imrishabh18/corne-keyboard
The code defines and renders two surface-mount chip components with SMT pads, silkscreen outlines, and 3D CAD models (OBJ and STEP) for PCB assembly.
- Version
- 2.0.21
- License
- unset
- Stars
- 1
debug-autorouter.mjs
var t=Object.create,e=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,i=Object.getPrototypeOf,r=Object.prototype.hasOwnProperty,s=(t,e)=>function(){return e||(0,t[o(t)[0]])((e={exports:{}}).exports,e),e.exports},a=(t,n)=>{for(var o in n)e(t,o,{get:n[o],enumerable:!0})},c=(s,a,c)=>(c=null!=s?t(i(s)):{},((t,i,s,a)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let c of o(i))r.call(t,c)||c===s||e(t,c,{get:()=>i[c],enumerable:!(a=n(i,c))||a.enumerable});return t})(!a&&s&&s.__esModule?c:e(c,"default",{value:s,enumerable:!0}),s)),l=s({"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)}}}),d=s({"node_modules/kind-of/index.js"(t,e){var n=l(),o=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=o.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"}}}),h=s({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(n[e(o,t[o])||o]=t[o]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),u=s({"node_modules/deep-rename-keys/index.js"(t,e){var n=d(),o=h();e.exports=function t(e,i){var r=n(e);if("object"!==r&&"array"!==r)throw new Error("expected an object");var s=[];for(var a in"object"===r&&(e=o(e,i),s={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?s[a]=t(c,i):s[a]=c}return s}}}),p=s({"node_modules/xml-reader/node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,o="~";function i(){}function r(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function s(){this._events=new i,this._eventsCount=0}Object.create&&(i.prototype=Object.create(null),(new i).__proto__||(o=!1)),s.prototype.eventNames=function(){var t,e,i=[];if(0===this._eventsCount)return i;for(e in t=this._events)n.call(t,e)&&i.push(o?e.slice(1):e);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},s.prototype.listeners=function(t,e){var n=o?o+t:t,i=this._events[n];if(e)return!!i;if(!i)return[];if(i.fn)return[i.fn];for(var r=0,s=i.length,a=new Array(s);r<s;r++)a[r]=i[r].fn;return a},s.prototype.emit=function(t,e,n,i,r,s){var a=o?o+t:t;if(!this._events[a])return!1;var c,l,d=this._events[a],h=arguments.length;if(d.fn){switch(d.once&&this.removeListener(t,d.fn,void 0,!0),h){case 1:return d.fn.call(d.context),!0;case 2:return d.fn.call(d.context,e),!0;case 3:return d.fn.call(d.context,e,n),!0;case 4:return d.fn.call(d.context,e,n,i),!0;case 5:return d.fn.call(d.context,e,n,i,r),!0;case 6:return d.fn.call(d.context,e,n,i,r,s),!0}for(l=1,c=new Array(h-1);l<h;l++)c[l-1]=arguments[l];d.fn.apply(d.context,c)}else{var u,p=d.length;for(l=0;l<p;l++)switch(d[l].once&&this.removeListener(t,d[l].fn,void 0,!0),h){case 1:d[l].fn.call(d[l].context);break;case 2:d[l].fn.call(d[l].context,e);break;case 3:d[l].fn.call(d[l].context,e,n);break;case 4:d[l].fn.call(d[l].context,e,n,i);break;default:if(!c)for(u=1,c=new Array(h-1);u<h;u++)c[u-1]=arguments[u];d[l].fn.apply(d[l].context,c)}}return!0},s.prototype.on=function(t,e,n){var i=new r(e,n||this),s=o?o+t:t;return this._events[s]?this._events[s].fn?this._events[s]=[this._events[s],i]:this._events[s].push(i):(this._events[s]=i,this._eventsCount++),this},s.prototype.once=function(t,e,n){var i=new r(e,n||this,!0),s=o?o+t:t;return this._events[s]?this._events[s].fn?this._events[s]=[this._events[s],i]:this._events[s].push(i):(this._events[s]=i,this._eventsCount++),this},s.prototype.removeListener=function(t,e,n,r){var s=o?o+t:t;if(!this._events[s])return this;if(!e)return 0===--this._eventsCount?this._events=new i:delete this._events[s],this;var a=this._events[s];if(a.fn)a.fn!==e||r&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new i:delete this._events[s]);else{for(var c=0,l=[],d=a.length;c<d;c++)(a[c].fn!==e||r&&!a[c].once||n&&a[c].context!==n)&&l.push(a[c]);l.length?this._events[s]=1===l.length?l[0]:l:0===--this._eventsCount?this._events=new i:delete this._events[s]}return this},s.prototype.removeAllListeners=function(t){var e;return t?(e=o?o+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new i:delete this._events[e])):(this._events=new i,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prototype.setMaxListeners=function(){return this},s.prefixed=o,s.EventEmitter=s,void 0!==e&&(e.exports=s)}}),m=s({"node_modules/xml-lexer/node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,o="~";function i(){}function r(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function s(){this._events=new i,this._eventsCount=0}Object.create&&(i.prototype=Object.create(null),(new i).__proto__||(o=!1)),s.prototype.eventNames=function(){var t,e,i=[];if(0===this._eventsCount)return i;for(e in t=this._events)n.call(t,e)&&i.push(o?e.slice(1):e);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},s.prototype.listeners=function(t,e){var n=o?o+t:t,i=this._events[n];if(e)return!!i;if(!i)return[];if(i.fn)return[i.fn];for(var r=0,s=i.length,a=new Array(s);r<s;r++)a[r]=i[r].fn;return a},s.prototype.emit=function(t,e,n,i,r,s){var a=o?o+t:t;if(!this._events[a])return!1;var c,l,d=this._events[a],h=arguments.length;if(d.fn){switch(d.once&&this.removeListener(t,d.fn,void 0,!0),h){case 1:return d.fn.call(d.context),!0;case 2:return d.fn.call(d.context,e),!0;case 3:return d.fn.call(d.context,e,n),!0;case 4:return d.fn.call(d.context,e,n,i),!0;case 5:return d.fn.call(d.context,e,n,i,r),!0;case 6:return d.fn.call(d.context,e,n,i,r,s),!0}for(l=1,c=new Array(h-1);l<h;l++)c[l-1]=arguments[l];d.fn.apply(d.context,c)}else{var u,p=d.length;for(l=0;l<p;l++)switch(d[l].once&&this.removeListener(t,d[l].fn,void 0,!0),h){case 1:d[l].fn.call(d[l].context);break;case 2:d[l].fn.call(d[l].context,e);break;case 3:d[l].fn.call(d[l].context,e,n);break;case 4:d[l].fn.call(d[l].context,e,n,i);break;default:if(!c)for(u=1,c=new Array(h-1);u<h;u++)c[u-1]=arguments[u];d[l].fn.apply(d[l].context,c)}}return!0},s.prototype.on=function(t,e,n){var i=new r(e,n||this),s=o?o+t:t;return this._events[s]?this._events[s].fn?this._events[s]=[this._events[s],i]:this._events[s].push(i):(this._events[s]=i,this._eventsCount++),this},s.prototype.once=function(t,e,n){var i=new r(e,n||this,!0),s=o?o+t:t;return this._events[s]?this._events[s].fn?this._events[s]=[this._events[s],i]:this._events[s].push(i):(this._events[s]=i,this._eventsCount++),this},s.prototype.removeListener=function(t,e,n,r){var s=o?o+t:t;if(!this._events[s])return this;if(!e)return 0===--this._eventsCount?this._events=new i:delete this._events[s],this;var a=this._events[s];if(a.fn)a.fn!==e||r&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new i:delete this._events[s]);else{for(var c=0,l=[],d=a.length;c<d;c++)(a[c].fn!==e||r&&!a[c].once||n&&a[c].context!==n)&&l.push(a[c]);l.length?this._events[s]=1===l.length?l[0]:l:0===--this._eventsCount?this._events=new i:delete this._events[s]}return this},s.prototype.removeAllListeners=function(t){var e;return t?(e=o?o+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new i:delete this._events[e])):(this._events=new i,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prototype.setMaxListeners=function(){return this},s.prefixed=o,s.EventEmitter=s,void 0!==e&&(e.exports=s)}}),g=s({"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 o=m(),i=function(){},r={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"},s={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={" ":s.space,"\t":s.space,"\n":s.space,"\r":s.space,"<":s.lt,">":s.gt,'"':s.quote,"'":s.quote,"=":s.equal,"/":s.slash};e.exports={State:r,Action:s,Type:a,create:function(t){var e,l,d,h,u,p,m,g,f,y;t=Object.assign({debug:!1},t);var _=new o,b=r.data,x="",v="",S="",I="",C="",P="",M=function(e,n){if("?"!==v[0]&&"!"!==v[0]){var o={type:e,value:n};t.debug&&console.log("emit:",o),_.emit("data",o)}};_.stateMachine=(n(y={},r.data,(n(e={},s.lt,function(){x.trim()&&M(a.text,x),v="",C=!1,b=r.tagBegin}),n(e,s.char,function(t){x+=t}),e)),n(y,r.cdata,n({},s.char,function(t){"]]>"===(x+=t).substr(-3)&&(M(a.text,x.slice(0,-3)),x="",b=r.data)})),n(y,r.tagBegin,(n(l={},s.space,i),n(l,s.char,function(t){v=t,b=r.tagName}),n(l,s.slash,function(){v="",C=!0}),l)),n(y,r.tagName,(n(d={},s.space,function(){C?b=r.tagEnd:(b=r.attributeNameStart,M(a.openTag,v))}),n(d,s.gt,function(){M(C?a.closeTag:a.openTag,v),x="",b=r.data}),n(d,s.slash,function(){b=r.tagEnd,M(a.openTag,v)}),n(d,s.char,function(t){"![CDATA["===(v+=t)&&(b=r.cdata,x="",v="")}),d)),n(y,r.tagEnd,(n(h={},s.gt,function(){M(a.closeTag,v),x="",b=r.data}),n(h,s.char,i),h)),n(y,r.attributeNameStart,(n(u={},s.char,function(t){S=t,b=r.attributeName}),n(u,s.gt,function(){x="",b=r.data}),n(u,s.space,i),n(u,s.slash,function(){C=!0,b=r.tagEnd}),u)),n(y,r.attributeName,(n(p={},s.space,function(){b=r.attributeNameEnd}),n(p,s.equal,function(){M(a.attributeName,S),b=r.attributeValueBegin}),n(p,s.gt,function(){I="",M(a.attributeName,S),M(a.attributeValue,I),x="",b=r.data}),n(p,s.slash,function(){C=!0,I="",M(a.attributeName,S),M(a.attributeValue,I),b=r.tagEnd}),n(p,s.char,function(t){S+=t}),p)),n(y,r.attributeNameEnd,(n(m={},s.space,i),n(m,s.equal,function(){M(a.attributeName,S),b=r.attributeValueBegin}),n(m,s.gt,function(){I="",M(a.attributeName,S),M(a.attributeValue,I),x="",b=r.data}),n(m,s.char,function(t){I="",M(a.attributeName,S),M(a.attributeValue,I),S=t,b=r.attributeName}),m)),n(y,r.attributeValueBegin,(n(g={},s.space,i),n(g,s.quote,function(t){P=t,I="",b=r.attributeValue}),n(g,s.gt,function(){M(a.attributeValue,I=""),x="",b=r.data}),n(g,s.char,function(t){P="",I=t,b=r.attributeValue}),g)),n(y,r.attributeValue,(n(f={},s.space,function(t){P?I+=t:(M(a.attributeValue,I),b=r.attributeNameStart)}),n(f,s.quote,function(t){P===t?(M(a.attributeValue,I),b=r.attributeNameStart):I+=t}),n(f,s.gt,function(t){P?I+=t:(M(a.attributeValue,I),x="",b=r.data)}),n(f,s.slash,function(t){P?I+=t:(M(a.attributeValue,I),C=!0,b=r.tagEnd)}),n(f,s.char,function(t){I+=t}),f)),y);var N=function(e){t.debug&&console.log(b,e);var n=_.stateMachine[b],o=n[function(t){return c[t]||s.char}(e)]||n[s.error]||n[s.char];o(e)};return _.write=function(t){for(var e=t.length,n=0;n<e;n++)N(t[n])},_}}}}),f=s({"node_modules/xml-reader/dist/reader.js"(t,e){var n=p(),o=g(),i=o.Type,r={element:"element",text:"text"},s=function(t){return Object.assign({name:"",type:r.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,l=void 0,d=new n,h=function(n){switch(n.type){case i.openTag:if(null===c)(c=a).name=n.value;else{var o=s({name:n.value,parent:c});c.children.push(o),c=o}break;case i.closeTag:var h=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&h===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&h!==a||(d.emit(t.tagPrefix+c.name,c),d.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),d.emit(t.doneEvent,c),a=null),c=h;break;case i.text:c&&c.children.push(s({type:r.text,value:n.value,parent:t.parentNodes?c:null}));break;case i.attributeName:l=n.value,c.attributes[l]="";break;case i.attributeValue:c.attributes[l]=n.value}};return d.reset=function(){(e=o.create({debug:t.debug})).on("data",h),a=s(),c=null,l="",d.parse=e.write},d.reset(),d};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),o=void 0;return n.on("done",function(t){o=t}),n.parse(t),o},create:a,NodeType:r}}}),y=s({"node_modules/binary-search-bounds/search-bounds.js"(t,e){function n(t,e,n,o,i){for(var r=i+1;o<=i;){var s=o+i>>>1,a=t[s];(void 0!==n?n(a,e):a-e)>=0?(r=s,i=s-1):o=s+1}return r}function o(t,e,n,o,i){for(var r=i+1;o<=i;){var s=o+i>>>1,a=t[s];(void 0!==n?n(a,e):a-e)>0?(r=s,i=s-1):o=s+1}return r}function i(t,e,n,o,i){for(var r=o-1;o<=i;){var s=o+i>>>1,a=t[s];(void 0!==n?n(a,e):a-e)<0?(r=s,o=s+1):i=s-1}return r}function r(t,e,n,o,i){for(var r=o-1;o<=i;){var s=o+i>>>1,a=t[s];(void 0!==n?n(a,e):a-e)<=0?(r=s,o=s+1):i=s-1}return r}function s(t,e,n,o,i){for(;o<=i;){var r=o+i>>>1,s=t[r],a=void 0!==n?n(s,e):s-e;if(0===a)return r;a<=0?o=r+1:i=r-1}return-1}function a(t,e,n,o,i,r){return"function"==typeof n?r(t,e,n,void 0===o?0:0|o,void 0===i?t.length-1:0|i):r(t,e,void 0,void 0===n?0:0|n,void 0===o?t.length-1:0|o)}e.exports={ge:function(t,e,o,i,r){return a(t,e,o,i,r,n)},gt:function(t,e,n,i,r){return a(t,e,n,i,r,o)},lt:function(t,e,n,o,r){return a(t,e,n,o,r,i)},le:function(t,e,n,o,i){return a(t,e,n,o,i,r)},eq:function(t,e,n,o,i){return a(t,e,n,o,i,s)}}}}),_=s({"node_modules/two-product/two-product.js"(t,e){e.exports=function(t,e,o){var i=t*e,r=n*t,s=r-(r-t),a=t-s,c=n*e,l=c-(c-e),d=e-l,h=a*d-(i-s*l-a*l-s*d);if(o)return o[0]=h,o[1]=i,o;return[h,i]};var n=+(Math.pow(2,27)+1)}}),b=s({"node_modules/robust-sum/robust-sum.js"(t,e){e.exports=function(t,e){var n=0|t.length,o=0|e.length;if(1===n&&1===o)return function(t,e){var n=t+e,o=n-t,i=n-o,r=e-o,s=t-i,a=s+r;if(a)return[a,n];return[n]}(t[0],e[0]);var i,r,s=new Array(n+o),a=0,c=0,l=0,d=Math.abs,h=t[c],u=d(h),p=e[l],m=d(p);u<m?(r=h,(c+=1)<n&&(u=d(h=t[c]))):(r=p,(l+=1)<o&&(m=d(p=e[l])));c<n&&u<m||l>=o?(i=h,(c+=1)<n&&(u=d(h=t[c]))):(i=p,(l+=1)<o&&(m=d(p=e[l])));var g,f,y=i+r,_=y-i,b=r-_,x=b,v=y;for(;c<n&&l<o;)u<m?(i=h,(c+=1)<n&&(u=d(h=t[c]))):(i=p,(l+=1)<o&&(m=d(p=e[l]))),(b=(r=x)-(_=(y=i+r)-i))&&(s[a++]=b),x=v-((g=v+y)-(f=g-v))+(y-f),v=g;for(;c<n;)(b=(r=x)-(_=(y=(i=h)+r)-i))&&(s[a++]=b),x=v-((g=v+y)-(f=g-v))+(y-f),v=g,(c+=1)<n&&(h=t[c]);for(;l<o;)(b=(r=x)-(_=(y=(i=p)+r)-i))&&(s[a++]=b),x=v-((g=v+y)-(f=g-v))+(y-f),v=g,(l+=1)<o&&(p=e[l]);x&&(s[a++]=x);v&&(s[a++]=v);a||(s[a++]=0);return s.length=a,s}}}),x=s({"node_modules/two-sum/two-sum.js"(t,e){e.exports=function(t,e,n){var o=t+e,i=o-t,r=e-i,s=t-(o-i);if(n)return n[0]=s+r,n[1]=o,n;return[s+r,o]}}}),v=s({"node_modules/robust-scale/robust-scale.js"(t,e){var n=_(),o=x();e.exports=function(t,e){var i=t.length;if(1===i){var r=n(t[0],e);return r[0]?r:[r[1]]}var s=new Array(2*i),a=[.1,.1],c=[.1,.1],l=0;n(t[0],e,a),a[0]&&(s[l++]=a[0]);for(var d=1;d<i;++d){n(t[d],e,c);var h=a[1];o(h,c[0],a),a[0]&&(s[l++]=a[0]);var u=c[1],p=a[1],m=u+p,g=p-(m-u);a[1]=m,g&&(s[l++]=g)}a[1]&&(s[l++]=a[1]);0===l&&(s[l++]=0);return s.length=l,s}}}),S=s({"node_modules/robust-subtract/robust-diff.js"(t,e){e.exports=function(t,e){var n=0|t.length,o=0|e.length;if(1===n&&1===o)return function(t,e){var n=t+e,o=n-t,i=n-o,r=e-o,s=t-i,a=s+r;if(a)return[a,n];return[n]}(t[0],-e[0]);var i,r,s=new Array(n+o),a=0,c=0,l=0,d=Math.abs,h=t[c],u=d(h),p=-e[l],m=d(p);u<m?(r=h,(c+=1)<n&&(u=d(h=t[c]))):(r=p,(l+=1)<o&&(m=d(p=-e[l])));c<n&&u<m||l>=o?(i=h,(c+=1)<n&&(u=d(h=t[c]))):(i=p,(l+=1)<o&&(m=d(p=-e[l])));var g,f,y=i+r,_=y-i,b=r-_,x=b,v=y;for(;c<n&&l<o;)u<m?(i=h,(c+=1)<n&&(u=d(h=t[c]))):(i=p,(l+=1)<o&&(m=d(p=-e[l]))),(b=(r=x)-(_=(y=i+r)-i))&&(s[a++]=b),x=v-((g=v+y)-(f=g-v))+(y-f),v=g;for(;c<n;)(b=(r=x)-(_=(y=(i=h)+r)-i))&&(s[a++]=b),x=v-((g=v+y)-(f=g-v))+(y-f),v=g,(c+=1)<n&&(h=t[c]);for(;l<o;)(b=(r=x)-(_=(y=(i=p)+r)-i))&&(s[a++]=b),x=v-((g=v+y)-(f=g-v))+(y-f),v=g,(l+=1)<o&&(p=-e[l]);x&&(s[a++]=x);v&&(s[a++]=v);a||(s[a++]=0);return s.length=a,s}}}),I=s({"node_modules/robust-orientation/orientation.js"(t,e){var n=_(),o=b(),i=v(),r=S();function s(t,e,n,o){return function(n,i,r){var s=t(t(e(i[1],r[0]),e(-r[1],i[0])),t(e(n[1],i[0]),e(-i[1],n[0]))),a=t(e(n[1],r[0]),e(-r[1],n[0])),c=o(s,a);return c[c.length-1]}}function a(t,e,n,o){return function(i,r,s,a){var c=t(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),r[2]),t(n(t(e(r[1],a[0]),e(-a[1],r[0])),-s[2]),n(t(e(r[1],s[0]),e(-s[1],r[0])),a[2]))),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])))),l=t(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),a[2]))),t(n(t(e(r[1],s[0]),e(-s[1],r[0])),i[2]),t(n(t(e(i[1],s[0]),e(-s[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),s[2])))),d=o(c,l);return d[d.length-1]}}function c(t,e,n,o){return function(i,r,s,a,c){var l=t(t(t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),s[2]),t(n(t(e(s[1],c[0]),e(-c[1],s[0])),-a[2]),n(t(e(s[1],a[0]),e(-a[1],s[0])),c[2]))),r[3]),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]))),-s[3]),n(t(n(t(e(s[1],c[0]),e(-c[1],s[0])),r[2]),t(n(t(e(r[1],c[0]),e(-c[1],r[0])),-s[2]),n(t(e(r[1],s[0]),e(-s[1],r[0])),c[2]))),a[3]))),t(n(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),r[2]),t(n(t(e(r[1],a[0]),e(-a[1],r[0])),-s[2]),n(t(e(r[1],s[0]),e(-s[1],r[0])),a[2]))),-c[3]),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]),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])))),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]))),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]),n(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),r[2]),t(n(t(e(r[1],a[0]),e(-a[1],r[0])),-s[2]),n(t(e(r[1],s[0]),e(-s[1],r[0])),a[2]))),i[3]))),t(n(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),a[2]))),-r[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]))),s[3]),n(t(n(t(e(r[1],s[0]),e(-s[1],r[0])),i[2]),t(n(t(e(i[1],s[0]),e(-s[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),s[2]))),-a[3]))))),d=t(t(t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),s[2]),t(n(t(e(s[1],c[0]),e(-c[1],s[0])),-a[2]),n(t(e(s[1],a[0]),e(-a[1],s[0])),c[2]))),i[3]),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]))),-s[3])),t(n(t(n(t(e(s[1],c[0]),e(-c[1],s[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),c[2]))),a[3]),n(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),a[2]))),-c[3]))),t(t(n(t(n(t(e(s[1],c[0]),e(-c[1],s[0])),r[2]),t(n(t(e(r[1],c[0]),e(-c[1],r[0])),-s[2]),n(t(e(r[1],s[0]),e(-s[1],r[0])),c[2]))),i[3]),n(t(n(t(e(s[1],c[0]),e(-c[1],s[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),c[2]))),-r[3])),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]))),s[3]),n(t(n(t(e(r[1],s[0]),e(-s[1],r[0])),i[2]),t(n(t(e(i[1],s[0]),e(-s[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),s[2]))),-c[3])))),h=o(l,d);return h[h.length-1]}}function l(t){return(3===t?s:4===t?a:c)(o,n,i,r)}var d=l(3),h=l(4),u=[function(){return 0},function(){return 0},function(t,e){return e[0]-t[0]},function(t,e,n){var o,i=(t[1]-n[1])*(e[0]-n[0]),r=(t[0]-n[0])*(e[1]-n[1]),s=i-r;if(i>0){if(r<=0)return s;o=i+r}else{if(!(i<0))return s;if(r>=0)return s;o=-(i+r)}var a=33306690738754716e-32*o;return s>=a||s<=-a?s:d(t,e,n)},function(t,e,n,o){var i=t[0]-o[0],r=e[0]-o[0],s=n[0]-o[0],a=t[1]-o[1],c=e[1]-o[1],l=n[1]-o[1],d=t[2]-o[2],u=e[2]-o[2],p=n[2]-o[2],m=r*l,g=s*c,f=s*a,y=i*l,_=i*c,b=r*a,x=d*(m-g)+u*(f-y)+p*(_-b),v=7771561172376103e-31*((Math.abs(m)+Math.abs(g))*Math.abs(d)+(Math.abs(f)+Math.abs(y))*Math.abs(u)+(Math.abs(_)+Math.abs(b))*Math.abs(p));return x>v||-x>v?x:h(t,e,n,o)}];function p(t){var e=u[t.length];return e||(e=u[t.length]=l(t.length)),e.apply(void 0,t)}function m(t,e,n,o,i,r,s){return function(e,n,a,c,l){switch(arguments.length){case 0:case 1:return 0;case 2:return o(e,n);case 3:return i(e,n,a);case 4:return r(e,n,a,c);case 5:return s(e,n,a,c,l)}for(var d=new Array(arguments.length),h=0;h<arguments.length;++h)d[h]=arguments[h];return t(d)}}!function(){for(;u.length<=5;)u.push(l(u.length));e.exports=m.apply(void 0,[p].concat(u));for(var t=0;t<=5;++t)e.exports[t]=u[t]}()}}),C=s({"node_modules/cdt2d/lib/monotone.js"(t,e){var n=y(),o=I()[3];function i(t,e,n,o,i){this.a=t,this.b=e,this.idx=n,this.lowerIds=o,this.upperIds=i}function r(t,e,n,o){this.a=t,this.b=e,this.type=n,this.idx=o}function s(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=o(t.a,t.b,e.b))?n:t.idx-e.idx)}function a(t,e){return o(t.a,t.b,e)}function c(t,e,i,r,s){for(var c=n.lt(e,r,a),l=n.gt(e,r,a),d=c;d<l;++d){for(var h=e[d],u=h.lowerIds,p=u.length;p>1&&o(i[u[p-2]],i[u[p-1]],r)>0;)t.push([u[p-1],u[p-2],s]),p-=1;u.length=p,u.push(s);var m=h.upperIds;for(p=m.length;p>1&&o(i[m[p-2]],i[m[p-1]],r)<0;)t.push([m[p-2],m[p-1],s]),p-=1;m.length=p,m.push(s)}}function l(t,e){var n;return(n=t.a[0]<e.a[0]?o(t.a,t.b,e.a):o(e.b,e.a,t.a))?n:(n=e.b[0]<t.b[0]?o(t.a,t.b,e.b):o(e.b,e.a,t.b))||t.idx-e.idx}function d(t,e,o){var r=n.le(t,o,l),s=t[r],a=s.upperIds,c=a[a.length-1];s.upperIds=[c],t.splice(r+1,0,new i(o.a,o.b,o.idx,[c],a))}function h(t,e,o){var i=o.a;o.a=o.b,o.b=i;var r=n.eq(t,o,l),s=t[r];t[r-1].upperIds=s.upperIds,t.splice(r,1)}e.exports=function(t,e){for(var n=t.length,o=e.length,a=[],l=0;l<n;++l)a.push(new r(t[l],null,0,l));for(l=0;l<o;++l){var u=e[l],p=t[u[0]],m=t[u[1]];p[0]<m[0]?a.push(new r(p,m,2,l),new r(m,p,1,l)):p[0]>m[0]&&a.push(new r(m,p,2,l),new r(p,m,1,l))}a.sort(s);for(var g=a[0].a[0]-(1+Math.abs(a[0].a[0]))*Math.pow(2,-52),f=[new i([g,1],[g,0],-1,[],[],[],[])],y=[],_=(l=0,a.length);l<_;++l){var b=a[l],x=b.type;0===x?c(y,f,t,b.a,b.idx):2===x?d(f,t,b):h(f,t,b)}return y}}}),P=s({"node_modules/cdt2d/lib/triangulation.js"(t,e){var n=y();function o(t,e){this.stars=t,this.edges=e}e.exports=function(t,e){for(var n=new Array(t),i=0;i<t;++i)n[i]=[];return new o(n,e)};var i=o.prototype;function r(t,e,n){for(var o=1,i=t.length;o<i;o+=2)if(t[o-1]===e&&t[o]===n)return t[o-1]=t[i-2],t[o]=t[i-1],void(t.length=i-2)}i.isConstraint=function(){var t=[0,0];function e(t,e){return t[0]-e[0]||t[1]-e[1]}return function(o,i){return t[0]=Math.min(o,i),t[1]=Math.max(o,i),n.eq(this.edges,t,e)>=0}}(),i.removeTriangle=function(t,e,n){var o=this.stars;r(o[t],e,n),r(o[e],n,t),r(o[n],t,e)},i.addTriangle=function(t,e,n){var o=this.stars;o[t].push(e,n),o[e].push(n,t),o[n].push(t,e)},i.opposite=function(t,e){for(var n=this.stars[e],o=1,i=n.length;o<i;o+=2)if(n[o]===t)return n[o-1];return-1},i.flip=function(t,e){var n=this.opposite(t,e),o=this.opposite(e,t);this.removeTriangle(t,e,n),this.removeTriangle(e,t,o),this.addTriangle(t,o,n),this.addTriangle(e,n,o)},i.edges=function(){for(var t=this.stars,e=[],n=0,o=t.length;n<o;++n)for(var i=t[n],r=0,s=i.length;r<s;r+=2)e.push([i[r],i[r+1]]);return e},i.cells=function(){for(var t=this.stars,e=[],n=0,o=t.length;n<o;++n)for(var i=t[n],r=0,s=i.length;r<s;r+=2){var a=i[r],c=i[r+1];n<Math.min(a,c)&&e.push([n,a,c])}return e}}}),M=s({"node_modules/robust-in-sphere/in-sphere.js"(t,e){var n=_(),o=b(),i=S(),r=v();function s(t){return(3===t?a:4===t?c:5===t?l:d)(o,i,n,r)}function a(t,e,n,o){return function(i,r,s){var a=n(i[0],i[0]),c=o(a,r[0]),l=o(a,s[0]),d=n(r[0],r[0]),h=o(d,i[0]),u=o(d,s[0]),p=n(s[0],s[0]),m=o(p,i[0]),g=o(p,r[0]),f=t(e(g,u),e(h,c)),y=e(m,l),_=e(f,y);return _[_.length-1]}}function c(t,e,n,o){return function(i,r,s,a){var c=t(n(i[0],i[0]),n(i[1],i[1])),l=o(c,r[0]),d=o(c,s[0]),h=o(c,a[0]),u=t(n(r[0],r[0]),n(r[1],r[1])),p=o(u,i[0]),m=o(u,s[0]),g=o(u,a[0]),f=t(n(s[0],s[0]),n(s[1],s[1])),y=o(f,i[0]),_=o(f,r[0]),b=o(f,a[0]),x=t(n(a[0],a[0]),n(a[1],a[1])),v=o(x,i[0]),S=o(x,r[0]),I=o(x,s[0]),C=t(t(o(e(I,b),r[1]),t(o(e(S,g),-s[1]),o(e(_,m),a[1]))),t(o(e(S,g),i[1]),t(o(e(v,h),-r[1]),o(e(p,l),a[1])))),P=t(t(o(e(I,b),i[1]),t(o(e(v,h),-s[1]),o(e(y,d),a[1]))),t(o(e(_,m),i[1]),t(o(e(y,d),-r[1]),o(e(p,l),s[1])))),M=e(C,P);return M[M.length-1]}}function l(t,e,n,o){return function(i,r,s,a,c){var l=t(n(i[0],i[0]),t(n(i[1],i[1]),n(i[2],i[2]))),d=o(l,r[0]),h=o(l,s[0]),u=o(l,a[0]),p=o(l,c[0]),m=t(n(r[0],r[0]),t(n(r[1],r[1]),n(r[2],r[2]))),g=o(m,i[0]),f=o(m,s[0]),y=o(m,a[0]),_=o(m,c[0]),b=t(n(s[0],s[0]),t(n(s[1],s[1]),n(s[2],s[2]))),x=o(b,i[0]),v=o(b,r[0]),S=o(b,a[0]),I=o(b,c[0]),C=t(n(a[0],a[0]),t(n(a[1],a[1]),n(a[2],a[2]))),P=o(C,i[0]),M=o(C,r[0]),N=o(C,s[0]),w=o(C,c[0]),T=t(n(c[0],c[0]),t(n(c[1],c[1]),n(c[2],c[2]))),R=o(T,i[0]),E=o(T,r[0]),A=o(T,s[0]),O=o(T,a[0]),k=t(t(t(o(t(o(e(O,w),s[1]),t(o(e(A,I),-a[1]),o(e(N,S),c[1]))),r[2]),t(o(t(o(e(O,w),r[1]),t(o(e(E,_),-a[1]),o(e(M,y),c[1]))),-s[2]),o(t(o(e(A,I),r[1]),t(o(e(E,_),-s[1]),o(e(v,f),c[1]))),a[2]))),t(o(t(o(e(N,S),r[1]),t(o(e(M,y),-s[1]),o(e(v,f),a[1]))),-c[2]),t(o(t(o(e(O,w),r[1]),t(o(e(E,_),-a[1]),o(e(M,y),c[1]))),i[2]),o(t(o(e(O,w),i[1]),t(o(e(R,p),-a[1]),o(e(P,u),c[1]))),-r[2])))),t(t(o(t(o(e(E,_),i[1]),t(o(e(R,p),-r[1]),o(e(g,d),c[1]))),a[2]),t(o(t(o(e(M,y),i[1]),t(o(e(P,u),-r[1]),o(e(g,d),a[1]))),-c[2]),o(t(o(e(N,S),r[1]),t(o(e(M,y),-s[1]),o(e(v,f),a[1]))),i[2]))),t(o(t(o(e(N,S),i[1]),t(o(e(P,u),-s[1]),o(e(x,h),a[1]))),-r[2]),t(o(t(o(e(M,y),i[1]),t(o(e(P,u),-r[1]),o(e(g,d),a[1]))),s[2]),o(t(o(e(v,f),i[1]),t(o(e(x,h),-r[1]),o(e(g,d),s[1]))),-a[2]))))),L=t(t(t(o(t(o(e(O,w),s[1]),t(o(e(A,I),-a[1]),o(e(N,S),c[1]))),i[2]),o(t(o(e(O,w),i[1]),t(o(e(R,p),-a[1]),o(e(P,u),c[1]))),-s[2])),t(o(t(o(e(A,I),i[1]),t(o(e(R,p),-s[1]),o(e(x,h),c[1]))),a[2]),o(t(o(e(N,S),i[1]),t(o(e(P,u),-s[1]),o(e(x,h),a[1]))),-c[2]))),t(t(o(t(o(e(A,I),r[1]),t(o(e(E,_),-s[1]),o(e(v,f),c[1]))),i[2]),o(t(o(e(A,I),i[1]),t(o(e(R,p),-s[1]),o(e(x,h),c[1]))),-r[2])),t(o(t(o(e(E,_),i[1]),t(o(e(R,p),-r[1]),o(e(g,d),c[1]))),s[2]),o(t(o(e(v,f),i[1]),t(o(e(x,h),-r[1]),o(e(g,d),s[1]))),-c[2])))),D=e(k,L);return D[D.length-1]}}function d(t,e,n,o){return function(i,r,s,a,c,l){var d=t(t(n(i[0],i[0]),n(i[1],i[1])),t(n(i[2],i[2]),n(i[3],i[3]))),h=o(d,r[0]),u=o(d,s[0]),p=o(d,a[0]),m=o(d,c[0]),g=o(d,l[0]),f=t(t(n(r[0],r[0]),n(r[1],r[1])),t(n(r[2],r[2]),n(r[3],r[3]))),y=o(f,i[0]),_=o(f,s[0]),b=o(f,a[0]),x=o(f,c[0]),v=o(f,l[0]),S=t(t(n(s[0],s[0]),n(s[1],s[1])),t(n(s[2],s[2]),n(s[3],s[3]))),I=o(S,i[0]),C=o(S,r[0]),P=o(S,a[0]),M=o(S,c[0]),N=o(S,l[0]),w=t(t(n(a[0],a[0]),n(a[1],a[1])),t(n(a[2],a[2]),n(a[3],a[3]))),T=o(w,i[0]),R=o(w,r[0]),E=o(w,s[0]),A=o(w,c[0]),O=o(w,l[0]),k=t(t(n(c[0],c[0]),n(c[1],c[1])),t(n(c[2],c[2]),n(c[3],c[3]))),L=o(k,i[0]),D=o(k,r[0]),z=o(k,s[0]),F=o(k,a[0]),B=o(k,l[0]),j=t(t(n(l[0],l[0]),n(l[1],l[1])),t(n(l[2],l[2]),n(l[3],l[3]))),$=o(j,i[0]),Y=o(j,r[0]),X=o(j,s[0]),V=o(j,a[0]),W=o(j,c[0]),H=t(t(t(o(t(t(o(t(o(e(W,B),a[1]),t(o(e(V,O),-c[1]),o(e(F,A),l[1]))),s[2]),o(t(o(e(W,B),s[1]),t(o(e(X,N),-c[1]),o(e(z,M),l[1]))),-a[2])),t(o(t(o(e(V,O),s[1]),t(o(e(X,N),-a[1]),o(e(E,P),l[1]))),c[2]),o(t(o(e(F,A),s[1]),t(o(e(z,M),-a[1]),o(e(E,P),c[1]))),-l[2]))),r[3]),t(o(t(t(o(t(o(e(W,B),a[1]),t(o(e(V,O),-c[1]),o(e(F,A),l[1]))),r[2]),o(t(o(e(W,B),r[1]),t(o(e(Y,v),-c[1]),o(e(D,x),l[1]))),-a[2])),t(o(t(o(e(V,O),r[1]),t(o(e(Y,v),-a[1]),o(e(R,b),l[1]))),c[2]),o(t(o(e(F,A),r[1]),t(o(e(D,x),-a[1]),o(e(R,b),c[1]))),-l[2]))),-s[3]),o(t(t(o(t(o(e(W,B),s[1]),t(o(e(X,N),-c[1]),o(e(z,M),l[1]))),r[2]),o(t(o(e(W,B),r[1]),t(o(e(Y,v),-c[1]),o(e(D,x),l[1]))),-s[2])),t(o(t(o(e(X,N),r[1]),t(o(e(Y,v),-s[1]),o(e(C,_),l[1]))),c[2]),o(t(o(e(z,M),r[1]),t(o(e(D,x),-s[1]),o(e(C,_),c[1]))),-l[2]))),a[3]))),t(t(o(t(t(o(t(o(e(V,O),s[1]),t(o(e(X,N),-a[1]),o(e(E,P),l[1]))),r[2]),o(t(o(e(V,O),r[1]),t(o(e(Y,v),-a[1]),o(e(R,b),l[1]))),-s[2])),t(o(t(o(e(X,N),r[1]),t(o(e(Y,v),-s[1]),o(e(C,_),l[1]))),a[2]),o(t(o(e(E,P),r[1]),t(o(e(R,b),-s[1]),o(e(C,_),a[1]))),-l[2]))),-c[3]),o(t(t(o(t(o(e(F,A),s[1]),t(o(e(z,M),-a[1]),o(e(E,P),c[1]))),r[2]),o(t(o(e(F,A),r[1]),t(o(e(D,x),-a[1]),o(e(R,b),c[1]))),-s[2])),t(o(t(o(e(z,M),r[1]),t(o(e(D,x),-s[1]),o(e(C,_),c[1]))),a[2]),o(t(o(e(E,P),r[1]),t(o(e(R,b),-s[1]),o(e(C,_),a[1]))),-c[2]))),l[3])),t(o(t(t(o(t(o(e(W,B),a[1]),t(o(e(V,O),-c[1]),o(e(F,A),l[1]))),r[2]),o(t(o(e(W,B),r[1]),t(o(e(Y,v),-c[1]),o(e(D,x),l[1]))),-a[2])),t(o(t(o(e(V,O),r[1]),t(o(e(Y,v),-a[1]),o(e(R,b),l[1]))),c[2]),o(t(o(e(F,A),r[1]),t(o(e(D,x),-a[1]),o(e(R,b),c[1]))),-l[2]))),i[3]),o(t(t(o(t(o(e(W,B),a[1]),t(o(e(V,O),-c[1]),o(e(F,A),l[1]))),i[2]),o(t(o(e(W,B),i[1]),t(o(e($,g),-c[1]),o(e(L,m),l[1]))),-a[2])),t(o(t(o(e(V,O),i[1]),t(o(e($,g),-a[1]),o(e(T,p),l[1]))),c[2]),o(t(o(e(F,A),i[1]),t(o(e(L,m),-a[1]),o(e(T,p),c[1]))),-l[2]))),-r[3])))),t(t(t(o(t(t(o(t(o(e(W,B),r[1]),t(o(e(Y,v),-c[1]),o(e(D,x),l[1]))),i[2]),o(t(o(e(W,B),i[1]),t(o(e($,g),-c[1]),o(e(L,m),l[1]))),-r[2])),t(o(t(o(e(Y,v),i[1]),t(o(e($,g),-r[1]),o(e(y,h),l[1]))),c[2]),o(t(o(e(D,x),i[1]),t(o(e(L,m),-r[1]),o(e(y,h),c[1]))),-l[2]))),a[3]),o(t(t(o(t(o(e(V,O),r[1]),t(o(e(Y,v),-a[1]),o(e(R,b),l[1]))),i[2]),o(t(o(e(V,O),i[1]),t(o(e($,g),-a[1]),o(e(T,p),l[1]))),-r[2])),t(o(t(o(e(Y,v),i[1]),t(o(e($,g),-r[1]),o(e(y,h),l[1]))),a[2]),o(t(o(e(R,b),i[1]),t(o(e(T,p),-r[1]),o(e(y,h),a[1]))),-l[2]))),-c[3])),t(o(t(t(o(t(o(e(F,A),r[1]),t(o(e(D,x),-a[1]),o(e(R,b),c[1]))),i[2]),o(t(o(e(F,A),i[1]),t(o(e(L,m),-a[1]),o(e(T,p),c[1]))),-r[2])),t(o(t(o(e(D,x),i[1]),t(o(e(L,m),-r[1]),o(e(y,h),c[1]))),a[2]),o(t(o(e(R,b),i[1]),t(o(e(T,p),-r[1]),o(e(y,h),a[1]))),-c[2]))),l[3]),o(t(t(o(t(o(e(V,O),s[1]),t(o(e(X,N),-a[1]),o(e(E,P),l[1]))),r[2]),o(t(o(e(V,O),r[1]),t(o(e(Y,v),-a[1]),o(e(R,b),l[1]))),-s[2])),t(o(t(o(e(X,N),r[1]),t(o(e(Y,v),-s[1]),o(e(C,_),l[1]))),a[2]),o(t(o(e(E,P),r[1]),t(o(e(R,b),-s[1]),o(e(C,_),a[1]))),-l[2]))),i[3]))),t(t(o(t(t(o(t(o(e(V,O),s[1]),t(o(e(X,N),-a[1]),o(e(E,P),l[1]))),i[2]),o(t(o(e(V,O),i[1]),t(o(e($,g),-a[1]),o(e(T,p),l[1]))),-s[2])),t(o(t(o(e(X,N),i[1]),t(o(e($,g),-s[1]),o(e(I,u),l[1]))),a[2]),o(t(o(e(E,P),i[1]),t(o(e(T,p),-s[1]),o(e(I,u),a[1]))),-l[2]))),-r[3]),o(t(t(o(t(o(e(V,O),r[1]),t(o(e(Y,v),-a[1]),o(e(R,b),l[1]))),i[2]),o(t(o(e(V,O),i[1]),t(o(e($,g),-a[1]),o(e(T,p),l[1]))),-r[2])),t(o(t(o(e(Y,v),i[1]),t(o(e($,g),-r[1]),o(e(y,h),l[1]))),a[2]),o(t(o(e(R,b),i[1]),t(o(e(T,p),-r[1]),o(e(y,h),a[1]))),-l[2]))),s[3])),t(o(t(t(o(t(o(e(X,N),r[1]),t(o(e(Y,v),-s[1]),o(e(C,_),l[1]))),i[2]),o(t(o(e(X,N),i[1]),t(o(e($,g),-s[1]),o(e(I,u),l[1]))),-r[2])),t(o(t(o(e(Y,v),i[1]),t(o(e($,g),-r[1]),o(e(y,h),l[1]))),s[2]),o(t(o(e(C,_),i[1]),t(o(e(I,u),-r[1]),o(e(y,h),s[1]))),-l[2]))),-a[3]),o(t(t(o(t(o(e(E,P),r[1]),t(o(e(R,b),-s[1]),o(e(C,_),a[1]))),i[2]),o(t(o(e(E,P),i[1]),t(o(e(T,p),-s[1]),o(e(I,u),a[1]))),-r[2])),t(o(t(o(e(R,b),i[1]),t(o(e(T,p),-r[1]),o(e(y,h),a[1]))),s[2]),o(t(o(e(C,_),i[1]),t(o(e(I,u),-r[1]),o(e(y,h),s[1]))),-a[2]))),l[3]))))),G=t(t(t(o(t(t(o(t(o(e(W,B),a[1]),t(o(e(V,O),-c[1]),o(e(F,A),l[1]))),s[2]),o(t(o(e(W,B),s[1]),t(o(e(X,N),-c[1]),o(e(z,M),l[1]))),-a[2])),t(o(t(o(e(V,O),s[1]),t(o(e(X,N),-a[1]),o(e(E,P),l[1]))),c[2]),o(t(o(e(F,A),s[1]),t(o(e(z,M),-a[1]),o(e(E,P),c[1]))),-l[2]))),i[3]),t(o(t(t(o(t(o(e(W,B),a[1]),t(o(e(V,O),-c[1]),o(e(F,A),l[1]))),i[2]),o(t(o(e(W,B),i[1]),t(o(e($,g),-c[1]),o(e(L,m),l[1]))),-a[2])),t(o(t(o(e(V,O),i[1]),t(o(e($,g),-a[1]),o(e(T,p),l[1]))),c[2]),o(t(o(e(F,A),i[1]),t(o(e(L,m),-a[1]),o(e(T,p),c[1]))),-l[2]))),-s[3]),o(t(t(o(t(o(e(W,B),s[1]),t(o(e(X,N),-c[1]),o(e(z,M),l[1]))),i[2]),o(t(o(e(W,B),i[1]),t(o(e($,g),-c[1]),o(e(L,m),l[1]))),-s[2])),t(o(t(o(e(X,N),i[1]),t(o(e($,g),-s[1]),o(e(I,u),l[1]))),c[2]),o(t(o(e(z,M),i[1]),t(o(e(L,m),-s[1]),o(e(I,u),c[1]))),-l[2]))),a[3]))),t(t(o(t(t(o(t(o(e(V,O),s[1]),t(o(e(X,N),-a[1]),o(e(E,P),l[1]))),i[2]),o(t(o(e(V,O),i[1]),t(o(e($,g),-a[1]),o(e(T,p),l[1]))),-s[2])),t(o(t(o(e(X,N),i[1]),t(o(e($,g),-s[1]),o(e(I,u),l[1]))),a[2]),o(t(o(e(E,P),i[1]),t(o(e(T,p),-s[1]),o(e(I,u),a[1]))),-l[2]))),-c[3]),o(t(t(o(t(o(e(F,A),s[1]),t(o(e(z,M),-a[1]),o(e(E,P),c[1]))),i[2]),o(t(o(e(F,A),i[1]),t(o(e(L,m),-a[1]),o(e(T,p),c[1]))),-s[2])),t(o(t(o(e(z,M),i[1]),t(o(e(L,m),-s[1]),o(e(I,u),c[1]))),a[2]),o(t(o(e(E,P),i[1]),t(o(e(T,p),-s[1]),o(e(I,u),a[1]))),-c[2]))),l[3])),t(o(t(t(o(t(o(e(W,B),s[1]),t(o(e(X,N),-c[1]),o(e(z,M),l[1]))),r[2]),o(t(o(e(W,B),r[1]),t(o(e(Y,v),-c[1]),o(e(D,x),l[1]))),-s[2])),t(o(t(o(e(X,N),r[1]),t(o(e(Y,v),-s[1]),o(e(C,_),l[1]))),c[2]),o(t(o(e(z,M),r[1]),t(o(e(D,x),-s[1]),o(e(C,_),c[1]))),-l[2]))),i[3]),o(t(t(o(t(o(e(W,B),s[1]),t(o(e(X,N),-c[1]),o(e(z,M),l[1]))),i[2]),o(t(o(e(W,B),i[1]),t(o(e($,g),-c[1]),o(e(L,m),l[1]))),-s[2])),t(o(t(o(e(X,N),i[1]),t(o(e($,g),-s[1]),o(e(I,u),l[1]))),c[2]),o(t(o(e(z,M),i[1]),t(o(e(L,m),-s[1]),o(e(I,u),c[1]))),-l[2]))),-r[3])))),t(t(t(o(t(t(o(t(o(e(W,B),r[1]),t(o(e(Y,v),-c[1]),o(e(D,x),l[1]))),i[2]),o(t(o(e(W,B),i[1]),t(o(e($,g),-c[1]),o(e(L,m),l[1]))),-r[2])),t(o(t(o(e(Y,v),i[1]),t(o(e($,g),-r[1]),o(e(y,h),l[1]))),c[2]),o(t(o(e(D,x),i[1]),t(o(e(L,m),-r[1]),o(e(y,h),c[1]))),-l[2]))),s[3]),o(t(t(o(t(o(e(X,N),r[1]),t(o(e(Y,v),-s[1]),o(e(C,_),l[1]))),i[2]),o(t(o(e(X,N),i[1]),t(o(e($,g),-s[1]),o(e(I,u),l[1]))),-r[2])),t(o(t(o(e(Y,v),i[1]),t(o(e($,g),-r[1]),o(e(y,h),l[1]))),s[2]),o(t(o(e(C,_),i[1]),t(o(e(I,u),-r[1]),o(e(y,h),s[1]))),-l[2]))),-c[3])),t(o(t(t(o(t(o(e(z,M),r[1]),t(o(e(D,x),-s[1]),o(e(C,_),c[1]))),i[2]),o(t(o(e(z,M),i[1]),t(o(e(L,m),-s[1]),o(e(I,u),c[1]))),-r[2])),t(o(t(o(e(D,x),i[1]),t(o(e(L,m),-r[1]),o(e(y,h),c[1]))),s[2]),o(t(o(e(C,_),i[1]),t(o(e(I,u),-r[1]),o(e(y,h),s[1]))),-c[2]))),l[3]),o(t(t(o(t(o(e(F,A),s[1]),t(o(e(z,M),-a[1]),o(e(E,P),c[1]))),r[2]),o(t(o(e(F,A),r[1]),t(o(e(D,x),-a[1]),o(e(R,b),c[1]))),-s[2])),t(o(t(o(e(z,M),r[1]),t(o(e(D,x),-s[1]),o(e(C,_),c[1]))),a[2]),o(t(o(e(E,P),r[1]),t(o(e(R,b),-s[1]),o(e(C,_),a[1]))),-c[2]))),i[3]))),t(t(o(t(t(o(t(o(e(F,A),s[1]),t(o(e(z,M),-a[1]),o(e(E,P),c[1]))),i[2]),o(t(o(e(F,A),i[1]),t(o(e(L,m),-a[1]),o(e(T,p),c[1]))),-s[2])),t(o(t(o(e(z,M),i[1]),t(o(e(L,m),-s[1]),o(e(I,u),c[1]))),a[2]),o(t(o(e(E,P),i[1]),t(o(e(T,p),-s[1]),o(e(I,u),a[1]))),-c[2]))),-r[3]),o(t(t(o(t(o(e(F,A),r[1]),t(o(e(D,x),-a[1]),o(e(R,b),c[1]))),i[2]),o(t(o(e(F,A),i[1]),t(o(e(L,m),-a[1]),o(e(T,p),c[1]))),-r[2])),t(o(t(o(e(D,x),i[1]),t(o(e(L,m),-r[1]),o(e(y,h),c[1]))),a[2]),o(t(o(e(R,b),i[1]),t(o(e(T,p),-r[1]),o(e(y,h),a[1]))),-c[2]))),s[3])),t(o(t(t(o(t(o(e(z,M),r[1]),t(o(e(D,x),-s[1]),o(e(C,_),c[1]))),i[2]),o(t(o(e(z,M),i[1]),t(o(e(L,m),-s[1]),o(e(I,u),c[1]))),-r[2])),t(o(t(o(e(D,x),i[1]),t(o(e(L,m),-r[1]),o(e(y,h),c[1]))),s[2]),o(t(o(e(C,_),i[1]),t(o(e(I,u),-r[1]),o(e(y,h),s[1]))),-c[2]))),-a[3]),o(t(t(o(t(o(e(E,P),r[1]),t(o(e(R,b),-s[1]),o(e(C,_),a[1]))),i[2]),o(t(o(e(E,P),i[1]),t(o(e(T,p),-s[1]),o(e(I,u),a[1]))),-r[2])),t(o(t(o(e(R,b),i[1]),t(o(e(T,p),-r[1]),o(e(y,h),a[1]))),s[2]),o(t(o(e(C,_),i[1]),t(o(e(I,u),-r[1]),o(e(y,h),s[1]))),-a[2]))),c[3]))))),U=e(H,G);return U[U.length-1]}}var h=[function(){return 0},function(){return 0},function(){return 0}];function u(t){var e=h[t.length];return e||(e=h[t.length]=s(t.length)),e.apply(void 0,t)}function p(t,e,n,o,i,r,s,a){return function(e,n,c,l,d,h){switch(arguments.length){case 0:case 1:return 0;case 2:return o(e,n);case 3:return i(e,n,c);case 4:return r(e,n,c,l);case 5:return s(e,n,c,l,d);case 6:return a(e,n,c,l,d,h)}for(var u=new Array(arguments.length),p=0;p<arguments.length;++p)u[p]=arguments[p];return t(u)}}!function(){for(;h.length<=6;)h.push(s(h.length));e.exports=p.apply(void 0,[u].concat(h));for(var t=0;t<=6;++t)e.exports[t]=h[t]}()}}),N=s({"node_modules/cdt2d/lib/delaunay.js"(t,e){var n=M()[4];y();function o(t,e,o,i,r,s){var a=e.opposite(i,r);if(!(a<0)){if(r<i){var c=i;i=r,r=c,c=s,s=a,a=c}e.isConstraint(i,r)||n(t[i],t[r],t[s],t[a])<0&&o.push(i,r)}}e.exports=function(t,e){for(var i=[],r=t.length,s=e.stars,a=0;a<r;++a)for(var c=s[a],l=1;l<c.length;l+=2){if(!((p=c[l])<a)&&!e.isConstraint(a,p)){for(var d=c[l-1],h=-1,u=1;u<c.length;u+=2)if(c[u-1]===p){h=c[u];break}h<0||n(t[a],t[p],t[d],t[h])<0&&i.push(a,p)}}for(;i.length>0;){for(var p=i.pop(),m=(d=-1,h=-1,c=s[a=i.pop()],1);m<c.length;m+=2){var g=c[m-1],f=c[m];g===p?h=f:f===p&&(d=g)}d<0||h<0||(n(t[a],t[p],t[d],t[h])>=0||(e.flip(a,p),o(t,e,i,d,a,h),o(t,e,i,a,h,d),o(t,e,i,h,p,d),o(t,e,i,p,d,h)))}}}}),w=s({"node_modules/cdt2d/lib/filter.js"(t,e){var n=y();function o(t,e,n,o,i,r,s){this.cells=t,this.neighbor=e,this.flags=o,this.constraint=n,this.active=i,this.next=r,this.boundary=s}function i(t,e){return t[0]-e[0]||t[1]-e[1]||t[2]-e[2]}e.exports=function(t,e,n){var r=function(t,e){for(var n=t.cells(),r=n.length,s=0;s<r;++s){var a=(y=n[s])[0],c=y[1],l=y[2];c<l?c<a&&(y[0]=c,y[1]=l,y[2]=a):l<a&&(y[0]=l,y[1]=a,y[2]=c)}n.sort(i);var d=new Array(r);for(s=0;s<d.length;++s)d[s]=0;var h=[],u=[],p=new Array(3*r),m=new Array(3*r),g=null;e&&(g=[]);var f=new o(n,p,m,d,h,u,g);for(s=0;s<r;++s)for(var y=n[s],_=0;_<3;++_){a=y[_],c=y[(_+1)%3];var b=p[3*s+_]=f.locate(c,a,t.opposite(c,a)),x=m[3*s+_]=t.isConstraint(a,c);b<0&&(x?u.push(s):(h.push(s),d[s]=1),e&&g.push([c,a,-1]))}return f}(t,n);if(0===e)return n?r.cells.concat(r.boundary):r.cells;var s=1,a=r.active,c=r.next,l=r.flags,d=r.cells,h=r.constraint,u=r.neighbor;for(;a.length>0||c.length>0;){for(;a.length>0;){var p=a.pop();if(l[p]!==-s){l[p]=s;d[p];for(var m=0;m<3;++m){var g=u[3*p+m];g>=0&&0===l[g]&&(h[3*p+m]?c.push(g):(a.push(g),l[g]=s))}}}var f=c;c=a,a=f,c.length=0,s=-s}var y=function(t,e,n){for(var o=0,i=0;i<t.length;++i)e[i]===n&&(t[o++]=t[i]);return t.length=o,t}(d,l,e);if(n)return y.concat(r.boundary);return y},o.prototype.locate=function(){var t=[0,0,0];return function(e,o,r){var s=e,a=o,c=r;return o<r?o<e&&(s=o,a=r,c=e):r<e&&(s=r,a=e,c=o),s<0?-1:(t[0]=s,t[1]=a,t[2]=c,n.eq(this.cells,t,i))}}()}}),T=s({"node_modules/cdt2d/cdt2d.js"(t,e){var n=C(),o=P(),i=N(),r=w();function s(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,l){Array.isArray(e)?(l=l||{},e=e||[]):(l=e||{},e=[]);var d=!!c(l,"delaunay",!0),h=!!c(l,"interior",!0),u=!!c(l,"exterior",!0),p=!!c(l,"infinity",!1);if(!h&&!u||0===t.length)return[];var m=n(t,e);if(d||h!==u||p){for(var g=o(t.length,function(t){return t.map(s).sort(a)}(e)),f=0;f<m.length;++f){var y=m[f];g.addTriangle(y[0],y[1],y[2])}return d&&i(t,g),u?h?p?r(g,0,p):g.cells():r(g,1,p):r(g,-1)}return m}}});function R(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 E(t,e){return e.map(e=>R(t,e))}function A(t){const{a:e,b:n,c:o,d:i,e:r,f:s}=t,a=e*i-n*o;return{a:i/a,b:n/-a,c:o/-a,d:e/a,e:(i*r-o*s)/-a,f:(n*r-e*s)/a}}function O(t){return void 0===t}function k(t,e=0){return{a:1,c:0,e:t,b:0,d:1,f:e}}function L(...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,o,...i]=t;return L(e(n,o),...i)}}}function D(...t){return L(...t)}var{cos:z,sin:F,PI:B}=Math;function j(t,e=void 0,n=void 0){return function(t,e,n){const o=z(t),i=F(t),r={a:o,c:-i,e:0,b:i,d:o,f:0};return O(e)||O(n)?r:L([k(e,n),r,k(-e,-n)])}(t*B/180,e,n)}var{tan:$}=Math,Y=(c(u()),c(f()),new TextEncoder,(()=>{const t=new Uint8Array(4);new Uint32Array(t.buffer)[0]=1,t[0]})(),globalThis.Int8Array,globalThis.Uint8Array,globalThis.Int16Array,globalThis.Uint16Array,globalThis.Int32Array,globalThis.Uint32Array,globalThis.BigUint64Array,globalThis.BigInt64Array,globalThis.Float32Array,globalThis.Float64Array,[]);for(let t=0;t<256;t++){let e=t;for(let t=0;t<8;t++)1&e?e=3988292384^e>>>1:e>>>=1;Y[t]=e}var X=new Uint16Array([255]),V=(new Uint8Array(X.buffer)[0],new Uint16Array([255]));new Uint8Array(V.buffer)[0],new Uint8Array(0),Uint8Array.of(137,80,78,71,13,10,26,10),new TextDecoder("latin1");function W(){return W=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var o in n)({}).hasOwnProperty.call(n,o)&&(t[o]=n[o])}return t},W.apply(null,arguments)}function H(t,e){return(H=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t})(t,e)}function G(t){return(G=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function U(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(U=function(){return!!t})()}function Z(t){var e="function"==typeof Map?new Map:void 0;return Z=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(U())return Reflect.construct.apply(null,arguments);var o=[null];o.push.apply(o,e);var i=new(t.bind.apply(t,o));return n&&H(i,n.prototype),i}(t,arguments,G(this).constructor)}return n.prototype=Object.create(t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),H(n,t)},Z(t)}var q={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 J(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];var o,i=e[0],r=[];for(o=1;o<e.length;o+=1)r.push(e[o]);return r.forEach(function(t){i=i.replace(/%[a-z]/,t)}),i}var K=function(t){var e,n;function o(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 o=arguments.length,i=new Array(o>1?o-1:0),r=1;r<o;r++)i[r-1]=arguments[r];n=t.call(this,J.apply(void 0,[q[e]].concat(i)))||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=o).prototype=Object.create(n.prototype),e.prototype.constructor=e,H(e,n),o}(Z(Error));function Q(t,e){return t.substr(-e.length)===e}var tt=/^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/;function et(t){return"string"!=typeof t?t:t.match(tt)?parseFloat(t):t}var nt=function(t){return function(e,n){void 0===n&&(n="16px");var o=e,i=n;if("string"==typeof e){if(!Q(e,"px"))throw new K(69,t,e);o=et(e)}if("string"==typeof n){if(!Q(n,"px"))throw new K(70,t,n);i=et(n)}if("string"==typeof o)throw new K(71,e,t);if("string"==typeof i)throw new K(72,n,t);return""+o/i+t}};nt("em"),nt("rem");function ot(t){return Math.round(255*t)}function it(t,e,n){return ot(t)+","+ot(e)+","+ot(n)}function rt(t,e,n,o){if(void 0===o&&(o=it),0===e)return o(n,n,n);var i=(t%360+360)%360/60,r=(1-Math.abs(2*n-1))*e,s=r*(1-Math.abs(i%2-1)),a=0,c=0,l=0;i>=0&&i<1?(a=r,c=s):i>=1&&i<2?(a=s,c=r):i>=2&&i<3?(c=r,l=s):i>=3&&i<4?(c=s,l=r):i>=4&&i<5?(a=s,l=r):i>=5&&i<6&&(a=r,l=s);var d=n-r/2;return o(a+d,c+d,l+d)}var st={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 at=/^#[a-fA-F0-9]{6}$/,ct=/^#[a-fA-F0-9]{8}$/,lt=/^#[a-fA-F0-9]{3}$/,dt=/^#[a-fA-F0-9]{4}$/,ht=/^rgb\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*\)$/i,ut=/^rgb(?:a)?\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i,pt=/^hsl\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*\)$/i,mt=/^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 gt(t){if("string"!=typeof t)throw new K(3);var e=function(t){if("string"!=typeof t)return t;var e=t.toLowerCase();return st[e]?"#"+st[e]:t}(t);if(e.match(at))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(ct)){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(lt))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(dt)){var o=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:o}}var i=ht.exec(e);if(i)return{red:parseInt(""+i[1],10),green:parseInt(""+i[2],10),blue:parseInt(""+i[3],10)};var r=ut.exec(e.substring(0,50));if(r)return{red:parseInt(""+r[1],10),green:parseInt(""+r[2],10),blue:parseInt(""+r[3],10),alpha:parseFloat(""+r[4])>1?parseFloat(""+r[4])/100:parseFloat(""+r[4])};var s=pt.exec(e);if(s){var a="rgb("+rt(parseInt(""+s[1],10),parseInt(""+s[2],10)/100,parseInt(""+s[3],10)/100)+")",c=ht.exec(a);if(!c)throw new K(4,e,a);return{red:parseInt(""+c[1],10),green:parseInt(""+c[2],10),blue:parseInt(""+c[3],10)}}var l=mt.exec(e.substring(0,50));if(l){var d="rgb("+rt(parseInt(""+l[1],10),parseInt(""+l[2],10)/100,parseInt(""+l[3],10)/100)+")",h=ht.exec(d);if(!h)throw new K(4,e,d);return{red:parseInt(""+h[1],10),green:parseInt(""+h[2],10),blue:parseInt(""+h[3],10),alpha:parseFloat(""+l[4])>1?parseFloat(""+l[4])/100:parseFloat(""+l[4])}}throw new K(5)}function ft(t){return function(t){var e,n=t.red/255,o=t.green/255,i=t.blue/255,r=Math.max(n,o,i),s=Math.min(n,o,i),a=(r+s)/2;if(r===s)return void 0!==t.alpha?{hue:0,saturation:0,lightness:a,alpha:t.alpha}:{hue:0,saturation:0,lightness:a};var c=r-s,l=a>.5?c/(2-r-s):c/(r+s);switch(r){case n:e=(o-i)/c+(o<i?6:0);break;case o:e=(i-n)/c+2;break;default:e=(n-o)/c+4}return e*=60,void 0!==t.alpha?{hue:e,saturation:l,lightness:a,alpha:t.alpha}:{hue:e,saturation:l,lightness:a}}(gt(t))}var yt=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 _t(t){var e=t.toString(16);return 1===e.length?"0"+e:e}function bt(t){return _t(Math.round(255*t))}function xt(t,e,n){return yt("#"+bt(t)+bt(e)+bt(n))}function vt(t,e,n){return rt(t,e,n,xt)}function St(t,e,n){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n)return yt("#"+_t(t)+_t(e)+_t(n));if("object"==typeof t&&void 0===e&&void 0===n)return yt("#"+_t(t.red)+_t(t.green)+_t(t.blue));throw new K(6)}function It(t,e,n,o){if("string"==typeof t&&"number"==typeof e){var i=gt(t);return"rgba("+i.red+","+i.green+","+i.blue+","+e+")"}if("number"==typeof t&&"number"==typeof e&&"number"==typeof n&&"number"==typeof o)return o>=1?St(t,e,n):"rgba("+t+","+e+","+n+","+o+")";if("object"==typeof t&&void 0===e&&void 0===n&&void 0===o)return t.alpha>=1?St(t.red,t.green,t.blue):"rgba("+t.red+","+t.green+","+t.blue+","+t.alpha+")";throw new K(7)}function Ct(t){if("object"!=typeof t)throw new K(8);if(function(t){return"number"==typeof t.red&&"number"==typeof t.green&&"number"==typeof t.blue&&"number"==typeof t.alpha}(t))return It(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 St(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,o){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n&&"number"==typeof o)return o>=1?vt(t,e,n):"rgba("+rt(t,e,n)+","+o+")";if("object"==typeof t&&void 0===e&&void 0===n&&void 0===o)return t.alpha>=1?vt(t.hue,t.saturation,t.lightness):"rgba("+rt(t.hue,t.saturation,t.lightness)+","+t.alpha+")";throw new K(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 vt(t,e,n);if("object"==typeof t&&void 0===e&&void 0===n)return vt(t.hue,t.saturation,t.lightness);throw new K(1)}(t);throw new K(8)}function Pt(t,e,n){return function(){var o=n.concat(Array.prototype.slice.call(arguments));return o.length>=e?t.apply(this,o):Pt(t,e,o)}}function Mt(t){return Pt(t,t.length,[])}Mt(function(t,e){if("transparent"===e)return e;var n=ft(e);return Ct(W({},n,{hue:n.hue+parseFloat(t)}))});function Nt(t,e,n){return Math.max(t,Math.min(e,n))}Mt(function(t,e){if("transparent"===e)return e;var n=ft(e);return Ct(W({},n,{lightness:Nt(0,1,n.lightness-parseFloat(t))}))});Mt(function(t,e){if("transparent"===e)return e;var n=ft(e);return Ct(W({},n,{saturation:Nt(0,1,n.saturation-parseFloat(t))}))});Mt(function(t,e){if("transparent"===e)return e;var n=ft(e);return Ct(W({},n,{lightness:Nt(0,1,n.lightness+parseFloat(t))}))});var wt=Mt(function(t,e,n){if("transparent"===e)return n;if("transparent"===n)return e;if(0===t)return n;var o=gt(e),i=W({},o,{alpha:"number"==typeof o.alpha?o.alpha:1}),r=gt(n),s=W({},r,{alpha:"number"==typeof r.alpha?r.alpha:1}),a=i.alpha-s.alpha,c=2*parseFloat(t)-1,l=((c*a===-1?c:c+a)/(1+c*a)+1)/2,d=1-l;return It({red:Math.floor(i.red*l+s.red*d),green:Math.floor(i.green*l+s.green*d),blue:Math.floor(i.blue*l+s.blue*d),alpha:i.alpha*parseFloat(t)+s.alpha*(1-parseFloat(t))})});Mt(function(t,e){if("transparent"===e)return e;var n=gt(e);return It(W({},n,{alpha:Nt(0,1,(100*("number"==typeof n.alpha?n.alpha:1)+100*parseFloat(t))/100)}))});Mt(function(t,e){if("transparent"===e)return e;var n=ft(e);return Ct(W({},n,{saturation:Nt(0,1,n.saturation+parseFloat(t))}))});Mt(function(t,e){return"transparent"===e?e:Ct(W({},ft(e),{hue:parseFloat(t)}))});Mt(function(t,e){return"transparent"===e?e:Ct(W({},ft(e),{lightness:parseFloat(t)}))});Mt(function(t,e){return"transparent"===e?e:Ct(W({},ft(e),{saturation:parseFloat(t)}))});Mt(function(t,e){return"transparent"===e?e:wt(parseFloat(t),"rgb(0, 0, 0)",e)});Mt(function(t,e){return"transparent"===e?e:wt(parseFloat(t),"rgb(255, 255, 255)",e)});var Tt=Mt(function(t,e){if("transparent"===e)return e;var n=gt(e);return It(W({},n,{alpha:Nt(0,1,+(100*("number"==typeof n.alpha?n.alpha:1)-100*parseFloat(t)).toFixed(2)/100)}))}),Rt={0:"M0.301025 0.257813 L0.206593 0.283385 L0.122042 0.361307 L0.075923 0.474441 L0.064942 0.642221 L0.091296 0.78289 L0.159376 0.899463 L0.257104 0.961214 L0.344948 0.961214 L0.442678 0.899463 L0.510757 0.78289 L0.537111 0.642221 L0.526131 0.474441 L0.480012 0.361307 L0.39546 0.283385 L0.301025 0.257813",1:"M0.220426 0.40845 L0.381626 0.270996 L0.381626 0.948966",2:"M0.110409 0.39212 L0.125621 0.342293 L0.170571 0.295823 L0.244237 0.26431 L0.291518 0.257813 L0.373319 0.263799 L0.434683 0.290705 L0.468239 0.331966 L0.480292 0.379913 L0.479492 0.411806 L0.465088 0.465192 L0.402571 0.568988 L0.245134 0.766438 L0.07959 0.948045 L0.522462 0.948045",3:"M0.081606 0.345073 L0.119154 0.315633 L0.178996 0.284091 L0.255265 0.257813 L0.349133 0.263062 L0.43127 0.289348 L0.48994 0.336662 L0.525141 0.394491 L0.513407 0.457577 L0.466472 0.504892 L0.384334 0.541692 L0.290464 0.56272 L0.20833 0.573235 L0.290464 0.583749 L0.384334 0.610035 L0.466472 0.652092 L0.519274 0.709922 L0.531007 0.773007 L0.50754 0.841351 L0.454738 0.899179 L0.3726 0.946494 L0.310412 0.961214 L0.209503 0.959111 L0.127367 0.946494 L0.071046 0.929671",4:"M0.418494 0.270996 L0.048828 0.724199 L0.553224 0.724199 M0.414181 0.578167 L0.414181 0.94897",5:"M0.074951 0.270996 L0.074951 0.614701 L0.267655 0.5695 L0.405247 0.586502 L0.460002 0.617189 L0.498028 0.660731 L0.527101 0.779401 L0.513352 0.841049 L0.477274 0.889568 L0.406378 0.93463 L0.324445 0.958337 L0.247399 0.962139 L0.182516 0.949767 L0.130068 0.925508 L0.074951 0.875607 M0.074951 0.270996 L0.527101 0.270996",6:"M0.428549 0.257813 L0.341433 0.285053 L0.26073 0.312099 L0.192188 0.360182 L0.138902 0.410969 L0.098219 0.500422 L0.070249 0.584267 L0.067264 0.670716 L0.065164 0.756863 L0.087163 0.820973 L0.108168 0.861042 L0.157916 0.913131 L0.210981 0.948192 L0.29279 0.961214 L0.384548 0.956206 L0.456409 0.924151 L0.507262 0.881077 L0.5349 0.821975 L0.537111 0.771889 L0.521634 0.718798 L0.498418 0.67372 L0.463042 0.636657 L0.414398 0.613617 L0.34696 0.598591 L0.28284 0.595587 L0.215403 0.605604 L0.145756 0.641665 L0.109274 0.678729 L0.064942 0.724006",7:"M0.071534 0.270996 L0.530519 0.270996 L0.495935 0.291702 L0.477752 0.305407 L0.435186 0.346112 L0.412067 0.374136 L0.388565 0.40796 L0.365315 0.448098 L0.342943 0.495062 L0.322081 0.549366 L0.303364 0.611524 L0.287416 0.68205 L0.270077 0.80465 L0.26253 0.94897",8:"M0.286761 0.257813 L0.210684 0.27162 L0.1414 0.305622 L0.092494 0.382125 L0.111513 0.450128 L0.16857 0.502193 L0.228345 0.539382 L0.377781 0.594635 L0.470161 0.645637 L0.52586 0.706203 L0.538087 0.792269 L0.506841 0.87621 L0.438915 0.927212 L0.339743 0.961214 L0.263666 0.959089 L0.174004 0.929337 L0.102003 0.881523 L0.063965 0.811395 L0.066682 0.741266 L0.102003 0.671139 L0.180797 0.608448 L0.259591 0.580822 L0.358762 0.548945 L0.456576 0.49688 L0.486463 0.446941 L0.487822 0.362999 L0.453859 0.302434 L0.384574 0.265245 L0.286761 0.257813",9:"M0.511026 0.437812 L0.491026 0.347812 L0.451026 0.297812 L0.391026 0.267812 L0.311026 0.257813 L0.231026 0.267812 L0.161026 0.297812 L0.111026 0.347812 L0.091026 0.417812 L0.111026 0.487812 L0.161026 0.537812 L0.231026 0.567812 L0.311026 0.577812 L0.391026 0.557812 L0.451026 0.517812 L0.491026 0.477812 L0.511026 0.437812 M0.510026 0.438812 L0.434026 0.636812 L0.381026 0.777812 L0.337026 0.879812 L0.301026 0.957812","!":"M0.301026 0.270996 L0.301026 0.749566 M0.251466 0.94897 L0.350587 0.94897",'"':"M0.16504 0.270996 L0.16504 0.523022 M0.437013 0.270996 L0.437013 0.523022","#":"M0.20958 0.282227 L0.146515 0.949754 M0.461844 0.282227 L0.398779 0.949754 M0.032999 0.526969 L0.600587 0.452796 M0.001465 0.82366 L0.569055 0.749486",$:"M0.307121 0.240234 L0.307121 1.083502 M0.490031 0.415915 L0.404676 0.328075 L0.23396 0.310507 L0.136407 0.398347 L0.099828 0.521324 L0.124213 0.591596 L0.197379 0.644299 L0.429061 0.697003 L0.502224 0.749708 L0.526613 0.837547 L0.477836 0.960526 L0.355897 1.013228 L0.197379 0.99566 L0.112021 0.942957 L0.07544 0.837547","'":"M0.301026 0.270996 L0.301026 0.523022","(":"M0.413087 0.241211 L0.372337 0.28347 L0.331589 0.334184 L0.290838 0.393349 L0.25009 0.460965 L0.219528 0.528584 L0.199153 0.5962 L0.188966 0.655364 L0.199153 0.714529 L0.219528 0.782146 L0.25009 0.849764 L0.290838 0.91738 L0.331589 0.976544 L0.372337 1.027258 L0.413087 1.069491",")":"M0.188966 0.241211 L0.229716 0.28347 L0.270466 0.334184 L0.311213 0.393349 L0.351964 0.460965 L0.382526 0.528584 L0.4029 0.5962 L0.413087 0.655364 L0.4029 0.714529 L0.382526 0.782146 L0.351964 0.849764 L0.311213 0.91738 L0.270466 0.976544 L0.229716 1.027258 L0.188966 1.069491","*":"M0.301026 0.458702 L0.301026 0.681942 M0.301026 0.458702 L0.520997 0.536834 M0.301026 0.458702 L0.439954 0.257813 M0.301026 0.458702 L0.162098 0.257813 M0.301026 0.458702 L0.081055 0.536834","+":"M0.042969 0.66845 L0.559083 0.66845 M0.301023 0.428223 L0.301023 0.908661",",":"M0.38672 0.852051 L0.215333 1.030661 L0.301025 1.119971","-":"M0.173829 0.686035 L0.428224 0.686035",".":"M0.362549 0.851074 L0.239503 0.851074","/":"M0.062501 1.035249 L0.539551 0.270996","<":"M0.559083 0.441895 L0.042969 0.66939 L0.042969 0.66939 L0.559083 0.896902","=":"M0.042969 0.545898 L0.559083 0.545898 M0.042969 0.80837 L0.559083 0.80837",">":"M0.042969 0.441895 L0.559083 0.66939 L0.559083 0.66939 L0.042969 0.896902",A:"M0.018067 0.94897 L0.290179 0.270996 L0.583986 0.94897 M0.155303 0.684521 L0.433548 0.684521",B:"M0.063965 0.94897 L0.063965 0.278953 L0.209356 0.270996 L0.342486 0.294394 L0.432179 0.37292 L0.418224 0.48773 L0.312686 0.549166 L0.084728 0.575531 L0.306377 0.589434 L0.468877 0.647456 L0.538087 0.736658 L0.5324 0.85202 L0.501247 0.902983 L0.42355 0.944398 L0.063965 0.94897",C:"M0.529054 0.419847 L0.498425 0.345196 L0.442238 0.292341 L0.33583 0.257813 L0.257199 0.268357 L0.187906 0.303748 L0.120243 0.385432 L0.072998 0.599844 L0.110073 0.815385 L0.165381 0.902183 L0.222883 0.942801 L0.334904 0.961214 L0.43253 0.937679 L0.504816 0.868999 L0.529054 0.772065",D:"M0.064454 0.94897 L0.071838 0.285078 L0.171217 0.270996 L0.247348 0.272633 L0.37101 0.306078 L0.462461 0.378304 L0.514748 0.475555 L0.535591 0.576392 L0.537599 0.652313 L0.528065 0.717381 L0.508562 0.772419 L0.445948 0.855695 L0.362356 0.90871 L0.225203 0.945862 L0.064454 0.94897",E:"M0.080078 0.270996 L0.080078 0.94897 M0.080078 0.270996 L0.521974 0.270996 M0.080078 0.609981 L0.389405 0.609981 M0.080078 0.94897 L0.521974 0.94897",F:"M0.086426 0.270996 L0.086426 0.94897 M0.091304 0.275607 L0.515626 0.275607 M0.091304 0.607677 L0.447344 0.607677",G:"M0.498034 0.284943 L0.374621 0.257813 L0.244219 0.268648 L0.160577 0.311997 L0.094556 0.398116 L0.056397 0.58404 L0.076752 0.785532 L0.120865 0.858197 L0.188947 0.916734 L0.271008 0.953591 L0.357069 0.961214 L0.43715 0.932047 L0.501262 0.858539 L0.545656 0.648611 L0.329595 0.648131",H:"M0.066895 0.270996 L0.066895 0.94897 M0.066895 0.595658 L0.530009 0.595658 M0.535157 0.270996 L0.535157 0.94897",I:"M0.301026 0.270996 L0.301026 0.94897",J:"M0.506839 0.270996 L0.507814 0.782193 L0.498468 0.846168 L0.480733 0.880789 L0.455864 0.90832 L0.426095 0.929408 L0.360746 0.954812 L0.302508 0.962139 L0.223573 0.953638 L0.16538 0.930312 L0.137072 0.907715 L0.116428 0.880312 L0.102822 0.848819 L0.095633 0.813947 L0.094239 0.776413",K:"M0.035401 0.270996 L0.035401 0.94897 M0.502258 0.316194 L0.035401 0.687823 M0.212484 0.582361 L0.566652 0.933903",L:"M0.07544 0.270996 L0.07544 0.94897 L0.526613 0.94897",M:"M0.042481 0.94897 L0.042481 0.270996 L0.301027 0.712492 L0.559571 0.270996 L0.559571 0.94897",N:"M0.067871 0.94897 L0.067871 0.270996 L0.534181 0.94897 L0.525031 0.270996",O:"M0.287293 0.961214 L0.19843 0.933567 L0.1172 0.849451 L0.057129 0.563945 L0.114348 0.350255 L0.18455 0.289392 L0.306101 0.257813 L0.42054 0.29572 L0.487543 0.365003 L0.544923 0.625294 L0.516366 0.789624 L0.465476 0.884596 L0.375084 0.949287 L0.287293 0.961214",P:"M0.070557 0.94897 L0.070557 0.28379 L0.20704 0.270996 L0.329134 0.278993 L0.408525 0.300514 L0.444022 0.317908 L0.500637 0.368929 L0.525796 0.423728 L0.531496 0.50384 L0.508934 0.554205 L0.473724 0.582043 L0.417577 0.604365 L0.336375 0.620372 L0.226014 0.629268 L0.082368 0.630258",Q:"M0.282435 1.050813 L0.195447 1.019646 L0.115933 0.924817 L0.057129 0.602943 L0.113139 0.362034 L0.18186 0.293418 L0.300844 0.257813 L0.412868 0.300553 L0.478457 0.37866 L0.534625 0.672103 L0.506671 0.857367 L0.456855 0.964437 L0.368371 1.037368 L0.282435 1.050813 M0.341225 0.815559 L0.544923 1.070653",R:"M0.034912 0.944112 L0.034912 0.288556 L0.227127 0.270996 L0.362038 0.276867 L0.443423 0.294907 L0.477644 0.309614 L0.505809 0.328757 L0.526616 0.352817 L0.544963 0.418061 L0.543241 0.475921 L0.524463 0.517817 L0.49076 0.546518 L0.444265 0.564799 L0.355195 0.578739 L0.047653 0.589627 M0.303054 0.617306 L0.56714 0.94897",S:"M0.483037 0.364333 L0.407613 0.267477 L0.22883 0.257813 L0.128623 0.327565 L0.087712 0.455539 L0.104656 0.518727 L0.168054 0.573307 L0.41928 0.617318 L0.503796 0.669342 L0.535157 0.759324 L0.493846 0.900055 L0.367668 0.961214 L0.205436 0.956661 L0.116711 0.907038 L0.066895 0.790334",T:"M0.022949 0.270996 L0.579103 0.270996 M0.309284 0.270996 L0.309284 0.94897",U:"M0.072022 0.270996 L0.07308 0.648875 L0.080372 0.75167 L0.099024 0.827813 L0.134786 0.885729 L0.181571 0.924023 L0.251464 0.95168 L0.339655 0.962139 L0.401553 0.951668 L0.45232 0.924086 L0.482701 0.891771 L0.495745 0.870529 L0.515699 0.81637 L0.525014 0.744626 L0.530031 0.272017",V:"M0.027832 0.270996 L0.320083 0.94897 L0.57422 0.270996",W:"M0 0.270996 L0.079799 0.940377 L0.285198 0.472884 L0.505255 0.94897 L0.602052 0.270996",X:"M0.009034 0.270996 L0.586805 0.94897 M0.593019 0.270996 L0.015246 0.94897",Y:"M0.018067 0.270996 L0.293132 0.574135 M0.583986 0.271959 L0.294954 0.57606 L0.305277 0.94897",Z:"M0.053711 0.270996 L0.548341 0.270996 L0.053711 0.94897 L0.548341 0.94897","[":"M0.404542 0.240234 L0.197511 0.240234 L0.197511 1.069424 L0.404542 1.069424","\\":"M0.062501 0.270996 L0.539551 1.035249","]":"M0.19751 0.240234 L0.404542 0.240234 L0.404542 1.069424 L0.19751 1.069424","^":"M0.035156 0.523931 L0.301024 0.270996 L0.566896 0.523931",_:"M0 1.160601 L0.602052 1.160601",a:"M0.527101 0.439941 L0.527101 0.973965 M0.527101 0.553824 L0.451366 0.477535 L0.376759 0.439941 L0.263722 0.439941 L0.187989 0.477535 L0.112255 0.553824 L0.074951 0.66881 L0.074951 0.745099 L0.112255 0.85898 L0.187989 0.93527 L0.263722 0.973965 L0.376759 0.973965 L0.451366 0.93527 L0.527101 0.85898",b:"M0.07666 0.240234 L0.07666 0.959985 M0.07666 0.582737 L0.151822 0.514237 L0.225865 0.480483 L0.338045 0.480483 L0.413211 0.514237 L0.488374 0.582737 L0.525392 0.685983 L0.525392 0.754485 L0.488374 0.856739 L0.413211 0.92524 L0.338045 0.959985 L0.225865 0.959985 L0.151822 0.92524 L0.07666 0.856739",c:"M0.512452 0.553823 L0.441624 0.477535 L0.371854 0.439941 L0.26614 0.439941 L0.195312 0.477535 L0.124486 0.553823 L0.0896 0.668808 L0.0896 0.745099 L0.124486 0.858979 L0.195312 0.93527 L0.26614 0.973965 L0.371854 0.973965 L0.441624 0.93527 L0.512452 0.858979",d:"M0.525392 0.240234 L0.525392 0.959985 M0.525392 0.582737 L0.450232 0.514237 L0.376189 0.480483 L0.264006 0.480483 L0.188844 0.514237 L0.11368 0.582737 L0.076661 0.685983 L0.076661 0.754485 L0.11368 0.856739 L0.188844 0.92524 L0.264006 0.959985 L0.376189 0.959985 L0.450232 0.92524 L0.525392 0.856739",e:"M0.059571 0.668808 L0.542482 0.668808 M0.542482 0.592521 L0.502641 0.516231 L0.461594 0.477535 L0.381914 0.439941 L0.261186 0.439941 L0.180299 0.477535 L0.099412 0.553823 L0.059571 0.668808 L0.059571 0.745099 L0.099412 0.858979 L0.180299 0.93527 L0.261186 0.973965 L0.381914 0.973965 L0.461594 0.93527 L0.542482 0.858979",f:"M0.512941 0.240234 L0.406984 0.240234 L0.301026 0.274346 L0.248047 0.374731 L0.248047 0.946817 M0.089112 0.476088 L0.459965 0.476088",g:"M0.525392 0.439941 L0.525392 0.989395 L0.488373 1.091918 L0.45023 1.126757 L0.376189 1.160601 L0.264004 1.160601 L0.188844 1.126757 L0.113681 1.058075 L0.076661 0.954555 M0.525392 0.542467 L0.45023 0.473786 L0.376189 0.439941 L0.264004 0.439941 L0.188844 0.473786 L0.113681 0.542467 L0.076661 0.645988 L0.076661 0.714669 L0.113681 0.817193 L0.188844 0.885875 L0.264004 0.920713 L0.376189 0.920713 L0.45023 0.885875 L0.525392 0.817193",h:"M0.092041 0.240234 L0.092041 0.946817 M0.092041 0.61058 L0.205937 0.509225 L0.282214 0.476086 L0.396109 0.476086 L0.47187 0.509225 L0.510011 0.61058 L0.510011 0.946817",i:"M0.261026 0.240234 L0.341026 0.240234 M0.300978 0.476089 L0.300978 0.946817",j:"M0.3853 0.240234 L0.447023 0.240234 M0.416159 0.465708 L0.416159 1.011689 L0.383887 1.108586 L0.252832 1.140264 L0.15503 1.108586",k:"M0.065186 0.240234 L0.065186 0.946817 M0.493824 0.476086 L0.065186 0.812323 M0.236758 0.677829 L0.536867 0.946817",l:"M0.301026 0.234863 L0.301026 0.946441",m:"M0.050538 0.439941 L0.050538 0.960796 M0.050538 0.588758 L0.114405 0.476607 L0.157178 0.439941 L0.236864 0.439941 L0.279637 0.476607 L0.32241 0.588758 L0.32241 0.960796 M0.32241 0.588758 L0.386281 0.476607 L0.428467 0.439941 L0.50874 0.439941 L0.551515 0.476607 L0.551515 0.960796",n:"M0.092041 0.439941 L0.092041 0.960796 M0.092041 0.588758 L0.205936 0.476607 L0.282216 0.439941 L0.396113 0.439941 L0.471871 0.476607 L0.510011 0.588758 L0.510011 0.960796",o:"M0.247175 0.439941 L0.175178 0.477535 L0.103186 0.553823 L0.066895 0.668808 L0.066895 0.745099 L0.103186 0.858979 L0.175178 0.93527 L0.247175 0.973965 L0.354874 0.973965 L0.426872 0.93527 L0.498866 0.858979 L0.535157 0.745099 L0.535157 0.668808 L0.498866 0.553823 L0.426872 0.477535 L0.354874 0.439941 L0.247175 0.439941",p:"M0.076904 0.439941 L0.076904 1.154244 M0.076904 0.541563 L0.151986 0.473487 L0.225944 0.439941 L0.338005 0.439941 L0.413087 0.473487 L0.488166 0.541563 L0.525148 0.644169 L0.525148 0.712246 L0.488166 0.813866 L0.413087 0.881942 L0.338005 0.916471 L0.225944 0.916471 L0.151986 0.881942 L0.076904 0.813866",q:"M0.525148 0.441895 L0.525148 1.156195 M0.525148 0.5435 L0.450067 0.47544 L0.376106 0.441895 L0.264042 0.441895 L0.188966 0.47544 L0.113885 0.5435 L0.076905 0.646108 L0.076905 0.714187 L0.113885 0.815809 L0.188966 0.883886 L0.264042 0.918418 L0.376106 0.918418 L0.450067 0.883886 L0.525148 0.815809",r:"M0.107422 0.439941 L0.107422 0.960796 M0.107422 0.663164 L0.155824 0.551014 L0.252626 0.476607 L0.349428 0.439941 L0.49463 0.439941",s:"M0.475556 0.477535 L0.400757 0.439941 L0.276092 0.439941 L0.176361 0.477535 L0.101563 0.553823 L0.101563 0.630112 L0.176361 0.668808 L0.301024 0.668808 L0.425688 0.745099 L0.50049 0.821387 L0.50049 0.897677 L0.425688 0.93527 L0.325956 0.973965 L0.201295 0.973965 L0.126496 0.93527 L0.101563 0.858979",t:"M0.246032 0.297852 L0.246032 0.826549 L0.301023 0.919323 L0.411011 0.950848 L0.520997 0.950848 M0.081055 0.515799 L0.466004 0.515799",u:"M0.092041 0.454102 L0.092041 0.826134 L0.13018 0.937211 L0.205936 0.974954 L0.319832 0.974954 L0.396113 0.937211 L0.510011 0.826134 M0.510011 0.454102 L0.510011 0.974954",v:"M0.048828 0.453125 L0.301026 0.961719 M0.553224 0.453125 L0.301026 0.961719",w:"M0 0.453125 L0.150512 0.961719 M0.301024 0.453125 L0.150512 0.961719 M0.301024 0.453125 L0.451539 0.961719 M0.602052 0.453125 L0.451539 0.961719",x:"M0.03711 0.453125 L0.564943 0.961719 M0.564943 0.453125 L0.03711 0.961719",y:"M0.084618 0.453125 L0.320232 0.921476 M0.55713 0.453125 L0.320232 0.921476 L0.242119 1.055289 L0.163369 1.122196 L0.084618 1.155166 L0.044922 1.155166",z:"M0.505373 0.452148 L0.09668 0.961651 M0.09668 0.452148 L0.505373 0.452148 M0.09668 0.961651 L0.505373 0.961651"},Et={};for(const t in Rt){Et[t]=[];const e=Rt[t].split("M").slice(1).map(t=>t.split("L").map(t=>t.trim().split(" ").map(parseFloat)));for(const n of e)for(let e=0;e<n.length-1;e++)Et[t].push({x1:n[e][0],y1:1-n[e][1],x2:n[e+1][0],y2:1-n[e+1][1]})}var At=(t,e)=>({...t,rects:[...t.rects??[],...e.rects??[]],points:[...t.points??[],...e.points??[]],lines:[...t.lines??[],...e.lines??[]],infiniteLines:[...t.infiniteLines??[],...e.infiniteLines??[]],polygons:[...t.polygons??[],...e.polygons??[]],circles:[...t.circles??[],...e.circles??[]],arrows:[...t.arrows??[],...e.arrows??[]],texts:[...t.texts??[],...e.texts??[]]});function Ot(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;if(t.arrows)for(const n of t.arrows)n.step=e;return t}var kt=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 Lt(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var Dt=class extends kt{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,o=this.firstIterationOfStage[e.solverName]||0,i=this.iterations,r=e.solverName===this.getCurrentStageName()?i-o:0,s=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:r,completed:s}}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&&(Ot(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const o=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const o=this[e.solverName],i=o?.visualize();return i?(Ot(i,n+t),i):null}).filter(Boolean));return 0===o.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(Ot(n,o.length+t+1),o.push(n)),1===o.length?o[0]:{points:o.flatMap(t=>t.points||[]),rects:o.flatMap(t=>t.rects||[]),lines:o.flatMap(t=>t.lines||[]),circles:o.flatMap(t=>t.circles||[]),texts:o.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]}},zt=class{constructor(t=1/0,e=Float64Array,n=Uint32Array){const o=t!==1/0;this.ids=o?new n(t):[],this.values=o?new e(t):[],this.capacity=t,this.length=0}clear(){this.length=0}push(t,e){if(this.length===this.capacity)throw new RangeError("Queue is at capacity.");let n=this.length++;for(;n>0;){const t=n-1>>1,o=this.values[t];if(e>=o)break;this.ids[n]=this.ids[t],this.values[n]=o,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],o=--this.length;if(o>0){const n=t[o],i=e[o];let r=0;const s=o>>1;for(;r<s;){const n=1+(r<<1),s=n+1,a=n+(+(s<o)&+(e[s]<e[n]));if(e[a]>=i)break;t[r]=t[a],e[r]=e[a],r=a}t[r]=n,e[r]=i}return n}peek(){return this.length>0?this.ids[0]:void 0}peekValue(){return this.length>0?this.values[0]:void 0}shrink(){Array.isArray(this.ids)&&(this.ids.length=this.length),Array.isArray(this.values)&&(this.values.length=this.length)}},Ft=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],Bt=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||"buffer"in e)throw new Error("Data must be an instance of ArrayBuffer or SharedArrayBuffer.");const[o,i]=new Uint8Array(e,n+0,2);if(251!==o)throw new Error("Data does not appear to be in a Flatbush format.");const r=i>>4;if(3!==r)throw new Error(`Got v${r} data when expected v3.`);const s=Ft[15&i];if(!s)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,s,void 0,e,n)}constructor(t,e=16,n=Float64Array,o=ArrayBuffer,i,r=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=r;let s=t,a=s;this._levelBounds=[4*s];do{s=Math.ceil(s/this.nodeSize),a+=s,this._levelBounds.push(4*a)}while(1!==s);this.ArrayType=n,this.IndexArrayType=a<16384?Uint16Array:Uint32Array;const c=Ft.indexOf(n),l=4*a*n.BYTES_PER_ELEMENT;if(c<0)throw new Error(`Unexpected typed array class: ${n}.`);const d=n,h=this.IndexArrayType;if(i)this.data=i,this._boxes=new d(i,r+8,4*a),this._indices=new h(i,r+8+l,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 n=this.data=new o(8+l+a*this.IndexArrayType.BYTES_PER_ELEMENT);this._boxes=new d(n,8,4*a),this._indices=new h(n,8+l,a),this._pos=0,this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0,new Uint8Array(n,0,2).set([251,48+c]),new Uint16Array(n,2,1)[0]=e,new Uint32Array(n,4,1)[0]=t}this._queue=new zt}add(t,e,n=t,o=e){const i=this._pos,r=i>>2,s=this._boxes;return this._indices[r]=r,s[i]=t,s[i+1]=e,s[i+2]=n,s[i+3]=o,this._pos=i+4,t<this.minX&&(this.minX=t),e<this.minY&&(this.minY=e),n>this.maxX&&(this.maxX=n),o>this.maxY&&(this.maxY=o),r}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{numItems:e,minX:n,minY:o,nodeSize:i,_indices:r,_levelBounds:s}=this,a=this.maxX-n||1,c=this.maxY-o||1,l=new Int32Array(e),d=65535/a,h=65535/c;for(let i=0,r=0;i<e;i++){const e=t[r++],s=t[r++],a=d*((e+t[r++])/2-n)|0,c=h*((s+t[r++])/2-o)|0;l[i]=Yt(a,c)}!function(t,e,n,o,i,r){const s=[o,i];for(;s.length;){const o=s.pop()||0,i=s.pop()||0;if(o-i<=r&&Math.floor(i/r)>=Math.floor(o/r))continue;const a=t[i],c=t[i+o>>1],l=t[o],d=a>c!=a>l?a:c<a!=c<l?c:l;let h=i-1,u=o+1;for(;;){do{h++}while(t[h]<d);do{u--}while(t[u]>d);if(h>=u)break;$t(t,e,n,h,u)}s.push(i,u,u+1,o)}}(l,t,r,0,e-1,i);let u=4*e;for(let e=0,n=0;e<s.length-1;e++){const o=s[e];for(;n<o;){const e=n;let s=t[n++],a=t[n++],c=t[n++],l=t[n++];for(let e=1;e<i&&n<o;e++)s=Math.min(s,t[n++]),a=Math.min(a,t[n++]),c=Math.max(c,t[n++]),l=Math.max(l,t[n++]);r[u>>2]=e,t[u++]=s,t[u++]=a,t[u++]=c,t[u++]=l}}this._pos=u}search(t,e,n,o,i){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");const{_boxes:r,_levelBounds:s,_indices:a,nodeSize:c}=this,l=4*this.numItems;let d=r.length-4,h=s.length-1;const u=[],p=[];let m=!1;for(;void 0!==d;){const g=Math.min(d+4*c,s[h]),f=d>=l;if(m)this._collectContained(d,g,h,l,p,i);else for(let s=d;s<g;s+=4){const c=r[s];if(n<c)continue;const l=r[s+1];if(o<l)continue;const d=r[s+2];if(t>d)continue;const m=r[s+3];if(e>m)continue;const g=0|a[s>>2];if(f){const i=+(t<=c&&e<=l&&n>=d&&o>=m);u.push(g|i,h-1)}else(void 0===i||i(g,c,l,d,m))&&p.push(g)}h=u.pop(),d=u.pop(),void 0!==d&&(m=!(1&~d),d&=-2)}return p}_collectContained(t,e,n,o,i,r){const s=this._boxes,a=this._indices;let c=t;for(let t=n;t>0;t--)c=a[c>>2];const l=Math.min(c+(e-t)*this.nodeSize**n,o);if(void 0===r)for(;c<l;c+=4)i.push(0|a[c>>2]);else for(;c<l;c+=4){const t=0|a[c>>2];r(t,s[c],s[c+1],s[c+2],s[c+3])&&i.push(t)}}neighbors(t,e,n=1/0,o=1/0,i){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");const{_boxes:r,_levelBounds:s,_indices:a,_queue:c,nodeSize:l}=this,d=4*this.numItems,h=4*l,u=[],p=1===n;let m=o*o;for(c.push(r.length-4<<1,0);c.length;){const o=c.ids[0];if(1&o){if(c.pop(),u.push(o>>1),u.length===n)break;continue}c.pop();const l=o>>1,g=l<d,f=Math.min(l+h,jt(l,s));for(let n=l;n<f;n+=4){const o=r[n],s=r[n+1],l=r[n+2],d=r[n+3],h=Math.max(Math.max(o-t,t-l),0),u=Math.max(Math.max(s-e,e-d),0),f=h*h+u*u;if(f>m)continue;const y=0|a[n>>2];g?(void 0===i||i(y))&&(c.push(y<<1|1,f),p&&f<m&&(m=f)):c.push(y<<1,f)}}return c.clear(),u}};function jt(t,e){let n=0,o=e.length-1;for(;n<o;){const i=n+o>>1;e[i]>t?o=i:n=i+1}return e[n]}function $t(t,e,n,o,i){const r=t[o];t[o]=t[i],t[i]=r;const s=4*o,a=4*i,c=e[s],l=e[s+1],d=e[s+2],h=e[s+3];e[s]=e[a],e[s+1]=e[a+1],e[s+2]=e[a+2],e[s+3]=e[a+3],e[a]=c,e[a+1]=l,e[a+2]=d,e[a+3]=h;const u=n[o];n[o]=n[i],n[i]=u}function Yt(t,e){let n=t^e,o=65535^n,i=65535^(t|e),r=t&(65535^e),s=n|o>>1,a=n>>1^n,c=i^i>>1^o&r>>1,l=r^n&i>>1^r>>1;return n=s&s>>2^a&a>>2,o=s&a>>2^a&(s^a)>>2,i=c^s&c>>2^a&l>>2,r=l^a&c>>2^(s^a)&l>>2,s=n&n>>4^o&o>>4,a=n&o>>4^o&(n^o)>>4,c=i^n&i>>4^o&r>>4,l=r^o&i>>4^(n^o)&r>>4,i=c^s&c>>8^a&l>>8,r=l^a&c>>8^(s^a)&l>>8,i^=i>>1,r^=r>>1,n=t^e,o=r|65535^(n|i),n=16711935&(n|n<<8),n=252645135&(n|n<<4),n=858993459&(n|n<<2),n=1431655765&(n|n<<1),o=16711935&(o|o<<8),o=252645135&(o|o<<4),o=858993459&(o|o<<2),o=1431655765&(o|o<<1),((o<<1|n)>>>0)-2147483648}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}],Wt={"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)},Ht={"x-":{x:-1,y:0},"x+":{x:1,y:0},"y-":{x:0,y:-1},"y+":{x:0,y:1}},Gt=(t,e)=>{const{dir:n,amt:o}=e,i=Ht[n];return t.map(t=>({x:t.x+i.x*o,y:t.y+i.y*o}))},Ut=1e-4;function Zt(t){const e=[];for(const n of t)for(const t of Vt){let o={x:n.center.x+n.width*t.startX,y:n.center.y+n.height*t.startY},i={x:n.center.x+n.width*t.endX,y:n.center.y+n.height*t.endY};o.x>i.x&&([o,i]=[i,o]),Math.abs(o.x-i.x)<Ut&&o.y>i.y&&([o,i]=[i,o]);for(const r of n.availableZ)e.push({parent:n,start:o,end:i,facingDirection:t.facingDirection,z:r})}return e}var qt=class extends kt{constructor(t){super(),this.input=t;const e=this.input.targetMeshNodes??this.input.allMeshNodes,n=new Set(e.map(t=>t.capacityMeshNodeId)),o=this.input.allMeshNodes.filter(t=>!n.has(t.capacityMeshNodeId));this.unprocessedEdges=Zt(e),this.allEdges=[...this.unprocessedEdges,...Zt(o)],this.edgeSpatialIndex=new Bt(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()}input;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-Ut,t.start.y-Ut,t.end.x+Ut,t.end.y+Ut).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,o=Math.abs(t.start.x-t.end.x)<Xt;if(!n&&!o)return[];const i=n?"x":"y",r=n?"y":"x",s=t.start[r],a=t.start[i],c=t.end[i],l=Math.min(a,c),d=Math.max(a,c),h=t=>Math.max(l,Math.min(d,t)),u=[];for(const n of e){if(n===t)continue;const e=Math.abs(n.start.y-n.end.y)<Xt,o=Math.abs(n.start.x-n.end.x)<Xt;if("x"===i&&!e)continue;if("y"===i&&!o)continue;if(Math.abs(n.start[r]-s)>Xt)continue;const a=Math.min(n.start[i],n.end[i]),c=Math.max(n.start[i],n.end[i]),l=h(a),d=h(c);d-l>Xt&&u.push({s:l,e:d})}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 m=[];let g=l;for(const t of p)if(t.s>g+Xt&&m.push({s:g,e:t.s}),g=Math.max(g,t.e),g>=d-Xt)break;return d>g+Xt&&m.push({s:g,e:d}),0===m.length?[]:m.filter(t=>t.e-t.s>Xt).map(e=>{const n="x"===i?{x:e.s,y:s}:{x:s,y:e.s},o="x"===i?{x:e.e,y:s}:{x:s,y:e.e};return{parent:t.parent,facingDirection:t.facingDirection,start:n,end:o,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:[],infiniteLines:[],polygons:[],arrows:[],texts:[]};for(const e of this.input.allMeshNodes)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:Gt([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:Gt([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:Gt([e.start,e.end],{dir:e.facingDirection,amt:-.05}),strokeColor:"green",strokeDash:"2 2"});return t}};function Jt(t,e,n=0,o=t.length-1,i=Qt){for(;o>n;){if(o-n>600){const r=o-n+1,s=e-n+1,a=Math.log(r),c=.5*Math.exp(2*a/3),l=.5*Math.sqrt(a*c*(r-c)/r)*(s-r/2<0?-1:1);Jt(t,e,Math.max(n,Math.floor(e-s*c/r+l)),Math.min(o,Math.floor(e+(r-s)*c/r+l)),i)}const r=t[e];let s=n,a=o;for(Kt(t,n,e),i(t[o],r)>0&&Kt(t,n,o);s<a;){for(Kt(t,s,a),s++,a--;i(t[s],r)<0;)s++;for(;i(t[a],r)>0;)a--}0===i(t[n],r)?Kt(t,n,a):(a++,Kt(t,a,o)),a<=e&&(n=a+1),e<=a&&(o=a-1)}}function Kt(t,e,n){const o=t[e];t[e]=t[n],t[n]=o}function Qt(t,e){return t<e?-1:t>e?1:0}var te=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(!ue(t,e))return n;const o=this.toBBox,i=[];for(;e;){for(let r=0;r<e.children.length;r++){const s=e.children[r],a=e.leaf?o(s):s;ue(t,a)&&(e.leaf?n.push(s):he(t,a)?this._all(s,n):i.push(s))}e=i.pop()}return n}collides(t){let e=this.data;if(!ue(t,e))return!1;const n=[];for(;e;){for(let o=0;o<e.children.length;o++){const i=e.children[o],r=e.leaf?this.toBBox(i):i;if(ue(t,r)){if(e.leaf||he(t,r))return!0;n.push(i)}}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=pe([]),this}remove(t,e){if(!t)return this;let n=this.data;const o=this.toBBox(t),i=[],r=[];let s,a,c;for(;n||i.length;){if(n||(n=i.pop(),a=i[i.length-1],s=r.pop(),c=!0),n.leaf){const o=ee(t,n.children,e);if(-1!==o)return n.children.splice(o,1),i.push(n),this._condense(i),this}c||n.leaf||!he(n,o)?a?(s++,n=a.children[s],c=!1):n=null:(i.push(n),r.push(s),s=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,o){const i=n-e+1;let r,s=this._maxEntries;if(i<=s)return r=pe(t.slice(e,n+1)),ne(r,this.toBBox),r;o||(o=Math.ceil(Math.log(i)/Math.log(s)),s=Math.ceil(i/Math.pow(s,o-1))),r=pe([]),r.leaf=!1,r.height=o;const a=Math.ceil(i/s),c=a*Math.ceil(Math.sqrt(s));me(t,e,n,c,this.compareMinX);for(let i=e;i<=n;i+=c){const e=Math.min(i+c-1,n);me(t,i,e,a,this.compareMinY);for(let n=i;n<=e;n+=a){const i=Math.min(n+a-1,e);r.children.push(this._build(t,n,i,o-1))}}return ne(r,this.toBBox),r}_chooseSubtree(t,e,n,o){for(;o.push(e),!e.leaf&&o.length-1!==n;){let n,o=1/0,i=1/0;for(let r=0;r<e.children.length;r++){const s=e.children[r],a=ae(s),c=le(t,s)-a;c<i?(i=c,o=a<o?a:o,n=s):c===i&&a<o&&(o=a,n=s)}e=n||e.children[0]}return e}_insert(t,e,n){const o=n?t:this.toBBox(t),i=[],r=this._chooseSubtree(o,this.data,e,i);for(r.children.push(t),ie(r,o);e>=0&&i[e].children.length>this._maxEntries;)this._split(i,e),e--;this._adjustParentBBoxes(o,i,e)}_split(t,e){const n=t[e],o=n.children.length,i=this._minEntries;this._chooseSplitAxis(n,i,o);const r=this._chooseSplitIndex(n,i,o),s=pe(n.children.splice(r,n.children.length-r));s.height=n.height,s.leaf=n.leaf,ne(n,this.toBBox),ne(s,this.toBBox),e?t[e-1].children.push(s):this._splitRoot(n,s)}_splitRoot(t,e){this.data=pe([t,e]),this.data.height=t.height+1,this.data.leaf=!1,ne(this.data,this.toBBox)}_chooseSplitIndex(t,e,n){let o,i=1/0,r=1/0;for(let s=e;s<=n-e;s++){const e=oe(t,0,s,this.toBBox),a=oe(t,s,n,this.toBBox),c=de(e,a),l=ae(e)+ae(a);c<i?(i=c,o=s,r=l<r?l:r):c===i&&l<r&&(r=l,o=s)}return o||n-e}_chooseSplitAxis(t,e,n){const o=t.leaf?this.compareMinX:re,i=t.leaf?this.compareMinY:se;this._allDistMargin(t,e,n,o)<this._allDistMargin(t,e,n,i)&&t.children.sort(o)}_allDistMargin(t,e,n,o){t.children.sort(o);const i=this.toBBox,r=oe(t,0,e,i),s=oe(t,n-e,n,i);let a=ce(r)+ce(s);for(let o=e;o<n-e;o++){const e=t.children[o];ie(r,t.leaf?i(e):e),a+=ce(r)}for(let o=n-e-1;o>=e;o--){const e=t.children[o];ie(s,t.leaf?i(e):e),a+=ce(s)}return a}_adjustParentBBoxes(t,e,n){for(let o=n;o>=0;o--)ie(e[o],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():ne(t[n],this.toBBox)}};function ee(t,e,n){if(!n)return e.indexOf(t);for(let o=0;o<e.length;o++)if(n(t,e[o]))return o;return-1}function ne(t,e){oe(t,0,t.children.length,e,t)}function oe(t,e,n,o,i){i||(i=pe(null)),i.minX=1/0,i.minY=1/0,i.maxX=-1/0,i.maxY=-1/0;for(let r=e;r<n;r++){const e=t.children[r];ie(i,t.leaf?o(e):e)}return i}function ie(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 re(t,e){return t.minX-e.minX}function se(t,e){return t.minY-e.minY}function ae(t){return(t.maxX-t.minX)*(t.maxY-t.minY)}function ce(t){return t.maxX-t.minX+(t.maxY-t.minY)}function le(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 de(t,e){const n=Math.max(t.minX,e.minX),o=Math.max(t.minY,e.minY),i=Math.min(t.maxX,e.maxX),r=Math.min(t.maxY,e.maxY);return Math.max(0,i-n)*Math.max(0,r-o)}function he(t,e){return t.minX<=e.minX&&t.minY<=e.minY&&e.maxX<=t.maxX&&e.maxY<=t.maxY}function ue(t,e){return e.minX<=t.maxX&&e.minY<=t.maxY&&e.maxX>=t.minX&&e.maxY>=t.minY}function pe(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function me(t,e,n,o,i){const r=[e,n];for(;r.length;){if((n=r.pop())-(e=r.pop())<=o)continue;const s=e+Math.ceil((n-e)/o/2)*o;Jt(t,s,e,n,i),r.push(e,s,s,n)}}var ge=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))});function fe(t,e,n,o){const i=ye(t,e,n),r=ye(t,e,o),s=ye(n,o,t),a=ye(n,o,e);return i!==r&&s!==a||(!(0!==i||!_e(t,n,e))||(!(0!==r||!_e(t,o,e))||(!(0!==s||!_e(n,t,o))||!(0!==a||!_e(n,e,o)))))}function ye(t,e,n){const o=(e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y);return 0===o?0:o>0?1:2}function _e(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 be(t,e,n){const o=(n.x-e.x)**2+(n.y-e.y)**2;if(0===o)return xe(t,e);let i=((t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y))/o;i=Math.max(0,Math.min(1,i));return xe(t,{x:e.x+i*(n.x-e.x),y:e.y+i*(n.y-e.y)})}function xe(t,e){const n=t.x-e.x,o=t.y-e.y;return Math.sqrt(n*n+o*o)}function ve(t,e,n,o){const i=e.x-t.x,r=e.y-t.y,s=o.x-n.x,a=o.y-n.y,c=t.x-n.x,l=t.y-n.y,d=i*a-r*s;if(Math.abs(d)<1e-10)return null;const h=(l*s-c*a)/d,u=(i*l-r*c)/d,p=1e-9;if(h>=-1e-9&&h<=1+p&&u>=-1e-9&&u<=1+p){return{x:t.x+h*i,y:t.y+h*r}}return null}var Se=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}},Ie=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}],Ce=t=>{const e=[];for(let n=0;n<t.length;n++){const o=t[n],i=t[(n+1)%t.length];e.push([o,i])}return e},Pe=(t,e,n)=>{const o=(t.y-e.y)*(n.x-e.x)-(t.x-e.x)*(n.y-e.y);if(Math.abs(o)>1e-9)return!1;const i=(t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y);if(i<0)return!1;const r=(n.x-e.x)**2+(n.y-e.y)**2;return 0!==r&&!(i>r)},Me=(t,e)=>t.x>=e.minX&&t.x<=e.maxX&&t.y>=e.minY&&t.y<=e.maxY,Ne=(t,e)=>{if(e.length<3)return!1;const n=Ce(e);for(const[e,o]of n)if(Pe(t,e,o))return!0;let o=!1;for(let n=0,i=e.length-1;n<e.length;i=n++){const r=e[n].x,s=e[n].y,a=e[i].x,c=e[i].y;s>t.y!=c>t.y&&t.x<(a-r)*(t.y-s)/(c-s)+r&&(o=!o)}return o},we=(t,e)=>{const n=Ie(t),o=[[n[0],n[1]],[n[1],n[2]],[n[2],n[3]],[n[3],n[0]]],i=Ce(e);for(const[t,e]of i)for(const[n,i]of o)if(fe(t,e,n,i))return!0;return!1},Te=(t,e)=>((t,e)=>!(e.length<3)&&(!!e.some(e=>Me(e,t))||(!!Ie(t).some(t=>Ne(t,e))||we(t,e))))(Se(t),e),Re=(t,e)=>((t,e)=>!(e.length<3)&&(!!Ie(t).every(t=>Ne(t,e))&&!we(t,e)))(Se(t),e);function Ee(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 Ae(t,e,n){return Math.max(e,Math.min(n,t))}function Oe(t,e,n,o){if(t.x===e.x&&t.y===e.y)return be(t,n,o);if(n.x===o.x&&n.y===o.y)return be(n,t,e);if(fe(t,e,n,o))return 0;const i=[be(t,n,o),be(e,n,o),be(n,t,e),be(o,t,e)];return Math.min(...i)}function ke(t,e,n){const o={x:n.minX,y:n.minY},i={x:n.maxX,y:n.minY},r={x:n.minX,y:n.maxY},s={x:n.maxX,y:n.maxY};if(fe(t,e,o,i)||fe(t,e,i,s)||fe(t,e,s,r)||fe(t,e,r,o))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=[be(o,t,e),be(i,t,e),be(r,t,e),be(s,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=Ae(t.x,n.minX,n.maxX),o=Ae(t.y,n.minY,n.maxY);a.push(xe(t,{x:e,y:o}))}if(e.x<n.minX||e.x>n.maxX||e.y<n.minY||e.y>n.maxY){const t=Ae(e.x,n.minX,n.maxX),o=Ae(e.y,n.minY,n.maxY);a.push(xe(e,{x:t,y:o}))}return Math.min(...a)}function Le(t,e,n){const o=n.width/2,i=n.height/2;return ke(t,e,{minX:n.center.x-o,maxX:n.center.x+o,minY:n.center.y-i,maxY:n.center.y+i})}function De(t,e,n){const o={x:n.x,y:n.y};if(t.x===e.x&&t.y===e.y)return Math.max(0,xe(t,o)-n.radius);const i=e.x-t.x,r=e.y-t.y,s=o.x-t.x,a=o.y-t.y,c=i*i+r*r,l=Math.max(0,Math.min(1,(i*s+r*a)/c)),d=xe({x:t.x+l*i,y:t.y+l*r},o);return Math.max(0,d-n.radius)}function ze(t,e,n){const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(0===r)return{x:e.x,y:e.y};let s=((t.x-e.x)*o+(t.y-e.y)*i)/r;s=Math.max(0,Math.min(1,s));return{x:e.x+s*o,y:e.y+s*i}}var Fe=(t,e)=>{const n=e.x-t.x,o=e.y-t.y,i=Math.sqrt(n**2+o**2);return{x:n/i,y:o/i}};function Be(t,e){const n=e.width/2,o=e.height/2,i=e.center.x-n,r=e.center.x+n,s=e.center.y-o,a=e.center.y+o;if(t.x>=i&&t.x<=r&&t.y>=s&&t.y<=a)return 0;return xe(t,{x:Ae(t.x,i,r),y:Ae(t.y,s,a)})}function je(t,e){if(t.x>=e.minX&&t.x<=e.maxX&&t.y>=e.minY&&t.y<=e.maxY)return 0;return xe(t,{x:Ae(t.x,e.minX,e.maxX),y:Ae(t.y,e.minY,e.maxY)})}function $e(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}function Ye(t,e){const n=t.x-e.x,o=t.y-e.y;return n*n+o*o}var Xe=(t,e)=>!(t.maxX<e.minX||e.maxX<t.minX||t.maxY<e.minY||e.maxY<t.minY),Ve=t=>{const{center:e,width:n,height:o}=t,i=n/2,r=o/2;return{minX:e.x-i,maxX:e.x+i,minY:e.y-r,maxY:e.y+r}},We=t=>{if(0===t.length)return null;let e=t[0].x,n=t[0].y,o=t[0].x,i=t[0].y;for(let r=1;r<t.length;r++){const s=t[r];s.x<e&&(e=s.x),s.y<n&&(n=s.y),s.x>o&&(o=s.x),s.y>i&&(i=s.y)}return{minX:e,minY:n,maxX:o,maxY:i}},He=1e-4,Ge=class extends kt{constructor(t){super(),this.input=t,this.unprocessedSegments=[...this.input.segmentsWithAdjacentEmptySpace],this.rectSpatialIndex=new te,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})))}input;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}=Wt[t.facingDirection],o=t.end.x-t.start.x,i=t.end.y-t.start.y,r=Math.sqrt(o**2+i**2),s=o/r,a=i/r;let c=null,l=1;const d={x:t.start.x+e*He+s*He*10,y:t.start.y+n*He+a*He*10},h={x:t.end.x+e*He-s*He*10,y:t.end.y+n*He-a*He*10};for(this.lastSearchCorner1=d,this.lastSearchCorner2=h;(!c||0===c.length)&&l<1e3;){const o=ge([d,h,{x:d.x+e*l,y:d.y+n*l},{x:h.x+e*l,y:h.y+n*l}]);this.lastSearchBounds=o,c=this.rectSpatialIndex.search(o).filter(e=>e.availableZ.includes(t.z)).filter(e=>e.capacityMeshNodeId!==t.parent.capacityMeshNodeId),l*=4}if(!c||0===c.length)return;this.lastCollidingNodes=c;let u=1/0;for(const e of c){const n=Le(t.start,t.end,e);n<u&&(u=n)}const p=u,m=ge([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}]),g={x:(m.minX+m.maxX)/2,y:(m.minY+m.maxY)/2},f=m.maxX-m.minX,y=m.maxY-m.minY,_={segment:t,newNode:{capacityMeshNodeId:`new-${t.parent.capacityMeshNodeId}-${this.expandedSegments.length}`,center:g,width:f,height:y,availableZ:[t.z],layer:t.parent.layer}};this.lastExpandedSegment=_,f<He||y<He||(this.expandedSegments.push(_),this.rectSpatialIndex.insert({..._.newNode,...m}))}getOutput(){return{expandedSegments:this.expandedSegments}}visualize(){const t={title:"ExpandEdgesToEmptySpace",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],infiniteLines:[],polygons:[],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}},Ue=class extends Dt{findSegmentsWithAdjacentEmptySpaceSolver;expandEdgesToEmptySpaceSolver;outputNodes=[];passExpandedCounts=[];currentPassNodes=[];currentTargetNodes=[];currentPassIndex=0;expandedNodeIds=new Set;maxGapFillPasses=1;pipelineDef=[Lt("findSegmentsWithAdjacentEmptySpaceSolver",qt,t=>[{allMeshNodes:t.currentPassNodes,targetMeshNodes:t.currentTargetNodes}],{onSolved:()=>{}}),Lt("expandEdgesToEmptySpaceSolver",Ge,t=>[{inputMeshNodes:t.currentPassNodes,segmentsWithAdjacentEmptySpace:t.findSegmentsWithAdjacentEmptySpaceSolver.getOutput().segmentsWithAdjacentEmptySpace,boardVoid:t.inputProblem.boardVoid}],{onSolved:t=>{t.completePass()}})];_setup(){this.outputNodes=[...this.inputProblem.meshNodes],this.currentPassNodes=[...this.inputProblem.meshNodes],this.currentTargetNodes=[...this.inputProblem.meshNodes],this.passExpandedCounts=[],this.currentPassIndex=0,this.expandedNodeIds.clear();const t=this.inputProblem.maxGapFillPasses;this.maxGapFillPasses=Number.isFinite(t)?Math.max(1,Math.floor(t)):1}completePass(){const t=(this.expandEdgesToEmptySpaceSolver?.getOutput().expandedSegments??[]).map(t=>t.newNode);for(const e of t)this.expandedNodeIds.add(e.capacityMeshNodeId);this.passExpandedCounts.push(t.length),this.currentPassNodes=[...this.currentPassNodes,...t],this.currentTargetNodes=t,this.outputNodes=this.currentPassNodes,0===t.length||this.currentPassIndex+1>=this.maxGapFillPasses||(this.currentPassIndex+=1,this.currentPipelineStageIndex=-1)}getOutput(){return{outputNodes:this.outputNodes.length?this.outputNodes:this.inputProblem.meshNodes}}initialVisualize(){const t={title:"GapFillSolverPipeline - Initial",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],infiniteLines:[],polygons:[],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:[],infiniteLines:[],polygons:[],arrows:[],texts:[]},{outputNodes:e}=this.getOutput();for(const n of e){const e=this.expandedNodeIds.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}};function Ze(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 qe(t){const e=function(t){return Array.from(new Set(t)).sort((t,e)=>{const n=Ze(t),o=Ze(e);return n!==o?n-o:t.localeCompare(e)})}((t.obstacles??[]).flatMap(t=>t.layers??[])),n=Math.max(1,t.layerCount||e.length||1),o=Array.from({length:n},(t,e)=>0===e?"top":e===n-1?"bottom":`inner${e}`),i=[],r=new Set,s=t=>{const e=t.toLowerCase();r.has(e)||(r.add(e),i.push(t))};o.forEach(s),e.forEach(s);const a=i.slice(0,n),c=new Map;return a.forEach((t,e)=>c.set(t.toLowerCase(),e)),i.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 Je(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 Ke(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 Qe=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]},tn=1e-9,en=(t,e)=>t>e+tn,nn=(t,e)=>t>e-tn,on=(t,e)=>t<e-tn,rn=(t,e)=>t<e+tn;function sn(t,e){return!(t.x+t.width<=e.x+tn||e.x+e.width<=t.x+tn||t.y+t.height<=e.y+tn||e.y+e.height<=t.y+tn)}function an(t,e){const n=e.x,o=e.x+e.width,i=e.y,r=e.y+e.height;if(t.x>=n&&t.x<=o&&t.y>=i&&t.y<=r)return Math.min(t.x-n,o-t.x,t.y-i,r-t.y);const s=t.x<n?n-t.x:t.x>o?t.x-o:0,a=t.y<i?i-t.y:t.y>r?t.y-r:0;return 0===s?a:0===a?s:Math.hypot(s,a)}function cn(t,e){const n=Math.max(t[0],e[0]),o=Math.min(t[1],e[1]);return o>n+tn?[n,o]:null}function ln(t,e){if(!sn(t,e))return[t];const n=cn([t.x,t.x+t.width],[e.x,e.x+e.width]),o=cn([t.y,t.y+t.height],[e.y,e.y+e.height]);if(!n||!o)return[t];const[i,r]=n,[s,a]=o,c=[];i>t.x+tn&&c.push({x:t.x,y:t.y,width:i-t.x,height:t.height}),t.x+t.width>r+tn&&c.push({x:r,y:t.y,width:t.x+t.width-r,height:t.height});const l=Math.max(0,r-i);return l>tn&&s>t.y+tn&&c.push({x:i,y:t.y,width:l,height:s-t.y}),l>tn&&t.y+t.height>a+tn&&c.push({x:i,y:a,width:l,height:t.y+t.height-a}),c.filter(t=>t.width>tn&&t.height>tn)}var dn=(t,e)=>!e||e<=0?t:{x:t.x-e,y:t.y-e,width:t.width+2*e,height:t.height+2*e},hn=t=>({x:t.center.x-t.width/2,y:t.center.y-t.height/2,width:t.width,height:t.height}),un=t=>t.width*t.height,pn=t=>({...t,center:{...t.center},availableZ:[...t.availableZ]}),mn=(t,e,n)=>({...t,capacityMeshNodeId:n,center:{x:e.x+e.width/2,y:e.y+e.height/2},width:e.width,height:e.height,availableZ:[...t.availableZ],layer:`z${t.availableZ.join(",")}`}),gn=t=>!t._containsObstacle&&!t._containsTarget,fn=(t,e)=>1===t.availableZ.length&&t.availableZ[0]===e,yn=(t,e)=>Math.abs(t.x-e.x)<=tn&&Math.abs(t.y-e.y)<=tn&&Math.abs(t.width-e.width)<=tn&&Math.abs(t.height-e.height)<=tn,_n=(t,e)=>{let n=[t];for(const t of e){if(0===n.length)return n;const e=[];for(const o of n)e.push(...ln(o,t));n=e}return n},bn=(t,e)=>0===_n(t,e).length,xn=class extends kt{constructor(t){super(),this.input=t}input;outputNodes=[];promotedNodeIds=new Set;residualNodeIds=new Set;_setup(){this.outputNodes=this.input.meshNodes.map(pn),this.promotedNodeIds.clear(),this.residualNodeIds.clear()}_step(){this.outputNodes=this.processOuterLayerContainmentMerges(),this.solved=!0}processOuterLayerContainmentMerges(){const t=this.input.simpleRouteJson,e=Math.max(1,t.layerCount||1);if(e<3)return this.input.meshNodes.map(pn);const n=e-1,o=Math.max(t.minViaDiameter??0,t.minTraceWidth||0),i=this.input.meshNodes.map(pn),r=this.buildObstaclesByLayer(e),s=i.filter(t=>gn(t)&&(fn(t,0)||fn(t,n))),a=i.filter(t=>!s.includes(t)),c=new Map;c.set(0,i.filter(t=>gn(t)&&t.availableZ.includes(0)).map(hn)),c.set(n,i.filter(t=>gn(t)&&t.availableZ.includes(n)).map(hn));const l=[],d=[],h=s.filter(t=>t.width+tn>=o&&t.height+tn>=o).sort((t,e)=>un(hn(e))-un(hn(t)));for(const t of h){const e=t.availableZ[0],o=0===e?n:0,i=hn(t),s=c.get(o)??[];this.isTransitCompatibleAcrossIntermediateLayers({rect:i,fromZ:e,toZ:o,obstaclesByLayer:r})&&(bn(i,s)&&(l.push({...t,availableZ:[0,n],layer:`z0,${n}`}),d.push(i),this.promotedNodeIds.add(t.capacityMeshNodeId)))}let u=0;const p=[];for(const t of s){if(this.promotedNodeIds.has(t.capacityMeshNodeId))continue;const e=hn(t),n=_n(e,d);if(1===n.length&&yn(n[0],e))p.push(t);else for(const e of n){const n=mn(t,e,`${t.capacityMeshNodeId}-outer-merge-${u++}`);p.push(n),this.residualNodeIds.add(n.capacityMeshNodeId)}}return[...a,...l,...p]}buildObstaclesByLayer(t){const e=Array.from({length:t},()=>[]);for(const n of this.input.simpleRouteJson.obstacles??[]){const o=Ke(n);if(!o)continue;const i=dn(o,this.input.obstacleClearance??0),r=Je(n,this.input.zIndexByName);for(const o of r)o<0||o>=t||e[o].push({obstacle:n,rect:i})}return e}isTransitCompatibleAcrossIntermediateLayers(t){const{rect:e,fromZ:n,toZ:o,obstaclesByLayer:i}=t,r=Math.min(n,o),s=Math.max(n,o);if(s-r<2)return!1;for(let t=r+1;t<s;t++){const n=(i[t]??[]).filter(t=>sn(t.rect,e));if(0===n.length)return!1;if(n.some(t=>!t.obstacle.isCopperPour))return!1;const o=n.filter(t=>t.obstacle.isCopperPour).map(t=>t.rect);if(!bn(e,o))return!1}return!0}getOutput(){return{outputNodes:this.outputNodes}}visualize(){return{title:"OuterLayerContainmentMergeSolver",coordinateSystem:"cartesian",rects:this.outputNodes.map(t=>{const e=Qe(t.availableZ),n=this.promotedNodeIds.has(t.capacityMeshNodeId),o=this.residualNodeIds.has(t.capacityMeshNodeId);return{center:t.center,width:t.width,height:t.height,stroke:n?"rgba(22, 163, 74, 0.95)":o?"rgba(37, 99, 235, 0.95)":e.stroke,fill:t._containsObstacle?"rgba(239, 68, 68, 0.35)":n?"rgba(34, 197, 94, 0.28)":o?"rgba(59, 130, 246, 0.18)":e.fill,layer:`z${t.availableZ.join(",")}`,label:[`node ${t.capacityMeshNodeId}`,`z:${t.availableZ.join(",")}`].join("\n")}}),points:[],lines:[],texts:[]}}},vn=1e-9,Sn=t=>Math.abs(t.rect.x+t.rect.width/2-t.startX)<vn&&Math.abs(t.rect.y+t.rect.height/2-t.startY)<vn&&Math.abs(t.rect.width-t.initialW)<vn&&Math.abs(t.rect.height-t.initialH)<vn,In=({rect:t,bounds:e})=>({x:t.x,y:t.y,width:e.x+e.width-t.x,height:t.height}),Cn=({rect:t,bounds:e})=>({x:t.x,y:t.y,width:t.width,height:e.y+e.height-t.y}),Pn=({rect:t,bounds:e})=>({x:e.x,y:t.y,width:t.x-e.x,height:t.height}),Mn=({rect:t,bounds:e})=>({x:t.x,y:e.y,width:t.width,height:t.y-e.y}),Nn=(t,e=1e-6)=>Math.round(t/e)*e,wn=t=>({x:Nn(t.x),y:Nn(t.y),width:Nn(t.width),height:Nn(t.height)});function Tn(t){const{r:e,bounds:n,blockers:o,maxAspect:i}=t;let r=n.x+n.width-e.x;for(const t of o){if(e.y+e.height>t.y+tn&&t.y+t.height>e.y+tn)if(nn(t.x,e.x+e.width))r=Math.min(r,t.x-e.x);else if(t.x+t.width>e.x+e.width-tn&&t.x<e.x+e.width+tn)return 0}let s=Math.max(0,r-e.width);if(s<=0)return 0;if(null!=i){const t=e.width,n=e.height;t>=n&&(s=Math.min(s,i*n-t))}return Math.max(0,s)}function Rn(t){const{r:e,bounds:n,blockers:o,maxAspect:i}=t;let r=n.y+n.height-e.y;for(const t of o){if(e.x+e.width>t.x+tn&&t.x+t.width>e.x+tn)if(nn(t.y,e.y+e.height))r=Math.min(r,t.y-e.y);else if(t.y+t.height>e.y+e.height-tn&&t.y<e.y+e.height+tn)return 0}let s=Math.max(0,r-e.height);if(s<=0)return 0;if(null!=i){const t=e.width,n=e.height;n>=t&&(s=Math.min(s,i*t-n))}return Math.max(0,s)}function En(t){const{r:e,bounds:n,blockers:o,maxAspect:i}=t;let r=n.x;for(const t of o){if(e.y+e.height>t.y+tn&&t.y+t.height>e.y+tn)if(rn(t.x+t.width,e.x))r=Math.max(r,t.x+t.width);else if(t.x<e.x+tn&&t.x+t.width>e.x-tn)return 0}let s=Math.max(0,e.x-r);if(s<=0)return 0;if(null!=i){const t=e.width,n=e.height;t>=n&&(s=Math.min(s,i*n-t))}return Math.max(0,s)}function An(t){const{r:e,bounds:n,blockers:o,maxAspect:i}=t;let r=n.y;for(const t of o){if(e.x+e.width>t.x+tn&&t.x+t.width>e.x+tn)if(rn(t.y+t.height,e.y))r=Math.max(r,t.y+t.height);else if(t.y<e.y+tn&&t.y+t.height>e.y-tn)return 0}let s=Math.max(0,e.y-r);if(s<=0)return 0;if(null!=i){const t=e.width,n=e.height;n>=t&&(s=Math.min(s,i*t-n))}return Math.max(0,s)}var On=t=>{const{rect:e,seen:n,blockers:o}=t;n.has(e)||(n.add(e),o.push(e))};function kn(t){const{startX:e,startY:n,gridSize:o,bounds:i,obsticalIndexByLayer:r,placedIndexByLayer:s,initialCellRatio:a,maxAspectRatio:c,minReq:l}=t,d=Math.max(1e-9,o*a),h=Math.max(d,l.width),u=Math.max(d,l.height),p=[],m=new Set,g=s.length,f=o=>{const a=(t=>{const{bounds:e,rect:n}=t,o=Math.max(e.x,n.x),i=Math.max(e.y,n.y),r=Math.min(e.x+e.width,n.x+n.width),s=Math.min(e.y+e.height,n.y+n.height);return r<=o+tn||s<=i+tn?null:{minX:o,minY:i,maxX:r,maxY:s}})({bounds:i,rect:o});if(a)for(const o of t.zLayers){const t=r[o];if(t)for(const e of t.search(a))On({rect:e,seen:m,blockers:p});const i=s[o];if(i)for(const t of i.search(a)){t.zLayers.length>=g&&(Sn({rect:t,startX:e,startY:n,initialW:h,initialH:u})||On({rect:t,seen:m,blockers:p}))}}},y=[{ox:0,oy:0},{ox:-h,oy:0},{ox:0,oy:-u},{ox:-h,oy:-u},{ox:-h/2,oy:-u/2}];let _=null,b=0;t:for(const t of y){let o={x:e+t.ox,y:n+t.oy,width:h,height:u};if(f(o),on(o.x,i.x)||on(o.y,i.y)||en(o.x+o.width,i.x+i.width)||en(o.y+o.height,i.y+i.height))continue;for(const t of p)if(sn(o,t))continue t;const r=1e-6,s=1e3;let a=!0,d=0;for(;a&&d<s;){d++,a=!1;const t={bounds:i,blockers:p,maxAspect:c};f(In({rect:o,bounds:i}));const e=Tn({...t,r:o});e>r&&(o={...o,width:o.width+e},f(o),a=!0),f(Cn({rect:o,bounds:i}));const n=Rn({...t,r:o});n>r&&(o={...o,height:o.height+n},f(o),a=!0),f(Pn({rect:o,bounds:i}));const s=En({...t,r:o});s>r&&(o={x:o.x-s,y:o.y,width:o.width+s,height:o.height},f(o),a=!0),f(Mn({rect:o,bounds:i}));const l=An({...t,r:o});l>r&&(o={x:o.x,y:o.y-l,width:o.width,height:o.height+l},f(o),a=!0)}if(o.width+tn>=l.width&&o.height+tn>=l.height){const t=o.width*o.height;t>b&&(_=wn(o),b=t)}}return _}function Ln(t){const e=Math.max(t.width,t.height);return[e/8,e/16,e/32]}function Dn(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 o=t.obstacleIndexByLayer[n],i=!!o&&o.collides(e),r=t.placedIndexByLayer[n],s=!!r&&r.collides(e);if(!i&&!s)return!1}return!0}function zn(t){const{x:e,y:n,z:o,layerCount:i,minSpan:r,maxSpan:s,obstacleIndexByLayer:a,additionalBlockersByLayer:c}=t,l=t=>{const o={minX:e,minY:n,maxX:e,maxY:n},i=a[t];if(i&&i.collides(o))return!1;return!(c?.[t]??[]).some(t=>{return(i={x:e,y:n}).x>=(o=t).x-tn&&i.x<=o.x+o.width+tn&&i.y>=o.y-tn&&i.y<=o.y+o.height+tn;var o,i})};let d=o,h=o;for(;d-1>=0&&l(d-1);)d--;for(;h+1<i&&l(h+1);)h++;if("number"==typeof s){const t=((t,e,n)=>Math.max(e,Math.min(n,t)))(s,1,i);for(;h-d+1>t;)o-d>h-o?d++:h--}const u=[];for(let t=d;t<=h;t++)u.push(t);return u.length>=r?u:[]}var Fn=(t,e=1e-6)=>Math.round(t/e)*e;var Bn=(t,e=1e-6)=>Math.round(t/e)*e,jn=t=>"minX"in t?{x:t.minX,y:t.minY,width:t.maxX-t.minX,height:t.maxY-t.minY}:t;function $n(t){const{lineStart:e,lineEnd:n,coveringIntervals:o,minSegmentLength:i}=t,r=Bn(e),s=Bn(n),a=o.map(t=>{const e=Bn(t.start),n=Bn(t.end);return{start:Math.min(e,n),end:Math.max(e,n)}}).filter(t=>t.end>t.start+tn);if(0===a.length){return[{start:r,end:s,center:(r+s)/2}]}const c=[...a].sort((t,e)=>t.start-e.start),l=[];let d={...c[0]};for(let t=1;t<c.length;t++){const e=c[t];e.start<=d.end+tn?d.end=Math.max(d.end,e.end):(l.push(d),d={...e})}l.push(d);const h=[];if(l[0].start>r+tn){const t=r,e=l[0].start;e-t>=i&&h.push({start:t,end:e,center:(t+e)/2})}for(let t=0;t<l.length-1;t++){const e=l[t].end,n=l[t+1].start;n-e>=i&&h.push({start:e,end:n,center:(e+n)/2})}if(l[l.length-1].end<s-tn){const t=l[l.length-1].end,e=s;e-t>=i&&h.push({start:t,end:e,center:(t+e)/2})}return h}function Yn(t){const{bounds:e,minSize:n,layerCount:o,obstacleIndexByLayer:i,placedIndexByLayer:r,hardPlacedByLayer:s}=t,a=[],c=Math.max(.15*n,3*tn),l=new Set,d=Array.from({length:o},(t,e)=>[...i[e]?.all()??[],...s[e]??[]].map(jn));function h(t){const n=Bn(t.x),c=Bn(t.y),{z:h}=t,u=n,p=c;if(u<e.x+tn||p<e.y+tn||u>e.x+e.width-tn||p>e.y+e.height-tn)return;if(function(t){return Dn({layerCount:o,obstacleIndexByLayer:i,placedIndexByLayer:r,point:t})}({x:u,y:p}))return;const m=d[h]??[];let g=an({x:u,y:p},e);for(const t of m)g=Math.min(g,an({x:u,y:p},t));const f=Bn(g),y=(t=>`${t.z}|${t.x.toFixed(6)}|${t.y.toFixed(6)}`)({x:u,y:p,z:h});if(l.has(y))return;l.add(y);const _=zn({x:u,y:p,z:h,layerCount:o,minSpan:1,maxSpan:void 0,obstacleIndexByLayer:i,additionalBlockersByLayer:s});a.push({x:u,y:p,z:h,distance:f,zSpanLen:_.length,isEdgeSeed:!0})}for(let t=0;t<o;t++){const o=(d[t]??[]).map(t=>({x:Bn(t.x),y:Bn(t.y),width:Bn(t.width),height:Bn(t.height)})),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)h({x:e.x,y:e.y,z:t});const r=e.y+c,s=o.filter(t=>t.y<=r&&t.y+t.height>=r).map(t=>({start:Math.max(e.x,t.x),end:Math.min(e.x+e.width,t.x+t.width)})),a=$n({lineStart:e.x+c,lineEnd:e.x+e.width-c,coveringIntervals:s,minSegmentLength:.5*n});for(const e of a){const o=e.end-e.start;o>=n&&(h({x:e.center,y:r,z:t}),o>1.5*n&&(h({x:e.start+.4*n,y:r,z:t}),h({x:e.end-.4*n,y:r,z:t})))}const l=e.y+e.height-c,u=o.filter(t=>t.y<=l&&t.y+t.height>=l).map(t=>({start:Math.max(e.x,t.x),end:Math.min(e.x+e.width,t.x+t.width)})),p=$n({lineStart:e.x+c,lineEnd:e.x+e.width-c,coveringIntervals:u,minSegmentLength:.5*n});for(const e of p){const o=e.end-e.start;o>=n&&(h({x:e.center,y:l,z:t}),o>1.5*n&&(h({x:e.start+.4*n,y:l,z:t}),h({x:e.end-.4*n,y:l,z:t})))}const m=e.x+c,g=o.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)})),f=$n({lineStart:e.y+c,lineEnd:e.y+e.height-c,coveringIntervals:g,minSegmentLength:.5*n});for(const e of f){const o=e.end-e.start;o>=n&&(h({x:m,y:e.center,z:t}),o>1.5*n&&(h({x:m,y:e.start+.4*n,z:t}),h({x:m,y:e.end-.4*n,z:t})))}const y=e.x+e.width-c,_=o.filter(t=>t.x<=y&&t.x+t.width>=y).map(t=>({start:Math.max(e.y,t.y),end:Math.min(e.y+e.height,t.y+t.height)})),b=$n({lineStart:e.y+c,lineEnd:e.y+e.height-c,coveringIntervals:_,minSegmentLength:.5*n});for(const e of b){const o=e.end-e.start;o>=n&&(h({x:y,y:e.center,z:t}),o>1.5*n&&(h({x:y,y:e.start+.4*n,z:t}),h({x:y,y:e.end-.4*n,z:t})))}for(const i of o){const r=i.x-c;if(r>e.x+tn&&r<e.x+e.width-tn){const e=o.filter(t=>t!==i&&t.x<=r&&t.x+t.width>=r).map(t=>({start:Math.max(i.y,t.y),end:Math.min(i.y+i.height,t.y+t.height)})),s=$n({lineStart:i.y,lineEnd:i.y+i.height,coveringIntervals:e,minSegmentLength:.5*n});for(const e of s)h({x:r,y:e.center,z:t})}const s=i.x+i.width+c;if(s>e.x+tn&&s<e.x+e.width-tn){const e=o.filter(t=>t!==i&&t.x<=s&&t.x+t.width>=s).map(t=>({start:Math.max(i.y,t.y),end:Math.min(i.y+i.height,t.y+t.height)})),r=$n({lineStart:i.y,lineEnd:i.y+i.height,coveringIntervals:e,minSegmentLength:.5*n});for(const e of r)h({x:s,y:e.center,z:t})}const a=i.y-c;if(a>e.y+tn&&a<e.y+e.height-tn){const e=o.filter(t=>t!==i&&t.y<=a&&t.y+t.height>=a).map(t=>({start:Math.max(i.x,t.x),end:Math.min(i.x+i.width,t.x+t.width)})),r=$n({lineStart:i.x,lineEnd:i.x+i.width,coveringIntervals:e,minSegmentLength:.5*n});for(const e of r)h({x:e.center,y:a,z:t})}const l=i.y+i.height+c;if(l>e.y+tn&&l<e.y+e.height-tn){const e=o.filter(t=>t!==i&&t.y<=l&&t.y+t.height>=l).map(t=>({start:Math.max(i.x,t.x),end:Math.min(i.x+i.width,t.x+t.width)})),r=$n({lineStart:i.x,lineEnd:i.x+i.width,coveringIntervals:e,minSegmentLength:.5*n});for(const e of r)h({x:e.center,y:l,z:t})}}}return a.sort((t,e)=>e.zSpanLen-t.zSpanLen||e.distance-t.distance||t.z-e.z||t.x-e.x||t.y-e.y),a}function Xn(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}var Vn=(t,e)=>({...t,minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:e.zLayers});function Wn(t,e){const n=t.placed[e],{rect:o,zLayers:i}=n,r=t.layerCount,s=[],a=[];for(let n=0;n<t.placed.length;n++){if(n===e)continue;const c=t.placed[n];if(c.zLayers.length>=r)continue;const l=c.zLayers.filter(t=>i.includes(t));if(0===l.length)continue;if(!sn(c.rect,o))continue;const d=ln(c.rect,o);s.push(n);const h=c.zLayers.filter(t=>!i.includes(t));h.length>0&&a.push({rect:c.rect,zLayers:h});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 d)t.width+tn>=u&&t.height+tn>=p&&a.push({rect:t,zLayers:l.slice()})}const c=(t,e)=>t.minX===e.minX&&t.minY===e.minY&&t.maxX===e.maxX&&t.maxY===e.maxY;s.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 o=t.placedIndexByLayer[e];o&&o.remove(Vn(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 o=t.placedIndexByLayer[n];o&&o.insert(Vn(e.rect,{zLayers:e.zLayers.slice()}))}}}var Hn=class extends kt{constructor(t){super(),this.input=t}input;srj;layerNames;layerCount;bounds;options;boardVoidRects;gridIndex;candidates;placed;placedIndexByLayer;hardPlacedByLayer;expansionIndex;edgeAnalysisDone;totalSeedsThisGrid;consumedSeedsThisGrid;_setup(){const t=this.input.simpleRouteJson,e=this.input.gridOptions??{},n=this.input.layerNames&&this.input.zIndexByName,{layerNames:o,zIndexByName:i}=n?{layerNames:this.input.layerNames,zIndexByName:this.input.zIndexByName}:qe({obstacles:t.obstacles,layerCount:t.layerCount}),r=Math.max(1,o.length,t.layerCount||1),s={x:t.bounds.minX,y:t.bounds.minY,width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY},a=Math.max(.01,t.minTraceWidth||.15),c={...{gridSizes:[],initialCellRatio:.2,maxAspectRatio:3,minSingle:{width:2*a,height:2*a},minMulti:{width:4*a,height:4*a,minLayers:Math.min(2,Math.max(1,t.layerCount||1))},preferMultiLayer:!0,maxMultiLayerSpan:void 0},...e,gridSizes:e.gridSizes??Ln(s)};this.srj=t,this.layerNames=o,this.layerCount=r,this.bounds=s,this.options=c,this.boardVoidRects=this.input.boardVoidRects,this.gridIndex=0,this.candidates=[],this.placed=[],this.placedIndexByLayer=Array.from({length:r},()=>new te),this.hardPlacedByLayer=Array.from({length:r},()=>[]),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:o,minMulti:i,preferMultiLayer:r,maxMultiLayerSpan:s}=this.options,a=t[this.gridIndex];if(0===this.candidates.length&&0===this.consumedSeedsThisGrid&&(this.candidates=function(t){const{bounds:e,gridSize:n,layerCount:o,obstacleIndexByLayer:i,placedIndexByLayer:r,hardPlacedByLayer:s}=t,a=new Map,c=Array.from({length:o},(t,e)=>[...i[e]?.all()??[],...s[e]??[]]);for(let t=e.x;t<e.x+e.width;t+=n)for(let l=e.y;l<e.y+e.height;l+=n){if(Math.abs(t-e.x)<tn||Math.abs(l-e.y)<tn||t>e.x+e.width-n-tn||l>e.y+e.height-n-tn)continue;if(Dn({layerCount:o,obstacleIndexByLayer:i,placedIndexByLayer:r,point:{x:t,y:l}}))continue;let d=[],h=0;for(let e=0;e<o;e++){const n=zn({x:t,y:l,z:e,layerCount:o,minSpan:1,maxSpan:void 0,obstacleIndexByLayer:i,additionalBlockersByLayer:s});n.length>d.length&&(d=n,h=e)}const u=d.length?d[Math.floor(d.length/2)]:h,p=c[u]??[];let m=an({x:t,y:l},e);for(const e of p)m=Math.min(m,an({x:t,y:l},e));const g=Fn(m),f=`${t.toFixed(6)}|${l.toFixed(6)}`,y={x:t,y:l,z:u,distance:g,zSpanLen:d.length},_=a.get(f);(!_||y.zSpanLen>(_.zSpanLen??0)||y.zSpanLen===_.zSpanLen&&y.distance>_.distance)&&a.set(f,y)}const l=Array.from(a.values());return l.sort((t,e)=>e.zSpanLen-t.zSpanLen||e.distance-t.distance||t.z-e.z||t.x-e.x||t.y-e.y),l}({bounds:this.bounds,gridSize:a,layerCount:this.layerCount,hardPlacedByLayer:this.hardPlacedByLayer,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer}),this.totalSeedsThisGrid=this.candidates.length,this.consumedSeedsThisGrid=0),this.consumedSeedsThisGrid>=this.candidates.length){if(this.gridIndex+1<t.length)return this.gridIndex+=1,this.candidates=[],this.totalSeedsThisGrid=0,void(this.consumedSeedsThisGrid=0);if(!this.edgeAnalysisDone){const t=Math.min(o.width,o.height);return this.candidates=Yn({bounds:this.bounds,minSize:t,layerCount:this.layerCount,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,hardPlacedByLayer:this.hardPlacedByLayer}),this.edgeAnalysisDone=!0,this.totalSeedsThisGrid=this.candidates.length,void(this.consumedSeedsThisGrid=0)}return this.candidates=[],this.solved=!0,void(this.expansionIndex=0)}const c=this.candidates[this.consumedSeedsThisGrid++];if(Dn({layerCount:this.layerCount,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,point:{x:c.x,y:c.y}}))return;const l=zn({x:c.x,y:c.y,z:c.z,layerCount:this.layerCount,minSpan:i.minLayers,maxSpan:s,obstacleIndexByLayer:this.input.obstacleIndexByLayer,additionalBlockersByLayer:this.hardPlacedByLayer}),d=[];l.length>=i.minLayers&&d.push({kind:"multi",layers:l,minReq:{width:i.width,height:i.height}}),d.push({kind:"single",layers:[c.z],minReq:{width:o.width,height:o.height}});const h=r?d:d.reverse();for(const t of h){const o=kn({startX:c.x,startY:c.y,gridSize:a,bounds:this.bounds,obsticalIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,initialCellRatio:e,maxAspectRatio:n,minReq:t.minReq,zLayers:t.layers});if(!o)continue;const i={rect:o,zLayers:[...t.layers]},r=this.placed.push(i)-1;for(const e of t.layers){const t=this.placedIndexByLayer[e];t&&t.insert(Vn(o,{zLayers:i.zLayers}))}return Wn({layerCount:this.layerCount,placed:this.placed,options:this.options,placedIndexByLayer:this.placedIndexByLayer},r),void(this.hardPlacedByLayer=Xn({layerCount:this.layerCount,placed:this.placed}))}}computeProgress(){if(this.solved)return 1;const t=this.options.gridSizes.length,e=this.gridIndex/(t+1),n=Math.max(1,this.totalSeedsThisGrid),o=n?this.consumedSeedsThisGrid/n:1;return Math.min(.999,e+o*(1/(t+1)))}getOutput(){return{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,obstacles:this.srj.obstacles,obstacleClearance:this.input.obstacleClearance}}visualize(){const t=[],e=[],n=[],o=this.srj??this.input.simpleRouteJson,i=o.bounds.minX,r=o.bounds.maxX,s=o.bounds.minY,a=o.bounds.maxY;o.outline&&o.outline.length>1?n.push({points:[...o.outline,o.outline[0]],strokeColor:"#111827",strokeWidth:.01,label:"outline"}):t.push({center:{x:(i+r)/2,y:(s+a)/2},width:r-i,height:a-s,fill:"none",stroke:"#111827",label:"board"});for(const e of o.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(o.outline&&o.outline.length>0){const t=o.outline.map(t=>t.x),n=o.outline.map(t=>t.y),i=Math.min(...t),r=Math.min(...n);e={x:i,y:r,width:Math.max(...t)-i,height:Math.max(...n)-r}}for(const n of this.boardVoidRects)e&&!sn(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,label:`z:${t.z}`});if(this.placed?.length)for(const e of this.placed){const n=Qe(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 Gn=(t,e)=>t.minX===e.minX&&t.minY===e.minY&&t.maxX===e.maxX&&t.maxY===e.maxY,Un=class extends kt{constructor(t){super(),this.input=t}input;placedIndexByLayer=[];_meshNodes=[];_setup(){this.stats={gridIndex:this.input.gridIndex},this.placedIndexByLayer=Array.from({length:this.input.layerCount},()=>new te);for(const t of this.input.placed)for(const e of t.zLayers){const n=this.placedIndexByLayer[e];n&&n.insert(Vn(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],o=e.rect,i=kn({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(i){this.input.placed[t]={rect:i,zLayers:e.zLayers};for(const t of e.zLayers){const n=this.placedIndexByLayer[t];n&&(n.remove(Vn(o,{zLayers:e.zLayers}),Gn),n.insert(Vn(i,{zLayers:e.zLayers})))}Wn({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)}));for(const n of t.obstacles??[]){const o=Ke(n);if(!o)continue;const i=t.obstacleClearance?{x:o.x-t.obstacleClearance,y:o.y-t.obstacleClearance,width:o.width+2*t.obstacleClearance,height:o.height+2*t.obstacleClearance}:o,r=n.zLayers?.length&&n.zLayers.length>0?n.zLayers:Je(n,t.zIndexByName);e.push({minX:i.x,minY:i.y,maxX:i.x+i.width,maxY:i.y+i.height,zLayers:[...new Set(r)].sort((t,e)=>t-e),isObstacle:!0,connectedTo:[...n.connectedTo]})}return e}({placed:this.input.placed,obstacles:this.input.obstacles,zIndexByName:this.input.zIndexByName,boardVoidRects:this.input.boardVoidRects,obstacleClearance:this.input.obstacleClearance});this._meshNodes=function(t){let e=0;const n=[];for(const o of t){const t=Math.max(0,o.maxX-o.minX),i=Math.max(0,o.maxY-o.minY);t<=0||i<=0||0===o.zLayers.length||n.push({capacityMeshNodeId:"cmn_"+e++,center:{x:(o.minX+o.maxX)/2,y:(o.minY+o.maxY)/2},width:t,height:i,layer:"top",availableZ:o.zLayers.slice(),_containsObstacle:o.isObstacle,_containsTarget:o.isObstacle,...o.connectedTo?.length?{_connectedTo:[...o.connectedTo]}:{}})}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),o=n?this.input.expansionIndex/n:1;return Math.min(.999,e+o*(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:[]}}},Zn=class extends Dt{rectDiffSeedingSolver;rectDiffExpansionSolver;obstacleIndexByLayer;layerNames;zIndexByName;constructor(t){super(t);const{obstacleIndexByLayer:e,layerNames:n,zIndexByName:o}=(t=>{const{srj:e,boardVoidRects:n,obstacleClearance:o}=t,{layerNames:i,zIndexByName:r}=qe({obstacles:e.obstacles,layerCount:e.layerCount}),s=Math.max(1,i.length,e.layerCount||1),a=(e.bounds.minX,e.bounds.minY,e.bounds.maxX,e.bounds.minX,e.bounds.maxY,e.bounds.minY,Array.from({length:s},()=>new te)),c=(t,e)=>{const n={...t,minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:[e]};a[e]?.insert(n)};if(e.outline&&e.outline.length>2)for(const t of n??[])for(let e=0;e<s;e++)c(t,e);for(const t of e.obstacles??[]){const e=Ke(t);if(!e)continue;const n=dn(e,o??0),i=Je(t,r),a=i.filter(t=>t<0||t>=s);if(a.length)throw new Error(`RectDiff: obstacle uses z-layer indices ${a.join(",")} outside 0-${s-1}`);t.zLayers&&0!==t.zLayers.length||!i.length||(t.zLayers=i);for(const t of i)c(n,t)}return{obstacleIndexByLayer:a,layerNames:i,zIndexByName:r}})({srj:{bounds:t.bounds,obstacles:t.obstacles,connections:t.connections,outline:t.outline?.outline,layerCount:t.layerCount,minTraceWidth:t.minTraceWidth},boardVoidRects:t.boardVoidRects,obstacleClearance:t.obstacleClearance});this.obstacleIndexByLayer=e,this.layerNames=t.layerNames??n,this.zIndexByName=t.zIndexByName??o}pipelineDef=[Lt("rectDiffSeedingSolver",Hn,t=>[{simpleRouteJson:{bounds:t.inputProblem.bounds,obstacles:t.inputProblem.obstacles,connections:t.inputProblem.connections,outline:t.inputProblem.outline?.outline,layerCount:t.inputProblem.layerCount,minTraceWidth:t.inputProblem.minTraceWidth},gridOptions:t.inputProblem.gridOptions,obstacleIndexByLayer:t.obstacleIndexByLayer,boardVoidRects:t.inputProblem.boardVoidRects,layerNames:t.layerNames,zIndexByName:t.zIndexByName,obstacleClearance:t.inputProblem.obstacleClearance}]),Lt("rectDiffExpansionSolver",Un,t=>{const e=t.rectDiffSeedingSolver?.getOutput();if(!e)throw new Error("RectDiffSeedingSolver did not produce output");return[{layerNames:e.layerNames??[],boardVoidRects:t.inputProblem.boardVoidRects??[],layerCount:t.inputProblem.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,zIndexByName:t.zIndexByName,layerNamesCanonical:t.layerNames,obstacles:t.inputProblem.obstacles,obstacleClearance:t.inputProblem.obstacleClearance}]})];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:[]}}};var qn=t=>{const{srj:e,clearance:n}=t,o=n??0;if(o<=0)return{title:"Obstacle Clearance",coordinateSystem:"cartesian",rects:[]};const i=[];for(const t of e.obstacles??[]){if("rect"!==t.type&&"oval"!==t.type)continue;const e={x:t.center.x-t.width/2-o,y:t.center.y-t.height/2-o,width:t.width+2*o,height:t.height+2*o};i.push({center:{x:e.x+e.width/2,y:e.y+e.height/2},width:e.width,height:e.height,stroke:"rgba(202, 138, 4, 0.9)",fill:"rgba(234, 179, 8, 0.15)",layer:"obstacle-clearance",label:`clearance\nz:${(t.zLayers??[]).join(",")||"all"}`})}return{title:"Obstacle Clearance",coordinateSystem:"cartesian",rects:i}};function Jn(t,e,n={}){if(!e||e.length<3)return[];const o=e.length>120,i=o?function(t,e){const n=t=>Math.round(t/e)*e,o=new Set,i=[];for(const e of t){const t=n(e.x),r=n(e.y),s=`${t},${r}`;o.has(s)||(o.add(s),i.push({x:t,y:r}))}return i}(e,Math.max(t.width,t.height)/120):e,r=new Set([t.x,t.x+t.width]),s=new Set([t.y,t.y+t.height]);for(const t of i)r.add(t.x),s.add(t.y);!function({polygon:t,xs:e,ys:n,minGridSize:o}){const i=[];let r=0;for(let e=0;e<t.length;e++){const n=t[e],o=t[(e+1)%t.length],s=Math.abs(o.x-n.x),a=Math.abs(o.y-n.y);if(s<=tn||a<=tn)continue;const c=Math.max(s,a);i.push({start:n,end:o,span:c}),r+=c}if(0===i.length)return;const s=Math.max(o,r/256);for(const{start:t,end:o,span:r}of i){const i=Math.max(1,Math.ceil(r/s));for(let r=1;r<i;r++){const s=r/i;e.add(t.x+(o.x-t.x)*s),n.add(t.y+(o.y-t.y)*s)}}}({polygon:i,xs:r,ys:s,minGridSize:Math.max(tn,n.minGridSize??Math.max(t.width,t.height)/256)});const a=Array.from(r).sort((t,e)=>t-e),c=Array.from(s).sort((t,e)=>t-e),l=[];for(let n=0;n<a.length-1;n++)for(let i=0;i<c.length-1;i++){const r=a[n],s=a[n+1],d=c[i],h=c[i+1],u=(r+s)/2,p=(d+h)/2;if(u>=t.x&&u<=t.x+t.width&&p>=t.y&&p<=t.y+t.height){(o?[{x:u,y:p}]:[{x:u,y:p},{x:r,y:d},{x:s,y:d},{x:r,y:h},{x:s,y:h}]).every(t=>Ne(t,e))||l.push({x:r,y:d,width:s-r,height:h-d})}}const d=[];l.sort((t,e)=>Math.abs(t.y-e.y)>tn?t.y-e.y:t.x-e.x);let h=null;for(const t of l){if(!h){h=t;continue}const e=Math.abs(h.y-t.y)<tn,n=Math.abs(h.height-t.height)<tn,o=Math.abs(h.x+h.width-t.x)<tn;e&&n&&o?h.width+=t.width:(d.push(h),h=t)}h&&d.push(h),d.sort((t,e)=>Math.abs(t.x-e.x)>tn?t.x-e.x:t.y-e.y);const u=[];h=null;for(const t of d){if(!h){h=t;continue}const e=Math.abs(h.x-t.x)<tn,n=Math.abs(h.width-t.width)<tn,o=Math.abs(h.y+h.height-t.y)<tn;e&&n&&o?h.height+=t.height:(u.push(h),h=t)}return h&&u.push(h),u}var Kn=class extends Dt{rectDiffGridSolverPipeline;gapFillSolver;outerLayerContainmentMergeSolver;boardVoidRects;zIndexByName;layerNames;pipelineDef=[Lt("rectDiffGridSolverPipeline",Zn,t=>[{bounds:t.inputProblem.simpleRouteJson.bounds,obstacles:t.inputProblem.simpleRouteJson.obstacles,connections:t.inputProblem.simpleRouteJson.connections,outline:t.inputProblem.simpleRouteJson.outline?{outline:t.inputProblem.simpleRouteJson.outline}:void 0,layerCount:t.inputProblem.simpleRouteJson.layerCount,gridOptions:t.inputProblem.gridOptions,boardVoidRects:t.boardVoidRects,layerNames:t.layerNames,zIndexByName:t.zIndexByName,minTraceWidth:t.inputProblem.simpleRouteJson.minTraceWidth,obstacleClearance:t.inputProblem.obstacleClearance}]),Lt("gapFillSolver",Ue,t=>[{meshNodes:t.rectDiffGridSolverPipeline?.getOutput().meshNodes??[],boardVoid:{boardVoidRects:t.boardVoidRects||[],layerCount:t.inputProblem.simpleRouteJson.layerCount||0},maxGapFillPasses:t.inputProblem.maxGapFillPasses}]),Lt("outerLayerContainmentMergeSolver",xn,t=>[{meshNodes:t.gapFillSolver?.getOutput().outputNodes??t.rectDiffGridSolverPipeline?.getOutput().meshNodes??[],simpleRouteJson:t.inputProblem.simpleRouteJson,zIndexByName:t.zIndexByName??new Map,obstacleClearance:t.inputProblem.obstacleClearance}])];_setup(){const{zIndexByName:t,layerNames:e}=qe({obstacles:this.inputProblem.simpleRouteJson.obstacles,layerCount:this.inputProblem.simpleRouteJson.layerCount});if(this.zIndexByName=t,this.layerNames=e,this.inputProblem.simpleRouteJson.outline){const t=Math.max(0,this.inputProblem.simpleRouteJson.minBoardEdgeClearance??0);this.boardVoidRects=Jn({x:this.inputProblem.simpleRouteJson.bounds.minX-t,y:this.inputProblem.simpleRouteJson.bounds.minY-t,width:this.inputProblem.simpleRouteJson.bounds.maxX-this.inputProblem.simpleRouteJson.bounds.minX+2*t,height:this.inputProblem.simpleRouteJson.bounds.maxY-this.inputProblem.simpleRouteJson.bounds.minY+2*t},this.inputProblem.simpleRouteJson.outline??[],{minGridSize:this.inputProblem.simpleRouteJson.minTraceWidth}).map(e=>dn(e,t))}}getConstructorParams(){return[this.inputProblem]}getOutput(){const t=this.outerLayerContainmentMergeSolver?.getOutput();if(t)return{meshNodes:t.outputNodes};const e=this.gapFillSolver?.getOutput();return e?{meshNodes:e.outputNodes}:this.rectDiffGridSolverPipeline?this.rectDiffGridSolverPipeline.getOutput():{meshNodes:[]}}initialVisualize(){const t=function(t,e="RectDiff"){const n=[],o=[],i=t.bounds.minX,r=t.bounds.maxX,s=t.bounds.minY,a=t.bounds.maxY;t.outline&&t.outline.length>1?o.push({points:[...t.outline,t.outline[0]],strokeColor:"#111827",strokeWidth:.01,label:"outline"}):n.push({center:{x:(i+r)/2,y:(s+a)/2},width:r-i,height:a-s,fill:"none",stroke:"#111827",label:"board"});for(const e of t.obstacles??[])if("rect"===e.type||"oval"===e.type){const t=(e.zLayers??[]).join(",")||"all";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\nz:${t}`})}return{title:e,coordinateSystem:"cartesian",rects:n,points:[],lines:o}}(this.inputProblem.simpleRouteJson,"RectDiffPipeline - Initial"),e=qn({srj:this.inputProblem.simpleRouteJson,clearance:this.inputProblem.obstacleClearance}),n={title:"Initial Nodes",coordinateSystem:"cartesian",rects:(this.rectDiffGridSolverPipeline?.getOutput().meshNodes??[]).map(t=>({center:t.center,width:t.width,height:t.height,stroke:"rgba(0, 0, 0, 0.3)",fill:"rgba(100, 100, 100, 0.1)",layer:`z${t.availableZ.join(",")}`,label:[`node ${t.capacityMeshNodeId}`,`z:${t.availableZ.join(",")}`].join("\n")}))};return At(At(t,e),n)}finalVisualize(){return(({srj:t,meshNodes:e,obstacleClearance:n})=>{const o=(({srj:t})=>({title:"SimpleRoute Outline",coordinateSystem:"cartesian",lines:t.outline&&t.outline.length>1?[{points:[...t.outline,t.outline[0]],strokeColor:"#111827",strokeWidth:.1,label:"outline"}]:[{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:"#111827",strokeWidth:.1,label:"bounds"}]}))({srj:t}),i=qn({srj:t,clearance:n}),r=e.map(t=>({center:t.center,width:t.width,height:t.height,stroke:Qe(t.availableZ).stroke,fill:t._containsObstacle?"#fca5a5":Qe(t.availableZ).fill,layer:`z${t.availableZ.join(",")}`,label:`node ${t.capacityMeshNodeId}\nz:${t.availableZ.join(",")}`}));return At(At({title:"RectDiffPipeline - Final",coordinateSystem:"cartesian",rects:r,lines:[],points:[],texts:[]},o),i)})({srj:this.inputProblem.simpleRouteJson,meshNodes:this.getOutput().meshNodes,obstacleClearance:this.inputProblem.obstacleClearance})}},Qn=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())}},to="tscircuit_autorouter_cache_",eo=class{isSyncCache=!0;cacheHits=0;cacheMisses=0;cacheHitsByPrefix={};cacheMissesByPrefix={};constructor(){}getKey(t){return`${to}${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 o=t.split(":")[0];return this.cacheHitsByPrefix[o]=(this.cacheHitsByPrefix[o]||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 o=t.split(":")[0];return void(this.cacheMissesByPrefix[o]=(this.cacheMissesByPrefix[o]||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(to)&&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(to)&&t.push(n)}return t}};function no(){return globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE||io(),globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE}function oo(){return globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE||io(),globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE}function io(){globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE??=new eo,globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE??=new Qn}function ro(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 so=(t,e)=>t<=e?[t,e]:[e,t],ao=t=>`${t[0]}|${t[1]}`,co=({portPointId:t,currentNodeId:e,inputNodes:n})=>{let o;if(t)for(const e of n){const n=e.portPoints.find(e=>e.portPointId===t);if(n?.connectionNodeIds){o=n.connectionNodeIds;break}}if(!o||2!==o.length)return[e,e];const[i,r]=o;return i&&r?so(i,r):[e,e]},lo=1e-6,ho=(t,e)=>Math.abs(t-e)<=lo,uo=({nodeAId:t,nodeBId:e,nodeBounds:n})=>{if(t===e)return null;const o=n.get(t),i=n.get(e);if(!o||!i)return null;const r=so(t,e),s=ao(r);if(ho(o.maxX,i.minX)||ho(i.maxX,o.minX)){const n=Math.max(o.minY,i.minY),a=Math.min(o.maxY,i.maxY),c=a-n;if(c>lo){const l=ho(o.maxX,i.minX)?o.maxX:o.minX;return{ownerNodeIds:r,ownerPairKey:s,orientation:"vertical",x1:l,y1:n,x2:l,y2:a,center:{x:l,y:(n+a)/2},length:c,nodeSideByOwnerId:ho(o.maxX,i.minX)?{[t]:"right",[e]:"left"}:{[t]:"left",[e]:"right"}}}}if(ho(o.maxY,i.minY)||ho(i.maxY,o.minY)){const n=Math.max(o.minX,i.minX),a=Math.min(o.maxX,i.maxX),c=a-n;if(c>lo){const l=ho(o.maxY,i.minY)?o.maxY:o.minY;return{ownerNodeIds:r,ownerPairKey:s,orientation:"horizontal",x1:n,y1:l,x2:a,y2:l,center:{x:(n+a)/2,y:l},length:c,nodeSideByOwnerId:ho(o.maxY,i.minY)?{[t]:"top",[e]:"bottom"}:{[t]:"bottom",[e]:"top"}}}}return null},po=({portPoint:t,ownerNodeIds:e,inputNodes:n})=>{for(const o of e){const e=n.find(t=>t.capacityMeshNodeId===o);if(e?._containsTarget)return!0;const i=e?.portPoints.find(e=>e.portPointId===t.portPointId);if(i?.connectionNodeIds?.some(t=>n.find(e=>e.capacityMeshNodeId===t)?._containsTarget))return!0}return!1},mo=1e-6,go=class extends kt{constructor(t){super(),this.input=t;for(const e of t.nodeWithPortPoints)this.mapOfNodeIdToBounds.set(e.capacityMeshNodeId,ro(e));const e=new Map;for(const n of t.nodeWithPortPoints)for(const o of n.portPoints){if(!o.portPointId)continue;const i=co({portPointId:o.portPointId,currentNodeId:n.capacityMeshNodeId,inputNodes:t.inputNodesWithPortPoints}),r=ao(i),s=this.mapOfOwnerPairToPortPoints.get(r)??[];s.some(t=>t.portPointId&&t.portPointId===o.portPointId)||s.push({...o,ownerNodeIds:i,ownerPairKey:r}),this.mapOfOwnerPairToPortPoints.set(r,s),e.set(r,i)}this.mapOfOwnerPairToSharedEdge=(({ownerPairs:t,nodeBounds:e})=>{const n=new Map;for(const o of t){const[t,i]=o;if(t===i)continue;const r=uo({nodeAId:t,nodeBId:i,nodeBounds:e});r&&n.set(ao(o),r)}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),o=this.mapOfOwnerPairToSharedEdge.get(e);return n.center.x-o.center.x||n.center.y-o.center.y})}input;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,o=n.center.x+n.width/2,i=n.center.y-n.height/2,r=n.center.y+n.height/2;if("vertical"!==t.orientation){if(Math.abs(t.y1-i)<mo||Math.abs(t.y1-r)<mo){const n=Math.max(t.x1,e);if(Math.min(t.x2,o)-n>mo)return!0}}else if(Math.abs(t.x1-e)<mo||Math.abs(t.x1-o)<mo){const e=Math.max(t.y1,i);if(Math.min(t.y2,r)-e>mo)return!0}}return!1})({sharedEdge:e,obstacles:this.input.obstacles}))return;const n=this.mapOfOwnerPairToPortPoints.get(t)??[],o=[];for(const t of n)po({portPoint:t,ownerNodeIds:t.ownerNodeIds,inputNodes:this.input.inputNodesWithPortPoints})||o.push(t);const i=(({sharedEdge:t,portPoints:e})=>{if(0===e.length)return[];const n=new Map;for(const t of e){const e=t.z??0,o=n.get(e)??[];o.push(t),n.set(e,o)}const o=[],i=Array.from(n.keys()).sort((t,e)=>t-e);for(const e of i){const i=n.get(e),r=i.length;i.sort((e,n)=>"horizontal"===t.orientation?e.x-n.x:e.y-n.y);for(let e=0;e<r;e++){const n=(2*e+1)/(2*r),s="horizontal"===t.orientation?t.x1+t.length*n:t.x1,a="horizontal"===t.orientation?t.y1:t.y1+t.length*n;o.push({...i[e],x:s,y:a})}}return o})({sharedEdge:e,portPoints:o});this.mapOfOwnerPairToPortPoints.set(t,i)}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});const e=e=>{if(e.portPointId&&t.has(e.portPointId)){const n=t.get(e.portPointId);return{...e,x:n.x,y:n.y}}return e};this.redistributedNodes=this.input.nodeWithPortPoints.map(t=>({...t,portPoints:t.portPoints.map(e),portPointsInPairs:t.portPointsInPairs?.map(([t,n])=>[e(t),e(n)])}))}getOutput=()=>this.redistributedNodes;visualize(){return(({obstacles:t,nodeWithPortPoints:e,mapOfOwnerPairToPortPoints:n,mapOfOwnerPairToSharedEdge:o,ownerPairsToProcess:i,currentOwnerPairBeingProcessed:r,mapOfNodeIdToBounds:s})=>{const a=t.filter(t=>!t.isCopperPour).map(t=>({...t,fill:"#ec000070"})),c=[],l=[],d=new Map,h=new Map,u=new Map,p=t=>t.portPointId?d.get(t.portPointId)??{x:t.x,y:t.y}:{x:t.x,y:t.y};for(const t of e)for(const e of t.portPoints)e.portPointId&&(d.set(e.portPointId,{x:e.x,y:e.y}),h.set(e.portPointId,e.z??0));for(const t of n.values())for(const e of t)e.portPointId&&(d.set(e.portPointId,{x:e.x,y:e.y}),h.set(e.portPointId,e.z??0),u.set(e.portPointId,`${e.ownerNodeIds[0]}&${e.ownerNodeIds[1]}`));e.forEach(t=>{const e=s.get(t.capacityMeshNodeId);if(e){const n=(e.minX+e.maxX)/2,o=(e.minY+e.maxY)/2,i=e.maxX-e.minX,r=e.maxY-e.minY;a.push({center:{x:n,y:o},width:i,height:r,fill:"#00000030",label:`${t.capacityMeshNodeId}`})}t.portPoints.forEach(e=>{if(!e.portPointId)return;const n=d.get(e.portPointId),o=h.get(e.portPointId)??0,i=u.get(e.portPointId)??`${t.capacityMeshNodeId}&${t.capacityMeshNodeId}`;c.push({x:n.x,y:n.y,label:`z:${o}\no:${i}`}),t.portPointsInPairs?.length||t.portPoints.forEach(t=>{if(t.portPointId&&e!==t&&e.connectionName===t.connectionName){const e=d.get(t.portPointId);l.push({points:[n,e],strokeColor:"#fff822c9"})}})}),t.portPointsInPairs?.forEach(([t,e])=>{l.push({points:[p(t),p(e)],strokeColor:"#fff822c9"})})});for(const t of i){const e=o.get(t);e&&l.push({points:[{x:e.x1,y:e.y1},{x:e.x2,y:e.y2}],strokeColor:"orange",strokeWidth:.01})}if(r){const t=o.get(r);t&&(l.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 o.values())l.push({points:[{x:t.x1,y:t.y1},{x:t.x2,y:t.y2}],strokeColor:"#33b5ff80",strokeWidth:.006});return{rects:a,lines:l,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})}},fo=(t,e,n)=>t.connectedTo.some(t=>t===e.connectionName||t===e.rootConnectionName||(n?.areIdsConnected(e.connectionName,t)??!1)||void 0!==e.rootConnectionName&&(n?.areIdsConnected(e.rootConnectionName,t)??!1));function yo(t){return"layers"in t&&Array.isArray(t.layers)}function _o(t){return"layer"in t&&"string"==typeof t.layer}function bo(t){return yo(t)?t.layers[0]:t.layer}function xo(t){return yo(t)?t.layers:[t.layer]}var vo=(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}`},So=(t,e)=>!!t&&!!e&&Math.abs(t.x-e.x)<=1e-12&&Math.abs(t.y-e.y)<=1e-12,Io=(t,e)=>Be(t,e)<=1e-6,Co=(t,e,n,o)=>"through_obstacle"===e.toNextSegmentType||(o.connectedMultilayerObstacles?o.connectedMultilayerObstacles.some(t=>Io(e,t)&&Io(n,t)):o.obstacles?.some(i=>(t=>(t.__zLayers?.length??t.layers?.length??0)>1)(i)&&Io(e,i)&&Io(n,i)&&fo(i,t,o.connMap))??!1),Po=({endpoint:t,endpointLayer:e,connectionPoints:n,tolerance:o})=>{let i;for(const r of n){if(!_o(r)||!r.terminalVia)continue;if(r.layer!==e)continue;const n=xe(r,t);n>o||(!i||n<i.distance)&&(i={point:r,distance:n})}return i?.point},Mo=(t,e,n={})=>{const o=[];if(0===t.route.length)return o;let i=[],r=t.route[0].z;for(let s=0;s<t.route.length;s++){const a=t.route[s];if(a.z!==r){const s=i[i.length-1],c=vo(r,e);for(const e of i)o.push({route_type:"wire",x:e.x,y:e.y,width:e.traceThickness??t.traceThickness,layer:c});const l=vo(a.z,e);if(s&&Co(t,s,a,n))o.push({route_type:"through_obstacle",start:{x:s.x,y:s.y},end:{x:a.x,y:a.y},from_layer:c,to_layer:l,width:s.traceThickness??t.traceThickness,...s.toNextSegmentCircuitJsonMetadata?{circuitJsonMetadata:s.toNextSegmentCircuitJsonMetadata}:{}});else{t.vias.some(t=>Math.abs(t.x-a.x)<.001&&Math.abs(t.y-a.y)<.001)&&o.push({route_type:"via",x:a.x,y:a.y,from_layer:c,to_layer:l,via_diameter:t.viaDiameter,...void 0!==n.defaultViaHoleDiameter?{via_hole_diameter:n.defaultViaHoleDiameter}:{}})}i=[a],r=a.z}else So(i[i.length-1],a)||i.push(a)}const s=vo(r,e);for(const e of i)o.push({route_type:"wire",x:e.x,y:e.y,width:e.traceThickness??t.traceThickness,layer:s});if(t.jumpers&&t.jumpers.length>0){const n=vo(t.route[0]?.z??0,e);for(const e of t.jumpers)o.push({route_type:"jumper",start:e.start,end:e.end,footprint:e.footprint,layer:n})}return(({route:t,hdRoute:e,layerCount:n,connectionPoints:o=[],tolerance:i=.25,defaultViaHoleDiameter:r})=>{if(0===t.length||0===e.route.length||!o.length)return t;if(!o.some(t=>_o(t)&&t.terminalVia))return t;const s=t.filter(t=>"jumper"!==t.route_type),a=t.filter(t=>"jumper"===t.route_type);if(0===s.length)return t;const c=e.route[0],l=e.route[e.route.length-1],d=vo(c.z,n),h=vo(l.z,n),u=Po({endpoint:c,endpointLayer:d,connectionPoints:o,tolerance:i}),p=Po({endpoint:l,endpointLayer:h,connectionPoints:o,tolerance:i}),m=[],g=[],f=s[0],y=s[s.length-1],_=c.traceThickness??e.traceThickness,b=l.traceThickness??e.traceThickness;return u?.terminalVia&&(m.push({route_type:"via",x:u.x,y:u.y,from_layer:u.layer,to_layer:u.terminalVia.toLayer,via_diameter:u.terminalVia.viaDiameter??e.viaDiameter,...void 0!==r?{via_hole_diameter:r}:{}}),"wire"===f?.route_type&&f.layer===u.layer&&xe(f,u)<=.001||m.push({route_type:"wire",x:u.x,y:u.y,width:_,layer:u.layer})),p?.terminalVia&&("wire"===y?.route_type&&y.layer===p.layer&&xe(y,p)<=.001||g.push({route_type:"wire",x:p.x,y:p.y,width:b,layer:p.layer}),g.push({route_type:"via",x:p.x,y:p.y,from_layer:p.layer,to_layer:p.terminalVia.toLayer,via_diameter:p.terminalVia.viaDiameter??e.viaDiameter,...void 0!==r?{via_hole_diameter:r}:{}})),[...m,...s,...g,...a]})({route:o,hdRoute:t,layerCount:e,connectionPoints:n.connectionPoints,tolerance:n.terminalViaAttachTolerance,defaultViaHoleDiameter:n.defaultViaHoleDiameter})},No=["blue","orange","purple","cyan","magenta","yellowgreen","darkgoldenrod","deeppink"],wo=(t,e)=>{const n={};for(let o=0;o<t.connections.length;o++){const i=t.connections[o],r=e?.getNetConnectedToId(i.name);r&&!n[r]&&(n[r]=`hsl(${300*o/t.connections.length}, 100%, 50%)`),n[i.name]=(r?n[r]:null)??`hsl(${340*o/t.connections.length}, 100%, 50%)`}return n},To=(t,e)=>{try{return Tt(e,t)}catch(e){return console.error(e),t}},Ro=(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%360;return e<1?`hsla(${n}, 100%, 50%, ${e})`:`hsl(${n}, 100%, 50%)`},Eo=t=>{const e=new Set;return t.filter(t=>!e.has(t)&&(e.add(t),!0))},Ao=(t,e,n)=>{if(!e)return;const o=t.get(e);o?o.includes(n)||o.push(n):t.set(e,[n])},Oo=t=>{const e=new Map;for(const n of t.connections){const t=n.__rootConnectionNames??[n.name];for(const o of t){Ao(e,n.name,o),Ao(e,o,o),Ao(e,n.__netConnectionName,o);for(const t of n.pointsToConnect)Ao(e,t.pointId,o),Ao(e,t.pcb_port_id,o)}}return t=>((t,e=[])=>{const n=Eo(e).join(", ");return t.layers.map(t=>n?`${t}\n${n}`:t).join("\n")})(t,((t,e)=>Eo([...t.connectedTo.flatMap(t=>e.get(t)??[]),...(t.offBoardConnectsTo??[]).flatMap(t=>e.get(t)??[])]))(t,e))},ko=(t,e)=>"top"===t?0:"bottom"===t?e-1:parseInt(t.slice(5));function Lo(t,e){return[...new Set(t)].filter(t=>Number.isInteger(t)&&t>=0&&t<e).sort((t,e)=>t-e)}function Do(t,e){return Lo(t.map(t=>ko(t,e)),e)}var zo=(t,e)=>`z${Do(t,e).join(",")}`,Fo=(t,e)=>zo(xo(t),e),Bo=(t,e)=>t.__zLayers&&t.__zLayers.length>0?Lo(t.__zLayers,e):Do(t.layers,e),jo=(t,e)=>`z${Bo(t,e).join(",")}`,$o=(...t)=>t.find(t=>"number"==typeof t&&Number.isFinite(t)),Yo=t=>{const e=$o(t.min_via_hole_diameter,t.minViaHoleDiameter),n=$o(t.min_via_pad_diameter,t.minViaPadDiameter,t.minViaDiameter),o=Math.max(n??t.minViaDiameter??.3,e??0);return{padDiameter:o,holeDiameter:e??.5*o}},Xo={"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}},Vo={top:"red",bottom:"blue",inner1:"green",inner2:"yellow",inner3:"orange",inner4:"purple",inner5:"cyan",inner6:"magenta",inner7:"lime",inner8:"brown"};function Wo(t){if(Object.hasOwn(Vo,t))return Vo[t];const e=/^inner([1-9]\d*)$/.exec(t);if(e){return`hsl(${137*Number(e[1])%360}, 70%, 45%)`}throw new Error(`No visualization color for layer "${t}"`)}var Ho=(t,e={})=>{const n=[],o=[],i=[],r=[],s=wo(t),a=e.traceColorMode??"layer",c=t.layerCount,l=Yo(t),d=Oo(t);if(t.connections)for(const e of t.connections)for(const t of e.pointsToConnect){const n=xo(t),o=e.__rootConnectionNames??[e.name];i.push({x:t.x,y:t.y,color:s[e.name],layer:Fo(t,c),label:[e.name,o.join(", "),n.join(",")].join("\n")})}if(t.traces)for(const e of t.traces){let i=t.minTraceWidth;const d=e.route.filter(t=>"jumper"===t.route_type),h=(t,e)=>{const n=.01;for(const o of d){const i=Math.abs(t.x-o.start.x)<n&&Math.abs(t.y-o.start.y)<n&&Math.abs(e.x-o.end.x)<n&&Math.abs(e.y-o.end.y)<n,r=Math.abs(t.x-o.end.x)<n&&Math.abs(t.y-o.end.y)<n&&Math.abs(e.x-o.start.x)<n&&Math.abs(e.y-o.start.y)<n;if(i||r)return!0}return!1};for(const t of e.route)if("via"===t.route_type){const n=ko(t.from_layer,c),i=ko(t.to_layer,c),r=(t.via_diameter??l.padDiameter)/2,d=Array.from({length:Math.abs(i-n)+1},(t,e)=>Math.min(n,i)+e);o.push({center:{x:t.x,y:t.y},radius:r,fill:"net"===a?s[e.connection_name]:"blue",stroke:"none",layer:`z${d.join(",")}`})}else if("through_obstacle"===t.route_type){const o=s[e.connection_name]??"purple";n.push({points:[t.start,t.end],strokeColor:To(o,.35),strokeWidth:t.width,strokeDash:[.1,.1],layer:zo([t.from_layer,t.to_layer],c),label:`${e.connection_name} through_obstacle`})}let u;for(let t=0;t<e.route.length-1;t++){const o=e.route[t],l=e.route[t+1];if("jumper"===o.route_type){u=void 0;const t=s[e.connection_name]??"rgba(255, 165, 0, 0.8)",i=o.footprint,a=Xo["1206x4_pair"===i?"1206x4_pair":"0603"]??Xo["0603"],l=o.end.x-o.start.x,d=o.end.y-o.start.y,h=Math.abs(l)>Math.abs(d),p=h?a.padLength:a.padWidth,m=h?a.padWidth:a.padLength;r.push({center:o.start,width:p,height:m,fill:To(t,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:zo([o.layer],c)}),r.push({center:o.end,width:p,height:m,fill:To(t,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:zo([o.layer],c)}),n.push({points:[o.start,o.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*a.padWidth,layer:zo([o.layer],c)})}else if("wire"===o.route_type&&"wire"===l.route_type&&l.layer===o.layer){if(h({x:o.x,y:o.y},{x:l.x,y:l.y})){u=void 0;continue}i=o.width;const t="top"===o.layer,r="net"===a?s[e.connection_name]:Wo(o.layer),d=`z${ko(o.layer,c)}`;if(u&&u.layer===d&&u.strokeWidth===i){u.points.push({x:l.x,y:l.y});continue}u={points:[{x:o.x,y:o.y},{x:l.x,y:l.y}],layer:d,strokeWidth:i,strokeColor:t?r:To(r,.5),..."net"===a?{label:e.connection_name}:{},...t?{}:{strokeDash:[.2,.2]}},n.push(u)}else u=void 0}}for(const e of t.obstacles){if(e.isCopperPour)continue;const t=Bo(e,c);if(0===t.length)throw new Error(`Cannot visualize obstacle "${e.obstacleId??"unknown"}" without a valid layer: layers=${e.layers.join(",")}, __zLayers=${e.__zLayers?.join(",")??"unset"}, layerCount=${c}`);const n=Wo("bottom"===(1===t.length?vo(t[0],c):null)?"bottom":"top"),o=.5**t.length;r.push({center:e.center,width:e.width,height:e.height,ccwRotationDegrees:e.ccwRotationDegrees,fill:To(n,o),layer:jo(e,c),label:d(e)})}if(t.jumpers)for(const e of t.jumpers)for(const t of e.pads)r.push({center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,fill:"rgba(255, 165, 0, 0.3)",stroke:"rgba(255, 165, 0, 0.8)",layer:jo(t,c)});return{rects:r,circles:o,lines:n,points:i}};function Go([t,e],[n,o],{lineThickness:i=0}={}){if(0===i)return Uo(t,e,n,o);const r=function(t,e,n,o){if(t.x===e.x&&t.y===e.y)return Jo(t,n,o);if(n.x===o.x&&n.y===o.y)return Jo(n,t,e);if(Uo(t,e,n,o))return 0;const i=[Jo(t,n,o),Jo(e,n,o),Jo(n,t,e),Jo(o,t,e)];return Math.min(...i)}(t,e,n,o);return r<=i}function Uo(t,e,n,o){const i=Zo(t,e,n),r=Zo(t,e,o),s=Zo(n,o,t),a=Zo(n,o,e);return i!==r&&s!==a||(!(0!==i||!qo(t,n,e))||(!(0!==r||!qo(t,o,e))||(!(0!==s||!qo(n,t,o))||!(0!==a||!qo(n,e,o)))))}function Zo(t,e,n){const o=(e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y);return 0===o?0:o>0?1:2}function qo(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 Jo(t,e,n){const o=(n.x-e.x)**2+(n.y-e.y)**2;if(0===o)return Ko(t,e);let i=((t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y))/o;i=Math.max(0,Math.min(1,i));return Ko(t,{x:e.x+i*(n.x-e.x),y:e.y+i*(n.y-e.y)})}function Ko(t,e){const n=t.x-e.x,o=t.y-e.y;return Math.sqrt(n*n+o*o)}function Qo(t){const e=new Map;let n=0;function o(t){for(const[,n]of e)if(n.has(t))return n;const o=new Set;return e.set("connectivity_net"+n++,o),o}for(const n of t){let t=null;for(const i of n){if(t){if(!t.has(i)){const n=o(i);if(n!==t){for(const e of n)t.add(e);e.delete(Array.from(e.entries()).find(([,t])=>t===n)[0])}}}else t=o(i);t.add(i)}}return Object.fromEntries(Array.from(e.entries()).map(([t,e])=>[t,Array.from(e)]))}var ti=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 o=this.getNetConnectedToId(e);return!!o&&(n===o||o===t||o===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}},ei=t=>{const e=[];for(const n of t)if("source_trace"===n.type)e.push([n.source_trace_id,...n.connected_source_port_ids??[],...n.connected_source_net_ids??[]].filter(Boolean));else if("pcb_port"===n.type){const{pcb_port_id:t,source_port_id:o}=n;o&&t&&e.push([o,t])}else if("pcb_smtpad"===n.type){const{pcb_smtpad_id:t,pcb_port_id:o}=n;o&&t&&e.push([t,o])}else if("pcb_plated_hole"===n.type){const{pcb_plated_hole_id:t,pcb_port_id:o}=n;o&&t&&e.push([t,o])}else if("pcb_trace"===n.type){const{pcb_trace_id:t,source_trace_id:o}=n;o&&t&&e.push([t,o])}const n=Qo(e);return new ti(n)},ni=class{circuitJson;traceIdToElm;portIdToElm;connMap;constructor(t){this.circuitJson=t||[],this.traceIdToElm=new Map,this.portIdToElm=new Map,t?(this._buildTraceMap(),this._buildPortMap(),this.connMap=this._buildTraceConnectivityMap()):this.connMap=new ti({})}_buildPortMap(){for(const t of this.circuitJson)"pcb_port"===t.type&&this.portIdToElm.set(t.pcb_port_id,t)}_buildTraceMap(){for(const t of this.circuitJson)"pcb_trace"===t.type&&this.traceIdToElm.set(t.pcb_trace_id,t)}_buildTraceConnectivityMap(){const t=[],e=Array.from(this.traceIdToElm.keys());for(let n=0;n<e.length;n++)for(let o=n+1;o<e.length;o++){const i=this.traceIdToElm.get(e[n]),r=this.traceIdToElm.get(e[o]);this._arePcbTracesConnected(i,r)&&t.push([e[n],e[o]])}for(const e of this.portIdToElm.values())for(const n of this.traceIdToElm.values())for(const o of n.route)"wire"===o.route_type&&(o.start_pcb_port_id===e.pcb_port_id?t.push([e.pcb_port_id,n.pcb_trace_id]):o.end_pcb_port_id===e.pcb_port_id&&t.push([n.pcb_trace_id,e.pcb_port_id]));return new ti(Qo(t))}addTrace(t){this.traceIdToElm.set(t.pcb_trace_id,t);const e=[];for(const n of t.route)"wire"===n.route_type&&(n.start_pcb_port_id&&e.push([n.start_pcb_port_id,t.pcb_trace_id]),n.end_pcb_port_id&&e.push([n.end_pcb_port_id,t.pcb_trace_id]));this.connMap.addConnections(e)}_arePcbTracesConnected(t,e){for(let n=0;n<t.route.length-1;n++){const o=t.route[n],i=t.route[n+1];if("wire"===o.route_type&&"wire"===i.route_type)for(let t=0;t<e.route.length-1;t++){const n=e.route[t],r=e.route[t+1];if("wire"!==n.route_type)continue;if("wire"!==r.route_type)continue;if(Go([o,i],[n,r],{lineThickness:(o.width+n.width)/2}))return!0}}return!1}areTracesConnected(t,e){return this.connMap.areIdsConnected(t,e)}getAllTracesConnectedToTrace(t){const e=this.connMap.getNetConnectedToId(t);return e?this.connMap.getIdsConnectedToNet(e).filter(t=>this.traceIdToElm.has(t)).map(t=>this.traceIdToElm.get(t)):[]}getAllTracesConnectedToPort(t){const e=this.connMap.getNetConnectedToId(t);return e?this.connMap.getIdsConnectedToNet(e).filter(t=>this.traceIdToElm.has(t)).map(t=>this.traceIdToElm.get(t)):[]}},oi=t=>`${Math.round(100*t.x)},${Math.round(100*t.y)}`,ii=t=>{const e=new ti({});for(const n of t.connections){for(const t of n.__rootConnectionNames??[])e.addConnections([[n.name,t]]);n.__netConnectionName&&e.addConnections([[n.name,n.__netConnectionName]]);for(const o of n.pointsToConnect)e.addConnections([[n.name,`${oi(o)}:${"layers"in o?o.layers.map(e=>ko(e,t.layerCount)).sort().join("-"):ko(o.layer,t.layerCount)}`]]),"pcb_port_id"in o&&o.pcb_port_id&&e.addConnections([[n.name,o.pcb_port_id]]),o.pointId&&e.addConnections([[n.name,o.pointId]])}for(const n of t.obstacles){const o=n.offBoardConnectsTo??[],i=Array.from(new Set([n.obstacleId,...n.connectedTo,...o,`${oi(n.center)}:${n.layers.map(e=>ko(e,t.layerCount)).sort().join("-")}`].filter(Boolean)));i.length>0&&e.addConnections([i])}for(const n of t.traces??[]){const t=Array.from(new Set([n.pcb_trace_id,n.connection_name,...n.connectsTo??[]].filter(Boolean)));t.length>0&&e.addConnections([t])}return e},ri=t=>{const e=new ti({});for(const n of t.connections){const t=n.externallyConnectedPointIds??[];e.addConnections(t)}for(const n of t.traces??[]){const t=n.connectsTo??[];0!==t.length&&e.addConnections([[n.pcb_trace_id,...t]])}return e},si=class{MAX_ITERATIONS=1e3;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};pendingEffects;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 ai(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 ci=class extends si{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:o,colorMap:i,shouldReturnCrampedPortPoints:r}){super(),this.nodes=t,this.edges=e,this.traceWidth=n,this.obstacleMargin=o??.15,this.shouldReturnCrampedPortPoints=r,this.minPortSpacing=this.traceWidth+this.obstacleMargin,this.colorMap=i??{},this.nodeMap=new Map(t.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=ai(e),this.MAX_ITERATIONS=1}_step(){this.computeAllSharedEdgeSegments(),this.solved=!0}computeAllSharedEdgeSegments(){for(const t of this.edges){const[e,n]=t.nodeIds,o=this.nodeMap.get(e),i=this.nodeMap.get(n);if(!o||!i)continue;const r=this.computeSharedEdgeSegment(t,o,i);if(r){this.sharedEdgeSegments.push(r),this.edgeSegmentMap.set(t.capacityMeshEdgeId,r);for(const t of r.portPoints)this.portPointMap.set(t.segmentPortPointId,t)}}}computeSharedEdgeSegment(t,e,n){const o=this.findOverlappingSegment(e,n);if(!o)return null;const i=e.availableZ.filter(t=>n.availableZ.includes(t));if(0===i.length)return null;const r=Math.sqrt((o.end.x-o.start.x)**2+(o.end.y-o.start.y)**2),s=Boolean(e._isNarrowQfpPadGap||n._isNarrowQfpPadGap),a=3*this.minPortSpacing/4,c=Math.max(0,r-2*a);if(c<=0&&!e._containsTarget&&!n._containsTarget){if(!this.shouldReturnCrampedPortPoints)return null;const r=[];for(const s of i)r.push({segmentPortPointId:`${t.capacityMeshEdgeId}_pp0_z${s}_cramped`,x:(o.start.x+o.end.x)/2,y:(o.start.y+o.end.y)/2,availableZ:[s],nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],edgeId:t.capacityMeshEdgeId,connectionName:null,distToCentermostPortOnZ:0,cramped:!0});return{edgeId:t.capacityMeshEdgeId,nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],start:o.start,end:o.end,availableZ:i,portPoints:r}}let l=Math.max(1,Math.floor(c/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;l=1}const d=[],h=o.end.x-o.start.x,u=o.end.y-o.start.y,p=(o.start.x+o.end.x)/2,m=(o.start.y+o.end.y)/2;l>5&&(l=5+Math.floor(l/4));const g=[];for(let t=0;t<l;t++){let e;e=0===r||1===l?.5:(a+c*t/(l-1))/r;const n=o.start.x+h*e,i=o.start.y+u*e,s=Math.sqrt((n-p)**2+(i-m)**2);g.push({x:n,y:i,distToCenter:s})}const f=g.reduce((t,e)=>e.distToCenter<t.distToCenter?e:t);for(let o=0;o<l;o++){const{x:r,y:a}=g[o],c=Math.sqrt((r-f.x)**2+(a-f.y)**2);for(const l of i){const i={segmentPortPointId:`${t.capacityMeshEdgeId}_pp${o}_z${l}`,x:r,y:a,availableZ:[l],nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],edgeId:t.capacityMeshEdgeId,connectionName:null,distToCentermostPortOnZ:c,cramped:s};d.push(i)}}return{edgeId:t.capacityMeshEdgeId,nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],start:o.start,end:o.end,availableZ:i,portPoints:d}}shouldSkipOffBoardPortPoint(t,e){const n=this.nodeEdgeMap.get(e.capacityMeshNodeId)??[];for(const o of n){const n=o.nodeIds[0]===e.capacityMeshNodeId?o.nodeIds[1]:o.nodeIds[0];if(n===t.capacityMeshNodeId)continue;const i=this.nodeMap.get(n);if(i?._offBoardConnectionId!==t._offBoardConnectionId)continue;if(2!==this.nodes.filter(e=>e._offBoardConnectionId===t._offBoardConnectionId).length)continue;const r={x:(t.center.x+i.center.x)/2,y:(t.center.y+i.center.y)/2};if(r.x>=e.center.x-e.width/2&&r.x<=e.center.x+e.width/2&&r.y>=e.center.y-e.height/2&&r.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)},o={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)},i=n.end-n.start,r=o.end-o.start;if(i<-1e-4||r<-1e-4)return null;if(i<r){const t=(n.start+n.end)/2;return{start:{x:t,y:o.start},end:{x:t,y:o.end}}}{const t=(o.start+o.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 o=this.edgeSegmentMap.get(n.capacityMeshEdgeId);return o?o.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 o=this.edgeSegmentMap.get(n.capacityMeshEdgeId);return o?.portPoints??[]}assignPortPoint(t,e,n){const o=this.portPointMap.get(t);return!!o&&(null===o.connectionName&&(o.connectionName=e,o.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 li(t,e){const n=t.center.x-t.width/2,o=t.center.x+t.width/2,i=t.center.y-t.height/2,r=t.center.y+t.height/2,s=e.center.x-e.width/2,a=e.center.x+e.width/2,c=e.center.y-e.height/2,l=e.center.y+e.height/2,d=.001,h=(Math.abs(o-s)<d||Math.abs(n-a)<d)&&Math.min(r,l)-Math.max(i,c)>=d,u=(Math.abs(r-c)<d||Math.abs(i-l)<d)&&Math.min(o,a)-Math.max(n,s)>=d;return h||u}var di=class extends si{constructor(t){super(),this.nodes=t,this.edges=[]}nodes;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)&&li(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),e=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t]));for(let e=0;e<t.length;e++)for(let n=e+1;n<t.length;n++){const o=t[e],i=t[n];this.doNodesHaveSharedLayer(o,i)&&(this.doNodesTouchOrOverlap(o,i)&&(this.hasEdgeBetween(o,i)||this.edges.push({capacityMeshEdgeId:this.getNextCapacityMeshEdgeId(),nodeIds:[o.capacityMeshNodeId,i.capacityMeshNodeId]})))}for(const n of t){if(!n._containsObstacle||!n._targetConnectionName)continue;if(!this.edges.some(t=>{if(!t.nodeIds.includes(n.capacityMeshNodeId))return!1;const o=t.nodeIds[0]===n.capacityMeshNodeId?t.nodeIds[1]:t.nodeIds[0],i=e.get(o);return!!i&&(!i._containsObstacle&&!i._containsTarget&&this.doNodesHaveSharedLayer(n,i))}))throw new Error(`Target obstacle region "${n.capacityMeshNodeId}" for connection "${n._targetConnectionName}" has no bordering routing edge`)}}doNodesHaveSharedLayer(t,e){return t.availableZ.some(t=>e.availableZ.includes(t))}hasEdgeBetween(t,e){return this.edges.some(n=>n.nodeIds.includes(t.capacityMeshNodeId)&&n.nodeIds.includes(e.capacityMeshNodeId))}doNodesTouchOrOverlap(t,e){const n=.001,o=t.center.x-t.width/2,i=t.center.x+t.width/2,r=t.center.y-t.height/2,s=t.center.y+t.height/2,a=e.center.x-e.width/2,c=e.center.x+e.width/2,l=e.center.y-e.height/2,d=e.center.y+e.height/2;return o<=c+n&&i+n>=a&&r<=d+n&&s+n>=l}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]),o=this.nodeMap.get(t.nodeIds[1]);if(n?.center&&o?.center){const t=Math.min(...n.availableZ),i=Math.min(...o.availableZ),r={x:n.center.x+t*n.width*.05,y:n.center.y-t*n.width*.05},s={x:o.center.x+i*o.width*.05,y:o.center.y-i*o.width*.05},a=Array.from(new Set([...n.availableZ,...o.availableZ])).sort();e.lines.push({layer:`z${a.join(",")}`,points:[r,s],strokeDash:n.availableZ.join(",")===o.availableZ.join(",")?void 0:"10 5"})}}return e}},hi=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,o=e.center.x+e.width/2,i=e.center.y+e.height/2,r=Math.floor(t/this.CELL_SIZE),s=Math.floor(o/this.CELL_SIZE),a=Math.floor(n/this.CELL_SIZE),c=Math.floor(i/this.CELL_SIZE);for(let t=r;t<=s;t++)for(let n=a;n<=c;n++){const o=`${t}x${n}`,i=this.buckets.get(o);i?i.push(e):this.buckets.set(o,[e])}}}nodes;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,o){const i=[],r=new Set,s=t-n/2,a=e-o/2,c=t+n/2,l=e+o/2,d=Math.floor(s/this.CELL_SIZE),h=Math.floor(c/this.CELL_SIZE),u=Math.floor(a/this.CELL_SIZE),p=Math.floor(l/this.CELL_SIZE);for(let t=d;t<=h;t++)for(let e=u;e<=p;e++){const n=`${t}x${e}`,o=this.buckets.get(n)||[];for(const t of o)r.has(t.capacityMeshNodeId)||(r.add(t.capacityMeshNodeId),i.push(t))}return i}},ui=class extends di{constructor(t){super(t),this.nodes=t,this.MAX_ITERATIONS=1e7,this.nodeTree=new hi(this.nodes),this.currentNodeIndex=0,this.edgeSet=new Set}nodes;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(!li(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++}},pi=(...t)=>{const e={points:[],lines:[],circles:[],rects:[],polygons:[],infiniteLines:[],arrows:[],texts:[]};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}))]),t.polygons&&(e.polygons=[...e.polygons||[],...t.polygons.map(t=>({...t,step:n}))]),t.infiniteLines&&(e.infiniteLines=[...e.infiniteLines||[],...t.infiniteLines.map(t=>({...t,step:n}))]),t.arrows&&(e.arrows=[...e.arrows||[],...t.arrows.map(t=>({...t,step:n}))]),t.texts&&(e.texts=[...e.texts||[],...t.texts.map(t=>({...t,step:n}))]))}),e};function mi(t,e,n){const o=[];let i=null;for(let r=0;r<t.length;r++){const s=t[r];i?i.z===s.z?i.points.push({x:s.x,y:s.y}):(o.push(i),i={points:[{x:s.x,y:s.y}],z:s.z,connectionName:e,color:n}):i={points:[{x:s.x,y:s.y}],z:s.z,connectionName:e,color:n},r===t.length-1&&i&&o.push(i)}return o}function gi(t,e){return{x:t.a*e.x+t.b*e.y+t.c,y:t.d*e.x+t.e*e.y+t.f}}var fi=(t,e,n)=>{const[o,i]=t;if(o===i)return;const r=((t,e)=>{const n=t.portPointId??`${t.connectionName}:${t.x}:${t.y}:${t.z}`,o=e.portPointId??`${e.connectionName}:${e.x}:${e.y}:${e.z}`;return n<o?`${n}|${o}`:`${o}|${n}`})(o,i);e.has(r)||(e.add(r),n.push(t))},yi=(t,e,n)=>{for(let o=0;o<t.length-1;o++)fi([t[o],t[o+1]],e,n)},_i=t=>{const e=[],n=new Set,o=(t=>{const e=new Map;for(const n of t)n.portPointId&&e.set(n.portPointId,n);return e})(t);for(const i of t){if(i.prevPortPointId){const t=o.get(i.prevPortPointId);t&&t.connectionName===i.connectionName&&fi([t,i],n,e)}if(i.nextPortPointId){const t=o.get(i.nextPortPointId);t&&t.connectionName===i.connectionName&&fi([i,t],n,e)}}if(0===e.length)return yi(t,n,e),e;const i=(t=>{const e=new Set;for(const[n,o]of t)n.portPointId&&e.add(n.portPointId),o.portPointId&&e.add(o.portPointId);return e})(e),r=t.filter(t=>!t.portPointId||!i.has(t.portPointId));return yi(r,n,e),e};function bi(t,e,n){return Math.max(e,Math.min(n,t))}function xi(t){const e=t.planeSize*t.layers,n=t.connectionCount,o=Math.sqrt(n),i=Math.max(1,t.maxIterations),r=bi(Math.round(e*(8+1.2*o)),15e4,12e6),s=bi(Math.round(r*t.effort),15e4,12e6),a=bi(Math.round(.2*i),15e4,2e6);return{maxIterationsIters:Math.max(1,Math.min(i,Math.max(a,s))),baseSearchBudgetIters:bi(Math.round(e*(10+.8*o)*t.effort),5e4,4e6)}}function vi(t,e){for(let n=t;n;n=n.prev)if(n.id===e)return!0;return!1}var Si=class{f=[];seq=[];id=[];n=0;push(t,e,n){let o=this.n++;for(this.f[o]=t,this.seq[o]=e,this.id[o]=n;o>0;){const t=o-1>>1;if(this.less(t,o))break;this.swap(o,t),o=t}}pop(){const t=this.id[0];return this.n--,this.n>0&&(this.f[0]=this.f[this.n],this.seq[0]=this.seq[this.n],this.id[0]=this.id[this.n],this.siftDown(0)),t}get size(){return this.n}clear(){this.n=0}siftDown(t){for(;;){const e=2*t+1,n=e+1;if(e>=this.n)return;let o=e;if(n<this.n&&!this.less(e,n)&&(o=n),this.less(t,o))return;this.swap(t,o),t=o}}less(t,e){const n=this.f[t],o=this.f[e];return n!==o?n<o:this.seq[t]<this.seq[e]}swap(t,e){const n=this.f[t];this.f[t]=this.f[e],this.f[e]=n;const o=this.seq[t];this.seq[t]=this.seq[e],this.seq[e]=o;const i=this.id[t];this.id[t]=this.id[e],this.id[e]=i}};var Ii=[-1,-1,-1,0,0,1,1,1],Ci=[-1,0,1,-1,1,-1,0,1],Pi=class extends kt{getSolverName(){return"HighDensitySolverA01"}nodeWithPortPoints;cellSizeMm;viaDiameter;MAX_RIPS;maxCellCount;traceThickness;traceMargin;viaMinDistFromBorder;showPenaltyMap;showUsedCellMap;effort;stepMultiplier;hyperParameters;initialPenaltyFn;rows;cols;layers;gridOrigin;gridToBoundsTransform;availableZ;zToLayer;layerToZ;connNameToId;connIdToName;connIdToRootNet;overlapFriendlyRootNets;planeSize;usedCellsFlat;portOwnerFlat;usedDiagFlat;penalty2d;visitedStamp;sharedCrossRootPortCells;stamp=0;viaOffsetsDr;viaOffsetsDc;viaOffsetsLen;minViaRow;maxViaRow;minViaCol;maxViaCol;usedIndicesByConn;usedDiagIndicesByConn;unsolvedSegs;solvedRoutes;activeConnSeg=null;activeConnId=-1;crossLayerSearch=!1;nodePool;heap;seqCounter=0;_viaOccs=[];ripCount;totalRipEvents=0;searchIterations=0;consecutiveSkips=0;penaltyCap;baseSearchBudgetIters;_moveCost=0;_moveRipped=null;get unsolvedConnections(){return this.unsolvedSegs}get solvedConnectionsMap(){return this.solvedRoutes}get activeConnection(){if(!this.activeConnSeg)return null;const t=this.activeConnSeg;return{connectionName:this.connIdToName[t.connId]??"",start:{row:t.startRow,col:t.startCol,z:t.startZ,x:0,y:0},end:{row:t.endRow,col:t.endCol,z:t.endZ,x:0,y:0}}}get openSet(){return{length:this.heap?.size??0}}get gridStats(){return{cells:this.planeSize||0,layers:this.layers||0,states:(this.planeSize||0)*(this.layers||0)}}constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.cellSizeMm=t.cellSizeMm,this.viaDiameter=t.viaDiameter,this.maxCellCount=t.maxCellCount,this.traceThickness=t.traceThickness??.1,this.traceMargin=t.traceMargin??.15,this.viaMinDistFromBorder=t.viaMinDistFromBorder??.15,this.showPenaltyMap=t.showPenaltyMap??!1,this.showUsedCellMap=t.showUsedCellMap??!1,this.effort=t.effort??1,this.stepMultiplier=Math.max(1,Math.floor(t.stepMultiplier??1)),this.hyperParameters={shuffleSeed:0,ripCost:10,ripTracePenalty:.5,ripViaPenalty:.75,viaBaseCost:.1,greedyMultiplier:1.5,...t.hyperParameters},this.MAX_ITERATIONS=1e8,this.MAX_RIPS=200,this.initialPenaltyFn=t.initialPenaltyFn}getConstructorParams(){return[{nodeWithPortPoints:this.nodeWithPortPoints,cellSizeMm:this.cellSizeMm,viaDiameter:this.viaDiameter,maxCellCount:this.maxCellCount,stepMultiplier:this.stepMultiplier,traceThickness:this.traceThickness,traceMargin:this.traceMargin,viaMinDistFromBorder:this.viaMinDistFromBorder,showPenaltyMap:this.showPenaltyMap,showUsedCellMap:this.showUsedCellMap,effort:this.effort,hyperParameters:this.hyperParameters,initialPenaltyFn:this.initialPenaltyFn}]}_setup(){const{nodeWithPortPoints:t,cellSizeMm:e}=this,{width:n,height:o,center:i}=t;this.availableZ=t.availableZ??[...new Set(t.portPoints.map(t=>t.z))].sort((t,e)=>t-e),this.rows=Math.floor(o/e),this.cols=Math.floor(n/e),this.layers=this.availableZ.length,this.planeSize=this.rows*this.cols;const r=this.layers*this.planeSize;if(void 0!==this.maxCellCount&&r>this.maxCellCount)return this.error=`Cell count ${r} exceeds maxCellCount ${this.maxCellCount}`,void(this.failed=!0);const s=this.layers*Math.max(0,this.rows-1)*Math.max(0,this.cols-1)*2;this.zToLayer=new Map,this.layerToZ=new Map;for(let t=0;t<this.availableZ.length;t++){const e=this.availableZ[t];this.zToLayer.set(e,t),this.layerToZ.set(t,e)}if(this.gridOrigin={x:i.x-n/2,y:i.y-o/2},this.gridToBoundsTransform=function(t){const{originX:e,originY:n,rows:o,cols:i,cellSizeMm:r,width:s,height:a}=t;let c,l,d,h;return i>1?(c=s/((i-1)*r),l=e*(1-c)-.5*r*c):(c=1,l=e+s/2-(e+.5*r)),o>1?(d=a/((o-1)*r),h=n*(1-d)-.5*r*d):(d=1,h=n+a/2-(n+.5*r)),{a:c,b:0,c:l,d:0,e:d,f:h}}({originX:this.gridOrigin.x,originY:this.gridOrigin.y,rows:this.rows,cols:this.cols,cellSizeMm:e,width:n,height:o}),this.connNameToId=new Map,this.connIdToName=[],this.connIdToRootNet=[],this.overlapFriendlyRootNets=new Set,this.penalty2d=new Float64Array(this.planeSize),this.initialPenaltyFn)for(let t=0;t<this.rows;t++){const n=t*this.cols;for(let o=0;o<this.cols;o++){const i=this.gridOrigin.x+(o+.5)*e,r=this.gridOrigin.y+(t+.5)*e,s=(o+.5)/this.cols,a=(t+.5)/this.rows;this.penalty2d[n+o]=this.initialPenaltyFn({x:i,y:r,px:s,py:a,row:t,col:o})}}this.usedCellsFlat=new Int32Array(r).fill(-1),this.portOwnerFlat=new Int32Array(r).fill(-1),this.usedDiagFlat=new Int32Array(s).fill(-1),this.visitedStamp=new Uint32Array(r),this.stamp=0;const a=Math.ceil(this.viaDiameter/2/e),c=a*a,l=[],d=[];for(let t=-a;t<=a;t++)for(let e=-a;e<=a;e++)t*t+e*e<=c&&(l.push(t),d.push(e));if(this.viaOffsetsLen=l.length,this.viaOffsetsDr=new Int32Array(l),this.viaOffsetsDc=new Int32Array(d),this.viaMinDistFromBorder>0){const t=Math.ceil(this.viaMinDistFromBorder/e);this.minViaRow=t,this.maxViaRow=this.rows-1-t,this.minViaCol=t,this.maxViaCol=this.cols-1-t}else this.minViaRow=0,this.maxViaRow=this.rows-1,this.minViaCol=0,this.maxViaCol=this.cols-1;this.unsolvedSegs=this.buildConnectionSegs(),this.sharedCrossRootPortCells=new Set;const h=new Map;for(const t of this.nodeWithPortPoints.portPoints){const e=this.connNameToId.get(t.connectionName);if(void 0===e)continue;const n=this.pointToCell(t),o=(n.z*this.rows+n.row)*this.cols+n.col,i=this.connIdToRootNet[e],r=h.get(o);void 0===r?h.set(o,i):r!==i&&this.sharedCrossRootPortCells.add(o);const s=this.portOwnerFlat[o];this.portOwnerFlat[o]=-1===s||s===e?e:-2}this.solvedRoutes=new Map,this.usedIndicesByConn=[],this.usedDiagIndicesByConn=[],this.ripCount=[],this.consecutiveSkips=0,this.penaltyCap=.5*this.hyperParameters.ripCost,this.shuffleConnections();const u=xi({planeSize:this.planeSize,layers:this.layers,connectionCount:this.unsolvedSegs.length,effort:this.effort,maxIterations:this.MAX_ITERATIONS});this.baseSearchBudgetIters=u.baseSearchBudgetIters,this.MAX_ITERATIONS=u.maxIterationsIters,this.activeConnSeg=null,this.activeConnId=-1,this.nodePool=[],this.heap=new Si,this.seqCounter=0}_step(){for(let t=0;t<this.stepMultiplier;t++){if(this.solved||this.failed)return;this.stepOnce()}}stepOnce(){if(!this.activeConnSeg){if(0===this.unsolvedSegs.length)return void(this.solved=!0);const t=this.unsolvedSegs.shift();this.activeConnSeg=t,this.activeConnId=t.connId,this.crossLayerSearch=t.startZ!==t.endZ,this.nodePool=[],this.heap.clear(),this.seqCounter=0,this.searchIterations=0,this.nextStamp();const e=this.computeH(t.startZ,t.startRow,t.startCol,t.endZ,t.endRow,t.endCol)*this.hyperParameters.greedyMultiplier;return this.nodePool.push({z:t.startZ,row:t.startRow,col:t.startCol,g:0,f:e,parentIdx:-1,ripped:null}),void this.heap.push(e,this.seqCounter++,0)}this.searchIterations++;const t=this.ripCount[this.activeConnId]??0,e=Math.round(this.baseSearchBudgetIters*(1+.25*Math.min(t,10)));if(this.searchIterations>e){const t=this.penalty2d;for(let e=0;e<t.length;e++)t[e]=.9*t[e];return this.unsolvedSegs.push(this.activeConnSeg),this.activeConnSeg=null,this.activeConnId=-1,this.heap.clear(),this.nodePool=[],this.consecutiveSkips++,void(this.consecutiveSkips>=3*this.unsolvedSegs.length&&(this.error=`Convergence failure: ${this.unsolvedSegs.length} connections stuck`,this.failed=!0))}if(0===this.heap.size)return this.error=`No path found for ${this.connIdToName[this.activeConnId]}`,void(this.failed=!0);const n=this.heap.pop(),o=this.nodePool[n],{z:i,row:r,col:s,g:a,ripped:c}=o,l=(i*this.rows+r)*this.cols+s;if(this.visitedStamp[l]===this.stamp)return;this.visitedStamp[l]=this.stamp;const d=this.activeConnSeg;if(i===d.endZ&&r===d.endRow&&s===d.endCol)return this.finalizeRoute(n),this.activeConnSeg=null,void(this.activeConnId=-1);const h=d.endZ,u=d.endRow,p=d.endCol,m=this.activeConnId,g=this.rows,f=this.cols,y=(this.cellSizeMm,this.visitedStamp),_=this.stamp;for(let t=0;t<8;t++){const e=r+Ii[t],o=s+Ci[t];if(e<0||e>=g||o<0||o>=f)continue;if(y[(i*g+e)*f+o]===_)continue;if(this.computeMoveCostAndRips(m,i,r,s,i,e,o,c),this._moveCost<0)continue;const l=a+this._moveCost,d=l+this.computeH(i,e,o,h,u,p)*this.hyperParameters.greedyMultiplier,b=this.nodePool.length;this.nodePool.push({z:i,row:e,col:o,g:l,f:d,parentIdx:n,ripped:this._moveRipped}),this.heap.push(d,this.seqCounter++,b)}if(r>=this.minViaRow&&r<=this.maxViaRow&&s>=this.minViaCol&&s<=this.maxViaCol)for(let t=0;t<this.layers;t++){if(t===i)continue;if(y[(t*g+r)*f+s]===_)continue;if(this.computeMoveCostAndRips(m,i,r,s,t,r,s,c),this._moveCost<0)continue;const e=a+this._moveCost,o=e+this.computeH(t,r,s,h,u,p)*this.hyperParameters.greedyMultiplier,l=this.nodePool.length;this.nodePool.push({z:t,row:r,col:s,g:e,f:o,parentIdx:n,ripped:this._moveRipped}),this.heap.push(o,this.seqCounter++,l)}}computeMoveCostAndRips(t,e,n,o,i,r,s,a){let c=0,l=a;const d=this.cols;if(e!==i){c+=this.hyperParameters.viaBaseCost,c+=Math.min(this.penalty2d[r*d+s],this.penaltyCap);const e=(i*this.rows+r)*d+s,n=this.portOwnerFlat[e],o=this.connIdToRootNet[n]===this.connIdToRootNet[t]&&this.overlapFriendlyRootNets.has(this.connIdToRootNet[t]),a=this.activeConnSeg,h=!!a&&i===a.endZ&&r===a.endRow&&s===a.endCol;if(n>=0&&n!==t&&!o&&!h)return this._moveCost=-1,void(this._moveRipped=l);this.fillViaOccupants(r,s,t);const u=this._viaOccs;for(let t=0;t<u.length;t++){const e=u[t];vi(l,e)||(c+=this.hyperParameters.ripCost,l={id:e,prev:l}),c+=this.hyperParameters.ripViaPenalty}}else{const e=n>r?n-r:r-n,a=o>s?o-s:s-o;c+=(e+a>1?Math.SQRT2:1)*this.cellSizeMm,c+=Math.min(this.penalty2d[r*d+s],this.penaltyCap);const h=(i*this.rows+r)*d+s,u=this.portOwnerFlat[h],p=this.connIdToRootNet[u]===this.connIdToRootNet[t]&&this.overlapFriendlyRootNets.has(this.connIdToRootNet[t]),m=this.activeConnSeg,g=!!m&&i===m.endZ&&r===m.endRow&&s===m.endCol;if(u>=0&&u!==t&&!p&&!g)return this._moveCost=-1,void(this._moveRipped=l);const f=this.usedCellsFlat[h],y=this.connIdToRootNet[f]===this.connIdToRootNet[t]&&this.overlapFriendlyRootNets.has(this.connIdToRootNet[t]);if(-1===f||f===t||y||(vi(l,f)||(c+=this.hyperParameters.ripCost,l={id:f,prev:l}),c+=this.hyperParameters.ripTracePenalty),1===e&&1===a){const e=n<r?n:r,a=o<s?o:s,c=1^(n<r&&o<s||n>r&&o>s?0:1),d=this.cols-1,h=2*((i*(this.rows-1)+e)*d+a),u=this.usedDiagFlat[h+c],p=this.connIdToRootNet[u]===this.connIdToRootNet[t]&&this.overlapFriendlyRootNets.has(this.connIdToRootNet[t]);if(-1!==u&&u!==t&&!p)return this._moveCost=-1,void(this._moveRipped=l)}}this._moveCost=c,this._moveRipped=l}fillViaOccupants(t,e,n){const o=this._viaOccs;o.length=0;const i=this.rows,r=this.cols,s=this.viaOffsetsDr,a=this.viaOffsetsDc,c=this.viaOffsetsLen,l=this.usedCellsFlat;for(let d=0;d<this.layers;d++){const h=d*this.planeSize;for(let d=0;d<c;d++){const c=t+s[d],u=e+a[d];if(c<0||u<0||c>=i||u>=r)continue;const p=l[h+c*r+u];if(-1===p||p===n)continue;if(this.connIdToRootNet[p]===this.connIdToRootNet[n]&&this.overlapFriendlyRootNets.has(this.connIdToRootNet[n]))continue;let m=!1;for(let t=0;t<o.length;t++)if(o[t]===p){m=!0;break}m||o.push(p)}}}shouldSkipFixedPortHalo(t,e){const n=this.portOwnerFlat[t];if(n===e)return!1;if(-2===n)return!0;if(n<0)return!1;return!(this.connIdToRootNet[n]===this.connIdToRootNet[e]&&this.overlapFriendlyRootNets.has(this.connIdToRootNet[e]))}nextStamp(){this.stamp=this.stamp+1>>>0,0===this.stamp&&(this.visitedStamp.fill(0),this.stamp=1)}computeH(t,e,n,o,i,r){const s=Math.abs(e-i)+Math.abs(n-r);if(t===o)return s*this.cellSizeMm;if(!this.crossLayerSearch)return s*this.cellSizeMm+this.hyperParameters.viaBaseCost;const a=Math.max(this.minViaRow,Math.min(this.maxViaRow,e)),c=Math.max(this.minViaCol,Math.min(this.maxViaCol,n)),l=Math.max(this.minViaRow,Math.min(this.maxViaRow,i)),d=Math.max(this.minViaCol,Math.min(this.maxViaCol,r)),h=Math.abs(e-a)+Math.abs(n-c)+Math.abs(a-i)+Math.abs(c-r),u=Math.abs(e-l)+Math.abs(n-d)+Math.abs(l-i)+Math.abs(d-r);return Math.max(Math.min(h,u),s)*this.cellSizeMm+this.hyperParameters.viaBaseCost}internConn(t,e){const n=this.connNameToId.get(t);if(void 0!==n)return n;const o=this.connIdToName.length;var i;return this.connIdToName.push(t),this.connIdToRootNet.push((i=t,e??i.replace(/_mst\d+$/,""))),this.connNameToId.set(t,o),o}buildConnectionSegs(){const t=new Map;for(const e of this.nodeWithPortPoints.portPoints){const n=e.connectionName;t.has(n)||t.set(n,{points:[],rootConnectionName:e.rootConnectionName}),t.get(n).points.push(e)}const e=[],n=new Set;for(const[o,i]of t){const t=i.points,r=_i(t);if(0===r.length)continue;const s=this.internConn(o,i.rootConnectionName);for(const[t,a]of r){const r=this.pointToCell(t),c=this.pointToCell(a),l=`${r.z}:${r.row}:${r.col}`,d=`${c.z}:${c.row}:${c.col}`,h=l<d?`${l}|${d}`:`${d}|${l}`,u=i.rootConnectionName??o,p=`${u}|${h}`;n.has(p)?this.overlapFriendlyRootNets.add(u):(n.add(p),e.push({connId:s,startZ:r.z,startRow:r.row,startCol:r.col,startPoint:t,endZ:c.z,endRow:c.row,endCol:c.col,endPoint:a}))}}return e}pointToCell(t){const e=Math.max(0,Math.min(this.cols-1,Math.round((t.x-this.gridOrigin.x)/this.cellSizeMm-.5))),n=Math.max(0,Math.min(this.rows-1,Math.round((t.y-this.gridOrigin.y)/this.cellSizeMm-.5)));return{z:this.zToLayer.get(t.z)??0,row:n,col:e}}shuffleConnections(){const t=this.unsolvedSegs;let e=this.hyperParameters.shuffleSeed;const n=()=>(e=1664525*e+1013904223&4294967295,(e>>>0)/4294967295);for(let e=t.length-1;e>0;e--){const o=Math.floor(n()*(e+1)),i=t[e];t[e]=t[o],t[o]=i}}finalizeRoute(t){this.consecutiveSkips=Math.max(0,this.consecutiveSkips-1);const e=[];let n=t;for(;n>=0;){const t=this.nodePool[n];e.push({z:t.z,row:t.row,col:t.col}),n=t.parentIdx}for(e.reverse();e.length>1;){const t=e[0],n=(t.z*this.rows+t.row)*this.cols+t.col;if(!this.sharedCrossRootPortCells.has(n))break;e.shift()}for(;e.length>1;){const t=e[e.length-1],n=(t.z*this.rows+t.row)*this.cols+t.col;if(!this.sharedCrossRootPortCells.has(n))break;e.pop()}const o=[];for(let t=1;t<e.length;t++)e[t].z!==e[t-1].z&&o.push({row:e[t].row,col:e[t].col});const i=e[0],r=e[e.length-1],s=this.activeConnId,a=[];for(let e=this.nodePool[t].ripped;e;e=e.prev)a.push(e.id);for(let t=0;t<a.length;t++)if(this.ripTrace(a[t]),this.failed)return;const c=Math.ceil(this.traceMargin/this.cellSizeMm),l=[],d=this.rows,h=this.cols,u=this.usedCellsFlat;for(let t=0;t<e.length;t++){const n=e[t];for(let t=-c;t<=c;t++)for(let e=-c;e<=c;e++){const o=n.row+t,i=n.col+e;if(o<0||o>=d||i<0||i>=h)continue;const r=(n.z*d+o)*h+i;if((o!==n.row||i!==n.col)&&this.shouldSkipFixedPortHalo(r,s))continue;const a=u[r],c=this.connIdToRootNet[a]===this.connIdToRootNet[s]&&this.overlapFriendlyRootNets.has(this.connIdToRootNet[s]);(-1===a||a===s||c)&&(u[r]=s,l.push(r))}}const p=[],m=this.viaOffsetsDr,g=this.viaOffsetsDc,f=this.viaOffsetsLen;for(let t=0;t<o.length;t++){const e=o[t];for(let t=0;t<this.layers;t++){const n=t*this.planeSize;for(let t=0;t<f;t++){const o=e.row+m[t],i=e.col+g[t];if(o<0||o>=d||i<0||i>=h)continue;const r=n+o*h+i;if((o!==e.row||i!==e.col)&&this.shouldSkipFixedPortHalo(r,s))continue;const a=u[r],c=this.connIdToRootNet[a]===this.connIdToRootNet[s]&&this.overlapFriendlyRootNets.has(this.connIdToRootNet[s]);if(-1!==a&&a!==s&&!c){let t=!1;for(let e=0;e<p.length;e++)if(p[e]===a){t=!0;break}t||p.push(a)}u[r]=s,l.push(r)}}}const y=[],_=this.cols-1;for(let t=1;t<e.length;t++){const n=e[t-1],o=e[t];if(n.z!==o.z)continue;const i=n.row>o.row?n.row-o.row:o.row-n.row,r=n.col>o.col?n.col-o.col:o.col-n.col;if(1!==i||1!==r)continue;const a=n.row<o.row?n.row:o.row,c=n.col<o.col?n.col:o.col,l=n.row<o.row&&n.col<o.col||n.row>o.row&&n.col>o.col?0:1,d=1^l,h=2*((n.z*(this.rows-1)+a)*_+c),u=h+d,p=this.usedDiagFlat[u],m=this.connIdToRootNet[p]===this.connIdToRootNet[s]&&this.overlapFriendlyRootNets.has(this.connIdToRootNet[s]);if(-1!==p&&p!==s&&!m)continue;const g=h+l;this.usedDiagFlat[g]=s,y.push(g)}for(;this.usedIndicesByConn.length<=s;)this.usedIndicesByConn.push([]);const b=this.usedIndicesByConn[s]??[];for(b.push(...l),this.usedIndicesByConn[s]=b;this.usedDiagIndicesByConn.length<=s;)this.usedDiagIndicesByConn.push([]);const x=this.usedDiagIndicesByConn[s]??[];x.push(...y),this.usedDiagIndicesByConn[s]=x;const v=this.solvedRoutes.get(s)??[];v.push({connId:s,startZ:i.z,startRow:i.row,startCol:i.col,startPoint:this.activeConnSeg.startPoint,endZ:r.z,endRow:r.row,endCol:r.col,endPoint:this.activeConnSeg.endPoint,cells:e,viaCells:o}),this.solvedRoutes.set(s,v);for(let t=0;t<p.length;t++)if(this.ripTrace(p[t]),this.failed)return;if(a.length>0||p.length>0){const t=this.penalty2d,e=this.penaltyCap;if(this.totalRipEvents>50)for(let e=0;e<t.length;e++)t[e]=.99*t[e];else for(let n=0;n<t.length;n++)t[n]>e&&(t[n]=.5*t[n])}}ripTrace(t){for(;this.ripCount.length<=t;)this.ripCount.push(0);if(this.ripCount[t]++,this.totalRipEvents++,this.totalRipEvents>=this.MAX_RIPS)return this.error=`Convergence failure: exceeded MAX_RIPS ${this.MAX_RIPS}`,void(this.failed=!0);const e=this.solvedRoutes.get(t)??[];if(e.length>0){const t=this.cols;for(const n of e){for(let e=0;e<n.cells.length;e++){const o=n.cells[e],i=o.row*t+o.col;this.penalty2d[i]=this.penalty2d[i]+this.hyperParameters.ripTracePenalty}for(let e=0;e<n.viaCells.length;e++){const o=n.viaCells[e],i=o.row*t+o.col;this.penalty2d[i]=this.penalty2d[i]+this.hyperParameters.ripViaPenalty}}}const n=this.usedIndicesByConn[t];if(n){const e=this.usedCellsFlat;for(let o=0;o<n.length;o++){const i=n[o];e[i]===t&&(e[i]=-1)}this.usedIndicesByConn[t]=[]}const o=this.usedDiagIndicesByConn[t];if(o){const e=this.usedDiagFlat;for(let n=0;n<o.length;n++){const i=o[n];e[i]===t&&(e[i]=-1)}this.usedDiagIndicesByConn[t]=[]}if(e.length>0){this.solvedRoutes.delete(t);for(const n of e)this.unsolvedSegs.push({connId:t,startZ:n.startZ,startRow:n.startRow,startCol:n.startCol,startPoint:n.startPoint,endZ:n.endZ,endRow:n.endRow,endCol:n.endCol,endPoint:n.endPoint})}}visualize(){const t=["red","blue","orange","green"],e=[],n=[],o=[],i=[],{width:r,height:s,center:a}=this.nodeWithPortPoints;i.push({center:{x:a.x,y:a.y},width:r,height:s,stroke:"gray"});const c=this.gridToBoundsTransform;if(this.showPenaltyMap&&this.penalty2d){let t=0;for(let e=0;e<this.penalty2d.length;e++)this.penalty2d[e]>t&&(t=this.penalty2d[e]);if(t>0)for(let e=0;e<this.rows;e++)for(let n=0;n<this.cols;n++){const o=this.penalty2d[e*this.cols+n];if(o<=0)continue;const r=Math.min(.6,o/t*.6),s=gi(c,{x:this.gridOrigin.x+(n+.5)*this.cellSizeMm,y:this.gridOrigin.y+(e+.5)*this.cellSizeMm});i.push({center:s,width:this.cellSizeMm*c.a,height:this.cellSizeMm*c.e,fill:`rgba(255,165,0,${r.toFixed(3)})`})}}if(this.showUsedCellMap&&this.usedCellsFlat)for(let t=0;t<this.layers;t++)for(let e=0;e<this.rows;e++)for(let n=0;n<this.cols;n++){if(-1===this.usedCellsFlat[(t*this.rows+e)*this.cols+n])continue;const o=gi(c,{x:this.gridOrigin.x+(n+.5)*this.cellSizeMm,y:this.gridOrigin.y+(e+.5)*this.cellSizeMm});i.push({center:o,width:this.cellSizeMm*c.a,height:this.cellSizeMm*c.e,fill:"rgba(0,0,255,0.5)"})}for(const n of this.nodeWithPortPoints.portPoints)e.push({x:n.x,y:n.y,color:t[n.z]??"gray",label:n.connectionName});const l=["rgba(255,0,0,0.75)","rgba(0,0,255,0.75)","rgba(255,165,0,0.75)","rgba(0,128,0,0.75)"],d=this.getOutput();for(const t of d){if(t.route.length<2)continue;let e=0;for(let o=1;o<t.route.length;o++){const i=t.route[o-1];t.route[o].z!==i.z&&(o-e>=2&&n.push({points:t.route.slice(e,o).map(t=>({x:t.x,y:t.y})),strokeColor:l[i.z]??"rgba(128,128,128,0.75)",strokeWidth:this.traceThickness}),e=o)}if(t.route.length-e>=2){const o=t.route[e].z;n.push({points:t.route.slice(e).map(t=>({x:t.x,y:t.y})),strokeColor:l[o]??"rgba(128,128,128,0.75)",strokeWidth:this.traceThickness})}}for(const t of d)for(const e of t.vias)o.push({center:{x:e.x,y:e.y},radius:this.viaDiameter/2,fill:"rgba(0,0,0,0.3)",stroke:"black"});if(this.activeConnSeg&&this.visitedStamp){const t=this.stamp;for(let n=0;n<this.layers;n++)for(let o=0;o<this.rows;o++)for(let i=0;i<this.cols;i++){if(this.visitedStamp[(n*this.rows+o)*this.cols+i]!==t)continue;const r=gi(c,{x:this.gridOrigin.x+(i+.5)*this.cellSizeMm,y:this.gridOrigin.y+(o+.5)*this.cellSizeMm});e.push({x:r.x,y:r.y,color:"rgba(0,0,255,0.2)"})}}return{points:e,lines:n,circles:o,rects:i,coordinateSystem:"cartesian",title:`HighDensityA01 [${this.solvedRoutes?.size??0} solved, ${this.unsolvedSegs?.length??0} remaining]`}}getOutput(){const t=this.gridToBoundsTransform,e=[];for(const[n,o]of this.solvedRoutes??[]){const i=this.connIdToName[n];for(const r of o){const o=r.cells.map(e=>{const n=this.gridOrigin.x+(e.col+.5)*this.cellSizeMm,o=this.gridOrigin.y+(e.row+.5)*this.cellSizeMm,i=gi(t,{x:n,y:o});return{x:i.x,y:i.y,z:this.layerToZ.get(e.z)??e.z}});o.length>0&&(o[0]={...r.startPoint},o.length>1&&(o[o.length-1]={...r.endPoint})),e.push({connectionName:i,rootConnectionName:this.connIdToRootNet[n],regionId:this.nodeWithPortPoints.capacityMeshNodeId,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,route:o,vias:r.viaCells.map(e=>{const n=this.gridOrigin.x+(e.col+.5)*this.cellSizeMm,o=this.gridOrigin.y+(e.row+.5)*this.cellSizeMm;return gi(t,{x:n,y:o})})})}}return e}},Mi=["left","top","right","bottom","middle"],Ni=class{f=new Float64Array(1024);seq=new Uint32Array(1024);id=new Int32Array(1024);n=0;push(t,e,n){this.ensureCapacity(this.n+1);let o=this.n++;for(this.f[o]=t,this.seq[o]=e,this.id[o]=n;o>0;){const t=o-1>>1;if(this.less(t,o))break;this.swap(o,t),o=t}}pop(){const t=this.id[0];return this.n--,this.n>0&&(this.f[0]=this.f[this.n],this.seq[0]=this.seq[this.n],this.id[0]=this.id[this.n],this.siftDown(0)),t}get size(){return this.n}clear(){this.n=0}ensureCapacity(t){if(t<=this.f.length)return;let e=this.f.length;for(;e<t;)e*=2;const n=new Float64Array(e);n.set(this.f),this.f=n;const o=new Uint32Array(e);o.set(this.seq),this.seq=o;const i=new Int32Array(e);i.set(this.id),this.id=i}siftDown(t){for(;;){const e=2*t+1,n=e+1;if(e>=this.n)return;let o=e;if(n<this.n&&!this.less(e,n)&&(o=n),this.less(t,o))return;this.swap(t,o),t=o}}less(t,e){const n=this.f[t],o=this.f[e];return n!==o?n<o:this.seq[t]<this.seq[e]}swap(t,e){const n=this.f[t];this.f[t]=this.f[e],this.f[e]=n;const o=this.seq[t];this.seq[t]=this.seq[e],this.seq[e]=o;const i=this.id[t];this.id[t]=this.id[e],this.id[e]=i}},wi=class{z=new Int32Array(1024);cellId=new Int32Array(1024);g=new Float64Array(1024);parent=new Int32Array(1024);ripHead=new Int32Array(1024).fill(-1);ripCount=new Int32Array(1024);length=0;clear(){this.length=0}push(t,e,n,o,i,r){this.ensureCapacity(this.length+1);const s=this.length++;return this.z[s]=t,this.cellId[s]=e,this.g[s]=n,this.parent[s]=o,this.ripHead[s]=i,this.ripCount[s]=r,s}ensureCapacity(t){if(t<=this.z.length)return;let e=this.z.length;for(;e<t;)e*=2;const n=new Int32Array(e);n.set(this.z),this.z=n;const o=new Int32Array(e);o.set(this.cellId),this.cellId=o;const i=new Float64Array(e);i.set(this.g),this.g=i;const r=new Int32Array(e);r.set(this.parent),this.parent=r;const s=new Int32Array(e);s.fill(-1),s.set(this.ripHead.subarray(0,this.length)),this.ripHead=s;const a=new Int32Array(e);a.set(this.ripCount.subarray(0,this.length)),this.ripCount=a}},Ti=class{connId=new Int32Array(1024);prev=new Int32Array(1024).fill(-1);length=0;clear(){this.length=0}append(t,e){this.ensureCapacity(this.length+1);const n=this.length++;return this.connId[n]=e,this.prev[n]=t,n}contains(t,e){for(let n=t;n>=0;n=this.prev[n])if(this.connId[n]===e)return!0;return!1}collect(t,e){e.length=0;for(let n=t;n>=0;n=this.prev[n])e.push(this.connId[n])}ensureCapacity(t){if(t<=this.connId.length)return;let e=this.connId.length;for(;e<t;)e*=2;const n=new Int32Array(e);n.set(this.connId),this.connId=n;const o=new Int32Array(e);o.fill(-1),o.set(this.prev.subarray(0,this.length)),this.prev=o}};function Ri(t,e,n){return Math.max(e,Math.min(n,t))}function Ei(t,e){for(let n=0;n<t.length;n++)if(t[n]===e)return;t.push(e)}function Ai(t,e){for(let n=0;n<t.length;n++)if(t[n].cellId===e.cellId)return;t.push(e)}function Oi(t,e,n,o,i,r,s){const a=t-Ri(t,o,r),c=e-Ri(e,i,s);return a*a+c*c<=n*n}var ki=class extends kt{getSolverName(){return"HighDensitySolverA03"}nodeWithPortPoints;highResolutionCellSize;highResolutionCellThickness;lowResolutionCellSize;viaDiameter;MAX_RIPS;maxCellCount;traceThickness;traceMargin;viaMinDistFromBorder;showPenaltyMap;showUsedCellMap;effort;stepMultiplier;hyperParameters;initialPenaltyFn;boundsMinX;boundsMaxX;boundsMinY;boundsMaxY;gridToBoundsTransform;availableZ;zToLayer;layerToZ;layers;fineRows;fineCols;lowScale;bandRows;bandCols;regions;planeSize;cellCenterX;cellCenterY;cellMinX;cellMinY;cellMaxX;cellMaxY;cellWidth;cellHeight;cellRegion;cellRow;cellCol;viaAllowed;neighborOffset;neighborIds;neighborCosts;usedCellsFlat;sharedCellsFlat;portOwnerFlat;penalty2d;ripStateBuckets;visitedStamp;bestGStamp;bestGValue;visitedFlatStamp;sharedCrossRootPortFlat;stamp=0;connNameToId;connIdToName;connIdToRootNet;overlapFriendlyRootNets;usedIndicesByConn;unsolvedSegs;solvedRoutes;activeConnSeg=null;activeConnId=-1;nodePool;heap;ripChain;seqCounter=0;_viaOccs=[];_cellOccs=[];_rippedIds=[];ripCount;totalRipEvents=0;searchIterations=0;consecutiveSkips=0;penaltyCap;baseSearchBudgetIters;_moveCost=0;_moveRippedHead=-1;_moveRipCount=0;traceKeepoutRadius;viaKeepoutRadius;get unsolvedConnections(){return this.unsolvedSegs}get solvedConnectionsMap(){const t=new Map;for(let e=0;e<this.solvedRoutes.length;e++){const n=this.getSolvedRoutesForConn(e);n.length>0&&t.set(e,n)}return t}get activeConnection(){if(!this.activeConnSeg)return null;const t=this.activeConnSeg.startCellId,e=this.activeConnSeg.endCellId;return{connectionName:this.connIdToName[this.activeConnSeg.connId]??"",start:{cellId:t,region:Mi[this.cellRegion[t]],row:this.cellRow[t],col:this.cellCol[t],x:this.cellCenterX[t],y:this.cellCenterY[t],z:this.activeConnSeg.startZ},end:{cellId:e,region:Mi[this.cellRegion[e]],row:this.cellRow[e],col:this.cellCol[e],x:this.cellCenterX[e],y:this.cellCenterY[e],z:this.activeConnSeg.endZ}}}get openSet(){return{length:this.heap?.size??0}}get gridStats(){return{cells:this.planeSize||0,layers:this.layers||0,states:(this.planeSize||0)*(this.layers||0),ripStateBuckets:this.ripStateBuckets||0,neighborEdges:this.neighborIds?.length??0,regionCounts:this.regions?Object.fromEntries(this.regions.map(t=>[t.name,t.rows*t.cols])):{}}}constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.highResolutionCellSize=t.highResolutionCellSize??.1,this.highResolutionCellThickness=Math.max(1,Math.floor(t.highResolutionCellThickness??8)),this.lowResolutionCellSize=t.lowResolutionCellSize??.4,this.viaDiameter=t.viaDiameter,this.maxCellCount=t.maxCellCount,this.traceThickness=t.traceThickness??.1,this.traceMargin=t.traceMargin??.15,this.viaMinDistFromBorder=t.viaMinDistFromBorder??.15,this.showPenaltyMap=t.showPenaltyMap??!1,this.showUsedCellMap=t.showUsedCellMap??!1,this.effort=t.effort??1,this.stepMultiplier=Math.max(1,Math.floor(t.stepMultiplier??1)),this.hyperParameters={shuffleSeed:0,ripCost:8,ripTracePenalty:.5,ripViaPenalty:.75,viaBaseCost:.1,greedyMultiplier:1.5,...t.hyperParameters},this.MAX_ITERATIONS=1e8,this.MAX_RIPS=200,this.initialPenaltyFn=t.initialPenaltyFn}getConstructorParams(){return[{nodeWithPortPoints:this.nodeWithPortPoints,highResolutionCellSize:this.highResolutionCellSize,highResolutionCellThickness:this.highResolutionCellThickness,lowResolutionCellSize:this.lowResolutionCellSize,viaDiameter:this.viaDiameter,maxCellCount:this.maxCellCount,stepMultiplier:this.stepMultiplier,traceThickness:this.traceThickness,traceMargin:this.traceMargin,viaMinDistFromBorder:this.viaMinDistFromBorder,showPenaltyMap:this.showPenaltyMap,showUsedCellMap:this.showUsedCellMap,effort:this.effort,hyperParameters:this.hyperParameters,initialPenaltyFn:this.initialPenaltyFn}]}_setup(){const{nodeWithPortPoints:t}=this,{width:e,height:n,center:o}=t,i=this.lowResolutionCellSize/this.highResolutionCellSize,r=Math.round(i);if(!Number.isFinite(i)||i<=0||Math.abs(i-r)>1e-9)return this.error="lowResolutionCellSize must be a positive integer multiple of highResolutionCellSize",void(this.failed=!0);this.lowScale=Math.max(1,r),this.availableZ=t.availableZ??[...new Set(t.portPoints.map(t=>t.z))].sort((t,e)=>t-e),this.layers=this.availableZ.length,this.zToLayer=new Map,this.layerToZ=new Map;for(let t=0;t<this.availableZ.length;t++){const e=this.availableZ[t];this.zToLayer.set(e,t),this.layerToZ.set(t,e)}this.boundsMinX=o.x-e/2,this.boundsMaxX=o.x+e/2,this.boundsMinY=o.y-n/2,this.boundsMaxY=o.y+n/2,this.traceKeepoutRadius=this.traceMargin+this.traceThickness/2,this.viaKeepoutRadius=this.viaDiameter/2+this.traceKeepoutRadius,this.buildFiveRegionGrid(e,n),this.gridToBoundsTransform=this.computeGridToBoundsTransform();const s=this.layers*this.planeSize;if(void 0!==this.maxCellCount&&s>this.maxCellCount)return this.error=`Cell count ${s} exceeds maxCellCount ${this.maxCellCount}`,void(this.failed=!0);this.connNameToId=new Map,this.connIdToName=[],this.connIdToRootNet=[],this.overlapFriendlyRootNets=new Set,this.unsolvedSegs=this.buildConnectionSegs(),this.penalty2d=new Float64Array(this.planeSize);const a=e>0?1/e:0,c=n>0?1/n:0;for(let t=0;t<this.planeSize;t++){let e=0;this.initialPenaltyFn&&(e+=this.initialPenaltyFn({x:this.cellCenterX[t],y:this.cellCenterY[t],px:(this.cellCenterX[t]-this.boundsMinX)*a,py:(this.cellCenterY[t]-this.boundsMinY)*c,cellId:t,region:Mi[this.cellRegion[t]],row:this.cellRow[t],col:this.cellCol[t]})),this.penalty2d[t]=e}this.usedCellsFlat=new Int32Array(s).fill(-1),this.sharedCellsFlat=Array.from({length:s},()=>{}),this.portOwnerFlat=new Int32Array(s).fill(-1),this.sharedCrossRootPortFlat=new Uint8Array(s),this.ripStateBuckets=1;const l=s;this.visitedStamp=new Uint32Array(l),this.bestGStamp=new Uint32Array(l),this.bestGValue=new Float64Array(l),this.visitedFlatStamp=new Uint32Array(s),this.stamp=0;const d=new Map;for(const t of this.nodeWithPortPoints.portPoints){const e=this.connNameToId.get(t.connectionName);if(void 0===e)continue;const n=this.pointToCell(t),o=n.z*this.planeSize+n.cellId,i=this.connIdToRootNet[e],r=d.get(o);void 0===r?d.set(o,i):r!==i&&(this.sharedCrossRootPortFlat[o]=1);const s=this.portOwnerFlat[o];this.portOwnerFlat[o]=-1===s||s===e?e:-2}this.solvedRoutes=[],this.usedIndicesByConn=[],this.ripCount=[],this.consecutiveSkips=0,this.penaltyCap=.5*this.hyperParameters.ripCost,this.shuffleConnections();const h=xi({planeSize:this.planeSize,layers:this.layers,connectionCount:this.unsolvedSegs.length,effort:this.effort,maxIterations:this.MAX_ITERATIONS});this.baseSearchBudgetIters=h.baseSearchBudgetIters,this.MAX_ITERATIONS=h.maxIterationsIters,this.activeConnSeg=null,this.activeConnId=-1,this.nodePool=new wi,this.heap=new Ni,this.ripChain=new Ti,this.seqCounter=0}_step(){for(let t=0;t<this.stepMultiplier;t++){if(this.solved||this.failed)return;this.stepOnce()}}buildFiveRegionGrid(t,e){this.fineCols=Math.max(1,Math.ceil(t/this.highResolutionCellSize)),this.fineRows=Math.max(1,Math.ceil(e/this.highResolutionCellSize)),this.bandCols=Math.min(this.highResolutionCellThickness,Math.floor(this.fineCols/2)),this.bandRows=Math.min(this.highResolutionCellThickness,Math.floor(this.fineRows/2));const n=Math.max(0,this.fineCols-2*this.bandCols),o=Math.max(0,this.fineRows-2*this.bandRows),i=n,r=n;this.regions=[{id:0,name:"left",fineOriginRow:0,fineOriginCol:0,fineRows:this.fineRows,fineCols:this.bandCols,cellScale:1,rows:this.fineRows,cols:this.bandCols,offset:0},{id:1,name:"top",fineOriginRow:0,fineOriginCol:this.bandCols,fineRows:this.bandRows,fineCols:i,cellScale:1,rows:this.bandRows,cols:i,offset:0},{id:2,name:"right",fineOriginRow:0,fineOriginCol:this.fineCols-this.bandCols,fineRows:this.fineRows,fineCols:this.bandCols,cellScale:1,rows:this.fineRows,cols:this.bandCols,offset:0},{id:3,name:"bottom",fineOriginRow:this.fineRows-this.bandRows,fineOriginCol:this.bandCols,fineRows:this.bandRows,fineCols:r,cellScale:1,rows:this.bandRows,cols:r,offset:0},{id:4,name:"middle",fineOriginRow:this.bandRows,fineOriginCol:this.bandCols,fineRows:o,fineCols:n,cellScale:this.lowScale,rows:o>0?Math.ceil(o/this.lowScale):0,cols:n>0?Math.ceil(n/this.lowScale):0,offset:0}];let s=0;for(let t=0;t<this.regions.length;t++)this.regions[t].offset=s,s+=this.regions[t].rows*this.regions[t].cols;this.planeSize=s,this.cellCenterX=new Float64Array(this.planeSize),this.cellCenterY=new Float64Array(this.planeSize),this.cellMinX=new Float64Array(this.planeSize),this.cellMinY=new Float64Array(this.planeSize),this.cellMaxX=new Float64Array(this.planeSize),this.cellMaxY=new Float64Array(this.planeSize),this.cellWidth=new Float64Array(this.planeSize),this.cellHeight=new Float64Array(this.planeSize),this.cellRegion=new Uint8Array(this.planeSize),this.cellRow=new Int32Array(this.planeSize),this.cellCol=new Int32Array(this.planeSize),this.viaAllowed=new Uint8Array(this.planeSize);for(let t=0;t<this.regions.length;t++){const e=this.regions[t];for(let t=0;t<e.rows;t++){const n=e.fineOriginRow+t*e.cellScale,o=Math.min(e.fineOriginRow+e.fineRows,n+e.cellScale),i=this.boundsMinY+n*this.highResolutionCellSize,r=Math.min(this.boundsMaxY,this.boundsMinY+o*this.highResolutionCellSize);for(let n=0;n<e.cols;n++){const o=e.fineOriginCol+n*e.cellScale,s=Math.min(e.fineOriginCol+e.fineCols,o+e.cellScale),a=this.boundsMinX+o*this.highResolutionCellSize,c=Math.min(this.boundsMaxX,this.boundsMinX+s*this.highResolutionCellSize),l=this.cellIdFor(e.id,t,n);this.cellCenterX[l]=(a+c)/2,this.cellCenterY[l]=(i+r)/2,this.cellMinX[l]=a,this.cellMinY[l]=i,this.cellMaxX[l]=c,this.cellMaxY[l]=r,this.cellWidth[l]=c-a,this.cellHeight[l]=r-i,this.cellRegion[l]=e.id,this.cellRow[l]=t,this.cellCol[l]=n;const d=Math.min(this.cellCenterX[l]-this.boundsMinX,this.boundsMaxX-this.cellCenterX[l],this.cellCenterY[l]-this.boundsMinY,this.boundsMaxY-this.cellCenterY[l]);this.viaAllowed[l]=d>=this.viaMinDistFromBorder?1:0}}}const a=Array.from({length:this.planeSize},()=>[]),c=(t,e)=>{if(t===e||t<0||e<0)return;const n=this.cellCenterX[t]-this.cellCenterX[e],o=this.cellCenterY[t]-this.cellCenterY[e],i=Math.hypot(n,o);Ai(a[t],{cellId:e,cost:i}),Ai(a[e],{cellId:t,cost:i})};for(let t=0;t<this.regions.length;t++){const e=this.regions[t];for(let t=0;t<e.rows;t++)for(let n=0;n<e.cols;n++){const o=this.cellIdFor(e.id,t,n);t+1<e.rows&&c(o,this.cellIdFor(e.id,t+1,n)),n+1<e.cols&&c(o,this.cellIdFor(e.id,t,n+1))}}const l=this.regions[0],d=this.regions[1],h=this.regions[2],u=this.regions[3],p=this.regions[4],m=l.rows>0&&l.cols>0,g=d.rows>0&&d.cols>0,f=h.rows>0&&h.cols>0,y=u.rows>0&&u.cols>0,_=p.rows>0&&p.cols>0;if(m&&g)for(let t=0;t<this.bandRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(1,t,0));if(g&&f)for(let t=0;t<this.bandRows;t++)c(this.cellIdFor(1,t,d.cols-1),this.cellIdFor(2,t,0));if(m&&y)for(let t=this.fineRows-this.bandRows;t<this.fineRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(3,t-(this.fineRows-this.bandRows),0));if(y&&f)for(let t=this.fineRows-this.bandRows;t<this.fineRows;t++)c(this.cellIdFor(3,t-(this.fineRows-this.bandRows),u.cols-1),this.cellIdFor(2,t,0));if(m&&_)for(let t=this.bandRows;t<this.fineRows-this.bandRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(4,Math.floor((t-this.bandRows)/this.lowScale),0));if(f&&_)for(let t=this.bandRows;t<this.fineRows-this.bandRows;t++)c(this.cellIdFor(4,Math.floor((t-this.bandRows)/this.lowScale),p.cols-1),this.cellIdFor(2,t,0));if(g&&_)for(let t=this.bandCols;t<this.fineCols-this.bandCols;t++)c(this.cellIdFor(1,d.rows-1,t-this.bandCols),this.cellIdFor(4,0,Math.floor((t-this.bandCols)/this.lowScale)));if(y&&_)for(let t=this.bandCols;t<this.fineCols-this.bandCols;t++)c(this.cellIdFor(4,p.rows-1,Math.floor((t-this.bandCols)/this.lowScale)),this.cellIdFor(3,0,t-this.bandCols));if(!_&&!g&&!y&&m&&f)for(let t=0;t<Math.min(l.rows,h.rows);t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(2,t,0));if(!_&&!m&&!f&&g&&y)for(let t=0;t<Math.min(d.cols,u.cols);t++)c(this.cellIdFor(1,d.rows-1,t),this.cellIdFor(3,0,t));const b=this.flattenNeighborLists(a);this.neighborOffset=b.offset,this.neighborIds=b.ids,this.neighborCosts=b.costs}cellIdFor(t,e,n){const o=this.regions[t];return o.offset+e*o.cols+n}stepOnce(){if(!this.activeConnSeg){if(0===this.unsolvedSegs.length)return void(this.solved=!0);const t=this.unsolvedSegs.shift();this.activeConnSeg=t,this.activeConnId=t.connId,this.nodePool.clear(),this.ripChain.clear(),this.heap.clear(),this.seqCounter=0,this.searchIterations=0,this.nextStamp();const e=this.computeH(t.startZ,t.startCellId,t.endZ,t.endCellId)*this.hyperParameters.greedyMultiplier,n=this.nodePool.push(t.startZ,t.startCellId,0,-1,-1,0),o=t.startZ*this.planeSize+t.startCellId,i=this.getSearchStateIdx(o,0);return this.bestGStamp[i]=this.stamp,this.bestGValue[i]=0,void this.heap.push(e,this.seqCounter++,n)}this.searchIterations++;const t=this.ripCount[this.activeConnId]??0,e=Math.round(this.baseSearchBudgetIters*(1+.25*Math.min(t,10)));if(this.searchIterations>e){const t=this.penalty2d;for(let e=0;e<t.length;e++)t[e]=.9*t[e];return this.unsolvedSegs.push(this.activeConnSeg),this.activeConnSeg=null,this.activeConnId=-1,this.heap.clear(),this.nodePool.clear(),this.consecutiveSkips++,void(this.consecutiveSkips>=Math.max(3,3*this.unsolvedSegs.length)&&(this.error=`Convergence failure: ${this.unsolvedSegs.length} connections stuck`,this.failed=!0))}if(0===this.heap.size)return this.error=`No path found for ${this.connIdToName[this.activeConnId]}`,void(this.failed=!0);const n=this.heap.pop(),o=this.nodePool.z[n],i=this.nodePool.cellId[n],r=this.nodePool.g[n],s=this.nodePool.ripHead[n],a=this.nodePool.ripCount[n],c=o*this.planeSize+i,l=this.getSearchStateIdx(c,a);if(this.visitedStamp[l]===this.stamp)return;this.visitedStamp[l]=this.stamp,this.visitedFlatStamp[c]=this.stamp;const d=this.activeConnSeg;if(o===d.endZ&&i===d.endCellId)return this.finalizeRoute(n),this.activeConnSeg=null,void(this.activeConnId=-1);const h=this.visitedStamp,u=this.stamp,p=this.activeConnId,m=d.endZ,g=d.endCellId,f=this.neighborOffset[i],y=this.neighborOffset[i+1];for(let t=f;t<y;t++){const e=this.neighborIds[t],i=o*this.planeSize+e;if(this.computeMoveCostAndRips(p,o,e,!1,s,a,this.neighborCosts[t]),this._moveCost<0)continue;const c=this.getSearchStateIdx(i,this._moveRipCount);if(h[c]===u)continue;const l=r+this._moveCost;if(this.bestGStamp[c]===u&&l>=this.bestGValue[c])continue;this.bestGStamp[c]=u,this.bestGValue[c]=l;const d=l+this.computeH(o,e,m,g)*this.hyperParameters.greedyMultiplier,f=this.nodePool.push(o,e,l,n,this._moveRippedHead,this._moveRipCount);this.heap.push(d,this.seqCounter++,f)}if(this.viaAllowed[i])for(let t=0;t<this.layers;t++){if(t===o)continue;const e=t*this.planeSize+i;if(this.computeMoveCostAndRips(p,t,i,!0,s,a,0),this._moveCost<0)continue;const c=this.getSearchStateIdx(e,this._moveRipCount);if(h[c]===u)continue;const l=r+this._moveCost;if(this.bestGStamp[c]===u&&l>=this.bestGValue[c])continue;this.bestGStamp[c]=u,this.bestGValue[c]=l;const d=l+this.computeH(t,i,m,g)*this.hyperParameters.greedyMultiplier,f=this.nodePool.push(t,i,l,n,this._moveRippedHead,this._moveRipCount);this.heap.push(d,this.seqCounter++,f)}}computeMoveCostAndRips(t,e,n,o,i,r,s){let a=0,c=i,l=r;const d=e*this.planeSize+n;if(o){a+=this.hyperParameters.viaBaseCost,a+=Math.min(this.penalty2d[n],this.penaltyCap);const o=this.portOwnerFlat[d],i=this.allowSharedUse(t,o),r=this.activeConnSeg,s=!!r&&e===r.endZ&&n===r.endCellId;if(o>=0&&o!==t&&!i&&!s)return this._moveCost=-1,void(this._moveRippedHead=c);this.fillViaOccupants(n,t);const h=this._viaOccs;for(let t=0;t<h.length;t++){const e=h[t];this.ripChain.contains(c,e)||(a+=this.hyperParameters.ripCost,c=this.ripChain.append(c,e),l++),a+=this.hyperParameters.ripViaPenalty}}else{a+=s,a+=Math.min(this.penalty2d[n],this.penaltyCap);const o=this.portOwnerFlat[d],i=this.allowSharedUse(t,o),r=this.activeConnSeg,h=!!r&&e===r.endZ&&n===r.endCellId;if(o>=0&&o!==t&&!i&&!h)return this._moveCost=-1,void(this._moveRippedHead=c);this.fillTraceOccupants(d,t,this._cellOccs);for(let t=0;t<this._cellOccs.length;t++){const e=this._cellOccs[t];this.ripChain.contains(c,e)||(a+=this.hyperParameters.ripCost,c=this.ripChain.append(c,e),l++),a+=this.hyperParameters.ripTracePenalty}}this._moveCost=a,this._moveRippedHead=c,this._moveRipCount=l}fillViaOccupants(t,e){const n=this._viaOccs;n.length=0;const o=this.cellCenterX[t],i=this.cellCenterY[t];this.forEachCellNearCircle(o,i,this.viaKeepoutRadius,t=>{if(Oi(o,i,this.viaKeepoutRadius,this.cellMinX[t],this.cellMinY[t],this.cellMaxX[t],this.cellMaxY[t]))for(let o=0;o<this.layers;o++)this.pushFlatOccupants(o*this.planeSize+t,e,n)})}fillTraceOccupants(t,e,n){n.length=0,this.pushFlatOccupants(t,e,n)}pushFlatOccupants(t,e,n){const o=this.usedCellsFlat[t];-1===o||o===e||this.allowSharedUse(e,o)||Ei(n,o);const i=this.sharedCellsFlat[t];if(i)for(let t=0;t<i.length;t++){const o=i[t];o!==e&&(this.allowSharedUse(e,o)||Ei(n,o))}}addSharedOccupant(t,e){if(this.usedCellsFlat[t]===e)return;let n=this.sharedCellsFlat[t];n||(n=[],this.sharedCellsFlat[t]=n),Ei(n,e)}replaceOccupants(t,e){this.usedCellsFlat[t]=e,this.sharedCellsFlat[t]=void 0}removeOccupant(t,e){const n=this.sharedCellsFlat[t];if(this.usedCellsFlat[t]===e)return void(n&&n.length>0?(this.usedCellsFlat[t]=n.pop(),0===n.length&&(this.sharedCellsFlat[t]=void 0)):this.usedCellsFlat[t]=-1);if(!n)return;const o=n.indexOf(e);-1!==o&&(n.splice(o,1),0===n.length&&(this.sharedCellsFlat[t]=void 0))}allowSharedUse(t,e){if(e<0)return!1;return this.connIdToRootNet[e]===this.connIdToRootNet[t]}shouldSkipFixedPortHalo(t,e){const n=this.portOwnerFlat[t];return n!==e&&(-2===n||!(n<0)&&!this.allowSharedUse(e,n))}nextStamp(){this.stamp=this.stamp+1>>>0,0===this.stamp&&(this.visitedStamp.fill(0),this.bestGStamp.fill(0),this.visitedFlatStamp.fill(0),this.stamp=1)}getSearchStateIdx(t,e){return t}computeH(t,e,n,o){const i=Math.hypot(this.cellCenterX[e]-this.cellCenterX[o],this.cellCenterY[e]-this.cellCenterY[o]);return t===n?i:i+this.hyperParameters.viaBaseCost}internConn(t,e){const n=this.connNameToId.get(t);if(void 0!==n)return n;const o=this.connIdToName.length;var i;return this.connIdToName.push(t),this.connIdToRootNet.push((i=t,e??i.replace(/_mst\d+$/,""))),this.connNameToId.set(t,o),o}buildConnectionSegs(){const t=new Map;for(const e of this.nodeWithPortPoints.portPoints){const n=e.connectionName;t.has(n)||t.set(n,{points:[],rootConnectionName:e.rootConnectionName}),t.get(n).points.push(e)}const e=[],n=new Set;for(const[o,i]of t){const t=i.points,r=_i(t);if(0===r.length)continue;const s=this.internConn(o,i.rootConnectionName);for(const[t,a]of r){const r=this.pointToCell(t),c=this.pointToCell(a),l=`${r.z}:${r.cellId}`,d=`${c.z}:${c.cellId}`,h=l<d?`${l}|${d}`:`${d}|${l}`,u=i.rootConnectionName??o,p=`${u}|${h}`;n.has(p)?this.overlapFriendlyRootNets.add(u):(n.add(p),e.push({connId:s,startZ:r.z,startCellId:r.cellId,startPoint:t,endZ:c.z,endCellId:c.cellId,endPoint:a}))}}return e}pointToCell(t){const e=Ri(Math.floor((t.x-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),n=Ri(Math.floor((t.y-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1);let o=4;e<this.bandCols?o=0:e>=this.fineCols-this.bandCols?o=2:n<this.bandRows?o=1:n>=this.fineRows-this.bandRows&&(o=3);const i=this.regions[o],r=n-i.fineOriginRow,s=e-i.fineOriginCol,a=Ri(Math.floor(r/i.cellScale),0,Math.max(0,i.rows-1)),c=Ri(Math.floor(s/i.cellScale),0,Math.max(0,i.cols-1));return{z:this.zToLayer.get(t.z)??0,cellId:this.cellIdFor(o,a,c)}}shuffleConnections(){const t=this.unsolvedSegs;let e=this.hyperParameters.shuffleSeed>>>0;const n=()=>(e=Math.imul(e,1664525)+1013904223>>>0,e/4294967295);for(let e=t.length-1;e>0;e--){const o=Math.floor(n()*(e+1)),i=t[e];t[e]=t[o],t[o]=i}}finalizeRoute(t){this.consecutiveSkips=Math.max(0,this.consecutiveSkips-1);const e=[];let n=t;for(;n>=0;){const t=this.nodePool.z[n],o=this.nodePool.cellId[n];e.push(t*this.planeSize+o),n=this.nodePool.parent[n]}for(e.reverse();e.length>1&&this.sharedCrossRootPortFlat[e[0]];)e.shift();for(;e.length>1&&this.sharedCrossRootPortFlat[e[e.length-1]];)e.pop();const o=this.extractViaCellIds(e),i=this.activeConnId;this.ripChain.collect(this.nodePool.ripHead[t],this._rippedIds);for(let t=0;t<this._rippedIds.length;t++)if(this.ripTrace(this._rippedIds[t]),this.failed)return;const r=[];for(let t=0;t<e.length;t++){const n=e[t],o=Math.floor(n/this.planeSize),s=n-o*this.planeSize;this.markTraceFootprint(i,o,s,r)}const s=[];for(let t=0;t<o.length;t++)this.markViaFootprint(i,o[t],r,s);for(;this.usedIndicesByConn.length<=i;)this.usedIndicesByConn.push(void 0);const a=this.usedIndicesByConn[i]??[];for(a.push(...r),this.usedIndicesByConn[i]=a;this.solvedRoutes.length<=i;)this.solvedRoutes.push(void 0);const c=this.solvedRoutes[i]??[];c.push({connId:i,states:Int32Array.from(e),viaCellIds:Int32Array.from(o),startPoint:this.activeConnSeg.startPoint,endPoint:this.activeConnSeg.endPoint}),this.solvedRoutes[i]=c;for(let t=0;t<s.length;t++)if(this.ripTrace(s[t]),this.failed)return;if(this._rippedIds.length>0||s.length>0){const t=this.penalty2d,e=this.penaltyCap;if(this.totalRipEvents>50)for(let e=0;e<t.length;e++)t[e]=.99*t[e];else for(let n=0;n<t.length;n++)t[n]>e&&(t[n]=.5*t[n])}}extractViaCellIds(t){const e=[];for(let n=1;n<t.length;n++){const o=t[n-1],i=t[n],r=Math.floor(o/this.planeSize),s=Math.floor(i/this.planeSize);r!==s&&e.push(i-s*this.planeSize)}return e}markTraceFootprint(t,e,n,o){const i=this.cellCenterX[n],r=this.cellCenterY[n];this.forEachCellNearCircle(i,r,this.traceKeepoutRadius,s=>{if(!Oi(i,r,this.traceKeepoutRadius,this.cellMinX[s],this.cellMinY[s],this.cellMaxX[s],this.cellMaxY[s]))return;const a=e*this.planeSize+s;if(s!==n&&this.shouldSkipFixedPortHalo(a,t))return;const c=this.usedCellsFlat[a],l=this.allowSharedUse(t,c);(-1===c||c===t||l)&&(-1!==c&&c!==t?this.addSharedOccupant(a,t):this.usedCellsFlat[a]=t,o.push(a))})}markViaFootprint(t,e,n,o){const i=this.cellCenterX[e],r=this.cellCenterY[e];this.forEachCellNearCircle(i,r,this.viaKeepoutRadius,s=>{if(Oi(i,r,this.viaKeepoutRadius,this.cellMinX[s],this.cellMinY[s],this.cellMaxX[s],this.cellMaxY[s]))for(let i=0;i<this.layers;i++){const r=i*this.planeSize+s;if(s!==e&&this.shouldSkipFixedPortHalo(r,t))continue;if(this.fillTraceOccupants(r,t,this._cellOccs),this._cellOccs.length>0){for(let t=0;t<this._cellOccs.length;t++)Ei(o,this._cellOccs[t]);this.replaceOccupants(r,t),n.push(r);continue}const a=this.usedCellsFlat[r];-1!==a&&a!==t?this.addSharedOccupant(r,t):this.usedCellsFlat[r]=t,n.push(r)}})}forEachCellNearCircle(t,e,n,o){const i=Ri(Math.floor((t-n-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),r=Ri(Math.floor((t+n-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),s=Ri(Math.floor((e-n-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1),a=Ri(Math.floor((e+n-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1);for(let t=0;t<this.regions.length;t++){const e=this.regions[t];if(0===e.rows||0===e.cols)continue;const n=Math.max(s,e.fineOriginRow),c=Math.min(a,e.fineOriginRow+e.fineRows-1),l=Math.max(i,e.fineOriginCol),d=Math.min(r,e.fineOriginCol+e.fineCols-1);if(n>c)continue;if(l>d)continue;const h=Math.floor((n-e.fineOriginRow)/e.cellScale),u=Math.floor((c-e.fineOriginRow)/e.cellScale),p=Math.floor((l-e.fineOriginCol)/e.cellScale),m=Math.floor((d-e.fineOriginCol)/e.cellScale);for(let t=h;t<=u;t++)for(let n=p;n<=m;n++)o(this.cellIdFor(e.id,t,n))}}ripTrace(t){for(;this.ripCount.length<=t;)this.ripCount.push(0);if(this.ripCount[t]++,this.totalRipEvents++,this.totalRipEvents>=this.MAX_RIPS)return this.error=`Convergence failure: exceeded MAX_RIPS ${this.MAX_RIPS}`,void(this.failed=!0);const e=this.getSolvedRoutesForConn(t);if(e.length>0)for(const t of e){for(let e=0;e<t.states.length;e++){const n=t.states[e]%this.planeSize;this.penalty2d[n]=this.penalty2d[n]+this.hyperParameters.ripTracePenalty}for(let e=0;e<t.viaCellIds.length;e++){const n=t.viaCellIds[e];this.penalty2d[n]=this.penalty2d[n]+this.hyperParameters.ripViaPenalty}}const n=this.usedIndicesByConn[t];if(n){for(let e=0;e<n.length;e++)this.removeOccupant(n[e],t);this.usedIndicesByConn[t]=void 0}if(e.length>0){this.solvedRoutes[t]=void 0;for(const n of e){const e=n.states[0],o=n.states[n.states.length-1],i=Math.floor(e/this.planeSize),r=Math.floor(o/this.planeSize);this.unsolvedSegs.push({connId:t,startZ:i,startCellId:e-i*this.planeSize,startPoint:n.startPoint,endZ:r,endCellId:o-r*this.planeSize,endPoint:n.endPoint})}}}flattenNeighborLists(t){const e=new Int32Array(t.length+1);let n=0;for(let o=0;o<t.length;o++)e[o]=n,n+=t[o].length;e[t.length]=n;const o=new Int32Array(n),i=new Float32Array(n);let r=0;for(let e=0;e<t.length;e++){const n=t[e];for(let t=0;t<n.length;t++){const e=n[t];o[r]=e.cellId,i[r]=e.cost,r++}}return{offset:e,ids:o,costs:i}}visualize(){const t=["red","blue","orange","green"],e=this.gridToBoundsTransform,n=[],o=[],i=[],r=[];if(r.push({center:{x:this.nodeWithPortPoints.center.x,y:this.nodeWithPortPoints.center.y},width:this.nodeWithPortPoints.width,height:this.nodeWithPortPoints.height,stroke:"gray"}),this.showPenaltyMap&&this.penalty2d){let t=0;for(let e=0;e<this.penalty2d.length;e++)this.penalty2d[e]>t&&(t=this.penalty2d[e]);if(t>0)for(let n=0;n<this.planeSize;n++){const o=this.penalty2d[n];if(o<=0)continue;const i=gi(e,{x:this.cellCenterX[n],y:this.cellCenterY[n]}),s=Math.min(.6,o/t*.6);r.push({center:i,width:this.cellWidth[n]*e.a,height:this.cellHeight[n]*e.e,fill:`rgba(255,165,0,${s.toFixed(3)})`})}}if(this.showUsedCellMap&&this.usedCellsFlat)for(let t=0;t<this.layers;t++){const n=t*this.planeSize;for(let t=0;t<this.planeSize;t++){if(-1===this.usedCellsFlat[n+t])continue;const o=gi(e,{x:this.cellCenterX[t],y:this.cellCenterY[t]});r.push({center:o,width:this.cellWidth[t]*e.a,height:this.cellHeight[t]*e.e,fill:"rgba(0,0,255,0.5)"})}}for(const e of this.nodeWithPortPoints.portPoints)n.push({x:e.x,y:e.y,color:t[e.z]??"gray",label:e.connectionName});const s=["rgba(255,0,0,0.75)","rgba(0,0,255,0.75)","rgba(255,165,0,0.75)","rgba(0,128,0,0.75)"],a=this.getOutput();for(const t of a){if(t.route.length<2)continue;let e=0;for(let n=1;n<t.route.length;n++){const i=t.route[n-1];t.route[n].z!==i.z&&(n-e>=2&&o.push({points:t.route.slice(e,n).map(t=>({x:t.x,y:t.y})),strokeColor:s[i.z]??"rgba(128,128,128,0.75)",strokeWidth:this.traceThickness}),e=n)}if(t.route.length-e>=2){const n=t.route[e].z;o.push({points:t.route.slice(e).map(t=>({x:t.x,y:t.y})),strokeColor:s[n]??"rgba(128,128,128,0.75)",strokeWidth:this.traceThickness})}}for(const t of a)for(const e of t.vias)i.push({center:{x:e.x,y:e.y},radius:this.viaDiameter/2,fill:"rgba(0,0,0,0.3)",stroke:"black"});if(this.activeConnSeg&&this.visitedFlatStamp){const t=this.stamp;for(let o=0;o<this.layers;o++){const i=o*this.planeSize;for(let o=0;o<this.planeSize;o++){if(this.visitedFlatStamp[i+o]!==t)continue;const r=gi(e,{x:this.cellCenterX[o],y:this.cellCenterY[o]});n.push({x:r.x,y:r.y,color:"rgba(0,0,255,0.2)"})}}}return{points:n,lines:o,circles:i,rects:r,coordinateSystem:"cartesian",title:`HighDensityA03 [${this.getSolvedRouteCount()} solved, ${this.unsolvedSegs?.length??0} remaining]`}}getOutput(){const t=this.gridToBoundsTransform,e=[];for(let n=0;n<this.solvedRoutes.length;n++){const o=this.getSolvedRoutesForConn(n);if(0===o.length)continue;const i=this.connIdToName[n];for(const n of o){const o=Array.from(n.states,e=>{const n=Math.floor(e/this.planeSize),o=e-n*this.planeSize,i=gi(t,{x:this.cellCenterX[o],y:this.cellCenterY[o]});return{x:i.x,y:i.y,z:this.layerToZ.get(n)??n}});o.length>0&&(o[0]={...n.startPoint},o.length>1&&(o[o.length-1]={...n.endPoint})),e.push({connectionName:i,regionId:this.nodeWithPortPoints.capacityMeshNodeId,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,route:o,vias:Array.from(n.viaCellIds,e=>gi(t,{x:this.cellCenterX[e],y:this.cellCenterY[e]}))})}}return e}getSolvedRoutesForConn(t){const e=this.solvedRoutes[t];return e?Array.isArray(e)?e:[e]:[]}getSolvedRouteCount(){let t=0;for(let e=0;e<this.solvedRoutes.length;e++)t+=this.getSolvedRoutesForConn(e).length;return t}computeGridToBoundsTransform(){let t=1/0,e=-1/0,n=1/0,o=-1/0;for(let i=0;i<this.planeSize;i++){const r=this.cellCenterX[i],s=this.cellCenterY[i];r<t&&(t=r),r>e&&(e=r),s<n&&(n=s),s>o&&(o=s)}const i=e-t,r=o-n,s=this.boundsMaxX-this.boundsMinX,a=this.boundsMaxY-this.boundsMinY,c=i>0?s/i:1,l=r>0?a/r:1;return{a:c,b:0,c:i>0?this.boundsMinX-c*t:(this.boundsMinX+this.boundsMaxX)/2-t,d:0,e:l,f:r>0?this.boundsMinY-l*n:(this.boundsMinY+this.boundsMaxY)/2-n}}};import Li from"object-hash";var Di=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 zi(t,e){const n=t.x-e.x,o=t.y-e.y;return n*n+o*o}function Fi(t,e,n){const o=zi(e,n);if(0===o)return zi(t,e);let i=((t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y))/o;i=Math.max(0,Math.min(1,i));return zi(t,{x:e.x+i*(n.x-e.x),y:e.y+i*(n.y-e.y)})}function Bi(t,e,n,o){if(fe(t,e,n,o))return 0;const i={x:t.x,y:t.y},r={x:e.x,y:e.y},s={x:n.x,y:n.y},a={x:o.x,y:o.y};return Math.min(Fi(i,s,a),Fi(r,s,a),Fi(s,i,r),Fi(a,i,r))}var ji=class{segmentBuckets;viaBuckets;CELL_SIZE;maximumCopperRadius=0;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(this.maximumCopperRadius=Math.max(this.maximumCopperRadius,e.traceThickness/2,e.viaDiameter/2),e.route&&e.route.length>=2)for(let t=0;t<e.route.length-1;t++){const n=e.route[t],o=e.route[t+1];if(n.x===o.x&&n.y===o.y)continue;if(n.insideJumperPad&&o.insideJumperPad)continue;const i=[n,o],r=Di(i),s={segmentId:`${e.connectionName}-seg-${t}`,segment:i,parentRoute:e},a=Math.floor(r.minX/this.CELL_SIZE),c=Math.floor((r.maxX+1e-9)/this.CELL_SIZE),l=Math.floor(r.minY/this.CELL_SIZE),d=Math.floor((r.maxY+1e-9)/this.CELL_SIZE);for(let t=a;t<=c;t++)for(let e=l;e<=d;e++){const n=`${t}x${e}`;let o=this.segmentBuckets.get(n);o||(o=[],this.segmentBuckets.set(n,o)),o.push(s)}}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 o={viaId:`${e.connectionName}-via-${t}`,x:n.x,y:n.y,parentRoute:e},i=`${Math.floor(n.x/this.CELL_SIZE)}x${Math.floor(n.y/this.CELL_SIZE)}`;let r=this.viaBuckets.get(i);r||(r=[],this.viaBuckets.set(i,r)),r.push(o)}}else console.warn("Skipping route with missing data:",e)}getConflictingRoutesForSegment(t,e,n){const o=Di([t,e]),i=n+this.maximumCopperRadius,r=o.minX-i,s=o.minY-i,a=o.maxX+i,c=o.maxY+i,l=Math.floor(r/this.CELL_SIZE),d=Math.floor((a+1e-9)/this.CELL_SIZE),h=Math.floor(s/this.CELL_SIZE),u=Math.floor((c+1e-9)/this.CELL_SIZE),p=new Map,m=new Set,g=new Set,f={x:t.x,y:t.y},y={x:e.x,y:e.y};for(let o=l;o<=d;o++)for(let i=h;i<=u;i++){const r=`${o}x${i}`,s=this.segmentBuckets.get(r);if(s)for(const o of s){if(m.has(o.segmentId))continue;m.add(o.segmentId);const i=o.parentRoute,[r,s]=o.segment;if(t.z!==e.z||r.z!==s.z||r.z!==t.z)continue;const a=n+i.traceThickness/2,c=a*a,l=Bi(t,e,r,s);if(l<c){const t=i.connectionName,e=p.get(t);(!e||l<e.minDistSq)&&p.set(t,{route:i,minDistSq:l})}}const a=this.viaBuckets.get(r);if(a)for(const t of a){if(g.has(t.viaId))continue;g.add(t.viaId);const e=t.parentRoute,o={x:t.x,y:t.y},i=n+e.viaDiameter/2,r=i*i,s=Fi(o,f,y);if(s<r){const t=e.connectionName,n=p.get(t);(!n||s<n.minDistSq)&&p.set(t,{route:e,minDistSq:s})}}}const _=[];for(const t of p.values())_.push({conflictingRoute:t.route,distance:Math.sqrt(t.minDistSq)});return _}removeRoute(t){for(const[e,n]of this.segmentBuckets){const o=n.filter(e=>e.parentRoute.connectionName!==t);0===o.length?this.segmentBuckets.delete(e):o.length!==n.length&&this.segmentBuckets.set(e,o)}for(const[e,n]of this.viaBuckets){const o=n.filter(e=>e.parentRoute.connectionName!==t);0===o.length?this.viaBuckets.delete(e):o.length!==n.length&&this.viaBuckets.set(e,o)}}addRoute(t){if(!t||!t.connectionName)return void console.warn("Skipping route with missing data:",t);this.maximumCopperRadius=Math.max(this.maximumCopperRadius,t.traceThickness/2,t.viaDiameter/2);if(t.route&&t.route.length>=2)for(let e=0;e<t.route.length-1;e++){const n=t.route[e],o=t.route[e+1];if(n.x===o.x&&n.y===o.y)continue;if(n.insideJumperPad&&o.insideJumperPad)continue;const i=[n,o],r=Di(i),s={segmentId:`${t.connectionName}-seg-${e}`,segment:i,parentRoute:t},a=Math.floor(r.minX/this.CELL_SIZE),c=Math.floor((r.maxX+1e-9)/this.CELL_SIZE),l=Math.floor(r.minY/this.CELL_SIZE),d=Math.floor((r.maxY+1e-9)/this.CELL_SIZE);for(let t=a;t<=c;t++)for(let e=l;e<=d;e++){const n=`${t}x${e}`;let o=this.segmentBuckets.get(n);o||(o=[],this.segmentBuckets.set(n,o)),o.push(s)}}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 o={viaId:`${t.connectionName}-via-${e}`,x:n.x,y:n.y,parentRoute:t},i=`${Math.floor(n.x/this.CELL_SIZE)}x${Math.floor(n.y/this.CELL_SIZE)}`;let r=this.viaBuckets.get(i);r||(r=[],this.viaBuckets.set(i,r)),r.push(o)}}getConflictingRoutesNearPoint(t,e){const n=e+this.maximumCopperRadius,o=t.x-n,i=t.y-n,r=t.x+n,s=t.y+n,a=Math.floor(o/this.CELL_SIZE),c=Math.floor((r+1e-9)/this.CELL_SIZE),l=Math.floor(i/this.CELL_SIZE),d=Math.floor((s+1e-9)/this.CELL_SIZE),h=new Map,u=new Set,p=new Set;for(let n=a;n<=c;n++)for(let o=l;o<=d;o++){const i=`${n}x${o}`,r=this.segmentBuckets.get(i);if(r)for(const n of r){if(u.has(n.segmentId))continue;u.add(n.segmentId);const o=n.segment[0],i=n.segment[1];if(o.z!==i.z||o.z!==t.z)continue;const r=n.parentRoute,s={x:n.segment[0].x,y:n.segment[0].y},a={x:n.segment[1].x,y:n.segment[1].y},c=e+r.traceThickness/2,l=c*c,d=Fi(t,s,a);if(d<l){const t=r.connectionName,e=h.get(t);(!e||d<e.minDistSq)&&h.set(t,{route:r,minDistSq:d})}}const s=this.viaBuckets.get(i);if(s)for(const n of s){if(p.has(n.viaId))continue;p.add(n.viaId);const o=n.parentRoute,i={x:n.x,y:n.y},r=e+o.viaDiameter/2,s=r*r,a=zi(t,i);if(a<s){const t=o.connectionName,e=h.get(t);(!e||a<e.minDistSq)&&h.set(t,{route:o,minDistSq:a})}}}const m=[];for(const t of h.values())m.push({conflictingRoute:t.route,distance:Math.sqrt(t.minDistSq)});return m}};function $i(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 o=e;return()=>{let t=n;n=o,t^=t<<23,t^=t>>>17,t^=o,t^=o>>>26,o=t;const e=(n+o)/4294967296;return e-Math.floor(e)}}var Yi={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 Xi(t,e){if(0===e)return t;if(0===t.length)return t;if(t.length<=4){const n=Yi[t.length];return n[e%n.length].map(e=>t[e])}const n=$i(e),o=t.slice();for(let t=0;t<o.length;t++){const e=Math.floor(n()*o.length),i=Math.floor(n()*(t+1));[o[e],o[i]]=[o[i],o[e]]}return o}var Vi=t=>{let e=1/0;const n=t.portPoints;for(let t=0;t<n.length;t++)for(let o=t+1;o<n.length;o++){const i=n[t],r=n[o];if(i.z!==r.z)continue;if(i.rootConnectionName&&i.rootConnectionName===r.rootConnectionName)continue;const s=Math.sqrt((i.x-r.x)**2+(i.y-r.y)**2);e=Math.min(e,s)}return e===1/0?0:e},Wi=class{heap=[];constructor(t){this.heap=[];for(const e of t)this.enqueue(e)}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;const e=this.heap[t];for(;t>0;){const n=Math.floor((t-1)/2),o=this.heap[n];if(o.f<=e.f)break;this.heap[t]=o,t=n}this.heap[t]=e}heapifyDown(){let t=0;const e=this.heap.length,n=this.heap[t];if(n){for(;;){const o=2*t+1;if(o>=e)break;const i=o+1;let r=o;if(i<e&&this.heap[i].f<this.heap[o].f&&(r=i),n.f<this.heap[r].f)break;this.heap[t]=this.heap[r],t=r}this.heap[t]=n}}getTopN(t){return[...this.heap].sort((t,e)=>t.f-e.f).slice(0,t)}},Hi=(t,e,n=[])=>[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join("\n"),Gi=class extends si{getSolverName(){return"SingleHighDensityRouteSolver"}obstacleRoutes;bounds;boundsSize;boundsCenter;A;B;straightLineDistance;viaDiameter;traceThickness;obstacleMargin;layerCount;availableZ;minCellSize=.05;cellStep=.05;GREEDY_MULTIPLER=1.1;numRoutes;VIA_PENALTY_FACTOR=.3;CELL_SIZE_FACTOR;NEARBY_SEGMENT_CLEARANCE;exploredNodes;viasInPathByNode=new WeakMap;gridMinXIndex;gridMinYIndex;gridWidth;gridHeight;candidates;connectionName;rootConnectionName;regionId;solvedPath=null;futureConnections;hyperParameters;connMap;obstacleSegments=[];obstacleSegmentIndex=null;obstacleSegmentsByLayer=new Map;obstacleSegmentIndexByLayer=new Map;obstacleVias=[];obstacleViaIndex=null;debug_exploredNodesOrdered;debug_nodesTooCloseToObstacle;debug_nodePathToParentIntersectsObstacle;debugEnabled;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.rootConnectionName=t.rootConnectionName,this.regionId=t.regionId,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??.15,this.layerCount=t.layerCount??2,this.availableZ=t.availableZ&&t.availableZ.length>0?[...new Set(t.availableZ)].sort((t,e)=>t-e):Array.from({length:this.layerCount},(t,e)=>e),this.exploredNodes=new Set,this.straightLineDistance=xe(this.A,this.B),this.futureConnections=t.futureConnections??[],this.NEARBY_SEGMENT_CLEARANCE=t.nearbySegmentClearance??.15,this.debugEnabled=t.captureSearchDebug??!0,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,this.buildObstacleIndexes();const e=Math.ceil(5*(this.numRoutes+1));let n=this.boundsSize.width/this.cellStep,o=this.boundsSize.height/this.cellStep;for(;n*o>e**2&&!(2*this.cellStep>t.minDistBetweenEnteringPoints);)this.cellStep*=2,n=this.boundsSize.width/this.cellStep,o=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR,this.gridMinXIndex=Math.round(this.bounds.minX/this.cellStep)-1,this.gridMinYIndex=Math.round(this.bounds.minY/this.cellStep)-1;const i=Math.round(this.bounds.maxX/this.cellStep)+1,r=Math.round(this.bounds.maxY/this.cellStep)+1;this.gridWidth=i-this.gridMinXIndex+1,this.gridHeight=r-this.gridMinYIndex+1;const s=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&&!s&&this.handleSimpleCases();const a={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:a.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:a.y-Math.round(t.A.y/this.cellStep)*this.cellStep};const c={...t.A,z:t.A.z??0,g:0,h:0,f:0,parent:null},l={...t.A,...a,z:t.A.z??0,g:0,h:0,f:0,parent:c},d=(Math.abs(l.x-t.A.x)>1e-9||Math.abs(l.y-t.A.y)>1e-9)&&(this.isNodeTooCloseToObstacle(l)||this.isNodeTooCloseToEdge(l,!1)||this.doesPathToParentIntersectObstacle(l));this.candidates=new Wi([d?c:l])}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,rootConnectionName:this.rootConnectionName,regionId:this.regionId,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,o){if(e??=this.obstacleMargin,n&&t.parent){const n=this.getViasInNodePath(t.parent);for(const o of n)if(xe(t,o)<this.viaDiameter/2+e)return!0}const i=this.traceThickness+e,r=o?.segments??(n?this.obstacleSegments:this.obstacleSegmentsByLayer.get(t.z)),s=o?.segmentIds??(n?this.obstacleSegmentIndex:this.obstacleSegmentIndexByLayer.get(t.z))?.search(t.x-i,t.y-i,t.x+i,t.y+i)??[];if(r)for(const e of s){const s=r[e];if(s&&!s.connectedToCurrentConnection&&((n||s.z===t.z)&&(!o||!(t.x+i<s.minX||t.y+i<s.minY||t.x-i>s.maxX||t.y-i>s.maxY))&&be(t,s.A,s.B)<i))return!0}const a=this.viaDiameter/2+this.traceThickness/2+e;if(this.obstacleViaIndex){const e=this.obstacleViaIndex.search(t.x-a,t.y-a,t.x+a,t.y+a);for(const n of e){const e=this.obstacleVias[n];if(e&&xe(t,e)<a)return!0}}return!1}isNodeTooCloseToEdge(t,e){const n=e?this.viaDiameter/2+this.obstacleMargin/2:this.obstacleMargin/2,o=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!(o&&!e&&(xe(t,this.B)<2*n||xe(t,this.A)<2*n))&&o}doesPathToParentIntersectObstacle(t,e){const n=t.parent;if(!n)return!1;const o=e?.segments??this.obstacleSegmentsByLayer.get(t.z);if(!o)return!1;const i=t.z===n.z&&this.obstacleSegments.length>0?this.NEARBY_SEGMENT_CLEARANCE:0,r=Math.min(t.x,n.x),s=Math.max(t.x,n.x),a=Math.min(t.y,n.y),c=Math.max(t.y,n.y),l=e?.segmentIds??this.obstacleSegmentIndexByLayer.get(t.z)?.search(r-i,a-i,s+i,c+i)??[];for(const d of l){const l=o[d];if(l&&!l.connectedToCurrentConnection&&!(l.z!==t.z||e&&(s+i<l.minX||c+i<l.minY||r-i>l.maxX||a-i>l.maxY))){if(fe(t,n,l.A,l.B))return!0;if(i>0&&qi(t,n,l.A,l.B)<i)return!0}}return!1}getPlanarObstacleQuery(t){const e=t.parent;if(!e)return;const n=this.obstacleSegmentIndexByLayer.get(t.z),o=this.obstacleSegmentsByLayer.get(t.z);if(!n||!o)return;const i=this.traceThickness+this.obstacleMargin,r=t.z===e.z&&this.obstacleSegments.length>0?this.NEARBY_SEGMENT_CLEARANCE:0;return{segments:o,segmentIds:n.search(Math.min(t.x-i,e.x-r),Math.min(t.y-i,e.y-r),Math.max(t.x+i,e.x+r),Math.max(t.y+i,e.y+r))}}buildObstacleIndexes(){if(0===this.obstacleRoutes.length)return this.obstacleSegmentIndex=null,this.obstacleSegmentsByLayer.clear(),this.obstacleSegmentIndexByLayer.clear(),void(this.obstacleViaIndex=null);const t=[],e=[];for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName)??!1;for(const e of Ui(n))t.push({...e,minX:Math.min(e.A.x,e.B.x),minY:Math.min(e.A.y,e.B.y),maxX:Math.max(e.A.x,e.B.x),maxY:Math.max(e.A.y,e.B.y),connectedToCurrentConnection:o});for(const t of n.vias)e.push(t)}if(this.obstacleSegments=t,this.obstacleVias=e,this.obstacleSegmentsByLayer.clear(),this.obstacleSegmentIndexByLayer.clear(),t.length>0){const e=new Bt(t.length);for(const n of t)e.add(n.minX,n.minY,n.maxX,n.maxY);e.finish(),this.obstacleSegmentIndex=e;for(const e of t){if(e.connectedToCurrentConnection)continue;const t=this.obstacleSegmentsByLayer.get(e.z);t?t.push(e):this.obstacleSegmentsByLayer.set(e.z,[e])}for(const[t,e]of this.obstacleSegmentsByLayer){const n=new Bt(e.length);for(const t of e)n.add(t.minX,t.minY,t.maxX,t.maxY);n.finish(),this.obstacleSegmentIndexByLayer.set(t,n)}}else this.obstacleSegmentIndex=null;if(e.length>0){const t=new Bt(e.length);for(const n of e)t.add(n.x,n.y,n.x,n.y);t.finish(),this.obstacleViaIndex=t}else this.obstacleViaIndex=null}computeH(t){return xe(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)+xe(t,t.parent)}computeF(t,e){return t+e*this.GREEDY_MULTIPLER}setNodeCosts(t){t.g=this.computeG(t),t.h=this.computeH(t),t.f=this.computeF(t.g,t.h)}getNodeKey(t){const e=Math.round(t.x/this.cellStep)-this.gridMinXIndex,n=Math.round(t.y/this.cellStep)-this.gridMinYIndex;return(t.z*this.gridHeight+n)*this.gridWidth+e}getNeighbors(t){const e=[],{maxX:n,minX:o,maxY:i,minY:r}=this.bounds;for(let s=-1;s<=1;s++)for(let a=-1;a<=1;a++){if(0===s&&0===a)continue;const c={x:Zi(t.x+s*this.cellStep,o,n),y:Zi(t.y+a*this.cellStep,r,i),z:t.z,g:t.g,h:t.h,f:t.f,parent:t},l=this.getNodeKey(c);if(this.exploredNodes.has(l))continue;const d=this.getPlanarObstacleQuery(c);this.isNodeTooCloseToObstacle(c,void 0,!1,d)?(this.debugEnabled&&this.debug_nodesTooCloseToObstacle.add(l),this.exploredNodes.add(l)):this.isNodeTooCloseToEdge(c,!1)?this.exploredNodes.add(l):this.doesPathToParentIntersectObstacle(c,d)?(this.debugEnabled&&this.debug_nodePathToParentIntersectsObstacle.add(l),this.exploredNodes.add(l)):(this.setNodeCosts(c),e.push(c))}for(const n of this.availableZ){if(n===t.z)continue;const o={x:t.x,y:t.y,z:n,g:t.g,h:t.h,f:t.f,parent:t};this.exploredNodes.has(this.getNodeKey(o))||this.isNodeTooCloseToObstacle(o,this.viaDiameter/2+this.obstacleMargin/2,!0)||this.isNodeTooCloseToEdge(o,!0)||(this.setNodeCosts(o),e.push(o))}return e}getNodePath(t){const e=[];for(;t;)e.push(t),t=t.parent;return e}getViasInNodePath(t){const e=this.viasInPathByNode.get(t);if(e)return e;const n=t.parent,o=n?this.getViasInNodePath(n):[],i=n&&t.z!==n.z?[{x:t.x,y:t.y},...o]:o;return this.viasInPathByNode.set(t,i),i}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,rootConnectionName:this.rootConnectionName,regionId:this.regionId,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){if(void 0===e||void 0===n)return Number.NaN;n||(e+=this.viaPenaltyDistance);const o=1-e/this.straightLineDistance;return Math.max(this.progress||0,2/Math.PI*Math.atan(.112*o/(1-o)))}_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.debugEnabled&&this.debug_exploredNodesOrdered.push({key:e,x:Math.round(t.x/this.cellStep)*this.cellStep+this.initialNodeGridOffset.x,y:Math.round(t.y/this.cellStep)*this.cellStep+this.initialNodeGridOffset.y,z:t.z});const n=xe(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 o=this.getNeighbors(t);for(const t of o)this.candidates.enqueue(t)}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:Hi(this.connectionName,this.rootConnectionName,["Input A",`z: ${this.A.z}`]),color:"orange"}),t.points.push({x:this.B.x,y:this.B.y,label:Hi(this.connectionName,this.rootConnectionName,["Input B",`z: ${this.B.z}`]),color:"orange"}),t.lines.push({points:[this.A,this.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:Hi(this.connectionName,this.rootConnectionName,["Direct Input Connection"])});for(let e=0;e<this.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let o=0;o<n.route.length-1;o++){const i=n.route[o].z;t.lines.push({points:[n.route[o],n.route[o+1]],strokeColor:0===i?"rgba(255, 0, 0, 0.75)":"rgba(255, 128, 0, 0.25)",strokeWidth:n.traceThickness,label:Hi(n.connectionName,n.rootConnectionName,["Obstacle Route"]),layer:`obstacle${e.toString()}`})}}for(let e=0;e<this.debug_exploredNodesOrdered.length;e++){const{key:n,x:o,y:i,z:r}=this.debug_exploredNodesOrdered[e];this.debug_nodesTooCloseToObstacle.has(n)||(this.debug_nodePathToParentIntersectsObstacle.has(n)||t.rects.push({center:{x:o+r*this.cellStep/20,y:i+r*this.cellStep/20},fill:0===r?`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=${r})`}))}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:Hi(this.solvedPath.connectionName,this.solvedPath.rootConnectionName,["Solved Route"])});for(const e of this.solvedPath.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"green",label:Hi(this.solvedPath.connectionName,this.solvedPath.rootConnectionName,["Via"])})}return t}};function Ui(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 Zi(t,e,n){return Math.max(e,Math.min(t,n))}function qi(t,e,n,o){return Math.min(be(t,n,o),be(e,n,o),be(n,t,e),be(o,t,e))}var Ji=class extends Gi{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;FUTURE_CONNECTION_VIA_TRACE_CLEARANCE=.1;futureConnectionPoints;futureConnectionSegmentsCache=null;constructor(t){super({...t,nearbySegmentClearance:t.nearbySegmentClearance??(t.traceThickness??.15)/2+(t.obstacleMargin??.15)});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,this.futureConnectionPoints=this.futureConnections.flatMap(t=>t.points)}getClosestFutureConnectionPoint(t){let e=1/0,n=null;for(const o of this.futureConnectionPoints){const i=xe(t,o)+(t.z!==o.z?this.viaPenaltyDistance:0);i<e&&(e=i,n=o)}return n}getFutureConnectionSegments(){if(this.futureConnectionSegmentsCache)return this.futureConnectionSegmentsCache;const t=[];for(const e of this.futureConnections){if(e.connectionName===this.connectionName||(this.connMap?.areIdsConnected?.(this.connectionName,e.connectionName)??!1))continue;const[n,...o]=e.points;if(n)for(const i of o)Math.abs(n.x-i.x)<1e-9&&Math.abs(n.y-i.y)<1e-9||t.push({connectionName:e.connectionName,start:n,end:i})}return this.futureConnectionSegmentsCache=t,t}isViaTooCloseToFutureConnectionTrace(t){const e=this.viaDiameter/2+this.traceThickness/2+this.FUTURE_CONNECTION_VIA_TRACE_CLEARANCE;for(const n of this.getFutureConnectionSegments())if(be(t,n.start,n.end)<e)return!0;return!1}isNodeTooCloseToObstacle(t,e,n,o){return!!super.isNodeTooCloseToObstacle(t,e,n,o)||!(!n||!this.isViaTooCloseToFutureConnectionTrace(t))}diminishCloseToGoal(t){const e=xe(t,this.B);return 1-Math.exp(-e/this.straightLineDistance*5)}getFutureConnectionPenalty(t,e){let n=0;const o=this.getClosestFutureConnectionPoint(t),i=xe(t,this.B);if(o){const r=xe(t,o);if(i<=r)return 0;const s=r/(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*-s)}return n}computeH(t){const e=xe(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),o=Math.sqrt(e**2+n**2),i=t.z%2==0,r=this.FLIP_TRACE_ALIGNMENT_DIRECTION?i?e:n:i?n:e;return(t.parent?.g??0)+(t.z===t.parent?.z?0:this.viaPenaltyDistance)+o+r*this.MISALIGNED_DIST_PENALTY_FACTOR+this.getFutureConnectionPenalty(t,t.z!==t.parent?.z)}setNodeCosts(t){const e=Math.abs(t.x-t.parent.x),n=Math.abs(t.y-t.parent.y),o=Math.sqrt(e**2+n**2),i=t.z%2==0,r=this.FLIP_TRACE_ALIGNMENT_DIRECTION?i?e:n:i?n:e,s=(t.parent?.g??0)+(t.z===t.parent?.z?0:this.viaPenaltyDistance)+o+r*this.MISALIGNED_DIST_PENALTY_FACTOR,a=xe(t,this.B)**1.6+(t.z!==this.B.z?this.viaPenaltyDistance:0),c=this.getFutureConnectionPenalty(t,t.z!==t.parent?.z);t.g=s+c,t.h=a+c,t.f=this.computeF(t.g,t.h)}},Ki=(t,e,n=[])=>[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join("\n"),Qi=t=>`${t.x.toFixed(6)},${t.y.toFixed(6)},${t.z}`,tr=t=>{const e=new Set,n=[];for(const o of t){const t=Qi(o);e.has(t)||(e.add(t),n.push(o))}return n},er=class extends si{getSolverName(){return"IntraNodeRouteSolver"}nodeWithPortPoints;colorMap;unsolvedConnections;originalConnectionPointsByName;rootConnectionNameByConnectionName;totalConnections;solvedRoutes;failedSubSolvers;hyperParameters;minDistBetweenEnteringPoints;viaDiameter;traceWidth;obstacleMargin;captureSearchDebug;rerouteAttemptsByConnection;POSTROUTE_VIA_TRACE_CLEARANCE=.1;MAX_POSTROUTE_REPAIR_ATTEMPTS=2;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,this.obstacleMargin=t.obstacleMargin??.15,this.captureSearchDebug=t.captureSearchDebug??!0;const o=new Map;this.rootConnectionNameByConnectionName=new Map;for(const{connectionName:t,rootConnectionName:n,x:i,y:r,z:s}of e.portPoints)n&&this.rootConnectionNameByConnectionName.set(t,n),o.set(t,[...o.get(t)??[],{x:i,y:r,z:s??0}]);this.originalConnectionPointsByName=new Map(Array.from(o.entries()).map(([t,e])=>[t,tr(e)])),this.unsolvedConnections=Array.from(o.entries().map(([t,e])=>({connectionName:t,rootConnectionName:this.rootConnectionNameByConnectionName.get(t),points:tr(e)}))),this.rerouteAttemptsByConnection=new Map,this.hyperParameters.SHUFFLE_SEED&&(this.unsolvedConnections=Xi(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=>({...e,points:Xi(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Vi(this.nodeWithPortPoints)}computeProgress(){return(this.solvedRoutes.length+(this.activeSubSolver?.progress||0))/this.totalConnections}getSingleRouteSolverOpts(t){const{connectionName:e,rootConnectionName:n,points:o}=t;return{connectionName:e,rootConnectionName:n,regionId:this.nodeWithPortPoints.capacityMeshNodeId,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:ro(this.nodeWithPortPoints),A:{x:o[0].x,y:o[0].y,z:o[0].z},B:{x:o[o.length-1].x,y:o[o.length-1].y,z:o[o.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),availableZ:this.nodeWithPortPoints.availableZ&&this.nodeWithPortPoints.availableZ.length>0?this.nodeWithPortPoints.availableZ:[...new Set(this.nodeWithPortPoints.portPoints.map(t=>t.z??0))].sort((t,e)=>t-e),hyperParameters:this.hyperParameters,connMap:this.connMap,viaDiameter:this.viaDiameter,traceThickness:this.traceWidth,obstacleMargin:this.obstacleMargin,captureSearchDebug:this.captureSearchDebug}}trySolveSamePointLayerChange(t){const e=this.getSingleRouteSolverOpts(t),n=new Ji(e),{A:o,B:i}=e,r={x:o.x,y:o.y};if(!nr(n,r,o,i))return!1;const s=[{x:o.x,y:o.y,z:o.z},{...r,z:o.z},{...r,z:i.z},{x:i.x,y:i.y,z:i.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 this.solvedRoutes.push({connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,regionId:this.nodeWithPortPoints.capacityMeshNodeId,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:s,vias:[{x:r.x,y:r.y}]}),!0}queueExtraBranchesForMultiPointConnection(t){const[e,...n]=tr(t.points);if(!e||n.length<=1)return!1;for(const o of n)this.unsolvedConnections.push({connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,points:[e,o]});return!0}getAvailableZLayers(){return this.nodeWithPortPoints.availableZ&&this.nodeWithPortPoints.availableZ.length>0?[...new Set(this.nodeWithPortPoints.availableZ)].sort((t,e)=>t-e):[...new Set(this.nodeWithPortPoints.portPoints.map(t=>t.z??0))].sort((t,e)=>t-e)}getFirstSolvedViaTraceConflict(){if(this.solvedRoutes.length<2)return null;const t=new ji(this.solvedRoutes),e=this.getAvailableZLayers();for(const n of this.solvedRoutes){const o=n.viaDiameter/2+this.POSTROUTE_VIA_TRACE_CLEARANCE;for(const i of n.vias)for(const r of e){const e=t.getConflictingRoutesNearPoint({x:i.x,y:i.y,z:r},o).filter(({conflictingRoute:t})=>t.connectionName!==n.connectionName&&!this.connMap?.areIdsConnected(n.connectionName,t.connectionName));if(e.length>0)return{route:n,via:i,conflictingRoute:e[0].conflictingRoute}}}return null}queueConnectionForPostrouteRepair(t){const e=this.originalConnectionPointsByName.get(t);return!(!e||e.length<2)&&(this.solvedRoutes=this.solvedRoutes.filter(e=>e.connectionName!==t),this.unsolvedConnections.push({connectionName:t,rootConnectionName:this.rootConnectionNameByConnectionName.get(t),points:e.map(t=>({...t}))}),this.rerouteAttemptsByConnection.set(t,(this.rerouteAttemptsByConnection.get(t)??0)+1),!0)}_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){const t=this.getFirstSolvedViaTraceConflict();if(t){if((this.rerouteAttemptsByConnection.get(t.route.connectionName)??0)>=this.MAX_POSTROUTE_REPAIR_ATTEMPTS)return this.error=["Post-route via/trace clearance repair exceeded retry budget",`route: ${t.route.connectionName}`,`conflicts with: ${t.conflictingRoute.connectionName}`,`via: (${t.via.x.toFixed(3)}, ${t.via.y.toFixed(3)})`].join("\n"),void(this.failed=!0);if(this.queueConnectionForPostrouteRepair(t.route.connectionName))return void(this.progress=this.computeProgress())}return void(this.solved=0===this.failedSubSolvers.length)}if(1!==t.points.length&&!(t.points.length>2&&this.queueExtraBranchesForMultiPointConnection(t))){if(2===t.points.length){const[e,n]=t.points,o=Math.abs(e.x-n.x)<1e-6,i=Math.abs(e.y-n.y)<1e-6;if(o&&i&&e.z===n.z)return;if(o&&i&&e.z!==n.z&&this.trySolveSamePointLayerChange(t))return}this.activeSubSolver=new Ji(this.getSingleRouteSolverOpts(t))}}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.nodeWithPortPoints.portPoints)t.points.push({x:e.x,y:e.y,label:Ki(e.connectionName,e.rootConnectionName,[`layer: ${e.z}`]),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 o=this.colorMap[n.connectionName]??"blue",i=n.rootConnectionName??this.rootConnectionNameByConnectionName.get(n.connectionName);for(let r=0;r<n.route.length-1;r++){const s=n.route[r],a=n.route[r+1];t.lines.push({points:[s,a],label:Ki(n.connectionName,i,[`layer: ${s.z}`]),strokeColor:0===s.z?To(o,.2):To(o,.8),layer:`route-layer-${s.z}`,step:e,strokeWidth:n.traceThickness})}for(const r of n.vias)t.circles.push({center:{x:r.x,y:r.y},radius:n.viaDiameter/2,fill:To(o,.5),layer:"via",step:e,label:Ki(n.connectionName,i,["via"])})}}const e=ro(this.nodeWithPortPoints),{minX:n,minY:o,maxX:i,maxY:r}=e;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:r},{x:n,y:r},{x:n,y:o}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}},nr=(t,e,n,o)=>{const i={x:e.x,y:e.y,z:n.z,parent:{x:n.x,y:n.y,z:n.z,g:0,h:0,f:0,parent:null},g:0,h:0,f:0};return!t.isNodeTooCloseToObstacle(i,t.viaDiameter/2+t.obstacleMargin/2,!0)&&!t.isNodeTooCloseToEdge(i,!0)},or=t=>Math.round(200*t)/200,ir=t=>"function"==typeof structuredClone?structuredClone(t):JSON.parse(JSON.stringify(t));io();var rr=class extends er{getSolverName(){return"CachedIntraNodeRouteSolver"}cacheProvider;cacheHit=!1;hasAttemptedToUseCache=!1;initialUnsolvedConnections;constructor(t){super(t),this.cacheProvider=void 0===t.cacheProvider?oo():t.cacheProvider,this.initialUnsolvedConnections=ir(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,rootConnectionName:n,points:o})=>({connectionName:e,rootConnectionName:n,points:o.map(n=>({connectionName:e,x:or(n.x-t.x),y:or(n.y-t.y),z:n.z??0}))})),n=[...this.nodeWithPortPoints.portPoints].sort((t,e)=>t.connectionName!==e.connectionName?t.connectionName.localeCompare(e.connectionName):(t.portPointId??"")!==(e.portPointId??"")?(t.portPointId??"").localeCompare(e.portPointId??""):t.x!==e.x?t.x-e.x:t.y!==e.y?t.y-e.y:(t.z??0)-(e.z??0)).map(e=>({connectionName:e.connectionName,rootConnectionName:e.rootConnectionName,portPointId:e.portPointId,prevPortPointId:e.prevPortPointId,nextPortPointId:e.nextPortPointId,x:or(e.x-t.x),y:or(e.y-t.y),z:e.z??0})),o=Object.fromEntries(Object.entries(this.hyperParameters??{}).filter(([,t])=>void 0!==t).sort(([t],[e])=>t.localeCompare(e))),i=this.connMap?this.initialUnsolvedConnections.map(({connectionName:t})=>({connectionName:t,connectedIds:[...new Set(this.connMap.getIdsConnectedToNet(t)??[])].sort()})):void 0,r={cacheSchemaVersion:4,node:{width:or(this.nodeWithPortPoints.width),height:or(this.nodeWithPortPoints.height),center:{x:or(this.nodeWithPortPoints.center.x),y:or(this.nodeWithPortPoints.center.y)},availableZ:this.nodeWithPortPoints.availableZ?[...this.nodeWithPortPoints.availableZ].sort():void 0,portPoints:n},normalizedConnections:e,normalizedHyperParameters:o,minDistBetweenEnteringPoints:or(this.minDistBetweenEnteringPoints),traceWidth:or(this.traceWidth),viaDiameter:or(this.viaDiameter),obstacleMargin:or(this.obstacleMargin),normalizedConnMap:i},s=`intranode-solver:${Li(r,{respectType:!1,unorderedObjects:!1})}`,a={};return this.cacheKey=s,this.cacheToSolveSpaceTransform=a,{cacheKey:s,cacheToSolveSpaceTransform:a}}applyCachedSolution(t){t.success?(this.solvedRoutes=ir(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:ir(this.solvedRoutes)};try{this.cacheProvider.setCachedSolutionSync(this.cacheKey,t)}catch(t){console.error("Error saving solution to cache:",t)}}},sr=(t,e)=>{const n={};return t.portPoints.forEach((e,o)=>{n[e.connectionName]=`hsl(${360*o/t.portPoints.length}, 100%, 50%)`}),n},ar=class extends si{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:o}){super(),this.MAX_ITERATIONS=1e5,this.colorMap=e??sr(t),this.maxViaCount=5,this.bounds=ro(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=o??.3,this.unprocessedConnections=Array.from(this.portPairMap.keys()).sort(),n?.SHUFFLE_SEED&&(this.unprocessedConnections=Xi(this.unprocessedConnections,n.SHUFFLE_SEED));for(const[t,{start:e,end:n}]of this.portPairMap.entries())if(e.z===n.z){const o=Math.abs(e.x-n.x)<1e-9,i=Math.abs(e.y-n.y)<1e-9;o||i?this.placeholderPaths.set(t,[e,this._padByPlaceholderWallBuffer(e),this._padByPlaceholderWallBuffer(n),n]):this.placeholderPaths.set(t,[e,n])}else{const o=(e.x+n.x)/2,i=(e.y+n.y)/2,r=this._padByPlaceholderWallBuffer({x:o,y:i,z:e.z}),s=this._padByPlaceholderWallBuffer({x:o,y:i,z:n.z});this.placeholderPaths.set(t,[e,this._padByPlaceholderWallBuffer(e),r,s,this._padByPlaceholderWallBuffer(n),n])}this.currentConnectionName=this.unprocessedConnections.pop();const i=this.portPairMap.get(this.currentConnectionName).start;this.currentHead=this._padByNewHeadWallBuffer(i),this.currentPath=[i,this.currentHead],this.currentViaCount=0,this.placeholderPaths.delete(this.currentConnectionName)}_padByNewHeadWallBuffer(t){return{x:Ae(t.x,this.bounds.minX+this.NEW_HEAD_WALL_BUFFER_DISTANCE,this.bounds.maxX-this.NEW_HEAD_WALL_BUFFER_DISTANCE),y:Ae(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:Ae(t.x,this.bounds.minX+this.PLACEHOLDER_WALL_BUFFER_DISTANCE,this.bounds.maxX-this.PLACEHOLDER_WALL_BUFFER_DISTANCE),y:Ae(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,o=null;const i=t=>{for(const i of t.values())for(let t=0;t<i.length-1;t++){const r=[i[t],i[t+1]];if(r[0].x===r[1].x&&r[0].y===r[1].y)continue;if(r[0].z!==this.currentHead.z)continue;const s=ve(e[0],e[1],r[0],r[1]);if(s){const t=xe(this.currentHead,s);if(t<1e-6)continue;(!n||t<n.dist)&&(n={point:s,dist:t},o=r[0].z)}}};i(this.completedPaths),i(this.placeholderPaths);const r=this.currentHead.z!==t.z;if((n||r)&&(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=$e(this.currentHead,n.point);else{const o=n.point,i=o.x-this.currentHead.x,r=o.y-this.currentHead.y,s=(e-this.VIA_INTERSECTION_BUFFER_DISTANCE)/e;t={x:this.currentHead.x+i*s,y:this.currentHead.y+r*s}}const i=this.availableZ.find(t=>t!==o);if(void 0===i)return this.error="Could not determine next Z level for via placement!",void(this.failed=!0);const r={...t,z:this.currentHead.z},s={...t,z:i};this.currentPath.push(r,s),this.currentHead=s}else if(r){let e;const n=xe(this.currentHead,t);if(n<this.VIA_INTERSECTION_BUFFER_DISTANCE)e=$e(this.currentHead,t);else{const o=t.x-this.currentHead.x,i=t.y-this.currentHead.y,r=(n-this.VIA_INTERSECTION_BUFFER_DISTANCE)/n;e={x:this.currentHead.x+o*r,y:this.currentHead.y+i*r}}const o=t.z,i={...e,z:this.currentHead.z},r={...e,z:o};this.currentPath.push(i,r),this.currentHead=r}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:o}]of this.portPairMap.entries()){const i=this.colorMap[e]??"black";t.points.push({x:n.x,y:n.y,color:i,label:`Port: ${e} Start (z${n.z})`}),t.points.push({x:o.x,y:o.y,color:i,label:`Port: ${e} End (z${o.z})`})}const n=(n,o)=>{for(const[i,r]of n.entries()){const n=e[i]??"black";for(let e=0;e<r.length-1;e++){const s=r[e],a=r[e+1];s.x===a.x&&s.y===a.y&&s.z!==a.z?t.circles.push({center:{x:s.x,y:s.y},radius:this.viaDiameter/2,fill:To(n,.5),label:`${o}: ${i} Via (z${s.z}->z${a.z})`}):t.lines.push({points:[s,a],strokeColor:To(n,.5),strokeDash:0===s.z?void 0:[.1,.1],strokeWidth:.1,label:`${o}: ${i} (z${s.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 o=this.currentPath[e],i=this.currentPath[e+1];o.x===i.x&&o.y===i.y&&o.z!==i.z?t.circles.push({center:{x:o.x,y:o.y},radius:this.viaDiameter/2,fill:To(n,.5),label:`Current: ${this.currentConnectionName} Via (z${o.z}->z${i.z})`}):t.lines.push({points:[o,i],strokeColor:To(n,.5),strokeWidth:.15,strokeDash:"2,2",label:`Current: ${this.currentConnectionName} (z${o.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}},cr=t=>Math.round(1e4*t),lr=t=>{let e=0,n=[];const o=[];for(const e of t.portPoints){if(n.some(t=>t.connectionName===e.connectionName))continue;if(o.some(t=>t.connectionName===e.connectionName))continue;const i={connectionName:e.connectionName,z:e.z,points:[{x:cr(e.x),y:cr(e.y),z:e.z}]};for(const n of t.portPoints)e.connectionName===n.connectionName&&(e.x===n.x&&e.y===n.y||i.points.push({x:cr(n.x),y:cr(n.y),z:n.z}));i.points.some(t=>t.z!==i.z)?o.push(i):n.push(i)}n=n.filter(t=>t.points.length>1);for(let t=0;t<n.length;t++)for(let o=t+1;o<n.length;o++){const i=n[t],r=n[o];i.z===r.z&&fe(i.points[0],i.points[1],r.points[0],r.points[1])&&e++}let i=0;for(let t=0;t<o.length;t++)for(let e=t+1;e<o.length;e++){const n=o[t],r=o[e];fe(n.points[0],n.points[1],r.points[0],r.points[1])&&i++}return{numSameLayerCrossings:e,numEntryExitLayerChanges:o.length,numTransitionPairCrossings:i}};var dr=t=>{const{start:e,end:n,segmentsPerPolyline:o,viaPositions:i,viaCount:r,availableZ:s}=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 o=Math.floor(t/e),i=Math.floor((t-(o*(e-1)+1))/2);for(let t=0;t<e;t++)n[i+t*o]=1}else{const o=t-e,i=Math.floor(t/o),r=Math.floor((t-(i*(o-1)+1))/2);n.fill(1);for(let t=0;t<o;t++)n[r+t*i]=0}return n}(o,r),c=a.map(()=>null);let l=0,d=e.z1;const h=s.indexOf(e.z1);for(let t=0;t<a.length;t++)if(1===a[t]){const e=s[(h+l+1)%s.length];c[t]={...i[l],z1:d,z2:e},d=e,l++}let u=e;for(let t=0;t<c.length;t++){if(c[t]){u=c[t];continue}let e=n,o=c.length;for(let n=t+1;n<c.length;n++)if(c[n]){e=c[n],o=n;break}const i=o-t,r=e.x-u.x,s=e.y-u.y;for(let e=1/(i+1),n=0;t+n!==o;e+=1/(i+1),n++)c[t+n]={x:u.x+r*e,y:u.y+s*e,z1:u.z2,z2:u.z2}}return c},hr=1e-9;function ur(t,e){return Math.abs(t-e)<hr}function pr(t){return`${Math.round(t.x/hr)}:${Math.round(t.y/hr)}`}function mr(t,e,n,o){return t*o-e*n}function gr(t,e,n,o){const i={x:e.x-t.x,y:e.y-t.y},r={x:o.x-n.x,y:o.y-n.y},s=mr(i.x,i.y,r.x,r.y),a={x:n.x-t.x,y:n.y-t.y};if(ur(s,0))return null;const c=mr(a.x,a.y,r.x,r.y)/s,l=mr(a.x,a.y,i.x,i.y)/s;return c>=-1e-9&&c<=1+hr&&l>=-1e-9&&l<=1+hr?{x:t.x+c*i.x,y:t.y+c*i.y}:null}function fr(t,e,n){return ur(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 yr(t,e){const n=[],o=new Map;for(const e of t){const t=[e.start,...e.mPoints,e.end];for(let i=0;i<t.length-1;i++){const r=t[i],s=t[i+1],a=r.z2;if(n.push({start:{x:r.x,y:r.y},end:{x:s.x,y:s.y},connectionName:e.connectionName,layer:a}),r.z1!==r.z2){const t=pr(r);o.has(t)||o.set(t,{point:r,connectionName:e.connectionName})}}const i=t[t.length-1];if(i.z1!==i.z2){const t=pr(i);o.has(t)||o.set(t,{point:i,connectionName:e.connectionName})}}const i=[{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(...i);const r=new Map;let s=0;function a(t,e){const n=pr(t);let i=r.get(n);if(!i){const e=o.has(n);i={id:s++,x:t.x,y:t.y,isVia:e,connectionNames:new Set,outgoingEdges:[]},r.set(n,i),e&&o.get(n)&&i.connectionNames.add(o.get(n).connectionName)}return e&&i.connectionNames.add(e),i}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 o=gr(n[t].start,n[t].end,n[e].start,n[e].end);o&&(a(o),fr(o,n[t].start,n[t].end)&&c.get(n[t]).push(o),fr(o,n[e].start,n[e].end)&&c.get(n[e]).push(o))}const l=[];let d=0;for(const t of n){const e=[t.start,...c.get(t),t.end];e.sort((e,n)=>{const o=t.end.x-t.start.x,i=t.end.y-t.start.y;return Math.abs(o)>Math.abs(i)?(e.x-t.start.x)/o-(n.x-t.start.x)/o:Math.abs(i)<hr?0:(e.y-t.start.y)/i-(n.y-t.start.y)/i});const n=[];if(e.length>0){n.push(e[0]);for(let t=1;t<e.length;t++)ur(e[t].x,e[t-1].x)&&ur(e[t].y,e[t-1].y)||n.push(e[t])}for(let e=0;e<n.length-1;e++){const o=n[e],i=n[e+1],r=a(o,t.connectionName),s=a(i,t.connectionName);if(r===s)continue;const c={id:d++,origin:r,twin:null,next:null,face:null,connectionName:t.connectionName,layer:t.layer,visited:!1},h={id:d++,origin:s,twin:c,next:null,face:null,connectionName:t.connectionName,layer:t.layer,visited:!1};c.twin=h,l.push(c,h),r.outgoingEdges.push(c),s.outgoingEdges.push(h)}}for(const t of r.values()){t.outgoingEdges.sort((e,n)=>{const o=e.twin.origin,i=n.twin.origin;return Math.atan2(o.y-t.y,o.x-t.x)-Math.atan2(i.y-t.y,i.x-t.x)});const e=t.outgoingEdges.length;for(let n=0;n<e;n++){const o=t.outgoingEdges[n],i=t.outgoingEdges[(n-1+e)%e];o.twin&&(o.twin.next=i)}}const h=[];let u=0,p=null,m=-1/0;for(const t of l){if(t.visited)continue;const e={id:u++,outerComponent:t,innerComponents:[],isOuterFace:!1};h.push(e);let n=t;const o=[],i=[],r=new Set;let s=0;do{if(!n||n.visited){console.warn("Face traversal encountered visited edge or null, breaking loop.",e.id),o.length=0;break}n.visited=!0,n.face=e,o.push(n),i.push(n.origin),null!==n.connectionName&&r.add(n.connectionName);const t=n.origin,a=n.twin.origin;s+=t.x*a.y-a.x*t.y,n=n.next}while(n!==t&&null!==n);if(n===t){if(s=.5*Math.abs(s),s>m&&(m=s,p&&(p.isOuterFace=!1),p=e,e.isOuterFace=!0),!e.isOuterFace&&o.length>0){if([...r].filter(t=>null!==t).length>1){let t=!1;for(const e of i)if(e.isVia){t=!0;break}if(!t)return!0}}}else console.warn(`Face ${e.id} did not close properly.`),h.pop(),u--}return!1}var _r=t=>{if(0===t.length)return[[]];const e=[];for(let n=0;n<t.length;n++){const o=t[n],i=[...t.slice(0,n),...t.slice(n+1)],r=_r(i);for(const t of r)e.push([o,...t])}return e},br=1e-9;function xr(t,e,n=1e-9){return Math.abs(t-e)<n}function vr(t,e,n,o){return t*o-e*n}function Sr(t,e,n,o){const i={x:e.x-t.x,y:e.y-t.y},r={x:o.x-n.x,y:o.y-n.y},s=vr(i.x,i.y,r.x,r.y);if(xr(s,0))return null;const a={x:n.x-t.x,y:n.y-t.y},c=vr(a.x,a.y,r.x,r.y)/s,l=vr(a.x,a.y,i.x,i.y)/s;return c<-1e-9||c>1+br||l<-1e-9||l>1+br?null:{x:t.x+c*i.x,y:t.y+c*i.y}}function Ir(t){let e=0;for(let n=0,o=t.length;n<o;++n){const i=(n+1)%o;e+=t[n].x*t[i].y-t[i].x*t[n].y}return.5*e}function Cr(t){let e=0,n=0,o=0;for(let i=0,r=t.length;i<r;++i){const s=(i+1)%r,a=t[i].x*t[s].y-t[s].x*t[i].y;e+=a,n+=(t[i].x+t[s].x)*a,o+=(t[i].y+t[s].y)*a}return e*=.5,xr(e,0)?null:(n/=6*e,o/=6*e,{x:n,y:o})}var Pr=class{x;y;out;connectionNames;constructor(t,e){this.x=t,this.y=e,this.out=[],this.connectionNames=new Set}},Mr=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 Nr(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}}]],o=n.map(()=>[]);for(let t=0;t<n.length;++t){const e=n[t];o[t].push(e.start,e.end)}for(let t=0;t<n.length;++t)for(let e=t+1;e<n.length;++e){const i=Sr(n[t].start,n[t].end,n[e].start,n[e].end);i&&(o[t].push(i),o[e].push(i))}const i=new Map,r=[];function s(t){const e=function(t,e=1e-9){return`${Math.round(t.x/e)}:${Math.round(t.y/e)}`}(t);if(!i.has(e)){const n=r.length;return i.set(e,n),r.push(new Pr(t.x,t.y)),n}return i.get(e)}const a=[];for(let t=0;t<n.length;++t){const e=n[t],i=o[t].slice();i.sort((t,n)=>{const o=e.end.x-e.start.x,i=e.end.y-e.start.y;return(xr(Math.abs(o),0)?(t.y-e.start.y)/i:(t.x-e.start.x)/o)-(xr(Math.abs(o),0)?(n.y-e.start.y)/i:(n.x-e.start.x)/o)});for(let t=0;t<i.length-1;++t){const n=i[t],o=i[t+1],c=s(n),l=s(o);c!==l&&(a.push([c,l]),e.connectionName&&(r[c].connectionNames.add(e.connectionName),r[l].connectionNames.add(e.connectionName)))}}const c=[];for(const[t,e]of a){const n=new Mr(t,e),o=new Mr(e,t);n.twin=c.length+1,o.twin=c.length;const i=c.length;c.push(n,o),r[t].out.push(i),r[e].out.push(i+1)}for(let t=0;t<r.length;++t){const e=r[t];e.out.sort((t,n)=>{const o=c[t],i=c[n],s=r[o.dest],a=r[i.dest];return Math.atan2(s.y-e.y,s.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 o=e.out[t],i=e.out[(t-1+n)%n],r=c[o];null!==r.twin&&(c[r.twin].next=i)}}const l=[],d=[];for(let t=0;t<c.length;++t){if(c[t].visited)continue;let e=t;const n=[],o=[];do{if(null===e)break;const t=c[e];t.visited=!0,n.push(r[t.orig]),o.push(e),e=t.next}while(null!==e&&e!==t&&!c[e].visited);if(n.length<3)continue;if(Ir(n)>br){const t=Cr(n);t&&(l.push(t),d.push({vertices:n.map(t=>({x:t.x,y:t.y,connectionNames:t.connectionNames.size>0?t.connectionNames:void 0})),centroid:t}))}}return{centroids:l,faces:d,allVertices:r}}function wr(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(o,i,r){r!==e?(o[r]=0,t(o,i,r+1),i>0&&(o[r]=1,t(o,i-1,r+1))):0===i&&n.push([...o])}(Array(e).fill(0),t,0),n}var Tr=class extends si{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??sr(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,o=new Set(this.nodeWithPortPoints.portPoints.map(t=>t.connectionName)).size;this.uniqueConnections=o;const{numSameLayerCrossings:i,numEntryExitLayerChanges:r}=lr(this.nodeWithPortPoints);if(this.minViaCount=2*i+r,this.maxViaCount=Math.min(Math.floor(e/n),Math.ceil(1.5*o)),this.minViaCount>this.SEGMENTS_PER_POLYLINE*(o/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=[],o=[];for(let e=0;e<t.length;e++){const i=t[e],r=[i.start,...i.mPoints,i.end],s=new Map(this.availableZ.map(t=>[t,[]]));for(let t=0;t<r.length-1;t++){const e=[r[t],r[t+1]],n=e[0].z2;s.has(n)||s.set(n,[]),s.get(n).push(e)}n.push(s),o.push(r.filter(t=>t.z1!==t.z2))}for(let i=0;i<t.length;i++){const r=n[i],s=o[i];for(let a=i+1;a<t.length;a++){if(this.connMap?.areIdsConnected(t[i].connectionName,t[a].connectionName))continue;const c=n[a],l=o[a];let d=1;for(const t of this.availableZ){const e=r.get(t)??[],n=c.get(t)??[];for(const t of e)for(const e of n)d=Math.min(d,Oe(t[0],t[1],e[0],e[1])-this.traceWidth);for(const t of s)for(const e of n)d=Math.min(d,be(t,e[0],e[1])-this.traceWidth/2-this.viaDiameter/2);for(const t of l)for(const n of e)d=Math.min(d,be(t,n[0],n[1])-this.traceWidth/2-this.viaDiameter/2);for(const t of s)for(const e of l)d=Math.min(d,xe(t,e)-this.viaDiameter)}e.push(d)}}return e}insertCandidate(t){let e=0,n=this.candidates.length-1;for(;e<=n;){const o=Math.floor((e+n)/2);this.candidates[o].f<t.f?e=o+1:n=o-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,o)=>{const i=[];for(const[,n]of t){const t=n.start.z1!==n.end.z1,o=[];for(let n=0;n<=e;n++){const e=n%2!=0;t&&e?o.push(n):t||e||o.push(n)}i.push(o)}if(0===i.length)return[[]];let r=(t=>{if(!t||0===t.length)return[[]];let e=[[]];for(const n of t){const t=[];for(const o of e)for(const e of n)t.push([...o,e]);e=t}return e})(i).filter(t=>{for(let e=0;e<t.length;e++)if(t.reduce((t,e)=>t+e,0)<o)return!1;return!0});return r=r.filter(e=>{for(let n=0;n<t.length;n++){const[,o]=t[n];if(o.start.z1!==o.start.z2&&0===e[n])return!1}return!0}),r=r.filter(e=>{for(let n=0;n<t.length;n++){const[,o]=t[n];if(t[n][1].start.z1===t[n][1].start.z2)for(let i=n+1;i<t.length;i++){if(t[i][1].start.z1!==t[i][1].start.z2)continue;const[,r]=t[i];if(o.start.z1===o.end.z1&&r.start.z1===r.end.z1&&o.start.z1===r.start.z1&&fe(o.start,o.end,r.start,r.end)&&e[n]+e[i]<2)return!1}}return!0}),r=r.filter(t=>!(t.reduce((t,e)=>t+e,0)>n)),r})(e,this.SEGMENTS_PER_POLYLINE,this.maxViaCount,this.minViaCount),o=(t=>{const{bounds:e,portPairsEntries:n,viaCountVariants:o}=t,{centroids:i}=Nr(e,n.map(([t,e])=>e)),r=[];for(const t of o){const n=t.reduce((t,e)=>t+e,0);let o=i;if(i.length<n){o=[];const t=Math.ceil(Math.sqrt(n)),i=t;for(let n=0;n<t;n++)for(let r=0;r<i;r++)o.push({x:e.minX+(r+1)/(i+1)*(e.maxX-e.minX),y:e.minY+(n+1)/(t+1)*(e.maxY-e.minY)})}const s=wr(n,o.length);for(const e of s){const n=[];for(let t=0;t<e.length;t++)1===e[t]&&n.push(o[t]);r.push({viaPositions:n,viaCountVariant:t})}}return r})({portPairsEntries:e,viaCountVariants:n,bounds:this.bounds}),i=[];for(const{viaCountVariant:t,viaPositions:e}of o){const n=_r(e);for(const e of n)i.push({viaCountVariant:t,viaPositions:e})}for(const{viaPositions:t,viaCountVariant:n}of i){const o=[];let i=0;for(let r=0;r<e.length;r++){const[s,a]=e[r],c=n[r],l=t.slice(i,i+c),d=dr({start:a.start,end:a.end,segmentsPerPolyline:this.SEGMENTS_PER_POLYLINE,viaPositions:l,viaCount:c,availableZ:this.availableZ});i+=c,o.push({connectionName:s,start:a.start,end:a.end,mPoints:d})}if(yr(o,this.bounds))continue;const r=this.computeMinGapBtwPolyLines(o),s=this.computeH({minGaps:r,forces:[]}),a={polyLines:o,g:0,h:s,f:s,viaCount:n.reduce((t,e)=>t+e,0),minGaps:r};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,o=.02,i=.008,r=1e-6,s=Array.from({length:n},(t,n)=>Array.from({length:e[n].mPoints.length},()=>new Map)),a=(t,n,o,i,r)=>{if(n>0&&n<e[t].mPoints.length+1){const e=n-1,a=s[t][e],c=a.get(o)||{fx:0,fy:0};a.set(o,{fx:c.fx+i,fy:c.fy+r})}};for(let t=0;t<n;t++)for(let i=t+1;i<n;i++){const n=e[t],s=e[i],c=[n.start,...n.mPoints,n.end],l=[s.start,...s.mPoints,s.end],d=[],h=[];for(let t=0;t<c.length-1;t++)d.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&&h.push({point:t,layers:[t.z1,t.z2],index:e})});const u=[],p=[];for(let t=0;t<l.length-1;t++)u.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&&p.push({point:t,layers:[t.z1,t.z2],index:e})});for(const e of d)for(const n of u)if(e.layer===n.layer){if(Oe(e.p1,e.p2,n.p1,n.p2)<r)continue;const o={x:(e.p1.x+e.p2.x)/2,y:(e.p1.y+e.p2.y)/2},s={x:(n.p1.x+n.p2.x)/2,y:(n.p1.y+n.p2.y)/2},c=o.x-s.x,l=o.y-s.y,d=c*c+l*l;if(d>r){const o=Math.sqrt(d),s=(Math.exp(-6*o),`seg:${i}:${n.p1Idx}:${n.p2Idx}`),c=`seg:${t}:${e.p1Idx}:${e.p2Idx}`,l=(t,e,n,o,i,s,c)=>{const l=ze(t,n.p1,n.p2),d=t.x-l.x,h=t.y-l.y,u=d*d+h*h;if(u<=r)return;const p=Math.sqrt(u),m=.02*Math.exp(-6*p),g=d/p*m,f=h/p*m;a(o,e,s,g,f),a(i,n.p1Idx,c,-g/2,-f/2),a(i,n.p2Idx,c,-g/2,-f/2)};l(e.p1,e.p1Idx,n,t,i,s,c),l(e.p2,e.p2Idx,n,t,i,s,c),l(n.p1,n.p1Idx,e,i,t,c,s),l(n.p2,n.p2Idx,e,i,t,c,s)}}for(const e of h)for(const n of u)if(e.layers.includes(n.layer)){const s=ze(e.point,n.p1,n.p2),c=e.point.x-s.x,l=e.point.y-s.y,d=c*c+l*l;if(d>r){const s=Math.sqrt(d);let h=2,u=s;s<this.viaDiameter/2?(h*=4,u=Math.max(r,s)):u=Math.max(r,s-this.viaDiameter/2);const p=h*o*Math.exp(-6*u),m=c/s*p,g=l/s*p,f=`seg:${i}:${n.p1Idx}:${n.p2Idx}`;a(t,e.index,f,m,g);const y=`via:${t}:${e.index}`;a(i,n.p1Idx,y,-m/2,-g/2),a(i,n.p2Idx,y,-m/2,-g/2)}}for(const e of p)for(const n of d)if(e.layers.includes(n.layer)){const s=ze(e.point,n.p1,n.p2),c=e.point.x-s.x,l=e.point.y-s.y,d=c*c+l*l;if(d>r){const s=Math.sqrt(d);let h=2,u=s;s<this.viaDiameter/2?(h*=4,u=Math.max(r,s)):u=Math.max(r,s-this.viaDiameter/2);const p=h*o*Math.exp(-6*u),m=c/s*p,g=l/s*p,f=`seg:${t}:${n.p1Idx}:${n.p2Idx}`;a(i,e.index,f,m,g);const y=`via:${i}:${e.index}`;a(t,n.p1Idx,y,-m/2,-g/2),a(t,n.p2Idx,y,-m/2,-g/2)}}for(const e of h)for(const n of p){if(e.layers.filter(t=>n.layers.includes(t)).length>0){const s=e.point.x-n.point.x,c=e.point.y-n.point.y,l=s*s+c*c;if(l>r){const d=Math.sqrt(l);let h=2,u=d;d<this.viaDiameter?(h*=4,u=Math.max(r,d)):u=Math.max(r,d-this.viaDiameter);const p=h*o*Math.exp(-6*u),m=s/d*p,g=c/d*p,f=`via:${i}:${n.index}`,y=`via:${t}:${e.index}`;a(t,e.index,f,m,g),a(i,n.index,y,-m,-g)}}}}for(let t=0;t<n;t++){const n=e[t],i=[n.start,...n.mPoints,n.end],s=[];if(i.forEach((t,e)=>{t.z1!==t.z2&&s.push({point:t,layers:[t.z1,t.z2],index:e})}),!(s.length<2))for(let e=0;e<s.length;e++)for(let n=e+1;n<s.length;n++){const i=s[e],c=s[n],l=i.point.x-c.point.x,d=i.point.y-c.point.y,h=l*l+d*d;if(h>r){const e=Math.sqrt(h);let n=2,s=e;e<this.viaDiameter?(n*=4,s=Math.max(r,e)):s=Math.max(r,e-this.viaDiameter);const u=n*o*Math.exp(-6*s),p=l/e*u,m=d/e*u,g=`via:${t}:${c.index}`,f=`via:${t}:${i.index}`;a(t,i.index,g,p,m),a(t,c.index,f,-p,-m)}}}const c=e.map(t=>({...t,mPoints:t.mPoints.map(t=>({...t}))}));let l=!1;for(let t=0;t<n;t++)for(let e=0;e<c[t].mPoints.length;e++){const n=c[t].mPoints[e],o=s[t][e],a={fx:0,fy:0};for(const t of o.values())a.fx+=t.fx,a.fy+=t.fy;const d=n.z1!==n.z2;let h=n.x+a.fx,u=n.y+a.fy;if(d){const t=this.viaDiameter/2;let e=0,o=0;const r=this.viaDiameter/2+this.BOUNDARY_PADDING,s=this.bounds.minX+r,c=this.bounds.maxX-r,l=this.bounds.minY+r,d=this.bounds.maxY-r,p=s+t-n.x,m=n.x-(c-t),g=l+t-n.y,f=n.y-(d-t);p>0?e=i*(Math.exp(p/(2*this.obstacleMargin))-1):m>0&&(e=-.008*(Math.exp(m/(2*this.obstacleMargin))-1)),g>0?o=i*(Math.exp(g/(2*this.obstacleMargin))-1):f>0&&(o=-.008*(Math.exp(f/(2*this.obstacleMargin))-1)),a.fx+=e,a.fy+=o,h=n.x+a.fx,u=n.y+a.fy}else{const t=this.traceWidth/2+this.BOUNDARY_PADDING;h=Math.max(this.bounds.minX+t,Math.min(this.bounds.maxX-t,h)),u=Math.max(this.bounds.minY+t,Math.min(this.bounds.maxY-t,u))}Math.abs(a.fx)<r&&Math.abs(a.fy)<r||(Math.abs(n.x-h)>r||Math.abs(n.y-u)>r)&&(n.x=h,n.y=u,l=!0)}if(!l)return[];const d=this.computeMinGapBtwPolyLines(c),h=this.computeG(c,t),u=this.computeH({minGaps:d,forces:s});return[{polyLines:c,g:h,h:u,f:Math.round(5*h)/5+u,minGaps:d,forces:s,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,o)=>{const i=this.colorMap[n.connectionName]??"purple",r=[n.start,...n.mPoints,n.end];for(let e=0;e<r.length-1;e++){const o=r[e],s=r[e+1],a=o.z2,c=0===a,l=c?i:To(i,.5);t.lines.push({points:[o,s],strokeColor:l,strokeWidth:this.traceWidth,strokeDash:c?void 0:[.15,.15],label:`${n.connectionName} segment (z=${a})`})}r.forEach((s,a)=>{const c=s.z1!==s.z2,l=s.z1,d=a>0&&a<r.length-1;let h="",u="";if(d){const i=a-1,r=e.forces?.[o]?.[i];if(r&&r.size>0){const o={fx:0,fy:0};r.forEach((r,a)=>{if(o.fx+=r.fx,o.fy+=r.fy,Math.abs(r.fx)>1e-6||Math.abs(r.fy)>1e-6){const o=a.split(":"),c=o[0],l=parseInt(o[1],10),d=e.polyLines[l],h=this.colorMap[d.connectionName]??"gray",u=20,p={x:s.x+r.fx*u,y:s.y+r.fy*u};let m=d.connectionName;if("via"===c){m+=` Via ${parseInt(o[2],10)}`}else if("seg"===c){m+=` Seg ${parseInt(o[2],10)}-${parseInt(o[3],10)}`}t.lines.push({points:[s,p],strokeColor:h,strokeWidth:.02,strokeDash:"2,2",label:`Force by ${m} on ${n.connectionName} mPoint ${i}`})}}),(Math.abs(o.fx)>1e-6||Math.abs(o.fy)>1e-6)&&(u=`\nNet Force: (${o.fx.toFixed(3)}, ${o.fy.toFixed(3)})`)}}if(c)h=`Via (${n.connectionName} z=${s.z1} -> z=${s.z2})${u}`,t.circles.push({center:s,radius:this.viaDiameter/2,fill:To(i,.5),label:h});else if(d){const e=0===l?i:To(i,.5);h=`mPoint (${n.connectionName} z=${l})${u}`,t.circles.push({center:s,radius:this.cellSize/8,fill:e,label:h})}})}),t}_setSolvedRoutes(){if(!this.solved||!this.lastCandidate)return[];const t=[];for(const e of this.lastCandidate.polyLines){const n=[],o=[],i=[e.start,...e.mPoints,e.end];for(let t=0;t<i.length;t++){const e=i[t];n.push({x:e.x,y:e.y,z:e.z1}),e.z1!==e.z2&&(o.push({x:e.x,y:e.y}),n.push({x:e.x,y:e.y,z:e.z2}))}t.push({connectionName:e.connectionName,regionId:this.nodeWithPortPoints.capacityMeshNodeId,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:n,vias:o})}this.solvedRoutes=t}},Rr=class extends Tr{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 o=void 0===t.magForceApplied?1:10;for(let i=0;i<o;i++){const o=this.applyForcesToPolyLines(t.polyLines);if(n+=o.magForceApplied,e=o.lastStepMoved,!o.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,o=.02,i=.008,r=1e-6,s=Array.from({length:n},(e,n)=>Array.from({length:t[n].mPoints.length},()=>({fx:0,fy:0}))),a=(e,n,o,i)=>{if(n>0&&n<t[e].mPoints.length+1){const t=n-1;s[e][t].fx+=o,s[e][t].fy+=i}},c=(t,e,n,o,i)=>{const s=ze(t,n.p1,n.p2),c=t.x-s.x,l=t.y-s.y,d=c*c+l*l;if(d<=r)return;const h=Math.sqrt(d),u=.02*Math.exp(-6*h),p=c/h*u,m=l/h*u;a(o,e,p,m),a(i,n.p1Idx,-p/2,-m/2),a(i,n.p2Idx,-p/2,-m/2)};for(let e=0;e<n;e++)for(let i=e+1;i<n;i++){const n=t[e],s=t[i],l=[n.start,...n.mPoints,n.end],d=[s.start,...s.mPoints,s.end],h=[],u=[];for(let t=0;t<l.length-1;t++)h.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&&u.push({point:t,layers:[t.z1,t.z2],index:e})});const p=[],m=[];for(let t=0;t<d.length-1;t++)p.push({p1:d[t],p2:d[t+1],layer:d[t].z2,p1Idx:t,p2Idx:t+1});d.forEach((t,e)=>{t.z1!==t.z2&&m.push({point:t,layers:[t.z1,t.z2],index:e})});for(const t of h)for(const n of p)if(t.layer===n.layer){Oe(t.p1,t.p2,n.p1,n.p2);c(t.p1,t.p1Idx,n,e,i),c(t.p2,t.p2Idx,n,e,i),c(n.p1,n.p1Idx,t,i,e),c(n.p2,n.p2Idx,t,i,e)}for(const t of u)for(const n of p)if(t.layers.includes(n.layer)){const s=ze(t.point,n.p1,n.p2),c=t.point.x-s.x,l=t.point.y-s.y,d=c*c+l*l;if(d>r){const s=Math.sqrt(d);let h=2,u=s;s<this.viaDiameter/2?(h*=4,u=Math.max(r,s)):u=Math.max(r,s-this.viaDiameter/2);const p=h*o*Math.exp(-6*u),m=c/s*p,g=l/s*p;a(e,t.index,m,g),a(i,n.p1Idx,-m/2,-g/2),a(i,n.p2Idx,-m/2,-g/2)}}for(const t of m)for(const n of h)if(t.layers.includes(n.layer)){const s=ze(t.point,n.p1,n.p2),c=t.point.x-s.x,l=t.point.y-s.y,d=c*c+l*l;if(d>r){const s=Math.sqrt(d);let h=2,u=s;s<this.viaDiameter/2?(h*=4,u=Math.max(r,s)):u=Math.max(r,s-this.viaDiameter/2);const p=h*o*Math.exp(-6*u),m=c/s*p,g=l/s*p;a(i,t.index,m,g),a(e,n.p1Idx,-m/2,-g/2),a(e,n.p2Idx,-m/2,-g/2)}}for(const t of u)for(const n of m){if(t.layers.filter(t=>n.layers.includes(t)).length>0){const s=t.point.x-n.point.x,c=t.point.y-n.point.y,l=s*s+c*c;if(l>r){const d=Math.sqrt(l);let h=2,u=d;d<this.viaDiameter?(h*=4,u=Math.max(r,d)):u=Math.max(r,d-this.viaDiameter);const p=h*o*Math.exp(-6*u),m=s/d*p,g=c/d*p;a(e,t.index,m,g),a(i,n.index,-m,-g)}}}}for(let e=0;e<n;e++){const n=t[e],i=[n.start,...n.mPoints,n.end],s=[];if(i.forEach((t,e)=>{t.z1!==t.z2&&s.push({point:t,layers:[t.z1,t.z2],index:e})}),!(s.length<2))for(let t=0;t<s.length;t++)for(let n=t+1;n<s.length;n++){const i=s[t],c=s[n],l=i.point.x-c.point.x,d=i.point.y-c.point.y,h=l*l+d*d;if(h>r){const t=Math.sqrt(h);let n=2,s=t;t<this.viaDiameter?(n*=4,s=Math.max(r,t)):s=Math.max(r,t-this.viaDiameter);const u=n*o*Math.exp(-6*s),p=l/t*u,m=d/t*u;a(e,i.index,p,m),a(e,c.index,-p,-m)}}}let l=!1;for(let o=0;o<n;o++)for(let n=0;n<t[o].mPoints.length;n++){const a=t[o].mPoints[n],c=s[o][n],d=a.z1!==a.z2;let h=c.fx,u=c.fy,p=a.x+h,m=a.y+u;if(d){const t=this.viaDiameter/2;let e=0,n=0;const o=this.viaDiameter/2+this.BOUNDARY_PADDING,r=this.bounds.minX+o,s=this.bounds.maxX-o,c=this.bounds.minY+o,l=this.bounds.maxY-o,d=r+t-a.x,g=a.x-(s-t),f=c+t-a.y,y=a.y-(l-t);d>0?e=i*(Math.exp(d/(2*this.obstacleMargin))-1):g>0&&(e=-.008*(Math.exp(g/(2*this.obstacleMargin))-1)),f>0?n=i*(Math.exp(f/(2*this.obstacleMargin))-1):y>0&&(n=-.008*(Math.exp(y/(2*this.obstacleMargin))-1)),h+=e,u+=n,p=a.x+h,m=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)),m=Math.max(this.bounds.minY+t,Math.min(this.bounds.maxY-t,m))}if(Math.abs(h)<r&&Math.abs(u)<r)continue;e+=Math.sqrt(h*h+u*u),(Math.abs(a.x-p)>r||Math.abs(a.y-m)>r)&&(a.x=p,a.y=m,l=!0)}return{lastStepMoved:l,magForceApplied:e}}},Er=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 Ar=class extends Rr{getSolverName(){return"MultiHeadPolyLineIntraNodeSolver3"}constructor(t){super(t),this.MAX_ITERATIONS=1e3}createInitialCandidateFromSeed(t){const e=new ar({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 o=0;for(const[t,i]of e.completedPaths.entries()){if(i.length<2){console.warn(`Skipping connection "${t}" due to insufficient points (${i.length}) in ViaPossibilitiesSolver2 path.`);continue}const e=i[0],r=i[i.length-1],s=i.slice(1,-1),a=[];let c=0,l=e.z;for(let t=0;t<s.length;t++){const e=s[t],n=t+1<s.length?s[t+1]:r,o=l,i=t+1<s.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:o,z2:i}),o!==i?(c++,t++,l=i):l=e.z}o+=c;const d=this.SEGMENTS_PER_POLYLINE;let h=a.length+1;for(;h<d;){let n=-1,o=-1,i=null,s=null;const c=[{...e,z1:e.z,z2:e.z,connectionName:t},...a,{...r,z1:r.z,z2:r.z,connectionName:t}];for(let t=0;t<c.length-1;t++){const e=c[t],r=c[t+1];if(e.x===r.x&&e.y===r.y)continue;const a=xe(e,r);a>n&&(n=a,o=t,i=e,s=r)}if(-1===o||!i||!s){console.warn(`Could not find longest segment for ${t} while trying to reach ${d} segments.`);break}const l=(i.x+s.x)/2,u=(i.y+s.y)/2,p=i.z2,m={x:l,y:u,z1:p,z2:p};a.splice(o,0,m),h++}n.push({connectionName:t,start:{...e,z1:e.z,z2:e.z},end:{...r,z1:r.z,z2:r.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 i=this.computeMinGapBtwPolyLines(n),r=this.computeH({minGaps:i,forces:[]}),s={polyLines:n,g:0,h:r,f:0+r,viaCount:o,minGaps:i};return s.g=this.computeG(n,s),s.f=s.g+s.h,s}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 o=Er(t.polyLines);e.has(o)||(e.add(o),this.candidates.push(t))}this.candidates.sort((t,e)=>t.f-e.f)}},Or=t=>t.portPointId??`${t.connectionName}:${t.x}:${t.y}:${t.z}`,kr=(t,e)=>{const[n,o]=t;if(n===o)return!1;const i=(t=>{const[e,n]=t,o=Or(e),i=Or(n);return o<i?`${o}|${i}`:`${i}|${o}`})(t);return!e.seenPairKeys.has(i)&&(e.seenPairKeys.add(i),e.pairs.push(t),!0)},Lr=(t,e)=>{for(let n=0;n<t.length-1;n++)kr([t[n],t[n+1]],e)},Dr=t=>{const e=[],n=new Set,o=new Map(t.filter(t=>"string"==typeof t.portPointId).map(t=>[t.portPointId,t])),i={pairs:e,seenPairKeys:n};for(const e of t){if(e.prevPortPointId){const t=o.get(e.prevPortPointId);t&&t.connectionName===e.connectionName&&kr([t,e],i)}if(e.nextPortPointId){const t=o.get(e.nextPortPointId);t&&t.connectionName===e.connectionName&&kr([e,t],i)}}if(0===e.length)return Lr(t,i),e;const r=new Set(e.flatMap(([t,e])=>[t.portPointId,e.portPointId]).filter(Boolean)),s=t.filter(t=>!t.portPointId||!r.has(t.portPointId));return Lr(s,i),e},zr=1e-6,Fr=.02,Br=t=>`${t.x.toFixed(6)},${t.y.toFixed(6)}`,jr=(t,e)=>Math.abs(t.x-e.x)<zr&&Math.abs(t.y-e.y)<zr,$r=t=>({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}),Yr=(t,e)=>t.x>=e.minX-zr&&t.x<=e.maxX+zr&&t.y>=e.minY-zr&&t.y<=e.maxY+zr,Xr=(t,e,n)=>{for(const o of n)if(!jr(o,t)&&!jr(o,e)&&be(o,t,e)<1e-4)return!0;return!1},Vr=(t,e,n)=>{for(const o of n)if(!(jr(t,o.A)||jr(t,o.B)||jr(e,o.A)||jr(e,o.B))&&fe(t,e,o.A,o.B))return!0;return!1},Wr=(t,e)=>{const n=[];for(const o of t){const t=o.rootConnectionName??o.connectionName;if(t!==e)for(let e=0;e<o.route.length-1;e++){const i=o.route[e],r=o.route[e+1];i.z===r.z&&n.push({A:{x:i.x,y:i.y},B:{x:r.x,y:r.y},rootConnectionName:t})}}return n},Hr=(t,e)=>t.portPoints.filter(t=>(t.rootConnectionName??t.connectionName)!==e).map(t=>({x:t.x,y:t.y}));function*Gr(t,e=t.length){if(e<=1)yield t.slice();else for(let n=0;n<e;n++)[t[n],t[e-1]]=[t[e-1],t[n]],yield*Gr(t,e-1),[t[n],t[e-1]]=[t[e-1],t[n]]}var Ur=({A:t,B:e,bounds:n,obstacleSegments:o,foreignPorts:i})=>{const r=[{x:t.x,y:t.y},{x:e.x,y:e.y},{x:(n.minX+n.maxX)/2,y:(n.minY+n.maxY)/2},{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}],s=[...o.flatMap(t=>[t.A,t.B]),...i,{x:t.x,y:t.y},{x:e.x,y:e.y}];for(const t of s)for(const e of[-.02,0,Fr])for(const o of[-.02,0,Fr]){const i={x:t.x+e,y:t.y+o};Yr(i,n)&&r.push(i)}const a=(t=>{const e=new Set,n=[];for(const o of t){const t=Br(o);e.has(t)||(e.add(t),n.push(o))}return n})(r),c=Br(t),l=Br(e),d=new Map(a.map(t=>[Br(t),t])),h=new Map,u=new Map,p=new Set;for(const t of a){const e=Br(t);h.set(e,e===c?0:1/0),u.set(e,null),p.add(e)}for(;p.size>0;){let t=null,e=1/0;for(const n of p){const o=h.get(n)??1/0;(o<e-zr||Math.abs(o-e)<=zr&&(null===t||n<t))&&(e=o,t=n)}if(!t||e===1/0)break;if(p.delete(t),t===l)break;const n=d.get(t);for(const r of p){const s=d.get(r);if(jr(n,s))continue;if(Vr(n,s,o))continue;if(Xr(n,s,i))continue;const a=e+xe(n,s),c=h.get(r)??1/0,l=u.get(r);(a<c-zr||Math.abs(a-c)<=zr&&(null==l||t<l))&&(h.set(r,a),u.set(r,t))}}if((h.get(l)??1/0)===1/0)return null;const m=[];let g=l;for(;g;)m.push(d.get(g)),g=u.get(g)??null;return m.reverse(),m.map(e=>({x:e.x,y:e.y,z:t.z}))},Zr=class extends si{getSolverName(){return"SingleLayerNoDifferentRootIntersectionsIntraNodeSolver"}nodeWithPortPoints;traceWidth;viaDiameter;solvedRoutes=[];constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.traceWidth=t.traceWidth??.15,this.viaDiameter=t.viaDiameter??.3,this.MAX_ITERATIONS=1}static isApplicable(t){const e=(t=>t.availableZ?.length?[...new Set(t.availableZ)].sort((t,e)=>t-e):[...new Set(t.portPoints.map(t=>t.z??0))].sort((t,e)=>t-e))(t);if(1!==e.length)return!1;if(t.portPoints.length>12)return!1;const n=$r(t);if(t.portPoints.some(t=>null===((t,e)=>Math.abs(t.y-e.minY)<.001?"top":Math.abs(t.x-e.maxX)<.001?"right":Math.abs(t.y-e.maxY)<.001?"bottom":Math.abs(t.x-e.minX)<.001?"left":null)(t,n)))return!1;const o=new Map;for(const e of t.portPoints)o.set(e.connectionName,(o.get(e.connectionName)??0)+1);return[...o.values()].some(t=>t>2)}buildTaskGroups(){const t=new Map;for(const e of this.nodeWithPortPoints.portPoints){const n=t.get(e.connectionName)??[];n.push(e),t.set(e.connectionName,n)}return t}trySolveNode(){const t=$r(this.nodeWithPortPoints),e=this.buildTaskGroups(),n=Array.from(e.entries()).flatMap(([t,e])=>Dr(e).map(([e,n])=>({connectionName:t,rootConnectionName:e.rootConnectionName??n.rootConnectionName??t,A:e,B:n}))),o=n.length<=6?Gr(n.slice()):[n];for(const e of o){const n=[];let o=!1;for(const i of e){const e=Wr(n,i.rootConnectionName),r=Hr(this.nodeWithPortPoints,i.rootConnectionName),s=Ur({A:i.A,B:i.B,bounds:t,obstacleSegments:e,foreignPorts:r});if(!s||s.length<2){o=!0;break}n.push({connectionName:i.connectionName,rootConnectionName:i.rootConnectionName,regionId:this.nodeWithPortPoints.capacityMeshNodeId,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:s,vias:[]})}if(!o)return n}return null}_step(){const t=this.trySolveNode();if(!t)return this.failed=!0,void(this.error="Failed to find a single-layer route set without different-root intersections");this.solvedRoutes=t,this.stats={routeCount:t.length,distinctRoots:new Set(t.map(t=>t.rootConnectionName??t.connectionName)).size},this.solved=!0}visualize(){return{lines:this.solvedRoutes.map(t=>({points:t.route,strokeColor:"cyan",strokeWidth:t.traceThickness,label:`${t.connectionName}\nroot: ${t.rootConnectionName??t.connectionName}`})),points:this.nodeWithPortPoints.portPoints.map(t=>({x:t.x,y:t.y,color:"blue",label:`${t.connectionName}\nroot: ${t.rootConnectionName??t.connectionName}`})),rects:[],circles:[]}}},qr=t=>t.min<=t.max?Ae(t.value,t.min,t.max):t.value,Jr=class extends si{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,o={x:qr({value:(e.A.x+e.B.x)/2,min:this.bounds.minX+n,max:this.bounds.maxX-n}),y:qr({value:(e.A.y+e.B.y)/2,min:this.bounds.minY+n,max:this.bounds.maxY-n})};this.solvedRoutes.push(this.createTransitionRoute({start:e.A,end:e.B,via:o,connectionName: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,o]of n.entries())for(const[n,i]of Dr(o))t.push({A:{...n},B:{...i},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){const{start:e,end:n,via:o,connectionName:i}=t,r=[{x:e.x,y:e.y,z:e.z},{x:o.x,y:o.y,z:e.z},{x:o.x,y:o.y,z:n.z},{x:n.x,y:n.y,z:n.z}];return{connectionName:i,regionId:this.nodeWithPortPoints.capacityMeshNodeId,route:r,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[o]}}_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],o="rgba(0, 255, 0, 0.75)";for(let e=0;e<n.route.length-1;e++){const i=n.route[e],r=n.route[e+1];t.lines.push({points:[i,r],strokeColor:o,strokeDash:i.z!==n.route[0].z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${i.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}},Kr=(t,e=2)=>{const n=Array.from({length:e},(t,e)=>e);return t.map(t=>{const o=Lo(t.__zLayers??(t.layers?Do(t.layers,e):void 0)??n,e);return{...t,__zLayers:o.length>0?o:n}})},Qr=1e-6,ts=t=>{const{point:e,obstacle:n}=t,o=n.width/2+Qr,i=n.height/2+Qr;return Math.abs(e.x-n.center.x)<=o&&Math.abs(e.y-n.center.y)<=i},es=class t extends si{getSolverName(){return"SingleTransitionThroughObstacleIntraNodeSolver"}nodeWithPortPoints;routes;obstacles;viaDiameter;traceThickness;connMap;solvedRoutes=[];constructor(t){if(super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.obstacles=Kr(t.obstacles??[],t.layerCount??2),this.connMap=t.connMap,this.viaDiameter=t.viaDiameter??.3,this.traceThickness=t.traceThickness??.15,this.routes=this.extractRoutesFromNode(),0===this.routes.length)return this.failed=!0,void(this.error="Expected at least 1 route");if(this.routes.some(t=>void 0===t.A.z||void 0===t.B.z))return this.failed=!0,void(this.error="Route points should have predefined z values");if(!this.routes.some(t=>t.A.z!==t.B.z))return this.failed=!0,void(this.error="No route transitions through an obstacle");const e=this.routes.map(t=>this.getContainingThroughObstacle(t));if(e.some(t=>!t))return this.failed=!0,void(this.error="No same-net multilayer obstacle contains every route");this.solvedRoutes.push(...this.routes.map((t,n)=>({connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,regionId:this.nodeWithPortPoints.capacityMeshNodeId,route:[{x:t.A.x,y:t.A.y,z:t.A.z,...t.A.z!==t.B.z?{toNextSegmentType:"through_obstacle",...e[n].circuitJsonMetadata?{toNextSegmentCircuitJsonMetadata:e[n].circuitJsonMetadata}:{}}:{}},{x:t.B.x,y:t.B.y,z:t.B.z}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]}))),this.solved=!0}static isApplicable(e){return new t(e).solved}extractRoutesFromNode(){const t=[],e=new Map;for(const t of this.nodeWithPortPoints.portPoints){const{connectionName:n}=t;e.has(n)||e.set(n,[]),e.get(n).push(t)}for(const[n,o]of e.entries())for(const[e,i]of Dr(o))t.push({A:{...e},B:{...i},connectionName:n,rootConnectionName:e.rootConnectionName??i.rootConnectionName});return t}getContainingThroughObstacle(t){const e=t.A.z,n=t.B.z;return void 0===e||void 0===n?null:this.obstacles.find(o=>{return!(o.__zLayers.length<2)&&(!(!o.__zLayers.includes(e)||!o.__zLayers.includes(n))&&(!!(i={obstacle:o,connectionName:t.connectionName,connMap:this.connMap}).obstacle.connectedTo.some(t=>t===i.connectionName||(i.connMap?.areIdsConnected(i.connectionName,t)??!1))&&(ts({point:t.A,obstacle:o})&&ts({point:t.B,obstacle:o}))));var i})??null}_step(){this.solved=!0}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.obstacles)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(128, 0, 128, 0.2)",stroke:"rgba(128, 0, 128, 0.6)",label:`through obstacle candidate\nz: ${e.__zLayers.join(",")}`});for(const e of this.solvedRoutes){t.lines.push({points:e.route,strokeColor:"rgba(0, 180, 0, 0.8)",strokeDash:"4, 3",strokeWidth:e.traceThickness,label:`${e.connectionName} through_obstacle`});for(const n of e.route)t.points.push({x:n.x,y:n.y,color:"green",label:`${e.connectionName}\nz: ${n.z}`})}return t}},ns=1e-6,os=({value:t,min:e,max:n})=>t>=e&&t<=n,is=({value:t,target:e,epsilon:n})=>Math.abs(t-e)<=n,rs=({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";if(t.x<e.minX-n||t.x>e.maxX+n||t.y<e.minY-n||t.y>e.maxY+n)return"outside";const o=is({value:t.x,target:e.minX,epsilon:n}),i=is({value:t.x,target:e.maxX,epsilon:n}),r=is({value:t.y,target:e.minY,epsilon:n}),s=is({value:t.y,target:e.maxY,epsilon:n}),a=o||i,c=r||s;if(a&&c)return"on-boundary";const l=os({value:t.y,min:e.minY,max:e.maxY}),d=os({value:t.x,min:e.minX,max:e.maxX});return a&&l||c&&d?"on-boundary":"inside"};function ss(t,e,n,o,i){const r={x:(t.x+e.x+n.x)/3,y:(t.y+e.y+n.y)/3},s=(t,e)=>Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2),a=r=>{const a=s(r,t),c=s(r,e),l=s(r,n),d=r.x>=i.minX&&r.x<=i.maxX&&r.y>=i.minY&&r.y<=i.maxY;return a>=o&&c>=o&&l>=o&&d};if(a(r))return r;const c=(t,e,n)=>{const o=t.x-e.x,i=t.y-e.y,r=Math.sqrt(o*o+i*i);return r<1e-10?{x:e.x+n,y:e.y}:{x:e.x+o/r*n,y:e.y+i/r*n}},l=(t,e,n)=>{const o=e.x-t.x,i=e.y-t.y,r=Math.sqrt(o*o+i*i);if(r>2*n-1e-10||r<1e-10)return[];const a=r*r/(2*r),c=Math.sqrt(Math.max(0,n*n-a*a)),l=t.x+o*a/r,d=t.y+i*a/r,h={x:l+c*i/r,y:d-c*o/r},u={x:l-c*i/r,y:d+c*o/r},p=[],m=1e-6;return Math.abs(s(h,t)-n)<m&&Math.abs(s(h,e)-n)<m&&p.push(h),Math.abs(s(u,t)-n)<m&&Math.abs(s(u,e)-n)<m&&p.push(u),p},d=[c(r,t,o),c(r,e,o),c(r,n,o),...l(t,e,o),...l(e,n,o),...l(n,t,o)],h=d.filter(a);if(h.length>0){const t=h.filter(t=>!(t=>{const e=1e-6;return Math.abs(t.x-i.minX)<e||Math.abs(t.x-i.maxX)<e||Math.abs(t.y-i.minY)<e||Math.abs(t.y-i.maxY)<e})(t));if(t.length>0)return t.sort((t,e)=>s(t,r)-s(e,r)),t[0]}let u=null,p=1/0;for(let t=i.minX+1;t<i.maxX;t+=5)for(let e=i.minY+1;e<i.maxY;e+=5){const n={x:t,y:e};if(a(n)){const t=s(n,r);t<p&&(p=t,u=n)}}if(null!==u)return u;const m=[];for(let t=0;t<=100;t++){const e=t/100;m.push({x:i.minX+e*(i.maxX-i.minX),y:i.minY}),m.push({x:i.maxX,y:i.minY+e*(i.maxY-i.minY)}),m.push({x:i.maxX-e*(i.maxX-i.minX),y:i.maxY}),m.push({x:i.minX,y:i.maxY-e*(i.maxY-i.minY)})}const g=m.filter(a);if(g.length>0)return g.sort((t,e)=>s(t,r)-s(e,r)),g[0];let f=1/0,y={x:i.minX,y:i.minY};for(const r of[...d,...m])if(r.x>=i.minX&&r.x<=i.maxX&&r.y>=i.minY&&r.y<=i.maxY){const i=Math.max(0,o-s(r,t))+Math.max(0,o-s(r,e))+Math.max(0,o-s(r,n));i<f&&(f=i,y=r)}return y}function as(t,e,n){const o=cs(e,t,n.center,n.radius),i=cs(t,e,n.center,n.radius),r=ls(o,e),s=ls(t,i),a=1e-6;let c;if(r>a&&s>a){c={x:(o.x+i.x)/2,y:(o.y+i.y)/2};const r=ls(o,c),s=ls(i,c);if(Math.abs(r-s)>.5*Math.min(r,s)){const n=ls(t,o),r=ls(e,i),s=n+r;if(s>a){const t=r/s,e=n/s;c={x:o.x*t+i.x*e,y:o.y*t+i.y*e}}}const l=ls(c,n.center);if(l<1.05*n.radius){const t={x:(c.x-n.center.x)/l,y:(c.y-n.center.y)/l};c={x:n.center.x+t.x*n.radius*1.2,y:n.center.y+t.y*n.radius*1.2}}}else{const o={x:(t.x+e.x)/2,y:(t.y+e.y)/2},i=ls(o,n.center);if(i<1.1*n.radius){const t={x:(o.x-n.center.x)/i,y:(o.y-n.center.y)/i};c={x:n.center.x+t.x*n.radius*1.2,y:n.center.y+t.y*n.radius*1.2}}else c=o}return{B:o,D:i,E:c}}function cs(t,e,n,o){const i=[n.x-t.x,n.y-t.y],r=Math.sqrt(i[0]*i[0]+i[1]*i[1]);if(r<=o){if(r<1e-8){const i=[e.x-t.x,e.y-t.y],r=Math.sqrt(i[0]*i[0]+i[1]*i[1]);return r<1e-8?{x:n.x+o,y:n.y}:{x:n.x+i[0]/r*o,y:n.y+i[1]/r*o}}const s=[i[0]/r,i[1]/r];return{x:n.x-s[0]*o,y:n.y-s[1]*o}}const s=[e.x-t.x,e.y-t.y],a=Math.sqrt(r*r-o*o),c=[i[0]/r,i[1]/r],l=[-c[1],c[0]],d=[c[1],-c[0]],h=s[0]*l[0]+s[1]*l[1]>s[0]*d[0]+s[1]*d[1]?l:d,u=o/r,p=a/r,m=[c[0]*p+h[0]*u,c[1]*p+h[1]*u];return{x:t.x+a*m[0],y:t.y+a*m[1]}}function ls(t,e){const n=e.x-t.x,o=e.y-t.y;return Math.sqrt(n*n+o*o)}var ds=1e-9;function hs(t,e,n,o="cw"){const i=us(t,n),r=us(e,n);return Math.abs(r-i)<ds?{left:0,top:0,right:0,bottom:0}:function(t,e,n,o){const i=n.maxX-n.minX,r=n.maxY-n.minY;if(i<ds&&r<ds)return{left:0,top:0,right:0,bottom:0};const s=2*(i+r);if(s<ds)return{left:0,top:0,right:0,bottom:0};const a=i/s*(2*Math.PI),c=(i+r)/s*(2*Math.PI),l=(i+i+r)/s*(2*Math.PI),d=2*Math.PI,h=[{name:"top",start:0,end:a,length:i},{name:"right",start:a,end:c,length:r},{name:"bottom",start:c,end:l,length:i},{name:"left",start:l,end:d,length:r}],u={left:0,top:0,right:0,bottom:0},p=(t,e,n,o,i)=>{const r=e>2*Math.PI-ds?2*Math.PI:e;if(r<=t+ds)return 0;if(i){const e=Math.max(t,n),i=Math.min(r,2*Math.PI),s=Math.max(0,i-e),a=Math.max(t,0),c=Math.min(r,o);return s+Math.max(0,c-a)}{const e=Math.max(t,n),i=Math.min(r,o);return Math.max(0,i-e)}};for(const n of h){const i=n.end-n.start;if(i<ds||n.length<ds)continue;let r=0;if("cw"===o){const o=t>e+ds;r=p(n.start,n.end,t,e,o)}else{const o=e>t+ds;r=p(n.start,n.end,e,t,o)}if(r>ds){const t=r/i;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}(i,r,n,o)}function us(t,e){const n=e.maxX-e.minX,o=e.maxY-e.minY;if(n<ds&&o<ds)return 0;const i=2*(n+o);if(i<ds)return 0;let r=0;if(Math.abs(t.y-e.maxY)<=ns&&t.x>=e.minX-ns&&t.x<=e.maxX+ns)r=Math.max(0,Math.min(n,t.x-e.minX));else if(Math.abs(t.x-e.maxX)<=ns&&t.y>=e.minY-ns&&t.y<=e.maxY+ns)r=n+Math.max(0,Math.min(o,e.maxY-t.y));else if(Math.abs(t.y-e.minY)<=ns&&t.x>=e.minX-ns&&t.x<=e.maxX+ns)r=n+o+Math.max(0,Math.min(n,e.maxX-t.x));else{if(!(Math.abs(t.x-e.minX)<=ns&&t.y>=e.minY-ns&&t.y<=e.maxY+ns))throw new Error(`Point (${t.x}, ${t.y}) does not lie on the boundary defined by ${JSON.stringify(e)}`);r=n+o+n+Math.max(0,Math.min(o,t.y-e.minY))}return r=Math.max(0,Math.min(i,r)),i>ds?r/i*(2*Math.PI):0}function ps(t,e,n,o){return function({angleA:t,angleB:e,angleC:n}){const o=Math.cos(t),i=Math.sin(t),r=Math.cos(e),s=Math.sin(e),a=Math.cos(n);return(r-o)*(Math.sin(n)-i)-(s-i)*(a-o)<0?"ccw":"cw"}({angleA:us(t,o),angleB:us(e,o),angleC:us(n,o)})}var ms=class extends si{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);this.routes=this.routes.map(t=>({...t,A:this.snapPortPointToBounds(t.A),B:this.snapPortPointToBounds(t.B)}));const[n,o]=this.routes,i=n.A.z!==n.B.z,r=o.A.z!==o.B.z;return i&&r||!i&&!r?(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,o]of n.entries())2===o.length&&t.push({A:{...o[0],z:o[0].z??0},B:{...o[1],z:o[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){return rs({point:t,bounds:this.bounds})}snapPortPointToBounds(t){const e=Ae(t.x,this.bounds.minX,this.bounds.maxX),n=Ae(t.y,this.bounds.minY,this.bounds.maxY);return[{distance:Math.abs(t.y-this.bounds.maxY),point:{...t,x:e,y:this.bounds.maxY}},{distance:Math.abs(t.x-this.bounds.maxX),point:{...t,x:this.bounds.maxX,y:n}},{distance:Math.abs(t.y-this.bounds.minY),point:{...t,x:e,y:this.bounds.minY}},{distance:Math.abs(t.x-this.bounds.minX),point:{...t,x:this.bounds.minX,y:n}}].reduce((t,e)=>e.distance<t.distance?e:t).point}doRoutesCross(t,e){return fe(t.A,t.B,e.A,e.B)}calculateViaPosition(t,e){const n=e.A.z,o=t.A.z!==n?t.A:t.B,i=2*this.obstacleMargin+this.viaDiameter/2+this.traceThickness,r=this.obstacleMargin+this.viaDiameter/2,s=e.A,a=o,c=e.B,l=ps(s,a,c,this.bounds),d=function(t,e,n,o,i){const r=hs(t,e,o,i),s=hs(e,n,o,i),a={left:Math.min(1,r.left+s.left),top:Math.min(1,r.top+s.top),right:Math.min(1,r.right+s.right),bottom:Math.min(1,r.bottom+s.bottom)};for(const t in a)Math.abs(a[t])<ds&&(a[t]=0);return a}(s,a,c,this.bounds,l),h={minX:this.bounds.minX+(d.left>.5?i:r),minY:this.bounds.minY+(d.bottom>.5?i:r),maxX:this.bounds.maxX-(d.right>.5?i:r),maxY:this.bounds.maxY-(d.top>.5?i:r)};return h.maxY<h.minY&&(h.minY=(h.minY+h.maxY)/2,h.maxY=h.minY),h.maxX<h.minX&&(h.minX=(h.minX+h.maxX)/2,h.maxX=h.minX),ss(s,a,c,i,h)}createTransitionRoute(t,e,n,o){const i=[{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}];return{connectionName:o,regionId:this.nodeWithPortPoints.capacityMeshNodeId,route:i,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[n]}}createFlatRoute(t,e,n,o,i,r){o.z,t.z;const s=this.viaDiameter/2+this.traceThickness/2+this.obstacleMargin,a=((t,e,n,o)=>{const i=n.x-t.x,r=n.y-t.y;return((t,e)=>({x:(t.x+e.x)/2,y:(t.y+e.y)/2}))({x:t.x+i*e,y:t.y+r*e},{x:n.x-i*o,y:n.y-r*o})})(n,this.viaDiameter,o.z!==t.z?o:i,this.traceThickness),c={center:{x:n.x,y:n.y},radius:s},l=as(t,a,c).E,d=as(a,e,c).E,h=as(t,l,c).E,u=as(l,a,c).E,p=as(a,d,c).E,m=as(d,e,c).E,g=as(u,p,c).E;return{connectionName:r,regionId:this.nodeWithPortPoints.capacityMeshNodeId,route:[{x:t.x,y:t.y,z:t.z??0},{x:h.x,y:h.y,z:t.z??0},{x:l.x,y:l.y,z:t.z??0},{x:u.x,y:u.y,z:t.z??0},{x:g.x,y:g.y,z:t.z??0},{x:p.x,y:p.y,z:t.z??0},{x:d.x,y:d.y,z:t.z??0},{x:m.x,y:m.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,o=n?t:e,i=n?e:t,r=this.calculateViaPosition(o,i);if(!r)return!1;this.debugViaPositions.push({via:r});const s=this.createTransitionRoute(o.A,o.B,r,o.connectionName),a=this.createFlatRoute(i.A,i.B,r,o.A,o.B,i.connectionName);return this.solvedRoutes.push(s,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 o=this.viaDiameter/2+this.obstacleMargin;t.circles.push({center:n,radius:o,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],o=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 i=n.route[e],r=n.route[e+1];t.lines.push({points:[i,r],strokeColor:o,strokeDash:i.z!==n.route[0].z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${i.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}};function gs({A:t,B:e,C:n,D:o,E:i,F:r,radius:s,margin:a,subdivisions:c=0}){const l=(t,e)=>({x:(t.x+e.x)/2,y:(t.y+e.y)/2}),d=(t,e,n)=>{const o=e.x-t.x,i=e.y-t.y,r=Math.sqrt(o*o+i*i),s=o/r,a=i/r,c=-a,l=s;return{midpoint:{x:(t.x+e.x)/2,y:(t.y+e.y)/2},A_Opp:{x:t.x-s*n,y:t.y-a*n},A_Right:{x:t.x+c*n,y:t.y+l*n},A_Left:{x:t.x-c*n,y:t.y-l*n},B_Opp:{x:e.x+s*n,y:e.y+a*n},B_Right:{x:e.x+c*n,y:e.y+l*n},B_Left:{x:e.x-c*n,y:e.y-l*n}}},h=(t,e)=>{const n=xe(t,e.start),o=xe(t,e.end),i=xe(e.start,e.end);return Math.abs(n+o-i)<1e-4},u=(t,e)=>{const{start:n,end:o}=t,{start:i,end:r}=e;if(h(n,e)||h(o,e)||h(i,t)||h(r,t))return!0;const s=o.x-n.x,a=o.y-n.y,c=r.x-i.x,l=r.y-i.y,d=s*l-a*c;if(Math.abs(d)<1e-4)return!1;const u=i.x-n.x,p=i.y-n.y,m=(u*l-p*c)/d,g=(u*a-p*s)/d;return m>0&&m<1&&g>0&&g<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 o=[];for(let t=0;t<e.length-1;t++)o.push({start:e[t],end:e[t+1]});for(const t of n)for(const e of o)if(u(t,e))return!0;return!1},m=t=>{let e=0;for(let n=1;n<t.length;n++){const o=t[n].x-t[n-1].x,i=t[n].y-t[n-1].y;e+=Math.sqrt(o*o+i*i)}return e},g=(t,e)=>{const{start:n,end:o}=t,i=o.x-n.x,r=o.y-n.y,s=i*i+r*r;if(0===s)return{...n,t:0};const a=Math.max(0,Math.min(1,((e.x-n.x)*i+(e.y-n.y)*r)/s));return{x:n.x+a*i,y:n.y+a*r,t:a}},f=(e,n,o)=>{const i=g(e,n);if(xe(i,n)>=o)return i;const r=i.x-n.x,s=i.y-n.y,a=Math.sqrt(r*r+s*s);if(0===a){const r=e.end.x-e.start.x,s=e.end.y-e.start.y,a=Math.sqrt(r*r+s*s);return{x:n.x+o*r/a,y:n.y+o*s/a,t:i.t,isSpecial:!0,specialType:n===t?"A":"B"}}return{x:n.x+o*r/a,y:n.y+o*s/a,t:i.t,isSpecial:!0,specialType:n===t?"A":"B"}},y=d(t,e,s),_=d(t,e,s+a),b=(t,e,n,o,i)=>{const r=t.points;if(r.length<2)return r;const a=n+o,c=[r[0]];for(let t=0;t<r.length-1;t++){const n={start:r[t],end:r[t+1]};if(be(e,n.start,n.end)<a){const t=g(n,e),o=t.x-e.x,i=t.y-e.y,r=Math.sqrt(o*o+i*i);let l=null;if(r>1e-6)l={x:e.x+a*o/r,y:e.y+a*i/r};else{const t=n.end.x-n.start.x,o=n.end.y-n.start.y,i=Math.sqrt(t*t+o*o);i>1e-6&&(l={x:e.x+a*t/i,y:e.y+a*o/i})}l&&xe(n.start,l)>s/10&&c.push(l)}xe(c[c.length-1],n.end)>s/10&&c.push(n.end)}if(c.length>1){const t=[c[0]];for(let e=1;e<c.length;e++)xe(t[t.length-1],c[e])>s/10&&t.push(c[e]);return t}return c},x=(()=>{const t=[[n,y.B_Left,y.B_Opp,y.B_Right,l(y.midpoint,l(y.B_Right,y.A_Right)),l(y.midpoint,l(y.A_Left,y.B_Left)),y.A_Left,y.A_Opp,y.A_Right,o],[n,y.B_Right,y.B_Opp,y.B_Left,l(y.midpoint,l(y.A_Left,y.B_Left)),l(y.midpoint,l(y.A_Right,y.B_Right)),y.A_Right,y.A_Opp,y.A_Left,o],[o,y.B_Left,y.B_Opp,y.B_Right,l(y.midpoint,l(y.A_Right,y.B_Right)),l(y.midpoint,l(y.A_Left,y.B_Left)),y.A_Left,y.A_Opp,y.A_Right,n],[o,y.B_Right,y.B_Opp,y.B_Left,l(y.midpoint,l(y.A_Left,y.B_Left)),l(y.midpoint,l(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 o=t[n],i={start:o[0],end:o[1]},r={start:o[o.length-2],end:o[o.length-1]},s={start:o[3],end:o[4]};u(i,r)||u(i,s)||u(r,s)||e.push({index:n+1,path:o,length:m(o)})}if(0===e.length)return{index:0,path:[]};const i=e.sort((t,e)=>t.length-e.length)[0],r=[...i.path],s=r[0],a=xe(s,r[2]),c=xe(s,r[3]),d=a<c?2:3;(a<xe(s,r[1])||c<xe(s,r[1]))&&r.splice(1,d-1);const h=r[r.length-1],p=xe(h,r[r.length-3]),g=xe(h,r[r.length-4]),f=p<g?r.length-3:r.length-4;return(p<xe(h,r[r.length-2])||g<xe(h,r[r.length-2]))&&r.splice(f+1,r.length-f-2),{index:i.index,path:r,startsAt:r[0]===n?"C":"D",goesTo:r[r.length-1]===n?"C":"D"}})(),v=c>0?((n,o)=>{if(n.length<2)return n;const i=[n[0]];for(let r=0;r<n.length-1;r++){const a={start:n[r],end:n[r+1]},c={x:(a.start.x+a.end.x)/2,y:(a.start.y+a.end.y)/2},l=xe(c,t),d=xe(c,e);if((l<=s||d<=s)&&Math.abs(l-d)>1e-4){const n=g(a,t),r=g(a,e),c=xe(n,t),l=xe(r,e)<s,d=c<s?f(a,t,s):null,h=l?f(a,e,s):null;let u=[];if(xe(a.start,a.end)>s/2&&o>0)for(let n=1;n<=o;n++){const i=n/(o+1),r={x:a.start.x+i*(a.end.x-a.start.x),y:a.start.y+i*(a.end.y-a.start.y),t:i,isSpecial:!1},c=xe(r,t),l=xe(r,e);c<s||l<s||(d&&Math.abs(r.t-d.t)<.1||h&&Math.abs(r.t-h.t)<.1||u.push(r))}if(d&&u.push(d),h&&u.push(h),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],o=u[e];xe(n,o)>s/10&&t.push(o)}u=t}u.forEach(t=>i.push(t))}i.push(n[r+1])}if(i.length>1){const t=[i[0]];for(let e=1;e<i.length;e++){const n=t[t.length-1],o=i[e];xe(n,o)>s/10&&t.push(o)}return t}return i})(x.path,c):x.path;let S=(()=>{if(0===x.path.length)return null;const n=(()=>{const n=l(y.A_Right,y.B_Right),o=l(y.B_Left,y.A_Left);return[{startsAt:"E",goesTo:"B",points:[i,e]},{startsAt:"E",goesTo:"A",points:[i,t]},{startsAt:"F",goesTo:"B",points:[r,e]},{startsAt:"F",goesTo:"A",points:[r,t]},{startsAt:"E",goesTo:"B",points:[i,n,e]},{startsAt:"E",goesTo:"A",points:[i,n,t]},{startsAt:"F",goesTo:"B",points:[r,n,e]},{startsAt:"F",goesTo:"A",points:[r,n,t]},{startsAt:"E",goesTo:"B",points:[i,o,e]},{startsAt:"E",goesTo:"A",points:[i,o,t]},{startsAt:"F",goesTo:"B",points:[r,o,e]},{startsAt:"F",goesTo:"A",points:[r,o,t]},{startsAt:"E",goesTo:"B",points:[i,_.A_Right,n,e]},{startsAt:"F",goesTo:"B",points:[r,_.B_Right,n,e]},{startsAt:"E",goesTo:"A",points:[i,_.B_Left,o,t]},{startsAt:"F",goesTo:"A",points:[r,_.A_Left,o,t]},{startsAt:"E",goesTo:"B",points:[i,_.A_Left,o,e]},{startsAt:"E",goesTo:"A",points:[i,_.B_Right,n,t]},{startsAt:"E",goesTo:"B",points:[i,_.A_Opp,_.A_Right,n,e]},{startsAt:"E",goesTo:"A",points:[i,_.B_Opp,_.B_Left,o,t]},{startsAt:"F",goesTo:"B",points:[r,_.A_Opp,_.A_Left,o,e]},{startsAt:"F",goesTo:"A",points:[r,_.B_Opp,_.B_Right,n,t]},{startsAt:"F",goesTo:"A",points:[r,_.B_Opp,_.B_Left,o,t]},{startsAt:"E",goesTo:"B",points:[i,_.A_Opp,_.A_Left,o,e]},{startsAt:"E",goesTo:"A",points:[i,_.B_Opp,_.B_Right,n,t]},{startsAt:"E",goesTo:"B",points:[i,_.A_Left,_.A_Opp,_.A_Right,n,e]},{startsAt:"E",goesTo:"A",points:[i,_.B_Right,_.B_Opp,_.B_Left,o,t]},{startsAt:"F",goesTo:"B",points:[r,_.A_Right,_.A_Opp,_.A_Left,o,e]},{startsAt:"F",goesTo:"A",points:[r,_.B_Left,_.B_Opp,_.B_Right,n,t]},{startsAt:"F",goesTo:"A",points:[r,_.B_Right,_.B_Opp,_.B_Left,o,t]},{startsAt:"E",goesTo:"B",points:[i,_.A_Right,_.A_Opp,_.A_Left,o,e]},{startsAt:"E",goesTo:"A",points:[i,_.B_Left,_.B_Opp,_.B_Right,n,t]}].map((t,e)=>({...t,index:e}))})(),o=n.filter(t=>"E"===t.startsAt),s=n.filter(t=>"F"===t.startsAt),a=[],c=[];for(const t of o)if(!p(t.points,x.path)){a.push(t);break}for(const t of s)if(!p(t.points,x.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,o="A"===S.line2.goesTo?e:t,i=b(S.line1,n,s,a),r=b(S.line2,o,s,a);S={line1:{...S.line1,points:i},line2:{...S.line2,points:r}}}return{jPair:S,optimalPath:{startsAt:x.startsAt,goesTo:x.goesTo,points:v}}}var fs=class extends si{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,o]of n.entries())2===o.length&&t.push({startPort:{...o[0],z:o[0].z??0},endPort:{...o[1],z:o[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 fe(t.startPort,t.endPort,e.startPort,e.endPort)}calculateViaPositions(t,e){const n=this.bounds.maxX-this.bounds.minX,o=this.bounds.maxY-this.bounds.minY,i=this.bounds.minX,r=this.bounds.minY,s={width:n-2*this.obstacleMargin-this.viaDiameter,height:o-2*this.obstacleMargin-this.viaDiameter,x:i+this.obstacleMargin+this.viaDiameter/2,y:r+this.obstacleMargin+this.viaDiameter/2},a=this.viaDiameter+this.obstacleMargin,c=e.startPort,l=e.endPort,d=[{x:s.x,y:s.y},{x:s.x+s.width,y:s.y},{x:s.x+s.width,y:s.y+s.height},{x:s.x,y:s.y+s.height}],h=(t,e)=>xe(t,e),u=[];d.forEach((t,e)=>{h(t,c)>=a&&h(t,l)>=a&&u.push({...t,type:"corner",index:e})});const p=[{p1:d[0],p2:d[1]},{p1:d[1],p2:d[2]},{p1:d[2],p2:d[3]},{p1:d[3],p2:d[0]}];if([c,l].forEach((t,e)=>{p.forEach((n,o)=>{((t,e)=>{const n=t.x,o=t.y,i=t.r,r=e.p1.x,s=e.p1.y,a=e.p2.x,c=e.p2.y;if(Math.abs(a-r)<.001){const t=r,e=i*i-(t-n)**2;if(e<0)return[];if(Math.abs(e)<.001){const e=o;return e>=Math.min(s,c)&&e<=Math.max(s,c)?[{x:t,y:e}]:[]}const a=o+Math.sqrt(e),l=o-Math.sqrt(e),d=[];return a>=Math.min(s,c)&&a<=Math.max(s,c)&&d.push({x:t,y:a}),l>=Math.min(s,c)&&l<=Math.max(s,c)&&d.push({x:t,y:l}),d}const l=(c-s)/(a-r),d=s-l*r,h=1+l*l,u=2*(l*d-l*o-n),p=u*u-4*h*(n*n+(d-o)*(d-o)-i*i);if(p<0)return[];if(Math.abs(p)<.001){const t=-u/(2*h),e=l*t+d;return t>=Math.min(r,a)&&t<=Math.max(r,a)&&e>=Math.min(s,c)&&e<=Math.max(s,c)?[{x:t,y:e}]:[]}const m=(-u+Math.sqrt(p))/(2*h),g=(-u-Math.sqrt(p))/(2*h),f=l*m+d,y=l*g+d,_=[];return m>=Math.min(r,a)&&m<=Math.max(r,a)&&f>=Math.min(s,c)&&f<=Math.max(s,c)&&_.push({x:m,y:f}),g>=Math.min(r,a)&&g<=Math.max(r,a)&&y>=Math.min(s,c)&&y<=Math.max(s,c)&&_.push({x:g,y:y}),_})({...t,r:a},n).forEach(t=>{h(t,0===e?l:c)>=a&&u.push({...t,type:"intersection",circle:e,edge:o})})})}),u.length<2){const t=.8*a;if(d.forEach((e,n)=>{h(e,c)>=t&&h(e,l)>=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=[...d].sort((t,e)=>{const n=Math.min(h(t,c),h(t,l));return Math.min(h(e,c),h(e,l))-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 m=0,g=[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=h(u[t],u[e]);n>m&&(m=n,g=[u[t],u[e]])}let f={x:g[0].x,y:g[0].y},y={x:g[1].x,y:g[1].y};const _=xe(f,t.startPort);return xe(y,t.startPort)<_&&([f,y]=[y,f]),{via1:f,via2:y}}trySolveAOverB(t,e,n=!1){const o=n?this.calculateViaPositions(t,e):this.calculateViaPositions(e,t);if(!o)return!1;this.debugViaPositions.push(o);const{via1:i,via2:r}=this.pushViasFromEndpoints(this.moveViasAsCloseAsPossible(o));this.debugViaPositions.push({via1:i,via2:r});const{jPair:s,optimalPath:a}=gs({A:i,B:r,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(!s)return!1;const c={connectionName:t.connectionName,regionId:this.nodeWithPortPoints.capacityMeshNodeId,route:a.points.map(e=>({x:e.x,y:e.y,z:t.startPort.z??0})),traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]};s.line2.points.reverse();const l={connectionName:e.connectionName,regionId:this.nodeWithPortPoints.capacityMeshNodeId,route:[...s.line1.points.map(t=>({x:t.x,y:t.y,z:e.startPort.z??0})),{...s.line1.points[s.line1.points.length-1],z:this.escapeLayer},{...s.line2.points[0],z:this.escapeLayer},...s.line2.points.map(t=>({x:t.x,y:t.y,z:e.startPort.z??0}))],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[i,r]};return this.solvedRoutes.push(c,l),!0}pushViasFromEndpoints(t){const e={...t.via1},n={...t.via2},o=[this.routes[0].startPort,this.routes[0].endPort,this.routes[1].startPort,this.routes[1].endPort],i=this.getMinDistanceBetweenViaCenters(),r=this.viaDiameter/2+2*this.traceThickness+2*this.obstacleMargin;for(let t=0;t<10;t++){let s=!1,a=!1;const c=.9**t;for(const t of o){const o=xe(e,t);if(o<r){const n=(r-o)*c,i=e.x-t.x,a=e.y-t.y,l=Math.sqrt(i*i+a*a);l>1e-6&&(e.x+=i/l*n,e.y+=a/l*n,s=!0)}const i=xe(n,t);if(i<r){const e=(r-i)*c,o=n.x-t.x,s=n.y-t.y,l=Math.sqrt(o*o+s*s);l>1e-6&&(n.x+=o/l*e,n.y+=s/l*e,a=!0)}}const l=xe(e,n);if(l<i){const t=(i-l)/2,o=n.x-e.x,r=n.y-e.y,c=Math.sqrt(o*o+r*r);c>1e-6?(e.x-=o/c*t,e.y-=r/c*t,n.x+=o/c*t,n.y+=r/c*t,s=!0,a=!0):(e.x-=t,n.x+=t,s=!0,a=!0)}if(!s&&!a)break}const s=xe(e,n);if(s<i){const t=(i-s)/2,o=n.x-e.x,r=n.y-e.y,a=Math.sqrt(o*o+r*r);a>1e-6?(e.x-=o/a*t,e.y-=r/a*t,n.x+=o/a*t,n.y+=r/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,o=this.getMinDistanceBetweenViaCenters(),i=xe(e,n);if(i<=o)return t;const r=n.x-e.x,s=n.y-e.y,a=Math.sqrt(r*r+s*s),c=r/a,l=s/a,d=(e.x,n.x,e.y,n.y,(i-o)/2);return{via1:{x:e.x+c*d,y:e.y+l*d},via2:{x:n.x-c*d,y:n.y-l*d}}}handleRoutesDontCross(){const[t,e]=this.routes,n={connectionName:t.connectionName,regionId:this.nodeWithPortPoints.capacityMeshNodeId,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:[]},o={connectionName:e.connectionName,regionId:this.nodeWithPortPoints.capacityMeshNodeId,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,o),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:o}=this.debugViaPositions[e],i=["rgba(255, 165, 0, 0.3)","rgba(128, 0, 128, 0.3)"],r=i[e%i.length];t.circles.push({center:n,radius:this.viaDiameter/2,fill:r,stroke:"rgba(0, 0, 0, 0.3)",label:`Computed Via A (attempt ${e+1})`}),t.circles.push({center:o,radius:this.viaDiameter/2,fill:r,stroke:"rgba(0, 0, 0, 0.3)",label:`Computed Via B (attempt ${e+1})`});const s=this.viaDiameter/2+this.obstacleMargin;t.circles.push({center:n,radius:s,stroke:r,fill:"rgba(0, 0, 0, 0)",label:`Debug Via 1 Safety Margin (attempt ${e+1})`}),t.circles.push({center:o,radius:s,stroke:r,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,o,this.routes[e%2].endPort],strokeColor:`${r.substring(0,r.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],o=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 i=n.route[e],r=n.route[e+1];t.lines.push({points:[i,r],strokeColor:o,strokeDash:1===i.z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${i.z}`}),i._label&&t.points.push({x:i.x,y:i.y,label:i._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}},ys=class extends si{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,...o]=t,i=this.getHyperParameterCombinations(o);return n.possibleValues.forEach(t=>{i.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 o=n.f;o<t&&(t=o,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}},_s=t=>`${t.x.toFixed(6)},${t.y.toFixed(6)},${t.z}`,bs=t=>[t.route[0],t.route[t.route.length-1]],xs=(t,e,n)=>{const o=new Map,i=(t,e)=>{o.has(t)||o.set(t,new Set),o.has(e)||o.set(e,new Set),o.get(t).add(e),o.get(e).add(t)};for(const n of t)if(n.connectionName===e&&0!==n.route.length){if(1===n.route.length){const t=_s(n.route[0]);o.has(t)||o.set(t,new Set);continue}for(let t=0;t<n.route.length-1;t++)i(_s(n.route[t]),_s(n.route[t+1]))}const r=new Set([n]),s=[n];for(;s.length>0;){const t=s.pop();for(const e of o.get(t)??[])r.has(e)||(r.add(e),s.push(e))}return r},vs=Array.from({length:6},(t,e)=>e),Ss=class extends ys{getSolverName(){return"PortfolioSingleIntraNodeSolver"}constructorParams;solvedRoutes=[];nodeWithPortPoints;connMap;effort;adaptiveSearchExpanded=!1;getSolvedSegmentCount(t){const e=t.solvedConnectionsMap;if(!(e instanceof Map))return null;let n=0;for(const t of e.values())Array.isArray(t)&&(n+=t.length);return n}getNodeSegmentCount(){return Math.max(1,this.nodeWithPortPoints.portPointsInPairs?.length??new Set(this.nodeWithPortPoints.portPoints.map(t=>t.connectionName)).size)}getCandidateProgress(t){const e=this.getSolvedSegmentCount(t);return null!==e?Math.min(1,e/this.getNodeSegmentCount()):Math.max(0,Math.min(1,t.progress||0))}getTotalCandidateWork(){return(this.supervisedSolvers??[]).reduce((t,{solver:e})=>t+e.iterations,0)}getDynamicExpansionWorkBudget(){return Math.max(1,...(this.supervisedSolvers??[]).map(({solver:t})=>t.MAX_ITERATIONS))}constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.connMap=t.connMap,this.constructorParams=t,this.effort=t.effort??1,this.MAX_ITERATIONS=2e7*this.effort,this.GREEDY_MULTIPLIER=5,this.MIN_SUBSTEPS=100}getCombinationDefs(){return[["throughObstacle"],["singleLayerNoDifferentRootIntersections"],["multiHeadPolyLine"],["majorCombinations","orderings6","cellSizeFactor"],["noVias"],["orderings50"],["flipTraceAlignmentDirection","orderings6"],["closedFormSingleTrace"],["highDensityA01"],["highDensityA03"]]}getHyperParameterDefs(){return[{name:"singleLayerNoDifferentRootIntersections",possibleValues:[{SINGLE_LAYER_NO_DIFFERENT_ROOT_INTERSECTIONS:!0}]},{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:vs.map(t=>({SHUFFLE_SEED:t}))},{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:20},(t,e)=>({SHUFFLE_SEED:100+e}))},{name:"throughObstacle",possibleValues:[{THROUGH_OBSTACLE:!0}]},{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,SHUFFLE_SEED:vs[0]}]},{name:"highDensityA03",possibleValues:[{HIGH_DENSITY_A03:!0}]}]}initializeCandidateBudget(t){const e=t.setup;"function"==typeof e&&e.call(t)}refreshDynamicIterationLimit(){const t=(this.supervisedSolvers??[]).reduce((t,{solver:e})=>{if(e.solved||e.failed)return t;const n=Math.max(0,e.MAX_ITERATIONS-e.iterations+1);return t+Math.ceil(n/this.MIN_SUBSTEPS)},0);this.MAX_ITERATIONS=Math.max(this.iterations+1,this.iterations+t),this.stats.dynamicSupervisorIterationLimit=this.MAX_ITERATIONS}initializeSolvers(){super.initializeSolvers();for(const{solver:t}of this.supervisedSolvers??[])this.initializeCandidateBudget(t);this.stats.dynamicExpansionWorkBudget=this.getDynamicExpansionWorkBudget(),this.refreshDynamicIterationLimit()}addSupervisedCandidate(t){const e=this.generateSolver(t);this.initializeCandidateBudget(e);const n=this.computeG(e);this.supervisedSolvers.push({hyperParameters:t,solver:e,h:0,g:n,f:n})}expandAdaptiveSearch(){if(!this.adaptiveSearchExpanded){this.adaptiveSearchExpanded=!0;for(const t of vs.slice(1))this.addSupervisedCandidate({HIGH_DENSITY_A01:!0,SHUFFLE_SEED:t});this.refreshDynamicIterationLimit(),this.stats.adaptiveSearchExpanded=!0,this.stats.adaptiveSearchExpandedAtIteration=this.iterations,this.stats.candidateWorkAtExpansion=this.getTotalCandidateWork(),this.stats.bestProgressAtExpansion=Math.max(0,...(this.supervisedSolvers??[]).map(({solver:t})=>this.getCandidateProgress(t)))}}shouldExpandPortfolio(){if(this.adaptiveSearchExpanded)return!1;const t=this.getDynamicExpansionWorkBudget();return this.stats.dynamicExpansionWorkBudget=t,this.getTotalCandidateWork()>=t}_step(){this.supervisedSolvers||this.initializeSolvers(),this.adaptiveSearchExpanded||this.getSupervisedSolverWithBestFitness()||this.expandAdaptiveSearch(),super._step(),this.solved||this.failed||!this.shouldExpandPortfolio()||this.expandAdaptiveSearch()}computeG(t){return t instanceof Pi||t instanceof ki?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 this.adaptiveSearchExpanded?1-this.getCandidateProgress(t):1-(t.progress||0)}generateSolver(t){if(t.SINGLE_LAYER_NO_DIFFERENT_ROOT_INTERSECTIONS){if(!Zr.isApplicable(this.nodeWithPortPoints)){const t=new er({nodeWithPortPoints:this.nodeWithPortPoints,connMap:this.connMap,traceWidth:this.constructorParams.traceWidth,viaDiameter:this.constructorParams.viaDiameter,obstacleMargin:this.constructorParams.obstacleMargin});return t.failed=!0,t.error="Single-layer no-different-root-intersection solver not applicable",t}return new Zr({nodeWithPortPoints:this.nodeWithPortPoints,traceWidth:this.constructorParams.traceWidth,viaDiameter:this.constructorParams.viaDiameter})}if(t.HIGH_DENSITY_A01){return new Pi({nodeWithPortPoints:this.nodeWithPortPoints,cellSizeMm:.1,viaDiameter:this.constructorParams.viaDiameter??.3,viaMinDistFromBorder:(this.constructorParams.viaDiameter??.3)/2,traceMargin:.1,traceThickness:this.constructorParams.traceWidth??.15,effort:this.effort,hyperParameters:{shuffleSeed:t.SHUFFLE_SEED??0}})}if(t.HIGH_DENSITY_A03){return new ki({nodeWithPortPoints:this.nodeWithPortPoints,highResolutionCellSize:.1,highResolutionCellThickness:8,lowResolutionCellSize:.4,viaDiameter:this.constructorParams.viaDiameter??.3,viaMinDistFromBorder:(this.constructorParams.viaDiameter??.3)/2,traceMargin:.1,traceThickness:.1,effort:this.effort,hyperParameters:t})}return t.CLOSED_FORM_TWO_TRACE_SAME_LAYER?new fs({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.CLOSED_FORM_TWO_TRACE_TRANSITION_CROSSING?new ms({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.CLOSED_FORM_SINGLE_TRANSITION?new Jr({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.THROUGH_OBSTACLE?new es({nodeWithPortPoints:this.nodeWithPortPoints,obstacles:this.constructorParams.obstacles,connMap:this.connMap,layerCount:this.constructorParams.layerCount,viaDiameter:this.constructorParams.viaDiameter,traceThickness:this.constructorParams.traceWidth}):t.MULTI_HEAD_POLYLINE_SOLVER?new Ar({nodeWithPortPoints:this.nodeWithPortPoints,connMap:this.connMap,hyperParameters:t,viaDiameter:this.constructorParams.viaDiameter}):new rr({...this.constructorParams,hyperParameters:t})}onSolve(t){let e;e=t.solver instanceof Pi||t.solver instanceof ki?t.solver.getOutput():t.solver.solvedRoutes;const n=e.map(t=>{const e=this.nodeWithPortPoints.portPoints.find(e=>e.connectionName===t.connectionName);return e?.rootConnectionName?{...t,rootConnectionName:e.rootConnectionName}:t});this.solvedRoutes=((t,e)=>{const n=[...t],o=new Map;for(const t of e.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}for(const[t,e]of o){if(e.length<=1)continue;const o=e[0]?.rootConnectionName??t,i=new Set(e.map(_s));let r=xs(n,t,_s(e[0]));for(const s of e.slice(1)){const a=_s(s);if(r.has(a))continue;const c=n.find(e=>{if((e.rootConnectionName??e.connectionName)!==o)return!1;if(e.connectionName===t)return!1;const[n,s]=bs(e);if(!n||!s)return!1;const c=_s(n),l=_s(s);return r.has(c)&&l===a||r.has(l)&&c===a||i.has(c)&&i.has(l)&&(c===a||l===a)});c&&(n.push({...c,connectionName:t,rootConnectionName:o,route:c.route.map(e=>({...e,connectionName:t,rootConnectionName:o})),vias:c.vias.map(t=>({...t})),jumpers:c.jumpers?.map(t=>({...t,start:{...t.start},end:{...t.end}}))}),r=xs(n,t,_s(e[0])))}}return n})(n,this.nodeWithPortPoints)}};function Is(t,e,n,o,i){const r=n-e,s=i-o,a=1e-6;if(Math.abs(t.y-i)<a)return t.x-e;if(Math.abs(t.x-n)<a)return r+(i-t.y);if(Math.abs(t.y-o)<a)return r+s+(n-t.x);if(Math.abs(t.x-e)<a)return 2*r+s+(t.y-o);const c=Math.abs(t.y-i),l=Math.abs(t.x-n),d=Math.abs(t.y-o),h=Math.abs(t.x-e),u=Math.min(c,l,d,h);return u===c?Math.max(0,Math.min(r,t.x-e)):u===l?r+Math.max(0,Math.min(s,i-t.y)):u===d?r+s+Math.max(0,Math.min(r,n-t.x)):2*r+s+Math.max(0,Math.min(s,t.y-o))}function Cs(t,e,n=1e-6){return Math.abs(t-e)<n}function Ps(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[o,i]=e[t];for(let r=t+1;r<e.length;r++){const[t,s]=e[r];Cs(o,t)||Cs(o,s)||Cs(i,t)||Cs(i,s)||(o<t&&t<i&&i<s||t<o&&o<s&&s<i)&&n++}}return n}var Ms=t=>{const e=t.center.x-t.width/2,n=t.center.x+t.width/2,o=t.center.y-t.height/2,i=t.center.y+t.height/2,r=new Map;for(const e of t.portPoints){const t=r.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}),r.set(e.connectionName,t)}const s=new Map,a=[];let c=0;for(const[t,l]of r){if(l.length<2)continue;const t=l[0],r=l[1],d=Is(t,e,n,o,i),h=Is(r,e,n,o,i);if(t.z===r.z){const e=t.z,n=s.get(e)??[];n.push([d,h]),s.set(e,n)}else c++,a.push([d,h])}let l=0;for(const[t,e]of s)l+=Ps(e);return{numSameLayerCrossings:l,numEntryExitLayerChanges:c,numTransitionPairCrossings:Ps(a)}},Ns=t=>t.availableZ?.length?[...new Set(t.availableZ)].sort((t,e)=>t-e):[...new Set(t.portPoints.map(t=>t.z??0))].sort((t,e)=>t-e),ws=t=>1===Ns(t).length&&Ms(t).numSameLayerCrossings>0,Ts=(t,e,n)=>{const o=new Map,[i]=Ns(t);for(const e of t.portPoints)o.set(e.connectionName,[...o.get(e.connectionName)??[],e]);return Array.from(o.entries()).flatMap(([o,r])=>{if(r.length<2)return[];const s=r[0],a=r[r.length-1];return[{connectionName:o,rootConnectionName:s.rootConnectionName,regionId:t.capacityMeshNodeId,traceThickness:e,viaDiameter:n,route:[{x:s.x,y:s.y,z:i??s.z??0},{x:a.x,y:a.y,z:i??a.z??0}],vias:[]}]})},Rs=Ts,Es=(t,e,n)=>({...t,x:e.x+(t.x-e.x)*n,y:e.y+(t.y-e.y)*n}),As=(t,e,n)=>Es(t,e,n),Os=["#dc2626","#2563eb","#16a34a","#ca8a04","#9333ea","#0891b2"],ks=(t,e,n=[])=>[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join("\n"),Ls=class extends si{getSolverName(){return"GrowShrinkHighDensityIntraNodeSolver"}constructorParams;nodeWithPortPoints;solvedRoutes=[];failedSolvers=[];activeSubSolver=null;winningSolver;scaleFactor=1;growthAttempts=0;maxGrowthAttempts;constructor(t){if(super(),this.constructorParams=t,this.nodeWithPortPoints=t.nodeWithPortPoints,this.maxGrowthAttempts=t.maxGrowthAttempts??3,this.MAX_ITERATIONS=2e7*(t.effort??1)*(this.maxGrowthAttempts+1),ws(this.nodeWithPortPoints)){if(!t.fallbackToInvalidGeometryOnFailure)return this.failed=!0,this.progress=1,void(this.error="GrowShrinkHighDensityIntraNodeSolver cannot route an impossible single-layer crossing");this.solvedRoutes=Rs(this.nodeWithPortPoints,t.traceWidth??.15,t.viaDiameter??.3),this.solved=!0,this.progress=1,this.stats={invalidGeometryFallback:!0,reason:"single-layer node has same-layer crossings"}}}getConstructorParams(){return this.constructorParams}createActiveSubSolver(){const{growShrinkSolutionValidator:t,...e}=this.constructorParams;var n,o;this.activeSubSolver=new Ss({...e,nodeWithPortPoints:(n=this.nodeWithPortPoints,o=this.scaleFactor,{...n,width:n.width*o,height:n.height*o,portPoints:n.portPoints.map(t=>As(t,n.center,o)),portPointsInPairs:n.portPointsInPairs?.map(([t,e])=>[As(t,n.center,o),As(e,n.center,o)])})}),this.constructorParams.maxInnerIterationsPerGrowthAttempt&&(this.activeSubSolver.MAX_ITERATIONS=this.constructorParams.maxInnerIterationsPerGrowthAttempt)}acceptSolution(t){const e=1===this.scaleFactor?t.solvedRoutes:t.solvedRoutes.map(t=>((t,e,n)=>({...t,route:t.route.map(t=>Es(t,e,n)),vias:t.vias.map(t=>Es(t,e,n)),jumpers:t.jumpers?.map(t=>({...t,start:Es(t.start,e,n),end:Es(t.end,e,n)}))}))(t,this.nodeWithPortPoints.center,1/this.scaleFactor));return this.constructorParams.growShrinkSolutionValidator&&!this.constructorParams.growShrinkSolutionValidator(e)?(t.solved=!1,t.failed=!0,t.error="High-density scale solution rejected by validator",!1):(this.winningSolver=t,this.solvedRoutes=e,this.solved=!0,this.failed=!1,!0)}computeProgress(){return Math.min(.99,(this.growthAttempts+(this.activeSubSolver?.progress??0))/(this.maxGrowthAttempts+1))}_step(){if(this.activeSubSolver||this.createActiveSubSolver(),this.activeSubSolver.step(),this.activeSubSolver.solved&&this.acceptSolution(this.activeSubSolver))this.activeSubSolver=null;else if(this.activeSubSolver.failed){if(this.failedSolvers.push(this.activeSubSolver),this.error=this.activeSubSolver.error,this.activeSubSolver=null,this.growthAttempts>=this.maxGrowthAttempts)return this.constructorParams.fallbackToInvalidGeometryOnFailure?(this.solvedRoutes=Ts(this.nodeWithPortPoints,this.constructorParams.traceWidth??.15,this.constructorParams.viaDiameter??.3),this.solved=!0,this.failed=!1,this.progress=1,this.stats={...this.stats,invalidGeometryFallback:!0,reason:"growth attempts exhausted",lastError:this.error},void(this.error=null)):(this.failed=!0,void(this.error=`GrowShrinkHighDensityIntraNodeSolver failed after resizing to ${this.scaleFactor}x. Last error: ${this.error}`));this.growthAttempts++,this.scaleFactor*=2}}visualize(){const t=this.activeSubSolver?.visualize()??this.winningSolver?.visualize();return t||(this.solvedRoutes.length>0?{title:this.stats.invalidGeometryFallback?"Invalid same-layer crossing geometry":"Grow/shrink high density routes",lines:this.solvedRoutes.flatMap((t,e)=>t.route.slice(0,-1).map((n,o)=>({points:[n,t.route[o+1]],strokeColor:Os[e%Os.length],strokeWidth:t.traceThickness,layer:`z${n.z}`,label:ks(t.connectionName,t.rootConnectionName,[`z${n.z}`,this.stats.invalidGeometryFallback?"invalid fallback route":void 0].filter(Boolean))}))),points:this.nodeWithPortPoints.portPoints.map(t=>({x:t.x,y:t.y,color:Os[Math.max(0,this.solvedRoutes.findIndex(e=>e.connectionName===t.connectionName))%Os.length],label:ks(t.connectionName,t.rootConnectionName,[`z${t.z}`])})),rects:[{center:this.nodeWithPortPoints.center,width:this.nodeWithPortPoints.width,height:this.nodeWithPortPoints.height,fill:this.stats.invalidGeometryFallback?"rgba(245, 158, 11, 0.12)":"rgba(14, 165, 233, 0.08)",stroke:this.stats.invalidGeometryFallback?"rgba(217, 119, 6, 0.8)":"rgba(14, 165, 233, 0.55)",label:[this.nodeWithPortPoints.capacityMeshNodeId,this.stats.reason].filter(Boolean).join("\n")}],circles:[]}:t??{lines:[],points:[],rects:[],circles:[]})}},Ds=(t,e,n=[])=>[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join("\n"),zs=class extends si{getSolverName(){return"HighDensitySolver"}unsolvedNodePortPoints;routes;colorMap;defaultViaDiameter=.3;defaultTraceThickness=.15;viaDiameter;traceWidth;obstacleMargin;effort;obstacles;layerCount;useGrowShrinkHighDensityIntraNodeSolver;preserveTerminalPcbPortIds;growShrinkMaxInnerIterationsPerGrowthAttempt;growShrinkFallbackToInvalidGeometryOnFailure;growShrinkSolutionValidator;captureSearchDebug;failedSolvers;activeSubSolver=null;connMap;nodePfById;nodeSolveMetadataById;constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a,obstacles:c,layerCount:l,useGrowShrinkHighDensityIntraNodeSolver:d,preserveTerminalPcbPortIds:h,growShrinkMaxInnerIterationsPerGrowthAttempt:u,growShrinkFallbackToInvalidGeometryOnFailure:p,growShrinkSolutionValidator:m,captureSearchDebug:g}){super(),this.unsolvedNodePortPoints=t,this.colorMap=e??{},this.connMap=n,this.routes=[],this.failedSolvers=[],this.effort=s??1,this.viaDiameter=o??this.defaultViaDiameter,this.traceWidth=i??this.defaultTraceThickness,this.obstacleMargin=r??.15,this.obstacles=c??[],this.layerCount=l??2,this.useGrowShrinkHighDensityIntraNodeSolver=d??!1,this.preserveTerminalPcbPortIds=h??!1,this.growShrinkMaxInnerIterationsPerGrowthAttempt=u,this.growShrinkFallbackToInvalidGeometryOnFailure=p??!1,this.growShrinkSolutionValidator=m,this.captureSearchDebug=g??!0,this.MAX_ITERATIONS=1e7*this.effort*(this.useGrowShrinkHighDensityIntraNodeSolver?4:1),this.nodePfById=a instanceof Map?new Map(a):new Map(Object.entries(a??{})),this.nodeSolveMetadataById=new Map,this.stats={solverNodeCount:{},difficultNodePfs:{},highDensityResizeCount:0}}getSolvedNodeSolverType(t){return t instanceof Ls&&t.winningSolver?this.getSolvedNodeSolverType(t.winningSolver):t instanceof Ss&&t.winningSolver?this.getConcreteSolverTypeName(t.winningSolver):this.getConcreteSolverTypeName(t)}recordNodeSolveMetadata(t,e){const n=t.nodeWithPortPoints,o=this.nodePfById.get(n.capacityMeshNodeId)??null;this.nodeSolveMetadataById.set(n.capacityMeshNodeId,{node:n,status:e,solverType:this.getSolvedNodeSolverType(t),iterations:t.iterations,routeCount:t.solvedRoutes.length,nodePf:o,error:t.error??void 0})}createNodeMarkerLabel(t,e){return["hd_node_marker",`node: ${t}`,`status: ${e.status}`,`solver: ${e.solverType}`,`iterations: ${e.iterations}`,`routes: ${e.routeCount}`,`nodePf: ${e.nodePf??"n/a"}`,`portPoints: ${e.node.portPoints.length}`,...e.error?[`error: ${e.error}`]:[]].join("\n")}getConcreteSolverTypeName(t){if(t instanceof rr){const e=this.getIntraNodeStrategyName(t.hyperParameters);return t.cacheHit?`${e} [cached]`:e}return t instanceof er?this.getIntraNodeStrategyName(t.hyperParameters):t.getSolverName()}getIntraNodeStrategyName(t){return t?.MULTI_HEAD_POLYLINE_SOLVER?"MultiHeadPolyLineIntraNodeSolver3":t?.SINGLE_LAYER_NO_DIFFERENT_ROOT_INTERSECTIONS?"SingleLayerNoDifferentRootIntersectionsIntraNodeSolver":t?.CLOSED_FORM_SINGLE_TRANSITION?"SingleTransitionIntraNodeSolver":t?.CLOSED_FORM_TWO_TRACE_SAME_LAYER?"TwoCrossingRoutesHighDensitySolver":t?.CLOSED_FORM_TWO_TRACE_TRANSITION_CROSSING?"SingleTransitionCrossingRouteSolver":t?.HIGH_DENSITY_A01?"HighDensitySolverA01":t?.HIGH_DENSITY_A03?"HighDensitySolverA03":"SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost"}recordSolvedNodeStats(t,e){const n=this.getSolvedNodeSolverType(t),o=this.stats.solverNodeCount,i=this.stats.difficultNodePfs;o[n]=(o[n]??0)+1;const r=this.nodePfById.get(e.capacityMeshNodeId)??null;null!==r&&r>.05&&(i[n]||(i[n]=[]),i[n].push(r))}recordResizeStats(t){t instanceof Ls&&(this.stats.highDensityResizeCount=(this.stats.highDensityResizeCount??0)+t.growthAttempts)}getSolvedRoutesWithTerminalPcbPortIds(t){const e=t.nodeWithPortPoints.portPoints.filter(t=>void 0!==t.pcb_port_id);if(0===e.length)return t.solvedRoutes;const n=(t,n)=>{const o=e.filter(e=>e.connectionName===t.connectionName&&e.x===n.x&&e.y===n.y&&e.z===n.z);if(o.length>1)throw new Error(`HighDensitySolver found multiple PCB terminals at an endpoint of "${t.connectionName}"`);const i=o[0];if(i?.pcb_port_id)return i.pcb_port_id};return t.solvedRoutes.map(t=>({...t,startPcbPortId:t.route[0]?n(t,t.route[0]):void 0,endPcbPortId:t.route.length>1?n(t,t.route[t.route.length-1]):void 0}))}_step(){if(this.updateCacheStats(),this.activeSubSolver)return this.activeSubSolver.step(),this.activeSubSolver.solved?(this.routes.push(...this.preserveTerminalPcbPortIds?this.getSolvedRoutesWithTerminalPcbPortIds(this.activeSubSolver):this.activeSubSolver.solvedRoutes),this.recordNodeSolveMetadata(this.activeSubSolver,"solved"),this.recordSolvedNodeStats(this.activeSubSolver,this.activeSubSolver.nodeWithPortPoints),this.recordResizeStats(this.activeSubSolver),this.activeSubSolver=null):this.activeSubSolver.failed&&(this.recordNodeSolveMetadata(this.activeSubSolver,"failed"),this.recordResizeStats(this.activeSubSolver),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={nodeWithPortPoints:this.unsolvedNodePortPoints.pop(),colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,obstacles:this.obstacles,layerCount:this.layerCount,maxInnerIterationsPerGrowthAttempt:this.growShrinkMaxInnerIterationsPerGrowthAttempt,fallbackToInvalidGeometryOnFailure:this.growShrinkFallbackToInvalidGeometryOnFailure,growShrinkSolutionValidator:this.growShrinkSolutionValidator,captureSearchDebug:this.captureSearchDebug};this.activeSubSolver=this.useGrowShrinkHighDensityIntraNodeSolver?new Ls(t):new Ss(t),this.updateCacheStats()}updateCacheStats(){const t=oo();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=mi(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const o of n)t.lines.push({points:o.points,label:Ds(e.connectionName,e.rootConnectionName),strokeColor:0===o.z?o.color:To(o.color,.5),layer:`z${o.z}`,strokeWidth:e.traceThickness,strokeDash:0!==o.z?[.1,.3]: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:Ds(e.connectionName,e.rootConnectionName,["via"])})}if(this.solved||this.failed)for(const[e,n]of this.nodeSolveMetadataById){const o=n.node.center.x-n.node.width/2,i=n.node.center.x+n.node.width/2,r=n.node.center.y-n.node.height/2,s=n.node.center.y+n.node.height/2,a=this.createNodeMarkerLabel(e,n),c="solved"===n.status?"blue":"red";if(t.lines.push({points:[{x:o,y:r},{x:i,y:r}],layer:"hd_node_boundaries",strokeColor:c,strokeDash:"6, 4",strokeWidth:.03,label:a},{points:[{x:i,y:r},{x:i,y:s}],layer:"hd_node_boundaries",strokeColor:c,strokeDash:"6, 4",strokeWidth:.03,label:a},{points:[{x:i,y:s},{x:o,y:s}],layer:"hd_node_boundaries",strokeColor:c,strokeDash:"6, 4",strokeWidth:.03,label:a},{points:[{x:o,y:s},{x:o,y:r}],layer:"hd_node_boundaries",strokeColor:c,strokeDash:"6, 4",strokeWidth:.03,label:a}),"solved"===n.status)t.points.push({x:n.node.center.x,y:n.node.center.y,color:c,layer:"hd_node_markers",label:a});else{t.lines.push({points:[{x:0,y:0},{x:n.node.center.x,y:n.node.center.y}],layer:"hd_failed_node_guides",strokeColor:"red",strokeDash:"8, 6",strokeWidth:.05,label:a});const e=Math.max(.1*n.node.width,.12),o=Math.max(.1*n.node.height,.12);t.rects.push({center:n.node.center,layer:"hd_node_markers",width:e,height:o,fill:"red",label:a})}}return this.activeSubSolver&&(t=pi(t,this.activeSubSolver.visualize())),t}};function Fs(t,e){const n=[],o=e.filter(t=>t._containsTarget),i=new Map;for(const r of t.connections){const t=[];for(const n of r.pointsToConnect){let i=e[0],r=Number.MAX_VALUE;for(const t of o){const e=Math.sqrt((t.center.x-n.x)**2+(t.center.y-n.y)**2);e<r&&(r=e,i=t)}t.push(i)}if(t.length<2)throw new Error(`Not enough nodes for connection "${r.name}", only ${t.length} found`);i.set(r.name,t.map(t=>t.capacityMeshNodeId)),n.push({connection:r,nodeIds:[t[0].capacityMeshNodeId,t[t.length-1].capacityMeshNodeId],straightLineDistance:xe(t[0].center,t[t.length-1].center)})}return{unshuffledConnectionsWithResults:n,connectionNameToGoalNodeIds:i}}function Bs(t,e){const n=new Map(e.map(t=>[t.capacityMeshNodeId,t])),o=e.map(t=>(t.width+t.height)/2).filter(t=>Number.isFinite(t)&&t>0),i=o.length>0?o.reduce((t,e)=>t+e,0)/o.length:1,r=e.filter(t=>t._offBoardConnectionId),s=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){s.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:l,connectionNameToGoalNodeIds:d}=Fs(t,e);return{nodeMap:n,avgNodePitch:i,offBoardNodes:r,portPointMap:s,nodePortPointsMap:a,nodeAssignedPortPoints:c,unshuffledConnectionsWithResults:l,connectionNameToGoalNodeIds:d}}var js=(t,e=1,n={})=>{const o=n.viaDiameter??.3,i="width"in t?t.width:t,r=n.obstacleMargin??.2,s="height"in t&&"number"==typeof t.height?t.height:i;if(!Number.isFinite(i)||!Number.isFinite(s))return 0;if(i<=0||s<=0)return 0;const a=Math.min(i,s)/(o+r),c=(Math.sqrt(i*s)*Math.min(1.2,Math.max(.85,a**.05))/(o/2+r)/2)**1.1*e;return Number.isFinite(c)?1===t.availableZ?.length&&c>1?1:c:0},$s=(t,e=.5,n=16)=>{let o=0,i=t;for(;o<n;){if(js({width:i})<=e)break;i/=2,o++}return Math.max(1,o)},Ys=(t,e,n,o)=>{if(t?._containsTarget)return 0;if(1===(t.availableZ?.length??2)&&(e>0||n>0||o>0))return 1;const i=((.82*e+.41*n+.2*o)/2)**1.1;if(!Number.isFinite(i))return 1;const r=js(t);if(!Number.isFinite(r)||r<=0)return i>0?1:0;const s=i/r;if(Number.isNaN(s))throw new Error("calculateNodeProbabilityOfFailure returned NaN");return Number.isFinite(s)?s:i>0?1:0};function Xs(t,e,n){let o=0;const i=n?.NODE_MAX_PF??.99999;for(const n of t){const t=e.get(n.capacityMeshNodeId);if(!t)continue;if(t._containsTarget)continue;const r=Ms(n),s=Math.min(Ys(t,r.numSameLayerCrossings,r.numEntryExitLayerChanges,r.numTransitionPairCrossings),i);o+=Math.log(1-s)}return o}function Vs(t,e){if(e._containsTarget)return 0;const n=Ms(t);return Ys(e,n.numSameLayerCrossings,n.numEntryExitLayerChanges,n.numTransitionPairCrossings)}function Ws(t,e,n,o,i){const r=n-e,s=i-o,a=1e-6;if(Math.abs(t.y-i)<a)return t.x-e;if(Math.abs(t.x-n)<a)return r+(i-t.y);if(Math.abs(t.y-o)<a)return r+s+(n-t.x);if(Math.abs(t.x-e)<a)return 2*r+s+(t.y-o);const c=Math.abs(t.y-i),l=Math.abs(t.x-n),d=Math.abs(t.y-o),h=Math.abs(t.x-e),u=Math.min(c,l,d,h);return u===c?Math.max(0,Math.min(r,t.x-e)):u===l?r+Math.max(0,Math.min(s,i-t.y)):u===d?r+s+Math.max(0,Math.min(r,n-t.x)):2*r+s+Math.max(0,Math.min(s,t.y-o))}var Hs=1.6*3.2,Gs=(t,e)=>{const n=Math.ceil(e/2),o=Math.min(t.width,t.height),i=Math.max(t.width,t.height),r=(Math.floor(o/1.6)+.1)*(Math.floor(i/3.2)+.1)/Hs;return Math.min(1,n/r)};function Us(t,e,n,o){const i=e.x-n/2,r=e.x+n/2,s=e.y-o/2,a=e.y+o/2,c=Math.abs(t.y-a),l=Math.abs(t.x-r),d=Math.abs(t.y-s),h=Math.abs(t.x-i),u=Math.min(c,l,d,h);return u>.001?"interior":u===c?"top":u===l?"right":u===d?"bottom":"left"}function Zs(t,e,n,o,i){const r=Us(t,n,o,i),s=Us(e,n,o,i);return"interior"!==r&&r===s}function qs(t,e,n,o,i){const r=Us(t,n,o,i);let s;if("top"===r||"bottom"===r){const n=o;s=Math.abs(e.x-t.x)/n}else{const n=i;s=Math.abs(e.y-t.y)/n}s=Math.min(1,Math.max(0,s));const a=(t.x+e.x)/2,c=(t.y+e.y)/2;return{x:a+(n.x-a)*s,y:c+(n.y-c)*s}}function Js(t){return"computeNodePf"in t&&"function"==typeof t.computeNodePf}function Ks(t){const e={lines:[],points:[],rects:[],circles:[]};for(const n of t.inputNodes){let o=0,i=0,r={numSameLayerCrossings:0,numEntryExitLayerChanges:0,numTransitionPairCrossings:0},s=0;if(Js(t)){o=t.computeNodePf(n),i=t.nodeMemoryPfMap.get(n.capacityMeshNodeId)??0;const e=t.buildNodeWithPortPointsForCrossing(n);r=Ms(e);const a=new Set,c=t.nodeAssignedPortPoints.get(n.capacityMeshNodeId)??[];for(const t of c)t.connectionName&&a.add(t.connectionName);s=a.size}else{o=t.nodePfMap.get(n.capacityMeshNodeId)??0;const e=t.nodeAssignedPortPoints.get(n.capacityMeshNodeId)??[],i={capacityMeshNodeId:n.capacityMeshNodeId,center:n.center,width:n.width,height:n.height,portPoints:e,availableZ:n.availableZ};r=Ms(i);const a=new Set;for(const t of e)t.connectionName&&a.add(t.connectionName);s=a.size}const a=Math.min(255,Math.floor(512*o)),c=Math.max(0,255-Math.floor(512*o));let l=`rgba(${a}, ${c}, ${c}, ${o<.001?"0.1":"0.3"})`;n._containsObstacle&&(l="rgba(255, 0, 0, 0.3)"),n._offBoardConnectedCapacityMeshNodeIds?.length&&(l="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:l,label:`${n.capacityMeshNodeId}\npf: ${o.toFixed(3)}, memPf: ${i.toFixed(3)}\nC#: ${s}\nxSame: ${r.numSameLayerCrossings}, xLC: ${r.numEntryExitLayerChanges}, xTransition: ${r.numTransitionPairCrossings}\nobCmid: ${n._offBoardConnectedCapacityMeshNodeIds?.join(",")}\nobs: ${n._containsObstacle?"yes":"no"}`})}if(Js(t))for(const[n,o]of t.portPointMap){const i=t.assignedPortPoints.get(n),r=i?t.colorMap[i.connectionName]??"blue":"rgba(150, 150, 150, 0.5)";e.circles.push({center:{x:o.x,y:o.y},radius:.05,fill:r,layer:`z${o.z}`,label:[n,`conn: ${i?.connectionName}`,`cd: ${o.distToCentermostPortOnZ}`,`connects: ${o.connectionNodeIds.join(",")}`,`rootConn: ${i?.rootConnectionName}`].filter(Boolean).join("\n")})}const n=Js(t)?t.connectionsWithResults:t.connectionResults;for(const o of n){if(!o.path)continue;const n=o.connection,i=t.colorMap[n.name]??"blue",r=[];for(const t of o.path)r.push({x:t.point.x,y:t.point.y,z:t.z,nodeId:t.currentNodeId});for(let n=0;n<r.length-1;n++){const o=r[n],s=r[n+1],a=o.z===s.z,c=o.z;let l;l=a?0===c?void 0:"10 5":"3 3 10";const d=o.nodeId?t.nodeMap.get(o.nodeId):null;if(d&&Zs(o,s,d.center,d.width,d.height)){const t=qs(o,s,d.center,d.width,d.height);e.lines.push({points:[{x:o.x,y:o.y},{x:t.x,y:t.y}],strokeColor:i,strokeDash:l}),e.lines.push({points:[{x:t.x,y:t.y},{x:s.x,y:s.y}],strokeColor:i,strokeDash:l})}else e.lines.push({points:[{x:o.x,y:o.y},{x:s.x,y:s.y}],strokeColor:i,strokeDash:l})}}if(Js(t)&&!t.solved&&t.candidates&&t.candidates.length>0){const n=t.currentConnection,o=n?t.colorMap[n.connection.name]??"blue":"blue";if(n){const[i,r]=n.nodeIds,s=t.nodeMap.get(i),a=t.nodeMap.get(r),c=n.connection.pointsToConnect[0],l=n.connection.pointsToConnect[n.connection.pointsToConnect.length-1];if(s&&a){const t=c?{x:c.x,y:c.y}:s.center,i=l?{x:l.x,y:l.y}:a.center;e.lines.push({points:[t,i],strokeColor:To(o,.5),strokeDash:"5 5"}),e.points.push({x:t.x,y:t.y,color:o,label:[`Start: ${n.connection.name}`,`${n.connection.__rootConnectionNames?.[0]}`].join("\n")}),e.points.push({x:i.x,y:i.y,color:o,label:[`End: ${n.connection.name}`,`${n.connection.__rootConnectionNames?.[0]}`].join("\n")}),e.circles.push({center:i,radius:.08,stroke:o,label:`Goal: ${n.connection.name}`})}}const i=[...t.candidates].sort((t,e)=>t.f-e.f).slice(0,1);for(const r of i){const i=[];let s=r;for(;s;)i.unshift({x:s.point.x,y:s.point.y,z:s.z,lastMoveWasOffBoard:s.lastMoveWasOffBoard,nodeId:s.currentNodeId}),s=s.prevCandidate;for(let n=0;n<i.length-1;n++){const r=i[n],s=i[n+1],a=r.z===s.z,c=r.z;let l;l=s.lastMoveWasOffBoard?"2 2":a?0===c?void 0:"10 5":"3 3 10";const d=r.nodeId?t.nodeMap.get(r.nodeId):null,h=.02*r.z;if(d&&Zs(r,s,d.center,d.width,d.height)){const t=qs(r,s,d.center,d.width,d.height);e.lines.push({points:[{x:r.x+h,y:r.y+h},{x:t.x+h,y:t.y+h}],strokeColor:To(o,.25),strokeDash:l}),e.lines.push({points:[{x:t.x+h,y:t.y+h},{x:s.x+h,y:s.y+h}],strokeColor:To(o,.25),strokeDash:l})}else e.lines.push({points:[{x:r.x+h,y:r.y+h},{x:s.x+h,y:s.y+h}],strokeColor:To(o,.25),strokeDash:l})}if(i.length>=1){const s=i[i.length-1];let a=0,c=0,l=0,d=0,h=0,u=0;const p=t.nodeMap.get(r.prevCandidate?.currentNodeId);if(p&&r.prevCandidate&&r.portPoint&&n){const e=n.connection.name,o={x:r.prevCandidate.point.x,y:r.prevCandidate.point.y,z:r.prevCandidate.z,connectionName:e},i={x:r.portPoint.x,y:r.portPoint.y,z:r.portPoint.z,connectionName:e},s=t.buildNodeWithPortPointsForCrossing(p,[o,i]),m=lr(s);l=m.numSameLayerCrossings,d=m.numTransitionPairCrossings,h=m.numEntryExitLayerChanges;const g=t.capacityMeshNodeMap.get(p.capacityMeshNodeId);g&&(c=t.JUMPER_PF_FN_ENABLED&&1===p.availableZ.length?Gs(g,l):Ys(g,l,h,d),a=c**2*t.NODE_PF_FACTOR),u=r.prevCandidate.g>0?r.g-r.prevCandidate.g:r.g}if(!n)continue;const[m,g]=n.nodeIds,f=t.nodeMap.get(g),y=f?Math.sqrt((s.x-f.center.x)**2+(s.y-f.center.y)**2):0,_=t.avgNodePitch>0?y/t.avgNodePitch:0,b=_*t.BASE_CANDIDATE_COST,x=t.nodeMemoryPfMap.get(r.currentNodeId)??0,v=-Math.log(1-x)*t.MEMORY_PF_FACTOR;e.circles.push({center:s,radius:.03,fill:To(o,.25),layer:`z${r.z}`,label:[`f: ${r.f.toFixed(2)}`,`g: ${r.g.toFixed(2)} (nodeDelta: ${u.toFixed(2)})`,`h: ${r.h.toFixed(2)}`,` dist: ${y.toFixed(2)}`,` estHops: ${_.toFixed(1)}`,` estStepCost: ${b.toFixed(2)}`,` memRiskCost: ${v.toFixed(2)}`,`z: ${r.z}`,`node: ${r.currentNodeId}`,`Cost(Pf): ${a.toFixed(3)}`,`Pf: ${c.toFixed(3)}`,`xSame: ${l}, xTrans: ${d}, xLC: ${h}`,`routeOffBoard=${t.currentConnectionShouldRouteOffBoard}`,`offBoardTouched=${r.hasTouchedOffBoardNode??!1}`,`lastMoveWasOffBoard=${r.lastMoveWasOffBoard??!1}`].join("\n")})}}}return e}function Qs(t,e,n){let o=0;const i=n?.NODE_MAX_PF??.99999;for(const n of t){const t=e.get(n.capacityMeshNodeId);if(!t)continue;if(t._containsTarget)continue;const r=Ms(n),s=Math.min(Gs(t,r.numSameLayerCrossings),i);o+=Math.log(1-s)}return o}var ta=class extends si{constructor(t){super(),this.input=t;const{simpleRouteJson:e,capacityMeshNodes:n,inputNodes:o,colorMap:i,nodeMemoryPfMap:r,hyperParameters:s,precomputedInitialParams:a,fixedRoutes:c}=t;if(this.input=structuredClone(t),this.MAX_ITERATIONS=1e8,this.simpleRouteJson=e,this.inputNodes=o,this.colorMap=i??{},this.capacityMeshNodeMap=new Map(n.map(t=>[t.capacityMeshNodeId,t])),this.nodeMemoryPfMap=r??new Map,this.hyperParameters=s??{},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,o]of t.nodeAssignedPortPoints)e.set(n,[...o]);return{nodeAssignedPortPoints:e}}(a);this.nodeAssignedPortPoints=t,this.connectionsWithResults=Xi(structuredClone(a.unshuffledConnectionsWithResults),this.hyperParameters.SHUFFLE_SEED??0)}else{this.nodeMap=new Map(o.map(t=>[t.capacityMeshNodeId,t]));const t=o.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=o.filter(t=>t._offBoardConnectionId),this.portPointMap=new Map,this.nodePortPointsMap=new Map;for(const t of o)this.nodePortPointsMap.set(t.capacityMeshNodeId,[]),this.nodeAssignedPortPoints.set(t.capacityMeshNodeId,[]);for(const t of o)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}input;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 o=this.computeNodePf(n),i=this.pfToFailureCost(o);return this.baseNodeCostCache.set(t,i),i}computeBoardScore(){const t=this.getNodesWithPortPoints();return this.JUMPER_PF_FN_ENABLED?Qs(t,this.capacityMeshNodeMap):Xs(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 o=this.nodeMap.get(t);if(!o)return 0;const i=this.getBaseNodeFailureCost(t),r=this.computeNodePf(o,[e,n]),s=this.pfToFailureCost(r),a=Math.max(0,s-i);return r>=this.NODE_MAX_PF?this.NODE_PF_MAX_PENALTY:a*this.NODE_PF_FACTOR}getConnectionsWithNodes(){const{unshuffledConnectionsWithResults:t,connectionNameToGoalNodeIds:e}=Fs(this.simpleRouteJson,this.inputNodes);return{connectionsWithResults:Xi(t,this.hyperParameters.SHUFFLE_SEED??0),connectionNameToGoalNodeIds:e}}buildNodeWithPortPointsForCrossing(t,e){const n=this.nodeAssignedPortPoints.get(t.capacityMeshNodeId)??[],o=e?[...n,...e]:n;return{capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:o,availableZ:t.availableZ}}computeNodePf(t,e){if(t._containsTarget)return 0;const n=this.buildNodeWithPortPointsForCrossing(t,e),o=Ms(n);return this.JUMPER_PF_FN_ENABLED&&1===t.availableZ.length?Gs(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),o.numSameLayerCrossings):Ys(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.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,o]=t.connectionNodeIds;return n===e?o:o===e?n:null}computeG(t,e,n,o,i){const r=t.currentNodeId,s=t.point,a={x:s.x,y:s.y,z:t.z,connectionName:o,rootConnectionName:i},c={x:e.x,y:e.y,z:e.z,connectionName:o,rootConnectionName:i},l=this.getNodeDeltaFailureCostForSegment(r,a,c);return t.g+l}computeGToEndTarget(t,e,n,o){const i=t.currentNodeId,r={x:t.point.x,y:t.point.y,z:t.z,connectionName:n,rootConnectionName:o},s={x:e.x,y:e.y,z:t.z,connectionName:n,rootConnectionName:o},a=this.getNodeDeltaFailureCostForSegment(i,r,s);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 o=xe(t,n.center);o<e&&(e=o)}return e}computeH(t,e,n,o,i,r){if(this.RANDOM_WALK_DISTANCE>0&&i<this.RANDOM_WALK_DISTANCE)return 0;if(this.currentConnectionShouldRouteOffBoard&&!r)return this.BASE_COST_FOR_NOT_GOING_OFF_BOARD+this.computeDistanceToNearestOffBoardNode(t);const s=this.nodeMap.get(n);if(!s)return 0;const a=xe(t,s.center),c=this.avgNodePitch>0?a/this.avgNodePitch:0,l=this.clampPf(this.nodeMemoryPfMap.get(e)??0),d=this.pfToFailureCost(l)*this.MEMORY_PF_FACTOR,h=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=be(t,this.currentConnection.connection.pointsToConnect[0],this.currentConnection.connection.pointsToConnect[1]);p=this.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR*e}return a+h+d+u+p}getVisitedPortPointKey(t,e){return this.currentConnectionShouldRouteOffBoard&&e?`${t}:touched_off_board`:t}getAvailableExitPortPoints(t,e){const n=this.currentConnection?.connection.__rootConnectionNames?.[0],o=this.nodePortPointsMap.get(t)??[],i=[];for(const t of o){const o=this.getVisitedPortPointKey(t.portPointId,e);if(this.visitedPortPoints?.has(o))continue;const r=this.assignedPortPoints.get(t.portPointId);r&&r?.rootConnectionName!==n||i.push(t)}return i}getAvailableExitPortPointsWithOmissions(t,e,n){const o=this.nodePortPointsMap.get(t)??[],i=this.currentConnection?.connection.__rootConnectionNames?.[0],r=new Map;for(const e of o){const o=this.getVisitedPortPointKey(e.portPointId,n);if(this.visitedPortPoints?.has(o))continue;const i=this.getOtherNodeId(e,t);if(!i)continue;this.nodeMap.get(i);const s=`${i}|${e.z}`,a=r.get(s)??[];a.push(e),r.set(s,a)}const s=[];for(const[,t]of r){t.sort((t,e)=>t.distToCentermostPortOnZ-e.distToCentermostPortOnZ);const e=t[0];if(!e)continue;const n=this.assignedPortPoints.get(e.portPointId),o=n&&n.rootConnectionName===i;if(!n||o){s.push(e);continue}const r=[...t].sort((t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y),a=[];let c=[];for(const t of r){const e=this.assignedPortPoints.get(t.portPointId);!e||e.rootConnectionName===i?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);s.push(t[e])}}return s}getAvailableExitPortPointsForOffboardConnection(t,e){const n=this.nodeMap.get(t);if(!n)return[];const o=this.currentConnection?.connection.__rootConnectionNames?.[0],i=[];for(const r of n?._offBoardConnectedCapacityMeshNodeIds??[]){if(r===t)continue;if(!this.nodeMap.get(r))continue;const n=this.nodePortPointsMap.get(r)??[];for(const t of n){const n=this.getVisitedPortPointKey(t.portPointId,e);if(this.visitedPortPoints?.has(n))continue;const s=this.assignedPortPoints.get(t.portPointId);s&&s.rootConnectionName!==o||i.push({...t,throughNodeId:r})}}return i}canTravelThroughObstacle(t,e,n){const o=this.connectionNameToGoalNodeIds.get(e);return o?.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),o=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}),o&&o._offBoardConnectionId&&e.push({prevCandidate:null,portPoint:null,currentNodeId:n.prevCandidate.currentNodeId,point:o.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 o=[];for(let i=0;i<t.length;i++){const r=t[i];if(!r.portPoint){const s=0===i,a=i===t.length-1;if(!s&&!a){const t={x:r.point.x,y:r.point.y,z:r.z,connectionName:e,rootConnectionName:n};o.push(t);const i=this.nodeAssignedPortPoints.get(r.currentNodeId)??[];i.push(t),this.nodeAssignedPortPoints.set(r.currentNodeId,i)}continue}const s=r.portPoint;this.assignedPortPoints.set(s.portPointId,{connectionName:e,rootConnectionName:n});const a={portPointId:s.portPointId,x:s.x,y:s.y,z:s.z,connectionName:e,rootConnectionName:n,prevPortPointId:s.prevPortPointId,nextPortPointId:s.nextPortPointId};o.push(a);for(const t of s.connectionNodeIds){const e=this.nodeAssignedPortPoints.get(t)??[];e.push(a),this.nodeAssignedPortPoints.set(t,e)}}const i=o.map(t=>t.portPointId).filter(t=>Boolean(t));let r=0;for(const t of o)t.portPointId&&(t.prevPortPointId=i[r-1],t.nextPortPointId=i[r+1],r+=1);const s=Array.from(new Set(t.map(t=>t.currentNodeId)));for(const t of s){const o=this.nodeMap.get(t);if(o&&o._offBoardConnectionId)for(const t of o?._offBoardConnectedCapacityMeshNodeIds??[]){const o=this.nodePortPointsMap.get(t)??[];for(const t of o)this.assignedPortPoints.set(t.portPointId,{connectionName:e,rootConnectionName:n})}}return o}addTargetPointsToNodes(t,e){const n=t[0],o=t[t.length-1],i=e.pointsToConnect[0],r=e.pointsToConnect[e.pointsToConnect.length-1];if(n&&i){const t=this.nodeAssignedPortPoints.get(n.currentNodeId)??[];t.push({x:i.x,y:i.y,z:n.z,connectionName:e.name,rootConnectionName:e.__rootConnectionNames?.[0]}),this.nodeAssignedPortPoints.set(n.currentNodeId,t)}if(o&&r){const t=this.nodeAssignedPortPoints.get(o.currentNodeId)??[];t.push({x:r.x,y:r.y,z:o.z,connectionName:e.name,rootConnectionName:e.__rootConnectionNames?.[0]}),this.nodeAssignedPortPoints.set(o.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,o]=t.nodeIds,i=this.nodeMap.get(n),r=this.nodeMap.get(o);if(!i||!r)return this.processedConnectionQueue.push(t),this.currentConnection=null,void(this.currentPathIterations=0);const s=t.connection.name,a=t.connection.__rootConnectionNames?.[0],c=t.connection.pointsToConnect[0];if(!this.candidates){if(this.clearCostCaches(),this.FORCE_OFF_BOARD_FREQUENCY>0){const t=$i(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 i.availableZ){const e=c?{x:c.x,y:c.y}:i.center,r={portPointId:`start:${n}:${t}`,x:e.x,y:e.y,z:t,connectionNodeIds:[n,n],distToCentermostPortOnZ:0},s=this.computeH(r,n,o,t,0,!1),a=0+s*this.GREEDY_MULTIPLIER;this.candidates.push({prevCandidate:null,portPoint:null,currentNodeId:n,point:e,z:t,f:a,g:0,h:s,distanceTraveled:0,hasTouchedOffBoardNode:!1})}}this.candidates.sort((t,e)=>t.f-e.f);let l,d=this.candidates.shift();for(;d?.portPoint&&this.visitedPortPoints;){const t=this.getVisitedPortPointKey(d.portPoint.portPointId,d.hasTouchedOffBoardNode);if(!this.visitedPortPoints.has(t))break;d=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),!d)return this.error=`Ran out of candidates on connection ${s}`,this.failedConnection=t,this.processedConnectionQueue.push(t),this.currentConnection=null,this.candidates=null,this.visitedPortPoints=null,this.currentPathIterations=0,void(this.failed=!0);if(d.portPoint&&this.visitedPortPoints){const t=this.getVisitedPortPointKey(d.portPoint.portPointId,d.hasTouchedOffBoardNode);this.visitedPortPoints.add(t)}if(this.isAtEndGoal(d.currentNodeId,o)){const e=t.connection.pointsToConnect[t.connection.pointsToConnect.length-1],n=e?{x:e.x,y:e.y}:r.center,i=this.computeGToEndTarget(d,n,s,a),c={prevCandidate:d,portPoint:null,currentNodeId:o,point:n,z:d.z,g:i,h:0,f:i,distanceTraveled:d.distanceTraveled+xe(d.point,n)},l=this.getBacktrackedPath(c);return t.path=l,t.portPoints=this.assignPortPointsForPath(l,s,a),this.addTargetPointsToNodes(l,t.connection),this.clearCostCaches(),this.RIPPING_ENABLED&&this.processRippingForPath(l,s),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 h=this.nodeMap.get(d.currentNodeId);l=h?._offBoardConnectionId?this.getAvailableExitPortPointsForOffboardConnection(d.currentNodeId,d.hasTouchedOffBoardNode):this.FORCE_CENTER_FIRST?this.getAvailableExitPortPointsWithOmissions(d.currentNodeId,o,d.hasTouchedOffBoardNode):this.getAvailableExitPortPoints(d.currentNodeId,d.hasTouchedOffBoardNode);for(const t of l){if(this.isPortPointInPathChain(d,t.portPointId))continue;if(this.visitedPortPoints?.has(t.portPointId))continue;const e=this.getOtherNodeId(t,t.throughNodeId??d.currentNodeId);if(!e)continue;if(this.isNodeInPathChain(d,e))continue;const n="throughNodeId"in t?t.throughNodeId:void 0,i=n?this.nodeMap.get(n):null,r=this.nodeMap.get(e);if(!r)continue;if(r._containsObstacle&&!this.canTravelThroughObstacle(r,s,a))continue;const c=this.computeG(d,t,e,s,a);if(!this.RIPPING_ENABLED&&c>-this.MIN_ALLOWED_BOARD_SCORE)continue;const l=d.distanceTraveled+xe(d.point,t),u=d.hasTouchedOffBoardNode||Boolean(r._offBoardConnectionId),p=this.computeH(t,e,o,t.z,l,u),m=c+p*this.GREEDY_MULTIPLIER,g=Boolean(h?._offBoardConnectionId)&&Boolean(i?._offBoardConnectionId);this.candidates.push({prevCandidate:d,portPoint:t,currentNodeId:e,point:{x:t.x,y:t.y},z:t.z,f:m,g:c,h:p,distanceTraveled:l,lastMoveWasOffBoard:g,throughNodeId:g?n:void 0,hasTouchedOffBoardNode:u||Boolean(r._offBoardConnectionId)||Boolean(h?._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=[],o=new Set;for(const i of this.connectionsWithResults)if(i.path&&i.connection.name!==e&&!o.has(i.connection.name))for(const e of i.path)if(e.currentNodeId===t){n.push(i),o.add(i.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),o={capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:n,availableZ:t.availableZ},i=Ms(o),r=i.numSameLayerCrossings+i.numEntryExitLayerChanges+i.numTransitionPairCrossings;return{pf:Ys(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),i.numSameLayerCrossings,i.numEntryExitLayerChanges,i.numTransitionPairCrossings),totalCrossings:r}}computeNodeCrossings(t){if(t._containsTarget)return 0;const e=this.buildNodeWithPortPointsForCrossing(t),n=Ms(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 o=n.filter(t=>t.connectionName!==e);this.nodeAssignedPortPoints.set(t,o)}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 o=!1;for(const t of n){if(this.totalRipCount>this.MAX_RIPS)break;const n=this.nodeMap.get(t);if(!n)continue;let i=this.computeNodePf(n);if(i<=this.RIPPING_PF_THRESHOLD)continue;this.testedRipConnections.has(t)||this.testedRipConnections.set(t,new Set);const r=this.testedRipConnections.get(t),s=Xi(this.getConnectionsInNode(t,e),(this.hyperParameters.SHUFFLE_SEED??0)+this.processedConnectionQueue.length);for(const t of s){if(i<=this.RIPPING_PF_THRESHOLD)break;const e=t.connection.name;r.add(e);const{pf:s}=this.computeNodePfWithoutConnection(n,e);this.ripConnection(t);if(!this.requeueConnection(t))return;i=s,o=!0,this.clearCostCaches()}}o&&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)),o=Xi(e,(this.hyperParameters.SHUFFLE_SEED??0)+this.totalRipCount+this.processedConnectionQueue.length);for(let t=0;t<n&&t<o.length&&!(this.totalRipCount>this.MAX_RIPS);t++){const e=o[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 At(Ks(this),t)}},ea=class extends ys{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??Bs(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 ta({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}computeNodePf(t){if(this.winningSolver)return this.winningSolver.computeNodePf(t);const e=this.getSupervisedSolverWithBestFitness();return e?e.solver.computeNodePf(t):null}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 na(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 oa=[{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}],ia=class extends si{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=15;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=oa;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.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 o={capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ},i=this.JUMPER_PF_FN_ENABLED&&1===e.availableZ.length?Gs(e,Ms(o).numSameLayerCrossings):Vs(o,e);t.set(e.capacityMeshNodeId,i)}return t}computeBoardScore(){const t=this.getNodesWithPortPoints();return this.computeScoreForNodes(t)}computeScoreForNodes(t){return this.JUMPER_PF_FN_ENABLED?Qs(t,this.capacityMeshNodeMap):Xs(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 o={capacityMeshNodeId:e,center:t.center,width:t.width,height:t.height,portPoints:n,availableZ:t.availableZ},i=this.JUMPER_PF_FN_ENABLED&&1===t.availableZ.length?Gs(t,Ms(o).numSameLayerCrossings):Vs(o,t);this.nodePfMap.set(e,i)}}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:o,capacityMeshEdges:i,connectionResults:r}=t,{centerOfSectionCapacityNodeId:s,expansionDegrees:a}=e,c=new Map;for(const t of i){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 l=new Set,d=new Set,h=[];for(h.push({nodeId:s,depth:0}),d.add(s);h.length>0;){const{nodeId:t,depth:e}=h.shift();if(l.add(t),e<a){const n=c.get(t)??new Set;for(const t of n)d.has(t)||(d.add(t),h.push({nodeId:t,depth:e+1}))}}const u=n.filter(t=>l.has(t.capacityMeshNodeId)),p=o.filter(t=>l.has(t.capacityMeshNodeId)),m=[],g=[];for(const t of i){const[e,n]=t.nodeIds,o=l.has(e),i=l.has(n);o&&i?m.push(t):(o||i)&&g.push(t)}const f=u.map(t=>{const e=t.portPoints.filter(t=>{const[e,n]=t.connectionNodeIds,o=l.has(e),i=l.has(n);return o||i});return{...t,portPoints:e}}),y=function(t,e){const n=[];for(const o of t){if(!o.path||0===o.path.length)continue;const t=o.connection.name,i=o.connection.__rootConnectionNames?.[0],r=[];for(let t=0;t<o.path.length;t++){const n=o.path[t];e.has(n.currentNodeId)&&r.push(t)}if(0===r.length)continue;const s=r[0],a=r[r.length-1];let c=s,l=a;if(s>0){const t=o.path[0].currentNodeId;(o.nodeIds[0]===t||o.nodeIds[1]===t)&&(c=0)}if(a<o.path.length-1){const t=o.path.length-1,e=o.path[t].currentNodeId;(o.nodeIds[0]===e||o.nodeIds[1]===e)&&(l=t)}const d=o.path.slice(c,l+1),h=c>0,u=l<o.path.length-1;n.push({connectionName:t,rootConnectionName:i,points:d.map(t=>({x:t.point.x,y:t.point.y,z:t.z,nodeId:t.currentNodeId,portPointId:t.portPoint?.portPointId})),originalStartIndex:c,originalEndIndex:l,hasEntryFromOutside:h,hasExitToOutside:u})}return n}(r??[],l);return{centerNodeId:s,expansionDegrees:a,nodeIds:l,inputNodes:f,capacityMeshNodes:p,internalEdges:m,boundaryEdges:g,sectionPaths:y}}(this.getCreatePortPointSectionInput(),t)}getSectionNodesWithPortPoints(t){const e=[];for(const n of t.nodeIds){const t=this.nodeMap.get(n),o=this.capacityMeshNodeMap.get(n);if(!t||!o)continue;const i=this.nodeAssignedPortPoints.get(n)??[];i.length>0&&e.push({capacityMeshNodeId:n,center:t.center,width:t.width,height:t.height,portPoints:i,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,o]of this.nodePfMap.entries()){o*(1-(this.attemptsToFixNode.get(n)??0)/this.MAX_ATTEMPTS_PER_NODE)**2>e&&(e=o,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,o=na(n);if(this.FRACTION_TO_REPLACE>=1)return new Set(e);const i=function(t,e){const n=na(e),o=[...t];for(let t=o.length-1;t>0;t--){const e=Math.floor(n()*(t+1));[o[t],o[e]]=[o[e],o[t]]}return o}(e,n),r=Math.max(1,Math.ceil(i.length*this.FRACTION_TO_REPLACE)),s=new Set(i.slice(0,r));if(this.ALWAYS_RIP_INTERSECTIONS){const n=function(t){const{section:e,nodePfMap:n,capacityMeshNodeMap:o,nodeAssignedPortPoints:i,acceptablePf:r}=t,s=[];for(const t of e.nodeIds){if((n.get(t)??0)<=r)continue;const e=o.get(t);if(!e)continue;const a=i.get(t)??[];if(a.length<2)continue;const c=e.center.x-e.width/2,l=e.center.x+e.width/2,d=e.center.y-e.height/2,h=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],o=e[1];if(n.z!==o.z)continue;const i=Ws(n,c,l,d,h),r=Ws(o,c,l,d,h),s=n.z,a=p.get(s)??[];a.push({connectionName:t,t1:i,t2:r}),p.set(s,a)}const m=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:o,b:i}=e[t];for(let r=t+1;r<e.length;r++){const{connectionName:t,a:a,b:c}=e[r];Math.abs(o-a)<m||Math.abs(o-c)<m||Math.abs(i-a)<m||Math.abs(i-c)<m||(o<a&&a<i&&i<c||a<o&&o<c&&c<i)&&s.push([n,t])}}}}return s}({section:t,nodePfMap:this.nodePfMap,capacityMeshNodeMap:this.capacityMeshNodeMap,nodeAssignedPortPoints:this.nodeAssignedPortPoints,acceptablePf:this.ACCEPTABLE_PF});for(const[t,i]of n){if(s.has(t)||s.has(i))continue;const n=e.includes(t),r=e.includes(i);if(n&&r){const e=o()<.5;s.add(e?t:i)}else n?s.add(t):r&&s.add(i)}}return this.stats.lastRipCount=s.size,s}createSectionSimpleRouteJson(t){const e=[];this.currentSectionCutPathInfo.clear(),this.currentSectionKeptPortPoints.clear(),this.currentSectionFixedRoutes=[];const n=[],o=[];for(const e of this.connectionResults){if(!e.path||0===e.path.length)continue;const[i,r]=e.nodeIds,s=t.nodeIds.has(i),a=t.nodeIds.has(r);s&&a&&(o.push(e),n.push(e.connection.name))}const i=[];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&&(i.push({sectionPath:e,originalResult:t}),n.includes(e.connectionName)||n.push(e.connectionName))}const r=this.determineConnectionsToRip(t,n);for(const t of o)r.has(t.connection.name)&&e.push(t.connection);for(const{sectionPath:t,originalResult:n}of i){if(!r.has(t.connectionName))continue;const o=`__cut__${t.connectionName}__${t.originalStartIndex}`;this.colorMap[o]=this.colorMap[t.connectionName];const i=t.points[0],s=t.points[t.points.length-1],a={name:o,__rootConnectionNames:[t.rootConnectionName??t.connectionName],pointsToConnect:[{x:i.x,y:i.y,layers:[`layer${i.z+1}`]},{x:s.x,y:s.y,layers:[`layer${s.z+1}`]}]};e.push(a),this.currentSectionCutPathInfo.set(o,{sectionPath:t,originalConnectionResult:n})}const s=new Set(n.filter(t=>!r.has(t)));if(s.size>0){for(const e of t.nodeIds){const t=(this.nodeAssignedPortPoints.get(e)??[]).filter(t=>s.has(t.connectionName));t.length>0&&this.currentSectionKeptPortPoints.set(e,t)}for(const t of o)s.has(t.connection.name)&&this.currentSectionFixedRoutes.push(t);for(const{sectionPath:t,originalResult:e}of i)if(s.has(t.connectionName)){const n={connection:{name:t.connectionName,__rootConnectionNames:t.rootConnectionName?[t.rootConnectionName]:void 0,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 o=n.points[0].nodeId;e.add(o);const i=n.points[n.points.length-1].nodeId;e.add(i)}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),o=Bs(e,n);for(const[t,e]of this.currentSectionKeptPortPoints){const n=o.nodeAssignedPortPoints.get(t)??[];o.nodeAssignedPortPoints.set(t,[...n,...e])}return new ea({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:o,fixedRoutes:this.currentSectionFixedRoutes})}reattachSection(t,e,n,o){const i=[],r=[];for(const t of e)t.connection.name.startsWith("__cut__")?r.push(t):i.push(t);const s=new Set(i.map(t=>t.connection.name));this.connectionResults=this.connectionResults.filter(t=>!s.has(t.connection.name)),this.connectionResults.push(...i);for(const[e,n]of this.nodeAssignedPortPoints.entries()){if(!t.nodeIds.has(e))continue;const o=n.filter(t=>!s.has(t.connectionName));this.nodeAssignedPortPoints.set(e,o)}for(const[t,e]of this.assignedPortPoints.entries())s.has(e.connectionName)&&this.assignedPortPoints.delete(t);for(const e of r){const n=this.currentSectionCutPathInfo.get(e.connection.name);if(!n||!e.path)continue;const{sectionPath:o,originalConnectionResult:i}=n,r=i.path;if(!r)continue;const s=o.connectionName;for(const[e,n]of this.nodeAssignedPortPoints.entries()){const o=n.filter(n=>n.connectionName!==s||!t.nodeIds.has(e));this.nodeAssignedPortPoints.set(e,o)}const a=r.slice(0,o.originalStartIndex),c=r.slice(o.originalEndIndex+1),l=[];let d=a.length>0?a[a.length-1]:null;for(const t of e.path){const e={...t,prevCandidate:d};l.push(e),d=e}if(c.length>0&&l.length>0&&(c[0]={...c[0],prevCandidate:l[l.length-1]}),i.path=[...a,...l,...c],e.portPoints)for(const n of e.portPoints){const e={...n,connectionName:s,rootConnectionName:o.rootConnectionName??s};for(const o of t.inputNodes)for(const t of o.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 o.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("__"),o=n>=0?e.slice(0,n):e;return{...t,connectionName:o}}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),o=this.computeScoreForNodes(n),i=this.computeScoreForNodes(t),r=`attempt${this.sectionAttempts}`;if(this.stats.lastSectionScore=i,i>o){const t=this.stats.currentBoardScore;this.stats.lastBoardScore=t;const e=[...this.connectionResults],n=new Map(this.assignedPortPoints),o=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 i=this.computeBoardScore();this.stats.sectionScores[r]=i,i>t?(this.stats.successfulOptimizations++,this.stats.currentBoardScore=i):(this.connectionResults=e,this.assignedPortPoints=n,this.nodeAssignedPortPoints=o,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?Ks(this):this.activeSubSolver?this.activeSubSolver.visualize():this.currentSection?function(t,e){const n={lines:[],points:[],rects:[],circles:[]};for(const e of t.inputNodes){const o=e.capacityMeshNodeId===t.centerNodeId,i=o?"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:i,label:`${e.capacityMeshNodeId}${o?" (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 o of t.sectionPaths){const t=e?.[o.connectionName]??"blue";for(let e=0;e<o.points.length-1;e++){const i=o.points[e],r=o.points[e+1],s=i.z===r.z,a=i.z;let c;c=s?0===a?"5 5":"10 5":"3 3 10",n.lines.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:t,strokeDash:c})}}return n}(this.currentSection,this.colorMap):Ks(this)}},ra=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),o=this.find(e);n!==o&&(this.parent[o]=n)}getGroup(t){const e=this.find(t),n=[];for(const t in this.parent)this.find(t)===e&&n.push(t);return n}},sa=class{point;left=null;right=null;constructor(t){this.point=t}},aa=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 o=Math.floor(t.length/2),i=new sa(t[o]);return o>0&&(i.left=this.buildTree(t.slice(0,o),e+1)),o<t.length-1&&(i.right=this.buildTree(t.slice(o+1),e+1)),i}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,o,i){if(!t)return o;const r=n%2?"x":"y",s=this.distance(e,t.point);s<i&&(o=t.point,i=s);const a=e[r]-t.point[r],c=a<=0?t.left:t.right,l=a<=0?t.right:t.left;return o=this.nearestNeighborSearch(c,e,n+1,o,i),i=this.distance(e,o),Math.abs(a)<i&&(o=this.nearestNeighborSearch(l,e,n+1,o,i)),o}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,o,i){if(!t)return;const r=n%2?"x":"y",s=this.distance(e,t.point);o.push({point:t.point,distance:s});const a=e[r]-t.point[r],c=a<=0?t.left:t.right,l=a<=0?t.right:t.left;this.kNearestNeighborSearch(c,e,n+1,o,i);let d=1/0;o.length>=i&&(o.sort((t,e)=>t.distance-e.distance),d=o[i-1]?.distance||1/0),(Math.abs(a)<d||o.length<i)&&this.kNearestNeighborSearch(l,e,n+1,o,i)}distance(t,e){return Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2)}},ca=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 o=e;for(;o!==n;){const t=this.parent.get(o);this.parent.set(o,n),o=t}return n}union(t,e){const n=this.find(t),o=this.find(e);if(n===o)return!1;const i=this.rank.get(n)||0,r=this.rank.get(o)||0;return i<r?this.parent.set(n,o):i>r?this.parent.set(o,n):(this.parent.set(o,n),this.rank.set(n,i+1)),!0}};function la(t,e={}){if(t.length<=1)return[];const n=[...t],o=new aa(n),i=[],r=Math.min(10,t.length-1);for(const t of n){const e=o.findKNearestNeighbors(t,r+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);i.push({from:t,to:n,weight:e})}}e.extraEdges&&i.push(...e.extraEdges),i.sort((t,e)=>t.weight-e.weight);const s=new ca(n),a=[];for(const t of i)if(s.union(t.from,t.to)&&(a.push(t),a.length===n.length-1))break;return a}var da=(t,e)=>{const n=new Map;for(const o of t.pointsToConnect){if(!o.pointId)continue;const t=e.getNetConnectedToId(o.pointId);if(!t)continue;const i=n.get(t)??[];i.push(o),n.set(t,i)}const o=[];for(const t of n.values()){const e=t[0];if(e)for(const n of t.slice(1))o.push({from:e,to:n,weight:0})}return o},ha=(t,e)=>({zeroWeightEdges:da(t,e),arePointsConnected:(t,n)=>Boolean(t.pointId&&n.pointId&&((t,e,n)=>{const o=t.getNetConnectedToId(e);return!!o&&o===t.getNetConnectedToId(n)})(e,t.pointId,n.pointId))});function ua(t){if(t.pointId)return t.pointId;let e="";return _o(t)?e=t.layer:yo(t)&&t.layers&&(e=t.layers.sort().join("-")),`${t.x.toFixed(4)},${t.y.toFixed(4)},${e}`}function pa(t){if(0===t.length)return[];const e=t.map((t,e)=>`conn_${e}`),n=new ra(e),o=new Map;t.forEach((t,e)=>{const n=`conn_${e}`;t.pointsToConnect.forEach(t=>{const e=ua(t);o.has(e)||o.set(e,[]),o.get(e).push(n)})});for(const t of o.values())if(t.length>1){const e=t[0];for(let o=1;o<t.length;o++)n.union(e,t[o])}const i=new Map;t.forEach((t,e)=>{const o=`conn_${e}`,r=n.find(o);i.has(r)||i.set(r,[]),i.get(r).push(t)});const r=[];for(const t of i.values()){if(1===t.length){r.push(t[0]);continue}const e=new Map,n=new Set;let o=!1;const i=[],s=new Set;let a;t.forEach(t=>{t.pointsToConnect.forEach(t=>e.set(ua(t),t));const r=t.__rootConnectionNames;if(r&&r.length>0)for(const t of r)n.add(t);else n.add(t.name);t.isOffBoard&&(o=!0),t.externallyConnectedPointIds&&i.push(...t.externallyConnectedPointIds),t.__netConnectionName&&s.add(t.__netConnectionName),void 0===a&&void 0!==t.nominalTraceWidth&&(a=t.nominalTraceWidth)});const c={name:t.map(t=>t.name).join("__"),pointsToConnect:Array.from(e.values()),isOffBoard:o,externallyConnectedPointIds:i.length>0?i:void 0,__netConnectionName:s.size>0?Array.from(s).join("__"):void 0,__rootConnectionNames:Array.from(n),nominalTraceWidth:a};r.push(c)}return r}var ma=class extends si{constructor(t,e={},n){super(),this.ogSrj=t,this.colorMap=e;const o=new Map;for(const e of t.buses??[])if(void 0!==e.traceWidth)for(const t of e.connectionNames)o.set(t,Math.max(o.get(t)??0,e.traceWidth));const i=t.connections.map(t=>{const e=o.get(t.name);return void 0===e?t:{...t,nominalTraceWidth:Math.max(t.nominalTraceWidth??0,e)}});this.unprocessedConnections=pa(i),this.newConnections=[],this.initiallyConnectedMap=n}ogSrj;colorMap;getSolverName(){return"NetToPointPairsSolver"}unprocessedConnections;newConnections;initiallyConnectedMap;_step(){if(0===this.unprocessedConnections.length)return void(this.solved=!0);const t=this.unprocessedConnections.pop(),{zeroWeightEdges:e,arePointsConnected:n}=ha(t,this.initiallyConnectedMap);if(2===t.pointsToConnect.length){const[e,o]=t.pointsToConnect;if(e&&o&&n(e,o))return;return void this.newConnections.push({...t,__rootConnectionNames:t.__rootConnectionNames??[t.name]})}const o=la(t.pointsToConnect,{extraEdges:e});let i=0;for(const e of o)n(e.from,e.to)||this.newConnections.push({...t,pointsToConnect:[e.from,e.to],name:`${t.name}_mst${i++}`,__rootConnectionNames:t.__rootConnectionNames??[t.name],__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(e=>{t.points.push({x:e.x,y:e.y,color:"red",label:e.pcb_port_id??e.pointId})});const n=e.pointsToConnect.length**2,o=$i(0),i=new Set;for(let r=0;r<Math.max(n,2*e.pointsToConnect.length);r++){const n=Math.floor(o()*e.pointsToConnect.length),r=Math.floor(o()*e.pointsToConnect.length);i.has(`${n}-${r}`)||(i.add(`${n}-${r}`),t.lines.push({points:[e.pointsToConnect[n],e.pointsToConnect[r]],strokeColor:"rgba(255,0,0,0.25)",label:e.name}))}}),this.newConnections.forEach(e=>{const n=this.colorMap?.[e.name]||"blue";e.pointsToConnect.forEach(e=>{t.points.push({x:e.x,y:e.y,color:n,label:e.pcb_port_id??e.pointId})});for(let o=0;o<e.pointsToConnect.length-1;o++)for(let i=o+1;i<e.pointsToConnect.length;i++)t.lines.push({points:[e.pointsToConnect[o],e.pointsToConnect[i]],strokeColor:n,label:e.name})}),t}},ga=class extends ma{constructor(t,e={},n){const o=t.connections.flatMap(t=>t.pointsToConnect),i=new Map;for(const t of o)t.pointId&&i.set(t.pointId,t);const r=o.map(t=>t.pointId).filter(t=>!!t),s=new ra(r),a=[];for(const e of t.connections)e.isOffBoard?e.pointsToConnect.length>=2&&e.pointsToConnect[0].pointId&&e.pointsToConnect[1].pointId&&s.union(e.pointsToConnect[0].pointId,e.pointsToConnect[1].pointId):a.push(e);super({...t,connections:a},e,n),this.ogSrj=t,this.colorMap=e,this.connectionPointDsu=s,this.connectionPointMap=i,this.ogSrj=t}ogSrj;colorMap;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)),o=this.connectionPointDsu.getGroup(e.pointId).map(t=>this.connectionPointMap.get(t));let i=t,r=e,s=1/0;for(const t of n)for(const e of o){const n=Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2));n<s&&(s=n,i=t,r=e)}return{pointsToConnect:[i,r]}}_step(){if(0===this.unprocessedConnections.length)return void(this.solved=!0);const t=this.unprocessedConnections.pop(),{zeroWeightEdges:e,arePointsConnected:n}=ha(t,this.initiallyConnectedMap);if(2===t.pointsToConnect.length){const[e,o]=t.pointsToConnect;if(e&&o&&n(e,o))return;const i=this._findBestConnectionPointsFromDisjointSets(t.pointsToConnect[0],t.pointsToConnect[1]);return void this.newConnections.push({...t,pointsToConnect:i.pointsToConnect,__rootConnectionNames:t.__rootConnectionNames??[t.name]})}const o=la(t.pointsToConnect,{extraEdges:e});let i=0;for(const e of o){if(n(e.from,e.to))continue;const o=this._findBestConnectionPointsFromDisjointSets(e.from,e.to);this.newConnections.push({...t,pointsToConnect:o.pointsToConnect,name:`${t.name}_mst${i++}`,__rootConnectionNames:t.__rootConnectionNames??[t.name],__netConnectionName:t.__netConnectionName})}}},fa=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],o=this.netMap[e];if(t&&o){t.push(...o),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 o=this.getNetConnectedToId(e);return!!o&&(n===o||o===t||o===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 ya(t,e={}){const n=[],o=[],i=e.color??"gray",r=e.label,s=Xo[t.footprint]??Xo["0603"],a=t.end.x-t.start.x,c=t.end.y-t.start.y,l=Math.abs(a)>Math.abs(c),d=l?s.padLength:s.padWidth,h=l?s.padWidth:s.padLength;return n.push({center:t.start,width:d,height:h,fill:To(i,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper",label:r?`${r} (start)`:void 0}),n.push({center:t.end,width:d,height:h,fill:To(i,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper",label:r?`${r} (end)`:void 0}),o.push({points:[t.start,t.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*s.padWidth,layer:"jumper-body"}),{rects:n,lines:o}}function _a(t,e={}){const n={rects:[],lines:[]};for(const o of t){const{rects:t,lines:i}=ya(o,e);n.rects.push(...t),n.lines.push(...i)}return n}var ba=1e5,xa=.001,va=class extends si{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],o="start-to-end";for(const i of t.hdRoutes){const r=i.route[0],s=i.route[i.route.length-1],a=xe(t.start,r),c=xe(t.start,s),l=xe(t.end,r),d=xe(t.end,s),h=Math.min(a,c,l,d);h<e&&(e=h,n=i,o=Math.min(l,d)<Math.min(a,c)?"end-to-start":"start-to-end")}"start-to-end"===o?(this.start=t.start,this.end=t.end):(this.start=t.end,this.end=t.start);const i=n.route[0],r=n.route[n.route.length-1],s=xe(this.start,i)<=xe(this.start,r)?i:r;this.mergedHdRoute={connectionName:t.connectionName,rootConnectionName:n.rootConnectionName,route:[{x:this.start.x,y:this.start.y,z:s.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&&xe(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",o=1/0;for(let i=0;i<this.remainingHdRoutes.length;i++){const r=this.remainingHdRoutes[i],s=r.route[0],a=r.route[r.route.length-1],c=xe(t,s),l=xe(t,a);let d=1/0;d=t.z===s.z?c<xa?c:ba+c:c<xa?1e3+c:ba+c,d<o&&(o=d,e=i,n="first");let h=1/0;h=t.z===a.z?l<xa?l:ba+l:l<xa?1e3+l:ba+l,h<o&&(o=h,e=i,n="last")}if(-1===e)return void(this.remainingHdRoutes=[]);const i=this.remainingHdRoutes[e];let r;this.remainingHdRoutes.splice(e,1),r="first"===n?i.route:[...i.route].reverse(),xe(t,r[0])<xa&&t.z===r[0].z?this.mergedHdRoute.route.push(...r.slice(1)):this.mergedHdRoute.route.push(...r),this.mergedHdRoute.vias.push(...i.vias),i.jumpers&&this.mergedHdRoute.jumpers.push(...i.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=_a(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 o=this.colorMap[n.connectionName]??"gray";t.lines?.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:o});for(let i=0;i<n.route.length;i++){const r=n.route[i];t.points?.push({x:r.x+(e%2-.5)/500+(i%8-4)/1e3,y:r.y+(e%2-.5)/500+(i%8-4)/1e3,color:o,label:`Route ${n.connectionName} ${r===n.route[0]?"First":r===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:o});if(n.jumpers&&n.jumpers.length>0){const e=_a(n.jumpers,{color:o,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}return t}},Sa=t=>`${Math.round(100*t.x)},${Math.round(100*t.y)},${Math.round(100*t.z)}`,Ia=t=>({startHash:Sa(t.route[0]),endHash:Sa(t.route[t.route.length-1])}),Ca=class extends si{getSolverName(){return"MultipleHighDensityRouteStitchSolver"}unsolvedRoutes;activeSolver=null;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;getClosestEndpointHash(t,e){let n=null,o=1/0;for(const i of t){const t=[i.route[0],i.route[i.route.length-1]];for(const i of t){const t=xe(e,i);t<o&&(o=t,n=Sa(i))}}return n}selectRoutesAlongEndpointPath(t,e,n){if(t.length<=2)return t;const o=this.getClosestEndpointHash(t,e),i=this.getClosestEndpointHash(t,n);if(!o||!i||o===i)return t;const r=new Map;for(let e=0;e<t.length;e++){const{startHash:n,endHash:o}=Ia(t[e]),i=r.get(n)??[];i.push({nextHash:o,routeIndex:e}),r.set(n,i);const s=r.get(o)??[];s.push({nextHash:n,routeIndex:e}),r.set(o,s)}const s=[o],a=new Set([o]),c=new Map;for(;s.length>0;){const t=s.shift();if(t===i)break;for(const e of r.get(t)??[])a.has(e.nextHash)||(a.add(e.nextHash),c.set(e.nextHash,{prevHash:t,routeIndex:e.routeIndex}),s.push(e.nextHash))}if(!a.has(i))return t;const l=new Set;let d=i;for(;d!==o;){const e=c.get(d);if(!e)return t;l.add(e.routeIndex),d=e.prevHash}if(0===l.size)return t;return t.filter((t,e)=>l.has(e))}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 fa({}),o=[],i=new Map;for(let e=0;e<t.hdRoutes.length;e++){const n=t.hdRoutes[e],i=n.route[0],r=n.route[n.route.length-1];o.push([`route_island_${e}`,`${n.connectionName}:${Sa(i)}`,`${n.connectionName}:${Sa(r)}`])}n.addConnections(o);for(const t of o)for(const e of t.slice(1))i.set(e,(i.get(e)??0)+1);this.unsolvedRoutes=[];const r=Array.from(new Set(Object.values(n.idToNetMap)));for(const e of r){const o=n.getIdsConnectedToNet(e),r=t.hdRoutes.filter((t,e)=>o.includes(`route_island_${e}`));if(0===r.length)continue;const s=t.connections.find(t=>t.name===r[0].connectionName),a=r.flatMap(t=>[t.route[0],t.route[t.route.length-1]]),c=[];for(const t of a){const e=`${r[0].connectionName}:${Sa(t)}`;1===i.get(e)&&c.push(t)}if(0===c.length){console.log("no possible endpoints, can't stitch");continue}let l,d;2!==c.length?(l={...s.pointsToConnect[0],z:ko(bo(s.pointsToConnect[0]),t.layerCount)},d={...s.pointsToConnect[1],z:ko(bo(s.pointsToConnect[1]),t.layerCount)}):(l=c[0],d=c[1],xe(l,s.pointsToConnect[1])<xe(d,s.pointsToConnect[0])&&([l,d]=[d,l]));const h=this.selectRoutesAlongEndpointPath(r,l,d);this.unsolvedRoutes.push({connectionName:r[0].connectionName,hdRoutes:h,start:l,end:d})}const s=new Map;for(const t of this.unsolvedRoutes){const e=s.get(t.connectionName);e?e.push(t):s.set(t.connectionName,[t])}this.unsolvedRoutes=Array.from(s.entries()).flatMap(([e,n])=>{if(!n.some(t=>t.hdRoutes.some(t=>t.route.length<2)))return n;const o=t.connections.find(t=>t.name===e);if(!o)return n;const i={...o.pointsToConnect[0],z:ko(bo(o.pointsToConnect[0]),t.layerCount)},r={...o.pointsToConnect[1],z:ko(bo(o.pointsToConnect[1]),t.layerCount)},s=n.flatMap(t=>t.hdRoutes);return[{connectionName:e,hdRoutes:this.selectRoutesAlongEndpointPath(s,i,r),start:i,end:r}]}),this.MAX_ITERATIONS=1e5}_step(){if(this.activeSolver)return this.activeSolver.step(),void(this.activeSolver.solved?(this.activeSolver instanceof va&&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 va({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 o=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e<n.route.length-1;e++){const i=n.route[e],r=n.route[e+1],s=0!==i.z?To(o,.5):o;t.lines?.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:s,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?To(o,.5):o;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:o});if(n.jumpers&&n.jumpers.length>0){const e=_a(n.jumpers,{color:o,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 o of e.hdRoutes){o.route.length>1&&t.lines?.push({points:o.route.map(t=>({x:t.x,y:t.y})),strokeColor:To(n,.5),strokeDash:"10 5"});for(const e of o.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:o.viaDiameter/2,fill:n});if(o.jumpers&&o.jumpers.length>0){const e=_a(o.jumpers,{color:n,label:o.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}}return t}},Pa=class{tree;constructor(t=9){this.tree=new te(t)}insert(t,e,n,o,i){this.tree.insert({minX:e,minY:n,maxX:o,maxY:i,data:t})}bulkLoad(t){const e=t.map(({item:t,minX:e,minY:n,maxX:o,maxY:i})=>({minX:e,minY:n,maxX:o,maxY:i,data:t}));this.tree.load(e)}search(t,e,n,o){return this.tree.search({minX:t,minY:e,maxX:n,maxY:o}).map(t=>t.data)}clear(){this.tree.clear()}},Ma=class{index;items=[];currentIndex=0;capacity;constructor(t){this.capacity=Math.max(1,t),this.index=new Bt(this.capacity)}insert(t,e,n,o,i){if(this.currentIndex>=this.index.numItems)throw new Error("Exceeded initial capacity");this.items[this.currentIndex]=t,this.index.add(e,n,o,i),this.currentIndex++}finish(){this.index.finish()}search(t,e,n,o){return this.index.search(t,e,n,o).map(t=>this.items[t]||null).filter(Boolean)}clear(){this.items=[],this.currentIndex=0,this.index=new Bt(this.capacity)}},Na=class{idx;storage=[];constructor(t="native",e=[]){"flatbush"===t?0===e.length?(this.idx=new Pa,t="rbush"):this.idx=new Ma(e.length):this.idx="rbush"===t?new Pa:new class{shi=new wa(e);insert(t){}search(t,e,n,o){const i=(t+n)/2,r=(e+o)/2,s=n-t,a=o-e;return this.shi.getNodesInArea(i,r,s,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,o){return this.search({minX:t-n/2,minY:e-o/2,maxX:t+n/2,maxY:e+o/2})}},wa=class{constructor(t){this.obstacles=t,this.buckets=new Map;for(let e=0;e<t.length;e++){const n=t[e],o=n.center.x-n.width/2,i=n.center.y-n.height/2,r=n.center.x+n.width/2,s=n.center.y+n.height/2;for(let t=o;t<=r;t+=this.CELL_SIZE)for(let o=i;o<=s;o+=this.CELL_SIZE){const i=this.getBucketKey(t,o),r=this.buckets.get(i);r?r.push([n,e]):this.buckets.set(i,[[n,e]])}}}obstacles;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,o){const i=[],r=new Set,s=e-o/2,a=t+n/2,c=e+o/2;for(let e=t-n/2;e<=a;e+=this.CELL_SIZE)for(let t=s;t<=c;t+=this.CELL_SIZE){const n=this.getBucketKey(e,t),o=this.buckets.get(n)||[];for(const t of o)r.has(t[1])||(r.add(t[1]),i.push(t[0]))}return i}},Ta=(t,e)=>{const n=[],o=Math.abs(e.x-t.x),i=Math.abs(e.y-t.y),r=e.x>t.x?1:-1,s=e.y>t.y?1:-1,a={x:e.x-r*Math.abs(e.y-t.y),y:t.y};(a.x-t.x)*r>=0&&(a.x-e.x)*r<=0&&n.push([t,a,e]);const c={x:t.x,y:e.y-s*Math.abs(e.x-t.x)};(c.y-t.y)*s>=0&&(c.y-e.y)*s<=0&&n.push([t,c,e]);const l=Math.min(o,i),d={x:t.x+r*l,y:t.y+s*l};return(d.x-t.x)*r>=0&&(d.x-e.x)*r<=0&&(d.y-t.y)*s>=0&&(d.y-e.y)*s<=0&&n.push([t,d,e]),n};function Ra(t,e,n,o){if(fe(t,e,n,o))return 0;const i=Ea(t,n,o),r=Ea(e,n,o),s=Ea(n,t,e),a=Ea(o,t,e);return Math.min(i,r,s,a)}function Ea(t,e,n){const o={x:n.x-e.x,y:n.y-e.y},i=Aa({x:t.x-e.x,y:t.y-e.y},o);if(i<=0)return Oa(t,e);const r=Aa(o,o);if(r<=i)return Oa(t,n);const s=i/r;return Oa(t,{x:e.x+s*o.x,y:e.y+s*o.y})}function Aa(t,e){return t.x*e.x+t.y*e.y}function Oa(t,e){const n=e.x-t.x,o=e.y-t.y;return Math.sqrt(n*n+o*o)}var ka=1e-6,La=(t,e,n)=>be(t,e,n)<=ka,Da=(t,e)=>Math.abs(t.x-e.x)<=ka&&Math.abs(t.y-e.y)<=ka,za=(t,e)=>{if(!e||e.length<3)return!1;for(let n=0;n<e.length;n++){const o=e[n],i=e[(n+1)%e.length];if(La(t,o,i))return!0}let n=!1;for(let o=0,i=e.length-1;o<e.length;i=o++){const r=e[o],s=e[i];r.y>t.y!=s.y>t.y&&t.x<(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x&&(n=!n)}return n},Fa=({start:t,end:e,polygon:n,margin:o=.2})=>{if(!n||n.length<3)return!1;const i=za(t,n),r=za(e,n);if(!i||!r)return!0;for(let i=0;i<n.length;i++){const r=n[i],s=n[(i+1)%n.length],a=La(t,r,s),c=La(e,r,s);if(a&&c)continue;if(!fe(t,e,r,s)){if(!a&&!c){if(Ra(t,e,r,s)<o-ka)return!0}continue}const l=ve(t,e,r,s);if((!l||!(a&&Da(l,t)||c&&Da(l,e)))&&(!l||!Da(l,t)&&!Da(l,e)))return!0}return!1},Ba=t=>{const e=[],n=t.route;if(0===n.length)return[];let o={startIndex:0,endIndex:-1,z:n[0].z,points:[n[0]]};for(let t=1;t<n.length;t++)n[t].z===o.z?o.points.push(n[t]):(o.endIndex=t-1,e.push(o),o={startIndex:t,endIndex:-1,z:n[t].z,points:[n[t]]});return o.endIndex=n.length-1,e.push(o),e},ja=({endpointX:t,endpointY:e,targetZ:n,endpointPcbPortId:o,terminalLayerIndicesByPcbPortId:i,obstacleSHI:r,route:s,connMap:a})=>{const c=o?i?.get(o):void 0;if(c&&!c.has(n))return!1;const l=[s.connectionName,s.rootConnectionName].filter(t=>void 0!==t),d=r.searchArea(t,e,2,2).filter(n=>{if(!l.some(t=>n.connectedTo.some(e=>e===t||a.areIdsConnected(t,e))))return!1;const o=n.width/2+.05,i=n.height/2+.05,r=Math.abs(t-n.center.x)<=o,s=Math.abs(e-n.center.y)<=i;return r&&s});return d.length>0&&d.some(t=>t.__zLayers?.includes(n))},$a=({currentSection:t,targetZ:e,route:n,hdRouteSHI:o,obstacleSHI:i,connMap:r,defaultTraceThickness:s,obstacleMargin:a,traceMargin:c,shouldCheckStaticGeometryForSegment:l})=>{const d=n.traceThickness??s,h=c??0,u=[n.connectionName,n.rootConnectionName].filter(t=>void 0!==t);for(let n=0;n<t.points.length-1;n++){const c={...t.points[n],z:e},p={...t.points[n+1],z:e},m=o.getConflictingRoutesForSegment(c,p,d/2+h);for(const{conflictingRoute:t,distance:e}of m){const n=[t.connectionName,t.rootConnectionName].filter(t=>void 0!==t);if(u.some(t=>n.some(e=>e===t||r.areIdsConnected(e,t))))continue;const o=t.traceThickness??s;if(e<d/2+(h>0?Math.max(o/2,t.viaDiameter/2):o/2)+h)return!1}if(!1===l?.(c,p))continue;const g={centerX:(c.x+p.x)/2,centerY:(c.y+p.y)/2,width:Math.abs(c.x-p.x),height:Math.abs(c.y-p.y)},f=d/2+a,y=i.searchArea(g.centerX,g.centerY,g.width+2*f,g.height+2*f);for(const t of y){if(u.some(e=>t.connectedTo.some(t=>t===e||r.areIdsConnected(t,e))))continue;if(t.__zLayers?.includes(e)){if(Math.abs(c.x-t.center.x)<.01&&Math.abs(c.y-t.center.y)<.01||Math.abs(p.x-t.center.x)<.01&&Math.abs(p.y-t.center.y)<.01)continue}if(Le(c,p,t)<f)return!1}}return!0},Ya=class extends si{getSolverName(){return"SingleRouteUselessViaRemovalSolver"}obstacleSHI;hdRouteSHI;unsimplifiedRoute;connMap;outline;terminalLayerIndicesByPcbPortId;routeSections;currentSectionIndex;TRACE_THICKNESS=.15;OBSTACLE_MARGIN=.1;GEOMETRY_SHORTCUT_TRACE_MARGIN=.1;GEOMETRY_SHORTCUT_OBSTACLE_MARGIN=.15;MAX_GEOMETRY_SHORTCUT_ADDED_LENGTH=4;ENABLE_GEOMETRY_SHORTCUTS=!0;ENABLE_OBSTACLE_DETOUR_SHORTCUTS=!1;PRESERVE_ROUTE_ENDPOINTS=!1;geometryShortcutsApplied=0;multilayerSectionsCollapsed=0;obstacleDetourCandidatesValidated=0;constructor(t){super(),this.currentSectionIndex=0,this.obstacleSHI=t.obstacleSHI,this.hdRouteSHI=t.hdRouteSHI,this.unsimplifiedRoute=t.unsimplifiedRoute,this.connMap=t.connMap,this.outline=t.outline,this.terminalLayerIndicesByPcbPortId=t.terminalLayerIndicesByPcbPortId,this.GEOMETRY_SHORTCUT_TRACE_MARGIN=t.geometryShortcutTraceMargin??this.GEOMETRY_SHORTCUT_TRACE_MARGIN,this.GEOMETRY_SHORTCUT_OBSTACLE_MARGIN=t.geometryShortcutObstacleMargin??this.GEOMETRY_SHORTCUT_OBSTACLE_MARGIN,this.ENABLE_GEOMETRY_SHORTCUTS=t.enableGeometryShortcuts??!0,this.ENABLE_OBSTACLE_DETOUR_SHORTCUTS=t.enableObstacleDetourShortcuts??!1,this.PRESERVE_ROUTE_ENDPOINTS=t.preserveRouteEndpoints??!1,this.routeSections=Ba(this.unsimplifiedRoute)}getPathLength(t){let e=0;for(let n=1;n<t.length;n++)e+=Math.hypot(t[n].x-t[n-1].x,t[n].y-t[n-1].y);return e}normalizeShortcutPath(t,e,n){const o=t.filter((e,n)=>{const o=t[n-1];return!o||e.x!==o.x||e.y!==o.y});return o.map((t,i)=>0===i?{...e}:i===o.length-1?{...n}:{x:t.x,y:t.y,z:e.z})}shortcutCrossesOutline(t){if(!this.outline||this.outline.length<3)return!1;for(let e=1;e<t.length;e++)if(Fa({start:t[e-1],end:t[e],polygon:this.outline}))return!0;return!1}getObstacleDetourPaths(t,e,n,o){const i=(this.unsimplifiedRoute.traceThickness??this.TRACE_THICKNESS)/2+this.GEOMETRY_SHORTCUT_OBSTACLE_MARGIN+1e-6,r=this.MAX_GEOMETRY_SHORTCUT_ADDED_LENGTH/2+i,s=Math.min(t.x,e.x)-r,a=Math.max(t.x,e.x)+r,c=Math.min(t.y,e.y)-r,l=Math.max(t.y,e.y)+r,d=this.obstacleSHI.search({minX:s,minY:c,maxX:a,maxY:l}).filter(t=>t.__zLayers?.includes(n));if(0===d.length)return[];const h=new Set,u=new Set;for(const t of d)h.add(t.center.x-t.width/2-i),h.add(t.center.x+t.width/2+i),u.add(t.center.y-t.height/2-i),u.add(t.center.y+t.height/2+i);const p=[],m=new Set,g=n=>{let i=0;for(let t=1;t<n.length;t++)i+=Math.hypot(n[t].x-n[t-1].x,n[t].y-n[t-1].y);if(i>o)return;const r=this.normalizeShortcutPath(n,t,e);let s=0,a=-1;for(let t=0;t<r.length-1;t++){const e=r[t+1].x-r[t].x,n=r[t+1].y-r[t].y,o=e*e+n*n;o>a&&(s=t,a=o)}const c=r.map(t=>`${t.x}:${t.y}`).join("|");m.has(c)||(m.add(c),p.push({path:r,length:i,longestSegmentIndex:s}))};for(const n of u)g([t,{x:t.x,y:n},{x:e.x,y:n},e]);for(const n of h)g([t,{x:n,y:t.y},{x:n,y:e.y},e]);return p}getDirectGeometryShortcut(t,e,n){let o=null;for(let i=0;i<t.points.length;i++){const r=t.points[i];for(let s=0;s<n.points.length;s++){const a=n.points[s],c=[...t.points.slice(i),...e.points,...n.points.slice(0,s+1)];if(!c.some(t=>t.insideJumperPad||t.toNextSegmentType))for(const e of Ta(r,a)){const l=this.normalizeShortcutPath(e,r,a),d=this.getPathLength(c)-this.getPathLength(l);if(d<-1e-6||this.shortcutCrossesOutline(l))continue;const h={startIndex:t.startIndex+i,endIndex:n.startIndex+s,z:t.z,points:l};$a({currentSection:h,targetZ:t.z,route:this.unsimplifiedRoute,hdRouteSHI:this.hdRouteSHI,obstacleSHI:this.obstacleSHI,connMap:this.connMap,defaultTraceThickness:this.TRACE_THICKNESS,obstacleMargin:this.GEOMETRY_SHORTCUT_OBSTACLE_MARGIN,traceMargin:this.GEOMETRY_SHORTCUT_TRACE_MARGIN})&&((!o||d>o.savedLength)&&(o={path:l,previousPointIndex:i,nextPointIndex:s,savedLength:d}))}}}return o}getObstacleDetourShortcut(t,e,n){const o=t.points.length-1,i=[];for(let t=0;t<=o;t++)i.push([t,0]);for(let t=1;t<n.points.length;t++)i.push([o,t]);const r=[];for(const[o,s]of i){const i=t.points[o],a=n.points[s],c=[...t.points.slice(o),...e.points,...n.points.slice(0,s+1)];if(c.some(t=>t.insideJumperPad||t.toNextSegmentType))continue;const l=this.getPathLength(c);for(const{path:e,length:n,longestSegmentIndex:c}of this.getObstacleDetourPaths(i,a,t.z,l+this.MAX_GEOMETRY_SHORTCUT_ADDED_LENGTH+1e-6)){const t=l-n;t<-this.MAX_GEOMETRY_SHORTCUT_ADDED_LENGTH-1e-6||r.push({path:e,previousPointIndex:o,nextPointIndex:s,savedLength:t,validationFirstSegmentIndex:c})}}r.sort((t,e)=>e.savedLength-t.savedLength);let s=0;const a=r.length>=256,c=(({targetZ:t,route:e,hdRouteSHI:n,obstacleSHI:o,connMap:i,defaultTraceThickness:r,obstacleMargin:s,traceMargin:a,useNumericSegmentKeys:c})=>{const l=e.traceThickness??r,d=l/2+a,h=l/2+s,u=e.connectionName,p=e.rootConnectionName,m=new Map,g=new WeakMap,f=new WeakMap,y=c?new Map:void 0;let _=0;const b=t=>{let e=y.get(t.x);e||(e=new Map,y.set(t.x,e));let n=e.get(t.y);return void 0===n&&(n=_++,e.set(t.y,n)),n},x=(t,e)=>{if(c){const n=b(t),o=b(e),i=Math.max(n,o);return i*(i+1)/2+Math.min(n,o)}return t.x<e.x||t.x===e.x&&t.y<=e.y?`${t.x}:${t.y}|${e.x}:${e.y}`:`${e.x}:${e.y}|${t.x}:${t.y}`},v=t=>t===u||i.areIdsConnected(t,u)||void 0!==p&&(t===p||i.areIdsConnected(t,p));return(e,i)=>{const s=e.length-1;for(let c=0;c<s;c++){const s=c-1,u=0===i?c:0===c?i:s>=i?s+1:s,p=e[u],y=e[u+1],_=x(p,y),b=m.get(_);if(void 0!==b){if(!b)return!1;continue}const S=p.z===t?p:{...p,z:t},I=y.z===t?y:{...y,z:t},C={centerX:(S.x+I.x)/2,centerY:(S.y+I.y)/2,width:Math.abs(S.x-I.x),height:Math.abs(S.y-I.y)},P=o.searchArea(C.centerX,C.centerY,C.width+2*h,C.height+2*h);for(const e of P){let n=g.get(e);if((void 0===n&&(n=e.connectedTo.some(v),g.set(e,n)),!n)&&((!e.__zLayers?.includes(t)||!(Math.abs(S.x-e.center.x)<.01&&Math.abs(S.y-e.center.y)<.01||Math.abs(I.x-e.center.x)<.01&&Math.abs(I.y-e.center.y)<.01))&&Le(S,I,e)<h))return m.set(_,!1),!1}const M=n.getConflictingRoutesForSegment(S,I,d);for(const{conflictingRoute:t,distance:e}of M){let n=f.get(t);if(void 0===n&&(n=v(t.connectionName)||void 0!==t.rootConnectionName&&v(t.rootConnectionName),f.set(t,n)),n)continue;const o=t.traceThickness??r,i=Math.max(o/2,t.viaDiameter/2);if(e<l/2+i+a)return m.set(_,!1),!1}m.set(_,!0)}return!0}})({targetZ:t.z,route:this.unsimplifiedRoute,hdRouteSHI:this.hdRouteSHI,obstacleSHI:this.obstacleSHI,connMap:this.connMap,defaultTraceThickness:this.TRACE_THICKNESS,obstacleMargin:this.GEOMETRY_SHORTCUT_OBSTACLE_MARGIN,traceMargin:this.GEOMETRY_SHORTCUT_TRACE_MARGIN,useNumericSegmentKeys:a});for(const t of r){s++;const{path:e}=t;if(c(e,t.validationFirstSegmentIndex??0)&&!this.shortcutCrossesOutline(e))return this.obstacleDetourCandidatesValidated+=s,this.stats.obstacleDetourCandidatesValidated=this.obstacleDetourCandidatesValidated,t}return this.obstacleDetourCandidatesValidated+=s,this.stats.obstacleDetourCandidatesValidated=this.obstacleDetourCandidatesValidated,null}findGeometryShortcut(t,e,n){if(this.unsimplifiedRoute.jumpers?.length)return null;if(this.ENABLE_GEOMETRY_SHORTCUTS){const o=this.getDirectGeometryShortcut(t,e,n);if(o)return o}return this.ENABLE_OBSTACLE_DETOUR_SHORTCUTS?this.getObstacleDetourShortcut(t,e,n):null}applyGeometryShortcut(t){const e=this.routeSections[this.currentSectionIndex-1],n=this.routeSections[this.currentSectionIndex+1],o=[...e.points.slice(0,t.previousPointIndex),...t.path,...n.points.slice(t.nextPointIndex+1)].filter((t,e,n)=>{const o=n[e-1];return!o||t.x!==o.x||t.y!==o.y||t.z!==o.z});this.routeSections.splice(this.currentSectionIndex-1,3,{startIndex:e.startIndex,endIndex:n.endIndex,z:e.z,points:o}),this.geometryShortcutsApplied++,this.stats.geometryShortcutsApplied=this.geometryShortcutsApplied,this.stats.viasRemovedByGeometryShortcuts=2*this.geometryShortcutsApplied,this.currentSectionIndex=Math.max(0,this.currentSectionIndex-1)}findMultilayerSectionCollapse(t,e,n){if(t.z===n.z||this.unsimplifiedRoute.jumpers?.length)return null;const o=t.points[t.points.length-1];if(o?.insideJumperPad||o?.toNextSegmentType||e.points.some(t=>t.insideJumperPad||t.toNextSegmentType))return null;const i=[{targetZ:t.z,mergeWith:"previous"},{targetZ:n.z,mergeWith:"next"}];for(const t of i)if(t.targetZ!==e.z&&$a({currentSection:e,targetZ:t.targetZ,route:this.unsimplifiedRoute,hdRouteSHI:this.hdRouteSHI,obstacleSHI:this.obstacleSHI,connMap:this.connMap,defaultTraceThickness:this.TRACE_THICKNESS,obstacleMargin:this.GEOMETRY_SHORTCUT_OBSTACLE_MARGIN,traceMargin:this.GEOMETRY_SHORTCUT_TRACE_MARGIN}))return t;return null}applyMultilayerSectionCollapse(t){const e=this.routeSections[this.currentSectionIndex-1],n=this.routeSections[this.currentSectionIndex],o=this.routeSections[this.currentSectionIndex+1],i=n.points.map(e=>({...e,z:t.targetZ})),r=t=>t.filter((e,n)=>{const o=t[n-1];return!o||e.x!==o.x||e.y!==o.y||e.z!==o.z});"previous"===t.mergeWith?this.routeSections.splice(this.currentSectionIndex-1,2,{startIndex:e.startIndex,endIndex:n.endIndex,z:t.targetZ,points:r([...e.points,...i])}):this.routeSections.splice(this.currentSectionIndex,2,{startIndex:n.startIndex,endIndex:o.endIndex,z:t.targetZ,points:r([...i,...o.points])}),this.multilayerSectionsCollapsed++,this.stats.multilayerSectionsCollapsed=this.multilayerSectionsCollapsed,this.stats.viasRemovedByMultilayerSectionCollapses=this.multilayerSectionsCollapsed,this.currentSectionIndex=Math.max(0,this.currentSectionIndex-1)}_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(!this.PRESERVE_ROUTE_ENDPOINTS&&t.z!==e.z){const n=e.z,o=t.points[0];if(ja({endpointX:o.x,endpointY:o.y,targetZ:n,endpointPcbPortId:this.unsimplifiedRoute.startPcbPortId,terminalLayerIndicesByPcbPortId:this.terminalLayerIndicesByPcbPortId,obstacleSHI:this.obstacleSHI,route:this.unsimplifiedRoute,connMap:this.connMap})&&$a({currentSection:t,targetZ:n,route:this.unsimplifiedRoute,hdRouteSHI:this.hdRouteSHI,obstacleSHI:this.obstacleSHI,connMap:this.connMap,defaultTraceThickness:this.TRACE_THICKNESS,obstacleMargin:this.OBSTACLE_MARGIN}))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.PRESERVE_ROUTE_ENDPOINTS&&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,o=t.points[t.points.length-1];ja({endpointX:o.x,endpointY:o.y,targetZ:n,endpointPcbPortId:this.unsimplifiedRoute.endPcbPortId,terminalLayerIndicesByPcbPortId:this.terminalLayerIndicesByPcbPortId,obstacleSHI:this.obstacleSHI,route:this.unsimplifiedRoute,connMap:this.connMap})&&$a({currentSection:t,targetZ:n,route:this.unsimplifiedRoute,hdRouteSHI:this.hdRouteSHI,obstacleSHI:this.obstacleSHI,connMap:this.connMap,defaultTraceThickness:this.TRACE_THICKNESS,obstacleMargin:this.OBSTACLE_MARGIN})&&(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){const o=this.findMultilayerSectionCollapse(t,e,n);return o?void this.applyMultilayerSectionCollapse(o):void this.currentSectionIndex++}const o=t.z;if($a({currentSection:e,targetZ:o,route:this.unsimplifiedRoute,hdRouteSHI:this.hdRouteSHI,obstacleSHI:this.obstacleSHI,connMap:this.connMap,defaultTraceThickness:this.TRACE_THICKNESS,obstacleMargin:this.OBSTACLE_MARGIN}))return e.z=o,e.points=e.points.map(t=>({...t,z:o})),void(this.currentSectionIndex+=2);const i=this.findGeometryShortcut(t,e,n);i?this.applyGeometryShortcut(i):this.currentSectionIndex++}getConstructorParams(){return{obstacleSHI:this.obstacleSHI,hdRouteSHI:this.hdRouteSHI,unsimplifiedRoute:this.unsimplifiedRoute,connMap:this.connMap,outline:this.outline,geometryShortcutTraceMargin:this.GEOMETRY_SHORTCUT_TRACE_MARGIN,geometryShortcutObstacleMargin:this.GEOMETRY_SHORTCUT_OBSTACLE_MARGIN,enableGeometryShortcuts:this.ENABLE_GEOMETRY_SHORTCUTS,enableObstacleDetourShortcuts:this.ENABLE_OBSTACLE_DETOUR_SHORTCUTS,preserveRouteEndpoints:this.PRESERVE_ROUTE_ENDPOINTS,terminalLayerIndicesByPcbPortId:this.terminalLayerIndicesByPcbPortId}}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,startPcbPortId:this.unsimplifiedRoute.startPcbPortId,endPcbPortId:this.unsimplifiedRoute.endPcbPortId,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}},Xa=class extends si{constructor(t){super(),this.input=t,this.input={...t,obstacles:Kr(t.obstacles,t.layerCount)},this.MAX_ITERATIONS=1e6,this.unsimplifiedHdRoutes=t.unsimplifiedHdRoutes,this.optimizedHdRoutes=[],this.unprocessedRoutes=[...t.unsimplifiedHdRoutes],this.obstacleSHI=new Na("flatbush",this.input.obstacles),this.hdRouteSHI=new ji([...this.unsimplifiedHdRoutes,...t.otherHdRoutes??[]])}input;getSolverName(){return"UselessViaRemovalSolver"}unsimplifiedHdRoutes;optimizedHdRoutes;unprocessedRoutes;activeSubSolver=null;obstacleSHI=null;hdRouteSHI=null;_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){const t=this.activeSubSolver.getOptimizedHdRoute();this.hdRouteSHI.removeRoute(t.connectionName),this.hdRouteSHI.addRoute(t),this.optimizedHdRoutes.push(t),this.activeSubSolver=null}else(this.activeSubSolver.failed||this.activeSubSolver.error)&&(this.error=this.activeSubSolver.error,this.failed=!0);return}const t=this.unprocessedRoutes.shift();t?this.activeSubSolver=new Ya({hdRouteSHI:this.hdRouteSHI,obstacleSHI:this.obstacleSHI,unsimplifiedRoute:t,connMap:this.input.connMap,outline:this.input.outline,geometryShortcutTraceMargin:this.input.geometryShortcutTraceMargin,geometryShortcutObstacleMargin:this.input.geometryShortcutObstacleMargin,enableGeometryShortcuts:this.input.enableGeometryShortcuts,enableObstacleDetourShortcuts:this.input.enableObstacleDetourShortcuts,preserveRouteEndpoints:this.input.preserveRouteEndpoints,terminalLayerIndicesByPcbPortId:this.input.terminalLayerIndicesByPcbPortId}):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 o=e.__zLayers?.includes(0),i=e.__zLayers?.includes(1);o&&i?n="rgba(128, 0, 128, 0.2)":o?n="rgba(255, 0, 0, 0.2)":i&&(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 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: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 o=_a(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...o.rects??[]),t.lines.push(...o.lines??[])}}return this.activeSubSolver&&t.lines.push(...this.activeSubSolver.visualize().lines??[]),t}},Va=class extends si{getSolverName(){return"SingleSimplifiedPathSolver"}newRoute;newVias;headIndex=0;tailIndex=0;inputRoute;otherHdRoutes;obstacles;connMap;colorMap;outline;minBoardEdgeClearance;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.minBoardEdgeClearance=t.minBoardEdgeClearance??.2,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,minBoardEdgeClearance:this.minBoardEdgeClearance}}get simplifiedRoute(){return{connectionName:this.inputRoute.connectionName,rootConnectionName:this.inputRoute.rootConnectionName,startPcbPortId:this.inputRoute.startPcbPortId,endPcbPortId:this.inputRoute.endPcbPortId,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,o]of e)t.lines.push({points:[n,o]})}return t}},Wa=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)}),Ha=class{constructor(t,e=.4){this.segments=t,this.buckets=new Map,this.SEGMENT_MARGIN=e;const n=new Map;for(const e of t){const t=this.getSegmentKey(e);if(n.has(t))continue;n.set(t,e);const o=Wa(e),i=Math.floor(o.minX/this.CELL_SIZE),r=Math.floor(o.maxX/this.CELL_SIZE),s=Math.floor(o.minY/this.CELL_SIZE),a=Math.floor(o.maxY/this.CELL_SIZE);for(let n=i;n<=r;n++)for(let o=s;o<=a;o++){const i=`${n}x${o}`,r=this.buckets.get(i),s=[e[0],e[1],t];r?r.push(s):this.buckets.set(i,[s])}}}segments;buckets;CELL_SIZE=.4;SEGMENT_MARGIN;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=[],o=new Set,i=Math.min(t.x,e.x)-this.SEGMENT_MARGIN,r=Math.min(t.y,e.y)-this.SEGMENT_MARGIN,s=Math.max(t.x,e.x)+this.SEGMENT_MARGIN,a=Math.max(t.y,e.y)+this.SEGMENT_MARGIN,c=Math.floor(i/this.CELL_SIZE),l=Math.floor(s/this.CELL_SIZE),d=Math.floor(r/this.CELL_SIZE),h=Math.floor(a/this.CELL_SIZE);for(let t=c;t<=l;t++)for(let e=d;e<=h;e++){const i=`${t}x${e}`,r=this.buckets.get(i);if(r)for(const t of r){const e=t[2];o.has(e)||(o.add(e),n.push(t))}}return n}},Ga=class extends Va{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=[];traceThicknessByObstacleSegmentId=new Map;filteredVias=[];filteredJumperPads=[];jumperPadPointIndices=new Set;segmentTree;OBSTACLE_MARGIN=.1;TRACE_THICKNESS=.15;useTraceWidthAwareClearance=!1;clearanceTraceThickness=this.TRACE_THICKNESS;TAIL_JUMP_RATIO=.8;isSameNetRoute(t){const e=[this.inputRoute.connectionName,this.inputRoute.rootConnectionName].filter(t=>void 0!==t),n=[t.connectionName,t.rootConnectionName].filter(t=>void 0!==t);return e.some(t=>n.some(e=>t===e||this.connMap.areIdsConnected(t,e)))}constructor(t){if(super(t),this.cachedValidPathSegments=new Set,this.useTraceWidthAwareClearance=t.useTraceWidthAwareClearance??!1,this.clearanceTraceThickness=this.useTraceWidthAwareClearance?this.inputRoute.traceThickness:this.TRACE_THICKNESS,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=this.useTraceWidthAwareClearance?Math.max(0,...this.otherHdRoutes.flatMap(t=>[t.traceThickness,...t.route.map(e=>e.traceThickness??t.traceThickness)])):this.TRACE_THICKNESS,o=this.useTraceWidthAwareClearance?this.OBSTACLE_MARGIN+this.clearanceTraceThickness/2+n/2:this.OBSTACLE_MARGIN+this.TRACE_THICKNESS,i={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=Ee(t),o=Ee(e),i=Math.max(n.minX-o.maxX,o.minX-n.maxX,0),r=Math.max(n.minY-o.maxY,o.minY-n.maxY,0);return Math.hypot(i,r)}(i,t)<this.OBSTACLE_MARGIN+this.clearanceTraceThickness/2}),this.filteredObstaclePathSegments=this.otherHdRoutes.flatMap(t=>{if(this.isSameNetRoute(t))return[];const n=t.route,i=[];for(let r=0;r<n.length-1;r++){const s=n[r],a=n[r+1];if(ke(s,a,e)<=o){i.push([s,a]);const e=`${s.x}-${s.y}-${s.z}-${a.x}-${a.y}-${a.z}`;if(this.useTraceWidthAwareClearance){const n=Math.max(s.traceThickness??t.traceThickness,a.traceThickness??t.traceThickness);this.traceThicknessByObstacleSegmentId.set(e,Math.max(this.traceThicknessByObstacleSegmentId.get(e)??0,n))}}}return i}),this.segmentTree=this.useTraceWidthAwareClearance?new Ha(this.filteredObstaclePathSegments,o):new Ha(this.filteredObstaclePathSegments),this.filteredVias=this.otherHdRoutes.flatMap(t=>{if(this.isSameNetRoute(t))return[];const n=t.vias,o=[];for(const i of n){const n=this.OBSTACLE_MARGIN+this.clearanceTraceThickness/2+t.viaDiameter/2,r=i.x-n,s=i.x+n,a=i.y-n,c=i.y+n;r<=e.maxX&&s>=e.minX&&a<=e.maxY&&c>=e.minY&&o.push({...i,diameter:t.viaDiameter})}return o});const r=(t,n)=>{const o=[];for(const i of t){const t=Xo[i.footprint]??Xo["0603"],r=i.end.x-i.start.x,s=i.end.y-i.start.y,a=Math.abs(r)>Math.abs(s),c=a?t.padLength:t.padWidth,l=a?t.padWidth:t.padLength,d=this.OBSTACLE_MARGIN+this.clearanceTraceThickness/2;i.start.x-c/2-d<=e.maxX&&i.start.x+c/2+d>=e.minX&&i.start.y-l/2-d<=e.maxY&&i.start.y+l/2+d>=e.minY&&o.push({center:i.start,width:c,height:l,connectionName:n}),i.end.x-c/2-d<=e.maxX&&i.end.x+c/2+d>=e.minX&&i.end.y-l/2-d<=e.maxY&&i.end.y+l/2+d>=e.minY&&o.push({center:i.end,width:c,height:l,connectionName:n})}return o};if(this.filteredJumperPads=this.otherHdRoutes.flatMap(t=>this.isSameNetRoute(t)?[]:r(t.jumpers??[],t.connectionName)),this.inputRoute.jumpers&&this.inputRoute.jumpers.length>0){this.filteredJumperPads.push(...r(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],o=this.inputRoute.route[e+1],i=Math.sqrt((o.x-n.x)**2+(o.y-n.y)**2)+e/1e4;this.pathSegments.push({start:n,end:o,length:i,startDistance:t,endDistance:t+i}),t+=i}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],o=(n.startDistance+n.endDistance)/2;return t>o?e+1:e}isValidPathSegment(t,e){for(const n of this.filteredObstacles){if(!n.__zLayers?.includes(t.z))continue;if(Le(t,e,n)<this.OBSTACLE_MARGIN+this.clearanceTraceThickness/2)return!1}const n=this.segmentTree.getSegmentsThatCouldIntersect(t,e);for(const[o,i,r]of n)if(o.z===t.z&&i.z===t.z){const n=Ra({x:t.x,y:t.y},{x:e.x,y:e.y},{x:o.x,y:o.y},{x:i.x,y:i.y});if(!this.useTraceWidthAwareClearance){if(n<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS)return!1;continue}const s=this.traceThicknessByObstacleSegmentId.get(r);if(void 0===s)throw new Error(`Missing trace thickness for segment "${r}"`);if(n<this.OBSTACLE_MARGIN+this.clearanceTraceThickness/2+s/2)return!1}for(const n of this.filteredVias)if(be(n,t,e)<this.OBSTACLE_MARGIN+n.diameter/2+this.clearanceTraceThickness/2)return!1;for(const n of this.filteredJumperPads){if(Le(t,e,n)<this.OBSTACLE_MARGIN+this.clearanceTraceThickness/2)return!1}if(this.outline&&this.outline.length>=3){if(Fa({start:{x:t.x,y:t.y},end:{x:e.x,y:e.y},polygon:this.outline,margin:this.minBoardEdgeClearance+this.inputRoute.traceThickness/2}))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=Ta({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}}appendOriginalRouteSlice(t,e){const n=this.pathSegments.findIndex(e=>t>=e.startDistance&&t<=e.endDistance);if(-1===n)throw new Error(`Could not find path segment containing distance ${t}`);for(let t=n+1;t<=e&&t<this.inputRoute.route.length;t++){const e=this.inputRoute.route[t],n=this.newRoute[this.newRoute.length-1];n&&this.arePointsEqual(n,e)||this.newRoute.push({...e})}}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);const o=this.lastValidPath?this.lastValidPathHeadDistance:this.tailDistanceAlongPath;this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null);this.getNearestIndexForDistance(o);return this.appendOriginalRouteSlice(o,this.inputRoute.route.length-1),this.tailDistanceAlongPath=this.totalPathLength,this.headDistanceAlongPath=this.totalPathLength,void(this.solved=!0)}this.moveHead(this.currentStepSize);const n=this.getPointAtDistance(this.tailDistanceAlongPath),o=this.getPointAtDistance(this.headDistanceAlongPath),i=this.getNearestIndexForDistance(this.tailDistanceAlongPath),r=this.getNearestIndexForDistance(this.headDistanceAlongPath);let s=!1,a=-1;for(let t=i;t<r;t++)if(t+1<this.inputRoute.route.length&&this.inputRoute.route[t].z!==this.inputRoute.route[t+1].z){s=!0;const e=t;a=this.pathSegments[e].startDistance;break}if(s&&this.lastHeadMoveDistance>this.minStepSize)return void this.stepBackAndReduceStepSize();let c=!1,l=-1,d=-1;for(let t=i+1;t<=r;t++)if(this.jumperPadPointIndices.has(t)){c=!0,l=t,d=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&&l>=0){const t=this.inputRoute.route[l];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=d,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,void(this.lastValidPathHeadDistance=this.tailDistanceAlongPath)}if(s&&a>0){const t=this.lastValidPath?this.lastValidPathHeadDistance:this.tailDistanceAlongPath,e=this.getNearestIndexForDistance(a)+1,n=this.inputRoute.route[e],o={x:n.x,y:n.y};this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null);const i=this.newRoute[this.newRoute.length-1],r={x:o.x,y:o.y,z:i.z};if(!this.arePointsEqual(i,r)){const n=this.find45DegreePath(i,r);n?this.addPathToResult(n):this.appendOriginalRouteSlice(t,e-1)}this.newVias.push(o),this.newRoute.push({x:o.x,y:o.y,z:n.z}),this.currentStepSize=this.maxStepSize;const s=this.pathSegments.findIndex(t=>t.start===n);if(-1!==s)this.tailDistanceAlongPath=this.pathSegments[s].startDistance,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,this.lastValidPathHeadDistance=this.tailDistanceAlongPath;else if(e<this.inputRoute.route.length){if(e===this.inputRoute.route.length-1)return void(this.solved=!0);console.warn("Fallback used for tailDistanceAlongPath after layer change");const t=this.pathSegments.find(t=>t.start===this.inputRoute.route[e]);t?(this.tailDistanceAlongPath=t.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: ${e}, Point: (${this.inputRoute.route[e].x.toFixed(3)}, ${this.inputRoute.route[e].y.toFixed(3)}, z=${this.inputRoute.route[e].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 h=this.find45DegreePath(n,o);if(!h&&this.lastHeadMoveDistance>this.minStepSize)this.stepBackAndReduceStepSize();else{if(!h&&!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],o=this.inputRoute.route[this.inputRoute.route.length-1];return void(this.arePointsEqual(t,n)||this.arePointsEqual(n,o)||this.newRoute.push(n))}if(h)return this.lastValidPath=h,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 o=this.getPointAtDistance(this.headDistanceAlongPath+this.currentStepSize);t.points.push({x:o.x,y:o.y,color:"red",label:["Tentative Head",`z: ${o.z}`].join("\n")});let i=0;for(;i<this.totalPathLength;){const e=this.getPointAtDistance(i);t.circles.push({center:{x:e.x,y:e.y},radius:.05,fill:"rgba(100, 100, 100, 0.5)"}),i+=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}},Ua=class extends Ga{vertexIndex=0;constructor(t){super(t),this.newRoute=this.inputRoute.route.slice(0,1).map(t=>({...t})),this.newVias=this.inputRoute.vias.map(t=>({...t}))}getSolverName(){return"VertexShortcutPathSolver"}_step(){const t=this.inputRoute.route,e=t[this.vertexIndex];if(this.vertexIndex>=t.length-1)return void(this.solved=!0);let n=this.vertexIndex+1;const o=[0];for(let e=this.vertexIndex;e<t.length-1;e++){const i=t[e],r=t[e+1];if(i.z!==r.z||i.toNextSegmentType||i.traceThickness!==r.traceThickness||void 0!==i.traceThickness&&i.traceThickness!==this.inputRoute.traceThickness||i.insideJumperPad||r.insideJumperPad)break;if(o.push(o.at(-1)+Math.hypot(r.x-i.x,r.y-i.y)),n=e+1,r.pcb_port_id||this.jumperPadPointIndices.has(n))break}for(let i=n;i>this.vertexIndex+1;i--){const n=t[i],r=o[i-this.vertexIndex];for(const t of Ta(e,n)){const o=t.filter((e,n)=>0===n||e.x!==t[n-1].x||e.y!==t[n-1].y).map(t=>({...t,z:e.z,traceThickness:e.traceThickness})),s=o.reduce((t,e,n)=>0===n?t:t+Math.hypot(e.x-o[n-1].x,e.y-o[n-1].y),0);if(!(o.length<2||s>r+1e-9||s>=r-1e-9&&o.length>=i-this.vertexIndex+1)&&this.isValidPath(o))return o[o.length-1]={...n},this.newRoute.push(...o.slice(1)),void(this.vertexIndex=i)}}this.vertexIndex++,this.newRoute.push({...t[this.vertexIndex]})}},Za=class extends si{getSolverName(){return"MultiSimplifiedPathSolver"}simplifiedHdRoutes;currentUnsimplifiedHdRouteIndex=0;activeSubSolver=null;unsimplifiedHdRoutes;otherHdRoutes;obstacles;connMap;colorMap;outline;minBoardEdgeClearance;defaultViaDiameter;useTraceWidthAwareClearance;enableVertexShortcuts;constructor(t){super(),this.MAX_ITERATIONS=1e8,this.unsimplifiedHdRoutes=t.unsimplifiedHdRoutes,this.otherHdRoutes=t.otherHdRoutes??[];const e=Math.max(2,...[...t.unsimplifiedHdRoutes,...this.otherHdRoutes].flatMap(t=>t.route.map(t=>t.z+1)))||2;this.obstacles=Kr(t.obstacles,e),this.connMap=t.connMap||new ti({}),this.colorMap=t.colorMap||{},this.outline=t.outline,this.minBoardEdgeClearance=t.minBoardEdgeClearance??.2,this.defaultViaDiameter=t.defaultViaDiameter??.3,this.useTraceWidthAwareClearance=t.useTraceWidthAwareClearance??!1,this.enableVertexShortcuts=t.enableVertexShortcuts??!1,this.simplifiedHdRoutes=[]}_step(){const t=this.unsimplifiedHdRoutes[this.currentUnsimplifiedHdRouteIndex];if(!this.activeSubSolver)return t?(this.activeSubSolver=new Ga({inputRoute:t,otherHdRoutes:this.otherHdRoutes.concat(this.unsimplifiedHdRoutes.slice(this.currentUnsimplifiedHdRouteIndex+1).concat(this.simplifiedHdRoutes)),obstacles:this.obstacles,connMap:this.connMap,colorMap:this.colorMap,outline:this.outline,minBoardEdgeClearance:this.minBoardEdgeClearance,useTraceWidthAwareClearance:this.useTraceWidthAwareClearance}),void this.currentUnsimplifiedHdRouteIndex++):void(this.solved=!0);if(this.activeSubSolver.step(),this.activeSubSolver.solved){if(this.enableVertexShortcuts&&!(this.activeSubSolver instanceof Ua))return void(this.activeSubSolver=new Ua({inputRoute:this.activeSubSolver.simplifiedRoute,otherHdRoutes:this.activeSubSolver.otherHdRoutes,obstacles:this.obstacles,connMap:this.connMap,colorMap:this.colorMap,outline:this.outline,minBoardEdgeClearance:this.minBoardEdgeClearance,useTraceWidthAwareClearance:this.useTraceWidthAwareClearance}));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 o=0;o<e.route.length-1;o++)t.lines.push({points:[{x:e.route[o].x,y:e.route[o].y},{x:e.route[o+1].x,y:e.route[o+1].y}],strokeWidth:.15,strokeColor:n,strokeDash:1===e.route[o].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}},qa=(t,e)=>{for(let n=0;n<t.route.length-1;n++){const o=t.route[n],i=t.route[n+1];if(o.z===i.z||o.x!==e.x||o.y!==e.y||i.x!==e.x||i.y!==e.y)continue;let r=n;for(;r>0&&t.route[r-1].x===e.x&&t.route[r-1].y===e.y;)r--;let s=n+1;for(;s<t.route.length-1&&t.route[s+1].x===e.x&&t.route[s+1].y===e.y;)s++;if(0===r||s===t.route.length-1)return!0}return!1},Ja=(t,e,n)=>n?.get(e.connectionName)??t.idToNetMap[e.connectionName]??(e.rootConnectionName?t.idToNetMap[e.rootConnectionName]:void 0),Ka=(t,e,n)=>{for(const o of e.connectedTo){if(o===n.net)return!0;if(t.idToNetMap[o]===n.net)return!0;if(t.areIdsConnected(o,n.net))return!0}return!1},Qa=(t,e,n)=>{const o=n.mergedViaHdRoutes[t.routeIndex];if(!o)throw new Error(`SameNetViaMergerSolver could not find route for via at index ${t.routeIndex}`);const i=new Set;for(let e=1;e<o.route.length;e++){const n=o.route[e-1],r=o.route[e];n.z!==r.z&&(n.x===t.x&&n.y===t.y&&r.x===t.x&&r.y===t.y&&(i.add(n.z),i.add(r.z)))}if(0===i.size)throw new Error(`SameNetViaMergerSolver could not find transition layers for via at (${t.x}, ${t.y})`);for(const r of i){const i=o.traceThickness,s={x:t.x,y:t.y,z:r},a={x:e.x,y:e.y,z:r};if(s.x===a.x&&s.y===a.y)continue;const c=n.hdRouteSHI.getConflictingRoutesForSegment(s,a,i/2);for(const{conflictingRoute:e,distance:r}of c){if(e.connectionName===o.connectionName)continue;if(Ja(n.connMap,e,n.netByConnectionName)===t.net)continue;if(r<i/2+e.traceThickness/2)return!1}const l={centerX:(s.x+a.x)/2,centerY:(s.y+a.y)/2,width:Math.abs(s.x-a.x),height:Math.abs(s.y-a.y)},d=i/2+.1,h=n.obstacleSHI.searchArea(l.centerX,l.centerY,l.width+2*d,l.height+2*d);for(const e of h){if(!e.__zLayers)throw new Error(`SameNetViaMergerSolver found obstacle without zLayers near via at (${t.x}, ${t.y})`);if(e.__zLayers.includes(r)&&(!Ka(n.connMap,e,t)&&Le(s,a,e)<d))return!1}}return!0},tc=class extends si{constructor(t){if(super(),this.input=t,!t.connMap)throw new Error("SameNetViaMergerSolver requires connMap");this.input={...t,obstacles:Kr(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 Na("flatbush",this.input.obstacles),this.hdRouteSHI=this.createHdRouteSpatialIndex(),this.vias=[],this.offendingVias=[],this.connMap=t.connMap,this.netByConnectionName=t.netByConnectionName,this.viasByNet=new Map,this.rebuildVias()}input;getSolverName(){return"SameNetViaMergerSolver"}inputHdRoutes;mergedViaHdRoutes;unprocessedRoutes;vias;offendingVias;currentViaRoutes=[];connMap;colorMap;outline;obstacles;viasByNet;netByConnectionName;obstacleSHI;hdRouteSHI;createHdRouteSpatialIndex(){return new ji([...this.mergedViaHdRoutes,...this.input.otherHdRoutes??[]])}rebuildVias(){this.vias=[],this.viasByNet=new Map;const t=(t,e,n)=>{if(0===t.vias.length)return;const o=n?((t,e,n)=>{const o=Ja(t,e,n);if(!o)throw new Error(`SameNetViaMergerSolver could not find net for route "${e.connectionName}"`);return o})(this.connMap,t,this.netByConnectionName):Ja(this.connMap,t,this.netByConnectionName);if(o)for(let i=0;i<t.vias.length;i++){const r=t.vias[i],s=[...new Set(t.route.map(t=>t.z))];if(0===s.length)throw new Error(`SameNetViaMergerSolver found via on route "${t.connectionName}" with no route points`);const a={x:r.x,y:r.y,diameter:t.viaDiameter,net:o,layers:s,routeIndex:e,mutable:n&&!(this.input.preserveRouteEndpoints&&qa(t,r))};this.vias.push(a);const c=this.viasByNet.get(a.net);c?c.push(a):this.viasByNet.set(a.net,[a])}};for(let e=0;e<this.mergedViaHdRoutes.length;e++)t(this.mergedViaHdRoutes[e],e,!0);for(let e=0;e<(this.input.otherHdRoutes?.length??0);e++)t(this.input.otherHdRoutes[e],this.mergedViaHdRoutes.length+e,!1)}getViaKey(t){return[t.mutable?"mutable":"immutable",t.routeIndex,t.x,t.y,t.layers.join(","),t.net].join(":")}dedupeRouteVias(t){const e=new Set;t.vias=t.vias.filter(t=>{const n=`${t.x}:${t.y}`;return!e.has(n)&&(e.add(n),!0)})}getOffendingViaGroupsBatch(){const t=[],e=new Set,n=[];for(const t of this.viasByNet.values()){if(t.length<2)continue;const e=Math.max(1e-6,...t.map(t=>t.diameter)),o=new Map;for(let n=0;n<t.length;n++){const i=t[n],r=`${Math.floor(i.x/e)}:${Math.floor(i.y/e)}`,s=o.get(r);s?s.push(n):o.set(r,[n])}for(let i=0;i<t.length;i++){const r=t[i],s=Math.floor(r.x/e),a=Math.floor(r.y/e),c=Math.ceil(2.5),l=[];for(let e=-c;e<=c;e++)for(let n=-c;n<=c;n++){const c=o.get(`${s+e}:${a+n}`);if(c)for(const e of c){if(e===i)continue;const n=t[e];if(!n.mutable)continue;const o=r.x-n.x,s=r.y-n.y,a=o*o+s*s,c=r.diameter/2+n.diameter/2,d=2.5*c;0!==a?(a<=c*c||a<=d*d&&Qa(n,r,{connMap:this.connMap,mergedViaHdRoutes:this.mergedViaHdRoutes,hdRouteSHI:this.hdRouteSHI,obstacleSHI:this.obstacleSHI,netByConnectionName:this.netByConnectionName}))&&l.push(n):r.mutable||l.push(n)}}l.length>0&&n.push({keep:r,remove:l})}}n.sort((t,e)=>e.remove.length!==t.remove.length?e.remove.length-t.remove.length:t.keep.mutable!==e.keep.mutable?t.keep.mutable?1:-1:e.keep.layers.length!==t.keep.layers.length?e.keep.layers.length-t.keep.layers.length:t.keep.routeIndex-e.keep.routeIndex);for(const o of n){const n=this.getViaKey(o.keep);if(e.has(n))continue;const i=o.remove.filter(t=>!e.has(this.getViaKey(t)));if(0!==i.length){t.push({keep:o.keep,remove:i}),e.add(n);for(const t of i)e.add(this.getViaKey(t))}}return t}moveViaTo(t,e,n=!0){if(!t.mutable)throw new Error("SameNetViaMergerSolver cannot mutate an immutable via anchor");const o=this.mergedViaHdRoutes[t.routeIndex];if(!o)throw new Error(`SameNetViaMergerSolver could not find route for via at index ${t.routeIndex}`);const i=o.route,r=new Set;let s=!1;for(let e=i.length-1;e>=1;e--){const n=i[e-1],o=i[e];if(n.z===o.z)continue;if(n.x!==t.x||n.y!==t.y)continue;if(o.x!==t.x||o.y!==t.y)continue;let s=e-1;for(;s>0&&i[s-1].x===t.x&&i[s-1].y===t.y;)s--;let a=e;for(;a<i.length-1&&i[a+1].x===t.x&&i[a+1].y===t.y;)a++;for(let t=s;t<=a;t++)r.add(t)}if(0===r.size)throw new Error(`SameNetViaMergerSolver could not find route transition for via at (${t.x}, ${t.y}) on route "${o.connectionName}"`);for(const t of r){const n=i[t];i[t]={...n,x:e.x,y:e.y}}if(o.vias=o.vias.flatMap(n=>n.x!==t.x||n.y!==t.y?n:(s=!0,e.mutable?[{x:e.x,y:e.y}]:[])),!s)throw new Error(`SameNetViaMergerSolver could not find via at (${t.x}, ${t.y}) on route "${o.connectionName}"`);this.dedupeRouteVias(o),n&&this.rebuildVias()}_step(){const t=this.getOffendingViaGroupsBatch();if(0===t.length)return void(this.solved=!0);let e=0;for(const n of t)for(const t of n.remove)this.moveViaTo(t,n.keep,!1),e++;this.rebuildVias(),this.hdRouteSHI=this.createHdRouteSpatialIndex(),this.stats.mergedViaGroups=t.length,this.stats.mergedViaCount=e}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){if(!e.__zLayers)throw new Error("SameNetViaMergerSolver found obstacle without zLayers while visualizing");let n="rgba(128, 128, 128, 0.2)";const o=e.__zLayers.includes(0),i=e.__zLayers.includes(1);o&&i?n="rgba(128, 0, 128, 0.2)":o?n="rgba(255, 0, 0, 0.2)":i&&(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];if(!n)throw new Error(`SameNetViaMergerSolver could not find color for route "${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:0===o.z?"rgba(255, 0, 0, 0.5)":"rgba(0, 0, 255, 0.5)",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 o=_a(e.jumpers,{color:n,label:e.connectionName});if(!o.rects||!o.lines)throw new Error(`SameNetViaMergerSolver expected jumper graphics for route "${e.connectionName}"`);t.rects.push(...o.rects),t.lines.push(...o.lines)}}return t}},ec={getConflictingRoutesForSegment:()=>[],getConflictingRoutesNearPoint:()=>[]},nc=1e-6,oc=(t,e)=>{const n=`${t.x}:${t.y}:${t.z}`,o=`${e.x}:${e.y}:${e.z}`;return n<o?`${n}|${o}`:`${o}|${n}`},ic=t=>{const e=new Set;for(let n=1;n<t.route.length;n++){const o=t.route[n-1],i=t.route[n];o.z===i.z&&e.add(oc(o,i))}return e},rc=t=>t.filter((e,n)=>{const o=t[n-1];return!o||e.x!==o.x||e.y!==o.y||e.z!==o.z}),sc=t=>{const e=[],n=new Set;for(let o=1;o<t.length;o++){const i=t[o-1],r=t[o];if(i.z===r.z)continue;if("through_obstacle"===i.toNextSegmentType)continue;if(i.x!==r.x||i.y!==r.y)throw new Error(`CrossingViaReductionSolver found a layer transition without a via at route point ${o}`);const s=`${r.x}:${r.y}`;n.has(s)||(n.add(s),e.push({x:r.x,y:r.y}))}return e},ac=t=>{const e=[t.connectionName];return t.rootConnectionName&&e.push(t.rootConnectionName),e},cc=(t,e,n)=>{const o=ac(t),i=ac(e);return o.some(t=>i.some(e=>t===e||n.areIdsConnected(t,e)))},lc=(t,e,n)=>{const o=ac(e);return t.connectedTo.some(t=>o.some(e=>t===e||n.areIdsConnected(t,e)))},dc=t=>{let e=0;for(let n=1;n<t.length;n++)e+=Math.hypot(t[n].x-t[n-1].x,t[n].y-t[n-1].y);return e},hc=(t,e)=>{const n=dc(t);if(e<=nc||e>=n-nc)return null;let o=0;for(let n=1;n<t.length;n++){const i=t[n-1],r=t[n],s=Math.hypot(r.x-i.x,r.y-i.y);if(o+s<e-nc){o+=s;continue}const a=e-o;if(a<=nc)return{prefix:t.slice(0,n).map(t=>({...t})),suffix:t.slice(n-1).map(t=>({...t})),point:{...i}};if(s-a<=nc)return{prefix:t.slice(0,n+1).map(t=>({...t})),suffix:t.slice(n).map(t=>({...t})),point:{...r}};const c=a/s,l={x:i.x+(r.x-i.x)*c,y:i.y+(r.y-i.y)*c,z:i.z};return{prefix:[...t.slice(0,n),l].map(t=>({...t})),suffix:[l,...t.slice(n)].map(t=>({...t})),point:l}}return null},uc=(t,e,n,o)=>{const i=ve(t,e,n,o);if(!i)return null;const r=Math.hypot(i.x-t.x,i.y-t.y),s=Math.hypot(i.x-e.x,i.y-e.y),a=Math.hypot(i.x-n.x,i.y-n.y),c=Math.hypot(i.x-o.x,i.y-o.y);return Math.min(r,s,a,c)<=nc?null:r},pc=t=>t.points.some(t=>t.insideJumperPad||t.toNextSegmentType),mc=({sections:t,sectionIndex:e,side:n})=>{const o=t[e],i="start"===n?t[e-1]:t[e+1];if(!i)return null;const r="start"===n?o.points[0]:o.points.at(-1),s="start"===n?i.points.at(-1):i.points[0];return r.x!==s.x||r.y!==s.y?null:i.z},gc=({sections:t,sectionIndex:e,targetZ:n,side:o})=>mc({sections:t,sectionIndex:e,side:o})===n,fc=({baseIndexes:t,otherCandidateRoutes:e,ignoredConnectionNames:n,originalRouteSegmentKeys:o})=>{const i=new ji([...e]);return{getConflictingRoutesForSegment:(e,r,s)=>{const a=o.has(oc(e,r));return[...a?[]:t.mutableRoutes.getConflictingRoutesForSegment(e,r,s).filter(({conflictingRoute:t})=>!n.has(t.connectionName)),...a?[]:t.immutableRoutes?.getConflictingRoutesForSegment(e,r,s)??[],...i.getConflictingRoutesForSegment(e,r,s)]},getConflictingRoutesNearPoint:(e,o)=>[...t.mutableRoutes.getConflictingRoutesNearPoint(e,o).filter(({conflictingRoute:t})=>!n.has(t.connectionName)),...t.immutableRoutes?.getConflictingRoutesNearPoint(e,o)??[],...i.getConflictingRoutesNearPoint(e,o)]}},yc=class extends si{input;obstacleSHI;traceMargin;obstacleMargin;reducedHdRoutes;getSolverName(){return"CrossingViaReductionSolver"}constructor(t){super(),this.input={...t,obstacles:Kr(t.obstacles,t.layerCount)},this.traceMargin=t.traceMargin??.1,this.obstacleMargin=t.obstacleMargin??.15,this.reducedHdRoutes=structuredClone([...t.inputHdRoutes]),this.obstacleSHI=new Na("flatbush",[...this.input.obstacles]),this.MAX_ITERATIONS=1e6}collapseDetourSection({route:t,section:e,targetZ:n}){const o=e.points.map(t=>({...t,z:n})),i=rc([...t.route.slice(0,e.startIndex).map(t=>({...t})),...o,...t.route.slice(e.endIndex+1).map(t=>({...t}))]);return{...t,route:i,vias:sc(i)}}relocateTransitionVia({route:t,section:e,targetZ:n,side:o,newViaDistance:i}){const r=hc(e.points,i);if(!r)return null;const s="start"===o?n:e.z,a="start"===o?e.z:n,c=[...r.prefix.map(t=>({...t,z:s})),...r.suffix.map(t=>({...t,z:a}))],l=rc([...t.route.slice(0,e.startIndex).map(t=>({...t})),...c,...t.route.slice(e.endIndex+1).map(t=>({...t}))]);return{route:{...t,route:l,vias:sc(l)},relocatedVia:{x:r.point.x,y:r.point.y}}}relocateTransitionVias({route:t,sections:e,crossingGroups:n,detourZ:o,detourTraceThickness:i}){const r=new Map;for(const t of n){const e=r.get(t.transitionSectionIndex)??[];e.push(t),r.set(t.transitionSectionIndex,e)}const s=[],a=[],c=t.viaDiameter/2+i/2+this.traceMargin+nc;for(const[t,n]of r){if(1!==n.length)return null;const i=e[t],r=n[0];if(!gc({sections:e,sectionIndex:t,targetZ:o,side:r.side}))return null;const l="start"===r.side?Math.max(...r.crossingDistances)+c:Math.min(...r.crossingDistances)-c,d=hc(i.points,l);if(!d)return null;const h="start"===r.side?o:i.z,u="start"===r.side?i.z:o;s.push({section:i,points:[...d.prefix.map(t=>({...t,z:h})),...d.suffix.map(t=>({...t,z:u}))]}),a.push({x:d.point.x,y:d.point.y})}let l=t.route.map(t=>({...t}));for(const t of s.sort((t,e)=>e.section.startIndex-t.section.startIndex))l=[...l.slice(0,t.section.startIndex),...t.points,...l.slice(t.section.endIndex+1)];return l=rc(l),{route:{...t,route:l,vias:sc(l)},relocatedVias:a}}routeIsClear(t,e,n){for(const o of Ba(t)){for(let e=1;e<o.points.length;e++){const i=o.points[e-1],r=o.points[e];if(!n.has(oc(i,r))&&this.input.outline&&Fa({start:i,end:r,polygon:[...this.input.outline],margin:t.traceThickness/2}))return!1}if(!$a({currentSection:o,targetZ:o.z,route:t,hdRouteSHI:e,obstacleSHI:this.obstacleSHI,connMap:this.input.connMap,defaultTraceThickness:t.traceThickness,obstacleMargin:this.obstacleMargin,traceMargin:this.traceMargin,shouldCheckStaticGeometryForSegment:(t,e)=>!n.has(oc(t,e))}))return!1}return!0}relocatedViaIsClear(t,e,n){const o=t.viaDiameter/2;for(let i=0;i<this.input.layerCount;i++){if(n.getConflictingRoutesNearPoint({...e,z:i},o+this.traceMargin).some(({conflictingRoute:e})=>!cc(t,e,this.input.connMap)))return!1}const i=o+this.obstacleMargin,r=this.obstacleSHI.searchArea(e.x,e.y,2*i,2*i);for(const n of r)if(!lc(n,t,this.input.connMap)&&Le(e,e,n)<i)return!1;if(this.input.outline)for(let t=0;t<this.input.outline.length;t++){if(be(e,this.input.outline[t],this.input.outline[(t+1)%this.input.outline.length])<o+this.traceMargin)return!1}return!0}changedSectionsAreStaticallyClear(t,e){for(const n of Ba(t)){if(n.points.some((t,o)=>{const i=n.points[o-1];return void 0!==i&&!e.has(oc(i,t))})){if(this.input.outline)for(let e=1;e<n.points.length;e++)if(Fa({start:n.points[e-1],end:n.points[e],polygon:[...this.input.outline],margin:t.traceThickness/2}))return!1;if(!$a({currentSection:n,targetZ:n.z,route:t,hdRouteSHI:ec,obstacleSHI:this.obstacleSHI,connMap:this.input.connMap,defaultTraceThickness:t.traceThickness,obstacleMargin:Math.min(this.obstacleMargin,.1),traceMargin:this.traceMargin}))return!1}}return!0}candidateIsClear(t,e){const n=[{routeIndex:t.detourRouteIndex,route:t.detourRoute},...t.transitionUpdates],o=new Set(n.map(({routeIndex:t})=>this.reducedHdRoutes[t].connectionName)),i=ic(this.reducedHdRoutes[t.detourRouteIndex]),r=fc({baseIndexes:e,otherCandidateRoutes:t.transitionUpdates.map(({route:t})=>t),ignoredConnectionNames:o,originalRouteSegmentKeys:i});if(this.stats.candidateClearanceChecks=(this.stats.candidateClearanceChecks??0)+1,!this.routeIsClear(t.detourRoute,r,i))return!1;for(const i of t.transitionUpdates){const t=ic(this.reducedHdRoutes[i.routeIndex]),r=fc({baseIndexes:e,otherCandidateRoutes:n.filter(({routeIndex:t})=>t!==i.routeIndex).map(({route:t})=>t),ignoredConnectionNames:o,originalRouteSegmentKeys:t});if(!this.routeIsClear(i.route,r,t)||i.relocatedVias.some(t=>!this.relocatedViaIsClear(i.route,t,r)))return!1}return this.changedSectionsAreStaticallyClear(t.detourRoute,i)}candidateRoutesHaveNoExternalCopperConflicts(t,e){const n=[t.detourRoute,...t.transitionUpdates.map(({route:t})=>t)],o=new Set(n.map(({connectionName:t})=>t)),i=[e.mutableRoutes,...e.immutableRoutes?[e.immutableRoutes]:[]];for(const t of n)for(const e of Ba(t))for(let n=1;n<e.points.length;n++){const r=e.points[n-1],s=e.points[n];for(const e of i){if(e.getConflictingRoutesForSegment(r,s,t.traceThickness/2+this.traceMargin).some(({conflictingRoute:e})=>!o.has(e.connectionName)&&!cc(t,e,this.input.connMap)))return!1}}return!0}buildTransitionSegmentIndex(t,e){const n=[];for(let o=0;o<this.reducedHdRoutes.length;o++){if(this.reducedHdRoutes[o].jumpers?.length)continue;const i=t[o];for(let t=0;t<i.length;t++){const r=i[t];if(!pc(r))for(const s of["start","end"]){const a=mc({sections:i,sectionIndex:t,side:s});if(null===a||a===r.z)continue;if(!e.has(`${r.z}:${a}`))continue;let c=0;for(let e=1;e<r.points.length;e++){const i=r.points[e-1],l=r.points[e],d=Math.hypot(l.x-i.x,l.y-i.y);d>nc&&n.push({routeIndex:o,sectionIndex:t,side:s,adjacentZ:a,start:i,end:l,distanceFromSectionStart:c}),c+=d}}}}if(this.stats.transitionSegmentsIndexed=(this.stats.transitionSegmentsIndexed??0)+n.length,0===n.length)return null;const o=new Ma(n.length);for(const t of n)o.insert(t,Math.min(t.start.x,t.end.x),Math.min(t.start.y,t.end.y),Math.max(t.start.x,t.end.x),Math.max(t.start.y,t.end.y));return o.finish(),o}getIndexedCrossingGroups({detourRouteIndex:t,detourSection:e,targetZ:n,transitionSegmentIndex:o}){const i=new Map;for(let r=1;r<e.points.length;r++){const s=e.points[r-1],a=e.points[r];if(Math.hypot(a.x-s.x,a.y-s.y)<=nc)continue;this.stats.indexedDetourSegmentQueries=(this.stats.indexedDetourSegmentQueries??0)+1;const c=o.search(Math.min(s.x,a.x)-nc,Math.min(s.y,a.y)-nc,Math.max(s.x,a.x)+nc,Math.max(s.y,a.y)+nc);for(const o of c){if(o.routeIndex===t||o.start.z!==n||o.adjacentZ!==e.z)continue;this.stats.exactSegmentIntersectionChecks=(this.stats.exactSegmentIntersectionChecks??0)+1;const r=uc(o.start,o.end,s,a);if(null===r)continue;const c=`${o.routeIndex}:${o.sectionIndex}:${o.side}`;let l=i.get(c);l||(l={transitionRouteIndex:o.routeIndex,transitionSectionIndex:o.sectionIndex,side:o.side,crossingDistances:[]},i.set(c,l)),l.crossingDistances.push(o.distanceFromSectionStart+r)}}return[...i.values()].sort((t,e)=>t.transitionRouteIndex!==e.transitionRouteIndex?t.transitionRouteIndex-e.transitionRouteIndex:t.transitionSectionIndex!==e.transitionSectionIndex?t.transitionSectionIndex-e.transitionSectionIndex:t.side===e.side?0:"start"===t.side?-1:1)}tryCreateCandidate({detourRouteIndex:t,detourSection:e,targetZ:n,transitionRouteIndex:o,transitionSection:i,transitionSections:r,transitionSectionIndex:s,side:a,crossingDistances:c,baseClearanceIndexes:l}){if(!gc({sections:r,sectionIndex:s,targetZ:e.z,side:a}))return null;const d=this.reducedHdRoutes[t],h=this.reducedHdRoutes[o];if(0===c.length)return null;const u=h.viaDiameter/2+d.traceThickness/2+this.traceMargin+nc,p="start"===a?Math.max(...c)+u:Math.min(...c)-u,m=this.relocateTransitionVia({route:h,section:i,targetZ:e.z,side:a,newViaDistance:p});if(!m)return null;const g=this.collapseDetourSection({route:d,section:e,targetZ:n});if(2!==d.vias.length+h.vias.length-g.vias.length-m.route.vias.length)return null;const f={detourRouteIndex:t,detourRoute:g,transitionUpdates:[{routeIndex:o,route:m.route,relocatedVias:[m.relocatedVia]}]};return this.candidateIsClear(f,l)?f:null}tryCreateMultiCrossingCandidate({detourRouteIndex:t,detourSection:e,targetZ:n,crossingGroups:o,sectionsByRoute:i,baseClearanceIndexes:r}){if(o.length<2)return null;const s=this.reducedHdRoutes[t],a=[],c=new Map;for(const t of o){const e=c.get(t.transitionRouteIndex)??[];e.push(t),c.set(t.transitionRouteIndex,e)}for(const[t,n]of c){const o=this.reducedHdRoutes[t],r=this.relocateTransitionVias({route:o,sections:i[t],crossingGroups:n,detourZ:e.z,detourTraceThickness:s.traceThickness});if(!r)return null;a.push({routeIndex:t,route:r.route,relocatedVias:r.relocatedVias})}const l=this.collapseDetourSection({route:s,section:e,targetZ:n});if(s.vias.length+[...c.keys()].reduce((t,e)=>t+this.reducedHdRoutes[e].vias.length,0)-(l.vias.length+a.reduce((t,{route:e})=>t+e.vias.length,0))!==2)return null;this.stats.multiCrossingCandidates=(this.stats.multiCrossingCandidates??0)+1;const d={detourRouteIndex:t,detourRoute:l,transitionUpdates:a};return this.candidateIsClear(d,r)?this.candidateRoutesHaveNoExternalCopperConflicts(d,r)?(this.stats.multiCrossingReductions=(this.stats.multiCrossingReductions??0)+1,this.stats.transitionRoutesMovedByMultiCrossingReductions=(this.stats.transitionRoutesMovedByMultiCrossingReductions??0)+a.length,d):(this.stats.multiCrossingPreexistingConflictRejections=(this.stats.multiCrossingPreexistingConflictRejections??0)+1,null):null}findCrossingReduction(){const t=this.reducedHdRoutes.map(t=>Ba(t)),e=[],n=new Set;for(let o=0;o<this.reducedHdRoutes.length;o++){if(this.reducedHdRoutes[o].jumpers?.length)continue;const i=t[o];for(let t=1;t<i.length-1;t++){const r=i[t-1],s=i[t],a=i[t+1];r.z!==a.z||r.z===s.z||pc(s)||(e.push({routeIndex:o,section:s,targetZ:r.z}),n.add(`${r.z}:${s.z}`))}}if(0===e.length)return null;const o=this.buildTransitionSegmentIndex(t,n);if(!o)return null;let i=null;for(const n of e){const e=n.routeIndex,r=n.section,s=this.reducedHdRoutes[e],a=this.getIndexedCrossingGroups({detourRouteIndex:e,detourSection:r,targetZ:n.targetZ,transitionSegmentIndex:o}).filter(({transitionRouteIndex:t})=>{const e=this.reducedHdRoutes[t];return!e.jumpers?.length&&!cc(s,e,this.input.connMap)}),c=new Map;for(const t of a){const e=`${t.transitionRouteIndex}:${t.transitionSectionIndex}`,n=c.get(e)??[];n.push(t),c.set(e,n)}if(c.size>1){i??={mutableRoutes:new ji(this.reducedHdRoutes),immutableRoutes:this.input.otherHdRoutes?.length?new ji([...this.input.otherHdRoutes]):null};let o=[{groups:[],movement:0}];const a=e=>{const n=this.reducedHdRoutes[e.transitionRouteIndex],o=t[e.transitionRouteIndex][e.transitionSectionIndex],i=n.viaDiameter/2+s.traceThickness/2+this.traceMargin+nc,r="start"===e.side?Math.max(...e.crossingDistances)+i:Math.min(...e.crossingDistances)-i;return"start"===e.side?r:dc(o.points)-r};for(const t of c.values()){const e=t.map(t=>({group:t,movement:a(t)})).sort((t,e)=>t.movement-e.movement);o=o.flatMap(t=>e.map(e=>({groups:[...t.groups,e.group],movement:t.movement+e.movement}))).sort((t,e)=>t.movement-e.movement).slice(0,4)}for(const s of o){const o=this.tryCreateMultiCrossingCandidate({detourRouteIndex:e,detourSection:r,targetZ:n.targetZ,crossingGroups:s.groups,sectionsByRoute:t,baseClearanceIndexes:i});if(o)return o}continue}const l=c.values().next().value??[];for(const o of l){const s=o.transitionRouteIndex,a=t[s],c=a[o.transitionSectionIndex];i??={mutableRoutes:new ji(this.reducedHdRoutes),immutableRoutes:this.input.otherHdRoutes?.length?new ji([...this.input.otherHdRoutes]):null};const l=this.tryCreateCandidate({detourRouteIndex:e,detourSection:r,targetZ:n.targetZ,transitionRouteIndex:s,transitionSection:c,transitionSections:a,transitionSectionIndex:o.transitionSectionIndex,side:o.side,crossingDistances:o.crossingDistances,baseClearanceIndexes:i});if(l)return l}}return null}_step(){const t=this.findCrossingReduction();if(t){this.reducedHdRoutes[t.detourRouteIndex]=t.detourRoute;for(const e of t.transitionUpdates)this.reducedHdRoutes[e.routeIndex]=e.route;this.stats.crossingViaReductions=(this.stats.crossingViaReductions??0)+1,this.stats.viasRemovedByCrossingReductions=(this.stats.viasRemovedByCrossingReductions??0)+2}else this.solved=!0}getReducedHdRoutes(){return this.reducedHdRoutes}visualize(){const t={lines:[],circles:[],rects:[],coordinateSystem:"cartesian",title:"Crossing Via Reduction Solver"};for(const e of this.input.obstacles)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(128, 128, 128, 0.2)"});for(const e of this.reducedHdRoutes){for(let n=1;n<e.route.length;n++){const o=e.route[n-1],i=e.route[n];o.z===i.z&&t.lines.push({points:[o,i],strokeColor:0===o.z?"#d32f2f":"#3367a8",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${o.z})`})}for(const n of e.vias)t.circles.push({center:n,radius:e.viaDiameter/2,fill:"#ff20d6",label:`${e.connectionName} via`})}return t}},_c=1e-6,bc=(t,e)=>Math.abs(t.x-e.center.x)<=e.width/2+_c&&Math.abs(t.y-e.center.y)<=e.height/2+_c,xc=t=>(t.__zLayers?.length??t.layers?.length??0)>1,vc=class extends si{constructor(t){if(super(),this.simplificationConfig=t,this.simplificationConfig={...t,obstacles:Kr(t.obstacles,t.layerCount)},this.hdRoutes=this.markThroughObstacleSegments(t.hdRoutes),t.preserveRouteEndpoints){const e=new Map;for(const n of t.hdRoutes){const t=n.route[0],o=n.route.at(-1);if(!t||!o)throw new Error(`TraceSimplificationSolver cannot preserve endpoints for empty route "${n.connectionName}"`);if(e.has(n.connectionName))throw new Error(`TraceSimplificationSolver cannot preserve endpoints for duplicate route "${n.connectionName}"`);e.set(n.connectionName,{start:{...t},end:{...o}})}this.preservedRouteEndpoints=e}this.MAX_ITERATIONS=1e8}simplificationConfig;getSolverName(){return"TraceSimplificationSolver"}hdRoutes=[];preservedRouteEndpoints;simplificationPipelineLoops=0;MAX_SIMPLIFICATION_PIPELINE_LOOPS=2;PHASE_ORDER=["via_removal","crossing_via_reduction","via_merging","path_simplification"];currentPhase="via_removal";extractResult=null;get simplifiedHdRoutes(){return this.hdRoutes}validatePreservedRouteEndpoints(t){if(!this.preservedRouteEndpoints)return;if(t.length!==this.preservedRouteEndpoints.size)throw new Error(`TraceSimplificationSolver changed the preserved route set (expected ${this.preservedRouteEndpoints.size}, got ${t.length})`);const e=new Set,n=(t,e)=>Math.abs(t.x-e.x)<=_c&&Math.abs(t.y-e.y)<=_c&&t.z===e.z;for(const o of t){if(e.has(o.connectionName))throw new Error(`TraceSimplificationSolver produced duplicate preserved route "${o.connectionName}"`);e.add(o.connectionName);const t=this.preservedRouteEndpoints.get(o.connectionName),i=o.route[0],r=o.route.at(-1);if(!(t&&i&&r&&n(i,t.start)&&n(r,t.end)))throw new Error(`TraceSimplificationSolver changed a preserved endpoint for route "${o.connectionName}"`)}}isSameNetObstacle(t,e){return e.connectedTo.some(e=>e===t.connectionName||e===t.rootConnectionName||this.simplificationConfig.connMap.areIdsConnected(t.connectionName,e)||void 0!==t.rootConnectionName&&this.simplificationConfig.connMap.areIdsConnected(t.rootConnectionName,e))}getSameNetObstacleForSegment(t,e,n){return this.simplificationConfig.obstacles.find(o=>xc(o)&&this.isSameNetObstacle(t,o)&&bc(e,o)&&bc(n,o))}isViaInsideSameNetObstacle(t,e){return this.simplificationConfig.obstacles.some(n=>xc(n)&&this.isSameNetObstacle(t,n)&&bc(e,n))}markThroughObstacleSegments(t){return t.map(t=>({...t,route:t.route.map((e,n,o)=>{const i=o[n+1],r=i&&e.z!==i.z&&this.getSameNetObstacleForSegment(t,e,i);if(r)return{...e,toNextSegmentType:"through_obstacle",...r.circuitJsonMetadata?{toNextSegmentCircuitJsonMetadata:r.circuitJsonMetadata}:{}};const s={...e};return delete s.toNextSegmentType,delete s.toNextSegmentCircuitJsonMetadata,s}),vias:t.vias.filter(e=>!this.isViaInsideSameNetObstacle(t,e))}))}_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){const t=this.extractResult(this.activeSubSolver);this.validatePreservedRouteEndpoints(t),this.hdRoutes=this.markThroughObstacleSegments(t)}if(this.activeSubSolver=null,this.extractResult=null,"via_removal"===this.currentPhase?this.currentPhase=this.simplificationConfig.enableCrossingViaReduction?"crossing_via_reduction":"via_merging":"crossing_via_reduction"===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 Xa({unsimplifiedHdRoutes:this.hdRoutes,otherHdRoutes:[...this.simplificationConfig.otherHdRoutes??[]],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,geometryShortcutTraceMargin:.1,geometryShortcutObstacleMargin:this.simplificationConfig.minTraceToPadEdgeClearance??.15,enableGeometryShortcuts:this.simplificationPipelineLoops>0,enableObstacleDetourShortcuts:!0===this.simplificationConfig.enableCrossingViaReduction&&this.simplificationPipelineLoops>0,preserveRouteEndpoints:this.simplificationConfig.preserveRouteEndpoints,terminalLayerIndicesByPcbPortId:this.simplificationConfig.terminalLayerIndicesByPcbPortId}),this.extractResult=t=>t.getOptimizedHdRoutes()??[];break;case"crossing_via_reduction":this.activeSubSolver=new yc({inputHdRoutes:this.hdRoutes,otherHdRoutes:[...this.simplificationConfig.otherHdRoutes??[]],obstacles:[...this.simplificationConfig.obstacles],connMap:this.simplificationConfig.connMap,layerCount:this.simplificationConfig.layerCount,outline:this.simplificationConfig.outline?[...this.simplificationConfig.outline]:void 0,traceMargin:.1,obstacleMargin:this.simplificationConfig.minTraceToPadEdgeClearance??.15}),this.extractResult=t=>t.getReducedHdRoutes();break;case"via_merging":this.activeSubSolver=new tc({inputHdRoutes:this.hdRoutes,otherHdRoutes:[...this.simplificationConfig.otherHdRoutes??[]],netByConnectionName:this.simplificationConfig.netByConnectionName,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,preserveRouteEndpoints:this.simplificationConfig.preserveRouteEndpoints}),this.extractResult=t=>t.getMergedViaHdRoutes()??[];break;case"path_simplification":this.activeSubSolver=new Za({unsimplifiedHdRoutes:this.hdRoutes,otherHdRoutes:[...this.simplificationConfig.otherHdRoutes??[]],obstacles:[...this.simplificationConfig.obstacles],connMap:this.simplificationConfig.connMap,colorMap:{...this.simplificationConfig.colorMap},outline:this.simplificationConfig.outline?[...this.simplificationConfig.outline]:void 0,minBoardEdgeClearance:this.simplificationConfig.minBoardEdgeClearance,defaultViaDiameter:this.simplificationConfig.defaultViaDiameter,useTraceWidthAwareClearance:this.simplificationConfig.useTraceWidthAwareClearance,enableVertexShortcuts:this.simplificationConfig.enableVertexShortcuts}),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 o=e.__zLayers?.includes(0),i=e.__zLayers?.includes(1);o&&i?n="rgba(128, 0, 128, 0.2)":o?n="rgba(255, 0, 0, 0.2)":i&&(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.simplificationConfig.otherHdRoutes??[]){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:0===o.z?"rgba(160, 32, 32, 0.55)":"rgba(32, 32, 160, 0.55)",strokeWidth:e.traceThickness,strokeDash:[.08,.08],label:`${e.connectionName} immutable (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(96, 96, 96, 0.45)",label:`${e.connectionName} immutable via`})}for(const e of this.hdRoutes)if(0!==e.route.length){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: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 n=_a(e.jumpers,{color:"orange",label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}return t}},Sc=1e-9,Ic=class extends si{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=Kr(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 Na("flatbush",this.obstacles)),this.hdRouteSHI=new ji(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){const e=t.traceThickness??this.minTraceWidth;return this.processedRoutes.push(this.createRouteWithWidth(t,e)),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.createRouteWithWidth(this.currentTrace,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],o=t[this.currentTraceSegmentIndex+1];if(n.insideJumperPad&&o.insideJumperPad){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const i=o.x-n.x,r=o.y-n.y,s=Math.sqrt(i*i+r*r);if(0===s){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const a=this.currentTraceSegmentT*s,c=s-a;if(e<=c){const t=a+e;return this.currentTraceSegmentT=t/s,this.cursorPosition={x:n.x+i*this.currentTraceSegmentT,y:n.y+r*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),o=Math.sqrt((t.center.x-e.end.x)**2+(t.center.y-e.end.y)**2),i=Math.max(t.width,t.height)/2+.01;if(n<i||o<i)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 o=1/0;if(this.lastCollidingObstacles=[],this.lastCollidingRoutes=[],this.obstacleSHI){const i=this.obstacleSHI.searchArea(t.x,t.y,n,n);for(const n of i){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 i=!1;if(this.connMap)for(const t of n.connectedTo)if(this.connMap.areIdsConnected(e,t)){i=!0;break}if(i)continue;if(this.isObstacleOwnJumperPad(n))continue;const r=n.center.x-n.width/2,s=n.center.x+n.width/2,a=n.center.y-n.height/2,c=n.center.y+n.height/2,l=Math.max(r-t.x,0,t.x-s),d=Math.max(a-t.y,0,t.y-c),h=Math.sqrt(l*l+d*d);h<this.currentTargetWidth/2+this.obstacleMargin&&this.lastCollidingObstacles.push(n),h<o&&(o=h)}}const i=this.hdRouteSHI.getConflictingRoutesNearPoint({x:t.x,y:t.y,z:t.z},n);for(const{conflictingRoute:t,distance:n}of i){const i=t.rootConnectionName??t.connectionName;if(i===e)continue;if(this.connMap?.areIdsConnected(e,i))continue;const r=n-(t.traceThickness??.15)/2;r<this.currentTargetWidth/2+this.obstacleMargin&&this.lastCollidingRoutes.push(t),r<o&&(o=r)}return this.lastClearance=o,o}isObstacleOnPointLayer(t,e){return!t.__zLayers||t.__zLayers.includes(e.z)}getAdjacentNonCoincidentRoutePoint(t,e){const n=t.route[e];if(!n)return;const o=0===e?1:-1;for(let i=e+o;i>=0&&i<t.route.length;i+=o){const e=t.route[i];if(xe(e,n)>Sc)return e}}getObstacleWidthAlongVector(t,e){const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.cos(n),i=Math.sin(n),r=o,s=i,a=-i,c=o;return Math.abs(e.x*r+e.y*s)*t.width+Math.abs(e.x*a+e.y*c)*t.height}getTerminalPadWidthLimit(t,e,n){const o=t.route[e];if(!o)return;const i=this.getAdjacentNonCoincidentRoutePoint(t,e);if(!i)return;const r=0===e?Fe(o,i):Fe(i,o);if(xe(r,{x:0,y:0})<=Sc)return;const s={x:-r.y,y:r.x};let a;for(const e of this.obstacles){if(!this.isObstacleOnPointLayer(e,o))continue;if(!fo(e,t,this.connMap))continue;if(Be(o,e)>Sc)continue;const n=this.getObstacleWidthAlongVector(e,s);if(n<=Sc)continue;const i=this.getObstacleWidthAlongVector(e,r)/2;(!a||n<a.width||Math.abs(n-a.width)<=Sc&&i>a.neckDistance)&&(a={width:n,neckDistance:i})}return!a||a.width>=n-Sc?void 0:a}getRouteDistanceInfo(t){const e=[0];let n=0;for(let o=1;o<t.length;o++){const i=t[o-1];n+=xe(t[o],i),e.push(n)}return{distances:e,totalDistance:n}}interpolateRoutePointAtDistance(t,e,n){for(let o=1;o<t.length;o++){const i=e[o-1],r=e[o],s=r-i;if(n>r+Sc)continue;const a=t[o-1],c=t[o];if(s<=Sc)return{...c};const l=Math.max(0,Math.min(1,(n-i)/s));return{x:a.x+(c.x-a.x)*l,y:a.y+(c.y-a.y)*l,z:a.z}}return{...t[t.length-1]}}getTaperWidthAtDistance({distanceFromStart:t,totalDistance:e,startLimit:n,endLimit:o,taperDistance:i,traceWidth:r}){let s=r;if(void 0!==n&&t<=i){const e=Math.min(n.neckDistance,i);if(t<=e)s=Math.min(s,n.width);else{const o=(t-e)/Math.max(i-e,Sc);s=Math.min(s,n.width+(r-n.width)*o)}}if(void 0!==o){const n=e-t;if(n<=i){const t=Math.min(o.neckDistance,i);if(n<=t)s=Math.min(s,o.width);else{const e=(n-t)/Math.max(i-t,Sc);s=Math.min(s,o.width+(r-o.width)*e)}}}return s}createTerminalTaperedRoute(t,e){if(t.route.length<2)return t.route.map(t=>({...t,traceThickness:t.traceThickness??e}));const n=this.getTerminalPadWidthLimit(t,0,e),o=this.getTerminalPadWidthLimit(t,t.route.length-1,e),{distances:i,totalDistance:r}=this.getRouteDistanceInfo(t.route);if(r<=Sc){const i=Math.min(n?.width??e,o?.width??e);return t.route.map(t=>({...t,traceThickness:i}))}const s=Math.min(Math.max(2*e,.75),r/2),a=i.map((t,e)=>({distanceFromStart:t,originalPointIndex:e})),c=[];if(void 0!==n){c.push(n.neckDistance);for(let t=0;t<=8;t++)c.push(s*t/8)}if(void 0!==o){c.push(r-o.neckDistance);for(let t=0;t<=8;t++)c.push(r-s+s*t/8)}for(const t of c){const e=Math.max(0,Math.min(r,t));a.some(t=>Math.abs(t.distanceFromStart-e)<=Sc)||a.push({distanceFromStart:e})}return a.sort((t,e)=>{const n=t.distanceFromStart-e.distanceFromStart;return Math.abs(n)>Sc?n:(t.originalPointIndex??1/0)-(e.originalPointIndex??1/0)}),a.map(a=>{const{distanceFromStart:c}=a,l=void 0!==a.originalPointIndex?{...t.route[a.originalPointIndex]}:this.interpolateRoutePointAtDistance(t.route,i,c);return l.traceThickness=this.getTaperWidthAtDistance({distanceFromStart:c,totalDistance:r,startLimit:n,endLimit:o,taperDistance:s,traceWidth:e}),l})}createRouteWithWidth(t,e){return{connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,traceThickness:e,viaDiameter:t.viaDiameter,route:this.createTerminalTaperedRoute(t,e),vias:[...t.vias],jumpers:t.jumpers}}finalizeCurrentTrace(t){if(!this.currentTrace)return;const e=this.createRouteWithWidth(this.currentTrace,t);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 o=e.has(n.obstacleId),i=n.__zLayers?.includes(0),r=n.__zLayers?.includes(1);let s;s=o?"rgba(255, 0, 0, 0.6)":i&&r?"rgba(128, 0, 128, 0.15)":i?"rgba(255, 0, 0, 0.15)":r?"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:s,stroke:o?"red":void 0,label:o?`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,o=e.traceThickness===this.TRACE_WIDTH_SCHEDULE[1],i=n?"green":o?"yellow":"orange";for(let n=0;n<e.route.length-1;n++){const o=e.route[n],r=e.route[n+1];o.insideJumperPad&&r.insideJumperPad||o.z===r.z&&t.lines.push({points:[{x:o.x,y:o.y},{x:r.x,y:r.y}],strokeColor:i,strokeWidth:o.traceThickness??e.traceThickness,label:`${e.connectionName} (w=${(o.traceThickness??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=_a(e.jumpers,{color:i,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],o=this.currentTrace.route[e+1];n.insideJumperPad&&o.insideJumperPad||n.z===o.z&&t.lines.push({points:[{x:n.x,y:n.y},{x:o.x,y:o.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 o=n.has(e.connectionName);for(let n=0;n<e.route.length-1;n++){const i=e.route[n],r=e.route[n+1];i.z===r.z&&t.lines.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:o?"rgba(255, 0, 0, 0.8)":"rgba(128, 128, 128, 0.3)",strokeWidth:e.traceThickness??this.minTraceWidth,label:o?`COLLIDING: ${e.connectionName}`:e.connectionName})}}return t}getHdRoutesWithWidths(){return this.hdRoutesWithWidths}};function Cc(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var Pc=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.viaDiameter=Yo(t).padDiameter,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),r=n.targetMinCapacity??.5;n.capacityDepth=$s(i,r)}this.connMap=ii(t),this.colorMap=wo(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;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=[Cc("netToPointPairsSolver",ga,t=>[t.srj,t.colorMap,ri(t.srj)],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,this.connMap),t.connMap=ii(t.srjWithPointPairs)}}),Cc("nodeSolver",Kn,t=>[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),Cc("edgeSolver",ui,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Cc("availableSegmentPointSolver",ci,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),Cc("portPointPathingSolver",ea,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,o]=n.nodeIds,i={portPointId:n.segmentPortPointId,x:n.x,y:n.y,z:n.availableZ[0]??0,connectionNodeIds:[t,o],distToCentermostPortOnZ:n.distToCentermostPortOnZ},r=e.get(t);r&&r.portPoints.push(i)}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}}]}),Cc("multiSectionPortPointOptimizer",ia,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}]}),Cc("uniformPortDistributionSolver",go,t=>[{nodeWithPortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],inputNodesWithPortPoints:this.inputNodeWithPortPoints,minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),Cc("highDensityRouteSolver",zs,t=>[{nodePortPoints:t.uniformPortDistributionSolver?.getOutput()??t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],nodePfById:t.multiSectionPortPointOptimizer?.nodePfMap??new Map((t.portPointPathingSolver?.inputNodes??[]).map(e=>[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,effort:t.effort}]),Cc("highDensityStitchSolver",Ca,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),Cc("traceSimplificationSolver",vc,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}]),Cc("traceWidthSolver",Ic,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(),o=this.singleLayerNodeMerger?.visualize(),i=this.strawSolver?.visualize(),r=this.edgeSolver?.visualize(),s=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.portPointPathingSolver?.visualize(),l=this.multiSectionPortPointOptimizer?.visualize(),d=this.uniformPortDistributionSolver?.visualize(),h=this.highDensityRouteSolver?.visualize(),u=this.highDensityStitchSolver?.visualize(),p=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 f=Oo(this.srj),y={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,layer:Fo(e,this.srj.layerCount),label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).filter(t=>!t.isCopperPour).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)",layer:jo(t,this.srj.layerCount),label:f(t)}))],lines:g},_=[y,t,e,n,o,i,r,s,a,c,l,d,h?pi(y,h):null,u,p,this.solved?pi({lines:g},Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(..._)}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 o=n.__netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.__netConnectionName,i=e.filter(t=>t.connectionName===n.name);for(let e=0;e<i.length;e++){const r=i[e],s={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount)};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},Mc=Pc,Nc=class extends si{getSolverName(){return"CapacityEdgeToPortSegmentSolver"}nodes;edges;capacityPaths;nodeMap;nodeEdgeMap;unprocessedNodeIds;nodePortSegments;colorMap;constructor({nodes:t,edges:e,capacityPaths:n,colorMap:o}){super(),this.nodes=t,this.edges=e,this.nodeMap=new Map(t.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=ai(e),this.capacityPaths=n,this.colorMap=o??{},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 o=n.nodeIds.indexOf(t);-1!==o&&e.push({path:n,indexOfNodeInPath:o})}const n=this.nodeMap.get(t),o=[];for(const{path:i,indexOfNodeInPath:r}of e){const e=i.nodeIds[r-1],s=i.nodeIds[r+1];for(const r of[e,s]){const e=this.nodeMap.get(r);if(!e)continue;const s=wc(n,e),a=e.availableZ.filter(t=>n.availableZ.includes(t));if(0===a.length)continue;const c={capacityMeshNodeId:t,start:s.start,end:s.end,connectionNames:[i.connectionName],rootConnectionNames:i.rootConnectionName?[i.rootConnectionName]:void 0,availableZ:a};o.push(c)}}const i=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 o=!1;for(let n=0;n<e.length;n++){const i=e[n],r=Rc(i.start,t.start)&&Rc(i.end,t.end)||Rc(i.start,t.end)&&Rc(i.end,t.start),s=Ec(i.availableZ,t.availableZ);if(r&&s){const e=new Set(i.connectionNames);t.connectionNames.forEach(t=>e.add(t)),i.connectionNames=Array.from(e);const n=new Set(i.rootConnectionNames||[]);t.rootConnectionNames?.forEach(t=>n.add(t)),i.rootConnectionNames=Array.from(n),o=!0;break}}o||e.push(t)}return e}(o);this.nodePortSegments.set(t,i)}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 o=0;o<e.connectionNames.length;o++){const i={x:.05*Math.max(...e.availableZ),y:.05*Math.max(...e.availableZ)},r={x:(e.start.x+e.end.x)/2,y:(e.start.y+e.end.y)/2},s={x:r.x+i.x,y:r.y+i.y};i.x>0&&t.lines.push({points:[r,s],strokeColor:"rgba(0, 0, 0, 0.25)",strokeDash:"5 5"}),t.points.push({x:s.x,y:s.y,label:`${n}: ${e.connectionNames.join(", ")}\navailableZ: ${e.availableZ.join(",")}\nnodePortSegmentId: ${e.nodePortSegmentId}`}),t.lines.push({points:[e.start,e.end],strokeColor:To(this.colorMap[e.connectionNames[o]],.6)})}})}),t}};function wc(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)},o={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<o.end-o.start){const t=(n.start+n.end)/2;return{start:{x:t,y:o.start},end:{x:t,y:o.end}}}{const t=(o.start+o.end)/2;return{start:{x:n.start,y:t},end:{x:n.end,y:t}}}}var Tc=1e-9;function Rc(t,e){return Math.abs(t.x-e.x)<Tc&&Math.abs(t.y-e.y)<Tc}function Ec(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 Ac=class{constructor(t){this.targets=t,this.buckets=new Map;for(let e=0;e<t.length;e++){const n=t[e],o=Math.floor(n.bounds.minX/this.CELL_SIZE)*this.CELL_SIZE,i=Math.floor(n.bounds.minY/this.CELL_SIZE)*this.CELL_SIZE,r=n.bounds.maxX,s=n.bounds.maxY;for(let t=o;t<=r;t+=this.CELL_SIZE)for(let o=i;o<=s;o+=this.CELL_SIZE){const i=this.getBucketKey(t,o),r=this.buckets.get(i);r?r.push([n,e]):this.buckets.set(i,[[n,e]])}}}targets;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,o){const i=[],r=new Set,s=Math.floor((t-n/2)/this.CELL_SIZE)*this.CELL_SIZE,a=Math.floor((e-o/2)/this.CELL_SIZE)*this.CELL_SIZE,c=t+n/2,l=e+o/2;for(let t=s;t<=c;t+=this.CELL_SIZE)for(let e=a;e<=l;e+=this.CELL_SIZE){const n=this.getBucketKey(t,e),o=this.buckets.get(n)||[];for(const t of o)r.has(t[1])||(r.add(t[1]),i.push(t[0]))}return i}},Oc=class extends si{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},o={width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY},i=Math.max(o.width,o.height);this.unfinishedNodes=[{capacityMeshNodeId:this.getNextNodeId(),center:n,width:i,height:i,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 r=Kr(this.srj.obstacles,this.layerCount);for(const[t,e]of this.srj.obstacles.entries())this.obstacleZLayersByObstacle.set(e,r[t].__zLayers);this.obstacleTree=new Na("flatbush",this.srj.obstacles),this.targets=this.computeTargets(),this.targetTree=new Ac(this.targets)}srj;opts;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 o=xo(n),i=this.obstacleTree.searchArea(n.x,n.y,.01,.01).filter(t=>{const e=this.getObstacleZLayers(t);return!(!e||0===e.length)&&e.some(t=>o.some(e=>t===ko(e,this.layerCount)))});let r={minX:n.x-.005,minY:n.y-.005,maxX:n.x+.005,maxY:n.y+.005};i.length>0&&(r={minX:Math.min(...i.map(t=>t.center.x-t.width/2)),minY:Math.min(...i.map(t=>t.center.y-t.height/2)),maxX:Math.max(...i.map(t=>t.center.x+t.width/2)),maxY:Math.max(...i.map(t=>t.center.y+t.height/2))});const s={...n,connectionName:e.name,availableZ:o.map(t=>ko(t,this.layerCount)),bounds:r};t.push(s)}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=[],o=this.getNodeBounds(t),i=o.minX,r=o.maxX,s=o.minY,a=o.maxY,c=t._parent?this.getXYOverlappingObstacles(t._parent):this.srj.obstacles;for(const t of c){const e=t.center.x-t.width/2,o=t.center.x+t.width/2,c=t.center.y-t.height/2,l=t.center.y+t.height/2;r>=e&&i<=o&&a>=c&&s<=l?n.push(t):(i>=e&&r<=o&&s>=c&&a<=l||e>=i&&o<=r&&c>=s&&l<=a)&&n.push(t)}return this.nodeToXYOverlappingObstaclesMap.set(t.capacityMeshNodeId,n),n}getXYZOverlappingObstacles(t){const e=this.getXYOverlappingObstacles(t),n=[];for(const o of e)t.availableZ.some(t=>this.getObstacleZLayers(o).includes(t))&&n.push(o);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(!Re(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(!Te(e,this.outlinePolygon))return!0}for(const t of e){const e=t.center.x-t.width/2,o=t.center.x+t.width/2,i=t.center.y-t.height/2,r=t.center.y+t.height/2;if(n.minX>=e&&n.maxX<=o&&n.minY>=i&&n.maxY<=r)return!0}return!1}getChildNodes(t){if(t._depth===this.MAX_DEPTH)return[];const e=[],n={width:t.width/2,height:t.height/2},o=[{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 i of o){const o={capacityMeshNodeId:this.getNextNodeId(),center:i,width:n.width,height:n.height,layer:t.layer,availableZ:t.availableZ,_depth:(t._depth??0)+1,_parent:t};o._containsObstacle=this.doesNodeOverlapObstacle(o);const r=this.getTargetIfNodeContainsTarget(o);r&&(o._targetConnectionName=r.connectionName,o.availableZ=r.availableZ,o._containsTarget=!0),o._containsObstacle&&(o._completelyInsideObstacle=this.isNodeCompletelyInsideObstacle(o)),o._completelyInsideObstacle&&!o._containsTarget||e.push(o)}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=[],o=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t);e?o.push(t):e||t._containsObstacle?!e&&t._containsTarget&&n.push(t):n.push(t)}this.unfinishedNodes.push(...o),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){if(e.isCopperPour)continue;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),o=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:o?"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: ${js(n).toFixed(2)}`].join("\n")})}return t.rects.sort((t,e)=>t.center.y-e.center.y),this.srj.connections.forEach((e,n)=>{const o=No[n%No.length];for(const i of e.pointsToConnect){const e=xo(i);t.points.push({x:i.x,y:i.y,label:`conn-${n} (${e.join(",")})`,color:o})}}),t}getObstacleZLayers(t){return this.obstacleZLayersByObstacle.get(t)??[]}},kc=class extends Oc{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e,this.VIA_DIAMETER=Yo(t).padDiameter}srj;opts;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(!Te(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!!Te(e,this.outlinePolygon)&&!Re(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,o=t.center.x+t.width/2,i=t.center.y-t.height/2,r=t.center.y+t.height/2,s=t.width*t.height;let a=0;for(const t of e){const e=Math.max(n,t.center.x-t.width/2),s=Math.min(o,t.center.x+t.width/2),c=Math.max(i,t.center.y-t.height/2),l=Math.min(r,t.center.y+t.height/2);if(e<s&&c<l){a+=(s-e)*(l-c)}}return a/s}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},o=this.getXYZOverlappingObstacles(n);n._containsObstacle=o.length>0||this.isNodePartiallyOutsideBounds(n);const i=this.getTargetIfNodeContainsTarget(n);return i&&(n._targetConnectionName=i.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 o of n){const n=this.createChildNodeAtPosition(t,{center:{...t.center},width:t.width,height:t.height,availableZ:o,_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},o=[{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 i of o){const o=this.createChildNodeAtPosition(t,{center:i,width:n.width,height:n.height,availableZ:t.availableZ});this.isNodeCompletelyOutsideBounds(o)||e.push(o)}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=[],o=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),i=t.availableZ.length>1&&!e&&(t._containsObstacle||t.width<this.VIA_DIAMETER+this.OBSTACLE_MARGIN);if(e)o.push(t);else if(e||this.shouldFilterNodeForObstacle(t)||i)if(!e&&t._containsTarget)if(i){const e=this.getZSubdivisionChildNodes(t);n.push(...e.filter(t=>t._containsTarget||!this.shouldFilterNodeForObstacle(t)))}else n.push(t);else i&&n.push(...this.getZSubdivisionChildNodes(t).filter(t=>!this.shouldFilterNodeForObstacle(t)));else n.push(t)}this.unfinishedNodes.push(...o),this.finishedNodes.push(...n)}},Lc=class extends si{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 o=[...n.connectionNames].sort(),i=n.end.x-n.start.x,r=n.end.y-n.start.y,s=o.length,a=[];for(let t=1;t<=s;t++){const e=t/(s+1);a.push({x:n.start.x+i*e,y:n.start.y+r*e,z:n.availableZ[0]})}n.assignedPoints=o.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,o=this.nodeMap[n];t.has(n)||t.set(n,{capacityMeshNodeId:n,portPoints:[],center:o.center,width:o.width,height:o.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 o=n.assignedPoints[e],i={x:o.point.x,y:o.point.y},r={x:o.point.x+.05*o.point.z,y:o.point.y+.05*o.point.z};0!==o.point.z&&t.lines.push({points:[i,r],strokeColor:"rgba(0, 0, 0, 0.25)",strokeDash:"5 5",step:4}),t.points.push({x:r.x,y:r.y,label:[`${n.capacityMeshNodeId}-${o.connectionName}`,`z: ${n.availableZ.join(",")}`,`nodePortSegmentId: ${n.nodePortSegmentId}`].join("\n"),color:this.colorMap[o.connectionName],step:4})}}const e=[],n={};for(const t of this.solvedSegments){const e=t.capacityMeshNodeId;n[e]||(n[e]={});for(const o of t.assignedPoints)n[e][o.connectionName]||(n[e][o.connectionName]=[]),n[e][o.connectionName].push({x:o.point.x,y:o.point.y})}for(const t in n)for(const o in n[t]){const i=n[t][o];i.length>1&&e.push({points:i,step:4,strokeDash:"5 5",strokeColor:this.colorMap[o]||"#000"})}return t.lines.push(...e),t}},Dc=(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")}},zc=class extends si{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:o,MAX_ITERATIONS:i=1e6,hyperParameters:r={}}){super(),this.MAX_ITERATIONS=i,this.simpleRouteJson=t,this.nodes=e,this.edges=n,this.colorMap=o??{};const{connectionsWithNodes:s,connectionNameToGoalNodeIds:a}=this.getConnectionsWithNodes();this.connectionsWithNodes=s,this.connectionNameToGoalNodeIds=a,this.hyperParameters=r,this.usedNodeCapacityMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,0])),this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=ai(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 o of this.simpleRouteJson.connections){const i=[];for(const t of o.pointsToConnect){let n=this.nodes[0],o=Number.MAX_VALUE;for(const i of e){const e=Math.sqrt((i.center.x-t.x)**2+(i.center.y-t.y)**2);e<o&&(o=e,n=i)}i.push(n)}if(i.length<2)throw new Error(`Not enough nodes for connection "${o.name}", only ${i.length} found`);n.set(o.name,i.map(t=>t.capacityMeshNodeId)),t.push({connection:o,nodes:i,pathFound:!1,straightLineDistance:xe(i[0].center,i[i.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.__rootConnectionNames?.[0],nodeIds:n.map(t=>t.capacityMeshNodeId)})}return t}doesNodeHaveCapacityForTrace(t,e){const n=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,o=this.getTotalCapacity(t);if(1===t.availableZ.length&&!t._containsTarget&&n>0)return!1;let i=0;return t.availableZ.length>1&&1===e.availableZ.length&&(i+=.5),n+i<o}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=xe(e.center,n.center)),this.candidates.sort((t,e)=>t.f-e.f);const o=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),!o)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(o.node,n))return t.path=this.getBacktrackedPath({prevCandidate:o,node:n,f:0,g:0,h:0}),this.reduceCapacityAlongPath(t),this.currentConnectionIndex++,this.candidates=null,void(this.visitedNodes=null);const i=this.getNeighboringNodes(o.node);for(const t of i){if(this.visitedNodes?.has(t.capacityMeshNodeId))continue;if(!this.doesNodeHaveCapacityForTrace(t,o.node))continue;const e=this.connectionsWithNodes[this.currentConnectionIndex].connection.name;if(t._containsObstacle&&!this.canTravelThroughObstacle(t,e))continue;const i=this.computeG(o,t,n),r=this.computeH(o,t,n),s=i+r*this.GREEDY_MULTIPLIER;this.debug_lastNodeCostMap.set(t.capacityMeshNodeId,{f:s,g:i,h:r});const a={prevCandidate:o,node:t,f:s,g:i,h:r};this.candidates.push(a)}this.visitedNodes.add(o.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 o=n.path.map(({center:{x:t,y:n},width:o,availableZ:i})=>({x:t+.005*o*(e%10+e%19),y:n+.005*o*(e%10+e%19),availableZ:i}));t.lines.push({points:o,strokeColor:this.colorMap[n.connection.name]});for(let e=0;e<o.length;e++){const i=o[e];t.points.push({x:i.x,y:i.y,label:[`conn: ${n.connection.name}`,`node: ${n.path[e].capacityMeshNodeId}`,`z: ${i.availableZ.join(",")}`].join("\n")})}}}for(const e of this.nodes){const n=this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0,o=this.getTotalCapacity(e),i=this.debug_lastNodeCostMap.get(e.capacityMeshNodeId);t.rects.push({...Dc(e,{rectMargin:.025,zOffset:.01}),label:[`${e.capacityMeshNodeId}`,`${n}/${o}`,`${e.width.toFixed(2)}x${e.height.toFixed(2)}`,`g: ${void 0!==i?.g?i.g.toFixed(2):"?"}`,`h: ${void 0!==i?.h?i.h.toFixed(2):"?"}`,`f: ${void 0!==i?.f?i.f.toFixed(2):"?"}`,`z: ${e.availableZ.join(", ")}`].join("\n"),stroke:n>o+.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,o]=e.connection.pointsToConnect;t.lines.push({points:[{x:n.x,y:n.y},{x:o.x,y:o.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,o)=>{const i=.5*(1-o/5),r=this.getBacktrackedPath(e);t.lines.push({points:r.map(({center:{x:t,y:e}})=>({x:t,y:e})),strokeColor:To(this.colorMap[n]??"red",1-i)})})}return t}},Fc=class extends zc{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 js(t,this.maxCapacityFactor)}getNodeCapacityPenalty(t){const e=t.width+t.height,n=.05,o=this.getTotalCapacity(t)-(this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0);if(o>2)return n;return(e-n)*Math.max(1,(2-o)/(e-n))+n}getDistanceBetweenNodes(t,e){const n=t.center.x-e.center.x,o=t.center.y-e.center.y;return Math.sqrt(n**2+o**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)}},Bc=class extends Fc{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 jc(t,e,n){const o=e.x-t.x,i=e.y-t.y;if(Math.abs(o)<1e-9&&Math.abs(i)<1e-9)return t;const r=n.width/2,s=n.height/2,a=n.center.x-r,c=n.center.x+r,l=n.center.y-s,d=n.center.y+s;let h=0,u=1/0;if(Math.abs(o)>1e-9){const e=(a-t.x)/o,n=(c-t.x)/o;h=Math.max(h,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(i)>1e-9){const e=(l-t.y)/i,n=(d-t.y)/i;h=Math.max(h,Math.min(e,n)),u=Math.min(u,Math.max(e,n))}else if(t.y<l||t.y>d)return t;if(u<h||h===1/0||h<-1e9)return t;return{x:t.x+o*h,y:t.y+i*h}}function $c(t,e){const n=t.center,o=e.center,i=jc(n,o,t),r=jc(o,n,e),s=o.x-n.x,a=o.y-n.y,c=Math.sqrt(s*s+a*a);let l=i,d=r;if(c>1e-9){const n={x:s/c,y:a/c},o=.3*t.width,h=.3*e.width;o+h<Math.sqrt((r.x-i.x)**2+(r.y-i.y)**2)?(l={x:i.x+n.x*o,y:i.y+n.y*o},d={x:r.x-n.x*h,y:r.y-n.y*h}):(l=i,d=r)}return{lineStart:l,lineEnd:d}}var Yc=t=>{const{usedCapacity:e,totalCapacity:n,layerCount:o}=t;if(e<n)return 0;if(n<1&&e<=1)return 0;if(1===o&&e>1)return 1-.01**e;const i=e/n-1;return 1-Math.exp(-2*i)},Xc=(t,e,n)=>{if(n._containsTarget)return 0;if(t<=e)return 0;const o=1-Yc({usedCapacity:t,totalCapacity:e,layerCount:n.availableZ.length});return o<=0?-1e9:Math.log(o)},Vc=({totalNodeCapacityMap:t,usedNodeCapacityMap:e,nodeMap:n,sectionNodeIds:o})=>{let i=0;const r=o??new Set(e.keys());for(const o of r){if(!t.has(o))continue;const r=n.get(o);if(!r)continue;const s=t.get(o),a=e.get(o)??0;i+=Xc(a,s,r)}return i};function Wc({sectionNodes:t,sectionEdges:e,sectionConnectionTerminals:n,completedPaths:o,nodeMap:i,colorMap:r,centerNodeId:s,title:a,nodeOpacity:c=.1,usedNodeCapacityMap:l,totalCapacityMap:d}){const h={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 o=e.availableZ??[],i=o.includes(0),r=o.includes(1);i&&r?(t=`rgba(128, 0, 128, ${c})`,n=`rgba(128, 0, 128, ${c})`):i?(t=`rgba(0, 0, 255, ${c})`,n=`rgba(0, 0, 255, ${c})`):r&&(t=`rgba(255, 0, 0, ${c})`,n=`rgba(255, 0, 0, ${c})`),s&&e.capacityMeshNodeId===s&&(t=`rgba(0, 255, 0, ${c})`,n=`rgba(0, 128, 0, ${c})`),h.rects.push({...Dc(e),fill:t,stroke:n,label:`${e.capacityMeshNodeId}\n(Section Node)\nZ: ${o.join(",")}`});const a=h.rects.length-1;if(l&&d){const t=l.get(e.capacityMeshNodeId)??0,n=d.get(e.capacityMeshNodeId)??0,o=n>0?(t/n*100).toFixed(1):"N/A",i=Yc({usedCapacity:t,totalCapacity:n,layerCount:e.availableZ.length});h.rects[a].label+=`\n${t.toFixed(1)} / ${n.toFixed(1)}\n${o}% (Pf: ${(100*i).toFixed(1)}%)`,i>.2&&(h.rects[a].stroke=To("red",.7*(.8+c)))}}for(const t of e){const[e,n]=t.nodeIds,o=i.get(e),r=i.get(n);if(o&&r){const{lineStart:t,lineEnd:e}=$c(o,r);h.lines.push({points:[t,e],strokeColor:`rgba(0, 0, 0, ${.2*Math.min(1,c/.1)})`})}}return n.forEach((t,e)=>{const n=i.get(t.startNodeId),o=i.get(t.endNodeId),s=r[t.connectionName]??"black",a=n&&u.has(n.capacityMeshNodeId),c=o&&u.has(o.capacityMeshNodeId),l=(e+e/50)%5;let d=0,p=0,m=0,g=0;if(a&&n){const e=.02*Math.min(n.width,n.height);d=e*l,p=e*l,h.points.push({x:n.center.x+d,y:n.center.y+p,color:s,label:`Start: ${t.connectionName}\n(${t.startNodeId})`}),h.lines.push({points:[{x:n.center.x,y:n.center.y},{x:n.center.x+d,y:n.center.y+p}],strokeColor:"gray",strokeDash:"2 2"})}if(c&&o){const e=.02*Math.min(o.width,o.height);m=e*l,g=e*l,h.points.push({x:o.center.x+m,y:o.center.y+g,color:s,label:`End: ${t.connectionName}\n(${t.endNodeId})`}),h.lines.push({points:[{x:o.center.x,y:o.center.y},{x:o.center.x+m,y:o.center.y+g}],strokeColor:"gray",strokeDash:"2 2"})}a&&c&&n&&o&&h.lines.push({points:[{x:n.center.x+d,y:n.center.y+p},{x:o.center.x+m,y:o.center.y+g}],strokeColor:s,strokeDash:"5 5"})}),o&&o.forEach((t,e)=>{if(t.path&&t.path.length>0){const n=r[t.connectionName]??"gray",o={x:(e+e/50)%5*.03,y:(e+e/50)%5*.03};h.lines.push({points:t.path.map(({center:{x:t,y:e}})=>({x:t+o.x,y:e+o.y})),strokeColor:To(n,.2)})}}),h}var Hc=class extends si{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??ai(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=Vc({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:e}),t.hyperParameters?.SHUFFLE_SEED&&(this.sectionConnectionTerminals=Xi(this.sectionConnectionTerminals,t.hyperParameters?.SHUFFLE_SEED))}getTotalCapacity(t){return js(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,o=t.center.y-e.center.y;return Math.sqrt(n**2+o**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 o=this.totalNodeCapacityMap.get(t),i=this.usedNodeCapacityMap.get(t)??0,r=Xc(i,o,n);this.currentSectionScore-=r;const s=i+1;this.usedNodeCapacityMap.set(t,s);const a=Xc(s,o,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 o=this.candidates;if(0===o.length)return void this._handleCandidatesExhausted(t);o.sort((t,e)=>t.f-e.f);const i=o.shift();if(o.length>this.MAX_CANDIDATES_IN_MEMORY&&o.splice(this.MAX_CANDIDATES_IN_MEMORY,o.length-this.MAX_CANDIDATES_IN_MEMORY),this.visitedNodes.add(i.node.capacityMeshNodeId),i.node.capacityMeshNodeId===n.capacityMeshNodeId)return void this._handleGoalReached(i,t,n);const r=this.getNeighboringNodes(i.node);for(const e of r){if(this.queuedNodes?.has(e.capacityMeshNodeId))continue;if(!this.doesNodeHaveCapacityForTrace(e,i.node))continue;if(e._containsObstacle){const n=e.capacityMeshNodeId===t.startNodeId,o=e.capacityMeshNodeId===t.endNodeId;if(!n&&!o)continue}const r=this.computeG(i,e,n),s=this.computeH(i,e,n),a=r+s*this.GREEDY_MULTIPLIER;this.debug_lastNodeCostMap.set(e.capacityMeshNodeId,{f:a,g:r,h:s});const c={prevCandidate:i,node:e,f:a,g:r,h:s};this.queuedNodes?.add(e.capacityMeshNodeId),o.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=xe(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 o=this.getBacktrackedPath(t);e.path=o,this.reduceCapacityAlongPath(o),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=Wc({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 o=this.debug_lastNodeCostMap.get(t.capacityMeshNodeId),i=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,r=this.getTotalCapacity(t),s=`${i.toFixed(1)}/${r.toFixed(1)}`,a=o?`f:${o.f.toFixed(1)} g:${o.g.toFixed(1)} h:${o.h.toFixed(1)}`:"cost:?";e.rects[n].label=[t.capacityMeshNodeId,`Cap: ${s}`,a,`Z: ${t.availableZ.join(",")}`].join("\n"),i>r&&(e.rects[n].stroke=To("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],o=n?.connectionName??"unknown",i=this.colorMap[o]??"purple";t.forEach((t,n)=>{const o=.8*(1-n/5),r=this.getBacktrackedPath(t);r.length>0&&e.lines.push({points:r.map(({center:{x:t,y:e}})=>({x:t,y:e})),strokeColor:To(i,1-o),strokeWidth:.05})})}return e}},Gc=t=>Array.from({length:t},(t,e)=>e),Uc=class extends ys{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:Gc(2).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings6_for3",possibleValues:Gc(6).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings24_for4",possibleValues:Gc(24).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings30",possibleValues:Gc(30).map(t=>({SHUFFLE_SEED:t}))}]}generateSolver(t){return new Hc({...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 Zc from"object-hash";var qc=t=>Math.floor(10*t)/10,Jc=class extends Uc{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?oo():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 o=n.pop();if(!o)break;e.push(o.capacityMeshNodeId);const i=this.constructorParams.nodeEdgeMap.get(o.capacityMeshNodeId).flatMap(t=>t.nodeIds).filter(e=>!t.has(e)).filter(t=>this.sectionNodeIdSet.has(t));for(const e of i){t.add(e);const i=this.constructorParams.nodeMap.get(e),r=js(i);n.push({ancestorCapacitySum:o.g,capacity:r,g:o.g+r,capacityMeshNodeId:e})}}return e}computeCacheKeyAndTransform(){const t=this._computeBfsOrderingOfNodesInSection(),e=new Map,n=new Map;t.forEach((t,o)=>{const i=`node${o}`;e.set(t,i),n.set(i,t)});const o={};for(const n of t){const t=e.get(n),i=this.constructorParams.nodeMap.get(n),r=js(i);o[t]=qc(r).toFixed(1)}const i=new Set,r=[];for(const n of t){const t=e.get(n),o=this.constructorParams.nodeEdgeMap.get(n)??[];for(const s of o){const o=s.nodeIds.find(t=>t!==n);if(this.sectionNodeIdSet.has(o)){const n=[t,e.get(o)].sort(),s=`${n[0]}-${n[1]}`;i.has(s)||(r.push(n),i.add(s))}}}r.sort((t,e)=>t[0]!==e[0]?t[0].localeCompare(e[0]):t[1].localeCompare(e[1]));const s={},a=new Map,c=new Map;for(const t of this.constructorParams.sectionConnectionTerminals){const n=e.get(t.startNodeId),o=e.get(t.endNodeId),[i,r]=[n,o].sort(),l=`${i}->${r}`,d=c.get(l)??0;c.set(l,d+1);const h=`${i}->${r}::${d}`;s[h]={start:i,end:r},a.set(h,t.connectionName)}const l=`capacitypathing:${Zc({node_capacity_map:o,node_edge_map:r,terminals:s})}`,d={cacheSpaceToRealConnectionId:a,cacheSpaceToRealNodeId:n};return this.cacheKey=l,this.cacheToSolveSpaceTransform=d,{cacheKey:l,cacheToSolveSpaceTransform:d}}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[o,i]of Object.entries(t.solutionPaths)){const t=n.get(o);if(!t){console.warn(`Could not find real connection name for ${o}`);continue}const r=this.constructorParams.sectionConnectionTerminals.find(e=>e.connectionName===t);if(!r){console.warn(`Could not find original terminal for connection name ${t}`);continue}const s=i.map(n=>{const o=e.get(n);if(!o)throw new Error(`Could not map cache node ID ${n} to real node ID for connection ${t}`);const i=this.constructorParams.nodeMap.get(o);if(!i)throw new Error(`Could not find node with ID ${o} in nodeMap for connection ${t}`);return i});this.cachedSectionConnectionTerminals.push({...r,path:s})}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:o}=this.cacheToSolveSpaceTransform,i=new Map;for(const[t,e]of n)i.set(e,t);const r=new Map;for(const[t,e]of o)r.set(e,t);const s=[];if(super.sectionConnectionTerminals)for(const t of super.sectionConnectionTerminals)if(t.path&&t.path.length>0){const e=t.path.map(t=>t.capacityMeshNodeId);s.push([t.connectionName,e])}for(const[t,n]of s){const o=r.get(t);if(!o){console.warn(`Could not find cache space connection ID for ${t} when saving to cache.`);continue}const s=n.map(e=>{const n=i.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[o]=s}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 Wc({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"})}},Kc=class extends si{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=ai(this.edges),this.colorMap=t.colorMap??{},this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=ai(this.edges),this.initialSolver=t.initialPathingSolver||new Bc({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,o=e>0?n/e:0;this.nodeCapacityPercentMap.set(t.capacityMeshNodeId,o),this.nodeOptimizationAttemptCountMap.set(t.capacityMeshNodeId,0)}this.connectionsWithNodes=this.initialSolver.connectionsWithNodes,this.stats.startingScore=Vc({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 o of this.nodes){if(o._containsTarget)continue;const i=this.nodeOptimizationAttemptCountMap.get(o.capacityMeshNodeId),r=this.totalNodeCapacityMap.get(o.capacityMeshNodeId),s=Yc({usedCapacity:this.usedNodeCapacityMap.get(o.capacityMeshNodeId)??0,totalCapacity:r,layerCount:o.availableZ.length}),a=s/(i+1);i<this.currentSchedule.MAX_ATTEMPTS_PER_NODE&&a>t&&s>this.currentSchedule.MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE&&(t=a,e=s,n=o.capacityMeshNodeId)}return n}getOverallScore(){let t=0;for(const e of this.nodes){if(e._containsTarget)continue;const n=this.totalNodeCapacityMap.get(e.capacityMeshNodeId),o=Yc({usedCapacity:this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0,totalCapacity:n,layerCount:e.availableZ.length});o>t&&(t=o)}return{highestNodePf:t,score:Vc({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:o,edges:i,nodeEdgeMap:r,expansionDegrees:s}=t,a=new Set,c=[{nodeId:e,depth:0}];a.add(e);let l=0;for(;l<c.length;){const{nodeId:t,depth:e}=c[l++];if(e>=s)continue;const n=r.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 d=Array.from(a).map(t=>o.get(t)),h=i.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 o=t.path[e];if(a.has(o.capacityMeshNodeId)){n=o.capacityMeshNodeId;break}}e&&n&&u.push({connectionName:t.connection.name,startNodeId:e,endNodeId:n})}return{sectionConnectionTerminals:u,sectionNodes:d,sectionEdges:h,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 Jc({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 o=new Set(e.map(t=>t.capacityMeshNodeId)),i=Vc({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:o}),r=new Map(this.usedNodeCapacityMap),s=t;for(const t of s){const e=this.connectionsWithNodes.find(e=>e.connection.name===t.connectionName);if(e?.path)for(const t of e.path)if(o.has(t.capacityMeshNodeId)){const e=r.get(t.capacityMeshNodeId)??0;r.set(t.capacityMeshNodeId,Math.max(0,e-1))}}for(const t of s)if(t.path)for(const e of t.path)o.has(e.capacityMeshNodeId)&&r.set(e.capacityMeshNodeId,(r.get(e.capacityMeshNodeId)??0)+1);Vc({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:r,nodeMap:this.nodeMap,sectionNodeIds:o})>i?(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 o=e.path,i=n.path,r=o.findIndex(t=>t.capacityMeshNodeId===n.startNodeId),s=o.findIndex(t=>t.capacityMeshNodeId===n.endNodeId);if(-1===r||-1===s){console.warn(`Could not find start/end nodes (${n.startNodeId}/${n.endNodeId}) in original path for ${n.connectionName}`);continue}const[a,c]=r<=s?[r,s]:[s,r],l=o.slice(0,a),d=o.slice(c+1);let h=i;if(i.length>0&&o[a]&&i[0].capacityMeshNodeId!==o[a].capacityMeshNodeId){if(i[i.length-1].capacityMeshNodeId!==o[a].capacityMeshNodeId){console.warn(`New section path for ${n.connectionName} doesn't align with original path boundaries. Skipping merge for this connection.`);continue}h=[...i].reverse()}e.path=[...l,...h,...d]}}_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,o=e>0?n/e:0;this.nodeCapacityPercentMap.set(t.capacityMeshNodeId,o)}}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 Wc({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)"})}},Qc=class extends si{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,o=n?this.adjacencyList.get(n):void 0;if(!n||!o)return this.removedNodeIds.add(t),this.adjacencyList.delete(t),this.leavesIndex+=1,void(this.leavesIndex===this.leaves.length&&(this.solved=!0));o.delete(t),this.removedNodeIds.add(t),this.adjacencyList.delete(t),1!==o.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]),o=this.nodeMap.get(t.nodeIds[1]);if(n?.center&&o?.center){const i=Math.min(...n.availableZ),r=Math.min(...o.availableZ),s={x:n.center.x+i*n.width*.05,y:n.center.y-i*n.width*.05},a={x:o.center.x+r*o.width*.05,y:o.center.y-r*o.width*.05},c=Array.from(new Set([...n.availableZ,...o.availableZ])).sort();e.lines.push({layer:`z${c.join(",")}`,points:[s,a],strokeDash:n.availableZ.join(",")===o.availableZ.join(",")?void 0:"10 5",strokeColor:t.nodeIds.some(t=>this.removedNodeIds.has(t))?To("black",.9):void 0})}}return e}},tl=class extends Ca{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,o]of e.entries()){const e=t.connections.find(t=>t.name===n);if(!e)continue;const i={...e.pointsToConnect[0],z:ko(bo(e.pointsToConnect[0]),t.layerCount)},r={...e.pointsToConnect[1],z:ko(bo(e.pointsToConnect[1]),t.layerCount)};this.unsolvedRoutes.push({connectionName:n,hdRoutes:o,start:i,end:r})}for(const n of t.connections)e.has(n.name)||this.unsolvedRoutes.push({connectionName:n.name,hdRoutes:[],start:{...n.pointsToConnect[0],z:ko(bo(n.pointsToConnect[0]),t.layerCount)},end:{...n.pointsToConnect[1],z:ko(bo(n.pointsToConnect[1]),t.layerCount)}})}},el=.005,nl=class extends si{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 o=0;o<=e;o++)n.push(new hi(t.filter(t=>t.availableZ[0]===o)));for(const e of t){const t=[],o=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of o)n._containsTarget&&n._targetConnectionName!==e._targetConnectionName||e._containsTarget&&(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId&&li(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),o=this.nodeMap.get(e);return n.width*n.height-o.width*o.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 o=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===o.length)return void this.nextBatchNodeIds.push(t);const i=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))))},r=o.filter(t=>t.center.x<e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(r.length>0){const{width:t,height:o}=r[0],s=r.every(e=>e.width===t&&e.height===o);Math.abs(r.reduce((t,e)=>t+e.height,0)-e.height)<el&&s&&(e.width+=t,e.center.x=e.center.x-t/2,i(r),n=!0)}const s=o.filter(t=>t.center.x>e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(s.length>0&&!n){const{width:t,height:o}=s[0],r=s.every(e=>e.width===t&&e.height===o);Math.abs(s.reduce((t,e)=>t+e.height,0)-e.height)<el&&r&&(e.width+=t,e.center.x=e.center.x+t/2,i(s),n=!0)}const a=o.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:o}=a[0],r=a.every(e=>e.width===t&&e.height===o);Math.abs(a.reduce((t,e)=>t+e.width,0)-e.width)<el&&r&&(e.height+=o,e.center.y=e.center.y+o/2,i(a),n=!0)}const c=o.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:o}=c[0],r=c.every(e=>e.width===t&&e.height===o);Math.abs(c.reduce((t,e)=>t+e.width,0)-e.width)<el&&r&&(e.height+=o,e.center.y=e.center.y-o/2,i(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(Dc(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e&&(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const o of this.currentBatchNodeIds){const i=this.nodeMap.get(o);if(!this.absorbedNodeIds.has(o)&&i){const r=Dc(i,{rectMargin:.01});o===e?r.stroke="rgba(0, 255, 0, 0.8)":n?.some(t=>t.capacityMeshNodeId===o)?r.stroke="rgba(128, 0, 128, 0.8)":r.stroke="rgba(255, 165, 0, 0.8)",r.layer=`z${i.availableZ.join(",")}`,r.label=`${r.label}\n(unprocessed)`,t.rects.push(r)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)&&n){const e=Dc(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}},ol=class extends si{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 o=n.center.x-n.width/2,i=n.center.x+n.width/2,r=n.center.y-n.height/2,s=n.center.y+n.height/2,a=Math.max(t.minX,o),c=Math.min(t.maxX,i),l=Math.max(t.minY,r),d=Math.min(t.maxY,s);if(a<c&&l<d){const t=(c-a)*(d-l)/(n.width*n.height);e+=js(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:o,topSurroundingCapacity:i,bottomSurroundingCapacity:r}=this.getSurroundingCapacities(t);if(1*(n+o)>i+r){const n=Math.floor(t.height/this.strawSize),o=t.height/n;for(let i=0;i<n;i++){const n=t.center.y-t.height/2+i*o+o/2;e.push({capacityMeshNodeId:`${t.capacityMeshNodeId}_straw${i}`,center:{x:t.center.x,y:n},width:t.width,height:o,layer:t.layer,availableZ:[...t.availableZ],_depth:t._depth,_strawNode:!0,_strawParentCapacityMeshNodeId:t.capacityMeshNodeId})}}else{const n=Math.floor(t.width/this.strawSize),o=t.width/n;for(let i=0;i<n;i++){const n=t.center.x-t.width/2+i*o+o/2;e.push({capacityMeshNodeId:`${t.capacityMeshNodeId}_straw${i}`,center:{x:n,y:t.center.y},width:o,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 il(t){const{nodeId:e,nodeIdToSegmentIds:n,segmentIdToNodeIds:o,hops:i}=t;if(0===i)return[e];const r=new Set([e]),s=[{nodeId:e,remainingHops:i}];for(;s.length>0;){const{nodeId:t,remainingHops:e}=s.shift();if(0===e)continue;const i=n.get(t)||[];for(const t of i){const n=o.get(t)||[];for(const t of n)r.has(t)||(r.add(t),s.push({nodeId:t,remainingHops:e-1}))}}return Array.from(r)}var rl=t=>Array.from(t.entries()).map(([t,{x:e,y:n,z:o}])=>`${t}(${e?.toFixed(3)??""},${n?.toFixed(3)??""},${o??""})`).sort().join("&"),sl=(t,e,n,o)=>{const i=Math.min(t,e),r=Math.max(t,e),s=Math.min(n,o);return i<=Math.max(n,o)&&r>=s},al=(t,e,n,o)=>{const i=[],r=new Map(t.originalPointMap);for(const[t,e]of n.entries()){const n=r.get(t);r.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 s=t.segmentPairsInNode.get(n);for(const t of s){const e=r.get(t[0]),o=r.get(t[1]);e.z!==o.z&&i.push({type:"transition_via",segmentPoints:t,capacityMeshNodeId:n,probabilityOfFailure:0})}for(let t=0;t<s.length;t++)for(let e=t+1;e<s.length;e++){if(o?.areIdsConnected(s[t][0],s[t][1]))continue;const a=s[t],c=s[e],l=r.get(a[0]),d=r.get(a[1]),h=r.get(c[0]),u=r.get(c[1]);if(!sl(l.z,d.z,h.z,u.z))continue;const p=fe(l,d,h,u),m=l.z===d.z&&h.z===u.z&&l.z===h.z;p&&(m?i.push({type:"same_layer_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,crossingLine1:a,crossingLine2:c,probabilityOfFailure:0}):l.z===d.z&&h.z!==u.z?i.push({type:"single_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,sameLayerCrossingLine:a,transitionCrossingLine:c,probabilityOfFailure:0}):l.z!==d.z&&h.z===u.z?i.push({type:"single_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,sameLayerCrossingLine:c,transitionCrossingLine:a,probabilityOfFailure:0}):l.z!==d.z&&h.z!==u.z&&i.push({type:"double_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,crossingLine1:a,crossingLine2:c,probabilityOfFailure:0}))}}return i},cl=(t,e,n)=>{if("change_layer"===e.type)for(const n of e.segmentPointIds){const o=t.get(n)||{};t.set(n,{...o,z:e.newZ})}else if("swap_position_on_segment"===e.type){const[o,i]=e.segmentPointIds,r=n(o),s=n(i),a=t.get(o)||{},c=t.get(i)||{};t.set(o,{...a,x:s.x,y:s.y}),t.set(i,{...c,x:r.x,y:r.y})}else if("combined"===e.type)for(const o of e.operations)cl(t,o,n)},ll=(t,e)=>{const n=new Map,o=new Map,i=new Map,r=[];let s=0;for(const a of t)for(const t of a.assignedPoints){const c={segmentPointId:"SP"+s++,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)o.set(t,[...o.get(t)??[],c.segmentPointId]);i.set(a.nodePortSegmentId,[...i.get(a.nodePortSegmentId)??[],c.segmentPointId]),r.push(c)}return{segmentPointMap:n,nodeToSegmentPointMap:o,segmentToSegmentPointMap:i}},dl=class extends si{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,js(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=il({nodeId:this.rootNodeId,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,hops:this.MUTABLE_HOPS}),n=il({nodeId:this.rootNodeId,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,hops:this.MUTABLE_HOPS+1}),o=Array.from(new Set(n).difference(new Set(e)));t?.segmentPointMap||(t=ll(this.dedupedSegments,this.segmentIdToNodeIds));const i=new Map;for(const e of n)i.set(e,t.nodeToSegmentPointMap.get(e));const r=new Map;for(const e of n)for(const n of i.get(e)){const e=t.segmentPointMap.get(n);r.set(n,e)}const s=Array.from(r.values()),a=new Map;for(const t of s)a.set(t.segmentId,[...a.get(t.segmentId)??[],t.segmentPointId]);for(const[e,n]of i.entries())for(let e=0;e<n.length;e++){const o=t.segmentPointMap.get(n[e]);for(let i=e+1;i<n.length;i++){const e=t.segmentPointMap.get(n[i]);e.segmentPointId!==o.segmentPointId&&(e.segmentId!==o.segmentId&&e.connectionName===o.connectionName&&(e.directlyConnectedSegmentPointIds.includes(o.segmentPointId)||(o.directlyConnectedSegmentPointIds.push(e.segmentPointId),e.directlyConnectedSegmentPointIds.push(o.segmentPointId))))}}const c=new Map;for(const t of n)c.set(t,[]);for(const e of s)for(const n of e.capacityMeshNodeIds){const o=c.get(n);if(o)for(const i of e.directlyConnectedSegmentPointIds){const r=t.segmentPointMap.get(i);r.segmentPointId!==e.segmentPointId&&(r.capacityMeshNodeIds.some(t=>t===n)&&(o.some(([t,n])=>t===e.segmentPointId&&n===r.segmentPointId||t===r.segmentPointId&&n===e.segmentPointId)||o.push([e.segmentPointId,r.segmentPointId])))}}const l=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)&&l.add(e)}const d=new Set;for(const t of s){const n=t.capacityMeshNodeIds.some(t=>e.includes(t)),o=this.dedupedSegmentMap.get(t.segmentId),i=o&&o.availableZ.length>1;(n||i)&&d.add(t.segmentPointId)}const h=new Set;for(const t of s){if(t.capacityMeshNodeIds.some(t=>this.nodeMap.get(t)?._containsTarget)){const e=this.dedupedSegmentMap.get(t.segmentId);e&&1===e.availableZ.length&&h.add(t.segmentPointId)}}return{allNodeIds:n,mutableNodeIds:e,immutableNodeIds:o,mutableSegmentIds:l,segmentPairsInNode:c,segmentPointMap:r,segmentPointsInNode:i,segmentPointsInSegment:a,originalPointMap:r,mutableSegmentPointIds:d,zLockedSegmentPointIds:h}}createInitialCandidate(){const t=new Map,e=al(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:rl(t),issues:al(this.unravelSection,this.nodeMap,t)}}get nextCandidate(){return this.candidates[0]??null}getPointInCandidate(t,e){const n=this.unravelSection.segmentPointMap.get(e),o=t.pointModifications.get(e);return{x:o?.x??n.x,y:o?.y??n.y,z:o?.z??n.z,segmentId:n.segmentId}}getConnectionSegmentPointIds(t){const e=[];for(const[n,o]of this.unravelSection.segmentPointMap.entries())o.connectionName===t&&e.push(n);return e}canConnectionUseLayer(t,e){for(const n of t){const t=this.unravelSection.segmentPointMap.get(n),o=this.dedupedSegmentMap.get(t.segmentId);if(!o||!o.availableZ.includes(e))return!1}return!0}getOperationsForIssue(t,e){const n=[];if("transition_via"===e.type){const[o,i]=e.segmentPoints,r=this.getPointInCandidate(t,o),s=this.getPointInCandidate(t,i),a=this.unravelSection.segmentPointMap.get(o),c=(this.unravelSection.segmentPointMap.get(i),this.dedupedSegmentMap.get(r.segmentId).availableZ),l=this.dedupedSegmentMap.get(s.segmentId).availableZ,d=this.unravelSection.zLockedSegmentPointIds.has(o),h=this.unravelSection.zLockedSegmentPointIds.has(i),u=this.getConnectionSegmentPointIds(a.connectionName);if(this.canConnectionUseLayer(u,s.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:s.z,segmentPointIds:t})}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})}this.unravelSection.mutableSegmentPointIds.has(o)&&!d&&c.includes(s.z)&&n.push({type:"change_layer",newZ:s.z,segmentPointIds:[o]}),this.unravelSection.mutableSegmentPointIds.has(i)&&!h&&l.includes(r.z)&&n.push({type:"change_layer",newZ:r.z,segmentPointIds:[i]})}if("same_layer_crossing"===e.type){const[t,o]=e.crossingLine1,[i,r]=e.crossingLine2,s=[],a=this.unravelSection.segmentPointMap.get(t),c=this.unravelSection.segmentPointMap.get(o),l=this.unravelSection.segmentPointMap.get(i),d=this.unravelSection.segmentPointMap.get(r),h=this.unravelSection.mutableSegmentPointIds.has(t),u=this.unravelSection.mutableSegmentPointIds.has(o),p=this.unravelSection.mutableSegmentPointIds.has(i),m=this.unravelSection.mutableSegmentPointIds.has(r),g=this.unravelSection.zLockedSegmentPointIds.has(t),f=this.unravelSection.zLockedSegmentPointIds.has(o),y=this.unravelSection.zLockedSegmentPointIds.has(i),_=this.unravelSection.zLockedSegmentPointIds.has(r);h&&p&&a.segmentId===l.segmentId&&s.push([t,i]),h&&m&&a.segmentId===d.segmentId&&s.push([t,r]),u&&p&&c.segmentId===l.segmentId&&s.push([o,i]),u&&m&&c.segmentId===d.segmentId&&s.push([o,r]);for(const[t,e]of s)n.push({type:"swap_position_on_segment",segmentPointIds:[t,e]});const b=this.getConnectionSegmentPointIds(a.connectionName),x=this.getConnectionSegmentPointIds(l.connectionName),v=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)v.add(t)}for(const t of v)if(t!==a.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})}for(const t of v)if(t!==l.z&&this.canConnectionUseLayer(x,t)){const e=x.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),I=this.dedupedSegmentMap.get(c.segmentId),C=this.dedupedSegmentMap.get(l.segmentId),P=this.dedupedSegmentMap.get(d.segmentId),M=(t,e)=>t.every(t=>t.availableZ.includes(e));if(h&&u&&!g&&!f){const e=0===a.z?1:0;M([S,I],e)&&n.push({type:"change_layer",newZ:e,segmentPointIds:[t,o]})}if(p&&m&&!y&&!_){const t=0===l.z?1:0;M([C,P],t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[i,r]})}if(h&&!g){const e=0===a.z?1:0;S.availableZ.includes(e)&&n.push({type:"change_layer",newZ:e,segmentPointIds:[t]})}if(u&&!f){const t=0===c.z?1:0;I.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[o]})}if(p&&!y){const t=0===l.z?1:0;C.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[i]})}if(m&&!_){const t=0===d.z?1:0;P.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[r]})}}return n}computeG(t){const{issues:e,originalCandidate:n,operationsPerformed:o,operation:i}=t,r=new Map;for(const t of e){r.has(t.capacityMeshNodeId)||r.set(t.capacityMeshNodeId,{numTransitionCrossings:0,numSameLayerCrossings:0,numEntryExitLayerChanges:0});const e=r.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 s=0;for(const[t,{numEntryExitLayerChanges:e,numSameLayerCrossings:n,numTransitionCrossings:o}]of r){const i=this.nodeMap.get(t),r=Math.min(Ys(i,n,e,o),.999999);s+=Math.log(1-r)}var a;return(a=s)<-Math.LN2?Math.log(1-Math.exp(a)):Math.log(-Math.expm1(a))}getUnexploredNeighborByApplyingOperation(t,e){const n=new Map(t.pointModifications);cl(n,e,e=>this.getPointInCandidate(t,e));const o=rl(n);if(this.queuedOrExploredCandidatePointModificationHashes.has(o))return null;const i=al(this.unravelSection,this.nodeMap,n),r=t.operationsPerformed+1,s=this.computeG({issues:i,originalCandidate:t,operationsPerformed:r,operation:e});return{issues:i,g:s,h:0,f:s,pointModifications:n,candidateHash:o,operationsPerformed:r}}getNeighborOperationsForCandidate(t){return t.issues.flatMap(e=>this.getOperationsForIssue(t,e))}getNeighbors(t){const e=[],n=this.getNeighborOperationsForCandidate(t);for(const o of n){const n=this.getUnexploredNeighborByApplyingOperation(t,o);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,o]of this.unravelSection.segmentPointMap){const i={...o},r=e.pointModifications.get(t);r&&(void 0!==r.x&&(i.x=r.x),void 0!==r.y&&(i.y=r.y),void 0!==r.z&&(i.z=r.z)),n.set(t,i)}for(const[e,o]of n)t.points.push({x:o.x,y:o.y,label:`${e}\nSegment: ${o.segmentId} ${this.unravelSection.mutableSegmentIds.has(o.segmentId)?"MUTABLE":"IMMUTABLE"}\nLayer: ${o.z}`,color:this.colorMap[o.connectionName]||"#000"});const o=new Map;for(const t of this.unravelSection.allNodeIds)o.set(t,{numTransitionCrossings:0,numSameLayerCrossings:0,numEntryExitLayerChanges:0,estPf:0});for(const t of e.issues){const e=o.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 o.entries()){const n=this.nodeMap.get(t);e.estPf=Ys(n,e.numSameLayerCrossings,e.numEntryExitLayerChanges,e.numTransitionCrossings)}for(const e of this.unravelSection.allNodeIds){const n=this.nodeMap.get(e),i=this.unravelSection.mutableNodeIds.includes(e),r=o.get(e),s=[`${e} (${i?"MUT":"IMM"})`,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`Pf: ${r.estPf.toFixed(3)}`,`TC: ${r.numTransitionCrossings}`,`SLC: ${r.numSameLayerCrossings}`,`EELC: ${r.numEntryExitLayerChanges}`].join("\n");t.rects.push({center:n.center,label:s,color:i?"green":"red",width:n.width/8,height:n.height/8})}for(const[e,o]of this.unravelSection.segmentPointsInSegment){if(o.length<=1)continue;const i=o.map(t=>n.get(t));for(let n=0;n<i.length-1;n++)t.lines.push({points:[{x:i[n].x,y:i[n].y},{x:i[n+1].x,y:i[n+1].y}],strokeColor:this.colorMap[e]||"#000"})}for(const[e,o]of n)for(const i of o.directlyConnectedSegmentPointIds)if(e<i){const e=n.get(i);if(!e)continue;const r=o.z===e.z,s=o.z;let a;a=r?0===s?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]||"#000"})}for(const o of e.issues){const e=this.nodeMap.get(o.capacityMeshNodeId);if("transition_via"===o.type)for(const i of o.segmentPoints){const o=n.get(i);t.circles.push({center:{x:o.x,y:o.y},radius:e.width/16,stroke:"#ff0000",fill:"rgba(255, 0, 0, 0.2)",label:`Via Issue\n${i}\nLayer: ${o.z}`})}else if("same_layer_crossing"===o.type)for(const[i,r]of[o.crossingLine1,o.crossingLine2]){const o=n.get(i),s=n.get(r);t.lines.push({points:[{x:o.x,y:o.y},{x:s.x,y:s.y}],strokeColor:"rgba(255,0,0,0.2)",strokeWidth:e.width/32})}}for(const[o,i]of e.pointModifications){const e=n.get(o),i=this.unravelSection.segmentPointMap.get(o);t.circles.push({center:{x:e.x,y:e.y},radius:.05,stroke:"#0000ff",fill:"rgba(0, 0, 255, 0.2)",label:`${o}\nOriginal: (${i.x.toFixed(2)}, ${i.y.toFixed(2)}, ${i.z})\nNew: (${e.x.toFixed(2)}, ${e.y.toFixed(2)}, ${e.z})`})}return t}};import hl from"object-hash";var ul=t=>(Math.round(20*t)/20).toFixed(2),pl=t=>(Math.round(1e3*t)/1e3).toFixed(3);io();var ml=class extends dl{cacheHit=!1;cacheProvider;hasAttemptedToUseCache=!1;constructor(t){super(t),this.cacheProvider=void 0===t.cacheProvider?no():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=k(-t.center.x,-t.center.y),n=new Map,o=new Map,i=new Map,r=new Map,s=new Map,a=new Map;let c=0,l=0,d=0;const h=[...this.unravelSection.allNodeIds].sort((t,e)=>{const n=this.nodeMap.get(t),o=this.nodeMap.get(e);return n.center.x!==o.center.x?n.center.x-o.center.x:n.center.y-o.center.y});for(const t of h){const e="node_"+c++;n.set(t,e),o.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_"+d++;s.set(t,e),a.set(e,t);const n=this.unravelSection.segmentPointMap.get(t).segmentId;if(!i.has(n)){const t="seg_"+l++;i.set(n,t),r.set(t,n)}}const p={};for(const[t,o]of n.entries()){const n=this.nodeMap.get(t),i=R(e,n.center);p[o]={width:n.width,height:n.height,availableZ:n.availableZ,center:{x:ul(i.x),y:ul(i.y)}}}const m={};for(const[t,n]of s.entries()){const o=this.unravelSection.segmentPointMap.get(t),i=R(e,{x:o.x,y:o.y});m[n]={x:ul(i.x),y:ul(i.y),z:o.z}}const g={hyperParameters:this.hyperParameters,normalizedNodes:p,normalizedSegmentPoints:m,mutableHops:this.MUTABLE_HOPS},f=`unravelsec:${hl(g)}`,y={realToCacheTransform:e,nodeIdMap:n,segmentIdMap:i,segmentPointIdMap:s,reverseNodeIdMap:o,reverseSegmentIdMap:r,reverseSegmentPointIdMap:a};return this.cacheKey=f,this.cacheToSolveSpaceTransform=y,{cacheKey:f,cacheToSolveSpaceTransform:y}}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,o=new Map;for(const[n,i]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 r=this.unravelSection.segmentPointMap.get(t);if(!r){console.warn(`Could not find original segment point for ID: ${t} when applying cache.`);continue}const s={};if(void 0!==i.dx){const t=parseFloat(i.dx);Number.isNaN(t)?console.warn(`Failed to parse cached dx coordinate: ${i.dx}`):s.x=r.x+t}if(void 0!==i.dy){const t=parseFloat(i.dy);Number.isNaN(t)?console.warn(`Failed to parse cached dy coordinate: ${i.dy}`):s.y=r.y+t}void 0!==i.dz&&(s.z=r.z+i.dz),Object.keys(s).length>0&&o.set(t,s)}const i=al(this.unravelSection,this.nodeMap,o);this.bestCandidate={pointModifications:o,issues:i,f:t.bestCandidateF,g:t.bestCandidateF,h:0,operationsPerformed:-1,candidateHash:rl(o)},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,o]of this.bestCandidate.pointModifications.entries()){const i=t.get(n);if(!i){console.warn(`Could not find normalized ID for original SP ID: ${n} when saving to cache.`);continue}const r=this.unravelSection.segmentPointMap.get(n);if(!r){console.warn(`Could not find original segment point for ID: ${n} when saving cache.`);continue}const s={};let a=!1;if(void 0!==o.x){const t=o.x-r.x,e=pl(t);0!==parseFloat(e)&&(s.dx=e,a=!0)}if(void 0!==o.y){const t=o.y-r.y,e=pl(t);0!==parseFloat(e)&&(s.dy=e,a=!0)}if(void 0!==o.z){const t=o.z-r.z;0!==t&&(s.dz=t,a=!0)}a&&e.push([i,s])}const n={success:!0,bestCandidatePointModificationsDelta:e,bestCandidateF:this.bestCandidate.f};this.cacheProvider?.setCachedSolutionSync(this.cacheKey,n)}},gl=class extends si{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:o}){super(),this.stats.successfulOptimizations=0,this.stats.failedOptimizations=0,this.stats.cacheHits=0,this.stats.cacheMisses=0,this.cacheProvider=o??null,this.MAX_ITERATIONS=1e6,this.dedupedSegments=(t=>{const e=[],n=new Map;let o=-1;for(const i of t){const t=`${i.start.x}-${i.start.y}-${i.end.x}-${i.end.y}-${i.availableZ.join(",")}`,r=n.get(t);r?i.nodePortSegmentId=r.nodePortSegmentId:(o++,i.nodePortSegmentId=`SEG${o}`,n.set(t,i),e.push(i))}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,js(e));const{segmentPointMap:i,nodeToSegmentPointMap:r,segmentToSegmentPointMap:s}=ll(this.dedupedSegments,this.segmentIdToNodeIds);this.segmentPointMap=i,this.nodeToSegmentPointMap=r,this.segmentToSegmentPointMap=s,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:o}=(t=>{let e=0,n=0,o=0;const i=new Map;for(const e of t)i.has(e.connectionName)||i.set(e.connectionName,[]),i.get(e.connectionName).push(e);const r=[],s=[];for(const[t,e]of i.entries()){if(e.length<2)continue;const o=e[0];for(let i=1;i<e.length;i++){const a=e[i],c={connectionName:t,z:o.z,points:[o,a]};o.z!==a.z?(n++,s.push({connectionName:t,points:[o,a]})):r.push(c)}}for(let t=0;t<r.length;t++)for(let n=t+1;n<r.length;n++){const o=r[t],i=r[n];o.z===i.z&&fe(o.points[0],o.points[1],i.points[0],i.points[1])&&e++}for(let t=0;t<s.length;t++)for(let e=t+1;e<s.length;e++){const n=s[t],i=s[e];fe(n.points[0],n.points[1],i.points[0],i.points[1])&&o++}for(let t=0;t<s.length;t++)for(let e=0;e<r.length;e++){const n=s[t],i=r[e];fe(n.points[0],n.points[1],i.points[0],i.points[1])&&o++}return{numSameLayerCrossings:e,numEntryExitLayerChanges:n,numTransitionCrossings:o}})((this.nodeToSegmentPointMap.get(t.capacityMeshNodeId)??[]).map(t=>this.segmentPointMap.get(t)));return Ys(t,e,n,o)}_step(){if(this.iterations>=this.MAX_ITERATIONS-1)return void(this.solved=!0);if(!this.activeSubSolver){let t=null,e=0;for(const[n,o]of this.nodePfMap.entries()){o*(1-(this.attemptsToFixNode.get(n)??0)/this.MAX_NODE_ATTEMPTS)>e&&(e=o,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 ml({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 o=this.nodePfMap.get(e)||0,i=Math.min(o,1),r=`rgb(${Math.floor(255*i)}, ${Math.floor(255*(1-i))}, 0)`;0===(this.attemptsToFixNode.get(e)??0)&&0===i||t.rects.push({center:n.center,label:[e,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`Pf: ${o.toFixed(3)}`].join("\n"),color:r,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,o]of e.entries()){if(o.length<2)continue;const e=[...o].sort((t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y);for(let o=0;o<e.length-1;o++)t.lines.push({points:[{x:e[o].x,y:e[o].y},{x:e[o+1].x,y:e[o+1].y}],strokeColor:this.colorMap[n]||"#000"})}const n=new Set,o=Array.from(this.segmentPointMap.values());for(let e=0;e<o.length;e++){const i=o[e];for(let r=e+1;r<o.length;r++){const e=o[r];if(i.connectionName!==e.connectionName||i.segmentId===e.segmentId)continue;if(i.capacityMeshNodeIds.some(t=>e.capacityMeshNodeIds.includes(t))){const o=`${i.segmentPointId}-${e.segmentPointId}`;if(n.has(o))continue;n.add(o);const r=i.z===e.z,s=i.z;let a;a=r?0===s?void 0:"10 5":"3 3 10",t.lines.push({points:[{x:i.x,y:i.y},{x:e.x,y:e.y}],strokeDash:a,strokeColor:this.colorMap[i.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 o=t.get(n);o&&o.portPoints.push({x:e.x,y:e.y,z:e.z,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName})}return Array.from(t.values())}};function fl(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var yl=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=Yo(t).padDiameter,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),r=n.targetMinCapacity??.5;n.capacityDepth=$s(i,r)}this.connMap=ii(t),this.colorMap=wo(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;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=[fl("netToPointPairsSolver",ga,t=>[t.srj,t.colorMap,ri(t.srj)],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,this.connMap),t.connMap=ii(t.srjWithPointPairs)}}),fl("nodeSolver",kc,t=>[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.finishedNodes}}),fl("singleLayerNodeMerger",nl,t=>[t.nodeSolver?.finishedNodes],{onSolved:t=>{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),fl("strawSolver",ol,t=>[{nodes:t.singleLayerNodeMerger?.newNodes}],{onSolved:t=>{t.capacityNodes=t.strawSolver?.getResultNodes()}}),fl("edgeSolver",ui,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),fl("deadEndSolver",Qc,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)))}}),fl("initialPathingSolver",Bc,t=>[{simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,hyperParameters:{MAX_CAPACITY_FACTOR:1}}]),fl("pathingOptimizer",Kc,t=>[{initialPathingSolver:t.initialPathingSolver,simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,cacheProvider:t.cacheProvider,hyperParameters:{MAX_CAPACITY_FACTOR:1}}]),fl("edgeToPortSegmentSolver",Nc,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.pathingOptimizer?.getCapacityPaths()||[],colorMap:t.colorMap}]),fl("segmentToPointSolver",Lc,t=>{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments&&t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=>{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),fl("unravelMultiSectionSolver",gl,t=>[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),fl("highDensityRouteSolver",zs,t=>[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth}]),fl("highDensityStitchSolver",tl,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),fl("traceSimplificationSolver",vc,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(),o=this.singleLayerNodeMerger?.visualize(),i=this.strawSolver?.visualize(),r=this.edgeSolver?.visualize(),s=this.deadEndSolver?.visualize(),a=this.initialPathingSolver?.visualize(),c=this.pathingOptimizer?.visualize(),l=this.edgeToPortSegmentSolver?.visualize(),d=this.segmentToPointSolver?.visualize(),h=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),u=this.highDensityRouteSolver?.visualize(),p=this.highDensityStitchSolver?.visualize(),m=this.traceSimplificationSolver?.visualize(),g=this.srj.outline,f=[];if(f.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)"}),g&&g.length>=2){const t=g.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),f.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const y=Oo(this.srj),_={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,layer:Fo(e,this.srj.layerCount),label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).filter(t=>!t.isCopperPour).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)",layer:jo(t,this.srj.layerCount),label:y(t)}))],lines:f},b=[_,t,e,n,o,i,r,s,a,c,l,d,h,u?pi(_,u):null,p,m,this.solved?pi({lines:f},Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...b)}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 o=n.__netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.__netConnectionName,i=e.filter(t=>t.connectionName===n.name);for(let e=0;e<i.length;e++){const r=i[e],s={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount)};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}};function _l(t){const{pos:e,segments:n,dir:o,keepoutRadius:i}=t;let r=1/0;const s=i/4,a={x:e.x-o.x*s,y:e.y-o.y*s},c={x:e.x+o.x*s,y:e.y+o.y*s};for(const t of n){const e=Oe(a,c,t.start,t.end);r=Math.min(r,e)}return r}function bl(t,e,n,o){const i=xl(n,o,t),r=xl(n,o,e),s=xl(t,e,n),a=xl(t,e,o);if((i>0&&r<0||i<0&&r>0)&&(s>0&&a<0||s<0&&a>0))return!0;const c=1e-4;return!!(Math.abs(i)<c&&vl(n,o,t))||(!!(Math.abs(r)<c&&vl(n,o,e))||(!!(Math.abs(s)<c&&vl(t,e,n))||!!(Math.abs(a)<c&&vl(t,e,o))))}function xl(t,e,n){return(n.x-t.x)*(e.y-t.y)-(e.x-t.x)*(n.y-t.y)}function vl(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 Sl(t,e,n){for(const o of n)if(bl(t,e,o.start,o.end))return!1;return!0}var Il=1e-4;function Cl(t){const e=t.width/2,n=t.height/2,o=t.center.x,i=t.center.y,r={x:o-e,y:i+n},s={x:o+e,y:i+n},a={x:o-e,y:i-n},c={x:o+e,y:i-n};return[{start:r,end:s},{start:s,end:c},{start:c,end:a},{start:a,end:r}]}function Pl(t,e,n=.1){const o=e.x-t.x,i=e.y-t.y,r=Math.sqrt(o*o+i*i);if(0===r)return[];const s=-(i/r),a=o/r,c=n/2;return[{start:{x:t.x+s*c,y:t.y+a*c},end:{x:e.x+s*c,y:e.y+a*c}},{start:{x:t.x-s*c,y:t.y-a*c},end:{x:e.x-s*c,y:e.y-a*c}}]}function Ml(t,e,n){const o=Math.hypot(t.start.x-e.x,t.start.y-e.y),i=Math.hypot(t.end.x-e.x,t.end.y-e.y);if(o<=n||i<=n)return!0;const r=t.end.x-t.start.x,s=t.end.y-t.start.y,a=r*r+s*s;if(0===a)return!1;const c=Math.max(0,Math.min(1,((e.x-t.start.x)*r+(e.y-t.start.y)*s)/a)),l=t.start.x+c*r,d=t.start.y+c*s;return Math.hypot(l-e.x,d-e.y)<=n}function Nl(t,e,n){if(!n||0===n.length)return!1;for(const o of n){const n=Math.abs(t.x-o.start.x)<Il&&Math.abs(t.y-o.start.y)<Il&&Math.abs(e.x-o.end.x)<Il&&Math.abs(e.y-o.end.y)<Il,i=Math.abs(t.x-o.end.x)<Il&&Math.abs(t.y-o.end.y)<Il&&Math.abs(e.x-o.start.x)<Il&&Math.abs(e.y-o.start.y)<Il;if(n||i)return!0}return!1}function wl(t,e,n,o,i){const r=[];for(let s=0;s<t.length-1;s++){const a=t[s],c=t[s+1];Nl(a,c,i)||Ml({start:a,end:c},n,o+e)&&r.push(...Pl(a,c,e))}return r}var Tl=1e-4;function Rl(t,e,n,o){const i=e.x-t.x,r=e.y-t.y,s=o.x-n.x,a=o.y-n.y,c=i*a-r*s;if(Math.abs(c)<1e-10)return null;const l=n.x-t.x,d=n.y-t.y,h=(l*a-d*s)/c,u=(l*r-d*i)/c,p=1e-6;return h>p&&h<.999999&&u>p&&u<.999999?{x:t.x+h*i,y:t.y+h*r}:null}function El(t,e){if(!e||0===e.length)return!1;for(const n of e)if(Math.abs(t.x-n.start.x)<Tl&&Math.abs(t.y-n.start.y)<Tl||Math.abs(t.x-n.end.x)<Tl&&Math.abs(t.y-n.end.y)<Tl)return!0;return!1}function Al(t,e,n,o){if(!o||0===o.length)return!1;for(let i=e;i<=n;i++)if(i>=0&&i<t.length&&El(t[i],o))return!0;return!1}var Ol=1e-4,kl=class extends si{constructor(t){super(),this.input=t;const e=t.srj?.layerCount??2;this.input={...t,obstacles:Kr(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 Na("flatbush",n),this.boardOutlineRoutes=this.createBoardOutlineRoutes(),this.hdRouteSHI=new ji([...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 o=this.obstacleSHI.searchArea(t.x,t.y,.01,.01).filter(e=>e.__zLayers?.includes(t.z));if(0===o.length)continue;const i=o[0];this.input.connMap.addConnections([[e,n,...i.offBoardConnectsTo??[],i.obstacleId,...i.connectedTo].filter(Boolean)])}}input;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 o of t.jumpers){let t=-1,i=1/0;for(let e=0;e<n.length-1;e++){const r=n[e],s=n[e+1],a=Math.sqrt((r.x-o.start.x)**2+(r.y-o.start.y)**2),c=Math.sqrt((s.x-o.end.x)**2+(s.y-o.end.y)**2),l=a+c,d=Math.sqrt((r.x-o.end.x)**2+(r.y-o.end.y)**2),h=Math.sqrt((s.x-o.start.x)**2+(s.y-o.start.y)**2),u=d+h,p=Math.min(l,u);(l<=u?a:d)<1&&(l<=u?c:h)<1&&p<i&&(i=p,t=e)}t>=0&&e.set(t,o)}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=Xi([...this.processedRoutes],this.currentScheduleIndex),this.smoothedCursorRoutes=[...this.unprocessedRoutes],this.processedRoutes=[],void(this.hdRouteSHI=new ji([...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:o,keepoutRadius:i}=t;if(0===o.length)return null;const r=1e-4,s=e.x-n.x,a=e.y-n.y,c=Math.sqrt(s*s+a*a),l=c>r?{x:s/c,y:a/c}:{x:1,y:0},d=-l.y,h=l.x,u=_l({pos:e,segments:o,dir:l,keepoutRadius:i});if(u>=i)return null;for(let t=1;t<=20;t++){const n=t/20*i,r={x:e.x+d*n,y:e.y+h*n},s=_l({pos:r,segments:o,dir:l,keepoutRadius:i}),a={x:e.x-d*n,y:e.y-h*n},c=_l({pos:a,segments:o,dir:l,keepoutRadius:i}),u=s>=i&&Sl(e,r,o),p=c>=i&&Sl(e,a,o);if(u&&p)return s>=c?r:a;if(u)return r;if(p)return a}const p=i,m=[];for(let t=-60;t<=60;t++){const n=t/60*p,r={x:e.x+d*n,y:e.y+h*n},s=_l({pos:r,segments:o,dir:l,keepoutRadius:i}),a=Sl(e,r,o);m.push({pos:r,clearance:s,dist:Math.abs(n),pathClear:a,index:t})}const g=m.filter(t=>t.pathClear),f=m.findIndex(t=>0===t.index),y=f>=0?f:Math.floor(m.length/2);let _=null;for(let t=y+1;t<m.length-1;t++){const e=m[t-1],n=m[t],o=m[t+1];if(n.clearance>=e.clearance&&n.clearance>=o.clearance){_=n;break}}let b=null;for(let t=y-1;t>0;t--){const e=m[t-1],n=m[t],o=m[t+1];if(n.clearance>=e.clearance&&n.clearance>=o.clearance){b=n;break}}let x=null,v=null;if(g.length>0){const t=g.findIndex(t=>0===t.index),e=t>=0?t:Math.floor(g.length/2);for(let t=e+1;t<g.length-1;t++){const e=g[t-1],n=g[t],o=g[t+1];if(n.clearance>=e.clearance&&n.clearance>=o.clearance){x=n;break}}for(let t=e-1;t>0;t--){const e=g[t-1],n=g[t],o=g[t+1];if(n.clearance>=e.clearance&&n.clearance>=o.clearance){v=n;break}}}const S=[_,b,x,v,m.find(t=>0===t.index)].filter(t=>null!=t),I=new Set,C=S.filter(t=>{const e=`${t.pos.x.toFixed(6)},${t.pos.y.toFixed(6)}`;return!I.has(e)&&(I.add(e),!0)});if(0===C.length){let t=m[0];if(!t)return null;for(const e of m)e.clearance>t.clearance&&(t=e);return Math.sqrt((t.pos.x-e.x)**2+(t.pos.y-e.y)**2)>r?t.pos:null}let P;if(u<.15*i){P=C[0];for(const t of C)t.clearance>P.clearance&&(P=t)}else{const t=C.filter(t=>t.pathClear),e=t.length>0?t:C;P=e[0];for(const t of e)t.clearance>P.clearance&&(P=t)}return Math.sqrt((P.pos.x-e.x)**2+(P.pos.y-e.y)**2)>r?P.pos:null}({cursorPosition:this.cursorPosition,lastCursorPosition:this.lastCursorPosition,collidingSegments:e,keepoutRadius:this.currentKeepoutRadius});this.drawPosition=n??{...this.cursorPosition};const o=this.recordedDrawPositions[this.recordedDrawPositions.length-1];if(o&&this.drawPosition){const t={x:o.x,y:o.y,z:o.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>Ol?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],o=t[this.currentTraceSegmentIndex+1],i=Math.sqrt((e.x-n.start.x)**2+(e.y-n.start.y)**2),r=Math.sqrt((e.x-n.end.x)**2+(e.y-n.end.y)**2),s=i<=r?n.start:n.end,a=i<=r?n.end:n.start;return this.recordedDrawPositions.push({x:s.x,y:s.y,z:e.z,insideJumperPad:!0}),this.recordedDrawPositions.push({x:a.x,y:a.y,z:o.z,insideJumperPad:!0}),this.cursorPosition={x:a.x,y:a.y,z:o.z},this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0,"jumper"}const o=t[this.currentTraceSegmentIndex],i=t[this.currentTraceSegmentIndex+1],r=i.x-o.x,s=i.y-o.y,a=Math.sqrt(r*r+s*s);if(0===a){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const c=this.currentTraceSegmentT*a,l=a-c;if(e<=l){const t=c+e;return this.currentTraceSegmentT=t/a,this.cursorPosition={x:o.x+r*this.currentTraceSegmentT,y:o.y+s*this.currentTraceSegmentT,z:o.z},"stepped"}if(e-=l,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,o=[],i=this.obstacleSHI.searchArea(t.x,t.y,n,n).filter(e=>e.__zLayers?.includes(t.z));for(const n of i){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 i=!1;for(const t of n.connectedTo)if(this.input.connMap.areIdsConnected(e,t)){i=!0;break}i||o.push(...Cl(n))}const r=this.hdRouteSHI.getConflictingRoutesNearPoint({x:t.x,y:t.y,z:t.z},n);for(const{conflictingRoute:i}of r){const r=i.rootConnectionName??i.connectionName;if(r===e)continue;if(this.input.connMap.areIdsConnected(e,r))continue;const s=i.traceThickness??.15;o.push(...wl(i.route,s,{x:t.x,y:t.y},n,i.jumpers))}return o}positionHasCollision(t,e=0){const n=this.getCollidingSegments(t);for(const o of n)if(be(t,o.start,o.end)<=this.currentKeepoutRadius+e)return!0;return!1}segmentIntersectsOtherRoutes(t,e){if(!this.currentTrace)return!1;const n=this.currentTrace.rootConnectionName??this.currentTrace.connectionName,o=[...this.unprocessedRoutes,...this.smoothedCursorRoutes,...this.processedRoutes];for(const i of o){if((i.rootConnectionName??i.connectionName)!==n)for(let n=0;n<i.route.length-1;n++){const o=i.route[n],r=i.route[n+1];if((o.z===t.z||r.z===t.z)&&((!o.insideJumperPad||!r.insideJumperPad)&&fe({x:t.x,y:t.y},{x:e.x,y:e.y},{x:o.x,y:o.y},{x:r.x,y:r.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],o=!0;for(;o;){o=!1;for(let t=0;t<n.length-1&&!o;t++){const i=n[t],r=n[t+1];if(i.z===r.z)for(let s=t+2;s<n.length-1&&!o;s++){if(s===t+1)continue;const a=n[s],c=n[s+1];if(a.z!==c.z||i.z!==a.z)continue;const l=Rl(i,r,a,c);if(l){if(Al(n,t+1,s,e))continue;const r=[];for(let e=0;e<=t;e++)r.push(n[e]);r.push({x:l.x,y:l.y,z:i.z});for(let t=s+1;t<n.length;t++)r.push(n[t]);n=r,o=!0}}}}return n}(this.simplifyRoute(this.recordedDrawPositions,this.currentTrace.jumpers),this.currentTrace.jumpers),o={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(o),this.hdRouteSHI.removeRoute(this.currentTrace.connectionName),this.hdRouteSHI.addRoute(o),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)<Ol&&Math.abs(t.y-n.start.y)<Ol||Math.abs(t.x-n.end.x)<Ol&&Math.abs(t.y-n.end.y)<Ol)return!0;return!1}simplifyRoute(t,e){if(t.length<=2)return t;const n=[t[0]];for(let o=1;o<t.length-1;o++){const i=n[n.length-1],r=t[o],s=t[o+1];if(this.isJumperEndpoint(r,e)){n.push(r);continue}if(r.z!==i.z||r.z!==s.z){n.push(r);continue}const a=r.x-i.x,c=r.y-i.y,l=s.x-r.x,d=a*(s.y-r.y)-c*l,h=1e-6;Math.abs(d)>h&&n.push(r)}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 o;o=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 i=this.input.srj.layerCount??2;for(let e=0;e<o.length;e++){const n=o[e],r=o[(e+1)%o.length];for(let o=0;o<i;o++)t.push({connectionName:`__board_outline___${e}_z${o}`,traceThickness:.01,viaDiameter:0,route:[{x:n.x,y:n.y,z:o},{x:r.x,y:r.y,z:o}],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 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:"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",o=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:o,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 o=e.__zLayers?.includes(0),i=e.__zLayers?.includes(1);o&&i?n="rgba(128, 0, 128, 0.2)":o?n="rgba(255, 0, 0, 0.2)":i&&(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 o;o=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<o.length;e++){const n=o[e],i=o[(e+1)%o.length];t.lines.push({points:[{x:n.x,y:n.y},{x:i.x,y:i.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",o=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 i=e.route[n],r=e.route[n+1],s=Math.abs(i.x-t.start.x)<Ol&&Math.abs(i.y-t.start.y)<Ol&&Math.abs(r.x-t.end.x)<Ol&&Math.abs(r.y-t.end.y)<Ol,a=Math.abs(i.x-t.end.x)<Ol&&Math.abs(i.y-t.end.y)<Ol&&Math.abs(r.x-t.start.x)<Ol&&Math.abs(r.y-t.start.y)<Ol;if(s||a){o.add(n);break}}for(let n=0;n<e.route.length-1;n++){const i=e.route[n],r=e.route[n+1];o.has(n)?t.lines.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:"rgba(128, 128, 128, 0.6)",strokeDash:"2 2",label:`${e.connectionName} (jumper segment - fixed)`}):i.z===r.z&&t.lines.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:0===i.z?"red":"blue",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${i.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 o=_a(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...o.rects??[]),t.lines.push(...o.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],o=this.recordedDrawPositions[e+1];t.lines.push({points:[{x:n.x,y:n.y},{x:o.x,y:o.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,o=Math.sqrt(e*e+n*n),i=o>1e-4?{x:e/o,y:n/o}:{x:1,y:0},r=this.currentKeepoutRadius/4,s={x:this.cursorPosition.x-i.x*r,y:this.cursorPosition.y-i.y*r},a={x:this.cursorPosition.x+i.x*r,y:this.cursorPosition.y+i.y*r};t.lines.push({points:[s,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 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:"gray"})}return t}getRedrawnHdRoutes(){return this.redrawnHdRoutes}},Ll=class extends si{constructor(t){super(),this.input=t,this.unprocessedObstacles=Kr(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 fa({}),this.offBoardConnMap.addConnections(this.unprocessedObstacles.filter(t=>t.offBoardConnectsTo?.length).map(t=>[t.obstacleId,...t.offBoardConnectsTo??[]])),this.nodeTree=new hi(this.input.capacityMeshNodes)}input;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),o=n.map(t=>t.capacityMeshNodeId),i=this.nodesInNet.get(e)??[],r=[...i.map(t=>t.capacityMeshNodeId),...o];for(const t of i)t._offBoardConnectedCapacityMeshNodeIds=r;for(const t of n)t._offBoardConnectedCapacityMeshNodeIds=r,t._offBoardConnectionId=e;this.nodesInNet.set(e,[...i,...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 o of n)t.rects.push({center:o.center,width:o.width,height:o.height,fill:Ro(e,.2),label:`OffBoardConn: ${e}`});for(const o of n)for(const i of n)o.capacityMeshNodeId!==i.capacityMeshNodeId&&t.lines.push({points:[o.center,i.center],strokeColor:Ro(e,1)})}return t}},Dl=.1,zl=.1;function Fl(t,e,n,o,i,r){return(i-t)*(o-e)-(r-e)*(n-t)}function Bl(t,e,n,o,i,r){return Math.min(t,n)<=i&&i<=Math.max(t,n)&&Math.min(e,o)<=r&&r<=Math.max(e,o)}function jl(t,e,n,o,i,r,s,a){const c=Fl(i,r,s,a,t,e),l=Fl(i,r,s,a,n,o),d=Fl(t,e,n,o,i,r),h=Fl(t,e,n,o,s,a);return(c>0&&l<0||c<0&&l>0)&&(d>0&&h<0||d<0&&h>0)||(!(0!==c||!Bl(i,r,s,a,t,e))||(!(0!==l||!Bl(i,r,s,a,n,o))||(!(0!==d||!Bl(t,e,n,o,i,r))||!(0!==h||!Bl(t,e,n,o,s,a)))))}function $l(t,e,n,o,i,r){const s=i-n,a=r-o,c=t-n,l=e-o,d=s*s+a*a;if(0===d){return{x:n,y:o,distSq:c*c+l*l}}let h=(c*s+l*a)/d;h=Math.max(0,Math.min(1,h));const u=n+h*s,p=o+h*a,m=t-u,g=e-p;return{x:u,y:p,distSq:m*m+g*g}}var Yl=class extends si{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:o=.3,pushMargin:i=.3,numMovablePoints:r=2}){if(super(),r<1||r>3)throw new Error(`numMovablePoints must be 1, 2, or 3, got ${r}`);this.allNodes=[...t],this.unsolvedNodes=[...t],this.colorMap=e??{},this.routes=[],this.traceWidth=n,this.viaDiameter=o,this.numMovablePoints=r,this.pushMargin=i,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,o=t.center.y-t.height/2,i=t.center.y+t.height/2;this.currentNodeBounds={minX:e,maxX:n,minY:o,maxY:i};const r=new Map;for(const e of t.portPoints)r.has(e.connectionName)||r.set(e.connectionName,[]),r.get(e.connectionName).push({x:e.x,y:e.y,z:e.z,rootConnectionName:e.rootConnectionName});for(const[t,e]of r){if(e.length<2)continue;const n=e[0],o=e[e.length-1],i=n.z,r=o.x-n.x,s=o.y-n.y,a=Math.sqrt(r*r+s*s),c=a>0?r/a:0,l=a>0?s/a:0,d=[];this.numMovablePoints>=1&&d.push({x:n.x+c*zl,y:n.y+l*zl,z:i,rootConnectionName:n.rootConnectionName,connectionName:t}),this.numMovablePoints>=2&&d.push({x:o.x-c*zl,y:o.y-l*zl,z:i,rootConnectionName:n.rootConnectionName,connectionName:t}),this.numMovablePoints>=3&&d.push({x:n.x+r/2,y:n.y+s/2,z:i,rootConnectionName:n.rootConnectionName,connectionName:t}),this.routesInProgress.push({connectionName:t,rootConnectionName:n.rootConnectionName,startPoint:{x:n.x,y:n.y,z:i},endPoint:{x:o.x,y:o.y,z:i},movablePoints:d})}}_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 o=.3+this.pushMargin,i=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}),i.set(t,e)}for(const r of e){const e=n.get(r),s=r.x-t.minX,a=t.maxX-r.x,c=t.maxY-r.y,l=r.y-t.minY;s<o&&(e.fx+=Dl*(o-s)),a<o&&(e.fx-=Dl*(o-a)),l<o&&(e.fy+=Dl*(o-l)),c<o&&(e.fy-=Dl*(o-c));for(const t of this.routesInProgress){if(t.rootConnectionName===r.rootConnectionName)continue;const s=i.get(t);for(let t=0;t<s.length-1;t++){const i=s[t],a=s[t+1],c=$l(r.x,r.y,i.x,i.y,a.x,a.y),l=Math.sqrt(c.distSq);if(l>0&&l<2*o){const t=r.x-c.x,o=r.y-c.y,s=.002/c.distSq,l=s*t,d=s*o;e.fx+=l,e.fy+=d;const h=i.movablePoint,u=a.movablePoint;if(h&&u){const t=n.get(h),e=n.get(u);t.fx-=l/2,t.fy-=d/2,e.fx-=l/2,e.fy-=d/2}else if(h){const t=n.get(h);t.fx-=l,t.fy-=d}else if(u){const t=n.get(u);t.fx-=l,t.fy-=d}}}}}const r=t=>t.movablePoint?{x:t.movablePoint.x,y:t.movablePoint.y}:{x:t.x,y:t.y},s=t=>{let e=null;for(const n of this.routesInProgress)if(n.movablePoints.includes(t)){e=n;break}if(!e)return!1;const n=i.get(e);let o=-1;for(let e=0;e<n.length;e++)if(n[e].movablePoint===t){o=e;break}if(-1===o)return!1;const s=[];if(o>0){const e=r(n[o-1]);s.push({ax:e.x,ay:e.y,bx:t.x,by:t.y})}if(o<n.length-1){const e=r(n[o+1]);s.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=i.get(t);for(let t=0;t<n.length-1;t++){const e=r(n[t]),o=r(n[t+1]);for(const t of s)if(jl(t.ax,t.ay,t.bx,t.by,e.x,e.y,o.x,o.y))return!0}}return!1};for(const o of e){const e=n.get(o);o.forceX=e.fx,o.forceY=e.fy;const i=o.x,r=o.y;o.x+=e.fx,o.y+=e.fy,o.x=Math.max(t.minX,Math.min(t.maxX,o.x)),o.y=Math.max(t.minY,Math.min(t.maxY,o.y)),s(o)&&(o.x=i,o.y=r)}}_finalizeRoutesForCurrentNode(){for(const t of this.routesInProgress){const{connectionName:e,rootConnectionName:n,startPoint:o,endPoint:i,movablePoints:r}=t,s=[{x:o.x,y:o.y,z:o.z}];1===r.length?s.push({x:r[0].x,y:r[0].y,z:r[0].z}):2===r.length?(s.push({x:r[0].x,y:r[0].y,z:r[0].z}),s.push({x:r[1].x,y:r[1].y,z:r[1].z})):3===r.length&&(s.push({x:r[0].x,y:r[0].y,z:r[0].z}),s.push({x:r[2].x,y:r[2].y,z:r[2].z}),s.push({x:r[1].x,y:r[1].y,z:r[1].z})),s.push({x:i.x,y:i.y,z:i.z});const a={connectionName:e,rootConnectionName:n,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:s,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,o]of n)o.length<2||t.lines.push({points:o.map(t=>({x:t.x,y:t.y})),label:e,strokeColor:"gray",strokeWidth:this.traceWidth})}for(const e of this.routes){const n=mi(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const o of n)t.lines.push({points:o.points,label:o.connectionName,strokeColor:0===o.z?o.color:To(o.color,.75),layer:`z${o.z}`,strokeWidth:e.traceThickness,strokeDash:0!==o.z?"10, 5":void 0});const o=e.route;for(let e=0;e<o.length;e++){const n=o[e],i=0===e,r=e===o.length-1,s=!i&&!r;let a;a=i?"start":r?"end":`M${e}`,t.points.push({x:n.x,y:n.y,label:a,color:s?"orange":"blue"})}}for(const e of this.routesInProgress){const{startPoint:n,endPoint:o,movablePoints:i,connectionName:r}=e,s=this.colorMap[r]??"gray",a=[{x:n.x,y:n.y}];1===i.length?a.push({x:i[0].x,y:i[0].y}):2===i.length?(a.push({x:i[0].x,y:i[0].y}),a.push({x:i[1].x,y:i[1].y})):3===i.length&&(a.push({x:i[0].x,y:i[0].y}),a.push({x:i[2].x,y:i[2].y}),a.push({x:i[1].x,y:i[1].y})),a.push({x:o.x,y:o.y}),t.lines.push({points:a,label:r,strokeColor:s,strokeWidth:this.traceWidth}),t.points.push({x:n.x,y:n.y,label:"start",color:"blue"});for(let e=0;e<i.length;e++){const n=i[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 o=5;t.lines.push({points:[{x:n.x,y:n.y},{x:n.x+n.forceX*o,y:n.y+n.forceY*o}],strokeColor:"red",strokeWidth:.02,label:`F${e+1}`});const i=.05,r=n.x+n.forceX*o,s=n.y+n.forceY*o,a=Math.atan2(n.forceY,n.forceX);t.lines.push({points:[{x:r,y:s},{x:r-i*Math.cos(a-Math.PI/6),y:s-i*Math.sin(a-Math.PI/6)}],strokeColor:"red",strokeWidth:.02}),t.lines.push({points:[{x:r,y:s},{x:r-i*Math.cos(a+Math.PI/6),y:s-i*Math.sin(a+Math.PI/6)}],strokeColor:"purple",strokeWidth:.02})}}}t.points.push({x:o.x,y:o.y,label:"end",color:"blue"})}return t}},Xl=({connMap:t,connectionsWithResults:e,inputNodes:n,obstacles:o})=>{const i=o.filter(t=>t.offBoardConnectsTo?.length);if(0===i.length)return;const r=new ti({});r.addConnections(i.map((t,e)=>[t.obstacleId??`__obs${e}`,...t.offBoardConnectsTo??[]]));const s=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,o=new Set;for(const t of n.path){const e=s.get(t.currentNodeId);if(e?._offBoardConnectionId&&o.add(e._offBoardConnectionId),t.throughNodeId){const e=s.get(t.throughNodeId);e?._offBoardConnectionId&&o.add(e._offBoardConnectionId)}}for(const n of o){const o=r.getIdsConnectedToNet(n);o?.length&&t.addConnections([[e,...o]])}}};function Vl(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var Wl=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.viaDiameter=Yo(t).padDiameter,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),r=n.targetMinCapacity??.5;n.capacityDepth=$s(i,r)}this.connMap=ii(t),this.colorMap=wo(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;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=[Vl("netToPointPairsSolver",ma,t=>[t.srj,t.colorMap,ri(t.srj)],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,this.connMap),t.connMap=ii(t.srjWithPointPairs)}}),Vl("nodeSolver",Kn,t=>[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),Vl("relateNodesToOffBoardConnections",Ll,t=>[{capacityMeshNodes:t.capacityNodes,srj:t.srj}],{onSolved:t=>{t.capacityNodes=t.relateNodesToOffBoardConnections?.getOutput().capacityNodes}}),Vl("edgeSolver",ui,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Vl("availableSegmentPointSolver",ci,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),Vl("portPointPathingSolver",ea,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])),o=t.availableSegmentPointSolver;for(const t of o.sharedEdgeSegments)for(const e of t.portPoints){const[o,i]=e.nodeIds,r={portPointId:e.segmentPortPointId,x:e.x,y:e.y,z:e.availableZ[0]??0,connectionNodeIds:[o,i],distToCentermostPortOnZ:e.distToCentermostPortOnZ,connectsToOffBoardNode:t.nodeIds.some(t=>n.get(t)?._offBoardConnectionId)},s=n.get(o);s&&s.portPoints.push(r)}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&&Xl({connMap:t.connMap,connectionsWithResults:e.connectionsWithResults,inputNodes:e.inputNodes,obstacles:t.srj.obstacles})}}),Vl("multiSectionPortPointOptimizer",ia,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}]}),Vl("highDensitySolver",Yl,t=>[{nodePortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,connMap:t.connMap}]),Vl("highDensityStitchSolver",Ca,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensitySolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),Vl("traceSimplificationSolver",vc,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}]),Vl("traceKeepoutSolver",kl,t=>[{hdRoutes:t.traceSimplificationSolver?.simplifiedHdRoutes??[],obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,srj:t.srj}]),Vl("traceWidthSolver",Ic,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(),o=this.singleLayerNodeMerger?.visualize(),i=this.strawSolver?.visualize(),r=this.edgeSolver?.visualize(),s=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.offboardPathFragmentSolver?.visualize(),l=this.portPointPathingSolver?.visualize(),d=this.multiSectionPortPointOptimizer?.visualize(),h=this.highDensityRouteSolver?.visualize(),u=this.highDensitySolver?.visualize(),p=this.simpleHighDensityRouteSolver?.visualize(),m=this.highDensityStitchSolver?.visualize(),g=this.traceSimplificationSolver?.visualize(),f=this.traceKeepoutSolver?.visualize(),y=this.traceWidthSolver?.visualize(),_=this.srj.outline,b=[];if(b.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)"}),_&&_.length>=2){const t=_.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),b.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const x=Oo(this.srj),v={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,layer:Fo(e,this.srj.layerCount),label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).filter(t=>!t.isCopperPour).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)",layer:jo(t,this.srj.layerCount),label:x(t)}))],lines:b},S=[v,t,e,n,o,i,r,s,a,c,l,d,h?pi(v,h):null,u?pi(v,u):null,p?pi(v,p):null,m,g,f,y,this.solved?pi({lines:b},Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...S)}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 o=t[n];if(e.push({points:o.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[o.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.flatMap(t=>t.__rootConnectionNames??[t.name]));for(const[n,o]of this.srj.obstacles.entries()){if(!o.offBoardConnectsTo?.length)continue;const i=o.obstacleId??`__obs${n}`,r=this.connMap.getNetConnectedToId(i);if(!r)continue;const s=this.connMap.getIdsConnectedToNet(r).find(t=>e.has(t));s&&(t[i]=s)}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 o=n.__netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.__netConnectionName,i=e.filter(t=>t.connectionName===n.name);for(let e=0;e<i.length;e++){const r=i[e],s={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount)};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},Hl=class extends si{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 o=new Map;for(const e of t.hdRoutes){const t=o.get(e.connectionName);t?t.push(e):o.set(e.connectionName,[e])}this.unsolvedRoutes=[];for(const[e,i]of o.entries()){const o=t.connections.find(t=>t.name===e);if(!o)continue;const r=n.get(e);let s=[];r?.path&&(s=r.path.map(t=>t.currentNodeId));const a={...o.pointsToConnect[0],z:ko(bo(o.pointsToConnect[0]),t.layerCount)},c={...o.pointsToConnect[1],z:ko(bo(o.pointsToConnect[1]),t.layerCount)};this.unsolvedRoutes.push({connectionName:e,hdRoutes:i,nodeOrder:s,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:o,start:i,end:r}=t;if(0===n.length)return{connectionName:e,traceThickness:this.defaultTraceThickness,viaDiameter:this.defaultViaDiameter,route:[i,r],vias:[],jumpers:[]};let s;s=o.length>0?this.orderRoutesByNodePath(n,o,i,e):this.orderRoutesByProximity(n,i);const a=[],c=[],l=[];a.push({x:i.x,y:i.y,z:i.z});for(let t=0;t<s.length;t++){const e=s[t],n=a[a.length-1],o=e.route[0],i=e.route[e.route.length-1],r=xe(n,o),d=xe(n,i),h=Math.min(r,d);if(t>0&&h>1)continue;let u;u=r<=d?[...e.route]:[...e.route].reverse();const p=.001;u.length>0&&xe(n,u[0])<p&&(u=u.slice(1)),a.push(...u),c.push(...e.vias),e.jumpers&&l.push(...e.jumpers)}const d=xe(a[a.length-1],r);return d>.001&&d<1&&a.push({x:r.x,y:r.y,z:r.z}),{connectionName:e,rootConnectionName:n[0]?.rootConnectionName,traceThickness:n[0]?.traceThickness??this.defaultTraceThickness,viaDiameter:n[0]?.viaDiameter??this.defaultViaDiameter,route:a,vias:c,jumpers:l}}orderRoutesByNodePath(t,e,n,o){if(0===t.length)return[];const i=new Set(t);let r=null,s=1/0;for(const t of i){const e=t.route[0],o=t.route[t.route.length-1],i=Math.min(xe(n,e),xe(n,o));i<s&&(s=i,r=t)}if(!r)return[];i.delete(r);const a=r.route[0],c=r.route[r.route.length-1];let l,d;xe(n,a)<=xe(n,c)?(l=a,d=c):(l=c,d=a);const h=(t,e)=>{let n=0;for(const o of i){if(o===e)continue;const i=o.route[0],r=o.route[o.route.length-1];(xe(t,i)<10||xe(t,r)<10)&&n++}return n},u=[r];let p=d;for(;i.size>0;){let t=null,e=1/0,n=-1;for(const o of i){const i=o.route[0],r=o.route[o.route.length-1],s=xe(p,i),a=xe(p,r),c=Math.min(s,a);if(c>=10)continue;const l=h(s<=a?r:i,o),d=0===l,u=0===n,m=c-e;let g=!1;g=null===t||(!!(!d&&u&&m<5)||!(d&&!u&&m>-5)&&c<e),g&&(e=c,t=o,n=l)}if(!t)break;{u.push(t),i.delete(t);const e=t.route[0],n=t.route[t.route.length-1];p=xe(p,e)<=xe(p,n)?n:e}}const m=[];for(p=l;i.size>0;){let t=null,e=1/0,o=-1;const r=xe(p,n);for(const s of i){const i=s.route[0],a=s.route[s.route.length-1],c=xe(p,i),l=xe(p,a),d=Math.min(c,l);if(d>=10)continue;const u=c<=l?a:i;if(xe(u,n)>r+2)continue;const m=h(u,s),g=0===m,f=0===o,y=d-e;let _=!1;_=null===t||(!!(!g&&f&&y<5)||!(g&&!f&&y>-5)&&d<e),_&&(e=d,t=s,o=m)}if(!t)break;{m.unshift(t),i.delete(t);const e=t.route[0],n=t.route[t.route.length-1];p=xe(p,e)<=xe(p,n)?n:e}}const g=[...m,...u];if(i.size>0){const e=[...i].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 ${i.size} routes for connection ${t[0]?.connectionName??"?"}, skipped routes: ${e.join("; ")}`)}return g}orderRoutesByProximity(t,e){const n=new Set(t),o=[];let i=e;for(;n.size>0;){let t=null,e=1/0,r=!1;for(const o of n){const n=o.route[0],s=o.route[o.route.length-1],a=xe(i,n),c=xe(i,s);a<e&&(e=a,t=o,r=!1),c<e&&(e=c,t=o,r=!0)}if(!t)break;{o.push(t),n.delete(t);const e=t.route[0],s=t.route[t.route.length-1];i=r?e:s}}return o}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Multiple High Density Route Stitch Solver 2"};for(const[e,n]of this.mergedHdRoutes.entries()){const o=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e<n.route.length-1;e++){const i=n.route[e],r=n.route[e+1],s=0!==i.z?To(o,.5):o;t.lines?.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:s,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?To(o,.5):o;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:o});if(n.jumpers&&n.jumpers.length>0){const e=_a(n.jumpers,{color:o,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 o=0;o<e.hdRoutes.length;o++){const i=e.hdRoutes[o];if(i.route.length>1&&t.lines?.push({points:i.route.map(t=>({x:t.x,y:t.y})),strokeColor:To(n,.5),strokeDash:"10 5",label:`segment ${o}`}),i.jumpers&&i.jumpers.length>0){const e=_a(i.jumpers,{color:n,label:i.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}}return t}},Gl=Object.create,Ul=Object.defineProperty,Zl=Object.getOwnPropertyDescriptor,ql=Object.getOwnPropertyNames,Jl=Object.getPrototypeOf,Kl=Object.prototype.hasOwnProperty,Ql=(t,e)=>function(){return e||(0,t[ql(t)[0]])((e={exports:{}}).exports,e),e.exports},td=(t,e,n)=>(n=null!=t?Gl(Jl(t)):{},((t,e,n,o)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let i of ql(e))Kl.call(t,i)||i===n||Ul(t,i,{get:()=>e[i],enumerable:!(o=Zl(e,i))||o.enumerable});return t})(!e&&t&&t.__esModule?n:Ul(n,"default",{value:t,enumerable:!0}),t)),ed=Ql({"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)}}}),nd=Ql({"node_modules/kind-of/index.js"(t,e){var n=ed(),o=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=o.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"}}}),od=Ql({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(n[e(o,t[o])||o]=t[o]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),id=Ql({"node_modules/deep-rename-keys/index.js"(t,e){var n=nd(),o=od();e.exports=function t(e,i){var r=n(e);if("object"!==r&&"array"!==r)throw new Error("expected an object");var s=[];for(var a in"object"===r&&(e=o(e,i),s={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?s[a]=t(c,i):s[a]=c}return s}}}),rd=Ql({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,o="~";function i(){}function r(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function s(){this._events=new i,this._eventsCount=0}Object.create&&(i.prototype=Object.create(null),(new i).__proto__||(o=!1)),s.prototype.eventNames=function(){var t,e,i=[];if(0===this._eventsCount)return i;for(e in t=this._events)n.call(t,e)&&i.push(o?e.slice(1):e);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},s.prototype.listeners=function(t,e){var n=o?o+t:t,i=this._events[n];if(e)return!!i;if(!i)return[];if(i.fn)return[i.fn];for(var r=0,s=i.length,a=new Array(s);r<s;r++)a[r]=i[r].fn;return a},s.prototype.emit=function(t,e,n,i,r,s){var a=o?o+t:t;if(!this._events[a])return!1;var c,l,d=this._events[a],h=arguments.length;if(d.fn){switch(d.once&&this.removeListener(t,d.fn,void 0,!0),h){case 1:return d.fn.call(d.context),!0;case 2:return d.fn.call(d.context,e),!0;case 3:return d.fn.call(d.context,e,n),!0;case 4:return d.fn.call(d.context,e,n,i),!0;case 5:return d.fn.call(d.context,e,n,i,r),!0;case 6:return d.fn.call(d.context,e,n,i,r,s),!0}for(l=1,c=new Array(h-1);l<h;l++)c[l-1]=arguments[l];d.fn.apply(d.context,c)}else{var u,p=d.length;for(l=0;l<p;l++)switch(d[l].once&&this.removeListener(t,d[l].fn,void 0,!0),h){case 1:d[l].fn.call(d[l].context);break;case 2:d[l].fn.call(d[l].context,e);break;case 3:d[l].fn.call(d[l].context,e,n);break;case 4:d[l].fn.call(d[l].context,e,n,i);break;default:if(!c)for(u=1,c=new Array(h-1);u<h;u++)c[u-1]=arguments[u];d[l].fn.apply(d[l].context,c)}}return!0},s.prototype.on=function(t,e,n){var i=new r(e,n||this),s=o?o+t:t;return this._events[s]?this._events[s].fn?this._events[s]=[this._events[s],i]:this._events[s].push(i):(this._events[s]=i,this._eventsCount++),this},s.prototype.once=function(t,e,n){var i=new r(e,n||this,!0),s=o?o+t:t;return this._events[s]?this._events[s].fn?this._events[s]=[this._events[s],i]:this._events[s].push(i):(this._events[s]=i,this._eventsCount++),this},s.prototype.removeListener=function(t,e,n,r){var s=o?o+t:t;if(!this._events[s])return this;if(!e)return 0===--this._eventsCount?this._events=new i:delete this._events[s],this;var a=this._events[s];if(a.fn)a.fn!==e||r&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new i:delete this._events[s]);else{for(var c=0,l=[],d=a.length;c<d;c++)(a[c].fn!==e||r&&!a[c].once||n&&a[c].context!==n)&&l.push(a[c]);l.length?this._events[s]=1===l.length?l[0]:l:0===--this._eventsCount?this._events=new i:delete this._events[s]}return this},s.prototype.removeAllListeners=function(t){var e;return t?(e=o?o+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new i:delete this._events[e])):(this._events=new i,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prototype.setMaxListeners=function(){return this},s.prefixed=o,s.EventEmitter=s,void 0!==e&&(e.exports=s)}}),sd=Ql({"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 o=rd(),i=function(){},r={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"},s={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={" ":s.space,"\t":s.space,"\n":s.space,"\r":s.space,"<":s.lt,">":s.gt,'"':s.quote,"'":s.quote,"=":s.equal,"/":s.slash};e.exports={State:r,Action:s,Type:a,create:function(t){var e,l,d,h,u,p,m,g,f,y;t=Object.assign({debug:!1},t);var _=new o,b=r.data,x="",v="",S="",I="",C="",P="",M=function(e,n){if("?"!==v[0]&&"!"!==v[0]){var o={type:e,value:n};t.debug&&console.log("emit:",o),_.emit("data",o)}};_.stateMachine=(n(y={},r.data,(n(e={},s.lt,function(){x.trim()&&M(a.text,x),v="",C=!1,b=r.tagBegin}),n(e,s.char,function(t){x+=t}),e)),n(y,r.cdata,n({},s.char,function(t){"]]>"===(x+=t).substr(-3)&&(M(a.text,x.slice(0,-3)),x="",b=r.data)})),n(y,r.tagBegin,(n(l={},s.space,i),n(l,s.char,function(t){v=t,b=r.tagName}),n(l,s.slash,function(){v="",C=!0}),l)),n(y,r.tagName,(n(d={},s.space,function(){C?b=r.tagEnd:(b=r.attributeNameStart,M(a.openTag,v))}),n(d,s.gt,function(){M(C?a.closeTag:a.openTag,v),x="",b=r.data}),n(d,s.slash,function(){b=r.tagEnd,M(a.openTag,v)}),n(d,s.char,function(t){"![CDATA["===(v+=t)&&(b=r.cdata,x="",v="")}),d)),n(y,r.tagEnd,(n(h={},s.gt,function(){M(a.closeTag,v),x="",b=r.data}),n(h,s.char,i),h)),n(y,r.attributeNameStart,(n(u={},s.char,function(t){S=t,b=r.attributeName}),n(u,s.gt,function(){x="",b=r.data}),n(u,s.space,i),n(u,s.slash,function(){C=!0,b=r.tagEnd}),u)),n(y,r.attributeName,(n(p={},s.space,function(){b=r.attributeNameEnd}),n(p,s.equal,function(){M(a.attributeName,S),b=r.attributeValueBegin}),n(p,s.gt,function(){I="",M(a.attributeName,S),M(a.attributeValue,I),x="",b=r.data}),n(p,s.slash,function(){C=!0,I="",M(a.attributeName,S),M(a.attributeValue,I),b=r.tagEnd}),n(p,s.char,function(t){S+=t}),p)),n(y,r.attributeNameEnd,(n(m={},s.space,i),n(m,s.equal,function(){M(a.attributeName,S),b=r.attributeValueBegin}),n(m,s.gt,function(){I="",M(a.attributeName,S),M(a.attributeValue,I),x="",b=r.data}),n(m,s.char,function(t){I="",M(a.attributeName,S),M(a.attributeValue,I),S=t,b=r.attributeName}),m)),n(y,r.attributeValueBegin,(n(g={},s.space,i),n(g,s.quote,function(t){P=t,I="",b=r.attributeValue}),n(g,s.gt,function(){M(a.attributeValue,I=""),x="",b=r.data}),n(g,s.char,function(t){P="",I=t,b=r.attributeValue}),g)),n(y,r.attributeValue,(n(f={},s.space,function(t){P?I+=t:(M(a.attributeValue,I),b=r.attributeNameStart)}),n(f,s.quote,function(t){P===t?(M(a.attributeValue,I),b=r.attributeNameStart):I+=t}),n(f,s.gt,function(t){P?I+=t:(M(a.attributeValue,I),x="",b=r.data)}),n(f,s.slash,function(t){P?I+=t:(M(a.attributeValue,I),C=!0,b=r.tagEnd)}),n(f,s.char,function(t){I+=t}),f)),y);var N=function(e){t.debug&&console.log(b,e);var n=_.stateMachine[b],o=n[function(t){return c[t]||s.char}(e)]||n[s.error]||n[s.char];o(e)};return _.write=function(t){for(var e=t.length,n=0;n<e;n++)N(t[n])},_}}}}),ad=Ql({"node_modules/xml-reader/dist/reader.js"(t,e){var n=rd(),o=sd(),i=o.Type,r={element:"element",text:"text"},s=function(t){return Object.assign({name:"",type:r.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,l=void 0,d=new n,h=function(n){switch(n.type){case i.openTag:if(null===c)(c=a).name=n.value;else{var o=s({name:n.value,parent:c});c.children.push(o),c=o}break;case i.closeTag:var h=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&h===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&h!==a||(d.emit(t.tagPrefix+c.name,c),d.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),d.emit(t.doneEvent,c),a=null),c=h;break;case i.text:c&&c.children.push(s({type:r.text,value:n.value,parent:t.parentNodes?c:null}));break;case i.attributeName:l=n.value,c.attributes[l]="";break;case i.attributeValue:c.attributes[l]=n.value}};return d.reset=function(){(e=o.create({debug:t.debug})).on("data",h),a=s(),c=null,l="",d.parse=e.write},d.reset(),d};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),o=void 0;return n.on("done",function(t){o=t}),n.parse(t),o},create:a,NodeType:r}}}),{cos:cd,sin:ld,PI:dd}=Math,{tan:hd}=Math,ud=(td(id()),td(ad()),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:[]}}}),pd=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)",md=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 gd(t,e){const{minX:n,maxX:o,minY:i,maxY:r}=e,s=o-n,a=r-i,c=1e-6;return Math.abs(t.y-r)<c?t.x-n:Math.abs(t.x-o)<c?s+(r-t.y):Math.abs(t.y-i)<c?s+a+(o-t.x):Math.abs(t.x-n)<c?2*s+a+(t.y-i):0}function fd(t,e){const{minX:n,maxX:o,minY:i,maxY:r}=e,s=1e-6,a=Math.abs(t.y-r)<s,c=Math.abs(t.y-i)<s,l=Math.abs(t.x-o)<s,d=Math.abs(t.x-n)<s;if(a&&l)return{x:-Math.SQRT1_2,y:-Math.SQRT1_2};if(a&&d)return{x:Math.SQRT1_2,y:-Math.SQRT1_2};if(c&&l)return{x:-Math.SQRT1_2,y:Math.SQRT1_2};if(c&&d)return{x:Math.SQRT1_2,y:Math.SQRT1_2};if(a)return{x:0,y:-1};if(c)return{x:0,y:1};if(l)return{x:-1,y:0};if(d)return{x:1,y:0};const h=(i+r)/2,u=(n+o)/2-t.x,p=h-t.y,m=Math.hypot(u,p);return m>0?{x:u/m,y:p/m}:{x:0,y:-1}}function yd(t,e,n,o,i,r,s,a,c,l){for(let d=0;d<=l;d++){const h=d/l,u=1-h,p=u*u,m=p*u,g=h*h,f=g*h,y=2*d;c[y]=m*t+3*p*h*n+3*u*g*i+f*s,c[y+1]=m*e+3*p*h*o+3*u*g*r+f*a}}function _d(t,e,n,o,i){const r=[];for(let s=0;s<=i;s++){const a=s/i,c=1-a,l=c*c,d=l*c,h=a*a,u=h*a;r.push({x:d*t.x+3*l*a*e.x+3*c*h*n.x+u*o.x,y:d*t.y+3*l*a*e.y+3*c*h*n.y+u*o.y})}return r}function bd(t,e,n,o,i,r){const s=i-n,a=r-o,c=s*s+a*a;if(0===c){const i=t-n,r=e-o;return i*i+r*r}const l=Math.max(0,Math.min(1,((t-n)*s+(e-o)*a)/c)),d=t-(n+l*s),h=e-(o+l*a);return d*d+h*h}function xd(t,e,n,o,i,r,s,a){const c=(s-i)*(e-r)-(a-r)*(t-i),l=(s-i)*(o-r)-(a-r)*(n-i),d=(n-t)*(r-e)-(o-e)*(i-t),h=(n-t)*(a-e)-(o-e)*(s-t);return(c>0&&l<0||c<0&&l>0)&&(d>0&&h<0||d<0&&h>0)?0:Math.min(bd(t,e,i,r,s,a),bd(n,o,i,r,s,a),bd(i,r,t,e,n,o),bd(s,a,t,e,n,o))}function vd(t,e,n,o,i,r,s,a){const c=(s-i)*(e-r)-(a-r)*(t-i),l=(s-i)*(o-r)-(a-r)*(n-i),d=(n-t)*(r-e)-(o-e)*(i-t),h=(n-t)*(a-e)-(o-e)*(s-t);return(c>0&&l<0||c<0&&l>0)&&(d>0&&h<0||d<0&&h>0)}function Sd(t,e,n,o,i){const r=t=>(t%i+i)%i,s=r(t),a=r(e),c=r(n),l=r(o),[d,h]=s<a?[s,a]:[a,s];return c>d&&c<h&&l>d&&l<h}function Id(t,e){let n=1/0,o=-1/0,i=1/0,r=-1/0;for(let s=0;s<e;s++){const e=t[2*s],a=t[2*s+1];e<n&&(n=e),e>o&&(o=e),a<i&&(i=a),a>r&&(r=a)}return{minX:n,maxX:o,minY:i,maxY:r}}var Cd=class extends ud{constructor(t){super(),this.problem=t;for(const t of this.problem.obstacles)t.outerSegments=md(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:o,minY:i,maxY:r}=t,s=o-n,a=r-i,c=2*s+2*a,l=function(t){return{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}}(t),d=e.map((e,n)=>({pair:e,t1:gd(e.start,t),t2:gd(e.end,t),idx:n})),h=d.map(()=>[]),u=d.map(()=>[]);for(const t of d)for(const e of d)if(t.idx!==e.idx){if(t.pair.networkId&&e.pair.networkId&&t.pair.networkId===e.pair.networkId)continue;Sd(e.t1,e.t2,t.t1,t.t2,c)&&(h[t.idx].push(e.idx),u[e.idx].push(t.idx))}const p=h.map(t=>t.length),m=Math.max(...p,1);this.traces=d.map(({pair:e,t1:n,t2:o,idx:i})=>{const r=fd(e.start,t),c=fd(e.end,t),d=Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),g=p[i]/m,f=(e.start.x+e.end.x)/2,y=(e.start.y+e.end.y)/2,_=d*(.25+.15*(1-Math.hypot(f-l.x,y-l.y)/Math.hypot(s/2,a/2)))*(1-.3*g),b=.05*Math.min(s,a),x=Math.max(b,_),v=Math.max(b,_);return{waypointPair:e,ctrl1:{x:e.start.x+x*r.x,y:e.start.y+x*r.y},ctrl2:{x:e.end.x+v*c.x,y:e.end.y+v*c.y},networkId:e.networkId,t1:n,t2:o,perpDir1:r,perpDir2:c,d1:x,d2:v,containedBy:h[i],contains:u[i]}}),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];yd(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]=Id(this.sampledPoints[t],6)}}updateSingleTraceSample(t){const e=this.traces[t];yd(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]=Id(this.sampledPoints[t],6)}updateControlPointsFromDistances(t){const e=this.traces[t],{minX:n,maxX:o,minY:i,maxY:r}=this.problem.bounds,s=1e-6;let a=e.waypointPair.start.x+e.d1*e.perpDir1.x,c=e.waypointPair.start.y+e.d1*e.perpDir1.y,l=e.waypointPair.end.x+e.d2*e.perpDir2.x,d=e.waypointPair.end.y+e.d2*e.perpDir2.y;const h=e.waypointPair.start;Math.abs(h.x-n)<s&&(a=Math.max(a,n)),Math.abs(h.x-o)<s&&(a=Math.min(a,o)),Math.abs(h.y-i)<s&&(c=Math.max(c,i)),Math.abs(h.y-r)<s&&(c=Math.min(c,r));const u=e.waypointPair.end;Math.abs(u.x-n)<s&&(l=Math.max(l,n)),Math.abs(u.x-o)<s&&(l=Math.min(l,o)),Math.abs(u.y-i)<s&&(d=Math.max(d,i)),Math.abs(u.y-r)<s&&(d=Math.min(d,r)),a=Math.max(n,Math.min(o,a)),c=Math.max(i,Math.min(r,c)),l=Math.max(n,Math.min(o,l)),d=Math.max(i,Math.min(r,d)),e.ctrl1.x=a,e.ctrl1.y=c,e.ctrl2.x=l,e.ctrl2.y=d}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 o=this.traces[e],i=this.traces[n];if(o.networkId&&i.networkId&&o.networkId===i.networkId)continue;const r=this.traceBounds[e],s=this.traceBounds[n];r.maxX+t>=s.minX&&s.maxX+t>=r.minX&&r.maxY+t>=s.minY&&s.maxY+t>=r.minY&&this.collisionPairs.push([e,n])}}computeTotalCost(){const{preferredObstacleToTraceSpacing:t}=this.problem,e=this.effectiveTraceToTraceSpacing,n=e**2,o=t**2;let i=0;for(const[t,o]of this.collisionPairs){const r=this.sampledPoints[t],s=this.sampledPoints[o];for(let t=0;t<5;t++){const o=r[2*t],a=r[2*t+1],c=r[2*(t+1)],l=r[2*(t+1)+1];for(let t=0;t<5;t++){const r=xd(o,a,c,l,s[2*t],s[2*t+1],s[2*(t+1)],s[2*(t+1)+1]);if(r<n){i+=(e-Math.sqrt(r))**2,r<1e-18&&(i+=20*n)}}}}for(let e=0;e<this.traces.length;e++){const n=this.traces[e],r=this.sampledPoints[e],s=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],l=this.obstacleSegments[a+1],d=this.obstacleSegments[a+2],h=this.obstacleSegments[a+3],u=Math.min(c,d),p=Math.max(c,d),m=Math.min(l,h),g=Math.max(l,h);if(!(s.maxX+t<u||p+t<s.minX||s.maxY+t<m||g+t<s.minY))for(let e=0;e<5;e++){const n=xd(r[2*e],r[2*e+1],r[2*(e+1)],r[2*(e+1)+1],c,l,d,h);if(n<o){i+=(t-Math.sqrt(n))**2,n<1e-18&&(i+=20*o)}}}}return i}computeCostForTrace(t){const{preferredObstacleToTraceSpacing:e}=this.problem,n=this.effectiveTraceToTraceSpacing,o=n**2,i=e**2,r=this.traces[t],s=this.sampledPoints[t],a=this.traceBounds[t];let c=0;for(let e=0;e<this.traces.length;e++){if(e===t)continue;const i=this.traces[e];if(r.networkId&&i.networkId&&r.networkId===i.networkId)continue;const l=this.traceBounds[e];if(a.maxX+n<l.minX||l.maxX+n<a.minX||a.maxY+n<l.minY||l.maxY+n<a.minY)continue;const d=this.sampledPoints[e];for(let t=0;t<5;t++){const e=s[2*t],i=s[2*t+1],r=s[2*(t+1)],a=s[2*(t+1)+1];for(let t=0;t<5;t++){const s=xd(e,i,r,a,d[2*t],d[2*t+1],d[2*(t+1)],d[2*(t+1)+1]);if(s<o){c+=(n-Math.sqrt(s))**2,s<1e-18&&(c+=20*o)}}}}for(let t=0;t<this.numObstacleSegments;t++){if(r.networkId&&this.obstacleNetworkIds[t]&&r.networkId===this.obstacleNetworkIds[t])continue;const n=4*t,o=this.obstacleSegments[n],l=this.obstacleSegments[n+1],d=this.obstacleSegments[n+2],h=this.obstacleSegments[n+3],u=Math.min(o,d),p=Math.max(o,d),m=Math.min(l,h),g=Math.max(l,h);if(!(a.maxX+e<u||p+e<a.minX||a.maxY+e<m||g+e<a.minY))for(let t=0;t<5;t++){const n=xd(s[2*t],s[2*t+1],s[2*(t+1)],s[2*(t+1)+1],o,l,d,h);if(n<i){c+=(e-Math.sqrt(n))**2,n<1e-18&&(c+=20*i)}}}return c}tracesIntersect(t,e){const n=this.traces[t],o=this.traces[e],i=15,r=new Float64Array(32),s=new Float64Array(32);yd(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,r,i),yd(o.waypointPair.start.x,o.waypointPair.start.y,o.ctrl1.x,o.ctrl1.y,o.ctrl2.x,o.ctrl2.y,o.waypointPair.end.x,o.waypointPair.end.y,s,i);for(let t=0;t<i;t++){const e=r[2*t],n=r[2*t+1],o=r[2*(t+1)],a=r[2*(t+1)+1];for(let t=0;t<i;t++){if(vd(e,n,o,a,s[2*t],s[2*t+1],s[2*(t+1)],s[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 o=this.traces[e],i=this.traces[n];if(o.networkId&&i.networkId&&o.networkId===i.networkId)continue;const r=this.traceBounds[e],s=this.traceBounds[n];r.maxX<s.minX||s.maxX<r.minX||r.maxY<s.minY||s.maxY<r.minY||this.tracesIntersect(e,n)&&t.push([e,n])}return t}resolveIntersections(){const{bounds:t,preferredTraceToTraceSpacing:e}=this.problem,{minX:n,maxX:o,minY:i,maxY:r}=t,s=Math.min(o-n,r-i),a=.02*s,c=1.5*s,l=this.findIntersectingPairs();if(0===l.length)return 0;let d=0;for(const[t,n]of l){const o=this.traces[t],i=this.traces[n];if(!this.tracesIntersect(t,n))continue;let r,s;if(o.containedBy.includes(n))r=n,s=t;else if(i.containedBy.includes(t))r=t,s=n;else{(o.d1+o.d2)/2<(i.d1+i.d2)/2?(r=t,s=n):(r=n,s=t)}const l=this.traces[r],h=this.traces[s],u=l.d1,p=l.d2,m=h.d1,g=h.d2,f=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 _=this.computeTotalCost(),b=null;for(const t of y)if(l.d1=u,l.d2=p,h.d1=m,h.d2=g,h.d1=Math.min(c,m+f*t.innerMult),h.d2=Math.min(c,g+f*t.innerMult),l.d1=Math.max(a,u-f*t.outerMult),l.d2=Math.max(a,p-f*t.outerMult),this.updateControlPointsFromDistances(s),this.updateControlPointsFromDistances(r),this.updateSingleTraceSample(s),this.updateSingleTraceSample(r),!this.tracesIntersect(r,s)){const e=this.computeTotalCost();(null===b||e<_)&&(_=e,b=t)}b?(h.d1=Math.min(c,m+f*b.innerMult),h.d2=Math.min(c,g+f*b.innerMult),l.d1=Math.max(a,u-f*b.outerMult),l.d2=Math.max(a,p-f*b.outerMult),this.updateControlPointsFromDistances(s),this.updateControlPointsFromDistances(r),this.updateSingleTraceSample(s),this.updateSingleTraceSample(r),d++):(l.d1=u,l.d2=p,h.d1=m,h.d2=g,this.updateControlPointsFromDistances(r),this.updateControlPointsFromDistances(s),this.updateSingleTraceSample(r),this.updateSingleTraceSample(s))}return d}optimizeStep(){const{bounds:t}=this.problem,{minX:e,maxX:n,minY:o,maxY:i}=t,r=Math.min(n-e,i-o),s=this.effectiveTraceToTraceSpacing,a=4*(1-this.optimizationStep/this.maxOptimizationSteps)+.5,c=.02*r,l=1.5*r,d=[];for(let t=0;t<this.traces.length;t++)d.push({idx:t,cost:this.computeCostForTrace(t)});d.sort((t,e)=>e.cost-t.cost);for(const{idx:t,cost:e}of d){if(0===e)continue;const n=this.traces[t],o=e>100?2:1,i=[a*o,1.5*a*o,.5*a];for(const o of i){const i=e>100?[o,-o,2*o,2*-o,3*o,3*-o,2*s,2*-s]:[o,-o,2*o,2*-o];let r=this.computeCostForTrace(t),a=n.d1,d=n.d2;const h=n.d1,u=n.d2;for(const e of i){n.d1=Math.max(c,Math.min(l,h+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const o=this.computeCostForTrace(t);o<r&&(r=o,a=n.d1,d=u),n.d1=h,this.updateControlPointsFromDistances(t),n.d2=Math.max(c,Math.min(l,u+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const i=this.computeCostForTrace(t);i<r&&(r=i,a=h,d=n.d2),n.d2=u,this.updateControlPointsFromDistances(t),n.d1=Math.max(c,Math.min(l,h+e)),n.d2=Math.max(c,Math.min(l,u+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const s=this.computeCostForTrace(t);s<r&&(r=s,a=n.d1,d=n.d2),n.d1=h,n.d2=u,this.updateControlPointsFromDistances(t),n.d1=Math.max(c,Math.min(l,h+e)),n.d2=Math.max(c,Math.min(l,u-e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const p=this.computeCostForTrace(t);p<r&&(r=p,a=n.d1,d=n.d2),n.d1=h,n.d2=u,this.updateControlPointsFromDistances(t)}if(n.d1=a,n.d2=d,this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t),r<.9*e)break}}this.optimizationStep%10==0&&this.updateCollisionPairs()}buildOutputTraces(){this.outputTraces=this.traces.map(t=>({waypointPair:t.waypointPair,points:_d(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:pd(e.networkId)}),n.points.push({...e.end,label:`end ${e.networkId??""}`,color:pd(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:pd(t.networkId)});return n})(this.problem,this.outputTraces)}},Pd=class extends si{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 o=[];for(const[t,e]of n){if(e.length<2)continue;const n=e[0],i=e[e.length-1];o.push({start:{x:n.x,y:n.y},end:{x:i.x,y:i.y},networkId:t})}if(0===o.length)return void(this.phase="done");const i={bounds:e,waypointPairs:o,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 Cd(i),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??"",o=e.get(n);if(!o)continue;const i={connectionName:o.connectionName,rootConnectionName:o.rootConnectionName,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:t.points.map(t=>({x:t.x,y:t.y,z:o.z})),vias:[]};this.routes.push(i)}}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}},Md=Object.create,Nd=Object.defineProperty,wd=Object.getOwnPropertyDescriptor,Td=Object.getOwnPropertyNames,Rd=Object.getPrototypeOf,Ed=Object.prototype.hasOwnProperty,Ad=(t,e)=>function(){return e||(0,t[Td(t)[0]])((e={exports:{}}).exports,e),e.exports},Od=Ad({"node_modules/binary-search-bounds/search-bounds.js"(t,e){function n(t,e,n,o,i){for(var r=i+1;o<=i;){var s=o+i>>>1,a=t[s];(void 0!==n?n(a,e):a-e)>=0?(r=s,i=s-1):o=s+1}return r}function o(t,e,n,o,i){for(var r=i+1;o<=i;){var s=o+i>>>1,a=t[s];(void 0!==n?n(a,e):a-e)>0?(r=s,i=s-1):o=s+1}return r}function i(t,e,n,o,i){for(var r=o-1;o<=i;){var s=o+i>>>1,a=t[s];(void 0!==n?n(a,e):a-e)<0?(r=s,o=s+1):i=s-1}return r}function r(t,e,n,o,i){for(var r=o-1;o<=i;){var s=o+i>>>1,a=t[s];(void 0!==n?n(a,e):a-e)<=0?(r=s,o=s+1):i=s-1}return r}function s(t,e,n,o,i){for(;o<=i;){var r=o+i>>>1,s=t[r],a=void 0!==n?n(s,e):s-e;if(0===a)return r;a<=0?o=r+1:i=r-1}return-1}function a(t,e,n,o,i,r){return"function"==typeof n?r(t,e,n,void 0===o?0:0|o,void 0===i?t.length-1:0|i):r(t,e,void 0,void 0===n?0:0|n,void 0===o?t.length-1:0|o)}e.exports={ge:function(t,e,o,i,r){return a(t,e,o,i,r,n)},gt:function(t,e,n,i,r){return a(t,e,n,i,r,o)},lt:function(t,e,n,o,r){return a(t,e,n,o,r,i)},le:function(t,e,n,o,i){return a(t,e,n,o,i,r)},eq:function(t,e,n,o,i){return a(t,e,n,o,i,s)}}}}),kd=Ad({"node_modules/two-product/two-product.js"(t,e){e.exports=function(t,e,o){var i=t*e,r=n*t,s=r-(r-t),a=t-s,c=n*e,l=c-(c-e),d=e-l,h=a*d-(i-s*l-a*l-s*d);if(o)return o[0]=h,o[1]=i,o;return[h,i]};var n=+(Math.pow(2,27)+1)}}),Ld=Ad({"node_modules/robust-sum/robust-sum.js"(t,e){e.exports=function(t,e){var n=0|t.length,o=0|e.length;if(1===n&&1===o)return function(t,e){var n=t+e,o=n-t,i=n-o,r=e-o,s=t-i,a=s+r;if(a)return[a,n];return[n]}(t[0],e[0]);var i,r,s=new Array(n+o),a=0,c=0,l=0,d=Math.abs,h=t[c],u=d(h),p=e[l],m=d(p);u<m?(r=h,(c+=1)<n&&(u=d(h=t[c]))):(r=p,(l+=1)<o&&(m=d(p=e[l])));c<n&&u<m||l>=o?(i=h,(c+=1)<n&&(u=d(h=t[c]))):(i=p,(l+=1)<o&&(m=d(p=e[l])));var g,f,y=i+r,_=y-i,b=r-_,x=b,v=y;for(;c<n&&l<o;)u<m?(i=h,(c+=1)<n&&(u=d(h=t[c]))):(i=p,(l+=1)<o&&(m=d(p=e[l]))),(b=(r=x)-(_=(y=i+r)-i))&&(s[a++]=b),x=v-((g=v+y)-(f=g-v))+(y-f),v=g;for(;c<n;)(b=(r=x)-(_=(y=(i=h)+r)-i))&&(s[a++]=b),x=v-((g=v+y)-(f=g-v))+(y-f),v=g,(c+=1)<n&&(h=t[c]);for(;l<o;)(b=(r=x)-(_=(y=(i=p)+r)-i))&&(s[a++]=b),x=v-((g=v+y)-(f=g-v))+(y-f),v=g,(l+=1)<o&&(p=e[l]);x&&(s[a++]=x);v&&(s[a++]=v);a||(s[a++]=0);return s.length=a,s}}}),Dd=Ad({"node_modules/two-sum/two-sum.js"(t,e){e.exports=function(t,e,n){var o=t+e,i=o-t,r=e-i,s=t-(o-i);if(n)return n[0]=s+r,n[1]=o,n;return[s+r,o]}}}),zd=Ad({"node_modules/robust-scale/robust-scale.js"(t,e){var n=kd(),o=Dd();e.exports=function(t,e){var i=t.length;if(1===i){var r=n(t[0],e);return r[0]?r:[r[1]]}var s=new Array(2*i),a=[.1,.1],c=[.1,.1],l=0;n(t[0],e,a),a[0]&&(s[l++]=a[0]);for(var d=1;d<i;++d){n(t[d],e,c);var h=a[1];o(h,c[0],a),a[0]&&(s[l++]=a[0]);var u=c[1],p=a[1],m=u+p,g=p-(m-u);a[1]=m,g&&(s[l++]=g)}a[1]&&(s[l++]=a[1]);0===l&&(s[l++]=0);return s.length=l,s}}}),Fd=Ad({"node_modules/robust-subtract/robust-diff.js"(t,e){e.exports=function(t,e){var n=0|t.length,o=0|e.length;if(1===n&&1===o)return function(t,e){var n=t+e,o=n-t,i=n-o,r=e-o,s=t-i,a=s+r;if(a)return[a,n];return[n]}(t[0],-e[0]);var i,r,s=new Array(n+o),a=0,c=0,l=0,d=Math.abs,h=t[c],u=d(h),p=-e[l],m=d(p);u<m?(r=h,(c+=1)<n&&(u=d(h=t[c]))):(r=p,(l+=1)<o&&(m=d(p=-e[l])));c<n&&u<m||l>=o?(i=h,(c+=1)<n&&(u=d(h=t[c]))):(i=p,(l+=1)<o&&(m=d(p=-e[l])));var g,f,y=i+r,_=y-i,b=r-_,x=b,v=y;for(;c<n&&l<o;)u<m?(i=h,(c+=1)<n&&(u=d(h=t[c]))):(i=p,(l+=1)<o&&(m=d(p=-e[l]))),(b=(r=x)-(_=(y=i+r)-i))&&(s[a++]=b),x=v-((g=v+y)-(f=g-v))+(y-f),v=g;for(;c<n;)(b=(r=x)-(_=(y=(i=h)+r)-i))&&(s[a++]=b),x=v-((g=v+y)-(f=g-v))+(y-f),v=g,(c+=1)<n&&(h=t[c]);for(;l<o;)(b=(r=x)-(_=(y=(i=p)+r)-i))&&(s[a++]=b),x=v-((g=v+y)-(f=g-v))+(y-f),v=g,(l+=1)<o&&(p=-e[l]);x&&(s[a++]=x);v&&(s[a++]=v);a||(s[a++]=0);return s.length=a,s}}}),Bd=Ad({"node_modules/robust-orientation/orientation.js"(t,e){var n=kd(),o=Ld(),i=zd(),r=Fd();function s(t,e,n,o){return function(n,i,r){var s=t(t(e(i[1],r[0]),e(-r[1],i[0])),t(e(n[1],i[0]),e(-i[1],n[0]))),a=t(e(n[1],r[0]),e(-r[1],n[0])),c=o(s,a);return c[c.length-1]}}function a(t,e,n,o){return function(i,r,s,a){var c=t(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),r[2]),t(n(t(e(r[1],a[0]),e(-a[1],r[0])),-s[2]),n(t(e(r[1],s[0]),e(-s[1],r[0])),a[2]))),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])))),l=t(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),a[2]))),t(n(t(e(r[1],s[0]),e(-s[1],r[0])),i[2]),t(n(t(e(i[1],s[0]),e(-s[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),s[2])))),d=o(c,l);return d[d.length-1]}}function c(t,e,n,o){return function(i,r,s,a,c){var l=t(t(t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),s[2]),t(n(t(e(s[1],c[0]),e(-c[1],s[0])),-a[2]),n(t(e(s[1],a[0]),e(-a[1],s[0])),c[2]))),r[3]),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]))),-s[3]),n(t(n(t(e(s[1],c[0]),e(-c[1],s[0])),r[2]),t(n(t(e(r[1],c[0]),e(-c[1],r[0])),-s[2]),n(t(e(r[1],s[0]),e(-s[1],r[0])),c[2]))),a[3]))),t(n(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),r[2]),t(n(t(e(r[1],a[0]),e(-a[1],r[0])),-s[2]),n(t(e(r[1],s[0]),e(-s[1],r[0])),a[2]))),-c[3]),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]),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])))),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]))),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]),n(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),r[2]),t(n(t(e(r[1],a[0]),e(-a[1],r[0])),-s[2]),n(t(e(r[1],s[0]),e(-s[1],r[0])),a[2]))),i[3]))),t(n(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),a[2]))),-r[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]))),s[3]),n(t(n(t(e(r[1],s[0]),e(-s[1],r[0])),i[2]),t(n(t(e(i[1],s[0]),e(-s[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),s[2]))),-a[3]))))),d=t(t(t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),s[2]),t(n(t(e(s[1],c[0]),e(-c[1],s[0])),-a[2]),n(t(e(s[1],a[0]),e(-a[1],s[0])),c[2]))),i[3]),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]))),-s[3])),t(n(t(n(t(e(s[1],c[0]),e(-c[1],s[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),c[2]))),a[3]),n(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),a[2]))),-c[3]))),t(t(n(t(n(t(e(s[1],c[0]),e(-c[1],s[0])),r[2]),t(n(t(e(r[1],c[0]),e(-c[1],r[0])),-s[2]),n(t(e(r[1],s[0]),e(-s[1],r[0])),c[2]))),i[3]),n(t(n(t(e(s[1],c[0]),e(-c[1],s[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),c[2]))),-r[3])),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]))),s[3]),n(t(n(t(e(r[1],s[0]),e(-s[1],r[0])),i[2]),t(n(t(e(i[1],s[0]),e(-s[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),s[2]))),-c[3])))),h=o(l,d);return h[h.length-1]}}function l(t){return(3===t?s:4===t?a:c)(o,n,i,r)}var d=l(3),h=l(4),u=[function(){return 0},function(){return 0},function(t,e){return e[0]-t[0]},function(t,e,n){var o,i=(t[1]-n[1])*(e[0]-n[0]),r=(t[0]-n[0])*(e[1]-n[1]),s=i-r;if(i>0){if(r<=0)return s;o=i+r}else{if(!(i<0))return s;if(r>=0)return s;o=-(i+r)}var a=33306690738754716e-32*o;return s>=a||s<=-a?s:d(t,e,n)},function(t,e,n,o){var i=t[0]-o[0],r=e[0]-o[0],s=n[0]-o[0],a=t[1]-o[1],c=e[1]-o[1],l=n[1]-o[1],d=t[2]-o[2],u=e[2]-o[2],p=n[2]-o[2],m=r*l,g=s*c,f=s*a,y=i*l,_=i*c,b=r*a,x=d*(m-g)+u*(f-y)+p*(_-b),v=7771561172376103e-31*((Math.abs(m)+Math.abs(g))*Math.abs(d)+(Math.abs(f)+Math.abs(y))*Math.abs(u)+(Math.abs(_)+Math.abs(b))*Math.abs(p));return x>v||-x>v?x:h(t,e,n,o)}];function p(t){var e=u[t.length];return e||(e=u[t.length]=l(t.length)),e.apply(void 0,t)}function m(t,e,n,o,i,r,s){return function(e,n,a,c,l){switch(arguments.length){case 0:case 1:return 0;case 2:return o(e,n);case 3:return i(e,n,a);case 4:return r(e,n,a,c);case 5:return s(e,n,a,c,l)}for(var d=new Array(arguments.length),h=0;h<arguments.length;++h)d[h]=arguments[h];return t(d)}}!function(){for(;u.length<=5;)u.push(l(u.length));e.exports=m.apply(void 0,[p].concat(u));for(var t=0;t<=5;++t)e.exports[t]=u[t]}()}}),jd=Ad({"node_modules/cdt2d/lib/monotone.js"(t,e){var n=Od(),o=Bd()[3];function i(t,e,n,o,i){this.a=t,this.b=e,this.idx=n,this.lowerIds=o,this.upperIds=i}function r(t,e,n,o){this.a=t,this.b=e,this.type=n,this.idx=o}function s(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=o(t.a,t.b,e.b))?n:t.idx-e.idx)}function a(t,e){return o(t.a,t.b,e)}function c(t,e,i,r,s){for(var c=n.lt(e,r,a),l=n.gt(e,r,a),d=c;d<l;++d){for(var h=e[d],u=h.lowerIds,p=u.length;p>1&&o(i[u[p-2]],i[u[p-1]],r)>0;)t.push([u[p-1],u[p-2],s]),p-=1;u.length=p,u.push(s);var m=h.upperIds;for(p=m.length;p>1&&o(i[m[p-2]],i[m[p-1]],r)<0;)t.push([m[p-2],m[p-1],s]),p-=1;m.length=p,m.push(s)}}function l(t,e){var n;return(n=t.a[0]<e.a[0]?o(t.a,t.b,e.a):o(e.b,e.a,t.a))?n:(n=e.b[0]<t.b[0]?o(t.a,t.b,e.b):o(e.b,e.a,t.b))||t.idx-e.idx}function d(t,e,o){var r=n.le(t,o,l),s=t[r],a=s.upperIds,c=a[a.length-1];s.upperIds=[c],t.splice(r+1,0,new i(o.a,o.b,o.idx,[c],a))}function h(t,e,o){var i=o.a;o.a=o.b,o.b=i;var r=n.eq(t,o,l),s=t[r];t[r-1].upperIds=s.upperIds,t.splice(r,1)}e.exports=function(t,e){for(var n=t.length,o=e.length,a=[],l=0;l<n;++l)a.push(new r(t[l],null,0,l));for(l=0;l<o;++l){var u=e[l],p=t[u[0]],m=t[u[1]];p[0]<m[0]?a.push(new r(p,m,2,l),new r(m,p,1,l)):p[0]>m[0]&&a.push(new r(m,p,2,l),new r(p,m,1,l))}a.sort(s);for(var g=a[0].a[0]-(1+Math.abs(a[0].a[0]))*Math.pow(2,-52),f=[new i([g,1],[g,0],-1,[],[],[],[])],y=[],_=(l=0,a.length);l<_;++l){var b=a[l],x=b.type;0===x?c(y,f,t,b.a,b.idx):2===x?d(f,t,b):h(f,t,b)}return y}}}),$d=Ad({"node_modules/cdt2d/lib/triangulation.js"(t,e){var n=Od();function o(t,e){this.stars=t,this.edges=e}e.exports=function(t,e){for(var n=new Array(t),i=0;i<t;++i)n[i]=[];return new o(n,e)};var i=o.prototype;function r(t,e,n){for(var o=1,i=t.length;o<i;o+=2)if(t[o-1]===e&&t[o]===n)return t[o-1]=t[i-2],t[o]=t[i-1],void(t.length=i-2)}i.isConstraint=function(){var t=[0,0];function e(t,e){return t[0]-e[0]||t[1]-e[1]}return function(o,i){return t[0]=Math.min(o,i),t[1]=Math.max(o,i),n.eq(this.edges,t,e)>=0}}(),i.removeTriangle=function(t,e,n){var o=this.stars;r(o[t],e,n),r(o[e],n,t),r(o[n],t,e)},i.addTriangle=function(t,e,n){var o=this.stars;o[t].push(e,n),o[e].push(n,t),o[n].push(t,e)},i.opposite=function(t,e){for(var n=this.stars[e],o=1,i=n.length;o<i;o+=2)if(n[o]===t)return n[o-1];return-1},i.flip=function(t,e){var n=this.opposite(t,e),o=this.opposite(e,t);this.removeTriangle(t,e,n),this.removeTriangle(e,t,o),this.addTriangle(t,o,n),this.addTriangle(e,n,o)},i.edges=function(){for(var t=this.stars,e=[],n=0,o=t.length;n<o;++n)for(var i=t[n],r=0,s=i.length;r<s;r+=2)e.push([i[r],i[r+1]]);return e},i.cells=function(){for(var t=this.stars,e=[],n=0,o=t.length;n<o;++n)for(var i=t[n],r=0,s=i.length;r<s;r+=2){var a=i[r],c=i[r+1];n<Math.min(a,c)&&e.push([n,a,c])}return e}}}),Yd=Ad({"node_modules/robust-in-sphere/in-sphere.js"(t,e){var n=kd(),o=Ld(),i=Fd(),r=zd();function s(t){return(3===t?a:4===t?c:5===t?l:d)(o,i,n,r)}function a(t,e,n,o){return function(i,r,s){var a=n(i[0],i[0]),c=o(a,r[0]),l=o(a,s[0]),d=n(r[0],r[0]),h=o(d,i[0]),u=o(d,s[0]),p=n(s[0],s[0]),m=o(p,i[0]),g=o(p,r[0]),f=t(e(g,u),e(h,c)),y=e(m,l),_=e(f,y);return _[_.length-1]}}function c(t,e,n,o){return function(i,r,s,a){var c=t(n(i[0],i[0]),n(i[1],i[1])),l=o(c,r[0]),d=o(c,s[0]),h=o(c,a[0]),u=t(n(r[0],r[0]),n(r[1],r[1])),p=o(u,i[0]),m=o(u,s[0]),g=o(u,a[0]),f=t(n(s[0],s[0]),n(s[1],s[1])),y=o(f,i[0]),_=o(f,r[0]),b=o(f,a[0]),x=t(n(a[0],a[0]),n(a[1],a[1])),v=o(x,i[0]),S=o(x,r[0]),I=o(x,s[0]),C=t(t(o(e(I,b),r[1]),t(o(e(S,g),-s[1]),o(e(_,m),a[1]))),t(o(e(S,g),i[1]),t(o(e(v,h),-r[1]),o(e(p,l),a[1])))),P=t(t(o(e(I,b),i[1]),t(o(e(v,h),-s[1]),o(e(y,d),a[1]))),t(o(e(_,m),i[1]),t(o(e(y,d),-r[1]),o(e(p,l),s[1])))),M=e(C,P);return M[M.length-1]}}function l(t,e,n,o){return function(i,r,s,a,c){var l=t(n(i[0],i[0]),t(n(i[1],i[1]),n(i[2],i[2]))),d=o(l,r[0]),h=o(l,s[0]),u=o(l,a[0]),p=o(l,c[0]),m=t(n(r[0],r[0]),t(n(r[1],r[1]),n(r[2],r[2]))),g=o(m,i[0]),f=o(m,s[0]),y=o(m,a[0]),_=o(m,c[0]),b=t(n(s[0],s[0]),t(n(s[1],s[1]),n(s[2],s[2]))),x=o(b,i[0]),v=o(b,r[0]),S=o(b,a[0]),I=o(b,c[0]),C=t(n(a[0],a[0]),t(n(a[1],a[1]),n(a[2],a[2]))),P=o(C,i[0]),M=o(C,r[0]),N=o(C,s[0]),w=o(C,c[0]),T=t(n(c[0],c[0]),t(n(c[1],c[1]),n(c[2],c[2]))),R=o(T,i[0]),E=o(T,r[0]),A=o(T,s[0]),O=o(T,a[0]),k=t(t(t(o(t(o(e(O,w),s[1]),t(o(e(A,I),-a[1]),o(e(N,S),c[1]))),r[2]),t(o(t(o(e(O,w),r[1]),t(o(e(E,_),-a[1]),o(e(M,y),c[1]))),-s[2]),o(t(o(e(A,I),r[1]),t(o(e(E,_),-s[1]),o(e(v,f),c[1]))),a[2]))),t(o(t(o(e(N,S),r[1]),t(o(e(M,y),-s[1]),o(e(v,f),a[1]))),-c[2]),t(o(t(o(e(O,w),r[1]),t(o(e(E,_),-a[1]),o(e(M,y),c[1]))),i[2]),o(t(o(e(O,w),i[1]),t(o(e(R,p),-a[1]),o(e(P,u),c[1]))),-r[2])))),t(t(o(t(o(e(E,_),i[1]),t(o(e(R,p),-r[1]),o(e(g,d),c[1]))),a[2]),t(o(t(o(e(M,y),i[1]),t(o(e(P,u),-r[1]),o(e(g,d),a[1]))),-c[2]),o(t(o(e(N,S),r[1]),t(o(e(M,y),-s[1]),o(e(v,f),a[1]))),i[2]))),t(o(t(o(e(N,S),i[1]),t(o(e(P,u),-s[1]),o(e(x,h),a[1]))),-r[2]),t(o(t(o(e(M,y),i[1]),t(o(e(P,u),-r[1]),o(e(g,d),a[1]))),s[2]),o(t(o(e(v,f),i[1]),t(o(e(x,h),-r[1]),o(e(g,d),s[1]))),-a[2]))))),L=t(t(t(o(t(o(e(O,w),s[1]),t(o(e(A,I),-a[1]),o(e(N,S),c[1]))),i[2]),o(t(o(e(O,w),i[1]),t(o(e(R,p),-a[1]),o(e(P,u),c[1]))),-s[2])),t(o(t(o(e(A,I),i[1]),t(o(e(R,p),-s[1]),o(e(x,h),c[1]))),a[2]),o(t(o(e(N,S),i[1]),t(o(e(P,u),-s[1]),o(e(x,h),a[1]))),-c[2]))),t(t(o(t(o(e(A,I),r[1]),t(o(e(E,_),-s[1]),o(e(v,f),c[1]))),i[2]),o(t(o(e(A,I),i[1]),t(o(e(R,p),-s[1]),o(e(x,h),c[1]))),-r[2])),t(o(t(o(e(E,_),i[1]),t(o(e(R,p),-r[1]),o(e(g,d),c[1]))),s[2]),o(t(o(e(v,f),i[1]),t(o(e(x,h),-r[1]),o(e(g,d),s[1]))),-c[2])))),D=e(k,L);return D[D.length-1]}}function d(t,e,n,o){return function(i,r,s,a,c,l){var d=t(t(n(i[0],i[0]),n(i[1],i[1])),t(n(i[2],i[2]),n(i[3],i[3]))),h=o(d,r[0]),u=o(d,s[0]),p=o(d,a[0]),m=o(d,c[0]),g=o(d,l[0]),f=t(t(n(r[0],r[0]),n(r[1],r[1])),t(n(r[2],r[2]),n(r[3],r[3]))),y=o(f,i[0]),_=o(f,s[0]),b=o(f,a[0]),x=o(f,c[0]),v=o(f,l[0]),S=t(t(n(s[0],s[0]),n(s[1],s[1])),t(n(s[2],s[2]),n(s[3],s[3]))),I=o(S,i[0]),C=o(S,r[0]),P=o(S,a[0]),M=o(S,c[0]),N=o(S,l[0]),w=t(t(n(a[0],a[0]),n(a[1],a[1])),t(n(a[2],a[2]),n(a[3],a[3]))),T=o(w,i[0]),R=o(w,r[0]),E=o(w,s[0]),A=o(w,c[0]),O=o(w,l[0]),k=t(t(n(c[0],c[0]),n(c[1],c[1])),t(n(c[2],c[2]),n(c[3],c[3]))),L=o(k,i[0]),D=o(k,r[0]),z=o(k,s[0]),F=o(k,a[0]),B=o(k,l[0]),j=t(t(n(l[0],l[0]),n(l[1],l[1])),t(n(l[2],l[2]),n(l[3],l[3]))),$=o(j,i[0]),Y=o(j,r[0]),X=o(j,s[0]),V=o(j,a[0]),W=o(j,c[0]),H=t(t(t(o(t(t(o(t(o(e(W,B),a[1]),t(o(e(V,O),-c[1]),o(e(F,A),l[1]))),s[2]),o(t(o(e(W,B),s[1]),t(o(e(X,N),-c[1]),o(e(z,M),l[1]))),-a[2])),t(o(t(o(e(V,O),s[1]),t(o(e(X,N),-a[1]),o(e(E,P),l[1]))),c[2]),o(t(o(e(F,A),s[1]),t(o(e(z,M),-a[1]),o(e(E,P),c[1]))),-l[2]))),r[3]),t(o(t(t(o(t(o(e(W,B),a[1]),t(o(e(V,O),-c[1]),o(e(F,A),l[1]))),r[2]),o(t(o(e(W,B),r[1]),t(o(e(Y,v),-c[1]),o(e(D,x),l[1]))),-a[2])),t(o(t(o(e(V,O),r[1]),t(o(e(Y,v),-a[1]),o(e(R,b),l[1]))),c[2]),o(t(o(e(F,A),r[1]),t(o(e(D,x),-a[1]),o(e(R,b),c[1]))),-l[2]))),-s[3]),o(t(t(o(t(o(e(W,B),s[1]),t(o(e(X,N),-c[1]),o(e(z,M),l[1]))),r[2]),o(t(o(e(W,B),r[1]),t(o(e(Y,v),-c[1]),o(e(D,x),l[1]))),-s[2])),t(o(t(o(e(X,N),r[1]),t(o(e(Y,v),-s[1]),o(e(C,_),l[1]))),c[2]),o(t(o(e(z,M),r[1]),t(o(e(D,x),-s[1]),o(e(C,_),c[1]))),-l[2]))),a[3]))),t(t(o(t(t(o(t(o(e(V,O),s[1]),t(o(e(X,N),-a[1]),o(e(E,P),l[1]))),r[2]),o(t(o(e(V,O),r[1]),t(o(e(Y,v),-a[1]),o(e(R,b),l[1]))),-s[2])),t(o(t(o(e(X,N),r[1]),t(o(e(Y,v),-s[1]),o(e(C,_),l[1]))),a[2]),o(t(o(e(E,P),r[1]),t(o(e(R,b),-s[1]),o(e(C,_),a[1]))),-l[2]))),-c[3]),o(t(t(o(t(o(e(F,A),s[1]),t(o(e(z,M),-a[1]),o(e(E,P),c[1]))),r[2]),o(t(o(e(F,A),r[1]),t(o(e(D,x),-a[1]),o(e(R,b),c[1]))),-s[2])),t(o(t(o(e(z,M),r[1]),t(o(e(D,x),-s[1]),o(e(C,_),c[1]))),a[2]),o(t(o(e(E,P),r[1]),t(o(e(R,b),-s[1]),o(e(C,_),a[1]))),-c[2]))),l[3])),t(o(t(t(o(t(o(e(W,B),a[1]),t(o(e(V,O),-c[1]),o(e(F,A),l[1]))),r[2]),o(t(o(e(W,B),r[1]),t(o(e(Y,v),-c[1]),o(e(D,x),l[1]))),-a[2])),t(o(t(o(e(V,O),r[1]),t(o(e(Y,v),-a[1]),o(e(R,b),l[1]))),c[2]),o(t(o(e(F,A),r[1]),t(o(e(D,x),-a[1]),o(e(R,b),c[1]))),-l[2]))),i[3]),o(t(t(o(t(o(e(W,B),a[1]),t(o(e(V,O),-c[1]),o(e(F,A),l[1]))),i[2]),o(t(o(e(W,B),i[1]),t(o(e($,g),-c[1]),o(e(L,m),l[1]))),-a[2])),t(o(t(o(e(V,O),i[1]),t(o(e($,g),-a[1]),o(e(T,p),l[1]))),c[2]),o(t(o(e(F,A),i[1]),t(o(e(L,m),-a[1]),o(e(T,p),c[1]))),-l[2]))),-r[3])))),t(t(t(o(t(t(o(t(o(e(W,B),r[1]),t(o(e(Y,v),-c[1]),o(e(D,x),l[1]))),i[2]),o(t(o(e(W,B),i[1]),t(o(e($,g),-c[1]),o(e(L,m),l[1]))),-r[2])),t(o(t(o(e(Y,v),i[1]),t(o(e($,g),-r[1]),o(e(y,h),l[1]))),c[2]),o(t(o(e(D,x),i[1]),t(o(e(L,m),-r[1]),o(e(y,h),c[1]))),-l[2]))),a[3]),o(t(t(o(t(o(e(V,O),r[1]),t(o(e(Y,v),-a[1]),o(e(R,b),l[1]))),i[2]),o(t(o(e(V,O),i[1]),t(o(e($,g),-a[1]),o(e(T,p),l[1]))),-r[2])),t(o(t(o(e(Y,v),i[1]),t(o(e($,g),-r[1]),o(e(y,h),l[1]))),a[2]),o(t(o(e(R,b),i[1]),t(o(e(T,p),-r[1]),o(e(y,h),a[1]))),-l[2]))),-c[3])),t(o(t(t(o(t(o(e(F,A),r[1]),t(o(e(D,x),-a[1]),o(e(R,b),c[1]))),i[2]),o(t(o(e(F,A),i[1]),t(o(e(L,m),-a[1]),o(e(T,p),c[1]))),-r[2])),t(o(t(o(e(D,x),i[1]),t(o(e(L,m),-r[1]),o(e(y,h),c[1]))),a[2]),o(t(o(e(R,b),i[1]),t(o(e(T,p),-r[1]),o(e(y,h),a[1]))),-c[2]))),l[3]),o(t(t(o(t(o(e(V,O),s[1]),t(o(e(X,N),-a[1]),o(e(E,P),l[1]))),r[2]),o(t(o(e(V,O),r[1]),t(o(e(Y,v),-a[1]),o(e(R,b),l[1]))),-s[2])),t(o(t(o(e(X,N),r[1]),t(o(e(Y,v),-s[1]),o(e(C,_),l[1]))),a[2]),o(t(o(e(E,P),r[1]),t(o(e(R,b),-s[1]),o(e(C,_),a[1]))),-l[2]))),i[3]))),t(t(o(t(t(o(t(o(e(V,O),s[1]),t(o(e(X,N),-a[1]),o(e(E,P),l[1]))),i[2]),o(t(o(e(V,O),i[1]),t(o(e($,g),-a[1]),o(e(T,p),l[1]))),-s[2])),t(o(t(o(e(X,N),i[1]),t(o(e($,g),-s[1]),o(e(I,u),l[1]))),a[2]),o(t(o(e(E,P),i[1]),t(o(e(T,p),-s[1]),o(e(I,u),a[1]))),-l[2]))),-r[3]),o(t(t(o(t(o(e(V,O),r[1]),t(o(e(Y,v),-a[1]),o(e(R,b),l[1]))),i[2]),o(t(o(e(V,O),i[1]),t(o(e($,g),-a[1]),o(e(T,p),l[1]))),-r[2])),t(o(t(o(e(Y,v),i[1]),t(o(e($,g),-r[1]),o(e(y,h),l[1]))),a[2]),o(t(o(e(R,b),i[1]),t(o(e(T,p),-r[1]),o(e(y,h),a[1]))),-l[2]))),s[3])),t(o(t(t(o(t(o(e(X,N),r[1]),t(o(e(Y,v),-s[1]),o(e(C,_),l[1]))),i[2]),o(t(o(e(X,N),i[1]),t(o(e($,g),-s[1]),o(e(I,u),l[1]))),-r[2])),t(o(t(o(e(Y,v),i[1]),t(o(e($,g),-r[1]),o(e(y,h),l[1]))),s[2]),o(t(o(e(C,_),i[1]),t(o(e(I,u),-r[1]),o(e(y,h),s[1]))),-l[2]))),-a[3]),o(t(t(o(t(o(e(E,P),r[1]),t(o(e(R,b),-s[1]),o(e(C,_),a[1]))),i[2]),o(t(o(e(E,P),i[1]),t(o(e(T,p),-s[1]),o(e(I,u),a[1]))),-r[2])),t(o(t(o(e(R,b),i[1]),t(o(e(T,p),-r[1]),o(e(y,h),a[1]))),s[2]),o(t(o(e(C,_),i[1]),t(o(e(I,u),-r[1]),o(e(y,h),s[1]))),-a[2]))),l[3]))))),G=t(t(t(o(t(t(o(t(o(e(W,B),a[1]),t(o(e(V,O),-c[1]),o(e(F,A),l[1]))),s[2]),o(t(o(e(W,B),s[1]),t(o(e(X,N),-c[1]),o(e(z,M),l[1]))),-a[2])),t(o(t(o(e(V,O),s[1]),t(o(e(X,N),-a[1]),o(e(E,P),l[1]))),c[2]),o(t(o(e(F,A),s[1]),t(o(e(z,M),-a[1]),o(e(E,P),c[1]))),-l[2]))),i[3]),t(o(t(t(o(t(o(e(W,B),a[1]),t(o(e(V,O),-c[1]),o(e(F,A),l[1]))),i[2]),o(t(o(e(W,B),i[1]),t(o(e($,g),-c[1]),o(e(L,m),l[1]))),-a[2])),t(o(t(o(e(V,O),i[1]),t(o(e($,g),-a[1]),o(e(T,p),l[1]))),c[2]),o(t(o(e(F,A),i[1]),t(o(e(L,m),-a[1]),o(e(T,p),c[1]))),-l[2]))),-s[3]),o(t(t(o(t(o(e(W,B),s[1]),t(o(e(X,N),-c[1]),o(e(z,M),l[1]))),i[2]),o(t(o(e(W,B),i[1]),t(o(e($,g),-c[1]),o(e(L,m),l[1]))),-s[2])),t(o(t(o(e(X,N),i[1]),t(o(e($,g),-s[1]),o(e(I,u),l[1]))),c[2]),o(t(o(e(z,M),i[1]),t(o(e(L,m),-s[1]),o(e(I,u),c[1]))),-l[2]))),a[3]))),t(t(o(t(t(o(t(o(e(V,O),s[1]),t(o(e(X,N),-a[1]),o(e(E,P),l[1]))),i[2]),o(t(o(e(V,O),i[1]),t(o(e($,g),-a[1]),o(e(T,p),l[1]))),-s[2])),t(o(t(o(e(X,N),i[1]),t(o(e($,g),-s[1]),o(e(I,u),l[1]))),a[2]),o(t(o(e(E,P),i[1]),t(o(e(T,p),-s[1]),o(e(I,u),a[1]))),-l[2]))),-c[3]),o(t(t(o(t(o(e(F,A),s[1]),t(o(e(z,M),-a[1]),o(e(E,P),c[1]))),i[2]),o(t(o(e(F,A),i[1]),t(o(e(L,m),-a[1]),o(e(T,p),c[1]))),-s[2])),t(o(t(o(e(z,M),i[1]),t(o(e(L,m),-s[1]),o(e(I,u),c[1]))),a[2]),o(t(o(e(E,P),i[1]),t(o(e(T,p),-s[1]),o(e(I,u),a[1]))),-c[2]))),l[3])),t(o(t(t(o(t(o(e(W,B),s[1]),t(o(e(X,N),-c[1]),o(e(z,M),l[1]))),r[2]),o(t(o(e(W,B),r[1]),t(o(e(Y,v),-c[1]),o(e(D,x),l[1]))),-s[2])),t(o(t(o(e(X,N),r[1]),t(o(e(Y,v),-s[1]),o(e(C,_),l[1]))),c[2]),o(t(o(e(z,M),r[1]),t(o(e(D,x),-s[1]),o(e(C,_),c[1]))),-l[2]))),i[3]),o(t(t(o(t(o(e(W,B),s[1]),t(o(e(X,N),-c[1]),o(e(z,M),l[1]))),i[2]),o(t(o(e(W,B),i[1]),t(o(e($,g),-c[1]),o(e(L,m),l[1]))),-s[2])),t(o(t(o(e(X,N),i[1]),t(o(e($,g),-s[1]),o(e(I,u),l[1]))),c[2]),o(t(o(e(z,M),i[1]),t(o(e(L,m),-s[1]),o(e(I,u),c[1]))),-l[2]))),-r[3])))),t(t(t(o(t(t(o(t(o(e(W,B),r[1]),t(o(e(Y,v),-c[1]),o(e(D,x),l[1]))),i[2]),o(t(o(e(W,B),i[1]),t(o(e($,g),-c[1]),o(e(L,m),l[1]))),-r[2])),t(o(t(o(e(Y,v),i[1]),t(o(e($,g),-r[1]),o(e(y,h),l[1]))),c[2]),o(t(o(e(D,x),i[1]),t(o(e(L,m),-r[1]),o(e(y,h),c[1]))),-l[2]))),s[3]),o(t(t(o(t(o(e(X,N),r[1]),t(o(e(Y,v),-s[1]),o(e(C,_),l[1]))),i[2]),o(t(o(e(X,N),i[1]),t(o(e($,g),-s[1]),o(e(I,u),l[1]))),-r[2])),t(o(t(o(e(Y,v),i[1]),t(o(e($,g),-r[1]),o(e(y,h),l[1]))),s[2]),o(t(o(e(C,_),i[1]),t(o(e(I,u),-r[1]),o(e(y,h),s[1]))),-l[2]))),-c[3])),t(o(t(t(o(t(o(e(z,M),r[1]),t(o(e(D,x),-s[1]),o(e(C,_),c[1]))),i[2]),o(t(o(e(z,M),i[1]),t(o(e(L,m),-s[1]),o(e(I,u),c[1]))),-r[2])),t(o(t(o(e(D,x),i[1]),t(o(e(L,m),-r[1]),o(e(y,h),c[1]))),s[2]),o(t(o(e(C,_),i[1]),t(o(e(I,u),-r[1]),o(e(y,h),s[1]))),-c[2]))),l[3]),o(t(t(o(t(o(e(F,A),s[1]),t(o(e(z,M),-a[1]),o(e(E,P),c[1]))),r[2]),o(t(o(e(F,A),r[1]),t(o(e(D,x),-a[1]),o(e(R,b),c[1]))),-s[2])),t(o(t(o(e(z,M),r[1]),t(o(e(D,x),-s[1]),o(e(C,_),c[1]))),a[2]),o(t(o(e(E,P),r[1]),t(o(e(R,b),-s[1]),o(e(C,_),a[1]))),-c[2]))),i[3]))),t(t(o(t(t(o(t(o(e(F,A),s[1]),t(o(e(z,M),-a[1]),o(e(E,P),c[1]))),i[2]),o(t(o(e(F,A),i[1]),t(o(e(L,m),-a[1]),o(e(T,p),c[1]))),-s[2])),t(o(t(o(e(z,M),i[1]),t(o(e(L,m),-s[1]),o(e(I,u),c[1]))),a[2]),o(t(o(e(E,P),i[1]),t(o(e(T,p),-s[1]),o(e(I,u),a[1]))),-c[2]))),-r[3]),o(t(t(o(t(o(e(F,A),r[1]),t(o(e(D,x),-a[1]),o(e(R,b),c[1]))),i[2]),o(t(o(e(F,A),i[1]),t(o(e(L,m),-a[1]),o(e(T,p),c[1]))),-r[2])),t(o(t(o(e(D,x),i[1]),t(o(e(L,m),-r[1]),o(e(y,h),c[1]))),a[2]),o(t(o(e(R,b),i[1]),t(o(e(T,p),-r[1]),o(e(y,h),a[1]))),-c[2]))),s[3])),t(o(t(t(o(t(o(e(z,M),r[1]),t(o(e(D,x),-s[1]),o(e(C,_),c[1]))),i[2]),o(t(o(e(z,M),i[1]),t(o(e(L,m),-s[1]),o(e(I,u),c[1]))),-r[2])),t(o(t(o(e(D,x),i[1]),t(o(e(L,m),-r[1]),o(e(y,h),c[1]))),s[2]),o(t(o(e(C,_),i[1]),t(o(e(I,u),-r[1]),o(e(y,h),s[1]))),-c[2]))),-a[3]),o(t(t(o(t(o(e(E,P),r[1]),t(o(e(R,b),-s[1]),o(e(C,_),a[1]))),i[2]),o(t(o(e(E,P),i[1]),t(o(e(T,p),-s[1]),o(e(I,u),a[1]))),-r[2])),t(o(t(o(e(R,b),i[1]),t(o(e(T,p),-r[1]),o(e(y,h),a[1]))),s[2]),o(t(o(e(C,_),i[1]),t(o(e(I,u),-r[1]),o(e(y,h),s[1]))),-a[2]))),c[3]))))),U=e(H,G);return U[U.length-1]}}var h=[function(){return 0},function(){return 0},function(){return 0}];function u(t){var e=h[t.length];return e||(e=h[t.length]=s(t.length)),e.apply(void 0,t)}function p(t,e,n,o,i,r,s,a){return function(e,n,c,l,d,h){switch(arguments.length){case 0:case 1:return 0;case 2:return o(e,n);case 3:return i(e,n,c);case 4:return r(e,n,c,l);case 5:return s(e,n,c,l,d);case 6:return a(e,n,c,l,d,h)}for(var u=new Array(arguments.length),p=0;p<arguments.length;++p)u[p]=arguments[p];return t(u)}}!function(){for(;h.length<=6;)h.push(s(h.length));e.exports=p.apply(void 0,[u].concat(h));for(var t=0;t<=6;++t)e.exports[t]=h[t]}()}}),Xd=Ad({"node_modules/cdt2d/lib/delaunay.js"(t,e){var n=Yd()[4];Od();function o(t,e,o,i,r,s){var a=e.opposite(i,r);if(!(a<0)){if(r<i){var c=i;i=r,r=c,c=s,s=a,a=c}e.isConstraint(i,r)||n(t[i],t[r],t[s],t[a])<0&&o.push(i,r)}}e.exports=function(t,e){for(var i=[],r=t.length,s=e.stars,a=0;a<r;++a)for(var c=s[a],l=1;l<c.length;l+=2){if(!((p=c[l])<a)&&!e.isConstraint(a,p)){for(var d=c[l-1],h=-1,u=1;u<c.length;u+=2)if(c[u-1]===p){h=c[u];break}h<0||n(t[a],t[p],t[d],t[h])<0&&i.push(a,p)}}for(;i.length>0;){for(var p=i.pop(),m=(d=-1,h=-1,c=s[a=i.pop()],1);m<c.length;m+=2){var g=c[m-1],f=c[m];g===p?h=f:f===p&&(d=g)}d<0||h<0||(n(t[a],t[p],t[d],t[h])>=0||(e.flip(a,p),o(t,e,i,d,a,h),o(t,e,i,a,h,d),o(t,e,i,h,p,d),o(t,e,i,p,d,h)))}}}}),Vd=Ad({"node_modules/cdt2d/lib/filter.js"(t,e){var n=Od();function o(t,e,n,o,i,r,s){this.cells=t,this.neighbor=e,this.flags=o,this.constraint=n,this.active=i,this.next=r,this.boundary=s}function i(t,e){return t[0]-e[0]||t[1]-e[1]||t[2]-e[2]}e.exports=function(t,e,n){var r=function(t,e){for(var n=t.cells(),r=n.length,s=0;s<r;++s){var a=(y=n[s])[0],c=y[1],l=y[2];c<l?c<a&&(y[0]=c,y[1]=l,y[2]=a):l<a&&(y[0]=l,y[1]=a,y[2]=c)}n.sort(i);var d=new Array(r);for(s=0;s<d.length;++s)d[s]=0;var h=[],u=[],p=new Array(3*r),m=new Array(3*r),g=null;e&&(g=[]);var f=new o(n,p,m,d,h,u,g);for(s=0;s<r;++s)for(var y=n[s],_=0;_<3;++_){a=y[_],c=y[(_+1)%3];var b=p[3*s+_]=f.locate(c,a,t.opposite(c,a)),x=m[3*s+_]=t.isConstraint(a,c);b<0&&(x?u.push(s):(h.push(s),d[s]=1),e&&g.push([c,a,-1]))}return f}(t,n);if(0===e)return n?r.cells.concat(r.boundary):r.cells;var s=1,a=r.active,c=r.next,l=r.flags,d=r.cells,h=r.constraint,u=r.neighbor;for(;a.length>0||c.length>0;){for(;a.length>0;){var p=a.pop();if(l[p]!==-s){l[p]=s;d[p];for(var m=0;m<3;++m){var g=u[3*p+m];g>=0&&0===l[g]&&(h[3*p+m]?c.push(g):(a.push(g),l[g]=s))}}}var f=c;c=a,a=f,c.length=0,s=-s}var y=function(t,e,n){for(var o=0,i=0;i<t.length;++i)e[i]===n&&(t[o++]=t[i]);return t.length=o,t}(d,l,e);if(n)return y.concat(r.boundary);return y},o.prototype.locate=function(){var t=[0,0,0];return function(e,o,r){var s=e,a=o,c=r;return o<r?o<e&&(s=o,a=r,c=e):r<e&&(s=r,a=e,c=o),s<0?-1:(t[0]=s,t[1]=a,t[2]=c,n.eq(this.cells,t,i))}}()}}),Wd=Ad({"node_modules/cdt2d/cdt2d.js"(t,e){var n=jd(),o=$d(),i=Xd(),r=Vd();function s(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,l){Array.isArray(e)?(l=l||{},e=e||[]):(l=e||{},e=[]);var d=!!c(l,"delaunay",!0),h=!!c(l,"interior",!0),u=!!c(l,"exterior",!0),p=!!c(l,"infinity",!1);if(!h&&!u||0===t.length)return[];var m=n(t,e);if(d||h!==u||p){for(var g=o(t.length,function(t){return t.map(s).sort(a)}(e)),f=0;f<m.length;++f){var y=m[f];g.addTriangle(y[0],y[1],y[2])}return d&&i(t,g),u?h?p?r(g,0,p):g.cells():r(g,1,p):r(g,-1)}return m}}}),Hd=t=>t.map(t=>({connectionId:t.connectionId,startRegionId:t.startRegion.regionId,endRegionId:t.endRegion.regionId,mutuallyConnectedNetworkId:t.mutuallyConnectedNetworkId})),Gd=t=>({ports:t.ports.map(t=>({portId:t.portId,region1Id:t.region1.regionId,region2Id:t.region2.regionId,d:t.d})),regions:t.regions.map(t=>({regionId:t.regionId,pointIds:t.ports.map(t=>t.portId),d:t.d}))}),Ud=({port:t,boundaryRegionMap:e})=>{let n=e.get(t.portId);if(!n){const o="number"==typeof t.d?.x?t.d.x:0,i="number"==typeof t.d?.y?t.d.y:0;n={regionId:`__section_boundary__${t.portId}`,ports:[],d:{isBoundaryRegion:!0,boundaryPortId:t.portId,...t.d,center:{x:o,y:i},bounds:{minX:o-.05,maxX:o+.05,minY:i-.05,maxY:i+.05}},assignments:[]},e.set(t.portId,n)}return n},Zd=t=>{const{sectionRoute:e,graph:n}=t,o=new Set(n.ports.map(t=>t.portId)),i=e.globalRoute.path.slice(e.sectionStartIndex,e.sectionEndIndex+1).filter(t=>o.has(t.port.portId)),r=[];let s=e.sectionConnection.startRegion;for(let t=0;t<i.length;t++){const e=i[t],o=n.ports.find(t=>t.portId===e.port.portId),a=o.region1===s?o.region2:o.region1;r.push({port:o,g:0,h:0,f:0,hops:t,ripRequired:e.ripRequired,parent:t>0?r[t-1]:void 0,lastPort:t>0?r[t-1].port:void 0,lastRegion:t>0?s:void 0,nextRegion:a}),s=a}return{connection:e.sectionConnection,path:r,requiredRip:e.globalRoute.requiredRip}},qd=(t,e)=>{let n=-1,o=-1;for(let i=0;i<t.path.length;i++){const r=t.path[i];(r.lastRegion&&e.has(r.lastRegion.regionId)||r.nextRegion&&e.has(r.nextRegion.regionId))&&(-1===n&&(n=i),o=i)}return-1===n?null:{startIndex:n,endIndex:o}},Jd=t=>{const{graph:e,solvedRoutes:n,centralRegion:o,expansionHopsFromCentralRegion:i}=t,r=(({centralRegion:t,expansionHopsFromCentralRegion:e})=>{const n=new Set([t.regionId]),o=[{region:t,hops:0}];for(;o.length>0;){const{region:t,hops:i}=o.shift();if(!(i>=e+1))for(const e of t.ports){const r=e.region1===t?e.region2:e.region1;n.has(r.regionId)||(n.add(r.regionId),o.push({region:r,hops:i+1}))}}return n})({graph:e,centralRegion:o,expansionHopsFromCentralRegion:i}),s=new Map,a=new Map,c=[];for(const t of e.regions)r.has(t.regionId)&&s.set(t.regionId,{regionId:t.regionId,ports:[],d:t.d?structuredClone(t.d):t.d,assignments:[]});for(const t of e.ports){const e=r.has(t.region1.regionId),n=r.has(t.region2.regionId);if(!e&&!n)continue;if(e&&n){const e={portId:t.portId,region1:s.get(t.region1.regionId),region2:s.get(t.region2.regionId),d:t.d};e.region1.ports.push(e),e.region2.ports.push(e),c.push(e);continue}const o=e?t.region1:t.region2,i=Ud({port:t,boundaryRegionMap:a}),l={portId:t.portId,region1:s.get(o.regionId),region2:i,d:t.d};l.region1.ports.push(l),l.region2.ports.push(l),c.push(l)}const l={regions:[...s.values(),...a.values()],ports:c},d=[],h=[],u=[];for(const t of n){const e=qd(t,r);if(!e)continue;const n=t.path[e.startIndex],o=t.path[e.endIndex];u.push({solvedRoute:t,solvedPathStartIndex:e.startIndex,solvedPathEndIndex:e.endIndex,startCandidate:n,endCandidate:o})}const p=new Map(l.regions.map(t=>[t.regionId,t]));for(const{solvedRoute:t,solvedPathStartIndex:e,solvedPathEndIndex:n,startCandidate:o,endCandidate:i}of u){let s,c,u,m;if(r.has(t.connection.startRegion.regionId))s=t.connection.startRegion.regionId,c=p.get(s);else{const t=Ud({port:o.port,boundaryRegionMap:a});s=t.regionId,c=t,p.has(s)||p.set(s,t)}if(r.has(t.connection.endRegion.regionId))u=t.connection.endRegion.regionId,m=p.get(u);else{const t=Ud({port:i.port,boundaryRegionMap:a});u=t.regionId,m=t,p.has(u)||p.set(u,t)}if(!c)throw console.error("[getSectionOfHyperGraphAsHyperGraph] CRITICAL ERROR: startRegion not found!"),console.error(` Looking for: ${s}`),console.error(` Route connection: ${t.connection.connectionId}`),console.error(` Original startRegion: ${t.connection.startRegion.regionId}`),console.error(` startCandidate port: ${o.port.portId}`),console.error(" Available regions in sectionRegionMap:",Array.from(p.keys())),new Error(`startRegion ${s} not found in sectionRegionMap`);if(!m)throw console.error("[getSectionOfHyperGraphAsHyperGraph] CRITICAL ERROR: endRegion not found!"),console.error(` Looking for: ${u}`),console.error(` Route connection: ${t.connection.connectionId}`),console.error(` Original endRegion: ${t.connection.endRegion.regionId}`),console.error(` endCandidate port: ${i.port.portId}`),console.error(" Available regions in sectionRegionMap:",Array.from(p.keys())),new Error(`endRegion ${u} not found in sectionRegionMap`);const g={connectionId:t.connection.connectionId,mutuallyConnectedNetworkId:t.connection.mutuallyConnectedNetworkId,startRegion:c,endRegion:m},f=t.path.slice(e,n+1),y={globalRoute:t,globalConnection:t.connection,sectionConnection:g,sectionStartIndex:e,sectionEndIndex:n};d.push({...y,canRemainFixedInSectionSolve:f.every(t=>l.ports.some(e=>e.portId===t.port.portId)),sectionRoute:Zd({sectionRoute:y,graph:l})}),h.push(g)}return{centralRegionId:o.regionId,sectionRegionIds:r,graph:l,connections:h,sectionRoutes:d}},Kd=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),o=this._rightChildIndex(e);let i=e;if(t<n&&this.heap[t].f<this.heap[i].f&&(i=t),o<n&&this.heap[o].f<this.heap[i].f&&(i=o),i===e)break;this._swap(e,i),e=i}}_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}},Qd=t=>{for(const e of t.regions)e.assignments=[];for(const e of t.ports)e.assignment=void 0},th=({graph:t,connections:e,solvedRoutes:n})=>{const o=new Map(t.ports.map(t=>[t.portId,t])),i=new Map(t.regions.map(t=>[t.regionId,t])),r=new Map(e.map(t=>[t.connectionId,t])),s=n.map(t=>{const e=[];for(const n of t.path){const t={port:o.get(n.port.portId),g:n.g,h:n.h,f:n.f,hops:n.hops,ripRequired:n.ripRequired};n.lastPort&&(t.lastPort=o.get(n.lastPort.portId)),n.lastRegion&&(t.lastRegion=i.get(n.lastRegion.regionId)),n.nextRegion&&(t.nextRegion=i.get(n.nextRegion.regionId));const r=e[e.length-1];r&&(t.parent=r),e.push(t)}return{path:e,connection:r.get(t.connection.connectionId),requiredRip:t.requiredRip}});Qd(t),t.solvedRoutes=s;for(const t of s)for(const e of t.path){if(e.port.assignment={solvedRoute:t,connection:t.connection},!e.lastPort||!e.lastRegion)continue;const n={regionPort1:e.lastPort,regionPort2:e.port,region:e.lastRegion,connection:t.connection,solvedRoute:t};e.lastRegion.assignments??=[],e.lastRegion.assignments.push(n)}return s},eh=class extends kt{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,...o}=e;n.set(e.regionId,{...o,d:o.d?structuredClone(o.d):o.d,ports:[],assignments:void 0})}for(const o of t.ports){const t=n.get(o.region1Id??o.region1?.regionId),i=n.get(o.region2Id??o.region2?.regionId),r={portId:o.portId,region1:t,region2:i,d:o.d};e.set(o.portId,r),t.ports.push(r),i.ports.push(r)}return{ports:Array.from(e.values()),regions:Array.from(n.values())}})(t.inputGraph),Qd(this.graph),this.connections=((t,e)=>{const n=[];for(const o of t)"startRegionId"in o?n.push({connectionId:o.connectionId,mutuallyConnectedNetworkId:o.mutuallyConnectedNetworkId??o.connectionId,startRegion:e.regions.find(t=>t.regionId===o.startRegionId),endRegion:e.regions.find(t=>t.regionId===o.endRegionId)}):n.push(o);return n})(t.inputConnections,this.graph),t.inputSolvedRoutes?this.solvedRoutes=th({graph:this.graph,connections:this.connections,solvedRoutes:t.inputSolvedRoutes}):this.graph.solvedRoutes=this.solvedRoutes,void 0!==t.greedyMultiplier&&(this.greedyMultiplier=t.greedyMultiplier),void 0!==t.rippingEnabled&&(this.rippingEnabled=t.rippingEnabled),void 0!==t.ripCost&&(this.ripCost=t.ripCost);const e=new Set(this.solvedRoutes.map(t=>t.connection.connectionId));this.unprocessedConnections=this.connections.filter(t=>!e.has(t.connectionId)),this.candidateQueue=new Kd,0===this.unprocessedConnections.length?this.solved=!0: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:Gd(this.graph),inputConnections:Hd(this.connections),greedyMultiplier:this.greedyMultiplier,rippingEnabled:this.rippingEnabled,ripCost:this.ripCost,inputSolvedRoutes:this.solvedRoutes}}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,o={};for(const i of e.ports){if(i===t.port)continue;if(!this.isTransitionAllowed(e,n,i))continue;const r=i.assignment&&i.assignment.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId||this.isRipRequiredForPortUsage(e,n,i),s={port:i,hops:t.hops+1,parent:t,lastRegion:e,nextRegion:i.region1===e?i.region2:i.region1,lastPort:n,ripRequired:r};!this.rippingEnabled&&s.ripRequired||(o[s.nextRegion.regionId]??=[],o[s.nextRegion.regionId].push(s))}const i=[];for(const t in o){const e=o[t];i.push(...this.selectCandidatesForEnteringRegion(e))}for(const t of i)t.g=this.computeG(t),t.h=this.computeH(t),t.f=t.g+t.h*this.greedyMultiplier;return i}processSolvedRoute(t){const e={path:[],connection:this.currentConnection,requiredRip:!1};let n=t,o=!1;for(;n;)o||=!!n.ripRequired,e.path.unshift(n),n=n.parent;o&&(e.requiredRip=!0);const i=this.computeRoutesToRip(e);if(i.size>0){e.requiredRip=!0;for(const t of i)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 Kd,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 nh(t,e){const n=t.x-e.x,o=t.y-e.y;return n*n+o*o}function oh(t,e,n,o,i){const r=n-e,s=i-o,a=1e-6;if(Math.abs(t.y-i)<a)return t.x-e;if(Math.abs(t.x-n)<a)return r+(i-t.y);if(Math.abs(t.y-o)<a)return r+s+(n-t.x);if(Math.abs(t.x-e)<a)return 2*r+s+(t.y-o);const c=Math.abs(t.y-i),l=Math.abs(t.x-n),d=Math.abs(t.y-o),h=Math.abs(t.x-e),u=Math.min(c,l,d,h);return u===c?Math.max(0,Math.min(r,t.x-e)):u===l?r+Math.max(0,Math.min(s,i-t.y)):u===d?r+s+Math.max(0,Math.min(r,n-t.x)):2*r+s+Math.max(0,Math.min(s,t.y-o))}function ih(t,e,n){const o=n.x-e.x,i=n.y-e.y,r=t.x-e.x,s=t.y-e.y,a=o*o+i*i,c=a>0?(l=(r*o+s*i)/a,d=0,h=1,Math.max(d,Math.min(h,l))):0;var l,d,h;return{u:c,d2:nh(t,{x:e.x+c*o,y:e.y+c*i})}}function rh(t){const e=t.d.polygon;if(!e||e.length<3)return null;const n=t.d.polygonPerimeterCache;if(n)return n;const o=function(t){const e=t.length,n=new Array(e),o=new Array(e+1);o[0]=0;for(let i=0;i<e;i++){const r=t[i],s=t[(i+1)%e],a=Math.hypot(s.x-r.x,s.y-r.y);n[i]=a,o[i+1]=o[i]+a}return{edgeLengths:n,cumulative:o,perimeter:o[e]}}(e);return t.d.polygonPerimeterCache=o,o}function sh(t){const e=rh(t);if(e)return e.perimeter;const{minX:n,maxX:o,minY:i,maxY:r}=t.d.bounds;return 2*(o-n)+2*(r-i)}function ah(t,e){if(t.region1===e){if("number"==typeof t.region1T)return t.region1T;const n=ch(t.d,e);return t.region1T=n,n}if(t.region2===e){if("number"==typeof t.region2T)return t.region2T;const n=ch(t.d,e);return t.region2T=n,n}return ch(t.d,e)}function ch(t,e){const n=e.d.polygon;if(n&&n.length>=3){const o=rh(e);if(o)return function(t,e,n,o=1e-6){let i=0,r=0,s=Number.POSITIVE_INFINITY;const a=o*o;for(let n=0;n<e.length;n++){const o=ih(t,e[n],e[(n+1)%e.length]);if(o.d2<=a){i=n,r=o.u,s=o.d2;break}o.d2<s&&(i=n,r=o.u,s=o.d2)}return n.cumulative[i]+r*n.edgeLengths[i]}(t,n,o)}const{minX:o,maxX:i,minY:r,maxY:s}=e.d.bounds;return oh(t,o,i,r,s)}function lh(t,e,n=1e-6){return Math.abs(t-e)<n}function dh(t,e){return(t%e+e)%e}function hh(t,e,n,o){const i=Math.abs(dh(t-e,n));return i<o||n-i<o}function uh(t,e,n,o,i){const r=dh(t,o),s=dh(e,o),a=dh(n,o);return!(Math.abs(s-a)<i)&&(s<a?s<r&&r<a:r>s||r<a)}function ph(t,e,n){if("number"==typeof n&&n>0){let[o,i]=t,[r,s]=e;if(o=dh(o,n),i=dh(i,n),r=dh(r,n),s=dh(s,n),hh(o,r,n,1e-6)||hh(o,s,n,1e-6)||hh(i,r,n,1e-6)||hh(i,s,n,1e-6))return!1;return uh(r,o,i,n,1e-12)!==uh(s,o,i,n,1e-12)}const[o,i]=t[0]<t[1]?t:[t[1],t[0]],[r,s]=e[0]<e[1]?e:[e[1],e[0]];return!(lh(o,r)||lh(o,s)||lh(i,r)||lh(i,s))&&(o<r&&r<i&&i<s||r<o&&o<s&&s<i)}var mh=t=>{let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t){const{bounds:t}=r.d;e=Math.min(e,t.minX),n=Math.max(n,t.maxX),o=Math.min(o,t.minY),i=Math.max(i,t.maxY)}return{minX:e,maxX:n,minY:o,maxY:i}},gh=(t,e,n,o)=>{const i={portId:t,region1:e,region2:n,d:{x:o.x,y:o.y}};return e.ports.push(i),n.ports.push(i),i},fh=(t,e,n)=>{const o=.2;return{regionId:t,ports:[],d:{bounds:{minX:e-o,maxX:e+o,minY:n-o,maxY:n+o},center:{x:e,y:n},isPad:!1,isConnectionRegion:!0}}},yh=.01,_h=(t,e,n)=>Math.max(e,Math.min(n,t)),bh=(t,e,n)=>"left"===e?Math.abs(t.x-n.minX)<yh:"right"===e?Math.abs(t.x-n.maxX)<yh:"top"===e?Math.abs(t.y-n.maxY)<yh:Math.abs(t.y-n.minY)<yh,xh=(t,e,n,o)=>{const i=o.x-n.x,r=o.y-n.y,s=t-n.x,a=e-n.y,c=i*i+r*r,l=c>0?_h((s*i+a*r)/c,0,1):0,d=n.x+l*i,h=n.y+l*r,u=t-d,p=e-h;return{x:d,y:h,d2:u*u+p*p}},vh=(t,e,n,o,i)=>{const r=n.d.polygon;if(r&&r.length>=3){const n=new Set(i);let s=null;for(let a=0;a<r.length;a++){const c=r[a],l=r[(a+1)%r.length];if(i.length>0){if(!i.some(t=>bh(c,t,o)&&bh(l,t,o)&&n.has(t)))continue}const d=xh(t,e,c,l);(!s||d.d2<s.d2)&&(s=d)}if(s)return s}const s=n.d.bounds,a=[];if(i.length>0)for(const n of i)"left"===n?a.push({side:n,x:s.minX,y:_h(e,s.minY,s.maxY)}):"right"===n?a.push({side:n,x:s.maxX,y:_h(e,s.minY,s.maxY)}):"top"===n?a.push({side:n,x:_h(t,s.minX,s.maxX),y:s.maxY}):a.push({side:n,x:_h(t,s.minX,s.maxX),y:s.minY});0===a.length&&a.push({side:"left",x:s.minX,y:_h(e,s.minY,s.maxY)},{side:"right",x:s.maxX,y:_h(e,s.minY,s.maxY)},{side:"top",x:_h(t,s.minX,s.maxX),y:s.maxY},{side:"bottom",x:_h(t,s.minX,s.maxX),y:s.minY});let c=null;for(const n of a){if(i.length>0&&!i.includes(n.side))continue;const o=t-n.x,r=e-n.y,s=o*o+r*r;(!c||s<c.d2)&&(c={x:n.x,y:n.y,d2:s})}return c},Sh=(t,e,n,o)=>{const i=((t,e,n)=>{const o=[];return Math.abs(t-n.minX)<yh&&o.push("left"),Math.abs(t-n.maxX)<yh&&o.push("right"),Math.abs(e-n.maxY)<yh&&o.push("top"),Math.abs(e-n.minY)<yh&&o.push("bottom"),o})(t,e,o);let r=null,s=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-o.minX)<.01||Math.abs(n.maxX-o.maxX)<.01||Math.abs(n.minY-o.minY)<.01||Math.abs(n.maxY-o.maxY)<.01))continue;const l=vh(t,e,c,o,i);if(!l)continue;const d=Math.sqrt(l.d2);d<s&&(s=d,r=c,a={x:l.x,y:l.y})}return r?{region:r,portPosition:a}:null},Ih=class extends kt{constructor(t){super(),this.input=t,this.graph=t.hyperGraphSolver.graph;const e=t.inputSolvedRoutes,n=t.hyperGraphSolver.connections;this.connections=n,this.solvedRoutes=th({graph:this.graph,connections:this.connections,solvedRoutes:e}),this.maxAttemptsPerRegion=t.MAX_ATTEMPTS_PER_REGION,this.maxSectionAttempts=t.MAX_ATTEMPTS_PER_SECTION??500,this.iterations+=this.iterations*(t.effort??1),this.fractionToReplace=t.FRACTION_TO_REPLACE??.2,this.alwaysRipConflicts=t.alwaysRipConflicts??!0}graph;connections;solvedRoutes;activeSection=null;baselineSectionCost=1/0;baselineGlobalCost=1/0;regionAttemptCounts=new Map;sectionAttempts=0;maxAttemptsPerRegion;maxSectionAttempts;fractionToReplace;alwaysRipConflicts;random=(t=>{let e=t;return()=>(e=1664525*e+1013904223>>>0,e/4294967295)})(31337);getSolverName(){return"HyperGraphSectionOptimizer"}getConstructorParams(){return{inputGraph:Gd(this.graph),inputConnections:Hd(this.connections),inputSolvedRoutes:this.solvedRoutes,expansionHopsFromCentralRegion:this.input.expansionHopsFromCentralRegion,maxAttemptsPerRegion:this.maxAttemptsPerRegion,maxSectionAttempts:this.maxSectionAttempts,effort:this.input.effort,fractionToReplace:this.fractionToReplace,alwaysRipConflicts:this.alwaysRipConflicts,ACCEPTABLE_COST:this.input.ACCEPTABLE_REGION_COST}}getOutput(){return this.solvedRoutes}_setup(){this.beginSectionSolve()}visualize(){return this.activeSubSolver?this.activeSubSolver.visualize():{title:"HyperGraphSectionOptimizer",points:[],lines:[],rects:[],circles:[],texts:[],polygons:[],arrows:[]}}getCostOfRegionWithAttempts(t){const e=this.regionAttemptCounts.get(t.regionId)??0;return this.input.regionCost(t)+1e4*e}computeCostOfSection({section:t,solvedRoutes:e}){if(this.input.computeSolvedGraphCost)return this.input.computeSolvedGraphCost(e);const n=this.input.createHyperGraphSolver({inputGraph:t.graph,inputConnections:t.connections,inputSolvedRoutes:e});let o=0;for(const t of n.graph.regions)o+=this.input.regionCost(t);return o}computeSolvedGraphCost(t){if(this.input.computeSolvedGraphCost)return this.input.computeSolvedGraphCost(t);const e=this.input.createHyperGraphSolver({inputGraph:this.graph,inputConnections:this.connections,inputSolvedRoutes:t});let n=0;for(const t of e.graph.regions)n+=this.input.regionCost(t);return n}determineConnectionsToRip(t,e){const n=t.sectionRoutes.map(t=>t.globalConnection.connectionId);if(this.fractionToReplace>=1)return new Set(n);const o=[...n];for(let t=o.length-1;t>0;t--){const e=Math.floor(this.random()*(t+1));[o[t],o[e]]=[o[e],o[t]]}const i=Math.max(1,Math.ceil(o.length*this.fractionToReplace)),r=new Set(o.slice(0,i));if(!this.alwaysRipConflicts)return r;const s=new Map(t.graph.regions.map(t=>[t.regionId,t]));for(const n of t.sectionRoutes)for(const t of n.sectionRoute.path){if(!t.lastPort||!t.lastRegion)continue;const o=s.get(t.lastRegion.regionId);if(!o)continue;e.currentConnection=n.globalConnection;const i=e.getRipsRequiredForPortUsage(o,t.lastPort,t.port);for(const t of i){const e=n.globalConnection.connectionId,o=t.connection.connectionId;r.has(e)||r.has(o)||r.add(this.random()<.5?e:o)}}return r}getNextCentralRegion(){let t=null,e=1/0;for(const n of this.graph.regions){if(0===(n.assignments?.length??0))continue;if((this.regionAttemptCounts.get(n.regionId)??0)>=this.maxAttemptsPerRegion)continue;if(this.input.regionCost(n)<this.input.ACCEPTABLE_REGION_COST)continue;const o=this.getCostOfRegionWithAttempts(n);o>=e||(e=o,t=n)}return t}beginSectionSolve(){if(this.sectionAttempts>=this.maxSectionAttempts)return console.log(`Reached max section attempts (${this.maxSectionAttempts}), stopping optimization`),void(this.solved=!0);const t=this.getNextCentralRegion();if(!t)return void(this.solved=!0);if(this.sectionAttempts++,this.activeSection=Jd({graph:this.graph,solvedRoutes:this.solvedRoutes,centralRegion:t,expansionHopsFromCentralRegion:this.input.expansionHopsFromCentralRegion}),!this.activeSection)return;if(0===this.activeSection.connections.length)return this.regionAttemptCounts.set(t.regionId,(this.regionAttemptCounts.get(t.regionId)??0)+1),void(this.activeSection=null);const e=this.activeSection.sectionRoutes.filter(t=>t.canRemainFixedInSectionSolve),n=this.input.createHyperGraphSolver({inputGraph:this.activeSection.graph,inputConnections:this.activeSection.connections,inputSolvedRoutes:e.map(t=>t.sectionRoute)}),o=this.determineConnectionsToRip(this.activeSection,n);for(const t of this.activeSection.sectionRoutes)t.canRemainFixedInSectionSolve||o.add(t.globalConnection.connectionId);const i=this.activeSection.sectionRoutes.filter(t=>t.canRemainFixedInSectionSolve&&!o.has(t.globalConnection.connectionId)).map(t=>t.sectionRoute),r=[...i,...this.activeSection.sectionRoutes.filter(t=>o.has(t.globalConnection.connectionId)).map(t=>t.sectionRoute)];this.baselineSectionCost=this.computeCostOfSection({section:this.activeSection,solvedRoutes:r}),this.baselineGlobalCost=this.computeSolvedGraphCost(this.solvedRoutes),this.activeSubSolver=this.input.createHyperGraphSolver({inputGraph:this.activeSection.graph,inputConnections:this.activeSection.connections,inputSolvedRoutes:i});for(const t of this.activeSubSolver.connections)t.startRegion&&t.endRegion||console.error({startRegion:t.startRegion?.regionId,endRegion:t.endRegion?.regionId})}_step(){if(!this.activeSubSolver)return void this.beginSectionSolve();if(this.activeSubSolver.step(),!this.activeSection)return;if(this.activeSubSolver.failed){this.failedSubSolvers??=[],this.failedSubSolvers.push(this.activeSubSolver);const t=this.regionAttemptCounts.get(this.activeSection.centralRegionId)??0;return this.regionAttemptCounts.set(this.activeSection.centralRegionId,t+1),this.activeSubSolver=null,this.activeSection=null,this.baselineSectionCost=1/0,void(this.baselineGlobalCost=1/0)}if(!this.activeSubSolver.solved)return;const t=this.activeSubSolver.solvedRoutes,e=this.computeCostOfSection({section:this.activeSection,solvedRoutes:t}),n=(t=>{const{solvedRoutes:e,section:n,replacementSolvedRoutes:o}=t,i=new Map(o.map(t=>[t.connection.connectionId,t]));return e.map(t=>{const e=n.sectionRoutes.find(e=>e.globalConnection.connectionId===t.connection.connectionId);if(!e)return t;const o=i.get(t.connection.connectionId);if(!o)return t;const r=[...t.path.slice(0,e.sectionStartIndex),...o.path,...t.path.slice(e.sectionEndIndex+1)].map(t=>({port:t.port,g:t.g,h:t.h,f:t.f,hops:t.hops,ripRequired:t.ripRequired,lastPort:t.lastPort,lastRegion:t.lastRegion,nextRegion:t.nextRegion}));for(let t=0;t<r.length;t++)r[t].parent=t>0?r[t-1]:void 0;return{connection:t.connection,path:r,requiredRip:t.requiredRip||o.requiredRip}})})({solvedRoutes:this.solvedRoutes,section:this.activeSection,replacementSolvedRoutes:t}),o=this.computeSolvedGraphCost(n),i=e<=this.baselineSectionCost,r=o<this.baselineGlobalCost;if(i&&r){this.solvedRoutes=n;const t=this.input.hyperGraphSolver;if(!t)return;t.solvedRoutes=th({graph:t.graph,connections:t.connections,solvedRoutes:this.solvedRoutes});for(const t of this.activeSection.sectionRegionIds)this.regionAttemptCounts.set(t,0);this.baselineSectionCost=e,this.baselineGlobalCost=o}else{const t=this.regionAttemptCounts.get(this.activeSection.centralRegionId)??0;this.regionAttemptCounts.set(this.activeSection.centralRegionId,t+1)}this.activeSubSolver=null,this.activeSection=null,this.baselineSectionCost=1/0,this.baselineGlobalCost=1/0}};function Ch(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 Ph(t){return void 0===t}function Mh(t,e=0){return{a:1,c:0,e:t,b:0,d:1,f:e}}function Nh(...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,o,...i]=t;return Nh(e(n,o),...i)}}}var{cos:wh,sin:Th,PI:Rh}=Math;var{tan:Eh}=Math,Ah=t=>({x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}),Oh=(t,e)=>{const n=t.regions.map(t=>{const{bounds:n,center:o,...i}=t.d,r=[{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=>Ch(e,t)),s={minX:Math.min(...r.map(t=>t.x)),maxX:Math.max(...r.map(t=>t.x)),minY:Math.min(...r.map(t=>t.y)),maxY:Math.max(...r.map(t=>t.y))},a=Ch(e,o);return{...t,ports:[],d:{...i,bounds:s,center:a}}}),o=new Map;for(let e=0;e<t.regions.length;e++)o.set(t.regions[e],n[e]);const i=t.ports.map(t=>{const n=Ch(e,t.d),i=o.get(t.region1),r=o.get(t.region2),s={...t,region1:i,region2:r,d:n};return i.ports.push(s),r.ports.push(s),s}),r=t.jumperLocations?.map(t=>{const n=Ch(e,t.center),i=t.padRegions.map(t=>o.get(t)),r=Ch(e,{x:1,y:0}),s=Ch(e,{x:0,y:0}),a=r.x-s.x,c=r.y-s.y;return{center:n,orientation:Math.abs(c)>Math.abs(a)?"horizontal"===t.orientation?"vertical":"horizontal":t.orientation,padRegions:i}});return{regions:n,ports:i,...r&&{jumperLocations:r}}};var kh=(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})`},Lh=t=>{const e=(t=>{const e=((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:o,isThroughJumper:i,isConnectionRegion:r,polygon:s}=e.d,a=(t.minX+t.maxX)/2,c=(t.minY+t.maxY)/2,l=t.maxX-t.minX,d=t.maxY-t.minY;let h;if(h=r?"rgba(255, 100, 255, 0.6)":i?"rgba(100, 200, 100, 0.5)":o?"rgba(255, 200, 100, 0.5)":"rgba(200, 200, 255, 0.1)",s&&s.length>=3){const t=s;n.polygons.push({points:t,fill:h})}else n.rects.push({center:{x:a,y:c},width:l-.1,height:d-.1,fill:h})}if(!e?.hidePortPoints)for(const e of t.ports){const t=e.region1.regionId.split(":").pop()??e.region1.regionId,o=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}-${o}`})}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},o={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},o],strokeColor:"rgba(100, 100, 100, 0.3)"})}if(e?.connections&&!e?.hideConnectionLines)for(const t of e.connections){const e=t.startRegion,o=t.endRegion,i={x:(e.d.bounds.minX+e.d.bounds.maxX)/2,y:(e.d.bounds.minY+e.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},s=(i.x+r.x)/2,a=(i.y+r.y)/2;n.lines.push({points:[i,r],strokeColor:"rgba(255, 50, 150, 0.8)",strokeDash:"3 3"}),n.points.push({x:s,y:a,color:"rgba(200, 0, 100, 1)",label:t.connectionId})}return n})(t.graph,{connections:t.connections,...t.hideInitialGeometry?{hideRegionPortLines:!0,hideConnectionLines:!0,hidePortPoints:!0}:{}});if(!t.hideInitialGeometry)for(const t of e.polygons)t.stroke="rgba(128, 128, 128, 0.5)",t.strokeWidth=.03;t.title&&(e.title=t.title);for(const n of t.priorSolvedRoutes??[]){const t=n.path.map(t=>{const e=t.port;return{x:e.d.x,y:e.d.y}});0!==t.length&&e.lines.push({points:t,strokeColor:"rgba(80, 80, 80, 0.45)",strokeDash:"4 4"})}for(const n of t.solvedRoutes){const t=kh(n.connection.connectionId),o=[];for(const t of n.path){const e=t.port;o.push({x:e.d.x,y:e.d.y})}o.length>0&&e.lines.push({points:o,strokeColor:t})}return e})({graph:{regions:t.graph.regions,ports:t.graph.ports},connections:t.connections,solvedRoutes:t.solvedRoutes,hideInitialGeometry:t.iterations>0});if(t.currentConnection&&!t.solved){const n=kh(t.currentConnection.connectionId),o=t.currentConnection.startRegion,i=t.currentConnection.endRegion;if(!o?.d||!i?.d)return e;const r={x:(o.d.bounds.minX+o.d.bounds.maxX)/2,y:(o.d.bounds.minY+o.d.bounds.maxY)/2},s={x:(i.d.bounds.minX+i.d.bounds.maxX)/2,y:(i.d.bounds.minY+i.d.bounds.maxY)/2};e.lines.push({points:[r,s],strokeColor:n,strokeDash:"10 5"}),e.points.push({x:r.x-.1,y:r.y+.1,color:n,label:[t.currentConnection.connectionId,"start"].join("\n")}),e.points.push({x:s.x-.1,y:s.y+.1,color:n,label:[t.currentConnection.connectionId,"end"].join("\n")})}const n=t.candidateQueue.peekMany(10);for(let t=0;t<n.length;t++){const o=n[t],i=o.port,r=0===t;e.points.push({x:i.d.x,y:i.d.y,color:r?"green":"rgba(128, 128, 128, 0.25)",label:[o.port.portId,`g: ${o.g.toFixed(2)}`,`h: ${o.h.toFixed(2)}`,`f: ${o.f.toFixed(2)}`].join("\n")})}const o=n[0];if(!t.solved&&o&&t.currentConnection){const n=kh(t.currentConnection.connectionId),i=[];let r=o;for(;r;){const t=r.port;i.unshift({x:t.d.x,y:t.d.y}),r=r.parent}i.length>1&&e.lines.push({points:i,strokeColor:n})}return e},Dh=.034685181009478865,zh=0,Fh=4.072520483177124,Bh=0,jh=35.38577539020022,$h=.5518001238069296,Yh=class extends eh{getSolverName(){return"JumperGraphSolver"}UNIT_OF_COST="hops";portUsagePenalty=Dh;portUsagePenaltySq=zh;crossingPenalty=Fh;crossingPenaltySq=Bh;ripCost=jh;baseMaxIterations=4e3;additionalMaxIterationsPerConnection=2e3;additionalMaxIterationsPerCrossing=2e3;constructor(t){super({greedyMultiplier:$h,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=function(t,e){if(e.length<2)return 0;let n=1/0,o=-1/0,i=1/0,r=-1/0;for(const e of t.regions){const t=e;t.d?.bounds?(n=Math.min(n,t.d.bounds.minX),o=Math.max(o,t.d.bounds.maxX),i=Math.min(i,t.d.bounds.minY),r=Math.max(r,t.d.bounds.maxY)):t.d?.center&&(n=Math.min(n,t.d.center.x),o=Math.max(o,t.d.center.x),i=Math.min(i,t.d.center.y),r=Math.max(r,t.d.center.y))}const s=new Map;for(const e of t.regions){const t=e;t.d?.center&&s.set(e.regionId,t.d.center)}const a=[],c=2*(o-n)+2*(r-i);for(const t of e){let e,c;if("startRegion"in t&&t.startRegion){const n=t.startRegion,o=t.endRegion;e=n.d?.center,c=o.d?.center}else"startRegionId"in t&&(e=s.get(t.startRegionId),c=s.get(t.endRegionId));if(!e||!c)continue;const l=oh(e,n,o,i,r),d=oh(c,n,o,i,r);a.push([l,d])}let l=0;for(let t=0;t<a.length;t++)for(let e=t+1;e<a.length;e++)ph(a[t],a[e],c)&&l++;return l}(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:o}=n.shift();for(const i of e.ports){const r=i.region1===e?i.region2:i.region1;t.has(r.regionId)||(t.set(r.regionId,o+1),n.push({region:r,distance:o+1}))}}for(const n of this.graph.ports){n.distanceToEndMap||(n.distanceToEndMap={});const o=t.get(n.region1.regionId)??1/0,i=t.get(n.region2.regionId)??1/0;n.distanceToEndMap[e.regionId]=Math.min(o,i)}}}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 o=e=>{const n=e.region1===t?e.region2:e.region1;return Boolean(n.d.isThroughJumper)};return o(e)||o(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 o=function(t,e,n){const o=sh(t),i=[ah(e,t),ah(n,t)];let r=0;const s=t.assignments??[];for(const e of s)ph(i,[ah(e.regionPort1,t),ah(e.regionPort2,t)],o)&&r++;return r}(t,e,n);return o*this.crossingPenalty+o*this.crossingPenaltySq}getRipsRequiredForPortUsage(t,e,n){if(t.d.isPad){return(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}const o=function(t,e,n){const o=sh(t),i=[ah(e,t),ah(n,t)],r=[],s=t.assignments??[];for(const e of s)ph(i,[ah(e.regionPort1,t),ah(e.regionPort2,t)],o)&&r.push(e);return r}(t,e,n),i=o.filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId);if(!t.d.isThroughJumper)return i;for(const e of t.assignments??[])e.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId&&i.push(e);return i}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 Lh(this)}},Xh={padWidth:.8,outerPadHeight:.5,innerPadHeight:.4,leftPadCenterX:-.9,rightPadCenterX:.9,row1CenterY:-1.2,row2CenterY:-.4,row3CenterY:.4,row4CenterY:1.2},Vh=({cols:t,rows:e,marginX:n,marginY:o,innerColChannelPointCount:i=1,innerRowChannelPointCount:r=1,regionsBetweenPads:s=!1,outerPaddingX:a=.5,outerPaddingY:c=.5,outerChannelXPointCount:l,outerChannelYPointCount:d,orientation:h="vertical",center:u,bounds:p,parallelTracesUnderJumperCount:m=2})=>{const g=[],f=[],{padWidth:y,outerPadHeight:_,innerPadHeight:b,leftPadCenterX:x,rightPadCenterX:v,row1CenterY:S,row2CenterY:I,row3CenterY:C,row4CenterY:P}=Xh,M=y/2,N=_/2,w=b/2,T=v-x+y,R=T+n,E=P-S+_,A=E+o;let O=a,k=c;if(p){const i=t*T+(t-1)*n,r=e*E+(e-1)*o;O=(("horizontal"===h?p.maxY-p.minY:p.maxX-p.minX)-i)/2,k=(("horizontal"===h?p.maxX-p.minX:p.maxY-p.minY)-r)/2}const L=l??Math.max(1,Math.floor(O/.4)),D=d??Math.max(1,Math.floor(k/.4)),z=[],F=[],B=(t,e,n,o)=>({regionId:t,ports:[],d:{bounds:e,center:Ah(e),isPad:n,isThroughJumper:o}}),j=(t,e,n)=>{const o=e.d.bounds,i=n.d.bounds;let r,s;Math.abs(o.maxX-i.minX)<.001?(r=o.maxX,s=(Math.max(o.minY,i.minY)+Math.min(o.maxY,i.maxY))/2):Math.abs(o.minX-i.maxX)<.001?(r=o.minX,s=(Math.max(o.minY,i.minY)+Math.min(o.maxY,i.maxY))/2):Math.abs(o.maxY-i.minY)<.001?(r=(Math.max(o.minX,i.minX)+Math.min(o.maxX,i.maxX))/2,s=o.maxY):(r=(Math.max(o.minX,i.minX)+Math.min(o.maxX,i.maxX))/2,s=o.minY);const a={portId:t,region1:e,region2:n,d:{x:r,y:s}};return e.ports.push(a),n.ports.push(a),a},$=(t,e,n,o)=>{if(o<=0)return[];if(1===o)return[j(t,e,n)];const i=e.d.bounds,r=n.d.bounds,s=[];let a,c,l,d;Math.abs(i.maxX-r.minX)<.001?(a=!0,c=i.maxX,l=Math.max(i.minY,r.minY),d=Math.min(i.maxY,r.maxY)):Math.abs(i.minX-r.maxX)<.001?(a=!0,c=i.minX,l=Math.max(i.minY,r.minY),d=Math.min(i.maxY,r.maxY)):Math.abs(i.maxY-r.minY)<.001?(a=!1,c=i.maxY,l=Math.max(i.minX,r.minX),d=Math.min(i.maxX,r.maxX)):(a=!1,c=i.minY,l=Math.max(i.minX,r.minX),d=Math.min(i.maxX,r.maxX));for(let i=0;i<o;i++){const r=l+(i+.5)/o*(d-l),h={portId:`${t}:${i}`,region1:e,region2:n,d:{x:a?c:r,y:a?r:c}};e.ports.push(h),n.ports.push(h),s.push(h)}return s};for(let n=0;n<e;n++){z[n]=[];for(let a=0;a<t;a++){const c=`cell_${n}_${a}`,l=a*R,d=-n*A,h=l+x,u=d+S,p=l+x,y=d+I,_=l+x,b=d+C,T=l+x,E=d+P,Y=l+v,X=d+P,V=l+v,W=d+C,H=l+v,G=d+I,U=l+v,Z=d+S,q=(t,e,n)=>({minX:t-M,maxX:t+M,minY:e-n,maxY:e+n}),J=q(h,u,N),K=q(p,y,w),Q=q(_,b,w),tt=q(T,E,N),et=q(Y,X,N),nt=q(V,W,w),ot=q(H,G,w),it=q(U,Z,N),rt={minX:J.maxX,maxX:it.minX,minY:J.minY,maxY:tt.maxY},st=.3,at={minX:h,maxX:U,minY:u-st/2,maxY:u+st/2},ct={minX:p,maxX:H,minY:y-st/2,maxY:y+st/2},lt={minX:_,maxX:V,minY:b-st/2,maxY:b+st/2},dt={minX:T,maxX:Y,minY:E-st/2,maxY:E+st/2},ht=J.minX,ut=it.maxX,pt=J.minY,mt=tt.maxY,gt=B(`${c}:pad1`,J,!0),ft=B(`${c}:pad2`,K,!0),yt=B(`${c}:pad3`,Q,!0),_t=B(`${c}:pad4`,tt,!0),bt=B(`${c}:pad5`,et,!0),xt=B(`${c}:pad6`,nt,!0),vt=B(`${c}:pad7`,ot,!0),St=B(`${c}:pad8`,it,!0),It=B(`${c}:underjumper`,rt,!1),Ct=B(`${c}:throughjumper1`,at,!1,!0),Pt=B(`${c}:throughjumper2`,ct,!1,!0),Mt=B(`${c}:throughjumper3`,lt,!1,!0),Nt=B(`${c}:throughjumper4`,dt,!1,!0);g.push(gt,ft,yt,_t,bt,xt,vt,St,It,Ct,Pt,Mt,Nt);const wt=(h+U)/2,Tt=(u+E)/2;F.push({center:{x:wt,y:Tt},orientation:"vertical",padRegions:[gt,ft,yt,_t,bt,xt,vt,St]});let Rt=null,Et=null,At=null,Ot=null,kt=null,Lt=null;s&&(Rt=B(`${c}:L-BP12`,{minX:J.minX,maxX:J.maxX,minY:J.maxY,maxY:K.minY},!1),Et=B(`${c}:L-BP23`,{minX:K.minX,maxX:K.maxX,minY:K.maxY,maxY:Q.minY},!1),At=B(`${c}:L-BP34`,{minX:Q.minX,maxX:Q.maxX,minY:Q.maxY,maxY:tt.minY},!1),Ot=B(`${c}:R-BP87`,{minX:it.minX,maxX:it.maxX,minY:it.maxY,maxY:ot.minY},!1),kt=B(`${c}:R-BP76`,{minX:ot.minX,maxX:ot.maxX,minY:ot.maxY,maxY:nt.minY},!1),Lt=B(`${c}:R-BP65`,{minX:nt.minX,maxX:nt.maxX,minY:nt.maxY,maxY:et.minY},!1),g.push(Rt,Et,At,Ot,kt,Lt));const Dt=0===a,zt=n===e-1,Ft=a===t-1;let Bt;if(Ft)Bt=ut+O;else{Bt=(a+1)*R+x-M}let jt=null;0===n&&(jt=B(`${c}:T`,{minX:Dt?ht-O:ht,maxX:Bt,minY:mt,maxY:mt+k},!1),g.push(jt));let $t=null;$t=B(`${c}:B`,{minX:Dt?ht-O:ht,maxX:Bt,minY:pt-(zt?k:o),maxY:pt},!1),g.push($t);let Yt=null;Dt&&(Yt=B(`${c}:L`,{minX:ht-O,maxX:ht,minY:pt,maxY:mt},!1),g.push(Yt));const Xt=B(`${c}:R`,{minX:ut,maxX:Bt,minY:pt,maxY:mt},!1);if(g.push(Xt),z[n][a]={pad1:gt,pad2:ft,pad3:yt,pad4:_t,pad5:bt,pad6:xt,pad7:vt,pad8:St,underjumper:It,throughjumper1:Ct,throughjumper2:Pt,throughjumper3:Mt,throughjumper4:Nt,top:jt,bottom:$t,left:Yt,right:Xt,leftBP12:Rt,leftBP23:Et,leftBP34:At,rightBP87:Ot,rightBP76:kt,rightBP65:Lt},jt)if(Yt&&f.push(...$(`${c}:T-L`,jt,Yt,L)),f.push(...$(`${c}:T-R`,jt,Xt,Ft?L:i)),f.push(j(`${c}:T-P4`,jt,_t)),f.push(j(`${c}:T-P5`,jt,bt)),s){const t=It.d.bounds,e=(t.maxX-t.minX)/(m+1);for(let n=1;n<=m;n++){const o={portId:`${c}:T-UJ${n}`,region1:jt,region2:It,d:{x:t.minX+e*n,y:t.maxY}};jt.ports.push(o),It.ports.push(o),f.push(o)}}else f.push(j(`${c}:T-UJ`,jt,It));if($t)if(Yt&&f.push(...$(`${c}:B-L`,$t,Yt,L)),f.push(...$(`${c}:B-R`,$t,Xt,Ft?L:i)),f.push(j(`${c}:B-P1`,$t,gt)),f.push(j(`${c}:B-P8`,$t,St)),s){const t=It.d.bounds,e=(t.maxX-t.minX)/(m+1);for(let n=1;n<=m;n++){const o={portId:`${c}:B-UJ${n}`,region1:$t,region2:It,d:{x:t.minX+e*n,y:t.minY}};$t.ports.push(o),It.ports.push(o),f.push(o)}}else f.push(j(`${c}:B-UJ`,$t,It));Yt&&(f.push(j(`${c}:L-P1`,Yt,gt)),f.push(j(`${c}:L-P2`,Yt,ft)),f.push(j(`${c}:L-P3`,Yt,yt)),f.push(j(`${c}:L-P4`,Yt,_t))),f.push(j(`${c}:R-P5`,Xt,bt)),f.push(j(`${c}:R-P6`,Xt,xt)),f.push(j(`${c}:R-P7`,Xt,vt)),f.push(j(`${c}:R-P8`,Xt,St)),s&&(Yt&&(f.push(j(`${c}:L-BP12`,Yt,Rt)),f.push(j(`${c}:L-BP23`,Yt,Et)),f.push(j(`${c}:L-BP34`,Yt,At))),f.push(j(`${c}:UJ-LBP12`,Rt,It)),f.push(j(`${c}:UJ-LBP23`,Et,It)),f.push(j(`${c}:UJ-LBP34`,At,It)),f.push(j(`${c}:R-BP87`,Xt,Ot)),f.push(j(`${c}:R-BP76`,Xt,kt)),f.push(j(`${c}:R-BP65`,Xt,Lt)),f.push(j(`${c}:UJ-RBP87`,Ot,It)),f.push(j(`${c}:UJ-RBP76`,kt,It)),f.push(j(`${c}:UJ-RBP65`,Lt,It)));const Vt={portId:`${c}:TJ1-P1`,region1:Ct,region2:gt,d:{x:h,y:u}};Ct.ports.push(Vt),gt.ports.push(Vt),f.push(Vt);const Wt={portId:`${c}:TJ1-P8`,region1:Ct,region2:St,d:{x:U,y:Z}};Ct.ports.push(Wt),St.ports.push(Wt),f.push(Wt);const Ht={portId:`${c}:TJ2-P2`,region1:Pt,region2:ft,d:{x:p,y:y}};Pt.ports.push(Ht),ft.ports.push(Ht),f.push(Ht);const Gt={portId:`${c}:TJ2-P7`,region1:Pt,region2:vt,d:{x:H,y:G}};Pt.ports.push(Gt),vt.ports.push(Gt),f.push(Gt);const Ut={portId:`${c}:TJ3-P3`,region1:Mt,region2:yt,d:{x:_,y:b}};Mt.ports.push(Ut),yt.ports.push(Ut),f.push(Ut);const Zt={portId:`${c}:TJ3-P6`,region1:Mt,region2:xt,d:{x:V,y:W}};Mt.ports.push(Zt),xt.ports.push(Zt),f.push(Zt);const qt={portId:`${c}:TJ4-P4`,region1:Nt,region2:_t,d:{x:T,y:E}};Nt.ports.push(qt),_t.ports.push(qt),f.push(qt);const Jt={portId:`${c}:TJ4-P5`,region1:Nt,region2:bt,d:{x:Y,y:X}};if(Nt.ports.push(Jt),bt.ports.push(Jt),f.push(Jt),a>0){const t=z[n][a-1];f.push(j(`cell_${n}_${a-1}->cell_${n}_${a}:R-P1`,t.right,gt)),f.push(j(`cell_${n}_${a-1}->cell_${n}_${a}:R-P2`,t.right,ft)),f.push(j(`cell_${n}_${a-1}->cell_${n}_${a}:R-P3`,t.right,yt)),f.push(j(`cell_${n}_${a-1}->cell_${n}_${a}:R-P4`,t.right,_t)),s&&(f.push(j(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP12`,t.right,Rt)),f.push(j(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP23`,t.right,Et)),f.push(j(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP34`,t.right,At))),jt&&t.top&&f.push(...$(`cell_${n}_${a-1}->cell_${n}_${a}:T-T`,t.top,jt,D)),$t&&t.bottom&&f.push(...$(`cell_${n}_${a-1}->cell_${n}_${a}:B-B`,t.bottom,$t,zt?D:r))}if(n>0){const t=z[n-1][a];if(Yt&&f.push(...$(`cell_${n-1}_${a}->cell_${n}_${a}:B-L`,t.bottom,Yt,L)),f.push(j(`cell_${n-1}_${a}->cell_${n}_${a}:B-P4`,t.bottom,_t)),s){const e=It.d.bounds,o=(e.maxX-e.minX)/(m+1);for(let i=1;i<=m;i++){const r=e.minX+o*i,s={portId:`cell_${n-1}_${a}->cell_${n}_${a}:B-UJ${i}`,region1:t.bottom,region2:It,d:{x:r,y:e.maxY}};t.bottom.ports.push(s),It.ports.push(s),f.push(s)}}else f.push(j(`cell_${n-1}_${a}->cell_${n}_${a}:B-UJ`,t.bottom,It));f.push(j(`cell_${n-1}_${a}->cell_${n}_${a}:B-P5`,t.bottom,bt)),f.push(...$(`cell_${n-1}_${a}->cell_${n}_${a}:B-R`,t.bottom,Xt,Ft?L:i))}}}let Y={regions:g,ports:f,jumperLocations:F};const X="horizontal"===h;if(X||void 0!==u||void 0!==p){const t=mh(Y.regions),e=Ah(t),n=[];let o;o=u||(p?Ah(p):e),n.push(Mh(o.x,o.y)),X&&n.push(function(t,e,n){const o=wh(t),i=Th(t),r={a:o,c:-i,e:0,b:i,d:o,f:0};return Ph(e)||Ph(n)?r:Nh([Mh(e,n),r,Mh(-e,-n)])}(-Math.PI/2)),n.push(Mh(-e.x,-e.y));const i=function(...t){return Nh(...t)}(...n);Y=Oh(Y,i)}return Y},Wh=!0,Hh={CCW:-1,CW:1,NOT_ORIENTABLE:0},Gh=2*Math.PI,Uh=Object.freeze({__proto__:null,BOUNDARY:2,CCW:Wh,CONTAINS:3,CW:!1,END_VERTEX:2,INSIDE:1,INTERLACE:4,NOT_VERTEX:0,ORIENTATION:Hh,OUTSIDE:0,OVERLAP_OPPOSITE:2,OVERLAP_SAME:1,PIx2:Gh,START_VERTEX:1}),Zh=1e-6;function qh(t){Zh=t}function Jh(){return Zh}function Kh(t){return t<Zh&&t>-Zh}function Qh(t,e){return t-e<Zh&&t-e>-Zh}function tu(t,e){return t-e>Zh}function eu(t,e){return t-e<-Zh}var nu={Utils:Object.freeze({__proto__:null,DECIMALS:3,EQ:Qh,EQ_0:Kh,GE:function(t,e){return t-e>-Zh},GT:tu,LE:function(t,e){return t-e<Zh},LT:eu,getTolerance:Jh,setTolerance:qh}),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 Uh)nu[t]=Uh[t];Object.defineProperty(nu,"DP_TOL",{get:function(){return Jh()},set:function(t){qh(t)}});var ou=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")}};nu.Errors=ou;var iu=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=[],o=t||this.first,i=e||this.last,r=o;if(void 0===r)return n;do{n.push(r),r=r.next}while(r!==i.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 ou.INFINITE_LOOP;e=e.next,n=n.next.next}while(e!=t)}},ru={stroke:"black"},su=class{constructor(t=ru){for(const e in t)this[e]=t[e];this.stroke=t.stroke??ru.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 au(t){return new su(t).toAttributesString()}function cu(t,e){let n=[],[o,i,r]=t.standard,[s,a,c]=e.standard,l=o*a-i*s,d=r*a-i*c,h=o*c-r*s;if(!nu.Utils.EQ_0(l)){let t,e;0===i?(t=r/o,e=h/l):0===a?(t=c/s,e=h/l):0===o?(t=d/l,e=r/i):0===s?(t=d/l,e=c/a):(t=d/l,e=h/l),n.push(new nu.Point(t,e))}return n}function lu(t,e){let n=[],o=e.pc.projectionOn(t),i=e.pc.distanceTo(o)[0];if(nu.Utils.EQ(i,e.r))n.push(o);else if(nu.Utils.LT(i,e.r)){let r,s,a=Math.sqrt(e.r*e.r-i*i);r=t.norm.rotate90CCW().multiply(a),s=o.translate(r),n.push(s),r=t.norm.rotate90CW().multiply(a),s=o.translate(r),n.push(s)}return n}function du(t,e){let n=[];for(let o of e.toSegments()){let e=uu(o,t);for(let t of e)Ru(t,n)||n.push(t)}return n}function hu(t,e){let n=[];if(0===du(t,e.box).length)return n;let o=lu(t,new nu.Circle(e.pc,e.r));for(let t of o)t.on(e)&&n.push(t);return n}function uu(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:cu(new nu.Line(t.ps,t.pe),e)}function pu(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 o=new nu.Line(t.ps,t.pe),i=new nu.Line(e.ps,e.pe);if(o.incidentTo(i))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 r=cu(o,i);r.length>0&&mu(r[0],t)&&mu(r[0],e)&&n.push(r[0])}return n}function mu(t,e){const n=e.box;return nu.Utils.LE(t.x,n.xmax)&&nu.Utils.GE(t.x,n.xmin)&&nu.Utils.LE(t.y,n.ymax)&&nu.Utils.GE(t.y,n.ymin)}function gu(t,e){let n=[];if(t.isZeroLength()){let[o,i]=t.ps.distanceTo(e.pc);return nu.Utils.EQ(o,e.r)&&n.push(t.ps),n}let o=lu(new nu.Line(t.ps,t.pe),e);for(let e of o)e.on(t)&&n.push(e);return n}function fu(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)&&n.push(t.ps),n;let o=lu(new nu.Line(t.ps,t.pe),new nu.Circle(e.pc,e.r));for(let i of o)i.on(t)&&i.on(e)&&n.push(i);return n}function yu(t,e){let n=[],o=new nu.Vector(t.pc,e.pc),i=t.r,r=e.r;if(nu.Utils.EQ_0(i)||nu.Utils.EQ_0(r))return n;if(nu.Utils.EQ_0(o.x)&&nu.Utils.EQ_0(o.y)&&nu.Utils.EQ(i,r))return n.push(t.pc.translate(-i,0)),n;let s,a=t.pc.distanceTo(e.pc)[0];if(nu.Utils.GT(a,i+r))return n;if(nu.Utils.LT(a,Math.abs(i-r)))return n;if(o.x/=a,o.y/=a,nu.Utils.EQ(a,i+r)||nu.Utils.EQ(a,Math.abs(i-r)))return s=t.pc.translate(i*o.x,i*o.y),n.push(s),n;let c=i*i/(2*a)-r*r/(2*a)+a/2,l=t.pc.translate(c*o.x,c*o.y),d=Math.sqrt(i*i-c*c);return s=l.translate(o.rotate90CCW().multiply(d)),n.push(s),s=l.translate(o.rotate90CW().multiply(d)),n.push(s),n}function _u(t,e){let n=[];if(t.pc.equalTo(e.pc)&&nu.Utils.EQ(t.r,e.r)){let o;return o=t.start,o.on(e)&&n.push(o),o=t.end,o.on(e)&&n.push(o),o=e.start,o.on(t)&&n.push(o),o=e.end,o.on(t)&&n.push(o),n}let o=new nu.Circle(t.pc,t.r),i=new nu.Circle(e.pc,e.r),r=o.intersect(i);for(let o of r)o.on(t)&&o.on(e)&&n.push(o);return n}function bu(t,e){let n=[];if(e.pc.equalTo(t.pc)&&nu.Utils.EQ(e.r,t.r))return n.push(t.start),n.push(t.end),n;let o=yu(e,new nu.Circle(t.pc,t.r));for(let e of o)e.on(t)&&n.push(e);return n}function xu(t,e){return t.isSegment?pu(t.shape,e):fu(e,t.shape)}function vu(t,e){return t.isSegment?fu(t.shape,e):_u(t.shape,e)}function Su(t,e){return t.isSegment?uu(t.shape,e):hu(e,t.shape)}function Iu(t,e){return t.isSegment?gu(t.shape,e):bu(t.shape,e)}function Cu(t,e){let n=[];for(let o of e.edges)for(let e of xu(o,t))n.push(e);return n}function Pu(t,e){let n=[];for(let o of e.edges)for(let e of vu(o,t))n.push(e);return n}function Mu(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of Su(o,t))Ru(e,n)||n.push(e);return t.sortPoints(n)}function Nu(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of Iu(o,t))n.push(e);return n}function wu(t,e){return t.isSegment?xu(e,t.shape):t.isArc?vu(e,t.shape):t.isLine?Su(e,t.shape):t.isRay?(n=e,o=t.shape,n.isSegment?Au(o,n.shape):Ou(o,n.shape)):[];var n,o}function Tu(t,e){let n=[];if(e.isEmpty()||t.shape.box.not_intersect(e.box))return n;let o=e.edges.search(t.shape.box);for(let e of o)n=[...n,...wu(t,e)];return n}function Ru(t,e){return e.some(e=>e.equalTo(t))}function Eu(t){return new nu.Line(t.start,t.norm)}function Au(t,e){return uu(e,Eu(t)).filter(e=>t.contains(e))}function Ou(t,e){return hu(Eu(t),e).filter(e=>t.contains(e))}function ku(t,e){return lu(Eu(t),e).filter(e=>t.contains(e))}function Lu(t,e){return cu(Eu(t),e).filter(e=>t.contains(e))}function Du(t,e){return Mu(Eu(t),e).filter(e=>t.contains(e))}function zu(t,e){if(t.intersect&&t.intersect instanceof Function)return t.intersect(e);throw ou.UNSUPPORTED_SHAPE_TYPE}function Fu(t,e){let n=[];for(let o of e)n=[...n,...zu(t,o.shape)];return n}var Bu=class t extends iu{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,o=t=>t instanceof nu.Segment||t instanceof nu.Arc||t instanceof nu.Ray,i=t=>t instanceof nu.Segment||t instanceof nu.Arc;if(!(1===n&&(t=>t instanceof nu.Segment||t instanceof nu.Arc||t instanceof nu.Ray||t instanceof nu.Line)(e[0])||n>1&&o(e[0])&&o(e[n-1])&&e.slice(1,n-1).every(i)))throw nu.Errors.ILLEGAL_PARAMETERS;this.isInfinite=e.some(t=>t instanceof nu.Ray||t instanceof nu.Line);for(let t of e){let e=new nu.Edge(t);this.append(e)}this.setArcLength()}}get edges(){return[...this]}get box(){return this.edges.reduce((t,e)=>t.merge(e.box),new nu.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 o=new nu.Edge(n[0]),i=e.prev;return this.insert(o,i),e.shape=n[1],o}getChain(t,e){let n=[];for(let o=t;o!==e.next;o=o.next)n.push(o);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]=nu.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof nu.Line){const[e,n]=nu.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof nu.Circle){const[e,n]=nu.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof nu.Segment){const[e,n]=nu.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof nu.Arc){const[e,n]=nu.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof nu.Multiline)return nu.Distance.multiline2multiline(this,t);throw nu.Errors.UNSUPPORTED_SHAPE_TYPE}intersect(t){return t instanceof nu.Multiline?function(t,e){let n=[];for(let o of t)for(let t of e)n=[...n,...zu(o.shape,t.shape)];return n}(this,t):Fu(t,this)}contains(t){if(t instanceof nu.Point)return this.edges.some(e=>e.shape.contains(t));throw nu.Errors.UNSUPPORTED_SHAPE_TYPE}translate(e){return new t(this.edges.map(t=>t.shape.translate(e)))}rotate(e=0,n=new nu.Point){return new t(this.edges.map(t=>t.shape.rotate(e,n)))}transform(e=new nu.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 ${au({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}};nu.Multiline=Bu;function ju(t,e,n){let o=n.length,i=t.shape.split(e);if(0===i.length)return;let r=0;r=null===i[0]?0:null===i[1]?t.shape.length:i[0].length;let s,a=0;Qh(r,0)&&(a|=1),Qh(r,t.shape.length)&&(a|=2),s=r===1/0?i[0].coord(e):2&a&&t.next&&0===t.next.arc_length?0:t.arc_length+r,n.push({id:o,pt:e,arc_length:s,edge_before:t,edge_after:void 0,face:t.face,is_vertex:a})}function $u(t){t.int_points1_sorted=Yu(t.int_points1),t.int_points2_sorted=Yu(t.int_points2)}function Yu(t){let e=new Map,n=0;for(let o of t)e.has(o.face)||(e.set(o.face,n),n++);for(let n of t)n.faceId=e.get(n.face);return t.slice().sort(Xu)}function Xu(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 Vu(t){if(t.int_points1.length<2)return;let e,n,o,i,r=!1;for(let s=0;s<t.int_points1_sorted.length;s++)if(-1!==t.int_points1_sorted[s].id){e=t.int_points1_sorted[s],n=t.int_points2[e.id];for(let a=s+1;a<t.int_points1_sorted.length&&(o=t.int_points1_sorted[a],Qh(o.arc_length,e.arc_length));a++)-1!==o.id&&(i=t.int_points2[o.id],-1!==i.id&&o.edge_before===e.edge_before&&o.edge_after===e.edge_after&&i.edge_before===n.edge_before&&i.edge_after===n.edge_after&&(o.id=-1,i.id=-1,r=!0))}n=t.int_points2_sorted[0],e=t.int_points1[n.id];for(let o=1;o<t.int_points2_sorted.length;o++){let i=t.int_points2_sorted[o];if(-1===i.id)continue;if(-1===n.id||!Qh(i.arc_length,n.arc_length)){n=i,e=t.int_points1[n.id];continue}let s=t.int_points1[i.id];s.edge_before===e.edge_before&&s.edge_after===e.edge_after&&i.edge_before===n.edge_before&&i.edge_after===n.edge_after&&(s.id=-1,i.id=-1,r=!0)}r&&(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 Wu(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 Hu(t,e){for(let n of t)n.edge_before&&n.edge_before.setInclusion(e),n.edge_after&&n.edge_after.setInclusion(e)}function Gu(t,e,n){let o,i,r=1;if(1===t.length)return 1;o=t[e];for(let s=e+1;s<t.length&&o.face===n&&(i=t[s],i.pt.equalTo(o.pt)&&i.edge_before===o.edge_before&&i.edge_after===o.edge_after);s++)r++;return r}function Uu(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 o=t.addVertex(n.pt,e);n.edge_before=o}for(let n of e)n.edge_before?n.edge_after=n.edge_before.next:t instanceof Bu&&1&n.is_vertex&&(n.edge_after=t.first)}}function Zu(t,e,n){const o=t.edge_before,i=e.edge_after,r=n.length;o.next=n[0],n[0].prev=o,n[r-1].next=i,i.prev=n[r-1]}nu.multiline=(...t)=>new nu.Multiline(...t);var{INSIDE:qu,OUTSIDE:Ju,BOUNDARY:Ku,OVERLAP_SAME:Qu,OVERLAP_OPPOSITE:tp}=Uh,{NOT_VERTEX:ep,START_VERTEX:np,END_VERTEX:op}=Uh;function ip(t,e){let n=e.clone().reverse(),[o,i]=dp(t,n,3,!0);return o}function rp(t,e){let[n,o]=dp(t,e,2,!0);return n}function sp(t,e){let[n,o]=dp(t,e,2,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=>t.shape)];let r=[];for(let t of o.faces)r=[...r,...[...t.edges].map(t=>t.shape)];return[i,r]}function ap(t,e){let[n,o]=dp(t,e,3,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=>t.shape)];return i}function cp(t,e){let n=t.clone(),o=e.clone(),i=hp(n,o);return $u(i),Uu(n,i.int_points1_sorted),Uu(o,i.int_points2_sorted),Vu(i),$u(i),[i.int_points1_sorted.map(t=>t.pt),i.int_points2_sorted.map(t=>t.pt)]}function lp(t,e,n,o){let i=up(t,n.int_points1),r=up(e,n.int_points2);for(pp(i,e),pp(r,t),Wu(n.int_points1),Wu(n.int_points2),Hu(n.int_points1,e),Hu(n.int_points2,t);mp(t,e,n.int_points1,n.int_points1_sorted,n.int_points2,n););!function(t){let e,n,o,i=t.int_points1.length;for(let r=0;r<i;r++){let s=t.int_points1_sorted[r];s.face!==e&&(n=r,e=s.face);let a,c=r,l=Gu(t.int_points1_sorted,r,e);a=c+l<i&&t.int_points1_sorted[c+l].face===e?c+l:n;let d=Gu(t.int_points1_sorted,a,e);o=null;for(let n=a;n<a+d;n++){let i=t.int_points1_sorted[n];if(i.face===e&&t.int_points2[i.id].face===t.int_points2[s.id].face){o=i;break}}if(null===o)continue;let h=s.edge_after,u=o.edge_before;if(2!==h.bv||2!==u.bv)continue;if(h!==u)continue;let p=t.int_points2[s.id],m=t.int_points2[o.id],g=p.edge_after,f=m.edge_before;2===g.bv&&2===f.bv&&g===f||(p=t.int_points2[o.id],m=t.int_points2[s.id],g=p.edge_after,f=m.edge_before),2===g.bv&&2===f.bv&&g===f&&h.setOverlap(g)}}(n),gp(t,o,n.int_points1_sorted,!0),gp(e,o,n.int_points2_sorted,!1),_p(t,i,o,!0),_p(e,r,o,!1)}function dp(t,e,n,o){let i=t.clone(),r=e.clone(),s=hp(i,r);return $u(s),Uu(i,s.int_points1_sorted),Uu(r,s.int_points2_sorted),Vu(s),$u(s),lp(i,r,s,n),o&&function(t,e,n){!function(t,e,n,o){for(let n of e.faces){for(let e of n)t.edges.add(e);void 0===o.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],o=n.int_points2[t];if(void 0!==e.edge_before&&void 0===e.edge_after&&void 0===o.edge_before&&void 0!==o.edge_after&&(e.edge_before.next=o.edge_after,o.edge_after.prev=e.edge_before,e.edge_after=o.edge_after,o.edge_before=e.edge_before),void 0!==o.edge_before&&void 0===o.edge_after&&void 0===e.edge_before&&void 0!==e.edge_after&&(o.edge_before.next=e.edge_after,e.edge_after.prev=o.edge_before,o.edge_after=e.edge_after,e.edge_before=o.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!==o.edge_before&&void 0===o.edge_after)for(let t of n.int_points2_sorted)t!==o&&void 0===t.edge_before&&void 0!==t.edge_after&&t.pt.equalTo(o.pt)&&(o.edge_before.next=t.edge_after,t.edge_after.prev=o.edge_before,o.edge_after=t.edge_after,t.edge_before=o.edge_before)}}(0,0,n),fp(t,n.int_points1),fp(e,n.int_points2),yp(t,n.int_points1,n.int_points2),yp(t,n.int_points2,n.int_points1)}(i,r,s),[i,r]}function hp(t,e){let n={int_points1:[],int_points2:[]};for(let o of t.edges){let t=e.edges.search(o.box);for(let e of t){let t=o.shape.intersect(e.shape);for(let i of t)ju(o,i,n.int_points1),ju(e,i,n.int_points2)}}return n}function up(t,e){let n=[];for(let o of t.faces)e.find(t=>t.face===o)||n.push(o);return n}function pp(t,e){for(let n of t)n.first.bv=n.first.bvStart=n.first.bvEnd=void 0,n.first.setInclusion(e)}function mp(t,e,n,o,i,r){let s,a,c,l=o.length,d=!1;for(let h=0;h<l;h++){let u=o[h];u.face!==s&&(a=h,s=u.face);let p,m=h,g=Gu(o,h,s);p=m+g<l&&o[m+g].face===s?m+g:a;let f=Gu(o,p,s);c=null;for(let t=p;t<p+f;t++){let e=o[t];if(e.face===s&&i[e.id].face===i[u.id].face){c=e;break}}if(null===c)continue;let y=u.edge_after,_=c.edge_before;if(y.bv!==Ku||_.bv==Ku)if(y.bv==Ku||_.bv!==Ku){if(y.bv===Ku&&_.bv===Ku&&y!=_||y.bv===qu&&_.bv===Ju||y.bv===Ju&&_.bv===qu){let t=y.next;for(;t!=_;)t.bvStart=void 0,t.bvEnd=void 0,t.bv=void 0,t.setInclusion(e),t=t.next}if(y.bv===Ku&&_.bv===Ku&&y!=_){let t,e=y.next;for(;e!=_;){if(e.bv!=Ku)if(void 0===t)t=e.bv;else if(e.bv!=t)throw ou.UNRESOLVED_BOUNDARY_CONFLICT;e=e.next}null!=t&&(y.bv=t,_.bv=t);continue}if(y.bv===qu&&_.bv===Ju||y.bv===Ju&&_.bv===qu){let o=y;for(;o!=_;){if(o.bvStart===y.bv&&o.bvEnd===_.bv){let[s,a]=o.shape.distanceTo(e);if(s<10*nu.DP_TOL){ju(o,a.ps,n);let s=n[n.length-1];if(s.is_vertex&np)s.edge_after=o,s.edge_before=o.prev,o.bvStart=Ku,o.bv=void 0,o.setInclusion(e);else if(s.is_vertex&op)s.edge_after=o.next,o.bvEnd=Ku,o.bv=void 0,o.setInclusion(e);else{let t=e.addVertex(s.pt,o);s.edge_before=t,s.edge_after=t.next,t.setInclusion(e),t.next.bvStart=Ku,t.next.bvEnd=void 0,t.next.bv=void 0,t.next.setInclusion(e)}let c=e.findEdgeByPoint(a.pe);ju(c,a.pe,i);let l=i[i.length-1];if(l.is_vertex&np)l.edge_after=c,l.edge_before=c.prev;else if(l.is_vertex&op)l.edge_after=c.next;else{let n=i.find(t=>t.edge_after===c),o=e.addVertex(l.pt,c);l.edge_before=o,l.edge_after=o.next,n&&(n.edge_after=o),o.bvStart=void 0,o.bvEnd=Ku,o.bv=void 0,o.setInclusion(t),o.next.bvStart=Ku,o.next.bvEnd=void 0,o.next.bv=void 0,o.next.setInclusion(t)}$u(r),d=!0;break}}o=o.next}if(d)break;throw ou.UNRESOLVED_BOUNDARY_CONFLICT}}else _.bv=y.bv;else y.bv=_.bv}return d}function gp(t,e,n,o){if(!n)return;let i,r,s,a;for(let c=0;c<n.length;c++){if(s=n[c],s.face!==i&&(r=c,i=s.face),i.isEmpty())continue;let l,d=c,h=Gu(n,c,i);l=d+h<n.length&&n[d+h].face===s.face?d+h:r,a=n[l];let u=l,p=Gu(n,u,i),m=s.edge_after,g=a.edge_before;if(m.bv===qu&&g.bv===qu&&1===e||m.bv===Ju&&g.bv===Ju&&2===e||(m.bv===Ju||g.bv===Ju)&&3===e&&!o||(m.bv===qu||g.bv===qu)&&3===e&&o||m.bv===Ku&&g.bv===Ku&&m.overlap&Qu&&o||m.bv===Ku&&g.bv===Ku&&m.overlap&tp){t.removeChain(i,m,g);for(let t=d;t<d+h;t++)n[t].edge_after=void 0;for(let t=u;t<u+p;t++)n[t].edge_before=void 0}c+=h-1}}function fp(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 yp(t,e,n){for(let o of e){if(void 0===o.edge_before||void 0===o.edge_after)continue;if(o.face)continue;if(o.edge_after.face||o.edge_before.face)continue;let i=o.edge_after,r=o.edge_before;try{iu.testInfiniteLoop(i)}catch(t){throw ou.CANNOT_COMPLETE_BOOLEAN_OPERATION}let s=t.addFace(i,r);for(let t of e)t.edge_before&&t.edge_after&&t.edge_before.face===s&&t.edge_after.face===s&&(t.face=s);for(let t of n)t.edge_before&&t.edge_after&&t.edge_before.face===s&&t.edge_after.face===s&&(t.face=s)}}function _p(t,e,n,o){for(let i of e){let e=i.first.bv;(1===n&&e===qu||3===n&&e===qu&&o||3===n&&e===Ju&&!o||2===n&&e===Ju)&&t.deleteFace(i)}}var bp=Object.freeze({__proto__:null,BOOLEAN_INTERSECT:2,BOOLEAN_SUBTRACT:3,BOOLEAN_UNION:1,calculateIntersections:cp,innerClip:sp,intersect:rp,outerClip:ap,removeNotRelevantChains:gp,removeOldFaces:fp,restoreFaces:yp,subtract:ip,unify:function(t,e){let[n,o]=dp(t,e,1,!0);return n}}),xp=RegExp("T.F..FFF.|T.F...F.."),vp=RegExp("T........|.T.......|...T.....|....T...."),Sp=RegExp("FT.......|F..T.....|F...T...."),Ip=RegExp("T.F..F..."),Cp=RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF..."),Pp=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 xp.test(this.toString())}intersect(){return vp.test(this.toString())}touch(){return Sp.test(this.toString())}inside(){return Ip.test(this.toString())}covered(){return Cp.test(this.toString())}};function Mp(t,e){let n,o=new nu.Ray(e),i=new nu.Line(o.pt,o.norm);const r=new nu.Box(o.box.xmin-nu.DP_TOL,o.box.ymin-nu.DP_TOL,o.box.xmax+nu.DP_TOL,o.box.ymax+nu.DP_TOL);if(t.box.not_intersect(r))return nu.OUTSIDE;let s=t.edges.search(r);if(0===s.length)return nu.OUTSIDE;for(let t of s)if(t.shape.contains(e))return nu.BOUNDARY;let a=[...t.faces],c=[];for(let t of s)for(let n of o.intersect(t.shape)){if(n.equalTo(e))return nu.BOUNDARY;c.push({pt:n,edge:t,face_index:a.indexOf(t.face)})}c.sort((t,e)=>eu(t.pt.x,e.pt.x)?-1:tu(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 l=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(;Kh(n.length);)n=n.prev;let o=n.shape.tangentInEnd(),r=e.pt.translate(o),s=e.edge.shape.tangentInStart(),a=e.pt.translate(s),d=r.leftTo(i),h=a.leftTo(i);(d&&!h||!d&&h)&&l++}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(;Kh(n.length);)n=n.next;let o=n.shape.tangentInStart(),r=e.pt.translate(o),s=e.edge.shape.tangentInEnd(),a=e.pt.translate(s),d=r.leftTo(i),h=a.leftTo(i);(d&&!h||!d&&h)&&l++}else if(e.edge.shape instanceof nu.Segment)l++;else{let t=e.edge.shape.box;Qh(e.pt.y,t.ymin)||Qh(e.pt.y,t.ymax)||l++}}return n=l%2==1?1:0,n}function Np(t,e){return Ep(t,e).intersect()}function wp(t,e){return Ep(t,e).inside()}function Tp(t,e){return Ep(t,e).covered()}function Rp(t,e){return Tp(e,t)}function Ep(t,e){return t instanceof nu.Line&&e instanceof nu.Line?function(t,e){let n=new Pp,o=cu(t,e);0===o.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=o,n.I2E=t.split(o),n.E2I=e.split(o));return n}(t,e):t instanceof nu.Line&&e instanceof nu.Circle?function(t,e){let n=new Pp,o=lu(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new Bu([t]),r=t.sortPoints(o);i.split(r);let s=i.toShapes();n.I2I=[s[1]],n.I2B=r,n.I2E=[s[0],s[2]],n.E2I=new nu.Polygon([e.toArc()]).cutWithLine(t)}return n}(t,e):t instanceof nu.Line&&e instanceof nu.Box?function(t,e){let n=new Pp,o=du(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new Bu([t]),r=t.sortPoints(o);i.split(r);let s=i.toShapes();e.toSegments().some(t=>t.contains(o[0])&&t.contains(o[1]))?(n.I2I=[],n.I2B=[s[1]],n.I2E=[s[0],s[2]],n.E2I=[e]):(n.I2I=[s[1]],n.I2B=r,n.I2E=[s[0],s[2]],n.E2I=new nu.Polygon(e.toSegments()).cutWithLine(t))}return n}(t,e):t instanceof nu.Line&&e instanceof nu.Polygon?function(t,e){let n=new Pp,o=Mu(t,e),i=new Bu([t]),r=o.length>0?o.slice():t.sortPoints(o);return i.split(r),[...i].forEach(t=>t.setInclusion(e)),n.I2I=[...i].filter(t=>t.bv===nu.INSIDE).map(t=>t.shape),n.I2B=[...i].slice(1).map(t=>t.bv===nu.BOUNDARY?t.shape:t.shape.start),n.I2E=[...i].filter(t=>t.bv===nu.OUTSIDE).map(t=>t.shape),n.E2I=e.cutWithLine(t),n}(t,e):(t instanceof nu.Segment||t instanceof nu.Arc)&&e instanceof nu.Polygon?Ap(t,e):(t instanceof nu.Segment||t instanceof nu.Arc)&&(e instanceof nu.Circle||e instanceof nu.Box)?Ap(t,new nu.Polygon(e)):t instanceof nu.Polygon&&e instanceof nu.Polygon?Op(t,e):(t instanceof nu.Circle||t instanceof nu.Box)&&(e instanceof nu.Circle||e instanceof nu.Box)?Op(new nu.Polygon(t),new nu.Polygon(e)):(t instanceof nu.Circle||t instanceof nu.Box)&&e instanceof nu.Polygon?Op(new nu.Polygon(t),e):t instanceof nu.Polygon&&(e instanceof nu.Circle||e instanceof nu.Box)?Op(t,new nu.Polygon(e)):void 0}function Ap(t,e){let n=new Pp,o=function(t,e){return t instanceof nu.Line?Mu(t,e):t instanceof nu.Segment?Cu(t,e):t instanceof nu.Arc?Pu(t,e):[]}(t,e),i=o.length>0?o.slice():t.sortPoints(o),r=new Bu([t]);r.split(i),[...r].forEach(t=>t.setInclusion(e)),n.I2I=[...r].filter(t=>t.bv===nu.INSIDE).map(t=>t.shape),n.I2B=[...r].slice(1).map(t=>t.bv===nu.BOUNDARY?t.shape:t.shape.start),n.I2E=[...r].filter(t=>t.bv===nu.OUTSIDE).map(t=>t.shape),n.B2I=[],n.B2B=[],n.B2E=[];for(let o of[t.start,t.end])switch(Mp(e,o)){case nu.INSIDE:n.B2I.push(o);break;case nu.BOUNDARY:n.B2B.push(o);break;case nu.OUTSIDE:n.B2E.push(o)}return n}function Op(t,e){let n=new Pp,[o,i]=cp(t,e),r=rp(t,e),s=ip(t,e),a=ip(e,t),[c,l]=sp(t,e),d=ap(t,e),h=ap(e,t);return n.I2I=r.isEmpty()?[]:[r],n.I2B=l,n.I2E=s.isEmpty()?[]:[s],n.B2I=c,n.B2B=o,n.B2E=d,n.E2I=a.isEmpty()?[]:[a],n.E2B=h,n}var kp=Object.freeze({__proto__:null,contain:function(t,e){return wp(e,t)},cover:Rp,covered:Tp,disjoint:function(t,e){return!Np(t,e)},equal:function(t,e){return Ep(t,e).equal()},inside:wp,intersect:Np,relate:Ep,touch:function(t,e){return Ep(t,e).touch()}}),Lp=class t{constructor(t=1,e=0,n=0,o=1,i=0,r=0){this.a=t,this.b=e,this.c=n,this.d=o,this.tx=i,this.ty=r}fromMatrix3x3(e){const[n,o,i]=e[0],[r,s,a]=e[1];return new t(n,r,o,s,i,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,o;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 ou.ILLEGAL_PARAMETERS;n=e[0],o=e[1]}else n=e[0].x,o=e[0].y;return this.multiply(new t(1,0,0,1,n,o))}rotate(e,n=0,o=0){let i=Math.cos(e),r=Math.sin(e);return this.translate(n,o).multiply(new t(i,r,-r,i,0,0)).translate(-n,-o)}scale(e,n){return this.multiply(new t(e,0,0,n,0,0))}equalTo(t){return!!nu.Utils.EQ(this.tx,t.tx)&&(!!nu.Utils.EQ(this.ty,t.ty)&&(!!nu.Utils.EQ(this.a,t.a)&&(!!nu.Utils.EQ(this.b,t.b)&&(!!nu.Utils.EQ(this.c,t.c)&&!!nu.Utils.EQ(this.d,t.d)))))}};nu.Matrix=Lp;nu.matrix=(...t)=>new nu.Matrix(...t);var Dp=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,o=this.clone();return o.low=e,o.high=n,o}output(){return[this.low,this.high]}comparable_less_than(t,e){return t<e}},zp=class t extends Dp{clone(){return new t(this.low,this.high)}},Fp=class{constructor(t,e,n=null,o=null,i=null,r=0){if(this.left=n,this.right=o,this.parent=i,this.color=r,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,o=n;t>o&&([t,o]=[o,t]),this.item.key=new zp(t,o)}}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(),o=t.requireKey();return n.comparable_less_than(e,o.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(),o=t.requireKey();return n.comparable_less_than(o.high,e)}},Bp=class t{constructor(){this.root=null,this.nil_node=new Fp}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 o of e.item.values)t.push({key:n,value:o})}),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 Fp(t));if(n)return n.item.values.push(e),n;const o=new Fp(t,e,this.nil_node,this.nil_node,null,1);return this.tree_insert(o),this.recalc_max(o),o}exist(t,e=t){const n=this.tree_search(this.root,new Fp(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 Fp(t));if(!n)return;if(arguments.length<2)return this.tree_delete(n),n;const o=n.item.values.findIndex(t=>t&&t.equal_to?t.equal_to(e):t===e);return o>=0?(n.item.values.splice(o,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 Fp(t),o=[];this.tree_search_interval(this.root,n,o);const i=[];for(const t of o)for(const n of t.item.values)i.push(e(n,t.item.key));return i}intersect_any(t){const e=new Fp(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 o of t.item.values)n.insert(t.item.key,e(o,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 Fp(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,o=t;for(;o&&o!==this.nil_node;)o.less_than(e)?o.intersect(e)?(n=o,o=o.left):o=o.right:(n&&!o.less_than(n)||(n=o),o=o.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,o;if(t.right!==this.nil_node)e=this.local_minimum(t.right);else{for(n=t,o=t.parent;null!=o&&o.right===n;)n=o,o=o.parent;e=o}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,o=0;if(0===t.color&&e++,n=t.left!==this.nil_node?this.testBlackHeightProperty(t.left):1,o=t.right!==this.nil_node?this.testBlackHeightProperty(t.right):1,n!==o)throw new Error("Red-black height property violated");return e+=n,e}},jp=class extends Set{constructor(t){super(t),this.index=new Bp,this.forEach(t=>this.index.insert(t))}add(t){let e=this.size;const{key:n,value:o}=t,i=n||t.box,r=o||t;return super.add(r),this.size>e&&this.index.insert(i,r),this}delete(t){const{key:e,value:n}=t,o=e||t.box,i=n||t;let r=super.delete(i);return r&&this.index.remove(o,i),r}clear(){super.clear(),this.index=new Bp}search(t){return this.index.search(t)}hit(t){let e=new nu.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(),"")}};nu.PlanarSet=jp;var $p=class{get name(){throw ou.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw ou.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw ou.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform((new Lp).translate(...t))}rotate(t,e=new nu.Point){return this.transform((new Lp).rotate(t,e.x,e.y))}scale(t,e){return this.transform((new Lp).scale(t,e))}transform(...t){throw ou.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw ou.CANNOT_INVOKE_ABSTRACT_METHOD}};nu.Point=class t extends $p{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 ou.ILLEGAL_PARAMETERS}}get box(){return new nu.Box(this.x,this.y,this.x,this.y)}clone(){return new nu.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return nu.Utils.EQ(this.x,t.x)&&nu.Utils.EQ(this.y,t.y)}lessThan(t){return!!nu.Utils.LT(this.y,t.y)||!(!nu.Utils.EQ(this.y,t.y)||!nu.Utils.LT(this.x,t.x))}transform(t){return new nu.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let e=new nu.Vector(this,t.pt);if(nu.Utils.EQ_0(e.cross(t.norm)))return t.pt.clone();let n=e.dot(t.norm),o=t.norm.multiply(n);return this.translate(o)}leftTo(t){let e=new nu.Vector(t.pt,this);return nu.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 nu.Segment(this,e)]}return e instanceof nu.Line?nu.Distance.point2line(this,e):e instanceof nu.Circle?nu.Distance.point2circle(this,e):e instanceof nu.Segment?nu.Distance.point2segment(this,e):e instanceof nu.Arc?nu.Distance.point2arc(this,e):e instanceof nu.Polygon?nu.Distance.point2polygon(this,e):e instanceof nu.PlanarSet?nu.Distance.shape2planarSet(this,e):e instanceof nu.Multiline?nu.Distance.shape2multiline(this,e):void 0}on(t){if(t instanceof nu.Point)return this.equalTo(t);if(t.contains&&t.contains instanceof Function)return t.contains(this);throw nu.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 ${au({fill:"red",...t})} />`}};nu.point=(...t)=>new nu.Point(...t);nu.Vector=class extends $p{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 nu.Point&&n instanceof nu.Point)return this.x=n.x-e.x,void(this.y=n.y-e.y)}throw ou.ILLEGAL_PARAMETERS}}clone(){return new nu.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 nu.Utils.EQ_0(this.length)}equalTo(t){return nu.Utils.EQ(this.x,t.x)&&nu.Utils.EQ(this.y,t.y)}multiply(t){return new nu.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 ou.ZERO_DIVISION;return new nu.Vector(this.x/this.length,this.y/this.length)}rotate(t,e=new nu.Point){if(0===e.x&&0===e.y)return this.transform((new Lp).rotate(t));throw ou.OPERATION_IS_NOT_SUPPORTED}transform(t){return new nu.Vector(t.transform([this.x,this.y]))}rotate90CCW(){return new nu.Vector(-this.y,this.x)}rotate90CW(){return new nu.Vector(this.y,-this.x)}invert(){return new nu.Vector(-this.x,-this.y)}add(t){return new nu.Vector(this.x+t.x,this.y+t.y)}subtract(t){return new nu.Vector(this.x-t.x,this.y-t.y)}angleTo(t){let e=this.normalize(),n=t.normalize(),o=Math.atan2(e.cross(n),e.dot(n));return o<0&&(o+=2*Math.PI),o}projectionOn(t){let e=t.normalize(),n=this.dot(e);return e.multiply(n)}get name(){return"vector"}};var Yp=(...t)=>new nu.Vector(...t);nu.vector=Yp;nu.Segment=class t extends $p{constructor(...t){if(super(),this.ps=new nu.Point,this.pe=new nu.Point,0!==t.length){if(1===t.length&&t[0]instanceof Array&&4===t[0].length){let e=t[0];return this.ps=new nu.Point(e[0],e[1]),void(this.pe=new nu.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 nu.Point(e.x,e.y),void(this.pe=new nu.Point(n.x,n.y))}if(!(1===t.length&&t[0]instanceof nu.Point)){if(2===t.length&&t[0]instanceof nu.Point&&t[1]instanceof nu.Point)return this.ps=t[0].clone(),void(this.pe=t[1].clone());if(4===t.length)return this.ps=new nu.Point(t[0],t[1]),void(this.pe=new nu.Point(t[2],t[3]));throw ou.ILLEGAL_PARAMETERS}this.ps=t[0].clone()}}clone(){return new nu.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 nu.Vector(this.start,this.end).slope}get box(){return new nu.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 nu.Utils.EQ_0(this.distanceToPoint(t))}intersect(t){return t instanceof nu.Point?this.contains(t)?[t]:[]:t instanceof nu.Line?uu(this,t):t instanceof nu.Ray?Au(t,this):t instanceof nu.Segment?pu(this,t):t instanceof nu.Circle?gu(this,t):t instanceof nu.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=pu(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof nu.Arc?fu(this,t):t instanceof nu.Polygon?Cu(this,t):t instanceof nu.Multiline?Fu(this,t):void 0}distanceTo(t){if(t instanceof nu.Point){let[e,n]=nu.Distance.point2segment(t,this);return n=n.reverse(),[e,n]}if(t instanceof nu.Circle){let[e,n]=nu.Distance.segment2circle(this,t);return[e,n]}if(t instanceof nu.Line){let[e,n]=nu.Distance.segment2line(this,t);return[e,n]}if(t instanceof nu.Segment){let[e,n]=nu.Distance.segment2segment(this,t);return[e,n]}if(t instanceof nu.Arc){let[e,n]=nu.Distance.segment2arc(this,t);return[e,n]}if(t instanceof nu.Polygon){let[e,n]=nu.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof nu.PlanarSet){let[e,n]=nu.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof nu.Multiline)return nu.Distance.shape2multiline(this,t)}tangentInStart(){return new nu.Vector(this.start,this.end).normalize()}tangentInEnd(){return new nu.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 nu.Segment(this.start,t),new nu.Segment(t,this.end)]}middle(){return new nu.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 nu.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]=nu.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 nu.Matrix){return new t(this.ps.transform(e),this.pe.transform(e))}isZeroLength(){return this.ps.equalTo(this.pe)}sortPoints(t){return new nu.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}" ${au(t)} />`}};nu.segment=(...t)=>new nu.Segment(...t);var{vector:Xp}=nu;nu.Line=class t extends $p{constructor(...e){if(super(),this.pt=new nu.Point,this.norm=new nu.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 nu.Point(t),void(this.norm=new nu.Vector(n))}if(2===e.length){let n=e[0],o=e[1];if(n instanceof nu.Point&&o instanceof nu.Point)return this.pt=n,this.norm=t.points2norm(n,o),void(this.norm.dot(Xp(this.pt.x,this.pt.y))>=0&&this.norm.invert());if(n instanceof nu.Point&&o instanceof nu.Vector){if(nu.Utils.EQ_0(o.x)&&nu.Utils.EQ_0(o.y))throw ou.ILLEGAL_PARAMETERS;return this.pt=n.clone(),this.norm=o.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(Xp(this.pt.x,this.pt.y))>=0&&this.norm.invert())}if(n instanceof nu.Vector&&o instanceof nu.Point){if(nu.Utils.EQ_0(n.x)&&nu.Utils.EQ_0(n.y))throw ou.ILLEGAL_PARAMETERS;return this.pt=o.clone(),this.norm=n.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(Xp(this.pt.x,this.pt.y))>=0&&this.norm.invert())}}throw ou.ILLEGAL_PARAMETERS}}clone(){return new nu.Line(this.pt,this.norm)}get start(){}get end(){}get length(){return Number.POSITIVE_INFINITY}get box(){return new nu.Box(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)}get middle(){}get slope(){return new nu.Vector(this.norm.y,-this.norm.x).slope}get standard(){return[this.norm.x,this.norm.y,this.norm.dot(Xp(this.pt.x,this.pt.y))]}parallelTo(t){return nu.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 nu.Vector(this.pt,t);return nu.Utils.EQ_0(this.norm.dot(e))}coord(t){return Xp(t.x,t.y).cross(this.norm)}intersect(t){return t instanceof nu.Point?this.contains(t)?[t]:[]:t instanceof nu.Line?cu(this,t):t instanceof nu.Ray?Lu(t,this):t instanceof nu.Circle?lu(this,t):t instanceof nu.Box?du(this,t):t instanceof nu.Segment?uu(t,this):t instanceof nu.Arc?hu(this,t):t instanceof nu.Polygon?Mu(this,t):t instanceof nu.Multiline?Fu(this,t):void 0}distanceTo(t){if(t instanceof nu.Point){let[e,n]=nu.Distance.point2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof nu.Circle){let[e,n]=nu.Distance.circle2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof nu.Segment){let[e,n]=nu.Distance.segment2line(t,this);return[e,n.reverse()]}if(t instanceof nu.Arc){let[e,n]=nu.Distance.arc2line(t,this);return[e,n.reverse()]}if(t instanceof nu.Polygon){let[e,n]=nu.Distance.shape2polygon(this,t);return[e,n]}}split(t){if(t instanceof nu.Point)return[new nu.Ray(t,this.norm),new nu.Ray(t,this.norm)];{let e=new nu.Multiline([this]),n=this.sortPoints(t);return e.split(n),e.toShapes()}}rotate(t,e=new nu.Point){return new nu.Line(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new nu.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=du(this,t);if(0===n.length)return"";let o=n[0],i=2===n.length?n[1]:n.find(t=>!t.equalTo(o));return void 0===i&&(i=o),new nu.Segment(o,i).svg(e)}static points2norm(t,e){if(t.equalTo(e))throw ou.ILLEGAL_PARAMETERS;return new nu.Vector(t,e).normalize().rotate90CCW()}};nu.line=(...t)=>new nu.Line(...t);nu.Circle=class extends $p{constructor(...t){if(super(),this.pc=new nu.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 nu.Point(e),this.r=n}else{let[e,n]=[...t];e&&e instanceof nu.Point&&(this.pc=e.clone()),void 0!==n&&(this.r=n)}}clone(){return new nu.Circle(this.pc.clone(),this.r)}get center(){return this.pc}get box(){return new nu.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 nu.Point?nu.Utils.LE(t.distanceTo(this.center)[0],this.r):t instanceof nu.Segment?nu.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&nu.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof nu.Arc?0===this.intersect(t).length&&nu.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&nu.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof nu.Circle?0===this.intersect(t).length&&nu.Utils.LE(t.r,this.r)&&nu.Utils.LE(t.center.distanceTo(this.center)[0],this.r):void 0}toArc(t=!0){return new nu.Arc(this.center,this.r,Math.PI,-Math.PI,t)}scale(t,e){if(t!==e)throw ou.OPERATION_IS_NOT_SUPPORTED;if(0!==this.pc.x||0!==this.pc.y)throw ou.OPERATION_IS_NOT_SUPPORTED;return new nu.Circle(this.pc,this.r*t)}transform(t=new nu.Matrix){return new nu.Circle(this.pc.transform(t),this.r)}intersect(t){return t instanceof nu.Point?this.contains(t)?[t]:[]:t instanceof nu.Line?lu(t,this):t instanceof nu.Ray?ku(t,this):t instanceof nu.Segment?gu(t,this):t instanceof nu.Circle?yu(t,this):t instanceof nu.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=gu(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof nu.Arc?bu(t,this):t instanceof nu.Polygon?Nu(this,t):t instanceof nu.Multiline?Fu(this,t):void 0}distanceTo(t){if(t instanceof nu.Point){let[e,n]=nu.Distance.point2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof nu.Circle){let[e,n]=nu.Distance.circle2circle(this,t);return[e,n]}if(t instanceof nu.Line){let[e,n]=nu.Distance.circle2line(this,t);return[e,n]}if(t instanceof nu.Segment){let[e,n]=nu.Distance.segment2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof nu.Arc){let[e,n]=nu.Distance.arc2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof nu.Polygon){let[e,n]=nu.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof nu.PlanarSet){let[e,n]=nu.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof nu.Multiline){let[e,n]=nu.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 ${au({fill:"none",...t})} />`}};nu.circle=(...t)=>new nu.Circle(...t);nu.Arc=class extends $p{constructor(...t){if(super(),this.pc=new nu.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:o,endAngle:i,counterClockwise:r}=t[0];this.pc=new nu.Point(e.x,e.y),this.r=n,this.startAngle=o,this.endAngle=i,this.counterClockwise=r}else{let[e,n,o,i,r]=[...t];e&&e instanceof nu.Point&&(this.pc=e.clone()),void 0!==n&&(this.r=n),void 0!==o&&(this.startAngle=o),void 0!==i&&(this.endAngle=i),void 0!==r&&(this.counterClockwise=r)}}clone(){return new nu.Arc(this.pc.clone(),this.r,this.startAngle,this.endAngle,this.counterClockwise)}get sweep(){let t=this.startAngle,e=this.endAngle;if(nu.Utils.EQ(Math.abs(t-e),nu.PIx2))return nu.PIx2;Math.abs(t)>nu.PIx2&&(t-=Math.trunc(t/nu.PIx2)*nu.PIx2),t<0&&(t+=nu.PIx2),Math.abs(e)>nu.PIx2&&(e-=Math.trunc(e/nu.PIx2)*nu.PIx2),e<0&&(e+=nu.PIx2);let n=this.counterClockwise?e-t:t-e;return n<0&&(n+=nu.PIx2),n}get start(){return new nu.Point(this.pc.x+this.r,this.pc.y).rotate(this.startAngle,this.pc)}get end(){return new nu.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 nu.Box);return t=t.merge(this.end.box),t}contains(t){if(!nu.Utils.EQ(this.pc.distanceTo(t)[0],this.r))return!1;if(t.equalTo(this.start))return!0;let e=new nu.Vector(this.pc,t).slope,n=new nu.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise);return nu.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 nu.Vector(this.pc,t).slope;return[new nu.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise),new nu.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 nu.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 nu.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 nu.Point?this.contains(t)?[t]:[]:t instanceof nu.Line?hu(t,this):t instanceof nu.Ray?Ou(t,this):t instanceof nu.Circle?bu(this,t):t instanceof nu.Segment?fu(t,this):t instanceof nu.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=fu(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof nu.Arc?_u(this,t):t instanceof nu.Polygon?Pu(this,t):t instanceof nu.Multiline?Fu(this,t):void 0}distanceTo(t){if(t instanceof nu.Point){let[e,n]=nu.Distance.point2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof nu.Circle){let[e,n]=nu.Distance.arc2circle(this,t);return[e,n]}if(t instanceof nu.Line){let[e,n]=nu.Distance.arc2line(this,t);return[e,n]}if(t instanceof nu.Segment){let[e,n]=nu.Distance.segment2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof nu.Arc){let[e,n]=nu.Distance.arc2arc(this,t);return[e,n]}if(t instanceof nu.Polygon){let[e,n]=nu.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof nu.PlanarSet){let[e,n]=nu.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof nu.Multiline)return nu.Distance.shape2multiline(this,t)}breakToFunctional(){let t=[],e=[0,Math.PI/2,Math.PI,3*Math.PI/2],n=this.startAngle,o=this.endAngle;nu.Utils.EQ(Math.abs(n-o),nu.PIx2)&&(o=n),Math.abs(n)>nu.PIx2&&(n-=Math.trunc(n/nu.PIx2)*nu.PIx2),n<0&&(n+=nu.PIx2),Math.abs(o)>nu.PIx2&&(o-=Math.trunc(o/nu.PIx2)*nu.PIx2),o<0&&(o+=nu.PIx2);let i,r,s,a=n;this.counterClockwise?(r=Math.ceil(n/(Math.PI/2))%4,s=1):(r=Math.floor(n/(Math.PI/2))%4,s=-1);for(let o=0,c=r;o<4;o++,c=(c+s+4)%4){if(i=e[c],i===a)continue;let o=this.counterClockwise?i-n:n-i;if(o<0&&(o+=nu.PIx2),o>this.sweep)break;t.push(new nu.Arc(this.pc,this.r,a,i,this.counterClockwise)),a=i}return 0===t.length?(t.push(this),t):(i=o,a!==i&&t.push(new nu.Arc(this.pc,this.r,a,i,this.counterClockwise)),t)}tangentInStart(){let t=new nu.Vector(this.pc,this.start),e=this.counterClockwise?Math.PI/2:-Math.PI/2;return t.rotate(e).normalize()}tangentInEnd(){let t=new nu.Vector(this.pc,this.end),e=this.counterClockwise?-Math.PI/2:Math.PI/2;return t.rotate(e).normalize()}reverse(){return new nu.Arc(this.pc,this.r,this.endAngle,this.startAngle,!this.counterClockwise)}transform(t=new nu.Matrix){let e=this.start.transform(t),n=this.end.transform(t),o=this.pc.transform(t),i=this.counterClockwise;return t.a*t.d<0&&(i=!i),nu.Arc.arcSE(o,e,n,i)}static arcSE(t,e,n,o){let{vector:i}=nu,r=i(t,e).slope,s=i(t,n).slope;nu.Utils.EQ(r,s)&&(s+=2*Math.PI,o=!0);let a=i(t,e).length;return new nu.Arc(t,a,r,s,o)}definiteIntegral(t=0){return this.breakToFunctional().reduce((e,n)=>e+n.circularSegmentDefiniteIntegral(t),0)}circularSegmentDefiniteIntegral(t){let e=new nu.Segment(this.start,this.end).definiteIntegral(t),n=nu.Utils.EQ(this.sweep,nu.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}=nu;return t.slice().sort((t,n)=>{let o=e(this.pc,t).slope,i=e(this.pc,n).slope;return o<i?-1:o>i?1:0})}get name(){return"arc"}svg(t={}){let e=this.sweep<=Math.PI?"0":"1",n=this.counterClockwise?"1":"0";if(nu.Utils.EQ(this.sweep,2*Math.PI)){return new nu.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 ${au({fill:"none",...t})} />`}};nu.arc=(...t)=>new nu.Arc(...t);nu.Box=class t extends $p{constructor(t=void 0,e=void 0,n=void 0,o=void 0){super(),this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}clone(){return new t(this.xmin,this.ymin,this.xmax,this.ymax)}get low(){return new nu.Point(this.xmin,this.ymin)}get high(){return new nu.Point(this.xmax,this.ymax)}get max(){return this.clone()}get center(){return new nu.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,o){this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}extend(e){return e<=0?this.clone():new t(this.xmin-e,this.ymin-e,this.xmax+e,this.ymax+e)}toPoints(){return[new nu.Point(this.xmin,this.ymin),new nu.Point(this.xmax,this.ymin),new nu.Point(this.xmax,this.ymax),new nu.Point(this.xmin,this.ymax)]}toSegments(){let t=this.toPoints();return[new nu.Segment(t[0],t[1]),new nu.Segment(t[1],t[2]),new nu.Segment(t[2],t[3]),new nu.Segment(t[3],t[0])]}rotate(t,e=new nu.Point){throw ou.OPERATION_IS_NOT_SUPPORTED}transform(e=new nu.Matrix){return this.toPoints().map(t=>t.transform(e)).reduce((t,e)=>t.merge(e.box),new t)}contains(t){return t instanceof nu.Point?t.x>=this.xmin&&t.x<=this.xmax&&t.y>=this.ymin&&t.y<=this.ymax:t instanceof nu.Segment?t.vertices.every(t=>this.contains(t)):t instanceof nu.Box?t.toSegments().every(t=>this.contains(t)):t instanceof nu.Circle?this.contains(t.box):t instanceof nu.Arc?t.vertices.every(t=>this.contains(t))&&this.toSegments().every(e=>0===fu(e,t).length):!(t instanceof nu.Line||t instanceof nu.Ray)&&(t instanceof nu.Multiline?t.toShapes().every(t=>this.contains(t)):t instanceof nu.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 ${au({fill:"none",...t})} />`}};nu.box=(...t)=>new nu.Box(...t);nu.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 nu.Segment}get isArc(){return this.shape instanceof nu.Arc}get isLine(){return this.shape instanceof nu.Line}get isRay(){return this.shape instanceof nu.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 nu.Line||this.shape instanceof nu.Ray)return this.bv=nu.OUTSIDE,this.bv;if(void 0===this.bvStart&&(this.bvStart=Mp(t,this.start)),void 0===this.bvEnd&&(this.bvEnd=Mp(t,this.end)),this.bvStart===nu.OUTSIDE||this.bvEnd==nu.OUTSIDE)this.bv=nu.OUTSIDE;else if(this.bvStart===nu.INSIDE||this.bvEnd==nu.INSIDE)this.bv=nu.INSIDE;else{let e=Mp(t,this.middle());this.bv=e}return this.bv}setOverlap(t){let e,n=this.shape,o=t.shape;n instanceof nu.Segment&&o instanceof nu.Segment?n.start.equalTo(o.start)&&n.end.equalTo(o.end)?e=nu.OVERLAP_SAME:n.start.equalTo(o.end)&&n.end.equalTo(o.start)&&(e=nu.OVERLAP_OPPOSITE):(n instanceof nu.Arc&&o instanceof nu.Arc||n instanceof nu.Segment&&o instanceof nu.Arc||n instanceof nu.Arc&&o instanceof nu.Segment)&&(n.start.equalTo(o.start)&&n.end.equalTo(o.end)&&n.middle().equalTo(o.middle())?e=nu.OVERLAP_SAME:n.start.equalTo(o.end)&&n.end.equalTo(o.start)&&n.middle().equalTo(o.middle())&&(e=nu.OVERLAP_OPPOSITE)),void 0===this.overlap&&(this.overlap=e),void 0===t.overlap&&(t.overlap=e)}svg(){if(this.shape instanceof nu.Segment)return` L${this.shape.end.x},${this.shape.end.y}`;if(this.shape instanceof nu.Arc){let t,e=this.shape,n=e.counterClockwise?"1":"0";if(nu.Utils.EQ(e.sweep,2*Math.PI)){let o=e.counterClockwise?1:-1,i=new nu.Arc(e.pc,e.r,e.startAngle,e.startAngle+o*Math.PI,e.counterClockwise),r=new nu.Arc(e.pc,e.r,e.startAngle+o*Math.PI,e.endAngle,e.counterClockwise);return t="0",` A${i.r},${i.r} 0 ${t},${n} ${i.end.x},${i.end.y}\n A${r.r},${r.r} 0 ${t},${n} ${r.end.x},${r.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 Vp=class extends iu{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}};nu.Face=class t extends Vp{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 o=n[0];if(0===o.length)return;if(o.every(t=>t instanceof nu.Point)){let n=t.points2segments(o);this.shapes2face(e.edges,n)}else if(o.every(t=>t instanceof Array&&2===t.length)){let n=o.map(t=>new nu.Point(t[0],t[1])),i=t.points2segments(n);this.shapes2face(e.edges,i)}else if(o.every(t=>t instanceof nu.Segment||t instanceof nu.Arc))this.shapes2face(e.edges,o);else if(o.every(t=>"segment"===t.name||"arc"===t.name)){let t=[];for(let e of o){let n;n="segment"===e.name?new nu.Segment(e):new nu.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 nu.Circle)this.shapes2face(e.edges,[n[0].toArc(Wh)]);else if(n[0]instanceof nu.Box){let t=n[0];this.shapes2face(e.edges,[new nu.Segment(new nu.Point(t.xmin,t.ymin),new nu.Point(t.xmax,t.ymin)),new nu.Segment(new nu.Point(t.xmax,t.ymin),new nu.Point(t.xmax,t.ymax)),new nu.Segment(new nu.Point(t.xmax,t.ymax),new nu.Point(t.xmin,t.ymax)),new nu.Segment(new nu.Point(t.xmin,t.ymax),new nu.Point(t.xmin,t.ymin))])}2===n.length&&n[0]instanceof nu.Edge&&n[1]instanceof nu.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 nu.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 nu.Segment(t[n],t[(n+1)%t.length]));return e}shapes2face(t,e){for(let n of e){let e=new nu.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();nu.Utils.EQ_0(t)?this._orientation=Hh.NOT_ORIENTABLE:nu.Utils.LT(t,0)?this._orientation=Hh.CCW:this._orientation=Hh.CW}return this._orientation}isSimple(e){return 0===t.getSelfIntersections(this,e,!0).length}static getSelfIntersections(t,e,n=!1){let o=[];for(let i of t){let r=e.search(i.box);for(let e of r){if(i===e)continue;if(e.face!==t)continue;if(i.shape instanceof nu.Segment&&e.shape instanceof nu.Segment&&(i.next===e||i.prev===e))continue;let r=i.shape.intersect(e.shape);for(let t of r)if((!t.equalTo(i.start)||!t.equalTo(e.end)||e!==i.prev)&&(!t.equalTo(i.end)||!t.equalTo(e.start)||e!==i.next)&&(o.push(t),n))break;if(o.length>0&&n)break}if(o.length>0&&n)break}return o}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 nu.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}};nu.Ray=class t extends $p{constructor(...t){if(super(),this.pt=new nu.Point,this.norm=new nu.Vector(0,1),0!==t.length&&(t.length>=1&&t[0]instanceof nu.Point&&(this.pt=t[0].clone()),1!==t.length)){if(!(2===t.length&&t[1]instanceof nu.Vector))throw ou.ILLEGAL_PARAMETERS;this.norm=t[1].clone()}}clone(){return new t(this.pt,this.norm)}get slope(){return new nu.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new nu.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 nu.Vector(this.pt,t);return nu.Utils.EQ_0(this.norm.dot(e))&&nu.Utils.GE(e.cross(this.norm),0)}coord(t){return Yp(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new nu.Segment(this.pt,t),new nu.Ray(t,this.norm)]:[]}intersect(t){return t instanceof nu.Point?this.contains(t)?[t]:[]:t instanceof nu.Segment?Au(this,t):t instanceof nu.Arc?Ou(this,t):t instanceof nu.Line?Lu(this,t):t instanceof nu.Ray?(n=t,cu(Eu(e=this),Eu(n)).filter(t=>e.contains(t)).filter(t=>n.contains(t))):t instanceof nu.Circle?ku(this,t):t instanceof nu.Box?function(t,e){return du(Eu(t),e).filter(e=>t.contains(e))}(this,t):t instanceof nu.Polygon?Du(this,t):t instanceof nu.Multiline?Fu(this,t):void 0;var e,n}rotate(t,e=new nu.Point){return new nu.Ray(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new nu.Ray(this.pt.transform(t),this.norm.clone())}get name(){return"ray"}svg(t,e={}){let n=du(new nu.Line(this.pt,this.norm),t);return n=n.filter(t=>this.contains(t)),0===n.length||2===n.length?"":new nu.Segment(this.pt,n[0]).svg(e)}};nu.ray=(...t)=>new nu.Ray(...t);nu.Polygon=class t{constructor(){this.faces=new nu.PlanarSet,this.edges=new nu.PlanarSet;let t=[...arguments];if(1===t.length&&(t[0]instanceof Array&&t[0].length>0||t[0]instanceof nu.Circle||t[0]instanceof nu.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 nu.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 nu.Face(this,e));else this.faces.add(new nu.Face(this,t));else this.faces.add(new nu.Face(this,e))}}get box(){return[...this.faces].reduce((t,e)=>t.merge(e.box),new nu.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 nu.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 o=e;o!==n.next;o=o.next)if(t.remove(o),this.edges.delete(o),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 o=new nu.Edge(n[0]),i=e.prev;return e.face.insert(o,i),this.edges.delete(e),this.edges.add(o),e.shape=n[1],this.edges.add(e),o}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 o,i,r={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let t of n.edges)for(let n of e.edges){let e=wu(t,n);for(let o of e)ju(t,o,r.int_points1),ju(n,o,r.int_points2)}if(0===r.int_points1.length)return e;r.int_points1_sorted=Yu(r.int_points1),r.int_points2_sorted=Yu(r.int_points2),Uu(n,r.int_points1_sorted),Uu(e,r.int_points2_sorted),Vu(r),r.int_points1_sorted=Yu(r.int_points1),r.int_points2_sorted=Yu(r.int_points2),Wu(r.int_points1),Hu(r.int_points1,e);for(let t of r.int_points1_sorted)t.edge_before&&t.edge_after&&t.edge_before.bv===t.edge_after.bv&&(r.int_points2[t.id]=-1,t.id=-1);if(r.int_points1=r.int_points1.filter(t=>t.id>=0),r.int_points2=r.int_points2.filter(t=>t.id>=0),r.int_points1.forEach((t,e)=>{t.id=e}),r.int_points2.forEach((t,e)=>{t.id=e}),0===r.int_points1.length)return e;r.int_points1_sorted=Yu(r.int_points1),r.int_points2_sorted=Yu(r.int_points2);for(let t=1;t<r.int_points1_sorted.length;t++)if(i=r.int_points1_sorted[t],o=r.int_points1_sorted[t-1],i.edge_before&&1===i.edge_before.bv){let t=o.edge_after,s=i.edge_before,a=n.getChain(t,s);Zu(r.int_points2[o.id],r.int_points2[i.id],a),a.forEach(t=>e.edges.add(t)),a=a.reverse().map(t=>new nu.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];Zu(r.int_points2[i.id],r.int_points2[o.id],a),a.forEach(t=>e.edges.add(t))}return e.recreateFaces(),e}cutWithLine(t){let e=new Bu([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 o of t){let t=[...o.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()?Hh.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 nu.Point){let e=Mp(this,t);return 1===e||2===e}return Rp(this,t)}distanceTo(t){if(t instanceof nu.Point){let[e,n]=nu.Distance.point2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof nu.Circle||t instanceof nu.Line||t instanceof nu.Segment||t instanceof nu.Arc){let[e,n]=nu.Distance.shape2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof nu.Polygon){let e,n,o=[Number.POSITIVE_INFINITY,new nu.Segment];for(let i of this.edges){let r=o[0];[e,n]=nu.Distance.shape2planarSet(i.shape,t.edges,r),nu.Utils.LT(e,r)&&(o=[e,n])}return o}}intersect(t){return t instanceof nu.Point?this.contains(t)?[t]:[]:t instanceof nu.Line?Mu(t,this):t instanceof nu.Ray?Du(t,this):t instanceof nu.Circle?Nu(t,this):t instanceof nu.Segment?Cu(t,this):t instanceof nu.Arc?Pu(t,this):t instanceof nu.Polygon?function(t,e){let n=[];if(t.isEmpty()||e.isEmpty())return n;if(t.box.not_intersect(e.box))return n;for(let o of t.edges)n=[...n,...Tu(o,e)];return n}(t,this):t instanceof nu.Multiline?function(t,e){let n=[];if(e.isEmpty()||0===t.size)return n;for(let o of t)n=[...n,...Tu(o,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 nu.Point){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=>t.rotate(e,n)));return o}scale(e,n){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=>t.scale(e,n)));return o}transform(e=new nu.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 ${au({fillRule:"evenodd",fill:"lightcyan",...t})} d="`;for(let t of this.faces)e+=`\n${t.svg()}`;return e+='" >\n</path>',e}};nu.polygon=(...t)=>new nu.Polygon(...t);var{Circle:Wp,Line:Hp,Point:Gp,Vector:Up,Utils:Zp}=nu;nu.Inversion=class t{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,e){const n=new Up(t.pc,e),o=t.r*t.r,i=n.dot(n);return Zp.EQ_0(i)?new Gp(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY):t.pc.translate(n.multiply(o/i))}static inverseCircle(t,e){const n=t.pc.distanceTo(e.pc)[0];if(Zp.EQ(n,e.r)){let n=t.r*t.r/(2*e.r),o=new Up(t.pc,e.pc);o=o.normalize();let i=t.pc.translate(o.multiply(n));return new Hp(i,o)}{let n=new Up(t.pc,e.pc),o=t.r*t.r/(n.dot(n)-e.r*e.r),i=t.pc.translate(n.multiply(o)),r=Math.abs(o)*e.r;return new Wp(i,r)}}static inverseLine(t,e){const[n,o]=t.pc.distanceTo(e);if(Zp.EQ_0(n))return e.clone();{let e=t.r*t.r/(2*n),i=new Up(t.pc,o.end);return i=i.multiply(e/n),new Wp(t.pc.translate(i),e)}}inverse(e){return e instanceof Gp?t.inversePoint(this.circle,e):e instanceof Wp?t.inverseCircle(this.circle,e):e instanceof Hp?t.inverseLine(this.circle,e):void 0}};nu.inversion=t=>new nu.Inversion(t);nu.Distance=class t{static point2point(t,e){return t.distanceTo(e)}static point2line(t,e){let n=t.projectionOn(e);return[new nu.Vector(t,n).length,new nu.Segment(t,n)]}static point2circle(t,e){let[n,o]=t.distanceTo(e.center);if(nu.Utils.EQ_0(n))return[e.r,new nu.Segment(t,e.toArc().start)];{let o=Math.abs(n-e.r),i=new nu.Vector(e.pc,t).normalize().multiply(e.r),r=e.pc.translate(i);return[o,new nu.Segment(t,r)]}}static point2segment(e,n){if(n.start.equalTo(n.end))return t.point2point(e,n.start);let o,i,r=new nu.Vector(n.start,n.end),s=new nu.Vector(n.start,e),a=new nu.Vector(n.end,e),c=r.dot(s),l=-r.dot(a);if(nu.Utils.GE(c,0)&&nu.Utils.GE(l,0)){let t=n.tangentInStart();return o=Math.abs(t.cross(s)),i=n.start.translate(t.multiply(t.dot(s))),[o,new nu.Segment(e,i)]}return c<0?e.distanceTo(n.start):e.distanceTo(n.end)}static point2arc(e,n){let o,i,r=new nu.Circle(n.pc,n.r),s=[];return[o,i]=t.point2circle(e,r),i.end.on(n)&&s.push(t.point2circle(e,r)),s.push(t.point2point(e,n.start)),s.push(t.point2point(e,n.end)),t.sort(s),s[0]}static point2edge(e,n){return n.shape instanceof nu.Segment?t.point2segment(e,n.shape):t.point2arc(e,n.shape)}static segment2line(e,n){let o=e.intersect(n);if(o.length>0)return[0,new nu.Segment(o[0],o[0])];let i=[];return i.push(t.point2line(e.start,n)),i.push(t.point2line(e.end,n)),t.sort(i),i[0]}static segment2segment(e,n){let o=pu(e,n);if(o.length>0)return[0,new nu.Segment(o[0],o[0])];let i,r,s=[];return[i,r]=t.point2segment(n.start,e),s.push([i,r.reverse()]),[i,r]=t.point2segment(n.end,e),s.push([i,r.reverse()]),s.push(t.point2segment(e.start,n)),s.push(t.point2segment(e.end,n)),t.sort(s),s[0]}static segment2circle(e,n){let o=e.intersect(n);if(o.length>0)return[0,new nu.Segment(o[0],o[0])];let i=new nu.Line(e.ps,e.pe),[r,s]=t.point2line(n.center,i);if(nu.Utils.GE(r,n.r)&&s.end.on(e))return t.point2circle(s.end,n);{let[o,i]=t.point2circle(e.start,n),[r,s]=t.point2circle(e.end,n);return nu.Utils.LT(o,r)?[o,i]:[r,s]}}static segment2arc(e,n){let o=e.intersect(n);if(o.length>0)return[0,new nu.Segment(o[0],o[0])];let i=new nu.Line(e.ps,e.pe),r=new nu.Circle(n.pc,n.r),[s,a]=t.point2line(r.center,i);if(nu.Utils.GE(s,r.r)&&a.end.on(e)){let[e,o]=t.point2circle(a.end,r);if(o.end.on(n))return[e,o]}let c,l,d=[];return d.push(t.point2arc(e.start,n)),d.push(t.point2arc(e.end,n)),[c,l]=t.point2segment(n.start,e),d.push([c,l.reverse()]),[c,l]=t.point2segment(n.end,e),d.push([c,l.reverse()]),t.sort(d),d[0]}static circle2circle(e,n){let o=e.intersect(n);if(o.length>0)return[0,new nu.Segment(o[0],o[0])];if(e.center.equalTo(n.center)){let o=e.toArc(),i=n.toArc();return t.point2point(o.start,i.start)}{let o=new nu.Line(e.center,n.center),i=o.intersect(e),r=o.intersect(n),s=[];return s.push(t.point2point(i[0],r[0])),s.push(t.point2point(i[0],r[1])),s.push(t.point2point(i[1],r[0])),s.push(t.point2point(i[1],r[1])),t.sort(s),s[0]}}static circle2line(e,n){let o=e.intersect(n);if(o.length>0)return[0,new nu.Segment(o[0],o[0])];let[i,r]=t.point2line(e.center,n),[s,a]=t.point2circle(r.end,e);return a=a.reverse(),[s,a]}static arc2line(e,n){let o=n.intersect(e);if(o.length>0)return[0,new nu.Segment(o[0],o[0])];let i=new nu.Circle(e.center,e.r),[r,s]=t.point2line(i.center,n);if(!nu.Utils.GE(r,i.r)){let o=[];return o.push(t.point2line(e.start,n)),o.push(t.point2line(e.end,n)),t.sort(o),o[0]}{let[n,o]=t.point2circle(s.end,i);if(o.end.on(e))return[n,o]}}static arc2circle(e,n){let o=e.intersect(n);if(o.length>0)return[0,new nu.Segment(o[0],o[0])];let i=new nu.Circle(e.center,e.r),[r,s]=t.circle2circle(i,n);if(s.start.on(e))return[r,s];{let o=[];return o.push(t.point2circle(e.start,n)),o.push(t.point2circle(e.end,n)),t.sort(o),o[0]}}static arc2arc(e,n){let o=e.intersect(n);if(o.length>0)return[0,new nu.Segment(o[0],o[0])];let i=new nu.Circle(e.center,e.r),r=new nu.Circle(n.center,n.r),[s,a]=t.circle2circle(i,r);if(a.start.on(e)&&a.end.on(n))return[s,a];{let o,i,r=[];return[o,i]=t.point2arc(e.start,n),i.end.on(n)&&r.push([o,i]),[o,i]=t.point2arc(e.end,n),i.end.on(n)&&r.push([o,i]),[o,i]=t.point2arc(n.start,e),i.end.on(e)&&r.push([o,i.reverse()]),[o,i]=t.point2arc(n.end,e),i.end.on(e)&&r.push([o,i.reverse()]),[o,i]=t.point2point(e.start,n.start),r.push([o,i]),[o,i]=t.point2point(e.start,n.end),r.push([o,i]),[o,i]=t.point2point(e.end,n.start),r.push([o,i]),[o,i]=t.point2point(e.end,n.end),r.push([o,i]),t.sort(r),r[0]}}static point2polygon(e,n){let o=[Number.POSITIVE_INFINITY,new nu.Segment];for(let i of n.edges){let[n,r]=t.point2edge(e,i);nu.Utils.LT(n,o[0])&&(o=[n,r])}return o}static shape2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new nu.Segment];for(let o of e.edges){let[e,i]=t.distanceTo(o.shape);nu.Utils.LT(e,n[0])&&(n=[e,i])}return n}static polygon2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new nu.Segment];for(let o of t.edges)for(let t of e.edges){let[e,i]=o.shape.distanceTo(t.shape);nu.Utils.LT(e,n[0])&&(n=[e,i])}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)),o=Math.max(Math.max(t.ymin-e.ymax,0),Math.max(e.ymin-t.ymax,0)),i=n*n+o*o,r=t.merge(e),s=r.xmax-r.xmin,a=r.ymax-r.ymin;return[i,s*s+a*a]}static minmax_tree_process_level(e,n,o,i){let r,s;for(let a of n){[r,s]=t.box2box_minmax(e.box,a.item.key);for(let t of a.item.values)t instanceof nu.Edge?i.insert([r,s],t.shape):i.insert([r,s],t);nu.Utils.LT(s,o)&&(o=s)}if(0===n.length)return o;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[i,r]=t.box2box_minmax(e.box,n.max);return nu.Utils.LE(i,o)});return o=t.minmax_tree_process_level(e,a,o,i)}static minmax_tree(e,n,o){let i=new Bp,r=[n.index.root],s=o<Number.POSITIVE_INFINITY?o*o:Number.POSITIVE_INFINITY;return s=t.minmax_tree_process_level(e,r,s,i),i}static minmax_tree_calc_distance(e,n,o){let i,r;if(null!=n&&!n.isNil()){if([i,r]=t.minmax_tree_calc_distance(e,n.left,o),r)return[i,r];if(nu.Utils.LT(i[0],Math.sqrt(n.item.key.low)))return[i,!0];let[s,a]=t.distanceToArray(e,n.item.values);return nu.Utils.LT(s,i[0])&&(i=[s,a]),[i,r]=t.minmax_tree_calc_distance(e,n.right,i),[i,r]}return[o,!1]}static shape2planarSet(e,n,o=Number.POSITIVE_INFINITY){let i=[o,new nu.Segment],r=!1;if(n instanceof nu.PlanarSet){let s=t.minmax_tree(e,n,o);[i,r]=t.minmax_tree_calc_distance(e,s.root,i)}return i}static sort(t){t.sort((t,e)=>nu.Utils.LT(t[0],e[0])?-1:nu.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 nu.Segment];for(let o of e){let[e,i]=t.distanceTo(o);nu.Utils.LT(e,n[0])&&(n=[e,i])}return n}static shape2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new nu.Segment];for(let i of n){let[n,r]=t.distance(e,i.shape);nu.Utils.LT(n,o[0])&&(o=[n,r])}return o}static multiline2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new nu.Segment];for(let i of e)for(let e of n){let[n,r]=t.distance(i.shape,e.shape);nu.Utils.LT(n,o[0])&&(o=[n,r])}return o}};var{Multiline:qp,Point:Jp,Segment:Kp,Polygon:Qp}=nu;function tm(t){return new Jp(t.split(" ").map(Number))}function em(t){return t.split(", ").map(tm)}function nm(t){const e=em(t);let n=[];for(let t=0;t<e.length-1;t++)n.push(new Kp(e[t],e[t+1]));return new qp(n)}function om(t){const e=t.replace(/\(\(/,"").replace(/\)\)$/,"").split("), ("),n=new Qp;let o;return e.forEach((t,e)=>{let i=t.split(", ").map(t=>new Jp(t.split(" ").map(Number)));const r=n.addFace(i);0===e?o=r.orientation():r.orientation()===o&&r.reverse()}),n}function im(t){if(t.startsWith("POLYGON")){return om(t.replace(/^POLYGON /,""))}return function(t){const e=t.split(/\)\), \(\(/).map(t=>"(("+t+"))").map(om),n=new Qp;return e.reduce((t,e)=>[...t,...e?.faces],[]).forEach(t=>n.addFace([...t?.shapes])),n}(t.replace(/^MULTIPOLYGON \(\(\((.*)\)\)\)$/,"$1"))}function rm(t){return t.split("\n")?.every(t=>t.includes("POINT"))}function sm(t){return t.split("\n")?.every(t=>t.includes("LINESTRING"))}nu.isWktString=function(t){return t.startsWith("POINT")||rm(t)||t.startsWith("LINESTRING")||sm(t)||t.startsWith("MULTILINESTRING")||t.startsWith("POLYGON")||t.startsWith("MULTIPOINT")||t.startsWith("MULTIPOLYGON")||t.startsWith("GEOMETRYCOLLECTION")},nu.parseWKT=function t(e){if(e.startsWith("POINT")){return tm(e.replace(/^POINT \(/,"").replace(/\)$/,""))}if(e.startsWith("MULTIPOINT")){return em(e.replace(/^MULTIPOINT \(/,"").replace(/\)$/,""))}if(e.startsWith("LINESTRING")){return nm(e.replace(/^LINESTRING \(/,"").replace(/\)$/,""))}if(e.startsWith("MULTILINESTRING")){return function(t){return t.replace(/\(\(/,"").replace(/\)\)$/,"").split("), (").map(nm)}(e.replace(/^MULTILINESTRING /,""))}if(e.startsWith("POLYGON")||e.startsWith("MULTIPOLYGON"))return im(e);if(e.startsWith("GEOMETRYCOLLECTION")){const n=/(?<type>POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \((?:[^\(\)]|\([^\)]*\))*\)/g,o=e.match(n);o[0].startsWith("GEOMETRYCOLLECTION")&&(o[0]=o[0].replace("GEOMETRYCOLLECTION (",""));return o.map(t).map(t=>t instanceof Array?t:[t]).reduce((t,e)=>[...t,...e],[])}return rm(e)?function(t){return t.split("\n").map(t=>t.match(/\(([^)]+)\)/)[1]).map(tm)}(e):sm(e)?function(t){return t.split("\n").map(t=>t.match(/\(([^)]+)\)/)[1]).map(nm).reduce((t,e)=>[...t,...e],[])}(e):[]},nu.BooleanOperations=bp,nu.Relations=kp;am=Wd(),cm=1,lm=null!=am?Md(Rd(am)):{},((t,e,n,o)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let i of Td(e))Ed.call(t,i)||i===n||Nd(t,i,{get:()=>e[i],enumerable:!(o=wd(e,i))||o.enumerable})})(!cm&&am&&am.__esModule?lm:Nd(lm,"default",{value:am,enumerable:!0}),am);var am,cm,lm,dm=Object.create,hm=Object.defineProperty,um=Object.getOwnPropertyDescriptor,pm=Object.getOwnPropertyNames,mm=Object.getPrototypeOf,gm=Object.prototype.hasOwnProperty,fm=(t,e)=>function(){return e||(0,t[pm(t)[0]])((e={exports:{}}).exports,e),e.exports},ym=(t,e,n)=>(n=null!=t?dm(mm(t)):{},((t,e,n,o)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let i of pm(e))gm.call(t,i)||i===n||hm(t,i,{get:()=>e[i],enumerable:!(o=um(e,i))||o.enumerable});return t})(!e&&t&&t.__esModule?n:hm(n,"default",{value:t,enumerable:!0}),t)),_m=fm({"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)}}}),bm=fm({"node_modules/kind-of/index.js"(t,e){var n=_m(),o=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=o.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"}}}),xm=fm({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(n[e(o,t[o])||o]=t[o]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),vm=fm({"node_modules/deep-rename-keys/index.js"(t,e){var n=bm(),o=xm();e.exports=function t(e,i){var r=n(e);if("object"!==r&&"array"!==r)throw new Error("expected an object");var s=[];for(var a in"object"===r&&(e=o(e,i),s={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?s[a]=t(c,i):s[a]=c}return s}}}),Sm=fm({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,o="~";function i(){}function r(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function s(){this._events=new i,this._eventsCount=0}Object.create&&(i.prototype=Object.create(null),(new i).__proto__||(o=!1)),s.prototype.eventNames=function(){var t,e,i=[];if(0===this._eventsCount)return i;for(e in t=this._events)n.call(t,e)&&i.push(o?e.slice(1):e);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},s.prototype.listeners=function(t,e){var n=o?o+t:t,i=this._events[n];if(e)return!!i;if(!i)return[];if(i.fn)return[i.fn];for(var r=0,s=i.length,a=new Array(s);r<s;r++)a[r]=i[r].fn;return a},s.prototype.emit=function(t,e,n,i,r,s){var a=o?o+t:t;if(!this._events[a])return!1;var c,l,d=this._events[a],h=arguments.length;if(d.fn){switch(d.once&&this.removeListener(t,d.fn,void 0,!0),h){case 1:return d.fn.call(d.context),!0;case 2:return d.fn.call(d.context,e),!0;case 3:return d.fn.call(d.context,e,n),!0;case 4:return d.fn.call(d.context,e,n,i),!0;case 5:return d.fn.call(d.context,e,n,i,r),!0;case 6:return d.fn.call(d.context,e,n,i,r,s),!0}for(l=1,c=new Array(h-1);l<h;l++)c[l-1]=arguments[l];d.fn.apply(d.context,c)}else{var u,p=d.length;for(l=0;l<p;l++)switch(d[l].once&&this.removeListener(t,d[l].fn,void 0,!0),h){case 1:d[l].fn.call(d[l].context);break;case 2:d[l].fn.call(d[l].context,e);break;case 3:d[l].fn.call(d[l].context,e,n);break;case 4:d[l].fn.call(d[l].context,e,n,i);break;default:if(!c)for(u=1,c=new Array(h-1);u<h;u++)c[u-1]=arguments[u];d[l].fn.apply(d[l].context,c)}}return!0},s.prototype.on=function(t,e,n){var i=new r(e,n||this),s=o?o+t:t;return this._events[s]?this._events[s].fn?this._events[s]=[this._events[s],i]:this._events[s].push(i):(this._events[s]=i,this._eventsCount++),this},s.prototype.once=function(t,e,n){var i=new r(e,n||this,!0),s=o?o+t:t;return this._events[s]?this._events[s].fn?this._events[s]=[this._events[s],i]:this._events[s].push(i):(this._events[s]=i,this._eventsCount++),this},s.prototype.removeListener=function(t,e,n,r){var s=o?o+t:t;if(!this._events[s])return this;if(!e)return 0===--this._eventsCount?this._events=new i:delete this._events[s],this;var a=this._events[s];if(a.fn)a.fn!==e||r&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new i:delete this._events[s]);else{for(var c=0,l=[],d=a.length;c<d;c++)(a[c].fn!==e||r&&!a[c].once||n&&a[c].context!==n)&&l.push(a[c]);l.length?this._events[s]=1===l.length?l[0]:l:0===--this._eventsCount?this._events=new i:delete this._events[s]}return this},s.prototype.removeAllListeners=function(t){var e;return t?(e=o?o+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new i:delete this._events[e])):(this._events=new i,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prototype.setMaxListeners=function(){return this},s.prefixed=o,s.EventEmitter=s,void 0!==e&&(e.exports=s)}}),Im=fm({"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 o=Sm(),i=function(){},r={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"},s={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={" ":s.space,"\t":s.space,"\n":s.space,"\r":s.space,"<":s.lt,">":s.gt,'"':s.quote,"'":s.quote,"=":s.equal,"/":s.slash};e.exports={State:r,Action:s,Type:a,create:function(t){var e,l,d,h,u,p,m,g,f,y;t=Object.assign({debug:!1},t);var _=new o,b=r.data,x="",v="",S="",I="",C="",P="",M=function(e,n){if("?"!==v[0]&&"!"!==v[0]){var o={type:e,value:n};t.debug&&console.log("emit:",o),_.emit("data",o)}};_.stateMachine=(n(y={},r.data,(n(e={},s.lt,function(){x.trim()&&M(a.text,x),v="",C=!1,b=r.tagBegin}),n(e,s.char,function(t){x+=t}),e)),n(y,r.cdata,n({},s.char,function(t){"]]>"===(x+=t).substr(-3)&&(M(a.text,x.slice(0,-3)),x="",b=r.data)})),n(y,r.tagBegin,(n(l={},s.space,i),n(l,s.char,function(t){v=t,b=r.tagName}),n(l,s.slash,function(){v="",C=!0}),l)),n(y,r.tagName,(n(d={},s.space,function(){C?b=r.tagEnd:(b=r.attributeNameStart,M(a.openTag,v))}),n(d,s.gt,function(){M(C?a.closeTag:a.openTag,v),x="",b=r.data}),n(d,s.slash,function(){b=r.tagEnd,M(a.openTag,v)}),n(d,s.char,function(t){"![CDATA["===(v+=t)&&(b=r.cdata,x="",v="")}),d)),n(y,r.tagEnd,(n(h={},s.gt,function(){M(a.closeTag,v),x="",b=r.data}),n(h,s.char,i),h)),n(y,r.attributeNameStart,(n(u={},s.char,function(t){S=t,b=r.attributeName}),n(u,s.gt,function(){x="",b=r.data}),n(u,s.space,i),n(u,s.slash,function(){C=!0,b=r.tagEnd}),u)),n(y,r.attributeName,(n(p={},s.space,function(){b=r.attributeNameEnd}),n(p,s.equal,function(){M(a.attributeName,S),b=r.attributeValueBegin}),n(p,s.gt,function(){I="",M(a.attributeName,S),M(a.attributeValue,I),x="",b=r.data}),n(p,s.slash,function(){C=!0,I="",M(a.attributeName,S),M(a.attributeValue,I),b=r.tagEnd}),n(p,s.char,function(t){S+=t}),p)),n(y,r.attributeNameEnd,(n(m={},s.space,i),n(m,s.equal,function(){M(a.attributeName,S),b=r.attributeValueBegin}),n(m,s.gt,function(){I="",M(a.attributeName,S),M(a.attributeValue,I),x="",b=r.data}),n(m,s.char,function(t){I="",M(a.attributeName,S),M(a.attributeValue,I),S=t,b=r.attributeName}),m)),n(y,r.attributeValueBegin,(n(g={},s.space,i),n(g,s.quote,function(t){P=t,I="",b=r.attributeValue}),n(g,s.gt,function(){M(a.attributeValue,I=""),x="",b=r.data}),n(g,s.char,function(t){P="",I=t,b=r.attributeValue}),g)),n(y,r.attributeValue,(n(f={},s.space,function(t){P?I+=t:(M(a.attributeValue,I),b=r.attributeNameStart)}),n(f,s.quote,function(t){P===t?(M(a.attributeValue,I),b=r.attributeNameStart):I+=t}),n(f,s.gt,function(t){P?I+=t:(M(a.attributeValue,I),x="",b=r.data)}),n(f,s.slash,function(t){P?I+=t:(M(a.attributeValue,I),C=!0,b=r.tagEnd)}),n(f,s.char,function(t){I+=t}),f)),y);var N=function(e){t.debug&&console.log(b,e);var n=_.stateMachine[b],o=n[function(t){return c[t]||s.char}(e)]||n[s.error]||n[s.char];o(e)};return _.write=function(t){for(var e=t.length,n=0;n<e;n++)N(t[n])},_}}}}),Cm=fm({"node_modules/xml-reader/dist/reader.js"(t,e){var n=Sm(),o=Im(),i=o.Type,r={element:"element",text:"text"},s=function(t){return Object.assign({name:"",type:r.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,l=void 0,d=new n,h=function(n){switch(n.type){case i.openTag:if(null===c)(c=a).name=n.value;else{var o=s({name:n.value,parent:c});c.children.push(o),c=o}break;case i.closeTag:var h=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&h===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&h!==a||(d.emit(t.tagPrefix+c.name,c),d.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),d.emit(t.doneEvent,c),a=null),c=h;break;case i.text:c&&c.children.push(s({type:r.text,value:n.value,parent:t.parentNodes?c:null}));break;case i.attributeName:l=n.value,c.attributes[l]="";break;case i.attributeValue:c.attributes[l]=n.value}};return d.reset=function(){(e=o.create({debug:t.debug})).on("data",h),a=s(),c=null,l="",d.parse=e.write},d.reset(),d};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),o=void 0;return n.on("done",function(t){o=t}),n.parse(t),o},create:a,NodeType:r}}}),{cos:Pm,sin:Mm,PI:Nm}=Math,{tan:wm}=Math,Tm=(ym(vm()),ym(Cm()),Object.create),Rm=Object.defineProperty,Em=Object.getOwnPropertyDescriptor,Am=Object.getOwnPropertyNames,Om=Object.getPrototypeOf,km=Object.prototype.hasOwnProperty,Lm=(t,e)=>function(){return e||(0,t[Am(t)[0]])((e={exports:{}}).exports,e),e.exports},Dm=(t,e,n)=>(n=null!=t?Tm(Om(t)):{},((t,e,n,o)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let i of Am(e))km.call(t,i)||i===n||Rm(t,i,{get:()=>e[i],enumerable:!(o=Em(e,i))||o.enumerable});return t})(!e&&t&&t.__esModule?n:Rm(n,"default",{value:t,enumerable:!0}),t)),zm=Lm({"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)}}}),Fm=Lm({"node_modules/kind-of/index.js"(t,e){var n=zm(),o=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=o.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"}}}),Bm=Lm({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(n[e(o,t[o])||o]=t[o]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),jm=Lm({"node_modules/deep-rename-keys/index.js"(t,e){var n=Fm(),o=Bm();e.exports=function t(e,i){var r=n(e);if("object"!==r&&"array"!==r)throw new Error("expected an object");var s=[];for(var a in"object"===r&&(e=o(e,i),s={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?s[a]=t(c,i):s[a]=c}return s}}}),$m=Lm({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,o="~";function i(){}function r(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function s(){this._events=new i,this._eventsCount=0}Object.create&&(i.prototype=Object.create(null),(new i).__proto__||(o=!1)),s.prototype.eventNames=function(){var t,e,i=[];if(0===this._eventsCount)return i;for(e in t=this._events)n.call(t,e)&&i.push(o?e.slice(1):e);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},s.prototype.listeners=function(t,e){var n=o?o+t:t,i=this._events[n];if(e)return!!i;if(!i)return[];if(i.fn)return[i.fn];for(var r=0,s=i.length,a=new Array(s);r<s;r++)a[r]=i[r].fn;return a},s.prototype.emit=function(t,e,n,i,r,s){var a=o?o+t:t;if(!this._events[a])return!1;var c,l,d=this._events[a],h=arguments.length;if(d.fn){switch(d.once&&this.removeListener(t,d.fn,void 0,!0),h){case 1:return d.fn.call(d.context),!0;case 2:return d.fn.call(d.context,e),!0;case 3:return d.fn.call(d.context,e,n),!0;case 4:return d.fn.call(d.context,e,n,i),!0;case 5:return d.fn.call(d.context,e,n,i,r),!0;case 6:return d.fn.call(d.context,e,n,i,r,s),!0}for(l=1,c=new Array(h-1);l<h;l++)c[l-1]=arguments[l];d.fn.apply(d.context,c)}else{var u,p=d.length;for(l=0;l<p;l++)switch(d[l].once&&this.removeListener(t,d[l].fn,void 0,!0),h){case 1:d[l].fn.call(d[l].context);break;case 2:d[l].fn.call(d[l].context,e);break;case 3:d[l].fn.call(d[l].context,e,n);break;case 4:d[l].fn.call(d[l].context,e,n,i);break;default:if(!c)for(u=1,c=new Array(h-1);u<h;u++)c[u-1]=arguments[u];d[l].fn.apply(d[l].context,c)}}return!0},s.prototype.on=function(t,e,n){var i=new r(e,n||this),s=o?o+t:t;return this._events[s]?this._events[s].fn?this._events[s]=[this._events[s],i]:this._events[s].push(i):(this._events[s]=i,this._eventsCount++),this},s.prototype.once=function(t,e,n){var i=new r(e,n||this,!0),s=o?o+t:t;return this._events[s]?this._events[s].fn?this._events[s]=[this._events[s],i]:this._events[s].push(i):(this._events[s]=i,this._eventsCount++),this},s.prototype.removeListener=function(t,e,n,r){var s=o?o+t:t;if(!this._events[s])return this;if(!e)return 0===--this._eventsCount?this._events=new i:delete this._events[s],this;var a=this._events[s];if(a.fn)a.fn!==e||r&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new i:delete this._events[s]);else{for(var c=0,l=[],d=a.length;c<d;c++)(a[c].fn!==e||r&&!a[c].once||n&&a[c].context!==n)&&l.push(a[c]);l.length?this._events[s]=1===l.length?l[0]:l:0===--this._eventsCount?this._events=new i:delete this._events[s]}return this},s.prototype.removeAllListeners=function(t){var e;return t?(e=o?o+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new i:delete this._events[e])):(this._events=new i,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prototype.setMaxListeners=function(){return this},s.prefixed=o,s.EventEmitter=s,void 0!==e&&(e.exports=s)}}),Ym=Lm({"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 o=$m(),i=function(){},r={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"},s={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={" ":s.space,"\t":s.space,"\n":s.space,"\r":s.space,"<":s.lt,">":s.gt,'"':s.quote,"'":s.quote,"=":s.equal,"/":s.slash};e.exports={State:r,Action:s,Type:a,create:function(t){var e,l,d,h,u,p,m,g,f,y;t=Object.assign({debug:!1},t);var _=new o,b=r.data,x="",v="",S="",I="",C="",P="",M=function(e,n){if("?"!==v[0]&&"!"!==v[0]){var o={type:e,value:n};t.debug&&console.log("emit:",o),_.emit("data",o)}};_.stateMachine=(n(y={},r.data,(n(e={},s.lt,function(){x.trim()&&M(a.text,x),v="",C=!1,b=r.tagBegin}),n(e,s.char,function(t){x+=t}),e)),n(y,r.cdata,n({},s.char,function(t){"]]>"===(x+=t).substr(-3)&&(M(a.text,x.slice(0,-3)),x="",b=r.data)})),n(y,r.tagBegin,(n(l={},s.space,i),n(l,s.char,function(t){v=t,b=r.tagName}),n(l,s.slash,function(){v="",C=!0}),l)),n(y,r.tagName,(n(d={},s.space,function(){C?b=r.tagEnd:(b=r.attributeNameStart,M(a.openTag,v))}),n(d,s.gt,function(){M(C?a.closeTag:a.openTag,v),x="",b=r.data}),n(d,s.slash,function(){b=r.tagEnd,M(a.openTag,v)}),n(d,s.char,function(t){"![CDATA["===(v+=t)&&(b=r.cdata,x="",v="")}),d)),n(y,r.tagEnd,(n(h={},s.gt,function(){M(a.closeTag,v),x="",b=r.data}),n(h,s.char,i),h)),n(y,r.attributeNameStart,(n(u={},s.char,function(t){S=t,b=r.attributeName}),n(u,s.gt,function(){x="",b=r.data}),n(u,s.space,i),n(u,s.slash,function(){C=!0,b=r.tagEnd}),u)),n(y,r.attributeName,(n(p={},s.space,function(){b=r.attributeNameEnd}),n(p,s.equal,function(){M(a.attributeName,S),b=r.attributeValueBegin}),n(p,s.gt,function(){I="",M(a.attributeName,S),M(a.attributeValue,I),x="",b=r.data}),n(p,s.slash,function(){C=!0,I="",M(a.attributeName,S),M(a.attributeValue,I),b=r.tagEnd}),n(p,s.char,function(t){S+=t}),p)),n(y,r.attributeNameEnd,(n(m={},s.space,i),n(m,s.equal,function(){M(a.attributeName,S),b=r.attributeValueBegin}),n(m,s.gt,function(){I="",M(a.attributeName,S),M(a.attributeValue,I),x="",b=r.data}),n(m,s.char,function(t){I="",M(a.attributeName,S),M(a.attributeValue,I),S=t,b=r.attributeName}),m)),n(y,r.attributeValueBegin,(n(g={},s.space,i),n(g,s.quote,function(t){P=t,I="",b=r.attributeValue}),n(g,s.gt,function(){M(a.attributeValue,I=""),x="",b=r.data}),n(g,s.char,function(t){P="",I=t,b=r.attributeValue}),g)),n(y,r.attributeValue,(n(f={},s.space,function(t){P?I+=t:(M(a.attributeValue,I),b=r.attributeNameStart)}),n(f,s.quote,function(t){P===t?(M(a.attributeValue,I),b=r.attributeNameStart):I+=t}),n(f,s.gt,function(t){P?I+=t:(M(a.attributeValue,I),x="",b=r.data)}),n(f,s.slash,function(t){P?I+=t:(M(a.attributeValue,I),C=!0,b=r.tagEnd)}),n(f,s.char,function(t){I+=t}),f)),y);var N=function(e){t.debug&&console.log(b,e);var n=_.stateMachine[b],o=n[function(t){return c[t]||s.char}(e)]||n[s.error]||n[s.char];o(e)};return _.write=function(t){for(var e=t.length,n=0;n<e;n++)N(t[n])},_}}}}),Xm=Lm({"node_modules/xml-reader/dist/reader.js"(t,e){var n=$m(),o=Ym(),i=o.Type,r={element:"element",text:"text"},s=function(t){return Object.assign({name:"",type:r.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,l=void 0,d=new n,h=function(n){switch(n.type){case i.openTag:if(null===c)(c=a).name=n.value;else{var o=s({name:n.value,parent:c});c.children.push(o),c=o}break;case i.closeTag:var h=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&h===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&h!==a||(d.emit(t.tagPrefix+c.name,c),d.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),d.emit(t.doneEvent,c),a=null),c=h;break;case i.text:c&&c.children.push(s({type:r.text,value:n.value,parent:t.parentNodes?c:null}));break;case i.attributeName:l=n.value,c.attributes[l]="";break;case i.attributeValue:c.attributes[l]=n.value}};return d.reset=function(){(e=o.create({debug:t.debug})).on("data",h),a=s(),c=null,l="",d.parse=e.write},d.reset(),d};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),o=void 0;return n.on("done",function(t){o=t}),n.parse(t),o},create:a,NodeType:r}}}),{cos:Vm,sin:Wm,PI:Hm}=Math,{tan:Gm}=Math;Dm(jm()),Dm(Xm());function Um(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 Zm=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 qm(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var Jm=class extends Zm{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,o=this.firstIterationOfStage[e.solverName]||0,i=this.iterations,r=e.solverName===this.getCurrentStageName()?i-o:0,s=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:r,completed:s}}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&&(Um(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const o=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const o=this[e.solverName],i=o?.visualize();return i?(Um(i,n+t),i):null}).filter(Boolean));return 0===o.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(Um(n,o.length+t+1),o.push(n)),1===o.length?o[0]:{points:o.flatMap(t=>t.points||[]),rects:o.flatMap(t=>t.rects||[]),lines:o.flatMap(t=>t.lines||[]),circles:o.flatMap(t=>t.circles||[]),texts:o.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]}},Km=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),Qm=(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 o=[],i=[];for(const t of n){for(;o.length>=2;){const e=o[o.length-2],n=o[o.length-1];if(!e||!n||Km(e,n,t)>1e-10)break;o.pop()}o.push(t)}for(let t=n.length-1;t>=0;t--){const e=n[t];if(e){for(;i.length>=2;){const t=i[i.length-2],n=i[i.length-1];if(!t||!n||Km(t,n,e)>1e-10)break;i.pop()}i.push(e)}}return o.pop(),i.pop(),o.concat(i).map(t=>t.i)},tg=t=>void 0!==t,eg=class extends Zm{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(tg)),hulls:n.cells.map(t=>Qm(t,n.pts).map(t=>n.pts[t]).filter(tg))};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 o=t[(n+1)%t.length];return o?[{points:[e,o],strokeColor:"#0f766e"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`regions: ${t.regions.length}`,color:"#1f2937"}]}:{points:[],lines:[],rects:[],circles:[],texts:[]}}},ng=(t,e,n)=>{const o=Math.cos(n.ccwRotation),i=Math.sin(n.ccwRotation);return{x:n.center.x+t*o-e*i,y:n.center.y+t*i+e*o}},og=(t,e=[],n,o=[])=>{const i=[],{minX:r,maxX:s,minY:a,maxY:c}=t;i.push({x:r,y:a},{x:s,y:a},{x:s,y:c},{x:r,y:c});for(let t=1;t<10;t++){const e=t/10;i.push({x:r+e*(s-r),y:a}),i.push({x:s,y:a+e*(c-a)}),i.push({x:s-e*(s-r),y:c}),i.push({x:r,y:c-e*(c-a)})}for(const t of e){const e=t.diameter/2+n;for(let n=0;n<24;n++){const o=2*Math.PI*n/24;i.push({x:t.center.x+e*Math.cos(o),y:t.center.y+e*Math.sin(o)})}}for(const t of o){const e=t.width/2+n,o=t.height/2+n,r=Math.max(2,Math.ceil(Math.max(2*e,2*o)/20));for(let n=0;n<r;n++){const s=n/r;i.push(ng(2*s*e-e,-o,t)),i.push(ng(e,2*s*o-o,t)),i.push(ng(e-2*s*e,o,t)),i.push(ng(-e,o-2*s*o,t))}}return i.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))},ig=class extends Zm{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[];this.output={pts:og(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"}]}}},rg=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r<1e-10)return Math.hypot(t.x-e.x,t.y-e.y);let s=((t.x-e.x)*o+(t.y-e.y)*i)/r;return s=Math.max(0,Math.min(1,s)),Math.hypot(t.x-e.x-s*o,t.y-e.y-s*i)},sg=(t,e)=>{if(t.length<=3)return 0;const n=Qm(t,e),o=new Set(n),i=n.map(t=>e[t]).filter(t=>Boolean(t));let r=0;for(const n of t){if(o.has(n))continue;const t=e[n];if(!t)continue;let s=Number.POSITIVE_INFINITY;for(let e=0;e<i.length;e++){const n=i[e],o=i[(e+1)%i.length];n&&o&&(s=Math.min(s,rg(t,n,o)))}r=Math.max(r,s)}return r},ag=(t,e)=>t<e?1e5*t+e:1e5*e+t,cg=(t,e)=>{const n=t.map((e,n)=>[e,t[(n+1)%t.length]]),o=e.map((t,n)=>[t,e[(n+1)%e.length]]),i=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,r]of o)void 0!==r&&t===r&&e===n&&i.add(ag(t,e));if(0===i.size)return null;const r=[];for(const[t,e]of n)void 0!==e&&(i.has(ag(t,e))||r.push([t,e]));for(const[t,e]of o)void 0!==e&&(i.has(ag(t,e))||r.push([t,e]));if(0===r.length)return null;const s=new Map;for(const[t,e]of r)s.set(t,e);const a=r[0]?.[0];if(void 0===a)return null;const c=[a];let l=s.get(a),d=0;for(;void 0!==l&&l!==a&&d++<r.length+5;)c.push(l),l=s.get(l);return l!==a||c.length!==r.length?null:c},lg=(t,e)=>t<e?1e5*t+e:1e5*e+t,dg=class extends Zm{input;output=null;constructor(t){super(),this.input=t}_step(){const t=((t,e,n)=>{if(!t.length)return{cells:[],depths:[]};const o=t.map(([t,n,o])=>{const i=e[t],r=e[n],s=e[o];return i&&r&&s&&Km(i,r,s)<0?[t,o,n]:[t,n,o]});let i=!0,r=0;for(;i&&r++<800;){i=!1;const t=new Map,r=o.map(()=>new Set);for(let e=0;e<o.length;e++){const n=o[e];if(n)for(let o=0;o<n.length;o++){const i=n[o],s=n[(o+1)%n.length];if(void 0===i||void 0===s)continue;const a=lg(i,s);if(t.has(a)){const n=t.get(a);void 0!==n&&(r[e]?.add(n),r[n]?.add(e))}else t.set(a,e)}}let s=-1,a=-1,c=null,l=Number.POSITIVE_INFINITY;for(let t=0;t<o.length;t++){const i=r[t];if(i)for(const r of i){if(r<=t)continue;const i=cg(o[t]??[],o[r]??[]);if(!i)continue;const d=sg(i,e);d<=n+1e-6&&d<l&&(l=d,s=t,a=r,c=i)}}if(s<0||a<0||!c)break;o[s]=c,o.splice(a,1),i=!0}const s=o.map(t=>sg(t,e));return{cells:o,depths:s}})(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 o=this.input.pts[e],i=t[(n+1)%t.length],r=void 0===i?void 0:this.input.pts[i];return o&&r?[{points:[o,r],strokeColor:"#10b981"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`merged cells: ${t.length}`,color:"#1f2937"}]}}},hg=(t,e,n)=>{const o=2*(t.x*(e.y-n.y)+e.x*(n.y-t.y)+n.x*(t.y-e.y));if(Math.abs(o)<1e-10)return{x:0,y:0,r2:1e18};const i=t.x*t.x+t.y*t.y,r=e.x*e.x+e.y*e.y,s=n.x*n.x+n.y*n.y,a=(i*(e.y-n.y)+r*(n.y-t.y)+s*(t.y-e.y))/o,c=(i*(n.x-e.x)+r*(t.x-n.x)+s*(e.x-t.x))/o;return{x:a,y:c,r2:(t.x-a)**2+(t.y-c)**2}},ug=(t,e,n)=>[t.a,t.b,t.c].includes(e)&&[t.a,t.b,t.c].includes(n),pg=(t,e,n,o=[],i,r=[])=>t.filter(([t,s,a])=>{const c=e[t],l=e[s],d=e[a];if(!c||!l||!d)return!1;return((t,e,n,o=[],i,r=[])=>{const{minX:s,maxX:a,minY:c,maxY:l}=n;if(t<s-.1||t>a+.1||e<c-.1||e>l+.1)return!1;for(const n of o){const o=n.diameter/2+i;if((t-n.center.x)**2+(e-n.center.y)**2<o*o-.1)return!1}for(const n of r){const o=n.width/2+i,r=n.height/2+i,s=t-n.center.x,a=e-n.center.y,c=Math.cos(n.ccwRotation),l=Math.sin(n.ccwRotation),d=s*c+a*l,h=-s*l+a*c;if(Math.abs(d)<o-.1&&Math.abs(h)<r-.1)return!1}return!0})((c.x+l.x+d.x)/3,(c.y+l.y+d.y)/3,n,o,i,r)}),mg=class extends Zm{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,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),o=Math.min(o,t.y),i=Math.max(i,t.x),r=Math.max(r,t.y);const s=Math.max(i-n,r-o)||1,a=(n+i)/2,c=(o+r)/2,l={x:a-30*s,y:c-s,i:-1},d={x:a,y:c+30*s,i:-2},h={x:a+30*s,y:c-s,i:-3};let u=[{a:l,b:d,c:h,cc:hg(l,d,h)}];for(const t of e){const e=u.filter(e=>{const n=t.x-e.cc.x,o=t.y-e.cc.y;return n*n+o*o<e.cc.r2+1e-6}),n=new Set(e),o=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[i,r]of n){let n=!1;for(const o of e)if(o!==t&&ug(o,i,r)){n=!0;break}n||o.push([i,r])}}u=u.filter(t=>!n.has(t));for(const[e,n]of o)u.push({a:e,b:n,c:t,cc:hg(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),o=pg(n,this.input.pts,this.input.bounds,t,this.input.clearance,e);this.output={pts:this.input.pts,validTris:o},this.stats={candidateTriangles:n.length,validTriangles:o.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 o=this.input.pts[t],i=this.input.pts[e],r=this.input.pts[n];return o&&i&&r?[{points:[o,i],strokeColor:"#64748b"},{points:[i,r],strokeColor:"#64748b"},{points:[r,o],strokeColor:"#64748b"}]:[]}),rects:[],circles:[],texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`valid triangles: ${t.length}`,color:"#1f2937"}]}}},gg=class extends Jm{pipelineDef=[qm("generatePoints",ig,t=>[t.inputProblem]),qm("triangulate",mg,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}]}),qm("mergeCells",dg,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}]}),qm("buildRegions",eg,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 o=t[(n+1)%t.length]??e;return{points:[{x:e.x,y:e.y},{x:o.x,y:o.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:[]}}},fg=1e-9,yg=(t,e)=>{const n=[Ag(t)],o=[];let i=e.maxSplitsPerRegion??32;for(;n.length>0;){const t=n.pop();if(!t)continue;if(t.length<4){o.push(t);continue}const r=_g(t,e);if(!r||i<=0){o.push(t);continue}const[s,a]=xg(t,r.i,r.j);i-=1,n.push(s,a)}return o},_g=(t,e)=>{const n=Sg(t);if(!n)return null;const{triangles:o}=n,i=wg(t);if(i<=fg)return null;const r=Math.sqrt(i),s=o.map(e=>Tg(t[e[0]],t[e[1]],t[e[2]]));let a=null;for(const c of n.internalEdges){const{i:l,j:d,triA:h,triB:u}=c,p=Rg(t[l],t[d])/r;if(p>e.maxNeckRatio)continue;const m=bg(h,u,o.length,n.triangleAdjacency,s),g=i-m,f=Math.min(m,g)/i;if(f<e.minSplitBalanceRatio)continue;const y=p/Math.max(f,fg);(!a||y<a.score)&&(a={i:l,j:d,score:y})}return a?{i:a.i,j:a.j}:null},bg=(t,e,n,o,i)=>{const r=new Array(n).fill(!1),s=[t];r[e]=!0;let a=0;for(;s.length>0;){const t=s.pop();if(void 0===t||r[t])continue;r[t]=!0,a+=i[t]??0;const e=o[t]??[];for(const t of e)r[t]||s.push(t)}return a},xg=(t,e,n)=>[vg(t,e,n),vg(t,n,e)],vg=(t,e,n)=>{const o=[],i=t.length;let r=e;for(o.push(t[r]);r!==n;)r=(r+1)%i,o.push(t[r]);return Ag(o)},Sg=t=>{const e=t.length;if(e<3)return null;const n=new Set;for(let t=0;t<e;t++){const o=(t+1)%e;n.add(Eg(t,o))}const o=Ig(t);if(!o||0===o.length)return null;const i=new Map;o.forEach((t,e)=>{for(let n=0;n<3;n++){const o=t[n],r=t[(n+1)%3],s=Eg(o,r),a=i.get(s);a?a.push(e):i.set(s,[e])}});const r=Array.from({length:o.length},()=>[]),s=[];for(const[t,e]of i.entries()){if(n.has(t))continue;if(2!==e.length)continue;const[o,i]=t.split("_"),a=Number(o),c=Number(i),l=e[0],d=e[1];s.push({i:a,j:c,triA:l,triB:d});const h=r[l],u=r[d];h&&h.push(d),u&&u.push(l)}return{triangles:o,internalEdges:s,triangleAdjacency:r}},Ig=t=>{const e=t.length;if(e<3)return null;const n=Math.sign(Ng(t));if(0===n)return null;const o=[...Array(e).keys()];n<0&&o.reverse();const i=[];let r=0;for(;o.length>3&&r<e*e;){let e=!1;for(let n=0;n<o.length;n++){const r=o[(n-1+o.length)%o.length],s=o[n],a=o[(n+1)%o.length];if(void 0===r||void 0===s||void 0===a)continue;const c=t[r],l=t[s],d=t[a];if(!c||!l||!d)continue;if(!Cg(c,l,d))continue;let h=!1;for(const e of o){if(e===r||e===s||e===a)continue;const n=t[e];if(n&&Pg(n,c,l,d)){h=!0;break}}if(!h){i.push([r,s,a]),o.splice(n,1),e=!0;break}}if(!e)return null;r+=1}if(3===o.length){const[t,e,n]=o;void 0!==t&&void 0!==e&&void 0!==n&&i.push([t,e,n])}return i},Cg=(t,e,n)=>Mg(t,e,n)>fg,Pg=(t,e,n,o)=>{const i=Mg(e,n,t),r=Mg(n,o,t),s=Mg(o,e,t);return i>=-1e-9&&r>=-1e-9&&s>=-1e-9},Mg=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),Ng=t=>{let e=0;for(let n=0;n<t.length;n++){const o=t[n],i=t[(n+1)%t.length];o&&i&&(e+=o.x*i.y-i.x*o.y)}return e/2},wg=t=>Math.abs(Ng(t)),Tg=(t,e,n)=>Math.abs(Mg(t,e,n))/2,Rg=(t,e)=>Math.hypot(t.x-e.x,t.y-e.y),Eg=(t,e)=>t<e?`${t}_${e}`:`${e}_${t}`,Ag=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},Og={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},kg=(t,e)=>{let n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const s of t)for(const t of s.padCenters){const s="horizontal"===e.orientation?e.padWidth/2:e.padHeight/2,a="horizontal"===e.orientation?e.padHeight/2:e.padWidth/2;t.x-s<n&&(n=t.x-s),t.y-a<o&&(o=t.y-a),t.x+s>i&&(i=t.x+s),t.y+a>r&&(r=t.y+a)}return{minX:n-e.boundsPadding,minY:o-e.boundsPadding,maxX:i+e.boundsPadding,maxY:r+e.boundsPadding}},Lg=t=>"staggered"===t.pattern?(t=>{const e=[],n=[],o=t.padGap/2+t.padWidth/2,i=-(t.cols-1)*t.pitchX/2,r=-(t.rows-1)*t.pitchY/2;for(let s=0;s<t.rows;s++){const a="x"===t.staggerAxis&&s%2==1?t.staggerOffset:0;for(let c=0;c<t.cols;c++){const l="y"===t.staggerAxis&&c%2==1?t.staggerOffset:0,d={x:i+c*t.pitchX+a,y:r+s*t.pitchY+l},h="horizontal"===t.orientation?{x:d.x-o,y:d.y}:{x:d.x,y:d.y-o},u="horizontal"===t.orientation?{x:d.x+o,y:d.y}:{x:d.x,y:d.y+o};e.push({jumperId:`jumper_r${s}_c${c}`,center:d,orientation:t.orientation,padCenters:[h,u]}),n.push({center:h,diameter:t.viaDiameter},{center:u,diameter:t.viaDiameter})}}return{jumpers:e,vias:n,bounds:kg(e,t)}})(t):(t=>{const e=[],n=[],o=t.padGap/2+t.padWidth/2,i=-(t.cols-1)*t.pitchX/2,r=-(t.rows-1)*t.pitchY/2;for(let s=0;s<t.rows;s++)for(let a=0;a<t.cols;a++){const c={x:i+a*t.pitchX,y:r+s*t.pitchY},l="horizontal"===t.orientation?{x:c.x-o,y:c.y}:{x:c.x,y:c.y-o},d="horizontal"===t.orientation?{x:c.x+o,y:c.y}:{x:c.x,y:c.y+o},h=`jumper_r${s}_c${a}`;e.push({jumperId:h,center:c,orientation:t.orientation,padCenters:[l,d]}),n.push({center:l,diameter:t.viaDiameter},{center:d,diameter:t.viaDiameter})}return{jumpers:e,vias:n,bounds:{minX:i-o-t.padWidth/2-t.boundsPadding,maxX:i+(t.cols-1)*t.pitchX+o+t.padWidth/2+t.boundsPadding,minY:r-o-t.padHeight/2-t.boundsPadding,maxY:r+(t.rows-1)*t.pitchY+o+t.padHeight/2+t.boundsPadding}}})(t),Dg=t=>({x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}),zg=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}],Fg=(t,e,n)=>Math.abs(t-e)<=n,Bg=(t,e,n)=>Fg(t.x,e.x,n)&&Fg(t.y,e.y,n),jg=t=>t.map((t,e)=>{const n=(t=>{let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t)r.x<e&&(e=r.x),r.y<n&&(n=r.y),r.x>o&&(o=r.x),r.y>i&&(i=r.y);return{minX:e,minY:n,maxX:o,maxY:i}})(t);return{regionId:`top_${e}`,ports:[],d:{bounds:n,center:Dg(n),polygon:t,isPad:!1}}}),$g=t=>{const e=t.end.x-t.start.x,n=t.end.y-t.start.y;return Math.hypot(e,n)},Yg=(t,e)=>({x:t.start.x+(t.end.x-t.start.x)*e,y:t.start.y+(t.end.y-t.start.y)*e}),Xg=(t,e,n)=>{const o=[];if(!t.d.polygon||!e.d.polygon)return o;for(let i=0;i<t.d.polygon.length;i++){const r=t.d.polygon[i],s=t.d.polygon[(i+1)%t.d.polygon.length];if(r&&s)for(let t=0;t<e.d.polygon.length;t++){const i=e.d.polygon[t],a=e.d.polygon[(t+1)%e.d.polygon.length];if(!i||!a)continue;const c=Gg({start:r,end:s},{start:i,end:a},n);if(!c)continue;o.some(t=>Hg(t,c,n))||o.push(c)}}return o},Vg=(t,e)=>{const n=[];for(const o of t){let t=o,i=!0;for(;i;){i=!1;for(let o=0;o<n.length;o++){const r=n[o];if(!r)continue;const s=Wg(t,r,e);if(s){t=s,n.splice(o,1),i=!0;break}}}n.push(t)}return n},Wg=(t,e,n)=>{const o=t.end.x-t.start.x,i=t.end.y-t.start.y,r=e.end.x-e.start.x,s=e.end.y-e.start.y,a=o**2+i**2;if(a<=n**2)return null;if(!Fg(o*s-i*r,0,n))return null;const c=e.start.x-t.start.x,l=e.start.y-t.start.y,d=e.end.x-t.start.x,h=e.end.y-t.start.y,u=o*h-i*d;if(!Fg(o*l-i*c,0,n)||!Fg(u,0,n))return null;const p=(c*o+l*i)/a,m=(d*o+h*i)/a,g=Math.min(p,m),f=Math.max(p,m),y=n/Math.sqrt(a);if(g>1+y||f<0-y)return null;const _=Math.min(0,g),b=Math.max(1,f);return{start:Yg(t,_),end:Yg(t,b)}},Hg=(t,e,n)=>Bg(t.start,e.start,n)&&Bg(t.end,e.end,n)||Bg(t.start,e.end,n)&&Bg(t.end,e.start,n),Gg=(t,e,n)=>{const o=t.end.x-t.start.x,i=t.end.y-t.start.y,r=e.end.x-e.start.x,s=e.end.y-e.start.y,a=o**2+i**2;if(a<=n**2)return null;if(!Fg(o*s-i*r,0,n))return null;const c=e.start.x-t.start.x,l=e.start.y-t.start.y,d=e.end.x-t.start.x,h=e.end.y-t.start.y,u=o*h-i*d;if(!Fg(o*l-i*c,0,n)||!Fg(u,0,n))return null;const p=(c*o+l*i)/a,m=(d*o+h*i)/a,g=Math.max(0,Math.min(p,m)),f=Math.min(1,Math.max(p,m));return f-g<=n/Math.sqrt(a)?null:{start:Yg(t,g),end:Yg(t,f)}},Ug=(t,e,n)=>{const o=Math.max(t.minX,e.minX),i=Math.min(t.maxX,e.maxX),r=Math.max(t.minY,e.minY),s=Math.min(t.maxY,e.maxY);return i<o-n||s<r-n?null:{minX:o,maxX:i,minY:r,maxY:s}},Zg=t=>{const e=(t=>{const e=t.orientation??Og.orientation,n=t.staggerAxis??Og.staggerAxis,o=t.padWidth??Og.padWidth,i=t.padHeight??Og.padHeight,r=t.padGap??Og.padGap,s=t.clearance??Og.clearance,a=t.colSpacing??t.pitchX??Og.pitchX,c=t.rowSpacing??t.pitchY??Og.pitchY,l=(d=o,h=i,u=r,"horizontal"===e?{x:u+2*d,y:h}:{x:h,y:u+2*d});var d,h,u;const p=s,m=((t,e,n,o,i)=>"horizontal"===t?"x"===e?i+2*n:o:"x"===e?o:i+2*n)(e,n,o,i,r)/2,g=t.staggerOffset??t.staggerOffsetX??m,f={...Og,...t,orientation:e,staggerAxis:n,pitchX:Math.max(a,l.x+p),pitchY:Math.max(c,l.y+p),padWidth:o,padHeight:i,padGap:r,staggerOffset:g,staggerOffsetX:g,concavityTolerance:t.concavityTolerance??Og.concavityTolerance,clearance:s,portSpacing:t.portSpacing??Og.portSpacing,maxNeckRatio:t.maxNeckRatio??Og.maxNeckRatio,minSplitBalanceRatio:t.minSplitBalanceRatio??Og.minSplitBalanceRatio};if(f.cols<=0||f.rows<=0)throw new Error("rows and cols must be > 0");if(!Number.isFinite(f.portSpacing)||f.portSpacing<=0)throw new Error("portSpacing must be > 0");if(!Number.isFinite(f.maxNeckRatio)||f.maxNeckRatio<0)throw new Error("maxNeckRatio must be >= 0");if(!Number.isFinite(f.minSplitBalanceRatio)||f.minSplitBalanceRatio<0||f.minSplitBalanceRatio>.5)throw new Error("minSplitBalanceRatio must be between 0 and 0.5");return f})(t),n=Lg(e),o="horizontal"===e.orientation?e.padWidth:e.padHeight,i="horizontal"===e.orientation?e.padHeight:e.padWidth,r=n.jumpers.flatMap(t=>t.padCenters.map(t=>({center:t,width:o,height:i,ccwRotation:0}))),s=new gg({bounds:n.bounds,rects:r,clearance:0,concavityTolerance:e.concavityTolerance});s.solve();const a=s.getOutput();if(!a)throw new Error(s.error??"ConvexRegionsSolver failed");const c=((t,e)=>{if(e.maxNeckRatio<=0)return t;const n=[];for(const o of t)n.push(...yg(o,e));return n})(a.regions,{maxNeckRatio:e.maxNeckRatio,minSplitBalanceRatio:e.minSplitBalanceRatio}),l=jg(c),d=((t,e)=>t.flatMap(t=>{const[n,o]=t.padCenters,i="horizontal"===e.orientation?e.padWidth/2:e.padHeight/2,r="horizontal"===e.orientation?e.padHeight/2:e.padWidth/2,s={minX:n.x-i,maxX:n.x+i,minY:n.y-r,maxY:n.y+r},a={minX:o.x-i,maxX:o.x+i,minY:o.y-r,maxY:o.y+r},c=i/2,l=r/2,d="horizontal"===e.orientation?{minX:Math.min(n.x,o.x),maxX:Math.max(n.x,o.x),minY:t.center.y-l,maxY:t.center.y+l}:{minX:t.center.x-c,maxX:t.center.x+c,minY:Math.min(n.y,o.y),maxY:Math.max(n.y,o.y)};return[{regionId:`${t.jumperId}_pad1`,ports:[],d:{bounds:s,center:n,polygon:zg(s),isPad:!0,isThroughJumper:!1}},{regionId:`${t.jumperId}_bridge`,ports:[],d:{bounds:d,center:t.center,polygon:zg(d),isPad:!1,isThroughJumper:!0}},{regionId:`${t.jumperId}_pad2`,ports:[],d:{bounds:a,center:o,polygon:zg(a),isPad:!0,isThroughJumper:!1}}]}))(n.jumpers,{orientation:e.orientation,padWidth:e.padWidth,padHeight:e.padHeight}),h=((t,e,n=1e-5)=>{const o=[];let i=0;for(let r=0;r<t.length;r++){const s=t[r];if(s?.d.polygon)for(let a=r+1;a<t.length;a++){const r=t[a];if(!r?.d.polygon)continue;const c=Xg(s,r,n);for(const t of c){const n=$g(t),a=Math.floor(n/e),c=Math.max(1,a-1);for(let e=0;e<c;e++){const n=Yg(t,(e+1)/(c+1));o.push({portId:"tp_"+i++,region1:s,region2:r,d:{x:n.x,y:n.y}})}}}}return o})(l,e.portSpacing),u=((t,e,n=1e-5)=>{const o=[];let i=0,r=0;const s=t.filter(t=>t.d.isPad),a=t.filter(t=>t.d.isThroughJumper&&!t.d.isPad);for(const t of s)for(const r of e){const e=Xg(t,r,n),s=Vg(e,n);for(const e of s){const n=Yg(e,.5);o.push({portId:"jp_"+i++,region1:t,region2:r,d:{x:n.x,y:n.y}})}}for(const t of a)for(const e of s){const i=Ug(t.d.bounds,e.d.bounds,n);if(!i)continue;const s=Dg(i);o.push({portId:"jip_"+r++,region1:e,region2:t,d:{x:s.x,y:s.y}})}return o})(d,l),p=[...h,...u];return(t=>{for(const e of t)e.region1.ports.push(e),e.region2.ports.push(e)})(p),{regions:[...l,...d],ports:p,jumperLocations:n.jumpers.map((t,e)=>({center:t.center,orientation:t.orientation,padRegions:[d[3*e],d[3*e+2]].filter(t=>Boolean(t))})),topLayerRegions:l,jumperRegions:d,jumpers:n.jumpers,vias:n.vias,bounds:n.bounds}},qg=class extends si{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 o=0;for(const i of Array.from(n))e[i]=t[o%t.length],o++;return e}_normalizeRegionPolygonsToBounds(t){for(const e of t.regions){const t=e.d,n=t?.polygon,o=t?.bounds;if(!n||0===n.length||!o)continue;let i=1/0,r=1/0;for(const t of n)i=Math.min(i,t.x),r=Math.min(r,t.y);const s=o.minX-i,a=o.minY-r;(Math.abs(s)>1e-12||Math.abs(a)>1e-12)&&(t.polygon=n.map(t=>({x:t.x+s,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,o){const i="horizontal"===e?t.rows:t.cols,r="horizontal"===e?t.cols:t.rows,s=o.maxX-o.minX,a=o.maxY-o.minY,c=.35,l=this.hyperParameters.TRACE_CHANNELS_BETWEEN_JUMPERS??1,d=this.traceWidth*l+2*this.obstacleMargin,h="horizontal"===e?2.15:1,u="horizontal"===e?1:2.15,p="horizontal"===e?"x":"y",m="staggered"===n,g=m&&"x"===p?h/2:m?u/2:0,f=Math.max(0,s-1),y=Math.max(0,a-1),_=Math.max(0,f-(m&&"x"===p?g:0)),b=Math.max(0,y-(m&&"y"===p?g:0)),x=i>1?Math.max(h+d,(_-h)/(i-1)):h,v=r>1?Math.max(u+d,(b-u)/(r-1)):u,S=Zg({cols:i,rows:r,orientation:e,pattern:n,staggerAxis:p,colSpacing:x,rowSpacing:v,padWidth:.9,padHeight:1,padGap:c,clearance:d,boundsPadding:0,maxNeckRatio:.4,minSplitBalanceRatio:.2}),I=S.bounds,C=(I.minX+I.maxX)/2,P=(I.minY+I.maxY)/2,M=k((o.minX+o.maxX)/2-C,(o.minY+o.maxY)/2-P);return this._normalizeRegionPolygonsToBounds(Oh(S,M))}_initializeGraph(){const t=this.nodeWithPortPoints,e=this._getPatternConfig(),n=this.hyperParameters.ORIENTATION??"vertical",o=this.hyperParameters.JUMPER_TYPE??"1206x4",i=this.hyperParameters.PATTERN??"grid",r={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 s;if(this.graphBounds=r,"0603"===o){const t=this._generate0603Grid(e,n,i,r);if(!t)return this.error=`0603 grid (${e.cols}x${e.rows}) is too large to fit in node bounds`,this.failed=!0,!1;s=t}else s=Vh({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:r});if(s.regions.length>0){let t=1/0,e=-1/0,n=1/0,i=-1/0;for(const o of s.regions){if(!o.d?.isPad)continue;const r=o.d?.bounds;r&&(t=Math.min(t,r.minX),e=Math.max(e,r.maxX),n=Math.min(n,r.minY),i=Math.max(i,r.maxY))}const a="0603"===o?.5:1;if(t-a<r.minX||e+a>r.maxX||n-a<r.minY||i+a>r.maxY)return this.error=`baseGraph bounds (${t.toFixed(2)}, ${n.toFixed(2)}, ${e.toFixed(2)}, ${i.toFixed(2)}) exceed node bounds (${r.minX.toFixed(2)}, ${r.minY.toFixed(2)}, ${r.maxX.toFixed(2)}, ${r.maxY.toFixed(2)})`,this.failed=!0,!1}this.jumperLocations=s.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],o=[...t.ports],i=[],r=mh(t.regions);for(const s of e){const{start:e,end:a,connectionId:c}=s,l=fh(`conn:${c}:start`,e.x,e.y);n.push(l);const d=fh(`conn:${c}:end`,a.x,a.y);n.push(d);const h=Sh(e.x,e.y,t.regions,r);if(h){const t=gh(`conn:${c}:start-port`,l,h.region,h.portPosition);o.push(t)}const u=Sh(a.x,a.y,t.regions,r);if(u){const t=gh(`conn:${c}:end-port`,d,u.region,u.portPosition);o.push(t)}const p={connectionId:c,mutuallyConnectedNetworkId:c,startRegion:l,endRegion:d};i.push(p)}return{regions:n,ports:o,connections:i}})(s,this.xyConnections);return this.jumperGraphSolver=new Yh({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??"",o=t.points.map(t=>({x:t.x,y:t.y})),i={path:o,start:o[0]??{x:0,y:0},end:o[o.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(i)}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,o=n.d.center;e.push({minX:t.minX,minY:t.minY,maxX:t.maxX,maxY:t.maxY,center:{x:o.x,y:o.y},networkIds:[]})}const n=new Map;for(let e=0;e<this.jumperGraphSolver.solvedRoutes.length;e++){const o=this.jumperGraphSolver.solvedRoutes[e],i=o.connection.connectionId,r=this.nodeWithPortPoints.portPoints.find(t=>t.connectionName===i)?.rootConnectionName,s=[],a=[];let c=null,l=null;for(let d=0;d<o.path.length;d++){const h=o.path[d],u=h.port,p=h.lastRegion,m=u.region1,g=u.region2;let f;if(p)m&&m.regionId!==p.regionId?f=m:g&&g.regionId!==p.regionId&&(f=g);else{const t=o.path[d+1],e=t?.lastRegion;if(e&&(m&&m.regionId===e.regionId?f=m:g&&g.regionId===e.regionId&&(f=g)),!f){const t=t=>t?.regionId?.startsWith("conn:");f=!m||t(m)||m.d?.isPad||m.d?.isThroughJumper?!g||t(g)||g.d?.isPad||g.d?.isThroughJumper?!m||m.d?.isPad||m.d?.isThroughJumper?(!g||g.d?.isPad||g.d?.isThroughJumper)&&m||g:m:g:m}}if(f&&(!c||f.regionId!==c.regionId)){if(c&&l){a.push({regionId:c.regionId,region:c,entryPort:l,exitPort:u});const t=c.regionId;n.has(t)||n.set(t,[]),n.get(t).push({regionId:c.regionId,region:c,routeIndex:e,connectionName:i,rootConnectionName:r,entryPort:l,exitPort:u})}c=f,l=u}if(p?.d?.isThroughJumper&&!t.has(p.regionId)){t.add(p.regionId);const e=p.d.bounds,n=p.d.center,o=e.maxX-e.minX>e.maxY-e.minY,i="0603"===(this.hyperParameters.JUMPER_TYPE??"1206x4")?"0603":"1206x4_pair";o?s.push({route_type:"jumper",start:{x:e.minX,y:n.y},end:{x:e.maxX,y:n.y},footprint:i}):s.push({route_type:"jumper",start:{x:n.x,y:e.minY},end:{x:n.x,y:e.maxY},footprint:i})}}if(c&&l){const t=o.path[o.path.length-1];a.push({regionId:c.regionId,region:c,entryPort:l,exitPort:t?.port||null})}this.routeInfos.push({connectionId:i,rootConnectionName:r,jumpers:s,traversals:a})}for(let t=0;t<this.routeInfos.length;t++){const n=this.routeInfos[t],o=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),i=Math.abs(n.center.y-t.y);e<.1&&i<.1&&(n.networkIds.includes(o)||n.networkIds.push(o))}}}for(const[t,o]of n){if(0===o.length)continue;const n=o[0].region;if(n.d.isPad||n.d.isThroughJumper)continue;const i=n.d.bounds,r=[];for(const t of o)r.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 s=.01,a=e.filter(t=>t.minX<=i.maxX+s&&t.maxX>=i.minX-s&&t.minY<=i.maxY+s&&t.maxY>=i.minY-s).map(t=>{const e=o.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:i,waypointPairs:r,obstacles:a,preferredTraceToTraceSpacing:2*this.traceWidth,preferredObstacleToTraceSpacing:2*this.traceWidth},l=new Cd(c);this.curvySolvers.push({solver:l,regionId:t,traversals:o.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],o=[];for(const e of n.traversals){const i=e.regionId,r=n.rootConnectionName??n.connectionId,s=this.regionCurvedPaths.get(i)?.get(r);let a=null;if(s&&s.length>0){const n={x:e.entryPort.d.x,y:e.entryPort.d.y},o=e.exitPort?{x:e.exitPort.d.x,y:e.exitPort.d.y}:null;let i=null,r=1/0;for(const e of s){const s=t(e.start,n)+(o?t(e.end,o):0);s<r&&(r=s,i=e)}i&&r<.5&&(a=i.path)}if(a&&a.length>0){for(let t=o.length>0?1:0;t<a.length;t++)o.push({x:a[t].x,y:a[t].y,z:0})}else 0===o.length&&o.push({x:e.entryPort.d.x,y:e.entryPort.d.y,z:0}),e.exitPort&&o.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:o,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 o=[n.start,n.end];for(const n of o){const o=`${n.x.toFixed(3)},${n.y.toFixed(3)}`,i=t.get(o)??[];e.rootConnectionName&&!i.includes(e.rootConnectionName)&&i.push(e.rootConnectionName),i.includes(e.connectionName)||i.push(e.connectionName),t.set(o,i)}}const e=this.hyperParameters.JUMPER_TYPE??"1206x4",n=Xo["0603"===e?"0603":"1206x4_pair"];for(const o of this.jumperLocations){const i="horizontal"===o.orientation,r=o.padRegions.map(e=>{const n=e.d.bounds,o=e.d.center,i=n.maxX-n.minX,r=n.maxY-n.minY,s=`${o.x.toFixed(3)},${o.y.toFixed(3)}`;return{type:"rect",center:o,width:i,height:r,layers:["top"],connectedTo:[...t.get(s)??[]]}}),s={jumper_footprint:e,center:o.center,orientation:o.orientation,width:i?n.length:n.width,height:i?n.width:n.length,pads:r};this.jumpers.push(s)}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 o=0;o<e.route.length-1;o++){const i=e.route[o],r=e.route[o+1];t.lines.push({points:[i,r],strokeColor:To(n,.2),strokeWidth:e.traceThickness,layer:"route-layer-0"})}for(const o of e.jumpers)this._drawJumperPads(t,o,To(n,.5))}return t}_drawJumperPads(t,e,n){const o=Xo[e.footprint],i=e.end.x-e.start.x,r=e.end.y-e.start.y,s=Math.abs(i)>Math.abs(r),a=s?o.padLength:o.padWidth,c=s?o.padWidth:o.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*o.padWidth,layer:"jumper-body"})}},Jg=class extends ys{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 o=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:o.cols,ROWS:o.rows,ORIENTATION:"vertical",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const i=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",2);t.push({name:"0603_max_rows_and_cols_vert_2trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:i.cols,ROWS:i.rows,ORIENTATION:"vertical",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const r=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:r.cols,ROWS:r.rows,ORIENTATION:"vertical",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const s=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",1);t.push({name:"0603_max_rows_and_cols_horz_1trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:s.cols,ROWS:s.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 l=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:l.cols,ROWS:l.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:o}=t,i=[1,2,4,6,8],r=[1,2,3,4,6,8,10],s=[1,2,3,4,8];return"0603"===e?i.includes(n)&&i.includes(o):"1206x4"===e&&(r.includes(n)&&s.includes(o))}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,o,i="grid"){const r=this.traceWidth*o+2*this.obstacleMargin,s="horizontal"===n?2.15:1,a="horizontal"===n?1:2.15,c="horizontal"===n?"x":"y",l="staggered"===i&&"x"===c?s/2:"staggered"===i?a/2:0,d=Math.max(0,t-1),h=Math.max(0,e-1),u=Math.max(0,d-("staggered"===i&&"x"===c?l:0)),p=Math.max(0,h-("staggered"===i&&"y"===c?l:0)),m=s+r,g=a+r,f=Math.max(1,Math.floor(1+(u-s)/m)),y=Math.max(1,Math.floor(1+(p-a)/g));return"vertical"===n?{cols:f,rows:y}:{cols:y,rows:f}}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_")),o=n.includes("1206x4");if(e&&!this.availableJumperTypes.includes("0603"))continue;if(o&&!this.availableJumperTypes.includes("1206x4"))continue;const i=this.getHyperParameterCombinations(t.filter(t=>n.includes(t.name)));for(const t of i){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 qg({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 Kg(t){return{connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,regionId:t.regionId,traceThickness:t.traceThickness,viaDiameter:0,route:t.route,vias:[],jumpers:t.jumpers}}var Qg=class extends si{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:o=.15,viaDiameter:i=.3,connMap:r,hyperParameters:s,capacityMeshNodes:a=[],capacityMeshEdges:c=[],availableJumperTypes:l}){super(),this.allNodes=[...t],this.colorMap=e??{},this.routes=[],this.traceWidth=n,this.obstacleMargin=o,this.viaDiameter=i,this.connMap=r,this.hyperParameters=s,this.capacityMeshNodes=a,this.capacityMeshEdges=c,this.availableJumperTypes=l??["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 d=1e3*this.nodesWithoutCrossings.length,h=1e5*this.nodesWithCrossings.length;this.MAX_ITERATIONS=d+h+100}_buildNodeAdjacencyMap(){const t=new Map;for(const e of this.capacityMeshEdges){const[n,o]=e.nodeIds;t.has(n)||t.set(n,new Set),t.has(o)||t.set(o,new Set),t.get(n).add(o),t.get(o).add(n)}return t}_analyzeNodes(){for(const t of this.allNodes){const e=Ms(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 o=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 i=n.center.x-n.width/2,r=n.center.y-n.height/2,s=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=o.get(t);e&&e.portPoints.length>0&&(c=e.portPoints[0].rootConnectionName??e.portPoints[0].connectionName)}e.push({minX:i,minY:r,maxX:s,maxY:a,networkId:c})}return e}_initializeCurvySolvers(){for(const t of this.nodesWithoutCrossings){const e=this._getAdjacentObstacles(t),n=new Pd({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),o=new Pd({nodeWithPortPoints:e,colorMap:this.colorMap,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter,adjacentObstacles:n});this.curvyIntraNodeSolvers[t]=o}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 Jg({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(Kg(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 o=this.jumperSolvers[this.currentJumperSolverIndex];return o&&(e+=o.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,o=mi(e.route,e.connectionName,this.colorMap[n]);for(const n of o)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:To(n.color??"gray",.75),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?"10, 5":void 0});for(const o of e.vias)t.circles.push({center:o,radius:e.viaDiameter/2,fill:To(this.colorMap[n]??"gray",.5),layer:"via"});if("jumpers"in e&&e.jumpers)for(const o of e.jumpers){const e=this.colorMap[n]??"gray",i=o.footprint??"1206",r=Xo[i],s=o.end.x-o.start.x,a=o.end.y-o.start.y,c=Math.abs(s)>Math.abs(a),l=c?r.padLength:r.padWidth,d=c?r.padWidth:r.padLength;t.rects.push({center:o.start,width:l,height:d,fill:To(e,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.rects.push({center:o.end,width:l,height:d,fill:To(e,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.lines.push({points:[o.start,o.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*r.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,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var ef=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.viaDiameter=Yo(t).padDiameter,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),r=n.targetMinCapacity??.5;n.capacityDepth=$s(i,r)}this.connMap=ii(t),this.colorMap=wo(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;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",ma,t=>[t.srj,t.colorMap,ri(t.srj)],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,this.connMap),t.connMap=ii(t.srjWithPointPairs)}}),tf("nodeSolver",Kn,t=>[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),tf("relateNodesToOffBoardConnections",Ll,t=>[{capacityMeshNodes:t.capacityNodes,srj:t.srj}],{onSolved:t=>{t.capacityNodes=t.relateNodesToOffBoardConnections?.getOutput().capacityNodes}}),tf("edgeSolver",ui,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),tf("availableSegmentPointSolver",ci,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),tf("portPointPathingSolver",ea,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])),o=t.availableSegmentPointSolver;for(const t of o.sharedEdgeSegments)for(const e of t.portPoints){const[o,i]=e.nodeIds,r={portPointId:e.segmentPortPointId,x:e.x,y:e.y,z:e.availableZ[0]??0,connectionNodeIds:[o,i],distToCentermostPortOnZ:e.distToCentermostPortOnZ,connectsToOffBoardNode:t.nodeIds.some(t=>n.get(t)?._offBoardConnectionId)},s=n.get(o);s&&s.portPoints.push(r)}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&&Xl({connMap:t.connMap,connectionsWithResults:e.connectionsWithResults,inputNodes:e.inputNodes,obstacles:t.srj.obstacles})}}),tf("highDensitySolver",Qg,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",Hl,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",kl,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(),o=this.singleLayerNodeMerger?.visualize(),i=this.strawSolver?.visualize(),r=this.edgeSolver?.visualize(),s=this.traceKeepoutSolver?.visualize(),a=this.deadEndSolver?.visualize(),c=this.availableSegmentPointSolver?.visualize(),l=this.offboardPathFragmentSolver?.visualize(),d=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),u=this.highDensityRouteSolver?.visualize(),p=this.highDensitySolver?.visualize(),m=this.simpleHighDensityRouteSolver?.visualize(),g=this.highDensityStitchSolver?.visualize(),f=this.traceSimplificationSolver?.visualize(),y=this.traceWidthSolver?.visualize(),_=this.srj.outline,b=[];if(b.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)"}),_&&_.length>=2){const t=_.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),b.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const x=Oo(this.srj),v={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,layer:Fo(e,this.srj.layerCount),label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).filter(t=>!t.isCopperPour).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)",layer:jo(t,this.srj.layerCount),label:x(t)}))],lines:b},S=[v,t,e,n,o,i,r,a,c,l,d,h,u?pi(v,u):null,p?pi(v,p):null,m?pi(v,m):null,g,f,s,y,this.solved?pi({lines:b},Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...S)}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 o=t[n];if(e.push({points:o.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[o.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.flatMap(t=>t.__rootConnectionNames??[t.name]));for(const[n,o]of this.srj.obstacles.entries()){if(!o.offBoardConnectsTo?.length)continue;const i=o.obstacleId??`__obs${n}`;o.obstacleId=i;const r=this.connMap.getNetConnectedToId(i);if(!r)continue;const s=this.connMap.getIdsConnectedToNet(r).find(t=>e.has(t));s&&(t[i]=s)}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 o=n.__netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.__netConnectionName,i=e.filter(t=>t.connectionName===n.name);for(let e=0;e<i.length;e++){const r=i[e],s={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount)};t.push(s)}}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}}},nf=t=>{const{candidates:e,mapOfCapacityMeshNodeIdToRef:n}=t;let o=!0;for(const t of e){let e=!1;t.port.nodeIds.forEach(t=>{const o=n.get(t);if(!o)throw new Error(`Could not find capacity mesh node for id ${t}`);o._containsObstacle&&(e=!0)}),e||(o=!1)}return o},of=t=>t.depth+1e3*t.countOfCrampedPortPointsInPath,rf=class extends kt{constructor(t){if(super(),this.input=t,this.input.depthLimit<1)throw new Error("Depth limit must be at least 1");this._setup()}input;queue=[];resultExploredPortPoints=[];currentExploredPortPoints=null;visitedExploredPortPoints=new Map;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},n=this.visitedExploredPortPoints.get(e);(!n||this.getCandidateCost(t)<this.getCandidateCost(n))&&(this.visitedExploredPortPoints.set(e,t),this.queue.push(t))}}_step(){if(0===this.queue.length)return this.currentExploredPortPoints=null,void(this.solved=!0);for(;this.queue.length>0;){this.currentExploredPortPoints=this.queue.shift();if(this.visitedExploredPortPoints.get(this.currentExploredPortPoints.port)!==this.currentExploredPortPoints)continue;if(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){if(this.input.shouldIgnoreCrampedPortPoints&&e.cramped)continue;const t={port:e,depth:this.currentExploredPortPoints.depth+1,parent:this.currentExploredPortPoints,countOfCrampedPortPointsInPath:this.currentExploredPortPoints.countOfCrampedPortPointsInPath+(e.cramped?1:0)},n=this.visitedExploredPortPoints.get(e);n&&this.getCandidateCost(n)<=this.getCandidateCost(t)||(this.visitedExploredPortPoints.set(e,t),this.queue.push(t))}}this.solved=!0}getCandidateCost(t){return t.depth+1e3*t.countOfCrampedPortPointsInPath}getOutput(){return this.resultExploredPortPoints}visualize(){const t={points:[],rects:[]};for(const e of this.visitedExploredPortPoints.keys())t.points.push({...e,color:e.cramped?"blue":"green"});return t}},sf=class extends kt{constructor(t){super(),this.input=t,this._setup()}input;unprocessedTargets=[];targetNode=[];currentTarget;crampedPortPointsToKeep=new Set;candidatesAtDepth=[];isRunningCrampedPass=!1;filteredOutput;activeSubSolver=null;nodeMap=new Map;mapOfCapacityMeshNodeIdToSegmentPortPoints=new Map;getSolverName(){return"multiTargetNecessaryCrampedPortPointSolver"}_setup(){this.targetNode=this.input.capacityMeshNodes.filter(t=>t._containsObstacle),this.targetNode=this.targetNode.filter(t=>{for(const e of this.input.simpleRouteJson.connections)for(const n of e.pointsToConnect)if(Be(n,t)<=0)return!0;return!1}),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 nf({candidates:this.candidatesAtDepth,mapOfCapacityMeshNodeIdToRef:this.nodeMap})||0===this.candidatesAtDepth.length?(this.isRunningCrampedPass=!0,void(this.activeSubSolver=new rf({target:this.currentTarget,depthLimit:3,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});if(nf({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)=>{const n=of(t)-of(e);return 0!==n?n:this.getCandidateExitCapacity(e)-this.getCandidateExitCapacity(t)}),0===this.candidatesAtDepth.length)this.error=`No candidates found for capacity mesh node ${this.currentTarget.capacityMeshNodeId} even after including cramped port points`;else{const t=new Map;for(const e of this.candidatesAtDepth){if(!e.parent)throw new Error(`Missing parent for cramped escape candidate ${e.port.segmentPortPointId}`);const n=`${e.parent.port.segmentPortPointId}->${e.port.segmentPortPointId}`;if(!t.has(n)&&(t.set(n,e),5===t.size))break}const e=[...t.values()];for(const t of e)this.keepCandidatePath(t)}return 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.filteredOutput||(this.filteredOutput=this.input.sharedEdgeSegments.map(t=>({...t,portPoints:t.portPoints.flatMap(t=>!t.cramped||this.crampedPortPointsToKeep.has(t)?[t]:this.isMultilayerEscapePort(t)?[{...t,tinyHypergraphPortPenalty:1e3}]:[])}))),this.filteredOutput}getCandidateExitCapacity(t){if(!t.parent)throw new Error(`Missing parent for cramped escape candidate ${t.port.segmentPortPointId}`);const e=new Set(t.parent.port.nodeIds),n=t.port.nodeIds.filter(t=>!e.has(t)).map(t=>{const e=this.nodeMap.get(t);if(!e)throw new Error(`Could not find capacity mesh node for id ${t}`);return e});if(0===n.length)throw new Error(`Could not find exit node for cramped escape candidate ${t.port.segmentPortPointId}`);return Math.max(0,...n.map(t=>t.width*t.height*t.availableZ.length))}keepCandidatePath(t){this.crampedPortPointsToKeep.add(t.port);let e=t.parent;for(;e;)this.crampedPortPointsToKeep.add(e.port),e=e.parent}isMultilayerEscapePort(t){return t.nodeIds.some(t=>(this.nodeMap.get(t)?.availableZ.length??0)>1)}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?At(t,this.activeSubSolver.visualize()):t}},af=t=>`${t.x.toFixed(4)},${t.y.toFixed(4)}`,cf=t=>!0===t.netIsAssignable&&(t.layers?.length??0)>1,lf=(t,e)=>t.connectedTo?.find(t=>t.startsWith("pcb_via"))??t.obstacleId??`assignable_via_${e}`,df=t=>[...new Set(t.obstacle.layers.map(e=>ko(e,t.layerCount)))].sort((t,e)=>t-e),hf=t=>af(t.center),uf=t=>new Set(t.filter(cf).map(hf));function pf(t,e){if(null==t)throw new Error(e)}function mf(t,e){const n=[];for(const o of t)e.includes(o)&&n.push(o);return n}function gf(t){if(Be(t.point,t.region.d)<=.001){if(mf(("layers"in t.point?t.point.layers:[t.point.layer]).map(e=>ko(e,t.layerCount)),t.region.d.availableZ).length>0)return!0}return!1}function ff({graph:t,point:e,layerCount:n}){const o=t.regions.filter(t=>gf({point:e,region:t,layerCount:n})),i=function({point:t,layerCount:e}){const n=("layers"in t?t.layers:[t.layer]).map(t=>ko(t,e));return[...new Set(n)]}({point:e,layerCount:n});return o.find(t=>function({region:t,pointZLayers:e}){return t.ports.some(t=>e.includes(t.d.z)&&mf(e,t.region1.d.availableZ).length>0&&mf(e,t.region2.d.availableZ).length>0)}({region:t,pointZLayers:i}))??o[0]}var yf=(t,e)=>{const n=t.getNetConnectedToId(e);if(!n)throw new Error(`Could not resolve net ID for connection "${e}"`);return n},_f=t=>{const e=t.graph.regions.filter(e=>e.d.availableZ.includes(t.z)&&!e.d._assignableVia).map(e=>({region:e,distance:Be(t.point,e.d)})).sort((t,e)=>t.distance-e.distance||t.region.d.width*t.region.d.height-e.region.d.width*e.region.d.height),n=e[0]?.distance;if(void 0===n)return[];const o=Math.max(n+1e-6,t.viaRadius+.15);return e.filter(t=>t.distance<=o).slice(0,4).map(t=>t.region)};function bf(t){const e={ports:[],regions:[]},n=[];for(const n of t.capacityMeshNodes){const o=n._connectedTo?.map(e=>yf(t.connectivityMap,e));e.regions.push({regionId:n.capacityMeshNodeId,d:o?{...n,_connectedTo:[...new Set(o)]}:n,ports:[]})}for(const n of t.segmentPortPoints){const[t,o]=n.nodeIds,i=e.regions.find(e=>e.regionId===t),r=e.regions.find(t=>t.regionId===o);pf(i,`Could not find region with id ${t} for segment port point ${n.segmentPortPointId}`),pf(r,`Could not find region with id ${o} for segment port point ${n.segmentPortPointId}`);for(const t of n.availableZ){const o=n._preloadedTracePortAssignments?.filter(e=>e.z===t),s={portId:`${n.segmentPortPointId}::${t}`,x:n.x,y:n.y,z:t,distToCentermostPortOnZ:n.distToCentermostPortOnZ,cramped:n.cramped,regions:[i,r],tinyHypergraphPortPenalty:n.tinyHypergraphPortPenalty,_preloadedFixedNetIds:o&&o.length>0?[...new Set(o.map(t=>t.fixedNetId))].sort():void 0,_preloadedTracePortAssignments:o},a={portId:n.segmentPortPointId,d:s,region1:i,region2:r};e.ports.push(a),i.ports.push(a),r.ports.push(a)}}(t=>{for(const[e,n]of t.assignableViaObstacles.entries()){if(!cf(n))continue;const o=df({obstacle:n,layerCount:t.layerCount});if(o.length<2)continue;const i=`assignable-via:${lf(n,e)}`,r=Math.min(n.width,n.height)/2,s={regionId:i,d:{capacityMeshNodeId:i,center:{...n.center},width:n.width,height:n.height,layer:`z${o.join(",")}`,availableZ:o,_containsObstacle:!1,_completelyInsideObstacle:!1,_containsTarget:!1,_assignableVia:!0,_assignedViaObstacle:n},ports:[]},a=[];for(const e of o)for(const o of _f({graph:t.graph,point:n.center,z:e,viaRadius:r})){const t={portId:`${i}:port:${o.regionId}:z${e}`,x:n.center.x,y:n.center.y,z:e,distToCentermostPortOnZ:0,cramped:!1,regions:[o,s]},r={portId:t.portId,d:t,region1:o,region2:s};a.push(r),o.ports.push(r)}if(new Set(a.map(t=>t.d.z)).size<2)for(const t of a)t.region1.ports=t.region1.ports.filter(e=>e!==t);else s.ports.push(...a),t.graph.regions.push(s),t.graph.ports.push(...a)}})({graph:e,assignableViaObstacles:t.assignableViaObstacles??[],layerCount:t.layerCount});for(const o of t.simpleRouteJsonConnections){const[i,r]=o.pointsToConnect,s=ff({graph:e,point:i,layerCount:t.layerCount}),a=ff({graph:e,point:r,layerCount:t.layerCount});pf(s,`Could not find start region for connection "${o.name}"`),pf(a,`Could not find end region for connection "${o.name}"`),n.push({connectionId:o.name,mutuallyConnectedNetworkId:yf(t.connectivityMap,o.name),startRegion:s,endRegion:a,simpleRouteConnection:o})}return{graph:e,connections:n}}function xf(t,e){const n={lines:[],points:[]};if(!t)return n;let o=t.shift();if(!o)return n;const i=[];n.points.push({...o.port.d,color:"rgb(255, 50, 50)",label:`g: ${o.g}\nh: ${o.h}\nf: ${o.f}\nripRequired: ${o.ripRequired}`});do{i.push({x:o.port.d.x,y:o.port.d.y,z:o.port.d.z}),o=o.parent}while(o);i.reverse();const r=i[0]?.z??0;i.unshift({x:e.x,y:e.y,z:r});for(let t=0;t<i.length-1;t++){const e=i[t],o=i[t+1];let r;r=e.z===o.z?0===e.z?void 0:"10 5":"3 3 10",n.lines.push({points:[{x:e.x,y:e.y},{x:o.x,y:o.y}],strokeColor:"rgba(255, 250, 50, 1)",strokeWidth:.01,strokeDash:r})}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 vf(t,e){const n={lines:[],points:[]};for(const o of t){const t=e[o.connection.connectionId]??"rgba(255, 50, 50, 1)",i=[{x:o.connection.startRegion.d.center.x,y:o.connection.startRegion.d.center.y,z:o.connection.startRegion.d?.availableZ?.[0]??0}];for(const t of o.path)i.push({x:t.port.d.x,y:t.port.d.y,z:t.port.d.z});i.push({x:o.connection.endRegion.d.center.x,y:o.connection.endRegion.d.center.y,z:o.connection.endRegion.d?.availableZ?.[0]??0});for(let e=0;e<i.length-1;e++){const o=i[e],r=i[e+1];let s;s=o.z===r.z?0===o.z?void 0:"10 5":"3 3 10";const a={points:[{x:o.x,y:o.y},{x:r.x,y:r.y}],strokeColor:t,strokeWidth:.01,strokeDash:s};n.lines.push(a)}}return n}function Sf(t,e){const n={lines:[],points:[]};for(const o of t){const t=o.startRegion.d.center,i=o.endRegion.d.center,r=(t.x+i.x)/2,s=(t.y+i.y)/2,a=e[o.connectionId]??"rgba(255, 50, 150, 0.8)";n.points.push({x:r,y:s,color:a,label:o.connectionId}),n.lines.push({points:[t,i],strokeColor:a,strokeWidth:.1,strokeDash:0===(o.startRegion.d?.availableZ?.[0]??0)?void 0:"10 5"})}return n}function If(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 Cf=class extends eh{constructor(t){super({inputConnections:t.connections,inputGraph:t.graph,inputSolvedRoutes:t.inputSolvedRoutes,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)}params;regionMemoryPfMap;baseRegionFailureCostMap;regionRipCountMap;totalRipCount;estimateCostToEnd(t){const e=this.currentEndRegion;return pf(e,"Current end region is undefined"),xe(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 o=this.estimateCostToEnd(t.port),i=(t.port.d.distToCentermostPortOnZ-this.params.weights.CENTER_OFFSET_FOCUS_SHIFT)*this.params.weights.CENTER_OFFSET_DIST_PENALTY_FACTOR,r=t.nextRegion?.regionId??t.lastRegion?.regionId,s=r?this.regionMemoryPfMap.get(r)??0:0;return o+i+this.computeMemoryPfPenalty(s)+this.computeDeviation(t)*this.params.weights.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){const o=this.currentConnection;pf(o,"Current connection is undefined");const i=this.getBaseRegionFailureCost(t),r=this.computeRegionPfWithAdditionalSegment(t,e,n,o.connectionId,o.mutuallyConnectedNetworkId);if(r>=this.NODE_MAX_PF)return this.params.weights.NODE_PF_MAX_PENALTY;const s=this.pfToFailureCost(r),a=Math.max(0,s-i);return Math.min(this.params.weights.NODE_PF_MAX_PENALTY,a*this.params.weights.NODE_PF_FACTOR)}computeG(t){const e=t;let n=super.computeG(t);return e.lastPort&&e.lastPort.d.z!==e.port.d.z&&(n+=this.params.weights.LAYER_CHANGE_COST),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 o=t.assignments??[];if(0===o.length)return[];return o.filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection?.mutuallyConnectedNetworkId&&(t.regionPort1!==e&&t.regionPort2!==e&&(t.regionPort1!==n&&t.regionPort2!==n&&fe(t.regionPort1.d,t.regionPort2.d,e.d,n.d))))}selectCandidatesForEnteringRegion(t){const e=this.currentConnection?.startRegion,n=this.currentConnection?.endRegion;pf(e,"Current connection or start region is undefined"),pf(n,"Current connection or end region is undefined");const o=t.filter(t=>{const o=t.nextRegion;return!o?.d._containsObstacle||(o===e||o===n)});let i=this.params.flags.FORCE_CENTER_FIRST?this.getCenterFirstEnteringRegionCandidates(o):o;const r=-this.params.weights.MIN_ALLOWED_BOARD_SCORE;if(r>0){const t=i.filter(t=>t.g+t.h<=r);t.length>0&&(i=t)}return i}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,...o]=this.unprocessedConnections;this.unprocessedConnections=[...o,n]}computeRoutesToRip(t){const e=super.computePortOverlapRoutes(t),n=new Set(e),o=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=o.get(t.lastRegion)??new Set;for(const t of e)n.add(t.solvedRoute);o.set(t.lastRegion,n)});const i=t.path.flatMap(t=>t.lastRegion?[t.lastRegion]:[]),r=Array.from(new Set([...o.keys(),...i])),s=this.params.weights.SHUFFLE_SEED+this.iterations+this.solvedRoutes.length+this.totalRipCount,a=Xi(r,s);for(const e of a){if(this.totalRipCount>=this.params.weights.MAX_RIPS)break;const o=this.getRegionRippingPfThreshold(e.regionId);let i=this.computeRegionPf({region:e,newlySolvedRoute:t,routesToRip:n});if(this.regionMemoryPfMap.set(e.regionId,i),i<=o)continue;const r=new Set;let a=0;for(;i>o&&!(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 o=e.assignments.map(e=>{const o=e.solvedRoute;return e.connection.connectionId===t.connection.connectionId?null:n.has(o)?void 0:o}).filter(t=>!!t);if(0===o.length)break;const c=Xi(o,s+a+r.size)[0];if(!c)break;r.add(c.connection),n.add(c),this.totalRipCount++,a++,this.regionRipCountMap.set(e.regionId,(this.regionRipCountMap.get(e.regionId)??0)+1),i=this.computeRegionPf({region:e,newlySolvedRoute:t,routesToRip:n}),this.regionMemoryPfMap.set(e.regionId,i)}}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 o=Math.max(1,Math.floor(this.params.weights.RANDOM_RIP_FRACTION*e.length)),i=Xi(e,s);let r=0;for(const t of i){if(r>=o)break;if(this.totalRipCount>=this.params.weights.MAX_RIPS)break;n.has(t)||(n.add(t),r++,this.totalRipCount++)}}return n}computeDeviation(t){const e=this.currentConnection?.startRegion.d.center,n=this.currentConnection?.endRegion.d.center;pf(e,"Current connection or start region is undefined"),pf(n,"Current connection or end region is undefined");return be(t.port.d,e,n)}computeDistanceTraveled(t){let e=0,n=t;for(;n?.parent;)e+=xe(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;pf(e,"Current connection is undefined"),pf(n,"Current end region is undefined");const o=e.endRegion.d.center,i={portId:`end-target:${e.connectionId}`,region1:n,region2:n,d:{portId:`end-target:${e.connectionId}`,x:o.x,y:o.y,z:t.port.d.z,distToCentermostPortOnZ:0,regions:[n,n]}};return this.computeIncreasedRegionCostIfPortsAreUsed(n,t.port,i)}getCenterFirstEnteringRegionCandidates(t){const e=new Map;for(const n of t){const t=n.port.d.z,o=e.get(t)??[];o.push(n),e.set(t,o)}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 o=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),i=[];let r=[];for(const t of o)this.isPortAvailableForCurrentNet(t.port)?r.push(t):r.length>0&&(i.push(r),r=[]);r.length>0&&i.push(r);for(const t of i)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},o=Ms(n),i=t.d;return Ys(i,o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.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),o=this.pfToFailureCost(n);return this.baseRegionFailureCostMap.set(t.regionId,o),o}getRegionAssignedPortPoints(t){return(t.assignments??[]).flatMap(t=>{const e=t.regionPort1.d,n=t.regionPort2.d,o=t.connection.connectionId,i=t.connection.simpleRouteConnection?.__rootConnectionNames?.[0];return[{x:e.x,y:e.y,z:e.z,connectionName:o,rootConnectionName:i},{x:n.x,y:n.y,z:n.z,connectionName:o,rootConnectionName:i}]})}computeRegionPfWithAdditionalSegment(t,e,n,o,i){const r=this.getRegionAssignedPortPoints(t),s=[{x:e.d.x,y:e.d.y,z:e.d.z,connectionName:o,rootConnectionName:i},{x:n.d.x,y:n.d.y,z:n.d.z,connectionName:o,rootConnectionName:i}],a={...t.d,portPoints:[...r,...s]},c=Ms(a);return Ys(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)),o=Math.min(1,e/n);return(this.params.weights.START_RIPPING_PF_THRESHOLD||.3)*(1-o)+(this.params.weights.END_RIPPING_PF_THRESHOLD||1)*o}computeRegionPf({region:t,newlySolvedRoute:e,routesToRip:n}){const o=[...(t.assignments??[]).filter(t=>!n.has(t.solvedRoute)).flatMap(t=>{const e=t.regionPort1,n=t.regionPort2,o=t.connection.connectionId,i=t.connection.simpleRouteConnection?.__rootConnectionNames?.[0];return[{x:e.d.x,y:e.d.y,z:e.d.z,connectionName:o,rootConnectionName:i},{x:n.d.x,y:n.d.y,z:n.d.z,connectionName:o,rootConnectionName:i}]}),...e.path.flatMap(n=>{if(!n.lastPort||n.lastRegion!==t)return[];const o=n.lastPort,i=n.port;return[{x:o.d.x,y:o.d.y,z:o.d.z,connectionName:e.connection.connectionId,rootConnectionName:e.connection.simpleRouteConnection?.__rootConnectionNames?.[0]},{x:i.d.x,y:i.d.y,z:i.d.z,connectionName:e.connection.connectionId,rootConnectionName:e.connection.simpleRouteConnection?.__rootConnectionNames?.[0]}]})],i={capacityMeshNodeId:t.d.capacityMeshNodeId,center:t.d.center,width:t.d.width,height:t.d.height,portPoints:o,availableZ:t.d.availableZ},r=Ms(i),s=t.d;return Ys(s,r.numSameLayerCrossings,r.numEntryExitLayerChanges,r.numTransitionPairCrossings)}computeNodePf(t){const e=this.getOutput().nodesWithPortPoints.find(e=>e.capacityMeshNodeId===t.capacityMeshNodeId),n=this.params.graph.regions.find(e=>e.d.capacityMeshNodeId===t.capacityMeshNodeId);if(!e||!n)return null;const o=Ms(e);return Ys(n.d,o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.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 o=n[0]?.port,i=n[n.length-1]?.port;if(!o||!i)continue;const r=t.connection.connectionId,s=t.connection,a=s.simpleRouteConnection?.__rootConnectionNames?.[0],c=t.connection.startRegion.regionId,l=t.connection.endRegion.regionId,d=e.get(c)??[];d.push({portPointId:o.d.portId,x:o.d.x,y:o.d.y,z:o.d.z,connectionName:r,rootConnectionName:a}),e.set(c,d);const h=e.get(l)??[];h.push({portPointId:i.d.portId,x:i.d.x,y:i.d.y,z:i.d.z,connectionName:r,rootConnectionName:a}),e.set(l,h)}const n=[],o=[];for(const i of this.params.graph.regions){const r=(i.assignments??[]).flatMap(t=>{const e=t.connection.connectionId,n=t.connection.simpleRouteConnection?.__rootConnectionNames?.[0];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,nextPortPointId:t.regionPort2.d.portId},{portPointId:t.regionPort2.d.portId,x:t.regionPort2.d.x,y:t.regionPort2.d.y,z:t.regionPort2.d.z,connectionName:e,rootConnectionName:n,prevPortPointId:t.regionPort1.d.portId}]}),s=[];if(i.d._containsObstacle&&t.has(i.regionId)){const t=e.get(i.regionId)??[],n=[];for(const e of t){r.some(t=>t.connectionName===e.connectionName&&t.rootConnectionName===e.rootConnectionName&&t.portPointId===e.portPointId)||n.push(e)}r.push(...n);const o=new Map;for(const t of r){const e=`${t.connectionName}::${t.rootConnectionName??""}`,n=o.get(e)??[];n.push(t),o.set(e,n)}for(const[t,e]of o.entries()){const[n,o=""]=t.split("::"),r=e[0];if(!r)continue;const a={portPointId:`center:${i.regionId}:${n}:${o}`,x:i.d.center.x,y:i.d.center.y,z:r.z,connectionName:n,rootConnectionName:o||void 0};if(e.length>=2){const t=e[e.length-1];r.portPointId&&(r.nextPortPointId=a.portPointId,a.prevPortPointId=r.portPointId),t.portPointId&&(t.prevPortPointId=a.portPointId,a.nextPortPointId=t.portPointId)}s.push(a)}}const a=[...r,...s];a.length>0&&n.push({capacityMeshNodeId:i.d.capacityMeshNodeId,center:i.d.center,width:i.d.width,height:i.d.height,portPoints:a,availableZ:i.d.availableZ});const c=i.ports.map(t=>{const e=t.d,n=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,prevPortPointId:e.prevPortPointId,nextPortPointId:e.nextPortPointId,connectionNodeIds:t.d.regions.map(t=>t.regionId),distToCentermostPortOnZ:t.d.distToCentermostPortOnZ,connectsToOffBoardNode:n}});o.push({capacityMeshNodeId:i.d.capacityMeshNodeId,center:i.d.center,width:i.d.width,height:i.d.height,portPoints:c,availableZ:i.d.availableZ,_containsObstacle:i.d._containsObstacle,_containsTarget:i.d._containsTarget,_offBoardConnectionId:i.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:i.d._offBoardConnectedCapacityMeshNodeIds})}return{nodesWithPortPoints:n,inputNodeWithPortPoints:o}}visualize(){return function(t){let e={};return e=t.reduce((t,e)=>t&&e?At(t,e):{},e),e||{}}([If(this.params.graph),this.visualizePfOverlay(),Sf(this.params.connections,this.params.colorMap??{}),xf(this.candidateQueue.peekMany(100),this.currentConnection?.startRegion.d.center),vf(this.solvedRoutes,this.params.colorMap??{})])}visualizePfOverlay(){const t=this.getOutput(),e=t?.inputNodeWithPortPoints??[],n=new Map((t?.nodesWithPortPoints??[]).map(t=>[t.capacityMeshNodeId,t])),o={rects:[]};for(const t of e){const e=this.computeNodePf(t),i=e??0,r=n.get(t.capacityMeshNodeId),s=r?Ms(r):{numSameLayerCrossings:0,numEntryExitLayerChanges:0,numTransitionPairCrossings:0},a=Math.min(255,Math.floor(512*i)),c=Math.max(0,255-Math.floor(512*i));let l=`rgba(${a}, ${c}, ${c}, ${i<.001?"0.1":"0.3"})`;t._containsObstacle&&(l="rgba(255, 0, 0, 0.3)"),t._offBoardConnectedCapacityMeshNodeIds?.length&&(l="rgba(255, 165, 0, 0.3)"),o.rects.push({center:t.center,width:t.width-.2,height:t.height-.2,layer:`z${t?.availableZ?.join(",")}`,fill:l,label:`${t.capacityMeshNodeId}\npf: ${null===e?"n/a":e.toFixed(3)}\nxSame: ${s.numSameLayerCrossings}, xLC: ${s.numEntryExitLayerChanges}, xTransition: ${s.numTransitionPairCrossings}`})}return o}},Pf=t=>{if(!t.assignments||0===t.assignments.length)return t.d?.assignment?0:1;const e=t.assignments.flatMap(t=>{const e=t.regionPort1.d,n=t.regionPort2.d,o=t.connection.connectionId,i=t.connection,r=i.simpleRouteConnection?.__rootConnectionNames?.[0];return[{x:e.x,y:e.y,z:e.z,connectionName:o,rootConnectionName:r},{x:n.x,y:n.y,z:n.z,connectionName:o,rootConnectionName:r}]}),n={...t.d,portPoints:e},o=Ms(n);return Ys(t.d,o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.numTransitionPairCrossings)};function Mf(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var Nf=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.viaDiameter=Yo(t).padDiameter,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),r=n.targetMinCapacity??.5;n.capacityDepth=$s(i,r)}this.connMap=ii(t),this.colorMap=wo(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;hyperGraphSectionOptimizer;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[Mf("netToPointPairsSolver",ga,t=>[t.srj,t.colorMap,ri(t.srj)],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,this.connMap),t.connMap=ii(t.srjWithPointPairs)}}),Mf("nodeSolver",Kn,t=>[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),Mf("edgeSolver",ui,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Mf("availableSegmentPointSolver",ci,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),Mf("necessaryCrampedPortPointSolver",sf,t=>[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),Mf("portPointPathingSolver",Cf,t=>{const e=t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=>t.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,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:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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("hyperGraphSectionOptimizer",Ih,t=>{const e=t.portPointPathingSolver;return[{hyperGraphSolver:e,inputSolvedRoutes:e.solvedRoutes,expansionHopsFromCentralRegion:1,createHyperGraphSolver:e=>new Cf({graph:e.inputGraph,connections:e.inputConnections,inputSolvedRoutes:e.inputSolvedRoutes,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:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}),regionCost:Pf,effort:t.effort,ACCEPTABLE_REGION_COST:.1,MAX_ATTEMPTS_PER_REGION:Math.max(3,3*t.effort),MAX_ATTEMPTS_PER_SECTION:Math.max(50,50*t.effort),FRACTION_TO_REPLACE:1,alwaysRipConflicts:!0}]}),Mf("uniformPortDistributionSolver",go,t=>[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),Mf("highDensityRouteSolver",zs,t=>[{nodePortPoints:t.uniformPortDistributionSolver?.getOutput()??[],nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=>[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth}]),Mf("highDensityStitchSolver",Ca,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),Mf("traceSimplificationSolver",vc,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",Ic,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(),o=this.singleLayerNodeMerger?.visualize(),i=this.strawSolver?.visualize(),r=this.edgeSolver?.visualize(),s=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.portPointPathingSolver?.visualize(),l=this.multiSectionPortPointOptimizer?.visualize(),d=this.uniformPortDistributionSolver?.visualize(),h=this.highDensityRouteSolver?.visualize(),u=this.highDensityStitchSolver?.visualize(),p=this.traceSimplificationSolver?.visualize(),m=this.necessaryCrampedPortPointSolver?.visualize(),g=this.highDensityRouteSolver?.visualize(),f=this.srj.outline,y=[];if(y.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]}),y.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const _=Oo(this.srj),b={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,layer:Fo(e,this.srj.layerCount),label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).filter(t=>!t.isCopperPour).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)",layer:jo(t,this.srj.layerCount),label:_(t)}))],lines:y},x=[b,t,e,n,o,i,r,s,a,m,c,g,l,d,h?pi(b,h):null,u,p,this.solved?pi({lines:y},Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...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 o=n.__netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.__netConnectionName,i=e.filter(t=>t.connectionName===n.name);for(let e=0;e<i.length;e++){const r=i[e],s={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount)};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},wf=class{MAX_ITERATIONS=1e3;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};pendingEffects;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:[]}}},Tf=(t,e)=>{const n=t=>" "===t||"\n"===t||"\r"===t||"\t"===t,o=t=>{let e=0,o=t.length;for(;e<o&&n(t[e]);)e+=1;for(;o>e&&n(t[o-1]);)o-=1;return t.slice(e,o)},i=t=>{const e=[];let n=0,i=0;for(let r=0;r<t.length;r+=1){const s=t[r];"("!==s?")"!==s?","===s&&0===i&&(e.push(o(t.slice(n,r))),n=r+1):i>0&&(i-=1):i+=1}return e.push(o(t.slice(n))),e},r=t=>{return`${e=t,Math.min(1,Math.max(0,e))}`;var e},s=(t=>{const e=o(t);if(!e.startsWith("#"))return null;const n=e.slice(1);if(3!==n.length&&6!==n.length)return null;for(const t of n){const e=t.toLowerCase();if(!(e>="0"&&e<="9")&&!(e>="a"&&e<="f"))return null}if(3===n.length){const[t,e,o]=n;return{r:Number.parseInt(t+t,16),g:Number.parseInt(e+e,16),b:Number.parseInt(o+o,16)}}return{r:Number.parseInt(n.slice(0,2),16),g:Number.parseInt(n.slice(2,4),16),b:Number.parseInt(n.slice(4,6),16)}})(e);if(s)return`rgba(${s.r}, ${s.g}, ${s.b}, ${r(1-t)})`;const a=(t=>{const e=o(t),n=e.indexOf("(");return n<=0||")"!==e[e.length-1]?null:{name:o(e.slice(0,n)).toLowerCase(),args:i(e.slice(n+1,-1))}})(e);if(!a)return e;const{name:c,args:l}=a;if("hsl"===c||"rgb"===c)return 3!==l.length?e:`${c}a(${l[0]}, ${l[1]}, ${l[2]}, ${r(1-t)})`;if("hsla"===c||"rgba"===c){if(4!==l.length)return e;const n=(t=>{const e=o(t);if(!e)return null;const n=Number.parseFloat(e);return Number.isFinite(n)?n:null})(l[3]);return null===n?e:`${c}(${l[0]}, ${l[1]}, ${l[2]}, ${r(n-t)})`}return e},Rf=(t,e)=>{try{return Tf(e,t)}catch(e){return console.error(e),t}},Ef=t=>t.rootConnectionName??t.connectionName,Af=t=>{const e=[];for(let n=0;n<t.route.length-1;n+=1){const o=t.route[n],i=t.route[n+1];if(!o||!i||o.z===i.z)continue;if(Math.abs(o.x-i.x)>1e-6||Math.abs(o.y-i.y)>1e-6)continue;const r={x:Math.round(1e3*o.x)/1e3,y:Math.round(1e3*o.y)/1e3},s=e.at(-1);s&&s.x===r.x&&s.y===r.y||e.push(r)}return e},Of=(t,e,n=.001)=>Math.abs(t.x-e.x)<=n&&Math.abs(t.y-e.y)<=n,kf=(t,e)=>({minX:t.center.x-t.width/2+e,maxX:t.center.x+t.width/2-e,minY:t.center.y-t.height/2+e,maxY:t.center.y+t.height/2-e}),Lf=(t,e)=>({x:t.x-e.x,y:t.y-e.y}),Df=(t,e)=>t.x*e.x+t.y*e.y,zf=(t,e,n)=>({x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n}),Ff=t=>{const e=[];for(let n=0;n<t.length;n+=1){const o=t[n];if(o)for(let t=0;t<o.route.length-1;t+=1){const i=o.route[t],r=o.route[t+1];i&&r&&(i.z!==r.z||Of(i,r)||e.push({routeIndex:n,rootConnectionName:Ef(o),startIndex:t,endIndex:t+1,start:i,end:r,z:i.z,traceRadius:(o.traceThickness??.1)/2}))}}return e},Bf=(t,e,n=1e-6)=>{const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=o*o+i*i;if(r<=n)return{x:e.start.x,y:e.start.y,t:0};const s=((t.x-e.start.x)*o+(t.y-e.start.y)*i)/r,a=(c=s,Math.max(0,Math.min(c,1)));var c;return{x:e.start.x+o*a,y:e.start.y+i*a,t:a}},jf=(t,e,n=1e-6)=>{const o=Lf(t.end,t.start),i=Lf(e.end,e.start),r=Lf(t.start,e.start),s=Df(o,o),a=Df(o,i),c=Df(i,i),l=Df(o,r),d=Df(i,r),h=s*c-a*a,u=n;let p,m,g=h,f=h;h<=u?(p=0,g=1,m=d,f=c):(p=a*d-c*l,m=s*d-a*l,p<0?(p=0,m=d,f=c):p>g&&(p=g,m=d+a,f=c)),m<0?(m=0,-l<0?p=0:-l>s?p=g:(p=-l,g=s)):m>f&&(m=f,-l+a<0?p=0:-l+a>s?p=g:(p=-l+a,g=s));const y=Math.abs(p)<=u?0:p/g,_=Math.abs(m)<=u?0:m/f,b=zf(t.start,t.end,y),x=zf(e.start,e.end,_),v=Bf(t.start,e,n),S=Bf(t.end,e,n),I=Bf(e.start,t,n),C=Bf(e.end,t,n);return[{leftT:y,rightT:_,leftPoint:b,rightPoint:x},{leftT:0,rightT:v.t,leftPoint:t.start,rightPoint:v},{leftT:1,rightT:S.t,leftPoint:t.end,rightPoint:S},{leftT:I.t,rightT:0,leftPoint:I,rightPoint:e.start},{leftT:C.t,rightT:1,leftPoint:C,rightPoint:e.end}].sort((t,e)=>Math.hypot(t.leftPoint.x-t.rightPoint.x,t.leftPoint.y-t.rightPoint.y)-Math.hypot(e.leftPoint.x-e.rightPoint.x,e.leftPoint.y-e.rightPoint.y))},$f=1e-6,Yf=t=>{const e=[];for(const n of t){const t=e[n.routeIndex]??[];t[n.startIndex]=n,e[n.routeIndex]=t}return e},Xf=(t,e)=>t<e?[t,e]:[e,t],Vf=(t,e)=>t.some(([t,n])=>t===e[0]&&n===e[1]),Wf=(t,e,n)=>{let o,i=Number.POSITIVE_INFINITY;for(const r of t){if(r.routeIndex!==e.routeIndex||r.z!==e.z||r.endIndex!==e.startIndex&&r.startIndex!==e.endIndex)continue;const[t]=jf(r,n);if(!t)continue;const s=Math.hypot(t.leftPoint.x-t.rightPoint.x,t.leftPoint.y-t.rightPoint.y);s>=i||(i=s,o=r)}return o},Hf=(t,e)=>{const n=Ff(e),o=Ff(t),i=Yf(o),r=[];for(let t=0;t<n.length;t+=1){const e=n[t];if(e)for(let s=t+1;s<n.length;s+=1){const t=n[s];if(!t||e.z!==t.z||e.rootConnectionName===t.rootConnectionName||Math.max(e.start.x,e.end.x)<Math.min(t.start.x,t.end.x)||Math.max(t.start.x,t.end.x)<Math.min(e.start.x,e.end.x)||Math.max(e.start.y,e.end.y)<Math.min(t.start.y,t.end.y)||Math.max(t.start.y,t.end.y)<Math.min(e.start.y,e.end.y))continue;const[a]=jf(e,t);if(!a||Math.hypot(a.leftPoint.x-a.rightPoint.x,a.leftPoint.y-a.rightPoint.y)>$f||a.leftT<=$f||a.leftT>=.999999||a.rightT<=$f||a.rightT>=.999999)continue;const c=i[e.routeIndex]?.[e.startIndex],l=i[t.routeIndex]?.[t.startIndex];if(!c||!l)continue;const[d]=jf(c,l);if(!d||Math.hypot(d.leftPoint.x-d.rightPoint.x,d.leftPoint.y-d.rightPoint.y)<=$f)continue;const h=Wf(o,c,l),u=Wf(o,l,c),p=h?[c,h]:[c],m=u?[l,u]:[l];for(const n of p)for(const o of m){const i={leftRouteIndex:e.routeIndex,leftStartPointIndex:n.startIndex,rightRouteIndex:t.routeIndex,rightStartPointIndex:o.startIndex};r.some(t=>t.leftRouteIndex===i.leftRouteIndex&&t.leftStartPointIndex===i.leftStartPointIndex&&t.rightRouteIndex===i.rightRouteIndex&&t.rightStartPointIndex===i.rightStartPointIndex)||r.push(i)}}}return r},Gf=t=>{const e=Ff(t),n=[];for(let t=0;t<e.length;t+=1){const o=e[t];if(o)for(let i=t+1;i<e.length;i+=1){const t=e[i];if(!t||o.z!==t.z||o.rootConnectionName===t.rootConnectionName)continue;const[r]=jf(o,t);if(!r)continue;if(Math.hypot(r.leftPoint.x-r.rightPoint.x,r.leftPoint.y-r.rightPoint.y)+$f<o.traceRadius+t.traceRadius){const e=Xf(o.routeIndex,t.routeIndex);Vf(n,e)||n.push(e)}}}return n},Uf=(t,e)=>e<=1||e>=t-2,Zf=(t,e)=>e.some(e=>Uf(t,e)),qf=.2,Jf=.4,Kf=.65+.05,Qf=.03,ty=1e3,ey=1e-6,ny=.015,oy=t=>Math.round(t*ty)/ty,iy=(t,e)=>({x:t.x-e.x,y:t.y-e.y}),ry=(t,e)=>({x:t.x*e,y:t.y*e}),sy=(t,e)=>t.x*e.x+t.y*e.y,ay=(t,e,n)=>({x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n}),cy=t=>Math.max(0,Math.min(t,1)),ly=(t,e,n)=>Math.max(e,Math.min(t,n)),dy=(t,e)=>{const n=(t=>Math.hypot(t.x,t.y))(t);return n<=e||n<=ey?t:ry(t,e/n)},hy=(t,e=0)=>({minX:t.center.x-t.width/2-e,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2-e,maxY:t.center.y+t.height/2+e}),uy=(t,e,n=0)=>{const o=hy(e,n);return t.x>=o.minX&&t.x<=o.maxX&&t.y>=o.minY&&t.y<=o.maxY},py=(t,e,n)=>{if(t.regionId){const n=e.findIndex(e=>e.capacityMeshNodeId===t.regionId);if(-1!==n)return n}const o=[...t.route.map(({x:t,y:e})=>({x:t,y:e})),...t.vias.map(({x:t,y:e})=>({x:t,y:e}))];let i=-1,r=Number.POSITIVE_INFINITY;for(let t=0;t<e.length;t++){const s=e[t];if(!s||!o.every(t=>uy(t,s,n)))continue;const a=s.width*s.height;a<r&&(r=a,i=t)}return i},my=(t,e,n,o)=>{const i=((t,e,n)=>{const o=Math.min(Math.abs(t.originalX-n.minX),Math.abs(n.maxX-t.originalX)),i=Math.min(Math.abs(t.originalY-n.minY),Math.abs(n.maxY-t.originalY));if(Math.abs(o-i)<=ey)return Math.abs(e.x-t.x)>=Math.abs(e.y-t.y)?"y":"x";return o<i?"y":"x"})(t,e,n);return dy("x"===i?{x:1.1*(t.x-e.x)*o,y:0}:{x:0,y:1.1*(t.y-e.y)*o},.06*o)},gy=(t,e,n,o,i=3.5,r=.2,s=.4)=>{const a=Math.max(t,0);if(a>=s)return 0;const c=a/r;if(c<1){const t=1-c;return e*t**3*(1+t*i)}const l=(a-r)/Math.max(s-r,ey),d=e*n*Math.exp(-l*o);return d<1e-5?0:d},fy=(t,e)=>{const n=t.boundaryPadding>0?.001:0,o=e.minX+t.boundaryPadding+n,i=e.maxX-t.boundaryPadding-n,r=e.minY+t.boundaryPadding+n,s=e.maxY-t.boundaryPadding-n;t.x=ly(t.x,o,i),t.y=ly(t.y,r,s)},yy=(t,e)=>{for(const n of t)for(const t of n.nodes)fy(t,e)},_y=t=>"via"===t.kind?.4:.25,by=t=>(t.kind,.5),xy=t=>"via"===t.kind?12:3.5,vy=t=>"via"===t.kind?.18:.06,Sy=t=>"via"===t.kind?1.35:1.05,Iy=(t,e)=>"via"===t.kind?3*e:e,Cy=(t,e,n,o)=>{const i=2*e;t[i]=(t[i]??0)+n,t[i+1]=(t[i+1]??0)+o},Py=(t,e,n,o,i,r)=>{if(t.fixed||Cy(o,t.node.forceIndex,e,n),!t.fixed&&i&&void 0!==r){const t=2*r;i[t]=(i[t]??0)+e,i[t+1]=(i[t+1]??0)+n}},My=(t,e,n,o,i=.5)=>{const{startNode:r,endNode:s}=t,a=1-cy(i),c=cy(i),l=r.fixed?0:a,d=s.fixed?0:c,h=l+d;if(!(h<=ey)){if(!r.fixed&&l>0){const t=l/h;Cy(o,r.forceIndex,e*t,n*t)}if(!s.fixed&&d>0){const t=d/h;Cy(o,s.forceIndex,e*t,n*t)}}},Ny=(t,e,n,o,i)=>{if(e.fixed)return{x:0,y:0};const{minX:r,maxX:s,minY:a,maxY:c}=t,l=(t=>"via"===t.kind?.65:qf)(e),d=(t=>"via"===t.kind?Kf:Jf)(e),h=(t=>"via"===t.kind?.015:.08)(e),u=(t=>"via"===t.kind?80:20)(e),p=xy(e);return{x:gy(n-r,Qf,h,u,p,l,d)*i-gy(s-n,Qf,h,u,p,l,d)*i,y:gy(o-a,Qf,h,u,p,l,d)*i-gy(c-o,Qf,h,u,p,l,d)*i}},wy=t=>{if(0===t.length)return null;const e=new Bt(t.length);for(const n of t){const{startNode:t,endNode:o}=n;e.add(Math.min(t.x,o.x),Math.min(t.y,o.y),Math.max(t.x,o.x),Math.max(t.y,o.y))}return e.finish(),{index:e,segments:t}},Ty=t=>{const e=new Map,n=new Map;for(const e of t){const t=n.get(e.z)??[];t.push(e),n.set(e.z,t)}for(const[t,o]of n){const n=wy(o);n&&e.set(t,n)}return{byLayer:e}},Ry=(t,e,n,o,i)=>{const r=t=>({candidateIndexes:t.index.search(n-i,o-i,n+i,o+i),segments:t.segments});if("point"===e.kind){const n=t.byLayer.get(e.z);return n?[r(n)]:[]}const s=[];for(const e of t.byLayer.values())s.push(r(e));return s},Ey=t=>{const e=[];for(let n=0;n<t.length;n+=1){const o=t[n];if(!o)continue;const i=new Set;for(let t=0;t<o.route.length-1;t+=1){const r=o.route[t],s=o.route[t+1];if(!r||!s)continue;if(r.z===s.z||!Of(r,s))continue;const a=[t,t+1];for(let e=t-1;e>=0;e-=1){const t=o.route[e];if(!t||!Of(t,r))break;a.push(e)}for(let e=t+2;e<o.route.length;e+=1){const t=o.route[e];if(!t||!Of(t,r))break;a.push(e)}const c=[...new Set(a)].sort((t,e)=>t-e);let l=!1;for(const t of c)if(i.has(t)){l=!0;break}if(!l){for(const t of c)i.add(t);e.push({routeIndex:n,rootConnectionName:Ef(o),pointIndexes:c,x:r.x,y:r.y,radius:(o.viaDiameter??.3)/2,movable:!Zf(o.route.length,c)})}}}return e},Ay=t=>{const{routes:e,via:n,dx:o,dy:i,node:r}=t;if(!n.movable)return!1;n.x+=o,n.y+=i,((t,e)=>{const n=kf(e,t.radius+ey);t.x=ly(t.x,n.minX,n.maxX),t.y=ly(t.y,n.minY,n.maxY)})(n,r);const s=e[n.routeIndex];if(!s)return!1;for(const t of n.pointIndexes){const e=s.route[t];e&&(e.x=n.x,e.y=n.y)}return!0},Oy=t=>{const{routes:e,node:n,vias:o}=t;let i=!1;for(let t=0;t<o.length;t+=1){const r=o[t];if(r)for(let s=t+1;s<o.length;s+=1){const a=o[s];if(!a)continue;const c=r.radius+a.radius+.1+ny,l=r.x-a.x,d=r.y-a.y,h=Math.hypot(l,d),u=c-h;if(u<=0)continue;const p=1.61803398875*(97*t+13*s),m=h>ey?l/h:Math.cos(p),g=h>ey?d/h:Math.sin(p),f=Number(r.movable)+Number(a.movable);if(0===f)continue;const y=Math.min(.04,u/f);i=Ay({routes:e,via:r,dx:m*y,dy:g*y,node:n})||i,i=Ay({routes:e,via:a,dx:-m*y,dy:-g*y,node:n})||i}}return i},ky=t=>{const{routes:e,node:n,vias:o,segments:i}=t;let r=!1;for(let t=0;t<o.length;t+=1){const s=o[t];if(s?.movable)for(const o of i){if(s.rootConnectionName===o.rootConnectionName)continue;const i=Bf(s,o),a=s.x-i.x,c=s.y-i.y,l=Math.hypot(a,c),d=s.radius+o.traceRadius+.1+ny-l;if(d<=0)continue;const h=o.end.x-o.start.x,u=o.end.y-o.start.y,p=Math.hypot(h,u),m=t%2==0?1:-1,g=l>ey?a/l:p>ey?-u/p*m:1,f=l>ey?c/l:p>ey?h/p*m:0,y=Math.min(.04,d);r=Ay({routes:e,via:s,dx:g*y,dy:f*y,node:n})||r}}return r},Ly=t=>{const{routes:e,routeIndex:n,pointIndex:o,dx:i,dy:r,node:s}=t,a=e[n];if(!a||o<=0||o>=a.route.length-1)return!1;const c=((t,e,n=.001)=>{const o=t[e];if(!o)return[];const i=[e];for(let r=e-1;r>=0;r-=1){const e=t[r];if(!e||!Of(e,o,n))break;i.push(r)}for(let r=e+1;r<t.length;r+=1){const e=t[r];if(!e||!Of(e,o,n))break;i.push(r)}return[...new Set(i)]})(a.route,o);if(Zf(a.route.length,c))return!1;const l=kf(s,ey);let d=!1;for(const t of c){const e=a.route[t];e&&(e.x=ly(e.x+i,l.minX,l.maxX),e.y=ly(e.y+r,l.minY,l.maxY),d=!0)}return d},Dy=t=>{const{routes:e,segment:n,dx:o,dy:i,node:r,t:s}=t,a=1-cy(s),c=cy(s),l=Ly({routes:e,routeIndex:n.routeIndex,pointIndex:n.startIndex,dx:o*a,dy:i*a,node:r}),d=Ly({routes:e,routeIndex:n.routeIndex,pointIndex:n.endIndex,dx:o*c,dy:i*c,node:r});return l||d},zy=t=>{const{routes:e,node:n,segments:o,movableRouteIndexes:i}=t;let r=!1;for(let t=0;t<o.length;t+=1){const s=o[t];if(s)for(let a=t+1;a<o.length;a+=1){const c=o[a];if(!c||s.z!==c.z||s.rootConnectionName===c.rootConnectionName)continue;const l=s.traceRadius+c.traceRadius+.1+ny;if(Math.max(s.start.x,s.end.x)+l<=Math.min(c.start.x,c.end.x)||Math.max(c.start.x,c.end.x)+l<=Math.min(s.start.x,s.end.x)||Math.max(s.start.y,s.end.y)+l<=Math.min(c.start.y,c.end.y)||Math.max(c.start.y,c.end.y)+l<=Math.min(s.start.y,s.end.y))continue;const[d]=jf(s,c);if(!d)continue;const h=d.leftPoint.x-d.rightPoint.x,u=d.leftPoint.y-d.rightPoint.y,p=Math.hypot(h,u),m=l-p;if(m<=0)continue;const g=!i||i.has(s.routeIndex),f=!i||i.has(c.routeIndex),y=Number(g)+Number(f);if(0===y)continue;const _=s.end.x-s.start.x,b=s.end.y-s.start.y,x=Math.hypot(_,b),v=(t+a)%2==0?1:-1,S=p>ey?h/p:x>ey?-b/x*v:1,I=p>ey?u/p:x>ey?_/x*v:0,C=Math.min(.025,m/y);g&&(r=Dy({routes:e,segment:s,dx:S*C,dy:I*C,node:n,t:d.leftT})||r),f&&(r=Dy({routes:e,segment:c,dx:-S*C,dy:-I*C,node:n,t:d.rightT})||r)}}return r},Fy=(t,e)=>{for(let n=0;n<10;n+=1){const n=Ey(e),o=Ff(e),i=Oy({routes:e,node:t,vias:n}),r=ky({routes:e,node:t,vias:n,segments:o}),s=zy({routes:e,node:t,segments:o});if(!i&&!r&&!s)break}for(const t of e)t.vias=Af(t);return e},By=(t,e,n)=>{for(let o=0;o<10;o+=1){if(!zy({routes:e,node:t,segments:Ff(e),movableRouteIndexes:n}))break}for(const t of n){const n=e[t];n&&(n.vias=Af(n))}return e},jy=(t,e,n,o,i,r=3,s=.02)=>{for(let a=0;a<r;a+=1){i.fill(0);const r=Ty(o);for(let t=0;t<n.length;t+=1){const e=n[t];if(!e||"via"!==e.kind)continue;const o=e.node;for(let r=t+1;r<n.length;r+=1){const c=n[r];if(!c||"via"!==c.kind)continue;if(e.rootConnectionName===c.rootConnectionName)continue;const l=c.node,d=o.x-l.x,h=o.y-l.y;if(Math.abs(d)>=qf||Math.abs(h)>=qf)continue;const u=Math.hypot(d,h),p=qf-u;if(p<=0)continue;let m=0,g=0;if(u>ey){const t=1/u;m=d*t,g=h*t}else{const e=1.61803398875*(1009*a+97*t+13*r);m=Math.cos(e),g=Math.sin(e)}const f=Math.min(s,.9*p),y=m*f,_=g*f;Py(e,y,_,i),Py(c,-y,-_,i)}}for(let t=0;t<n.length;t+=1){const e=n[t];if(!e)continue;const o=e.node,c=_y(e),l=Ry(r,e,o.x,o.y,c);for(const n of l)for(const r of n.candidateIndexes){const l=n.segments[r];if(!l)continue;if(e.rootConnectionName===l.rootConnectionName)continue;const{startNode:d,endNode:h}=l,u=h.x-d.x,p=h.y-d.y,m=u*u+p*p;if(m<=ey)continue;const g=o.x-d.x,f=o.y-d.y,y=cy((g*u+f*p)/m),_=d.x+u*y,b=d.y+p*y,x=o.x-_,v=o.y-b,S=Math.hypot(x,v),I=c-S;if(I<=0)continue;const C=1009*a+97*t+13*l.obstacleIndex;let P=0,M=0;if(S>ey){const t=1/S;P=x*t,M=v*t}else{const t=-p,e=u,n=Math.hypot(t,e);if(n>ey){const o=(C%2==0?1:-1)/n;P=t*o,M=e*o}else{const t=1.61803398875*C;P=Math.cos(t),M=Math.sin(t)}}const N=Math.min(Iy(e,s),I*Sy(e)),w=P*N,T=M*N;Py(e,w,T,i),My(l,-w,-T,i,y)}}for(let t=0;t<e.length;t+=1){const n=e[t];if(n)for(let t=0;t<n.nodes.length;t+=1){const e=n.nodes[t];if(!e||e.fixed)continue;const o=2*e.forceIndex;let r=i[o]??0,a=i[o+1]??0;const c=Math.hypot(r,a);if(c>s&&c>ey){const t=s/c;r*=t,a*=t}e.x+=r,e.y+=a}}yy(e,t)}},$y=(t,e,n,o)=>{const{mutableRoutes:i,totalNodeCount:r}=(t=>{let e=0;return{mutableRoutes:t.map(t=>{const n=[],o=new Int32Array(t.route.length);o.fill(-1);for(let i=0;i<t.route.length;i+=1){const r=t.route[i];if(!r)continue;const s=t.route[i-1],a=n.at(-1),c=n.length-1;a&&s&&s.x===r.x&&s.y===r.y?(s.z!==r.z&&(a.boundaryPadding=Math.max(a.boundaryPadding,t.viaDiameter/2)),a.pointIndexes.push(i),a.fixed||=Uf(t.route.length,i),o[i]=c):(n.push({x:r.x,y:r.y,originalX:r.x,originalY:r.y,boundaryPadding:0,pointIndexes:[i],fixed:Uf(t.route.length,i),forceIndex:e}),o[i]=n.length-1,e+=1)}return{route:t,rootConnectionName:t.rootConnectionName??t.connectionName,nodes:n,pointNodeIndexes:o}}),totalNodeCount:e}})(e),s=(t=>{const e=[];for(let n=0;n<t.length;n+=1){const o=t[n];if(o)for(let t=0;t<o.nodes.length;t+=1){const i=o.nodes[t],r=i?.pointIndexes[0],s=void 0===r?void 0:o.route.route[r];i&&s&&(i.pointIndexes.length>1?e.push({kind:"via",routeIndex:n,rootConnectionName:o.rootConnectionName,node:i,fixed:i.fixed}):e.push({kind:"point",routeIndex:n,rootConnectionName:o.rootConnectionName,node:i,z:s.z,fixed:i.fixed}))}}return e})(i),a=(t=>{const e=[];for(let n=0;n<t.length;n+=1){const o=t[n];if(o)for(let t=0;t<o.nodes.length-1;t+=1){const n=o.nodes[t],i=o.nodes[t+1],r=n?.pointIndexes[0],s=void 0===r?void 0:o.route.route[r];n&&i&&s&&e.push({obstacleIndex:e.length,rootConnectionName:o.rootConnectionName,z:s.z,startNode:n,endNode:i})}}return e})(i),c=new Float64Array(2*r),l=new Float64Array(2*r),d=o?.includeForceVectors??!0;yy(i,t);let h=[];for(let e=0;e<n;e+=1){const o=n<=1?0:e/Math.max(n-1,1),r=.25+.75*(1-o),u=1-o,p=d&&e===n-1,m=p?new Float64Array(2*s.length):void 0;c.fill(0);for(let t=0;t<s.length;t+=1){const e=s[t];if(!e||"via"!==e.kind)continue;const n=e.node;for(let o=t+1;o<s.length;o+=1){const i=s[o];if(!i||"via"!==i.kind)continue;if(e.rootConnectionName===i.rootConnectionName)continue;const a=i.node,l=n.x-a.x,d=n.y-a.y;if(Math.abs(l)>=Jf||Math.abs(d)>=Jf)continue;const h=Math.hypot(l,d);let u=0,p=0;if(h>ey){const t=1/h;u=l*t,p=d*t}else{const e=1.61803398875*(97*t+13*o);u=Math.cos(e),p=Math.sin(e)}const g=gy(h,.034,.08,18)*r;if(g<=0)continue;const f=u*g,y=p*g;Py(e,f,y,c,m,t),Py(i,-f,-y,c,m,o)}}const g=Ty(a);for(let t=0;t<s.length;t+=1){const e=s[t];if(!e)continue;const n=e.node,o=by(e),i=Ry(g,e,n.x,n.y,o);for(const s of i)for(const i of s.candidateIndexes){const a=s.segments[i];if(!a)continue;if(e.rootConnectionName===a.rootConnectionName)continue;const{startNode:l,endNode:d}=a,h=d.x-l.x,u=d.y-l.y,p=h*h+u*u;if(p<=ey)continue;const g=n.x-l.x,f=n.y-l.y,y=cy((g*h+f*u)/p),_=l.x+h*y,b=l.y+u*y,x=n.x-_,v=n.y-b,S=Math.hypot(x,v),I=97*t+13*a.obstacleIndex;let C=0,P=0;if(S>ey){const t=1/S;C=x*t,P=v*t}else{const t=-u,e=h,n=Math.hypot(t,e);if(n>ey){const o=(I%2==0?1:-1)/n;C=t*o,P=e*o}else{const t=1.61803398875*I;C=Math.cos(t),P=Math.sin(t)}}const M=gy(S,vy(e),.08,18,xy(e),_y(e),o)*r;if(M<=0)continue;const N=C*M,w=P*M;Py(e,N,w,c,m,t),My(a,-N,-w,c,y)}}p&&(h=new Array(s.length));for(let e=0;e<s.length;e+=1){const n=s[e];if(!n)continue;const o=n.node,i=Ny(t,n,o.x,o.y,r);if(Py(n,i.x,i.y,c,m,e),p&&m){const t=2*e;h[e]={kind:n.kind,routeIndex:n.routeIndex,rootConnectionName:n.rootConnectionName,x:o.x,y:o.y,dx:m[t]??0,dy:m[t+1]??0}}}for(let e=0;e<i.length;e+=1){const n=i[e];if(!n)continue;const o=n.nodes.length-2;for(let e=0;e<n.nodes.length;e+=1){const i=n.nodes[e];if(!i||i.fixed)continue;const s=2*i.forceIndex;let a=(c[s]??0)+.14*(i.originalX-i.x),l=(c[s+1]??0)+.14*(i.originalY-i.y),d=0,h=0,p=0,m=0;const g=n.nodes[e-1],f=n.nodes[e+1];if(g||f){let t=0,e=0,n=0;if(g&&(t+=g.x,e+=g.y,n+=1),f&&(t+=f.x,e+=f.y,n+=1),n>0){const o=1/n;a+=.22*(t*o-i.x),l+=.22*(e*o-i.y)}}if(g&&f&&u>0){const t=iy(f,g),e=sy(t,t);if(e>ey){const n=cy(sy(iy(i,g),t)/e),o=ay(g,f,n),r=dy(ry(iy(o,i),.55*u),.02*u);d=r.x,h=r.y}}if(u>0){if(1===e&&g?.fixed){const e=my(g,i,t,u);p+=e.x,m+=e.y}if(e===o&&f?.fixed){const e=my(f,i,t,u);p+=e.x,m+=e.y}}let y=.85*a*r,_=.85*l*r;const b=Math.hypot(y,_),x=.012*r;if(b>x&&b>ey){const t=x/b;y*=t,_*=t}i.x+=y+d+p,i.y+=_+h+m}}yy(i,t),jy(t,i,s,a,l,3,.02)}jy(t,i,s,a,l,8,.03);const u=(t=>t.map(({route:t,nodes:e,pointNodeIndexes:n})=>{const o=t.route.map((t,o)=>{const i=n[o]??-1,r=i>=0?e[i]:void 0;return r?{...t,x:oy(r.x),y:oy(r.y)}:t}),i={...t,route:o,vias:[]};return i.vias=Af(i),i}))(i);return{routes:u,forceVectors:h,stepsCompleted:n}},Yy=class extends wf{sampleEntries;originalHdRoutes;originalNodeWithPortPoints;colorMap;totalStepsPerNode;nodeAssignmentMargin;improvedRoutesByIndex=new Map;activeSampleIndex=0;latestVisualization={};constructor(t){super(),this.originalHdRoutes=t.hdRoutes,this.originalNodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.totalStepsPerNode=t.totalStepsPerNode??60,this.nodeAssignmentMargin=t.nodeAssignmentMargin??.2;const e=new Map;for(let n=0;n<t.hdRoutes.length;n++){const o=py(t.hdRoutes[n],t.nodeWithPortPoints,this.nodeAssignmentMargin);if(-1===o)continue;const i=e.get(o)??[];i.push(n),e.set(o,i)}this.sampleEntries=Array.from(e.entries()).map(([e,n])=>({node:t.nodeWithPortPoints[e],routeIndexes:n})),this.MAX_ITERATIONS=Math.max(10*this.sampleEntries.length,1e3),this.stats={nodeAssignmentMargin:this.nodeAssignmentMargin,sampleCount:this.sampleEntries.length,improvedNodeCount:0,improvedRouteCount:0,totalStepsPerNode:this.totalStepsPerNode}}getSolverName(){return"HighDensityForceImproveSolver"}getConstructorParams(){return[{nodeWithPortPoints:this.originalNodeWithPortPoints,hdRoutes:this.originalHdRoutes,totalStepsPerNode:this.totalStepsPerNode,nodeAssignmentMargin:this.nodeAssignmentMargin,colorMap:this.colorMap}]}_step(){const t=this.sampleEntries[this.activeSampleIndex];if(!t)return void(this.solved=!0);const e=hy(t.node),n=t.routeIndexes.map(t=>this.originalHdRoutes[t]),o=$y(e,n,this.totalStepsPerNode,{includeForceVectors:!0});Fy(t.node,o.routes);const i=Hf(n,o.routes);let r=0===i.length?o:$y(e,((t,e)=>{const{routes:n,node:o,selectors:i}=t,r=structuredClone(n),s=Ff(n),a=Yf(s),c=i.flatMap(t=>{const e=a[t.leftRouteIndex]?.[t.leftStartPointIndex],n=a[t.rightRouteIndex]?.[t.rightStartPointIndex];if(!e||!n)return[];const[o]=jf(e,n);if(!o)return[];const i=o.leftPoint.x-o.rightPoint.x,r=o.leftPoint.y-o.rightPoint.y,s=Math.hypot(i,r);return s<=$f?[]:[{selector:t,directionX:i/s,directionY:r/s,requiredDistance:e.traceRadius+n.traceRadius+.015}]});for(let t=0;t<3;t+=1){const t=Ff(r),n=Yf(t);for(const t of c){const i=n[t.selector.leftRouteIndex]?.[t.selector.leftStartPointIndex],s=n[t.selector.rightRouteIndex]?.[t.selector.rightStartPointIndex];if(!i||!s)continue;const[a]=jf(i,s);if(!a)continue;const c=(a.leftPoint.x-a.rightPoint.x)*t.directionX+(a.leftPoint.y-a.rightPoint.y)*t.directionY,l=t.requiredDistance-c;if(l<=0)continue;const d=Math.min(.025,l/2);e({routes:r,segment:i,dx:t.directionX*d,dy:t.directionY*d,node:o,t:a.leftT}),e({routes:r,segment:s,dx:-t.directionX*d,dy:-t.directionY*d,node:o,t:a.rightT})}}for(const t of r)t.vias=Af(t);return r})({routes:n,node:t.node,selectors:i},Dy),this.totalStepsPerNode,{includeForceVectors:!0});if(r!==o){Fy(t.node,r.routes);const e=Hf(n,r.routes);if(e.length>0){const o=((t,e)=>{const{originalRoutes:n,guardedRoutes:o,node:i,crossingSelectors:r,protectedSelectors:s}=t,a=Yf(Ff(n)),c=Yf(Ff(o)),l=Gf(o),d=s.map(({leftRouteIndex:t,rightRouteIndex:e})=>Xf(t,e)),h=kf(i,$f);for(const t of r){const r=c[t.leftRouteIndex]?.[t.leftStartPointIndex],s=c[t.rightRouteIndex]?.[t.rightStartPointIndex];if(!r||!s)continue;const[u]=jf(r,s);if(!(!u||Math.hypot(u.leftPoint.x-u.rightPoint.x,u.leftPoint.y-u.rightPoint.y)>$f||u.leftT<=$f||u.leftT>=.999999||u.rightT<=$f||u.rightT>=.999999))for(const r of["right","left"]){const s="left"===r?t.leftRouteIndex:t.rightRouteIndex,u="left"===r?t.leftStartPointIndex:t.rightStartPointIndex,p="left"===r?t.rightRouteIndex:t.leftRouteIndex,m="left"===r?t.rightStartPointIndex:t.leftStartPointIndex,g=n[s],f=o[s],y=a[p]?.[m],_=c[p]?.[m];if(!(g&&f&&y&&_))continue;const b=g.route[u]?.z,x=[];for(let t=u-2;t<=u+3;t+=1){const e=g.route[t];!e||t<=0||t>=g.route.length-1||e.z!==b||[g.route[t-1],g.route[t+1]].some(t=>t&&t.z!==e.z)||x.push(t)}if(0!==x.length)for(const[t,n]of[[y.start,_.start],[y.end,_.end]])for(const r of[1.51,1.25,1.75,2]){const a=[...o],c=structuredClone(f);a[s]=c;let u=!0;for(const e of x){const o=g.route[e],i=c.route[e];if(!o||!i)continue;const s=n.x+(o.x-t.x)*r,a=n.y+(o.y-t.y)*r;if(s<=h.minX||s>=h.maxX||a<=h.minY||a>=h.maxY){u=!1;break}i.x=s,i.y=a}if(!u)continue;c.vias=Af(c);let p=a,m=Gf(p);const y=new Set;for(const[t,e]of m)Vf(l,[t,e])||(t===s&&e!==s?y.add(e):e===s&&t!==s&&y.add(t));if(y.size>0){const t=e(i,structuredClone(a),y),n=Gf(t);d.every(t=>!Vf(n,t))&&n.length<m.length&&(p=t,m=n)}if(d.every(t=>!Vf(m,t))&&m.length<l.length)return p}}}})({originalRoutes:n,guardedRoutes:r.routes,node:t.node,crossingSelectors:e,protectedSelectors:[...i,...e]},By);o&&(r={...r,routes:o})}}for(let e=0;e<t.routeIndexes.length;e++)this.improvedRoutesByIndex.set(t.routeIndexes[e],r.routes[e]);this.latestVisualization=Xy({node:t.node,routes:r.routes,forceVectors:r.forceVectors,colorMap:this.colorMap}),this.activeSampleIndex+=1,this.stats={nodeAssignmentMargin:this.nodeAssignmentMargin,sampleCount:this.sampleEntries.length,improvedNodeCount:this.activeSampleIndex,improvedRouteCount:this.improvedRoutesByIndex.size,totalStepsPerNode:this.totalStepsPerNode},this.activeSampleIndex>=this.sampleEntries.length&&(this.solved=!0)}getOutput(){return this.originalHdRoutes.map((t,e)=>this.improvedRoutesByIndex.get(e)??t)}visualize(){return this.solved?Xy({routes:this.getOutput(),colorMap:this.colorMap}):this.latestVisualization}},Xy=t=>{const e=[],n=[],o=[];t.node&&o.push({center:t.node.center,width:t.node.width,height:t.node.height,stroke:"rgba(14,165,233,0.7)",fill:"rgba(14,165,233,0.04)",label:t.node.capacityMeshNodeId});for(const o of t.routes){const i=t.colorMap?.[o.connectionName]??"#0ea5e9";for(let t=0;t<o.route.length-1;t++){const n=o.route[t],r=o.route[t+1];n.z===r.z&&e.push({points:[{x:n.x,y:n.y},{x:r.x,y:r.y}],strokeColor:0===n.z?i:Rf(i,.5),strokeWidth:o.traceThickness,layer:`z${n.z}`,strokeDash:0!==n.z?[.1,.3]:void 0})}for(const t of o.vias)n.push({center:{x:t.x,y:t.y},radius:o.viaDiameter/2,stroke:i,fill:"rgba(14,165,233,0.12)"})}for(const n of t.forceVectors??[])e.push({points:[{x:n.x,y:n.y},{x:n.x+5*n.dx,y:n.y+5*n.dy}],strokeColor:"rgba(244,63,94,0.85)",strokeWidth:.06,strokeDash:[.08,.08]});return{lines:e,circles:n,rects:o}},Vy=(t,e)=>0===t?"top":t===e-1?"bottom":`inner${t}`,Wy=(t,e)=>{if(!Number.isInteger(e)||e<1)throw new Error(`Invalid board layer count: ${e}`);const n=Array.from({length:e},(t,n)=>Vy(n,e)),o=n.findIndex(e=>e===t.from_layer),i=n.findIndex(e=>e===t.to_layer);if(o<0||i<0)throw new Error(`Via span ${t.from_layer} -> ${t.to_layer} is outside the board`);return n.slice(Math.min(o,i),Math.max(o,i)+1)},Hy=.005,Gy=1e-6,Uy=(t,e)=>({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),Zy=t=>Uy({minX:Math.min(t.start.x,t.end.x),minY:Math.min(t.start.y,t.end.y),maxX:Math.max(t.start.x,t.end.x),maxY:Math.max(t.start.y,t.end.y)},t.width/2),qy=t=>{const e=t.diameter/2;return{minX:t.x-e,minY:t.y-e,maxX:t.x+e,maxY:t.y+e}},Jy=t=>We(E(t.localToWorld,[{x:-t.width/2,y:-t.height/2},{x:t.width/2,y:-t.height/2},{x:t.width/2,y:t.height/2},{x:-t.width/2,y:t.height/2}])),Ky=t=>({minX:-t.width/2,minY:-t.height/2,maxX:t.width/2,maxY:t.height/2}),Qy=(t,e)=>`${t}:${e}`,t_=class{constructor(t){this.cellSize=t}cellSize;cells=new Map;insert(t,e){const n=Math.floor(e.minX/this.cellSize),o=Math.floor(e.maxX/this.cellSize),i=Math.floor(e.minY/this.cellSize),r=Math.floor(e.maxY/this.cellSize);for(let e=n;e<=o;e+=1)for(let n=i;n<=r;n+=1){const o=Qy(e,n),i=this.cells.get(o);i?i.push(t):this.cells.set(o,[t])}}query(t){const e=Math.floor(t.minX/this.cellSize),n=Math.floor(t.maxX/this.cellSize),o=Math.floor(t.minY/this.cellSize),i=Math.floor(t.maxY/this.cellSize),r=new Set;for(let t=e;t<=n;t+=1)for(let e=o;e<=i;e+=1){const n=this.cells.get(Qy(t,e));if(n)for(const t of n)r.add(t)}return[...r]}},e_=(t,e)=>{const n=ve(t.start,t.end,e.start,e.end);if(n)return n;const o=[{left:t.start,right:ze(t.start,e.start,e.end)},{left:t.end,right:ze(t.end,e.start,e.end)},{left:ze(e.start,t.start,t.end),right:e.start},{left:ze(e.end,t.start,t.end),right:e.end}];let i={left:t.start,right:e.start},r=Number.POSITIVE_INFINITY;for(const t of o){const e=Math.hypot(t.left.x-t.right.x,t.left.y-t.right.y);e<r&&(i=t,r=e)}return{x:(i.left.x+i.right.x)/2,y:(i.left.y+i.right.y)/2}},n_=(t,e)=>{const n=ze(e,t.start,t.end);return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}},o_=(t,e)=>{const n=ze({x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},t.start,t.end),o=Math.max(e.minX,Math.min(e.maxX,n.x)),i=Math.max(e.minY,Math.min(e.maxY,n.y));return{x:(n.x+o)/2,y:(n.y+i)/2}},i_=t=>{const e=new Set;for(const n of t.route)"wire"===n.route_type&&(n.start_pcb_port_id&&e.add(n.start_pcb_port_id),n.end_pcb_port_id&&e.add(n.end_pcb_port_id));return[...e]},r_=(t,e,n)=>n<0?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,s_=class{constructor(t,e={}){if(this.srj=t,this.traceClearance=e.traceClearance??.1,this.viaClearance=Math.max(e.viaClearance??.1,.1),this.viaToPadClearance=e.viaToPadClearance??this.srj.minViaEdgeToPadEdgeClearance??.1,this.connMap=e.connMap,this.includeTraceViaOwnerMetadata=e.includeTraceViaOwnerMetadata??!1,this.cellSize=e.spatialCellSize??this.getDefaultSpatialCellSize(),!Number.isFinite(this.traceClearance)||this.traceClearance<0)throw new Error("traceClearance must be a non-negative finite number");if(!Number.isFinite(this.viaClearance))throw new Error("viaClearance must be a finite number");if(!Number.isFinite(this.viaToPadClearance)||this.viaToPadClearance<0)throw new Error("viaToPadClearance must be a non-negative finite number");if(!Number.isFinite(this.cellSize)||this.cellSize<=0)throw new Error("spatialCellSize must be a positive finite number");this.compileConnectionAliases(),this.obstacles=this.compileStaticObstacles(),this.indexStaticObstacles()}srj;traceClearance;viaClearance;viaToPadClearance;cellSize;connMap;includeTraceViaOwnerMetadata;canonicalNetByAlias=new Map;connMapNetByCanonicalNet=new Map;obstacles;obstacleIndexesByLayer=new Map;lastRunStats={traceCount:0,segmentCount:0,viaCount:0,obstacleCount:0,broadPhaseCandidateCount:0,exactCheckCount:0};getDefaultSpatialCellSize(){const t=Math.max(0,this.srj.bounds.maxX-this.srj.bounds.minX),e=Math.max(0,this.srj.bounds.maxY-this.srj.bounds.minY);return Math.max(.25,Math.max(t,e)/64,(this.srj.minViaDiameter??.3)+Math.max(this.traceClearance,this.viaToPadClearance))}compileConnectionAliases(){const t=new Map;for(const e of this.srj.connections){const n=e.netConnectionName??e.rootConnectionName??e.name,o=[e.name,e.rootConnectionName,e.netConnectionName,...e.mergedConnectionNames??[],...e.pointsToConnect.flatMap(t=>[t.pointId,t.pcb_port_id])];for(const e of o){if(!e)continue;this.canonicalNetByAlias.set(e,n);const o=this.connMap?.getNetConnectedToId(e);if(!o)continue;let i=t.get(n);i||(i=new Set,t.set(n,i)),i.add(o)}this.canonicalNetByAlias.set(n,n)}for(const[e,n]of t)1===n.size&&this.connMapNetByCanonicalNet.set(e,n.values().next().value)}resolveNetId(t){const e=this.connMap?.getNetConnectedToId(t);if(e)return e;const n=this.canonicalNetByAlias.get(t);return n?this.connMapNetByCanonicalNet.get(n)??n:t}areConnected(t,e){return t===e||(!!this.connMap?.areIdsConnected(t,e)||this.resolveNetId(t)===this.resolveNetId(e))}compileStaticObstacles(){const t=[],e=new Set,n=new Set;for(const o of this.srj.obstacles){if(0===o.layers.length)continue;const i=o.connectedTo.find(t=>t.startsWith("pcb_smtpad_")),r=o.connectedTo.find(t=>t.startsWith("pcb_plated_hole_")),s=o.connectedTo.find(t=>t.startsWith("pcb_port_"));if(!i&&!r&&!s)continue;const a=o.layers.length>1,c=a?"pcb_plated_hole":"pcb_smtpad",l=a?r??`pcb_plated_hole_${o.center.x.toFixed(3)}_${o.center.y.toFixed(3)}`:i??`pcb_smtpad_${o.center.x.toFixed(3)}_${o.center.y.toFixed(3)}`,d=a?n:e;if(d.has(l))continue;d.add(l);const h="number"==typeof o.ccwRotationDegrees&&Number.isFinite(o.ccwRotationDegrees),u=D(k(o.center.x,o.center.y),j(h?o.ccwRotationDegrees:0)),p=!h&&a&&Math.abs(o.width-o.height)<.001;t.push({kind:"obstacle",obstacleType:c,obstacleId:l,connectedTo:o.connectedTo,x:o.center.x,y:o.center.y,width:o.width,height:o.height,localToWorld:u,worldToLocal:A(u),...p?{radius:Math.max(o.width,o.height)/2}:{},layers:o.layers,...s?{pcbPortId:s}:{}})}return t}indexStaticObstacles(){for(const t of this.obstacles){const e=Uy(Jy(t),Math.max(this.traceClearance,this.viaToPadClearance));for(const n of t.layers){let o=this.obstacleIndexesByLayer.get(n);o||(o=new t_(this.cellSize),this.obstacleIndexesByLayer.set(n,o)),o.insert(t,e)}}}collectDynamicGeometry(t){const e=[],n=[],o=new Set;for(const i of t){const t=this.resolveNetId(i.connection_name),r=i_(i);for(let n=0;n<i.route.length-1;n+=1){const o=i.route[n],s=i.route[n+1];"wire"===o?.route_type&&"wire"===s?.route_type&&o.layer===s.layer&&(Math.abs(o.x-s.x)<=Gy&&Math.abs(o.y-s.y)<=Gy||e.push({kind:"trace_segment",order:e.length,traceId:i.pcb_trace_id,netId:t,start:{x:o.x,y:o.y},end:{x:s.x,y:s.y},width:a_(o,s),layer:o.layer,pcbPortIds:r}))}for(const e of i.route){if("via"!==e.route_type)continue;const r=`${e.x},${e.y},${e.from_layer},${e.to_layer}`;o.has(r)||(o.add(r),n.push({kind:"via",order:n.length,viaId:`via_${n.length}`,traceId:i.pcb_trace_id,netId:t,x:e.x,y:e.y,diameter:e.via_diameter??this.srj.minViaDiameter??.3,layers:Wy(e,this.srj.layerCount)}))}}return{segments:e,vias:n}}buildDynamicIndexes(t,e){const n=new Map,o=(t,e,o)=>{let i=n.get(t);i||(i=new t_(this.cellSize),n.set(t,i)),i.insert(e,Uy(o,this.traceClearance))};for(const e of t)o(e.layer,e,Zy(e));for(const t of e)for(const e of t.layers)o(e,t,qy(t));return n}obstacleSharesNet(t,e){return e.connectedTo.some(e=>this.areConnected(t,e))}checkTracePair(t,e){if(this.areConnected(t.netId,e.netId))return;this.lastRunStats.exactCheckCount+=1;const n=Oe(t.start,t.end,e.start,e.end)-t.width/2-e.width/2;if(n>this.traceClearance-Hy)return;const o=`overlap_${t.traceId}_${e.traceId}`;return{type:"pcb_trace_error",error_type:"pcb_trace_error",message:r_(t.traceId,`PCB trace ${e.traceId}`,n),pcb_trace_id:t.traceId,source_trace_id:"",pcb_trace_error_id:o,minimum_clearance:this.traceClearance,actual_clearance:n,pcb_component_ids:[],pcb_port_ids:[...new Set([...t.pcbPortIds,...e.pcbPortIds])],center:e_(t,e)}}checkTraceVia(t,e){if(this.areConnected(t.netId,e.netId))return;this.lastRunStats.exactCheckCount+=1;const n=De(t.start,t.end,{x:e.x,y:e.y,radius:e.diameter/2})-t.width/2;if(n>this.traceClearance-Hy)return;const o=`overlap_${t.traceId}_${e.viaId}`;return{type:"pcb_trace_error",error_type:"pcb_trace_error",message:r_(t.traceId,`pcb_via "${e.viaId}"`,n),pcb_trace_id:t.traceId,...this.includeTraceViaOwnerMetadata?{pcb_trace_ids:[t.traceId,e.traceId],pcb_via_id:e.viaId,pcb_via_ids:[e.viaId]}:{},source_trace_id:"",pcb_trace_error_id:o,minimum_clearance:this.traceClearance,actual_clearance:n,pcb_component_ids:[],pcb_port_ids:t.pcbPortIds,center:n_(t,e)}}checkTraceObstacle(t,e){if(this.obstacleSharesNet(t.netId,e))return;this.lastRunStats.exactCheckCount+=1;const n=Ky(e),o={...t,start:R(e.worldToLocal,t.start),end:R(e.worldToLocal,t.end)},i=(void 0===e.radius?ke(o.start,o.end,n):De(t.start,t.end,{x:e.x,y:e.y,radius:e.radius}))-t.width/2;if(i+Hy>=this.traceClearance)return;const r=`overlap_${t.traceId}_${e.obstacleId}`;return{type:"pcb_trace_error",error_type:"pcb_trace_error",message:r_(t.traceId,`${e.obstacleType} "${e.obstacleId}"`,i),pcb_trace_id:t.traceId,source_trace_id:"",pcb_trace_error_id:r,minimum_clearance:this.traceClearance,actual_clearance:i,pcb_component_ids:[],pcb_port_ids:[...new Set([...t.pcbPortIds,...e.pcbPortId?[e.pcbPortId]:[]])],center:void 0===e.radius?R(e.localToWorld,o_(o,n)):n_(t,e)}}checkViaObstacle(t,e){if(this.obstacleSharesNet(t.netId,e))return;this.lastRunStats.exactCheckCount+=1;const n=Ky(e),o=R(e.worldToLocal,t),i=(void 0===e.radius?Math.hypot(Math.max(n.minX-o.x,0,o.x-n.maxX),Math.max(n.minY-o.y,0,o.y-n.maxY)):Math.hypot(t.x-e.x,t.y-e.y)-e.radius)-t.diameter/2;if(i+Hy>=this.viaToPadClearance)return;const r=`via_pad_clearance_${t.viaId}_${e.obstacleId}`,s={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return{type:"pcb_pad_pad_clearance_error",error_type:"pcb_pad_pad_clearance_error",pcb_pad_pad_clearance_error_id:r,message:`pcb_via "${t.viaId}" and ${e.obstacleType} "${e.obstacleId}" are too close (gap: ${i.toFixed(3)}mm)`,pcb_trace_id:t.traceId,pcb_pad_ids:[t.viaId,e.obstacleId],pcb_via_ids:[t.viaId],minimum_clearance:this.viaToPadClearance,actual_clearance:i,center:s}}checkViaPairs(t){if(t.length<2)return[];const e=[],n=new t_(this.cellSize);for(const e of t)n.insert(e,Uy(qy(e),this.viaClearance));for(const o of t)for(const t of n.query(qy(o))){if(this.lastRunStats.broadPhaseCandidateCount+=1,t.order<=o.order)continue;this.lastRunStats.exactCheckCount+=1;const n=Math.hypot(o.x-t.x,o.y-t.y);if(n<=Gy)continue;const i=n-o.diameter/2-t.diameter/2;if(i+Hy>=this.viaClearance)continue;const r=this.areConnected(o.netId,t.netId),s=[o.viaId,t.viaId].sort().join("_"),a={x:(o.x+t.x)/2,y:(o.y+t.y)/2};e.push({type:"pcb_via_clearance_error",error_type:"pcb_via_clearance_error",pcb_error_id:`${r?"same_net":"different_net"}_vias_close_${s}`,message:`Vias ${o.viaId} and ${t.viaId}${r?"":" from different nets"} are too close together (gap: ${i.toFixed(3)}mm)`,pcb_via_ids:[o.viaId,t.viaId],...this.includeTraceViaOwnerMetadata?{pcb_trace_ids:[o.traceId,t.traceId]}:{},pcb_via_pair_net_relation:r?"same_net":"different_net",minimum_clearance:this.viaClearance,actual_clearance:i,pcb_center:a,center:a})}return e}evaluate(t){return this.evaluateInternal(t,!0)}evaluateLegacy(t){return this.evaluateInternal(t,!1)}evaluateInternal(t,e){const{segments:n,vias:o}=this.collectDynamicGeometry(t),i=this.buildDynamicIndexes(n,o),r=[],s=[];this.lastRunStats={traceCount:t.length,segmentCount:n.length,viaCount:o.length,obstacleCount:this.obstacles.length,broadPhaseCandidateCount:0,exactCheckCount:0};for(const t of n){const e=Zy(t),n=i.get(t.layer)?.query(e)??[],o=this.obstacleIndexesByLayer.get(t.layer)?.query(e)??[];for(const e of n){if(this.lastRunStats.broadPhaseCandidateCount+=1,"trace_segment"===e.kind&&e.order<=t.order)continue;const n="trace_segment"===e.kind?this.checkTracePair(t,e):this.checkTraceVia(t,e);n&&r.push(n)}for(const e of o){this.lastRunStats.broadPhaseCandidateCount+=1;const n=this.checkTraceObstacle(t,e);n&&r.push(n)}}const a=this.checkViaPairs(o);if(e)for(const t of o){const e=new Set;for(const n of t.layers){const o=this.obstacleIndexesByLayer.get(n)?.query(qy(t))??[];for(const n of o){if(e.has(n))continue;e.add(n),this.lastRunStats.broadPhaseCandidateCount+=1;const o=this.checkViaObstacle(t,n);o&&s.push(o)}}}const c=new Map;for(const t of r){const e=String(t.pcb_trace_error_id),n=c.get(e),o=Number(t.actual_clearance);if(!n){c.set(e,{...t,first_contact_center:t.center,first_contact_message:t.message,first_actual_clearance:o,worst_contact_center:t.center,worst_contact_message:t.message,worst_actual_clearance:o});continue}const i=Number(n.worst_actual_clearance);(o<i||!Number.isFinite(i))&&(n.worst_contact_center=t.center,n.worst_contact_message=t.message,n.worst_actual_clearance=o)}const l=[...c.values()].map(t=>({...t,center:"object"==typeof t.worst_contact_center?t.worst_contact_center:t.center,message:"string"==typeof t.worst_contact_message?t.worst_contact_message:t.message,actual_clearance:"number"==typeof t.worst_actual_clearance?t.worst_actual_clearance:t.actual_clearance}));l.push(...s),l.push(...a);const d=l.filter(t=>t.center);return{errors:l,errorsWithCenters:d,locationAwareErrors:d}}},a_=(t,e)=>t.width??e.width??.1,c_=[1,1.75,-1],l_=[1,1.75,-1],d_=8/3,h_=1e-6,u_=.001,p_=.14,m_=.035,g_=.015,f_=t=>t.minTraceToPadEdgeClearance??.16,y_=t=>t.minViaEdgeToPadEdgeClearance??.1,__=t=>Math.max(48,Math.round(48*Math.max(1,t))),b_=t=>t>=2?c_:l_;var x_=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 o=this.getNetConnectedToId(e);return!!o&&(n===o||o===t||o===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}},v_=t=>{const e=[];for(const n of t)if("source_trace"===n.type)e.push([n.source_trace_id,...n.connected_source_port_ids??[],...n.connected_source_net_ids??[]].filter(Boolean));else if("pcb_port"===n.type){const{pcb_port_id:t,source_port_id:o}=n;o&&t&&e.push([o,t])}else if("pcb_smtpad"===n.type){const{pcb_smtpad_id:t,pcb_port_id:o}=n;o&&t&&e.push([t,o])}else if("pcb_plated_hole"===n.type){const{pcb_plated_hole_id:t,pcb_port_id:o}=n;o&&t&&e.push([t,o])}else if("pcb_trace"===n.type){const{pcb_trace_id:t,source_trace_id:o}=n,i=Array.isArray(n.route)?n.route.filter(t=>t&&"wire"===t.route_type):[];if(o&&t&&e.push([t,o]),Array.isArray(i)){const n=i.find(t=>t?.start_pcb_port_id)?.start_pcb_port_id,o=i.find(t=>t?.end_pcb_port_id)?.end_pcb_port_id;n&&t&&o&&e.push([n,t,o])}}else if("pcb_via"===n.type){const{pcb_via_id:t,pcb_trace_id:o}=n;o&&t&&e.push([t,o])}else if("source_component"===n.type&&n.internally_connected_source_port_ids)for(const t of n.internally_connected_source_port_ids)e.push(t);const n=function(t){const e=new Map;let n=0;function o(t){for(const[,n]of e)if(n.has(t))return n;const o=new Set;return e.set("connectivity_net"+n++,o),o}for(const n of t){let t=null;for(const i of n){if(t){if(!t.has(i)){const n=o(i);if(n!==t){for(const e of n)t.add(e);e.delete(Array.from(e.entries()).find(([,t])=>t===n)[0])}}}else t=o(i);t.add(i)}}return Object.fromEntries(Array.from(e.entries()).map(([t,e])=>[t,Array.from(e)]))}(e);return new x_(n)},S_={};a(S_,{all_layers:()=>WS,any_circuit_element:()=>yM,any_soup_element:()=>_M,any_source_component:()=>DS,asset:()=>Ev,base_circuit_json_error:()=>Gv,battery_capacity:()=>Sv,brep_shape:()=>DI,cadModelDefaultDirectionMap:()=>GP,cad_component:()=>UP,cad_model_axis_directions:()=>HP,cad_model_formats:()=>WP,capacitance:()=>dv,circuit_json_footprint_load_error:()=>yP,current:()=>fv,distance:()=>gv,duration_ms:()=>yv,experiment_type:()=>iM,external_footprint_load_error:()=>fP,frequency:()=>mv,getZodPrefixedIdWithDefault:()=>wv,inductance:()=>hv,kicadAt:()=>Av,kicadEffects:()=>kv,kicadFont:()=>Ov,kicadFootprintAttributes:()=>zv,kicadFootprintMetadata:()=>jv,kicadFootprintModel:()=>Bv,kicadFootprintPad:()=>Fv,kicadFootprintProperties:()=>Dv,kicadProperty:()=>Lv,kicadSymbolEffects:()=>Xv,kicadSymbolMetadata:()=>Hv,kicadSymbolPinNames:()=>Yv,kicadSymbolPinNumbers:()=>$v,kicadSymbolProperties:()=>Wv,kicadSymbolProperty:()=>Vv,layer_ref:()=>GS,layer_string:()=>HS,length:()=>pv,manufacturing_drc_properties:()=>jI,ms:()=>bv,ninePointAnchor:()=>Tv,parseAndConvertSiUnit:()=>T_,pcbRenderLayer:()=>Rv,pcb_autorouting_error:()=>bP,pcb_board:()=>DC,pcb_breakout_point:()=>CP,pcb_component:()=>$I,pcb_component_invalid_layer_error:()=>LP,pcb_component_not_on_board_edge_error:()=>kP,pcb_component_outside_board_error:()=>OP,pcb_connector_not_in_accessible_orientation_warning:()=>SP,pcb_copper_pour:()=>AP,pcb_copper_pour_brep:()=>RP,pcb_copper_pour_polygon:()=>EP,pcb_copper_pour_rect:()=>TP,pcb_copper_text:()=>VC,pcb_courtyard_circle:()=>XP,pcb_courtyard_outline:()=>$P,pcb_courtyard_overlap_error:()=>aP,pcb_courtyard_pill:()=>VP,pcb_courtyard_polygon:()=>YP,pcb_courtyard_rect:()=>jP,pcb_cutout:()=>mP,pcb_cutout_circle:()=>hP,pcb_cutout_path:()=>pP,pcb_cutout_polygon:()=>uP,pcb_cutout_rect:()=>dP,pcb_fabrication_note_dimension:()=>tP,pcb_fabrication_note_path:()=>KC,pcb_fabrication_note_rect:()=>QC,pcb_fabrication_note_text:()=>JC,pcb_footprint_overlap_error:()=>sP,pcb_ground_plane:()=>PP,pcb_ground_plane_region:()=>MP,pcb_group:()=>_P,pcb_hole:()=>tC,pcb_hole_circle_or_square_shape:()=>GI,pcb_hole_circle_shape:()=>XI,pcb_hole_oval_shape:()=>ZI,pcb_hole_pill_shape:()=>JI,pcb_hole_rect_shape:()=>WI,pcb_hole_rotated_pill_shape:()=>QI,pcb_keepout:()=>cP,pcb_manual_edit_conflict_warning:()=>xP,pcb_missing_footprint_error:()=>gP,pcb_net:()=>kC,pcb_note_dimension:()=>rP,pcb_note_line:()=>iP,pcb_note_path:()=>oP,pcb_note_rect:()=>nP,pcb_note_text:()=>eP,pcb_pad_pad_clearance_error:()=>FP,pcb_pad_trace_clearance_error:()=>BP,pcb_panel:()=>zC,pcb_panelization_placement_error:()=>BC,pcb_placement_error:()=>FC,pcb_plated_hole:()=>aC,pcb_port:()=>cC,pcb_port_not_connected_error:()=>OC,pcb_port_not_matched_error:()=>AC,pcb_route_hint:()=>zI,pcb_route_hints:()=>FI,pcb_silkscreen_circle:()=>HC,pcb_silkscreen_graphic:()=>ZC,pcb_silkscreen_graphic_brep:()=>UC,pcb_silkscreen_line:()=>$C,pcb_silkscreen_oval:()=>GC,pcb_silkscreen_path:()=>YC,pcb_silkscreen_pill:()=>qC,pcb_silkscreen_rect:()=>WC,pcb_silkscreen_text:()=>XC,pcb_smtpad:()=>gC,pcb_smtpad_pill:()=>uC,pcb_solder_paste:()=>vC,pcb_text:()=>SC,pcb_thermal_spoke:()=>NP,pcb_trace:()=>NC,pcb_trace_error:()=>RC,pcb_trace_hint:()=>jC,pcb_trace_missing_error:()=>EC,pcb_trace_route_point:()=>MC,pcb_trace_route_point_through_pad:()=>PC,pcb_trace_route_point_via:()=>CC,pcb_trace_route_point_wire:()=>IC,pcb_trace_too_long_warning:()=>TC,pcb_trace_warning:()=>wC,pcb_via:()=>LC,pcb_via_clearance_error:()=>DP,pcb_via_trace_clearance_error:()=>zP,point:()=>Iv,point3:()=>Pv,point_with_bulge:()=>kI,port_arrangement:()=>cI,position:()=>Cv,position3:()=>Mv,resistance:()=>lv,ring:()=>LI,rotation:()=>vv,route_hint_point:()=>BI,schematic_arc:()=>gI,schematic_box:()=>oI,schematic_circle:()=>mI,schematic_component:()=>lI,schematic_component_port_arrangement_by_sides:()=>aI,schematic_component_port_arrangement_by_size:()=>sI,schematic_debug_line:()=>PI,schematic_debug_object:()=>NI,schematic_debug_object_base:()=>II,schematic_debug_point:()=>MI,schematic_debug_rect:()=>CI,schematic_error:()=>vI,schematic_group:()=>RI,schematic_layout_error:()=>SI,schematic_line:()=>uI,schematic_manual_edit_conflict_warning:()=>TI,schematic_net_label:()=>xI,schematic_path:()=>iI,schematic_pin_styles:()=>rI,schematic_port:()=>bI,schematic_rect:()=>pI,schematic_sheet:()=>OI,schematic_symbol:()=>hI,schematic_table:()=>EI,schematic_table_cell:()=>AI,schematic_text:()=>_I,schematic_trace:()=>fI,schematic_voltage_probe:()=>wI,simulation_ac_current_source:()=>nM,simulation_ac_voltage_source:()=>KP,simulation_current_probe:()=>hM,simulation_current_source:()=>oM,simulation_dc_current_source:()=>eM,simulation_dc_voltage_source:()=>JP,simulation_experiment:()=>sM,simulation_op_amp:()=>pM,simulation_oscilloscope_trace:()=>fM,simulation_spice_subcircuit:()=>mM,simulation_switch:()=>lM,simulation_transient_current_graph:()=>cM,simulation_transient_voltage_graph:()=>aM,simulation_unknown_experiment_error:()=>uM,simulation_voltage_probe:()=>dM,simulation_voltage_source:()=>QP,size:()=>Nv,source_ambiguous_port_reference:()=>XS,source_board:()=>YS,source_component_base:()=>Zv,source_component_internal_connection:()=>FS,source_component_misconfigured_error:()=>kS,source_component_pins_underspecified_warning:()=>QS,source_failed_to_create_component_error:()=>CS,source_group:()=>jS,source_i2c_misconfigured_error:()=>OS,source_interconnect:()=>AS,source_invalid_component_property_error:()=>PS,source_manually_placed_via:()=>ZS,source_missing_manufacturer_part_number_warning:()=>TS,source_missing_property_error:()=>IS,source_net:()=>$S,source_no_ground_pin_defined_warning:()=>KS,source_no_power_pin_defined_warning:()=>JS,source_part_not_found_warning:()=>nI,source_pcb_ground_plane:()=>VS,source_pin_attributes:()=>aS,source_pin_missing_trace_warning:()=>wS,source_pin_must_be_connected_error:()=>tI,source_port:()=>zS,source_project_metadata:()=>SS,source_property_ignored_warning:()=>NS,source_refdes_convention_warning:()=>RS,source_simple_ammeter:()=>sS,source_simple_battery:()=>cS,source_simple_capacitor:()=>qv,source_simple_chip:()=>nS,source_simple_connector:()=>mS,source_simple_crystal:()=>uS,source_simple_current_source:()=>iS,source_simple_diode:()=>Kv,source_simple_fiducial:()=>Qv,source_simple_fuse:()=>rS,source_simple_ground:()=>eS,source_simple_inductor:()=>lS,source_simple_led:()=>tS,source_simple_mosfet:()=>bS,source_simple_op_amp:()=>xS,source_simple_pin_header:()=>pS,source_simple_pinout:()=>gS,source_simple_potentiometer:()=>hS,source_simple_power_source:()=>oS,source_simple_push_button:()=>dS,source_simple_resistor:()=>Jv,source_simple_resonator:()=>fS,source_simple_switch:()=>vS,source_simple_test_point:()=>_S,source_simple_transistor:()=>yS,source_simple_voltage_probe:()=>ES,source_simple_voltage_source:()=>LS,source_trace:()=>BS,source_trace_not_connected_error:()=>MS,source_unnamed_trace_warning:()=>qS,spice_simulation_options:()=>rM,supplier_footprint_mismatch_warning:()=>IP,supplier_name:()=>Uv,time:()=>_v,timestamp:()=>xv,unknown_error_finding_part:()=>eI,visible_layer:()=>US,voltage:()=>uv,wave_shape:()=>ZP});var I_=t=>{const e=Math.round(1e3*t)/1e3;return`${Number(e.toFixed(3))}mm`},C_=new Map([["T",1e12],["G",1e9],["M",1e6],["K",1e3],["k",1e3],["",1],["m",.001],["µ",1e-6],["μ",1e-6],["u",1e-6],["n",1e-9],["p",1e-12],["f",1e-15]]),P_=[...C_.keys()];function M_(t){return C_.get(t)}var N_={Hz:{baseUnit:"Hz",variants:{MHz:1e6,kHz:1e3,Hz:1}},g:{baseUnit:"g",variants:{kg:1e3,g:1}},"Ω":{baseUnit:"Ω",variants:{"mΩ":.001,mohm:.001,mOhm:.001,milliohm:.001,"Ω":1,ohm:1,Ohm:1,"kΩ":1e3,"KΩ":1e3,kohm:1e3,kOhm:1e3,KOhm:1e3,Kohm:1e3,"MΩ":1e6,Mohm:1e6,MOhm:1e6,megohm:1e6,Megohm:1e6,"GΩ":1e9,Gohm:1e9,GOhm:1e9,"TΩ":1e12,Tohm:1e12,TOhm:1e12}},V:{baseUnit:"V",variants:{mV:.001,V:1,kV:1e3,KV:1e3,MV:1e6,GV:1e9,TV:1e12}},A:{baseUnit:"A",variants:{"µA":1e-6,"μA":1e-6,mA:.001,ma:.001,A:1,kA:1e3,MA:1e6}},F:{baseUnit:"F",variants:{pF:1e-12,nF:1e-9,"µF":1e-6,"μF":1e-6,uF:1e-6,mF:.001,F:1,kF:1e3,KF:1e3,MF:1e6}},H:{baseUnit:"H",variants:{pH:1e-12,nH:1e-9,"µH":1e-6,"μH":1e-6,uH:1e-6,mH:.001,H:1,kH:1e3,KH:1e3,MH:1e6}},ml:{baseUnit:"ml",variants:{ml:1,mL:1,l:1e3,L:1e3}},deg:{baseUnit:"deg",variants:{rad:180/Math.PI}},ms:{baseUnit:"ms",variants:{fs:1e-12,ps:1e-9,ns:1e-6,us:.001,"µs":.001,"μs":.001,ms:1,s:1e3}},mm:{baseUnit:"mm",variants:{nm:1e-6,"µm":.001,"μm":.001,um:.001,mm:1,cm:10,dm:100,m:1e3,km:1e6,in:25.4,ft:304.8,IN:25.4,FT:304.8,yd:914.4,mi:1609344,mil:.0254}}},w_=new Set;for(const[t,e]of Object.entries(N_)){w_.add(t);for(const t of Object.keys(e.variants))w_.add(t)}function T_(t,e){if(null==t)return{parsedUnit:null,unitOfValue:null,value:null};if("string"==typeof t&&t.match(/^-?[\d.]+$/))return{value:Number.parseFloat(t),parsedUnit:null,unitOfValue:null};if("number"==typeof t)return{value:t,parsedUnit:null,unitOfValue:null};if("object"==typeof t&&"x"in t&&"y"in t){const n=T_(t.x,e),o=T_(t.x,e),i=T_(t.y,e);return null===o.value||null===i.value?{parsedUnit:null,unitOfValue:null,value:null}:{parsedUnit:n.parsedUnit,unitOfValue:n.unitOfValue,value:{x:o.value,y:i.value}}}const n=t.toString().split("").reverse().join(""),o=n.match(/[^\d\s]+/)?.[0];if(!o)throw new Error(`Could not determine unit: "${t}"`);const i=o.split("").reverse().join(""),r=t.slice(0,-i.length),s=M_(i);if(e&&null!=s)return{parsedUnit:null,unitOfValue:e,value:Number.parseFloat(r)*s};if(null!=s&&!w_.has(i))return{parsedUnit:null,unitOfValue:null,value:Number.parseFloat(r)*s};const{baseUnit:a,conversionFactor:c}=function(t){for(const e of Object.values(N_)){if(t in e.variants)return{baseUnit:e.baseUnit,conversionFactor:e.variants[t]};for(const[n,o]of Object.entries(e.variants)){if(!t.endsWith(n))continue;const i=M_(t.slice(0,-n.length));if(null!=i)return{baseUnit:e.baseUnit,conversionFactor:i*o}}}return{baseUnit:t,conversionFactor:1}}(i);return{parsedUnit:i,unitOfValue:a,value:c*Number.parseFloat(r)}}var R_,E_,A_,O_=P_.filter(t=>""!==t).sort((t,e)=>e.length-t.length).map(t=>t.replace(/[.*+?^${}()|[\]\\]/g,"\\amp;")).join("|"),k_=(new RegExp(`^([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?)(?:(${O_}))?
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
),{});a(k_,{BRAND:()=\u003emx,DIRTY:()=\u003eJ_,EMPTY_PATH:()=\u003eW_,INVALID:()=\u003eq_,NEVER:()=\u003ecv,OK:()=\u003eK_,ParseStatus:()=\u003eZ_,Schema:()=\u003eab,ZodAny:()=\u003eBb,ZodArray:()=\u003eXb,ZodBigInt:()=\u003eOb,ZodBoolean:()=\u003ekb,ZodBranded:()=\u003egx,ZodCatch:()=\u003eux,ZodDate:()=\u003eLb,ZodDefault:()=\u003ehx,ZodDiscriminatedUnion:()=\u003eUb,ZodEffects:()=\u003ecx,ZodEnum:()=\u003erx,ZodError:()=\u003eB_,ZodFirstPartyTypeKind:()=\u003exx,ZodFunction:()=\u003eex,ZodIntersection:()=\u003eqb,ZodIssueCode:()=\u003ez_,ZodLazy:()=\u003enx,ZodLiteral:()=\u003eox,ZodMap:()=\u003eQb,ZodNaN:()=\u003epx,ZodNativeEnum:()=\u003esx,ZodNever:()=\u003e$b,ZodNull:()=\u003eFb,ZodNullable:()=\u003edx,ZodNumber:()=\u003eAb,ZodObject:()=\u003eWb,ZodOptional:()=\u003elx,ZodParsedType:()=\u003eL_,ZodPipeline:()=\u003efx,ZodPromise:()=\u003eax,ZodReadonly:()=\u003eyx,ZodRecord:()=\u003eKb,ZodSchema:()=\u003eab,ZodSet:()=\u003etx,ZodString:()=\u003eRb,ZodSymbol:()=\u003eDb,ZodTransformer:()=\u003ecx,ZodTuple:()=\u003eJb,ZodType:()=\u003eab,ZodUndefined:()=\u003ezb,ZodUnion:()=\u003eHb,ZodUnknown:()=\u003ejb,ZodVoid:()=\u003eYb,addIssueToContext:()=\u003eH_,any:()=\u003eOx,array:()=\u003ezx,bigint:()=\u003eNx,boolean:()=\u003ewx,coerce:()=\u003eav,custom:()=\u003ebx,date:()=\u003eTx,datetimeRegex:()=\u003eMb,defaultErrorMap:()=\u003ej_,discriminatedUnion:()=\u003e$x,effect:()=\u003eQx,enum:()=\u003eqx,function:()=\u003eGx,getErrorMap:()=\u003eX_,getParsedType:()=\u003eD_,instanceof:()=\u003eIx,intersection:()=\u003eYx,isAborted:()=\u003eQ_,isAsync:()=\u003enb,isDirty:()=\u003etb,isValid:()=\u003eeb,late:()=\u003eSx,lazy:()=\u003eUx,literal:()=\u003eZx,makeIssue:()=\u003eV_,map:()=\u003eWx,nan:()=\u003eMx,nativeEnum:()=\u003eJx,never:()=\u003eLx,null:()=\u003eAx,nullable:()=\u003eev,number:()=\u003ePx,object:()=\u003eFx,objectUtil:()=\u003eA_,oboolean:()=\u003esv,onumber:()=\u003erv,optional:()=\u003etv,ostring:()=\u003eiv,pipeline:()=\u003eov,preprocess:()=\u003env,promise:()=\u003eKx,quotelessJson:()=\u003eF_,record:()=\u003eVx,set:()=\u003eHx,setErrorMap:()=\u003eY_,strictObject:()=\u003eBx,string:()=\u003eCx,symbol:()=\u003eRx,transformer:()=\u003eQx,tuple:()=\u003eXx,undefined:()=\u003eEx,union:()=\u003ejx,unknown:()=\u003ekx,util:()=\u003eR_,void:()=\u003eDx}),(E_=R_||(R_={})).assertEqual=t=\u003e{},E_.assertIs=function(t){},E_.assertNever=function(t){throw new Error},E_.arrayToEnum=t=\u003e{const e={};for(const n of t)e[n]=n;return e},E_.getValidEnumValues=t=\u003e{const e=E_.objectKeys(t).filter(e=\u003e\"number\"!=typeof t[t[e]]),n={};for(const o of e)n[o]=t[o];return E_.objectValues(n)},E_.objectValues=t=\u003eE_.objectKeys(t).map(function(e){return t[e]}),E_.objectKeys=\"function\"==typeof Object.keys?t=\u003eObject.keys(t):t=\u003e{const e=[];for(const n in t)Object.prototype.hasOwnProperty.call(t,n)\u0026\u0026e.push(n);return e},E_.find=(t,e)=\u003e{for(const n of t)if(e(n))return n},E_.isInteger=\"function\"==typeof Number.isInteger?t=\u003eNumber.isInteger(t):t=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)\u0026\u0026Math.floor(t)===t,E_.joinValues=function(t,e=\" | \"){return t.map(t=\u003e\"string\"==typeof t?`'${t}'`:t).join(e)},E_.jsonStringifyReplacer=(t,e)=\u003e\"bigint\"==typeof e?e.toString():e,(A_||(A_={})).mergeShapes=(t,e)=\u003e({...t,...e});var L_=R_.arrayToEnum([\"string\",\"nan\",\"number\",\"integer\",\"float\",\"boolean\",\"date\",\"bigint\",\"symbol\",\"function\",\"undefined\",\"null\",\"array\",\"object\",\"unknown\",\"promise\",\"void\",\"never\",\"map\",\"set\"]),D_=t=\u003e{switch(typeof t){case\"undefined\":return L_.undefined;case\"string\":return L_.string;case\"number\":return Number.isNaN(t)?L_.nan:L_.number;case\"boolean\":return L_.boolean;case\"function\":return L_.function;case\"bigint\":return L_.bigint;case\"symbol\":return L_.symbol;case\"object\":return Array.isArray(t)?L_.array:null===t?L_.null:t.then\u0026\u0026\"function\"==typeof t.then\u0026\u0026t.catch\u0026\u0026\"function\"==typeof t.catch?L_.promise:\"undefined\"!=typeof Map\u0026\u0026t instanceof Map?L_.map:\"undefined\"!=typeof Set\u0026\u0026t instanceof Set?L_.set:\"undefined\"!=typeof Date\u0026\u0026t instanceof Date?L_.date:L_.object;default:return L_.unknown}},z_=R_.arrayToEnum([\"invalid_type\",\"invalid_literal\",\"custom\",\"invalid_union\",\"invalid_union_discriminator\",\"invalid_enum_value\",\"unrecognized_keys\",\"invalid_arguments\",\"invalid_return_type\",\"invalid_date\",\"invalid_string\",\"too_small\",\"too_big\",\"invalid_intersection_types\",\"not_multiple_of\",\"not_finite\"]),F_=t=\u003eJSON.stringify(t,null,2).replace(/\"([^\"]+)\":/g,\"$1:\"),B_=class t extends Error{get errors(){return this.issues}constructor(t){super(),this.issues=[],this.addIssue=t=\u003e{this.issues=[...this.issues,t]},this.addIssues=(t=[])=\u003e{this.issues=[...this.issues,...t]};const e=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,e):this.__proto__=e,this.name=\"ZodError\",this.issues=t}format(t){const e=t||function(t){return t.message},n={_errors:[]},o=t=\u003e{for(const i of t.issues)if(\"invalid_union\"===i.code)i.unionErrors.map(o);else if(\"invalid_return_type\"===i.code)o(i.returnTypeError);else if(\"invalid_arguments\"===i.code)o(i.argumentsError);else if(0===i.path.length)n._errors.push(e(i));else{let t=n,o=0;for(;o\u003ci.path.length;){const n=i.path[o];o===i.path.length-1?(t[n]=t[n]||{_errors:[]},t[n]._errors.push(e(i))):t[n]=t[n]||{_errors:[]},t=t[n],o++}}};return o(this),n}static assert(e){if(!(e instanceof t))throw new Error(`Not a ZodError: ${e}`)}toString(){return this.message}get message(){return JSON.stringify(this.issues,R_.jsonStringifyReplacer,2)}get isEmpty(){return 0===this.issues.length}flatten(t=t=\u003et.message){const e={},n=[];for(const o of this.issues)if(o.path.length\u003e0){const n=o.path[0];e[n]=e[n]||[],e[n].push(t(o))}else n.push(t(o));return{formErrors:n,fieldErrors:e}}get formErrors(){return this.flatten()}};B_.create=t=\u003enew B_(t);var j_=(t,e)=\u003e{let n;switch(t.code){case z_.invalid_type:n=t.received===L_.undefined?\"Required\":`Expected ${t.expected}, received ${t.received}`;break;case z_.invalid_literal:n=`Invalid literal value, expected ${JSON.stringify(t.expected,R_.jsonStringifyReplacer)}`;break;case z_.unrecognized_keys:n=`Unrecognized key(s) in object: ${R_.joinValues(t.keys,\", \")}`;break;case z_.invalid_union:n=\"Invalid input\";break;case z_.invalid_union_discriminator:n=`Invalid discriminator value. Expected ${R_.joinValues(t.options)}`;break;case z_.invalid_enum_value:n=`Invalid enum value. Expected ${R_.joinValues(t.options)}, received '${t.received}'`;break;case z_.invalid_arguments:n=\"Invalid function arguments\";break;case z_.invalid_return_type:n=\"Invalid function return type\";break;case z_.invalid_date:n=\"Invalid date\";break;case z_.invalid_string:\"object\"==typeof t.validation?\"includes\"in t.validation?(n=`Invalid input: must include \"${t.validation.includes}\"`,\"number\"==typeof t.validation.position\u0026\u0026(n=`${n} at one or more positions greater than or equal to ${t.validation.position}`)):\"startsWith\"in t.validation?n=`Invalid input: must start with \"${t.validation.startsWith}\"`:\"endsWith\"in t.validation?n=`Invalid input: must end with \"${t.validation.endsWith}\"`:R_.assertNever(t.validation):n=\"regex\"!==t.validation?`Invalid ${t.validation}`:\"Invalid\";break;case z_.too_small:n=\"array\"===t.type?`Array must contain ${t.exact?\"exactly\":t.inclusive?\"at least\":\"more than\"} ${t.minimum} element(s)`:\"string\"===t.type?`String must contain ${t.exact?\"exactly\":t.inclusive?\"at least\":\"over\"} ${t.minimum} character(s)`:\"number\"===t.type||\"bigint\"===t.type?`Number must be ${t.exact?\"exactly equal to \":t.inclusive?\"greater than or equal to \":\"greater than \"}${t.minimum}`:\"date\"===t.type?`Date must be ${t.exact?\"exactly equal to \":t.inclusive?\"greater than or equal to \":\"greater than \"}${new Date(Number(t.minimum))}`:\"Invalid input\";break;case z_.too_big:n=\"array\"===t.type?`Array must contain ${t.exact?\"exactly\":t.inclusive?\"at most\":\"less than\"} ${t.maximum} element(s)`:\"string\"===t.type?`String must contain ${t.exact?\"exactly\":t.inclusive?\"at most\":\"under\"} ${t.maximum} character(s)`:\"number\"===t.type?`Number must be ${t.exact?\"exactly\":t.inclusive?\"less than or equal to\":\"less than\"} ${t.maximum}`:\"bigint\"===t.type?`BigInt must be ${t.exact?\"exactly\":t.inclusive?\"less than or equal to\":\"less than\"} ${t.maximum}`:\"date\"===t.type?`Date must be ${t.exact?\"exactly\":t.inclusive?\"smaller than or equal to\":\"smaller than\"} ${new Date(Number(t.maximum))}`:\"Invalid input\";break;case z_.custom:n=\"Invalid input\";break;case z_.invalid_intersection_types:n=\"Intersection results could not be merged\";break;case z_.not_multiple_of:n=`Number must be a multiple of ${t.multipleOf}`;break;case z_.not_finite:n=\"Number must be finite\";break;default:n=e.defaultError,R_.assertNever(t)}return{message:n}},$_=j_;function Y_(t){$_=t}function X_(){return $_}var V_=t=\u003e{const{data:e,path:n,errorMaps:o,issueData:i}=t,r=[...n,...i.path||[]],s={...i,path:r};if(void 0!==i.message)return{...i,path:r,message:i.message};let a=\"\";const c=o.filter(t=\u003e!!t).slice().reverse();for(const t of c)a=t(s,{data:e,defaultError:a}).message;return{...i,path:r,message:a}},W_=[];function H_(t,e){const n=X_(),o=V_({issueData:e,data:t.data,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,n,n===j_?void 0:j_].filter(t=\u003e!!t)});t.common.issues.push(o)}var G_,U_,Z_=class t{constructor(){this.value=\"valid\"}dirty(){\"valid\"===this.value\u0026\u0026(this.value=\"dirty\")}abort(){\"aborted\"!==this.value\u0026\u0026(this.value=\"aborted\")}static mergeArray(t,e){const n=[];for(const o of e){if(\"aborted\"===o.status)return q_;\"dirty\"===o.status\u0026\u0026t.dirty(),n.push(o.value)}return{status:t.value,value:n}}static async mergeObjectAsync(e,n){const o=[];for(const t of n){const e=await t.key,n=await t.value;o.push({key:e,value:n})}return t.mergeObjectSync(e,o)}static mergeObjectSync(t,e){const n={};for(const o of e){const{key:e,value:i}=o;if(\"aborted\"===e.status)return q_;if(\"aborted\"===i.status)return q_;\"dirty\"===e.status\u0026\u0026t.dirty(),\"dirty\"===i.status\u0026\u0026t.dirty(),\"__proto__\"===e.value||void 0===i.value\u0026\u0026!o.alwaysSet||(n[e.value]=i.value)}return{status:t.value,value:n}}},q_=Object.freeze({status:\"aborted\"}),J_=t=\u003e({status:\"dirty\",value:t}),K_=t=\u003e({status:\"valid\",value:t}),Q_=t=\u003e\"aborted\"===t.status,tb=t=\u003e\"dirty\"===t.status,eb=t=\u003e\"valid\"===t.status,nb=t=\u003e\"undefined\"!=typeof Promise\u0026\u0026t instanceof Promise;(U_=G_||(G_={})).errToObj=t=\u003e\"string\"==typeof t?{message:t}:t||{},U_.toString=t=\u003e\"string\"==typeof t?t:t?.message;var ob=class{constructor(t,e,n,o){this._cachedPath=[],this.parent=t,this.data=e,this._path=n,this._key=o}get path(){return this._cachedPath.length||(Array.isArray(this._key)?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}},ib=(t,e)=\u003e{if(eb(e))return{success:!0,data:e.value};if(!t.common.issues.length)throw new Error(\"Validation failed but no issues detected.\");return{success:!1,get error(){if(this._error)return this._error;const e=new B_(t.common.issues);return this._error=e,this._error}}};function rb(t){if(!t)return{};const{errorMap:e,invalid_type_error:n,required_error:o,description:i}=t;if(e\u0026\u0026(n||o))throw new Error('Can\\'t use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.');if(e)return{errorMap:e,description:i};return{errorMap:(e,i)=\u003e{const{message:r}=t;return\"invalid_enum_value\"===e.code?{message:r??i.defaultError}:void 0===i.data?{message:r??o??i.defaultError}:\"invalid_type\"!==e.code?{message:i.defaultError}:{message:r??n??i.defaultError}},description:i}}var sb,ab=class{get description(){return this._def.description}_getType(t){return D_(t.data)}_getOrReturnCtx(t,e){return e||{common:t.parent.common,data:t.data,parsedType:D_(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}_processInputParams(t){return{status:new Z_,ctx:{common:t.parent.common,data:t.data,parsedType:D_(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}}_parseSync(t){const e=this._parse(t);if(nb(e))throw new Error(\"Synchronous parse encountered promise.\");return e}_parseAsync(t){const e=this._parse(t);return Promise.resolve(e)}parse(t,e){const n=this.safeParse(t,e);if(n.success)return n.data;throw n.error}safeParse(t,e){const n={common:{issues:[],async:e?.async??!1,contextualErrorMap:e?.errorMap},path:e?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)},o=this._parseSync({data:t,path:n.path,parent:n});return ib(n,o)}\"~validate\"(t){const e={common:{issues:[],async:!!this[\"~standard\"].async},path:[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)};if(!this[\"~standard\"].async)try{const n=this._parseSync({data:t,path:[],parent:e});return eb(n)?{value:n.value}:{issues:e.common.issues}}catch(t){t?.message?.toLowerCase()?.includes(\"encountered\")\u0026\u0026(this[\"~standard\"].async=!0),e.common={issues:[],async:!0}}return this._parseAsync({data:t,path:[],parent:e}).then(t=\u003eeb(t)?{value:t.value}:{issues:e.common.issues})}async parseAsync(t,e){const n=await this.safeParseAsync(t,e);if(n.success)return n.data;throw n.error}async safeParseAsync(t,e){const n={common:{issues:[],contextualErrorMap:e?.errorMap,async:!0},path:e?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)},o=this._parse({data:t,path:n.path,parent:n}),i=await(nb(o)?o:Promise.resolve(o));return ib(n,i)}refine(t,e){const n=t=\u003e\"string\"==typeof e||void 0===e?{message:e}:\"function\"==typeof e?e(t):e;return this._refinement((e,o)=\u003e{const i=t(e),r=()=\u003eo.addIssue({code:z_.custom,...n(e)});return\"undefined\"!=typeof Promise\u0026\u0026i instanceof Promise?i.then(t=\u003e!!t||(r(),!1)):!!i||(r(),!1)})}refinement(t,e){return this._refinement((n,o)=\u003e!!t(n)||(o.addIssue(\"function\"==typeof e?e(n,o):e),!1))}_refinement(t){return new cx({schema:this,typeName:xx.ZodEffects,effect:{type:\"refinement\",refinement:t}})}superRefine(t){return this._refinement(t)}constructor(t){this.spa=this.safeParseAsync,this._def=t,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this),this[\"~standard\"]={version:1,vendor:\"zod\",validate:t=\u003ethis[\"~validate\"](t)}}optional(){return lx.create(this,this._def)}nullable(){return dx.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return Xb.create(this)}promise(){return ax.create(this,this._def)}or(t){return Hb.create([this,t],this._def)}and(t){return qb.create(this,t,this._def)}transform(t){return new cx({...rb(this._def),schema:this,typeName:xx.ZodEffects,effect:{type:\"transform\",transform:t}})}default(t){const e=\"function\"==typeof t?t:()=\u003et;return new hx({...rb(this._def),innerType:this,defaultValue:e,typeName:xx.ZodDefault})}brand(){return new gx({typeName:xx.ZodBranded,type:this,...rb(this._def)})}catch(t){const e=\"function\"==typeof t?t:()=\u003et;return new ux({...rb(this._def),innerType:this,catchValue:e,typeName:xx.ZodCatch})}describe(t){return new(0,this.constructor)({...this._def,description:t})}pipe(t){return fx.create(this,t)}readonly(){return yx.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}},cb=/^c[^\\s-]{8,}$/i,lb=/^[0-9a-z]+$/,db=/^[0-9A-HJKMNP-TV-Z]{26}$/i,hb=/^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i,ub=/^[a-z0-9_-]{21}$/i,pb=/^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$/,mb=/^[-+]?P(?!$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??$/,gb=/^(?!\\.)(?!.*\\.\\.)([A-Z0-9_'+\\-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i,fb=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,yb=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/(3[0-2]|[12]?[0-9])$/,_b=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,bb=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,xb=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,vb=/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,Sb=\"((\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\\\d|30)|(02)-(0[1-9]|1\\\\d|2[0-8])))\",Ib=new RegExp(`^${Sb}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
);function Cb(t){let e=\"[0-5]\\\\d\";t.precision?e=`${e}\\\\.\\\\d{${t.precision}}`:null==t.precision\u0026\u0026(e=`${e}(\\\\.\\\\d+)?`);return`([01]\\\\d|2[0-3]):[0-5]\\\\d(:${e})${t.precision?\"+\":\"?\"}`}function Pb(t){return new RegExp(`^${Cb(t)}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
)}function Mb(t){let e=`${Sb}T${Cb(t)}`;const n=[];return n.push(t.local?\"Z?\":\"Z\"),t.offset\u0026\u0026n.push(\"([+-]\\\\d{2}:?\\\\d{2})\"),e=`${e}(${n.join(\"|\")})`,new RegExp(`^${e}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
)}function Nb(t,e){return!(\"v4\"!==e\u0026\u0026e||!fb.test(t))||!(\"v6\"!==e\u0026\u0026e||!_b.test(t))}function wb(t,e){if(!pb.test(t))return!1;try{const[n]=t.split(\".\");if(!n)return!1;const o=n.replace(/-/g,\"+\").replace(/_/g,\"/\").padEnd(n.length+(4-n.length%4)%4,\"=\"),i=JSON.parse(atob(o));return\"object\"==typeof i\u0026\u0026null!==i\u0026\u0026((!(\"typ\"in i)||\"JWT\"===i?.typ)\u0026\u0026(!!i.alg\u0026\u0026(!e||i.alg===e)))}catch{return!1}}function Tb(t,e){return!(\"v4\"!==e\u0026\u0026e||!yb.test(t))||!(\"v6\"!==e\u0026\u0026e||!bb.test(t))}var Rb=class t extends ab{_parse(t){this._def.coerce\u0026\u0026(t.data=String(t.data));if(this._getType(t)!==L_.string){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.string,received:e.parsedType}),q_}const e=new Z_;let n;for(const o of this._def.checks)if(\"min\"===o.kind)t.data.length\u003co.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_small,minimum:o.value,type:\"string\",inclusive:!0,exact:!1,message:o.message}),e.dirty());else if(\"max\"===o.kind)t.data.length\u003eo.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_big,maximum:o.value,type:\"string\",inclusive:!0,exact:!1,message:o.message}),e.dirty());else if(\"length\"===o.kind){const i=t.data.length\u003eo.value,r=t.data.length\u003co.value;(i||r)\u0026\u0026(n=this._getOrReturnCtx(t,n),i?H_(n,{code:z_.too_big,maximum:o.value,type:\"string\",inclusive:!0,exact:!0,message:o.message}):r\u0026\u0026H_(n,{code:z_.too_small,minimum:o.value,type:\"string\",inclusive:!0,exact:!0,message:o.message}),e.dirty())}else if(\"email\"===o.kind)gb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"email\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"emoji\"===o.kind)sb||(sb=new RegExp(\"^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+$\",\"u\")),sb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"emoji\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"uuid\"===o.kind)hb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"uuid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"nanoid\"===o.kind)ub.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"nanoid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"cuid\"===o.kind)cb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"cuid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"cuid2\"===o.kind)lb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"cuid2\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"ulid\"===o.kind)db.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"ulid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"url\"===o.kind)try{new URL(t.data)}catch{n=this._getOrReturnCtx(t,n),H_(n,{validation:\"url\",code:z_.invalid_string,message:o.message}),e.dirty()}else if(\"regex\"===o.kind){o.regex.lastIndex=0;o.regex.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"regex\",code:z_.invalid_string,message:o.message}),e.dirty())}else if(\"trim\"===o.kind)t.data=t.data.trim();else if(\"includes\"===o.kind)t.data.includes(o.value,o.position)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{includes:o.value,position:o.position},message:o.message}),e.dirty());else if(\"toLowerCase\"===o.kind)t.data=t.data.toLowerCase();else if(\"toUpperCase\"===o.kind)t.data=t.data.toUpperCase();else if(\"startsWith\"===o.kind)t.data.startsWith(o.value)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{startsWith:o.value},message:o.message}),e.dirty());else if(\"endsWith\"===o.kind)t.data.endsWith(o.value)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{endsWith:o.value},message:o.message}),e.dirty());else if(\"datetime\"===o.kind){Mb(o).test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:\"datetime\",message:o.message}),e.dirty())}else if(\"date\"===o.kind){Ib.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:\"date\",message:o.message}),e.dirty())}else if(\"time\"===o.kind){Pb(o).test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:\"time\",message:o.message}),e.dirty())}else\"duration\"===o.kind?mb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"duration\",code:z_.invalid_string,message:o.message}),e.dirty()):\"ip\"===o.kind?Nb(t.data,o.version)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"ip\",code:z_.invalid_string,message:o.message}),e.dirty()):\"jwt\"===o.kind?wb(t.data,o.alg)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"jwt\",code:z_.invalid_string,message:o.message}),e.dirty()):\"cidr\"===o.kind?Tb(t.data,o.version)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"cidr\",code:z_.invalid_string,message:o.message}),e.dirty()):\"base64\"===o.kind?xb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"base64\",code:z_.invalid_string,message:o.message}),e.dirty()):\"base64url\"===o.kind?vb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"base64url\",code:z_.invalid_string,message:o.message}),e.dirty()):R_.assertNever(o);return{status:e.value,value:t.data}}_regex(t,e,n){return this.refinement(e=\u003et.test(e),{validation:e,code:z_.invalid_string,...G_.errToObj(n)})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}email(t){return this._addCheck({kind:\"email\",...G_.errToObj(t)})}url(t){return this._addCheck({kind:\"url\",...G_.errToObj(t)})}emoji(t){return this._addCheck({kind:\"emoji\",...G_.errToObj(t)})}uuid(t){return this._addCheck({kind:\"uuid\",...G_.errToObj(t)})}nanoid(t){return this._addCheck({kind:\"nanoid\",...G_.errToObj(t)})}cuid(t){return this._addCheck({kind:\"cuid\",...G_.errToObj(t)})}cuid2(t){return this._addCheck({kind:\"cuid2\",...G_.errToObj(t)})}ulid(t){return this._addCheck({kind:\"ulid\",...G_.errToObj(t)})}base64(t){return this._addCheck({kind:\"base64\",...G_.errToObj(t)})}base64url(t){return this._addCheck({kind:\"base64url\",...G_.errToObj(t)})}jwt(t){return this._addCheck({kind:\"jwt\",...G_.errToObj(t)})}ip(t){return this._addCheck({kind:\"ip\",...G_.errToObj(t)})}cidr(t){return this._addCheck({kind:\"cidr\",...G_.errToObj(t)})}datetime(t){return\"string\"==typeof t?this._addCheck({kind:\"datetime\",precision:null,offset:!1,local:!1,message:t}):this._addCheck({kind:\"datetime\",precision:void 0===t?.precision?null:t?.precision,offset:t?.offset??!1,local:t?.local??!1,...G_.errToObj(t?.message)})}date(t){return this._addCheck({kind:\"date\",message:t})}time(t){return\"string\"==typeof t?this._addCheck({kind:\"time\",precision:null,message:t}):this._addCheck({kind:\"time\",precision:void 0===t?.precision?null:t?.precision,...G_.errToObj(t?.message)})}duration(t){return this._addCheck({kind:\"duration\",...G_.errToObj(t)})}regex(t,e){return this._addCheck({kind:\"regex\",regex:t,...G_.errToObj(e)})}includes(t,e){return this._addCheck({kind:\"includes\",value:t,position:e?.position,...G_.errToObj(e?.message)})}startsWith(t,e){return this._addCheck({kind:\"startsWith\",value:t,...G_.errToObj(e)})}endsWith(t,e){return this._addCheck({kind:\"endsWith\",value:t,...G_.errToObj(e)})}min(t,e){return this._addCheck({kind:\"min\",value:t,...G_.errToObj(e)})}max(t,e){return this._addCheck({kind:\"max\",value:t,...G_.errToObj(e)})}length(t,e){return this._addCheck({kind:\"length\",value:t,...G_.errToObj(e)})}nonempty(t){return this.min(1,G_.errToObj(t))}trim(){return new t({...this._def,checks:[...this._def.checks,{kind:\"trim\"}]})}toLowerCase(){return new t({...this._def,checks:[...this._def.checks,{kind:\"toLowerCase\"}]})}toUpperCase(){return new t({...this._def,checks:[...this._def.checks,{kind:\"toUpperCase\"}]})}get isDatetime(){return!!this._def.checks.find(t=\u003e\"datetime\"===t.kind)}get isDate(){return!!this._def.checks.find(t=\u003e\"date\"===t.kind)}get isTime(){return!!this._def.checks.find(t=\u003e\"time\"===t.kind)}get isDuration(){return!!this._def.checks.find(t=\u003e\"duration\"===t.kind)}get isEmail(){return!!this._def.checks.find(t=\u003e\"email\"===t.kind)}get isURL(){return!!this._def.checks.find(t=\u003e\"url\"===t.kind)}get isEmoji(){return!!this._def.checks.find(t=\u003e\"emoji\"===t.kind)}get isUUID(){return!!this._def.checks.find(t=\u003e\"uuid\"===t.kind)}get isNANOID(){return!!this._def.checks.find(t=\u003e\"nanoid\"===t.kind)}get isCUID(){return!!this._def.checks.find(t=\u003e\"cuid\"===t.kind)}get isCUID2(){return!!this._def.checks.find(t=\u003e\"cuid2\"===t.kind)}get isULID(){return!!this._def.checks.find(t=\u003e\"ulid\"===t.kind)}get isIP(){return!!this._def.checks.find(t=\u003e\"ip\"===t.kind)}get isCIDR(){return!!this._def.checks.find(t=\u003e\"cidr\"===t.kind)}get isBase64(){return!!this._def.checks.find(t=\u003e\"base64\"===t.kind)}get isBase64url(){return!!this._def.checks.find(t=\u003e\"base64url\"===t.kind)}get minLength(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return t}get maxLength(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return t}};function Eb(t,e){const n=(t.toString().split(\".\")[1]||\"\").length,o=(e.toString().split(\".\")[1]||\"\").length,i=n\u003eo?n:o;return Number.parseInt(t.toFixed(i).replace(\".\",\"\"))%Number.parseInt(e.toFixed(i).replace(\".\",\"\"))/10**i}Rb.create=t=\u003enew Rb({checks:[],typeName:xx.ZodString,coerce:t?.coerce??!1,...rb(t)});var Ab=class t extends ab{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(t){this._def.coerce\u0026\u0026(t.data=Number(t.data));if(this._getType(t)!==L_.number){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.number,received:e.parsedType}),q_}let e;const n=new Z_;for(const o of this._def.checks)if(\"int\"===o.kind)R_.isInteger(t.data)||(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.invalid_type,expected:\"integer\",received:\"float\",message:o.message}),n.dirty());else if(\"min\"===o.kind){(o.inclusive?t.data\u003co.value:t.data\u003c=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_small,minimum:o.value,type:\"number\",inclusive:o.inclusive,exact:!1,message:o.message}),n.dirty())}else if(\"max\"===o.kind){(o.inclusive?t.data\u003eo.value:t.data\u003e=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_big,maximum:o.value,type:\"number\",inclusive:o.inclusive,exact:!1,message:o.message}),n.dirty())}else\"multipleOf\"===o.kind?0!==Eb(t.data,o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_multiple_of,multipleOf:o.value,message:o.message}),n.dirty()):\"finite\"===o.kind?Number.isFinite(t.data)||(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_finite,message:o.message}),n.dirty()):R_.assertNever(o);return{status:n.value,value:t.data}}gte(t,e){return this.setLimit(\"min\",t,!0,G_.toString(e))}gt(t,e){return this.setLimit(\"min\",t,!1,G_.toString(e))}lte(t,e){return this.setLimit(\"max\",t,!0,G_.toString(e))}lt(t,e){return this.setLimit(\"max\",t,!1,G_.toString(e))}setLimit(e,n,o,i){return new t({...this._def,checks:[...this._def.checks,{kind:e,value:n,inclusive:o,message:G_.toString(i)}]})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}int(t){return this._addCheck({kind:\"int\",message:G_.toString(t)})}positive(t){return this._addCheck({kind:\"min\",value:0,inclusive:!1,message:G_.toString(t)})}negative(t){return this._addCheck({kind:\"max\",value:0,inclusive:!1,message:G_.toString(t)})}nonpositive(t){return this._addCheck({kind:\"max\",value:0,inclusive:!0,message:G_.toString(t)})}nonnegative(t){return this._addCheck({kind:\"min\",value:0,inclusive:!0,message:G_.toString(t)})}multipleOf(t,e){return this._addCheck({kind:\"multipleOf\",value:t,message:G_.toString(e)})}finite(t){return this._addCheck({kind:\"finite\",message:G_.toString(t)})}safe(t){return this._addCheck({kind:\"min\",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:G_.toString(t)})._addCheck({kind:\"max\",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:G_.toString(t)})}get minValue(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return t}get maxValue(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return t}get isInt(){return!!this._def.checks.find(t=\u003e\"int\"===t.kind||\"multipleOf\"===t.kind\u0026\u0026R_.isInteger(t.value))}get isFinite(){let t=null,e=null;for(const n of this._def.checks){if(\"finite\"===n.kind||\"int\"===n.kind||\"multipleOf\"===n.kind)return!0;\"min\"===n.kind?(null===e||n.value\u003ee)\u0026\u0026(e=n.value):\"max\"===n.kind\u0026\u0026(null===t||n.value\u003ct)\u0026\u0026(t=n.value)}return Number.isFinite(e)\u0026\u0026Number.isFinite(t)}};Ab.create=t=\u003enew Ab({checks:[],typeName:xx.ZodNumber,coerce:t?.coerce||!1,...rb(t)});var Ob=class t extends ab{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(t){if(this._def.coerce)try{t.data=BigInt(t.data)}catch{return this._getInvalidInput(t)}if(this._getType(t)!==L_.bigint)return this._getInvalidInput(t);let e;const n=new Z_;for(const o of this._def.checks)if(\"min\"===o.kind){(o.inclusive?t.data\u003co.value:t.data\u003c=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_small,type:\"bigint\",minimum:o.value,inclusive:o.inclusive,message:o.message}),n.dirty())}else if(\"max\"===o.kind){(o.inclusive?t.data\u003eo.value:t.data\u003e=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_big,type:\"bigint\",maximum:o.value,inclusive:o.inclusive,message:o.message}),n.dirty())}else\"multipleOf\"===o.kind?t.data%o.value!==BigInt(0)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_multiple_of,multipleOf:o.value,message:o.message}),n.dirty()):R_.assertNever(o);return{status:n.value,value:t.data}}_getInvalidInput(t){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.bigint,received:e.parsedType}),q_}gte(t,e){return this.setLimit(\"min\",t,!0,G_.toString(e))}gt(t,e){return this.setLimit(\"min\",t,!1,G_.toString(e))}lte(t,e){return this.setLimit(\"max\",t,!0,G_.toString(e))}lt(t,e){return this.setLimit(\"max\",t,!1,G_.toString(e))}setLimit(e,n,o,i){return new t({...this._def,checks:[...this._def.checks,{kind:e,value:n,inclusive:o,message:G_.toString(i)}]})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}positive(t){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!1,message:G_.toString(t)})}negative(t){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!1,message:G_.toString(t)})}nonpositive(t){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!0,message:G_.toString(t)})}nonnegative(t){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!0,message:G_.toString(t)})}multipleOf(t,e){return this._addCheck({kind:\"multipleOf\",value:t,message:G_.toString(e)})}get minValue(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return t}get maxValue(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return t}};Ob.create=t=\u003enew Ob({checks:[],typeName:xx.ZodBigInt,coerce:t?.coerce??!1,...rb(t)});var kb=class extends ab{_parse(t){this._def.coerce\u0026\u0026(t.data=Boolean(t.data));if(this._getType(t)!==L_.boolean){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.boolean,received:e.parsedType}),q_}return K_(t.data)}};kb.create=t=\u003enew kb({typeName:xx.ZodBoolean,coerce:t?.coerce||!1,...rb(t)});var Lb=class t extends ab{_parse(t){this._def.coerce\u0026\u0026(t.data=new Date(t.data));if(this._getType(t)!==L_.date){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.date,received:e.parsedType}),q_}if(Number.isNaN(t.data.getTime())){return H_(this._getOrReturnCtx(t),{code:z_.invalid_date}),q_}const e=new Z_;let n;for(const o of this._def.checks)\"min\"===o.kind?t.data.getTime()\u003co.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_small,message:o.message,inclusive:!0,exact:!1,minimum:o.value,type:\"date\"}),e.dirty()):\"max\"===o.kind?t.data.getTime()\u003eo.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_big,message:o.message,inclusive:!0,exact:!1,maximum:o.value,type:\"date\"}),e.dirty()):R_.assertNever(o);return{status:e.value,value:new Date(t.data.getTime())}}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}min(t,e){return this._addCheck({kind:\"min\",value:t.getTime(),message:G_.toString(e)})}max(t,e){return this._addCheck({kind:\"max\",value:t.getTime(),message:G_.toString(e)})}get minDate(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return null!=t?new Date(t):null}get maxDate(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return null!=t?new Date(t):null}};Lb.create=t=\u003enew Lb({checks:[],coerce:t?.coerce||!1,typeName:xx.ZodDate,...rb(t)});var Db=class extends ab{_parse(t){if(this._getType(t)!==L_.symbol){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.symbol,received:e.parsedType}),q_}return K_(t.data)}};Db.create=t=\u003enew Db({typeName:xx.ZodSymbol,...rb(t)});var zb=class extends ab{_parse(t){if(this._getType(t)!==L_.undefined){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.undefined,received:e.parsedType}),q_}return K_(t.data)}};zb.create=t=\u003enew zb({typeName:xx.ZodUndefined,...rb(t)});var Fb=class extends ab{_parse(t){if(this._getType(t)!==L_.null){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.null,received:e.parsedType}),q_}return K_(t.data)}};Fb.create=t=\u003enew Fb({typeName:xx.ZodNull,...rb(t)});var Bb=class extends ab{constructor(){super(...arguments),this._any=!0}_parse(t){return K_(t.data)}};Bb.create=t=\u003enew Bb({typeName:xx.ZodAny,...rb(t)});var jb=class extends ab{constructor(){super(...arguments),this._unknown=!0}_parse(t){return K_(t.data)}};jb.create=t=\u003enew jb({typeName:xx.ZodUnknown,...rb(t)});var $b=class extends ab{_parse(t){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.never,received:e.parsedType}),q_}};$b.create=t=\u003enew $b({typeName:xx.ZodNever,...rb(t)});var Yb=class extends ab{_parse(t){if(this._getType(t)!==L_.undefined){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.void,received:e.parsedType}),q_}return K_(t.data)}};Yb.create=t=\u003enew Yb({typeName:xx.ZodVoid,...rb(t)});var Xb=class t extends ab{_parse(t){const{ctx:e,status:n}=this._processInputParams(t),o=this._def;if(e.parsedType!==L_.array)return H_(e,{code:z_.invalid_type,expected:L_.array,received:e.parsedType}),q_;if(null!==o.exactLength){const t=e.data.length\u003eo.exactLength.value,i=e.data.length\u003co.exactLength.value;(t||i)\u0026\u0026(H_(e,{code:t?z_.too_big:z_.too_small,minimum:i?o.exactLength.value:void 0,maximum:t?o.exactLength.value:void 0,type:\"array\",inclusive:!0,exact:!0,message:o.exactLength.message}),n.dirty())}if(null!==o.minLength\u0026\u0026e.data.length\u003co.minLength.value\u0026\u0026(H_(e,{code:z_.too_small,minimum:o.minLength.value,type:\"array\",inclusive:!0,exact:!1,message:o.minLength.message}),n.dirty()),null!==o.maxLength\u0026\u0026e.data.length\u003eo.maxLength.value\u0026\u0026(H_(e,{code:z_.too_big,maximum:o.maxLength.value,type:\"array\",inclusive:!0,exact:!1,message:o.maxLength.message}),n.dirty()),e.common.async)return Promise.all([...e.data].map((t,n)=\u003eo.type._parseAsync(new ob(e,t,e.path,n)))).then(t=\u003eZ_.mergeArray(n,t));const i=[...e.data].map((t,n)=\u003eo.type._parseSync(new ob(e,t,e.path,n)));return Z_.mergeArray(n,i)}get element(){return this._def.type}min(e,n){return new t({...this._def,minLength:{value:e,message:G_.toString(n)}})}max(e,n){return new t({...this._def,maxLength:{value:e,message:G_.toString(n)}})}length(e,n){return new t({...this._def,exactLength:{value:e,message:G_.toString(n)}})}nonempty(t){return this.min(1,t)}};function Vb(t){if(t instanceof Wb){const e={};for(const n in t.shape){const o=t.shape[n];e[n]=lx.create(Vb(o))}return new Wb({...t._def,shape:()=\u003ee})}return t instanceof Xb?new Xb({...t._def,type:Vb(t.element)}):t instanceof lx?lx.create(Vb(t.unwrap())):t instanceof dx?dx.create(Vb(t.unwrap())):t instanceof Jb?Jb.create(t.items.map(t=\u003eVb(t))):t}Xb.create=(t,e)=\u003enew Xb({type:t,minLength:null,maxLength:null,exactLength:null,typeName:xx.ZodArray,...rb(e)});var Wb=class t extends ab{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(null!==this._cached)return this._cached;const t=this._def.shape(),e=R_.objectKeys(t);return this._cached={shape:t,keys:e},this._cached}_parse(t){if(this._getType(t)!==L_.object){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.object,received:e.parsedType}),q_}const{status:e,ctx:n}=this._processInputParams(t),{shape:o,keys:i}=this._getCached(),r=[];if(!(this._def.catchall instanceof $b\u0026\u0026\"strip\"===this._def.unknownKeys))for(const t in n.data)i.includes(t)||r.push(t);const s=[];for(const t of i){const e=o[t],i=n.data[t];s.push({key:{status:\"valid\",value:t},value:e._parse(new ob(n,i,n.path,t)),alwaysSet:t in n.data})}if(this._def.catchall instanceof $b){const t=this._def.unknownKeys;if(\"passthrough\"===t)for(const t of r)s.push({key:{status:\"valid\",value:t},value:{status:\"valid\",value:n.data[t]}});else if(\"strict\"===t)r.length\u003e0\u0026\u0026(H_(n,{code:z_.unrecognized_keys,keys:r}),e.dirty());else if(\"strip\"!==t)throw new Error(\"Internal ZodObject error: invalid unknownKeys value.\")}else{const t=this._def.catchall;for(const e of r){const o=n.data[e];s.push({key:{status:\"valid\",value:e},value:t._parse(new ob(n,o,n.path,e)),alwaysSet:e in n.data})}}return n.common.async?Promise.resolve().then(async()=\u003e{const t=[];for(const e of s){const n=await e.key,o=await e.value;t.push({key:n,value:o,alwaysSet:e.alwaysSet})}return t}).then(t=\u003eZ_.mergeObjectSync(e,t)):Z_.mergeObjectSync(e,s)}get shape(){return this._def.shape()}strict(e){return G_.errToObj,new t({...this._def,unknownKeys:\"strict\",...void 0!==e?{errorMap:(t,n)=\u003e{const o=this._def.errorMap?.(t,n).message??n.defaultError;return\"unrecognized_keys\"===t.code?{message:G_.errToObj(e).message??o}:{message:o}}}:{}})}strip(){return new t({...this._def,unknownKeys:\"strip\"})}passthrough(){return new t({...this._def,unknownKeys:\"passthrough\"})}extend(e){return new t({...this._def,shape:()=\u003e({...this._def.shape(),...e})})}merge(e){return new t({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=\u003e({...this._def.shape(),...e._def.shape()}),typeName:xx.ZodObject})}setKey(t,e){return this.augment({[t]:e})}catchall(e){return new t({...this._def,catchall:e})}pick(e){const n={};for(const t of R_.objectKeys(e))e[t]\u0026\u0026this.shape[t]\u0026\u0026(n[t]=this.shape[t]);return new t({...this._def,shape:()=\u003en})}omit(e){const n={};for(const t of R_.objectKeys(this.shape))e[t]||(n[t]=this.shape[t]);return new t({...this._def,shape:()=\u003en})}deepPartial(){return Vb(this)}partial(e){const n={};for(const t of R_.objectKeys(this.shape)){const o=this.shape[t];e\u0026\u0026!e[t]?n[t]=o:n[t]=o.optional()}return new t({...this._def,shape:()=\u003en})}required(e){const n={};for(const t of R_.objectKeys(this.shape))if(e\u0026\u0026!e[t])n[t]=this.shape[t];else{let e=this.shape[t];for(;e instanceof lx;)e=e._def.innerType;n[t]=e}return new t({...this._def,shape:()=\u003en})}keyof(){return ix(R_.objectKeys(this.shape))}};Wb.create=(t,e)=\u003enew Wb({shape:()=\u003et,unknownKeys:\"strip\",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)}),Wb.strictCreate=(t,e)=\u003enew Wb({shape:()=\u003et,unknownKeys:\"strict\",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)}),Wb.lazycreate=(t,e)=\u003enew Wb({shape:t,unknownKeys:\"strip\",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)});var Hb=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n=this._def.options;if(e.common.async)return Promise.all(n.map(async t=\u003e{const n={...e,common:{...e.common,issues:[]},parent:null};return{result:await t._parseAsync({data:e.data,path:e.path,parent:n}),ctx:n}})).then(function(t){for(const e of t)if(\"valid\"===e.result.status)return e.result;for(const n of t)if(\"dirty\"===n.result.status)return e.common.issues.push(...n.ctx.common.issues),n.result;const n=t.map(t=\u003enew B_(t.ctx.common.issues));return H_(e,{code:z_.invalid_union,unionErrors:n}),q_});{let t;const o=[];for(const i of n){const n={...e,common:{...e.common,issues:[]},parent:null},r=i._parseSync({data:e.data,path:e.path,parent:n});if(\"valid\"===r.status)return r;\"dirty\"!==r.status||t||(t={result:r,ctx:n}),n.common.issues.length\u0026\u0026o.push(n.common.issues)}if(t)return e.common.issues.push(...t.ctx.common.issues),t.result;const i=o.map(t=\u003enew B_(t));return H_(e,{code:z_.invalid_union,unionErrors:i}),q_}}get options(){return this._def.options}};Hb.create=(t,e)=\u003enew Hb({options:t,typeName:xx.ZodUnion,...rb(e)});var Gb=t=\u003et instanceof nx?Gb(t.schema):t instanceof cx?Gb(t.innerType()):t instanceof ox?[t.value]:t instanceof rx?t.options:t instanceof sx?R_.objectValues(t.enum):t instanceof hx?Gb(t._def.innerType):t instanceof zb?[void 0]:t instanceof Fb?[null]:t instanceof lx?[void 0,...Gb(t.unwrap())]:t instanceof dx?[null,...Gb(t.unwrap())]:t instanceof gx||t instanceof yx?Gb(t.unwrap()):t instanceof ux?Gb(t._def.innerType):[],Ub=class t extends ab{_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.object)return H_(e,{code:z_.invalid_type,expected:L_.object,received:e.parsedType}),q_;const n=this.discriminator,o=e.data[n],i=this.optionsMap.get(o);return i?e.common.async?i._parseAsync({data:e.data,path:e.path,parent:e}):i._parseSync({data:e.data,path:e.path,parent:e}):(H_(e,{code:z_.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[n]}),q_)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,n,o){const i=new Map;for(const t of n){const n=Gb(t.shape[e]);if(!n.length)throw new Error(`A discriminator value for key \\`${e}\\` could not be extracted from all schema options`);for(const o of n){if(i.has(o))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(o)}`);i.set(o,t)}}return new t({typeName:xx.ZodDiscriminatedUnion,discriminator:e,options:n,optionsMap:i,...rb(o)})}};function Zb(t,e){const n=D_(t),o=D_(e);if(t===e)return{valid:!0,data:t};if(n===L_.object\u0026\u0026o===L_.object){const n=R_.objectKeys(e),o=R_.objectKeys(t).filter(t=\u003e-1!==n.indexOf(t)),i={...t,...e};for(const n of o){const o=Zb(t[n],e[n]);if(!o.valid)return{valid:!1};i[n]=o.data}return{valid:!0,data:i}}if(n===L_.array\u0026\u0026o===L_.array){if(t.length!==e.length)return{valid:!1};const n=[];for(let o=0;o\u003ct.length;o++){const i=Zb(t[o],e[o]);if(!i.valid)return{valid:!1};n.push(i.data)}return{valid:!0,data:n}}return n===L_.date\u0026\u0026o===L_.date\u0026\u0026+t===+e?{valid:!0,data:t}:{valid:!1}}var qb=class extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t),o=(t,o)=\u003e{if(Q_(t)||Q_(o))return q_;const i=Zb(t.value,o.value);return i.valid?((tb(t)||tb(o))\u0026\u0026e.dirty(),{status:e.value,value:i.data}):(H_(n,{code:z_.invalid_intersection_types}),q_)};return n.common.async?Promise.all([this._def.left._parseAsync({data:n.data,path:n.path,parent:n}),this._def.right._parseAsync({data:n.data,path:n.path,parent:n})]).then(([t,e])=\u003eo(t,e)):o(this._def.left._parseSync({data:n.data,path:n.path,parent:n}),this._def.right._parseSync({data:n.data,path:n.path,parent:n}))}};qb.create=(t,e,n)=\u003enew qb({left:t,right:e,typeName:xx.ZodIntersection,...rb(n)});var Jb=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.array)return H_(n,{code:z_.invalid_type,expected:L_.array,received:n.parsedType}),q_;if(n.data.length\u003cthis._def.items.length)return H_(n,{code:z_.too_small,minimum:this._def.items.length,inclusive:!0,exact:!1,type:\"array\"}),q_;!this._def.rest\u0026\u0026n.data.length\u003ethis._def.items.length\u0026\u0026(H_(n,{code:z_.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:\"array\"}),e.dirty());const o=[...n.data].map((t,e)=\u003e{const o=this._def.items[e]||this._def.rest;return o?o._parse(new ob(n,t,n.path,e)):null}).filter(t=\u003e!!t);return n.common.async?Promise.all(o).then(t=\u003eZ_.mergeArray(e,t)):Z_.mergeArray(e,o)}get items(){return this._def.items}rest(e){return new t({...this._def,rest:e})}};Jb.create=(t,e)=\u003e{if(!Array.isArray(t))throw new Error(\"You must pass an array of schemas to z.tuple([ ... ])\");return new Jb({items:t,typeName:xx.ZodTuple,rest:null,...rb(e)})};var Kb=class t extends ab{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.object)return H_(n,{code:z_.invalid_type,expected:L_.object,received:n.parsedType}),q_;const o=[],i=this._def.keyType,r=this._def.valueType;for(const t in n.data)o.push({key:i._parse(new ob(n,t,n.path,t)),value:r._parse(new ob(n,n.data[t],n.path,t)),alwaysSet:t in n.data});return n.common.async?Z_.mergeObjectAsync(e,o):Z_.mergeObjectSync(e,o)}get element(){return this._def.valueType}static create(e,n,o){return new t(n instanceof ab?{keyType:e,valueType:n,typeName:xx.ZodRecord,...rb(o)}:{keyType:Rb.create(),valueType:e,typeName:xx.ZodRecord,...rb(n)})}},Qb=class extends ab{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.map)return H_(n,{code:z_.invalid_type,expected:L_.map,received:n.parsedType}),q_;const o=this._def.keyType,i=this._def.valueType,r=[...n.data.entries()].map(([t,e],r)=\u003e({key:o._parse(new ob(n,t,n.path,[r,\"key\"])),value:i._parse(new ob(n,e,n.path,[r,\"value\"]))}));if(n.common.async){const t=new Map;return Promise.resolve().then(async()=\u003e{for(const n of r){const o=await n.key,i=await n.value;if(\"aborted\"===o.status||\"aborted\"===i.status)return q_;\"dirty\"!==o.status\u0026\u0026\"dirty\"!==i.status||e.dirty(),t.set(o.value,i.value)}return{status:e.value,value:t}})}{const t=new Map;for(const n of r){const o=n.key,i=n.value;if(\"aborted\"===o.status||\"aborted\"===i.status)return q_;\"dirty\"!==o.status\u0026\u0026\"dirty\"!==i.status||e.dirty(),t.set(o.value,i.value)}return{status:e.value,value:t}}}};Qb.create=(t,e,n)=\u003enew Qb({valueType:e,keyType:t,typeName:xx.ZodMap,...rb(n)});var tx=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.set)return H_(n,{code:z_.invalid_type,expected:L_.set,received:n.parsedType}),q_;const o=this._def;null!==o.minSize\u0026\u0026n.data.size\u003co.minSize.value\u0026\u0026(H_(n,{code:z_.too_small,minimum:o.minSize.value,type:\"set\",inclusive:!0,exact:!1,message:o.minSize.message}),e.dirty()),null!==o.maxSize\u0026\u0026n.data.size\u003eo.maxSize.value\u0026\u0026(H_(n,{code:z_.too_big,maximum:o.maxSize.value,type:\"set\",inclusive:!0,exact:!1,message:o.maxSize.message}),e.dirty());const i=this._def.valueType;function r(t){const n=new Set;for(const o of t){if(\"aborted\"===o.status)return q_;\"dirty\"===o.status\u0026\u0026e.dirty(),n.add(o.value)}return{status:e.value,value:n}}const s=[...n.data.values()].map((t,e)=\u003ei._parse(new ob(n,t,n.path,e)));return n.common.async?Promise.all(s).then(t=\u003er(t)):r(s)}min(e,n){return new t({...this._def,minSize:{value:e,message:G_.toString(n)}})}max(e,n){return new t({...this._def,maxSize:{value:e,message:G_.toString(n)}})}size(t,e){return this.min(t,e).max(t,e)}nonempty(t){return this.min(1,t)}};tx.create=(t,e)=\u003enew tx({valueType:t,minSize:null,maxSize:null,typeName:xx.ZodSet,...rb(e)});var ex=class t extends ab{constructor(){super(...arguments),this.validate=this.implement}_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.function)return H_(e,{code:z_.invalid_type,expected:L_.function,received:e.parsedType}),q_;function n(t,n){return V_({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,X_(),j_].filter(t=\u003e!!t),issueData:{code:z_.invalid_arguments,argumentsError:n}})}function o(t,n){return V_({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,X_(),j_].filter(t=\u003e!!t),issueData:{code:z_.invalid_return_type,returnTypeError:n}})}const i={errorMap:e.common.contextualErrorMap},r=e.data;if(this._def.returns instanceof ax){const t=this;return K_(async function(...e){const s=new B_([]),a=await t._def.args.parseAsync(e,i).catch(t=\u003e{throw s.addIssue(n(e,t)),s}),c=await Reflect.apply(r,this,a);return await t._def.returns._def.type.parseAsync(c,i).catch(t=\u003e{throw s.addIssue(o(c,t)),s})})}{const t=this;return K_(function(...e){const s=t._def.args.safeParse(e,i);if(!s.success)throw new B_([n(e,s.error)]);const a=Reflect.apply(r,this,s.data),c=t._def.returns.safeParse(a,i);if(!c.success)throw new B_([o(a,c.error)]);return c.data})}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new t({...this._def,args:Jb.create(e).rest(jb.create())})}returns(e){return new t({...this._def,returns:e})}implement(t){return this.parse(t)}strictImplement(t){return this.parse(t)}static create(e,n,o){return new t({args:e||Jb.create([]).rest(jb.create()),returns:n||jb.create(),typeName:xx.ZodFunction,...rb(o)})}},nx=class extends ab{get schema(){return this._def.getter()}_parse(t){const{ctx:e}=this._processInputParams(t);return this._def.getter()._parse({data:e.data,path:e.path,parent:e})}};nx.create=(t,e)=\u003enew nx({getter:t,typeName:xx.ZodLazy,...rb(e)});var ox=class extends ab{_parse(t){if(t.data!==this._def.value){const e=this._getOrReturnCtx(t);return H_(e,{received:e.data,code:z_.invalid_literal,expected:this._def.value}),q_}return{status:\"valid\",value:t.data}}get value(){return this._def.value}};function ix(t,e){return new rx({values:t,typeName:xx.ZodEnum,...rb(e)})}ox.create=(t,e)=\u003enew ox({value:t,typeName:xx.ZodLiteral,...rb(e)});var rx=class t extends ab{_parse(t){if(\"string\"!=typeof t.data){const e=this._getOrReturnCtx(t),n=this._def.values;return H_(e,{expected:R_.joinValues(n),received:e.parsedType,code:z_.invalid_type}),q_}if(this._cache||(this._cache=new Set(this._def.values)),!this._cache.has(t.data)){const e=this._getOrReturnCtx(t),n=this._def.values;return H_(e,{received:e.data,code:z_.invalid_enum_value,options:n}),q_}return K_(t.data)}get options(){return this._def.values}get enum(){const t={};for(const e of this._def.values)t[e]=e;return t}get Values(){const t={};for(const e of this._def.values)t[e]=e;return t}get Enum(){const t={};for(const e of this._def.values)t[e]=e;return t}extract(e,n=this._def){return t.create(e,{...this._def,...n})}exclude(e,n=this._def){return t.create(this.options.filter(t=\u003e!e.includes(t)),{...this._def,...n})}};rx.create=ix;var sx=class extends ab{_parse(t){const e=R_.getValidEnumValues(this._def.values),n=this._getOrReturnCtx(t);if(n.parsedType!==L_.string\u0026\u0026n.parsedType!==L_.number){const t=R_.objectValues(e);return H_(n,{expected:R_.joinValues(t),received:n.parsedType,code:z_.invalid_type}),q_}if(this._cache||(this._cache=new Set(R_.getValidEnumValues(this._def.values))),!this._cache.has(t.data)){const t=R_.objectValues(e);return H_(n,{received:n.data,code:z_.invalid_enum_value,options:t}),q_}return K_(t.data)}get enum(){return this._def.values}};sx.create=(t,e)=\u003enew sx({values:t,typeName:xx.ZodNativeEnum,...rb(e)});var ax=class extends ab{unwrap(){return this._def.type}_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.promise\u0026\u0026!1===e.common.async)return H_(e,{code:z_.invalid_type,expected:L_.promise,received:e.parsedType}),q_;const n=e.parsedType===L_.promise?e.data:Promise.resolve(e.data);return K_(n.then(t=\u003ethis._def.type.parseAsync(t,{path:e.path,errorMap:e.common.contextualErrorMap})))}};ax.create=(t,e)=\u003enew ax({type:t,typeName:xx.ZodPromise,...rb(e)});var cx=class extends ab{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===xx.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(t){const{status:e,ctx:n}=this._processInputParams(t),o=this._def.effect||null,i={addIssue:t=\u003e{H_(n,t),t.fatal?e.abort():e.dirty()},get path(){return n.path}};if(i.addIssue=i.addIssue.bind(i),\"preprocess\"===o.type){const t=o.transform(n.data,i);if(n.common.async)return Promise.resolve(t).then(async t=\u003e{if(\"aborted\"===e.value)return q_;const o=await this._def.schema._parseAsync({data:t,path:n.path,parent:n});return\"aborted\"===o.status?q_:\"dirty\"===o.status||\"dirty\"===e.value?J_(o.value):o});{if(\"aborted\"===e.value)return q_;const o=this._def.schema._parseSync({data:t,path:n.path,parent:n});return\"aborted\"===o.status?q_:\"dirty\"===o.status||\"dirty\"===e.value?J_(o.value):o}}if(\"refinement\"===o.type){const t=t=\u003e{const e=o.refinement(t,i);if(n.common.async)return Promise.resolve(e);if(e instanceof Promise)throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");return t};if(!1===n.common.async){const o=this._def.schema._parseSync({data:n.data,path:n.path,parent:n});return\"aborted\"===o.status?q_:(\"dirty\"===o.status\u0026\u0026e.dirty(),t(o.value),{status:e.value,value:o.value})}return this._def.schema._parseAsync({data:n.data,path:n.path,parent:n}).then(n=\u003e\"aborted\"===n.status?q_:(\"dirty\"===n.status\u0026\u0026e.dirty(),t(n.value).then(()=\u003e({status:e.value,value:n.value}))))}if(\"transform\"===o.type){if(!1===n.common.async){const t=this._def.schema._parseSync({data:n.data,path:n.path,parent:n});if(!eb(t))return q_;const r=o.transform(t.value,i);if(r instanceof Promise)throw new Error(\"Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.\");return{status:e.value,value:r}}return this._def.schema._parseAsync({data:n.data,path:n.path,parent:n}).then(t=\u003eeb(t)?Promise.resolve(o.transform(t.value,i)).then(t=\u003e({status:e.value,value:t})):q_)}R_.assertNever(o)}};cx.create=(t,e,n)=\u003enew cx({schema:t,typeName:xx.ZodEffects,effect:e,...rb(n)}),cx.createWithPreprocess=(t,e,n)=\u003enew cx({schema:e,effect:{type:\"preprocess\",transform:t},typeName:xx.ZodEffects,...rb(n)});var lx=class extends ab{_parse(t){return this._getType(t)===L_.undefined?K_(void 0):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}};lx.create=(t,e)=\u003enew lx({innerType:t,typeName:xx.ZodOptional,...rb(e)});var dx=class extends ab{_parse(t){return this._getType(t)===L_.null?K_(null):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}};dx.create=(t,e)=\u003enew dx({innerType:t,typeName:xx.ZodNullable,...rb(e)});var hx=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t);let n=e.data;return e.parsedType===L_.undefined\u0026\u0026(n=this._def.defaultValue()),this._def.innerType._parse({data:n,path:e.path,parent:e})}removeDefault(){return this._def.innerType}};hx.create=(t,e)=\u003enew hx({innerType:t,typeName:xx.ZodDefault,defaultValue:\"function\"==typeof e.default?e.default:()=\u003ee.default,...rb(e)});var ux=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n={...e,common:{...e.common,issues:[]}},o=this._def.innerType._parse({data:n.data,path:n.path,parent:{...n}});return nb(o)?o.then(t=\u003e({status:\"valid\",value:\"valid\"===t.status?t.value:this._def.catchValue({get error(){return new B_(n.common.issues)},input:n.data})})):{status:\"valid\",value:\"valid\"===o.status?o.value:this._def.catchValue({get error(){return new B_(n.common.issues)},input:n.data})}}removeCatch(){return this._def.innerType}};ux.create=(t,e)=\u003enew ux({innerType:t,typeName:xx.ZodCatch,catchValue:\"function\"==typeof e.catch?e.catch:()=\u003ee.catch,...rb(e)});var px=class extends ab{_parse(t){if(this._getType(t)!==L_.nan){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.nan,received:e.parsedType}),q_}return{status:\"valid\",value:t.data}}};px.create=t=\u003enew px({typeName:xx.ZodNaN,...rb(t)});var mx=Symbol(\"zod_brand\"),gx=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n=e.data;return this._def.type._parse({data:n,path:e.path,parent:e})}unwrap(){return this._def.type}},fx=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.common.async){return(async()=\u003e{const t=await this._def.in._parseAsync({data:n.data,path:n.path,parent:n});return\"aborted\"===t.status?q_:\"dirty\"===t.status?(e.dirty(),J_(t.value)):this._def.out._parseAsync({data:t.value,path:n.path,parent:n})})()}{const t=this._def.in._parseSync({data:n.data,path:n.path,parent:n});return\"aborted\"===t.status?q_:\"dirty\"===t.status?(e.dirty(),{status:\"dirty\",value:t.value}):this._def.out._parseSync({data:t.value,path:n.path,parent:n})}}static create(e,n){return new t({in:e,out:n,typeName:xx.ZodPipeline})}},yx=class extends ab{_parse(t){const e=this._def.innerType._parse(t),n=t=\u003e(eb(t)\u0026\u0026(t.value=Object.freeze(t.value)),t);return nb(e)?e.then(t=\u003en(t)):n(e)}unwrap(){return this._def.innerType}};function _x(t,e){const n=\"function\"==typeof t?t(e):\"string\"==typeof t?{message:t}:t;return\"string\"==typeof n?{message:n}:n}function bx(t,e={},n){return t?Bb.create().superRefine((o,i)=\u003e{const r=t(o);if(r instanceof Promise)return r.then(t=\u003e{if(!t){const t=_x(e,o),r=t.fatal??n??!0;i.addIssue({code:\"custom\",...t,fatal:r})}});if(!r){const t=_x(e,o),r=t.fatal??n??!0;i.addIssue({code:\"custom\",...t,fatal:r})}}):Bb.create()}yx.create=(t,e)=\u003enew yx({innerType:t,typeName:xx.ZodReadonly,...rb(e)});var xx,vx,Sx={object:Wb.lazycreate};(vx=xx||(xx={})).ZodString=\"ZodString\",vx.ZodNumber=\"ZodNumber\",vx.ZodNaN=\"ZodNaN\",vx.ZodBigInt=\"ZodBigInt\",vx.ZodBoolean=\"ZodBoolean\",vx.ZodDate=\"ZodDate\",vx.ZodSymbol=\"ZodSymbol\",vx.ZodUndefined=\"ZodUndefined\",vx.ZodNull=\"ZodNull\",vx.ZodAny=\"ZodAny\",vx.ZodUnknown=\"ZodUnknown\",vx.ZodNever=\"ZodNever\",vx.ZodVoid=\"ZodVoid\",vx.ZodArray=\"ZodArray\",vx.ZodObject=\"ZodObject\",vx.ZodUnion=\"ZodUnion\",vx.ZodDiscriminatedUnion=\"ZodDiscriminatedUnion\",vx.ZodIntersection=\"ZodIntersection\",vx.ZodTuple=\"ZodTuple\",vx.ZodRecord=\"ZodRecord\",vx.ZodMap=\"ZodMap\",vx.ZodSet=\"ZodSet\",vx.ZodFunction=\"ZodFunction\",vx.ZodLazy=\"ZodLazy\",vx.ZodLiteral=\"ZodLiteral\",vx.ZodEnum=\"ZodEnum\",vx.ZodEffects=\"ZodEffects\",vx.ZodNativeEnum=\"ZodNativeEnum\",vx.ZodOptional=\"ZodOptional\",vx.ZodNullable=\"ZodNullable\",vx.ZodDefault=\"ZodDefault\",vx.ZodCatch=\"ZodCatch\",vx.ZodPromise=\"ZodPromise\",vx.ZodBranded=\"ZodBranded\",vx.ZodPipeline=\"ZodPipeline\",vx.ZodReadonly=\"ZodReadonly\";var Ix=(t,e={message:`Input not instance of ${t.name}`})=\u003ebx(e=\u003ee instanceof t,e),Cx=Rb.create,Px=Ab.create,Mx=px.create,Nx=Ob.create,wx=kb.create,Tx=Lb.create,Rx=Db.create,Ex=zb.create,Ax=Fb.create,Ox=Bb.create,kx=jb.create,Lx=$b.create,Dx=Yb.create,zx=Xb.create,Fx=Wb.create,Bx=Wb.strictCreate,jx=Hb.create,$x=Ub.create,Yx=qb.create,Xx=Jb.create,Vx=Kb.create,Wx=Qb.create,Hx=tx.create,Gx=ex.create,Ux=nx.create,Zx=ox.create,qx=rx.create,Jx=sx.create,Kx=ax.create,Qx=cx.create,tv=lx.create,ev=dx.create,nv=cx.createWithPreprocess,ov=fx.create,iv=()=\u003eCx().optional(),rv=()=\u003ePx().optional(),sv=()=\u003ewx().optional(),av={string:t=\u003eRb.create({...t,coerce:!0}),number:t=\u003eAb.create({...t,coerce:!0}),boolean:t=\u003ekb.create({...t,coerce:!0}),bigint:t=\u003eOb.create({...t,coerce:!0}),date:t=\u003eLb.create({...t,coerce:!0})},cv=q_,lv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"Ω\").value),dv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"F\").value).transform(t=\u003eNumber.parseFloat(t.toPrecision(12))),hv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"H\").value),uv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"V\").value),pv=k_.string().or(k_.number()).transform(t=\u003eT_(t).value),mv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"Hz\").value),gv=pv,fv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"A\").value),yv=k_.string().or(k_.number()).transform(t=\u003eT_(t).value),_v=yv,bv=yv,xv=k_.string().datetime(),vv=k_.string().or(k_.number()).transform(t=\u003e\"number\"==typeof t?t:t.endsWith(\"deg\")?Number.parseFloat(t.split(\"deg\")[0]):t.endsWith(\"rad\")?180*Number.parseFloat(t.split(\"rad\")[0])/Math.PI:Number.parseFloat(t)),Sv=k_.number().or(k_.string().endsWith(\"mAh\")).transform(t=\u003e{if(\"string\"==typeof t){const e=t.replace(\"mAh\",\"\"),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error(\"Invalid capacity\");return n}return t}).describe(\"Battery capacity in mAh\"),Iv=k_.object({x:gv,y:gv}),Cv=Iv,Pv=k_.object({x:gv,y:gv,z:gv}),Mv=Pv,Nv=k_.object({width:k_.number(),height:k_.number()}),wv=t=\u003ek_.string().optional().default(()=\u003e`${t}_${(t=\u003e{const e=\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";return Array.from({length:t},()=\u003ee[Math.floor(62*Math.random())]).join(\"\")})(10)}`),Tv=k_.enum([\"top_left\",\"top_center\",\"top_right\",\"center_left\",\"center\",\"center_right\",\"bottom_left\",\"bottom_center\",\"bottom_right\"]),Rv=k_.enum([\"top_silkscreen\",\"bottom_silkscreen\",\"top_copper\",\"bottom_copper\",\"top_soldermask\",\"bottom_soldermask\",\"top_fabrication_note\",\"bottom_fabrication_note\",\"top_user_note\",\"bottom_user_note\",\"top_courtyard\",\"bottom_courtyard\",\"inner1_copper\",\"inner2_copper\",\"inner3_copper\",\"inner4_copper\",\"inner5_copper\",\"inner6_copper\",\"inner7_copper\",\"inner8_copper\",\"edge_cuts\",\"drill\"]),Ev=k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()}),Av=Iv.extend({rotation:vv.optional()}),Ov=k_.object({size:Iv.optional(),thickness:gv.optional()}),kv=k_.object({font:Ov.optional()}),Lv=k_.object({value:k_.string(),at:Av.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:kv.optional()}),Dv=k_.object({Reference:Lv.optional(),Value:Lv.optional(),Datasheet:Lv.optional(),Description:Lv.optional()}),zv=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),Fv=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:Av.optional(),size:Iv.optional(),drill:gv.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),Bv=k_.object({path:k_.string(),offset:Pv.optional(),scale:Pv.optional(),rotate:Pv.optional()}),jv=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:Dv.optional(),attributes:zv.optional(),pads:k_.array(Fv).optional(),embeddedFonts:k_.boolean().optional(),model:Bv.optional()}),$v=k_.object({hide:k_.boolean().optional()}),Yv=k_.object({offset:gv.optional(),hide:k_.boolean().optional()}),Xv=k_.object({font:Ov.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),Vv=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:Av.optional(),effects:Xv.optional()}),Wv=k_.object({Reference:Vv.optional(),Value:Vv.optional(),Footprint:Vv.optional(),Datasheet:Vv.optional(),Description:Vv.optional(),ki_keywords:Vv.optional(),ki_fp_filters:Vv.optional()}),Hv=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:$v.optional(),pinNames:Yv.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:Wv.optional(),embeddedFonts:k_.boolean().optional()}),Gv=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),Uv=k_.enum([\"jlcpcb\",\"macrofab\",\"pcbway\",\"digikey\",\"mouser\",\"lcsc\"]),Zv=k_.object({type:k_.literal(\"source_component\"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(Uv,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),qv=Zv.extend({ftype:k_.literal(\"simple_capacitor\"),capacitance:dv,max_voltage_rating:uv.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:gv.optional()}),Jv=Zv.extend({ftype:k_.literal(\"simple_resistor\"),resistance:lv,display_resistance:k_.string().optional()}),Kv=Zv.extend({ftype:k_.literal(\"simple_diode\")}),Qv=Zv.extend({ftype:k_.literal(\"simple_fiducial\")}),tS=Kv.extend({ftype:k_.literal(\"simple_led\"),color:k_.string().optional(),wavelength:k_.string().optional()}),eS=Zv.extend({ftype:k_.literal(\"simple_ground\")}),nS=Zv.extend({ftype:k_.literal(\"simple_chip\")}),oS=Zv.extend({ftype:k_.literal(\"simple_power_source\"),voltage:uv}),iS=Zv.extend({ftype:k_.literal(\"simple_current_source\"),current:fv,frequency:mv.optional(),peak_to_peak_current:fv.optional(),wave_shape:k_.enum([\"sine\",\"square\",\"triangle\",\"sawtooth\",\"dc\"]).optional().default(\"dc\"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),rS=Zv.extend({ftype:k_.literal(\"simple_fuse\"),current_rating_amps:k_.number().describe(\"Nominal current in amps the fuse is rated for\"),voltage_rating_volts:k_.number().describe(\"Voltage rating in volts, e.g. ±5V would be 5\")}),sS=Zv.extend({ftype:k_.literal(\"simple_ammeter\")}),aS=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),cS=Zv.extend({ftype:k_.literal(\"simple_battery\"),capacity:Sv}),lS=Zv.extend({ftype:k_.literal(\"simple_inductor\"),inductance:hv,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),dS=Zv.extend({ftype:k_.literal(\"simple_push_button\")}),hS=Zv.extend({ftype:k_.literal(\"simple_potentiometer\"),max_resistance:lv,display_max_resistance:k_.string().optional()}),uS=Zv.extend({ftype:k_.literal(\"simple_crystal\"),frequency:k_.number().describe(\"Frequency in Hz\"),load_capacitance:k_.number().optional().describe(\"Load capacitance in pF\"),pin_variant:k_.enum([\"two_pin\",\"four_pin\"]).optional()}),pS=Zv.extend({ftype:k_.literal(\"simple_pin_header\"),pin_count:k_.number(),gender:k_.enum([\"male\",\"female\"]).optional().default(\"male\")}),mS=Zv.extend({ftype:k_.literal(\"simple_connector\"),standard:k_.enum([\"usb_c\",\"m2\"]).optional()}),gS=Zv.extend({ftype:k_.literal(\"simple_pinout\")}),fS=Zv.extend({ftype:k_.literal(\"simple_resonator\"),load_capacitance:dv,equivalent_series_resistance:lv.optional(),frequency:mv}),yS=Zv.extend({ftype:k_.literal(\"simple_transistor\"),transistor_type:k_.enum([\"npn\",\"pnp\"])}),_S=Zv.extend({ftype:k_.literal(\"simple_test_point\"),footprint_variant:k_.enum([\"pad\",\"through_hole\"]).optional(),pad_shape:k_.enum([\"rect\",\"circle\"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),bS=Zv.extend({ftype:k_.literal(\"simple_mosfet\"),channel_type:k_.enum([\"n\",\"p\"]),mosfet_mode:k_.enum([\"enhancement\",\"depletion\"])}),xS=Zv.extend({ftype:k_.literal(\"simple_op_amp\")}),vS=Zv.extend({ftype:k_.literal(\"simple_switch\")}),SS=k_.object({type:k_.literal(\"source_project_metadata\"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),source_filesystem_md5_hash:k_.string().optional(),created_at:xv.optional()}),IS=Gv.extend({type:k_.literal(\"source_missing_property_error\"),source_missing_property_error_id:wv(\"source_missing_property_error\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_missing_property_error\").default(\"source_missing_property_error\")}).describe(\"The source code is missing a property\"),CS=Gv.extend({type:k_.literal(\"source_failed_to_create_component_error\"),source_failed_to_create_component_error_id:wv(\"source_failed_to_create_component_error\"),error_type:k_.literal(\"source_failed_to_create_component_error\").default(\"source_failed_to_create_component_error\"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe(\"Error emitted when a component fails to be constructed\"),PS=Gv.extend({type:k_.literal(\"source_invalid_component_property_error\"),source_invalid_component_property_error_id:wv(\"source_invalid_component_property_error\"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_invalid_component_property_error\").default(\"source_invalid_component_property_error\")}).describe(\"The source component property is invalid\"),MS=Gv.extend({type:k_.literal(\"source_trace_not_connected_error\"),source_trace_not_connected_error_id:wv(\"source_trace_not_connected_error\"),error_type:k_.literal(\"source_trace_not_connected_error\").default(\"source_trace_not_connected_error\"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe(\"Occurs when a source trace selector does not match any ports\"),NS=k_.object({type:k_.literal(\"source_property_ignored_warning\"),source_property_ignored_warning_id:wv(\"source_property_ignored_warning\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_property_ignored_warning\").default(\"source_property_ignored_warning\"),message:k_.string()}).describe(\"The source property was ignored\"),wS=k_.object({type:k_.literal(\"source_pin_missing_trace_warning\"),source_pin_missing_trace_warning_id:wv(\"source_pin_missing_trace_warning\"),warning_type:k_.literal(\"source_pin_missing_trace_warning\").default(\"source_pin_missing_trace_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component pin is missing a trace connection\"),TS=k_.object({type:k_.literal(\"source_missing_manufacturer_part_number_warning\"),source_missing_manufacturer_part_number_warning_id:wv(\"source_missing_manufacturer_part_number_warning\"),warning_type:k_.literal(\"source_missing_manufacturer_part_number_warning\").default(\"source_missing_manufacturer_part_number_warning\"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a standard connector is missing manufacturer part number\"),RS=k_.object({type:k_.literal(\"source_refdes_convention_warning\"),source_refdes_convention_warning_id:wv(\"source_refdes_convention_warning\"),warning_type:k_.literal(\"source_refdes_convention_warning\").default(\"source_refdes_convention_warning\"),message:k_.string(),source_component_id:k_.string(),refdes:k_.string(),source_component_ftype:k_.string(),expected_prefixes:k_.array(k_.string()),actual_prefix:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component reference designator does not match the component type convention\"),ES=Zv.extend({ftype:k_.literal(\"simple_voltage_probe\")}),AS=Zv.extend({ftype:k_.literal(\"interconnect\")}),OS=Gv.extend({type:k_.literal(\"source_i2c_misconfigured_error\"),source_i2c_misconfigured_error_id:wv(\"source_i2c_misconfigured_error\"),error_type:k_.literal(\"source_i2c_misconfigured_error\").default(\"source_i2c_misconfigured_error\"),source_port_ids:k_.array(k_.string())}).describe(\"Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net\"),kS=Gv.extend({type:k_.literal(\"source_component_misconfigured_error\"),source_component_misconfigured_error_id:wv(\"source_component_misconfigured_error\"),error_type:k_.literal(\"source_component_misconfigured_error\").default(\"source_component_misconfigured_error\"),source_component_ids:k_.array(k_.string()),source_port_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when one or more source components have an invalid or conflicting configuration\"),LS=Zv.extend({ftype:k_.literal(\"simple_voltage_source\"),voltage:uv,frequency:mv.optional(),peak_to_peak_voltage:uv.optional(),wave_shape:k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]).optional(),phase:vv.optional(),duty_cycle:k_.number().optional().describe(\"Duty cycle as a fraction (0 to 1)\"),pulse_delay:bv.optional(),rise_time:bv.optional(),fall_time:bv.optional(),pulse_width:bv.optional(),period:bv.optional()}),DS=k_.union([Jv,qv,Kv,Qv,tS,eS,nS,oS,iS,sS,cS,lS,dS,hS,uS,pS,mS,gS,fS,vS,yS,_S,bS,xS,rS,ES,AS,LS,SS,IS,PS,CS,MS,NS,wS,TS,RS,OS,kS]),zS=k_.object({type:k_.literal(\"source_port\"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(aS),FS=k_.object({type:k_.literal(\"source_component_internal_connection\"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),BS=k_.object({type:k_.literal(\"source_trace\"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),name:k_.string().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),jS=k_.object({type:k_.literal(\"source_group\"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),$S=k_.object({type:k_.literal(\"source_net\"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),YS=k_.object({type:k_.literal(\"source_board\"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe(\"Defines a board in the source domain\"),XS=Gv.extend({type:k_.literal(\"source_ambiguous_port_reference\"),source_ambiguous_port_reference_id:wv(\"source_ambiguous_port_reference\"),error_type:k_.literal(\"source_ambiguous_port_reference\").default(\"source_ambiguous_port_reference\"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous\"),VS=k_.object({type:k_.literal(\"source_pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane in the source domain\"),WS=[\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\",\"inner7\",\"inner8\"],HS=k_.enum(WS),GS=HS.or(k_.object({name:HS})).transform(t=\u003e\"string\"==typeof t?t:t.name),US=k_.enum([\"top\",\"bottom\"]),ZS=k_.object({type:k_.literal(\"source_manually_placed_via\"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe(\"Defines a via that is manually placed in the source domain\"),qS=k_.object({type:k_.literal(\"source_unnamed_trace_warning\"),source_unnamed_trace_warning_id:wv(\"source_unnamed_trace_warning\"),warning_type:k_.literal(\"source_unnamed_trace_warning\").default(\"source_unnamed_trace_warning\"),message:k_.string(),source_trace_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source trace is missing a name\"),JS=k_.object({type:k_.literal(\"source_no_power_pin_defined_warning\"),source_no_power_pin_defined_warning_id:wv(\"source_no_power_pin_defined_warning\"),warning_type:k_.literal(\"source_no_power_pin_defined_warning\").default(\"source_no_power_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports with requires_power=true\"),KS=k_.object({type:k_.literal(\"source_no_ground_pin_defined_warning\"),source_no_ground_pin_defined_warning_id:wv(\"source_no_ground_pin_defined_warning\"),warning_type:k_.literal(\"source_no_ground_pin_defined_warning\").default(\"source_no_ground_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports marked as ground pins\"),QS=k_.object({type:k_.literal(\"source_component_pins_underspecified_warning\"),source_component_pins_underspecified_warning_id:wv(\"source_component_pins_underspecified_warning\"),warning_type:k_.literal(\"source_component_pins_underspecified_warning\").default(\"source_component_pins_underspecified_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when all ports on a source component are underspecified\"),tI=Gv.extend({type:k_.literal(\"source_pin_must_be_connected_error\"),source_pin_must_be_connected_error_id:wv(\"source_pin_must_be_connected_error\"),error_type:k_.literal(\"source_pin_must_be_connected_error\").default(\"source_pin_must_be_connected_error\"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pin with mustBeConnected attribute is not connected to any trace\"),eI=Gv.extend({type:k_.literal(\"unknown_error_finding_part\"),unknown_error_finding_part_id:wv(\"unknown_error_finding_part\"),error_type:k_.literal(\"unknown_error_finding_part\").default(\"unknown_error_finding_part\"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when an unexpected error occurs while finding a part\"),nI=k_.object({type:k_.literal(\"source_part_not_found_warning\"),source_part_not_found_warning_id:wv(\"source_part_not_found_warning\"),warning_type:k_.literal(\"source_part_not_found_warning\").default(\"source_part_not_found_warning\"),message:k_.string(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:Uv.optional(),manufacturer_part_number:k_.string().optional(),supplier_part_number:k_.string().optional(),part_name:k_.string().optional()}).describe(\"Warning emitted when a requested part can not be found\"),oI=k_.object({type:k_.literal(\"schematic_box\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:gv,height:gv,is_dashed:k_.boolean().default(!1),x:gv,y:gv,subcircuit_id:k_.string().optional()}).describe(\"Draws a box on the schematic\"),iI=k_.object({type:k_.literal(\"schematic_path\"),schematic_path_id:wv(\"schematic_path\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),is_dashed:k_.boolean().default(!1),stroke_width:gv.nullable().optional(),stroke_color:k_.string().optional(),dash_length:gv.optional(),dash_gap:gv.optional(),points:k_.array(Iv),subcircuit_id:k_.string().optional()}),rI=k_.record(k_.object({left_margin:pv.optional(),right_margin:pv.optional(),top_margin:pv.optional(),bottom_margin:pv.optional()})),sI=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),aI=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional()}),cI=k_.union([sI,aI]),lI=k_.object({type:k_.literal(\"schematic_component\"),size:Nv,center:Iv,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_sheet_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),pin_spacing:pv.optional(),pin_styles:rI.optional(),box_width:pv.optional(),symbol_name:k_.string().optional(),port_arrangement:cI.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),dI=k_.object({kicad_symbol:Hv.optional()}).catchall(k_.unknown()),hI=k_.object({type:k_.literal(\"schematic_symbol\"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:dI.optional()}).describe(\"Defines a named schematic symbol that can be referenced by components.\"),uI=k_.object({type:k_.literal(\"schematic_line\"),schematic_line_id:wv(\"schematic_line\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:gv,y1:gv,x2:gv,y2:gv,stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),dash_length:gv.optional(),dash_gap:gv.optional(),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled line on the schematic\"),pI=k_.object({type:k_.literal(\"schematic_rect\"),schematic_rect_id:wv(\"schematic_rect\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,width:gv,height:gv,rotation:vv.default(0),stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled rectangle on the schematic\"),mI=k_.object({type:k_.literal(\"schematic_circle\"),schematic_circle_id:wv(\"schematic_circle\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,radius:gv,stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled circle on the schematic\"),gI=k_.object({type:k_.literal(\"schematic_arc\"),schematic_arc_id:wv(\"schematic_arc\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,radius:gv,start_angle_degrees:vv,end_angle_degrees:vv,direction:k_.enum([\"clockwise\",\"counterclockwise\"]).default(\"counterclockwise\"),stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled arc on the schematic\"),fI=k_.object({type:k_.literal(\"schematic_trace\"),schematic_trace_id:k_.string(),schematic_sheet_id:k_.string().optional(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),yI=k_.enum([\"center\",\"left\",\"right\",\"top\",\"bottom\"]),_I=k_.object({type:k_.literal(\"schematic_text\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:gv,y:gv}),rotation:k_.number().default(0),anchor:k_.union([yI.describe(\"legacy\"),Tv]).default(\"center\"),color:k_.string().default(\"#000000\"),subcircuit_id:k_.string().optional()}),bI=k_.object({type:k_.literal(\"schematic_port\"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),center:Iv,facing_direction:k_.enum([\"up\",\"down\",\"left\",\"right\"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe(\"Defines a port on a schematic component\"),xI=k_.object({type:k_.literal(\"schematic_net_label\"),schematic_net_label_id:wv(\"schematic_net_label\"),schematic_sheet_id:k_.string().optional(),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:Iv,anchor_position:Iv.optional(),anchor_side:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),vI=Gv.extend({type:k_.literal(\"schematic_error\"),schematic_error_id:k_.string(),error_type:k_.literal(\"schematic_port_not_found\").default(\"schematic_port_not_found\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic error on the schematic\"),SI=Gv.extend({type:k_.literal(\"schematic_layout_error\"),schematic_layout_error_id:wv(\"schematic_layout_error\"),error_type:k_.literal(\"schematic_layout_error\").default(\"schematic_layout_error\"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when schematic layout fails for a group\"),II=k_.object({type:k_.literal(\"schematic_debug_object\"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),CI=II.extend({shape:k_.literal(\"rect\"),center:Iv,size:Nv}),PI=II.extend({shape:k_.literal(\"line\"),start:Iv,end:Iv}),MI=II.extend({shape:k_.literal(\"point\"),center:Iv}),NI=k_.discriminatedUnion(\"shape\",[CI,PI,MI]),wI=k_.object({type:k_.literal(\"schematic_voltage_probe\"),schematic_voltage_probe_id:k_.string(),schematic_sheet_id:k_.string().optional(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:Iv,schematic_trace_id:k_.string(),voltage:uv.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:Tv.optional()}).describe(\"Defines a voltage probe measurement point on a schematic trace\"),TI=k_.object({type:k_.literal(\"schematic_manual_edit_conflict_warning\"),schematic_manual_edit_conflict_warning_id:wv(\"schematic_manual_edit_conflict_warning\"),warning_type:k_.literal(\"schematic_manual_edit_conflict_warning\").default(\"schematic_manual_edit_conflict_warning\"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit schX/schY coordinates\"),RI=k_.object({type:k_.literal(\"schematic_group\"),schematic_group_id:wv(\"schematic_group\"),schematic_sheet_id:k_.string().optional(),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:pv,height:pv,center:Iv,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe(\"Defines a group of components on the schematic\"),EI=k_.object({type:k_.literal(\"schematic_table\"),schematic_table_id:wv(\"schematic_table\"),schematic_sheet_id:k_.string().optional(),anchor_position:Iv,column_widths:k_.array(gv),row_heights:k_.array(gv),cell_padding:gv.optional(),border_width:gv.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:Tv.optional()}).describe(\"Defines a table on the schematic\"),AI=k_.object({type:k_.literal(\"schematic_table_cell\"),schematic_table_cell_id:wv(\"schematic_table_cell\"),schematic_sheet_id:k_.string().optional(),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:Iv,width:gv,height:gv,horizontal_align:k_.enum([\"left\",\"center\",\"right\"]).optional(),vertical_align:k_.enum([\"top\",\"middle\",\"bottom\"]).optional(),font_size:gv.optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a cell within a schematic_table\"),OI=k_.object({type:k_.literal(\"schematic_sheet\"),schematic_sheet_id:wv(\"schematic_sheet\"),name:k_.string().optional(),sheet_index:k_.number().optional(),subcircuit_id:k_.string().optional(),outline_color:k_.string().optional()}).describe(\"Defines a schematic sheet or page that components can be placed on\"),kI=k_.object({x:gv,y:gv,bulge:k_.number().optional()}),LI=k_.object({vertices:k_.array(kI)}),DI=k_.object({outer_ring:LI,inner_rings:k_.array(LI).default([])}),zI=k_.object({x:gv,y:gv,via:k_.boolean().optional(),via_to_layer:GS.optional()}),FI=k_.array(zI),BI=k_.object({x:gv,y:gv,via:k_.boolean().optional(),to_layer:GS.optional(),trace_width:gv.optional()}),jI=k_.object({min_trace_width:pv.optional(),min_board_edge_clearance:pv.optional(),min_via_hole_edge_to_via_hole_edge_clearance:pv.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:pv.optional(),min_trace_to_pad_edge_clearance:pv.optional(),min_pad_edge_to_pad_edge_clearance:pv.optional(),min_same_net_trace_edge_to_trace_edge_clearance:pv.optional(),min_different_net_trace_edge_to_trace_edge_clearance:pv.optional(),min_via_edge_to_pad_edge_clearance:pv.optional(),min_via_hole_diameter:pv.optional(),min_via_pad_diameter:pv.optional()}),$I=k_.object({type:k_.literal(\"pcb_component\"),pcb_component_id:wv(\"pcb_component\"),source_component_id:k_.string(),center:Iv,layer:GS,rotation:vv,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this part, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this part, usually corresponding with how the user specified it\"),width:pv,height:pv,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"relative_to_another_component\",\"none\"]).optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:Iv.optional(),insertion_direction:k_.enum([\"from_above\",\"from_left\",\"from_right\",\"from_front\",\"from_back\"]).optional(),metadata:k_.object({kicad_footprint:jv.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe(\"Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath\")}).describe(\"Defines a component on the PCB\"),YI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),hole_diameter:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),XI=YI.describe(\"Defines a circular hole on the PCB\"),VI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),WI=VI.describe(\"Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.\"),HI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"square\"]),hole_diameter:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),GI=HI.describe(\"Defines a circular or square hole on the PCB\"),UI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"oval\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),ZI=UI.describe(\"Defines an oval hole on the PCB\"),qI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),JI=qI.describe(\"Defines a pill-shaped hole on the PCB\"),KI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,ccw_rotation:vv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),QI=KI.describe(\"Defines a rotated pill-shaped hole on the PCB\"),tC=HI.or(UI).or(qI).or(KI).or(YI).or(VI),eC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),nC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.enum([\"oval\",\"pill\"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,ccw_rotation:vv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),oC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circular_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),pad_shape:k_.literal(\"rect\"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:vv.optional()}),iC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),rC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"rotated_pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:vv,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:vv,hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),sC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"hole_with_polygon_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"oval\",\"pill\",\"rotated_pill\"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:gv,y:gv})).min(3),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),ccw_rotation:vv.optional()}),aC=k_.union([eC,nC,oC,iC,rC,sC]),cC=k_.object({type:k_.literal(\"pcb_port\"),pcb_port_id:wv(\"pcb_port\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:gv,y:gv,layers:k_.array(GS),is_board_pinout:k_.boolean().optional()}).describe(\"Defines a port on the PCB\"),lC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"circle\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,radius:k_.number(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),dC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rect\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),hC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_rect\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:vv,layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),uC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"pill\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),pC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_pill\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:vv,layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),mC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"polygon\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(Iv),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),gC=k_.discriminatedUnion(\"shape\",[lC,dC,hC,pC,uC,mC]).describe(\"Defines an SMT pad on the PCB\"),fC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"circle\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,radius:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),yC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rect\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),_C=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"pill\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),bC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rotated_rect\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),ccw_rotation:gv,layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),xC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"oval\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),vC=k_.union([fC,yC,_C,bC,xC]).describe(\"Defines solderpaste on the PCB\"),SC=k_.object({type:k_.literal(\"pcb_text\"),pcb_text_id:wv(\"pcb_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:Iv,layer:GS,width:pv,height:pv,lines:k_.number(),align:k_.enum([\"bottom-left\"])}).describe(\"Defines text on the PCB\"),IC=k_.object({route_type:k_.literal(\"wire\"),x:gv,y:gv,width:gv,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:GS}),CC=k_.object({route_type:k_.literal(\"via\"),x:gv,y:gv,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:gv.optional(),outer_diameter:gv.optional(),from_layer:GS,to_layer:GS}),PC=k_.object({route_type:k_.literal(\"through_pad\"),start:Iv,end:Iv,width:gv,start_layer:GS,end_layer:GS,pcb_smtpad_id:k_.string().optional(),pcb_plated_hole_id:k_.string().optional()}),MC=k_.union([IC,CC,PC]),NC=k_.object({type:k_.literal(\"pcb_trace\"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:wv(\"pcb_trace\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum([\"constant\",\"interpolated\"]).default(\"constant\").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(MC)}).describe(\"Defines a trace on the PCB\"),wC=k_.object({type:k_.literal(\"pcb_trace_warning\"),pcb_trace_warning_id:wv(\"pcb_trace_warning\"),warning_type:k_.literal(\"pcb_trace_warning\").default(\"pcb_trace_warning\"),message:k_.string(),center:Iv.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace warning on the PCB\"),TC=k_.object({type:k_.literal(\"pcb_trace_too_long_warning\"),pcb_trace_too_long_warning_id:wv(\"pcb_trace_too_long_warning\"),warning_type:k_.literal(\"pcb_trace_too_long_warning\").default(\"pcb_trace_too_long_warning\"),message:k_.string(),pcb_trace_id:k_.string(),source_net_id:k_.string().optional(),source_trace_id:k_.string().optional(),actual_trace_length:gv,maximum_trace_length:gv,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a PCB trace is longer than its maximum allowed length\"),RC=Gv.extend({type:k_.literal(\"pcb_trace_error\"),pcb_trace_error_id:wv(\"pcb_trace_error\"),error_type:k_.literal(\"pcb_trace_error\").default(\"pcb_trace_error\"),center:Iv.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB\"),EC=Gv.extend({type:k_.literal(\"pcb_trace_missing_error\"),pcb_trace_missing_error_id:wv(\"pcb_trace_missing_error\"),error_type:k_.literal(\"pcb_trace_missing_error\").default(\"pcb_trace_missing_error\"),center:Iv.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a source trace has no corresponding PCB trace\"),AC=Gv.extend({type:k_.literal(\"pcb_port_not_matched_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_port_not_matched_error\").default(\"pcb_port_not_matched_error\"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB where a port is not matched\"),OC=Gv.extend({type:k_.literal(\"pcb_port_not_connected_error\"),pcb_port_not_connected_error_id:wv(\"pcb_port_not_connected_error\"),error_type:k_.literal(\"pcb_port_not_connected_error\").default(\"pcb_port_not_connected_error\"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a pcb port is not connected to any trace\"),kC=k_.object({type:k_.literal(\"pcb_net\"),pcb_net_id:wv(\"pcb_net\"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe(\"Defines a net on the PCB\"),LC=k_.object({type:k_.literal(\"pcb_via\"),pcb_via_id:wv(\"pcb_via\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:gv,y:gv,outer_diameter:gv.default(\"0.6mm\"),hole_diameter:gv.default(\"0.25mm\"),from_layer:GS.optional(),to_layer:GS.optional(),layers:k_.array(GS),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe(\"Defines a via on the PCB\"),DC=k_.object({type:k_.literal(\"pcb_board\"),pcb_board_id:wv(\"pcb_board\"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:pv.optional(),height:pv.optional(),center:Iv,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this board, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this board, usually corresponding with how the user specified it\"),thickness:pv.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(Iv).optional(),shape:k_.enum([\"rect\",\"polygon\"]).optional(),material:k_.enum([\"fr4\",\"fr1\"]).default(\"fr4\"),solder_mask_color:k_.string().optional(),silkscreen_color:k_.string().optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.optional(),position_mode:k_.enum([\"relative_to_panel_anchor\",\"none\"]).optional()}).merge(jI).describe(\"Defines the board outline of the PCB\"),zC=k_.object({type:k_.literal(\"pcb_panel\"),pcb_panel_id:wv(\"pcb_panel\"),width:pv,height:pv,center:Iv,thickness:pv.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe(\"Defines a PCB panel that can contain multiple boards\"),FC=Gv.extend({type:k_.literal(\"pcb_placement_error\"),pcb_placement_error_id:wv(\"pcb_placement_error\"),error_type:k_.literal(\"pcb_placement_error\").default(\"pcb_placement_error\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a placement error on the PCB\"),BC=Gv.extend({type:k_.literal(\"pcb_panelization_placement_error\"),pcb_panelization_placement_error_id:wv(\"pcb_panelization_placement_error\"),error_type:k_.literal(\"pcb_panelization_placement_error\").default(\"pcb_panelization_placement_error\"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a panelization placement error on the PCB\"),jC=k_.object({type:k_.literal(\"pcb_trace_hint\"),pcb_trace_hint_id:wv(\"pcb_trace_hint\"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(BI),subcircuit_id:k_.string().optional()}).describe(\"A hint that can be used during generation of a PCB trace\"),$C=k_.object({type:k_.literal(\"pcb_silkscreen_line\"),pcb_silkscreen_line_id:wv(\"pcb_silkscreen_line\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:gv.default(\"0.1mm\"),x1:gv,y1:gv,x2:gv,y2:gv,layer:US}).describe(\"Defines a silkscreen line on the PCB\"),YC=k_.object({type:k_.literal(\"pcb_silkscreen_path\"),pcb_silkscreen_path_id:wv(\"pcb_silkscreen_path\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,route:k_.array(Iv),stroke_width:pv}).describe(\"Defines a silkscreen path on the PCB\"),XC=k_.object({type:k_.literal(\"pcb_silkscreen_text\"),pcb_silkscreen_text_id:wv(\"pcb_silkscreen_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:pv,top:pv,bottom:pv,right:pv}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:GS,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:Tv.default(\"center\")}).describe(\"Defines silkscreen text on the PCB\"),VC=k_.object({type:k_.literal(\"pcb_copper_text\"),pcb_copper_text_id:wv(\"pcb_copper_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:pv,top:pv,bottom:pv,right:pv}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:GS,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:Tv.default(\"center\")}).describe(\"Defines copper text on the PCB\"),WC=k_.object({type:k_.literal(\"pcb_silkscreen_rect\"),pcb_silkscreen_rect_id:wv(\"pcb_silkscreen_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:GS,stroke_width:pv.default(\"1mm\"),corner_radius:pv.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen rect on the PCB\"),HC=k_.object({type:k_.literal(\"pcb_silkscreen_circle\"),pcb_silkscreen_circle_id:wv(\"pcb_silkscreen_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:pv,layer:US,stroke_width:pv.default(\"1mm\"),is_filled:k_.boolean().optional()}).describe(\"Defines a silkscreen circle on the PCB\"),GC=k_.object({type:k_.literal(\"pcb_silkscreen_oval\"),pcb_silkscreen_oval_id:wv(\"pcb_silkscreen_oval\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius_x:gv,radius_y:gv,layer:US,ccw_rotation:vv.optional()}).describe(\"Defines a silkscreen oval on the PCB\"),UC=k_.object({type:k_.literal(\"pcb_silkscreen_graphic\"),pcb_silkscreen_graphic_id:wv(\"pcb_silkscreen_graphic\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,image_asset:Ev.optional()}).extend({shape:k_.literal(\"brep\"),brep_shape:DI}).describe(\"Defines a BRep silkscreen graphic on the PCB\"),ZC=k_.discriminatedUnion(\"shape\",[UC]).describe(\"Defines a silkscreen graphic on the PCB\"),qC=k_.object({type:k_.literal(\"pcb_silkscreen_pill\"),pcb_silkscreen_pill_id:wv(\"pcb_silkscreen_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:GS,ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen pill on the PCB\"),JC=k_.object({type:k_.literal(\"pcb_fabrication_note_text\"),pcb_fabrication_note_text_id:wv(\"pcb_fabrication_note_text\"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"1mm\"),pcb_component_id:k_.string(),text:k_.string(),ccw_rotation:k_.number().optional(),layer:US,anchor_position:Iv.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),color:k_.string().optional()}).describe(\"Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators\"),KC=k_.object({type:k_.literal(\"pcb_fabrication_note_path\"),pcb_fabrication_note_path_id:wv(\"pcb_fabrication_note_path\"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:GS,route:k_.array(Iv),stroke_width:pv,color:k_.string().optional()}).describe(\"Defines a fabrication path on the PCB for fabricators or assemblers\"),QC=k_.object({type:k_.literal(\"pcb_fabrication_note_rect\"),pcb_fabrication_note_rect_id:wv(\"pcb_fabrication_note_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US,stroke_width:pv.default(\"0.1mm\"),corner_radius:pv.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a fabrication note rectangle on the PCB\"),tP=k_.object({type:k_.literal(\"pcb_fabrication_note_dimension\"),pcb_fabrication_note_dimension_id:wv(\"pcb_fabrication_note_dimension\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,from:Iv,to:Iv,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:pv.optional(),offset_distance:pv.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:pv.default(\"1mm\"),color:k_.string().optional(),arrow_size:pv.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB fabrication notes\"),eP=k_.object({type:k_.literal(\"pcb_note_text\"),pcb_note_text_id:wv(\"pcb_note_text\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"1mm\"),text:k_.string().optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),layer:US.default(\"top\"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a documentation note in text on the PCB\"),nP=k_.object({type:k_.literal(\"pcb_note_rect\"),pcb_note_rect_id:wv(\"pcb_note_rect\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US.default(\"top\"),stroke_width:pv.default(\"0.1mm\"),corner_radius:pv.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a rectangular documentation note on the PCB\"),oP=k_.object({type:k_.literal(\"pcb_note_path\"),pcb_note_path_id:wv(\"pcb_note_path\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(Iv),layer:US.default(\"top\"),stroke_width:pv.default(\"0.1mm\"),color:k_.string().optional()}).describe(\"Defines a polyline documentation note on the PCB\"),iP=k_.object({type:k_.literal(\"pcb_note_line\"),pcb_note_line_id:wv(\"pcb_note_line\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:gv,y1:gv,x2:gv,y2:gv,layer:US.default(\"top\"),stroke_width:gv.default(\"0.1mm\"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe(\"Defines a straight documentation note line on the PCB\"),rP=k_.object({type:k_.literal(\"pcb_note_dimension\"),pcb_note_dimension_id:wv(\"pcb_note_dimension\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:Iv,to:Iv,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:pv.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:pv.default(\"1mm\"),layer:US.default(\"top\"),color:k_.string().optional(),arrow_size:pv.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB documentation notes\"),sP=Gv.extend({type:k_.literal(\"pcb_footprint_overlap_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_footprint_overlap_error\").default(\"pcb_footprint_overlap_error\"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when a pcb footprint overlaps with another element\"),aP=Gv.extend({type:k_.literal(\"pcb_courtyard_overlap_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_courtyard_overlap_error\").default(\"pcb_courtyard_overlap_error\"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe(\"Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another\"),cP=k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"rect\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:gv,height:gv,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:gv,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),lP=k_.object({type:k_.literal(\"pcb_cutout\"),pcb_cutout_id:wv(\"pcb_cutout\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),dP=lP.extend({shape:k_.literal(\"rect\"),center:Iv,width:pv,height:pv,rotation:vv.optional(),corner_radius:pv.optional()}),hP=lP.extend({shape:k_.literal(\"circle\"),center:Iv,radius:pv}),uP=lP.extend({shape:k_.literal(\"polygon\"),points:k_.array(Iv)}),pP=lP.extend({shape:k_.literal(\"path\"),route:k_.array(Iv),slot_width:pv,slot_length:pv.optional(),space_between_slots:pv.optional(),slot_corner_radius:pv.optional()}),mP=k_.discriminatedUnion(\"shape\",[dP,hP,uP,pP]).describe(\"Defines a cutout on the PCB, removing board material.\"),gP=Gv.extend({type:k_.literal(\"pcb_missing_footprint_error\"),pcb_missing_footprint_error_id:wv(\"pcb_missing_footprint_error\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"pcb_missing_footprint_error\").default(\"pcb_missing_footprint_error\"),source_component_id:k_.string()}).describe(\"Defines a missing footprint error on the PCB\"),fP=Gv.extend({type:k_.literal(\"external_footprint_load_error\"),external_footprint_load_error_id:wv(\"external_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal(\"external_footprint_load_error\").default(\"external_footprint_load_error\")}).describe(\"Defines an error when an external footprint fails to load\"),yP=Gv.extend({type:k_.literal(\"circuit_json_footprint_load_error\"),circuit_json_footprint_load_error_id:wv(\"circuit_json_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"circuit_json_footprint_load_error\").default(\"circuit_json_footprint_load_error\"),circuit_json:k_.array(k_.any()).optional()}).describe(\"Defines an error when a circuit JSON footprint fails to load\"),_P=k_.object({type:k_.literal(\"pcb_group\"),pcb_group_id:wv(\"pcb_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:pv.optional(),height:pv.optional(),center:Iv,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this group, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this group, usually corresponding with how the user specified it\"),outline:k_.array(Iv).optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.default(\"center\"),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"none\"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum([\"packed\",\"none\"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:pv}).optional(),autorouter_used_string:k_.string().optional()}).describe(\"Defines a group of components on the PCB\"),bP=Gv.extend({type:k_.literal(\"pcb_autorouting_error\"),pcb_error_id:wv(\"pcb_autorouting_error\"),error_type:k_.literal(\"pcb_autorouting_error\").default(\"pcb_autorouting_error\"),subcircuit_id:k_.string().optional()}).describe(\"The autorouting has failed to route a portion of the board\"),xP=k_.object({type:k_.literal(\"pcb_manual_edit_conflict_warning\"),pcb_manual_edit_conflict_warning_id:wv(\"pcb_manual_edit_conflict_warning\"),warning_type:k_.literal(\"pcb_manual_edit_conflict_warning\").default(\"pcb_manual_edit_conflict_warning\"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates\"),vP=k_.enum([\"x-\",\"x+\",\"y+\",\"y-\"]),SP=k_.object({type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\"),pcb_connector_not_in_accessible_orientation_warning_id:wv(\"pcb_connector_not_in_accessible_orientation_warning\"),warning_type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\").default(\"pcb_connector_not_in_accessible_orientation_warning\"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:vP,recommended_facing_direction:vP,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction\"),IP=k_.object({type:k_.literal(\"supplier_footprint_mismatch_warning\"),supplier_footprint_mismatch_warning_id:wv(\"supplier_footprint_mismatch_warning\"),warning_type:k_.literal(\"supplier_footprint_mismatch_warning\").default(\"supplier_footprint_mismatch_warning\"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:Uv.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe(\"Warning emitted when a supplier part footprint does not match the expected footprint\"),CP=k_.object({type:k_.literal(\"pcb_breakout_point\"),pcb_breakout_point_id:wv(\"pcb_breakout_point\"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:gv,y:gv}).describe(\"Defines a routing target within a pcb_group for a source_trace or source_net\"),PP=k_.object({type:k_.literal(\"pcb_ground_plane\"),pcb_ground_plane_id:wv(\"pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane on the PCB\"),MP=k_.object({type:k_.literal(\"pcb_ground_plane_region\"),pcb_ground_plane_region_id:wv(\"pcb_ground_plane_region\"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:GS,points:k_.array(Iv)}).describe(\"Defines a polygon region of a ground plane\"),NP=k_.object({type:k_.literal(\"pcb_thermal_spoke\"),pcb_thermal_spoke_id:wv(\"pcb_thermal_spoke\"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:gv,spoke_inner_diameter:gv,spoke_outer_diameter:gv,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Pattern for connecting a ground plane to a plated hole\"),wP=k_.object({type:k_.literal(\"pcb_copper_pour\"),pcb_copper_pour_id:wv(\"pcb_copper_pour\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:GS,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),TP=wP.extend({shape:k_.literal(\"rect\"),center:Iv,width:pv,height:pv,rotation:vv.optional()}),RP=wP.extend({shape:k_.literal(\"brep\"),brep_shape:DI}),EP=wP.extend({shape:k_.literal(\"polygon\"),points:k_.array(Iv)}),AP=k_.discriminatedUnion(\"shape\",[TP,RP,EP]).describe(\"Defines a copper pour on the PCB.\"),OP=Gv.extend({type:k_.literal(\"pcb_component_outside_board_error\"),pcb_component_outside_board_error_id:wv(\"pcb_component_outside_board_error\"),error_type:k_.literal(\"pcb_component_outside_board_error\").default(\"pcb_component_outside_board_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Iv,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a PCB component is placed outside the board boundaries\"),kP=Gv.extend({type:k_.literal(\"pcb_component_not_on_board_edge_error\"),pcb_component_not_on_board_edge_error_id:wv(\"pcb_component_not_on_board_edge_error\"),error_type:k_.literal(\"pcb_component_not_on_board_edge_error\").default(\"pcb_component_not_on_board_edge_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Iv,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component that must be placed on the board edge is centered away from the edge\"),LP=Gv.extend({type:k_.literal(\"pcb_component_invalid_layer_error\"),pcb_component_invalid_layer_error_id:wv(\"pcb_component_invalid_layer_error\"),error_type:k_.literal(\"pcb_component_invalid_layer_error\").default(\"pcb_component_invalid_layer_error\"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:GS,subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)\"),DP=Gv.extend({type:k_.literal(\"pcb_via_clearance_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_via_clearance_error\").default(\"pcb_via_clearance_error\"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when vias are closer than the allowed clearance\"),zP=Gv.extend({type:k_.literal(\"pcb_via_trace_clearance_error\"),pcb_via_trace_clearance_error_id:wv(\"pcb_via_trace_clearance_error\"),error_type:k_.literal(\"pcb_via_trace_clearance_error\").default(\"pcb_via_trace_clearance_error\"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a via and trace are closer than the allowed clearance\"),FP=Gv.extend({type:k_.literal(\"pcb_pad_pad_clearance_error\"),pcb_pad_pad_clearance_error_id:wv(\"pcb_pad_pad_clearance_error\"),error_type:k_.literal(\"pcb_pad_pad_clearance_error\").default(\"pcb_pad_pad_clearance_error\"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when pads are closer than the allowed clearance\"),BP=Gv.extend({type:k_.literal(\"pcb_pad_trace_clearance_error\"),pcb_pad_trace_clearance_error_id:wv(\"pcb_pad_trace_clearance_error\"),error_type:k_.literal(\"pcb_pad_trace_clearance_error\").default(\"pcb_pad_trace_clearance_error\"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pad and trace are closer than allowed clearance\"),jP=k_.object({type:k_.literal(\"pcb_courtyard_rect\"),pcb_courtyard_rect_id:wv(\"pcb_courtyard_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US,ccw_rotation:vv.optional(),color:k_.string().optional()}).describe(\"Defines a courtyard rectangle on the PCB\"),$P=k_.object({type:k_.literal(\"pcb_courtyard_outline\"),pcb_courtyard_outline_id:wv(\"pcb_courtyard_outline\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,outline:k_.array(Iv).min(2)}).describe(\"Defines a courtyard outline on the PCB\"),YP=k_.object({type:k_.literal(\"pcb_courtyard_polygon\"),pcb_courtyard_polygon_id:wv(\"pcb_courtyard_polygon\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,points:k_.array(Iv).min(3),color:k_.string().optional()}).describe(\"Defines a courtyard polygon on the PCB\"),XP=k_.object({type:k_.literal(\"pcb_courtyard_circle\"),pcb_courtyard_circle_id:wv(\"pcb_courtyard_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:pv,layer:US,color:k_.string().optional()}).describe(\"Defines a courtyard circle on the PCB\"),VP=k_.object({type:k_.literal(\"pcb_courtyard_pill\"),pcb_courtyard_pill_id:wv(\"pcb_courtyard_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,radius:pv,layer:US,color:k_.string().optional()}).describe(\"Defines a courtyard pill on the PCB\"),WP=[\"obj\",\"stl\",\"3mf\",\"gltf\",\"glb\",\"step\",\"wrl\"],HP=[\"x+\",\"x-\",\"y+\",\"y-\",\"z+\",\"z-\"],GP={obj:\"z+\",stl:\"z+\",\"3mf\":\"z+\",gltf:\"y+\",glb:\"y+\",step:\"z+\",wrl:\"y+\"},UP=k_.object({type:k_.literal(\"cad_component\"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:Pv,rotation:Pv.optional(),size:Pv.optional(),layer:GS.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:Ev.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum(HP).optional().describe('The direction in the model\\'s coordinate space that is considered \"up\" or \"coming out of the board surface\"'),model_origin_position:Pv.optional(),model_origin_alignment:k_.enum([\"unknown\",\"center\",\"center_of_component_on_board_surface\",\"bottom_center_of_component\"]).optional(),model_object_fit:k_.enum([\"contain_within_bounds\",\"fill_bounds\"]).optional().default(\"contain_within_bounds\"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),show_as_bounding_box:k_.boolean().optional(),anchor_alignment:k_.enum([\"center\",\"center_of_component_on_board_surface\"]).optional().default(\"center\")}).describe(\"Defines a component on the PCB\"),ZP=k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]),qP=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),JP=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:wv(\"simulation_voltage_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:uv}).describe(\"Defines a DC voltage source for simulation\"),KP=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:wv(\"simulation_voltage_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:uv.optional(),frequency:mv.optional(),peak_to_peak_voltage:uv.optional(),wave_shape:ZP.optional(),phase:vv.optional(),duty_cycle:qP.optional(),pulse_delay:bv.optional(),rise_time:bv.optional(),fall_time:bv.optional(),pulse_width:bv.optional(),period:bv.optional()}).describe(\"Defines an AC voltage source for simulation\"),QP=k_.union([JP,KP]).describe(\"Defines a voltage source for simulation\"),tM=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),eM=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:wv(\"simulation_current_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:fv}).describe(\"Defines a DC current source for simulation\"),nM=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:wv(\"simulation_current_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:fv.optional(),frequency:mv.optional(),peak_to_peak_current:fv.optional(),wave_shape:ZP.optional(),phase:vv.optional(),duty_cycle:tM.optional()}).describe(\"Defines an AC current source for simulation\"),oM=k_.union([eM,nM]).describe(\"Defines a current source for simulation\"),iM=k_.union([k_.literal(\"spice_dc_sweep\"),k_.literal(\"spice_dc_operating_point\"),k_.literal(\"spice_transient_analysis\"),k_.literal(\"spice_ac_analysis\")]),rM=k_.object({method:k_.enum([\"trap\",\"gear\"]).optional(),reltol:k_.union([k_.number(),k_.string()]).optional(),abstol:k_.union([k_.number(),k_.string()]).optional(),vntol:k_.union([k_.number(),k_.string()]).optional()}).describe(\"SPICE solver options for a simulation experiment\"),sM=k_.object({type:k_.literal(\"simulation_experiment\"),simulation_experiment_id:wv(\"simulation_experiment\"),name:k_.string(),experiment_type:iM,time_per_step:yv.optional(),start_time_ms:bv.optional(),end_time_ms:bv.optional(),spice_options:rM.optional()}).describe(\"Defines a simulation experiment configuration\"),aM=k_.object({type:k_.literal(\"simulation_transient_voltage_graph\"),simulation_transient_voltage_graph_id:wv(\"simulation_transient_voltage_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:yv,start_time_ms:bv,end_time_ms:bv,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores voltage measurements over time for a simulation\"),cM=k_.object({type:k_.literal(\"simulation_transient_current_graph\"),simulation_transient_current_graph_id:wv(\"simulation_transient_current_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),current_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:yv,start_time_ms:bv,end_time_ms:bv,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores current measurements over time for a simulation\"),lM=k_.object({type:k_.literal(\"simulation_switch\"),simulation_switch_id:wv(\"simulation_switch\"),source_component_id:k_.string().optional(),closes_at:bv.optional(),opens_at:bv.optional(),starts_closed:k_.boolean().optional(),switching_frequency:mv.optional()}).describe(\"Defines a switch for simulation timing control\"),dM=k_.object({type:k_.literal(\"simulation_voltage_probe\"),simulation_voltage_probe_id:wv(\"simulation_voltage_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.\").superRefine((t,e)=\u003e{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n\u0026\u0026o?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a differential probe.\"}):n?t.signal_input_source_port_id\u0026\u0026t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id.\"}):o\u0026\u0026(t.signal_input_source_net_id\u0026\u0026t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id.\"}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id.\"})}),hM=k_.object({type:k_.literal(\"simulation_current_probe\"),simulation_current_probe_id:wv(\"simulation_current_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a current probe for simulation. It measures current flowing from the positive endpoint to the negative endpoint.\").superRefine((t,e)=\u003e{const n=!!t.positive_source_port_id,o=!!t.negative_source_port_id,i=!!t.positive_source_net_id,r=!!t.negative_source_net_id,s=n||o,a=i||r;s\u0026\u0026a?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a current probe.\"}):s?n\u0026\u0026o||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Current probe using source ports requires both positive_source_port_id and negative_source_port_id.\"}):a?i\u0026\u0026r||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Current probe using source nets requires both positive_source_net_id and negative_source_net_id.\"}):e.addIssue({code:k_.ZodIssueCode.custom,message:\"A current probe must have either positive/negative source port ids or positive/negative source net ids.\"})}),uM=Gv.extend({type:k_.literal(\"simulation_unknown_experiment_error\"),simulation_unknown_experiment_error_id:wv(\"simulation_unknown_experiment_error\"),error_type:k_.literal(\"simulation_unknown_experiment_error\").default(\"simulation_unknown_experiment_error\"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"An unknown error occurred during the simulation experiment.\"),pM=k_.object({type:k_.literal(\"simulation_op_amp\"),simulation_op_amp_id:wv(\"simulation_op_amp\"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe(\"Defines a simple ideal operational amplifier for simulation\"),mM=k_.object({type:k_.literal(\"simulation_spice_subcircuit\"),simulation_spice_subcircuit_id:wv(\"simulation_spice_subcircuit\"),source_component_id:k_.string(),spice_pin_to_source_port_map:k_.record(k_.string(),k_.string()),subcircuit_source:k_.string()}).describe(\"Defines a custom SPICE subcircuit model for simulation\"),gM=t=\u003evoid 0!==t,fM=k_.object({type:k_.literal(\"simulation_oscilloscope_trace\"),simulation_oscilloscope_trace_id:wv(\"simulation_oscilloscope_trace\"),simulation_transient_voltage_graph_id:k_.string().optional(),simulation_transient_current_graph_id:k_.string().optional(),simulation_voltage_probe_id:k_.string().optional(),simulation_current_probe_id:k_.string().optional(),display_name:k_.string().optional(),color:k_.string().optional(),display_center_value:k_.number().optional(),display_center_offset_divs:k_.number().optional(),volts_per_div:k_.number().positive().optional(),amps_per_div:k_.number().positive().optional()}).describe(\"Defines how a simulation measurement is rendered as an oscilloscope-style trace.\").superRefine((t,e)=\u003e{const n=[t.simulation_transient_voltage_graph_id,t.simulation_voltage_probe_id].filter(gM).length,o=[t.simulation_transient_current_graph_id,t.simulation_current_probe_id].filter(gM).length;n+o!==1\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"An oscilloscope trace must reference exactly one voltage graph, current graph, voltage probe, or current probe.\"}),n\u003e0\u0026\u0026void 0!==t.amps_per_div\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"Voltage oscilloscope traces must use volts_per_div, not amps_per_div.\"}),o\u003e0\u0026\u0026void 0!==t.volts_per_div\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"Current oscilloscope traces must use amps_per_div, not volts_per_div.\"})}),yM=k_.union([BS,zS,FS,DS,$S,jS,nS,qv,Kv,tS,Jv,oS,cS,lS,pS,gS,fS,vS,yS,_S,bS,xS,hS,dS,VS,ZS,YS,SS,PS,MS,wS,qS,TS,RS,JS,KS,QS,tI,eI,nI,OS,kS,XS,$I,tC,gP,fP,yP,xP,SP,IP,aC,cP,cC,kC,SC,NC,wC,TC,LC,gC,vC,DC,zC,_P,jC,$C,YC,XC,qC,VC,WC,HC,GC,ZC,RC,EC,FC,BC,AC,OC,DP,zP,FP,BP,KC,JC,QC,tP,eP,nP,oP,iP,rP,bP,sP,aP,CP,mP,PP,MP,NP,AP,OP,kP,LP,jP,$P,YP,XP,VP,oI,_I,uI,pI,mI,gI,lI,hI,bI,fI,iI,vI,SI,xI,NI,wI,TI,RI,OI,EI,AI,UP,QP,oM,sM,aM,cM,lM,dM,hM,fM,uM,pM,mM]),_M=yM;function bM(t,e,n){if(!e||!n)return;let o=t.get(e);o||(o=new Set,t.set(e,o)),o.add(n);let i=t.get(n);i||(i=new Set,t.set(n,i)),i.add(e)}var xM=(t,e={})=\u003e{const n=t;let o=n._internal_store;if(!o){o={counts:{},editCount:0},n._internal_store=o;for(const t of n){const e=t.type,n=t[`${e}_id`];if(!n)continue;const i=Number.parseInt(n.split(\"_\").pop());Number.isNaN(i)||(o.counts[e]=Math.max(o.counts[e]??0,i))}}const i=new Proxy({},{get:(t,r)=\u003e{if(\"toArray\"===r)return()=\u003e(n.editCount=o.editCount,n);if(\"editCount\"===r)return o.editCount;if(\"subtree\"===r)return t=\u003exM(function(t,e){if(!e.subcircuit_id\u0026\u0026!e.source_group_id)return[...t];let n=e;if(e.subcircuit_id){const o=new Set([e.subcircuit_id]),i=new Map,r=new Map;for(const e of t)if(\"source_group\"===e.type){const t=e.source_group_id,n=e.subcircuit_id;n\u0026\u0026r.set(t,n);const o=e.parent_source_group_id;o\u0026\u0026(i.has(o)||i.set(o,[]),i.get(o).push(t))}let s;for(const[t,n]of r)if(n===e.subcircuit_id){s=t;break}if(s){const t=e=\u003e{const n=i.get(e)||[];for(const e of n){const n=r.get(e);n\u0026\u0026o.add(n),t(e)}};t(s),n={...e,subcircuit_ids:Array.from(o)}}}const o=new Map;for(const e of t){const t=e[`${e.type}_id`];\"string\"==typeof t\u0026\u0026o.set(t,e)}const i=new Map;for(const e of t){const t=Object.entries(e);for(const[n,r]of t)if(\"parent_source_group_id\"!==n)if(n.endsWith(\"_id\")\u0026\u0026\"string\"==typeof r)bM(i,e,o.get(r));else if(n.endsWith(\"_ids\")\u0026\u0026Array.isArray(r))for(const t of r)\"string\"==typeof t\u0026\u0026bM(i,e,o.get(t))}const r=[],s=new Set;for(const e of t){let t=!1;(n.subcircuit_id\u0026\u0026\"subcircuit_id\"in e\u0026\u0026e.subcircuit_id===n.subcircuit_id||n.subcircuit_ids\u0026\u0026\"subcircuit_id\"in e\u0026\u0026e.subcircuit_id\u0026\u0026n.subcircuit_ids.includes(e.subcircuit_id)||n.source_group_id\u0026\u0026\"source_group_id\"in e\u0026\u0026e.source_group_id===n.source_group_id||n.source_group_id\u0026\u0026\"member_source_group_ids\"in e\u0026\u0026Array.isArray(e.member_source_group_ids)\u0026\u0026e.member_source_group_ids.includes(n.source_group_id))\u0026\u0026(t=!0),t\u0026\u0026(r.push(e),s.add(e))}for(;r.length\u003e0;){const t=r.shift(),e=i.get(t);if(e)for(const t of e)s.has(t)||(s.add(t),r.push(t))}return t.filter(t=\u003es.has(t))}(n,t),e);if(\"insert\"===r)return t=\u003e{const i=t.type;if(!i)throw new Error(\"insert requires an element with a type\");o.counts[i]??=-1,o.counts[i]++;const r=o.counts[i],s={...t,type:i,[`${i}_id`]:`${i}_${r}`};if(e.validateInserts){(S_[i]??_M).parse(s)}return n.push(s),o.editCount++,s};if(\"insertAll\"===r)return t=\u003et.map(t=\u003ei.insert(t));const s=r;return{get:t=\u003en.find(e=\u003ee.type===s\u0026\u0026e[`${s}_id`]===t),getUsing:t=\u003e{const e=Object.keys(t);if(1!==e.length)throw new Error(\"getUsing requires exactly one key, e.g. { pcb_component_id }\");const o=e[0],i=o.replace(\"_id\",\"\"),r=n.find(e=\u003ee.type===i\u0026\u0026e[o]===t[o]);return r?n.find(t=\u003et.type===s\u0026\u0026t[`${s}_id`]===r[`${s}_id`]):null},getWhere:t=\u003e{const e=Object.keys(t);return n.find(n=\u003en.type===s\u0026\u0026e.every(e=\u003en[e]===t[e]))},list:t=\u003e{const e=t?Object.keys(t):[];return n.filter(n=\u003en.type===s\u0026\u0026e.every(e=\u003en[e]===t[e]))},insert:t=\u003e{o.counts[s]??=-1,o.counts[s]++;const i=o.counts[s],r={type:s,[`${s}_id`]:`${s}_${i}`,...t};if(e.validateInserts){(S_[s]??_M).parse(r)}return n.push(r),o.editCount++,r},delete:t=\u003e{const e=n.find(e=\u003ee[`${s}_id`]===t);e\u0026\u0026(n.splice(n.indexOf(e),1),o.editCount++)},update:(t,e)=\u003e{const i=n.find(e=\u003ee.type===s\u0026\u0026e[`${s}_id`]===t);return i?(Object.assign(i,e),o.editCount++,i):null},select:t=\u003e{if(\"source_component\"===s)return n.find(e=\u003e\"source_component\"===e.type\u0026\u0026e.name===t.replace(/\\./g,\"\"));if(\"pcb_port\"===s||\"source_port\"===s||\"schematic_port\"===s){const[e,o]=t.replace(/\\./g,\"\").split(/[\\s\\\u003e]+/),i=n.find(t=\u003e\"source_component\"===t.type\u0026\u0026t.name===e);if(!i)return null;const r=n.find(t=\u003e\"source_port\"===t.type\u0026\u0026t.source_component_id===i.source_component_id\u0026\u0026(t.name===o||(t.port_hints??[]).includes(o)));if(!r)return null;if(\"source_port\"===s)return r;if(\"pcb_port\"===s)return n.find(t=\u003e\"pcb_port\"===t.type\u0026\u0026t.source_port_id===r.source_port_id);if(\"schematic_port\"===s)return n.find(t=\u003e\"schematic_port\"===t.type\u0026\u0026t.source_port_id===r.source_port_id)}}}}});return i};xM.unparsed=xM;var vM=xM;function SM(t){const e=t.type;return`${e}:${t[`${e}_id`]}`}var IM=(t,e={})=\u003e{let n=t._internal_store_indexed;if(!n){n={counts:{},editCount:0,indexes:{}};for(const e of t){const t=e.type,o=e[`${t}_id`];if(!o)continue;const i=Number.parseInt(o.split(\"_\").pop()||\"\");Number.isNaN(i)||(n.counts[t]=Math.max(n.counts[t]??0,i))}const o=e.indexConfig||{},i=n.indexes;if(o.byId\u0026\u0026(i.byId=new Map),o.byType\u0026\u0026(i.byType=new Map),o.byRelation\u0026\u0026(i.byRelation=new Map),o.bySubcircuit\u0026\u0026(i.bySubcircuit=new Map),o.byCustomField\u0026\u0026o.byCustomField.length\u003e0){i.byCustomField=new Map;for(const t of o.byCustomField)i.byCustomField.set(t,new Map)}for(const e of t){if(o.byId){const t=SM(e);i.byId.set(t,e)}if(o.byType){const t=i.byType.get(e.type)||[];t.push(e),i.byType.set(e.type,t)}if(o.byRelation){const t=Object.entries(e);for(const[n,o]of t)if(n.endsWith(\"_id\")\u0026\u0026n!==`${e.type}_id`\u0026\u0026\"string\"==typeof o){const t=i.byRelation.get(n)||new Map,r=t.get(o)||[];r.push(e),t.set(o,r),i.byRelation.set(n,t)}}if(o.bySubcircuit\u0026\u0026\"subcircuit_id\"in e){const t=e.subcircuit_id;if(t\u0026\u0026\"string\"==typeof t){const n=i.bySubcircuit.get(t)||[];n.push(e),i.bySubcircuit.set(t,n)}}if(o.byCustomField\u0026\u0026i.byCustomField)for(const t of o.byCustomField)if(t in e){const n=e[t];if(void 0!==n\u0026\u0026(\"string\"==typeof n||\"number\"==typeof n)){const o=String(n),r=i.byCustomField.get(t),s=r.get(o)||[];s.push(e),r.set(o,s)}}}t._internal_store_indexed=n}return new Proxy({},{get:(o,i)=\u003e{if(\"toArray\"===i)return()=\u003e(t.editCount=n.editCount,t);if(\"editCount\"===i)return n.editCount;const r=i;return{get:o=\u003e{const i=e.indexConfig||{};if(i.byId\u0026\u0026n.indexes.byId)return n.indexes.byId.get(`${r}:${o}`)||null;if(i.byType\u0026\u0026n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=\u003et[`${r}_id`]===o)||null}return t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===o)||null},getUsing:o=\u003e{const i=e.indexConfig||{},s=Object.keys(o);if(1!==s.length)throw new Error(\"getUsing requires exactly one key, e.g. { pcb_component_id }\");const a=s[0],c=a.replace(\"_id\",\"\");if(i.byRelation\u0026\u0026n.indexes.byRelation){const e=n.indexes.byRelation.get(a);if(e){const s=(e.get(o[a])||[]).find(t=\u003et.type===c);if(!s)return null;const l=s[`${r}_id`];if(i.byId\u0026\u0026n.indexes.byId)return n.indexes.byId.get(`${r}:${l}`)||null;if(i.byType\u0026\u0026n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=\u003et[`${r}_id`]===l)||null}return t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===l)||null}}const l=t.find(t=\u003et.type===c\u0026\u0026t[a]===o[a]);return l\u0026\u0026t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===l[`${r}_id`])||null},getWhere:o=\u003e{const i=e.indexConfig||{},s=Object.keys(o);if(1===s.length\u0026\u0026i.byCustomField\u0026\u0026n.indexes.byCustomField){const t=s[0],e=n.indexes.byCustomField.get(t);if(e){const n=String(o[t]);return(e.get(n)||[]).find(t=\u003et.type===r)||null}}if(\"subcircuit_id\"in o\u0026\u0026i.bySubcircuit\u0026\u0026n.indexes.bySubcircuit){const t=o.subcircuit_id;return(n.indexes.bySubcircuit.get(t)||[]).find(t=\u003et.type===r\u0026\u0026s.every(e=\u003et[e]===o[e]))||null}if(i.byType\u0026\u0026n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=\u003es.every(e=\u003et[e]===o[e]))||null}return t.find(t=\u003et.type===r\u0026\u0026s.every(e=\u003et[e]===o[e]))||null},list:o=\u003e{const i=e.indexConfig||{},s=o?Object.keys(o):[];if(0===s.length\u0026\u0026i.byType\u0026\u0026n.indexes.byType)return n.indexes.byType.get(r)||[];if(1===s.length\u0026\u0026\"subcircuit_id\"===s[0]\u0026\u0026i.bySubcircuit\u0026\u0026n.indexes.bySubcircuit){const t=o.subcircuit_id;return(n.indexes.bySubcircuit.get(t)||[]).filter(t=\u003et.type===r)}let a;return a=i.byType\u0026\u0026n.indexes.byType?n.indexes.byType.get(r)||[]:t.filter(t=\u003et.type===r),s.length\u003e0?a.filter(t=\u003es.every(e=\u003et[e]===o[e])):a},insert:o=\u003e{n.counts[r]??=-1,n.counts[r]++;const i=n.counts[r],s={type:r,[`${r}_id`]:`${r}_${i}`,...o};if(e.validateInserts){(S_[r]??_M).parse(s)}t.push(s),n.editCount++;const a=e.indexConfig||{};if(a.byId\u0026\u0026n.indexes.byId){const t=SM(s);n.indexes.byId.set(t,s)}if(a.byType\u0026\u0026n.indexes.byType){const t=n.indexes.byType.get(r)||[];t.push(s),n.indexes.byType.set(r,t)}if(a.byRelation\u0026\u0026n.indexes.byRelation){const t=Object.entries(s);for(const[e,o]of t)if(e.endsWith(\"_id\")\u0026\u0026e!==`${s.type}_id`\u0026\u0026\"string\"==typeof o){const t=n.indexes.byRelation.get(e)||new Map,i=t.get(o)||[];i.push(s),t.set(o,i),n.indexes.byRelation.set(e,t)}}if(a.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in s){const t=s.subcircuit_id;if(t\u0026\u0026\"string\"==typeof t){const e=n.indexes.bySubcircuit.get(t)||[];e.push(s),n.indexes.bySubcircuit.set(t,e)}}if(a.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of a.byCustomField)if(t in s){const e=s[t];if(void 0!==e\u0026\u0026(\"string\"==typeof e||\"number\"==typeof e)){const o=String(e),i=n.indexes.byCustomField.get(t),r=i.get(o)||[];r.push(s),i.set(o,r)}}return s},delete:o=\u003e{const i=e.indexConfig||{};let s;if(i.byId\u0026\u0026n.indexes.byId)s=n.indexes.byId.get(`${r}:${o}`);else if(i.byType\u0026\u0026n.indexes.byType){const t=n.indexes.byType.get(r)||[];s=t.find(t=\u003et[`${r}_id`]===o)}else s=t.find(t=\u003et[`${r}_id`]===o);if(!s)return;const a=t.indexOf(s);if(a\u003e=0\u0026\u0026(t.splice(a,1),n.editCount++),i.byId\u0026\u0026n.indexes.byId){const t=SM(s);n.indexes.byId.delete(t)}if(i.byType\u0026\u0026n.indexes.byType){const t=(n.indexes.byType.get(r)||[]).filter(t=\u003et[`${r}_id`]!==o);n.indexes.byType.set(r,t)}if(i.byRelation\u0026\u0026n.indexes.byRelation)for(const[t,e]of n.indexes.byRelation.entries())for(const[t,n]of e.entries()){const o=n.filter(t=\u003et!==s);0===o.length?e.delete(t):e.set(t,o)}if(i.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in s){const t=s.subcircuit_id;if(t){const e=(n.indexes.bySubcircuit.get(t)||[]).filter(t=\u003et!==s);0===e.length?n.indexes.bySubcircuit.delete(t):n.indexes.bySubcircuit.set(t,e)}}if(i.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of n.indexes.byCustomField.values())for(const[e,n]of t.entries()){const o=n.filter(t=\u003et!==s);0===o.length?t.delete(e):t.set(e,o)}},update:(o,i)=\u003e{const s=e.indexConfig||{};let a;if(s.byId\u0026\u0026n.indexes.byId)a=n.indexes.byId.get(`${r}:${o}`);else if(s.byType\u0026\u0026n.indexes.byType){const t=n.indexes.byType.get(r)||[];a=t.find(t=\u003et[`${r}_id`]===o)}else a=t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===o);if(!a)return null;if(s.byRelation\u0026\u0026n.indexes.byRelation){const t=Object.entries(a);for(const[e,o]of t)if(e.endsWith(\"_id\")\u0026\u0026e!==`${a.type}_id`\u0026\u0026\"string\"==typeof o\u0026\u0026e in i\u0026\u0026i[e]!==o){const t=n.indexes.byRelation.get(e);if(t){const e=(t.get(o)||[]).filter(t=\u003et!==a);0===e.length?t.delete(o):t.set(o,e)}}}if(s.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in a\u0026\u0026\"subcircuit_id\"in i){const t=a.subcircuit_id;if(t!==i.subcircuit_id){const e=(n.indexes.bySubcircuit.get(t)||[]).filter(t=\u003et!==a);0===e.length?n.indexes.bySubcircuit.delete(t):n.indexes.bySubcircuit.set(t,e)}}if(s.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of s.byCustomField)if(t in a\u0026\u0026t in i\u0026\u0026a[t]!==i[t]){const e=n.indexes.byCustomField.get(t);if(e){const n=String(a[t]),o=(e.get(n)||[]).filter(t=\u003et!==a);0===o.length?e.delete(n):e.set(n,o)}}if(Object.assign(a,i),n.editCount++,s.byRelation\u0026\u0026n.indexes.byRelation){const t=Object.entries(a);for(const[e,o]of t)if(e.endsWith(\"_id\")\u0026\u0026e!==`${a.type}_id`\u0026\u0026\"string\"==typeof o\u0026\u0026e in i){const t=n.indexes.byRelation.get(e)||new Map,i=t.get(o)||[];i.includes(a)||(i.push(a),t.set(o,i),n.indexes.byRelation.set(e,t))}}if(s.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in a\u0026\u0026\"subcircuit_id\"in i){const t=a.subcircuit_id;if(t\u0026\u0026\"string\"==typeof t){const e=n.indexes.bySubcircuit.get(t)||[];e.includes(a)||(e.push(a),n.indexes.bySubcircuit.set(t,e))}}if(s.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of s.byCustomField)if(t in a\u0026\u0026t in i){const e=a[t];if(void 0!==e\u0026\u0026(\"string\"==typeof e||\"number\"==typeof e)){const o=String(e),i=n.indexes.byCustomField.get(t),r=i.get(o)||[];r.includes(a)||(r.push(a),i.set(o,r))}}return a},select:e=\u003e{if(\"source_component\"===r)return t.find(t=\u003e\"source_component\"===t.type\u0026\u0026t.name===e.replace(/\\./g,\"\"))||null;if(\"pcb_port\"===r||\"source_port\"===r||\"schematic_port\"===r){const[n,o]=e.replace(/\\./g,\"\").split(/[\\s\\\u003e]+/),i=t.find(t=\u003e\"source_component\"===t.type\u0026\u0026t.name===n);if(!i)return null;const s=t.find(t=\u003e\"source_port\"===t.type\u0026\u0026t.source_component_id===i.source_component_id\u0026\u0026(t.name===o||(t.port_hints??[]).includes(o)));if(!s)return null;if(\"source_port\"===r)return s;if(\"pcb_port\"===r)return t.find(t=\u003e\"pcb_port\"===t.type\u0026\u0026t.source_port_id===s.source_port_id)||null;if(\"schematic_port\"===r)return t.find(t=\u003e\"schematic_port\"===t.type\u0026\u0026t.source_port_id===s.source_port_id)||null}return null}}}})};IM.unparsed=IM;var CM=t=\u003et[`${t.type}_id`];function PM(t,e){const n=xM(t).pcb_trace.get(e);if(!n)return`trace[${e}]`;const o=n.route.flatMap(t=\u003e[t.start_pcb_port_id,t.end_pcb_port_id]).filter(Boolean);if(0===o.length)return`trace[${e}]`;return`trace[${o.map(e=\u003e{const n=function(e){const n=xM(t).pcb_port.get(e);if(!n)return null;const o=n.pcb_component_id?xM(t).pcb_component.get(n.pcb_component_id):void 0;if(!o)return null;const i=xM(t).source_component.get(o.source_component_id);if(!i)return null;const r=xM(t).source_port.get(n.source_port_id),s=r?.port_hints?r.port_hints[1]:\"\";return{componentName:i.name,portHint:s}}(e);return n?`.${n.componentName} \u003e port.${n.portHint}`:`port[${e}]`}).join(\", \")}]`}var MM=(t,e)=\u003e{const n=xM(t).pcb_port.get(e);if(!n)return`pcb_port[#${e}]`;const o=n.pcb_component_id?xM(t).pcb_component.get(n.pcb_component_id):void 0;if(!o)return`pcb_port[#${e}]`;const i=xM(t).source_component.get(o.source_component_id);if(!i)return`pcb_port[#${e}]`;const r=xM(t).source_port.get(n.source_port_id);if(!r)return`pcb_port[#${e}]`;let s;return s=r?.port_hints\u0026\u0026r.port_hints.length\u003e0||r.port_hints\u0026\u0026r.port_hints.length\u003e0?r.port_hints[0]:e,`pcb_port[.${i.name} \u003e .${s}]`};var NM=(t,e)=\u003e{if(\"string\"==typeof e){const n=((t,e)=\u003et.find(t=\u003eCM(t)===e)??null)(t,e);return NM(t,n)}switch(e.type){case\"pcb_port\":return MM(t,e.pcb_port_id);case\"pcb_smtpad\":return function(t,e){const n=xM(t).pcb_smtpad.get(e);return n\u0026\u0026n.pcb_port_id?MM(t,n.pcb_port_id):`smtpad[${e}]`}(t,e.pcb_smtpad_id);case\"pcb_trace\":return PM(t,e.pcb_trace_id);case\"source_component\":return`source_component[${e.name}]`;default:return`${e.type}[#${CM(e)}]`}},wM=(t,e)=\u003e({minX:Math.min(t.minX,e.minX),minY:Math.min(t.minY,e.minY),maxX:Math.max(t.maxX,e.maxX),maxY:Math.max(t.maxY,e.maxY)}),TM=(t,e,n)=\u003e{const o=n/2;return{minX:t-o,minY:e-o,maxX:t+o,maxY:e+o}},RM=(t,e,n,o,i)=\u003e{const r=n/2,s=o/2,a=i*Math.PI/180,c=Math.cos(a),l=Math.sin(a),d=[{x:-r,y:-s},{x:r,y:-s},{x:r,y:s},{x:-r,y:s}].map(n=\u003e({x:t+n.x*c-n.y*l,y:e+n.x*l+n.y*c}));return{minX:Math.min(...d.map(t=\u003et.x)),minY:Math.min(...d.map(t=\u003et.y)),maxX:Math.max(...d.map(t=\u003et.x)),maxY:Math.max(...d.map(t=\u003et.y))}},EM=t=\u003e{let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t){if(!r.type.startsWith(\"pcb_\"))continue;if(\"pcb_smtpad\"===r.type\u0026\u0026\"polygon\"===r.shape\u0026\u0026Array.isArray(r.points)){for(const t of r.points)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);continue}if(\"pcb_hole\"===r.type\u0026\u0026\"circle\"===r.hole_shape){const t=TM(r.x,r.y,r.hole_diameter);e=Math.min(e,t.minX),n=Math.min(n,t.minY),o=Math.max(o,t.maxX),i=Math.max(i,t.maxY);continue}if(\"pcb_plated_hole\"===r.type){let t;if(\"outer_diameter\"in r\u0026\u0026\"number\"==typeof r.outer_diameter?t=TM(r.x,r.y,r.outer_diameter):\"hole_diameter\"in r\u0026\u0026\"number\"==typeof r.hole_diameter\u0026\u0026(t=TM(r.x,r.y,r.hole_diameter)),\"rect_pad_width\"in r\u0026\u0026\"number\"==typeof r.rect_pad_width\u0026\u0026\"rect_pad_height\"in r\u0026\u0026\"number\"==typeof r.rect_pad_height){const e=RM(r.x,r.y,r.rect_pad_width,r.rect_pad_height,\"rect_ccw_rotation\"in r?r.rect_ccw_rotation??0:0);t=t?wM(t,e):e}if(\"hole_diameter\"in r\u0026\u0026\"number\"==typeof r.hole_diameter){const e=TM(r.x+(\"hole_offset_x\"in r?r.hole_offset_x??0:0),r.y+(\"hole_offset_y\"in r?r.hole_offset_y??0:0),r.hole_diameter);t=t?wM(t,e):e}if(t){e=Math.min(e,t.minX),n=Math.min(n,t.minY),o=Math.max(o,t.maxX),i=Math.max(i,t.maxY);continue}}let t,s,a,c;if(\"x\"in r\u0026\u0026\"y\"in r\u0026\u0026(t=Number(r.x),s=Number(r.y)),\"outer_diameter\"in r\u0026\u0026(a=Number(r.outer_diameter),c=Number(r.outer_diameter)),\"width\"in r\u0026\u0026(a=Number(r.width)),\"height\"in r\u0026\u0026(c=Number(r.height)),\"center\"in r\u0026\u0026(t=r.center.x,s=r.center.y),void 0!==t\u0026\u0026void 0!==s)e=Math.min(e,t),n=Math.min(n,s),o=Math.max(o,t),i=Math.max(i,s),void 0!==a\u0026\u0026void 0!==c\u0026\u0026(e=Math.min(e,t-a/2),n=Math.min(n,s-c/2),o=Math.max(o,t+a/2),i=Math.max(i,s+c/2)),\"radius\"in r\u0026\u0026(e=Math.min(e,t-r.radius),n=Math.min(n,s-r.radius),o=Math.max(o,t+r.radius),i=Math.max(i,s+r.radius));else if(\"pcb_trace\"===r.type)for(const t of r.route)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);else if(\"pcb_courtyard_outline\"===r.type)for(const t of r.outline)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);else if(\"pcb_courtyard_polygon\"===r.type)for(const t of r.points)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y)}return{minX:e,minY:n,maxX:o,maxY:i}},AM=t=\u003et[`${t.type}_id`],OM={Hz:{baseUnit:\"Hz\",variants:{MHz:1e6,kHz:1e3,Hz:1}},g:{baseUnit:\"g\",variants:{kg:1e3,g:1}},\"Ω\":{baseUnit:\"Ω\",variants:{\"mΩ\":.001,\"Ω\":1,\"kΩ\":1e3,\"KΩ\":1e3,kohm:1e3,\"MΩ\":1e6,\"GΩ\":1e9,\"TΩ\":1e12}},V:{baseUnit:\"V\",variants:{mV:.001,V:1,kV:1e3,KV:1e3,MV:1e6,GV:1e9,TV:1e12}},A:{baseUnit:\"A\",variants:{\"µA\":1e-6,mA:.001,ma:.001,A:1,kA:1e3,MA:1e6}},F:{baseUnit:\"F\",variants:{pF:1e-12,nF:1e-9,\"µF\":1e-6,uF:1e-6,mF:.001,F:1}},ml:{baseUnit:\"ml\",variants:{ml:1,mL:1,l:1e3,L:1e3}},deg:{baseUnit:\"deg\",variants:{rad:180/Math.PI}},ms:{baseUnit:\"ms\",variants:{fs:1e-12,ps:1e-9,ns:1e-6,us:.001,\"µs\":.001,ms:1,s:1e3}},mm:{baseUnit:\"mm\",variants:{nm:1e-6,\"µm\":.001,um:.001,mm:1,cm:10,dm:100,m:1e3,km:1e6,in:25.4,ft:304.8,IN:25.4,FT:304.8,yd:914.4,mi:1609344,mil:.0254}}},kM=new Set;for(const[t,e]of Object.entries(OM)){kM.add(t);for(const t of Object.keys(e.variants))kM.add(t)}var LM={tera:1e12,T:1e12,giga:1e9,G:1e9,mega:1e6,M:1e6,kilo:1e3,k:1e3,deci:.1,d:.1,centi:.01,c:.01,milli:.001,m:.001,micro:1e-6,u:1e-6,\"µ\":1e-6,nano:1e-9,n:1e-9,pico:1e-12,p:1e-12};function DM(t){if(null==t)return{parsedUnit:null,unitOfValue:null,value:null};if(\"string\"==typeof t\u0026\u0026t.match(/^-?[\\d\\.]+$/))return{value:Number.parseFloat(t),parsedUnit:null,unitOfValue:null};if(\"number\"==typeof t)return{value:t,parsedUnit:null,unitOfValue:null};if(\"object\"==typeof t\u0026\u0026\"x\"in t\u0026\u0026\"y\"in t){const{parsedUnit:e,unitOfValue:n}=DM(t.x),o=DM(t.x),i=DM(t.y);return null===o.value||null===i.value?{parsedUnit:null,unitOfValue:null,value:null}:{parsedUnit:e,unitOfValue:n,value:{x:o.value,y:i.value}}}const e=t.toString().split(\"\").reverse().join(\"\"),n=e.match(/[^\\d\\s]+/)?.[0];if(!n)throw new Error(`Could not determine unit: \"${t}\"`);const o=n.split(\"\").reverse().join(\"\"),i=t.slice(0,-o.length);if(o in LM\u0026\u0026!kM.has(o)){const t=LM[o];return{parsedUnit:null,unitOfValue:null,value:Number.parseFloat(i)*t}}const{baseUnit:r,conversionFactor:s}=function(t){for(const[e,n]of Object.entries(OM))if(t in n.variants)return{baseUnit:n.baseUnit,conversionFactor:n.variants[t]};return{baseUnit:t,conversionFactor:1}}(o);return{parsedUnit:o,unitOfValue:r,value:s*Number.parseFloat(i)}}var zM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),FM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value).transform(t=\u003eNumber.parseFloat(t.toPrecision(12))),BM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),jM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),$M=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),YM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),XM=$M,VM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),WM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),HM=WM,GM=k_.string().datetime(),UM=k_.string().or(k_.number()).transform(t=\u003e\"number\"==typeof t?t:t.endsWith(\"deg\")?Number.parseFloat(t.split(\"deg\")[0]):t.endsWith(\"rad\")?180*Number.parseFloat(t.split(\"rad\")[0])/Math.PI:Number.parseFloat(t)),ZM=k_.number().or(k_.string().endsWith(\"mAh\")).transform(t=\u003e{if(\"string\"==typeof t){const e=t.replace(\"mAh\",\"\"),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error(\"Invalid capacity\");return n}return t}).describe(\"Battery capacity in mAh\"),qM=k_.object({x:XM,y:XM}),JM=k_.object({x:XM,y:XM,z:XM}),KM=k_.object({width:k_.number(),height:k_.number()}),QM=t=\u003ek_.string().optional().default(()=\u003e`${t}_${(t=\u003e{const e=\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";return Array.from({length:t},()=\u003ee[Math.floor(62*Math.random())]).join(\"\")})(10)}`),tN=k_.enum([\"top_left\",\"top_center\",\"top_right\",\"center_left\",\"center\",\"center_right\",\"bottom_left\",\"bottom_center\",\"bottom_right\"]),eN=(k_.enum([\"top_silkscreen\",\"bottom_silkscreen\",\"top_copper\",\"bottom_copper\",\"top_soldermask\",\"bottom_soldermask\",\"top_fabrication_note\",\"bottom_fabrication_note\",\"top_user_note\",\"bottom_user_note\",\"top_courtyard\",\"bottom_courtyard\",\"inner1_copper\",\"inner2_copper\",\"inner3_copper\",\"inner4_copper\",\"inner5_copper\",\"inner6_copper\",\"edge_cuts\",\"drill\"]),k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()})),nN=qM.extend({rotation:UM.optional()}),oN=k_.object({size:qM.optional(),thickness:XM.optional()}),iN=k_.object({font:oN.optional()}),rN=k_.object({value:k_.string(),at:nN.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:iN.optional()}),sN=k_.object({Reference:rN.optional(),Value:rN.optional(),Datasheet:rN.optional(),Description:rN.optional()}),aN=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),cN=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:nN.optional(),size:qM.optional(),drill:XM.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),lN=k_.object({path:k_.string(),offset:JM.optional(),scale:JM.optional(),rotate:JM.optional()}),dN=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:sN.optional(),attributes:aN.optional(),pads:k_.array(cN).optional(),embeddedFonts:k_.boolean().optional(),model:lN.optional()}),hN=k_.object({hide:k_.boolean().optional()}),uN=k_.object({offset:XM.optional(),hide:k_.boolean().optional()}),pN=k_.object({font:oN.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),mN=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:nN.optional(),effects:pN.optional()}),gN=k_.object({Reference:mN.optional(),Value:mN.optional(),Footprint:mN.optional(),Datasheet:mN.optional(),Description:mN.optional(),ki_keywords:mN.optional(),ki_fp_filters:mN.optional()}),fN=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:hN.optional(),pinNames:uN.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:gN.optional(),embeddedFonts:k_.boolean().optional()}),yN=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),_N=k_.enum([\"jlcpcb\",\"macrofab\",\"pcbway\",\"digikey\",\"mouser\",\"lcsc\"]),bN=k_.object({type:k_.literal(\"source_component\"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(_N,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),xN=bN.extend({ftype:k_.literal(\"simple_capacitor\"),capacitance:FM,max_voltage_rating:jM.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:XM.optional()}),vN=bN.extend({ftype:k_.literal(\"simple_resistor\"),resistance:zM,display_resistance:k_.string().optional()}),SN=bN.extend({ftype:k_.literal(\"simple_diode\")}),IN=bN.extend({ftype:k_.literal(\"simple_fiducial\")}),CN=SN.extend({ftype:k_.literal(\"simple_led\"),color:k_.string().optional(),wavelength:k_.string().optional()}),PN=bN.extend({ftype:k_.literal(\"simple_ground\")}),MN=bN.extend({ftype:k_.literal(\"simple_chip\")}),NN=bN.extend({ftype:k_.literal(\"simple_power_source\"),voltage:jM}),wN=bN.extend({ftype:k_.literal(\"simple_current_source\"),current:VM,frequency:YM.optional(),peak_to_peak_current:VM.optional(),wave_shape:k_.enum([\"sine\",\"square\",\"triangle\",\"sawtooth\",\"dc\"]).optional().default(\"dc\"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),TN=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),RN=bN.extend({ftype:k_.literal(\"simple_fuse\"),current_rating_amps:k_.number().describe(\"Nominal current in amps the fuse is rated for\"),voltage_rating_volts:k_.number().describe(\"Voltage rating in volts, e.g. ±5V would be 5\")}),EN=bN.extend({ftype:k_.literal(\"simple_battery\"),capacity:ZM}),AN=bN.extend({ftype:k_.literal(\"simple_inductor\"),inductance:BM,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),ON=bN.extend({ftype:k_.literal(\"simple_push_button\")}),kN=bN.extend({ftype:k_.literal(\"simple_potentiometer\"),max_resistance:zM,display_max_resistance:k_.string().optional()}),LN=bN.extend({ftype:k_.literal(\"simple_crystal\"),frequency:k_.number().describe(\"Frequency in Hz\"),load_capacitance:k_.number().optional().describe(\"Load capacitance in pF\"),pin_variant:k_.enum([\"two_pin\",\"four_pin\"]).optional()}),DN=bN.extend({ftype:k_.literal(\"simple_pin_header\"),pin_count:k_.number(),gender:k_.enum([\"male\",\"female\"]).optional().default(\"male\")}),zN=bN.extend({ftype:k_.literal(\"simple_connector\"),standard:k_.enum([\"usb_c\",\"m2\"]).optional()}),FN=bN.extend({ftype:k_.literal(\"simple_pinout\")}),BN=bN.extend({ftype:k_.literal(\"simple_resonator\"),load_capacitance:FM,equivalent_series_resistance:zM.optional(),frequency:YM}),jN=bN.extend({ftype:k_.literal(\"simple_transistor\"),transistor_type:k_.enum([\"npn\",\"pnp\"])}),$N=bN.extend({ftype:k_.literal(\"simple_test_point\"),footprint_variant:k_.enum([\"pad\",\"through_hole\"]).optional(),pad_shape:k_.enum([\"rect\",\"circle\"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),YN=bN.extend({ftype:k_.literal(\"simple_mosfet\"),channel_type:k_.enum([\"n\",\"p\"]),mosfet_mode:k_.enum([\"enhancement\",\"depletion\"])}),XN=bN.extend({ftype:k_.literal(\"simple_op_amp\")}),VN=bN.extend({ftype:k_.literal(\"simple_switch\")}),WN=k_.object({type:k_.literal(\"source_project_metadata\"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),created_at:GM.optional()}),HN=yN.extend({type:k_.literal(\"source_missing_property_error\"),source_missing_property_error_id:QM(\"source_missing_property_error\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_missing_property_error\").default(\"source_missing_property_error\")}).describe(\"The source code is missing a property\"),GN=yN.extend({type:k_.literal(\"source_failed_to_create_component_error\"),source_failed_to_create_component_error_id:QM(\"source_failed_to_create_component_error\"),error_type:k_.literal(\"source_failed_to_create_component_error\").default(\"source_failed_to_create_component_error\"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe(\"Error emitted when a component fails to be constructed\"),UN=yN.extend({type:k_.literal(\"source_invalid_component_property_error\"),source_invalid_component_property_error_id:QM(\"source_invalid_component_property_error\"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_invalid_component_property_error\").default(\"source_invalid_component_property_error\")}).describe(\"The source component property is invalid\"),ZN=yN.extend({type:k_.literal(\"source_trace_not_connected_error\"),source_trace_not_connected_error_id:QM(\"source_trace_not_connected_error\"),error_type:k_.literal(\"source_trace_not_connected_error\").default(\"source_trace_not_connected_error\"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe(\"Occurs when a source trace selector does not match any ports\"),qN=k_.object({type:k_.literal(\"source_property_ignored_warning\"),source_property_ignored_warning_id:QM(\"source_property_ignored_warning\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_property_ignored_warning\").default(\"source_property_ignored_warning\"),message:k_.string()}).describe(\"The source property was ignored\"),JN=k_.object({type:k_.literal(\"source_pin_missing_trace_warning\"),source_pin_missing_trace_warning_id:QM(\"source_pin_missing_trace_warning\"),warning_type:k_.literal(\"source_pin_missing_trace_warning\").default(\"source_pin_missing_trace_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component pin is missing a trace connection\"),KN=k_.object({type:k_.literal(\"source_missing_manufacturer_part_number_warning\"),source_missing_manufacturer_part_number_warning_id:QM(\"source_missing_manufacturer_part_number_warning\"),warning_type:k_.literal(\"source_missing_manufacturer_part_number_warning\").default(\"source_missing_manufacturer_part_number_warning\"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a standard connector is missing manufacturer part number\"),QN=bN.extend({ftype:k_.literal(\"simple_voltage_probe\")}),tw=bN.extend({ftype:k_.literal(\"interconnect\")}),ew=yN.extend({type:k_.literal(\"source_i2c_misconfigured_error\"),source_i2c_misconfigured_error_id:QM(\"source_i2c_misconfigured_error\"),error_type:k_.literal(\"source_i2c_misconfigured_error\").default(\"source_i2c_misconfigured_error\"),source_port_ids:k_.array(k_.string())}).describe(\"Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net\"),nw=bN.extend({ftype:k_.literal(\"simple_voltage_source\"),voltage:jM,frequency:YM.optional(),peak_to_peak_voltage:jM.optional(),wave_shape:k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]).optional(),phase:UM.optional(),duty_cycle:k_.number().optional().describe(\"Duty cycle as a fraction (0 to 1)\")}),ow=k_.union([vN,xN,SN,IN,CN,PN,MN,NN,wN,EN,AN,ON,kN,LN,DN,zN,FN,BN,VN,jN,$N,YN,XN,RN,QN,tw,nw,WN,HN,UN,GN,ZN,qN,JN,KN,ew]),iw=k_.object({type:k_.literal(\"source_port\"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(TN),rw=k_.object({type:k_.literal(\"source_component_internal_connection\"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),sw=k_.object({type:k_.literal(\"source_trace\"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),aw=k_.object({type:k_.literal(\"source_group\"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),cw=k_.object({type:k_.literal(\"source_net\"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),lw=k_.object({type:k_.literal(\"source_board\"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe(\"Defines a board in the source domain\"),dw=yN.extend({type:k_.literal(\"source_ambiguous_port_reference\"),source_ambiguous_port_reference_id:QM(\"source_ambiguous_port_reference\"),error_type:k_.literal(\"source_ambiguous_port_reference\").default(\"source_ambiguous_port_reference\"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous\"),hw=k_.object({type:k_.literal(\"source_pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane in the source domain\"),uw=[\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\"],pw=k_.enum(uw),mw=pw.or(k_.object({name:pw})).transform(t=\u003e\"string\"==typeof t?t:t.name),gw=k_.enum([\"top\",\"bottom\"]),fw=k_.object({type:k_.literal(\"source_manually_placed_via\"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe(\"Defines a via that is manually placed in the source domain\"),yw=k_.object({type:k_.literal(\"source_no_power_pin_defined_warning\"),source_no_power_pin_defined_warning_id:QM(\"source_no_power_pin_defined_warning\"),warning_type:k_.literal(\"source_no_power_pin_defined_warning\").default(\"source_no_power_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports with requires_power=true\"),_w=k_.object({type:k_.literal(\"source_no_ground_pin_defined_warning\"),source_no_ground_pin_defined_warning_id:QM(\"source_no_ground_pin_defined_warning\"),warning_type:k_.literal(\"source_no_ground_pin_defined_warning\").default(\"source_no_ground_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports marked as ground pins\"),bw=k_.object({type:k_.literal(\"source_component_pins_underspecified_warning\"),source_component_pins_underspecified_warning_id:QM(\"source_component_pins_underspecified_warning\"),warning_type:k_.literal(\"source_component_pins_underspecified_warning\").default(\"source_component_pins_underspecified_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when all ports on a source component are underspecified\"),xw=yN.extend({type:k_.literal(\"source_pin_must_be_connected_error\"),source_pin_must_be_connected_error_id:QM(\"source_pin_must_be_connected_error\"),error_type:k_.literal(\"source_pin_must_be_connected_error\").default(\"source_pin_must_be_connected_error\"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pin with mustBeConnected attribute is not connected to any trace\"),vw=yN.extend({type:k_.literal(\"unknown_error_finding_part\"),unknown_error_finding_part_id:QM(\"unknown_error_finding_part\"),error_type:k_.literal(\"unknown_error_finding_part\").default(\"unknown_error_finding_part\"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when an unexpected error occurs while finding a part\"),Sw=k_.object({type:k_.literal(\"schematic_box\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:XM,height:XM,is_dashed:k_.boolean().default(!1),x:XM,y:XM,subcircuit_id:k_.string().optional()}).describe(\"Draws a box on the schematic\"),Iw=k_.object({type:k_.literal(\"schematic_path\"),schematic_path_id:QM(\"schematic_path\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),stroke_width:XM.nullable().optional(),stroke_color:k_.string().optional(),points:k_.array(qM),subcircuit_id:k_.string().optional()}),Cw=k_.record(k_.object({left_margin:$M.optional(),right_margin:$M.optional(),top_margin:$M.optional(),bottom_margin:$M.optional()})),Pw=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),Mw=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional()}),Nw=k_.union([Pw,Mw]),ww=k_.object({type:k_.literal(\"schematic_component\"),size:KM,center:qM,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_symbol_id:k_.string().optional(),pin_spacing:$M.optional(),pin_styles:Cw.optional(),box_width:$M.optional(),symbol_name:k_.string().optional(),port_arrangement:Nw.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),Tw=k_.object({kicad_symbol:fN.optional()}).catchall(k_.unknown()),Rw=k_.object({type:k_.literal(\"schematic_symbol\"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:Tw.optional()}).describe(\"Defines a named schematic symbol that can be referenced by components.\"),Ew=k_.object({type:k_.literal(\"schematic_line\"),schematic_line_id:QM(\"schematic_line\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:XM,y1:XM,x2:XM,y2:XM,stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled line on the schematic\"),Aw=k_.object({type:k_.literal(\"schematic_rect\"),schematic_rect_id:QM(\"schematic_rect\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,width:XM,height:XM,rotation:UM.default(0),stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled rectangle on the schematic\"),Ow=k_.object({type:k_.literal(\"schematic_circle\"),schematic_circle_id:QM(\"schematic_circle\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,radius:XM,stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled circle on the schematic\"),kw=k_.object({type:k_.literal(\"schematic_arc\"),schematic_arc_id:QM(\"schematic_arc\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,radius:XM,start_angle_degrees:UM,end_angle_degrees:UM,direction:k_.enum([\"clockwise\",\"counterclockwise\"]).default(\"counterclockwise\"),stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled arc on the schematic\"),Lw=k_.object({type:k_.literal(\"schematic_trace\"),schematic_trace_id:k_.string(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),Dw=k_.enum([\"center\",\"left\",\"right\",\"top\",\"bottom\"]),zw=k_.object({type:k_.literal(\"schematic_text\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:XM,y:XM}),rotation:k_.number().default(0),anchor:k_.union([Dw.describe(\"legacy\"),tN]).default(\"center\"),color:k_.string().default(\"#000000\"),subcircuit_id:k_.string().optional()}),Fw=k_.object({type:k_.literal(\"schematic_port\"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_component_id:k_.string().optional(),center:qM,facing_direction:k_.enum([\"up\",\"down\",\"left\",\"right\"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe(\"Defines a port on a schematic component\"),Bw=k_.object({type:k_.literal(\"schematic_net_label\"),schematic_net_label_id:QM(\"schematic_net_label\"),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:qM,anchor_position:qM.optional(),anchor_side:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),jw=yN.extend({type:k_.literal(\"schematic_error\"),schematic_error_id:k_.string(),error_type:k_.literal(\"schematic_port_not_found\").default(\"schematic_port_not_found\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic error on the schematic\"),$w=yN.extend({type:k_.literal(\"schematic_layout_error\"),schematic_layout_error_id:QM(\"schematic_layout_error\"),error_type:k_.literal(\"schematic_layout_error\").default(\"schematic_layout_error\"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when schematic layout fails for a group\"),Yw=k_.object({type:k_.literal(\"schematic_debug_object\"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),Xw=Yw.extend({shape:k_.literal(\"rect\"),center:qM,size:KM}),Vw=Yw.extend({shape:k_.literal(\"line\"),start:qM,end:qM}),Ww=Yw.extend({shape:k_.literal(\"point\"),center:qM}),Hw=k_.discriminatedUnion(\"shape\",[Xw,Vw,Ww]),Gw=k_.object({type:k_.literal(\"schematic_voltage_probe\"),schematic_voltage_probe_id:k_.string(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:qM,schematic_trace_id:k_.string(),voltage:jM.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:tN.optional()}).describe(\"Defines a voltage probe measurement point on a schematic trace\"),Uw=k_.object({type:k_.literal(\"schematic_manual_edit_conflict_warning\"),schematic_manual_edit_conflict_warning_id:QM(\"schematic_manual_edit_conflict_warning\"),warning_type:k_.literal(\"schematic_manual_edit_conflict_warning\").default(\"schematic_manual_edit_conflict_warning\"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit schX/schY coordinates\"),Zw=k_.object({type:k_.literal(\"schematic_group\"),schematic_group_id:QM(\"schematic_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:$M,height:$M,center:qM,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe(\"Defines a group of components on the schematic\"),qw=k_.object({type:k_.literal(\"schematic_table\"),schematic_table_id:QM(\"schematic_table\"),anchor_position:qM,column_widths:k_.array(XM),row_heights:k_.array(XM),cell_padding:XM.optional(),border_width:XM.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:tN.optional()}).describe(\"Defines a table on the schematic\"),Jw=k_.object({type:k_.literal(\"schematic_table_cell\"),schematic_table_cell_id:QM(\"schematic_table_cell\"),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:qM,width:XM,height:XM,horizontal_align:k_.enum([\"left\",\"center\",\"right\"]).optional(),vertical_align:k_.enum([\"top\",\"middle\",\"bottom\"]).optional(),font_size:XM.optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a cell within a schematic_table\"),Kw=k_.object({type:k_.literal(\"schematic_sheet\"),schematic_sheet_id:QM(\"schematic_sheet\"),name:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic sheet or page that components can be placed on\"),Qw=k_.object({x:XM,y:XM,bulge:k_.number().optional()}),tT=k_.object({vertices:k_.array(Qw)}),eT=k_.object({outer_ring:tT,inner_rings:k_.array(tT).default([])}),nT=k_.object({x:XM,y:XM,via:k_.boolean().optional(),via_to_layer:mw.optional()}),oT=(k_.array(nT),k_.object({x:XM,y:XM,via:k_.boolean().optional(),to_layer:mw.optional(),trace_width:XM.optional()})),iT=k_.object({min_trace_width:$M.optional(),min_board_edge_clearance:$M.optional(),min_via_hole_edge_to_via_hole_edge_clearance:$M.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:$M.optional(),min_trace_to_pad_edge_clearance:$M.optional(),min_pad_edge_to_pad_edge_clearance:$M.optional(),min_same_net_trace_edge_to_trace_edge_clearance:$M.optional(),min_different_net_trace_edge_to_trace_edge_clearance:$M.optional(),min_via_hole_diameter:$M.optional(),min_via_pad_diameter:$M.optional()}),rT=k_.object({type:k_.literal(\"pcb_component\"),pcb_component_id:QM(\"pcb_component\"),source_component_id:k_.string(),center:qM,layer:mw,rotation:UM,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this part, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this part, usually corresponding with how the user specified it\"),width:$M,height:$M,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"relative_to_another_component\",\"none\"]).optional(),anchor_position:qM.optional(),anchor_alignment:tN.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:qM.optional(),insertion_direction:k_.enum([\"from_above\",\"from_left\",\"from_right\",\"from_front\",\"from_back\"]).optional(),metadata:k_.object({kicad_footprint:dN.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe(\"Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath\")}).describe(\"Defines a component on the PCB\"),sT=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),hole_diameter:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),aT=(sT.describe(\"Defines a circular hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),cT=(aT.describe(\"Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"square\"]),hole_diameter:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),lT=(cT.describe(\"Defines a circular or square hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"oval\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),dT=(lT.describe(\"Defines an oval hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),hT=(dT.describe(\"Defines a pill-shaped hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,ccw_rotation:UM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),uT=(hT.describe(\"Defines a rotated pill-shaped hole on the PCB\"),cT.or(lT).or(dT).or(hT).or(sT).or(aT)),pT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),mT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.enum([\"oval\",\"pill\"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,ccw_rotation:UM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),gT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circular_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),pad_shape:k_.literal(\"rect\"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:UM.optional()}),fT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),yT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"rotated_pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:UM,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:UM,hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),_T=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"hole_with_polygon_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"oval\",\"pill\",\"rotated_pill\"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:XM,y:XM})).min(3),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),ccw_rotation:UM.optional()}),bT=k_.union([pT,mT,gT,fT,yT,_T]),xT=k_.object({type:k_.literal(\"pcb_port\"),pcb_port_id:QM(\"pcb_port\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:XM,y:XM,layers:k_.array(mw),is_board_pinout:k_.boolean().optional()}).describe(\"Defines a port on the PCB\"),vT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"circle\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,radius:k_.number(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),ST=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rect\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),IT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_rect\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:UM,layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),CT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"pill\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),PT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_pill\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:UM,layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),MT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"polygon\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(qM),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),NT=k_.discriminatedUnion(\"shape\",[vT,ST,IT,PT,CT,MT]).describe(\"Defines an SMT pad on the PCB\"),wT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"circle\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,radius:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),TT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rect\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),RT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"pill\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),ET=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rotated_rect\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),ccw_rotation:XM,layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),AT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"oval\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),OT=k_.union([wT,TT,RT,ET,AT]).describe(\"Defines solderpaste on the PCB\"),kT=k_.object({type:k_.literal(\"pcb_text\"),pcb_text_id:QM(\"pcb_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:qM,layer:mw,width:$M,height:$M,lines:k_.number(),align:k_.enum([\"bottom-left\"])}).describe(\"Defines text on the PCB\"),LT=k_.object({route_type:k_.literal(\"wire\"),x:XM,y:XM,width:XM,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:mw}),DT=k_.object({route_type:k_.literal(\"via\"),x:XM,y:XM,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:XM.optional(),outer_diameter:XM.optional(),from_layer:mw,to_layer:mw}),zT=k_.union([LT,DT]),FT=k_.object({type:k_.literal(\"pcb_trace\"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:QM(\"pcb_trace\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum([\"constant\",\"interpolated\"]).default(\"constant\").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(zT)}).describe(\"Defines a trace on the PCB\"),BT=k_.object({type:k_.literal(\"pcb_trace_warning\"),pcb_trace_warning_id:QM(\"pcb_trace_warning\"),warning_type:k_.literal(\"pcb_trace_warning\").default(\"pcb_trace_warning\"),message:k_.string(),center:qM.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace warning on the PCB\"),jT=yN.extend({type:k_.literal(\"pcb_trace_error\"),pcb_trace_error_id:QM(\"pcb_trace_error\"),error_type:k_.literal(\"pcb_trace_error\").default(\"pcb_trace_error\"),center:qM.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB\"),$T=yN.extend({type:k_.literal(\"pcb_trace_missing_error\"),pcb_trace_missing_error_id:QM(\"pcb_trace_missing_error\"),error_type:k_.literal(\"pcb_trace_missing_error\").default(\"pcb_trace_missing_error\"),center:qM.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a source trace has no corresponding PCB trace\"),YT=yN.extend({type:k_.literal(\"pcb_port_not_matched_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_port_not_matched_error\").default(\"pcb_port_not_matched_error\"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB where a port is not matched\"),XT=yN.extend({type:k_.literal(\"pcb_port_not_connected_error\"),pcb_port_not_connected_error_id:QM(\"pcb_port_not_connected_error\"),error_type:k_.literal(\"pcb_port_not_connected_error\").default(\"pcb_port_not_connected_error\"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a pcb port is not connected to any trace\"),VT=k_.object({type:k_.literal(\"pcb_net\"),pcb_net_id:QM(\"pcb_net\"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe(\"Defines a net on the PCB\"),WT=k_.object({type:k_.literal(\"pcb_via\"),pcb_via_id:QM(\"pcb_via\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:XM,y:XM,outer_diameter:XM.default(\"0.6mm\"),hole_diameter:XM.default(\"0.25mm\"),from_layer:mw.optional(),to_layer:mw.optional(),layers:k_.array(mw),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe(\"Defines a via on the PCB\"),HT=k_.object({type:k_.literal(\"pcb_board\"),pcb_board_id:QM(\"pcb_board\"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:$M.optional(),height:$M.optional(),center:qM,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this board, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this board, usually corresponding with how the user specified it\"),thickness:$M.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(qM).optional(),shape:k_.enum([\"rect\",\"polygon\"]).optional(),material:k_.enum([\"fr4\",\"fr1\"]).default(\"fr4\"),anchor_position:qM.optional(),anchor_alignment:tN.optional(),position_mode:k_.enum([\"relative_to_panel_anchor\",\"none\"]).optional()}).merge(iT).describe(\"Defines the board outline of the PCB\"),GT=k_.object({type:k_.literal(\"pcb_panel\"),pcb_panel_id:QM(\"pcb_panel\"),width:$M,height:$M,center:qM,thickness:$M.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe(\"Defines a PCB panel that can contain multiple boards\"),UT=yN.extend({type:k_.literal(\"pcb_placement_error\"),pcb_placement_error_id:QM(\"pcb_placement_error\"),error_type:k_.literal(\"pcb_placement_error\").default(\"pcb_placement_error\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a placement error on the PCB\"),ZT=yN.extend({type:k_.literal(\"pcb_panelization_placement_error\"),pcb_panelization_placement_error_id:QM(\"pcb_panelization_placement_error\"),error_type:k_.literal(\"pcb_panelization_placement_error\").default(\"pcb_panelization_placement_error\"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a panelization placement error on the PCB\"),qT=k_.object({type:k_.literal(\"pcb_trace_hint\"),pcb_trace_hint_id:QM(\"pcb_trace_hint\"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(oT),subcircuit_id:k_.string().optional()}).describe(\"A hint that can be used during generation of a PCB trace\"),JT=k_.object({type:k_.literal(\"pcb_silkscreen_line\"),pcb_silkscreen_line_id:QM(\"pcb_silkscreen_line\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:XM.default(\"0.1mm\"),x1:XM,y1:XM,x2:XM,y2:XM,layer:gw}).describe(\"Defines a silkscreen line on the PCB\"),KT=k_.object({type:k_.literal(\"pcb_silkscreen_path\"),pcb_silkscreen_path_id:QM(\"pcb_silkscreen_path\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,route:k_.array(qM),stroke_width:$M}).describe(\"Defines a silkscreen path on the PCB\"),QT=k_.object({type:k_.literal(\"pcb_silkscreen_text\"),pcb_silkscreen_text_id:QM(\"pcb_silkscreen_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:$M,top:$M,bottom:$M,right:$M}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:mw,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:tN.default(\"center\")}).describe(\"Defines silkscreen text on the PCB\"),tR=k_.object({type:k_.literal(\"pcb_copper_text\"),pcb_copper_text_id:QM(\"pcb_copper_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:$M,top:$M,bottom:$M,right:$M}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:mw,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:tN.default(\"center\")}).describe(\"Defines copper text on the PCB\"),eR=k_.object({type:k_.literal(\"pcb_silkscreen_rect\"),pcb_silkscreen_rect_id:QM(\"pcb_silkscreen_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:mw,stroke_width:$M.default(\"1mm\"),corner_radius:$M.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen rect on the PCB\"),nR=k_.object({type:k_.literal(\"pcb_silkscreen_circle\"),pcb_silkscreen_circle_id:QM(\"pcb_silkscreen_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:$M,layer:gw,stroke_width:$M.default(\"1mm\"),is_filled:k_.boolean().optional()}).describe(\"Defines a silkscreen circle on the PCB\"),oR=k_.object({type:k_.literal(\"pcb_silkscreen_oval\"),pcb_silkscreen_oval_id:QM(\"pcb_silkscreen_oval\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius_x:XM,radius_y:XM,layer:gw,ccw_rotation:UM.optional()}).describe(\"Defines a silkscreen oval on the PCB\"),iR=k_.object({type:k_.literal(\"pcb_silkscreen_pill\"),pcb_silkscreen_pill_id:QM(\"pcb_silkscreen_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:mw,ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen pill on the PCB\"),rR=k_.object({type:k_.literal(\"pcb_fabrication_note_text\"),pcb_fabrication_note_text_id:QM(\"pcb_fabrication_note_text\"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"1mm\"),pcb_component_id:k_.string(),text:k_.string(),layer:gw,anchor_position:qM.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),color:k_.string().optional()}).describe(\"Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators\"),sR=k_.object({type:k_.literal(\"pcb_fabrication_note_path\"),pcb_fabrication_note_path_id:QM(\"pcb_fabrication_note_path\"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:mw,route:k_.array(qM),stroke_width:$M,color:k_.string().optional()}).describe(\"Defines a fabrication path on the PCB for fabricators or assemblers\"),aR=k_.object({type:k_.literal(\"pcb_fabrication_note_rect\"),pcb_fabrication_note_rect_id:QM(\"pcb_fabrication_note_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw,stroke_width:$M.default(\"0.1mm\"),corner_radius:$M.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a fabrication note rectangle on the PCB\"),cR=k_.object({type:k_.literal(\"pcb_fabrication_note_dimension\"),pcb_fabrication_note_dimension_id:QM(\"pcb_fabrication_note_dimension\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,from:qM,to:qM,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:$M.optional(),offset_distance:$M.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:$M.default(\"1mm\"),color:k_.string().optional(),arrow_size:$M.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB fabrication notes\"),lR=k_.object({type:k_.literal(\"pcb_note_text\"),pcb_note_text_id:QM(\"pcb_note_text\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"1mm\"),text:k_.string().optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),layer:gw.default(\"top\"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a documentation note in text on the PCB\"),dR=k_.object({type:k_.literal(\"pcb_note_rect\"),pcb_note_rect_id:QM(\"pcb_note_rect\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw.default(\"top\"),stroke_width:$M.default(\"0.1mm\"),corner_radius:$M.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a rectangular documentation note on the PCB\"),hR=k_.object({type:k_.literal(\"pcb_note_path\"),pcb_note_path_id:QM(\"pcb_note_path\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(qM),layer:gw.default(\"top\"),stroke_width:$M.default(\"0.1mm\"),color:k_.string().optional()}).describe(\"Defines a polyline documentation note on the PCB\"),uR=k_.object({type:k_.literal(\"pcb_note_line\"),pcb_note_line_id:QM(\"pcb_note_line\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:XM,y1:XM,x2:XM,y2:XM,layer:gw.default(\"top\"),stroke_width:XM.default(\"0.1mm\"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe(\"Defines a straight documentation note line on the PCB\"),pR=k_.object({type:k_.literal(\"pcb_note_dimension\"),pcb_note_dimension_id:QM(\"pcb_note_dimension\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:qM,to:qM,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:$M.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:$M.default(\"1mm\"),layer:gw.default(\"top\"),color:k_.string().optional(),arrow_size:$M.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB documentation notes\"),mR=yN.extend({type:k_.literal(\"pcb_footprint_overlap_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_footprint_overlap_error\").default(\"pcb_footprint_overlap_error\"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when a pcb footprint overlaps with another element\"),gR=yN.extend({type:k_.literal(\"pcb_courtyard_overlap_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_courtyard_overlap_error\").default(\"pcb_courtyard_overlap_error\"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe(\"Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another\"),fR=k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"rect\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:XM,height:XM,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:XM,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),yR=k_.object({type:k_.literal(\"pcb_cutout\"),pcb_cutout_id:QM(\"pcb_cutout\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),_R=yR.extend({shape:k_.literal(\"rect\"),center:qM,width:$M,height:$M,rotation:UM.optional(),corner_radius:$M.optional()}),bR=yR.extend({shape:k_.literal(\"circle\"),center:qM,radius:$M}),xR=yR.extend({shape:k_.literal(\"polygon\"),points:k_.array(qM)}),vR=yR.extend({shape:k_.literal(\"path\"),route:k_.array(qM),slot_width:$M,slot_length:$M.optional(),space_between_slots:$M.optional(),slot_corner_radius:$M.optional()}),SR=k_.discriminatedUnion(\"shape\",[_R,bR,xR,vR]).describe(\"Defines a cutout on the PCB, removing board material.\"),IR=yN.extend({type:k_.literal(\"pcb_missing_footprint_error\"),pcb_missing_footprint_error_id:QM(\"pcb_missing_footprint_error\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"pcb_missing_footprint_error\").default(\"pcb_missing_footprint_error\"),source_component_id:k_.string()}).describe(\"Defines a missing footprint error on the PCB\"),CR=yN.extend({type:k_.literal(\"external_footprint_load_error\"),external_footprint_load_error_id:QM(\"external_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal(\"external_footprint_load_error\").default(\"external_footprint_load_error\")}).describe(\"Defines an error when an external footprint fails to load\"),PR=yN.extend({type:k_.literal(\"circuit_json_footprint_load_error\"),circuit_json_footprint_load_error_id:QM(\"circuit_json_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"circuit_json_footprint_load_error\").default(\"circuit_json_footprint_load_error\"),circuit_json:k_.array(k_.any()).optional()}).describe(\"Defines an error when a circuit JSON footprint fails to load\"),MR=k_.object({type:k_.literal(\"pcb_group\"),pcb_group_id:QM(\"pcb_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:$M.optional(),height:$M.optional(),center:qM,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this group, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this group, usually corresponding with how the user specified it\"),outline:k_.array(qM).optional(),anchor_position:qM.optional(),anchor_alignment:tN.default(\"center\"),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"none\"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum([\"packed\",\"none\"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:$M}).optional(),autorouter_used_string:k_.string().optional()}).describe(\"Defines a group of components on the PCB\"),NR=yN.extend({type:k_.literal(\"pcb_autorouting_error\"),pcb_error_id:QM(\"pcb_autorouting_error\"),error_type:k_.literal(\"pcb_autorouting_error\").default(\"pcb_autorouting_error\"),subcircuit_id:k_.string().optional()}).describe(\"The autorouting has failed to route a portion of the board\"),wR=k_.object({type:k_.literal(\"pcb_manual_edit_conflict_warning\"),pcb_manual_edit_conflict_warning_id:QM(\"pcb_manual_edit_conflict_warning\"),warning_type:k_.literal(\"pcb_manual_edit_conflict_warning\").default(\"pcb_manual_edit_conflict_warning\"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates\"),TR=k_.enum([\"x-\",\"x+\",\"y+\",\"y-\"]),RR=k_.object({type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\"),pcb_connector_not_in_accessible_orientation_warning_id:QM(\"pcb_connector_not_in_accessible_orientation_warning\"),warning_type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\").default(\"pcb_connector_not_in_accessible_orientation_warning\"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:TR,recommended_facing_direction:TR,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction\"),ER=k_.object({type:k_.literal(\"supplier_footprint_mismatch_warning\"),supplier_footprint_mismatch_warning_id:QM(\"supplier_footprint_mismatch_warning\"),warning_type:k_.literal(\"supplier_footprint_mismatch_warning\").default(\"supplier_footprint_mismatch_warning\"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:_N.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe(\"Warning emitted when a supplier part footprint does not match the expected footprint\"),AR=k_.object({type:k_.literal(\"pcb_breakout_point\"),pcb_breakout_point_id:QM(\"pcb_breakout_point\"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:XM,y:XM}).describe(\"Defines a routing target within a pcb_group for a source_trace or source_net\"),OR=k_.object({type:k_.literal(\"pcb_ground_plane\"),pcb_ground_plane_id:QM(\"pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane on the PCB\"),kR=k_.object({type:k_.literal(\"pcb_ground_plane_region\"),pcb_ground_plane_region_id:QM(\"pcb_ground_plane_region\"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:mw,points:k_.array(qM)}).describe(\"Defines a polygon region of a ground plane\"),LR=k_.object({type:k_.literal(\"pcb_thermal_spoke\"),pcb_thermal_spoke_id:QM(\"pcb_thermal_spoke\"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:XM,spoke_inner_diameter:XM,spoke_outer_diameter:XM,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Pattern for connecting a ground plane to a plated hole\"),DR=k_.object({type:k_.literal(\"pcb_copper_pour\"),pcb_copper_pour_id:QM(\"pcb_copper_pour\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:mw,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),zR=DR.extend({shape:k_.literal(\"rect\"),center:qM,width:$M,height:$M,rotation:UM.optional()}),FR=DR.extend({shape:k_.literal(\"brep\"),brep_shape:eT}),BR=DR.extend({shape:k_.literal(\"polygon\"),points:k_.array(qM)}),jR=k_.discriminatedUnion(\"shape\",[zR,FR,BR]).describe(\"Defines a copper pour on the PCB.\"),$R=yN.extend({type:k_.literal(\"pcb_component_outside_board_error\"),pcb_component_outside_board_error_id:QM(\"pcb_component_outside_board_error\"),error_type:k_.literal(\"pcb_component_outside_board_error\").default(\"pcb_component_outside_board_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:qM,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a PCB component is placed outside the board boundaries\"),YR=yN.extend({type:k_.literal(\"pcb_component_not_on_board_edge_error\"),pcb_component_not_on_board_edge_error_id:QM(\"pcb_component_not_on_board_edge_error\"),error_type:k_.literal(\"pcb_component_not_on_board_edge_error\").default(\"pcb_component_not_on_board_edge_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:qM,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component that must be placed on the board edge is centered away from the edge\"),XR=yN.extend({type:k_.literal(\"pcb_component_invalid_layer_error\"),pcb_component_invalid_layer_error_id:QM(\"pcb_component_invalid_layer_error\"),error_type:k_.literal(\"pcb_component_invalid_layer_error\").default(\"pcb_component_invalid_layer_error\"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:mw,subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)\"),VR=yN.extend({type:k_.literal(\"pcb_via_clearance_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_via_clearance_error\").default(\"pcb_via_clearance_error\"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when vias are closer than the allowed clearance\"),WR=yN.extend({type:k_.literal(\"pcb_via_trace_clearance_error\"),pcb_via_trace_clearance_error_id:QM(\"pcb_via_trace_clearance_error\"),error_type:k_.literal(\"pcb_via_trace_clearance_error\").default(\"pcb_via_trace_clearance_error\"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a via and trace are closer than the allowed clearance\"),HR=yN.extend({type:k_.literal(\"pcb_pad_pad_clearance_error\"),pcb_pad_pad_clearance_error_id:QM(\"pcb_pad_pad_clearance_error\"),error_type:k_.literal(\"pcb_pad_pad_clearance_error\").default(\"pcb_pad_pad_clearance_error\"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when pads are closer than the allowed clearance\"),GR=yN.extend({type:k_.literal(\"pcb_pad_trace_clearance_error\"),pcb_pad_trace_clearance_error_id:QM(\"pcb_pad_trace_clearance_error\"),error_type:k_.literal(\"pcb_pad_trace_clearance_error\").default(\"pcb_pad_trace_clearance_error\"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pad and trace are closer than allowed clearance\"),UR=k_.object({type:k_.literal(\"pcb_courtyard_rect\"),pcb_courtyard_rect_id:QM(\"pcb_courtyard_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw,ccw_rotation:UM.optional(),color:k_.string().optional()}).describe(\"Defines a courtyard rectangle on the PCB\"),ZR=k_.object({type:k_.literal(\"pcb_courtyard_outline\"),pcb_courtyard_outline_id:QM(\"pcb_courtyard_outline\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,outline:k_.array(qM).min(2)}).describe(\"Defines a courtyard outline on the PCB\"),qR=k_.object({type:k_.literal(\"pcb_courtyard_polygon\"),pcb_courtyard_polygon_id:QM(\"pcb_courtyard_polygon\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,points:k_.array(qM).min(3),color:k_.string().optional()}).describe(\"Defines a courtyard polygon on the PCB\"),JR=k_.object({type:k_.literal(\"pcb_courtyard_circle\"),pcb_courtyard_circle_id:QM(\"pcb_courtyard_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:$M,layer:gw,color:k_.string().optional()}).describe(\"Defines a courtyard circle on the PCB\"),KR=k_.object({type:k_.literal(\"cad_component\"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:JM,rotation:JM.optional(),size:JM.optional(),layer:mw.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:eN.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum([\"x+\",\"x-\",\"y+\",\"y-\",\"z+\",\"z-\"]).optional().describe('The direction in the model\\'s coordinate space that is considered \"up\" or \"coming out of the board surface\"'),model_origin_position:JM.optional(),model_origin_alignment:k_.enum([\"unknown\",\"center\",\"center_of_component_on_board_surface\",\"bottom_center_of_component\"]).optional(),model_object_fit:k_.enum([\"contain_within_bounds\",\"fill_bounds\"]).optional().default(\"contain_within_bounds\"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),anchor_alignment:k_.enum([\"center\",\"center_of_component_on_board_surface\"]).optional().default(\"center\")}).describe(\"Defines a component on the PCB\"),QR=k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]),tE=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),eE=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:QM(\"simulation_voltage_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:jM}).describe(\"Defines a DC voltage source for simulation\"),nE=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:QM(\"simulation_voltage_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:jM.optional(),frequency:YM.optional(),peak_to_peak_voltage:jM.optional(),wave_shape:QR.optional(),phase:UM.optional(),duty_cycle:tE.optional()}).describe(\"Defines an AC voltage source for simulation\"),oE=k_.union([eE,nE]).describe(\"Defines a voltage source for simulation\"),iE=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),rE=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:QM(\"simulation_current_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:VM}).describe(\"Defines a DC current source for simulation\"),sE=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:QM(\"simulation_current_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:VM.optional(),frequency:YM.optional(),peak_to_peak_current:VM.optional(),wave_shape:QR.optional(),phase:UM.optional(),duty_cycle:iE.optional()}).describe(\"Defines an AC current source for simulation\"),aE=k_.union([rE,sE]).describe(\"Defines a current source for simulation\"),cE=k_.union([k_.literal(\"spice_dc_sweep\"),k_.literal(\"spice_dc_operating_point\"),k_.literal(\"spice_transient_analysis\"),k_.literal(\"spice_ac_analysis\")]),lE=k_.object({type:k_.literal(\"simulation_experiment\"),simulation_experiment_id:QM(\"simulation_experiment\"),name:k_.string(),experiment_type:cE,time_per_step:WM.optional(),start_time_ms:HM.optional(),end_time_ms:HM.optional()}).describe(\"Defines a simulation experiment configuration\"),dE=k_.object({type:k_.literal(\"simulation_transient_voltage_graph\"),simulation_transient_voltage_graph_id:QM(\"simulation_transient_voltage_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:WM,start_time_ms:HM,end_time_ms:HM,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores voltage measurements over time for a simulation\"),hE=k_.object({type:k_.literal(\"simulation_switch\"),simulation_switch_id:QM(\"simulation_switch\"),source_component_id:k_.string().optional(),closes_at:HM.optional(),opens_at:HM.optional(),starts_closed:k_.boolean().optional(),switching_frequency:YM.optional()}).describe(\"Defines a switch for simulation timing control\"),uE=k_.object({type:k_.literal(\"simulation_voltage_probe\"),simulation_voltage_probe_id:QM(\"simulation_voltage_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.\").superRefine((t,e)=\u003e{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n\u0026\u0026o?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a differential probe.\"}):n?t.signal_input_source_port_id\u0026\u0026t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id.\"}):o\u0026\u0026(t.signal_input_source_net_id\u0026\u0026t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id.\"}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id.\"})}),pE=yN.extend({type:k_.literal(\"simulation_unknown_experiment_error\"),simulation_unknown_experiment_error_id:QM(\"simulation_unknown_experiment_error\"),error_type:k_.literal(\"simulation_unknown_experiment_error\").default(\"simulation_unknown_experiment_error\"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"An unknown error occurred during the simulation experiment.\"),mE=k_.object({type:k_.literal(\"simulation_op_amp\"),simulation_op_amp_id:QM(\"simulation_op_amp\"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe(\"Defines a simple ideal operational amplifier for simulation\"),gE=(k_.union([sw,iw,rw,ow,cw,aw,MN,xN,SN,CN,vN,NN,EN,AN,DN,FN,BN,VN,jN,$N,YN,XN,kN,ON,hw,fw,lw,WN,UN,ZN,JN,KN,yw,_w,bw,xw,vw,ew,dw,rT,uT,IR,CR,PR,wR,RR,ER,bT,fR,xT,VT,kT,FT,BT,WT,NT,OT,HT,GT,MR,qT,JT,KT,QT,iR,tR,eR,nR,oR,jT,$T,UT,ZT,YT,XT,VR,WR,HR,GR,sR,rR,aR,cR,lR,dR,hR,uR,pR,NR,mR,gR,AR,SR,OR,kR,LR,jR,$R,YR,XR,UR,ZR,qR,JR,Sw,zw,Ew,Aw,Ow,kw,ww,Rw,Fw,Lw,Iw,jw,$w,Bw,Hw,Gw,Uw,Zw,Kw,qw,Jw,KR,oE,aE,lE,dE,hE,uE,pE,mE]),!0),fE={CCW:-1,CW:1,NOT_ORIENTABLE:0},yE=2*Math.PI,_E=Object.freeze({__proto__:null,BOUNDARY:2,CCW:gE,CONTAINS:3,CW:!1,END_VERTEX:2,INSIDE:1,INTERLACE:4,NOT_VERTEX:0,ORIENTATION:fE,OUTSIDE:0,OVERLAP_OPPOSITE:2,OVERLAP_SAME:1,PIx2:yE,START_VERTEX:1}),bE=1e-6;function xE(t){bE=t}function vE(){return bE}function SE(t){return t\u003cbE\u0026\u0026t\u003e-bE}function IE(t,e){return t-e\u003cbE\u0026\u0026t-e\u003e-bE}function CE(t,e){return t-e\u003ebE}function PE(t,e){return t-e\u003c-bE}var ME={Utils:Object.freeze({__proto__:null,DECIMALS:3,EQ:IE,EQ_0:SE,GE:function(t,e){return t-e\u003e-bE},GT:CE,LE:function(t,e){return t-e\u003cbE},LT:PE,getTolerance:vE,setTolerance:xE}),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 _E)ME[t]=_E[t];Object.defineProperty(ME,\"DP_TOL\",{get:function(){return vE()},set:function(t){xE(t)}});var NE=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\")}};ME.Errors=NE;var wE=class{constructor(t,e){this.first=t,this.last=e||this.first}[Symbol.iterator](){let t;return{next:()=\u003e(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=[],o=t||this.first,i=e||this.last,r=o;if(void 0===r)return n;do{n.push(r),r=r.next}while(r!==i.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\u0026\u0026(n.prev=t),t.prev=e,t.next=n,this.last===e\u0026\u0026(this.last=t)}return this.last.next=void 0,this.first.prev=void 0,this}remove(t){return t===this.first\u0026\u0026t===this.last?(this.first=void 0,this.last=void 0):(t.prev\u0026\u0026(t.prev.next=t.next),t.next\u0026\u0026(t.next.prev=t.prev),t===this.first\u0026\u0026(this.first=t.next),t===this.last\u0026\u0026(this.last=t.prev)),this}isEmpty(){return void 0===this.first}static testInfiniteLoop(t){let e=t,n=t;do{if(e!=t\u0026\u0026e===n)throw NE.INFINITE_LOOP;e=e.next,n=n.next.next}while(e!=t)}},TE={stroke:\"black\"},RE=class{constructor(t=TE){for(const e in t)this[e]=t[e];this.stroke=t.stroke??TE.stroke}toAttributesString(){return Object.keys(this).reduce((t,e)=\u003et+(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 EE(t){return new RE(t).toAttributesString()}function AE(t,e){let n=[],[o,i,r]=t.standard,[s,a,c]=e.standard,l=o*a-i*s,d=r*a-i*c,h=o*c-r*s;if(!ME.Utils.EQ_0(l)){let t,e;0===i?(t=r/o,e=h/l):0===a?(t=c/s,e=h/l):0===o?(t=d/l,e=r/i):0===s?(t=d/l,e=c/a):(t=d/l,e=h/l),n.push(new ME.Point(t,e))}return n}function OE(t,e){let n=[],o=e.pc.projectionOn(t),i=e.pc.distanceTo(o)[0];if(ME.Utils.EQ(i,e.r))n.push(o);else if(ME.Utils.LT(i,e.r)){let r,s,a=Math.sqrt(e.r*e.r-i*i);r=t.norm.rotate90CCW().multiply(a),s=o.translate(r),n.push(s),r=t.norm.rotate90CW().multiply(a),s=o.translate(r),n.push(s)}return n}function kE(t,e){let n=[];for(let o of e.toSegments()){let e=DE(o,t);for(let t of e)eA(t,n)||n.push(t)}return n}function LE(t,e){let n=[];if(0===kE(t,e.box).length)return n;let o=OE(t,new ME.Circle(e.pc,e.r));for(let t of o)t.on(e)\u0026\u0026n.push(t);return n}function DE(t,e){let n=[];return t.ps.on(e)\u0026\u0026n.push(t.ps),t.pe.on(e)\u0026\u0026!t.isZeroLength()\u0026\u0026n.push(t.pe),n.length\u003e0||t.isZeroLength()||t.ps.leftTo(e)\u0026\u0026t.pe.leftTo(e)||!t.ps.leftTo(e)\u0026\u0026!t.pe.leftTo(e)?n:AE(new ME.Line(t.ps,t.pe),e)}function zE(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)\u0026\u0026n.push(t.ps),n;if(e.isZeroLength())return e.ps.on(t)\u0026\u0026n.push(e.ps),n;let o=new ME.Line(t.ps,t.pe),i=new ME.Line(e.ps,e.pe);if(o.incidentTo(i))t.ps.on(e)\u0026\u0026n.push(t.ps),t.pe.on(e)\u0026\u0026n.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 if(o.parallelTo(i)){const o=new ME.Vector(t.ps,t.pe),i=new ME.Vector(e.ps,e.pe),r=new ME.Vector(t.ps,e.ps),s=o.cross(i);if(!ME.Utils.EQ_0(s)){const a=r.cross(i)/s,c=r.cross(o)/s;ME.Utils.GE(a,0)\u0026\u0026ME.Utils.LE(a,1)\u0026\u0026ME.Utils.GE(c,0)\u0026\u0026ME.Utils.LE(c,1)\u0026\u0026n.push(FE(t.ps.translate(o.multiply(a)),t,e))}}else{let r=AE(o,i);r.length\u003e0\u0026\u0026BE(r[0],t)\u0026\u0026BE(r[0],e)\u0026\u0026n.push(FE(r[0],t,e))}return n}function FE(t,e,n){for(const o of[e.ps,e.pe,n.ps,n.pe])if(t.equalTo(o))return o;return t}function BE(t,e){const n=e.box;return ME.Utils.LE(t.x,n.xmax)\u0026\u0026ME.Utils.GE(t.x,n.xmin)\u0026\u0026ME.Utils.LE(t.y,n.ymax)\u0026\u0026ME.Utils.GE(t.y,n.ymin)}function jE(t,e){let n=[];if(t.isZeroLength()){let[o,i]=t.ps.distanceTo(e.pc);return ME.Utils.EQ(o,e.r)\u0026\u0026n.push(t.ps),n}let o=OE(new ME.Line(t.ps,t.pe),e);for(let e of o)e.on(t)\u0026\u0026n.push(e);return n}function $E(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)\u0026\u0026n.push(t.ps),n;let o=OE(new ME.Line(t.ps,t.pe),new ME.Circle(e.pc,e.r));for(let i of o)i.on(t)\u0026\u0026i.on(e)\u0026\u0026n.push(i);return n}function YE(t,e){let n=[],o=new ME.Vector(t.pc,e.pc),i=t.r,r=e.r;if(ME.Utils.EQ_0(i)||ME.Utils.EQ_0(r))return n;if(ME.Utils.EQ_0(o.x)\u0026\u0026ME.Utils.EQ_0(o.y)\u0026\u0026ME.Utils.EQ(i,r))return n.push(t.pc.translate(-i,0)),n;let s,a=t.pc.distanceTo(e.pc)[0];if(ME.Utils.GT(a,i+r))return n;if(ME.Utils.LT(a,Math.abs(i-r)))return n;if(o.x/=a,o.y/=a,ME.Utils.EQ(a,i+r)||ME.Utils.EQ(a,Math.abs(i-r)))return s=t.pc.translate(i*o.x,i*o.y),n.push(s),n;let c=i*i/(2*a)-r*r/(2*a)+a/2,l=t.pc.translate(c*o.x,c*o.y),d=Math.sqrt(i*i-c*c);return s=l.translate(o.rotate90CCW().multiply(d)),n.push(s),s=l.translate(o.rotate90CW().multiply(d)),n.push(s),n}function XE(t,e){let n=[];if(t.pc.equalTo(e.pc)\u0026\u0026ME.Utils.EQ(t.r,e.r)){let o;return o=t.start,o.on(e)\u0026\u0026n.push(o),o=t.end,o.on(e)\u0026\u0026n.push(o),o=e.start,o.on(t)\u0026\u0026n.push(o),o=e.end,o.on(t)\u0026\u0026n.push(o),n}let o=new ME.Circle(t.pc,t.r),i=new ME.Circle(e.pc,e.r),r=o.intersect(i);for(let o of r)o.on(t)\u0026\u0026o.on(e)\u0026\u0026n.push(o);return n}function VE(t,e){let n=[];if(e.pc.equalTo(t.pc)\u0026\u0026ME.Utils.EQ(e.r,t.r))return n.push(t.start),n.push(t.end),n;let o=YE(e,new ME.Circle(t.pc,t.r));for(let e of o)e.on(t)\u0026\u0026n.push(e);return n}function WE(t,e){return t.isSegment?zE(t.shape,e):$E(e,t.shape)}function HE(t,e){return t.isSegment?$E(t.shape,e):XE(t.shape,e)}function GE(t,e){return t.isSegment?DE(t.shape,e):LE(e,t.shape)}function UE(t,e){return t.isSegment?jE(t.shape,e):VE(t.shape,e)}function ZE(t,e){let n=[];for(let o of e.edges)for(let e of WE(o,t))n.push(e);return n}function qE(t,e){let n=[];for(let o of e.edges)for(let e of HE(o,t))n.push(e);return n}function JE(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of GE(o,t))eA(e,n)||n.push(e);return t.sortPoints(n)}function KE(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of UE(o,t))n.push(e);return n}function QE(t,e){return t.isSegment?WE(e,t.shape):t.isArc?HE(e,t.shape):t.isLine?GE(e,t.shape):t.isRay?(n=e,o=t.shape,n.isSegment?oA(o,n.shape):iA(o,n.shape)):[];var n,o}function tA(t,e){let n=[];if(e.isEmpty()||t.shape.box.not_intersect(e.box))return n;let o=e.edges.search(t.shape.box);for(let e of o)n=[...n,...QE(t,e)];return n}function eA(t,e){return e.some(e=\u003ee.equalTo(t))}function nA(t){return new ME.Line(t.start,t.norm)}function oA(t,e){return DE(e,nA(t)).filter(e=\u003et.contains(e))}function iA(t,e){return LE(nA(t),e).filter(e=\u003et.contains(e))}function rA(t,e){return OE(nA(t),e).filter(e=\u003et.contains(e))}function sA(t,e){return AE(nA(t),e).filter(e=\u003et.contains(e))}function aA(t,e){return JE(nA(t),e).filter(e=\u003et.contains(e))}function cA(t,e){if(t.intersect\u0026\u0026t.intersect instanceof Function)return t.intersect(e);throw NE.UNSUPPORTED_SHAPE_TYPE}function lA(t,e){let n=[];for(let o of e)n=[...n,...cA(t,o.shape)];return n}var dA=class t extends wE{constructor(...t){if(super(),this.isInfinite=!1,1===t.length\u0026\u0026t[0]instanceof Array\u0026\u0026t[0].length\u003e0){const e=t[0],n=e.length,o=t=\u003et instanceof ME.Segment||t instanceof ME.Arc||t instanceof ME.Ray,i=t=\u003et instanceof ME.Segment||t instanceof ME.Arc;if(!(1===n\u0026\u0026(t=\u003et instanceof ME.Segment||t instanceof ME.Arc||t instanceof ME.Ray||t instanceof ME.Line)(e[0])||n\u003e1\u0026\u0026o(e[0])\u0026\u0026o(e[n-1])\u0026\u0026e.slice(1,n-1).every(i)))throw ME.Errors.ILLEGAL_PARAMETERS;this.isInfinite=e.some(t=\u003et instanceof ME.Ray||t instanceof ME.Line);for(let t of e){let e=new ME.Edge(t);this.append(e)}this.setArcLength()}}get edges(){return[...this]}get box(){return this.edges.reduce((t,e)=\u003et.merge(e.box),new ME.Box)}get vertices(){let t=this.edges.map(t=\u003et.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\u003ethis.length||t\u003c0)return null;if(this.isInfinite)return null;let e=null;for(let n of this)if(t\u003e=n.arc_length\u0026\u0026(n===this.last||t\u003cn.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 o=new ME.Edge(n[0]),i=e.prev;return this.insert(o,i),e.shape=n[1],o}getChain(t,e){let n=[];for(let o=t;o!==e.next;o=o.next)n.push(o);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 ME.Point){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Line){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Circle){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Segment){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Arc){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Box){const[e,n]=ME.Distance.shape2multiline(new ME.Polygon(t),this);return[e,n.reverse()]}if(t instanceof ME.Multiline)return ME.Distance.multiline2multiline(this,t);throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}intersect(t){return t instanceof ME.Multiline?function(t,e){let n=[];for(let o of t)for(let t of e)n=[...n,...cA(o.shape,t.shape)];return n}(this,t):lA(t,this)}contains(t){if(t instanceof ME.Point)return this.edges.some(e=\u003ee.shape.contains(t));throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}translate(e){return new t(this.edges.map(t=\u003et.shape.translate(e)))}rotate(e=0,n=new ME.Point){return new t(this.edges.map(t=\u003et.shape.rotate(e,n)))}transform(e=new ME.Matrix){return new t(this.edges.map(t=\u003et.shape.transform(e)))}toShapes(){return this.edges.map(t=\u003et.shape.clone())}toJSON(){return this.edges.map(t=\u003et.toJSON())}svgPoints(){return this.vertices.map(t=\u003e`${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\u003cpath ${EE({fill:\"none\",...t})} d=\"`;e+=`\\nM${this.first.start.x},${this.first.start.y}`;for(let t of this)e+=t.svg();return e+='\" \u003e\\n\u003c/path\u003e',e}};ME.Multiline=dA;function hA(t,e,n){let o=n.length,i=t.shape.split(e);if(0===i.length)return;let r=0;r=null===i[0]?0:null===i[1]?t.shape.length:i[0].length;let s,a=0;IE(r,0)\u0026\u0026(a|=1),IE(r,t.shape.length)\u0026\u0026(a|=2),s=r===1/0?i[0].coord(e):2\u0026a\u0026\u0026t.next\u0026\u00260===t.next.arc_length?0:t.arc_length+r,n.push({id:o,pt:e,arc_length:s,edge_before:t,edge_after:void 0,face:t.face,is_vertex:a})}function uA(t){t.int_points1_sorted=pA(t.int_points1),t.int_points2_sorted=pA(t.int_points2)}function pA(t){let e=new Map,n=0;for(let o of t)e.has(o.face)||(e.set(o.face,n),n++);for(let n of t)n.faceId=e.get(n.face);return t.slice().sort(mA)}function mA(t,e){return t.faceId\u003ce.faceId?-1:t.faceId\u003ee.faceId?1:t.arc_length\u003ce.arc_length?-1:t.arc_length\u003ee.arc_length?1:0}function gA(t){if(t.int_points1.length\u003c2)return;let e,n,o,i,r=!1;for(let s=0;s\u003ct.int_points1_sorted.length;s++)if(-1!==t.int_points1_sorted[s].id){e=t.int_points1_sorted[s],n=t.int_points2[e.id];for(let a=s+1;a\u003ct.int_points1_sorted.length\u0026\u0026(o=t.int_points1_sorted[a],IE(o.arc_length,e.arc_length));a++)-1!==o.id\u0026\u0026(i=t.int_points2[o.id],-1!==i.id\u0026\u0026o.edge_before===e.edge_before\u0026\u0026o.edge_after===e.edge_after\u0026\u0026i.edge_before===n.edge_before\u0026\u0026i.edge_after===n.edge_after\u0026\u0026(o.id=-1,i.id=-1,r=!0))}n=t.int_points2_sorted[0],e=t.int_points1[n.id];for(let o=1;o\u003ct.int_points2_sorted.length;o++){let i=t.int_points2_sorted[o];if(-1===i.id)continue;if(-1===n.id||!IE(i.arc_length,n.arc_length)){n=i,e=t.int_points1[n.id];continue}let s=t.int_points1[i.id];s.edge_before===e.edge_before\u0026\u0026s.edge_after===e.edge_after\u0026\u0026i.edge_before===n.edge_before\u0026\u0026i.edge_after===n.edge_after\u0026\u0026(s.id=-1,i.id=-1,r=!0)}r\u0026\u0026(t.int_points1=t.int_points1.filter(t=\u003et.id\u003e=0),t.int_points2=t.int_points2.filter(t=\u003et.id\u003e=0),t.int_points1.forEach((t,e)=\u003et.id=e),t.int_points2.forEach((t,e)=\u003et.id=e))}function fA(t){for(let e of t)e.edge_before\u0026\u0026(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\u0026\u0026(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\u0026\u0026(e.edge_before.bvEnd=2),e.edge_after\u0026\u0026(e.edge_after.bvStart=2)}function yA(t,e){for(let n of t)n.edge_before\u0026\u0026n.edge_before.setInclusion(e),n.edge_after\u0026\u0026n.edge_after.setInclusion(e)}function _A(t,e,n){let o,i,r=1;if(1===t.length)return 1;o=t[e];for(let s=e+1;s\u003ct.length\u0026\u0026o.face===n\u0026\u0026(i=t[s],i.pt.equalTo(o.pt)\u0026\u0026i.edge_before===o.edge_before\u0026\u0026i.edge_after===o.edge_after);s++)r++;return r}function bA(t,e){if(e){for(let n of e){let e=n.edge_before;if(n.is_vertex=0,e.shape.start\u0026\u0026e.shape.start.equalTo(n.pt)\u0026\u0026(n.is_vertex|=1),e.shape.end\u0026\u0026e.shape.end.equalTo(n.pt)\u0026\u0026(n.is_vertex|=2),1\u0026n.is_vertex){n.edge_before=e.prev,e.prev\u0026\u0026(n.is_vertex=2);continue}if(2\u0026n.is_vertex)continue;let o=t.addVertex(n.pt,e);n.edge_before=o}for(let n of e)n.edge_before?n.edge_after=n.edge_before.next:t instanceof dA\u0026\u00261\u0026n.is_vertex\u0026\u0026(n.edge_after=t.first)}}function xA(t,e,n){const o=t.edge_before,i=e.edge_after,r=n.length;o.next=n[0],n[0].prev=o,n[r-1].next=i,i.prev=n[r-1]}ME.multiline=(...t)=\u003enew ME.Multiline(...t);var{INSIDE:vA,OUTSIDE:SA,BOUNDARY:IA,OVERLAP_SAME:CA,OVERLAP_OPPOSITE:PA}=_E,{NOT_VERTEX:MA,START_VERTEX:NA,END_VERTEX:wA}=_E;function TA(t,e){let n=e.clone().reverse(),[o,i]=LA(t,n,3,!0);return o}function RA(t,e){let[n,o]=LA(t,e,2,!0);return n}function EA(t,e){let[n,o]=LA(t,e,2,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=\u003et.shape)];let r=[];for(let t of o.faces)r=[...r,...[...t.edges].map(t=\u003et.shape)];return[i,r]}function AA(t,e){let[n,o]=LA(t,e,3,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=\u003et.shape)];return i}function OA(t,e){let n=t.clone(),o=e.clone(),i=DA(n,o);return uA(i),bA(n,i.int_points1_sorted),bA(o,i.int_points2_sorted),gA(i),uA(i),[i.int_points1_sorted.map(t=\u003et.pt),i.int_points2_sorted.map(t=\u003et.pt)]}function kA(t,e,n,o){let i=zA(t,n.int_points1),r=zA(e,n.int_points2);for(FA(i,e),FA(r,t),fA(n.int_points1),fA(n.int_points2),yA(n.int_points1,e),yA(n.int_points2,t);BA(t,e,n.int_points1,n.int_points1_sorted,n.int_points2,n););!function(t){let e,n,o,i=t.int_points1.length;for(let r=0;r\u003ci;r++){let s=t.int_points1_sorted[r];s.face!==e\u0026\u0026(n=r,e=s.face);let a,c=r,l=_A(t.int_points1_sorted,r,e);a=c+l\u003ci\u0026\u0026t.int_points1_sorted[c+l].face===e?c+l:n;let d=_A(t.int_points1_sorted,a,e);o=null;for(let n=a;n\u003ca+d;n++){let i=t.int_points1_sorted[n];if(i.face===e\u0026\u0026t.int_points2[i.id].face===t.int_points2[s.id].face){o=i;break}}if(null===o)continue;let h=s.edge_after,u=o.edge_before;if(2!==h.bv||2!==u.bv)continue;if(h!==u)continue;let p=t.int_points2[s.id],m=t.int_points2[o.id],g=p.edge_after,f=m.edge_before;2===g.bv\u0026\u00262===f.bv\u0026\u0026g===f||(p=t.int_points2[o.id],m=t.int_points2[s.id],g=p.edge_after,f=m.edge_before),2===g.bv\u0026\u00262===f.bv\u0026\u0026g===f\u0026\u0026h.setOverlap(g)}}(n),jA(t,o,n.int_points1_sorted,!0),jA(e,o,n.int_points2_sorted,!1),XA(t,i,o,!0),XA(e,r,o,!1)}function LA(t,e,n,o){let i=t.clone(),r=e.clone(),s=DA(i,r);return uA(s),bA(i,s.int_points1_sorted),bA(r,s.int_points2_sorted),gA(s),uA(s),kA(i,r,s,n),o\u0026\u0026function(t,e,n){!function(t,e,n,o){for(let n of e.faces){for(let e of n)t.edges.add(e);void 0===o.find(t=\u003et.face===n)\u0026\u0026t.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\u003cn.int_points1.length;t++){let e=n.int_points1[t],o=n.int_points2[t];if(void 0!==e.edge_before\u0026\u0026void 0===e.edge_after\u0026\u0026void 0===o.edge_before\u0026\u0026void 0!==o.edge_after\u0026\u0026(e.edge_before.next=o.edge_after,o.edge_after.prev=e.edge_before,e.edge_after=o.edge_after,o.edge_before=e.edge_before),void 0!==o.edge_before\u0026\u0026void 0===o.edge_after\u0026\u0026void 0===e.edge_before\u0026\u0026void 0!==e.edge_after\u0026\u0026(o.edge_before.next=e.edge_after,e.edge_after.prev=o.edge_before,o.edge_after=e.edge_after,e.edge_before=o.edge_before),void 0!==e.edge_before\u0026\u0026void 0===e.edge_after)for(let t of n.int_points1_sorted)t!==e\u0026\u0026void 0===t.edge_before\u0026\u0026void 0!==t.edge_after\u0026\u0026t.pt.equalTo(e.pt)\u0026\u0026(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!==o.edge_before\u0026\u0026void 0===o.edge_after)for(let t of n.int_points2_sorted)t!==o\u0026\u0026void 0===t.edge_before\u0026\u0026void 0!==t.edge_after\u0026\u0026t.pt.equalTo(o.pt)\u0026\u0026(o.edge_before.next=t.edge_after,t.edge_after.prev=o.edge_before,o.edge_after=t.edge_after,t.edge_before=o.edge_before)}}(0,0,n),$A(t,n.int_points1),$A(e,n.int_points2),YA(t,n.int_points1,n.int_points2),YA(t,n.int_points2,n.int_points1),VA(t),VA(e)}(i,r,s),[i,r]}function DA(t,e){let n={int_points1:[],int_points2:[]};for(let o of t.edges){let t=e.edges.search(o.box);for(let e of t){let t=o.shape.intersect(e.shape);for(let i of t)hA(o,i,n.int_points1),hA(e,i,n.int_points2)}}return n}function zA(t,e){let n=[];for(let o of t.faces)e.find(t=\u003et.face===o)||n.push(o);return n}function FA(t,e){for(let n of t)n.first.bv=n.first.bvStart=n.first.bvEnd=void 0,n.first.setInclusion(e)}function BA(t,e,n,o,i,r){let s,a,c,l=o.length,d=!1;for(let h=0;h\u003cl;h++){let u=o[h];u.face!==s\u0026\u0026(a=h,s=u.face);let p,m=h,g=_A(o,h,s);p=m+g\u003cl\u0026\u0026o[m+g].face===s?m+g:a;let f=_A(o,p,s);c=null;for(let t=p;t\u003cp+f;t++){let e=o[t];if(e.face===s\u0026\u0026i[e.id].face===i[u.id].face){c=e;break}}if(null===c)continue;let y=u.edge_after,_=c.edge_before;if(y.bv!==IA||_.bv==IA)if(y.bv==IA||_.bv!==IA){if(y.bv===IA\u0026\u0026_.bv===IA\u0026\u0026y!=_||y.bv===vA\u0026\u0026_.bv===SA||y.bv===SA\u0026\u0026_.bv===vA){let t=y.next;for(;t!=_;)t.bvStart=void 0,t.bvEnd=void 0,t.bv=void 0,t.setInclusion(e),t=t.next}if(y.bv===IA\u0026\u0026_.bv===IA\u0026\u0026y!=_){let t,e=y.next;for(;e!=_;){if(e.bv!=IA)if(void 0===t)t=e.bv;else if(e.bv!=t)throw NE.UNRESOLVED_BOUNDARY_CONFLICT;e=e.next}null!=t\u0026\u0026(y.bv=t,_.bv=t);continue}if(y.bv===vA\u0026\u0026_.bv===SA||y.bv===SA\u0026\u0026_.bv===vA){let o=y;for(;o!=_;){if(o.bvStart===y.bv\u0026\u0026o.bvEnd===_.bv){let[s,a]=o.shape.distanceTo(e);if(s\u003c10*ME.DP_TOL){hA(o,a.ps,n);let s=n[n.length-1];if(s.is_vertex\u0026NA)s.edge_after=o,s.edge_before=o.prev,o.bvStart=IA,o.bv=void 0,o.setInclusion(e);else if(s.is_vertex\u0026wA)s.edge_after=o.next,o.bvEnd=IA,o.bv=void 0,o.setInclusion(e);else{let t=e.addVertex(s.pt,o);s.edge_before=t,s.edge_after=t.next,t.setInclusion(e),t.next.bvStart=IA,t.next.bvEnd=void 0,t.next.bv=void 0,t.next.setInclusion(e)}let c=e.findEdgeByPoint(a.pe);hA(c,a.pe,i);let l=i[i.length-1];if(l.is_vertex\u0026NA)l.edge_after=c,l.edge_before=c.prev;else if(l.is_vertex\u0026wA)l.edge_after=c.next;else{let n=i.find(t=\u003et.edge_after===c),o=e.addVertex(l.pt,c);l.edge_before=o,l.edge_after=o.next,n\u0026\u0026(n.edge_after=o),o.bvStart=void 0,o.bvEnd=IA,o.bv=void 0,o.setInclusion(t),o.next.bvStart=IA,o.next.bvEnd=void 0,o.next.bv=void 0,o.next.setInclusion(t)}uA(r),d=!0;break}}o=o.next}if(d)break;throw NE.UNRESOLVED_BOUNDARY_CONFLICT}}else _.bv=y.bv;else y.bv=_.bv}return d}function jA(t,e,n,o){if(!n)return;let i,r,s,a;for(let c=0;c\u003cn.length;c++){if(s=n[c],s.face!==i\u0026\u0026(r=c,i=s.face),i.isEmpty())continue;let l,d=c,h=_A(n,c,i);l=d+h\u003cn.length\u0026\u0026n[d+h].face===s.face?d+h:r,a=n[l];let u=l,p=_A(n,u,i),m=s.edge_after,g=a.edge_before;if(m.bv===vA\u0026\u0026g.bv===vA\u0026\u00261===e||m.bv===SA\u0026\u0026g.bv===SA\u0026\u00262===e||(m.bv===SA||g.bv===SA)\u0026\u00263===e\u0026\u0026!o||(m.bv===vA||g.bv===vA)\u0026\u00263===e\u0026\u0026o||m.bv===IA\u0026\u0026g.bv===IA\u0026\u0026m.overlap\u0026CA\u0026\u0026o||m.bv===IA\u0026\u0026g.bv===IA\u0026\u0026m.overlap\u0026PA){t.removeChain(i,m,g);for(let t=d;t\u003cd+h;t++)n[t].edge_after=void 0;for(let t=u;t\u003cu+p;t++)n[t].edge_before=void 0}c+=h-1}}function $A(t,e){for(let n of e)t.faces.delete(n.face),n.face=void 0,n.edge_before\u0026\u0026(n.edge_before.face=void 0),n.edge_after\u0026\u0026(n.edge_after.face=void 0)}function YA(t,e,n){for(let o of e){if(void 0===o.edge_before||void 0===o.edge_after)continue;if(o.face)continue;if(o.edge_after.face||o.edge_before.face)continue;let i=o.edge_after,r=o.edge_before;try{wE.testInfiniteLoop(i)}catch(t){throw NE.CANNOT_COMPLETE_BOOLEAN_OPERATION}let s=t.addFace(i,r);for(let t of e)t.edge_before\u0026\u0026t.edge_after\u0026\u0026t.edge_before.face===s\u0026\u0026t.edge_after.face===s\u0026\u0026(t.face=s);for(let t of n)t.edge_before\u0026\u0026t.edge_after\u0026\u0026t.edge_before.face===s\u0026\u0026t.edge_after.face===s\u0026\u0026(t.face=s)}}function XA(t,e,n,o){for(let i of e){let e=i.first.bv;(1===n\u0026\u0026e===vA||3===n\u0026\u0026e===vA\u0026\u0026o||3===n\u0026\u0026e===SA\u0026\u0026!o||2===n\u0026\u0026e===SA)\u0026\u0026t.deleteFace(i)}}function VA(t){const e=[];for(const n of t.edges)n.face\u0026\u0026t.faces.has(n.face)||e.push(n);for(const n of e)t.edges.delete(n)}var WA=Object.freeze({__proto__:null,BOOLEAN_INTERSECT:2,BOOLEAN_SUBTRACT:3,BOOLEAN_UNION:1,calculateIntersections:OA,innerClip:EA,intersect:RA,outerClip:AA,removeNotRelevantChains:jA,removeOldFaces:$A,restoreFaces:YA,subtract:TA,unify:function(t,e){let[n,o]=LA(t,e,1,!0);return n}}),HA=RegExp(\"T.F..FFF.|T.F...F..\"),GA=RegExp(\"T........|.T.......|...T.....|....T....\"),UA=RegExp(\"FT.......|F..T.....|F...T....\"),ZA=RegExp(\"T.F..F...\"),qA=RegExp(\"T.F..F...|.TF..F...|..FT.F...|..F.TF...\"),JA=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=\u003et instanceof Array\u0026\u0026t.length\u003e0?\"T\":t instanceof Array\u0026\u00260===t.length?\"F\":\"*\").join(\"\")}equal(){return HA.test(this.toString())}intersect(){return GA.test(this.toString())}touch(){return UA.test(this.toString())}inside(){return ZA.test(this.toString())}covered(){return qA.test(this.toString())}};function KA(t,e){let n,o=new ME.Ray(e),i=new ME.Line(o.pt,o.norm);const r=new ME.Box(o.box.xmin-ME.DP_TOL,o.box.ymin-ME.DP_TOL,o.box.xmax+ME.DP_TOL,o.box.ymax+ME.DP_TOL);if(t.box.not_intersect(r))return ME.OUTSIDE;let s=t.edges.search(r);if(0===s.length)return ME.OUTSIDE;for(let t of s)if(t.shape.contains(e))return ME.BOUNDARY;let a=[...t.faces],c=[];for(let t of s)for(let n of o.intersect(t.shape)){if(n.equalTo(e))return ME.BOUNDARY;c.push({pt:n,edge:t,face_index:a.indexOf(t.face)})}c.sort((t,e)=\u003ePE(t.pt.x,e.pt.x)?-1:CE(t.pt.x,e.pt.x)?1:t.face_index\u003ce.face_index?-1:t.face_index\u003ee.face_index?1:t.edge.arc_length\u003ce.edge.arc_length?-1:t.edge.arc_length\u003ee.edge.arc_length?1:0);let l=0;for(let t=0;t\u003cc.length;t++){let e=c[t];if(e.pt.equalTo(e.edge.shape.start)){if(t\u003e0\u0026\u0026e.pt.equalTo(c[t-1].pt)\u0026\u0026e.face_index===c[t-1].face_index\u0026\u0026e.edge.prev===c[t-1].edge)continue;let n=e.edge.prev;for(;SE(n.length);)n=n.prev;let o=n.shape.tangentInEnd(),r=e.pt.translate(o),s=e.edge.shape.tangentInStart(),a=e.pt.translate(s),d=r.leftTo(i),h=a.leftTo(i);(d\u0026\u0026!h||!d\u0026\u0026h)\u0026\u0026l++}else if(e.pt.equalTo(e.edge.shape.end)){if(t\u003e0\u0026\u0026e.pt.equalTo(c[t-1].pt)\u0026\u0026e.face_index===c[t-1].face_index\u0026\u0026e.edge.next===c[t-1].edge)continue;let n=e.edge.next;for(;SE(n.length);)n=n.next;let o=n.shape.tangentInStart(),r=e.pt.translate(o),s=e.edge.shape.tangentInEnd(),a=e.pt.translate(s),d=r.leftTo(i),h=a.leftTo(i);(d\u0026\u0026!h||!d\u0026\u0026h)\u0026\u0026l++}else if(e.edge.shape instanceof ME.Segment)l++;else{let t=e.edge.shape.box;IE(e.pt.y,t.ymin)||IE(e.pt.y,t.ymax)||l++}}return n=l%2==1?1:0,n}function QA(t,e){return oO(t,e).intersect()}function tO(t,e){return oO(t,e).inside()}function eO(t,e){return oO(t,e).covered()}function nO(t,e){return eO(e,t)}function oO(t,e){return t instanceof ME.Line\u0026\u0026e instanceof ME.Line?function(t,e){let n=new JA,o=AE(t,e);0===o.length?t.contains(e.pt)\u0026\u0026e.contains(t.pt)?(n.I2I=[t],n.I2E=[],n.E2I=[]):(n.I2I=[],n.I2E=[t],n.E2I=[e]):(n.I2I=o,n.I2E=t.split(o),n.E2I=e.split(o));return n}(t,e):t instanceof ME.Line\u0026\u0026e instanceof ME.Circle?function(t,e){let n=new JA,o=OE(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new dA([t]),r=t.sortPoints(o);i.split(r);let s=i.toShapes();n.I2I=[s[1]],n.I2B=r,n.I2E=[s[0],s[2]],n.E2I=new ME.Polygon([e.toArc()]).cutWithLine(t)}return n}(t,e):t instanceof ME.Line\u0026\u0026e instanceof ME.Box?function(t,e){let n=new JA,o=kE(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new dA([t]),r=t.sortPoints(o);i.split(r);let s=i.toShapes();e.toSegments().some(t=\u003et.contains(o[0])\u0026\u0026t.contains(o[1]))?(n.I2I=[],n.I2B=[s[1]],n.I2E=[s[0],s[2]],n.E2I=[e]):(n.I2I=[s[1]],n.I2B=r,n.I2E=[s[0],s[2]],n.E2I=new ME.Polygon(e.toSegments()).cutWithLine(t))}return n}(t,e):t instanceof ME.Line\u0026\u0026e instanceof ME.Polygon?function(t,e){let n=new JA,o=JE(t,e),i=new dA([t]),r=o.length\u003e0?o.slice():t.sortPoints(o);return i.split(r),[...i].forEach(t=\u003et.setInclusion(e)),n.I2I=[...i].filter(t=\u003et.bv===ME.INSIDE).map(t=\u003et.shape),n.I2B=[...i].slice(1).map(t=\u003et.bv===ME.BOUNDARY?t.shape:t.shape.start),n.I2E=[...i].filter(t=\u003et.bv===ME.OUTSIDE).map(t=\u003et.shape),n.E2I=e.cutWithLine(t),n}(t,e):(t instanceof ME.Segment||t instanceof ME.Arc)\u0026\u0026e instanceof ME.Polygon?iO(t,e):(t instanceof ME.Segment||t instanceof ME.Arc)\u0026\u0026(e instanceof ME.Circle||e instanceof ME.Box)?iO(t,new ME.Polygon(e)):t instanceof ME.Polygon\u0026\u0026e instanceof ME.Polygon?rO(t,e):(t instanceof ME.Circle||t instanceof ME.Box)\u0026\u0026(e instanceof ME.Circle||e instanceof ME.Box)?rO(new ME.Polygon(t),new ME.Polygon(e)):(t instanceof ME.Circle||t instanceof ME.Box)\u0026\u0026e instanceof ME.Polygon?rO(new ME.Polygon(t),e):t instanceof ME.Polygon\u0026\u0026(e instanceof ME.Circle||e instanceof ME.Box)?rO(t,new ME.Polygon(e)):void 0}function iO(t,e){let n=new JA,o=function(t,e){return t instanceof ME.Line?JE(t,e):t instanceof ME.Segment?ZE(t,e):t instanceof ME.Arc?qE(t,e):[]}(t,e),i=o.length\u003e0?o.slice():t.sortPoints(o),r=new dA([t]);r.split(i),[...r].forEach(t=\u003et.setInclusion(e)),n.I2I=[...r].filter(t=\u003et.bv===ME.INSIDE).map(t=\u003et.shape),n.I2B=[...r].slice(1).map(t=\u003et.bv===ME.BOUNDARY?t.shape:t.shape.start),n.I2E=[...r].filter(t=\u003et.bv===ME.OUTSIDE).map(t=\u003et.shape),n.B2I=[],n.B2B=[],n.B2E=[];for(let o of[t.start,t.end])switch(KA(e,o)){case ME.INSIDE:n.B2I.push(o);break;case ME.BOUNDARY:n.B2B.push(o);break;case ME.OUTSIDE:n.B2E.push(o)}return n}function rO(t,e){let n=new JA,[o,i]=OA(t,e),r=RA(t,e),s=TA(t,e),a=TA(e,t),[c,l]=EA(t,e),d=AA(t,e),h=AA(e,t);return n.I2I=r.isEmpty()?[]:[r],n.I2B=l,n.I2E=s.isEmpty()?[]:[s],n.B2I=c,n.B2B=o,n.B2E=d,n.E2I=a.isEmpty()?[]:[a],n.E2B=h,n}var sO=Object.freeze({__proto__:null,contain:function(t,e){return tO(e,t)},cover:nO,covered:eO,disjoint:function(t,e){return!QA(t,e)},equal:function(t,e){return oO(t,e).equal()},inside:tO,intersect:QA,relate:oO,touch:function(t,e){return oO(t,e).touch()}}),aO=class t{constructor(t=1,e=0,n=0,o=1,i=0,r=0){this.a=t,this.b=e,this.c=n,this.d=o,this.tx=i,this.ty=r}fromMatrix3x3(e){const[n,o,i]=e[0],[r,s,a]=e[1];return new t(n,r,o,s,i,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,o;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 NE.ILLEGAL_PARAMETERS;n=e[0],o=e[1]}else n=e[0].x,o=e[0].y;return this.multiply(new t(1,0,0,1,n,o))}rotate(e,n=0,o=0){let i=Math.cos(e),r=Math.sin(e);return this.translate(n,o).multiply(new t(i,r,-r,i,0,0)).translate(-n,-o)}scale(e,n){return this.multiply(new t(e,0,0,n,0,0))}equalTo(t){return!!ME.Utils.EQ(this.tx,t.tx)\u0026\u0026(!!ME.Utils.EQ(this.ty,t.ty)\u0026\u0026(!!ME.Utils.EQ(this.a,t.a)\u0026\u0026(!!ME.Utils.EQ(this.b,t.b)\u0026\u0026(!!ME.Utils.EQ(this.c,t.c)\u0026\u0026!!ME.Utils.EQ(this.d,t.d)))))}};ME.Matrix=aO;ME.matrix=(...t)=\u003enew ME.Matrix(...t);var cO=class{constructor(t,e){this.low=t,this.high=e}get max(){return this.clone()}less_than(t){return this.low\u003ct.low||this.low===t.low\u0026\u0026this.high\u003ct.high}equal_to(t){return this.low===t.low\u0026\u0026this.high===t.high}intersect(t){return!this.not_intersect(t)}not_intersect(t){return this.high\u003ct.low||t.high\u003cthis.low}merge(t){const e=void 0===this.low?t.low:this.low\u003ct.low?this.low:t.low,n=void 0===this.high?t.high:this.high\u003et.high?this.high:t.high,o=this.clone();return o.low=e,o.high=n,o}output(){return[this.low,this.high]}comparable_less_than(t,e){return t\u003ce}},lO=class t extends cO{clone(){return new t(this.low,this.high)}},dO=class{constructor(t,e,n=null,o=null,i=null,r=0){if(this.left=n,this.right=o,this.parent=i,this.color=r,this.item={key:void 0,values:[]},void 0!==e\u0026\u0026this.item.values.push(e),void 0!==t)if(Array.isArray(t)){const[e,n]=t;if(!Number.isNaN(e)\u0026\u0026!Number.isNaN(n)){let t=e,o=n;t\u003eo\u0026\u0026([t,o]=[o,t]),this.item.key=new lO(t,o)}}else this.item.key=t;this.max=this.item.key?this.item.key.max:void 0}isNil(){return void 0===this.item.key\u0026\u00260===this.item.values.length\u0026\u0026null===this.left\u0026\u0026null===this.right\u0026\u00260===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\u0026\u0026n\u0026\u0026e.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\u0026\u0026this.right.max\u0026\u0026(this.max=this.max?this.max.merge(this.right.max):this.right.max),this.left\u0026\u0026this.left.max\u0026\u0026(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(),o=t.requireKey();return n.comparable_less_than(e,o.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(),o=t.requireKey();return n.comparable_less_than(o.high,e)}},hO=class t{constructor(){this.root=null,this.nil_node=new dO}get size(){let t=0;return this.tree_walk(this.root,e=\u003et+=e.item.values.length),t}get keys(){const t=[];return this.tree_walk(this.root,e=\u003et.push(e.item.key.output())),t}get values(){const t=[];return this.tree_walk(this.root,e=\u003e{for(const n of e.item.values)t.push(n)}),t}get items(){const t=[];return this.tree_walk(this.root,e=\u003e{const n=e.item.key.output();for(const o of e.item.values)t.push({key:n,value:o})}),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 dO(t));if(n)return n.item.values.push(e),n;const o=new dO(t,e,this.nil_node,this.nil_node,null,1);return this.tree_insert(o),this.recalc_max(o),o}exist(t,e=t){const n=this.tree_search(this.root,new dO(t));return!!n\u0026\u0026(arguments.length\u003c2||e===t||n.item.values.some(t=\u003et\u0026\u0026t.equal_to?t.equal_to(e):t===e))}remove(t,e=t){const n=this.tree_search(this.root,new dO(t));if(!n)return;if(arguments.length\u003c2)return this.tree_delete(n),n;const o=n.item.values.findIndex(t=\u003et\u0026\u0026t.equal_to?t.equal_to(e):t===e);return o\u003e=0?(n.item.values.splice(o,1),0===n.item.values.length\u0026\u0026this.tree_delete(n),n):void 0}search(t,e=(t,e)=\u003et===e?e.output():t){const n=new dO(t),o=[];this.tree_search_interval(this.root,n,o);const i=[];for(const t of o)for(const n of t.item.values)i.push(e(n,t.item.key));return i}intersect_any(t){const e=new dO(t);return this.tree_find_any_interval(this.root,e)}forEach(t){this.tree_walk(this.root,e=\u003e{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=\u003e{for(const o of t.item.values)n.insert(t.item.key,e(o,t.item.key))}),n}*iterate(t,e=(t,e)=\u003et===e?e.output():t){let n=null;for(t?n=this.tree_search_nearest_forward(this.root,new dO(t)):this.root\u0026\u0026(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\u0026\u00261===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\u0026\u0026(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\u0026\u0026(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\u0026\u0026(t.copy_data(e),t.update_max(),this.recalc_max(t)),0===e.color\u0026\u0026this.delete_fixup(n)}delete_fixup(t){let e,n=t;for(;n!==this.root\u0026\u0026null!=n.parent\u0026\u00260===n.color;)n===n.parent.left?(e=n.parent.right,1===e.color\u0026\u0026(e.color=0,n.parent.color=1,this.rotate_left(n.parent),e=n.parent.right),0===e.left.color\u0026\u00260===e.right.color?(e.color=1,n=n.parent):(0===e.right.color\u0026\u0026(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\u0026\u0026(e.color=0,n.parent.color=1,this.rotate_right(n.parent),e=n.parent.left),0===e.left.color\u0026\u00260===e.right.color?(e.color=1,n=n.parent):(0===e.left.color\u0026\u0026(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\u0026\u0026t!==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,o=t;for(;o\u0026\u0026o!==this.nil_node;)o.less_than(e)?o.intersect(e)?(n=o,o=o.left):o=o.right:(n\u0026\u0026!o.less_than(n)||(n=o),o=o.left);return n||null}tree_search_interval(t,e,n){null!=t\u0026\u0026t!==this.nil_node\u0026\u0026(t.left===this.nil_node||t.not_intersect_left_subtree(e)||this.tree_search_interval(t.left,e,n),t.intersect(e)\u0026\u0026n.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\u0026\u0026t!==this.nil_node\u0026\u0026(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\u0026\u0026e.left!==this.nil_node;)e=e.left;return e}local_maximum(t){let e=t;for(;null!=e.right\u0026\u0026e.right!==this.nil_node;)e=e.right;return e}tree_successor(t){let e,n,o;if(t.right!==this.nil_node)e=this.local_minimum(t.right);else{for(n=t,o=t.parent;null!=o\u0026\u0026o.right===n;)n=o,o=o.parent;e=o}return e}rotate_left(t){const e=t.right;t.right=e.left,e.left!==this.nil_node\u0026\u0026(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\u0026\u0026t!==this.nil_node\u0026\u0026t.update_max(),null!=e\u0026\u0026e!==this.nil_node\u0026\u0026e.update_max()}rotate_right(t){const e=t.left;t.left=e.right,e.right!==this.nil_node\u0026\u0026(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\u0026\u0026t!==this.nil_node\u0026\u0026t.update_max(),null!=e\u0026\u0026e!==this.nil_node\u0026\u0026e.update_max()}tree_walk(t,e){null!=t\u0026\u0026t!==this.nil_node\u0026\u0026(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\u0026\u0026(0===e.left.color\u0026\u00260===e.right.color||(t=!1))}),t}testBlackHeightProperty(t){let e=0,n=0,o=0;if(0===t.color\u0026\u0026e++,n=t.left!==this.nil_node?this.testBlackHeightProperty(t.left):1,o=t.right!==this.nil_node?this.testBlackHeightProperty(t.right):1,n!==o)throw new Error(\"Red-black height property violated\");return e+=n,e}},uO=class extends Set{constructor(t){super(t),this.index=new hO,this.forEach(t=\u003ethis.index.insert(t))}add(t){let e=this.size;const{key:n,value:o}=t,i=n||t.box,r=o||t;return super.add(r),this.size\u003ee\u0026\u0026this.index.insert(i,r),this}delete(t){const{key:e,value:n}=t,o=e||t.box,i=n||t;let r=super.delete(i);return r\u0026\u0026this.index.remove(o,i),r}clear(){super.clear(),this.index=new hO}search(t){return this.index.search(t)}hit(t){let e=new ME.Box(t.x-1,t.y-1,t.x+1,t.y+1);return this.index.search(e).filter(e=\u003et.on(e))}svg(){return[...this].reduce((t,e)=\u003et+e.svg(),\"\")}};ME.PlanarSet=uO;var pO=class{get name(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform((new aO).translate(...t))}rotate(t,e=new ME.Point){return this.transform((new aO).rotate(t,e.x,e.y))}scale(t,e){return this.transform((new aO).scale(t,e))}transform(...t){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}};ME.Point=class t extends pO{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length\u0026\u0026t[0]instanceof Array\u0026\u00262===t[0].length){let e=t[0];if(\"number\"==typeof e[0]\u0026\u0026\"number\"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"point\"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(2===t.length\u0026\u0026\"number\"==typeof t[0]\u0026\u0026\"number\"==typeof t[1])return this.x=t[0],void(this.y=t[1]);throw NE.ILLEGAL_PARAMETERS}}get box(){return new ME.Box(this.x,this.y,this.x,this.y)}clone(){return new ME.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return ME.Utils.EQ(this.x,t.x)\u0026\u0026ME.Utils.EQ(this.y,t.y)}lessThan(t){return!!ME.Utils.LT(this.y,t.y)||!(!ME.Utils.EQ(this.y,t.y)||!ME.Utils.LT(this.x,t.x))}transform(t){return new ME.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let e=new ME.Vector(this,t.pt);if(ME.Utils.EQ_0(e.cross(t.norm)))return t.pt.clone();let n=e.dot(t.norm),o=t.norm.multiply(n);return this.translate(o)}leftTo(t){let e=new ME.Vector(t.pt,this);return ME.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 ME.Segment(this,e)]}return e instanceof ME.Line?ME.Distance.point2line(this,e):e instanceof ME.Circle?ME.Distance.point2circle(this,e):e instanceof ME.Segment?ME.Distance.point2segment(this,e):e instanceof ME.Arc?ME.Distance.point2arc(this,e):e instanceof ME.Box?ME.Distance.point2polygon(this,new ME.Polygon(e)):e instanceof ME.Polygon?ME.Distance.point2polygon(this,e):e instanceof ME.PlanarSet?ME.Distance.shape2planarSet(this,e):e instanceof ME.Multiline?ME.Distance.shape2multiline(this,e):void 0}on(t){if(t instanceof ME.Point)return this.equalTo(t);if(t.contains\u0026\u0026t.contains instanceof Function)return t.contains(this);throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}get name(){return\"point\"}svg(t={}){const e=t.r??3;return`\\n\u003ccircle cx=\"${this.x}\" cy=\"${this.y}\" r=\"${e}\"\\n ${EE({fill:\"red\",...t})} /\u003e`}};var mO=(...t)=\u003enew ME.Point(...t);ME.point=mO;ME.Vector=class extends pO{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length\u0026\u0026t[0]instanceof Array\u0026\u00262===t[0].length){let e=t[0];if(\"number\"==typeof e[0]\u0026\u0026\"number\"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"vector\"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"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\u0026\u0026\"number\"==typeof n)return this.x=e,void(this.y=n);if(e instanceof ME.Point\u0026\u0026n instanceof ME.Point)return this.x=n.x-e.x,void(this.y=n.y-e.y)}throw NE.ILLEGAL_PARAMETERS}}clone(){return new ME.Vector(this.x,this.y)}get slope(){let t=Math.atan2(this.y,this.x);return t\u003c0\u0026\u0026(t=2*Math.PI+t),t}get length(){return Math.sqrt(this.dot(this))}isZeroLength(){return ME.Utils.EQ_0(this.length)}equalTo(t){return ME.Utils.EQ(this.x,t.x)\u0026\u0026ME.Utils.EQ(this.y,t.y)}multiply(t){return new ME.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 NE.ZERO_DIVISION;return new ME.Vector(this.x/this.length,this.y/this.length)}rotate(t,e=new ME.Point){if(0===e.x\u0026\u00260===e.y)return this.transform((new aO).rotate(t));throw NE.OPERATION_IS_NOT_SUPPORTED}transform(t){return new ME.Vector(t.transform([this.x,this.y]))}rotate90CCW(){return new ME.Vector(-this.y,this.x)}rotate90CW(){return new ME.Vector(this.y,-this.x)}invert(){return new ME.Vector(-this.x,-this.y)}add(t){return new ME.Vector(this.x+t.x,this.y+t.y)}subtract(t){return new ME.Vector(this.x-t.x,this.y-t.y)}angleTo(t){let e=this.normalize(),n=t.normalize(),o=Math.atan2(e.cross(n),e.dot(n));return o\u003c0\u0026\u0026(o+=2*Math.PI),o}projectionOn(t){let e=t.normalize(),n=this.dot(e);return e.multiply(n)}get name(){return\"vector\"}};var gO=(...t)=\u003enew ME.Vector(...t);ME.vector=gO;ME.Segment=class t extends pO{constructor(...t){if(super(),this.ps=new ME.Point,this.pe=new ME.Point,0!==t.length){if(1===t.length\u0026\u0026t[0]instanceof Array\u0026\u00264===t[0].length){let e=t[0];return this.ps=new ME.Point(e[0],e[1]),void(this.pe=new ME.Point(e[2],e[3]))}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"segment\"===t[0].name){let{ps:e,pe:n}=t[0];return this.ps=new ME.Point(e.x,e.y),void(this.pe=new ME.Point(n.x,n.y))}if(!(1===t.length\u0026\u0026t[0]instanceof ME.Point)){if(2===t.length\u0026\u0026t[0]instanceof ME.Point\u0026\u0026t[1]instanceof ME.Point)return this.ps=t[0].clone(),void(this.pe=t[1].clone());if(4===t.length)return this.ps=new ME.Point(t[0],t[1]),void(this.pe=new ME.Point(t[2],t[3]));throw NE.ILLEGAL_PARAMETERS}this.ps=t[0].clone()}}clone(){return new ME.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 ME.Vector(this.start,this.end).slope}get box(){return new ME.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)\u0026\u0026this.pe.equalTo(t.pe)}contains(t){return ME.Utils.EQ_0(this.distanceToPoint(t))}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?DE(this,t):t instanceof ME.Ray?oA(t,this):t instanceof ME.Segment?zE(this,t):t instanceof ME.Circle?jE(this,t):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=zE(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?$E(this,t):t instanceof ME.Polygon?ZE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2segment(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.segment2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.segment2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2segment(this,t);return[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.segment2arc(this,t);return[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline)return ME.Distance.shape2multiline(this,t)}tangentInStart(){return new ME.Vector(this.start,this.end).normalize()}tangentInEnd(){return new ME.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 ME.Segment(this.start,t),new ME.Segment(t,this.end)]}middle(){return new ME.Point((this.start.x+this.end.x)/2,(this.start.y+this.end.y)/2)}pointAtLength(t){if(t\u003ethis.length||t\u003c0)return null;if(0==t)return this.start;if(t==this.length)return this.end;let e=t/this.length;return new ME.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]=ME.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 ME.Matrix){return new t(this.ps.transform(e),this.pe.transform(e))}isZeroLength(){return this.ps.equalTo(this.pe)}sortPoints(t){return new ME.Line(this.start,this.end).sortPoints(t)}get name(){return\"segment\"}svg(t={}){return`\\n\u003cline x1=\"${this.start.x}\" y1=\"${this.start.y}\" x2=\"${this.end.x}\" y2=\"${this.end.y}\" ${EE(t)} /\u003e`}};var fO=(...t)=\u003enew ME.Segment(...t);ME.segment=fO;var{vector:yO}=ME;ME.Line=class t extends pO{constructor(...e){if(super(),this.pt=new ME.Point,this.norm=new ME.Vector(0,1),0!==e.length){if(1===e.length\u0026\u0026e[0]instanceof Object\u0026\u0026\"line\"===e[0].name){let{pt:t,norm:n}=e[0];return this.pt=new ME.Point(t),void(this.norm=new ME.Vector(n))}if(2===e.length){let n=e[0],o=e[1];if(n instanceof ME.Point\u0026\u0026o instanceof ME.Point)return this.pt=n,this.norm=t.points2norm(n,o),void(this.norm.dot(yO(this.pt.x,this.pt.y))\u003e=0\u0026\u0026this.norm.invert());if(n instanceof ME.Point\u0026\u0026o instanceof ME.Vector){if(ME.Utils.EQ_0(o.x)\u0026\u0026ME.Utils.EQ_0(o.y))throw NE.ILLEGAL_PARAMETERS;return this.pt=n.clone(),this.norm=o.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(yO(this.pt.x,this.pt.y))\u003e=0\u0026\u0026this.norm.invert())}if(n instanceof ME.Vector\u0026\u0026o instanceof ME.Point){if(ME.Utils.EQ_0(n.x)\u0026\u0026ME.Utils.EQ_0(n.y))throw NE.ILLEGAL_PARAMETERS;return this.pt=o.clone(),this.norm=n.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(yO(this.pt.x,this.pt.y))\u003e=0\u0026\u0026this.norm.invert())}}throw NE.ILLEGAL_PARAMETERS}}clone(){return new ME.Line(this.pt,this.norm)}get start(){}get end(){}get length(){return Number.POSITIVE_INFINITY}get box(){return new ME.Box(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)}get middle(){}get slope(){return new ME.Vector(this.norm.y,-this.norm.x).slope}get standard(){return[this.norm.x,this.norm.y,this.norm.dot(yO(this.pt.x,this.pt.y))]}parallelTo(t){return ME.Utils.EQ_0(this.norm.cross(t.norm))}incidentTo(t){return this.parallelTo(t)\u0026\u0026this.pt.on(t)}contains(t){if(this.pt.equalTo(t))return!0;let e=new ME.Vector(this.pt,t);return ME.Utils.EQ_0(this.norm.dot(e))}coord(t){return yO(t.x,t.y).cross(this.norm)}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?AE(this,t):t instanceof ME.Ray?sA(t,this):t instanceof ME.Circle?OE(this,t):t instanceof ME.Box?kE(this,t):t instanceof ME.Segment?DE(t,this):t instanceof ME.Arc?LE(this,t):t instanceof ME.Polygon?JE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.circle2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2line(t,this);return[e,n.reverse()]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2line(t,this);return[e,n.reverse()]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}}split(t){if(t instanceof ME.Point)return[new ME.Ray(t,this.norm),new ME.Ray(t,this.norm)];{let e=new ME.Multiline([this]),n=this.sortPoints(t);return e.split(n),e.toShapes()}}rotate(t,e=new ME.Point){return new ME.Line(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new ME.Line(this.pt.transform(t),this.norm.clone())}sortPoints(t){return t.slice().sort((t,e)=\u003ethis.coord(t)\u003cthis.coord(e)?-1:this.coord(t)\u003ethis.coord(e)?1:0)}get name(){return\"line\"}svg(t,e={}){let n=kE(this,t);if(0===n.length)return\"\";let o=n[0],i=2===n.length?n[1]:n.find(t=\u003e!t.equalTo(o));return void 0===i\u0026\u0026(i=o),new ME.Segment(o,i).svg(e)}static points2norm(t,e){if(t.equalTo(e))throw NE.ILLEGAL_PARAMETERS;return new ME.Vector(t,e).normalize().rotate90CCW()}};var _O=(...t)=\u003enew ME.Line(...t);ME.line=_O;ME.Circle=class extends pO{constructor(...t){if(super(),this.pc=new ME.Point,this.r=1,1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"circle\"===t[0].name){let{pc:e,r:n}=t[0];this.pc=new ME.Point(e),this.r=n}else{let[e,n]=[...t];e\u0026\u0026e instanceof ME.Point\u0026\u0026(this.pc=e.clone()),void 0!==n\u0026\u0026(this.r=n)}}clone(){return new ME.Circle(this.pc.clone(),this.r)}get center(){return this.pc}get box(){return new ME.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 ME.Point?ME.Utils.LE(t.distanceTo(this.center)[0],this.r):t instanceof ME.Segment?ME.Utils.LE(t.start.distanceTo(this.center)[0],this.r)\u0026\u0026ME.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof ME.Arc?0===this.intersect(t).length\u0026\u0026ME.Utils.LE(t.start.distanceTo(this.center)[0],this.r)\u0026\u0026ME.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof ME.Circle?0===this.intersect(t).length\u0026\u0026ME.Utils.LE(t.r,this.r)\u0026\u0026ME.Utils.LE(t.center.distanceTo(this.center)[0],this.r):void 0}toArc(t=!0){return new ME.Arc(this.center,this.r,Math.PI,-Math.PI,t)}scale(t,e){if(t!==e)throw NE.OPERATION_IS_NOT_SUPPORTED;if(0!==this.pc.x||0!==this.pc.y)throw NE.OPERATION_IS_NOT_SUPPORTED;return new ME.Circle(this.pc,this.r*t)}transform(t=new ME.Matrix){return new ME.Circle(this.pc.transform(t),this.r)}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?OE(t,this):t instanceof ME.Ray?rA(t,this):t instanceof ME.Segment?jE(t,this):t instanceof ME.Circle?YE(t,this):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=jE(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?VE(t,this):t instanceof ME.Polygon?KE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.circle2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.circle2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline){let[e,n]=ME.Distance.shape2multiline(this,t);return[e,n]}}get name(){return\"circle\"}svg(t={}){return`\\n\u003ccircle cx=\"${this.pc.x}\" cy=\"${this.pc.y}\" r=\"${this.r}\"\\n ${EE({fill:\"none\",...t})} /\u003e`}};ME.circle=(...t)=\u003enew ME.Circle(...t);ME.Arc=class extends pO{constructor(...t){if(super(),this.pc=new ME.Point,this.r=1,this.startAngle=0,this.endAngle=2*Math.PI,this.counterClockwise=!0,0!==t.length)if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"arc\"===t[0].name){let{pc:e,r:n,startAngle:o,endAngle:i,counterClockwise:r}=t[0];this.pc=new ME.Point(e.x,e.y),this.r=n,this.startAngle=o,this.endAngle=i,this.counterClockwise=r}else{let[e,n,o,i,r]=[...t];e\u0026\u0026e instanceof ME.Point\u0026\u0026(this.pc=e.clone()),void 0!==n\u0026\u0026(this.r=n),void 0!==o\u0026\u0026(this.startAngle=o),void 0!==i\u0026\u0026(this.endAngle=i),void 0!==r\u0026\u0026(this.counterClockwise=r)}}clone(){return new ME.Arc(this.pc.clone(),this.r,this.startAngle,this.endAngle,this.counterClockwise)}get sweep(){let t=this.startAngle,e=this.endAngle;if(ME.Utils.EQ(Math.abs(t-e),ME.PIx2))return ME.PIx2;Math.abs(t)\u003eME.PIx2\u0026\u0026(t-=Math.trunc(t/ME.PIx2)*ME.PIx2),t\u003c0\u0026\u0026(t+=ME.PIx2),Math.abs(e)\u003eME.PIx2\u0026\u0026(e-=Math.trunc(e/ME.PIx2)*ME.PIx2),e\u003c0\u0026\u0026(e+=ME.PIx2);let n=this.counterClockwise?e-t:t-e;return n\u003c0\u0026\u0026(n+=ME.PIx2),n}get start(){return new ME.Point(this.pc.x+this.r,this.pc.y).rotate(this.startAngle,this.pc)}get end(){return new ME.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)=\u003et.merge(e.start.box),new ME.Box);return t=t.merge(this.end.box),t}contains(t){if(!ME.Utils.EQ(this.pc.distanceTo(t)[0],this.r))return!1;if(t.equalTo(this.start))return!0;let e=new ME.Vector(this.pc,t).slope,n=new ME.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise);return ME.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 ME.Vector(this.pc,t).slope;return[new ME.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise),new ME.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 ME.Arc(this.pc,this.r,this.startAngle,t,this.counterClockwise).end}pointAtLength(t){if(t\u003ethis.length||t\u003c0)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 ME.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 ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?LE(t,this):t instanceof ME.Ray?iA(t,this):t instanceof ME.Circle?VE(this,t):t instanceof ME.Segment?$E(t,this):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=$E(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?XE(this,t):t instanceof ME.Polygon?qE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.arc2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.arc2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2arc(this,t);return[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline)return ME.Distance.shape2multiline(this,t)}breakToFunctional(){let t=[],e=[0,Math.PI/2,Math.PI,3*Math.PI/2],n=this.startAngle,o=this.endAngle;ME.Utils.EQ(Math.abs(n-o),ME.PIx2)\u0026\u0026(o=n),Math.abs(n)\u003eME.PIx2\u0026\u0026(n-=Math.trunc(n/ME.PIx2)*ME.PIx2),n\u003c0\u0026\u0026(n+=ME.PIx2),Math.abs(o)\u003eME.PIx2\u0026\u0026(o-=Math.trunc(o/ME.PIx2)*ME.PIx2),o\u003c0\u0026\u0026(o+=ME.PIx2);let i,r,s,a=n;this.counterClockwise?(r=Math.ceil(n/(Math.PI/2))%4,s=1):(r=Math.floor(n/(Math.PI/2))%4,s=-1);for(let o=0,c=r;o\u003c4;o++,c=(c+s+4)%4){if(i=e[c],i===a)continue;let o=this.counterClockwise?i-n:n-i;if(o\u003c0\u0026\u0026(o+=ME.PIx2),o\u003ethis.sweep)break;t.push(new ME.Arc(this.pc,this.r,a,i,this.counterClockwise)),a=i}return 0===t.length?(t.push(this),t):(i=o,a!==i\u0026\u0026t.push(new ME.Arc(this.pc,this.r,a,i,this.counterClockwise)),t)}tangentInStart(){let t=new ME.Vector(this.pc,this.start),e=this.counterClockwise?Math.PI/2:-Math.PI/2;return t.rotate(e).normalize()}tangentInEnd(){let t=new ME.Vector(this.pc,this.end),e=this.counterClockwise?-Math.PI/2:Math.PI/2;return t.rotate(e).normalize()}reverse(){return new ME.Arc(this.pc,this.r,this.endAngle,this.startAngle,!this.counterClockwise)}transform(t=new ME.Matrix){let e=this.start.transform(t),n=this.end.transform(t),o=this.pc.transform(t),i=this.counterClockwise;return t.a*t.d\u003c0\u0026\u0026(i=!i),ME.Arc.arcSE(o,e,n,i)}static arcSE(t,e,n,o){let{vector:i}=ME,r=i(t,e).slope,s=i(t,n).slope;ME.Utils.EQ(r,s)\u0026\u0026(s+=2*Math.PI,o=!0);let a=i(t,e).length;return new ME.Arc(t,a,r,s,o)}definiteIntegral(t=0){return this.breakToFunctional().reduce((e,n)=\u003ee+n.circularSegmentDefiniteIntegral(t),0)}circularSegmentDefiniteIntegral(t){let e=new ME.Segment(this.start,this.end).definiteIntegral(t),n=ME.Utils.EQ(this.sweep,ME.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}=ME;return t.slice().sort((t,n)=\u003e{let o=e(this.pc,t).slope,i=e(this.pc,n).slope;return o\u003ci?-1:o\u003ei?1:0})}get name(){return\"arc\"}svg(t={}){let e=this.sweep\u003c=Math.PI?\"0\":\"1\",n=this.counterClockwise?\"1\":\"0\";if(ME.Utils.EQ(this.sweep,2*Math.PI)){return new ME.Circle(this.pc,this.r).svg(t)}return`\\n\u003cpath d=\"M${this.start.x},${this.start.y}\\n A${this.r},${this.r} 0 ${e},${n} ${this.end.x},${this.end.y}\"\\n ${EE({fill:\"none\",...t})} /\u003e`}};ME.arc=(...t)=\u003enew ME.Arc(...t);ME.Box=class t extends pO{constructor(t=void 0,e=void 0,n=void 0,o=void 0){super(),this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}clone(){return new t(this.xmin,this.ymin,this.xmax,this.ymax)}get low(){return new ME.Point(this.xmin,this.ymin)}get high(){return new ME.Point(this.xmax,this.ymax)}get max(){return this.clone()}get center(){return new ME.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\u003ct.xmin||this.xmin\u003et.xmax||this.ymax\u003ct.ymin||this.ymin\u003et.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)\u0026\u0026this.high.equalTo(t.high)}output(){return this.clone()}comparable_less_than(t,e){return t.lessThan(e)}set(t,e,n,o){this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}extend(e){return e\u003c=0?this.clone():new t(this.xmin-e,this.ymin-e,this.xmax+e,this.ymax+e)}toPoints(){return[new ME.Point(this.xmin,this.ymin),new ME.Point(this.xmax,this.ymin),new ME.Point(this.xmax,this.ymax),new ME.Point(this.xmin,this.ymax)]}toSegments(){let t=this.toPoints();return[new ME.Segment(t[0],t[1]),new ME.Segment(t[1],t[2]),new ME.Segment(t[2],t[3]),new ME.Segment(t[3],t[0])]}rotate(t,e=new ME.Point){throw NE.OPERATION_IS_NOT_SUPPORTED}transform(e=new ME.Matrix){return this.toPoints().map(t=\u003et.transform(e)).reduce((t,e)=\u003et.merge(e.box),new t)}contains(t){return t instanceof ME.Point?t.x\u003e=this.xmin\u0026\u0026t.x\u003c=this.xmax\u0026\u0026t.y\u003e=this.ymin\u0026\u0026t.y\u003c=this.ymax:t instanceof ME.Segment?t.vertices.every(t=\u003ethis.contains(t)):t instanceof ME.Box?t.toSegments().every(t=\u003ethis.contains(t)):t instanceof ME.Circle?this.contains(t.box):t instanceof ME.Arc?t.vertices.every(t=\u003ethis.contains(t))\u0026\u0026this.toSegments().every(e=\u003e0===$E(e,t).length):!(t instanceof ME.Line||t instanceof ME.Ray)\u0026\u0026(t instanceof ME.Multiline?t.toShapes().every(t=\u003ethis.contains(t)):t instanceof ME.Polygon?this.contains(t.box):void 0)}distanceTo(t){const e=this.toSegments().map(e=\u003ee.distanceTo(t));let n=[Number.MAX_SAFE_INTEGER,null];return e.forEach(t=\u003e{t[0]\u003cn[0]\u0026\u0026(n=t)}),n}get name(){return\"box\"}svg(t={}){const e=this.xmax-this.xmin,n=this.ymax-this.ymin;return`\\n\u003crect x=\"${this.xmin}\" y=\"${this.ymin}\" width=\"${e}\" height=\"${n}\"\\n ${EE({fill:\"none\",...t})} /\u003e`}};ME.box=(...t)=\u003enew ME.Box(...t);ME.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 ME.Segment}get isArc(){return this.shape instanceof ME.Arc}get isLine(){return this.shape instanceof ME.Line}get isRay(){return this.shape instanceof ME.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 ME.Line||this.shape instanceof ME.Ray)return this.bv=ME.OUTSIDE,this.bv;if(void 0===this.bvStart\u0026\u0026(this.bvStart=KA(t,this.start)),void 0===this.bvEnd\u0026\u0026(this.bvEnd=KA(t,this.end)),this.bvStart===ME.OUTSIDE||this.bvEnd==ME.OUTSIDE)this.bv=ME.OUTSIDE;else if(this.bvStart===ME.INSIDE||this.bvEnd==ME.INSIDE)this.bv=ME.INSIDE;else{let e=KA(t,this.middle());this.bv=e}return this.bv}setOverlap(t){let e,n=this.shape,o=t.shape;n instanceof ME.Segment\u0026\u0026o instanceof ME.Segment?n.start.equalTo(o.start)\u0026\u0026n.end.equalTo(o.end)?e=ME.OVERLAP_SAME:n.start.equalTo(o.end)\u0026\u0026n.end.equalTo(o.start)\u0026\u0026(e=ME.OVERLAP_OPPOSITE):(n instanceof ME.Arc\u0026\u0026o instanceof ME.Arc||n instanceof ME.Segment\u0026\u0026o instanceof ME.Arc||n instanceof ME.Arc\u0026\u0026o instanceof ME.Segment)\u0026\u0026(n.start.equalTo(o.start)\u0026\u0026n.end.equalTo(o.end)\u0026\u0026n.middle().equalTo(o.middle())?e=ME.OVERLAP_SAME:n.start.equalTo(o.end)\u0026\u0026n.end.equalTo(o.start)\u0026\u0026n.middle().equalTo(o.middle())\u0026\u0026(e=ME.OVERLAP_OPPOSITE)),void 0===this.overlap\u0026\u0026(this.overlap=e),void 0===t.overlap\u0026\u0026(t.overlap=e)}svg(){if(this.shape instanceof ME.Segment)return` L${this.shape.end.x},${this.shape.end.y}`;if(this.shape instanceof ME.Arc){let t,e=this.shape,n=e.counterClockwise?\"1\":\"0\";if(ME.Utils.EQ(e.sweep,2*Math.PI)){let o=e.counterClockwise?1:-1,i=new ME.Arc(e.pc,e.r,e.startAngle,e.startAngle+o*Math.PI,e.counterClockwise),r=new ME.Arc(e.pc,e.r,e.startAngle+o*Math.PI,e.endAngle,e.counterClockwise);return t=\"0\",` A${i.r},${i.r} 0 ${t},${n} ${i.end.x},${i.end.y}\\n A${r.r},${r.r} 0 ${t},${n} ${r.end.x},${r.end.y}`}return t=e.sweep\u003c=Math.PI?\"0\":\"1\",` A${e.r},${e.r} 0 ${t},${n} ${e.end.x},${e.end.y}`}}toJSON(){return this.shape.toJSON()}};var bO=class extends wE{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:()=\u003e{let e=t||this.first,n=!this.first||!!t\u0026\u0026t===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}};ME.Face=class t extends bO{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 o=n[0];if(0===o.length)return;if(o.every(t=\u003et instanceof ME.Point)){let n=t.points2segments(o);this.shapes2face(e.edges,n)}else if(o.every(t=\u003et instanceof Array\u0026\u00262===t.length)){let n=o.map(t=\u003enew ME.Point(t[0],t[1])),i=t.points2segments(n);this.shapes2face(e.edges,i)}else if(o.every(t=\u003et instanceof ME.Segment||t instanceof ME.Arc))this.shapes2face(e.edges,o);else if(o.every(t=\u003e\"segment\"===t.name||\"arc\"===t.name)){let t=[];for(let e of o){let n;n=\"segment\"===e.name?new ME.Segment(e):new ME.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 ME.Circle)this.shapes2face(e.edges,[n[0].toArc(gE)]);else if(n[0]instanceof ME.Box){let t=n[0];this.shapes2face(e.edges,[new ME.Segment(new ME.Point(t.xmin,t.ymin),new ME.Point(t.xmax,t.ymin)),new ME.Segment(new ME.Point(t.xmax,t.ymin),new ME.Point(t.xmax,t.ymax)),new ME.Segment(new ME.Point(t.xmax,t.ymax),new ME.Point(t.xmin,t.ymax)),new ME.Segment(new ME.Point(t.xmin,t.ymax),new ME.Point(t.xmin,t.ymin))])}2===n.length\u0026\u0026n[0]instanceof ME.Edge\u0026\u0026n[1]instanceof ME.Edge\u0026\u0026(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=\u003et.shape.start.clone())}get shapes(){return this.edges.map(t=\u003et.shape.clone())}get box(){if(void 0===this._box){let t=new ME.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\u003ethis.perimeter||t\u003c0)return null;let e=null;for(let n of this)if(t\u003e=n.arc_length\u0026\u0026(n===this.last||t\u003cn.next.arc_length)){e=n.pointAtLength(t-n.arc_length);break}return e}static points2segments(t){let e=[];for(let n=0;n\u003ct.length;n++)t[n].equalTo(t[(n+1)%t.length])||e.push(new ME.Segment(t[n],t[(n+1)%t.length]));return e}shapes2face(t,e){for(let n of e){let e=new ME.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\u0026\u0026(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();ME.Utils.EQ_0(t)?this._orientation=fE.NOT_ORIENTABLE:ME.Utils.LT(t,0)?this._orientation=fE.CCW:this._orientation=fE.CW}return this._orientation}isSimple(e){return 0===t.getSelfIntersections(this,e,!0).length}static getSelfIntersections(t,e,n=!1){let o=[];for(let i of t){let r=e.search(i.box);for(let e of r){if(i===e)continue;if(e.face!==t)continue;if(i.shape instanceof ME.Segment\u0026\u0026e.shape instanceof ME.Segment\u0026\u0026(i.next===e||i.prev===e))continue;let r=i.shape.intersect(e.shape);for(let t of r)if((!t.equalTo(i.start)||!t.equalTo(e.end)||e!==i.prev)\u0026\u0026(!t.equalTo(i.end)||!t.equalTo(e.start)||e!==i.next)\u0026\u0026(o.push(t),n))break;if(o.length\u003e0\u0026\u0026n)break}if(o.length\u003e0\u0026\u0026n)break}return o}findEdgeByPoint(t){let e;for(let n of this)if(!t.equalTo(n.shape.start)\u0026\u0026(t.equalTo(n.shape.end)||n.shape.contains(t))){e=n;break}return e}toPolygon(){return new ME.Polygon(this.shapes)}toJSON(){return this.edges.map(t=\u003et.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}};ME.Ray=class t extends pO{constructor(...t){if(super(),this.pt=new ME.Point,this.norm=new ME.Vector(0,1),0!==t.length\u0026\u0026(t.length\u003e=1\u0026\u0026t[0]instanceof ME.Point\u0026\u0026(this.pt=t[0].clone()),1!==t.length)){if(!(2===t.length\u0026\u0026t[1]instanceof ME.Vector))throw NE.ILLEGAL_PARAMETERS;this.norm=t[1].clone()}}clone(){return new t(this.pt,this.norm)}get slope(){return new ME.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new ME.Box(t\u003eMath.PI/2\u0026\u0026t\u003c3*Math.PI/2?Number.NEGATIVE_INFINITY:this.pt.x,t\u003e=0\u0026\u0026t\u003c=Math.PI?this.pt.y:Number.NEGATIVE_INFINITY,t\u003e=Math.PI/2\u0026\u0026t\u003c=3*Math.PI/2?this.pt.x:Number.POSITIVE_INFINITY,t\u003e=Math.PI\u0026\u0026t\u003c=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 ME.Vector(this.pt,t);return ME.Utils.EQ_0(this.norm.dot(e))\u0026\u0026ME.Utils.GE(e.cross(this.norm),0)}coord(t){return gO(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new ME.Segment(this.pt,t),new ME.Ray(t,this.norm)]:[]}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Segment?oA(this,t):t instanceof ME.Arc?iA(this,t):t instanceof ME.Line?sA(this,t):t instanceof ME.Ray?(n=t,AE(nA(e=this),nA(n)).filter(t=\u003ee.contains(t)).filter(t=\u003en.contains(t))):t instanceof ME.Circle?rA(this,t):t instanceof ME.Box?(i=t,kE(nA(o=this),i).filter(t=\u003eo.contains(t))):t instanceof ME.Polygon?aA(this,t):t instanceof ME.Multiline?lA(this,t):void 0;var e,n,o,i}rotate(t,e=new ME.Point){return new ME.Ray(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new ME.Ray(this.pt.transform(t),this.norm.clone())}get name(){return\"ray\"}svg(t,e={}){let n=kE(new ME.Line(this.pt,this.norm),t);return n=n.filter(t=\u003ethis.contains(t)),0===n.length||2===n.length?\"\":new ME.Segment(this.pt,n[0]).svg(e)}};ME.ray=(...t)=\u003enew ME.Ray(...t);var xO=class t{constructor(){this.faces=new ME.PlanarSet,this.edges=new ME.PlanarSet;let t=[...arguments];if(1===t.length\u0026\u0026(t[0]instanceof Array\u0026\u0026t[0].length\u003e0||t[0]instanceof ME.Circle||t[0]instanceof ME.Box)){let e=t[0];if(t[0]instanceof Array\u0026\u0026t[0].every(t=\u003et instanceof Array))if(e.every(t=\u003et instanceof Array\u0026\u00262===t.length\u0026\u0026\"number\"==typeof t[0]\u0026\u0026\"number\"==typeof t[1]))this.faces.add(new ME.Face(this,e));else for(let t of e)if(t instanceof Array\u0026\u0026t[0]instanceof Array\u0026\u0026t[0].every(t=\u003et instanceof Array\u0026\u00262===t.length\u0026\u0026\"number\"==typeof t[0]\u0026\u0026\"number\"==typeof t[1]))for(let e of t)this.faces.add(new ME.Face(this,e));else this.faces.add(new ME.Face(this,t));else this.faces.add(new ME.Face(this,e))}}get box(){return[...this.faces].reduce((t,e)=\u003et.merge(e.box),new ME.Box)}get vertices(){return[...this.faces].flatMap(t=\u003et.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=\u003e[...t.faces].forEach(t=\u003en.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)=\u003et+e.signedArea(),0);return Math.abs(t)}addFace(...t){let e=new ME.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 o=e;o!==n.next;o=o.next)if(t.remove(o),this.edges.delete(o),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 o=new ME.Edge(n[0]),i=e.prev;return e.face.insert(o,i),this.edges.delete(e),this.edges.add(o),e.shape=n[1],this.edges.add(e),o}removeEndVertex(t){const e=t.next;e!==t\u0026\u0026(t.face.merge_with_next_edge(t),this.edges.delete(e))}cut(t){const e=this.splitToIslands().flatMap(e=\u003ee._cutSingleIsland(t)).filter(t=\u003et.isValid()\u0026\u0026!1===t.isEmpty());return this.createFromArray(e)}_cutSingleIsland(t){let e=this.clone();const n=t.clone();let o,i,r={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let t of n.edges)for(let n of e.edges){let e=QE(t,n);for(let o of e)hA(t,o,r.int_points1),hA(n,o,r.int_points2)}if(0===r.int_points1.length)return e;r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2),bA(n,r.int_points1_sorted),bA(e,r.int_points2_sorted),gA(r),r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2),fA(r.int_points1),yA(r.int_points1,e);for(let t of r.int_points1_sorted)t.edge_before\u0026\u0026t.edge_after\u0026\u0026t.edge_before.bv===t.edge_after.bv\u0026\u0026(r.int_points2[t.id]=-1,t.id=-1);if(r.int_points1=r.int_points1.filter(t=\u003et.id\u003e=0),r.int_points2=r.int_points2.filter(t=\u003et.id\u003e=0),r.int_points1.forEach((t,e)=\u003e{t.id=e}),r.int_points2.forEach((t,e)=\u003e{t.id=e}),0===r.int_points1.length)return e;r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2);for(let t=1;t\u003cr.int_points1_sorted.length;t++)if(i=r.int_points1_sorted[t],o=r.int_points1_sorted[t-1],i.edge_before\u0026\u00261===i.edge_before.bv){let t=o.edge_after,s=i.edge_before,a=n.getChain(t,s);xA(r.int_points2[o.id],r.int_points2[i.id],a),a.forEach(t=\u003ee.edges.add(t)),a=a.reverse().map(t=\u003enew ME.Edge(t.shape.reverse()));for(let t=0;t\u003ca.length-1;t++)a[t].next=a[t+1],a[t+1].prev=a[t];xA(r.int_points2[i.id],r.int_points2[o.id],a),a.forEach(t=\u003ee.edges.add(t))}return e.recreateFaces(),e}cutWithLine(t){let e=new dA([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)=\u003ee.area()-t.area());let e=[...t[0].faces][0].orientation(),n=t.filter(t=\u003e[...t.faces][0].orientation()===e);for(let o of t){let t=[...o.faces][0];if(t.orientation()!==e)for(let e of n)if(t.shapes.every(t=\u003ee.contains(t))){e.addFace(t.shapes);break}}return n}rearrange(){if(this.faces.size\u003c=1)return this.clone();const e=this.splitToIslands(),n=new t;return e.forEach(t=\u003e{t.faces.forEach(t=\u003en.addFace(t.shapes))}),n}orientation(){return this.isEmpty()?fE.NOT_ORIENTABLE:[...this.faces][0].orientation()}isOuter(t){return t.orientation()===this.orientation()}isMultiPolygon(){let t=0;return this.faces.forEach(e=\u003e{this.isOuter(e)\u0026\u0026t++}),t\u003e1}reverse(){for(let t of this.faces)t.reverse();return this}contains(t){if(t instanceof ME.Point){let e=KA(this,t);return 1===e||2===e}return nO(this,t)}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle||t instanceof ME.Line||t instanceof ME.Segment||t instanceof ME.Arc){let[e,n]=ME.Distance.shape2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Box)return this.distanceTo(new ME.Polygon(t));if(t instanceof ME.Polygon){let e,n,o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of this.edges){let r=o[0];[e,n]=ME.Distance.shape2planarSet(i.shape,t.edges,r),ME.Utils.LT(e,r)\u0026\u0026(o=[e,n])}return o}}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?JE(t,this):t instanceof ME.Ray?aA(t,this):t instanceof ME.Circle?KE(t,this):t instanceof ME.Segment?ZE(t,this):t instanceof ME.Arc?qE(t,this):t instanceof ME.Polygon?function(t,e){let n=[];if(t.isEmpty()||e.isEmpty())return n;if(t.box.not_intersect(e.box))return n;for(let o of t.edges)n=[...n,...tA(o,e)];return n}(t,this):t instanceof ME.Multiline?function(t,e){let n=[];if(e.isEmpty()||0===t.size)return n;for(let o of t)n=[...n,...tA(o,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=\u003et.translate(e)));return n}rotate(e=0,n=new ME.Point){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=\u003et.rotate(e,n)));return o}scale(e,n){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=\u003et.scale(e,n)));return o}transform(e=new ME.Matrix){let n=new t;for(let t of this.faces)n.addFace(t.shapes.map(t=\u003et.transform(e)));return n}toJSON(){return[...this.faces].map(t=\u003et.toJSON())}toArray(){return[...this.faces].map(t=\u003et.toPolygon())}dpath(){return[...this.faces].reduce((t,e)=\u003et+e.svg(),\"\")}svg(t={}){let e=`\\n\u003cpath ${EE({fillRule:\"evenodd\",fill:\"lightcyan\",...t})} d=\"`;for(let t of this.faces)e+=`\\n${t.svg()}`;return e+='\" \u003e\\n\u003c/path\u003e',e}};ME.Polygon=xO;ME.polygon=(...t)=\u003enew ME.Polygon(...t);var{Circle:vO,Line:SO,Point:IO,Vector:CO,Utils:PO}=ME;ME.Inversion=class t{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,e){const n=new CO(t.pc,e),o=t.r*t.r,i=n.dot(n);return PO.EQ_0(i)?new IO(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY):t.pc.translate(n.multiply(o/i))}static inverseCircle(t,e){const n=t.pc.distanceTo(e.pc)[0];if(PO.EQ(n,e.r)){let n=t.r*t.r/(2*e.r),o=new CO(t.pc,e.pc);o=o.normalize();let i=t.pc.translate(o.multiply(n));return new SO(i,o)}{let n=new CO(t.pc,e.pc),o=t.r*t.r/(n.dot(n)-e.r*e.r),i=t.pc.translate(n.multiply(o)),r=Math.abs(o)*e.r;return new vO(i,r)}}static inverseLine(t,e){const[n,o]=t.pc.distanceTo(e);if(PO.EQ_0(n))return e.clone();{let e=t.r*t.r/(2*n),i=new CO(t.pc,o.end);return i=i.multiply(e/n),new vO(t.pc.translate(i),e)}}inverse(e){return e instanceof IO?t.inversePoint(this.circle,e):e instanceof vO?t.inverseCircle(this.circle,e):e instanceof SO?t.inverseLine(this.circle,e):void 0}};ME.inversion=t=\u003enew ME.Inversion(t);ME.Distance=class t{static point2point(t,e){return t.distanceTo(e)}static point2line(t,e){let n=t.projectionOn(e);return[new ME.Vector(t,n).length,new ME.Segment(t,n)]}static point2circle(t,e){let[n,o]=t.distanceTo(e.center);if(ME.Utils.EQ_0(n))return[e.r,new ME.Segment(t,e.toArc().start)];{let o=Math.abs(n-e.r),i=new ME.Vector(e.pc,t).normalize().multiply(e.r),r=e.pc.translate(i);return[o,new ME.Segment(t,r)]}}static point2segment(e,n){if(n.start.equalTo(n.end))return t.point2point(e,n.start);let o,i,r=new ME.Vector(n.start,n.end),s=new ME.Vector(n.start,e),a=new ME.Vector(n.end,e),c=r.dot(s),l=-r.dot(a);if(ME.Utils.GE(c,0)\u0026\u0026ME.Utils.GE(l,0)){let t=n.tangentInStart();return o=Math.abs(t.cross(s)),i=n.start.translate(t.multiply(t.dot(s))),[o,new ME.Segment(e,i)]}return c\u003c0?e.distanceTo(n.start):e.distanceTo(n.end)}static point2arc(e,n){let o,i,r=new ME.Circle(n.pc,n.r),s=[];return[o,i]=t.point2circle(e,r),i.end.on(n)\u0026\u0026s.push(t.point2circle(e,r)),s.push(t.point2point(e,n.start)),s.push(t.point2point(e,n.end)),t.sort(s),s[0]}static point2edge(e,n){return n.shape instanceof ME.Segment?t.point2segment(e,n.shape):t.point2arc(e,n.shape)}static segment2line(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=[];return i.push(t.point2line(e.start,n)),i.push(t.point2line(e.end,n)),t.sort(i),i[0]}static segment2segment(e,n){let o=zE(e,n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i,r,s=[];return[i,r]=t.point2segment(n.start,e),s.push([i,r.reverse()]),[i,r]=t.point2segment(n.end,e),s.push([i,r.reverse()]),s.push(t.point2segment(e.start,n)),s.push(t.point2segment(e.end,n)),t.sort(s),s[0]}static segment2circle(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Line(e.ps,e.pe),[r,s]=t.point2line(n.center,i);if(ME.Utils.GE(r,n.r)\u0026\u0026s.end.on(e))return t.point2circle(s.end,n);{let[o,i]=t.point2circle(e.start,n),[r,s]=t.point2circle(e.end,n);return ME.Utils.LT(o,r)?[o,i]:[r,s]}}static segment2arc(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Line(e.ps,e.pe),r=new ME.Circle(n.pc,n.r),[s,a]=t.point2line(r.center,i);if(ME.Utils.GE(s,r.r)\u0026\u0026a.end.on(e)){let[e,o]=t.point2circle(a.end,r);if(o.end.on(n))return[e,o]}let c,l,d=[];return d.push(t.point2arc(e.start,n)),d.push(t.point2arc(e.end,n)),[c,l]=t.point2segment(n.start,e),d.push([c,l.reverse()]),[c,l]=t.point2segment(n.end,e),d.push([c,l.reverse()]),t.sort(d),d[0]}static circle2circle(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];if(e.center.equalTo(n.center)){let o=e.toArc(),i=n.toArc();return t.point2point(o.start,i.start)}{let o=new ME.Line(e.center,n.center),i=o.intersect(e),r=o.intersect(n),s=[];return s.push(t.point2point(i[0],r[0])),s.push(t.point2point(i[0],r[1])),s.push(t.point2point(i[1],r[0])),s.push(t.point2point(i[1],r[1])),t.sort(s),s[0]}}static circle2line(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let[i,r]=t.point2line(e.center,n),[s,a]=t.point2circle(r.end,e);return a=a.reverse(),[s,a]}static arc2line(e,n){let o=n.intersect(e);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),[r,s]=t.point2line(i.center,n);if(!ME.Utils.GE(r,i.r)){let o=[];return o.push(t.point2line(e.start,n)),o.push(t.point2line(e.end,n)),t.sort(o),o[0]}{let[n,o]=t.point2circle(s.end,i);if(o.end.on(e))return[n,o]}}static arc2circle(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),[r,s]=t.circle2circle(i,n);if(s.start.on(e))return[r,s];{let o=[];return o.push(t.point2circle(e.start,n)),o.push(t.point2circle(e.end,n)),t.sort(o),o[0]}}static arc2arc(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),r=new ME.Circle(n.center,n.r),[s,a]=t.circle2circle(i,r);if(a.start.on(e)\u0026\u0026a.end.on(n))return[s,a];{let o,i,r=[];return[o,i]=t.point2arc(e.start,n),i.end.on(n)\u0026\u0026r.push([o,i]),[o,i]=t.point2arc(e.end,n),i.end.on(n)\u0026\u0026r.push([o,i]),[o,i]=t.point2arc(n.start,e),i.end.on(e)\u0026\u0026r.push([o,i.reverse()]),[o,i]=t.point2arc(n.end,e),i.end.on(e)\u0026\u0026r.push([o,i.reverse()]),[o,i]=t.point2point(e.start,n.start),r.push([o,i]),[o,i]=t.point2point(e.start,n.end),r.push([o,i]),[o,i]=t.point2point(e.end,n.start),r.push([o,i]),[o,i]=t.point2point(e.end,n.end),r.push([o,i]),t.sort(r),r[0]}}static point2polygon(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of n.edges){let[n,r]=t.point2edge(e,i);ME.Utils.LT(n,o[0])\u0026\u0026(o=[n,r])}return o}static shape2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new ME.Segment];for(let o of e.edges){let[e,i]=t.distanceTo(o.shape);ME.Utils.LT(e,n[0])\u0026\u0026(n=[e,i])}return n}static polygon2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new ME.Segment];for(let o of t.edges)for(let t of e.edges){let[e,i]=o.shape.distanceTo(t.shape);ME.Utils.LT(e,n[0])\u0026\u0026(n=[e,i])}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)),o=Math.max(Math.max(t.ymin-e.ymax,0),Math.max(e.ymin-t.ymax,0)),i=n*n+o*o,r=t.merge(e),s=r.xmax-r.xmin,a=r.ymax-r.ymin;return[i,s*s+a*a]}static minmax_tree_process_level(e,n,o,i){let r,s;for(let a of n){[r,s]=t.box2box_minmax(e.box,a.item.key);for(let t of a.item.values)t instanceof ME.Edge?i.insert([r,s],t.shape):i.insert([r,s],t);ME.Utils.LT(s,o)\u0026\u0026(o=s)}if(0===n.length)return o;let a=[...n.map(t=\u003et.left.isNil()?void 0:t.left).filter(t=\u003evoid 0!==t),...n.map(t=\u003et.right.isNil()?void 0:t.right).filter(t=\u003evoid 0!==t)].filter(n=\u003e{let[i,r]=t.box2box_minmax(e.box,n.max);return ME.Utils.LE(i,o)});return o=t.minmax_tree_process_level(e,a,o,i)}static minmax_tree(e,n,o){let i=new hO,r=[n.index.root],s=o\u003cNumber.POSITIVE_INFINITY?o*o:Number.POSITIVE_INFINITY;return s=t.minmax_tree_process_level(e,r,s,i),i}static minmax_tree_calc_distance(e,n,o){let i,r;if(null!=n\u0026\u0026!n.isNil()){if([i,r]=t.minmax_tree_calc_distance(e,n.left,o),r)return[i,r];if(ME.Utils.LT(i[0],Math.sqrt(n.item.key.low)))return[i,!0];let[s,a]=t.distanceToArray(e,n.item.values);return ME.Utils.LT(s,i[0])\u0026\u0026(i=[s,a]),[i,r]=t.minmax_tree_calc_distance(e,n.right,i),[i,r]}return[o,!1]}static shape2planarSet(e,n,o=Number.POSITIVE_INFINITY){let i=[o,new ME.Segment],r=!1;if(n instanceof ME.PlanarSet){let s=t.minmax_tree(e,n,o);[i,r]=t.minmax_tree_calc_distance(e,s.root,i)}return i}static sort(t){t.sort((t,e)=\u003eME.Utils.LT(t[0],e[0])?-1:ME.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 ME.Segment];for(let o of e){let[e,i]=t.distanceTo(o);ME.Utils.LT(e,n[0])\u0026\u0026(n=[e,i])}return n}static shape2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of n){let[n,r]=t.distance(e,i.shape);ME.Utils.LT(n,o[0])\u0026\u0026(o=[n,r])}return o}static multiline2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of e)for(let e of n){let[n,r]=t.distance(i.shape,e.shape);ME.Utils.LT(n,o[0])\u0026\u0026(o=[n,r])}return o}};var{Multiline:MO,Point:NO,Segment:wO,Polygon:TO}=ME;function RO(t){return new NO(t.split(\" \").map(Number))}function EO(t){return t.split(\", \").map(RO)}function AO(t){const e=EO(t);let n=[];for(let t=0;t\u003ce.length-1;t++)n.push(new wO(e[t],e[t+1]));return new MO(n)}function OO(t){const e=t.replace(/\\(\\(/,\"\").replace(/\\)\\)$/,\"\").split(\"), (\"),n=new TO;let o;return e.forEach((t,e)=\u003e{let i=t.split(\", \").map(t=\u003enew NO(t.split(\" \").map(Number)));const r=n.addFace(i);0===e?o=r.orientation():r.orientation()===o\u0026\u0026r.reverse()}),n}function kO(t){if(t.startsWith(\"POLYGON\")){return OO(t.replace(/^POLYGON /,\"\"))}return function(t){const e=t.split(/\\)\\), \\(\\(/).map(t=\u003e\"((\"+t+\"))\").map(OO),n=new TO;return e.reduce((t,e)=\u003e[...t,...e?.faces],[]).forEach(t=\u003en.addFace([...t?.shapes])),n}(t.replace(/^MULTIPOLYGON \\(\\(\\((.*)\\)\\)\\)$/,\"$1\"))}function LO(t){return t.split(\"\\n\")?.every(t=\u003et.includes(\"POINT\"))}function DO(t){return t.split(\"\\n\")?.every(t=\u003et.includes(\"LINESTRING\"))}function zO(t,e,n,o){return Math.sqrt((n-t)**2+(o-e)**2)}ME.isWktString=function(t){return t.startsWith(\"POINT\")||LO(t)||t.startsWith(\"LINESTRING\")||DO(t)||t.startsWith(\"MULTILINESTRING\")||t.startsWith(\"POLYGON\")||t.startsWith(\"MULTIPOINT\")||t.startsWith(\"MULTIPOLYGON\")||t.startsWith(\"GEOMETRYCOLLECTION\")},ME.parseWKT=function t(e){if(e.startsWith(\"POINT\")){return RO(e.replace(/^POINT \\(/,\"\").replace(/\\)$/,\"\"))}if(e.startsWith(\"MULTIPOINT\")){return EO(e.replace(/^MULTIPOINT \\(/,\"\").replace(/\\)$/,\"\"))}if(e.startsWith(\"LINESTRING\")){return AO(e.replace(/^LINESTRING \\(/,\"\").replace(/\\)$/,\"\"))}if(e.startsWith(\"MULTILINESTRING\")){return function(t){return t.replace(/\\(\\(/,\"\").replace(/\\)\\)$/,\"\").split(\"), (\").map(AO)}(e.replace(/^MULTILINESTRING /,\"\"))}if(e.startsWith(\"POLYGON\")||e.startsWith(\"MULTIPOLYGON\"))return kO(e);if(e.startsWith(\"GEOMETRYCOLLECTION\")){const n=/(?\u003ctype\u003ePOINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \\((?:[^\\(\\)]|\\([^\\)]*\\))*\\)/g,o=e.match(n);o[0].startsWith(\"GEOMETRYCOLLECTION\")\u0026\u0026(o[0]=o[0].replace(\"GEOMETRYCOLLECTION (\",\"\"));return o.map(t).map(t=\u003et instanceof Array?t:[t]).reduce((t,e)=\u003e[...t,...e],[])}return LO(e)?function(t){return t.split(\"\\n\").map(t=\u003et.match(/\\(([^)]+)\\)/)[1]).map(RO)}(e):DO(e)?function(t){return t.split(\"\\n\").map(t=\u003et.match(/\\(([^)]+)\\)/)[1]).map(AO).reduce((t,e)=\u003e[...t,...e],[])}(e):[]},ME.BooleanOperations=WA,ME.Relations=sO;var FO=class{buckets;objectsById;getBounds;getId;CELL_SIZE=.4;constructor({objects:t,getBounds:e,getId:n,CELL_SIZE:o}){this.buckets=new Map,this.objectsById=new Map,this.getBounds=e,this.getId=n??(()=\u003ethis._getNextId()),this.CELL_SIZE=o??this.CELL_SIZE;for(const e of t)this.addObject(e)}_idCounter=0;_getNextId(){return\"\"+this._idCounter++}addObject(t){const e=this.getBounds(t),n=this.getId(t),o={...t,spatialIndexId:n};this.objectsById.set(n,o);const i=Math.floor(e.minX/this.CELL_SIZE),r=Math.floor(e.minY/this.CELL_SIZE),s=Math.floor(e.maxX/this.CELL_SIZE),a=Math.floor(e.maxY/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const n=`${t}x${e}`,i=this.buckets.get(n);i?i.push(o):this.buckets.set(n,[o])}}removeObject(t){const e=this.objectsById.get(t);if(!e)return!1;this.objectsById.delete(t);const n=this.getBounds(e),o=Math.floor(n.minX/this.CELL_SIZE),i=Math.floor(n.minY/this.CELL_SIZE),r=Math.floor(n.maxX/this.CELL_SIZE),s=Math.floor(n.maxY/this.CELL_SIZE);for(let e=o;e\u003c=r;e++)for(let n=i;n\u003c=s;n++){const o=`${e}x${n}`,i=this.buckets.get(o);if(i){const e=i.findIndex(e=\u003ee.spatialIndexId===t);-1!==e\u0026\u0026(i.splice(e,1),0===i.length\u0026\u0026this.buckets.delete(o))}}return!0}getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getObjectsInBounds(t,e=0){const n=[],o=new Set,i=Math.floor((t.minX-e)/this.CELL_SIZE),r=Math.floor((t.minY-e)/this.CELL_SIZE),s=Math.floor((t.maxX+e)/this.CELL_SIZE),a=Math.floor((t.maxY+e)/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const i=`${t}x${e}`,r=this.buckets.get(i)||[];for(const t of r){const e=t.spatialIndexId;o.has(e)||(o.add(e),n.push(t))}}return n}},BO=.1,jO=.1,$O=BO,YO=BO,XO=.005;function VO(t){return\"pcb_trace_segment\"===t.type||\"pcb_smtpad\"===t.type?[t.layer]:\"pcb_plated_hole\"===t.type?Array.isArray(t.layers)?t.layers:[...uw]:\"pcb_hole\"===t.type?[...uw]:\"pcb_via\"===t.type?Array.isArray(t.layers)?t.layers:[...uw]:\"pcb_keepout\"===t.type\u0026\u0026Array.isArray(t.layers)?t.layers:[]}var WO=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=e.minX,r=e.minY,s=e.maxX,a=e.maxY;if(n.x===o.x\u0026\u0026n.y===o.y){const t=Math.max(i,Math.min(s,n.x)),e=Math.max(r,Math.min(a,n.y));return t===n.x\u0026\u0026e===n.y?{x:n.x,y:n.y}:{x:t,y:e}}const c=o.x-n.x,l=o.y-n.y,d=0!==c?(i-n.x)/c:Number.NEGATIVE_INFINITY,h=0!==c?(s-n.x)/c:Number.POSITIVE_INFINITY,u=0!==l?(r-n.y)/l:Number.NEGATIVE_INFINITY,p=0!==l?(a-n.y)/l:Number.POSITIVE_INFINITY,m=Math.max(Math.min(d,h),Math.min(u,p)),g=Math.min(Math.max(d,h),Math.max(u,p));if(m\u003c=g\u0026\u0026g\u003e=0\u0026\u0026m\u003c=1){const t=Math.max(0,Math.min(1,m));return{x:n.x+t*c,y:n.y+t*l}}const f={x:Math.max(i,Math.min(s,n.x)),y:Math.max(r,Math.min(a,n.y))},y={x:Math.max(i,Math.min(s,o.x)),y:Math.max(r,Math.min(a,o.y))},_=(f.x-n.x)**2+(f.y-n.y)**2,b=(y.x-o.x)**2+(y.y-o.y)**2,x=[{start:{x:i,y:r},end:{x:s,y:r}},{start:{x:s,y:r},end:{x:s,y:a}},{start:{x:s,y:a},end:{x:i,y:a}},{start:{x:i,y:a},end:{x:i,y:r}}];let v=Math.min(_,b),S=_\u003c=b?f:y;const I=(t,e,n)=\u003eMath.max(e,Math.min(n,t));for(const t of x){const e={x:o.x-n.x,y:o.y-n.y},i={x:t.end.x-t.start.x,y:t.end.y-t.start.y},r={x:n.x-t.start.x,y:n.y-t.start.y},s=e.x*e.x+e.y*e.y,a=e.x*i.x+e.y*i.y,c=e.x*r.x+e.y*r.y,l=i.x*i.x+i.y*i.y,d=i.x*r.x+i.y*r.y,h=s*l-a*a;if(Math.abs(h)\u003c1e-10)continue;let u=(a*d-l*c)/h,p=(s*d-a*c)/h;u=I(u,0,1),p=I(p,0,1);const m={x:n.x+u*e.x,y:n.y+u*e.y},g={x:t.start.x+p*i.x,y:t.start.y+p*i.y},f=m.x-g.x,y=m.y-g.y,_=f*f+y*y;_\u003cv\u0026\u0026(v=_,S={x:(m.x+g.x)/2,y:(m.y+g.y)/2})}return S},HO=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i={x:e.x1,y:e.y1},r={x:e.x2,y:e.y2},s={x:o.x-n.x,y:o.y-n.y},a={x:r.x-i.x,y:r.y-i.y},c=s.x*s.x+s.y*s.y,l=a.x*a.x+a.y*a.y;if(0===c||0===l){if(0===c\u0026\u00260===l)return{x:(n.x+i.x)/2,y:(n.y+i.y)/2};if(0===c){const t=UO(((n.x-i.x)*a.x+(n.y-i.y)*a.y)/l,0,1),e={x:i.x+t*a.x,y:i.y+t*a.y};return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}}const t=UO(((i.x-n.x)*s.x+(i.y-n.y)*s.y)/c,0,1),e={x:n.x+t*s.x,y:n.y+t*s.y};return{x:(e.x+i.x)/2,y:(e.y+i.y)/2}}const d=n.x-i.x,h=n.y-i.y,u=s.x*s.x+s.y*s.y,p=s.x*a.x+s.y*a.y,m=s.x*d+s.y*h,g=a.x*a.x+a.y*a.y,f=a.x*d+a.y*h,y=u*g-p*p;if(y\u003c1e-10)return GO(n,o,i,r,s,a,c,l);let _=(p*f-g*m)/y,b=(u*f-p*m)/y;_=UO(_,0,1),b=UO(b,0,1),b=(_*p+f)/g,b=UO(b,0,1),_=(b*p-m)/u,_=UO(_,0,1);const x=n.x+_*s.x,v=n.y+_*s.y,S=i.x+b*a.x,I=i.y+b*a.y,C=x-S,P=v-I;Math.sqrt(C*C+P*P);return{x:(x+S)/2,y:(v+I)/2}},GO=(t,e,n,o,i,r,s,a)=\u003e{let c=((n.x-t.x)*i.x+(n.y-t.y)*i.y)/s;c=UO(c,0,1);const l={x:t.x+c*i.x,y:t.y+c*i.y};let d=((o.x-t.x)*i.x+(o.y-t.y)*i.y)/s;d=UO(d,0,1);const h={x:t.x+d*i.x,y:t.y+d*i.y};let u=((t.x-n.x)*r.x+(t.y-n.y)*r.y)/a;u=UO(u,0,1);const p={x:n.x+u*r.x,y:n.y+u*r.y};let m=((e.x-n.x)*r.x+(e.y-n.y)*r.y)/a;m=UO(m,0,1);const g={x:n.x+m*r.x,y:n.y+m*r.y},f=[{pointA:l,pointB:n,distance:Math.sqrt((l.x-n.x)**2+(l.y-n.y)**2)},{pointA:h,pointB:o,distance:Math.sqrt((h.x-o.x)**2+(h.y-o.y)**2)},{pointA:t,pointB:p,distance:Math.sqrt((t.x-p.x)**2+(t.y-p.y)**2)},{pointA:e,pointB:g,distance:Math.sqrt((e.x-g.x)**2+(e.y-g.y)**2)}].reduce((t,e)=\u003ee.distance\u003ct.distance?e:t);return{x:(f.pointA.x+f.pointB.x)/2,y:(f.pointA.y+f.pointB.y)/2}},UO=(t,e,n)=\u003eMath.max(e,Math.min(n,t)),ZO=t=\u003e\"pcb_trace_segment\"===t.type?{minX:Math.min(t.x1,t.x2),minY:Math.min(t.y1,t.y2),maxX:Math.max(t.x1,t.x2),maxY:Math.max(t.y1,t.y2)}:EM([t]);function qO(t){const e=new Set;for(const n of t.route)\"wire\"===n.route_type\u0026\u0026(n.start_pcb_port_id\u0026\u0026e.add(n.start_pcb_port_id),n.end_pcb_port_id\u0026\u0026e.add(n.end_pcb_port_id));return Array.from(e)}function JO(t){const e=new Set;for(const n of t)for(const t of qO(n))e.add(t);return Array.from(e)}var KO=t=\u003e{if(\"pcb_via\"===t.type)return t.outer_diameter/2;if(\"pcb_plated_hole\"===t.type\u0026\u0026\"circle\"===t.shape)return t.outer_diameter/2;if(\"pcb_hole\"===t.type\u0026\u0026\"circle\"===t.hole_shape)return t.hole_diameter/2;if(\"pcb_smtpad\"===t.type\u0026\u0026\"circle\"===t.shape)return t.radius;throw new Error(`Could not determine radius of element: ${JSON.stringify(t)}`)};function QO(t,{connMap:e,minClearance:n=.1}={}){const o=[];(t=\u003e{const e=t.filter(t=\u003e\"pcb_port\"===t.type),n=t.filter(t=\u003e\"pcb_smtpad\"===t.type),o=t.filter(t=\u003e\"pcb_trace\"===t.type);function i(t,o={}){const i=o.traceWidth||0,r=e.find(e=\u003ezO(e.x,e.y,t.x,t.y)\u003c.01);if(r)return r.pcb_port_id;if(o.isFirstOrLastPoint){const e=n.find(e=\u003e\"rect\"===e.shape?Math.abs(t.x-e.x)\u003ce.width/2+i/2\u0026\u0026Math.abs(t.y-e.y)\u003ce.height/2+i/2:\"circle\"===e.shape?zO(t.x,t.y,e.x,e.y)\u003ce.radius:void 0);if(e)return e.pcb_port_id??null}return null}for(const t of o)for(let e=0;e\u003ct.route.length;e++){const n=t.route[e],o=0===e||e===t.route.length-1;if(\"wire\"===n.route_type){if(!n.start_pcb_port_id\u0026\u00260===e){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.start_pcb_port_id=t)}if(!n.end_pcb_port_id\u0026\u0026e===t.route.length-1){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.end_pcb_port_id=t)}}}})(t),e??=v_(t);const i=vM(t).pcb_trace.list().flatMap(t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];\"wire\"===o.route_type\u0026\u0026(\"wire\"===i.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({type:\"pcb_trace_segment\",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:\"width\"in o?o.width:\"width\"in i?i.width:jO,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),r=vM(t).pcb_smtpad.list(),s=vM(t).pcb_plated_hole.list(),a=vM(t).pcb_hole.list(),c=vM(t).pcb_via.list(),l=vM(t).pcb_keepout.list(),d=[...i,...r,...s,...a,...c,...l],h=new FO({objects:d,getBounds:ZO}),u=e=\u003eNM(t,e),p=(t,e,n)=\u003en\u003c0?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,m=new Set;for(const t of i){const i=n,r=ZO(t),s=h.getObjectsInBounds(r,i+t.thickness/2);if(t.x1!==t.x2||t.y1!==t.y2)for(const r of s){if(!VO(r).includes(t.layer))continue;if(\"pcb_trace_segment\"===r.type){const i=r;if(t.layer!==i.layer)continue;if(e.areIdsConnected(t.pcb_trace_id,i.pcb_trace_id))continue;const s=Oe({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:i.x1,y:i.y1},{x:i.x2,y:i.y2})-t.thickness/2-i.thickness/2;if(s\u003en-XO)continue;const a=`overlap_${t.pcb_trace_id}_${i.pcb_trace_id}`,c=`overlap_${i.pcb_trace_id}_${t.pcb_trace_id}`;if(m.has(a))continue;if(m.has(c))continue;m.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:p(u(t.pcb_trace_id),u(i.pcb_trace_id),s),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[],center:HO(t,i),pcb_port_ids:JO([t._pcbTrace,i._pcbTrace])});continue}const s=AM(r);if(e.areIdsConnected(t.pcb_trace_id,\"pcb_trace_id\"in r?r.pcb_trace_id:s))continue;if(\"pcb_via\"===r.type||\"pcb_plated_hole\"===r.type\u0026\u0026\"circle\"===r.shape||\"pcb_hole\"===r.type||\"pcb_smtpad\"===r.type\u0026\u0026\"circle\"===r.shape){const e=KO(r),i=De({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:r.x,y:r.y,radius:e})-t.thickness/2;if(i\u003en-XO)continue;const a=`overlap_${t.pcb_trace_id}_${s}`;if(m.has(a))continue;m.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:p(u(t.pcb_trace_id),`${r.type} \"${u(AM(r))}\"`,i),pcb_trace_id:t.pcb_trace_id,center:WO(t,ZO(r)),source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...JO([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}const a=ke({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},ZO(r))-t.thickness/2;if(a+XO\u003ci){const e=`overlap_${t.pcb_trace_id}_${s}`;if(m.has(e))continue;m.add(e),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:p(u(t.pcb_trace_id),`${r.type} \"${u(AM(r))}\"`,a),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:e,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),center:WO(t,ZO(r)),pcb_port_ids:[...JO([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}}}return o}function tk(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function ek(t,e){return tk(t,e)\u003c=XO}function nk(t,{connMap:e,minClearance:n=$O}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];e??=v_(t);const i=[],r=new Set;for(let s=0;s\u003co.length;s++)for(let a=s+1;a\u003co.length;a++){const c=o[s],l=o[a];if(ek(c,l))continue;if(!e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=tk(c,l)-c.outer_diameter/2-l.outer_diameter/2;if(d+XO\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");r.has(h)||(r.add(h),i.push({type:\"pcb_via_clearance_error\",pcb_error_id:`same_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return i}function ok(t,{connMap:e,minClearance:n=YO}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];e??=v_(t);const i=[],r=new Set;for(let s=0;s\u003co.length;s++)for(let a=s+1;a\u003co.length;a++){const c=o[s],l=o[a];if(ek(c,l))continue;if(e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=tk(c,l)-c.outer_diameter/2-l.outer_diameter/2;if(d+XO\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");r.has(h)||(r.add(h),i.push({type:\"pcb_via_clearance_error\",pcb_error_id:`different_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} from different nets are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return i}var ik=t=\u003e({minSpacing:t,minClearance:t}),rk={traceClearance:.1,viaClearance:.1},sk=t=\u003e(t=\u003e\"layer\"in t)(t)?[t.layer]:t.layers;function ak(t,e,n){let o,i=Number.POSITIVE_INFINITY;for(const r of e){const e=n.get(r);if(!e)continue;const s=Math.hypot(e.x-t.x,e.y-t.y);s\u003ci\u0026\u0026(i=s,o=r)}return o??e[0]}function ck(t){const e=[],n=new Set,o=new Set,i=function(t){const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{x:t.x,y:t.y});return e}(t);for(const r of t.obstacles){const t=r.connectedTo,s=t.find(t=\u003et.startsWith(\"pcb_smtpad_\")),a=t.find(t=\u003et.startsWith(\"pcb_plated_hole_\")),c=t.filter(t=\u003et.startsWith(\"pcb_port_\")),l=ak(r.center,c,i);if(!s\u0026\u0026!a\u0026\u0026!l)continue;const d=r.layers;if(0===d.length)continue;const h=r.width,u=r.height,p=r.center.x,m=r.center.y,g=r.ccwRotationDegrees,f=\"number\"==typeof g\u0026\u0026Number.isFinite(g);if(d.length\u003e1){const t=a??`pcb_plated_hole_${p.toFixed(3)}_${m.toFixed(3)}`;if(o.has(t))continue;if(o.add(t),f){const n=Math.max(.5*Math.min(h,u),.1);e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"rotated_pill_hole_with_rect_pad\",hole_shape:\"rotated_pill\",pad_shape:\"rect\",hole_width:n,hole_height:n,hole_ccw_rotation:g,rect_pad_width:h,rect_pad_height:u,rect_ccw_rotation:g,hole_offset_x:0,hole_offset_y:0,x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}if(Math.abs(h-u)\u003c.001){e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circle\",outer_diameter:Math.max(h,u),hole_diameter:Math.max(.5*Math.min(h,u),.1),x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circular_hole_with_rect_pad\",hole_shape:\"circle\",hole_diameter:Math.max(.5*Math.min(h,u),.1),rect_pad_width:h,rect_pad_height:u,hole_offset_x:0,hole_offset_y:0,x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}const y=s??`pcb_smtpad_${p.toFixed(3)}_${m.toFixed(3)}`;n.has(y)||(n.add(y),f?e.push({type:\"pcb_smtpad\",pcb_smtpad_id:y,layer:d[0],shape:\"rotated_rect\",x:p,y:m,width:h,height:u,ccw_rotation:g,...l?{pcb_port_id:l}:{}}):e.push({type:\"pcb_smtpad\",pcb_smtpad_id:y,layer:d[0],shape:\"rect\",width:h,height:u,x:p,y:m,...l?{pcb_port_id:l}:{}}))}return e}function lk(t,e,n=.1,o=t.minViaDiameter??.3){const i=[];i.push(...function(t,e){const n=[];return t.connections.forEach(o=\u003e{const i=o.pointsToConnect.filter(t=\u003et.pcb_port_id).map(t=\u003et.pcb_port_id).filter(Boolean),r=o.netConnectionName||o.rootConnectionName||o.name,s=[],a=e.find(t=\u003e(t.connection_name??t.connectionName)===o.name);if(a){const e=t=\u003e\"route_type\"in t\u0026\u0026\"jumper\"===t.route_type?t.start:\"x\"in t\u0026\u0026\"y\"in t?{x:t.x,y:t.y}:{x:0,y:0},n=[e(a.route[0]),e(a.route[a.route.length-1])];for(const e of n)for(const n of t.obstacles)Be(e,n)\u003c=0\u0026\u0026s.push(n)}const c=n.find(t=\u003e\"source_trace\"===t.type\u0026\u0026t.source_trace_id===r);if(c){const t=c;t.connected_source_port_ids=[...new Set([...t.connected_source_port_ids,...i])]}else n.push({type:\"source_trace\",source_trace_id:r,connected_source_port_ids:i.concat(s.flatMap(t=\u003e[`obstacle_${t.center.x.toFixed(3)}_${t.center.y.toFixed(3)}_${t.layers.join(\".\")}`,...t.connectedTo])),connected_source_net_ids:[]})}),n}(t,e)),i.push(...function(t){const e=new Map;return t.connections.forEach(t=\u003e{t.pointsToConnect.forEach(t=\u003e{t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{type:\"pcb_port\",pcb_port_id:t.pcb_port_id,source_port_id:t.pcb_port_id,x:t.x,y:t.y,layers:sk(t)})})}),Array.from(e.values())}(t)),i.push(...ck(t)),i.push(...function(t,e,n=.3){const o=[],i=new Set;return t.length\u003e0\u0026\u0026(\"type\"in t[0]\u0026\u0026\"pcb_trace\"===t[0].type?t.forEach(t=\u003e{t.route.forEach(r=\u003e{if(\"via\"===r.route_type){const s=r.via_diameter??n,a=`${r.x},${r.y},${r.from_layer},${r.to_layer}`;i.has(a)||(o.push({type:\"pcb_via\",pcb_via_id:`via_${o.length}`,pcb_trace_id:t.pcb_trace_id,x:r.x,y:r.y,outer_diameter:s,hole_diameter:.5*s,layers:Wy(r,e)}),i.add(a))}})}):t.forEach((t,r)=\u003e{const s=`trace_${r}`,a=t.viaDiameter??n;for(let n=1;n\u003ct.route.length;n++){const r=t.route[n-1],c=t.route[n];if(r.z!==c.z\u0026\u0026Math.abs(r.x-c.x)\u003c.01\u0026\u0026Math.abs(r.y-c.y)\u003c.01){const t=Vy(r.z,e),n=Vy(c.z,e),l=`${c.x},${c.y},${t},${n}`;i.has(l)||(o.push({type:\"pcb_via\",pcb_via_id:`via_${o.length}`,pcb_trace_id:s,x:c.x,y:c.y,outer_diameter:a,hole_diameter:.5*a,layers:Wy({from_layer:t,to_layer:n},e)}),i.add(l))}}})),o}(e,t.layerCount,o));const r=new Map;return t.connections.forEach(t=\u003e{r.set(t.name,t.netConnectionName||t.rootConnectionName||t.name)}),e.length\u003e0\u0026\u0026(\"type\"in e[0]\u0026\u0026\"pcb_trace\"===e[0].type?e.forEach(t=\u003e{const e=t.connection_name;i.push(function(t,e){return{type:\"pcb_trace\",pcb_trace_id:t.pcb_trace_id,source_trace_id:e,route:t.route.map(t=\u003e\"wire\"===t.route_type?{route_type:\"wire\",x:t.x,y:t.y,width:t.width,layer:t.layer,start_pcb_port_id:t.start_pcb_port_id,end_pcb_port_id:t.end_pcb_port_id}:\"via\"===t.route_type?{route_type:\"via\",x:t.x,y:t.y,from_layer:t.from_layer,to_layer:t.to_layer}:null).filter(t=\u003enull!==t)}}(t,r.get(e)||e))}):e.forEach((e,o)=\u003e{const s=e.connectionName,a=function(t,e,n,o=.1,i){const r=[];if(!t.jumpers||0===t.jumpers.length)return[{type:\"pcb_trace\",pcb_trace_id:e,source_trace_id:n,route:t.route.map((e,n)=\u003e{const r=0===n,s=n===t.route.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:o,layer:Vy(e.z,i),...r\u0026\u0026e.pcb_port_id?{start_pcb_port_id:e.pcb_port_id}:{},...s\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})}];const s=[];for(const e of t.jumpers){let n=-1,o=-1;for(let i=0;i\u003ct.route.length;i++){const r=t.route[i];Math.abs(r.x-e.start.x)\u003c.01\u0026\u0026Math.abs(r.y-e.start.y)\u003c.01\u0026\u0026(n=i),Math.abs(r.x-e.end.x)\u003c.01\u0026\u0026Math.abs(r.y-e.end.y)\u003c.01\u0026\u0026(o=i)}-1!==n\u0026\u0026-1!==o\u0026\u0026(n\u003eo\u0026\u0026([n,o]=[o,n]),s.push({startIdx:n,endIdx:o}))}s.sort((t,e)=\u003et.startIdx-e.startIdx);let a=0,c=0;for(const{startIdx:l,endIdx:d}of s){if(l\u003e=a){const s=t.route.slice(a,l+1);s.length\u003e0\u0026\u0026(r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((t,e)=\u003e{const n=0===e\u0026\u00260===a;return{route_type:\"wire\",x:t.x,y:t.y,width:o,layer:Vy(t.z,i),...n\u0026\u0026t.pcb_port_id?{start_pcb_port_id:t.pcb_port_id}:{}}})}),c++)}a=d}if(a\u003ct.route.length){const s=t.route.slice(a);if(s.length\u003e0){const t=!0;r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((e,n)=\u003e{const r=t\u0026\u0026n===s.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:o,layer:Vy(e.z,i),...r\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})})}}return r}(e,`trace_${o}`,r.get(s)||s,n,t.layerCount);i.push(...a)})),i}var dk=t=\u003et.rootConnectionName??t.connectionName,hk=(t,e)=\u003e{if(t\u0026\u0026e)return t.getNetConnectedToId(e)},uk=(t,e,n)=\u003e{if(!e)return!1;if(t===e)return!0;if(n?.areIdsConnected(t,e))return!0;const o=hk(n,t),i=hk(n,e);return!(!o||o!==e\u0026\u0026o!==i)||!(!i||i!==t\u0026\u0026i!==o)},pk=(t,e,n)=\u003ee.connectedTo?.some(e=\u003euk(t,e,n))??!1,mk=(t,e,n)=\u003eMath.max(e,Math.min(t,n)),gk=(t,e)=\u003e{t.x=mk(t.x,e.minX,e.maxX),t.y=mk(t.y,e.minY,e.maxY)},fk=(t,e)=\u003e({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),yk=(t,e)=\u003e({minCellX:Math.floor(t.minX/e),maxCellX:Math.floor(t.maxX/e),minCellY:Math.floor(t.minY/e),maxCellY:Math.floor(t.maxY/e)}),_k=(t,e)=\u003e`${t}:${e}`,bk=(t,e,n)=\u003e{const o=new Map;for(let i=0;i\u003ct.length;i+=1){const r=t[i];if(!r)continue;const s=yk(e(r),n);for(let t=s.minCellX;t\u003c=s.maxCellX;t+=1)for(let e=s.minCellY;e\u003c=s.maxCellY;e+=1){const n=_k(t,e),r=o.get(n);r?r.push(i):o.set(n,[i])}}return o},xk=(t,e,n)=\u003e{const o=new Set,i=yk(e,n);for(let e=i.minCellX;e\u003c=i.maxCellX;e+=1)for(let n=i.minCellY;n\u003c=i.maxCellY;n+=1){const i=t.get(_k(e,n));if(i)for(const t of i)o.add(t)}return[...o].sort((t,e)=\u003et-e)},vk=1e-6,Sk=(t,e,n)=\u003e{if(0===t.length)return[];const o=n?.traceThickness??.1,i=t[0],r=t.at(-1),s=t=\u003e{if(t.pcb_port_id)return t.pcb_port_id;const o=Vy(t.z,e);return n?.connectionPoints?.find(e=\u003e{return e.pcb_port_id\u0026\u0026(n=e,i=t,Math.abs(n.x-i.x)\u003c=vk\u0026\u0026Math.abs(n.y-i.y)\u003c=vk)\u0026\u0026sk(e).includes(o);var n,i})?.pcb_port_id},a=s(i),c=s(r),l=[{route_type:\"wire\",x:i.x,y:i.y,width:o,layer:Vy(i.z,e),...a?{start_pcb_port_id:a}:{},...1===t.length\u0026\u0026c?{end_pcb_port_id:c}:{}}];for(let i=1;i\u003ct.length;i+=1){const r=t[i-1],s=t[i];r\u0026\u0026s\u0026\u0026(r.z!==s.z\u0026\u0026r.x===s.x\u0026\u0026r.y===s.y\u0026\u0026l.push({route_type:\"via\",x:s.x,y:s.y,from_layer:Vy(r.z,e),to_layer:Vy(s.z,e),...n?.viaDiameter?{via_diameter:n.viaDiameter}:{}}),l.push({route_type:\"wire\",x:s.x,y:s.y,width:o,layer:Vy(s.z,e),...i===t.length-1\u0026\u0026c?{end_pcb_port_id:c}:{}}))}return l},Ik=(t,e)=\u003e({x:Ae(t.x,e.minX,e.maxX),y:Ae(t.y,e.minY,e.maxY)}),Ck=(t,e)=\u003e{const n=t.x-e.center.x,o=t.y-e.center.y;return e.circular?Math.max(0,Math.hypot(n,o)-e.halfWidth):je(R(e.worldToLocal,t),{minX:-e.halfWidth,maxX:e.halfWidth,minY:-e.halfHeight,maxY:e.halfHeight})},Pk=(t,e)=\u003e({kind:\"line\",start:t,end:e,bounds:We([t,e])}),Mk=(t,e)=\u003e({kind:\"circle\",center:t,radius:e,bounds:Ve({center:t,width:2*e,height:2*e})}),Nk=t=\u003e{const e=t.clearance+h_;if(t.circular)return[Mk(t.center,t.halfWidth+e)];const n=(e,n)=\u003eR(t.localToWorld,{x:e,y:n}),{halfWidth:o,halfHeight:i}=t;return[Pk(n(-o,-i-e),n(o,-i-e)),Pk(n(o+e,-i),n(o+e,i)),Pk(n(o,i+e),n(-o,i+e)),Pk(n(-o-e,i),n(-o-e,-i)),Mk(n(-o,-i),e),Mk(n(o,-i),e),Mk(n(o,i),e),Mk(n(-o,i),e)]},wk=(t,e)=\u003e{if(\"circle\"===e.kind){const n=t.x-e.center.x,o=t.y-e.center.y,i=Math.hypot(n,o);return 0===i?[{x:e.center.x+e.radius,y:e.center.y},{x:e.center.x-e.radius,y:e.center.y},{x:e.center.x,y:e.center.y+e.radius},{x:e.center.x,y:e.center.y-e.radius}]:[{x:e.center.x+n*e.radius/i,y:e.center.y+o*e.radius/i}]}return[e.start,e.end,ze(t,e.start,e.end)]},Tk=(t,e)=\u003e{const n=t.end.x-t.start.x,o=t.end.y-t.start.y,i=t.start.x-e.center.x,r=t.start.y-e.center.y,s=n*n+o*o;if(0===s)return[];const a=2*(i*n+r*o),c=a*a-4*s*(i*i+r*r-e.radius*e.radius);if(c\u003c0)return[];const l=Math.sqrt(c);return[(-a-l)/(2*s),(-a+l)/(2*s)].filter(t=\u003et\u003e=0\u0026\u0026t\u003c=1).map(e=\u003e({x:t.start.x+n*e,y:t.start.y+o*e}))},Rk=(t,e)=\u003e{if(\"line\"===t.kind\u0026\u0026\"circle\"===e.kind)return Tk(t,e);if(\"circle\"===t.kind\u0026\u0026\"line\"===e.kind)return Tk(e,t);if(\"line\"===t.kind\u0026\u0026\"line\"===e.kind){const n=ve(t.start,t.end,e.start,e.end);return n?[n]:[]}if(\"circle\"!==t.kind||\"circle\"!==e.kind)return[];const n=e.center.x-t.center.x,o=e.center.y-t.center.y,i=Math.hypot(n,o);if(0===i||i\u003et.radius+e.radius||i\u003cMath.abs(t.radius-e.radius))return[];const r=(t.radius**2-e.radius**2+i**2)/(2*i),s=Math.sqrt(Math.max(0,t.radius**2-r**2)),a=t.center.x+n*r/i,c=t.center.y+o*r/i;return[{x:a-o*s/i,y:c+n*s/i},{x:a+o*s/i,y:c-n*s/i}]},Ek=(t,e,n,o,i)=\u003e{const r=new Set(function(t,e,n=1){if(0===n)throw new Error(\"step cannot be 0\");let o,i;void 0===e?(o=0,i=t):(o=t,i=e);const r=[];if(n\u003e0)for(let t=o;t\u003ci;t+=n)r.push(t);else for(let t=o;t\u003ei;t+=n)r.push(t);return r}(Math.min(...o),Math.max(...o)+1).map(e=\u003eVy(e,t.layerCount)));return t.obstacles.filter(t=\u003e!t.isCopperPour\u0026\u0026t.layers.some(t=\u003er.has(t))).map(o=\u003e{const r=\"number\"==typeof o.ccwRotationDegrees\u0026\u0026Number.isFinite(o.ccwRotationDegrees),s=!r\u0026\u0026o.layers.length\u003e1\u0026\u0026Math.abs(o.width-o.height)\u003c.001,a=D(k(o.center.x,o.center.y),j(r?o.ccwRotationDegrees:0)),c=s?Math.max(o.width,o.height)/2:o.width/2,l=s?c:o.height/2,d=pk(dk(e),o,i)||pk(e.connectionName,o,i),h=n+(d?0:y_(t)),u=We(E(a,[{x:-c,y:-l},{x:c,y:-l},{x:c,y:l},{x:-c,y:l}])),p=h+h_;return{center:o.center,halfWidth:c,halfHeight:l,localToWorld:a,worldToLocal:A(a),circular:s,clearance:h,bounds:{minX:u.minX-p,maxX:u.maxX+p,minY:u.minY-p,maxY:u.maxY+p}}})},Ak=(t,e,n,o)=\u003e{const i=Math.min(...t.zLayers),r=Math.max(...t.zLayers),s=e.filter(e=\u003ee.z\u003e=i\u0026\u0026e.z\u003c=r\u0026\u0026!uk(t.rootConnectionName,e.rootConnectionName,o)).map(e=\u003e({segment:e,required:t.radius+e.radius+n})).filter(({segment:e,required:n})=\u003ebe(t,e.start,e.end)\u003c=n+p_),a=s.flatMap(({segment:t,required:e})=\u003e{const{start:n,end:o}=t,i=Math.sqrt(Ye(n,o));if(i\u003c=h_)return[];const r=e+h_,s=(o.y-n.y)/i*r,a=(n.x-o.x)/i*r;return[Pk({x:n.x+s,y:n.y+a},{x:o.x+s,y:o.y+a}),Pk({x:n.x-s,y:n.y-a},{x:o.x-s,y:o.y-a}),Mk(n,r),Mk(o,r)]}).filter(e=\u003eje(t,e.bounds)\u003c=p_),c=[],l=e=\u003e{Ye(e,t)\u003ep_**2||c.some(t=\u003eYe(t,e)\u003c1e-12)||s.some(({segment:t,required:n})=\u003ebe(e,t.start,t.end)\u003cn)||c.push(e)};l(t);for(let e=0;e\u003ca.length;e+=1){const n=a[e];for(const e of wk(t,n))l(e);for(let t=e+1;t\u003ca.length;t+=1){const e=a[t];if(Xe(n.bounds,e.bounds))for(const t of Rk(n,e))l(t)}}return c.sort((e,n)=\u003eYe(e,t)-Ye(n,t))},Ok=t=\u003e({...t,route:t.route.map(t=\u003e({...t})),vias:t.vias.map(t=\u003e({...t}))}),kk=t=\u003et.map(Ok),Lk=(t,e)=\u003e{const n=new Set(e);return t.map((t,e)=\u003en.has(e)?Ok(t):t)},Dk=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=u_\u0026\u0026Math.abs(t.y-e.y)\u003c=u_,zk=[\"pcb_smtpad\",\"pcb_plated_hole\",\"pcb_hole\",\"pcb_keepout\"],Fk=t=\u003e\"string\"==typeof t.type?t.type:\"string\"==typeof t.error_type?t.error_type:void 0,Bk=t=\u003e{if(\"pcb_pad_trace_clearance_error\"===Fk(t))return!0;const e=\"string\"==typeof t.message?t.message.toLowerCase():\"\";return(e.includes(\"pcb_trace\")||e.includes(\"pcb trace\"))\u0026\u0026zk.some(t=\u003ee.includes(t))},jk=t=\u003e{const e=\"string\"==typeof t.message?t.message:\"\",n=e.match(/gap: (-?\\d+(?:\\.\\d+)?)mm/),o=e.match(/required: (-?\\d+(?:\\.\\d+)?)mm/);if(n\u0026\u0026o){const t=Number.parseFloat(n[1]),e=Number.parseFloat(o[1]);if(Number.isFinite(t)\u0026\u0026Number.isFinite(e))return Math.max(0,e-t)}if(n){const t=Number.parseFloat(n[1]),e=rk.traceClearance??.1;if(Number.isFinite(t))return Math.max(0,e-t)}return 1},$k={projectEngineError:t=\u003e({...t,center:\"object\"==typeof t.first_contact_center?t.first_contact_center:t.center,message:\"string\"==typeof t.first_contact_message?t.first_contact_message:t.message,actual_clearance:\"number\"==typeof t.first_actual_clearance?t.first_actual_clearance:t.actual_clearance}),getErrorSeverity:jk},Yk={projectEngineError:t=\u003et,getErrorSeverity:t=\u003e{const e=Number(t.minimum_clearance),n=Number(t.worst_actual_clearance);return Number.isFinite(e)\u0026\u0026Number.isFinite(n)?Math.max(0,e-n):jk(t)}},Xk=(t,e=jk)=\u003et.reduce((t,n)=\u003et+e(n),0),Vk=(t,e,n,o,i,r=$k)=\u003e{const s=i\u0026\u0026!n?t:((t,e)=\u003ee?{...t,connections:t.connections.map(t=\u003e{const n=hk(e,t.name)??hk(e,t.rootConnectionName)??t.netConnectionName;return n?{...t,netConnectionName:n}:t}),obstacles:t.obstacles.map(t=\u003e{const n=new Set(t.connectedTo);for(const o of t.connectedTo){const t=hk(e,o);t\u0026\u0026n.add(t)}return{...t,connectedTo:[...n]}})}:t)(t,o),{traces:a,traceRouteIndexById:c}=((t,e)=\u003e{const n=[],o=new Map,i=new Map;for(let t=0;t\u003ce.length;t+=1){const n=e[t];if(!n)continue;const o=i.get(n.connectionName);o?o.push({route:n,routeIndex:t}):i.set(n.connectionName,[{route:n,routeIndex:t}])}for(const e of t.connections){const r=i.get(e.name)??[];for(let i=0;i\u003cr.length;i+=1){const s=r[i];if(!s)continue;const a=`${e.name}_${i}`;n.push({type:\"pcb_trace\",pcb_trace_id:a,connection_name:e.netConnectionName??e.rootConnectionName??e.name,route:Sk(s.route.route,t.layerCount,{traceThickness:s.route.traceThickness??e.nominalTraceWidth??t.nominalTraceWidth??t.minTraceWidth,viaDiameter:s.route.viaDiameter??t.minViaDiameter,connectionPoints:e.pointsToConnect})}),o.set(a,s.routeIndex)}}return{traces:n,traceRouteIndexById:o}})(s,e),l=n?.({srj:s,routes:e,traces:a});if(l){const t=Array.isArray(l)?l:l.errors,e=Array.isArray(l)?l:l.errorsWithCenters??l.errors;return{errors:e,count:t.length,issueScore:Xk(e,r.getErrorSeverity),legacyIssueScore:Xk(e.filter(t=\u003e!uD(t)),r.getErrorSeverity),traceRouteIndexById:c}}const d=i?.evaluate(a)??((t,e={})=\u003e{const n=Math.max(e.viaClearance??.1,.1),o=[...QO(t,ik(e.traceClearance)),...nk(t,ik(n)),...ok(t,ik(n))],i=t.filter(t=\u003e\"pcb_via\"===t.type),r=new Map(i.map(t=\u003e[t.pcb_via_id,t])),s=o.map(t=\u003e{if(\"center\"in t\u0026\u0026t.center)return t;if(\"pcb_center\"in t\u0026\u0026t.pcb_center)return{...t,center:t.pcb_center};if(\"pcb_via_ids\"in t\u0026\u0026Array.isArray(t.pcb_via_ids)){const[e,n]=t.pcb_via_ids;if(\"string\"!=typeof e||\"string\"!=typeof n)return t;const o=r.get(e),i=r.get(n);if(o\u0026\u0026i)return{...t,center:{x:(o.x+i.x)/2,y:(o.y+i.y)/2}}}if(\"pcb_error_id\"in t\u0026\u0026\"string\"==typeof t.pcb_error_id\u0026\u0026(t.pcb_error_id.startsWith(\"same_net_vias_close_\")||t.pcb_error_id.startsWith(\"different_net_vias_close_\"))){const e=t.pcb_error_id.replace(\"same_net_vias_close_\",\"\").replace(\"different_net_vias_close_\",\"\").split(\"_\").filter(Boolean);if(2===e.length){const n=e[0],o=e[1];if(!n||!o)return t;const i=r.get(n),s=r.get(o);if(i\u0026\u0026s)return{...t,center:{x:(i.x+s.x)/2,y:(i.y+s.y)/2}}}}return t}),a=s.filter(t=\u003eBoolean(t.center));return{errors:o,errorsWithCenters:s,locationAwareErrors:a}})(lk(s,a,s.minTraceWidth,s.minViaDiameter),{...rk,traceClearance:s.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:s.minTraceToPadEdgeClearance??rk.viaClearance}),h=d.errors,u=(d.errorsWithCenters.length\u003e0?d.errorsWithCenters:d.errors).map(t=\u003er.projectEngineError(t));return{errors:u,count:h.length,issueScore:Xk(u,r.getErrorSeverity),legacyIssueScore:Xk(u.filter(t=\u003e!uD(t)),r.getErrorSeverity),traceRouteIndexById:c}},Wk=(t,e,n,o,i)=\u003eVk(t,e,n,o,i,$k),Hk=(t,e,n,o,i)=\u003eVk(t,e,n,o,i,Yk),Gk=(t,e=.3)=\u003e{const n=[];for(let o=0;o\u003ct.length;o+=1){const i=t[o];if(!i)continue;const r=new Set;for(let t=0;t\u003ci.route.length-1;t+=1){const s=i.route[t],a=i.route[t+1];if(!s||!a)continue;if(s.z===a.z||!Dk(s,a))continue;const c=[t,t+1];for(let e=t-1;e\u003e=0;e-=1){const t=i.route[e];if(!t||!Dk(t,s))break;c.push(e)}for(let e=t+2;e\u003ci.route.length;e+=1){const t=i.route[e];if(!t||!Dk(t,s))break;c.push(e)}const l=[...new Set(c)];if(l.some(t=\u003er.has(t)))continue;for(const t of l)r.add(t);const d=l.filter(t=\u003e0===t||t===i.route.length-1),h=d.some(t=\u003eBoolean(i.route[t]?.pcb_port_id));n.push({routeIndex:o,rootConnectionName:dk(i),pointIndexes:l,zLayers:[...new Set(l.map(t=\u003ei.route[t].z))],x:s.x,y:s.y,radius:(i.viaDiameter??e)/2,movable:0===d.length,canCanonicalize:0===d.length||!h})}}return n},Uk=(t,e)=\u003e{const n=[];for(let o=0;o\u003ct.route.length-1;o+=1){const i=t.route[o],r=t.route[o+1];i\u0026\u0026r\u0026\u0026(i.z!==r.z||Dk(i,r)||n.push({routeIndex:e,rootConnectionName:dk(t),startIndex:o,endIndex:o+1,start:i,end:r,z:i.z,radius:(t.traceThickness??.1)/2}))}return n},Zk=t=\u003et.flatMap((t,e)=\u003eUk(t,e)),qk=t=\u003e({minX:t.x,minY:t.y,maxX:t.x,maxY:t.y}),Jk=t=\u003e({minX:Math.min(t.start.x,t.end.x),minY:Math.min(t.start.y,t.end.y),maxX:Math.max(t.start.x,t.end.x),maxY:Math.max(t.start.y,t.end.y)}),Kk=t=\u003e({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}),Qk=(t,e)=\u003e{if(t.zLayers\u0026\u0026t.zLayers.length\u003e0)return t.zLayers;const n=Array.from({length:e},(t,e)=\u003ee).filter(n=\u003et.layers.includes(Vy(n,e)));return n.length\u003e0?n:Array.from({length:e},(t,e)=\u003ee)},tL=(t,e,n)=\u003e{const o=e.reduce((t,e)=\u003eMath.max(t,e.radius),(t.minViaDiameter??.3)/2),i=n.reduce((t,e)=\u003eMath.max(t,e.radius),t.minTraceWidth/2),r=(rk.traceClearance??.1)+g_;return Math.max(2*o+.2+g_,o+i+r,2*i+r,i+f_(t)+g_,o+y_(t)+g_)},eL=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c=h_)return{x:e.x,y:e.y,t:0};const s=mk(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return{x:e.x+o*s,y:e.y+i*s,t:s}},nL=(t,e)=\u003eeL(t,e.start,e.end),oL=(t,e)=\u003e{const n=e.width/2,o=e.height/2,i=Math.max(Math.abs(t.x-e.center.x)-n,0),r=Math.max(Math.abs(t.y-e.center.y)-o,0);return Math.hypot(i,r)},iL=(t,e)=\u003et.x\u003e=e.center.x-e.width/2-u_\u0026\u0026t.x\u003c=e.center.x+e.width/2+u_\u0026\u0026t.y\u003e=e.center.y-e.height/2-u_\u0026\u0026t.y\u003c=e.center.y+e.height/2+u_,rL=(t,e,n,o)=\u003et.obstacles.find(i=\u003epk(dk(e),i,o)\u0026\u0026Qk(i,t.layerCount).includes(n.z)\u0026\u0026iL(n,i)),sL=(t,e,n=.6,o)=\u003e{let i;for(const r of t.obstacles){if(o\u0026\u0026!o(r))continue;const t=oL(e,r);t\u003en||(!i||t\u003ci.distance)\u0026\u0026(i={obstacle:r,distance:t})}return i?.obstacle},aL=(t,e,n)=\u003e{const o=e.width/2,i=e.height/2,r=mk(t.x,e.center.x-o,e.center.x+o),s=mk(t.y,e.center.y-i,e.center.y+i);let a=t.x-r,c=t.y-s,l=Math.hypot(a,c);if(l\u003c=h_){o-Math.abs(t.x-e.center.x)\u003ci-Math.abs(t.y-e.center.y)?(a=t.x\u003e=e.center.x?1:-1,c=0,l=0):(a=0,c=t.y\u003e=e.center.y?1:-1,l=0)}const d=n-l;if(d\u003c=0)return;const h=Math.hypot(a,c);return{direction:{x:h\u003eh_?a/h:1,y:h\u003eh_?c/h:0},penetration:d}},cL=(t,e,n,o)=\u003e{const i=e.message;if(\"string\"!=typeof i||!i.includes(\"pcb_\"))return n;const r=Array.isArray(e.pcb_pad_ids)?e.pcb_pad_ids.filter(t=\u003e\"string\"==typeof t):[],s=t.obstacles.find(t=\u003er.some(e=\u003et.connectedTo.includes(e))\u0026\u0026(o?.(t)??!0));return s?s.center:sL(t,n,.6,o)?.center??n},lL=(t,e)=\u003e{const n=t.route[e];if(!n)return[];const o=[e];for(let i=e-1;i\u003e=0;i-=1){const e=t.route[i];if(!e||!Dk(e,n))break;o.push(i)}for(let i=e+1;i\u003ct.route.length;i+=1){const e=t.route[i];if(!e||!Dk(e,n))break;o.push(i)}return[...new Set(o)]},dL=(t,e)=\u003e{if(e\u003c=0||e\u003e=t.route.length-1)return;const n=lL(t,e);return n.includes(0)||n.includes(t.route.length-1)?void 0:n},hL=(t,e)=\u003et.x\u003e=e.minX-u_\u0026\u0026t.x\u003c=e.maxX+u_\u0026\u0026t.y\u003e=e.minY-u_\u0026\u0026t.y\u003c=e.maxY+u_,uL=(t,e)=\u003eMath.min(t.x-e.minX,e.maxX-t.x,t.y-e.minY,e.maxY-t.y),pL=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=t.x-e.x,s=o*(t.y-e.y)-i*r;if(Math.abs(s)\u003eu_)return!1;const a=Math.min(e.x,n.x)-u_,c=Math.max(e.x,n.x)+u_,l=Math.min(e.y,n.y)-u_,d=Math.max(e.y,n.y)+u_;return t.x\u003e=a\u0026\u0026t.x\u003c=c\u0026\u0026t.y\u003e=l\u0026\u0026t.y\u003c=d},mL=(t,e)=\u003e{if(e.length\u003c3)return!0;for(let n=0;n\u003ce.length;n+=1){const o=e[n],i=e[(n+1)%e.length];if(o\u0026\u0026i\u0026\u0026pL(t,o,i))return!0}let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o,o+=1){const r=e[o],s=e[i];if(!r||!s)continue;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n},gL=(t,e)=\u003e{const n=Math.hypot(t,e);if(!(n\u003c=h_))return{x:t/n,y:e/n}},fL=(t,e)=\u003et.outline\u0026\u0026t.outline.length\u003e=3?((t,e)=\u003e{const n=mL(t,e);let o;for(let n=0;n\u003ce.length;n+=1){const i=e[n],r=e[(n+1)%e.length];if(!i||!r)continue;const s=eL(t,i,r),a=Math.hypot(t.x-s.x,t.y-s.y);(!o||a\u003co.distance)\u0026\u0026(o={projection:s,start:i,end:r,distance:a})}if(!o)return;const i=gL(n?t.x-o.projection.x:o.projection.x-t.x,n?t.y-o.projection.y:o.projection.y-t.y);if(i)return i;const r=o.end.x-o.start.x,s=o.end.y-o.start.y,a=Math.hypot(r,s);if(a\u003c=h_)return;const c=(t=\u003e{let e=0;for(let n=0;n\u003ct.length;n+=1){const o=t[n],i=t[(n+1)%t.length];o\u0026\u0026i\u0026\u0026(e+=o.x*i.y-i.x*o.y)}return e/2})(e)\u003e=0;return{x:c?-s/a:s/a,y:c?r/a:-r/a}})(e,t.outline):((t,e)=\u003e{const n=t.x-e.minX,o=e.maxX-t.x,i=t.y-e.minY,r=e.maxY-t.y,s=Math.min(n,o,i,r);let a=0,c=0;return n\u003c=s+u_\u0026\u0026(a+=1),o\u003c=s+u_\u0026\u0026(a-=1),i\u003c=s+u_\u0026\u0026(c+=1),r\u003c=s+u_\u0026\u0026(c-=1),gL(a,c)})(e,t.bounds),yL=(t,e)=\u003et.outline\u0026\u0026t.outline.length\u003e=3?mL(e,t.outline):hL(e,t.bounds),_L=(t,e)=\u003e{if(t.outline\u0026\u0026t.outline.length\u003e=3){const n=((t,e)=\u003e{let n=Number.POSITIVE_INFINITY;for(let o=0;o\u003ce.length;o+=1){const i=e[o],r=e[(o+1)%e.length];i\u0026\u0026r\u0026\u0026(n=Math.min(n,be(t,i,r)))}return n})(e,t.outline);return mL(e,t.outline)?n:-n}return uL(e,t.bounds)},bL=(t,e,n)=\u003e{if(Math.abs(e.x-n.x)\u003c=u_\u0026\u0026Math.abs(e.y-n.y)\u003c=u_)return Math.min(_L(t,e),_L(t,n));if(t.outline\u0026\u0026t.outline.length\u003e=3){if(!mL(e,t.outline)||!mL(n,t.outline))return Math.min(_L(t,e),_L(t,n));let o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ct.outline.length;i+=1){const r=t.outline[i],s=t.outline[(i+1)%t.outline.length];r\u0026\u0026s\u0026\u0026(o=Math.min(o,Oe(e,n,r,s)))}return o}return hL(e,t.bounds)\u0026\u0026hL(n,t.bounds)?Math.min(uL(e,t.bounds),uL(n,t.bounds)):Math.min(_L(t,e),_L(t,n))},xL=(t,e)=\u003ee+Math.max(.16,t.defaultObstacleMargin??0,rk.traceClearance??.1),vL=(t,e,n)=\u003ee\u003ct-u_\u0026\u0026Math.min(t,e)\u003c=n+u_,SL=(t,e,n,o,i)=\u003e{const r=t*n.x+e*n.y,s=-Math.max(0,o-i);if(r\u003e=s-u_)return{x:t,y:e};const a=s-r;return{x:t+n.x*a,y:e+n.y*a}},IL=(t,e,n,o,i)=\u003e{const r=fL(t,e);return r?SL(n,o,r,_L(t,e),xL(t,i)):{x:n,y:o}},CL=(t,e,n,o)=\u003e{const i=[...new Set(n)].sort((t,e)=\u003et-e);if(0===i.length)return Number.POSITIVE_INFINITY;const r=new Set(i),s=t=\u003eo?.get(t)??e.route[t];let a=Number.POSITIVE_INFINITY;for(const e of i){const n=s(e);n\u0026\u0026(a=Math.min(a,_L(t,n)))}for(let n=0;n\u003ce.route.length-1;n+=1){if(!r.has(n)\u0026\u0026!r.has(n+1))continue;const e=s(n),o=s(n+1);e\u0026\u0026o\u0026\u0026(a=Math.min(a,bL(t,e,o)))}return a},PL=(t,e,n,o,i,r)=\u003e{const s=[...new Set(n)].sort((t,e)=\u003et-e);if(0===s.length)return;const a=((t,e,n,o,i,r)=\u003e{const s=[...new Set(n)].sort((t,e)=\u003et-e);let a={x:o,y:i};const c=xL(t,r);for(let n=0;n\u003cMath.max(1,s.length);n+=1){let n=!1;for(const o of s){const i=e.route[o];if(!i)continue;const r=fL(t,i);if(!r)continue;const s=SL(a.x,a.y,r,_L(t,i),c);(Math.abs(s.x-a.x)\u003eh_||Math.abs(s.y-a.y)\u003eh_)\u0026\u0026(a=s,n=!0)}if(!n)break}return a})(t,e,s,o,i,r);if(Math.abs(a.x)\u003c=h_\u0026\u0026Math.abs(a.y)\u003c=h_)return;const c=new Map;for(const t of s){const n=e.route[t];if(!n)continue;const o={x:n.x+a.x,y:n.y+a.y};c.set(t,o)}const l=CL(t,e,s),d=CL(t,e,s,c);if(d\u003cr-u_)return;const h=xL(t,r);return vL(l,d,h)?void 0:a},ML=(t,e,n,o,i,r,s)=\u003e{const a=t[e];if(!a)return!1;const c=dL(a,n);if(!c)return!1;const l=PL(r,a,c,o,i,s);if(!l)return!1;let d=!1;for(const t of c){const e=a.route[t];e\u0026\u0026(e.x+=l.x,e.y+=l.y,gk(e,r.bounds),d=!0)}return d},NL=(t,e,n,o,i,r)=\u003edL(e,n)??((t,e,n,o,i,r)=\u003e{const s=e.route[n];if(!s||s.pcb_port_id||0!==n\u0026\u0026n!==e.route.length-1)return;const a=rL(t,e,s,r);if(!a)return;const c={...s,x:s.x+o,y:s.y+i};return yL(t,c)\u0026\u0026iL(c,a)?lL(e,n):void 0})(t,e,n,o,i,r),wL=(t,e,n,o,i,r)=\u003e{const s=PL(i,t,e,n,o,r);if(!s)return!1;let a=!1;for(const n of e){const e=t.route[n];e\u0026\u0026(e.x+=s.x,e.y+=s.y,gk(e,i.bounds),a=!0)}return a},TL=(t,e,n,o,i,r)=\u003e{const s=e.route[n];if(!s)return!1;if(s.pcb_port_id)return!1;const a=rL(t,e,s,r);return!!a\u0026\u0026iL({...s,x:s.x+o,y:s.y+i},a)},RL=(t,e,n,o)=\u003e{const i=e.route[n];if(i\u0026\u0026!i.pcb_port_id)return rL(t,e,i,o)},EL=(t,e,n,o,i,r,s)=\u003e{const a=t[e];if(!a||0===a.route.length)return!1;const c=((t,e,n,o,i)=\u003e{let r=Number.NEGATIVE_INFINITY,s=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY,c=Number.POSITIVE_INFINITY;for(const n of[0,e.route.length-1]){const o=e.route[n],l=RL(t,e,n,i);if(!o||!l)return;r=Math.max(r,l.center.x-l.width/2-o.x),s=Math.min(s,l.center.x+l.width/2-o.x),a=Math.max(a,l.center.y-l.height/2-o.y),c=Math.min(c,l.center.y+l.height/2-o.y)}if(!(r\u003es||a\u003ec))return{x:mk(n,r,s),y:mk(o,a,c)}})(i,a,n,o,s);if(!c)return!1;const l=a.route.map((t,e)=\u003ee),d=PL(i,a,l,c.x,c.y,r);if(!d)return!1;const h=a.route.length-1;if(!TL(i,a,0,d.x,d.y,s)||!TL(i,a,h,d.x,d.y,s))return!1;let u=!1;for(const t of a.route)t.x+=d.x,t.y+=d.y,gk(t,i.bounds),u=!0;return u},AL=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y,r=n.x-e.x,s=n.y-e.y;return Math.abs(o*s-i*r)\u003c=u_},OL=(t,e)=\u003e{if(t.z!==e.z)return!1;const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=t.x-e.start.x,r=t.y-e.start.y;return Math.abs(n*r-o*i)\u003c=u_},kL=(t,e)=\u003e{const n=((t,e)=\u003e{const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.max(u_,.12*(t.traceThickness??.1)),r=Math.abs(o)\u003c=i,s=Math.abs(n)\u003c=i;let a=e.startIndex,c=e.endIndex;if(r||s){const n=r?(e.start.y+e.end.y)/2:(e.start.x+e.end.x)/2;for(;a\u003e0;){const o=t.route[a-1];if(!o||o.z!==e.z||Math.abs((r?o.y:o.x)-n)\u003ei)break;a-=1}for(;c\u003ct.route.length-1;){const o=t.route[c+1];if(!o||o.z!==e.z||Math.abs((r?o.y:o.x)-n)\u003ei)break;c+=1}return Array.from({length:c-a+1},(t,e)=\u003ea+e)}for(;a\u003e0;){const n=t.route[a-1],o=t.route[a],i=t.route[a+1];if(!(n\u0026\u0026o\u0026\u0026i\u0026\u0026n.z===e.z\u0026\u0026OL(n,e)\u0026\u0026AL(n,o,i)))break;a-=1}for(;c\u003ct.route.length-1;){const n=t.route[c-1],o=t.route[c],i=t.route[c+1];if(!(n\u0026\u0026o\u0026\u0026i\u0026\u0026i.z===e.z\u0026\u0026OL(i,e)\u0026\u0026AL(n,o,i)))break;c+=1}return Array.from({length:c-a+1},(t,e)=\u003ea+e)})(t,e);if(n.length\u003c=2)return;const o=[];for(const e of n){const n=dL(t,e);if(!n)return;o.push(...n)}return[...new Set(o)]},LL=(t,e)=\u003ee\u003e0\u0026\u0026e\u003ct.route.length-1\u0026\u0026!((t,e)=\u003e{const n=t.route[e];if(!n)return!1;const o=t.route[e-1],i=t.route[e+1];return o\u0026\u0026o.z!==n.z\u0026\u0026Dk(o,n)||i\u0026\u0026i.z!==n.z\u0026\u0026Dk(i,n)})(t,e),DL=(t,e,n)=\u003e{const o=t.route[e.startIndex],i=t.route[e.endIndex];return!(!o||!i)\u0026\u0026(o.z===e.z\u0026\u0026i.z===e.z\u0026\u0026(!!((t,e)=\u003eJk(t).maxX\u003e=e.minX-u_\u0026\u0026Jk(t).minX\u003c=e.maxX+u_\u0026\u0026Jk(t).maxY\u003e=e.minY-u_\u0026\u0026Jk(t).minY\u003c=e.maxY+u_)(e,n)\u0026\u0026(LL(t,e.startIndex)||LL(t,e.endIndex))))},zL=(t,e,n,o,i,r,s)=\u003e{const a=t[e.routeIndex];if(!a)return!1;const c=((t,e,n,o)=\u003e{const i=fk(Kk(n),o);let r=e.startIndex,s=e.startIndex;for(;r\u003e0;){const n={...e,startIndex:r-1,endIndex:r,start:t.route[r-1],end:t.route[r]};if(!t.route[r-1]||!DL(t,n,i))break;r-=1}for(;s\u003ct.route.length-2;){const n={...e,startIndex:s+1,endIndex:s+2,start:t.route[s+1],end:t.route[s+2]};if(!t.route[s+2]||!DL(t,n,i))break;s+=1}const a=[];for(let e=r;e\u003c=s+1;e+=1)LL(t,e)\u0026\u0026a.push(e);return[...new Set(a)]})(a,e,n,o);return!(c.length\u003c=2)\u0026\u0026wL(a,c,i,r,s,e.radius)},FL=(t,e)=\u003e{const n=nL(e,t),o=n.x-e.x,i=n.y-e.y,r=Math.hypot(o,i),s=t.end.x-t.start.x,a=t.end.y-t.start.y,c=Math.hypot(s,a),l=t.routeIndex%2==0?1:-1;return{projection:n,direction:r\u003eh_?{x:o/r,y:i/r}:c\u003eh_?{x:-a/c*l,y:s/c*l}:{x:1,y:0}}},BL=(t,e,n,o,i)=\u003e{const r=t[e.routeIndex];if(!r)return!1;const s=IL(i,e,n,o,e.radius);if(Math.abs(s.x)\u003c=h_\u0026\u0026Math.abs(s.y)\u003c=h_)return!1;const a={x:e.x+s.x,y:e.y+s.y},c=_L(i,e),l=_L(i,a);if(l\u003ce.radius-u_)return!1;const d=xL(i,e.radius);if(vL(c,l,d))return!1;e.x+=s.x,e.y+=s.y,gk(e,i.bounds);for(const t of e.pointIndexes){const n=r.route[t];n\u0026\u0026(n.x=e.x,n.y=e.y)}return!0},jL=(t,e)=\u003e{const n=Gk(t),o=n.find(t=\u003et.routeIndex===e.routeIndex\u0026\u0026t.pointIndexes.some(t=\u003ee.pointIndexes.includes(t)));return o?n.filter(t=\u003et.rootConnectionName===o.rootConnectionName\u0026\u0026Math.hypot(t.x-o.x,t.y-o.y)\u003c=u_):[]},$L=(t,e,n,o,i)=\u003ee.movable\u0026\u0026jL(t,e).length\u003c=1\u0026\u0026BL(t,e,n,o,i),YL=(t,e,n,o,i=1)=\u003e{const{projection:r,direction:s}=FL(e,n),a=p_*i,c=1-r.t,l=r.t,d=ML(t,e.routeIndex,e.startIndex,s.x*a*c,s.y*a*c,o,e.radius),h=ML(t,e.routeIndex,e.endIndex,s.x*a*l,s.y*a*l,o,e.radius);return!(!d\u0026\u0026!h)||((t,e,n,o,i)=\u003e{const r=t[e.routeIndex];if(!r)return!1;const{projection:s,direction:a}=FL(e,n),c=IL(o,s,a.x*p_*i,a.y*p_*i,e.radius);if(Math.abs(c.x)\u003c=h_\u0026\u0026Math.abs(c.y)\u003c=h_)return!1;const l={...r.route[e.startIndex],x:s.x+c.x,y:s.y+c.y};if(gk(l,o.bounds),be(l,e.start,e.end)\u003c=u_)return!1;const d=r.route[e.startIndex],h=r.route[e.endIndex];if(!d||!h)return!1;const u=bL(o,d,h),p=Math.min(_L(o,l),bL(o,d,l),bL(o,l,h));if(p\u003ce.radius-u_)return!1;const m=xL(o,e.radius);return!vL(u,p,m)\u0026\u0026(r.route.splice(e.endIndex,0,l),!0)})(t,e,n,o,i)},XL=(t,e,n,o,i,r=1)=\u003e{const s=e.radius+f_(o)+g_,a=nD(e,n,s);if(!a)return!1;const c=Math.min(.3*Math.abs(r),a.penetration+g_),l=a.direction.x*c,d=a.direction.y*c,h=t[e.routeIndex];if(!h)return!1;const u=!(t=\u003e{for(let e=0;e\u003ct.route.length-1;e+=1){const n=t.route[e],o=t.route[e+1];if(n\u0026\u0026o\u0026\u0026n.z!==o.z\u0026\u0026Dk(n,o))return!0}return!1})(h);if(u\u0026\u0026EL(t,e.routeIndex,l,d,o,e.radius,i))return!0;const p=zL(t,e,n,s,l,d,o)||((t,e,n,o,i)=\u003e{const r=t[e.routeIndex];if(!r)return!1;const s=kL(r,e);return!!s\u0026\u0026wL(r,s,n,o,i,e.radius)})(t,e,l,d,o)||((t,e,n,o,i,r)=\u003e{const s=t[e.routeIndex];if(!s)return!1;const a=NL(i,s,e.startIndex,n,o,r),c=NL(i,s,e.endIndex,n,o,r);if(!a||!c)return!1;const l=[...new Set([...a,...c])],d=PL(i,s,l,n,o,e.radius);if(!d)return!1;let h=!1;for(const t of l){const e=s.route[t];e\u0026\u0026(e.x+=d.x,e.y+=d.y,gk(e,i.bounds),h=!0)}return h})(t,e,l,d,o,i);if(p)return!0;if(!u\u0026\u0026EL(t,e.routeIndex,l,d,o,e.radius,i))return!0;const m=n.width/2,g=n.height/2,f=(Math.abs(a.direction.y)\u003e=Math.abs(a.direction.x)?[{...h.route[e.startIndex],x:n.center.x-m-s,y:n.center.y+a.direction.y*(g+s)},{...h.route[e.startIndex],x:n.center.x+m+s,y:n.center.y+a.direction.y*(g+s)}]:[{...h.route[e.startIndex],x:n.center.x+a.direction.x*(m+s),y:n.center.y-g-s},{...h.route[e.startIndex],x:n.center.x+a.direction.x*(m+s),y:n.center.y+g+s}]).map(t=\u003e{const{t:n}=nL(t,e),i={x:e.start.x+(e.end.x-e.start.x)*n,y:e.start.y+(e.end.y-e.start.y)*n},r=IL(o,i,t.x-i.x,t.y-i.y,e.radius);return t.x=i.x+r.x,t.y=i.y+r.y,gk(t,o.bounds),{point:t,t:n,moved:Math.abs(r.x)\u003eh_||Math.abs(r.y)\u003eh_,awayFromObstacleMotion:r.x*a.direction.x+r.y*a.direction.y}}).sort((t,e)=\u003et.t-e.t);if(!f.some(({moved:t})=\u003et))return!1;if(!f.some(({awayFromObstacleMotion:t})=\u003et\u003eu_))return!1;const y=f.map(({point:t})=\u003et);if(y.every(t=\u003ebe(t,e.start,e.end)\u003c=u_))return!1;if(y.some(t=\u003e!yL(o,t)))return!1;const _=h.route[e.startIndex],b=h.route[e.endIndex],x=y[0],v=y[1];if(!(_\u0026\u0026b\u0026\u0026x\u0026\u0026v))return!1;const S=bL(o,_,b),I=Math.min(_L(o,x),_L(o,v),bL(o,_,x),bL(o,x,v),bL(o,v,b));if(I\u003ce.radius-u_)return!1;const C=xL(o,e.radius);return!vL(S,I,C)\u0026\u0026(h.route.splice(e.endIndex,0,...y),!0)},VL=(t,e,n)=\u003e{let o;for(const i of t){if(void 0!==n\u0026\u0026i.routeIndex!==n)continue;const t=nL(e,i),r=Math.hypot(t.x-e.x,t.y-e.y);(!o||r\u003co.distance)\u0026\u0026(o={segment:i,distance:r})}return o?.segment},WL=(t,e,n)=\u003e{let o;for(const i of t){if(void 0!==n\u0026\u0026i.routeIndex!==n)continue;const t=Math.hypot(i.x-e.x,i.y-e.y);(!o||t\u003co.distance)\u0026\u0026(o={via:i,distance:t})}return o?.via},HL=(t,e)=\u003e{const n=t.map(t=\u003e({via:t,distance:Math.hypot(t.x-e.x,t.y-e.y)})).sort((t,e)=\u003et.distance-e.distance).slice(0,2).map(({via:t})=\u003et);return 2===n.length?n:void 0},GL=(t,e,n,o)=\u003e{const i=e.x-n.x,r=e.y-n.y,s=Math.hypot(i,r);return $L(t,e,(s\u003eh_?i/s:1)*p_,(s\u003eh_?r/s:0)*p_,o)},UL=(t,e)=\u003e{const n=nL(t.start,e),o=nL(t.end,e),i=nL(e.start,t),r=nL(e.end,t);return[{leftT:0,rightT:n.t,leftPoint:t.start,rightPoint:n},{leftT:1,rightT:o.t,leftPoint:t.end,rightPoint:o},{leftT:i.t,rightT:0,leftPoint:i,rightPoint:e.start},{leftT:r.t,rightT:1,leftPoint:r,rightPoint:e.end}].sort((t,e)=\u003eMath.hypot(t.leftPoint.x-t.rightPoint.x,t.leftPoint.y-t.rightPoint.y)-Math.hypot(e.leftPoint.x-e.rightPoint.x,e.leftPoint.y-e.rightPoint.y))},ZL=(t,e,n,o,i,r)=\u003e{const s=mk(r,0,1),a=1-s,c=s,l=ML(t,e.routeIndex,e.startIndex,n*a,o*a,i,e.radius),d=ML(t,e.routeIndex,e.endIndex,n*c,o*c,i,e.radius);return l||d},qL=(t,e,n,o,i,r=.035,s=!1)=\u003e{if(!s\u0026\u0026uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const a=e.radius+n.radius+.2+g_,c=e.x-n.x,l=e.y-n.y,d=Math.hypot(c,l),h=a-d;if(h\u003c=0)return!1;const u=1.618*(97*e.routeIndex+13*n.routeIndex),p=d\u003eh_?c/d:Math.cos(u),m=d\u003eh_?l/d:Math.sin(u),g=Number(e.movable)+Number(n.movable);if(0===g)return!1;const f=Math.min(r,h/g),y=$L(t,e,p*f,m*f,o),_=$L(t,n,-p*f,-m*f,o);return y||_},JL=(t,e,n,o,i)=\u003e{if(!uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const[r,s]=e.canCanonicalize?n.canCanonicalize\u0026\u0026e.routeIndex\u003c=n.routeIndex?[e,n]:[n,e]:[e,n];return((t,e,n,o)=\u003e{if(!n.canCanonicalize)return!1;const i=e.x-n.x,r=e.y-n.y;if(!n.movable\u0026\u0026Math.hypot(i,r)\u003en.radius+u_)return!1;const s=t[n.routeIndex];if(!s)return!1;const a={x:n.x,y:n.y},c=n.pointIndexes.map(t=\u003e{const e=s.route[t];return e?{pointIndex:t,x:e.x,y:e.y}:void 0});if(BL(t,n,i,r,o)\u0026\u0026Dk(n,e))return!0;n.x=a.x,n.y=a.y;for(const t of c){if(!t)continue;const e=s.route[t.pointIndex];e\u0026\u0026(e.x=t.x,e.y=t.y)}return!1})(t,r,s,o)},KL=(t,e,n,o,i,r=.035,s=2,a=!1)=\u003e{if(uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const c=nL(e,n),l=e.x-c.x,d=e.y-c.y,h=Math.hypot(l,d),u=e.radius+n.radius+(rk.traceClearance??.1)+g_-h;if(u\u003c=0)return!1;const p=n.end.x-n.start.x,m=n.end.y-n.start.y,g=Math.hypot(p,m),f=e.routeIndex%2==0?1:-1,y=h\u003eh_?l/h:g\u003eh_?-m/g*f:1,_=h\u003eh_?d/h:g\u003eh_?p/g*f:0,b=Math.min(r,u/s),x=a?((t,e,n,o,i)=\u003e{const r=jL(t,e);if(0===r.length||r.some(e=\u003e!e.movable||void 0===t[e.routeIndex]))return!1;const s=r.reduce((t,e)=\u003ee.radius\u003et.radius?e:t);if(!BL(t,s,n,o,i))return!1;for(const e of r){if(e===s)continue;e.x=s.x,e.y=s.y;const n=t[e.routeIndex];for(const t of e.pointIndexes){const e=n.route[t];e\u0026\u0026(e.x=s.x,e.y=s.y)}}return!0})(t,e,y*b,_*b,o):$L(t,e,y*b,_*b,o),v=ZL(t,n,-y*b,-_*b,o,c.t);return x||v},QL=(t,e,n,o,i)=\u003e{if(e.z!==n.z||uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const[r]=UL(e,n);if(!r)return!1;const s=r.leftPoint.x-r.rightPoint.x,a=r.leftPoint.y-r.rightPoint.y,c=Math.hypot(s,a),l=e.radius+n.radius+(rk.traceClearance??.1)+g_-c;if(l\u003c=0)return!1;const d=e.end.x-e.start.x,h=e.end.y-e.start.y,u=Math.hypot(d,h),p=(e.routeIndex+n.routeIndex)%2==0?1:-1,m=c\u003eh_?s/c:u\u003eh_?-h/u*p:1,g=c\u003eh_?a/c:u\u003eh_?d/u*p:0,f=Math.min(m_,l/2),y=ZL(t,e,m*f,g*f,o,r.leftT),_=ZL(t,n,-m*f,-g*f,o,r.rightT);return y||_},tD=(t,e,n)=\u003eQk(t,n).includes(e.z),eD=(t,e,n,o,i)=\u003e{const r=e[n];if(!r)return;const s=Uk(r,n);if(0===s.length)return;const a=dk(r),c=VL(s,o);if(!c)return;const l=sL(t,o,.6,e=\u003e!pk(a,e,i)\u0026\u0026tD(e,c,t.layerCount));if(l)return{obstacle:l,segment:c};const d=sL(t,o,.6,e=\u003e!pk(a,e,i)\u0026\u0026s.some(n=\u003etD(e,n,t.layerCount)));if(!d)return;const h=VL(s.filter(e=\u003etD(d,e,t.layerCount)),o);return h?{obstacle:d,segment:h}:void 0},nD=(t,e,n)=\u003e{const o=e.width/2,i=e.height/2,r=[{x:e.center.x-o,y:e.center.y-i},{x:e.center.x+o,y:e.center.y-i},{x:e.center.x+o,y:e.center.y+i},{x:e.center.x-o,y:e.center.y+i}],s=[e.center,...r].map(e=\u003enL(e,t)),a=[{point:t.start,t:0},{point:t.end,t:1},{point:{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2},t:.5},...s.map(t=\u003e({point:{x:t.x,y:t.y},t:t.t}))];let c;const l=Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y);for(const o of a){const i=aL(o.point,e,n);if(!i)continue;const r=l\u003eh_?Math.abs(((t.end.x-t.start.x)*i.direction.y-(t.end.y-t.start.y)*i.direction.x)/l):0;(!c||i.penetration\u003ec.penetration+h_||Math.abs(i.penetration-c.penetration)\u003c=h_\u0026\u0026r\u003ec.normality)\u0026\u0026(c={...i,normality:r,t:o.t})}return c},oD=(t,e,n,o=!1)=\u003e{let i=!1;const r=Gk(e),s=Zk(e),a=tL(t,r,s),c=Math.max(1,2*a),l=bk(r,qk,c),d=bk(s,Jk,c);for(let s=0;s\u003cr.length;s+=1){const d=r[s];if(!d)continue;const h=xk(l,fk(qk(d),a),c);for(const a of h){if(a\u003c=s)continue;const c=r[a];c\u0026\u0026(i=qL(e,d,c,t,n,m_,o)||i)}}for(let o=0;o\u003cr.length;o+=1){const l=r[o];if(!l)continue;const h=xk(d,fk(qk(l),a),c);for(const o of h){const r=s[o];r\u0026\u0026(i=KL(e,l,r,t,n)||i)}}for(let o=0;o\u003cs.length;o+=1){const r=s[o];if(!r)continue;const l=xk(d,fk(Jk(r),a),c);for(const a of l){if(a\u003c=o)continue;const c=s[a];c\u0026\u0026(i=QL(e,r,c,t,n)||i)}}return((t,e,n,o,i,r,s,a)=\u003e{let c=!1;const l=t.minTraceWidth/2+f_(t)+g_,d=(t.minViaDiameter??.3)/2+y_(t)+g_;for(const h of t.obstacles){if(h.isCopperPour)continue;const u=Kk(h),p=xk(i,fk(u,d),s);for(const o of p){const i=n[o];if(!i)continue;if(pk(i.rootConnectionName,h,a))continue;const r=aL(i,h,d);if(!r)continue;const s=Math.min(m_,r.penetration);c=$L(e,i,r.direction.x*s,r.direction.y*s,t)||c}const m=xk(r,fk(u,l),s);for(const n of m){const i=o[n];if(!i)continue;if(pk(i.rootConnectionName,h,a)||!tD(h,i,t.layerCount))continue;const r=nD(i,h,l);if(!r)continue;const s=Math.min(m_,r.penetration);c=ZL(e,i,r.direction.x*s,r.direction.y*s,t,r.t)||c}}return c})(t,e,r,s,l,d,c,n)||i},iD=(t,e,n,o=1,i,r=!1,s=!0)=\u003e{const a=kk(e),c=Math.max(2,Math.round(12*Math.max(1,n)*o));let l=!1;for(let e=0;e\u003cc;e+=1){if(!oD(t,a,i,r))break;l=!0}return l\u0026\u0026s\u0026\u0026((t,e,n)=\u003e{let o=!1;const i=Gk(e),r=Zk(e),s=tL(t,i,r),a=Math.max(1,2*s),c=bk(r,Jk,a);for(const l of i){const i=xk(c,fk(qk(l),s),a);for(const s of i){const i=r[s];i\u0026\u0026(o=KL(e,l,i,t,n,m_,1.75)||o)}}})(t,a,i),l?aD(a):e},rD=t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n+=1){const o=t.route[n],i=t.route[n+1];if(!o||!i)continue;if(\"through_obstacle\"===o.toNextSegmentType)continue;if(o.z===i.z||!Dk(o,i))continue;const r={x:o.x,y:o.y},s=e.at(-1);s\u0026\u0026Dk(s,r)||e.push(r)}return e},sD=t=\u003e({...t,vias:rD(t)}),aD=t=\u003et.map(sD),cD=(t,e)=\u003e{const n=new Set(e);return t.map((t,e)=\u003en.has(e)?sD(t):t)},lD=t=\u003e{const e=t.pcb_trace_id;if(\"string\"!=typeof e)return;const n=e.match(/^trace_(\\d+)/);return n?Number.parseInt(n[1],10):void 0},dD=t=\u003e{const e=t.center??t.pcb_center;if(!e||\"object\"!=typeof e)return;const n=e;return\"number\"==typeof n.x\u0026\u0026\"number\"==typeof n.y?{x:n.x,y:n.y}:void 0},hD=(t,e=!0)=\u003et.errors.filter(t=\u003e(t=\u003e\"pcb_via_clearance_error\"===Fk(t)||Array.isArray(t.pcb_via_ids))(t)\u0026\u0026(e||!uD(t))).length,uD=t=\u003e\"pcb_pad_pad_clearance_error\"===Fk(t)\u0026\u0026Array.isArray(t.pcb_via_ids)\u0026\u00261===t.pcb_via_ids.length,pD=t=\u003e{const e=Object.entries(t).filter(([t,e])=\u003e\"source_trace_id\"!==t\u0026\u0026(t.endsWith(\"_id\")||t.endsWith(\"_ids\"))\u0026\u0026void 0!==e\u0026\u0026\"\"!==e).sort(([t],[e])=\u003et.localeCompare(e)),n=\"string\"==typeof t.message?t.message.replace(/-?\\d+\\.\\d+/g,\"#\"):\"\";return JSON.stringify([Fk(t),e,n])},mD=t=\u003eMath.max(t.errors.filter(t=\u003e!uD(t)).length,t.count-t.errors.filter(uD).length),gD=t=\u003e{const e=mD(t);return e\u003e0?e:t.count},fD=t=\u003e{if(0===mD(t))return t.issueScore;const e=t.errors.filter(t=\u003e!uD(t));return t.errors.some(uD)?Xk(e):t.legacyIssueScore??Xk(e)},yD=(t,e)=\u003e{const n=mD(t),o=mD(e);return n!==o?n\u003co:!(n\u003e0)\u0026\u0026t.count\u003ce.count},_D=t=\u003e{const e=t.filter(t=\u003e!uD(t));return e.length\u003e0?e:t},bD=(t,e)=\u003e{const n=t.pcb_trace_id;return\"string\"==typeof n?e.get(n)??lD(t):lD(t)},xD=(t,e,n,o,i)=\u003e{const r=n.pcb_port_id;if(!r)return!1;const s=(i??e.viaDiameter)/2;return t.obstacles.some(i=\u003e{const a=Qk(i,t.layerCount);return!(1!==a.length||a[0]!==n.z||!i.connectedTo.includes(r)||n.x-s\u003ci.center.x-i.width/2-h_||n.x+s\u003ei.center.x+i.width/2+h_||n.y-s\u003ci.center.y-i.height/2-h_||n.y+s\u003ei.center.y+i.height/2+h_)\u0026\u0026(pk(dk(e),i,o)||pk(e.connectionName,i,o))})},vD=[0,1,-1,2,-2,3,-3,4],SD=vD.flatMap(t=\u003evD.map(e=\u003e[t,e])).sort(([t,e],[n,o])=\u003eMath.abs(t)+Math.abs(e)-Math.abs(n)-Math.abs(o)),ID=SD.length,CD=(t,e,n)=\u003et.x-e\u003e=n.minX-h_\u0026\u0026t.x+e\u003c=n.maxX+h_\u0026\u0026t.y-e\u003e=n.minY-h_\u0026\u0026t.y+e\u003c=n.maxY+h_,PD=(t,e)=\u003e{const n=t.at(-1);n\u0026\u0026Dk(n,e)\u0026\u0026n.z===e.z\u0026\u0026n.pcb_port_id===e.pcb_port_id||t.push(e)},MD=(t,e,n,o,i,r,s,a=0,c=!1)=\u003e{const l=Fk(n);if(\"pcb_pad_trace_clearance_error\"!==l\u0026\u0026\"pcb_trace_error\"!==l)return!1;if(i\u003c0||i\u003e=t.layerCount)return!1;const d=e[o];if(!d||d.route.length\u003c2)return!1;const h=d.route.map(t=\u003e({...t})),u=h[0],p=h.at(-1);if(!u||!p)return!1;const m=dD(n);if(!m)return!1;const g=Bk(n),f=g?eD(t,e,o,m,s):void 0,y=g?f?.segment:VL(Uk(d,o),m);if(!y||y.z===i)return!1;let _=y.startIndex,b=y.endIndex;const x=\"full\"===r?h.length:r;for(let t=0;t\u003cx;t+=1){let t=!1;const e=h[_-1];e?.z===y.z\u0026\u0026(_-=1,t=!0);const n=h[b+1];if(n?.z===y.z\u0026\u0026(b+=1,t=!0),!t)break}const v=0===_\u0026\u0026u.pcb_port_id,S=b===h.length-1\u0026\u0026p.pcb_port_id,I=d.viaDiameter/2,C=SD[a%ID];let P=!1;const M=e=\u003e{const n=\"start\"===e?u:p,o=((t,e,n,o)=\u003e{const i=n.pcb_port_id;if(i)return t.obstacles.find(r=\u003e{const s=Qk(r,t.layerCount);return!(1!==s.length||s[0]!==n.z||!r.connectedTo.includes(i)||!iL(n,r))\u0026\u0026(pk(dk(e),r,o)||pk(e.connectionName,r,o))})})(t,d,n,s),r=((t,e)=\u003e{const n=\"start\"===e?t[0]:t.at(-1);if(!n)return;const o=\"start\"===e?Array.from({length:t.length-1},(t,e)=\u003ee+1):Array.from({length:t.length-1},(e,n)=\u003et.length-n-2);for(const e of o){const o=t[e];if(!o)continue;const i=o.x-n.x,r=o.y-n.y,s=Math.hypot(i,r);if(!(s\u003c=h_))return{x:i/s,y:r/s}}})(h,e);if(!o||!r)return;const a=((t,e,n,o)=\u003e{let i=0,r=Math.hypot(e.width,e.height)+2*o;const s=o+h_,a=e=\u003e({x:t.x+n.x*e,y:t.y+n.y*e});if(!(oL(a(r),e)\u003cs)){for(;r-i\u003eh_;){const t=(i+r)/2;oL(a(t),e)\u003e=s?r=t:i=t}return a(r)}})(n,o,((t,e)=\u003e{const n=e*Math.PI/4,o=Math.cos(n),i=Math.sin(n);return{x:t.x*o-t.y*i,y:t.x*i+t.y*o}})(r,\"start\"===e?C[0]:C[1]),I);if(!a||!CD(a,I,t.bounds)||oL(a,o)+h_\u003cI)return;if(!c)return a;const l=((t,e,n,o,i,r)=\u003e{const s=o+(t.minBoardEdgeClearance??0),a={minX:t.bounds.minX+s,maxX:t.bounds.maxX-s,minY:t.bounds.minY+s,maxY:t.bounds.maxY-s};if(a.minX\u003ea.maxX||a.minY\u003ea.maxY)return;const c=Ek(t,e,o,i,r),l=t=\u003eMe(t,a)\u0026\u0026c.every(e=\u003eCk(t,e)\u003e=e.clearance),d=Ik(n,a);if(l(d))return Me(n,a)?n:d;const h=c.filter(t=\u003eCk(d,t)\u003ct.clearance),u=new Set(h);for(let t=0;t\u003ch.length;t+=1)for(const e of c)!u.has(e)\u0026\u0026Xe(h[t].bounds,e.bounds)\u0026\u0026(u.add(e),h.push(e));const p=h.flatMap(Nk),m={x:a.minX,y:a.minY},g={x:a.maxX,y:a.minY},f={x:a.maxX,y:a.maxY},y={x:a.minX,y:a.maxY};let _;p.push(Pk(m,g),Pk(g,f),Pk(f,y),Pk(y,m));let b=Number.POSITIVE_INFINITY;const x=t=\u003e{const e=Ye(t,n);e\u003cb\u0026\u0026l(t)\u0026\u0026(_=t,b=e)};for(const t of p)for(const e of wk(n,t))x(e);for(let t=0;t\u003cp.length;t+=1){const e=p[t];if(!(Ye(n,Ik(n,e.bounds))\u003eb))for(let o=t+1;o\u003cp.length;o+=1){const t=p[o];if(Xe(e.bounds,t.bounds)\u0026\u0026!(Ye(n,Ik(n,t.bounds))\u003eb))for(const n of Rk(e,t))x(n)}}return _})(t,d,a,I,[y.z,i],s);return P||=void 0!==l\u0026\u0026l!==a,l},N=v?M(\"start\"):void 0,w=S?M(\"end\"):void 0;if(v\u0026\u0026!N||S\u0026\u0026!w||c\u0026\u0026!P)return!1;const T=[];for(let t=0;t\u003c_;t+=1)PD(T,h[t]);const R=h[_],E=_\u003e0\u0026\u0026Dk(h[_-1],R),A=h[b],O=b\u003ch.length-1\u0026\u0026Dk(h[b+1],A);v?(PD(T,u),PD(T,{...u,...N,pcb_port_id:void 0}),PD(T,{...u,...N,z:i,pcb_port_id:void 0})):(E||PD(T,{...R,pcb_port_id:void 0}),PD(T,{...R,z:i,pcb_port_id:void 0}));const k=S?b-1:b;for(let t=_+1;t\u003c=k;t+=1)PD(T,{...h[t],z:i,pcb_port_id:void 0});S?(PD(T,{...p,...w,z:i,pcb_port_id:void 0}),PD(T,{...p,...w,pcb_port_id:void 0}),PD(T,p)):O||PD(T,{...A,pcb_port_id:void 0});for(let t=b+1;t\u003ch.length;t+=1)PD(T,h[t]);for(let t=1;t\u003cT.length-1;t+=1)T[t].pcb_port_id=void 0;const L=t.minBoardEdgeClearance??.2,D=Uk(d,o),z=Gk([d]);for(let e=1;e\u003cT.length;e+=1){const n=T[e-1],o=T[e];if(n.z===o.z\u0026\u0026!D.some(t=\u003epL(n,t.start,t.end)\u0026\u0026pL(o,t.start,t.end))\u0026\u0026bL(t,n,o)\u003cd.traceThickness/2+L)return!1;if(n.z!==o.z\u0026\u0026\"through_obstacle\"!==n.toNextSegmentType\u0026\u0026!z.some(t=\u003eDk(t,o)\u0026\u0026t.radius\u003e=I)\u0026\u0026_L(t,o)\u003cI+L)return!1}return d.route=T,!0},ND=(t,e,n,o,i,r,s)=\u003e{const a=Fk(n);if(\"pcb_pad_trace_clearance_error\"!==a\u0026\u0026\"pcb_trace_error\"!==a)return!1;if(i\u003c0||i\u003e=t.layerCount)return!1;const c=bD(n,o);if(void 0===c)return!1;const l=e[c];if(!l||l.route.length\u003c2)return!1;const d=l.route[0],h=l.route.at(-1);if(!d||!h||d.z!==h.z||i===d.z)return!1;if(l.route.some(t=\u003et.z!==d.z))return!1;if(!d.pcb_port_id||!h.pcb_port_id)return!1;if(!xD(t,l,d,r,s)||!xD(t,l,h,r,s))return!1;const u=l.route.map(t=\u003e({...t}));return l.route=[u[0],{...u[0],z:i,pcb_port_id:void 0},...u.slice(1,-1).map(t=\u003e({...t,z:i})),{...u.at(-1),z:i,pcb_port_id:void 0},u.at(-1)],!0},wD=(t,e,n,o,i,r,s)=\u003e{if(\"pcb_pad_trace_clearance_error\"!==Fk(n))return!1;const a=bD(n,o);if(void 0===a)return!1;const c=e[a];if(!c||c.route.length\u003c4)return!1;const l=c.route.map(t=\u003e({...t}));if(\"start\"===i){const e=l[0];if(!xD(t,c,e,r,s))return!1;let n=-1;for(let t=1;t\u003cl.length;t+=1)if(l[t].z!==e.z){n=t;break}if(n\u003c=0)return!1;const o=n-1;if(!Dk(l[o],l[n]))return!1;let i=n;for(;i+1\u003cl.length\u0026\u0026Dk(l[n],l[i+1]);)i+=1;const a=l[i].z,d=l.slice(o,i+1).map(t=\u003et.z);return c.route=[e,...d.slice(1).map(t=\u003e({...e,z:t,pcb_port_id:void 0})),...l.slice(1,o+1).map(t=\u003e({...t,z:a})),...l.slice(i+1)],!0}const d=l.at(-1);if(!xD(t,c,d,r,s))return!1;let h=-1;for(let t=l.length-2;t\u003e=0;t-=1)if(l[t].z!==d.z){h=t;break}if(h\u003c0||h\u003e=l.length-1)return!1;const u=h+1;if(!Dk(l[h],l[u]))return!1;let p=h;for(;p-1\u003e=0\u0026\u0026Dk(l[h],l[p-1]);)p-=1;const m=l[p].z,g=l.slice(p,u+1).map(t=\u003et.z);return c.route=[...l.slice(0,p+1),...l.slice(u+1,-1).map(t=\u003e({...t,z:m})),{...d,z:m,pcb_port_id:void 0},...g.slice(1,-1).map(t=\u003e({...d,z:t,pcb_port_id:void 0})),d],!0},TD=(t,e)=\u003e{const n=t.pcb_trace_id;if(\"string\"!=typeof n)return;if(Array.isArray(t.pcb_via_ids)\u0026\u0026t.pcb_via_ids.length\u003e0)return;const o=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],i=t.pcb_trace_error_id,r=`overlap_${n}_`,s=\"string\"==typeof i\u0026\u0026i.startsWith(r)?i.slice(r.length):void 0,a=[n,...o,...s?[s]:[]],c=[...new Set(a.map(t=\u003ee.get(t)).filter(t=\u003evoid 0!==t))];return c.length\u003e=2?[c[0],c[1]]:void 0},RD=(t,e,n,o,i)=\u003e{if(\"pcb_trace_error\"!==Fk(n))return;const r=TD(n,o);if(!r)return;const s=n.worst_contact_center??n.center;if(!s||\"object\"!=typeof s)return;const a=s;if(\"number\"!=typeof a.x||\"number\"!=typeof a.y)return;const c={x:a.x,y:a.y},l=Zk(e),d=VL(l,c,r[0]),h=VL(l,c,r[1]);if(!d||!h||d.z!==h.z)return;const[u]=UL(d,h);if(!u)return;const p=u.leftPoint.x-u.rightPoint.x,m=u.leftPoint.y-u.rightPoint.y,g=Math.hypot(p,m),f=Number(n.minimum_clearance),y=Number.isFinite(f)?f:rk.traceClearance??.1,_=d.radius+h.radius+y-g;if(_\u003c=h_)return;const b=0===i?d:h,x=0===i?u.leftT:u.rightT,v=(1-x)**2+x**2;if(v\u003c=h_)return;const S=_/v,I=0===i?u.leftPoint:u.rightPoint,C=0===i?u.rightPoint:u.leftPoint,P=0===i?1:-1,M=b.end.x-b.start.x,N=b.end.y-b.start.y,w=Math.hypot(M,N),T=(b.routeIndex+(0===i?h.routeIndex:d.routeIndex))%2==0?1:-1,R=g\u003eh_?(I.x-C.x)/g:w\u003eh_?-N/w*T*P:P,E=g\u003eh_?(I.y-C.y)/g:w\u003eh_?M/w*T*P:0;return ZL(e,b,R*S,E*S,t,x)?{movedRouteIndex:b.routeIndex}:void 0},ED=t=\u003e{const{srj:e,via:n,segment:o,segments:i,initialTarget:r,requiredTraceDistance:s,requiredObstacleDistance:a,connMap:c}=t,l=Math.min(...n.zLayers),d=Math.max(...n.zLayers),h=e.obstacles.filter(t=\u003e!t.isCopperPour\u0026\u0026!pk(n.rootConnectionName,t,c)\u0026\u0026Qk(t,e.layerCount).some(t=\u003et\u003e=l\u0026\u0026t\u003c=d)),u=h.filter(t=\u003eBoolean(aL(r,t,a))),p=[r,...Ak(n,i,s-n.radius-o.radius,c),...u.flatMap(t=\u003e(t=\u003e{const{point:e,obstacle:n,requiredDistance:o}=t,i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=n.center.y-n.height/2,a=n.center.y+n.height/2,c=Math.max(i-e.x,e.x-r,0),l=Math.max(s-e.y,e.y-a,0),d=[];if(c\u003co){const t=Math.sqrt(o*o-c*c);d.push({x:e.x,y:s-t-h_},{x:e.x,y:a+t+h_})}if(l\u003co){const t=Math.sqrt(o*o-l*l);d.push({x:i-t-h_,y:e.y},{x:r+t+h_,y:e.y})}return d})({point:r,obstacle:t,requiredDistance:a}))];return p.filter(t=\u003e{if(!CD(t,n.radius,e.bounds))return!1;const r=nL(t,o);return!(Math.hypot(t.x-r.x,t.y-r.y)\u003cs-h_)\u0026\u0026(!i.some(e=\u003ee.z\u003e=l\u0026\u0026e.z\u003c=d\u0026\u0026!uk(n.rootConnectionName,e.rootConnectionName,c)\u0026\u0026be(t,e.start,e.end)\u003cs+e.radius-o.radius-h_)\u0026\u0026h.every(e=\u003eoL(t,e)\u003e=a-h_))}).sort((t,e)=\u003eMath.hypot(t.x-n.x,t.y-n.y)-Math.hypot(e.x-n.x,e.y-n.y))[0]},AD=(t,e,n,o,i,r)=\u003e{if(\"pcb_trace_error\"!==Fk(n))return!1;const s=\"string\"==typeof n.pcb_trace_error_id?n.pcb_trace_error_id.toLowerCase():\"\",a=\"string\"==typeof n.message?n.message.toLowerCase():\"\";if(!(\"string\"==typeof n.pcb_via_id||Array.isArray(n.pcb_via_ids)||s.includes(\"_via_\")||a.includes(\"via\")))return!1;if(bD(n,o)!==i)return!1;if(TD(n,o))return!1;const c=n.worst_contact_center??n.center;if(!c||\"object\"!=typeof c)return!1;const l=c;if(\"number\"!=typeof l.x||\"number\"!=typeof l.y)return!1;const d={x:l.x,y:l.y},h=Zk(e),u=VL(h,d,i),p=Array.isArray(n.pcb_trace_ids)?n.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t\u0026\u0026t!==n.pcb_trace_id):[],m=p.map(t=\u003eo.get(t)).filter(t=\u003evoid 0!==t),g=Gk(e),f=WL(p.length\u003e0?g.filter(t=\u003em.includes(t.routeIndex)):g,d);if(!u||!f||!f.movable||uk(f.rootConnectionName,u.rootConnectionName,r))return!1;const y=nL(f,u),_=f.x-y.x,b=f.y-y.y,x=Math.hypot(_,b),v=Number(n.minimum_clearance),S=Number.isFinite(v)?v:rk.traceClearance??.1,I=f.radius+u.radius+S-x;if(I\u003c=h_)return!1;const C=u.end.x-u.start.x,P=u.end.y-u.start.y,M=Math.hypot(C,P),N=f.routeIndex%2==0?1:-1,w=x\u003eh_?_/x:M\u003eh_?-P/M*N:1,T=x\u003eh_?b/x:M\u003eh_?C/M*N:0,R=f.radius+u.radius+S,E=f.radius+y_(t)+g_,A={x:f.x+w*(I+g_),y:f.y+T*(I+g_)},O=ED({srj:t,via:f,segment:u,segments:h,initialTarget:A,requiredTraceDistance:R,requiredObstacleDistance:E,connMap:r});return!!O\u0026\u0026$L(e,f,O.x-f.x,O.y-f.y,t)},OD=(t,e,n)=\u003e{if(\"pcb_trace_error\"!==Fk(e))return;const o=dD(e),i=t[n];if(!o||!i)return;const r=VL(Uk(i,n),o);return r?{center:o,route:i,segment:r}:void 0},kD=(t,e,n,o)=\u003e{const i=OD(t,e,n);if(!i)return;const{route:r,segment:s}=i,a=Math.max(0,s.startIndex-o),c=Math.min(r.route.length-1,s.endIndex+o),l=r.route.slice(a,c+1),d=l[0],h=l.at(-1);return d\u0026\u0026h\u0026\u0026!l.some(t=\u003et.z!==d.z)\u0026\u0026d.z===h.z?{route:r,spanStartIndex:a,spanEndIndex:c,start:d,end:h}:void 0},LD=(t,e,n,o,i,r,s=0,a,c)=\u003e{if(r\u003c0||r\u003e=t.layerCount)return!1;const l=TD(n,o);if(!l)return!1;const d=l[i],h=OD(e,n,d);if(!h||h.segment.z===r)return!1;const{route:u,segment:p}=h;let m=p.startIndex,g=p.endIndex;for(let t=0;t\u003cs;t+=1){const t=u.route[m-1];t?.z===p.z\u0026\u0026(m-=1);const e=u.route[g+1];e?.z===p.z\u0026\u0026(g+=1)}if(0===m\u0026\u0026u.route[0]?.pcb_port_id\u0026\u0026!xD(t,u,u.route[0],a,c)||g===u.route.length-1\u0026\u0026u.route.at(-1)?.pcb_port_id\u0026\u0026!xD(t,u,u.route.at(-1),a,c))return!1;const f=u.route[m],y=u.route[g];if(!f||!y||f.z!==y.z)return!1;const _=u.route.slice(m,g+1).map(t=\u003e({...t,z:r,pcb_port_id:void 0}));return u.route.splice(m,g-m+1,{...f},..._,{...y}),!0},DD=(t,e,n,o,i,r)=\u003e{if(o\u003c=0||i\u003c=0)return!1;const s=OD(t,e,n);if(!s)return!1;const{center:a,route:c,segment:l}=s,d=l.end.x-l.start.x,h=l.end.y-l.start.y,u=Math.hypot(d,h);if(u\u003c=h_)return!1;const p=nL(a,l),m=mk(p.t-o/u,.02,.98),g=mk(p.t+o/u,.02,.98);if(m\u003e=g)return!1;const f=t=\u003e({x:l.start.x+d*t,y:l.start.y+h*t,z:l.z}),y=f(m),_=f(g),b=-h/u*r,x=d/u*r,v=c.route[l.startIndex],S=c.route[l.endIndex];return c.route.splice(l.startIndex,2,{...v},y,{...y,x:y.x+b*i,y:y.y+x*i},{..._,x:_.x+b*i,y:_.y+x*i},_,{...S}),!0},zD=(t,e,n,o,i,r,s,a=!1)=\u003e{if(!Number.isInteger(i)||i\u003c0||i\u003e=t.layerCount)return!1;const c=dD(n),l=e[o],d=l?.route[0],h=l?.route.at(-1);if(!l||!c||!d||!h||d.z!==h.z||d.z===i||l.jumpers?.length||l.route.some(t=\u003et.z!==d.z||\"through_obstacle\"===t.toNextSegmentType))return!1;const u=h.x-d.x,p=h.y-d.y,m=Math.hypot(u,p);if(m\u003c=h_||m\u003e8)return!1;const g=u/m,f=p/m,y=f*r,_=-g*r,b=t=\u003e(t.x-c.x)*g+(t.y-c.y)*f,x=(t,e,n)=\u003e({x:c.x+g*t+y*e,y:c.y+f*t+_*e,z:n}),v=(l.viaDiameter??t.minViaDiameter??.3)+(t.minTraceToPadEdgeClearance??rk.traceClearance??.1),S=(a?1.25:-.75)*v,I=(a?-.75:1.25)*v,C=b(d)+.5*v*s,P=b(h)+v*s,M=x(C,S,d.z),N=x(P,I,d.z),w=x(C,2*v,i),T=x(P,2*v,i),R=[{...d},M,{...M,z:i},w,T,{...N,z:i},N,{...h}],E=t.minBoardEdgeClearance??0,A=(l.viaDiameter??t.minViaDiameter??.3)/2,O=l.traceThickness/2;if([M,N].some(e=\u003e_L(t,e)+u_\u003cA+E))return!1;for(let e=0;e\u003cR.length-1;e+=1){const n=R[e],o=R[e+1];if(n.z===o.z\u0026\u0026bL(t,n,o)+u_\u003cO+E)return!1}return l.route.splice(0,l.route.length,...R),!0},FD=(t,e,n,o,i,r,s)=\u003e{if(!Number.isInteger(i)||i\u003c1||r\u003c=0)return!1;const a=kD(e,n,o,i);if(!a)return!1;const{route:c,spanStartIndex:l,spanEndIndex:d,start:h,end:u}=a,p=u.x-h.x,m=u.y-h.y,g=Math.hypot(p,m);if(g\u003c=h_)return!1;const f=-m/g*s*r,y=p/g*s*r,_={...h,x:h.x+f,y:h.y+y,pcb_port_id:void 0},b={...u,x:u.x+f,y:u.y+y,pcb_port_id:void 0};return!(!hL(_,t.bounds)||!hL(b,t.bounds))\u0026\u0026(c.route.splice(l,d-l+1,{...h},_,b,{...u}),!0)},BD=(t,e,n,o,i,r)=\u003e{if(!Number.isInteger(i)||i\u003c0)return!1;const s=kD(e,n,o,i);if(!s)return!1;const{route:a,spanStartIndex:c,spanEndIndex:l,start:d,end:h}=s;return!(Math.hypot(r.x-d.x,r.y-d.y)\u003c=h_||Math.hypot(r.x-h.x,r.y-h.y)\u003c=h_||!hL(r,t.bounds))\u0026\u0026(a.route.splice(c,l-c+1,{...d},{x:r.x,y:r.y,z:d.z},{...h}),!0)},jD=(t,e,n,o,i,r)=\u003e{if(r){const e=mD(t),n=mD(r);if(e!==n)return e\u003cn}const s=gD(t),a=fD(t);return s\u003cn||s===n\u0026\u0026a\u003co||s===n\u0026\u0026e\u003ci},$D=(t,e,n,o,i,r,s=!0,a=!1,c=!0,l=!1)=\u003e{let d=!1;const h=Gk(e),u=Zk(e);for(const p of n){const n=dD(p);if(!n)continue;let m=n;const g=p.pcb_via_ids,f=\"pcb_via_clearance_error\"===Fk(p),y=uD(p),_=Array.isArray(g)\u0026\u0026g.length\u003e0,b=!f\u0026\u0026!y\u0026\u0026_\u0026\u0026(\"string\"==typeof p.pcb_trace_id||Array.isArray(p.pcb_trace_ids)),x=l\u0026\u0026b;if(_\u0026\u0026!b){m=cL(t,p,n);const c=bD(p,o),l=g.length\u003e1?HL(h,n):void 0;if(l){const n=a\u0026\u0026\"pcb_via_clearance_error\"===Fk(p)\u0026\u0026\"same_net\"===p.pcb_via_pair_net_relation,o=s\u0026\u0026\"pcb_via_clearance_error\"===Fk(p);d=(n?JL(e,l[0],l[1],t,r):qL(e,l[0],l[1],t,r,.16*Math.abs(i),o))||d}else{const o=WL(h,n,c);o\u0026\u0026(d=GL(e,o,m,t)||d)}continue}const v=p.pcb_trace_id,S=bD(p,o);if(x\u0026\u0026void 0===S)continue;const I=Array.isArray(p.pcb_trace_ids)?p.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[];if(x\u0026\u0026\"string\"==typeof v\u0026\u0026void 0!==S\u0026\u0026I.includes(v)\u0026\u0026I.some(t=\u003et!==v\u0026\u0026!o.has(t))){const o=WL(h,n,S);if(o){d=GL(e,o,n,t)||d;continue}}const C=s\u0026\u0026!b?TD(p,o):void 0;if(C){const o=VL(u,n,C[0]),i=VL(u,n,C[1]);if(o\u0026\u0026i\u0026\u0026QL(e,o,i,t,r)){d=!0;continue}}const P=Bk(p),M=P\u0026\u0026void 0!==S?eD(t,e,S,n,r):void 0,N=P?M?.segment:VL(u,n,S);if(N){const o=P?M?.obstacle:sL(t,n);if(P\u0026\u0026!o)continue;m=P?o?.center??n:cL(t,p,n);const s=x?void 0:WL(h,n),a=\"pcb_via_trace_clearance_error\"===Fk(p),l=\"string\"==typeof p.pcb_trace_error_id?p.pcb_trace_error_id.toLowerCase():\"\",u=\"string\"==typeof p.message?p.message.toLowerCase():\"\",g=a||\"string\"==typeof p.pcb_via_id||Array.isArray(p.pcb_via_ids)||l.includes(\"_via_\")||u.includes(\"via\"),f=Array.isArray(p.pcb_port_ids)\u0026\u0026p.pcb_port_ids.length\u003e0;if(s\u0026\u0026!uk(s.rootConnectionName,N.rootConnectionName,r)\u0026\u0026(a||Math.hypot(s.x-n.x,s.y-n.y)\u003c.45)){if(KL(e,s,N,t,r,.3*Math.abs(i),1,c)\u0026\u0026(d=!0,g\u0026\u0026!f))continue}d=(void 0!==o\u0026\u0026(P||!pk(N.rootConnectionName,o,r)\u0026\u0026tD(o,N,t.layerCount))?XL(e,N,o,t,r,i):YL(e,N,m,t,i))||d}const w=x?void 0:WL(h,n);w\u0026\u0026Math.hypot(w.x-n.x,w.y-n.y)\u003c.35\u0026\u0026(d=GL(e,w,m,t)||d)}return d},YD=1e-6,XD=.006,VD=[1,.5,.25,.1,.05,.025],WD=(t,e)=\u003e(e.traceThickness??t.minTraceWidth)/2,HD=t=\u003et.minTraceToPadEdgeClearance??.1,GD=(t,e)=\u003ee.viaDiameter??t.minViaDiameter??.3,UD=(t,e)=\u003exe(t,e)\u003cYD,ZD=t=\u003e{const e=[],n=t=\u003e{e.some(e=\u003eUD(e,t))||e.push({x:t.x,y:t.y})};for(const e of t.vias)n(e);for(let e=0;e\u003ct.route.length-1;e+=1){const o=t.route[e],i=t.route[e+1];o\u0026\u0026i\u0026\u0026o.z!==i.z\u0026\u0026(UD(o,i)\u0026\u0026n(o))}return e},qD=t=\u003exe({x:0,y:0},t)\u003cYD?{x:0,y:0}:Fe({x:0,y:0},t),JD=(t,e)=\u003e{if(t.zLayers\u0026\u0026t.zLayers.length\u003e0)return t.zLayers;const n=Array.from({length:e},(t,e)=\u003ee).filter(n=\u003et.layers.includes(Vy(n,e)));return n.length\u003e0?n:Array.from({length:e},(t,e)=\u003ee)},KD=(t,e,n)=\u003euk(dk(t),dk(e),n)||uk(dk(t),e.connectionName,n)||uk(t.connectionName,dk(e),n)||uk(t.connectionName,e.connectionName,n),QD=(t,e,n)=\u003epk(dk(t),e,n)||pk(t.connectionName,e,n),tz=(t,e,n,o)=\u003e!n.pcb_port_id\u0026\u0026t.obstacles.some(i=\u003eQD(e,i,o)\u0026\u0026JD(i,t.layerCount).includes(n.z)\u0026\u0026((t,e)=\u003et.x\u003e=e.center.x-e.width/2-YD\u0026\u0026t.x\u003c=e.center.x+e.width/2+YD\u0026\u0026t.y\u003e=e.center.y-e.height/2-YD\u0026\u0026t.y\u003c=e.center.y+e.height/2+YD)(n,i)),ez=(t,e,n,o,i)=\u003e{if(!((t,e)=\u003et.zLayers.includes(e))(i,n.z))return Number.POSITIVE_INFINITY;const r=WD(t,e);return\"pad\"===i.kind?Le(n,o,i.obstacle)-(HD(t)+r+XD):be(i.center,n,o)-(HD(t)+r+i.diameter/2+XD)},nz=(t,e,n)=\u003e{const o=\"pad\"===n.kind?n.obstacle.center:n.center,i=ze(o,t,e);let r=qD({x:i.x-o.x,y:i.y-o.y});if(Math.abs(r.x)\u003cYD\u0026\u0026Math.abs(r.y)\u003cYD){const n=e.x-t.x,i=e.y-t.y,s=$e(t,e),a=qD({x:-i,y:n}),c={x:-a.x,y:-a.y};r=xe({x:s.x+a.x,y:s.y+a.y},o)\u003e=xe({x:s.x+c.x,y:s.y+c.y},o)?a:c}return r},oz=(t,e,n,o)=\u003e{if(n\u003c=0||n\u003e=e.route.length-1){const i=e.route[n];return!i||!tz(t,e,i,o)}const i=e.route[n];if(!i||i.insideJumperPad)return!0;const r=e.route[n-1],s=e.route[n+1];return!(!r||r.z===i.z)||(!(!s||s.z===i.z)||e.vias.some(t=\u003eUD(t,i)))},iz=(t,e,n)=\u003e{let o=0;for(let i=0;i\u003ce.route.length-1;i+=1){const r=e.route[i],s=e.route[i+1];if(r\u0026\u0026s\u0026\u0026r.z===s.z\u0026\u0026!UD(r,s))for(const i of n){const n=ez(t,e,r,s,i);if(!(n\u003e=0)\u0026\u0026(o+=n*n,\"pad\"===i.kind)){if(Le(r,s,i.obstacle)\u003cYD){o+=.01/(be(i.obstacle.center,r,s)+.01)}}}}return o},rz=(t,e,n,o)=\u003e{let i=0;for(let r=0;r\u003ce.route.length-1;r+=1){const s=e.route[r],a=e.route[r+1];if(s\u0026\u0026a\u0026\u0026s.z===a.z\u0026\u0026!UD(s,a))for(const r of n)if(!KD(e,r,o)){for(let n=0;n\u003cr.route.length-1;n+=1){const o=r.route[n],c=r.route[n+1];if(!o||!c||o.z!==s.z||c.z!==s.z||UD(o,c))continue;const l=Oe(s,a,o,c)-WD(t,e)-WD(t,r),d=HD(t)+XD-l;d\u003e0\u0026\u0026(i+=d*d)}for(const n of ZD(r)){const o=be(n,s,a)-WD(t,e)-GD(t,r)/2,c=HD(t)+XD-o;c\u003e0\u0026\u0026(i+=c*c)}}}return i},sz=(t,e,n,o,i)=\u003e{const r=e.route.map(()=\u003e({x:0,y:0}));for(let s=0;s\u003ce.route.length-1;s+=1){const a=e.route[s],c=e.route[s+1];if(a\u0026\u0026c\u0026\u0026a.z===c.z\u0026\u0026!UD(a,c)){for(const o of n){const n=ez(t,e,a,c,o);if(n\u003e=0)continue;const l=nz(a,c,o);if(Math.abs(l.x)\u003cYD\u0026\u0026Math.abs(l.y)\u003cYD)continue;const d=!oz(t,e,s,i),h=!oz(t,e,s+1,i);if(!d\u0026\u0026!h)continue;const u=-n,p=d\u0026\u0026h?.5:d?1:0,m=d\u0026\u0026h?.5:h?1:0;r[s].x+=l.x*u*p,r[s].y+=l.y*u*p,r[s+1].x+=l.x*u*m,r[s+1].y+=l.y*u*m}for(const n of o)if(!KD(e,n,i))for(let o=0;o\u003cn.route.length-1;o+=1){const l=n.route[o],d=n.route[o+1];if(!l||!d||l.z!==a.z||d.z!==a.z||UD(l,d))continue;const h=Oe(a,c,l,d)-WD(t,e)-WD(t,n),u=t.minTraceToPadEdgeClearance+XD-h;if(u\u003c=0)continue;const p=$e(a,c),m=ze(p,l,d);let g=qD({x:p.x-m.x,y:p.y-m.y});if(Math.abs(g.x)\u003cYD\u0026\u0026Math.abs(g.y)\u003cYD){const t=c.x-a.x,e=c.y-a.y;g=qD({x:-e,y:t})}const f=!oz(t,e,s,i),y=!oz(t,e,s+1,i);if(!f\u0026\u0026!y)continue;const _=f\u0026\u0026y?.5:f?1:0,b=f\u0026\u0026y?.5:y?1:0;r[s].x+=g.x*u*_,r[s].y+=g.y*u*_,r[s+1].x+=g.x*u*b,r[s+1].y+=g.y*u*b}}}return r},az=(t,e,n,o,i)=\u003e({...e,route:e.route.map((r,s)=\u003e{if(oz(t,e,s,i))return{...r};const a=((t,e)=\u003e{const n=xe({x:0,y:0},t);if(n\u003c=e||n\u003cYD)return t;const o=e/n;return{x:t.x*o,y:t.y*o}})(n[s]??{x:0,y:0},.5);return{...r,x:r.x+a.x*o,y:r.y+a.y*o}}),vias:e.vias.map(t=\u003e({...t})),jumpers:e.jumpers?[...e.jumpers]:void 0}),cz=(t,e)=\u003ee.route.every(e=\u003ee.x\u003e=t.bounds.minX-YD\u0026\u0026e.x\u003c=t.bounds.maxX+YD\u0026\u0026e.y\u003e=t.bounds.minY-YD\u0026\u0026e.y\u003c=t.bounds.maxY+YD),lz=(t,e,n,o,i)=\u003e{const r=((t,e,n,o)=\u003e{const i=[];for(const e of t.obstacles)e.isCopperPour||QD(n,e,o)||i.push({kind:\"pad\",obstacle:e,zLayers:JD(e,t.layerCount)});const r=Array.from({length:t.layerCount},(t,e)=\u003ee);for(const s of e)if(s!==n\u0026\u0026!KD(n,s,o))for(const e of ZD(s))i.push({kind:\"via\",center:{x:e.x,y:e.y},diameter:GD(t,s),zLayers:r,connectionName:s.connectionName,rootConnectionName:s.rootConnectionName});return i})(t,e,n,i),s=e.filter((t,e)=\u003ee!==o\u0026\u0026t!==n);let a=n,c=iz(t,a,r)+rz(t,a,s,i);for(let e=0;e\u003c160\u0026\u0026!(c\u003c=YD);e+=1){const e=sz(t,a,r,s,i);if(e.every(t=\u003exe(t,{x:0,y:0})\u003c1e-9))break;let n=null,o=c;for(const l of VD){const d=az(t,a,e,l,i),h=iz(t,d,r)+rz(t,d,s,i);if(h\u003cc-1e-6\u0026\u0026cz(t,d)){n=d,o=h;break}}if(!n)break;a=n,c=o}return a},dz=1e-6,hz=[1,.5,.25,.1,.05,.025],uz=(t,e)=\u003et.some(t=\u003ee.includes(t)),pz=(t,e,n,o)=\u003e(pk(t.rootConnectionName,n,o)||pk(e.connectionName,n,o))\u0026\u0026oL(t,n)\u003c=dz,mz=(t,e,n,o)=\u003e{const i=[],r=e[n.routeIndex];if(!r)return i;for(const e of t.obstacles){if(e.isCopperPour||pz(n,r,e,o))continue;const s=Qk(e,t.layerCount);uz(n.zLayers,s)\u0026\u0026i.push({obstacle:e})}return i},gz=(t,e,n)=\u003eoL(e,n.obstacle)-(e.radius+t.minViaEdgeToPadEdgeClearance+.006),fz=(t,e,n,o)=\u003eGk(e,t.minViaDiameter).filter(t=\u003et.routeIndex===n).reduce((n,i)=\u003en+((t,e,n,o)=\u003e{let i=0;for(const r of mz(t,e,n,o)){const e=gz(t,n,r);!(e\u003e=0)\u0026\u0026(i+=e*e,oL(n,r.obstacle)\u003cdz)\u0026\u0026(i+=.01/(xe(n,r.obstacle.center)+.01))}return i})(t,e,i,o),0),yz=(t,e,n,o)=\u003e{const i=e[n];if(!i)return[];const r=i.route.map(()=\u003e({x:0,y:0})),s=Gk(e,t.minViaDiameter).filter(t=\u003et.routeIndex===n);for(const n of s)if(n.movable)for(const i of mz(t,e,n,o)){const e=n.radius+t.minViaEdgeToPadEdgeClearance+.006,o=aL(n,i.obstacle,e);if(o)for(const t of n.pointIndexes)r[t].x+=o.direction.x*o.penetration,r[t].y+=o.direction.y*o.penetration}return r},_z=(t,e,n,o)=\u003e{const i=new Set(Gk([e],t.minViaDiameter).flatMap(t=\u003et.movable?t.pointIndexes:[]));return{...e,route:e.route.map((t,e)=\u003e{if(!i.has(e))return{...t};const r=((t,e)=\u003e{const n=xe({x:0,y:0},t);if(n\u003c=e||n\u003cdz)return t;const o=e/n;return{x:t.x*o,y:t.y*o}})(n[e]??{x:0,y:0},.5);return{...t,x:t.x+r.x*o,y:t.y+r.y*o}}),vias:e.vias.map(t=\u003e({...t})),jumpers:e.jumpers?[...e.jumpers]:void 0}},bz=(t,e)=\u003ee.route.every(e=\u003ee.x\u003e=t.bounds.minX-dz\u0026\u0026e.x\u003c=t.bounds.maxX+dz\u0026\u0026e.y\u003e=t.bounds.minY-dz\u0026\u0026e.y\u003c=t.bounds.maxY+dz),xz=(t,e,n,o,i)=\u003e{let r=n,s=fz(t,e,o,i);for(let n=0;n\u003c160\u0026\u0026!(s\u003c=dz);n+=1){const n=yz(t,e,o,i);if(n.every(t=\u003exe(t,{x:0,y:0})\u003c1e-9))break;let a=null,c=s;for(const l of hz){const d=_z(t,r,n,l),h=[...e];h[o]=d;const u=fz(t,h,o,i);if(u\u003cs-1e-6\u0026\u0026bz(t,d)){a=d,c=u;break}}if(!a)break;e[o]=a,r=a,s=c}return r},vz=[.2,.4,.8,1.2].flatMap(t=\u003e[.2,.3,.45,.6].flatMap(e=\u003e[-1,1].map(n=\u003e({halfSpan:t,offset:e,directionSign:n})))),Sz=vz.flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,...t}))),Iz=[1,-1].flatMap(t=\u003e[1,-1].flatMap(e=\u003e[!1,!0].flatMap(n=\u003e[0,1].map(o=\u003e({routeSide:o,normalDirectionSign:t,tangentDirectionSign:e,reverseEndpointOffsets:n}))))),Cz=[0,1].map(t=\u003e({kind:\"displacementChain\",routeSide:t})),Pz=[...Cz,...[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,halfSpan:.4,offset:1.2,directionSign:t}))),...[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"span\",routeSide:e,spanExpansion:3,offset:1.8,directionSign:t}))),...[{dx:-2.4,dy:-.4},{dx:-2.4,dy:.4},{dx:2.4,dy:-.4},{dx:2.4,dy:.4},{dx:-.4,dy:-2.4},{dx:-.4,dy:2.4},{dx:.4,dy:-2.4},{dx:.4,dy:2.4}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:2,...t}))),...[{dx:-.17,dy:0},{dx:.17,dy:0},{dx:0,dy:-.17},{dx:0,dy:.17}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:0,...t}))),...Sz],Mz=[0,1,2],Nz=class extends kt{srj;inputHdRoutes;guardedInputHdRoutes;connMap;effort;drcEvaluator;referenceDrcEvaluator;autoroutingDrcEngine;viaHoleDiameter;configuredMaxIterations;enableBroadFallback;enableLargeBoardBroadFallback;enableTargetedErrorSweep;enablePostSolveClearanceRelaxation;enableSafeTraceLayerMoves;enableViaInPadLayerMoves;enableTraceViaOwnerTargeting;outputHdRoutes;initialDrcIssueCount;initialRepairDrcIssueCount;initialLowCountErrorsHaveMovableTraces=!1;broadForceAccepted=!1;targetedForceAccepted=!1;candidateAttempts=0;viaInPadCandidateAttempts=0;viaInPadCandidatesAccepted=0;padTopologyErrorCursor=0;safeTraceLayerCursorByErrorId=new Map;traceLayerCorridorCursorByErrorId=new Map;tracePairDetourCursorByErrorId=new Map;errorCursor=0;stalledIterations=0;bestDrcIssueCountSeen;bestDrcIssueScoreSeen;lastDrcCountImprovementCheckIteration=0;drcCountPlateauChecks=0;largeBoardBroadFallbackMisses=0;outputSnapshot;legacyCleanCheckpoint;viaPadRepairRolledBack=!1;referenceInputDrcIssueCount;referenceCandidateDrcIssueCount;referenceCandidateRolledBack=!1;referenceInputSnapshot;inputSnapshot;constructor(t){if(super(),this.srj=t.srj,this.inputHdRoutes=t.hdRoutes,this.guardedInputHdRoutes=aD(kk(t.hdRoutes)),this.connMap=t.connMap,this.effort=t.effort??1,this.drcEvaluator=t.drcEvaluator,this.referenceDrcEvaluator=t.referenceDrcEvaluator,this.autoroutingDrcEngine=t.autoroutingDrcEngine??(t.drcEvaluator?void 0:new s_(t.srj,{connMap:t.connMap,traceClearance:t.srj.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:t.srj.minTraceToPadEdgeClearance??rk.viaClearance,includeTraceViaOwnerMetadata:t.enableTraceViaOwnerTargeting??!1})),void 0!==t.viaHoleDiameter\u0026\u0026(!Number.isFinite(t.viaHoleDiameter)||t.viaHoleDiameter\u003c=0))throw new Error(\"viaHoleDiameter must be a positive finite number\");this.viaHoleDiameter=t.viaHoleDiameter,this.configuredMaxIterations=t.maxIterations,this.enableBroadFallback=t.enableBroadFallback??!0,this.enableLargeBoardBroadFallback=t.enableLargeBoardBroadFallback??!0,this.enableTargetedErrorSweep=t.enableTargetedErrorSweep??!1,this.enablePostSolveClearanceRelaxation=t.enablePostSolveClearanceRelaxation??!0,this.enableSafeTraceLayerMoves=t.enableSafeTraceLayerMoves??!1,this.enableViaInPadLayerMoves=t.enableViaInPadLayerMoves??!1,this.enableTraceViaOwnerTargeting=t.enableTraceViaOwnerTargeting??!1,this.outputHdRoutes=t.hdRoutes,this.referenceDrcEvaluator\u0026\u0026(this.referenceInputSnapshot=this.getReferenceDrcSnapshot(this.inputHdRoutes)),this.MAX_ITERATIONS=this.configuredMaxIterations??__(this.effort)}getConstructorParams(){return[{srj:this.srj,hdRoutes:this.inputHdRoutes,connMap:this.connMap,effort:this.effort,drcEvaluator:this.drcEvaluator,referenceDrcEvaluator:this.referenceDrcEvaluator,autoroutingDrcEngine:this.autoroutingDrcEngine,viaHoleDiameter:this.viaHoleDiameter,maxIterations:this.configuredMaxIterations,enableBroadFallback:this.enableBroadFallback,enableLargeBoardBroadFallback:this.enableLargeBoardBroadFallback,enableTargetedErrorSweep:this.enableTargetedErrorSweep,enablePostSolveClearanceRelaxation:this.enablePostSolveClearanceRelaxation,enableSafeTraceLayerMoves:this.enableSafeTraceLayerMoves,enableViaInPadLayerMoves:this.enableViaInPadLayerMoves,enableTraceViaOwnerTargeting:this.enableTraceViaOwnerTargeting}]}updateStats(t){this.stats={initialDrcIssueCount:this.initialDrcIssueCount??t.count,finalDrcIssueCount:t.count,globalDrcForceImproveMaxIterations:this.MAX_ITERATIONS,globalDrcForceImproveBroadForceAccepted:this.broadForceAccepted,globalDrcForceImproveTargetedForceAccepted:this.targetedForceAccepted,globalDrcForceImproveCandidateAttempts:this.candidateAttempts,globalDrcForceImproveViaInPadCandidateAttempts:this.viaInPadCandidateAttempts,globalDrcForceImproveViaInPadCandidatesAccepted:this.viaInPadCandidatesAccepted,globalDrcForceImproveStalledIterations:this.stalledIterations,globalDrcForceImproveBestDrcIssueCountSeen:this.bestDrcIssueCountSeen??t.count,globalDrcForceImproveBestDrcIssueScoreSeen:this.bestDrcIssueScoreSeen??t.issueScore,globalDrcForceImproveDrcCountPlateauChecks:this.drcCountPlateauChecks,globalDrcForceImproveLargeBoardBroadFallbackMisses:this.largeBoardBroadFallbackMisses,globalDrcForceImproveViaPadRepairRolledBack:this.viaPadRepairRolledBack,globalDrcForceImproveReferenceInputDrcIssueCount:this.referenceInputDrcIssueCount,globalDrcForceImproveReferenceCandidateDrcIssueCount:this.referenceCandidateDrcIssueCount,globalDrcForceImproveReferenceCandidateRolledBack:this.referenceCandidateRolledBack}}finishAtLegacyCleanCheckpoint(){const t=this.legacyCleanCheckpoint;return!!t\u0026\u0026(this.outputHdRoutes=t.routes,this.outputSnapshot=t.snapshot,this.viaPadRepairRolledBack=!0,this.updateStats(t.snapshot),this.solved=!0,!0)}increaseMaxIterationsForDrcIssueCount(t){void 0===this.configuredMaxIterations?this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,((t,e)=\u003eMath.max(__(e),Math.ceil(t*d_*Math.max(1,e))))(t,this.effort),((t,e)=\u003et\u003e120\u0026\u0026e\u003e0?192:48)(this.inputHdRoutes.length,t)):this.MAX_ITERATIONS=this.configuredMaxIterations}getSnapshot(t){return(this.initialLowCountErrorsHaveMovableTraces?Hk:Wk)(this.srj,t,this.drcEvaluator,this.connMap,this.autoroutingDrcEngine)}getReferenceDrcSnapshot(t){const e={traces:[],srj:this.srj,routes:t,hdRoutes:t},n=this.referenceDrcEvaluator?.getCachedResult?.(e);if(n){const t=Array.isArray(n)?n:n.errors;return{errors:t,count:t.length}}return Wk(this.srj,t,this.referenceDrcEvaluator,this.connMap,this.autoroutingDrcEngine)}getViaIssueCount(t){return hD(t)}getRepairIssueCount(t){return gD(t)}getRepairIssueScore(t){return fD(t)}acceptSolvedRoutes(t,e){const n=this.enablePostSolveClearanceRelaxation?((t,e,n)=\u003e{if(void 0===t.minTraceToPadEdgeClearance||t.minTraceToPadEdgeClearance\u003c=0)return e;let o=!1;const i=kk(e);for(let e=0;e\u003c4;e+=1)for(let e=0;e\u003ci.length;e+=1){const r=i[e];if(!r)continue;const s=lz(t,i,r,e,n);s!==r\u0026\u0026(i[e]=s,o=!0)}return o?i:e})(this.srj,t,this.connMap):t,o=this.enablePostSolveClearanceRelaxation?((t,e,n)=\u003e{if(void 0===t.minViaEdgeToPadEdgeClearance||t.minViaEdgeToPadEdgeClearance\u003c=0)return e;let o=!1;const i=kk(e);for(let e=0;e\u003c4;e+=1)for(let e=0;e\u003ci.length;e+=1){const r=i[e];if(!r)continue;const s=xz(t,i,r,e,n);s!==r\u0026\u0026(i[e]=s,o=!0)}return o?aD(i):e})(this.srj,n,this.connMap):t,i=o===t?e:this.getSnapshot(o),r=i.count\u003ce.count||i.count===e.count\u0026\u0026i.issueScore\u003c=e.issueScore;let s=r?o:t,a=r?i:e;const c=this.inputSnapshot??this.getSnapshot(this.guardedInputHdRoutes);if(this.referenceDrcEvaluator){const t=this.referenceInputSnapshot,e=this.getReferenceDrcSnapshot(s);this.referenceInputDrcIssueCount=t.count,this.referenceCandidateDrcIssueCount=e.count,e.count\u003et.count\u0026\u0026(s=this.guardedInputHdRoutes,a=c,this.referenceCandidateRolledBack=!0)}this.outputHdRoutes=s,this.outputSnapshot=a,this.stalledIterations=0,this.updateStats(a),this.solved=!0}updateDrcCountPlateauState(t){const e=this.getRepairIssueCount(t),n=this.getRepairIssueScore(t);this.bestDrcIssueCountSeen??=e,this.bestDrcIssueScoreSeen??=n;const o=this.initialRepairDrcIssueCount??e,i=this.inputHdRoutes.length\u003e120\u0026\u0026o\u003e0;if((o\u003e=20||i)\u0026\u0026this.iterations\u003c192)return(e\u003cthis.bestDrcIssueCountSeen||e===this.bestDrcIssueCountSeen\u0026\u0026n\u003cthis.bestDrcIssueScoreSeen)\u0026\u0026(this.bestDrcIssueCountSeen=e,this.bestDrcIssueScoreSeen=n),void(i\u0026\u0026this.largeBoardBroadFallbackMisses\u003e=2\u0026\u0026(this.solved=!0));const r=(t=\u003et\u003e=20?8:t\u003c=2?1:2)(o);if(!(this.iterations-this.lastDrcCountImprovementCheckIteration\u003cr)){if(this.lastDrcCountImprovementCheckIteration=this.iterations,e\u003cthis.bestDrcIssueCountSeen||e===this.bestDrcIssueCountSeen\u0026\u0026n\u003cthis.bestDrcIssueScoreSeen)return this.bestDrcIssueCountSeen=e,this.bestDrcIssueScoreSeen=n,void(this.drcCountPlateauChecks=0);this.drcCountPlateauChecks+=1,this.drcCountPlateauChecks\u003e=2\u0026\u0026(this.solved=!0)}}_step(){let t=this.outputHdRoutes,e=this.outputSnapshot??this.getSnapshot(t);const n=mD(e);if(this.legacyCleanCheckpoint\u0026\u0026n\u003e0)return void this.finishAtLegacyCleanCheckpoint();if(!this.legacyCleanCheckpoint\u0026\u00260===n\u0026\u0026e.errors.some(uD)\u0026\u0026(this.legacyCleanCheckpoint={routes:aD(kk(t)),snapshot:e}),void 0===this.initialDrcIssueCount){this.inputSnapshot=e,this.initialDrcIssueCount=e.count,this.initialRepairDrcIssueCount=this.getRepairIssueCount(e);const n=_D(e.errors);this.initialLowCountErrorsHaveMovableTraces=this.initialRepairDrcIssueCount\u003e0\u0026\u0026this.initialRepairDrcIssueCount\u003c=3\u0026\u0026n.every(t=\u003evoid 0!==bD(t,e.traceRouteIndexById)),this.initialLowCountErrorsHaveMovableTraces\u0026\u0026(e=this.getSnapshot(t)),this.bestDrcIssueCountSeen=this.getRepairIssueCount(e),this.bestDrcIssueScoreSeen=this.getRepairIssueScore(e),this.increaseMaxIterationsForDrcIssueCount(this.getRepairIssueCount(e))}if(0===e.count)return void this.acceptSolvedRoutes(t,e);let o=this.getRepairIssueCount(e),i=this.getRepairIssueScore(e),r=this.getViaIssueCount(e);const s=e.errors.filter(t=\u003eBoolean(dD(t)));if(0===s.length)return void this.acceptSolvedRoutes(t,e);const a=(c=this.effort,Math.max(1,Math.round(3*Math.max(1,c))));var c;let l=0,d=0,h=!1,u=!1,p=!1;const m=_D(s),g=this.enableTargetedErrorSweep?m.find(t=\u003e\"pcb_via_clearance_error\"===t.type\u0026\u0026\"same_net\"===t.pcb_via_pair_net_relation):void 0,f=this.enableTargetedErrorSweep\u0026\u0026(this.iterations-1)%8==0,y=g??(f?m.find(t=\u003e\"pcb_via_clearance_error\"===t.type):void 0),_=y?[y,...m.filter(t=\u003et!==y)]:m,b=Math.min(_.length,Math.max(1,Math.ceil(this.effort))),x=y?0:this.errorCursor%_.length,v=this.enableTargetedErrorSweep?((t,e)=\u003e{const n=Math.max(2,Math.round(12*Math.max(1,e)));return t.filter(t=\u003e\"pcb_trace_error\"===Fk(t)).slice(0,n)})(s,this.effort):[],S=o\u003c=1||this.initialLowCountErrorsHaveMovableTraces,I=!this.initialLowCountErrorsHaveMovableTraces\u0026\u0026o\u003c=8\u0026\u0026this.srj.layerCount\u003e1,C=y?[]:s.filter(t=\u003e\"pcb_pad_trace_clearance_error\"===t.type||(this.enableSafeTraceLayerMoves||S||I)\u0026\u0026\"pcb_trace_error\"===t.type),P=C.map((t,e)=\u003eC[(this.padTopologyErrorCursor+e)%C.length]);for(const n of this.enableSafeTraceLayerMoves||this.enableViaInPadLayerMoves?P:[]){const s=!this.enableSafeTraceLayerMoves||d\u003e=a,c=!this.enableViaInPadLayerMoves||l\u003e=a;if(u||s\u0026\u0026c)break;let p;this.padTopologyErrorCursor=(C.indexOf(n)+1)%C.length;const m=\"string\"==typeof n.pcb_trace_error_id?n.pcb_trace_error_id:\"string\"==typeof n.pcb_trace_id?n.pcb_trace_id:void 0,g=bD(n,e.traceRouteIndexById),f=TD(n,e.traceRouteIndexById);if(this.enableTraceViaOwnerTargeting\u0026\u0026void 0!==g\u0026\u0026Array.isArray(n.pcb_via_ids)\u0026\u00261===n.pcb_via_ids.length\u0026\u0026l\u003ca){const o=kk(t);if(AD(this.srj,o,n,e.traceRouteIndexById,g,this.connMap)){const t=aD(o),n=this.getSnapshot(t),i=this.getViaIssueCount(n);l+=1,this.candidateAttempts+=1,i\u003c=r\u0026\u0026yD(n,e)\u0026\u0026(p={routes:t,snapshot:n,viaIssueCount:i,usesViaInPad:!1})}}if(this.enableSafeTraceLayerMoves\u0026\u0026void 0!==g){const o=f??[g],i=o.length*this.srj.layerCount*Mz.length,s=o.length*this.srj.layerCount*ID,c=i+s,l=Bk(n),h=l?0:i,u=l?s:0;let y=m?this.safeTraceLayerCursorByErrorId.get(m)??0:0,_=0;for(;d\u003ca\u0026\u0026_\u003cc;){const i=y;y=(y+1)%c,_+=1;const a=i\u003e=h\u0026\u0026i\u003ch+s,l=i-(a?h:u),m=l%o.length,g=Math.floor(l/o.length),f=g%this.srj.layerCount,b=a?\"full\":Mz[Math.floor(g/this.srj.layerCount)%Mz.length],x=a?Math.floor(g/this.srj.layerCount):0,v=o[m];let S=!1;for(const o of[!1,!0]){const i=Lk(t,[v]);if(!MD(this.srj,i,n,v,f,b,this.connMap,x,o))continue;const s=cD(i,[v]);S=!0,this.candidateAttempts+=1;const a=this.getSnapshot(s),c=this.getViaIssueCount(a),l=p?.snapshot??e;c\u003c=(p?.viaIssueCount??r)\u0026\u0026(yD(a,l)||void 0!==p\u0026\u0026gD(a)===gD(l)\u0026\u0026a.count\u003cl.count)\u0026\u0026(p={routes:s,snapshot:a,viaIssueCount:c,usesViaInPad:!1})}S\u0026\u0026(d+=1)}m\u0026\u0026this.safeTraceLayerCursorByErrorId.set(m,y)}if(this.enableSafeTraceLayerMoves\u0026\u0026I\u0026\u0026m\u0026\u0026f){let o=this.traceLayerCorridorCursorByErrorId.get(m)??0,i=0;for(;l\u003ca\u0026\u0026i\u003cIz.length;){const s=Iz[o%Iz.length];o+=1,i+=1;const a=f[s.routeSide],c=t[a]?.route[0]?.z;if(void 0===c)continue;const d=(c+1)%this.srj.layerCount,h=Lk(t,[a]);if(!zD(this.srj,h,n,a,d,s.normalDirectionSign,s.tangentDirectionSign,s.reverseEndpointOffsets))continue;const u=cD(h,[a]);l+=1,this.candidateAttempts+=1;const m=this.getSnapshot(u),g=this.getViaIssueCount(m),y=p?.snapshot??e;g\u003c=(p?.viaIssueCount??r)\u0026\u0026yD(m,y)\u0026\u0026(p={routes:u,snapshot:m,viaIssueCount:g,usesViaInPad:!1})}this.traceLayerCorridorCursorByErrorId.set(m,o)}if(this.enableSafeTraceLayerMoves\u0026\u0026m\u0026\u0026(this.initialLowCountErrorsHaveMovableTraces\u0026\u0026(f||void 0!==g)||!this.initialLowCountErrorsHaveMovableTraces\u0026\u0026f)){const s=this.initialLowCountErrorsHaveMovableTraces?Pz:S?[...Cz,...Sz]:Cz,c=f??[g];let d=this.tracePairDetourCursorByErrorId.get(m)??0,u=0;for(;l\u003ca\u0026\u0026u\u003cs.length;){const m=s[d%s.length];d+=1,u+=1;const g=c[m.routeSide];if(void 0===g)continue;const f=this.initialLowCountErrorsHaveMovableTraces\u0026\u0026n.worst_contact_center?{...n,center:n.worst_contact_center,message:n.worst_contact_message??n.message,actual_clearance:n.worst_actual_clearance??n.actual_clearance}:n;if(\"displacementChain\"===m.kind){const n=kk(t),s=RD(this.srj,n,f,e.traceRouteIndexById,m.routeSide);if(!s)continue;h=!0,l+=1,this.candidateAttempts+=1;let c=aD(n),d=this.getSnapshot(c),u=this.getViaIssueCount(d),g=this.getRepairIssueCount(d);if(g\u003e0\u0026\u0026l\u003ca){const t=kk(c);let e=!1;for(const n of d.errors)e=AD(this.srj,t,n,d.traceRouteIndexById,s.movedRouteIndex,this.connMap)||e;if(e){l+=1,this.candidateAttempts+=1;const e=aD(t),n=this.getSnapshot(e),o=this.getViaIssueCount(n);jD(n,o,g,this.getRepairIssueScore(d),u,d)\u0026\u0026(c=e,d=n,u=o,g=this.getRepairIssueCount(d))}}const y=p?this.getRepairIssueCount(p.snapshot):o,_=p?this.getRepairIssueScore(p.snapshot):i,b=p?.viaIssueCount??r;if(u\u003c=b\u0026\u0026jD(d,u,y,_,b,p?.snapshot??e)\u0026\u0026(p={routes:c,snapshot:d,viaIssueCount:u,usesViaInPad:!1}),0===g)break;continue}const y=Lk(t,[g]);if(!(\"segment\"===m.kind?DD(y,f,g,m.halfSpan,m.offset,m.directionSign):\"span\"===m.kind?FD(this.srj,y,f,g,m.spanExpansion,m.offset,m.directionSign):BD(this.srj,y,f,g,m.spanExpansion,{x:f.center.x+m.dx,y:f.center.y+m.dy})))continue;const _=cD(y,[g]);h=!0,l+=1,this.candidateAttempts+=1;const b=this.getSnapshot(_),x=this.getViaIssueCount(b),v=p?this.getRepairIssueCount(p.snapshot):o,S=p?this.getRepairIssueScore(p.snapshot):i,I=p?.viaIssueCount??r;(this.initialLowCountErrorsHaveMovableTraces?jD(b,x,v,S,I,p?.snapshot??e):x\u003c=I\u0026\u0026yD(b,p?.snapshot??e))\u0026\u0026(p={routes:_,snapshot:b,viaIssueCount:x,usesViaInPad:!1})}this.tracePairDetourCursorByErrorId.set(m,d)}for(const s of this.enableViaInPadLayerMoves?[\"start\",\"end\"]:[]){if(l\u003e=a)break;if(void 0===g)break;const c=Lk(t,[g]);if(!wD(this.srj,c,n,e.traceRouteIndexById,s,this.connMap,this.viaHoleDiameter))continue;const d=cD(c,[g]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const h=this.getSnapshot(d),u=this.getViaIssueCount(h),m=p?this.getRepairIssueCount(p.snapshot):o,f=p?this.getRepairIssueScore(p.snapshot):i;jD(h,u,m,f,p?.viaIssueCount??r,p?.snapshot??e)\u0026\u0026(p={routes:d,snapshot:h,viaIssueCount:u,usesViaInPad:!0})}const y=this.enableViaInPadLayerMoves?this.srj.layerCount:0;for(let s=0;s\u003cy\u0026\u0026!(l\u003e=a)\u0026\u0026void 0!==g;s+=1){const a=Lk(t,[g]);if(!ND(this.srj,a,n,e.traceRouteIndexById,s,this.connMap,this.viaHoleDiameter))continue;const c=cD(a,[g]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const d=this.getSnapshot(c),h=this.getViaIssueCount(d),u=p?this.getRepairIssueCount(p.snapshot):o,m=p?this.getRepairIssueScore(p.snapshot):i;jD(d,h,u,m,p?.viaIssueCount??r,p?.snapshot??e)\u0026\u0026(p={routes:c,snapshot:d,viaIssueCount:h,usesViaInPad:!0})}if(this.enableViaInPadLayerMoves\u0026\u0026S\u0026\u0026f){const s=this.iterations%2==0?[0,1]:[1,0],c=this.iterations%3;for(const d of s)for(let s=0;s\u003cthis.srj.layerCount\u0026\u0026!(l\u003e=a);s+=1){const a=f[d],h=Lk(t,[a]);if(!LD(this.srj,h,n,e.traceRouteIndexById,d,s,c,this.connMap,this.viaHoleDiameter))continue;const u=cD(h,[a]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const m=this.getSnapshot(u),g=this.getViaIssueCount(m),y=p?this.getRepairIssueCount(p.snapshot):o,_=p?this.getRepairIssueScore(p.snapshot):i;jD(m,g,y,_,p?.viaIssueCount??r,p?.snapshot??e)\u0026\u0026(p={routes:u,snapshot:m,viaIssueCount:g,usesViaInPad:!0})}}p\u0026\u0026(t=p.routes,e=p.snapshot,o=this.getRepairIssueCount(e),i=this.getRepairIssueScore(e),r=p.viaIssueCount,this.targetedForceAccepted=!0,p.usesViaInPad\u0026\u0026(this.viaInPadCandidatesAccepted+=1),u=!0)}if(!u\u0026\u0026v.length\u003e=2){const n=kk(t);let s=!1;for(const t of v)s=$D(this.srj,n,[t],e.traceRouteIndexById,1,this.connMap,!0,this.enableTargetedErrorSweep,!1,this.enableTraceViaOwnerTargeting)||s;if(s){const s=aD(n);l+=1,this.candidateAttempts+=1;const a=this.getSnapshot(s),c=this.getViaIssueCount(a);if(jD(a,c,o,i,r,e)\u0026\u0026(t=s,e=a,o=this.getRepairIssueCount(a),i=this.getRepairIssueScore(a),r=c,this.targetedForceAccepted=!0,u=!0,0===a.count))return void this.acceptSolvedRoutes(t,e)}}for(let n=0;n\u003cb\u0026\u0026l\u003ca\u0026\u0026!u;n+=1){const s=(x+n)%_.length,c=_[s];if(!c)continue;this.errorCursor=(s+1)%_.length;const d=1===o;for(const n of b_(this.effort)){if(l\u003e=a)break;const s=kk(t);if(!$D(this.srj,s,[c],e.traceRouteIndexById,n,this.connMap,!0,this.enableTargetedErrorSweep,d,this.enableTraceViaOwnerTargeting))continue;const h=aD(s);l+=1,this.candidateAttempts+=1;const p=this.getSnapshot(h),m=this.getViaIssueCount(p);if(jD(p,m,o,i,r,e)){if(t=h,e=p,o=this.getRepairIssueCount(p),i=this.getRepairIssueScore(p),r=m,this.targetedForceAccepted=!0,u=!0,0===p.count)return void this.acceptSolvedRoutes(t,e);break}}if(u)break}const M=t.length\u003c=120,N=(w=s.length,Math.max(16,Math.min(64,2*w)));var w;const T=this.enableLargeBoardBroadFallback\u0026\u0026this.MAX_ITERATIONS\u003e=192\u0026\u0026!M\u0026\u0026this.stalledIterations\u003e0\u0026\u0026this.stalledIterations%N===0;if(this.enableBroadFallback\u0026\u0026!u\u0026\u0026(M||this.effort\u003e=2\u0026\u0026this.stalledIterations\u003e=2||T)){p=T;for(const n of[1,2]){const s=iD(this.srj,t,this.effort,n,this.connMap,void 0===this.drcEvaluator,!1);if(s===t)continue;const a=this.getSnapshot(s),c=this.getViaIssueCount(a);if(jD(a,c,o,i,r,e)\u0026\u0026(t=s,e=a,o=this.getRepairIssueCount(a),i=this.getRepairIssueScore(a),r=c,this.broadForceAccepted=!0,u=!0,0===a.count))return void this.acceptSolvedRoutes(t,e)}}u?this.largeBoardBroadFallbackMisses=0:p\u0026\u0026(this.largeBoardBroadFallbackMisses+=1),this.outputHdRoutes=t,this.outputSnapshot=e,this.stalledIterations=u?0:this.stalledIterations+1,h||this.updateDrcCountPlateauState(e),this.updateStats(e),(this.solved||0===o)\u0026\u0026this.acceptSolvedRoutes(t,e)}tryFinalAcceptance(){const t=this.outputSnapshot??this.getSnapshot(this.outputHdRoutes);this.legacyCleanCheckpoint\u0026\u0026mD(t)\u003e0\u0026\u0026this.finishAtLegacyCleanCheckpoint()||this.acceptSolvedRoutes(this.outputHdRoutes,t)}getOutput(){return this.outputHdRoutes}visualize(){return super.visualize()}preview(){return this.visualize()}},wz=class extends kt{params;inputHdRoutes;guardedInputHdRoutes;broadMaxIterations;broadPassMultiplier;autoroutingDrcEngine;legacyDrcEvaluator;outputHdRoutes;phase=\"start\";inputSnapshot;baselineSolver;baselineSnapshot;broadInputSnapshot;broadSnapshot;broadSolver;safeTraceLayerInputRoutes;safeTraceLayerInputSnapshot;safeTraceLayerSolver;safeTraceLayerPhaseAccepted=!1;mixedSafeTraceLayerSolver;mixedSafeTraceLayerPhaseAccepted=!1;legacySafeTraceLayerRoutes;legacySafeTraceLayerSnapshot;legacySafeTraceLayerSelectedSolver;viaInPadSolver;portfolioSelectedSolver;selectedSolver;referenceInputDrcIssueCount;referenceCandidateDrcIssueCount;referenceCandidateRolledBack=!1;mixedReferenceInputDrcIssueCount;mixedReferenceCandidateDrcIssueCount;referenceInputSnapshot;constructor(t){if(super(),!Number.isFinite(t.broadPassMultiplier))throw new Error(\"broadPassMultiplier must be a finite number\");if(t.broadPassMultiplier\u003c=0)throw new Error(\"broadPassMultiplier must be greater than zero\");if(!Number.isInteger(t.broadMaxIterations))throw new Error(\"broadMaxIterations must be an integer\");if(t.broadMaxIterations\u003c=0)throw new Error(\"broadMaxIterations must be greater than zero\");if(void 0!==t.viaInPadMaxIterations\u0026\u0026!Number.isInteger(t.viaInPadMaxIterations))throw new Error(\"viaInPadMaxIterations must be an integer\");if(void 0!==t.viaInPadMaxIterations\u0026\u0026t.viaInPadMaxIterations\u003c=0)throw new Error(\"viaInPadMaxIterations must be greater than zero\");this.autoroutingDrcEngine=t.autoroutingDrcEngine??(t.drcEvaluator?void 0:new s_(t.srj,{connMap:t.connMap,traceClearance:t.srj.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:t.srj.minTraceToPadEdgeClearance??rk.viaClearance,includeTraceViaOwnerMetadata:t.enableTraceViaOwnerTargeting??!1})),this.legacyDrcEvaluator=e=\u003e{const n=t.drcEvaluator?.evaluateLegacy??t.drcEvaluator,o=n?n(e):this.autoroutingDrcEngine.evaluateLegacy(e.traces),i=Array.isArray(o)?o:o.errors,r=Array.isArray(o)?o:o.errorsWithCenters??o.errors;return{errors:i.filter(t=\u003e!uD(t)),errorsWithCenters:r.filter(t=\u003e!uD(t))}},this.params={...t,autoroutingDrcEngine:this.autoroutingDrcEngine},this.inputHdRoutes=t.hdRoutes,this.guardedInputHdRoutes=aD(kk(t.hdRoutes)),this.broadMaxIterations=t.broadMaxIterations,this.broadPassMultiplier=t.broadPassMultiplier,this.outputHdRoutes=t.hdRoutes,this.params.referenceDrcEvaluator\u0026\u0026(this.referenceInputSnapshot=this.getReferenceDrcSnapshot(this.inputHdRoutes))}getConstructorParams(){return[{...this.params,hdRoutes:this.inputHdRoutes}]}stepBranch(t,e){if(this.activeSubSolver=t,t.step(),t.failed)throw new Error(`${e} DRC repair branch failed: ${t.error}`)}getReferenceDrcSnapshot(t){const e={traces:[],srj:this.params.srj,routes:t,hdRoutes:t},n=this.params.referenceDrcEvaluator?.getCachedResult?.(e);if(n){const t=Array.isArray(n)?n:n.errors;return{errors:t,count:t.length}}return Wk(this.params.srj,t,this.params.referenceDrcEvaluator,this.params.connMap,this.autoroutingDrcEngine)}finishWithOutput(t,e,n){let o=t,i=e;if(this.params.referenceDrcEvaluator){const t=this.referenceInputSnapshot,e=this.getReferenceDrcSnapshot(o);this.referenceInputDrcIssueCount=t.count,this.referenceCandidateDrcIssueCount=e.count,(e.count\u003et.count||e.count===t.count\u0026\u0026((t,e)=\u003e{const n=new Set(e.map(pD));return t.some(t=\u003e!n.has(pD(t)))})(e.errors,t.errors))\u0026\u0026(o=this.guardedInputHdRoutes,i=this.inputSnapshot,this.referenceCandidateRolledBack=!0)}this.outputHdRoutes=o,this.selectedSolver=n,this.activeSubSolver=null,this.phase=\"done\",this.progress=1,this.stats={...this.portfolioSelectedSolver?.stats??{},...n?.stats??{},finalDrcIssueCount:i.count,drcBranchPortfolioInitialDrcIssueCount:this.inputSnapshot?.count??e.count,drcBranchPortfolioBaselineDrcIssueCount:this.baselineSnapshot?.count??e.count,drcBranchPortfolioBroadInitialDrcIssueCount:this.broadInputSnapshot?.count,drcBranchPortfolioBroadFinalDrcIssueCount:this.broadSnapshot?.count,drcBranchPortfolioBroadMaxIterations:this.broadMaxIterations,drcBranchPortfolioBroadBranchAttempted:Boolean(this.broadSolver),drcBranchPortfolioBroadBranchAccepted:void 0!==this.portfolioSelectedSolver\u0026\u0026this.portfolioSelectedSolver===this.broadSolver,drcBranchPortfolioSafeTraceLayerPhaseAttempted:Boolean(this.safeTraceLayerSolver),drcBranchPortfolioSafeTraceLayerPhaseAccepted:this.safeTraceLayerPhaseAccepted,drcBranchPortfolioMixedSafeTraceLayerPhaseAttempted:Boolean(this.mixedSafeTraceLayerSolver),drcBranchPortfolioMixedSafeTraceLayerPhaseAccepted:this.mixedSafeTraceLayerPhaseAccepted,drcBranchPortfolioViaInPadPhaseAttempted:Boolean(this.viaInPadSolver),drcBranchPortfolioViaInPadMaxIterations:this.params.viaInPadMaxIterations,drcBranchPortfolioFinalNonViaPadDrcIssueCount:mD(i),drcBranchPortfolioReferenceInputDrcIssueCount:this.referenceInputDrcIssueCount,drcBranchPortfolioReferenceCandidateDrcIssueCount:this.referenceCandidateDrcIssueCount,drcBranchPortfolioReferenceCandidateRolledBack:this.referenceCandidateRolledBack,drcBranchPortfolioMixedReferenceInputDrcIssueCount:this.mixedReferenceInputDrcIssueCount,drcBranchPortfolioMixedReferenceCandidateDrcIssueCount:this.mixedReferenceCandidateDrcIssueCount},this.solved=!0}startBaselineBranch(){this.baselineSolver=new Nz({...this.params,hdRoutes:this.inputHdRoutes,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.baselineSolver,this.phase=\"baseline\"}startSafeTraceLayerPhase(t,e,n){this.portfolioSelectedSolver=n,this.params.enableSafeTraceLayerMoves?(this.safeTraceLayerInputRoutes=t,this.safeTraceLayerInputSnapshot=e,this.safeTraceLayerSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.safeTraceLayerSolver,this.phase=\"safeTraceLayer\"):this.startViaInPadPhase(t,e,n)}startViaInPadPhase(t,e,n){this.portfolioSelectedSolver=n;const o=this.params.enableViaInPadLayerMoves\u0026\u0026void 0!==this.params.viaInPadDrcEvaluator;e.errors.some(uD)||o?(this.viaInPadSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.params.viaInPadDrcEvaluator??this.params.drcEvaluator,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:this.params.enableViaInPadLayerMoves}),this.activeSubSolver=this.viaInPadSolver,this.phase=\"viaInPad\"):this.finishWithOutput(t,e,n)}startMixedSafeTraceLayerPhase(t,e,n){this.legacySafeTraceLayerRoutes=t,this.legacySafeTraceLayerSnapshot=e,this.legacySafeTraceLayerSelectedSolver=n,this.mixedSafeTraceLayerSolver=new Nz({...this.params,hdRoutes:this.safeTraceLayerInputRoutes,drcEvaluator:this.params.drcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.mixedSafeTraceLayerSolver,this.phase=\"mixedSafeTraceLayer\"}startBroadBranch(){const t=iD(this.params.srj,this.inputHdRoutes,this.params.effort??1,this.broadPassMultiplier,this.params.connMap);this.broadInputSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),yD(this.broadInputSnapshot,this.baselineSnapshot)?(this.broadSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.broadMaxIterations,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.broadSolver,this.phase=\"broad\"):this.startSafeTraceLayerPhase(this.baselineSolver.getOutput(),this.baselineSnapshot,this.baselineSolver)}_step(){if(\"start\"===this.phase)return this.inputSnapshot=Wk(this.params.srj,this.inputHdRoutes,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),0===mD(this.inputSnapshot)?void this.startViaInPadPhase(this.inputHdRoutes,this.inputSnapshot):void this.startBaselineBranch();if(\"baseline\"===this.phase){if(this.stepBranch(this.baselineSolver,\"baseline\"),!this.baselineSolver.solved)return;const t=this.baselineSolver.getOutput();return this.baselineSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),0===mD(this.baselineSnapshot)?void this.startViaInPadPhase(t,this.baselineSnapshot,this.baselineSolver):void(this.params.enableSafeTraceLayerMoves\u0026\u0026this.baselineSnapshot.count\u003c=3?this.startSafeTraceLayerPhase(t,this.baselineSnapshot,this.baselineSolver):this.startBroadBranch())}if(\"broad\"===this.phase){if(this.stepBranch(this.broadSolver,\"broad\"),!this.broadSolver.solved)return;const t=this.broadSolver.getOutput();return this.broadSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),yD(this.broadSnapshot,this.baselineSnapshot)?void this.startSafeTraceLayerPhase(t,this.broadSnapshot,this.broadSolver):void this.startSafeTraceLayerPhase(this.baselineSolver.getOutput(),this.baselineSnapshot,this.baselineSolver)}if(\"safeTraceLayer\"===this.phase){if(this.stepBranch(this.safeTraceLayerSolver,\"safe trace-layer\"),!this.safeTraceLayerSolver.solved)return;const t=this.safeTraceLayerSolver.getOutput(),e=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),n=hD(this.safeTraceLayerInputSnapshot,!1),o=hD(e,!1);this.safeTraceLayerPhaseAccepted=o\u003c=n\u0026\u0026jD(e,o,this.safeTraceLayerInputSnapshot.count,this.safeTraceLayerInputSnapshot.issueScore,n,this.safeTraceLayerInputSnapshot);const i=this.safeTraceLayerPhaseAccepted?t:this.safeTraceLayerInputRoutes,r=this.safeTraceLayerPhaseAccepted?e:this.safeTraceLayerInputSnapshot,s=this.safeTraceLayerPhaseAccepted?this.safeTraceLayerSolver:this.portfolioSelectedSolver;return r.count\u003e0\u0026\u0026!this.broadInputSnapshot?void this.startBroadBranch():mD(r)\u003e0\u0026\u0026this.safeTraceLayerInputSnapshot.errors.some(uD)?void this.startMixedSafeTraceLayerPhase(i,r,s):void this.startViaInPadPhase(i,r,s)}if(\"mixedSafeTraceLayer\"===this.phase){if(this.stepBranch(this.mixedSafeTraceLayerSolver,\"mixed safe trace-layer\"),!this.mixedSafeTraceLayerSolver.solved)return;const t=this.mixedSafeTraceLayerSolver.getOutput(),e=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),n=mD(e)\u003c=mD(this.legacySafeTraceLayerSnapshot);let o=!0;if(this.params.referenceDrcEvaluator){const e=this.getReferenceDrcSnapshot(this.legacySafeTraceLayerRoutes),n=this.getReferenceDrcSnapshot(t);this.mixedReferenceInputDrcIssueCount=e.count,this.mixedReferenceCandidateDrcIssueCount=n.count,o=n.count\u003c=e.count}return this.mixedSafeTraceLayerPhaseAccepted=n\u0026\u0026o,void this.startViaInPadPhase(this.mixedSafeTraceLayerPhaseAccepted?t:this.legacySafeTraceLayerRoutes,this.mixedSafeTraceLayerPhaseAccepted?e:this.legacySafeTraceLayerSnapshot,this.mixedSafeTraceLayerPhaseAccepted?this.mixedSafeTraceLayerSolver:this.legacySafeTraceLayerSelectedSolver)}if(\"viaInPad\"===this.phase){if(this.stepBranch(this.viaInPadSolver,\"via-in-pad\"),!this.viaInPadSolver.solved)return;const t=this.viaInPadSolver.getOutput(),e=Wk(this.params.srj,t,this.params.viaInPadDrcEvaluator??this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine);this.finishWithOutput(t,e,this.viaInPadSolver)}}getOutput(){return this.outputHdRoutes}visualize(){const t=this.activeSubSolver??this.selectedSolver;return t?.visualize()??super.visualize()}preview(){const t=this.activeSubSolver??this.selectedSolver;return t?.preview()??this.visualize()}},Tz=class extends si{constructor(t,e,n=Number.POSITIVE_INFINITY,o=.010000000000000002){super(),this.nodes=t,this.maxNodeDimension=e,this.maxNodeRatio=n,this.minNodeArea=o,this.outputNodes=[]}nodes;maxNodeDimension;maxNodeRatio;minNodeArea;outputNodes;getSolverName(){return\"NodeDimensionSubdivisionSolver\"}getSubdivisionGrid(t){const e=Number.isFinite(this.maxNodeDimension)\u0026\u0026this.maxNodeDimension\u003e0,n=Number.isFinite(this.maxNodeRatio)\u0026\u0026this.maxNodeRatio\u003e0;let o=e?Math.max(1,Math.ceil(t.width/this.maxNodeDimension)):1,i=e?Math.max(1,Math.ceil(t.height/this.maxNodeDimension)):1;if(n\u0026\u0026t.width\u003e0\u0026\u0026t.height\u003e0)for(;;){const e=t.width/o,n=t.height/i;if((e\u003e=n?e/n:n/e)\u003c=this.maxNodeRatio)break;e\u003e=n?o++:i++}return{cols:o,rows:i}}shouldRemoveNode(t){const e=Number.isFinite(this.minNodeArea)\u0026\u0026this.minNodeArea\u003e0;if(!Number.isFinite(t.width)||!Number.isFinite(t.height))return!0;if(!e||t.width*t.height\u003e=this.minNodeArea)return!1;if(Math.min(t.width,t.height)\u003c.002)return!0;if(t._containsTarget)return!1;let n=0;for(const e of this.nodes)if(e.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026t.availableZ.some(t=\u003ee.availableZ.includes(t))\u0026\u0026li(t,e)){if(e._containsTarget)return!1;if(n++,n\u003e=2)return!1}return!0}subdivideNode(t){if(this.shouldRemoveNode(t))return[];const{cols:e,rows:n}=this.getSubdivisionGrid(t);if(1===e\u0026\u00261===n)return[t];const o=t.width/e,i=t.height/n,r=t.center.x-t.width/2,s=t.center.y-t.height/2,a=[];for(let c=0;c\u003cn;c++)for(let n=0;n\u003ce;n++)a.push({...t,capacityMeshNodeId:`${t.capacityMeshNodeId}__sub_${c}_${n}`,center:{x:r+o*(n+.5),y:s+i*(c+.5)},width:o,height:i,availableZ:[...t.availableZ]});return a}_step(){const t=this.nodes.length;let e=0,n=0,o=0;for(const t of this.nodes){const i=!Number.isFinite(t.width)||!Number.isFinite(t.height),r=this.subdivideNode(t);0!==r.length?(r.length\u003e1\u0026\u0026e++,this.outputNodes.push(...r)):i?o++:n++}this.stats={inputNodeCount:t,outputNodeCount:this.outputNodes.length,subdividedNodeCount:e,removedSmallNodeCount:n,removedInvalidNodeCount:o,maxNodeDimension:this.maxNodeDimension,maxNodeRatio:this.maxNodeRatio,minNodeArea:this.minNodeArea},this.solved=!0}visualize(){return{rects:this.outputNodes.map(t=\u003e({center:t.center,width:t.width,height:t.height,label:`${t.capacityMeshNodeId}\\n${t.width.toFixed(2)}x${t.height.toFixed(2)}`,layer:`z${t.availableZ.join(\",\")}`,fill:\"rgba(0, 200, 255, 0.08)\",stroke:\"rgba(0, 120, 180, 0.5)\"}))}}},Rz=t=\u003e{const e=[...new Set(t.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0))].sort((t,e)=\u003et-e);if(0!==e.length)return`z${e.join(\",\")}`},Ez=t=\u003e{const e=[];for(let n=0;n\u003c31;n++)t\u00261\u003c\u003cn\u0026\u0026e.push(n);return e},Az=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,Oz=t=\u003eAz(t)?{...t}:void 0===t?{}:{value:t},kz=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];if(Az(n)){if(\"string\"==typeof n.serializedRegionId)return n.serializedRegionId;if(\"string\"==typeof n.regionId)return n.regionId;if(\"string\"==typeof n.capacityMeshNodeId)return n.capacityMeshNodeId}return`region-${e}`},Lz=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];if(Az(n)){if(\"string\"==typeof n.serializedPortId)return n.serializedPortId;if(\"string\"==typeof n.portId)return(o=n.portId).includes(\"::\")?o.slice(0,o.indexOf(\"::\")):o}var o;return`port-${e}`},Dz=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return Az(n)\u0026\u0026\"string\"==typeof n.connectionId?n.connectionId:`route-${e}`},zz=(t,e)=\u003e{const n=Oz(t.topology.regionMetadata?.[e]);if(Az(n.center)||(n.center={x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),\"number\"!=typeof n.width\u0026\u0026(n.width=t.topology.regionWidth[e]),\"number\"!=typeof n.height\u0026\u0026(n.height=t.topology.regionHeight[e]),!Array.isArray(n.availableZ)){const o=t.topology.regionAvailableZMask?.[e]??0;0!==o\u0026\u0026(n.availableZ=Ez(o))}return n.layer=Rz(Array.isArray(n.availableZ)?n.availableZ:[])??Rz((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))??\"z0\",n},Fz=(t,e)=\u003e{const n=Oz(t.topology.portMetadata?.[e]);return\"number\"!=typeof n.x\u0026\u0026(n.x=t.topology.portX[e]),\"number\"!=typeof n.y\u0026\u0026(n.y=t.topology.portY[e]),\"number\"!=typeof n.z\u0026\u0026(n.z=t.topology.portZ[e]),n.layer=Rz([t.topology.portZ[e]])??\"z0\",n},Bz=(t,e,n)=\u003e{const o=(t.topology.incidentPortRegion[e]??[]).find(t=\u003et!==n);if(void 0===o)throw new Error(`Port ${e} is not incident to a region outside route region ${n}`);return o},jz=(t,e,n)=\u003e{const{orderedPortIds:o,orderedRegionIds:i}=((t,e,n)=\u003e{if(0===n.length)throw new Error(`Route ${e} has no solved segments`);const o=t.problem.routeStartPort[e],i=t.problem.routeEndPort[e],r=new Map;n.forEach((t,e)=\u003e{const n={...t,segmentIndex:e},o=r.get(t.fromPortId)??[];o.push(n),r.set(t.fromPortId,o);const i=r.get(t.toPortId)??[];i.push(n),r.set(t.toPortId,i)});const s=[o],a=[],c=(t,e,n)=\u003e{if(t===i)return!0;for(const o of r.get(t)??[]){if(e.has(o.segmentIndex))continue;const i=o.fromPortId===t?o.toPortId:o.fromPortId;if(!n.has(i)){if(e.add(o.segmentIndex),n.add(i),a.push(o.regionId),s.push(i),c(i,e,n))return!0;s.pop(),a.pop(),n.delete(i),e.delete(o.segmentIndex)}}return!1};if(!c(o,new Set,new Set([o])))throw new Error(`Route ${e} is not a single ordered path from ${o} to ${i}`);return{orderedPortIds:s,orderedRegionIds:a}})(t,e,n),r=i[0],s=i[i.length-1];if(void 0===r||void 0===s)throw new Error(`Route ${e} could not determine endpoint regions`);const a=kz(t,Bz(t,o[0],r)),c=kz(t,Bz(t,o[o.length-1],s)),l=((t,e,n,o)=\u003e{const i=t.problem.routeMetadata?.[e];return{connectionId:Dz(t,e),startRegionId:(Az(i)\u0026\u0026\"string\"==typeof i.startRegionId?i.startRegionId:void 0)??n,endRegionId:(Az(i)\u0026\u0026\"string\"==typeof i.endRegionId?i.endRegionId:void 0)??o,mutuallyConnectedNetworkId:(Az(i)\u0026\u0026\"string\"==typeof i.mutuallyConnectedNetworkId?i.mutuallyConnectedNetworkId:void 0)??`net-${t.problem.routeNet[e]}`}})(t,e,a,c),d=o.map((e,n)=\u003e{const r={portId:Lz(t,e),g:n,h:0,f:n,hops:n,ripRequired:!1,nextRegionId:n\u003ci.length?kz(t,i[n]):l.endRegionId};return n\u003e0\u0026\u0026(r.lastPortId=Lz(t,o[n-1]),r.lastRegionId=kz(t,i[n-1])),r});return{connection:l,solvedRoute:{connection:l,path:d,requiredRip:!1}}},$z=t=\u003e{if(!t.solved||t.failed)throw new Error(\"convertToSerializedHyperGraph requires a solved, non-failed solver\");const{topology:e}=t,n=(t=\u003e{const e=Array.from({length:t.problem.routeCount},()=\u003e[]);return t.state.regionSegments.forEach((t,n)=\u003e{for(const[o,i,r]of t)e[o].push({regionId:n,fromPortId:i,toPortId:r})}),e})(t),o=Array.from({length:e.regionCount},(n,o)=\u003e{const i=t.state.regionSegments[o].map(([e,n,o])=\u003e({regionPort1Id:Lz(t,n),regionPort2Id:Lz(t,o),connectionId:Dz(t,e)}));return{regionId:kz(t,o),pointIds:e.regionIncidentPorts[o].map(e=\u003eLz(t,e)),d:zz(t,o),...i.length\u003e0\u0026\u0026{assignments:i}}}),i=Array.from({length:e.portCount},(n,o)=\u003e{const[i,r]=e.incidentPortRegion[o]??[];if(void 0===i||void 0===r)throw new Error(`Port ${o} is missing incident regions`);return{portId:Lz(t,o),region1Id:kz(t,i),region2Id:kz(t,r),d:Fz(t,o)}}),r=n.map((e,n)=\u003ejz(t,n,e));return{regions:o,ports:i,connections:r.map(({connection:t})=\u003et),solvedRoutes:r.map(({solvedRoute:t})=\u003et)}},Yz=.3,Xz=t=\u003et\u003e0\u0026\u0026!(t\u0026t-1),Vz=(t,e,n,o,i,r=0,s=.3,a=0)=\u003e(2*e+1*n+1*o)*(s+.15)**2*(1+i/5)/t+(Xz(r)?10*e:0)+a*(i/Wz(r))**2*.1**2/t,Wz=t=\u003e{if(0===t)return 2;let e=t\u003e\u003e\u003e0,n=0;for(;0!==e;)n+=1\u0026e,e\u003e\u003e\u003e=1;return n},Hz=(t,e,n,o,i,r)=\u003e{const{netIds:s,lesserAngles:a,greaterAngles:c,layerMasks:l}=t;let d=0,h=0;for(let t=0;t\u003cs.length;t++){if(e===s[t])continue;(n\u003ca[t]\u0026\u0026a[t]\u003co)!==(n\u003cc[t]\u0026\u0026c[t]\u003co)\u0026\u0026(0!==(i\u0026l[t])?d++:h++)}return[d,h,r]},Gz=(t,e,n)=\u003e{const o=t.routeStartPort[e],i=t.routeEndPort[e],r=new Map;for(const{fromPortId:t,toPortId:e}of n){const n=r.get(t)??new Set;n.add(e),r.set(t,n);const o=r.get(e)??new Set;o.add(t),r.set(e,o)}const s=new Set,a=[o];for(;a.length\u003e0;){const t=a.pop();if(!s.has(t)){s.add(t);for(const e of r.get(t)??[])a.push(e)}}if(!s.has(i))throw new Error(`Initial assignments for route ${e} do not connect ${o} to ${i}`);if(n.some(({fromPortId:t,toPortId:e})=\u003e!s.has(t)||!s.has(e)))throw new Error(`Initial assignments for route ${e} contain disconnected segments`)},Uz=({topology:t,problem:e,state:n,routeSuccessCountByRouteId:o,appendSegmentToRegionCache:i})=\u003e{const r=e.initialAssignments??[];if(0===r.length)return;const s=new Map;for(const n of r){const{routeId:o,regionId:i,fromPortId:r,toPortId:a}=n;if(!Number.isInteger(o)||o\u003c0||o\u003e=e.routeCount)throw new Error(`Initial assignment references invalid route ${o}`);if(!Number.isInteger(i)||i\u003c0||i\u003e=t.regionCount)throw new Error(`Initial assignment references invalid region ${i}`);for(const e of[r,a]){if(!Number.isInteger(e)||e\u003c0||e\u003e=t.portCount)throw new Error(`Initial assignment references invalid port ${e}`);if(!t.incidentPortRegion[e]?.includes(i))throw new Error(`Initial assignment port ${e} is not incident to region ${i}`)}const c=s.get(o)??[];c.push(n),s.set(o,c)}for(const[t,n]of s)Gz(e,t,n);const a=new Set(s.keys());for(const{routeId:t,regionId:o,fromPortId:s,toPortId:a}of r){const r=e.routeNet[t];for(const t of[s,a]){const e=n.portAssignment[t];if(-1!==e\u0026\u0026e!==r)throw new Error(`Initial assignment port ${t} is assigned to multiple nets`);n.portAssignment[t]=r}n.currentRouteNetId=r,n.regionSegments[o].push([t,s,a]),i(o,s,a)}n.currentRouteNetId=void 0,n.unroutedRoutes=n.unroutedRoutes.filter(t=\u003e!a.has(t));for(const t of a)o[t]=1;return{initialAssignmentCount:r.length,initiallyRoutedRouteCount:a.size}},Zz=class{constructor(t,e){this.items=t,this.compare=e}items;compare;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0}queue(t){this.items.push(t),this.siftUp(this.items.length-1)}dequeue(){const t=this.items[0];if(void 0===t)return;const e=this.items.pop();return this.items.length\u003e0\u0026\u0026(this.items[0]=e,this.siftDown(0)),t}siftUp(t){let e=t;for(;e\u003e0;){const t=e-1\u003e\u003e1,n=this.items[t],o=this.items[e];if(this.compare(n,o)\u003c=0)return;this.items[t]=o,this.items[e]=n,e=t}}siftDown(t){let e=t;const n=this.items.length;for(;;){const t=2*e+1;if(t\u003e=n)return;const o=t+1;let i=t;o\u003cn\u0026\u0026this.compare(this.items[o],this.items[t])\u003c0\u0026\u0026(i=o);const r=this.items[e],s=this.items[i];if(this.compare(r,s)\u003c=0)return;this.items[e]=s,this.items[i]=r,e=i}}},qz=(t,e)=\u003e{const n=[...t],o=(t=\u003e{let e=t\u003e\u003e\u003e0;return()=\u003e{e+=1831565813;let t=e;return t=Math.imul(t^t\u003e\u003e\u003e15,1|t),t^=t+Math.imul(t^t\u003e\u003e\u003e7,61|t),((t^t\u003e\u003e\u003e14)\u003e\u003e\u003e0)/4294967296}})(e);for(let t=n.length-1;t\u003e0;t--){const e=Math.floor(o()*(t+1));[n[t],n[e]]=[n[e],n[t]]}return n},Jz=(t,e)=\u003et.routeMetadata?.[e],Kz=t=\u003et?.simpleRouteConnection?.pointsToConnect?.map(({pointId:t})=\u003e\"string\"==typeof t?t:null).filter(t=\u003enull!==t)??[],Qz=(t,e)=\u003e{const n=Jz(t,e)?.connectionId;return\"string\"==typeof n?n:`route-${e}`},tF=(t,e,n)=\u003e{const o=t.portEndpointNetIds[n];if(!o)return!1;for(const t of o)if(t!==e)return!0;return!1},eF=(t,e,n)=\u003e{const o=t.regionNetId[n];return-1!==o\u0026\u0026o!==e},nF=t=\u003e[...new Set(t.routeIds)].filter(e=\u003e!((t,e)=\u003e{const{topology:n,problem:o,problemSetup:i,portAssignment:r,maxPrecheckHops:s}=t,a=o.routeNet[e],c=o.routeStartPort[e],l=o.routeEndPort[e];if(c===l)return!0;const d=t.getStartingNextRegionId(e,c);if(void 0===d)return!1;const h=[{portId:c,nextRegionId:d}],u=new Set([c*n.regionCount+d]);for(let t=0;t\u003ch.length;t++){const e=h[t];if(!eF(o,a,e.nextRegionId))for(const t of n.regionIncidentPorts[e.nextRegionId]??[]){const c=r[t];if(tF(i,a,t))continue;if(t===l){if(-1!==c\u0026\u0026c!==a)continue;return!0}if(t===e.portId)continue;if(-1!==c\u0026\u0026c!==a)continue;if(0===o.portSectionMask[t])continue;const d=n.incidentPortRegion[t]??[],p=d[0]===e.nextRegionId?d[1]:d[0];if(void 0===p||eF(o,a,p))continue;const m=t*n.regionCount+p;if(!u.has(m)){if(u.size\u003e=s)return!0;u.add(m),h.push({portId:t,nextRegionId:p})}}}return!1})(t,e)).map(e=\u003et.getRouteSummary(e)),oF=t=\u003e{const e=new Array(t);for(let n=0;n\u003ct;n++)e[n]=n;return e},iF=\"rgba(220, 38, 38, 0.98)\",rF=\"rgba(220, 38, 38, 0.18)\",sF=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),aF=(t,e)=\u003e{const n=.005*t.topology.portZ[e];return{x:t.topology.portX[e]+n,y:t.topology.portY[e]+n}},cF=(t,e)=\u003eRz([t.topology.portZ[e]])??\"z0\",lF=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},dF=(t,e)=\u003e`z: ${t.topology.portZ[e]}`,hF=(t,e)=\u003e((t,e,n)=\u003e{const o=t.topology.portZ[e],i=t.topology.portZ[n];return o===i?`z: ${o}`:`z: ${o} -\u003e ${i}`})(t,t.problem.routeStartPort[e],t.problem.routeEndPort[e]),uF=(t,e)=\u003e`net: ${t.problem.routeNet[e]}`,pF=.05,mF={r:255,g:64,b:64,a:.72},gF=\"rgba(220, 38, 38, 0.98)\",fF=\"rgba(220, 38, 38, 0.12)\",yF=\"10 6\",_F=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),bF=t=\u003eMath.min(1,Math.max(0,t)),xF=(t,e,n)=\u003eMath.round(t+(e-t)*n),vF=({r:t,g:e,b:n,a:o})=\u003e`rgba(${t}, ${e}, ${n}, ${o})`,SF=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},IF=t=\u003e\"number\"==typeof t.centerRouteId,CF=(t,e)=\u003eIF(t)?e===t.centerRouteId?1:.5:1,PF=(t,e)=\u003e{const n=t.match(/^(rgba|hsla)\\((.*),\\s*([0-9]*\\.?[0-9]+)\\)$/);if(!n)return t;const[,o,i,r]=n,s=bF(Number(r)*e);return`${o}(${i}, ${Number(s.toFixed(3))})`},MF=(t,e,n=.8)=\u003e((t,e,n=.8)=\u003e{const o=`${t.problem.routeNet[e]}:${SF(t,e)}`;let i=0;for(let t=0;t\u003co.length;t++)i=17777*o.charCodeAt(t)+((i\u003c\u003c5)-i);return`hsla(${Math.abs(i)%360}, 70%, 50%, ${n})`})(t,e,n*CF(t,e)),NF=(t,e)=\u003e`net: ${t.problem.routeNet[e]}`,wF=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=n?.polygon;if(Array.isArray(o)\u0026\u0026o.length\u003e=3){const t=o.map(t=\u003et.x),e=o.map(t=\u003et.y);return{minX:Math.min(...t),maxX:Math.max(...t),minY:Math.min(...e),maxY:Math.max(...e)}}const i=n?.bounds;if(i\u0026\u0026\"number\"==typeof i.minX\u0026\u0026\"number\"==typeof i.maxX\u0026\u0026\"number\"==typeof i.minY\u0026\u0026\"number\"==typeof i.maxY)return i;const r=t.topology.regionWidth[e],s=t.topology.regionHeight[e],a=t.topology.regionCenterX[e],c=t.topology.regionCenterY[e];return{minX:a-r/2,maxX:a+r/2,minY:c-s/2,maxY:c+s/2}},TF=(t,e)=\u003e({x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),RF=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=Array.isArray(n?.availableZ)?n.availableZ.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0):[];if(o.length\u003e0)return Rz(o)??\"z0\";const i=Ez(t.topology.regionAvailableZMask?.[e]??0);if(i.length\u003e0)return Rz(i)??\"z0\";const r=[...new Set((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))].sort((t,e)=\u003et-e);return Rz(r)??\"z0\"},EF=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e],o=n?.existingRegionCost??0,i=t.state.regionCongestionCost[e]??0,r=t.problem.regionNetId[e];return _F(`region: region-${e}`,`net: ${-1===r?\"free\":`${r}`}`,t.getAdditionalRegionLabel(e),`cost: ${o.toFixed(3)}`,`congestion: ${i.toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},AF=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];return n?.isConnectionRegion?{r:255,g:100,b:255,a:.6}:n?.isThroughJumper?{r:100,g:200,b:100,a:.5}:n?.isPad?{r:255,g:200,b:100,a:.5}:\"bottom\"===n?.layer?{r:52,g:152,b:219,a:.08}:{r:200,g:200,b:255,a:.1}},OF=(t,e)=\u003e{const n=AF(t,e),o=bF(t.state.regionIntersectionCaches[e]?.existingRegionCost??0);return vF((r=mF,s=o**.8,{r:xF((i=n).r,r.r,s),g:xF(i.g,r.g,s),b:xF(i.b,r.b,s),a:Number((i.a+(r.a-i.a)*s).toFixed(3))}));var i,r,s},kF=(t,e)=\u003e{const n=((t,e)=\u003e({x:t.topology.portX[e],y:t.topology.portY[e]}))(t,e),o=.005*t.topology.portZ[e];return{x:n.x+o,y:n.y+o}},LF=kF,DF=(t,e)=\u003eRz([t.topology.portZ[e]])??\"z0\",zF=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},FF=(t,e,n)=\u003e{if(void 0!==n)return`net: ${t.problem.routeNet[n]}`;const o=t.state.portAssignment[e];if(o\u003e=0)return`net: ${o}`;const i=new Set;for(let n=0;n\u003ct.problem.routeCount;n++)t.problem.routeStartPort[n]!==e\u0026\u0026t.problem.routeEndPort[n]!==e||i.add(t.problem.routeNet[n]);return 0!==i.size?`net: ${Array.from(i).sort((t,e)=\u003et-e).join(\", \")}`:void 0},BF=(t,e)=\u003e`z: ${t.topology.portZ[e]}`,jF=(t,e,n)=\u003e{const o=t.topology.portZ[e],i=t.topology.portZ[n];return o===i?`z: ${o}`:`z: ${o} -\u003e ${i}`},$F=(t,e)=\u003ejF(t,t.problem.routeStartPort[e],t.problem.routeEndPort[e]),YF=(t,e,n)=\u003e_F(zF(t,e),((t,e)=\u003e{const n=t.topology.incidentPortRegion[e]?.[0],o=t.topology.incidentPortRegion[e]?.[1];return`connects: region-${n??\"?\"} \u003c-\u003e region-${o??\"?\"}`})(t,e),FF(t,e,n)),XF=(t,e,n,o)=\u003e{const i=t.topology.portZ[n];return i!==t.topology.portZ[o]?{strokeColor:PF(\"rgba(22, 160, 133, 0.95)\",CF(t,e)),strokeDash:\"2 4 2\"}:i\u003e0?{strokeColor:PF(\"rgba(52, 152, 219, 0.95)\",CF(t,e)),strokeDash:\"3 2\"}:{strokeColor:MF(t,e)}},VF=(t,e)=\u003e{for(let n=0;n\u003ct.state.regionSegments.length;n++){const o=t.state.regionSegments[n]??[];for(const[i,r,s]of o)e.lines.push({points:[kF(t,r),kF(t,s)],label:_F(`route: ${SF(t,i)}`,`region: region-${n}`,jF(t,r,s)),layer:DF(t,r),...XF(t,i,r,s)})}},WF=(t,e)=\u003e{const n=new Set;for(let o=0;o\u003ct.state.regionSegments.length;o++){const i=t.state.regionSegments[o]??[];for(const[o,r,s]of i)for(const i of[r,s]){const r=`${o}:${i}`;if(n.has(r))continue;n.add(r);const s=kF(t,i);e.points.push({x:s.x,y:s.y,color:MF(t,o,1),layer:DF(t,i),label:_F(`route: ${SF(t,o)}`,zF(t,i),FF(t,i,o),BF(t,i))})}}},HF=(t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++)if(t.problem.routeStartPort[n]===e||t.problem.routeEndPort[n]===e)return!0;return!1},GF=(t,e,n)=\u003e{const o=((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ce.length;o++)if(1===e[o])for(const e of t.topology.incidentPortRegion[o]??[])n.add(e);return n})(t,n),i=\"rgba(245, 158, 11, 0.95)\",r=\"rgba(245, 158, 11, 0.08)\";for(const n of o){const o=t.topology.regionMetadata?.[n],s=o?.polygon,a=wF(t,n),c=TF(t,n),l=a.maxX-a.minX,d=a.maxY-a.minY,h=RF(t,n),u=_F(\"section region\",EF(t,n));Array.isArray(s)\u0026\u0026s.length\u003e=3?e.polygons.push({points:s,fill:r,stroke:i,strokeWidth:2,layer:h,label:u}):e.rects.push({center:c,width:Math.max(l-pF,.05),height:Math.max(d-pF,.05),fill:r,stroke:i,layer:h,label:u})}for(let o=0;o\u003cn.length;o++)1===n[o]\u0026\u0026e.circles.push({center:LF(t,o),radius:.07,fill:\"rgba(251, 191, 36, 0.18)\",stroke:i,layer:DF(t,o),label:_F(YF(t,o),BF(t,o),\"section port\")})},UF=(t,e={})=\u003e{const n={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:\"Tiny HyperGraph\",coordinateSystem:\"cartesian\"},o=((t,e)=\u003e{if(!e?.highlightSectionMask)return;const n=e.sectionPortMask??t.problem.portSectionMask;if(n.length!==t.topology.portCount)return;let o=0,i=0;for(let t=0;t\u003cn.length;t++)1===n[t]?o+=1:i+=1;return 0!==o\u0026\u00260!==i?n:void 0})(t,e),i=(t=\u003e{const e=t.getStaticallyUnroutableRoutes();if(0!==e.length)return new Set(e.map(t=\u003et.routeId))})(t);for(let e=0;e\u003ct.topology.regionCount;e++){const o=t.topology.regionMetadata?.[e],i=o?.polygon,r=wF(t,e),s=TF(t,e),a=r.maxX-r.minX,c=r.maxY-r.minY,l=RF(t,e),d=vF(AF(t,e));Array.isArray(i)\u0026\u0026i.length\u003e=3?n.polygons.push({points:i,fill:d,layer:l}):n.rects.push({center:s,width:Math.max(a-pF,.05),height:Math.max(c-pF,.05),fill:OF(t,e),layer:l,label:EF(t,e)})}if(((t,e,n)=\u003e{for(let o=0;o\u003ct.problem.routeCount;o++){if(n\u0026\u0026!n.has(o))continue;const i=t.problem.routeStartPort[o],r=t.problem.routeEndPort[o],s=kF(t,i),a=kF(t,r),c=MF(t,o),l=SF(t,o),d=NF(t,o);e.points.push({x:s.x,y:s.y,color:c,layer:DF(t,i),label:_F(`route: ${l}`,d,\"endpoint: start\",zF(t,i),BF(t,i))}),e.points.push({x:a.x,y:a.y,color:c,layer:DF(t,r),label:_F(`route: ${l}`,d,\"endpoint: end\",zF(t,r),BF(t,r))})}})(t,n,i),0===t.iterations){for(const t of n.polygons)t.stroke=\"rgba(128, 128, 128, 0.5)\";for(const t of n.rects)t.stroke=\"rgba(128, 128, 128, 0.5)\"}if(0===t.iterations){for(let i=0;i\u003ct.topology.portCount;i++){const r=1===o?.[i];e.showOnlySectionPortsOnIdle\u0026\u0026!r||n.circles.push({center:LF(t,i),radius:.05,fill:t.topology.portZ[i]\u003e0?\"rgba(52, 152, 219, 0.55)\":\"rgba(128, 128, 128, 0.5)\",layer:DF(t,i),label:_F(YF(t,i),BF(t,i))})}if(i)((t,e)=\u003e{for(const n of t.getStaticallyUnroutableRoutes()){const{routeId:o,connectionId:i,startPortId:r,endPortId:s}=n,a=aF(t,r),c=aF(t,s),l=sF(`static reachability failed: ${i}`,uF(t,o),n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0,n.pointIds.length\u003e=2?`points: ${n.pointIds.join(\" -\u003e \")}`:void 0,hF(t,o));e.lines.push({points:[a,c],strokeColor:iF,strokeDash:\"8 4\",label:l}),e.circles.push({center:a,radius:.12,fill:rF,stroke:iF,layer:cF(t,r),label:sF(l,\"endpoint: start\",lF(t,r),dF(t,r))}),e.circles.push({center:c,radius:.12,fill:rF,stroke:iF,layer:cF(t,s),label:sF(l,\"endpoint: end\",lF(t,s),dF(t,s))})}})(t,n);else{const o=new Set;for(const e of t.state.regionSegments)for(const[t]of e)o.add(t);if(o.size\u003e0\u0026\u0026(VF(t,n),WF(t,n)),!1!==e.showInitialRouteHints){const e=new Set(t.state.unroutedRoutes);void 0!==t.state.currentRouteId\u0026\u0026e.add(t.state.currentRouteId),((t,e,n)=\u003e{for(let o=0;o\u003ct.problem.routeCount;o++){if(n\u0026\u0026!n.has(o))continue;const i=t.problem.routeStartPort[o],r=t.problem.routeEndPort[o],s=kF(t,i),a=kF(t,r),c={x:(s.x+a.x)/2,y:(s.y+a.y)/2};e.lines.push({points:[s,a],strokeColor:MF(t,o),strokeDash:\"3 3\",layer:DF(t,i),label:_F(SF(t,o),$F(t,o))}),e.points.push({x:c.x,y:c.y,color:MF(t,o,1),layer:DF(t,i),label:_F(SF(t,o),$F(t,o))})}})(t,n,e)}}}else VF(t,n),WF(t,n),(t=\u003eIF(t)\u0026\u0026!0===t.showUnassignedPortsInVisualization)(t)\u0026\u0026((t,e)=\u003e{for(let n=0;n\u003ct.topology.portCount;n++)t.state.portAssignment[n]\u003e=0||HF(t,n)||e.circles.push({center:LF(t,n),radius:.04,fill:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.2)\":\"rgba(128, 128, 128, 0.2)\",stroke:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.6)\":\"rgba(128, 128, 128, 0.6)\",layer:DF(t,n),label:_F(YF(t,n),BF(t,n),\"state: unassigned\")})})(t,n),IF(t)||(((t,e)=\u003e{const n=t.state.currentRouteId;if(void 0===n||t.solved)return;const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=kF(t,o),s=kF(t,i),a=MF(t,n),c=SF(t,n);e.lines.push({points:[r,s],strokeColor:a,strokeDash:\"10 5\",label:_F(c,$F(t,n))})})(t,n),((t,e)=\u003e{if(t.solved)return;const n=t.state.currentRouteId,o=t.state.candidateQueue.toArray().sort((t,e)=\u003et.f-e.f).slice(0,10);for(let i=0;i\u003co.length;i++){const r=o[i],s=kF(t,r.portId),a=0===i;e.points.push({x:s.x,y:s.y,color:a?\"green\":\"rgba(128, 128, 128, 0.25)\",layer:DF(t,r.portId),label:_F(YF(t,r.portId,n),BF(t,r.portId),`g: ${r.g.toFixed(2)}`,`h: ${r.h.toFixed(2)}`,`f: ${r.f.toFixed(2)}`)})}const i=o[0];if(!i)return;const r=[];let s=i;for(;s;)r.unshift(kF(t,s.portId)),s=s.prevCandidate;r.length\u003e1\u0026\u0026e.lines.push({points:r,strokeColor:void 0!==n?MF(t,n):\"rgba(0, 160, 120, 0.9)\"})})(t,n));o\u0026\u0026GF(t,n,o),((t,e)=\u003e{if(t.failed)for(const n of t.getNeverSuccessfullyRoutedRoutes()){const{routeId:o,connectionId:i,attempts:r,startPortId:s,endPortId:a}=n,c=NF(t,o),l=LF(t,s),d=LF(t,a),h=_F(`never routed: ${i}`,`attempts: ${r}`,c,n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0);e.lines.push({points:[{x:0,y:0},{x:l.x,y:l.y}],strokeColor:gF,strokeDash:yF,layer:DF(t,s),label:_F(h,\"origin guide\",\"endpoint: start\")}),e.circles.push({center:l,radius:1,fill:fF,stroke:gF,layer:DF(t,s),label:_F(h,\"endpoint: start\",zF(t,s),BF(t,s))}),e.lines.push({points:[{x:0,y:0},{x:d.x,y:d.y}],strokeColor:gF,strokeDash:yF,layer:DF(t,a),label:_F(h,\"origin guide\",\"endpoint: end\")}),e.circles.push({center:d,radius:1,fill:fF,stroke:gF,layer:DF(t,a),label:_F(h,\"endpoint: end\",zF(t,a),BF(t,a))})}})(t,n);const r=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1),s=o?o.reduce((t,e)=\u003et+Number(1===e),0):0;return n.title=[\"Tiny HyperGraph\",`iter=${t.iterations}`,`pending=${r}`,o?`sectionPorts=${s}`:void 0,i?`staticReachabilityFailed=${i.size}`:void 0,t.failed?\"failed\":t.solved?\"solved\":\"running\"].filter(Boolean).join(\" | \"),n},ZF=5e4,qF=()=\u003e({netIds:new Int32Array(0),lesserAngles:new Int32Array(0),greaterAngles:new Int32Array(0),layerMasks:new Int32Array(0),existingCrossingLayerIntersections:0,existingSameLayerIntersections:0,existingEntryExitLayerChanges:0,existingRegionCost:0,existingSegmentCount:0}),JF=t=\u003e({netIds:new Int32Array(t.netIds),lesserAngles:new Int32Array(t.lesserAngles),greaterAngles:new Int32Array(t.greaterAngles),layerMasks:new Int32Array(t.layerMasks),existingCrossingLayerIntersections:t.existingCrossingLayerIntersections,existingSameLayerIntersections:t.existingSameLayerIntersections,existingEntryExitLayerChanges:t.existingEntryExitLayerChanges,existingRegionCost:t.existingRegionCost,existingSegmentCount:t.existingSegmentCount}),KF=t=\u003e{return{portAssignment:new Int32Array(t.portAssignment),regionSegments:(e=t.regionSegments,e.map(t=\u003et.map(([t,e,n])=\u003e[t,e,n]))),regionIntersectionCaches:t.regionIntersectionCaches.map(JF),regionCongestionCost:new Float64Array(t.regionCongestionCost),ripCount:t.ripCount};var e},QF=(t,e)=\u003e{e\u0026\u0026(void 0!==e.minViaPadDiameter\u0026\u0026(t.minViaPadDiameter=e.minViaPadDiameter),void 0!==e.DISTANCE_TO_COST\u0026\u0026(t.DISTANCE_TO_COST=e.DISTANCE_TO_COST),void 0!==e.RIP_THRESHOLD_START\u0026\u0026(t.RIP_THRESHOLD_START=e.RIP_THRESHOLD_START),void 0!==e.RIP_THRESHOLD_END\u0026\u0026(t.RIP_THRESHOLD_END=e.RIP_THRESHOLD_END),void 0!==e.RIP_THRESHOLD_RAMP_ATTEMPTS\u0026\u0026(t.RIP_THRESHOLD_RAMP_ATTEMPTS=e.RIP_THRESHOLD_RAMP_ATTEMPTS),void 0!==e.RIP_CONGESTION_REGION_COST_FACTOR\u0026\u0026(t.RIP_CONGESTION_REGION_COST_FACTOR=e.RIP_CONGESTION_REGION_COST_FACTOR),void 0!==e.TRACE_DENSITY_COST_FACTOR\u0026\u0026(t.TRACE_DENSITY_COST_FACTOR=Math.max(0,e.TRACE_DENSITY_COST_FACTOR)),void 0!==e.USE_LAZY_ROUTE_HEURISTIC\u0026\u0026(t.USE_LAZY_ROUTE_HEURISTIC=e.USE_LAZY_ROUTE_HEURISTIC),void 0!==e.USE_SPARSE_CANDIDATE_STORAGE\u0026\u0026(t.USE_SPARSE_CANDIDATE_STORAGE=e.USE_SPARSE_CANDIDATE_STORAGE),void 0!==e.MAX_ITERATIONS\u0026\u0026(t.MAX_ITERATIONS=e.MAX_ITERATIONS),void 0!==e.VERBOSE\u0026\u0026(t.VERBOSE=e.VERBOSE),void 0!==e.STATIC_REACHABILITY_PRECHECK\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK=e.STATIC_REACHABILITY_PRECHECK),void 0!==e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS=e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),void 0!==e.ACCEPT_BEST_SOLUTION_ON_TIMEOUT\u0026\u0026(t.ACCEPT_BEST_SOLUTION_ON_TIMEOUT=e.ACCEPT_BEST_SOLUTION_ON_TIMEOUT),void 0!==e.GREEDY_FINAL_ROUTE_ITERS\u0026\u0026(t.GREEDY_FINAL_ROUTE_ITERS=e.GREEDY_FINAL_ROUTE_ITERS),void 0!==e.PARTIAL_RIP_ENABLED\u0026\u0026(t.PARTIAL_RIP_ENABLED=e.PARTIAL_RIP_ENABLED),void 0!==e.PARTIAL_RIP_MIN_ROUTE_COUNT\u0026\u0026(t.PARTIAL_RIP_MIN_ROUTE_COUNT=e.PARTIAL_RIP_MIN_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_MAX_ROUTE_COUNT\u0026\u0026(t.PARTIAL_RIP_MAX_ROUTE_COUNT=e.PARTIAL_RIP_MAX_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_MAX_DISTANCE\u0026\u0026(t.PARTIAL_RIP_MAX_DISTANCE=e.PARTIAL_RIP_MAX_DISTANCE),void 0!==e.PARTIAL_RIP_QUALITY_MAX_DISTANCE\u0026\u0026(t.PARTIAL_RIP_QUALITY_MAX_DISTANCE=e.PARTIAL_RIP_QUALITY_MAX_DISTANCE),void 0!==e.PARTIAL_RIP_MAX_ATTEMPTS\u0026\u0026(t.PARTIAL_RIP_MAX_ATTEMPTS=e.PARTIAL_RIP_MAX_ATTEMPTS),void 0!==e.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS\u0026\u0026(t.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS=e.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS),void 0!==e.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT\u0026\u0026(t.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT=e.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO\u0026\u0026(t.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO=e.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO),void 0!==e.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO\u0026\u0026(t.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO=e.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO),void 0!==e.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO\u0026\u0026(t.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO=e.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO),void 0!==e.OUTSIDE_IN_ROUTING\u0026\u0026(t.OUTSIDE_IN_ROUTING=e.OUTSIDE_IN_ROUTING),void 0!==e.OUTSIDE_IN_MAX_DISTANCE\u0026\u0026(t.OUTSIDE_IN_MAX_DISTANCE=e.OUTSIDE_IN_MAX_DISTANCE))},tB=t=\u003e({minViaPadDiameter:t.minViaPadDiameter,DISTANCE_TO_COST:t.DISTANCE_TO_COST,RIP_THRESHOLD_START:t.RIP_THRESHOLD_START,RIP_THRESHOLD_END:t.RIP_THRESHOLD_END,RIP_THRESHOLD_RAMP_ATTEMPTS:t.RIP_THRESHOLD_RAMP_ATTEMPTS,RIP_CONGESTION_REGION_COST_FACTOR:t.RIP_CONGESTION_REGION_COST_FACTOR,TRACE_DENSITY_COST_FACTOR:t.TRACE_DENSITY_COST_FACTOR,USE_LAZY_ROUTE_HEURISTIC:t.USE_LAZY_ROUTE_HEURISTIC,USE_SPARSE_CANDIDATE_STORAGE:t.USE_SPARSE_CANDIDATE_STORAGE,MAX_ITERATIONS:t.MAX_ITERATIONS,VERBOSE:t.VERBOSE,STATIC_REACHABILITY_PRECHECK:t.STATIC_REACHABILITY_PRECHECK,STATIC_REACHABILITY_PRECHECK_MAX_HOPS:t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:t.ACCEPT_BEST_SOLUTION_ON_TIMEOUT,GREEDY_FINAL_ROUTE_ITERS:t.GREEDY_FINAL_ROUTE_ITERS,PARTIAL_RIP_ENABLED:t.PARTIAL_RIP_ENABLED,PARTIAL_RIP_MIN_ROUTE_COUNT:t.PARTIAL_RIP_MIN_ROUTE_COUNT,PARTIAL_RIP_MAX_ROUTE_COUNT:t.PARTIAL_RIP_MAX_ROUTE_COUNT,PARTIAL_RIP_MAX_DISTANCE:t.PARTIAL_RIP_MAX_DISTANCE,PARTIAL_RIP_QUALITY_MAX_DISTANCE:t.PARTIAL_RIP_QUALITY_MAX_DISTANCE,PARTIAL_RIP_MAX_ATTEMPTS:t.PARTIAL_RIP_MAX_ATTEMPTS,PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS:t.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:t.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT,PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO:t.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO,PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO:t.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO,PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO:t.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO,OUTSIDE_IN_ROUTING:t.OUTSIDE_IN_ROUTING,OUTSIDE_IN_MAX_DISTANCE:t.OUTSIDE_IN_MAX_DISTANCE}),eB=(t,e)=\u003et.f-e.f,nB=class extends kt{constructor(t,e,n){super(),this.topology=t,this.problem=e,QF(this,n);let o=1;const i=new Int32Array(t.portCount).fill(-1),r=new Int32Array(t.portCount).fill(-1);for(let e=0;e\u003ct.portCount;e++){const n=t.incidentPortRegion[e]??[];n.length\u003eo\u0026\u0026(o=n.length),i[e]=n[0]??-1,r[e]=n[1]??-1}this.candidateHopSlotStride=o,this.candidateFirstRegionByPortId=i,this.candidateSecondRegionByPortId=r;const s=t.portCount*o;this.candidateHopCapacity=s,this.state={portAssignment:new Int32Array(t.portCount).fill(-1),regionSegments:Array.from({length:t.regionCount},()=\u003e[]),regionIntersectionCaches:Array.from({length:t.regionCount},()=\u003eqF()),currentRouteId:void 0,currentRouteNetId:void 0,unroutedRoutes:oF(e.routeCount),candidateQueue:new Zz([],eB),candidateBestCostByHopId:this.USE_SPARSE_CANDIDATE_STORAGE?new Map:new Float64Array(s),candidateBestCostGenerationByHopId:this.USE_SPARSE_CANDIDATE_STORAGE?new Map:new Uint32Array(s),candidateBestCostGeneration:1,goalPortId:-1,ripCount:0,regionCongestionCost:new Float64Array(t.regionCount).fill(0)},this.routeAttemptCountByRouteId=new Uint32Array(e.routeCount),this.routeSuccessCountByRouteId=new Uint32Array(e.routeCount);const a=Uz({topology:t,problem:e,state:this.state,routeSuccessCountByRouteId:this.routeSuccessCountByRouteId,appendSegmentToRegionCache:(t,e,n)=\u003ethis.appendSegmentToRegionCache(t,e,n)});a\u0026\u0026(this.stats={...this.stats,...a})}topology;problem;state;candidateHopSlotStride;candidateHopCapacity;candidateFirstRegionByPortId;candidateSecondRegionByPortId;candidateOverflowBestCost;_problemSetup;routeAttemptCountByRouteId;routeSuccessCountByRouteId;bestSolvedStateSnapshot;bestSolvedStateSummary;hasLoggedNeverSuccessfullyRoutedRoutes=!1;staticallyUnroutableRoutes=[];segmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};ADD_SEGMENT_DISTANCE_TO_G=!1;DISTANCE_TO_COST=.05;minViaPadDiameter=Yz;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;RIP_CONGESTION_REGION_COST_FACTOR=.1;TRACE_DENSITY_COST_FACTOR=0;USE_LAZY_ROUTE_HEURISTIC=!1;USE_SPARSE_CANDIDATE_STORAGE=!1;MAX_ITERATIONS=1e6;VERBOSE=!1;STATIC_REACHABILITY_PRECHECK=!0;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;ACCEPT_BEST_SOLUTION_ON_TIMEOUT=!0;GREEDY_FINAL_ROUTE_ITERS=4;PARTIAL_RIP_ENABLED=!1;PARTIAL_RIP_MIN_ROUTE_COUNT=0;PARTIAL_RIP_MAX_ROUTE_COUNT=Number.POSITIVE_INFINITY;PARTIAL_RIP_MAX_DISTANCE=12;PARTIAL_RIP_QUALITY_MAX_DISTANCE;PARTIAL_RIP_MAX_ATTEMPTS=Number.POSITIVE_INFINITY;PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS=0;PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT=Number.POSITIVE_INFINITY;PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO=0;PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO=.2;PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO=.1;OUTSIDE_IN_ROUTING=!1;OUTSIDE_IN_MAX_DISTANCE=24;get problemSetup(){return this._problemSetup||(this._problemSetup=this.computeProblemSetup()),this._problemSetup}computeProblemSetup(){const{topology:t,problem:e}=this,n=this.USE_LAZY_ROUTE_HEURISTIC?void 0:new Float64Array(t.portCount*e.routeCount),o=t.portX,i=t.portY,r=Array.from({length:t.portCount},()=\u003enew Set),s=new Int32Array(t.portCount).fill(-1),a=(t,e)=\u003e{r[t].add(e);const n=s[t];-1===n?s[t]=e:n!==e\u0026\u0026(s[t]=-2)};for(let r=0;r\u003ce.routeCount;r++){const s=e.routeNet[r];if(a(e.routeStartPort[r],s),a(e.routeEndPort[r],s),n){const s=e.routeEndPort[r],a=o[s],c=i[s];for(let s=0;s\u003ct.portCount;s++){const t=o[s]-a,l=i[s]-c;n[s*e.routeCount+r]=Math.sqrt(t*t+l*l)*this.DISTANCE_TO_COST}}}return{portHCostToEndOfRoute:n,portEndpointNetIds:r,portEndpointReservationNetId:s}}_setup(){if(this.problemSetup,this.STATIC_REACHABILITY_PRECHECK){const t=nF({topology:this.topology,problem:this.problem,problemSetup:this.problemSetup,portAssignment:this.state.portAssignment,routeIds:this.state.unroutedRoutes,maxPrecheckHops:Math.max(0,this.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),getStartingNextRegionId:(t,e)=\u003ethis.getStartingNextRegionId(t,e),getRouteSummary:t=\u003ethis.getRouteSummary(t)});this.staticallyUnroutableRoutes=t,t.length\u003e0\u0026\u0026(this.failed=!0,this.error=(t=\u003e{const e=t.slice(0,5).map(t=\u003e{const e=t.pointIds.length\u003e=2?`${t.pointIds[0]}-\u003e${t.pointIds[1]}`:`${t.startPortId}-\u003e${t.endPortId}`;return`${t.connectionId} (${e})`}).join(\", \"),n=t.length-5;return[\"Static reachability precheck failed:\",`${t.length} route(s) have no legal path under the current reservation and start-region rules`,n\u003e0?`${e}, +${n} more`:e].join(\" \")})(t),this.stats={...this.stats,staticallyUnroutableRouteCount:t.length})}}_step(){const{problem:t,topology:e,state:n}=this;if(void 0===n.currentRouteId){if(0===n.unroutedRoutes.length)return void this.onAllRoutesRouted();n.currentRouteId=n.unroutedRoutes.shift(),n.currentRouteNetId=t.routeNet[n.currentRouteId],this.routeAttemptCountByRouteId[n.currentRouteId]+=1,this.resetCandidateBestCosts();const e=this.getRouteStartPortId(n.currentRouteId);n.candidateQueue.clear();const o=this.getStartingNextRegionId(n.currentRouteId,e);if(void 0===o)return this.failed=!0,void(this.error=`Start port ${e} has no incident regions`);this.setCandidateBestCost(this.getHopId(e,o),0),n.candidateQueue.queue({nextRegionId:o,portId:e,f:0,g:0,h:0}),n.goalPortId=this.getRouteEndPortId(n.currentRouteId)}const o=n.candidateQueue.dequeue();if(!o)return void this.onOutOfCandidates();const i=this.getHopId(o.portId,o.nextRegionId);if(o.g\u003ethis.getCandidateBestCost(i))return;if(this.isRegionReservedForDifferentNet(o.nextRegionId))return;const r=e.regionIncidentPorts[o.nextRegionId];for(const i of r){const r=n.portAssignment[i];if(this.isPortReservedForDifferentNet(i))continue;if(i===n.goalPortId){if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;return void this.onPathFound(o)}if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;if(i===o.portId)continue;if(0===t.portSectionMask[i])continue;const s=e.incidentPortRegion[i][0]===o.nextRegionId?e.incidentPortRegion[i][1]:e.incidentPortRegion[i][0];if(void 0===s||this.isRegionReservedForDifferentNet(s))continue;const a=this.getHopId(i,s);if(!0===n.candidateQueue.isClosedHop?.(i,s))continue;const c=this.getCandidateBestCost(a);if(o.g\u003e=c)continue;const l=this.computeG(o,i,c);if(!Number.isFinite(l)||l\u003e=c)continue;const d=this.computeH(i),h={prevRegionId:o.nextRegionId,nextRegionId:s,portId:i,g:l,h:d,f:l+d,prevCandidate:o};if(i===n.goalPortId)return void this.onPathFound(h);this.setCandidateBestCost(a,l),n.candidateQueue.queue(h)}}resetCandidateBestCosts(){const{state:t}=this;if(this.candidateOverflowBestCost?.clear(),4294967295===t.candidateBestCostGeneration)return t.candidateBestCostByHopId instanceof Map\u0026\u0026t.candidateBestCostByHopId.clear(),t.candidateBestCostGenerationByHopId instanceof Map?t.candidateBestCostGenerationByHopId.clear():t.candidateBestCostGenerationByHopId.fill(0),void(t.candidateBestCostGeneration=1);t.candidateBestCostGeneration+=1}getCandidateBestCost(t){if(t\u003c0)return this.candidateOverflowBestCost?.get(t)??Number.POSITIVE_INFINITY;const{state:e}=this,n=e.candidateBestCostGenerationByHopId;return(n instanceof Map?n.get(t):n[t])===e.candidateBestCostGeneration?e.candidateBestCostByHopId instanceof Map?e.candidateBestCostByHopId.get(t):e.candidateBestCostByHopId[t]:Number.POSITIVE_INFINITY}setCandidateBestCost(t,e){if(t\u003c0)return this.candidateOverflowBestCost||(this.candidateOverflowBestCost=new Map),void this.candidateOverflowBestCost.set(t,e);const{state:n}=this;n.candidateBestCostGenerationByHopId instanceof Map?n.candidateBestCostGenerationByHopId.set(t,n.candidateBestCostGeneration):n.candidateBestCostGenerationByHopId[t]=n.candidateBestCostGeneration,n.candidateBestCostByHopId instanceof Map?n.candidateBestCostByHopId.set(t,e):n.candidateBestCostByHopId[t]=e}getHopId(t,e){const n=t*this.candidateHopSlotStride;if(this.candidateFirstRegionByPortId[t]===e)return n;if(this.candidateSecondRegionByPortId[t]===e)return n+1;const o=this.topology.incidentPortRegion[t];for(let t=2;t\u003c(o?.length??0);t++)if(o[t]===e)return n+t;return-(t*this.topology.regionCount+e)-1}getStartingNextRegionId(t,e){const n=this.topology.incidentPortRegion[e]??[],o=this.problem.routeNet[t];return n.find(t=\u003e-1===this.problem.regionNetId[t])??n.find(t=\u003ethis.problem.regionNetId[t]===o)??n[0]}getRouteStartPortId(t){return this.problem.routeStartPort[t]}getRouteEndPortId(t){return this.problem.routeEndPort[t]}isPortReservedForDifferentNet(t){const e=this.problemSetup.portEndpointReservationNetId[t]??-1;return-2===e||-1!==e\u0026\u0026e!==this.state.currentRouteNetId}isRegionReservedForDifferentNet(t){const e=this.problem.regionNetId[t];return-1!==e\u0026\u0026e!==this.state.currentRouteNetId}isKnownSingleLayerRegion(t){const e=this.topology.regionAvailableZMask?.[t]??0;return Xz(e)}computeRegionCostForRegion(t,e,n,o,i){return((t,e,n,o,i,r,s=0,a=.3,c=0)=\u003eVz(t*e,n,o,i,r,s,a,c))(this.topology.regionWidth[t],this.topology.regionHeight[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0,this.minViaPadDiameter,this.TRACE_DENSITY_COST_FACTOR)}populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.segmentGeometryScratch,r=this.candidateFirstRegionByPortId[e]===t||this.candidateSecondRegionByPortId[e]!==t?o.portAngleForRegion1[e]:o.portAngleForRegion2?.[e]??o.portAngleForRegion1[e],s=this.candidateFirstRegionByPortId[n]===t||this.candidateSecondRegionByPortId[n]!==t?o.portAngleForRegion1[n]:o.portAngleForRegion2?.[n]??o.portAngleForRegion1[n],a=o.portZ[e],c=o.portZ[n];return i.lesserAngle=r\u003cs?r:s,i.greaterAngle=r\u003cs?s:r,i.layerMask=1\u003c\u003ca|1\u003c\u003cc,i.entryExitLayerChanges=a!==c?1:0,i}appendSegmentToRegionCache(t,e,n){const{state:o}=this,i=o.regionIntersectionCaches[t],r=this.populateSegmentGeometryScratch(t,e,n),[s,a,c]=Hz(i,o.currentRouteNetId,r.lesserAngle,r.greaterAngle,r.layerMask,r.entryExitLayerChanges),l=i.netIds.length+1,d=new Int32Array(l);d.set(i.netIds),d[l-1]=o.currentRouteNetId;const h=new Int32Array(l);h.set(i.lesserAngles),h[l-1]=r.lesserAngle;const u=new Int32Array(l);u.set(i.greaterAngles),u[l-1]=r.greaterAngle;const p=new Int32Array(l);p.set(i.layerMasks),p[l-1]=r.layerMask;const m=i.existingSameLayerIntersections+s,g=i.existingCrossingLayerIntersections+a,f=i.existingEntryExitLayerChanges+c,y=h.length;o.regionIntersectionCaches[t]={netIds:d,lesserAngles:h,greaterAngles:u,layerMasks:p,existingSameLayerIntersections:m,existingCrossingLayerIntersections:g,existingEntryExitLayerChanges:f,existingSegmentCount:y,existingRegionCost:this.computeRegionCostForRegion(t,m,g,f,y)}}getSolvedPathSegments(t){const{state:e}=this,n=[];let o=t;for(;o;)n.unshift(o),o=o.prevCandidate;const i=[];for(let t=1;t\u003cn.length;t++)i.push({regionId:n[t-1].nextRegionId,fromPortId:n[t-1].portId,toPortId:n[t].portId});const r=n[n.length-1];return r\u0026\u0026r.portId!==e.goalPortId\u0026\u0026i.push({regionId:r.nextRegionId,fromPortId:r.portId,toPortId:e.goalPortId}),i}resetRoutingStateForRerip(){const{topology:t,problem:e,state:n}=this;n.portAssignment.fill(-1),n.regionSegments=Array.from({length:t.regionCount},()=\u003e[]),n.regionIntersectionCaches=Array.from({length:t.regionCount},()=\u003eqF()),n.currentRouteNetId=void 0,n.currentRouteId=void 0,n.unroutedRoutes=qz(oF(e.routeCount),n.ripCount),n.candidateQueue.clear(),this.resetCandidateBestCosts(),n.goalPortId=-1}getMaxRegionCost(){const{topology:t,state:e}=this;let n=0;for(let o=0;o\u003ct.regionCount;o++){const t=e.regionIntersectionCaches[o]?.existingRegionCost??0;n=Math.max(n,t)}return n}getRouteMetadata(t){return this.problem.routeMetadata?.[t]}getRouteConnectionId(t){const e=this.getRouteMetadata(t)?.connectionId;return\"string\"==typeof e?e:`route-${t}`}getRouteSummary(t){return(({problem:t,routeId:e,getRouteMetadata:n,getRouteConnectionId:o})=\u003e{const i=n?.(e)??Jz(t,e);return{routeId:e,connectionId:o?.(e)??Qz(t,e),startPortId:t.routeStartPort[e],endPortId:t.routeEndPort[e],startRegionId:\"string\"==typeof i?.startRegionId?i.startRegionId:void 0,endRegionId:\"string\"==typeof i?.endRegionId?i.endRegionId:void 0,pointIds:Kz(i)}})({problem:this.problem,routeId:t,getRouteMetadata:t=\u003ethis.getRouteMetadata(t),getRouteConnectionId:t=\u003ethis.getRouteConnectionId(t)})}getAdditionalRegionLabel(t){}getNeverSuccessfullyRoutedRoutes(){const t=[];for(let e=0;e\u003cthis.problem.routeCount;e++){const n=this.routeAttemptCountByRouteId[e];0===n||this.routeSuccessCountByRouteId[e]\u003e0||t.push({...this.getRouteSummary(e),attempts:n})}return t}getStaticallyUnroutableRoutes(){return this.staticallyUnroutableRoutes}logNeverSuccessfullyRoutedRoutes(){if(!this.VERBOSE||this.hasLoggedNeverSuccessfullyRoutedRoutes)return;const t=this.getNeverSuccessfullyRoutedRoutes();if(this.hasLoggedNeverSuccessfullyRoutedRoutes=!0,0!==t.length){console.log([\"[TinyHyperGraphSolver:never-routed-summary]\",`count=${t.length}`].join(\" \"));for(const e of t){const t=e.pointIds.length\u003e=2?`${e.pointIds[0]}-\u003e${e.pointIds[1]}`:\"unknown\";console.log([\"[TinyHyperGraphSolver:never-routed]\",`routeId=${e.routeId}`,`connectionId=${e.connectionId}`,`attempts=${e.attempts}`,`pointPath=${t}`,`startRegionId=${e.startRegionId??\"unknown\"}`,`endRegionId=${e.endRegionId??\"unknown\"}`].join(\" \"))}}}logRipEvent(t,e,n={}){this.VERBOSE\u0026\u0026console.log([\"[TinyHyperGraphSolver:rip]\",`ripCount=${this.state.ripCount}`,`maxRegionCostBeforeRip=${e.toFixed(3)}`,`reason=${t}`,...Object.entries(n).map(([t,e])=\u003e`${t}=${\"number\"==typeof e?Number.isInteger(e)?String(e):e.toFixed(3):e}`)].join(\" \"))}compareRegionCostSummaries(t,e){return t.maxRegionCost!==e.maxRegionCost?t.maxRegionCost-e.maxRegionCost:t.totalRegionCost-e.totalRegionCost}captureBestSolvedState(t){this.bestSolvedStateSummary\u0026\u0026this.compareRegionCostSummaries(t,this.bestSolvedStateSummary)\u003e=0||this.replaceBestSolvedState(t)}replaceBestSolvedState(t){this.bestSolvedStateSummary=t,this.bestSolvedStateSnapshot=KF({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches,regionCongestionCost:this.state.regionCongestionCost,ripCount:this.state.ripCount})}restoreBestSolvedState(){if(!this.bestSolvedStateSnapshot)return;const t=KF(this.bestSolvedStateSnapshot);this.state.portAssignment=t.portAssignment,this.state.regionSegments=t.regionSegments,this.state.regionIntersectionCaches=t.regionIntersectionCaches,this.state.regionCongestionCost=t.regionCongestionCost,this.state.ripCount=t.ripCount,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1}getRemainingRouteIdsForGreedyFinalRoute(){const t=new Set(this.state.unroutedRoutes);return void 0!==this.state.currentRouteId\u0026\u0026t.add(this.state.currentRouteId),[...t]}applySnapshotToGreedyFinalRouteSolver(t,e,n){const o=KF(e);t.state.portAssignment=o.portAssignment,t.state.regionSegments=o.regionSegments,t.state.regionIntersectionCaches=o.regionIntersectionCaches,t.state.regionCongestionCost=o.regionCongestionCost,t.state.ripCount=0,t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.state.unroutedRoutes=[...n],t.state.candidateQueue.clear(),t.resetCandidateBestCosts(),t.state.goalPortId=-1}summarizeSolvedState(t){let e=0,n=0;for(const o of t.state.regionIntersectionCaches){const t=o.existingRegionCost;e=Math.max(e,t),n+=t}return{maxRegionCost:e,totalRegionCost:n}}tryGreedyFinalRouteAcceptance(){const t=Math.max(0,Math.floor(this.GREEDY_FINAL_ROUTE_ITERS));if(0===t)return!1;const e=this.getRemainingRouteIdsForGreedyFinalRoute();if(0===e.length)return!1;const n=KF({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches,regionCongestionCost:this.state.regionCongestionCost,ripCount:this.state.ripCount});for(let o=0;o\u003ct;o++){const t=0===o?e:qz(e,this.state.ripCount+o),i=new oB(this.topology,this.problem,{...tB(this),ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!1,GREEDY_FINAL_ROUTE_ITERS:0,MAX_ITERATIONS:ZF,RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!1});if(this.applySnapshotToGreedyFinalRouteSolver(i,n,t),i.solve(),i.solved\u0026\u0026!i.failed)return this.bestSolvedStateSnapshot=KF({portAssignment:i.state.portAssignment,regionSegments:i.state.regionSegments,regionIntersectionCaches:i.state.regionIntersectionCaches,regionCongestionCost:i.state.regionCongestionCost,ripCount:i.state.ripCount}),this.bestSolvedStateSummary=this.summarizeSolvedState(i),this.restoreBestSolvedState(),this.stats={...this.stats,acceptedGreedyFinalRouteOnTimeout:!0,greedyFinalRouteIter:o,greedyFinalRouteRemainingRouteCount:e.length,greedyFinalRouteMaxIterations:ZF,neverSuccessfullyRoutedRouteCount:0,maxRegionCost:this.bestSolvedStateSummary.maxRegionCost,totalRegionCost:this.bestSolvedStateSummary.totalRegionCost,bestMaxRegionCost:this.bestSolvedStateSummary.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary.totalRegionCost},this.solved=!0,this.failed=!1,this.error=null,!0}return this.stats={...this.stats,greedyFinalRouteAttemptCount:t,greedyFinalRouteRemainingRouteCount:e.length,greedyFinalRouteMaxIterations:ZF},!1}onAllRoutesRouted(){const{topology:t,state:e}=this,n=this.RIP_THRESHOLD_RAMP_ATTEMPTS\u003c=0?1:Math.min(1,e.ripCount/this.RIP_THRESHOLD_RAMP_ATTEMPTS),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(t.regionCount);let s=0,a=0;for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;r[n]=t,s=Math.max(s,t),a+=t,t\u003eo\u0026\u0026i.push(n)}if(this.captureBestSolvedState({maxRegionCost:s,totalRegionCost:a}),this.stats={...this.stats,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:s,totalRegionCost:a,bestMaxRegionCost:this.bestSolvedStateSummary?.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary?.totalRegionCost,ripCount:e.ripCount},0===i.length||e.ripCount\u003e=this.RIP_THRESHOLD_RAMP_ATTEMPTS)this.solved=!0;else{for(let n=0;n\u003ct.regionCount;n++)e.regionCongestionCost[n]+=r[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCostBeforeRip:s,reripRegionCount:i.length},this.logRipEvent(\"hot_regions\",s,{hotRegionCount:i.length,currentRipThreshold:o})}}onOutOfCandidates(){const{topology:t,state:e}=this,n=e.currentRouteId,o=this.getMaxRegionCost();for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;e.regionCongestionCost[n]+=t*this.RIP_CONGESTION_REGION_COST_FACTOR}e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCost:o,maxRegionCostBeforeRip:o,reripReason:\"out_of_candidates\"},this.logRipEvent(\"out_of_candidates\",o,{...void 0===n?{}:{routeId:n,connectionId:this.getRouteConnectionId(n)}})}onPathFound(t){const{state:e}=this,n=e.currentRouteId;if(void 0===n)return;this.routeSuccessCountByRouteId[n]+=1;const o=this.getSolvedPathSegments(t);for(const{regionId:t,fromPortId:i,toPortId:r}of o)e.regionSegments[t].push([n,i,r]),e.portAssignment[i]=e.currentRouteNetId,e.portAssignment[r]=e.currentRouteNetId,this.appendSegmentToRegionCache(t,i,r);e.candidateQueue.clear(),e.currentRouteNetId=void 0,e.currentRouteId=void 0}computeG(t,e,n=Number.POSITIVE_INFINITY,o){const{state:i,topology:r}=this,s=t.nextRegionId,a=i.regionIntersectionCaches[s];let c=0;if(this.ADD_SEGMENT_DISTANCE_TO_G){let n=o;if(void 0===n){const o=r.portX[t.portId]-r.portX[e],i=r.portY[t.portId]-r.portY[e];n=Math.sqrt(o*o+i*i)}c=n*this.DISTANCE_TO_COST}if(t.g+i.regionCongestionCost[s]+(this.problem.portPenalty?.[e]??0)+c\u003en+1e-9)return Number.POSITIVE_INFINITY;const l=t.portId,d=this.candidateFirstRegionByPortId[l]===s||this.candidateSecondRegionByPortId[l]!==s?r.portAngleForRegion1[l]:r.portAngleForRegion2?.[l]??r.portAngleForRegion1[l],h=this.candidateFirstRegionByPortId[e]===s||this.candidateSecondRegionByPortId[e]!==s?r.portAngleForRegion1[e]:r.portAngleForRegion2?.[e]??r.portAngleForRegion1[e],u=d\u003ch?d:h,p=d\u003ch?h:d,m=r.portZ[l],g=r.portZ[e],f=1\u003c\u003cm|1\u003c\u003cg,y=m!==g?1:0,[_,b,x]=Hz(a,i.currentRouteNetId,u,p,f,y);if(_\u003e0\u0026\u0026this.isKnownSingleLayerRegion(s))return Number.POSITIVE_INFINITY;const v=this.computeRegionCostForRegion(s,a.existingSameLayerIntersections+_,a.existingCrossingLayerIntersections+b,a.existingEntryExitLayerChanges+x,a.existingSegmentCount+1)-a.existingRegionCost;return t.g+v+i.regionCongestionCost[s]+(this.problem.portPenalty?.[e]??0)+c}tryFinalAcceptance(){const t=this.getNeverSuccessfullyRoutedRoutes();if(this.stats={...this.stats,neverSuccessfullyRoutedRouteCount:t.length},this.ACCEPT_BEST_SOLUTION_ON_TIMEOUT\u0026\u0026this.bestSolvedStateSnapshot\u0026\u0026this.bestSolvedStateSummary)return this.restoreBestSolvedState(),this.stats={...this.stats,acceptedBestSolutionOnTimeout:!0,maxRegionCost:this.bestSolvedStateSummary.maxRegionCost,totalRegionCost:this.bestSolvedStateSummary.totalRegionCost,bestMaxRegionCost:this.bestSolvedStateSummary.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary.totalRegionCost},this.solved=!0,this.failed=!1,void(this.error=null);this.ACCEPT_BEST_SOLUTION_ON_TIMEOUT\u0026\u0026this.tryGreedyFinalRouteAcceptance()||this.logNeverSuccessfullyRoutedRoutes()}computeH(t){const e=this.problemSetup.portHCostToEndOfRoute;if(e)return e[t*this.problem.routeCount+this.state.currentRouteId];const n=this.getRouteEndPortId(this.state.currentRouteId),o=this.topology.portX[t]-this.topology.portX[n],i=this.topology.portY[t]-this.topology.portY[n];return Math.sqrt(o*o+i*i)*this.DISTANCE_TO_COST}visualize(){return UF(this)}getOutput(){return $z(this)}},oB=class extends nB{computeG(t,e){return t.g}},iB=class{constructor(t,e){this.regionCount=t,this.compactHopIndex=e,e\u0026\u0026(this.hopStateGeneration=new Uint32Array(e.hopCapacity),this.hopIndexOrClosed=new Int32Array(e.hopCapacity))}regionCount;compactHopIndex;items=[];indexByHopId=new Map;closedHopIds=new Set;hopStateGeneration;hopIndexOrClosed;currentHopStateGeneration=1;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0,this.indexByHopId.clear(),this.closedHopIds.clear(),this.hopStateGeneration\u0026\u0026(4294967295===this.currentHopStateGeneration?(this.hopStateGeneration.fill(0),this.currentHopStateGeneration=1):this.currentHopStateGeneration+=1)}isClosedHop(t,e){return this.isHopClosed(this.getHopIdFromValues(t,e))}queue(t){const e=this.getHopId(t);if(this.isHopClosed(e))return;const n=this.getQueuedHopIndex(e);if(void 0!==n){const e=this.items[n];if(t.g\u003e=e.g)return;return this.items[n]=t,void(t.f\u003c=e.f?this.siftUp(n):this.siftDown(n))}const o=this.items.length;this.items.push(t),this.siftUp(o)}dequeue(){const t=this.items[0];if(!t)return;const e=this.getHopId(t);this.closeHop(e);const n=this.items.pop();return this.items.length\u003e0\u0026\u0026(this.items[0]=n,this.siftDown(0)),t}getHopId(t){return this.getHopIdFromValues(t.portId,t.nextRegionId)}getHopIdFromValues(t,e){const n=this.compactHopIndex;if(!n)return t*this.regionCount+e;const o=t*n.hopSlotStride;if(n.firstRegionByPortId[t]===e)return o;if(n.secondRegionByPortId[t]===e)return o+1;const i=n.incidentPortRegion[t];for(let t=2;t\u003c(i?.length??0);t++)if(i[t]===e)return o+t;return-(t*this.regionCount+e)-1}getQueuedHopIndex(t){if(t\u003e=0\u0026\u0026this.hopStateGeneration?.[t]===this.currentHopStateGeneration){const e=this.hopIndexOrClosed[t];return e\u003e=0?e:void 0}return this.indexByHopId.get(t)}isHopClosed(t){return t\u003e=0\u0026\u0026this.hopStateGeneration?.[t]===this.currentHopStateGeneration?-1===this.hopIndexOrClosed[t]:this.closedHopIds.has(t)}setQueuedHopIndex(t,e){if(t\u003e=0\u0026\u0026this.hopStateGeneration)return this.hopStateGeneration[t]=this.currentHopStateGeneration,void(this.hopIndexOrClosed[t]=e);this.indexByHopId.set(t,e)}closeHop(t){if(t\u003e=0\u0026\u0026this.hopStateGeneration)return this.hopStateGeneration[t]=this.currentHopStateGeneration,void(this.hopIndexOrClosed[t]=-1);this.indexByHopId.delete(t),this.closedHopIds.add(t)}siftUp(t){const e=this.items[t];let n=t;for(;n\u003e0;){const t=n-1\u003e\u003e1,o=this.items[t];if(o.f\u003c=e.f)break;this.items[n]=o,this.setQueuedHopIndex(this.getHopId(o),n),n=t}this.items[n]=e,this.setQueuedHopIndex(this.getHopId(e),n)}siftDown(t){const e=this.items[t];let n=t;for(;;){const t=2*n+1;if(t\u003e=this.items.length)break;const o=t+1,i=o\u003cthis.items.length\u0026\u0026this.items[o].f\u003cthis.items[t].f?o:t,r=this.items[i];if(e.f\u003c=r.f)break;this.items[n]=r,this.setQueuedHopIndex(this.getHopId(r),n),n=i}this.items[n]=e,this.setQueuedHopIndex(this.getHopId(e),n)}},rB=class extends nB{constructor(t,e,n){super(t,e,n),this.ADD_SEGMENT_DISTANCE_TO_G=!0}_setup(){super._setup(),this.state.candidateQueue=new iB(this.topology.regionCount,{hopCapacity:this.candidateHopCapacity,hopSlotStride:this.candidateHopSlotStride,firstRegionByPortId:this.candidateFirstRegionByPortId,secondRegionByPortId:this.candidateSecondRegionByPortId,incidentPortRegion:this.topology.incidentPortRegion})}onPathFound(t){const e=this.state.goalPortId;if(t.portId===e)return void super.onPathFound(t);const n=this.computeG(t,e);if(!Number.isFinite(n))return;const o=this.getHopId(e,t.nextRegionId);n\u003e=this.getCandidateBestCost(o)||(this.setCandidateBestCost(o,n),this.state.candidateQueue.queue({prevRegionId:t.nextRegionId,nextRegionId:t.nextRegionId,portId:e,g:n,h:0,f:n,prevCandidate:t}))}},sB=new Set,aB=class extends rB{partialRipRoutePlans=new Map;outsideInRouteSearch;oneSidedFallbackRouteId;partialRipWindowDistance;partialRipCount=0;partiallyRippedRouteCount=0;partiallyRippedSegmentCount=0;retainedPartialRipSegmentCount=0;outsideInRouteCount=0;outsideInCompletedRouteCount=0;outsideInFallbackRouteCount=0;outsideInForwardExpansionCount=0;outsideInReverseExpansionCount=0;outsideInDistancePruneCount=0;completedRoundSummaries=[];firstCompletedRoundSummary;partialRipQualityBaselineSummary;bestSolvedRoundSummary;partialRipTargetReached=!1;useComplexityAwareSelection=!1;constructor(t,e,n){super(t,e,n),void 0===n?.PARTIAL_RIP_ENABLED\u0026\u0026(this.PARTIAL_RIP_ENABLED=!0),void 0===n?.OUTSIDE_IN_ROUTING\u0026\u0026(this.OUTSIDE_IN_ROUTING=!0),this.PARTIAL_RIP_ENABLED\u0026\u0026void 0===n?.PARTIAL_RIP_MAX_ATTEMPTS\u0026\u0026(this.PARTIAL_RIP_MAX_ATTEMPTS=10),(e.routeCount\u003cMath.max(0,this.PARTIAL_RIP_MIN_ROUTE_COUNT)||e.routeCount\u003eMath.max(0,this.PARTIAL_RIP_MAX_ROUTE_COUNT))\u0026\u0026(this.PARTIAL_RIP_ENABLED=!1,this.OUTSIDE_IN_ROUTING=!1),this.useComplexityAwareSelection=e.routeCount\u003e=Math.max(0,this.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT)}getRouteStartPortId(t){return this.PARTIAL_RIP_ENABLED?this.partialRipRoutePlans.get(t)?.activeStartPortId??super.getRouteStartPortId(t):super.getRouteStartPortId(t)}getRouteEndPortId(t){return this.PARTIAL_RIP_ENABLED?this.partialRipRoutePlans.get(t)?.activeEndPortId??super.getRouteEndPortId(t):super.getRouteEndPortId(t)}getStartingNextRegionId(t,e){if(!this.PARTIAL_RIP_ENABLED)return super.getStartingNextRegionId(t,e);const n=this.partialRipRoutePlans.get(t);return n\u0026\u0026n.activeStartPortId===e?n.forcedStartRegionId:super.getStartingNextRegionId(t,e)}getEndingNextRegionId(t,e){const n=this.partialRipRoutePlans.get(t);return n\u0026\u0026n.activeEndPortId===e?n.forcedEndRegionId:super.getStartingNextRegionId(t,e)}computeH(t){if(!this.PARTIAL_RIP_ENABLED)return super.computeH(t);const e=this.state.currentRouteId;if(void 0===e||!this.partialRipRoutePlans.has(e))return super.computeH(t);const n=this.getRouteEndPortId(e),o=this.topology.portX[t]-this.topology.portX[n],i=this.topology.portY[t]-this.topology.portY[n];return Math.sqrt(o*o+i*i)*this.DISTANCE_TO_COST}onPathFound(t){if(!this.PARTIAL_RIP_ENABLED\u0026\u0026!this.OUTSIDE_IN_ROUTING)return void super.onPathFound(t);const e=this.state.currentRouteId,n=void 0!==e\u0026\u0026this.outsideInRouteSearch?.routeId===e;super.onPathFound(t),void 0!==e\u0026\u0026void 0===this.state.currentRouteId\u0026\u0026(this.partialRipRoutePlans.delete(e),n\u0026\u0026(this.outsideInCompletedRouteCount+=1),this.oneSidedFallbackRouteId===e\u0026\u0026(this.oneSidedFallbackRouteId=void 0)),this.outsideInRouteSearch=void 0,this.publishOutsideInStats()}resetRoutingStateForRerip(){this.PARTIAL_RIP_ENABLED||this.OUTSIDE_IN_ROUTING?(this.partialRipRoutePlans.clear(),this.outsideInRouteSearch=void 0,this.oneSidedFallbackRouteId=void 0,super.resetRoutingStateForRerip()):super.resetRoutingStateForRerip()}clearPartialRipPlans(t){for(const e of t)this.partialRipRoutePlans.delete(e)}getRouteIdsPreferredForPreservation(){return sB}getCommittedRouteSegments(t){const e=[];for(let n=0;n\u003cthis.state.regionSegments.length;n++)for(const[o,i,r]of this.state.regionSegments[n]??[])o===t\u0026\u0026e.push({segmentIndex:e.length,regionId:n,fromPortId:i,toPortId:r});if(0===e.length)return;const n=new Map;for(const t of e)for(const e of[t.fromPortId,t.toPortId]){const o=n.get(e)??[];o.push(t.segmentIndex),n.set(e,o)}const o=this.problem.routeEndPort[t],i=[],r=new Set,s=new Set([this.problem.routeStartPort[t]]),a=t=\u003e{if(t===o)return!0;for(const o of n.get(t)??[]){if(r.has(o))continue;const n=e[o],c=n.fromPortId===t?n.toPortId:n.fromPortId;if(!s.has(c)){if(r.add(o),s.add(c),i.push({regionId:n.regionId,fromPortId:t,toPortId:c}),a(c))return!0;i.pop(),s.delete(c),r.delete(o)}}return!1};return a(this.problem.routeStartPort[t])\u0026\u0026r.size===e.length?i:void 0}getSegmentDistance(t){const e=this.topology.portX[t.fromPortId]-this.topology.portX[t.toPortId],n=this.topology.portY[t.fromPortId]-this.topology.portY[t.toPortId];return Math.sqrt(e*e+n*n)}getPartialRipWindow(t,e,n){let o,i=Number.NEGATIVE_INFINITY;for(let r=0;r\u003ct.length;r++){const s=t[r];if(!e.has(s.regionId))continue;const a=n[s.regionId]??0;a\u003ei\u0026\u0026(i=a,o=r)}if(void 0===o)return;const r=Math.max(0,this.partialRipWindowDistance??this.PARTIAL_RIP_MAX_DISTANCE);let s=o,a=o,c=this.getSegmentDistance(t[o])/2,l=c;for(;s\u003e0;){const e=this.getSegmentDistance(t[s-1]);if(c+e\u003er)break;s-=1,c+=e}for(;a+1\u003ct.length;){const e=this.getSegmentDistance(t[a+1]);if(l+e\u003er)break;a+=1,l+=e}return{startIndex:s,endIndex:a}}appendRetainedSegment(t,e,n){t[n.regionId].push([e,n.fromPortId,n.toPortId])}preparePartialRip(t,e){if(!this.PARTIAL_RIP_ENABLED||0===t.length)return!1;const n=new Set(t);if(void 0===this.partialRipWindowDistance){let n=0;for(const o of t)n=Math.max(n,e[o]??0);const o=Math.max(0,this.PARTIAL_RIP_MAX_DISTANCE),i=Math.max(o,this.PARTIAL_RIP_QUALITY_MAX_DISTANCE??2*o);this.partialRipWindowDistance=n\u003c=1.5*this.RIP_THRESHOLD_END?i:o}const o=new Set;for(const e of t)for(const[t]of this.state.regionSegments[e]??[])o.add(t);if(0===o.size)return!1;const i=this.getRouteIdsPreferredForPreservation(),r=[...o].some(t=\u003e!i.has(t)),s=Array.from({length:this.topology.regionCount},()=\u003e[]),a=new Map;let c=0,l=0;for(let t=0;t\u003cthis.problem.routeCount;t++){const d=this.getCommittedRouteSegments(t);if(!d)return!1;if(!o.has(t)||r\u0026\u0026i.has(t)){for(const e of d)this.appendRetainedSegment(s,t,e),l+=1;continue}const h=this.getPartialRipWindow(d,n,e);if(!h)return!1;for(let e=0;e\u003cd.length;e++){const n=d[e];e\u003e=h.startIndex\u0026\u0026e\u003c=h.endIndex?c+=1:(this.appendRetainedSegment(s,t,n),l+=1)}const u=d[h.startIndex],p=d[h.endIndex];a.set(t,{routeId:t,activeStartPortId:u.fromPortId,activeEndPortId:p.toPortId,forcedStartRegionId:u.regionId,forcedEndRegionId:p.regionId,rippedSegmentCount:h.endIndex-h.startIndex+1,retainedSegmentCount:d.length-(h.endIndex-h.startIndex+1)})}return 0!==a.size\u0026\u00260!==c\u0026\u0026(this.partialRipRoutePlans=a,this.rebuildRetainedRoutingState(s,[...a.keys()]),this.partialRipCount+=1,this.partiallyRippedRouteCount+=a.size,this.partiallyRippedSegmentCount+=c,this.retainedPartialRipSegmentCount+=l,this.publishPartialRipStats(),!0)}rebuildRetainedRoutingState(t,e){this.state.portAssignment.fill(-1),this.state.regionSegments=Array.from({length:this.topology.regionCount},()=\u003e[]),this.state.regionIntersectionCaches=Array.from({length:this.topology.regionCount},()=\u003eqF()),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=e,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.outsideInRouteSearch=void 0,this.oneSidedFallbackRouteId=void 0;for(let e=0;e\u003ct.length;e++)for(const[n,o,i]of t[e]??[]){const t=this.problem.routeNet[n];this.state.currentRouteNetId=t;for(const e of[o,i]){const n=this.state.portAssignment[e];if(-1!==n\u0026\u0026n!==t)throw new Error(`OutsideInPartialRipTinyHyperGraphSolver: retained port ${e} belongs to multiple nets`);this.state.portAssignment[e]=t}this.state.regionSegments[e].push([n,o,i]),this.appendSegmentToRegionCache(e,o,i)}this.state.currentRouteNetId=void 0}publishPartialRipStats(){this.stats={...this.stats,partialRipCount:this.partialRipCount,partiallyRippedRouteCount:this.partiallyRippedRouteCount,partiallyRippedSegmentCount:this.partiallyRippedSegmentCount,retainedPartialRipSegmentCount:this.retainedPartialRipSegmentCount,partialRipMaxDistance:this.partialRipWindowDistance??this.PARTIAL_RIP_MAX_DISTANCE,partialRipBaseMaxDistance:this.PARTIAL_RIP_MAX_DISTANCE,partialRipQualityMaxDistance:this.PARTIAL_RIP_QUALITY_MAX_DISTANCE??2*this.PARTIAL_RIP_MAX_DISTANCE,partialRipMaxAttempts:this.PARTIAL_RIP_MAX_ATTEMPTS}}publishOutsideInStats(){this.stats={...this.stats,outsideInRouteCount:this.outsideInRouteCount,outsideInCompletedRouteCount:this.outsideInCompletedRouteCount,outsideInFallbackRouteCount:this.outsideInFallbackRouteCount,outsideInForwardExpansionCount:this.outsideInForwardExpansionCount,outsideInReverseExpansionCount:this.outsideInReverseExpansionCount,outsideInDistancePruneCount:this.outsideInDistancePruneCount,outsideInMaxDistance:this.OUTSIDE_IN_MAX_DISTANCE}}createOutsideInFrontier(t,e,n){const o=new Zz([],(t,e)=\u003et.f===e.f?t.g-e.g:t.f-e.f),i=this.topology.portX[t]-this.topology.portX[n],r=this.topology.portY[t]-this.topology.portY[n],s=Math.sqrt(i*i+r*r)*this.DISTANCE_TO_COST,a={portId:t,nextRegionId:e,f:s,g:0,h:s,travelDistance:0};return o.queue(a),{queue:o,bestCostByHopId:new Map([[this.getHopId(t,e),0]]),settledByPortId:new Map,settledByRegionId:new Map,targetPortId:n}}startOutsideInRouteSearch(t){const e=this.getRouteStartPortId(t),n=this.getRouteEndPortId(t),o=this.getStartingNextRegionId(t,e),i=this.getEndingNextRegionId(t,n);return void 0!==o\u0026\u0026void 0!==i\u0026\u0026(this.state.goalPortId=n,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.outsideInRouteSearch={routeId:t,forward:this.createOutsideInFrontier(e,o,n),reverse:this.createOutsideInFrontier(n,i,e),expandForwardNext:!0,distanceLimitHit:!1,bestJoinedCost:Number.POSITIVE_INFINITY},this.outsideInRouteCount+=1,this.publishOutsideInStats(),!0)}dequeueFreshCandidate(t){for(;t.queue.length\u003e0;){const e=t.queue.dequeue(),n=this.getHopId(e.portId,e.nextRegionId);if(e.g\u003c=(t.bestCostByHopId.get(n)??1/0))return e}}recordSettledCandidate(t,e){const n=t.settledByPortId.get(e.portId);(!n||e.g\u003cn.g)\u0026\u0026t.settledByPortId.set(e.portId,e);const o=t.settledByRegionId.get(e.nextRegionId)??[];o.push(e),o.sort((t,e)=\u003et.g-e.g),o.length\u003e16\u0026\u0026(o.length=16),t.settledByRegionId.set(e.nextRegionId,o)}getCandidatePath(t){const e=[];let n=t;for(;n;)e.push(n),n=n.prevCandidate;return e.reverse(),e}buildJoinedCandidate(t,e){const n=this.getCandidatePath(t),o=this.getCandidatePath(e),i=n.map(({portId:t})=\u003et),r=n.slice(0,-1).map(({nextRegionId:t})=\u003et);if(t.portId!==e.portId){if(t.nextRegionId!==e.nextRegionId)return;const n=this.topology.portX[t.portId]-this.topology.portX[e.portId],o=this.topology.portY[t.portId]-this.topology.portY[e.portId],s=Math.sqrt(n*n+o*o);if(t.travelDistance+e.travelDistance+s\u003e2*this.OUTSIDE_IN_MAX_DISTANCE)return;const a=this.computeG(t,e.portId);if(!Number.isFinite(a))return;r.push(t.nextRegionId),i.push(e.portId)}for(let t=o.length-2;t\u003e=0;t--){const e=o[t];r.push(e.nextRegionId),i.push(e.portId)}if(new Set(i).size!==i.length||r.length+1!==i.length)return;let s={portId:i[0],nextRegionId:r[0],f:0,g:0,h:0};for(let t=1;t\u003ci.length;t++)s={portId:i[t],prevRegionId:r[t-1],nextRegionId:r[t]??r[t-1],prevCandidate:s,f:0,g:0,h:0};const a=t.portId===e.portId?0:this.computeG(t,e.portId)-t.g;return{candidate:s,cost:t.g+e.g+a}}considerOutsideInJoins(t,e){const n=this.outsideInRouteSearch,o=e?n.reverse:n.forward,i=t=\u003e{!t||t.cost\u003e=n.bestJoinedCost||(n.bestJoinedCandidate=t.candidate,n.bestJoinedCost=t.cost,n.remainingPostMeetingExpansions=24)},r=o.settledByPortId.get(t.portId);r\u0026\u0026i(e?this.buildJoinedCandidate(t,r):this.buildJoinedCandidate(r,t));for(const n of o.settledByRegionId.get(t.nextRegionId)??[])i(e?this.buildJoinedCandidate(t,n):this.buildJoinedCandidate(n,t))}commitBestOutsideInJoin(){const t=this.outsideInRouteSearch?.bestJoinedCandidate;return!!t\u0026\u0026(this.onPathFound(t),!0)}expandOutsideInFrontier(t){const e=this.outsideInRouteSearch,n=t?e.forward:e.reverse,o=this.dequeueFreshCandidate(n);if(!o)return!1;if(t?this.outsideInForwardExpansionCount+=1:this.outsideInReverseExpansionCount+=1,this.isRegionReservedForDifferentNet(o.nextRegionId))return!0;this.recordSettledCandidate(n,o),this.considerOutsideInJoins(o,t);for(const t of this.topology.regionIncidentPorts[o.nextRegionId]??[]){if(t===o.portId)continue;if(this.isPortReservedForDifferentNet(t))continue;const i=this.state.portAssignment[t];if(-1!==i\u0026\u0026i!==this.state.currentRouteNetId)continue;if(t!==n.targetPortId\u0026\u00260===this.problem.portSectionMask[t])continue;const r=this.topology.portX[o.portId]-this.topology.portX[t],s=this.topology.portY[o.portId]-this.topology.portY[t],a=Math.sqrt(r*r+s*s),c=o.travelDistance+a;if(c\u003ethis.OUTSIDE_IN_MAX_DISTANCE){e.distanceLimitHit=!0,this.outsideInDistancePruneCount+=1;continue}const l=this.topology.incidentPortRegion[t]?.[0]===o.nextRegionId?this.topology.incidentPortRegion[t]?.[1]:this.topology.incidentPortRegion[t]?.[0];if(void 0===l||this.isRegionReservedForDifferentNet(l))continue;const d=this.getHopId(t,l),h=n.bestCostByHopId.get(d)??1/0;if(o.g\u003e=h)continue;const u=this.computeG(o,t,h,a);if(!Number.isFinite(u)||u\u003e=h)continue;n.bestCostByHopId.set(d,u);const p=this.topology.portX[t]-this.topology.portX[n.targetPortId],m=this.topology.portY[t]-this.topology.portY[n.targetPortId],g=Math.sqrt(p*p+m*m)*this.DISTANCE_TO_COST;n.queue.queue({portId:t,prevRegionId:o.nextRegionId,nextRegionId:l,prevCandidate:o,f:u+g,g:u,h:g,travelDistance:c})}return!0}fallBackToOneSidedRouteSearch(){const t=this.state.currentRouteId;void 0!==t\u0026\u0026(this.outsideInRouteSearch=void 0,this.outsideInFallbackRouteCount+=1,this.oneSidedFallbackRouteId=t,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.goalPortId=-1,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.unroutedRoutes.unshift(t),this.publishOutsideInStats())}_step(){if(!this.OUTSIDE_IN_ROUTING)return void super._step();const t=this.state.currentRouteId??this.state.unroutedRoutes[0];if(void 0!==t\u0026\u0026!this.partialRipRoutePlans.has(t))return void super._step();if(void 0!==this.oneSidedFallbackRouteId)return void super._step();if(void 0===this.state.currentRouteId){if(0===this.state.unroutedRoutes.length)return void this.onAllRoutesRouted();const t=this.state.unroutedRoutes.shift();if(this.state.currentRouteId=t,this.state.currentRouteNetId=this.problem.routeNet[t],this.routeAttemptCountByRouteId[t]+=1,!this.startOutsideInRouteSearch(t))return this.failed=!0,void(this.error=`Route ${t} has an endpoint without an incident region`)}const e=this.outsideInRouteSearch;if(!e)return;let n=this.expandOutsideInFrontier(e.expandForwardNext);if(void 0!==this.state.currentRouteId\u0026\u0026(n||(n=this.expandOutsideInFrontier(!e.expandForwardNext),void 0!==this.state.currentRouteId)))if(e.expandForwardNext=!e.expandForwardNext,e.bestJoinedCandidate\u0026\u0026(e.remainingPostMeetingExpansions=(e.remainingPostMeetingExpansions??1)-1,(e.remainingPostMeetingExpansions??0)\u003c=0))this.commitBestOutsideInJoin();else{if(!n\u0026\u00260===e.forward.queue.length\u0026\u00260===e.reverse.queue.length){if(this.commitBestOutsideInJoin())return;this.outsideInRouteSearch=void 0,e.distanceLimitHit?this.fallBackToOneSidedRouteSearch():this.onOutOfCandidates()}this.publishOutsideInStats()}}shouldReplaceBestSolvedState(t){const e=this.bestSolvedRoundSummary;if(!e)return!0;if(!this.useComplexityAwareSelection)return this.compareRegionCostSummaries(t,e)\u003c0;const n=this.partialRipQualityBaselineSummary;if(!n)return this.compareRegionCostSummaries(t,e)\u003c0;const o=this.firstCompletedRoundSummary??n,i=o.maxRegionCost*(1+Math.max(0,this.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO)),r=o.totalRegionCost*(1+Math.max(0,this.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO)),s=t.maxRegionCost\u003c=i\u0026\u0026t.totalRegionCost\u003c=r;return s!==(e.maxRegionCost\u003c=i\u0026\u0026e.totalRegionCost\u003c=r)?s:s\u0026\u0026t.segmentCount!==e.segmentCount?t.segmentCount\u003ce.segmentCount:this.compareRegionCostSummaries(t,e)\u003c0}onAllRoutesRouted(){if(!this.PARTIAL_RIP_ENABLED)return void super.onAllRoutesRouted();const{state:t,topology:e}=this,n=Math.min(this.RIP_THRESHOLD_RAMP_ATTEMPTS,this.PARTIAL_RIP_MAX_ATTEMPTS),o=Math.max(0,this.RIP_THRESHOLD_RAMP_ATTEMPTS),i=o\u003c=0?1:Math.min(1,t.ripCount/o),r=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*i,s=new Float64Array(e.regionCount),a=[];let c=0,l=0,d=0,h=0,u=0;for(let n=0;n\u003ce.regionCount;n++){const e=t.regionIntersectionCaches[n]?.existingRegionCost??0;s[n]=e,c=Math.max(c,e),l+=e;const o=t.regionSegments[n]?.length??0;d+=o,h=Math.max(h,o),u+=o*o,e\u003er\u0026\u0026a.push(n)}const p={maxRegionCost:c,totalRegionCost:l},m={...p,ripCount:t.ripCount,segmentCount:d,maxRegionSegmentCount:h,squaredRegionSegmentCount:u};this.completedRoundSummaries.push(m),this.firstCompletedRoundSummary??=m,void 0===this.partialRipQualityBaselineSummary\u0026\u0026t.ripCount\u003e=Math.max(0,this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS)\u0026\u0026(this.partialRipQualityBaselineSummary=m);this.shouldReplaceBestSolvedState(m)\u0026\u0026(this.replaceBestSolvedState(p),this.bestSolvedRoundSummary=m);const g=this.firstCompletedRoundSummary,f=this.partialRipQualityBaselineSummary??g,y=Math.max(0,this.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO),_=Math.max(0,this.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO),b=f.maxRegionCost*(1-y),x=f.totalRegionCost*(1+_),v=this.useComplexityAwareSelection\u0026\u0026t.ripCount\u003ef.ripCount\u0026\u0026y\u003e0\u0026\u0026c\u003c=b\u0026\u0026l\u003c=x\u0026\u0026d\u003c=f.segmentCount;if(v\u0026\u0026(this.partialRipTargetReached=!0),this.stats={...this.stats,currentRipThreshold:r,hotRegionCount:a.length,maxRegionCost:c,totalRegionCost:l,bestMaxRegionCost:this.bestSolvedStateSummary?.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary?.totalRegionCost,ripCount:t.ripCount,completedRoundSummaries:this.completedRoundSummaries.map(t=\u003e({...t})),firstMaxRegionCost:g.maxRegionCost,firstTotalRegionCost:g.totalRegionCost,firstSegmentCount:g.segmentCount,firstMaxRegionSegmentCount:g.maxRegionSegmentCount,firstSquaredRegionSegmentCount:g.squaredRegionSegmentCount,partialRipQualityBaselineRipCount:f.ripCount,partialRipQualityBaselineMaxRegionCost:f.maxRegionCost,partialRipQualityBaselineTotalRegionCost:f.totalRegionCost,partialRipQualityBaselineSegmentCount:f.segmentCount,partialRipQualityBaselineMaxRegionSegmentCount:f.maxRegionSegmentCount,partialRipQualityBaselineSquaredRegionSegmentCount:f.squaredRegionSegmentCount,bestSolvedSegmentCount:this.bestSolvedRoundSummary?.segmentCount,bestSolvedMaxRegionSegmentCount:this.bestSolvedRoundSummary?.maxRegionSegmentCount,bestSolvedSquaredRegionSegmentCount:this.bestSolvedRoundSummary?.squaredRegionSegmentCount,partialRipTargetMaxRegionCost:b,partialRipMaxTargetTotalRegionCost:x,partialRipComplexityAwareSelection:this.useComplexityAwareSelection,partialRipComplexitySelectionMinRouteCount:this.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT,partialRipMaxRegionCostGrowthRatio:this.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO,partialRipTargetReached:this.partialRipTargetReached},this.publishPartialRipStats(),0===a.length||v||t.ripCount\u003e=n)return this.restoreBestSolvedState(),void(this.solved=!0);for(let n=0;n\u003ce.regionCount;n++)t.regionCongestionCost[n]+=s[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;const S=t.ripCount\u003cMath.max(0,this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS);t.ripCount+=1;const I=!S\u0026\u0026this.preparePartialRip(a,s);I||this.resetRoutingStateForRerip();const C=S?\"warmup_full\":I?\"partial\":\"full_fallback\";this.stats={...this.stats,ripCount:t.ripCount,maxRegionCostBeforeRip:c,reripRegionCount:a.length,reripMode:C,partialRipWarmupFullRipAttempts:this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS},this.logRipEvent(\"hot_regions\",c,{hotRegionCount:a.length,currentRipThreshold:r,reripMode:C,partialRouteCount:I?this.partialRipRoutePlans.size:0})}},cB=t=\u003e{const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;return Number.isFinite(e)?e:void 0},lB=t=\u003e{const e=new Set;for(const n of t.connections??[])e.add(n.startRegionId),e.add(n.endRegionId);const n=new Set(t.regions.filter(t=\u003e(t=\u003e{if(!0!==t.d?._containsObstacle)return!1;const e=cB(t);return void 0===e||-1===e})(t)\u0026\u0026!e.has(t.regionId)).map(t=\u003et.regionId));if(0===n.size)return t;const o=t.ports.filter(t=\u003e!n.has(t.region1Id)\u0026\u0026!n.has(t.region2Id)),i=(t.connections??[]).find(t=\u003en.has(t.startRegionId)||n.has(t.endRegionId));if(i)throw new Error(`Connection \"${i.connectionId}\" references full-obstacle region`);return{...t,regions:t.regions.filter(t=\u003e!n.has(t.regionId)),ports:o}},dB=t=\u003e{const e=t.d?.bounds;if(e)return e;const n=t.d?.center,o=t.d?.width,i=t.d?.height;return n\u0026\u0026\"number\"==typeof n.x\u0026\u0026\"number\"==typeof n.y\u0026\u0026\"number\"==typeof o\u0026\u0026\"number\"==typeof i?{minX:n.x-o/2,maxX:n.x+o/2,minY:n.y-i/2,maxY:n.y+i/2}:{minX:0,maxX:0,minY:0,maxY:0}},hB=t=\u003eNumber(t.d?.x??0),uB=t=\u003eNumber(t.d?.y??0),pB=(t,e)=\u003e{if(!e)return 0;const n=dB(e),o=hB(t),i=uB(t),r=n.minX\u003c=o\u0026\u0026o\u003c=n.maxX,s=n.minY\u003c=i\u0026\u0026i\u003c=n.maxY;if(s\u0026\u0026o\u003e=n.maxX){const t=Math.max(n.maxY-n.minY,1e-9),e=(i-n.minY)/t;return Math.round(9e3*e)}if(r\u0026\u0026i\u003e=n.maxY){const t=Math.max(n.maxX-n.minX,1e-9),e=(n.maxX-o)/t;return 9e3+Math.round(9e3*e)}if(s\u0026\u0026o\u003c=n.minX){const t=Math.max(n.maxY-n.minY,1e-9),e=(n.maxY-i)/t;return 18e3+Math.round(9e3*e)}if(r\u0026\u0026i\u003c=n.minY){const t=Math.max(n.maxX-n.minX,1e-9),e=(o-n.minX)/t;return 27e3+Math.round(9e3*e)}const a=Math.abs(o-n.minX),c=Math.abs(o-n.maxX),l=Math.abs(i-n.minY),d=Math.abs(i-n.maxY),h=Math.min(a,c,l,d),u=Math.max(n.maxX-n.minX,1e-9),p=Math.max(n.maxY-n.minY,1e-9);if(h===c){const t=(i-n.minY)/p;return Math.round(9e3*t)}if(h===d){const t=(n.maxX-o)/u;return 9e3+Math.round(9e3*t)}if(h===a){const t=(n.maxY-i)/p;return 18e3+Math.round(9e3*t)}const m=(o-n.minX)/u;return 27e3+Math.round(9e3*m)},mB=(t,e)=\u003e{if(!t)return;return[...t.pointIds].sort((t,n)=\u003e{const o=e.get(t),i=e.get(n),r=Number(o?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY),s=Number(i?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY);if(r!==s)return r-s;const a=Number(o?.d?.z??0),c=Number(i?.d?.z??0);return a!==c?a-c:t.localeCompare(n)})[0]},gB=t=\u003e{const e=lB(t),n=new Map,o=new Map,i=new Map,r=new Map((e.solvedRoutes??[]).map(t=\u003e[t.connection.connectionId,t]));e.regions.forEach((t,e)=\u003e{n.set(t.regionId,e)}),e.ports.forEach((t,e)=\u003e{o.set(t.portId,e),i.set(t.portId,t)});const s=e.regions.length,a=e.ports.length,c=e.regions.map(t=\u003et.pointIds.map(t=\u003eo.get(t)).filter(t=\u003evoid 0!==t)),l=Array.from({length:a},()=\u003e[]),d=new Float64Array(s),h=new Float64Array(s),u=new Float64Array(s),p=new Float64Array(s),m=new Int32Array(s),g=new Int32Array(s).fill(-1),f=new Int8Array(s);e.regions.forEach((t,e)=\u003e{const n=(t=\u003e{const e=dB(t),n=\"number\"==typeof t.d?.width?t.d.width:e.maxX-e.minX,o=\"number\"==typeof t.d?.height?t.d.height:e.maxY-e.minY;return{centerX:\"number\"==typeof t.d?.center?.x?t.d.center.x:(e.minX+e.maxX)/2,centerY:\"number\"==typeof t.d?.center?.y?t.d.center.y:(e.minY+e.maxY)/2,width:n,height:o}})(t);d[e]=n.width,h[e]=n.height,u[e]=n.centerX,p[e]=n.centerY,m[e]=(t=\u003e{const e=t.d?.availableZ;if(!Array.isArray(e))return 0;let n=0;for(const t of e)!Number.isInteger(t)||t\u003c0||t\u003e=31||(n|=1\u003c\u003ct);return n})(t);const o=cB(t);void 0!==o\u0026\u0026(g[e]=o,f[e]=1)});const y=new Int32Array(a),_=new Int32Array(a),b=new Float64Array(a),x=new Float64Array(a),v=new Int32Array(a);e.ports.forEach((t,o)=\u003e{const i=n.get(t.region1Id),r=n.get(t.region2Id);if(void 0===i||void 0===r)throw new Error(`Port \"${t.portId}\" references missing regions \"${t.region1Id}\" or \"${t.region2Id}\"`);l[o]=[i,r],b[o]=hB(t),x[o]=uB(t),v[o]=(t=\u003e{const e=Number(t.d?.z??0);return Number.isFinite(e)?e:0})(t),y[o]=pB(t,e.regions[i]),_[o]=pB(t,e.regions[r])});const S=e.regions.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedRegionId\",{value:t.regionId,enumerable:!1,configurable:!0,writable:!0}),n})(t,(t=\u003eRz(Ez(m[t]))??Rz((c[t]??[]).map(t=\u003ev[t]))??\"z0\")(e))),I=e.ports.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedPortId\",{value:t.portId,enumerable:!1,configurable:!0,writable:!0}),n})(t,Rz([v[e]])??\"z0\")),C=e.connections??[],P=new Map;let M=0;const N=t=\u003e{const e=t.mutuallyConnectedNetworkId??t.connectionId;let n=P.get(e);return void 0===n\u0026\u0026(n=M++,P.set(e,n)),n},w=Array.from({length:s},()=\u003enew Set),T=(t,e)=\u003e{const o=n.get(t);if(void 0===o)throw new Error(`Connection references missing region \"${t}\"`);w[o].add(e)};C.forEach(t=\u003e{const e=N(t);T(t.startRegionId,e),T(t.endRegionId,e)}),w.forEach((t,e)=\u003e{1!==f[e]\u0026\u00261===t.size\u0026\u0026(g[e]=[...t][0])});const R=C.map(t=\u003e{const n=r.get(t.connectionId),o=((t,e)=\u003et.ports.filter(t=\u003et.region1Id===e.startRegionId\u0026\u0026t.region2Id===e.endRegionId||t.region2Id===e.startRegionId\u0026\u0026t.region1Id===e.endRegionId).map(t=\u003et.portId))(e,t);return{connection:t,solvedRoute:n,sharedPortIds:o}}).filter(({solvedRoute:t,sharedPortIds:e})=\u003e0===e.length||(t?.path.length??0)\u003e1),E=R.length,A=new Map(R.map(({connection:t},e)=\u003e[t.connectionId,e])),O=new Int8Array(a).fill(1),k=new Int32Array(E),L=new Int32Array(E),D=new Int32Array(E);R.forEach(({connection:t,solvedRoute:n},r)=\u003e{const s=mB(e.regions.find(e=\u003ee.regionId===t.startRegionId),i),a=mB(e.regions.find(e=\u003ee.regionId===t.endRegionId),i),c=n?.path[0]?.portId??s,l=n?.path[n.path.length-1]?.portId??a,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)throw new Error(`Connection \"${t.connectionId}\" could not be mapped to route endpoints`);k[r]=d,L[r]=h,D[r]=N(t)});const z={portCount:a,regionCount:s,regionIncidentPorts:c,incidentPortRegion:l,regionWidth:d,regionHeight:h,regionCenterX:u,regionCenterY:p,regionAvailableZMask:m,regionMetadata:S,portAngleForRegion1:y,portAngleForRegion2:_,portX:b,portY:x,portZ:v,portMetadata:I},F=e.regions.flatMap((t,e)=\u003e(t.assignments??[]).map(n=\u003e{const i=A.get(n.connectionId);if(void 0===i)throw new Error(`Region \"${t.regionId}\" assignment references unknown routable connection \"${n.connectionId}\"`);const r=o.get(n.regionPort1Id),s=o.get(n.regionPort2Id);if(void 0===r||void 0===s)throw new Error(`Region \"${t.regionId}\" assignment references missing port \"${void 0===r?n.regionPort1Id:n.regionPort2Id}\"`);if(!c[e]?.includes(r)||!c[e]?.includes(s))throw new Error(`Region \"${t.regionId}\" assignment ports must both belong to the region`);return{routeId:i,regionId:e,fromPortId:r,toPortId:s}})),B=Float64Array.from(e.ports,t=\u003e{const e=Number(t.d?.tinyHypergraphPortPenalty??0);return Number.isFinite(e)\u0026\u0026e\u003e0?e:0}),j=B.some(t=\u003et\u003e0),$={routeCount:E,portSectionMask:O,routeMetadata:R.map(({connection:t})=\u003et),routeStartPort:k,routeEndPort:L,routeNet:D,regionNetId:g,...F.length\u003e0\u0026\u0026{initialAssignments:F},...j\u0026\u0026{portPenalty:B}},Y=[],X=[];for(const{solvedRoute:t}of R){if(!t){Y.push([]),X.push([]);continue}const e=[],i=[];for(let r=1;r\u003ct.path.length;r++){const s=t.path[r-1],a=t.path[r],c=s?.portId,l=a?.portId,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)continue;const u=\"string\"==typeof s?.nextRegionId?s.nextRegionId:\"string\"==typeof a?.lastRegionId?a.lastRegionId:void 0;e.push([d,h]),i.push(void 0!==u?n.get(u):void 0)}Y.push(e),X.push(i)}return{topology:z,problem:$,solution:{solvedRoutePathSegments:Y,solvedRoutePathRegionIds:X}}},fB=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,yB=t=\u003eArray.isArray(t)?t.map(t=\u003eyB(t)):fB(t)?Object.fromEntries(Object.entries(t).map(([t,e])=\u003e[t,yB(e)])):t,_B=t=\u003efB(t)?{...t}:void 0===t?{}:{value:t},bB=(t,e=0)=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)?t:e,xB=t=\u003e({x:bB(t.d?.x),y:bB(t.d?.y)}),vB=t=\u003e[t.region1Id,t.region2Id].sort().join(\"\\0\"),SB=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y),IB=t=\u003e{const e=Math.hypot(t.x,t.y);if(!(e\u003c=1e-9))return{x:t.x/e,y:t.y/e}},CB=t=\u003e{const e=t?.d?.center;if(fB(e))return{x:bB(e.x),y:bB(e.y)};const n=(t=\u003e{const e=t?.d?.bounds;if(fB(e)\u0026\u0026\"number\"==typeof e.minX\u0026\u0026\"number\"==typeof e.maxX\u0026\u0026\"number\"==typeof e.minY\u0026\u0026\"number\"==typeof e.maxY)return{minX:e.minX,maxX:e.maxX,minY:e.minY,maxY:e.maxY};const n=t?.d?.center,o=bB(t?.d?.width),i=bB(t?.d?.height);if(fB(n)){const t=bB(n.x),e=bB(n.y);return{minX:t-o/2,maxX:t+o/2,minY:e-i/2,maxY:e+i/2}}return{minX:0,maxX:0,minY:0,maxY:0}})(t);return{x:(n.minX+n.maxX)/2,y:(n.minY+n.maxY)/2}},PB=(t,e)=\u003e{const n=vB(t),o=xB(t);let i,r=Number.POSITIVE_INFINITY;for(const s of e){if(s.portId===t.portId)continue;if(vB(s)!==n)continue;const e=SB(o,xB(s));e\u003c=1e-9||e\u003e=r||(i=s,r=e)}return i},MB=(t,e,n)=\u003e{const o=xB(t);if(e){const t=xB(e),n=IB({x:o.x-t.x,y:o.y-t.y});if(n)return n}return((t,e)=\u003e{const n=CB(e.get(t.region1Id)),o=CB(e.get(t.region2Id));return IB({x:-(o.y-n.y),y:o.x-n.x})??{x:1,y:0}})(t,n)},NB=(t,e,n)=\u003e{const o=`${t}::dup${e}`;if(!n.has(o))return n.add(o),o;for(let t=2;;t++){const e=`${o}-${t}`;if(!n.has(e))return n.add(e),e}},wB=(t,e,n)=\u003e{const o=t.indexOf(e);-1!==o?t.splice(o+1,0,...n):t.push(...n)},TB=(t,e)=\u003e{const n=t.portMetadata?.[e];if(fB(n)){if(\"string\"==typeof n.serializedPortId)return n.serializedPortId;if(\"string\"==typeof n.portId)return n.portId}return`port-${e}`},RB=(t,e)=\u003e({routeCount:1,portSectionMask:new Int8Array(t.portSectionMask),routeMetadata:void 0===t.routeMetadata?void 0:[t.routeMetadata[e]],routeStartPort:Int32Array.from([t.routeStartPort[e]]),routeEndPort:Int32Array.from([t.routeEndPort[e]]),routeNet:Int32Array.from([t.routeNet[e]]),regionNetId:new Int32Array(t.regionNetId),portPenalty:void 0===t.portPenalty?void 0:new Float64Array(t.portPenalty)}),EB=t=\u003e{const e=new Set;for(const n of t.state.regionSegments)for(const[,t,o]of n)e.add(t),e.add(o);return 0===e.size\u0026\u00261===t.problem.routeCount\u0026\u0026(e.add(t.problem.routeStartPort[0]),e.add(t.problem.routeEndPort[0])),e},AB=class extends kt{constructor(t,e={}){super(),this.serializedHyperGraph=t,this.options=e}serializedHyperGraph;options;revisedSerializedHyperGraph;report={portUseCounts:{},duplicatedPorts:[]};getDuplicatePortProximity(){return this.options.duplicatePortProximity??.05}getIndividualRouteSolveOptions(){return{RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!1,...this.options.routeSolveOptions}}getPortUseCounts(){const{topology:t,problem:e}=gB(this.serializedHyperGraph);!1===this.options.useSerializedPortPenalties\u0026\u0026(e.portPenalty=void 0);const n=new Map;for(let o=0;o\u003ce.routeCount;o++){const i=RB(e,o),r=new nB(t,i,this.getIndividualRouteSolveOptions());if(r.solve(),!r.solved||r.failed)throw new Error(`Route ${o} could not be solved independently: ${r.error??\"unknown error\"}`);for(const e of EB(r)){const o=TB(t,e);n.set(o,(n.get(o)??0)+1)}}return n}duplicateCongestedPorts(t){const e=this.getDuplicatePortProximity();if(!(e\u003e0))throw new Error(\"duplicatePortProximity must be greater than zero\");const{solvedRoutes:n,...o}=this.serializedHyperGraph,i=this.serializedHyperGraph.regions.map(t=\u003e({...t,pointIds:[...t.pointIds],d:yB(t.d)})),r=this.serializedHyperGraph.ports.map(t=\u003e({...t,d:yB(t.d)})),s=new Map(i.map(t=\u003e[t.regionId,t])),a=new Map(r.map(t=\u003e[t.portId,t])),c=new Set(r.map(t=\u003et.portId)),l=[];for(const[n,o]of[...t.entries()].sort(([t],[e])=\u003et.localeCompare(e))){if(o\u003c=1)continue;const t=a.get(n);if(!t)continue;const i=o-1,d=PB(t,this.serializedHyperGraph.ports),h=MB(t,d,s),u=xB(t),p=[];for(let s=1;s\u003c=i;s++){const a=NB(n,s,c),l=e*s/(i+1),d=_B(yB(t.d));d.x=u.x+h.x*l,d.y=u.y+h.y*l,d.duplicatedFromPortId=n,d.duplicateIndex=s,d.duplicatePortUseCount=o,d.duplicatePortProximity=e,d.repairReason=\"congested-port\",r.push({...t,portId:a,d:d}),p.push(a)}for(const e of[t.region1Id,t.region2Id]){const t=s.get(e);t\u0026\u0026wB(t.pointIds,n,p)}l.push({sourcePortId:n,duplicatePortIds:p,useCount:o})}return this.report={portUseCounts:Object.fromEntries([...t.entries()].sort()),duplicatedPorts:l},{...o,regions:i,ports:r,connections:void 0===this.serializedHyperGraph.connections?void 0:yB(this.serializedHyperGraph.connections)}}_setup(){try{const t=this.getPortUseCounts();this.revisedSerializedHyperGraph=this.duplicateCongestedPorts(t),this.stats={...this.stats,duplicateSourcePortCount:this.report.duplicatedPorts.length,duplicatedPortCount:this.report.duplicatedPorts.reduce((t,e)=\u003et+e.duplicatePortIds.length,0)},this.solved=!0}catch(t){this.failed=!0,this.error=t instanceof Error?t.message:String(t)}}_step(){this.failed||(this.solved=!0)}getOutput(){if(!this.revisedSerializedHyperGraph||this.failed)throw new Error(\"DuplicateCongestedPortSolver does not have a repaired topology output\");return this.revisedSerializedHyperGraph}},OB=(t,e)=\u003e{const n=t.owners.size-e.owners.size;if(0!==n)return n;const o=t.distance-e.distance;return 0!==o?o:t.queueOrder-e.queueOrder},kB=class{heap=[];push(t){this.heap.push(t);let e=this.heap.length-1;for(;e\u003e0;){const t=Math.floor((e-1)/2);if(OB(this.heap[t],this.heap[e])\u003c=0)break;[this.heap[t],this.heap[e]]=[this.heap[e],this.heap[t]],e=t}}pop(){const t=this.heap[0],e=this.heap.pop();if(!t||!e)return null;if(0===this.heap.length)return t;this.heap[0]=e;let n=0;for(;;){const t=2*n+1,e=t+1;let o=n;if(t\u003cthis.heap.length\u0026\u0026OB(this.heap[t],this.heap[o])\u003c0\u0026\u0026(o=t),e\u003cthis.heap.length\u0026\u0026OB(this.heap[e],this.heap[o])\u003c0\u0026\u0026(o=e),o===n)break;[this.heap[n],this.heap[o]]=[this.heap[o],this.heap[n]],n=o}return t}},LB=(t,e)=\u003e!(t.distance\u003ee.distance)\u0026\u0026((t,e)=\u003e{if(t.size\u003ee.size)return!1;for(const n of t)if(!e.has(n))return!1;return!0})(t.owners,e.owners),DB=(t,e)=\u003e{const n=[],o=[];let i=t;for(;null!==i;)n.push(i.state),null!==i.incomingHop\u0026\u0026o.push(i.incomingHop),i=i.parent;return n.reverse(),o.reverse(),{found:!0,states:n,hops:o,owners:new Set(t.owners),distance:t.distance,expandedLabelCount:e}},zB=t=\u003e{for(;;){const e=t.pop();if(null===e)return null;if(e.active)return e}},FB=(t,e)=\u003e{QF(t,e),e\u0026\u0026(void 0!==e.MAX_RIPS\u0026\u0026(t.MAX_RIPS=e.MAX_RIPS),void 0!==e.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT\u0026\u0026(t.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=e.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT),void 0!==e.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST\u0026\u0026(t.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=e.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST))},BB=t=\u003et.map(t=\u003et.map(([t,e,n])=\u003e[t,e,n])),jB=t=\u003e({netIds:new Int32Array(t.netIds),lesserAngles:new Int32Array(t.lesserAngles),greaterAngles:new Int32Array(t.greaterAngles),layerMasks:new Int32Array(t.layerMasks),existingCrossingLayerIntersections:t.existingCrossingLayerIntersections,existingSameLayerIntersections:t.existingSameLayerIntersections,existingEntryExitLayerChanges:t.existingEntryExitLayerChanges,existingRegionCost:t.existingRegionCost,existingSegmentCount:t.existingSegmentCount}),$B=t=\u003e({portAssignment:new Int32Array(t.portAssignment),regionSegments:BB(t.regionSegments),regionIntersectionCaches:t.regionIntersectionCaches.map(jB)}),YB=(t,e)=\u003e{const n=$B(e);t.state.portAssignment=n.portAssignment,t.state.regionSegments=n.regionSegments,t.state.regionIntersectionCaches=n.regionIntersectionCaches},XB=t=\u003e{let e=0,n=0;for(let o=0;o\u003ct.length;o++){const i=t[o]?.existingRegionCost??0;e=Math.max(e,i),n+=i}return{maxRegionCost:e,totalRegionCost:n}},VB=(t,e)=\u003et.maxRegionCost!==e.maxRegionCost?t.maxRegionCost-e.maxRegionCost:t.totalRegionCost-e.totalRegionCost,WB=(t,e,n)=\u003e{const o=t.incidentPortRegion[e]??[],i=t.incidentPortRegion[n]??[],r=o.find(t=\u003ei.includes(t));if(void 0===r)throw new Error(`Ports ${e} and ${n} do not share a region`);return r},HB=(t,e,n,o)=\u003e{const i=n.solvedRoutePathSegments[o]??[],r=n.solvedRoutePathRegionIds?.[o]??[],s=e.routeStartPort[o],a=e.routeEndPort[o];if(0===i.length){if(s===a)return{orderedPortIds:[s],orderedRegionIds:[]};throw new Error(`Route ${o} does not have an existing solved path`)}const c=new Map;i.forEach(([t,e],n)=\u003e{const o={segmentIndex:n,fromPortId:t,toPortId:e,regionId:r[n]},i=c.get(t)??[];i.push(o),c.set(t,i);const s=c.get(e)??[];s.push(o),c.set(e,s)});const l=[s],d=[],h=new Set;let u,p=s;for(;p!==a;){const e=(c.get(p)??[]).filter(({segmentIndex:t,fromPortId:e,toPortId:n})=\u003e{if(h.has(t))return!1;return(e===p?n:e)!==u});if(1!==e.length)throw new Error(`Route ${o} is not a single ordered path from ${s} to ${a}`);const n=e[0],i=n.fromPortId===p?n.toPortId:n.fromPortId;h.add(n.segmentIndex),d.push(n.regionId??WB(t,n.fromPortId,n.toPortId)),l.push(i),u=p,p=i}if(h.size!==i.length)throw new Error(`Route ${o} contains disconnected solved segments`);return{orderedPortIds:l,orderedRegionIds:d}},GB=(t,e,n,o)=\u003e{const i=new nB(t,e,o);return((t,e)=\u003e{t.state.portAssignment.fill(-1),t.state.regionSegments=Array.from({length:t.topology.regionCount},()=\u003e[]),t.state.regionIntersectionCaches=Array.from({length:t.topology.regionCount},()=\u003eqF()),t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.state.unroutedRoutes=[],t.state.candidateQueue.clear(),t.resetCandidateBestCosts(),t.state.goalPortId=-1,t.state.ripCount=0,t.state.regionCongestionCost.fill(0);for(let n=0;n\u003ce.length;n++)for(const[o,i,r]of e[n]??[])t.state.currentRouteNetId=t.problem.routeNet[o],t.state.regionSegments[n].push([o,i,r]),t.state.portAssignment[i]=t.state.currentRouteNetId,t.state.portAssignment[r]=t.state.currentRouteNetId,t.appendSegmentToRegionCache(n,i,r);t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.solved=!0,t.failed=!1,t.error=null})(i,n),i},UB=(t,e,n)=\u003e{const o=new Int32Array(e.routeStartPort),i=new Int32Array(e.routeEndPort),r=Array.from({length:e.routeCount},(t,e)=\u003e({routeId:e,fixedSegments:[]})),s=[];for(let a=0;a\u003ce.routeCount;a++){const c=r[a],{orderedPortIds:l,orderedRegionIds:d}=HB(t,e,n,a),h=[];let u;for(let t=0;t\u003cl.length;t++){const n=l[t],o=1===e.portSectionMask[n];o\u0026\u0026void 0===u?u=t:o||void 0===u||(h.push({startIndex:u,endIndex:t-1}),u=void 0)}if(void 0!==u\u0026\u0026h.push({startIndex:u,endIndex:l.length-1}),0===h.length){for(let t=1;t\u003cl.length;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});continue}if(h.length\u003e1)throw new Error(`Route ${a} enters the section multiple times; only one contiguous section span is currently supported`);const p=h[0],m=Math.max(0,p.startIndex-1),g=Math.min(l.length-1,p.endIndex+1);if(g\u003c=m)throw new Error(`Route ${a} does not have a valid section span`);for(let t=1;t\u003c=m;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});for(let t=g+1;t\u003cl.length;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});c.activeStartPortId=l[m],c.activeEndPortId=l[g],c.forcedStartRegionId=d[m],o[a]=c.activeStartPortId,i[a]=c.activeEndPortId,s.push(a)}return{sectionProblem:{routeCount:e.routeCount,portSectionMask:new Int8Array(e.portSectionMask),routeMetadata:e.routeMetadata,routeStartPort:o,routeEndPort:i,routeNet:new Int32Array(e.routeNet),regionNetId:new Int32Array(e.regionNetId),portPenalty:void 0===e.portPenalty?void 0:new Float64Array(e.portPenalty)},routePlans:r,activeRouteIds:s}},ZB=(t,e,n)=\u003eUB(t,e,n).activeRouteIds,qB=class extends nB{constructor(t,e,n,o,i,r,s,a){super(t,e,a),this.routePlans=n,this.activeRouteIds=o,this.mutableRegionIds=i,this.immutableRegionSummary=r,this.baselineSummary=s,FB(this,a),this.state.unroutedRoutes=[...o],this.applyFixedSegments(),this.fixedSnapshot=$B({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches})}routePlans;activeRouteIds;mutableRegionIds;immutableRegionSummary;baselineSummary;bestSnapshot;fixedSnapshot;bestSummary;baselineBeatRipCount;previousBestMaxRegionCost=Number.POSITIVE_INFINITY;ripsSinceBestMaxRegionCostImprovement=0;MAX_RIPS=Number.POSITIVE_INFINITY;MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=Number.POSITIVE_INFINITY;EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=Number.POSITIVE_INFINITY;applyFixedSegments(){for(const t of this.routePlans)for(const{regionId:e,fromPortId:n,toPortId:o}of t.fixedSegments)this.state.currentRouteNetId=this.problem.routeNet[t.routeId],this.state.regionSegments[e].push([t.routeId,n,o]),this.state.portAssignment[n]=this.state.currentRouteNetId,this.state.portAssignment[o]=this.state.currentRouteNetId,this.appendSegmentToRegionCache(e,n,o);this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0}captureBestState(t){this.bestSummary\u0026\u0026VB(t,this.bestSummary)\u003e=0||(this.bestSummary=t,this.bestSnapshot=$B({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches}))}restoreBestState(){this.bestSnapshot\u0026\u0026(YB(this,this.bestSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1)}getStartingNextRegionId(t,e){const n=this.routePlans[t]?.forcedStartRegionId;return void 0!==n?n:super.getStartingNextRegionId(t,e)}resetRoutingStateForRerip(){if(!this.fixedSnapshot)return super.resetRoutingStateForRerip(),this.state.unroutedRoutes=qz([...this.activeRouteIds],this.state.ripCount),void this.applyFixedSegments();YB(this,this.fixedSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=qz([...this.activeRouteIds],this.state.ripCount),this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1}onAllRoutesRouted(){const{state:t}=this,e=Math.min(this.MAX_RIPS,this.RIP_THRESHOLD_RAMP_ATTEMPTS),n=e\u003c=0?1:Math.min(1,t.ripCount/e),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(this.mutableRegionIds.length);let s=0,a=0;for(let e=0;e\u003cthis.mutableRegionIds.length;e++){const n=this.mutableRegionIds[e],c=t.regionIntersectionCaches[n]?.existingRegionCost??0;r[e]=c,s=Math.max(s,c),a+=c,c\u003eo\u0026\u0026i.push(n)}const c=Math.max(this.immutableRegionSummary.maxRegionCost,s),l=this.immutableRegionSummary.totalRegionCost+a;this.captureBestState({maxRegionCost:c,totalRegionCost:l});const d=this.bestSummary??{maxRegionCost:c,totalRegionCost:l};if(d.maxRegionCost\u003cthis.previousBestMaxRegionCost-Number.EPSILON?(this.previousBestMaxRegionCost=d.maxRegionCost,this.ripsSinceBestMaxRegionCostImprovement=0):this.ripsSinceBestMaxRegionCostImprovement+=1,void 0===this.baselineBeatRipCount\u0026\u0026d.maxRegionCost\u003cthis.baselineSummary.maxRegionCost-Number.EPSILON\u0026\u0026(this.baselineBeatRipCount=t.ripCount),this.stats={...this.stats,activeRouteCount:this.activeRouteIds.length,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:c,totalRegionCost:l,bestMaxRegionCost:d.maxRegionCost,bestTotalRegionCost:d.totalRegionCost,ripCount:t.ripCount},0===i.length||t.ripCount\u003e=e||this.ripsSinceBestMaxRegionCostImprovement\u003e=this.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT||void 0!==this.baselineBeatRipCount\u0026\u0026t.ripCount-this.baselineBeatRipCount\u003e=this.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST)return this.restoreBestState(),void(this.solved=!0);for(let e=0;e\u003cthis.mutableRegionIds.length;e++){const n=this.mutableRegionIds[e];t.regionCongestionCost[n]+=r[e]*this.RIP_CONGESTION_REGION_COST_FACTOR}t.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:t.ripCount,reripRegionCount:i.length}}onOutOfCandidates(){const{state:t}=this;for(const e of this.mutableRegionIds){const n=t.regionIntersectionCaches[e]?.existingRegionCost??0;t.regionCongestionCost[e]+=n*this.RIP_CONGESTION_REGION_COST_FACTOR}t.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:t.ripCount,reripReason:\"out_of_candidates\"}}tryFinalAcceptance(){if(this.bestSnapshot)return this.restoreBestState(),void(this.solved=!0);this.fixedSnapshot\u0026\u0026YB(this,this.fixedSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[...this.activeRouteIds],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.stats={...this.stats,acceptedFixedSectionStateOnTimeout:!0},this.solved=!0}visualize(){return UF(this,{highlightSectionMask:!0,showInitialRouteHints:!1,showOnlySectionPortsOnIdle:!0})}},JB=class extends kt{constructor(t,e,n,o){super(),this.topology=t,this.problem=e,this.initialSolution=n,FB(this,o),this.baselineSolver=((t,e,n,o)=\u003e{const i=Array.from({length:t.regionCount},()=\u003e[]);for(let o=0;o\u003ce.routeCount;o++){const{orderedPortIds:r,orderedRegionIds:s}=HB(t,e,n,o);for(let t=1;t\u003cr.length;t++){const e=r[t-1],n=r[t];i[s[t-1]].push([o,e,n])}}return GB(t,e,i,o)})(t,e,n,tB(this)),this.baselineSummary=XB(this.baselineSolver.state.regionIntersectionCaches),this.sectionRegionIds=((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ce.portSectionMask.length;o++)if(1===e.portSectionMask[o])for(const e of t.incidentPortRegion[o]??[])n.add(e);return[...n]})(t,e),this.sectionBaselineSummary=((t,e)=\u003e{let n=0,o=0;for(const i of e){const e=t[i]?.existingRegionCost??0;n=Math.max(n,e),o+=e}return{maxRegionCost:n,totalRegionCost:o}})(this.baselineSolver.state.regionIntersectionCaches,this.sectionRegionIds),this.outsideSectionBaselineSummary=((t,e)=\u003e{const n=new Set(e);let o=0,i=0;for(let e=0;e\u003ct.length;e++){if(n.has(e))continue;const r=t[e]?.existingRegionCost??0;o=Math.max(o,r),i+=r}return{maxRegionCost:o,totalRegionCost:i}})(this.baselineSolver.state.regionIntersectionCaches,this.sectionRegionIds),this.applySectionRipPolicy()}topology;problem;initialSolution;baselineSolver;baselineSummary;sectionBaselineSummary;outsideSectionBaselineSummary;sectionRegionIds;optimizedSolver;sectionSolver;activeRouteIds=[];DISTANCE_TO_COST=.05;minViaPadDiameter=Yz;VERBOSE=!1;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;MAX_RIPS=Number.POSITIVE_INFINITY;MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=10;EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=10;RIP_CONGESTION_REGION_COST_FACTOR=.1;MAX_ITERATIONS=1e6;STATIC_REACHABILITY_PRECHECK=!1;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;ACCEPT_BEST_SOLUTION_ON_TIMEOUT=!0;GREEDY_FINAL_ROUTE_ITERS=4;applySectionRipPolicy(){this.RIP_THRESHOLD_START=.05,this.RIP_THRESHOLD_END=Math.max(this.RIP_THRESHOLD_START,this.sectionBaselineSummary.maxRegionCost),this.MAX_RIPS=Math.min(this.MAX_RIPS,20)}_setup(){this.applySectionRipPolicy();const{sectionProblem:t,routePlans:e,activeRouteIds:n}=UB(this.topology,this.problem,this.initialSolution);if(this.activeRouteIds=n,0===n.length)return this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,activeRouteCount:0,initialMaxRegionCost:this.baselineSummary.maxRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,optimized:!1},void(this.solved=!0);var o;this.sectionSolver=new qB(this.topology,t,e,n,this.sectionRegionIds,this.outsideSectionBaselineSummary,this.baselineSummary,{...tB(o=this),MAX_RIPS:o.MAX_RIPS,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:o.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:o.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST}),this.activeSubSolver=this.sectionSolver,this.stats={...this.stats,sectionBaselineMaxRegionCost:this.sectionBaselineSummary.maxRegionCost,sectionBaselineTotalRegionCost:this.sectionBaselineSummary.totalRegionCost,effectiveRipThresholdStart:this.RIP_THRESHOLD_START,effectiveRipThresholdEnd:this.RIP_THRESHOLD_END,effectiveMaxRips:this.MAX_RIPS}}_step(){if(!this.sectionSolver)return void(this.solved=!0);if(this.sectionSolver.step(),this.stats={...this.stats,...this.sectionSolver.stats,activeRouteCount:this.activeRouteIds.length},this.sectionSolver.failed)return this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,finalTotalRegionCost:this.baselineSummary.totalRegionCost,optimized:!1,sectionSearchFailedFallbackToBaseline:!0,sectionSearchError:this.sectionSolver.error},void(this.solved=!0);if(!this.sectionSolver.solved)return;const t=GB(this.topology,this.problem,BB(this.sectionSolver.state.regionSegments),tB(this)),e=XB(t.state.regionIntersectionCaches),n=VB(e,this.baselineSummary)\u003c0;this.optimizedSolver=n?t:this.baselineSolver;const o=n?e:this.baselineSummary;this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,candidateMaxRegionCost:e.maxRegionCost,candidateTotalRegionCost:e.totalRegionCost,finalMaxRegionCost:o.maxRegionCost,finalTotalRegionCost:o.totalRegionCost,optimized:n},this.solved=!0}tryFinalAcceptance(){this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,finalTotalRegionCost:this.baselineSummary.totalRegionCost,optimized:!1,sectionSolverTimeoutFallbackToBaseline:!0},this.solved=!0,this.failed=!1,this.error=null}getSolvedSolver(){if(!this.solved||this.failed||!this.optimizedSolver)throw new Error(\"TinyHyperGraphSectionSolver does not have a solved output yet\");return this.optimizedSolver}visualize(){return this.optimizedSolver?UF(this.optimizedSolver,{highlightSectionMask:!0}):this.sectionSolver?this.sectionSolver.visualize():UF(this.baselineSolver,{highlightSectionMask:!0,showInitialRouteHints:!1,showOnlySectionPortsOnIdle:!0})}getOutput(){return this.getSolvedSolver().getOutput()}},KB=[\"self-touch\",\"onehop-all\",\"onehop-touch\",\"twohop-all\",\"twohop-touch\"],QB={\"self-all\":0,\"self-touch\":0,\"onehop-all\":1,\"onehop-touch\":1,\"twohop-all\":2,\"twohop-touch\":2,\"threehop-all\":3,\"threehop-touch\":3,\"fourhop-all\":4,\"fourhop-touch\":4},tj=(t,e)=\u003e{const n=new Set(e);for(const o of e)for(const e of t.regionIncidentPorts[o]??[])for(const o of t.incidentPortRegion[e]??[])n.add(o);return[...n]},ej=(t,e,n)=\u003e{let o=[...new Set(e)];for(let e=0;e\u003cn;e+=1)o=tj(t,o);return o},nj=(t,e,n)=\u003ee.flatMap(e=\u003en.map(n=\u003e((t,e,n)=\u003e({label:`hot-${e}-${n}`,family:n,regionIds:ej(t,[e],QB[n]),portSelectionRule:n.endsWith(\"-all\")?\"all-incident-regions-selected\":\"touches-selected-region\"}))(t,e,n))),oj={RIP_THRESHOLD_RAMP_ATTEMPTS:5},ij={DISTANCE_TO_COST:.05,RIP_THRESHOLD_RAMP_ATTEMPTS:16,RIP_CONGESTION_REGION_COST_FACTOR:.1,MAX_ITERATIONS:5e4,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:6,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:Number.POSITIVE_INFINITY},rj=t=\u003et.state.regionIntersectionCaches.reduce((t,e)=\u003eMath.max(t,e.existingRegionCost),0),sj=(t,e)=\u003e{const n=gB(t),o=new JB(n.topology,n.problem,n.solution,e);return rj(o.baselineSolver)},aj=(t,e,n)=\u003e{const o=new Set(e);return Int8Array.from({length:t.portCount},(e,i)=\u003e{const r=t.incidentPortRegion[i]??[];return\"touches-selected-region\"===n?r.some(t=\u003eo.has(t))?1:0:r.length\u003e0\u0026\u0026r.every(t=\u003eo.has(t))?1:0})},cj=(t,e)=\u003e({routeCount:t.routeCount,portSectionMask:e,routeMetadata:t.routeMetadata,routeStartPort:new Int32Array(t.routeStartPort),routeEndPort:new Int32Array(t.routeEndPort),routeNet:new Int32Array(t.routeNet),regionNetId:new Int32Array(t.regionNetId),portPenalty:void 0===t.portPenalty?void 0:new Float64Array(t.portPenalty)}),lj=(t,e,n,o,i,r)=\u003e{const s=performance.now(),a=performance.now(),c=new JB(e,n,o,r),l=rj(c.baselineSolver),d=performance.now()-a;let h,u,p=l,m=new Int8Array(e.portCount),g=0,f=0,y=0,_=0,b=0,x=0,v=0;const S=new Set,I=i?.maxHotRegions??r.MAX_HOT_REGIONS??2;for(const s of((t,e,n,o)=\u003e{const i=t.state.regionIntersectionCaches.map((t,e)=\u003e({regionId:e,regionCost:t.existingRegionCost})).filter(({regionCost:t})=\u003et\u003e0).sort((t,e)=\u003ee.regionCost-t.regionCost).slice(0,n).map(({regionId:t})=\u003et);return nj(e,i,o)})(t,e,I,i?.candidateFamilies??[...KB])){const t=cj(n,aj(e,s.regionIds,s.portSelectionRule));g+=1;const i=t.portSectionMask.join(\",\");if(S.has(i))y+=1;else{S.add(i);try{const n=performance.now(),i=ZB(e,t,o);if(_+=performance.now()-n,0===i.length)continue;f+=1;const a=performance.now(),c=new JB(e,t,o,r);b+=performance.now()-a;const l=performance.now();if(c.solve(),x+=performance.now()-l,c.failed||!c.solved)continue;if(Number(c.stats.finalMaxRegionCost??rj(c.getSolvedSolver()))\u003cp-1e-9){const e=performance.now(),n=sj(c.getOutput(),r);v+=performance.now()-e,n\u003cp-1e-9\u0026\u0026(p=n,m=new Int8Array(t.portSectionMask),h=s.label,u=s.family)}}catch{}}}return{portSectionMask:m,baselineMaxRegionCost:l,finalMaxRegionCost:p,generatedCandidateCount:g,candidateCount:f,duplicateCandidateCount:y,totalMs:performance.now()-s,baselineEvaluationMs:d,candidateEligibilityMs:_,candidateInitMs:b,candidateSolveMs:x,candidateReplayScoreMs:v,winningCandidateLabel:h,winningCandidateFamily:u}},dj=class extends Dt{initialVisualizationSolver;selectedSectionMask;selectedSectionCandidateLabel;selectedSectionCandidateFamily;constructor(t){super(t),this.MAX_ITERATIONS=2e5}loadHyperGraph(t){return gB(t)}getSolveGraphOptions(){return{...oj,...void 0===this.inputProblem.minViaPadDiameter?{}:{minViaPadDiameter:this.inputProblem.minViaPadDiameter},...this.inputProblem.solveGraphOptions}}getSectionSolverOptions(){return{...ij,...void 0===this.inputProblem.minViaPadDiameter?{}:{minViaPadDiameter:this.inputProblem.minViaPadDiameter},...this.inputProblem.sectionSolverOptions}}pipelineDef=[{solverName:\"solveGraph\",solverClass:nB,getConstructorParams:t=\u003e{const{topology:e,problem:n}=t.loadHyperGraph(t.inputProblem.serializedHyperGraph);return[e,n,t.getSolveGraphOptions()]}},{solverName:\"optimizeSection\",solverClass:JB,getConstructorParams:t=\u003et.getSectionStageParams()}];getSectionStageParams(){const t=this.getStageOutput(\"solveGraph\");if(!t)throw new Error(\"solveGraph did not produce a solved serialized hypergraph\");const e=this.getSolver(\"solveGraph\");if(!e)throw new Error(\"solveGraph solver is unavailable\");const n=this.getSectionSolverOptions(),{topology:o,problem:i,solution:r}=this.loadHyperGraph(t),s=this.inputProblem.createSectionMask?this.inputProblem.createSectionMask({serializedHyperGraph:this.inputProblem.serializedHyperGraph,solvedSerializedHyperGraph:t,solvedSolver:e,topology:o,problem:i,solution:r}):(()=\u003e{const t=lj(e,o,i,r,this.inputProblem.sectionSearchConfig,n);return this.selectedSectionCandidateLabel=t.winningCandidateLabel,this.selectedSectionCandidateFamily=t.winningCandidateFamily,this.stats={...this.stats,sectionSearchGeneratedCandidateCount:t.generatedCandidateCount,sectionSearchCandidateCount:t.candidateCount,sectionSearchDuplicateCandidateCount:t.duplicateCandidateCount,sectionSearchBaselineMaxRegionCost:t.baselineMaxRegionCost,sectionSearchFinalMaxRegionCost:t.finalMaxRegionCost,sectionSearchDelta:t.baselineMaxRegionCost-t.finalMaxRegionCost,selectedSectionCandidateLabel:t.winningCandidateLabel??null,selectedSectionCandidateFamily:t.winningCandidateFamily??null,sectionSearchMs:t.totalMs,sectionSearchBaselineEvaluationMs:t.baselineEvaluationMs,sectionSearchCandidateEligibilityMs:t.candidateEligibilityMs,sectionSearchCandidateInitMs:t.candidateInitMs,sectionSearchCandidateSolveMs:t.candidateSolveMs,sectionSearchCandidateReplayScoreMs:t.candidateReplayScoreMs},t.portSectionMask})();return this.selectedSectionMask=new Int8Array(s),i.portSectionMask=new Int8Array(s),this.stats={...this.stats,sectionMaskPortCount:[...s].filter(t=\u003e1===t).length},[o,i,r,n]}getInitialVisualizationSolver(){if(!this.initialVisualizationSolver){const{topology:t,problem:e}=this.loadHyperGraph(this.inputProblem.serializedHyperGraph);this.initialVisualizationSolver=new nB(t,e,this.getSolveGraphOptions())}return this.initialVisualizationSolver}initialVisualize(){return this.getInitialVisualizationSolver().visualize()}visualize(){return 0===this.iterations?this.initialVisualize()??super.visualize():super.visualize()}getOutput(){return this.getStageOutput(\"optimizeSection\")??this.getStageOutput(\"solveGraph\")??null}tryFinalAcceptance(){this.getStageOutput(\"solveGraph\")\u0026\u0026(this.stats={...this.stats,acceptedSolveGraphOutputOnSectionPipelineTimeout:!0},this.activeSubSolver=void 0,this.solved=!0,this.failed=!1,this.error=null)}};var hj=class extends aB{failedOwnerPairCounts=new Map;selectiveReripStats={selectiveRipCount:0,selectivelyRippedRouteCount:0,globalReripCount:0,alternateBlockerSearchCount:0,alternateOwnerCount:0,failedOwnerPairCount:0,maxFailedOwnerPairCount:0,failedOwnerPairs:[],lastDirectOwnerRouteIds:[],lastRepeatedOwnerRouteIds:[],lastAlternateOwnerRouteIds:[],lastRippedRouteIds:[],lastRelaxedSearchExpandedLabelCount:0,lastAlternateSearchExpandedLabelCount:0};selectiveReripCongestionUpdateCount=0;constructor(t,e,n){super(t,e,n)}getSelectiveReripStats(){return{...this.selectiveReripStats,failedOwnerPairs:this.selectiveReripStats.failedOwnerPairs.map(t=\u003e({...t})),lastDirectOwnerRouteIds:[...this.selectiveReripStats.lastDirectOwnerRouteIds],lastRepeatedOwnerRouteIds:[...this.selectiveReripStats.lastRepeatedOwnerRouteIds],lastAlternateOwnerRouteIds:[...this.selectiveReripStats.lastAlternateOwnerRouteIds],lastRippedRouteIds:[...this.selectiveReripStats.lastRippedRouteIds]}}onOutOfCandidates(){const t=this.state.currentRouteId;if(void 0===t)throw new Error(\"SelectiveReripTinyHyperGraphSolver: candidate search exhausted without a current route\");const e=this.findRelaxedBlockerPathPreferringPreservedRoutes();if(!e.found||0===e.owners.size)return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=e.found?\"no_blocker_path\":e.reason,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=[],this.selectiveReripStats.lastRepeatedOwnerRouteIds=[],this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=0,super.onOutOfCandidates(),void this.publishSelectiveReripStats();const n=[...e.owners],o=[];for(const e of n){this.incrementFailedOwnerPair(t,e)\u003e=2\u0026\u0026o.push(e)}if(n.some(e=\u003ethis.hasFailedOwnerPath(e,t)))return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=\"failed_owner_cycle\",this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=0,this.failedOwnerPairCounts.clear(),super.onOutOfCandidates(),void this.publishSelectiveReripStats();let i;if(o.length\u003e0\u0026\u0026(this.selectiveReripStats.alternateBlockerSearchCount+=1,i=this.findRelaxedBlockerPathPreferringPreservedRoutes(new Set(o)),!i.found))return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=i.reason,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=i.expandedLabelCount,super.onOutOfCandidates(),void this.publishSelectiveReripStats();const r=i?.found?[...i.owners]:void 0,s=function(t){const e=new Set(t.alternateOwnerRouteIds??t.directOwnerRouteIds);if(e.delete(t.failedRouteId),0===e.size)throw new Error(`SelectiveReripTinyHyperGraphSolver: route ${t.failedRouteId} has blocker resources but no distinct committed owner can be reripped`);return e}({failedRouteId:t,directOwnerRouteIds:n,alternateOwnerRouteIds:r});this.clearPartialRipPlans(s);const a=(r??[]).filter(t=\u003e!e.owners.has(t));this.selectiveReripCongestionUpdateCount\u003c1\u0026\u0026(this.addCongestionCostForSelectiveRerip(),this.selectiveReripCongestionUpdateCount+=1),this.rebuildCommittedState(s),this.state.ripCount+=1,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=function(t){const e=t.pendingRouteIds.filter(e=\u003ee!==t.failedRouteId\u0026\u0026!t.rippedRouteIds.has(e)),n=[...t.rippedRouteIds].filter(e=\u003ee!==t.failedRouteId);return[t.failedRouteId,...e,...n]}({failedRouteId:t,pendingRouteIds:this.state.unroutedRoutes,rippedRouteIds:s}),this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.selectiveReripStats.selectiveRipCount+=1,this.selectiveReripStats.selectivelyRippedRouteCount+=s.size,this.selectiveReripStats.alternateOwnerCount+=a.length,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=a,this.selectiveReripStats.lastRippedRouteIds=[...s],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=i?.expandedLabelCount??0,this.publishSelectiveReripStats()}addCongestionCostForSelectiveRerip(){for(let t=0;t\u003cthis.topology.regionCount;t++){const e=this.state.regionIntersectionCaches[t]?.existingRegionCost??0;this.state.regionCongestionCost[t]+=e*this.RIP_CONGESTION_REGION_COST_FACTOR}}findRelaxedBlockerPath(t=new Set){const e=this.state.currentRouteId,n=this.state.currentRouteNetId;if(void 0===e||void 0===n)throw new Error(\"SelectiveReripTinyHyperGraphSolver: blocker search requires a current route and net\");const o=this.getRouteStartPortId(e),i=this.getRouteEndPortId(e),r=this.getStartingNextRegionId(e,o);if(void 0===r)throw new Error(`SelectiveReripTinyHyperGraphSolver: route ${this.describeRoute(e)} has no starting region for blocker search`);const s=this.getPortOwners();return(t=\u003e{const e=t.maxExpandedLabels??Number.POSITIVE_INFINITY;if(e!==Number.POSITIVE_INFINITY\u0026\u0026(!Number.isInteger(e)||e\u003c0))throw new Error(\"maxExpandedLabels must be a non-negative integer\");const n=new Map,o=new kB;let i=0,r=0;const s={state:t.start,stateKey:t.getStateKey(t.start),owners:new Set,distance:0,parent:null,incomingHop:null,queueOrder:i++,active:!0};for(n.set(s.stateKey,[s]),o.push(s);;){const s=zB(o);if(null===s)return{found:!1,reason:\"no_path\",expandedLabelCount:r};if(t.isGoal(s.state))return DB(s,r);if(r\u003e=e)return{found:!1,reason:\"expansion_limit\",expandedLabelCount:r};r++;for(const e of t.getHops(s.state)){if(!Number.isFinite(e.distance)||e.distance\u003c0)throw new Error(\"Distinct-owner blocker hops require finite distances \u003e= 0\");const r=new Set(s.owners);for(const t of e.owners??[])r.add(t);const a=s.distance+e.distance;if(!Number.isFinite(a))throw new Error(\"Distinct-owner blocker path distance overflowed\");const c={state:e.state,stateKey:t.getStateKey(e.state),owners:r,distance:a,parent:s,incomingHop:e,queueOrder:i++,active:!0},l=n.get(c.stateKey)??[];if(l.some(t=\u003eLB(t,c)))continue;const d=[];for(const t of l)LB(c,t)?t.active=!1:d.push(t);d.push(c),n.set(c.stateKey,d),o.push(c)}}})({start:{portId:o,nextRegionId:r},getStateKey:({portId:t,nextRegionId:e})=\u003ethis.getHopId(t,e),isGoal:({portId:t})=\u003et===i,getHops:e=\u003ethis.getRelaxedSearchHops({state:e,goalPortId:i,routeNetId:n,portOwners:s,forbiddenOwnerRouteIds:t}),maxExpandedLabels:this.getRelaxedSearchExpansionLimit()})}findRelaxedBlockerPathPreferringPreservedRoutes(t=new Set){const e=this.getRouteIdsPreferredForPreservation();if(0===e.size)return this.findRelaxedBlockerPath(t);const n=new Set(t);for(const t of e)n.add(t);const o=this.findRelaxedBlockerPath(n);return o.found\u0026\u0026o.owners.size\u003e0?o:this.findRelaxedBlockerPath(t)}getRelaxedSearchExpansionLimit(){let t=0;for(const e of this.topology.incidentPortRegion)t+=e.length;const e=Math.max(4,Math.ceil(Math.log2(this.problem.routeCount+1)));return Math.max(4096,t*e*4)}getRelaxedSearchHops(t){const{state:e,goalPortId:n,routeNetId:o}=t;if(this.isRegionReservedForDifferentNet(e.nextRegionId))return[];const i=[];for(const r of this.topology.regionIncidentPorts[e.nextRegionId]??[]){if(r===e.portId)continue;if(this.isPortReservedForDifferentNet(r))continue;if(r!==n\u0026\u00260===this.problem.portSectionMask[r])continue;const s=this.getHopBlockerResources({regionId:e.nextRegionId,fromPortId:e.portId,toPortId:r,routeNetId:o,portOwners:t.portOwners}),a=[...new Set(s.flatMap(t=\u003et.owners))];if(a.some(e=\u003et.forbiddenOwnerRouteIds.has(e)))continue;let c=e.nextRegionId;if(r!==n){const[t,n]=this.topology.incidentPortRegion[r]??[];if(c=t===e.nextRegionId?n:t,void 0===c||this.isRegionReservedForDifferentNet(c))continue}i.push({state:{portId:r,nextRegionId:c},distance:Math.hypot(this.topology.portX[e.portId]-this.topology.portX[r],this.topology.portY[e.portId]-this.topology.portY[r]),owners:a,data:{resources:s}})}return i}getHopBlockerResources(t){const e=[],n=this.state.portAssignment[t.toPortId];if(-1!==n\u0026\u0026n!==t.routeNetId){const o=[...t.portOwners.get(t.toPortId)??new Set].filter(e=\u003ethis.problem.routeNet[e]!==t.routeNetId);if(0===o.length)throw new Error(`SelectiveReripTinyHyperGraphSolver: port ${t.toPortId} is assigned to foreign net ${n} without a committed route owner`);e.push({kind:\"port\",portId:t.toPortId,owners:o})}const o=this.getHardBlockedCrossingOwners(t.regionId,t.fromPortId,t.toPortId);return o.length\u003e0\u0026\u0026e.push({kind:\"same_layer_intersection\",regionId:t.regionId,fromPortId:t.fromPortId,toPortId:t.toPortId,owners:o}),e}getPortOwners(){const t=new Map;for(const e of this.state.regionSegments)for(const[n,o,i]of e)for(const e of[o,i]){const o=t.get(e)??new Set;o.add(n),t.set(e,o)}return t}getHardBlockedCrossingOwners(t,e,n){if(!this.isKnownSingleLayerRegion(t))return[];const o=this.state.currentRouteNetId;if(void 0===o)throw new Error(\"SelectiveReripTinyHyperGraphSolver: crossing ownership requires a current route net\");const i=new Set;for(const[r,s,a]of this.state.regionSegments[t]??[])this.problem.routeNet[r]!==o\u0026\u0026this.segmentsCrossOnSameLayer(t,e,n,s,a)\u0026\u0026i.add(r);return[...i]}segmentsCrossOnSameLayer(t,e,n,o,i){const r={...this.populateSegmentGeometryScratch(t,e,n)},s={...this.populateSegmentGeometryScratch(t,o,i)};if(0===(r.layerMask\u0026s.layerMask))return!1;if(r.lesserAngle===s.lesserAngle||r.lesserAngle===s.greaterAngle||r.greaterAngle===s.lesserAngle||r.greaterAngle===s.greaterAngle)return!1;return(r.lesserAngle\u003cs.lesserAngle\u0026\u0026s.lesserAngle\u003cr.greaterAngle)!==(r.lesserAngle\u003cs.greaterAngle\u0026\u0026s.greaterAngle\u003cr.greaterAngle)}rebuildCommittedState(t){this.state.regionSegments=this.state.regionSegments.map(e=\u003ee.filter(([e])=\u003e!t.has(e))),this.state.portAssignment.fill(-1),this.state.regionIntersectionCaches=Array.from({length:this.topology.regionCount},()=\u003eqF());for(let t=0;t\u003cthis.state.regionSegments.length;t++)for(const[e,n,o]of this.state.regionSegments[t]){const i=this.problem.routeNet[e];this.state.currentRouteNetId=i;for(const t of[n,o]){const e=this.state.portAssignment[t];if(-1!==e\u0026\u0026e!==i)throw new Error(`SelectiveReripTinyHyperGraphSolver: rebuilding committed routes found cross-net ownership at port ${t} between net ${e} and net ${i}`);this.state.portAssignment[t]=i}this.appendSegmentToRegionCache(t,n,o)}this.state.currentRouteNetId=void 0}incrementFailedOwnerPair(t,e){const n=this.failedOwnerPairCounts.get(t)??new Map,o=(n.get(e)??0)+1;return n.set(e,o),this.failedOwnerPairCounts.set(t,n),o}hasFailedOwnerPath(t,e){const n=[t],o=new Set;for(;n.length\u003e0;){const t=n.pop();if(t===e)return!0;o.has(t)||(o.add(t),n.push(...this.failedOwnerPairCounts.get(t)?.keys()??[]))}return!1}publishSelectiveReripStats(){const t=[];for(const[e,n]of this.failedOwnerPairCounts)for(const[o,i]of n)t.push({failedRouteId:e,ownerRouteId:o,count:i});t.sort((t,e)=\u003et.failedRouteId-e.failedRouteId||t.ownerRouteId-e.ownerRouteId),this.selectiveReripStats.failedOwnerPairs=t,this.selectiveReripStats.failedOwnerPairCount=t.length,this.selectiveReripStats.maxFailedOwnerPairCount=Math.max(0,...t.map(({count:t})=\u003et)),this.stats={...this.stats,...this.getSelectiveReripStats()}}describeRoute(t){const e=this.problem.routeMetadata?.[t]?.connectionId;return void 0===e?String(t):`${t} (${String(e)})`}};new Int32Array(0);var uj=class extends hj{initialAssignmentRouteIds;getRouteIdsPreferredForPreservation(){return this.initialAssignmentRouteIds||(this.initialAssignmentRouteIds=new Set((this.problem.initialAssignments??[]).map(t=\u003et.routeId))),this.initialAssignmentRouteIds}resetRoutingStateForRerip(){super.resetRoutingStateForRerip(),this.problem.initialAssignments?.length\u0026\u0026Uz({topology:this.topology,problem:this.problem,state:this.state,routeSuccessCountByRouteId:this.routeSuccessCountByRouteId,appendSegmentToRegionCache:(t,e,n)=\u003ethis.appendSegmentToRegionCache(t,e,n)})}},pj=t=\u003e{if(\"object\"!=typeof t||null===t)return!1;const e=t,n=e.preloadedTraceSection;return\"string\"==typeof e.connectionId\u0026\u0026\"string\"==typeof n?.traceId\u0026\u0026\"number\"==typeof n.startRoutePosition\u0026\u0026\"number\"==typeof n.endRoutePosition\u0026\u0026\"number\"==typeof n.startPoint?.x\u0026\u0026\"number\"==typeof n.startPoint.y\u0026\u0026\"number\"==typeof n.startPoint.z\u0026\u0026\"number\"==typeof n.endPoint?.x\u0026\u0026\"number\"==typeof n.endPoint.y\u0026\u0026\"number\"==typeof n.endPoint.z},mj=(t,e)=\u003e`__tscircuit_preloaded_trace__:${JSON.stringify([t,e])}`,gj=t=\u003e[t.region1Id,t.region2Id],fj=(t,e)=\u003e{const n=new Set(gj(e));return gj(t).filter(t=\u003en.has(t))},yj=(t,e,n)=\u003e{const o=t[e],i=t[e+1],r=fj(o.port,i.port);if(0===r.length)return;if(1===r.length)return r[0];const s=t[e+2];if(s){const t=new Set(fj(i.port,s.port)),e=r.find(e=\u003et.has(e));if(e)return e}return n\u0026\u0026r.includes(n)?n:[...r].sort()[0]},_j=(t,e)=\u003egj(t).find(t=\u003et!==e)??e,bj=t=\u003e{const e=new Set((t.connections??[]).filter(pj).map(t=\u003et.connectionId)),n=t.ports.filter(t=\u003e(t.d?._preloadedTracePortAssignments?.length??0)\u003e0).length,o=t.regions.reduce((t,n)=\u003et+(n.assignments??[]).filter(t=\u003ee.has(t.connectionId)).length,0);return{preloadedTraceCount:e.size,preloadedPortCount:n,preloadedAssignmentCount:o}},xj=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},vj=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},Sj=1e-6,Ij={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,PARTIAL_RIP_MIN_ROUTE_COUNT:100,PARTIAL_RIP_MAX_ROUTE_COUNT:350,PARTIAL_RIP_MAX_ATTEMPTS:7,PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS:1,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:100,PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO:.02,PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO:.05,PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO:.1},Cj={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:6,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:Number.POSITIVE_INFINITY},Pj=t=\u003eMath.max(t,.01),Mj=t=\u003eNumber.isFinite(t)?{minViaPadDiameter:t}:{},Nj=(t,e)=\u003e{const n=Pj(t);return{...Ij,...Mj(e),USE_SPARSE_CANDIDATE_STORAGE:!1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.ceil(10*n),MAX_ITERATIONS:Math.ceil(2e6*n)}},wj=(t,e)=\u003e{const n=Pj(t);return{...Cj,...Mj(e),USE_SPARSE_CANDIDATE_STORAGE:!1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.ceil(16*n),MAX_ITERATIONS:Math.ceil(1e6*n)}},Tj=t=\u003e(t.solveGraphOptions?.MAX_ITERATIONS??1e6)+(t.sectionSolverOptions?.MAX_ITERATIONS??1e6)+1e6,Rj=t=\u003et.mutuallyConnectedNetworkId,Ej=(t,e)=\u003et.simpleRouteConnection?.pointsToConnect[e],Aj=t=\u003e{const e=Ej(t.routeMetadata,t.endpointIndex);if(!e)return t.fallbackZ;const n=xo(e).map(e=\u003eko(e,t.layerCount));return t.regionAvailableZ.find(t=\u003en.includes(t))??t.fallbackZ},Oj=(t,e)=\u003e{const n=t.d,o=n.bounds;return{capacityMeshNodeId:t.d.capacityMeshNodeId,center:{x:t.d.center.x,y:t.d.center.y},width:t.d.width,height:t.d.height,availableZ:[...t.d.availableZ],...o?{bounds:{minX:o.minX,maxX:o.maxX,minY:o.minY,maxY:o.maxY}}:{},_containsObstacle:t.d._containsObstacle,_containsTarget:t.d._containsTarget,_offBoardConnectionId:t.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:void 0===t.d._offBoardConnectedCapacityMeshNodeIds?void 0:[...t.d._offBoardConnectedCapacityMeshNodeIds],_qfpRegionType:n._qfpRegionType,_isNarrowQfpPadGap:n._isNarrowQfpPadGap,...void 0!==e?{netId:e}:{}}},kj=t=\u003e{const e=t.d;return{portId:t.d.portId,x:t.d.x,y:t.d.y,z:t.d.z,prevPortPointId:e.prevPortPointId,nextPortPointId:e.nextPortPointId,distToCentermostPortOnZ:t.d.distToCentermostPortOnZ,tinyHypergraphPortPenalty:t.d.tinyHypergraphPortPenalty,cramped:t.d.cramped,_preloadedFixedNetIds:t.d._preloadedFixedNetIds,_preloadedTracePortAssignments:t.d._preloadedTracePortAssignments}},Lj=t=\u003e{const e=function(){const t=new Map;return e=\u003e{const n=e.mutuallyConnectedNetworkId;let o=t.get(n);return void 0===o\u0026\u0026(o=t.size,t.set(n,o)),o}}(),n=function(t){const e=new Map,n=new Set,o=new Map;for(const i of t.params.connections){const r=i.mutuallyConnectedNetworkId,s=t.getNetIndex({connectionId:i.connectionId,mutuallyConnectedNetworkId:r});for(const t of[i.connectionId,r])o.set(t,s);for(const o of i.simpleRouteConnection.pointsToConnect)for(const i of t.params.graph.regions){if(!gf({point:o,region:i,layerCount:t.params.layerCount}))continue;if(void 0===o.pcb_port_id\u0026\u0026!0!==i.d._containsTarget){n.add(i.regionId);continue}let r=e.get(i.regionId);r||(r=new Set,e.set(i.regionId,r)),r.add(s)}}for(const n of t.params.graph.regions)for(const t of n.d._connectedTo??[]){const i=o.get(t);if(void 0===i)continue;let r=e.get(n.regionId);r||(r=new Set,e.set(n.regionId,r)),r.add(i)}const i=new Map;for(const t of n)i.set(t,-1);for(const[t,n]of e)1===n.size\u0026\u0026i.set(t,[...n][0]);return i}({params:t,getNetIndex:e}),o=t.graph.regions.map(t=\u003e({regionId:t.regionId,pointIds:t.ports.map(t=\u003et.d.portId),d:Oj(t,n.get(t.regionId))})),i=t.graph.ports.map(t=\u003e({portId:t.d.portId,region1Id:t.region1.regionId,region2Id:t.region2.regionId,d:kj(t)})),r=t.connections.map(t=\u003e({connectionId:t.connectionId,mutuallyConnectedNetworkId:t.mutuallyConnectedNetworkId,startRegionId:t.startRegion.regionId,endRegionId:t.endRegion.regionId,simpleRouteConnection:t.simpleRouteConnection})),s=[];for(const n of t.connections){const r={connectionId:n.connectionId,mutuallyConnectedNetworkId:n.mutuallyConnectedNetworkId,simpleRouteConnection:n.simpleRouteConnection},a=e(r),c=Ej(r,0),l=Ej(r,1),d=n.startRegion.d.availableZ[0]??0,h=n.endRegion.d.availableZ[0]??0,u=Aj({routeMetadata:r,endpointIndex:0,fallbackZ:d,regionAvailableZ:n.startRegion.d.availableZ,layerCount:t.layerCount}),p=Aj({routeMetadata:r,endpointIndex:1,fallbackZ:h,regionAvailableZ:n.endRegion.d.availableZ,layerCount:t.layerCount}),m=`tiny-terminal:start-region:${n.connectionId}`,g=`tiny-terminal:end-region:${n.connectionId}`,f=`tiny-terminal:start-port:${n.connectionId}`,y=`tiny-terminal:end-port:${n.connectionId}`;o.push({regionId:m,pointIds:[f],d:{capacityMeshNodeId:m,center:{x:c?.x??n.startRegion.d.center.x,y:c?.y??n.startRegion.d.center.y},width:Sj,height:Sj,availableZ:[u],_containsTarget:!0,_tinyTerminal:!0,_tinyTerminalNetId:n.mutuallyConnectedNetworkId,netId:a}}),o.push({regionId:g,pointIds:[y],d:{capacityMeshNodeId:g,center:{x:l?.x??n.endRegion.d.center.x,y:l?.y??n.endRegion.d.center.y},width:Sj,height:Sj,availableZ:[p],_containsTarget:!0,_tinyTerminal:!0,_tinyTerminalNetId:n.mutuallyConnectedNetworkId,netId:a}}),i.push({portId:f,region1Id:n.startRegion.regionId,region2Id:m,d:{portId:f,x:c?.x??n.startRegion.d.center.x,y:c?.y??n.startRegion.d.center.y,z:u,distToCentermostPortOnZ:0,_tinyTerminal:!0,...t.preserveTerminalPcbPortIds\u0026\u0026c?.pcb_port_id?{pcb_port_id:c.pcb_port_id}:{}}}),i.push({portId:y,region1Id:n.endRegion.regionId,region2Id:g,d:{portId:y,x:l?.x??n.endRegion.d.center.x,y:l?.y??n.endRegion.d.center.y,z:p,distToCentermostPortOnZ:0,_tinyTerminal:!0,...t.preserveTerminalPcbPortIds\u0026\u0026l?.pcb_port_id?{pcb_port_id:l.pcb_port_id}:{}}});const _=o.find(t=\u003et.regionId===n.startRegion.regionId),b=o.find(t=\u003et.regionId===n.endRegion.regionId);_?.pointIds.push(f),b?.pointIds.push(y),s.push({connection:{connectionId:n.connectionId},path:[{portId:f},{portId:y}]})}const a={regions:o,ports:i,connections:r,solvedRoutes:s};return(t=\u003e{const e=new Map,n=new Map,o=new Set((t.connections??[]).flatMap(t=\u003e[t.startRegionId,t.endRegionId])),i=new Set(t.regions.filter(t=\u003e{const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;return!0===t.d?._containsObstacle\u0026\u0026(void 0===e||-1===e)\u0026\u0026!o.has(t.regionId)}).map(t=\u003et.regionId));let r=0;for(const o of t.ports){const t=o.d,s=t?._preloadedTracePortAssignments??[];if(s.length\u003e0\u0026\u0026r++,!i.has(o.region1Id)\u0026\u0026!i.has(o.region2Id))for(const t of s){const i=n.get(t.traceId);if(void 0!==i\u0026\u0026i!==t.fixedNetId)throw new Error(`Preloaded trace \"${t.traceId}\" maps to multiple canonical nets`);n.set(t.traceId,t.fixedNetId);const r=e.get(t.traceId)??[];r.push({port:o,assignment:t}),e.set(t.traceId,r)}}const s=new Map(t.regions.map(t=\u003e[t.regionId,t])),a=t.connections??=[],c=t.solvedRoutes??=[];let l=0,d=0;for(const[t,o]of e){o.sort((t,e)=\u003et.assignment.routePosition-e.assignment.routePosition||t.assignment.z-e.assignment.z||t.port.portId.localeCompare(e.port.portId));const e=o.filter(({port:t},e)=\u003e0===e||t.portId!==o[e-1].port.portId);if(e.length\u003c2)continue;const i=[];let r;for(let t=0;t\u003ce.length-1;t++){const n=e[t],o=e[t+1];if(n.assignment.z===o.assignment.z\u0026\u0026Math.abs(n.assignment.routePosition-o.assignment.routePosition)\u003c=1e-6){r=void 0;continue}const s=yj(e,t,r);s?(i.push({regionId:s,from:n,to:o}),r=s):r=void 0}const h=[];for(const t of i){const e=h.at(-1);e\u0026\u0026e.at(-1).to.port.portId===t.from.port.portId?e.push(t):h.push([t])}for(const[e,o]of h.entries()){const i=mj(t,e);for(const e of o){const n=s.get(e.regionId);if(!n)throw new Error(`Preloaded trace \"${t}\" references missing region \"${e.regionId}\"`);n.assignments=[...n.assignments??[],{regionPort1Id:e.from.port.portId,regionPort2Id:e.to.port.portId,connectionId:i}],d++}const r=o[0],l=o.at(-1),h=r.from.port,u=l.to.port,p={connectionId:i,mutuallyConnectedNetworkId:n.get(t)??t,startRegionId:_j(h,r.regionId),endRegionId:_j(u,l.regionId),preloadedTraceSection:{traceId:t,startRoutePosition:r.from.assignment.routePosition,endRoutePosition:l.to.assignment.routePosition,startPoint:{x:r.from.assignment.tracePoint.x,y:r.from.assignment.tracePoint.y,z:r.from.assignment.z},endPoint:{x:l.to.assignment.tracePoint.x,y:l.to.assignment.tracePoint.y,z:l.to.assignment.z}}};a.push(p),c.push({requiredRip:!1,connection:p,path:[h,u].map(t=\u003e({portId:t.portId,g:0,h:0,f:0,hops:0,ripRequired:!1}))})}h.length\u003e0\u0026\u0026l++}})(a),a},Dj=t=\u003e{const e=new Map;for(let n=0;n\u003ct.problem.routeNet.length;n++){const o=t.problem.routeMetadata?.[n],i=o?.mutuallyConnectedNetworkId;if(\"string\"!=typeof i||0===i.length)throw new Error(`Tiny hypergraph route ${n} is missing a net ID`);e.set(i,t.problem.routeNet[n])}for(let n=0;n\u003ct.problem.regionNetId.length;n++){const o=t.topology.regionMetadata?.[n]?._tinyTerminalNetId;if(\"string\"!=typeof o)continue;const i=e.get(o);void 0!==i\u0026\u0026(t.problem.regionNetId[n]=i)}},zj=t=\u003e{const e=new Map;t.topology.regionMetadata?.forEach((t,n)=\u003e{\"string\"==typeof t.serializedRegionId\u0026\u0026e.set(t.serializedRegionId,n)});const n=new Set;for(const e of t.problem.routeMetadata??[])pj(e)||(\"string\"==typeof e.startRegionId\u0026\u0026n.add(e.startRegionId),\"string\"==typeof e.endRegionId\u0026\u0026n.add(e.endRegionId));for(const o of t.problem.routeMetadata??[])if(pj(o))for(const i of[o.startRegionId,o.endRegionId]){if(\"string\"!=typeof i||n.has(i))continue;const o=e.get(i);if(void 0===o)continue;const r=t.topology.regionMetadata?.[o];\"number\"==typeof r?.netId||\"number\"==typeof r?.NetId||(t.problem.regionNetId[o]=-1)}},Fj=t=\u003e{if(t.problem.metadataPortPenaltiesApplied)return 0;let e=0,n=void 0!==t.problem.portPenalty;for(let o=0;o\u003ct.topology.portCount;o++){const i=Number(t.topology.portMetadata?.[o]?.tinyHypergraphPortPenalty),r=Number.isFinite(i)\u0026\u0026i\u003e0?i:0;r\u003e0\u0026\u0026e++,t.problem.portPenalty?.[o]!==r\u0026\u0026(n=!1)}if(n)return t.problem.metadataPortPenaltiesApplied=!0,e;e=0;const o=t.problem.portPenalty?new Float64Array(t.problem.portPenalty):new Float64Array(t.topology.portCount);for(let n=0;n\u003ct.topology.portCount;n++){const i=Number(t.topology.portMetadata?.[n]?.tinyHypergraphPortPenalty);!Number.isFinite(i)||i\u003c=0||(o[n]+=i,e++)}return e\u003e0\u0026\u0026(t.problem.portPenalty=o),t.problem.metadataPortPenaltiesApplied=!0,e},Bj=class extends dj{configuredSolvers=new WeakSet;duplicatePortPenaltyCount=0;metadataPortPenaltyCount=0;crampedPortPenaltyCount=0;preloadedPortCount=0;preloadedFixedSegmentCount=0;crampedPortTraversalPenalty;useSelectiveReripRouting;constructor(t,e){super(t),this.useSelectiveReripRouting=e,this.crampedPortTraversalPenalty=150;const n=bj(t.serializedHyperGraph);if(this.preloadedPortCount=n.preloadedPortCount,this.preloadedFixedSegmentCount=n.preloadedAssignmentCount,e){const t=this.pipelineDef.find(t=\u003e\"solveGraph\"===t.solverName);if(!t)throw new Error(\"Tiny hypergraph pipeline is missing the solveGraph stage\");t.solverClass=uj}this.MAX_ITERATIONS=Tj(t)}loadHyperGraph(t){const e=super.loadHyperGraph(t);((t,e)=\u003e{const n=new Map;for(const t of e.connections??[])pj(t)\u0026\u0026n.set(t.connectionId,t.preloadedTraceSection);for(const e of t.problem.routeMetadata??[]){const t=n.get(e.connectionId);t\u0026\u0026(e.preloadedTraceSection=t)}})(e,this.inputProblem.serializedHyperGraph);const n=Fj(e),{duplicatePortPenaltyCount:o,crampedPortPenaltyCount:i}=((t,e)=\u003e{let n=0,o=0;const i=t.problem.portPenalty?new Float64Array(t.problem.portPenalty):new Float64Array(t.topology.portCount);for(let r=0;r\u003ct.topology.portCount;r++){const s=t.topology.portMetadata?.[r];\"string\"==typeof s?.duplicatedFromPortId\u0026\u0026(i[r]+=150,n++),s?.cramped\u0026\u0026e\u003e0\u0026\u0026(i[r]+=e,o++)}return(n\u003e0||o\u003e0)\u0026\u0026(t.problem.portPenalty=i),{duplicatePortPenaltyCount:n,crampedPortPenaltyCount:o}})(e,this.crampedPortTraversalPenalty);return Dj(e),zj(e),this.metadataPortPenaltyCount=Math.max(this.metadataPortPenaltyCount,n),this.duplicatePortPenaltyCount=Math.max(this.duplicatePortPenaltyCount,o),this.crampedPortPenaltyCount=Math.max(this.crampedPortPenaltyCount,i),e}_step(){super._step(),this.configureSolver(this.activeSubSolver)}getInitialVisualizationSolver(){if(this.useSelectiveReripRouting\u0026\u0026!this.initialVisualizationSolver){const{topology:t,problem:e}=this.loadHyperGraph(this.inputProblem.serializedHyperGraph);this.initialVisualizationSolver=new uj(t,e,this.getSolveGraphOptions())}const t=super.getInitialVisualizationSolver();return this.configureSolver(t),t}getSolvedTinySolver(){const t=this.getSolver(\"optimizeSection\");if(t?.solved\u0026\u0026!t.failed)return t.getSolvedSolver();const e=this.getSolver(\"solveGraph\");if(e?.solved\u0026\u0026!e.failed)return e;throw new Error(\"TinyHyperGraph section pipeline does not have a solved graph\")}configureSolver(t){if(t\u0026\u0026!this.configuredSolvers.has(t)){if(t instanceof JB||t instanceof nB){const e=t;Fj(e),Dj(e),zj(e)}this.configuredSolvers.add(t)}}},jj=class extends si{constructor(t){super(),this.params=t;const e=(t=\u003et.map(t=\u003e{const e=t.simpleRouteConnection;if(!e)throw new Error(`TinyHypergraphPortPointPathingSolver requires a SimpleRouteConnection for \"${t.connectionId}\"`);const n=t.mutuallyConnectedNetworkId;if(!n)throw new Error(`TinyHypergraphPortPointPathingSolver requires a net ID for \"${t.connectionId}\"`);return{...t,mutuallyConnectedNetworkId:n,simpleRouteConnection:e}}))(t.connections),n=t.flags.USE_SELECTIVE_RERIP_ROUTING?function(t,e){const n=new Map;for(const o of t){const t=e(o);n.set(t,(n.get(t)??0)+1)}return t.map((t,e)=\u003e({connection:t,index:e})).sort((t,o)=\u003e(n.get(e(o.connection))??0)-(n.get(e(t.connection))??0)||t.index-o.index).map(({connection:t})=\u003et)}(e,Rj):e;this.rootConnectionNameByConnectionId=new Map(n.map(t=\u003e[t.connectionId,t.simpleRouteConnection.__rootConnectionNames?.[0]]));const o=Lj({...t,connections:n});this.originalPreloadedSegmentKeysByConnectionId=(t=\u003e{const e=new Map;for(const n of t.connections??[])pj(n)\u0026\u0026e.set(n.connectionId,new Set);for(const n of t.regions)for(const t of n.assignments??[]){const o=e.get(t.connectionId);if(!o)continue;const[i,r]=[t.regionPort1Id,t.regionPort2Id].sort();o.add(JSON.stringify([n.regionId,i,r]))}return e})(o);const i=bj(o),r=i.preloadedPortCount\u003e0,s=r\u0026\u0026!0===t.flags.USE_PARTIAL_RIP_ROUTING_WITH_PRELOADED_TRACES,a=s?Math.max(o.connections?.length??0,i.preloadedAssignmentCount):void 0;let c=o;if(n.length\u003c=180){const e=new AB(o,{duplicatePortProximity:.05,useSerializedPortPenalties:!1,routeSolveOptions:{...Mj(t.minViaPadDiameter),USE_SPARSE_CANDIDATE_STORAGE:!1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,MAX_ITERATIONS:Math.ceil(2e6*Pj(t.effort)),RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!0}});if(e.solve(),e.failed)this.duplicateCongestedPortError=e.error??\"unknown error\";else{this.duplicateCongestedPortReport=e.report,c=e.getOutput();for(const t of c.ports){const e=vj(t.d);\"string\"==typeof e.duplicatedFromPortId\u0026\u0026(delete e._preloadedFixedNetIds,delete e._preloadedTracePortAssignments)}}}else this.duplicateCongestedPortError=`Skipped for ${n.length} connections`;this.duplicatedPortCount=this.duplicateCongestedPortReport?.duplicatedPorts.reduce((t,e)=\u003et+e.duplicatePortIds.length,0)??0;const l=((t,e,n,o=!0,i)=\u003e{const r=t.connections?.length??0,s=i??r,a=Ij.PARTIAL_RIP_MIN_ROUTE_COUNT??0,c=Ij.PARTIAL_RIP_MAX_ROUTE_COUNT??Number.POSITIVE_INFINITY,l=o\u0026\u0026s\u003e=a\u0026\u0026s\u003c=c;return{serializedHyperGraph:t,createSectionMask:({topology:t})=\u003enew Int8Array(t.portCount),solveGraphOptions:{...Nj(e,n),...l?{PARTIAL_RIP_MIN_ROUTE_COUNT:0,PARTIAL_RIP_MAX_ROUTE_COUNT:Number.POSITIVE_INFINITY,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:0}:{PARTIAL_RIP_ENABLED:!1,OUTSIDE_IN_ROUTING:!1}},sectionSolverOptions:wj(e,n)}})({...c,solvedRoutes:o.solvedRoutes},t.effort,t.minViaPadDiameter,!r||s,a);this.tinyPipelineSolver=new Bj(l,!0===t.flags.USE_SELECTIVE_RERIP_ROUTING),this.primaryTinyPipelineSolver=this.tinyPipelineSolver,n.length\u003e=30\u0026\u0026n.length\u003c=99\u0026\u0026(this.alternativeTinyPipelineInput={...l,solveGraphOptions:{...l.solveGraphOptions,TRACE_DENSITY_COST_FACTOR:1}}),this.MAX_ITERATIONS=Tj(l)*(this.alternativeTinyPipelineInput?2:1),this.originalRegionById=new Map(t.graph.regions.map(t=\u003e[t.regionId,t])),this.originalRegionIds=new Set(this.originalRegionById.keys()),this.inputNodeWithPortPoints=((t,e)=\u003e{const n=new Map(e.regions.map(t=\u003e[t.regionId,t])),o=new Map(e.ports.map(t=\u003e[t.portId,t]));return t.graph.regions.map(t=\u003e{const e=n.get(t.regionId),i=(e?.pointIds??t.ports.map(t=\u003et.d.portId)).map(t=\u003eo.get(t)).filter(t=\u003et\u0026\u0026!vj(t.d)._tinyTerminal).map(t=\u003e{const e=t,o=vj(e.d),i=n.get(e.region1Id),r=n.get(e.region2Id),s=Boolean(xj(i?.d)._offBoardConnectionId??xj(r?.d)._offBoardConnectionId);return{portPointId:e.portId,x:Number(o.x??0),y:Number(o.y??0),z:Number(o.z??0),prevPortPointId:\"string\"==typeof o.prevPortPointId?o.prevPortPointId:void 0,nextPortPointId:\"string\"==typeof o.nextPortPointId?o.nextPortPointId:void 0,connectionNodeIds:[e.region1Id,e.region2Id],distToCentermostPortOnZ:Number(o.distToCentermostPortOnZ??0),cramped:Boolean(o.cramped),connectsToOffBoardNode:s}});return{capacityMeshNodeId:t.d.capacityMeshNodeId,center:t.d.center,width:t.d.width,height:t.d.height,portPoints:i,availableZ:t.d.availableZ,_containsObstacle:t.d._containsObstacle,_containsTarget:t.d._containsTarget,_offBoardConnectionId:t.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t.d._offBoardConnectedCapacityMeshNodeIds,_qfpRegionType:t.d._qfpRegionType,_isNarrowQfpPadGap:t.d._isNarrowQfpPadGap}})})(t,c)}params;tinyPipelineSolver;primaryTinyPipelineSolver;alternativeTinyPipelineSolver;alternativeTinyPipelineInput;candidatePortfolioPhase=\"primary\";primaryCandidateSummary;alternativeCandidateSummary;alternativeCandidateEvaluated=!1;selectedCandidate=\"primary\";duplicateCongestedPortReport;duplicateCongestedPortError;duplicatedPortCount=0;inputNodeWithPortPoints;originalRegionById;originalRegionIds;rootConnectionNameByConnectionId;originalPreloadedSegmentKeysByConnectionId;getSolverName(){return\"TinyHypergraphPortPointPathingSolver\"}getChangedPreloadedRouteIds(t){const e=new Map,n=new Map;for(let o=0;o\u003ct.problem.routeCount;o++){const i=this.getRouteMetadata(t,o);pj(i)\u0026\u0026(e.set(i.connectionId,o),n.set(o,new Set))}for(let e=0;e\u003ct.state.regionSegments.length;e++){const o=t.topology.regionMetadata?.[e]?.serializedRegionId;for(const[i,r,s]of t.state.regionSegments[e]??[]){const e=n.get(i);if(!e)continue;const a=t.topology.portMetadata?.[r]?.serializedPortId,c=t.topology.portMetadata?.[s]?.serializedPortId;if(\"string\"!=typeof o||\"string\"!=typeof a||\"string\"!=typeof c)throw new Error(`Tiny hypergraph preloaded route ${i} has a segment without serialized topology IDs`);const[l,d]=[a,c].sort();e.add(JSON.stringify([o,l,d]))}}const o=new Set;for(const[t,i]of this.originalPreloadedSegmentKeysByConnectionId){const r=e.get(t);if(void 0===r)throw new Error(`Tiny hypergraph lost preloaded trace section \"${t}\"`);const s=n.get(r);if(i.size\u003e0\u0026\u00260===s.size)throw new Error(`Tiny hypergraph lost preloaded trace section \"${t}\"`);(i.size!==s.size||[...i].some(t=\u003e!s.has(t)))\u0026\u0026o.add(r)}return o}summarizePipelineCandidate(t){const e=t.getSolvedTinySolver();let n=0,o=0,i=0,r=0,s=0,a=0;const c=e.topology.regionMetadata??[];for(let t=0;t\u003ce.state.regionSegments.length;t++){const l=e.state.regionSegments[t];s+=l.length;for(const[,t,n]of l)e.topology.portZ[t]!==e.topology.portZ[n]\u0026\u0026(a+=1);const d=c[t]?.capacityMeshNodeId;if(!d||!this.originalRegionIds.has(d))continue;const h=this.originalRegionById.get(d);if(!h||0===l.length)continue;const u=l.map(([t,n,o])=\u003e[this.createAssignedPortPoint(e,t,n),this.createAssignedPortPoint(e,t,o)]),p={capacityMeshNodeId:h.d.capacityMeshNodeId,center:h.d.center,width:h.d.width,height:h.d.height,portPoints:u.flat(),portPointsInPairs:u,availableZ:h.d.availableZ},m=Ms(p),g=Ys(h.d,m.numSameLayerCrossings,m.numEntryExitLayerChanges,m.numTransitionPairCrossings);n+=g,o+=g*g,i=Math.max(i,g),r+=p.portPoints.length**2}return{nodePfSum:n,nodePfSquaredSum:o,nodePfMax:i,squaredNodePortPointCount:r,segmentCount:s,layerChangeCount:a,changedPreloadedTraceSectionCount:this.getChangedPreloadedRouteIds(e).size}}shouldEvaluateAlternative(t){const e=this.primaryTinyPipelineSolver.getSolvedTinySolver().problem.routeCount;return void 0!==this.alternativeTinyPipelineInput\u0026\u0026((t,e)=\u003et.nodePfSum\u003e4\u0026\u0026t.nodePfMax\u003e1\u0026\u0026t.squaredNodePortPointCount/Math.max(1,e)\u003e=125)(t,e)}shouldSelectAlternative(t,e){return((t,e,n)=\u003e{if(e.changedPreloadedTraceSectionCount\u003et.changedPreloadedTraceSectionCount)return!1;const o=n\u003e40?.92:.95,i=e.nodePfSum\u003c=.9*t.nodePfSum\u0026\u0026e.nodePfSquaredSum\u003c=.85*t.nodePfSquaredSum\u0026\u0026e.nodePfMax\u003c=.85*t.nodePfMax\u0026\u0026e.squaredNodePortPointCount\u003c.98*t.squaredNodePortPointCount\u0026\u0026e.segmentCount\u003c=.97*t.segmentCount;return e.nodePfSum\u003c=1.03*t.nodePfSum\u0026\u0026e.nodePfSquaredSum\u003c=1.06*t.nodePfSquaredSum\u0026\u0026(e.squaredNodePortPointCount\u003ct.squaredNodePortPointCount*o||i)})(t,e,this.primaryTinyPipelineSolver.getSolvedTinySolver().problem.routeCount)}finishCandidatePortfolio(){this.candidatePortfolioPhase=\"complete\",this.solved=this.tinyPipelineSolver.solved,this.failed=this.tinyPipelineSolver.failed,this.error=this.tinyPipelineSolver.error??null}getSolveGraphBenchmarkMetrics(){const t=this.tinyPipelineSolver.getSolver(\"solveGraph\");if(!t)return;const e=t.state.regionSegments.map(t=\u003et.length),n=\"alternative\"===this.selectedCandidate?this.alternativeCandidateSummary:this.primaryCandidateSummary,o=t.stats,i=this.tinyPipelineSolver.getStageStats().solveGraph;return{routeCount:t.problem.routeCount,traceDensityCandidateEvaluated:this.alternativeCandidateEvaluated,traceDensityCandidateSelected:\"alternative\"===this.selectedCandidate,downstreamNodePfSum:n?.nodePfSum,downstreamNodePfSquaredSum:n?.nodePfSquaredSum,downstreamNodePfMax:n?.nodePfMax,downstreamSquaredNodePortPointCount:n?.squaredNodePortPointCount,changedPreloadedTraceSectionCount:n?.changedPreloadedTraceSectionCount,iterations:t.iterations,timeMs:i?.timeSpent,ripCount:o.ripCount,partialRipCount:o.partialRipCount,partiallyRippedRouteCount:o.partiallyRippedRouteCount,partiallyRippedSegmentCount:o.partiallyRippedSegmentCount,retainedPartialRipSegmentCount:o.retainedPartialRipSegmentCount,firstMaxRegionCost:o.firstMaxRegionCost,bestMaxRegionCost:o.bestMaxRegionCost,firstTotalRegionCost:o.firstTotalRegionCost,bestTotalRegionCost:o.bestTotalRegionCost,firstSegmentCount:o.firstSegmentCount,bestSolvedSegmentCount:o.bestSolvedSegmentCount,bestSolvedMaxRegionSegmentCount:o.bestSolvedMaxRegionSegmentCount,bestSolvedSquaredRegionSegmentCount:o.bestSolvedSquaredRegionSegmentCount,finalMaxRegionSegmentCount:Math.max(0,...e),finalSquaredRegionSegmentCount:e.reduce((t,e)=\u003et+e*e,0),finalSegmentCount:n?.segmentCount,finalLayerChangeCount:n?.layerChangeCount,warmupFullRipAttempts:o.partialRipWarmupFullRipAttempts,complexityAwareSelection:o.partialRipComplexityAwareSelection,targetReached:o.partialRipTargetReached,outsideInCompletedRouteCount:o.outsideInCompletedRouteCount,outsideInFallbackRouteCount:o.outsideInFallbackRouteCount,outsideInForwardExpansionCount:o.outsideInForwardExpansionCount,outsideInReverseExpansionCount:o.outsideInReverseExpansionCount}}_step(){this.tinyPipelineSolver.step(),\"primary\"===this.candidatePortfolioPhase\u0026\u0026this.primaryTinyPipelineSolver.failed?(this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio()):\"primary\"===this.candidatePortfolioPhase\u0026\u0026this.primaryTinyPipelineSolver.solved?(this.primaryCandidateSummary=this.summarizePipelineCandidate(this.primaryTinyPipelineSolver),this.shouldEvaluateAlternative(this.primaryCandidateSummary)?(this.alternativeCandidateEvaluated=!0,this.alternativeTinyPipelineSolver=new Bj(this.alternativeTinyPipelineInput,!0===this.params.flags.USE_SELECTIVE_RERIP_ROUTING),this.tinyPipelineSolver=this.alternativeTinyPipelineSolver,this.candidatePortfolioPhase=\"alternative\"):(this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio())):\"alternative\"===this.candidatePortfolioPhase\u0026\u0026(this.tinyPipelineSolver.solved||this.tinyPipelineSolver.failed)\u0026\u0026(this.tinyPipelineSolver.solved\u0026\u0026!this.tinyPipelineSolver.failed\u0026\u0026(this.alternativeCandidateSummary=this.summarizePipelineCandidate(this.tinyPipelineSolver)),this.alternativeCandidateSummary\u0026\u0026this.primaryCandidateSummary\u0026\u0026this.shouldSelectAlternative(this.primaryCandidateSummary,this.alternativeCandidateSummary)?(this.selectedCandidate=\"alternative\",this.primaryTinyPipelineSolver=void 0,this.alternativeTinyPipelineSolver=void 0):(this.tinyPipelineSolver=this.primaryTinyPipelineSolver,this.alternativeTinyPipelineSolver=void 0),this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio());const t=this.tinyPipelineSolver.getSolver(\"optimizeSection\"),e=this.getCurrentTinySolver();this.solved=\"complete\"===this.candidatePortfolioPhase\u0026\u0026this.tinyPipelineSolver.solved,this.failed=\"complete\"===this.candidatePortfolioPhase\u0026\u0026this.tinyPipelineSolver.failed,this.error=this.failed?this.tinyPipelineSolver.error??null:null,this.progress=\"complete\"===this.candidatePortfolioPhase?1:\"alternative\"===this.candidatePortfolioPhase?.5+.5*this.tinyPipelineSolver.progress:this.alternativeTinyPipelineInput?.5*this.tinyPipelineSolver.progress:this.tinyPipelineSolver.progress,this.stats={duplicateCongestedPortSourceCount:this.duplicateCongestedPortReport?.duplicatedPorts.length??0,duplicateCongestedPortCount:this.duplicateCongestedPortReport?.duplicatedPorts.reduce((t,e)=\u003et+e.duplicatePortIds.length,0)??0,duplicateCongestedPortFallbackToOriginal:Boolean(this.duplicateCongestedPortError),duplicateCongestedPortPenalty:this.duplicatedPortCount\u003e0?150:0,duplicateCongestedPortPenaltyCount:this.tinyPipelineSolver.duplicatePortPenaltyCount,metadataPortPenaltyCount:this.tinyPipelineSolver.metadataPortPenaltyCount,crampedPortPenalty:this.tinyPipelineSolver.crampedPortTraversalPenalty,crampedPortPenaltyCount:this.tinyPipelineSolver.crampedPortPenaltyCount,preloadedPortCount:this.tinyPipelineSolver.preloadedPortCount,preloadedFixedSegmentCount:this.tinyPipelineSolver.preloadedFixedSegmentCount,duplicateCongestedPortError:this.duplicateCongestedPortError,candidatePortfolioPhase:this.candidatePortfolioPhase,candidatePortfolioSelectedCandidate:this.selectedCandidate,candidatePortfolioPrimarySummary:this.primaryCandidateSummary,candidatePortfolioAlternativeSummary:this.alternativeCandidateSummary,...this.tinyPipelineSolver.stats??{},...e?.stats??{},...t?.stats??{},currentStage:this.tinyPipelineSolver.getCurrentStageName(),stageStats:this.tinyPipelineSolver.getStageStats()},this.activeSubSolver=this.tinyPipelineSolver.activeSubSolver??null}preview(){return this.visualize()}getCurrentTinySolver(){const t=this.tinyPipelineSolver.getSolver(\"optimizeSection\");if(t?.solved\u0026\u0026!t.failed)return t.getSolvedSolver();const e=this.tinyPipelineSolver.getSolver(\"solveGraph\");return e||void 0}getSolvedTinySolver(){return this.tinyPipelineSolver.getSolvedTinySolver()}getRouteMetadata(t,e){return t.problem.routeMetadata?.[e]}createAssignedPortPoint(t,e,n){const o=this.getRouteMetadata(t,e),i=o?(t=\u003et.simpleRouteConnection?.name??t.connectionId)(o):`route-${e}`,r=o?this.rootConnectionNameByConnectionId.get(o.connectionId)??o.mutuallyConnectedNetworkId:void 0,s=t.topology.portMetadata?.[n];return{portPointId:String(s?.serializedPortId??s?.portId??`tiny-port-${n}`),x:t.topology.portX[n],y:t.topology.portY[n],z:t.topology.portZ[n],connectionName:i,rootConnectionName:r,...this.params.preserveTerminalPcbPortIds\u0026\u0026\"string\"==typeof s?.pcb_port_id?{pcb_port_id:s.pcb_port_id}:{},prevPortPointId:\"string\"==typeof s?.prevPortPointId?s.prevPortPointId:void 0,nextPortPointId:\"string\"==typeof s?.nextPortPointId?s.nextPortPointId:void 0}}getOutput(){const t=this.getSolvedTinySolver(),e=[],n=t.state.regionSegments,o=t.topology.regionMetadata??[],i=this.getChangedPreloadedRouteIds(t);for(let r=0;r\u003cn.length;r++){const s=o[r]?.capacityMeshNodeId;if(!s||!this.originalRegionIds.has(s))continue;const a=this.originalRegionById.get(s);if(!a)continue;const c=n[r].filter(([e])=\u003e{const n=this.getRouteMetadata(t,e);return!pj(n)||i.has(e)}).map(([e,n,o])=\u003e{const i=this.createAssignedPortPoint(t,e,n),r=this.createAssignedPortPoint(t,e,o);return i.portPointId\u0026\u0026r.portPointId\u0026\u0026(i.nextPortPointId=r.portPointId,r.prevPortPointId=i.portPointId),[i,r]}),l=c.flat();0!==l.length\u0026\u0026e.push({capacityMeshNodeId:a.d.capacityMeshNodeId,center:a.d.center,width:a.d.width,height:a.d.height,portPoints:l,portPointsInPairs:c,availableZ:a.d.availableZ})}const r=[...i].map(e=\u003e{const n=this.getRouteMetadata(t,e);if(!pj(n))throw new Error(`Changed preloaded hypergraph route ${e} is missing section metadata`);const o=n.preloadedTraceSection;return{connectionName:n.connectionId,traceId:o.traceId,startRoutePosition:o.startRoutePosition,endRoutePosition:o.endRoutePosition,connection:{name:n.connectionId,__rootConnectionNames:[n.mutuallyConnectedNetworkId],pointsToConnect:[{x:o.startPoint.x,y:o.startPoint.y,layer:vo(o.startPoint.z,this.params.layerCount)},{x:o.endPoint.x,y:o.endPoint.y,layer:vo(o.endPoint.z,this.params.layerCount)}]}}});return this.stats.changedPreloadedTraceSectionCount=r.length,{nodesWithPortPoints:e,inputNodeWithPortPoints:this.inputNodeWithPortPoints,changedPreloadedTraceSections:r}}computeNodePf(t){const e=this.getOutput().nodesWithPortPoints.find(e=\u003ee.capacityMeshNodeId===t.capacityMeshNodeId),n=this.originalRegionById.get(t.capacityMeshNodeId);if(!e||!n)return null;const o=Ms(e);return Ys(n.d,o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.numTransitionPairCrossings)}tryFinalAcceptance(){}getConstructorParams(){return[this.params]}visualize(){return this.tinyPipelineSolver.visualize()}},$j=(t,e)=\u003e{if(!t||\"none\"===t)return t;try{const n=gt(t);return`rgba(${n.red},${n.green},${n.blue},${e})`}catch{return To(t,1-e)}},Yj=({srj:t,opacity:e=.25,visualizationOptions:n={}})=\u003e{const o=Ho({...t,obstacles:[]},n);return{...o,points:[],lines:o.lines?.map(t=\u003e({...t,strokeColor:$j(t.strokeColor,e)})),rects:o.rects?.map(t=\u003e({...t,fill:$j(t.fill,e),stroke:$j(t.stroke,e)})),circles:o.circles?.map(t=\u003e({...t,fill:$j(t.fill,e),stroke:$j(t.stroke,e)}))}};function Xj(t,e){return t.x\u003e=e.center.x-e.width/2\u0026\u0026t.x\u003c=e.center.x+e.width/2\u0026\u0026t.y\u003e=e.center.y-e.height/2\u0026\u0026t.y\u003c=e.center.y+e.height/2}var Vj=\"escape-via:\",Wj=1e-4,Hj=t=\u003et.obstacleId??[t.layers.join(\".\"),t.center.x.toFixed(4),t.center.y.toFixed(4),t.width.toFixed(4),t.height.toFixed(4)].join(\":\"),Gj=(t,e,n=1e-4)=\u003exe(t,e)\u003c=n,Uj=class extends si{constructor(t,e={}){super(),this.ogSrj=t,this.viaDiameter=e.viaDiameter??Yo(t).padDiameter,this.viaRadius=this.viaDiameter/2,this.minTraceWidth=e.minTraceWidth??t.minTraceWidth,this.obstacleMargin=e.obstacleMargin??t.defaultObstacleMargin??.15,this.requiredViaToPadClearance=Math.max(this.obstacleMargin,t.minViaEdgeToPadEdgeClearance??0),this.escapeOffset=this.viaRadius+Math.max(this.minTraceWidth/2,this.requiredViaToPadClearance),this.requiredTraceClearance=this.minTraceWidth/2+this.obstacleMargin/2,this.requiredViaToViaClearance=this.viaDiameter+this.obstacleMargin,this.outputSrj=t,this.escapeViaMetadataByPointId=new Map,this.createdEscapeVias=[]}ogSrj;getSolverName(){return\"EscapeViaLocationSolver\"}viaDiameter;viaRadius;minTraceWidth;obstacleMargin;escapeOffset;requiredTraceClearance;requiredViaToPadClearance;requiredViaToViaClearance;outputSrj;escapeViaMetadataByPointId;createdEscapeVias;nextEscapeViaIndex=0;getConnectionNetIds(t){return new Set([t.name,...t.__rootConnectionNames??[],t.__netConnectionName].filter(t=\u003eBoolean(t)))}obstacleMatchesConnectionNet(t,e){return t.connectedTo.some(t=\u003ee.has(t))}getObstacleZs(t){return t.__zLayers\u0026\u0026t.__zLayers.length\u003e0?t.__zLayers:t.layers.map(t=\u003eko(t,this.ogSrj.layerCount))}getViaSpanLayers(t,e){const n=ko(t,this.ogSrj.layerCount),o=ko(e,this.ogSrj.layerCount),i=Math.min(n,o),r=Math.max(n,o),s=Array.from({length:r-i+1},(t,e)=\u003ei+e);return{__zLayers:s,layers:s.map(t=\u003evo(t,this.ogSrj.layerCount))}}createEscapeViaObstacle(t){const{escapeVia:e,connectionNetIds:n}=t,{layers:o,__zLayers:i}=this.getViaSpanLayers(e.sourceLayer,e.targetLayer);return{obstacleId:`escape-via-obstacle:${e.pointId}`,type:\"rect\",layers:o,__zLayers:i,center:{x:e.x,y:e.y},width:this.viaDiameter,height:this.viaDiameter,connectedTo:Array.from(n)}}selectSourceObstacle(t){const{point:e,sourceLayer:n,connectionNetIds:o}=t;return this.ogSrj.obstacles.filter(t=\u003e!t.isCopperPour\u0026\u0026t.layers.includes(n)\u0026\u0026Xj(e,t)).sort((t,n)=\u003e{const i=t.connectedTo.includes(e.pointId??\"\")||t.connectedTo.includes(e.pcb_port_id??\"\")||this.obstacleMatchesConnectionNet(t,o);return i!==(n.connectedTo.includes(e.pointId??\"\")||n.connectedTo.includes(e.pcb_port_id??\"\")||this.obstacleMatchesConnectionNet(n,o))?i?-1:1:t.width*t.height-n.width*n.height})[0]}getCandidatePositions(t,e){if(!e)return this.dedupeCandidatePositions([{x:t.x+this.escapeOffset,y:t.y},{x:t.x-this.escapeOffset,y:t.y},{x:t.x,y:t.y+this.escapeOffset},{x:t.x,y:t.y-this.escapeOffset},{x:t.x+this.escapeOffset,y:t.y+this.escapeOffset},{x:t.x+this.escapeOffset,y:t.y-this.escapeOffset},{x:t.x-this.escapeOffset,y:t.y+this.escapeOffset},{x:t.x-this.escapeOffset,y:t.y-this.escapeOffset}]);const n=e.center.x-e.width/2,o=e.center.x+e.width/2,i=e.center.y-e.height/2,r=e.center.y+e.height/2,s=n-this.escapeOffset,a=o+this.escapeOffset,c=i-this.escapeOffset,l=r+this.escapeOffset,d=this.getEdgeSamples(i,r,t.y),h=this.getEdgeSamples(n,o,t.x),u=[];for(const t of d)u.push({x:s,y:t},{x:a,y:t});for(const t of h)u.push({x:t,y:c},{x:t,y:l});return this.dedupeCandidatePositions(u)}dedupeCandidatePositions(t){const e=[];for(const n of t)e.some(t=\u003eGj(t,n))||e.push(n);return e}pushEdgeSample(t,e,n,o){const i=Math.max(n,Math.min(o,e));t.some(t=\u003eMath.abs(t-i)\u003c=Wj)||t.push(i)}getEdgeSamples(t,e,n){const o=[],i=e-t;if(this.pushEdgeSample(o,n,t,e),i\u003c=Wj)return o;this.pushEdgeSample(o,t,t,e),this.pushEdgeSample(o,e,t,e),this.pushEdgeSample(o,(t+e)/2,t,e);const r=Math.max(t,Math.min(e,n)),s=Math.max(this.requiredViaToViaClearance,Wj),a=Math.ceil(i/s);for(let n=1;n\u003c=a;n++){const i=n*s;this.pushEdgeSample(o,r+i,t,e),this.pushEdgeSample(o,r-i,t,e)}return o}isInsideBoard(t){return!!(t.x\u003e=this.ogSrj.bounds.minX+this.viaRadius\u0026\u0026t.x\u003c=this.ogSrj.bounds.maxX-this.viaRadius\u0026\u0026t.y\u003e=this.ogSrj.bounds.minY+this.viaRadius\u0026\u0026t.y\u003c=this.ogSrj.bounds.maxY-this.viaRadius)\u0026\u0026(!(this.ogSrj.outline\u0026\u0026this.ogSrj.outline.length\u003e=3)||za(t,this.ogSrj.outline))}hasClearEscapePath(t){const{sourcePoint:e,candidate:n,sourceLayer:o,sourceObstacle:i}=t;if(this.ogSrj.outline\u0026\u0026this.ogSrj.outline.length\u003e=3){if(Fa({start:e,end:n,polygon:this.ogSrj.outline,margin:this.requiredTraceClearance}))return!1}for(const t of this.ogSrj.obstacles){if(t===i)continue;if(!t.layers.includes(o))continue;if(Xj(n,t))return!1;const r=Cl(t);if(Math.min(...r.map(t=\u003eRa(e,n,t.start,t.end)))+Wj\u003cthis.requiredTraceClearance)return!1}return!0}getBoardBoundarySegments(){if(this.ogSrj.outline\u0026\u0026this.ogSrj.outline.length\u003e=3)return this.ogSrj.outline.map((t,e)=\u003e({start:t,end:this.ogSrj.outline[(e+1)%this.ogSrj.outline.length]}));const{minX:t,maxX:e,minY:n,maxY:o}=this.ogSrj.bounds;return[{start:{x:t,y:n},end:{x:e,y:n}},{start:{x:e,y:n},end:{x:e,y:o}},{start:{x:e,y:o},end:{x:t,y:o}},{start:{x:t,y:o},end:{x:t,y:n}}]}getRayProbeDistance(){const{minX:t,maxX:e,minY:n,maxY:o}=this.ogSrj.bounds;return 2*Math.hypot(e-t,o-n)+this.viaDiameter}getRayIntersectionDistance(t){const{rayStart:e,rayEnd:n,segmentStart:o,segmentEnd:i}=t;if(!fe(e,n,o,i))return null;const r=ve(e,n,o,i);if(!r)return null;const s=xe(e,r);return s\u003c=Wj?null:s}getProjectedFreeSpace(t){const{sourcePoint:e,candidate:n}=t,o=n.x-e.x,i=n.y-e.y;return Math.abs(o)\u003c=Wj||Math.abs(i)\u003c=Wj?this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:o,y:i},travelDistance:xe(e,n)}):Math.min(this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:0,y:Math.sign(i)},travelDistance:Math.abs(i)}),this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:Math.sign(o),y:Math.sign(i)},travelDistance:xe(e,n)}),this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:Math.sign(o),y:0},travelDistance:Math.abs(o)}))}getProjectedFreeSpaceAlongDirection(t){const{sourcePoint:e,sourceLayer:n,sourceObstacle:o,direction:i,travelDistance:r}=t,s=Math.hypot(i.x,i.y);if(s\u003c=Wj||r\u003c=Wj)return 0;const a=this.getRayProbeDistance(),c=i.x/s,l=i.y/s,d={x:e.x+c*a,y:e.y+l*a};let h=Number.POSITIVE_INFINITY;for(const t of this.ogSrj.obstacles)if(t!==o\u0026\u0026t.layers.includes(n))for(const n of Cl(t)){const t=this.getRayIntersectionDistance({rayStart:e,rayEnd:d,segmentStart:n.start,segmentEnd:n.end});null!==t\u0026\u0026(h=Math.min(h,t))}for(const t of this.getBoardBoundarySegments()){const n=this.getRayIntersectionDistance({rayStart:e,rayEnd:d,segmentStart:t.start,segmentEnd:t.end});null!==n\u0026\u0026(h=Math.min(h,n))}return Number.isFinite(h)?Math.max(0,h-r):0}getMinBlockingClearance(t){const{candidate:e,connectionNetIds:n,sourceZ:o,targetZ:i}=t,r=Math.min(o,i),s=Math.max(o,i);let a=Number.POSITIVE_INFINITY;for(const t of this.ogSrj.obstacles){const n=this.getObstacleZs(t);if(!n.some(t=\u003et\u003e=r\u0026\u0026t\u003c=s))continue;if(t.isCopperPour\u0026\u0026!n.includes(o))continue;const i=Be(e,t)-this.viaRadius;if(a=Math.min(a,i),a+Wj\u003cthis.requiredViaToPadClearance)return a}return a}getMinPlacedEscapeViaClearance(t){let e=Number.POSITIVE_INFINITY;for(const n of this.createdEscapeVias){const o=xe(t,n)-this.viaDiameter;if(e=Math.min(e,o),e+Wj\u003cthis.obstacleMargin)return e}return e}selectPointOwner(t){const{point:e,groupConnections:n,matchingCopperPours:o}=t,i=ua(e),r=n.map(t=\u003e({connection:t,pointIndex:t.pointsToConnect.findIndex(t=\u003eua(t)===i)})).filter(t=\u003e-1!==t.pointIndex);return 0===r.length?null:(r.sort((t,e)=\u003e{const n=o.some(e=\u003ethis.obstacleMatchesConnectionNet(e,this.getConnectionNetIds(t.connection)));return n!==o.some(t=\u003ethis.obstacleMatchesConnectionNet(t,this.getConnectionNetIds(e.connection)))?n?-1:1:t.pointIndex-e.pointIndex}),r[0])}findBestEscapeViaCandidate(t){const{connection:e,point:n,pointIndex:o,matchingCopperPours:i,connectionNetIds:r,sourceObstacle:s}=t;if(!_o(n))return null;const a=n.layer,c=ko(a,this.ogSrj.layerCount),l=s??this.selectSourceObstacle({point:n,sourceLayer:a,connectionNetIds:r}),d=this.getCandidatePositions(n,l);let h=null;for(const t of i){const i=t.layers[0];if(!i||i===a)continue;const s=ko(i,this.ogSrj.layerCount),u=Hj(t);for(const p of d){if(!this.isInsideBoard(p))continue;if(!Xj(p,t))continue;if(!this.hasClearEscapePath({sourcePoint:n,candidate:p,sourceLayer:a,sourceObstacle:l}))continue;const d=this.getMinBlockingClearance({candidate:p,connectionNetIds:r,sourceZ:c,targetZ:s});if(d+Wj\u003cthis.requiredViaToPadClearance)continue;const m=this.getMinPlacedEscapeViaClearance(p);if(m+Wj\u003cthis.obstacleMargin)continue;const g=this.getProjectedFreeSpace({sourcePoint:n,candidate:p,sourceLayer:a,sourceObstacle:l}),f=Math.min(g,3),y=100*d-xe(n,p)-.5*Math.abs(s-c)+2*f+(Number.isFinite(m)?10*Math.min(m,this.requiredViaToViaClearance):0);(!h||y\u003eh.score)\u0026\u0026(h={pointId:`${Vj}${e.name}:${n.pointId??`p${o}`}:${i}:${this.nextEscapeViaIndex++}`,x:p.x,y:p.y,connectionName:e.name,rootConnectionName:e.__rootConnectionNames?.[0]??e.name,sourcePointIndex:o,sourcePointId:n.pointId,sourceLayer:a,targetLayer:i,targetPourKey:u,score:y})}}return h}buildPointPlacementPlans(t){const{mergedConnection:e,groupConnections:n,matchingCopperPours:o,connectionNetIds:i}=t,r=[];for(const t of e.pointsToConnect){const e=this.selectPointOwner({point:t,groupConnections:n,matchingCopperPours:o});if(!e)continue;const s=_o(t)?this.selectSourceObstacle({point:t,sourceLayer:t.layer,connectionNetIds:i}):void 0,a=_o(t)?this.getCandidatePositions(t,s).length:0;r.push({point:t,pointOwner:e,sourceObstacle:s,candidateCount:a})}return r.sort((t,e)=\u003e{if(t.candidateCount!==e.candidateCount)return t.candidateCount-e.candidateCount;const n=(t.sourceObstacle?.width??0)*(t.sourceObstacle?.height??0),o=(e.sourceObstacle?.width??0)*(e.sourceObstacle?.height??0);return n!==o?n-o:t.pointOwner.pointIndex-e.pointOwner.pointIndex})}_step(){const t=this.ogSrj.obstacles.filter(t=\u003et.isCopperPour),e=this.ogSrj.connections,n=e.map(t=\u003estructuredClone(t)),o=new Map(n.map(t=\u003e[t.name,t])),i=structuredClone(this.ogSrj.obstacles),r=pa([...e]);for(const n of r){const r=new Set(n.__rootConnectionNames??[n.name]),s=e.filter(t=\u003e(t.__rootConnectionNames??[t.name]).some(t=\u003er.has(t)));if(0===s.length)continue;const a=new Set;for(const t of s)for(const e of this.getConnectionNetIds(t))a.add(e);const c=t.filter(t=\u003ethis.obstacleMatchesConnectionNet(t,a));if(0===c.length)continue;const l=new Map,d=new Map,h=this.buildPointPlacementPlans({mergedConnection:n,groupConnections:s,matchingCopperPours:c,connectionNetIds:a});for(const{point:t,pointOwner:e,sourceObstacle:n}of h){const r=this.findBestEscapeViaCandidate({connection:e.connection,point:t,pointIndex:e.pointIndex,matchingCopperPours:c,connectionNetIds:a,sourceObstacle:n});if(!r)continue;const s=o.get(e.connection.name);if(!s)continue;if(s.pointsToConnect.some(t=\u003e_o(t)\u0026\u0026t.layer===r.sourceLayer\u0026\u0026Gj(t,r)))continue;s.pointsToConnect.push({x:r.x,y:r.y,layer:r.sourceLayer,pointId:r.pointId,terminalVia:{toLayer:r.targetLayer,viaDiameter:this.viaDiameter}}),this.escapeViaMetadataByPointId.set(r.pointId,r),this.createdEscapeVias.push(r),i.push(this.createEscapeViaObstacle({escapeVia:r,connectionNetIds:this.getConnectionNetIds(e.connection)}));const h=l.get(r.targetPourKey);h?h.push(r.pointId):l.set(r.targetPourKey,[r.pointId]),d.has(r.targetPourKey)||d.set(r.targetPourKey,e.connection.name)}for(const[t,e]of l.entries()){if(e.length\u003c=1)continue;const n=d.get(t);if(!n)continue;const i=o.get(n);i\u0026\u0026(i.externallyConnectedPointIds=[...i.externallyConnectedPointIds??[],e])}}this.outputSrj={...structuredClone(this.ogSrj),connections:n,obstacles:i},this.solved=!0}getOutputSimpleRouteJson(){return structuredClone(this.outputSrj)}getEscapeViaMetadataByPointId(){return new Map(this.escapeViaMetadataByPointId)}visualize(){return{title:\"Escape Via Location Solver\",points:this.outputSrj.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({x:e.x,y:e.y,color:!0===e.pointId?.startsWith(Vj)?\"#0f766e\":\"#dc2626\",label:!0===e.pointId?.startsWith(Vj)?`${t.name}\\nescape via`:t.name}))),lines:this.createdEscapeVias.map(t=\u003e{const e=this.outputSrj.connections.find(e=\u003ee.name===t.connectionName)?.pointsToConnect[t.sourcePointIndex]??null;return{points:e?[{x:e.x,y:e.y},{x:t.x,y:t.y}]:[{x:t.x,y:t.y}],strokeColor:\"#0f766e\"}}),circles:this.createdEscapeVias.map(t=\u003e({center:{x:t.x,y:t.y},radius:this.viaRadius,strokeColor:\"#0f766e\",label:`${t.connectionName}\\n${t.targetLayer}`})),rects:this.outputSrj.obstacles.filter(t=\u003e!t.isCopperPour).map(t=\u003e({...t,fill:\"rgba(220,38,38,0.12)\"}))}}},Zj=t=\u003e({...t}),qj=t=\u003e({...t,route:t.route?.map(Zj),vias:t.vias?.map(t=\u003e({...t}))}),Jj=t=\u003et.map(qj),Kj=\"#0000FF\",Qj=.15,t$=1e-6,e$=.1,n$=[\"top\",\"bottom\",\"left\",\"right\"],o$=t=\u003et.x*t.x+t.y*t.y,i$=(t,e)=\u003e({x:t.x-e.x,y:t.y-e.y}),r$=(t,e,n)=\u003e{const o=i$(n,e),i=o$(o);if(i\u003c=t$)return Math.sqrt(o$(i$(t,e)));const r=(a=i$(t,e),c=o,s=(a.x*c.x+a.y*c.y)/i,Math.max(0,Math.min(1,s)));var s,a,c;const l={x:e.x+o.x*r,y:e.y+o.y*r};return Math.sqrt(o$(i$(t,l)))},s$=t=\u003e1===t?.z?\"bottom\":\"top\",a$=(t,e,n)=\u003e(t.z??0)===(e.z??0)\u0026\u0026((e.z??0)===(n.z??0)\u0026\u0026(t.x===e.x\u0026\u0026e.x===n.x||t.y===e.y\u0026\u0026e.y===n.y)),c$=(t,e,n)=\u003e{const o=n?.get(t);if(o)return o;const i=t.route??[],r=t.traceThickness??Qj;let s=Number.POSITIVE_INFINITY,a=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY,l=Number.NEGATIVE_INFINITY,d=!1;const h=(t,e,n)=\u003e{s=Math.min(s,t-n),a=Math.min(a,e-n),c=Math.max(c,t+n),l=Math.max(l,e+n),d=!0},u={segments:[],segmentsByLayer:{top:[],bottom:[]},vias:(t.vias??[]).map(n=\u003e{const o=(n.diameter??t.viaDiameter??.3)/2;return h(n.x,n.y,o),{center:{x:n.x,y:n.y},radius:o,routeIndex:e}}),bounds:{minX:0,minY:0,maxX:0,maxY:0}};for(let t=0;t\u003ci.length-1;){const n=i[t];let o=t+1,s=i[o];const a=r/2;for(n\u0026\u0026h(n.x,n.y,a),s\u0026\u0026h(s.x,s.y,a);o\u003ci.length-1;){const t=i[o],e=i[o+1];if(!n||!t||!e)break;if(s$(n)!==s$(t))break;if(s$(t)!==s$(e))break;if(!a$(n,t,e))break;o+=1,s=e,h(e.x,e.y,a)}if(!n||!s){t+=1;continue}const c=s$(n),l={start:n,end:s,routeIndex:e,pointIndex:t,endPointIndex:o,thickness:r,halfThickness:a,layer:c,minX:Math.min(n.x,s.x)-a,maxX:Math.max(n.x,s.x)+a,minY:Math.min(n.y,s.y)-a,maxY:Math.max(n.y,s.y)+a};u.segments.push(l),u.segmentsByLayer[c].push(l),t=o}if(!d)for(const t of i)h(t.x,t.y,r/2);return u.bounds=d?{minX:s,minY:a,maxX:c,maxY:l}:{minX:0,minY:0,maxX:0,maxY:0},n?.set(t,u),u},l$=(t,e,n)=\u003ee.x\u003c=Math.max(t.x,n.x)+t$\u0026\u0026e.x\u003e=Math.min(t.x,n.x)-t$\u0026\u0026e.y\u003c=Math.max(t.y,n.y)+t$\u0026\u0026e.y\u003e=Math.min(t.y,n.y)-t$,d$=(t,e,n)=\u003e(e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y),h$=(t,e,n,o)=\u003e((t,e,n,o)=\u003e{const i=d$(t,e,n),r=d$(t,e,o),s=d$(n,o,t),a=d$(n,o,e);return!!(Math.abs(i)\u003c=t$\u0026\u0026l$(t,n,e))||!!(Math.abs(r)\u003c=t$\u0026\u0026l$(t,o,e))||!!(Math.abs(s)\u003c=t$\u0026\u0026l$(n,t,o))||!!(Math.abs(a)\u003c=t$\u0026\u0026l$(n,e,o))||i\u003e0!=r\u003e0\u0026\u0026s\u003e0!=a\u003e0})(t,e,n,o)?0:Math.min(r$(t,n,o),r$(e,n,o),r$(n,t,e),r$(o,t,e)),u$=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=t$\u0026\u0026Math.abs(t.y-e.y)\u003c=t$,p$=(t,e)=\u003eu$(t.start,e.start)||u$(t.start,e.end)||u$(t.end,e.start)||u$(t.end,e.end),m$=t=\u003e{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))},g$=(t,e)=\u003e{const n=m$(t),o=m$(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))},f$=(t,e,n)=\u003et.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY,y$=(t,e,n)=\u003e{const o=n+t.halfThickness+e.halfThickness-t$;return t.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY\u0026\u0026o\u003e0},_$=(t,e,n,o)=\u003e{const i=o+n.halfThickness+e-t$,r=t.x-i,s=t.x+i,a=t.y-i,c=t.y+i;return r\u003c=n.maxX\u0026\u0026s\u003e=n.minX\u0026\u0026a\u003c=n.maxY\u0026\u0026c\u003e=n.minY},b$=(t,e)=\u003e{const n=new WeakMap,o=t.map((t,e)=\u003ec$(t,e,n)),i=[],r=new Set,s=t=\u003e{r.has(t.label)||(r.add(t.label),i.push(t))};for(let n=0;n\u003co.length;n+=1){const i=o[n];if(i)for(let r=n+1;r\u003co.length;r+=1){const a=o[r];if(a\u0026\u0026(!g$(t[n],t[r])\u0026\u0026f$(i.bounds,a.bounds,e))){for(const t of[\"top\",\"bottom\"]){const o=i.segmentsByLayer[t],c=a.segmentsByLayer[t];for(const i of o)for(const o of c){if(p$(i,o))continue;if(!y$(i,o,e))continue;const a=e+(i.thickness+o.thickness)/2-t$;if(h$(i.start,i.end,o.start,o.end)\u003e=a)continue;s({center:{x:(Math.max(i.minX-e,o.minX-e)+Math.min(i.maxX+e,o.maxX+e))/2,y:(Math.max(i.minY-e,o.minY-e)+Math.min(i.maxY+e,o.maxY+e))/2},label:`trace-violation:${n}:s${i.pointIndex}:${r}:s${o.pointIndex}:${t}`})}}for(const t of i.segments)for(const[o,i]of a.vias.entries()){if(!_$(i.center,i.radius,t,e))continue;const a=e+t.halfThickness+i.radius-t$;r$(i.center,t.start,t.end)\u003e=a||s({center:i.center,label:`trace-violation:${n}:s${t.pointIndex}:${r}:v${o}`})}for(const t of a.segments)for(const[o,a]of i.vias.entries()){if(!_$(a.center,a.radius,t,e))continue;const i=e+t.halfThickness+a.radius-t$;r$(a.center,t.start,t.end)\u003e=i||s({center:a.center,label:`trace-violation:${n}:v${o}:${r}:s${t.pointIndex}`})}}}}return(t=\u003e{const e=[];for(const n of t){const t=e.find(t=\u003e{return e=t.center,o=n.center,Math.hypot(e.x-o.x,e.y-o.y)\u003c=.28;var e,o});t?(t.center={x:(t.center.x*t.count+n.center.x)/(t.count+1),y:(t.center.y*t.count+n.center.y)/(t.count+1)},t.labels.push(n.label),t.count+=1):e.push({center:n.center,labels:[n.label],count:1})}return e.map((t,e)=\u003e({center:t.center,radius:Math.min(.3,.2+.035*Math.sqrt(t.count-1)),stroke:\"#f59e0b\",fill:\"rgba(245, 158, 11, 0.46)\",label:1===t.count?t.labels[0]:`trace-violations:${e}:count-${t.count}`}))})(i)},x$=({routeIndexes:t,layers:e,routePointIndexes:n})=\u003e`${t[0]}:${e[0]}:${n[0].join(\",\")}:${t[1]}:${e[1]}:${n[1].join(\",\")}`,v$=(t,e,n,o,i,r,s)=\u003e{const a=((t,e,n,o,i,r)=\u003et\u003cn?`${t}:${e}:${i.join(\",\")}:${n}:${o}:${r.join(\",\")}`:`${n}:${o}:${r.join(\",\")}:${t}:${e}:${i.join(\",\")}`)(e,n,o,i,r,s),c=t.get(a);if(c){const[t,n]=e\u003co?[r,s]:[s,r];for(const e of t)c.routePointIndexes[0].includes(e)||c.routePointIndexes[0].push(e);for(const t of n)c.routePointIndexes[1].includes(t)||c.routePointIndexes[1].push(t);return c.routePointIndexes[0].sort((t,e)=\u003et-e),void c.routePointIndexes[1].sort((t,e)=\u003et-e)}e\u003co?t.set(a,{routeIndexes:[e,o],layers:[n,i],routePointIndexes:[[...new Set(r)].sort((t,e)=\u003et-e),[...new Set(s)].sort((t,e)=\u003et-e)]}):t.set(a,{routeIndexes:[o,e],layers:[i,n],routePointIndexes:[[...new Set(s)].sort((t,e)=\u003et-e),[...new Set(r)].sort((t,e)=\u003et-e)]})},S$=t=\u003e{const e=[];for(let n=t.pointIndex;n\u003c=t.endPointIndex;n+=1)e.push(n);return e},I$=(t,e)=\u003e!e||t.some(t=\u003ee.has(t)),C$=(t,e)=\u003e{const n=t.route??[],o=[];for(let t=0;t\u003cn.length;t+=1){const i=n[t];i\u0026\u0026(Math.abs(i.x-e.center.x)\u003c=t$\u0026\u0026Math.abs(i.y-e.center.y)\u003c=t$\u0026\u0026o.push(t))}return o},P$=(t,e,n)=\u003et.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY,M$=(t,e,n)=\u003e{const o=n+t.halfThickness+e.halfThickness-t$;return t.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY\u0026\u0026o\u003e0},N$=(t,e,n,o)=\u003e{const i=o+n.halfThickness+e-t$,r=t.x-i,s=t.x+i,a=t.y-i,c=t.y+i;return r\u003c=n.maxX\u0026\u0026s\u003e=n.minX\u0026\u0026a\u003c=n.maxY\u0026\u0026c\u003e=n.minY},w$=(t,e,n)=\u003e{const o=n+t.radius+e.radius-t$;return Math.abs(t.center.x-e.center.x)\u003c=o\u0026\u0026Math.abs(t.center.y-e.center.y)\u003c=o},T$=(t,e,n,o,i)=\u003e{const r=t.map((t,e)=\u003ec$(t,e,o)),s=new Map;if(0===e.size)return[];const a=Array.from(e),c=new Map,l=t=\u003e{const e=c.get(t);if(e)return e;const o=r[t];if(!o)return[];const i=[];for(let e=0;e\u003cr.length;e+=1){if(e===t)continue;const s=r[e];s\u0026\u0026(P$(o.bounds,s.bounds,n)\u0026\u0026i.push(e))}return c.set(t,i),i};for(const t of a){const o=r[t];if(!o)continue;const a=l(t),c=i?.get(t);for(const l of o.segments){const o=S$(l);if(I$(o,c))for(const c of a){if(t\u003ec\u0026\u0026e.has(c))continue;const a=r[c];if(!a)continue;const d=i?.get(c),h=a.segmentsByLayer[l.layer];for(const t of h){const e=S$(t);if(!I$(e,d))continue;if(p$(l,t))continue;if(!M$(l,t,n))continue;const i=n+(l.thickness+t.thickness)/2-t$;h$(l.start,l.end,t.start,t.end)\u003ci\u0026\u0026v$(s,l.routeIndex,l.layer,t.routeIndex,t.layer,o,e)}}}}for(const o of a){const a=r[o];if(!a)continue;const c=l(o),d=i?.get(o);for(const l of a.vias){const a=C$(t[l.routeIndex],l);if(I$(a,d))for(const t of c){if(o\u003et\u0026\u0026e.has(t))continue;const c=r[t];if(!c)continue;const d=i?.get(t);for(const t of c.segments){const e=S$(t);if(!I$(e,d))continue;if(!N$(l.center,l.radius,t,n))continue;const o=n+t.thickness/2+l.radius-t$;r$(l.center,t.start,t.end)\u003co\u0026\u0026v$(s,t.routeIndex,t.layer,l.routeIndex,\"via\",e,a)}}}}for(const e of a){const o=r[e];if(!o)continue;const a=l(e),c=i?.get(e);for(const e of o.segments){const o=S$(e);if(I$(o,c))for(const c of a){const a=r[c];if(!a)continue;const l=i?.get(c);for(const i of a.vias){const r=C$(t[i.routeIndex],i);if(!I$(r,l))continue;if(!N$(i.center,i.radius,e,n))continue;const a=n+e.thickness/2+i.radius-t$;r$(i.center,e.start,e.end)\u003ca\u0026\u0026v$(s,e.routeIndex,e.layer,i.routeIndex,\"via\",o,r)}}}}for(const o of a){const a=r[o];if(!a)continue;const c=l(o),d=i?.get(o);for(const l of a.vias){const a=C$(t[l.routeIndex],l);if(I$(a,d))for(const d of c){if(o\u003ed\u0026\u0026e.has(d))continue;const c=r[d];if(!c)continue;const h=i?.get(d);for(const e of c.vias){const o=C$(t[e.routeIndex],e);if(!I$(o,h))continue;if(!w$(l,e,n))continue;const i=n+l.radius+e.radius-t$;Math.hypot(l.center.x-e.center.x,l.center.y-e.center.y)\u003ci\u0026\u0026v$(s,l.routeIndex,\"via\",e.routeIndex,\"via\",a,o)}}}}return Array.from(s.values())},R$=(t,e)=\u003et.x\u003e=e.minX-t$\u0026\u0026t.x\u003c=e.maxX+t$\u0026\u0026t.y\u003e=e.minY-t$\u0026\u0026t.y\u003c=e.maxY+t$,E$=(t,e,n)=\u003e{switch(e){case\"left\":return{minX:t.minX,maxX:t.minX+n,minY:t.minY,maxY:t.maxY};case\"right\":return{minX:t.maxX-n,maxX:t.maxX,minY:t.minY,maxY:t.maxY};case\"top\":return{minX:t.minX,maxX:t.maxX,minY:t.maxY-n,maxY:t.maxY};case\"bottom\":return{minX:t.minX,maxX:t.maxX,minY:t.minY,maxY:t.minY+n}}},A$=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;let r=0,s=1;const a=(t,e)=\u003e{if(Math.abs(t)\u003c=t$)return e\u003e=-1e-6;const n=e/t;return t\u003c0?!(n\u003es)\u0026\u0026(n\u003er\u0026\u0026(r=n),!0):!(n\u003cr)\u0026\u0026(n\u003cs\u0026\u0026(s=n),!0)};if(!(a(-o,t.x-n.minX)\u0026\u0026a(o,n.maxX-t.x)\u0026\u0026a(-i,t.y-n.minY)\u0026\u0026a(i,n.maxY-t.y)))return 0;const c=Math.hypot(o,i);return Math.max(0,s-r)*c},O$=(t,e)=\u003en$.filter(n=\u003e{switch(n){case\"left\":return Math.abs(t.x-e.minX)\u003c=t$;case\"right\":return Math.abs(t.x-e.maxX)\u003c=t$;case\"top\":return Math.abs(t.y-e.maxY)\u003c=t$;case\"bottom\":return Math.abs(t.y-e.minY)\u003c=t$}return!1}),k$=(t,e)=\u003e{const n=[];return t.x\u003ce.minX-t$\u0026\u0026n.push(\"left\"),t.x\u003ee.maxX+t$\u0026\u0026n.push(\"right\"),t.y\u003ee.maxY+t$\u0026\u0026n.push(\"top\"),t.y\u003ce.minY-t$\u0026\u0026n.push(\"bottom\"),n},L$=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;switch(n){case\"left\":case\"right\":return Math.abs(o)\u003c=t$\u0026\u0026Math.abs(i)\u003et$;case\"top\":case\"bottom\":return Math.abs(i)\u003c=t$\u0026\u0026Math.abs(o)\u003et$}},D$=(t,e,n)=\u003e{const o=[],i=Math.max(n,t$),r=Math.min(.1,i/4);for(let n=0;n\u003ct.length;n+=1){const s=t[n],a=s?.route??[];for(let t=0;t\u003ca.length-1;t+=1){const c=a[t],l=a[t+1];if(!c||!l)continue;const d=k$(c,e),h=k$(l,e),u=O$(c,e),p=O$(l,e),m=n$.filter(t=\u003e{if(s.connectedPadSides?.includes(t))return!1;return!(A$(c,l,E$(e,t,i))\u003c=r)\u0026\u0026!!L$(c,l,t)}),g=!R$(c,e)||!R$(l,e),f=Array.from(new Set([...m,...d,...h]));(g||0!==f.length)\u0026\u0026o.push({routeIndex:n,connectionName:s.connectionName??s.rootConnectionName??`route-${n}`,segmentIndex:t,touchedSides:f,startSides:u,endSides:p,start:c,end:l})}}return o},z$=t=\u003et?.center\u0026\u0026t.width\u0026\u0026t.height?{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,width:t.width,height:t.height,center:t.center}:null,F$=t=\u003e\"bottom\"===t?Kj:\"#FF0000\",B$=t=\u003e{const e=t.route??[],n=[];if(e.length\u003c2)return n;let o=s$(e[0]),i=[e[0]];for(let r=1;r\u003ce.length;r+=1){const s=e[r],a=s$(s);a===o?i.push(s):(i.length\u003e=2\u0026\u0026n.push({points:i,strokeColor:F$(o),strokeWidth:t.traceThickness??Qj,label:t.connectionName??\"route\"}),o=a,i=[e[r-1],s])}return i.length\u003e=2\u0026\u0026n.push({points:i,strokeColor:F$(o),strokeWidth:t.traceThickness??Qj,label:t.connectionName??\"route\"}),n},j$=(t,e)=\u003e({title:`HighDensityRepair02 Initial State (margin=${e})`,routes:t}),$=t=\u003e{const e=[];for(const n of t){const t=e[e.length-1];t\u0026\u0026t.z===n.z\u0026\u0026u$(t,n)||e.push(n)}return e},Y$=(t,e,n)=\u003e{const o=Math.max(0,t.minX-e.maxX,e.minX-t.maxX),i=Math.max(0,t.minY-e.maxY,e.minY-t.maxY);return Math.hypot(o,i)\u003c=n+t$},X$=(t,e)=\u003e{let n=Number.POSITIVE_INFINITY;for(const o of t.segments)for(const t of e.segments){if(o.layer!==t.layer)continue;const e=h$(o.start,o.end,t.start,t.end)-(o.thickness+t.thickness)/2;n=Math.min(n,e)}return n},V$=({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,maximumAllowedClearance:o})=\u003e{const i=new WeakMap,r=new WeakMap,s=[],a=Array.from(n).sort((t,e)=\u003et-e),c=t.map((t,e)=\u003ec$(t,e,i)),l=e.map((t,e)=\u003ec$(t,e,r)),d=new Set;for(const t of a)for(let n=0;n\u003ce.length;n+=1){if(n===t)continue;const e=Math.min(t,n),i=Math.max(t,n),r=`${e}:${i}`;if(d.has(r))continue;d.add(r);const a=l[e],h=l[i];if(!a||!h||!Y$(a.bounds,h.bounds,o))continue;const u=X$(a,h);if(!Number.isFinite(u)||u\u003eo+t$||!c[e]||!c[i])continue;const p=X$(c[e],c[i]);!Number.isFinite(p)||u\u003e=p-t$||s.push({routeIndexes:[e,i],previousClearance:p,nextClearance:u})}return s},W$=.001,H$=(t,e)=\u003et.map(t=\u003e{const n=t.route??[];return 0===n.length?t:{...t,route:n.map((t,o)=\u003e0===o||o===n.length-1?((t,e)=\u003e{const n={...t};return Math.abs(n.x-e.minX)\u003c=W$?n.x=e.minX:Math.abs(n.x-e.maxX)\u003c=W$\u0026\u0026(n.x=e.maxX),Math.abs(n.y-e.minY)\u003c=W$?n.y=e.minY:Math.abs(n.y-e.maxY)\u003c=W$\u0026\u0026(n.y=e.maxY),n})(t,e):t)}}),G$=(t,e)=\u003eArray.from(e).flatMap(e=\u003eB$(t[e]).map(t=\u003e({...t,strokeColor:\"#000000\",strokeWidth:t.strokeWidth,label:`candidate:${t.label}`}))),U$=(t,e,n,o,i)=\u003e{const r=\"rgba(0, 0, 0, 0)\";switch(e){case\"left\":return{center:{x:t.minX+n/2,y:t.center.y},width:n,height:t.height,stroke:r,fill:o,label:i};case\"right\":return{center:{x:t.maxX-n/2,y:t.center.y},width:n,height:t.height,stroke:r,fill:o,label:i};case\"top\":return{center:{x:t.center.x,y:t.maxY-n/2},width:t.width,height:n,stroke:r,fill:o,label:i};case\"bottom\":return{center:{x:t.center.x,y:t.minY+n/2},width:t.width,height:n,stroke:r,fill:o,label:i}}},Z$=({routes:t,candidateRoutes:e,candidateRouteIndexes:n,originalRoutes:o,boundary:i,side:r,margin:s,rejected:a,rejectionReason:c})=\u003e{const l=Array.from(n).map(t=\u003ee[t].connectionName??`route-${t}`);return{title:a?`${r} move rejected (${c})`:`${r} move accepted`,routes:a?t:e,originalRoutes:o,activeSide:r,candidateRouteNames:l,overlayLines:a?G$(e,n):[],overlayRects:[U$(i,r,s,a?\"rgba(220, 38, 38, 0.14)\":\"rgba(16, 185, 129, 0.14)\",a?`rejected:${r}`:`accepted:${r}`)]}},q$=(t,e,n,o)=\u003e{const i=(t?.adjacentObstacles??[]).some(t=\u003e((t,e,n,o)=\u003e{const i=(t=\u003et.center\u0026\u0026t.width\u0026\u0026t.height?{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}:null)(t);if(!i)return!1;switch(n){case\"left\":return i.maxX\u003e=e.minX-t$\u0026\u0026i.minX\u003c=e.minX+o+t$;case\"right\":return i.minX\u003c=e.maxX+t$\u0026\u0026i.maxX\u003e=e.maxX-o-t$;case\"top\":return i.minY\u003c=e.maxY+t$\u0026\u0026i.maxY\u003e=e.maxY-o-t$;case\"bottom\":return i.maxY\u003e=e.minY-t$\u0026\u0026i.minY\u003c=e.minY+o+t$}})(t,e,n,o));return{hasObstacle:i,moveAmount:i?o:o/2}},J$=({start:t,end:e,side:n,boundary:o,amount:i,targetAxisValue:r})=\u003e{const s=(({side:t,boundary:e,amount:n,targetAxisValue:o})=\u003e{const i=o??(()=\u003e{switch(t){case\"left\":return e.minX+n;case\"right\":return e.maxX-n;case\"top\":return e.maxY-n;case\"bottom\":return e.minY+n}})();switch(t){case\"left\":case\"right\":return Math.min(Math.max(i,e.minX),e.maxX);case\"top\":case\"bottom\":return Math.min(Math.max(i,e.minY),e.maxY)}})({side:n,boundary:o,amount:i,targetAxisValue:r});switch(n){case\"left\":case\"right\":return $([t,{x:s,y:t.y,z:t.z},{x:s,y:e.y,z:e.z},e]);case\"top\":case\"bottom\":return $([t,{x:t.x,y:s,z:t.z},{x:e.x,y:s,z:e.z},e])}},K$=(t,e,n,o,i,r,s,a=!1)=\u003e{const c=t.route??[];if(c.length\u003c2||0===e.length)return qj(t);const l=a?i:Math.max(i,r),d=((t,e)=\u003e{switch(t){case\"left\":return{x:e,y:0};case\"right\":return{x:-e,y:0};case\"top\":return{x:0,y:-e};case\"bottom\":return{x:0,y:e}}})(o,l);if(a||(t.vias?.length??0)\u003e0||c.length\u003e2){const n=qj(t),o=n.route??[];for(const t of e){const e=o[t];e\u0026\u0026(o[t]={...e,x:e.x+d.x,y:e.y+d.y})}for(const o of n.vias??[]){e.some(e=\u003e{const n=t.route?.[e];return!!n\u0026\u0026u$(n,o)})\u0026\u0026(o.x+=d.x,o.y+=d.y)}return n}const h=qj(t);if(2===c.length\u0026\u00262===e.length\u0026\u00260===e[0]\u0026\u00261===e[1]){const e=c[0],i=c[1];return qj({...t,route:J$({start:e,end:i,side:o,boundary:n,amount:l,targetAxisValue:s})})}return h},Q$=(t,e,n)=\u003e{switch(n){case\"left\":return t.x-e.minX;case\"right\":return e.maxX-t.x;case\"top\":return e.maxY-t.y;case\"bottom\":return t.y-e.minY}},tY=(t,e,n)=\u003e{const o=(t=\u003e{const e=t.route??[];if(0===e.length)return[];const n=[];for(let t=0;t\u003ce.length;t+=1){const o=e[t];if(!o)continue;0===t||t===e.length-1||n.push(o);const i=e[t+1];i\u0026\u0026n.push({x:(o.x+i.x)/2,y:(o.y+i.y)/2})}return n})(t);return 0===o.length?Number.POSITIVE_INFINITY:o.reduce((t,o)=\u003eMath.min(t,Q$(o,e,n)),Number.POSITIVE_INFINITY)},eY=(t,e,n=[])=\u003e{const o=t.route??[],i=[],r=new Set,s=0===e.length||e.includes(\"via\");if(2===o.length)return[0,1];const a=t=\u003e{if(t\u003c=0||t\u003e=o.length-1)return;if(r.has(t))return;const n=o[t];n\u0026\u0026(s||e.includes(s$(n)))\u0026\u0026(r.add(t),i.push(t))};if(n.length\u003e0)for(const t of n)a(t);else for(let t=1;t\u003co.length-1;t+=1)a(t);for(let t=0;t\u003ci.length;t+=1){const e=i[t],n=o[e];if(n)for(let t=1;t\u003co.length-1;t+=1){if(r.has(t))continue;const e=o[t];e\u0026\u0026(e.z!==n.z\u0026\u0026u$(e,n)\u0026\u0026(r.add(t),i.push(t)))}}return i.sort((t,e)=\u003et-e),i},nY=(t,e)=\u003eMath.max(0,...(t.route??[]).map(t=\u003eMath.max(e.minX-t.x,t.x-e.maxX,e.minY-t.y,t.y-e.maxY,0))),oY=(t,e,n,o)=\u003eQ$(t,e,n)\u003c=o+t$,iY=(t,e,n,o)=\u003e{const i=t.route??[],r=[],s=new Set;let a=1,c=i.length-2;for(;a\u003ci.length-1\u0026\u0026u$(i[a],i[0]);)a+=1;for(;c\u003e0\u0026\u0026u$(i[c],i[i.length-1]);)c-=1;for(let t=a;t\u003c=c;t+=1)oY(i[t],e,n,o)\u0026\u0026(s.add(t),r.push(t));for(let t=0;t\u003cr.length;t+=1){const e=i[r[t]];if(e)for(let t=a;t\u003c=c;t+=1){if(s.has(t))continue;const n=i[t];n\u0026\u0026(n.z!==e.z\u0026\u0026u$(n,e)\u0026\u0026(s.add(t),r.push(t)))}}return 0===r.length\u0026\u00262===i.length\u0026\u0026i.some(t=\u003eoY(t,e,n,o))?[0,1]:(r.sort((t,e)=\u003et-e),r)},rY=(t,e,n)=\u003e{const o=t.route??[],i=0===n?o[0]:o[o.length-1];return i?n$.filter(t=\u003eQ$(i,e,t)\u003c=t$):[]},sY=(t,e,n)=\u003e{const o=t.route??[],i=e.route??[];if(0===o.length||0===i.length)return!0;for(const e of[0,-1]){const o=rY(t,n,e);if(0===o.length)continue;const r=0===e?i[0]:i[i.length-1];if(!r)return!1;for(const t of o)if(Q$(r,n,t)\u003et$)return!1}return!0},aY=(t,e)=\u003eMath.hypot(e.x-t.x,e.y-t.y),cY=(t,e,n,o)=\u003e{const i=t.route??[];if(0===i.length)return\"none\";let r=!1;for(let t=0;t\u003ci.length;t+=1){const s=i[t];if(s\u0026\u0026oY(s,e,n,o)){if(0!==t\u0026\u0026t!==i.length-1)return\"interior\";r=!0}}for(let t=0;t\u003ci.length-1;t+=1){const r=i[t],s=i[t+1];if(r\u0026\u0026s\u0026\u0026(oY(r,e,n,o)\u0026\u0026oY(s,e,n,o)\u0026\u0026!(aY(r,s)\u003c=t$)))return\"interior\"}return r?\"endpoint\":\"none\"},lY=({currentRoutes:t,routeIndex:e,side:n,moveSide:o=n,boundary:i,margin:r,moveAmount:s,geometryCache:a})=\u003e{const c=t[e],l=2===(c.route?.length??0),d=iY(c,i,n,r);if(0===d.length)return null;const h=new Set,u=new Map,p=new Set,m=t.slice();let g=!1,f=\"overlap\";const y=new Set([e]),_=new Map([[e,new Set]]),b=new Map([[e,new Set]]),x=[e];let v=0,S=null,I=null,C=null,P=null;const M=t=\u003enew Set(t.map(t=\u003ex$(t))),N=()=\u003eS||(S=T$(t,h,r,a,u),S),w=()=\u003eC||(C=T$(t,h,0,a,u),C),T=()=\u003eP||(P=T$(m,h,0,a,u),P);for(;v\u003cx.length\u0026\u0026!g;){const c=x[v];if(v+=1,y.delete(c),h.has(c))continue;const l=m[c],d=Array.from(_.get(c)??[]),w=Array.from(b.get(c)??[]);_.delete(c),b.delete(c);const T=c===e?iY(l,i,n,r):eY(l,d,w);if(0===T.length){if(c===e)return null;g=!0,f=\"eventual-overlap\";break}const R=l.route??[],E=c===e?void 0:\"left\"===o||\"right\"===o?(R[T[0]]?.x??0)+(\"left\"===o?s:-s):(R[T[0]]?.y??0)+(\"top\"===o?-s:s);m[c]=K$(l,T,i,o,s,r,E,c!==e),h.add(c),u.set(c,new Set(T)),S=null,I=null,C=null,P=null,2===(l.route?.length??0)\u0026\u0026p.add(c);const A=nY(t[c],i);if(nY(m[c],i)\u003eA+1e-6){g=!0,f=\"boundary\";break}if(!sY(t[c],m[c],i)){g=!0,f=\"endpoint-boundary\";break}const O=T$(m,new Set([c]),r,a,new Map([[c,new Set(T)]]));for(const t of O){if(M(N()).has(x$(t)))continue;const[e,n]=t.routeIndexes,o=h.has(e),i=h.has(n);if(o\u0026\u0026i)continue;const r=o?n:e,s=o?t.layers[1]:t.layers[0],a=o?t.routePointIndexes[1]:t.routePointIndexes[0];if(h.has(r)||y.has(r)){if(y.has(r)){const t=_.get(r)??new Set;t.add(s),_.set(r,t);const e=b.get(r)??new Set;for(const t of a)e.add(t);b.set(r,e)}}else y.add(r),x.push(r),_.set(r,new Set([s])),b.set(r,new Set(a))}}if(!g\u0026\u0026h.size\u003e1){const t=M(N()),e=M(I||(I=T$(m,h,r,a,u),I));for(const n of e)if(!t.has(n)){g=!0,f=\"eventual-overlap\";break}}if(!g\u0026\u0026h.size\u003e1){const t=M(w()),e=M(T());for(const n of e)if(!t.has(n)){g=!0,f=\"eventual-overlap\";break}}if(!g){const e=new Set(T$(t,h,0,a).map(t=\u003ex$(t))),n=T$(m,h,0,a);for(const t of n){const n=x$(t);if(!e.has(n)){g=!0,f=\"eventual-overlap\";break}}}if(!g){const e=(({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,boundary:o,activeSide:i})=\u003e{const r=n$.filter(t=\u003et!==i),s=[];for(const i of n){const n=t[i],a=e[i];if(n\u0026\u0026a)for(const t of r){const e=tY(n,o,t),r=tY(a,o,t);e\u003et$\u0026\u0026r\u003c=t$\u0026\u0026s.push({routeIndex:i,side:t,previousClearance:e,nextClearance:r})}}return s})({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,boundary:i,activeSide:n});e.length\u003e0\u0026\u0026(g=!0,f=\"boundary-touch\")}if(!g){const e=(({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,geometryCache:o,currentConflicts:i,candidateConflicts:r})=\u003e{const s=i??T$(t,n,0,o),a=r??T$(e,n,0,o),c=new Set(s.map(t=\u003ex$(t)));return a.filter(t=\u003e{const o=x$(t);if(c.has(o))return!1;const[i,r]=t.routeIndexes,[s,a]=t.layers,l=n.has(i),d=n.has(r);if(l\u0026\u0026d)return!1;const h=l?a:s,u=e[l?r:i];return!!u\u0026\u00260===eY(u,[h]).length})})({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,geometryCache:a,currentConflicts:w(),candidateConflicts:T()});e.length\u003e0\u0026\u0026(g=!0,f=\"fixed-trace-touch\")}if(!g){V$({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,maximumAllowedClearance:Math.min(r/2,e$)}).length\u003e0\u0026\u0026(g=!0,f=\"trace-clearance\")}return!g\u0026\u0026((t,e,n,o,i,r)=\u003eArray.from(n).some(n=\u003e{const s=t[n],a=e[n];return n$.filter(t=\u003et!==i).some(t=\u003e{const e=cY(s,o,t,r),n=cY(a,o,t,r);return\"none\"===e\u0026\u0026\"none\"!==n})}))(t,m,h,i,n,r)\u0026\u0026(g=!0,f=\"side-regression\"),{isTwoPointRoute:l,movableIndexes:d,candidateRouteIndexes:h,movedTwoPointRouteIndexes:p,candidateRoutes:m,rejected:g,rejectionReason:f}},dY=(t,e,n,o,i)=\u003e{const r=t.route??[];if(0===e.length)return null;if(\"top\"===o||\"bottom\"===o){const t=e.reduce((t,e)=\u003et+(r[e]?.x??n.center.x),0)/e.length;return t\u003cn.center.x-i/2?\"right\":t\u003en.center.x+i/2?\"left\":null}const s=e.reduce((t,e)=\u003et+(r[e]?.y??n.center.y),0)/e.length;return s\u003en.center.y+i/2?\"bottom\":s\u003cn.center.y-i/2?\"top\":null},hY=({side:t,sample:e,boundary:n,margin:o,repairedRoutes:i,frames:r,captureProgressFrames:s,lockedTwoPointRoutes:a,geometryCache:c,allowTwoPointWithoutObstacle:l=!1})=\u003e{const{hasObstacle:d,moveAmount:h}=q$(e,n,t,o);s\u0026\u0026r.push(((t,e,n,o,i,r)=\u003e({title:`${n} boundary analysis: move=${i.toFixed(3)} (${r?\"obstacle-side\":\"clear-side\"})`,routes:t,activeSide:n,overlayRects:[U$(e,n,o,\"rgba(245, 158, 11, 0.16)\",`strip:${n}`)]}))(Jj(i),n,t,o,h,d));const u=new Set;let p=0;for(let e=0;e\u003ci.length;e+=1){if(u.has(e))continue;if(a.has(e))continue;const m=i[e];if(m.connectedPadSides?.includes(t))continue;if(2===(m.route?.length??0)\u0026\u0026!d\u0026\u0026!l)continue;let g=lY({currentRoutes:i,routeIndex:e,side:t,boundary:n,margin:o,moveAmount:h,geometryCache:c});if(g){if(g.rejected){const r=dY(m,g.movableIndexes,n,t,o);if(r){const s=lY({currentRoutes:i,routeIndex:e,side:t,moveSide:r,boundary:n,margin:o,moveAmount:h,geometryCache:c});s\u0026\u0026!s.rejected\u0026\u0026(g=s)}}if(s\u0026\u0026r.push(Z$({routes:Jj(i),candidateRoutes:g.candidateRoutes,candidateRouteIndexes:g.candidateRouteIndexes,originalRoutes:g.rejected?void 0:Array.from(g.candidateRouteIndexes).map(t=\u003eqj(i[t])),boundary:n,side:t,margin:o,rejected:g.rejected,rejectionReason:g.rejectionReason})),!g.rejected){i.splice(0,i.length,...g.candidateRoutes);for(const t of g.movedTwoPointRouteIndexes)a.add(t);p+=1}u.add(e)}}return{movesAccepted:p}},uY=(t,e,n,o)=\u003eoY(t,e,n,o),pY=(t,e,n,o)=\u003e{switch(n){case\"left\":return{...t,x:Math.min(e.minX+o,e.maxX)};case\"right\":return{...t,x:Math.max(e.maxX-o,e.minX)};case\"top\":return{...t,y:Math.max(e.maxY-o,e.minY)};case\"bottom\":return{...t,y:Math.min(e.minY+o,e.maxY)}}},mY=t=\u003e`${t.routeIndexes[0]}:${t.layers[0]}:${t.routeIndexes[1]}:${t.layers[1]}`,gY=t=\u003e{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))},fY=(t,e)=\u003e{const n=gY(t),o=gY(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))},yY=(t,e,n)=\u003et?D$([t],e,n).length:0,_Y=(t,e,n,o)=\u003e{const i=new Set(T$(t,new Set([n]),o).map(x$));return T$(e,new Set([n]),o).some(t=\u003e!i.has(x$(t)))},bY=(t,e,n)=\u003eD$(t,e,n).length,xY=t=\u003e{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))},vY=(t,e)=\u003eT$(t,new Set(t.map((t,e)=\u003ee)),e$,e).filter(e=\u003e!(\"via\"===e.layers[0]\u0026\u0026\"via\"===e.layers[1]||((t,e)=\u003e{const n=xY(t),o=xY(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))})(t[e.routeIndexes[0]],t[e.routeIndexes[1]]))).length,SY=t=\u003e{const e=n$;return[...e.slice(t%e.length),...e.slice(0,t%e.length)]},IY=(t,e,n=!1)=\u003e{const o=z$(t?.nodeWithPortPoints),i=o?((t,e)=\u003et.map(t=\u003e{const n=t.route??[];let o=!1;const i=n.map(t=\u003e{let n=t.x,i=t.y;return n\u003ce.minX?n=e.minX:n\u003ee.maxX\u0026\u0026(n=e.maxX),i\u003ce.minY?i=e.minY:i\u003ee.maxY\u0026\u0026(i=e.maxY),n===t.x\u0026\u0026i===t.y?t:(o=!0,{...t,x:n,y:i})});return o?{...t,route:i}:t}))(H$(Jj(t?.nodeHdRoutes??[]),o),o):Jj(t?.nodeHdRoutes??[]),r=Math.max(e??.4,.05),s=Jj(i);if(!o)return{boundary:null,baseRoutes:i,repairedRoutes:s,margin:r,frames:[{title:\"HighDensityRepair02 Missing Boundary\",routes:s}]};const a=n?[j$(Jj(s),r)]:[],c=new WeakMap;let l=bY(s,o,r);for(let e=0;e\u003c1;e+=1){const i=new Set;let d=0;for(const l of SY(e)){const{movesAccepted:h}=hY({side:l,sample:t,boundary:o,frames:a,margin:r,repairedRoutes:s,captureProgressFrames:n,lockedTwoPointRoutes:i,geometryCache:c,allowTwoPointWithoutObstacle:e\u003e=1});d+=h}const h=bY(s,o,r);if(0===d)break;if(0===h)break;if(h\u003e=l)break;l=h}const d=Jj(s),h=vY(s,c);(({routes:t,boundary:e,margin:n,geometryCache:o})=\u003e{const i=D$(t,e,n);if(0===i.length)return{movesAccepted:0};const r=new Map;for(const t of i){const e=r.get(t.routeIndex)??new Set;for(const n of t.touchedSides)e.add(n);r.set(t.routeIndex,e)}const s=[8e-6,.01,n/4,n/2,n+8e-6];let a=0;const c=(i,r,s)=\u003e{const a=r.route??[];if(a.length\u003c2)return!1;const c={...r,route:$(a)};if((c.route?.length??0)\u003c2)return!1;const l=t.slice();if(l[i]=c,yY(l[i],e,n)\u003e=s)return!1;const d=e=\u003efY(t[e.routeIndexes[0]],t[e.routeIndexes[1]]),h=new Set(T$(t,new Set([i]),0,o).filter(t=\u003e!d(t)).map(mY));return!T$(l,new Set([i]),0,o).filter(t=\u003e!d(t)).some(t=\u003e!h.has(mY(t)))\u0026\u0026!(V$({currentRoutes:t,candidateRoutes:l,candidateRouteIndexes:new Set([i]),maximumAllowedClearance:Math.min(n/2,e$)}).filter(e=\u003e!fY(t[e.routeIndexes[0]],t[e.routeIndexes[1]])).length\u003e0||(t[i]=c,0))},l=(n,o,i,r)=\u003e{if(0===o.length)return!1;for(const a of s){const s=t[n],l=qj(s),d=l.route??[];let h=!1;for(const t of o){const n=d[t];n\u0026\u0026(d[t]=pY(n,e,i,a),h=!0)}if(!h)return!1;if(c(n,l,r))return!0}return!1},d=(t,n)=\u003e{const o=[];return\"top\"===n||\"bottom\"===n?(Math.abs(t.x-e.minX)\u003c=t$\u0026\u0026o.push(\"left\"),Math.abs(t.x-e.maxX)\u003c=t$\u0026\u0026o.push(\"right\")):(Math.abs(t.y-e.minY)\u003c=t$\u0026\u0026o.push(\"bottom\"),Math.abs(t.y-e.maxY)\u003c=t$\u0026\u0026o.push(\"top\")),o},h=(o,i,r)=\u003e{const a=t[o],l=a.route??[];if(2!==l.length)return!1;const[h,u]=l;if(!uY(h,e,i,n))return!1;if(!uY(u,e,i,n))return!1;const p=d(h,i),m=d(u,i);for(const t of s){let n=pY(h,e,i,t),s=pY(u,e,i,t);for(const o of p)n=pY(n,e,o,t);for(const n of m)s=pY(s,e,n,t);const l={...a,route:[h,n,s,u]};if(c(o,l,r))return!0}return!1};for(const[o,i]of r)if(t[o])for(const r of i){let i=!0;for(;i;){i=!1;const s=t[o].route??[];if(2===s.length){const i=yY(t[o],e,n);i\u003e0\u0026\u0026h(o,r,i)\u0026\u0026(a+=1);break}if(s.length\u003c3)break;const c=yY(t[o],e,n);if(0===c)break;const d=[];for(let t=1;t\u003cs.length-1;t+=1){const o=s[t];o\u0026\u0026uY(o,e,r,n)\u0026\u0026d.push(t)}if(0===d.length)break;if(l(o,d,r,c)){a+=1,i=!0;continue}let u=!1,p=c,m=0;for(;m\u003cd.length;){let i=m;for(;i+1\u003cd.length\u0026\u0026d[i+1]===d[i]+1;)i+=1;l(o,d.slice(m,i+1),r,p)\u0026\u0026(a+=1,u=!0,p=yY(t[o],e,n)),m=i+1}if(!u){const i=t[o].route??[];let s=c;for(let c=1;c\u003ci.length-1;c+=1){const d=i[c];d\u0026\u0026uY(d,e,r,n)\u0026\u0026l(o,[c],r,s)\u0026\u0026(a+=1,u=!0,s=yY(t[o],e,n))}}u\u0026\u0026(i=!0)}}for(const[o,i]of r){const r=t[o];if(!r)continue;const s=r.route??[];if(s.length\u003c=2)continue;const c=yY(t[o],e,n);if(0!==c)for(const l of i){if(!s.every(t=\u003euY(t,e,l,n)))continue;const i=s[0]?.z;if(!s.every(t=\u003et.z===i))continue;const d={...r,route:[s[0],s[s.length-1]]},u=t[o];t[o]=d,h(o,l,c)?a+=1:t[o]=u;break}}})({routes:d,boundary:o,margin:r,geometryCache:c});return vY(d,c)\u003c=h\u0026\u0026s.splice(0,s.length,...d),(({routes:t,boundary:e,clearanceMargin:n})=\u003e{for(let o=0;o\u003ct.length;o+=1){const i=t[o];if((i.route??[]).length\u003c=2)continue;const r=n,s=Math.max(e.width/2-t$,0),a=Math.max(e.height/2-t$,0),c=Math.min(r,s),l=Math.min(r,a),d=i.connectedPadSides??[],h=e.minX+(d.includes(\"left\")?0:c),u=e.maxX-(d.includes(\"right\")?0:c),p=e.minY+(d.includes(\"bottom\")?0:l),m=e.maxY-(d.includes(\"top\")?0:l),g=qj(i),f=g.route??[];let y=!1;for(let t=1;t\u003cf.length-1;t+=1){const e=f[t];if(!e)continue;const n=Math.min(Math.max(e.x,h),u),o=Math.min(Math.max(e.y,p),m);(Math.abs(n-e.x)\u003et$||Math.abs(o-e.y)\u003et$)\u0026\u0026(e.x=n,e.y=o,y=!0)}if(!y)continue;if(g.route=$(f),(g.route?.length??0)\u003c2)continue;const _=Jj(t);_[o]=g;const b=_Y(t,_,o,0),x=_Y(t,_,o,n),v=V$({currentRoutes:t,candidateRoutes:_,candidateRouteIndexes:new Set([o]),maximumAllowedClearance:n}).length\u003e0;b||x||v||(t[o]=g)}})({routes:s,boundary:o,clearanceMargin:r}),a.push(((t,e,n)=\u003e({title:`HighDensityRepair02 Final State (margin=${n})`,routes:t,originalRoutes:e}))(Jj(s),Jj(i),r)),{boundary:o,baseRoutes:i,repairedRoutes:s,frames:a,margin:r}},CY=class extends kt{constructor(t={}){super(),this.params=t,this.showBoundryViolationMarkers=t.showBoundryViolationMarkers??!1}params;frames=[];currentFrameIndex=0;showBoundryViolationMarkers;repairedRoutes=[];_setup(){this.buildFrames();const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();this.stats={boundryViolationCount:t,traceViolationCount:e,margin:this.params.margin??.4,frames:this.frames.length,currentFrame:this.currentFrameIndex}}_step(){if(this.frames.length\u003c=1){const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();return this.showBoundryViolationMarkers=!0,this.stats={...this.stats,boundryViolationCount:t,traceViolationCount:e},void(this.solved=!0)}this.currentFrameIndex\u003cthis.frames.length-1\u0026\u0026(this.currentFrameIndex+=1);const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();this.stats={boundryViolationCount:t,traceViolationCount:e,margin:this.params.margin??.4,frames:this.frames.length,currentFrame:this.currentFrameIndex,title:this.frames[this.currentFrameIndex]?.title},this.currentFrameIndex\u003e=this.frames.length-1\u0026\u0026(this.showBoundryViolationMarkers=!0,this.solved=!0)}getConstructorParams(){return[this.params]}getOutput(){const t=this.getCurrentTraceViolationCount();return{margin:this.params.margin??.4,repairedRoutes:this.repairedRoutes,frameCount:this.frames.length,traceViolationCount:t}}setShowBoundryViolationMarkers(t){this.showBoundryViolationMarkers=t}buildFrames(){const t=IY(this.params.sample,this.params.margin,this.params.captureProgressFrames??!1);this.frames=t.frames,this.repairedRoutes=t.repairedRoutes}getCurrentFrame(){const t=this.params.sample;return this.frames[this.currentFrameIndex]??{title:\"HighDensityRepair02\",routes:Jj(t?.nodeHdRoutes??[])}}getBoundryViolationsForFrame(t){const e=z$(this.params.sample?.nodeWithPortPoints);return e?D$(t.routes,e,this.params.margin??.4):[]}getCurrentBoundryViolationCount(){return this.getBoundryViolationsForFrame(this.getCurrentFrame()).length}getRouteNetNames(t){if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))}areRoutesSameNet(t,e){const n=this.getRouteNetNames(t),o=this.getRouteNetNames(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))}getCurrentTraceViolationCount(){const t=this.getCurrentFrame().routes,e=new Set(t.map((t,e)=\u003ee));return T$(t,e,e$).filter(e=\u003e!(\"via\"===e.layers[0]\u0026\u0026\"via\"===e.layers[1]||this.areRoutesSameNet(t[e.routeIndexes[0]],t[e.routeIndexes[1]]))).length}visualize(){const t=this.params.sample,e=t?.nodeWithPortPoints,n=t?.adjacentObstacles??[],o=this.getCurrentFrame(),i=z$(e),r=i\u0026\u0026e?.capacityMeshNodeId?[{center:i.center,width:i.width,height:i.height,stroke:\"#1d4ed8\",fill:\"rgba(29, 78, 216, 0.08)\",label:e.capacityMeshNodeId}]:i?[{center:i.center,width:i.width,height:i.height,stroke:\"#1d4ed8\",fill:\"rgba(29, 78, 216, 0.08)\",label:\"capacity-node\"}]:[],s=n.filter(t=\u003et.center\u0026\u0026t.width\u0026\u0026t.height).map((t,e)=\u003e({center:t.center,width:t.width,height:t.height,stroke:\"oval\"===t.type?\"#a855f7\":\"#dc2626\",fill:\"oval\"===t.type?\"rgba(168, 85, 247, 0.12)\":\"rgba(220, 38, 38, 0.08)\",label:t.type?`obstacle:${t.type}:${e}`:`obstacle:${e}`})),a=this.showBoundryViolationMarkers\u0026\u0026i?this.getBoundryViolationsForFrame(o).map(t=\u003e{const e=t.end.x-t.start.x,n=t.end.y-t.start.y,o=Math.max(Math.hypot(e,n),.2),i=Math.abs(e)\u003e=Math.abs(n);return{center:{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2},width:i?o:.18,height:i?.18:o,stroke:\"#b45309\",fill:\"rgba(250, 204, 21, 0.45)\",label:`boundry-violation:${t.routeIndex}:${t.segmentIndex}`}}):[];const c=this.showBoundryViolationMarkers?b$(o.routes,e$):[],l=[...(e?.portPoints??[]).map(t=\u003e({x:t.x,y:t.y,color:\"#0f766e\",label:t.connectionName??t.portPointId??\"port-point\"})),...o.routes.flatMap(t=\u003et.route??[]).map(t=\u003e({x:t.x,y:t.y,color:\"bottom\"===s$(t)?Kj:\"#0ea5e9\",label:\"\"})),...o.overlayPoints??[]],d=[...(o.originalRoutes??[]).flatMap(t=\u003eB$(t).map(t=\u003e({...t,strokeColor:\"#111111\",strokeWidth:Math.max(.6*t.strokeWidth,.05),label:`original:${t.label}`}))),...o.routes.filter(t=\u003e(t.route?.length??0)\u003e=2).flatMap(t=\u003eB$(t)),...o.overlayLines??[]],h=o.routes.flatMap(t=\u003e(t.vias??[]).map(e=\u003e({center:{x:e.x,y:e.y},radius:(e.diameter??t.viaDiameter??.3)/2,stroke:\"#7c3aed\",fill:\"rgba(124, 58, 237, 0.2)\",label:t.connectionName?`via:${t.connectionName}`:\"via\"})));return h.push(...c),{coordinateSystem:\"cartesian\",title:o.title,rects:[...r,...s,...o.overlayRects??[],...a],points:l,lines:d,circles:h,arrows:o.overlayArrows}}},PY=(t,e,n,o)=\u003e{const i=.001,r=new Set;for(const s of[e.route[0],e.route.at(-1)]){if(!s)continue;n.some(t=\u003et.__zLayers.includes(s.z)\u0026\u0026fo(t,e,o)\u0026\u0026Math.abs(s.x-t.center.x)\u003c=t.width/2+i\u0026\u0026Math.abs(s.y-t.center.y)\u003c=t.height/2+i)\u0026\u0026(Math.abs(s.x-(t.center.x-t.width/2))\u003c=i\u0026\u0026r.add(\"left\"),Math.abs(s.x-(t.center.x+t.width/2))\u003c=i\u0026\u0026r.add(\"right\"),Math.abs(s.y-(t.center.y-t.height/2))\u003c=i\u0026\u0026r.add(\"bottom\"),Math.abs(s.y-(t.center.y+t.height/2))\u003c=i\u0026\u0026r.add(\"top\"))}return[...r]},MY=(t,e=0)=\u003e({minX:t.center.x-t.width/2-e,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2-e,maxY:t.center.y+t.height/2+e}),NY=(t,e,n=0)=\u003e{const o=MY(e,n);return t.x\u003e=o.minX\u0026\u0026t.x\u003c=o.maxX\u0026\u0026t.y\u003e=o.minY\u0026\u0026t.y\u003c=o.maxY},wY=(t,e,n)=\u003et.route.length\u003e0\u0026\u0026e.some(e=\u003e(t=\u003e(t.__zLayers?.length??t.layers?.length??0)\u003e1)(e)\u0026\u0026fo(e,t,n)\u0026\u0026t.route.every(t=\u003e((t,e)=\u003e{const n=e.width/2,o=e.height/2;return Math.abs(t.x-e.center.x)\u003c=n\u0026\u0026Math.abs(t.y-e.center.y)\u003c=o})(t,e))),TY=(t,e,n)=\u003e{if(t.regionId){const n=e.findIndex(e=\u003ee.capacityMeshNodeId===t.regionId);if(-1!==n)return n}const o=[...t.route.map(({x:t,y:e})=\u003e({x:t,y:e})),...t.vias.map(({x:t,y:e})=\u003e({x:t,y:e}))];for(let t=0;t\u003ce.length;t++){const i=e[t];if(o.every(t=\u003eNY(t,i,n)))return t}return-1},RY=(t,e)=\u003e({connectionName:t.connectionName??e.connectionName,rootConnectionName:t.rootConnectionName??e.rootConnectionName,...e.startPcbPortId?{startPcbPortId:e.startPcbPortId}:{},...e.endPcbPortId?{endPcbPortId:e.endPcbPortId}:{},regionId:t.capacityMeshNodeId??e.regionId,traceThickness:t.traceThickness??e.traceThickness,viaDiameter:t.viaDiameter??e.viaDiameter,route:t.route?.map(t=\u003e({x:t.x,y:t.y,z:t.z??0}))??e.route,vias:t.vias?.map(t=\u003e({x:t.x,y:t.y}))??e.vias,jumpers:e.jumpers}),EY=(t,e,n,o,i)=\u003e{const r=MY(t,n);return e.search(r).filter(t=\u003e{return e=r,n=(t=\u003e({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}))(t),e.minX\u003c=n.maxX\u0026\u0026e.maxX\u003e=n.minX\u0026\u0026e.minY\u003c=n.maxY\u0026\u0026e.maxY\u003e=n.minY;var e,n}).filter(t=\u003e!i||!o.some(e=\u003efo(t,e,i))).map(t=\u003e({type:t.type,center:t.center,width:t.width,height:t.height}))},AY=class extends si{repairMargin;sampleEntries;originalHdRoutes;originalNodeWithPortPoints;originalObstacles;obstacleSHI;colorMap;connMap;repairedRoutesByIndex=new Map;activeSampleIndex=0;activeSubSolver=null;latestVisualization={};constructor(t){super(),this.repairMargin=t.repairMargin??.2,this.originalHdRoutes=t.hdRoutes,this.originalNodeWithPortPoints=t.nodeWithPortPoints,this.originalObstacles=t.obstacles,this.obstacleSHI=new Na(\"flatbush\",this.originalObstacles),this.colorMap=t.colorMap??{},this.connMap=t.connMap;const e=new Map;for(let n=0;n\u003ct.hdRoutes.length;n++){if(wY(t.hdRoutes[n],t.obstacles,t.connMap))continue;const o=TY(t.hdRoutes[n],t.nodeWithPortPoints,this.repairMargin);if(-1===o)continue;const i=e.get(o)??[];i.push(n),e.set(o,i)}const n=Kr(t.obstacles,Math.max(2,...t.nodeWithPortPoints.flatMap(t=\u003et.availableZ?.map(t=\u003et+1)??[]))),o=Array.from(e.entries()).map(([e,o])=\u003e{const i=t.nodeWithPortPoints[e];return{node:i,routeIndexes:o,sample:{nodeWithPortPoints:{capacityMeshNodeId:i.capacityMeshNodeId,center:i.center,width:i.width,height:i.height,portPoints:i.portPoints.map(t=\u003e({x:t.x,y:t.y,z:t.z,connectionName:t.connectionName,portPointId:t.portPointId,prevPortPointId:t.prevPortPointId,nextPortPointId:t.nextPortPointId}))},nodeHdRoutes:o.map(e=\u003e{return{...(o=t.hdRoutes[e],{capacityMeshNodeId:o.regionId,connectionName:o.connectionName,rootConnectionName:o.rootConnectionName,route:o.route.map(t=\u003e({x:t.x,y:t.y,z:t.z})),traceThickness:o.traceThickness,vias:o.vias.map(t=\u003e({x:t.x,y:t.y,diameter:o.viaDiameter})),viaDiameter:o.viaDiameter}),...t.connMap?{connectedPadSides:PY(i,t.hdRoutes[e],n,t.connMap)}:{}};var o}),adjacentObstacles:EY(i,this.obstacleSHI,this.repairMargin,o.map(e=\u003et.hdRoutes[e]),t.connMap)}}});this.sampleEntries=void 0!==t.maxSampleEntries\u0026\u0026o.length\u003et.maxSampleEntries?[]:o,this.MAX_ITERATIONS=Math.max(1e3*this.sampleEntries.length,1e5),this.stats={sampleCount:this.sampleEntries.length,skippedSampleCount:o.length\u003ethis.sampleEntries.length?o.length:0,repairedNodeCount:0,repairedRouteCount:0}}getSolverName(){return\"Pipeline4HighDensityRepairSolver\"}getConstructorParams(){return[{nodeWithPortPoints:this.sampleEntries.map(t=\u003et.node),hdRoutes:this.originalHdRoutes,obstacles:this.originalObstacles,repairMargin:this.repairMargin,colorMap:this.colorMap,connMap:this.connMap}]}_step(){const t=this.sampleEntries[this.activeSampleIndex];if(t){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.latestVisualization=this.activeSubSolver.visualize(),this.activeSubSolver.failed)return this.failed=!0,this.error=this.activeSubSolver.error??`High density repair failed for node ${t.node.capacityMeshNodeId}`,void(this.activeSubSolver=null);if(!this.activeSubSolver.solved)return;const e=this.activeSubSolver.getOutput().repairedRoutes;for(let n=0;n\u003ct.routeIndexes.length;n++){const o=t.routeIndexes[n],i=this.originalHdRoutes[o],r=e[n];this.repairedRoutesByIndex.set(o,r?RY(r,i):i)}return this.activeSubSolver=null,this.activeSampleIndex+=1,this.stats={sampleCount:this.sampleEntries.length,repairedNodeCount:this.activeSampleIndex,repairedRouteCount:this.repairedRoutesByIndex.size},void(this.activeSampleIndex\u003e=this.sampleEntries.length\u0026\u0026(this.solved=!0))}this.activeSubSolver=new CY({sample:t.sample,margin:this.repairMargin}),this.latestVisualization=this.activeSubSolver.visualize()}else this.solved=!0}getOutput(){return this.originalHdRoutes.map((t,e)=\u003ethis.repairedRoutesByIndex.get(e)??t)}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();if(!this.solved)return this.latestVisualization;const t=[],e=[];for(const n of this.getOutput()){const o=this.colorMap[n.connectionName]??\"#0ea5e9\";for(let e=0;e\u003cn.route.length-1;e++){const i=n.route[e],r=n.route[e+1];i.z===r.z\u0026\u0026t.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:0===i.z?o:To(o,.5),strokeWidth:n.traceThickness,layer:`z${i.z}`,strokeDash:0!==i.z?[.1,.3]:void 0})}for(const t of n.vias)e.push({center:{x:t.x,y:t.y},radius:n.viaDiameter/2,stroke:o,fill:\"rgba(14,165,233,0.12)\"})}return{title:\"Pipeline4 High Density Repair\",lines:t,circles:e}}},OY=1e-6,kY=({startGap:t,endGap:e,segmentGap:n,requiredGap:o})=\u003e{const i=t\u003co\u0026\u0026e\u003e=o-OY\u0026\u0026n\u003e=t-OY,r=e\u003co\u0026\u0026t\u003e=o-OY\u0026\u0026n\u003e=e-OY,s=t\u003co\u0026\u0026e\u003co\u0026\u0026n\u003e=Math.min(t,e)-OY;return i||r||s},LY=class{minClearance;rootsByConnection=new Map;sameNetCache=new Map;segments=[];vias=[];segmentIndexesByLayer;viaIndex;constructor({hdRoutes:t,minClearance:e=.1}){this.minClearance=e;for(const e of t)this.addRoute(e);this.buildSpatialIndexes()}addRoute(t){const e=this.rootsByConnection.get(t.connectionName)??new Set;e.add(t.rootConnectionName??t.connectionName),this.rootsByConnection.set(t.connectionName,e),this.sameNetCache.clear();for(let e=0;e\u003ct.route.length-1;e+=1){const n=t.route[e],o=t.route[e+1];if(n.z!==o.z)continue;if(n.insideJumperPad\u0026\u0026o.insideJumperPad)continue;const i={connectionName:t.connectionName,start:n,end:o,traceThickness:t.traceThickness};this.segments.push(i),this.insertSegmentIntoSpatialIndex(i)}for(const e of t.vias){const n={connectionName:t.connectionName,x:e.x,y:e.y,diameter:t.viaDiameter};this.vias.push(n),this.insertViaIntoSpatialIndex(n)}}insertSegmentIntoSpatialIndex(t){if(!this.segmentIndexesByLayer)return;let e=this.segmentIndexesByLayer.get(t.start.z);e||(e=new Pa,this.segmentIndexesByLayer.set(t.start.z,e));const n=t.traceThickness/2;e.insert(t,Math.min(t.start.x,t.end.x)-n,Math.min(t.start.y,t.end.y)-n,Math.max(t.start.x,t.end.x)+n,Math.max(t.start.y,t.end.y)+n)}insertViaIntoSpatialIndex(t){if(!this.viaIndex)return;const e=t.diameter/2;this.viaIndex.insert(t,t.x-e,t.y-e,t.x+e,t.y+e)}buildSpatialIndexes(){this.segmentIndexesByLayer=new Map;const t=new Map;for(const e of this.segments){const n=t.get(e.start.z);n?n.push(e):t.set(e.start.z,[e])}for(const[e,n]of t){const t=new Pa;t.bulkLoad(n.map(t=\u003e{const e=t.traceThickness/2;return{item:t,minX:Math.min(t.start.x,t.end.x)-e,minY:Math.min(t.start.y,t.end.y)-e,maxX:Math.max(t.start.x,t.end.x)+e,maxY:Math.max(t.start.y,t.end.y)+e}})),this.segmentIndexesByLayer.set(e,t)}this.viaIndex=new Pa,this.viaIndex.bulkLoad(this.vias.map(t=\u003e{const e=t.diameter/2;return{item:t,minX:t.x-e,minY:t.y-e,maxX:t.x+e,maxY:t.y+e}}))}areSameNet(t,e){if(t===e)return!0;const n=this.sameNetCache.get(t)?.get(e);if(void 0!==n)return n;const o=this.rootsByConnection.get(t),i=this.rootsByConnection.get(e);let r=!1;if(o\u0026\u0026i)for(const t of o)if(i.has(t)){r=!0;break}let s=this.sameNetCache.get(t);return s||(s=new Map,this.sameNetCache.set(t,s)),s.set(e,r),r}isSegmentClear({connectionName:t,start:e,end:n,traceThickness:o}){const i=o/2,r=this.minClearance+i,s=Math.min(e.x,n.x)-r,a=Math.min(e.y,n.y)-r,c=Math.max(e.x,n.x)+r,l=Math.max(e.y,n.y)+r,d=this.segmentIndexesByLayer?.get(e.z)?.search(s,a,c,l)??[];for(const o of d){if(this.areSameNet(t,o.connectionName))continue;const r=this.minClearance+i+o.traceThickness/2,s=Ra(e,n,o.start,o.end);if(s\u003cr\u0026\u0026!kY({startGap:be(e,o.start,o.end),endGap:be(n,o.start,o.end),segmentGap:s,requiredGap:r}))return!1}const h=this.viaIndex?.search(s,a,c,l)??[];for(const o of h){if(this.areSameNet(t,o.connectionName))continue;const r=this.minClearance+i+o.diameter/2,s=be(o,e,n);if(s\u003cr\u0026\u0026!kY({startGap:Math.hypot(e.x-o.x,e.y-o.y),endGap:Math.hypot(n.x-o.x,n.y-o.y),segmentGap:s,requiredGap:r}))return!1}return!0}},DY=1e-9,zY=1.25,FY=(t,e)=\u003et\u003ce?-1:t\u003ee?1:0,BY=(t,e)=\u003eFY(t.z,e.z)||FY(t.x,e.x)||FY(t.y,e.y),jY=t=\u003e`${t.z.toFixed(6)}:${t.x.toFixed(6)}:${t.y.toFixed(6)}`,$Y=t=\u003e{const e=t.route.map(jY).join(\"|\"),n=[...t.route].reverse().map(jY).join(\"|\");return e\u003c=n?e:n},YY=(t,e)=\u003e{const n=t.connectionName.localeCompare(e.connectionName);if(0!==n)return n;const o=(t.rootConnectionName??\"\").localeCompare(e.rootConnectionName??\"\");if(0!==o)return o;const i=$Y(t).localeCompare($Y(e));return 0!==i?i:FY(t.traceThickness,e.traceThickness)||FY(t.viaDiameter,e.viaDiameter)||FY(t.route.length,e.route.length)||FY(t.vias.length,e.vias.length)||FY(t.jumpers?.length??0,e.jumpers?.length??0)},XY=1e5,VY=.001,WY=1.000000001,HY=class extends si{getSolverName(){return\"SingleHighDensityRouteStitchSolver3\"}mergedHdRoute;remainingHdRoutes;start;end;colorMap;allowedLayerTransitionPointKeys;isStitchSegmentClear;stitchClearanceMode;isPlanarStitchClear(t,e){return this.isStitchSegmentClear({connectionName:this.mergedHdRoute.connectionName,start:t,end:e,traceThickness:this.mergedHdRoute.traceThickness})}constructor(t){super();const e=[...t.hdRoutes].sort(YY);if(this.remainingHdRoutes=e,this.colorMap=t.colorMap??{},this.allowedLayerTransitionPointKeys=t.allowedLayerTransitionPointKeys,this.isStitchSegmentClear=t.isStitchSegmentClear,this.stitchClearanceMode=t.stitchClearanceMode,0===e.length){this.start=t.start,this.end=t.end;const n=t.defaultTraceThickness??.15,o=[{x:t.start.x,y:t.start.y,z:t.start.z}],i=[];if(t.start.z!==t.end.z){if(t.allowedLayerTransitionPointKeys\u0026\u0026!t.allowedLayerTransitionPointKeys.has(af(t.start)))return this.failed=!0,void(this.error=`Layer transition at ${af(t.start)} is not allowed`);o.push({x:t.start.x,y:t.start.y,z:t.end.z}),i.push({x:t.start.x,y:t.start.y})}const r=o[o.length-1],s={x:t.end.x,y:t.end.y,z:t.end.z},a={connectionName:t.connectionName,start:r,end:s,traceThickness:n};return xe(r,s)\u003eVY\u0026\u0026!this.isStitchSegmentClear(a)\u0026\u0026\"require_clear\"===this.stitchClearanceMode?(this.failed=!0,void(this.error=`Terminal stitch for \"${t.connectionName}\" violates copper clearance`)):(o.push(s),this.mergedHdRoute={connectionName:t.connectionName,...t.preserveTerminalPcbPortIds\u0026\u0026t.start.pcb_port_id?{startPcbPortId:t.start.pcb_port_id}:{},...t.preserveTerminalPcbPortIds\u0026\u0026t.end.pcb_port_id?{endPcbPortId:t.end.pcb_port_id}:{},rootConnectionName:e[0]?.rootConnectionName,route:o,vias:i,jumpers:[],viaDiameter:t.defaultViaDiameter??.3,traceThickness:n},void(this.solved=!0))}const n=new Set((t.preserveTerminalPcbPortIds?[t.start.pcb_port_id,t.end.pcb_port_id]:[]).filter(t=\u003evoid 0!==t));if(t.preserveTerminalPcbPortIds\u0026\u0026t.start.pcb_port_id\u0026\u0026t.start.pcb_port_id===t.end.pcb_port_id)throw new Error(`SingleHighDensityRouteStitchSolver3 received duplicate PCB terminal \"${t.start.pcb_port_id}\" for \"${t.connectionName}\"`);const o=e.flatMap(t=\u003e[t.startPcbPortId,t.endPcbPortId]).filter(t=\u003evoid 0!==t);if(n.size\u003e0)for(const e of o)if(!n.has(e))throw new Error(`SingleHighDensityRouteStitchSolver3 found unknown PCB terminal \"${e}\" on \"${t.connectionName}\"`);let i=1/0,r=e[0],s=\"start-to-end\";for(const n of e){const e=n.route[0],o=n.route[n.route.length-1],a=xe(t.start,e),c=xe(t.start,o),l=xe(t.end,e),d=xe(t.end,o),h=Math.min(a,c,l,d);(h\u003ci-DY||Math.abs(h-i)\u003c=DY\u0026\u0026YY(n,r)\u003c0)\u0026\u0026(i=h,r=n,s=Math.min(l,d)\u003cMath.min(a,c)-DY||Math.abs(Math.min(l,d)-Math.min(a,c))\u003c=DY\u0026\u0026BY(t.end,t.start)\u003c0?\"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 a=r.route[0],c=r.route[r.route.length-1],l=xe(this.start,a),d=xe(this.start,c),h=l\u003cd-DY||Math.abs(l-d)\u003c=DY\u0026\u0026BY(a,c)\u003c=0?a:c,u=h===a?r.startPcbPortId:r.endPcbPortId;if(u\u0026\u0026this.start.pcb_port_id\u0026\u0026u!==this.start.pcb_port_id)throw new Error(`SingleHighDensityRouteStitchSolver3 terminal identity disagrees with route orientation for \"${t.connectionName}\"`);this.mergedHdRoute={connectionName:t.connectionName,...t.preserveTerminalPcbPortIds\u0026\u0026this.start.pcb_port_id?{startPcbPortId:this.start.pcb_port_id}:{},...t.preserveTerminalPcbPortIds\u0026\u0026this.end.pcb_port_id?{endPcbPortId:this.end.pcb_port_id}:{},rootConnectionName:r.rootConnectionName,route:[{x:this.start.x,y:this.start.y,z:h.z}],vias:[],jumpers:[],viaDiameter:r.viaDiameter,traceThickness:r.traceThickness}}getDisjointedRoute(){for(const t of this.remainingHdRoutes){if([t.route[0],t.route[t.route.length-1]].some(e=\u003e!this.remainingHdRoutes.some(n=\u003e{if(n===t)return!1;return[n.route[0],n.route[n.route.length-1]].some(t=\u003et.z===e.z\u0026\u0026xe(e,t)\u003c.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],e={...this.end,z:t.z},n=xe(t,e);if(n\u003eVY\u0026\u0026n\u003c=zY){if(!this.isPlanarStitchClear(t,e)\u0026\u0026\"require_clear\"===this.stitchClearanceMode)return this.failed=!0,void(this.error=`Terminal stitch for \"${this.mergedHdRoute.connectionName}\" violates copper clearance`);this.mergedHdRoute.route.push({x:this.end.x,y:this.end.y,z:t.z})}return void(this.solved=!0)}const t=this.mergedHdRoute.route[this.mergedHdRoute.route.length-1];let e=-1,n=\"first\",o=1/0,i=!1;for(let r=0;r\u003cthis.remainingHdRoutes.length;r++){const s=this.remainingHdRoutes[r],a=s.route[0],c=s.route[s.route.length-1],l=xe(t,a),d=xe(t,c);let h=1/0;if(t.z===a.z){if(l\u003cVY)h=l;else if(l\u003c=1){const e=this.isPlanarStitchClear(t,a);if(e||\"prefer_clear\"===this.stitchClearanceMode){h=XY+(e?0:WY)+l}else i=!0}}else l\u003cVY\u0026\u0026(!this.allowedLayerTransitionPointKeys||this.allowedLayerTransitionPointKeys.has(af(a)))\u0026\u0026(h=1e3+l);h\u003co\u0026\u0026(o=h,e=r,n=\"first\");let u=1/0;if(t.z===c.z){if(d\u003cVY)u=d;else if(d\u003c=1){const e=this.isPlanarStitchClear(t,c);if(e||\"prefer_clear\"===this.stitchClearanceMode){u=XY+(e?0:WY)+d}else i=!0}}else d\u003cVY\u0026\u0026(!this.allowedLayerTransitionPointKeys||this.allowedLayerTransitionPointKeys.has(af(c)))\u0026\u0026(u=1e3+d);u\u003co\u0026\u0026(o=u,e=r,n=\"last\")}if(-1===e)return i?(this.failed=!0,void(this.error=`Route stitch for \"${this.mergedHdRoute.connectionName}\" violates copper clearance`)):void(this.remainingHdRoutes=[]);const r=this.remainingHdRoutes[e];let s;this.remainingHdRoutes.splice(e,1),s=\"first\"===n?r.route:(t=\u003e{const e=[...t].reverse().map(t=\u003e{const{toNextSegmentType:e,...n}=t;return n});for(let n=0;n\u003ct.length-1;n++){const o=t[n]?.toNextSegmentType;if(!o)continue;const i=t.length-n-2;e[i]={...e[i],toNextSegmentType:o}}return e})(r.route),s.length\u003e0\u0026\u0026xe(t,s[0])\u003cVY\u0026\u0026t.z===s[0].z?(s[0].toNextSegmentType\u0026\u0026(t.toNextSegmentType=s[0].toNextSegmentType),this.mergedHdRoute.route.push(...s.slice(1))):this.mergedHdRoute.route.push(...s),this.mergedHdRoute.vias.push(...r.vias),r.jumpers\u0026\u0026this.mergedHdRoute.jumpers.push(...r.jumpers)}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:\"Single High Density Route Stitch Solver 3\"};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\u0026\u0026this.mergedHdRoute.route.length\u003e1){t.lines?.push({points:this.mergedHdRoute.route.map(t=\u003e({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\u0026\u0026this.mergedHdRoute.jumpers.length\u003e0){const e=_a(this.mergedHdRoute.jumpers,{color:\"green\",label:this.mergedHdRoute.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const e of this.remainingHdRoutes){t.lines?.push({points:e.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:\"orange\"});for(const n of e.route)t.points?.push({x:n.x,y:n.y,color:\"orange\"});for(const n of e.vias)t.circles?.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:\"orange\"});if(e.jumpers\u0026\u0026e.jumpers.length\u003e0){const n=_a(e.jumpers,{color:\"orange\",label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}return t}},GY=class{constructor(t=!1){this.preferSameLayerTerminalEndpoints=t}preferSameLayerTerminalEndpoints;endpointClusters=new Map;getEndpointKey(t,e){const n=this.endpointClusters.get(t)??[];let o,i=1/0;for(const t of n){if(t.point.z!==e.z)continue;const n=xe(t.point,e);n\u003c=.1\u0026\u0026(n\u003ci-DY||Math.abs(n-i)\u003c=DY\u0026\u0026(!o||BY(t.point,o.point)\u003c0))\u0026\u0026(o=t,i=n)}if(o)return o.key;const r=`${t}:endpoint_${n.length}`;return n.push({key:r,point:{x:e.x,y:e.y,z:e.z}}),this.endpointClusters.set(t,n),r}getClusters(t){return this.endpointClusters.get(t)??[]}getClosestEndpointKey(t,e,n){const o=e.flatMap(t=\u003e[t.route[0],t.route[t.route.length-1]]),i=o.filter(t=\u003et.z===n.z),r=this.preferSameLayerTerminalEndpoints\u0026\u0026i.length\u003e0?i:o;let s=null,a=null,c=1/0;for(const e of r){const o=xe(n,e),i=this.getEndpointKey(t,e);(o\u003cc-DY||Math.abs(o-c)\u003c=DY\u0026\u0026(null===s||i.localeCompare(s)\u003c0||i===s\u0026\u0026null!==a\u0026\u0026BY(e,a)\u003c0))\u0026\u0026(c=o,s=i,a=e)}return s}},UY=(t,e,n)=\u003e{const o=t.get(e)??[];o.some(t=\u003et.nextHash===n.nextHash\u0026\u0026t.routeIndex===n.routeIndex)||(o.push(n),t.set(e,o))},ZY=t=\u003e{const e=[...t.possibleEndpoints].sort(BY),n=e.reduce((e,n)=\u003e{const o=xe(n,t.globalStart),i=xe(e,t.globalStart);return o\u003ci-DY||Math.abs(o-i)\u003c=DY\u0026\u0026BY(n,e)\u003c0?n:e}),o=e.filter(t=\u003et!==n),i=(o.length\u003e0?o:t.possibleEndpoints).reduce((e,n)=\u003e{const o=xe(n,t.globalEnd),i=xe(e,t.globalEnd);return o\u003ci-DY||Math.abs(o-i)\u003c=DY\u0026\u0026BY(n,e)\u003c0?n:e});return{start:n,end:i}},qY=t=\u003e{const e=[...t.terminals].sort(BY);let n=e[0],o=xe(t.islandEndpoint,n);for(const i of e.slice(1)){const e=xe(t.islandEndpoint,i);(e\u003co-DY||Math.abs(e-o)\u003c=DY\u0026\u0026BY(i,n)\u003c0)\u0026\u0026(n=i,o=e)}return o\u003c=zY?n:t.islandEndpoint},JY=t=\u003e{if(t.hdRoutes.length\u003c=2)return t.hdRoutes;const e=[...t.hdRoutes].sort(YY),n=t.endpointIndex.getClosestEndpointKey(t.connectionName,e,t.start),o=t.endpointIndex.getClosestEndpointKey(t.connectionName,e,t.end);if(!n||!o||n===o)return e;const i=new Map;for(let n=0;n\u003ce.length;n++){const o=e[n],r=t.endpointIndex.getEndpointKey(t.connectionName,o.route[0]),s=t.endpointIndex.getEndpointKey(t.connectionName,o.route[o.route.length-1]);UY(i,r,{nextHash:s,routeIndex:n}),UY(i,s,{nextHash:r,routeIndex:n})}const r=[...t.endpointIndex.getClusters(t.connectionName)].sort((t,e)=\u003eBY(t.point,e.point));for(let t=0;t\u003cr.length;t++){const e=r[t];for(let n=t+1;n\u003cr.length;n++){const t=r[n];e.point.z===t.point.z\u0026\u0026(xe(e.point,t.point)\u003e1||(UY(i,e.key,{nextHash:t.key,routeIndex:null}),UY(i,t.key,{nextHash:e.key,routeIndex:null})))}}for(const[t,n]of i.entries())i.set(t,[...n].sort((t,n)=\u003e{if(null===t.routeIndex\u0026\u0026null!==n.routeIndex)return 1;if(null!==t.routeIndex\u0026\u0026null===n.routeIndex)return-1;if(null!==t.routeIndex\u0026\u0026null!==n.routeIndex){const o=YY(e[t.routeIndex],e[n.routeIndex]);if(0!==o)return o}return t.nextHash.localeCompare(n.nextHash)}));const s=[n],a=new Set([n]),c=new Map;for(;s.length\u003e0;){const t=s.shift();if(t===o)break;for(const e of i.get(t)??[])a.has(e.nextHash)||(a.add(e.nextHash),c.set(e.nextHash,{prevHash:t,routeIndex:e.routeIndex}),s.push(e.nextHash))}if(!a.has(o))return e;const l=[];let d=o;for(;d!==n;){const t=c.get(d);if(!t)return e;null!==t.routeIndex\u0026\u0026l.push(t.routeIndex),d=t.prevHash}if(0===l.length)return t.hdRoutes;const h=l.reverse().map(t=\u003ee[t]);return h.length\u003e0\u0026\u0026!t.canStitchBetweenTerminals({connectionName:t.connectionName,hdRoutes:h,start:t.start,end:t.end})?e:h},KY=class extends si{getSolverName(){return\"MultipleHighDensityRouteStitchSolver3\"}unsolvedRoutes;activeSolver=null;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;allowedLayerTransitionPointKeys;preserveTerminalPcbPortIds;endpointIndex;clearanceValidator;canStitchBetweenTerminals(t){const e=new HY({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter,allowedLayerTransitionPointKeys:this.allowedLayerTransitionPointKeys,preserveTerminalPcbPortIds:this.preserveTerminalPcbPortIds,isStitchSegmentClear:t=\u003ethis.clearanceValidator.isSegmentClear(t),stitchClearanceMode:\"require_clear\"});for(;!e.solved\u0026\u0026!e.failed\u0026\u0026e.iterations\u003ce.MAX_ITERATIONS;)e.step();if(e.failed)return!1;const n=e.mergedHdRoute.route[0],o=e.mergedHdRoute.route[e.mergedHdRoute.route.length-1],i=xe(n,t.start)+xe(o,t.end),r=xe(n,t.end)+xe(o,t.start);return Math.min(i,r)\u003c=zY}getSharedRootPathRoutes(t){const e=t.rootConnectionName;if(!e)return null;const n=new Set(t.hdRoutes),o=t.allHdRoutes.filter(t=\u003e(t.rootConnectionName??t.connectionName)===e);if(o.every(t=\u003en.has(t)))return null;const i=JY({connectionName:t.connectionName,hdRoutes:o,start:t.start,end:t.end,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=\u003ethis.canStitchBetweenTerminals(t)});return!i.some(t=\u003e!n.has(t))||i.length\u003e=o.length?null:i}constructor(t){super(),this.endpointIndex=new GY(t.preferSameLayerTerminalEndpoints),this.colorMap=t.colorMap??{},this.allowedLayerTransitionPointKeys=t.allowedLayerTransitionPointKeys,this.preserveTerminalPcbPortIds=t.preserveTerminalPcbPortIds??!1;const e=[...t.hdRoutes].sort(YY);this.clearanceValidator=new LY({hdRoutes:e});const n=e[0];this.defaultTraceThickness=n?.traceThickness??.15,this.defaultViaDiameter=n?.viaDiameter??t.defaultViaDiameter??.3;const o=new fa({}),i=[],r=new Map;for(let t=0;t\u003ce.length;t++){const n=e[t],o=n.route[0],r=n.route[n.route.length-1];i.push([`route_island_${t}`,this.endpointIndex.getEndpointKey(n.connectionName,o),this.endpointIndex.getEndpointKey(n.connectionName,r)])}o.addConnections(i);for(const t of i)for(const e of t.slice(1))r.set(e,(r.get(e)??0)+1);this.unsolvedRoutes=[];const s=Array.from(new Set(Object.values(o.idToNetMap)));for(const n of s){const i=o.getIdsConnectedToNet(n),s=e.filter((t,e)=\u003ei.includes(`route_island_${e}`));if(0===s.length)continue;const a=t.connections.find(t=\u003et.name===s[0].connectionName),c=s.flatMap(t=\u003e[t.route[0],t.route[t.route.length-1]]),l=new Map,d=[];for(const t of c){const e=this.endpointIndex.getEndpointKey(s[0].connectionName,t);l.has(e)||l.set(e,t),1===r.get(e)\u0026\u0026d.push(t)}const h=d.length\u003e0?d:[...l.values()];if(0===h.length)continue;let u,p;if(h.length\u003e=2){const e={...a.pointsToConnect[0],z:ko(bo(a.pointsToConnect[0]),t.layerCount)},n={...a.pointsToConnect[1],z:ko(bo(a.pointsToConnect[1]),t.layerCount)};({start:u,end:p}=ZY({possibleEndpoints:h,globalStart:e,globalEnd:n})),xe(u,a.pointsToConnect[1])\u003cxe(p,a.pointsToConnect[0])\u0026\u0026([u,p]=[p,u]),u=qY({islandEndpoint:u,terminals:[e,n]}),p=qY({islandEndpoint:p,terminals:[e,n]})}else u={...a.pointsToConnect[0],z:ko(bo(a.pointsToConnect[0]),t.layerCount)},p={...a.pointsToConnect[1],z:ko(bo(a.pointsToConnect[1]),t.layerCount)};const m=JY({connectionName:s[0].connectionName,hdRoutes:s,start:u,end:p,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=\u003ethis.canStitchBetweenTerminals(t)});this.unsolvedRoutes.push({connectionName:s[0].connectionName,hdRoutes:m,start:u,end:p})}const a=new Map;for(const t of this.unsolvedRoutes){const e=a.get(t.connectionName);e?e.push(t):a.set(t.connectionName,[t])}this.unsolvedRoutes=Array.from(a.entries()).flatMap(([n,o])=\u003e{const i=t.connections.find(t=\u003et.name===n),r=o.some(t=\u003et.hdRoutes.some(t=\u003et.route.length\u003c2)),s=o.length\u003e1\u0026\u0026(t=\u003e{for(let e=0;e\u003ct.length;e++)for(let n=e+1;n\u003ct.length;n++){const o=[t[e].start,t[e].end],i=[t[n].start,t[n].end];for(const t of o)for(const e of i)if(t.z===e.z\u0026\u0026xe(t,e)\u003c=1)return!0}return!1})(o);if(!i)return o;const a={...i.pointsToConnect[0],z:ko(bo(i.pointsToConnect[0]),t.layerCount)},c={...i.pointsToConnect[1],z:ko(bo(i.pointsToConnect[1]),t.layerCount)},l=o.flatMap(t=\u003et.hdRoutes),d=o.length\u003e1?this.getSharedRootPathRoutes({connectionName:n,rootConnectionName:i.__rootConnectionNames?.[0]??l[0]?.rootConnectionName,hdRoutes:l,allHdRoutes:e,start:a,end:c}):null;return r||s||d?[{connectionName:n,hdRoutes:d??JY({connectionName:n,hdRoutes:l,start:a,end:c,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=\u003ethis.canStitchBetweenTerminals(t)}),start:a,end:c}]:o}),this.MAX_ITERATIONS=1e5}_step(){if(this.activeSolver)return this.activeSolver.step(),void(this.activeSolver.solved?(this.activeSolver instanceof HY\u0026\u0026(this.clearanceValidator.addRoute(this.activeSolver.mergedHdRoute),this.mergedHdRoutes.push(this.activeSolver.mergedHdRoute)),this.activeSolver=null):this.activeSolver.failed\u0026\u0026(this.failed=!0,this.error=this.activeSolver.error));const t=this.unsolvedRoutes.pop();t?this.activeSolver=new HY({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter,allowedLayerTransitionPointKeys:this.allowedLayerTransitionPointKeys,preserveTerminalPcbPortIds:this.preserveTerminalPcbPortIds,isStitchSegmentClear:t=\u003ethis.clearanceValidator.isSegmentClear(t),stitchClearanceMode:\"prefer_clear\"}):this.solved=!0}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:\"Multiple High Density Route Stitch Solver 3\"};if(this.activeSolver){const e=this.activeSolver.visualize();e.points?.length\u0026\u0026t.points?.push(...e.points),e.lines?.length\u0026\u0026t.lines?.push(...e.lines),e.circles?.length\u0026\u0026t.circles?.push(...e.circles),e.rects?.length\u0026\u0026(t.rects||(t.rects=[]),t.rects.push(...e.rects))}for(const[e,n]of this.mergedHdRoutes.entries()){const o=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e\u003cn.route.length-1;e++){const i=n.route[e],r=n.route[e+1],s=0!==i.z?To(o,.5):o;t.lines?.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:s,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?To(o,.5):o;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:o});if(n.jumpers\u0026\u0026n.jumpers.length\u003e0){const e=_a(n.jumpers,{color:o,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}return t}},QY=t=\u003e(t%360+360)%360,tX=(t,e)=\u003e{const{ccwRotationDegrees:n,...o}=t,i=(t=\u003e{const e=QY(t),n=[0,90,180,270];for(const t of n)if(Math.min(Math.abs(e-t),360-Math.abs(e-t))\u003c=.01)return t;return null})(e);return 90===i||270===i?{...o,width:t.height,height:t.width}:o},eX=t=\u003e\"layers\"in t?t.layers:[t.layer],nX=(t,e)=\u003e!(eX(t).length\u003e0\u0026\u0026!eX(t).some(t=\u003ee.layers.includes(t)))\u0026\u0026Me(t,Ve(e)),oX=(t,e)=\u003e{const{minX:n,maxX:o,minY:i,maxY:r}=Ve(e);return{x:Math.max(n,Math.min(o,t.x)),y:Math.max(i,Math.min(r,t.y))}},iX=(t,e)=\u003et.obstacleId??`${t.componentId??\"obstacle\"}_${e}`;function rX(t,e=2){const{center:n,width:o,height:i,rotation:r}=t,s=[],a=Math.max(1,Math.ceil(e)),c=r*Math.PI/180,l=Math.cos(c),d=Math.sin(c);if(o\u003e=i){const t=o/a;for(let e=0;e\u003ca;e++){const o=(e-a/2+.5)*t,r=o*l,c=o*d,h=Math.abs(t*l)+Math.abs(i*d),u=Math.abs(t*d)+Math.abs(i*l);s.push({center:{x:n.x+r,y:n.y+c},width:h,height:u})}}else{const t=i/a;for(let e=0;e\u003ca;e++){const i=(e-a/2+.5)*t,r=-i*d,c=i*l,h=Math.abs(o*l)+Math.abs(t*d),u=Math.abs(o*d)+Math.abs(t*l);s.push({center:{x:n.x+r,y:n.y+c},width:h,height:u})}}return s}var sX=t=\u003e{if(\"oval\"===t.type)return sX({...t,type:\"rect\"});const e=t.ccwRotationDegrees;if(\"number\"!=typeof e||!Number.isFinite(e))return[t];if((t=\u003e{const e=QY(t);return[0,90,180,270].some(t=\u003eMath.min(Math.abs(e-t),360-Math.abs(e-t))\u003c=.01)})(e))return[tX(t,e)];const{ccwRotationDegrees:n,...o}=t,i={center:t.center,width:t.width,height:t.height,rotation:e},r=(t=\u003e{const e=Math.max(t.width,t.height),n=Math.min(t.width,t.height);return t.obstacleId?.startsWith(\"trace_obstacle_\")?Math.max(2,Math.ceil(e/.75)):n\u003c=0?2:e/n\u003c2||n\u003e=.9?null:Math.max(2,Math.ceil(e/.75))})(t),s=t.connectedTo.length\u003e0\u0026\u0026!t.obstacleId?.startsWith(\"trace_obstacle_\")?(t=\u003e{const e=t.rotation*Math.PI/180,n=Math.cos(e),o=Math.sin(e),i=[-1,1].flatMap(e=\u003e[-1,1].map(i=\u003e{const r=e*(t.width/2),s=i*(t.height/2);return{x:t.center.x+r*n-s*o,y:t.center.y+r*o+s*n}})),r=[i[0],i[2],i[3],i[1]],s=Math.min(...r.map(t=\u003et.x)),a=Math.max(...r.map(t=\u003et.x)),c=Math.min(...r.map(t=\u003et.y)),l=Math.max(...r.map(t=\u003et.y)),d=a-s\u003c=l-c?\"x\":\"y\",h=\"x\"===d?s:c,u=\"x\"===d?a:l,p=Math.max(1,Math.ceil((u-h)/.4)),m=(u-h)/p,g=(t,e,n)=\u003e{const o=[],i=t=\u003et[d];for(let r=0;r\u003ct.length;r++){const s=t[r],a=t[(r+1)%t.length],c=i(s),l=i(a),d=n?c\u003e=e:c\u003c=e,h=n?l\u003e=e:l\u003c=e;if(d\u0026\u0026o.push(s),d===h)continue;const u=(e-c)/(l-c);o.push({x:s.x+(a.x-s.x)*u,y:s.y+(a.y-s.y)*u})}return o},f=[];for(let t=0;t\u003cp;t++){const e=h+t*m,n=t===p-1?u:e+m,o=g(g(r,e,!0),n,!1);if(0===o.length)continue;const i=Math.min(...o.map(t=\u003et.x)),s=Math.max(...o.map(t=\u003et.x)),a=Math.min(...o.map(t=\u003et.y)),c=Math.max(...o.map(t=\u003et.y));f.push({center:{x:(i+s)/2,y:(a+c)/2},width:s-i,height:c-a})}return f})(i):null===r?((t,e)=\u003e{const{center:n,width:o,height:i,rotation:r}=t,s=Math.max(1,Math.ceil(o/e)),a=Math.max(1,Math.ceil(i/e)),c=o/s,l=i/a,d=r*Math.PI/180,h=Math.cos(d),u=Math.sin(d),p=[];for(let t=0;t\u003cs;t++){const e=(t-s/2+.5)*c;for(let t=0;t\u003ca;t++){const o=(t-a/2+.5)*l;p.push({center:{x:n.x+e*h-o*u,y:n.y+e*u+o*h},width:Math.abs(c*h)+Math.abs(l*u),height:Math.abs(c*u)+Math.abs(l*h)})}}return p})(i,(t=\u003et.obstacleId?.startsWith(\"trace_obstacle_\")?.75:.4)(t)):t.obstacleId?.startsWith(\"trace_obstacle_\")?rX(i,r):((t,e)=\u003e{const{center:n,width:o,height:i,rotation:r}=t,s=Math.max(o,i),a=Math.min(o,i),c=Math.max(1,Math.ceil(e)),l=s/c,d=r*Math.PI/180,h=Math.cos(d),u=Math.sin(d),p=Math.max(l,.75*a),m=[];for(let t=0;t\u003cc;t++){const e=(t-c/2+.5)*l,r=o\u003e=i?e*h:-e*u,s=o\u003e=i?e*u:e*h;m.push({center:{x:n.x+r,y:n.y+s},width:p,height:p})}return m})(i,r),a=t.connectedTo.length\u003e0?s.reduce((e,n,o)=\u003e{const i=s[e],r=(i.center.x-t.center.x)**2+(i.center.y-t.center.y)**2;return(n.center.x-t.center.x)**2+(n.center.y-t.center.y)**2\u003cr?o:e},0):-1;return s.map((t,e)=\u003e({...o,obstacleId:e===a?o.obstacleId:o.obstacleId?`${o.obstacleId}_approx_${e}`:void 0,connectedTo:o.connectedTo,center:t.center,width:t.width,height:t.height}))},aX=t=\u003e{const e=new Map,n=new Map,o=new Map;for(const[i,r]of t.obstacles.entries()){const t=sX(r),s=iX(r,i);n.set(s,t),o.set(s,r);for(const n of t){const t=[n.center.x.toFixed(6),n.center.y.toFixed(6),n.width.toFixed(6),n.height.toFixed(6),n.layers.join(\",\")].join(\":\"),o=e.get(t);o?o.connectedTo=[...new Set([...o.connectedTo,...n.connectedTo])]:e.set(t,n)}}const i=t.connections.map(t=\u003e({...t,pointsToConnect:t.pointsToConnect.map(t=\u003e{const e=(t=\u003e[t.pointId,t.pcb_port_id].filter(t=\u003eBoolean(t)))(t);if(0===e.length)return t;for(const[i,r]of o){if(!e.some(t=\u003er.connectedTo.includes(t)))continue;if(!nX(t,r))continue;const o=n.get(i)??[];if(0===o.length)continue;if(o.some(e=\u003enX(t,e)))return t;let s=o[0],a=Number.POSITIVE_INFINITY;for(const e of o){const n=xe(oX(t,e),t);n\u003ca\u0026\u0026(a=n,s=e)}return{...t,...oX(t,s)}}return t})}));return{...t,connections:i,obstacles:[...e.values()]}},cX=.001,lX=t=\u003e\"wire\"===t.route_type,dX=t=\u003e\"via\"===t.route_type,hX=t=\u003e\"through_obstacle\"===t.route_type,uX=(t,e,n)=\u003e{const o=ko(t,n),i=ko(e,n),r=Math.min(o,i),s=Math.max(o,i);return Array.from({length:s-r+1},(t,e)=\u003evo(r+e,n))},pX=({obstacleId:t,start:e,end:n,width:o,layer:i,connectedTo:r})=\u003e{const s=n.x-e.x,a=n.y-e.y,c=Math.hypot(s,a);return c\u003c=cX?null:{obstacleId:t,type:\"rect\",layers:[i],center:{x:(e.x+n.x)/2,y:(e.y+n.y)/2},width:c,height:Math.max(o,cX),ccwRotationDegrees:180*Math.atan2(a,s)/Math.PI,connectedTo:r}};function mX(t){if(!t)return t;const e=(t=\u003e{if(!t)return[];const e=[],n=Yo(t);for(const[o,i]of(t.traces??[]).entries()){const r=i.connectsTo??[];for(let s=0;s\u003ci.route.length;s++){const a=i.route[s];if(dX(a)){const c=a.via_diameter??n.padDiameter;e.push({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${s}_via`,type:\"rect\",layers:uX(a.from_layer,a.to_layer,t.layerCount),center:{x:a.x,y:a.y},width:Math.max(c,cX),height:Math.max(c,cX),connectedTo:r});continue}if(hX(a)){const n=pX({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${s}_through`,start:a.start,end:a.end,width:a.width,layer:a.from_layer,connectedTo:r});n\u0026\u0026(n.layers=uX(a.from_layer,a.to_layer,t.layerCount),e.push(n))}}for(let t=0;t\u003ci.route.length-1;t++){const n=i.route[t],s=i.route[t+1];if(!lX(n)||!lX(s)||n.layer!==s.layer)continue;const a=pX({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${t}_wire`,start:n,end:s,width:n.width,layer:n.layer,connectedTo:r});a\u0026\u0026e.push(a)}}return e})(t);return 0===e.length?t:{...t,obstacles:[...t.obstacles??[],...e]}}function gX(t,e){const n=function(t,e){const n=Lo(t.__zLayers??t.zLayers??[],e);if(n.length\u003e0)return n;const o=Do(t.layers,e);if(o.length\u003e0)return o;throw new Error(`Obstacle \"${t.obstacleId??\"unknown\"}\" has no layers on this ${e}-layer board`)}(t,e);return{...t,layers:n.map(t=\u003evo(t,e)),zLayers:n,__zLayers:n}}function fX(t){return{...t,obstacles:t.obstacles.map(e=\u003egX(e,t.layerCount)),jumpers:t.jumpers?.map(e=\u003e({...e,pads:e.pads.map(e=\u003egX(e,t.layerCount))}))}}var yX=t=\u003e{const e=t.obstacles.filter(e=\u003e!((t,e)=\u003e!(t=\u003e(t.connectedTo?.length??0)\u003e0||(t.offBoardConnectsTo?.length??0)\u003e0||!0===t.netIsAssignable)(t)\u0026\u0026(e.outline\u0026\u0026e.outline.length\u003e=3?!Te(t,e.outline):!Xe({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.bounds)))(e,t)),n=e.length!==t.obstacles.length,o=n\u0026\u0026t.outline\u0026\u0026t.outline.length\u003e=3?(t=\u003e{if(t.width\u0026\u0026t.height\u0026\u0026t.center){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,width:t.width,height:t.height,center:{x:t.center.x,y:t.center.y}}}if(!t.outline||0===t.outline.length)throw new Error(\"Unable to compute board bounds. pcb_board must include width/height/center or a non-empty outline.\");let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t.outline)e=Math.min(e,r.x),n=Math.min(n,r.y),o=Math.max(o,r.x),i=Math.max(i,r.y);const r=o-e,s=i-n;return{minX:e,minY:n,maxX:o,maxY:i,width:r,height:s,center:{x:e+r/2,y:n+s/2}}})({type:\"pcb_board\",pcb_board_id:\"__autorouting_board_outline__\",center:{x:0,y:0},thickness:1,num_layers:t.layerCount,material:\"fr4\",outline:t.outline}):t.bounds;return n?{...t,obstacles:e,bounds:o}:t},_X=class extends si{constructor(t,e={}){super(),this.inputSrj=t,this.visualizationOptions=e,this.MAX_ITERATIONS=1}inputSrj;visualizationOptions;outputSrj;_step(){const t=fX(this.inputSrj),e=mX(t)??t,n=aX(yX(e));this.outputSrj=fX(n),this.solved=!0}getOutputSimpleRouteJson(){if(!this.outputSrj)throw new Error(\"PreprocessSimpleRouteJsonSolver has not solved yet\");return this.outputSrj}getConstructorParams(){return[this.inputSrj,this.visualizationOptions]}visualize(){return this.outputSrj?pi(Ho({...this.outputSrj,traces:[]},this.visualizationOptions),Yj({srj:this.outputSrj,visualizationOptions:this.visualizationOptions})):{lines:[],points:[],rects:[],circles:[]}}};function bX(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var xX=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;nodeSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[bX(\"preprocessSimpleRouteJsonSolver\",_X,t=\u003e[t.originalSrj],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),bX(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),bX(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),bX(\"nodeSolver\",Kn,t=\u003e[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=\u003e{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),bX(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver?.outputNodes??[]}}),bX(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),bX(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),bX(\"necessaryCrampedPortPointSolver\",sf,t=\u003e[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),bX(\"portPointPathingSolver\",jj,t=\u003e{const e=t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),bX(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),bX(\"highDensityRouteSolver\",zs,t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=(e.length\u003e0?e:n).map(e=\u003ews(e)?{...e,availableZ:Array.from({length:t.srj.layerCount},(t,e)=\u003ee)}:e);return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0}]}),bX(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,totalStepsPerNode:Math.max(20,Math.round(60*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),bX(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2}]),bX(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),bX(\"traceSimplificationSolver\",vc,t=\u003e[{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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,iterations:2}]),bX(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),bX(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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\u0026\u0026(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\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.nodeSolver?.visualize(),o=this.nodeDimensionSubdivisionSolver?.visualize(),i=this.nodeTargetMerger?.visualize(),r=this.singleLayerNodeMerger?.visualize(),s=this.strawSolver?.visualize(),a=this.edgeSolver?.visualize(),c=this.deadEndSolver?.visualize(),l=this.availableSegmentPointSolver?.visualize(),d=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),u=this.uniformPortDistributionSolver?.visualize(),p=this.highDensityRouteSolver?.visualize(),m=this.highDensityForceImproveSolver?.visualize(),g=this.highDensityRepairSolver?.visualize(),f=this.highDensityStitchSolver?.visualize(),y=this.traceSimplificationSolver?.visualize(),_=this.necessaryCrampedPortPointSolver?.visualize(),b=(this.highDensityRouteSolver?.visualize(),this.originalSrj),x=b.outline,v=[];if(v.push({points:[{x:b.bounds?.minX??-50,y:b.bounds?.minY??-50},{x:b.bounds?.maxX??50,y:b.bounds?.minY??-50},{x:b.bounds?.maxX??50,y:b.bounds?.maxY??50},{x:b.bounds?.minX??-50,y:b.bounds?.maxY??50},{x:b.bounds?.minX??-50,y:b.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),x\u0026\u0026x.length\u003e=2){const t=x.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const S=Oo(b),I={points:[...b.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,b.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(b.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,b.layerCount),label:S(t)}))],lines:v},C=Yj({srj:b}),P=[pi(I,C),t,e,n,o,i,r,s,a,c,l,_,d,h,u,p?pi(I,p):null,m,g,f,y,this.solved?pi({lines:v},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...P)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){return this.globalDrcForceImproveSolver?.getOutput()??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 o=n.__netConnectionName??this.originalSrj.connections.find(t=\u003et.name===n.name)?.__netConnectionName,i=e.filter(t=\u003et.connectionName===n.name);for(let e=0;e\u003ci.length;e++){const r=i[e],s={type:\"pcb_trace\",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.srj.obstacles,connMap:this.connMap})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},vX=t=\u003e{const e=[];let n=t;for(;n;)e.push(n),n=n.activeSubSolver;for(let t=e.length-1;t\u003e=0;t--){const n=e[t]?.pendingEffects?.filter(Boolean)??[];if(n.length\u003e0)return n}return[]},SX=t=\u003e/\\/solve\\/?$/.test(t)?t.replace(/\\/+$/,\"\"):`${t.replace(/\\/+$/,\"\")}/solve`,IX=(t,e,n)=\u003e{const o=(t=\u003e{const e=new Map;for(const n of t.portPoints)n.rootConnectionName\u0026\u0026!e.has(n.connectionName)\u0026\u0026e.set(n.connectionName,n.rootConnectionName);return e})(t);return e.map(t=\u003e({connectionName:t.connectionName,rootConnectionName:t.rootConnectionName??o.get(t.connectionName)??void 0,traceThickness:t.traceThickness??n.traceWidth,viaDiameter:t.viaDiameter??n.viaDiameter,route:(t.route??[]).map(t=\u003e({x:t.x,y:t.y,z:t.z,...t.insideJumperPad?{insideJumperPad:!0}:{}})),vias:(t.vias??[]).map(t=\u003e({x:t.x,y:t.y})),...t.jumpers?{jumpers:t.jumpers}:{}}))},CX=(t,e)=\u003e{if(0===t.length)return null;const n=Math.min(Math.max(e,0),1),o=(t.length-1)*n,i=Math.floor(o),r=Math.ceil(o),s=t[i],a=t[r];return i===r?s:s+(a-s)*(o-i)},PX=t=\u003enew Set(t.portPoints.map(t=\u003et.connectionName)).size,MX=t=\u003e!(PX(t)\u003c3)\u0026\u00261!==(t.availableZ?.length??0),NX=t=\u003et?.MULTI_HEAD_POLYLINE_SOLVER?\"MultiHeadPolyLineIntraNodeSolver3\":t?.CLOSED_FORM_SINGLE_TRANSITION?\"SingleTransitionIntraNodeSolver\":t?.CLOSED_FORM_TWO_TRACE_SAME_LAYER?\"TwoCrossingRoutesHighDensitySolver\":t?.CLOSED_FORM_TWO_TRACE_TRANSITION_CROSSING?\"SingleTransitionCrossingRouteSolver\":t?.HIGH_DENSITY_A01?\"HighDensitySolverA01\":t?.HIGH_DENSITY_A03?\"HighDensitySolverA03\":\"SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost\",wX=t=\u003e{if(t instanceof rr){const e=NX(t.hyperParameters);return t.cacheHit?`${e} [cached]`:e}if(t instanceof er)return NX(t.hyperParameters);if(t\u0026\u0026\"object\"==typeof t\u0026\u0026\"getSolverName\"in t\u0026\u0026\"function\"==typeof t.getSolverName)return t.getSolverName();const e=t?.constructor;return\"string\"==typeof e?.name?e.name:\"unknown\"},TX=t=\u003et.winningSolver?wX(t.winningSolver):wX(t),RX=class extends si{getSolverName(){return\"Pipeline5HdCacheHighDensitySolver\"}unsolvedNodePortPoints;colorMap;connMap;viaDiameter;traceWidth;obstacleMargin;obstacles;layerCount;hdCacheBaseUrl;fetchImpl;nodePfById;routes=[];nodeSolveMetadataById=new Map;launchedRemoteSolves=!1;solvedRoutesByNodeIndex=new Map;failedNodeResults=[];remoteResponseMeasurements=[];constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,obstacles:s,layerCount:a,nodePfById:c,hdCacheBaseUrl:l,fetchImpl:d}){super(),this.unsolvedNodePortPoints=t,this.colorMap=e??{},this.connMap=n,this.viaDiameter=o??.3,this.traceWidth=i??.15,this.obstacleMargin=r??.15,this.obstacles=s??[],this.layerCount=a??2,this.hdCacheBaseUrl=l??\"https://hd-cache.tscircuit.com\",this.fetchImpl=(d??globalThis.fetch).bind(globalThis),this.nodePfById=c instanceof Map?new Map(c):new Map(Object.entries(c??{})),this.pendingEffects=[],this.stats={localDirectNodeCount:0,localSolvedNodeCount:0,localFallbackNodeCount:0,remoteFallbackNodeCount:0,remoteRequestsStarted:0,remoteRequestsCompleted:0,remoteResponseSampleCount:0,remoteKOrderSampleCount:0,slowestRemoteResponseMs:null,slowestRemoteResponseNodeId:null,p50RemoteResponseMs:null,p50RemoteKOrder:null,p95RemoteKOrder:null,remoteSources:{}}}computeProgress(){return 0===this.unsolvedNodePortPoints.length?1:this.nodeSolveMetadataById.size/this.unsolvedNodePortPoints.length}solveNodeLocally(t,e,n={}){const o=new Ss({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,obstacles:this.obstacles,layerCount:this.layerCount});if(o.solve(),o.failed){const e=o.error??`Local intra-node solver failed for ${t.capacityMeshNodeId}`,i=PX(t);return this.failedNodeResults.push({node:t,error:n.remoteFailure\u0026\u0026\"local-fallback\"===n.resolution?`Remote solve failed (${n.remoteFailure}); local fallback failed (${e})`:e}),void this.recordNodeSolveMetadata(t,{status:\"failed\",resolution:\"failed\",solverType:TX(o),supervisorType:o.getSolverName(),iterations:o.iterations,pairCount:i,routeCount:0,remoteAttempt:\"local-fallback\"===n.resolution?{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:\"error\",durationMs:n.remoteDurationMs,error:n.remoteFailure??e}:{attempted:!1},error:e})}this.solvedRoutesByNodeIndex.set(e,o.solvedRoutes);const i=PX(t);this.recordNodeSolveMetadata(t,{status:\"solved\",resolution:n.resolution??\"local\",solverType:TX(o),supervisorType:o.getSolverName(),iterations:o.iterations,pairCount:i,routeCount:o.solvedRoutes.length,remoteAttempt:\"local-fallback\"===n.resolution?{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:\"error\",durationMs:n.remoteDurationMs,error:n.remoteFailure}:{attempted:!1}}),\"local-fallback\"===n.resolution?(this.stats.localFallbackNodeCount+=1,this.stats.remoteFallbackNodeCount+=1):this.stats.localDirectNodeCount+=1,this.stats.localSolvedNodeCount+=1}async solveNodeViaHdCache(t,e){const n=SX(this.hdCacheBaseUrl),o={\"content-type\":\"application/json\"},i={nodeWithPortPoints:t},r=JSON.stringify(i),s=Date.now();let a,c,l,d=null,h=null;try{const i=await this.fetchImpl(n,{method:\"POST\",headers:o,body:r});if(a=i.status,c=i.ok,l=await i.text(),d=Date.now()-s,h=l?JSON.parse(l):null,!i.ok)throw new Error(h?.message??l??`hd-cache request failed with status ${i.status}`);if(!h?.ok||null===h.routes)throw new Error(h?.message??`hd-cache returned no routes for ${t.capacityMeshNodeId}`);const u=IX(t,h.routes,{traceWidth:this.traceWidth,viaDiameter:this.viaDiameter});this.solvedRoutesByNodeIndex.set(e,u),this.recordNodeSolveMetadata(t,{status:\"solved\",resolution:\"remote\",solverType:`hd-cache.tscircuit.com [${h.source}]`,iterations:null,pairCount:PX(t),routeCount:u.length,remoteAttempt:{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:h.source,durationMs:d}}),this.recordRemoteSource(h.source)}catch(u){d??=Date.now()-s;const p=(t=\u003et instanceof Error?t.message:String(t))(u);this.recordFailedHdCacheRequest({nodeId:t.capacityMeshNodeId,pairCount:PX(t),failedAt:(new Date).toISOString(),durationMs:d,error:p,url:n,request:{method:\"POST\",headers:o,body:r,bodyJson:i},response:void 0!==a||void 0!==c||void 0!==l||null!==h?{status:a,ok:c,text:l,body:h}:void 0}),this.recordRemoteSource(\"error\"),this.solveNodeLocally(t,e,{resolution:\"local-fallback\",remoteFailure:p,remoteDurationMs:d})}finally{this.recordRemoteResponseMetrics(t.capacityMeshNodeId,d??Date.now()-s,(u=h?.kOrder,\"number\"==typeof u\u0026\u0026Number.isFinite(u)?h.kOrder:null)),this.stats.remoteRequestsCompleted+=1}var u}launchRemoteSolves(){const t=[];this.unsolvedNodePortPoints.forEach((e,n)=\u003e{if(!MX(e))return void this.solveNodeLocally(e,n);const o={name:`hd-cache:${e.capacityMeshNodeId}`,promise:Promise.resolve()};o.promise=this.solveNodeViaHdCache(e,n).finally(()=\u003e{this.pendingEffects=this.pendingEffects?.filter(t=\u003et!==o)}),t.push(o)}),this.pendingEffects=t,this.stats.remoteRequestsStarted=t.length}recordRemoteSource(t){this.stats.remoteSources[t]=(this.stats.remoteSources[t]??0)+1}recordRemoteResponseMetrics(t,e,n){this.remoteResponseMeasurements.push({nodeId:t,durationMs:e,kOrder:n}),this.stats.remoteResponseSampleCount=this.remoteResponseMeasurements.length,this.stats.remoteKOrderSampleCount=this.remoteResponseMeasurements.filter(t=\u003enull!==t.kOrder).length;let o=null;for(const t of this.remoteResponseMeasurements)(!o||t.durationMs\u003eo.durationMs)\u0026\u0026(o=t);this.stats.slowestRemoteResponseMs=o?.durationMs??null,this.stats.slowestRemoteResponseNodeId=o?.nodeId??null;const i=this.remoteResponseMeasurements.map(t=\u003et.durationMs).sort((t,e)=\u003et-e);this.stats.p50RemoteResponseMs=CX(i,.5);const r=this.remoteResponseMeasurements.map(t=\u003et.kOrder).filter(t=\u003enull!==t).sort((t,e)=\u003et-e);this.stats.p50RemoteKOrder=CX(r,.5),this.stats.p95RemoteKOrder=CX(r,.95)}recordFailedHdCacheRequest(t){const e=(()=\u003e{if(\"undefined\"==typeof window)return null;const t=window;return Array.isArray(t.__FAILED_HD_CACHE_REQUESTS)||(t.__FAILED_HD_CACHE_REQUESTS=[]),t.__FAILED_HD_CACHE_REQUESTS})();e\u0026\u0026e.push(t)}recordNodeSolveMetadata(t,e){this.nodeSolveMetadataById.set(t.capacityMeshNodeId,{...e,node:t,nodePf:this.nodePfById.get(t.capacityMeshNodeId)??null})}ensureFailedNodeMetadata(){for(const t of this.failedNodeResults)this.nodeSolveMetadataById.has(t.node.capacityMeshNodeId)||this.recordNodeSolveMetadata(t.node,{status:\"failed\",resolution:\"failed\",solverType:\"unknown\",iterations:null,pairCount:PX(t.node),routeCount:0,remoteAttempt:{attempted:MX(t.node),source:\"error\",error:t.error},error:t.error})}getVisibleRoutes(){if(this.solved)return this.routes;const t=[];for(let e=0;e\u003cthis.unsolvedNodePortPoints.length;e++)t.push(...this.solvedRoutesByNodeIndex.get(e)??[]);return t}createNodeMarkerLabel(t,e){return[\"hd_node_marker\",`node: ${t}`,`status: ${e.status}`,`resolution: ${e.resolution}`,`solver: ${e.solverType}`,...e.supervisorType?[`supervisor: ${e.supervisorType}`]:[],...null!==e.iterations?[`iterations: ${e.iterations}`]:[],`pairCount: ${e.pairCount}`,`routes: ${e.routeCount}`,`nodePf: ${e.nodePf??\"n/a\"}`,\"remoteAttempted: \"+(e.remoteAttempt.attempted?\"yes\":\"no\"),...e.remoteAttempt.source?[`remoteSource: ${e.remoteAttempt.source}`]:[],...void 0!==e.remoteAttempt.durationMs?[`remoteDurationMs: ${e.remoteAttempt.durationMs}`]:[],...e.remoteAttempt.error?[`remoteError: ${e.remoteAttempt.error}`]:[],`portPoints: ${e.node.portPoints.length}`,...e.error?[`error: ${e.error}`]:[]].join(\"\\n\")}_step(){if(!this.launchedRemoteSolves)return this.launchedRemoteSolves=!0,void this.launchRemoteSolves();if(!((this.pendingEffects?.length??0)\u003e0)){if(this.failedNodeResults.length\u003e0){this.ensureFailedNodeMetadata();const t=this.failedNodeResults[0];return this.failed=!0,void(this.error=`Failed to solve ${this.failedNodeResults.length} nodes via hd-cache. First failure: ${t?.node.capacityMeshNodeId} (${t?.error})`)}this.routes=[];for(let t=0;t\u003cthis.unsolvedNodePortPoints.length;t++)this.routes.push(...this.solvedRoutesByNodeIndex.get(t)??[]);this.solved=!0}}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.getVisibleRoutes()){const n=mi(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const o of n)t.lines.push({points:o.points,label:o.connectionName,strokeColor:0===o.z?o.color:To(o.color,.75),layer:`z${o.z}`,strokeWidth:e.traceThickness,strokeDash:0!==o.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,n]of this.nodeSolveMetadataById){const o=n.node.center.x-n.node.width/2,i=n.node.center.x+n.node.width/2,r=n.node.center.y-n.node.height/2,s=n.node.center.y+n.node.height/2,a=this.createNodeMarkerLabel(e,n),c=\"solved\"===n.status?\"blue\":\"red\",l=\"solved\"===n.status?.03:.08;if(t.lines.push({points:[{x:o,y:r},{x:i,y:r}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a},{points:[{x:i,y:r},{x:i,y:s}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a},{points:[{x:i,y:s},{x:o,y:s}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a},{points:[{x:o,y:s},{x:o,y:r}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a}),\"solved\"===n.status)t.points.push({x:n.node.center.x,y:n.node.center.y,color:c,layer:\"hd_node_markers\",label:a});else{t.lines.push({points:[{x:0,y:0},{x:n.node.center.x,y:n.node.center.y}],layer:\"hd_failed_node_guides\",strokeColor:c,strokeDash:\"8, 6\",strokeWidth:.05,label:a});const e=Math.max(n.node.width,1.2),o=Math.max(n.node.height,1.2),i=e/2,r=o/2;t.rects.push({center:n.node.center,layer:\"hd_node_markers\",width:e,height:o,fill:\"rgba(255, 0, 0, 0.3)\",stroke:c,label:a}),t.circles.push({center:n.node.center,radius:Math.max(.6*Math.max(e,o),1.1),layer:\"hd_node_markers\",fill:\"rgba(255, 0, 0, 0.08)\",stroke:c,label:a}),t.lines.push({points:[{x:n.node.center.x-i,y:n.node.center.y-r},{x:n.node.center.x+i,y:n.node.center.y+r}],layer:\"hd_node_markers\",strokeColor:c,strokeWidth:.16,label:a},{points:[{x:n.node.center.x-i,y:n.node.center.y+r},{x:n.node.center.x+i,y:n.node.center.y-r}],layer:\"hd_node_markers\",strokeColor:c,strokeWidth:.16,label:a})}}return t}},EX=class extends xX{hdCacheBaseUrl;hdCacheFetch;constructor(t,e={}){super(t,{...e,maxNodeDimension:e.maxNodeDimension??7,maxNodeRatio:e.maxNodeRatio??4}),this.hdCacheBaseUrl=e.hdCacheBaseUrl??\"https://hd-cache.tscircuit.com\",this.hdCacheFetch=e.hdCacheFetch,this.replaceHighDensityPipelineStep()}replaceHighDensityPipelineStep(){const t=this.pipelineDef.findIndex(t=\u003e\"highDensityRouteSolver\"===t.solverName);if(-1===t)throw new Error(\"Pipeline4 highDensityRouteSolver step is missing\");this.pipelineDef[t]={...this.pipelineDef[t],solverClass:RX,getConstructorParams:t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length\u003e0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,hdCacheBaseUrl:t.hdCacheBaseUrl,fetchImpl:t.hdCacheFetch}]}}}async stepAsync(){if(this.solved||this.failed)return;this.step();const t=vX(this);0!==t.length\u0026\u0026(await Promise.race(t.map(t=\u003et.promise.then(()=\u003et.name,()=\u003et.name))),this.solved||this.failed||this.step())}async solveAsync(){const t=Date.now();for(;!this.solved\u0026\u0026!this.failed;)await this.stepAsync();this.timeToSolve=Date.now()-t}solve(){throw new Error(\"AutoroutingPipelineSolver5_HdCache requires async execution. Use solveAsync() or stepAsync().\")}},AX=1e-9,OX=Math.PI/2,kX=(t,e)=\u003et.x*e.y-t.y*e.x,LX=(t,e)=\u003et.x*e.x+t.y*e.y,DX=t=\u003e{let e=t%OX;return e\u003c0\u0026\u0026(e+=OX),OX-e\u003c1e-8?0:e},zX=t=\u003e{const e=Math.cos(t),n=Math.sin(t);return{u:{x:e,y:n},v:{x:-n,y:e}}},FX=t=\u003e{let e=0;for(let n=0;n\u003ct.length;n++){const o=t[n],i=t[(n+1)%t.length];e+=o.x*i.y-i.x*o.y}return e/2},BX=t=\u003eMath.abs(FX(t)),jX=t=\u003e{const e=FX(t);if(Math.abs(e)\u003cAX){const e=t.reduce((t,e)=\u003e({x:t.x+e.x,y:t.y+e.y}),{x:0,y:0});return{x:e.x/Math.max(1,t.length),y:e.y/Math.max(1,t.length)}}let n=0,o=0;for(let e=0;e\u003ct.length;e++){const i=t[e],r=t[(e+1)%t.length],s=i.x*r.y-r.x*i.y;n+=(i.x+r.x)*s,o+=(i.y+r.y)*s}const i=1/(6*e);return{x:n*i,y:o*i}},$X=t=\u003eFX(t)\u003e=0?[...t]:[...t].reverse(),YX=(t,e)=\u003e{const n=new Set;n.add(0);for(let t=0;t\u003c90;t++)n.add(t/90*OX);for(let e=0;e\u003ct.length;e++){const o=t[e],i=t[(e+1)%t.length],r=Math.atan2(i.y-o.y,i.x-o.x);n.add(DX(r)),n.add(DX(r+OX))}const o=n=\u003e{const o=((t,e=jX(t),n=0)=\u003e{const o=$X(t),{u:i,v:r}=zX(n),s=o.map((t,n)=\u003e{const s=o[(n+1)%o.length],a=s.x-t.x,c=s.y-t.y,l={x:a,y:c};return{hxCoeff:Math.abs(kX(l,i)),hyCoeff:Math.abs(kX(l,r)),limit:a*(e.y-t.y)-c*(e.x-t.x)}});if(s.some(t=\u003et.limit\u003c-1e-7))throw new Error(\"Projected rect center is outside polygon\");let a=Number.POSITIVE_INFINITY;for(const t of s)t.hxCoeff\u003eAX\u0026\u0026(a=Math.min(a,t.limit/t.hxCoeff));if(!Number.isFinite(a)||a\u003c=AX)return{center:e,width:1e-6,height:1e-6,ccwRotationRadians:n,ccwRotationDegrees:180*n/Math.PI};const c=t=\u003e{let e=Number.POSITIVE_INFINITY;for(const n of s){const o=n.limit-n.hxCoeff*t;if(o\u003c-1e-8)return 0;n.hyCoeff\u003eAX\u0026\u0026(e=Math.min(e,o/n.hyCoeff))}return Number.isFinite(e)?Math.max(0,e):0},l=t=\u003et*c(t);let d=0,h=a;for(let t=0;t\u003c80;t++){const t=d+(h-d)/3,e=h-(h-d)/3;l(t)\u003cl(e)?d=t:h=e}const u=(d+h)/2,p=c(u);return{center:e,width:Math.max(1e-6,2*u),height:Math.max(1e-6,2*p),ccwRotationRadians:n,ccwRotationDegrees:180*n/Math.PI}})(t,e,n);return{rect:o,area:o.width*o.height}};let i=o(0),r=0;for(const t of n){const e=o(t);e.area\u003ei.area+1e-8\u0026\u0026(i=e,r=t)}const s=OX/90;let a=r-s,c=r+s;for(let t=0;t\u003c60;t++){const t=a+(c-a)/3,e=c-(c-a)/3;o(t).area\u003co(e).area?a=t:c=e}const l=o(DX((a+c)/2));return l.area\u003ei.area+1e-8?l.rect:i.rect},XX=(t,e,n,o)=\u003e{const i=o.x-n.x,r=o.y-n.y,s=e.x*r-e.y*i;if(Math.abs(s)\u003cAX)return;const a=n.x-t.x,c=n.y-t.y,l=(a*r-c*i)/s,d=(a*e.y-c*e.x)/s;return l\u003c-1e-8||d\u003c-1e-8||d\u003e1+1e-8?void 0:{x:t.x+e.x*l,y:t.y+e.y*l,rayT:l}},VX=(t,e)=\u003e{const n=[],o=[];for(let i=0;i\u003c4;i++){const{x:r,y:s}=t[i],a=e[i].x,c=e[i].y;n.push([r,s,1,0,0,0,-a*r,-a*s]),o.push(a),n.push([0,0,0,r,s,1,-c*r,-c*s]),o.push(c)}const i=((t,e)=\u003e{const n=e.length,o=t.map((t,n)=\u003e[...t,e[n]]);for(let t=0;t\u003cn;t++){let e=t;for(let i=t+1;i\u003cn;i++)Math.abs(o[i][t])\u003eMath.abs(o[e][t])\u0026\u0026(e=i);if(Math.abs(o[e][t])\u003cAX)throw new Error(\"Could not solve homography\");[o[t],o[e]]=[o[e],o[t]];const i=o[t][t];for(let e=t;e\u003c=n;e++)o[t][e]=o[t][e]/i;for(let e=0;e\u003cn;e++){if(e===t)continue;const i=o[e][t];for(let r=t;r\u003c=n;r++)o[e][r]=o[e][r]-i*o[t][r]}}return o.map(t=\u003et[n])})(n,o);return[i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7],1]},WX=(t,e)=\u003e{const n=Math.cos(e),o=Math.sin(e);return[n,-o,t.x-n*t.x+o*t.y,o,n,t.y-o*t.x-n*t.y,0,0,1]},HX=(t,e)=\u003e{const n=t[6]*e.x+t[7]*e.y+t[8];return Math.abs(n)\u003cAX?{x:e.x,y:e.y}:{x:(t[0]*e.x+t[1]*e.y+t[2])/n,y:(t[3]*e.x+t[4]*e.y+t[5])/n}},GX=(t,e,n)=\u003e{const{u:o,v:i}=zX(n);return{x:e.x+t.x*o.x+t.y*i.x,y:e.y+t.x*o.y+t.y*i.y}},UX=(t,e)=\u003eGX({x:t.x-e.center.x,y:t.y-e.center.y},e.center,e.ccwRotationRadians),ZX=(t,e)=\u003e{const n=((t,e,n)=\u003e{const{u:o,v:i}=zX(n),r={x:t.x-e.x,y:t.y-e.y};return{x:LX(r,o),y:LX(r,i)}})(t,e.center,e.ccwRotationRadians);if(Math.abs(n.x)\u003cAX\u0026\u0026Math.abs(n.y)\u003cAX)return{...e.center};const o=e.width/2,i=e.height/2,r=Math.abs(n.x)\u003eAX?o/Math.abs(n.x):1/0,s=Math.abs(n.y)\u003eAX?i/Math.abs(n.y):1/0,a=Math.min(r,s);return{x:e.center.x+n.x*a,y:e.center.y+n.y*a}},qX=(t,e=0,n=0)=\u003e{const o=((t,e)=\u003e{const n=$X(e);for(let e=0;e\u003cn.length;e++){const o=n[e],i=n[(e+1)%n.length];if((i.x-o.x)*(t.y-o.y)-(i.y-o.y)*(t.x-o.x)\u003c-1e-7)return!1}return!0})(jX(t),t)?[...t]:(t=\u003e{const e=[...t].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e.x-t.x)\u003c1e-9\u0026\u0026Math.abs(e.y-t.y)\u003c1e-9)===e).sort((t,e)=\u003et.x-e.x||t.y-e.y);if(e.length\u003c=3)return e;const n=(t,e,n)=\u003e(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),o=[];for(const t of e){for(;o.length\u003e=2\u0026\u0026n(o[o.length-2],o[o.length-1],t)\u003c=1e-9;)o.pop();o.push(t)}const i=[];for(let t=e.length-1;t\u003e=0;t--){const o=e[t];for(;i.length\u003e=2\u0026\u0026n(i[i.length-2],i[i.length-1],o)\u003c=1e-9;)i.pop();i.push(o)}return o.pop(),i.pop(),[...o,...i]})(t),i=jX(o),r=YX(o,i),s=BX(o),a=r.width*r.height,c=(l=e,Math.max(0,l));var l;const d=a+Math.max(0,s-a)*c,h=a\u003eAX\u0026\u0026d\u003ea?Math.sqrt(d/a):1,u=Math.max(0,n),p=Math.max(r.width*h,u),m=Math.max(r.height*h,u),g=DX(r.ccwRotationRadians),f=180*g/Math.PI,y=(t=\u003e{const e=t.width/2,n=t.height/2;return[{x:t.center.x-e,y:t.center.y-n},{x:t.center.x+e,y:t.center.y-n},{x:t.center.x+e,y:t.center.y+n},{x:t.center.x-e,y:t.center.y+n}]})({center:i,width:p,height:m}),_=(t=\u003e{const e=t.width/2,n=t.height/2;return[GX({x:-e,y:-n},t.center,t.ccwRotationRadians),GX({x:e,y:-n},t.center,t.ccwRotationRadians),GX({x:e,y:n},t.center,t.ccwRotationRadians),GX({x:-e,y:n},t.center,t.ccwRotationRadians)]})({center:i,width:p,height:m,ccwRotationRadians:g}),b=_.map(t=\u003e{const e={x:t.x-i.x,y:t.y-i.y},n=((t,e,n)=\u003e{let o;for(let i=0;i\u003cn.length;i++){const r=XX(t,e,n[i],n[(i+1)%n.length]);r\u0026\u0026(!o||r.rayT\u003co.rayT)\u0026\u0026(o=r)}return o})(i,e,o);return n?{x:n.x,y:n.y}:t});let x=BX(b)\u003eAX?b:_;let v,S;try{v=VX(y,x),S=(t=\u003e{const[e,n,o,i,r,s,a,c,l]=t,d=r*l-s*c,h=-(i*l-s*a),u=i*c-r*a,p=-(n*l-o*c),m=e*l-o*a,g=-(e*c-n*a),f=n*s-o*r,y=-(e*s-o*i),_=e*r-n*i,b=e*d+n*h+o*u;if(Math.abs(b)\u003cAX)throw new Error(\"Cannot invert singular 3x3 matrix\");const x=1/b;return[d*x,p*x,f*x,h*x,m*x,y*x,u*x,g*x,_*x]})(v)}catch{x=_,v=WX(i,g),S=WX(i,-g)}return{center:i,width:p,height:m,innerWidth:r.width,innerHeight:r.height,ccwRotationDegrees:f,ccwRotationRadians:g,polygonArea:s,equivalentAreaExpansionFactor:c,targetQuad:x,rectToPolygonMatrix:v,polygonToRectMatrix:S}},JX=class extends si{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1}params;getSolverName(){return\"AttachProjectedRectsSolver\"}outputNodes=[];projectionAdjustmentByNodeId=new Map;_step(){this.projectionAdjustmentByNodeId.clear(),this.outputNodes=this.params.nodesWithPortPoints.map(t=\u003e{const e=this.params.equivalentAreaExpansionFactor??0,n=this.params.minProjectedRectDimension??0,o=(({traceWidth:t,viaDiameter:e,obstacleMargin:n,minProjectedRectDimension:o})=\u003eMath.max(o,e??0,(t??0)+2*(n??0)))({traceWidth:this.params.traceWidth,viaDiameter:this.params.viaDiameter,obstacleMargin:this.params.obstacleMargin,minProjectedRectDimension:n});let i=qX(t.polygon,e,n);if(Math.min(i.width,i.height)\u003eo+(this.params.traceWidth??0))return{...t,center:i.center,width:i.width,height:i.height,projectedRect:i};const r=qX(t.polygon,1,n);return(({node:t,projectedRect:e,conservativeProjectedRect:n,requiredRoutingCorridorWidth:o,traceWidth:i})=\u003e{if(o\u003c=0)return!1;const r=Math.min(e.width,e.height),s=Math.min(n.width,n.height),a=Math.max(e.width,e.height),c=Math.max(n.width,n.height),l=o+(i??0),d=Math.floor(r/o),h=Math.floor(s/o);return new Set(t.portPoints.map(t=\u003et.connectionName)).size\u003e1\u0026\u0026d\u003c=h\u0026\u0026r\u003c=l\u0026\u0026a-c\u003e=o\u0026\u0026e.equivalentAreaExpansionFactor\u003e1})({node:t,projectedRect:i,conservativeProjectedRect:r,requiredRoutingCorridorWidth:o,traceWidth:this.params.traceWidth})\u0026\u0026(i=r,this.projectionAdjustmentByNodeId.set(t.capacityMeshNodeId,\"corridor-expansion-factor-1\")),{...t,center:i.center,width:i.width,height:i.height,projectedRect:i}}),this.solved=!0}getOutput(){return this.outputNodes}getConstructorParams(){return[this.params]}visualize(){const t=this.outputNodes.length\u003e0?this.outputNodes:this.params.nodesWithPortPoints;return{polygons:t.map(t=\u003e({points:t.polygon,fill:\"rgba(40, 140, 220, 0.06)\",stroke:\"rgba(20, 70, 160, 0.95)\",strokeWidth:.04,label:`${t.capacityMeshNodeId} polygon`})),lines:t.map(t=\u003e({points:[...t.polygon,t.polygon[0]],strokeColor:\"rgba(20, 70, 160, 0.95)\",strokeWidth:.04,label:`${t.capacityMeshNodeId} polygon outline`})),rects:t.flatMap(t=\u003et.projectedRect?[{center:t.projectedRect.center,width:t.projectedRect.width,height:t.projectedRect.height,ccwRotationDegrees:t.projectedRect.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.16)\",stroke:\"rgba(255, 140, 0, 0.8)\",label:`${t.capacityMeshNodeId} projectedRect`}]:[]),points:t.flatMap(t=\u003et.portPoints.map(t=\u003e({x:t.x,y:t.y,color:\"rgba(30, 30, 30, 0.85)\",label:t.connectionName})))}}},KX=class extends si{constructor(t){super(),this.params=t;const{nodeWithPortPoints:e}=t;if(!e.projectedRect)throw new Error(\"Poly node is missing projectedRect\");this.projectedPorts=e.portPoints.map(t=\u003e{const n=ZX(t,e.projectedRect);return{original:t,projected:{...t,x:n.x,y:n.y}}}),this.projectedNode={capacityMeshNodeId:e.capacityMeshNodeId,center:e.projectedRect.center,width:e.projectedRect.width,height:e.projectedRect.height,availableZ:e.availableZ,portPoints:this.projectedPorts.map(({projected:t})=\u003et)},this.highDensitySolver=new Ss({nodeWithPortPoints:this.projectedNode,colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort}),this.activeSubSolver=this.highDensitySolver,this.MAX_ITERATIONS=this.highDensitySolver.MAX_ITERATIONS+1e3}params;getSolverName(){return\"PolySingleIntraNodeSolver\"}highDensitySolver;projectedNode;solvedRoutes=[];projectedPorts;_step(){this.highDensitySolver.step(),this.progress=this.highDensitySolver.progress,this.stats=this.highDensitySolver.stats,this.highDensitySolver.solved?(this.solvedRoutes=this.highDensitySolver.solvedRoutes,this.solved=!0,this.activeSubSolver=null):this.highDensitySolver.failed\u0026\u0026(this.error=this.highDensitySolver.error,this.failed=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.params]}visualize(){const t=this.params.nodeWithPortPoints,e=t.projectedRect,n={polygons:[{points:t.polygon,fill:\"rgba(60, 160, 220, 0.10)\",stroke:\"rgba(40, 90, 150, 0.7)\",label:`${t.capacityMeshNodeId} polygon`},...e?[{points:e.targetQuad,fill:\"rgba(255, 165, 0, 0.08)\",stroke:\"rgba(255, 120, 0, 0.65)\",label:`${t.capacityMeshNodeId} distortion target`}]:[]],rects:e?[{center:e.center,width:e.width,height:e.height,ccwRotationDegrees:e.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.14)\",stroke:\"rgba(255, 120, 0, 0.8)\",label:`${t.capacityMeshNodeId} projectedRect`}]:[],points:[...t.portPoints.map(t=\u003e({x:t.x,y:t.y,color:\"rgba(0, 80, 160, 0.85)\",label:`${t.connectionName} original`})),...this.projectedPorts.map(({projected:t})=\u003e({x:t.x,y:t.y,color:\"rgba(255, 120, 0, 0.85)\",label:`${t.connectionName} projected`}))]};return pi(n,this.highDensitySolver.visualize())}},QX=class extends si{getSolverName(){return\"PolyHighDensitySolver\"}unsolvedNodePortPoints;nodePortPoints;routes=[];routesByNodeId=new Map;failedSolvers=[];activeSubSolver=null;colorMap;connMap;viaDiameter;traceWidth;obstacleMargin;effort;nodePfById;constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a}){super(),this.nodePortPoints=[...t],this.unsolvedNodePortPoints=[...t],this.colorMap=e??{},this.connMap=n,this.viaDiameter=o??.3,this.traceWidth=i??.15,this.obstacleMargin=r??.15,this.effort=s??1,this.MAX_ITERATIONS=1e7*this.effort,this.nodePfById=a instanceof Map?new Map(a):new Map(Object.entries(a??{}))}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){const t=this.activeSubSolver.params.nodeWithPortPoints.capacityMeshNodeId,e=this.activeSubSolver.solvedRoutes;this.routesByNodeId.set(t,[...this.routesByNodeId.get(t)??[],...e]),this.routes.push(...this.activeSubSolver.solvedRoutes),this.activeSubSolver=null}else this.activeSubSolver.failed\u0026\u0026(this.failedSolvers.push(this.activeSubSolver),this.activeSubSolver=null);return}if(0===this.unsolvedNodePortPoints.length)return this.failedSolvers.length\u003e0?(this.failed=!0,void(this.error=`Failed to solve ${this.failedSolvers.length} poly nodes, ${this.failedSolvers.slice(0,5).map(t=\u003et.params.nodeWithPortPoints.capacityMeshNodeId).join(\", \")}. err0: ${this.failedSolvers[0]?.error}`)):void(this.solved=!0);const t=this.unsolvedNodePortPoints.pop();this.activeSubSolver=new KX({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort})}computeProgress(){const t=this.routes.length+this.failedSolvers.length+this.unsolvedNodePortPoints.length+(this.activeSubSolver?1:0);return 0===t?1:(this.routes.length+this.failedSolvers.length+(this.activeSubSolver?.progress??0))/t}getConstructorParams(){return[{nodePortPoints:this.nodePortPoints,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById}]}visualize(){const t={polygons:this.nodePortPoints.map(t=\u003e({points:t.polygon,fill:\"rgba(180, 180, 180, 0.05)\",stroke:\"rgba(120, 120, 120, 0.25)\",label:`${t.capacityMeshNodeId} polygon`})),rects:this.nodePortPoints.flatMap(t=\u003et.projectedRect?[{center:t.projectedRect.center,width:t.projectedRect.width,height:t.projectedRect.height,ccwRotationDegrees:t.projectedRect.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.08)\",stroke:\"rgba(255, 120, 0, 0.65)\",label:`${t.capacityMeshNodeId} projectedRect`}]:[]),lines:[],circles:[],points:this.nodePortPoints.flatMap(t=\u003et.portPoints.map(t=\u003e({x:t.x,y:t.y,color:\"rgba(80, 80, 80, 0.5)\",label:`${t.connectionName} original`})))};for(const[e,n]of this.routesByNodeId){const o=this.nodePortPoints.find(t=\u003et.capacityMeshNodeId===e),i=o?.projectedRect;if(i)for(const e of n){const n=this.colorMap[e.connectionName]??\"#0000ff\",o={...e,route:e.route.map(t=\u003e({...t,...UX(t,i)})),vias:e.vias.map(t=\u003eUX(t,i))},r=mi(o.route,e.connectionName,n);for(const n of r)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:To(n.color,.5),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?[.1,.3]:void 0});for(const i of o.vias)t.circles.push({center:i,layer:\"z0,1\",radius:e.viaDiameter/2,fill:n,label:`${e.connectionName} via`})}}const e=this.activeSubSolver?.visualize();return e\u0026\u0026t.polygons.push(...this.unsolvedNodePortPoints.map(t=\u003e({points:t.polygon,fill:\"rgba(180, 180, 180, 0.08)\",stroke:\"rgba(120, 120, 120, 0.4)\",label:t.capacityMeshNodeId}))),e?pi(t,e):t}},tV=t=\u003e{const{o:e,a:n,b:o}=t;return(n.x-e.x)*(o.y-e.y)-(n.y-e.y)*(o.x-e.x)},eV=(t,e)=\u003e{const n=[...new Set(t)].map(t=\u003e{const n=e[t];return n?{i:t,x:n.x,y:n.y}:null}).filter(t=\u003enull!==t);if(n.sort((t,e)=\u003et.x-e.x||t.y-e.y),n.length\u003c=2)return n.map(t=\u003et.i);const o=[],i=[];for(const t of n){for(;o.length\u003e=2;){const e=o[o.length-2],n=o[o.length-1];if(!e||!n||tV({o:e,a:n,b:t})\u003e1e-10)break;o.pop()}o.push(t)}for(let t=n.length-1;t\u003e=0;t--){const e=n[t];if(e){for(;i.length\u003e=2;){const t=i[i.length-2],n=i[i.length-1];if(!t||!n||tV({o:t,a:n,b:e})\u003e1e-10)break;i.pop()}i.push(e)}}return o.pop(),i.pop(),o.concat(i).map(t=\u003et.i)},nV=t=\u003e{const e=Math.max(0,Math.min(30,Math.floor(t)));return 0===e?0:(1\u003c\u003ce)-1},oV=(t,e=31)=\u003e{const n=[],o=Math.max(0,Math.min(31,Math.floor(e)));for(let e=0;e\u003co;e++)t\u00261\u003c\u003ce\u0026\u0026n.push(e);return n},iV=t=\u003e{let e=0;for(const n of t)Number.isInteger(n)\u0026\u0026n\u003e=0\u0026\u0026n\u003c31\u0026\u0026(e|=1\u003c\u003cn);return e},rV=(t,e)=\u003e{const n=t.trim().toLowerCase();if(\"top\"===n)return 0;if(\"bottom\"===n)return Math.max(0,e-1);const o=n.match(/^inner(\\d+)$/);if(o?.[1]){const t=Number(o[1]);return t\u003e=0\u0026\u0026t\u003ce?t:void 0}const i=n.match(/^layer(\\d+)$/);if(i?.[1]){const t=Number(i[1])-1;return t\u003e=0\u0026\u0026t\u003ce?t:void 0}const r=n.match(/^z(\\d+)$/);if(r?.[1]){const t=Number(r[1]);return t\u003e=0\u0026\u0026t\u003ce?t:void 0}},sV=(t,e)=\u003e{const n=nV(e),o=t.zLayers;if(Array.isArray(o)\u0026\u0026o.length\u003e0)return iV(o)\u0026n;const i=t.layers;if(Array.isArray(i)\u0026\u0026i.length\u003e0){let t=0;for(const n of i){const o=rV(n,e);void 0!==o\u0026\u0026(t|=1\u003c\u003co)}return t\u0026n}return n},aV=.1,cV=.15,lV=aV+cV,dV=3*lV/4,hV=5,uV=1e-9,pV=t=\u003eMath.round(1e6*t)/1e6,mV=t=\u003e`${pV(t.x)},${pV(t.y)}`,gV=(t,e)=\u003e{const n=mV(t),o=mV(e);return n\u003co?`${n}|${o}`:`${o}|${n}`},fV=t=\u003e{let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t)e=Math.min(e,r.x),n=Math.max(n,r.x),o=Math.min(o,r.y),i=Math.max(i,r.y);return{minX:e,maxX:n,minY:o,maxY:i}},yV=(t,e)=\u003e{const n=t.x\u003ce.minX?e.minX-t.x:t.x\u003ee.maxX?t.x-e.maxX:0,o=t.y\u003ce.minY?e.minY-t.y:t.y\u003ee.maxY?t.y-e.maxY:0;return n*n+o*o},_V=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c1e-18)return!1;const s=((t.x-e.x)*o+(t.y-e.y)*i)/r;if(s\u003c-1e-9||s\u003e1+1e-9)return!1;const a=e.x+s*o,c=e.y+s*i;return(t.x-a)**2+(t.y-c)**2\u003c1e-12},bV=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003cuV)return(t.x-e.x)**2+(t.y-e.y)**2;const s=Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r)),a=e.x+s*o,c=e.y+s*i;return(t.x-a)**2+(t.y-c)**2},xV=(t,e)=\u003e({x:(t.x+e.x)/2,y:(t.y+e.y)/2}),vV=(t,e,n,o=.001)=\u003e{const i=o*o;return((t,e)=\u003e{let n=Number.POSITIVE_INFINITY;for(let o=0;o\u003ce.length;o++){const i=e[o],r=e[(o+1)%e.length];n=Math.min(n,bV(t,i,r))}return n})(xV(t,e),n)\u003c=i},SV=(t,e)=\u003e{let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];if(_V(t,r,s))return!0;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y+1e-12)+r.x\u0026\u0026(n=!n)}return n},IV=(t,e,n,o)=\u003e{const i=e.x-t.x,r=e.y-t.y,s=o.x-n.x,a=o.y-n.y,c=i*a-r*s;if(Math.abs(c)\u003cuV){for(const i of[t,e])if(_V(i,n,o))return i;for(const i of[n,o])if(_V(i,t,e))return i;return}const l=((n.x-t.x)*a-(n.y-t.y)*s)/c,d=((n.x-t.x)*r-(n.y-t.y)*i)/c;if(!(l\u003c-1e-9||l\u003e1.000000001||d\u003c-1e-9||d\u003e1.000000001))return{x:t.x+l*i,y:t.y+l*r}},CV=(t,e)=\u003e{for(const n of t)if(SV(n,e))return n;for(const n of e)if(SV(n,t))return n;for(let n=0;n\u003ct.length;n++){const o=t[n],i=t[(n+1)%t.length];for(let t=0;t\u003ce.length;t++){const n=e[t],r=e[(t+1)%e.length],s=IV(o,i,n,r);if(s)return s}}},PV=(t,e=1e-6)=\u003e[{x:t.x-e,y:t.y-e},{x:t.x+e,y:t.y-e},{x:t.x,y:t.y+e}],MV=(t,e,n,o,i)=\u003e{const r=e.x-t.x,s=e.y-t.y,a=Math.hypot(r,s);if(a\u003cuV)return[];const c=Number.isFinite(n)\u0026\u0026n\u003euV?n:lV,l=Number.isFinite(o)?Math.max(0,o):dV,d=Math.min(l,a/2),h=a-2*d;if(h\u003c=.75*c)return[{x:(t.x+e.x)/2,y:(t.y+e.y)/2,distToCentermostPortOnZ:0,cramped:!0}];const u=Math.max(1,Math.floor(h/c)+1),p=Number.isFinite(i)\u0026\u0026i\u003e0?Math.floor(i):hV,m=u\u003ep?p+Math.floor(u/4):u;if(m\u003c=1)return[{x:(t.x+e.x)/2,y:(t.y+e.y)/2,distToCentermostPortOnZ:0,cramped:!1}];const g=a/2,f=Array.from({length:m},(e,n)=\u003e{const o=d+h*n/(m-1),i=o/a;return{x:t.x+r*i,y:t.y+s*i,distanceFromStart:o}}),y=f.reduce((t,e)=\u003eMath.abs(e.distanceFromStart-g)\u003cMath.abs(t-g)?e.distanceFromStart:t,f[0].distanceFromStart);return f.map(({x:t,y:e,distanceFromStart:n})=\u003e({x:t,y:e,distToCentermostPortOnZ:Math.abs(n-y),cramped:!1}))},NV=(t,e)=\u003e{if(!(Math.hypot(e.x-t.x,e.y-t.y)\u003cuV))return{...xV(t,e),distToCentermostPortOnZ:0,cramped:!1}},wV=(t,e)=\u003e{if(\"object\"!=typeof t||null===t)return;const n=t[e];return\"string\"==typeof n?n:void 0},TV=t=\u003e{const e=new Set,n=t=\u003e{\"string\"==typeof t\u0026\u0026t.length\u003e0\u0026\u0026e.add(t)},o=t=\u003e{n(t.pointId),n(t.pcb_port_id)};n(t.connectionId),n(t.mutuallyConnectedNetworkId),o(t.start),o(t.end);const i=t.simpleRouteConnection;n(wV(i,\"name\")),n(wV(i,\"source_trace_id\")),n(wV(i,\"rootConnectionName\"));const r=\"object\"==typeof i\u0026\u0026null!==i?i.pointsToConnect:void 0;if(Array.isArray(r))for(const t of r)o(t);return e},RV=t=\u003e{const{regions:e,availableZ:n,layerCount:o,connections:i=[],obstacleRegions:r=[],regionIdPrefix:s=\"free\",portIdPrefix:a=\"shared-port\",traceWidth:c=aV,obstacleMargin:l=cV,portSpacing:d=c+l,portMarginFromSegmentEndpoint:h=3*d/4,maxDensePortsBeforeDecimation:u=hV}=t,p=Array.from({length:o},(t,e)=\u003ee),m=new Map,g=new Map,f=t=\u003et.mutuallyConnectedNetworkId??t.connectionId;for(const t of i){const e=f(t);let n=m.get(e);void 0===n\u0026\u0026(n=m.size,m.set(e,n));for(const e of TV(t))g.has(e)||g.set(e,n)}const y=e.map((t,e)=\u003e{const o=fV(t);return{regionId:`${s}-${e}`,pointIds:[],d:{polygon:t,availableZ:n?.[e]??p,center:{x:(o.minX+o.maxX)/2,y:(o.minY+o.maxY)/2},width:o.maxX-o.minX,height:o.maxY-o.minY}}}),_=y.map((t,e)=\u003e({regionId:t.regionId,serializedRegionIndex:e,polygon:t.d.polygon,availableZ:t.d.availableZ,bounds:fV(t.d.polygon),isObstacle:!1,netId:void 0})),b=r.flatMap((t,e)=\u003e{if(t.polygon.length\u003c3)return[];const n=(t=\u003e{if(Number.isInteger(t.netId)\u0026\u0026t.netId\u003e=0)return t.netId;if(\"string\"==typeof t.mutuallyConnectedNetworkId)return m.get(t.mutuallyConnectedNetworkId);for(const e of t.connectedTo??[]){const t=g.get(e);if(void 0!==t)return t}})(t);if(void 0===n)return[];const o=t.polygon,i=fV(o),r=t.availableZ??p,s=t.regionId??`obstacle-${e}`,a=y.length;y.push({regionId:s,pointIds:[],d:{...t.d??{},polygon:o,availableZ:r,center:{x:(i.minX+i.maxX)/2,y:(i.minY+i.maxY)/2},width:i.maxX-i.minX,height:i.maxY-i.minY,_containsObstacle:!0,_containsTarget:!0,netId:n}});const c={regionId:s,serializedRegionIndex:a,polygon:o,availableZ:r,bounds:i,isObstacle:!0,netId:n};return _.push(c),[c]}),x=[],v=new Map;for(let t=0;t\u003ce.length;t++){const n=e[t];for(let e=0;e\u003cn.length;e++){const o=n[e],i=n[(e+1)%n.length],r=gV(o,i),s=v.get(r)??[];s.push({regionIndex:t,a:o,b:i}),v.set(r,s)}}let S=0;const I=t=\u003e{const{region1Id:e,region2Id:n,pointIndex:o,portPoint:i,z:r,portIdSuffix:s}=t,c=`${a}-${String(S).padStart(5,\"0\")}::p${o}::z${r}${s??\"\"}`;return x.push({portId:c,region1Id:e,region2Id:n,d:{portId:c,x:i.x,y:i.y,z:r,distToCentermostPortOnZ:i.distToCentermostPortOnZ,...i.cramped?{cramped:!0}:{}}}),S+=1,c};for(const t of v.values()){if(2!==t.length)continue;const[e,o]=t,i=n?.[e.regionIndex]??p,r=n?.[o.regionIndex]??p,a=i.filter(t=\u003er.includes(t));if(0===a.length)continue;const c=MV(e.a,e.b,d,h,u);if(0!==c.length)for(let t=0;t\u003cc.length;t++){const n=c[t];for(const i of a){if(b.some(t=\u003et.availableZ.includes(i)\u0026\u0026vV(e.a,e.b,t.polygon)))continue;const r=I({region1Id:`${s}-${e.regionIndex}`,region2Id:`${s}-${o.regionIndex}`,pointIndex:t,portPoint:n,z:i});y[e.regionIndex].pointIds.push(r),y[o.regionIndex].pointIds.push(r)}}}for(const t of b)for(const e of v.values())for(const o of e){if(!vV(o.a,o.b,t.polygon))continue;const e=(n?.[o.regionIndex]??p).filter(e=\u003et.availableZ.includes(e));if(0===e.length)continue;const i=NV(o.a,o.b);if(i)for(const n of e){const e=I({region1Id:`${s}-${o.regionIndex}`,region2Id:t.regionId,pointIndex:0,portPoint:i,z:n,portIdSuffix:\"::obstacle\"});y[o.regionIndex].pointIds.push(e),y[t.serializedRegionIndex].pointIds.push(e)}}for(let t=0;t\u003cb.length;t++){const e=b[t];for(let n=t+1;n\u003cb.length;n++){const t=b[n];if(e.netId!==t.netId)continue;const o=e.availableZ.filter(e=\u003et.availableZ.includes(e));if(0===o.length)continue;const i=CV(e.polygon,t.polygon);if(i)for(const n of o){const o=I({region1Id:e.regionId,region2Id:t.regionId,pointIndex:0,portPoint:{x:i.x,y:i.y,distToCentermostPortOnZ:0},z:n,portIdSuffix:\"::obstacle-contact\"});y[e.serializedRegionIndex].pointIds.push(o),y[t.serializedRegionIndex].pointIds.push(o)}}}const C=(t,e)=\u003e{const n=((t,e)=\u003e{if(Number.isInteger(t.z)\u0026\u0026t.z\u003e=0\u0026\u0026t.z\u003ce)return[t.z];if(Array.isArray(t.zLayers)\u0026\u0026t.zLayers.length\u003e0)return t.zLayers.filter(t=\u003eNumber.isInteger(t)\u0026\u0026t\u003e=0\u0026\u0026t\u003ce);if(\"string\"==typeof t.layer){const n=rV(t.layer,e);return void 0===n?[]:[n]}return Array.isArray(t.layers)\u0026\u0026t.layers.length\u003e0?t.layers.map(t=\u003erV(t,e)).filter(t=\u003evoid 0!==t):[0]})(t,o);let i;const r=_.filter(t=\u003et.isObstacle\u0026\u0026(void 0===e||t.netId===e));for(const e of r){const o=n.find(t=\u003ee.availableZ.includes(t))??e.availableZ[0];if(void 0!==o\u0026\u0026SV(t,e.polygon))return{regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o}}for(const e of _.filter(t=\u003e!t.isObstacle)){const o=n.find(t=\u003ee.availableZ.includes(t))??e.availableZ[0];if(void 0===o)continue;if(SV(t,e.polygon))return{regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o};const r=yV(t,e.bounds);(!i||r\u003ci.distanceSq)\u0026\u0026(i={regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o,distanceSq:r})}return i},P=[];for(const t of i){const e=m.get(f(t)),n=C(t.start,e),o=C(t.end,e);if(!n||!o)throw new Error(`Could not map connection \"${t.connectionId}\" endpoint into a generated region`);const i=`terminal-start-${t.connectionId}`,r=`terminal-end-${t.connectionId}`,s=`terminal-start-port-${t.connectionId}`,a=`terminal-end-port-${t.connectionId}`;y.push({regionId:i,pointIds:[s],d:{polygon:PV(t.start),availableZ:[n.z],center:{x:t.start.x,y:t.start.y},width:1e-6,height:1e-6,_containsTarget:!0}}),y.push({regionId:r,pointIds:[a],d:{polygon:PV(t.end),availableZ:[o.z],center:{x:t.end.x,y:t.end.y},width:1e-6,height:1e-6,_containsTarget:!0}}),x.push({portId:s,region1Id:n.regionId,region2Id:i,d:{portId:s,x:t.start.x,y:t.start.y,z:n.z,distToCentermostPortOnZ:0}}),x.push({portId:a,region1Id:o.regionId,region2Id:r,d:{portId:a,x:t.end.x,y:t.end.y,z:o.z,distToCentermostPortOnZ:0}}),y[n.serializedRegionIndex].pointIds.push(s),y[o.serializedRegionIndex].pointIds.push(a),P.push({connectionId:t.connectionId,mutuallyConnectedNetworkId:t.mutuallyConnectedNetworkId,startRegionId:i,endRegionId:r,simpleRouteConnection:t.simpleRouteConnection})}return{regions:y,ports:x,connections:P}},EV=t=\u003e{const{polygon:e,clearance:n,verticesOnly:o=!1}=t,i=e.points,r=i.length;if(r\u003c3)return[];const s=new xO(i.map(t=\u003emO(t.x,t.y))).orientation()===fE.CCW,a=[];for(let t=0;t\u003cr;t++){const e=i[t],o=i[(t+1)%r],c=gO(o.x-e.x,o.y-e.y);if(0===c.length){a.push(_O(mO(e.x,e.y),gO(1,0)));continue}const l=c.normalize(),d=s?gO(l.y,-l.x):gO(-l.y,l.x),h=mO(e.x+n*d.x,e.y+n*d.y);a.push(_O(h,d))}const c=[];for(let t=0;t\u003cr;t++){const e=a[(t-1+r)%r],n=a[t],o=e.intersect(n);if(o.length\u003e0){const t=o[0];c.push({x:t.x,y:t.y})}else c.push({x:n.pt.x,y:n.pt.y})}if(o)return c;const l=[];for(let t=0;t\u003cr;t++){const e=c[t],n=c[(t+1)%r],o=fO(mO(e.x,e.y),mO(n.x,n.y)).length,i=Math.max(2,Math.ceil(o/20));for(let t=0;t\u003ci;t++){const o=t/i;l.push({x:e.x+o*(n.x-e.x),y:e.y+o*(n.y-e.y)})}}return l},AV=t=\u003e{const{localX:e,localY:n,rect:o}=t,i=Math.cos(o.ccwRotation),r=Math.sin(o.ccwRotation);return{x:o.center.x+e*i-n*r,y:o.center.y+e*r+n*i}},OV=t=\u003enew xO(t.map(t=\u003emO(t.x,t.y))),kV=t=\u003e{const e=[];for(const n of t.faces){const t=[];for(const e of n.vertices)t.push({x:e.x,y:e.y});t.length\u003e=3\u0026\u0026e.push(t)}return e},LV=(t,e,n)=\u003e{const o=e.length;e.push(...t);const i=t.length;for(let t=0;t\u003ci;t++)n.push([o+t,o+(t+1)%i])},DV=t=\u003e{const{bounds:e,vias:n,clearance:o,rects:i,polygons:r=[],viaSegments:s=8,preserveObstacleBoundaries:a=!1}=t,c=[],l=[],d=[],{minX:h,maxX:u,minY:p,maxY:m}=e,g=10,f=[];for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:h+e*(u-h),y:p})}for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:u,y:p+e*(m-p)})}for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:u-e*(u-h),y:m})}for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:h,y:m-e*(m-p)})}d.push(l.length),LV(f,c,l);const y=[];for(const t of n){const e=t.diameter/2+o,n=[];for(let o=0;o\u003cs;o++){const i=2*Math.PI*o/s;n.push({x:t.center.x+e*Math.cos(i),y:t.center.y+e*Math.sin(i)})}y.push(n)}for(const t of i){const e=t.width/2+o,n=t.height/2+o,i=[AV({localX:-e,localY:-n,rect:t}),AV({localX:e,localY:-n,rect:t}),AV({localX:e,localY:n,rect:t}),AV({localX:-e,localY:n,rect:t})];y.push(i)}for(const t of r){if(t.points.length\u003c3)continue;const e=EV({polygon:t,clearance:o,verticesOnly:!0});y.push(e)}const _=a?y:(t=\u003e{if(t.length\u003c=1)return t;try{let e=t.map(OV);for(let t=0;t\u003c2;t++){const t=[],n=new Set;for(let o=0;o\u003ce.length;o++){if(n.has(o))continue;let i=e[o];for(let t=o+1;t\u003ce.length;t++){if(n.has(t))continue;const o=i.box,r=e[t].box;if(!(o.xmin\u003er.xmax+1e-6||o.xmax\u003cr.xmin-1e-6||o.ymin\u003er.ymax+1e-6||o.ymax\u003cr.ymin-1e-6))try{const o=WA.unify(i,e[t]);o.faces.size\u003e0\u0026\u0026(i=o,n.add(t))}catch{}}t.push(i),n.add(o)}e=t}const n=[];for(const t of e){const e=kV(t);n.push(...e)}return n.length\u003e0?n:t}catch{return t}})(y);for(const t of _)d.push(l.length),LV(t,c,l);const b=((t,e,n)=\u003e{const o=new Array(e.length);for(let t=0;t\u003ce.length;t++)for(let e=n.length-1;e\u003e=0;e--)if(t\u003e=n[e]){o[t]=e;break}const i=new Map,r=t.slice();for(let t=0;t\u003ce.length;t++)for(let n=t+1;n\u003ce.length;n++){if(o[t]===o[n])continue;const[s,a]=e[t],[c,l]=e[n],d=r[s],h=r[a],u=r[c],p=r[l],m=h.x-d.x,g=h.y-d.y,f=p.x-u.x,y=p.y-u.y,_=m*y-g*f;if(Math.abs(_)\u003c1e-10)continue;const b=((u.x-d.x)*y-(u.y-d.y)*f)/_,x=((u.x-d.x)*g-(u.y-d.y)*m)/_;if(b\u003e1e-6\u0026\u0026b\u003c.999999\u0026\u0026x\u003e1e-6\u0026\u0026x\u003c.999999){const e=d.x+b*m,o=d.y+b*g,s=r.length;r.push({x:e,y:o}),i.has(t)||i.set(t,[]),i.get(t).push({t:b,idx:s}),i.has(n)||i.set(n,[]),i.get(n).push({t:x,idx:s})}}if(0===i.size)return{pts:t,constraintEdges:e,hadCrossings:!1};const s=[];for(let t=0;t\u003ce.length;t++){const n=i.get(t);if(!n||0===n.length){s.push(e[t]);continue}n.sort((t,e)=\u003et.t-e.t);const[o,r]=e[t];let a=o;for(const t of n)s.push([a,t.idx]),a=t.idx;s.push([a,r])}return{pts:r,constraintEdges:s,hadCrossings:!0}})(c,l,d);return{pts:b.pts.map((t,e)=\u003e({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)})),constraintEdges:b.constraintEdges,hadCrossings:b.hadCrossings}},zV=t=\u003e{const{p:e,a:n,b:o}=t,i=o.x-n.x,r=o.y-n.y,s=i*i+r*r;if(s\u003c1e-10)return Math.hypot(e.x-n.x,e.y-n.y);let a=((e.x-n.x)*i+(e.y-n.y)*r)/s;return a=Math.max(0,Math.min(1,a)),Math.hypot(e.x-n.x-a*i,e.y-n.y-a*r)},FV=(t,e)=\u003e{if(t.length\u003c=3)return 0;const n=eV(t,e),o=new Set(n),i=n.map(t=\u003ee[t]).filter(t=\u003eBoolean(t));let r=0;for(const n of t){if(o.has(n))continue;const t=e[n];if(!t)continue;let s=Number.POSITIVE_INFINITY;for(let e=0;e\u003ci.length;e++){const n=i[e],o=i[(e+1)%i.length];n\u0026\u0026o\u0026\u0026(s=Math.min(s,zV({p:t,a:n,b:o})))}r=Math.max(r,s)}return r},BV=(t,e)=\u003et\u003ce?1e5*t+e:1e5*e+t,jV=(t,e)=\u003e{const n=t.map((e,n)=\u003e[e,t[(n+1)%t.length]]),o=e.map((t,n)=\u003e[t,e[(n+1)%e.length]]),i=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,r]of o)void 0!==r\u0026\u0026t===r\u0026\u0026e===n\u0026\u0026i.add(BV(t,e));if(0===i.size)return null;const r=[];for(const[t,e]of n)void 0!==e\u0026\u0026(i.has(BV(t,e))||r.push([t,e]));for(const[t,e]of o)void 0!==e\u0026\u0026(i.has(BV(t,e))||r.push([t,e]));if(0===r.length)return null;const s=new Map;for(const[t,e]of r)s.set(t,e);const a=r[0]?.[0];if(void 0===a)return null;const c=[a];let l=s.get(a),d=0;for(;void 0!==l\u0026\u0026l!==a\u0026\u0026d++\u003cr.length+5;)c.push(l),l=s.get(l);return l!==a||c.length!==r.length?null:c},$V=(t,e)=\u003et\u003ce?1e5*t+e:1e5*e+t,YV=(t,e)=\u003et\u003ce?1e5*t+e:1e5*e+t,XV=c(T(),1),VV=t=\u003e{const{a:e,b:n,c:o}=t,i=2*(e.x*(n.y-o.y)+n.x*(o.y-e.y)+o.x*(e.y-n.y));if(Math.abs(i)\u003c1e-10)return{x:0,y:0,r2:1e18};const r=e.x*e.x+e.y*e.y,s=n.x*n.x+n.y*n.y,a=o.x*o.x+o.y*o.y,c=(r*(n.y-o.y)+s*(o.y-e.y)+a*(e.y-n.y))/i,l=(r*(o.x-n.x)+s*(e.x-o.x)+a*(n.x-e.x))/i;return{x:c,y:l,r2:(e.x-c)**2+(e.y-l)**2}},WV=(t,e,n)=\u003e[t.a,t.b,t.c].includes(e)\u0026\u0026[t.a,t.b,t.c].includes(n),HV=t=\u003e{const{px:e,py:n,polygonPoints:o,clearance:i}=t;if(o.length\u003c3)return!1;const r=o.map(t=\u003emO(t.x,t.y)),s=[];for(let t=0;t\u003cr.length;t++){const e=r[t],n=r[(t+1)%r.length];s.push(fO(e,n))}const a=new xO;a.addFace(s);const c=mO(e,n);if(a.contains(c))return!0;const[l]=a.distanceTo(c);return l\u003ci-.1},GV=t=\u003e{const{point:e,via:n,clearance:o}=t,i=e.x-n.center.x,r=e.y-n.center.y,s=n.diameter/2+o;return i*i+r*r\u003c=s*s+1e-9},UV=t=\u003e{const{point:e,rect:n,clearance:o}=t,i=Math.cos(-n.ccwRotation),r=Math.sin(-n.ccwRotation),s=e.x-n.center.x,a=e.y-n.center.y,c=s*i-a*r,l=s*r+a*i;return Math.abs(c)\u003c=n.width/2+o+1e-9\u0026\u0026Math.abs(l)\u003c=n.height/2+o+1e-9},ZV=t=\u003eHV({px:t.point.x,py:t.point.y,polygonPoints:t.polygon.points,clearance:t.clearance}),qV=(t,e)=\u003et.x\u003e=e.minX-1e-9\u0026\u0026t.x\u003c=e.maxX+1e-9\u0026\u0026t.y\u003e=e.minY-1e-9\u0026\u0026t.y\u003c=e.maxY+1e-9,JV=t=\u003e{const{point:e,vias:n,rects:o,polygons:i,clearance:r,layerCount:s}=t;let a=0;for(const t of n)GV({point:e,via:t,clearance:r})\u0026\u0026(a|=sV(t,s));for(const t of o)UV({point:e,rect:t,clearance:r})\u0026\u0026(a|=sV(t,s));for(const t of i)ZV({point:e,polygon:t,clearance:r})\u0026\u0026(a|=sV(t,s));return a},KV=t=\u003e{const{triangles:e,pts:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a,layerCount:c}=t,l=nV(c),d=[],h=[];for(const[t,u,p]of e){const e=n[t],m=n[u],g=n[p];if(!e||!m||!g)continue;const f={x:(e.x+m.x+g.x)/3,y:(e.y+m.y+g.y)/3};if(!qV(f,o))continue;const y=l\u0026~JV({point:f,vias:i,rects:s,polygons:a,clearance:r,layerCount:c});0!==y\u0026\u0026(d.push([t,u,p]),h.push(oV(y,c)))}return{triangles:d,triangleAvailableZ:h}},QV=t=\u003e{const{triangles:e,pts:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a}=t;return e.filter(([t,e,c])=\u003e{const l=n[t],d=n[e],h=n[c];if(!l||!d||!h)return!1;if(!(t=\u003e{const{px:e,py:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a}=t,{minX:c,maxX:l,minY:d,maxY:h}=o,u=1e-6*Math.max(l-c,h-d,1);if(e\u003cc-u||e\u003el+u||n\u003cd-u||n\u003eh+u)return!1;for(const t of i){const o=t.diameter/2+r,i=Math.max(0,o-u);if((e-t.center.x)**2+(n-t.center.y)**2\u003ci*i)return!1}for(const t of s){const o=t.width/2+r,i=t.height/2+r,s=Math.max(0,o-u),a=Math.max(0,i-u),c=e-t.center.x,l=n-t.center.y,d=Math.cos(t.ccwRotation),h=Math.sin(t.ccwRotation),p=c*d+l*h,m=-c*h+l*d;if(Math.abs(p)\u003cs\u0026\u0026Math.abs(m)\u003ca)return!1}for(const t of a)if(HV({px:e,py:n,polygonPoints:t.points,clearance:r}))return!1;return!0})({px:(l.x+d.x+h.x)/3,py:(l.y+d.y+h.y)/3,bounds:o,vias:i,clearance:r,rects:s,polygons:a}))return!1;if(a.length\u003e0){const t=[l,d,h,{x:(l.x+d.x)/2,y:(l.y+d.y)/2},{x:(d.x+h.x)/2,y:(d.y+h.y)/2},{x:(h.x+l.x)/2,y:(h.y+l.y)/2}];for(const e of t)for(const t of a)if(HV({px:e.x,py:e.y,polygonPoints:t.points,clearance:r}))return!1}return!0})},tW=t=\u003evoid 0!==t,eW=t=\u003e{const{bounds:e,clearance:n,concavityTolerance:o}=t,i=t.vias??[],r=t.rects??[],s=t.polygons??[];let a,c,l;if(!1!==t.useConstrainedDelaunay){const o=DV({bounds:e,vias:i,clearance:n,rects:r,polygons:s,viaSegments:t.viaSegments,preserveObstacleBoundaries:void 0!==t.layerCount});a=o.pts;const d=((t,e,n={})=\u003e{const o=t.map(t=\u003e[t.x,t.y]);return(0,XV.default)(o,e,{exterior:!!n.includeConstraintInteriors})})(a,o.constraintEdges,{includeConstraintInteriors:void 0!==t.layerCount});if(void 0!==t.layerCount){const o=KV({triangles:d,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s,layerCount:t.layerCount});c=o.triangles,l=o.triangleAvailableZ}else{c=i.length\u003e0||r.length\u003e0||s.length\u003e0?QV({triangles:d,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s}):d}}else{a=(t=\u003e{const{bounds:e,vias:n,clearance:o,rects:i,polygons:r=[],viaSegments:s=24}=t,a=[],{minX:c,maxX:l,minY:d,maxY:h}=e;a.push({x:c,y:d},{x:l,y:d},{x:l,y:h},{x:c,y:h});for(let t=1;t\u003c10;t++){const e=t/10;a.push({x:c+e*(l-c),y:d}),a.push({x:l,y:d+e*(h-d)}),a.push({x:l-e*(l-c),y:h}),a.push({x:c,y:h-e*(h-d)})}for(const t of n){const e=t.diameter/2+o;for(let n=0;n\u003cs;n++){const o=2*Math.PI*n/s;a.push({x:t.center.x+e*Math.cos(o),y:t.center.y+e*Math.sin(o)})}}for(const t of i){const e=t.width/2+o,n=t.height/2+o,i=Math.max(2,Math.ceil(Math.max(2*e,2*n)/20));for(let o=0;o\u003ci;o++){const r=o/i;a.push(AV({localX:2*r*e-e,localY:-n,rect:t})),a.push(AV({localX:e,localY:2*r*n-n,rect:t})),a.push(AV({localX:e-2*r*e,localY:n,rect:t})),a.push(AV({localX:-e,localY:n-2*r*n,rect:t}))}}for(const t of r){if(t.points.length\u003c3)continue;const e=EV({polygon:t,clearance:o});a.push(...e)}return a.map((t,e)=\u003e({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))})({bounds:e,vias:i,clearance:n,rects:r,polygons:s,viaSegments:t.viaSegments});const o=(t=\u003e{const e=t.map((t,e)=\u003e({...t,i:e}));if(e.length\u003c3)return[];let n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),o=Math.min(o,t.y),i=Math.max(i,t.x),r=Math.max(r,t.y);const s=Math.max(i-n,r-o)||1,a=(n+i)/2,c=(o+r)/2,l={x:a-30*s,y:c-s,i:-1},d={x:a,y:c+30*s,i:-2},h={x:a+30*s,y:c-s,i:-3};let u=[{a:l,b:d,c:h,cc:VV({a:l,b:d,c:h})}];for(const t of e){const e=u.filter(e=\u003e{const n=t.x-e.cc.x,o=t.y-e.cc.y;return n*n+o*o\u003ce.cc.r2+1e-6}),n=new Set(e),o=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[i,r]of n){let n=!1;for(const o of e)if(o!==t\u0026\u0026WV(o,i,r)){n=!0;break}n||o.push([i,r])}}u=u.filter(t=\u003e!n.has(t));for(const[e,n]of o)u.push({a:e,b:n,c:t,cc:VV({a:e,b:n,c:t})})}return u.filter(t=\u003et.a.i\u003e=0\u0026\u0026t.b.i\u003e=0\u0026\u0026t.c.i\u003e=0).map(t=\u003e[t.a.i,t.b.i,t.c.i])})(a);if(void 0!==t.layerCount){const d=KV({triangles:o,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s,layerCount:t.layerCount});c=d.triangles,l=d.triangleAvailableZ}else c=QV({triangles:o,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s})}const{cells:d,depths:h,availableZ:u}=!1!==t.usePolyanyaMerge?(t=\u003e{const{triangles:e,pts:n,cellAvailableZ:o,layerMergeMode:i=\"same\"}=t;if(!e.length)return{cells:[],depths:[]};const r=e.length,s=e.map(([t,e,o])=\u003e{const i=n[t],r=n[e],s=n[o];return i\u0026\u0026r\u0026\u0026s\u0026\u0026tV({o:i,a:r,b:s})\u003c0?[t,o,e]:[t,e,o]}),a=o?.map(iV),c=new Array(r).fill(null);for(let t=0;t\u003cr;t++)c[t]=new Map;function l(){for(let t=0;t\u003cc.length;t++)c[t]\u0026\u0026c[t].clear();const t=new Map;for(let e=0;e\u003cs.length;e++){const n=s[e];if(n)for(let o=0;o\u003cn.length;o++){const i=n[o],r=n[(o+1)%n.length],s=YV(i,r),a=t.get(s);a?(c[e].set(o,{neighbor:a.cellIdx,neighborEdge:a.edgePos}),c[a.cellIdx].set(a.edgePos,{neighbor:e,neighborEdge:o})):t.set(s,{cellIdx:e,edgePos:o})}}}function d(t){let e=0;for(let o=0;o\u003ct.length;o++){const i=n[t[o]],r=n[t[(o+1)%t.length]];e+=i.x*r.y-r.x*i.y}return Math.abs(e)/2}function h(t,e){const n=s[t],o=c[t],i=n.length;let r=-1;for(const[t,n]of o)if(n.neighbor===e){r=t;break}if(-1===r)return null;let a=r;for(;;){const t=(a-1+i)%i;if(t===r)break;const n=o.get(t);if(!n||n.neighbor!==e)break;a=t}let l=r;for(;;){const t=(l+1)%i;if(t===a)break;const n=o.get(t);if(!n||n.neighbor!==e)break;l=t}return{firstK:a,lastK:l,sharedCount:(l-a+i)%i+1}}function u(t,e){const o=s[t],r=s[e],c=h(t,e);if(!c)return!1;const{firstK:l,lastK:d,sharedCount:u}=c,p=o.length,m=r.length,g=o[l],f=o[(d+1)%p];let y=-1;for(let t=0;t\u003cm;t++)if(r[t]===g){y=t;break}if(-1===y)return!1;const _=(y-u+m)%m;if(r[_]!==f)return!1;const b=n[o[(l-1+p)%p]],x=n[g],v=n[r[(y+1)%m]];if(tV({o:b,a:x,b:v})\u003c-1e-8)return!1;const S=n[r[(_-1+m)%m]],I=n[f],C=n[o[(d+2)%p]];if(tV({o:S,a:I,b:C})\u003c-1e-8)return!1;if(a){if(0===(a[t]\u0026a[e]))return!1;if(\"same\"===i\u0026\u0026a[t]!==a[e])return!1}return!0}function p(t,e){const n=s[t],o=s[e],i=h(t,e),{firstK:r,lastK:c,sharedCount:l}=i,d=n.length,u=o.length,p=n[r],m=n[(c+1)%d];let g=-1;for(let t=0;t\u003cu;t++)if(o[t]===p){g=t;break}const f=[];f.push(p);const y=u-l-1;for(let t=1;t\u003c=y;t++)f.push(o[(g+t)%u]);f.push(m);const _=d-l-1;for(let t=2;t\u003c=_+1;t++)f.push(n[(c+t)%d]);s[t]=f,s[e]=null,a\u0026\u0026(a[t]=a[t]\u0026a[e],a[e]=0)}l();let m=!0;for(;m;){m=!1,l();for(let t=0;t\u003cs.length;t++){if(!s[t])continue;const e=c[t],n=new Set;for(const[,t]of e)s[t.neighbor]\u0026\u0026n.add(t.neighbor);if(1===n.size){const e=n.values().next().value;u(t,e)\u0026\u0026(p(t,e),m=!0)}}}l();const g=new Array(s.length).fill(0);for(let t=0;t\u003cs.length;t++)s[t]\u0026\u0026(g[t]=d(s[t]));const f=[];function y(t){f.push(t);let e=f.length-1;for(;e\u003e0;){const t=e-1\u003e\u003e1;if(f[t].area\u003e=f[e].area)break;const n=f[t];f[t]=f[e],f[e]=n,e=t}}function _(){if(0===f.length)return;const t=f[0],e=f.pop();if(f.length\u003e0){f[0]=e;let t=0;for(;;){let e=t;const n=2*t+1,o=2*t+2;if(n\u003cf.length\u0026\u0026f[n].area\u003ef[e].area\u0026\u0026(e=n),o\u003cf.length\u0026\u0026f[o].area\u003ef[e].area\u0026\u0026(e=o),e===t)break;const i=f[t];f[t]=f[e],f[e]=i,t=e}}return t}const b=new Set;for(let t=0;t\u003cs.length;t++){if(!s[t])continue;const e=c[t],n=new Set;for(const[,t]of e)s[t.neighbor]\u0026\u0026n.add(t.neighbor);for(const e of n){const n=t\u003ce?1e5*t+e:1e5*e+t;b.has(n)||(b.add(n),u(t,e)\u0026\u0026y({area:g[t]+g[e],xIdx:t,yIdx:e}))}}for(;f.length\u003e0;){const t=_(),{xIdx:e,yIdx:n}=t;if(!s[e]||!s[n])continue;const o=g[e]+g[n];if(Math.abs(o-t.area)\u003e1e-10){u(e,n)\u0026\u0026y({area:o,xIdx:e,yIdx:n});continue}if(!u(e,n))continue;p(e,n),g[e]=d(s[e]),l();const i=c[e],r=new Set;for(const[,t]of i)s[t.neighbor]\u0026\u0026r.add(t.neighbor);for(const t of r)u(e,t)\u0026\u0026y({area:g[e]+g[t],xIdx:e,yIdx:t})}const x=s.filter(t=\u003enull!==t),v=a?s.flatMap((t,e)=\u003enull===t?[]:[oV(a[e])]):void 0,S=x.map(()=\u003e0);return{cells:x,depths:S,...v?{availableZ:v}:{}}})({triangles:c,pts:a,cellAvailableZ:l,layerMergeMode:t.layerMergeMode}):(t=\u003e{const{triangles:e,pts:n,concavityTolerance:o,cellAvailableZ:i,layerMergeMode:r=\"same\"}=t;if(!e.length)return{cells:[],depths:[]};const s=e.map(([t,e,o])=\u003e{const i=n[t],r=n[e],s=n[o];return i\u0026\u0026r\u0026\u0026s\u0026\u0026tV({o:i,a:r,b:s})\u003c0?[t,o,e]:[t,e,o]}),a=i?.map(iV),c=(t,e)=\u003e{if(!a)return;const n=a[t]\u0026a[e];return 0===n||\"same\"===r\u0026\u0026a[t]!==a[e]?0:n};let l=!0,d=0;for(;l\u0026\u0026d++\u003c800;){l=!1;const t=new Map,e=s.map(()=\u003enew Set);for(let n=0;n\u003cs.length;n++){const o=s[n];if(o)for(let i=0;i\u003co.length;i++){const r=o[i],s=o[(i+1)%o.length];if(void 0===r||void 0===s)continue;const a=$V(r,s);if(t.has(a)){const o=t.get(a);void 0!==o\u0026\u0026(e[n]?.add(o),e[o]?.add(n))}else t.set(a,n)}}let i=-1,r=-1,d=null,h=Number.POSITIVE_INFINITY;for(let t=0;t\u003cs.length;t++){const a=e[t];if(a)for(const e of a){if(e\u003c=t)continue;const a=jV(s[t]??[],s[e]??[]);if(!a)continue;if(0===c(t,e))continue;const l=FV(a,n);l\u003c=o+1e-6\u0026\u0026l\u003ch\u0026\u0026(h=l,i=t,r=e,d=a)}}if(i\u003c0||r\u003c0||!d)break;s[i]=d,a\u0026\u0026(a[i]=c(i,r),a.splice(r,1)),s.splice(r,1),l=!0}const h=s.map(t=\u003eFV(t,n));return{cells:s,depths:h,...a?{availableZ:a.map(t=\u003eoV(t))}:{}}})({triangles:c,pts:a,concavityTolerance:o,cellAvailableZ:l,layerMergeMode:t.layerMergeMode}),p=a.map(t=\u003e((t,e)=\u003e({x:Math.min(e.maxX,Math.max(e.minX,t.x)),y:Math.min(e.maxY,Math.max(e.minY,t.y))}))(t,e)),m=d.map(t=\u003et.map(t=\u003ep[t]).filter(tW)),g=d.map(t=\u003eeV(t,p).map(t=\u003ep[t]).filter(tW));return{pts:p,validTris:c,regions:m,hulls:g,depths:h,...u?{availableZ:u}:{}}},nW=t=\u003e{const e=[...new Set(t.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0))].sort((t,e)=\u003et-e);if(0!==e.length)return`z${e.join(\",\")}`},oW=t=\u003e{const e=[];for(let n=0;n\u003c31;n++)t\u00261\u003c\u003cn\u0026\u0026e.push(n);return e},iW=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,rW=t=\u003eiW(t)?{...t}:void 0===t?{}:{value:t},sW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];if(iW(n)){if(\"string\"==typeof n.serializedRegionId)return n.serializedRegionId;if(\"string\"==typeof n.regionId)return n.regionId;if(\"string\"==typeof n.capacityMeshNodeId)return n.capacityMeshNodeId}return`region-${e}`},aW=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];if(iW(n)){if(\"string\"==typeof n.serializedPortId)return n.serializedPortId;if(\"string\"==typeof n.portId)return(o=n.portId).includes(\"::\")?o.slice(0,o.indexOf(\"::\")):o}var o;return`port-${e}`},cW=(t,e)=\u003e{const n=rW(t.topology.regionMetadata?.[e]);if(iW(n.center)||(n.center={x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),\"number\"!=typeof n.width\u0026\u0026(n.width=t.topology.regionWidth[e]),\"number\"!=typeof n.height\u0026\u0026(n.height=t.topology.regionHeight[e]),!Array.isArray(n.availableZ)){const o=t.topology.regionAvailableZMask?.[e]??0;0!==o\u0026\u0026(n.availableZ=oW(o))}return n.layer=nW(Array.isArray(n.availableZ)?n.availableZ:[])??nW((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))??\"z0\",n},lW=(t,e)=\u003e{const n=rW(t.topology.portMetadata?.[e]);return\"number\"!=typeof n.x\u0026\u0026(n.x=t.topology.portX[e]),\"number\"!=typeof n.y\u0026\u0026(n.y=t.topology.portY[e]),\"number\"!=typeof n.z\u0026\u0026(n.z=t.topology.portZ[e]),n.layer=nW([t.topology.portZ[e]])??\"z0\",n},dW=(t,e,n)=\u003e{const o=(t.topology.incidentPortRegion[e]??[]).find(t=\u003et!==n);if(void 0===o)throw new Error(`Port ${e} is not incident to a region outside route region ${n}`);return o},hW=(t,e,n)=\u003e{const{orderedPortIds:o,orderedRegionIds:i}=((t,e,n)=\u003e{if(0===n.length)throw new Error(`Route ${e} has no solved segments`);const o=t.problem.routeStartPort[e],i=t.problem.routeEndPort[e],r=new Map;n.forEach((t,e)=\u003e{const n={...t,segmentIndex:e},o=r.get(t.fromPortId)??[];o.push(n),r.set(t.fromPortId,o);const i=r.get(t.toPortId)??[];i.push(n),r.set(t.toPortId,i)});const s=[o],a=[],c=new Set;let l,d=o;for(;d!==i;){const t=(r.get(d)??[]).filter(t=\u003e!c.has(t.segmentIndex)\u0026\u0026(t.fromPortId===d?t.toPortId:t.fromPortId)!==l);if(1!==t.length)throw new Error(`Route ${e} is not a single ordered path from ${o} to ${i}`);const n=t[0],h=n.fromPortId===d?n.toPortId:n.fromPortId;c.add(n.segmentIndex),a.push(n.regionId),s.push(h),l=d,d=h}if(c.size!==n.length)throw new Error(`Route ${e} contains disconnected solved segments`);return{orderedPortIds:s,orderedRegionIds:a}})(t,e,n),r=i[0],s=i[i.length-1];if(void 0===r||void 0===s)throw new Error(`Route ${e} could not determine endpoint regions`);const a=sW(t,dW(t,o[0],r)),c=sW(t,dW(t,o[o.length-1],s)),l=((t,e,n,o)=\u003e{const i=t.problem.routeMetadata?.[e];return{connectionId:(iW(i)\u0026\u0026\"string\"==typeof i.connectionId?i.connectionId:void 0)??`route-${e}`,startRegionId:(iW(i)\u0026\u0026\"string\"==typeof i.startRegionId?i.startRegionId:void 0)??n,endRegionId:(iW(i)\u0026\u0026\"string\"==typeof i.endRegionId?i.endRegionId:void 0)??o,mutuallyConnectedNetworkId:(iW(i)\u0026\u0026\"string\"==typeof i.mutuallyConnectedNetworkId?i.mutuallyConnectedNetworkId:void 0)??`net-${t.problem.routeNet[e]}`}})(t,e,a,c),d=o.map((e,n)=\u003e{const r={portId:aW(t,e),g:n,h:0,f:n,hops:n,ripRequired:!1,nextRegionId:n\u003ci.length?sW(t,i[n]):l.endRegionId};return n\u003e0\u0026\u0026(r.lastPortId=aW(t,o[n-1]),r.lastRegionId=sW(t,i[n-1])),r});return{connection:l,solvedRoute:{connection:l,path:d,requiredRip:!1}}},uW=t=\u003e{if(!t.solved||t.failed)throw new Error(\"convertToSerializedHyperGraph requires a solved, non-failed solver\");const{topology:e}=t,n=(t=\u003e{const e=Array.from({length:t.problem.routeCount},()=\u003e[]);return t.state.regionSegments.forEach((t,n)=\u003e{for(const[o,i,r]of t)e[o].push({regionId:n,fromPortId:i,toPortId:r})}),e})(t),o=Array.from({length:e.regionCount},(n,o)=\u003e({regionId:sW(t,o),pointIds:e.regionIncidentPorts[o].map(e=\u003eaW(t,e)),d:cW(t,o)})),i=Array.from({length:e.portCount},(n,o)=\u003e{const[i,r]=e.incidentPortRegion[o]??[];if(void 0===i||void 0===r)throw new Error(`Port ${o} is missing incident regions`);return{portId:aW(t,o),region1Id:sW(t,i),region2Id:sW(t,r),d:lW(t,o)}}),r=n.map((e,n)=\u003ehW(t,n,e));return{regions:o,ports:i,connections:r.map(({connection:t})=\u003et),solvedRoutes:r.map(({solvedRoute:t})=\u003et)}},pW=t=\u003et\u003e0\u0026\u0026!(t\u0026t-1),mW=(t,e,n,o,i,r=0)=\u003e.2025*(2*e+1*n+1*o)*(1+i/5)/t+(pW(r)?10*e:0),gW=(t,e,n,o,i,r)=\u003e{const{netIds:s,lesserAngles:a,greaterAngles:c,layerMasks:l}=t;let d=0,h=0;for(let t=0;t\u003cs.length;t++){if(e===s[t])continue;(n\u003ca[t]\u0026\u0026a[t]\u003co)!==(n\u003cc[t]\u0026\u0026c[t]\u003co)\u0026\u0026(0!==(i\u0026l[t])?d++:h++)}return[d,h,r]},fW=class{constructor(t,e){this.items=t,this.compare=e}items;compare;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0}queue(t){this.items.push(t),this.siftUp(this.items.length-1)}dequeue(){const t=this.items[0];if(void 0===t)return;const e=this.items.pop();return this.items.length\u003e0\u0026\u0026(this.items[0]=e,this.siftDown(0)),t}siftUp(t){let e=t;for(;e\u003e0;){const t=e-1\u003e\u003e1,n=this.items[t],o=this.items[e];if(this.compare(n,o)\u003c=0)return;this.items[t]=o,this.items[e]=n,e=t}}siftDown(t){let e=t;const n=this.items.length;for(;;){const t=2*e+1;if(t\u003e=n)return;const o=t+1;let i=t;o\u003cn\u0026\u0026this.compare(this.items[o],this.items[t])\u003c0\u0026\u0026(i=o);const r=this.items[e],s=this.items[i];if(this.compare(r,s)\u003c=0)return;this.items[e]=s,this.items[i]=r,e=i}}},yW=(t,e)=\u003e{const n=[...t],o=(t=\u003e{let e=t\u003e\u003e\u003e0;return()=\u003e{e+=1831565813;let t=e;return t=Math.imul(t^t\u003e\u003e\u003e15,1|t),t^=t+Math.imul(t^t\u003e\u003e\u003e7,61|t),((t^t\u003e\u003e\u003e14)\u003e\u003e\u003e0)/4294967296}})(e);for(let t=n.length-1;t\u003e0;t--){const e=Math.floor(o()*(t+1));[n[t],n[e]]=[n[e],n[t]]}return n},_W=(t,e)=\u003et.routeMetadata?.[e],bW=t=\u003et?.simpleRouteConnection?.pointsToConnect?.map(({pointId:t})=\u003e\"string\"==typeof t?t:null).filter(t=\u003enull!==t)??[],xW=(t,e)=\u003e{const n=_W(t,e)?.connectionId;return\"string\"==typeof n?n:`route-${e}`},vW=(t,e,n)=\u003e{const o=t.portEndpointNetIds[n];if(!o)return!1;for(const t of o)if(t!==e)return!0;return!1},SW=(t,e,n)=\u003e{const o=t.regionNetId[n];return-1!==o\u0026\u0026o!==e},IW=t=\u003e[...new Set(t.routeIds)].filter(e=\u003e!((t,e)=\u003e{const{topology:n,problem:o,problemSetup:i,portAssignment:r,maxPrecheckHops:s}=t,a=o.routeNet[e],c=o.routeStartPort[e],l=o.routeEndPort[e];if(c===l)return!0;const d=t.getStartingNextRegionId(e,c);if(void 0===d)return!1;const h=[{portId:c,nextRegionId:d}],u=new Set([c*n.regionCount+d]);for(let t=0;t\u003ch.length;t++){const e=h[t];if(!SW(o,a,e.nextRegionId))for(const t of n.regionIncidentPorts[e.nextRegionId]??[]){const c=r[t];if(vW(i,a,t))continue;if(t===l){if(-1!==c\u0026\u0026c!==a)continue;return!0}if(t===e.portId)continue;if(-1!==c\u0026\u0026c!==a)continue;if(0===o.portSectionMask[t])continue;const d=n.incidentPortRegion[t]??[],p=d[0]===e.nextRegionId?d[1]:d[0];if(void 0===p||SW(o,a,p))continue;const m=t*n.regionCount+p;if(!u.has(m)){if(u.size\u003e=s)return!0;u.add(m),h.push({portId:t,nextRegionId:p})}}}return!1})(t,e)).map(e=\u003et.getRouteSummary(e)),CW=t=\u003e{const e=new Array(t);for(let n=0;n\u003ct;n++)e[n]=n;return e},PW=.05,MW={r:255,g:64,b:64,a:.72},NW=\"rgba(220, 38, 38, 0.98)\",wW=\"rgba(220, 38, 38, 0.12)\",TW=\"10 6\",RW=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),EW=t=\u003eMath.min(1,Math.max(0,t)),AW=(t,e,n)=\u003eMath.round(t+(e-t)*n),OW=({r:t,g:e,b:n,a:o})=\u003e`rgba(${t}, ${e}, ${n}, ${o})`,kW=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},LW=t=\u003e\"number\"==typeof t.centerRouteId,DW=(t,e)=\u003eLW(t)?e===t.centerRouteId?1:.5:1,zW=(t,e)=\u003e{const n=t.match(/^(rgba|hsla)\\((.*),\\s*([0-9]*\\.?[0-9]+)\\)$/);if(!n)return t;const[,o,i,r]=n,s=EW(Number(r)*e);return`${o}(${i}, ${Number(s.toFixed(3))})`},FW=(t,e,n=.8)=\u003e((t,e,n=.8)=\u003e{const o=`${t.problem.routeNet[e]}:${kW(t,e)}`;let i=0;for(let t=0;t\u003co.length;t++)i=17777*o.charCodeAt(t)+((i\u003c\u003c5)-i);return`hsla(${Math.abs(i)%360}, 70%, 50%, ${n})`})(t,e,n*DW(t,e)),BW=(t,e)=\u003e`net: ${t.problem.routeNet[e]}`,jW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=n?.polygon;if(Array.isArray(o)\u0026\u0026o.length\u003e=3){const t=o.map(t=\u003et.x),e=o.map(t=\u003et.y);return{minX:Math.min(...t),maxX:Math.max(...t),minY:Math.min(...e),maxY:Math.max(...e)}}const i=n?.bounds;if(i\u0026\u0026\"number\"==typeof i.minX\u0026\u0026\"number\"==typeof i.maxX\u0026\u0026\"number\"==typeof i.minY\u0026\u0026\"number\"==typeof i.maxY)return i;const r=t.topology.regionWidth[e],s=t.topology.regionHeight[e],a=t.topology.regionCenterX[e],c=t.topology.regionCenterY[e];return{minX:a-r/2,maxX:a+r/2,minY:c-s/2,maxY:c+s/2}},$W=(t,e)=\u003e({x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),YW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=Array.isArray(n?.availableZ)?n.availableZ.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0):[];if(o.length\u003e0)return nW(o)??\"z0\";const i=oW(t.topology.regionAvailableZMask?.[e]??0);if(i.length\u003e0)return nW(i)??\"z0\";const r=[...new Set((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))].sort((t,e)=\u003et-e);return nW(r)??\"z0\"},XW=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e],o=n?.existingRegionCost??0,i=t.state.regionCongestionCost[e]??0,r=t.problem.regionNetId[e];return RW(`region: region-${e}`,`net: ${-1===r?\"free\":`${r}`}`,t.getAdditionalRegionLabel(e),`cost: ${o.toFixed(3)}`,`congestion: ${i.toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},VW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];return n?.isConnectionRegion?{r:255,g:100,b:255,a:.6}:n?.isThroughJumper?{r:100,g:200,b:100,a:.5}:n?.isPad?{r:255,g:200,b:100,a:.5}:\"bottom\"===n?.layer?{r:52,g:152,b:219,a:.08}:{r:200,g:200,b:255,a:.1}},WW=(t,e)=\u003e{const n=VW(t,e),o=EW(t.state.regionIntersectionCaches[e]?.existingRegionCost??0),i=Math.pow(o,.8);return OW((s=MW,a=i,{r:AW((r=n).r,s.r,a),g:AW(r.g,s.g,a),b:AW(r.b,s.b,a),a:Number((r.a+(s.a-r.a)*a).toFixed(3))}));var r,s,a},HW=(t,e)=\u003e({x:t.topology.portX[e],y:t.topology.portY[e]}),GW=HW,UW=HW,ZW=(t,e)=\u003enW([t.topology.portZ[e]])??\"z0\",qW=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},JW=(t,e,n)=\u003e{if(void 0!==n)return`net: ${t.problem.routeNet[n]}`;const o=t.state.portAssignment[e];if(o\u003e=0)return`net: ${o}`;const i=new Set;for(let n=0;n\u003ct.problem.routeCount;n++)t.problem.routeStartPort[n]!==e\u0026\u0026t.problem.routeEndPort[n]!==e||i.add(t.problem.routeNet[n]);return 0!==i.size?`net: ${Array.from(i).sort((t,e)=\u003et-e).join(\", \")}`:void 0},KW=(t,e)=\u003e`z: ${t.topology.portZ[e]}`,QW=(t,e,n)=\u003eRW(qW(t,e),((t,e)=\u003e{const n=t.topology.incidentPortRegion[e]?.[0],o=t.topology.incidentPortRegion[e]?.[1];return`connects: region-${n??\"?\"} \u003c-\u003e region-${o??\"?\"}`})(t,e),JW(t,e,n)),tH=(t,e,n,o)=\u003e{const i=t.topology.portZ[n],r=t.topology.portZ[o];return i\u003e0\u0026\u0026r\u003e0?{strokeColor:zW(\"rgba(52, 152, 219, 0.95)\",DW(t,e)),strokeDash:\"3 2\"}:i!==r?{strokeColor:zW(\"rgba(22, 160, 133, 0.95)\",DW(t,e)),strokeDash:\"2 4 2\"}:{strokeColor:FW(t,e)}},eH=(t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++)if(t.problem.routeStartPort[n]===e||t.problem.routeEndPort[n]===e)return!0;return!1},nH=(t,e,n)=\u003e{const o=((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ce.length;o++)if(1===e[o])for(const e of t.topology.incidentPortRegion[o]??[])n.add(e);return n})(t,n),i=\"rgba(245, 158, 11, 0.95)\",r=\"rgba(245, 158, 11, 0.08)\";for(const n of o){const o=t.topology.regionMetadata?.[n],s=o?.polygon,a=jW(t,n),c=$W(t,n),l=a.maxX-a.minX,d=a.maxY-a.minY,h=YW(t,n),u=RW(\"section region\",XW(t,n));Array.isArray(s)\u0026\u0026s.length\u003e=3?e.polygons.push({points:s,fill:r,stroke:i,strokeWidth:2,layer:h,label:u}):e.rects.push({center:c,width:Math.max(l-PW,.05),height:Math.max(d-PW,.05),fill:r,stroke:i,layer:h,label:u})}for(let o=0;o\u003cn.length;o++)1===n[o]\u0026\u0026e.circles.push({center:UW(t,o),radius:.07,fill:\"rgba(251, 191, 36, 0.18)\",stroke:i,layer:ZW(t,o),label:RW(QW(t,o),KW(t,o),\"section port\")})},oH=(t,e={})=\u003e{const n={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:\"Tiny HyperGraph\",coordinateSystem:\"cartesian\"},o=((t,e)=\u003e{if(!e?.highlightSectionMask)return;const n=e.sectionPortMask??t.problem.portSectionMask;if(n.length!==t.topology.portCount)return;let o=0,i=0;for(let t=0;t\u003cn.length;t++)1===n[t]?o+=1:i+=1;return 0!==o\u0026\u00260!==i?n:void 0})(t,e);for(let e=0;e\u003ct.topology.regionCount;e++){const o=t.topology.regionMetadata?.[e],i=o?.polygon,r=jW(t,e),s=$W(t,e),a=r.maxX-r.minX,c=r.maxY-r.minY,l=YW(t,e),d=OW(VW(t,e));Array.isArray(i)\u0026\u0026i.length\u003e=3?n.polygons.push({points:i,fill:d,layer:l}):n.rects.push({center:s,width:Math.max(a-PW,.05),height:Math.max(c-PW,.05),fill:WW(t,e),layer:l,label:XW(t,e)})}if(((t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a=FW(t,n),c=kW(t,n),l=BW(t,n);e.points.push({x:r.x,y:r.y,color:a,layer:ZW(t,o),label:RW(`route: ${c}`,l,\"endpoint: start\",qW(t,o),KW(t,o))}),e.points.push({x:s.x,y:s.y,color:a,layer:ZW(t,i),label:RW(`route: ${c}`,l,\"endpoint: end\",qW(t,i),KW(t,i))})}})(t,n),0===t.iterations){for(const t of n.polygons)t.stroke=\"rgba(128, 128, 128, 0.5)\";for(const t of n.rects)t.stroke=\"rgba(128, 128, 128, 0.5)\"}if(0===t.iterations){for(let i=0;i\u003ct.topology.portCount;i++){const r=1===o?.[i];e.showOnlySectionPortsOnIdle\u0026\u0026!r||n.circles.push({center:UW(t,i),radius:.05,fill:t.topology.portZ[i]\u003e0?\"rgba(52, 152, 219, 0.55)\":\"rgba(128, 128, 128, 0.5)\",layer:ZW(t,i),label:RW(QW(t,i),KW(t,i))})}!1!==e.showInitialRouteHints\u0026\u0026((t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a={x:(r.x+s.x)/2,y:(r.y+s.y)/2};e.lines.push({points:[r,s],strokeColor:FW(t,n),strokeDash:\"3 3\",label:kW(t,n)}),e.points.push({x:a.x,y:a.y,color:FW(t,n,1),label:kW(t,n)})}})(t,n)}else((t,e)=\u003e{for(let n=0;n\u003ct.state.regionSegments.length;n++){const o=t.state.regionSegments[n]??[];for(const[i,r,s]of o)e.lines.push({points:[GW(t,r),GW(t,s)],label:RW(`route: ${kW(t,i)}`,`region: region-${n}`),...tH(t,i,r,s)})}})(t,n),((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ct.state.regionSegments.length;o++){const i=t.state.regionSegments[o]??[];for(const[o,r,s]of i)for(const i of[r,s]){const r=`${o}:${i}`;if(n.has(r))continue;n.add(r);const s=GW(t,i);e.points.push({x:s.x,y:s.y,color:FW(t,o,1),layer:ZW(t,i),label:RW(`route: ${kW(t,o)}`,qW(t,i),JW(t,i,o),KW(t,i))})}}})(t,n),(t=\u003eLW(t)\u0026\u0026!0===t.showUnassignedPortsInVisualization)(t)\u0026\u0026((t,e)=\u003e{for(let n=0;n\u003ct.topology.portCount;n++)t.state.portAssignment[n]\u003e=0||eH(t,n)||e.circles.push({center:UW(t,n),radius:.04,fill:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.2)\":\"rgba(128, 128, 128, 0.2)\",stroke:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.6)\":\"rgba(128, 128, 128, 0.6)\",layer:ZW(t,n),label:RW(QW(t,n),KW(t,n),\"state: unassigned\")})})(t,n),LW(t)||(((t,e)=\u003e{const n=t.state.currentRouteId;if(void 0===n||t.solved)return;const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a=FW(t,n),c=kW(t,n);e.lines.push({points:[r,s],strokeColor:a,strokeDash:\"10 5\",label:c})})(t,n),((t,e)=\u003e{if(t.solved)return;const n=t.state.currentRouteId,o=t.state.candidateQueue.toArray().sort((t,e)=\u003et.f-e.f).slice(0,10);for(let i=0;i\u003co.length;i++){const r=o[i],s=GW(t,r.portId),a=0===i;e.points.push({x:s.x,y:s.y,color:a?\"green\":\"rgba(128, 128, 128, 0.25)\",layer:ZW(t,r.portId),label:RW(QW(t,r.portId,n),KW(t,r.portId),`g: ${r.g.toFixed(2)}`,`h: ${r.h.toFixed(2)}`,`f: ${r.f.toFixed(2)}`)})}const i=o[0];if(!i)return;const r=[];let s=i;for(;s;)r.unshift(GW(t,s.portId)),s=s.prevCandidate;r.length\u003e1\u0026\u0026e.lines.push({points:r,strokeColor:void 0!==n?FW(t,n):\"rgba(0, 160, 120, 0.9)\"})})(t,n));o\u0026\u0026nH(t,n,o),((t,e)=\u003e{if(t.failed)for(const n of t.getNeverSuccessfullyRoutedRoutes()){const{routeId:o,connectionId:i,attempts:r,startPortId:s,endPortId:a}=n,c=BW(t,o),l=UW(t,s),d=UW(t,a),h=RW(`never routed: ${i}`,`attempts: ${r}`,c,n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0);e.lines.push({points:[{x:0,y:0},{x:l.x,y:l.y}],strokeColor:NW,strokeDash:TW,layer:ZW(t,s),label:RW(h,\"origin guide\",\"endpoint: start\")}),e.circles.push({center:l,radius:1,fill:wW,stroke:NW,layer:ZW(t,s),label:RW(h,\"endpoint: start\",qW(t,s),KW(t,s))}),e.lines.push({points:[{x:0,y:0},{x:d.x,y:d.y}],strokeColor:NW,strokeDash:TW,layer:ZW(t,a),label:RW(h,\"origin guide\",\"endpoint: end\")}),e.circles.push({center:d,radius:1,fill:wW,stroke:NW,layer:ZW(t,a),label:RW(h,\"endpoint: end\",qW(t,a),KW(t,a))})}})(t,n);const i=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1),r=o?o.reduce((t,e)=\u003et+Number(1===e),0):0;return n.title=[\"Tiny HyperGraph\",`iter=${t.iterations}`,`pending=${i}`,o?`sectionPorts=${r}`:void 0,t.failed?\"failed\":t.solved?\"solved\":\"running\"].filter(Boolean).join(\" | \"),n},iH=()=\u003e({netIds:new Int32Array(0),lesserAngles:new Int32Array(0),greaterAngles:new Int32Array(0),layerMasks:new Int32Array(0),existingCrossingLayerIntersections:0,existingSameLayerIntersections:0,existingEntryExitLayerChanges:0,existingRegionCost:0,existingSegmentCount:0}),rH=(t,e)=\u003et.f-e.f,sH=class extends kt{constructor(t,e,n){super(),this.topology=t,this.problem=e,((t,e)=\u003e{e\u0026\u0026(void 0!==e.DISTANCE_TO_COST\u0026\u0026(t.DISTANCE_TO_COST=e.DISTANCE_TO_COST),void 0!==e.RIP_THRESHOLD_START\u0026\u0026(t.RIP_THRESHOLD_START=e.RIP_THRESHOLD_START),void 0!==e.RIP_THRESHOLD_END\u0026\u0026(t.RIP_THRESHOLD_END=e.RIP_THRESHOLD_END),void 0!==e.RIP_THRESHOLD_RAMP_ATTEMPTS\u0026\u0026(t.RIP_THRESHOLD_RAMP_ATTEMPTS=e.RIP_THRESHOLD_RAMP_ATTEMPTS),void 0!==e.RIP_CONGESTION_REGION_COST_FACTOR\u0026\u0026(t.RIP_CONGESTION_REGION_COST_FACTOR=e.RIP_CONGESTION_REGION_COST_FACTOR),void 0!==e.MAX_ITERATIONS\u0026\u0026(t.MAX_ITERATIONS=e.MAX_ITERATIONS),void 0!==e.VERBOSE\u0026\u0026(t.VERBOSE=e.VERBOSE),void 0!==e.STATIC_REACHABILITY_PRECHECK\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK=e.STATIC_REACHABILITY_PRECHECK),void 0!==e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS=e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS))})(this,n),this.state={portAssignment:new Int32Array(t.portCount).fill(-1),regionSegments:Array.from({length:t.regionCount},()=\u003e[]),regionIntersectionCaches:Array.from({length:t.regionCount},()=\u003eiH()),currentRouteId:void 0,currentRouteNetId:void 0,unroutedRoutes:CW(e.routeCount),candidateQueue:new fW([],rH),candidateBestCostByHopId:new Float64Array(t.portCount*t.regionCount),candidateBestCostGenerationByHopId:new Uint32Array(t.portCount*t.regionCount),candidateBestCostGeneration:1,goalPortId:-1,ripCount:0,regionCongestionCost:new Float64Array(t.regionCount).fill(0)},this.routeAttemptCountByRouteId=new Uint32Array(e.routeCount),this.routeSuccessCountByRouteId=new Uint32Array(e.routeCount)}topology;problem;state;_problemSetup;routeAttemptCountByRouteId;routeSuccessCountByRouteId;hasLoggedNeverSuccessfullyRoutedRoutes=!1;segmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};DISTANCE_TO_COST=.05;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;RIP_CONGESTION_REGION_COST_FACTOR=.1;MAX_ITERATIONS=1e6;VERBOSE=!1;STATIC_REACHABILITY_PRECHECK=!0;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;get problemSetup(){return this._problemSetup||(this._problemSetup=this.computeProblemSetup()),this._problemSetup}computeProblemSetup(){const{topology:t,problem:e}=this,n=t.portX,o=t.portY,i=new Float64Array(t.portCount*e.routeCount),r=Array.from({length:t.portCount},()=\u003enew Set);for(let s=0;s\u003ce.routeCount;s++){r[e.routeStartPort[s]].add(e.routeNet[s]),r[e.routeEndPort[s]].add(e.routeNet[s]);const a=e.routeEndPort[s],c=n[a],l=o[a];for(let r=0;r\u003ct.portCount;r++){const t=n[r]-c,a=o[r]-l;i[r*e.routeCount+s]=Math.hypot(t,a)*this.DISTANCE_TO_COST}}return{portHCostToEndOfRoute:i,portEndpointNetIds:r}}_setup(){if(this.problemSetup,this.STATIC_REACHABILITY_PRECHECK){const t=IW({topology:this.topology,problem:this.problem,problemSetup:this.problemSetup,portAssignment:this.state.portAssignment,routeIds:this.state.unroutedRoutes,maxPrecheckHops:Math.max(0,this.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),getStartingNextRegionId:(t,e)=\u003ethis.getStartingNextRegionId(t,e),getRouteSummary:t=\u003ethis.getRouteSummary(t)});t.length\u003e0\u0026\u0026(this.failed=!0,this.error=(t=\u003e{const e=t.slice(0,5).map(t=\u003e{const e=t.pointIds.length\u003e=2?`${t.pointIds[0]}-\u003e${t.pointIds[1]}`:`${t.startPortId}-\u003e${t.endPortId}`;return`${t.connectionId} (${e})`}).join(\", \"),n=t.length-5;return[\"Static reachability precheck failed:\",`${t.length} route(s) have no legal path under the current reservation and start-region rules`,n\u003e0?`${e}, +${n} more`:e].join(\" \")})(t),this.stats={...this.stats,staticallyUnroutableRouteCount:t.length})}}_step(){const{problem:t,topology:e,state:n}=this;if(void 0===n.currentRouteId){if(0===n.unroutedRoutes.length)return void this.onAllRoutesRouted();n.currentRouteId=n.unroutedRoutes.shift(),n.currentRouteNetId=t.routeNet[n.currentRouteId],this.routeAttemptCountByRouteId[n.currentRouteId]+=1,this.resetCandidateBestCosts();const e=t.routeStartPort[n.currentRouteId];n.candidateQueue.clear();const o=this.getStartingNextRegionId(n.currentRouteId,e);if(void 0===o)return this.failed=!0,void(this.error=`Start port ${e} has no incident regions`);this.setCandidateBestCost(this.getHopId(e,o),0),n.candidateQueue.queue({nextRegionId:o,portId:e,f:0,g:0,h:0}),n.goalPortId=t.routeEndPort[n.currentRouteId]}const o=n.candidateQueue.dequeue();if(!o)return void this.onOutOfCandidates();const i=this.getHopId(o.portId,o.nextRegionId);if(o.g\u003ethis.getCandidateBestCost(i))return;if(this.isRegionReservedForDifferentNet(o.nextRegionId))return;const r=e.regionIncidentPorts[o.nextRegionId];for(const i of r){const r=n.portAssignment[i];if(this.isPortReservedForDifferentNet(i))continue;if(i===n.goalPortId){if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;return void this.onPathFound(o)}if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;if(i===o.portId)continue;if(0===t.portSectionMask[i])continue;const s=this.computeG(o,i);if(!Number.isFinite(s))continue;const a=this.computeH(i),c=e.incidentPortRegion[i][0]===o.nextRegionId?e.incidentPortRegion[i][1]:e.incidentPortRegion[i][0];if(void 0===c||this.isRegionReservedForDifferentNet(c))continue;const l={prevRegionId:o.nextRegionId,nextRegionId:c,portId:i,g:s,h:a,f:s+a,prevCandidate:o};if(i===n.goalPortId)return void this.onPathFound(l);const d=this.getHopId(i,c);s\u003e=this.getCandidateBestCost(d)||(this.setCandidateBestCost(d,s),n.candidateQueue.queue(l))}}resetCandidateBestCosts(){const{state:t}=this;if(4294967295===t.candidateBestCostGeneration)return t.candidateBestCostGenerationByHopId.fill(0),void(t.candidateBestCostGeneration=1);t.candidateBestCostGeneration+=1}getCandidateBestCost(t){const{state:e}=this;return e.candidateBestCostGenerationByHopId[t]===e.candidateBestCostGeneration?e.candidateBestCostByHopId[t]:Number.POSITIVE_INFINITY}setCandidateBestCost(t,e){const{state:n}=this;n.candidateBestCostGenerationByHopId[t]=n.candidateBestCostGeneration,n.candidateBestCostByHopId[t]=e}getHopId(t,e){return t*this.topology.regionCount+e}getStartingNextRegionId(t,e){const n=this.topology.incidentPortRegion[e]??[],o=this.problem.routeNet[t];return n.find(t=\u003e-1===this.problem.regionNetId[t])??n.find(t=\u003ethis.problem.regionNetId[t]===o)??n[0]}isPortReservedForDifferentNet(t){const e=this.problemSetup.portEndpointNetIds[t];if(!e)return!1;for(const t of e)if(t!==this.state.currentRouteNetId)return!0;return!1}isRegionReservedForDifferentNet(t){const e=this.problem.regionNetId[t];return-1!==e\u0026\u0026e!==this.state.currentRouteNetId}isKnownSingleLayerRegion(t){const e=this.topology.regionAvailableZMask?.[t]??0;return pW(e)}computeRegionCostForRegion(t,e,n,o,i){return((t,e,n,o,i,r,s=0)=\u003emW(t*e,n,o,i,r,s))(this.topology.regionWidth[t],this.topology.regionHeight[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0)}populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.segmentGeometryScratch,r=o.incidentPortRegion[e],s=o.incidentPortRegion[n],a=r[0]===t||r[1]!==t?o.portAngleForRegion1[e]:o.portAngleForRegion2?.[e]??o.portAngleForRegion1[e],c=s[0]===t||s[1]!==t?o.portAngleForRegion1[n]:o.portAngleForRegion2?.[n]??o.portAngleForRegion1[n],l=o.portZ[e],d=o.portZ[n];return i.lesserAngle=a\u003cc?a:c,i.greaterAngle=a\u003cc?c:a,i.layerMask=1\u003c\u003cl|1\u003c\u003cd,i.entryExitLayerChanges=l!==d?1:0,i}appendSegmentToRegionCache(t,e,n){const{topology:o,state:i}=this,r=i.regionIntersectionCaches[t],s=this.populateSegmentGeometryScratch(t,e,n),[a,c,l]=gW(r,i.currentRouteNetId,s.lesserAngle,s.greaterAngle,s.layerMask,s.entryExitLayerChanges),d=r.netIds.length+1,h=new Int32Array(d);h.set(r.netIds),h[d-1]=i.currentRouteNetId;const u=new Int32Array(d);u.set(r.lesserAngles),u[d-1]=s.lesserAngle;const p=new Int32Array(d);p.set(r.greaterAngles),p[d-1]=s.greaterAngle;const m=new Int32Array(d);m.set(r.layerMasks),m[d-1]=s.layerMask;const g=r.existingSameLayerIntersections+a,f=r.existingCrossingLayerIntersections+c,y=r.existingEntryExitLayerChanges+l,_=u.length;i.regionIntersectionCaches[t]={netIds:h,lesserAngles:u,greaterAngles:p,layerMasks:m,existingSameLayerIntersections:g,existingCrossingLayerIntersections:f,existingEntryExitLayerChanges:y,existingSegmentCount:_,existingRegionCost:this.computeRegionCostForRegion(t,g,f,y,_)}}getSolvedPathSegments(t){const{state:e}=this,n=[];let o=t;for(;o;)n.unshift(o),o=o.prevCandidate;const i=[];for(let t=1;t\u003cn.length;t++)i.push({regionId:n[t-1].nextRegionId,fromPortId:n[t-1].portId,toPortId:n[t].portId});const r=n[n.length-1];return r\u0026\u0026r.portId!==e.goalPortId\u0026\u0026i.push({regionId:r.nextRegionId,fromPortId:r.portId,toPortId:e.goalPortId}),i}resetRoutingStateForRerip(){const{topology:t,problem:e,state:n}=this;n.portAssignment.fill(-1),n.regionSegments=Array.from({length:t.regionCount},()=\u003e[]),n.regionIntersectionCaches=Array.from({length:t.regionCount},()=\u003eiH()),n.currentRouteNetId=void 0,n.currentRouteId=void 0,n.unroutedRoutes=yW(CW(e.routeCount),n.ripCount),n.candidateQueue.clear(),this.resetCandidateBestCosts(),n.goalPortId=-1}getMaxRegionCost(){const{topology:t,state:e}=this;let n=0;for(let o=0;o\u003ct.regionCount;o++){const t=e.regionIntersectionCaches[o]?.existingRegionCost??0;n=Math.max(n,t)}return n}getRouteMetadata(t){return this.problem.routeMetadata?.[t]}getRouteConnectionId(t){const e=this.getRouteMetadata(t)?.connectionId;return\"string\"==typeof e?e:`route-${t}`}getRouteSummary(t){return(({problem:t,routeId:e,getRouteMetadata:n,getRouteConnectionId:o})=\u003e{const i=n?.(e)??_W(t,e);return{routeId:e,connectionId:o?.(e)??xW(t,e),startPortId:t.routeStartPort[e],endPortId:t.routeEndPort[e],startRegionId:\"string\"==typeof i?.startRegionId?i.startRegionId:void 0,endRegionId:\"string\"==typeof i?.endRegionId?i.endRegionId:void 0,pointIds:bW(i)}})({problem:this.problem,routeId:t,getRouteMetadata:t=\u003ethis.getRouteMetadata(t),getRouteConnectionId:t=\u003ethis.getRouteConnectionId(t)})}getAdditionalRegionLabel(t){}getNeverSuccessfullyRoutedRoutes(){const t=[];for(let e=0;e\u003cthis.problem.routeCount;e++){const n=this.routeAttemptCountByRouteId[e];0===n||this.routeSuccessCountByRouteId[e]\u003e0||t.push({...this.getRouteSummary(e),attempts:n})}return t}logNeverSuccessfullyRoutedRoutes(){if(!this.VERBOSE||this.hasLoggedNeverSuccessfullyRoutedRoutes)return;const t=this.getNeverSuccessfullyRoutedRoutes();if(this.hasLoggedNeverSuccessfullyRoutedRoutes=!0,0!==t.length){console.log([\"[TinyHyperGraphSolver:never-routed-summary]\",`count=${t.length}`].join(\" \"));for(const e of t){const t=e.pointIds.length\u003e=2?`${e.pointIds[0]}-\u003e${e.pointIds[1]}`:\"unknown\";console.log([\"[TinyHyperGraphSolver:never-routed]\",`routeId=${e.routeId}`,`connectionId=${e.connectionId}`,`attempts=${e.attempts}`,`pointPath=${t}`,`startRegionId=${e.startRegionId??\"unknown\"}`,`endRegionId=${e.endRegionId??\"unknown\"}`].join(\" \"))}}}logRipEvent(t,e,n={}){this.VERBOSE\u0026\u0026console.log([\"[TinyHyperGraphSolver:rip]\",`ripCount=${this.state.ripCount}`,`maxRegionCostBeforeRip=${e.toFixed(3)}`,`reason=${t}`,...Object.entries(n).map(([t,e])=\u003e`${t}=${\"number\"==typeof e?Number.isInteger(e)?String(e):e.toFixed(3):e}`)].join(\" \"))}onAllRoutesRouted(){const{topology:t,state:e}=this,n=this.RIP_THRESHOLD_RAMP_ATTEMPTS\u003c=0?1:Math.min(1,e.ripCount/this.RIP_THRESHOLD_RAMP_ATTEMPTS),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(t.regionCount);let s=0;for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;r[n]=t,s=Math.max(s,t),t\u003eo\u0026\u0026i.push(n)}if(this.stats={...this.stats,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:s,ripCount:e.ripCount},0===i.length||e.ripCount\u003e=this.RIP_THRESHOLD_RAMP_ATTEMPTS)this.solved=!0;else{for(let n=0;n\u003ct.regionCount;n++)e.regionCongestionCost[n]+=r[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCostBeforeRip:s,reripRegionCount:i.length},this.logRipEvent(\"hot_regions\",s,{hotRegionCount:i.length,currentRipThreshold:o})}}onOutOfCandidates(){const{topology:t,state:e}=this,n=e.currentRouteId,o=this.getMaxRegionCost();for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;e.regionCongestionCost[n]+=t*this.RIP_CONGESTION_REGION_COST_FACTOR}e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCost:o,maxRegionCostBeforeRip:o,reripReason:\"out_of_candidates\"},this.logRipEvent(\"out_of_candidates\",o,{...void 0===n?{}:{routeId:n,connectionId:this.getRouteConnectionId(n)}})}onPathFound(t){const{state:e}=this,n=e.currentRouteId;if(void 0===n)return;this.routeSuccessCountByRouteId[n]+=1;const o=this.getSolvedPathSegments(t);for(const{regionId:t,fromPortId:i,toPortId:r}of o)e.regionSegments[t].push([n,i,r]),e.portAssignment[i]=e.currentRouteNetId,e.portAssignment[r]=e.currentRouteNetId,this.appendSegmentToRegionCache(t,i,r);e.candidateQueue.clear(),e.currentRouteNetId=void 0,e.currentRouteId=void 0}computeG(t,e){const{topology:n,state:o}=this,i=t.nextRegionId,r=o.regionIntersectionCaches[i],s=this.populateSegmentGeometryScratch(i,t.portId,e),[a,c,l]=gW(r,o.currentRouteNetId,s.lesserAngle,s.greaterAngle,s.layerMask,s.entryExitLayerChanges);if(a\u003e0\u0026\u0026this.isKnownSingleLayerRegion(i))return Number.POSITIVE_INFINITY;const d=this.computeRegionCostForRegion(i,r.existingSameLayerIntersections+a,r.existingCrossingLayerIntersections+c,r.existingEntryExitLayerChanges+l,r.existingSegmentCount+1)-r.existingRegionCost;return t.g+d+o.regionCongestionCost[i]}tryFinalAcceptance(){const t=this.getNeverSuccessfullyRoutedRoutes();this.stats={...this.stats,neverSuccessfullyRoutedRouteCount:t.length},this.logNeverSuccessfullyRoutedRoutes()}computeH(t){return this.problemSetup.portHCostToEndOfRoute[t*this.problem.routeCount+this.state.currentRouteId]}visualize(){return oH(this)}getOutput(){return uW(this)}},aH=t=\u003e{const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;return Number.isFinite(e)?e:void 0},cH=t=\u003e{const e=new Set;for(const n of t.connections??[])e.add(n.startRegionId),e.add(n.endRegionId);const n=new Set(t.regions.filter(t=\u003e(t=\u003e{if(!0!==t.d?._containsObstacle)return!1;if(!0!==t.d?._containsTarget)return!0;const e=aH(t);return void 0===e||-1===e})(t)\u0026\u0026!e.has(t.regionId)).map(t=\u003et.regionId));if(0===n.size)return t;const o=t.ports.filter(t=\u003e!n.has(t.region1Id)\u0026\u0026!n.has(t.region2Id)),i=(t.connections??[]).find(t=\u003en.has(t.startRegionId)||n.has(t.endRegionId));if(i)throw new Error(`Connection \"${i.connectionId}\" references full-obstacle region`);return{...t,regions:t.regions.filter(t=\u003e!n.has(t.regionId)),ports:o}},lH=t=\u003e{const e=t.d?.bounds;if(e)return e;const n=t.d?.center,o=t.d?.width,i=t.d?.height;return n\u0026\u0026\"number\"==typeof n.x\u0026\u0026\"number\"==typeof n.y\u0026\u0026\"number\"==typeof o\u0026\u0026\"number\"==typeof i?{minX:n.x-o/2,maxX:n.x+o/2,minY:n.y-i/2,maxY:n.y+i/2}:{minX:0,maxX:0,minY:0,maxY:0}},dH=t=\u003e{const e=Number(t.d?.z??0);return Number.isFinite(e)?e:0},hH=t=\u003e.005*dH(t),uH=t=\u003eNumber(t.d?.x??0)+hH(t),pH=t=\u003eNumber(t.d?.y??0)+hH(t),mH=(t,e)=\u003e{if(!e)return 0;const n=lH(e),o=uH(t),i=pH(t),r=n.minX\u003c=o\u0026\u0026o\u003c=n.maxX,s=n.minY\u003c=i\u0026\u0026i\u003c=n.maxY;if(s\u0026\u0026o\u003e=n.maxX){const t=Math.max(n.maxY-n.minY,1e-9),e=(i-n.minY)/t;return Math.round(9e3*e)}if(r\u0026\u0026i\u003e=n.maxY){const t=Math.max(n.maxX-n.minX,1e-9),e=(n.maxX-o)/t;return 9e3+Math.round(9e3*e)}if(s\u0026\u0026o\u003c=n.minX){const t=Math.max(n.maxY-n.minY,1e-9),e=(n.maxY-i)/t;return 18e3+Math.round(9e3*e)}if(r\u0026\u0026i\u003c=n.minY){const t=Math.max(n.maxX-n.minX,1e-9),e=(o-n.minX)/t;return 27e3+Math.round(9e3*e)}const a=Math.abs(o-n.minX),c=Math.abs(o-n.maxX),l=Math.abs(i-n.minY),d=Math.abs(i-n.maxY),h=Math.min(a,c,l,d),u=Math.max(n.maxX-n.minX,1e-9),p=Math.max(n.maxY-n.minY,1e-9);if(h===c){const t=(i-n.minY)/p;return Math.round(9e3*t)}if(h===d){const t=(n.maxX-o)/u;return 9e3+Math.round(9e3*t)}if(h===a){const t=(n.maxY-i)/p;return 18e3+Math.round(9e3*t)}const m=(o-n.minX)/u;return 27e3+Math.round(9e3*m)},gH=(t,e)=\u003e{if(!t)return;return[...t.pointIds].sort((t,n)=\u003e{const o=e.get(t),i=e.get(n),r=Number(o?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY),s=Number(i?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY);if(r!==s)return r-s;const a=Number(o?.d?.z??0),c=Number(i?.d?.z??0);return a!==c?a-c:t.localeCompare(n)})[0]},fH=t=\u003e{const e=cH(t),n=new Map,o=new Map,i=new Map,r=new Map((e.solvedRoutes??[]).map(t=\u003e[t.connection.connectionId,t]));e.regions.forEach((t,e)=\u003e{n.set(t.regionId,e)}),e.ports.forEach((t,e)=\u003e{o.set(t.portId,e),i.set(t.portId,t)});const s=e.regions.length,a=e.ports.length,c=e.regions.map(t=\u003et.pointIds.map(t=\u003eo.get(t)).filter(t=\u003evoid 0!==t)),l=Array.from({length:a},()=\u003e[]),d=new Float64Array(s),h=new Float64Array(s),u=new Float64Array(s),p=new Float64Array(s),m=new Int32Array(s),g=new Int32Array(s).fill(-1),f=new Int8Array(s);e.regions.forEach((t,e)=\u003e{const n=(t=\u003e{const e=lH(t),n=\"number\"==typeof t.d?.width?t.d.width:e.maxX-e.minX,o=\"number\"==typeof t.d?.height?t.d.height:e.maxY-e.minY;return{centerX:\"number\"==typeof t.d?.center?.x?t.d.center.x:(e.minX+e.maxX)/2,centerY:\"number\"==typeof t.d?.center?.y?t.d.center.y:(e.minY+e.maxY)/2,width:n,height:o}})(t);d[e]=n.width,h[e]=n.height,u[e]=n.centerX,p[e]=n.centerY,m[e]=(t=\u003e{const e=t.d?.availableZ;if(!Array.isArray(e))return 0;let n=0;for(const t of e)!Number.isInteger(t)||t\u003c0||t\u003e=31||(n|=1\u003c\u003ct);return n})(t);const o=aH(t);void 0!==o\u0026\u0026(g[e]=o,f[e]=1)});const y=new Int32Array(a),_=new Int32Array(a),b=new Float64Array(a),x=new Float64Array(a),v=new Int32Array(a);e.ports.forEach((t,o)=\u003e{const i=n.get(t.region1Id),r=n.get(t.region2Id);if(void 0===i||void 0===r)throw new Error(`Port \"${t.portId}\" references missing regions \"${t.region1Id}\" or \"${t.region2Id}\"`);l[o]=[i,r],b[o]=uH(t),x[o]=pH(t),v[o]=dH(t),y[o]=mH(t,e.regions[i]),_[o]=mH(t,e.regions[r])});const S=e.regions.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedRegionId\",{value:t.regionId,enumerable:!1,configurable:!0,writable:!0}),n})(t,(t=\u003enW(oW(m[t]))??nW((c[t]??[]).map(t=\u003ev[t]))??\"z0\")(e))),I=e.ports.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedPortId\",{value:t.portId,enumerable:!1,configurable:!0,writable:!0}),n})(t,nW([v[e]])??\"z0\")),C=e.connections??[],P=new Map;let M=0;const N=t=\u003e{const e=t.mutuallyConnectedNetworkId??t.connectionId;let n=P.get(e);return void 0===n\u0026\u0026(n=M++,P.set(e,n)),n},w=Array.from({length:s},()=\u003enew Set),T=(t,e)=\u003e{const o=n.get(t);if(void 0===o)throw new Error(`Connection references missing region \"${t}\"`);w[o].add(e)};C.forEach(t=\u003e{const e=N(t);T(t.startRegionId,e),T(t.endRegionId,e)}),w.forEach((t,e)=\u003e{1!==f[e]\u0026\u00261===t.size\u0026\u0026(g[e]=[...t][0])});const R=C.map(t=\u003e{const n=r.get(t.connectionId),o=((t,e)=\u003et.ports.filter(t=\u003et.region1Id===e.startRegionId\u0026\u0026t.region2Id===e.endRegionId||t.region2Id===e.startRegionId\u0026\u0026t.region1Id===e.endRegionId).map(t=\u003et.portId))(e,t);return{connection:t,solvedRoute:n,sharedPortIds:o}}).filter(({solvedRoute:t,sharedPortIds:e})=\u003e0===e.length||(t?.path.length??0)\u003e1),E=R.length,A=new Int8Array(a).fill(1),O=new Int32Array(E),k=new Int32Array(E),L=new Int32Array(E);R.forEach(({connection:t,solvedRoute:n},r)=\u003e{const s=gH(e.regions.find(e=\u003ee.regionId===t.startRegionId),i),a=gH(e.regions.find(e=\u003ee.regionId===t.endRegionId),i),c=n?.path[0]?.portId??s,l=n?.path[n.path.length-1]?.portId??a,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)throw new Error(`Connection \"${t.connectionId}\" could not be mapped to route endpoints`);O[r]=d,k[r]=h,L[r]=N(t)});const D={portCount:a,regionCount:s,regionIncidentPorts:c,incidentPortRegion:l,regionWidth:d,regionHeight:h,regionCenterX:u,regionCenterY:p,regionAvailableZMask:m,regionMetadata:S,portAngleForRegion1:y,portAngleForRegion2:_,portX:b,portY:x,portZ:v,portMetadata:I},z={routeCount:E,portSectionMask:A,routeMetadata:R.map(({connection:t})=\u003et),routeStartPort:O,routeEndPort:k,routeNet:L,regionNetId:g},F=[],B=[];for(const{solvedRoute:t}of R){if(!t){F.push([]),B.push([]);continue}const e=[],i=[];for(let r=1;r\u003ct.path.length;r++){const s=t.path[r-1],a=t.path[r],c=s?.portId,l=a?.portId,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)continue;const u=\"string\"==typeof s?.nextRegionId?s.nextRegionId:\"string\"==typeof a?.lastRegionId?a.lastRegionId:void 0;e.push([d,h]),i.push(void 0!==u?n.get(u):void 0)}F.push(e),B.push(i)}return{topology:D,problem:z,solution:{solvedRoutePathSegments:F,solvedRoutePathRegionIds:B}}},yH=(Number.POSITIVE_INFINITY,1e-9),_H=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,bH=(t,e=0)=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)?t:e,xH=t=\u003e{const e=(t=\u003e{const e=Math.min(t.minX,t.maxX),n=Math.max(t.minX,t.maxX),o=Math.min(t.minY,t.maxY),i=Math.max(t.minY,t.maxY);return{minX:e,maxX:n\u003ee?n:e+yH,minY:o,maxY:i\u003eo?i:o+yH}})(t);return[{x:e.maxX,y:e.minY},{x:e.maxX,y:e.maxY},{x:e.minX,y:e.maxY},{x:e.minX,y:e.minY}]},vH=(t,e)=\u003e{const n=t.filter(t=\u003eNumber.isFinite(t.x)\u0026\u0026Number.isFinite(t.y)),o=n.length\u003e=3?n:xH(e),i=(t=\u003e{let e=0;for(let n=0;n\u003ct.length;n++){const o=t[n],i=t[(n+1)%t.length];e+=o.x*i.y-o.y*i.x}return e})(o);if(Math.abs(i)\u003c=Number.EPSILON)return xH(e);return(t=\u003e{if(t.length\u003c3)throw new Error(\"Convex polygon requires at least three points\");return t})(i\u003c0?[...o].reverse():[...o])},SH=t=\u003e{const e=(t=\u003e{const e=t.d,n=e?.bounds;if(n\u0026\u0026\"number\"==typeof n.minX\u0026\u0026\"number\"==typeof n.maxX\u0026\u0026\"number\"==typeof n.minY\u0026\u0026\"number\"==typeof n.maxY)return{minX:n.minX,maxX:n.maxX,minY:n.minY,maxY:n.maxY};const o=e?.center,i=bH(e?.width,0),r=bH(e?.height,0);return o\u0026\u0026\"number\"==typeof o.x\u0026\u0026\"number\"==typeof o.y?{minX:o.x-i/2,maxX:o.x+i/2,minY:o.y-r/2,maxY:o.y+r/2}:{minX:0,maxX:yH,minY:0,maxY:yH}})(t);return vH((t=\u003e{const e=t.d,n=e?.polygon??e?.points??e?.vertices;if(!Array.isArray(n))return;const o=n.map(t=\u003e{if(!_H(t))return;const e=t.x,n=t.y;return\"number\"==typeof e\u0026\u0026\"number\"==typeof n?{x:e,y:n}:void 0}).filter(t=\u003evoid 0!==t);if(o.length\u003e1){const t=o[0],e=o[o.length-1];t.x===e.x\u0026\u0026t.y===e.y\u0026\u0026o.pop()}return o.length\u003e=3?o:void 0})(t)??xH(e),e)},IH=t=\u003e{let e=0,n=0,o=0,i=0,r=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,a=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY;for(let l=0;l\u003ct.length;l++){const d=t[l],h=t[(l+1)%t.length],u=d.x*h.y-h.x*d.y;e+=u,n+=(d.x+h.x)*u,o+=(d.y+h.y)*u,i+=Math.hypot(h.x-d.x,h.y-d.y),r=Math.min(r,d.x),s=Math.max(s,d.x),a=Math.min(a,d.y),c=Math.max(c,d.y)}const l=Math.abs(e)/2,d=Math.abs(e)\u003eNumber.EPSILON?3*e:Number.NaN,h=t.reduce((e,n)=\u003e({x:e.x+n.x/t.length,y:e.y+n.y/t.length}),{x:0,y:0});return{area:l,perimeter:i,centerX:Number.isFinite(d)?n/d:h.x,centerY:Number.isFinite(d)?o/d:h.y,bounds:{minX:r,maxX:s,minY:a,maxY:c}}},CH=(t,e,n,o)=\u003e{if(n\u003c=0)return{boundaryPosition:0,edgeIndex:0,edgeT:0};let i=Number.POSITIVE_INFINITY,r=0,s=0,a=0,c=0;for(let n=0;n\u003ce.length;n++){const o=e[n],l=e[(n+1)%e.length],d=l.x-o.x,h=l.y-o.y,u=d*d+h*h,p=Math.sqrt(u),m=u\u003c=Number.EPSILON?0:((t.x-o.x)*d+(t.y-o.y)*h)/u,g=Math.min(1,Math.max(0,m)),f=o.x+d*g,y=o.y+h*g,_=t.x-f,b=t.y-y,x=_*_+b*b;x\u003ci\u0026\u0026(i=x,r=n,s=g,a=c+p*g),c+=p}return{boundaryPosition:Math.round(a/n*o)%o,edgeIndex:r,edgeT:s}},PH=(t,e)=\u003e{const n=t.regionMetadata?.[e];return _H(n)\u0026\u0026\"string\"==typeof n.serializedRegionId?n.serializedRegionId:`region-${e}`},MH=(t,e)=\u003e{const n=t.portMetadata?.[e];return _H(n)\u0026\u0026\"string\"==typeof n.serializedPortId?n.serializedPortId:`port-${e}`},NH=(t,e,n,o)=\u003e{const i={..._H(t)?{...t}:void 0===t?{}:{value:t},polygon:n,sourceBounds:o};return Object.defineProperty(i,\"serializedRegionId\",{value:e,enumerable:!1,configurable:!0,writable:!0}),i},wH=(t,e)=\u003e{const n=new Map,o=new Map,i=new Map,r=new Map;for(let e=0;e\u003ct.regionCount;e++)n.set(PH(t,e),e);for(let e=0;e\u003ct.portCount;e++)o.set(MH(t,e),e);for(let t=0;t\u003ce.routeCount;t++){const n=e.routeMetadata?.[t];if(!_H(n))continue;\"string\"==typeof n.connectionId\u0026\u0026i.set(n.connectionId,t);const o=\"string\"==typeof n.mutuallyConnectedNetworkId?n.mutuallyConnectedNetworkId:\"string\"==typeof n.connectionId?n.connectionId:void 0;void 0!==o\u0026\u0026r.set(o,e.routeNet[t])}return{serializedRegionIdToRegionId:n,serializedPortIdToPortId:o,connectionIdToRouteId:i,netIdToNetIndex:r}},TH=(t,e,n)=\u003e{const o=t.incidentPortRegion[e];return o[0]===n||o[1]!==n?t.portBoundaryPositionForRegion1[e]:t.portBoundaryPositionForRegion2[e]},RH=class extends sH{constructor(t,e,n){super(t,e,n),this.topology=t,this.problem=e}topology;problem;polySegmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.polySegmentGeometryScratch,r=TH(o,e,t),s=TH(o,n,t),a=o.portZ[e],c=o.portZ[n];return i.lesserAngle=r\u003cs?r:s,i.greaterAngle=r\u003cs?s:r,i.layerMask=1\u003c\u003ca|1\u003c\u003cc,i.entryExitLayerChanges=a!==c?1:0,i}computeRegionCostForRegion(t,e,n,o,i){return mW(this.topology.regionArea[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0)}visualize(){return $H(this)}},EH=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),AH=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},OH=(t,e,n=.85)=\u003e{const o=`${t.problem.routeNet[e]}:${AH(t,e)}`;let i=0;for(let t=0;t\u003co.length;t++)i=17777*o.charCodeAt(t)+((i\u003c\u003c5)-i);return`hsla(${Math.abs(i)%360}, 70%, 45%, ${n})`},kH=(t,e)=\u003e{const n=t.regionVertexStart[e],o=t.regionVertexCount[e],i=[];for(let e=0;e\u003co;e++){const o=n+e;i.push({x:t.regionVertexX[o],y:t.regionVertexY[o]})}return i},LH=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e]?.existingRegionCost??0,o=Math.min(1,Math.max(0,Math.pow(n,.8))),i=Math.round(245-105*o);return`rgba(245, ${Math.round(248-168*o)}, ${i}, ${.18+.48*o})`},DH=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e],o=PH(t.topology,e),i=t.problem.regionNetId[e];return EH(`region: ${o}`,`net: ${-1===i?\"free\":i}`,`area: ${t.topology.regionArea[e].toFixed(3)}`,`cost: ${(n?.existingRegionCost??0).toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},zH=(t,e)=\u003enW(oW(t.topology.regionAvailableZMask?.[e]??0))??nW((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))??\"z0\",FH=(t,e)=\u003e({x:t.topology.portX[e],y:t.topology.portY[e]}),BH=(t,e)=\u003enW([t.topology.portZ[e]])??\"z0\",jH=(t,e)=\u003e{const[n,o]=t.topology.incidentPortRegion[e]??[];return EH(`port: ${MH(t.topology,e)}`,`connects: ${n??\"?\"} \u003c-\u003e ${o??\"?\"}`,`z: ${t.topology.portZ[e]}`)},$H=t=\u003e{const e={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:\"Poly HyperGraph\",coordinateSystem:\"cartesian\"};for(let n=0;n\u003ct.topology.regionCount;n++)e.polygons.push({points:kH(t.topology,n),fill:LH(t,n),stroke:\"rgba(80, 80, 120, 0.55)\",layer:zH(t,n),label:DH(t,n)});for(let n=0;n\u003ct.topology.portCount;n++)e.circles.push({center:FH(t,n),radius:.05,fill:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.55)\":\"rgba(80, 80, 80, 0.45)\",layer:BH(t,n),label:jH(t,n)});((t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=AH(t,n),s=OH(t,n);e.points.push({...FH(t,o),color:s,layer:BH(t,o),label:EH(`route: ${r}`,\"endpoint: start\",jH(t,o))}),e.points.push({...FH(t,i),color:s,layer:BH(t,i),label:EH(`route: ${r}`,\"endpoint: end\",jH(t,i))})}})(t,e),((t,e)=\u003e{for(let n=0;n\u003ct.state.regionSegments.length;n++)for(const[o,i,r]of t.state.regionSegments[n]??[])e.lines.push({points:[FH(t,i),FH(t,r)],strokeColor:OH(t,o),layer:nW([t.topology.portZ[i],t.topology.portZ[r]])??\"z0\",label:EH(`route: ${AH(t,o)}`,`region: ${PH(t.topology,n)}`)})})(t,e),((t,e)=\u003e{if(t.solved)return;const n=t.state.candidateQueue.toArray().sort((t,e)=\u003et.f-e.f).slice(0,10);for(let o=0;o\u003cn.length;o++){const i=n[o];e.points.push({...FH(t,i.portId),color:0===o?\"green\":\"rgba(128, 128, 128, 0.4)\",layer:BH(t,i.portId),label:EH(jH(t,i.portId),`g: ${i.g.toFixed(2)}`,`h: ${i.h.toFixed(2)}`,`f: ${i.f.toFixed(2)}`)})}const o=n[0];if(!o)return;const i=[];let r=o;for(;r;)i.unshift(FH(t,r.portId)),r=r.prevCandidate;if(i.length\u003c=1)return;const s=t.state.currentRouteId;e.lines.push({points:i,strokeColor:void 0!==s?OH(t,s,.95):\"rgba(0, 160, 120, 0.95)\",strokeDash:\"4 3\",layer:BH(t,o.portId),label:EH(void 0!==s?`route: ${AH(t,s)}`:void 0,\"active candidate path\",`candidate port: ${MH(t.topology,o.portId)}`)})})(t,e);const n=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1);return e.title=[\"Poly HyperGraph\",`iter=${t.iterations}`,`pending=${n}`,t.failed?\"failed\":t.solved?\"solved\":\"running\"].join(\" | \"),e},YH=(new Int32Array(0),t=\u003e(t.ccwRotationDegrees??0)*Math.PI/180),XH=(t,e=8)=\u003e{const n=t.width/2,o=t.height/2,i=YH(t),r=Math.cos(i),s=Math.sin(i);return Array.from({length:e},(i,a)=\u003e{const c=2*Math.PI*a/e,l=n*Math.cos(c),d=o*Math.sin(c);return{x:t.center.x+l*r-d*s,y:t.center.y+l*s+d*r}})},VH=t=\u003e(t.obstacles??[]).filter(t=\u003e\"oval\"===t.type).map(t=\u003e({points:XH(t),layers:t.layers,zLayers:t.__zLayers,isCopperPour:t.isCopperPour})),WH=(t,e)=\u003e(t.obstacles??[]).flatMap((n,o)=\u003e{if(!Array.isArray(n.connectedTo)||0===n.connectedTo.length)return[];const i=oV(sV(n,t.layerCount),t.layerCount);if(0===i.length)return[];let r;const s=n.type;if(\"rect\"===s)r=((t,e=0)=\u003e{const n=t.width/2+e,o=t.height/2+e,i=YH(t),r=Math.cos(i),s=Math.sin(i);return[{localX:-n,localY:-o},{localX:n,localY:-o},{localX:n,localY:o},{localX:-n,localY:o}].map(({localX:e,localY:n})=\u003e({x:t.center.x+e*r-n*s,y:t.center.y+e*s+n*r}))})(n,e);else{if(\"oval\"!==s)return[];r=EV({polygon:{points:XH(n),layers:n.layers,zLayers:n.__zLayers,isCopperPour:n.isCopperPour},clearance:e,verticesOnly:!0})}return[{regionId:`connected-obstacle-${o}`,polygon:r,availableZ:i,connectedTo:n.connectedTo,d:{obstacleIndex:o,obstacleType:s,connectedTo:n.connectedTo}}]}),HH=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},GH=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},UH=(t,e)=\u003e{const n=HH(t).serializedRegionId;return\"string\"==typeof n?n:`region-${e}`},ZH=(t,e)=\u003e{const n=GH(t);return\"string\"==typeof n.serializedPortId?n.serializedPortId:\"string\"==typeof n.portId?n.portId:`poly-port-${e}`},qH=t=\u003e{const e=GH(t);return{prevPortPointId:\"string\"==typeof e.prevPortPointId?e.prevPortPointId:void 0,nextPortPointId:\"string\"==typeof e.nextPortPointId?e.nextPortPointId:void 0}},JH=t=\u003e{const e=HH(t).polygon;if(Array.isArray(e)\u0026\u0026!(e.length\u003c3))return e.every(t=\u003e\"object\"==typeof t\u0026\u0026null!==t\u0026\u0026\"number\"==typeof t.x\u0026\u0026\"number\"==typeof t.y)?e:void 0},KH=class extends si{constructor(t){super(),this.params=t,this.effort=t.effort??1,this.clearance=t.srj.defaultObstacleMargin??t.srj.minTraceWidth;const e=e=\u003e{return eW({bounds:t.srj.bounds,rects:(n=t.srj,(n.obstacles??[]).filter(t=\u003e\"rect\"===t.type).map(t=\u003e({center:t.center,width:t.width,height:t.height,ccwRotation:YH(t),layers:t.layers,zLayers:t.__zLayers,isCopperPour:t.isCopperPour}))),polygons:VH(t.srj),clearance:this.clearance,concavityTolerance:t.concavityTolerance??0,layerCount:t.srj.layerCount,layerMergeMode:t.layerMergeMode??\"same\",useConstrainedDelaunay:e,usePolyanyaMerge:t.usePolyanyaMerge??!1,viaSegments:t.viaSegments??8});var n},n=t.useConstrainedDelaunay??!0;try{this.convexRegions=e(n)}catch(t){if(!n)throw t;this.usedUnconstrainedDelaunayFallback=!0,this.convexRegions=e(!1)}var o;this.serializedGraph=RV({regions:this.convexRegions.regions,availableZ:this.convexRegions.availableZ,layerCount:t.srj.layerCount,connections:(o=t.srj,o.connections.flatMap(t=\u003e{const e=t.pointsToConnect??[];if(e.length\u003c2)return[];const n=e[0];return e.slice(1).map((e,o)=\u003e{const i=((t,e,n,o)=\u003e{const i=2===t.pointsToConnect.length?t.name:`${t.name}::${o}`;return{...t,name:i,__rootConnectionNames:t.__rootConnectionNames??[t.name],pointsToConnect:[e,n]}})(t,n,e,o);return{connectionId:i.name,mutuallyConnectedNetworkId:i.__rootConnectionNames?.[0]??i.name,start:n,end:e,simpleRouteConnection:i}})})),obstacleRegions:WH(t.srj,this.clearance),portSpacing:t.portSpacing??lV,portMarginFromSegmentEndpoint:t.portMarginFromSegmentEndpoint??dV}),this.loaded=((t,e={})=\u003e{const n=e.boundaryCoordinateScale??36e3,o=fH(t),{topology:i,problem:r,solution:s}=o,a=new Map(t.regions.map(t=\u003e[t.regionId,t])),c=[];for(let t=0;t\u003ci.regionCount;t++){const e=PH(i,t),n=a.get(e),o=n?SH(n):xH({minX:i.regionCenterX[t]-i.regionWidth[t]/2,maxX:i.regionCenterX[t]+i.regionWidth[t]/2,minY:i.regionCenterY[t]-i.regionHeight[t]/2,maxY:i.regionCenterY[t]+i.regionHeight[t]/2});c.push(o)}const l=c.reduce((t,e)=\u003et+e.length,0),d=new Int32Array(i.regionCount),h=new Int32Array(i.regionCount),u=new Float64Array(l),p=new Float64Array(l),m=new Float64Array(i.regionCount),g=new Float64Array(i.regionCount),f=new Float64Array(i.regionCount),y=new Float64Array(i.regionCount),_=new Float64Array(i.regionCount),b=new Float64Array(i.regionCount),x=new Float64Array(i.regionCount),v=new Float64Array(i.regionCount),S=new Float64Array(i.regionCount),I=new Float64Array(i.regionCount),C=new Array(i.regionCount);let P=0;for(let t=0;t\u003ci.regionCount;t++){const e=c[t],n=IH(e),o=Math.sqrt(Math.max(n.area,yH));d[t]=P,h[t]=e.length,m[t]=n.area,g[t]=n.perimeter,f[t]=n.centerX,y[t]=n.centerY,_[t]=n.bounds.minX,b[t]=n.bounds.maxX,x[t]=n.bounds.minY,v[t]=n.bounds.maxY,S[t]=o,I[t]=o,C[t]=NH(i.regionMetadata?.[t],PH(i,t),e,n.bounds);for(const t of e)u[P]=t.x,p[P]=t.y,P+=1}const M=new Int32Array(i.portCount),N=new Int32Array(i.portCount),w=new Int32Array(i.portCount),T=new Int32Array(i.portCount),R=new Float64Array(i.portCount),E=new Float64Array(i.portCount);for(let t=0;t\u003ci.portCount;t++){const e={x:i.portX[t],y:i.portY[t]},[o,r]=i.incidentPortRegion[t]??[];if(void 0!==o){const i=CH(e,c[o],g[o],n);M[t]=i.boundaryPosition,w[t]=i.edgeIndex,R[t]=i.edgeT}if(void 0!==r){const o=CH(e,c[r],g[r],n);N[t]=o.boundaryPosition,T[t]=o.edgeIndex,E[t]=o.edgeT}}for(let t=0;t\u003ci.regionCount;t++)C[t].layer=nW(oW(i.regionAvailableZMask?.[t]??0))??nW((i.regionIncidentPorts[t]??[]).map(t=\u003ei.portZ[t]))??\"z0\";const A={...i,regionWidth:S,regionHeight:I,regionCenterX:f,regionCenterY:y,regionMetadata:C,portAngleForRegion1:M,portAngleForRegion2:N,regionVertexStart:d,regionVertexCount:h,regionVertexX:u,regionVertexY:p,regionArea:m,regionPerimeter:g,regionBoundsMinX:_,regionBoundsMaxX:b,regionBoundsMinY:x,regionBoundsMaxY:v,portBoundaryPositionForRegion1:M,portBoundaryPositionForRegion2:N,portEdgeIndexForRegion1:w,portEdgeIndexForRegion2:T,portEdgeTForRegion1:R,portEdgeTForRegion2:E};return{topology:A,problem:r,solution:s,mapping:wH(A,r)}})(this.serializedGraph),this.reservedRegionCount=((t,e)=\u003e{const n=t.problem.regionNetId;if(!n)return 0;const o=new Map;for(const t of e.regions){const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;Number.isInteger(e)\u0026\u0026e\u003e=0\u0026\u0026o.set(t.regionId,e)}let i=0;for(let e=0;e\u003ct.topology.regionCount;e++){const r=t.topology.regionMetadata?.[e],s=\"object\"==typeof r\u0026\u0026null!==r?r.serializedRegionId:void 0;if(\"string\"!=typeof s)continue;const a=o.get(s);void 0!==a\u0026\u0026(n[e]=a,i+=1)}return i})(this.loaded,this.serializedGraph);const i={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.max(1,Math.ceil(10*this.effort)),MAX_ITERATIONS:Math.max(1e5,Math.ceil(1e7*this.effort))};this.polySolver=new RH(this.loaded.topology,this.loaded.problem,i),this.activeSubSolver=this.polySolver,this.MAX_ITERATIONS=i.MAX_ITERATIONS+1e3,this.inputNodeWithPortPoints=this.createInputNodesWithPortPoints()}params;getSolverName(){return\"PolyHypergraphPortPointPathingSolver\"}convexRegions;serializedGraph;loaded;polySolver;inputNodeWithPortPoints=[];nodesWithPortPoints=[];reservedRegionCount=0;clearance;effort;usedUnconstrainedDelaunayFallback=!1;createInputNodesWithPortPoints(){const{topology:t}=this.loaded,e=[];for(let n=0;n\u003ct.regionCount;n++){const o=HH(t.regionMetadata?.[n]??{}),i=UH(o,n);if(i.startsWith(\"terminal-\"))continue;const r=(t.regionIncidentPorts[n]??[]).map(e=\u003e{const n=t.incidentPortRegion[e]??[],o=t.portMetadata?.[e];return{portPointId:ZH(o,e),x:t.portX[e],y:t.portY[e],z:t.portZ[e],...qH(o),connectionNodeIds:n.map(e=\u003eUH(t.regionMetadata?.[e],e)),distToCentermostPortOnZ:t.portMetadata?.[e]?.distToCentermostPortOnZ??0,connectsToOffBoardNode:!1}});e.push({capacityMeshNodeId:i,center:{x:t.regionCenterX[n],y:t.regionCenterY[n]},width:t.regionWidth[n],height:t.regionHeight[n],portPoints:r,availableZ:o.availableZ??Array.from({length:this.params.srj.layerCount},(t,e)=\u003ee),_containsObstacle:Boolean(o._containsObstacle),_containsTarget:Boolean(o._containsTarget)})}return e}createAssignedPortPoint(t,e){const n=this.polySolver.problem.routeMetadata?.[t],o=n?(t=\u003et.simpleRouteConnection?.name??t.connectionId)(n):`route-${t}`,i=n?(t=\u003et.simpleRouteConnection?.rootConnectionName??t.mutuallyConnectedNetworkId)(n):void 0,r=this.polySolver.topology.portMetadata?.[e];return{portPointId:ZH(r,e),x:this.polySolver.topology.portX[e],y:this.polySolver.topology.portY[e],z:this.polySolver.topology.portZ[e],connectionName:o,rootConnectionName:i,...qH(r)}}buildOutputNodes(){const{topology:t,state:e}=this.polySolver,n=[];for(let o=0;o\u003ce.regionSegments.length;o++){const i=HH(t.regionMetadata?.[o]??{}),r=UH(i,o);if(r.startsWith(\"terminal-\"))continue;const s=JH(i);if(!s)continue;const a=(e.regionSegments[o]??[]).flatMap(([t,e,n])=\u003e{const o=this.createAssignedPortPoint(t,e),i=this.createAssignedPortPoint(t,n);return o.portPointId\u0026\u0026i.portPointId\u0026\u0026(o.nextPortPointId=i.portPointId,i.prevPortPointId=o.portPointId),[o,i]});0!==a.length\u0026\u0026n.push({capacityMeshNodeId:r,center:{x:t.regionCenterX[o],y:t.regionCenterY[o]},width:t.regionWidth[o],height:t.regionHeight[o],polygon:s,portPoints:a,availableZ:i.availableZ})}this.nodesWithPortPoints=n}_step(){this.polySolver.step(),this.progress=this.polySolver.progress,this.stats={...this.polySolver.stats??{},reservedRegionCount:this.reservedRegionCount,usedUnconstrainedDelaunayFallback:this.usedUnconstrainedDelaunayFallback,regionCount:this.loaded.topology.regionCount,portCount:this.loaded.topology.portCount,routeCount:this.loaded.problem.routeCount},this.polySolver.solved?(this.buildOutputNodes(),this.solved=!0,this.activeSubSolver=null):this.polySolver.failed\u0026\u0026(this.error=this.polySolver.error,this.failed=!0,this.activeSubSolver=null)}getOutput(){return{nodesWithPortPoints:this.nodesWithPortPoints,inputNodeWithPortPoints:this.inputNodeWithPortPoints}}computeNodePf(t){const e=this.nodesWithPortPoints.find(e=\u003ee.capacityMeshNodeId===t.capacityMeshNodeId);if(!e)return null;const n=Ms(e);return Ys({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,layer:\"top\",availableZ:e.availableZ??[]},n.numSameLayerCrossings,n.numEntryExitLayerChanges,n.numTransitionPairCrossings)}getConstructorParams(){return[this.params]}preview(){return this.visualize()}visualize(){return this.polySolver.visualize()}},QH=class extends si{constructor(t){super(),this.inputSrj=t,this.MAX_ITERATIONS=1}inputSrj;outputSrj;_step(){this.outputSrj=mX(this.inputSrj)??this.inputSrj,this.solved=!0}getOutputSimpleRouteJson(){if(!this.outputSrj)throw new Error(\"PreprocessSimpleRouteJsonSolver has not solved yet\");return this.outputSrj}getConstructorParams(){return[this.inputSrj]}visualize(){return this.outputSrj?pi(Ho({...this.outputSrj,traces:[]}),Yj({srj:this.outputSrj})):{lines:[],points:[],rects:[],circles:[]}}},tG=(t,e)=\u003e(t.x-e.x)**2+(t.y-e.y)**2,eG=(t,e,n)=\u003e{if(!n)return;const o=t.filter(({projected:t})=\u003et.connectionName===e\u0026\u0026(void 0===n.z||t.z===n.z));return 0!==o.length?o.reduce((t,e)=\u003etG(e.projected,n)\u003ctG(t.projected,n)?e:t).original:void 0},nG=(t,e)=\u003e{const n=e.projectedRect;if(!n)throw new Error(\"Poly node is missing projectedRect\");const o=n.rectToPolygonMatrix,i=(t=\u003e{if(!t.projectedRect)throw new Error(\"Poly node is missing projectedRect\");return t.portPoints.map(e=\u003e{const n=ZX(e,t.projectedRect);return{original:e,projected:{...e,x:n.x,y:n.y}}})})(e),r=t.route.map(t=\u003e({...t,...HX(o,t)})),s=t.vias.map(t=\u003eHX(o,t)),a=eG(i,t.connectionName,t.route[0]),c=eG(i,t.connectionName,t.route[t.route.length-1]);return a\u0026\u0026r[0]\u0026\u0026(r[0]={...r[0],x:a.x,y:a.y,z:a.z}),c\u0026\u0026r[r.length-1]\u0026\u0026(r[r.length-1]={...r[r.length-1],x:c.x,y:c.y,z:c.z}),{...t,route:r,vias:s,jumpers:t.jumpers?.map(t=\u003e({...t,start:HX(o,t.start),end:HX(o,t.end)}))}},oG=class extends si{getSolverName(){return\"ProjectHighDensityToPolygonSolver\"}routes=[];routesByNodeId=new Map;colorMap;nodePortPoints;rawRoutesByNodeId;constructor({nodePortPoints:t,routesByNodeId:e,colorMap:n}){super(),this.MAX_ITERATIONS=1,this.nodePortPoints=t,this.rawRoutesByNodeId=e instanceof Map?new Map(e):new Map(Object.entries(e)),this.colorMap=n??{}}_step(){this.routes=[],this.routesByNodeId=new Map;for(const t of this.nodePortPoints){const e=(this.rawRoutesByNodeId.get(t.capacityMeshNodeId)??[]).map(e=\u003enG(e,t));e.length\u003e0\u0026\u0026(this.routesByNodeId.set(t.capacityMeshNodeId,e),this.routes.push(...e))}this.solved=!0}getOutput(){return this.routes}getConstructorParams(){return[{nodePortPoints:this.nodePortPoints,routesByNodeId:this.rawRoutesByNodeId,colorMap:this.colorMap}]}visualize(){const t={polygons:this.nodePortPoints.flatMap(t=\u003e[{points:t.polygon,fill:\"rgba(40, 140, 220, 0.06)\",stroke:\"rgba(20, 70, 160, 0.65)\",label:`${t.capacityMeshNodeId} polygon`},...t.projectedRect?[{points:t.projectedRect.targetQuad,fill:\"rgba(255, 165, 0, 0.05)\",stroke:\"rgba(255, 120, 0, 0.45)\",label:`${t.capacityMeshNodeId} projection target`}]:[]]),lines:[],circles:[]};for(const e of this.routes){const n=this.colorMap[e.connectionName]??\"#0000ff\",o=mi(e.route,e.connectionName,n);for(const n of o)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:To(n.color,.5),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?[.1,.3]:void 0});for(const o of e.vias)t.circles.push({center:o,layer:\"z0,1\",radius:e.viaDiameter/2,fill:n,label:`${e.connectionName} via`})}return t}};function iG(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var rG=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),this.equivalentAreaExpansionFactor=n.equivalentAreaExpansionFactor??2,this.minProjectedRectDimension=n.minProjectedRectDimension??3*this.minTraceWidth,void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;polyGraphSolver;attachProjectedRectsSolver;highDensityRouteSolver;projectHighDensityToPolgonSolver;highDensityStitchSolver;traceSimplificationSolver;traceWidthSolver;globalDrcForceImproveSolver;colorMap;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;equivalentAreaExpansionFactor;minProjectedRectDimension;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;highDensityNodePortPoints;projectedHighDensityNodePortPoints;cacheProvider=null;pipelineDef=[iG(\"preprocessSimpleRouteJsonSolver\",QH,t=\u003e[t.originalSrj],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),iG(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),iG(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),iG(\"polyGraphSolver\",KH,t=\u003e[{srj:t.srjWithPointPairs,effort:t.effort,concavityTolerance:t.opts.polyConcavityTolerance,portSpacing:t.opts.polyPortSpacing,portMarginFromSegmentEndpoint:t.opts.polyPortMarginFromSegmentEndpoint}],{onSolved:t=\u003e{t.highDensityNodePortPoints=t.polyGraphSolver?.getOutput().nodesWithPortPoints??[]}}),iG(\"attachProjectedRectsSolver\",JX,t=\u003e[{nodesWithPortPoints:t.highDensityNodePortPoints??[],equivalentAreaExpansionFactor:t.equivalentAreaExpansionFactor,minProjectedRectDimension:t.minProjectedRectDimension,traceWidth:t.minTraceWidth,viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.projectedHighDensityNodePortPoints=t.attachProjectedRectsSolver?.getOutput()??[]}}),iG(\"highDensityRouteSolver\",QX,t=\u003e[{nodePortPoints:t.projectedHighDensityNodePortPoints??[],nodePfById:new Map((t.polyGraphSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.polyGraphSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,effort:t.effort}]),iG(\"projectHighDensityToPolgonSolver\",oG,t=\u003e[{nodePortPoints:t.projectedHighDensityNodePortPoints??[],routesByNodeId:t.highDensityRouteSolver.routesByNodeId,colorMap:t.colorMap}]),iG(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.projectHighDensityToPolgonSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),iG(\"traceSimplificationSolver\",vc,t=\u003e[{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}]),iG(\"traceWidthSolver\",Ic,t=\u003e[{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}]),iG(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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\u0026\u0026(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\"}getProblemVisualization({includeRoutes:t=!0}={}){const e=this.originalSrj,n=[{points:[{x:e.bounds?.minX??-50,y:e.bounds?.minY??-50},{x:e.bounds?.maxX??50,y:e.bounds?.minY??-50},{x:e.bounds?.maxX??50,y:e.bounds?.maxY??50},{x:e.bounds?.minX??-50,y:e.bounds?.maxY??50},{x:e.bounds?.minX??-50,y:e.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}];if(e.outline\u0026\u0026e.outline.length\u003e=2){const t=e.outline.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),n.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const o=Oo(e),i={points:[...e.connections.flatMap(t=\u003et.pointsToConnect.map(n=\u003e({...n,layer:Fo(n,e.layerCount),label:`${t.name} ${n.pcb_port_id??\"\"}`})))],rects:[...(e.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,e.layerCount),label:o(t)}))],lines:n};if(!t)return i;const r=Yj({srj:e});return pi(i,r)}visualize(){if(!this.solved\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.getProblemVisualization(),e=this.getProblemVisualization({includeRoutes:!1}),n=this.polyGraphSolver?.visualize(),o=this.attachProjectedRectsSolver?.visualize(),i=this.highDensityRouteSolver?.visualize(),r=this.projectHighDensityToPolgonSolver?.visualize(),s=this.highDensityStitchSolver?.visualize(),a=this.traceSimplificationSolver?.visualize();return pi(...[t,this.escapeViaLocationSolver?.visualize(),this.netToPointPairsSolver?.visualize(),n,o,i?pi(e,i):null,r?pi(e,r):null,s,a,this.solved?pi({lines:e.lines},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean))}preview(){if(this.projectHighDensityToPolgonSolver){const t=[];for(let e=this.projectHighDensityToPolgonSolver.routes.length-1;e\u003e=0;e--){const n=this.projectHighDensityToPolgonSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.polyGraphSolver?this.polyGraphSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){return this.globalDrcForceImproveSolver?.getOutput()??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 o=n.__netConnectionName??this.originalSrj.connections.find(t=\u003et.name===n.name)?.__netConnectionName,i=e.filter(t=\u003et.connectionName===n.name);for(let e=0;e\u003ci.length;e++){const r=i[e],s={type:\"pcb_trace\",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},sG=t=\u003et.rootConnectionName??t.connectionName,aG=(t,e)=\u003et.flatMap((t,n)=\u003esG(t)===e?[n]:[]),cG=(t,e,n,o)=\u003e{const i=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=t.x-e.x,s=t.y-e.y,a=o**2+i**2,c=0===a?0:Math.max(0,Math.min(1,(r*o+s*i)/a));return Math.hypot(t.x-(e.x+c*o),t.y-(e.y+c*i))},r={x:e.x-t.x,y:e.y-t.y},s={x:o.x-n.x,y:o.y-n.y},a={x:n.x-t.x,y:n.y-t.y},c=(t,e)=\u003et.x*e.y-t.y*e.x,l=c(r,s),d=Math.hypot(r.x,r.y),h=1e-12*(d*Math.hypot(s.x,s.y)+1);if(Math.abs(l)\u003eh){const t=c(a,s)/l,e=c(a,r)/l;if(t\u003e=-1e-12\u0026\u0026t\u003c=1+1e-12\u0026\u0026e\u003e=-1e-12\u0026\u0026e\u003c=1+1e-12)return 0}else if(d\u003e1e-12\u0026\u0026Math.abs(c(a,r))\u003c=h){const i=Math.abs(r.x)\u003e=Math.abs(r.y),s=Math.min(i?t.x:t.y,i?e.x:e.y),a=Math.max(i?t.x:t.y,i?e.x:e.y),c=Math.min(i?n.x:n.y,i?o.x:o.y),l=Math.max(i?n.x:n.y,i?o.x:o.y);if(Math.max(s,c)\u003c=Math.min(a,l)+1e-12)return 0}return Math.min(i(t,n,o),i(e,n,o),i(n,t,e),i(o,t,e))},lG=(t,e)=\u003eMath.hypot(e.x-t.x,e.y-t.y),dG=t=\u003e{let e=0;for(let n=0;n\u003ct.route.length-1;n++)e+=lG(t.route[n],t.route[n+1]);return e},hG=(t,e)=\u003ee.reduce((e,n)=\u003ee+dG(t[n]),0),uG=(t,e)=\u003e{const n=t.__zLayers,o=t.zLayers,i=void 0!==n?n:o;if(void 0!==i){if(!Array.isArray(i)||0===i.length||i.some(t=\u003e!Number.isInteger(t)||t\u003c0||t\u003e=e))throw new Error(\"Obstacle has invalid z-layer indexes\");return i}if(0===t.layers.length)throw new Error(\"Obstacle has no declared layers\");return t.layers.map(t=\u003e{if(\"top\"===t)return 0;if(\"bottom\"===t)return e-1;const n=/^inner(\\d+)$/.exec(t),o=n?Number(n[1]):-1;if(o\u003c=0||o\u003e=e-1)throw new Error(`Obstacle has invalid layer name \"${t}\"`);return o})},pG=t=\u003e{const e=(t,e,n,o)=\u003e{const i=n.center.x-n.width/2-o,r=n.center.x+n.width/2+o,s=n.center.y-n.height/2-o,a=n.center.y+n.height/2+o;if(t.x\u003e=i\u0026\u0026t.x\u003c=r\u0026\u0026t.y\u003e=s\u0026\u0026t.y\u003c=a||e.x\u003e=i\u0026\u0026e.x\u003c=r\u0026\u0026e.y\u003e=s\u0026\u0026e.y\u003c=a)return!0;const c=[{x:i,y:s},{x:r,y:s},{x:r,y:a},{x:i,y:a}];return c.some((n,o)=\u003e0===cG(t,e,n,c[(o+1)%c.length]))};if(t.bounds\u0026\u0026t.meanderPoints.some(e=\u003ee.x\u003ct.bounds.minX||e.x\u003et.bounds.maxX||e.y\u003ct.bounds.minY||e.y\u003et.bounds.maxY))return!1;const n=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},o=sG(t.route),i=t.route.traceThickness/2+t.obstacleMargin;for(let r=0;r\u003ct.meanderPoints.length-1;r++){const s=t.meanderPoints[r],a=t.meanderPoints[r+1];for(const n of t.obstacles){if(!uG(n,t.layerCount).includes(s.z))continue;const c=0===r||r===t.meanderPoints.length-2;if((!n.connectedTo.includes(o)||!c)\u0026\u0026e(s,a,n,i))return!1}for(const e of t.routedRoutes){const i=sG(e)===o;for(const o of e.vias){if(o.zLayers\u0026\u0026!o.zLayers.includes(s.z))continue;const r=Math.hypot(o.x-s.x,o.y-s.y)\u003c=1e-8||Math.hypot(o.x-a.x,o.y-a.y)\u003c=1e-8,c=t.route.traceThickness/2+e.viaDiameter/2+t.obstacleMargin;if((!i||!r)\u0026\u0026n(o,s,a)\u003cc)return!1}if(!i)for(let n=0;n\u003ce.route.length-1;n++){const o=e.route[n],i=e.route[n+1];if(s.z!==o.z||s.z!==i.z)continue;const r=t.route.traceThickness/2+e.traceThickness/2+t.obstacleMargin;if(cG(s,a,o,i)\u003cr)return!1}}}return!0},mG=t=\u003e{const e=[];for(const n of t.routeIndexes){const o=t.routes[n],i=t.minMeanderGap??Math.max(.3,2*o.traceThickness),r=o.traceThickness+i,s=Math.max(t.minimumToothPitch??0,2*r),a=t.minMeanderHeight??r;for(let i=0;i\u003co.route.length-1;i++){const r=o.route[i],c=o.route[i+1],l=lG(r,c);if(l\u003c=0||r.z!==c.z)continue;const d=Math.min(Math.max(0,Math.floor(l/s)-1),t.maxToothCount);for(let o=1;o\u003c=d;o++){const r=l/(o+1),c=[r,Math.sqrt(s*r),s].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e-t)\u003c1e-9)===e),d=o%2==0?[\"balanced\",\"negative\",\"positive\"]:[\"negative\",\"positive\"];for(const r of c)for(const s of d)e.push({routeIndex:n,segmentIndex:i,segmentLength:l,toothCount:o,maximumDepth:t.maximumDepth,minimumHeight:a,toothPitch:r,placement:s,heightProfile:o\u003e1?\"tapered\":\"uniform\"})}}}const n={balanced:0,negative:1,positive:2};return e.sort((t,e)=\u003et.toothCount-e.toothCount||n[t.placement]-n[e.placement]||e.toothPitch-t.toothPitch||e.segmentLength-t.segmentLength)},gG=t=\u003e{if(null===t.centerlineDistanceCost)return 0;const e=t.predictedToothDepths.flatMap((t,e)=\u003et\u003e0?[e]:[]);if(0===e.length)return 0;const n=e.map(e=\u003et.predictedToothDepths[e]),o=Math.max(...n),i=n.reduce((t,e)=\u003et+e,0)/n.length,r=Math.sqrt(n.reduce((t,e)=\u003et+(e-i)**2,0)/n.length),s=e[0],a=(e.at(-1)-s+1)*t.toothPitch,c=o/(t.toothPitch/2),l=t.addedLength/a,d=c/(1+c)*40,h=l/(1+l)*30,u=t.predictedToothDepths.map((e,n)=\u003eMath.sin(Math.PI*(n+1)/(t.predictedToothDepths.length+1))),p=Math.max(...u),m=Math.sqrt(t.predictedToothDepths.reduce((t,e,n)=\u003et+(e-o*u[n]/p)**2,0)/t.predictedToothDepths.length),g=100-d-h-Math.min(10,(\"tapered\"===t.heightProfile?m:r)/i*10)-2*(n.length-1)-7*Math.min(1,t.addedLength/t.segmentLength)-100*t.centerlineDistanceCost,f=t.centerlineDistanceCost\u003e0?g:Math.max(0,g);return Math.round(1e6*f)/1e6},fG=t=\u003e{if(t.toothDepths.length!==t.toothCount)throw new Error(`LengthMatchingSolver: expected ${t.toothCount} tooth depths, received ${t.toothDepths.length}`);if(t.toothDepths.some(t=\u003e!Number.isFinite(t)||t\u003c0))throw new Error(\"LengthMatchingSolver: every meander tooth depth must be a non-negative finite number\");const e=t.route.route[t.segmentIndex],n=t.route.route[t.segmentIndex+1],o=lG(e,n),i=(n.x-e.x)/o,r=(n.y-e.y)/o,s=(o-(t.toothCount-.5)*t.toothPitch)/2,a=[{...e}];for(let n=0;n\u003ct.toothCount;n++){const o=t.toothDepths[n];if(0===o)continue;const c=\"balanced\"===t.placement?n%2==0?-1:1:\"negative\"===t.placement?-1:1,l={x:-r*c,y:i*c},d=s+n*t.toothPitch,h=d+t.toothPitch/2,u={...e,x:e.x+i*d,y:e.y+r*d};a.push(u,{...u,x:u.x+l.x*o,y:u.y+l.y*o},{...e,x:e.x+i*h+l.x*o,y:e.y+r*h+l.y*o},{...e,x:e.x+i*h,y:e.y+r*h})}return a.push({...n}),(t=\u003e{if(t.length\u003c3)return t;const e=[{...t[0]}];for(let n=1;n\u003ct.length-1;n++){const o=t[n-1],i=t[n],r=t[n+1],s=Math.hypot(i.x-o.x,i.y-o.y),a=Math.hypot(r.x-i.x,r.y-i.y);if(0===s||0===a)throw new Error(\"LengthMatchingSolver: meander contains a zero-length segment\");const c={x:(i.x-o.x)/s,y:(i.y-o.y)/s},l={x:(r.x-i.x)/a,y:(r.y-i.y)/a};if(Math.abs(c.x*l.y-c.y*l.x)\u003c1e-9){e.push({...i});continue}const d=Math.min(s,a)/2,h={...i,x:i.x-c.x*d,y:i.y-c.y*d},u={...i,x:i.x+l.x*d,y:i.y+l.y*d},p=e.at(-1);h.x===p.x\u0026\u0026h.y===p.y||e.push(h);for(let t=1;t\u003c6;t++){const n=t/6,o=1-n;e.push({...i,x:o**2*h.x+2*o*n*i.x+n**2*u.x,y:o**2*h.y+2*o*n*i.y+n**2*u.y})}e.push(u)}return e.push({...t[t.length-1]}),e})(a)},yG=t=\u003e[...t.route.route.slice(0,t.segmentIndex),...fG(t),...t.route.route.slice(t.segmentIndex+2)],_G=t=\u003e{const e=dG(t.route),n=(()=\u003e{const e=[];for(let n=0;n\u003ct.candidate.toothCount;n++){const o=Array(t.candidate.toothCount).fill(0);o[n]=t.candidate.maximumDepth;const i=fG({...t.candidate,route:t.route,toothDepths:o});if(t.isGeometryValid(i)){e.push(t.candidate.maximumDepth);continue}let r=0,s=t.candidate.maximumDepth;for(let e=0;e\u003c32;e++){const e=(r+s)/2,o=Array(t.candidate.toothCount).fill(0);o[n]=e;const i=fG({...t.candidate,route:t.route,toothDepths:o});t.isGeometryValid(i)?r=e:s=e}e.push(r)}return e})(),o=(t=\u003e{if(\"tapered\"!==t.heightProfile)return Array(t.toothCount).fill(1);const e=Array.from({length:t.toothCount},(e,n)=\u003eMath.sin(Math.PI*(n+1)/(t.toothCount+1))),n=Math.max(...e);return e.map(t=\u003et/n)})(t.candidate),i=t.candidate.maximumDepth,r=n.map((t,e)=\u003eMath.min(t,i*o[e])),s=[.25,.75],a=r.map(t=\u003et*s[0]),c=r.map(t=\u003et*s[1]),l=yG({...t.candidate,route:t.route,toothDepths:a}),d=yG({...t.candidate,route:t.route,toothDepths:c}),h=[dG({...t.route,route:l})-e,dG({...t.route,route:d})-e],u=yG({...t.candidate,route:t.route,toothDepths:r}),p=dG({...t.route,route:u})-e,m=(h[1]-h[0])/(s[1]-s[0]),g=h[0]-m*s[0],f=m\u003e0\u0026\u0026Number.isFinite(m)?(t.targetAddedLength-g)/m:0,y=Math.min(t.targetAddedLength,p),_=t.targetAddedLength\u003e0\u0026\u0026y\u003e0?(e=\u003e{let n=0,o=t.candidate.maximumDepth;for(let i=0;i\u003c32;i++){const i=(n+o)/2,r=e.maximumToothDepths.map((t,n)=\u003eMath.min(t,i*e.toothHeightWeights[n])),s=yG({...t.candidate,route:t.route,toothDepths:r}),a=dG({...t.route,route:s})-e.originalLength,c=fG({...t.candidate,route:t.route,toothDepths:r});t.isGeometryValid(c)?a\u003ce.targetAddedLength?n=i:o=i:o=i}const i=(n+o)/2;return{depthLevel:i,toothDepths:e.maximumToothDepths.map((t,n)=\u003eMath.min(t,i*e.toothHeightWeights[n]))}})({maximumToothDepths:n,toothHeightWeights:o,originalLength:e,targetAddedLength:y}):{depthLevel:f*i,toothDepths:r.map(t=\u003eMath.max(0,t*f))},b=_.depthLevel/i,x=_.toothDepths,v=yG({...t.candidate,route:t.route,toothDepths:x}),S=dG({...t.route,route:v})-e,I=Math.abs(y-S),C=fG({...t.candidate,route:t.route,toothDepths:x});let P=0;if(t.getCenterlineDistanceCost\u0026\u0026(P=t.getCenterlineDistanceCost(C)),null!==P\u0026\u0026(!Number.isFinite(P)||P\u003c0))throw new Error(\"LengthMatchingSolver: meander centerline distance cost must be a non-negative finite number\");const M=Number.isFinite(b)\u0026\u0026b\u003e0\u0026\u0026b\u003c=1,N=x.every(e=\u003e0===e||e\u003e=t.candidate.minimumHeight),w=t.isGeometryValid(C);let T,R=null;null===P?R=\"no-paired-same-layer-geometry\":M?I\u003et.lengthTolerance?R=\"target-error\":w?N||(R=\"below-minimum-height\"):R=\"invalid-geometry\":R=\"invalid-scale\",T=R?{valid:!1,invalidReason:R}:{valid:!0,invalidReason:null};const E={...t.candidate,connectionName:t.connectionName,maximumToothDepths:n,sampleScaleFactors:s,sampleAddedLengths:h,slope:m,intercept:g,predictedScaleFactor:b,predictedToothDepths:x,predictedRoute:v,addedLength:S,maximumAddedLength:p,resultingError:I,testedSegment:[{...t.route.route[t.candidate.segmentIndex]},{...t.route.route[t.candidate.segmentIndex+1]}],meanderPoints:C,centerlineDistanceCost:P,qualityScore:0,...T};return{...E,qualityScore:gG(E)}},bG=t=\u003e{const e=(t=\u003e{if(\"tapered\"!==t.heightProfile)return Array(t.toothCount).fill(1);const e=Array.from({length:t.toothCount},(e,n)=\u003eMath.sin(Math.PI*(n+1)/(t.toothCount+1))),n=Math.max(...e);return e.map(t=\u003et/n)})(t.candidate),n=Math.max(...e.map(e=\u003et.candidate.minimumHeight/e)),o=t.candidate.maximumDepth/2**30,i=e.map(t=\u003et*(n+o));if(i.some(e=\u003ee\u003et.candidate.maximumDepth))return null;const r=fG({...t.candidate,route:t.route,toothDepths:i});if(!t.isGeometryValid(r))return null;const s=yG({...t.candidate,route:t.route,toothDepths:i}),a=dG({...t.route,route:s})-dG(t.route),c=_G({...t,targetAddedLength:a});return c.valid?c:null},xG=t=\u003e{const e=(t,e)=\u003e{const n=t[e.routeIndex];if(!n)throw new Error(`LengthMatchingSolver: dual meander references missing route ${e.routeIndex}`);const o=[...t];return o[e.routeIndex]={...n,route:e.predictedRoute},o},n=(()=\u003e{if(t.targetAddedLength+t.config.lengthTolerance\u003ct.plan.minimumAddedLength||t.targetAddedLength-t.config.lengthTolerance\u003et.plan.maximumAddedLength)return null;const e=t.plan.attemptOptions.map(t=\u003eMath.min(...t.map(t=\u003et.attempt.addedLength)));let n=Math.max(0,t.targetAddedLength-t.plan.minimumAddedLength),o=e.map((t,e)=\u003ee);for(;n\u003e1e-9\u0026\u0026o.length\u003e0;){const i=n/o.length;let r=0;const s=[];for(const n of o){const o=Math.max(...t.plan.attemptOptions[n].map(t=\u003et.attempt.maximumAddedLength))-e[n],a=Math.min(o,i);e[n]+=a,r+=a,o-a\u003e1e-9\u0026\u0026s.push(n)}if(r\u003c=1e-9)break;n-=r,o=s}return n\u003c=t.config.lengthTolerance?e:null})();if(!n)return null;const o=t.plan.attemptOptions.map((t,e)=\u003e({attemptOptions:t,targetAddedLength:n[e]})).sort((t,e)=\u003ee.attemptOptions[0].candidate.routeIndex-t.attemptOptions[0].candidate.routeIndex||e.attemptOptions[0].candidate.segmentIndex-t.attemptOptions[0].candidate.segmentIndex);let i=[...t.routes];const r=[];for(const n of o){const o=n.attemptOptions[0]?.candidate;if(!o)throw new Error(\"LengthMatchingSolver: empty dual-meander segment options\");const s=i[o.routeIndex];if(!s)throw new Error(`LengthMatchingSolver: missing planned dual-meander route ${o.routeIndex}`);let a=null;for(const e of n.attemptOptions){if(e.attempt.addedLength-t.config.lengthTolerance\u003en.targetAddedLength||e.attempt.maximumAddedLength+t.config.lengthTolerance\u003cn.targetAddedLength)continue;const o=_G({candidate:e.candidate,route:s,connectionName:t.connectionName,targetAddedLength:n.targetAddedLength,lengthTolerance:t.config.lengthTolerance,isGeometryValid:e=\u003epG({route:s,meanderPoints:e,routedRoutes:t.excludedConnectionName?i.filter(e=\u003esG(e)!==t.excludedConnectionName):i,...t.config})});o.valid\u0026\u0026(!a||o.qualityScore\u003ea.qualityScore)\u0026\u0026(a=o)}if(!a)return null;i=e(i,a),r.push(a)}const s=r.reduce((t,e)=\u003et+e.addedLength,0);if(Math.abs(s-t.targetAddedLength)\u003et.config.lengthTolerance)return null;const a=r[0];if(!a)throw new Error(\"LengthMatchingSolver: fitted an empty dual-meander plan\");return{attempts:[a,...r.slice(1)],routes:i,addedLength:s}},vG=t=\u003e{if(0===t.length)throw new Error(\"LengthMatchingSolver: cannot score an empty meander plan\");return t.reduce((t,e)=\u003et+e.qualityScore,0)/t.length-3*(t.length-1)},SG=t=\u003e{const e=t=\u003e[t.candidate.toothCount,t.candidate.placement,t.candidate.heightProfile].join(\":\"),n=new Map;for(const o of t){const t=e(o),i=`${o.candidate.routeIndex}:${o.candidate.segmentIndex}`,r=n.get(t);if(!r){n.set(t,new Map([[i,[o]]]));continue}const s=r.get(i);s?s.push(o):r.set(i,[o])}const o=[];for(const t of n.values()){const e=[...t.values()].map(t=\u003e({attempts:t,maximumAddedLength:Math.max(...t.map(t=\u003et.attempt.maximumAddedLength)),minimumAddedLength:Math.min(...t.map(t=\u003et.attempt.addedLength)),rankingAttempt:t.reduce((t,e)=\u003ee.attempt.qualityScore\u003et.attempt.qualityScore?e:t)})).sort((t,e)=\u003ee.maximumAddedLength-t.maximumAddedLength);for(const t of e)o.push({attempts:[t.rankingAttempt],attemptOptions:[t.attempts],minimumAddedLength:t.minimumAddedLength,maximumAddedLength:t.maximumAddedLength,rankingQualityScore:t.rankingAttempt.attempt.qualityScore});for(let t=2;t\u003c=e.length;t++){const n=e.slice(0,t),i=n.map(t=\u003et.rankingAttempt);o.push({attempts:i,attemptOptions:n.map(t=\u003et.attempts),minimumAddedLength:n.reduce((t,e)=\u003et+e.minimumAddedLength,0),maximumAddedLength:n.reduce((t,e)=\u003et+e.maximumAddedLength,0),rankingQualityScore:vG(i.map(t=\u003et.attempt))})}}return o},IG=class extends Error{connectionName;reason;constructor(t){super(t.message),this.name=\"LengthMatchingNoSolutionError\",this.connectionName=t.connectionName,this.reason=t.reason}},CG=t=\u003e[t.routeIndex,t.segmentIndex,t.toothCount,t.placement,t.toothPitch,t.heightProfile,t.maximumDepth,t.minimumHeight].join(\":\"),PG=t=\u003e{const e=new Map,n=[...t.attempts].sort((t,e)=\u003et.addedLength-e.addedLength);let o=t.targetAddedLength;for(let t=0;t\u003cn.length;t++){const i=n[t],r=Math.min(i.addedLength,o/(n.length-t));e.set(CG(i),{routeIndex:i.routeIndex,segmentIndex:i.segmentIndex,targetAddedLength:r}),o-=r}return e},MG=(t,e)=\u003e`z${uG(t,e).join(\",\")}`,NG=t=\u003e`z${t}`,wG=t=\u003e{if(!t.showAttempt)return;if(!t.attempt)return void(t=\u003e{const e=t.activePair?.candidates[t.activePair.candidateIndex];if(!e)return;const n=t.routes[e.routeIndex];if(!n)return;const o=n.route[e.segmentIndex],i=n.route[e.segmentIndex+1];o\u0026\u0026i\u0026\u0026t.graphics.lines.push({points:[o,i],strokeColor:\"rgba(234, 179, 8, 0.6)\",strokeWidth:2*n.traceThickness,strokeDash:[.1,.1],layer:NG(o.z)})})(t);const e=t.routes[t.attempt.routeIndex],[n,o]=t.attempt.testedSegment,i=t.theme.getConnectionColor(t.attempt.connectionName);t.graphics.lines.push({points:[n,o],strokeColor:t.theme.getTestedSegmentColor(i),strokeWidth:e.traceThickness,strokeDash:[.15,.15],layer:NG(n.z)}),t.attempt.valid?t.graphics.lines.push({points:t.attempt.meanderPoints.map(({x:t,y:e})=\u003e({x:t,y:e})),strokeColor:\"rgba(234, 179, 8, 0.6)\",strokeWidth:2*e.traceThickness,strokeDash:[.1,.1],layer:NG(n.z)}):t.graphics.lines.push({points:t.attempt.meanderPoints.map(({x:t,y:e})=\u003e({x:t,y:e})),strokeColor:t.theme.getRejectedCandidateColor(i),strokeWidth:e.traceThickness,strokeDash:[.1,.1],layer:NG(n.z)}),t.graphics.points.push({x:n.x,y:n.y,color:i,layer:NG(n.z)},{x:o.x,y:o.y,color:i,layer:NG(o.z)})},TG=t=\u003e{const e={lines:[],points:[],rects:[],circles:[]},n=(t=\u003e{for(const e of Object.values(t))Tt(0,e);return{getConnectionColor:(e,n)=\u003et[e]??(n?t[n]:void 0)??(t=\u003et?`hsl(${300*t.split(\"\").reduce((t,e)=\u003et+e.charCodeAt(0),0)/t.length%360}, 100%, 50%)`:\"rgba(0, 0, 0, 0.5)\")(e),getInnerLayerConnectionColor:t=\u003eTt(.5,t),getTestedSegmentColor:t=\u003eTt(.55,t),getRejectedCandidateColor:t=\u003eTt(.45,t),boardBounds:{fill:\"rgba(30,41,59,0.03)\",stroke:\"rgba(30,41,59,0.55)\"},obstacle:{fill:\"rgba(255,0,0,0.25)\",stroke:\"rgba(255,0,0,0.5)\"},via:{fill:\"blue\",stroke:\"none\"}}})(t.colorMap);return(t=\u003e{for(const e of t.routes){const n=sG(e),o=t.theme.getConnectionColor(n,e.connectionName);for(let n=0;n\u003ce.route.length-1;n++){const i=e.route[n],r=e.route[n+1];i.z===r.z\u0026\u0026t.graphics.lines.push({points:[i,r],strokeColor:0===i.z?o:t.theme.getInnerLayerConnectionColor(o),strokeWidth:e.traceThickness,...0===i.z?{}:{strokeDash:[.2,.2]},layer:NG(i.z)})}const i=[...new Set(e.route.map(t=\u003et.z))];for(const n of e.vias)t.graphics.circles.push({center:n,radius:e.viaDiameter/2,fill:t.theme.via.fill,stroke:t.theme.via.stroke,layer:`z${(n.zLayers??i).join(\",\")}`})}})({routes:t.routes,theme:n,graphics:e}),(t=\u003e{if(t.bounds){const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds;t.graphics.rects.push({center:{x:(e+n)/2,y:(o+i)/2},width:n-e,height:i-o,fill:t.theme.boardBounds.fill,stroke:t.theme.boardBounds.stroke,layer:`z${Array.from({length:t.layerCount},(t,e)=\u003ee).join(\",\")}`})}for(const e of t.obstacles)t.graphics.rects.push({center:e.center,width:e.width,height:e.height,ccwRotationDegrees:e.ccwRotationDegrees,fill:t.theme.obstacle.fill,stroke:t.theme.obstacle.stroke,layer:MG(e,t.layerCount)})})({obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,theme:n,graphics:e}),wG({routes:t.routes,attempt:t.currentAttempt,activePair:t.activePair,showAttempt:!t.solved,theme:n,graphics:e}),{...e}},RG=class extends kt{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1e5,this.matchedHdRoutes=t.hdRoutes.map(t=\u003e({...t,route:t.route.map(t=\u003e({...t}))})),this.pairs=t.differentialPairs??[]}params;matchedHdRoutes;pairs;nextPairIndex=0;activePair=null;currentAttempt=null;config=null;candidatesTried=0;getSolverName(){return\"LengthMatchingSolver\"}startNextPair(){const t=this.pairs[this.nextPairIndex++];if(!t)return void(this.solved=!0);((t,e)=\u003e{if(t.connectionNames[0]===t.connectionNames[1])throw new Error(\"LengthMatchingSolver: a differential pair must reference two distinct connections\");if(!Number.isFinite(t.lengthTolerance)||t.lengthTolerance\u003c0)throw new Error(\"LengthMatchingSolver: differential pair lengthTolerance must be a non-negative finite number\");for(const e of[t.minimumCenterlineDistance,t.maximumCenterlineDistance])if(void 0!==e\u0026\u0026(!Number.isFinite(e)||e\u003c=0))throw new Error(\"LengthMatchingSolver: differential pair centerline distances must be positive finite numbers\");if(void 0!==t.minimumCenterlineDistance\u0026\u0026void 0!==t.maximumCenterlineDistance\u0026\u0026t.minimumCenterlineDistance\u003et.maximumCenterlineDistance)throw new Error(\"LengthMatchingSolver: differential pair minimumCenterlineDistance cannot exceed maximumCenterlineDistance\");const n=new Map(e.map(t=\u003e[t.name,t]));for(const e of t.connectionNames){const t=n.get(e);if(!t)throw new Error(`LengthMatchingSolver: differential pair references unknown connection \"${e}\"`);if(2!==t.pointsToConnect.length)throw new Error(`LengthMatchingSolver: differential pair connection \"${e}\" must have exactly two points before MST splitting`)}})(t,this.params.originalConnections);const e=aG(this.matchedHdRoutes,t.connectionNames[0]),n=aG(this.matchedHdRoutes,t.connectionNames[1]);if(0===e.length\u0026\u00260===n.length)return;if(0===e.length||0===n.length)throw new Error(`LengthMatchingSolver: differential pair ${t.connectionNames.join(\"/\")} has routed geometry for only one connection`);const o=hG(this.matchedHdRoutes,e),i=hG(this.matchedHdRoutes,n),r=Math.abs(o-i);if(r\u003c=t.lengthTolerance)return;const s=o\u003ci,a=t.connectionNames[s?0:1],c=t.connectionNames[s?1:0],l=mG({routes:this.matchedHdRoutes,routeIndexes:s?e:n,maximumDepth:this.getConfig().maximumMeanderDepth,minimumToothPitch:this.getConfig().minimumToothPitch,minMeanderGap:this.getConfig().minMeanderGap,minMeanderHeight:this.getConfig().minMeanderHeight,maxToothCount:this.getConfig().maxToothCount});if(0===l.length)throw new IG({message:`LengthMatchingSolver: no same-layer straight segment can tune connection \"${a}\"`,connectionName:a,reason:\"no-meander-candidate\"});this.activePair={pair:t,longerConnectionName:c,longerRouteIndexes:s?n:e,shorterConnectionName:a,targetAddedLength:r,remainingAddedLength:r,candidates:l,candidateIndex:0,lastMatchedSegmentIndexByRoute:new Map,partialAttempts:[],fullAttempts:[],plannedAttemptTargets:null,hasMinimumHeightBlockedAttempt:!1}}acceptAttempt(t,e){const n=this.matchedHdRoutes[e.routeIndex];this.matchedHdRoutes[e.routeIndex]={...n,route:e.predictedRoute},t.remainingAddedLength-=e.addedLength,t.lastMatchedSegmentIndexByRoute.set(e.routeIndex,e.segmentIndex),t.candidateIndex=0,t.partialAttempts=[],t.fullAttempts=[],t.plannedAttemptTargets?.delete(CG(e)),0===t.plannedAttemptTargets?.size\u0026\u0026(t.plannedAttemptTargets=null),t.remainingAddedLength\u003c=t.pair.lengthTolerance\u0026\u0026(this.activePair=null)}tryCandidate(t){let e;for(;!e;){const n=t.candidates[t.candidateIndex++];if(!n)break;const o=t.lastMatchedSegmentIndexByRoute.get(n.routeIndex);(void 0===o||n.segmentIndex\u003co)\u0026\u0026(!t.plannedAttemptTargets||t.plannedAttemptTargets.has(CG(n))\u0026\u0026![...t.plannedAttemptTargets.values()].some(t=\u003et.routeIndex===n.routeIndex\u0026\u0026t.segmentIndex\u003en.segmentIndex))\u0026\u0026(e=n)}if(!e){const e=t.fullAttempts.reduce((t,e)=\u003e!t||e.qualityScore\u003et.qualityScore?e:t,null),n=(t=\u003e{const e=t=\u003e[t.toothCount,t.placement,t.heightProfile].join(\":\"),n=new Map;for(const o of t.attempts){const t=`${o.routeIndex}:${o.segmentIndex}`,i=e(o),r=n.get(i);if(!r){n.set(i,new Map([[t,[o]]]));continue}const s=r.get(t);s?s.push(o):r.set(t,[o])}let o=null;for(const e of n.values()){const n=[...e.values()].map(t=\u003e({attempts:t,maximumCapacityAttempt:t.reduce((t,e)=\u003ee.addedLength\u003et.addedLength?e:t)})).sort((t,e)=\u003ee.maximumCapacityAttempt.addedLength-t.maximumCapacityAttempt.addedLength);let i=0;for(let e=0;e\u003cn.length;e++){if(i+=n[e].maximumCapacityAttempt.addedLength,i+t.lengthTolerance\u003ct.targetAddedLength)continue;const r=n.slice(0,e+1),s=r.map(t=\u003et.maximumCapacityAttempt),a=PG({attempts:s,targetAddedLength:t.targetAddedLength}),c=r.map(e=\u003e{const n=a.get(CG(e.maximumCapacityAttempt));if(!n)throw new Error(`LengthMatchingSolver: missing capacity target for ${CG(e.maximumCapacityAttempt)}`);const o=e.attempts.filter(e=\u003ee.addedLength+t.lengthTolerance\u003e=n.targetAddedLength);if(0===o.length)throw new Error(`LengthMatchingSolver: no pitch can supply planned target for route ${e.maximumCapacityAttempt.routeIndex} segment ${e.maximumCapacityAttempt.segmentIndex}`);return o.reduce((t,e)=\u003ee.qualityScore\u003et.qualityScore||e.qualityScore===t.qualityScore\u0026\u0026e.toothPitch\u003et.toothPitch?e:t)}),l=vG(c);if(!o){o={attempts:c};break}const d=vG(o.attempts);(c.length\u003co.attempts.length||c.length===o.attempts.length\u0026\u0026l\u003ed)\u0026\u0026(o={attempts:c});break}}return o})({attempts:t.partialAttempts,targetAddedLength:t.remainingAddedLength,lengthTolerance:t.pair.lengthTolerance});if(e\u0026\u0026(!n||e.qualityScore\u003e=vG(n.attempts)))return void this.acceptAttempt(t,e);if(!n){if(!(t.hasMinimumHeightBlockedAttempt\u0026\u0026null===t.plannedAttemptTargets\u0026\u00260===t.lastMatchedSegmentIndexByRoute.size))throw new IG({message:`LengthMatchingSolver: linear regression exhausted all segment/tooth combinations for \"${t.shorterConnectionName}\"; required ${t.targetAddedLength.toFixed(4)}mm`,connectionName:t.shorterConnectionName,reason:\"meander-search-exhausted\"});return this.tryDualMeanderPlan(t)}return t.plannedAttemptTargets=PG({attempts:n.attempts,targetAddedLength:t.remainingAddedLength}),t.candidateIndex=0,t.partialAttempts=[],void(t.fullAttempts=[])}const n=this.matchedHdRoutes[e.routeIndex],o=this.getConfig(),i=t.plannedAttemptTargets?.get(CG(e));if(null!==t.plannedAttemptTargets\u0026\u0026void 0===i)throw new Error(`LengthMatchingSolver: missing planned target for ${CG(e)}`);this.currentAttempt=_G({candidate:e,route:n,connectionName:t.shorterConnectionName,targetAddedLength:void 0===i?t.remainingAddedLength:i.targetAddedLength,lengthTolerance:t.pair.lengthTolerance,isGeometryValid:t=\u003epG({route:n,meanderPoints:t,routedRoutes:this.matchedHdRoutes,obstacles:o.obstacles,bounds:o.bounds,layerCount:o.layerCount,obstacleMargin:o.obstacleMargin}),getCenterlineDistanceCost:void 0===t.pair.minimumCenterlineDistance\u0026\u0026void 0===t.pair.maximumCenterlineDistance?void 0:e=\u003e(t=\u003e{let e=0,n=0;for(let o=0;o\u003ct.meanderPoints.length-1;o++){const i=t.meanderPoints[o],r=t.meanderPoints[o+1],s=Math.hypot(r.x-i.x,r.y-i.y);if(0!==s){for(let e=0;e\u003c4;e++){const o=(e+.5)/4,a={x:i.x+(r.x-i.x)*o,y:i.y+(r.y-i.y)*o},c=[];for(const e of t.pairedRoutes)for(let t=0;t\u003ce.route.length-1;t++){const n=e.route[t],o=e.route[t+1];i.z===n.z\u0026\u0026i.z===o.z\u0026\u0026c.push(cG(a,a,n,o))}if(0===c.length)return null;const l=Math.min(...c);n+=s*Math.max(0,(t.minimumCenterlineDistance??Number.NEGATIVE_INFINITY)-l,l-(t.maximumCenterlineDistance??Number.POSITIVE_INFINITY))/4}e+=s}}if(0===e)throw new Error(\"LengthMatchingSolver: cannot measure a zero-length meander centerline\");return n/e})({meanderPoints:e,pairedRoutes:t.longerRouteIndexes.map(t=\u003ethis.matchedHdRoutes[t]),minimumCenterlineDistance:t.pair.minimumCenterlineDistance,maximumCenterlineDistance:t.pair.maximumCenterlineDistance})}),this.candidatesTried++,\"below-minimum-height\"===this.currentAttempt.invalidReason\u0026\u0026(t.hasMinimumHeightBlockedAttempt=!0),this.stats={pair:`${t.pair.connectionNames[0]}/${t.pair.connectionNames[1]}`,candidatesTried:this.candidatesTried,segmentIndex:e.segmentIndex,toothCount:e.toothCount,toothPitch:e.toothPitch,placement:e.placement,predictedScaleFactor:this.currentAttempt.predictedScaleFactor,predictedToothDepths:this.currentAttempt.predictedToothDepths,resultingError:this.currentAttempt.resultingError,qualityScore:this.currentAttempt.qualityScore,accepted:this.currentAttempt.valid},this.currentAttempt.valid\u0026\u0026(null===t.plannedAttemptTargets?t.remainingAddedLength-this.currentAttempt.addedLength\u003c=t.pair.lengthTolerance?t.fullAttempts.push(this.currentAttempt):t.partialAttempts.push(this.currentAttempt):this.acceptAttempt(t,this.currentAttempt))}tryDualMeanderPlan(t){if(t.remainingAddedLength!==t.targetAddedLength)throw new Error(`LengthMatchingSolver: cannot start a dual-meander plan after partially tuning \"${t.shorterConnectionName}\"`);const e=this.getConfig(),n=mG({routes:this.matchedHdRoutes,routeIndexes:t.longerRouteIndexes,maximumDepth:e.maximumMeanderDepth,minimumToothPitch:e.minimumToothPitch,minMeanderGap:e.minMeanderGap,minMeanderHeight:e.minMeanderHeight,maxToothCount:e.maxToothCount}),o=(t=\u003e{const e=(t,e)=\u003et.rankingQualityScore!==e.rankingQualityScore?t.rankingQualityScore\u003ee.rankingQualityScore:t.leftIndex!==e.leftIndex?t.leftIndex\u003ce.leftIndex:t.rightIndex\u003ce.rightIndex,n=(t,n)=\u003e{t.push(n);let o=t.length-1;for(;o\u003e0;){const i=Math.floor((o-1)/2),r=t[i];if(e(r,n))break;t[o]=r,o=i}t[o]=n},o=t=\u003e{const n=t[0],o=t.pop();if(!n||!o||0===t.length)return n;let i=0;for(;;){const n=2*i+1,r=n+1;if(n\u003e=t.length)break;const s=r\u003ct.length\u0026\u0026e(t[r],t[n])?r:n,a=t[s];if(e(o,a))break;t[i]=a,i=s}return t[i]=o,n},i=function*(t){const e=[...t.leftOptions].sort((e,n)=\u003et.getLeftQualityScore(n)-t.getLeftQualityScore(e)),i=[...t.rightOptions].sort((e,n)=\u003et.getRightQualityScore(n)-t.getRightQualityScore(e)),r=[];for(let o=0;o\u003ce.length;o++){const s=i[0];if(!s)break;n(r,{leftIndex:o,rightIndex:0,rankingQualityScore:(t.getLeftQualityScore(e[o])+t.getRightQualityScore(s))/2})}for(;r.length\u003e0;){const s=o(r);yield[e[s.leftIndex],i[s.rightIndex]];const a=s.rightIndex+1,c=i[a];c\u0026\u0026n(r,{leftIndex:s.leftIndex,rightIndex:a,rankingQualityScore:(t.getLeftQualityScore(e[s.leftIndex])+t.getRightQualityScore(c))/2})}},r=(t,e)=\u003e{const n=t[e.routeIndex];if(!n)throw new Error(`LengthMatchingSolver: dual meander references missing route ${e.routeIndex}`);const o=[...t];return o[e.routeIndex]={...n,route:e.predictedRoute},o},s=t=\u003e{const e=t.routes[t.attempt.routeIndex];if(!e)throw new Error(`LengthMatchingSolver: cannot validate missing dual-meander route ${t.attempt.routeIndex}`);return pG({route:e,meanderPoints:t.attempt.meanderPoints,routedRoutes:t.routes,...t.config})},a=t=\u003e{const e=t.routes.filter(e=\u003esG(e)!==t.counterpartConnectionName),n=[];for(const o of t.candidates){const i=t.routes[o.routeIndex];if(!i)throw new Error(`LengthMatchingSolver: dual-meander candidate references missing route ${o.routeIndex}`);const r=bG({candidate:o,route:i,connectionName:t.connectionName,lengthTolerance:t.config.lengthTolerance,isGeometryValid:n=\u003epG({route:i,meanderPoints:n,routedRoutes:e,...t.config})});r\u0026\u0026n.push({candidate:o,attempt:r})}return n},c={obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,obstacleMargin:t.obstacleMargin},l=a({candidates:t.shorterCandidates,routes:t.routes,connectionName:t.shorterConnectionName,counterpartConnectionName:t.longerConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(0===l.length)return null;const d=a({candidates:t.longerCandidates,routes:t.routes,connectionName:t.longerConnectionName,counterpartConnectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}}),h=i({leftOptions:d,rightOptions:l,getLeftQualityScore:t=\u003et.attempt.qualityScore,getRightQualityScore:t=\u003et.attempt.qualityScore});for(const[e,n]of h){const o=Math.max(e.attempt.addedLength,n.attempt.addedLength-t.originalLengthDifference),i=o+t.originalLengthDifference;if(o-t.lengthTolerance\u003ee.attempt.maximumAddedLength||i-t.lengthTolerance\u003en.attempt.maximumAddedLength)continue;const a=t.routes[e.candidate.routeIndex];if(!a)throw new Error(`LengthMatchingSolver: missing longer route ${e.candidate.routeIndex}`);const l=t.routes[n.candidate.routeIndex];if(!l)throw new Error(`LengthMatchingSolver: missing shorter route ${n.candidate.routeIndex}`);const d=t.routes.filter(e=\u003esG(e)!==t.shorterConnectionName),h=_G({candidate:e.candidate,route:a,connectionName:t.longerConnectionName,targetAddedLength:o,lengthTolerance:t.lengthTolerance,isGeometryValid:t=\u003epG({route:a,meanderPoints:t,routedRoutes:d,...c})});if(!h.valid||Math.abs(h.addedLength-o)\u003et.lengthTolerance)continue;const u=r(t.routes,h),p=h.addedLength+t.originalLengthDifference,m=_G({candidate:n.candidate,route:l,connectionName:t.shorterConnectionName,targetAddedLength:p,lengthTolerance:t.lengthTolerance,isGeometryValid:t=\u003epG({route:l,meanderPoints:t,routedRoutes:u,...c})});if(!m.valid)continue;const g=r(u,m),f=aG(g,t.longerConnectionName),y=aG(g,t.shorterConnectionName);if(!(Math.abs(hG(g,y)-hG(g,f))\u003et.lengthTolerance)\u0026\u0026s({attempt:h,routes:g,config:c})\u0026\u0026s({attempt:m,routes:g,config:c}))return{longerAttempts:[h],shorterAttempts:[m]}}const u=i({leftOptions:SG(d),rightOptions:SG(l),getLeftQualityScore:t=\u003et.rankingQualityScore,getRightQualityScore:t=\u003et.rankingQualityScore});for(const[e,n]of u){if(1===e.attempts.length\u0026\u00261===n.attempts.length)continue;const o=Math.max(e.minimumAddedLength,n.minimumAddedLength-t.originalLengthDifference),i=o+t.originalLengthDifference;if(o-t.lengthTolerance\u003ee.maximumAddedLength||i-t.lengthTolerance\u003en.maximumAddedLength)continue;const r=xG({plan:e,targetAddedLength:o,routes:t.routes,connectionName:t.longerConnectionName,excludedConnectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(!r)continue;const a=xG({plan:n,targetAddedLength:r.addedLength+t.originalLengthDifference,routes:r.routes,connectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(!a)continue;const l=aG(a.routes,t.longerConnectionName),d=aG(a.routes,t.shorterConnectionName),h=Math.abs(hG(a.routes,d)-hG(a.routes,l)),u=[...r.attempts,...a.attempts];if(!(h\u003et.lengthTolerance||u.some(t=\u003e!s({attempt:t,routes:a.routes,config:c}))))return{longerAttempts:r.attempts,shorterAttempts:a.attempts}}return null})({routes:this.matchedHdRoutes,longerConnectionName:t.longerConnectionName,shorterConnectionName:t.shorterConnectionName,originalLengthDifference:t.targetAddedLength,lengthTolerance:t.pair.lengthTolerance,longerCandidates:n,shorterCandidates:t.candidates,obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,obstacleMargin:e.obstacleMargin});if(!o)throw new IG({message:`LengthMatchingSolver: linear regression exhausted all segment/tooth combinations for \"${t.shorterConnectionName}\"; required ${t.targetAddedLength.toFixed(4)}mm`,connectionName:t.shorterConnectionName,reason:\"meander-search-exhausted\"});const i=[...this.matchedHdRoutes];for(const t of[...o.longerAttempts,...o.shorterAttempts]){const e=this.matchedHdRoutes[t.routeIndex];if(!e)throw new Error(`LengthMatchingSolver: cannot commit dual meander to missing route ${t.routeIndex}`);i[t.routeIndex]={...e,route:t.predictedRoute}}this.matchedHdRoutes=i,this.currentAttempt=o.shorterAttempts[0];const r=o.longerAttempts.reduce((t,e)=\u003et+e.addedLength,0),s=o.shorterAttempts.reduce((t,e)=\u003et+e.addedLength,0);this.stats={pair:`${t.pair.connectionNames[0]}/${t.pair.connectionNames[1]}`,mode:\"dual-meander\",longerAddedLength:r,shorterAddedLength:s,resultingError:Math.abs(s-r-t.targetAddedLength)},this.activePair=null}getConfig(){return this.config||(this.config=(t=\u003e{const e=t.maximumMeanderDepth??5,n=t.maxToothCount??12;if(!Number.isFinite(e)||e\u003c=0)throw new Error(\"LengthMatchingSolver: maximumMeanderDepth must be a positive finite number\");if(void 0!==t.minimumToothPitch\u0026\u0026(!Number.isFinite(t.minimumToothPitch)||t.minimumToothPitch\u003c=0))throw new Error(\"LengthMatchingSolver: minimumToothPitch must be a positive finite number\");if(void 0!==t.minMeanderGap\u0026\u0026(!Number.isFinite(t.minMeanderGap)||t.minMeanderGap\u003c=0))throw new Error(\"LengthMatchingSolver: minMeanderGap must be a positive finite number\");if(void 0!==t.minMeanderHeight\u0026\u0026(!Number.isFinite(t.minMeanderHeight)||t.minMeanderHeight\u003c=0))throw new Error(\"LengthMatchingSolver: minMeanderHeight must be a positive finite number\");if(void 0!==t.minMeanderHeight\u0026\u0026t.minMeanderHeight\u003ee)throw new Error(\"LengthMatchingSolver: minMeanderHeight cannot exceed maximumMeanderDepth\");if(!Number.isFinite(n)||!Number.isInteger(n)||n\u003c=0)throw new Error(\"LengthMatchingSolver: maxToothCount must be a positive finite integer\");return{maximumMeanderDepth:e,minimumToothPitch:t.minimumToothPitch,minMeanderGap:t.minMeanderGap,minMeanderHeight:t.minMeanderHeight,maxToothCount:n,obstacles:t.obstacles??[],bounds:t.bounds,obstacleMargin:t.obstacleMargin??.15,layerCount:t.layerCount??2,colorMap:t.colorMap??{}}})(this.params)),this.config}_step(){this.getConfig(),this.activePair?this.tryCandidate(this.activePair):this.startNextPair()}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved)throw new Error(\"LengthMatchingSolver: getOutput() called before the solver completed\");return{matchedHdRoutes:this.matchedHdRoutes}}getBestEffortOutput(){const t=structuredClone(this.matchedHdRoutes),e=this.activePair?.fullAttempts??[];let n=null;for(const t of e)(!n||t.qualityScore\u003en.qualityScore)\u0026\u0026(n=t);if(!n)for(const t of this.activePair?.partialAttempts??[])(!n||t.addedLength\u003en.addedLength||t.addedLength===n.addedLength\u0026\u0026t.qualityScore\u003en.qualityScore)\u0026\u0026(n=t);if(n){const e=t[n.routeIndex];e\u0026\u0026(t[n.routeIndex]={...e,route:structuredClone(n.predictedRoute)})}return{matchedHdRoutes:t}}computeProgress(){if(this.solved)return 1;if(0===this.pairs.length)return this.config?1:0;const t=Math.max(0,this.nextPairIndex-1),e=this.activePair?this.activePair.candidateIndex/this.activePair.candidates.length:0;return Math.min(.99,(t+e)/this.pairs.length)}visualize(){const t=this.getConfig();return TG({routes:this.matchedHdRoutes,obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,colorMap:t.colorMap,activePair:this.activePair,currentAttempt:this.currentAttempt,solved:this.solved})}},EG=(t,e)=\u003e{if(\"top\"===t)return 0;if(\"bottom\"===t)return e-1;const n=/^inner(\\d+)$/.exec(t);if(!n)return-1;const o=Number(n[1]);return o\u003e0\u0026\u0026o\u003ce-1?o:-1},AG=(t,e)=\u003e0===t?\"top\":t===e-1?\"bottom\":`inner${t}`,OG=(t,e,n)=\u003e{const o=EG(t,n),i=EG(e,n);if(o\u003c0||i\u003c0)return[];const r=Math.min(o,i),s=Math.max(o,i);return Array.from({length:s-r+1},(t,e)=\u003eAG(r+e,n))},kG=1e-8,LG=(t,e)=\u003e{if(0===t.route.length)throw new Error(`trace \"${t.connection_name}\" has an empty route`);if(t.route.some(t=\u003e\"wire\"!==t.route_type\u0026\u0026\"via\"!==t.route_type))throw new Error(`trace \"${t.connection_name}\" contains unsupported jumper or through-obstacle geometry`);const n=t.route.findIndex(t=\u003e\"wire\"===t.route_type),o=t.route[n],i=t.route.findLast(t=\u003e\"wire\"===t.route_type);if(\"wire\"!==o?.route_type||!i)throw new Error(`trace \"${t.connection_name}\" must contain a wire point`);const r=[],s=[],a=[],c=[];let l=null,d=o.width;if(n\u003e0){let e=o.layer;for(let o=n-1;o\u003e=0;o--){const n=t.route[o];if(\"via\"!==n?.route_type)throw new Error(`trace \"${t.connection_name}\" has unsupported geometry before its first wire`);if(e===n.to_layer)e=n.from_layer;else{if(e!==n.from_layer)throw new Error(`trace \"${t.connection_name}\" has discontinuous leading vias`);e=n.to_layer}}const i=t.route[0];if(\"via\"!==i.route_type)throw new Error(`trace \"${t.connection_name}\" has an invalid leading entry`);l={x:i.x,y:i.y,layer:e,width:o.width},r.push(l)}for(const n of t.route){if(\"wire\"===n.route_type){if(!Number.isFinite(n.x)||!Number.isFinite(n.y)||!Number.isFinite(n.width)||n.width\u003c=0||EG(n.layer,e)\u003c0)throw new Error(`trace \"${t.connection_name}\" has an invalid wire point`);d=Math.max(d,n.width);const o={x:n.x,y:n.y,layer:n.layer,width:n.width};if(l){if(l.layer!==o.layer)throw new Error(`trace \"${t.connection_name}\" changes layers without a via`);Math.hypot(l.x-o.x,l.y-o.y)\u003ekG\u0026\u0026s.push({start:l,end:o,layer:o.layer,width:Math.max(l.width,o.width),connectionName:t.connection_name,terminal:null})}r.push(o),l=o;continue}if(\"via\"!==n.route_type)throw new Error(`trace \"${t.connection_name}\" contains unsupported route geometry`);if(!l)throw new Error(`trace \"${t.connection_name}\" has a leading via`);const o=EG(n.from_layer,e),i=EG(n.to_layer,e),h=n.via_diameter??l.width;if(!Number.isFinite(n.x)||!Number.isFinite(n.y)||o\u003c0||i\u003c0||o===i||void 0!==n.via_diameter\u0026\u0026(!Number.isFinite(n.via_diameter)||n.via_diameter\u003c=0)||void 0!==n.via_hole_diameter\u0026\u0026(!Number.isFinite(n.via_hole_diameter)||n.via_hole_diameter\u003c=0||n.via_hole_diameter\u003e=h))throw new Error(`trace \"${t.connection_name}\" has an invalid via`);const u=l.layer===n.from_layer?n.from_layer:l.layer===n.to_layer?n.to_layer:null;if(!u)throw new Error(`trace \"${t.connection_name}\" has a discontinuous via transition`);Math.hypot(l.x-n.x,l.y-n.y)\u003ekG\u0026\u0026s.push({start:l,end:n,layer:l.layer,width:l.width,connectionName:t.connection_name,terminal:null});const p=u===n.from_layer?n.to_layer:n.from_layer;c.push({...n,from_layer:u,to_layer:p}),a.push({x:n.x,y:n.y,layers:OG(u,p,e),diameter:h,connectionName:t.connection_name,terminal:1===r.length?\"start\":null}),l={x:n.x,y:n.y,layer:p,width:l.width},r.push(l)}if(r.length\u003c2||0===s.length)throw new Error(`trace \"${t.connection_name}\" does not contain a routable path`);s[0].terminal=1===s.length?\"both\":\"start\",s[s.length-1].terminal=1===s.length?\"both\":\"end\";const h=a.at(-1);return h\u0026\u0026Math.hypot(h.x-i.x,h.y-i.y)\u003c=kG\u0026\u0026(h.terminal=\"end\"),{source:t,points:r,segments:s,vias:a,transitions:c,width:d,viaDiameter:t.__postProcessingViaDiameter??d,...o.start_pcb_port_id?{startPortId:o.start_pcb_port_id}:{},...i.end_pcb_port_id?{endPortId:i.end_pcb_port_id}:{}}},DG=(t,e)=\u003e{const n=[],o=[],i=t.route.find(t=\u003e\"wire\"===t.route_type),r=\"wire\"===i?.route_type?i.width:null,s={\"0603\":.95,1206:1.8,\"1206x4_pair\":1.8};let a=null;for(let i=0;i\u003ct.route.length;i++){const c=t.route[i];if(\"wire\"===c.route_type){if(!Number.isFinite(c.x)||!Number.isFinite(c.y)||!Number.isFinite(c.width)||c.width\u003c=0||EG(c.layer,e)\u003c0)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has an invalid wire`);if(a\u0026\u0026a.layer!==c.layer)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" changes layer without a transition`);a\u0026\u0026n.push({start:a,end:c,layer:c.layer,width:Math.max(a.width,c.width),connectionName:t.connection_name,terminal:null}),a=c;continue}if(\"via\"===c.route_type){const s=OG(c.from_layer,c.to_layer,e),l=a,d=c.via_diameter??l?.width??r;if(!Number.isFinite(c.x)||!Number.isFinite(c.y)||s.length\u003c2||null===d||!Number.isFinite(d)||d\u003c=0||void 0!==c.via_hole_diameter\u0026\u0026(!Number.isFinite(c.via_hole_diameter)||c.via_hole_diameter\u003c=0||null!==d\u0026\u0026c.via_hole_diameter\u003e=d))throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has an invalid via`);l\u0026\u0026Math.hypot(l.x-c.x,l.y-c.y)\u003e1e-8\u0026\u0026n.push({start:l,end:c,layer:l.layer,width:l.width,connectionName:t.connection_name,terminal:null}),o.push({x:c.x,y:c.y,layers:s,diameter:d,connectionName:t.connection_name,terminal:0===i?\"start\":i===t.route.length-1?\"end\":null});const h=t.route.slice(i+1).find(t=\u003e\"wire\"===t.route_type),u=l?.layer===c.from_layer?c.to_layer:l?.layer===c.to_layer?c.from_layer:\"wire\"!==h?.route_type||h.layer!==c.from_layer\u0026\u0026h.layer!==c.to_layer?null:h.layer;if(!u)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has a discontinuous via`);a={x:c.x,y:c.y,layer:u,width:l?.width??r??d};continue}if(\"jumper\"===c.route_type){const o=s[c.footprint];if(!Number.isFinite(c.start.x)||!Number.isFinite(c.start.y)||!Number.isFinite(c.end.x)||!Number.isFinite(c.end.y)||EG(c.layer,e)\u003c0)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has an invalid jumper`);if(a\u0026\u0026(a.layer!==c.layer||Math.hypot(a.x-c.start.x,a.y-c.start.y)\u003e1e-8))throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has a discontinuous jumper`);n.push({start:c.start,end:c.end,layer:c.layer,width:o,connectionName:t.connection_name,terminal:null}),a={...c.end,layer:c.layer,width:o};continue}const l=OG(c.from_layer,c.to_layer,e);if(!Number.isFinite(c.start.x)||!Number.isFinite(c.start.y)||!Number.isFinite(c.end.x)||!Number.isFinite(c.end.y)||!Number.isFinite(c.width)||c.width\u003c=0||l.length\u003c2)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has invalid through-obstacle copper`);if(a\u0026\u0026(a.layer!==c.from_layer\u0026\u0026a.layer!==c.to_layer||Math.hypot(a.x-c.start.x,a.y-c.start.y)\u003e1e-8))throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has discontinuous through-obstacle copper`);for(const e of l)n.push({start:c.start,end:c.end,layer:e,width:c.width,connectionName:t.connection_name,terminal:null});const d=a,h=d?.layer===c.to_layer?c.from_layer:c.to_layer;a={...c.end,layer:h,width:c.width}}return{segments:n,vias:o}},zG=(t,e)=\u003e{const n=DG(t,e);return[...n.segments.map((n,o)=\u003e({connectionName:`${t.connection_name}#immutable-segment-${o}`,rootConnectionName:t.connection_name,traceThickness:n.width,viaDiameter:n.width,route:[{x:n.start.x,y:n.start.y,z:EG(n.layer,e),traceThickness:n.width},{x:n.end.x,y:n.end.y,z:EG(n.layer,e),traceThickness:n.width}],vias:[]})),...n.vias.map((n,o)=\u003e({connectionName:`${t.connection_name}#immutable-via-${o}`,rootConnectionName:t.connection_name,traceThickness:n.diameter,viaDiameter:n.diameter,route:[],vias:[{x:n.x,y:n.y,zLayers:n.layers.map(t=\u003eEG(t,e))}]}))]},FG=t=\u003et.segments.reduce((t,e)=\u003et+Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),0),BG=t=\u003e{const{simpleRouteJson:e}=t.params,n=(t=\u003e{const e=new Set(t.reroutedPairs.map(t=\u003et.connectionNames.join(\"\\0\")));return t.declaredPairs.filter(n=\u003e{const o=n.connectionNames.map(e=\u003et.traces.filter(t=\u003et.connection_name===e));if(o.some(t=\u003e1!==t.length))return!1;if(e.has(n.connectionNames.join(\"\\0\")))return!0;const i=o.map(t=\u003et[0]);if(i.some(t=\u003et.route.length\u003c2||\"wire\"!==t.route[0]?.route_type||!t.route.every(t=\u003e\"wire\"===t.route_type||\"via\"===t.route_type)))return!1;const r=i.map(e=\u003eFG(LG(e,t.layerCount)));return Math.abs(r[0]-r[1])\u003en.lengthTolerance+1e-7}).map(t=\u003estructuredClone(t))})({traces:t.result.traces,declaredPairs:e.differentialPairs,reroutedPairs:t.result.reroutedPairs,layerCount:e.layerCount}),o=new Set(n.flatMap(t=\u003et.connectionNames)),i=[],r=[],s=[],a=new Set;for(let n=0;n\u003ct.result.traces.length;n++){const c=t.result.traces[n];if(!o.has(c.connection_name))continue;const l=c.route.every(t=\u003e\"wire\"===t.route_type||\"via\"===t.route_type),d=\"wire\"===c.route[0]?.route_type;if(!l||!d)throw new Error(`PostProcessingSolver: rerouted connection \"${c.connection_name}\" cannot be bound to LengthMatchingSolver`);const h=LG(c,e.layerCount),u=c.route[0];if(\"wire\"!==u.route_type)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" lost its first wire during binding`);const p=[{x:u.x,y:u.y,z:EG(u.layer,e.layerCount),traceThickness:u.width}],m=[],g=[];let f=u.layer,y=u.width;for(const t of c.route.slice(1)){if(\"wire\"===t.route_type){if(t.layer!==f)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" changes layers without a via while binding`);p.push({x:t.x,y:t.y,z:EG(t.layer,e.layerCount),traceThickness:t.width}),y=t.width;continue}if(\"via\"!==t.route_type)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" contains unsupported bound geometry`);const n=f===t.from_layer?t.to_layer:f===t.to_layer?t.from_layer:null;if(!n)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" has a discontinuous bound via`);const o=p.at(-1);Math.hypot(o.x-t.x,o.y-t.y)\u003e1e-8\u0026\u0026p.push({x:t.x,y:t.y,z:EG(f,e.layerCount),traceThickness:y}),p.push({x:t.x,y:t.y,z:EG(n,e.layerCount),traceThickness:y}),m.push({x:t.x,y:t.y,zLayers:OG(t.from_layer,t.to_layer,e.layerCount).map(t=\u003eEG(t,e.layerCount))}),g.push({...t}),f=n}if(p.length\u003c2)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" has no bound copper segments`);const _=Math.max(...p.map(t=\u003et.traceThickness??h.width)),b=h.viaDiameter,x=i.length;i.push({connectionName:c.connection_name,traceThickness:_,viaDiameter:b,route:p,vias:m});const v=p[0],S=p.at(-1);r.push({name:c.connection_name,pointsToConnect:[{x:v.x,y:v.y,layer:u.layer,...h.startPortId?{pcb_port_id:h.startPortId}:{}},{x:S.x,y:S.y,layer:h.points.at(-1).layer,...h.endPortId?{pcb_port_id:h.endPortId}:{}}]}),s.push({traceIndex:n,matchedRouteIndex:x,viaTemplates:g,startEndpoint:{...v},endEndpoint:{...S},...h.startPortId?{startPortId:h.startPortId}:{},...h.endPortId?{endPortId:h.endPortId}:{}}),a.add(c.connection_name)}for(const t of o)if(!a.has(t))throw new Error(`PostProcessingSolver: missing LengthMatchingSolver binding for rerouted connection \"${t}\"`);for(const n of t.result.traces)o.has(n.connection_name)||i.push(...zG(n,e.layerCount));const c=e.minTraceToPadEdgeClearance??Math.max(0,...i.filter(t=\u003et.route.length\u003e=2).map(t=\u003et.traceThickness));return{solverParams:{hdRoutes:i,originalConnections:r,differentialPairs:n,obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,obstacleMargin:c},traceBindings:s,baseTraces:structuredClone(t.result.traces)}},jG=t=\u003e{const e=new Map;for(const n of t.differentialPairs)for(const o of n.connectionNames){const n=t.hdRoutes.map((t,e)=\u003e({route:t,hdRouteIndex:e})).filter(({route:t})=\u003et.connectionName===o);1===n.length\u0026\u0026e.set(n[0].hdRouteIndex,o)}const n=t.hdRoutes.map((e,n)=\u003e{const o=[],i=new Map;for(let t=0;t\u003c(e.jumpers?.length??0);t++){const n=e.jumpers[t],o=e.route.map((t,e)=\u003e({point:t,index:e})).filter(({point:t})=\u003eMath.hypot(t.x-n.start.x,t.y-n.start.y)\u003c=1e-8).map(({index:t})=\u003et),r=e.route.map((t,e)=\u003e({point:t,index:e})).filter(({point:t})=\u003eMath.hypot(t.x-n.end.x,t.y-n.end.y)\u003c=1e-8).map(({index:t})=\u003et),s=[...o.flatMap(t=\u003er.filter(e=\u003ee\u003et).map(e=\u003e({startIndex:t,endIndex:e}))),...r.flatMap(t=\u003eo.filter(e=\u003ee\u003et).map(e=\u003e({startIndex:t,endIndex:e})))];if(1!==s.length)throw new Error(`PostProcessingSolver: immutable HD route \"${e.connectionName}\" has an ambiguous jumper traversal`);const a=s[0];if(i.has(a.startIndex)||[...i.values()].some(({endIndex:t})=\u003ea.startIndex\u003ct||a.endIndex\u003c=t))throw new Error(`PostProcessingSolver: immutable HD route \"${e.connectionName}\" has overlapping or unordered jumpers`);i.set(a.startIndex,{endIndex:a.endIndex,jumperIndex:t})}if(e.route.length\u003e0){const n=e.route[0];o.push({route_type:\"wire\",x:n.x,y:n.y,width:n.traceThickness??e.traceThickness,layer:AG(n.z,t.layerCount)});for(let n=0;n\u003ce.route.length-1;n++){const r=e.route[n],s=i.get(n);if(s){const i=e.route[s.endIndex],a=e.jumpers[s.jumperIndex];if(r.z!==i.z)throw new Error(`PostProcessingSolver: immutable HD route \"${e.connectionName}\" changes layers through a jumper`);o.push({route_type:\"jumper\",start:{x:r.x,y:r.y},end:{x:i.x,y:i.y},footprint:a.footprint,layer:AG(r.z,t.layerCount)}),o.push({route_type:\"wire\",x:i.x,y:i.y,width:i.traceThickness??e.traceThickness,layer:AG(i.z,t.layerCount)}),n=s.endIndex-1;continue}const a=e.route[n+1],c=AG(r.z,t.layerCount),l=AG(a.z,t.layerCount);r.z!==a.z\u0026\u0026(\"through_obstacle\"===r.toNextSegmentType?o.push({route_type:\"through_obstacle\",start:{x:r.x,y:r.y},end:{x:a.x,y:a.y},from_layer:c,to_layer:l,width:r.traceThickness??e.traceThickness}):o.push({route_type:\"via\",x:a.x,y:a.y,from_layer:c,to_layer:l,via_diameter:e.viaDiameter})),o.push({route_type:\"wire\",x:a.x,y:a.y,width:a.traceThickness??e.traceThickness,layer:l})}const r=o.filter(t=\u003e\"wire\"===t.route_type),s=e.startPcbPortId??e.route[0]?.pcb_port_id,a=e.endPcbPortId??e.route.at(-1)?.pcb_port_id;s\u0026\u0026r[0]\u0026\u0026(r[0].start_pcb_port_id=s),a\u0026\u0026r.at(-1)\u0026\u0026(r.at(-1).end_pcb_port_id=a)}return{type:\"pcb_trace\",pcb_trace_id:`post_processing_hd_route_${n}`,connection_name:e.connectionName,__postProcessingViaDiameter:e.viaDiameter,route:o}}),o=structuredClone(t.obstacles);for(let n=0;n\u003ct.hdRoutes.length;n++){const i=t.hdRoutes[n],r=new Set([i.connectionName,i.rootConnectionName,i.startPcbPortId,i.endPcbPortId,i.route[0]?.pcb_port_id,i.route.at(-1)?.pcb_port_id,e.get(n)].filter(t=\u003evoid 0!==t));for(const t of o)t.connectedTo.some(t=\u003er.has(t))\u0026\u0026(t.connectedTo=[...new Set([...t.connectedTo,...r])])}return{params:{simpleRouteJson:{traces:n,differentialPairs:structuredClone(t.differentialPairs),obstacles:o,bounds:structuredClone(t.bounds),layerCount:t.layerCount,minTraceToPadEdgeClearance:t.minTraceToPadEdgeClearance},...t.routingGrid?{routingGrid:structuredClone(t.routingGrid)}:{}},routeBindings:[...e.entries()].map(([t,e])=\u003e({hdRouteIndex:t,traceIndex:t,internalConnectionName:e})),sourceHdRoutes:structuredClone(t.hdRoutes)}};function $G(t){const e=structuredClone(t.model.sourceHdRoutes);for(const n of t.model.routeBindings){const o=t.binding.traceBindings.find(t=\u003et.traceIndex===n.traceIndex);if(!o)continue;const i=t.result.matchedHdRoutes[o.matchedRouteIndex],r=e[n.hdRouteIndex];if(!i||!r)throw new Error(`PostProcessingSolver: missing matched or source HD route for \"${n.internalConnectionName}\"`);if(i.connectionName!==n.internalConnectionName)throw new Error(`PostProcessingSolver: matched HD binding changed \"${n.internalConnectionName}\" to \"${i.connectionName}\"`);const s=i.route.map(t=\u003e({...t})),a=(e,o)=\u003e{if(e\u0026\u0026o\u0026\u0026(o.pcb_port_id\u0026\u0026(e.pcb_port_id=o.pcb_port_id),o.insideJumperPad\u0026\u0026t.rejectInsideJumperPad))throw new Error(`PostProcessingSolver: cannot restore jumper-pad metadata on rerouted connection \"${n.internalConnectionName}\"`)};a(s[0],r.route[0]),a(s.at(-1),r.route.at(-1)),e[n.hdRouteIndex]={...r,route:s,vias:structuredClone(i.vias)}}return{hdRoutes:e,postProcessingErrors:[]}}var YG=class extends Error{connectionNames;reason;constructor(t){super(`PostProcessingSolver: differential pair ${t.connectionNames.join(\"/\")} ${t.message}`),this.name=\"DifferentialPairRoutingError\",this.connectionNames=[t.connectionNames[0],t.connectionNames[1]],this.reason=t.reason}},XG=class extends Error{connectionNames;reason;constructor(t){super(t.message),this.name=\"PostProcessingConstraintError\",this.connectionNames=[...t.connectionNames],this.reason=t.reason}},VG=class extends Error{reason=\"grid-capacity-exhausted\";constructor(t){super(t),this.name=\"PostProcessingGridCapacityError\"}},WG=t=\u003e{const e=75e3*t.simpleRouteJson.differentialPairs.length;if(!Number.isSafeInteger(e))throw new Error(\"PostProcessingSolver: derived rerouting iteration bound exceeds the safe integer range\");const n=Math.min(e,8e4);return Math.max(1,n)},HG=t=\u003estructuredClone(t),GG=(t,e,n)=\u003e{const o=t=\u003e{const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}},i=o(t.start),r=o(t.end),s=e.width/2+n,a=e.height/2+n;if(Math.abs(i.x)\u003c=s\u0026\u0026Math.abs(i.y)\u003c=a||Math.abs(r.x)\u003c=s\u0026\u0026Math.abs(r.y)\u003c=a)return!0;const c=[{x:-s,y:-a},{x:s,y:-a},{x:s,y:a},{x:-s,y:a}];return c.some((t,e)=\u003ecG(i,r,t,c[(e+1)%c.length])\u003c=1e-7)},UG=t=\u003e{const e=[],n=[];for(const o of t.immutableTraces){const i=DG(o,t.layerCount);e.push(...i.segments),n.push(...i.vias)}const o=Array.from({length:t.layerCount},()=\u003e[]);for(const n of e){const e=EG(n.layer,t.layerCount);o[e].push(n)}const i=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y)\u003c=1e-8,r=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-e.x-o*s,t.y-e.y-i*s)},s=(t,e,n)=\u003e{const o=-(e.ccwRotationDegrees??0)*Math.PI/180,i=t.x-e.center.x,r=t.y-e.center.y,s=i*Math.cos(o)-r*Math.sin(o),a=i*Math.sin(o)+r*Math.cos(o);return Math.abs(s)\u003c=e.width/2+n\u0026\u0026Math.abs(a)\u003c=e.height/2+n},a=(e,n)=\u003e{const o=EG(n,t.layerCount);return uG(e,t.layerCount).includes(o)},c=(e,n,o)=\u003e{const i=((e,n,o)=\u003e{const i=Math.hypot(n.x,n.y);if(i\u003c=1e-10)throw new Error(\"PostProcessingSolver: cannot orient terminal fanout on a zero-length spine\");const r=-n.y/i*t.side*t.centerlineSpacing/2,s=n.x/i*t.side*t.centerlineSpacing/2,a=\"start\"===o?[t.firstStartTerminal,t.secondStartTerminal]:[t.firstEndTerminal,t.secondEndTerminal],c=[t.firstWidth,t.secondWidth],l=[t.firstConnectionName,t.secondConnectionName];return a.map((t,n)=\u003e{const i=0===n?1:-1,a={x:e.x+r*i,y:e.y+s*i};return{start:\"start\"===o?t:a,end:\"start\"===o?a:t,layer:e.layer,width:c[n],connectionName:l[n],terminal:o}})})(e,n,o),r=i.map(t=\u003e\"start\"===o?t.end:t.start);return i.every(l)\u0026\u0026r.every((n,o)=\u003et.obstacles.every(r=\u003e!a(r,e.layer)||!s(n,r,1.5*i[o].width+(t.terminalMiterMargin??0))))\u0026\u0026cG(i[0].start,i[0].end,i[1].start,i[1].end)\u003e=i[0].width/2+i[1].width/2-1e-7},l=e=\u003e{const i=e.width/2,c=i+(t.minTraceToPadEdgeClearance??e.width),l=EG(e.layer,t.layerCount),d=Math.min(e.start.x,e.end.x),h=Math.max(e.start.x,e.end.x),u=Math.min(e.start.y,e.end.y),p=Math.max(e.start.y,e.end.y);for(const n of[e.start,e.end])if(n.x-i\u003ct.bounds.minX||n.x+i\u003et.bounds.maxX||n.y-i\u003ct.bounds.minY||n.y+i\u003et.bounds.maxY)return!1;for(const n of t.obstacles){if(!a(n,e.layer))continue;const o=Math.hypot(n.width/2+c,n.height/2+c);if(h\u003cn.center.x-o||d\u003en.center.x+o||p\u003cn.center.y-o||u\u003en.center.y+o)continue;const[i,r]=e.connectionName===t.firstConnectionName?[t.firstStartTerminal,t.firstEndTerminal]:[t.secondStartTerminal,t.secondEndTerminal],l=s(i,n,0)\u0026\u0026(s(e.start,n,c)||s(e.end,n,c))\u0026\u0026Math.hypot(e.end.x-i.x,e.end.y-i.y)\u003e=Math.hypot(e.start.x-i.x,e.start.y-i.y),m=s(r,n,0)\u0026\u0026(s(e.start,n,c)||s(e.end,n,c))\u0026\u0026Math.hypot(e.end.x-r.x,e.end.y-r.y)\u003c=Math.hypot(e.start.x-r.x,e.start.y-r.y);if(!(n.connectedTo.includes(e.connectionName)\u0026\u0026(l||m))\u0026\u0026GG(e,n,c))return!1}for(const t of o[l]){const n=e.width/2+t.width/2+Math.max(e.width,t.width);if(!(h+n\u003cMath.min(t.start.x,t.end.x)||d-n\u003eMath.max(t.start.x,t.end.x)||p+n\u003cMath.min(t.start.y,t.end.y)||u-n\u003eMath.max(t.start.y,t.end.y))\u0026\u0026cG(e.start,e.end,t.start,t.end)\u003cn)return!1}for(const t of n)if(t.layers.includes(e.layer)\u0026\u0026r(t,e.start,e.end)\u003ce.width/2+t.diameter/2+e.width)return!1;return!0},d=o=\u003e{const i=o.diameter/2;if(o.x-i\u003ct.bounds.minX||o.x+i\u003et.bounds.maxX||o.y-i\u003ct.bounds.minY||o.y+i\u003et.bounds.maxY)return!1;for(const e of t.obstacles){if(!o.layers.some(t=\u003ea(e,t)))continue;if(!(null!==o.terminal\u0026\u0026e.connectedTo.includes(o.connectionName)\u0026\u0026s(o,e,0))\u0026\u0026s(o,e,i+o.diameter))return!1}for(const t of e){if(!o.layers.includes(t.layer))continue;const e=i+t.width/2+Math.max(o.diameter,t.width);if(r(o,t.start,t.end)\u003ce)return!1}for(const t of n){if(!t.layers.some(t=\u003eo.layers.includes(t)))continue;const e=i+t.diameter/2+Math.max(o.diameter,t.diameter);if(Math.hypot(o.x-t.x,o.y-t.y)\u003ce)return!1}return!0};return{isEdgeValid:(e,n)=\u003e{if(e.layer!==n.layer||!((e,n)=\u003e{const o=Math.hypot(n.x-e.x,n.y-e.y);if(0===o)return[];const r=-(n.y-e.y)/o*t.side*t.centerlineSpacing/2,s=(n.x-e.x)/o*t.side*t.centerlineSpacing/2,a=i(e,t.start),c=i(n,t.end),l=t.terminalFanout?a\u0026\u0026c?\"both\":a?\"start\":c?\"end\":null:null,d=a\u0026\u0026t.terminalFanout?t.firstStartTerminal:{x:e.x+r,y:e.y+s},h=c\u0026\u0026t.terminalFanout?t.firstEndTerminal:{x:n.x+r,y:n.y+s},u=a\u0026\u0026t.terminalFanout?t.secondStartTerminal:{x:e.x-r,y:e.y-s},p=c\u0026\u0026t.terminalFanout?t.secondEndTerminal:{x:n.x-r,y:n.y-s};return[{start:d,end:h,layer:e.layer,width:t.firstWidth,connectionName:t.firstConnectionName,terminal:l},{start:u,end:p,layer:e.layer,width:t.secondWidth,connectionName:t.secondConnectionName,terminal:l}]})(e,n).every(l))return!1;if(t.terminalFanout||void 0===t.terminalMiterMargin)return!0;const o={x:n.x-e.x,y:n.y-e.y};return!(i(e,t.start)\u0026\u0026!c(e,o,\"start\"))\u0026\u0026!(i(n,t.end)\u0026\u0026!c(n,o,\"end\"))},isTerminalFanoutValid:c,isViaValid:(e,n,o)=\u003e{const r=Math.hypot(o.x,o.y);if(r\u003c=1e-10)throw new Error(\"PostProcessingSolver: cannot orient a coupled via on a zero-length spine\");const s=OG(e.layer,n,t.layerCount),a=-o.y/r*t.side*t.centerlineSpacing/2,c=o.x/r*t.side*t.centerlineSpacing/2,l=i(e,t.start)?\"start\":i(e,t.end)?\"end\":null;return[{x:e.x+a,y:e.y+c,layers:s,diameter:t.firstViaDiameter,connectionName:t.firstConnectionName,terminal:l},{x:e.x-a,y:e.y-c,layers:s,diameter:t.secondViaDiameter,connectionName:t.secondConnectionName,terminal:l}].every(d)}}},ZG=(t,e,n)=\u003e{const o=1e-7,i=(t,e)=\u003e{const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}},r=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},s=(t,e,n)=\u003e{const o=EG(e,n);return uG(t,n).includes(o)},a=(t,e,n)=\u003e{const a=t.width/2;if(t.start.x-a\u003ce.bounds.minX-o||t.start.x+a\u003ee.bounds.maxX+o||t.start.y-a\u003ce.bounds.minY-o||t.start.y+a\u003ee.bounds.maxY+o||t.end.x-a\u003ce.bounds.minX-o||t.end.x+a\u003ee.bounds.maxX+o||t.end.y-a\u003ce.bounds.minY-o||t.end.y+a\u003ee.bounds.maxY+o)return!1;for(const n of e.obstacles){if(!s(n,t.layer,e.layerCount))continue;const r=\"both\"===t.terminal?[t.start,t.end]:\"start\"===t.terminal?[t.start]:\"end\"===t.terminal?[t.end]:[];if(!(n.connectedTo.includes(t.connectionName)\u0026\u0026r.some(t=\u003e{const e=i(t,n);return Math.abs(e.x)\u003c=n.width/2+o\u0026\u0026Math.abs(e.y)\u003c=n.height/2+o}))\u0026\u0026GG(t,n,a+(e.minTraceToPadEdgeClearance??t.width)))return!1}for(const e of n.segments){if(e.layer!==t.layer)continue;const n=t.width/2+e.width/2+Math.max(t.width,e.width);if(cG(t.start,t.end,e.start,e.end)\u003cn-o)return!1}for(const e of n.vias){if(!e.layers.includes(t.layer))continue;const n=t.width/2+e.diameter/2+t.width;if(r(e,t.start,t.end)\u003cn-o)return!1}return!0},c=(t,e,n)=\u003e{const a=t.diameter/2;if(t.x-a\u003ce.bounds.minX-o||t.x+a\u003ee.bounds.maxX+o||t.y-a\u003ce.bounds.minY-o||t.y+a\u003ee.bounds.maxY+o)return!1;for(const n of e.obstacles){if(!t.layers.some(t=\u003es(n,t,e.layerCount)))continue;const r=i(t,n);if(!(null!==t.terminal\u0026\u0026n.connectedTo.includes(t.connectionName)\u0026\u0026Math.abs(r.x)\u003c=n.width/2+o\u0026\u0026Math.abs(r.y)\u003c=n.height/2+o)\u0026\u0026Math.abs(r.x)\u003c=n.width/2+a+t.diameter\u0026\u0026Math.abs(r.y)\u003c=n.height/2+a+t.diameter)return!1}for(const e of n.segments){if(!t.layers.includes(e.layer))continue;const n=a+e.width/2+Math.max(t.diameter,e.width);if(r(t,e.start,e.end)\u003cn-o)return!1}for(const e of n.vias){if(!e.layers.some(e=\u003et.layers.includes(e)))continue;const n=a+e.diameter/2+Math.max(t.diameter,e.diameter);if(Math.hypot(t.x-e.x,t.y-e.y)\u003cn-o)return!1}return!0},l=t=\u003e{for(let e=0;e\u003ct.segments.length;e++){const n=t.segments[e];for(let i=e+2;i\u003ct.segments.length;i++){const r=t.segments[i];if(n.layer!==r.layer)continue;if(!(t.segments.slice(e+1,i).reduce((t,e)=\u003et+Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),0)\u003c=n.width+r.width+o)\u0026\u0026cG(n.start,n.end,r.start,r.end)\u003cn.width/2+r.width/2-o)return!0}}for(const e of t.vias)for(const n of t.segments){if(!e.layers.includes(n.layer))continue;if(!(Math.hypot(e.x-n.start.x,e.y-n.start.y)\u003c=o||Math.hypot(e.x-n.end.x,e.y-n.end.y)\u003c=o)\u0026\u0026r(e,n.start,n.end)\u003ce.diameter/2+n.width/2-o)return!0}return!1},d=((t,e)=\u003e{const n=[],o=[];for(const i of t){const t=DG(i,e);n.push(...t.segments),o.push(...t.vias)}return{segments:n,vias:o}})(n.immutableTraces,n.layerCount);if(!((t,e)=\u003e{for(const n of t.segments)for(const t of e.segments){if(n.layer!==t.layer)continue;const e=n.width/2+t.width/2;if(cG(n.start,n.end,t.start,t.end)\u003ce-o)return!1}for(const[n,i]of[[t.vias,e.segments],[e.vias,t.segments]])for(const t of n)for(const e of i)if(t.layers.includes(e.layer)\u0026\u0026r(t,e.start,e.end)\u003ct.diameter/2+e.width/2-o)return!1;for(const n of t.vias)for(const t of e.vias)if(n.layers.some(e=\u003et.layers.includes(e))\u0026\u0026Math.hypot(n.x-t.x,n.y-t.y)\u003cn.diameter/2+t.diameter/2-o)return!1;return!0})(t,e)||l(t)||l(e))return!1;for(const o of[t,e])if(o.segments.some(t=\u003e!a(t,n,d))||o.vias.some(t=\u003e!c(t,n,d)))return!1;return!0},qG=[{x:1,y:0},{x:1,y:1},{x:0,y:1},{x:-1,y:1},{x:-1,y:0},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1}],JG=class{constructor(t){this.input=t;const{bounds:e,grid:n}=t,o={minX:e.minX+n.outerPerimeterWidth,maxX:e.maxX-n.outerPerimeterWidth,minY:e.minY+n.outerPerimeterWidth,maxY:e.maxY-n.outerPerimeterWidth},i=this.createAxis(e.minX,e.maxX,n.outerGridStep,[o.minX,o.maxX]),r=this.createAxis(e.minY,e.maxY,n.outerGridStep,[o.minY,o.maxY]),s=this.createAxis(o.minX,o.maxX,n.innerGridStep,[],t.start.x),a=this.createAxis(o.minY,o.maxY,n.innerGridStep,[],t.start.y),c=this.createGrid(i,r,t=\u003et.x\u003c=o.minX||t.x\u003e=o.maxX||t.y\u003c=o.minY||t.y\u003e=o.maxY),l=this.createGrid(s,a,()=\u003e!0);this.connectLocalNeighbors(c),this.connectLocalNeighbors(l);for(const t of[\"left\",\"right\",\"bottom\",\"top\"])this.connectBoundaries(t,c,l,o);const d=this.nodes.map((t,e)=\u003ee);this.connectEndpoint(t.start,d),this.connectEndpoint(t.end,d)}input;nodes=[];nodeIdByPoint=new Map;endpointNodeIdByPoint=new Map;getPlanarNeighbors(t){const e=this.endpointNodeIdByPoint.get(this.exactKeyFor(t))??this.nodeIdByPoint.get(this.keyFor(t));if(void 0===e)throw new Error(`PostProcessingSolver: coupled path point (${t.x}, ${t.y}) is not on the composite grid`);return[...this.nodes[e].neighborIds].map(e=\u003e({...this.nodes[e].point,layer:t.layer}))}getNodeCount(){return this.nodes.length}getSearchStateCountUpperBound(t){const e=this.nodes.reduce((t,e)=\u003et+e.neighborIds.size,0)*t+1;if(!Number.isSafeInteger(e))throw new Error(\"PostProcessingSolver: composite-grid search-state bound exceeds the safe integer range\");return e}createAxis(t,e,n,o,i=t){const r=[t,e,...o].map(t=\u003e({value:t,fixed:!0}));for(let o=Math.ceil((t-i)/n);i+o*n\u003ce-1e-8;o++)r.push({value:i+o*n,fixed:!1});r.sort((t,e)=\u003et.value-e.value||Number(e.fixed)-Number(t.fixed));const s=[];for(const t of r){const e=s.at(-1);!e||Math.abs(t.value-e.value)\u003e1e-8?s.push(t):t.fixed\u0026\u0026!e.fixed\u0026\u0026(s[s.length-1]=t)}return s.map(t=\u003et.value)}createGrid(t,e,n){return e.map(e=\u003et.map(t=\u003e{const o={x:t,y:e};return n(o)?this.addNode(o):null}))}connectLocalNeighbors(t){for(let e=0;e\u003ct.length;e++)for(let n=0;n\u003c(t[e]?.length??0);n++){const o=t[e][n];if(null!==o)for(const i of qG){const r=t[e+i.y]?.[n+i.x];null!=r\u0026\u0026this.connect(o,r)}}}connectBoundaries(t,e,n,o){const i=\"left\"===t?o.minX:\"right\"===t?o.maxX:\"bottom\"===t?o.minY:o.maxY,r=\"left\"===t||\"right\"===t,s=t=\u003eMath.abs((r?t.x:t.y)-i)\u003c=1e-8,a=t=\u003e{const e=new Set;for(const n of t)for(const t of n)null!==t\u0026\u0026s(this.nodes[t].point)\u0026\u0026e.add(t);return[...e].sort((t,e)=\u003e{const n=this.nodes[t].point,o=this.nodes[e].point;return(r?n.y-o.y:n.x-o.x)||t-e})},c=a(e),l=a(n);if(0===c.length||0===l.length)throw new Error(`PostProcessingSolver: composite grid has no ${t} boundary bridge candidates`);for(const t of c)this.connect(t,this.findNearestAlongBoundary(t,l,r));for(const t of l)this.connect(t,this.findNearestAlongBoundary(t,c,r))}findNearestAlongBoundary(t,e,n){const o=this.nodes[t].point;let i=e[0],r=Number.POSITIVE_INFINITY;for(const t of e){const e=this.nodes[t].point,s=Math.abs(n?o.y-e.y:o.x-e.x);(s\u003cr-1e-8||Math.abs(s-r)\u003c=1e-8\u0026\u0026t\u003ci)\u0026\u0026(r=s,i=t)}return i}connectEndpoint(t,e){const n=this.nodeIdByPoint.get(this.keyFor(t)),o=void 0===n?null:this.nodes[n].point,i=o?.x===t.x\u0026\u0026o.y===t.y?n:this.nodes.push({point:{x:t.x,y:t.y},neighborIds:new Set})-1;this.endpointNodeIdByPoint.set(this.exactKeyFor(t),i);const r=(t,n)=\u003e{const o=this.nodes[t].point,i=e.filter(e=\u003ee!==t).map(t=\u003e({nodeId:t,distance:Math.hypot(this.nodes[t].point.x-o.x,this.nodes[t].point.y-o.y)})).filter(({distance:t})=\u003et\u003e1e-10).sort((t,e)=\u003et.distance-e.distance||t.nodeId-e.nodeId).slice(0,n);if(0===i.length)throw new Error(\"PostProcessingSolver: composite grid has no endpoint connection candidates\");for(const{nodeId:e}of i)this.connect(t,e)};r(i,8);for(const e of qG){const n={x:t.x+e.x*this.input.grid.innerGridStep,y:t.y+e.y*this.input.grid.innerGridStep};if(n.x\u003cthis.input.bounds.minX||n.x\u003ethis.input.bounds.maxX||n.y\u003cthis.input.bounds.minY||n.y\u003ethis.input.bounds.maxY)continue;const o=this.addNode(n);this.connect(i,o),r(o,4)}}addNode(t){const e=this.keyFor(t),n=this.nodeIdByPoint.get(e);if(void 0!==n)return n;const o=this.nodes.length;return this.nodes.push({point:{x:t.x,y:t.y},neighborIds:new Set}),this.nodeIdByPoint.set(e,o),o}connect(t,e){if(t===e)return;const n=this.nodes[t],o=this.nodes[e];n.neighborIds.add(e),o.neighborIds.add(t)}keyFor(t){const e=Object.is(t.x,-0)?0:t.x,n=Object.is(t.y,-0)?0:t.y;return`${e.toFixed(12)}:${n.toFixed(12)}`}exactKeyFor(t){return`${Object.is(t.x,-0)?0:t.x}:${Object.is(t.y,-0)?0:t.y}`}},KG=class{constructor(t){if(this.input=t,this.startLayer=EG(t.start.layer,t.layerCount),this.endLayer=EG(t.end.layer,t.layerCount),this.grid=new JG(t),this.maxSearchStates=this.grid.getSearchStateCountUpperBound(t.layerCount),this.exploredStateLimit=Math.min(this.maxSearchStates,2e4),this.startLayer\u003c0||this.endLayer\u003c0)return this.queue=[],void(this.status=\"exhausted\");const e={point:t.start,direction:null,cost:0,estimate:this.estimate(t.start),parent:null,sequence:0};this.queue=[e],this.bestCosts.set(this.keyFor(t.start,null),0)}input;queue;bestCosts=new Map;startLayer;endLayer;grid;maxSearchStates;exploredStateLimit;current=null;result=null;status=\"searching\";explored=0;nextSequence=1;isComplete(){return\"searching\"!==this.status}getPath(){return this.result}getPreviewPath(){return this.current?this.createPath(this.current):[this.input.start]}getExploredCount(){return this.explored}getProgress(){return\"searching\"!==this.status?1:Math.min(.99,this.explored/this.exploredStateLimit)}getGridNodeCount(){return this.grid.getNodeCount()}step(){if(\"searching\"!==this.status)return;const t=this.popQueue();if(!t)return void(this.status=\"exhausted\");const e=this.bestCosts.get(this.keyFor(t.point,t.direction));if(void 0===e)throw new Error(\"PostProcessingSolver: coupled path queue contains an untracked state\");if(t.cost\u003ee+1e-10)0===this.queue.length\u0026\u0026(this.status=\"exhausted\");else{if(this.current=t,this.explored++,this.explored\u003ethis.maxSearchStates)throw new Error(`PostProcessingSolver: coupled path search exceeded its ${this.maxSearchStates}-state graph invariant limit`);if(this.isEnd(t.point)){const e=this.createPath(t);return e[e.length-1]=this.input.end,this.result=this.simplifyPath(e),void(this.status=\"found\")}this.explored\u003e=this.exploredStateLimit?this.status=\"exhausted\":(this.enqueuePlanarNeighbors(t),this.enqueueViaNeighbors(t),0===this.queue.length\u0026\u0026(this.status=\"exhausted\"))}}isEnd(t){return t.layer===this.input.end.layer\u0026\u0026t.x===this.input.end.x\u0026\u0026t.y===this.input.end.y}estimate(t){return Math.hypot(t.x-this.input.end.x,t.y-this.input.end.y)+3*Math.abs(EG(t.layer,this.input.layerCount)-this.endLayer)}keyFor(t,e){return`${Object.is(t.x,-0)?0:t.x}:${Object.is(t.y,-0)?0:t.y}:${t.layer}:${e?.key??\"start\"}`}createDirection(t,e){const n=e.x-t.x,o=e.y-t.y,i=Math.hypot(n,o);if(i\u003c=1e-10)throw new Error(\"PostProcessingSolver: composite grid produced a zero-length planar edge\");const r=n/i,s=o/i;return{x:r,y:s,key:`${r.toFixed(6)}:${s.toFixed(6)}`}}createPath(t){const e=[];let n=t;for(;n;)e.push(n.point),n=n.parent;return e.reverse()}simplifyPath(t){return t.filter((e,n)=\u003e{if(0===n||n===t.length-1)return!0;const o=t[n-1],i=t[n+1],r={x:e.x-o.x,y:e.y-o.y},s={x:i.x-e.x,y:i.y-e.y},a=r.x*s.y-r.y*s.x,c=Math.hypot(r.x,r.y)*Math.hypot(s.x,s.y);return Math.abs(a)\u003e1e-10*c||e.layer!==o.layer||e.layer!==i.layer})}hasHigherQueuePriority(t,e){return t.estimate!==e.estimate?t.estimate\u003ce.estimate:t.cost!==e.cost?t.cost\u003ce.cost:t.point.x!==e.point.x?t.point.x\u003ce.point.x:t.point.y!==e.point.y?t.point.y\u003ce.point.y:t.point.layer!==e.point.layer?t.point.layer\u003ce.point.layer:t.sequence\u003ce.sequence}pushQueue(t){this.queue.push(t);let e=this.queue.length-1;for(;e\u003e0;){const n=Math.floor((e-1)/2),o=this.queue[n];if(!this.hasHigherQueuePriority(t,o))break;this.queue[e]=o,e=n}this.queue[e]=t}popQueue(){const t=this.queue[0],e=this.queue.pop();if(!t||!e||0===this.queue.length)return t;let n=0;for(;;){const t=2*n+1;if(t\u003e=this.queue.length)break;const o=t+1;let i=t;o\u003cthis.queue.length\u0026\u0026this.hasHigherQueuePriority(this.queue[o],this.queue[t])\u0026\u0026(i=o);const r=this.queue[i];if(!this.hasHigherQueuePriority(r,e))break;this.queue[n]=r,n=i}return this.queue[n]=e,t}enqueuePlanarNeighbors(t){for(const e of this.grid.getPlanarNeighbors(t.point)){if(!this.input.isEdgeValid(t.point,e))continue;const n=this.createDirection(t.point,e),o=null===t.direction||t.direction.key===n.key?0:.18,i=t.cost+Math.hypot(e.x-t.point.x,e.y-t.point.y)+o,r=this.keyFor(e,n);(this.bestCosts.get(r)??Number.POSITIVE_INFINITY)\u003c=i||(this.bestCosts.set(r,i),this.pushQueue({point:e,direction:n,cost:i,estimate:i+this.estimate(e),parent:t,sequence:this.nextSequence++}))}}enqueueViaNeighbors(t){if(!t.direction)return;const e=EG(t.point.layer,this.input.layerCount);for(const n of[e-1,e+1]){if(n\u003c0||n\u003e=this.input.layerCount)continue;const e=AG(n,this.input.layerCount);if(!this.input.isViaValid(t.point,e,t.direction))continue;const o={...t.point,layer:e},i=t.cost+4,r=this.keyFor(o,t.direction);(this.bestCosts.get(r)??Number.POSITIVE_INFINITY)\u003c=i||(this.bestCosts.set(r,i),this.pushQueue({point:o,direction:t.direction,cost:i,estimate:i+this.estimate(o),parent:t,sequence:this.nextSequence++}))}}},QG=t=\u003e{const e=Math.min(t.bounds.maxX-t.bounds.minX,t.bounds.maxY-t.bounds.minY),n=t.config?.innerGridStep??t.defaultInnerGridStep,o=t.config?.outerGridStep??4*n,i=t.config?.outerPerimeterWidth??Math.min(o,e/4);if(!Number.isFinite(n)||n\u003c1e-4)throw new Error(\"PostProcessingSolver: routingGrid.innerGridStep must be finite and at least 0.0001\");if(!Number.isFinite(o)||o\u003c=n)throw new Error(\"PostProcessingSolver: routingGrid.outerGridStep must be finite and greater than innerGridStep\");if(!Number.isFinite(i)||i\u003c=0||2*i\u003e=e)throw new Error(\"PostProcessingSolver: routingGrid.outerPerimeterWidth must be finite, positive, and less than half the smaller board extent\");const r=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY;if((Math.ceil(r/o)+4)*(Math.ceil(s/o)+4)+(Math.ceil((r-2*i)/n)+2)*(Math.ceil((s-2*i)/n)+2)+18\u003e25e4)throw new VG(\"PostProcessingSolver: valid input exceeds the 250000-node optimization grid capacity\");return{innerGridStep:n,outerGridStep:o,outerPerimeterWidth:i}},tU=t=\u003e{const e=-t.pathDirection.y,n=t.pathDirection.x,o=Math.tan(t.maximumTurnDegrees*Math.PI/180),i=Math.max(0,...t.lanes.map(({point:i,polarity:r})=\u003e{const s=i.x-t.anchor.x,a=i.y-t.anchor.y,c=s*t.escapeDirection.x+a*t.escapeDirection.y,l=s*e+a*n,d=r*t.side*t.centerlineSpacing/2;return c+Math.abs(l-d)/o})),r=t.maxUncoupledLength??i;if(i\u003er+1e-8)return null;const s=Math.max(.05,Math.min(.25,t.searchStep/2)),a=Math.max(1,Math.ceil((r-i)/s)+1);for(let o=0;o\u003ca;o++){const a=Math.min(r,i+o*s),c={x:t.anchor.x+t.escapeDirection.x*a,y:t.anchor.y+t.escapeDirection.y*a,layer:t.anchor.layer};if(t.lanes.every(({point:o,polarity:i})=\u003e{const r=i*t.side*t.centerlineSpacing/2,s=c.x+e*r,a=c.y+n*r;return void 0===t.maxUncoupledLength||Math.hypot(s-o.x,a-o.y)\u003c=t.maxUncoupledLength+1e-8})\u0026\u0026t.isValid(c))return c}return null},eU=[.75,.5,1,.25,1.25],nU=100,oU=class{constructor(t){this.input=t,this.pairName=t.pair.connectionNames.join(\"/\"),this.prepared=this.prepare()}input;pairName;prepared;candidates=[];result=null;search=null;nextAttempt=0;exploredNodeCount=0;isComplete(){return null!==this.result}getResult(){if(!this.result)throw new Error(`PostProcessingSolver: differential pair ${this.pairName} is not complete`);return this.result}getPreviewPath(){return this.search?.getPreviewPath()??null}getProgress(){if(this.result)return 1;const t=this.prepared.attempts.length,e=this.search?.getProgress()??0;return Math.min(.99,(this.nextAttempt+e)/t)}getStats(){return{phase:this.search?\"searching\":\"candidate-selection\",pair:this.pairName,attemptIndex:this.nextAttempt,attemptCount:this.prepared.attempts.length,exploredNodeCount:this.exploredNodeCount+(this.search?.getExploredCount()??0),gridNodeCount:this.search?.getGridNodeCount()??0,acceptedCandidateCount:this.candidates.length}}step(){if(this.result)return;const t=this.prepared;if(!this.search){const e=t.attempts[this.nextAttempt];return e?void(this.search=new KG(e.input)):void this.complete()}if(this.search.step(),!this.search.isComplete())return;const e=this.search.getPath();this.exploredNodeCount+=this.search.getExploredCount();const n=t.attempts[this.nextAttempt];if(!n)throw new Error(`PostProcessingSolver: differential pair ${this.pairName} lost its active attempt`);if(this.search=null,this.nextAttempt++,!e)return;const o=(t=\u003e{const e=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y)\u003c=1e-8;if(t.path.length\u003c2)throw new Error(\"PostProcessingSolver: coupled path has fewer than two stations\");const n=(n,o)=\u003e{for(let i=n+o;i\u003e=0\u0026\u0026i\u003ct.path.length;i+=o){const o=t.path[i];if(!e(o,t.path[n]))return o}return null},o=e=\u003e{const o=t.path[e],i=n(e,-1),r=n(e,1),s=(t,e)=\u003e{const n=e.x-t.x,o=e.y-t.y,i=Math.hypot(n,o);if(i\u003c=1e-10)throw new Error(\"PostProcessingSolver: cannot offset a zero-length spine\");return{x:-o/i,y:n/i}},a=t.side*t.centerlineSpacing/2;if(!i||!r){const t=s(i??o,r??o);return{x:t.x*a,y:t.y*a}}if(t.terminalFanout\u0026\u00261===e)return s(i,o);if(t.terminalFanout\u0026\u0026e===t.path.length-2)return s(o,r);if(t.terminalFanout\u0026\u0026t.path[e+1]?.layer!==o.layer)return s(i,o);const c=s(i,o),l=s(o,r),d={x:c.x+l.x,y:c.y+l.y},h=Math.hypot(d.x,d.y);if(h\u003c=1e-10)return null;const u=d.x/h,p=d.y/h,m=a/(u*c.x+p*c.y);return{x:u*m,y:p*m}},i=t.first.points[0],r=t.first.points.at(-1),s=t.reverseSecond?t.second.points.at(-1):t.second.points[0],a=t.reverseSecond?t.second.points[0]:t.second.points.at(-1),c=[[{route_type:\"wire\",x:i.x,y:i.y,width:i.width,layer:i.layer}],[{route_type:\"wire\",x:s.x,y:s.y,width:s.width,layer:s.layer}]],l=[t.first.transitions[0],t.second.transitions[0]];let d=0;const h=t.terminalFanout?1:0,u=t.path.length-2,p=t.path[u],m=t.path[u-1],g=t.terminalFanout\u0026\u0026p?.layer===r.layer\u0026\u0026m?.layer===p.layer,f=t.terminalFanout?g?u-1:t.path.length-1:t.path.length;for(let n=h;n\u003cf;n++){const i=t.path[n],r=o(n);if(!r)return null;for(const o of[0,1]){const s=0===o?1:-1,a={x:i.x+r.x*s,y:i.y+r.y*s},d=c[o],h=t.path[n-1];if(h\u0026\u0026h.layer!==i.layer){if(!e(h,i))throw new Error(\"PostProcessingSolver: a coupled layer transition moved in the plane\");const n=[...d].reverse().find(t=\u003e\"wire\"===t.route_type);if(!n)throw new Error(\"PostProcessingSolver: generated via has no preceding wire\");const r=l[o];d.push({route_type:\"via\",x:n.x,y:n.y,from_layer:h.layer,to_layer:i.layer,via_diameter:r?.via_diameter??(0===o?t.first.viaDiameter:t.second.viaDiameter),...void 0!==r?.via_hole_diameter?{via_hole_diameter:r.via_hole_diameter}:{}}),d.push({route_type:\"wire\",x:n.x,y:n.y,width:0===o?t.first.width:t.second.width,layer:i.layer})}else{const n=d.at(-1);\"wire\"===n?.route_type\u0026\u0026e(n,a)\u0026\u0026n.layer===i.layer||d.push({route_type:\"wire\",...a,width:0===o?t.first.width:t.second.width,layer:i.layer})}}t.path[n-1]?.layer!==i.layer\u0026\u0026n\u003e0\u0026\u0026d++}const y=(e,n)=\u003e{const o=e.at(-1);if(!o||\"wire\"!==o.route_type)throw new Error(\"PostProcessingSolver: terminal fanout has no preceding wire\");const i=e.at(-2);let r=!1;if(\"wire\"===i?.route_type\u0026\u0026i.layer===o.layer\u0026\u0026o.layer===n.layer){const t={x:o.x-i.x,y:o.y-i.y},e={x:n.x-o.x,y:n.y-o.y},s=Math.hypot(t.x,t.y),a=Math.hypot(e.x,e.y);if(s\u003e1e-8\u0026\u0026a\u003e1e-8\u0026\u0026Math.abs(t.x*e.x+t.y*e.y)\u003c=1e-8){const e={x:o.x-t.x/s*a,y:o.y-t.y/s*a};(e.x-i.x)*(t.x/s)+(e.y-i.y)*(t.y/s)\u003e1e-8\u0026\u0026(o.x=e.x,o.y=e.y,r=!0)}}t.terminalFanout\u0026\u0026!r\u0026\u0026o.x!==n.x\u0026\u0026o.y!==n.y\u0026\u0026e.push({route_type:\"wire\",x:n.x,y:o.y,width:n.width,layer:n.layer}),e.push({route_type:\"wire\",x:n.x,y:n.y,width:n.width,layer:n.layer})};y(c[0],r),y(c[1],a),t.reverseSecond\u0026\u0026(c[1]=c[1].reverse().map(t=\u003e\"via\"===t.route_type?{...t,from_layer:t.to_layer,to_layer:t.from_layer}:t));const _=(t,e)=\u003e{const n=t.filter(t=\u003e\"wire\"===t.route_type);for(const t of n)delete t.start_pcb_port_id,delete t.end_pcb_port_id;e.startPortId\u0026\u0026(n[0].start_pcb_port_id=e.startPortId),e.endPortId\u0026\u0026(n.at(-1).end_pcb_port_id=e.endPortId)};_(c[0],t.first),_(c[1],t.second);const b={...t.first.source,route:c[0]},x={...t.second.source,route:c[1]};return{first:b,second:x,firstParsed:LG(b,t.layerCount),secondParsed:LG(x,t.layerCount),edgeGap:t.edgeGap,centerlineDistance:t.centerlineSpacing,bendCount:Math.max(0,t.path.length-d-2),viaPairCount:d}})({first:t.first,second:t.second,reverseSecond:t.reverseSecond,path:e,centerlineSpacing:n.edgeGap+t.first.width/2+t.second.width/2,edgeGap:n.edgeGap,side:n.side,layerCount:this.input.layerCount,terminalFanout:t.terminalFanout});o\u0026\u0026ZG(o.firstParsed,o.secondParsed,t.context)\u0026\u0026this.candidates.push(o)}prepare(){const t=this.input.traces.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:t})=\u003et.connection_name===this.input.pair.connectionNames[0]),e=this.input.traces.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:t})=\u003et.connection_name===this.input.pair.connectionNames[1]);if(1!==t.length||1!==e.length)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"trace-resolution-failure\",message:\"must resolve each connection_name to exactly one non-branching trace\"});if(t[0].index===e[0].index)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"trace-resolution-failure\",message:\"resolved both members to one trace\"});let n,o;try{n=LG(t[0].trace,this.input.layerCount),o=LG(e[0].trace,this.input.layerCount)}catch(t){throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"invalid-routed-geometry\",message:`has unsupported or invalid routed geometry: ${t instanceof Error?t.message:String(t)}`})}const i=n.points[0],r=n.points.at(-1),s=Math.hypot(i.x-o.points[0].x,i.y-o.points[0].y)+Math.hypot(r.x-o.points.at(-1).x,r.y-o.points.at(-1).y),a=Math.hypot(i.x-o.points.at(-1).x,i.y-o.points.at(-1).y)+Math.hypot(r.x-o.points[0].x,r.y-o.points[0].y)+1e-8\u003cs,c=a?o.points.at(-1):o.points[0],l=a?o.points[0]:o.points.at(-1);if(i.layer!==c.layer||r.layer!==l.layer)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"terminal-layer-mismatch\",message:\"does not have common paired layers at both terminal stations\"});const d={x:(i.x+c.x)/2,y:(i.y+c.y)/2,layer:i.layer},h={x:(r.x+l.x)/2,y:(r.y+l.y)/2,layer:r.layer},u=Math.hypot(h.x-d.x,h.y-d.y);if(u\u003c1e-6)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"coincident-terminal-midpoints\",message:\"has coincident terminal-pair midpoints\"});const p={x:-(h.y-d.y)/u,y:(h.x-d.x)/u},m=i.x-c.x,g=i.y-c.y,f=m*p.x+g*p.y\u003e=0?1:-1,y=(t,e)=\u003e{const n=t.x-e.x,o=t.y-e.y,i=Math.hypot(n,o);return i\u003e1e-8\u0026\u0026Math.abs(n*p.x+o*p.y)/i\u003c.5},_=y(i,c)\u0026\u0026y(r,l),b={x:p.y,y:-p.x},x=[i,c].some(t=\u003e(t.x-d.x)*b.x+(t.y-d.y)*b.y\u003e1e-8),v={immutableTraces:this.input.traces.filter((n,o)=\u003eo!==t[0].index\u0026\u0026o!==e[0].index),obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,minTraceToPadEdgeClearance:this.input.minTraceToPadEdgeClearance},S=(t=\u003e{const{minimumCenterlineDistance:e,maximumCenterlineDistance:n}=t;if(void 0===e\u0026\u0026void 0===n)return t.legacyCenterlineDistances;const o=[...void 0!==e\u0026\u0026void 0!==n?[(e+n)/2,e,n,e-.25,n+.25]:void 0!==e?[e,e+.25,e+.5,e-.25,e+1]:[n,n-.25,n-.5,n+.25,n-1],...t.legacyCenterlineDistances];return o.filter((e,n)=\u003ee\u003et.minimumPhysicalDistance\u0026\u0026o.findIndex(t=\u003eMath.abs(t-e)\u003c1e-8)===n)})({minimumCenterlineDistance:this.input.pair.minimumCenterlineDistance,maximumCenterlineDistance:this.input.pair.maximumCenterlineDistance,minimumPhysicalDistance:n.width/2+o.width/2,legacyCenterlineDistances:eU.map(t=\u003et+n.width/2+o.width/2)}).flatMap(t=\u003e{const e=t-n.width/2-o.width/2;return[f,1===f?-1:1].flatMap(s=\u003e{const a=QG({config:this.input.routingGrid,bounds:this.input.bounds,defaultInnerGridStep:Math.max(.25,Math.min(.5,t/2))}),u=(e,a)=\u003eUG({...v,start:e,end:a,firstConnectionName:n.source.connection_name,secondConnectionName:o.source.connection_name,firstStartTerminal:i,firstEndTerminal:r,secondStartTerminal:c,secondEndTerminal:l,firstWidth:n.width,secondWidth:o.width,firstViaDiameter:n.transitions[0]?.via_diameter??n.viaDiameter,secondViaDiameter:o.transitions[0]?.via_diameter??o.viaDiameter,centerlineSpacing:t,side:s,terminalFanout:_,terminalMiterMargin:void 0===this.input.pair.maxUncoupledLength?void 0:t/2});let m=void 0===this.input.pair.maxUncoupledLength?((t,e)=\u003e{if(!x||_)return d;const n=[{terminal:i,offset:e*t/2},{terminal:c,offset:-e*t/2}],o=Math.tan(55*Math.PI/180),r=Math.max(...n.map(({terminal:t,offset:e})=\u003e{const n=(t.x-d.x)*b.x+(t.y-d.y)*b.y,i=(t.x-d.x)*p.x+(t.y-d.y)*p.y;return n+Math.abs(i-e)/o}));return{x:d.x+b.x*r,y:d.y+b.y*r,layer:d.layer}})(t,s):d,g=h;if(!_\u0026\u0026void 0!==this.input.pair.maxUncoupledLength){const e=u(d,h),n=tU({anchor:d,escapeDirection:b,pathDirection:b,centerlineSpacing:t,side:s,lanes:[{point:i,polarity:1},{point:c,polarity:-1}],maxUncoupledLength:this.input.pair.maxUncoupledLength,maximumTurnDegrees:55,searchStep:a.innerGridStep,isValid:t=\u003ee.isTerminalFanoutValid(t,b,\"start\")}),o=tU({anchor:h,escapeDirection:{x:-b.x,y:-b.y},pathDirection:b,centerlineSpacing:t,side:s,lanes:[{point:r,polarity:1},{point:l,polarity:-1}],maxUncoupledLength:this.input.pair.maxUncoupledLength,maximumTurnDegrees:45,searchStep:a.innerGridStep,isValid:t=\u003ee.isTerminalFanoutValid(t,b,\"end\")});if(!n||!o)return[];m=n,g=o;if((g.x-m.x)*b.x+(g.y-m.y)*b.y\u003c=a.innerGridStep)return[]}const f=u(m,g);return[{edgeGap:e,side:s,input:{start:m,end:g,bounds:this.input.bounds,layerCount:this.input.layerCount,grid:a,...f}}]})});return{first:n,second:o,reverseSecond:a,terminalFanout:_,context:v,attempts:S}}complete(){if(0===this.candidates.length)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"no-valid-candidate\",message:\"could not be improved without violating bounds, copper clearance, or coupled-via constraints\"});this.candidates.sort((t,e)=\u003ethis.score(t)-this.score(e)||t.edgeGap-e.edgeGap),this.result={status:\"accepted\",candidate:this.candidates[0]}}score(t){return(void 0!==this.input.pair.minimumCenterlineDistance||void 0!==this.input.pair.maximumCenterlineDistance?Math.max(0,(this.input.pair.minimumCenterlineDistance??Number.NEGATIVE_INFINITY)-t.centerlineDistance)*nU+Math.max(0,t.centerlineDistance-(this.input.pair.maximumCenterlineDistance??Number.POSITIVE_INFINITY))*nU:t.edgeGap\u003c.5?(.5-t.edgeGap)*nU:t.edgeGap\u003e1?(t.edgeGap-1)*nU:0)+FG(t.firstParsed)+FG(t.secondParsed)+.15*t.bendCount+8*t.viaPairCount}},iU=t=\u003e{const e={lines:[],points:[],rects:[],circles:[]};e.rects.push({center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,fill:\"rgba(30, 70, 120, 0.04)\",stroke:\"rgba(30, 70, 120, 0.55)\",layer:`z${Array.from({length:t.layerCount},(t,e)=\u003ee).join(\",\")}`});for(const n of t.obstacles){const o=uG(n,t.layerCount);e.rects.push({center:n.center,width:n.width,height:n.height,ccwRotationDegrees:n.ccwRotationDegrees,fill:\"rgba(220, 60, 60, 0.16)\",stroke:\"rgba(190, 40, 40, 0.75)\",layer:`z${o.join(\",\")}`})}for(let n=0;n\u003c(t.previewPath?.length??0)-1;n++){const o=t.previewPath[n],i=t.previewPath[n+1];if(o.layer!==i.layer)continue;const r=EG(o.layer,t.layerCount);e.lines.push({points:[o,i],strokeColor:\"#16a34a\",strokeWidth:.08,strokeDash:[.18,.12],layer:`z${r}`})}for(const n of t.traces){if(t.activeConnectionNames?.includes(n.connection_name))continue;const o=\"#2563eb\";let i=null;for(const r of n.route)if(\"wire\"===r.route_type){if(i\u0026\u0026i.layer===r.layer){const n=EG(r.layer,t.layerCount);e.lines.push({points:[i,r],strokeColor:o,strokeWidth:Math.max(i.width,r.width),...0===n?{}:{strokeDash:[.2,.16]},layer:`z${n}`})}i=r}else if(\"via\"===r.route_type){const n=OG(r.from_layer,r.to_layer,t.layerCount).map(e=\u003eEG(e,t.layerCount));if(e.circles.push({center:r,radius:(r.via_diameter??i?.width??.2)/2,fill:\"rgba(37, 99, 235, 0.45)\",stroke:o,layer:`z${n.join(\",\")}`}),i){const t=i.width;i={x:r.x,y:r.y,layer:r.to_layer,width:t}}}}return e},rU=class extends kt{constructor(t){super(),this.params=t,this.outputTraces=HG(t.simpleRouteJson.traces),this.MAX_ITERATIONS=WG(t)}params;outputTraces;reroutedPairs=[];failures=[];nextPairIndex=0;activeConnectionNames=null;activeSession=null;getSolverName(){return\"DifferentialPairReroutingSolver\"}_step(){const t=this.params.simpleRouteJson.differentialPairs[this.nextPairIndex];if(!t)return void this.finish();this.activeConnectionNames=t.connectionNames;try{if(!this.activeSession)return this.activeSession=new oU({pair:t,traces:this.outputTraces,obstacles:this.params.simpleRouteJson.obstacles,bounds:this.params.simpleRouteJson.bounds,layerCount:this.params.simpleRouteJson.layerCount,minTraceToPadEdgeClearance:this.params.simpleRouteJson.minTraceToPadEdgeClearance,routingGrid:this.params.routingGrid}),void(this.stats=this.activeSession.getStats());this.activeSession.step()}catch(e){if(!(e instanceof YG))throw e;return void this.skipFailedPair(t,e)}if(this.stats=this.activeSession.getStats(),!this.activeSession.isComplete())return;const e=this.activeSession.getResult();this.activeSession=null;for(const t of[e.candidate.first,e.candidate.second]){const e=this.outputTraces.findIndex(e=\u003ee.connection_name===t.connection_name);if(e\u003c0)throw new Error(`DifferentialPairReroutingSolver: accepted replacement for unknown connection \"${t.connection_name}\"`);this.outputTraces[e]=t}this.reroutedPairs.push(t),this.nextPairIndex++,this.nextPairIndex!==this.params.simpleRouteJson.differentialPairs.length?this.stats={phase:\"accepted\",pair:t.connectionNames.join(\"/\"),pairIndex:this.nextPairIndex-1,pairCount:this.params.simpleRouteJson.differentialPairs.length}:this.finish()}finish(){this.activeConnectionNames=null,this.solved=!0,this.stats={phase:\"complete\",acceptedPairCount:this.reroutedPairs.length,skippedPairCount:this.failures.length}}skipFailedPair(t,e){this.failures.push({connectionNames:[...t.connectionNames],reason:e.reason,message:e.message}),this.activeSession=null,this.nextPairIndex++,this.nextPairIndex!==this.params.simpleRouteJson.differentialPairs.length?this.stats={phase:\"skipped\",pair:t.connectionNames.join(\"/\"),pairIndex:this.nextPairIndex-1,pairCount:this.params.simpleRouteJson.differentialPairs.length,skippedPairCount:this.failures.length}:this.finish()}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved)throw new Error(\"DifferentialPairReroutingSolver: getOutput() called before completion\");return this.getBestEffortOutput()}getBestEffortOutput(){return{traces:HG(this.outputTraces),reroutedPairs:this.reroutedPairs.map(t=\u003e({...t,connectionNames:[...t.connectionNames]})),failures:this.failures.map(t=\u003e({...t,connectionNames:[...t.connectionNames]}))}}computeProgress(){return this.solved?1:0===this.params.simpleRouteJson.differentialPairs.length?0:(this.nextPairIndex+(this.activeSession?.getProgress()??0))/this.params.simpleRouteJson.differentialPairs.length}visualize(){return iU({traces:this.outputTraces,obstacles:this.params.simpleRouteJson.obstacles,bounds:this.params.simpleRouteJson.bounds,layerCount:this.params.simpleRouteJson.layerCount,activeConnectionNames:this.activeConnectionNames,previewPath:this.activeSession?.getPreviewPath()??null})}},sU=1e-8,aU=class extends kt{constructor(t){super(),this.input=t,this.traces=HG(t.traces),this.MAX_ITERATIONS=Math.max(1,t.reroutedPairs.length+1)}input;traces;nextPairIndex=0;getSolverName(){return\"FortyFiveDegreeSimplificationSolver\"}_step(){const t=this.input.reroutedPairs[this.nextPairIndex];if(!t)return this.solved=!0,void(this.stats={phase:\"complete\",simplifiedPairCount:this.nextPairIndex});this.traces=(t=\u003e{const e=t.pair.connectionNames.join(\"/\"),n=t.pair.connectionNames.map(e=\u003et.traces.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:t})=\u003et.connection_name===e));if(1!==n[0].length||1!==n[1].length)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} must resolve to exactly two traces`);const o=n[0][0].index,i=n[1][0].index;if(o===i)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} resolved both members to one trace`);const r=structuredClone(t.traces),s={immutableTraces:r.filter((t,e)=\u003ee!==o\u0026\u0026e!==i),obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,minTraceToPadEdgeClearance:t.minTraceToPadEdgeClearance},a=n=\u003e{const r=LG(n[o],t.layerCount),s=LG(n[i],t.layerCount);let a=0;for(const[t,n]of[[r.segments,s.segments],[s.segments,r.segments]])for(const o of t){if(null!==o.terminal)continue;const t=n.filter(t=\u003et.layer===o.layer);if(0===t.length)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} lost common-layer interior copper`);a=Math.max(a,Math.min(...t.map(t=\u003ecG(o.start,o.end,t.start,t.end))))}return a},c=e=\u003e{const n=LG(e[o],t.layerCount),r=LG(e[i],t.layerCount);let s=Number.POSITIVE_INFINITY;for(const[t,e]of[[n.segments,r.segments],[r.segments,n.segments]])for(const n of t)if(null===n.terminal)for(const t of e)t.layer===n.layer\u0026\u0026(s=Math.min(s,cG(n.start,n.end,t.start,t.end)-n.width/2-t.width/2));return Number.isFinite(s)?s:null},l=e=\u003e{const n=LG(e[o],t.layerCount),r=LG(e[i],t.layerCount);return ZG(n,r,s)};if(!l(r))throw new Error(`FortyFiveDegreeSimplificationSolver: rerouted pair ${e} has invalid complete copper before simplification`);if(void 0!==t.pair.maxUncoupledLength\u0026\u0026void 0!==t.pair.minimumCenterlineDistance\u0026\u0026void 0!==t.pair.maximumCenterlineDistance\u0026\u0026Math.abs(t.pair.minimumCenterlineDistance-t.pair.maximumCenterlineDistance)\u003c=sU)return r;const d=LG(r[o],t.layerCount),h=LG(r[i],t.layerCount),u=Math.abs(FG(d)-FG(h)),p=c(r),m=t.pair.maximumCenterlineDistance??1+d.width/2+h.width/2,g=Math.min(a(r),m),f=t=\u003e{if(!l(t))return!1;if(a(t)\u003eg+sU)return!1;const e=c(t);return null===p||null===e||e\u003e=p-sU},y=(t,e)=\u003e{const n=Math.abs(e.x-t.x),o=Math.abs(e.y-t.y),i=e.x\u003e=t.x?1:-1,r=e.y\u003e=t.y?1:-1,s=[],a={x:e.x-i*o,y:t.y};(a.x-t.x)*i\u003e=-1e-8\u0026\u0026(a.x-e.x)*i\u003c=sU\u0026\u0026s.push([t,a,e]);const c={x:t.x,y:e.y-r*n};(c.y-t.y)*r\u003e=-1e-8\u0026\u0026(c.y-e.y)*r\u003c=sU\u0026\u0026s.push([t,c,e]);const l={x:t.x+i*Math.min(n,o),y:t.y+r*Math.min(n,o)};return s.push([t,l,e]),s.map((t,e)=\u003e{const n=t.filter((e,n)=\u003e0===n||Math.hypot(e.x-t[n-1].x,e.y-t[n-1].y)\u003esU),o=n.slice(0,-1).map((t,e)=\u003e{const o=n[e+1],i=Math.abs(o.x-t.x),r=Math.abs(o.y-t.y);return{length:Math.hypot(i,r),straight:i\u003c=sU||r\u003c=sU?Math.hypot(i,r):0}});return{points:n,usableStraightLength:Math.max(0,...o.map(t=\u003et.straight)),bendCount:Math.max(0,n.length-2),priority:e}}).filter((t,e,n)=\u003en.findIndex(e=\u003eJSON.stringify(e.points)===JSON.stringify(t.points))===e).sort((t,e)=\u003ee.usableStraightLength-t.usableStraightLength||t.bendCount-e.bendCount||t.priority-e.priority)},_=t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n];if(\"wire\"===o?.route_type)for(let i=t.route.length-1;i\u003e=n+1;i--){if(0===n||i===t.route.length-1)continue;const r=t.route[i];\"wire\"===r?.route_type\u0026\u0026r.layer===o.layer\u0026\u0026(t.route.slice(n+1,i).some(t=\u003e\"wire\"!==t.route_type||t.layer!==o.layer)||e.push({startIndex:n,endIndex:i,skippedPointCount:i-n-1}))}}return e.sort((t,e)=\u003ee.skippedPointCount-t.skippedPointCount||t.startIndex-e.startIndex||e.endIndex-t.endIndex)},b=(t,e,n)=\u003e{const o=t.route[e.startIndex],i=t.route[e.endIndex],r=Math.max(o.width,i.width),s=n.points.slice(1,-1).map(t=\u003e({route_type:\"wire\",...t,width:r,layer:o.layer}));return{...t,route:[...t.route.slice(0,e.startIndex+1),...s,...t.route.slice(e.endIndex)]}};for(const t of[o,i]){let e=!0;for(;e;){e=!1;const n=r[t];for(const s of _(n)){const a=n.route[s.startIndex],c=n.route[s.endIndex],l=n.route.slice(s.startIndex,s.endIndex+1),d=l.slice(0,-1).every((t,e)=\u003e{const n=l[e+1],o=Math.abs(n.x-t.x),i=Math.abs(n.y-t.y);return o\u003c=sU||i\u003c=sU||Math.abs(o-i)\u003c=sU});for(const h of y(a,c)){if(h.points.length\u003e=l.length\u0026\u0026d)continue;const a=b(n,s,h),c=[...r];if(c[t]=a,JSON.stringify(a.route)===JSON.stringify(n.route))continue;if(f(c)){r[t]=a,e=!0;break}const u=t===o?i:o,p=r[u],m=_(p).find(t=\u003et.startIndex===s.startIndex\u0026\u0026t.endIndex===s.endIndex);if(!m)continue;const g=p.route[m.startIndex],x=p.route[m.endIndex];for(const n of y(g,x)){const o=b(p,m,n),i=[...c];if(i[u]=o,f(i)){r[t]=a,r[u]=o,e=!0;break}}if(e)break}if(e)break}}}if(!f(r))throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} produced invalid complete copper`);const x=LG(r[o],t.layerCount),v=LG(r[i],t.layerCount),S=Math.abs(FG(x)-FG(v));return Math.abs(S-u)\u003et.pair.lengthTolerance+sU?structuredClone(t.traces):r})({traces:this.traces,pair:t,obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,minTraceToPadEdgeClearance:this.input.minTraceToPadEdgeClearance}),this.nextPairIndex++,this.stats={phase:\"simplifying\",pair:t.connectionNames.join(\"/\"),pairIndex:this.nextPairIndex-1,pairCount:this.input.reroutedPairs.length}}getConstructorParams(){return[this.input]}getOutput(){if(!this.solved)throw new Error(\"FortyFiveDegreeSimplificationSolver: getOutput() called before completion\");return this.getBestEffortOutput()}getBestEffortOutput(){return{traces:HG(this.traces),reroutedPairs:this.input.reroutedPairs.map(t=\u003e({...t,connectionNames:[...t.connectionNames]}))}}computeProgress(){return this.solved?1:0===this.input.reroutedPairs.length?0:this.nextPairIndex/this.input.reroutedPairs.length}visualize(){return iU({traces:this.traces,obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,activeConnectionNames:this.input.reroutedPairs[this.nextPairIndex]?.connectionNames??null,previewPath:null})}},cU=class extends kt{constructor(t){super(),this.input=t}input;output=null;visualizationTraces=null;getSolverName(){return\"HdRouteReconstructionSolver\"}_step(){this.visualizationTraces=(t=\u003e{const{simpleRouteJson:e}=t.params;if(t.result.matchedHdRoutes.length!==t.binding.solverParams.hdRoutes.length)throw new Error(\"PostProcessingSolver: LengthMatchingSolver changed the search route count\");const n=structuredClone(t.binding.baseTraces);for(const o of t.binding.traceBindings){const i=t.result.matchedHdRoutes[o.matchedRouteIndex];if(!i)throw new Error(`PostProcessingSolver: missing matched route at index ${o.matchedRouteIndex}`);const r=n[o.traceIndex];if(!r)throw new Error(`PostProcessingSolver: missing simplified trace binding at index ${o.traceIndex}`);if(r.connection_name!==i.connectionName)throw new Error(`PostProcessingSolver: route binding changed connection \"${r.connection_name}\" to \"${i.connectionName}\"`);if(i.route.length\u003c2)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" has incomplete geometry`);const s=i.route[0],a=i.route.at(-1);if(Math.hypot(s.x-o.startEndpoint.x,s.y-o.startEndpoint.y)\u003e1e-8||s.z!==o.startEndpoint.z||Math.hypot(a.x-o.endEndpoint.x,a.y-o.endEndpoint.y)\u003e1e-8||a.z!==o.endEndpoint.z)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" moved a preserved endpoint`);const c=[];let l=0;const d=t=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:t.traceThickness??i.traceThickness,layer:AG(t.z,e.layerCount)});c.push(d(i.route[0]));for(let t=1;t\u003ci.route.length;t++){const n=i.route[t-1],r=i.route[t];if(n.z===r.z){c.push(d(r));continue}if(Math.hypot(n.x-r.x,n.y-r.y)\u003e1e-8)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" moves while changing layers`);const s=o.viaTemplates[l++];if(!s)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" added an unbound via`);if(Math.hypot(s.x-r.x,s.y-r.y)\u003e1e-8)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" moved a preserved via`);const a=AG(n.z,e.layerCount),h=AG(r.z,e.layerCount),u=new Set([s.from_layer,s.to_layer]);if(!u.has(a)||!u.has(h))throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" changed a preserved via span`);c.push({...s}),c.push(d(r))}if(l!==o.viaTemplates.length)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" removed a preserved via`);const h=c.filter(t=\u003e\"wire\"===t.route_type);for(const t of h)delete t.start_pcb_port_id,delete t.end_pcb_port_id;o.startPortId\u0026\u0026(h[0].start_pcb_port_id=o.startPortId),o.endPortId\u0026\u0026(h.at(-1).end_pcb_port_id=o.endPortId),n[o.traceIndex]={...r,route:c}}for(const o of t.binding.solverParams.differentialPairs){const t=o.connectionNames.join(\"/\"),i=o.connectionNames.map(t=\u003en.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:e})=\u003ee.connection_name===t));if(1!==i[0].length||1!==i[1].length)throw new Error(`PostProcessingSolver: reconstructed pair ${t} does not resolve to complete copper`);const r=i[0][0],s=i[1][0],a=LG(r.trace,e.layerCount),c=LG(s.trace,e.layerCount),l=Math.abs(FG(a)-FG(c));if(l\u003eo.lengthTolerance+1e-7)throw new XG({message:`PostProcessingSolver: reconstructed pair ${t} exceeds length tolerance ${o.lengthTolerance} with error ${l}`,connectionNames:[...o.connectionNames],reason:\"length-tolerance-unsatisfied\"});if(!ZG(a,c,{immutableTraces:n.filter((t,e)=\u003ee!==r.index\u0026\u0026e!==s.index),obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,minTraceToPadEdgeClearance:e.minTraceToPadEdgeClearance}))throw new XG({message:`PostProcessingSolver: length matching produced invalid complete copper for pair ${t}`,connectionNames:[...o.connectionNames],reason:\"invalid-final-copper\"})}return n})(this.input),this.output=$G({...this.input,rejectInsideJumperPad:!0}),this.stats={phase:\"complete\",routeCount:this.output.hdRoutes.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){if(!this.output||!this.solved)throw new Error(\"HdRouteReconstructionSolver: getOutput() called before completion\");return structuredClone(this.output)}visualize(){const t=this.visualizationTraces??this.input.simplified.traces,{obstacles:e,bounds:n,layerCount:o}=this.input.params.simpleRouteJson;return iU({traces:t,obstacles:e,bounds:n,layerCount:o,activeConnectionNames:null,previewPath:null})}};var lU=class extends Dt{differentialPairReroutingSolver;fortyFiveDegreeSimplificationSolver;lengthMatchingSolver;hdRouteReconstructionSolver;lengthMatchingBinding=null;model;fallbackOutput=null;postProcessingErrors=[];pipelineDef=[Lt(\"differentialPairReroutingSolver\",rU,t=\u003e[t.model.params]),Lt(\"fortyFiveDegreeSimplificationSolver\",aU,t=\u003e{const e=t.getStageOutput(\"differentialPairReroutingSolver\");if(!e)throw new Error(\"PostProcessingSolver: rerouting stage completed without output\");const{obstacles:n,bounds:o,layerCount:i,minTraceToPadEdgeClearance:r}=t.model.params.simpleRouteJson;return[{...e,obstacles:n,bounds:o,layerCount:i,minTraceToPadEdgeClearance:r}]}),Lt(\"lengthMatchingSolver\",RG,t=\u003e{const e=t.getStageOutput(\"fortyFiveDegreeSimplificationSolver\");if(!e)throw new Error(\"PostProcessingSolver: 45-degree simplification stage completed without output\");return t.lengthMatchingBinding=BG({result:e,params:t.model.params}),[t.lengthMatchingBinding.solverParams]}),Lt(\"hdRouteReconstructionSolver\",cU,t=\u003e{const e=t.getStageOutput(\"fortyFiveDegreeSimplificationSolver\"),n=t.getStageOutput(\"lengthMatchingSolver\");if(!e||!n||!t.lengthMatchingBinding)throw new Error(\"PostProcessingSolver: reconstruction stage is missing a required binding or output\");return[{binding:t.lengthMatchingBinding,result:n,simplified:e,params:t.model.params,model:t.model}]},{onSolved:t=\u003e{const e=t.getStageOutput(\"differentialPairReroutingSolver\");if(!e)throw new Error(\"PostProcessingSolver: cannot summarize missing rerouting output\");t.stats={phase:\"complete\",acceptedPairCount:e.reroutedPairs.length},e.failures.length\u003e0\u0026\u0026(t.stats.skippedPairCount=e.failures.length,t.stats.postProcessingErrorCount=e.failures.length)}})];constructor(t){super(structuredClone(t));let e=null;try{!function(t){if(!t||\"object\"!=typeof t)throw new Error(\"PostProcessingSolver: params must be an object\");if(!Array.isArray(t.hdRoutes))throw new Error(\"PostProcessingSolver: hdRoutes must be an array\");if(!Array.isArray(t.differentialPairs))throw new Error(\"PostProcessingSolver: differentialPairs must be an array\");if(!Array.isArray(t.obstacles))throw new Error(\"PostProcessingSolver: obstacles must be an array\");if(void 0!==t.minTraceToPadEdgeClearance\u0026\u0026(!Number.isFinite(t.minTraceToPadEdgeClearance)||t.minTraceToPadEdgeClearance\u003c0))throw new Error(\"PostProcessingSolver: minTraceToPadEdgeClearance must be finite and nonnegative\");if(!Number.isInteger(t.layerCount)||t.layerCount\u003c1)throw new Error(\"PostProcessingSolver: layerCount must be a positive integer\");for(const e of t.obstacles){if(!e||\"object\"!=typeof e||\"rect\"!==e.type||!e.center||!Number.isFinite(e.center.x)||!Number.isFinite(e.center.y)||!Number.isFinite(e.width)||e.width\u003c=0||!Number.isFinite(e.height)||e.height\u003c=0||!Array.isArray(e.layers)||e.layers.some(t=\u003e\"string\"!=typeof t)||!Array.isArray(e.connectedTo)||e.connectedTo.some(t=\u003e\"string\"!=typeof t||0===t.length)||void 0!==e.ccwRotationDegrees\u0026\u0026!Number.isFinite(e.ccwRotationDegrees))throw new Error(\"PostProcessingSolver: obstacle declaration is invalid\");uG(e,t.layerCount)}const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds??{};if(![e,n,o,i].every(Number.isFinite)||e\u003e=n||o\u003e=i)throw new Error(\"PostProcessingSolver: bounds must have finite positive extents\");const r=new Set(t.differentialPairs.flatMap(t=\u003et.connectionNames));for(const e of t.hdRoutes){if(!e||\"object\"!=typeof e||\"string\"!=typeof e.connectionName||0===e.connectionName.length||void 0!==e.rootConnectionName\u0026\u0026(\"string\"!=typeof e.rootConnectionName||0===e.rootConnectionName.length)||!Number.isFinite(e.traceThickness)||e.traceThickness\u003c=0||!Number.isFinite(e.viaDiameter)||e.viaDiameter\u003c0||0===e.viaDiameter\u0026\u0026r.has(e.connectionName)||!Array.isArray(e.route)||!Array.isArray(e.vias)||void 0!==e.jumpers\u0026\u0026!Array.isArray(e.jumpers))throw new Error(\"PostProcessingSolver: HD route declaration is invalid\");if(void 0!==e.startPcbPortId\u0026\u0026(\"string\"!=typeof e.startPcbPortId||0===e.startPcbPortId.length)||void 0!==e.endPcbPortId\u0026\u0026(\"string\"!=typeof e.endPcbPortId||0===e.endPcbPortId.length))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has invalid terminal metadata`);for(const n of e.route)if(!n||\"object\"!=typeof n||!Number.isFinite(n.x)||!Number.isFinite(n.y)||!Number.isInteger(n.z)||n.z\u003c0||n.z\u003e=t.layerCount||void 0!==n.traceThickness\u0026\u0026(!Number.isFinite(n.traceThickness)||n.traceThickness\u003c=0))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has an invalid route point`);for(const n of e.vias)if(!n||\"object\"!=typeof n||!Number.isFinite(n.x)||!Number.isFinite(n.y)||void 0!==n.zLayers\u0026\u0026(!Array.isArray(n.zLayers)||n.zLayers.some(e=\u003e!Number.isInteger(e)||e\u003c0||e\u003e=t.layerCount)))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has an invalid via`);if(e.vias.length\u003e0\u0026\u0026e.viaDiameter\u003c=0)throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has a non-positive via diameter`);for(const t of e.jumpers??[])if(!(t\u0026\u0026\"object\"==typeof t\u0026\u0026\"jumper\"===t.route_type\u0026\u0026Number.isFinite(t.start?.x)\u0026\u0026Number.isFinite(t.start?.y)\u0026\u0026Number.isFinite(t.end?.x)\u0026\u0026Number.isFinite(t.end?.y)\u0026\u0026[\"0603\",\"1206\",\"1206x4_pair\"].includes(t.footprint)))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has an invalid jumper`)}const s=new Set;for(const e of t.differentialPairs){if(!e||\"object\"!=typeof e||!Array.isArray(e.connectionNames)||2!==e.connectionNames.length||e.connectionNames[0]===e.connectionNames[1]||!e.connectionNames.every(t=\u003e\"string\"==typeof t\u0026\u0026t.length\u003e0)||!Number.isFinite(e.lengthTolerance)||e.lengthTolerance\u003c0)throw new Error(\"PostProcessingSolver: differential pair declaration is invalid\");for(const t of[e.minimumCenterlineDistance,e.maximumCenterlineDistance])if(void 0!==t\u0026\u0026(!Number.isFinite(t)||t\u003c=0))throw new Error(\"PostProcessingSolver: differential pair centerline distances must be positive finite numbers\");if(void 0!==e.maxUncoupledLength\u0026\u0026(!Number.isFinite(e.maxUncoupledLength)||e.maxUncoupledLength\u003c0))throw new Error(\"PostProcessingSolver: differential pair maxUncoupledLength must be a non-negative finite number\");if(void 0!==e.minimumCenterlineDistance\u0026\u0026void 0!==e.maximumCenterlineDistance\u0026\u0026e.minimumCenterlineDistance\u003ee.maximumCenterlineDistance)throw new Error(\"PostProcessingSolver: differential pair minimumCenterlineDistance cannot exceed maximumCenterlineDistance\");for(const t of e.connectionNames){if(s.has(t))throw new Error(`PostProcessingSolver: connection \"${t}\" belongs to multiple differential pairs`);s.add(t)}}for(const e of[.25,.5])QG({config:t.routingGrid,bounds:t.bounds,defaultInnerGridStep:e})}(t)}catch(t){if(!(t instanceof VG))throw t;e=t}if(this.model=jG(t),e)return void this.finishWithBestEffortOutput({stage:\"differentialPairReroutingSolver\",message:e.message,reason:e.reason});const n=WG(this.model.params)+Math.max(1,t.differentialPairs.length+1)+1e5+10;if(!Number.isSafeInteger(n))throw new Error(\"PostProcessingSolver: derived pipeline iteration bound exceeds the safe integer range\");this.MAX_ITERATIONS=n}getSolverName(){return\"PostProcessingSolver\"}getConstructorParams(){return[structuredClone(this.inputProblem)]}_step(){const t=this.getCurrentStageName();try{super._step()}catch(e){const n=this.classifyOptimizationFailure(e,t);if(!n)throw e;return void this.finishWithBestEffortOutput(n)}if(!this.failed)return;const e=this.classifyIterationFailure(this.error,t);if(!e)throw new Error(this.error??\"PostProcessingSolver failed without an error message\");this.finishWithBestEffortOutput(e)}tryFinalAcceptance(){const t=this.getCurrentStageName();\"differentialPairReroutingSolver\"!==t\u0026\u0026\"lengthMatchingSolver\"!==t||this.finishWithBestEffortOutput({stage:t,message:\"PostProcessingSolver reached its iteration limit\",reason:\"iteration-limit-exhausted\"})}classifyOptimizationFailure(t,e){return\"lengthMatchingSolver\"===e\u0026\u0026t instanceof IG?{stage:e,message:t.message,connectionName:t.connectionName,reason:t.reason}:\"hdRouteReconstructionSolver\"===e\u0026\u0026t instanceof XG||\"differentialPairReroutingSolver\"===e\u0026\u0026t instanceof YG\u0026\u0026\"no-valid-candidate\"===t.reason?{stage:e,message:t.message,connectionNames:[...t.connectionNames],reason:t.reason}:null}classifyIterationFailure(t,e){return\"differentialPairReroutingSolver\"!==e\u0026\u0026\"lengthMatchingSolver\"!==e?null:t\u0026\u0026t.endsWith(\"ran out of iterations\")?{stage:e,message:t,reason:\"iteration-limit-exhausted\"}:null}createBestEffortOutput(t){let e=this.lengthMatchingBinding;if(!e){const t=this.getStageOutput(\"fortyFiveDegreeSimplificationSolver\")??this.fortyFiveDegreeSimplificationSolver?.getBestEffortOutput(),n=this.getStageOutput(\"differentialPairReroutingSolver\")??this.differentialPairReroutingSolver?.getBestEffortOutput(),o=t??n;o\u0026\u0026(e=BG({result:o,params:this.model.params}))}if(!e)return{output:{hdRoutes:structuredClone(this.inputProblem.hdRoutes),postProcessingErrors:[]},source:\"input-hd-routes\"};let n=this.getStageOutput(\"lengthMatchingSolver\");return n||(n=this.lengthMatchingSolver?.getBestEffortOutput()),n\u0026\u0026\"invalid-final-copper\"!==t.reason||(n={matchedHdRoutes:e.solverParams.hdRoutes}),{output:$G({binding:e,result:n,model:this.model}),source:\"best-effort-hd-routes\"}}finishWithBestEffortOutput(t){const e=this.createBestEffortOutput(t),n={type:\"post_processing_error\",...t,returnedRouteSource:e.source};this.postProcessingErrors.push(n),this.fallbackOutput=e.output,this.activeSubSolver=null,this.error=null,this.failed=!1,this.solved=!0,this.progress=1,this.stats={phase:\"complete\",postProcessingErrorCount:this.postProcessingErrors.length}}getOutput(){if(!this.solved)throw new Error(\"PostProcessingSolver: getOutput() called before the solver completed\");const t=this.fallbackOutput??this.getStageOutput(\"hdRouteReconstructionSolver\");if(!t)throw new Error(\"PostProcessingSolver: completed pipeline is missing reconstruction output\");const e=this.getStageOutput(\"differentialPairReroutingSolver\")??this.differentialPairReroutingSolver?.getBestEffortOutput(),n=e?.failures??[];let o=\"input-hd-routes\";(e?.reroutedPairs.length??0)\u003e0\u0026\u0026(o=\"best-effort-hd-routes\");const i=[...n.map(t=\u003e({type:\"post_processing_error\",stage:\"differentialPairReroutingSolver\",message:t.message,connectionNames:[...t.connectionNames],reason:t.reason,returnedRouteSource:o})),...this.postProcessingErrors],r=structuredClone(t);return r.postProcessingErrors=structuredClone(i),r}initialVisualize(){if(this.fallbackOutput)return{lines:this.fallbackOutput.hdRoutes.map(t=\u003e({points:t.route.map(({x:t,y:e})=\u003e({x:t,y:e})),strokeWidth:t.traceThickness}))};const{traces:t,obstacles:e,bounds:n,layerCount:o}=this.model.params.simpleRouteJson;return iU({traces:structuredClone(t),obstacles:e,bounds:n,layerCount:o,activeConnectionNames:null,previewPath:null})}finalVisualize(){if(this.fallbackOutput)return this.initialVisualize();const t=jG({...this.inputProblem,hdRoutes:this.getOutput().hdRoutes}),{traces:e,obstacles:n,bounds:o,layerCount:i}=t.params.simpleRouteJson;return iU({traces:e,obstacles:n,bounds:o,layerCount:i,activeConnectionNames:null,previewPath:null})}},dU=class t{static generators=new Map;static register(e){t.generators.set(e.componentKind,e)}static create(e){const n=e.detectedComponent.componentKind,o=t.generators.get(n);if(!o)throw new Error(`No topology generator registered for component kind \"${n}\"`);return new o(e)}},hU=t=\u003e[t.obstacle.obstacleId??t.obstacle.componentId??\"obstacle\",t.start.x.toFixed(4),t.start.y.toFixed(4),t.end.x.toFixed(4),t.end.y.toFixed(4),t.expansionDirection.x,t.expansionDirection.y].join(\":\"),uU=t=\u003e{let e=0;for(const n of t)e=31*e+n.charCodeAt(0)\u003e\u003e\u003e0;return e},pU=(t,e)=\u003e`hsla(${uU(hU(t))%360},72%,36%,${e})`,mU=t=\u003e{const e=t.expansionDirection;return e.x\u003c0?\"left\":e.x\u003e0?\"right\":e.y\u003c0?\"bottom\":\"top\"},gU=t=\u003e({x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2}),fU=t=\u003e{const e=/^bga-gapfill-(\\d+)-/.exec(t.capacityMeshNodeId);return e?Number.parseInt(e[1],10):null},yU=(t,e)=\u003e{const n=gU(t),o=gU(e),i=n.y-o.y;if(Math.abs(i)\u003e1e-6)return i;const r=n.x-o.x;return Math.abs(r)\u003e1e-6?r:hU(t).localeCompare(hU(e))},_U=t=\u003e{const e=[...t].sort(yU),n=[];let o=e.shift();for(;o\u0026\u0026(n.push(o),0!==e.length);){const t=gU(o);let n=0,i=Number.POSITIVE_INFINITY;for(let o=0;o\u003ce.length;o++){const r=e[o],s=gU(r),a=(s.x-t.x)**2+(s.y-t.y)**2;a\u003ci-1e-9?(i=a,n=o):Math.abs(a-i)\u003c=1e-9\u0026\u0026yU(r,e[n])\u003c0\u0026\u0026(n=o)}o=e.splice(n,1)[0]}return n},bU=(t,e)=\u003e{const n=hU(t),o=e.findIndex(t=\u003ehU(t)===n);return o\u003e=0?`E${o+1}`:`E${uU(n).toString(36).slice(0,4)}`},xU=t=\u003et.flatMap(t=\u003e{const e=Ve(t);return[{obstacle:t,start:{x:e.minX,y:e.minY},end:{x:e.minX,y:e.maxY},expansionDirection:{x:-1,y:0}},{obstacle:t,start:{x:e.maxX,y:e.minY},end:{x:e.maxX,y:e.maxY},expansionDirection:{x:1,y:0}},{obstacle:t,start:{x:e.minX,y:e.minY},end:{x:e.maxX,y:e.minY},expansionDirection:{x:0,y:-1}},{obstacle:t,start:{x:e.minX,y:e.maxY},end:{x:e.maxX,y:e.maxY},expansionDirection:{x:0,y:1}}]}),vU=.001,SU=.001,IU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;meshIndex;allEdges=[];queueEdges=[];disconnectedEdges=[];currentEdge=null;lastSearchBounds=null;lastCandidateMeshNodes=[];lastMatchedMeshNode=null;_setup(){const t=Math.max(this.inputProblem.meshNodes.length,1);this.meshIndex=new Bt(t);for(const t of this.inputProblem.meshNodes){const e=Ve(t);this.meshIndex.add(e.minX,e.minY,e.maxX,e.maxY)}this.meshIndex.finish();const e=xU(this.inputProblem.unmarkedComponentObstacles);this.queueEdges=e,this.allEdges=_U(e),this.currentEdge=null,this.lastSearchBounds=null,this.lastCandidateMeshNodes=[],this.lastMatchedMeshNode=null}_step(){const t=this.queueEdges.shift();if(!t)return this.currentEdge=null,this.lastSearchBounds=null,this.lastCandidateMeshNodes=[],this.lastMatchedMeshNode=null,void(this.solved=!0);this.currentEdge=t,this.lastMatchedMeshNode=null;const e=Math.abs(t.start.x-t.end.x)\u003c=vU,n=e?{minX:t.start.x-SU,maxX:t.start.x+SU,minY:Math.min(t.start.y,t.end.y),maxY:Math.max(t.start.y,t.end.y)}:{minX:Math.min(t.start.x,t.end.x),maxX:Math.max(t.start.x,t.end.x),minY:t.start.y-SU,maxY:t.start.y+SU};this.lastSearchBounds=n;const o=this.meshIndex.search(n.minX,n.minY,n.maxX,n.maxY);this.lastCandidateMeshNodes=o.map(t=\u003ethis.inputProblem.meshNodes[t]);let i=!1;for(const n of o){const o=this.inputProblem.meshNodes[n],r=Ve(o);if(e){if(!(Math.min(r.maxY,Math.max(t.start.y,t.end.y))-Math.max(r.minY,Math.min(t.start.y,t.end.y))\u003evU))continue;if(-1===t.expansionDirection.x\u0026\u0026Math.abs(r.maxX-t.start.x)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}if(1===t.expansionDirection.x\u0026\u0026Math.abs(r.minX-t.start.x)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}continue}if(Math.min(r.maxX,Math.max(t.start.x,t.end.x))-Math.max(r.minX,Math.min(t.start.x,t.end.x))\u003evU){if(-1===t.expansionDirection.y\u0026\u0026Math.abs(r.maxY-t.start.y)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}if(1===t.expansionDirection.y\u0026\u0026Math.abs(r.minY-t.start.y)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}}}i||this.disconnectedEdges.push(t)}getOutput(){return this.disconnectedEdges}visualize(){const t=this.disconnectedEdges,e=this.allEdges.length\u003e0?this.allEdges:[...t,...this.currentEdge?[this.currentEdge]:[]],n=this.currentEdge?pU(this.currentEdge,.88):\"rgba(40,40,40,0.4)\",o=this.inputProblem.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(120,120,120,0.18)\":\"rgba(120,120,120,0.08)\",stroke:t._containsObstacle?\"rgba(120,120,120,0.42)\":\"rgba(120,120,120,0.24)\"})),i=this.lastSearchBounds\u0026\u0026this.currentEdge?[{center:(r=this.lastSearchBounds,{x:(r.minX+r.maxX)/2,y:(r.minY+r.maxY)/2}),width:this.lastSearchBounds.maxX-this.lastSearchBounds.minX,height:this.lastSearchBounds.maxY-this.lastSearchBounds.minY,fill:pU(this.currentEdge,.1),stroke:pU(this.currentEdge,.36),label:[bU(this.currentEdge,e),\"search band\"].join(\" \")}]:[];var r;const s=this.lastCandidateMeshNodes.map(t=\u003e({...Dc(t,{rectMargin:.018}),fill:t===this.lastMatchedMeshNode?\"rgba(0,180,90,0.24)\":this.currentEdge?pU(this.currentEdge,.16):\"rgba(80,120,160,0.16)\",stroke:t===this.lastMatchedMeshNode?\"rgba(0,150,80,0.88)\":n,label:[t===this.lastMatchedMeshNode?\"matched\":\"candidate\",t.capacityMeshNodeId,`z:${t.availableZ.join(\",\")}`].join(\"\\n\")})),a=this.inputProblem.unmarkedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(160,160,160,0.10)\",stroke:\"rgba(160,160,160,0.40)\",label:t.obstacleId??t.componentId??\"obstacle\"})),c=t.map(t=\u003e({points:[t.start,t.end],strokeColor:pU(t,.14),strokeWidth:.01,strokeDash:\"5 4\",label:[bU(t,e),mU(t),\"disconnected\"].join(\" \")})),l=[],d=[];if(this.currentEdge){const t=gU(this.currentEdge);l.push({points:[this.currentEdge.start,this.currentEdge.end],strokeColor:pU(this.currentEdge,1),strokeWidth:.06,label:[bU(this.currentEdge,e),mU(this.currentEdge),\"checking\"].join(\" \")},{points:[t,{x:t.x+.16*this.currentEdge.expansionDirection.x,y:t.y+.16*this.currentEdge.expansionDirection.y}],strokeColor:pU(this.currentEdge,.82),strokeWidth:.02,strokeDash:\"3 3\"}),d.push({...t,color:pU(this.currentEdge,1),label:bU(this.currentEdge,e)})}return{rects:[...o,...i,...s,...a],lines:[...c,...l],points:d}}},CU=.001,PU=.001,MU=1e-6,NU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;meshIndex;meshBounds;expandedNodes=[];_setup(){const t=Math.max(this.inputProblem.meshNodes.length,1);this.meshIndex=new Bt(t);let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const t of this.inputProblem.meshNodes){const r=Ve(t);this.meshIndex.add(r.minX,r.minY,r.maxX,r.maxY),e=Math.min(e,r.minX),n=Math.max(n,r.maxX),o=Math.min(o,r.minY),i=Math.max(i,r.maxY)}this.meshIndex.finish(),this.meshBounds=this.inputProblem.meshNodes.length?{minX:e,maxX:n,minY:o,maxY:i}:{minX:0,maxX:0,minY:0,maxY:0}}getObstacleAvailableZ(t){return t.__zLayers??t.layers.map(t=\u003eko(t,this.inputProblem.layerCount))}getSharedOverlapArea(t,e){if(!t.availableZ.some(t=\u003ee.availableZ.includes(t)))return 0;const n=Ve(t),o=Ve(e),i=Math.min(n.maxX,o.maxX)-Math.max(n.minX,o.minX),r=Math.min(n.maxY,o.maxY)-Math.max(n.minY,o.minY);return i\u003c=MU||r\u003c=MU?0:i*r}getNodeObstacleOverlapArea(t,e){const n=this.getObstacleAvailableZ(e);if(!t.availableZ.some(t=\u003en.includes(t)))return 0;const o=Ve(t),i=Ve(e),r=Math.min(o.maxX,i.maxX)-Math.max(o.minX,i.minX),s=Math.min(o.maxY,i.maxY)-Math.max(o.minY,i.minY);return r\u003c=MU||s\u003c=MU?0:r*s}getClosestMeshNode(t,e){const n=Math.abs(t.start.x-t.end.x)\u003c=CU,o=this.getObstacleAvailableZ(t.obstacle),i=n?t.expansionDirection.x\u003c0?{minX:this.meshBounds.minX,maxX:t.start.x,minY:Math.min(t.start.y,t.end.y)-PU,maxY:Math.max(t.start.y,t.end.y)+PU}:{minX:t.start.x,maxX:this.meshBounds.maxX,minY:Math.min(t.start.y,t.end.y)-PU,maxY:Math.max(t.start.y,t.end.y)+PU}:t.expansionDirection.y\u003c0?{minX:Math.min(t.start.x,t.end.x)-PU,maxX:Math.max(t.start.x,t.end.x)+PU,minY:this.meshBounds.minY,maxY:t.start.y}:{minX:Math.min(t.start.x,t.end.x)-PU,maxX:Math.max(t.start.x,t.end.x)+PU,minY:t.start.y,maxY:this.meshBounds.maxY},r=this.meshIndex.search(i.minX,i.minY,i.maxX,i.maxY);let s=null,a=Number.POSITIVE_INFINITY;const c=[...r.map(t=\u003ethis.inputProblem.meshNodes[t]),...e];for(const e of c){if(e._containsObstacle)continue;if(!e.availableZ.some(t=\u003eo.includes(t)))continue;const i=Ve(e);if((n?Math.min(Math.max(t.start.y,t.end.y),i.maxY)-Math.max(Math.min(t.start.y,t.end.y),i.minY):Math.min(Math.max(t.start.x,t.end.x),i.maxX)-Math.max(Math.min(t.start.x,t.end.x),i.minX))\u003c=CU)continue;const r=n?t.expansionDirection.x\u003c0?t.start.x-i.maxX:i.minX-t.start.x:t.expansionDirection.y\u003c0?t.start.y-i.maxY:i.minY-t.start.y;r\u003cCU||(r\u003e=a||(a=r,s=e))}return s}createExpandedNode(t,e,n){const o=Ve(e),i=this.getObstacleAvailableZ(t.obstacle);if(Math.abs(t.start.x-t.end.x)\u003c=CU){const r=Math.max(Math.min(t.start.y,t.end.y),o.minY),s=Math.min(Math.max(t.start.y,t.end.y),o.maxY),a=t.expansionDirection.x\u003c0?o.maxX:t.start.x,c=t.expansionDirection.x\u003c0?t.start.x:o.minX;return c-a\u003c=CU||s-r\u003c=CU?null:{capacityMeshNodeId:`bga-gapfill-${n}-${t.obstacle.obstacleId??\"no-obstacle\"}-${e.capacityMeshNodeId}`,center:{x:(a+c)/2,y:(r+s)/2},width:c-a,height:s-r,layer:`z${i.join(\",\")}`,availableZ:i}}const r=Math.max(Math.min(t.start.x,t.end.x),o.minX),s=Math.min(Math.max(t.start.x,t.end.x),o.maxX),a=t.expansionDirection.y\u003c0?o.maxY:t.start.y,c=t.expansionDirection.y\u003c0?t.start.y:o.minY;return s-r\u003c=CU||c-a\u003c=CU?null:{capacityMeshNodeId:`bga-gapfill-${n}-${t.obstacle.obstacleId??\"no-obstacle\"}-${e.capacityMeshNodeId}`,center:{x:(r+s)/2,y:(a+c)/2},width:s-r,height:c-a,layer:`z${i.join(\",\")}`,availableZ:i}}overlapsExistingGeometry(t,e){for(const e of this.inputProblem.meshNodes)if(this.getSharedOverlapArea(t,e)\u003e0)return!0;for(const n of e)if(this.getSharedOverlapArea(t,n)\u003e0)return!0;for(const e of this.inputProblem.edgesWithObstacle)if(this.getNodeObstacleOverlapArea(t,e.obstacle)\u003e0)return!0;return!1}_step(){const t=[];for(const[e,n]of this.inputProblem.edgesWithObstacle.entries()){const o=this.getClosestMeshNode(n,t);if(!o)continue;const i=this.createExpandedNode(n,o,e);i\u0026\u0026(this.overlapsExistingGeometry(i,t)||t.push(i))}this.expandedNodes=t,this.solved=!0}getOutput(){return this.expandedNodes}visualize(){const t=this.inputProblem.edgesWithObstacle,e=_U(t);return{rects:[...this.inputProblem.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.16)\":\"rgba(0,120,255,0.08)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.35)\":\"rgba(0,120,255,0.28)\"})),...this.expandedNodes.map(n=\u003e{const o=fU(n),i=null===o?null:t[o]??null;return{...Dc(n,{rectMargin:.012,zOffset:.01}),fill:i?pU(i,.24):\"rgba(0,160,100,0.24)\",stroke:i?pU(i,.72):\"rgba(0,160,100,0.68)\",label:[i?bU(i,e):\"E?\",\"expanded\",n.capacityMeshNodeId,`z:${n.availableZ.join(\",\")}`].join(\"\\n\")}})],lines:[...this.inputProblem.edgesWithObstacle.map(t=\u003e({points:[t.start,t.end],strokeColor:pU(t,.9),strokeWidth:.034,label:[bU(t,e),mU(t)].join(\" \")})),...this.inputProblem.edgesWithObstacle.map(t=\u003e{const e=gU(t);return{points:[e,{x:e.x+.16*t.expansionDirection.x,y:e.y+.16*t.expansionDirection.y}],strokeColor:pU(t,.7),strokeWidth:.016,strokeDash:\"3 3\"}})],points:this.inputProblem.edgesWithObstacle.map(t=\u003e({...gU(t),color:pU(t,.95),label:bU(t,e)}))}}},wU=.001,TU=class extends Dt{constructor(t){super(t),this.inputProblem=t}inputProblem;detectEdgesNotConnectedToMesh;expandUnconnectedEdgesToMesh;pipelineDef=[Lt(\"detectEdgesNotConnectedToMesh\",IU,t=\u003e[t.inputProblem]),Lt(\"expandUnconnectedEdgesToMesh\",NU,t=\u003e[{meshNodes:t.inputProblem.meshNodes,edgesWithObstacle:t.detectEdgesNotConnectedToMesh.getOutput(),layerCount:t.inputProblem.layerCount}])];getOutput(){return[...this.inputProblem.meshNodes,...this.expandUnconnectedEdgesToMesh.getOutput()]}getExpandedNodes(){return this.expandUnconnectedEdgesToMesh.getOutput()}getObstacleLayer(t){return`z${(t.obstacle.__zLayers??t.obstacle.layers.map(t=\u003eko(t,this.inputProblem.layerCount))).join(\",\")}`}getObstacleRects(){return this.inputProblem.unmarkedComponentObstacles.map(t=\u003e{const e=t.__zLayers??t.layers.map(t=\u003eko(t,this.inputProblem.layerCount));return{center:t.center,width:t.width,height:t.height,fill:\"rgba(150,150,150,0.08)\",stroke:\"rgba(90,90,90,0.42)\",label:t.obstacleId??t.componentId??\"bga obstacle\",layer:`z${e.join(\",\")}`}})}getBaseMeshRects(){return this.inputProblem.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.025,zOffset:.01}),fill:t._containsObstacle?\"rgba(210,60,60,0.14)\":\"rgba(80,120,160,0.08)\",stroke:t._containsObstacle?\"rgba(190,40,40,0.42)\":\"rgba(80,120,160,0.28)\",label:`mesh ${t.capacityMeshNodeId}\\nz:${t.availableZ.join(\",\")}`}))}initialVisualize(){const t=xU(this.inputProblem.unmarkedComponentObstacles),e=_U(t),n=[...t.map(t=\u003e({points:[t.start,t.end],strokeColor:pU(t,.72),strokeWidth:.018,strokeDash:\"0.05 0.035\",layer:this.getObstacleLayer(t),label:[bU(t,e),mU(t)].join(\" \")})),...t.map(t=\u003e{const e=gU(t);return{points:[e,{x:e.x+.18*t.expansionDirection.x,y:e.y+.18*t.expansionDirection.y}],strokeColor:pU(t,.64),strokeWidth:.012,strokeDash:\"0.035 0.025\",layer:this.getObstacleLayer(t)}})];return{title:\"BGA GapFill: candidate obstacle edges\",rects:[...this.getBaseMeshRects(),...this.getObstacleRects()],lines:n}}finalVisualize(){const t=this.getStageOutput(\"detectEdgesNotConnectedToMesh\")??[],e=this.getStageOutput(\"expandUnconnectedEdgesToMesh\")??[],n=_U(xU(this.inputProblem.unmarkedComponentObstacles)),o=new Map;for(const t of e){const e=fU(t);null!==e\u0026\u0026o.set(e,t)}const i=e.map(e=\u003e{const o=fU(e),i=null===o?null:t[o]??null,r=i?(({expandedNode:t,edge:e,meshNodes:n})=\u003e{const o=Ve(t),i=Math.abs(e.start.x-e.end.x)\u003c=wU;return n.filter(n=\u003e{if(n._containsObstacle)return!1;if(!t.availableZ.some(t=\u003en.availableZ.includes(t)))return!1;const r=Ve(n);return i?!(Math.min(o.maxY,r.maxY)-Math.max(o.minY,r.minY)\u003c=wU)\u0026\u0026(e.expansionDirection.x\u003c0?Math.abs(r.maxX-o.minX)\u003c=wU:Math.abs(r.minX-o.maxX)\u003c=wU):!(Math.min(o.maxX,r.maxX)-Math.max(o.minX,r.minX)\u003c=wU)\u0026\u0026(e.expansionDirection.y\u003c0?Math.abs(r.maxY-o.minY)\u003c=wU:Math.abs(r.minY-o.maxY)\u003c=wU)}).map(t=\u003et.capacityMeshNodeId)})({expandedNode:e,edge:i,meshNodes:this.inputProblem.meshNodes}):[],s=i?bU(i,n):\"E?\",a=null===i?\"rgba(0,160,100,0.72)\":pU(i,.72);return{...Dc(e,{rectMargin:.012,zOffset:.01}),fill:null===i?\"rgba(0,160,100,0.24)\":pU(i,.16),stroke:a,label:[`${s} gap fill`,r.length\u003e0?`to ${r.join(\",\")}`:\"target mesh not adjacent\",`z:${e.availableZ.join(\",\")}`].join(\"\\n\")}}),r=t.map((t,e)=\u003e{const i=o.get(e);return{points:[t.start,t.end],strokeColor:i?pU(t,.68):\"rgba(80,80,80,0.14)\",strokeWidth:i?.026:.008,...i?{}:{strokeDash:\"5 4\"},layer:this.getObstacleLayer(t),label:[[bU(t,n),mU(t)].join(\" \"),i?\"filled\":\"no fill created\"].join(\"\\n\")}}),s=t.flatMap((t,e)=\u003e{const n=gU(t),i=o.get(e);return i?[{points:[n,i.center],strokeColor:pU(t,.42),strokeWidth:.012,strokeDash:\"0.035 0.025\",layer:this.getObstacleLayer(t)}]:[]}),a=t.flatMap((t,e)=\u003eo.has(e)?[{...gU(t),color:pU(t,.82),label:bU(t,n),layer:this.getObstacleLayer(t)}]:[]);return{title:\"BGA GapFill: disconnected edges and created mesh\",rects:[...this.getBaseMeshRects(),...this.getObstacleRects(),...i],lines:[...r,...s],points:a}}};function RU(t,e){const n=[];for(let o=0;o\u003ct.length;o++){const i=t[o];n.push(i);const r=t[o+1];if(void 0===r)continue;const s=Math.round((r-i)/e);if(!(s\u003c=1))for(let t=1;t\u003cs;t++){const e=t/s;n.push(Number((i+(r-i)*e).toFixed(6)))}}return n}var EU=.001;function AU(t){const e=[];for(let n=1;n\u003ct.length;n++){const o=t[n]-t[n-1];o\u003eEU\u0026\u0026e.push(o)}if(0===e.length)return null;const n=Math.min(...e),o=e.filter(t=\u003et\u003c=1.5*n).sort((t,e)=\u003et-e),i=Math.floor(o.length/2);return o.length%2==0?(o[i-1]+o[i])/2:o[i]}function OU(t){return[...new Set(t)].sort((t,e)=\u003et-e)}function kU(t){return Number(t.toFixed(6))}var LU=class t{static fromObstacles(e){if(0===e.length)return null;const n=OU(e.map(t=\u003et.center.x)),o=OU(e.map(t=\u003et.center.y)),i=AU(n),r=AU(o);return null===i||null===r?null:new t({obstacles:e,xCoordinates:RU(n,i),yCoordinates:RU(o,r),pitchX:i,pitchY:r})}xCoordinates;yCoordinates;pitchX;pitchY;originX;originY;rowCount;colCount;padWidth;padHeight;slots=new Map;constructor(t){this.xCoordinates=t.xCoordinates,this.yCoordinates=t.yCoordinates,this.pitchX=t.pitchX,this.pitchY=t.pitchY,this.originX=this.xCoordinates[0],this.originY=this.yCoordinates[0],this.colCount=this.xCoordinates.length,this.rowCount=this.yCoordinates.length,this.padWidth=t.obstacles[0].width,this.padHeight=t.obstacles[0].height;for(const e of t.obstacles){const t=this.getSlotForObstacle(e);t\u0026\u0026this.slots.set(this.getSlotKey(t.row,t.col),{...t,obstacle:e})}}getSlotKey(t,e){return`${t}:${e}`}getAxisIndex(t,e){let n=-1,o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ct.length;i++){const r=Math.abs(t[i]-e);r\u003co\u0026\u0026(o=r,n=i)}return o\u003c=EU?n:null}getAxisCoordinate(t,e){return t[e]}hasPadAt(t,e){return this.slots.has(this.getSlotKey(t,e))}getSlotForObstacle(t){const e=this.getAxisIndex(this.yCoordinates,t.center.y),n=this.getAxisIndex(this.xCoordinates,t.center.x);return null===e||null===n||e\u003c0||e\u003e=this.rowCount||n\u003c0||n\u003e=this.colCount?null:{row:e,col:n}}getSlotCenter(t,e){return{x:this.getAxisCoordinate(this.xCoordinates,e),y:this.getAxisCoordinate(this.yCoordinates,t)}}getHorizontalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t,e+1),i=Math.abs(o.x-n.x);return{orientation:\"horizontal\",row:t,col:e,center:{x:kU((n.x+o.x)/2),y:n.y},width:i-this.padWidth,height:this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)\u0026\u0026this.hasPadAt(t,e+1)}}getVerticalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t+1,e),i=Math.abs(o.y-n.y);return{orientation:\"vertical\",row:t,col:e,center:{x:n.x,y:kU((n.y+o.y)/2)},width:this.padWidth,height:i-this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)\u0026\u0026this.hasPadAt(t+1,e)}}getDiagonalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t+1,e+1),i=Math.abs(o.x-n.x),r=Math.abs(o.y-n.y);return{orientation:\"diagonal\",row:t,col:e,center:{x:kU((n.x+o.x)/2),y:kU((n.y+o.y)/2)},width:i-this.padWidth,height:r-this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)\u0026\u0026this.hasPadAt(t+1,e+1)}}getDiagonalGaps(){const t=[];for(let e=0;e\u003cthis.rowCount-1;e++)for(let n=0;n\u003cthis.colCount-1;n++)t.push(this.getDiagonalGap(e,n));return t.filter(t=\u003et.width\u003eEU\u0026\u0026t.height\u003eEU)}getAxisGaps(){const t=[];for(let e=0;e\u003cthis.rowCount;e++)for(let n=0;n\u003cthis.colCount-1;n++)t.push(this.getHorizontalGap(e,n));for(let e=0;e\u003cthis.rowCount-1;e++)for(let n=0;n\u003cthis.colCount;n++)t.push(this.getVerticalGap(e,n));return t.filter(t=\u003et.width\u003eEU\u0026\u0026t.height\u003eEU)}getMissingSlots(){const t=[];for(let e=0;e\u003cthis.rowCount;e++)for(let n=0;n\u003cthis.colCount;n++)this.hasPadAt(e,n)||t.push({row:e,col:n,center:this.getSlotCenter(e,n),width:this.padWidth,height:this.padHeight});return t}};function DU(t){if([t.point.pointId,t.point.pcb_port_id].filter(t=\u003e\"string\"==typeof t).some(e=\u003et.obstacle.connectedTo.includes(e)))return!0;if(0===t.obstacle.connectedTo.length)return!1;if(Be(t.point,t.obstacle)\u003e.001)return!1;const e=xo(t.point).map(e=\u003eko(e,t.layerCount)),n=t.obstacle.layers.map(e=\u003eko(e,t.layerCount));return e.some(t=\u003en.includes(t))}function zU(t){return t.obstacleId??[t.componentId??\"no-component\",t.center.x,t.center.y,t.width,t.height,t.layers.join(\",\")].join(\":\")}function FU({componentId:t,orientationKey:e,row:n,col:o,center:i,width:r,height:s}){return[\"cmn\",e,t,n,o,i.x,i.y,r,s].join(\"_\")}function BU(t){const{componentId:e,bgaGap:n,freeLayers:o,multiLayerThreshold:i}=t,r=n.width\u003ei\u0026\u0026n.height\u003ei;let s=\"d\";\"horizontal\"===n.orientation\u0026\u0026(s=\"h\"),\"vertical\"===n.orientation\u0026\u0026(s=\"v\");const a=FU({componentId:e,orientationKey:s,row:n.row,col:n.col,center:n.center,width:n.width,height:n.height});return\"diagonal\"===n.orientation\u0026\u0026r||!n.isBetweenTwoPads\u0026\u0026r?[{center:n.center,width:n.width,height:n.height,availableZ:[...o],capacityMeshNodeId:`${a}_all`,layer:\"\"}]:o.map(t=\u003e({center:n.center,width:n.width,height:n.height,availableZ:[t],capacityMeshNodeId:`${a}_${t}`,layer:\"\"}))}function jU(t){const{componentId:e,obstacle:n,freeLayers:o,layerCount:i}=t,r=n.layers.map(t=\u003eko(t,i)),s=o.filter(t=\u003e!r.includes(t)),a=zU(n);return s.map(t=\u003e({capacityMeshNodeId:`free-${e}-${a}-${t}`,center:n.center,width:n.width,height:n.height,layer:`z${t}`,availableZ:[t]}))}function $U(t,e,n){const o=e.layers.map(t=\u003eko(t,n.layerCount)),i=zU(e),r=function(t){for(const e of t.srj.connections)for(const n of e.pointsToConnect)if(DU({point:n,obstacle:t.obstacle,layerCount:t.srj.layerCount}))return e.__rootConnectionNames?.[0]??e.name}({obstacle:e,srj:n});return{capacityMeshNodeId:`obstacle-${t}-${i}-${o.join(\",\")}-${e.center.x}-${e.center.y}`,_containsObstacle:!0,...r?{_containsTarget:!0,_targetConnectionName:r}:{},center:e.center,width:e.width,height:e.height,layer:`z${o.join(\",\")}`,availableZ:o}}var YU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;componentObstacles=[];meshNodes=[];getConstructorParams(){return[this.inputProblem]}_step(){const{srj:t,componentBounds:e,componentId:n,markedComponentObstacles:o,unmarkedComponentObstacles:i}=this.inputProblem,r=t.obstacles.filter(t=\u003e!0===t.isCopperPour).filter(t=\u003eXe(Ve(t),e)).flatMap(e=\u003ee.layers.map(e=\u003eko(e,t.layerCount))),s=Array.from({length:t.layerCount},(t,e)=\u003ee).filter(t=\u003e!r.includes(t));if(this.componentObstacles=o,0===o.length||0===s.length)return void(this.solved=!0);const a=LU.fromObstacles(o);if(!a)return void(this.solved=!0);const c=a.getAxisGaps(),l=a.getDiagonalGaps(),d=a.getMissingSlots(),h=1.2*(this.inputProblem.viaDiameter??Yo(t).padDiameter);this.meshNodes=[...c.flatMap(t=\u003eBU({componentId:n,bgaGap:t,freeLayers:s,multiLayerThreshold:h})),...l.flatMap(t=\u003eBU({componentId:n,bgaGap:t,freeLayers:s,multiLayerThreshold:h})),...d.flatMap(t=\u003efunction(t){const{componentId:e,missingBgaSlot:n,freeLayers:o,multiLayerThreshold:i}=t,r=FU({componentId:e,orientationKey:\"missing\",row:n.row,col:n.col,center:n.center,width:n.width,height:n.height});return n.width\u003ei\u0026\u0026n.height\u003ei?[{center:n.center,width:n.width,height:n.height,availableZ:[...o],capacityMeshNodeId:`${r}_all`,layer:\"\"}]:o.map(t=\u003e({center:n.center,width:n.width,height:n.height,availableZ:[t],capacityMeshNodeId:`${r}_${t}`,layer:\"\"}))}({componentId:n,missingBgaSlot:t,freeLayers:s,multiLayerThreshold:h})),...o.flatMap(e=\u003e[...jU({componentId:n,obstacle:e,freeLayers:s,layerCount:t.layerCount}),$U(n,e,t)]),...i.flatMap(e=\u003e[$U(n,e,t)])],this.meshNodes=function(t){const e=new Map;return t.map(t=\u003e{const n=e.get(t.capacityMeshNodeId)??0;return e.set(t.capacityMeshNodeId,n+1),0===n?t:{...t,capacityMeshNodeId:`${t.capacityMeshNodeId}__dup${n}`}})}(this.meshNodes),this.solved=!0}getOutput(){return this.meshNodes}visualize(){return{rects:[{center:{x:(this.inputProblem.componentBounds.minX+this.inputProblem.componentBounds.maxX)/2,y:(this.inputProblem.componentBounds.minY+this.inputProblem.componentBounds.maxY)/2},width:this.inputProblem.componentBounds.maxX-this.inputProblem.componentBounds.minX,height:this.inputProblem.componentBounds.maxY-this.inputProblem.componentBounds.minY,fill:\"rgba(0,0,0,0)\",stroke:\"rgba(30,30,30,0.65)\",label:`component ${this.inputProblem.componentId}`},...this.inputProblem.markedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,0,0,0.18)\",stroke:\"rgba(255,0,0,0.52)\",label:`pad ${t.obstacleId??\"obstacle\"}`})),...this.inputProblem.unmarkedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.14)\",stroke:\"rgba(255,140,0,0.42)\",label:`foreign ${t.obstacleId??\"obstacle\"}`})),...this.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.14)\":t.capacityMeshNodeId.includes(\"missing\")?\"rgba(0,200,120,0.18)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.36)\":t.capacityMeshNodeId.includes(\"missing\")?\"rgba(0,200,120,0.52)\":\"rgba(0,120,255,0.38)\"}))]}}};function XU(t){return t.capacityMeshNodeId.startsWith(\"bga-gapfill-\")}function VU(t){return JSON.stringify({availableZ:[...t.availableZ].sort((t,e)=\u003et-e),_containsTarget:t._containsTarget??!1,_targetConnectionName:t._targetConnectionName??null,_depth:t._depth??null,_strawNode:t._strawNode??!1,_strawParentCapacityMeshNodeId:t._strawParentCapacityMeshNodeId??null,_qfpRegionType:t._qfpRegionType??null,_isNarrowQfpPadGap:t._isNarrowQfpPadGap??!1,_soicRegionType:t._soicRegionType??null,_offBoardConnectionId:t._offBoardConnectionId??null,_offboardNetName:t._offboardNetName??null,_isVirtualOffboard:t._isVirtualOffboard??!1,_containsObstacle:t._containsObstacle??!1})}function WU(t,e){const n=Ve(t);for(const o of e){if(!t.availableZ.some(t=\u003eo.availableZ.includes(t)))continue;const e=Ve(o);if(Xe(n,e))return!0}return!1}function HU(t){const e=t[0];if(!e)throw new Error(\"createMergedNode requires at least one source node\");let n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const e of t){const t=Ve(e);n=Math.min(n,t.minX),o=Math.max(o,t.maxX),i=Math.min(i,t.minY),r=Math.max(r,t.maxY)}return{...e,capacityMeshNodeId:`merge:${t.map(t=\u003et.capacityMeshNodeId).join(\":\")}`,center:{x:(n+o)/2,y:(i+r)/2},width:o-n,height:r-i}}function GU(t,e,n){return{center:t.center,width:t.width,height:t.height,fill:e,stroke:e,label:n}}var UU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;obstacleNodes=[];passthroughNodes=[];mergedNodes=[];pendingGroups=[];totalGroupCount=0;processedGroupCount=0;debugFilteredNodes=[];debugMergeEvents=[];currentGroupKey=null;currentRootNodeId=null;lastMergedNodeId=null;_setup(){this.obstacleNodes=this.inputProblem.meshNodes.filter(t=\u003e!0===t._containsObstacle),this.passthroughNodes=[],this.mergedNodes=[],this.pendingGroups=[],this.totalGroupCount=0,this.processedGroupCount=0,this.debugFilteredNodes=[],this.debugMergeEvents=[],this.currentGroupKey=null,this.currentRootNodeId=null,this.lastMergedNodeId=null;const t=new Map;for(const e of this.inputProblem.meshNodes){if(!0===e._containsObstacle){this.passthroughNodes.push(e),this.debugFilteredNodes.push({type:\"preserved-obstacle\",node:e,reason:\"contains-obstacle\"});continue}if(XU(e)){this.passthroughNodes.push(e);continue}if(e.availableZ.length!==this.inputProblem.layerCount){this.passthroughNodes.push(e);continue}let n=!1;for(let t=0;t\u003cthis.inputProblem.layerCount;t+=1)if(!e.availableZ.includes(t)){n=!0;break}if(n){this.passthroughNodes.push(e);continue}if(WU(e,this.obstacleNodes)){this.passthroughNodes.push(e),this.debugFilteredNodes.push({type:\"preserved-overlap\",node:e,reason:\"overlaps-obstacle\"});continue}const o=VU(e),i=t.get(o);i?i.push(e):t.set(o,[e])}for(const[e,n]of t.entries())n.length\u003c=1?this.passthroughNodes.push(...n):this.pendingGroups.push({groupKey:e,nodes:n});this.pendingGroups.sort((t,e)=\u003ee.nodes.length-t.nodes.length),this.totalGroupCount=this.pendingGroups.length,this.updateStats(\"setup\")}_step(){const t=this.pendingGroups.shift();if(!t)return this.currentGroupKey=null,this.currentRootNodeId=null,this.solved=!0,void this.updateStats(\"done\");const e=t.nodes[0];this.currentGroupKey=t.groupKey,this.currentRootNodeId=e?e.capacityMeshNodeId:null;const n=function(t){if(!t.nodes[0])return{outputNodes:[],mergeEvents:[]};let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.POSITIVE_INFINITY;for(const r of t.nodes){e=Math.min(e,r.width),n=Math.min(n,r.height);const t=Ve(r);o=Math.min(o,t.minX),i=Math.min(i,t.minY)}const r=new Map,s=[];for(const a of t.nodes){const t=Ve(a),c=Math.round((t.minX-o)/e),l=Math.round((t.minY-i)/n),d=Math.max(1,Math.round(a.width/e)),h=Math.max(1,Math.round(a.height/n));for(let t=0;t\u003ch;t+=1)for(let e=0;e\u003cd;e+=1)r.set(`${c+e},${l+t}`,a);s.push({col:c,row:l})}s.sort((t,e)=\u003et.row-e.row||t.col-e.col);const a=new Set,c=[],l=[];for(const o of s){const i=`${o.col},${o.row}`;if(a.has(i))continue;let s=0;for(;;){const t=`${o.col+s},${o.row}`;if(!r.has(t))break;if(a.has(t))break;s+=1}let d=s,h=1,u=1,p=1;for(let t=1;;t+=1){const i=o.row+t-1;let s=0;for(;s\u003cd;){const t=`${o.col+s},${i}`;if(!r.has(t))break;if(a.has(t))break;s+=1}if(0===s)break;d=Math.min(d,s);for(let o=d;o\u003e=1;o-=1){const i=o*e,r=t*n,s=Math.min(i,r);if((s\u003c=1e-6?Number.POSITIVE_INFINITY:Math.max(i,r)/s)\u003e4)continue;const a=o*t;a\u003ep\u0026\u0026(p=a,h=o,u=t);break}}const m=new Map;for(let t=0;t\u003cu;t+=1)for(let e=0;e\u003ch;e+=1){const n=`${o.col+e},${o.row+t}`,i=r.get(n);i\u0026\u0026(a.add(n),m.set(i.capacityMeshNodeId,i))}const g=[...m.values()];if(g.length\u003c=1){const t=g[0];t\u0026\u0026c.push(t);continue}const f=HU(g);c.push(f),l.push({type:\"merge\",groupKey:t.groupKey,sourceNodes:g,mergedNode:f})}return{outputNodes:c,mergeEvents:l}}(t);this.mergedNodes.push(...n.outputNodes),this.processedGroupCount+=1,this.debugMergeEvents.push(...n.mergeEvents);const o=n.mergeEvents[n.mergeEvents.length-1];o\u0026\u0026(this.lastMergedNodeId=o.mergedNode.capacityMeshNodeId),this.updateStats(n.mergeEvents.length\u003e0?\"merged-group\":\"passthrough-group\")}computeProgress(){return 0===this.totalGroupCount?1:this.processedGroupCount/this.totalGroupCount}updateStats(t){const e=new Set(this.debugMergeEvents.map(t=\u003et.groupKey)),n={lastAction:t,totalGroupCount:this.totalGroupCount,processedGroupCount:this.processedGroupCount,pendingGroupCount:this.pendingGroups.length,mergedNodeCount:this.mergedNodes.length,passthroughNodeCount:this.passthroughNodes.length,gapFillNodeCount:this.passthroughNodes.filter(XU).length,preservedObstacleNodeCount:this.debugFilteredNodes.filter(t=\u003e\"preserved-obstacle\"===t.type).length,preservedOverlapNodeCount:this.debugFilteredNodes.filter(t=\u003e\"preserved-overlap\"===t.type).length,mergeCount:this.debugMergeEvents.length,mergedGroupCount:e.size,currentGroupKey:this.currentGroupKey,currentRootNodeId:this.currentRootNodeId,lastMergedNodeId:this.lastMergedNodeId};this.stats=n}getConstructorParams(){return[this.inputProblem]}getOutput(){return[...this.mergedNodes,...this.passthroughNodes]}visualize(){const t=this.getOutput(),e=this.currentRootNodeId?t.find(t=\u003et.capacityMeshNodeId===this.currentRootNodeId)??null:null,n=this.lastMergedNodeId?t.find(t=\u003et.capacityMeshNodeId===this.lastMergedNodeId)??null:null;return{rects:[...this.debugFilteredNodes.map(t=\u003eGU(t.node,\"preserved-obstacle\"===t.type?\"rgba(255,64,64,0.35)\":\"rgba(255,160,64,0.35)\",t.reason)),...this.passthroughNodes.map(t=\u003eGU(t,t._containsObstacle?\"rgba(255,0,0,0.35)\":XU(t)?\"rgba(0,120,255,0.18)\":\"rgba(160,160,160,0.12)\")),...this.mergedNodes.map(t=\u003eGU(t,\"rgba(120,120,120,0.14)\")),...e?[GU(e,\"rgba(255,215,0,0.35)\",\"active-group\")]:[],...n?[GU(n,\"rgba(0,200,120,0.28)\",\"merged\")]:[]]}}},ZU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;obstacleQueue=[];obstacleQueueIndex=0;meshNodes=[];_setup(){this.obstacleQueue=this.inputProblem.obstacles,this.obstacleQueueIndex=0,this.meshNodes=[...this.inputProblem.meshNodes]}_step(){if(this.obstacleQueueIndex\u003e=this.obstacleQueue.length)return void(this.solved=!0);const t=this.obstacleQueue[this.obstacleQueueIndex],e=t.layers.map(t=\u003eko(t,this.inputProblem.layerCount)),n=[];for(const o of this.meshNodes){if(o._containsObstacle){n.push(o);continue}if(!e.some(t=\u003eo.availableZ.includes(t))){n.push(o);continue}if(!Xe(Ve(o),Ve(t))){n.push(o);continue}if(1===o.availableZ.length)continue;const i=o.availableZ.filter(t=\u003e!e.includes(t));for(const t of i){const e={...o,capacityMeshNodeId:`${o.capacityMeshNodeId}:z${t}`,availableZ:[t],layer:`z${t}`};n.push(e)}}this.meshNodes=n,this.obstacleQueueIndex+=1,this.stats={obstaclesProcessed:this.obstacleQueueIndex,obstacleCount:this.obstacleQueue.length,meshNodeCount:this.meshNodes.length}}computeProgress(){return 0===this.obstacleQueue.length?1:this.obstacleQueueIndex/this.obstacleQueue.length}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.meshNodes}visualize(){const t=this.obstacleQueueIndex\u003cthis.obstacleQueue.length?this.obstacleQueue[this.obstacleQueueIndex]??null:null,e=this.obstacleQueue.slice(0,this.obstacleQueueIndex),n=t?this.obstacleQueue.slice(this.obstacleQueueIndex+1):[];return{rects:[...e.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(160,160,160,0.10)\",stroke:\"rgba(160,160,160,0.35)\",label:`processed ${t.obstacleId??\"obstacle\"}`})),...t?[{center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.22)\",stroke:\"rgba(255,140,0,0.75)\",label:`active ${t.obstacleId??\"obstacle\"}`}]:[],...n.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,0,0,0.05)\",stroke:\"rgba(255,0,0,0.22)\",label:`pending ${t.obstacleId??\"obstacle\"}`})),...this.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.18)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.45)\":\"rgba(0,120,255,0.45)\"}))]}}};dU.register(class extends Dt{constructor(t){super(t),this.inputProblem=t}inputProblem;static componentKind=\"bga\";initialTopologySolver;removeMeshNodeOverlappingWithUnmarkedObstacle;gapfillDueToNodeRemoval;mergeMeshNodes;markedComponentObstacles=[];unmarkedComponentObstacles=[];pipelineDef=[Lt(\"initialTopologySolver\",YU,t=\u003e[{srj:t.inputProblem.inputSrj,componentBounds:t.inputProblem.detectedComponent.bounds,componentId:t.inputProblem.detectedComponent.componentId,markedComponentObstacles:t.markedComponentObstacles,unmarkedComponentObstacles:t.unmarkedComponentObstacles,viaDiameter:t.inputProblem.viaDiameter}]),Lt(\"removeMeshNodeOverlappingWithUnmarkedObstacle\",ZU,t=\u003e[{meshNodes:t.initialTopologySolver.getOutput(),obstacles:t.unmarkedComponentObstacles,layerCount:t.inputProblem.inputSrj.layerCount}]),Lt(\"gapfillDueToNodeRemoval\",TU,t=\u003e[{meshNodes:t.removeMeshNodeOverlappingWithUnmarkedObstacle.getOutput(),unmarkedComponentObstacles:t.unmarkedComponentObstacles,layerCount:t.inputProblem.inputSrj.layerCount}]),Lt(\"mergeMeshNodes\",UU,t=\u003e[{meshNodes:t.gapfillDueToNodeRemoval.getOutput(),layerCount:t.inputProblem.inputSrj.layerCount}])];_setup(){const t=this.inputProblem.detectedComponent.bounds,e=this.inputProblem.detectedComponent.componentId,n=[],o=[];for(const i of this.inputProblem.inputSrj.obstacles){const r=Ve(i);Xe(t,r)\u0026\u0026(i.componentId!==e?o.push(i):n.push(i))}this.markedComponentObstacles=n,this.unmarkedComponentObstacles=o}getConstructorParams(){return[this.inputProblem]}getOutput(){return{routingRegions:this.mergeMeshNodes?.getOutput()??this.gapfillDueToNodeRemoval?.getOutput()??this.removeMeshNodeOverlappingWithUnmarkedObstacle?.getOutput()??[]}}initialVisualize(){return{rects:[{center:{x:(this.inputProblem.detectedComponent.bounds.minX+this.inputProblem.detectedComponent.bounds.maxX)/2,y:(this.inputProblem.detectedComponent.bounds.minY+this.inputProblem.detectedComponent.bounds.maxY)/2},width:this.inputProblem.detectedComponent.bounds.maxX-this.inputProblem.detectedComponent.bounds.minX,height:this.inputProblem.detectedComponent.bounds.maxY-this.inputProblem.detectedComponent.bounds.minY,fill:\"rgba(0,0,0,0)\",stroke:\"rgba(30,30,30,0.65)\",label:`bga ${this.inputProblem.detectedComponent.componentId}`},...this.markedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,0,0,0.18)\",stroke:\"rgba(255,0,0,0.52)\",label:`pad ${t.obstacleId??\"obstacle\"}`})),...this.unmarkedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.14)\",stroke:\"rgba(255,140,0,0.42)\",label:`foreign ${t.obstacleId??\"obstacle\"}`}))]}}finalVisualize(){return{rects:this.getOutput().routingRegions.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.16)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.36)\":\"rgba(0,120,255,0.42)\"}))}}});var qU=1e-6;function JU(t,e){return t.__zLayers\u0026\u0026t.__zLayers.length\u003e0?Lo(t.__zLayers,e):Do(t.layers,e)}function KU(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(let t=1;t\u003ce.length;t++){const o=e[t]-e[t-1];o\u003eqU\u0026\u0026n.push(o)}const o=n.length\u003e0?Math.max(qU,Math.min(...n)/4):.001,i=[];for(const t of e){const e=i[i.length-1];(void 0===e||Math.abs(t-e)\u003eo)\u0026\u0026i.push(t)}return i}function QU(t){return Array.from({length:Math.max(0,t)},(t,e)=\u003ee)}var tZ=1e-6;function eZ(t){return t.maxX-t.minX\u003etZ\u0026\u0026t.maxY-t.minY\u003etZ}function nZ(t){return function(t){const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return e\u003c=0?0:n/e}(t)\u003e=1.5}function oZ(t,e){const n=[{side:\"top\",distance:Math.abs(t.center.y-e.minY)},{side:\"right\",distance:Math.abs(e.maxX-t.center.x)},{side:\"bottom\",distance:Math.abs(e.maxY-t.center.y)},{side:\"left\",distance:Math.abs(t.center.x-e.minX)}];return n.sort((t,e)=\u003et.distance-e.distance),n[0].side}function iZ(t,e){return t.map((t,n)=\u003e({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e)}))}function rZ(t,e){return t.map((t,n)=\u003e({key:`thermal-pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e)}))}function sZ(t,e){return!!eZ(t)\u0026\u0026Math.min(t.maxX-t.minX,t.maxY-t.minY)\u003c=e}function aZ({side:t,sideObstacles:e,bounds:n,innerBounds:o,narrowThreshold:i}){const r=[];for(let s=0;s\u003ce.length-1;s++){const a=Ee(e[s]),c=Ee(e[s+1]);let l;l=\"top\"===t?{minX:a.maxX,maxX:c.minX,minY:n.minY,maxY:o.minY}:\"right\"===t?{minX:o.maxX,maxX:n.maxX,minY:a.maxY,maxY:c.minY}:\"bottom\"===t?{minX:a.maxX,maxX:c.minX,minY:o.maxY,maxY:n.maxY}:{minX:n.minX,maxX:o.minX,minY:a.maxY,maxY:c.minY},r.push({key:`${t}-gap-${s}`,bounds:l,regionType:\"pad-gap\",isNarrowPadGap:sZ(l,i)})}return r}function cZ({side:t,sideObstacles:e,thermalPadBounds:n,narrowThreshold:o}){const i=[];for(let r=0;r\u003ce.length;r++){const s=Ee(e[r]),a=e[r-1]?Ee(e[r-1]):null,c=e[r+1]?Ee(e[r+1]):null;let l;l=\"top\"===t?{minX:a?(a.maxX+s.minX)/2:s.minX,maxX:c?(s.maxX+c.minX)/2:s.maxX,minY:s.maxY,maxY:n.minY}:\"right\"===t?{minX:n.maxX,maxX:s.minX,minY:a?(a.maxY+s.minY)/2:s.minY,maxY:c?(s.maxY+c.minY)/2:s.maxY}:\"bottom\"===t?{minX:a?(a.maxX+s.minX)/2:s.minX,maxX:c?(s.maxX+c.minX)/2:s.maxX,minY:n.maxY,maxY:s.minY}:{minX:s.maxX,maxX:n.minX,minY:a?(a.maxY+s.minY)/2:s.minY,maxY:c?(s.maxY+c.minY)/2:s.maxY},i.push({key:`inner-${t}-pad-${r}`,bounds:l,regionType:\"pad-gap\",isNarrowPadGap:sZ(l,o)})}return i}function lZ({bounds:t,innerBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:\"corner-nw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-top\",regionType:\"corner\",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:\"corner-ne-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-top\",regionType:\"corner\",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:\"corner-se-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-se-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:\"corner-se-bottom\",regionType:\"corner\",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-bottom\",regionType:\"corner\",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}function dZ({innerBounds:t,thermalPadBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:\"inner-corner-nw-core\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-nw-top\",regionType:\"corner\",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-nw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:\"inner-corner-ne-core\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-ne-top\",regionType:\"corner\",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-ne-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:\"inner-corner-se-core\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-se-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:\"inner-corner-se-bottom\",regionType:\"corner\",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-sw-core\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-sw-bottom\",regionType:\"corner\",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-sw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind=\"qfp_thermalpad\";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=\u003et.componentId===o),s=r.length\u003e0?r:e,{padRingObstacles:a,thermalPadObstacles:c}=function(t){return{padRingObstacles:t.filter(nZ),thermalPadObstacles:t.filter(t=\u003e!nZ(t))}}(s),l=function(t,e){const n={top:[],right:[],bottom:[],left:[]};for(const o of t)n[oZ(o,e)].push(o);return n.top.sort((t,e)=\u003et.center.x-e.center.x),n.bottom.sort((t,e)=\u003et.center.x-e.center.x),n.left.sort((t,e)=\u003et.center.y-e.center.y),n.right.sort((t,e)=\u003et.center.y-e.center.y),n}(a,n),d=function({bounds:t,sideGroups:e}){return{minX:e.left.length\u003e0?Math.max(...e.left.map(t=\u003eEe(t).maxX)):t.minX,maxX:e.right.length\u003e0?Math.min(...e.right.map(t=\u003eEe(t).minX)):t.maxX,minY:e.top.length\u003e0?Math.max(...e.top.map(t=\u003eEe(t).maxY)):t.minY,maxY:e.bottom.length\u003e0?Math.min(...e.bottom.map(t=\u003eEe(t).minY)):t.maxY}}({bounds:n,sideGroups:l}),h=function(t){return 0===t.length?null:t.reduce((t,e)=\u003e{const n=Ee(e);return{minX:Math.min(t.minX,n.minX),maxX:Math.max(t.maxX,n.maxX),minY:Math.min(t.minY,n.minY),maxY:Math.max(t.maxY,n.maxY)}},Ee(t[0]))}(c);if(!h)return this.failed=!0,void(this.error=\"QfpThermalPadTopologyGeneratorSolver requires a thermal pad\");const u=o,p=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,m=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,g=p+2*m,f=this.inputProblem.inputSrj.minTraceWidth+2*m,y=[...iZ(a,t),...rZ(c,t),...aZ({side:\"top\",sideObstacles:l.top,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:\"right\",sideObstacles:l.right,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:\"bottom\",sideObstacles:l.bottom,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:\"left\",sideObstacles:l.left,bounds:n,innerBounds:d,narrowThreshold:f}),...cZ({side:\"top\",sideObstacles:l.top,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:\"right\",sideObstacles:l.right,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:\"bottom\",sideObstacles:l.bottom,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:\"left\",sideObstacles:l.left,thermalPadBounds:h,narrowThreshold:f}),...dZ({innerBounds:d,thermalPadBounds:h,sideGroups:l}),...lZ({bounds:n,innerBounds:d,sideGroups:l})].flatMap(t=\u003efunction({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,isNarrowPadGap:r=!1,obstacleZ:s=[]}){if(!eZ(e))return[];const a=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),c=Math.min(a.width,a.height)\u003eo,l=c?[{availableZ:n.filter(t=\u003e!s.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=\u003es.includes(t)),containsObstacle:!0}].filter(t=\u003et.availableZ.length\u003e0):n.map(t=\u003e({availableZ:[t],containsObstacle:s.includes(t)}));return l.map(e=\u003e({capacityMeshNodeId:1===l.length?t:c?`${t}:${e.containsObstacle?\"obstacle\":\"free\"}`:`${t}:z${e.availableZ[0]}`,center:a.center,width:a.width,height:a.height,layer:`z${e.availableZ.join(\",\")}`,availableZ:e.availableZ,_qfpRegionType:i,_isNarrowQfpPadGap:r,_containsObstacle:e.containsObstacle}))}({nodeId:`qfp_thermalpad:${u}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:g,regionType:t.regionType,isNarrowPadGap:t.isNarrowPadGap,obstacleZ:t.obstacleZ}));this.output={routingRegions:y},this.stats={componentId:o,layerCount:t,viaDiameter:p,obstacleMargin:m,multiLayerThreshold:g,narrowPadGapThreshold:f,thermalPadCount:c.length,perimeterPadCount:a.length,innerCornerRectCount:y.filter(t=\u003et.capacityMeshNodeId.includes(\":inner-corner-\")).length,narrowPadGapNodeCount:y.filter(t=\u003et._isNarrowQfpPadGap).length,topPadCount:l.top.length,rightPadCount:l.right.length,bottomPadCount:l.bottom.length,leftPadCount:l.left.length,multiLayerNodeCount:y.filter(t=\u003et.availableZ.length\u003e1).length,totalMeshNodeCount:y.length},this.solved=!0}getOutput(){if(!this.output)throw new Error(\"QfpThermalPadTopologyGeneratorSolver has not solved yet\");return this.output}});var hZ=1e-6;function uZ(t){return t.maxX-t.minX\u003ehZ\u0026\u0026t.maxY-t.minY\u003ehZ}function pZ(t,e){const n=[{side:\"top\",distance:Math.abs(t.center.y-e.minY)},{side:\"right\",distance:Math.abs(e.maxX-t.center.x)},{side:\"bottom\",distance:Math.abs(e.maxY-t.center.y)},{side:\"left\",distance:Math.abs(t.center.x-e.minX)}];return n.sort((t,e)=\u003et.distance-e.distance),n[0].side}function mZ(t,e){return t.map((t,n)=\u003e({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e),connectedTo:[...t.connectedTo]}))}function gZ(t,e){return!!uZ(t)\u0026\u0026Math.min(t.maxX-t.minX,t.maxY-t.minY)\u003c=e}function fZ({side:t,sideObstacles:e,bounds:n,centralBounds:o,narrowThreshold:i}){const r=[];for(let s=0;s\u003ce.length-1;s++){const a=Ee(e[s]),c=Ee(e[s+1]);let l;l=\"top\"===t?{minX:a.maxX,maxX:c.minX,minY:n.minY,maxY:o.minY}:\"right\"===t?{minX:o.maxX,maxX:n.maxX,minY:a.maxY,maxY:c.minY}:\"bottom\"===t?{minX:a.maxX,maxX:c.minX,minY:o.maxY,maxY:n.maxY}:{minX:n.minX,maxX:o.minX,minY:a.maxY,maxY:c.minY},r.push({key:`${t}-gap-${s}`,bounds:l,regionType:\"pad-gap\",isNarrowPadGap:gZ(l,i)})}return r}function yZ({bounds:t,centralBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:\"corner-nw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-top\",regionType:\"corner\",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:\"corner-ne-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-top\",regionType:\"corner\",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:\"corner-se-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-se-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:\"corner-se-bottom\",regionType:\"corner\",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-bottom\",regionType:\"corner\",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind=\"qfp\";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=\u003et.componentId===o),s=r.length\u003e0?r:e,a=function(t,e){const n={top:[],right:[],bottom:[],left:[]};for(const o of t)n[pZ(o,e)].push(o);return n.top.sort((t,e)=\u003et.center.x-e.center.x),n.bottom.sort((t,e)=\u003et.center.x-e.center.x),n.left.sort((t,e)=\u003et.center.y-e.center.y),n.right.sort((t,e)=\u003et.center.y-e.center.y),n}(s,n),c=function({bounds:t,sideGroups:e}){return{minX:e.left.length\u003e0?Math.max(...e.left.map(t=\u003eEe(t).maxX)):t.minX,maxX:e.right.length\u003e0?Math.min(...e.right.map(t=\u003eEe(t).minX)):t.maxX,minY:e.top.length\u003e0?Math.max(...e.top.map(t=\u003eEe(t).maxY)):t.minY,maxY:e.bottom.length\u003e0?Math.min(...e.bottom.map(t=\u003eEe(t).minY)):t.maxY}}({bounds:n,sideGroups:a}),l=o,d=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,h=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,u=d+2*h,p=this.inputProblem.inputSrj.minTraceWidth+2*h,m=[{key:\"center\",bounds:c,regionType:\"center\"},...mZ(s,t),...fZ({side:\"top\",sideObstacles:a.top,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:\"right\",sideObstacles:a.right,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:\"bottom\",sideObstacles:a.bottom,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:\"left\",sideObstacles:a.left,bounds:n,centralBounds:c,narrowThreshold:p}),...yZ({bounds:n,centralBounds:c,sideGroups:a})].flatMap(t=\u003efunction({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,isNarrowPadGap:r=!1,obstacleZ:s=[],connectedTo:a}){if(!uZ(e))return[];const c=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),l=Math.min(c.width,c.height)\u003eo,d=l?[{availableZ:n.filter(t=\u003e!s.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=\u003es.includes(t)),containsObstacle:!0}].filter(t=\u003et.availableZ.length\u003e0):n.map(t=\u003e({availableZ:[t],containsObstacle:s.includes(t)}));return d.map(e=\u003e({capacityMeshNodeId:1===d.length?t:l?`${t}:${e.containsObstacle?\"obstacle\":\"free\"}`:`${t}:z${e.availableZ[0]}`,center:c.center,width:c.width,height:c.height,layer:`z${e.availableZ.join(\",\")}`,availableZ:e.availableZ,_qfpRegionType:i,_isNarrowQfpPadGap:r,_containsObstacle:e.containsObstacle,_connectedTo:e.containsObstacle?a:void 0}))}({nodeId:`qfp:${l}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:u,regionType:t.regionType,isNarrowPadGap:t.isNarrowPadGap,obstacleZ:t.obstacleZ,connectedTo:t.connectedTo}));this.output={routingRegions:m},this.stats={componentId:o,layerCount:t,viaDiameter:d,obstacleMargin:h,multiLayerThreshold:u,narrowPadGapThreshold:p,narrowPadGapNodeCount:m.filter(t=\u003et._isNarrowQfpPadGap).length,topPadCount:a.top.length,rightPadCount:a.right.length,bottomPadCount:a.bottom.length,leftPadCount:a.left.length,multiLayerNodeCount:m.filter(t=\u003et.availableZ.length\u003e1).length,totalMeshNodeCount:m.length},this.solved=!0}getOutput(){if(!this.output)throw new Error(\"QfpTopologyGeneratorSolver has not solved yet\");return this.output}});var _Z=1e-6;function bZ({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,obstacleZ:r=[],connectedTo:s}){if(!function(t){return t.maxX-t.minX\u003e_Z\u0026\u0026t.maxY-t.minY\u003e_Z}(e))return[];const a=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),c=Math.min(a.width,a.height)\u003eo,l=c?[{availableZ:n.filter(t=\u003e!r.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=\u003er.includes(t)),containsObstacle:!0}].filter(t=\u003et.availableZ.length\u003e0):n.map(t=\u003e({availableZ:[t],containsObstacle:r.includes(t)}));return l.map(e=\u003e({capacityMeshNodeId:1===l.length?t:c?`${t}:${e.containsObstacle?\"obstacle\":\"free\"}`:`${t}:z${e.availableZ[0]}`,center:a.center,width:a.width,height:a.height,layer:`z${e.availableZ.join(\",\")}`,availableZ:e.availableZ,_soicRegionType:i,_containsObstacle:e.containsObstacle,_connectedTo:e.containsObstacle?s:void 0}))}function xZ(t,e){let n=0,o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ce.length;i++){const r=Math.abs(t-e[i]);r\u003co\u0026\u0026(n=i,o=r)}return n}function vZ(t,e){return t.map((t,n)=\u003e({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e),connectedTo:[...t.connectedTo]}))}function SZ(t,e){if(t.componentId!==e.componentId)return!1;const{bounds:n}=e;return t.center.x\u003e=n.minX\u0026\u0026t.center.x\u003c=n.maxX\u0026\u0026t.center.y\u003e=n.minY\u0026\u0026t.center.y\u003c=n.maxY}function IZ({detectedComponent:t,inputSrj:e}){const n=e.obstacles.filter(e=\u003eSZ(e,t)),o=Array.from({length:e.layerCount},(t,e)=\u003ee),i=o.map(t=\u003evo(t,e.layerCount)),r=Array.from(new Set(n.flatMap(t=\u003et.connectedTo))),{bounds:s}=t;return{obstacleId:`${t.componentId}_component_bounds`,componentId:t.componentId,type:\"rect\",layers:i,__zLayers:o,center:{x:(s.minX+s.maxX)/2,y:(s.minY+s.maxY)/2},width:s.maxX-s.minX,height:s.maxY-s.minY,connectedTo:r}}function CZ(t){if(0===t.length)return{minX:0,maxX:0,minY:0,maxY:0};let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t){const t=Ee(r);e=Math.min(e,t.minX),n=Math.max(n,t.maxX),o=Math.min(o,t.minY),i=Math.max(i,t.maxY)}return{minX:e,maxX:n,minY:o,maxY:i}}function PZ(t){const e=t.componentDetectionOutput??[],n=function({detectedComponents:t,inputSrj:e}){return t.map(t=\u003e{const n=e.obstacles.filter(e=\u003eSZ(e,t));return{componentId:t.componentId,componentKind:t.componentKind,memberObstacleIds:n.map((e,n)=\u003ee.obstacleId??`${t.componentId}:member:${n}`),memberObstacles:n,replacementObstacle:IZ({detectedComponent:t,inputSrj:e})}})}({detectedComponents:e,inputSrj:t.inputSrj}),o=t.globalNoConnectionSrj??(e.length\u003e0?function({detectedComponents:t,inputSrj:e}){return{...structuredClone(e),obstacles:[...e.obstacles.filter(e=\u003e!t.some(t=\u003eSZ(e,t))),...t.map(t=\u003eIZ({detectedComponent:t,inputSrj:e}))]}}({detectedComponents:e,inputSrj:t.inputSrj}):t.inputSrj)??t.brokenSrj?.componentsAsObstaclesSrj,i=t.components??n??t.brokenSrj?.components??[];if(!o)throw new Error(\"MultiGraphTopologyPlannerSolver requires globalNoConnectionSrj or detected components\");return{globalNoConnectionSrj:o,components:i}}function MZ({rects:t,components:e}){return t\u0026\u00260!==e.length?t.filter(t=\u003e!function(t){return\"string\"==typeof t.label\u0026\u0026t.label.startsWith(\"node \")}(t)||!e.some(e=\u003efunction({rect:t,obstacle:e}){if(!t.center||void 0===t.width||void 0===t.height)return!1;const n=1e-9,o=Ve({center:t.center,width:t.width,height:t.height}),i=Ve({center:e.center,width:e.width,height:e.height});return NZ({bounds:o,outerBounds:i,epsilon:n})}({rect:t,obstacle:e.replacementObstacle}))):t}function NZ({bounds:t,outerBounds:e,epsilon:n}){return t.minX\u003e=e.minX-n\u0026\u0026t.maxX\u003c=e.maxX+n\u0026\u0026t.minY\u003e=e.minY-n\u0026\u0026t.maxY\u003c=e.maxY+n}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind=\"soic\";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=\u003et.componentId===o),s=r.length\u003e0?r:e,a=function(t){const e=KU(t.map(t=\u003et.center.y)).length;return 2===KU(t.map(t=\u003et.center.x)).length\u0026\u00262!==e?\"vertical-columns\":\"horizontal-rows\"}(s),c=function({obstacles:t,orientation:e}){const n={left:[],right:[],top:[],bottom:[]};if(\"vertical-columns\"===e){const e=KU(t.map(t=\u003et.center.x));for(const o of t)n[0===xZ(o.center.x,e)?\"left\":\"right\"].push(o);return n.left.sort((t,e)=\u003et.center.y-e.center.y),n.right.sort((t,e)=\u003et.center.y-e.center.y),n}const o=KU(t.map(t=\u003et.center.y));for(const e of t)n[0===xZ(e.center.y,o)?\"top\":\"bottom\"].push(e);return n.top.sort((t,e)=\u003et.center.x-e.center.x),n.bottom.sort((t,e)=\u003et.center.x-e.center.x),n}({obstacles:s,orientation:a}),l=function({bounds:t,orientation:e,sideGroups:n}){return\"vertical-columns\"===e?{minX:Math.max(...n.left.map(t=\u003eEe(t).maxX)),maxX:Math.min(...n.right.map(t=\u003eEe(t).minX)),minY:t.minY,maxY:t.maxY}:{minX:t.minX,maxX:t.maxX,minY:Math.max(...n.top.map(t=\u003eEe(t).maxY)),maxY:Math.min(...n.bottom.map(t=\u003eEe(t).minY))}}({bounds:n,orientation:a,sideGroups:c}),d=o,h=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,u=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,p=2*(h+u),m=\"vertical-columns\"===a?[\"left\",\"right\"]:[\"top\",\"bottom\"],g=[{key:\"center\",bounds:l,regionType:\"center\"},...vZ(s,t),...m.flatMap(t=\u003efunction({side:t,sideObstacles:e,bounds:n,centralBounds:o}){const i=[];for(let r=0;r\u003ce.length-1;r++){const s=Ee(e[r]),a=Ee(e[r+1]);let c;c=\"left\"===t?{minX:n.minX,maxX:o.minX,minY:s.maxY,maxY:a.minY}:\"right\"===t?{minX:o.maxX,maxX:n.maxX,minY:s.maxY,maxY:a.minY}:\"top\"===t?{minX:s.maxX,maxX:a.minX,minY:n.minY,maxY:o.minY}:{minX:s.maxX,maxX:a.minX,minY:o.maxY,maxY:n.maxY},i.push({key:`${t}-gap-${r}`,bounds:c,regionType:\"pad-gap\"})}return i}({side:t,sideObstacles:c[t],bounds:n,centralBounds:l}))],f=g.flatMap(t=\u003ebZ({nodeId:`soic:${d}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:p,regionType:t.regionType,obstacleZ:t.obstacleZ,connectedTo:t.connectedTo}));this.output={routingRegions:f},this.stats={componentId:o,layerCount:t,orientation:a,viaDiameter:h,obstacleMargin:u,multiLayerThreshold:p,firstSidePadCount:c[m[0]].length,secondSidePadCount:c[m[1]].length,multiLayerNodeCount:f.filter(t=\u003et.availableZ.length\u003e1).length,totalMeshNodeCount:f.length},this.solved=!0}getOutput(){if(!this.output)throw new Error(\"SoicTopologyGeneratorSolver has not solved yet\");return this.output}});var wZ=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;activeSubSolver=null;currentIndex=0;componentMeshNodes=[];getConstructorParams(){return[this.inputProblem]}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.failed)return this.error=this.activeSubSolver.error,this.failed=!0,void(this.activeSubSolver=null);if(!this.activeSubSolver.solved)return;return this.componentMeshNodes.push(this.activeSubSolver.getOutput().routingRegions),this.currentIndex+=1,void(this.activeSubSolver=null)}if(this.currentIndex\u003e=this.inputProblem.componentSrjs.length)return void(this.solved=!0);const t=this.inputProblem.componentKinds[this.currentIndex],e=this.inputProblem.componentSrjs[this.currentIndex],n={inputSrj:e,detectedComponent:{componentId:this.inputProblem.componentIds[this.currentIndex],componentKind:t,bounds:{__type:\"rect\",...e.bounds}},viaDiameter:this.inputProblem.viaDiameter,obstacleMargin:this.inputProblem.obstacleMargin};this.activeSubSolver=dU.create(n)}getOutput(){return{componentMeshNodes:this.componentMeshNodes}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.inputProblem.componentSrjs[this.currentIndex]??null,e=this.componentMeshNodes.flatMap(t=\u003et);return{rects:[...t?[{center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,fill:\"rgba(0,0,0,0)\",stroke:\"rgba(255,140,0,0.72)\",label:`active component ${this.inputProblem.componentIds[this.currentIndex]??this.currentIndex}`},...t.obstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.10)\",stroke:\"rgba(255,140,0,0.30)\",label:t.obstacleId??t.componentId??\"obstacle\"}))]:[],...e.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.14)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.34)\":\"rgba(0,120,255,0.38)\"}))]}}},TZ=.001;function RZ(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(const t of e){const e=n[n.length-1];(void 0===e||Math.abs(t-e)\u003eTZ)\u0026\u0026n.push(t)}return n}function EZ(t){const e=Math.min(...t),n=Math.max(...t);return!(e\u003c=0)\u0026\u0026n/e\u003c=1.01}function AZ(t){if(!function(t){return EZ(t.map(t=\u003et.width))\u0026\u0026EZ(t.map(t=\u003et.height))}(t))return!1;if(!function(t){return t.every(t=\u003e{const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return!(e\u003c=0)\u0026\u0026n/e\u003c=1.5})}(t))return!1;const e=RZ(t.map(t=\u003et.center.y)),n=RZ(t.map(t=\u003et.center.x)),o=e.length,i=n.length;if(o\u003c3||i\u003c3)return!1;const r=o*i;return!((r\u003e0?t.length/r:0)\u003c.5)\u0026\u0026!!function(t,e,n){if(e.length\u003c3)return!1;if(n.length\u003c3)return!1;const o=new Set(e.slice(1,-1)),i=new Set(n.slice(1,-1));let r=0;for(const e of t)o.has(e.center.y)\u0026\u0026i.has(e.center.x)\u0026\u0026(r+=1);return r\u003e=1}(t,e,n)}function OZ(t){return[Math.round(t.width/TZ),Math.round(t.height/TZ),t.layers.join(\",\")].join(\":\")}function kZ(t){if(t.length\u003c3)return!1;const e=[...t].sort((t,e)=\u003et-e),n=e[1]-e[0];return!(n\u003c=TZ)\u0026\u0026e.every((t,o)=\u003e0===o||Math.abs(t-e[o-1]-n)\u003c=TZ)}function LZ(t){const e=function(t){const e=new Map;for(const n of t){const t=Math.round(n.center.y/TZ),o=Math.round(n.center.x/TZ),i=e.get(t)??{y:n.center.y,obstaclesByX:new Map};i.obstaclesByX.set(o,n),e.set(t,i)}return[...e.values()]}(t);let n=[];for(const t of e){const o=[...t.obstaclesByX.keys()];if(!kZ([...t.obstaclesByX.values()].map(t=\u003et.center.x)))continue;const i=e.filter(t=\u003eo.every(e=\u003et.obstaclesByX.has(e)));if(!kZ(i.map(t=\u003et.y)))continue;const r=i.flatMap(t=\u003eo.map(e=\u003et.obstaclesByX.get(e)));r.length\u003en.length\u0026\u0026(n=r)}return n}function DZ(t){if(AZ(t))return t;const e=Map.groupBy(t,OZ);let n=[];for(const t of e.values()){const e=LZ(t);e.length\u003en.length\u0026\u0026(n=e)}return n.length\u003e0?n:null}function zZ(t){const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return e\u003e0\u0026\u0026n/e\u003e=1.5}function FZ({perimeterPadObstacles:t,thermalPadObstacles:e}){if(0===e.length)return!0;if(e.length\u003e4)return!1;const n=CZ(t),o=n.maxX-n.minX,i=n.maxY-n.minY,r=n.minX+.2*o,s=n.maxX-.2*o,a=n.minY+.2*i,c=n.maxY-.2*i,l=Math.min(...t.map(t=\u003eMath.min(t.width,t.height)));return e.every(t=\u003e{const e=Math.min(t.width,t.height);return t.center.x\u003e=r\u0026\u0026t.center.x\u003c=s\u0026\u0026t.center.y\u003e=a\u0026\u0026t.center.y\u003c=c\u0026\u0026e\u003el})}function BZ(t){if(t.length\u003c12)return!1;if(t.length\u003e32)return!1;const{counts:e,maxNearestSideRatio:n}=function(t){const e=CZ(t),n=e.maxX-e.minX,o=e.maxY-e.minY,i={top:0,right:0,bottom:0,left:0};if(n\u003c=0||o\u003c=0)return{counts:i,maxNearestSideRatio:1};let r=0;for(const s of t){const t=s.width\u003es.height,a=[{side:\"top\",distance:Math.abs(s.center.y-e.minY),axisSpan:o,orientationMatches:!t},{side:\"right\",distance:Math.abs(e.maxX-s.center.x),axisSpan:n,orientationMatches:t},{side:\"bottom\",distance:Math.abs(e.maxY-s.center.y),axisSpan:o,orientationMatches:!t},{side:\"left\",distance:Math.abs(s.center.x-e.minX),axisSpan:n,orientationMatches:t}].filter(t=\u003et.orientationMatches).sort((t,e)=\u003et.distance-e.distance)[0];i[a.side]+=1,r=Math.max(r,a.distance/a.axisSpan)}return{counts:i,maxNearestSideRatio:r}}(t);return e.top\u003e=3\u0026\u0026e.right\u003e=3\u0026\u0026e.bottom\u003e=3\u0026\u0026e.left\u003e=3\u0026\u0026n\u003c=.25}function jZ(t){const e=function(t){return t.filter(zZ)}(t);return{perimeterPadObstacles:e,thermalPadObstacles:t.filter(t=\u003e!zZ(t))}}function $Z(t){const e=Math.min(...t),n=Math.max(...t);return!(e\u003c=0)\u0026\u0026n/e\u003c=1.01}function YZ(t,e){let n=0,o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ce.length;i++){const r=Math.abs(t-e[i]);r\u003co\u0026\u0026(n=i,o=r)}return n}function XZ({memberObstacles:t,inputSrj:e}){if(!function(t){return $Z(t.map(t=\u003et.width))\u0026\u0026$Z(t.map(t=\u003et.height))}(t))return!1;const n=RZ(t.map(t=\u003et.center.y)),o=RZ(t.map(t=\u003et.center.x));if(!(2===n.length\u0026\u0026o.length\u003e=4||2===o.length\u0026\u0026n.length\u003e=4))return!1;const i=function({memberObstacles:t,rowAxisValues:e,columnAxisValues:n}){if(2===e.length\u0026\u0026n.length\u003e=4){const n=[[],[]];for(const o of t)n[YZ(o.center.y,e)].push(o);return Math.min(...n[1].map(t=\u003et.center.y-t.height/2))-Math.max(...n[0].map(t=\u003et.center.y+t.height/2))}if(2===n.length\u0026\u0026e.length\u003e=4){const e=[[],[]];for(const o of t)e[YZ(o.center.x,n)].push(o);return Math.min(...e[1].map(t=\u003et.center.x-t.width/2))-Math.max(...e[0].map(t=\u003et.center.x+t.width/2))}return null}({memberObstacles:t,rowAxisValues:n,columnAxisValues:o});if(null===i)return!1;return i\u003e2*(Yo(e).padDiameter+(e.defaultObstacleMargin??.15))}var VZ=[class t{constructor(t){this.params=t}params;static componentKind=\"qfp_thermalpad\";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){const{perimeterPadObstacles:e,thermalPadObstacles:n}=jZ(t);return 0!==n.length\u0026\u0026!!BZ(e)\u0026\u0026FZ({perimeterPadObstacles:e,thermalPadObstacles:n})}(t)}},class t{constructor(t){this.params=t}params;static componentKind=\"qfp\";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){const{perimeterPadObstacles:e,thermalPadObstacles:n}=jZ(t);return!(n.length\u003e0)\u0026\u0026!!FZ({perimeterPadObstacles:e,thermalPadObstacles:n})\u0026\u0026BZ(e)}(t)}},class t{constructor(t){this.params=t}params;static componentKind=\"soic\";componentKind=t.componentKind;static isMatch(t){return XZ(t)}},class t{constructor(t){this.params=t}params;static componentKind=\"bga\";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){return null!==DZ(t)}(t)}}];function WZ(t){return function(t){for(const e of VZ)if(e.isMatch(t))return new e(t);return null}(t)?.componentKind??null}var HZ=class extends kt{inputSrj;initialized=!1;groupedComponentObstacles={};groupedComponentKinds={};unprocessedComponentIds=[];detectedComponents=[];currentComponentId=null;currentMemberObstacles=[];output=null;constructor({inputSrj:t}){super(),this.inputSrj=t}getConstructorParams(){return[{inputSrj:this.inputSrj}]}_step(){this.initialized?this.output?this.solved=!0:null!==this.currentComponentId||this.unprocessedComponentIds.length\u003e0?this.processNextComponent():(this.finalizeOutput(),this.solved=!0):this.initializeDetectionState()}getOutput(){if(!this.output)throw new Error(\"ComponentDetectionSolver has not solved yet\");return this.output}visualize(){const t=[];t.push(...this.inputSrj.obstacles.filter(t=\u003e!t.componentId).map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(120, 120, 120, 0.10)\",stroke:\"rgba(120, 120, 120, 0.40)\",label:t.obstacleId,layer:t.layers.join(\",\"),step:0})));const e=new Set(this.detectedComponents.map(t=\u003et.componentId));for(const n of this.inputSrj.obstacles){if(!n.componentId)continue;if(e.has(n.componentId))continue;const o=n.componentId===this.currentComponentId,i=Ro(n.componentId),r=this.groupedComponentKinds[n.componentId];t.push({center:n.center,width:n.width,height:n.height,fill:To(i,o?.55:.82),stroke:To(i,o?.1:.45),label:r?`${n.componentId} ${r.toUpperCase()}`:n.componentId,layer:n.layers.join(\",\"),step:o?1:0})}for(const e of this.detectedComponents){const n=Ro(e.componentId);t.push({center:{x:(e.bounds.minX+e.bounds.maxX)/2,y:(e.bounds.minY+e.bounds.maxY)/2},width:e.bounds.maxX-e.bounds.minX,height:e.bounds.maxY-e.bounds.minY,fill:To(n,.88),stroke:To(n,.1),label:`${e.componentId} ${e.componentKind.toUpperCase()} region`,step:2})}return{title:this.getVisualizationTitle(),rects:t,lines:[],points:[],circles:[]}}preview(){return this.visualize()}initializeDetectionState(){this.initialized=!0,this.groupedComponentKinds={},this.groupedComponentObstacles=this.groupObstaclesByComponentId({obstacles:this.inputSrj.obstacles}),this.unprocessedComponentIds=Object.keys(this.groupedComponentObstacles).sort(),this.detectedComponents=[],this.currentComponentId=null,this.currentMemberObstacles=[],this.output=null}processNextComponent(){if(!this.currentComponentId){const t=this.unprocessedComponentIds.shift();return t?(this.currentComponentId=t,void(this.currentMemberObstacles=this.groupedComponentObstacles[t]??[])):(this.currentComponentId=null,void(this.currentMemberObstacles=[]))}if(0===this.currentMemberObstacles.length)return this.currentComponentId=null,void(this.currentMemberObstacles=[]);this.detectedComponents.push(this.createDetectedComponent({componentId:this.currentComponentId,componentKind:this.groupedComponentKinds[this.currentComponentId],memberObstacles:this.currentMemberObstacles})),this.currentComponentId=null,this.currentMemberObstacles=[]}finalizeOutput(){this.output=this.detectedComponents.map(t=\u003e({...t,bounds:{...t.bounds}})),this.stats={initialized:this.initialized,totalComponentCount:Object.keys(this.groupedComponentObstacles).length,detectedComponentCount:this.detectedComponents.length,detectedBgaComponentCount:this.detectedComponents.filter(t=\u003e\"bga\"===t.componentKind).length,detectedQfpComponentCount:this.detectedComponents.filter(t=\u003e\"qfp\"===t.componentKind).length,detectedQfpComponentIds:this.detectedComponents.filter(t=\u003e\"qfp\"===t.componentKind).map(t=\u003et.componentId),detectedQfpThermalPadComponentCount:this.detectedComponents.filter(t=\u003e\"qfp_thermalpad\"===t.componentKind).length,detectedQfpThermalPadComponentIds:this.detectedComponents.filter(t=\u003e\"qfp_thermalpad\"===t.componentKind).map(t=\u003et.componentId),detectedSoicComponentCount:this.detectedComponents.filter(t=\u003e\"soic\"===t.componentKind).length,detectedSoicComponentIds:this.detectedComponents.filter(t=\u003e\"soic\"===t.componentKind).map(t=\u003et.componentId),remainingComponentCount:this.unprocessedComponentIds.length,hasActiveComponent:null!==this.currentComponentId}}groupObstaclesByComponentId({obstacles:t}){const e={},n={};for(const n of t)n.componentId\u0026\u0026(e[n.componentId]??=[],e[n.componentId].push(n));const o=Object.entries(e).flatMap(([t,e])=\u003e{const o=this.inputSrj.bounds;if(e.some(t=\u003e!NZ({bounds:Ee(t),outerBounds:o,epsilon:0})))return[];const i=WZ({memberObstacles:e,inputSrj:this.inputSrj});if(!i)return[];n[t]=i;return[[t,\"bga\"===i?DZ(e):e]]});return this.groupedComponentKinds=n,Object.fromEntries(o)}createDetectedComponent({componentId:t,componentKind:e,memberObstacles:n}){return{componentId:t,componentKind:e,bounds:{__type:\"rect\",...CZ(n)}}}getVisualizationTitle(){const t=Object.keys(this.groupedComponentObstacles).length||new Set(this.inputSrj.obstacles.map(t=\u003et.componentId).filter(t=\u003eBoolean(t))).size,e=this.detectedComponents.length;return this.initialized?this.output||this.solved?`Component Detection: done ${e}/${t}`:null!==this.currentComponentId||this.unprocessedComponentIds.length\u003e0?`Component Detection: ${e}/${t} processed`:`Component Detection: finalizing ${e}/${t}`:\"Component Detection: setup\"}},GZ=t=\u003et.componentId\u0026\u0026t.obstacleId?`${t.componentId}\\n${t.obstacleId}`:t.componentId??t.obstacleId??\"obstacle\",UZ=class extends Dt{rectBoundsComponentDetection;pipelineDef=[Lt(\"rectBoundsComponentDetection\",HZ,t=\u003e[{inputSrj:t.inputProblem.inputSrj}])];getConstructorParams(){return[this.inputProblem]}getOutput(){const t=this.getStageOutput(\"rectBoundsComponentDetection\");if(!t)throw new Error(\"ComponentDetectionSolver has not solved yet\");return t}initialVisualize(){const{bounds:t}=this.inputProblem.inputSrj;return{title:\"Component Detection: board and grouped component pads\",rects:[{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,fill:\"rgba(0, 0, 0, 0)\",stroke:\"rgba(40, 40, 40, 0.7)\",label:\"Board bounds\",step:0},...this.inputProblem.inputSrj.obstacles.map(t=\u003e{const e=t.componentId?Ro(t.componentId):null;return{center:t.center,width:t.width,height:t.height,fill:e?To(e,.72):\"rgba(120, 120, 120, 0.10)\",stroke:e?To(e,.28):\"rgba(120, 120, 120, 0.40)\",label:GZ(t),layer:t.layers.join(\",\"),step:t.componentId?1:0}})],lines:[],points:[],circles:[]}}},ZZ=1e-9;function qZ(t){return Ve({center:t.center,width:t.width,height:t.height})}function JZ(t,e){const n={minX:Math.max(t.minX,e.minX),maxX:Math.min(t.maxX,e.maxX),minY:Math.max(t.minY,e.minY),maxY:Math.min(t.maxY,e.maxY)};return KZ(n)?n:null}function KZ(t){const e=t.maxX-t.minX,n=t.maxY-t.minY,o=Number.isFinite(e)\u0026\u0026e\u003eZZ,i=Number.isFinite(n)\u0026\u0026n\u003eZZ;return o\u0026\u0026i}function QZ(t){!function(t){if(!Number.isInteger(t.layerCount))throw new Error(\"TopologyMergingSolver: layerCount must be an integer\");if(t.layerCount\u003c=0)throw new Error(\"TopologyMergingSolver: layerCount must be positive\");if(0===t.nodeGroups.length)throw new Error(\"TopologyMergingSolver: at least one node group is required\");const e=new Set;let n=0;for(const o of t.nodeGroups){if(e.has(o.groupId))throw new Error(`TopologyMergingSolver: duplicate topology group id \"${o.groupId}\"`);if(e.add(o.groupId),n+=o.nodes.length,0===o.nodes.length)throw new Error(`TopologyMergingSolver: topology group \"${o.groupId}\" is empty`);const i=new Set;for(const e of o.nodes){if(i.has(e.capacityMeshNodeId))throw new Error(`TopologyMergingSolver: duplicate node id \"${e.capacityMeshNodeId}\" in group \"${o.groupId}\"`);i.add(e.capacityMeshNodeId),tq({node:e,groupId:o.groupId,layerCount:t.layerCount})}}if(0===n)throw new Error(\"TopologyMergingSolver: topology node groups are empty\")}(t);const e=[],n=new Map;for(let o=0;o\u003ct.nodeGroups.length;o++){const i=t.nodeGroups[o];for(const t of i.nodes){const r={sourceKey:`${i.groupId}:${t.capacityMeshNodeId}`,groupIndex:o,node:t,bounds:qZ(t)};e.push(r),n.set(r.sourceKey,r)}}return{preparedNodes:e,preparedNodeBySourceKey:n}}function tq({node:t,groupId:e,layerCount:n}){if(!KZ(qZ(t)))throw new Error(`TopologyMergingSolver: node \"${t.capacityMeshNodeId}\" in group \"${e}\" has invalid bounds`);if(0===t.availableZ.length)throw new Error(`TopologyMergingSolver: node \"${t.capacityMeshNodeId}\" in group \"${e}\" has no available layers`);const o=[...new Set(t.availableZ)].sort((t,e)=\u003et-e),i=o.some(t=\u003e!Number.isInteger(t)||t\u003c0||t\u003e=n),r=o.length===t.availableZ.length\u0026\u0026o.every((e,n)=\u003ee===t.availableZ[n]);if(i||!r)throw new Error(`TopologyMergingSolver: node \"${t.capacityMeshNodeId}\" in group \"${e}\" has invalid or unsorted availableZ`)}var eq=1e-5,nq=4e-5;function oq({regions:t,preparedNodeBySourceKey:e,nodeGroups:n,provenance:o,preserveSourceIds:i=!0}){i\u0026\u0026(o.groupIndexesByNodeId.clear(),o.sourceKeysByNodeId.clear());const r=[...t].sort((t,e)=\u003et.bounds.minX-e.bounds.minX||t.bounds.minY-e.bounds.minY||t.bounds.maxX-e.bounds.maxX||t.bounds.maxY-e.bounds.maxY||t.availableZ[0]-e.availableZ[0]),s=new Set;return r.map((t,r)=\u003e{const a=t.sourceKeys.map(t=\u003e{const n=e.get(t);if(!n)throw new Error(`TopologyMergingSolver: missing source node for \"${t}\"`);return n}),c=a.map(({node:t})=\u003et),l=function({sourceNodes:t,isComponentTopologyNode:e}){if(1===t.length)return{_isComponentTopologyNode:!!e||t[0]._isComponentTopologyNode};const n=t.map(t=\u003et.capacityMeshNodeId),o=iq(t.map(t=\u003et._targetConnectionName),\"target connection\",n),i=iq(t.map(t=\u003et._offBoardConnectionId),\"off-board connection\",n),r=iq(t.map(t=\u003et._offboardNetName),\"off-board net\",n),s=Array.from(new Set(t.flatMap(t=\u003et._offBoardConnectedCapacityMeshNodeIds??[]))),a=Array.from(new Set(t.flatMap(t=\u003et._connectedTo??[])));return{_containsObstacle:t.some(t=\u003et._containsObstacle)||void 0,_completelyInsideObstacle:t.some(t=\u003et._completelyInsideObstacle)||void 0,_containsTarget:t.some(t=\u003et._containsTarget)||void 0,_targetConnectionName:o,_isVirtualOffboard:t.some(t=\u003et._isVirtualOffboard)||void 0,_offboardNetName:r,_offBoardConnectionId:i,_offBoardConnectedCapacityMeshNodeIds:s.length\u003e0?s:void 0,_qfpRegionType:rq(t.map(t=\u003et._qfpRegionType)),_isNarrowQfpPadGap:t.some(t=\u003et._isNarrowQfpPadGap)||void 0,_soicRegionType:rq(t.map(t=\u003et._soicRegionType)),_isComponentTopologyNode:e||void 0,_connectedTo:a.length\u003e0?a:void 0}}({sourceNodes:c,isComponentTopologyNode:a.some(({groupIndex:t})=\u003en[t].isComponent)}),d=i\u0026\u00261===a.length?a[0].node:null,h=Boolean(d\u0026\u0026function({region:t,sourceNode:e,usedNodeIds:n}){const o=qZ(e),i=Math.abs(t.bounds.minX-o.minX)\u003c=eq\u0026\u0026Math.abs(t.bounds.maxX-o.maxX)\u003c=eq\u0026\u0026Math.abs(t.bounds.minY-o.minY)\u003c=eq\u0026\u0026Math.abs(t.bounds.maxY-o.maxY)\u003c=eq,r=t.availableZ.length===e.availableZ.length\u0026\u0026t.availableZ.every((t,n)=\u003et===e.availableZ[n]);return i\u0026\u0026r\u0026\u0026!n.has(e.capacityMeshNodeId)}({region:t,sourceNode:d,usedNodeIds:s}));let u=h?d.capacityMeshNodeId:`topology_merge_${r}`;for(;s.has(u);)u=`${u}_next`;return s.add(u),i\u0026\u0026(o.groupIndexesByNodeId.set(u,[...new Set(a.map(({groupIndex:t})=\u003et))]),o.sourceKeysByNodeId.set(u,[...t.sourceKeys])),{...d??c[0],...l,capacityMeshNodeId:u,center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,layer:`z${t.availableZ.join(\",\")}`,availableZ:[...t.availableZ],_adjacentNodeIds:void 0,_parent:void 0,_strawNode:void 0,_strawParentCapacityMeshNodeId:void 0}})}function iq(t,e,n){const o=Array.from(new Set(t.filter(t=\u003evoid 0!==t)));if(o.length\u003e1)throw new Error(`TopologyMergingSolver: conflicting ${e} values for overlapping source nodes ${n.join(\", \")}`);return o[0]}function rq(t){const e=Array.from(new Set(t.filter(t=\u003evoid 0!==t)));return 1===e.length?e[0]:void 0}function sq({node:t,sourceKey:e,preparedNodeBySourceKey:n}){const o=n.get(e);if(!o)throw new Error(`TopologyMergingSolver: missing source node for output \"${t.capacityMeshNodeId}\"`);const i=qZ(t),r=i.minX\u003e=o.bounds.minX-nq\u0026\u0026i.maxX\u003c=o.bounds.maxX+nq\u0026\u0026i.minY\u003e=o.bounds.minY-nq\u0026\u0026i.maxY\u003c=o.bounds.maxY+nq,s=t.availableZ.every(t=\u003eo.node.availableZ.includes(t));if(!r||!s)throw new Error(`TopologyMergingSolver: output node \"${t.capacityMeshNodeId}\" escapes its source geometry or layers`)}function aq({groupIndexesA:t,groupIndexesB:e,sourceKeysA:n,sourceKeysB:o,sharedLayers:i,preparedNodeBySourceKey:r}){if(1!==t.length||1!==e.length||t[0]!==e[0]||1!==n.length||1!==o.length||n[0]===o[0])return!1;const s=r.get(n[0]),a=r.get(o[0]);if(!s||!a||0===i.length)return!1;return i.some(t=\u003es.node.availableZ.includes(t)\u0026\u0026a.node.availableZ.includes(t))\u0026\u0026null!==JZ(s.bounds,a.bounds)}function cq(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(const t of e){const e=n[n.length-1];(void 0===e||Math.abs(t-e)\u003eeq)\u0026\u0026n.push(t)}return n}function lq(t,e){return e.x\u003e=t.minX-eq\u0026\u0026e.x\u003c=t.maxX+eq\u0026\u0026e.y\u003e=t.minY-eq\u0026\u0026e.y\u003c=t.maxY+eq}function dq({coveringNodes:t,nodeGroups:e,layerCount:n}){const o=new Map;for(let i=0;i\u003cn;i++){const n=t.filter(({node:t})=\u003et.availableZ.includes(i)).sort((t,e)=\u003et.sourceKey.localeCompare(e.sourceKey));if(0===n.length)continue;const r=new Set(n.map(({groupIndex:t})=\u003et)),s=n.filter(({node:t})=\u003et._containsObstacle\u0026\u0026t._containsTarget),a=s.filter(({groupIndex:t})=\u003e!e[t].isComponent),c=new Set(s.map(({groupIndex:t})=\u003et)),l=s.length\u003e0?a.length\u003e0||1===c.size?\"target-passthrough\":\"target-merged\":1===r.size?\"passthrough\":\"merged\",d=gq({topologyMode:l,nodesOnLayer:n,targetObstacleNodes:s,globalTargetObstacleNodes:a});for(const t of d){const e=JSON.stringify({mode:l,sourceKeys:t}),n=o.get(e);n?n.availableZ.push(i):o.set(e,{availableZ:[i],sourceKeys:t,topologyMode:l,topologySignature:e})}}return[...o.values()]}function hq(t){return JSON.stringify({availableZ:t.availableZ,topologySignature:t.topologySignature})}function uq(t){return JSON.stringify({mergeKey:hq(t),minY:t.bounds.minY.toPrecision(15),maxY:t.bounds.maxY.toPrecision(15)})}function pq(t){return JSON.stringify({mergeKey:hq(t),minX:t.bounds.minX.toPrecision(15),maxX:t.bounds.maxX.toPrecision(15)})}function mq(t,e){const n=new Map;for(const o of t){const t=\"horizontal\"===e?uq(o):pq(o),i=n.get(t)??[];i.push(o),n.set(t,i)}return[...n.values()].flatMap(t=\u003efunction(t,e){const n=[...t].sort((t,n)=\u003e\"horizontal\"===e?t.bounds.minX-n.bounds.minX:t.bounds.minY-n.bounds.minY),o=[];for(const t of n){const n=o[o.length-1],i=void 0!==n\u0026\u0026(\"horizontal\"===e?Math.abs(n.bounds.maxX-t.bounds.minX)\u003c=eq:Math.abs(n.bounds.maxY-t.bounds.minY)\u003c=eq);n\u0026\u0026i?\"horizontal\"===e?n.bounds.maxX=t.bounds.maxX:n.bounds.maxY=t.bounds.maxY:o.push({...t,bounds:{...t.bounds},availableZ:[...t.availableZ],sourceKeys:[...t.sourceKeys]})}return o}(t,e))}function gq({topologyMode:t,nodesOnLayer:e,targetObstacleNodes:n,globalTargetObstacleNodes:o}){if(\"target-passthrough\"===t){return(o.length\u003e0?o:n).map(({sourceKey:t})=\u003e[t])}return\"target-merged\"===t?[n.map(({sourceKey:t})=\u003et).sort()]:\"passthrough\"===t?e.map(({sourceKey:t})=\u003e[t]):[e.map(({sourceKey:t})=\u003et).sort()]}var fq=class extends kt{constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e5;const{preparedNodes:e,preparedNodeBySourceKey:n}=QZ(t);this.preparedNodes=e,this.preparedNodeBySourceKey=n,this.xCoordinates=cq(this.preparedNodes.flatMap(({bounds:t})=\u003e[t.minX,t.maxX])),this.stats={inputNodeCount:this.preparedNodes.length,xSlabCount:Math.max(0,this.xCoordinates.length-1),processedXSlabCount:0,atomicRegionCount:0,outputNodeCount:0}}inputProblem;preparedNodes;preparedNodeBySourceKey;outputProvenance={groupIndexesByNodeId:new Map,sourceKeysByNodeId:new Map};xCoordinates;atomicRegions=[];outputNodes=[];currentXIndex=0;getConstructorParams(){return[this.inputProblem]}_step(){if(1===this.inputProblem.nodeGroups.length)return void this.completePassthroughTopology();if(this.currentXIndex\u003cthis.xCoordinates.length-1)return this.processCurrentXSlab(),this.currentXIndex+=1,this.stats.processedXSlabCount=this.currentXIndex,void(this.stats.atomicRegionCount=this.atomicRegions.length);const t=function(t){let e=t;for(;;){const t=mq(e,\"horizontal\"),n=mq(t,\"vertical\");if(n.length===e.length)return n;e=n}}(function({regions:t,preparedNodeBySourceKey:e}){const n=new Map;for(const e of t)for(const t of e.sourceKeys){const o=n.get(t)??new Set;o.add(e.topologyMode),n.set(t,o)}const o=new Set([...n.entries()].filter(([,t])=\u003e1===t.size\u0026\u0026t.has(\"target-passthrough\")).map(([t])=\u003et));return 0===o.size?t:[...t.filter(t=\u003e\"target-passthrough\"!==t.topologyMode||!o.has(t.sourceKeys[0])),...[...o].map(t=\u003e{const n=e.get(t);if(!n)throw new Error(`TopologyMergingSolver: missing authoritative target source \"${t}\"`);return{bounds:{...n.bounds},availableZ:[...n.node.availableZ],sourceKeys:[t],topologyMode:\"target-passthrough\",topologySignature:JSON.stringify({mode:\"target-passthrough\",sourceKeys:[t]})}})]}({regions:this.atomicRegions,preparedNodeBySourceKey:this.preparedNodeBySourceKey}));this.outputNodes=oq({regions:t,preparedNodeBySourceKey:this.preparedNodeBySourceKey,nodeGroups:this.inputProblem.nodeGroups,provenance:this.outputProvenance}),function({nodes:t,preparedNodeBySourceKey:e,provenance:n}){const o=new Set;for(const i of t){if(o.has(i.capacityMeshNodeId))throw new Error(`TopologyMergingSolver: duplicate output node id \"${i.capacityMeshNodeId}\"`);if(o.add(i.capacityMeshNodeId),!KZ(qZ(i)))throw new Error(`TopologyMergingSolver: output node \"${i.capacityMeshNodeId}\" has invalid bounds`);if(0===i.availableZ.length)throw new Error(`TopologyMergingSolver: output node \"${i.capacityMeshNodeId}\" has no available layers`);const t=n.sourceKeysByNodeId.get(i.capacityMeshNodeId);if(!t)throw new Error(`TopologyMergingSolver: missing output provenance for node \"${i.capacityMeshNodeId}\"`);1===t.length\u0026\u0026sq({node:i,sourceKey:t[0],preparedNodeBySourceKey:e})}for(let o=0;o\u003ct.length;o++){const i=t[o];for(let r=o+1;r\u003ct.length;r++){const o=t[r],s=i.availableZ.filter(t=\u003eo.availableZ.includes(t));if(0===s.length)continue;const a=JZ(qZ(i),qZ(o));if(!a)continue;const c=a.maxX-a.minX,l=a.maxY-a.minY;if(c\u003c=nq||l\u003c=nq)continue;const d=n.groupIndexesByNodeId.get(i.capacityMeshNodeId),h=n.groupIndexesByNodeId.get(o.capacityMeshNodeId);if(!d||!h)throw new Error(`TopologyMergingSolver: missing output provenance for overlapping nodes \"${i.capacityMeshNodeId}\" and \"${o.capacityMeshNodeId}\"`);const u=n.sourceKeysByNodeId.get(i.capacityMeshNodeId),p=n.sourceKeysByNodeId.get(o.capacityMeshNodeId);if(!u||!p)throw new Error(`TopologyMergingSolver: missing source provenance for overlapping nodes \"${i.capacityMeshNodeId}\" and \"${o.capacityMeshNodeId}\"`);if(!aq({groupIndexesA:d,groupIndexesB:h,sourceKeysA:u,sourceKeysB:p,sharedLayers:s,preparedNodeBySourceKey:e}))throw new Error(`TopologyMergingSolver: output nodes \"${i.capacityMeshNodeId}\" and \"${o.capacityMeshNodeId}\" have an unresolved inter-group overlap on a shared layer`)}}}({nodes:this.outputNodes,preparedNodeBySourceKey:this.preparedNodeBySourceKey,provenance:this.outputProvenance}),this.stats.outputNodeCount=this.outputNodes.length,this.stats.compactedRegionCount=t.length,this.solved=!0}getOutput(){if(!this.solved)throw new Error(\"TopologyMergingSolver: getOutput() called before the solver completed\");return this.outputNodes}computeProgress(){const t=Math.max(1,this.xCoordinates.length-1);return this.solved?1:Math.min(.99,this.currentXIndex/t)}visualize(){const t=this.solved?this.outputNodes:oq({regions:this.atomicRegions,preparedNodeBySourceKey:this.preparedNodeBySourceKey,nodeGroups:this.inputProblem.nodeGroups,provenance:this.outputProvenance,preserveSourceIds:!1});return{title:`Topology Merging: ${t.length} refined regions`,coordinateSystem:\"cartesian\",rects:t.map(t=\u003e({...Dc(t,{rectMargin:.01,zOffset:.02}),label:`${t.capacityMeshNodeId}\\navailableZ: ${t.availableZ.join(\",\")}\\ncomponent: ${t._isComponentTopologyNode?\"yes\":\"no\"}`})),lines:[],points:[],circles:[],texts:[]}}completePassthroughTopology(){const t=this.inputProblem.nodeGroups[0];this.outputNodes=t.nodes;for(const e of this.outputNodes)this.outputProvenance.groupIndexesByNodeId.set(e.capacityMeshNodeId,[0]),this.outputProvenance.sourceKeysByNodeId.set(e.capacityMeshNodeId,[`${t.groupId}:${e.capacityMeshNodeId}`]);this.stats.processedXSlabCount=this.stats.xSlabCount,this.stats.atomicRegionCount=0,this.stats.compactedRegionCount=0,this.stats.outputNodeCount=this.outputNodes.length,this.stats.passthroughNodeCount=this.outputNodes.length,this.solved=!0}processCurrentXSlab(){const t=this.xCoordinates[this.currentXIndex],e=this.xCoordinates[this.currentXIndex+1];if(e-t\u003c=eq)return;const n=(t+e)/2,o=this.preparedNodes.filter(({bounds:t})=\u003en\u003e=t.minX-eq\u0026\u0026n\u003c=t.maxX+eq),i=cq(o.flatMap(({bounds:t})=\u003e[t.minY,t.maxY]));for(let r=0;r\u003ci.length-1;r++){const s=i[r],a=i[r+1];if(a-s\u003c=eq)continue;const c={x:n,y:(s+a)/2},l=o.filter(({bounds:t})=\u003elq(t,c));if(0===l.length)continue;const d=dq({coveringNodes:l,nodeGroups:this.inputProblem.nodeGroups,layerCount:this.inputProblem.layerCount});for(const n of d)this.atomicRegions.push({bounds:{minX:t,maxX:e,minY:s,maxY:a},availableZ:n.availableZ,sourceKeys:n.sourceKeys,topologyMode:n.topologyMode,topologySignature:n.topologySignature})}}};function yq({meshNodes:t,components:e}){return 0===e.length?t:t.map(t=\u003e{const n=e.some(e=\u003efunction({node:t,component:e}){const{replacementObstacle:n}=e,o=Math.abs(t.center.x-n.center.x)\u003c=ZZ\u0026\u0026Math.abs(t.center.y-n.center.y)\u003c=ZZ\u0026\u0026Math.abs(t.width-n.width)\u003c=ZZ\u0026\u0026Math.abs(t.height-n.height)\u003c=ZZ;if(\"qfp\"!==e.componentKind\u0026\u0026\"qfp_thermalpad\"!==e.componentKind\u0026\u0026\"soic\"!==e.componentKind)return o;const i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=n.center.y-n.height/2,a=n.center.y+n.height/2,c=t.center.x\u003e=i-ZZ\u0026\u0026t.center.x\u003c=r+ZZ\u0026\u0026t.center.y\u003e=s-ZZ\u0026\u0026t.center.y\u003c=a+ZZ,l=t.width*t.height,d=n.width*n.height,h=c\u0026\u0026l\u003e=.2*d;return o||h}({node:t,component:e}));return n?{...t,_containsObstacle:void 0,_completelyInsideObstacle:void 0,_containsTarget:void 0,_targetConnectionName:void 0,_connectedTo:void 0}:t})}var _q=class extends Dt{globalTopologySolver;componentTopologyBatchSolver;normalizedInput;pipelineDef=[Lt(\"globalTopologySolver\",Kn,t=\u003e[t.getGlobalTopologySolverInput()]),Lt(\"componentTopologyBatchSolver\",wZ,t=\u003e[{componentSrjs:t.getComponentNoConnectionSrjs(),componentIds:t.normalizedInput.components.map(t=\u003et.componentId),componentKinds:t.normalizedInput.components.map(t=\u003et.componentKind),viaDiameter:t.inputProblem.viaDiameter,obstacleMargin:t.inputProblem.obstacleMargin}])];constructor(t){super(t),this.normalizedInput=PZ(t)}getConstructorParams(){return[this.inputProblem]}getOutput(){const t=yq({meshNodes:this.getStageOutput(\"globalTopologySolver\")?.meshNodes??[],components:this.normalizedInput.components}),e=this.getStageOutput(\"componentTopologyBatchSolver\")?.componentMeshNodes??[],n=this.getComponentNoConnectionSrjs();return{globalNoConnectionSrj:this.normalizedInput.globalNoConnectionSrj,componentNoConnectionSrjs:n,globalMeshNodes:t,componentMeshNodes:e}}finalVisualize(){const t=this.getOutput();return{title:\"Topology Planning: generated topology groups\",rects:[...t.componentNoConnectionSrjs.flatMap((t,e)=\u003e{const n=this.normalizedInput.components[e]??null;return t.obstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(120, 120, 120, 0.06)\",stroke:\"rgba(120, 120, 120, 0.35)\",label:t.obstacleId??n?.componentId??\"component-pad\",layer:t.layers.join(\",\")}))}),...[...t.globalMeshNodes,...t.componentMeshNodes.flat()].map(t=\u003e{const e=this.normalizedInput.components.find(e=\u003et.capacityMeshNodeId.includes(e.componentId));return{...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?To(\"red\",.82):\"rgba(0, 120, 255, 0.12)\",stroke:t._containsObstacle?To(\"red\",.3):\"rgba(0, 120, 255, 0.55)\",label:e?`${e.componentKind.toUpperCase()} ${t.capacityMeshNodeId}`:t.capacityMeshNodeId}})],lines:[],points:[],circles:[],texts:[]}}visualize(){return this.filterGlobalRectDiffNodesFromVisualization({visualization:super.visualize()})}preview(){return this.filterGlobalRectDiffNodesFromVisualization({visualization:super.preview()})}getComponentNoConnectionSrjs(){return this.normalizedInput.components.map(t=\u003efunction({inputSrj:t,component:e}){const n=CZ(e.memberObstacles),o=Math.max(t.minViaPadDiameter??t.min_via_pad_diameter??t.minViaDiameter??.3,t.defaultObstacleMargin??.15,2*t.minTraceWidth),i=new Set(e.memberObstacles.flatMap(t=\u003et.connectedTo)),r=t.connections.flatMap(t=\u003et.pointsToConnect.filter(t=\u003e{const e=[t.pointId,t.pcb_port_id].filter(t=\u003e\"string\"==typeof t).some(t=\u003ei.has(t)),r=t.x\u003e=n.minX-o\u0026\u0026t.x\u003c=n.maxX+o\u0026\u0026t.y\u003e=n.minY-o\u0026\u0026t.y\u003c=n.maxY+o;return e\u0026\u0026r})).reduce((t,e)=\u003e({minX:Math.min(t.minX,e.x),maxX:Math.max(t.maxX,e.x),minY:Math.min(t.minY,e.y),maxY:Math.max(t.maxY,e.y)}),n),s=t.obstacles.filter(t=\u003eXe(Ee(t),r)).map(t=\u003e({...t}));return{...structuredClone(t),bounds:r,obstacles:s}}({inputSrj:this.inputProblem.inputSrj,component:t}))}getGlobalTopologySolverInput(){return{simpleRouteJson:this.normalizedInput.globalNoConnectionSrj,maxGapFillPasses:4}}filterGlobalRectDiffNodesFromVisualization({visualization:t}){return{...t,rects:MZ({rects:t.rects,components:this.normalizedInput.components})}}},bq=(t,e)=\u003e{if(t)return Object.entries(e).sort(([t],[e])=\u003ee.length-t.length).find(([e])=\u003et.includes(e))?.[1]},xq=(t,e)=\u003e({...t,points:t.points?.map(t=\u003e({...t,color:bq(t.label,e)??t.color})),lines:t.lines?.map(t=\u003e({...t,strokeColor:bq(t.label,e)??t.strokeColor})),circles:t.circles?.map(t=\u003e{const n=bq(t.label,e);return n?{...t,fill:n,stroke:n}:t})}),vq=class extends si{constructor(t){super(),this.topologyPlanningSolver=t,this.solved=t.solved,this.failed=t.failed,this.error=t.error,this.stats=t.stats}topologyPlanningSolver;getOutput(){return this.topologyPlanningSolver.getOutput().componentMeshNodes.flat()}visualize(){return this.topologyPlanningSolver.finalVisualize()??this.topologyPlanningSolver.visualize()}preview(){return this.visualize()}},Sq=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\u0026\u0026!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026this.tryFinalAcceptance(),!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),\"computeProgress\"in this\u0026\u0026(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error(\"getConstructorParams not implemented\")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved\u0026\u0026!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:[]}}},Iq=t=\u003et.filter(t=\u003eBoolean(t)),Cq=(t,e,n)=\u003e{const o=`${Math.round(100*t.x)},${Math.round(100*t.y)}`,i=e.map(t=\u003e((t,e)=\u003e\"top\"===t?0:\"bottom\"===t?e-1:Number.parseInt(t.slice(5),10))(t,n)).sort().join(\"-\");return`${o}:${i}`},Pq=class{parent=new Map;constructor(t,e=t.traces??[],n={}){for(const e of t.connections)this.unionAll(Iq([e.name,e.source_trace_id,e.rootConnectionName,e.netConnectionName,...e.mergedConnectionNames??[],...e.pointsToConnect.flatMap(e=\u003e[e.pointId,e.pcb_port_id,...n.includePhysicalPositionAliases?[Cq(e,e.layers??[e.layer],t.layerCount)]:[]])]));for(const n of[...e,...t.fixedTraces??[]])this.unionAll(Iq([n.pcb_trace_id,n.connection_name,n.source_trace_id,n.rootConnectionName,...n.mergedConnectionNames??[],...n.connectsTo??[]]));for(const e of t.obstacles)this.unionAll(n.includePhysicalPositionAliases?Iq([e.obstacleId,...e.connectedTo,...e.offBoardConnectsTo??[],Cq(e.center,e.layers,t.layerCount)]):e.connectedTo)}canonicalize(t){return[...new Set(t.map(t=\u003ethis.find(t)))]}unionAll(t){const e=t[0];if(e){this.add(e);for(let n=1;n\u003ct.length;n++)this.union(e,t[n])}}add(t){this.parent.has(t)||this.parent.set(t,t)}find(t){this.add(t);const e=this.parent.get(t);if(e===t)return t;const n=this.find(e);return this.parent.set(t,n),n}union(t,e){const n=this.find(t),o=this.find(e);n!==o\u0026\u0026this.parent.set(o,n)}},Mq=1e-6,Nq=(t,e)=\u003eMath.hypot(e.x-t.x,e.y-t.y),wq=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c=1e-12)return Nq(t,e);const s=Rq(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return Math.hypot(t.x-(e.x+o*s),t.y-(e.y+i*s))},Tq=(t,e,n=1e-6)=\u003eMath.abs(t.x-e.x)\u003c=n\u0026\u0026Math.abs(t.y-e.y)\u003c=n,Rq=(t,e,n)=\u003eMath.max(e,Math.min(n,t)),Eq=(t,e,n)=\u003e(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),Aq=(t,e,n)=\u003eMath.abs(Eq(e,n,t))\u003c=1e-9\u0026\u0026t.x\u003e=Math.min(e.x,n.x)-1e-9\u0026\u0026t.x\u003c=Math.max(e.x,n.x)+1e-9\u0026\u0026t.y\u003e=Math.min(e.y,n.y)-1e-9\u0026\u0026t.y\u003c=Math.max(e.y,n.y)+1e-9,Oq=(t,e,n,o)=\u003e((t,e,n,o)=\u003e{const i=Eq(t,e,n),r=Eq(t,e,o),s=Eq(n,o,t),a=Eq(n,o,e);return i*r\u003c0\u0026\u0026s*a\u003c0||Math.abs(i)\u003c=1e-9\u0026\u0026Aq(n,t,e)||Math.abs(r)\u003c=1e-9\u0026\u0026Aq(o,t,e)||Math.abs(s)\u003c=1e-9\u0026\u0026Aq(t,n,o)||Math.abs(a)\u003c=1e-9\u0026\u0026Aq(e,n,o)})(t,e,n,o)?0:Math.min(wq(t,n,o),wq(e,n,o),wq(n,t,e),wq(o,t,e)),kq=(t,e)=\u003e{let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];if(Aq(t,s,r))return!0;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n},Lq=(t,e,n)=\u003e{if(kq(t,n)||kq(e,n))return 0;let o=Number.POSITIVE_INFINITY;for(let i=0;i\u003cn.length;i++){const r=n[i],s=n[(i+1)%n.length];o=Math.min(o,Oq(t,e,r,s))}return o};function Dq(t,e,n){let o=0,i=1;const r=e.x-t.x,s=e.y-t.y,a=[[-r,t.x-n.minX],[r,n.maxX-t.x],[-s,t.y-n.minY],[s,n.maxY-t.y]];for(const[t,e]of a){if(Math.abs(t)\u003c1e-12){if(e\u003c0)return!1;continue}const n=e/t;if(t\u003c0?o=Math.max(o,n):i=Math.min(i,n),o\u003ei)return!1}return!0}function zq({start:t,end:e,width:n,base:o}){const i=Nq(t,e),r=(t=\u003eRq(1.25*t,.25,.75))(n),s=Math.max(1,Math.ceil(i/r)),a=n/2,c=[];for(let i=0;i\u003cs;i++){const r=i/s,l=(i+1)/s,d=t.x+(e.x-t.x)*r,h=t.y+(e.y-t.y)*r,u=t.x+(e.x-t.x)*l,p=t.y+(e.y-t.y)*l;c.push({...o,minX:Math.min(d,u)-a,minY:Math.min(h,p)-a,maxX:Math.max(d,u)+a,maxY:Math.max(h,p)+a,exactShape:{type:\"segment\",start:{x:d,y:h},end:{x:u,y:p},width:n}})}return c}var Fq=(t,e,n)=\u003e{const o=Math.cos(n),i=Math.sin(n),r=t.x-e.x,s=t.y-e.y;return{x:e.x+r*o-s*i,y:e.y+r*i+s*o}};var Bq=class{nodeIndices=[];priorities=[];get size(){return this.nodeIndices.length}push(t,e){let n=this.nodeIndices.length;for(this.nodeIndices.push(t),this.priorities.push(e);n\u003e0;){const t=n-1\u003e\u003e1;if(this.priorities[t]\u003c=e)break;this.swap(n,t),n=t}}pop(){const t=this.nodeIndices[0],e=this.nodeIndices.pop(),n=this.priorities.pop();if(0===this.nodeIndices.length)return t;this.nodeIndices[0]=e,this.priorities[0]=n;let o=0;for(;;){const t=2*o+1,e=t+1;if(t\u003e=this.nodeIndices.length)break;let n=t;if(e\u003cthis.nodeIndices.length\u0026\u0026this.priorities[e]\u003cthis.priorities[t]\u0026\u0026(n=e),this.priorities[o]\u003c=this.priorities[n])break;this.swap(o,n),o=n}return t}swap(t,e){[this.nodeIndices[t],this.nodeIndices[e]]=[this.nodeIndices[e],this.nodeIndices[t]],[this.priorities[t],this.priorities[e]]=[this.priorities[e],this.priorities[t]]}},jq=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]],$q=[\"#d53535\",\"#3478c8\",\"#8e44ad\",\"#15956f\"],Yq=class extends Sq{problem;searchBounds;rows;columns;origin;nodes=[];open=new Bq;bestCost=new Map;closed=new Set;baseStateCount;stateSpaceUpperBound;endLayerIndices;targetCell;segmentWidthCache=new Map;closedStateCount=0;output=null;constructor(t){super(),this.problem=t;const e=Math.max(t.traceWidth,t.viaDiameter)/2+t.obstacleIndex.clearance,n=Rq(Math.min(t.start.x,t.end.x)-t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),o=Rq(Math.max(t.start.x,t.end.x)+t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),i=Rq(Math.min(t.start.y,t.end.y)-t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),r=Rq(Math.max(t.start.y,t.end.y)+t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),s=Math.floor((n-t.gridOffset.x)/t.gridSize)*t.gridSize+t.gridOffset.x,a=Math.floor((i-t.gridOffset.y)/t.gridSize)*t.gridSize+t.gridOffset.y;this.origin={x:s,y:a},this.columns=Math.max(2,Math.floor((o-s)/t.gridSize)+1),this.rows=Math.max(2,Math.floor((r-a)/t.gridSize)+1),this.searchBounds={minX:s,minY:a,maxX:s+(this.columns-1)*t.gridSize,maxY:a+(this.rows-1)*t.gridSize};const c=this.rows*this.columns*t.layers.length*(t.maxViaCount+1);this.baseStateCount=c,this.stateSpaceUpperBound=c*(this.rows*this.columns+1),this.targetCell=this.pointToCell(t.end),this.endLayerIndices=new Set(t.endLayers.map(e=\u003et.layers.indexOf(e)).filter(t=\u003et\u003e=0));const l=this.pointToCell(t.start);for(const e of t.startLayers){const n=t.layers.indexOf(e);if(n\u003c0||this.endpointCollides(t.start,n))continue;const o={...l,...t.start,layerIndex:n,viaCount:0,viaPoints:[],g:0,f:this.heuristic(t.start),parentIndex:-1},i=this.nodes.length;this.nodes.push(o),this.open.push(i,o.f),this.bestCost.set(this.toStateIndex(o),0)}0!==this.open.size\u0026\u00260!==this.endLayerIndices.size||(this.failed=!0,this.error=\"No collision-free multilayer route endpoint\"),this.MAX_ITERATIONS=Math.min(15e3,Math.max(2e3,2*c)),this.stats=this.createStats()}getSolverName(){return`LayerAwareGridRouteSolver(${this.problem.gridSize.toFixed(3)}mm)`}_step(){if(0===this.open.size)return this.failed=!0,void(this.error=\"No collision-free multilayer grid route found\");const t=this.open.pop(),e=this.nodes[t],n=this.toStateIndex(e);if(!this.closed.has(n)){if(this.closed.add(n),this.closedStateCount++,e.row===this.targetCell.row\u0026\u0026e.column===this.targetCell.column\u0026\u0026this.endLayerIndices.has(e.layerIndex)\u0026\u0026e.viaCount\u003e=this.problem.minViaCount\u0026\u0026!this.segmentCollides(e,this.problem.end))return this.output=this.reconstructRoute(t),this.solved=!0,void(this.stats=this.createStats());this.expandPlanarMoves(t,e),this.expandViaMoves(t,e),this.stats=this.createStats()}}expandPlanarMoves(t,e){for(const[n,o]of jq){const i=e.row+n,r=e.column+o;if(i\u003c0||i\u003e=this.rows||r\u003c0||r\u003e=this.columns)continue;const s=this.cellToPoint(i,r),a=this.getSafeSegmentWidth(e,s);if(a\u003c=0)continue;const c=this.problem.gridSize*(0!==n\u0026\u00260!==o?Math.SQRT2:1)*Math.max(1,(this.problem.traceWidth/a)**this.problem.neckPenaltyExponent);this.enqueueNode({row:i,column:r,...s,layerIndex:e.layerIndex,viaCount:e.viaCount,viaPoints:e.viaPoints,g:e.g+c,parentIndex:t})}}expandViaMoves(t,e){if(e.viaCount\u003e=this.problem.maxViaCount)return;const n=.5*this.problem.gridSize;if(Nq(e,this.problem.start)\u003cn-1e-9||Nq(e,this.problem.end)\u003cn-1e-9)return;const o=e.parentIndex\u003e=0?this.nodes[e.parentIndex]:void 0;if(!o||o.layerIndex===e.layerIndex||!Tq(o,e))for(let n=0;n\u003cthis.problem.layers.length;n++)n!==e.layerIndex\u0026\u0026(this.problem.obstacleIndex.collidesVia({point:e,layers:this.problem.layers,padDiameter:this.problem.viaDiameter,holeDiameter:this.problem.viaHoleDiameter,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreTraceIndices:this.problem.softTraceIndices,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance,blockSameNetObstacles:!0,sameNetObstacleClearance:0,otherNewViaPoints:e.viaPoints,fixedVias:this.problem.fixedVias})||this.enqueueNode({row:e.row,column:e.column,x:e.x,y:e.y,layerIndex:n,viaCount:e.viaCount+1,viaPoints:[...e.viaPoints,{x:e.x,y:e.y}],g:e.g+this.problem.viaCost,parentIndex:t}))}enqueueNode(t){const e=this.toStateIndex(t);if(this.closed.has(e)||t.g\u003e=(this.bestCost.get(e)??Number.POSITIVE_INFINITY))return;this.bestCost.set(e,t.g);const n=t.g+this.heuristic(t),o=this.nodes.length;this.nodes.push({...t,f:n}),this.open.push(o,n)}endpointCollides(t,e){return this.getSafeSegmentWidth({...t,layerIndex:e,viaCount:0},t)\u003c=0}segmentCollides(t,e){return this.getSafeSegmentWidth(t,e)\u003c=0}getSafeSegmentWidth(t,e){const n=this.problem.layers[t.layerIndex],o=1===this.problem.startLayers.length\u0026\u00260===t.viaCount\u0026\u0026n===this.problem.originalStartLayer\u0026\u0026Nq(this.problem.start,t)\u003c=this.problem.maxStartNeckLength+1e-9\u0026\u0026Nq(this.problem.start,e)\u003c=this.problem.maxStartNeckLength+1e-9,i=1===this.problem.endLayers.length\u0026\u0026n===this.problem.originalEndLayer\u0026\u0026Nq(this.problem.end,t)\u003c=this.problem.maxEndNeckLength+1e-9\u0026\u0026Nq(this.problem.end,e)\u003c=this.problem.maxEndNeckLength+1e-9,r=Math.max(o?this.problem.startNeckWidth:0,i?this.problem.endNeckWidth:0),s=[t.x,t.y,e.x,e.y,t.layerIndex,t.viaCount,r].join(\":\"),a=this.segmentWidthCache.get(s);if(void 0!==a)return a;const c=o=\u003e!this.problem.obstacleIndex.collides({start:t,end:e,layer:n,width:o,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreTraceIndices:this.problem.softTraceIndices,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance});let l=0;if(o||i){const t=.025;let e=Math.ceil((r-1e-9)/t),n=Math.floor((this.problem.traceWidth+1e-9)/t);for(;e\u003c=n;){const o=Math.floor((e+n)/2),i=Number((o*t).toFixed(6));c(i)?(l=i,e=o+1):n=o-1}l\u003cr-1e-9\u0026\u0026c(r)\u0026\u0026(l=r)}else l=c(this.problem.traceWidth)?this.problem.traceWidth:0;return this.segmentWidthCache.set(s,l),l}reconstructRoute(t){const e=[];let n=t;for(;n\u003e=0;){const t=this.nodes[n];e.push(t),n=t.parentIndex}e.reverse();const o=e[e.length-1];Tq(o,this.problem.end)||e.push({...o,...this.problem.end,row:this.targetCell.row,column:this.targetCell.column,parentIndex:-1});const i=[];let r=[e[0]];for(let t=1;t\u003ce.length;t++){const n=e[t-1],o=e[t];o.layerIndex!==n.layerIndex?(i.push(r),r=[o]):r.push(o)}i.push(r);const s=[];for(let t=0;t\u003ci.length;t++){const e=this.simplifySection(i[t]),n=e.slice(0,-1).map((t,n)=\u003ethis.getSafeSegmentWidth(t,e[n+1])),o=e.map((t,o)=\u003e({route_type:\"wire\",x:t.x,y:t.y,layer:this.problem.layers[t.layerIndex],width:0===n.length?Math.min(this.problem.startNeckWidth,this.problem.endNeckWidth):0===o?n[0]:o===e.length-1?n[n.length-1]:Math.min(n[o-1],n[o])}));s.push(...o);const r=i[t+1];if(r){const t=this.problem.layers[e.at(-1).layerIndex],n=this.problem.layers[r[0].layerIndex],o=e.at(-1);s.push({route_type:\"via\",x:o.x,y:o.y,from_layer:t,to_layer:n,via_diameter:this.problem.viaDiameter,via_hole_diameter:this.problem.viaHoleDiameter})}}return{route:s,traceWidth:this.problem.traceWidth,startNeckWidth:this.problem.startNeckWidth,endNeckWidth:this.problem.endNeckWidth,gridSize:this.problem.gridSize,gridOffset:this.problem.gridOffset,viaCount:i.length-1}}simplifySection(t){return t.length\u003c=2?t:this.problem.neckPenaltyExponent\u003e1?this.simplifyStrictSection(t):this.simplifyWidthPreservingSection(t)}simplifyStrictSection(t){const e=t.slice(0,-1).map((e,n)=\u003ethis.getSafeSegmentWidth(e,t[n+1])),n=[0];for(let o=0;o\u003ce.length;o++)n.push(n[o]+this.getWidthPenalizedCost(t[o],t[o+1],e[o]));const o=[t[0]];let i=0;for(;i\u003ct.length-1;){let r=t.length-1;for(;r\u003ei+1\u0026\u0026!this.shortcutPreservesRouteQuality(t,e,n,i,r);)r--;o.push(t[r]),i=r}return this.removeRedundantCollinearPoints(o)}shortcutPreservesRouteQuality(t,e,n,o,i){const r=this.getSafeSegmentWidth(t[o],t[i]);if(r\u003c=0)return!1;let s=Number.POSITIVE_INFINITY;for(let t=o;t\u003ci;t++)s=Math.min(s,e[t]);const a=n[i]-n[o];return r\u003e=s-1e-9\u0026\u0026this.getWidthPenalizedCost(t[o],t[i],r)\u003c=a+1e-9}getWidthPenalizedCost(t,e,n){return Nq(t,e)*Math.max(1,(this.problem.traceWidth/n)**this.problem.neckPenaltyExponent)}simplifyWidthPreservingSection(t){const e=t.slice(0,-1).map((e,n)=\u003ethis.getSafeSegmentWidth(e,t[n+1])),n=[0];for(let o=0;o\u003ce.length;o++)n.push(n[o]+Nq(t[o],t[o+1])*Math.max(1,(this.problem.traceWidth/e[o])**this.problem.neckPenaltyExponent));const o=new Float64Array(t.length).fill(Number.POSITIVE_INFINITY),i=new Float64Array(t.length).fill(Number.POSITIVE_INFINITY),r=new Int32Array(t.length).fill(-1);o[0]=0,i[0]=0;for(let s=1;s\u003ct.length;s++){let a=Number.POSITIVE_INFINITY;for(let c=s-1;c\u003e=0;c--){if(a=Math.min(a,e[c]),!Number.isFinite(o[c]))continue;const l=this.getSafeSegmentWidth(t[c],t[s]);if(l\u003ca-1e-9)continue;const d=Nq(t[c],t[s]);if(d*Math.max(1,(this.problem.traceWidth/l)**this.problem.neckPenaltyExponent)\u003en[s]-n[c]+1e-9)continue;const h=o[c]+d*Math.max(0,this.problem.traceWidth-l),u=i[c]+d;(h\u003co[s]-1e-9||Math.abs(h-o[s])\u003c=1e-9\u0026\u0026u\u003ci[s]-1e-9)\u0026\u0026(o[s]=h,i[s]=u,r[s]=c)}}const s=[];let a=t.length-1;for(;a\u003e=0\u0026\u0026(s.push(t[a]),0!==a);)if(a=r[a],a\u003c0)return t;return s.reverse(),this.removeRedundantCollinearPoints(s)}removeRedundantCollinearPoints(t){return t.filter((t,e,n)=\u003e{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x),s=Math.abs(this.getSafeSegmentWidth(o,t)-this.getSafeSegmentWidth(t,i))\u003c1e-9;return Math.abs(r)\u003e1e-8||!s})}pointToCell(t){return{column:Rq(Math.round((t.x-this.origin.x)/this.problem.gridSize),0,this.columns-1),row:Rq(Math.round((t.y-this.origin.y)/this.problem.gridSize),0,this.rows-1)}}cellToPoint(t,e){return{x:this.origin.x+e*this.problem.gridSize,y:this.origin.y+t*this.problem.gridSize}}toStateIndex(t){const e=((t.viaCount*this.problem.layers.length+t.layerIndex)*this.rows+t.row)*this.columns+t.column;if(1!==t.viaCount||0===t.viaPoints.length||Nq(t,t.viaPoints[0])\u003e=this.problem.viaHoleDiameter+this.problem.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance-1e-9)return e;const n=this.pointToCell(t.viaPoints[0]);return e+(1+n.row*this.columns+n.column)*this.baseStateCount}heuristic(t){return Nq(t,this.problem.end)}createStats(){return{phase:\"layer-aware-grid-search\",gridSize:this.problem.gridSize,traceWidth:this.problem.traceWidth,startNeckWidth:this.problem.startNeckWidth,endNeckWidth:this.problem.endNeckWidth,maxViaCount:this.problem.maxViaCount,minViaCount:this.problem.minViaCount,openStates:this.open.size,closedStates:this.closedStateCount,trackedStates:this.bestCost.size,stateSpaceUpperBound:this.stateSpaceUpperBound}}computeProgress(){return Math.min(.99,this.iterations/this.MAX_ITERATIONS)}getOutput(){return this.output}getConstructorParams(){const{obstacleIndex:t,...e}=this.problem;return[e]}visualize(){const t=this.nodes.filter(t=\u003ethis.closed.has(this.toStateIndex(t))).slice(-2e3).map(t=\u003e({x:t.x,y:t.y,color:`${$q[t.layerIndex%$q.length]}55`})),e=[],n=[],o=this.output?.route??[];for(let t=0;t\u003co.length-1;t++){const i=o[t],r=o[t+1];if(\"wire\"===i?.route_type\u0026\u0026\"wire\"===r?.route_type\u0026\u0026i.layer===r.layer){const t=this.problem.layers.indexOf(i.layer);e.push({points:[i,r],strokeColor:$q[t%$q.length]??\"#333\",strokeWidth:i.width})}\"via\"===i?.route_type\u0026\u0026n.push({center:i,radius:(i.via_diameter??this.problem.viaDiameter)/2,fill:\"#d4a017\"})}return{coordinateSystem:\"cartesian\",title:this.getSolverName(),rects:[{center:{x:(this.searchBounds.minX+this.searchBounds.maxX)/2,y:(this.searchBounds.minY+this.searchBounds.maxY)/2},width:this.searchBounds.maxX-this.searchBounds.minX,height:this.searchBounds.maxY-this.searchBounds.minY,stroke:\"#777\"}],points:[...t,{...this.problem.start,color:\"green\",label:\"reroute start\"},{...this.problem.end,color:\"purple\",label:\"reroute target\"}],lines:e,circles:n,texts:[]}}},Xq=[{direction:1,strength:.7},{direction:-1,strength:.7},{direction:1,strength:1},{direction:-1,strength:1}],Vq=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c=1e-12)return{...e};const s=Rq(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return{x:e.x+o*s,y:e.y+i*s}},Wq=class extends Sq{problem;phase=\"prepare-candidate\";variantCursor=0;relaxationIteration=0;candidatePoints=[];sampledPoints;output=null;constructor(t){super(),this.problem=t,this.sampledPoints=this.sampleRoute(),this.MAX_ITERATIONS=100,this.stats=this.createStats()}getSolverName(){return\"ElasticTracePushSolver\"}_step(){switch(this.phase){case\"prepare-candidate\":if(this.variantCursor\u003e=Xq.length)return this.failed=!0,void(this.error=\"No collision-free elastic displacement found\");this.candidatePoints=this.sampledPoints.map(t=\u003e({...t})),this.relaxationIteration=0,this.phase=\"relax-candidate\";break;case\"relax-candidate\":this.relaxCandidate(),this.relaxationIteration++,this.relaxationIteration\u003e=10\u0026\u0026(this.phase=\"validate-candidate\");break;case\"validate-candidate\":{const t=this.simplifyCandidate(this.candidatePoints);this.pathCollides(t)?(this.variantCursor++,this.phase=\"prepare-candidate\"):(this.output={points:t,traceWidth:this.problem.traceWidth},this.phase=\"complete\");break}case\"complete\":this.solved=!0}this.stats=this.createStats()}sampleRoute(){const t=[],e=Rq(2*this.problem.traceWidth,.2,.45),n=this.problem.trace.route;for(let o=this.problem.range.startIndex;o\u003cthis.problem.range.endIndex;o++){const i=n[o],r=n[o+1];if(\"wire\"!==i?.route_type||\"wire\"!==r?.route_type||i.layer!==r.layer)continue;0===t.length\u0026\u0026t.push({x:i.x,y:i.y});const s=Nq(i,r),a=Math.max(1,Math.ceil(s/e));for(let e=1;e\u003c=a;e++){const n=e/a;t.push({x:i.x+(r.x-i.x)*n,y:i.y+(r.y-i.y)*n})}}return t}relaxCandidate(){const t=Xq[this.variantCursor],e=this.candidatePoints.map(t=\u003e({...t})),n=new Uint8Array(this.candidatePoints.length);for(let o=1;o\u003cthis.candidatePoints.length-1;o++){const i=this.candidatePoints[o],r=this.findNearestCorridorSegment(i);if(!r)continue;const s=Nq(r.segment.start,r.segment.end);if(s\u003c=1e-9)continue;const a=r.segment.width/2+this.problem.traceWidth/2+this.problem.obstacleIndex.clearance+.025;if(r.distance\u003ea+.35)continue;const c={x:(r.segment.start.y-r.segment.end.y)/s*t.direction,y:(r.segment.end.x-r.segment.start.x)/s*t.direction},l=a-((i.x-r.closest.x)*c.x+(i.y-r.closest.y)*c.y);if(l\u003c=0)continue;const d=Math.min(.35,l*t.strength);e[o]={x:i.x+c.x*d,y:i.y+c.y*d},n[o]=1}for(let t=1;t\u003ce.length-1;t++){if(!n[t])continue;const o=e[t-1],i=e[t],r=e[t+1];e[t]={x:.85*i.x+(o.x+r.x)/2*.15,y:.85*i.y+(o.y+r.y)/2*.15}}this.candidatePoints=e}findNearestCorridorSegment(t){let e;for(const n of this.problem.corridor){if(n.layer!==this.problem.layer)continue;const o=Vq(t,n.start,n.end),i=Nq(t,o);(!e||i\u003ce.distance)\u0026\u0026(e={segment:n,closest:o,distance:i})}return e}simplifyCandidate(t){if(t.length\u003c=2)return t;const e=[t[0]];let n=0;for(;n\u003ct.length-1;){let o=t.length-1;for(;o\u003en+1\u0026\u0026this.segmentCollides(t[n],t[o]);)o--;e.push(t[o]),n=o}return e.filter((t,e,n)=\u003e0===e||!Tq(t,n[e-1]))}pathCollides(t){if(t.length\u003c2)return!0;for(let e=0;e\u003ct.length-1;e++)if(this.segmentCollides(t[e],t[e+1]))return!0;return!1}segmentCollides(t,e){return this.problem.obstacleIndex.collides({start:t,end:e,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:-1})}createStats(){const t=Xq[this.variantCursor];return{phase:this.phase,direction:t?.direction,strength:t?.strength,variantCursor:this.variantCursor,relaxationIteration:this.relaxationIteration,sampledPointCount:this.sampledPoints.length}}computeProgress(){return Math.min(.99,(this.variantCursor+this.relaxationIteration/12)/Xq.length)}getOutput(){return this.output}getConstructorParams(){return[this.problem]}visualize(){return{coordinateSystem:\"cartesian\",title:`Elastic trace push: ${this.phase}`,lines:[...this.problem.corridor.map(t=\u003e({points:[t.start,t.end],strokeColor:\"rgba(255, 128, 0, 0.6)\",strokeWidth:t.width})),...this.candidatePoints.length\u003e1?[{points:this.candidatePoints,strokeColor:\"#1769d2\",strokeWidth:this.problem.traceWidth}]:[]],points:[],rects:[],circles:[],texts:[]}}},Hq=(t,e)=\u003e{const n=Math.abs(e.x-t.x),o=Math.abs(e.y-t.y);return n\u003c=Mq||o\u003c=Mq||Math.abs(n-o)\u003c=Mq},Gq=t=\u003e{let e=0;for(let n=0;n\u003ct.length-1;n++)Hq(t[n],t[n+1])||e++;return e},Uq=t=\u003e{let e=0;for(let n=0;n\u003ct.length-1;n++)e+=Nq(t[n],t[n+1]);return e},Zq=t=\u003et.filter((e,n)=\u003e0===n||!Tq(e,t[n-1])),qq=(t,e)=\u003e{const n=e.x-t.x,o=e.y-t.y,i=Math.abs(n),r=Math.abs(o),s=Math.sign(n),a=Math.sign(o),c=[];Hq(t,e)\u0026\u0026c.push([t,e]),c.push([t,{x:e.x,y:t.y},e],[t,{x:t.x,y:e.y},e]),i\u003e=r?c.push([t,{x:e.x-s*r,y:t.y},e],[t,{x:t.x+s*r,y:e.y},e]):c.push([t,{x:t.x,y:e.y-a*i},e],[t,{x:e.x,y:t.y+a*i},e]);const l=new Map;for(const t of c){const e=Zq(t);if(e.length\u003c2||e.some((t,n)=\u003en\u003ce.length-1\u0026\u0026!Hq(t,e[n+1])))continue;const n=e.map(t=\u003e`${t.x.toFixed(6)},${t.y.toFixed(6)}`).join(\";\");l.set(n,e)}return[...l.values()].sort((t,e)=\u003eUq(t)-Uq(e)||t.length-e.length)},Jq=class{nodeIndices=[];priorities=[];get size(){return this.nodeIndices.length}push(t,e){let n=this.nodeIndices.length;for(this.nodeIndices.push(t),this.priorities.push(e);n\u003e0;){const t=n-1\u003e\u003e1;if(this.priorities[t]\u003c=e)break;this.swap(n,t),n=t}}pop(){const t=this.nodeIndices[0],e=this.nodeIndices.pop(),n=this.priorities.pop();if(0===this.nodeIndices.length)return t;this.nodeIndices[0]=e,this.priorities[0]=n;let o=0;for(;;){const t=2*o+1,e=t+1;if(t\u003e=this.nodeIndices.length)break;let n=t;if(e\u003cthis.nodeIndices.length\u0026\u0026this.priorities[e]\u003cthis.priorities[t]\u0026\u0026(n=e),this.priorities[o]\u003c=this.priorities[n])break;this.swap(o,n),o=n}return t}swap(t,e){[this.nodeIndices[t],this.nodeIndices[e]]=[this.nodeIndices[e],this.nodeIndices[t]],[this.priorities[t],this.priorities[e]]=[this.priorities[e],this.priorities[t]]}},Kq=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]],Qq=class extends Sq{problem;searchBounds;rows;columns;origin;nodes=[];open=new Jq;bestCost;closed;closedCellCount=0;targetCell;output=null;constructor(t){super(),this.problem=t;const e=t.traceWidth/2+t.obstacleIndex.clearance,n=Rq(Math.min(t.start.x,t.end.x)-t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),o=Rq(Math.max(t.start.x,t.end.x)+t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),i=Rq(Math.min(t.start.y,t.end.y)-t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),r=Rq(Math.max(t.start.y,t.end.y)+t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),s=Math.floor((n-t.gridOffset.x)/t.gridSize)*t.gridSize+t.gridOffset.x,a=Math.floor((i-t.gridOffset.y)/t.gridSize)*t.gridSize+t.gridOffset.y;if(this.origin={x:s,y:a},this.columns=Math.max(2,Math.floor((o-s)/t.gridSize)+1),this.rows=Math.max(2,Math.floor((r-a)/t.gridSize)+1),this.searchBounds={minX:s,minY:a,maxX:s+(this.columns-1)*t.gridSize,maxY:a+(this.rows-1)*t.gridSize},this.bestCost=new Float64Array(this.rows*this.columns).fill(Number.POSITIVE_INFINITY),this.closed=new Uint8Array(this.rows*this.columns),this.endpointCollides(t.start)||this.endpointCollides(t.end))return this.failed=!0,this.error=\"Grid-route endpoint violates obstacle clearance\",this.targetCell={row:0,column:0},this.MAX_ITERATIONS=1,void(this.stats=this.createStats());const c=this.pointToCell(t.start);this.targetCell=this.pointToCell(t.end);const l={...c,x:t.start.x,y:t.start.y,g:0,f:this.heuristic(t.start),parentIndex:-1};this.nodes.push(l),this.open.push(0,l.f),this.bestCost[this.toFlatIndex(c.row,c.column)]=0,this.MAX_ITERATIONS=Math.min(5e3,Math.max(1e3,this.rows*this.columns*2)),this.stats=this.createStats()}endpointCollides(t){return this.problem.obstacleIndex.collides({start:t,end:t,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance})}getSolverName(){return`ObstacleAwareGridRouteSolver(${this.problem.gridSize.toFixed(3)}mm)`}_step(){if(0===this.open.size)return this.failed=!0,void(this.error=\"No collision-free grid route found\");const t=this.open.pop(),e=this.nodes[t],n=this.toFlatIndex(e.row,e.column);if(!this.closed[n]){if(this.closed[n]=1,this.closedCellCount++,e.row===this.targetCell.row\u0026\u0026e.column===this.targetCell.column\u0026\u0026null!==this.getAllowedConnector(e,this.problem.end))return this.output={points:this.reconstructPath(t),traceWidth:this.problem.traceWidth,gridSize:this.problem.gridSize,gridOffset:this.problem.gridOffset},this.solved=!0,void(this.stats=this.createStats());for(const[n,o]of Kq){const i=e.row+n,r=e.column+o;if(i\u003c0||i\u003e=this.rows||r\u003c0||r\u003e=this.columns)continue;const s=this.toFlatIndex(i,r);if(this.closed[s])continue;const a=this.cellToPoint(i,r),c=this.getAllowedConnector(e,a);if(null===c)continue;const l=-1===e.parentIndex\u0026\u0026this.problem.requireOctilinear?Uq(c):this.problem.gridSize*(0!==n\u0026\u00260!==o?Math.SQRT2:1),d=e.g+l;if(d\u003e=this.bestCost[s])continue;this.bestCost[s]=d;const h=d+this.heuristic(a),u=this.nodes.length;this.nodes.push({row:i,column:r,...a,g:d,f:h,parentIndex:t}),this.open.push(u,h)}this.stats=this.createStats()}}segmentCollides(t,e){return this.problem.obstacleIndex.collides({start:t,end:e,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance})}getAllowedConnector(t,e){return this.problem.requireOctilinear\u0026\u0026(\"parentIndex\"in t\u0026\u0026-1===t.parentIndex||Tq(e,this.problem.end))?qq(t,e).find(t=\u003et.slice(0,-1).every((e,n)=\u003e!this.segmentCollides(e,t[n+1])))??null:this.segmentCollides(t,e)?null:[t,e]}pointToCell(t){return{column:Rq(Math.round((t.x-this.origin.x)/this.problem.gridSize),0,this.columns-1),row:Rq(Math.round((t.y-this.origin.y)/this.problem.gridSize),0,this.rows-1)}}cellToPoint(t,e){return{x:this.origin.x+e*this.problem.gridSize,y:this.origin.y+t*this.problem.gridSize}}toFlatIndex(t,e){return t*this.columns+e}heuristic(t){return Math.hypot(this.problem.end.x-t.x,this.problem.end.y-t.y)}reconstructPath(t){const e=[];let n=t;for(;n\u003e=0;){const t=this.nodes[n];e.push({x:t.x,y:t.y}),n=t.parentIndex}if(e.reverse(),Tq(e[0],this.problem.start)||e.unshift({...this.problem.start}),Tq(e[e.length-1],this.problem.end)||e.push({...this.problem.end}),this.problem.requireOctilinear){const t=[e[0]];for(let n=0;n\u003ce.length-1;n++){const o=e[n],i=e[n+1],r=0===n||n===e.length-2?this.getAllowedConnector(0===n?{...o,parentIndex:-1}:o,i):[o,i];if(!r)return e;t.push(...r.slice(1))}return t.filter((t,e,n)=\u003e{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x);return Math.abs(r)\u003e1e-8||!Hq(o,i)})}const o=[e[0]];let i=0;for(;i\u003ce.length-1;){let t=e.length-1;for(;t\u003ei+1\u0026\u0026this.segmentCollides(e[i],e[t]);)t--;o.push(e[t]),i=t}return o.filter((t,e,n)=\u003e{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x);return Math.abs(r)\u003e1e-8})}createStats(){return{phase:\"obstacle-aware-grid-search\",gridSize:this.problem.gridSize,traceWidth:this.problem.traceWidth,gridOffset:this.problem.gridOffset,openCells:this.open.size,closedCells:this.closedCellCount,gridCells:this.rows*this.columns}}computeProgress(){return Math.min(.99,this.iterations/this.MAX_ITERATIONS)}getOutput(){return this.output}getConstructorParams(){const{obstacleIndex:t,...e}=this.problem;return[e]}visualize(){const t=this.nodes.filter(t=\u003ethis.closed[this.toFlatIndex(t.row,t.column)]).slice(-2e3).map(t=\u003e({x:t.x,y:t.y,color:\"rgba(0,90,255,0.22)\"})),e=this.output?.points??[];return{coordinateSystem:\"cartesian\",title:this.getSolverName(),rects:[{center:{x:(this.searchBounds.minX+this.searchBounds.maxX)/2,y:(this.searchBounds.minY+this.searchBounds.maxY)/2},width:this.searchBounds.maxX-this.searchBounds.minX,height:this.searchBounds.maxY-this.searchBounds.minY,stroke:\"#777\"}],points:[...t,{...this.problem.start,color:\"green\",label:\"reroute start\"},{...this.problem.end,color:\"purple\",label:\"reroute target\"}],lines:e.length\u003e1?[{points:e,strokeColor:\"#00a050\",strokeWidth:this.problem.traceWidth}]:[],circles:[],texts:[]}}},tJ=class{items;clearance;boardEdgeClearance;boardLayers;minViaHoleEdgeToViaHoleEdgeClearance;defaultViaHoleDiameter;bounds;maxIndexedViaHoleDiameter;index;connectionNameSets;copperObjectIds;connectionNameResolver;connectedPads;dynamicTraceIndex;constructor(t,e,n,o=[],i=new Pq(t,e)){var r;this.bounds=t.bounds,this.boardLayers=(r=t.layerCount,[\"top\",...Array.from({length:Math.max(0,r-2)},(t,e)=\u003e`inner${e+1}`),...r\u003e1?[\"bottom\"]:[]]),this.dynamicTraceIndex=n,this.clearance=Math.max(t.defaultObstacleMargin??0,t.minTraceToPadEdgeClearance??0,.1),this.boardEdgeClearance=t.minBoardEdgeClearance??this.clearance,this.minViaHoleEdgeToViaHoleEdgeClearance=Math.max(t.minViaHoleEdgeToViaHoleEdgeClearance??0,.1),this.defaultViaHoleDiameter=t.min_via_hole_diameter??t.minViaHoleDiameter??.3,this.items=[...t.obstacles.flatMap((t,e)=\u003efunction(t,e=.6){const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.max(1,Math.ceil(t.width/e)),i=Math.max(1,Math.ceil(t.height/e)),r=t.width/o,s=t.height/i,a=[];for(let e=0;e\u003ci;e++)for(let i=0;i\u003co;i++){const o={x:t.center.x-t.width/2+(i+.5)*r,y:t.center.y-t.height/2+(e+.5)*s},c=r/2,l=s/2,d=[{x:o.x-c,y:o.y-l},{x:o.x+c,y:o.y-l},{x:o.x+c,y:o.y+l},{x:o.x-c,y:o.y+l}].map(e=\u003eFq(e,t.center,n));a.push({minX:Math.min(...d.map(t=\u003et.x)),minY:Math.min(...d.map(t=\u003et.y)),maxX:Math.max(...d.map(t=\u003et.x)),maxY:Math.max(...d.map(t=\u003et.y)),layers:t.layers,kind:\"obstacle\",obstacleKind:t.connectedTo[0]?.startsWith(\"pcb_via_\")?\"via\":t.connectedTo[0]?.startsWith(\"pcb_smtpad_\")||t.connectedTo[0]?.startsWith(\"pcb_plated_hole_\")?\"pad\":\"other\",connectionNames:t.connectedTo,exactShape:{type:\"polygon\",points:d}})}return a}(t).map(t=\u003e({...t,copperObjectId:`obstacle:${e}`}))),...this.createTraceItems(t.fixedTraces??[],!0),...this.createTraceItems(e),...o],this.maxIndexedViaHoleDiameter=this.items.reduce((t,e)=\u003e\"via\"===e.kind?Math.max(t,e.viaHoleDiameter??this.defaultViaHoleDiameter):t,this.defaultViaHoleDiameter),this.connectionNameResolver=i,this.connectionNameSets=this.items.map(t=\u003enew Set(i.canonicalize(t.connectionNames))),this.copperObjectIds=this.items.map((t,e)=\u003et.copperObjectId??`indexed-item:${e}`),this.connectedPads=t.obstacles.flatMap(t=\u003et.connectedTo.some(t=\u003et.startsWith(\"pcb_smtpad_\")||t.startsWith(\"pcb_plated_hole_\"))?[{obstacle:t,canonicalConnectionNames:new Set(i.canonicalize(t.connectedTo))}]:[]),this.index=this.items.length\u003e0?new Bt(this.items.length):null;for(const t of this.items)this.index.add(t.minX,t.minY,t.maxX,t.maxY);this.index?.finish()}createTraceItems(t,e=!1){const n=[];for(let o=0;o\u003ct.length;o++){const i=t[o],r=e?void 0:o,s=`${e?\"fixed-trace\":\"trace\"}:${o}`,a=!e\u0026\u0026o===this.dynamicTraceIndex,c=[i.connection_name,i.source_trace_id,i.rootConnectionName,...i.mergedConnectionNames??[],...i.connectsTo??[]].filter(t=\u003eBoolean(t));for(let t=0;t\u003ci.route.length;t++){const e=i.route[t];if(\"via\"===e.route_type){const o=e.via_diameter??.6;n.push({minX:e.x-o/2,minY:e.y-o/2,maxX:e.x+o/2,maxY:e.y+o/2,layers:this.boardLayers,kind:\"via\",connectionNames:c,copperObjectId:s,traceIndex:r,routeStartIndex:t,routeEndIndex:t,viaHoleDiameter:e.via_hole_diameter??this.defaultViaHoleDiameter,exactShape:{type:\"circle\",center:{x:e.x,y:e.y},radius:o/2}});continue}if(a)continue;const o=i.route[t+1];\"wire\"===e.route_type\u0026\u0026\"wire\"===o?.route_type\u0026\u0026e.layer===o.layer\u0026\u0026n.push(...zq({start:e,end:o,width:e.width,base:{layers:[e.layer],kind:\"trace\",connectionNames:c,copperObjectId:s,traceIndex:r,routeStartIndex:t,routeEndIndex:t+1}}))}}return n}collides(t){if(this.isOutsideBounds(t))return!0;const{radius:e,candidates:n,canonicalConnectionNames:o}=this.getCollisionCandidates(t);for(const i of n)if(this.itemCollides(i,t,e,o))return!0;return!1}findCollisions(t){const{radius:e,candidates:n,canonicalConnectionNames:o}=this.getCollisionCandidates(t),i=[];for(const r of n)this.itemCollides(r,t,e,o)\u0026\u0026i.push(this.items[r]);return i}getSameNetCopperContactIds(t){const e=t.width/2,n=this.index?.search(Math.min(t.start.x,t.end.x)-e,Math.min(t.start.y,t.end.y)-e,Math.max(t.start.x,t.end.x)+e,Math.max(t.start.y,t.end.y)+e)??[],o=new Set(this.connectionNameResolver.canonicalize(t.connectionNames)),i=new Set;for(const r of n){const n=this.items[r];n.layers.includes(t.layer)\u0026\u0026(n.traceIndex===t.ignoreTraceIndex||t.ignoreTraceIndices?.includes(n.traceIndex??-1)||[...this.connectionNameSets[r]].some(t=\u003eo.has(t))\u0026\u0026this.itemCopperTouches(n,t,e)\u0026\u0026i.add(this.copperObjectIds[r]))}return i}getConnectedPadWidthLimit(t){if(Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y)\u003c=1e-5)return null;const e=this.getConnectedPadWidthLimitAtPoint(t,t.start),n=this.getConnectedPadWidthLimitAtPoint(t,t.end);return null===e?n:null===n?e:Math.min(e,n)}getConnectedPadWidthLimitAtPoint(t,e){const n=this.getConnectedPadsAtPoint(t,e);return 0===n.length?null:Math.max(...n.map(({obstacle:e})=\u003ethis.getPadWidthNormalToQuery(e,t)))}getConnectedPadEndpointWidthLimitAtPoint(t,e){const n=this.getConnectedPadsAtPoint(t,e);return 0===n.length?null:Math.max(...n.map(({obstacle:t})=\u003e{const n=this.getObstacleLocalPoint(e,t);return Math.max(0,2*Math.min(t.width/2-Math.abs(n.x),t.height/2-Math.abs(n.y)))}))}getConnectedPadBoundaryPoint(t,e){const n=\"start\"===e?t.start:t.end,o=\"start\"===e?t.end:t.start,i=this.getConnectedPadsAtPoint(t,n).sort((e,n)=\u003ethis.getPadWidthNormalToQuery(n.obstacle,t)-this.getPadWidthNormalToQuery(e.obstacle,t))[0];return!i||this.pointIsInsideObstacle(o,i.obstacle)?null:this.getObstacleBoundaryPoint(n,o,i.obstacle)}getConnectedPadsAtPoint(t,e){const n=new Set(this.connectionNameResolver.canonicalize(t.connectionNames));return this.connectedPads.filter(({obstacle:o,canonicalConnectionNames:i})=\u003eo.layers.includes(t.layer)\u0026\u0026[...i].some(t=\u003en.has(t))\u0026\u0026this.pointIsInsideObstacle(e,o))}pointIsInsideObstacle(t,e){const{x:n,y:o}=this.getObstacleLocalPoint(t,e);return Math.abs(n)\u003c=e.width/2+1e-9\u0026\u0026Math.abs(o)\u003c=e.height/2+1e-9}getObstacleLocalPoint(t,e){const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=Math.cos(n),i=Math.sin(n),r=t.x-e.center.x,s=t.y-e.center.y;return{x:r*o-s*i,y:r*i+s*o}}getPadWidthNormalToQuery(t,e){const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.hypot(n,o);if(i\u003c=1e-9)return Math.min(t.width,t.height);const r=-o/i,s=n/i,a=-(t.ccwRotationDegrees??0)*Math.PI/180,c=Math.cos(a),l=Math.sin(a),d=r*c-s*l,h=r*l+s*c;return Math.abs(d)*t.width+Math.abs(h)*t.height}getObstacleBoundaryPoint(t,e,n){const o=-(n.ccwRotationDegrees??0)*Math.PI/180,i=Math.cos(o),r=Math.sin(o),s=t=\u003e{const e=t.x-n.center.x,o=t.y-n.center.y;return{x:e*i-o*r,y:e*r+o*i}},a=s(t),c=s(e),l={x:c.x-a.x,y:c.y-a.y},d=[];if(Math.abs(l.x)\u003e1e-12){const t=l.x\u003e0?n.width/2:-n.width/2;d.push((t-a.x)/l.x)}if(Math.abs(l.y)\u003e1e-12){const t=l.y\u003e0?n.height/2:-n.height/2;d.push((t-a.y)/l.y)}const h=Math.min(...d.filter(t=\u003et\u003e=0\u0026\u0026t\u003c=1));return Number.isFinite(h)?{x:t.x+(e.x-t.x)*h,y:t.y+(e.y-t.y)*h}:null}getConnectedLayersAtPoint(t,e){const n=new Set(this.connectionNameResolver.canonicalize(e)),o=new Set,i=this.index?.search(t.x,t.y,t.x,t.y)??[];for(const e of i){const i=this.items[e];if(\"obstacle\"!==i.kind)continue;if(![...this.connectionNameSets[e]].some(t=\u003en.has(t)))continue;if(\"polygon\"===i.exactShape?.type?Lq(t,t,i.exactShape.points)\u003c=1e-9:\"circle\"===i.exactShape?.type?Math.hypot(i.exactShape.center.x-t.x,i.exactShape.center.y-t.y)\u003c=i.exactShape.radius+1e-9:t.x\u003e=i.minX-1e-9\u0026\u0026t.x\u003c=i.maxX+1e-9\u0026\u0026t.y\u003e=i.minY-1e-9\u0026\u0026t.y\u003c=i.maxY+1e-9)for(const t of i.layers)o.add(t)}return[...o]}collidesVia(t){return this.getViaViolationSignatures(t).size\u003e0}getViaViolationSignatures(t){const e=new Set;for(const n of t.layers){const o={start:t.point,end:t.point,layer:n,width:t.padDiameter,connectionNames:t.connectionNames,ignoreTraceIndex:t.ignoreTraceIndex,ignoreTraceIndices:t.ignoreTraceIndices,ignoreRouteRange:t.ignoreRouteRange,obstacleClearance:t.obstacleClearance,blockSameNetObstacles:t.blockSameNetObstacles,sameNetObstacleClearance:t.sameNetObstacleClearance};this.isOutsideBounds(o)\u0026\u0026e.add(`board-edge:${n}`);const{radius:i,candidates:r,canonicalConnectionNames:s}=this.getCollisionCandidates(o);for(const t of r)this.itemCollides(t,o,i,s)\u0026\u0026e.add(`copper:${n}:${this.getViolationObjectId(t)}`)}const n=t.holeDiameter+this.minViaHoleEdgeToViaHoleEdgeClearance;for(const o of t.otherNewViaPoints??[])Math.hypot(o.x-t.point.x,o.y-t.point.y)\u003cn-1e-9\u0026\u0026e.add(`new-via-drill:${o.x},${o.y}:${t.holeDiameter}`);const o=t.fixedVias??[];for(let n=0;n\u003co.length;n++){const i=o[n],r=t.holeDiameter/2+i.holeDiameter/2+this.minViaHoleEdgeToViaHoleEdgeClearance;Math.hypot(i.point.x-t.point.x,i.point.y-t.point.y)\u003cr-1e-9\u0026\u0026e.add(`fixed-via-drill:${n}:${i.point.x},${i.point.y}:${i.holeDiameter}`)}const i=t.holeDiameter/2+this.maxIndexedViaHoleDiameter/2+this.minViaHoleEdgeToViaHoleEdgeClearance,r=this.index?.search(t.point.x-i,t.point.y-i,t.point.x+i,t.point.y+i)??[],s=new Set;for(const n of r){const o=this.items[n];if(\"via\"!==o.kind||\"circle\"!==o.exactShape?.type)continue;if(o.traceIndex===t.ignoreTraceIndex\u0026\u0026t.ignoreRouteRange\u0026\u0026(o.routeEndIndex??-1)\u003e=t.ignoreRouteRange.start\u0026\u0026(o.routeStartIndex??Number.POSITIVE_INFINITY)\u003c=t.ignoreRouteRange.end)continue;if(t.ignoreTraceIndices?.includes(o.traceIndex??-1))continue;const i=`${this.copperObjectIds[n]??\"unknown\"}:${o.routeStartIndex??-1}`;if(s.has(i))continue;s.add(i);const r=o.viaHoleDiameter??this.defaultViaHoleDiameter,a=t.holeDiameter/2+r/2+this.minViaHoleEdgeToViaHoleEdgeClearance;Math.hypot(o.exactShape.center.x-t.point.x,o.exactShape.center.y-t.point.y)\u003ca-1e-9\u0026\u0026e.add(`indexed-via-drill:${this.getViolationObjectId(n)}`)}return e}getViolationObjectId(t){const e=this.items[t],n=this.copperObjectIds[t],o=`${e.routeStartIndex??\"\"}-${e.routeEndIndex??\"\"}`;if(\"obstacle\"===e.kind)return n;if(\"segment\"===e.exactShape?.type){const{start:t,end:i,width:r}=e.exactShape;return`${n}:${e.kind}:${o}:${t.x},${t.y}:${i.x},${i.y}:${r}`}if(\"circle\"===e.exactShape?.type){const{center:t,radius:i}=e.exactShape;return`${n}:${e.kind}:${o}:${t.x},${t.y}:${i}`}return\"polygon\"===e.exactShape?.type?`${n}:${e.kind}:${o}:${e.exactShape.points.map(t=\u003e`${t.x},${t.y}`).join(\";\")}`:`${n}:${e.kind}:${o}:${e.minX},${e.minY},${e.maxX},${e.maxY}`}getCollisionCandidates(t){const e=Math.max(this.clearance,t.obstacleClearance??this.clearance,t.sameNetObstacleClearance??0),n=t.width/2+e,o={minX:Math.min(t.start.x,t.end.x)-n,minY:Math.min(t.start.y,t.end.y)-n,maxX:Math.max(t.start.x,t.end.x)+n,maxY:Math.max(t.start.y,t.end.y)+n};return{radius:n,candidates:this.index?.search(o.minX,o.minY,o.maxX,o.maxY)??[],canonicalConnectionNames:this.connectionNameResolver.canonicalize(t.connectionNames)}}itemCollides(t,e,n,o){const i=this.items[t];if(!i.layers.includes(e.layer))return!1;const r=this.connectionNameSets[t],s=o.some(t=\u003er.has(t));if(s\u0026\u0026(!e.blockSameNetObstacles||\"obstacle\"!==i.kind||\"via\"===i.obstacleKind))return!1;if(\"trace\"===i.kind\u0026\u0026e.ignoreTraceIndices?.includes(i.traceIndex??-1))return!1;if(\"trace\"===i.kind\u0026\u0026i.traceIndex===e.ignoreTraceIndex\u0026\u0026e.ignoreRouteRange\u0026\u0026(i.routeEndIndex??-1)\u003e=e.ignoreRouteRange.start\u0026\u0026(i.routeStartIndex??Number.POSITIVE_INFINITY)\u003c=e.ignoreRouteRange.end)return!1;const a=\"obstacle\"===i.kind\u0026\u0026\"pad\"===i.obstacleKind?s\u0026\u0026e.blockSameNetObstacles?e.sameNetObstacleClearance??e.obstacleClearance??this.clearance:e.obstacleClearance??this.clearance:this.clearance,c=e.width/2+a;return\"segment\"===i.exactShape?.type?Oq(e.start,e.end,i.exactShape.start,i.exactShape.end)\u003c=c+i.exactShape.width/2+1e-9:\"polygon\"===i.exactShape?.type?Lq(e.start,e.end,i.exactShape.points)\u003c=c+1e-9:\"circle\"===i.exactShape?.type?wq(i.exactShape.center,e.start,e.end)\u003c=c+i.exactShape.radius+1e-9:Dq(e.start,e.end,{minX:i.minX-c,minY:i.minY-c,maxX:i.maxX+c,maxY:i.maxY+c})}itemCopperTouches(t,e,n){return\"segment\"===t.exactShape?.type?Oq(e.start,e.end,t.exactShape.start,t.exactShape.end)\u003c=n+t.exactShape.width/2+1e-9:\"polygon\"===t.exactShape?.type?Lq(e.start,e.end,t.exactShape.points)\u003c=n+1e-9:\"circle\"===t.exactShape?.type?wq(t.exactShape.center,e.start,e.end)\u003c=n+t.exactShape.radius+1e-9:Dq(e.start,e.end,{minX:t.minX-n,minY:t.minY-n,maxX:t.maxX+n,maxY:t.maxY+n})}isOutsideBounds(t){const e=t.width/2+this.boardEdgeClearance;return Math.min(t.start.x,t.end.x)-e\u003cthis.bounds.minX||Math.max(t.start.x,t.end.x)+e\u003ethis.bounds.maxX||Math.min(t.start.y,t.end.y)-e\u003cthis.bounds.minY||Math.max(t.start.y,t.end.y)+e\u003ethis.bounds.maxY}},eJ=[{x:0,y:0},{x:.5,y:0},{x:0,y:.5},{x:.5,y:.5}],nJ=t=\u003e\"wire\"===t?.route_type,oJ=class extends Sq{inputProblem;traces;corridor;phase=\"scan-corridor\";corridorCursor=0;blockerCursor=0;offsetCursor=0;resolutionCursor=0;attemptedGridCount=0;blockerIndex;connectionNameResolver;connectionByTraceId=new Map;mutableTraceIndices;blockersByTrace=new Map;blockers=[];currentBlocker=null;currentRange=null;currentTraceWidth=0;gridResolutions=[];currentObstacleIndex=null;output=null;constructor(t,e=new Pq(t.simpleRouteJson,t.traces)){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.corridor=structuredClone(t.corridor),this.mutableTraceIndices=t.mutableTraceIndices?new Set(t.mutableTraceIndices):null,this.connectionNameResolver=e,this.blockerIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,t.powerTraceIndex,[],this.connectionNameResolver),this.activeSubSolver=null,this.MAX_ITERATIONS=25e3,this.stats=this.createStats()}getSolverName(){return\"LocalTraceInflationSolver\"}_step(){if(this.activeSubSolver)return this.stepActiveSubSolver(),void(this.stats=this.createStats());switch(this.phase){case\"scan-corridor\":this.scanNextCorridorSegment();break;case\"select-blocker\":this.selectNextBlocker();break;case\"try-elastic-push\":break;case\"try-grid-candidate\":this.startNextGridCandidate();break;case\"complete\":this.output?this.solved=!0:(this.failed=!0,this.error=\"No locally reroutable trace blocks the power corridor\")}this.stats=this.createStats()}scanNextCorridorSegment(){const t=this.corridor[this.corridorCursor];if(!t)return this.blockers=[...this.blockersByTrace.values()].sort((t,e)=\u003et.traceIndex-e.traceIndex),void(this.phase=\"select-blocker\");const e=this.traces[this.inputProblem.powerTraceIndex],n=this.blockerIndex.findCollisions({start:t.start,end:t.end,layer:t.layer,width:t.width,connectionNames:e?this.getTraceConnectionNames(e):[]});for(const t of n)this.recordBlockingTrace(t);this.corridorCursor++}recordBlockingTrace(t){if(\"trace\"!==t.kind||void 0===t.traceIndex||void 0===t.routeStartIndex||void 0===t.routeEndIndex||t.traceIndex===this.inputProblem.powerTraceIndex||null!==this.mutableTraceIndices\u0026\u0026!this.mutableTraceIndices.has(t.traceIndex))return;const e=this.traces[t.traceIndex];if(!e)return;const n=this.findConnectionForTrace(e);if((n?this.resolveNominalTraceWidth(n):this.getTraceNominalWidth(e))\u003e=(this.inputProblem.pushOnlyNominalWidthsBelow??this.inputProblem.nominalPowerWidth)-Mq)return;const o=this.blockersByTrace.get(t.traceIndex);if(o)return o.firstRouteIndex=Math.min(o.firstRouteIndex,t.routeStartIndex),void(o.lastRouteIndex=Math.max(o.lastRouteIndex,t.routeEndIndex));this.blockersByTrace.set(t.traceIndex,{traceIndex:t.traceIndex,firstRouteIndex:t.routeStartIndex,lastRouteIndex:t.routeEndIndex})}selectNextBlocker(){if(this.currentBlocker=this.blockers[this.blockerCursor]??null,!this.currentBlocker)return void(this.phase=\"complete\");const t=this.findStableAnchorRange(this.currentBlocker);if(!t)return void this.blockerCursor++;const e=this.traces[this.currentBlocker.traceIndex];this.currentRange=t,this.currentTraceWidth=this.getRangeWidth(e,t),this.gridResolutions=this.getGridResolutions(this.currentTraceWidth),this.resolutionCursor=0,this.offsetCursor=0,this.currentObstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,this.currentBlocker.traceIndex,this.createInflatedCorridorItems(),this.connectionNameResolver),this.activeSubSolver=new Wq({trace:e,range:t,layer:e.route[t.startIndex].layer,traceWidth:this.currentTraceWidth,corridor:this.corridor,obstacleIndex:this.currentObstacleIndex,connectionNames:this.getTraceConnectionNames(e)}),this.phase=\"try-elastic-push\"}findStableAnchorRange(t){const e=this.traces[t.traceIndex];if(!e)return null;let n=t.firstRouteIndex,o=t.lastRouteIndex;for(;n\u003e0;){const t=e.route[n];if(nJ(t)\u0026\u0026this.pointClearsCorridor(t))break;n--}for(;o\u003ce.route.length-1;){const t=e.route[o];if(nJ(t)\u0026\u0026this.pointClearsCorridor(t))break;o++}const i=e.route[n],r=e.route[o];if(!nJ(i)||!nJ(r)||i.layer!==r.layer||!this.pointClearsCorridor(i)||!this.pointClearsCorridor(r)||n\u003e=o)return null;const s={startIndex:n,endIndex:o},a=this.getRangeLength(e,s);return!Number.isFinite(a)||a\u003e(this.inputProblem.maxRerouteLength??10)+Mq?null:s}pointClearsCorridor(t){return this.corridor.every(e=\u003e{if(e.layer!==t.layer)return!0;const n=e.width/2+t.width/2+this.blockerIndex.clearance;return wq(t,e.start,e.end)\u003e=n-Mq})}startNextGridCandidate(){if(!this.currentBlocker||!this.currentRange)return void(this.phase=\"select-blocker\");if(this.resolutionCursor\u003e=this.gridResolutions.length)return this.blockerCursor++,void(this.phase=\"select-blocker\");if(this.offsetCursor\u003e=eJ.length)return this.resolutionCursor++,void(this.offsetCursor=0);const t=this.traces[this.currentBlocker.traceIndex],e=t.route[this.currentRange.startIndex],n=t.route[this.currentRange.endIndex];if(!nJ(e)||!nJ(n))return this.blockerCursor++,void(this.phase=\"select-blocker\");const o=this.gridResolutions[this.resolutionCursor],i=eJ[this.offsetCursor],r=this.currentObstacleIndex;if(!r)return this.blockerCursor++,void(this.phase=\"select-blocker\");this.attemptedGridCount++,this.activeSubSolver=new Qq({start:e,end:n,layer:e.layer,traceWidth:this.currentTraceWidth,gridSize:o,gridOffset:{x:i.x*o,y:i.y*o},connectionNames:this.getTraceConnectionNames(t),obstacleIndex:r,ignoreTraceIndex:this.currentBlocker.traceIndex,ignoreRouteRange:{start:this.currentRange.startIndex,end:this.currentRange.endIndex},bounds:this.inputProblem.simpleRouteJson.bounds,searchPadding:Rq(2.5*this.inputProblem.nominalPowerWidth,1.5,4)})}stepActiveSubSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e)return this.applyRoute(e,t instanceof Wq?\"elastic\":\"grid\"),this.activeSubSolver=null,void(this.phase=\"complete\")}this.failedSubSolvers??=[],this.failedSubSolvers.push(t),this.activeSubSolver=null,t instanceof Wq?this.phase=\"try-grid-candidate\":this.offsetCursor++}}applyRoute(t,e){const n=this.currentBlocker,o=this.currentRange,i=this.traces[n.traceIndex],r=i.route[o.startIndex],s=i.route[o.endIndex],a=t.points.map(t=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:this.currentTraceWidth,layer:r.layer}));a[0].width=Math.max(a[0].width,r.width),a[a.length-1].width=Math.max(a[a.length-1].width,s.width),i.route.splice(o.startIndex,o.endIndex-o.startIndex+1,...a),this.output={traces:this.traces,pushedTraceIndex:n.traceIndex,replacedRange:o,strategy:e}}createInflatedCorridorItems(){return this.corridor.flatMap(t=\u003ezq({start:t.start,end:t.end,width:t.width,base:{layers:[t.layer],kind:\"obstacle\",connectionNames:[]}}))}getGridResolutions(t){return[Rq(1.5*t,.1,.3),Rq(.75*t,.08,.18)].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e-t)\u003cMq)===e)}getRangeWidth(t,e){let n=this.inputProblem.simpleRouteJson.minTraceWidth;for(let o=e.startIndex;o\u003c=e.endIndex;o++){const e=t.route[o];nJ(e)\u0026\u0026(n=Math.max(n,e.width))}return n}getRangeLength(t,e){let n=0;for(let o=e.startIndex;o\u003ce.endIndex;o++){const e=t.route[o],i=t.route[o+1];if(!nJ(e)||!nJ(i)||e.layer!==i.layer)return Number.POSITIVE_INFINITY;n+=Nq(e,i)}return n}resolveNominalTraceWidth(t){return Math.max(t.nominalTraceWidth??t.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.inputProblem.simpleRouteJson.minTraceWidth,this.inputProblem.simpleRouteJson.minTraceWidth)}getTraceNominalWidth(t){return t.route.reduce((t,e)=\u003e\"wire\"===e.route_type?Math.max(t,e.width):t,this.inputProblem.simpleRouteJson.minTraceWidth)}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=this.getTraceConnectionNames(t),o=this.inputProblem.simpleRouteJson.connections.find(t=\u003e[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t)).some(t=\u003en.includes(t)))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getTraceConnectionNames(t){return[t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))}createStats(){return{phase:this.phase,corridorSegment:this.corridorCursor,corridorSegmentCount:this.corridor.length,blockingTraceCount:this.blockersByTrace.size,blockerCursor:this.blockerCursor,pushedTraceIndex:this.currentBlocker?.traceIndex,anchorRange:this.currentRange,traceWidth:this.currentTraceWidth,gridSize:this.gridResolutions[this.resolutionCursor],gridOffsetVariant:this.offsetCursor,attemptedGridCount:this.attemptedGridCount}}computeProgress(){return\"scan-corridor\"===this.phase?0===this.corridor.length?.25:this.corridorCursor/this.corridor.length*.25:0===this.blockers.length?.5:Math.min(.99,.25+this.blockerCursor/this.blockers.length)}getOutput(){return this.output}getConstructorParams(){return[this.inputProblem]}visualize(){const t=[];for(let e=0;e\u003cthis.traces.length;e++){const n=this.traces[e];for(let o=0;o\u003cn.route.length-1;o++){const i=n.route[o],r=n.route[o+1];nJ(i)\u0026\u0026nJ(r)\u0026\u0026i.layer===r.layer\u0026\u0026t.push({points:[i,r],strokeColor:e===this.currentBlocker?.traceIndex?\"#1769d2\":\"#777\",strokeWidth:Math.max(i.width,r.width)})}}for(const e of this.corridor)t.push({points:[e.start,e.end],strokeColor:\"rgba(255, 128, 0, 0.55)\",strokeWidth:e.width});return{coordinateSystem:\"cartesian\",title:this.getSolverName(),lines:t,points:[],rects:[],circles:[],texts:[]}}},iJ=1e-6,rJ=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y),sJ=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r\u003c=1e-12?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},aJ=(t,e,n)=\u003e(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),cJ=(t,e,n,o)=\u003e((t,e,n,o)=\u003e{const i=aJ(n,o,t),r=aJ(n,o,e),s=aJ(t,e,n),a=aJ(t,e,o);return(i\u003e0\u0026\u0026r\u003c0||i\u003c0\u0026\u0026r\u003e0)\u0026\u0026(s\u003e0\u0026\u0026a\u003c0||s\u003c0\u0026\u0026a\u003e0)})(t,e,n,o)?0:Math.min(sJ(t,n,o),sJ(e,n,o),sJ(n,t,e),sJ(o,t,e)),lJ=t=\u003e{const e=(t.ccwRotationDegrees??0)*Math.PI/180,n=Math.cos(e),o=Math.sin(e);return[{x:-t.width/2,y:-t.height/2},{x:t.width/2,y:-t.height/2},{x:t.width/2,y:t.height/2},{x:-t.width/2,y:t.height/2}].map(e=\u003e({x:t.center.x+e.x*n-e.y*o,y:t.center.y+e.x*o+e.y*n}))},dJ=t=\u003e{if(!(\"oval\"===t.type||\"circle\"===t.shape))return!1;if(Math.abs(t.width-t.height)\u003eiJ)throw new Error(`Physical connectivity does not yet support non-circular oval obstacle ${t.obstacleId??\"\u003cunknown\u003e\"}`);return!0},hJ=(t,e)=\u003e{for(let n=0;n\u003ce.length;n++)if(sJ(t,e[n],e[(n+1)%e.length])\u003c=iJ)return!0;let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n},uJ=(t,e)=\u003e{if(dJ(e))return Math.max(0,rJ(t,e.center)-e.width/2);const n=lJ(e);return hJ(t,n)?0:Math.min(...n.map((e,o)=\u003esJ(t,e,n[(o+1)%n.length])))},pJ=(t,e)=\u003e{if(dJ(t))return dJ(e)?Math.max(0,rJ(t.center,e.center)-t.width/2-e.width/2):Math.max(0,uJ(t.center,e)-t.width/2);if(dJ(e))return pJ(e,t);const n=lJ(t),o=lJ(e);if(hJ(n[0],o)||hJ(o[0],n))return 0;let i=Number.POSITIVE_INFINITY;for(let t=0;t\u003cn.length;t++)for(let e=0;e\u003co.length;e++)i=Math.min(i,cJ(n[t],n[(t+1)%n.length],o[e],o[(e+1)%o.length]));return i},mJ=(t,e)=\u003e({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),gJ=t=\u003e({minX:t.x,minY:t.y,maxX:t.x,maxY:t.y}),fJ=t=\u003e{if(dJ(t))return mJ(gJ(t.center),t.width/2);const e=lJ(t);return{minX:Math.min(...e.map(t=\u003et.x)),minY:Math.min(...e.map(t=\u003et.y)),maxX:Math.max(...e.map(t=\u003et.x)),maxY:Math.max(...e.map(t=\u003et.y))}},yJ=(t,e)=\u003e{if(!((t,e)=\u003et.layers.some(t=\u003ee.layers.includes(t)))(t,e)||!((t,e)=\u003et.maxX+iJ\u003e=e.minX\u0026\u0026e.maxX+iJ\u003e=t.minX\u0026\u0026t.maxY+iJ\u003e=e.minY\u0026\u0026e.maxY+iJ\u003e=t.minY)(t.bounds,e.bounds))return!1;if(\"bridge-pad\"===t.kind){const n={kind:\"obstacle\",obstacle:t.obstacle,layers:t.layers,bounds:t.bounds};return\"bridge-pad\"===e.kind?yJ(n,{kind:\"obstacle\",obstacle:e.obstacle,layers:e.layers,bounds:e.bounds}):yJ(n,e)}return\"bridge-pad\"===e.kind?yJ(e,t):\"endpoint\"===t.kind?\"endpoint\"===e.kind?rJ(t.point,e.point)\u003c=iJ:\"obstacle\"===e.kind?uJ(t.point,e.obstacle)\u003c=iJ:\"segment\"===e.kind?sJ(t.point,e.start,e.end)\u003c=e.width/2+iJ:rJ(t.point,e.center)\u003c=e.diameter/2+iJ:\"endpoint\"===e.kind?yJ(e,t):\"obstacle\"===t.kind?\"obstacle\"===e.kind?pJ(t.obstacle,e.obstacle)\u003c=iJ:\"segment\"===e.kind?((t,e,n)=\u003e{if(dJ(n))return Math.max(0,sJ(n.center,t,e)-n.width/2);const o=lJ(n);return hJ(t,o)||hJ(e,o)?0:Math.min(...o.map((n,i)=\u003ecJ(t,e,n,o[(i+1)%o.length])))})(e.start,e.end,t.obstacle)\u003c=e.width/2+iJ:uJ(e.center,t.obstacle)\u003c=e.diameter/2+iJ:\"obstacle\"===e.kind?yJ(e,t):\"segment\"===t.kind?\"segment\"===e.kind?cJ(t.start,t.end,e.start,e.end)\u003c=(t.width+e.width)/2+iJ:sJ(e.center,t.start,t.end)\u003c=t.width/2+e.diameter/2+iJ:\"segment\"===e.kind?yJ(e,t):rJ(t.center,e.center)\u003c=(t.diameter+e.diameter)/2+iJ},_J=class{parent;constructor(t){this.parent=Array.from({length:t},(t,e)=\u003ee)}find(t){const e=this.parent[t];if(e===t)return t;const n=this.find(e);return this.parent[t]=n,n}union(t,e){const n=this.find(t),o=this.find(e);n!==o\u0026\u0026(this.parent[o]=n)}},bJ=(t,e)=\u003e{const n=e.indexOf(t.from_layer),o=e.indexOf(t.to_layer);return n\u003c0||o\u003c0?[...new Set([t.from_layer,t.to_layer])]:e.slice(Math.min(n,o),Math.max(n,o)+1)},xJ=t=\u003e[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=\u003eBoolean(t)),vJ=t=\u003e[t.name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],t.netConnectionName,...t.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])].filter(t=\u003eBoolean(t)),SJ=t=\u003e[t.obstacleId,...t.connectedTo,...t.offBoardConnectsTo??[]].filter(t=\u003eBoolean(t)),IJ=(t,e,n,o)=\u003e({kind:\"bridge-contact\",center:{x:t.x,y:t.y},diameter:e,layers:n,bridgeId:o,bounds:mJ(gJ(t),e/2)}),CJ=.01,PJ={\"0603\":{horizontalWidth:.8,horizontalHeight:.95,centerSpacings:[1.65,1.8]},1206:{horizontalWidth:.6,horizontalHeight:1.6,centerSpacings:[3.2]},\"1206x4_pair\":{horizontalWidth:.8,horizontalHeight:.5,centerSpacings:[2.7]}},MJ=(t,e,n)=\u003e{if(!t.layer)throw new Error(`Jumper ${n} is missing its layer`);const o=PJ[t.footprint];if(!o)throw new Error(`Unsupported jumper footprint ${String(t.footprint)} on ${n}`);const i=Math.abs(t.end.x-t.start.x),r=Math.abs(t.end.y-t.start.y),s=t=\u003eo.centerSpacings.some(e=\u003eMath.abs(t-e)\u003cCJ),a=r\u003cCJ\u0026\u0026s(i),c=i\u003cCJ\u0026\u0026s(r);if(!a\u0026\u0026!c)throw new Error(`Jumper ${n} does not match ${t.footprint} pad spacing`);const l={type:\"rect\",center:{...e},width:a?o.horizontalWidth:o.horizontalHeight,height:a?o.horizontalHeight:o.horizontalWidth,layers:[t.layer],connectedTo:[]};return{kind:\"bridge-pad\",obstacle:l,layers:l.layers,bridgeId:n,bounds:fJ(l)}},NJ=(t,e,n)=\u003e{if(t.layer!==n.layer||e.layer!==n.layer)return!1;const o=(t,e)=\u003eMath.abs(t.x-e.x)\u003cCJ\u0026\u0026Math.abs(t.y-e.y)\u003cCJ,i=o(t,n.start)\u0026\u0026o(e,n.end),r=o(t,n.end)\u0026\u0026o(e,n.start);return i||r},wJ=(t,e,n,o)=\u003e{const i=[],r=t.route.flatMap((t,e)=\u003e\"jumper\"===t.route_type?[{routePoint:t,routePointIndex:e}]:[]),s=new Map;for(const e of r){const n=[];for(let o=1;o\u003ct.route.length;o++){const i=t.route[o-1],r=t.route[o];\"wire\"===i?.route_type\u0026\u0026\"wire\"===r?.route_type\u0026\u0026NJ(i,r,e.routePoint)\u0026\u0026n.push(o)}if(1!==n.length)throw new Error(`Jumper ${t.pcb_trace_id}:${e.routePointIndex} matched ${n.length} placeholder wire segments`);const o=n[0];if(s.has(o))throw new Error(`Multiple jumpers matched placeholder segment ${o} on ${t.pcb_trace_id}`);s.set(o,e)}let a;for(let r=0;r\u003ct.route.length;r++){const c=t.route[r];if(\"wire\"===c.route_type){if(a\u0026\u0026a.layer===c.layer\u0026\u0026rJ(a,c)\u003eiJ){const t=a;if(s.get(r));else{const e=t.width/2;i.push({kind:\"segment\",start:{x:t.x,y:t.y},end:{x:c.x,y:c.y},width:t.width,layers:[t.layer],bounds:mJ({minX:Math.min(t.x,c.x),minY:Math.min(t.y,c.y),maxX:Math.max(t.x,c.x),maxY:Math.max(t.y,c.y)},e)})}}a=c;continue}if(a=void 0,\"via\"===c.route_type){const o=t.route[r-1],s=t.route[r+1];for(const e of[o,s])if(\"wire\"===e?.route_type\u0026\u0026rJ(e,c)\u003eiJ)throw new Error(`Via ${t.pcb_trace_id}:${r} is adjacent to a non-colocated wire endpoint`);const a=c.via_diameter??n;i.push({kind:\"via\",center:{x:c.x,y:c.y},diameter:a,layers:bJ(c,e),bounds:mJ(gJ(c),a/2)});continue}const l=`${t.pcb_trace_id}:${r}:${c.route_type}`;if(\"jumper\"===c.route_type){i.push(MJ(c,c.start,l),MJ(c,c.end,l));continue}if(\"through_obstacle\"===c.route_type){if(!o.find(t=\u003et.layers.includes(c.from_layer)\u0026\u0026t.layers.includes(c.to_layer)\u0026\u0026uJ(c.start,t)\u003c=iJ\u0026\u0026uJ(c.end,t)\u003c=iJ))throw new Error(`Through-obstacle marker ${l} has no same-net multilayer obstacle witness`);i.push(IJ(c.start,0,[c.from_layer],l),IJ(c.end,0,[c.to_layer],l));continue}throw new Error(`Unsupported route primitive: ${String(c.route_type)}`)}return i},TJ=(t,e,n)=\u003e{const o=t.pointsToConnect[n];return o.pointId??o.pcb_port_id??`${t.name}[${e}:${n}]`},RJ=t=\u003e{const e={},n={},o=[];for(let i=0;i\u003ct.connections.length;i++){const r=t.connections[i];for(let t=0;t\u003cr.pointsToConnect.length;t++){const s=`${i}:${t}`;e[s]=TJ(r,i,t),n[s]=s,o.push([s])}}return{endpointCount:Object.keys(e).length,endpointLabels:e,componentByEndpointKey:n,endpointComponents:o}},EJ=t=\u003e{if(null===t||\"object\"!=typeof t)return JSON.stringify(t)??String(t);if(Array.isArray(t))return`[${t.map(t=\u003eEJ(t)).join(\",\")}]`;const e=t;return`{${Object.keys(e).sort().map(t=\u003e`${JSON.stringify(t)}:${EJ(e[t])}`).join(\",\")}}`},AJ=(t,e)=\u003e{const n=new Pq(t,e,{includePhysicalPositionAliases:!0}),o=(i=t.layerCount)\u003c=1?[\"top\"]:2===i?[\"top\",\"bottom\"]:[\"top\",...Array.from({length:i-2},(t,e)=\u003e`inner${e+1}`),\"bottom\"];var i;const r=(t=\u003e{const e=t.min_via_hole_diameter??t.minViaHoleDiameter??0;return Math.max(e,t.min_via_pad_diameter??t.minViaPadDiameter??t.minViaDiameter??.6)})(t),s=new Map,a=new Map,c={},l=(t,e)=\u003e{const n=s.get(t)??[];n.push(e),s.set(t,n)};for(let e=0;e\u003ct.connections.length;e++){const o=t.connections[e],i=n.canonicalize(vJ(o));if(1!==i.length)throw new Error(`Connection ${o.name} resolved to ${i.length} canonical nets`);for(let t=0;t\u003co.pointsToConnect.length;t++){const n=o.pointsToConnect[t],r=`${e}:${t}`,s=TJ(o,e,t);c[r]=s;const a={kind:\"endpoint\",endpointKey:r,endpointLabel:s,point:{x:n.x,y:n.y},layers:n.layers??[n.layer],bounds:gJ(n)};for(const t of i)l(t,a)}}for(const e of t.obstacles){const t={kind:\"obstacle\",obstacle:e,layers:e.layers,bounds:fJ(e)};for(const o of n.canonicalize(SJ(e))){const n=a.get(o)??[];n.push(e),a.set(o,n),s.has(o)\u0026\u0026l(o,t)}}for(const i of[...e,...t.fixedTraces??[]]){const t=n.canonicalize(xJ(i));if(1!==t.length)throw new Error(`Trace ${i.pcb_trace_id} resolved to ${t.length} canonical nets`);const e=a.get(t[0])??[],c=wJ(i,o,r,e);for(const e of t)if(s.has(e))for(const t of c)l(e,t)}const d={},h=[];for(const t of s.values()){const e=new _J(t.length),n=new Map;for(let o=0;o\u003ct.length;o++){const i=t[o];if(\"bridge-contact\"!==i.kind\u0026\u0026\"bridge-pad\"!==i.kind)continue;const r=n.get(i.bridgeId);void 0===r?n.set(i.bridgeId,o):e.union(r,o)}const o=t.length\u003e0?new Bt(t.length):null;if(o){for(const e of t)o.add(e.bounds.minX,e.bounds.minY,e.bounds.maxX,e.bounds.maxY);o.finish()}for(let n=0;n\u003ct.length;n++){const i=t[n],r=o?.search(i.bounds.minX-iJ,i.bounds.minY-iJ,i.bounds.maxX+iJ,i.bounds.maxY+iJ)??[];for(const o of r)o\u003c=n||yJ(i,t[o])\u0026\u0026e.union(n,o)}const i=new Map;for(let n=0;n\u003ct.length;n++){const o=t[n];if(\"endpoint\"!==o.kind)continue;const r=e.find(n),s=i.get(r)??[];s.push(o.endpointKey),i.set(r,s)}for(const t of i.values()){t.sort();const e=t[0];h.push(t);for(const n of t){if(void 0!==d[n])throw new Error(`Endpoint ${n} was assigned to multiple canonical nets`);d[n]=e}}}return h.sort(([t=\"\"],[e=\"\"])=\u003et.localeCompare(e)),{endpointCount:Object.keys(c).length,endpointLabels:c,componentByEndpointKey:d,endpointComponents:h}},OJ=class{baseline;inputProblem;baselineCaptureError;baselineTraceSignature;constructor(t,e){this.inputProblem=t,this.baselineTraceSignature=EJ(e);try{this.baseline=AJ(t,e),this.baselineCaptureError=null}catch(e){this.baseline=RJ(t),this.baselineCaptureError=e instanceof Error?e.message:String(e)}}validate(t){if(this.baselineCaptureError){const e=EJ(t)===this.baselineTraceSignature;return{safe:e,candidate:this.baseline,regressions:[],validationError:e?`Connectivity validation is limited to exact trace preservation: ${this.baselineCaptureError}`:`Connectivity validation failed closed: ${this.baselineCaptureError}`}}let e;try{e=AJ(this.inputProblem,t)}catch(t){return{safe:!1,candidate:RJ(this.inputProblem),regressions:[],validationError:`Connectivity validation failed closed: ${t instanceof Error?t.message:String(t)}`}}const n=[];for(const t of this.baseline.endpointComponents){if(t.length\u003c2)continue;const o=new Map;for(const n of t){const t=e.componentByEndpointKey[n]??`missing:${n}`,i=o.get(t)??[];i.push(n),o.set(t,i)}o.size\u003c=1||n.push({baselineEndpointKeys:[...t],baselineEndpointLabels:t.map(t=\u003ethis.baseline.endpointLabels[t]),candidateComponents:[...o.values()]})}return{safe:0===n.length,candidate:e,regressions:n}}},kJ=[{x:0,y:0},{x:.5,y:.5}],LJ=[.15,.2,.25,.3,.4,.5],DJ=t=\u003e\"wire\"===t?.route_type,zJ=t=\u003e\"via\"===t?.route_type,FJ=Array.from({length:24},(t,e)=\u003e{const n=e*Math.PI/12;return{x:Math.cos(n),y:Math.sin(n)}}),BJ=t=\u003e[...new Set(t.map(t=\u003eNumber(t.toFixed(6))))].sort((t,e)=\u003ee-t),jJ=class extends Sq{inputProblem;traces;obstacleIndex;phase=\"repair-vias\";traceCursor=0;routeCursor=0;candidateCursor=0;clearanceTierCursor=0;attemptedCandidateCount=0;attemptedClearanceShoveCount=0;attemptedViaGridCount=0;committedClearanceShoveCount=0;viaPairCountRemoved=0;viaCountRemoved=0;simplifiedPathCount=0;normalizedSegmentCount=0;achievedExtraClearanceCount=0;relocatedViaCount=0;unresolvedViaCount=0;attemptedPushedViaRepairCount=0;committedPushedViaRepairCount=0;padClearanceRerouteCount=0;unresolvedPadClearanceCount=0;initialPadClearanceViolationCount=0;remainingPadClearanceViolationCount=0;initialPadClearanceViolationCountByClearance={};remainingPadClearanceViolationCountByClearance={};budgetLimited=!1;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;connectionNameResolver;connectionByTraceId=new Map;connectivityInvariant;initialConnectivitySafeTraces;mutableTraceIndices;mutableTraceIndexSet;viaRepairTraceIndices;traceIndices;maxRerouteLength;clearancePaddingTiers;desiredPadClearance;initialTraceLengths=new Map;candidates=[];candidateShoveCount=0;rollbackTraces=null;baseCandidateValidated=!1;activeShovePadding=0;viaGridAttempt=null;candidateSetMayUseGridFallback=!1;pendingPushedViaRepair=null;alternatePushedViaRepairs=[];pushedViaRepairRollbackTraces=null;connectivityFinalized=!1;finalizedMutatedTraceIndices=[];resumePhase=\"scan-via-pairs\";constructor(t){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.initialConnectivitySafeTraces=structuredClone(t.traces),this.connectivityInvariant=new OJ(this.inputProblem.simpleRouteJson,this.initialConnectivitySafeTraces),this.connectionNameResolver=new Pq(t.simpleRouteJson,this.traces),this.maxRerouteLength=t.maxRerouteLength??10,this.desiredPadClearance=t.desiredPadClearance,this.clearancePaddingTiers=BJ([...t.clearancePaddingTiers??[.1,.05,0],0]).filter(t=\u003et\u003e=0);const e=this.traces.map((t,e)=\u003ee),n=(t,e,n)=\u003e{const o=[...new Set(t??n)];for(const t of o)if(!Number.isInteger(t)||t\u003c0||t\u003e=this.traces.length)throw new RangeError(`Invalid cleanup ${e} index: ${t}`);return o},o=n(t.traceIndices,\"trace\",e);this.viaRepairTraceIndices=n(t.viaRepairTraceIndices,\"via repair trace\",o),this.mutableTraceIndices=n(t.mutableTraceIndices,\"mutable trace\",o),this.mutableTraceIndexSet=new Set(this.mutableTraceIndices),this.traceIndices=o.filter(t=\u003ethis.resolveNominalTraceWidth(this.traces[t])\u003e=.499999);for(const t of this.traceIndices)this.initialTraceLengths.set(t,this.measureTraceLength(this.traces[t]));this.obstacleIndex=this.createObstacleIndex(),this.initialPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCount=this.initialPadClearanceViolationCount,this.initialPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.remainingPadClearanceViolationCountByClearance={...this.initialPadClearanceViolationCountByClearance},this.activeSubSolver=null,this.MAX_ITERATIONS=1e6,this.stats=this.createStats()}getSolverName(){return\"PowerTraceCleanupSolver\"}_step(){if(this.activeSubSolver)return this.stepActiveShoveSolver(),void(this.stats=this.createStats());switch(this.phase){case\"repair-vias\":this.repairNextVia();break;case\"scan-via-pairs\":this.scanNextViaPair();break;case\"scan-pad-clearance\":this.scanNextPadClearance();break;case\"scan-simplification\":this.scanNextSimplification();break;case\"evaluate-candidate\":this.evaluateCurrentCandidate();break;case\"shove-clearance\":break;case\"route-via-pair\":this.startNextViaGridCandidate();break;case\"complete\":this.ensureConnectivitySafeOutput(),this.solved=!0}this.stats=this.createStats()}repairNextVia(){const t=this.viaRepairTraceIndices[this.traceCursor],e=void 0===t?void 0:this.traces[t];if(!e)return this.traceCursor=0,this.routeCursor=0,this.phase=\"scan-via-pairs\",void this.rebuildObstacleIndex();const n=e.route.findIndex((t,e)=\u003ee\u003e=this.routeCursor\u0026\u0026zJ(t));if(-1===n)return this.traceCursor++,void(this.routeCursor=0);this.routeCursor=n+1;const o=e.route[n],i=e.route[n-1],r=e.route[n+1];if(!zJ(o)||!DJ(i)||!DJ(r))return;const s=this.getTraceConnectionNames(e),a=this.getBaseObstacleClearance();if(!this.obstacleIndex.collidesVia({point:o,layers:this.obstacleIndex.boardLayers,padDiameter:o.via_diameter??.6,holeDiameter:o.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,connectionNames:s,ignoreTraceIndex:t,ignoreRouteRange:{start:n,end:n},obstacleClearance:a,blockSameNetObstacles:!0,sameNetObstacleClearance:0}))return;const c=this.findViaRepair(e,n,a);if(!c){const t=this.findPushableViaRepairs(e,n,a),o=t.shift();return o?(this.alternatePushedViaRepairs=t,void this.startPushedViaRepair(o)):void this.unresolvedViaCount++}e.route.splice(c.startIndex,c.endIndex-c.startIndex+1,...c.route),this.relocatedViaCount++,this.routeCursor=c.startIndex+c.route.length,this.rebuildObstacleIndex()}findViaRepair(t,e,n){const o=this.createViaRepairContext(t,e);if(!o)return null;const i=o.candidates.map(t=\u003e({point:t,movedLength:Nq(o.leftAnchor,t)+Nq(t,o.rightAnchor)})).filter(({movedLength:t})=\u003et\u003c=o.originalLength+Math.min(6,this.maxRerouteLength)+Mq);i.sort((t,e)=\u003et.movedLength-e.movedLength||Nq(t.point,o.via)-Nq(e.point,o.via));for(const t of i)if(this.isViaRepairPointSafe(o,t.point,n))return this.createViaRepairReplacement(o,t.point);return null}findPushableViaRepairs(t,e,n){const o=this.viaRepairTraceIndices[this.traceCursor];if(void 0===o)return[];const i=this.createViaRepairContext(t,e);if(!i)return[];const r=i.candidates.flatMap(t=\u003e{const e=Nq(i.leftAnchor,t)+Nq(t,i.rightAnchor);if(e\u003ei.originalLength+Math.min(6,this.maxRerouteLength)+Mq)return[];const r=new Set,s=this.getViaRepairCollisionQueries(i,t,n);for(const t of s)for(const e of this.obstacleIndex.findCollisions(t)){if(\"trace\"!==e.kind||void 0===e.traceIndex||e.traceIndex===o||!this.mutableTraceIndexSet.has(e.traceIndex))return[];r.add(e.traceIndex)}if(0===r.size||r.size\u003e2)return[];const a=[...r];return this.isViaRepairPointSafe(i,t,n,a)?[{point:t,movedLength:e,blockerCount:r.size,blockerKey:[...r].sort((t,e)=\u003et-e).join(\",\")}]:[]});r.sort((t,e)=\u003et.blockerCount-e.blockerCount||t.movedLength-e.movedLength||Nq(t.point,i.via)-Nq(e.point,i.via));return[...new Map([...r].reverse().map(t=\u003e[t.blockerKey,t])).values(),...r].filter((t,e,n)=\u003en.findIndex(e=\u003ee.point.x===t.point.x\u0026\u0026e.point.y===t.point.y)===e).slice(0,12).map(t=\u003e({traceIndex:o,viaIndex:e,point:t.point,padClearance:n,corridor:[{start:i.leftAnchor,end:t.point,layer:i.leftWire.layer,width:i.leftWire.width},{start:t.point,end:i.rightAnchor,layer:i.rightWire.layer,width:i.rightWire.width},...this.obstacleIndex.boardLayers.map(e=\u003e({start:t.point,end:t.point,layer:e,width:i.viaDiameter}))]}))}createViaRepairContext(t,e){const n=t.route[e],o=t.route[e-1],i=t.route[e+1];if(!zJ(n)||!DJ(o)||!DJ(i))return null;const r=e-1==0||!DJ(t.route[e-2]),s=e+1===t.route.length-1||!DJ(t.route[e+2]),a=r?o:t.route[e-2],c=s?i:t.route[e+2],l=Nq(a,n)+Nq(n,c),d=this.getTraceConnectionNames(t),h=n.via_diameter??.6,u=n.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,p=Math.max(.3,u+this.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance+.05),m=[p,p+.15,p+.3,p+.5,p+.75,p+1,p+1.5,p+2].flatMap(t=\u003eFJ.map(e=\u003e({x:.025*Math.round((n.x+e.x*t)/.025),y:.025*Math.round((n.y+e.y*t)/.025)}))),g=[...m,...m.flatMap(t=\u003e[{x:t.x,y:Math.floor(10*n.y)/10},{x:t.x,y:Math.ceil(10*n.y)/10},{x:Math.floor(10*n.x)/10,y:t.y},{x:Math.ceil(10*n.x)/10,y:t.y}])].filter((t,e,n)=\u003en.findIndex(e=\u003ee.x===t.x\u0026\u0026e.y===t.y)===e);return{trace:t,viaIndex:e,via:n,leftWire:o,rightWire:i,leftIsEndpoint:r,rightIsEndpoint:s,leftAnchor:a,rightAnchor:c,originalLength:l,connectionNames:d,viaDiameter:h,holeDiameter:u,ignoreRouteRange:{start:Math.max(0,e-2),end:Math.min(t.route.length-1,e+2)},candidates:g}}getViaRepairCollisionQueries(t,e,n,o){const i=this.viaRepairTraceIndices[this.traceCursor],r={connectionNames:t.connectionNames,ignoreTraceIndex:i,ignoreTraceIndices:o,ignoreRouteRange:t.ignoreRouteRange,obstacleClearance:n};return[...this.obstacleIndex.boardLayers.map(n=\u003e({...r,start:e,end:e,layer:n,width:t.viaDiameter,blockSameNetObstacles:!0,sameNetObstacleClearance:0})),{...r,start:t.leftAnchor,end:e,layer:t.leftWire.layer,width:t.leftWire.width},{...r,start:e,end:t.rightAnchor,layer:t.rightWire.layer,width:t.rightWire.width}]}isViaRepairPointSafe(t,e,n,o){const i=this.viaRepairTraceIndices[this.traceCursor];return!this.obstacleIndex.collidesVia({point:e,layers:this.obstacleIndex.boardLayers,padDiameter:t.viaDiameter,holeDiameter:t.holeDiameter,connectionNames:t.connectionNames,ignoreTraceIndex:i,ignoreTraceIndices:o,ignoreRouteRange:{start:t.viaIndex,end:t.viaIndex},obstacleClearance:n,blockSameNetObstacles:!0,sameNetObstacleClearance:0})\u0026\u0026!this.getViaRepairCollisionQueries(t,e,n,o).slice(this.obstacleIndex.boardLayers.length).some(t=\u003ethis.obstacleIndex.collides(t))}createViaRepairReplacement(t,e){const n={...t.leftWire,...e},o={...t.via,...e},i={...t.rightWire,...e};return{startIndex:t.viaIndex-1,endIndex:t.viaIndex+1,route:[...t.leftIsEndpoint?[t.leftWire]:[],n,o,i,...t.rightIsEndpoint?[t.rightWire]:[]]}}startPushedViaRepair(t){this.pendingPushedViaRepair=t,this.pushedViaRepairRollbackTraces=structuredClone(this.traces),this.attemptedPushedViaRepairCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem.simpleRouteJson,traces:this.traces,powerTraceIndex:t.traceIndex,nominalPowerWidth:Math.max(...t.corridor.map(t=\u003et.width)),pushOnlyNominalWidthsBelow:Number.POSITIVE_INFINITY,mutableTraceIndices:this.mutableTraceIndices,corridor:t.corridor,maxRerouteLength:this.maxRerouteLength},this.connectionNameResolver)}finishPushedViaRepairSolver(t){const e=this.pendingPushedViaRepair;if(this.activeSubSolver=null,!e)return;if(t.solved){const n=t.getOutput();if(n){this.traces=n.traces,this.rebuildObstacleIndex();const t=this.traces[e.traceIndex],o=t?this.createViaRepairContext(t,e.viaIndex):null;if(o\u0026\u0026this.isViaRepairPointSafe(o,e.point,e.padClearance)){const n=this.createViaRepairReplacement(o,e.point);return t.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...n.route),this.relocatedViaCount++,this.committedPushedViaRepairCount++,this.routeCursor=n.startIndex+n.route.length,this.pendingPushedViaRepair=null,this.alternatePushedViaRepairs=[],this.pushedViaRepairRollbackTraces=null,void this.rebuildObstacleIndex()}}}this.pushedViaRepairRollbackTraces\u0026\u0026(this.traces=this.pushedViaRepairRollbackTraces),this.pendingPushedViaRepair=null,this.pushedViaRepairRollbackTraces=null;const n=this.alternatePushedViaRepairs.shift();if(n)return this.rebuildObstacleIndex(),void this.startPushedViaRepair(n);this.alternatePushedViaRepairs=[],this.unresolvedViaCount++,this.rebuildObstacleIndex()}scanNextViaPair(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.traceCursor=0,this.routeCursor=0,void(this.phase=\"scan-pad-clearance\");const e=this.traces[t],n=e.route.findIndex((t,e)=\u003ee\u003e=this.routeCursor\u0026\u0026\"via\"===t.route_type);if(-1===n)return void this.advanceTrace();const o=e.route.slice(n+1).findIndex(t=\u003e\"via\"===t.route_type);if(-1===o)return void this.advanceTrace();const i=n-1,r=n+1+o+1,s=e.route[i],a=e.route[r];if(this.routeCursor=n+1,!DJ(s)||!DJ(a)||s.layer!==a.layer||Nq(s,a)\u003ethis.maxRerouteLength+Mq)return;const c=this.createCandidates({kind:\"via-pair\",traceIndex:t,startIndex:i,endIndex:r}),l=c[0]?.width??Math.max(s.width,a.width),d=c[0]?.padClearance??this.getCandidatePadClearance(\"via-pair\",t,i,r),h=n=\u003e{const o=e.route[n];return!!DJ(o)\u0026\u0026this.obstacleIndex.findCollisions({start:o,end:o,layer:o.layer,width:l,connectionNames:this.getTraceConnectionNames(e),ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,i-1),end:Math.min(e.route.length-1,r+1)},obstacleClearance:d}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind)},u=e.route[i-1],p=e.route[r+1],m=c.length\u003e0\u0026\u0026h(i)\u0026\u0026DJ(u)\u0026\u0026u.layer===s.layer?i-1:i,g=c.length\u003e0\u0026\u0026h(r)\u0026\u0026DJ(p)\u0026\u0026p.layer===a.layer?r+1:r,f=[{startIndex:i,endIndex:r},{startIndex:m,endIndex:r},{startIndex:i,endIndex:g},{startIndex:m,endIndex:g}].filter((t,e,n)=\u003en.findIndex(e=\u003ee.startIndex===t.startIndex\u0026\u0026e.endIndex===t.endIndex)===e).flatMap(e=\u003ee.startIndex===i\u0026\u0026e.endIndex===r?c:this.createCandidates({kind:\"via-pair\",traceIndex:t,startIndex:e.startIndex,endIndex:e.endIndex}));0!==f.length\u0026\u0026this.beginCandidates(f,\"scan-via-pairs\",!0)}scanNextPadClearance(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.traceCursor=0,this.routeCursor=0,void(this.phase=\"scan-simplification\");const e=this.traces[t];if(this.resolveNominalTraceWidth(e)\u003c.499999)return void this.advanceTrace();const n=this.routeCursor,o=e.route[n],i=e.route[n+1];if(!DJ(o)||!DJ(i)||o.layer!==i.layer)return void(n\u003e=e.route.length-1?this.advanceTrace():this.routeCursor++);if(this.routeCursor++,!this.segmentHasPadClearanceViolation(t,n))return;const r=this.getPadClearanceIntervals(e,n).flatMap(e=\u003ethis.getImprovedPadClearanceTiers(t,e.startIndex,e.endIndex).flatMap(n=\u003ethis.createCandidates({kind:\"pad-clearance\",traceIndex:t,startIndex:e.startIndex,endIndex:e.endIndex,padClearance:n}).slice(0,8)));0!==r.length?this.beginCandidates(r.slice(0,72),\"scan-pad-clearance\",!0):this.unresolvedPadClearanceCount++}segmentHasPadClearanceViolation(t,e){const n=this.traces[t],o=n.route[e],i=n.route[e+1];return!(!DJ(o)||!DJ(i)||o.layer!==i.layer)\u0026\u0026this.obstacleIndex.findCollisions({start:o,end:i,layer:o.layer,width:Math.max(o.width,i.width),connectionNames:this.getTraceConnectionNames(n),ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,e-1),end:Math.min(n.route.length-1,e+2)},obstacleClearance:this.getPadClearanceForTrace(n)}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind)}getPadClearanceIntervals(t,e){const n=t.route[e];if(!DJ(n))return[];const o=[e];let i=0;for(let r=e-1;r\u003e=0;r--){const e=t.route[r],s=t.route[r+1];if(!DJ(e)||!DJ(s)||e.layer!==n.layer||s.layer!==n.layer)break;if(i+=Nq(e,s),i\u003ethis.maxRerouteLength/2+Mq)break;o.push(r)}const r=[e+1];i=0;for(let o=e+1;o\u003ct.route.length-1;o++){const e=t.route[o],s=t.route[o+1];if(!DJ(e)||!DJ(s)||e.layer!==n.layer||s.layer!==n.layer)break;if(i+=Nq(e,s),i\u003ethis.maxRerouteLength/2+Mq)break;r.push(o+1)}return o.flatMap(e=\u003er.map(n=\u003e({startIndex:e,endIndex:n,length:this.measureRouteRange(t,e,n).length}))).filter(t=\u003et.length\u003c=this.maxRerouteLength+Mq\u0026\u0026t.startIndex\u003ct.endIndex).sort((t,e)=\u003ee.length-t.length).slice(0,8)}scanNextSimplification(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),void(this.phase=\"complete\");const e=this.traces[t],n=this.routeCursor,o=e.route[n];if(!DJ(o)||n\u003e=e.route.length-1)return void(n\u003e=e.route.length-1?this.advanceTrace():this.routeCursor++);let i=0;const r=[];for(let t=n+1;t\u003ce.route.length;t++){const s=e.route[t-1],a=e.route[t];if(!DJ(s)||!DJ(a)||s.layer!==o.layer||a.layer!==o.layer)break;if(i+=Nq(s,a),i\u003ethis.maxRerouteLength+Mq)break;const c=this.measureRouteRange(e,n,t);(c.nonOctilinearSegmentCount\u003e0||c.pointCount\u003e3)\u0026\u0026r.push(t)}const s=r.slice(-6).reverse().flatMap(e=\u003ethis.createCandidates({kind:\"simplification\",traceIndex:t,startIndex:n,endIndex:e}));0!==s.length?this.beginCandidates(s,\"scan-simplification\"):this.routeCursor++}createCandidates({kind:t,traceIndex:e,startIndex:n,endIndex:o,padClearance:i}){const r=this.traces[e],s=r.route[n],a=r.route[o];if(!DJ(s)||!DJ(a)||s.layer!==a.layer)return[];const c=this.resolveNominalTraceWidth(r),l=this.measureRouteRange(r,n,o),d=i??this.getCandidatePadClearance(t,e,n,o),h=[],u=qq(s,a);if(\"pad-clearance\"===t\u0026\u00260===Gq([s,a])){const t=Nq(s,a);if(t\u003eMq){const e={x:-(a.y-s.y)/t,y:(a.x-s.x)/t};for(const t of[.25,.5,.75,1,1.5,2])for(const n of[-1,1])u.push([s,{x:s.x+e.x*t*n,y:s.y+e.y*t*n},{x:a.x+e.x*t*n,y:a.y+e.y*t*n},a])}}const p=new Map(u.map(t=\u003e[t.map(t=\u003e`${t.x.toFixed(6)},${t.y.toFixed(6)}`).join(\";\"),t]));for(const i of p.values()){const u=Uq(i);if(u\u003ethis.maxRerouteLength+Mq||\"pad-clearance\"===t\u0026\u0026u\u003e1.35*l.length+.5||\"simplification\"===t\u0026\u0026(u\u003e1.1*l.length+Mq||this.measureTraceLength(r)-l.length+u\u003e1.01*(this.initialTraceLengths.get(e)??this.measureTraceLength(r))+Mq))continue;const p=u\u003c=Mq?c:c-l.deficitArea/u;if(p\u003ec+Mq)continue;const m=.05*Math.ceil(Math.max(this.inputProblem.simpleRouteJson.minTraceWidth,p)/.05-Mq),g=BJ([c,Math.min(c,m),Math.min(c,Math.max(this.inputProblem.simpleRouteJson.minTraceWidth,p))].map(t=\u003eMath.max(t,s.width)));for(const r of g){const u=this.measureCandidate(i,r,c,a.width,s.width);u.deficitArea\u003el.deficitArea+Mq||u.conservativeDeficitArea\u003el.conservativeDeficitArea+Mq||!this.preservesCoverage(u,l)||(\"simplification\"!==t||0!==l.nonOctilinearSegmentCount||u.pointCount\u003cl.pointCount\u0026\u0026u.length\u003cl.length-Mq)\u0026\u0026h.push({kind:t,traceIndex:e,startIndex:n,endIndex:o,layer:s.layer,points:i,width:r,padClearance:d,originalQuality:l})}}return h.slice(0,18)}beginCandidates(t,e,n=!1){this.candidates=t,this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.rollbackTraces=null,this.baseCandidateValidated=!1,this.resumePhase=e,this.candidateSetMayUseGridFallback=n,this.phase=\"evaluate-candidate\"}evaluateCurrentCandidate(){const t=this.candidates[this.candidateCursor];if(!t)return void this.finishCandidateSet(!1);if(!this.baseCandidateValidated){if(!this.candidateCollides(t,0))return this.candidateShoveCount\u003e0?void this.applyCandidate(t,0):(this.baseCandidateValidated=!0,void(this.clearanceTierCursor=0));return this.getPushableTraceIndices(t,0)\u0026\u0026this.candidateShoveCount\u003c2\u0026\u0026this.attemptedClearanceShoveCount\u003c48?void this.startClearanceShove(t,0):void this.advanceCandidate()}const e=this.clearancePaddingTiers[this.clearanceTierCursor];if(void 0===e||e\u003c=Mq)return void this.applyCandidate(t,0);if(this.attemptedCandidateCount++,!this.candidateCollides(t,e))return void this.applyCandidate(t,e);this.getPushableTraceIndices(t,e)\u0026\u0026this.candidateShoveCount\u003c2\u0026\u0026this.attemptedClearanceShoveCount\u003c48?this.startClearanceShove(t,e):(this.rollbackCandidateShoves(),this.clearanceTierCursor++,this.candidateShoveCount=0)}advanceCandidate(){this.rollbackCandidateShoves(),this.candidateCursor++,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1}candidateCollides(t,e){const n=this.traces[t.traceIndex],o=this.getTraceConnectionNames(n);for(let i=0;i\u003ct.points.length-1;i++){const r=this.getCandidateSegmentWidth(t,i);if(this.obstacleIndex.collides({start:t.points[i],end:t.points[i+1],layer:t.layer,width:r+2*e,connectionNames:o,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(n.route.length-1,t.endIndex+1)},obstacleClearance:t.padClearance}))return!0}return!1}getPushableTraceIndices(t,e){const n=this.traces[t.traceIndex],o=this.getTraceConnectionNames(n),i=new Set;for(let r=0;r\u003ct.points.length-1;r++){const s=this.getCandidateSegmentWidth(t,r),a={start:t.points[r],end:t.points[r+1],layer:t.layer,width:s+2*e,connectionNames:o,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(n.route.length-1,t.endIndex+1)},obstacleClearance:t.padClearance};if(!this.obstacleIndex.collides(a))continue;const c=this.obstacleIndex.findCollisions(a);if(0===c.length)return null;for(const e of c){if(\"trace\"!==e.kind||void 0===e.traceIndex||e.traceIndex===t.traceIndex||!this.mutableTraceIndexSet.has(e.traceIndex))return null;const n=this.traces[e.traceIndex];if(!n||this.resolveNominalTraceWidth(n)\u003e=t.width-Mq)return null;i.add(e.traceIndex)}}return i.size\u003e0\u0026\u0026i.size\u003c=2?[...i]:null}startClearanceShove(t,e){this.rollbackTraces??=structuredClone(this.traces),this.activeShovePadding=e;const n=t.width+2*e,o=t.points.slice(0,-1).map((n,o)=\u003e({start:n,end:t.points[o+1],layer:t.layer,width:this.getCandidateSegmentWidth(t,o)+2*e}));this.attemptedClearanceShoveCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem.simpleRouteJson,traces:this.traces,powerTraceIndex:t.traceIndex,nominalPowerWidth:n,pushOnlyNominalWidthsBelow:t.width,mutableTraceIndices:this.mutableTraceIndices,corridor:o,maxRerouteLength:this.maxRerouteLength},this.connectionNameResolver),this.phase=\"shove-clearance\"}getCandidateSegmentWidth(t,e){const n=this.traces[t.traceIndex],o=n.route[t.startIndex],i=n.route[t.endIndex],r=0===e\u0026\u0026DJ(o)?o.width:t.width,s=e===t.points.length-2\u0026\u0026DJ(i)?i.width:t.width;return Math.max(r,s)}stepActiveShoveSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed)if(this.pendingPushedViaRepair\u0026\u0026t instanceof oJ)this.finishPushedViaRepairSolver(t);else if(t instanceof Qq)this.finishViaGridSolver(t);else{if(this.activeSubSolver=null,this.phase=\"evaluate-candidate\",t.solved){const e=t.getOutput();if(e)return this.traces=e.traces,this.candidateShoveCount++,void this.rebuildObstacleIndex()}this.failedSubSolvers??=[],this.failedSubSolvers.push(t),this.rollbackCandidateShoves(),this.activeShovePadding\u003c=Mq?this.advanceCandidate():this.clearanceTierCursor++,this.candidateShoveCount=0}}rollbackCandidateShoves(){this.rollbackTraces\u0026\u0026(this.traces=this.rollbackTraces,this.rollbackTraces=null,this.rebuildObstacleIndex())}applyCandidate(t,e){const n=this.traces[t.traceIndex],o=n.route[t.startIndex],i=n.route[t.endIndex],r=t.points.map((e,n)=\u003e({...0===n?o:n===t.points.length-1?i:{route_type:\"wire\",layer:t.layer,width:t.width},x:e.x,y:e.y,layer:t.layer,width:0===n?o.width:n===t.points.length-1?i.width:t.width})),s=n.route.slice(t.startIndex,t.endIndex+1),a=t.originalQuality.nonOctilinearSegmentCount;if(n.route.splice(t.startIndex,t.endIndex-t.startIndex+1,...r),\"via-pair\"===t.kind){const e=s.filter(t=\u003e\"via\"===t.route_type).length;this.viaPairCountRemoved++,this.viaCountRemoved+=e,this.routeCursor=Math.max(0,t.startIndex-1)}else\"pad-clearance\"===t.kind?(this.padClearanceRerouteCount++,this.routeCursor=t.startIndex+Math.max(1,r.length-1)):(this.simplifiedPathCount++,this.normalizedSegmentCount+=a,this.routeCursor=t.startIndex+Math.max(1,r.length-1));this.committedClearanceShoveCount+=this.candidateShoveCount,e\u003eMq\u0026\u0026this.achievedExtraClearanceCount++,this.rollbackTraces=null,this.candidateShoveCount=0,this.rebuildObstacleIndex(),this.finishCandidateSet(!0)}finishCandidateSet(t){const e=this.candidates[0],n=BJ(this.candidates.filter(t=\u003et.kind===e?.kind).map(t=\u003et.width)),o=BJ(this.candidates.filter(t=\u003et.kind===e?.kind\u0026\u0026t.traceIndex===e.traceIndex\u0026\u0026t.startIndex===e.startIndex\u0026\u0026t.endIndex===e.endIndex).map(t=\u003et.padClearance));if(this.rollbackCandidateShoves(),this.candidates=[],this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1,!t\u0026\u0026this.candidateSetMayUseGridFallback\u0026\u0026e)return this.candidateSetMayUseGridFallback=!1,void this.beginViaGridAttempt(e,n,o);this.candidateSetMayUseGridFallback=!1,t||this.routeCursor++,this.phase=this.resumePhase}beginViaGridAttempt(t,e,n=[t.padClearance]){this.viaGridAttempt={kind:t.kind,traceIndex:t.traceIndex,startIndex:t.startIndex,endIndex:t.endIndex,layer:t.layer,padClearances:n,padClearanceCursor:0,originalQuality:t.originalQuality,widths:e,widthCursor:0,gridSizes:[],gridSizeCursor:0,offsetCursor:0},this.phase=\"route-via-pair\"}startNextViaGridCandidate(){const t=this.viaGridAttempt;if(!t)return void(this.phase=this.resumePhase);if(t.padClearanceCursor\u003e=t.padClearances.length)return\"pad-clearance\"===t.kind\u0026\u0026this.unresolvedPadClearanceCount++,this.viaGridAttempt=null,this.routeCursor++,void(this.phase=this.resumePhase);if(t.widthCursor\u003e=t.widths.length)return t.padClearanceCursor++,t.widthCursor=0,t.gridSizes=[],t.gridSizeCursor=0,void(t.offsetCursor=0);const e=t.widths[t.widthCursor],n=t.padClearances[t.padClearanceCursor];if(0===t.gridSizes.length\u0026\u0026(t.gridSizes=BJ([Rq(e/2,.2,.4),Rq(e/3,.15,.25)])),t.gridSizeCursor\u003e=t.gridSizes.length)return t.widthCursor++,t.gridSizes=[],t.gridSizeCursor=0,void(t.offsetCursor=0);if(t.offsetCursor\u003e=kJ.length)return t.gridSizeCursor++,void(t.offsetCursor=0);const o=this.traces[t.traceIndex],i=o.route[t.startIndex],r=o.route[t.endIndex];if(!DJ(i)||!DJ(r))return this.viaGridAttempt=null,this.routeCursor++,void(this.phase=this.resumePhase);const s=t.gridSizes[t.gridSizeCursor],a=kJ[t.offsetCursor];this.attemptedViaGridCount++,this.activeSubSolver=new Qq({start:i,end:r,layer:t.layer,traceWidth:e,gridSize:s,gridOffset:{x:a.x*s,y:a.y*s},connectionNames:this.getTraceConnectionNames(o),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(o.route.length-1,t.endIndex+1)},bounds:this.inputProblem.simpleRouteJson.bounds,obstacleClearance:n,searchPadding:Math.min(4,Math.max(2,Nq(i,r)/2,3*e)),requireOctilinear:!0})}finishViaGridSolver(t){const e=this.viaGridAttempt;if(this.activeSubSolver=null,t.solved\u0026\u0026e){const n=t.getOutput(),o=this.traces[e.traceIndex];if(n\u0026\u0026o){const t=this.resolveNominalTraceWidth(o),i=this.measureCandidate(n.points,n.traceWidth,t,o.route[e.endIndex].width,o.route[e.startIndex].width);if(0===i.nonOctilinearSegmentCount\u0026\u0026i.length\u003c=this.maxRerouteLength+Mq\u0026\u0026i.deficitArea\u003c=e.originalQuality.deficitArea+Mq\u0026\u0026i.conservativeDeficitArea\u003c=e.originalQuality.conservativeDeficitArea+Mq\u0026\u0026this.preservesCoverage(i,e.originalQuality)){const t={kind:e.kind,traceIndex:e.traceIndex,startIndex:e.startIndex,endIndex:e.endIndex,layer:e.layer,points:n.points,width:n.traceWidth,padClearance:e.padClearances[e.padClearanceCursor],originalQuality:e.originalQuality};return this.viaGridAttempt=null,void this.beginCandidates([t],this.resumePhase,!1)}}}t.failed\u0026\u0026(this.failedSubSolvers??=[],this.failedSubSolvers.push(t)),e\u0026\u0026e.offsetCursor++,this.phase=\"route-via-pair\"}measureRouteRange(t,e,n){const o=this.resolveNominalTraceWidth(t);let i=0,r=0,s=0,a=0,c=0,l=0,d=0;for(let h=e;h\u003c=n;h++){if(DJ(t.route[h])\u0026\u0026d++,h\u003e=n)continue;const e=t.route[h],u=t.route[h+1];if(!DJ(e)||!DJ(u)||e.layer!==u.layer)continue;const p=Nq(e,u);i+=p,r+=p*Math.max(0,o-e.width),e.width\u003e=o-Mq\u0026\u0026(a+=p),s+=p*Math.max(0,o-Math.min(e.width,u.width)),Math.min(e.width,u.width)\u003e=o-Mq\u0026\u0026(c+=p),l+=Gq([e,u])}return{length:i,deficitArea:r,conservativeDeficitArea:s,nominalLength:a,conservativeNominalLength:c,nonOctilinearSegmentCount:l,pointCount:d}}measureTraceLength(t){let e=0;for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];DJ(o)\u0026\u0026DJ(i)\u0026\u0026o.layer===i.layer\u0026\u0026(e+=Nq(o,i))}return e}measureCandidate(t,e,n,o=e,i=e){const r=Uq(t);let s=0,a=0,c=0,l=0;for(let r=0;r\u003ct.length-1;r++){const d=Nq(t[r],t[r+1]),h=0===r?i:e,u=r===t.length-2?o:e,p=Math.min(h,u);s+=d*Math.max(0,n-h),a+=d*Math.max(0,n-p),h\u003e=n-Mq\u0026\u0026(c+=d),p\u003e=n-Mq\u0026\u0026(l+=d)}return{length:r,deficitArea:s,conservativeDeficitArea:a,nominalLength:c,conservativeNominalLength:l,nonOctilinearSegmentCount:Gq(t),pointCount:t.length}}preservesCoverage(t,e){const n=e.length\u003c=Mq?1:e.nominalLength/e.length,o=t.length\u003c=Mq?1:t.nominalLength/t.length,i=e.length\u003c=Mq?1:e.conservativeNominalLength/e.length,r=t.length\u003c=Mq?1:t.conservativeNominalLength/t.length;return!(o+Mq\u003cn||r+Mq\u003ci)\u0026\u0026!(t.length\u003ee.length+Mq\u0026\u0026o\u003c.999999)}advanceTrace(){this.traceCursor++,this.routeCursor=0,this.rebuildObstacleIndex()}createObstacleIndex(){return new tJ(this.inputProblem.simpleRouteJson,this.traces,\"repair-vias\"===this.phase?void 0:this.traceIndices?.[this.traceCursor],[],this.connectionNameResolver)}rebuildObstacleIndex(){this.obstacleIndex=this.createObstacleIndex()}resolveNominalTraceWidth(t){const e=this.findConnectionForTrace(t);return Math.max(e?.nominalTraceWidth??e?.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.inputProblem.simpleRouteJson.minTraceWidth,this.inputProblem.simpleRouteJson.minTraceWidth)}getPadClearanceForTrace(t){const e=this.getBaseObstacleClearance();return this.resolveNominalTraceWidth(t)\u003e=.499999?Math.max(e,this.desiredPadClearance??this.resolveNominalTraceWidth(t)/2):e}getBaseObstacleClearance(){return Math.max(this.inputProblem.simpleRouteJson.defaultObstacleMargin??0,this.inputProblem.simpleRouteJson.minTraceToPadEdgeClearance??0,.1)}getCandidatePadClearance(t,e,n,o){const i=this.traces[e],r=this.getBaseObstacleClearance(),s=this.getPadClearanceForTrace(i);if(\"pad-clearance\"===t)return s;const a=\"via-pair\"===t?Math.min(s,Math.max(r,.15)):s;return this.findExistingPadClearance(e,n,o,r,a)}getImprovedPadClearanceTiers(t,e,n){const o=this.traces[t],i=this.getBaseObstacleClearance(),r=this.getPadClearanceForTrace(o),s=this.findExistingPadClearance(t,e,n,i,r),a=Math.max(.025,Math.min(.05,r/10)),c=[r];for(let t=r-a;t\u003es+a/2;t-=a)c.push(t);return BJ(c).filter(t=\u003et\u003es+Mq)}findExistingPadClearance(t,e,n,o,i){if(this.routeRangeHasPadClearanceViolation(t,e,n,o))return o;if(!this.routeRangeHasPadClearanceViolation(t,e,n,i))return i;let r=o,s=i;for(let o=0;o\u003c7;o++){const o=(r+s)/2;this.routeRangeHasPadClearanceViolation(t,e,n,o)?s=o:r=o}return Math.max(o,Number((r-.001).toFixed(6)))}routeRangeHasPadClearanceViolation(t,e,n,o){const i=this.traces[t],r=this.getTraceConnectionNames(i);for(let s=e;s\u003cn;s++){const a=i.route[s],c=i.route[s+1];if(!DJ(a)||!DJ(c)||a.layer!==c.layer)continue;if(this.obstacleIndex.findCollisions({start:a,end:c,layer:a.layer,width:Math.max(a.width,c.width),connectionNames:r,ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,e-1),end:Math.min(i.route.length-1,n+1)},obstacleClearance:o}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind))return!0}return!1}countPadClearanceViolations(t){let e=0;for(const n of this.traceIndices){const o=this.traces[n];if(!o)continue;const i=this.getTraceConnectionNames(o);for(let r=0;r\u003co.route.length-1;r++){const s=o.route[r],a=o.route[r+1];if(!DJ(s)||!DJ(a)||s.layer!==a.layer)continue;this.obstacleIndex.findCollisions({start:s,end:a,layer:s.layer,width:Math.max(s.width,a.width),connectionNames:i,ignoreTraceIndex:n,ignoreRouteRange:{start:Math.max(0,r-1),end:Math.min(o.route.length-1,r+2)},obstacleClearance:t??this.getPadClearanceForTrace(o)}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind)\u0026\u0026e++}}return e}countPadClearanceViolationsByTier(){return Object.fromEntries(LJ.map(t=\u003e[t.toFixed(2),this.countPadClearanceViolations(t)]))}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=new Set(this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t))),o=this.inputProblem.simpleRouteJson.connections.find(t=\u003ethis.connectionNameResolver.canonicalize(this.getConnectionNames(t)).some(t=\u003en.has(t)))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getConnectionNames(t){return[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))}getTraceConnectionNames(t){return[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=\u003eBoolean(t))}ensureConnectivitySafeOutput(){if(!this.connectivityFinalized){this.connectivityFinalized=!0,this.connectivityValidationCount++;try{const t=this.connectivityInvariant.validate(this.traces);if(this.connectivityValidationError??=t.validationError??null,t.safe)return void(this.finalizedMutatedTraceIndices=this.getMutatedTraceIndices());this.connectivityRegressionEndpointIds=[...new Set(t.regressions.flatMap(t=\u003et.baselineEndpointLabels))]}catch(t){this.connectivityValidationError=t instanceof Error?t.message:String(t)}this.connectivityRollbackCount++,this.connectivityRollbackMutationStats={committedClearanceShoveCount:this.committedClearanceShoveCount,viaPairCountRemoved:this.viaPairCountRemoved,viaCountRemoved:this.viaCountRemoved,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,achievedExtraClearanceCount:this.achievedExtraClearanceCount,relocatedViaCount:this.relocatedViaCount,committedPushedViaRepairCount:this.committedPushedViaRepairCount,padClearanceRerouteCount:this.padClearanceRerouteCount},this.committedClearanceShoveCount=0,this.viaPairCountRemoved=0,this.viaCountRemoved=0,this.simplifiedPathCount=0,this.normalizedSegmentCount=0,this.achievedExtraClearanceCount=0,this.relocatedViaCount=0,this.committedPushedViaRepairCount=0,this.padClearanceRerouteCount=0,this.traces=structuredClone(this.initialConnectivitySafeTraces),this.obstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,void 0,[],this.connectionNameResolver),this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.finalizedMutatedTraceIndices=this.getMutatedTraceIndices()}}getMutatedTraceIndices(){const t=Math.max(this.initialConnectivitySafeTraces.length,this.traces.length);return Array.from({length:t},(t,e)=\u003ee).filter(t=\u003eJSON.stringify(this.initialConnectivitySafeTraces[t])!==JSON.stringify(this.traces[t]))}createStats(){const t=this.candidates[this.candidateCursor],e=\"repair-vias\"===this.phase?this.viaRepairTraceIndices:this.traceIndices;return{phase:this.phase,budgetLimited:this.budgetLimited,completionReason:\"complete\"===this.phase||this.solved?this.connectivityRollbackCount\u003e0?\"connectivity_rollback\":this.budgetLimited?\"iteration_budget\":this.connectivityValidationError?\"connectivity_validation_unavailable\":\"completed\":null,resultStatus:this.connectivityRollbackCount\u003e0||this.budgetLimited||null!==this.connectivityValidationError?\"best_effort\":\"complete\",traceCursor:this.traceCursor,traceCount:e.length,traceIndex:e[this.traceCursor],routeCursor:this.routeCursor,candidateCursor:this.candidateCursor,candidateCount:this.candidates.length,candidateKind:t?.kind,candidateWidth:t?.width,candidatePointCount:t?.points.length,clearancePadding:this.clearancePaddingTiers[this.clearanceTierCursor],candidateShoveCount:this.candidateShoveCount,attemptedCandidateCount:this.attemptedCandidateCount,attemptedClearanceShoveCount:this.attemptedClearanceShoveCount,attemptedViaGridCount:this.attemptedViaGridCount,committedClearanceShoveCount:this.committedClearanceShoveCount,viaPairCountRemoved:this.viaPairCountRemoved,viaCountRemoved:this.viaCountRemoved,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,achievedExtraClearanceCount:this.achievedExtraClearanceCount,relocatedViaCount:this.relocatedViaCount,unresolvedViaCount:this.unresolvedViaCount,attemptedPushedViaRepairCount:this.attemptedPushedViaRepairCount,committedPushedViaRepairCount:this.committedPushedViaRepairCount,padClearanceRerouteCount:this.padClearanceRerouteCount,unresolvedPadClearanceCount:this.unresolvedPadClearanceCount,initialPadClearanceViolationCount:this.initialPadClearanceViolationCount,remainingPadClearanceViolationCount:this.remainingPadClearanceViolationCount,initialPadClearanceViolationCountByClearance:{...this.initialPadClearanceViolationCountByClearance},remainingPadClearanceViolationCountByClearance:{...this.remainingPadClearanceViolationCountByClearance},connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},mutatedTraceIndices:[...this.finalizedMutatedTraceIndices],spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){if(this.solved||\"complete\"===this.phase)return 1;const t=\"repair-vias\"===this.phase?this.viaRepairTraceIndices:this.traceIndices;if(0===t.length)return 1;const e=\"scan-via-pairs\"===this.resumePhase?0:.5;return Math.min(.99,e+this.traceCursor/t.length*.5)}getConstructorParams(){return[this.inputProblem]}tryFinalAcceptance(){const t=this.pushedViaRepairRollbackTraces??this.rollbackTraces;t\u0026\u0026(this.traces=t),this.activeSubSolver=null,this.rollbackTraces=null,this.pushedViaRepairRollbackTraces=null,this.pendingPushedViaRepair=null,this.alternatePushedViaRepairs=[],this.viaGridAttempt=null,this.candidates=[],this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1,this.candidateSetMayUseGridFallback=!1,this.ensureConnectivitySafeOutput(),this.obstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,void 0,[],this.connectionNameResolver),this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.budgetLimited=!0,this.phase=\"complete\",this.solved=!0,this.progress=1,this.stats=this.createStats()}getOutput(){return structuredClone(this.solved?this.traces:this.initialConnectivitySafeTraces)}visualize(){const t=[],e=[],n=this.candidates[this.candidateCursor];for(let n=0;n\u003cthis.traces.length;n++){const o=this.traces[n];for(const t of o.route)\"via\"===t.route_type\u0026\u0026e.push({center:t,radius:(t.via_diameter??.6)/2,fill:\"#d4a017\",stroke:\"#7a5700\"});for(let e=0;e\u003co.route.length-1;e++){const n=o.route[e],i=o.route[e+1];DJ(n)\u0026\u0026DJ(i)\u0026\u0026n.layer===i.layer\u0026\u0026t.push({points:[n,i],strokeColor:\"bottom\"===n.layer?\"#376fc4\":\"#777\",strokeWidth:n.width})}}if(n)for(let e=0;e\u003cn.points.length-1;e++)t.push({points:[n.points[e],n.points[e+1]],strokeColor:\"#ff7400\",strokeWidth:n.width+2*(this.clearancePaddingTiers[this.clearanceTierCursor]??0)});return{coordinateSystem:\"cartesian\",title:`Power trace cleanup: ${this.phase}`,lines:t,points:[],circles:e,rects:[],texts:[]}}},$J=t=\u003e\"wire\"===t?.route_type,YJ=class extends Sq{inputProblem;traces;obstacleIndex;traceCursor=0;routeCursor=0;repairedSegmentCount=0;repairedPadNeckSegmentCount=0;unresolvedSegmentCount=0;totalWidthReduction=0;budgetLimited=!1;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;connectionNameResolver;nominalWidthByTraceId=new Map;connectivityInvariant;initialConnectivitySafeTraces;minimumTraceWidth;traceIndices;connectivityFinalized=!1;constructor(t){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.initialConnectivitySafeTraces=structuredClone(t.traces),this.connectivityInvariant=new OJ(this.inputProblem.simpleRouteJson,this.initialConnectivitySafeTraces),this.connectionNameResolver=new Pq(t.simpleRouteJson,this.traces),this.minimumTraceWidth=t.simpleRouteJson.minTraceWidth;const e=t.traceIndices?[...new Set(t.traceIndices)]:this.traces.map((t,e)=\u003ee);for(const t of e)if(!Number.isInteger(t)||t\u003c0||t\u003e=this.traces.length)throw new RangeError(`Invalid clearance-repair trace index: ${t}`);this.traceIndices=e,this.obstacleIndex=this.createConservativeObstacleIndex();const n=this.traceIndices.reduce((t,e)=\u003et+Math.max(0,this.traces[e].route.length-1),0);this.MAX_ITERATIONS=Math.max(10,8*n+2*this.traceIndices.length),this.stats=this.createStats()}getSolverName(){return\"PowerTraceClearanceRepairSolver\"}_step(){const t=this.traceIndices[this.traceCursor],e=void 0===t?void 0:this.traces[t];if(!e)return this.ensureConnectivitySafeOutput(),this.solved=!0,void(this.stats=this.createStats());if(this.routeCursor\u003e=e.route.length-1)return this.traceCursor++,this.routeCursor=0,void(this.stats=this.createStats());const n=this.routeCursor++,o=e.route[n],i=e.route[n+1];if(!$J(o)||!$J(i)||o.layer!==i.layer)return void(this.stats=this.createStats());const r=Math.max(o.width,i.width),s={start:o,end:i,layer:o.layer,width:r,connectionNames:this.getTraceConnectionNames(e),ignoreTraceIndex:t,ignoreRouteRange:{start:n,end:n+1}};if(this.repairConnectedPadNeck(e,n,s))return void(this.stats=this.createStats());if(!this.segmentHasForeignTraceCollision(n,r))return void(this.stats=this.createStats());if(this.segmentHasForeignTraceCollision(n,this.minimumTraceWidth))return this.unresolvedSegmentCount++,void(this.stats=this.createStats());let a=this.minimumTraceWidth,c=r;for(let t=0;t\u003c10;t++){const t=(a+c)/2;this.segmentHasForeignTraceCollision(n,t)?c=t:a=t}const l=r\u003e=.5?.025:.0125,d=Math.max(this.minimumTraceWidth,Math.floor((a+Mq)/l)*l),h=this.segmentHasForeignTraceCollision(n,d)?a:d,u=o.width,p=i.width;o.width=Math.min(o.width,h),i.width=Math.min(i.width,h);const m=u-o.width+(p-i.width);if(m\u003c=Mq)return this.unresolvedSegmentCount++,void(this.stats=this.createStats());this.repairedSegmentCount++,this.totalWidthReduction+=m,this.obstacleIndex=this.createConservativeObstacleIndex(),this.routeCursor=Math.max(0,n-1),this.stats=this.createStats()}repairConnectedPadNeck(t,e,n){const o=t.route[e],i=t.route[e+1];if(!$J(o)||!$J(i))return!1;let r=this.obstacleIndex.getConnectedPadWidthLimitAtPoint(n,o),s=this.obstacleIndex.getConnectedPadWidthLimitAtPoint(n,i);0===e\u0026\u0026(r=this.getSmallerLimit(r,this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(n,o))),e+1===t.route.length-1\u0026\u0026(s=this.getSmallerLimit(s,this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(n,i)));const a=r,c=s;if((null===a||o.width\u003c=a+Mq)\u0026\u0026(null===c||i.width\u003c=c+Mq))return!1;const l=o.width,d=i.width;if(null!==a\u0026\u0026(o.width=Math.min(o.width,a)),null!==c\u0026\u0026(i.width=Math.min(i.width,c)),null!==a\u0026\u0026null===c)this.insertPadBoundaryTransition(t,e,n,\"start\",o.width,d);else if(null===a\u0026\u0026null!==c)this.insertPadBoundaryTransition(t,e,n,\"end\",i.width,l);else if(null!==a\u0026\u0026null!==c){const r=this.obstacleIndex.getConnectedPadBoundaryPoint(n,\"start\"),s=this.obstacleIndex.getConnectedPadBoundaryPoint(n,\"end\");r\u0026\u0026s\u0026\u0026(this.insertPadBoundaryTransition(t,e,n,\"start\",o.width,d),this.insertPadBoundaryTransition(t,e+2,n,\"end\",i.width,l))}return this.totalWidthReduction+=l-o.width+(d-i.width),this.repairedPadNeckSegmentCount++,this.obstacleIndex=this.createConservativeObstacleIndex(),this.routeCursor=Math.max(0,e-1),!0}getSmallerLimit(t,e){return null===t?e:null===e?t:Math.min(t,e)}insertPadBoundaryTransition(t,e,n,o,i,r){const s=this.obstacleIndex.getConnectedPadBoundaryPoint(n,o);if(!s)return;const a=\"start\"===o?n.start:n.end,c=\"start\"===o?n.end:n.start,l=Math.hypot(c.x-a.x,c.y-a.y);if(l\u003c=1e-9)return;const d=Math.min(1e-6,l/4),h=(c.x-a.x)/l,u=(c.y-a.y)/l,p={route_type:\"wire\",x:s.x-h*d,y:s.y-u*d,width:i,layer:n.layer},m={...p,x:s.x+h*d,y:s.y+u*d,width:r},g=\"start\"===o?t.route[e+1]:t.route[e],f=\"start\"===o?t.route[e+2]:t.route[e-1];if($J(g)\u0026\u0026\"via\"===f?.route_type){const e=this.resolveNominalTraceWidth(t);this.obstacleIndex.collides({...n,start:g,end:m,width:e})||(g.width=Math.max(g.width,e),m.width=g.width)}t.route.splice(e+1,0,...\"start\"===o?[p,m]:[m,p])}resolveNominalTraceWidth(t){const e=this.nominalWidthByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e;const n=new Set(this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t))),o=this.inputProblem.simpleRouteJson.connections.find(t=\u003ethis.connectionNameResolver.canonicalize([t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))).some(t=\u003en.has(t))),i=Math.max(o?.nominalTraceWidth??o?.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.minimumTraceWidth,this.minimumTraceWidth);return this.nominalWidthByTraceId.set(t.pcb_trace_id,i),i}segmentHasForeignTraceCollision(t,e){const n=this.traceIndices[this.traceCursor],o=void 0===n?void 0:this.traces[n],i=o?.route[t],r=o?.route[t+1];return!!(o\u0026\u0026$J(i)\u0026\u0026$J(r)\u0026\u0026i.layer===r.layer)\u0026\u0026this.obstacleIndex.findCollisions({start:i,end:r,layer:i.layer,width:e,connectionNames:this.getTraceConnectionNames(o),ignoreTraceIndex:n,ignoreRouteRange:{start:t,end:t+1}}).some(t=\u003e\"trace\"===t.kind\u0026\u0026void 0!==t.traceIndex\u0026\u0026t.traceIndex!==n)}createConservativeObstacleIndex(){const t=structuredClone(this.traces);for(const e of t)for(let t=0;t\u003ce.route.length-1;t++){const n=e.route[t],o=e.route[t+1];$J(n)\u0026\u0026$J(o)\u0026\u0026n.layer===o.layer\u0026\u0026(n.width=Math.max(n.width,o.width))}return new tJ(this.inputProblem.simpleRouteJson,t,void 0,[],this.connectionNameResolver)}getTraceConnectionNames(t){return[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=\u003eBoolean(t))}ensureConnectivitySafeOutput(){if(!this.connectivityFinalized){this.connectivityFinalized=!0,this.connectivityValidationCount++;try{const t=this.connectivityInvariant.validate(this.traces);if(this.connectivityValidationError??=t.validationError??null,t.safe)return;this.connectivityRegressionEndpointIds=[...new Set(t.regressions.flatMap(t=\u003et.baselineEndpointLabels))]}catch(t){this.connectivityValidationError=t instanceof Error?t.message:String(t)}this.connectivityRollbackCount++,this.connectivityRollbackMutationStats={repairedSegmentCount:this.repairedSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,totalWidthReduction:this.totalWidthReduction},this.repairedSegmentCount=0,this.repairedPadNeckSegmentCount=0,this.totalWidthReduction=0,this.traces=structuredClone(this.initialConnectivitySafeTraces),this.obstacleIndex=this.createConservativeObstacleIndex()}}createStats(){return{phase:this.solved?\"complete\":\"repair-trace-clearance\",budgetLimited:this.budgetLimited,completionReason:this.solved?this.connectivityRollbackCount\u003e0?\"connectivity_rollback\":this.budgetLimited?\"iteration_budget\":this.connectivityValidationError?\"connectivity_validation_unavailable\":\"completed\":null,resultStatus:this.connectivityRollbackCount\u003e0||this.budgetLimited||null!==this.connectivityValidationError?\"best_effort\":\"complete\",traceCursor:this.traceCursor,traceCount:this.traceIndices.length,traceIndex:this.traceIndices[this.traceCursor],routeCursor:this.routeCursor,repairedSegmentCount:this.repairedSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,unresolvedSegmentCount:this.unresolvedSegmentCount,totalWidthReduction:this.totalWidthReduction,connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){return this.solved||0===this.traceIndices.length?1:Math.min(.99,this.traceCursor/this.traceIndices.length)}tryFinalAcceptance(){this.ensureConnectivitySafeOutput(),this.budgetLimited=!0,this.solved=!0,this.progress=1,this.stats=this.createStats()}getConstructorParams(){return[this.inputProblem]}getOutput(){return structuredClone(this.solved?this.traces:this.initialConnectivitySafeTraces)}visualize(){const t=[];for(let e=0;e\u003cthis.traces.length;e++){const n=this.traces[e];for(let o=0;o\u003cn.route.length-1;o++){const i=n.route[o],r=n.route[o+1];$J(i)\u0026\u0026$J(r)\u0026\u0026i.layer===r.layer\u0026\u0026t.push({points:[i,r],strokeColor:e===this.traceIndices[this.traceCursor]\u0026\u0026o===this.routeCursor?\"#ff7400\":\"bottom\"===i.layer?\"#376fc4\":\"#777\",strokeWidth:Math.max(i.width,r.width)})}}return{coordinateSystem:\"cartesian\",title:\"Power trace direction-independent clearance repair\",lines:t,points:[],circles:[],rects:[],texts:[]}}},XJ=[{x:0,y:0},{x:.5,y:0},{x:0,y:.5},{x:.5,y:.5}],VJ=[{offset:{x:0,y:0},strictNecking:!0},{offset:{x:.5,y:.5},strictNecking:!0},{offset:{x:0,y:0},strictNecking:!1},{offset:{x:.5,y:.5},strictNecking:!1}],WJ=t=\u003e[...new Set(t.map(t=\u003eNumber(t.toFixed(6))))].sort((t,e)=\u003ee-t),HJ=t=\u003e\"wire\"===t?.route_type,GJ=class extends Sq{inputProblem;options;traces;obstacleIndex;connectionNameResolver;connectionByTraceId=new Map;connectivityInvariant;lastConnectivitySafeTraces;traceOrder;selectedOwnedTraceIndices;selectedCleanupTraceIndices;selectedViaRepairTraceIndices;mutableBlockerTraceIndices;immutableTraceIndices;initialImmutableTraceSignatures=new Map;traceOrderCursor=-1;maxPassCount=4;previousWidthDeficit=0;passIndex=0;completedPassCount=0;lastNormalizedWidthDeficitGain=0;normalizedWidthDeficitGainByPass=[];plateauReached=!1;phase=\"scan-trace\";traceIndex=-1;routeSegmentIndex=0;nominalTraceWidth=0;currentIntervals=[];intervalCursor=0;candidateWidths=[];widthCursor=0;gridResolutions=[];resolutionCursor=0;offsetCursor=0;keptTraceCount=0;recreatedTraceCount=0;expandedSegmentCount=0;intermediateExpandedSegmentCount=0;pathWidthUpgradeCount=0;inPlaceWidthProbeCount=0;reroutedSegmentCount=0;unresolvedSegmentCount=0;attemptedGridCount=0;attemptedLayerGridCount=0;attemptedInflationCount=0;pushedTraceCount=0;elasticPushedTraceCount=0;layerReroutedTraceCount=0;insertedViaCount=0;neckedLayerSegmentCount=0;removedViaPairCount=0;removedViaCount=0;simplifiedPathCount=0;normalizedSegmentCount=0;cleanupClearanceShoveCount=0;relocatedViaCount=0;unresolvedViaCount=0;initialImmutableViaViolationCount=0;remainingImmutableViaViolationCount=0;initialImmutableViaViolationPairCount=0;remainingImmutableViaViolationPairCount=0;immutableTraceMutationIds=[];lastSafeImmutableViaViolationSignatures=new Set;immutableViaViolationRollbackCount=0;attemptedImmutableViaViolationCount=null;attemptedImmutableViaViolationPairCount=null;immutableViaViolationRegressionIds=[];padClearanceRerouteCount=0;unresolvedPadClearanceCount=0;repairedTraceClearanceSegmentCount=0;repairedPadNeckSegmentCount=0;unresolvedTraceClearanceSegmentCount=0;sameNetContactRejectionCount=0;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRollbackPhases=[];immutableSafetyRollbackCount=0;immutableSafetyRollbackPhases=[];connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;immutableSafetyRollbackMutationStats=null;discardedExpansionMutationStats=null;initialPadClearanceViolationCount=0;remainingPadClearanceViolationCount=0;initialPadClearanceViolationCountByClearance={};remainingPadClearanceViolationCountByClearance={};budgetLimitedExpansion=!1;finalAcceptanceUsed=!1;cleanupCompleted=!1;clearanceRepairCompleted=!1;cleanupBestEffortAccepted=!1;clearanceRepairBestEffortAccepted=!1;cleanupIterationBudget=0;clearanceRepairIterationBudget=0;expansionPushedTraceIndices=new Set;cleanupMutatedTraceIndices=[];failedSubSolverCount=0;inflationAttemptsBySegment=new Map;layerAttemptCountByTrace=new Map;layerRerouteCountByTrace=new Map;activeInflationKey=null;activeInflationWidth=null;layerAttempt=null;pendingLayerOutput=null;pendingLayerPushCount=0;constructor(t,e={}){super(),this.inputProblem=structuredClone(t),this.options=structuredClone(e),this.traces=structuredClone(t.traces??[]),this.connectionNameResolver=new Pq(this.inputProblem,this.traces),this.lastConnectivitySafeTraces=structuredClone(this.traces),this.connectivityInvariant=new OJ(this.inputProblem,this.lastConnectivitySafeTraces);const n=e.onlyConnectionNames?new Set(this.connectionNameResolver.canonicalize([...e.onlyConnectionNames])):null,o=this.traces.flatMap((t,e)=\u003e{if(!n)return[e];return this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t)).some(t=\u003en.has(t))?[e]:[]}),i=new Map(o.map(t=\u003e[t,this.getInitialTracePriority(this.traces[t])]));this.traceOrder=o.sort((t,e)=\u003ei.get(e)-i.get(t)||t-e),this.selectedOwnedTraceIndices=this.traceOrder.filter(t=\u003ethis.findConnectionForTrace(this.traces[t])),this.selectedCleanupTraceIndices=[...this.selectedOwnedTraceIndices],this.selectedViaRepairTraceIndices=[...this.selectedOwnedTraceIndices],this.mutableBlockerTraceIndices=this.traces.flatMap((t,e)=\u003ethis.findConnectionForTrace(t)?[e]:[]);const r=new Set(this.mutableBlockerTraceIndices);this.immutableTraceIndices=this.traces.flatMap((t,e)=\u003er.has(e)?[]:(this.initialImmutableTraceSignatures.set(e,JSON.stringify(t)),[e])),this.previousWidthDeficit=this.calculateWidthDeficit().deficit,this.obstacleIndex=new tJ(this.inputProblem,this.traces,this.traceIndex\u003e=0?this.traceIndex:void 0,[],this.connectionNameResolver),this.lastSafeImmutableViaViolationSignatures=this.getImmutableViaViolationSignatures(this.traces),this.initialImmutableViaViolationCount=this.countViolatingImmutableVias(this.lastSafeImmutableViaViolationSignatures),this.remainingImmutableViaViolationCount=this.initialImmutableViaViolationCount,this.initialImmutableViaViolationPairCount=this.lastSafeImmutableViaViolationSignatures.size,this.remainingImmutableViaViolationPairCount=this.initialImmutableViaViolationPairCount,this.activeSubSolver=null,this.MAX_ITERATIONS=8e6,this.stats=this.createStats()}getSolverName(){return\"PowerTraceExpanderSolver\"}_step(){if(this.shouldStartBudgetFinalization())return this.startBudgetFinalization(),void(this.stats=this.createStats());if(this.activeSubSolver)return this.stepActiveGridSolver(),void(this.stats=this.createStats());switch(this.phase){case\"scan-trace\":this.scanNextTrace();break;case\"evaluate-segment\":this.evaluateNextSegment();break;case\"try-trace-inflation\":case\"cleanup\":case\"repair-trace-clearance\":break;case\"try-layer-candidate\":this.startNextLayerCandidate();break;case\"try-grid-candidate\":this.startNextGridCandidate();break;case\"complete\":this.acceptConnectivityCheckpoint(this.traces,\"final\"),this.solved=!0}this.stats=this.createStats()}scanNextTrace(){if(this.traceOrderCursor++,this.routeSegmentIndex=0,this.traceOrderCursor\u003e=this.traceOrder.length)return void this.finishOrStartNextPass();this.traceIndex=this.traceOrder[this.traceOrderCursor];const t=this.traces[this.traceIndex];this.findConnectionForTrace(t)?(this.nominalTraceWidth=this.resolveNominalTraceWidth(t),this.traceMeetsNominalWidth(t,this.nominalTraceWidth)?this.keptTraceCount++:(this.rebuildObstacleIndex(),t.route=function(t,e){if(t.length\u003c2)return t.map(t=\u003e({...t}));const n=[];for(let o=0;o\u003ct.length-1;o++){const i=t[o],r=t[o+1];if(n.push({...i}),\"wire\"!==i.route_type||\"wire\"!==r.route_type||i.layer!==r.layer||i.width\u003e=e-Mq)continue;const s=Nq(i,r),a=Math.max(1,Math.ceil(s/e));for(let t=1;t\u003ca;t++){const e=t/a;n.push({route_type:\"wire\",x:i.x+(r.x-i.x)*e,y:i.y+(r.y-i.y)*e,width:i.width,layer:i.layer})}}return n.push({...t[t.length-1]}),n}(t.route,this.nominalTraceWidth),this.recreatedTraceCount++,this.phase=\"evaluate-segment\")):this.keptTraceCount++}finishOrStartNextPass(){const{deficit:t,nominalArea:e}=this.calculateWidthDeficit(),n=this.previousWidthDeficit-t;if(this.lastNormalizedWidthDeficitGain=e\u003c=Mq?0:n/e,this.normalizedWidthDeficitGainByPass.push(this.lastNormalizedWidthDeficitGain),this.plateauReached=this.lastNormalizedWidthDeficitGain\u003c.001,this.completedPassCount=this.passIndex+1,this.passIndex+1\u003cthis.maxPassCount\u0026\u0026this.lastNormalizedWidthDeficitGain\u003e=.001)return this.previousWidthDeficit=t,this.passIndex++,this.traceOrderCursor=-1,this.traceIndex=-1,this.routeSegmentIndex=0,this.inflationAttemptsBySegment.clear(),void(this.phase=\"scan-trace\");this.startCleanup()}startCleanup(){this.acceptConnectivityCheckpoint(this.traces,\"expansion\"),this.traceIndex=this.traces.length,this.phase=\"cleanup\";const t=new jJ({simpleRouteJson:this.inputProblem,traces:this.traces,traceIndices:this.selectedCleanupTraceIndices,viaRepairTraceIndices:this.selectedViaRepairTraceIndices,mutableTraceIndices:this.mutableBlockerTraceIndices,maxRerouteLength:10,desiredPadClearance:this.options.powerTraceToPadClearance}),e=this.getRemainingParentIterationsAfterCurrentStep(),n=0===e?0:Math.max(1,Math.floor(.75*e));t.MAX_ITERATIONS=Math.min(t.MAX_ITERATIONS,n),this.cleanupIterationBudget=t.MAX_ITERATIONS,this.activeSubSolver=t}shouldStartBudgetFinalization(){return!this.budgetLimitedExpansion\u0026\u0026(\"cleanup\"!==this.phase\u0026\u0026\"repair-trace-clearance\"!==this.phase\u0026\u0026\"complete\"!==this.phase\u0026\u0026this.iterations\u003e=this.getExpansionIterationBudget())}getFinalizationIterationReserve(){return Math.min(Math.max(0,this.MAX_ITERATIONS-1),Math.max(1,Math.floor(.125*this.MAX_ITERATIONS)))}getExpansionIterationBudget(){return Math.max(1,this.MAX_ITERATIONS-this.getFinalizationIterationReserve())}startBudgetFinalization(){this.budgetLimitedExpansion=!0,this.activeSubSolver=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.activeInflationKey=null,this.activeInflationWidth=null,this.layerAttempt=null,this.discardInFlightExpansion(),this.startCleanup()}discardInFlightExpansion(){this.discardedExpansionMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}rollbackConnectivityRegressedExpansion(){this.connectivityRollbackMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}rollbackImmutableUnsafeExpansion(){this.immutableSafetyRollbackMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}captureAndResetExpansionMutationStats(){const t={recreatedTraceCount:this.recreatedTraceCount,expandedSegmentCount:this.expandedSegmentCount,intermediateExpandedSegmentCount:this.intermediateExpandedSegmentCount,pathWidthUpgradeCount:this.pathWidthUpgradeCount,reroutedSegmentCount:this.reroutedSegmentCount,pushedTraceCount:this.pushedTraceCount,elasticPushedTraceCount:this.elasticPushedTraceCount,layerReroutedTraceCount:this.layerReroutedTraceCount,insertedViaCount:this.insertedViaCount,neckedLayerSegmentCount:this.neckedLayerSegmentCount};return this.recreatedTraceCount=0,this.expandedSegmentCount=0,this.intermediateExpandedSegmentCount=0,this.pathWidthUpgradeCount=0,this.reroutedSegmentCount=0,this.pushedTraceCount=0,this.elasticPushedTraceCount=0,this.layerReroutedTraceCount=0,this.insertedViaCount=0,this.neckedLayerSegmentCount=0,this.expansionPushedTraceIndices.clear(),t}restoreLastConnectivitySafeTraces(){this.traces=structuredClone(this.lastConnectivitySafeTraces),this.rebuildObstacleIndex()}getRemainingParentIterationsAfterCurrentStep(){return Math.max(0,this.MAX_ITERATIONS-this.iterations-1)}calculateWidthDeficit(){let t=0,e=0;for(const n of this.traceOrder){const o=this.traces[n];if(!this.findConnectionForTrace(o))continue;const i=this.resolveNominalTraceWidth(o);for(let n=0;n\u003co.route.length-1;n++){const r=o.route[n],s=o.route[n+1];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)continue;const a=Nq(r,s),c=r.width;e+=a*i,t+=a*Math.max(0,i-c)}}return{deficit:t,nominalArea:e}}getInitialTracePriority(t){const e=this.resolveNominalTraceWidth(t);let n=0;for(let o=0;o\u003ct.route.length-1;o++){const i=t.route[o],r=t.route[o+1];HJ(i)\u0026\u0026HJ(r)\u0026\u0026i.layer===r.layer\u0026\u0026(n+=Nq(i,r)*Math.max(0,e-Math.min(i.width,r.width)))}return e*n}evaluateNextSegment(){const t=this.traces[this.traceIndex];if(!t)return void(this.phase=\"scan-trace\");const e=this.findNextUnderWidthSegment(t,this.routeSegmentIndex,this.nominalTraceWidth);if(-1===e)return void(this.phase=\"scan-trace\");this.routeSegmentIndex=e;const n=t.route[e],o=t.route[e+1];if(!HJ(n)||!HJ(o))return void this.routeSegmentIndex++;const i=this.getTraceConnectionNames(t),r=Math.min(n.width,o.width),s=this.findMaximumSafeInPlaceWidth(t,e,i);if(s\u003er+Mq){if(n.width=Math.max(n.width,s),o.width=Math.max(o.width,s),s\u003e=this.nominalTraceWidth-Mq)return this.expandedSegmentCount++,void this.routeSegmentIndex++;this.intermediateExpandedSegmentCount++}this.startTraceInflation(t,e)||this.prepareLayerRouteAttempt(t,e)||this.prepareRegularGridCandidates(t,e)}prepareRegularGridCandidates(t,e){if(this.currentIntervals=this.getExponentialIntervalCandidates(t,e,this.nominalTraceWidth),this.intervalCursor=0,this.candidateWidths=this.getCandidateWidths(this.nominalTraceWidth),this.widthCursor=0,this.gridResolutions=[],this.resolutionCursor=0,this.offsetCursor=0,0===this.currentIntervals.length)return this.unresolvedSegmentCount++,void this.routeSegmentIndex++;this.phase=\"try-grid-candidate\"}prepareLayerRouteAttempt(t,e){if(this.nominalTraceWidth\u003c.499999)return!1;const n=!1!==this.options.allowNewVias\u0026\u0026this.inputProblem.layerCount\u003e=2,o=n?2:this.maxPassCount,i=this.layerAttemptCountByTrace.get(this.traceIndex)??0,r=this.layerRerouteCountByTrace.get(this.traceIndex)??0;if(r\u003e=o||i\u003e=o||i\u003ethis.passIndex||i\u003e0\u0026\u00260===r)return!1;const s=t.route[e],a=t.route[e+1];if(!HJ(s)||!HJ(a)||Math.min(s.width,a.width)\u003e=.5*this.nominalTraceWidth-Mq)return!1;const c=this.getExponentialIntervalCandidates(t,e,this.nominalTraceWidth).filter(e=\u003ethis.intervalSupportsLayerRouting(t,e)).sort((e,n)=\u003en.endIndex-e.endIndex||e.startIndex-n.startIndex||this.getRouteIntervalLength(t,n.startIndex,n.endIndex)-this.getRouteIntervalLength(t,e.startIndex,e.endIndex))[0];if(!c)return!1;const l=this.getRouteQuality(t.route.slice(c.startIndex,c.endIndex+1));if(l.deficitArea\u003cthis.nominalTraceWidth)return!1;if(i\u003e0\u0026\u0026l.deficitArea/Math.max(l.length,Mq)\u003c.25)return!1;const d=t.route[c.startIndex],h=t.route[c.endIndex],u=this.getTraceConnectionNames(t),p=n?this.getEndpointLayers(d,u):[d.layer],m=n?this.getEndpointLayers(h,u):[h.layer],g=Math.min(this.nominalTraceWidth,Math.max(d.width,this.findMaximumSafeInPlaceWidth(t,c.startIndex,u))),f=Math.min(this.nominalTraceWidth,Math.max(h.width,this.findMaximumSafeInPlaceWidth(t,c.endIndex-1,u))),y=this.getSoftTraceIndices(this.nominalTraceWidth);return this.layerAttemptCountByTrace.set(this.traceIndex,i+1),this.layerAttempt={interval:c,minViaCount:n?1:0,maxViaCount:n?2:0,candidateWidths:[this.nominalTraceWidth],widthCursor:0,gridResolutions:[Rq(this.nominalTraceWidth/4,.2,.3)],resolutionCursor:0,offsetCursor:0,startLayers:p,endLayers:m,startNeckWidth:g,endNeckWidth:f,softTraceIndices:y},this.phase=\"try-layer-candidate\",!0}intervalSupportsLayerRouting(t,e){if(e.startIndex\u003e=e.endIndex)return!1;for(let n=e.startIndex;n\u003c=e.endIndex;n++){const e=t.route[n];if(!HJ(e))return!1}const n=t.route[e.startIndex],o=t.route[e.endIndex];return n.layer===o.layer}getEndpointLayers(t,e){return[...new Set([t.layer,...this.obstacleIndex.getConnectedLayersAtPoint({x:t.x,y:t.y},e)])].filter(t=\u003ethis.obstacleIndex.boardLayers.includes(t))}getSoftTraceIndices(t){const e=[];for(let n=0;n\u003cthis.traces.length;n++){if(n===this.traceIndex)continue;const o=this.traces[n],i=this.findConnectionForTrace(o);if(!i)continue;Math.max(i.nominalTraceWidth??i.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth,this.inputProblem.minTraceWidth)\u003ct-Mq\u0026\u0026e.push(n)}return e}startNextLayerCandidate(){const t=this.layerAttempt,e=this.traces[this.traceIndex];if(!t||!e)return this.layerAttempt=null,void(this.phase=\"evaluate-segment\");if(t.widthCursor\u003e=t.candidateWidths.length){const t=this.routeSegmentIndex;return this.layerAttempt=null,void this.prepareRegularGridCandidates(e,t)}const n=t.candidateWidths[t.widthCursor];if(0===t.gridResolutions.length\u0026\u0026(t.gridResolutions=this.getGridResolutions(n)),t.resolutionCursor\u003e=t.gridResolutions.length)return t.widthCursor++,t.gridResolutions=[],t.resolutionCursor=0,void(t.offsetCursor=0);if(t.offsetCursor\u003e=VJ.length)return t.resolutionCursor++,void(t.offsetCursor=0);const o=e.route[t.interval.startIndex],i=e.route[t.interval.endIndex];if(!HJ(o)||!HJ(i))return this.layerAttempt=null,void this.prepareRegularGridCandidates(e,this.routeSegmentIndex);const r=t.gridResolutions[t.resolutionCursor],s=VJ[t.offsetCursor],a=s.offset,c=Math.min(t.startNeckWidth,t.endNeckWidth),l=this.inputProblem.min_via_hole_diameter??this.inputProblem.minViaHoleDiameter??.3,d=Math.max(l,this.inputProblem.min_via_pad_diameter??this.inputProblem.minViaPadDiameter??this.inputProblem.minViaDiameter??.6),h=Math.max(this.inputProblem.minTraceWidth,Math.min(s.strictNecking?t.startNeckWidth:c,n)),u=Math.max(this.inputProblem.minTraceWidth,Math.min(s.strictNecking?t.endNeckWidth:c,n)),p=Rq(3*this.nominalTraceWidth,1.5,3);t.maxViaCount\u003e0?this.attemptedLayerGridCount++:this.attemptedGridCount++,this.activeSubSolver=new Yq({start:o,end:i,originalStartLayer:o.layer,originalEndLayer:i.layer,startLayers:t.startLayers,endLayers:t.endLayers,layers:this.obstacleIndex.boardLayers,traceWidth:n,startNeckWidth:h,endNeckWidth:u,maxStartNeckLength:p,maxEndNeckLength:p,neckPenaltyExponent:s.strictNecking?2:1,viaDiameter:d,viaHoleDiameter:l,minViaCount:t.minViaCount,maxViaCount:t.maxViaCount,viaCost:Math.max(1,2*this.nominalTraceWidth),gridSize:r,gridOffset:{x:a.x*r,y:a.y*r},connectionNames:this.getTraceConnectionNames(e),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,t.interval.startIndex-1),end:Math.min(e.route.length-1,t.interval.endIndex+1)},softTraceIndices:t.softTraceIndices,fixedVias:this.getFixedViasOutsideInterval(e,t.interval),bounds:this.inputProblem.bounds,obstacleClearance:this.getDesiredPadClearance(n),searchPadding:Math.min(5,Math.max(2.5,Nq(o,i)/2,4*n))})}startNextGridCandidate(){const t=this.traces[this.traceIndex];if(!t)return void(this.phase=\"scan-trace\");if(this.widthCursor\u003e=this.candidateWidths.length)return this.unresolvedSegmentCount++,this.routeSegmentIndex++,void(this.phase=\"evaluate-segment\");if(this.intervalCursor\u003e=this.currentIntervals.length)return this.widthCursor++,this.intervalCursor=0,this.gridResolutions=[],this.resolutionCursor=0,void(this.offsetCursor=0);const e=this.candidateWidths[this.widthCursor],n=t.route[this.routeSegmentIndex],o=t.route[this.routeSegmentIndex+1];if(HJ(n)\u0026\u0026HJ(o)\u0026\u0026e\u003c=Math.min(n.width,o.width)+Mq)return void(this.widthCursor=this.candidateWidths.length);if(0===this.gridResolutions.length\u0026\u0026(this.gridResolutions=this.getGridResolutions(e)),this.resolutionCursor\u003e=this.gridResolutions.length)return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);if(this.offsetCursor\u003e=XJ.length)return this.resolutionCursor++,void(this.offsetCursor=0);const i=this.currentIntervals[this.intervalCursor],r=t.route[i.startIndex],s=t.route[i.endIndex];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);if(this.endpointCollides(t,i,r,e)||this.endpointCollides(t,i,s,e))return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);const a=this.gridResolutions[this.resolutionCursor],c=XJ[this.offsetCursor],l={x:c.x*a,y:c.y*a};this.attemptedGridCount++,this.activeSubSolver=new Qq({start:r,end:s,layer:r.layer,traceWidth:e,gridSize:a,gridOffset:l,connectionNames:this.getTraceConnectionNames(t),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,i.startIndex-1),end:Math.min(t.route.length-1,i.endIndex+1)},bounds:this.inputProblem.bounds,obstacleClearance:this.getDesiredPadClearance(e),searchPadding:Math.min(5,Math.max(1.5,Nq(r,s)/2,3*e))})}endpointCollides(t,e,n,o){return this.obstacleIndex.collides({start:n,end:n,layer:n.layer,width:o,connectionNames:this.getTraceConnectionNames(t),ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,e.startIndex-1),end:Math.min(t.route.length-1,e.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(o)})}stepActiveGridSolver(){if(this.activeSubSolver instanceof YJ)return void this.stepActiveTraceClearanceRepairSolver();if(this.activeSubSolver instanceof jJ)return void this.stepActiveCleanupSolver();if(this.activeSubSolver instanceof oJ)return void this.stepActiveInflationSolver();if(this.activeSubSolver instanceof Yq)return void this.stepActiveLayerSolver();const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e){const t=this.gridRouteReplacementCollides(e)||this.gridRouteBoundaryCollides(e);if(!t\u0026\u0026this.gridRoutePreservesSameNetContacts(e))return this.applyGridRoute(this.maximizeGridRouteWidth(e)),void(this.activeSubSolver=null);t||this.sameNetContactRejectionCount++}}this.retainFailedSubSolver(t),this.activeSubSolver=null,this.offsetCursor++}}stepActiveCleanupSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved)return this.adoptCleanupOutput(t),this.activeSubSolver=null,void this.startTraceClearanceRepair();this.retainFailedSubSolver(t),this.activeSubSolver=null,this.startTraceClearanceRepair()}}adoptCleanupOutput(t){const e=this.acceptConnectivityCheckpoint(t.getOutput(),\"cleanup\");this.cleanupCompleted=!t.budgetLimited;const n=t.stats;this.connectivityValidationError??=n.connectivityValidationError??null,this.connectivityValidationCount+=Number(n.connectivityValidationCount??0);const o=Number(n.connectivityRollbackCount??0);o\u003e0\u0026\u0026(this.connectivityRollbackCount+=o,this.connectivityRollbackPhases.includes(\"cleanup\")||this.connectivityRollbackPhases.push(\"cleanup\"),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...n.connectivityRegressionEndpointIds??[]])]);const i=e\u0026\u00260===o;this.cleanupBestEffortAccepted=t.budgetLimited\u0026\u0026i,this.cleanupMutatedTraceIndices=i?[...n.mutatedTraceIndices??[]]:[],this.removedViaPairCount=i?Number(n.viaPairCountRemoved??0):0,this.removedViaCount=i?Number(n.viaCountRemoved??0):0,this.simplifiedPathCount=i?Number(n.simplifiedPathCount??0):0,this.normalizedSegmentCount=i?Number(n.normalizedSegmentCount??0):0,this.cleanupClearanceShoveCount=i?Number(n.committedClearanceShoveCount??0):0,this.relocatedViaCount=i?Number(n.relocatedViaCount??0):0,this.unresolvedViaCount=Number(n.unresolvedViaCount??0),this.padClearanceRerouteCount=i?Number(n.padClearanceRerouteCount??0):0,this.unresolvedPadClearanceCount=Number(n.unresolvedPadClearanceCount??0),this.initialPadClearanceViolationCount=Number(n.initialPadClearanceViolationCount??0),this.remainingPadClearanceViolationCount=Number(n.remainingPadClearanceViolationCount??0),this.initialPadClearanceViolationCountByClearance={...n.initialPadClearanceViolationCountByClearance??{}},this.remainingPadClearanceViolationCountByClearance={...n.remainingPadClearanceViolationCountByClearance??{}},this.rebuildObstacleIndex()}startTraceClearanceRepair(){this.phase=\"repair-trace-clearance\";const t=[...new Set([...this.getOwnedTraceIndices(),...this.expansionPushedTraceIndices,...this.cleanupMutatedTraceIndices])],e=new YJ({simpleRouteJson:this.inputProblem,traces:this.traces,traceIndices:t});e.MAX_ITERATIONS=Math.min(e.MAX_ITERATIONS,this.getRemainingParentIterationsAfterCurrentStep()),this.clearanceRepairIterationBudget=e.MAX_ITERATIONS,this.activeSubSolver=e}stepActiveTraceClearanceRepairSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved)return this.adoptClearanceRepairOutput(t),this.activeSubSolver=null,void(this.phase=\"complete\");this.retainFailedSubSolver(t),this.activeSubSolver=null,this.phase=\"complete\"}}adoptClearanceRepairOutput(t){const e=this.acceptConnectivityCheckpoint(t.getOutput(),\"clearance-repair\");this.clearanceRepairCompleted=!t.budgetLimited;const n=t.stats;this.connectivityValidationError??=n.connectivityValidationError??null,this.connectivityValidationCount+=Number(n.connectivityValidationCount??0);const o=Number(n.connectivityRollbackCount??0);o\u003e0\u0026\u0026(this.connectivityRollbackCount+=o,this.connectivityRollbackPhases.includes(\"clearance-repair\")||this.connectivityRollbackPhases.push(\"clearance-repair\"),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...n.connectivityRegressionEndpointIds??[]])]);const i=e\u0026\u00260===o;this.clearanceRepairBestEffortAccepted=t.budgetLimited\u0026\u0026i,this.repairedTraceClearanceSegmentCount=i?Number(n.repairedSegmentCount??0):0,this.repairedPadNeckSegmentCount=i?Number(n.repairedPadNeckSegmentCount??0):0,this.unresolvedTraceClearanceSegmentCount=Number(n.unresolvedSegmentCount??0),this.rebuildObstacleIndex()}stepActiveLayerSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e){const t=!this.layerRouteReplacementCollides(e,!0)\u0026\u0026this.layerRouteImprovesInterval(e),n=t\u0026\u0026this.layerRoutePreservesSameNetContacts(e);if(n){if(this.activeSubSolver=null,this.pendingLayerOutput=e,this.pendingLayerPushCount=0,!this.layerRouteReplacementCollides(e,!1))return void this.applyLayerRoute(e);if(this.startPendingLayerInflation())return;this.pendingLayerOutput=null}t\u0026\u0026!n\u0026\u0026this.sameNetContactRejectionCount++}}this.retainFailedSubSolver(t),this.activeSubSolver=null,this.layerAttempt\u0026\u0026this.layerAttempt.offsetCursor++,this.phase=\"try-layer-candidate\"}}layerRouteReplacementCollides(t,e){const n=this.traces[this.traceIndex],o=this.layerAttempt;if(!n||!o)return!0;const i=this.getTraceConnectionNames(n),r=e?o.softTraceIndices:void 0,s={start:Math.max(0,o.interval.startIndex-1),end:Math.min(n.route.length-1,o.interval.endIndex+1)},a=this.getFixedViasOutsideInterval(n,o.interval);for(let e=0;e\u003ct.route.length;e++){const n=t.route[e];if(\"via\"===n?.route_type){if(this.obstacleIndex.collidesVia({point:n,layers:this.obstacleIndex.boardLayers,padDiameter:n.via_diameter??.6,holeDiameter:n.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,connectionNames:i,ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:r,otherNewViaPoints:t.route.slice(0,e).filter(t=\u003e\"via\"===t.route_type).map(t=\u003e({x:t.x,y:t.y})),fixedVias:a,ignoreRouteRange:s,obstacleClearance:this.getDesiredPadClearance(t.traceWidth),blockSameNetObstacles:!0,sameNetObstacleClearance:0}))return!0;continue}const o=t.route[e+1];if(\"wire\"===n?.route_type\u0026\u0026\"wire\"===o?.route_type\u0026\u0026n.layer===o.layer\u0026\u0026this.obstacleIndex.collides({start:n,end:o,layer:n.layer,width:Math.max(n.width,o.width),connectionNames:i,ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:r,ignoreRouteRange:s,obstacleClearance:this.getDesiredPadClearance(t.traceWidth)}))return!0}return this.layerRouteBoundaryCollides(t,e)}getFixedViasOutsideInterval(t,e){return t.route.flatMap((t,n)=\u003e\"via\"!==t.route_type||n\u003e=e.startIndex\u0026\u0026n\u003c=e.endIndex?[]:[{point:{x:t.x,y:t.y},padDiameter:t.via_diameter??.6,holeDiameter:t.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter}])}layerRouteBoundaryCollides(t,e){const n=this.traces[this.traceIndex],o=this.layerAttempt,i=t.route.find(t=\u003e\"wire\"===t.route_type);let r;for(let e=t.route.length-1;e\u003e=0;e--){const n=t.route[e];if(\"wire\"===n?.route_type){r=n;break}}if(!i||!r)return!0;const s=[{outside:n.route[o.interval.startIndex-1],inside:i},{outside:n.route[o.interval.endIndex+1],inside:r}];for(const i of s)if(HJ(i.outside)\u0026\u0026i.outside.layer===i.inside.layer\u0026\u0026this.obstacleIndex.collides({start:i.outside,end:i.inside,layer:i.inside.layer,width:Math.max(i.outside.width,i.inside.width),connectionNames:this.getTraceConnectionNames(n),ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:e?o.softTraceIndices:void 0,ignoreRouteRange:{start:Math.max(0,o.interval.startIndex-1),end:Math.min(n.route.length-1,o.interval.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(t.traceWidth)}))return!0;return!1}layerRouteImprovesInterval(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=this.getRouteQuality(e.route.slice(n.startIndex,n.endIndex+1)),i=this.getRouteQuality(t.route);return i.length\u003c=o.length+10+Mq\u0026\u0026i.deficitArea\u003c=o.deficitArea-Math.max(.05,.1*o.deficitArea)}getRouteQuality(t){let e=0,n=0;for(let o=0;o\u003ct.length-1;o++){const i=t[o],r=t[o+1];if(!HJ(i)||!HJ(r)||i.layer!==r.layer)continue;const s=Nq(i,r),a=Math.min(i.width,r.width);e+=s,n+=s*Math.max(0,this.nominalTraceWidth-a)}return{length:e,deficitArea:n}}getLayerInflationCorridor(t){const e=[];for(let n=0;n\u003ct.route.length;n++){const o=t.route[n];if(\"via\"===o?.route_type){for(const t of this.obstacleIndex.boardLayers)e.push({start:o,end:o,layer:t,width:o.via_diameter??.6});continue}const i=t.route[n+1];\"wire\"===o?.route_type\u0026\u0026\"wire\"===i?.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({start:o,end:i,layer:o.layer,width:Math.max(o.width,i.width)})}return e}startPendingLayerInflation(){const t=this.pendingLayerOutput;if(!t||this.pendingLayerPushCount\u003e=2)return!1;const e=this.getLayerInflationCorridor(t);return 0!==e.length\u0026\u0026(this.pendingLayerPushCount++,this.attemptedInflationCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem,traces:this.traces,powerTraceIndex:this.traceIndex,nominalPowerWidth:t.traceWidth,mutableTraceIndices:this.mutableBlockerTraceIndices,corridor:e,maxRerouteLength:10},this.connectionNameResolver),this.phase=\"try-trace-inflation\",!0)}applyLayerRoute(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=this.createLayerRouteReplacement(t);e.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...o),t.viaCount\u003e0\u0026\u0026this.layerReroutedTraceCount++,this.layerRerouteCountByTrace.set(this.traceIndex,(this.layerRerouteCountByTrace.get(this.traceIndex)??0)+1),this.reroutedSegmentCount++,this.insertedViaCount+=t.viaCount,t.viaCount\u003e0\u0026\u0026(this.neckedLayerSegmentCount+=o.filter(t=\u003e\"wire\"===t.route_type\u0026\u0026t.width\u003cthis.nominalTraceWidth-Mq).length),this.routeSegmentIndex=n.startIndex,this.currentIntervals=[],this.layerAttempt=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.phase=\"evaluate-segment\"}createLayerRouteReplacement(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=e.route[n.startIndex],i=e.route[n.endIndex],r=structuredClone(t.route),s=r.findIndex(t=\u003e\"wire\"===t.route_type);let a=-1;for(let t=r.length-1;t\u003e=0;t--)if(\"wire\"===r[t]?.route_type){a=t;break}return s\u003e=0\u0026\u0026(r[s]={...o,...r[s]}),a\u003e=0\u0026\u0026(r[a]={...i,...r[a]}),r}layerRoutePreservesSameNetContacts(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval;return this.routeReplacementPreservesSameNetContacts(e,n,this.createLayerRouteReplacement(t))}startTraceInflation(t,e){const n=t.route[e],o=t.route[e+1];if(!HJ(n)||!HJ(o))return!1;const i=Math.min(n.width,o.width),r=this.findBestPushableInflationWidth(t,e,i);if(!r)return!1;const s=this.getLocalInflationCorridor(t,e,r);if(0===s.length)return!1;const a=[this.traceIndex,n.x,n.y,o.x,o.y].join(\":\"),c=this.inflationAttemptsBySegment.get(a)??0;return!(c\u003e=2)\u0026\u0026(this.inflationAttemptsBySegment.set(a,c+1),this.activeInflationKey=a,this.activeInflationWidth=r,this.attemptedInflationCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem,traces:this.traces,powerTraceIndex:this.traceIndex,nominalPowerWidth:r,mutableTraceIndices:this.mutableBlockerTraceIndices,corridor:s,maxRerouteLength:10},this.connectionNameResolver),this.phase=\"try-trace-inflation\",!0)}hasOnlyPushableTraceBlockers(t,e,n){const o=Math.max(0,e-1),i=Math.min(t.route.length-2,e+1),r=new Set;for(let e=o;e\u003c=i;e++){const s=t.route[e],a=t.route[e+1];if(!HJ(s)||!HJ(a)||s.layer!==a.layer)continue;const c={start:s,end:a,layer:s.layer,width:n,connectionNames:this.getTraceConnectionNames(t),ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:o,end:i+1},obstacleClearance:this.getDesiredPadClearance(n)},l=this.obstacleIndex.findCollisions(c);if(0===l.length\u0026\u0026this.obstacleIndex.collides(c))return!1;for(const t of l){if(\"trace\"!==t.kind||void 0===t.traceIndex)return!1;const e=this.traces[t.traceIndex];if(!e)return!1;const o=this.findConnectionForTrace(e);if(!o||(o.nominalTraceWidth??o.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth)\u003e=n-Mq)return!1;r.add(t.traceIndex)}}return r.size\u003e0\u0026\u0026r.size\u003c=2}findBestPushableInflationWidth(t,e,n){const o=this.nominalTraceWidth\u003e=.5?.05:.0125;for(let i=this.nominalTraceWidth;i\u003en+Mq;i-=o){const n=Number(i.toFixed(6));if(this.hasOnlyPushableTraceBlockers(t,e,n))return n}return null}stepActiveInflationSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput(),n=e\u0026\u0026this.sameNetContactsArePreserved(this.traces[e.pushedTraceIndex].route,e.traces[e.pushedTraceIndex].route,this.getTraceConnectionNames(this.traces[e.pushedTraceIndex]),e.pushedTraceIndex);if(e\u0026\u0026n){if(this.traces=e.traces,this.pushedTraceCount++,this.expansionPushedTraceIndices.add(e.pushedTraceIndex),\"elastic\"===e.strategy\u0026\u0026this.elasticPushedTraceCount++,this.activeSubSolver=null,this.activeInflationKey=null,this.activeInflationWidth=null,this.rebuildObstacleIndex(),this.pendingLayerOutput){if(!this.layerRouteReplacementCollides(this.pendingLayerOutput,!1)\u0026\u0026this.layerRoutePreservesSameNetContacts(this.pendingLayerOutput))return void this.applyLayerRoute(this.pendingLayerOutput);if(this.startPendingLayerInflation())return;return this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.layerAttempt\u0026\u0026this.layerAttempt.offsetCursor++,void(this.phase=\"try-layer-candidate\")}return void(this.phase=\"evaluate-segment\")}e\u0026\u0026!n\u0026\u0026this.sameNetContactRejectionCount++}if(this.retainFailedSubSolver(t),this.activeInflationKey\u0026\u0026this.inflationAttemptsBySegment.set(this.activeInflationKey,2),this.activeInflationKey=null,this.activeInflationWidth=null,this.activeSubSolver=null,this.pendingLayerOutput)return this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.layerAttempt\u0026\u0026this.layerAttempt.offsetCursor++,void(this.phase=\"try-layer-candidate\");this.phase=\"evaluate-segment\"}}getLocalInflationCorridor(t,e,n){const o=t.route[e],i=t.route[e+1];if(!HJ(o)||!HJ(i)||o.layer!==i.layer)return[];const r=Rq(4*n,2,4),s=r/2;let a=e,c=0;for(;a\u003e0;){const e=t.route[a-1],n=t.route[a];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(c+o\u003es+Mq)break;c+=o,a--}let l=e+1,d=0;for(;l\u003ct.route.length-1;){const e=t.route[l],n=t.route[l+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(d+o\u003es+Mq)break;d+=o,l++}let h=r-c-d;for(;h\u003eMq\u0026\u0026a\u003e0;){const e=t.route[a-1],n=t.route[a];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(o\u003eh+Mq)break;h-=o,a--}for(;h\u003eMq\u0026\u0026l\u003ct.route.length-1;){const e=t.route[l],n=t.route[l+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(o\u003eh+Mq)break;h-=o,l++}const u=[];for(let e=a;e\u003cl;e++){const o=t.route[e],i=t.route[e+1];HJ(o)\u0026\u0026HJ(i)\u0026\u0026o.layer===i.layer\u0026\u0026u.push({start:o,end:i,layer:o.layer,width:n})}return u}applyGridRoute(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=this.createGridRouteReplacement(t);e.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...o),this.reroutedSegmentCount++,this.routeSegmentIndex=n.startIndex+o.length-1,this.currentIntervals=[],this.phase=\"evaluate-segment\"}createGridRouteReplacement(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=e.route[n.startIndex],i=e.route[n.endIndex],r=t.points.map(e=\u003e({route_type:\"wire\",x:e.x,y:e.y,width:t.traceWidth,layer:o.layer}));return r[0].width=Math.max(o.width,t.traceWidth),r[r.length-1].width=Math.max(i.width,t.traceWidth),r}gridRoutePreservesSameNetContacts(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor];return this.routeReplacementPreservesSameNetContacts(e,n,this.createGridRouteReplacement(t))}routeReplacementPreservesSameNetContacts(t,e,n){const o=this.getTraceConnectionNames(t),i=this.getSameNetContactIds(t.route.slice(e.startIndex,e.endIndex+1),o,this.traceIndex),r=new Set([...this.getSameNetContactIds(t.route.slice(0,e.startIndex+1),o,this.traceIndex),...this.getSameNetContactIds(t.route.slice(e.endIndex),o,this.traceIndex)]),s=new Set([...i].filter(t=\u003e!r.has(t)));if(0===s.size)return!0;const a=this.getSameNetContactIds(n,o,this.traceIndex);return[...s].every(t=\u003ea.has(t))}sameNetContactsArePreserved(t,e,n,o){const i=this.getSameNetContactIds(t,n,o);if(0===i.size)return!0;const r=this.getSameNetContactIds(e,n,o);return[...i].every(t=\u003er.has(t))}getSameNetContactIds(t,e,n){const o=new Set;for(let i=0;i\u003ct.length;i++){const r=t[i];if(\"via\"===r?.route_type){for(const t of this.getViaLayers(r))for(const i of this.obstacleIndex.getSameNetCopperContactIds({start:r,end:r,layer:t,width:r.via_diameter??.6,connectionNames:e,ignoreTraceIndex:n}))o.add(i);continue}const s=t[i+1];if(\"wire\"===r?.route_type\u0026\u0026\"wire\"===s?.route_type\u0026\u0026r.layer===s.layer)for(const t of this.obstacleIndex.getSameNetCopperContactIds({start:r,end:s,layer:r.layer,width:Math.min(r.width,s.width),connectionNames:e,ignoreTraceIndex:n}))o.add(t)}return o}getViaLayers(t){const e=this.obstacleIndex.boardLayers.indexOf(t.from_layer),n=this.obstacleIndex.boardLayers.indexOf(t.to_layer);return e\u003c0||n\u003c0?this.obstacleIndex.boardLayers:this.obstacleIndex.boardLayers.slice(Math.min(e,n),Math.max(e,n)+1)}gridRouteReplacementCollides(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=e.route[n.startIndex],i=e.route[n.endIndex],r=this.getTraceConnectionNames(e);for(let s=0;s\u003ct.points.length-1;s++){const a=Math.max(t.traceWidth,0===s?o.width:0,s===t.points.length-2?i.width:0);if(this.obstacleIndex.collides({start:t.points[s],end:t.points[s+1],layer:o.layer,width:a,connectionNames:r,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,n.startIndex-1),end:Math.min(e.route.length-1,n.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(a)}))return!0}return!1}gridRouteBoundaryCollides(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=this.getTraceConnectionNames(e),i=[{startIndex:n.startIndex-1,endIndex:n.startIndex},{startIndex:n.endIndex,endIndex:n.endIndex+1}];for(const n of i){const i=e.route[n.startIndex],r=e.route[n.endIndex];if(HJ(i)\u0026\u0026HJ(r)\u0026\u0026i.layer===r.layer\u0026\u0026this.obstacleIndex.collides({start:i,end:r,layer:i.layer,width:Math.max(i.width,r.width,t.traceWidth),connectionNames:o,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:n.startIndex,end:n.endIndex},obstacleClearance:this.getDesiredPadClearance(Math.max(i.width,r.width,t.traceWidth))}))return!0}return!1}canExpandSegmentAndEndpoints(t,e,n,o=this.nominalTraceWidth){const i=Math.max(0,e-1),r=Math.min(t.route.length-2,e+1);for(let s=i;s\u003c=r;s++){const a=t.route[s],c=t.route[s+1];if(!HJ(a)||!HJ(c)||a.layer!==c.layer)continue;const l=s\u003c=e+1\u0026\u0026s+1\u003e=e,d=Math.max(a.width,c.width,l?o:0);if(this.obstacleIndex.collides({start:a,end:c,layer:a.layer,width:d,connectionNames:n,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:i,end:r+1},obstacleClearance:this.getDesiredPadClearance(d)}))return!1}return!0}findMaximumSafeInPlaceWidth(t,e,n){const o=t.route[e],i=t.route[e+1];if(!HJ(o)||!HJ(i))return 0;const r=Math.min(o.width,i.width);if(this.probeInPlaceWidth(t,e,n,this.nominalTraceWidth))return this.nominalTraceWidth;let s=r,a=this.nominalTraceWidth;for(let o=0;o\u003c7;o++){const o=(s+a)/2;if(o\u003c=s+Mq)break;this.probeInPlaceWidth(t,e,n,o)?s=o:a=o}const c=this.nominalTraceWidth\u003e=.5?.025:.0125,l=Math.max(r,Math.floor((s+Mq)/c)*c);return l\u003er+Mq\u0026\u0026this.probeInPlaceWidth(t,e,n,l)?l:r}probeInPlaceWidth(t,e,n,o){return this.inPlaceWidthProbeCount++,this.canExpandSegmentAndEndpoints(t,e,n,o)}maximizeGridRouteWidth(t){if(t.traceWidth\u003e=this.nominalTraceWidth-Mq)return t;let e=t.traceWidth,n=this.nominalTraceWidth;for(let o=0;o\u003c7;o++){const o=(e+n)/2,i={...t,traceWidth:o};this.gridRouteReplacementCollides(i)||this.gridRouteBoundaryCollides(i)?n=o:e=o}const o=this.nominalTraceWidth\u003e=.5?.025:.0125,i=Math.max(t.traceWidth,Math.floor((e+Mq)/o)*o);if(i\u003et.traceWidth+Mq){const e={...t,traceWidth:i};if(!this.gridRouteReplacementCollides(e)\u0026\u0026!this.gridRouteBoundaryCollides(e))return this.pathWidthUpgradeCount++,e}return t}getExponentialIntervalCandidates(t,e,n){const o=this.getExponentialIndices(t,e,-1,n,5),i=this.getExponentialIndices(t,e,1,n,10).filter(t=\u003et\u003ee),r=[];for(const e of o)for(const n of i){const o=this.getRouteIntervalLength(t,e,n);o\u003e10.000001||r.push({startIndex:e,endIndex:n,routeLength:o})}return r.sort((t,e)=\u003et.routeLength-e.routeLength).filter((t,e,n)=\u003en.findIndex(e=\u003ee.startIndex===t.startIndex\u0026\u0026e.endIndex===t.endIndex)===e).slice(0,10).map(({startIndex:t,endIndex:e})=\u003e({startIndex:t,endIndex:e}))}getExponentialIndices(t,e,n,o,i){const r=[e];let s=0,a=Math.max(o,.3),c=e,l=e;for(;;){const e=c+n;if(e\u003c0||e\u003e=t.route.length)break;const o=t.route[c],d=t.route[e];if(!HJ(o)||!HJ(d)||o.layer!==d.layer)break;const h=Nq(o,d);if(s+h\u003ei+Mq)break;s+=h,c=e,l=e,s+Mq\u003e=a\u0026\u0026(r.push(e),a*=2)}return r.includes(l)||r.push(l),r}getRouteIntervalLength(t,e,n){let o=0;for(let i=e;i\u003cn;i++){const e=t.route[i],n=t.route[i+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)return Number.POSITIVE_INFINITY;o+=Nq(e,n)}return o}getCandidateWidths(t){const e=this.inputProblem.minTraceWidth;return WJ([t,.875*t,.75*t,.625*t,.5*t,.375*t,.25*t,e]).filter(t=\u003et\u003e=e-Mq)}getGridResolutions(t){return WJ([Math.max(.1,Math.min(.5,t/2)),Math.max(.1,Math.min(.25,t/3))])}resolveNominalTraceWidth(t){const e=this.findConnectionForTrace(t);return Math.max(e?.nominalTraceWidth??e?.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth,this.inputProblem.minTraceWidth)}getDesiredPadClearance(t=this.nominalTraceWidth){const e=Math.max(this.inputProblem.defaultObstacleMargin??0,this.inputProblem.minTraceToPadEdgeClearance??0,.1);return t\u003c.499999||\"cleanup\"!==this.phase?e:Math.max(e,this.options.powerTraceToPadClearance??t/2)}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=this.getTraceConnectionNames(t),o=this.inputProblem.connections.find(t=\u003ethis.connectionMatchesTrace(t,n))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getOwnedTraceIndices(){return[...this.selectedOwnedTraceIndices]}connectionMatchesTrace(t,e){return[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t)).some(t=\u003ee.includes(t))}getTraceConnectionNames(t){return[t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))}traceMeetsNominalWidth(t,e){return t.route.every(t=\u003e\"wire\"!==t.route_type||t.width\u003e=e-Mq)}findNextUnderWidthSegment(t,e,n){for(let o=e;o\u003ct.route.length-1;o++){const e=t.route[o],i=t.route[o+1];if(HJ(e)\u0026\u0026HJ(i)\u0026\u0026e.layer===i.layer\u0026\u0026(e.width\u003cn-Mq||i.width\u003cn-Mq))return o}return-1}getMutatedImmutableTraceIds(t){return this.immutableTraceIndices.flatMap(e=\u003e{const n=t[e];return JSON.stringify(n)===this.initialImmutableTraceSignatures.get(e)?[]:[n?.pcb_trace_id??this.traces[e]?.pcb_trace_id??String(e)]})}getImmutableViaViolationSignatures(t){const e=new Set;if(0===this.immutableTraceIndices.length)return e;const n=new Pq(this.inputProblem,t),o=new tJ(this.inputProblem,t,void 0,[],n);for(const n of this.immutableTraceIndices){const i=t[n];if(!i)continue;const r=[i.pcb_trace_id,i.connection_name,i.source_trace_id,i.rootConnectionName,...i.mergedConnectionNames??[],...i.connectsTo??[]].filter(t=\u003eBoolean(t));for(let t=0;t\u003ci.route.length;t++){const s=i.route[t];if(\"via\"!==s?.route_type)continue;const a=`${i.pcb_trace_id}:${t}`,c=o.getViaViolationSignatures({point:s,layers:o.boardLayers,padDiameter:s.via_diameter??this.inputProblem.min_via_pad_diameter??this.inputProblem.minViaPadDiameter??this.inputProblem.minViaDiameter??.6,holeDiameter:s.via_hole_diameter??o.defaultViaHoleDiameter,connectionNames:r,ignoreTraceIndex:n,ignoreRouteRange:{start:t,end:t},blockSameNetObstacles:!0,sameNetObstacleClearance:0});for(const t of c)e.add(`${a}|${t}`)}}return e}countViolatingImmutableVias(t){return new Set([...t].map(t=\u003et.split(\"|\")[0])).size}acceptConnectivityCheckpoint(t,e){this.connectivityValidationCount++;let n=!1,o=!1;try{const e=this.connectivityInvariant.validate(t),i=this.getMutatedImmutableTraceIds(t),r=this.getImmutableViaViolationSignatures(t),s=[...r].filter(t=\u003e!this.lastSafeImmutableViaViolationSignatures.has(t)),a=s.length\u003e0;if(n=!e.safe,o=i.length\u003e0||a,this.connectivityValidationError??=e.validationError??null,!n\u0026\u0026!o)return this.traces=structuredClone(t),this.lastConnectivitySafeTraces=structuredClone(t),this.remainingImmutableViaViolationCount=this.countViolatingImmutableVias(r),this.remainingImmutableViaViolationPairCount=r.size,this.lastSafeImmutableViaViolationSignatures=r,this.connectivityInvariant=new OJ(this.inputProblem,this.lastConnectivitySafeTraces),!0;this.immutableTraceMutationIds=[...new Set([...this.immutableTraceMutationIds,...i])],a\u0026\u0026(this.immutableViaViolationRollbackCount++,this.attemptedImmutableViaViolationCount=this.countViolatingImmutableVias(r),this.attemptedImmutableViaViolationPairCount=r.size,this.immutableViaViolationRegressionIds=[...new Set([...this.immutableViaViolationRegressionIds,...s])]),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...e.regressions.flatMap(t=\u003et.baselineEndpointLabels)])]}catch(t){n=!0,this.connectivityValidationError=t instanceof Error?t.message:String(t)}return n\u0026\u0026(this.connectivityRollbackCount++,this.connectivityRollbackPhases.includes(e)||this.connectivityRollbackPhases.push(e)),o\u0026\u0026(this.immutableSafetyRollbackCount++,this.immutableSafetyRollbackPhases.includes(e)||this.immutableSafetyRollbackPhases.push(e)),\"expansion\"===e?n?this.rollbackConnectivityRegressedExpansion():this.rollbackImmutableUnsafeExpansion():this.restoreLastConnectivitySafeTraces(),this.remainingImmutableViaViolationCount=this.countViolatingImmutableVias(this.lastSafeImmutableViaViolationSignatures),this.remainingImmutableViaViolationPairCount=this.lastSafeImmutableViaViolationSignatures.size,!1}rebuildObstacleIndex(){this.obstacleIndex=new tJ(this.inputProblem,this.traces,this.traceIndex,[],this.connectionNameResolver)}retainFailedSubSolver(t){this.failedSubSolverCount++,this.failedSubSolvers??=[],this.failedSubSolvers.length\u003c16?this.failedSubSolvers.push(t):this.failedSubSolvers[15]=t}tryFinalAcceptance(){this.finalAcceptanceUsed=!0;let t=!1;this.activeSubSolver instanceof jJ?(this.activeSubSolver.tryFinalAcceptance(),this.adoptCleanupOutput(this.activeSubSolver),t=!0):this.activeSubSolver instanceof YJ\u0026\u0026(this.activeSubSolver.tryFinalAcceptance(),this.adoptClearanceRepairOutput(this.activeSubSolver),t=!0),t||\"cleanup\"===this.phase||\"repair-trace-clearance\"===this.phase||\"complete\"===this.phase||this.discardInFlightExpansion(),this.activeSubSolver=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.activeInflationKey=null,this.activeInflationWidth=null,this.layerAttempt=null,this.acceptConnectivityCheckpoint(this.traces,\"final\"),this.traceIndex=this.traces.length,this.phase=\"complete\",this.rebuildObstacleIndex(),this.progress=1,this.solved=!0,this.stats=this.createStats()}createStats(){return{phase:this.phase,pass:this.passIndex+1,completedPassCount:this.completedPassCount,lastNormalizedWidthDeficitGain:this.lastNormalizedWidthDeficitGain,normalizedWidthDeficitGainByPass:[...this.normalizedWidthDeficitGainByPass],plateauReached:this.plateauReached,traceIndex:this.traceIndex,traceCount:this.traces.length,selectedTraceCount:this.traceOrder.length,routeSegmentIndex:this.routeSegmentIndex,nominalTraceWidth:this.nominalTraceWidth,intervalCursor:this.intervalCursor,intervalCount:this.currentIntervals.length,candidateWidth:this.candidateWidths[this.widthCursor],gridSize:this.gridResolutions[this.resolutionCursor],gridOffsetVariant:this.offsetCursor,keptTraceCount:this.keptTraceCount,recreatedTraceCount:this.recreatedTraceCount,expandedSegmentCount:this.expandedSegmentCount,intermediateExpandedSegmentCount:this.intermediateExpandedSegmentCount,pathWidthUpgradeCount:this.pathWidthUpgradeCount,inPlaceWidthProbeCount:this.inPlaceWidthProbeCount,reroutedSegmentCount:this.reroutedSegmentCount,unresolvedSegmentCount:this.unresolvedSegmentCount,attemptedGridCount:this.attemptedGridCount,attemptedLayerGridCount:this.attemptedLayerGridCount,attemptedInflationCount:this.attemptedInflationCount,activeInflationWidth:this.activeInflationWidth,pushedTraceCount:this.pushedTraceCount,elasticPushedTraceCount:this.elasticPushedTraceCount,layerReroutedTraceCount:this.layerReroutedTraceCount,insertedViaCount:this.insertedViaCount,neckedLayerSegmentCount:this.neckedLayerSegmentCount,removedViaPairCount:this.removedViaPairCount,removedViaCount:this.removedViaCount,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,cleanupClearanceShoveCount:this.cleanupClearanceShoveCount,relocatedViaCount:this.relocatedViaCount,unresolvedViaCount:this.unresolvedViaCount,initialImmutableViaViolationCount:this.initialImmutableViaViolationCount,remainingImmutableViaViolationCount:this.remainingImmutableViaViolationCount,initialImmutableViaViolationPairCount:this.initialImmutableViaViolationPairCount,remainingImmutableViaViolationPairCount:this.remainingImmutableViaViolationPairCount,skippedImmutableViaRepairCount:this.remainingImmutableViaViolationCount,immutableViaViolationRollbackCount:this.immutableViaViolationRollbackCount,attemptedImmutableViaViolationCount:this.attemptedImmutableViaViolationCount,attemptedImmutableViaViolationPairCount:this.attemptedImmutableViaViolationPairCount,immutableViaViolationRegressionIds:[...this.immutableViaViolationRegressionIds],immutableTraceMutationIds:[...this.immutableTraceMutationIds],padClearanceRerouteCount:this.padClearanceRerouteCount,unresolvedPadClearanceCount:this.unresolvedPadClearanceCount,repairedTraceClearanceSegmentCount:this.repairedTraceClearanceSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,unresolvedTraceClearanceSegmentCount:this.unresolvedTraceClearanceSegmentCount,sameNetContactRejectionCount:this.sameNetContactRejectionCount,connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRollbackPhases:[...this.connectivityRollbackPhases],immutableSafetyRollbackCount:this.immutableSafetyRollbackCount,immutableSafetyRollbackPhases:[...this.immutableSafetyRollbackPhases],connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},immutableSafetyRollbackMutationStats:null===this.immutableSafetyRollbackMutationStats?null:{...this.immutableSafetyRollbackMutationStats},expansionPushedTraceIndices:[...this.expansionPushedTraceIndices],cleanupMutatedTraceIndices:[...this.cleanupMutatedTraceIndices],discardedExpansionMutationStats:null===this.discardedExpansionMutationStats?null:{...this.discardedExpansionMutationStats},initialPadClearanceViolationCount:this.initialPadClearanceViolationCount,remainingPadClearanceViolationCount:this.remainingPadClearanceViolationCount,initialPadClearanceViolationCountByClearance:{...this.initialPadClearanceViolationCountByClearance},remainingPadClearanceViolationCountByClearance:{...this.remainingPadClearanceViolationCountByClearance},budgetLimitedExpansion:this.budgetLimitedExpansion,finalAcceptanceUsed:this.finalAcceptanceUsed,cleanupCompleted:this.cleanupCompleted,clearanceRepairCompleted:this.clearanceRepairCompleted,cleanupBestEffortAccepted:this.cleanupBestEffortAccepted,clearanceRepairBestEffortAccepted:this.clearanceRepairBestEffortAccepted,cleanupStatus:this.connectivityRollbackPhases.includes(\"cleanup\")?\"connectivity_rollback\":this.immutableSafetyRollbackPhases.includes(\"cleanup\")?\"immutable_safety_rollback\":this.cleanupBestEffortAccepted?\"budget_limited\":this.cleanupCompleted?\"completed\":\"cleanup\"===this.phase?\"in_progress\":\"not_started\",clearanceRepairStatus:this.connectivityRollbackPhases.includes(\"clearance-repair\")?\"connectivity_rollback\":this.immutableSafetyRollbackPhases.includes(\"clearance-repair\")?\"immutable_safety_rollback\":this.clearanceRepairBestEffortAccepted?\"budget_limited\":this.clearanceRepairCompleted?\"completed\":\"repair-trace-clearance\"===this.phase?\"in_progress\":\"not_started\",cleanupIterationBudget:this.cleanupIterationBudget,clearanceRepairIterationBudget:this.clearanceRepairIterationBudget,completionReason:\"complete\"===this.phase||this.solved?this.connectivityRollbackCount\u003e0?\"connectivity_rollback\":this.immutableSafetyRollbackCount\u003e0?\"immutable_safety_rollback\":this.connectivityValidationError?\"connectivity_validation_unavailable\":this.finalAcceptanceUsed?\"total_iteration_budget\":this.budgetLimitedExpansion?\"expansion_budget\":this.cleanupBestEffortAccepted?\"cleanup_budget\":this.clearanceRepairBestEffortAccepted?\"clearance_repair_budget\":this.remainingImmutableViaViolationCount\u003e0?\"immutable_via_violations_preserved\":\"completed\":null,resultStatus:this.finalAcceptanceUsed||this.budgetLimitedExpansion||this.cleanupBestEffortAccepted||this.clearanceRepairBestEffortAccepted||this.connectivityRollbackCount\u003e0||this.immutableSafetyRollbackCount\u003e0||null!==this.connectivityValidationError||this.remainingImmutableViaViolationCount\u003e0?\"best_effort\":\"complete\",failedSubSolverCount:this.failedSubSolverCount,retainedFailedSubSolverCount:this.failedSubSolvers?.length??0,expansionIterationBudget:this.getExpansionIterationBudget(),finalizationIterationReserve:this.getFinalizationIterationReserve(),spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){return this.solved||\"complete\"===this.phase?1:this.budgetLimitedExpansion?.99:0===this.traceOrder.length?1:Math.min(.99,(this.passIndex+Math.max(0,this.traceOrderCursor)/this.traceOrder.length)/this.maxPassCount)}getConstructorParams(){return[this.inputProblem,this.options]}getOutput(){return structuredClone(this.lastConnectivitySafeTraces)}visualize(){const t=[],e=[];for(let n=0;n\u003cthis.traces.length;n++){const o=this.traces[n],i=this.resolveNominalTraceWidth(o);for(const t of o.route)\"via\"===t.route_type\u0026\u0026e.push({center:t,radius:(t.via_diameter??.6)/2,fill:\"#d4a017\",stroke:\"#7a5700\"});for(let e=0;e\u003co.route.length-1;e++){const r=o.route[e],s=o.route[e+1];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)continue;const a=n===this.traceIndex\u0026\u0026e===this.routeSegmentIndex,c=r.width\u003e=i-Mq\u0026\u0026s.width\u003e=i-Mq,l=\"bottom\"===r.layer;t.push({points:[r,s],strokeColor:a?\"#ff8c00\":c?l?\"#2468c7\":\"#169c45\":l?\"#8b4bb8\":\"#cc3344\",strokeWidth:Math.max(r.width,s.width)})}}return{coordinateSystem:\"cartesian\",title:`Power trace expander: ${this.phase}`,lines:t,points:[],circles:e,rects:this.obstacleIndex.items.filter(t=\u003e\"obstacle\"===t.kind).slice(0,2e3).map(t=\u003e({center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,fill:\"rgba(80,80,80,0.12)\",stroke:\"rgba(80,80,80,0.35)\"})),texts:[]}}},UJ=class extends si{constructor(t,e={}){if(super(),this.inputSrj=t,this.options=e,this.powerTraceExpanderSolver=new GJ(t,e),0===e.onlyConnectionNames?.length)return this.MAX_ITERATIONS=1,this.progress=1,this.solved=!0,void(this.stats={selectedTraceCount:0,bypassed:!0});this.MAX_ITERATIONS=this.powerTraceExpanderSolver.MAX_ITERATIONS+1}inputSrj;options;powerTraceExpanderSolver;_step(){const t=this.powerTraceExpanderSolver;if(t.step(),this.progress=t.progress,this.stats=t.stats,t.failed)return this.error=t.error,void(this.failed=!0);t.solved\u0026\u0026(this.solved=!0)}getConstructorParams(){return[this.inputSrj,this.options]}getOutput(){if(!this.solved)throw new Error(\"Cannot get power trace expansion output before solving\");return this.powerTraceExpanderSolver.getOutput()}visualize(){return Ho({...this.inputSrj,traces:this.getOutput()},{traceColorMode:\"layer\"})}},ZJ=({connections:t,originalConnections:e,layerCount:n,obstacles:o,defaultViaHoleDiameter:i,connMap:r})=\u003e{const s=new Map;for(const t of e)s.has(t.name)||s.set(t.name,t.__netConnectionName);const a=t.map(t=\u003e{if(2!==t.pointsToConnect.length)throw new Error(`Expected Pipeline7 output connection \"${t.name}\" to have two points, got ${t.pointsToConnect.length}`);const[e,n]=t.pointsToConnect;return{connection:t,connectsTo:[e?.pointId,n?.pointId].filter(t=\u003eBoolean(t)),outputConnectionName:t.__netConnectionName??s.get(t.name)??t.__rootConnectionNames?.[0]??t.name}}),c=o.filter(t=\u003e(t.__zLayers?.length??t.layers?.length??0)\u003e1),l=new Map,d=t=\u003e{let e=l.get(t.connectionName);e||(e=new Map,l.set(t.connectionName,e));const n=e.get(t.rootConnectionName);if(n)return n;const o=c.filter(e=\u003efo(e,t,r));return e.set(t.rootConnectionName,o),o};return t=\u003e{const e=[],o=new Map;for(const e of t){const t=o.get(e.connectionName);t?t.push(e):o.set(e.connectionName,[e])}for(const{connection:t,connectsTo:s,outputConnectionName:c}of a){const a=o.get(t.name)??[];for(let o=0;o\u003ca.length;o+=1){const l=a[o];e.push({type:\"pcb_trace\",pcb_trace_id:`${t.name}_${o}`,connection_name:c,connectsTo:s,route:Mo(l,n,{connectionPoints:t.pointsToConnect,defaultViaHoleDiameter:i,connectedMultilayerObstacles:d(l),connMap:r})})}}return e}},qJ=({connections:t,originalConnections:e,hdRoutes:n,layerCount:o,obstacles:i,defaultViaHoleDiameter:r,connMap:s})=\u003eZJ({connections:t,originalConnections:e,layerCount:o,obstacles:i,defaultViaHoleDiameter:r,connMap:s})(n),JJ=t=\u003e{const e=Math.max(t.minTraceWidth+.1,2*t.minTraceWidth);return t.connections.flatMap(n=\u003e(n.nominalTraceWidth??t.nominalTraceWidth??t.minTraceWidth)+1e-6\u003e=e?[n.name]:[])},KJ=(t,e,n=new Map(t.map(t=\u003e[t.connectionName,t])))=\u003e{const o=new Map(e.map(t=\u003e[t.name,t]));return t.map(t=\u003e{if(0===t.route.length)throw new Error(`Cannot lock PCB terminals for empty route \"${t.connectionName}\"`);const e=o.get(t.connectionName);if(!e)throw new Error(`Cannot lock PCB terminals: connection \"${t.connectionName}\" was not found`);if(2!==e.pointsToConnect.length)throw new Error(`Cannot lock PCB terminals for \"${t.connectionName}\": expected 2 connection points, found ${e.pointsToConnect.length}`);const i=n.get(t.connectionName)??t,r=new Map;for(const n of e.pointsToConnect)if(n.pcb_port_id){if(r.has(n.pcb_port_id))throw new Error(`Cannot lock duplicate PCB terminal \"${n.pcb_port_id}\" for \"${t.connectionName}\"`);r.set(n.pcb_port_id,n)}if(0===r.size)return t;const s=[i.startPcbPortId,i.endPcbPortId].filter(t=\u003evoid 0!==t);if(0===s.length)return t;if(new Set(s).size!==s.length||s.some(t=\u003e!r.has(t)))throw new Error(`Cannot lock PCB terminals for \"${t.connectionName}\": route endpoint IDs do not match connection terminal IDs`);const a=i.startPcbPortId?r.get(i.startPcbPortId):void 0,c=i.endPcbPortId?r.get(i.endPcbPortId):void 0,l=t.route.map((e,n)=\u003e{if(0===n\u0026\u0026a)return{...e,x:a.x,y:a.y,pcb_port_id:a.pcb_port_id};if(n===t.route.length-1\u0026\u0026c)return{...e,x:c.x,y:c.y,pcb_port_id:c.pcb_port_id};const o={...e};return delete o.pcb_port_id,o});return{...t,route:l}})},QJ=({originalSrj:t,newlyRoutedTraces:e,currentPreloadedTraces:n,expandedConnectionNames:o,resolveConnectedTraceAliases:i=!1})=\u003e{const r=n??t.traces??[],s=i?tK({originalSrj:t,newlyRoutedTraces:e,preloadedTraces:r,expandedConnectionNames:o}):new Set(r.filter(t=\u003eo.includes(t.connection_name))),a=r.filter(t=\u003e!s.has(t)),c=new Set([...e.map(t=\u003et.pcb_trace_id),...a.map(t=\u003et.pcb_trace_id)]),l=r.filter(t=\u003es.has(t)).map(t=\u003e{const e=t.pcb_trace_id;let n=e,o=2;for(;c.has(n);)n=`${e}_power_expansion_${o++}`;return c.add(n),{...t,pcb_trace_id:n,__replaces_pcb_trace_id:t.__replaces_pcb_trace_id??t.pcb_trace_id}});return{...t,traces:[...e,...l],fixedTraces:a}},tK=({originalSrj:t,newlyRoutedTraces:e,preloadedTraces:n,expandedConnectionNames:o})=\u003e{const i=new Set(n.map(t=\u003et.pcb_trace_id)),r=new Set([...i,...e.map(t=\u003et.pcb_trace_id)]),s=e.map((t,e)=\u003e{if(!i.has(t.pcb_trace_id))return t;const n=`__pipeline7_new_trace_${e}_${t.pcb_trace_id}`;let o=n,s=2;for(;r.has(o);)o=`${n}_${s++}`;return r.add(o),{...t,pcb_trace_id:o}}),a=new Pq({...t,traces:[...s,...n]}),c=new Set(a.canonicalize([...o]));return new Set(n.filter(t=\u003ea.canonicalize([t.connection_name]).some(t=\u003ec.has(t))))};function eK(t){return new Set((t??[]).filter(t=\u003et._isComponentTopologyNode).map(t=\u003et.capacityMeshNodeId))}function nK(t,e){return t.nodeIds.some(t=\u003ee.has(t))}function oK({sharedEdgeSegments:t,componentCapacityMeshNodeIds:e}){return t.filter(t=\u003e!nK(t,e))}function iK(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var rK=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e;const n=fX(t);this.originalSrj=n,this.opts={...e};const o=this.opts;if(this.effort=o.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=o.maxNodeDimension??16,this.maxNodeRatio=o.maxNodeRatio??6,this.minNodeArea=o.minNodeArea??.1**2,this.visualizationTraceColorMode=o.visualizationTraceColorMode??\"layer\",this.setSimpleRouteJson(n),void 0===o.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,n=Math.max(t,e),i=o.targetMinCapacity??.5;o.capacityDepth=$s(n,i)}this.cacheProvider=void 0===o.cacheProvider?oo():null===o.cacheProvider?null:o.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;getSolverName(){return\"AutoroutingPipelineSolver7_MultiGraph\"}preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;componentTopologyGeneratorSolver;topologyPlanningSolver;topologyMergingSolver;globalTopologyGeneratorSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;exactGeometryDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;lengthMatchingPostProcessingSolver;powerTraceExpansionSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;componentDetectionSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;visualizationTraceColorMode;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;sharedEdgeSegmentsWithNecessaryCrampedPortPoints;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[iK(\"preprocessSimpleRouteJsonSolver\",_X,t=\u003e[t.originalSrj,{traceColorMode:t.visualizationTraceColorMode}],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),iK(\"componentDetectionSolver\",UZ,t=\u003e[{inputSrj:t.srj}]),iK(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),iK(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),iK(\"topologyPlanningSolver\",_q,t=\u003e[{inputSrj:t.srjWithPointPairs,componentDetectionOutput:t.componentDetectionSolver.getOutput(),viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.topologyPlanningSolver.getOutput();t.globalTopologyGeneratorSolver=t.topologyPlanningSolver.globalTopologySolver,t.componentTopologyGeneratorSolver=new vq(t.topologyPlanningSolver)}}),iK(\"topologyMergingSolver\",fq,t=\u003e{const e=t.topologyPlanningSolver.getOutput();return[{layerCount:t.srj.layerCount,nodeGroups:[{groupId:\"global\",nodes:e.globalMeshNodes,isComponent:!1},...e.componentMeshNodes.map((t,e)=\u003e({groupId:`component-${e}`,nodes:t,isComponent:!0}))]}]},{onSolved:t=\u003e{t.capacityNodes=t.topologyMergingSolver.getOutput()}}),iK(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver.outputNodes}}),iK(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),iK(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),iK(\"necessaryCrampedPortPointSolver\",sf,t=\u003e{const e=eK(t.capacityNodes);return[{capacityMeshNodes:t.capacityNodes.filter(t=\u003e!e.has(t.capacityMeshNodeId)),sharedEdgeSegments:oK({sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),componentCapacityMeshNodeIds:e}),simpleRouteJson:t.srjWithPointPairs}]},{onSolved:t=\u003e{const e=eK(t.capacityNodes);t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints=function({originalSharedEdgeSegments:t,filteredSharedEdgeSegments:e,componentCapacityMeshNodeIds:n}){const o=new Map(e.map(t=\u003e[t.edgeId,t]));return t.map(t=\u003enK(t,n)?t:o.get(t.edgeId)??t)}({originalSharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),filteredSharedEdgeSegments:t.necessaryCrampedPortPointSolver.getOutput(),componentCapacityMeshNodeIds:e})}}),iK(\"portPointPathingSolver\",jj,t=\u003e{const e=t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints??t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,preserveTerminalPcbPortIds:!0,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0,USE_SELECTIVE_RERIP_ROUTING:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),iK(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),iK(\"highDensityRouteSolver\",zs,t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length\u003e0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!0,growShrinkFallbackToInvalidGeometryOnFailure:!0,captureSearchDebug:!1}]}),iK(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),iK(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2,maxSampleEntries:80}]),iK(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,preserveTerminalPcbPortIds:!0}]),iK(\"traceSimplificationSolver\",vc,t=\u003e[{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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,enableCrossingViaReduction:!0,iterations:2}]),iK(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),iK(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:KJ(t.traceWidthSolver.getHdRoutesWithWidths(),t.netToPointPairsSolver?.newConnections??[],new Map((t.highDensityStitchSolver?.mergedHdRoutes??[]).map(t=\u003e[t.connectionName,t]))),connMap:t.connMap,effort:t.effort,maxIterations:16,enableLargeBoardBroadFallback:!1,enablePostSolveClearanceRelaxation:!1}]),iK(\"exactGeometryDrcForceImproveSolver\",wz,t=\u003e{const e=t.globalDrcForceImproveSolver.getOutput(),n=(t=\u003e{const e={...t.srjWithPointPairs,obstacles:t.originalSrj.obstacles,minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter??t.srjWithPointPairs.minViaDiameter},n=Math.max(Yo(t.originalSrj).padDiameter,e.minTraceWidth)+Math.max(.1,.1),o=new s_(e,{connMap:t.connMap,includeTraceViaOwnerMetadata:!0,traceClearance:.1,viaClearance:.1,spatialCellSize:n}),i=ZJ(t),r=t.originalSrj.traces??[];return({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline7 autorouting DRC evaluation requires HD routes\");const s=i(n),a=r.length?[...r,...s]:s;return o.evaluate(a)}})({connections:t.netToPointPairsSolver?.newConnections??[],originalConnections:t.originalSrj.connections,layerCount:t.srj.layerCount,obstacles:t.srj.obstacles,defaultViaHoleDiameter:t.viaHoleDiameter,connMap:t.connMap,srjWithPointPairs:t.srjWithPointPairs,originalSrj:t.originalSrj});return[{srj:t.srjWithPointPairs,hdRoutes:e,connMap:t.connMap,effort:t.effort,viaHoleDiameter:t.viaHoleDiameter,drcEvaluator:n,viaInPadDrcEvaluator:n,maxIterations:32,enableLargeBoardBroadFallback:!1,enableBroadFallback:!1,enableTargetedErrorSweep:!0,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:t.originalSrj.allowViaInPad??!1,viaInPadMaxIterations:32,broadMaxIterations:12,broadPassMultiplier:3}]}),iK(\"lengthMatchingPostProcessingSolver\",lU,t=\u003e{const e=t.netToPointPairsSolver;if(!e)throw new Error(\"Pipeline7: length-matching post-processing requires NetToPointPairsSolver output\");const n=e.newConnections,o=new Map;for(const e of t.srj.differentialPairs??[])for(const t of e.connectionNames){const e=n.filter(e=\u003ee.name===t||e.__rootConnectionNames?.includes(t)||e.__netConnectionName===t);if(1!==e.length)throw new Error(`Pipeline7: differential pair connection \"${t}\" must resolve to exactly one final point-pair connection, got ${e.length}`);o.set(t,e[0].name)}const i=t.exactGeometryDrcForceImproveSolver.getOutput(),r=(t.srj.differentialPairs??[]).map(t=\u003e{const e=t.connectionNames.map(t=\u003e{const e=o.get(t);if(!e)throw new Error(`Pipeline7: differential pair connection \"${t}\" is missing from final routed output`);return e});if(e[0]===e[1])throw new Error(`Pipeline7: differential pair ${t.connectionNames.join(\"/\")} resolves both members to \"${e[0]}\"`);if(void 0===t.traceGap)return{connectionNames:e,lengthTolerance:t.lengthTolerance,maxUncoupledLength:t.maxUncoupledLength};const n=e.map(t=\u003e{const e=i.filter(e=\u003ee.connectionName===t);if(1!==e.length)throw new Error(`Pipeline7: differential pair connection \"${t}\" must resolve to exactly one final HD route, got ${e.length}`);return e[0]}),r=t.traceGap+n.reduce((t,e)=\u003et+e.traceThickness/2,0);return{connectionNames:e,lengthTolerance:t.lengthTolerance,maxUncoupledLength:t.maxUncoupledLength,minimumCenterlineDistance:r,maximumCenterlineDistance:r}});return[{hdRoutes:i,differentialPairs:r,obstacles:t.srj.obstacles,bounds:t.srj.bounds,layerCount:t.srj.layerCount}]}),iK(\"powerTraceExpansionSolver\",UJ,t=\u003e{const e=t.opts.powerTraceExpansion??{},n=e.onlyConnectionNames??JJ(t.originalSrj);return[QJ({originalSrj:t.originalSrj,newlyRoutedTraces:t.getPrePowerTraceOutputSimplifiedPcbTraces(),expandedConnectionNames:n}),{allowNewVias:!1,...e,onlyConnectionNames:n}]})];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;computeProgress(){const t=this.activeSubSolver?.progress??0;return(this.currentPipelineStepIndex+t)/this.pipelineDef.length}_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\u0026\u0026(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),\"lengthMatchingPostProcessingSolver\"!==t.solverName\u0026\u0026\"powerTraceExpansionSolver\"!==t.solverName||(this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,this.iterations+this.activeSubSolver.MAX_ITERATIONS+1)),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\u0026\u0026this.activeSubSolver)return this.visualizeStage(this.activeSubSolver);const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.componentDetectionSolver?.visualize(),o=this.componentTopologyGeneratorSolver?.visualize(),i=this.globalTopologyGeneratorSolver?.visualize(),r=this.topologyMergingSolver?.visualize(),s=this.nodeDimensionSubdivisionSolver?.visualize(),a=this.nodeTargetMerger?.visualize(),c=this.singleLayerNodeMerger?.visualize(),l=this.strawSolver?.visualize(),d=this.edgeSolver?.visualize(),h=this.deadEndSolver?.visualize(),u=this.availableSegmentPointSolver?.visualize(),p=this.portPointPathingSolver?.visualize(),m=this.multiSectionPortPointOptimizer?.visualize(),g=this.uniformPortDistributionSolver?.visualize(),f=this.highDensityRouteSolver?.visualize(),y=this.highDensityForceImproveSolver?.visualize(),_=this.highDensityRepairSolver?.visualize(),b=this.highDensityStitchSolver?.visualize(),x=this.traceSimplificationSolver?.visualize(),v=this.lengthMatchingPostProcessingSolver?.visualize(),S=this.traceWidthSolver?.visualize(),I=this.necessaryCrampedPortPointSolver?.visualize(),C=(this.highDensityRouteSolver?.visualize(),this.originalSrj),P=C.outline,M=[];if(M.push({points:[{x:C.bounds?.minX??-50,y:C.bounds?.minY??-50},{x:C.bounds?.maxX??50,y:C.bounds?.minY??-50},{x:C.bounds?.maxX??50,y:C.bounds?.maxY??50},{x:C.bounds?.minX??-50,y:C.bounds?.maxY??50},{x:C.bounds?.minX??-50,y:C.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),P\u0026\u0026P.length\u003e=2){const t=P.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),M.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const N=Oo(C),w={points:[...C.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,C.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(C.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,C.layerCount),label:N(t)}))],lines:M},T={traceColorMode:this.visualizationTraceColorMode},R=Yj({srj:C,visualizationOptions:T}),E=pi(w,R),A=this.preprocessSimpleRouteJsonSolver?.visualize(),O=this.globalDrcForceImproveSolver?.visualize(),k=this.exactGeometryDrcForceImproveSolver?.visualize(),L=[E,A,n,o,t,e,i,r,s,a,c,l,d,h,u,I,p,m,g,f?pi(w,f):null,y,_,b,x,S,O,k,v,this.solved?pi({lines:M},Yj({srj:this.originalSrj,visualizationOptions:T}),this.visualizeFinalOutput()):null].filter(Boolean),D=pi(...L);return\"net\"===this.visualizationTraceColorMode?xq(D,this.colorMap):D}visualizeStage(t){const e=t.visualize();return\"net\"===this.visualizationTraceColorMode?xq(e,this.colorMap):e}visualizeFinalOutput(){const t=this.visualizationTraceColorMode,e=this.getOutputSimpleRouteJson();return Ho(e,{traceColorMode:t})}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.componentTopologyGeneratorSolver?this.componentTopologyGeneratorSolver.visualize():this.componentDetectionSolver?this.componentDetectionSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){if(this.lengthMatchingPostProcessingSolver){const{hdRoutes:t}=this.lengthMatchingPostProcessingSolver.getOutput();return t}return this.exactGeometryDrcForceImproveSolver?.getOutput()??this.globalDrcForceImproveSolver?.getOutput()??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\");return this.powerTraceExpansionSolver?this.powerTraceExpansionSolver.getOutput():this.getPrePowerTraceOutputSimplifiedPcbTraces()}getPrePowerTraceOutputSimplifiedPcbTraces(){return qJ({connections:this.netToPointPairsSolver?.newConnections??[],originalConnections:this.originalSrj.connections,hdRoutes:this._getOutputHdRoutes(),layerCount:this.srj.layerCount,obstacles:this.srj.obstacles,defaultViaHoleDiameter:this.viaHoleDiameter,connMap:this.connMap})}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},sK=t=\u003e[...new Set(t)].sort((t,e)=\u003et-e),aK=class extends si{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1}params;outputNodes=[];outputSharedEdgeSegments=[];nodeIdByOriginalAndZ=new Map;getSolverName(){return\"SplitNodesIntoSingleLayerNodeSolver\"}_step(){this.outputNodes=this.params.capacityMeshNodes.flatMap(t=\u003esK(t.availableZ).map(e=\u003e{const n=((t,e)=\u003e`${t}__z${e}`)(t.capacityMeshNodeId,e);return this.nodeIdByOriginalAndZ.set(`${t.capacityMeshNodeId}:${e}`,n),{...t,capacityMeshNodeId:n,layer:`z${e}`,availableZ:[e],_parent:t}})),this.outputSharedEdgeSegments=this.params.sharedEdgeSegments.flatMap(t=\u003ethis.splitSharedEdgeSegment(t)),this.stats={inputNodeCount:this.params.capacityMeshNodes.length,outputNodeCount:this.outputNodes.length,inputPortPointCount:this.params.sharedEdgeSegments.reduce((t,e)=\u003et+e.portPoints.length,0),outputPortPointCount:this.outputSharedEdgeSegments.reduce((t,e)=\u003et+e.portPoints.length,0)},this.solved=!0}getSplitNodeId(t,e){return this.nodeIdByOriginalAndZ.get(`${t}:${e}`)}splitPortPoint(t){return sK(t.availableZ).flatMap(e=\u003e{const n=t.nodeIds.map(t=\u003ethis.getSplitNodeId(t,e));return n[0]\u0026\u0026n[1]?[{...t,segmentPortPointId:`${t.segmentPortPointId}__z${e}`,availableZ:[e],nodeIds:[n[0],n[1]]}]:[]})}splitSharedEdgeSegment(t){const e=new Map;for(const n of t.portPoints.flatMap(t=\u003ethis.splitPortPoint(t))){const t=n.availableZ[0];if(void 0===t)continue;const o=e.get(t)??[];o.push(n),e.set(t,o)}return[...e.entries()].map(([e,n])=\u003e({...t,edgeId:`${t.edgeId}__z${e}`,nodeIds:n[0].nodeIds,availableZ:[e],portPoints:n}))}getOutput(){return{capacityMeshNodes:this.outputNodes,sharedEdgeSegments:this.outputSharedEdgeSegments}}getConstructorParams(){return[this.params]}visualize(){return{rects:this.outputNodes.map(t=\u003e({...Dc(t),label:`${t.capacityMeshNodeId}\\n${t.layer}`})),points:this.outputSharedEdgeSegments.flatMap(t=\u003et.portPoints.map(t=\u003e({x:t.x,y:t.y,label:`${t.segmentPortPointId}\\nz${t.availableZ.join(\",\")}`})))}}};function cK(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var lK=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;nodeSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityForceImproveRoutes;highDensityRepairSolver;highDensityRepairRoutes;highDensityStitchSolver;globalDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;splitNodesIntoSingleLayerNodeSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[cK(\"preprocessSimpleRouteJsonSolver\",_X,t=\u003e[t.originalSrj],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),cK(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),cK(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),cK(\"nodeSolver\",Kn,t=\u003e[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=\u003e{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),cK(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver?.outputNodes??[]}}),cK(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),cK(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),cK(\"necessaryCrampedPortPointSolver\",sf,t=\u003e[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),cK(\"splitNodesIntoSingleLayerNodeSolver\",aK,t=\u003e[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput()}],{onSolved:t=\u003e{t.capacityNodes=t.splitNodesIntoSingleLayerNodeSolver.getOutput().capacityMeshNodes}}),cK(\"portPointPathingSolver\",jj,t=\u003e{const e=t.splitNodesIntoSingleLayerNodeSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:e.capacityMeshNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.sharedEdgeSegments.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections,assignableViaObstacles:t.originalSrj.obstacles});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),cK(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),cK(\"highDensityRouteSolver\",zs,t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length\u003e0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]}),cK(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.getHighDensityNodePortPointsWithAssignableViasFirst(),hdRoutes:t.getMovableHighDensityRoutes(t.highDensityRouteSolver.routes),colorMap:t.colorMap,totalStepsPerNode:Math.max(20,Math.round(60*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}],{onSolved:t=\u003e{t.highDensityForceImproveRoutes=t.mergeMovableHighDensityRoutesBack(t.highDensityRouteSolver.routes,t.highDensityForceImproveSolver.getOutput())}}),cK(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.getHighDensityNodePortPointsWithAssignableViasFirst(),hdRoutes:t.getMovableHighDensityRoutes(t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes),obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2}],{onSolved:t=\u003e{const e=t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes;t.highDensityRepairRoutes=t.mergeMovableHighDensityRoutesBack(e,t.highDensityRepairSolver.getOutput())}}),cK(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairRoutes??t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,allowedLayerTransitionPointKeys:uf(t.originalSrj.obstacles)}]),cK(\"traceSimplificationSolver\",vc,t=\u003e[{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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,iterations:2}]),cK(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),cK(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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\u0026\u0026(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\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.nodeSolver?.visualize(),o=this.nodeDimensionSubdivisionSolver?.visualize(),i=this.nodeTargetMerger?.visualize(),r=this.singleLayerNodeMerger?.visualize(),s=this.strawSolver?.visualize(),a=this.edgeSolver?.visualize(),c=this.deadEndSolver?.visualize(),l=this.availableSegmentPointSolver?.visualize(),d=this.splitNodesIntoSingleLayerNodeSolver?.visualize(),h=this.portPointPathingSolver?.visualize(),u=this.multiSectionPortPointOptimizer?.visualize(),p=this.uniformPortDistributionSolver?.visualize(),m=this.highDensityRouteSolver?.visualize(),g=this.highDensityForceImproveSolver?.visualize(),f=this.highDensityRepairSolver?.visualize(),y=this.highDensityStitchSolver?.visualize(),_=this.traceSimplificationSolver?.visualize(),b=this.necessaryCrampedPortPointSolver?.visualize(),x=(this.highDensityRouteSolver?.visualize(),this.originalSrj),v=x.outline,S=[];if(S.push({points:[{x:x.bounds?.minX??-50,y:x.bounds?.minY??-50},{x:x.bounds?.maxX??50,y:x.bounds?.minY??-50},{x:x.bounds?.maxX??50,y:x.bounds?.maxY??50},{x:x.bounds?.minX??-50,y:x.bounds?.maxY??50},{x:x.bounds?.minX??-50,y:x.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),v\u0026\u0026v.length\u003e=2){const t=v.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),S.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const I=Oo(x),C={points:[...x.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,x.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(x.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,x.layerCount),label:I(t)}))],lines:S},P=Yj({srj:x}),M=[pi(C,P),t,e,n,o,i,r,s,a,c,l,b,d,h,u,p,m?pi(C,m):null,g,f,y,_,this.solved?pi({lines:S},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...M)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){const t=this.globalDrcForceImproveSolver?.getOutput();return t\u0026\u0026this.routesOnlyUsePreplacedVias(t)?t:this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityRepairRoutes??this.highDensityForceImproveRoutes??this.highDensityStitchSolver.mergedHdRoutes}routesOnlyUsePreplacedVias(t){const e=uf(this.originalSrj.obstacles);return 0===e.size||t.every(t=\u003et.vias.every(t=\u003ee.has(af(t))))}getHighDensityNodePortPointsWithAssignableViasFirst(){return[...this.highDensityNodePortPoints??[]].sort((t,e)=\u003e{const n=t.capacityMeshNodeId.startsWith(\"assignable-via:\");return n===e.capacityMeshNodeId.startsWith(\"assignable-via:\")?0:n?-1:1})}getPreplacedAssignableViaObstacles(){return this.originalSrj.obstacles.filter(t=\u003e!0===t.netIsAssignable\u0026\u0026(t.layers?.length??0)\u003e1)}isFixedPreplacedViaRoute(t){const e=this.getPreplacedAssignableViaObstacles();return 0!==e.length\u0026\u00260!==t.vias.length\u0026\u0026e.some(e=\u003e[...t.route,...t.vias].every(t=\u003eBe(t,e)\u003c=0))}getMovableHighDensityRouteIndexes(t){return t.map((t,e)=\u003ethis.isFixedPreplacedViaRoute(t)?-1:e).filter(t=\u003e-1!==t)}getMovableHighDensityRoutes(t){return this.getMovableHighDensityRouteIndexes(t).map(e=\u003et[e])}mergeMovableHighDensityRoutesBack(t,e){const n=this.getMovableHighDensityRouteIndexes(t),o=[...t];for(let t=0;t\u003cn.length;t++)o[n[t]]=e[t];return o}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 o=n.__netConnectionName??this.originalSrj.connections.find(t=\u003et.name===n.name)?.__netConnectionName,i=e.filter(t=\u003et.connectionName===n.name);for(let e=0;e\u003ci.length;e++){const r=i[e],s={type:\"pcb_trace\",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.srj.obstacles,connMap:this.connMap})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},dK=(t,e)=\u003e{const n=t.filter(t=\u003e(t.rootConnectionName??t.connectionName)===e);if(0!==n.length)return n.reduce((t,e)=\u003et+e.route.slice(1).reduce((t,n,o)=\u003e{const i=e.route[o];return t+Math.hypot(n.x-i.x,n.y-i.y)},0),0)},hK=(t,e)=\u003e{const n=new Set(t.flatMap(t=\u003evoid 0===t.maxLengthSkew?[]:t.connectionNames));return e.flatMap(t=\u003e{if(!n.has(t.name))return[];const e=t.pointsToConnect[0],o=t.pointsToConnect.at(-1);if(!e||!o||e===o)throw new Error(`Length matching: bus connection \"${t.name}\" needs at least two points`);return[{...t,pointsToConnect:[e,o]}]})},uK=class extends si{constructor(t){super(),this.params=t,this.differentialPairSolver=new lU({hdRoutes:t.hdRoutes,differentialPairs:t.differentialPairs,obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,minTraceToPadEdgeClearance:t.obstacleMargin}),this.MAX_ITERATIONS=this.differentialPairSolver.MAX_ITERATIONS+1e5+10}params;differentialPairSolver;busLengthMatchingSolver;outputHdRoutes;getSolverName(){return\"LengthMatchingPostProcessingSolver\"}_step(){if(!this.differentialPairSolver.solved)return this.differentialPairSolver.step(),void(this.differentialPairSolver.failed\u0026\u0026(this.failed=!0,this.error=this.differentialPairSolver.error));if(!this.busLengthMatchingSolver){const n=this.differentialPairSolver.getOutput().hdRoutes,o=(t=this.params.buses,e=n,t.flatMap(t=\u003e{const n=t.maxLengthSkew;if(void 0===n||t.connectionNames.length\u003c2)return[];const o=t.connectionNames.map(n=\u003e{const o=dK(e,n);if(void 0===o)throw new Error(`Length matching: bus \"${t.busId}\" has no routed geometry for connection \"${n}\"`);return{connectionName:n,length:o}}),i=o.reduce((t,e)=\u003ee.length\u003et.length?e:t);return o.flatMap(t=\u003et.connectionName===i.connectionName?[]:[{connectionNames:[t.connectionName,i.connectionName],lengthTolerance:n}])}));return 0===o.length?(this.outputHdRoutes=n,void(this.solved=!0)):void(this.busLengthMatchingSolver=new RG({hdRoutes:n,originalConnections:hK(this.params.buses,this.params.connections),differentialPairs:o,obstacles:this.params.obstacles,bounds:this.params.bounds,layerCount:this.params.layerCount,obstacleMargin:this.params.obstacleMargin}))}var t,e;if(this.busLengthMatchingSolver.step(),this.busLengthMatchingSolver.failed)return this.failed=!0,void(this.error=this.busLengthMatchingSolver.error);this.busLengthMatchingSolver.solved\u0026\u0026(this.outputHdRoutes=this.busLengthMatchingSolver.getOutput().matchedHdRoutes,((t,e)=\u003e{for(const n of t){if(void 0===n.maxLengthSkew||n.connectionNames.length\u003c2)continue;const t=n.connectionNames.map(t=\u003e{const o=dK(e,t);if(void 0===o)throw new Error(`Length matching: bus \"${n.busId}\" lost routed geometry for connection \"${t}\"`);return o}),o=Math.max(...t)-Math.min(...t);if(o\u003en.maxLengthSkew+1e-6)throw new Error(`Length matching: bus \"${n.busId}\" routed length skew ${o.toFixed(4)}mm exceeds ${n.maxLengthSkew.toFixed(4)}mm`)}})(this.params.buses,this.outputHdRoutes),this.solved=!0)}getOutput(){if(!this.solved||!this.outputHdRoutes)throw new Error(\"LengthMatchingPostProcessingSolver output requested before completion\");return{hdRoutes:this.outputHdRoutes}}visualize(){return this.busLengthMatchingSolver?.visualize()??this.differentialPairSolver.visualize()}},pK=1e-9,mK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=pK\u0026\u0026Math.abs(t.y-e.y)\u003c=pK\u0026\u0026t.z===e.z,gK=(t,e)=\u003e{if(0===t.length)return void t.push(...e.route);const n=t.at(-1);if(e.route[0]\u0026\u0026mK(n,e.route[0]))t.push(...e.route.slice(1));else{if(!e.route.at(-1)||!mK(n,e.route.at(-1)))throw new Error(`Pipeline9 could not reconnect mutated preloaded segment \"${e.connectionName}\"`);t.push(...e.route.slice(0,-1).reverse())}},fK=(t,e)=\u003e{const n=t.preloadedRoutePositionStart??t.preloadedRouteIndex,o=e.preloadedRoutePositionStart??e.preloadedRouteIndex,i=t.preloadedRoutePositionEnd??n,r=e.preloadedRoutePositionEnd??o;return n-o||i-r||t.preloadedRouteIndex-e.preloadedRouteIndex||t.connectionName.localeCompare(e.connectionName)},yK=t=\u003e{const e=t.route.flatMap(t=\u003e\"wire\"===t.route_type||\"through_obstacle\"===t.route_type?[t.width]:[]);return e.length\u003e0?Math.max(...e):void 0},_K=({trace:t,updatedTraceRoutes:e,layerCount:n,defaultViaHoleDiameter:o,obstacles:i,connMap:r})=\u003e{if(0===e.length)throw new Error(`Pipeline9 lost every fixed route for mutated trace \"${t.pcb_trace_id}\"`);const s=[];let a,c=0,l=0;for(const t of[...e].sort(fK))gK(s,t),c=Math.max(c,t.traceThickness),l=Math.max(l,t.viaDiameter),a??=t.rootConnectionName;const d={connectionName:t.connection_name,rootConnectionName:a,traceThickness:yK(t)??c,viaDiameter:l,route:s,vias:s.slice(0,-1).flatMap((t,e)=\u003e{const n=s[e+1];return t.z!==n.z\u0026\u0026Math.abs(t.x-n.x)\u003c=pK\u0026\u0026Math.abs(t.y-n.y)\u003c=pK?[{x:n.x,y:n.y}]:[]})};return Mo(d,n,{defaultViaHoleDiameter:o,obstacles:i,connMap:r})},bK=(t,e)=\u003et.filter(t=\u003e{if(!0===t.isThroughObstacle)return!1;const n=t.preloadedRoutePositionStart,o=t.preloadedRoutePositionEnd;if(void 0===n||void 0===o)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" is missing route-position metadata`);const i=Math.min(n,o),r=Math.max(n,o);return i\u003e=e.routePositionStart-pK\u0026\u0026r\u003c=e.routePositionEnd+pK}),xK=({trace:t,originalTraceRoutes:e,updatedTraceRoutes:n,layerCount:o,defaultViaHoleDiameter:i,obstacles:r,connMap:s})=\u003e{if(0===n.length)throw new Error(`Pipeline9 lost every fixed route for mutated trace \"${t.pcb_trace_id}\"`);const a=(t=\u003e{const e=[];let n=0;for(let o=0;o\u003ct.route.length;o++)\"through_obstacle\"===t.route[o]?.route_type\u0026\u0026(n\u003co\u0026\u0026e.push({routePositionStart:n,routePositionEnd:o-1}),n=o+1);return n\u003ct.route.length\u0026\u0026e.push({routePositionStart:n,routePositionEnd:t.route.length-1}),e})(t),c=n.filter(t=\u003e!0!==t.isThroughObstacle);for(const t of c){if(1!==a.filter(e=\u003ebK([t],e).includes(t)).length)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" crosses an immutable through-obstacle primitive`)}const l=[];let d=0;for(const c of a){l.push(...t.route.slice(d,c.routePositionStart));const a=bK(e,c),h=bK(n,c);if(a.length\u003e0\u0026\u00260===h.length)throw new Error(`Pipeline9 lost every fixed route for an ordinary section of mutated trace \"${t.pcb_trace_id}\"`);l.push(...h.length\u003e0?_K({trace:t,updatedTraceRoutes:h,layerCount:o,defaultViaHoleDiameter:i,obstacles:r,connMap:s}):t.route.slice(c.routePositionStart,c.routePositionEnd+1)),d=c.routePositionEnd+1}return l.push(...t.route.slice(d)),l},vK=(t,e)=\u003e{const n=new Set(e.map(t=\u003et.pcb_trace_id));return t.map(t=\u003e{if(!n.has(t.pcb_trace_id))return n.add(t.pcb_trace_id),t;const e=`${t.pcb_trace_id}_routed`;let o=e,i=2;for(;n.has(o);)o=`${e}_${i}`,i+=1;return n.add(o),{...t,pcb_trace_id:o}})},SK=(t,e,n)=\u003e{const o=t=\u003e`${t.x}:${t.y}`,i=new Map;for(const t of e){const e=o(t.center),n=i.get(e)??[];n.push(t),i.set(e,n)}const r=new Map;for(const e of t)for(const t of e.pointsToConnect){if(!t.pcb_port_id)continue;const e=r.get(t.pcb_port_id)??new Set,s=\"layers\"in t?t.layers:[t.layer];for(const t of s)e.add(ko(t,n));for(const r of i.get(o(t))??[])if(!(r.layers.length\u003c=1)\u0026\u0026r.connectedTo.includes(t.pcb_port_id))for(const t of r.layers)e.add(ko(t,n));r.set(t.pcb_port_id,e)}return r},IK=(t,e)=\u003enew Map(t.flatMap(t=\u003e{const n=e.getNetConnectedToId(t.connectionName)??(t.rootConnectionName?e.getNetConnectedToId(t.rootConnectionName)??(e.netMap[t.rootConnectionName]?t.rootConnectionName:void 0):void 0);return n?[[t.connectionName,n]]:[]})),CK=1e-9,PK=1e-6,MK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=PK\u0026\u0026Math.abs(t.y-e.y)\u003c=PK\u0026\u0026t.z===e.z,NK=t=\u003enew Map(t.map((t,e)=\u003e[t.pcb_trace_id,e])),wK=(t,e)=\u003e{const n=t[0],o=t.at(-1);if(!n||!o)throw new Error(\"Pipeline9 cannot split an empty preloaded route\");if(n.z!==o.z)throw new Error(\"Pipeline9 cannot partially split a preloaded layer transition\");return{...n,x:n.x+(o.x-n.x)*e,y:n.y+(o.y-n.y)*e}},TK=({traces:t,fixedHdRoutes:e,sections:n})=\u003e{const o=(({traces:t,sections:e})=\u003e{const n=NK(t),o=new Map;for(const t of e){const e=n.get(t.traceId);if(void 0===e)throw new Error(`Pipeline9 hypergraph changed missing preloaded trace \"${t.traceId}\"`);const i=o.get(e)??[];i.push({start:Math.min(t.startRoutePosition,t.endRoutePosition),end:Math.max(t.startRoutePosition,t.endRoutePosition)}),o.set(e,i)}for(const t of o.values())t.sort((t,e)=\u003et.start-e.start||t.end-e.end);return o})({traces:t,sections:n});return e.flatMap(t=\u003e{const e=o.get(t.preloadedTraceIndex);if(!e?.length)return[t];const n=t.preloadedRoutePositionStart,i=t.preloadedRoutePositionEnd;if(void 0===n||void 0===i)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" is missing route-position metadata`);if(Math.abs(i-n)\u003c=CK)return e.some(t=\u003et.start-CK\u003c=n\u0026\u0026n\u003c=t.end+CK)?[]:[t];let r=[{start:n,end:i}];for(const t of e)r=r.flatMap(e=\u003e{if(t.end\u003c=e.start+CK||t.start\u003e=e.end-CK)return[e];const n=[];return t.start\u003ee.start+CK\u0026\u0026n.push({start:e.start,end:Math.min(t.start,e.end)}),t.end\u003ce.end-CK\u0026\u0026n.push({start:Math.max(t.end,e.start),end:e.end}),n});return r.map((e,o)=\u003e{const r=(e.start-n)/(i-n),s=(e.end-n)/(i-n);return{...t,connectionName:`${t.connectionName}_hypergraph_fixed_${o}`,preloadedRoutePositionStart:e.start,preloadedRoutePositionEnd:e.end,route:[wK(t.route,r),wK(t.route,s)],vias:[]}})})},RK=({traces:t,sections:e,stitchedHdRoutes:n,layerCount:o})=\u003e{const i=NK(t);return e.map((t,r)=\u003e{const s=i.get(t.traceId);if(void 0===s)throw new Error(`Pipeline9 cannot materialize missing preloaded trace \"${t.traceId}\"`);const[a,c]=((t,e)=\u003e{const n=t.connection.pointsToConnect.map(t=\u003e({x:t.x,y:t.y,z:ko(bo(t),e)}));if(!n[0]||!n[1])throw new Error(`Pipeline9 changed section \"${t.connectionName}\" is missing an endpoint`);return[n[0],n[1]]})(t,o),l=n.flatMap(e=\u003e{if(e.connectionName!==t.connectionName)return[];const n=(({route:t,sectionStart:e,sectionEnd:n})=\u003e{const o=t.route[0],i=t.route.at(-1);if(!o||!i)return null;const r=o.z===e.z\u0026\u0026i.z===n.z,s=o.z===n.z\u0026\u0026i.z===e.z,a=r?xe(o,e)+xe(i,n):Number.POSITIVE_INFINITY,c=s?xe(o,n)+xe(i,e):Number.POSITIVE_INFINITY;return Number.isFinite(a)||Number.isFinite(c)?a\u003c=c?{score:a,reverse:!1}:{score:c,reverse:!0}:null})({route:e,sectionStart:a,sectionEnd:c});return n?[{route:e,...n}]:[]});l.sort((t,e)=\u003et.score-e.score);const d=l[0],h=l[1];if(!d||h\u0026\u0026Math.abs(h.score-d.score)\u003c=PK)throw new Error(`Pipeline9 expected one nearest stitched route for changed preloaded section \"${t.connectionName}\", got ${l.length}`);const u=(({route:t,reverse:e,sectionStart:n,sectionEnd:o})=\u003e{const i=e?(t=\u003e{const e=[...t].reverse().map(t=\u003e{const{toNextSegmentType:e,...n}=t;return n});for(let n=0;n\u003ct.length-1;n++){const o=t[n]?.toNextSegmentType;o\u0026\u0026(e[t.length-n-2]={...e[t.length-n-2],toNextSegmentType:o})}return e})(t.route):[...t.route];if(!i[0]||!i.at(-1))throw new Error(`Pipeline9 cannot materialize empty route \"${t.connectionName}\"`);return MK(i[0],n)||i.unshift(n),MK(i.at(-1),o)||i.push(o),{...t,route:i}})({route:d.route,reverse:d.reverse,sectionStart:a,sectionEnd:c});return{...u,preloadedTraceIndex:s,preloadedRouteIndex:Number.MAX_SAFE_INTEGER-e.length+r,preloadedRoutePositionStart:t.startRoutePosition,preloadedRoutePositionEnd:t.endRoutePosition,isThroughObstacle:!1}})},EK=1e-6,AK=t=\u003et.map(t=\u003e{const e=[];for(const n of t.route){const o=e.at(-1);if(!o||o.z===n.z||\"through_obstacle\"===o.toNextSegmentType){e.push(n);continue}const i=Math.abs(o.x-n.x)\u003c=EK\u0026\u0026Math.abs(o.y-n.y)\u003c=EK,r=t.vias.some(t=\u003eMath.abs(t.x-o.x)\u003c=EK\u0026\u0026Math.abs(t.y-o.y)\u003c=EK),s=t.vias.some(t=\u003eMath.abs(t.x-n.x)\u003c=EK\u0026\u0026Math.abs(t.y-n.y)\u003c=EK);if(i)e.push(n);else{if(!r\u0026\u0026!s)throw new Error(`Pipeline9 route \"${t.connectionName}\" changes layers from z=${o.z} to z=${n.z} without an explicit via`);if(r===s)throw new Error(`Pipeline9 route \"${t.connectionName}\" has an ambiguous layer transition between (${o.x}, ${o.y}) and (${n.x}, ${n.y})`);r?e.push({x:o.x,y:o.y,z:n.z}):e.push({x:n.x,y:n.y,z:o.z}),e.push(n)}}return{...t,route:e}}),OK=1e-9,kK=t=\u003e({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}),LK=(t,e)=\u003et.x\u003e=e.minX-OK\u0026\u0026t.x\u003c=e.maxX+OK\u0026\u0026t.y\u003e=e.minY-OK\u0026\u0026t.y\u003c=e.maxY+OK,DK=(t,e,n)=\u003en\u003c=OK?t:n\u003e=.999999999?e:{x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n,z:t.z},zK=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;if(Math.abs(o)\u003c=OK\u0026\u0026Math.abs(i)\u003c=OK)return LK(t,n)\u0026\u0026LK(e,n)?{start:t,end:e}:null;let r=0,s=1;const a=[[-o,t.x-n.minX],[o,n.maxX-t.x],[-i,t.y-n.minY],[i,n.maxY-t.y]];for(const[t,e]of a){if(Math.abs(t)\u003c=OK){if(e\u003c0)return null;continue}const n=e/t;if(t\u003c0?r=Math.max(r,n):s=Math.min(s,n),r\u003es+OK)return null}return{start:DK(t,e,r),end:DK(t,e,s)}},FK=t=\u003e{const e=t.sourceRoutes[0],n=`pipeline9_fallback:${e.connectionName}`,o=`${n}:start`,i=`${n}:end`;return[{...t.start.point,portPointId:o,nextPortPointId:i,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName},{...t.end.point,portPointId:i,prevPortPointId:o,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName}]},BK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=OK\u0026\u0026Math.abs(t.y-e.y)\u003c=OK\u0026\u0026t.z===e.z,jK=(t,e)=\u003et.sourceRoute.preloadedTraceIndex===e.sourceRoute.preloadedTraceIndex\u0026\u0026BK(t.sourceRoute.route.at(-1),e.sourceRoute.route[0]),$K=(t,e,n=new Set)=\u003e{const o=new Map,i=[],r=new Set(t.portPoints.map(t=\u003et.z)),s=e.map(e=\u003e((t,e)=\u003e{const n=kK(e);let o,i;for(let e=0;e\u003ct.route.length-1;e++){const r=zK(t.route[e],t.route[e+1],n);r\u0026\u0026(o??={segmentIndex:e,point:r.start},i={segmentIndex:e,point:r.end})}return o\u0026\u0026i?Math.abs(o.point.x-i.point.x)\u003c=OK\u0026\u0026Math.abs(o.point.y-i.point.y)\u003c=OK\u0026\u0026o.point.z===i.point.z?null:{sourceRoute:t,start:o,end:i}:null})(e,t)).filter(t=\u003enull!==t),a=s.filter(t=\u003e!0!==t.sourceRoute.isThroughObstacle\u0026\u0026(((t,e)=\u003e0===e.size||[t.start.point,...t.sourceRoute.route.slice(t.start.segmentIndex+1,t.end.segmentIndex+1),t.end.point].some(t=\u003ee.has(t.z)))(t,r)||n.has(t.sourceRoute.connectionName))).sort((t,e)=\u003et.sourceRoute.preloadedTraceIndex-e.sourceRoute.preloadedTraceIndex||t.sourceRoute.preloadedRouteIndex-e.sourceRoute.preloadedRouteIndex),c=new Set(a.map(t=\u003et.sourceRoute)),l=s.map(t=\u003et.sourceRoute).filter(t=\u003e!c.has(t)),d=[];for(let t=0;t\u003ca.length;t++){const e=a[t],n=a[t-1],o=d.at(-1);n\u0026\u0026o\u0026\u0026jK(n,e)?(o.sourceRoutes.push(e.sourceRoute),o.end=e.end):d.push({sourceRoutes:[e.sourceRoute],start:e.start,end:e.end})}for(const t of d){const e=t.sourceRoutes[0].connectionName;if(o.has(e))throw new Error(`Pipeline9 regional fallback found duplicate fixed route section identity \"${e}\"`);o.set(e,t),i.push(FK(t))}return{nodeWithPortPoints:{...t,portPoints:[...t.portPoints,...i.flatMap(t=\u003et)],portPointsInPairs:[...t.portPointsInPairs??[],...i]},fixedRouteSectionsByConnectionName:o,fixedObstacleRoutes:l}},YK=t=\u003e{const e=[];for(let n=0;n\u003ct.length-1;n++){const o=t[n],i=t[n+1];o.z!==i.z\u0026\u0026Math.abs(o.x-i.x)\u003c=OK\u0026\u0026Math.abs(o.y-i.y)\u003c=OK\u0026\u0026e.push({x:i.x,y:i.y})}return e},XK=(t,e)=\u003eVK({section:t,replacement:e,sourceMutationMasks:new Map,replacementIsMutated:!1}).route,VK=({section:t,replacement:e,sourceMutationMasks:n,replacementIsMutated:o})=\u003e{const i=t.sourceRoutes[0],r=t.sourceRoutes.at(-1),s=((t,e)=\u003e{const n=t.route,o=n[0],i=n.at(-1);if(!o||!i)throw new Error(`Pipeline9 regional fallback produced an empty replacement for \"${e.sourceRoutes[0].connectionName}\"`);const r=Math.hypot(o.x-e.start.point.x,o.y-e.start.point.y)+Math.hypot(i.x-e.end.point.x,i.y-e.end.point.y);return Math.hypot(i.x-e.start.point.x,i.y-e.start.point.y)+Math.hypot(o.x-e.end.point.x,o.y-e.end.point.y)\u003cr?[...n].reverse():n})(e,t),a=[],c=[],l=(t,e)=\u003e{const o=n.get(t.connectionName);if(o\u0026\u0026o.length!==t.route.length-1)throw new Error(`Pipeline9 fixed route mutation mask for \"${t.connectionName}\" has ${o.length} segments, expected ${t.route.length-1}`);return o?.[e]??!1},d=(t,e)=\u003e{const n=a.at(-1);if(n){if(!BK(n,t)){if(n.z!==t.z\u0026\u0026(Math.abs(n.x-t.x)\u003eOK||Math.abs(n.y-t.y)\u003eOK)){const o={...t,z:n.z};BK(n,o)||(a.push(o),c.push(e))}BK(a.at(-1),t)||(a.push(t),c.push(e))}}else a.push(t)};d(i.route[0],!1);for(let e=1;e\u003c=t.start.segmentIndex;e++)d(i.route[e],l(i,e-1));d(t.start.point,l(i,t.start.segmentIndex));const h=c.length;for(const t of s.slice(1,-1))d(t,o);d(t.end.point,o);const u=c.length\u003eh;for(let e=t.end.segmentIndex+1;e\u003cr.route.length;e++)d(r.route[e],l(r,e-1));if(c.length!==a.length-1)throw new Error(`Pipeline9 produced an invalid mutation mask while splicing \"${i.connectionName}\"`);return{route:{...i,preloadedRoutePositionStart:i.preloadedRoutePositionStart,preloadedRoutePositionEnd:r.preloadedRoutePositionEnd,traceThickness:Math.max(...t.sourceRoutes.map(t=\u003et.traceThickness)),viaDiameter:Math.max(...t.sourceRoutes.map(t=\u003et.viaDiameter)),route:a,vias:YK(a)},mutatedSegments:c,replacementProducedSegment:u}},WK=1e-6,HK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=WK\u0026\u0026Math.abs(t.y-e.y)\u003c=WK\u0026\u0026t.z===e.z,GK=(t,e)=\u003e{for(const n of e)t.at(-1)\u0026\u0026HK(t.at(-1),n)||t.push(n)},UK=t=\u003et.slice(0,-1).flatMap((e,n)=\u003e{const o=t[n+1];return e.z!==o.z\u0026\u0026Math.abs(e.x-o.x)\u003c=WK\u0026\u0026Math.abs(e.y-o.y)\u003c=WK?[{x:o.x,y:o.y}]:[]}),ZK=t=\u003e{const e=t.preloadedRoutePositionStart,n=t.preloadedRoutePositionEnd;if(void 0===e||void 0===n)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" is missing route-position metadata`);return{start:Math.min(e,n),end:Math.max(e,n)}},qK=(t,e)=\u003e{const n=ZK(t),o=ZK(e);return t.preloadedTraceIndex-e.preloadedTraceIndex||n.start-o.start||n.end-o.end||t.preloadedRouteIndex-e.preloadedRouteIndex||t.connectionName.localeCompare(e.connectionName)},JK=(t,e)=\u003e{const n=t.route.at(-1),o=e.route[0];return Boolean(n\u0026\u0026o\u0026\u0026t.preloadedTraceIndex===e.preloadedTraceIndex\u0026\u0026HK(n,o))},KK=(t,e)=\u003e{const n=t.preloadedRoutePositionStart??t.preloadedRouteIndex;return n+((t.preloadedRoutePositionEnd??t.preloadedRouteIndex)-n)*e/(t.route.length-1)},QK=(t,e)=\u003et.route[e].z!==t.route[e+1].z,tQ=({updatedFixedRoutes:t,regionalMutationMasks:e})=\u003e{const n=[],o=(({updatedFixedRoutes:t,regionalMutationMasks:e})=\u003e{const n=new Map;for(const o of t){if(0===o.route.length)throw new Error(`Pipeline9 cannot normalize empty fixed route \"${o.connectionName}\"`);const t=o.route.length-1;if(n.has(o.connectionName))throw new Error(`Pipeline9 cannot normalize duplicate fixed route \"${o.connectionName}\"`);const i=e.get(o.connectionName);if(i\u0026\u0026i.length!==t)throw new Error(`Pipeline9 fixed route mutation mask for \"${o.connectionName}\" has ${i.length} segments, expected ${t}`);const r=!0!==o.isThroughObstacle\u0026\u00260===(o.jumpers?.length??0);n.set(o.connectionName,Array.from({length:t},(t,e)=\u003er\u0026\u0026(i?.[e]??!1)))}let o=[];const i=()=\u003e{for(;o[0]\u0026\u0026QK(o[0].route,o[0].segmentIndex);){const t=o.shift();n.get(t.route.connectionName)[t.segmentIndex]=!1}for(;o.at(-1)\u0026\u0026QK(o.at(-1).route,o.at(-1).segmentIndex);){const t=o.pop();n.get(t.route.connectionName)[t.segmentIndex]=!1}o=[]};let r;for(const e of[...t].sort(qK)){r\u0026\u0026!JK(r,e)\u0026\u0026i();const t=n.get(e.connectionName);if(0!==t.length){for(let n=0;n\u003ct.length;n++)t[n]?o.push({route:e,segmentIndex:n}):i();r=e}else i(),r=e}return i(),n})({updatedFixedRoutes:t,regionalMutationMasks:e});for(const e of t){const t=e.route.length-1,i=o.get(e.connectionName);if(0===t){n.push({route:e,mutated:!1});continue}const r=[];for(let e=0;e\u003ct;e++){const t=i[e],n=r.at(-1);n?.mutated===t?n.end=e+1:r.push({start:e,end:e+1,mutated:t})}for(const[t,o]of r.entries()){const i=e.route.slice(o.start,o.end+1),s={...e,connectionName:1===r.length?e.connectionName:`${e.connectionName}_mutation_fragment_${t}`,preloadedRouteIndex:e.preloadedRouteIndex+t/(r.length+1),preloadedRoutePositionStart:KK(e,o.start),preloadedRoutePositionEnd:KK(e,o.end),route:i,vias:UK(i)};n.push({route:s,mutated:o.mutated})}}return n},eQ=({updatedFixedRoutes:t,regionalMutationMasks:e})=\u003e{const n=tQ({updatedFixedRoutes:t,regionalMutationMasks:e}),o=n.map(({route:t})=\u003et),i=(t=\u003e{const e=[];let n;for(const o of[...t].sort((t,e)=\u003eqK(t.route,e.route))){const t=o.route;if(!o.mutated){n=void 0;continue}const i=t.route[0],r=t.route.at(-1);if(!i||!r||t.route.length\u003c2)throw new Error(`Pipeline9 cannot simplify empty fixed route \"${t.connectionName}\"`);const s=n?.sourceRoutes.at(-1);n\u0026\u0026s\u0026\u0026JK(s,t)?(n.sourceRoutes.push(t),n.end={segmentIndex:t.route.length-2,point:r}):(n={sourceRoutes:[t],start:{segmentIndex:0,point:i},end:{segmentIndex:t.route.length-2,point:r}},e.push(n))}return e})(n),r=i.map((t,e)=\u003e{const n=((t,e)=\u003e{const n=t.sourceRoutes[0],o=t.sourceRoutes.at(-1);if(!n||!o)throw new Error(\"Pipeline9 cannot simplify an empty mutation section\");const i=[t.start.point];for(const[e,n]of t.sourceRoutes.entries()){const o=0===e,r=e===t.sourceRoutes.length-1,s=o?t.start.segmentIndex+1:0,a=r?t.end.segmentIndex+1:n.route.length;GK(i,n.route.slice(s,a))}if(GK(i,[t.end.point]),i.length\u003c2)throw new Error(`Pipeline9 mutation section for \"${n.connectionName}\" has no routable span`);return{connectionName:`pipeline9_mutated_preload_${n.preloadedTraceIndex}_${e}`,rootConnectionName:n.rootConnectionName,traceThickness:Math.max(...t.sourceRoutes.map(t=\u003et.traceThickness)),viaDiameter:Math.max(...t.sourceRoutes.map(t=\u003et.viaDiameter)),route:i,vias:UK(i)}})(t,e);return{connectionName:n.connectionName,section:t,hdRoute:n}}),s=new Set(r.flatMap(({section:t})=\u003et.sourceRoutes.map(t=\u003et.connectionName)));return{sections:r,immutableHdRoutes:o.filter(t=\u003e!s.has(t.connectionName)),normalizedFixedRoutes:o}},nQ=1e-9,oQ=(t,e,n,o,i)=\u003e{const r=i.getNetConnectedToId(t.connection_name)??t.connection_name,s=[],a=(n,i,a=o,c=[],l,d,h=!1)=\u003e{n.length\u003c2||s.push({connectionName:`${t.connection_name}_fixed_${e}_${s.length}`,rootConnectionName:r,preloadedTraceIndex:e,preloadedRouteIndex:s.length,preloadedRoutePositionStart:l,preloadedRoutePositionEnd:d,isThroughObstacle:h,traceThickness:Math.max(nQ,i),viaDiameter:Math.max(nQ,a),route:n,vias:c})};for(let e=0;e\u003ct.route.length;e++){const i=t.route[e];if(\"via\"===i.route_type){a([{x:i.x,y:i.y,z:ko(i.from_layer,n)},{x:i.x,y:i.y,z:ko(i.to_layer,n)}],nQ,i.via_diameter??o,[{x:i.x,y:i.y}],e,e);continue}if(\"through_obstacle\"===i.route_type){const t=ko(i.from_layer,n),r=ko(i.to_layer,n);for(let n=Math.min(t,r);n\u003c=Math.max(t,r);n++)a([{...i.start,z:n},{...i.end,z:n}],i.width,o,[],e,e+1,!0);continue}const r=t.route[e+1];\"wire\"===i.route_type\u0026\u0026\"wire\"===r?.route_type\u0026\u0026i.layer===r.layer\u0026\u0026a([{x:i.x,y:i.y,z:ko(i.layer,n)},{x:r.x,y:r.y,z:ko(r.layer,n)}],Math.max(i.width,r.width),o,[],e,e+1)}return s};function iQ(t,e){return{x:t.a*e.x+t.b*e.y+t.c,y:t.d*e.x+t.e*e.y+t.f}}var rQ={highResolutionCellSize:.1,highResolutionCellThickness:8,lowResolutionCellSize:.4,traceMargin:.15,traceThickness:.1,viaDiameter:.3,viaMinDistFromBorder:.15},sQ={...rQ},aQ=(t,e,n)=\u003e{const[o,i]=t;if(o===i)return;const r=((t,e)=\u003e{const n=t.portPointId??`${t.connectionName}:${t.x}:${t.y}:${t.z}`,o=e.portPointId??`${e.connectionName}:${e.x}:${e.y}:${e.z}`;return n\u003co?`${n}|${o}`:`${o}|${n}`})(o,i);e.has(r)||(e.add(r),n.push(t))},cQ=(t,e,n)=\u003e{for(let o=0;o\u003ct.length-1;o++)aQ([t[o],t[o+1]],e,n)},lQ=t=\u003e{const e=[],n=new Set,o=(t=\u003e{const e=new Map;for(const n of t)n.portPointId\u0026\u0026e.set(n.portPointId,n);return e})(t);for(const i of t){if(i.prevPortPointId){const t=o.get(i.prevPortPointId);t\u0026\u0026t.connectionName===i.connectionName\u0026\u0026aQ([t,i],n,e)}if(i.nextPortPointId){const t=o.get(i.nextPortPointId);t\u0026\u0026t.connectionName===i.connectionName\u0026\u0026aQ([i,t],n,e)}}if(0===e.length)return cQ(t,n,e),e;const i=(t=\u003e{const e=new Set;for(const[n,o]of t)n.portPointId\u0026\u0026e.add(n.portPointId),o.portPointId\u0026\u0026e.add(o.portPointId);return e})(e),r=t.filter(t=\u003e!t.portPointId||!i.has(t.portPointId));return cQ(r,n,e),e};function dQ(t,e,n){return Math.max(e,Math.min(n,t))}var hQ=[\"left\",\"top\",\"right\",\"bottom\",\"middle\"],uQ=class{f=new Float64Array(1024);seq=new Uint32Array(1024);id=new Int32Array(1024);n=0;push(t,e,n){this.ensureCapacity(this.n+1);let o=this.n++;for(this.f[o]=t,this.seq[o]=e,this.id[o]=n;o\u003e0;){const t=o-1\u003e\u003e1;if(this.less(t,o))break;this.swap(o,t),o=t}}pop(){const t=this.id[0];return this.n--,this.n\u003e0\u0026\u0026(this.f[0]=this.f[this.n],this.seq[0]=this.seq[this.n],this.id[0]=this.id[this.n],this.siftDown(0)),t}get size(){return this.n}clear(){this.n=0}ensureCapacity(t){if(t\u003c=this.f.length)return;let e=this.f.length;for(;e\u003ct;)e*=2;const n=new Float64Array(e);n.set(this.f),this.f=n;const o=new Uint32Array(e);o.set(this.seq),this.seq=o;const i=new Int32Array(e);i.set(this.id),this.id=i}siftDown(t){for(;;){const e=2*t+1,n=e+1;if(e\u003e=this.n)return;let o=e;if(n\u003cthis.n\u0026\u0026!this.less(e,n)\u0026\u0026(o=n),this.less(t,o))return;this.swap(t,o),t=o}}less(t,e){const n=this.f[t],o=this.f[e];return n!==o?n\u003co:this.seq[t]\u003cthis.seq[e]}swap(t,e){const n=this.f[t];this.f[t]=this.f[e],this.f[e]=n;const o=this.seq[t];this.seq[t]=this.seq[e],this.seq[e]=o;const i=this.id[t];this.id[t]=this.id[e],this.id[e]=i}},pQ=class{z=new Int32Array(1024);cellId=new Int32Array(1024);g=new Float64Array(1024);parent=new Int32Array(1024);ripHead=new Int32Array(1024).fill(-1);ripCount=new Int32Array(1024);length=0;clear(){this.length=0}push(t,e,n,o,i,r){this.ensureCapacity(this.length+1);const s=this.length++;return this.z[s]=t,this.cellId[s]=e,this.g[s]=n,this.parent[s]=o,this.ripHead[s]=i,this.ripCount[s]=r,s}ensureCapacity(t){if(t\u003c=this.z.length)return;let e=this.z.length;for(;e\u003ct;)e*=2;const n=new Int32Array(e);n.set(this.z),this.z=n;const o=new Int32Array(e);o.set(this.cellId),this.cellId=o;const i=new Float64Array(e);i.set(this.g),this.g=i;const r=new Int32Array(e);r.set(this.parent),this.parent=r;const s=new Int32Array(e);s.fill(-1),s.set(this.ripHead.subarray(0,this.length)),this.ripHead=s;const a=new Int32Array(e);a.set(this.ripCount.subarray(0,this.length)),this.ripCount=a}},mQ=class{connId=new Int32Array(1024);prev=new Int32Array(1024).fill(-1);length=0;clear(){this.length=0}append(t,e){this.ensureCapacity(this.length+1);const n=this.length++;return this.connId[n]=e,this.prev[n]=t,n}contains(t,e){for(let n=t;n\u003e=0;n=this.prev[n])if(this.connId[n]===e)return!0;return!1}collect(t,e){e.length=0;for(let n=t;n\u003e=0;n=this.prev[n])e.push(this.connId[n])}ensureCapacity(t){if(t\u003c=this.connId.length)return;let e=this.connId.length;for(;e\u003ct;)e*=2;const n=new Int32Array(e);n.set(this.connId),this.connId=n;const o=new Int32Array(e);o.fill(-1),o.set(this.prev.subarray(0,this.length)),this.prev=o}};function gQ(t,e){return e??t.replace(/_mst\\d+$/,\"\")}function fQ(t,e){const n=t.x-e.center.x,o=t.y-e.center.y,i=Math.cos(-e.rotationRadians),r=Math.sin(-e.rotationRadians);return{x:n*i-o*r,y:n*r+o*i}}function yQ(t){return{minX:-t.width/2,minY:-t.height/2,maxX:t.width/2,maxY:t.height/2}}function _Q(t,e,n){return Math.max(e,Math.min(n,t))}function bQ(t,e){for(let n=0;n\u003ct.length;n++)if(t[n]===e)return;t.push(e)}function xQ(t,e){for(let n=0;n\u003ct.length;n++)if(t[n].cellId===e.cellId)return;t.push(e)}function vQ(t,e,n,o,i,r,s){const a=t-_Q(t,o,r),c=e-_Q(e,i,s);return a*a+c*c\u003c=n*n}function SQ(t){const e=t.segmentEnd.x-t.segmentStart.x,n=t.segmentEnd.y-t.segmentStart.y,o=e**2+n**2;if(0===o)return(t.point.x-t.segmentStart.x)**2+(t.point.y-t.segmentStart.y)**2;const i=_Q(((t.point.x-t.segmentStart.x)*e+(t.point.y-t.segmentStart.y)*n)/o,0,1),r=t.segmentStart.x+i*e,s=t.segmentStart.y+i*n;return(t.point.x-r)**2+(t.point.y-s)**2}function IQ(t){const e=_Q(t.point.x,t.rect.minX,t.rect.maxX),n=_Q(t.point.y,t.rect.minY,t.rect.maxY),o=t.point.x-e,i=t.point.y-n;return o*o+i*i}function CQ(t){return(t.second.x-t.first.x)*(t.third.y-t.first.y)-(t.second.y-t.first.y)*(t.third.x-t.first.x)}function PQ(t){return!(Math.abs(CQ({first:t.segmentStart,second:t.segmentEnd,third:t.point}))\u003e1e-9)\u0026\u0026(t.point.x\u003e=Math.min(t.segmentStart.x,t.segmentEnd.x)\u0026\u0026t.point.x\u003c=Math.max(t.segmentStart.x,t.segmentEnd.x)\u0026\u0026t.point.y\u003e=Math.min(t.segmentStart.y,t.segmentEnd.y)\u0026\u0026t.point.y\u003c=Math.max(t.segmentStart.y,t.segmentEnd.y))}function MQ(t){const e=CQ({first:t.firstStart,second:t.firstEnd,third:t.secondStart}),n=CQ({first:t.firstStart,second:t.firstEnd,third:t.secondEnd}),o=CQ({first:t.secondStart,second:t.secondEnd,third:t.firstStart}),i=CQ({first:t.secondStart,second:t.secondEnd,third:t.firstEnd});return e*n\u003c0\u0026\u0026o*i\u003c0||(PQ({point:t.secondStart,segmentStart:t.firstStart,segmentEnd:t.firstEnd})||PQ({point:t.secondEnd,segmentStart:t.firstStart,segmentEnd:t.firstEnd})||PQ({point:t.firstStart,segmentStart:t.secondStart,segmentEnd:t.secondEnd})||PQ({point:t.firstEnd,segmentStart:t.secondStart,segmentEnd:t.secondEnd}))}function NQ(t){return MQ(t)?0:Math.min(SQ({point:t.firstStart,segmentStart:t.secondStart,segmentEnd:t.secondEnd}),SQ({point:t.firstEnd,segmentStart:t.secondStart,segmentEnd:t.secondEnd}),SQ({point:t.secondStart,segmentStart:t.firstStart,segmentEnd:t.firstEnd}),SQ({point:t.secondEnd,segmentStart:t.firstStart,segmentEnd:t.firstEnd}))}function wQ(t){if(function(t){if(0===IQ({point:t.segmentStart,rect:t.rect})||0===IQ({point:t.segmentEnd,rect:t.rect}))return!0;const e=[{x:t.rect.minX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.maxY},{x:t.rect.minX,y:t.rect.maxY}];for(let n=0;n\u003ce.length;n++){const o=(n+1)%e.length;if(MQ({firstStart:t.segmentStart,firstEnd:t.segmentEnd,secondStart:e[n],secondEnd:e[o]}))return!0}return!1}(t))return!0;const e=t.radius**2;if(IQ({point:t.segmentStart,rect:t.rect})\u003c=e||IQ({point:t.segmentEnd,rect:t.rect})\u003c=e)return!0;return[{x:t.rect.minX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.maxY},{x:t.rect.minX,y:t.rect.maxY}].some(n=\u003eSQ({point:n,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd})\u003c=e)}var TQ=class extends kt{getSolverName(){return\"HighDensitySolverB01\"}nodeWithPortPoints;obstacles;highResolutionCellSize;highResolutionCellThickness;lowResolutionCellSize;viaDiameter;MAX_RIPS;maxCellCount;traceThickness;traceMargin;obstacleClearanceMargin;viaMinDistFromBorder;showPenaltyMap;showUsedCellMap;effort;stepMultiplier;hyperParameters;initialPenaltyFn;boundsMinX;boundsMaxX;boundsMinY;boundsMaxY;gridToBoundsTransform;availableZ;zToLayer;layerToZ;layers;fineRows;fineCols;lowScale;bandRows;bandCols;regions;planeSize;cellCenterX;cellCenterY;cellMinX;cellMinY;cellMaxX;cellMaxY;cellWidth;cellHeight;cellRegion;cellRow;cellCol;viaAllowed;neighborOffset;neighborIds;neighborCosts;usedCellsFlat;sharedCellsFlat;portOwnerFlat;penalty2d;ripStateBuckets;visitedStamp;bestGStamp;bestGValue;visitedFlatStamp;sharedCrossRootPortFlat;stamp=0;connNameToId;connIdToName;connIdToRootNet;overlapFriendlyRootNets;usedIndicesByConn;unsolvedSegs;solvedRoutes;activeConnSeg=null;activeConnId=-1;nodePool;heap;ripChain;seqCounter=0;_viaOccs=[];_cellOccs=[];_rippedIds=[];ripCount;totalRipEvents=0;searchIterations=0;consecutiveSkips=0;penaltyCap;baseSearchBudgetIters;_moveCost=0;_moveRippedHead=-1;_moveRipCount=0;traceKeepoutRadius;viaKeepoutRadius;obstacleTraceRootIdsFlat;obstacleViaRootIdsByCell;obstacleRootNameToId;obstacleRootNames;obstacleTracePrimitives;obstacleViaPrimitives;obstacleRectPrimitives;obstacleTraceBlockedCellCount=0;obstacleViaBlockedCellCount=0;get unsolvedConnections(){return this.unsolvedSegs}get solvedConnectionsMap(){const t=new Map;for(let e=0;e\u003cthis.solvedRoutes.length;e++){const n=this.getSolvedRoutesForConn(e);n.length\u003e0\u0026\u0026t.set(e,n)}return t}get activeConnection(){if(!this.activeConnSeg)return null;const t=this.activeConnSeg.startCellId,e=this.activeConnSeg.endCellId;return{connectionName:this.connIdToName[this.activeConnSeg.connId]??\"\",start:{cellId:t,region:hQ[this.cellRegion[t]],row:this.cellRow[t],col:this.cellCol[t],x:this.cellCenterX[t],y:this.cellCenterY[t],z:this.activeConnSeg.startZ},end:{cellId:e,region:hQ[this.cellRegion[e]],row:this.cellRow[e],col:this.cellCol[e],x:this.cellCenterX[e],y:this.cellCenterY[e],z:this.activeConnSeg.endZ}}}get openSet(){return{length:this.heap?.size??0}}get gridStats(){return{cells:this.planeSize||0,layers:this.layers||0,states:(this.planeSize||0)*(this.layers||0),ripStateBuckets:this.ripStateBuckets||0,neighborEdges:this.neighborIds?.length??0,regionCounts:this.regions?Object.fromEntries(this.regions.map(t=\u003e[t.name,t.rows*t.cols])):{},obstacleTraceBlockedCells:this.obstacleTraceBlockedCellCount,obstacleViaBlockedCells:this.obstacleViaBlockedCellCount,obstacleRootCount:this.obstacleRootNames?.length??0,obstacleRectCount:this.obstacleRectPrimitives?.length??0}}constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.obstacles=t.obstacles,this.highResolutionCellSize=t.highResolutionCellSize??.1,this.highResolutionCellThickness=Math.max(1,Math.floor(t.highResolutionCellThickness??8)),this.lowResolutionCellSize=t.lowResolutionCellSize??.4,this.viaDiameter=t.viaDiameter,this.maxCellCount=t.maxCellCount,this.traceThickness=t.traceThickness??.1,this.traceMargin=t.traceMargin??.15,this.obstacleClearanceMargin=t.obstacleClearanceMargin??0,this.viaMinDistFromBorder=t.viaMinDistFromBorder??.15,this.showPenaltyMap=t.showPenaltyMap??!1,this.showUsedCellMap=t.showUsedCellMap??!1,this.effort=t.effort??1,this.stepMultiplier=Math.max(1,Math.floor(t.stepMultiplier??1)),this.hyperParameters={shuffleSeed:0,ripCost:8,ripTracePenalty:.5,ripViaPenalty:.75,viaBaseCost:.1,greedyMultiplier:1.5,sameRootObstacleCostMultiplier:1,...t.hyperParameters},this.MAX_ITERATIONS=1e8,this.MAX_RIPS=200,this.initialPenaltyFn=t.initialPenaltyFn}getConstructorParams(){return[{nodeWithPortPoints:this.nodeWithPortPoints,obstacles:this.obstacles,highResolutionCellSize:this.highResolutionCellSize,highResolutionCellThickness:this.highResolutionCellThickness,lowResolutionCellSize:this.lowResolutionCellSize,viaDiameter:this.viaDiameter,maxCellCount:this.maxCellCount,stepMultiplier:this.stepMultiplier,traceThickness:this.traceThickness,traceMargin:this.traceMargin,obstacleClearanceMargin:this.obstacleClearanceMargin,viaMinDistFromBorder:this.viaMinDistFromBorder,showPenaltyMap:this.showPenaltyMap,showUsedCellMap:this.showUsedCellMap,effort:this.effort,hyperParameters:this.hyperParameters,initialPenaltyFn:this.initialPenaltyFn}]}_setup(){const{nodeWithPortPoints:t}=this,{width:e,height:n,center:o}=t;if(e\u003e15||n\u003e15)return this.error=`HighDensitySolverB01 only supports routing windows up to 15x15mm; received ${e}x${n}mm`,void(this.failed=!0);const i=this.lowResolutionCellSize/this.highResolutionCellSize,r=Math.round(i);if(!Number.isFinite(i)||i\u003c=0||Math.abs(i-r)\u003e1e-9)return this.error=\"lowResolutionCellSize must be a positive integer multiple of highResolutionCellSize\",void(this.failed=!0);this.lowScale=Math.max(1,r),this.availableZ=t.availableZ??[...new Set(t.portPoints.map(t=\u003et.z))].sort((t,e)=\u003et-e),this.layers=this.availableZ.length,this.zToLayer=new Map,this.layerToZ=new Map;for(let t=0;t\u003cthis.availableZ.length;t++){const e=this.availableZ[t];this.zToLayer.set(e,t),this.layerToZ.set(t,e)}this.boundsMinX=o.x-e/2,this.boundsMaxX=o.x+e/2,this.boundsMinY=o.y-n/2,this.boundsMaxY=o.y+n/2,this.traceKeepoutRadius=this.traceMargin+this.traceThickness/2,this.viaKeepoutRadius=this.viaDiameter/2+this.traceKeepoutRadius,this.buildFiveRegionGrid(e,n),this.gridToBoundsTransform=this.computeGridToBoundsTransform();const s=this.layers*this.planeSize;if(void 0!==this.maxCellCount\u0026\u0026s\u003ethis.maxCellCount)return this.error=`Cell count ${s} exceeds maxCellCount ${this.maxCellCount}`,void(this.failed=!0);this.connNameToId=new Map,this.connIdToName=[],this.connIdToRootNet=[],this.overlapFriendlyRootNets=new Set,this.unsolvedSegs=this.buildConnectionSegs(),this.penalty2d=new Float64Array(this.planeSize);const a=e\u003e0?1/e:0,c=n\u003e0?1/n:0;for(let t=0;t\u003cthis.planeSize;t++){let e=0;this.initialPenaltyFn\u0026\u0026(e+=this.initialPenaltyFn({x:this.cellCenterX[t],y:this.cellCenterY[t],px:(this.cellCenterX[t]-this.boundsMinX)*a,py:(this.cellCenterY[t]-this.boundsMinY)*c,cellId:t,region:hQ[this.cellRegion[t]],row:this.cellRow[t],col:this.cellCol[t]})),this.penalty2d[t]=e}this.usedCellsFlat=new Int32Array(s).fill(-1),this.sharedCellsFlat=Array.from({length:s},()=\u003e{}),this.portOwnerFlat=new Int32Array(s).fill(-1),this.sharedCrossRootPortFlat=new Uint8Array(s),this.obstacleTraceRootIdsFlat=Array.from({length:s},()=\u003e{}),this.obstacleViaRootIdsByCell=Array.from({length:this.planeSize},()=\u003e{}),this.obstacleRootNameToId=new Map,this.obstacleRootNames=[],this.obstacleTracePrimitives=[],this.obstacleViaPrimitives=[],this.obstacleRectPrimitives=[];const l=this.rasterizeObstacles();if(l)return this.error=l,void(this.failed=!0);this.ripStateBuckets=1;const d=s;this.visitedStamp=new Uint32Array(d),this.bestGStamp=new Uint32Array(d),this.bestGValue=new Float64Array(d),this.visitedFlatStamp=new Uint32Array(s),this.stamp=0;const h=new Map;for(const t of this.nodeWithPortPoints.portPoints){const e=this.connNameToId.get(t.connectionName);if(void 0===e)continue;const n=this.pointToCell(t),o=n.z*this.planeSize+n.cellId,i=this.connIdToRootNet[e],r=h.get(o);void 0===r?h.set(o,i):r!==i\u0026\u0026(this.sharedCrossRootPortFlat[o]=1);const s=this.portOwnerFlat[o];this.portOwnerFlat[o]=-1===s||s===e?e:-2}this.solvedRoutes=[],this.usedIndicesByConn=[],this.ripCount=[],this.consecutiveSkips=0,this.penaltyCap=.5*this.hyperParameters.ripCost,this.shuffleConnections();const u=function(t){const e=t.planeSize*t.layers,n=t.connectionCount,o=Math.sqrt(n),i=Math.max(1,t.maxIterations),r=dQ(Math.round(e*(8+1.2*o)),15e4,12e6),s=dQ(Math.round(r*t.effort),15e4,12e6),a=dQ(Math.round(.2*i),15e4,2e6);return{maxIterationsIters:Math.max(1,Math.min(i,Math.max(a,s))),baseSearchBudgetIters:dQ(Math.round(e*(10+.8*o)*t.effort),5e4,4e6)}}({planeSize:this.planeSize,layers:this.layers,connectionCount:this.unsolvedSegs.length,effort:this.effort,maxIterations:this.MAX_ITERATIONS});this.baseSearchBudgetIters=u.baseSearchBudgetIters,this.MAX_ITERATIONS=u.maxIterationsIters,this.activeConnSeg=null,this.activeConnId=-1,this.nodePool=new pQ,this.heap=new uQ,this.ripChain=new mQ,this.seqCounter=0}_step(){for(let t=0;t\u003cthis.stepMultiplier;t++){if(this.solved||this.failed)return;this.stepOnce()}}rasterizeObstacles(){for(let t=0;t\u003cthis.obstacles.length;t++){const e=this.obstacles[t];if(\"rect\"===e.type){const n=this.rasterizeRectObstacle(e,t);if(n)return n;continue}if(e.traceThickness\u003c=0||e.viaDiameter\u003c=0||e.route.length\u003c2)return`Obstacle ${t} must have positive trace/via sizes and at least two route points`;const n=gQ(e.connectionName,e.rootConnectionName),o=this.internObstacleRootName(n);for(let n=1;n\u003ce.route.length;n++){const i=e.route[n-1],r=e.route[n];if(!(Number.isFinite(i.x)\u0026\u0026Number.isFinite(i.y)\u0026\u0026Number.isFinite(i.z)\u0026\u0026Number.isFinite(r.x)\u0026\u0026Number.isFinite(r.y)\u0026\u0026Number.isFinite(r.z)))return`Obstacle ${t} contains non-finite route coordinates`;if(i.z===r.z){const n=this.zToLayer.get(i.z);if(void 0===n)return`Obstacle ${t} uses unavailable layer z=${i.z}`;this.rasterizeObstacleTraceSegment({segmentStart:i,segmentEnd:r,layer:n,obstacleRootId:o,obstacleTraceThickness:e.traceThickness})}else if(!e.vias.some(t=\u003et.x===r.x\u0026\u0026t.y===r.y)){const n=this.rasterizeObstacleVia({center:r,obstacleRootId:o,obstacleViaDiameter:e.viaDiameter,zStart:i.z,zEnd:r.z,obstacleIndex:t});if(n)return n}}for(const n of e.vias){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))return`Obstacle ${t} contains non-finite via coordinates`;const i=this.rasterizeObstacleVia({center:n,obstacleRootId:o,obstacleViaDiameter:e.viaDiameter,zStart:n.zStart,zEnd:n.zEnd,obstacleIndex:t});if(i)return i}}return this.obstacleTraceBlockedCellCount=this.obstacleTraceRootIdsFlat.reduce((t,e)=\u003et+(e?1:0),0),this.obstacleViaBlockedCellCount=this.obstacleViaRootIdsByCell.reduce((t,e)=\u003et+(e?1:0),0),null}rasterizeRectObstacle(t,e){if(!Number.isFinite(t.center.x)||!Number.isFinite(t.center.y)||!Number.isFinite(t.width)||!Number.isFinite(t.height)||t.width\u003c=0||t.height\u003c=0)return`Rect obstacle ${e} must have finite geometry and positive dimensions`;const n=[];for(const o of t.zLayers){const t=this.zToLayer.get(o);if(void 0===t)return`Rect obstacle ${e} uses unavailable layer z=${o}`;bQ(n,t)}if(0===n.length)return`Rect obstacle ${e} must apply to at least one layer`;const o=this.internObstacleRootName(gQ(t.connectionName,t.rootConnectionName)),i={rootId:o,center:t.center,width:t.width,height:t.height,rotationRadians:(t.ccwRotationDegrees??0)*Math.PI/180,layers:n};this.obstacleRectPrimitives.push(i);const r=this.transformBoundsPointToGrid(t.center),s=Math.hypot(t.width/2,t.height/2),a=this.getConservativeGridRadius(s+this.traceThickness/2+this.traceMargin);this.forEachCellNearCircle(r.x,r.y,a,t=\u003e{for(const e of n)this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:e*this.planeSize+t,obstacleRootId:o})});const c=this.getConservativeGridRadius(s+this.viaDiameter/2+this.traceMargin);return this.forEachCellNearCircle(r.x,r.y,c,t=\u003e{this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:t,obstacleRootId:o})}),null}internObstacleRootName(t){const e=this.obstacleRootNameToId.get(t);if(void 0!==e)return e;const n=this.obstacleRootNames.length;return this.obstacleRootNames.push(t),this.obstacleRootNameToId.set(t,n),n}rasterizeObstacleTraceSegment(t){this.obstacleTracePrimitives.push({rootId:t.obstacleRootId,layer:t.layer,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd,traceRadius:t.obstacleTraceThickness/2});const e=this.transformBoundsPointToGrid(t.segmentStart),n=this.transformBoundsPointToGrid(t.segmentEnd),o=this.getConservativeGridRadius(t.obstacleTraceThickness/2+this.traceMargin),i=this.getConservativeGridRadius(t.obstacleTraceThickness/2+this.viaDiameter/2+this.traceMargin);this.forEachCellNearSegment({segmentStart:e,segmentEnd:n,radius:o},e=\u003e{this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:t.layer*this.planeSize+e,obstacleRootId:t.obstacleRootId})}),this.forEachCellNearSegment({segmentStart:e,segmentEnd:n,radius:i},e=\u003e{this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:e,obstacleRootId:t.obstacleRootId})})}rasterizeObstacleVia(t){if(void 0===t.zStart!=(void 0===t.zEnd))return`Obstacle ${t.obstacleIndex} via must provide both zStart and zEnd`;let e=Array.from({length:this.layers},(t,e)=\u003ee);if(void 0!==t.zStart\u0026\u0026void 0!==t.zEnd){if(!Number.isFinite(t.zStart)||!Number.isFinite(t.zEnd))return`Obstacle ${t.obstacleIndex} contains a non-finite via layer span`;const n=Math.min(t.zStart,t.zEnd),o=Math.max(t.zStart,t.zEnd);e=this.availableZ.flatMap((t,e)=\u003et\u003e=n\u0026\u0026t\u003c=o?[e]:[])}if(0===e.length)return null;this.obstacleViaPrimitives.push({rootId:t.obstacleRootId,center:t.center,viaRadius:t.obstacleViaDiameter/2,layers:e});const n=this.transformBoundsPointToGrid(t.center),o=this.getConservativeGridRadius(t.obstacleViaDiameter/2+this.traceThickness/2+this.traceMargin),i=this.getConservativeGridRadius(t.obstacleViaDiameter/2+this.viaDiameter/2+this.traceMargin);return this.forEachCellNearCircle(n.x,n.y,Math.max(o,i),r=\u003e{const s=this.getCellRect(r);if(vQ(n.x,n.y,o,s.minX,s.minY,s.maxX,s.maxY))for(const n of e)this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:n*this.planeSize+r,obstacleRootId:t.obstacleRootId});vQ(n.x,n.y,i,s.minX,s.minY,s.maxX,s.maxY)\u0026\u0026this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:r,obstacleRootId:t.obstacleRootId})}),null}forEachCellNearSegment(t,e){const n={x:(t.segmentStart.x+t.segmentEnd.x)/2,y:(t.segmentStart.y+t.segmentEnd.y)/2},o=Math.hypot(t.segmentEnd.x-t.segmentStart.x,t.segmentEnd.y-t.segmentStart.y)/2+t.radius;this.forEachCellNearCircle(n.x,n.y,o,n=\u003e{wQ({segmentStart:t.segmentStart,segmentEnd:t.segmentEnd,radius:t.radius,rect:this.getCellRect(n)})\u0026\u0026e(n)})}getCellRect(t){return{minX:this.cellMinX[t],minY:this.cellMinY[t],maxX:this.cellMaxX[t],maxY:this.cellMaxY[t]}}transformBoundsPointToGrid(t){const e=this.gridToBoundsTransform;return{x:(t.x-e.c)/e.a,y:(t.y-e.f)/e.e}}getConservativeGridRadius(t){return t/Math.min(Math.abs(this.gridToBoundsTransform.a),Math.abs(this.gridToBoundsTransform.e))}addObstacleRootId(t){let e=t.rootIdsByCell[t.cellIndex];e||(e=[],t.rootIdsByCell[t.cellIndex]=e),bQ(e,t.obstacleRootId)}isBlockedByObstacleRoots(t,e){if(!t)return!1;const n=this.connIdToRootNet[e];for(const e of t)if(this.obstacleRootNames[e]!==n)return!0;return!1}hasSameRootObstacle(t,e){if(!t)return!1;const n=this.connIdToRootNet[e];return t.some(t=\u003ethis.obstacleRootNames[t]===n)}isLateralMoveBlockedByObstacleGeometry(t){const e=this.connIdToRootNet[t.activeConn],n=this.activeConnSeg,o=n\u0026\u0026t.layer===n.startZ\u0026\u0026t.fromCellId===n.startCellId?n.startPoint:iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.fromCellId],y:this.cellCenterY[t.fromCellId]}),i=n\u0026\u0026t.layer===n.endZ\u0026\u0026t.toCellId===n.endCellId?n.endPoint:iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.toCellId],y:this.cellCenterY[t.toCellId]});for(const n of this.obstacleTracePrimitives){if(n.layer!==t.layer||this.obstacleRootNames[n.rootId]===e)continue;const r=n.traceRadius+this.traceThickness/2+this.obstacleClearanceMargin;if(NQ({firstStart:o,firstEnd:i,secondStart:n.segmentStart,secondEnd:n.segmentEnd})\u003cr*r)return!0}for(const n of this.obstacleViaPrimitives){if(!n.layers.includes(t.layer)||this.obstacleRootNames[n.rootId]===e)continue;const r=n.viaRadius+this.traceThickness/2+this.obstacleClearanceMargin;if(SQ({point:n.center,segmentStart:o,segmentEnd:i})\u003cr*r)return!0}for(const n of this.obstacleRectPrimitives)if(n.layers.includes(t.layer)\u0026\u0026this.obstacleRootNames[n.rootId]!==e\u0026\u0026wQ({segmentStart:fQ(o,n),segmentEnd:fQ(i,n),radius:this.traceThickness/2+this.obstacleClearanceMargin,rect:yQ(n)}))return!0;return!1}isViaMoveBlockedByObstacleGeometry(t){const e=this.connIdToRootNet[t.activeConn],n=iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.cellId],y:this.cellCenterY[t.cellId]});for(const t of this.obstacleTracePrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=t.traceRadius+this.viaDiameter/2+this.obstacleClearanceMargin;if(SQ({point:n,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd})\u003co*o)return!0}for(const t of this.obstacleViaPrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=t.viaRadius+this.viaDiameter/2+this.obstacleClearanceMargin;if((n.x-t.center.x)**2+(n.y-t.center.y)**2\u003co*o)return!0}for(const t of this.obstacleRectPrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=fQ(n,t),i=this.viaDiameter/2+this.obstacleClearanceMargin;if(IQ({point:o,rect:yQ(t)})\u003ci*i)return!0}return!1}buildFiveRegionGrid(t,e){this.fineCols=Math.max(1,Math.ceil(t/this.highResolutionCellSize)),this.fineRows=Math.max(1,Math.ceil(e/this.highResolutionCellSize)),this.bandCols=Math.min(this.highResolutionCellThickness,Math.floor(this.fineCols/2)),this.bandRows=Math.min(this.highResolutionCellThickness,Math.floor(this.fineRows/2));const n=Math.max(0,this.fineCols-2*this.bandCols),o=Math.max(0,this.fineRows-2*this.bandRows),i=n,r=n;this.regions=[{id:0,name:\"left\",fineOriginRow:0,fineOriginCol:0,fineRows:this.fineRows,fineCols:this.bandCols,cellScale:1,rows:this.fineRows,cols:this.bandCols,offset:0},{id:1,name:\"top\",fineOriginRow:0,fineOriginCol:this.bandCols,fineRows:this.bandRows,fineCols:i,cellScale:1,rows:this.bandRows,cols:i,offset:0},{id:2,name:\"right\",fineOriginRow:0,fineOriginCol:this.fineCols-this.bandCols,fineRows:this.fineRows,fineCols:this.bandCols,cellScale:1,rows:this.fineRows,cols:this.bandCols,offset:0},{id:3,name:\"bottom\",fineOriginRow:this.fineRows-this.bandRows,fineOriginCol:this.bandCols,fineRows:this.bandRows,fineCols:r,cellScale:1,rows:this.bandRows,cols:r,offset:0},{id:4,name:\"middle\",fineOriginRow:this.bandRows,fineOriginCol:this.bandCols,fineRows:o,fineCols:n,cellScale:this.lowScale,rows:o\u003e0?Math.ceil(o/this.lowScale):0,cols:n\u003e0?Math.ceil(n/this.lowScale):0,offset:0}];let s=0;for(let t=0;t\u003cthis.regions.length;t++)this.regions[t].offset=s,s+=this.regions[t].rows*this.regions[t].cols;this.planeSize=s,this.cellCenterX=new Float64Array(this.planeSize),this.cellCenterY=new Float64Array(this.planeSize),this.cellMinX=new Float64Array(this.planeSize),this.cellMinY=new Float64Array(this.planeSize),this.cellMaxX=new Float64Array(this.planeSize),this.cellMaxY=new Float64Array(this.planeSize),this.cellWidth=new Float64Array(this.planeSize),this.cellHeight=new Float64Array(this.planeSize),this.cellRegion=new Uint8Array(this.planeSize),this.cellRow=new Int32Array(this.planeSize),this.cellCol=new Int32Array(this.planeSize),this.viaAllowed=new Uint8Array(this.planeSize);for(let t=0;t\u003cthis.regions.length;t++){const e=this.regions[t];for(let t=0;t\u003ce.rows;t++){const n=e.fineOriginRow+t*e.cellScale,o=Math.min(e.fineOriginRow+e.fineRows,n+e.cellScale),i=this.boundsMinY+n*this.highResolutionCellSize,r=Math.min(this.boundsMaxY,this.boundsMinY+o*this.highResolutionCellSize);for(let n=0;n\u003ce.cols;n++){const o=e.fineOriginCol+n*e.cellScale,s=Math.min(e.fineOriginCol+e.fineCols,o+e.cellScale),a=this.boundsMinX+o*this.highResolutionCellSize,c=Math.min(this.boundsMaxX,this.boundsMinX+s*this.highResolutionCellSize),l=this.cellIdFor(e.id,t,n);this.cellCenterX[l]=(a+c)/2,this.cellCenterY[l]=(i+r)/2,this.cellMinX[l]=a,this.cellMinY[l]=i,this.cellMaxX[l]=c,this.cellMaxY[l]=r,this.cellWidth[l]=c-a,this.cellHeight[l]=r-i,this.cellRegion[l]=e.id,this.cellRow[l]=t,this.cellCol[l]=n;const d=Math.min(this.cellCenterX[l]-this.boundsMinX,this.boundsMaxX-this.cellCenterX[l],this.cellCenterY[l]-this.boundsMinY,this.boundsMaxY-this.cellCenterY[l]);this.viaAllowed[l]=d\u003e=this.viaMinDistFromBorder?1:0}}}const a=Array.from({length:this.planeSize},()=\u003e[]),c=(t,e)=\u003e{if(t===e||t\u003c0||e\u003c0)return;const n=this.cellCenterX[t]-this.cellCenterX[e],o=this.cellCenterY[t]-this.cellCenterY[e],i=Math.hypot(n,o);xQ(a[t],{cellId:e,cost:i}),xQ(a[e],{cellId:t,cost:i})};for(let t=0;t\u003cthis.regions.length;t++){const e=this.regions[t];for(let t=0;t\u003ce.rows;t++)for(let n=0;n\u003ce.cols;n++){const o=this.cellIdFor(e.id,t,n);t+1\u003ce.rows\u0026\u0026c(o,this.cellIdFor(e.id,t+1,n)),n+1\u003ce.cols\u0026\u0026c(o,this.cellIdFor(e.id,t,n+1))}}const l=this.regions[0],d=this.regions[1],h=this.regions[2],u=this.regions[3],p=this.regions[4],m=l.rows\u003e0\u0026\u0026l.cols\u003e0,g=d.rows\u003e0\u0026\u0026d.cols\u003e0,f=h.rows\u003e0\u0026\u0026h.cols\u003e0,y=u.rows\u003e0\u0026\u0026u.cols\u003e0,_=p.rows\u003e0\u0026\u0026p.cols\u003e0;if(m\u0026\u0026g)for(let t=0;t\u003cthis.bandRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(1,t,0));if(g\u0026\u0026f)for(let t=0;t\u003cthis.bandRows;t++)c(this.cellIdFor(1,t,d.cols-1),this.cellIdFor(2,t,0));if(m\u0026\u0026y)for(let t=this.fineRows-this.bandRows;t\u003cthis.fineRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(3,t-(this.fineRows-this.bandRows),0));if(y\u0026\u0026f)for(let t=this.fineRows-this.bandRows;t\u003cthis.fineRows;t++)c(this.cellIdFor(3,t-(this.fineRows-this.bandRows),u.cols-1),this.cellIdFor(2,t,0));if(m\u0026\u0026_)for(let t=this.bandRows;t\u003cthis.fineRows-this.bandRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(4,Math.floor((t-this.bandRows)/this.lowScale),0));if(f\u0026\u0026_)for(let t=this.bandRows;t\u003cthis.fineRows-this.bandRows;t++)c(this.cellIdFor(4,Math.floor((t-this.bandRows)/this.lowScale),p.cols-1),this.cellIdFor(2,t,0));if(g\u0026\u0026_)for(let t=this.bandCols;t\u003cthis.fineCols-this.bandCols;t++)c(this.cellIdFor(1,d.rows-1,t-this.bandCols),this.cellIdFor(4,0,Math.floor((t-this.bandCols)/this.lowScale)));if(y\u0026\u0026_)for(let t=this.bandCols;t\u003cthis.fineCols-this.bandCols;t++)c(this.cellIdFor(4,p.rows-1,Math.floor((t-this.bandCols)/this.lowScale)),this.cellIdFor(3,0,t-this.bandCols));if(!_\u0026\u0026!g\u0026\u0026!y\u0026\u0026m\u0026\u0026f)for(let t=0;t\u003cMath.min(l.rows,h.rows);t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(2,t,0));if(!_\u0026\u0026!m\u0026\u0026!f\u0026\u0026g\u0026\u0026y)for(let t=0;t\u003cMath.min(d.cols,u.cols);t++)c(this.cellIdFor(1,d.rows-1,t),this.cellIdFor(3,0,t));const b=this.flattenNeighborLists(a);this.neighborOffset=b.offset,this.neighborIds=b.ids,this.neighborCosts=b.costs}cellIdFor(t,e,n){const o=this.regions[t];return o.offset+e*o.cols+n}stepOnce(){if(!this.activeConnSeg){if(0===this.unsolvedSegs.length)return void(this.solved=!0);const t=this.unsolvedSegs.shift();this.activeConnSeg=t,this.activeConnId=t.connId,this.nodePool.clear(),this.ripChain.clear(),this.heap.clear(),this.seqCounter=0,this.searchIterations=0,this.nextStamp();const e=this.computeH(t.startZ,t.startCellId,t.endZ,t.endCellId)*this.hyperParameters.greedyMultiplier,n=this.nodePool.push(t.startZ,t.startCellId,0,-1,-1,0),o=t.startZ*this.planeSize+t.startCellId,i=this.getSearchStateIdx(o,0);return this.bestGStamp[i]=this.stamp,this.bestGValue[i]=0,void this.heap.push(e,this.seqCounter++,n)}this.searchIterations++;const t=this.ripCount[this.activeConnId]??0,e=Math.round(this.baseSearchBudgetIters*(1+.25*Math.min(t,10)));if(this.searchIterations\u003ee){const t=this.penalty2d;for(let e=0;e\u003ct.length;e++)t[e]=.9*t[e];return this.unsolvedSegs.push(this.activeConnSeg),this.activeConnSeg=null,this.activeConnId=-1,this.heap.clear(),this.nodePool.clear(),this.consecutiveSkips++,void(this.consecutiveSkips\u003e=Math.max(3,3*this.unsolvedSegs.length)\u0026\u0026(this.error=`Convergence failure: ${this.unsolvedSegs.length} connections stuck`,this.failed=!0))}if(0===this.heap.size)return this.error=`No path found for ${this.connIdToName[this.activeConnId]}`,void(this.failed=!0);const n=this.heap.pop(),o=this.nodePool.z[n],i=this.nodePool.cellId[n],r=this.nodePool.g[n],s=this.nodePool.ripHead[n],a=this.nodePool.ripCount[n],c=o*this.planeSize+i,l=this.getSearchStateIdx(c,a);if(this.visitedStamp[l]===this.stamp)return;this.visitedStamp[l]=this.stamp,this.visitedFlatStamp[c]=this.stamp;const d=this.activeConnSeg;if(o===d.endZ\u0026\u0026i===d.endCellId)return this.finalizeRoute(n),this.activeConnSeg=null,void(this.activeConnId=-1);const h=this.visitedStamp,u=this.stamp,p=this.activeConnId,m=d.endZ,g=d.endCellId,f=this.neighborOffset[i],y=this.neighborOffset[i+1];for(let t=f;t\u003cy;t++){const e=this.neighborIds[t],c=o*this.planeSize+e;if(this.computeMoveCostAndRips(p,o,i,e,!1,s,a,this.neighborCosts[t]),this._moveCost\u003c0)continue;const l=this.getSearchStateIdx(c,this._moveRipCount);if(h[l]===u)continue;const d=r+this._moveCost;if(this.bestGStamp[l]===u\u0026\u0026d\u003e=this.bestGValue[l])continue;this.bestGStamp[l]=u,this.bestGValue[l]=d;const f=d+this.computeH(o,e,m,g)*this.hyperParameters.greedyMultiplier,y=this.nodePool.push(o,e,d,n,this._moveRippedHead,this._moveRipCount);this.heap.push(f,this.seqCounter++,y)}if(this.viaAllowed[i])for(let t=0;t\u003cthis.layers;t++){if(t===o)continue;const e=t*this.planeSize+i;if(this.computeMoveCostAndRips(p,t,i,i,!0,s,a,0),this._moveCost\u003c0)continue;const c=this.getSearchStateIdx(e,this._moveRipCount);if(h[c]===u)continue;const l=r+this._moveCost;if(this.bestGStamp[c]===u\u0026\u0026l\u003e=this.bestGValue[c])continue;this.bestGStamp[c]=u,this.bestGValue[c]=l;const d=l+this.computeH(t,i,m,g)*this.hyperParameters.greedyMultiplier,f=this.nodePool.push(t,i,l,n,this._moveRippedHead,this._moveRipCount);this.heap.push(d,this.seqCounter++,f)}}computeMoveCostAndRips(t,e,n,o,i,r,s,a){let c=0,l=r,d=s;const h=e*this.planeSize+o,u=i?this.obstacleViaRootIdsByCell[o]:[...this.obstacleTraceRootIdsFlat[e*this.planeSize+n]??[],...this.obstacleTraceRootIdsFlat[h]??[]];if(this.isBlockedByObstacleRoots(u,t)\u0026\u0026(i?this.isViaMoveBlockedByObstacleGeometry({activeConn:t,cellId:o}):this.isLateralMoveBlockedByObstacleGeometry({activeConn:t,layer:e,fromCellId:n,toCellId:o})))return this._moveCost=-1,this._moveRippedHead=l,void(this._moveRipCount=d);const p=this.hasSameRootObstacle(u,t);if(i){c+=this.hyperParameters.viaBaseCost,c+=Math.min(this.penalty2d[o],this.penaltyCap);const n=this.portOwnerFlat[h],i=this.allowSharedUse(t,n),r=this.activeConnSeg,s=!!r\u0026\u0026e===r.endZ\u0026\u0026o===r.endCellId;if(n\u003e=0\u0026\u0026n!==t\u0026\u0026!i\u0026\u0026!s)return this._moveCost=-1,void(this._moveRippedHead=l);this.fillViaOccupants(o,t);const a=this._viaOccs;for(let t=0;t\u003ca.length;t++){const e=a[t];this.ripChain.contains(l,e)||(c+=this.hyperParameters.ripCost,l=this.ripChain.append(l,e),d++),c+=this.hyperParameters.ripViaPenalty}}else{c+=a,c+=Math.min(this.penalty2d[o],this.penaltyCap);const n=this.portOwnerFlat[h],i=this.allowSharedUse(t,n),r=this.activeConnSeg,s=!!r\u0026\u0026e===r.endZ\u0026\u0026o===r.endCellId;if(n\u003e=0\u0026\u0026n!==t\u0026\u0026!i\u0026\u0026!s)return this._moveCost=-1,void(this._moveRippedHead=l);this.fillTraceOccupants(h,t,this._cellOccs);for(let t=0;t\u003cthis._cellOccs.length;t++){const e=this._cellOccs[t];this.ripChain.contains(l,e)||(c+=this.hyperParameters.ripCost,l=this.ripChain.append(l,e),d++),c+=this.hyperParameters.ripTracePenalty}}p\u0026\u0026(c*=this.hyperParameters.sameRootObstacleCostMultiplier),this._moveCost=c,this._moveRippedHead=l,this._moveRipCount=d}fillViaOccupants(t,e){const n=this._viaOccs;n.length=0;const o=this.cellCenterX[t],i=this.cellCenterY[t];this.forEachCellNearCircle(o,i,this.viaKeepoutRadius,t=\u003e{if(vQ(o,i,this.viaKeepoutRadius,this.cellMinX[t],this.cellMinY[t],this.cellMaxX[t],this.cellMaxY[t]))for(let o=0;o\u003cthis.layers;o++)this.pushFlatOccupants(o*this.planeSize+t,e,n)})}fillTraceOccupants(t,e,n){n.length=0,this.pushFlatOccupants(t,e,n)}pushFlatOccupants(t,e,n){const o=this.usedCellsFlat[t];-1===o||o===e||this.allowSharedUse(e,o)||bQ(n,o);const i=this.sharedCellsFlat[t];if(i)for(let t=0;t\u003ci.length;t++){const o=i[t];o!==e\u0026\u0026(this.allowSharedUse(e,o)||bQ(n,o))}}addSharedOccupant(t,e){if(this.usedCellsFlat[t]===e)return;let n=this.sharedCellsFlat[t];n||(n=[],this.sharedCellsFlat[t]=n),bQ(n,e)}replaceOccupants(t,e){this.usedCellsFlat[t]=e,this.sharedCellsFlat[t]=void 0}removeOccupant(t,e){const n=this.sharedCellsFlat[t];if(this.usedCellsFlat[t]===e)return void(n\u0026\u0026n.length\u003e0?(this.usedCellsFlat[t]=n.pop(),0===n.length\u0026\u0026(this.sharedCellsFlat[t]=void 0)):this.usedCellsFlat[t]=-1);if(!n)return;const o=n.indexOf(e);-1!==o\u0026\u0026(n.splice(o,1),0===n.length\u0026\u0026(this.sharedCellsFlat[t]=void 0))}allowSharedUse(t,e){if(e\u003c0)return!1;return this.connIdToRootNet[e]===this.connIdToRootNet[t]}shouldSkipFixedPortHalo(t,e){const n=this.portOwnerFlat[t];return n!==e\u0026\u0026(-2===n||!(n\u003c0)\u0026\u0026!this.allowSharedUse(e,n))}nextStamp(){this.stamp=this.stamp+1\u003e\u003e\u003e0,0===this.stamp\u0026\u0026(this.visitedStamp.fill(0),this.bestGStamp.fill(0),this.visitedFlatStamp.fill(0),this.stamp=1)}getSearchStateIdx(t,e){return t}computeH(t,e,n,o){const i=Math.hypot(this.cellCenterX[e]-this.cellCenterX[o],this.cellCenterY[e]-this.cellCenterY[o]);return t===n?i:i+this.hyperParameters.viaBaseCost}internConn(t,e){const n=this.connNameToId.get(t);if(void 0!==n)return n;const o=this.connIdToName.length;return this.connIdToName.push(t),this.connIdToRootNet.push(gQ(t,e)),this.connNameToId.set(t,o),o}buildConnectionSegs(){const t=new Map;for(const e of this.nodeWithPortPoints.portPoints){const n=e.connectionName;t.has(n)||t.set(n,{points:[],rootConnectionName:e.rootConnectionName}),t.get(n).points.push(e)}const e=[],n=new Map;for(const[o,i]of t){const t=i.points,r=lQ(t);if(0===r.length)continue;const s=this.internConn(o,i.rootConnectionName);for(const[t,i]of r){const r=this.pointToCell(t),a=this.pointToCell(i),c=`${r.z}:${r.cellId}`,l=`${a.z}:${a.cellId}`,d=c\u003cl?`${c}|${l}`:`${l}|${c}`,h=this.connIdToRootNet[s],u=`${h}|${d}`,p=n.get(u);if(p){if(this.overlapFriendlyRootNets.add(h),!p.connectionAliases.some(t=\u003et.connectionName===o)){const e=p.startZ===r.z\u0026\u0026p.startCellId===r.cellId\u0026\u0026p.endZ===a.z\u0026\u0026p.endCellId===a.cellId,n=p.startZ===a.z\u0026\u0026p.startCellId===a.cellId\u0026\u0026p.endZ===r.z\u0026\u0026p.endCellId===r.cellId;if(!e\u0026\u0026!n)throw new Error(`Connection alias ${o} does not match canonical segment ${u}`);p.connectionAliases.push({connectionName:o,rootConnectionName:h,startPoint:t,endPoint:i,reversedFromCanonical:!e\u0026\u0026n})}continue}const m={connId:s,startZ:r.z,startCellId:r.cellId,startPoint:t,endZ:a.z,endCellId:a.cellId,endPoint:i,connectionAliases:[{connectionName:o,rootConnectionName:h,startPoint:t,endPoint:i,reversedFromCanonical:!1}]};n.set(u,m),e.push(m)}}return e}pointToCell(t){const e=_Q(Math.floor((t.x-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),n=_Q(Math.floor((t.y-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1);let o=4;e\u003cthis.bandCols?o=0:e\u003e=this.fineCols-this.bandCols?o=2:n\u003cthis.bandRows?o=1:n\u003e=this.fineRows-this.bandRows\u0026\u0026(o=3);const i=this.regions[o],r=n-i.fineOriginRow,s=e-i.fineOriginCol,a=_Q(Math.floor(r/i.cellScale),0,Math.max(0,i.rows-1)),c=_Q(Math.floor(s/i.cellScale),0,Math.max(0,i.cols-1));return{z:this.zToLayer.get(t.z)??0,cellId:this.cellIdFor(o,a,c)}}shuffleConnections(){const t=this.unsolvedSegs;let e=this.hyperParameters.shuffleSeed\u003e\u003e\u003e0;const n=()=\u003e(e=Math.imul(e,1664525)+1013904223\u003e\u003e\u003e0,e/4294967295);for(let e=t.length-1;e\u003e0;e--){const o=Math.floor(n()*(e+1)),i=t[e];t[e]=t[o],t[o]=i}}finalizeRoute(t){this.consecutiveSkips=Math.max(0,this.consecutiveSkips-1);const e=[];let n=t;for(;n\u003e=0;){const t=this.nodePool.z[n],o=this.nodePool.cellId[n];e.push(t*this.planeSize+o),n=this.nodePool.parent[n]}for(e.reverse();e.length\u003e1\u0026\u0026this.sharedCrossRootPortFlat[e[0]];)e.shift();for(;e.length\u003e1\u0026\u0026this.sharedCrossRootPortFlat[e[e.length-1]];)e.pop();const o=this.extractViaCellIds(e),i=this.activeConnId;this.ripChain.collect(this.nodePool.ripHead[t],this._rippedIds);for(let t=0;t\u003cthis._rippedIds.length;t++)if(this.ripTrace(this._rippedIds[t]),this.failed)return;const r=[];for(let t=0;t\u003ce.length;t++){const n=e[t],o=Math.floor(n/this.planeSize),s=n-o*this.planeSize;this.markTraceFootprint(i,o,s,r)}const s=[];for(let t=0;t\u003co.length;t++)this.markViaFootprint(i,o[t],r,s);for(;this.usedIndicesByConn.length\u003c=i;)this.usedIndicesByConn.push(void 0);const a=this.usedIndicesByConn[i]??[];for(a.push(...r),this.usedIndicesByConn[i]=a;this.solvedRoutes.length\u003c=i;)this.solvedRoutes.push(void 0);const c=this.solvedRoutes[i]??[];c.push({connId:i,states:Int32Array.from(e),viaCellIds:Int32Array.from(o),startPoint:this.activeConnSeg.startPoint,endPoint:this.activeConnSeg.endPoint,connectionAliases:this.activeConnSeg.connectionAliases}),this.solvedRoutes[i]=c;for(let t=0;t\u003cs.length;t++)if(this.ripTrace(s[t]),this.failed)return;if(this._rippedIds.length\u003e0||s.length\u003e0){const t=this.penalty2d,e=this.penaltyCap;if(this.totalRipEvents\u003e50)for(let e=0;e\u003ct.length;e++)t[e]=.99*t[e];else for(let n=0;n\u003ct.length;n++)t[n]\u003ee\u0026\u0026(t[n]=.5*t[n])}}extractViaCellIds(t){const e=[];for(let n=1;n\u003ct.length;n++){const o=t[n-1],i=t[n],r=Math.floor(o/this.planeSize),s=Math.floor(i/this.planeSize);r!==s\u0026\u0026e.push(i-s*this.planeSize)}return e}markTraceFootprint(t,e,n,o){const i=this.cellCenterX[n],r=this.cellCenterY[n];this.forEachCellNearCircle(i,r,this.traceKeepoutRadius,s=\u003e{if(!vQ(i,r,this.traceKeepoutRadius,this.cellMinX[s],this.cellMinY[s],this.cellMaxX[s],this.cellMaxY[s]))return;const a=e*this.planeSize+s;if(s!==n\u0026\u0026this.shouldSkipFixedPortHalo(a,t))return;const c=this.usedCellsFlat[a],l=this.allowSharedUse(t,c);(-1===c||c===t||l)\u0026\u0026(-1!==c\u0026\u0026c!==t?this.addSharedOccupant(a,t):this.usedCellsFlat[a]=t,o.push(a))})}markViaFootprint(t,e,n,o){const i=this.cellCenterX[e],r=this.cellCenterY[e];this.forEachCellNearCircle(i,r,this.viaKeepoutRadius,s=\u003e{if(vQ(i,r,this.viaKeepoutRadius,this.cellMinX[s],this.cellMinY[s],this.cellMaxX[s],this.cellMaxY[s]))for(let i=0;i\u003cthis.layers;i++){const r=i*this.planeSize+s;if(s!==e\u0026\u0026this.shouldSkipFixedPortHalo(r,t))continue;if(this.fillTraceOccupants(r,t,this._cellOccs),this._cellOccs.length\u003e0){for(let t=0;t\u003cthis._cellOccs.length;t++)bQ(o,this._cellOccs[t]);this.replaceOccupants(r,t),n.push(r);continue}const a=this.usedCellsFlat[r];-1!==a\u0026\u0026a!==t?this.addSharedOccupant(r,t):this.usedCellsFlat[r]=t,n.push(r)}})}forEachCellNearCircle(t,e,n,o){const i=_Q(Math.floor((t-n-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),r=_Q(Math.floor((t+n-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),s=_Q(Math.floor((e-n-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1),a=_Q(Math.floor((e+n-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1);for(let t=0;t\u003cthis.regions.length;t++){const e=this.regions[t];if(0===e.rows||0===e.cols)continue;const n=Math.max(s,e.fineOriginRow),c=Math.min(a,e.fineOriginRow+e.fineRows-1),l=Math.max(i,e.fineOriginCol),d=Math.min(r,e.fineOriginCol+e.fineCols-1);if(n\u003ec)continue;if(l\u003ed)continue;const h=Math.floor((n-e.fineOriginRow)/e.cellScale),u=Math.floor((c-e.fineOriginRow)/e.cellScale),p=Math.floor((l-e.fineOriginCol)/e.cellScale),m=Math.floor((d-e.fineOriginCol)/e.cellScale);for(let t=h;t\u003c=u;t++)for(let n=p;n\u003c=m;n++)o(this.cellIdFor(e.id,t,n))}}ripTrace(t){for(;this.ripCount.length\u003c=t;)this.ripCount.push(0);if(this.ripCount[t]++,this.totalRipEvents++,this.totalRipEvents\u003e=this.MAX_RIPS)return this.error=`Convergence failure: exceeded MAX_RIPS ${this.MAX_RIPS}`,void(this.failed=!0);const e=this.getSolvedRoutesForConn(t);if(e.length\u003e0)for(const t of e){for(let e=0;e\u003ct.states.length;e++){const n=t.states[e]%this.planeSize;this.penalty2d[n]=this.penalty2d[n]+this.hyperParameters.ripTracePenalty}for(let e=0;e\u003ct.viaCellIds.length;e++){const n=t.viaCellIds[e];this.penalty2d[n]=this.penalty2d[n]+this.hyperParameters.ripViaPenalty}}const n=this.usedIndicesByConn[t];if(n){for(let e=0;e\u003cn.length;e++)this.removeOccupant(n[e],t);this.usedIndicesByConn[t]=void 0}if(e.length\u003e0){this.solvedRoutes[t]=void 0;for(const n of e){const e=n.states[0],o=n.states[n.states.length-1],i=Math.floor(e/this.planeSize),r=Math.floor(o/this.planeSize);this.unsolvedSegs.push({connId:t,startZ:i,startCellId:e-i*this.planeSize,startPoint:n.startPoint,endZ:r,endCellId:o-r*this.planeSize,endPoint:n.endPoint,connectionAliases:n.connectionAliases})}}}flattenNeighborLists(t){const e=new Int32Array(t.length+1);let n=0;for(let o=0;o\u003ct.length;o++)e[o]=n,n+=t[o].length;e[t.length]=n;const o=new Int32Array(n),i=new Float32Array(n);let r=0;for(let e=0;e\u003ct.length;e++){const n=t[e];for(let t=0;t\u003cn.length;t++){const e=n[t];o[r]=e.cellId,i[r]=e.cost,r++}}return{offset:e,ids:o,costs:i}}visualize(){const t=[\"red\",\"blue\",\"orange\",\"green\"],e=this.gridToBoundsTransform,n=[],o=[],i=[],r=[];r.push({center:{x:this.nodeWithPortPoints.center.x,y:this.nodeWithPortPoints.center.y},width:this.nodeWithPortPoints.width,height:this.nodeWithPortPoints.height,stroke:\"gray\"});const s=({route:e,connectionName:n,strokeWidth:i,strokeDash:r,labelPrefix:s})=\u003e{if(e.length\u003c2)return;let a=0;for(let c=1;c\u003ce.length;c+=1){const l=e[c-1];e[c].z!==l.z\u0026\u0026(c-a\u003e=2\u0026\u0026o.push({points:e.slice(a,c).map(t=\u003e({x:t.x,y:t.y})),strokeColor:t[l.z]??\"rgba(128,128,128,0.75)\",strokeWidth:i,strokeDash:r,label:`${s} ${n} z=${l.z}`}),a=c)}if(e.length-a\u003c2)return;const c=e[a].z;o.push({points:e.slice(a).map(t=\u003e({x:t.x,y:t.y})),strokeColor:t[c]??\"rgba(128,128,128,0.75)\",strokeWidth:i,strokeDash:r,label:`${s} ${n} z=${c}`})};for(const t of this.obstacles)if(\"rect\"!==t.type){s({route:t.route,connectionName:t.connectionName,strokeWidth:t.traceThickness,strokeDash:[.12,.08],labelPrefix:\"fixed obstacle\"});for(const e of t.vias)i.push({center:{x:e.x,y:e.y},radius:t.viaDiameter/2,fill:\"rgba(128,0,128,0.25)\",stroke:\"purple\",label:`fixed obstacle ${t.connectionName} via`})}else r.push({center:t.center,width:t.width,height:t.height,fill:\"rgba(128,0,128,0.12)\",stroke:\"purple\",label:`fixed obstacle ${t.connectionName}`});if(this.showPenaltyMap\u0026\u0026this.penalty2d){let t=0;for(let e=0;e\u003cthis.penalty2d.length;e++)this.penalty2d[e]\u003et\u0026\u0026(t=this.penalty2d[e]);if(t\u003e0)for(let n=0;n\u003cthis.planeSize;n++){const o=this.penalty2d[n];if(o\u003c=0)continue;const i=iQ(e,{x:this.cellCenterX[n],y:this.cellCenterY[n]}),s=Math.min(.6,o/t*.6);r.push({center:i,width:this.cellWidth[n]*e.a,height:this.cellHeight[n]*e.e,fill:`rgba(255,165,0,${s.toFixed(3)})`})}}if(this.showUsedCellMap\u0026\u0026this.usedCellsFlat)for(let t=0;t\u003cthis.layers;t++){const n=t*this.planeSize;for(let t=0;t\u003cthis.planeSize;t++){if(-1===this.usedCellsFlat[n+t])continue;const o=iQ(e,{x:this.cellCenterX[t],y:this.cellCenterY[t]});r.push({center:o,width:this.cellWidth[t]*e.a,height:this.cellHeight[t]*e.e,fill:\"rgba(0,0,255,0.5)\"})}}for(const e of this.nodeWithPortPoints.portPoints)n.push({x:e.x,y:e.y,color:t[e.z]??\"gray\",label:e.connectionName});const a=this.getOutput();for(const t of a)s({route:t.route,connectionName:t.connectionName,strokeWidth:this.traceThickness,labelPrefix:\"B01 route\"});for(const t of a)for(const e of t.vias)i.push({center:{x:e.x,y:e.y},radius:this.viaDiameter/2,fill:\"rgba(0,0,0,0.3)\",stroke:\"black\",label:`B01 route ${t.connectionName} via`});if(this.activeConnSeg\u0026\u0026this.visitedFlatStamp){const t=this.stamp;for(let o=0;o\u003cthis.layers;o++){const i=o*this.planeSize;for(let o=0;o\u003cthis.planeSize;o++){if(this.visitedFlatStamp[i+o]!==t)continue;const r=iQ(e,{x:this.cellCenterX[o],y:this.cellCenterY[o]});n.push({x:r.x,y:r.y,color:\"rgba(0,0,255,0.2)\"})}}}return{points:n,lines:o,circles:i,rects:r,coordinateSystem:\"cartesian\",title:`HighDensityB01 [${this.getSolvedRouteCount()} solved, ${this.unsolvedSegs?.length??0} remaining]`}}getOutput(){const t=this.gridToBoundsTransform,e=[];for(let n=0;n\u003cthis.solvedRoutes.length;n++){const o=this.getSolvedRoutesForConn(n);if(0!==o.length)for(const n of o){const o=Array.from(n.states,e=\u003e{const n=Math.floor(e/this.planeSize),o=e-n*this.planeSize,i=iQ(t,{x:this.cellCenterX[o],y:this.cellCenterY[o]});return{x:i.x,y:i.y,z:this.layerToZ.get(n)??n}}),i=Array.from(n.viaCellIds,e=\u003eiQ(t,{x:this.cellCenterX[e],y:this.cellCenterY[e]}));for(const t of n.connectionAliases){const n=(t.reversedFromCanonical?[...o].reverse():o).map(t=\u003e({...t}));n.length\u003e0\u0026\u0026(n[0]={...t.startPoint},n.length\u003e1\u0026\u0026(n[n.length-1]={...t.endPoint})),e.push({connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,regionId:this.nodeWithPortPoints.capacityMeshNodeId,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,route:n,vias:i.map(t=\u003e({...t}))})}}}return e}getSolvedRoutesForConn(t){const e=this.solvedRoutes[t];return e?Array.isArray(e)?e:[e]:[]}getSolvedRouteCount(){let t=0;for(let e=0;e\u003cthis.solvedRoutes.length;e++)t+=this.getSolvedRoutesForConn(e).length;return t}computeGridToBoundsTransform(){let t=1/0,e=-1/0,n=1/0,o=-1/0;for(let i=0;i\u003cthis.planeSize;i++){const r=this.cellCenterX[i],s=this.cellCenterY[i];r\u003ct\u0026\u0026(t=r),r\u003ee\u0026\u0026(e=r),s\u003cn\u0026\u0026(n=s),s\u003eo\u0026\u0026(o=s)}const i=e-t,r=o-n,s=this.boundsMaxX-this.boundsMinX,a=this.boundsMaxY-this.boundsMinY,c=i\u003e0?s/i:1,l=r\u003e0?a/r:1;return{a:c,b:0,c:i\u003e0?this.boundsMinX-c*t:(this.boundsMinX+this.boundsMaxX)/2-t,d:0,e:l,f:r\u003e0?this.boundsMinY-l*n:(this.boundsMinY+this.boundsMaxY)/2-n}}},RQ=new WeakMap,EQ=t=\u003e{const e=RQ.get(t);if(e)return e;const n=[],o=[];for(let e=1;e\u003ct.route.length;e++){const i=t.route[e-1],r=t.route[e],s=Math.hypot(r.x-i.x,r.y-i.y),a=Math.max(i.traceThickness??t.traceThickness,r.traceThickness??t.traceThickness);if(i.z!==r.z\u0026\u0026\"through_obstacle\"===i.toNextSegmentType){const e=Math.min(i.z,r.z),c=Math.max(i.z,r.z);if(s\u003c=1e-9){const n=t.vias.some(t=\u003eMath.hypot(t.x-r.x,t.y-r.y)\u003c=1e-9);o.push({center:{x:r.x,y:r.y},minZ:e,maxZ:c,diameter:n?t.viaDiameter:a});continue}for(let t=e;t\u003c=c;t++)n.push({start:{...i,z:t},end:{...r,z:t},z:t,width:a});continue}s\u003e1e-9\u0026\u0026n.push({start:i,end:i.z===r.z?r:{...r,z:i.z},z:i.z,width:a}),i.z!==r.z\u0026\u0026o.push({center:{x:r.x,y:r.y},minZ:Math.min(i.z,r.z),maxZ:Math.max(i.z,r.z),diameter:t.viaDiameter})}const i={wireSegments:n,viaSpans:o};return RQ.set(t,i),i},AQ=(t,e,n)=\u003e{const o=t.end.x-t.start.x,i=t.end.y-t.start.y,r=Math.hypot(o,i),s={x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2};return Math.abs(o)\u003c=1e-9||Math.abs(i)\u003c=1e-9?[{center:s,width:Math.abs(o)\u003eMath.abs(i)?r:t.width,height:Math.abs(o)\u003eMath.abs(i)?t.width:r}]:rX({center:s,width:r,height:t.width,rotation:180*Math.atan2(i,o)/Math.PI},Math.max(n,Math.ceil(r/e)))},OQ=({fixedObstacleRoutes:t,layerCount:e})=\u003et.flatMap((t,n)=\u003e{const o=[t.connectionName,t.rootConnectionName].filter(t=\u003e\"string\"==typeof t),i=EQ(t);return[...i.wireSegments.flatMap((t,i)=\u003eAQ(t,.75,2).map((r,s)=\u003e({obstacleId:`pipeline9_fixed_obstacle_${n}_wire_${i}_${s}`,type:\"rect\",layers:[vo(t.z,e)],center:r.center,width:r.width,height:r.height,connectedTo:o}))),...i.viaSpans.map((t,i)=\u003e({obstacleId:`pipeline9_fixed_obstacle_${n}_via_${i}`,type:\"rect\",layers:Array.from({length:t.maxZ-t.minZ+1},(n,o)=\u003evo(t.minZ+o,e)),center:t.center,width:t.diameter,height:t.diameter,connectedTo:o}))]}),kQ=(t,e,n)=\u003e{const o=[t.connectionName,t.rootConnectionName].filter(t=\u003e\"string\"==typeof t),i=[e.connectionName,e.rootConnectionName].filter(t=\u003e\"string\"==typeof t);return o.some(t=\u003ei.some(e=\u003et===e||n.areIdsConnected(t,e)))},LQ=(t,e)=\u003et.minX\u003c=e.maxX\u0026\u0026t.maxX\u003e=e.minX\u0026\u0026t.minY\u003c=e.maxY\u0026\u0026t.maxY\u003e=e.minY,DQ=({left:t,right:e,clearance:n,leftBounds:o})=\u003e{const i=EQ(t),r=EQ(e),s=o?i.wireSegments.filter(t=\u003e((t,e)=\u003e{const n={minX:Math.min(t.start.x,t.end.x)-t.width/2,maxX:Math.max(t.start.x,t.end.x)+t.width/2,minY:Math.min(t.start.y,t.end.y)-t.width/2,maxY:Math.max(t.start.y,t.end.y)+t.width/2};return LQ(n,e)})(t,o)):i.wireSegments,a=o?i.viaSpans.filter(t=\u003e((t,e)=\u003e{const n={minX:t.center.x-t.diameter/2,maxX:t.center.x+t.diameter/2,minY:t.center.y-t.diameter/2,maxY:t.center.y+t.diameter/2};return LQ(n,e)})(t,o)):i.viaSpans;for(const t of s){for(const e of r.wireSegments){if(t.z!==e.z)continue;const o=t.width/2+e.width/2+n;if(Ra(t.start,t.end,e.start,e.end)\u003co)return!0}for(const e of r.viaSpans){if(t.z\u003ce.minZ||t.z\u003ee.maxZ)continue;const o=t.width/2+e.diameter/2+n;if(Ra(t.start,t.end,e.center,e.center)\u003co)return!0}}for(const t of a){for(const e of r.wireSegments){if(e.z\u003ct.minZ||e.z\u003et.maxZ)continue;const o=t.diameter/2+e.width/2+n;if(Ra(t.center,t.center,e.start,e.end)\u003co)return!0}for(const e of r.viaSpans){if(t.minZ\u003ee.maxZ||e.minZ\u003et.maxZ)continue;const o=t.diameter/2+e.diameter/2+n;if(Math.hypot(t.center.x-e.center.x,t.center.y-e.center.y)\u003co)return!0}}return!1},zQ=({routes:t,movablePreloadedConnectionNames:e,boardObstacles:n,connMap:o,layerCount:i,viaToPadClearance:r})=\u003et.some(t=\u003e{if(!e.has(t.connectionName))return!1;return EQ(t).viaSpans.some(e=\u003en.some(n=\u003e{if(fo(n,t,o))return!1;const s=((t,e)=\u003e{const n=t.__zLayers??t.zLayers;return n||t.layers.map(t=\u003eko(t,e))})(n,i);return!!s.some(t=\u003et\u003e=e.minZ\u0026\u0026t\u003c=e.maxZ)\u0026\u0026((t,e)=\u003e{const n=-1*(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y,r=o*Math.cos(n)-i*Math.sin(n),s=o*Math.sin(n)+i*Math.cos(n),a=Math.max(Math.abs(r)-e.width/2,0),c=Math.max(Math.abs(s)-e.height/2,0);return Math.hypot(a,c)})(e.center,n)\u003ce.diameter/2+r}))}),FQ=class extends si{params;highDensitySolver;forceImproveSolver;repairSolver;phase=\"route\";constructor(t){super(),this.params=t,this.stats={preloadedViaCandidateRejectionCount:0,forceImproveCandidateRejectionCount:0,repairCandidateRejectionCount:0},this.highDensitySolver=new zs({nodePortPoints:[t.nodeWithPortPoints],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:t.nodePfById,obstacles:t.obstacles,layerCount:t.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!1,growShrinkFallbackToInvalidGeometryOnFailure:!1,growShrinkSolutionValidator:t.boardObstacles\u0026\u0026t.movablePreloadedConnectionNames\u0026\u0026void 0!==t.viaToPadClearance?t=\u003ethis.validateCandidateRoutes(t):void 0}),this.activeSubSolver=this.highDensitySolver,this.MAX_ITERATIONS=1e8*t.effort}getSolverName(){return\"Pipeline9RegionalFallbackSolver\"}validateCandidateRoutes(t){const{boardObstacles:e,movablePreloadedConnectionNames:n,viaToPadClearance:o}=this.params;if(!e||!n||void 0===o)return!0;const i=zQ({routes:t,movablePreloadedConnectionNames:n,boardObstacles:e,connMap:this.params.connMap,layerCount:this.params.layerCount,viaToPadClearance:o});return i\u0026\u0026(this.stats.preloadedViaCandidateRejectionCount=Number(this.stats.preloadedViaCandidateRejectionCount??0)+1),!i}_step(){if(\"route\"===this.phase){if(this.highDensitySolver.step(),this.highDensitySolver.failed)return this.error=this.highDensitySolver.error,void(this.failed=!0);if(!this.highDensitySolver.solved)return;const t=AK(this.highDensitySolver.routes);return this.validateCandidateRoutes(t)?(this.forceImproveSolver=new Yy({nodeWithPortPoints:[this.params.nodeWithPortPoints],hdRoutes:t,colorMap:this.params.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*this.params.effort)),nodeAssignmentMargin:this.params.obstacleMargin}),this.activeSubSolver=this.forceImproveSolver,void(this.phase=\"improve\")):(this.error=\"Pipeline9 regional route output failed its candidate validator\",void(this.failed=!0))}if(\"improve\"===this.phase){if(this.forceImproveSolver.step(),this.forceImproveSolver.failed)return this.error=this.forceImproveSolver.error,void(this.failed=!0);if(!this.forceImproveSolver.solved)return;const t=this.forceImproveSolver.getOutput();return this.validateCandidateRoutes(t)?(this.repairSolver=new AY({nodeWithPortPoints:[this.params.nodeWithPortPoints],hdRoutes:t,obstacles:this.params.obstacles,colorMap:this.params.colorMap,repairMargin:this.params.obstacleMargin,maxSampleEntries:80,connMap:this.params.connMap}),this.activeSubSolver=this.repairSolver,void(this.phase=\"repair\")):(this.stats.forceImproveCandidateRejectionCount=Number(this.stats.forceImproveCandidateRejectionCount??0)+1,this.error=\"Pipeline9 regional force-improve output failed its candidate validator\",void(this.failed=!0))}if(\"repair\"===this.phase){if(this.repairSolver.step(),this.repairSolver.failed)return this.error=this.repairSolver.error,void(this.failed=!0);if(!this.repairSolver.solved)return;const t=this.repairSolver.getOutput();return this.validateCandidateRoutes(t)?(this.activeSubSolver=null,this.phase=\"done\",void(this.solved=!0)):(this.stats.repairCandidateRejectionCount=Number(this.stats.repairCandidateRejectionCount??0)+1,this.error=\"Pipeline9 regional repair output failed its candidate validator\",void(this.failed=!0))}}getOutput(){return this.repairSolver?.getOutput()??this.forceImproveSolver?.getOutput()??this.highDensitySolver.routes}visualize(){return this.repairSolver?.visualize()??this.forceImproveSolver?.visualize()??this.highDensitySolver.visualize()}},BQ=(t,e)=\u003e({minX:t.center.x-t.width/2-e,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2-e,maxY:t.center.y+t.height/2+e}),jQ=(t,e,n)=\u003e{const o=Math.max(n.minX-t.x,0,t.x-n.maxX),i=Math.max(n.minY-t.y,0,t.y-n.maxY);return o*o+i*i\u003c=e*e},$Q=(t,e,n,o)=\u003eMath.min(t.x,e.x)-n\u003c=o.maxX\u0026\u0026Math.max(t.x,e.x)+n\u003e=o.minX\u0026\u0026Math.min(t.y,e.y)-n\u003c=o.maxY\u0026\u0026Math.max(t.y,e.y)+n\u003e=o.minY,YQ=(t,e)=\u003e{const n=t=\u003e({...t,rootConnectionName:e.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName});return{...t,portPoints:t.portPoints.map(n),portPointsInPairs:t.portPointsInPairs?.map(([t,e])=\u003e[n(t),n(e)])}},XQ=({nodeWithPortPoints:t,connMap:e,colorMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a,obstacles:c,layerCount:l})=\u003enew zs({nodePortPoints:[YQ(t,e)],colorMap:n,connMap:e,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a,obstacles:c,layerCount:l,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!1,growShrinkFallbackToInvalidGeometryOnFailure:!1,captureSearchDebug:!1}),VQ=class extends si{fixedHdRoutes;connMap;colorMap;obstacles;layerCount;viaDiameter;traceWidth;obstacleMargin;viaToPadClearance;effort;nodePfById;preserveTerminalPcbPortIds;includeBoardObstacles;enableRegionalFallback;maxB01Rips;routes=[];failedSolvers=[];unsolvedNodePortPoints;fixedRouteReplacements=new Map;removedFixedRouteConnectionNames=new Set;preloadedTraceMutationMasks=new Map;activeRegularSolver=null;activeB01Solver=null;activeFallbackSolver=null;activeFallbackFixedRouteSections=new Map;activeFallbackFixedObstacleRoutes=[];activeFallbackPromotedFixedRouteConnectionNames=new Set;activeFallbackReason=null;activeNode=null;constructor(t){super(),this.fixedHdRoutes=t.fixedHdRoutes,this.connMap=t.connMap,this.colorMap=t.colorMap??{},this.obstacles=t.obstacles,this.layerCount=t.layerCount,this.viaDiameter=t.viaDiameter,this.traceWidth=t.traceWidth,this.obstacleMargin=t.obstacleMargin,this.viaToPadClearance=t.viaToPadClearance,this.effort=t.effort,this.nodePfById=t.nodePfById instanceof Map?new Map(t.nodePfById):new Map(Object.entries(t.nodePfById??{})),this.preserveTerminalPcbPortIds=t.preserveTerminalPcbPortIds??!1,this.includeBoardObstacles=t.includeBoardObstacles??!1,this.enableRegionalFallback=t.enableRegionalFallback??!0,this.maxB01Rips=t.maxB01Rips,this.unsolvedNodePortPoints=[...t.nodePortPoints],this.MAX_ITERATIONS=1e8*this.effort,this.stats={nodeCount:t.nodePortPoints.length,solvedNodeCount:0,fixedObstacleCount:t.fixedHdRoutes.length,fixedObstacleUses:0,boardObstacleUses:0,fallbackNodeCount:0,regularNodeCount:0,b01NodeCount:0,reroutedFixedRouteCount:0,reroutedFixedRouteSectionCount:0,promotedFallbackAttemptCount:0,promotedFixedRouteCount:0,regionalPreloadedViaCandidateRejectionCount:0,regionalForceImproveCandidateRejectionCount:0,regionalRepairCandidateRejectionCount:0}}getSolverName(){return\"Pipeline9HighDensitySolver\"}getUpdatedFixedHdRoutes(){return this.fixedHdRoutes.flatMap(t=\u003ethis.removedFixedRouteConnectionNames.has(t.connectionName)?[]:[this.fixedRouteReplacements.get(t.connectionName)??t])}finishActiveNode(t){const e=this.activeNode?((t,e)=\u003et.map(t=\u003e({...t,rootConnectionName:e.portPoints.find(e=\u003ee.connectionName===t.connectionName)?.rootConnectionName??t.rootConnectionName})))(t,this.activeNode):t;this.routes.push(...this.preserveTerminalPcbPortIds\u0026\u0026this.activeNode?((t,e)=\u003e{const n=e.portPoints.filter(t=\u003evoid 0!==t.pcb_port_id);return t.map(t=\u003e{const e=t.route[0],o=t.route.at(-1),i=n.find(n=\u003evoid 0!==e\u0026\u0026n.connectionName===t.connectionName\u0026\u0026n.x===e.x\u0026\u0026n.y===e.y\u0026\u0026n.z===e.z),r=n.find(e=\u003evoid 0!==o\u0026\u0026e.connectionName===t.connectionName\u0026\u0026e.x===o.x\u0026\u0026e.y===o.y\u0026\u0026e.z===o.z);return{...t,startPcbPortId:i?.pcb_port_id,endPcbPortId:r?.pcb_port_id}})})(e,this.activeNode):e),this.stats.solvedNodeCount=Number(this.stats.solvedNodeCount??0)+1,this.activeB01Solver=null,this.activeRegularSolver=null,this.activeFallbackSolver=null,this.activeFallbackFixedRouteSections.clear(),this.activeFallbackFixedObstacleRoutes=[],this.activeFallbackPromotedFixedRouteConnectionNames.clear(),this.activeFallbackReason=null,this.activeNode=null}startRegularSolver(t){this.activeNode=t,this.activeRegularSolver=XQ({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById,obstacles:this.obstacles,layerCount:this.layerCount}),this.stats.regularNodeCount=Number(this.stats.regularNodeCount??0)+1}startRegionalFallback(t=new Set){if(!this.activeNode)throw new Error(\"Pipeline9 cannot start a regional fallback without an active node\");const e={...YQ(this.activeNode,this.connMap),availableZ:Array.from({length:this.layerCount},(t,e)=\u003ee)},n=$K(e,this.getUpdatedFixedHdRoutes(),t),o=new Set([...n.fixedRouteSectionsByConnectionName.values()].flatMap(t=\u003et.sourceRoutes.map(t=\u003et.connectionName)));for(const e of t)if(!o.has(e))throw new Error(`Pipeline9 could not promote fixed route \"${e}\" into the active regional fallback`);const i=[...t].filter(t=\u003e!this.activeFallbackPromotedFixedRouteConnectionNames.has(t)).length;this.activeFallbackFixedRouteSections=n.fixedRouteSectionsByConnectionName,this.activeFallbackFixedObstacleRoutes=n.fixedObstacleRoutes,this.activeFallbackPromotedFixedRouteConnectionNames=new Set(t);const r=OQ({fixedObstacleRoutes:this.activeFallbackFixedObstacleRoutes,layerCount:this.layerCount});this.activeFallbackSolver=new FQ({nodeWithPortPoints:n.nodeWithPortPoints,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById,obstacles:[...this.obstacles,...r],boardObstacles:this.obstacles,movablePreloadedConnectionNames:o,viaToPadClearance:this.viaToPadClearance,layerCount:this.layerCount}),0===t.size?this.stats.fallbackNodeCount=Number(this.stats.fallbackNodeCount??0)+1:(this.stats.promotedFallbackAttemptCount=Number(this.stats.promotedFallbackAttemptCount??0)+1,this.stats.promotedFixedRouteCount=Number(this.stats.promotedFixedRouteCount??0)+i)}finishRegionalFallback(){if(!this.activeFallbackSolver)return;if(!this.activeNode)throw new Error(\"Pipeline9 cannot finish a regional fallback without an active node\");this.recordRegionalCandidateRejections();const t=[],e=new Map;for(const n of this.activeFallbackSolver.getOutput()){if(!this.activeFallbackFixedRouteSections.has(n.connectionName)){t.push(n);continue}const o=e.get(n.connectionName)??[];o.push(n),e.set(n.connectionName,o)}const n=[],o=[];for(const[t,i]of this.activeFallbackFixedRouteSections){const r=e.get(t)??[];if(0===r.length){o.push(i);continue}if(r.length\u003e1)return this.error=`Pipeline9 regional fallback expected one replacement for fixed route \"${t}\", got ${r.length}`,void(this.failed=!0);const s=VK({section:i,replacement:r[0],sourceMutationMasks:this.preloadedTraceMutationMasks,replacementIsMutated:!0});n.push({connectionName:t,section:i,replacement:s.route,mutatedSegments:s.mutatedSegments,replacementProducedSegment:s.replacementProducedSegment})}const i=[...t,...n.map(({replacement:t})=\u003et)],r=[...this.activeFallbackFixedObstacleRoutes,...o.flatMap(t=\u003et.sourceRoutes)],s=BQ(this.activeNode,this.obstacleMargin+Math.max(this.traceWidth,this.viaDiameter)/2),a=new Map;for(const t of i)for(const e of r)kQ(t,e,this.connMap)||DQ({left:t,right:e,clearance:this.obstacleMargin,leftBounds:s})\u0026\u0026a.set(e.connectionName,e);if(a.size\u003e0){const t=[...a.keys()],e=[...a].flatMap(([t,e])=\u003e!0===e.isThroughObstacle?[]:[t]),n=new Set(this.activeFallbackPromotedFixedRouteConnectionNames);for(const t of e)n.add(t);if(n.size===this.activeFallbackPromotedFixedRouteConnectionNames.size){const e=[...a].flatMap(([t,e])=\u003e!0===e.isThroughObstacle?[t]:[]);return this.error=e.length\u003e0?`Pipeline9 regional fallback conflicts with immutable through-obstacle route(s): ${e.join(\", \")}`:`Pipeline9 promoted regional fallback could not resolve immutable fixed route conflict(s): ${t.join(\", \")}`,void(this.failed=!0)}return void this.startRegionalFallback(n)}const c=new Map;for(const{section:t,replacementProducedSegment:e}of n)if(e)for(const e of t.sourceRoutes){const t=e.preloadedRoutePositionStart,n=e.preloadedRoutePositionEnd;if(void 0===t!=(void 0===n))throw new Error(`Pipeline9 fixed route \"${e.connectionName}\" has incomplete route-position metadata`);const o=Math.min(t??e.preloadedRouteIndex,n??e.preloadedRouteIndex),i=Math.max(t??e.preloadedRouteIndex,n??e.preloadedRouteIndex),r=c.get(e.preloadedTraceIndex);c.set(e.preloadedTraceIndex,{start:Math.min(r?.start??o,o),end:Math.max(r?.end??i,i)})}for(const{connectionName:t,section:e,replacement:o,mutatedSegments:i}of n){this.fixedRouteReplacements.set(t,o),this.preloadedTraceMutationMasks.set(t,i);for(const t of e.sourceRoutes.slice(1))this.removedFixedRouteConnectionNames.add(t.connectionName),this.preloadedTraceMutationMasks.delete(t.connectionName)}const l=$K({...YQ(this.activeNode,this.connMap),portPoints:[],portPointsInPairs:[],availableZ:Array.from({length:this.layerCount},(t,e)=\u003ee)},this.getUpdatedFixedHdRoutes()),d=new Set;for(const t of l.fixedRouteSectionsByConnectionName.values()){const e=t.sourceRoutes[0];if(!e)continue;const n=c.get(e.preloadedTraceIndex);if(n)for(const[o,i]of t.sourceRoutes.entries()){const r=i.preloadedRoutePositionStart??i.preloadedRouteIndex,s=i.preloadedRoutePositionEnd??i.preloadedRouteIndex,a={start:Math.min(r,s),end:Math.max(r,s)},c=a.start===a.end,l=n.start===n.end;if(!(c||l?a.start\u003c=n.end\u0026\u0026n.start\u003c=a.end:a.start\u003cn.end\u0026\u0026n.start\u003ca.end))continue;d.add(e.preloadedTraceIndex);const h=[...this.preloadedTraceMutationMasks.get(i.connectionName)??Array(i.route.length-1).fill(!1)];if(h.length!==i.route.length-1)throw new Error(`Pipeline9 fixed route mutation mask for \"${i.connectionName}\" has ${h.length} segments, expected ${i.route.length-1}`);const u=0===o?t.start.segmentIndex:0,p=o===t.sourceRoutes.length-1?t.end.segmentIndex:i.route.length-2;for(let t=u;t\u003c=p;t++)h[t]=!0;this.preloadedTraceMutationMasks.set(i.connectionName,h)}}for(const t of c.keys())if(!d.has(t))throw new Error(`Pipeline9 could not capture accepted mutation provenance for trace ${t}`);const h=n.reduce((t,{section:e})=\u003et+e.sourceRoutes.length,0);this.stats.reroutedFixedRouteCount=Number(this.stats.reroutedFixedRouteCount??0)+h,this.stats.reroutedFixedRouteSectionCount=Number(this.stats.reroutedFixedRouteSectionCount??0)+n.length,this.finishActiveNode(t)}recordRegionalCandidateRejections(){if(!this.activeFallbackSolver)return;const t=this.activeFallbackSolver.stats;this.stats.regionalPreloadedViaCandidateRejectionCount=Number(this.stats.regionalPreloadedViaCandidateRejectionCount??0)+Number(t.preloadedViaCandidateRejectionCount??0),this.stats.regionalForceImproveCandidateRejectionCount=Number(this.stats.regionalForceImproveCandidateRejectionCount??0)+Number(t.forceImproveCandidateRejectionCount??0),this.stats.regionalRepairCandidateRejectionCount=Number(this.stats.regionalRepairCandidateRejectionCount??0)+Number(t.repairCandidateRejectionCount??0)}finishRegularSolverFailure(t){if(this.activeFallbackReason=`regular high-density routing failed: ${t}`,this.activeRegularSolver=null,!this.enableRegionalFallback)return this.error=`Pipeline9 ${this.activeFallbackReason}`,this.failed=!0,void(this.activeNode=null);this.startRegionalFallback()}_step(){if(this.activeFallbackSolver){if(this.activeFallbackSolver.step(),this.activeFallbackSolver.failed)return this.recordRegionalCandidateRejections(),this.error=[`Pipeline9 primary high-density routing failed: ${this.activeFallbackReason??\"unknown error\"}`,`regional fallback failed: ${this.activeFallbackSolver.error??\"unknown error\"}`].join(\"; \"),this.failed=!0,this.activeFallbackSolver=null,this.activeFallbackFixedRouteSections.clear(),this.activeFallbackFixedObstacleRoutes=[],this.activeFallbackPromotedFixedRouteConnectionNames.clear(),void(this.activeNode=null);if(!this.activeFallbackSolver.solved)return;return void this.finishRegionalFallback()}if(this.activeRegularSolver){if(this.activeRegularSolver.step(),this.activeRegularSolver.failed)return void this.finishRegularSolverFailure(this.activeRegularSolver.error??\"unknown error\");if(!this.activeRegularSolver.solved)return;return void this.finishActiveNode(this.activeRegularSolver.routes)}if(this.activeB01Solver){if(this.activeB01Solver.step(),this.activeB01Solver.failed)return this.failedSolvers.push(this.activeB01Solver),this.activeFallbackReason=`B01 failed: ${this.activeB01Solver.error??\"unknown error\"}`,this.activeB01Solver=null,this.enableRegionalFallback?void this.startRegionalFallback():(this.error=`Pipeline9 ${this.activeFallbackReason}`,this.failed=!0,void(this.activeNode=null));if(!this.activeB01Solver.solved)return;return void this.finishActiveNode(this.activeB01Solver.getOutput())}const t=this.unsolvedNodePortPoints.pop();if(!t)return void(this.solved=!0);const e=BQ(t,this.obstacleMargin),n=Math.max(this.traceWidth,this.viaDiameter)/2,o=this.getUpdatedFixedHdRoutes().filter(o=\u003e((t,e,n,o)=\u003e{const i=new Set(e.availableZ??e.portPoints.map(t=\u003et.z));for(let e=1;e\u003ct.route.length;e++){const r=t.route[e-1],s=t.route[e];if(r.z===s.z){if(i.has(r.z)\u0026\u0026$Q(r,s,t.traceThickness/2+o,n))return!0;continue}const a=Math.min(r.z,s.z),c=Math.max(r.z,s.z);if([...i].some(t=\u003et\u003e=a\u0026\u0026t\u003c=c)\u0026\u0026jQ(s,t.viaDiameter/2+o,n))return!0}return!1})(o,t,e,n)).flatMap(e=\u003e((t,e)=\u003e{const n=new Set(e.availableZ??e.portPoints.map(t=\u003et.z));if(0===n.size)throw new Error(`Pipeline9 B01 node \"${e.capacityMeshNodeId}\" has no available layers`);const o={type:\"route\",connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,traceThickness:t.traceThickness,viaDiameter:t.viaDiameter},i=[];for(let e=1;e\u003ct.route.length;e++){const r=t.route[e-1],s=t.route[e];if(r.z===s.z){if(!n.has(r.z))continue;i.push({...o,route:[r,s],vias:[]});continue}const a=Math.min(r.z,s.z),c=Math.max(r.z,s.z);[...n].some(t=\u003et\u003e=a\u0026\u0026t\u003c=c)\u0026\u0026i.push({...o,route:[r,s],vias:[{x:s.x,y:s.y,zStart:r.z,zEnd:s.z}]})}return i})(e,t));if(this.stats.fixedObstacleUses=Number(this.stats.fixedObstacleUses??0)+o.length,0===o.length)return void this.startRegularSolver(t);const i=(this.includeBoardObstacles?this.obstacles:[]).filter(t=\u003e((t,e)=\u003e{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.abs(Math.cos(n)),i=Math.abs(Math.sin(n)),r=t.width/2*o+t.height/2*i,s=t.width/2*i+t.height/2*o;return t.center.x-r\u003c=e.maxX\u0026\u0026t.center.x+r\u003e=e.minX\u0026\u0026t.center.y-s\u003c=e.maxY\u0026\u0026t.center.y+s\u003e=e.minY})(t,e)).map(e=\u003e(({obstacle:t,node:e,connMap:n,layerCount:o})=\u003e{const i=new Set(e.availableZ??e.portPoints.map(t=\u003et.z)),r=(t.zLayers??t.layers.map(t=\u003eko(t,o))).filter(t=\u003ei.has(t));if(0===r.length)return;const s=t.connectedTo[0]??t.obstacleId??`pipeline9_obstacle_${t.center.x}_${t.center.y}`;return{type:\"rect\",connectionName:s,rootConnectionName:n.getNetConnectedToId(s)??s,center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,zLayers:r}})({obstacle:e,node:t,connMap:this.connMap,layerCount:this.layerCount})).filter(t=\u003evoid 0!==t);if(this.stats.boardObstacleUses=Number(this.stats.boardObstacleUses??0)+i.length,this.activeNode=t,t.width\u003e15||t.height\u003e15)return this.activeFallbackReason=`B01 node \"${t.capacityMeshNodeId}\" exceeds the 15x15mm routing limit (${t.width}x${t.height}mm)`,void this.startRegionalFallback();const r=YQ(t,this.connMap);this.stats.b01NodeCount=Number(this.stats.b01NodeCount??0)+1,this.activeB01Solver=new TQ({...sQ,nodeWithPortPoints:r,obstacles:[...o,...i],viaDiameter:this.viaDiameter,viaMinDistFromBorder:this.viaDiameter/2,traceThickness:this.traceWidth,traceMargin:this.obstacleMargin,obstacleClearanceMargin:.15,effort:this.effort}),void 0!==this.maxB01Rips\u0026\u0026(this.activeB01Solver.MAX_RIPS=this.maxB01Rips)}visualize(){return this.activeFallbackSolver?.visualize()??this.activeRegularSolver?.visualize()??this.activeB01Solver?.visualize()??{lines:this.routes.flatMap(t=\u003et.route.slice(0,-1).map((e,n)=\u003e({points:[e,t.route[n+1]],strokeWidth:t.traceThickness,layer:`z${e.z}`,label:t.connectionName}))),points:[],rects:[],circles:[]}}},WQ=(t,e)=\u003e{const n=e*Math.PI/180;return{x:t.x*Math.cos(n)-t.y*Math.sin(n),y:t.x*Math.sin(n)+t.y*Math.cos(n)}},HQ=({x:t,y:e,width:n,height:o,ccwRotation:i})=\u003e{const r=n/2,s=o/2;return[{x:-r,y:-s},{x:r,y:-s},{x:r,y:s},{x:-r,y:s}].map(n=\u003e{const o=WQ(n,i);return{x:t+o.x,y:e+o.y}})},GQ=t=\u003e{const e=\"rotated_pill\"===t.shape?t.ccw_rotation:0,n=Math.max(Math.max(t.width,t.height)/2-t.radius,0),o=t.width\u003e=t.height?{x:n,y:0}:{x:0,y:n},i=WQ(o,e);return{start:{x:t.x-i.x,y:t.y-i.y},end:{x:t.x+i.x,y:t.y+i.y},radius:t.radius}},UQ=t=\u003e{if(\"pcb_smtpad\"===t.type){if(\"polygon\"===t.shape)return t.points;if(\"rotated_rect\"===t.shape)return HQ({x:t.x,y:t.y,width:t.width,height:t.height,ccwRotation:t.ccw_rotation})}if(\"pcb_plated_hole\"===t.type\u0026\u0026\"rect_pad_width\"in t\u0026\u0026\"rect_pad_height\"in t)return HQ({x:t.x,y:t.y,width:t.rect_pad_width,height:t.rect_pad_height,ccwRotation:\"rect_ccw_rotation\"in t\u0026\u0026\"number\"==typeof t.rect_ccw_rotation?t.rect_ccw_rotation:0});throw new Error(`Expected polygonal pad geometry, got ${t.type} with shape \"${t.shape}\"`)},ZQ=t=\u003et.map((e,n)=\u003e[e,t[(n+1)%t.length]]),qQ=(t,e,n,o)=\u003e{const i=ve(t,e,n,o);if(i)return{distance:0,pointOnA:i,pointOnB:i,center:i};const r=[{pointOnA:t,pointOnB:ze(t,n,o)},{pointOnA:e,pointOnB:ze(e,n,o)},{pointOnA:ze(n,t,e),pointOnB:n},{pointOnA:ze(o,t,e),pointOnB:o}];let s=r[0],a=Ye(s.pointOnA,s.pointOnB);for(const t of r.slice(1)){const e=Ye(t.pointOnA,t.pointOnB);e\u003ca\u0026\u0026(s=t,a=e)}return{distance:Oe(t,e,n,o),pointOnA:s.pointOnA,pointOnB:s.pointOnB,center:{x:(s.pointOnA.x+s.pointOnB.x)/2,y:(s.pointOnA.y+s.pointOnB.y)/2}}};function JQ(t,e){return Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2)}var KQ=1e-9,QQ=1e-9;function t0(t,e){const n=(t.y-e.start.y)*(e.end.x-e.start.x)-(t.x-e.start.x)*(e.end.y-e.start.y);if(Math.abs(n)\u003eKQ)return!1;const o=(t.x-e.start.x)*(e.end.x-e.start.x)+(t.y-e.start.y)*(e.end.y-e.start.y);if(o\u003c-1e-9)return!1;return o\u003c=(e.end.x-e.start.x)**2+(e.end.y-e.start.y)**2+KQ}function e0(t,e){let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];if(t0(t,{start:r,end:s}))return!0;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n}function n0(t,e){if(\"pcb_smtpad\"===e.type){if(\"circle\"===e.shape)return JQ(t,e)\u003c=e.radius+QQ;if(\"rect\"===e.shape){const n=e.width/2,o=e.height/2;return Math.abs(t.x-e.x)\u003c=n+QQ\u0026\u0026Math.abs(t.y-e.y)\u003c=o+QQ}if(\"rotated_rect\"===e.shape)return e0(t,UQ(e));if(\"pill\"===e.shape||\"rotated_pill\"===e.shape){if(\"rotated_pill\"===e.shape){const n=GQ(e);return be(t,n.start,n.end)\u003c=n.radius+QQ}const n=e.width/2,o=e.height/2,i=e.radius;if(Math.abs(t.x-e.x)\u003c=n-i+QQ\u0026\u0026Math.abs(t.y-e.y)\u003c=o+QQ)return!0;const r=Math.max(Math.abs(t.x-e.x)-(n-i),0),s=Math.max(Math.abs(t.y-e.y)-(o-i),0),a=i+QQ;return r*r+s*s\u003c=a*a}if(\"polygon\"===e.shape)return e0(t,e.points)}if(\"pcb_plated_hole\"===e.type){if(\"circle\"===e.shape)return JQ(t,e)\u003c=e.outer_diameter/2+QQ;if(\"rect_pad_width\"in e\u0026\u0026\"rect_pad_height\"in e)return e0(t,UQ(e));if(\"oval\"===e.shape||\"pill\"===e.shape)return Math.abs(t.x-e.x)\u003c=e.outer_width/2+QQ\u0026\u0026Math.abs(t.y-e.y)\u003c=e.outer_height/2+QQ}return!1}function o0(t,e,n,o){return Math.sqrt((n-t)**2+(o-e)**2)}var i0=.1,r0=.1,s0=.2,a0=.1,c0=.005,l0=t=\u003et.find(t=\u003e\"pcb_board\"===t.type),d0=(t,e)=\u003et?.[e],h0=t=\u003eEM([t]),u0=t=\u003e{const e=h0(t);return Math.min(e.maxX-e.minX,e.maxY-e.minY)/2},p0=t=\u003e{const e=(t=\u003e{const e=h0(t);return $e({x:e.minX,y:e.minY},{x:e.maxX,y:e.maxY})})(t);return{kind:\"circle\",x:e.x,y:e.y,radius:u0(t)}},m0=t=\u003evM(t).pcb_trace.list().flatMap(t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];\"wire\"===o.route_type\u0026\u0026(\"wire\"===i.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({type:\"pcb_trace_segment\",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:\"width\"in o?o.width:\"width\"in i?i.width:a0,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),g0=t=\u003e{const e=t._pcbTrace.route.flatMap(t=\u003e\"through_pad\"===t.route_type?[t.start,t.end]:[{x:t.x,y:t.y}]),n=e[0],o=e[e.length-1];return n\u0026\u0026o?$e(n,o):$e({x:t.x1,y:t.y1},{x:t.x2,y:t.y2})},f0=({tracePoint:t,obstaclePoint:e,traceRadius:n,obstacleRadius:o})=\u003e{const i=e.x-t.x,r=e.y-t.y,s=Math.hypot(i,r);if(0===s)return $e(t,e);const a=i/s,c=r/s;return $e({x:t.x+a*n,y:t.y+c*n},{x:e.x-a*o,y:e.y-c*o})},y0=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=t.thickness/2;if(\"pcb_via\"===e.type||(\"pcb_via\"===(r=e).type||\"circle\"===r.shape)){const t=\"pcb_via\"===e.type?{x:e.x,y:e.y,radius:e.outer_diameter/2}:p0(e),r=ze(t,n,o);return{gap:De(n,o,t)-i,center:f0({tracePoint:r,obstaclePoint:t,traceRadius:i,obstacleRadius:t.radius})}}var r;if((t=\u003e\"pcb_smtpad\"===t.type\u0026\u0026(\"pill\"===t.shape||\"rotated_pill\"===t.shape))(e)){const n=((t,e)=\u003e{const n=GQ(e),o=qQ({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},n.start,n.end);return{distance:o.distance,center:o.center,radius:n.radius,tracePoint:o.pointOnA,obstaclePoint:o.pointOnB}})(t,e);return{gap:n.distance-i-n.radius,center:f0({tracePoint:n.tracePoint,obstaclePoint:n.obstaclePoint,traceRadius:i,obstacleRadius:n.radius})}}const s=((t,e,n)=\u003e{if(n.length\u003c3)return{distance:Number.POSITIVE_INFINITY,center:t,tracePoint:t,obstaclePoint:t};const o=ZQ(n).map(([n,o])=\u003eve(t,e,n,o)).filter(t=\u003enull!==t);if(o.length\u003e0){const n=e.x-t.x,i=e.y-t.y,r=n*n+i*i;return o.sort((e,o)=\u003e((e.x-t.x)*n+(e.y-t.y)*i)/r-((o.x-t.x)*n+(o.y-t.y)*i)/r),{distance:0,center:o[0],tracePoint:o[0],obstaclePoint:o[0]}}if(Ne(t,n)||Ne(e,n)){const n={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return{distance:0,center:n,tracePoint:n,obstaclePoint:n}}let i=qQ(t,e,n[0],n[1]);for(const[o,r]of ZQ(n).slice(1)){const n=qQ(t,e,o,r);n.distance\u003ci.distance\u0026\u0026(i=n)}return{distance:i.distance,center:i.center,tracePoint:i.pointOnA,obstaclePoint:i.pointOnB}})(n,o,(t=\u003e{if(\"pcb_smtpad\"===t.type\u0026\u0026(\"polygon\"===t.shape||\"rotated_rect\"===t.shape))return{kind:\"polygon\",points:UQ(t)};if(\"pcb_plated_hole\"===t.type\u0026\u0026\"rect_pad_width\"in t\u0026\u0026\"rect_pad_height\"in t)return{kind:\"polygon\",points:UQ(t)};const e=h0(t);return{kind:\"polygon\",points:[{x:e.minX,y:e.minY},{x:e.maxX,y:e.minY},{x:e.maxX,y:e.maxY},{x:e.minX,y:e.maxY}]}})(e).points);return{gap:s.distance-i,center:f0({tracePoint:s.tracePoint,obstaclePoint:s.obstaclePoint,traceRadius:i,obstacleRadius:0})}},_0=t=\u003et\u003c=0,b0=class{buckets;objectsById;getBounds;getId;CELL_SIZE=.4;constructor({objects:t,getBounds:e,getId:n,CELL_SIZE:o}){this.buckets=new Map,this.objectsById=new Map,this.getBounds=e,this.getId=n??(()=\u003ethis._getNextId()),this.CELL_SIZE=o??this.CELL_SIZE;for(const e of t)this.addObject(e)}_idCounter=0;_getNextId(){return\"\"+this._idCounter++}addObject(t){const e=this.getBounds(t),n=this.getId(t),o={...t,spatialIndexId:n};this.objectsById.set(n,o);const i=Math.floor(e.minX/this.CELL_SIZE),r=Math.floor(e.minY/this.CELL_SIZE),s=Math.floor(e.maxX/this.CELL_SIZE),a=Math.floor(e.maxY/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const n=`${t}x${e}`,i=this.buckets.get(n);i?i.push(o):this.buckets.set(n,[o])}}removeObject(t){const e=this.objectsById.get(t);if(!e)return!1;this.objectsById.delete(t);const n=this.getBounds(e),o=Math.floor(n.minX/this.CELL_SIZE),i=Math.floor(n.minY/this.CELL_SIZE),r=Math.floor(n.maxX/this.CELL_SIZE),s=Math.floor(n.maxY/this.CELL_SIZE);for(let e=o;e\u003c=r;e++)for(let n=i;n\u003c=s;n++){const o=`${e}x${n}`,i=this.buckets.get(o);if(i){const e=i.findIndex(e=\u003ee.spatialIndexId===t);-1!==e\u0026\u0026(i.splice(e,1),0===i.length\u0026\u0026this.buckets.delete(o))}}return!0}getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getObjectsInBounds(t,e=0){const n=[],o=new Set,i=Math.floor((t.minX-e)/this.CELL_SIZE),r=Math.floor((t.minY-e)/this.CELL_SIZE),s=Math.floor((t.maxX+e)/this.CELL_SIZE),a=Math.floor((t.maxY+e)/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const i=`${t}x${e}`,r=this.buckets.get(i)||[];for(const t of r){const e=t.spatialIndexId;o.has(e)||(o.add(e),n.push(t))}}return n}};function x0(t){return\"pcb_trace_segment\"===t.type||\"pcb_smtpad\"===t.type?[t.layer]:\"pcb_plated_hole\"===t.type?Array.isArray(t.layers)?t.layers:[...WS]:\"pcb_hole\"===t.type?[...WS]:\"pcb_via\"===t.type?Array.isArray(t.layers)?t.layers:[...WS]:\"pcb_keepout\"===t.type\u0026\u0026Array.isArray(t.layers)?t.layers:[]}var v0=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=e.minX,r=e.minY,s=e.maxX,a=e.maxY;if(n.x===o.x\u0026\u0026n.y===o.y){const t=Math.max(i,Math.min(s,n.x)),e=Math.max(r,Math.min(a,n.y));return t===n.x\u0026\u0026e===n.y?{x:n.x,y:n.y}:{x:t,y:e}}const c=o.x-n.x,l=o.y-n.y,d=0!==c?(i-n.x)/c:Number.NEGATIVE_INFINITY,h=0!==c?(s-n.x)/c:Number.POSITIVE_INFINITY,u=0!==l?(r-n.y)/l:Number.NEGATIVE_INFINITY,p=0!==l?(a-n.y)/l:Number.POSITIVE_INFINITY,m=Math.max(Math.min(d,h),Math.min(u,p)),g=Math.min(Math.max(d,h),Math.max(u,p));if(m\u003c=g\u0026\u0026g\u003e=0\u0026\u0026m\u003c=1){const t=Math.max(0,Math.min(1,m));return{x:n.x+t*c,y:n.y+t*l}}const f={x:Math.max(i,Math.min(s,n.x)),y:Math.max(r,Math.min(a,n.y))},y={x:Math.max(i,Math.min(s,o.x)),y:Math.max(r,Math.min(a,o.y))},_=(f.x-n.x)**2+(f.y-n.y)**2,b=(y.x-o.x)**2+(y.y-o.y)**2,x=[{start:{x:i,y:r},end:{x:s,y:r}},{start:{x:s,y:r},end:{x:s,y:a}},{start:{x:s,y:a},end:{x:i,y:a}},{start:{x:i,y:a},end:{x:i,y:r}}];let v=Math.min(_,b),S=_\u003c=b?f:y;const I=(t,e,n)=\u003eMath.max(e,Math.min(n,t));for(const t of x){const e={x:o.x-n.x,y:o.y-n.y},i={x:t.end.x-t.start.x,y:t.end.y-t.start.y},r={x:n.x-t.start.x,y:n.y-t.start.y},s=e.x*e.x+e.y*e.y,a=e.x*i.x+e.y*i.y,c=e.x*r.x+e.y*r.y,l=i.x*i.x+i.y*i.y,d=i.x*r.x+i.y*r.y,h=s*l-a*a;if(Math.abs(h)\u003c1e-10)continue;let u=(a*d-l*c)/h,p=(s*d-a*c)/h;u=I(u,0,1),p=I(p,0,1);const m={x:n.x+u*e.x,y:n.y+u*e.y},g={x:t.start.x+p*i.x,y:t.start.y+p*i.y},f=m.x-g.x,y=m.y-g.y,_=f*f+y*y;_\u003cv\u0026\u0026(v=_,S={x:(m.x+g.x)/2,y:(m.y+g.y)/2})}return S},S0=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i={x:e.x1,y:e.y1},r={x:e.x2,y:e.y2},s={x:o.x-n.x,y:o.y-n.y},a={x:r.x-i.x,y:r.y-i.y},c=s.x*s.x+s.y*s.y,l=a.x*a.x+a.y*a.y;if(0===c||0===l){if(0===c\u0026\u00260===l)return{x:(n.x+i.x)/2,y:(n.y+i.y)/2};if(0===c){const t=C0(((n.x-i.x)*a.x+(n.y-i.y)*a.y)/l,0,1),e={x:i.x+t*a.x,y:i.y+t*a.y};return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}}const t=C0(((i.x-n.x)*s.x+(i.y-n.y)*s.y)/c,0,1),e={x:n.x+t*s.x,y:n.y+t*s.y};return{x:(e.x+i.x)/2,y:(e.y+i.y)/2}}const d=n.x-i.x,h=n.y-i.y,u=s.x*s.x+s.y*s.y,p=s.x*a.x+s.y*a.y,m=s.x*d+s.y*h,g=a.x*a.x+a.y*a.y,f=a.x*d+a.y*h,y=u*g-p*p;if(y\u003c1e-10)return I0(n,o,i,r,s,a,c,l);let _=(p*f-g*m)/y,b=(u*f-p*m)/y;_=C0(_,0,1),b=C0(b,0,1),b=(_*p+f)/g,b=C0(b,0,1),_=(b*p-m)/u,_=C0(_,0,1);const x=n.x+_*s.x,v=n.y+_*s.y,S=i.x+b*a.x,I=i.y+b*a.y,C=x-S,P=v-I;Math.sqrt(C*C+P*P);return{x:(x+S)/2,y:(v+I)/2}},I0=(t,e,n,o,i,r,s,a)=\u003e{let c=((n.x-t.x)*i.x+(n.y-t.y)*i.y)/s;c=C0(c,0,1);const l={x:t.x+c*i.x,y:t.y+c*i.y};let d=((o.x-t.x)*i.x+(o.y-t.y)*i.y)/s;d=C0(d,0,1);const h={x:t.x+d*i.x,y:t.y+d*i.y};let u=((t.x-n.x)*r.x+(t.y-n.y)*r.y)/a;u=C0(u,0,1);const p={x:n.x+u*r.x,y:n.y+u*r.y};let m=((e.x-n.x)*r.x+(e.y-n.y)*r.y)/a;m=C0(m,0,1);const g={x:n.x+m*r.x,y:n.y+m*r.y},f=[{pointA:l,pointB:n,distance:Math.sqrt((l.x-n.x)**2+(l.y-n.y)**2)},{pointA:h,pointB:o,distance:Math.sqrt((h.x-o.x)**2+(h.y-o.y)**2)},{pointA:t,pointB:p,distance:Math.sqrt((t.x-p.x)**2+(t.y-p.y)**2)},{pointA:e,pointB:g,distance:Math.sqrt((e.x-g.x)**2+(e.y-g.y)**2)}].reduce((t,e)=\u003ee.distance\u003ct.distance?e:t);return{x:(f.pointA.x+f.pointB.x)/2,y:(f.pointA.y+f.pointB.y)/2}},C0=(t,e,n)=\u003eMath.max(e,Math.min(n,t)),P0=t=\u003e{if(\"pcb_trace_segment\"===t.type)return{minX:Math.min(t.x1,t.x2),minY:Math.min(t.y1,t.y2),maxX:Math.max(t.x1,t.x2),maxY:Math.max(t.y1,t.y2)};if(\"pcb_smtpad\"===t.type||\"pcb_plated_hole\"===t.type){if(\"pcb_smtpad\"===t.type\u0026\u0026(\"rotated_rect\"===t.shape||\"polygon\"===t.shape)||\"pcb_plated_hole\"===t.type\u0026\u0026\"rect_pad_width\"in t\u0026\u0026\"rect_pad_height\"in t){const e=UQ(t);return{minX:Math.min(...e.map(t=\u003et.x)),minY:Math.min(...e.map(t=\u003et.y)),maxX:Math.max(...e.map(t=\u003et.x)),maxY:Math.max(...e.map(t=\u003et.y))}}if(\"pcb_smtpad\"===t.type\u0026\u0026\"rotated_pill\"===t.shape){const e=GQ(t);return{minX:Math.min(e.start.x,e.end.x)-e.radius,minY:Math.min(e.start.y,e.end.y)-e.radius,maxX:Math.max(e.start.x,e.end.x)+e.radius,maxY:Math.max(e.start.y,e.end.y)+e.radius}}}return EM([t])};function M0(t){return\"wire\"!==t.route_type?[]:[t.start_pcb_port_id,t.end_pcb_port_id].filter(t=\u003eBoolean(t))}function N0(t){const e=new Set;for(const n of t.route)for(const t of M0(n))e.add(t);return Array.from(e)}function w0(t){const e=new Set;for(const n of t)for(const t of N0(n))e.add(t);return Array.from(e)}var T0=t=\u003e{if(\"pcb_via\"===t.type)return t.outer_diameter/2;if(\"pcb_plated_hole\"===t.type\u0026\u0026\"circle\"===t.shape)return t.outer_diameter/2;if(\"pcb_hole\"===t.type\u0026\u0026\"circle\"===t.hole_shape)return t.hole_diameter/2;if(\"pcb_smtpad\"===t.type\u0026\u0026\"circle\"===t.shape)return t.radius;throw new Error(`Could not determine radius of element: ${JSON.stringify(t)}`)},R0=t=\u003e\"pcb_port\"===t.type?t.pcb_port_id:\"pcb_smtpad\"===t.type?t.pcb_smtpad_id:t.pcb_plated_hole_id;function E0(t,{connMap:e,minClearance:n}={}){const o=[];(t=\u003e{const e=t.filter(t=\u003e\"pcb_port\"===t.type),n=t.filter(t=\u003e\"pcb_smtpad\"===t.type),o=t.filter(t=\u003e\"pcb_trace\"===t.type);function i(t,o={}){const i=o.traceWidth||0,r=e.find(e=\u003eo0(e.x,e.y,t.x,t.y)\u003c.01);if(r)return r.pcb_port_id;if(o.isFirstOrLastPoint){const e=n.find(e=\u003e\"rect\"===e.shape?Math.abs(t.x-e.x)\u003ce.width/2+i/2\u0026\u0026Math.abs(t.y-e.y)\u003ce.height/2+i/2:\"circle\"===e.shape?o0(t.x,t.y,e.x,e.y)\u003ce.radius:\"pill\"===e.shape||\"rotated_pill\"===e.shape?n0(t,e):void 0);if(e)return e.pcb_port_id??null}return null}for(const t of o)for(let e=0;e\u003ct.route.length;e++){const n=t.route[e],o=0===e||e===t.route.length-1;if(\"wire\"===n.route_type){if(!n.start_pcb_port_id\u0026\u00260===e){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.start_pcb_port_id=t)}if(!n.end_pcb_port_id\u0026\u0026e===t.route.length-1){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.end_pcb_port_id=t)}}}})(t),e??=ei(t);const i=l0(t);n??=d0(i,\"min_trace_to_pad_edge_clearance\")??.1;const r=vM(t).pcb_trace.list().flatMap(t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];\"wire\"===o.route_type\u0026\u0026(\"wire\"===i.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({type:\"pcb_trace_segment\",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:\"width\"in o?o.width:\"width\"in i?i.width:a0,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),s=vM(t).pcb_smtpad.list(),a=vM(t).pcb_plated_hole.list(),c=vM(t).pcb_port.list(),l=vM(t).pcb_hole.list(),d=vM(t).pcb_via.list(),h=vM(t).pcb_keepout.list(),u=[...c,...s,...a],p=new Map;for(const t of h){const e=new Set(t.excluded_pcb_component_ids??[]);0!==e.size\u0026\u0026p.set(t.pcb_keepout_id,u.filter(t=\u003et.pcb_component_id\u0026\u0026e.has(t.pcb_component_id)).map(R0))}const m=[...r,...s,...a,...l,...d,...h],g=new b0({objects:m,getBounds:P0}),f=e=\u003eNM(t,e),y=(t,e,n)=\u003e_0(n)?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,_=new Set;for(const t of r){const i=n,r=P0(t),s=g.getObjectsInBounds(r,i+t.thickness/2);if(t.x1!==t.x2||t.y1!==t.y2)for(const r of s){if(!x0(r).includes(t.layer))continue;if(\"pcb_keepout\"===r.type\u0026\u0026(p.get(r.pcb_keepout_id)??[]).some(n=\u003ee.areIdsConnected(t.pcb_trace_id,n)))continue;if(\"pcb_trace_segment\"===r.type){const i=r;if(t.layer!==i.layer)continue;if(e.areIdsConnected(t.pcb_trace_id,i.pcb_trace_id))continue;const s=Oe({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:i.x1,y:i.y1},{x:i.x2,y:i.y2})-t.thickness/2-i.thickness/2;if(s\u003en-c0)continue;const a=`overlap_${t.pcb_trace_id}_${i.pcb_trace_id}`,c=`overlap_${i.pcb_trace_id}_${t.pcb_trace_id}`;if(_.has(a))continue;if(_.has(c))continue;_.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),f(i.pcb_trace_id),s),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[],center:S0(t,i),pcb_port_ids:w0([t._pcbTrace,i._pcbTrace])});continue}const s=AM(r);if(e.areIdsConnected(t.pcb_trace_id,\"pcb_trace_id\"in r?r.pcb_trace_id:s))continue;if(\"pcb_smtpad\"===r.type||\"pcb_plated_hole\"===r.type||\"pcb_via\"===r.type){const{gap:e,center:n}=y0(t,r);if(!_0(e))continue;const i=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(i))continue;_.add(i),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),`${r.type} \"${f(s)}\"`,e),pcb_trace_id:t.pcb_trace_id,center:n,source_trace_id:\"\",pcb_trace_error_id:i,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...w0([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)});continue}if(\"pcb_hole\"===r.type){const e=T0(r),i=De({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:r.x,y:r.y,radius:e})-t.thickness/2;if(i\u003en-c0)continue;const a=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(a))continue;_.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),`${r.type} \"${f(AM(r))}\"`,i),pcb_trace_id:t.pcb_trace_id,center:v0(t,P0(r)),source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...w0([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}const a=ke({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},P0(r))-t.thickness/2;if(a+c0\u003ci){const e=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(e))continue;_.add(e),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),`${r.type} \"${f(AM(r))}\"`,a),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:e,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),center:v0(t,P0(r)),pcb_port_ids:[...w0([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}}}return o}function A0(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function O0(t,e){return A0(t,e)\u003c=c0}function k0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];const i=l0(t);n??=d0(i,\"min_via_hole_edge_to_via_hole_edge_clearance\")??i0,e??=ei(t);const r=[],s=new Set;for(let i=0;i\u003co.length;i++)for(let a=i+1;a\u003co.length;a++){const c=o[i],l=o[a];if(O0(c,l))continue;if(!e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=A0(c,l)-c.hole_diameter/2-l.hole_diameter/2;if(d+c0\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");s.has(h)||(s.add(h),r.push({type:\"pcb_via_clearance_error\",pcb_error_id:`same_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return r}function L0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];const i=l0(t);n??=d0(i,\"min_via_hole_edge_to_via_hole_edge_clearance\")??i0,e??=ei(t);const r=[],s=new Set;for(let i=0;i\u003co.length;i++)for(let a=i+1;a\u003co.length;a++){const c=o[i],l=o[a];if(O0(c,l))continue;if(e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=A0(c,l)-c.hole_diameter/2-l.hole_diameter/2;if(d+c0\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");s.has(h)||(s.add(h),r.push({type:\"pcb_via_clearance_error\",pcb_error_id:`different_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} from different nets are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return r}function D0(t){return\"through_pad\"===t.route_type?{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2}:{x:t.x,y:t.y}}function z0(t,e,n,o){return\"wire\"===t.route_type\u0026\u0026e.some(e=\u003e{if(!e.pcb_port_id||e.pcb_port_id===n)return!1;const i=o.get(e.pcb_port_id);return i?.some(e=\u003en0({x:t.x,y:t.y},e))??!1})}function F0({firstPoint:t,lastPoint:e,port:n,expectedPorts:o,padMap:i}){let r;const s=\"wire\"===t.route_type?t:void 0,a=\"wire\"===e.route_type?e:void 0,c=M0(t).includes(n.pcb_port_id),l=M0(e).includes(n.pcb_port_id);c\u0026\u0026s?r=s:l\u0026\u0026a||z0(t,o,n.pcb_port_id,i)\u0026\u0026a?r=a:z0(e,o,n.pcb_port_id,i)\u0026\u0026s?r=s:s\u0026\u0026a?r=A0(s,n)\u003c=A0(a,n)?s:a:s?r=s:a\u0026\u0026(r=a);const d=D0(t),h=D0(e);return r?{x:r.x,y:r.y}:{x:(d.x+h.x)/2,y:(d.y+h.y)/2}}function B0(t){const e=[],n=t.filter(t=\u003e\"pcb_port\"===t.type),o=t.filter(t=\u003e\"pcb_trace\"===t.type),i=t.filter(t=\u003e\"source_trace\"===t.type),r=t.filter(t=\u003e\"pcb_smtpad\"===t.type),s=t.filter(t=\u003e\"pcb_plated_hole\"===t.type),a=new Map,c=new ni(t),l=new Set;for(const t of r)t.pcb_port_id\u0026\u0026a.set(t.pcb_port_id,[...a.get(t.pcb_port_id)??[],t]);for(const t of s)t.pcb_port_id\u0026\u0026a.set(t.pcb_port_id,[...a.get(t.pcb_port_id)??[],t]);for(const r of o){if(0===r.route.length)continue;const s=r.route[0],d=r.route[r.route.length-1],h=i.find(t=\u003et.source_trace_id===r.source_trace_id),u=h?n.filter(t=\u003eh.connected_source_port_ids?.includes(t.source_port_id)):[];for(let n=1;n\u003cr.route.length-1;n++){const o=r.route[n-1],i=r.route[n],s=r.route[n+1];if(\"via\"===i.route_type){const a=\"wire\"===o.route_type,c=\"wire\"===s.route_type;if(a\u0026\u0026c){const a=Math.abs(o.x-i.x)\u003c.01\u0026\u0026Math.abs(o.y-i.y)\u003c.01,c=Math.abs(s.x-i.x)\u003c.01\u0026\u0026Math.abs(s.y-i.y)\u003c.01;if(!a||!c){const o=PM(t,r.pcb_trace_id);e.push({type:\"pcb_trace_error\",message:`Via in trace [${o}] is misaligned at position {x: ${i.x}, y: ${i.y}}.`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`misaligned_via_${r.pcb_trace_id}_${n}`,pcb_component_ids:[],pcb_port_ids:[]})}}}}const p=PM(t,r.pcb_trace_id);if(h\u0026\u0026u.length\u003e0){if(l.has(h.source_trace_id))continue;l.add(h.source_trace_id)}for(const n of u){if(!n.pcb_port_id)continue;const l=a.get(n.pcb_port_id);if(!l?.length)continue;let m=!1;const g=[...c.getAllTracesConnectedToTrace(r.pcb_trace_id),...o.filter(t=\u003et.source_trace_id===h?.source_trace_id)];for(const t of g){if(t.pcb_trace_id===r.pcb_trace_id)continue;if(!t.source_trace_id)continue;const e=i.find(e=\u003ee.source_trace_id===t.source_trace_id);if(!h||t.source_trace_id!==h.source_trace_id\u0026\u0026!e?.connected_source_port_ids.includes(n.source_port_id))continue;const o=t.route[0],s=t.route.at(-1);if(N0(t).includes(n.pcb_port_id)||\"wire\"===o?.route_type\u0026\u0026l.some(t=\u003en0(o,t))||\"wire\"===s?.route_type\u0026\u0026l.some(t=\u003en0(s,t))){m=!0;break}}if(m)continue;const f=\"wire\"===s.route_type\u0026\u0026l.some(t=\u003en0({x:s.x,y:s.y},t)),y=\"wire\"===d.route_type\u0026\u0026l.some(t=\u003en0({x:d.x,y:d.y},t));if(!f\u0026\u0026!y){const o=MM(t,n.pcb_port_id).replace(\"pcb_port\",\"\"),i=l[0].type.replace(/pcb_/,\"\"),c=F0({firstPoint:s,lastPoint:d,port:n,expectedPorts:u,padMap:a});e.push({type:\"pcb_trace_error\",message:`Trace [${p}] is missing a connection to ${i}${o}`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`missing_connection_${r.pcb_trace_id}_${n.pcb_port_id}`,center:c,pcb_component_ids:[],pcb_port_ids:[n.pcb_port_id]})}}if(0===u.length){let t=!1,n=!1;const o=\"wire\"===s.route_type\u0026\u0026\"wire\"===d.route_type\u0026\u0026Math.abs(s.x-d.x)\u003c.01\u0026\u0026Math.abs(s.y-d.y)\u003c.01;for(const e of a.values())\"wire\"===s.route_type\u0026\u0026e.some(t=\u003en0({x:s.x,y:s.y},t))\u0026\u0026(t=!0),\"wire\"===d.route_type\u0026\u0026e.some(t=\u003en0({x:d.x,y:d.y},t))\u0026\u0026(n=!0);t||\"wire\"!==s.route_type||e.push({type:\"pcb_trace_error\",message:`Trace [${p}] has disconnected endpoint at (${s.x.toFixed(2)}, ${s.y.toFixed(2)})`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`disconnected_endpoint_${r.pcb_trace_id}_start`,center:{x:s.x,y:s.y},pcb_component_ids:[],pcb_port_ids:[]}),n||\"wire\"!==d.route_type||o\u0026\u0026!t||e.push({type:\"pcb_trace_error\",message:`Trace [${p}] has disconnected endpoint at (${d.x.toFixed(2)}, ${d.y.toFixed(2)})`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`disconnected_endpoint_${r.pcb_trace_id}_end`,center:{x:d.x,y:d.y},pcb_component_ids:[],pcb_port_ids:[]})}}return e}function j0(t,e={}){const n=[],o=l0(t);if(!o)return n;const i=e.margin??d0(o,\"min_board_edge_clearance\")??s0,r=function(t){if(t.outline\u0026\u0026t.outline.length\u003e0)return t.outline.map(t=\u003e({x:t.x,y:t.y}));if(t.center\u0026\u0026\"number\"==typeof t.width\u0026\u0026\"number\"==typeof t.height){const e=t.center.x,n=t.center.y,o=t.width/2,i=t.height/2;return[{x:e-o,y:n-i},{x:e+o,y:n-i},{x:e+o,y:n+i},{x:e-o,y:n+i}]}return null}(o);if(!r)return n;const s=vM(t).pcb_trace.list();for(const t of s)if(!(t.route.length\u003c2))for(let e=0;e\u003ct.route.length-1;e++){const o=t.route[e],s=t.route[e+1];if(\"wire\"!==o.route_type||\"wire\"!==s.route_type)continue;const a=\"width\"in o?o.width:\"width\"in s?s.width:.1,c={x:o.x,y:o.y},l={x:s.x,y:s.y};let d=Number.POSITIVE_INFINITY;for(let t=0;t\u003cr.length;t++){const e=Oe(c,l,r[t],r[(t+1)%r.length]);e\u003cd\u0026\u0026(d=e)}const h=a/2+i;if(d\u003ch){const o={type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",pcb_trace_error_id:`trace_too_close_to_board_${t.pcb_trace_id}_segment_${e}`,message:`Trace too close to board edge (${d.toFixed(3)}mm \u003c ${h.toFixed(3)}mm required, margin: ${i}mm)`,pcb_trace_id:t.pcb_trace_id,source_trace_id:t.source_trace_id||\"\",center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2},pcb_component_ids:[],pcb_port_ids:[]};n.push(o)}}return n}function $0(t,{connMap:e,minClearance:n}={}){const o=(t=\u003e[...vM(t).pcb_smtpad.list(),...vM(t).pcb_plated_hole.list()])(t),i=m0(t);if(0===o.length||0===i.length)return[];const r=l0(t);n??=d0(r,\"min_trace_to_pad_edge_clearance\")??r0,e??=ei(t);const s=new b0({objects:o,getBounds:h0,getId:t=\u003eAM(t)}),a=new Map,c=new Set;for(const o of i){const i=s.getObjectsInBounds(P0(o),n+o.thickness/2);for(const r of i){const i=AM(r);if(!x0(r).includes(o.layer))continue;if(e.areIdsConnected(o.pcb_trace_id,i))continue;const s=`${i}_${o.pcb_trace_id}`,{gap:l}=y0(o,r);if(_0(l)){a.delete(s),c.add(s);continue}if(c.has(s))continue;if(l+c0\u003e=n)continue;const d={type:\"pcb_pad_trace_clearance_error\",pcb_pad_trace_clearance_error_id:`pad_trace_clearance_${s}`,error_type:\"pcb_pad_trace_clearance_error\",message:`Pad ${NM(t,i)} and trace ${NM(t,o.pcb_trace_id)} are too close (clearance: ${I_(l)}, minimum: ${I_(n)})`,pcb_pad_id:i,pcb_trace_id:o.pcb_trace_id,minimum_clearance:n,actual_clearance:l,center:g0(o)},h=a.get(s);(!h||l\u003ch.gap)\u0026\u0026a.set(s,{error:d,gap:l})}}return Array.from(a.values()).map(({error:t})=\u003et)}function Y0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type),i=m0(t);if(0===o.length||0===i.length)return[];const r=l0(t);n??=d0(r,\"min_trace_to_pad_edge_clearance\")??r0,e??=ei(t);const s=new Map,a=new Set;for(const r of o)for(const o of i){if(!x0(r).includes(o.layer))continue;if(e.areIdsConnected(o.pcb_trace_id,r.pcb_via_id))continue;const i=`${r.pcb_via_id}_${o.pcb_trace_id}`,{gap:c}=y0(o,r);if(_0(c)){s.delete(i),a.add(i);continue}if(a.has(i))continue;if(c+c0\u003e=n)continue;const l={type:\"pcb_via_trace_clearance_error\",pcb_via_trace_clearance_error_id:`via_trace_clearance_${i}`,error_type:\"pcb_via_trace_clearance_error\",message:`Via ${NM(t,r.pcb_via_id)} and trace ${NM(t,o.pcb_trace_id)} are too close (clearance: ${I_(c)}, minimum: ${I_(n)})`,pcb_via_id:r.pcb_via_id,pcb_trace_id:o.pcb_trace_id,minimum_clearance:n,actual_clearance:c,center:g0(o)},d=s.get(i);(!d||c\u003cd.gap)\u0026\u0026s.set(i,{error:l,gap:c})}return Array.from(s.values()).map(({error:t})=\u003et)}var X0=(t,e={})=\u003e{const n=(t=\u003e{const e=ei(t),n=t.filter(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_trace_id).map(t=\u003e[t.pcb_via_id,t.pcb_trace_id]);return e.addConnections(n),e})(t),o=Math.max(e.viaClearance??.1,.1),i=E0(t,{connMap:n,minClearance:e.traceClearance}),r=!1!==e.includeTypedTraceClearance,s=r?Y0(t,{connMap:n,minClearance:e.traceClearance}):[],a=r?$0(t,{connMap:n,minClearance:e.traceClearance}):[],c=[...k0(t,{connMap:n,minClearance:o}),...L0(t,{connMap:n,minClearance:o})],l=[...i,...j0(t),...!1===e.includeTraceContinuity?[]:B0(t),...s,...a,...c],d=t.filter(t=\u003e\"pcb_via\"===t.type),h=new Map(d.map(t=\u003e[t.pcb_via_id,t])),u=l.map(t=\u003e{if(\"pcb_via_trace_clearance_error\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id){const e=h.get(t.pcb_via_id);if(e)return{...t,center:{x:e.x,y:e.y}}}if(\"center\"in t\u0026\u0026t.center)return t;if(\"pcb_center\"in t\u0026\u0026t.pcb_center)return{...t,center:t.pcb_center};if(\"pcb_via_ids\"in t\u0026\u0026Array.isArray(t.pcb_via_ids)){const[e,n]=t.pcb_via_ids,o=h.get(e),i=h.get(n);if(o\u0026\u0026i)return{...t,center:{x:(o.x+i.x)/2,y:(o.y+i.y)/2}}}if(\"pcb_error_id\"in t\u0026\u0026\"string\"==typeof t.pcb_error_id\u0026\u0026(t.pcb_error_id.startsWith(\"same_net_vias_close_\")||t.pcb_error_id.startsWith(\"different_net_vias_close_\"))){const e=t.pcb_error_id.replace(\"same_net_vias_close_\",\"\").replace(\"different_net_vias_close_\",\"\").split(\"_\").filter(Boolean);if(2===e.length){const n=h.get(e[0]),o=h.get(e[1]);if(n\u0026\u0026o)return{...t,center:{x:(n.x+o.x)/2,y:(n.y+o.y)/2}}}}return t}),p=u.filter(t=\u003eBoolean(t.center));return{errors:l,errorsWithCenters:u,locationAwareErrors:p}},V0={traceClearance:.1,viaClearance:.1};var W0=t=\u003et.circuitJsonMetadata??{},H0=({connections:t,obstacles:e})=\u003enew Set([...t.flatMap(t=\u003et.pointsToConnect.flatMap(t=\u003et.pcb_port_id?[t.pcb_port_id]:[])),...e.flatMap(t=\u003e{const e=W0(t).pcb_port_id;return e?[e]:[]})]),G0=t=\u003et.__netConnectionName??t.__rootConnectionNames?.[0]??t.name,U0=t=\u003eArray.from(new Set([t.name,t.__netConnectionName,...t.__rootConnectionNames??[],...t.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])])).filter(t=\u003eBoolean(t)),Z0=(t,e)=\u003e{const n=new Map,o=new Set,i=new Map;for(const r of t){const t=G0(r);for(const e of U0(r)){const i=n.get(e);i\u0026\u0026i!==t?(n.delete(e),o.add(e)):o.has(e)||n.set(e,t)}const s=e.getNetConnectedToId(r.name);if(!s)continue;const a=s,c=i.get(a)??new Set;c.add(t),i.set(a,c)}return{connMap:e,circuitJsonSourceTraceIdBySrjDeclaredConnectionReference:n,circuitJsonSourceTraceIdsByConnectivityNetId:i}},q0=(t,e)=\u003e{const n=t.circuitJsonSourceTraceIdBySrjDeclaredConnectionReference.get(e);if(n)return n;const o=t.connMap.getNetConnectedToId(e);if(!o)return;const i=t.circuitJsonSourceTraceIdsByConnectivityNetId.get(o);return 1===i?.size?i.values().next().value:void 0};function J0(t,e,n=t){const o=[],i=n===t?t.connections:[...t.connections,...n.connections],r=n===t?t.obstacles:n.obstacles,s=Z0(i,ii(n===t?t:{...n,connections:i})),a=H0({connections:i,obstacles:r});if(i.forEach(t=\u003e{const n=t.pointsToConnect.map(t=\u003et.pcb_port_id).filter(t=\u003eBoolean(t)),i=new Set(n),a=t=\u003e(t=\u003eArray.from(new Set(t.flatMap(t=\u003et.connectedTo))))(t).filter(t=\u003e!i.has(t)),c=t.pointsToConnect.map(t=\u003et.pointId).filter(t=\u003eBoolean(t)),l=q0(s,t.name)??G0(t),d=[],h=e.find(e=\u003e(e.connection_name??e.connectionName)===t.name);if(h){const t=t=\u003e\"route_type\"in t\u0026\u0026\"jumper\"===t.route_type?t.start:\"x\"in t\u0026\u0026\"y\"in t?{x:t.x,y:t.y}:{x:0,y:0},e=[t(h.route[0]),t(h.route[h.route.length-1])];for(const t of e)for(const e of r)Be(t,e)\u003c=0\u0026\u0026d.push(e)}const u=o.find(t=\u003e\"source_trace\"===t.type\u0026\u0026t.source_trace_id===l);if(u){const t=u;t.connected_source_port_ids=[...new Set([...t.connected_source_port_ids,...n])],t.connected_source_net_ids=[...new Set([...t.connected_source_net_ids??[],...c,...a(d)])]}else o.push({type:\"source_trace\",source_trace_id:l,connected_source_port_ids:n,connected_source_net_ids:a(d).concat(c)})}),e[0]\u0026\u0026\"type\"in e[0]){const t=new Map(i.map(t=\u003e[t.name,t]));for(const n of e){const e=[...new Set((n.connectsTo??[]).filter(t=\u003ea.has(t)))],i=new Set(e),r=[...new Set((n.connectsTo??[]).filter(t=\u003e!i.has(t)))];if(0===e.length\u0026\u00260===r.length)continue;const c=t.get(n.connection_name),l=q0(s,n.connection_name)??n.connectsTo?.map(t=\u003eq0(s,t)).find(t=\u003evoid 0!==t)??(c?G0(c):n.connection_name),d=o.find(t=\u003e\"source_trace\"===t.type\u0026\u0026t.source_trace_id===l);\"source_trace\"!==d?.type?o.push({type:\"source_trace\",source_trace_id:l,connected_source_port_ids:e,connected_source_net_ids:r}):(d.connected_source_port_ids=[...new Set([...d.connected_source_port_ids,...e])],d.connected_source_net_ids=[...new Set([...d.connected_source_net_ids??[],...r])])}}return o}function K0(t,e,n){let o,i=Number.POSITIVE_INFINITY;for(const r of e){const e=n.get(r);if(!e)continue;const s=Math.hypot(e.x-t.x,e.y-t.y);s\u003ci\u0026\u0026(i=s,o=r)}return o??e[0]}var Q0=new Set([\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\",\"inner7\",\"inner8\"]),t1=t=\u003eQ0.has(t);function e1(t){const e=[],n=new Set,o=new Set,i=function(t){const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{x:t.x,y:t.y});return e}(t),r=H0(t);for(const s of t.obstacles){const t=s.connectedTo,a=W0(s);if(a.pcb_via_id)continue;const c=a.pcb_smtpad_id,l=a.pcb_plated_hole_id,d=[...new Set([...a.pcb_port_id?[a.pcb_port_id]:[],...t.filter(t=\u003er.has(t))])],h=K0(s.center,d,i);if(!c\u0026\u0026!l\u0026\u0026!h)continue;const u=s.layers.filter(t1);if(0===u.length)continue;const p=s.width,m=s.height,g=s.center.x,f=s.center.y,y=s.ccwRotationDegrees;if(Boolean(l)||u.length\u003e1){const t=l??`pcb_plated_hole_${g.toFixed(3)}_${f.toFixed(3)}`;if(o.has(t))continue;if(o.add(t),\"number\"==typeof y\u0026\u0026Number.isFinite(y)){const n=Math.max(.5*Math.min(p,m),.1);e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"rotated_pill_hole_with_rect_pad\",hole_shape:\"rotated_pill\",pad_shape:\"rect\",hole_width:n,hole_height:n,hole_ccw_rotation:y,rect_pad_width:p,rect_pad_height:m,rect_ccw_rotation:y,hole_offset_x:0,hole_offset_y:0,x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}if(Math.abs(p-m)\u003c.001){e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circle\",outer_diameter:Math.max(p,m),hole_diameter:Math.max(.5*Math.min(p,m),.1),x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circular_hole_with_rect_pad\",hole_shape:\"circle\",hole_diameter:Math.max(.5*Math.min(p,m),.1),rect_pad_width:p,rect_pad_height:m,hole_offset_x:0,hole_offset_y:0,x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}const _=c??`pcb_smtpad_${g.toFixed(3)}_${f.toFixed(3)}`;n.has(_)||(n.add(_),\"number\"==typeof y\u0026\u0026Number.isFinite(y)?e.push({type:\"pcb_smtpad\",pcb_smtpad_id:_,layer:u[0],shape:\"rotated_rect\",x:g,y:f,width:p,height:m,ccw_rotation:y,...h?{pcb_port_id:h}:{}}):e.push({type:\"pcb_smtpad\",pcb_smtpad_id:_,layer:u[0],shape:\"rect\",width:p,height:m,x:g,y:f,...h?{pcb_port_id:h}:{}}))}return e}function n1(t,e,n={}){const{minTraceWidth:o=.1,minViaDiameter:i,minViaHoleDiameter:r,originalSrj:s,includeOriginalConnections:a=!1}=n,c=Yo(t),l=i??c.padDiameter,d=t.min_via_hole_diameter??t.minViaHoleDiameter,h=r??d??(void 0!==i?.5*l:c.holeDiameter),u=[];u.push(...J0(t,e,a\u0026\u0026s?s:t)),u.push(...function(t){const e=new Map;return t.connections.forEach(t=\u003e{t.pointsToConnect.forEach(t=\u003e{t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{type:\"pcb_port\",pcb_port_id:t.pcb_port_id,source_port_id:t.pcb_port_id,x:t.x,y:t.y,layers:xo(t)})})}),Array.from(e.values())}(a\u0026\u0026s?s:t)),u.push(...e1(s??t)),u.push(...function(t,e,n=.3,o=.5*n){const i=[],r=new Set;return t.length\u003e0\u0026\u0026(\"type\"in t[0]\u0026\u0026\"pcb_trace\"===t[0].type?t.forEach(t=\u003e{t.route.forEach(s=\u003e{if(\"via\"===s.route_type){if(!t1(s.from_layer)||!t1(s.to_layer))return;const a=s.via_diameter??n,c=s.via_hole_diameter??o,l=`${s.x},${s.y},${s.from_layer},${s.to_layer}`;r.has(l)||(i.push({type:\"pcb_via\",pcb_via_id:`via_${i.length}`,pcb_trace_id:t.pcb_trace_id,x:s.x,y:s.y,outer_diameter:a,hole_diameter:c,layers:Wy(s,e)}),r.add(l))}})}):t.forEach((t,s)=\u003e{const a=`trace_${s}`,c=t.viaDiameter??n,l=o;for(let n=1;n\u003ct.route.length;n++){const o=t.route[n-1],s=t.route[n];if(o.z!==s.z\u0026\u0026Math.abs(o.x-s.x)\u003c.01\u0026\u0026Math.abs(o.y-s.y)\u003c.01){const t=vo(o.z,e),n=vo(s.z,e),d=`${s.x},${s.y},${t},${n}`;r.has(d)||(i.push({type:\"pcb_via\",pcb_via_id:`via_${i.length}`,pcb_trace_id:a,x:s.x,y:s.y,outer_diameter:c,hole_diameter:l,layers:Wy({from_layer:t,to_layer:n},e)}),r.add(d))}}})),i}(e,t.layerCount,l,h));const p=Z0(t.connections,ii(t));return e.length\u003e0\u0026\u0026(\"type\"in e[0]\u0026\u0026\"pcb_trace\"===e[0].type?e.forEach(t=\u003e{const e=q0(p,t.connection_name)??t.connectsTo?.map(t=\u003eq0(p,t)).find(t=\u003eBoolean(t))??t.connection_name;u.push(function(t,e){return{type:\"pcb_trace\",pcb_trace_id:t.pcb_trace_id,source_trace_id:e,route:t.route.map(t=\u003e{if(\"wire\"===t.route_type){if(!t1(t.layer))return null;const e=\"start_pcb_port_id\"in t\u0026\u0026\"string\"==typeof t.start_pcb_port_id?t.start_pcb_port_id:void 0,n=\"end_pcb_port_id\"in t\u0026\u0026\"string\"==typeof t.end_pcb_port_id?t.end_pcb_port_id:void 0;return{route_type:\"wire\",x:t.x,y:t.y,width:t.width,layer:t.layer,...e?{start_pcb_port_id:e}:{},...n?{end_pcb_port_id:n}:{}}}return\"via\"===t.route_type\u0026\u0026t1(t.from_layer)\u0026\u0026t1(t.to_layer)?{route_type:\"via\",x:t.x,y:t.y,from_layer:t.from_layer,to_layer:t.to_layer}:null}).filter(t=\u003enull!==t)}}(t,e))}):e.forEach((e,n)=\u003e{const i=function(t,e,n,o,i=.1){const r=[];if(!t.jumpers||0===t.jumpers.length)return[{type:\"pcb_trace\",pcb_trace_id:e,source_trace_id:n,route:t.route.map((e,n)=\u003e{const r=0===n,s=n===t.route.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:e.traceThickness??i,layer:vo(e.z,o),...r\u0026\u0026e.pcb_port_id?{start_pcb_port_id:e.pcb_port_id}:{},...s\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})}];const s=[];for(const e of t.jumpers){let n=-1,o=-1;for(let i=0;i\u003ct.route.length;i++){const r=t.route[i];Math.abs(r.x-e.start.x)\u003c.01\u0026\u0026Math.abs(r.y-e.start.y)\u003c.01\u0026\u0026(n=i),Math.abs(r.x-e.end.x)\u003c.01\u0026\u0026Math.abs(r.y-e.end.y)\u003c.01\u0026\u0026(o=i)}-1!==n\u0026\u0026-1!==o\u0026\u0026(n\u003eo\u0026\u0026([n,o]=[o,n]),s.push({startIdx:n,endIdx:o}))}s.sort((t,e)=\u003et.startIdx-e.startIdx);let a=0,c=0;for(const{startIdx:l,endIdx:d}of s){if(l\u003e=a){const s=t.route.slice(a,l+1);s.length\u003e0\u0026\u0026(r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((t,e)=\u003e{const n=0===e\u0026\u00260===a;return{route_type:\"wire\",x:t.x,y:t.y,width:t.traceThickness??i,layer:vo(t.z,o),...n\u0026\u0026t.pcb_port_id?{start_pcb_port_id:t.pcb_port_id}:{}}})}),c++)}a=d}if(a\u003ct.route.length){const s=t.route.slice(a);if(s.length\u003e0){const t=!0;r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((e,n)=\u003e{const r=t\u0026\u0026n===s.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:e.traceThickness??i,layer:vo(e.z,o),...r\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})})}}return r}(e,`trace_${n}`,q0(p,e.connectionName)??e.connectionName,t.layerCount,o);u.push(...i)})),u}var o1=(t,e)=\u003e{const n=new Set(e.flatMap(t=\u003et.__replaces_pcb_trace_id?[t.__replaces_pcb_trace_id]:[]));return[...t.filter(t=\u003e!n.has(t.pcb_trace_id)),...e]},i1=({inputSrj:t,srjWithPointPairs:e,routedTraces:n,drcOptions:o})=\u003e{const i=t.traces??[],r=n1(e,o1(i,n),{minTraceWidth:t.minTraceWidth,minViaDiameter:t.minViaDiameter,originalSrj:t,includeOriginalConnections:!0});return{circuitJson:r,...X0(r,{...V0,...o})}},r1=(t,e)=\u003e{const n=t({hdRoutes:e,traces:[]});return Array.isArray(n)?n:n.errorsWithCenters??n.errors},s1=t=\u003e{const e=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,n=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],o=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids:[]].filter(t=\u003e\"string\"==typeof t),i=e?`overlap_${e}_`:void 0,r=i\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0;if(n.length\u003e0){const t=e\u0026\u0026!n.includes(e)?[e,...n]:[...n];return t.length\u003c2\u0026\u0026r\u0026\u0026!o.includes(r)\u0026\u0026t.push(r),t}return[e,r].filter(t=\u003e\"string\"==typeof t\u0026\u0026!o.includes(t))},a1=t=\u003es1(t).filter((t,e,n)=\u003en.indexOf(t)===e),c1=t=\u003et.reduce((t,e)=\u003e{if(\"number\"==typeof e.actual_clearance\u0026\u0026\"number\"==typeof e.minimum_clearance)return t+Math.max(0,e.minimum_clearance-e.actual_clearance);const n=(\"string\"==typeof e.message?e.message:\"\").match(/gap: (-?\\d+(?:\\.\\d+)?)mm/);return n?t+Math.max(0,.1-Number.parseFloat(n[1])):t+1},0),l1=(t,e)=\u003et.length\u003ce.length||t.length===e.length\u0026\u0026c1(t)\u003cc1(e)-1e-9,d1=({routes:t,newConnections:e,syntheticConnectionNames:n})=\u003e{const o=new Set([...e.map(t=\u003et.name),...n]),i=new Map,r=new Map;for(let e=0;e\u003ct.length;e++){const n=t[e];if(!o.has(n.connectionName))continue;const s=i.get(n.connectionName)??0;i.set(n.connectionName,s+1),r.set(`${n.connectionName}_${s}`,e)}return r},h1=[.03,.1,.25],u1=t=\u003e{let e=0;for(const n of t){if(\"number\"!=typeof n.actual_clearance||!Number.isFinite(n.actual_clearance)||\"number\"!=typeof n.minimum_clearance||!Number.isFinite(n.minimum_clearance))return;if(e+=Math.max(0,n.minimum_clearance-n.actual_clearance),!Number.isFinite(e))return}return e},p1=({errors:t,errorsWithCenters:e,routeIndexByTraceId:n,padPositionById:o})=\u003e{const i=[];let r=0;for(const s of t){const t=\"pcb_via_trace_clearance_error\"===s.type,a=\"pcb_pad_trace_clearance_error\"===s.type;if(!t\u0026\u0026!a||\"string\"!=typeof s.pcb_trace_id||!n.has(s.pcb_trace_id)||\"number\"!=typeof s.actual_clearance||!Number.isFinite(s.actual_clearance)||\"number\"!=typeof s.minimum_clearance||!Number.isFinite(s.minimum_clearance))return;const c=a1(s);if(t\u0026\u0026c.length\u003c2||c.some(t=\u003e!n.has(t)))return;const l=e.find(t=\u003et.type===s.type\u0026\u0026t.pcb_trace_id===s.pcb_trace_id\u0026\u0026t.pcb_pad_id===s.pcb_pad_id\u0026\u0026t.pcb_via_id===s.pcb_via_id),d=a?\"string\"==typeof s.pcb_pad_id?o.get(s.pcb_pad_id):void 0:l?.center??s.center;if(!d||\"object\"!=typeof d)return;if(!(\"x\"in d\u0026\u0026\"y\"in d\u0026\u0026\"number\"==typeof d.x\u0026\u0026Number.isFinite(d.x)\u0026\u0026\"number\"==typeof d.y\u0026\u0026Number.isFinite(d.y)))return;const h={...s,pcb_trace_id:s.pcb_trace_id,actual_clearance:s.actual_clearance,minimum_clearance:s.minimum_clearance,center:{x:d.x,y:d.y}};if(t){if(\"string\"!=typeof s.pcb_via_id)return;i.push({...h,type:\"pcb_via_trace_clearance_error\",pcb_via_id:s.pcb_via_id,pcb_pad_id:void 0})}else{if(\"string\"!=typeof s.pcb_pad_id)return;i.push({...h,type:\"pcb_pad_trace_clearance_error\",pcb_pad_id:s.pcb_pad_id,pcb_via_id:void 0})}if(r+=Math.max(0,s.minimum_clearance-s.actual_clearance),!Number.isFinite(r))return}return{errors:i,deficit:r}},m1=(t,e)=\u003e{const n=[];for(let o=0;o\u003ct.route.length;o+=1){const i=t.route[o];if(\"via\"!==i.route_type){n.push(structuredClone(i));continue}const r=n[n.length-1],s=t.route[o+1],a=\"wire\"===r?.route_type?r.width:\"wire\"===s?.route_type?s.width:e,c=\"wire\"===s?.route_type?s.width:a;\"wire\"===r?.route_type\u0026\u0026r.x===i.x\u0026\u0026r.y===i.y\u0026\u0026r.layer===i.from_layer||n.push({route_type:\"wire\",x:i.x,y:i.y,layer:i.from_layer,width:a}),n.push(structuredClone(i)),\"wire\"===s?.route_type\u0026\u0026s.x===i.x\u0026\u0026s.y===i.y\u0026\u0026s.layer===i.to_layer||n.push({route_type:\"wire\",x:i.x,y:i.y,layer:i.to_layer,width:c})}return{...structuredClone(t),route:n}};function g1(t){const{srj:e,routes:n,routeIndex:o,start:i,end:r,bounds:s,traceThickness:a}=t;if(void 0!==t.maxNodes\u0026\u0026(!Number.isSafeInteger(t.maxNodes)||t.maxNodes\u003c1))throw new Error(\"repair04: maxNodes must be a positive safe integer\");if(t.stats\u0026\u0026(t.stats.nodesPopped=0,t.stats.completionReason=\"no-path\"),!1===t.allowLayerChanges\u0026\u0026i.z!==r.z)return null;const c=n[o],l=new Map,d=t=\u003e{const e=l.get(t);if(void 0===e||e===t)return t;const n=d(e);return l.set(t,n),n},h=t=\u003e{const e=t.filter(t=\u003eBoolean(t));if(!e.length)return;const n=d(e[0]);for(const t of e)l.set(d(t),n)};for(const t of e.connections){const e=t;h([e.name,e.rootConnectionName,e.netConnectionName,e.__netConnectionName,...e.mergedConnectionNames??[],...e.__rootConnectionNames??[],...e.pointsToConnect.flatMap(t=\u003e[t.pcb_port_id,t.pointId])])}for(const t of e.obstacles)h(t.connectedTo);for(const t of n)h([t.connectionName,t.rootConnectionName]);const u=d(c.connectionName),p=t=\u003e\"top\"===t?0:\"bottom\"===t?e.layerCount-1:Number(t.slice(5)),m=[s.minX,s.maxX,s.minY,s.maxY,i.x,i.y,r.x,r.y,a,c.viaDiameter,t.traceClearance,t.viaClearance,e.defaultObstacleMargin??0,e.minTraceToPadEdgeClearance??0,e.minViaEdgeToPadEdgeClearance??0].every(t=\u003eNumber.isFinite(t)\u0026\u0026Math.abs(t)\u003c=1e4),g=[],f=(t,e,n,o,i=!1)=\u003e{const r=o?Math.hypot(o.width,o.height)/2:n,s=o?Math.cos(o.rotation):1,a=o?Math.sin(o.rotation):0,c={minX:Math.min(t.x,e.x)-r,maxX:Math.max(t.x,e.x)+r,minY:Math.min(t.y,e.y)-r,maxY:Math.max(t.y,e.y)+r},l=o\u0026\u0026m?((t,e,n,o,i,r)=\u003e{if(t.x!==e.x||t.y!==e.y||!Number.isFinite(n.rotation)||n.width\u003c=0||n.height\u003c=0||![t.x,t.y,n.width,n.height,r.minX,r.maxX,r.minY,r.maxY].every(t=\u003eNumber.isFinite(t)\u0026\u0026Math.abs(t)\u003c=1e4))return r;const s=o*o+i*i;if(!Number.isFinite(s)||Math.abs(s-1)\u003e1e-12)return r;const a=n.width/2,c=n.height/2,l=(Math.abs(o)*a+Math.abs(i)*c)/s+1e-8,d=(Math.abs(i)*a+Math.abs(o)*c)/s+1e-8,h={minX:t.x-l,maxX:t.x+l,minY:t.y-d,maxY:t.y+d};return h.minX\u003cr.minX||h.maxX\u003er.maxX||h.minY\u003cr.minY||h.maxY\u003er.maxY?r:h})(t,e,o,s,a,c):c;g.push({a:t,b:e,radius:n,rect:o,viaOnly:i,rectCos:s,rectSin:a,rectBounds:o?{minX:-o.width/2,maxX:o.width/2,minY:-o.height/2,maxY:o.height/2}:void 0,visitedQuery:0,...l,minZ:Math.min(t.z,e.z),maxZ:Math.max(t.z,e.z)})};for(const t of e.obstacles){const e=t.connectedTo.some(t=\u003ed(t)===u),n=t.__zLayers??t.zLayers??t.layers.map(p);for(const o of n)f({...t.center,z:o},{...t.center,z:o},0,{width:t.width,height:t.height,rotation:(t.ccwRotationDegrees??0)*Math.PI/180},e)}for(const t of n)if(d(t.connectionName)!==u)for(let e=1;e\u003ct.route.length;e++){const n=t.route[e-1],o=t.route[e];\"through_obstacle\"!==n.toNextSegmentType\u0026\u0026f(n,o,n.z!==o.z?t.viaDiameter/2:Math.max(n.traceThickness??t.traceThickness,o.traceThickness??t.traceThickness)/2)}for(const t of e.traces??[]){if(d(t.connection_name)===u)continue;const n=m1(t,e.minTraceWidth);for(let t=1;t\u003cn.route.length;t++){const e=n.route[t-1],o=n.route[t];\"wire\"===e.route_type\u0026\u0026\"wire\"===o.route_type\u0026\u0026e.layer===o.layer\u0026\u0026f({x:e.x,y:e.y,z:p(e.layer)},{x:o.x,y:o.y,z:p(o.layer)},Math.max(e.width,o.width)/2),\"via\"===o.route_type\u0026\u0026f({x:o.x,y:o.y,z:p(o.from_layer)},{x:o.x,y:o.y,z:p(o.to_layer)},(o.via_diameter??c.viaDiameter)/2)}}const y=new Map,_=Math.max(c.viaDiameter,a)/2+Math.max(t.traceClearance,t.viaClearance,e.defaultObstacleMargin??0,e.minTraceToPadEdgeClearance??0,e.minViaEdgeToPadEdgeClearance??0)+1e-5;for(const t of g)for(let e=Math.floor(Math.max(t.minX,s.minX-_));e\u003c=Math.floor(Math.min(t.maxX,s.maxX+_));e++){let n=y.get(e);for(let o=Math.floor(Math.max(t.minY,s.minY-_));o\u003c=Math.floor(Math.min(t.maxY,s.maxY+_));o++){n||(n=new Map,y.set(e,n));const i=n.get(o);i?i.push(t):n.set(o,[t])}}let b=0;const x={x:0,y:0},v={x:0,y:0},S=(n,o)=\u003e{const i=n.z!==o.z,r=i?c.viaDiameter/2:a/2,s=Math.max(i?t.viaClearance:t.traceClearance,e.defaultObstacleMargin??0,i?e.minViaEdgeToPadEdgeClearance??0:e.minTraceToPadEdgeClearance??0),l=r+s+1e-5,d=++b,h=Math.min(n.x,o.x),u=Math.max(n.x,o.x),p=Math.min(n.y,o.y),m=Math.max(n.y,o.y),g=Math.min(n.z,o.z),f=Math.max(n.z,o.z);for(let e=Math.floor(h-l);e\u003c=Math.floor(u+l);e++){const a=y.get(e);if(a)for(let e=Math.floor(p-l);e\u003c=Math.floor(m+l);e++){const c=a.get(e);if(c)for(const e of c){if(e.viaOnly\u0026\u0026!i)continue;if(e.visitedQuery===d)continue;if(e.visitedQuery=d,e.maxZ\u003cg||e.minZ\u003ef)continue;const a=r+(e.rect?s:i\u0026\u0026e.minZ!==e.maxZ?t.viaClearance:t.traceClearance)+1e-5;if(u+a\u003ce.minX||h-a\u003ee.maxX||m+a\u003ce.minY||p-a\u003ee.maxY)continue;let c;if(e.rect?(x.x=(n.x-e.a.x)*e.rectCos+(n.y-e.a.y)*e.rectSin,x.y=-(n.x-e.a.x)*e.rectSin+(n.y-e.a.y)*e.rectCos,v.x=(o.x-e.a.x)*e.rectCos+(o.y-e.a.y)*e.rectSin,v.y=-(o.x-e.a.x)*e.rectSin+(o.y-e.a.y)*e.rectCos,c=ke(x,v,e.rectBounds)):c=Oe(n,o,e.a,e.b)-e.radius,c\u003ca)return!1}}}return!0};if(!S(i,i)||!S(r,r))return null;const I=t.gridSize??.1;if(!Number.isFinite(I)||I\u003c=0)throw new Error(\"repair04: clearance grid size must be positive and finite\");const C=Math.floor((s.maxX-s.minX)/I),P=Math.floor((s.maxY-s.minY)/I),M=t=\u003e({x:s.minX+(t%C+.5)*I,y:s.minY+(Math.floor(t/C)%P+.5)*I,z:Math.floor(t/(C*P)),traceThickness:a}),N=(t,e,n)=\u003e(n*P+e)*C+t,w=t=\u003eMath.hypot(t.x-r.x,t.y-r.y)+(t.z===r.z?0:1),T=[],R=t=\u003e{T.push(t);let e=T.length-1;for(;e\u003e0;){const n=Math.floor((e-1)/2);if(T[n].priority\u003c=t.priority)break;T[e]=T[n],e=n}T[e]=t},E=()=\u003e{const t=T[0],e=T.pop();if(T.length){let t=0;for(;2*t+1\u003cT.length;){let n=2*t+1;if(n+1\u003cT.length\u0026\u0026T[n+1].priority\u003cT[n].priority\u0026\u0026n++,T[n].priority\u003e=e.priority)break;T[t]=T[n],t=n}T[t]=e}return t},A=new Map,O=new Map,k=(z=i,N(Math.max(0,Math.min(C-1,Math.floor((z.x-s.minX)/I))),Math.max(0,Math.min(P-1,Math.floor((z.y-s.minY)/I))),z.z)),L=k%C,D=Math.floor(k/C)%P;var z;for(let t=-2;t\u003c=2;t++)for(let e=-2;e\u003c=2;e++){const n=L+t,o=D+e;if(n\u003c0||n\u003e=C||o\u003c0||o\u003e=P)continue;const r=N(n,o,i.z),s=M(r);if(!S(i,s))continue;const a=Math.hypot(s.x-i.x,s.y-i.y);A.set(r,a),O.set(r,-1),R({id:r,cost:a,priority:a+w(s)})}const F=C*P*e.layerCount,B=C\u003e0\u0026\u0026P\u003e0\u0026\u0026Number.isSafeInteger(e.layerCount)\u0026\u0026Number.isSafeInteger(F)\u0026\u0026F\u003e0\u0026\u0026Number.isSafeInteger(F*F-1)\u0026\u0026Number.isInteger(i.z)\u0026\u0026i.z\u003e=0\u0026\u0026i.z\u003ce.layerCount,j=new Map;let $=0;for(;T.length\u0026\u0026$\u003c(t.maxNodes??3e4);){const n=E();if($++,t.stats\u0026\u0026(t.stats.nodesPopped=$),n.cost!==A.get(n.id))continue;const o=M(n.id);if(o.z===r.z\u0026\u0026Math.hypot(o.x-r.x,o.y-r.y)\u003c3*I\u0026\u0026S(o,r)){const e=[r];for(let t=n.id;-1!==t;t=O.get(t))e.push(M(t));e.push(i);const o=e.reverse(),s=[i];for(let t=1;t\u003co.length;){let e=t;if(o[t].z===s.at(-1).z)for(let n=t+1;n\u003co.length\u0026\u0026o[n].z===o[t].z;n++)S(s.at(-1),o[n])\u0026\u0026(e=n);s.push(o[e]),t=e+1}return t.stats\u0026\u0026(t.stats.completionReason=\"found\"),s}const s=n.id%C,a=Math.floor(n.id/C)%P,c=[];for(let t=-1;t\u003c=1;t++)for(let e=-1;e\u003c=1;e++)0===t\u0026\u00260===e||s+t\u003c0||s+t\u003e=C||a+e\u003c0||a+e\u003e=P||c.push(N(s+t,a+e,o.z));if(!1!==t.allowLayerChanges)for(let t=0;t\u003ce.layerCount;t++)t!==o.z\u0026\u0026c.push(N(s,a,t));for(const t of c){const e=M(t),i=n.cost+(o.z===e.z?Math.hypot(o.x-e.x,o.y-e.y):1);if(i\u003e=(A.get(t)??1/0))continue;const r=Math.min(n.id,t),s=Math.max(n.id,t),a=B?r*F+s:`${r},${s}`;let c=j.get(a);void 0===c\u0026\u0026(c=S(o,e),j.set(a,c)),c\u0026\u0026(A.set(t,i),O.set(t,n.id),R({id:t,cost:i,priority:i+w(e)}))}}return t.stats\u0026\u0026(t.stats.completionReason=T.length?\"node-limit\":\"no-path\"),null}var f1=(t,e)=\u003e{if(!Number.isInteger(e)||e\u003c1)throw new Error(`Invalid board layer count: ${e}`);const n=Array.from({length:e},(t,n)=\u003e((t,e)=\u003e0===t?\"top\":t===e-1?\"bottom\":`inner${t}`)(n,e)),o=n.findIndex(e=\u003ee===t.from_layer),i=n.findIndex(e=\u003ee===t.to_layer);if(o\u003c0||i\u003c0)throw new Error(`Via span ${t.from_layer} -\u003e ${t.to_layer} is outside the board`);return n.slice(Math.min(o,i),Math.max(o,i)+1)},y1=.005,_1=1e-6,b1=(t,e)=\u003e({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),x1=t=\u003eb1({minX:Math.min(t.start.x,t.end.x),minY:Math.min(t.start.y,t.end.y),maxX:Math.max(t.start.x,t.end.x),maxY:Math.max(t.start.y,t.end.y)},t.width/2),v1=t=\u003e{const e=t.diameter/2;return{minX:t.x-e,minY:t.y-e,maxX:t.x+e,maxY:t.y+e}},S1=t=\u003e({minX:t.x-t.width/2,minY:t.y-t.height/2,maxX:t.x+t.width/2,maxY:t.y+t.height/2}),I1=(t,e)=\u003e`${t}:${e}`,C1=class{constructor(t){this.cellSize=t}cellSize;cells=new Map;insert(t,e){const n=Math.floor(e.minX/this.cellSize),o=Math.floor(e.maxX/this.cellSize),i=Math.floor(e.minY/this.cellSize),r=Math.floor(e.maxY/this.cellSize);for(let e=n;e\u003c=o;e+=1)for(let n=i;n\u003c=r;n+=1){const o=I1(e,n),i=this.cells.get(o);i?i.push(t):this.cells.set(o,[t])}}insertWithCellKeys(t,e){for(const n of e){const e=this.cells.get(n);e?e.push(t):this.cells.set(n,[t])}}getCellKeys(t){const e=Math.floor(t.minX/this.cellSize),n=Math.floor(t.maxX/this.cellSize),o=Math.floor(t.minY/this.cellSize),i=Math.floor(t.maxY/this.cellSize),r=[];for(let t=e;t\u003c=n;t+=1)for(let e=o;e\u003c=i;e+=1)r.push(I1(t,e));return r}queryWithCellKeys(t){const e=new Set;for(const n of t){const t=this.cells.get(n);if(t)for(const n of t)e.add(n)}return[...e]}queryWithCellKeysUsingOrder(t,e){const n=[];for(const o of t){const t=this.cells.get(o);if(t)for(const o of t)o.lastDynamicQueryOrder!==e\u0026\u0026(o.lastDynamicQueryOrder=e,n.push(o))}return n}query(t){const e=Math.floor(t.minX/this.cellSize),n=Math.floor(t.maxX/this.cellSize),o=Math.floor(t.minY/this.cellSize),i=Math.floor(t.maxY/this.cellSize),r=new Set;for(let t=e;t\u003c=n;t+=1)for(let e=o;e\u003c=i;e+=1){const n=this.cells.get(I1(t,e));if(n)for(const t of n)r.add(t)}return[...r]}},P1=(t,e)=\u003e{const n=ve(t.start,t.end,e.start,e.end);if(n)return n;const o=[{left:t.start,right:ze(t.start,e.start,e.end)},{left:t.end,right:ze(t.end,e.start,e.end)},{left:ze(e.start,t.start,t.end),right:e.start},{left:ze(e.end,t.start,t.end),right:e.end}];let i={left:t.start,right:e.start},r=Number.POSITIVE_INFINITY;for(const t of o){const e=Math.hypot(t.left.x-t.right.x,t.left.y-t.right.y);e\u003cr\u0026\u0026(i=t,r=e)}return{x:(i.left.x+i.right.x)/2,y:(i.left.y+i.right.y)/2}},M1=(t,e)=\u003e{const n=ze(e,t.start,t.end);return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}},N1=(t,e)=\u003e{const n=ze({x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},t.start,t.end),o=Math.max(e.minX,Math.min(e.maxX,n.x)),i=Math.max(e.minY,Math.min(e.maxY,n.y));return{x:(n.x+o)/2,y:(n.y+i)/2}},w1=t=\u003e{const e=new Set;for(const n of t.route)\"wire\"===n.route_type\u0026\u0026(n.start_pcb_port_id\u0026\u0026e.add(n.start_pcb_port_id),n.end_pcb_port_id\u0026\u0026e.add(n.end_pcb_port_id));return[...e]},T1=(t,e,n)=\u003en\u003c0?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,R1=class{constructor(t,e={}){if(this.srj=t,this.cacheImmutableTraceGeometry=e.cacheImmutableTraceGeometry??!1,this.useConservativeRectObstaclePrecheck=e.useConservativeRectObstaclePrecheck??!1,this.useTransientDynamicQueryMarkers=e.useTransientDynamicQueryMarkers??!1,this.traceClearance=e.traceClearance??.1,this.viaClearance=Math.max(e.viaClearance??.1,.1),this.viaToPadClearance=e.viaToPadClearance??this.srj.minViaEdgeToPadEdgeClearance??.1,this.connMap=e.connMap,this.includeTraceViaOwnerMetadata=e.includeTraceViaOwnerMetadata??!1,this.cellSize=e.spatialCellSize??this.getDefaultSpatialCellSize(),!Number.isFinite(this.traceClearance)||this.traceClearance\u003c0)throw new Error(\"traceClearance must be a non-negative finite number\");if(!Number.isFinite(this.viaClearance))throw new Error(\"viaClearance must be a finite number\");if(!Number.isFinite(this.viaToPadClearance)||this.viaToPadClearance\u003c0)throw new Error(\"viaToPadClearance must be a non-negative finite number\");if(!Number.isFinite(this.cellSize)||this.cellSize\u003c=0)throw new Error(\"spatialCellSize must be a positive finite number\");if(e.cacheStaticObstacleNetMembership\u0026\u0026this.connMap)throw new Error(\"cacheStaticObstacleNetMembership cannot be combined with connMap\");if(this.cacheImmutableTraceGeometry\u0026\u0026this.connMap)throw new Error(\"cacheImmutableTraceGeometry cannot be combined with connMap\");if(this.useTransientDynamicQueryMarkers\u0026\u0026!this.cacheImmutableTraceGeometry)throw new Error(\"useTransientDynamicQueryMarkers requires cacheImmutableTraceGeometry\");this.compileConnectionAliases(),this.obstacles=this.compileStaticObstacles(),e.cacheStaticObstacleNetMembership\u0026\u0026(this.staticObstacleNets=new Map(this.obstacles.map(t=\u003e[t,new Set(t.connectedTo.map(t=\u003ethis.resolveNetId(t)))]))),this.indexStaticObstacles()}srj;cacheImmutableTraceGeometry;useConservativeRectObstaclePrecheck;useTransientDynamicQueryMarkers;immutableTraceGeometry=new WeakMap;immutableDynamicCellKeys=new WeakMap;immutableDynamicQueryCellKeys=new WeakMap;immutableStaticCandidates=new WeakMap;immutableStaticClearance=new WeakMap;traceClearance;viaClearance;viaToPadClearance;cellSize;connMap;includeTraceViaOwnerMetadata;canonicalNetByAlias=new Map;connMapNetByCanonicalNet=new Map;obstacles;staticObstacleNets;obstacleIndexesByLayer=new Map;lastRunStats={traceCount:0,segmentCount:0,viaCount:0,obstacleCount:0,broadPhaseCandidateCount:0,exactCheckCount:0};getDefaultSpatialCellSize(){const t=Math.max(0,this.srj.bounds.maxX-this.srj.bounds.minX),e=Math.max(0,this.srj.bounds.maxY-this.srj.bounds.minY);return Math.max(.25,Math.max(t,e)/64,(this.srj.minViaDiameter??.3)+Math.max(this.traceClearance,this.viaToPadClearance))}compileConnectionAliases(){const t=new Map;for(const e of this.srj.connections){const n=e.netConnectionName??e.rootConnectionName??e.name,o=[e.name,e.rootConnectionName,e.netConnectionName,...e.mergedConnectionNames??[],...e.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])];for(const e of o){if(!e)continue;this.canonicalNetByAlias.set(e,n);const o=this.connMap?.getNetConnectedToId(e);if(!o)continue;let i=t.get(n);i||(i=new Set,t.set(n,i)),i.add(o)}this.canonicalNetByAlias.set(n,n)}for(const[e,n]of t)1===n.size\u0026\u0026this.connMapNetByCanonicalNet.set(e,n.values().next().value)}resolveNetId(t){const e=this.connMap?.getNetConnectedToId(t);if(e)return e;const n=this.canonicalNetByAlias.get(t);return n?this.connMapNetByCanonicalNet.get(n)??n:t}areConnected(t,e){return t===e||(!!this.connMap?.areIdsConnected(t,e)||this.resolveNetId(t)===this.resolveNetId(e))}compileStaticObstacles(){const t=[],e=new Set,n=new Set;for(const o of this.srj.obstacles){if(0===o.layers.length)continue;const i=o.connectedTo.find(t=\u003et.startsWith(\"pcb_smtpad_\")),r=o.connectedTo.find(t=\u003et.startsWith(\"pcb_plated_hole_\")),s=o.connectedTo.find(t=\u003et.startsWith(\"pcb_port_\"));if(!i\u0026\u0026!r\u0026\u0026!s)continue;const a=o.layers.length\u003e1,c=a?\"pcb_plated_hole\":\"pcb_smtpad\",l=a?r??`pcb_plated_hole_${o.center.x.toFixed(3)}_${o.center.y.toFixed(3)}`:i??`pcb_smtpad_${o.center.x.toFixed(3)}_${o.center.y.toFixed(3)}`,d=a?n:e;if(d.has(l))continue;d.add(l);const h=a\u0026\u0026Math.abs(o.width-o.height)\u003c.001;t.push({kind:\"obstacle\",obstacleType:c,obstacleId:l,connectedTo:o.connectedTo,x:o.center.x,y:o.center.y,width:o.width,height:o.height,...h?{radius:Math.max(o.width,o.height)/2}:{},layers:o.layers,...s?{pcbPortId:s}:{}})}return t}indexStaticObstacles(){for(const t of this.obstacles){const e=b1(S1(t),Math.max(this.traceClearance,this.viaToPadClearance));for(const n of t.layers){let o=this.obstacleIndexesByLayer.get(n);o||(o=new C1(this.cellSize),this.obstacleIndexesByLayer.set(n,o)),o.insert(t,e)}}}getImmutableTraceGeometry(t){const e=this.immutableTraceGeometry.get(t);if(e)return e;const n=this.resolveNetId(t.connection_name),o=w1(t),i=[];for(let e=0;e\u003ct.route.length-1;e++){const r=t.route[e],s=t.route[e+1];\"wire\"===r?.route_type\u0026\u0026\"wire\"===s?.route_type\u0026\u0026r.layer===s.layer\u0026\u0026(Math.abs(r.x-s.x)\u003c=_1\u0026\u0026Math.abs(r.y-s.y)\u003c=_1||i.push({geometryKey:{},kind:\"trace_segment\",traceId:t.pcb_trace_id,netId:n,start:{x:r.x,y:r.y},end:{x:s.x,y:s.y},width:E1(r,s),layer:r.layer,pcbPortIds:o}))}const r=[];for(const e of t.route)\"via\"===e.route_type\u0026\u0026r.push({locationKey:`${e.x},${e.y},${e.from_layer},${e.to_layer}`,point:e,geometryKey:{}});const s={segments:i,vias:r,traceId:t.pcb_trace_id,netId:n};return this.immutableTraceGeometry.set(t,s),s}collectImmutableDynamicGeometry(t){const e=[],n=[],o=new Set;for(const i of t){const t=this.getImmutableTraceGeometry(i);for(const n of t.segments)e.push({geometryKey:n.geometryKey,kind:\"trace_segment\",traceId:n.traceId,netId:n.netId,start:n.start,end:n.end,width:n.width,layer:n.layer,pcbPortIds:n.pcbPortIds,order:e.length});for(const e of t.vias){if(o.has(e.locationKey))continue;o.add(e.locationKey);const i=e.point,r=e.prepared??={geometryKey:e.geometryKey,kind:\"via\",traceId:t.traceId,netId:t.netId,x:i.x,y:i.y,diameter:i.via_diameter??this.srj.minViaDiameter??.3,layers:f1(i,this.srj.layerCount)};n.push({geometryKey:r.geometryKey,kind:\"via\",traceId:r.traceId,netId:r.netId,x:r.x,y:r.y,diameter:r.diameter,layers:r.layers,order:n.length,viaId:`via_${n.length}`})}}return{segments:e,vias:n}}collectDynamicGeometry(t){if(this.cacheImmutableTraceGeometry)return this.collectImmutableDynamicGeometry(t);const e=[],n=[],o=new Set;for(const i of t){const t=this.resolveNetId(i.connection_name),r=w1(i);for(let n=0;n\u003ci.route.length-1;n+=1){const o=i.route[n],s=i.route[n+1];\"wire\"===o?.route_type\u0026\u0026\"wire\"===s?.route_type\u0026\u0026o.layer===s.layer\u0026\u0026(Math.abs(o.x-s.x)\u003c=_1\u0026\u0026Math.abs(o.y-s.y)\u003c=_1||e.push({kind:\"trace_segment\",order:e.length,traceId:i.pcb_trace_id,netId:t,start:{x:o.x,y:o.y},end:{x:s.x,y:s.y},width:E1(o,s),layer:o.layer,pcbPortIds:r}))}for(const e of i.route){if(\"via\"!==e.route_type)continue;const r=`${e.x},${e.y},${e.from_layer},${e.to_layer}`;o.has(r)||(o.add(r),n.push({kind:\"via\",order:n.length,viaId:`via_${n.length}`,traceId:i.pcb_trace_id,netId:t,x:e.x,y:e.y,diameter:e.via_diameter??this.srj.minViaDiameter??.3,layers:f1(e,this.srj.layerCount)}))}}return{segments:e,vias:n}}getImmutableDynamicCellKeys(t,e){const n=t.geometryKey;if(!n)throw new Error(\"Immutable spatial cache requires private entity identities\");let o=this.immutableDynamicCellKeys.get(n);if(!o){const i=\"trace_segment\"===t.kind?x1(t):v1(t);o=e.getCellKeys(b1(i,this.traceClearance)),this.immutableDynamicCellKeys.set(n,o)}return o}getImmutableDynamicQueryCellKeys(t,e,n){const o=t.geometryKey;if(!o)throw new Error(\"Immutable spatial cache requires private entity identities\");let i=this.immutableDynamicQueryCellKeys.get(o);return i||(i=e.getCellKeys(n),this.immutableDynamicQueryCellKeys.set(o,i)),i}getStaticObstacleCandidates(t,e){const n=t.geometryKey;if(!n)throw new Error(\"Immutable spatial cache requires private entity identities\");let o=this.immutableStaticCandidates.get(n);o||(o=new Map,this.immutableStaticCandidates.set(n,o));let i=o.get(e);if(!i){const n=\"trace_segment\"===t.kind?x1(t):v1(t);i=this.obstacleIndexesByLayer.get(e)?.query(n)??[],o.set(e,i)}return i}buildImmutableDynamicIndexes(t,e){const n=new Map,o=(t,e)=\u003e{let o=n.get(t);o||(o=new C1(this.cellSize),n.set(t,o)),o.insertWithCellKeys(e,this.getImmutableDynamicCellKeys(e,o))};for(const e of t)o(e.layer,e);for(const t of e)for(const e of t.layers)o(e,t);return n}buildDynamicIndexes(t,e){if(this.cacheImmutableTraceGeometry)return this.buildImmutableDynamicIndexes(t,e);const n=new Map,o=(t,e,o)=\u003e{let i=n.get(t);i||(i=new C1(this.cellSize),n.set(t,i)),i.insert(e,b1(o,this.traceClearance))};for(const e of t)o(e.layer,e,x1(e));for(const t of e)for(const e of t.layers)o(e,t,v1(t));return n}obstacleSharesNet(t,e){return this.staticObstacleNets?this.staticObstacleNets.get(e).has(this.resolveNetId(t)):e.connectedTo.some(e=\u003ethis.areConnected(t,e))}checkTracePair(t,e){if(this.areConnected(t.netId,e.netId))return;this.lastRunStats.exactCheckCount+=1;const n=Oe(t.start,t.end,e.start,e.end)-t.width/2-e.width/2;if(n\u003ethis.traceClearance-y1)return;const o=`overlap_${t.traceId}_${e.traceId}`;return{type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:T1(t.traceId,`PCB trace ${e.traceId}`,n),pcb_trace_id:t.traceId,source_trace_id:\"\",pcb_trace_error_id:o,minimum_clearance:this.traceClearance,actual_clearance:n,pcb_component_ids:[],pcb_port_ids:[...new Set([...t.pcbPortIds,...e.pcbPortIds])],center:this.cacheImmutableTraceGeometry?{...P1(t,e)}:P1(t,e)}}checkTraceVia(t,e){if(this.areConnected(t.netId,e.netId))return;this.lastRunStats.exactCheckCount+=1;const n=De(t.start,t.end,{x:e.x,y:e.y,radius:e.diameter/2})-t.width/2;if(n\u003ethis.traceClearance-y1)return;const o=`overlap_${t.traceId}_${e.viaId}`;return{type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:T1(t.traceId,`pcb_via \"${e.viaId}\"`,n),pcb_trace_id:t.traceId,...this.includeTraceViaOwnerMetadata?{pcb_trace_ids:[t.traceId,e.traceId],pcb_via_id:e.viaId,pcb_via_ids:[e.viaId]}:{},source_trace_id:\"\",pcb_trace_error_id:o,minimum_clearance:this.traceClearance,actual_clearance:n,pcb_component_ids:[],pcb_port_ids:this.cacheImmutableTraceGeometry?[...t.pcbPortIds]:t.pcbPortIds,center:M1(t,e)}}checkTraceObstacle(t,e){if(this.obstacleSharesNet(t.netId,e))return;this.lastRunStats.exactCheckCount+=1;const n=S1(e);if(this.useConservativeRectObstaclePrecheck\u0026\u0026void 0===e.radius\u0026\u0026((t,e,n)=\u003e{const o=t.width/2+n-y1;return Math.max(e.minX-Math.max(t.start.x,t.end.x),Math.min(t.start.x,t.end.x)-e.maxX,e.minY-Math.max(t.start.y,t.end.y),Math.min(t.start.y,t.end.y)-e.maxY)\u003eo+1e-9\u0026\u0026e.minX\u003c=e.maxX\u0026\u0026e.minY\u003c=e.maxY\u0026\u0026Number.isFinite(o)\u0026\u0026Math.abs(t.start.x)\u003c=1e4\u0026\u0026Math.abs(t.start.y)\u003c=1e4\u0026\u0026Math.abs(t.end.x)\u003c=1e4\u0026\u0026Math.abs(t.end.y)\u003c=1e4\u0026\u0026Math.abs(e.minX)\u003c=1e4\u0026\u0026Math.abs(e.minY)\u003c=1e4\u0026\u0026Math.abs(e.maxX)\u003c=1e4\u0026\u0026Math.abs(e.maxY)\u003c=1e4})(t,n,this.traceClearance))return;const o=(void 0===e.radius?ke(t.start,t.end,n):De(t.start,t.end,{x:e.x,y:e.y,radius:e.radius}))-t.width/2;if(o+y1\u003e=this.traceClearance)return;const i=`overlap_${t.traceId}_${e.obstacleId}`;return{type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:T1(t.traceId,`${e.obstacleType} \"${e.obstacleId}\"`,o),pcb_trace_id:t.traceId,source_trace_id:\"\",pcb_trace_error_id:i,minimum_clearance:this.traceClearance,actual_clearance:o,pcb_component_ids:[],pcb_port_ids:[...new Set([...t.pcbPortIds,...e.pcbPortId?[e.pcbPortId]:[]])],center:void 0===e.radius?N1(t,n):M1(t,e)}}appendTraceObstacleErrors(t,e){const n=this.cacheImmutableTraceGeometry?t.geometryKey:void 0,o=n?this.immutableStaticClearance.get(n):void 0;if(o)return this.lastRunStats.broadPhaseCandidateCount+=o.broadPhaseCandidateCount,void(this.lastRunStats.exactCheckCount+=o.exactCheckCount);const i=this.cacheImmutableTraceGeometry?this.getStaticObstacleCandidates(t,t.layer):this.obstacleIndexesByLayer.get(t.layer)?.query(x1(t))??[],r=e.length,s=this.lastRunStats.exactCheckCount;for(const n of i){this.lastRunStats.broadPhaseCandidateCount+=1;const o=this.checkTraceObstacle(t,n);o\u0026\u0026e.push(o)}n\u0026\u0026e.length===r\u0026\u0026this.immutableStaticClearance.set(n,{broadPhaseCandidateCount:i.length,exactCheckCount:this.lastRunStats.exactCheckCount-s})}checkViaObstacle(t,e){if(this.obstacleSharesNet(t.netId,e))return;this.lastRunStats.exactCheckCount+=1;const n=S1(e),o=(void 0===e.radius?Math.hypot(Math.max(n.minX-t.x,0,t.x-n.maxX),Math.max(n.minY-t.y,0,t.y-n.maxY)):Math.hypot(t.x-e.x,t.y-e.y)-e.radius)-t.diameter/2;if(o+y1\u003e=this.viaToPadClearance)return;const i=`via_pad_clearance_${t.viaId}_${e.obstacleId}`,r={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return{type:\"pcb_pad_pad_clearance_error\",error_type:\"pcb_pad_pad_clearance_error\",pcb_pad_pad_clearance_error_id:i,message:`pcb_via \"${t.viaId}\" and ${e.obstacleType} \"${e.obstacleId}\" are too close (gap: ${o.toFixed(3)}mm)`,pcb_trace_id:t.traceId,pcb_pad_ids:[t.viaId,e.obstacleId],pcb_via_ids:[t.viaId],minimum_clearance:this.viaToPadClearance,actual_clearance:o,center:r}}checkViaPairs(t){if(t.length\u003c2)return[];const e=[],n=new C1(this.cellSize);for(const e of t)n.insert(e,b1(v1(e),this.viaClearance));for(const o of t)for(const t of n.query(v1(o))){if(this.lastRunStats.broadPhaseCandidateCount+=1,t.order\u003c=o.order)continue;this.lastRunStats.exactCheckCount+=1;const n=Math.hypot(o.x-t.x,o.y-t.y);if(n\u003c=_1)continue;const i=n-o.diameter/2-t.diameter/2;if(i+y1\u003e=this.viaClearance)continue;const r=this.areConnected(o.netId,t.netId),s=[o.viaId,t.viaId].sort().join(\"_\"),a={x:(o.x+t.x)/2,y:(o.y+t.y)/2};e.push({type:\"pcb_via_clearance_error\",error_type:\"pcb_via_clearance_error\",pcb_error_id:`${r?\"same_net\":\"different_net\"}_vias_close_${s}`,message:`Vias ${o.viaId} and ${t.viaId}${r?\"\":\" from different nets\"} are too close together (gap: ${i.toFixed(3)}mm)`,pcb_via_ids:[o.viaId,t.viaId],...this.includeTraceViaOwnerMetadata?{pcb_trace_ids:[o.traceId,t.traceId]}:{},pcb_via_pair_net_relation:r?\"same_net\":\"different_net\",minimum_clearance:this.viaClearance,actual_clearance:i,pcb_center:a,center:a})}return e}evaluate(t){return this.evaluateInternal(t,!0)}evaluateLegacy(t){return this.evaluateInternal(t,!1)}evaluateInternal(t,e){const{segments:n,vias:o}=this.collectDynamicGeometry(t),i=this.buildDynamicIndexes(n,o),r=[],s=[];this.lastRunStats={traceCount:t.length,segmentCount:n.length,viaCount:o.length,obstacleCount:this.obstacles.length,broadPhaseCandidateCount:0,exactCheckCount:0};for(const t of n){const e=x1(t),n=i.get(t.layer),o=n?this.cacheImmutableTraceGeometry?this.useTransientDynamicQueryMarkers?n.queryWithCellKeysUsingOrder(this.getImmutableDynamicQueryCellKeys(t,n,e),t.order):n.queryWithCellKeys(this.getImmutableDynamicQueryCellKeys(t,n,e)):n.query(e):[];for(const e of o){if(this.lastRunStats.broadPhaseCandidateCount+=1,\"trace_segment\"===e.kind\u0026\u0026e.order\u003c=t.order)continue;const n=\"trace_segment\"===e.kind?this.checkTracePair(t,e):this.checkTraceVia(t,e);n\u0026\u0026r.push(n)}this.appendTraceObstacleErrors(t,r)}const a=this.checkViaPairs(o);if(e)for(const t of o){const e=new Set;for(const n of t.layers){const o=this.cacheImmutableTraceGeometry?this.getStaticObstacleCandidates(t,n):this.obstacleIndexesByLayer.get(n)?.query(v1(t))??[];for(const n of o){if(e.has(n))continue;e.add(n),this.lastRunStats.broadPhaseCandidateCount+=1;const o=this.checkViaObstacle(t,n);o\u0026\u0026s.push(o)}}}const c=new Map;for(const t of r){const e=String(t.pcb_trace_error_id),n=c.get(e),o=Number(t.actual_clearance);if(!n){c.set(e,{...t,first_contact_center:t.center,first_contact_message:t.message,first_actual_clearance:o,worst_contact_center:t.center,worst_contact_message:t.message,worst_actual_clearance:o});continue}const i=Number(n.worst_actual_clearance);(o\u003ci||!Number.isFinite(i))\u0026\u0026(n.worst_contact_center=t.center,n.worst_contact_message=t.message,n.worst_actual_clearance=o)}const l=[...c.values()].map(t=\u003e({...t,center:\"object\"==typeof t.worst_contact_center?t.worst_contact_center:t.center,message:\"string\"==typeof t.worst_contact_message?t.worst_contact_message:t.message,actual_clearance:\"number\"==typeof t.worst_actual_clearance?t.worst_actual_clearance:t.actual_clearance}));l.push(...s),l.push(...a);const d=l.filter(t=\u003et.center);return{errors:l,errorsWithCenters:d,locationAwareErrors:d}}},E1=(t,e)=\u003et.width??e.width??.1,A1={Hz:{baseUnit:\"Hz\",variants:{MHz:1e6,kHz:1e3,Hz:1}},g:{baseUnit:\"g\",variants:{kg:1e3,g:1}},\"Ω\":{baseUnit:\"Ω\",variants:{\"mΩ\":.001,\"Ω\":1,\"kΩ\":1e3,\"KΩ\":1e3,kohm:1e3,\"MΩ\":1e6,\"GΩ\":1e9,\"TΩ\":1e12}},V:{baseUnit:\"V\",variants:{mV:.001,V:1,kV:1e3,KV:1e3,MV:1e6,GV:1e9,TV:1e12}},A:{baseUnit:\"A\",variants:{\"µA\":1e-6,mA:.001,ma:.001,A:1,kA:1e3,MA:1e6}},F:{baseUnit:\"F\",variants:{pF:1e-12,nF:1e-9,\"µF\":1e-6,uF:1e-6,mF:.001,F:1}},ml:{baseUnit:\"ml\",variants:{ml:1,mL:1,l:1e3,L:1e3}},deg:{baseUnit:\"deg\",variants:{rad:180/Math.PI}},ms:{baseUnit:\"ms\",variants:{fs:1e-12,ps:1e-9,ns:1e-6,us:.001,\"µs\":.001,ms:1,s:1e3}},mm:{baseUnit:\"mm\",variants:{nm:1e-6,\"µm\":.001,um:.001,mm:1,cm:10,dm:100,m:1e3,km:1e6,in:25.4,ft:304.8,IN:25.4,FT:304.8,yd:914.4,mi:1609344,mil:.0254}}},O1=new Set;for(const[t,e]of Object.entries(A1)){O1.add(t);for(const t of Object.keys(e.variants))O1.add(t)}var k1={tera:1e12,T:1e12,giga:1e9,G:1e9,mega:1e6,M:1e6,kilo:1e3,k:1e3,deci:.1,d:.1,centi:.01,c:.01,milli:.001,m:.001,micro:1e-6,u:1e-6,\"µ\":1e-6,nano:1e-9,n:1e-9,pico:1e-12,p:1e-12};function L1(t){if(null==t)return{parsedUnit:null,unitOfValue:null,value:null};if(\"string\"==typeof t\u0026\u0026t.match(/^-?[\\d\\.]+$/))return{value:Number.parseFloat(t),parsedUnit:null,unitOfValue:null};if(\"number\"==typeof t)return{value:t,parsedUnit:null,unitOfValue:null};if(\"object\"==typeof t\u0026\u0026\"x\"in t\u0026\u0026\"y\"in t){const{parsedUnit:e,unitOfValue:n}=L1(t.x),o=L1(t.x),i=L1(t.y);return null===o.value||null===i.value?{parsedUnit:null,unitOfValue:null,value:null}:{parsedUnit:e,unitOfValue:n,value:{x:o.value,y:i.value}}}const e=t.toString().split(\"\").reverse().join(\"\"),n=e.match(/[^\\d\\s]+/)?.[0];if(!n)throw new Error(`Could not determine unit: \"${t}\"`);const o=n.split(\"\").reverse().join(\"\"),i=t.slice(0,-o.length);if(o in k1\u0026\u0026!O1.has(o)){const t=k1[o];return{parsedUnit:null,unitOfValue:null,value:Number.parseFloat(i)*t}}const{baseUnit:r,conversionFactor:s}=function(t){for(const[e,n]of Object.entries(A1))if(t in n.variants)return{baseUnit:n.baseUnit,conversionFactor:n.variants[t]};return{baseUnit:t,conversionFactor:1}}(o);return{parsedUnit:o,unitOfValue:r,value:s*Number.parseFloat(i)}}var D1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),z1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value).transform(t=\u003eNumber.parseFloat(t.toPrecision(12))),F1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),B1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),j1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),$1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),Y1=j1,X1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),V1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),W1=V1,H1=k_.string().datetime(),G1=k_.string().or(k_.number()).transform(t=\u003e\"number\"==typeof t?t:t.endsWith(\"deg\")?Number.parseFloat(t.split(\"deg\")[0]):t.endsWith(\"rad\")?180*Number.parseFloat(t.split(\"rad\")[0])/Math.PI:Number.parseFloat(t)),U1=k_.number().or(k_.string().endsWith(\"mAh\")).transform(t=\u003e{if(\"string\"==typeof t){const e=t.replace(\"mAh\",\"\"),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error(\"Invalid capacity\");return n}return t}).describe(\"Battery capacity in mAh\"),Z1=k_.object({x:Y1,y:Y1}),q1=k_.object({x:Y1,y:Y1,z:Y1}),J1=k_.object({width:k_.number(),height:k_.number()}),K1=t=\u003ek_.string().optional().default(()=\u003e`${t}_${(t=\u003e{const e=\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";return Array.from({length:t},()=\u003ee[Math.floor(62*Math.random())]).join(\"\")})(10)}`),Q1=k_.enum([\"top_left\",\"top_center\",\"top_right\",\"center_left\",\"center\",\"center_right\",\"bottom_left\",\"bottom_center\",\"bottom_right\"]),t2=(k_.enum([\"top_silkscreen\",\"bottom_silkscreen\",\"top_copper\",\"bottom_copper\",\"top_soldermask\",\"bottom_soldermask\",\"top_fabrication_note\",\"bottom_fabrication_note\",\"top_user_note\",\"bottom_user_note\",\"top_courtyard\",\"bottom_courtyard\",\"inner1_copper\",\"inner2_copper\",\"inner3_copper\",\"inner4_copper\",\"inner5_copper\",\"inner6_copper\",\"edge_cuts\",\"drill\"]),k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()})),e2=Z1.extend({rotation:G1.optional()}),n2=k_.object({size:Z1.optional(),thickness:Y1.optional()}),o2=k_.object({font:n2.optional()}),i2=k_.object({value:k_.string(),at:e2.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:o2.optional()}),r2=k_.object({Reference:i2.optional(),Value:i2.optional(),Datasheet:i2.optional(),Description:i2.optional()}),s2=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),a2=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:e2.optional(),size:Z1.optional(),drill:Y1.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),c2=k_.object({path:k_.string(),offset:q1.optional(),scale:q1.optional(),rotate:q1.optional()}),l2=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:r2.optional(),attributes:s2.optional(),pads:k_.array(a2).optional(),embeddedFonts:k_.boolean().optional(),model:c2.optional()}),d2=k_.object({hide:k_.boolean().optional()}),h2=k_.object({offset:Y1.optional(),hide:k_.boolean().optional()}),u2=k_.object({font:n2.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),p2=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:e2.optional(),effects:u2.optional()}),m2=k_.object({Reference:p2.optional(),Value:p2.optional(),Footprint:p2.optional(),Datasheet:p2.optional(),Description:p2.optional(),ki_keywords:p2.optional(),ki_fp_filters:p2.optional()}),g2=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:d2.optional(),pinNames:h2.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:m2.optional(),embeddedFonts:k_.boolean().optional()}),f2=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),y2=k_.enum([\"jlcpcb\",\"macrofab\",\"pcbway\",\"digikey\",\"mouser\",\"lcsc\"]),_2=k_.object({type:k_.literal(\"source_component\"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(y2,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),b2=_2.extend({ftype:k_.literal(\"simple_capacitor\"),capacitance:z1,max_voltage_rating:B1.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:Y1.optional()}),x2=_2.extend({ftype:k_.literal(\"simple_resistor\"),resistance:D1,display_resistance:k_.string().optional()}),v2=_2.extend({ftype:k_.literal(\"simple_diode\")}),S2=_2.extend({ftype:k_.literal(\"simple_fiducial\")}),I2=v2.extend({ftype:k_.literal(\"simple_led\"),color:k_.string().optional(),wavelength:k_.string().optional()}),C2=_2.extend({ftype:k_.literal(\"simple_ground\")}),P2=_2.extend({ftype:k_.literal(\"simple_chip\")}),M2=_2.extend({ftype:k_.literal(\"simple_power_source\"),voltage:B1}),N2=_2.extend({ftype:k_.literal(\"simple_current_source\"),current:X1,frequency:$1.optional(),peak_to_peak_current:X1.optional(),wave_shape:k_.enum([\"sine\",\"square\",\"triangle\",\"sawtooth\",\"dc\"]).optional().default(\"dc\"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),w2=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),T2=_2.extend({ftype:k_.literal(\"simple_fuse\"),current_rating_amps:k_.number().describe(\"Nominal current in amps the fuse is rated for\"),voltage_rating_volts:k_.number().describe(\"Voltage rating in volts, e.g. ±5V would be 5\")}),R2=_2.extend({ftype:k_.literal(\"simple_battery\"),capacity:U1}),E2=_2.extend({ftype:k_.literal(\"simple_inductor\"),inductance:F1,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),A2=_2.extend({ftype:k_.literal(\"simple_push_button\")}),O2=_2.extend({ftype:k_.literal(\"simple_potentiometer\"),max_resistance:D1,display_max_resistance:k_.string().optional()}),k2=_2.extend({ftype:k_.literal(\"simple_crystal\"),frequency:k_.number().describe(\"Frequency in Hz\"),load_capacitance:k_.number().optional().describe(\"Load capacitance in pF\"),pin_variant:k_.enum([\"two_pin\",\"four_pin\"]).optional()}),L2=_2.extend({ftype:k_.literal(\"simple_pin_header\"),pin_count:k_.number(),gender:k_.enum([\"male\",\"female\"]).optional().default(\"male\")}),D2=_2.extend({ftype:k_.literal(\"simple_connector\"),standard:k_.enum([\"usb_c\",\"m2\"]).optional()}),z2=_2.extend({ftype:k_.literal(\"simple_pinout\")}),F2=_2.extend({ftype:k_.literal(\"simple_resonator\"),load_capacitance:z1,equivalent_series_resistance:D1.optional(),frequency:$1}),B2=_2.extend({ftype:k_.literal(\"simple_transistor\"),transistor_type:k_.enum([\"npn\",\"pnp\"])}),j2=_2.extend({ftype:k_.literal(\"simple_test_point\"),footprint_variant:k_.enum([\"pad\",\"through_hole\"]).optional(),pad_shape:k_.enum([\"rect\",\"circle\"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),$2=_2.extend({ftype:k_.literal(\"simple_mosfet\"),channel_type:k_.enum([\"n\",\"p\"]),mosfet_mode:k_.enum([\"enhancement\",\"depletion\"])}),Y2=_2.extend({ftype:k_.literal(\"simple_op_amp\")}),X2=_2.extend({ftype:k_.literal(\"simple_switch\")}),V2=k_.object({type:k_.literal(\"source_project_metadata\"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),created_at:H1.optional()}),W2=f2.extend({type:k_.literal(\"source_missing_property_error\"),source_missing_property_error_id:K1(\"source_missing_property_error\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_missing_property_error\").default(\"source_missing_property_error\")}).describe(\"The source code is missing a property\"),H2=f2.extend({type:k_.literal(\"source_failed_to_create_component_error\"),source_failed_to_create_component_error_id:K1(\"source_failed_to_create_component_error\"),error_type:k_.literal(\"source_failed_to_create_component_error\").default(\"source_failed_to_create_component_error\"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe(\"Error emitted when a component fails to be constructed\"),G2=f2.extend({type:k_.literal(\"source_invalid_component_property_error\"),source_invalid_component_property_error_id:K1(\"source_invalid_component_property_error\"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_invalid_component_property_error\").default(\"source_invalid_component_property_error\")}).describe(\"The source component property is invalid\"),U2=f2.extend({type:k_.literal(\"source_trace_not_connected_error\"),source_trace_not_connected_error_id:K1(\"source_trace_not_connected_error\"),error_type:k_.literal(\"source_trace_not_connected_error\").default(\"source_trace_not_connected_error\"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe(\"Occurs when a source trace selector does not match any ports\"),Z2=k_.object({type:k_.literal(\"source_property_ignored_warning\"),source_property_ignored_warning_id:K1(\"source_property_ignored_warning\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_property_ignored_warning\").default(\"source_property_ignored_warning\"),message:k_.string()}).describe(\"The source property was ignored\"),q2=k_.object({type:k_.literal(\"source_pin_missing_trace_warning\"),source_pin_missing_trace_warning_id:K1(\"source_pin_missing_trace_warning\"),warning_type:k_.literal(\"source_pin_missing_trace_warning\").default(\"source_pin_missing_trace_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component pin is missing a trace connection\"),J2=k_.object({type:k_.literal(\"source_missing_manufacturer_part_number_warning\"),source_missing_manufacturer_part_number_warning_id:K1(\"source_missing_manufacturer_part_number_warning\"),warning_type:k_.literal(\"source_missing_manufacturer_part_number_warning\").default(\"source_missing_manufacturer_part_number_warning\"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a standard connector is missing manufacturer part number\"),K2=_2.extend({ftype:k_.literal(\"simple_voltage_probe\")}),Q2=_2.extend({ftype:k_.literal(\"interconnect\")}),t5=f2.extend({type:k_.literal(\"source_i2c_misconfigured_error\"),source_i2c_misconfigured_error_id:K1(\"source_i2c_misconfigured_error\"),error_type:k_.literal(\"source_i2c_misconfigured_error\").default(\"source_i2c_misconfigured_error\"),source_port_ids:k_.array(k_.string())}).describe(\"Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net\"),e5=_2.extend({ftype:k_.literal(\"simple_voltage_source\"),voltage:B1,frequency:$1.optional(),peak_to_peak_voltage:B1.optional(),wave_shape:k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]).optional(),phase:G1.optional(),duty_cycle:k_.number().optional().describe(\"Duty cycle as a fraction (0 to 1)\")}),n5=k_.union([x2,b2,v2,S2,I2,C2,P2,M2,N2,R2,E2,A2,O2,k2,L2,D2,z2,F2,X2,B2,j2,$2,Y2,T2,K2,Q2,e5,V2,W2,G2,H2,U2,Z2,q2,J2,t5]),o5=k_.object({type:k_.literal(\"source_port\"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(w2),i5=k_.object({type:k_.literal(\"source_component_internal_connection\"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),r5=k_.object({type:k_.literal(\"source_trace\"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),s5=k_.object({type:k_.literal(\"source_group\"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),a5=k_.object({type:k_.literal(\"source_net\"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),c5=k_.object({type:k_.literal(\"source_board\"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe(\"Defines a board in the source domain\"),l5=f2.extend({type:k_.literal(\"source_ambiguous_port_reference\"),source_ambiguous_port_reference_id:K1(\"source_ambiguous_port_reference\"),error_type:k_.literal(\"source_ambiguous_port_reference\").default(\"source_ambiguous_port_reference\"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous\"),d5=k_.object({type:k_.literal(\"source_pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane in the source domain\"),h5=k_.enum([\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\"]),u5=h5.or(k_.object({name:h5})).transform(t=\u003e\"string\"==typeof t?t:t.name),p5=k_.enum([\"top\",\"bottom\"]),m5=k_.object({type:k_.literal(\"source_manually_placed_via\"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe(\"Defines a via that is manually placed in the source domain\"),g5=k_.object({type:k_.literal(\"source_no_power_pin_defined_warning\"),source_no_power_pin_defined_warning_id:K1(\"source_no_power_pin_defined_warning\"),warning_type:k_.literal(\"source_no_power_pin_defined_warning\").default(\"source_no_power_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports with requires_power=true\"),f5=k_.object({type:k_.literal(\"source_no_ground_pin_defined_warning\"),source_no_ground_pin_defined_warning_id:K1(\"source_no_ground_pin_defined_warning\"),warning_type:k_.literal(\"source_no_ground_pin_defined_warning\").default(\"source_no_ground_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports marked as ground pins\"),y5=k_.object({type:k_.literal(\"source_component_pins_underspecified_warning\"),source_component_pins_underspecified_warning_id:K1(\"source_component_pins_underspecified_warning\"),warning_type:k_.literal(\"source_component_pins_underspecified_warning\").default(\"source_component_pins_underspecified_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when all ports on a source component are underspecified\"),_5=f2.extend({type:k_.literal(\"source_pin_must_be_connected_error\"),source_pin_must_be_connected_error_id:K1(\"source_pin_must_be_connected_error\"),error_type:k_.literal(\"source_pin_must_be_connected_error\").default(\"source_pin_must_be_connected_error\"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pin with mustBeConnected attribute is not connected to any trace\"),b5=f2.extend({type:k_.literal(\"unknown_error_finding_part\"),unknown_error_finding_part_id:K1(\"unknown_error_finding_part\"),error_type:k_.literal(\"unknown_error_finding_part\").default(\"unknown_error_finding_part\"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when an unexpected error occurs while finding a part\"),x5=k_.object({type:k_.literal(\"schematic_box\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:Y1,height:Y1,is_dashed:k_.boolean().default(!1),x:Y1,y:Y1,subcircuit_id:k_.string().optional()}).describe(\"Draws a box on the schematic\"),v5=k_.object({type:k_.literal(\"schematic_path\"),schematic_path_id:K1(\"schematic_path\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),stroke_width:Y1.nullable().optional(),stroke_color:k_.string().optional(),points:k_.array(Z1),subcircuit_id:k_.string().optional()}),S5=k_.record(k_.object({left_margin:j1.optional(),right_margin:j1.optional(),top_margin:j1.optional(),bottom_margin:j1.optional()})),I5=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),C5=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional()}),P5=k_.union([I5,C5]),M5=k_.object({type:k_.literal(\"schematic_component\"),size:J1,center:Z1,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_symbol_id:k_.string().optional(),pin_spacing:j1.optional(),pin_styles:S5.optional(),box_width:j1.optional(),symbol_name:k_.string().optional(),port_arrangement:P5.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),N5=k_.object({kicad_symbol:g2.optional()}).catchall(k_.unknown()),w5=k_.object({type:k_.literal(\"schematic_symbol\"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:N5.optional()}).describe(\"Defines a named schematic symbol that can be referenced by components.\"),T5=k_.object({type:k_.literal(\"schematic_line\"),schematic_line_id:K1(\"schematic_line\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:Y1,y1:Y1,x2:Y1,y2:Y1,stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled line on the schematic\"),R5=k_.object({type:k_.literal(\"schematic_rect\"),schematic_rect_id:K1(\"schematic_rect\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,width:Y1,height:Y1,rotation:G1.default(0),stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled rectangle on the schematic\"),E5=k_.object({type:k_.literal(\"schematic_circle\"),schematic_circle_id:K1(\"schematic_circle\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,radius:Y1,stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled circle on the schematic\"),A5=k_.object({type:k_.literal(\"schematic_arc\"),schematic_arc_id:K1(\"schematic_arc\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,radius:Y1,start_angle_degrees:G1,end_angle_degrees:G1,direction:k_.enum([\"clockwise\",\"counterclockwise\"]).default(\"counterclockwise\"),stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled arc on the schematic\"),O5=k_.object({type:k_.literal(\"schematic_trace\"),schematic_trace_id:k_.string(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),k5=k_.enum([\"center\",\"left\",\"right\",\"top\",\"bottom\"]),L5=k_.object({type:k_.literal(\"schematic_text\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:Y1,y:Y1}),rotation:k_.number().default(0),anchor:k_.union([k5.describe(\"legacy\"),Q1]).default(\"center\"),color:k_.string().default(\"#000000\"),subcircuit_id:k_.string().optional()}),D5=k_.object({type:k_.literal(\"schematic_port\"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_component_id:k_.string().optional(),center:Z1,facing_direction:k_.enum([\"up\",\"down\",\"left\",\"right\"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe(\"Defines a port on a schematic component\"),z5=k_.object({type:k_.literal(\"schematic_net_label\"),schematic_net_label_id:K1(\"schematic_net_label\"),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:Z1,anchor_position:Z1.optional(),anchor_side:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),F5=f2.extend({type:k_.literal(\"schematic_error\"),schematic_error_id:k_.string(),error_type:k_.literal(\"schematic_port_not_found\").default(\"schematic_port_not_found\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic error on the schematic\"),B5=f2.extend({type:k_.literal(\"schematic_layout_error\"),schematic_layout_error_id:K1(\"schematic_layout_error\"),error_type:k_.literal(\"schematic_layout_error\").default(\"schematic_layout_error\"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when schematic layout fails for a group\"),j5=k_.object({type:k_.literal(\"schematic_debug_object\"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),$5=j5.extend({shape:k_.literal(\"rect\"),center:Z1,size:J1}),Y5=j5.extend({shape:k_.literal(\"line\"),start:Z1,end:Z1}),X5=j5.extend({shape:k_.literal(\"point\"),center:Z1}),V5=k_.discriminatedUnion(\"shape\",[$5,Y5,X5]),W5=k_.object({type:k_.literal(\"schematic_voltage_probe\"),schematic_voltage_probe_id:k_.string(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:Z1,schematic_trace_id:k_.string(),voltage:B1.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:Q1.optional()}).describe(\"Defines a voltage probe measurement point on a schematic trace\"),H5=k_.object({type:k_.literal(\"schematic_manual_edit_conflict_warning\"),schematic_manual_edit_conflict_warning_id:K1(\"schematic_manual_edit_conflict_warning\"),warning_type:k_.literal(\"schematic_manual_edit_conflict_warning\").default(\"schematic_manual_edit_conflict_warning\"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit schX/schY coordinates\"),G5=k_.object({type:k_.literal(\"schematic_group\"),schematic_group_id:K1(\"schematic_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:j1,height:j1,center:Z1,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe(\"Defines a group of components on the schematic\"),U5=k_.object({type:k_.literal(\"schematic_table\"),schematic_table_id:K1(\"schematic_table\"),anchor_position:Z1,column_widths:k_.array(Y1),row_heights:k_.array(Y1),cell_padding:Y1.optional(),border_width:Y1.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:Q1.optional()}).describe(\"Defines a table on the schematic\"),Z5=k_.object({type:k_.literal(\"schematic_table_cell\"),schematic_table_cell_id:K1(\"schematic_table_cell\"),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:Z1,width:Y1,height:Y1,horizontal_align:k_.enum([\"left\",\"center\",\"right\"]).optional(),vertical_align:k_.enum([\"top\",\"middle\",\"bottom\"]).optional(),font_size:Y1.optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a cell within a schematic_table\"),q5=k_.object({type:k_.literal(\"schematic_sheet\"),schematic_sheet_id:K1(\"schematic_sheet\"),name:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic sheet or page that components can be placed on\"),J5=k_.object({x:Y1,y:Y1,bulge:k_.number().optional()}),K5=k_.object({vertices:k_.array(J5)}),Q5=k_.object({outer_ring:K5,inner_rings:k_.array(K5).default([])}),t3=k_.object({x:Y1,y:Y1,via:k_.boolean().optional(),via_to_layer:u5.optional()}),e3=(k_.array(t3),k_.object({x:Y1,y:Y1,via:k_.boolean().optional(),to_layer:u5.optional(),trace_width:Y1.optional()})),n3=k_.object({min_trace_width:j1.optional(),min_board_edge_clearance:j1.optional(),min_via_hole_edge_to_via_hole_edge_clearance:j1.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:j1.optional(),min_trace_to_pad_edge_clearance:j1.optional(),min_pad_edge_to_pad_edge_clearance:j1.optional(),min_same_net_trace_edge_to_trace_edge_clearance:j1.optional(),min_different_net_trace_edge_to_trace_edge_clearance:j1.optional(),min_via_hole_diameter:j1.optional(),min_via_pad_diameter:j1.optional()}),o3=k_.object({type:k_.literal(\"pcb_component\"),pcb_component_id:K1(\"pcb_component\"),source_component_id:k_.string(),center:Z1,layer:u5,rotation:G1,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this part, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this part, usually corresponding with how the user specified it\"),width:j1,height:j1,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"relative_to_another_component\",\"none\"]).optional(),anchor_position:Z1.optional(),anchor_alignment:Q1.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:Z1.optional(),insertion_direction:k_.enum([\"from_above\",\"from_left\",\"from_right\",\"from_front\",\"from_back\"]).optional(),metadata:k_.object({kicad_footprint:l2.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe(\"Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath\")}).describe(\"Defines a component on the PCB\"),i3=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),hole_diameter:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),r3=(i3.describe(\"Defines a circular hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),s3=(r3.describe(\"Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"square\"]),hole_diameter:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),a3=(s3.describe(\"Defines a circular or square hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"oval\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),c3=(a3.describe(\"Defines an oval hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),l3=(c3.describe(\"Defines a pill-shaped hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,ccw_rotation:G1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),d3=(l3.describe(\"Defines a rotated pill-shaped hole on the PCB\"),s3.or(a3).or(c3).or(l3).or(i3).or(r3)),h3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),u3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.enum([\"oval\",\"pill\"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,ccw_rotation:G1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),p3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circular_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),pad_shape:k_.literal(\"rect\"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:G1.optional()}),m3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),g3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"rotated_pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:G1,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:G1,hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),f3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"hole_with_polygon_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"oval\",\"pill\",\"rotated_pill\"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:Y1,y:Y1})).min(3),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),ccw_rotation:G1.optional()}),y3=k_.union([h3,u3,p3,m3,g3,f3]),_3=k_.object({type:k_.literal(\"pcb_port\"),pcb_port_id:K1(\"pcb_port\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:Y1,y:Y1,layers:k_.array(u5),is_board_pinout:k_.boolean().optional()}).describe(\"Defines a port on the PCB\"),b3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"circle\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,radius:k_.number(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),x3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rect\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),v3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_rect\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:G1,layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),S3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"pill\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),I3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_pill\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:G1,layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),C3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"polygon\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(Z1),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),P3=k_.discriminatedUnion(\"shape\",[b3,x3,v3,I3,S3,C3]).describe(\"Defines an SMT pad on the PCB\"),M3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"circle\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,radius:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),N3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rect\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),w3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"pill\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),T3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rotated_rect\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),ccw_rotation:Y1,layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),R3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"oval\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),E3=k_.union([M3,N3,w3,T3,R3]).describe(\"Defines solderpaste on the PCB\"),A3=k_.object({type:k_.literal(\"pcb_text\"),pcb_text_id:K1(\"pcb_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:Z1,layer:u5,width:j1,height:j1,lines:k_.number(),align:k_.enum([\"bottom-left\"])}).describe(\"Defines text on the PCB\"),O3=k_.object({route_type:k_.literal(\"wire\"),x:Y1,y:Y1,width:Y1,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:u5}),k3=k_.object({route_type:k_.literal(\"via\"),x:Y1,y:Y1,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:Y1.optional(),outer_diameter:Y1.optional(),from_layer:u5,to_layer:u5}),L3=k_.union([O3,k3]),D3=k_.object({type:k_.literal(\"pcb_trace\"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:K1(\"pcb_trace\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum([\"constant\",\"interpolated\"]).default(\"constant\").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(L3)}).describe(\"Defines a trace on the PCB\"),z3=k_.object({type:k_.literal(\"pcb_trace_warning\"),pcb_trace_warning_id:K1(\"pcb_trace_warning\"),warning_type:k_.literal(\"pcb_trace_warning\").default(\"pcb_trace_warning\"),message:k_.string(),center:Z1.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace warning on the PCB\"),F3=f2.extend({type:k_.literal(\"pcb_trace_error\"),pcb_trace_error_id:K1(\"pcb_trace_error\"),error_type:k_.literal(\"pcb_trace_error\").default(\"pcb_trace_error\"),center:Z1.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB\"),B3=f2.extend({type:k_.literal(\"pcb_trace_missing_error\"),pcb_trace_missing_error_id:K1(\"pcb_trace_missing_error\"),error_type:k_.literal(\"pcb_trace_missing_error\").default(\"pcb_trace_missing_error\"),center:Z1.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a source trace has no corresponding PCB trace\"),j3=f2.extend({type:k_.literal(\"pcb_port_not_matched_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_port_not_matched_error\").default(\"pcb_port_not_matched_error\"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB where a port is not matched\"),$3=f2.extend({type:k_.literal(\"pcb_port_not_connected_error\"),pcb_port_not_connected_error_id:K1(\"pcb_port_not_connected_error\"),error_type:k_.literal(\"pcb_port_not_connected_error\").default(\"pcb_port_not_connected_error\"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a pcb port is not connected to any trace\"),Y3=k_.object({type:k_.literal(\"pcb_net\"),pcb_net_id:K1(\"pcb_net\"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe(\"Defines a net on the PCB\"),X3=k_.object({type:k_.literal(\"pcb_via\"),pcb_via_id:K1(\"pcb_via\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:Y1,y:Y1,outer_diameter:Y1.default(\"0.6mm\"),hole_diameter:Y1.default(\"0.25mm\"),from_layer:u5.optional(),to_layer:u5.optional(),layers:k_.array(u5),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe(\"Defines a via on the PCB\"),V3=k_.object({type:k_.literal(\"pcb_board\"),pcb_board_id:K1(\"pcb_board\"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:j1.optional(),height:j1.optional(),center:Z1,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this board, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this board, usually corresponding with how the user specified it\"),thickness:j1.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(Z1).optional(),shape:k_.enum([\"rect\",\"polygon\"]).optional(),material:k_.enum([\"fr4\",\"fr1\"]).default(\"fr4\"),anchor_position:Z1.optional(),anchor_alignment:Q1.optional(),position_mode:k_.enum([\"relative_to_panel_anchor\",\"none\"]).optional()}).merge(n3).describe(\"Defines the board outline of the PCB\"),W3=k_.object({type:k_.literal(\"pcb_panel\"),pcb_panel_id:K1(\"pcb_panel\"),width:j1,height:j1,center:Z1,thickness:j1.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe(\"Defines a PCB panel that can contain multiple boards\"),H3=f2.extend({type:k_.literal(\"pcb_placement_error\"),pcb_placement_error_id:K1(\"pcb_placement_error\"),error_type:k_.literal(\"pcb_placement_error\").default(\"pcb_placement_error\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a placement error on the PCB\"),G3=f2.extend({type:k_.literal(\"pcb_panelization_placement_error\"),pcb_panelization_placement_error_id:K1(\"pcb_panelization_placement_error\"),error_type:k_.literal(\"pcb_panelization_placement_error\").default(\"pcb_panelization_placement_error\"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a panelization placement error on the PCB\"),U3=k_.object({type:k_.literal(\"pcb_trace_hint\"),pcb_trace_hint_id:K1(\"pcb_trace_hint\"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(e3),subcircuit_id:k_.string().optional()}).describe(\"A hint that can be used during generation of a PCB trace\"),Z3=k_.object({type:k_.literal(\"pcb_silkscreen_line\"),pcb_silkscreen_line_id:K1(\"pcb_silkscreen_line\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:Y1.default(\"0.1mm\"),x1:Y1,y1:Y1,x2:Y1,y2:Y1,layer:p5}).describe(\"Defines a silkscreen line on the PCB\"),q3=k_.object({type:k_.literal(\"pcb_silkscreen_path\"),pcb_silkscreen_path_id:K1(\"pcb_silkscreen_path\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,route:k_.array(Z1),stroke_width:j1}).describe(\"Defines a silkscreen path on the PCB\"),J3=k_.object({type:k_.literal(\"pcb_silkscreen_text\"),pcb_silkscreen_text_id:K1(\"pcb_silkscreen_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:j1,top:j1,bottom:j1,right:j1}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:u5,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:Q1.default(\"center\")}).describe(\"Defines silkscreen text on the PCB\"),K3=k_.object({type:k_.literal(\"pcb_copper_text\"),pcb_copper_text_id:K1(\"pcb_copper_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:j1,top:j1,bottom:j1,right:j1}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:u5,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:Q1.default(\"center\")}).describe(\"Defines copper text on the PCB\"),Q3=k_.object({type:k_.literal(\"pcb_silkscreen_rect\"),pcb_silkscreen_rect_id:K1(\"pcb_silkscreen_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:u5,stroke_width:j1.default(\"1mm\"),corner_radius:j1.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen rect on the PCB\"),t4=k_.object({type:k_.literal(\"pcb_silkscreen_circle\"),pcb_silkscreen_circle_id:K1(\"pcb_silkscreen_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:j1,layer:p5,stroke_width:j1.default(\"1mm\"),is_filled:k_.boolean().optional()}).describe(\"Defines a silkscreen circle on the PCB\"),e4=k_.object({type:k_.literal(\"pcb_silkscreen_oval\"),pcb_silkscreen_oval_id:K1(\"pcb_silkscreen_oval\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius_x:Y1,radius_y:Y1,layer:p5,ccw_rotation:G1.optional()}).describe(\"Defines a silkscreen oval on the PCB\"),n4=k_.object({type:k_.literal(\"pcb_silkscreen_pill\"),pcb_silkscreen_pill_id:K1(\"pcb_silkscreen_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:u5,ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen pill on the PCB\"),o4=k_.object({type:k_.literal(\"pcb_fabrication_note_text\"),pcb_fabrication_note_text_id:K1(\"pcb_fabrication_note_text\"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"1mm\"),pcb_component_id:k_.string(),text:k_.string(),layer:p5,anchor_position:Z1.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),color:k_.string().optional()}).describe(\"Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators\"),i4=k_.object({type:k_.literal(\"pcb_fabrication_note_path\"),pcb_fabrication_note_path_id:K1(\"pcb_fabrication_note_path\"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:u5,route:k_.array(Z1),stroke_width:j1,color:k_.string().optional()}).describe(\"Defines a fabrication path on the PCB for fabricators or assemblers\"),r4=k_.object({type:k_.literal(\"pcb_fabrication_note_rect\"),pcb_fabrication_note_rect_id:K1(\"pcb_fabrication_note_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5,stroke_width:j1.default(\"0.1mm\"),corner_radius:j1.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a fabrication note rectangle on the PCB\"),s4=k_.object({type:k_.literal(\"pcb_fabrication_note_dimension\"),pcb_fabrication_note_dimension_id:K1(\"pcb_fabrication_note_dimension\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,from:Z1,to:Z1,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:j1.optional(),offset_distance:j1.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:j1.default(\"1mm\"),color:k_.string().optional(),arrow_size:j1.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB fabrication notes\"),a4=k_.object({type:k_.literal(\"pcb_note_text\"),pcb_note_text_id:K1(\"pcb_note_text\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"1mm\"),text:k_.string().optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),layer:p5.default(\"top\"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a documentation note in text on the PCB\"),c4=k_.object({type:k_.literal(\"pcb_note_rect\"),pcb_note_rect_id:K1(\"pcb_note_rect\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5.default(\"top\"),stroke_width:j1.default(\"0.1mm\"),corner_radius:j1.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a rectangular documentation note on the PCB\"),l4=k_.object({type:k_.literal(\"pcb_note_path\"),pcb_note_path_id:K1(\"pcb_note_path\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(Z1),layer:p5.default(\"top\"),stroke_width:j1.default(\"0.1mm\"),color:k_.string().optional()}).describe(\"Defines a polyline documentation note on the PCB\"),d4=k_.object({type:k_.literal(\"pcb_note_line\"),pcb_note_line_id:K1(\"pcb_note_line\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:Y1,y1:Y1,x2:Y1,y2:Y1,layer:p5.default(\"top\"),stroke_width:Y1.default(\"0.1mm\"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe(\"Defines a straight documentation note line on the PCB\"),h4=k_.object({type:k_.literal(\"pcb_note_dimension\"),pcb_note_dimension_id:K1(\"pcb_note_dimension\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:Z1,to:Z1,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:j1.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:j1.default(\"1mm\"),layer:p5.default(\"top\"),color:k_.string().optional(),arrow_size:j1.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB documentation notes\"),u4=f2.extend({type:k_.literal(\"pcb_footprint_overlap_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_footprint_overlap_error\").default(\"pcb_footprint_overlap_error\"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when a pcb footprint overlaps with another element\"),p4=f2.extend({type:k_.literal(\"pcb_courtyard_overlap_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_courtyard_overlap_error\").default(\"pcb_courtyard_overlap_error\"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe(\"Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another\"),m4=k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"rect\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:Y1,height:Y1,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:Y1,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),g4=k_.object({type:k_.literal(\"pcb_cutout\"),pcb_cutout_id:K1(\"pcb_cutout\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),f4=g4.extend({shape:k_.literal(\"rect\"),center:Z1,width:j1,height:j1,rotation:G1.optional(),corner_radius:j1.optional()}),y4=g4.extend({shape:k_.literal(\"circle\"),center:Z1,radius:j1}),_4=g4.extend({shape:k_.literal(\"polygon\"),points:k_.array(Z1)}),b4=g4.extend({shape:k_.literal(\"path\"),route:k_.array(Z1),slot_width:j1,slot_length:j1.optional(),space_between_slots:j1.optional(),slot_corner_radius:j1.optional()}),x4=k_.discriminatedUnion(\"shape\",[f4,y4,_4,b4]).describe(\"Defines a cutout on the PCB, removing board material.\"),v4=f2.extend({type:k_.literal(\"pcb_missing_footprint_error\"),pcb_missing_footprint_error_id:K1(\"pcb_missing_footprint_error\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"pcb_missing_footprint_error\").default(\"pcb_missing_footprint_error\"),source_component_id:k_.string()}).describe(\"Defines a missing footprint error on the PCB\"),S4=f2.extend({type:k_.literal(\"external_footprint_load_error\"),external_footprint_load_error_id:K1(\"external_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal(\"external_footprint_load_error\").default(\"external_footprint_load_error\")}).describe(\"Defines an error when an external footprint fails to load\"),I4=f2.extend({type:k_.literal(\"circuit_json_footprint_load_error\"),circuit_json_footprint_load_error_id:K1(\"circuit_json_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"circuit_json_footprint_load_error\").default(\"circuit_json_footprint_load_error\"),circuit_json:k_.array(k_.any()).optional()}).describe(\"Defines an error when a circuit JSON footprint fails to load\"),C4=k_.object({type:k_.literal(\"pcb_group\"),pcb_group_id:K1(\"pcb_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:j1.optional(),height:j1.optional(),center:Z1,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this group, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this group, usually corresponding with how the user specified it\"),outline:k_.array(Z1).optional(),anchor_position:Z1.optional(),anchor_alignment:Q1.default(\"center\"),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"none\"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum([\"packed\",\"none\"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:j1}).optional(),autorouter_used_string:k_.string().optional()}).describe(\"Defines a group of components on the PCB\"),P4=f2.extend({type:k_.literal(\"pcb_autorouting_error\"),pcb_error_id:K1(\"pcb_autorouting_error\"),error_type:k_.literal(\"pcb_autorouting_error\").default(\"pcb_autorouting_error\"),subcircuit_id:k_.string().optional()}).describe(\"The autorouting has failed to route a portion of the board\"),M4=k_.object({type:k_.literal(\"pcb_manual_edit_conflict_warning\"),pcb_manual_edit_conflict_warning_id:K1(\"pcb_manual_edit_conflict_warning\"),warning_type:k_.literal(\"pcb_manual_edit_conflict_warning\").default(\"pcb_manual_edit_conflict_warning\"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates\"),N4=k_.enum([\"x-\",\"x+\",\"y+\",\"y-\"]),w4=k_.object({type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\"),pcb_connector_not_in_accessible_orientation_warning_id:K1(\"pcb_connector_not_in_accessible_orientation_warning\"),warning_type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\").default(\"pcb_connector_not_in_accessible_orientation_warning\"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:N4,recommended_facing_direction:N4,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction\"),T4=k_.object({type:k_.literal(\"supplier_footprint_mismatch_warning\"),supplier_footprint_mismatch_warning_id:K1(\"supplier_footprint_mismatch_warning\"),warning_type:k_.literal(\"supplier_footprint_mismatch_warning\").default(\"supplier_footprint_mismatch_warning\"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:y2.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe(\"Warning emitted when a supplier part footprint does not match the expected footprint\"),R4=k_.object({type:k_.literal(\"pcb_breakout_point\"),pcb_breakout_point_id:K1(\"pcb_breakout_point\"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:Y1,y:Y1}).describe(\"Defines a routing target within a pcb_group for a source_trace or source_net\"),E4=k_.object({type:k_.literal(\"pcb_ground_plane\"),pcb_ground_plane_id:K1(\"pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane on the PCB\"),A4=k_.object({type:k_.literal(\"pcb_ground_plane_region\"),pcb_ground_plane_region_id:K1(\"pcb_ground_plane_region\"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:u5,points:k_.array(Z1)}).describe(\"Defines a polygon region of a ground plane\"),O4=k_.object({type:k_.literal(\"pcb_thermal_spoke\"),pcb_thermal_spoke_id:K1(\"pcb_thermal_spoke\"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:Y1,spoke_inner_diameter:Y1,spoke_outer_diameter:Y1,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Pattern for connecting a ground plane to a plated hole\"),k4=k_.object({type:k_.literal(\"pcb_copper_pour\"),pcb_copper_pour_id:K1(\"pcb_copper_pour\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:u5,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),L4=k4.extend({shape:k_.literal(\"rect\"),center:Z1,width:j1,height:j1,rotation:G1.optional()}),D4=k4.extend({shape:k_.literal(\"brep\"),brep_shape:Q5}),z4=k4.extend({shape:k_.literal(\"polygon\"),points:k_.array(Z1)}),F4=k_.discriminatedUnion(\"shape\",[L4,D4,z4]).describe(\"Defines a copper pour on the PCB.\"),B4=f2.extend({type:k_.literal(\"pcb_component_outside_board_error\"),pcb_component_outside_board_error_id:K1(\"pcb_component_outside_board_error\"),error_type:k_.literal(\"pcb_component_outside_board_error\").default(\"pcb_component_outside_board_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Z1,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a PCB component is placed outside the board boundaries\"),j4=f2.extend({type:k_.literal(\"pcb_component_not_on_board_edge_error\"),pcb_component_not_on_board_edge_error_id:K1(\"pcb_component_not_on_board_edge_error\"),error_type:k_.literal(\"pcb_component_not_on_board_edge_error\").default(\"pcb_component_not_on_board_edge_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Z1,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component that must be placed on the board edge is centered away from the edge\"),$4=f2.extend({type:k_.literal(\"pcb_component_invalid_layer_error\"),pcb_component_invalid_layer_error_id:K1(\"pcb_component_invalid_layer_error\"),error_type:k_.literal(\"pcb_component_invalid_layer_error\").default(\"pcb_component_invalid_layer_error\"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:u5,subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)\"),Y4=f2.extend({type:k_.literal(\"pcb_via_clearance_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_via_clearance_error\").default(\"pcb_via_clearance_error\"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when vias are closer than the allowed clearance\"),X4=f2.extend({type:k_.literal(\"pcb_via_trace_clearance_error\"),pcb_via_trace_clearance_error_id:K1(\"pcb_via_trace_clearance_error\"),error_type:k_.literal(\"pcb_via_trace_clearance_error\").default(\"pcb_via_trace_clearance_error\"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a via and trace are closer than the allowed clearance\"),V4=f2.extend({type:k_.literal(\"pcb_pad_pad_clearance_error\"),pcb_pad_pad_clearance_error_id:K1(\"pcb_pad_pad_clearance_error\"),error_type:k_.literal(\"pcb_pad_pad_clearance_error\").default(\"pcb_pad_pad_clearance_error\"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when pads are closer than the allowed clearance\"),W4=f2.extend({type:k_.literal(\"pcb_pad_trace_clearance_error\"),pcb_pad_trace_clearance_error_id:K1(\"pcb_pad_trace_clearance_error\"),error_type:k_.literal(\"pcb_pad_trace_clearance_error\").default(\"pcb_pad_trace_clearance_error\"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pad and trace are closer than allowed clearance\"),H4=k_.object({type:k_.literal(\"pcb_courtyard_rect\"),pcb_courtyard_rect_id:K1(\"pcb_courtyard_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5,ccw_rotation:G1.optional(),color:k_.string().optional()}).describe(\"Defines a courtyard rectangle on the PCB\"),G4=k_.object({type:k_.literal(\"pcb_courtyard_outline\"),pcb_courtyard_outline_id:K1(\"pcb_courtyard_outline\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,outline:k_.array(Z1).min(2)}).describe(\"Defines a courtyard outline on the PCB\"),U4=k_.object({type:k_.literal(\"pcb_courtyard_polygon\"),pcb_courtyard_polygon_id:K1(\"pcb_courtyard_polygon\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,points:k_.array(Z1).min(3),color:k_.string().optional()}).describe(\"Defines a courtyard polygon on the PCB\"),Z4=k_.object({type:k_.literal(\"pcb_courtyard_circle\"),pcb_courtyard_circle_id:K1(\"pcb_courtyard_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:j1,layer:p5,color:k_.string().optional()}).describe(\"Defines a courtyard circle on the PCB\"),q4=k_.object({type:k_.literal(\"cad_component\"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:q1,rotation:q1.optional(),size:q1.optional(),layer:u5.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:t2.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum([\"x+\",\"x-\",\"y+\",\"y-\",\"z+\",\"z-\"]).optional().describe('The direction in the model\\'s coordinate space that is considered \"up\" or \"coming out of the board surface\"'),model_origin_position:q1.optional(),model_origin_alignment:k_.enum([\"unknown\",\"center\",\"center_of_component_on_board_surface\",\"bottom_center_of_component\"]).optional(),model_object_fit:k_.enum([\"contain_within_bounds\",\"fill_bounds\"]).optional().default(\"contain_within_bounds\"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),anchor_alignment:k_.enum([\"center\",\"center_of_component_on_board_surface\"]).optional().default(\"center\")}).describe(\"Defines a component on the PCB\"),J4=k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]),K4=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),Q4=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:K1(\"simulation_voltage_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:B1}).describe(\"Defines a DC voltage source for simulation\"),t6=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:K1(\"simulation_voltage_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:B1.optional(),frequency:$1.optional(),peak_to_peak_voltage:B1.optional(),wave_shape:J4.optional(),phase:G1.optional(),duty_cycle:K4.optional()}).describe(\"Defines an AC voltage source for simulation\"),e6=k_.union([Q4,t6]).describe(\"Defines a voltage source for simulation\"),n6=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),o6=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:K1(\"simulation_current_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:X1}).describe(\"Defines a DC current source for simulation\"),i6=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:K1(\"simulation_current_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:X1.optional(),frequency:$1.optional(),peak_to_peak_current:X1.optional(),wave_shape:J4.optional(),phase:G1.optional(),duty_cycle:n6.optional()}).describe(\"Defines an AC current source for simulation\"),r6=k_.union([o6,i6]).describe(\"Defines a current source for simulation\"),s6=k_.union([k_.literal(\"spice_dc_sweep\"),k_.literal(\"spice_dc_operating_point\"),k_.literal(\"spice_transient_analysis\"),k_.literal(\"spice_ac_analysis\")]),a6=k_.object({type:k_.literal(\"simulation_experiment\"),simulation_experiment_id:K1(\"simulation_experiment\"),name:k_.string(),experiment_type:s6,time_per_step:V1.optional(),start_time_ms:W1.optional(),end_time_ms:W1.optional()}).describe(\"Defines a simulation experiment configuration\"),c6=k_.object({type:k_.literal(\"simulation_transient_voltage_graph\"),simulation_transient_voltage_graph_id:K1(\"simulation_transient_voltage_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:V1,start_time_ms:W1,end_time_ms:W1,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores voltage measurements over time for a simulation\"),l6=k_.object({type:k_.literal(\"simulation_switch\"),simulation_switch_id:K1(\"simulation_switch\"),source_component_id:k_.string().optional(),closes_at:W1.optional(),opens_at:W1.optional(),starts_closed:k_.boolean().optional(),switching_frequency:$1.optional()}).describe(\"Defines a switch for simulation timing control\"),d6=k_.object({type:k_.literal(\"simulation_voltage_probe\"),simulation_voltage_probe_id:K1(\"simulation_voltage_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.\").superRefine((t,e)=\u003e{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n\u0026\u0026o?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a differential probe.\"}):n?t.signal_input_source_port_id\u0026\u0026t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id.\"}):o\u0026\u0026(t.signal_input_source_net_id\u0026\u0026t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id.\"}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id.\"})}),h6=f2.extend({type:k_.literal(\"simulation_unknown_experiment_error\"),simulation_unknown_experiment_error_id:K1(\"simulation_unknown_experiment_error\"),error_type:k_.literal(\"simulation_unknown_experiment_error\").default(\"simulation_unknown_experiment_error\"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"An unknown error occurred during the simulation experiment.\"),u6=k_.object({type:k_.literal(\"simulation_op_amp\"),simulation_op_amp_id:K1(\"simulation_op_amp\"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe(\"Defines a simple ideal operational amplifier for simulation\"),p6=(k_.union([r5,o5,i5,n5,a5,s5,P2,b2,v2,I2,x2,M2,R2,E2,L2,z2,F2,X2,B2,j2,$2,Y2,O2,A2,d5,m5,c5,V2,G2,U2,q2,J2,g5,f5,y5,_5,b5,t5,l5,o3,d3,v4,S4,I4,M4,w4,T4,y3,m4,_3,Y3,A3,D3,z3,X3,P3,E3,V3,W3,C4,U3,Z3,q3,J3,n4,K3,Q3,t4,e4,F3,B3,H3,G3,j3,$3,Y4,X4,V4,W4,i4,o4,r4,s4,a4,c4,l4,d4,h4,P4,u4,p4,R4,x4,E4,A4,O4,F4,B4,j4,$4,H4,G4,U4,Z4,x5,L5,T5,R5,E5,A5,M5,w5,D5,O5,v5,F5,B5,z5,V5,W5,H5,G5,q5,U5,Z5,q4,e6,r6,a6,c6,l6,d6,h6,u6]),[0,1,-1,2,-2,3,-3,4]),m6=(p6.flatMap(t=\u003ep6.map(e=\u003e[t,e])).sort(([t,e],[n,o])=\u003eMath.abs(t)+Math.abs(e)-Math.abs(n)-Math.abs(o)).length,[.2,.4,.8,1.2].flatMap(t=\u003e[.2,.3,.45,.6].flatMap(e=\u003e[-1,1].map(n=\u003e({halfSpan:t,offset:e,directionSign:n})))).flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,...t}))));[1,-1].flatMap(t=\u003e[1,-1].flatMap(e=\u003e[!1,!0].flatMap(n=\u003e[0,1].map(o=\u003e({routeSide:o,normalDirectionSign:t,tangentDirectionSign:e,reverseEndpointOffsets:n}))))),[0,1].map(t=\u003e({kind:\"displacementChain\",routeSide:t})),[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,halfSpan:.4,offset:1.2,directionSign:t}))),[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"span\",routeSide:e,spanExpansion:3,offset:1.8,directionSign:t}))),[{dx:-2.4,dy:-.4},{dx:-2.4,dy:.4},{dx:2.4,dy:-.4},{dx:2.4,dy:.4},{dx:-.4,dy:-2.4},{dx:-.4,dy:2.4},{dx:.4,dy:-2.4},{dx:.4,dy:2.4}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:2,...t}))),[{dx:-.17,dy:0},{dx:.17,dy:0},{dx:0,dy:-.17},{dx:0,dy:.17}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:0,...t})));var g6=1e-8,f6=(t,e,n=0)=\u003et.x\u003e=e.minX+n-g6\u0026\u0026t.x\u003c=e.maxX-n+g6\u0026\u0026t.y\u003e=e.minY+n-g6\u0026\u0026t.y\u003c=e.maxY-n+g6,y6=(t,e,n)=\u003e{let o=0,i=1;for(const[r,s,a,c]of[[t.x,e.x-t.x,n.minX,n.maxX],[t.y,e.y-t.y,n.minY,n.maxY]]){if(void 0===r||void 0===s||void 0===a||void 0===c)throw new Error(\"Invalid segment clipping axis\");if(Math.abs(s)\u003c=g6){if(r\u003ca-g6||r\u003ec+g6)return;continue}const t=(a-r)/s,e=(c-r)/s;if(o=Math.max(o,Math.min(t,e)),i=Math.min(i,Math.max(t,e)),i\u003co-g6)return}return[Math.max(0,o),Math.min(1,i)]},_6=(t,e,n)=\u003e{if(n\u003c=g6)return structuredClone(t);if(n\u003e=.99999999)return structuredClone(e);const o={...structuredClone(t),x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n};return delete o.pcb_port_id,o},b6=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=g6\u0026\u0026Math.abs(t.y-e.y)\u003c=g6\u0026\u0026t.z===e.z,x6=t=\u003eArray.isArray(t)?`[${t.map(x6).join(\",\")}]`:null!==t\u0026\u0026\"object\"==typeof t?`{${Object.keys(t).filter(e=\u003evoid 0!==t[e]).sort().map(e=\u003e`${JSON.stringify(e)}:${x6(t[e])}`).join(\",\")}}`:JSON.stringify(t)??\"undefined\",v6=(t,e,n)=\u003e{if(1===t.route.length)return structuredClone(t.route);const o=e=\u003e{const n=Math.min(Math.floor(e),t.route.length-2);return _6(t.route[n],t.route[n+1],e-n)},i=[o(e)];for(let o=Math.floor(e)+1;o\u003cn-g6;o+=1)i.push(structuredClone(t.route[o]));return n\u003ee+g6\u0026\u0026i.push(o(n)),i},S6=(t,e,n)=\u003e{const o=v6(t,e,n),i=Object.fromEntries(Object.entries(t).filter(([t])=\u003e\"route\"!==t\u0026\u0026\"vias\"!==t)),r=t.vias.filter(t=\u003eo.some(e=\u003eMath.hypot(e.x-t.x,e.y-t.y)\u003c=g6));return x6({metadata:i,points:o,vias:r})},I6=(t,e)=\u003e{const n=t.__zLayers;if(n)return new Set(n);if(t.zLayers)return new Set(t.zLayers);const o=new Set;for(const n of t.layers){const t=\"top\"===n?0:\"bottom\"===n?e-1:/^inner\\d+$/.test(n)?Number(n.slice(5)):-1;if(t\u003c0||t\u003e=e)throw new Error(`repair04 obstacle has an unknown layer: ${n}`);o.add(t)}return o},C6=({srj:t,routes:e,traceClearance:n=.1,viaClearance:o=.1})=\u003e{let i;const r=new Map,s=[];let a=!1;return c=\u003e{const l=i??=((t,e)=\u003e{const n=new Map,o=t=\u003e{const e=n.get(t);if(void 0===e)return n.set(t,t),t;if(e===t)return t;const i=o(e);return n.set(t,i),i},i=t=\u003e{const e=t.filter(t=\u003e\"string\"==typeof t\u0026\u0026t.length\u003e0);if(0===e.length)return;const i=o(e[0]);for(const t of e)n.set(o(t),i)};for(const e of t.connections){const t=e;i([t.name,t.rootConnectionName,t.netConnectionName,t.__netConnectionName,...t.mergedConnectionNames??[],...t.__rootConnectionNames??[],...t.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])])}for(const e of t.obstacles)i(e.connectedTo);for(const t of e)i([t.connectionName,t.rootConnectionName]);for(const t of n.keys())n.set(t,o(t));return n})(t,e),d=new Map,h=a?s:function*(e){for(let i=0;i\u003ct.obstacles.length;i++){if(r.has(i)){const t=r.get(i);t\u0026\u0026(yield t);continue}const a=t.obstacles[i],c=a.connectedTo.some(t=\u003e/^(pcb_smtpad_|pcb_plated_hole_|pcb_port_)/.test(t)),l=Math.abs((a.ccwRotationDegrees??0)%180)\u003e1e-8,d=\"rect\"===a.type\u0026\u0026a.layers.length\u003e1\u0026\u0026Math.abs(a.width-a.height)\u003c.001;if(c\u0026\u0026!l\u0026\u0026!d){r.set(i,null);continue}if(![a.center.x,a.center.y,a.width,a.height,a.ccwRotationDegrees??0].every(Number.isFinite)||a.width\u003c0||a.height\u003c0)throw new Error(\"repair04 fixed obstacle geometry must be finite and nonnegative\");const h=I6(a,t.layerCount),u=new Set(a.connectedTo.map(t=\u003ee.get(t)??t)),p={minX:-a.width/2,maxX:a.width/2,minY:-a.height/2,maxY:a.height/2},m=(a.ccwRotationDegrees??0)*Math.PI/180,g=Math.cos(m),f=Math.sin(m),y=Math.hypot(a.width,a.height)/2,_=t=\u003e{const e=t.x-a.center.x,n=t.y-a.center.y;return{x:e*g+n*f,y:-e*f+n*g}},b=(t,e,n)=\u003eMath.max(t.x,e.x)+n\u003ca.center.x-y||Math.min(t.x,e.x)-n\u003ea.center.x+y||Math.max(t.y,e.y)+n\u003ca.center.y-y||Math.min(t.y,e.y)-n\u003ea.center.y+y,x=!0===a.obstacleId?.startsWith(\"repair04_board_edge_\"),v=x?0:Math.max(n,t.defaultObstacleMargin??0,t.minTraceToPadEdgeClearance??0),S=x?0:Math.max(o,t.defaultObstacleMargin??0,t.minViaEdgeToPadEdgeClearance??0),I={obstacleIndex:i,obstacle:a,zLayers:h,obstacleNets:u,obstacleBounds:p,toLocal:_,separated:b,wireGap:v,viaGap:S};r.set(i,I),s.push(I),yield I}a=!0}(l);for(const{obstacleIndex:t,obstacle:e,zLayers:n,obstacleNets:o,obstacleBounds:i,toLocal:r,separated:s,wireGap:a,viaGap:u}of h)for(let h=0;h\u003cc.length;h+=1){const p=c[h];if(!(p.route.length\u003c2)\u0026\u0026![p.connectionName,p.rootConnectionName].some(t=\u003evoid 0!==t\u0026\u0026o.has(l.get(t)??t)))for(let o=1;o\u003cp.route.length;o+=1){const c=p.route[o-1],l=p.route[o];if(\"through_obstacle\"===c.toNextSegmentType)continue;if(c.z!==l.z){if(!Array.from(n).some(t=\u003et\u003e=Math.min(c.z,l.z)\u0026\u0026t\u003c=Math.max(c.z,l.z)))continue;if(Math.abs(c.x-l.x)\u003e1e-8||Math.abs(c.y-l.y)\u003e1e-8)throw new Error(\"repair04 found a non-colocated via transition: \"+JSON.stringify({route:p,from:c,to:l}));if(s(c,c,p.viaDiameter/2+u+1e-8))continue;const e=r(c),o=ke(e,e,i),a=p.viaDiameter/2+u-o;if(a\u003c=1e-8)continue;const m=`fixed-obstacle:${h}:${t}:via`;(d.get(m)?.severity??-1/0)\u003ca\u0026\u0026d.set(m,{key:m,center:{x:c.x,y:c.y},routeIndex:h,obstacleIndex:t,kind:\"via\",severity:a});continue}if(!n.has(c.z))continue;const m=Math.max(c.traceThickness??p.traceThickness,l.traceThickness??p.traceThickness)/2;if(s(c,l,m+a+1e-8))continue;const g=m+a-ke(r(c),r(l),i);if(g\u003c=1e-8)continue;const f=`fixed-obstacle:${h}:${t}:wire`;(d.get(f)?.severity??-1/0)\u003cg\u0026\u0026d.set(f,{key:f,center:ze(e.center,c,l),routeIndex:h,obstacleIndex:t,kind:\"wire\",severity:g})}}return Array.from(d.values())}},P6=t=\u003eC6(t)(t.routes),M6=(t,e)=\u003e{const n=[];for(let o=1;o\u003ct.route.length;o++){const i=t.route[o-1],r=t.route[o];if(i.z===r.z||\"through_obstacle\"===i.toNextSegmentType)continue;if(i.x!==r.x||i.y!==r.y||![i.x,i.y,i.z,r.z,t.viaDiameter].every(Number.isFinite)||!Number.isInteger(i.z)||!Number.isInteger(r.z)||Math.min(i.z,r.z)\u003c0||Math.max(i.z,r.z)\u003e=e||t.viaDiameter\u003c=0)throw new Error(\"repair04 new-via guard requires valid colocated vias\");const s=o-1,a=[i.z,r.z];let c=Math.min(i.z,r.z),l=Math.max(i.z,r.z);for(;o+1\u003ct.route.length\u0026\u0026\"through_obstacle\"!==t.route[o].toNextSegmentType;){const n=t.route[o+1];if(n.x!==r.x||n.y!==r.y)break;if(!Number.isInteger(n.z)||n.z\u003c0||n.z\u003e=e)throw new Error(\"repair04 new-via guard found an invalid layer span\");n.z!==a.at(-1)\u0026\u0026a.push(n.z),c=Math.min(c,n.z),l=Math.max(l,n.z),o++}n.push({pointIndices:Array.from({length:o-s+1},(t,e)=\u003es+e),layerSequence:a,x:r.x,y:r.y,minZ:c,maxZ:l,diameter:t.viaDiameter,identity:JSON.stringify([r.x,r.y,c,l,t.viaDiameter])})}return n},N6=({srj:t,viaClearance:e=.1})=\u003e{const n=new Map,o=new Map,i=[e,t.defaultObstacleMargin??0,t.minViaEdgeToPadEdgeClearance??0],r=Math.max(...i),s=e=\u003e{const i=o.get(e.identity);if(i)return i;const s=[];for(let o=0;o\u003ct.obstacles.length;o++){const i=t.obstacles[o];let a=n.get(o);if(!a){const e=i.__zLayers??i.zLayers??i.layers.map(e=\u003e\"top\"===e?0:\"bottom\"===e?t.layerCount-1:/^inner\\d+$/.test(e)?Number(e.slice(5)):-1);if(e.some(e=\u003e!Number.isInteger(e)||e\u003c0||e\u003e=t.layerCount))throw new Error(\"repair04 new-via guard found an unknown obstacle layer\");a={zs:e},n.set(o,a)}if(!a.zs.some(t=\u003et\u003e=e.minZ\u0026\u0026t\u003c=e.maxZ))continue;if(!a.geometry){if(![i.center.x,i.center.y,i.width,i.height,i.ccwRotationDegrees??0].every(Number.isFinite)||i.width\u003c0||i.height\u003c0)throw new Error(\"repair04 new-via guard found invalid obstacle geometry\");const t=(i.ccwRotationDegrees??0)*Math.PI/180;a.geometry={x:i.center.x,y:i.center.y,cosine:Math.cos(t),sine:Math.sin(t),extent:Math.hypot(i.width,i.height)/2,bounds:{minX:-i.width/2,maxX:i.width/2,minY:-i.height/2,maxY:i.height/2}}}const c=a.geometry,l=c.extent+e.diameter/2+r+1e-8;if(Math.abs(e.x-c.x)\u003el||Math.abs(e.y-c.y)\u003el)continue;const d=e.x-c.x,h=e.y-c.y,u={x:d*c.cosine+h*c.sine,y:-d*c.sine+h*c.cosine},p=ke(u,u,c.bounds),m=e.diameter/2+r-p;m\u003c=1e-8||s.push({obstacleIndex:o,severity:m})}return o.set(e.identity,s),s};return({previousRoutes:e,routes:n,includeExistingVias:o=[]})=\u003e{if(e.length!==n.length)throw new Error(\"repair04 new-via guard requires matching route ordering\");if(i.some(t=\u003e!Number.isFinite(t)||t\u003c0))throw new Error(\"repair04 new-via guard requires nonnegative finite margins\");const r=[];for(let i=0;i\u003cn.length;i++){const a=n[i],c=e[i],l=new Set(a.connectionName===c.connectionName\u0026\u0026a.rootConnectionName===c.rootConnectionName?M6(c,t.layerCount).map(t=\u003et.identity):[]),d=M6(a,t.layerCount);for(let t=0;t\u003cd.length;t++){const e=d[t];if(!l.has(e.identity)||o.some(e=\u003ee.routeIndex===i\u0026\u0026e.viaIndex===t))for(const n of s(e))r.push({key:`new-via-pad:${i}:${n.obstacleIndex}:${t}`,routeIndex:i,obstacleIndex:n.obstacleIndex,center:{x:e.x,y:e.y},kind:\"via\",severity:n.severity})}}return r}},w6=t=\u003eN6(t)(t);function T6(t,e){return t.x\u003ee.minX+4e-8\u0026\u0026t.x\u003ce.maxX-4e-8\u0026\u0026t.y\u003ee.minY+4e-8\u0026\u0026t.y\u003ce.maxY-4e-8}function R6(t){const e=[];for(let n=1;n\u003ct.route.length;n++){const o=t.route[n-1],i=t.route[n];if(o.z!==i.z\u0026\u0026\"through_obstacle\"!==o.toNextSegmentType){if(o.x!==i.x||o.y!==i.y)throw new Error(\"repair04: a layer transition must have coincident endpoints\");e.some(t=\u003et.x===i.x\u0026\u0026t.y===i.y)||e.push({x:i.x,y:i.y})}}return{...t,vias:e}}function E6(t){const e=[];for(let n=1;n\u003ct.route.length;n++){const o=t.route[n-1],i=t.route[n];o.z!==i.z\u0026\u0026\"through_obstacle\"!==o.toNextSegmentType\u0026\u0026e.push([o.x,o.y,o.z,i.z])}return JSON.stringify([t.viaDiameter,e])}var A6=class extends kt{input;mutableBounds;engine;fixedTraces;routes;score=null;candidates=null;bestAdjustment=null;lockedPoints;evaluated=0;accepted=0;maxCandidates;candidateAttempts=0;pathSearchNodes=0;pathSearchCalls=0;viaBlockerPathSearchCalls=0;coupledPathSearchCalls=0;threeRoutePathSearchCalls=0;threeRoutePathSearchNodes=0;candidateScores=new Map;routeCache=new WeakMap;fixedObstacleNetContext;fixedObstacleEvaluator;viaPadEvaluator;viaGeometryCache=new WeakMap;constructor(t){if(super(),!Number.isFinite(t.boundaryMargin)||t.boundaryMargin\u003c=0)throw new Error(\"repair04: boundaryMargin must be positive and finite\");const e=t.bounds;if(![e.minX,e.maxX,e.minY,e.maxY].every(Number.isFinite)||e.maxX-e.minX\u003c10-1e-8||e.maxY-e.minY\u003c10-1e-8)throw new Error(\"repair04: bounds must be finite and at least 10 × 10 mm\");if(this.input=structuredClone(t),this.viaPadEvaluator=(({srj:t,viaClearance:e})=\u003eN6({srj:{layerCount:t.layerCount,obstacles:structuredClone(t.obstacles),defaultObstacleMargin:t.defaultObstacleMargin,minViaEdgeToPadEdgeClearance:t.minViaEdgeToPadEdgeClearance},viaClearance:e}))({srj:this.input.srj,viaClearance:this.input.viaClearance}),this.routes=structuredClone(t.routes),this.fixedObstacleNetContext=this.input.routes.map(t=\u003e({...t,route:[]})),this.fixedObstacleEvaluator=(t=\u003eC6({...t,srj:structuredClone(t.srj),routes:t.routes.map(t=\u003e({...t,route:[]}))}))({srj:this.input.srj,routes:this.fixedObstacleNetContext,traceClearance:this.input.traceClearance,viaClearance:this.input.viaClearance}),this.fixedTraces=(t.srj.traces??[]).map(e=\u003em1(e,t.srj.minTraceWidth)),this.mutableBounds={minX:e.minX+t.boundaryMargin,minY:e.minY+t.boundaryMargin,maxX:e.maxX-t.boundaryMargin,maxY:e.maxY-t.boundaryMargin},this.mutableBounds.minX\u003e=this.mutableBounds.maxX||this.mutableBounds.minY\u003e=this.mutableBounds.maxY)throw new Error(\"repair04: boundary collar leaves no mutable area\");if(t.lockedPointIndices.length!==t.routes.length)throw new Error(\"repair04: every route requires a lock mask\");this.lockedPoints=this.routes.map((e,n)=\u003e{if(t.lockedPointIndices[n].length!==e.route.length)throw new Error(\"repair04: lock mask length must match its route\");for(let t=1;t\u003ce.route.length;t++){const n=y6(e.route[t-1],e.route[t],this.mutableBounds);if(n?.some(t=\u003et\u003e1e-8\u0026\u0026t\u003c1-1e-8))throw new Error(\"repair04: boundary crossings require fixed cut points; use extractRepairRegion\")}return e.route.filter((o,i)=\u003et.lockedPointIndices[n][i]||0===i||i===e.route.length-1||o.pcb_port_id||o.insideJumperPad||o.toNextSegmentType||!T6(o,this.mutableBounds))});for(const e of t.movableVias??[]){const n=this.routes[e.routeIndex],o=n\u0026\u0026M6(n,t.srj.layerCount)[e.viaIndex];if(!o||o.pointIndices.some(t=\u003ethis.isLocked(e.routeIndex,n.route[t])))throw new Error(\"repair04: movable via must identify an unlocked existing via\")}for(const e of[\"maxCandidateAttempts\",\"maxPathSearchNodes\"]){const n=t[e];if(void 0!==n\u0026\u0026(!Number.isSafeInteger(n)||n\u003c1))throw new Error(`repair04: ${e} must be a positive safe integer`)}if(this.maxCandidates=t.maxCandidates??8e3,!Number.isInteger(this.maxCandidates)||this.maxCandidates\u003c1)throw new Error(\"repair04: maxCandidates must be a positive integer\");this.MAX_ITERATIONS=2*this.maxCandidates+4,this.engine=new R1(this.input.srj,{cacheStaticObstacleNetMembership:!0,cacheImmutableTraceGeometry:!0,useTransientDynamicQueryMarkers:!0,useConservativeRectObstaclePrecheck:!0,traceClearance:t.traceClearance??.1,viaClearance:t.viaClearance??.1,includeTraceViaOwnerMetadata:!0})}getWorkLimitReason(){return void 0!==this.input.maxCandidateAttempts\u0026\u0026this.candidateAttempts\u003e=this.input.maxCandidateAttempts?\"candidate-attempt-limit\":void 0!==this.input.maxPathSearchNodes\u0026\u0026this.pathSearchNodes\u003e=this.input.maxPathSearchNodes?\"path-search-node-limit\":null}updateWorkStats(t){void 0===this.input.maxCandidateAttempts\u0026\u0026void 0===this.input.maxPathSearchNodes||(this.stats={...this.stats,candidateAttempts:this.candidateAttempts,pathSearchNodes:this.pathSearchNodes,pathSearchCalls:this.pathSearchCalls,...void 0===t?{}:{completionReason:t}})}finishSearch(t){this.bestAdjustment\u0026\u0026(this.routes=this.bestAdjustment.routes,this.candidateScores.clear(),this.score=this.bestAdjustment.score,this.accepted++,this.bestAdjustment=null,this.stats={...this.stats,finalErrorCount:this.score.count,accepted:this.accepted}),this.updateWorkStats(t),this.solved=!0}getRouteCache(t,e){let n=this.routeCache.get(e);n||(n=new Map,this.routeCache.set(e,n));let o=n.get(t);return o||(o={},n.set(t,o)),o}getViaGeometry(t){let e=this.viaGeometryCache.get(t);return e||(e=M6(t,this.input.srj.layerCount),this.viaGeometryCache.set(t,e)),e}getViaPadViolations(t,e){return 0===t.length?this.viaPadEvaluator({previousRoutes:[],routes:[]}):t.flatMap((t,n)=\u003e{const o=this.getRouteCache(n,t),i=e?\"scoredViaViolations\":\"newViaViolations\";if(!o[i]){const r=e?!0!==this.input.allowLayerChanges||this.input.movableVias?.length?(this.input.movableVias??[]).filter(t=\u003et.routeIndex===n).map(t=\u003e({routeIndex:0,viaIndex:t.viaIndex})):this.getViaGeometry(t).flatMap((e,o)=\u003ee.pointIndices.every(e=\u003e!this.isLocked(n,t.route[e]))?[{routeIndex:0,viaIndex:o}]:[]):[];o[i]=this.viaPadEvaluator({previousRoutes:[e?t:this.input.routes[n]],routes:[t],includeExistingVias:r}).map(t=\u003e({...t,routeIndex:n,key:t.key.replace(\"new-via-pad:0:\",`new-via-pad:${n}:`)}))}return o[i]})}getFixedViolations(t){if(0===t.length)return this.fixedObstacleEvaluator(t);const e=t.flatMap((t,e)=\u003evoid 0===this.getRouteCache(e,t).fixedViolations?[e]:[]);if(e.length){const n=this.fixedObstacleNetContext.slice();for(const o of e)n[o]=t[o];const o=this.fixedObstacleEvaluator(n);for(const n of e)this.getRouteCache(n,t[n]).fixedViolations=[];for(const e of o)this.getRouteCache(e.routeIndex,t[e.routeIndex]).fixedViolations.push(e)}return t.flatMap((t,e)=\u003ethis.getRouteCache(e,t).fixedViolations).sort((t,e)=\u003et.obstacleIndex-e.obstacleIndex||t.routeIndex-e.routeIndex)}evaluate(t){const{errors:e}=this.engine.evaluate([...this.fixedTraces,...t.map((t,e)=\u003e{const n=this.getRouteCache(e,t);return n.trace||(n.trace=function(t,e){const n=t=\u003e0===t?\"top\":t===e-1?\"bottom\":`inner${t}`;return t.map((t,e)=\u003e{const o=[];for(let e=0;e\u003ct.route.length;e++){const i=t.route[e],r=t.route[e-1];r\u0026\u0026\"through_obstacle\"!==r.toNextSegmentType\u0026\u0026r.z!==i.z\u0026\u0026r.x===i.x\u0026\u0026r.y===i.y\u0026\u0026o.push({route_type:\"via\",x:i.x,y:i.y,from_layer:n(r.z),to_layer:n(i.z),via_diameter:t.viaDiameter});const s=i.traceThickness??t.traceThickness;o.push({route_type:\"wire\",x:i.x,y:i.y,layer:n(i.z),width:s,...0===e\u0026\u0026i.pcb_port_id?{start_pcb_port_id:i.pcb_port_id}:{},...e===t.route.length-1\u0026\u0026i.pcb_port_id?{end_pcb_port_id:i.pcb_port_id}:{}})}return{type:\"pcb_trace\",pcb_trace_id:`repair04_${e}`,connection_name:t.rootConnectionName??t.connectionName,route:o}})}([t],this.input.srj.layerCount)[0],n.trace.pcb_trace_id=`repair04_${e}`),n.trace})]),n=new Map;for(const o of this.getFixedViolations(t))n.set(o.key,o.severity),e.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:`repair04 fixed obstacle clearance: ${o.key}`,center:o.center,minimum_clearance:o.severity,actual_clearance:0,pcb_trace_id:`repair04_${o.routeIndex}`,pcb_trace_error_id:o.key});for(const n of this.getViaPadViolations(t,!0))e.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:`repair04 selected existing via pad clearance: ${n.key}`,center:n.center,minimum_clearance:n.severity,actual_clearance:0,pcb_trace_id:`repair04_${n.routeIndex}`,pcb_trace_error_id:n.key});let o=0;for(const t of e){const e=/gap: (-?[\\d.]+)/.exec(t.message),n=\"number\"==typeof t.actual_clearance?t.actual_clearance:e?Number(e[1]):null,i=\"number\"==typeof t.minimum_clearance?t.minimum_clearance:.1;o+=null!==n?Math.max(0,i-n):1}return{count:e.length,severity:o,errors:e,fixedViolations:n}}isLocked(t,e){return!T6(e,this.mutableBounds)||this.lockedPoints[t].some(t=\u003et.x===e.x\u0026\u0026t.y===e.y)}*generateTaperedSegmentCandidates(t){const e=new Set;for(const{ri:n,pi:o}of t){if(!this.score.errors.some(t=\u003et.pcb_trace_id===`repair04_${n}`))continue;const t=this.routes[n];for(const[i,r]of[[o-2,o+1],[o-2,o],[o-1,o+1],[o-1,o]]){if(e.size\u003e=8)return;if(i\u003c=0||r\u003e=t.route.length-1)continue;const o=`${n}:${i}:${r}`;if(e.has(o))continue;const s=t.route.slice(i,r+1),a=s[0].z;if(!T6(t.route[i-1],this.mutableBounds)||!T6(t.route[r+1],this.mutableBounds)||t.route[i-1].z!==a||t.route[r+1].z!==a||s.some(e=\u003ee.z!==a||this.isLocked(n,e)||Boolean(e.portPointId)||t.vias.some(t=\u003et.x===e.x\u0026\u0026t.y===e.y)))continue;if(!(new Set(s.map(e=\u003ee.traceThickness??t.traceThickness)).size\u003c2)){e.add(o);for(const e of[.1,.05])for(let o=0;o\u003c8;o++){const a=e*Math.cos(o*Math.PI/4),c=e*Math.sin(o*Math.PI/4),l=s.map(t=\u003e({...t,x:t.x+a,y:t.y+c}));l.some(t=\u003e!T6(t,this.mutableBounds))||(yield{routeIndex:n,route:{...t,route:[...t.route.slice(0,i),...l,...t.route.slice(r+1)]}})}}}}}*generateCrossingPairCandidates(){if(this.coupledPathSearchCalls\u003e=4||this.getWorkLimitReason())return;const t=new Set,e=this.score.errors.filter(t=\u003e\"pcb_trace_error\"===t.type\u0026\u0026\"number\"==typeof t.actual_clearance\u0026\u0026t.actual_clearance\u003c0\u0026\u0026void 0!==t.center);for(const n of e){const e=n.center,o=[];for(let t=0;t\u003cthis.routes.length;t++){const n=this.routes[t];if(!n.jumpers?.length)for(let i=1;i\u003cn.route.length;i++){const r=n.route[i-1],s=n.route[i],a=s.x-r.x,c=s.y-r.y,l=a*a+c*c;if(r.z!==s.z||l\u003c1e-12)continue;const d=((e.x-r.x)*a+(e.y-r.y)*c)/l;d\u003c0||d\u003e1||Math.hypot(e.x-r.x-d*a,e.y-r.y-d*c)\u003c1e-6\u0026\u0026o.push({ri:t,pi:i,a:r,b:s})}}for(let e=0;e\u003co.length;e++)for(let i=e+1;i\u003co.length;i++){let r=o[e],s=o[i];if(r.ri===s.ri||r.a.z!==s.a.z)continue;const a=n.pcb_trace_error_id;if(a!==`overlap_repair04_${r.ri}_repair04_${s.ri}`\u0026\u0026a!==`overlap_repair04_${s.ri}_repair04_${r.ri}`)continue;0===this.routes[r.ri].vias.length\u0026\u0026([r,s]=[s,r]);const c=this.routes[r.ri],l=this.routes[s.ri];if(0===c.vias.length||0!==l.vias.length)continue;const d=`${r.ri}:${s.ri}`;if(t.has(d))continue;t.add(d);let h=s.pi-1,u=s.pi;for(;h\u003e0\u0026\u0026!this.isLocked(s.ri,l.route[h]);)h--;for(;u\u003cl.route.length-1\u0026\u0026!this.isLocked(s.ri,l.route[u]);)u++;if(u-h\u003e64||u-h\u003c2||!T6(l.route[h],this.mutableBounds)||!T6(l.route[u],this.mutableBounds))continue;const p=l.route[h].traceThickness??l.traceThickness;if(l.route.slice(h,u+1).some(t=\u003et.z!==s.a.z||t.toNextSegmentType||t.insideJumperPad||(t.traceThickness??l.traceThickness)!==p))continue;const m=this.getViaGeometry(c),g=m.map((t,e)=\u003e({via:t,viaIndex:e,distance:Math.min(...t.pointIndices.map(t=\u003eMath.abs(t-r.pi)))})).sort((t,e)=\u003et.distance-e.distance)[0];if(!g||g.via.pointIndices.some(t=\u003ethis.isLocked(r.ri,c.route[t]))||this.input.movableVias?.length\u0026\u0026!this.input.movableVias.some(t=\u003et.routeIndex===r.ri\u0026\u0026t.viaIndex===g.viaIndex))continue;const f=Math.max(...g.via.pointIndices);let y=r.pi-1;for(;y\u003e0\u0026\u0026!this.isLocked(r.ri,c.route[y]);)y--;if(y\u003e=Math.min(...g.via.pointIndices))continue;const _=s.b.x-s.a.x,b=s.b.y-s.a.y,x=Math.abs(b)\u003e=Math.abs(_)?{x:1,y:0}:{x:0,y:1},v=2*(this.input.traceClearance??.1)+p;for(const t of[-1,1])for(const e of[2,1]){if(this.coupledPathSearchCalls\u003e=4||this.getWorkLimitReason())return;const n=f+e;if(n\u003e=c.route.length)continue;if(c.route.slice(y+1,n).some(t=\u003ethis.isLocked(r.ri,t)))continue;if(!T6(c.route[y],this.mutableBounds)||!T6(c.route[n],this.mutableBounds))continue;const o=c.route[y].traceThickness??c.traceThickness;if(c.route.slice(y,n+1).some(t=\u003et.toNextSegmentType||t.insideJumperPad||(t.traceThickness??c.traceThickness)!==o))continue;const i={...l,route:l.route.map((e,n)=\u003en\u003eh\u0026\u0026n\u003cu?{...e,x:e.x+t*x.x*v,y:e.y+t*x.y*v}:e)};if(i.route.some((t,e)=\u003ee\u003eh\u0026\u0026e\u003cu\u0026\u0026!T6(t,this.mutableBounds)))continue;const a=this.routes.slice();a[s.ri]=i;const d={nodesPopped:0,completionReason:\"no-path\"},p=Math.min(3e4,void 0===this.input.maxPathSearchNodes?3e4:this.input.maxPathSearchNodes-this.pathSearchNodes);if(p\u003c1)return;const g=g1({srj:this.input.srj,routes:a,routeIndex:r.ri,start:c.route[y],end:c.route[n],bounds:this.mutableBounds,traceThickness:o,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,gridSize:o\u003c=.1?o/2:.1,allowLayerChanges:!0,maxNodes:p,stats:d});if(this.coupledPathSearchCalls++,this.pathSearchCalls++,this.pathSearchNodes+=d.nodesPopped,this.updateWorkStats(),!g)continue;const _=R6({...c,route:[...c.route.slice(0,y),...g,...c.route.slice(n+1)]}),b=this.getViaGeometry(_);b.length!==m.length||b.some((t,e)=\u003et.diameter!==m[e].diameter||JSON.stringify(t.layerSequence)!==JSON.stringify(m[e].layerSequence))||(yield{routeIndex:r.ri,route:_,additionalRoutes:[{routeIndex:s.ri,route:i}]})}}}}*generateClearanceCandidates(t,e){const n=new Set;for(const{ri:o,pi:i}of t){if(n.size\u003e=12)break;const t=this.routes[o],r=n=\u003e{const i=t.route[n];return this.isLocked(o,i)||!e\u0026\u0026(n\u003e0\u0026\u0026t.route[n-1].z!==i.z||n+1\u003ct.route.length\u0026\u0026t.route[n+1].z!==i.z)};let s=i-1,a=i;for(;s\u003e0\u0026\u0026!r(s);)s--;for(;a\u003ct.route.length-1\u0026\u0026!r(a);)a++;const c=`${o}:${s}:${a}`;if(n.has(c))continue;n.add(c);const l=t.route[s],d=t.route[a];if(l.x===d.x\u0026\u0026l.y===d.y)continue;const h=t=\u003et.x\u003e=this.mutableBounds.minX-g6\u0026\u0026t.x\u003c=this.mutableBounds.maxX+g6\u0026\u0026t.y\u003e=this.mutableBounds.minY-g6\u0026\u0026t.y\u003c=this.mutableBounds.maxY+g6;if(!h(l)||!h(d))continue;const u=new Set(t.route.slice(s,a+1).map(e=\u003ee.traceThickness??t.traceThickness));if(1!==u.size)continue;const p=[...u][0];if(\"path-search-node-limit\"===this.getWorkLimitReason())return;const m={nodesPopped:0,completionReason:\"no-path\"},g=g1({maxNodes:void 0===this.input.maxPathSearchNodes?void 0:Math.min(3e4,this.input.maxPathSearchNodes-this.pathSearchNodes),stats:m,allowLayerChanges:e,srj:this.input.srj,routes:this.routes,routeIndex:o,start:l,end:d,bounds:this.mutableBounds,traceThickness:p,gridSize:p\u003c=.1?p/2:.1,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1});this.pathSearchCalls++,this.pathSearchNodes+=m.nodesPopped,this.updateWorkStats(),g\u0026\u0026(yield{routeIndex:o,route:R6({...t,route:[...t.route.slice(0,s),...g,...t.route.slice(a+1)]})})}}preservesViaPermissions(t,e){const n=this.input.routes[t],o=this.getViaGeometry(n),i=this.getViaGeometry(e);return e.connectionName===n.connectionName\u0026\u0026e.rootConnectionName===n.rootConnectionName\u0026\u0026e.viaDiameter===n.viaDiameter\u0026\u0026o.length===i.length\u0026\u0026o.every((e,n)=\u003e{const o=i[n];if(JSON.stringify(e.layerSequence)!==JSON.stringify(o.layerSequence)||e.diameter!==o.diameter)return!1;const r=this.input.movableVias?.some(e=\u003ee.routeIndex===t\u0026\u0026e.viaIndex===n);return!0===r||e.x===o.x\u0026\u0026e.y===o.y})}getIndexedViaIds(t,e,n){const o=new Set;if(1!==this.getViaGeometry(e).filter(t=\u003et.x===n.x\u0026\u0026t.y===n.y\u0026\u0026t.identity===n.identity).length)return o;const i=t=\u003e0===t?\"top\":t===this.input.srj.layerCount-1?\"bottom\":`inner${t}`,r=new Set;for(let t=1;t\u003cn.layerSequence.length;t++)r.add(`${n.x},${n.y},${i(n.layerSequence[t-1])},${i(n.layerSequence[t])}`);const s=this.routes.map((n,o)=\u003e{const i=this.getRouteCache(o,o===t?e:n).trace;if(!i)throw new Error(\"repair04: indexed via mapping requires an evaluated route\");return i}),a=new Set;for(const e of[...this.fixedTraces,...s])for(const n of e.route){if(\"via\"!==n.route_type)continue;const i=`${n.x},${n.y},${n.from_layer},${n.to_layer}`;if(a.has(i))continue;const c=`via_${a.size}`;a.add(i),e===s[t]\u0026\u0026r.has(i)\u0026\u0026o.add(c)}return o.size===r.size?o:new Set}*generateViaBlockerCandidates(t,e,n={}){if(this.viaBlockerPathSearchCalls\u003e=4||this.getWorkLimitReason())return;const o=e.evaluatedScore;if(!o||!this.score||e.additionalRoutes?.length||e.routeIndex!==t.routeIndex)return;if(!this.input.movableVias?.some(e=\u003ee.routeIndex===t.routeIndex\u0026\u0026e.viaIndex===t.viaIndex)||!this.preservesViaPermissions(t.routeIndex,e.route))return;if([...o.fixedViolations].some(([t,e])=\u003e!this.score.fixedViolations.has(t)||e\u003ethis.score.fixedViolations.get(t)+g6))return;const i=this.routes[t.routeIndex],r=this.getViaGeometry(i)[t.viaIndex],s=this.getViaGeometry(e.route)[t.viaIndex],a=n.oldIds??=this.getIndexedViaIds(t.routeIndex,i,r);if(!a.size)return;const c=`repair04_${t.routeIndex}`,l=(t,e)=\u003e{const n=t.pcb_via_id,o=t.pcb_trace_id;if(\"pcb_trace_error\"===t.type\u0026\u0026\"string\"==typeof n\u0026\u0026e.has(n)\u0026\u0026\"string\"==typeof o\u0026\u0026o!==c\u0026\u0026t.pcb_trace_error_id===`overlap_${o}_${n}`\u0026\u0026Array.isArray(t.pcb_trace_ids)\u0026\u00262===t.pcb_trace_ids.length\u0026\u0026t.pcb_trace_ids.includes(c)\u0026\u0026t.pcb_trace_ids.includes(o))return o},d=(t,e)=\u003e{const n=new Set;for(const o of t){const t=l(o,e);void 0!==t\u0026\u0026n.add(t)}return n},h=n.oldContacts??=d(this.score.errors,a);if(!h.size)return;if(n.oldNeighborFixed??=this.getFixedViolations(this.routes).some(t=\u003e\"wire\"===t.kind\u0026\u0026h.has(`repair04_${t.routeIndex}`)))return;const u=this.getIndexedViaIds(t.routeIndex,e.route,s);if(a.size!==u.size)return;for(const t of o.errors){if([t.pcb_via_id,...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids:[],...Array.isArray(t.pcb_pad_ids)?t.pcb_pad_ids:[]].some(t=\u003e\"string\"==typeof t\u0026\u0026u.has(t))\u0026\u0026void 0===l(t,u))return}const p=d(o.errors,u);if(1!==p.size||[...p].some(t=\u003eh.has(t)))return;const m=[...p][0];if(!/^repair04_(0|[1-9][0-9]*)$/.test(m))return;const g=Number(m.slice(9)),f=this.routes[g];if(!f||g===t.routeIndex||f.jumpers?.length||f.connectionName===i.connectionName||f.rootConnectionName\u0026\u0026f.rootConnectionName===i.rootConnectionName||f.route.some(t=\u003eBoolean(t.toNextSegmentType||t.insideJumperPad)))return;let y=-1,_=1/0;for(let t=1;t\u003cf.route.length;t++){const e=f.route[t-1],n=f.route[t];if(e.z!==n.z||e.z\u003cs.minZ||e.z\u003es.maxZ)continue;const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,a=r?Math.max(0,Math.min(1,((s.x-e.x)*o+(s.y-e.y)*i)/r)):0,c=Math.hypot(s.x-e.x-a*o,s.y-e.y-a*i);c\u003c_\u0026\u0026(_=c,y=t)}if(y\u003c1)return;const b=t=\u003e{const e=f.route[t];return this.isLocked(g,e)||t\u003e0\u0026\u0026f.route[t-1].z!==e.z||t+1\u003cf.route.length\u0026\u0026f.route[t+1].z!==e.z};let x=y-1,v=y;for(;x\u003e0\u0026\u0026!b(x);)x--;for(;v\u003cf.route.length-1\u0026\u0026!b(v);)v++;const S=f.route[x],I=f.route[v],C=t=\u003et.x\u003e=this.mutableBounds.minX-g6\u0026\u0026t.x\u003c=this.mutableBounds.maxX+g6\u0026\u0026t.y\u003e=this.mutableBounds.minY-g6\u0026\u0026t.y\u003c=this.mutableBounds.maxY+g6;if(S.z!==I.z||!C(S)||!C(I))return;const P=S.traceThickness??f.traceThickness;if(f.route.slice(x,v+1).some(t=\u003e(t.traceThickness??f.traceThickness)!==P))return;const M=Math.min(3e4,void 0===this.input.maxPathSearchNodes?3e4:this.input.maxPathSearchNodes-this.pathSearchNodes);if(M\u003c1)return;const N=this.routes.slice();N[t.routeIndex]=e.route;const w={nodesPopped:0,completionReason:\"no-path\"},T=g1({srj:this.input.srj,routes:N,routeIndex:g,start:I,end:S,bounds:this.mutableBounds,traceThickness:P,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,gridSize:Math.max(.025,P/4),allowLayerChanges:!1,maxNodes:M,stats:w});if(this.viaBlockerPathSearchCalls++,this.pathSearchCalls++,this.pathSearchNodes+=w.nodesPopped,this.updateWorkStats(),!T)return;T.reverse();const R={...f,route:[...f.route.slice(0,x),...T,...f.route.slice(v+1)]};E6(R)===E6(f)\u0026\u0026(yield{routeIndex:e.routeIndex,route:e.route,additionalRoutes:[{routeIndex:g,route:R}]})}*generateExistingViaCandidates(){for(const t of this.input.movableVias??[]){const e=this.routes[t.routeIndex],n=this.getViaGeometry(e)[t.viaIndex];if(n.pointIndices.some(n=\u003ethis.isLocked(t.routeIndex,e.route[n])))continue;const o={};for(const i of[.025,.05,.1,.2,.35,.5,.8,1.2])for(let r=0;r\u003c16;r++){const s=n.x+i*Math.cos(r*Math.PI/8),a=n.y+i*Math.sin(r*Math.PI/8);if(!T6({x:s,y:a,z:n.minZ},this.mutableBounds))continue;const c=e.route.map((t,e)=\u003en.pointIndices.includes(e)?{...t,x:s,y:a}:t),l={routeIndex:t.routeIndex,route:R6({...e,route:c})};yield l,yield*this.generateViaBlockerCandidates(t,l,o)}}}*generateCandidates(){yield*this.generateExistingViaCandidates();for(const t of!0===this.input.allowLayerChanges?!1===this.input.traceOnlyFirst?[!0]:[!1,!0]:[!1]){if(\"path-search-node-limit\"===this.getWorkLimitReason())return;const e=!0===this.input.allowLayerChanges?Math.min(512,Math.floor(this.maxCandidates/4)):Number.MAX_SAFE_INTEGER;if(!t\u0026\u00260===e)continue;let n=0;for(const o of this.generateCandidatesForMode(t)){if(!t){if([o,...o.additionalRoutes??[]].some(({routeIndex:t,route:e})=\u003ethis.input.movableVias?.length?!this.preservesViaPermissions(t,e):E6(e)!==E6(this.routes[t])))continue;if(n++\u003e=e)break}yield o}}}*generateCandidatesForMode(t){const e=this.score.errors.flatMap(t=\u003e{const e=t.center??t.pcb_center;return e?[e]:[]}),n=[];for(let t=0;t\u003cthis.routes.length;t++){const o=this.routes[t];if(!o.jumpers?.length\u0026\u0026!o.route.some(t=\u003et.toNextSegmentType||t.insideJumperPad))for(let i=1;i\u003co.route.length;i++){const r=o.route[i-1],s=o.route[i];if(r.toNextSegmentType||r.insideJumperPad||s.insideJumperPad)continue;let a=1/0,c=.5;const l=s.x-r.x,d=s.y-r.y,h=l*l+d*d;for(const t of e){const e=h?Math.max(0,Math.min(1,((t.x-r.x)*l+(t.y-r.y)*d)/h)):0,n=Math.hypot(t.x-r.x-e*l,t.y-r.y-e*d);n\u003ca\u0026\u0026(a=n,c=e)}a\u003c1.5\u0026\u0026n.push({ri:t,pi:i,distance:a,t:c})}}if(n.sort((t,e)=\u003et.distance-e.distance||t.ri-e.ri||t.pi-e.pi),this.threeRoutePathSearchCalls\u003c18\u0026\u0026!this.getWorkLimitReason()){const t=function*(t){const{routes:e}=t,n=t.violations.filter(t=\u003e\"wire\"===t.kind).sort((t,e)=\u003ee.severity-t.severity||t.routeIndex-e.routeIndex||t.obstacleIndex-e.obstacleIndex);if(!n.length||t.maxSearchCalls\u003c=0||t.remainingNodes()\u003c=0)return;const o=[];let i=0;const r=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r?Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r)):0;return Math.hypot(t.x-e.x-s*o,t.y-e.y-s*i)},s=(t,e)=\u003e{const n=t.route[e],o=t.route[e-1],i=t.route[e+1];return void 0!==o\u0026\u0026o.z!==n.z||void 0!==i\u0026\u0026i.z!==n.z},a=e=\u003e{const n=t.bounds;return e.x\u003e=n.minX-1e-8\u0026\u0026e.x\u003c=n.maxX+1e-8\u0026\u0026e.y\u003e=n.minY-1e-8\u0026\u0026e.y\u003c=n.maxY+1e-8};for(let n=0;n\u003ce.length;n++){const i=e[n];if(i.jumpers?.length||i.route.some(t=\u003eBoolean(t.toNextSegmentType||t.insideJumperPad)))continue;const r=e=\u003et.isLocked(n,e)||s(i,e);for(let t=0;t\u003ci.route.length-1;){let e=t+1;if(i.route[t].z!==i.route[e].z){t=e;continue}for(;e\u003ci.route.length-1\u0026\u0026!r(e)\u0026\u0026i.route[e+1].z===i.route[t].z;)e++;const c=i.route[t].traceThickness??i.traceThickness;e\u003et\u0026\u0026a(i.route[t])\u0026\u0026a(i.route[e])\u0026\u0026i.route.slice(t,e+1).every(t=\u003e(t.traceThickness??i.traceThickness)===c)\u0026\u0026o.push({ri:n,a:t,b:e,z:i.route[t].z,width:c,distance:1/0,viaEnds:Number(s(i,t))+Number(s(i,e))}),t=e}}const c=new Set;for(const s of n){for(const t of o){t.distance=1/0;const n=e[t.ri];for(let e=t.a+1;e\u003c=t.b;e++)t.distance=Math.min(t.distance,r(s.center,n.route[e-1],n.route[e]))}const n=o.filter(t=\u003et.ri===s.routeIndex).sort((t,e)=\u003et.distance-e.distance||t.a-e.a)[0];if(!n||n.distance\u003e.5)continue;const a=e[n.ri],l=o.filter(t=\u003et.ri!==n.ri\u0026\u0026t.z===n.z\u0026\u0026t.distance\u003c1.5\u0026\u0026e[t.ri].connectionName!==a.connectionName\u0026\u0026(!a.rootConnectionName||e[t.ri].rootConnectionName!==a.rootConnectionName)).sort((t,e)=\u003et.distance-e.distance||t.ri-e.ri||t.a-e.a),d=l[0],h=l.find(t=\u003et.ri!==d?.ri);if(!d||!h)continue;const u=[n,d,h],p=u.map(t=\u003e`${t.ri}:${t.a}:${t.b}`).join(\"|\");if(c.has(p))continue;c.add(p);const m=d.viaEnds\u003e=h.viaEnds?1:2,g=3-m,f=[[m,0,g],[0,1,2],[0,2,1],[1,2,0],[2,1,0],[g,0,m]],y=new Set;for(const n of f){if(y.has(n.join()))continue;y.add(n.join());const o=e.map(t=\u003e({...t}));for(const t of u){const n=e[t.ri];o[t.ri]={...n,route:n.route.slice(0,t.a+1)},o.push({...n,route:n.route.slice(t.b)})}let r=!0;for(const s of n){if(i\u003e=t.maxSearchCalls||t.remainingNodes()\u003c=0)return;const n=u[s],a=e[n.ri],c={nodesPopped:0,completionReason:\"no-path\"},l=g1({srj:t.srj,routes:o,routeIndex:n.ri,start:a.route[n.b],end:a.route[n.a],bounds:t.bounds,traceThickness:n.width,traceClearance:t.traceClearance,viaClearance:t.viaClearance,gridSize:Math.max(.025,n.width/4),allowLayerChanges:!1,maxNodes:Math.min(3e4,t.remainingNodes()),stats:c});if(i++,t.onSearch(c),!l){r=!1;break}l.reverse(),o[n.ri]={...a,route:[...a.route.slice(0,n.a),...l,...a.route.slice(n.b+1)]},o[e.length+s].route=[]}r\u0026\u0026(yield u.map(t=\u003e({routeIndex:t.ri,route:o[t.ri]})))}}}({srj:this.input.srj,routes:this.routes,bounds:this.mutableBounds,violations:this.getFixedViolations(this.routes),isLocked:(t,e)=\u003ethis.isLocked(t,this.routes[t].route[e]),traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,maxSearchCalls:18-this.threeRoutePathSearchCalls,remainingNodes:()=\u003eMath.min(5e5-this.threeRoutePathSearchNodes,void 0===this.input.maxPathSearchNodes?Number.MAX_SAFE_INTEGER:this.input.maxPathSearchNodes-this.pathSearchNodes),onSearch:t=\u003e{this.threeRoutePathSearchCalls++,this.threeRoutePathSearchNodes+=t.nodesPopped,this.pathSearchCalls++,this.pathSearchNodes+=t.nodesPopped,this.updateWorkStats()}});for(const[e,...n]of t)e\u0026\u0026(yield{...e,additionalRoutes:n})}if(t\u0026\u0026(yield*this.generateCrossingPairCandidates()),yield*this.generateTaperedSegmentCandidates(n),yield*this.generateClearanceCandidates(n,t),\"path-search-node-limit\"===this.getWorkLimitReason())return;const o=new Set;for(const{ri:e,pi:i}of n.slice(0,80)){const n=this.routes[e];for(const r of[2,4,8,16]){const s=Math.max(0,i-r),a=Math.min(n.route.length-1,i+r),c=`${e}:${s}:${a}`;if(o.has(c))continue;o.add(c);const l=n.route[s],d=n.route[a];if(l.z!==d.z||!T6(l,this.mutableBounds)||!T6(d,this.mutableBounds))continue;if(n.route.slice(s+1,a).some(t=\u003ethis.isLocked(e,t)))continue;const h=new Set(n.route.slice(s,a+1).map(t=\u003et.traceThickness??n.traceThickness));if(1!==h.size)continue;const u=[...h][0],p=d.x-l.x,m=d.y-l.y,g=Math.hypot(p,m);if(!(g\u003c.1)){yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),...n.route.slice(a)]})};for(const t of[.15,-.15,.35,-.35,.7,-.7,1.5,-1.5])for(const o of[.2,0]){const i={x:l.x+p*o-m/g*t,y:l.y+m*o+p/g*t,z:l.z,traceThickness:u},r={x:l.x+p*(1-o)-m/g*t,y:l.y+m*(1-o)+p/g*t,z:l.z,traceThickness:u};T6(i,this.mutableBounds)\u0026\u0026T6(r,this.mutableBounds)\u0026\u0026(yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),i,r,...n.route.slice(a)]})})}if(t\u0026\u0026g\u003e2*n.viaDiameter+.3)for(let t=0;t\u003cthis.input.srj.layerCount;t++){if(t===l.z)continue;const o={x:l.x+.2*p,y:l.y+.2*m,z:l.z,traceThickness:u},i={x:l.x+.8*p,y:l.y+.8*m,z:l.z,traceThickness:u};yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),o,{...o,z:t},{...i,z:t},i,...n.route.slice(a)]})}}}}}const i=new Set;for(const{ri:e,pi:o,t:r}of n){const n=this.routes[e],s=n.route[o-1],a=n.route[o];for(const t of[o-1,o]){const o=n.route[t],r=`${e}:${o.x}:${o.y}`;if(i.has(r))continue;i.add(r);const s=n.route.map((t,e)=\u003et.x===o.x\u0026\u0026t.y===o.y?e:-1).filter(t=\u003et\u003e=0);if(!s.some(t=\u003ethis.isLocked(e,n.route[t])))for(const t of[.025,.05,.1,.2,.35,.5,.8,1.2])for(let o=0;o\u003c16;o++){const i=t*Math.cos(o*Math.PI/8),r=t*Math.sin(o*Math.PI/8),a=n.route.map((t,e)=\u003es.includes(e)?{...t,x:t.x+i,y:t.y+r}:t);s.some(t=\u003e!T6(a[t],this.mutableBounds))||(yield{routeIndex:e,route:R6({...n,route:a})})}}const c=t=\u003et.x\u003e=this.mutableBounds.minX-1e-8\u0026\u0026t.x\u003c=this.mutableBounds.maxX+1e-8\u0026\u0026t.y\u003e=this.mutableBounds.minY-1e-8\u0026\u0026t.y\u003c=this.mutableBounds.maxY+1e-8;if(s.z!==a.z||!c(s)||!c(a))continue;const l=a.x-s.x,d=a.y-s.y,h=Math.hypot(l,d);if(h\u003c.02)continue;const u=Math.max(s.traceThickness??n.traceThickness,a.traceThickness??n.traceThickness),p=l/h,m=d/h;for(const i of[.4,.8,1.5,3]){const a=Math.max(0,r*h-i),c=Math.min(h,r*h+i);for(const t of[.12,-.12,.25,-.25,.5,-.5,1,-1]){const i={x:s.x+p*a-m*t,y:s.y+m*a+p*t,z:s.z,traceThickness:u},r={x:s.x+p*c-m*t,y:s.y+m*c+p*t,z:s.z,traceThickness:u};T6(i,this.mutableBounds)\u0026\u0026T6(r,this.mutableBounds)\u0026\u0026(yield{routeIndex:e,route:{...n,route:[...n.route.slice(0,o),i,r,...n.route.slice(o)]}})}if(!t||c-a\u003cn.viaDiameter+.15)continue;const l={x:s.x+p*a,y:s.y+m*a,z:s.z,traceThickness:u},d={x:s.x+p*c,y:s.y+m*c,z:s.z,traceThickness:u};if(T6(l,this.mutableBounds)\u0026\u0026T6(d,this.mutableBounds))for(let t=0;t\u003cthis.input.srj.layerCount;t++){if(t===s.z)continue;const i=[l,{...l,z:t},{...d,z:t},d];yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,o),...i,...n.route.slice(o)]})}}}}}_step(){this.score||(this.score=this.evaluate(this.routes),this.stats={initialErrorCount:this.score.count,finalErrorCount:this.score.count,candidates:0,accepted:0},this.candidates=this.generateCandidates(),this.updateWorkStats());const t=this.getWorkLimitReason();if(0===this.score.count||this.evaluated\u003e=this.maxCandidates||t)return void this.finishSearch(0===this.score.count?\"clean\":this.evaluated\u003e=this.maxCandidates?\"candidate-limit\":t);const e=this.candidates.next();if(e.done){const t=this.getWorkLimitReason();return t?void this.finishSearch(t):void(this.bestAdjustment?(this.routes=this.bestAdjustment.routes,this.candidateScores.clear(),this.score=this.bestAdjustment.score,this.bestAdjustment=null,this.accepted++,this.candidates=this.generateCandidates()):(this.updateWorkStats(\"search-exhausted\"),this.solved=!0))}this.candidateAttempts++,this.updateWorkStats();const n=[e.value,...e.value.additionalRoutes??[]];if((!0!==this.input.allowLayerChanges||this.input.movableVias?.length)\u0026\u0026n.some(({routeIndex:t,route:e})=\u003e!this.preservesViaPermissions(t,e)))return;const o=this.routes.slice();for(const{routeIndex:t,route:e}of n)o[t]=e;const i=new Map;for(const t of this.getFixedViolations(o))i.set(t.key,t.severity);const r=[...i].every(([t,e])=\u003ethis.score.fixedViolations.has(t)\u0026\u0026e\u003c=this.score.fixedViolations.get(t)+g6),s=0===this.getViaPadViolations(o,!1).length;let a;if(s\u0026\u0026r){const t=JSON.stringify([e.value.routeIndex,e.value.route,...e.value.additionalRoutes??[]]);a=this.candidateScores.get(t),a||(a=this.evaluate(o),this.candidateScores.size\u003e=128\u0026\u0026this.candidateScores.delete(this.candidateScores.keys().next().value),this.candidateScores.set(t,a))}e.value.evaluatedScore=a,this.evaluated++,a\u0026\u0026s\u0026\u0026r\u0026\u0026a.count\u003cthis.score.count?(this.routes=o,this.candidateScores.clear(),this.score=a,this.accepted++,this.bestAdjustment=null,this.candidates=this.generateCandidates()):a\u0026\u0026r\u0026\u0026s\u0026\u0026a.count===this.score.count\u0026\u0026a.severity\u003c(this.bestAdjustment?.score.severity??this.score.severity)-1e-6\u0026\u0026(this.bestAdjustment={routes:o,score:a}),this.stats={...this.stats,finalErrorCount:this.score.count,candidates:this.evaluated,accepted:this.accepted},this.progress=this.evaluated/this.maxCandidates}getConstructorParams(){return[structuredClone(this.input)]}getOutput(){if(!this.solved||this.failed)throw new Error(\"repair04: getOutput requires a completed solve\");return structuredClone(this.routes)}visualize(){const t=this.input.bounds,e=this.mutableBounds;return{title:\"repair04 — fixed boundary, local copper repair\",rects:[{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,stroke:\"#64748b\",fill:\"rgba(148,163,184,0.15)\"},{center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,stroke:\"#0891b2\",fill:\"transparent\"},...this.input.srj.obstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,fill:\"rgba(239,68,68,0.22)\",stroke:\"#b91c1c\",layer:`z${t.layers.map(t=\u003e\"top\"===t?0:\"bottom\"===t?this.input.srj.layerCount-1:Number(t.slice(5))).join(\",\")}`}))],lines:this.routes.flatMap(t=\u003et.route.slice(1).flatMap((e,n)=\u003ee.z===t.route[n].z?[{points:[t.route[n],e],strokeColor:0===e.z?\"#dc2626\":\"rgba(37,99,235,0.65)\",strokeWidth:e.traceThickness??t.traceThickness,...0===e.z?{}:{strokeDash:[.2,.12]},layer:`z${e.z}`}]:[])),circles:this.routes.flatMap(t=\u003et.vias.map(e=\u003e{const n=t.route.filter(t=\u003et.x===e.x\u0026\u0026t.y===e.y).map(t=\u003et.z),o=Math.min(...n),i=Math.max(...n);return{center:e,radius:t.viaDiameter/2,fill:\"rgba(37,99,235,0.65)\",stroke:\"#1e40af\",layer:`z${Array.from({length:i-o+1},(t,e)=\u003eo+e).join(\",\")}`}})),points:this.lockedPoints.flat().map(t=\u003e({...t,color:\"#0f172a\",layer:`z${t.z}`}))}}},O6=(t,e,n)=\u003e{if(n\u003c=g6)return structuredClone(t);if(n\u003e=.99999999)return structuredClone(e);const o={...structuredClone(t),x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n};return delete o.start_pcb_port_id,delete o.end_pcb_port_id,o},k6=(t,e)=\u003e{const n=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,s=e.start.x-t.start.x,a=e.start.y-t.start.y,c=n*r-o*i,l=(t,e)=\u003e({x:t.start.x+(t.end.x-t.start.x)*e,y:t.start.y+(t.end.y-t.start.y)*e}),d=(t,e)=\u003e{const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=n*n+o*o,r=i\u003e10000000000000001e-32?Math.max(0,Math.min(1,((t.x-e.start.x)*n+(t.y-e.start.y)*o)/i)):0;return l(e,r)};if(Math.abs(c)\u003eg6){const e=(s*r-a*i)/c,d=(s*o-a*n)/c;if(e\u003e=0\u0026\u0026e\u003c=1\u0026\u0026d\u003e=0\u0026\u0026d\u003c=1){const n=l(t,e);return[n,n]}}else{const i=n*n+o*o;if(i\u003e10000000000000001e-32){const r=(s*n+a*o)/i,c=((e.end.x-t.start.x)*n+(e.end.y-t.start.y)*o)/i,h=Math.max(0,Math.min(r,c)),u=Math.min(1,Math.max(r,c));if(h\u003c=u){const n=l(t,(h+u)/2);return[n,d(n,e)]}}}const h=[[t.start,d(t.start,e)],[t.end,d(t.end,e)],[d(e.start,t),e.start],[d(e.end,t),e.end]];return h.sort((t,e)=\u003eMath.hypot(t[0].x-t[1].x,t[0].y-t[1].y)-Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y)),h[0]},L6=(t,e)=\u003e{const n=\"top\"===t?0:\"bottom\"===t?e-1:/^inner\\d+$/.test(t)?Number(t.slice(5)):-1;if(!Number.isInteger(n)||n\u003c0||n\u003e=e)throw new Error(`repair04 preload has an unknown layer: ${t}`);return n},D6=(t,e,n)=\u003e{const o=((t,e)=\u003e{const n=new Map,o=t=\u003e{const e=n.get(t);if(void 0===e||e===t)return t;const i=o(e);return n.set(t,i),i},i=t=\u003e{const e=t.filter(t=\u003e\"string\"==typeof t\u0026\u0026t.length\u003e0);if(0===e.length)return;const i=o(e[0]);for(const t of e)n.set(o(t),i)};for(const e of t.connections){const t=e;i([t.name,t.rootConnectionName,t.netConnectionName,t.__netConnectionName,...t.mergedConnectionNames??[],...t.__rootConnectionNames??[]])}for(const t of e)i([t.connectionName,t.rootConnectionName]);for(const e of t.traces??[])i([e.connection_name,...e.connectsTo??[]]);return o})(t,e),i=e.map((t,e)=\u003ee),r=t=\u003e{const e=i[t];if(e===t)return t;const n=r(e);return i[t]=n,n},s=new Map;for(let t=0;t\u003ce.length;t+=1){const n=e[t];for(const e of[n.route[0],n.route.at(-1)]){if(!e?.pcb_port_id)continue;const a=JSON.stringify([o(n.connectionName),e.pcb_port_id,e.x,e.y,e.z]),c=s.get(a);void 0===c?s.set(a,t):i[r(t)]=r(c)}}const a=(t,e)=\u003e!(!t.startsWith(\"route:\")||!e.startsWith(\"route:\"))\u0026\u0026r(Number(t.slice(6)))===r(Number(e.slice(6))),c=[],l=[],d=[],h=e.map(()=\u003e({segmentTimes:new Map,viaPositions:[]})),u=t=\u003e{if(f6(t,n)){d.push(t);for(let e=t.minZ;e\u003c=t.maxZ;e+=1)c.push({x:t.x,y:t.y,z:e,radius:t.radius,net:t.net,source:t.source,...void 0!==t.routeIndex?{viaOwner:t.routeIndex}:{}})}};for(let t=0;t\u003ce.length;t+=1){const i=e[t],r=o(i.connectionName),s=`route:${t}`;for(let e=0;e\u003ci.route.length;e+=1){const o=i.route[e];if((0===e||e===i.route.length-1||o.pcb_port_id)\u0026\u0026f6(o,n)\u0026\u0026c.push({x:o.x,y:o.y,z:o.z,radius:(o.traceThickness??i.traceThickness)/2,net:r,source:s}),0===e)continue;const a=i.route[e-1];\"through_obstacle\"!==a.toNextSegmentType\u0026\u0026(a.z===o.z?l.push({start:a,end:o,z:o.z,radius:Math.max(a.traceThickness??i.traceThickness,o.traceThickness??i.traceThickness)/2,net:r,source:s,routeIndex:t,segmentIndex:e-1}):u({x:o.x,y:o.y,minZ:Math.min(a.z,o.z),maxZ:Math.max(a.z,o.z),radius:i.viaDiameter/2,net:r,source:s,routeIndex:t}))}}for(let e=0;e\u003c(t.traces??[]).length;e+=1){const i=m1(t.traces[e],t.minTraceWidth),r=o(i.connection_name),s=`fixed:${e}`;for(let e=0;e\u003ci.route.length;e+=1){const o=i.route[e],a=i.route[e-1];if(\"wire\"===o.route_type){const d=L6(o.layer,t.layerCount);(0===e||e===i.route.length-1||o.start_pcb_port_id||o.end_pcb_port_id)\u0026\u0026f6(o,n)\u0026\u0026c.push({x:o.x,y:o.y,z:d,radius:o.width/2,net:r,source:s}),\"wire\"===a?.route_type\u0026\u0026a.layer===o.layer\u0026\u0026l.push({start:a,end:o,z:d,radius:Math.max(a.width,o.width)/2,net:r,source:s})}else if(\"via\"===o.route_type){const e=L6(o.from_layer,t.layerCount),n=L6(o.to_layer,t.layerCount);u({x:o.x,y:o.y,minZ:Math.min(e,n),maxZ:Math.max(e,n),radius:(o.via_diameter??t.minViaDiameter??.3)/2,net:r,source:s})}}}const p=new Map;for(const t of c){const e=JSON.stringify([t.net,t.z]),n=p.get(e)??[];n.push(t),p.set(e,n)}const m=(t,e)=\u003e{if(void 0===t)return;const n=h[t].viaPositions;n.some(t=\u003eMath.hypot(t.x-e.x,t.y-e.y)\u003c=g6)||n.push({x:e.x,y:e.y})};for(const t of l){if(!y6(t.start,t.end,n))continue;const e=t.end.x-t.start.x,o=t.end.y-t.start.y,i=e*e+o*o;if(!(i\u003c=10000000000000001e-32))for(const r of p.get(JSON.stringify([t.net,t.z]))??[]){if(r.source===t.source||a(r.source,t.source))continue;const s=Math.max(0,Math.min(1,((r.x-t.start.x)*e+(r.y-t.start.y)*o)/i)),c={x:t.start.x+e*s,y:t.start.y+o*s};if(f6(c,n)\u0026\u0026!(Math.hypot(c.x-r.x,c.y-r.y)\u003et.radius+r.radius+g6)){if(void 0!==t.routeIndex\u0026\u0026void 0!==t.segmentIndex){const e=h[t.routeIndex].segmentTimes.get(t.segmentIndex)??[];e.some(t=\u003eMath.abs(t-s)\u003c=g6)||e.push(s),h[t.routeIndex].segmentTimes.set(t.segmentIndex,e)}m(r.viaOwner,r)}}}for(const t of d)for(let e=t.minZ;e\u003c=t.maxZ;e+=1)for(const n of p.get(JSON.stringify([t.net,e]))??[])n.source===t.source||a(n.source,t.source)||Math.hypot(t.x-n.x,t.y-n.y)\u003et.radius+n.radius+g6||(m(t.routeIndex,t),m(n.viaOwner,n));return((t,e,n,o)=\u003e{const i=new Map,r=new Set,s=[],a=(t,e)=\u003e{if(void 0===t.routeIndex||void 0===t.segmentIndex)return;const o=t.end.x-t.start.x,i=t.end.y-t.start.y,r=o*o+i*i;if(r\u003c=10000000000000001e-32)return;const s=Math.max(0,Math.min(1,((e.x-t.start.x)*o+(e.y-t.start.y)*i)/r)),a=n[t.routeIndex].segmentTimes.get(t.segmentIndex)??[];a.some(t=\u003eMath.abs(t-s)\u003c=g6)||a.push(s),n[t.routeIndex].segmentTimes.set(t.segmentIndex,a)};for(const n of t){const t=y6(n.start,n.end,e);if(!t||t[1]-t[0]\u003c=g6)continue;const c=t=\u003e({x:n.start.x+(n.end.x-n.start.x)*t,y:n.start.y+(n.end.y-n.start.y)*t}),l={...n,start:c(t[0]),end:c(t[1])},d=s.length;s.push({original:n,clipped:l});const h=Math.floor((Math.min(l.start.x,l.end.x)-l.radius)/2),u=Math.floor((Math.max(l.start.x,l.end.x)+l.radius)/2),p=Math.floor((Math.min(l.start.y,l.end.y)-l.radius)/2),m=Math.floor((Math.max(l.start.y,l.end.y)+l.radius)/2);for(let t=h;t\u003c=u;t+=1)for(let e=p;e\u003c=m;e+=1){const c=JSON.stringify([l.net,l.z,t,e]),h=i.get(c)??[];for(const t of h){const e=s[t];if(e.original.source===n.source||o(e.original.source,n.source)||void 0===e.original.routeIndex\u0026\u0026void 0===n.routeIndex)continue;const i=`${t}:${d}`;if(r.has(i))continue;r.add(i);const[c,h]=k6(l,e.clipped);Math.hypot(c.x-h.x,c.y-h.y)\u003el.radius+e.clipped.radius+g6||(a(n,c),a(e.original,h))}h.push(d),i.set(c,h)}}})(l,n,h,a),h},z6=(t,e)=\u003e({minX:t.minX-e,maxX:t.maxX+e,minY:t.minY-e,maxY:t.maxY+e}),F6=(t,e,n,o)=\u003e{const i=[];let r;const s=t.route,a=t=\u003e0===t||t===s.length-1||void 0!==s[t]?.pcb_port_id,c=()=\u003e{void 0!==r\u0026\u0026r.points.length\u003e0\u0026\u0026(r.locks[0]=!0,r.locks[r.points.length-1]=!0,i.push(r)),r=void 0};if(1===s.length\u0026\u0026s[0]\u0026\u0026f6(s[0],e))return[{points:structuredClone(s),locks:[!0],start:{segmentIndex:0,t:0},end:{segmentIndex:0,t:0}}];for(let i=0;i\u003cs.length-1;i+=1){const l=s[i],d=s[i+1];if(!l||!d)throw new Error(\"repair04 found a missing route point\");if(![l.x,l.y,l.z,d.x,d.y,d.z].every(Number.isFinite))throw new Error(\"repair04 route coordinates must be finite\");if(l.z!==d.z\u0026\u0026!b6({x:l.x,y:l.y},{x:d.x,y:d.y})\u0026\u0026\"through_obstacle\"!==l.toNextSegmentType)throw new Error(\"repair04 requires colocated points at a via transition\");const h=y6(l,d,e);if(!h){c();continue}const[u,p]=h;if(p-u\u003c=g6\u0026\u0026!b6(l,d)){c();continue}const m=y6(l,d,n),g=[u,p],f=o.segmentTimes.get(i)??[];for(const t of f)t\u003e=u-g6\u0026\u0026t\u003c=p+g6\u0026\u0026g.push(Math.max(u,Math.min(p,t)));if(m\u0026\u0026l.z===d.z)for(const t of m)t\u003eu+g6\u0026\u0026t\u003cp-g6\u0026\u0026g.push(t);g.sort((t,e)=\u003et-e);const y=g.filter((t,e)=\u003e0===e||Math.abs(t-g[e-1])\u003eg6),_=_6(l,d,u);r\u0026\u0026!b6(r.points[r.points.length-1],_)\u0026\u0026c(),r||(r={points:[],locks:[],start:{segmentIndex:i,t:u},end:{segmentIndex:i,t:p}});for(const e of y){const s=_6(l,d,e),c=e\u003c=g6?i:e\u003e=.99999999?i+1:void 0,h=!f6(s,n,4e-8)||f.some(t=\u003eMath.abs(t-e)\u003c=g6)||o.viaPositions.some(t=\u003eMath.hypot(t.x-s.x,t.y-s.y)\u003c=g6)||void 0!==c\u0026\u0026a(c)||\"through_obstacle\"===l.toNextSegmentType||\"through_obstacle\"===s.toNextSegmentType||!0===l.insideJumperPad||!0===d.insideJumperPad||(t.jumpers??[]).some(t=\u003eb6(s,{...t.start,z:s.z})||b6(s,{...t.end,z:s.z})),u=r.points[r.points.length-1];u\u0026\u0026b6(u,s)?r.locks[r.locks.length-1]=r.locks[r.locks.length-1]||h:(r.points.push(s),r.locks.push(h))}r.end={segmentIndex:i,t:p},p\u003c.99999999\u0026\u0026c()}c();for(const t of i)for(let e=1;e\u003ct.points.length;e+=1){const n=t.points[e-1],o=t.points[e];if(n.z!==o.z\u0026\u0026(t.locks[e-1]||t.locks[e])){let n=e-1,i=e;for(;n\u003e0\u0026\u0026b6({x:t.points[n-1].x,y:t.points[n-1].y},{x:o.x,y:o.y});)n-=1;for(;i+1\u003ct.points.length\u0026\u0026b6({x:t.points[i+1].x,y:t.points[i+1].y},{x:o.x,y:o.y});)i+=1;for(let e=n;e\u003c=i;e+=1)t.locks[e]=!0}}return i},B6=(t,e)=\u003e{const n=t.bounds,o=t.outline\u0026\u0026t.outline.length\u003e=3?t.outline:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}],i=[];for(let n=0;n\u003co.length;n+=1){const r=o[n],s=o[(n+1)%o.length],a=y6(r,s,e);if(!a)continue;const c=s.x-r.x,l=s.y-r.y,d=Math.hypot(c,l);if(d\u003c=g6)continue;const h=(a[0]+a[1])/2;i.push({obstacleId:`repair04_board_edge_${n}`,type:\"rect\",center:{x:r.x+c*h,y:r.y+l*h},width:d*(a[1]-a[0]),height:Math.max(2*(t.minBoardEdgeClearance??0),g6),ccwRotationDegrees:180*Math.atan2(l,c)/Math.PI,layers:Array.from({length:t.layerCount},(e,n)=\u003e0===n?\"top\":n===t.layerCount-1?\"bottom\":`inner${n}`),zLayers:Array.from({length:t.layerCount},(t,e)=\u003ee),connectedTo:[]})}return i},j6=({srj:t,routes:e,bounds:n,boundaryMargin:o=.5,clearanceHalo:i})=\u003e{if((t=\u003e{if(!Object.values(t).every(Number.isFinite))throw new Error(\"repair04 bounds must contain finite coordinates\");if(t.maxX-t.minX\u003c9.99999999||t.maxY-t.minY\u003c9.99999999)throw new Error(\"repair04 requires bounds at least 10 mm by 10 mm\")})(n),!Number.isFinite(o)||o\u003c0||void 0!==i\u0026\u0026(!Number.isFinite(i)||i\u003c0))throw new Error(\"repair04 collar and halo must be finite and nonnegative\");const r=Math.max(t.defaultObstacleMargin??.2,t.minTraceToPadEdgeClearance??0,t.minViaEdgeToPadEdgeClearance??0);let s=Math.max(t.minTraceWidth,t.minViaDiameter??0);for(const t of e){s=Math.max(s,t.traceThickness,t.viaDiameter);for(const e of t.route)s=Math.max(s,e.traceThickness??0)}for(const e of t.traces??[])for(const n of e.route)\"wire\"===n.route_type\u0026\u0026(s=Math.max(s,n.width)),\"via\"===n.route_type\u0026\u0026(s=Math.max(s,n.via_diameter??t.minViaDiameter??.3));if(!Number.isFinite(s)||s\u003c=0)throw new Error(\"repair04 requires finite positive copper widths\");const a=Math.max(o,s+r);if(2*a\u003e=Math.min(n.maxX-n.minX,n.maxY-n.minY))throw new Error(\"repair04 bounds are too small for their required copper safety collar\");const c=z6(n,Math.max(i??a,r+s)),l=z6(n,-a),d=D6(t,e,c),h=((t,e,n)=\u003e{const o=[];for(const i of t){const t=m1(i,n),r=[];let s=[];const a=()=\u003e{s.length\u003e0\u0026\u0026r.push(s),s=[]},c=t=\u003e{x6(s[s.length-1])!==x6(t)\u0026\u0026s.push(structuredClone(t))};for(let n=0;n\u003ct.route.length;n+=1){const o=t.route[n],i=t.route[n-1];if(\"wire\"===o.route_type\u0026\u0026\"wire\"===i?.route_type\u0026\u0026o.layer===i.layer){const t=y6(i,o,e);if(!t){a();continue}const n=O6(i,o,t[0]),r=O6(i,o,t[1]),l=s[s.length-1];\"wire\"===l?.route_type\u0026\u0026(l.layer!==n.layer||Math.hypot(l.x-n.x,l.y-n.y)\u003eg6)\u0026\u0026a(),c(n),c(r),t[1]\u003c.99999999\u0026\u0026a()}else if(\"via\"===o.route_type){if(!f6(o,e)){a();continue}if(\"wire\"!==i?.route_type)throw new Error(\"repair04 normalized preload via has no incoming wire\");c(i),c(o);const r=t.route[n+1];if(\"wire\"!==r?.route_type)throw new Error(\"repair04 normalized preload via has no outgoing wire\");c(r)}else if(\"wire\"===o.route_type)f6(o,e)\u0026\u0026c(o);else if(\"start\"in o\u0026\u0026\"end\"in o){const t=y6(o.start,o.end,e);if(!t){a();continue}const n=t=\u003e({x:o.start.x+(o.end.x-o.start.x)*t,y:o.start.y+(o.end.y-o.start.y)*t});c({...structuredClone(o),start:n(t[0]),end:n(t[1])}),t[1]\u003c.99999999\u0026\u0026a()}}a();for(let t=0;t\u003cr.length;t+=1)o.push({...structuredClone(i),pcb_trace_id:1===r.length?i.pcb_trace_id:`${i.pcb_trace_id}__repair04_fixed_${t}`,route:r[t]})}return o})(t.traces??[],c,t.minTraceWidth),u=[],p=[],m=[];for(let t=0;t\u003ce.length;t+=1){const n=e[t];for(const e of F6(n,c,l,d[t])){const o={...structuredClone(Object.fromEntries(Object.entries(n).filter(([t])=\u003e\"route\"!==t\u0026\u0026\"vias\"!==t\u0026\u0026\"jumpers\"!==t))),connectionName:n.connectionName,traceThickness:n.traceThickness,viaDiameter:n.viaDiameter,route:e.points,vias:n.vias.filter(t=\u003ee.points.some(e=\u003eMath.abs(e.x-t.x)\u003c=g6\u0026\u0026Math.abs(e.y-t.y)\u003c=g6)).map(t=\u003estructuredClone(t)),...void 0!==n.jumpers?{jumpers:n.jumpers.filter(t=\u003evoid 0!==y6(t.start,t.end,c)).map(t=\u003estructuredClone(t))}:{}};u.push(o),p.push(e.locks),m.push({sourceRouteIndex:t,start:e.start,end:e.end,sourceGeometryKey:S6(n,e.start.segmentIndex+e.start.t,e.end.segmentIndex+e.end.t),originalFragment:structuredClone(o)})}}const g=new Set([...u.flatMap(t=\u003e[t.connectionName,...t.rootConnectionName?[t.rootConnectionName]:[]]),...h.map(t=\u003et.connection_name)]),f=t.connections.filter(t=\u003eg.has(t.name)||t.pointsToConnect.some(t=\u003ef6(t,c))).map(t=\u003e({...structuredClone(Object.fromEntries(Object.entries(t).filter(([t])=\u003e\"pointsToConnect\"!==t))),name:t.name,pointsToConnect:t.pointsToConnect.filter(t=\u003ef6(t,c)).map(t=\u003estructuredClone(t))}));for(let e=0;e\u003cu.length;e+=1){const n=u[e];let o=f.find(t=\u003et.name===n.connectionName);o||(o={name:n.connectionName,...n.rootConnectionName?{rootConnectionName:n.rootConnectionName}:{},pointsToConnect:[]},f.push(o));for(const[i,r]of[[\"start\",n.route[0]],[\"end\",n.route[n.route.length-1]]]){if(!r)continue;const n=0===r.z?\"top\":r.z===t.layerCount-1?\"bottom\":`inner${r.z}`;o.pointsToConnect.some(t=\u003eMath.abs(t.x-r.x)\u003c=g6\u0026\u0026Math.abs(t.y-r.y)\u003c=g6\u0026\u0026(\"layer\"in t?t.layer===n:t.layers.includes(n)))||o.pointsToConnect.push({x:r.x,y:r.y,layer:n,pointId:`repair04_${e}_${i}`,...r.pcb_port_id?{pcb_port_id:r.pcb_port_id}:{}})}}const y={...Object.fromEntries(Object.entries(t).filter(([t,e])=\u003e\"sourceCircuitJson\"!==t\u0026\u0026\"sourceKicadPcb\"!==t\u0026\u0026(\"number\"==typeof e||\"boolean\"==typeof e||\"string\"==typeof e))),layerCount:t.layerCount,minTraceWidth:t.minTraceWidth,bounds:structuredClone(c),obstacles:[...t.obstacles.filter(t=\u003e((t,e)=\u003e{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=(Math.abs(t.width*Math.cos(n))+Math.abs(t.height*Math.sin(n)))/2,i=(Math.abs(t.width*Math.sin(n))+Math.abs(t.height*Math.cos(n)))/2;return t.center.x+o\u003e=e.minX\u0026\u0026t.center.x-o\u003c=e.maxX\u0026\u0026t.center.y+i\u003e=e.minY\u0026\u0026t.center.y-i\u003c=e.maxY})(t,c)).map(t=\u003estructuredClone(t)),...B6(t,c)],connections:f,...void 0!==t.traces?{traces:h}:{},...void 0!==t.allowJumpers?{allowJumpers:t.allowJumpers}:{},...t.availableJumperTypes?{availableJumperTypes:structuredClone(t.availableJumperTypes)}:{}};return{srj:y,routes:u,bounds:structuredClone(n),contextBounds:c,mutableBounds:l,boundaryMargin:a,lockedPointIndices:p,routeMappings:m}},$6=t=\u003ex6(Object.fromEntries(Object.entries(t).filter(([t])=\u003e\"route\"!==t\u0026\u0026\"vias\"!==t))),Y6=(t,e)=\u003e{const n=[];for(let o=1;o\u003ct.route.length;o+=1){const i=t.route[o-1],r=t.route[o],s=y6(i,r,e),a=s?[...s[0]\u003eg6?[[0,s[0]]]:[],...s[1]\u003c.99999999?[[s[1],1]]:[]]:[[0,1]];s\u0026\u0026!f6(_6(i,r,.5),e,4e-8)\u0026\u00260===a.length\u0026\u0026a.push([0,1]);for(const[t,e]of a)n.push(x6([_6(i,r,t),_6(i,r,e)]))}return n},X6=(t,e,n,o,i,r)=\u003e{if($6(t)!==$6(e))throw new Error(\"repair04 merge rejected changed net, width, jumper, or route metadata\");if(n.length!==t.route.length)throw new Error(\"repair04 merge received an invalid lock mask\");if(0===e.route.length)throw new Error(\"repair04 merge rejected an empty replacement route\");if(x6(t.route[0])!==x6(e.route[0])||x6(t.route[t.route.length-1])!==x6(e.route[e.route.length-1]))throw new Error(\"repair04 merge rejected a moved fragment endpoint\");let s=0;for(let o=0;o\u003ct.route.length;o+=1){if(!n[o])continue;const i=x6(t.route[o]);for(;s\u003ce.route.length\u0026\u0026x6(e.route[s])!==i;)s+=1;if(s===e.route.length)throw new Error(\"repair04 merge rejected a moved or removed locked point\");s+=1}if(x6(Y6(t,o))!==x6(Y6(e,o)))throw new Error(\"repair04 merge rejected modified geometry in the fixed boundary collar\");for(let n=1;n\u003ct.route.length;n+=1){const o=t.route[n-1],i=t.route[n];if(!(\"through_obstacle\"===o.toNextSegmentType||!0===o.insideJumperPad||!0===i.insideJumperPad||(t.jumpers??[]).some(t=\u003eb6(o,{...t.start,z:o.z})\u0026\u0026b6(i,{...t.end,z:i.z})||b6(o,{...t.end,z:o.z})\u0026\u0026b6(i,{...t.start,z:i.z}))))continue;const r=x6([o,i]);if(!e.route.some((t,n)=\u003en+1\u003ce.route.length\u0026\u0026x6([t,e.route[n+1]])===r))throw new Error(\"repair04 merge rejected a changed atomic jumper or through-obstacle span\")}for(const n of e.route){if(![n.x,n.y,n.z].every(Number.isFinite)||!Number.isInteger(n.z)||n.z\u003c0||n.z\u003e=r||!f6(n,i))throw new Error(\"repair04 merge rejected invalid or out-of-region geometry\");if((void 0!==n.pcb_port_id||!0===n.insideJumperPad||void 0!==n.toNextSegmentCircuitJsonMetadata)\u0026\u0026!t.route.some(t=\u003ex6(t)===x6(n)))throw new Error(\"repair04 merge rejected invented or moved terminal/circuit metadata\");if(void 0!==n.traceThickness\u0026\u0026(!Number.isFinite(n.traceThickness)||n.traceThickness\u003c=0||n.traceThickness\u003eMath.max(t.traceThickness,...t.route.map(t=\u003et.traceThickness??0))+g6))throw new Error(\"repair04 merge rejected increased per-point copper width\")}for(let n=1;n\u003ce.route.length;n+=1){const o=e.route[n-1],i=e.route[n];if(\"through_obstacle\"===o.toNextSegmentType\u0026\u0026!t.route.some((e,n)=\u003en+1\u003ct.route.length\u0026\u0026x6([e,t.route[n+1]])===x6([o,i])))throw new Error(\"repair04 merge rejected an invented through-obstacle span\");if(o.z!==i.z\u0026\u0026\"through_obstacle\"!==o.toNextSegmentType\u0026\u0026(Math.abs(o.x-i.x)\u003eg6||Math.abs(o.y-i.y)\u003eg6||!e.vias.some(t=\u003eMath.abs(t.x-o.x)\u003c=g6\u0026\u0026Math.abs(t.y-o.y)\u003c=g6)))throw new Error(\"repair04 merge rejected a disconnected or missing via\")}for(const n of e.vias){if(!(Number.isFinite(n.x)\u0026\u0026Number.isFinite(n.y)\u0026\u0026f6(n,i)\u0026\u0026e.route.some(t=\u003eMath.abs(t.x-n.x)\u003c=g6\u0026\u0026Math.abs(t.y-n.y)\u003c=g6)))throw new Error(\"repair04 merge rejected an invalid via position\");if(!f6(n,o,4e-8)\u0026\u0026!t.vias.some(t=\u003ex6(t)===x6(n)))throw new Error(\"repair04 merge rejected a new via in the boundary collar\")}for(const n of t.vias)if(!f6(n,o,4e-8)\u0026\u0026!e.vias.some(t=\u003ex6(t)===x6(n)))throw new Error(\"repair04 merge rejected a changed via in the boundary collar\")},V6=(t,e)=\u003e{for(const n of e){const e=t[t.length-1];e\u0026\u0026b6(e,n)\u0026\u0026x6(e)===x6(n)||t.push(structuredClone(n))}},W6=(t,e,n)=\u003e{const o=new Set(e.route.map(x6)),i=new Set(n.flatMap(t=\u003et.originalFragment.route.map(x6)).filter(t=\u003e!o.has(t))),r=[];for(const e of t)for(r.push(e);r.length\u003e=3;){const t=r[r.length-3],e=r[r.length-2],n=r[r.length-1];if(!i.has(x6(e)))break;if(t.z!==e.z||e.z!==n.z\u0026\u0026\"through_obstacle\"!==t.toNextSegmentType)break;if(t.toNextSegmentType!==e.toNextSegmentType||t.insideJumperPad!==e.insideJumperPad||t.traceThickness!==e.traceThickness||x6(t.toNextSegmentCircuitJsonMetadata)!==x6(e.toNextSegmentCircuitJsonMetadata))break;const o=n.x-t.x,s=n.y-t.y,a=o*o+s*s;if(a\u003c=10000000000000001e-32)break;const c=(e.x-t.x)*s-(e.y-t.y)*o,l=((e.x-t.x)*o+(e.y-t.y)*s)/a;if(Math.abs(c)\u003eg6*Math.sqrt(a)||l\u003c0||l\u003e1)break;r.splice(r.length-2,1)}return r},H6=t=\u003e{if(!Number.isInteger(t.segmentIndex)||t.segmentIndex\u003c0||!Number.isFinite(t.t)||t.t\u003c0||t.t\u003e1)throw new Error(\"repair04 merge received invalid fragment provenance\");return t.segmentIndex+t.t},G6=({routes:t,region:e,repairedRoutes:n})=\u003e{if(n.length!==e.routeMappings.length||e.lockedPointIndices.length!==n.length)throw new Error(\"repair04 merge requires exactly one replacement for every extracted fragment\");const o=new Map;for(let i=0;i\u003cn.length;i+=1){const r=e.routeMappings[i],s=n[i];if(!t[r.sourceRouteIndex])throw new Error(\"repair04 merge source route no longer exists\");if(X6(r.originalFragment,s,e.lockedPointIndices[i],e.mutableBounds,e.contextBounds,e.srj.layerCount),x6(r.originalFragment)===x6(s))continue;const a=o.get(r.sourceRouteIndex)??[];a.push({mapping:r,repaired:s}),o.set(r.sourceRouteIndex,a)}return t.map((t,e)=\u003e{const n=o.get(e);if(!n)return t;n.sort((t,e)=\u003eH6(t.mapping.start)-H6(e.mapping.start));const i=[];let r=0;for(const{mapping:e,repaired:o}of n){const n=H6(e.start),s=H6(e.end);if(n\u003cr-g6||s\u003cn||s\u003et.route.length-1+g6)throw new Error(\"repair04 merge received overlapping or stale fragment provenance\");if(S6(t,n,s)!==e.sourceGeometryKey)throw new Error(\"repair04 merge rejected stale source geometry\");V6(i,v6(t,r,n)),V6(i,o.route),r=s}V6(i,v6(t,r,t.route.length-1));const s=new Set(n.flatMap(({mapping:t})=\u003et.originalFragment.vias.map(t=\u003e`${t.x},${t.y}`))),a=t.vias.filter(t=\u003e!s.has(`${t.x},${t.y}`)).map(t=\u003estructuredClone(t));for(const{repaired:t}of n)for(const e of t.vias)a.some(t=\u003eMath.abs(t.x-e.x)\u003c=g6\u0026\u0026Math.abs(t.y-e.y)\u003c=g6)||a.push(structuredClone(e));return{...t,route:W6(i,t,n.map(({mapping:t})=\u003et)),vias:a}})},U6=12e4,Z6=[10,16],q6=[3,4,5,6,8],J6=(t,e)=\u003e{const n=\"string\"==typeof t.pcb_pad_id?t.pcb_pad_id:\"string\"==typeof t.pcb_trace_error_id?t.pcb_trace_error_id.match(/(pcb_(?:smtpad|plated_hole|hole|keepout)_\\d+)$/)?.[1]:void 0;if(n){const t=e.obstacles.find(t=\u003et.obstacleId===n||t.connectedTo[0]===n);if(t)return t.center}return(t=\u003e{const e=t.center;return e\u0026\u0026\"object\"==typeof e\u0026\u0026\"x\"in e\u0026\u0026\"y\"in e\u0026\u0026\"number\"==typeof e.x\u0026\u0026\"number\"==typeof e.y?{x:e.x,y:e.y}:void 0})(t)},K6=({error:t,routeIndexByTraceId:e})=\u003e{const n=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,o=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]],i=n?`overlap_${n}_`:void 0,r=i\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0,s=void 0!==r\u0026\u0026o.includes(r);return[n,...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids:[],s?void 0:r].filter(t=\u003e\"string\"==typeof t\u0026\u0026e.has(t)).filter((t,e,n)=\u003en.indexOf(t)===e)},Q6=t=\u003et.filter(t=\u003e\"pcb_via_clearance_error\"===t.type||Array.isArray(t.pcb_via_ids)).length,t9=(t,e)=\u003e{const n=new Map;for(const e of t)n.set(e.connectionName,(n.get(e.connectionName)??0)+1);return t.map((t,o)=\u003e{const i=n.get(t.connectionName)\u003e1?`${t.connectionName}_regional_${o}`:t.connectionName;return i!==t.connectionName\u0026\u0026e.addConnections([[i,t.connectionName,t.rootConnectionName??t.connectionName]]),{...t,connectionName:i,preloadedTraceId:`pipeline9_joint_candidate_${o}`,preloadedTraceIndex:o,preloadedRouteIndex:0,isThroughObstacle:!1}})},e9=(t,e)=\u003et.minX\u003c=e.maxX\u0026\u0026t.maxX\u003e=e.minX\u0026\u0026t.minY\u003c=e.maxY\u0026\u0026t.maxY\u003e=e.minY,n9=t=\u003e({minX:t.center.x-t.diameter/2,maxX:t.center.x+t.diameter/2,minY:t.center.y-t.diameter/2,maxY:t.center.y+t.diameter/2}),o9=t=\u003e({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}),i9=(t,e)=\u003e{const n=EQ(t);return n.wireSegments.some(t=\u003ee9((t=\u003e({minX:Math.min(t.start.x,t.end.x)-t.width/2,maxX:Math.max(t.start.x,t.end.x)+t.width/2,minY:Math.min(t.start.y,t.end.y)-t.width/2,maxY:Math.max(t.start.y,t.end.y)+t.width/2}))(t),e))||n.viaSpans.some(t=\u003ee9(n9(t),e))},r9=({routes:t,fixedObstacleRoutes:e,routeIndex:n,center:o,regionSize:i,srj:r,connMap:s,colorMap:a,viaDiameter:c,traceWidth:l,obstacleMargin:d,effort:h})=\u003e{const u=t9(t,s),p=u[n];if(!p)return;const m={capacityMeshNodeId:`pipeline9_joint_drc_${n}_${i}`,center:o,width:i,height:i,availableZ:Array.from({length:r.layerCount},(t,e)=\u003ee),portPoints:[],portPointsInPairs:[]},g=$K(m,[p]),f=g.fixedRouteSectionsByConnectionName.get(p.connectionName);if(!f)return;const y=u.filter((t,e)=\u003ee!==n),_=new VQ({nodePortPoints:[g.nodeWithPortPoints],fixedHdRoutes:[...y,...e].map(t=\u003e({...t,rootConnectionName:s.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName})),connMap:s,colorMap:a,obstacles:r.obstacles,layerCount:r.layerCount,viaDiameter:c,traceWidth:l,obstacleMargin:d,effort:h,preserveTerminalPcbPortIds:!0,includeBoardObstacles:!0,enableRegionalFallback:!1,maxB01Rips:120});if(_.solve(),!_.solved||_.failed)return;const b=_.routes.find(t=\u003et.connectionName===p.connectionName);return b?{routes:t.map((t,e)=\u003ee===n?{...XK(f,b),connectionName:t.connectionName}:t),usedFallback:Number(_.stats.fallbackNodeCount??0)\u003e0}:void 0},s9=({routes:t,fixedRouteCopperSpatialIndex:e,center:n,regionSize:o,srj:i,connMap:r,colorMap:s,viaDiameter:a,traceWidth:c,obstacleMargin:l,effort:d})=\u003e{const h=t9(t,r),u={capacityMeshNodeId:\"pipeline9_joint_drc_regular_fallback\",center:n,width:o,height:o,availableZ:Array.from({length:i.layerCount},(t,e)=\u003ee),portPoints:[],portPointsInPairs:[]},p=$K(u,h);if(0===p.fixedRouteSectionsByConnectionName.size)return;if(!(t=\u003e{const e=kK(t);return t.portPoints.every(t=\u003e\"on-boundary\"===rs({point:t,bounds:e}))})(p.nodeWithPortPoints))return;const m=[...p.fixedRouteSectionsByConnectionName.values()].flatMap(t=\u003et.sourceRoutes).reduce((t,e)=\u003e{const n=EQ(e);return Math.max(t,e.viaDiameter/2,...n.wireSegments.map(t=\u003et.width/2),...n.viaSpans.map(t=\u003et.diameter/2))},Math.max(c/2,a/2)),g={minX:n.x-o/2-l-m,maxX:n.x+o/2+l+m,minY:n.y-o/2-l-m,maxY:n.y+o/2+l+m},f=e.getRoutesOverlappingBounds(g),y=OQ({fixedObstacleRoutes:f,layerCount:i.layerCount}),_=new FQ({nodeWithPortPoints:p.nodeWithPortPoints,colorMap:s,connMap:r,viaDiameter:a,traceWidth:c,obstacleMargin:l,effort:d,obstacles:[...i.obstacles,...y],layerCount:i.layerCount});if(_.solve(),!_.solved||_.failed)return;const b=_.getOutput(),x=new Map(b.map(t=\u003e[t.connectionName,t])),v=new Map,S=new Set;for(const[t,e]of p.fixedRouteSectionsByConnectionName){const n=x.get(t);if(!n)return;v.set(e.sourceRoutes[0].preloadedTraceIndex,XK(e,n));for(const t of e.sourceRoutes.slice(1))S.add(t.preloadedTraceIndex)}const I=h.flatMap((e,n)=\u003eS.has(n)?[]:[{...v.get(n)??e,connectionName:t[n].connectionName}]);return(({candidateRoutes:t,fixedObstacleRoutes:e,obstacleMargin:n,connMap:o,candidateBounds:i})=\u003e{for(const r of t)for(const t of e)if(!kQ(r,t,o)\u0026\u0026DQ({left:r,right:t,clearance:n,leftBounds:i}))return!0;return!1})({candidateRoutes:I,fixedObstacleRoutes:f,obstacleMargin:l,connMap:r,candidateBounds:g})?void 0:I},a9=({srj:t,routes:e,fixedObstacleRoutes:n,newConnections:o,syntheticConnectionNames:i,drcEvaluator:r,initialErrors:s,allowTracePairRepair:a=!1,preloadRepairTraceIds:c,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m})=\u003e{let g=e,f=s??r1(r,g),y=0,_=0,b=0,x=0,v=!1;const S=(t=\u003e{if(!Number.isInteger(t)||t\u003c0)throw new Error(\"Pipeline9 regional repair route count must be nonnegative\");const e=Math.floor(7e3/Math.max(1,t));return Math.max(16,Math.min(192,e))})(e.length),I=f.filter(t=\u003e(({error:t,preloadRepairTraceIds:e})=\u003e!!s1(t).some(t=\u003ee.has(t))||(t.__collapsed_trace_participants??[]).flatMap(t=\u003enew Set(t.evaluationTraceIds).size\u003e1?[t.solverTraceId]:[]).some(t=\u003ee.collidingFixedTraceIds?.has(t)))({error:t,preloadRepairTraceIds:c})).length,C=d1({routes:g,newConnections:o,syntheticConnectionNames:i}),P=a\u0026\u0026f.some(t=\u003e((t,e)=\u003e!(\"pcb_trace_error\"!==t.type||\"string\"==typeof t.pcb_via_id||Array.isArray(t.pcb_via_ids)\u0026\u0026t.pcb_via_ids.length\u003e0)\u0026\u00262===K6({error:t,routeIndexByTraceId:e}).length)(t,C));if(0===I\u0026\u0026!P)return{routes:g,attemptedCandidateCount:y,acceptedCandidateCount:_,fallbackCandidateCount:b,candidateSearchCount:x,candidateSearchBudget:S,candidateSearchBudgetExhausted:v,safeTraceLayerRepairSkippedForBudget:!1,remainingDrcIssueCount:f.length,preloadEligibleDrcIssueCount:I,preloadRepairAttempted:!1};const M=(t=\u003e{const e=new Map,n=(t,n)=\u003e{const o=Math.floor(n.minX/4),i=Math.floor(n.maxX/4),r=Math.floor(n.minY/4),s=Math.floor(n.maxY/4);for(let n=o;n\u003c=i;n++)for(let o=r;o\u003c=s;o++){const i=`${n}:${o}`,r=e.get(i)??new Set;r.add(t),e.set(i,r)}};for(let e=0;e\u003ct.length;e++){const o=EQ(t[e]);for(const t of o.wireSegments)for(const o of AQ(t,4,1))n(e,o9(o));for(const t of o.viaSpans)n(e,n9(t))}return{getRoutesOverlappingBounds:n=\u003e{const o=new Set,i=Math.floor(n.minX/4),r=Math.floor(n.maxX/4),s=Math.floor(n.minY/4),a=Math.floor(n.maxY/4);for(let t=i;t\u003c=r;t++)for(let n=s;n\u003c=a;n++)for(const i of e.get(`${t}:${n}`)??[])o.add(i);return[...o].sort((t,e)=\u003et-e).map(e=\u003et[e]).filter(t=\u003ei9(t,n))}}})(n);for(let e=0;e\u003c2\u0026\u0026!v;e++){let e=!1;const s=d1({routes:g,newConnections:o,syntheticConnectionNames:i}),a=f.filter(t=\u003e(\"pcb_trace_error\"===t.type||\"pcb_pad_trace_clearance_error\"===t.type||\"pcb_via_trace_clearance_error\"===t.type||\"pcb_via_clearance_error\"===t.type)\u0026\u0026\"string\"==typeof t.pcb_trace_id);for(const o of a){if(v)break;const i=J6(o,t),a=K6({error:o,routeIndexByTraceId:s});if(!i)continue;let c=g,I=f;for(const e of a.slice(0,2)){if(v)break;const o=s.get(e);if(void 0!==o){for(const e of q6){if(x\u003e=S){v=!0;break}x++;const s=r9({routes:g,fixedObstacleRoutes:n,routeIndex:o,center:i,regionSize:e,srj:t,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m});if(!s)continue;y++,s.usedFallback\u0026\u0026b++;const a=r1(r,s.routes);if(l1(a,I)\u0026\u0026(c=s.routes,I=a),0===I.length)break}if(0===I.length)break}}if(c!==g||v||(x\u003e=S?v=!0:x++),c===g\u0026\u0026!v){const e=s9({routes:g,fixedRouteCopperSpatialIndex:M,center:i,regionSize:3,srj:t,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m});if(e){y++,b++;const t=r1(r,e);l1(t,I)\u0026\u0026(c=e,I=t)}}if(c!==g\u0026\u0026(g=c,f=I,_++,e=!0),v)break}if(!e||0===f.length)break}if(_\u003e0\u0026\u0026f.length\u003e0){const e=iD({...t,traces:void 0},g,m,1,l);if(e!==g){const t=r1(r,e);Q6(t)\u003c=Q6(f)\u0026\u0026l1(t,f)\u0026\u0026(g=e,f=t)}}const N=f.some(t=\u003e\"pcb_trace_error\"===t.type||\"pcb_pad_trace_clearance_error\"===t.type),w=N\u0026\u0026v;if(N\u0026\u0026!v){const e=new Nz({srj:{...t,traces:void 0},hdRoutes:g,connMap:l,effort:m,drcEvaluator:r,maxIterations:8,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1});if(e.solve(),e.failed)throw new Error(`Pipeline9 post-regional safe trace-layer repair failed: ${e.error??\"unknown error\"}`);const n=e.getOutput(),o=r1(r,n);l1(o,f)\u0026\u0026(g=n,f=o)}return{routes:g,attemptedCandidateCount:y,acceptedCandidateCount:_,fallbackCandidateCount:b,candidateSearchCount:x,candidateSearchBudget:S,candidateSearchBudgetExhausted:v,safeTraceLayerRepairSkippedForBudget:w,remainingDrcIssueCount:f.length,preloadEligibleDrcIssueCount:I,preloadRepairAttempted:I\u003e0}},c9=[.9,.72],l9=Array.from({length:16},(t,e)=\u003ee*Math.PI/8),d9=t=\u003e\"pcb_pad_trace_clearance_error\"===t.type||\"pcb_trace_error\"===t.type\u0026\u0026!(Array.isArray(t.pcb_trace_ids)\u0026\u0026t.pcb_trace_ids.length\u003e=2),h9=t=\u003e{if(\"string\"==typeof t.pcb_pad_id)return t.pcb_pad_id;if(\"string\"==typeof t.pcb_trace_error_id){const e=t.pcb_trace_error_id.match(/(pcb_(?:smtpad|plated_hole|hole|keepout)_\\d+)$/)?.[1];if(e)return e}const e=\"string\"==typeof t.message?t.message:\"\";return e.match(/(?:pcb_smtpad|pcb_plated_hole|pcb_hole|pcb_keepout)\\[#?([^\\]\"]+)\\]/)?.[1]},u9=(t,e)=\u003e{if(!e)return;const n=e.startsWith(\"pcb_\")?e:`pcb_${e}`;return t.obstacles.find(t=\u003et.obstacleId===n||t.connectedTo[0]===n)},p9=({srj:t,pcbPortId:e,z:n,portPositionMap:o})=\u003e{const i=vo(n,t.layerCount),r=o.get(e),s=t.obstacles.filter(t=\u003et.layers.includes(i)\u0026\u0026t.connectedTo.includes(e));return r?s.reduce((t,e)=\u003et?Math.hypot(e.center.x-r.x,e.center.y-r.y)\u003cMath.hypot(t.center.x-r.x,t.center.y-r.y)?e:t:e,void 0):s[0]},m9=({terminalObstacle:t,conflictingObstacle:e,traceRadius:n})=\u003e{const o=Math.max(0,t.width/2-n),i=Math.max(0,t.height/2-n),r=(t.ccwRotationDegrees??0)*Math.PI/180;return c9.flatMap(e=\u003el9.map(n=\u003e{const s={x:Math.cos(n)*o*e,y:Math.sin(n)*i*e},a=(l=r,{x:(c=s).x*Math.cos(l)-c.y*Math.sin(l),y:c.x*Math.sin(l)+c.y*Math.cos(l)});var c,l;return{x:t.center.x+a.x,y:t.center.y+a.y}})).sort((t,n)=\u003eMath.hypot(n.x-e.center.x,n.y-e.center.y)-Math.hypot(t.x-e.center.x,t.y-e.center.y)).slice(0,16)},g9=({routes:t,routeIndex:e,endpointIndex:n,point:o,bounds:i,collapseAdjacent:r})=\u003e{const s=(t=\u003et.map(t=\u003e({...t,route:t.route.map(t=\u003e({...t})),vias:t.vias.map(t=\u003e({...t}))})))(t),a=s[e];if(!a||a.route.length\u003c2)return;const c=0===n?0:a.route.length-1,l=0===n?1:c-1,d=a.route[c],h=a.route[l];if(!d||!h||d.z!==h.z)return;const u=a.traceThickness/2;if(!(o.x-u\u003ci.minX||o.x+u\u003ei.maxX||o.y-u\u003ci.minY||o.y+u\u003ei.maxY)){if(a.route[c]={...d,...o},r){const t=0===n?l+1:l-1,e=a.route[t],i=a.vias.some(t=\u003et.x===h.x\u0026\u0026t.y===h.y);if(!e||e.z!==d.z||void 0!==h.pcb_port_id||i)return;a.route[l]={...h,...o}}return s}},f9=({srj:t,originalSrj:e,routes:n,newConnections:o,syntheticConnectionNames:i,drcEvaluator:r})=\u003e{let s=n,a=r1(r,s),c=0,l=0;const d=(t=\u003e{const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,t);return e})(e);for(let n=0;n\u003c2;n++){let n=!1;const h=d1({routes:s,newConnections:o,syntheticConnectionNames:i});for(const o of a.filter(d9)){if(c\u003e=256)break;if(\"string\"!=typeof o.pcb_trace_id)continue;const i=h.get(o.pcb_trace_id),u=u9(t,h9(o));if(void 0===i||!u)continue;const p=s[i];let m=s,g=a;t:for(const n of[0,-1]){const o=0===n?p.route[0]:p.route.at(-1);if(!o||\"string\"!=typeof o.pcb_port_id)continue;const a=p9({srj:e,pcbPortId:o.pcb_port_id,z:o.z,portPositionMap:d});if(!a||a===u)continue;const l=Math.hypot(u.width,u.height)/2+Math.hypot(a.width,a.height)/2+.5;if(!(Math.hypot(o.x-u.center.x,o.y-u.center.y)\u003el))for(const e of m9({terminalObstacle:a,conflictingObstacle:u,traceRadius:p.traceThickness/2}))for(const o of[!1,!0]){if(c\u003e=256)break t;const a=g9({routes:s,routeIndex:i,endpointIndex:n,point:e,bounds:t.bounds,collapseAdjacent:o});if(!a)continue;c++;const l=r1(r,a);l1(l,g)\u0026\u0026(m=a,g=l)}}m!==s\u0026\u0026(s=m,a=g,l++,n=!0)}if(!n||0===a.length)break}return{routes:s,attemptedCandidateCount:c,acceptedCandidateCount:l,remainingErrors:a}},y9=[\"pcb_trace_error_id\",\"pcb_error_id\",\"pcb_via_trace_clearance_error_id\",\"pcb_pad_trace_clearance_error_id\"],_9=(t,e)=\u003e{let n=t;const o=[...e].sort(([t],[e])=\u003ee.length-t.length);for(const[t,e]of o)n=n.replaceAll(t,e);return n},b9=(t,e)=\u003e{const n=String(t.type??t.error_type??\"unknown\");if(\"pcb_via_clearance_error\"===n)return((t,e)=\u003e{const n=[...\"string\"==typeof t.pcb_trace_id?[t.pcb_trace_id]:[],...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[]].map(t=\u003e_9(t,e)).filter((t,e,n)=\u003en.indexOf(t)===e).sort(),o=t.center\u0026\u0026\"object\"==typeof t.center?t.center:t.pcb_center\u0026\u0026\"object\"==typeof t.pcb_center?t.pcb_center:void 0,i=\"number\"==typeof o?.x\u0026\u0026\"number\"==typeof o.y?{x:o.x,y:o.y}:void 0,r=\"string\"==typeof t.pcb_via_pair_net_relation?t.pcb_via_pair_net_relation:void 0;if(0!==n.length\u0026\u0026i\u0026\u0026r)return`pcb_via_clearance_error:${JSON.stringify({traceIds:n,center:i,netRelation:r})}`})(t,e);for(const o of y9){const i=t[o];if(\"string\"==typeof i)return`${n}:${_9(i,e)}`}const o=Object.fromEntries(Object.entries(t).filter(([t,e])=\u003e(t.endsWith(\"_id\")||t.endsWith(\"_ids\"))\u0026\u0026(\"string\"==typeof e||Array.isArray(e))).sort(([t],[e])=\u003et.localeCompare(e)).map(([t,n])=\u003e[t,\"string\"==typeof n?_9(n,e):n]));return`${n}:${JSON.stringify(o)}`},x9=({errors:t,baselineErrors:e,originalTraceIdByPreparedTraceId:n=new Map})=\u003e{const o=new Set(e.filter(t=\u003e!(t=\u003e\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(\"missing_connection_\"))(t)).map(t=\u003eb9(t,new Map)));return o.delete(void 0),t.filter(t=\u003e{const e=b9(t,n);return void 0===e||!o.has(e)})},v9=1.5,S9=({errorsWithCenters:t,traces:e,layerCount:n,defaultViaDiameter:o,connMap:i})=\u003e{const r=(t=\u003et.flatMap(t=\u003e{if(\"pcb_trace_error\"!==t.type||!Array.isArray(t.pcb_port_ids)||t.pcb_port_ids.length\u003c4)return[];const e=t.center;return e\u0026\u0026\"object\"==typeof e\u0026\u0026\"x\"in e\u0026\u0026\"y\"in e\u0026\u0026\"number\"==typeof e.x\u0026\u0026\"number\"==typeof e.y?[{x:e.x,y:e.y}]:[]}))(t),s=new Set;for(let t=0;t\u003ce.length;t++){const a=e[t],c=oQ(a,t,n,o,i);r.some(t=\u003ec.some(e=\u003e{const n=e.route.map(t=\u003et.x),o=e.route.map(t=\u003et.y);return Math.min(...n)\u003c=t.x+v9\u0026\u0026Math.max(...n)\u003e=t.x-v9\u0026\u0026Math.min(...o)\u003c=t.y+v9\u0026\u0026Math.max(...o)\u003e=t.y-v9}))\u0026\u0026s.add(a.pcb_trace_id)}return s},I9=({routes:t,otherHdRoutes:e,obstacles:n,colorMap:o,layerCount:i,connMap:r})=\u003e{const s=IK([...t,...e],r),a=new tc({inputHdRoutes:t,otherHdRoutes:e,netByConnectionName:s,obstacles:n,colorMap:o,layerCount:i,connMap:r});if(a.solve(),a.failed)throw new Error(`Pipeline9 could not merge movable preloaded vias: ${a.error??\"unknown error\"}`);return a.getMergedViaHdRoutes()??t},C9=({errors:t,circuitJson:e,newTraceIds:n})=\u003e{const o=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.map(t=\u003e{const e=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,i=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],r=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]].filter((t,e,n)=\u003en.indexOf(t)===e);if(e\u0026\u0026\"string\"==typeof t.pcb_trace_error_id){const s=`overlap_${e}_`,a=t.pcb_trace_error_id.startsWith(s)?t.pcb_trace_error_id.slice(s.length):void 0,c=void 0!==a\u0026\u0026(r.includes(a)||o.has(a)\u0026\u0026!i.includes(a)),l=i.find(t=\u003et!==e\u0026\u0026n.has(t))??(a\u0026\u0026!c?a:void 0);if(!n.has(e)\u0026\u00260===r.length\u0026\u0026l\u0026\u0026n.has(l)){const n=[l,e,...i].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,pcb_trace_id:l,pcb_trace_ids:n,pcb_trace_error_id:`overlap_${l}_${e}`}}}const s=r.flatMap(t=\u003e{const e=o.get(t);return e?[e]:[]}).filter((t,e,n)=\u003en.indexOf(t)===e),a=s.length\u003e0?s:i.filter(t=\u003et!==e),c=a.find(t=\u003en.has(t));if(c\u0026\u0026(!e||!n.has(e))){const n=[c,...e?[e]:[],...i,...a].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,pcb_trace_id:c,pcb_trace_ids:n,pcb_via_id:r[0],pcb_via_ids:r}}if(r.length\u003e0){const n=[...e?[e]:[],...i,...a].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,pcb_trace_ids:n,pcb_via_id:r[0],pcb_via_ids:r}}return t})},P9=1e-9,M9=t=\u003e{const e=new Set,n=[];for(const o of t)for(const t of o.route){if(\"via\"!==t.route_type)continue;const i=`${t.x},${t.y},${t.from_layer},${t.to_layer}`;e.has(i)||(e.add(i),n.push({type:\"pcb_via\",pcb_via_id:`via_${n.length}`,pcb_trace_id:o.pcb_trace_id}))}return n},N9=({errors:t,circuitJson:e,evaluatedTraceIds:n})=\u003e{const o=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.map(t=\u003e{const e=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]],i=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,r=i?`overlap_${i}_`:void 0,s=r\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(r)?t.pcb_trace_error_id.slice(r.length):void 0,a=\"string\"==typeof t.pcb_trace_error_id?t.pcb_trace_error_id.match(/_(via_\\d+)$/)?.[1]:void 0,c=0!==e.length||!a||!o.has(a)||s\u0026\u0026n.has(s)?void 0:a,l=[...e,...c?[c]:[]].filter((t,e,n)=\u003en.indexOf(t)===e),d=[...\"string\"==typeof t.pcb_trace_id?[t.pcb_trace_id]:[],...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],...l.flatMap(t=\u003e{const e=o.get(t);return e?[e]:[]})].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,...l.length\u003e0?{pcb_via_id:l[0],pcb_via_ids:l}:{},...l.length\u003e0\u0026\u0026d.length\u003e0?{pcb_trace_ids:d}:{}}})},w9=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=P9\u0026\u0026Math.abs(t.y-e.y)\u003c=P9\u0026\u0026t.z===e.z,T9=({trace:t,sectionGroup:e,syntheticConnectionName:n,connMap:o})=\u003e{const i=e.routes;if(0===i.length)throw new Error(`Pipeline9 cannot exactly repair empty preloaded section for trace \"${t.pcb_trace_id}\"`);const r=[];for(const e of i){if(0===r.length){r.push(...e.route);continue}const n=r.at(-1);if(e.route[0]\u0026\u0026w9(n,e.route[0]))r.push(...e.route.slice(1));else{if(!e.route.at(-1)||!w9(n,e.route.at(-1)))throw new Error(`Pipeline9 cannot reconnect preloaded trace \"${t.pcb_trace_id}\" for exact repair`);r.push(...e.route.slice(0,-1).reverse())}}const s=0===e.routePositionStart,a=e.routePositionEnd===t.route.length-1,c=s?t.connectsTo?.[0]:null,l=a?t.connectsTo?.at(-1):null;return c\u0026\u0026r[0]\u0026\u0026(r[0]={...r[0],pcb_port_id:c}),l\u0026\u0026r.at(-1)\u0026\u0026(r[r.length-1]={...r.at(-1),pcb_port_id:l}),{connectionName:n,rootConnectionName:o.getNetConnectedToId(t.connection_name)??t.connection_name,traceThickness:Math.max(...i.map(t=\u003et.traceThickness)),viaDiameter:Math.max(...i.map(t=\u003et.viaDiameter)),route:r,vias:r.slice(0,-1).flatMap((t,e)=\u003e{const n=r[e+1];return t.z!==n.z\u0026\u0026(o=t,i=n,Math.abs(o.x-i.x)\u003c=P9\u0026\u0026Math.abs(o.y-i.y)\u003c=P9)?[{x:n.x,y:n.y}]:[];var o,i})}},R9=({trace:t,traceIndex:e,layerCount:n,defaultViaDiameter:o,connMap:i})=\u003e{const r=t.route.flatMap((t,e)=\u003e\"through_obstacle\"===t.route_type?[e]:[]),s=new Map,a=oQ(t,e,n,o,i);for(const e of a){const n=e.preloadedRoutePositionStart,o=e.preloadedRoutePositionEnd;if(void 0===n||void 0===o)throw new Error(`Pipeline9 preloaded trace section is missing route positions for \"${t.pcb_trace_id}\"`);if(\"through_obstacle\"===t.route[n]?.route_type)continue;const i=r.filter(t=\u003et\u003cn).length,a=s.get(i)??{routePositionStart:n,routePositionEnd:o,routes:[]};a.routePositionStart=Math.min(a.routePositionStart,n),a.routePositionEnd=Math.max(a.routePositionEnd,o),a.routes.push(e),s.set(i,a)}return[...s.values()]},E9=(t,e)=\u003et.map(t=\u003e{const n=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],o=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,i=o?`overlap_${o}_`:void 0,r=i\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0,s=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]],a=void 0!==r\u0026\u0026s.includes(r),c=[o,...n,a?void 0:r].filter(t=\u003e\"string\"==typeof t),l=new Map;for(const t of c){const n=e.get(t)??t,o=l.get(n)??new Set;o.add(t),l.set(n,o)}const d=[...l].flatMap(([t,e])=\u003ee.size\u003e1?[{solverTraceId:t,evaluationTraceIds:[...e]}]:[]),h=o?e.get(o)??o:void 0,u=n.map(t=\u003ee.get(t)??t),p=r?a?r:e.get(r)??r:void 0;return h!==o||u.some((t,e)=\u003et!==n[e])||p!==r?{...t,...o?{pcb_trace_id:h}:{},...Array.isArray(t.pcb_trace_ids)?{pcb_trace_ids:u}:{},...h\u0026\u0026p?{pcb_trace_error_id:`overlap_${h}_${p}`}:{},...d.length\u003e0?{__collapsed_trace_participants:d}:{}}:t}),A9=(t,e)=\u003e{const n=t.hdRoute.route[0],o=t.hdRoute.route.at(-1);return{name:t.syntheticConnectionName,rootConnectionName:t.hdRoute.rootConnectionName,__netConnectionName:t.originalTrace.connection_name,nominalTraceWidth:t.hdRoute.traceThickness,pointsToConnect:[{x:n.x,y:n.y,layer:vo(n.z,e),pointId:`${t.syntheticConnectionName}:start`},{x:o.x,y:o.y,layer:vo(o.z,e),pointId:`${t.syntheticConnectionName}:end`}]}},O9=({originalTrace:t,repairedSections:e})=\u003e{const n=[];let o=0;for(const i of[...e].sort((t,e)=\u003et.routePositionStart-e.routePositionStart)){if(i.routePositionStart\u003co)throw new Error(`Pipeline9 found overlapping repaired sections for preloaded trace \"${t.pcb_trace_id}\"`);n.push(...t.route.slice(o,i.routePositionStart),...i.route),o=i.routePositionEnd+1}return n.push(...t.route.slice(o)),{...t,__replaces_pcb_trace_id:t.pcb_trace_id,route:n}},k9=class extends si{params;inputNewHdRoutes;inputUpdatedPreloadedTraces;movablePreloadedSections;fixedPreloadedObstacleRoutes;syntheticConnectionNames;exactRepairSolver;drcEvaluator;cachedReferenceDrcEvaluator;clearancePrecisionDrcEvaluator;clearancePrecisionIndexedDrcEvaluator;clearanceMarginDrcEvaluator;referenceDrcValidationCount=0;referenceDrcFalseNegativeCount=0;indexedDrcEvaluationCount=0;indexedDrcCacheHitCount=0;indexedDrcEvaluationTimeMs=0;indexedDrcCandidateCache=new Map;combinedOutput;cacheIndexedDrcResult(t,e){if(this.indexedDrcCandidateCache.size\u003e=64){const t=this.indexedDrcCandidateCache.keys().next().value;void 0!==t\u0026\u0026this.indexedDrcCandidateCache.delete(t)}this.indexedDrcCandidateCache.set(t,e)}constructor(t){super(),this.params=t,this.inputNewHdRoutes=t.newHdRoutes,this.inputUpdatedPreloadedTraces=t.updatedPreloadedTraces;const e=t.updatedPreloadedTraces.filter(e=\u003et.mutatedPreloadedTraceIds.has(e.pcb_trace_id)),n=ZJ({connections:t.newConnections,originalConnections:t.originalSrj.connections,layerCount:t.layerCount,obstacles:t.obstacles,defaultViaHoleDiameter:t.defaultViaHoleDiameter,connMap:t.connMap}),o=n(t.newHdRoutes),i=new Set(o.map(t=\u003et.pcb_trace_id)),r=(({originalPreloadedTraces:t,mutatedPreloadedTraces:e,newTraces:n})=\u003e{const o=new Set(n.map(t=\u003et.pcb_trace_id)),i=new Map(e.map(t=\u003e[t.pcb_trace_id,t])),r=new Set([...t.map(t=\u003et.pcb_trace_id),...o]),s=new Map;return{routedTraces:[...t.filter(t=\u003eo.has(t.pcb_trace_id)).map(t=\u003e{const e=i.get(t.pcb_trace_id)??t,n=`${t.pcb_trace_id}_preloaded`;let o=n,a=2;for(;r.has(o);)o=`${n}_${a}`,a+=1;return r.add(o),s.set(o,t.pcb_trace_id),{...e,pcb_trace_id:o,__replaces_pcb_trace_id:t.pcb_trace_id}}),...e.filter(t=\u003e!o.has(t.pcb_trace_id)),...n],originalPreloadedTraceIdByPreparedTraceId:s}})({originalPreloadedTraces:t.originalSrj.traces??[],mutatedPreloadedTraces:e,newTraces:o}),s=t.originalSrj.minTraceToPadEdgeClearance??V0.traceClearance??.1,a=V0.viaClearance??.1,c=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:[],drcOptions:{traceClearance:s}}),l=new Set((t.originalSrj.traces??[]).map(t=\u003et.pcb_trace_id)),d=N9({errors:c.errors,circuitJson:c.circuitJson,evaluatedTraceIds:l}),h=N9({errors:c.errorsWithCenters,circuitJson:c.circuitJson,evaluatedTraceIds:l}),u=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:r.routedTraces,drcOptions:{traceClearance:s}}),p=new Set(o1(t.originalSrj.traces??[],r.routedTraces).map(t=\u003et.pcb_trace_id)),m=N9({errors:u.errors,circuitJson:u.circuitJson,evaluatedTraceIds:p}),g=N9({errors:u.errorsWithCenters,circuitJson:u.circuitJson,evaluatedTraceIds:p}),f={...u,errors:x9({errors:m,baselineErrors:d,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId}),errorsWithCenters:x9({errors:g,baselineErrors:h,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId})},y=(({errors:t,circuitJson:e})=\u003e{const n=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[])),o=new Set;for(const e of t){const t=\"string\"==typeof e.pcb_trace_id?e.pcb_trace_id:void 0,i=[...\"string\"==typeof e.pcb_via_id?[e.pcb_via_id]:[],...Array.isArray(e.pcb_via_ids)?e.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]];if(\"string\"==typeof e.pcb_trace_id\u0026\u0026o.add(e.pcb_trace_id),Array.isArray(e.pcb_trace_ids))for(const t of e.pcb_trace_ids)\"string\"==typeof t\u0026\u0026o.add(t);if(\"string\"==typeof e.pcb_via_id){const t=n.get(e.pcb_via_id);t\u0026\u0026o.add(t)}if(Array.isArray(e.pcb_via_ids))for(const t of e.pcb_via_ids){if(\"string\"!=typeof t)continue;const e=n.get(t);e\u0026\u0026o.add(e)}const r=t?`overlap_${t}_`:void 0;if(r\u0026\u0026\"string\"==typeof e.pcb_trace_error_id\u0026\u0026e.pcb_trace_error_id.startsWith(r)){const t=e.pcb_trace_error_id.slice(r.length);i.includes(t)||o.add(t)}}return o})({errors:f.errors,circuitJson:f.circuitJson}),_=new Map(t.updatedPreloadedTraces.map(t=\u003e[t.pcb_trace_id,t])),b=new Set;for(const t of y){const e=r.originalPreloadedTraceIdByPreparedTraceId.get(t);e\u0026\u0026_.has(e)?b.add(e):!i.has(t)\u0026\u0026_.has(t)\u0026\u0026b.add(t)}for(const e of S9({errorsWithCenters:f.errorsWithCenters,traces:t.updatedPreloadedTraces,layerCount:t.layerCount,defaultViaDiameter:t.defaultViaDiameter,connMap:t.connMap}))b.add(e);this.movablePreloadedSections=[];for(const e of b){const n=_.get(e);if(!n)throw new Error(`Pipeline9 cannot find preloaded trace \"${e}\" selected for exact repair`);const o=t.updatedPreloadedTraces.findIndex(t=\u003et.pcb_trace_id===e),i=R9({trace:n,traceIndex:o,layerCount:t.layerCount,defaultViaDiameter:t.defaultViaDiameter,connMap:t.connMap});for(const[e,o]of i.entries()){const i=`pipeline9_preloaded_drc_${this.movablePreloadedSections.length}`;this.movablePreloadedSections.push({originalTrace:n,originalRoutePositionStart:o.routePositionStart,originalRoutePositionEnd:o.routePositionEnd,syntheticConnectionName:i,evaluationTraceId:`${n.pcb_trace_id}__pipeline9_section_${e}`,hdRoute:T9({trace:n,sectionGroup:o,syntheticConnectionName:i,connMap:t.connMap})})}}this.syntheticConnectionNames=new Set(this.movablePreloadedSections.map(t=\u003et.syntheticConnectionName));const x=new Set(this.movablePreloadedSections.map(t=\u003et.originalTrace.pcb_trace_id));this.fixedPreloadedObstacleRoutes=t.updatedPreloadedTraces.flatMap((e,n)=\u003e{const o=oQ(e,n,t.layerCount,t.defaultViaDiameter,t.connMap);return x.has(e.pcb_trace_id)?o.filter(t=\u003e{const n=t.preloadedRoutePositionStart;return void 0!==n\u0026\u0026\"through_obstacle\"===e.route[n]?.route_type}):o});const v=new Map;for(const[t,e]of this.movablePreloadedSections.entries()){const n=e.originalTrace.pcb_trace_id,o=v.get(n)??[];o.push(t),v.set(n,o)}for(const e of(({errors:t,circuitJson:e,originalTraceIdByPreparedTraceId:n})=\u003e{const o=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.flatMap(t=\u003e{if(\"pcb_via_clearance_error\"!==t.type||!Array.isArray(t.pcb_via_ids)||\"number\"!=typeof t.actual_clearance||t.actual_clearance\u003e=0)return[];const e=t.pcb_via_ids.flatMap(t=\u003e{if(\"string\"!=typeof t)return[];const e=o.get(t);return e?[n.get(e)??e]:[]}).filter((t,e,n)=\u003en.indexOf(t)===e);return e.length\u003e0?[e]:[]})})({errors:f.errors,circuitJson:f.circuitJson,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId})){const n=e.flatMap(t=\u003ev.get(t)??[]).filter((t,e,n)=\u003en.indexOf(t)===e);if(0===n.length)continue;const o=new Set(n),i=I9({routes:n.map(t=\u003ethis.movablePreloadedSections[t].hdRoute),otherHdRoutes:[...t.newHdRoutes,...this.fixedPreloadedObstacleRoutes,...this.movablePreloadedSections.flatMap((t,e)=\u003eo.has(e)?[]:[t.hdRoute])],obstacles:t.obstacles,colorMap:t.colorMap,layerCount:t.layerCount,connMap:t.connMap});for(let t=0;t\u003cn.length;t++)this.movablePreloadedSections[n[t]].hdRoute=i[t]}if(this.stats={initialJointDrcIssueCount:f.errors.length,baselineJointDrcIssueCount:c.errors.length,initialJointDrcIssueCountByType:f.errors.reduce((t,e)=\u003e{const n=String(e.type??e.error_type??\"unknown\");return t[n]=(t[n]??0)+1,t},{}),movablePreloadedTraceCount:x.size,movablePreloadedSectionCount:this.movablePreloadedSections.length,exactRepairConfiguredMaxIterations:32,exactRepairConfiguredViaInPadMaxIterations:32,exactRepairConfiguredBroadMaxIterations:12},0===f.errors.length)return void(this.solved=!0);const S=new Set(this.movablePreloadedSections.map(t=\u003et.originalTrace.pcb_trace_id)),I=e.filter(t=\u003e!S.has(t.pcb_trace_id)),C=new Map(this.movablePreloadedSections.map(e=\u003e[e.syntheticConnectionName,A9(e,t.layerCount)])),{traces:P,...M}=t.srjWithPointPairs,N={...M,connections:[...t.srjWithPointPairs.connections,...C.values()]},w=new s_({...N,obstacles:t.originalSrj.obstacles,minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter??t.defaultViaDiameter},{connMap:t.connMap,traceClearance:s,viaClearance:a,includeTraceViaOwnerMetadata:!0,spatialCellSize:Math.max(t.defaultViaDiameter,t.originalSrj.minTraceWidth)+Math.max(s,a)}),T=w.evaluate(t.originalSrj.traces??[]),R=M9(t.originalSrj.traces??[]),E={...T,errors:N9({errors:T.errors,circuitJson:R,evaluatedTraceIds:l}),errorsWithCenters:N9({errors:T.errorsWithCenters,circuitJson:R,evaluatedTraceIds:l})};let A;const O=e=\u003e{const o=e.filter(t=\u003e!this.syntheticConnectionNames.has(t.connectionName)),i=n(o),r=vK(i,t.originalSrj.traces??[]),s=new Set,a=new Map,c=this.movablePreloadedSections.map(n=\u003e{const o=e.find(t=\u003et.connectionName===n.syntheticConnectionName);if(!o)throw new Error(`Pipeline9 joint DRC repair lost preloaded section \"${n.syntheticConnectionName}\"`);const i=n.originalTrace.pcb_trace_id;a.set(n.evaluationTraceId,i);const r=!s.has(i);return s.add(i),{...n.originalTrace,pcb_trace_id:n.evaluationTraceId,...r?{__replaces_pcb_trace_id:i}:{__replaces_pcb_trace_id:void 0},route:Mo(o,t.layerCount,{defaultViaHoleDiameter:t.defaultViaHoleDiameter,obstacles:t.obstacles,connMap:t.connMap})}}),l=new Map;for(let t=0;t\u003ci.length;t++)l.set(r[t].pcb_trace_id,i[t].pcb_trace_id);for(const t of this.movablePreloadedSections)l.set(t.evaluationTraceId,`${t.syntheticConnectionName}_0`);const d=new Set(l.values()),h=[...I,...c,...r];return{evaluatedTraces:o1(t.originalSrj.traces??[],h),movableTraceIds:d,originalTraceIdByEvaluationTraceId:a,routedTraces:h,solverTraceIdByEvaluationTraceId:l}},k=({errors:t,errorsWithCenters:e,circuitJson:n,movableTraceIds:o,solverTraceIdByEvaluationTraceId:i})=\u003e{const r=n.map(t=\u003e{if(!(\"pcb_trace_id\"in t)||\"string\"!=typeof t.pcb_trace_id)return t;const e=i.get(t.pcb_trace_id);return e?{...t,pcb_trace_id:e}:t});return{errors:C9({errors:E9(t,i),circuitJson:r,newTraceIds:o}),errorsWithCenters:C9({errors:E9(e,i),circuitJson:r,newTraceIds:o})}},L=({routes:e,hdRoutes:n},o=!0)=\u003e{const i=e??n;if(!i)throw new Error(\"Pipeline9 reference DRC repair requires HD routes\");const r=O(i),a=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:r.routedTraces,drcOptions:{traceClearance:s,includeTraceContinuity:o}}),c=new Set(r.evaluatedTraces.map(t=\u003et.pcb_trace_id)),l=N9({errors:a.errors,circuitJson:a.circuitJson,evaluatedTraceIds:c}),u=N9({errors:a.errorsWithCenters,circuitJson:a.circuitJson,evaluatedTraceIds:c}),p=x9({errors:l,baselineErrors:d,originalTraceIdByPreparedTraceId:r.originalTraceIdByEvaluationTraceId}),m=x9({errors:u,baselineErrors:h,originalTraceIdByPreparedTraceId:r.originalTraceIdByEvaluationTraceId});return k({errors:p,errorsWithCenters:m,circuitJson:a.circuitJson,movableTraceIds:r.movableTraceIds,solverTraceIdByEvaluationTraceId:r.solverTraceIdByEvaluationTraceId})},D=({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline9 cached reference DRC requires HD routes\");const o=JSON.stringify(n);if(A?.candidateKey===o)return A.result;this.referenceDrcValidationCount+=1;const i=L({traces:[],routes:n,hdRoutes:n});return A={candidateKey:o,result:i},i};this.cachedReferenceDrcEvaluator=D,this.clearancePrecisionDrcEvaluator=({routes:t,hdRoutes:e})=\u003eL({traces:[],routes:t,hdRoutes:e},!1);const z=e=\u003e{const n=O(e);return n1(t.srjWithPointPairs,n.routedTraces,{minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter,originalSrj:t.originalSrj,includeOriginalConnections:!0})};let F;this.clearanceMarginDrcEvaluator=(t,e,n)=\u003e(F?.routes!==n\u0026\u0026(F={routes:n,circuitJson:z(n)}),(({circuitJson:t,originalCircuitJson:e,targets:n})=\u003e{const o=new Map(t.filter(t=\u003e\"pcb_trace\"===t.type).map(t=\u003e[t.pcb_trace_id,t])),i=new Map(e.filter(t=\u003e\"pcb_trace\"===t.type).map(t=\u003e[t.pcb_trace_id,t])),r=t.filter(t=\u003e\"pcb_via\"===t.type),s=new Map;for(const e of t)\"pcb_via\"===e.type?s.set(e.pcb_via_id,e):\"pcb_smtpad\"===e.type?s.set(e.pcb_smtpad_id,e):\"pcb_plated_hole\"===e.type\u0026\u0026s.set(e.pcb_plated_hole_id,e);const a=[];for(const t of n){const n=\"pcb_via_trace_clearance_error\"===t.type,c=n?t.pcb_via_id:t.pcb_pad_id;if(!n\u0026\u0026\"pcb_pad_trace_clearance_error\"!==t.type||\"string\"!=typeof t.pcb_trace_id||\"string\"!=typeof c||\"number\"!=typeof t.minimum_clearance||!Number.isFinite(t.minimum_clearance)||t.minimum_clearance\u003c=0)throw new Error(\"Pipeline9 clearance margin requires a valid target pair\");const l=i.get(t.pcb_trace_id),d=e.find(t=\u003en?\"pcb_via\"===t.type\u0026\u0026t.pcb_via_id===c:\"pcb_smtpad\"===t.type\u0026\u0026t.pcb_smtpad_id===c||\"pcb_plated_hole\"===t.type\u0026\u0026t.pcb_plated_hole_id===c);if(!l||!d)throw new Error(`Pipeline9 clearance margin has no original target ${c}/${t.pcb_trace_id}`);const h=o.get(t.pcb_trace_id);let u=s.get(c);if(n){if(\"pcb_via\"!==d.type||\"string\"!=typeof d.pcb_trace_id)throw new Error(\"Pipeline9 clearance margin requires the original via owner\");const t=i.get(d.pcb_trace_id);if(!t)throw new Error(\"Pipeline9 clearance margin lost the original via owner\");const e=t.route.filter(t=\u003e\"via\"===t.route_type),n=e.map((t,e)=\u003e({segment:t,index:e})).filter(({segment:t})=\u003et.x===d.x\u0026\u0026t.y===d.y\u0026\u0026d.layers.includes(t.from_layer)\u0026\u0026d.layers.includes(t.to_layer)\u0026\u0026(t.from_layer===d.layers[0]\u0026\u0026t.to_layer===d.layers.at(-1)||t.to_layer===d.layers[0]\u0026\u0026t.from_layer===d.layers.at(-1))).filter(({segment:t},e,n)=\u003en.findIndex(e=\u003ee.segment.from_layer===t.from_layer\u0026\u0026e.segment.to_layer===t.to_layer)===e);if(0===n.length)throw new Error(\"Pipeline9 clearance margin lost the original via transition\");if(1!==n.length)return{status:\"unsupported-identity\"};const s=n[0].index,a=o.get(d.pcb_trace_id),c=a?.route.filter(t=\u003e\"via\"===t.route_type);if(!c||c.length!==e.length||c.some((t,n)=\u003et.from_layer!==e[n].from_layer||t.to_layer!==e[n].to_layer))return{status:\"unsupported-identity\"};const l=c[s];u=r.filter(t=\u003et.x===l.x\u0026\u0026t.y===l.y\u0026\u0026t.layers.join()===d.layers.join()).reduce((t,e)=\u003e!t||e.outer_diameter\u003et.outer_diameter?e:t,void 0)}if(!(h\u0026\u0026u\u0026\u0026\"x\"in u\u0026\u0026\"y\"in u))return{status:\"unsupported-identity\"};const p={minClearance:t.minimum_clearance+1},m=n?Y0([h,u],p):$0([h,u],p),g=t.minimum_clearance+.01;for(const e of m){const n=e.actual_clearance;if(\"number\"!=typeof n||!Number.isFinite(n))throw new Error(\"Pipeline9 clearance margin requires a finite measurement\");n\u003e=g||a.push({...t,...\"pcb_via\"===u.type?{pcb_via_id:u.pcb_via_id,pcb_via_ids:[u.pcb_via_id]}:{},actual_clearance:n,minimum_clearance:g,center:{x:u.x,y:u.y}})}}return{status:\"measured\",errors:a}})({circuitJson:z(t),originalCircuitJson:F.circuitJson,targets:e})),this.clearancePrecisionIndexedDrcEvaluator=({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline9 clearance ranking requires HD routes\");const o=O(n);return w.evaluate(o.evaluatedTraces)};const B=({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline9 joint DRC repair requires HD routes\");const o=JSON.stringify(n),i=this.indexedDrcCandidateCache.get(o);if(void 0!==i)return this.indexedDrcCacheHitCount+=1,i;const r=performance.now();this.indexedDrcEvaluationCount+=1;const s=O(n),a=w.evaluate(s.evaluatedTraces),c=M9(s.evaluatedTraces),l=new Set(s.evaluatedTraces.map(t=\u003et.pcb_trace_id)),d=N9({errors:a.errors,circuitJson:c,evaluatedTraceIds:l}),h=N9({errors:a.errorsWithCenters,circuitJson:c,evaluatedTraceIds:l}),u=x9({errors:d,baselineErrors:E.errors,originalTraceIdByPreparedTraceId:s.originalTraceIdByEvaluationTraceId}),p=x9({errors:h,baselineErrors:E.errorsWithCenters,originalTraceIdByPreparedTraceId:s.originalTraceIdByEvaluationTraceId});if(0===u.length){const t=this.referenceDrcValidationCount,e=D({traces:[],routes:n,hdRoutes:n}),i=Array.isArray(e)?e:e.errors;return this.referenceDrcValidationCount\u003et\u0026\u0026i.length\u003e0\u0026\u0026(this.referenceDrcFalseNegativeCount+=1),this.indexedDrcEvaluationTimeMs+=performance.now()-r,this.cacheIndexedDrcResult(o,e),e}const m=k({errors:u,errorsWithCenters:p,circuitJson:c,movableTraceIds:s.movableTraceIds,solverTraceIdByEvaluationTraceId:s.solverTraceIdByEvaluationTraceId});return this.indexedDrcEvaluationTimeMs+=performance.now()-r,this.cacheIndexedDrcResult(o,m),m};this.drcEvaluator=B,this.exactRepairSolver=new wz({srj:N,hdRoutes:[...t.newHdRoutes,...this.movablePreloadedSections.map(t=\u003et.hdRoute)],connMap:t.connMap,effort:t.effort,viaHoleDiameter:t.defaultViaHoleDiameter,drcEvaluator:B,viaInPadDrcEvaluator:B,maxIterations:32,enableBroadFallback:!1,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!0,enableTraceViaOwnerTargeting:!0,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:t.originalSrj.allowViaInPad??!1,viaInPadMaxIterations:32,broadMaxIterations:12,broadPassMultiplier:3}),this.activeSubSolver=this.exactRepairSolver,this.MAX_ITERATIONS=this.exactRepairSolver.MAX_ITERATIONS+1}getSolverName(){return\"Pipeline9JointDrcRepairSolver\"}_step(){if(!this.exactRepairSolver)return void(this.solved=!0);if(this.exactRepairSolver.step(),this.progress=this.exactRepairSolver.progress,this.exactRepairSolver.failed)return this.failed=!0,void(this.error=this.exactRepairSolver.error);if(!this.exactRepairSolver.solved)return;let t=this.exactRepairSolver.getOutput();const e=this.exactRepairSolver.stats.finalDrcIssueCount,n=\"number\"==typeof e\u0026\u0026Number.isFinite(e)\u0026\u0026e\u003e=0?e:void 0;let o,i=0,r=0,s=0,a=!1;const c=this.cachedReferenceDrcEvaluator({traces:[],routes:t,hdRoutes:t}),l=Array.isArray(c)?c:c.errors;if(o=l.length,l.length\u003e0){const e=(({srj:t,routes:e,newConnections:n,syntheticConnectionNames:o,connMap:i,indexedDrcEvaluator:r,candidateDrcEvaluator:s,marginDrcEvaluator:a,drcEvaluator:c,initialErrors:l,initialErrorsWithCenters:d=l})=\u003e{const h={routes:e,attemptedCandidateCount:0,candidateValidationCount:0,referenceValidationCount:0,repaired:!1};if((t.traces?.length??0)\u003e0||o.size\u003e0)return h;if(0===l.length)return h;const u=d1({routes:e,newConnections:n,syntheticConnectionNames:o}),p=new Map;for(const e of t.obstacles)for(const t of[e.obstacleId,e.circuitJsonMetadata?.pcb_smtpad_id,e.circuitJsonMetadata?.pcb_plated_hole_id,e.connectedTo[0]])\"string\"==typeof t\u0026\u0026p.set(t,e.center);const m=p1({errors:l,errorsWithCenters:d,routeIndexByTraceId:u,padPositionById:p});if(!m)return h;let g=m;const f=m.errors,y=m.errors.map(t=\u003e({...t,minimum_clearance:t.minimum_clearance+.01})),_=u1(y);if(void 0===_)return h;let b={errors:y,deficit:_},x=e,v=0,S=0,I=0;for(let n=0;n\u003c8;n++){const n=new Map;for(const t of[...b.errors,...g.errors]){const e=JSON.stringify([t.type,t.pcb_trace_id,t.pcb_pad_id,t.pcb_via_id]);n.set(e,t)}const o=[...n.values()];let l;for(const e of h1){const n=kk(x);if(!$D(t,n,o,u,e,i,!0,!0,!0,!1))continue;const s=aD(n);v++;const a=r({traces:[],routes:s,hdRoutes:s}),c=u1(Array.isArray(a)?a:a.errors);void 0!==c\u0026\u0026(!l||c\u003cl.deficit)\u0026\u0026(l={routes:s,deficit:c})}if(!l)break;S++;const d=s({traces:[],routes:l.routes,hdRoutes:l.routes}),h=Array.isArray(d)?d:d.errors,m=p1({errors:h,errorsWithCenters:Array.isArray(d)?d:d.errorsWithCenters??d.errors,routeIndexByTraceId:u,padPositionById:p});if(!m)break;const y=a(l.routes,f,e);if(\"unsupported-identity\"===y.status)break;const _=y.errors,C=p1({errors:_,errorsWithCenters:_,routeIndexByTraceId:u,padPositionById:p});if(!C)break;if(0===h.length\u0026\u00260===_.length){I++;const t=c({traces:[],routes:l.routes,hdRoutes:l.routes});if(0===(Array.isArray(t)?t:t.errors).length)return{routes:l.routes,attemptedCandidateCount:v,candidateValidationCount:S,referenceValidationCount:I,repaired:!0};break}if(m.deficit+C.deficit\u003e=g.deficit+b.deficit-1e-9)break;x=l.routes,g=m,b=C}return{routes:e,attemptedCandidateCount:v,candidateValidationCount:S,referenceValidationCount:I,repaired:!1}})({srj:this.params.srj,routes:t,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,connMap:this.params.connMap,indexedDrcEvaluator:this.clearancePrecisionIndexedDrcEvaluator,candidateDrcEvaluator:this.clearancePrecisionDrcEvaluator,marginDrcEvaluator:this.clearanceMarginDrcEvaluator,drcEvaluator:this.cachedReferenceDrcEvaluator,initialErrors:l,initialErrorsWithCenters:Array.isArray(c)?c:c.errorsWithCenters??c.errors});i=e.attemptedCandidateCount,r=e.candidateValidationCount,s=e.referenceValidationCount,a=e.repaired,e.repaired\u0026\u0026(t=e.routes,o=0)}if(0===o)return this.combinedOutput=t,this.stats={...this.stats,...this.exactRepairSolver.stats,postExactIndexedDrcIssueCount:n,postExactReferenceValidationAttempted:!0,postExactReferenceDrcIssueCount:0,postExactReferenceAccepted:!0,clearancePrecisionCandidateCount:i,clearancePrecisionCandidateValidationCount:r,clearancePrecisionReferenceValidationCount:s,clearancePrecisionRepaired:a,boundedRegionalRepairAttemptedRegionCount:0,boundedRegionalRepairAcceptedRegionCount:0,boundedRegionalRepairCandidateAttemptCount:0,boundedRegionalRepairPathSearchNodeCount:0,boundedRegionalRepairReferenceValidationCount:0,boundedRegionalRepairRepaired:!1,boundedRegionalRepairTimeMs:0,regionalB01RepairCandidateCount:0,regionalB01RepairAcceptedCount:0,regionalB01RepairFallbackCandidateCount:0,regionalB01RepairCandidateSearchCount:0,regionalB01RepairCandidateSearchBudget:0,regionalB01RepairCandidateSearchBudgetExhausted:!1,regionalB01RepairSafeTraceLayerSkippedForBudget:!1,regionalB01RepairRemainingDrcIssueCount:0,regionalB01RepairPreloadEligibleDrcIssueCount:0,regionalB01RepairAttempted:!1,regionalB01RepairTraceIdCount:0,terminalEscapeCandidateCount:0,terminalEscapeAcceptedCount:0,referenceDrcValidationCount:this.referenceDrcValidationCount,referenceDrcFalseNegativeCount:this.referenceDrcFalseNegativeCount,indexedDrcEvaluationCount:this.indexedDrcEvaluationCount,indexedDrcCacheHitCount:this.indexedDrcCacheHitCount,indexedDrcEvaluationTimeMs:this.indexedDrcEvaluationTimeMs,indexedDrcCandidateCacheSize:this.indexedDrcCandidateCache.size,indexedDrcCandidateCacheCapacity:64},void(this.solved=!0);const d=f9({srj:this.params.srj,originalSrj:this.params.originalSrj,routes:t,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.drcEvaluator}),h=(({routes:t,newConnections:e,syntheticConnectionNames:n,fixedPreloadedObstacleRoutes:o,updatedPreloadedTraces:i})=\u003e{const r=new Set,s=Object.assign(new Set,{collidingFixedTraceIds:r}),a=d1({routes:t,newConnections:e,syntheticConnectionNames:n}),c=new Set;for(const[e,o]of a)n.has(t[o].connectionName)?s.add(e):c.add(e);for(const t of o){const e=i[t.preloadedTraceIndex];if(!e)throw new Error(`Pipeline9 fixed preload route has invalid trace index ${t.preloadedTraceIndex}`);c.has(e.pcb_trace_id)?r.add(e.pcb_trace_id):s.add(e.pcb_trace_id)}return s})({routes:d.routes,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,fixedPreloadedObstacleRoutes:this.fixedPreloadedObstacleRoutes,updatedPreloadedTraces:this.params.updatedPreloadedTraces}),u=a9({srj:this.params.srj,routes:d.routes,fixedObstacleRoutes:this.fixedPreloadedObstacleRoutes,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.drcEvaluator,initialErrors:d.remainingErrors,allowTracePairRepair:!0,preloadRepairTraceIds:h,connMap:this.params.connMap,colorMap:this.params.colorMap,viaDiameter:this.params.defaultViaDiameter,traceWidth:this.params.srj.minTraceWidth,obstacleMargin:this.params.srj.defaultObstacleMargin??this.params.srj.minTraceToPadEdgeClearance??.15,effort:this.params.effort}),p=performance.now(),m=(({originalSrj:t,routes:e,syntheticConnectionNames:n,drcEvaluator:o})=\u003e{const i={routes:e,attemptedRegionCount:0,acceptedRegionCount:0,candidateAttemptCount:0,pathSearchNodeCount:0,referenceValidationCount:0,initialDrcIssueCount:void 0,finalDrcIssueCount:void 0,repaired:!1};if(t.traces?.length||n.size\u003e0)return i;const r=Math.max(t.defaultObstacleMargin??.2,t.minTraceToPadEdgeClearance??0,t.minViaEdgeToPadEdgeClearance??0);let s=Math.max(t.minTraceWidth,t.minViaDiameter??0);for(const t of e){s=Math.max(s,t.traceThickness,t.viaDiameter);for(const e of t.route)s=Math.max(s,e.traceThickness??0)}const a=Math.max(.5,s+r),c=Z6.filter(t=\u003e!Number.isFinite(a)||2*a\u003ct);if(0===c.length)return i;let l=e,d=o({traces:[],routes:e,hdRoutes:e});i.referenceValidationCount++;let h=Array.isArray(d)?d:d.errors;if(i.initialDrcIssueCount=h.length,i.finalDrcIssueCount=h.length,0===h.length)return i;const u={...fX(t),traces:void 0},p=[];let m=new Map(P6({srj:u,routes:l}).map(t=\u003e[t.key,t.severity]));for(;i.attemptedRegionCount\u003c4;){const t=(Array.isArray(d)?d:d.errorsWithCenters??d.errors).map(t=\u003et.center??t.pcb_center).filter(t=\u003enull!==t\u0026\u0026\"object\"==typeof t\u0026\u0026\"x\"in t\u0026\u0026\"y\"in t\u0026\u0026\"number\"==typeof t.x\u0026\u0026\"number\"==typeof t.y\u0026\u0026Number.isFinite(t.x)\u0026\u0026Number.isFinite(t.y));let e;for(const n of c){const o=t.find(({x:t,y:e})=\u003e!p.some(({bounds:o,size:i})=\u003en===i\u0026\u0026t\u003e=o.minX\u0026\u0026t\u003c=o.maxX\u0026\u0026e\u003e=o.minY\u0026\u0026e\u003c=o.maxY));if(o){e={center:o,size:n};break}}if(!e)break;const{center:n,size:r}=e,s=j6({srj:u,routes:l,bounds:{minX:n.x-r/2,maxX:n.x+r/2,minY:n.y-r/2,maxY:n.y+r/2}});if(p.push({bounds:s.mutableBounds,size:r}),i.attemptedRegionCount++,0===s.routes.length)continue;const a=new A6({srj:s.srj,routes:s.routes,bounds:s.bounds,boundaryMargin:s.boundaryMargin,lockedPointIndices:s.lockedPointIndices,maxCandidates:256,maxCandidateAttempts:256,maxPathSearchNodes:U6,allowLayerChanges:!0,traceOnlyFirst:!1});if(a.solve(),a.failed)throw new Error(`Pipeline9 bounded regional repair failed: ${a.error}`);const{candidateAttempts:g,pathSearchNodes:f}=a.stats;if(!Number.isSafeInteger(g)||g\u003c0||g\u003e256||!Number.isSafeInteger(f)||f\u003c0||f\u003eU6)throw new Error(\"Pipeline9 bounded regional repair exceeded its work budget\");i.candidateAttemptCount+=g,i.pathSearchNodeCount+=f;const y=G6({routes:l,region:s,repairedRoutes:a.getOutput()});if(y.every((t,e)=\u003et===l[e]))continue;const _=P6({srj:u,routes:y});if(!_.every(({key:t,severity:e})=\u003em.has(t)\u0026\u0026e\u003c=m.get(t)+1e-8)||w6({srj:u,previousRoutes:l,routes:y}).length\u003e0)continue;const b=o({traces:[],routes:y,hdRoutes:y});i.referenceValidationCount++;const x=Array.isArray(b)?b:b.errors;if(!(x.length\u003e=h.length)\u0026\u0026(l=y,h=x,d=b,m=new Map(_.map(t=\u003e[t.key,t.severity])),i.acceptedRegionCount++,i.finalDrcIssueCount=h.length,0===h.length))return i.routes=l,i.repaired=!0,i}return i})({originalSrj:this.params.originalSrj,routes:u.routes,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.cachedReferenceDrcEvaluator});this.combinedOutput=m.routes,this.stats={...this.stats,...this.exactRepairSolver.stats,postExactIndexedDrcIssueCount:n,postExactReferenceValidationAttempted:!0,postExactReferenceDrcIssueCount:o,postExactReferenceAccepted:!1,clearancePrecisionCandidateCount:i,clearancePrecisionCandidateValidationCount:r,clearancePrecisionReferenceValidationCount:s,clearancePrecisionRepaired:a,boundedRegionalRepairAttemptedRegionCount:m.attemptedRegionCount,boundedRegionalRepairAcceptedRegionCount:m.acceptedRegionCount,boundedRegionalRepairCandidateAttemptCount:m.candidateAttemptCount,boundedRegionalRepairPathSearchNodeCount:m.pathSearchNodeCount,boundedRegionalRepairReferenceValidationCount:m.referenceValidationCount,boundedRegionalRepairRepaired:m.repaired,boundedRegionalRepairTimeMs:performance.now()-p,regionalB01RepairCandidateCount:u.attemptedCandidateCount,regionalB01RepairAcceptedCount:u.acceptedCandidateCount,regionalB01RepairFallbackCandidateCount:u.fallbackCandidateCount,regionalB01RepairCandidateSearchCount:u.candidateSearchCount,regionalB01RepairCandidateSearchBudget:u.candidateSearchBudget,regionalB01RepairCandidateSearchBudgetExhausted:u.candidateSearchBudgetExhausted,regionalB01RepairSafeTraceLayerSkippedForBudget:u.safeTraceLayerRepairSkippedForBudget,regionalB01RepairRemainingDrcIssueCount:u.remainingDrcIssueCount,regionalB01RepairPreloadEligibleDrcIssueCount:u.preloadEligibleDrcIssueCount,regionalB01RepairAttempted:u.preloadRepairAttempted,regionalB01RepairTraceIdCount:h.size+(h.collidingFixedTraceIds?.size??0),terminalEscapeCandidateCount:d.attemptedCandidateCount,terminalEscapeAcceptedCount:d.acceptedCandidateCount,referenceDrcValidationCount:this.referenceDrcValidationCount,referenceDrcFalseNegativeCount:this.referenceDrcFalseNegativeCount,indexedDrcEvaluationCount:this.indexedDrcEvaluationCount,indexedDrcCacheHitCount:this.indexedDrcCacheHitCount,indexedDrcEvaluationTimeMs:this.indexedDrcEvaluationTimeMs,indexedDrcCandidateCacheSize:this.indexedDrcCandidateCache.size,indexedDrcCandidateCacheCapacity:64},this.solved=!0}getCombinedOutput(){return this.combinedOutput??this.exactRepairSolver?.getOutput()??this.inputNewHdRoutes}getOutput(){return this.getCombinedOutput().filter(t=\u003e!this.syntheticConnectionNames.has(t.connectionName))}getUpdatedPreloadedTraces(){const t=new Map(this.getCombinedOutput().map(t=\u003e[t.connectionName,t])),e=new Map;for(const n of this.movablePreloadedSections){const o=t.get(n.syntheticConnectionName);if(!o)throw new Error(`Pipeline9 joint DRC repair output is missing \"${n.syntheticConnectionName}\"`);const i=n.originalTrace.pcb_trace_id,r=e.get(i)??[];r.push({routePositionStart:n.originalRoutePositionStart,routePositionEnd:n.originalRoutePositionEnd,route:Mo(o,this.params.layerCount,{defaultViaHoleDiameter:this.params.defaultViaHoleDiameter,obstacles:this.params.obstacles,connMap:this.params.connMap})}),e.set(i,r)}const n=new Map([...e].map(([t,e])=\u003e{const n=this.inputUpdatedPreloadedTraces.find(e=\u003ee.pcb_trace_id===t);if(!n)throw new Error(`Pipeline9 cannot find preloaded trace \"${t}\" while rebuilding repaired sections`);return[t,O9({originalTrace:n,repairedSections:e})]}));return this.inputUpdatedPreloadedTraces.map(t=\u003en.get(t.pcb_trace_id)??t)}getMutatedPreloadedTraces(){const t=new Set([...this.params.mutatedPreloadedTraceIds,...this.movablePreloadedSections.map(t=\u003et.originalTrace.pcb_trace_id)]);return this.getUpdatedPreloadedTraces().filter(e=\u003et.has(e.pcb_trace_id))}visualize(){return this.exactRepairSolver?.visualize()??{}}},L9=1e-6,D9=(t,e,n)=\u003e{const o=ko(t,n),i=ko(e,n);return Array.from({length:Math.abs(i-o)+1},(t,e)=\u003eMath.min(o,i)+e)},z9=t=\u003e\"wire\"===t.route_type,F9=(t,e,n)=\u003et.portPoints.filter(t=\u003et.availableZ.includes(n)\u0026\u0026!(t._preloadedTracePortAssignments??[]).some(t=\u003et.z===n\u0026\u0026t.fixedNetId!==e.fixedNetId)).map(t=\u003e({portPoint:t,distance:be(t,e.start,e.end)})).sort((t,e)=\u003et.distance-e.distance||t.portPoint.distToCentermostPortOnZ-e.portPoint.distToCentermostPortOnZ||t.portPoint.segmentPortPointId.localeCompare(e.portPoint.segmentPortPointId))[0]?.portPoint,B9=(t,e,n)=\u003e{t._preloadedFixedNetIds=[...new Set([...t._preloadedFixedNetIds??[],e.fixedNetId])].sort();const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.start.x)*o+(t.y-e.start.y)*i)/r)),a={traceId:e.traceId,fixedNetId:e.fixedNetId,routePosition:e.routePositionStart+s*(e.routePositionEnd-e.routePositionStart),tracePoint:{x:e.start.x+s*o,y:e.start.y+s*i},z:n},c=t._preloadedTracePortAssignments??[];c.some(t=\u003et.traceId===a.traceId\u0026\u0026t.fixedNetId===a.fixedNetId\u0026\u0026t.z===a.z\u0026\u0026Math.abs(t.routePosition-a.routePosition)\u003c=L9)||(t._preloadedTracePortAssignments=[...c,a].sort((t,e)=\u003et.traceId.localeCompare(e.traceId)||t.routePosition-e.routePosition||t.z-e.z))},j9=class extends si{constructor(t,e){super(),this.sharedEdgeSegments=t,this.srj=e,this.MAX_ITERATIONS=1,this.primitives=(t=\u003e{const e=[],n=ii(t);for(const o of t.traces??[]){if(!o.connection_name)throw new Error(`Preloaded trace \"${o.pcb_trace_id}\" is missing a connection name`);const i=n.getNetConnectedToId(o.connection_name)??o.connection_name;for(const[n,r]of o.route.entries())if(\"via\"===r.route_type)e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n,zLayers:D9(r.from_layer,r.to_layer,t.layerCount),start:r,end:r});else if(\"through_obstacle\"===r.route_type)e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n+1,zLayers:D9(r.from_layer,r.to_layer,t.layerCount),start:r.start,end:r.end});else if(\"jumper\"===r.route_type){const s=ko(r.layer,t.layerCount);for(const[t,a]of[r.start,r.end].entries())e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n+t,routePositionEnd:n+t,zLayers:[s],start:a,end:a})}for(let n=0;n\u003co.route.length-1;n++){const r=o.route[n],s=o.route[n+1];z9(r)\u0026\u0026z9(s)\u0026\u0026r.layer===s.layer\u0026\u0026e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n+1,zLayers:[ko(r.layer,t.layerCount)],start:r,end:s})}}return e})(e)}sharedEdgeSegments;srj;primitives;getSolverName(){return\"PreloadedTraceGraphSolver\"}_step(){for(const t of this.primitives)for(const e of this.sharedEdgeSegments)if(!(Ra(t.start,t.end,e.start,e.end)\u003eL9))for(const n of t.zLayers){if(!e.availableZ.includes(n))continue;const o=F9(e,t,n);o\u0026\u0026B9(o,t,n)}const t=this.sharedEdgeSegments.flatMap(t=\u003et.portPoints),e=t.filter(t=\u003e(t._preloadedFixedNetIds?.length??0)\u003e0);this.stats={preloadedTraceCount:this.srj.traces?.length??0,preloadedTraceShapeCount:this.primitives.length,inputBoundaryCount:this.sharedEdgeSegments.length,outputBoundaryCount:this.sharedEdgeSegments.length,inputPortCount:t.length,outputPortCount:t.length,preloadedPortCount:e.length,tracePortAssignmentCount:e.reduce((t,e)=\u003et+(e._preloadedTracePortAssignments?.length??0),0),topologyChanged:!1},this.solved=!0}getOutput(){if(!this.solved)throw new Error(\"PreloadedTraceGraphSolver has not solved yet\");return this.sharedEdgeSegments}},$9=class extends _X{_step(){const{traces:t,...e}=this.inputSrj,n=fX(e),o=fX(aX(yX(n)));this.outputSrj=void 0===t?o:{...o,traces:t},this.solved=!0}};function Y9(t){return new Set((t??[]).filter(t=\u003et._isComponentTopologyNode).map(t=\u003et.capacityMeshNodeId))}function X9(t,e){return t.nodeIds.some(t=\u003ee.has(t))}function V9({sharedEdgeSegments:t,componentCapacityMeshNodeIds:e}){return t.filter(t=\u003e!X9(t,e))}function W9(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var H9=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e;const n=fX(t);this.originalSrj=n,this.opts={...e};const o=this.opts;if(this.effort=o.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=o.maxNodeDimension??15,this.maxNodeRatio=o.maxNodeRatio??6,this.minNodeArea=o.minNodeArea??.1**2,this.visualizationTraceColorMode=o.visualizationTraceColorMode??\"layer\",this.setSimpleRouteJson(n),void 0===o.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,n=Math.max(t,e),i=o.targetMinCapacity??.5;o.capacityDepth=$s(n,i)}this.cacheProvider=void 0===o.cacheProvider?oo():null===o.cacheProvider?null:o.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;getSolverName(){return\"AutoroutingPipelineSolver9_PreloadedTraceGraph\"}preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;componentTopologyGeneratorSolver;topologyPlanningSolver;topologyMergingSolver;globalTopologyGeneratorSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;pipeline9JointDrcRepairSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;mutatedPreloadedTraceSimplificationSolver;lengthMatchingPostProcessingSolver;powerTraceExpansionSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;preloadedTraceGraphSolver;componentDetectionSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;visualizationTraceColorMode;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;sharedEdgeSegmentsWithNecessaryCrampedPortPoints;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[W9(\"preprocessSimpleRouteJsonSolver\",$9,t=\u003e[t.originalSrj,{traceColorMode:t.visualizationTraceColorMode}],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),W9(\"componentDetectionSolver\",UZ,t=\u003e[{inputSrj:t.srj}]),W9(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),W9(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),W9(\"topologyPlanningSolver\",_q,t=\u003e[{inputSrj:t.srjWithPointPairs,componentDetectionOutput:t.componentDetectionSolver.getOutput(),viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.topologyPlanningSolver.getOutput();t.globalTopologyGeneratorSolver=t.topologyPlanningSolver.globalTopologySolver,t.componentTopologyGeneratorSolver=new vq(t.topologyPlanningSolver)}}),W9(\"topologyMergingSolver\",fq,t=\u003e{const e=t.topologyPlanningSolver.getOutput();return[{layerCount:t.srj.layerCount,nodeGroups:[{groupId:\"global\",nodes:e.globalMeshNodes,isComponent:!1},...e.componentMeshNodes.map((t,e)=\u003e({groupId:`component-${e}`,nodes:t,isComponent:!0}))]}]},{onSolved:t=\u003e{t.capacityNodes=t.topologyMergingSolver.getOutput()}}),W9(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver.outputNodes}}),W9(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),W9(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),W9(\"necessaryCrampedPortPointSolver\",sf,t=\u003e{const e=Y9(t.capacityNodes);return[{capacityMeshNodes:t.capacityNodes.filter(t=\u003e!e.has(t.capacityMeshNodeId)),sharedEdgeSegments:V9({sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),componentCapacityMeshNodeIds:e}),simpleRouteJson:t.srjWithPointPairs}]},{onSolved:t=\u003e{const e=Y9(t.capacityNodes);t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints=function({originalSharedEdgeSegments:t,filteredSharedEdgeSegments:e,componentCapacityMeshNodeIds:n}){const o=new Map(e.map(t=\u003e[t.edgeId,t]));return t.map(t=\u003eX9(t,n)?t:o.get(t.edgeId)??t)}({originalSharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),filteredSharedEdgeSegments:t.necessaryCrampedPortPointSolver.getOutput(),componentCapacityMeshNodeIds:e})}}),W9(\"preloadedTraceGraphSolver\",j9,t=\u003e[t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints,t.srjWithPointPairs]),W9(\"portPointPathingSolver\",jj,t=\u003e{const e=t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints??t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,preserveTerminalPcbPortIds:!0,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0,USE_SELECTIVE_RERIP_ROUTING:!0,USE_PARTIAL_RIP_ROUTING_WITH_PRELOADED_TRACES:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),W9(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),W9(\"highDensityRouteSolver\",VQ,t=\u003e{const e=t.portPointPathingSolver;if(!e)throw new Error(\"Pipeline9 invariant violated: high-density routing requires the completed port-point pathing solver\");const n=e.getOutput(),o=t.uniformPortDistributionSolver?.getOutput()??[],i=n.nodesWithPortPoints,r=o.length\u003e0?o:i;t.highDensityNodePortPoints=structuredClone(r);const s=(t.originalSrj.traces??[]).flatMap((e,n)=\u003eoQ(e,n,t.originalSrj.layerCount,t.viaDiameter,t.connMap));return[{nodePortPoints:r,fixedHdRoutes:TK({traces:t.originalSrj.traces??[],fixedHdRoutes:s,sections:t.getChangedPreloadedTraceSections()}),connMap:t.connMap,colorMap:t.colorMap,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,viaToPadClearance:t.srj.minViaEdgeToPadEdgeClearance,effort:t.effort,includeBoardObstacles:!0,nodePfById:new Map(n.inputNodeWithPortPoints.map(t=\u003e[t.capacityMeshNodeId,e.computeNodePf(t)])),preserveTerminalPcbPortIds:!0}]}),W9(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:AK(t.highDensityRouteSolver.routes),colorMap:t.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),W9(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2,maxSampleEntries:80,connMap:t.connMap}]),W9(\"highDensityStitchSolver\",KY,t=\u003e[{connections:[...t.srjWithPointPairs.connections,...t.getChangedPreloadedTraceSections().map(t=\u003et.connection)],hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,preserveTerminalPcbPortIds:!0,preferSameLayerTerminalEndpoints:!0}]),W9(\"traceSimplificationSolver\",vc,t=\u003e{const e=t.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces.flatMap((e,n)=\u003eoQ(e,n,t.originalSrj.layerCount,t.viaDiameter,t.connMap).map(t=\u003e({...t,rootConnectionName:e.connection_name}))),n=new Set(t.getChangedPreloadedTraceSections().map(t=\u003et.connectionName)),o=t.highDensityStitchSolver.mergedHdRoutes.filter(t=\u003e!n.has(t.connectionName)),i=IK([...o,...e],t.connMap);return[{hdRoutes:o,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,otherHdRoutes:e,netByConnectionName:i,enableCrossingViaReduction:!0,terminalLayerIndicesByPcbPortId:SK(t.srj.connections,t.srj.obstacles,t.srj.layerCount),iterations:2}]}),W9(\"mutatedPreloadedTraceSimplificationSolver\",vc,t=\u003e{const e=t.getPreparedMutatedPreloadedTraceSections(),n=e.sections.map(t=\u003et.hdRoute),o=[...e.immutableHdRoutes,...t.traceSimplificationSolver.simplifiedHdRoutes];return[{hdRoutes:n,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,otherHdRoutes:o,netByConnectionName:IK([...n,...o],t.connMap),enableCrossingViaReduction:!0,preserveRouteEndpoints:!0,iterations:2}]}),W9(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srjWithPointPairs.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),W9(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.getSrjWithMaterializedPreloadedTraces(),hdRoutes:KJ(t.traceWidthSolver.getHdRoutesWithWidths(),t.netToPointPairsSolver?.newConnections??[],new Map((t.highDensityStitchSolver?.mergedHdRoutes??[]).map(t=\u003e[t.connectionName,t]))),connMap:t.connMap,effort:t.effort,maxIterations:16,enableLargeBoardBroadFallback:!1,enablePostSolveClearanceRelaxation:!1}]),W9(\"pipeline9JointDrcRepairSolver\",k9,t=\u003e{const e=t.getPreloadedTraceUpdatesAfterHighDensity(),n=t.getSrjWithMaterializedPreloadedTraces();return[{srj:n,srjWithPointPairs:n,originalSrj:t.originalSrj,newConnections:t.netToPointPairsSolver?.newConnections??[],newHdRoutes:t.globalDrcForceImproveSolver.getOutput(),updatedPreloadedTraces:e.updatedPreloadedTraces,mutatedPreloadedTraceIds:new Set(e.mutatedPreloadedTraces.map(t=\u003et.pcb_trace_id)),connMap:t.connMap,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,defaultViaHoleDiameter:t.viaHoleDiameter,effort:t.effort,colorMap:t.colorMap}]}),W9(\"lengthMatchingPostProcessingSolver\",uK,t=\u003e{const e=t.netToPointPairsSolver;if(!e)throw new Error(\"Pipeline9: length-matching post-processing requires NetToPointPairsSolver output\");const n=e.newConnections,o=new Map;for(const e of t.srj.differentialPairs??[])for(const t of e.connectionNames){const e=n.filter(e=\u003ee.name===t||e.__rootConnectionNames?.includes(t)||e.__netConnectionName===t);if(1!==e.length)throw new Error(`Pipeline9: differential pair connection \"${t}\" must resolve to exactly one final point-pair connection, got ${e.length}`);o.set(t,e[0].name)}const i=t.pipeline9JointDrcRepairSolver.getOutput(),r=(t.srj.differentialPairs??[]).map(t=\u003e{const e=t.connectionNames.map(t=\u003e{const e=o.get(t);if(!e)throw new Error(`Pipeline9: differential pair connection \"${t}\" is missing from final routed output`);return e});if(e[0]===e[1])throw new Error(`Pipeline9: differential pair ${t.connectionNames.join(\"/\")} resolves both members to \"${e[0]}\"`);if(void 0===t.traceGap)return{connectionNames:e,lengthTolerance:t.lengthTolerance};const n=e.map(t=\u003e{const e=i.filter(e=\u003ee.connectionName===t);if(1!==e.length)throw new Error(`Pipeline9: differential pair connection \"${t}\" must resolve to exactly one final HD route, got ${e.length}`);return e[0]}),r=t.traceGap+n.reduce((t,e)=\u003et+e.traceThickness/2,0);return{connectionNames:e,lengthTolerance:t.lengthTolerance,minimumCenterlineDistance:r,maximumCenterlineDistance:r}});return[{hdRoutes:i,differentialPairs:r,buses:t.srj.buses??[],connections:t.srj.connections,obstacles:t.srj.obstacles,bounds:t.srj.bounds,layerCount:t.srj.layerCount,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15}]}),W9(\"powerTraceExpansionSolver\",UJ,t=\u003e{const e=t.opts.powerTraceExpansion??{},n=e.onlyConnectionNames??JJ(t.originalSrj);return[QJ({originalSrj:t.originalSrj,newlyRoutedTraces:t.getNewTracesBeforePowerExpansion(),currentPreloadedTraces:t.getUpdatedPreloadedTraces(),expandedConnectionNames:n,resolveConnectedTraceAliases:!0}),{allowNewVias:!1,...e,onlyConnectionNames:n}]})];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;computeProgress(){const t=this.activeSubSolver?.progress??0;return(this.currentPipelineStepIndex+t)/this.pipelineDef.length}_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\u0026\u0026(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),\"lengthMatchingPostProcessingSolver\"!==t.solverName\u0026\u0026\"powerTraceExpansionSolver\"!==t.solverName||(this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,this.iterations+this.activeSubSolver.MAX_ITERATIONS+1)),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\u0026\u0026this.activeSubSolver)return this.visualizeStage(this.activeSubSolver);const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.componentDetectionSolver?.visualize(),o=this.componentTopologyGeneratorSolver?.visualize(),i=this.globalTopologyGeneratorSolver?.visualize(),r=this.topologyMergingSolver?.visualize(),s=this.nodeDimensionSubdivisionSolver?.visualize(),a=this.nodeTargetMerger?.visualize(),c=this.singleLayerNodeMerger?.visualize(),l=this.strawSolver?.visualize(),d=this.edgeSolver?.visualize(),h=this.deadEndSolver?.visualize(),u=this.availableSegmentPointSolver?.visualize(),p=this.portPointPathingSolver?.visualize(),m=this.multiSectionPortPointOptimizer?.visualize(),g=this.uniformPortDistributionSolver?.visualize(),f=this.highDensityRouteSolver?.visualize(),y=this.highDensityForceImproveSolver?.visualize(),_=this.highDensityRepairSolver?.visualize(),b=this.highDensityStitchSolver?.visualize(),x=this.traceSimplificationSolver?.visualize(),v=this.mutatedPreloadedTraceSimplificationSolver?.visualize(),S=this.lengthMatchingPostProcessingSolver?.visualize(),I=this.powerTraceExpansionSolver?.visualize(),C=this.traceWidthSolver?.visualize(),P=this.necessaryCrampedPortPointSolver?.visualize(),M=(this.highDensityRouteSolver?.visualize(),this.originalSrj),N=M.outline,w=[];if(w.push({points:[{x:M.bounds?.minX??-50,y:M.bounds?.minY??-50},{x:M.bounds?.maxX??50,y:M.bounds?.minY??-50},{x:M.bounds?.maxX??50,y:M.bounds?.maxY??50},{x:M.bounds?.minX??-50,y:M.bounds?.maxY??50},{x:M.bounds?.minX??-50,y:M.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),N\u0026\u0026N.length\u003e=2){const t=N.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),w.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const T=Oo(M),R={points:[...M.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,M.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(M.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,M.layerCount),label:T(t)}))],lines:w},E={traceColorMode:this.visualizationTraceColorMode},A=Yj({srj:M,visualizationOptions:E}),O=pi(R,A),k=this.preprocessSimpleRouteJsonSolver?.visualize(),L=this.globalDrcForceImproveSolver?.visualize(),D=this.pipeline9JointDrcRepairSolver?.visualize(),z=[O,k,n,o,t,e,i,r,s,a,c,l,d,h,u,P,p,m,g,f?pi(R,f):null,y,_,b,x,v,C,L,D,S,I,this.solved?pi({lines:w},Yj({srj:this.originalSrj,visualizationOptions:E}),this.visualizeFinalOutput()):null].filter(Boolean),F=pi(...z);return\"net\"===this.visualizationTraceColorMode?xq(F,this.colorMap):F}visualizeStage(t){const e=t.visualize();return\"net\"===this.visualizationTraceColorMode?xq(e,this.colorMap):e}visualizeFinalOutput(){const t=this.visualizationTraceColorMode,e=this.getOutputSimpleRouteJson();return Ho(e,{traceColorMode:t})}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.componentTopologyGeneratorSolver?this.componentTopologyGeneratorSolver.visualize():this.componentDetectionSolver?this.componentDetectionSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){if(((this.originalSrj.differentialPairs?.length??0)\u003e0||(this.originalSrj.buses??[]).some(t=\u003evoid 0!==t.maxLengthSkew))\u0026\u0026this.lengthMatchingPostProcessingSolver){const{hdRoutes:t}=this.lengthMatchingPostProcessingSolver.getOutput();return t}return this.pipeline9JointDrcRepairSolver?.getOutput()??this.globalDrcForceImproveSolver?.getOutput()??this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOriginalFixedHdRoutes(){return(this.originalSrj.traces??[]).flatMap((t,e)=\u003eoQ(t,e,this.originalSrj.layerCount,this.viaDiameter,this.connMap))}getChangedPreloadedTraceSections(){return this.portPointPathingSolver?.getOutput().changedPreloadedTraceSections??[]}getPreloadedFixedRouteStateAfterHighDensity(){const t=this.getOriginalFixedHdRoutes(),e=this.getChangedPreloadedTraceSections(),n=TK({traces:this.originalSrj.traces??[],fixedHdRoutes:t,sections:e}),o=0===e.length?[]:RK({traces:this.originalSrj.traces??[],sections:e,stitchedHdRoutes:this.highDensityStitchSolver?.mergedHdRoutes??[],layerCount:this.originalSrj.layerCount}),i=new Set(e.map(t=\u003et.traceId)),r=t.filter(t=\u003ei.has(this.originalSrj.traces?.[t.preloadedTraceIndex]?.pcb_trace_id??\"\")).map(t=\u003et.connectionName);return{originalFixedRoutes:t,updatedFixedRoutes:[...this.highDensityRouteSolver?.getUpdatedFixedHdRoutes()??n,...o],replacedConnectionNames:new Set([...this.highDensityRouteSolver?.fixedRouteReplacements.keys()??[],...r]),mutationMasks:new Map([...this.highDensityRouteSolver?.preloadedTraceMutationMasks??[],...o.map(t=\u003e[t.connectionName,Array(t.route.length-1).fill(!0)])])}}getPreparedMutatedPreloadedTraceSections(){const t=this.getPreloadedFixedRouteStateAfterHighDensity();return eQ({updatedFixedRoutes:t.updatedFixedRoutes,regionalMutationMasks:t.mutationMasks})}getPreloadedTraceUpdatesAfterHighDensity(){const t=this.getPreloadedFixedRouteStateAfterHighDensity(),e=this.getPreparedMutatedPreloadedTraceSections(),n=!0===this.mutatedPreloadedTraceSimplificationSolver?.solved?(({updatedFixedRoutes:t,sections:e,simplifiedHdRoutes:n})=\u003e{const o=new Set(e.map(t=\u003et.connectionName)),i=new Map(n.map(t=\u003e[t.connectionName,t]));if(i.size!==e.length||n.some(t=\u003e!o.has(t.connectionName)))throw new Error(`Pipeline9 trace simplification changed the mutation-section set (expected ${e.length}, got ${n.length})`);const r=new Map,s=new Set;for(const t of e){const e=i.get(t.connectionName);if(!e)throw new Error(`Pipeline9 trace simplification lost mutation section \"${t.connectionName}\"`);const n=e.route[0],o=e.route.at(-1);if(!(n\u0026\u0026o\u0026\u0026HK(n,t.section.start.point)\u0026\u0026HK(o,t.section.end.point)))throw new Error(`Pipeline9 trace simplification changed mutation-section boundary \"${t.connectionName}\"`);const a=XK(t.section,e),c=t.section.sourceRoutes[0];s.add(c.connectionName);for(const e of t.section.sourceRoutes){if(r.has(e.connectionName))throw new Error(`Pipeline9 attempted to simplify fixed route \"${e.connectionName}\" more than once`);r.set(e.connectionName,a)}}return t.flatMap(t=\u003e{const e=r.get(t.connectionName);return e?s.has(t.connectionName)?[e]:[]:[t]})})({updatedFixedRoutes:e.normalizedFixedRoutes,sections:e.sections,simplifiedHdRoutes:this.mutatedPreloadedTraceSimplificationSolver.simplifiedHdRoutes}):t.updatedFixedRoutes;return(({originalTraces:t,originalFixedRoutes:e,updatedFixedRoutes:n,replacedConnectionNames:o,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a})=\u003e{const c=new Map,l=new Map;for(const t of e){const e=c.get(t.preloadedTraceIndex)??[];e.push(t),c.set(t.preloadedTraceIndex,e)}for(const t of n){const e=l.get(t.preloadedTraceIndex)??[];e.push(t),l.set(t.preloadedTraceIndex,e)}const d=[];return{updatedPreloadedTraces:t.map((t,e)=\u003e{const n=(c.get(e)??[]).sort(fK);if(!n.some(t=\u003eo.has(t.connectionName)))return t;const h=(l.get(e)??[]).sort(fK),u=t.route.some(t=\u003e\"through_obstacle\"===t.route_type),p={...t,__replaces_pcb_trace_id:t.pcb_trace_id,route:u?xK({trace:t,originalTraceRoutes:n,updatedTraceRoutes:h,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a}):_K({trace:t,updatedTraceRoutes:h,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a})};return d.push(p),p}),mutatedPreloadedTraces:d}})({originalTraces:this.originalSrj.traces??[],originalFixedRoutes:t.originalFixedRoutes,updatedFixedRoutes:n,replacedConnectionNames:t.replacedConnectionNames,layerCount:this.originalSrj.layerCount,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.originalSrj.obstacles,connMap:this.connMap})}getSrjWithMaterializedPreloadedTraces(){return{...this.srjWithPointPairs,traces:this.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces}}getUpdatedPreloadedTraces(){return this.pipeline9JointDrcRepairSolver?.getUpdatedPreloadedTraces()??this.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces}getMutatedPreloadedTraces(){return this.pipeline9JointDrcRepairSolver?.getMutatedPreloadedTraces()??this.getPreloadedTraceUpdatesAfterHighDensity().mutatedPreloadedTraces}getNewTracesBeforePowerExpansion(){if(!this.highDensityRouteSolver)throw new Error(\"Cannot get new traces before high-density routing\");const t=qJ({connections:this.netToPointPairsSolver?.newConnections??[],originalConnections:this.originalSrj.connections,hdRoutes:this._getOutputHdRoutes(),layerCount:this.srj.layerCount,obstacles:this.srj.obstacles,defaultViaHoleDiameter:this.viaHoleDiameter,connMap:this.connMap});return vK(t,this.originalSrj.traces??[])}getPowerTraceExpansionFixedTraces(){if(!this.powerTraceExpansionSolver)throw new Error(\"Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver\");return this.powerTraceExpansionSolver.inputSrj.fixedTraces}getOutputSimplifiedPcbTraces(){if(!this.solved)throw new Error(\"Cannot get output before solving is complete\");if(!this.powerTraceExpansionSolver)throw new Error(\"Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver\");return[...this.getPowerTraceExpansionFixedTraces().filter(t=\u003evoid 0!==t.__replaces_pcb_trace_id),...this.powerTraceExpansionSolver.getOutput()]}getOutputSimpleRouteJson(){if(!this.solved)throw new Error(\"Cannot get output before solving is complete\");if(!this.powerTraceExpansionSolver)throw new Error(\"Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver\");const t=[...this.getPowerTraceExpansionFixedTraces(),...this.powerTraceExpansionSolver.getOutput()];return{...this.originalSrj,traces:t}}},G9=String(\"0.0.886\"),U9=({nodeWithPortPoints:t,obstacleMargin:e,traceWidth:n,viaDiameter:o})=\u003e{const i=ro(t),r=e+Math.max(n,o)/2+1e-6;return{minX:t.center.x+8*(i.minX-t.center.x)-r,maxX:t.center.x+8*(i.maxX-t.center.x)+r,minY:t.center.y+8*(i.minY-t.center.y)-r,maxY:t.center.y+8*(i.maxY-t.center.y)+r}},Z9=(t,e)=\u003e{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.abs(Math.cos(n)),i=Math.abs(Math.sin(n)),r=t.width/2,s=t.height/2,a=Math.max(r,r*o+s*i),c=Math.max(s,r*i+s*o);return t.center.x-a\u003c=e.maxX\u0026\u0026t.center.x+a\u003e=e.minX\u0026\u0026t.center.y-c\u003c=e.maxY\u0026\u0026t.center.y+c\u003e=e.minY},q9=(t,e)=\u003e{for(const n of[e.connectionName,e.rootConnectionName,e.portPointId,e.pcb_port_id,e.prevPortPointId,e.nextPortPointId])void 0!==n\u0026\u0026t.add(n)},J9=(t,e)=\u003eObject.fromEntries(Object.entries(t.netMap).flatMap(([t,n])=\u003e{const o=n.filter(t=\u003ee.has(t));return o.length\u003e0||e.has(t)?[[t,o]]:[]})),K9=({obstacle:t,connectedTo:e,preserveRotation:n})=\u003e({type:\"rect\",layers:t.layers,...void 0===t.zLayers?{}:{zLayers:t.zLayers},...void 0===t.__zLayers?{}:{__zLayers:t.__zLayers},center:t.center,width:t.width,height:t.height,...n\u0026\u0026void 0!==t.ccwRotationDegrees?{ccwRotationDegrees:t.ccwRotationDegrees}:{},connectedTo:e,...void 0===t.circuitJsonMetadata?{}:{circuitJsonMetadata:t.circuitJsonMetadata}});function Q9({nodeWithPortPoints:t,connMap:e,obstacles:n,obstacleMargin:o,traceWidth:i,viaDiameter:r}){const s=U9({nodeWithPortPoints:t,obstacleMargin:o,traceWidth:i,viaDiameter:r}),a=new Set;for(const e of t.portPoints)q9(a,e);for(const e of t.portPointsInPairs??[])q9(a,e[0]),q9(a,e[1]);const c=n.flatMap(n=\u003e{if(!Z9(n,s))return[];const o=(({obstacle:t,nodeWithPortPoints:e,connMap:n})=\u003e{const o=new Set(e.portPoints.flatMap(t=\u003e{const e=n.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName;return[t.connectionName,e]})),i=new Set(t.connectedTo.filter(t=\u003eo.has(t))),r=new Map;for(const t of o){const e=n.getNetConnectedToId(t)??t,o=r.get(e)??[];o.push(t),r.set(e,o)}for(const e of r.values()){if([...i].some(t=\u003ee.some(e=\u003ee===t||n.areIdsConnected(e,t))))continue;const o=t.connectedTo.find(t=\u003ee.some(e=\u003ee===t||n.areIdsConnected(e,t)));void 0!==o\u0026\u0026i.add(o)}return[...i]})({obstacle:n,nodeWithPortPoints:t,connMap:e});for(const t of o)a.add(t);return[K9({obstacle:n,connectedTo:o,preserveRotation:!0})]});return{connectivityNetMap:J9(e,a),obstacles:c}}var t8=(...t)=\u003e{const e=new Map;for(const n of t)for(const[t,o]of Object.entries(n)){const n=e.get(t)??new Set;for(const t of o)n.add(t);e.set(t,n)}return Object.fromEntries([...e].map(([t,e])=\u003e[t,[...e]]))};function e8({nodeWithPortPoints:t,connMap:e,colorMap:n,obstacles:o,obstacleMargin:i,traceWidth:r,viaDiameter:s}){const a=U9({nodeWithPortPoints:t,obstacleMargin:i,traceWidth:r,viaDiameter:s}),c=(t=\u003e[...new Set(t.portPoints.map(t=\u003et.connectionName))])(t),l=o.flatMap(t=\u003e{if(!Z9(t,a))return[];const n=c.filter(n=\u003et.connectedTo.some(t=\u003et===n||e.areIdsConnected(n,t)));return 0===n.length?[]:[K9({obstacle:t,connectedTo:n,preserveRotation:!1})]}),d=new Set;for(const e of t.portPoints)q9(d,e);for(const e of t.portPointsInPairs??[])q9(d,e[0]),q9(d,e[1]);for(const t of l)for(const e of[t.circuitJsonMetadata?.pcb_smtpad_id,t.circuitJsonMetadata?.pcb_plated_hole_id,t.circuitJsonMetadata?.pcb_port_id,t.circuitJsonMetadata?.pcb_via_id,...t.connectedTo??[]])void 0!==e\u0026\u0026d.add(e);return{connectivityNetMap:J9(e,d),colorMap:Object.fromEntries(Object.entries(n??{}).filter(([t])=\u003ed.has(t))),obstacles:l}}var n8=\"https://hd-cache2.tscircuit.com\",o8=31e4,i8=1835008,r8=16777216,s8=class extends Error{constructor(t,e){super(e),this.reason=t,this.name=\"HdCache2RequestError\"}reason},a8=t=\u003et instanceof Error?t.message:String(t),c8=new Set([\"pcb_smtpad_id\",\"pcb_plated_hole_id\",\"pcb_port_id\",\"pcb_via_id\",\"source_component_name\",\"source_port_name\"]),l8=t=\u003e!(!t||\"object\"!=typeof t||Array.isArray(t))\u0026\u0026Object.entries(t).every(([t,e])=\u003ec8.has(t)\u0026\u0026\"string\"==typeof e),d8=(t,e)=\u003eMath.abs(t-e)\u003c=1e-9*Math.max(1,Math.abs(t),Math.abs(e)),h8=1e-6,u8=(t,e)=\u003e{const n=\"ordinary\"===e?h8:.001,o=new Set;for(let i=0;i\u003ct.route.length-1;i++){const r=t.route[i],s=t.route[i+1],a=r.z!==s.z;if(\"through_obstacle\"===r.toNextSegmentType){if(!a)return!1;continue}if(void 0!==r.toNextSegmentCircuitJsonMetadata)return!1;if(!a)continue;const c=[],l=[];for(const[e,o]of t.vias.entries())Math.hypot(o.x-r.x,o.y-r.y)\u003c=n\u0026\u0026c.push(e),Math.hypot(o.x-s.x,o.y-s.y)\u003c=n\u0026\u0026l.push(e);if(Math.hypot(r.x-s.x,r.y-s.y)\u003c=h8){if(0===c.length)return!1;for(const t of c)o.add(t)}else{if(\"regional-fallback\"===e)return!1;if(0===c.length==(0===l.length))return!1;for(const t of[...c,...l])o.add(t)}}const i=t.route.at(-1);return void 0===i.toNextSegmentType\u0026\u0026void 0===i.toNextSegmentCircuitJsonMetadata\u0026\u0026t.vias.every((t,e)=\u003eo.has(e))},p8=(t,e,n)=\u003e{if(!Array.isArray(t))return!1;const o=new Map;for(const t of e.nodeWithPortPoints.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}const i=new Set(e.nodeWithPortPoints.availableZ??e.nodeWithPortPoints.portPoints.map(t=\u003et.z)),r=U9({nodeWithPortPoints:e.nodeWithPortPoints,obstacleMargin:e.obstacleMargin,traceWidth:e.traceWidth,viaDiameter:e.viaDiameter}),s=(t,e)=\u003e(o.get(e)??[]).some(e=\u003e\"number\"==typeof t.x\u0026\u0026d8(t.x,e.x)\u0026\u0026\"number\"==typeof t.y\u0026\u0026d8(t.y,e.y)\u0026\u0026t.z===e.z);for(const a of t){if(!a||\"object\"!=typeof a)return!1;const t=a;if(\"string\"!=typeof t.connectionName||0===t.connectionName.length||!o.has(t.connectionName)||\"number\"!=typeof t.traceThickness||!Number.isFinite(t.traceThickness)||t.traceThickness\u003c=0||\"number\"!=typeof t.viaDiameter||!Number.isFinite(t.viaDiameter)||t.viaDiameter\u003c=0||!d8(t.viaDiameter,e.viaDiameter)||!Array.isArray(t.route)||t.route.length\u003c2||!Array.isArray(t.vias))return!1;for(const e of[t.rootConnectionName,t.startPcbPortId,t.endPcbPortId,t.regionId])if(void 0!==e\u0026\u0026\"string\"!=typeof e)return!1;for(const o of t.route){if(!o||\"object\"!=typeof o)return!1;const t=o;if(\"number\"!=typeof t.x||!Number.isFinite(t.x)||\"number\"!=typeof t.y||!Number.isFinite(t.y)||t.x\u003cr.minX||t.x\u003er.maxX||t.y\u003cr.minY||t.y\u003er.maxY||\"number\"!=typeof t.z||!Number.isInteger(t.z)||t.z\u003c0||t.z\u003e=e.layerCount||\"ordinary\"===n\u0026\u0026!i.has(t.z))return!1;if(void 0!==t.traceThickness\u0026\u0026(\"number\"!=typeof t.traceThickness||!Number.isFinite(t.traceThickness)||t.traceThickness\u003c=0))return!1;if(void 0!==t.pcb_port_id\u0026\u0026\"string\"!=typeof t.pcb_port_id)return!1;if(void 0!==t.insideJumperPad\u0026\u0026\"boolean\"!=typeof t.insideJumperPad)return!1;if(void 0!==t.toNextSegmentType\u0026\u0026\"through_obstacle\"!==t.toNextSegmentType)return!1;if(void 0!==t.toNextSegmentCircuitJsonMetadata\u0026\u0026!l8(t.toNextSegmentCircuitJsonMetadata))return!1}const c=t.route;if(!(\"ordinary\"!==n||s(c[0],t.connectionName)\u0026\u0026s(c.at(-1),t.connectionName)))return!1;for(const e of t.vias){if(!e||\"object\"!=typeof e)return!1;const t=e;if(\"number\"!=typeof t.x||!Number.isFinite(t.x)||\"number\"!=typeof t.y||!Number.isFinite(t.y)||t.x\u003cr.minX||t.x\u003er.maxX||t.y\u003cr.minY||t.y\u003er.maxY)return!1}if(!u8(t,n))return!1;if(void 0!==t.jumpers){if(!Array.isArray(t.jumpers))return!1;for(const e of t.jumpers){if(!e||\"object\"!=typeof e)return!1;const t=e,n=t.start,o=t.end;if(\"jumper\"!==t.route_type||\"0603\"!==t.footprint\u0026\u0026\"1206\"!==t.footprint\u0026\u0026\"1206x4_pair\"!==t.footprint||!n||\"number\"!=typeof n.x||!Number.isFinite(n.x)||\"number\"!=typeof n.y||!Number.isFinite(n.y)||!o||\"number\"!=typeof o.x||!Number.isFinite(o.x)||\"number\"!=typeof o.y||!Number.isFinite(o.y)||n.x\u003cr.minX||n.x\u003er.maxX||n.y\u003cr.minY||n.y\u003er.maxY||o.x\u003cr.minX||o.x\u003er.maxX||o.y\u003cr.minY||o.y\u003er.maxY)return!1}}}const a=t;return\"ordinary\"===n?((t,e)=\u003e{const n=e.portPointsInPairs??[];if(n.length\u003e0){for(const[e,o]of n)if(!xs(t,e.connectionName,_s(e)).has(_s(o)))return!1;return!0}const o=new Map;for(const t of e.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}for(const[e,n]of o)for(const[o,i]of Dr(n))if(!xs(t,e,_s(o)).has(_s(i)))return!1;return!0})(a,e.nodeWithPortPoints):((t,e)=\u003e{const n=(t,e)=\u003e{if(t.z!==e.z)return!1;const n=t.x-e.x,o=t.y-e.y;return Math.hypot(n,o)\u003c=.001},o=new Map;for(const i of t){const t=i.route.some((t,e)=\u003e{const n=i.route[e+1];return!(void 0===n||d8(t.x,n.x)\u0026\u0026d8(t.y,n.y)\u0026\u0026t.z===n.z)}),r=i.route[0],s=i.route.at(-1);if(!t||!r||!s)return!1;const a=e.portPoints.filter(t=\u003et.connectionName===i.connectionName);if(!a.some(t=\u003en(r,t))||!a.some(t=\u003en(s,t)))return!1;const c=o.get(i.connectionName)??[];c.push({start:r,end:s}),o.set(i.connectionName,c)}const i=(t,e,i)=\u003e{if(n(e,i))return!0;const r=o.get(t)??[],s=[],a=new Set;for(const[t,o]of r.entries())(n(e,o.start)||n(e,o.end))\u0026\u0026(s.push(t),a.add(t));for(;s.length\u003e0;){const t=r[s.pop()];if(n(i,t.start)||n(i,t.end))return!0;for(const[e,o]of r.entries())a.has(e)||(n(t.start,o.start)||n(t.start,o.end)||n(t.end,o.start)||n(t.end,o.end))\u0026\u0026(a.add(e),s.push(e))}return!1},r=e.portPointsInPairs??[];if(r.length\u003e0)return r.every(([t,e])=\u003ei(t.connectionName,t,e));const s=new Map;for(const t of e.portPoints){const e=s.get(t.connectionName)??[];e.push(t),s.set(t.connectionName,e)}return[...s].every(([,t])=\u003eDr(t).every(([t,e])=\u003ei(t.connectionName,t,e)))})(a,e.nodeWithPortPoints)},m8=class{constructor(t,e=n8,n={}){this.autorouterVersion=t,this.serverUrl=e;const{cacheVersion:o}=n;if(void 0!==o\u0026\u00260===o.trim().length)throw new Error(\"hd-cache2 cacheVersion must not be empty\");this.cacheVersion=o}autorouterVersion;serverUrl;cacheVersion;stats={batchRequestsStarted:0,batchRequestsCompleted:0,batchItemsStarted:0,batchBodyBytesStarted:0,batchMaxBodyBytes:0,batchCacheMisses:0,singleRequestsStarted:0,batchInvalidLines:0,batchUnknownRequestIds:0,batchDuplicateRequestIds:0};solveMany(t){const e=t.map((t,e)=\u003ethis.createPendingSolve(String(e),t)),n=e.filter(t=\u003enull!==t.serializedItem),{batches:o,singletonSolves:i}=this.prepareBatches(n);for(const t of o)this.fetchBatch(t);for(const t of i)this.launchSingleSolve(t);return e.map(t=\u003et.promise)}createPendingSolve(t,e){let n;const o={requestId:t,input:e,serializedItem:null,promise:new Promise(t=\u003e{n=t}),resolve:n,settled:!1,singleSolveStarted:!1};try{o.serializedItem=JSON.stringify({requestId:t,input:e})}catch(t){this.settleWithFallback(o,\"request_serialization_error\",a8(t))}return o}settle(t,e){t.settled||(t.settled=!0,t.resolve(e))}settleWithFallback(t,e,n){this.settle(t,{kind:\"local-fallback\",reason:e,error:n})}parseSuccessfulResponse(t,e){if(!t||\"object\"!=typeof t||Array.isArray(t))throw new s8(\"invalid_response\",\"hd-cache2 returned a non-object response\");const n=t;if(!0!==n.ok)throw new s8(\"remote_error\",\"string\"==typeof n.message?n.message:\"hd-cache2 returned an unsuccessful response\");if(n.autorouterVersion!==this.autorouterVersion)throw new s8(\"version_mismatch\",`hd-cache2 returned autorouter version ${String(n.autorouterVersion)}, expected ${this.autorouterVersion}`);if(n.cacheVersion!==this.cacheVersion)throw new s8(\"cache_version_mismatch\",`hd-cache2 returned cache version ${String(n.cacheVersion)}, expected ${String(this.cacheVersion)}`);if(\"cache\"!==n.source\u0026\u0026\"solver\"!==n.source)throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid cache source\");if(\"ordinary\"!==n.solutionStage\u0026\u0026\"regional-fallback\"!==n.solutionStage)throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid solution stage\");if(\"regional-fallback\"===n.solutionStage\u0026\u0026(!e.enableRegionalFallback||\"string\"!=typeof n.ordinaryFailure||0===n.ordinaryFailure.length))throw new s8(\"invalid_response\",\"hd-cache2 returned invalid regional fallback metadata\");if(\"ordinary\"===n.solutionStage\u0026\u0026Object.prototype.hasOwnProperty.call(n,\"ordinaryFailure\"))throw new s8(\"invalid_response\",\"hd-cache2 returned regional metadata on an ordinary result\");if(\"ordinary\"===n.solutionStage\u0026\u0026\"failed\"===n.status\u0026\u0026e.enableRegionalFallback)throw new s8(\"invalid_response\",\"hd-cache2 returned an intermediate ordinary failure\");if(\"solved\"===n.status\u0026\u0026p8(n.routes,e,n.solutionStage))return n;if(\"failed\"===n.status\u0026\u0026\"string\"==typeof n.error\u0026\u0026n.error.length\u003e0)return n;throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid solve result\")}parseBatchCacheMiss(t){if(!1!==t.ok||\"CACHE_MISS\"!==t.code)return null;if(t.autorouterVersion!==this.autorouterVersion)throw new s8(\"version_mismatch\",`hd-cache2 returned autorouter version ${String(t.autorouterVersion)}, expected ${this.autorouterVersion}`);if(t.cacheVersion!==this.cacheVersion)throw new s8(\"cache_version_mismatch\",`hd-cache2 returned cache version ${String(t.cacheVersion)}, expected ${String(this.cacheVersion)}`);if(\"string\"!=typeof t.message)throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid cache miss response\");return t}async fetchSingle(t){const e=new AbortController;let n=!1;const o=setTimeout(()=\u003e{n=!0,e.abort(new Error(\"hd-cache2 transport timed out after 310000ms\"))},o8);o.unref?.();try{const n={autorouterVersion:this.autorouterVersion,...void 0===this.cacheVersion?{}:{cacheVersion:this.cacheVersion},input:t.input};let o;try{o=JSON.stringify(n)}catch(t){throw new s8(\"request_serialization_error\",a8(t))}const r=await fetch((i=this.serverUrl,/\\/solve\\/?$/.test(i)?i.replace(/\\/+$/,\"\"):`${i.replace(/\\/+$/,\"\")}/solve`),{method:\"POST\",headers:{accept:\"application/json\",\"content-type\":\"application/json\"},body:o,signal:e.signal}),s=await r.text();let a=null;try{a=s?JSON.parse(s):null}catch{if(!r.ok)throw new s8(\"http_error\",`hd-cache2 request failed with status ${r.status}`);throw new s8(\"invalid_json\",`hd-cache2 returned invalid JSON with status ${r.status}`)}if(!r.ok){const t=a\u0026\u0026\"object\"==typeof a\u0026\u0026\"message\"in a\u0026\u0026\"string\"==typeof a.message?a.message:`hd-cache2 request failed with status ${r.status}`;throw new s8(\"http_error\",t)}this.settle(t,{kind:\"remote\",response:this.parseSuccessfulResponse(a,t.input)})}catch(e){const o=e instanceof s8?e.reason:n?\"transport_timeout\":\"transport_error\";this.settleWithFallback(t,o,a8(e))}finally{clearTimeout(o)}var i}launchSingleSolve(t){t.singleSolveStarted||t.settled||(t.singleSolveStarted=!0,this.stats.singleRequestsStarted+=1,this.fetchSingle(t))}handleBatchResponseLine(t,e,n){if(0===t.trim().length)return;if(t.length\u003er8)throw new s8(\"response_too_large\",\"hd-cache2 returned an oversized batch result line\");let o;try{o=JSON.parse(t)}catch{return void(this.stats.batchInvalidLines+=1)}if(!o||\"object\"!=typeof o||Array.isArray(o))return void(this.stats.batchInvalidLines+=1);const i=o,r=i.requestId;if(\"string\"!=typeof r)return void(this.stats.batchInvalidLines+=1);const s=e.get(r);if(s)if(n.has(r))this.stats.batchDuplicateRequestIds+=1;else{n.add(r);try{if(this.parseBatchCacheMiss(i))return this.stats.batchCacheMisses+=1,void this.launchSingleSolve(s);this.settle(s,{kind:\"remote\",response:this.parseSuccessfulResponse(i,s.input)})}catch(t){this.stats.batchInvalidLines+=1,this.settleWithFallback(s,t instanceof s8?t.reason:\"invalid_response\",a8(t))}}else this.stats.batchUnknownRequestIds+=1}async readBatchResponse(t,e){if(!t.body)throw new s8(\"invalid_response\",\"hd-cache2 returned an empty batch response body\");const n=new Map(e.items.map(t=\u003e[t.requestId,t])),o=new Set,i=new TextDecoder,r=t.body.getReader();let s=\"\";for(;o.size\u003ce.items.length;){const{done:t,value:e}=await r.read();if(s+=i.decode(e,{stream:!t}),s.length\u003er8\u0026\u0026!s.includes(\"\\n\"))throw new s8(\"response_too_large\",\"hd-cache2 returned an oversized unterminated batch result line\");let a=s.indexOf(\"\\n\");for(;a\u003e=0;){const t=s.slice(0,a);s=s.slice(a+1),this.handleBatchResponseLine(t,n,o),a=s.indexOf(\"\\n\")}if(t){s.trim().length\u003e0\u0026\u0026this.handleBatchResponseLine(s,n,o);break}}if(o.size!==e.items.length)for(const t of e.items)o.has(t.requestId)||this.settleWithFallback(t,\"missing_response\",`hd-cache2 batch ended without result ${t.requestId}`);else await r.cancel().catch(()=\u003e{})}async fetchBatch(t){const e=new AbortController;let n=!1;const o=setTimeout(()=\u003e{n=!0,e.abort(new Error(\"hd-cache2 batch transport timed out after 310000ms\"))},o8);o.unref?.(),this.stats.batchRequestsStarted+=1,this.stats.batchItemsStarted+=t.items.length,this.stats.batchBodyBytesStarted+=t.bodyBytes,this.stats.batchMaxBodyBytes=Math.max(this.stats.batchMaxBodyBytes,t.bodyBytes);try{const n=await fetch((t=\u003e{const e=t.replace(/\\/+$/,\"\");return/\\/solve-batch$/.test(e)?e:/\\/solve$/.test(e)?e.replace(/\\/solve$/,\"/solve-batch\"):`${e}/solve-batch`})(this.serverUrl),{method:\"POST\",headers:{accept:\"application/x-ndjson\",\"content-type\":\"application/json\"},body:t.body,signal:e.signal});if(!n.ok){const t=await n.text().catch(()=\u003e\"\");let e=`hd-cache2 batch request failed with status ${n.status}`;try{const n=t?JSON.parse(t):null;n\u0026\u0026\"object\"==typeof n\u0026\u0026\"message\"in n\u0026\u0026\"string\"==typeof n.message\u0026\u0026(e=n.message)}catch{}throw new s8(\"http_error\",e)}await this.readBatchResponse(n,t)}catch(e){const o=e instanceof s8?e.reason:n?\"transport_timeout\":\"transport_error\";for(const n of t.items)n.singleSolveStarted||this.settleWithFallback(n,o,a8(e))}finally{clearTimeout(o),this.stats.batchRequestsCompleted+=1}}prepareBatches(t){const e=new TextEncoder,n=void 0===this.cacheVersion?\"\":`,\"cacheVersion\":${JSON.stringify(this.cacheVersion)}`,o=`{\"autorouterVersion\":${JSON.stringify(this.autorouterVersion)}${n},\"items\":[`,i=e.encode(o+\"]}\").byteLength,r=[],s=[];let a=[],c=i;const l=()=\u003e{0!==a.length\u0026\u0026(r.push({body:`${o}${a.map(t=\u003et.serializedItem).join(\",\")}]}`,bodyBytes:c,items:a}),a=[],c=i)};for(const n of t){const t=e.encode(n.serializedItem).byteLength,o=0===a.length?0:1;i+t\u003ei8?(l(),s.push(n)):((a.length\u003e=100||c+o+t\u003ei8)\u0026\u0026l(),a.push(n),c+=(1===a.length?0:1)+t)}return l(),{batches:r,singletonSolves:s}}},g8=\"ordinary_then_regional_without_fixed_copper_v1\",f8=class extends VQ{autorouterVersion;hdCache2ServerUrl;hdCache2CacheVersion;requestTimeoutMs;hdCache2Client;launchedRemoteSolves=!1;waitingForRemoteNode=null;remoteRequestByNode=new Map;remoteResultByNode=new Map;logicallyTimedOutNodes=new Set;constructor({autorouterVersion:t,hdCache2ServerUrl:e,hdCache2CacheVersion:n,requestTimeoutMs:o,...i}){if(super(i),1!==i.effort)throw new Error(`Pipeline9 networked high-density routing requires effort=1, received ${i.effort}`);if(this.requestTimeoutMs=o??3e4,!Number.isFinite(this.requestTimeoutMs)||this.requestTimeoutMs\u003c=0)throw new Error(`Pipeline9 network request timeout must be a positive number, received ${this.requestTimeoutMs}`);this.autorouterVersion=t,this.hdCache2ServerUrl=e??n8,this.hdCache2CacheVersion=n,this.hdCache2Client=new m8(this.autorouterVersion,this.hdCache2ServerUrl,{cacheVersion:n}),this.pendingEffects=[],this.stats={...this.stats,remoteRequestsStarted:0,remoteRequestsCompleted:0,remoteBatchRequestsStarted:0,remoteBatchRequestsCompleted:0,remoteBatchItemsStarted:0,remoteBatchBodyBytesStarted:0,remoteBatchMaxBodyBytes:0,remoteBatchCacheMisses:0,remoteSingleRequestsStarted:0,remoteBatchInvalidLines:0,remoteBatchUnknownRequestIds:0,remoteBatchDuplicateRequestIds:0,remoteCacheHits:0,remoteSolverResults:0,remoteSolvedResults:0,remoteFailedResults:0,remoteOrdinaryResults:0,remoteRegionalFallbackResults:0,remoteRegionalFallbackResultsApplied:0,remoteRegionalFallbackResultsDeferredToLocal:0,remoteTransportFallbacks:0,remoteLogicalTimeoutFallbacks:0,remoteFallbackReasonCounts:{}}}getSolverName(){return\"Pipeline9NetworkedHighDensitySolver\"}async waitForAllRemoteRequests(){const t=[...this.remoteRequestByNode.values()];0!==t.length?(await Promise.all(t.map(({promise:t})=\u003et)),this.syncClientStats()):this.syncClientStats()}createNodeInput(t){const e=this.enableRegionalFallback?Q9({nodeWithPortPoints:t,connMap:this.connMap,obstacles:this.obstacles,obstacleMargin:this.obstacleMargin,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter}):{connectivityNetMap:{},obstacles:[]},n=e8({nodeWithPortPoints:t,connMap:this.connMap,colorMap:this.colorMap,obstacles:this.enableRegionalFallback?e.obstacles:this.obstacles,obstacleMargin:this.obstacleMargin,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter});return{solvePolicy:g8,enableRegionalFallback:this.enableRegionalFallback,nodeWithPortPoints:t,connectivityNetMap:t8(n.connectivityNetMap,e.connectivityNetMap),colorMap:n.colorMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:1,obstacles:n.obstacles,regionalObstacles:e.obstacles,layerCount:this.layerCount,nodePf:this.nodePfById.get(t.capacityMeshNodeId)??null}}syncClientStats(){const t=this.hdCache2Client.stats;this.stats.remoteBatchRequestsStarted=t.batchRequestsStarted,this.stats.remoteBatchRequestsCompleted=t.batchRequestsCompleted,this.stats.remoteBatchItemsStarted=t.batchItemsStarted,this.stats.remoteBatchBodyBytesStarted=t.batchBodyBytesStarted,this.stats.remoteBatchMaxBodyBytes=t.batchMaxBodyBytes,this.stats.remoteBatchCacheMisses=t.batchCacheMisses,this.stats.remoteSingleRequestsStarted=t.singleRequestsStarted,this.stats.remoteBatchInvalidLines=t.batchInvalidLines,this.stats.remoteBatchUnknownRequestIds=t.batchUnknownRequestIds,this.stats.remoteBatchDuplicateRequestIds=t.batchDuplicateRequestIds}recordFallbackReason(t){const e=this.stats.remoteFallbackReasonCounts;e[t]=(e[t]??0)+1}trackRemoteSolve(t,e){const n=performance.now()+this.requestTimeoutMs;this.stats.remoteRequestsStarted+=1;const o=e.then(e=\u003e{const n=this.logicallyTimedOutNodes.has(t);n||this.remoteResultByNode.set(t,e),\"remote\"===e.kind?(\"cache\"===e.response.source\u0026\u0026(this.stats.remoteCacheHits+=1),\"solver\"===e.response.source\u0026\u0026(this.stats.remoteSolverResults+=1),\"solved\"===e.response.status?this.stats.remoteSolvedResults+=1:this.stats.remoteFailedResults+=1):n||(this.stats.remoteTransportFallbacks+=1,this.recordFallbackReason(e.reason)),this.stats.remoteRequestsCompleted+=1,this.syncClientStats()});this.remoteRequestByNode.set(t,{promise:o,deadlineAt:n})}launchRemoteSolves(){const t=[],e=[...this.unsolvedNodePortPoints].reverse();for(const n of e)try{t.push({node:n,input:this.createNodeInput(n)})}catch(t){this.trackRemoteSolve(n,Promise.resolve({kind:\"local-fallback\",reason:\"request_serialization_error\",error:t instanceof Error?t.message:String(t)}))}const n=this.hdCache2Client.solveMany(t.map(({input:t})=\u003et));for(const[e,o]of n.entries())this.trackRemoteSolve(t[e].node,o);this.syncClientStats()}async waitForCurrentRemoteNode(t,e){const n=e.deadlineAt-performance.now();if(n\u003c=0)return void this.recordLogicalTimeout(t);let o;const i=await Promise.race([e.promise.then(()=\u003e\"request-settled\"),new Promise(t=\u003e{o=setTimeout(()=\u003et(\"logical-timeout\"),n)})]);void 0!==o\u0026\u0026clearTimeout(o),\"logical-timeout\"===i\u0026\u0026this.recordLogicalTimeout(t)}recordLogicalTimeout(t){this.logicallyTimedOutNodes.add(t),this.stats.remoteLogicalTimeoutFallbacks+=1,this.stats.remoteTransportFallbacks+=1,this.recordFallbackReason(\"logical_timeout\")}startRegularSolver(t){const e=this.remoteResultByNode.get(t);if(!e){const e=this.remoteRequestByNode.get(t);if(e){this.waitingForRemoteNode=t;const n=this.waitForCurrentRemoteNode(t,e);n.then(()=\u003e{this.waitingForRemoteNode===t\u0026\u0026(this.pendingEffects=[])});const o={name:`hd-cache2:${t.capacityMeshNodeId}`,promise:n};return void(this.pendingEffects=[o])}return void super.startRegularSolver(t)}this.applyRemoteResultToRegularNode(t,e)}applyRemoteResultToRegularNode(t,e){if(\"local-fallback\"!==e.kind){if(this.stats.regularNodeCount=Number(this.stats.regularNodeCount??0)+1,this.activeNode=t,\"regional-fallback\"===e.response.solutionStage){if(this.stats.remoteRegionalFallbackResults+=1,!this.canUseNoFixedCopperRegionalResult(t))return this.stats.remoteRegionalFallbackResultsDeferredToLocal+=1,void this.finishRegularSolverFailure(e.response.ordinaryFailure);this.stats.remoteRegionalFallbackResultsApplied+=1,this.stats.fallbackNodeCount=Number(this.stats.fallbackNodeCount??0)+1}else this.stats.remoteOrdinaryResults+=1;if(\"failed\"===e.response.status)return this.error=e.response.error,this.failed=!0,void(this.activeNode=null);this.finishActiveNode(e.response.routes)}else super.startRegularSolver(t)}canUseNoFixedCopperRegionalResult(t){const e={...YQ(t,this.connMap),availableZ:Array.from({length:this.layerCount},(t,e)=\u003ee)},n=$K(e,this.getUpdatedFixedHdRoutes());return 0===n.fixedRouteSectionsByConnectionName.size\u0026\u00260===n.fixedObstacleRoutes.length}_step(){if(this.syncClientStats(),this.launchedRemoteSolves||(this.launchedRemoteSolves=!0,this.launchRemoteSolves()),this.waitingForRemoteNode){const t=this.waitingForRemoteNode;if(this.logicallyTimedOutNodes.has(t))return this.waitingForRemoteNode=null,this.pendingEffects=[],void super.startRegularSolver(t);const e=this.remoteResultByNode.get(t);if(!e)return;return this.waitingForRemoteNode=null,this.pendingEffects=[],void this.applyRemoteResultToRegularNode(t,e)}super._step()}},y8=class extends H9{hdCache2ServerUrl;hdCache2CacheVersion;getSolverName(){return\"AutoroutingPipelineSolver9_Networked\"}constructor(t,e={}){if(super(t,e),1!==this.effort)throw new Error(`AutoroutingPipelineSolver9_Networked is only available at effort=1, received ${this.effort}`);this.hdCache2ServerUrl=e.hdCache2ServerUrl??n8,this.hdCache2CacheVersion=e.hdCache2CacheVersion,this.replaceHighDensityPipelineStep()}replaceHighDensityPipelineStep(){const t=this.pipelineDef.findIndex(t=\u003e\"highDensityRouteSolver\"===t.solverName),e=this.pipelineDef[t];if(!e)throw new Error(\"Pipeline9 highDensityRouteSolver step is missing\");const n=e.getConstructorParams;this.pipelineDef[t]={...e,solverClass:f8,getConstructorParams:t=\u003e{const[e]=n(t);return[{...e,autorouterVersion:G9,hdCache2ServerUrl:t.hdCache2ServerUrl,hdCache2CacheVersion:t.hdCache2CacheVersion}]}}}async stepAsync(){if(this.solved||this.failed)return;this.step();const t=vX(this);0!==t.length\u0026\u0026(await Promise.race(t.map(t=\u003et.promise.then(()=\u003et.name,()=\u003et.name))),this.solved||this.failed||this.step())}async solveAsync(){const t=Date.now();for(;!this.solved\u0026\u0026!this.failed;)await this.stepAsync();this.timeToSolve=Date.now()-t}async solveUntilPhaseAsync(t){for(;this.getCurrentPhase()!==t\u0026\u0026!this.solved\u0026\u0026!this.failed;)await this.stepAsync()}solve(){throw new Error(\"AutoroutingPipelineSolver9_Networked requires async execution. Use solveAsync() or stepAsync().\")}solveUntilPhase(t){throw new Error(\"AutoroutingPipelineSolver9_Networked requires solveUntilPhaseAsync().\")}};function _8(t){if(t.solvePolicy!==g8)throw new Error(`Unsupported Pipeline9 networked solve policy ${String(t.solvePolicy)}`);if(1!==t.effort)throw new Error(`Pipeline9 networked high-density solving requires effort=1, received ${t.effort}`);const e=new ti(t.connectivityNetMap),n=(({input:t,connMap:e})=\u003e{const n=XQ({nodeWithPortPoints:t.nodeWithPortPoints,colorMap:t.colorMap,connMap:e,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:{[t.nodeWithPortPoints.capacityMeshNodeId]:t.nodePf},obstacles:t.obstacles,layerCount:t.layerCount});return n.solve(),n.solved?{status:\"solved\",routes:n.routes}:{status:\"failed\",error:n.error||\"Pipeline9 ordinary high-density solver failed\"}})({input:t,connMap:e});if(\"solved\"===n.status)return{status:\"solved\",solutionStage:\"ordinary\",routes:n.routes};const o=n.error;if(!t.enableRegionalFallback)return{status:\"failed\",solutionStage:\"ordinary\",error:`Pipeline9 regular high-density routing failed: ${o}`};const i=YQ(t.nodeWithPortPoints,e),r=$K({...i,availableZ:Array.from({length:t.layerCount},(t,e)=\u003ee)},[]),s=new FQ({nodeWithPortPoints:r.nodeWithPortPoints,colorMap:t.colorMap,connMap:e,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:{[t.nodeWithPortPoints.capacityMeshNodeId]:t.nodePf},obstacles:t.regionalObstacles,layerCount:t.layerCount});if(s.solve(),s.solved)return{status:\"solved\",solutionStage:\"regional-fallback\",ordinaryFailure:o,routes:s.getOutput()};return{status:\"failed\",solutionStage:\"regional-fallback\",ordinaryFailure:o,error:[`Pipeline9 primary high-density routing failed: regular high-density routing failed: ${o}`,`regional fallback failed: ${s.error||\"Pipeline9 regional fallback solver failed\"}`].join(\"; \")}}var b8=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\u0026\u0026!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026this.tryFinalAcceptance(),!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),\"computeProgress\"in this\u0026\u0026(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error(\"getConstructorParams not implemented\")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved\u0026\u0026!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 x8(t){const e=`${t.connectionName}:source-${t.sourcePointIndex}`;return{boundaryExitPointId:`fanout-exit:${e}`,planeExitPointId:`fanout-plane:${e}`,traceId:`fanout:${e}`,viaObstacleId:`fanout-via:${e}`,planeEndpointPointId:`fanout-plane-endpoint-point:${e}`,planeEndpointTraceId:`fanout-plane-endpoint:${e}`,planeEndpointViaObstacleId:`fanout-plane-endpoint-via:${e}`}}function v8(t,e,n=!1){const o=n?t.planeEndpointVia:t.via;if(!o)return null;const i=o.spanLayers.map(n=\u003e{const o=e.indexOf(n);if(o\u003c0)throw new Error(`FanoutSolver: via for \"${t.connectionName}\" uses unknown layer \"${n}\"`);return o}),r=x8(t);return{obstacleId:n?r.planeEndpointViaObstacleId:r.viaObstacleId,type:\"rect\",center:o.center,width:o.diameter,height:o.diameter,layers:o.spanLayers,zLayers:i,__zLayers:i,connectedTo:[t.connectionName,t.trace.pcb_trace_id]}}function S8(t){const{inputSrj:e,plans:n,layerNames:o}=t,i=e.connections.map(t=\u003e({...t,pointsToConnect:t.pointsToConnect.map(t=\u003e({...t}))})),r=[],s=new Set;for(const t of n){const e=i[t.connectionIndex];if(!e)throw new Error(`FanoutSolver: output connection index ${t.connectionIndex} is missing`);const n=x8(t);e.pointsToConnect[t.sourcePointIndex]={x:t.exitPoint.x,y:t.exitPoint.y,layer:t.targetLayer,pointId:\"plane\"===t.termination.type?n.planeExitPointId:n.boundaryExitPointId},\"plane\"===t.termination.type\u0026\u0026s.add(t.connectionName);const a=v8(t,o);a\u0026\u0026r.push(a);const c=v8(t,o,!0);c\u0026\u0026r.push(c)}const a=n.flatMap(t=\u003e[t.trace,...t.planeEndpointTrace?[t.planeEndpointTrace]:[]]),c=a.flatMap(t=\u003et.route.filter(t=\u003e\"x\"in t\u0026\u0026\"y\"in t)),l=Math.max(e.defaultObstacleMargin??0,e.minTraceWidth),d=0===c.length?{...e.bounds}:{minX:Math.min(e.bounds.minX,...c.map(t=\u003et.x-l)),maxX:Math.max(e.bounds.maxX,...c.map(t=\u003et.x+l)),minY:Math.min(e.bounds.minY,...c.map(t=\u003et.y-l)),maxY:Math.max(e.bounds.maxY,...c.map(t=\u003et.y+l))};return{...e,fanoutPlaneConnectivity:n.flatMap(t=\u003e\"plane\"===t.termination.type?[{connectionName:t.connectionName,layer:t.termination.layer}]:[]),bounds:d,connections:i.filter(t=\u003e!s.has(t.name)),buses:e.buses?.map(t=\u003e({...t,connectionNames:t.connectionNames.filter(t=\u003e!s.has(t))})).filter(t=\u003et.connectionNames.length\u003e0),obstacles:[...e.obstacles.map(t=\u003e({...t,center:{...t.center},layers:[...t.layers],connectedTo:[...t.connectedTo]})),...r],traces:[...(e.traces??[]).map(t=\u003e({...t,route:t.route.map(t=\u003e({...t}))})),...a]}}var I8=1e-9;function C8(t){return\"circle\"===t.shape}function P8(t,e){const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}}function M8(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function N8(t,e,n){const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r\u003cI8?0:((t.x-e.x)*o+(t.y-e.y)*i)/r,a=Math.max(0,Math.min(1,s));return Math.hypot(t.x-(e.x+a*o),t.y-(e.y+a*i))}function w8(t,e,n){return(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x)}function T8(t,e,n,o){return function(t,e,n,o){const i=w8(n,o,t),r=w8(n,o,e),s=w8(t,e,n),a=w8(t,e,o);return(i\u003e0\u0026\u0026r\u003c0||i\u003c0\u0026\u0026r\u003e0)\u0026\u0026(s\u003e0\u0026\u0026a\u003c0||s\u003c0\u0026\u0026a\u003e0)}(t,e,n,o)?0:Math.min(N8(t,n,o),N8(e,n,o),N8(n,t,e),N8(o,t,e))}function R8(t,e,n=1e-9){if(C8(e))return M8(t,e.center)\u003c=e.width/2+n;const o=P8(t,e);return Math.abs(o.x)\u003c=e.width/2+n\u0026\u0026Math.abs(o.y)\u003c=e.height/2+n}function E8(t,e){if(C8(e))return Math.max(0,M8(t,e.center)-e.width/2);const n=P8(t,e),o=Math.max(Math.abs(n.x)-e.width/2,0),i=Math.max(Math.abs(n.y)-e.height/2,0);return Math.hypot(o,i)}function A8(t,e){if(C8(e))return Math.max(0,N8(e.center,t.start,t.end)-e.width/2);const n=P8(t.start,e),o=P8(t.end,e);if(Math.abs(n.x)\u003c=e.width/2+I8\u0026\u0026Math.abs(n.y)\u003c=e.height/2+I8)return 0;if(Math.abs(o.x)\u003c=e.width/2+I8\u0026\u0026Math.abs(o.y)\u003c=e.height/2+I8)return 0;const i=-e.width/2,r=e.width/2,s=-e.height/2,a=e.height/2,c=[{x:i,y:s},{x:r,y:s},{x:r,y:a},{x:i,y:a}];let l=Number.POSITIVE_INFINITY;for(let t=0;t\u003cc.length;t++)l=Math.min(l,T8(n,o,c[t],c[(t+1)%c.length]));return l}function O8(t,e,n){if(t.layer!==e.layer)return!0;const o=(t.width+e.width)/2+n;return T8(t.start,t.end,e.start,e.end)\u003e=o-I8}function k8(t){if(!Number.isInteger(t)||t\u003c1)throw new Error(`FanoutSolver: layerCount must be a positive integer, received ${t}`);return 1===t?[\"top\"]:2===t?[\"top\",\"bottom\"]:[\"top\",...Array.from({length:t-2},(t,e)=\u003e`inner${e+1}`),\"bottom\"]}function L8(t,e,n){const o=n.indexOf(t),i=n.indexOf(e);if(o\u003c0||i\u003c0)throw new Error(`FanoutSolver: cannot build via span from \"${t}\" to \"${e}\"`);const r=Math.min(o,i),s=Math.max(o,i);return n.slice(r,s+1)}var D8=new WeakMap;function z8(t){return t.netConnectionName??t.rootConnectionName??t.name}function F8(t,e,n){if(!e)return!1;const o=t.get(e)??new Set,i=o.size;return o.add(n),t.set(e,o),o.size!==i}function B8(t,e){const n=new Set;for(const o of e)for(const e of t.get(o)??[])n.add(e);return n}function j8(t){const e=D8.get(t);if(e)return e;const n=function(t){const e=new Map,n=new Map;for(const o of t.connections){const t=z8(o);e.set(o.name,t),F8(n,o.name,t),F8(n,o.rootConnectionName,t),F8(n,o.netConnectionName,t);for(const e of o.pointsToConnect)F8(n,e.pointId,t),F8(n,e.pcb_port_id,t)}for(const o of t.traces??[]){const t=o.connection_name?e.get(o.connection_name):void 0;if(t){F8(n,o.pcb_trace_id,t);for(const e of o.connectsTo??[])F8(n,e,t)}}for(let e=0;e\u003c2;e++){let e=!1;for(const o of t.obstacles){const t=B8(n,o.connectedTo);if(1!==t.size)continue;const i=[...t][0];for(const t of o.connectedTo)e=F8(n,t,i)||e}if(!e)break}const o=new Map,i=t=\u003e{const e=o.get(t)??t;if(o.set(t,e),e===t)return t;const n=i(e);return o.set(t,n),n},r=(t,e)=\u003e{const n=i(t),r=i(e);n!==r\u0026\u0026o.set(r,n)};for(const t of n.values()){const[e,...n]=[...t];if(e)for(const t of n)r(e,t)}for(const e of[...t.obstacles.map(t=\u003et.connectedTo),...(t.traces??[]).map(t=\u003et.connectsTo??[])]){const[t,...o]=[...B8(n,e)];if(t)for(const e of o)r(t,e)}for(const[t,n]of e)e.set(t,i(n));for(const[t,e]of n)n.set(t,new Set([...e].map(t=\u003ei(t))));return{connectionNetKeys:e,tokenNetKeys:n}}(t);return D8.set(t,n),n}function $8(t,e,n){const o=j8(t),i=o.connectionNetKeys.get(e),r=o.connectionNetKeys.get(n);return void 0!==i\u0026\u0026i===r}function Y8(t,e,n){const o=j8(t),i=o.connectionNetKeys.get(n);return!!i\u0026\u0026e.connectedTo.some(t=\u003eo.tokenNetKeys.get(t)?.has(i))}var X8=1e-6;function V8(t){return\"layer\"in t?[t.layer]:t.layers}function W8(t,e){return t.some(t=\u003ee.includes(t))}function H8(t,e){const n=[];let o;for(const i of t.route)\"via\"!==i.route_type?\"wire\"===i.route_type\u0026\u0026(o\u0026\u0026o.layer===i.layer\u0026\u0026M8(o,i)\u003eX8\u0026\u0026n.push({type:\"segment\",segment:{start:{x:o.x,y:o.y},end:{x:i.x,y:i.y},width:i.width,layer:i.layer}}),o=i):(n.push({type:\"via\",center:{x:i.x,y:i.y},diameter:i.via_diameter??0,layers:L8(i.from_layer,i.to_layer,e)}),o=void 0);return n}function G8(t,e){return\"plane\"===t.type\u0026\u0026\"plane\"===e.type?t.layer===e.layer:\"plane\"===t.type\u0026\u0026\"via\"===e.type?e.layers.includes(t.layer):\"via\"===t.type\u0026\u0026\"plane\"===e.type?G8(e,t):\"plane\"===t.type\u0026\u0026\"segment\"===e.type?t.layer===e.segment.layer:\"segment\"===t.type\u0026\u0026\"plane\"===e.type?G8(e,t):\"endpoint\"===t.type\u0026\u0026\"endpoint\"===e.type?W8(t.layers,e.layers)\u0026\u0026M8(t.point,e.point)\u003c=X8:\"endpoint\"===t.type\u0026\u0026\"obstacle\"===e.type?W8(t.layers,e.obstacle.layers)\u0026\u0026R8(t.point,e.obstacle,X8):\"obstacle\"===t.type\u0026\u0026\"endpoint\"===e.type?G8(e,t):\"endpoint\"===t.type\u0026\u0026\"segment\"===e.type?t.layers.includes(e.segment.layer)\u0026\u0026N8(t.point,e.segment.start,e.segment.end)\u003c=e.segment.width/2+X8:\"segment\"===t.type\u0026\u0026\"endpoint\"===e.type?G8(e,t):\"endpoint\"===t.type\u0026\u0026\"via\"===e.type?W8(t.layers,e.layers)\u0026\u0026M8(t.point,e.center)\u003c=e.diameter/2+X8:\"via\"===t.type\u0026\u0026\"endpoint\"===e.type?G8(e,t):\"obstacle\"===t.type\u0026\u0026\"segment\"===e.type?t.obstacle.layers.includes(e.segment.layer)\u0026\u0026A8(e.segment,t.obstacle)\u003c=e.segment.width/2+X8:\"segment\"===t.type\u0026\u0026\"obstacle\"===e.type?G8(e,t):\"obstacle\"===t.type\u0026\u0026\"via\"===e.type?W8(t.obstacle.layers,e.layers)\u0026\u0026E8(e.center,t.obstacle)\u003c=e.diameter/2+X8:\"via\"===t.type\u0026\u0026\"obstacle\"===e.type?G8(e,t):\"segment\"===t.type\u0026\u0026\"segment\"===e.type?t.segment.layer===e.segment.layer\u0026\u0026T8(t.segment.start,t.segment.end,e.segment.start,e.segment.end)\u003c=(t.segment.width+e.segment.width)/2+X8:\"segment\"===t.type\u0026\u0026\"via\"===e.type?e.layers.includes(t.segment.layer)\u0026\u0026N8(e.center,t.segment.start,t.segment.end)\u003c=e.diameter/2+t.segment.width/2+X8:\"via\"===t.type\u0026\u0026\"segment\"===e.type?G8(e,t):\"via\"===t.type\u0026\u0026\"via\"===e.type\u0026\u0026(W8(t.layers,e.layers)\u0026\u0026M8(t.center,e.center)\u003c=(t.diameter+e.diameter)/2+X8)}var U8=class{parent;constructor(t){this.parent=Array.from({length:t},(t,e)=\u003ee)}find(t){const e=this.parent[t];if(e===t)return t;const n=this.find(e);return this.parent[t]=n,n}union(t,e){const n=this.find(t),o=this.find(e);n!==o\u0026\u0026(this.parent[o]=n)}};function Z8(t,e,n){return Boolean(e.connection_name\u0026\u0026$8(t,e.connection_name,n.name))}function q8(t){const{inputSrj:e,routedSrj:n}=t,o=n.fanoutPlaneConnectivity,i=k8(n.layerCount),r=new Map;for(const t of e.connections){const e=z8(t),n=r.get(e)??[];n.push(t),r.set(e,n)}const s=[];let a=0,c=0;for(const t of r.values()){const r=t[0],l=t.flatMap(t=\u003et.pointsToConnect.map((e,n)=\u003e({type:\"endpoint\",connectionName:t.name,endpointIndex:n,point:e,layers:V8(e)}))),d=e.obstacles.filter(t=\u003eY8(e,t,r.name)).map(t=\u003e({type:\"obstacle\",obstacle:t})),h=(n.traces??[]).filter(t=\u003eZ8(e,t,r)).flatMap(t=\u003eH8(t,i)),u=[...new Set((o??[]).flatMap(t=\u003e$8(e,t.connectionName,r.name)?[t.layer]:[]))].map(t=\u003e({type:\"plane\",layer:t})),p=[...l,...d,...h,...u],m=new U8(p.length);for(let t=0;t\u003cp.length;t++)for(let e=t+1;e\u003cp.length;e++)G8(p[t],p[e])\u0026\u0026m.union(t,e);const g=new Map;for(let t=0;t\u003cl.length;t++){const e=l[t],n=g.get(e.connectionName)??[];n[e.endpointIndex]=t,g.set(e.connectionName,n)}for(const e of t){const t=g.get(e.name)??[],n=t[0],o=void 0===n?void 0:m.find(n),i=t.flatMap((t,e)=\u003evoid 0===o||m.find(t)!==o?[e]:[]);c+=t.length-i.length,0===i.length?a++:s.push({code:\"original-endpoints-disconnected\",connectionName:e.name,disconnectedEndpointIndices:i,message:`Connection ${e.name} has no physical copper path from endpoint 0 to original endpoint${1===i.length?\"\":\"s\"} ${i.join(\", \")}`})}}const l=e.connections.reduce((t,e)=\u003et+e.pointsToConnect.length,0);return{valid:0===s.length,checkedConnectionCount:e.connections.length,connectedConnectionCount:a,checkedEndpointCount:l,connectedEndpointCount:c,issues:s}}var J8=1e-6;function K8(t){const{inputSrj:e,segment:n,bodyObstacle:o,connectionName:i}=t;if(o.connectedTo.length\u003e0||!o.componentId)return!1;const r=e.obstacles.filter(t=\u003et.componentId===o.componentId\u0026\u0026t.layers.includes(n.layer)\u0026\u0026Y8(e,t,i));for(const t of r)for(const[e,i]of[[n.start,n.end],[n.end,n.start]]){if(!R8(e,t,J8))continue;const n={x:e.x-o.center.x,y:e.y-o.center.y},r={x:i.x-e.x,y:i.y-e.y};if(n.x*r.x+n.y*r.y\u003eJ8)return!0}return!1}function Q8(t,e){return M8(t,e)\u003c=J8}function t7(t,e){t.push(e)}function e7(t){const{srj:e,trace:n,connectionName:o,layerNames:i,issues:r}=t,s=[],a=[];let c,l;for(const t of n.route){if(\"via\"===t.route_type){const s=L8(t.from_layer,t.to_layer,i);a.push({center:{x:t.x,y:t.y},diameter:t.via_diameter??e.minViaPadDiameter??e.minTraceWidth,spanLayers:s}),c\u0026\u0026Q8(c,t)\u0026\u0026c.layer===t.from_layer||t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} reaches a via without a matching ${t.from_layer} wire endpoint`}),l=t;continue}\"wire\"===t.route_type?l?(Q8(t,l)\u0026\u0026t.layer===l.to_layer||t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} does not continue from its via on ${l.to_layer}`}),c=t,l=void 0):(c\u0026\u0026(c.layer!==t.layer?t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} changes from ${c.layer} to ${t.layer} without a via`}):Q8(c,t)||s.push({start:{x:c.x,y:c.y},end:{x:t.x,y:t.y},width:t.width,layer:t.layer})),c=t):(t7(r,{code:\"unsupported-route-point\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} contains unsupported ${t.route_type} geometry`}),c=void 0,l=void 0)}return l\u0026\u0026t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} ends at a via without a wire on ${l.to_layer}`}),{trace:n,connectionName:o,segments:s,vias:a}}function n7(t){const{inputSrj:e,routedSrj:n,clearance:o}=t,i=[],r=k8(n.layerCount),s=[],a=[e,n].flatMap(t=\u003et.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({connectionName:t.name,point:e}))));for(const t of n.traces??[]){const o=t.connection_name;o\u0026\u0026e.connections.some(t=\u003et.name===o)?s.push(e7({srj:n,trace:t,connectionName:o,layerNames:r,issues:i})):t7(i,{code:\"unknown-trace-connection\",traceId:t.pcb_trace_id,...o?{connectionName:o}:{},message:`Trace ${t.pcb_trace_id} does not identify an input connection`})}for(const t of s){for(const n of t.segments)for(const r of e.obstacles){if(!r.layers.includes(n.layer)||Y8(e,r,t.connectionName))continue;if(K8({inputSrj:e,segment:n,bodyObstacle:r,connectionName:t.connectionName}))continue;const s=A8(n,r),a=n.width/2+o;s\u003ca-J8\u0026\u0026t7(i,{code:\"trace-obstacle-clearance\",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,layer:n.layer,obstacleId:r.obstacleId,message:`Trace ${t.trace.pcb_trace_id} on ${n.layer} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId}; ${a.toFixed(4)}mm is required`})}for(const n of t.vias){const r=a.find(({point:t})=\u003eM8(n.center,t)\u003c=J8);r\u0026\u0026t7(i,{code:\"via-at-endpoint\",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,otherConnectionName:r.connectionName,message:`Via in ${t.trace.pcb_trace_id} is placed directly at an original or routed connection endpoint`});for(const r of e.obstacles){if(!r.layers.some(t=\u003en.spanLayers.includes(t))||Y8(e,r,t.connectionName))continue;const s=E8(n.center,r),a=n.diameter/2+o;s\u003ca-J8\u0026\u0026t7(i,{code:\"via-obstacle-clearance\",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,obstacleId:r.obstacleId,message:`Via in ${t.trace.pcb_trace_id} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId} on its layer span; ${a.toFixed(4)}mm is required`})}}}for(let t=0;t\u003cs.length;t++){const n=s[t];for(let r=t+1;r\u003cs.length;r++){const t=s[r];if(!$8(e,n.connectionName,t.connectionName)){for(const e of n.segments){for(const r of t.segments)O8(e,r,o)||t7(i,{code:\"different-net-trace-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:e.layer,message:`Different-net traces ${n.trace.pcb_trace_id} and ${t.trace.pcb_trace_id} intersect or violate clearance on ${e.layer}`});for(const r of t.vias)!r.spanLayers.includes(e.layer)||N8(r.center,e.start,e.end)\u003e=r.diameter/2+e.width/2+o-J8||t7(i,{code:\"different-net-trace-via-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:e.layer,message:`Trace ${n.trace.pcb_trace_id} violates via clearance to ${t.trace.pcb_trace_id} on ${e.layer}`})}for(const e of n.vias){for(const r of t.segments)!e.spanLayers.includes(r.layer)||N8(e.center,r.start,r.end)\u003e=e.diameter/2+r.width/2+o-J8||t7(i,{code:\"different-net-trace-via-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:r.layer,message:`Via in ${n.trace.pcb_trace_id} violates trace clearance to ${t.trace.pcb_trace_id} on ${r.layer}`});for(const r of t.vias)!e.spanLayers.some(t=\u003er.spanLayers.includes(t))||M8(e.center,r.center)\u003e=(e.diameter+r.diameter)/2+o-J8||t7(i,{code:\"different-net-via-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,message:`Different-net vias in ${n.trace.pcb_trace_id} and ${t.trace.pcb_trace_id} violate clearance on an overlapping layer span`})}}}}return{valid:0===i.length,checkedTraceCount:n.traces?.length??0,checkedSegmentCount:s.reduce((t,e)=\u003et+e.segments.length,0),checkedViaCount:s.reduce((t,e)=\u003et+e.vias.length,0),issues:i}}var o7=1e-9;function i7(t,e){if(\"layer\"in t)return t.layer;if(e\u0026\u0026t.layers.includes(e))return e;const n=t.layers[0];if(!n)throw new Error(\"Endpoint completion received a layerless point\");return n}function r7(t){const e=[];for(const n of t)e.at(-1)\u0026\u0026M8(e.at(-1),n)\u003co7||e.push(n);return e}function s7(t,e){const n=r7(t);if(n.length\u003c3)return n;const o=[n[0]];for(let t=1;t\u003cn.length-1;t++){const i=n[t-1],r=n[t],s=n[t+1],a=M8(i,r),c=M8(r,s),l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c};if(Math.abs(l.x*d.x+l.y*d.y)\u003e1e-6){o.push(r);continue}const h=Math.min(e,a/2,c/2);o.push({x:r.x-l.x*h,y:r.y-l.y*h}),o.push({x:r.x+d.x*h,y:r.y+d.y*h})}return o.push(n.at(-1)),r7(o)}function a7(t){const{inputSrj:e,plan:n}=t,o=i7(n.targetPoint),i=function(t){const{inputSrj:e,connectionName:n,target:o,targetLayer:i}=t;return e.obstacles.find(t=\u003et.layers.includes(i)\u0026\u0026Y8(e,t,n)\u0026\u0026R8(o,t,1e-6))}({inputSrj:e,connectionName:n.connectionName,target:n.targetPoint,targetLayer:o}),r=e.obstacles.find(t=\u003et.componentId===i?.componentId\u0026\u00260===t.connectedTo.length),s=r?{x:n.targetPoint.x-r.center.x,y:n.targetPoint.y-r.center.y}:{x:n.targetPoint.x-n.sourcePoint.x,y:n.targetPoint.y-n.sourcePoint.y},a=Math.hypot(s.x,s.y),c=a\u003eo7?{x:s.x/a,y:s.y/a}:{x:1,y:0};return{outward:c,perpendicular:{x:-c.y,y:c.x}}}function c7(t){const{plan:e,branchStart:n,viaPoint:o,assignedLayerPath:i,terminalApproach:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,candidateIndex:l,chamfer:d}=t,h=i7(e.targetPoint),u=s7(i,d),p=s7([o,...r?[r]:[],e.targetPoint],d),m=u.map(t=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:s,layer:n.layer}));n.layer!==h\u0026\u0026(m.push({route_type:\"via\",x:o.x,y:o.y,from_layer:n.layer,to_layer:h,via_diameter:a,via_hole_diameter:c}),m.push({route_type:\"wire\",x:o.x,y:o.y,width:s,layer:h}));for(const t of p.slice(1))m.push({route_type:\"wire\",x:t.x,y:t.y,width:s,layer:h});return{type:\"pcb_trace\",pcb_trace_id:(g={connectionName:e.connectionName,sourcePointIndex:e.sourcePointIndex,candidateIndex:l},`fanout-completion:${g.connectionName}:source-${g.sourcePointIndex}:${g.candidateIndex}`),connection_name:e.connectionName,route:m};var g}function l7(t,e){return!t.issues.some(t=\u003et.connectionName===e)}function d7(t){const{trace:e,endpointSrjs:n}=t,o=n.flatMap(t=\u003et.connections.flatMap(t=\u003et.pointsToConnect));return e.route.some(t=\u003e\"via\"===t.route_type\u0026\u0026o.some(e=\u003eM8(t,e)\u003c=1e-6))}function h7(t){const{inputSrj:e,fanoutSrj:n,plan:o,acceptedTraces:i,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,clearance:c}=t,{outward:l,perpendicular:d}=a7({inputSrj:e,plan:o}),h=[...o.via?[{x:o.via.center.x,y:o.via.center.y,layer:o.targetLayer}]:[],{x:o.sourcePoint.x,y:o.sourcePoint.y,layer:o.sourceLayer}];let u=[],p=Number.POSITIVE_INFINITY,m=0;const g=e.connections.length\u003e32?600:Number.POSITIVE_INFINITY,f=\"plane\"===o.termination.type?g7({trace:o.trace,endpoint:o.exitPoint,layer:o.sourceLayer,distances:[.2,.3,.4]}):[],y=[...\"plane\"===o.termination.type\u0026\u0026o.via?[{...o.via.center}]:[],...f,...[.4,.8,1.2,1.6].flatMap(t=\u003e[0,.4,-.4,.8,-.8,1.2,-1.2,1.6,-1.6].map(e=\u003e({x:o.sourcePoint.x+l.x*t+d.x*e,y:o.sourcePoint.y+l.y*t+d.y*e})))];for(const t of y){const y=[...\"plane\"===o.termination.type?[{...t,layer:o.targetLayer}]:[],...h,...f.flatMap(e=\u003eM8(e,t)\u003c=1e-6?[{...e,layer:o.sourceLayer}]:[])];for(const h of y){const f=M8(h,t)\u003c=1e-6?[[h]]:[[h,t],[h,{x:t.x,y:h.y},t],[h,{x:h.x,y:t.y},t],...[.4,-.4].map(e=\u003e[h,{x:h.x+e,y:h.y},{x:h.x+e,y:t.y},t])];for(const y of f){const f=[void 0,...[.4,.8].map(t=\u003e({x:o.targetPoint.x+l.x*t,y:o.targetPoint.y+l.y*t})),...[.4,-.4].map(t=\u003e({x:o.targetPoint.x+.4*l.x+d.x*t,y:o.targetPoint.y+.4*l.y+d.y*t}))];for(const l of f){if(m\u003e=g)return{blockingConnectionNames:u};const d=c7({plan:o,branchStart:h,viaPoint:t,assignedLayerPath:y,terminalApproach:l,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,candidateIndex:m++,chamfer:0});if(d7({trace:d,endpointSrjs:[e,n]}))continue;const f={...n,traces:[...n.traces??[],...i,d]},_=n7({inputSrj:e,routedSrj:f,clearance:c});if(!_.valid){_.issues.length\u003cp\u0026\u0026(p=_.issues.length,u=[...new Set(_.issues.flatMap(t=\u003e[t.connectionName,t.otherConnectionName].flatMap(t=\u003et\u0026\u0026t!==o.connectionName?[t]:[])))]);continue}if(l7(q8({inputSrj:e,routedSrj:f}),o.connectionName))return{trace:d,blockingConnectionNames:[]}}}}}return{blockingConnectionNames:u}}function u7(t){const{inputSrj:e,fanoutSrj:n,plans:o,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a}=t,c=[],l=[],d=new Set;for(const t of o){const o=h7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:c,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});if(o.trace)c.push(o.trace);else{l.push(t.connectionName);for(const t of o.blockingConnectionNames)d.add(t)}}const h={...n,traces:[...n.traces??[],...c]};return{traces:c,failedConnectionNames:l,blockingConnectionNames:[...d],connectivity:q8({inputSrj:e,routedSrj:h}),drc:n7({inputSrj:e,routedSrj:h,clearance:a})}}function p7(t){let e,n=0;for(const o of t.route)\"wire\"===o.route_type?(e?.layer===o.layer\u0026\u0026(n+=M8(e,o)),e=o):e=void 0;return n}function m7(t){const e=k8(t.layerCount),n=[];for(const o of t.traces??[]){let i;for(const r of o.route)if(\"via\"!==r.route_type)if(\"wire\"===r.route_type){if(i?.layer===r.layer){const t=M8(i,r);t\u003eo7\u0026\u0026n.push({obstacleId:`endpoint-completion-keepout:${o.pcb_trace_id}:segment:${n.length}`,type:\"rect\",center:{x:(i.x+r.x)/2,y:(i.y+r.y)/2},width:t,height:Math.max(i.width,r.width),ccwRotationDegrees:180*Math.atan2(r.y-i.y,r.x-i.x)/Math.PI,layers:[r.layer],connectedTo:[o.connection_name]})}i=r}else i=void 0;else n.push({obstacleId:`endpoint-completion-keepout:${o.pcb_trace_id}:via:${n.length}`,type:\"rect\",center:{x:r.x,y:r.y},width:r.via_diameter??t.minViaPadDiameter??.3,height:r.via_diameter??t.minViaPadDiameter??.3,layers:L8(r.from_layer,r.to_layer,e),connectedTo:[o.connection_name]}),i=void 0}return n}function g7(t){const{trace:e,endpoint:n,layer:o,distances:i}=t,r=e.route.findLastIndex(t=\u003e\"wire\"===t.route_type\u0026\u0026t.layer===o\u0026\u0026M8(t,n)\u003c=1e-6);return r\u003c0?[]:i.flatMap(t=\u003e{let i=t,s=n;for(let t=r-1;t\u003e=0;t--){const n=e.route[t];if(\"wire\"!==n?.route_type||n.layer!==o)break;const r=M8(s,n);if(!(r\u003c=o7)){if(i\u003cr-1e-6)return[{x:s.x+(n.x-s.x)*i/r,y:s.y+(n.y-s.y)*i/r}];i-=r,s=n}}return[]})}function f7(t){const{inputSrj:e,fanoutSrj:n,plan:o,acceptedTraces:i,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,clearance:c}=t,l={x:o.exitPoint.x,y:o.exitPoint.y,layer:o.targetLayer},d=o.targetPoint,h=i7(d);let u=0;const p=t=\u003e{const l=c7({plan:o,branchStart:t.start,viaPoint:t.viaPoint,assignedLayerPath:[t.start,t.viaPoint],terminalApproach:t.terminalApproach,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,candidateIndex:1e4+u++,chamfer:Math.max(r,.1)});if(d7({trace:l,endpointSrjs:[e,n]}))return;const d={...n,traces:[...n.traces??[],...i,l]};return n7({inputSrj:e,routedSrj:d,clearance:c}).valid\u0026\u0026l7(q8({inputSrj:e,routedSrj:d}),o.connectionName)?l:void 0};if(l.layer!==h){const t=g7({trace:o.trace,endpoint:o.exitPoint,layer:o.targetLayer,distances:[.4,.8,1.2,1.6]});for(const e of t){const t={...e,layer:o.targetLayer};for(const n of[void 0,{x:d.x,y:e.y},{x:e.x,y:d.y}]){const o=p({start:t,viaPoint:e,terminalApproach:n});if(o)return o}}}const m=[[d],[{x:d.x,y:l.y},d],[{x:l.x,y:d.y},d]];for(const t of m){const e=t[0],n=M8(l,e),o=l.layer===h?[0]:[.4,.8,1.2,1.6];for(const i of o){if(l.layer!==h\u0026\u0026(n\u003c=i+.2||i\u003c=1e-6))continue;const o=p({start:l,viaPoint:l.layer===h?{x:l.x,y:l.y}:{x:l.x+(e.x-l.x)*i/n,y:l.y+(e.y-l.y)*i/n},terminalApproach:t.length\u003e1?e:void 0});if(o)return o}}}function y7(t){const{inputSrj:e,fanoutSrj:n,plans:o,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a,effort:c=1,routeDownstreamConnections:l}=t,d=[],h=n7({inputSrj:e,routedSrj:n,clearance:a}),u=q8({inputSrj:e,routedSrj:n}),p=o.filter(t=\u003ei7(t.sourcePoint)!==i7(t.targetPoint)\u0026\u0026M8(t.sourcePoint,t.targetPoint)\u003c=.25\u0026\u0026!l7(u,t.connectionName));let m={traces:[],failedConnectionNames:p.map(t=\u003et.connectionName),blockingConnectionNames:[],connectivity:u,drc:h},g=0;if(h.valid){let t=[];const o=new Map(p.map((t,e)=\u003e[t.connectionName,e])),c=e.connections.length\u003e32?1:3;for(let l=0;l\u003cc;l++){const c=new Map(t.map((t,e)=\u003e[t,e])),l=u7({inputSrj:e,fanoutSrj:n,plans:p.toSorted((t,e)=\u003e(c.get(t.connectionName)??Number.MAX_SAFE_INTEGER)-(c.get(e.connectionName)??Number.MAX_SAFE_INTEGER)||(o.get(t.connectionName)??0)-(o.get(e.connectionName)??0)),traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});if(g++,l.drc.valid\u0026\u0026(l.connectivity.connectedConnectionCount\u003em.connectivity.connectedConnectionCount||l.connectivity.connectedConnectionCount===m.connectivity.connectedConnectionCount\u0026\u0026l.traces.length\u003cm.traces.length)\u0026\u0026(m=l),t=[...new Set([...l.failedConnectionNames,...l.blockingConnectionNames,...t])],0===l.failedConnectionNames.length)break}}else d.push(\"Fanout prefix failed emitted-copper DRC; skipped completion\");const f=new Set(p.map(t=\u003et.connectionName)),y=o.filter(t=\u003e!f.has(t.connectionName)\u0026\u0026!l7(u,t.connectionName)),_=[];if(h.valid)for(const t of y){const o=f7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:[...m.traces,..._],traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});o\u0026\u0026_.push(o)}const b={...n,traces:[...n.traces??[],...m.traces,..._]},x=new Set(q8({inputSrj:e,routedSrj:b}).issues.map(t=\u003et.connectionName)),v=n.connections.filter(t=\u003e!f.has(t.name)\u0026\u0026x.has(t.name));let S=[];if(h.valid\u0026\u0026v.length\u003e0\u0026\u0026v.length\u003c=12\u0026\u0026l){const t=new Set(v.map(t=\u003et.name)),o={...n,connections:v,buses:n.buses?.map(e=\u003e({...e,connectionNames:e.connectionNames.filter(e=\u003et.has(e))})).filter(t=\u003et.connectionNames.length\u003e0),obstacles:[...n.obstacles,...m7(n)],traces:[]};try{const i=l(o,{effort:c});S=function(t){const{inputSrj:e,fanoutSrj:n,localTraces:o,candidates:i,clearance:r}=t,s=[...n.traces??[],...o],a={...n,traces:s},c=q8({inputSrj:e,routedSrj:a}),l=i.filter(t=\u003et.route.length\u003e1\u0026\u0026t.route.every(t=\u003e\"wire\"===t.route_type||\"via\"===t.route_type)\u0026\u0026!d7({trace:t,endpointSrjs:[e,n]})).filter(t=\u003e{const o=q8({inputSrj:e,routedSrj:{...n,traces:[...s,t]}});return o.connectedConnectionCount\u003ec.connectedConnectionCount\u0026\u0026l7(o,t.connection_name)}),d={...n,traces:[...s,...l]};if(n7({inputSrj:e,routedSrj:d,clearance:r}).valid)return l;const h=[];for(const t of l.toSorted((t,e)=\u003ep7(t)-p7(e))){const o={...n,traces:[...s,...h,t]};if(!n7({inputSrj:e,routedSrj:o,clearance:r}).valid)continue;const i=q8({inputSrj:e,routedSrj:{...n,traces:[...s,...h]}}),a=q8({inputSrj:e,routedSrj:o});a.connectedConnectionCount\u003ei.connectedConnectionCount\u0026\u0026l7(a,t.connection_name)\u0026\u0026h.push(t)}return h}({inputSrj:e,fanoutSrj:n,localTraces:[...m.traces,..._],candidates:i.filter(e=\u003et.has(e.connection_name)),clearance:a})}catch(t){d.push(`Downstream router failed: ${t instanceof Error?t.message:String(t)}`)}}else!h.valid\u0026\u0026v.length\u003e0?d.push(\"Skipped downstream router because the endpoint-completion baseline failed emitted-copper DRC\"):v.length\u003e12?d.push(`Skipped downstream router for ${v.length} unresolved connections (bounded at 12)`):v.length\u003e0\u0026\u0026!l\u0026\u0026d.push(`Skipped downstream router for ${v.length} unresolved connections because no routeDownstreamConnections callback was provided`);const I=[...m.traces,..._,...S];for(const t of y){if(l7(q8({inputSrj:e,routedSrj:{...n,traces:[...n.traces??[],...I]}}),t.connectionName))continue;const o=f7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:I,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});o\u0026\u0026I.push(o)}const C=function(t){const{fanoutSrj:e,completionTraces:n}=t,o=new Map(n.flatMap(t=\u003e{const e=t.route.find(t=\u003e\"wire\"===t.route_type);return e?[[t.connection_name,{x:e.x,y:e.y,layer:e.layer}]]:[]})),i=(e.traces??[]).map(t=\u003e{if(!t.pcb_trace_id.startsWith(\"fanout:\"))return t;const e=o.get(t.connection_name);if(!e)return t;let n;for(let o=0;o\u003ct.route.length;o++){const i=t.route[o];if(\"wire\"===i?.route_type){if(void 0!==n){const o=t.route[n];if(\"wire\"===o?.route_type\u0026\u0026o.layer===e.layer\u0026\u0026i.layer===e.layer\u0026\u0026N8(e,o,i)\u003c=1e-6){const r=t.route.slice(0,n+1);return M8(o,e)\u003e1e-6\u0026\u0026r.push({route_type:\"wire\",x:e.x,y:e.y,width:i.width,layer:e.layer}),{...t,route:r}}}n=o}else n=void 0}return t});return{...e,traces:i}}({fanoutSrj:{...n,traces:[...n.traces??[],...I]},completionTraces:I}),P=q8({inputSrj:e,routedSrj:C}),M=n7({inputSrj:e,routedSrj:C,clearance:a});return M.valid?{simpleRouteJson:C,traces:I,report:{attemptedLocalConnectionCount:p.length,attemptedDownstreamConnectionCount:y.length,completionTraceCount:I.length,searchPassCount:g,errors:d,connectivity:P,drc:M}}:(d.push(\"Final endpoint-completion output failed emitted-copper DRC\"),{simpleRouteJson:n,traces:[],report:{attemptedLocalConnectionCount:p.length,attemptedDownstreamConnectionCount:y.length,completionTraceCount:0,searchPassCount:g,errors:d,connectivity:q8({inputSrj:e,routedSrj:n}),drc:h}})}var _7=new Set([\"left\",\"right\",\"top\",\"bottom\",\"top-left\",\"top-right\",\"bottom-left\",\"bottom-right\"]),b7={top_left:{direction:\"up\",preferredExit:\"top-left\"},top_middle:{direction:\"up\",preferredExit:\"top\"},top_right:{direction:\"up\",preferredExit:\"top-right\"},right_top:{direction:\"right\",preferredExit:\"top-right\"},right_middle:{direction:\"right\",preferredExit:\"right\"},right_bottom:{direction:\"right\",preferredExit:\"bottom-right\"},bottom_right:{direction:\"down\",preferredExit:\"bottom-right\"},bottom_middle:{direction:\"down\",preferredExit:\"bottom\"},bottom_left:{direction:\"down\",preferredExit:\"bottom-left\"},left_bottom:{direction:\"left\",preferredExit:\"bottom-left\"},left_middle:{direction:\"left\",preferredExit:\"left\"},left_top:{direction:\"left\",preferredExit:\"top-left\"},top:{direction:\"up\",preferredExit:\"top\"},right:{direction:\"right\",preferredExit:\"right\"},bottom:{direction:\"down\",preferredExit:\"bottom\"},left:{direction:\"left\",preferredExit:\"left\"}};function x7(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(const t of e)(0===n.length||Math.abs(n[n.length-1]-t)\u003e1e-6)\u0026\u0026n.push(t);return n}function v7(t){let e=Number.POSITIVE_INFINITY;for(let n=1;n\u003ct.length;n++){const o=t[n]-t[n-1];o\u003e1e-6\u0026\u0026(e=Math.min(e,o))}return e}function S7(t,e){const n=\"x\"===e?\"y\":\"x\";let o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ct.length;i++){const r=t[i];for(let s=i+1;s\u003ct.length;s++){const i=t[s];if(Math.abs(r.center[n]-i.center[n])\u003e1e-6)continue;const a=Math.abs(r.center[e]-i.center[e]);a\u003e1e-6\u0026\u0026(o=Math.min(o,a))}}return o}function I7(t){return{minX:Math.min(...t.map(t=\u003et.center.x-t.width/2)),maxX:Math.max(...t.map(t=\u003et.center.x+t.width/2)),minY:Math.min(...t.map(t=\u003et.center.y-t.height/2)),maxY:Math.max(...t.map(t=\u003et.center.y+t.height/2))}}function C7(t,e){const n=e.componentBounds?.[t.componentId];if(!n){const e=2.25*t.pitchX,n=2.25*t.pitchY;return{minX:t.bounds.minX-e,maxX:t.bounds.maxX+e,minY:t.bounds.minY-n,maxY:t.bounds.maxY+n}}if([n.minX,n.maxX,n.minY,n.maxY].some(t=\u003e!Number.isFinite(t))||n.minX\u003e=n.maxX||n.minY\u003e=n.maxY)throw new Error(`FanoutSolver: componentBounds for \"${t.componentId}\" must contain finite, increasing bounds`);if(n.minX\u003et.bounds.minX+1e-6||n.maxX\u003ct.bounds.maxX-1e-6||n.minY\u003et.bounds.minY+1e-6||n.maxY\u003ct.bounds.maxY-1e-6)throw new Error(`FanoutSolver: componentBounds for \"${t.componentId}\" must contain every component pad`);return{...n}}function P7(t,e){if([t.minX,t.maxX,t.minY,t.maxY].some(t=\u003e!Number.isFinite(t))||t.minX\u003e=t.maxX||t.minY\u003e=t.maxY)throw new Error(\"FanoutSolver: sharedBoundary must contain finite, increasing bounds\");for(const n of e)if(t.minX\u003en.bounds.minX+1e-6||t.maxX\u003cn.bounds.maxX-1e-6||t.minY\u003en.bounds.minY+1e-6||t.maxY\u003cn.bounds.maxY-1e-6)throw new Error(`FanoutSolver: sharedBoundary must contain every pad of component \"${n.componentId}\"`);return{...t}}function M7(t){return\"layer\"in t?[t.layer]:t.layers}function N7(t){const{point:e,connection:n,componentGrids:o}=t,i=M7(e),r=[];for(const t of o){const o=t.obstacles.filter(t=\u003et.layers.some(t=\u003ei.includes(t))).filter(t=\u003eR8(e,t,1e-5)).sort((t,o)=\u003e{const i=t.connectedTo.includes(n.name)||t.connectedTo.includes(e.pointId??\"\")||t.connectedTo.includes(e.pcb_port_id??\"\");return i!==(o.connectedTo.includes(n.name)||o.connectedTo.includes(e.pointId??\"\")||o.connectedTo.includes(e.pcb_port_id??\"\"))?i?-1:1:t.width*t.height-o.width*o.height});o[0]\u0026\u0026r.push({grid:t,obstacle:o[0]})}return r}function w7(t){for(const e of t.pointsToConnect)if(\"layers\"in e\u0026\u0026e.busId)return e.busId;const e=/^BUS[_:-]([^_:-]+)(?:[_:-]\\d+)?$/i.exec(t.name);return e?.[1]??null}function T7(t,e){if(void 0!==e){if(!_7.has(e))throw new Error(`FanoutSolver: bus \"${t}\" has invalid preferredExit \"${e}\"`);return e}}function R7(t){if(void 0===t)return;if(0===t.length)throw new Error(\"FanoutSolver: availableCornersAndSides must contain at least one boundary region\");const e=[],n=new Set;for(const o of t){const t=b7[o];if(!t)throw new Error(`FanoutSolver: invalid availableCornersAndSides value \"${o}\"`);const i=`${t.direction}:${t.preferredExit}`;n.has(i)||(n.add(i),e.push(t))}return e}function E7(t,e){if(void 0===e||\"boundary\"===e.type)return{type:\"boundary\"};if(\"plane\"!==e.type||\"string\"!=typeof e.layer||0===e.layer.length)throw new Error(`FanoutSolver: bus \"${t}\" has an invalid termination target`);return{type:\"plane\",layer:e.layer}}function A7(t,e,n,o){const i=e.pointsToConnect.filter((t,e)=\u003ee!==n).sort((e,n)=\u003eM8(t,n)-M8(t,e))[0];if(!i\u0026\u0026\"plane\"===o.type)return t;if(!i)throw new Error(`FanoutSolver: connection \"${e.name}\" has no target beyond its BGA pad`);return i}function O7(t,e){let n=0,o=0;for(const t of e){const e=t.exitTargetPoint??t.targetPoint;n+=e.x-t.sourcePoint.x,o+=e.y-t.sourcePoint.y}if(Math.abs(n)\u003c1e-9\u0026\u0026Math.abs(o)\u003c1e-9)throw new Error(`FanoutSolver: cannot infer an escape direction for bus \"${t}\"`);return Math.abs(n)\u003e=Math.abs(o)?n\u003e=0?\"right\":\"left\":o\u003e=0?\"up\":\"down\"}function k7(t){return{x:t.reduce((t,e)=\u003et+e.sourcePoint.x,0)/t.length,y:t.reduce((t,e)=\u003et+e.sourcePoint.y,0)/t.length}}function L7(t,e,n){switch(e){case\"left\":return t.x-n.minX;case\"right\":return n.maxX-t.x;case\"up\":return n.maxY-t.y;case\"down\":return t.y-n.minY}}function D7(t,e){return\"up\"===t.direction||\"down\"===t.direction?t.preferredExit.endsWith(\"left\")?e.minX:t.preferredExit.endsWith(\"right\")?e.maxX:(e.minX+e.maxX)/2:t.preferredExit.startsWith(\"top\")?e.maxY:t.preferredExit.startsWith(\"bottom\")?e.minY:(e.minY+e.maxY)/2}function z7(t,e){return\"up\"===e||\"down\"===e?t.x:t.y}function F7(t){const{busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s}=t,a=s.filter(t=\u003e!(void 0!==n\u0026\u0026t.direction!==n||void 0!==o\u0026\u0026t.preferredExit!==o));if(0===a.length)throw new Error(`FanoutSolver: bus \"${e}\" cannot use its requested exit with availableCornersAndSides`);const c=n?void 0:function(t,e){try{return O7(t,e)}catch{return}}(e,i),l=c?a.filter(t=\u003et.direction===c):[],d=l.length\u003e0?l:a,h=k7(i);return[...d].toSorted((t,e)=\u003eL7(h,t.direction,r)-L7(h,e.direction,r)||Math.abs(z7(h,t.direction)-D7(t,r))-Math.abs(z7(h,e.direction)-D7(e,r))||t.preferredExit.localeCompare(e.preferredExit))[0]}function B7(t){const{busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s}=t;if(s)return F7({busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s});if(!o)return{direction:n??O7(e,i)};const a=function(t){switch(t){case\"left\":return[\"left\"];case\"right\":return[\"right\"];case\"top\":return[\"up\"];case\"bottom\":return[\"down\"];case\"top-left\":return[\"up\",\"left\"];case\"top-right\":return[\"up\",\"right\"];case\"bottom-left\":return[\"down\",\"left\"];case\"bottom-right\":return[\"down\",\"right\"]}}(o);if(n){if(!a.includes(n))throw new Error(`FanoutSolver: bus \"${e}\" direction \"${n}\" is incompatible with preferredExit \"${o}\"`);return{direction:n,preferredExit:o}}if(1===a.length)return{direction:a[0],preferredExit:o};let c;try{c=O7(e,i)}catch{c=void 0}if(c\u0026\u0026a.includes(c))return{direction:c,preferredExit:o};const l=k7(i);return{direction:a.toSorted((t,e)=\u003eL7(l,t,r)-L7(l,e,r)||t.localeCompare(e))[0],preferredExit:o}}function j7(t,e){const n=function(t){const e=new Map;for(const n of t){if(!n.componentId||n.isCopperPour)continue;const t=e.get(n.componentId)??[];t.push(n),e.set(n.componentId,t)}const n=[];for(const[t,o]of e){const e=x7(o.map(t=\u003et.center.x)),i=x7(o.map(t=\u003et.center.y)),r=S7(o,\"x\"),s=S7(o,\"y\"),a=v7(e),c=v7(i),l=Math.min(...[r,s,a,c].filter(Number.isFinite)),d=Math.max(...o.flatMap(t=\u003e[t.width,t.height])),h=Number.isFinite(l)?l:d,u=Number.isFinite(r)?r:Number.isFinite(a)?a:h,p=Number.isFinite(s)?s:Number.isFinite(c)?c:h;n.push({componentId:t,obstacles:o,xCoordinates:e,yCoordinates:i,pitchX:u,pitchY:p,bounds:I7(o)})}return n}(t.obstacles);if(0===n.length\u0026\u0026t.connections.length\u003e0)throw new Error(\"FanoutSolver: no componentId-tagged pad footprint was found\");const o=new Map(t.connections.map((t,e)=\u003e[t.name,e])),i=function(t,e){const n=e.buses??t.buses,o=new Map,i=new Set,r=new Set(t.connections.map(t=\u003et.name));for(const t of n??[]){if(o.has(t.busId))throw new Error(`FanoutSolver: duplicate bus id \"${t.busId}\"`);for(const e of t.connectionNames){if(!r.has(e))throw new Error(`FanoutSolver: bus \"${t.busId}\" references unknown connection \"${e}\"`);if(i.has(e))throw new Error(`FanoutSolver: connection \"${e}\" belongs to more than one bus`);i.add(e)}const n=E7(t.busId,t.termination),s=T7(t.busId,e.busExitPreferences?.[t.busId]??t.preferredExit??e.defaultPreferredExit);if(\"plane\"===n.type\u0026\u0026void 0!==s)throw new Error(`FanoutSolver: plane-terminated bus \"${t.busId}\" cannot also specify preferredExit`);o.set(t.busId,{...t,sourceComponentId:t.sourceComponentId??e.sourceComponentId,direction:e.busDirections?.[t.busId]??t.direction??e.defaultDirection,preferredExit:s,termination:n})}for(const n of t.connections){if(i.has(n.name))continue;const t=w7(n);if(t){const i=o.get(t);o.set(t,{busId:t,connectionNames:[...i?.connectionNames??[],n.name],direction:e.busDirections?.[t]??i?.direction??e.defaultDirection,sourceComponentId:i?.sourceComponentId??e.sourceComponentId,preferredExit:T7(t,e.busExitPreferences?.[t]??i?.preferredExit??e.defaultPreferredExit),termination:i?.termination??{type:\"boundary\"}})}else{const t=`connection:${n.name}`;o.set(t,{busId:t,connectionNames:[n.name],sourceComponentId:e.sourceComponentId,direction:e.busDirections?.[t]??e.defaultDirection,preferredExit:T7(t,e.busExitPreferences?.[t]??e.defaultPreferredExit),termination:{type:\"boundary\"}})}}return[...o.values()]}(t,e).map(e=\u003e{for(const[t,n]of Object.entries(e.connectionExitTargets??{})){if(!e.connectionNames.includes(t))throw new Error(`FanoutSolver: connectionExitTargets contains connection \"${t}\" outside bus \"${e.busId}\"`);if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error(`FanoutSolver: connectionExitTargets for connection \"${t}\" must contain finite x and y coordinates`)}const i=e.connectionNames.map(e=\u003e{const n=o.get(e);if(void 0===n)throw new Error(`FanoutSolver: connection \"${e}\" is missing from the input`);return t.connections[n]}),r=function(t){const{busSpec:e,connections:n,componentGrids:o}=t,i=new Map;for(const t of n){const e=new Set;for(const n of t.pointsToConnect)for(const i of N7({point:n,connection:t,componentGrids:o}))e.add(i.grid.componentId);for(const t of e)i.set(t,(i.get(t)??0)+1)}const r=[...o].sort((t,e)=\u003e{const n=(i.get(e.componentId)??0)-(i.get(t.componentId)??0);return 0!==n?n:e.obstacles.length-t.obstacles.length})[0],s=e.sourceComponentId?o.find(t=\u003et.componentId===e.sourceComponentId):void 0;if(e.sourceComponentId\u0026\u0026!s)throw new Error(`FanoutSolver: source component \"${e.sourceComponentId}\" for bus \"${e.busId}\" was not found`);const a=s??r,c=a?i.get(a.componentId)??0:0;if(!a||c!==n.length)throw new Error(e.sourceComponentId?`FanoutSolver: source component \"${e.sourceComponentId}\" is not an endpoint on every connection in bus \"${e.busId}\"`:`FanoutSolver: bus \"${e.busId}\" does not have one component endpoint on every connection`);return a}({busSpec:e,connections:i,componentGrids:n}),s=i.map(t=\u003efunction(t){const{connection:e,connectionIndex:n,sourceGrid:o,componentGrids:i,termination:r,exitTargetPoint:s}=t;for(let t=0;t\u003ce.pointsToConnect.length;t++){const a=e.pointsToConnect[t],c=N7({point:a,connection:e,componentGrids:i}).find(t=\u003et.grid.componentId===o.componentId);if(!c)continue;const l=M7(a).find(t=\u003ec.obstacle.layers.includes(t));if(!l)throw new Error(`FanoutSolver: connection \"${e.name}\" has no source layer shared with its BGA pad`);const d=A7(a,e,t,r);return{connection:e,connectionIndex:n,sourcePoint:a,sourcePointIndex:t,sourceLayer:l,sourceObstacle:c.obstacle,targetPoint:d,exitTargetPoint:s??d}}throw new Error(`FanoutSolver: connection \"${e.name}\" does not touch component \"${o.componentId}\"`)}({connection:t,connectionIndex:o.get(t.name),sourceGrid:r,componentGrids:n,termination:e.termination??{type:\"boundary\"},exitTargetPoint:e.connectionExitTargets?.[t.name]}));return{busSpec:e,sourceGrid:r,preparedConnections:s}}),r=function(t,e){if(e.sharedBoundary)return P7(e.sharedBoundary,t);const n=t.map(t=\u003eC7(t,e)),o=2.25*Math.max(...t.flatMap(t=\u003e[t.pitchX,t.pitchY]));return P7({minX:Math.min(...n.map(t=\u003et.minX))-o,maxX:Math.max(...n.map(t=\u003et.maxX))+o,minY:Math.min(...n.map(t=\u003et.minY))-o,maxY:Math.max(...n.map(t=\u003et.maxY))+o},t)}([...new Map(i.map(({sourceGrid:t})=\u003e[t.componentId,t])).values()],e),s=R7(e.availableCornersAndSides),a=[];for(const{busSpec:t,sourceGrid:n,preparedConnections:o}of i){const i=B7({busId:t.busId,explicitDirection:t.direction??e.busDirections?.[t.busId],preferredExit:t.preferredExit,connections:o,sharedBoundary:r,availableRegions:\"plane\"===t.termination?.type?void 0:s});a.push({busId:t.busId,direction:i.direction,preferredExit:i.preferredExit,termination:t.termination??{type:\"boundary\"},connections:o,componentId:n.componentId,componentObstacles:n.obstacles,componentBounds:C7(n,e),sharedBoundary:r,xCoordinates:[...n.xCoordinates],yCoordinates:[...n.yCoordinates],pitchX:n.pitchX,pitchY:n.pitchY})}return a}function $7(t){return\"left\"===t||\"right\"===t}function Y7(t){return\"right\"===t||\"up\"===t?1:-1}function X7(t,e){return $7(e)?t.x:t.y}function V7(t,e){return $7(e)?t.y:t.x}function W7(t,e,n){return $7(n)?{x:t,y:e}:{x:e,y:t}}function H7(t){switch(t.direction){case\"right\":return t.sharedBoundary.maxX;case\"left\":return t.sharedBoundary.minX;case\"up\":return t.sharedBoundary.maxY;case\"down\":return t.sharedBoundary.minY}}function G7(t){return $7(t.direction)?t.pitchX:t.pitchY}function U7(t){const e=$7(t.direction)?t.xCoordinates:t.yCoordinates,n=t.connections.reduce((e,n)=\u003ee+X7(n.sourcePoint,t.direction),0)/t.connections.length,o=Y7(t.direction)\u003e0?Math.max(...e):Math.min(...e);return Math.abs(n-o)\u003c1e-6}function Z7(t,e){const n=[...t.connections].sort((e,n)=\u003eV7(e.sourcePoint,t.direction)-V7(n.sourcePoint,t.direction)).findIndex(t=\u003et.connectionIndex===e.connectionIndex);if(n\u003c0)throw new Error(`FanoutSolver: connection \"${e.connection.name}\" is missing from bus \"${t.busId}\"`);return n}function q7(t,e){return t.x\u003e=e.minX-1e-6\u0026\u0026t.x\u003c=e.maxX+1e-6\u0026\u0026t.y\u003e=e.minY-1e-6\u0026\u0026t.y\u003c=e.maxY+1e-6}function J7(t,e,n,o,i){const r=e-t,s=Math.floor((r-o)/(n+o)+1e-9);if(s\u003c1)return[];const a=t+(r-(s*n+(s-1)*o))/2+n/2;return Array.from({length:s},(t,e)=\u003e({value:a+e*(n+o),kind:i}))}function K7(t){const e=V7(t.connection.exitTargetPoint??t.connection.targetPoint,t.bus.direction),n=$7(t.bus.direction)?t.bus.sharedBoundary.minY:t.bus.sharedBoundary.minX,o=$7(t.bus.direction)?t.bus.sharedBoundary.maxY:t.bus.sharedBoundary.maxX;return Math.max(n+t.traceWidth/2,Math.min(o-t.traceWidth/2,e))}function Q7(t){const{bus:e,connection:n,targetUsesVia:o,interstitialEscape:i,compactBusTracks:r,traceWidth:s,viaDiameter:a,clearance:c}=t,l=($7(e.direction)?e.yCoordinates:e.xCoordinates).toSorted((t,e)=\u003et-e),d=V7(n.sourcePoint,e.direction);if(r){const t=Z7(e,n);return(l[0]+l.at(-1))/2+(t-(e.connections.length-1)/2)*(s+c)}if(!o||!i)return d;const h=function(t){const e=($7(t.direction)?t.xCoordinates:t.yCoordinates).toSorted((t,e)=\u003et-e),n=t.connections.reduce((e,n)=\u003ee+X7(n.sourcePoint,t.direction),0)/t.connections.length,o=Y7(t.direction)\u003e0?e.at(-1):e[0];return Math.abs(o-n)/G7(t)}(e),u=s+c,p=Math.ceil(e.connections.length/2),m=(p-1)*u,g=a/2+s/2+c+.001,f=Math.round(h)+1,y=f*g+(f-1)*m,_=Z7(e,n),b=l[0],x=l.at(-1),v=_\u003cp?b-y-(p-_-1)*u:x+y+(_-p)*u,S=$7(e.direction)?e.sharedBoundary.minY:e.sharedBoundary.minX,I=$7(e.direction)?e.sharedBoundary.maxY:e.sharedBoundary.maxX;return Math.max(S+s/2,Math.min(I-s/2,v))}function ttt(t){const e=Y7(t.direction),n=[...t.connections].sort((n,o)=\u003e{const i=e*(X7(o.sourcePoint,t.direction)-X7(n.sourcePoint,t.direction));return Math.abs(i)\u003e1e-6?i:V7(n.sourcePoint,t.direction)-V7(o.sourcePoint,t.direction)}),o=[...t.connections].sort((n,o)=\u003eV7(n.sourcePoint,t.direction)-V7(o.sourcePoint,t.direction)||e*(X7(o.sourcePoint,t.direction)-X7(n.sourcePoint,t.direction))),i=[n,[...n].reverse(),o,[...o].reverse()];for(let t=1;t\u003cMath.min(n.length,8);t++)i.push([...n.slice(t),...n.slice(0,t)]);return i}function ett(t,e,n,o,i){M8(e,n)\u003c1e-9||t.push({start:e,end:n,width:o,layer:i})}function ntt(t){const{preparedConnection:e,bus:n,targetLayer:o,track:i,exitAxis:r,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,viaHandedness:d,interstitialEscape:h,spreadLaneIndex:u,clearance:p,terminateAtVia:m}=t,g={x:e.sourcePoint.x,y:e.sourcePoint.y},f=Y7(n.direction),y=G7(n),_=function(t){return $7(t.direction)?t.pitchY:t.pitchX}(n),b=o!==e.sourceLayer,x=$7(n.direction)?e.sourceObstacle.width:e.sourceObstacle.height,v=b\u0026\u0026!U7(n)?x\u003e=y?x/2+c/2+p+.001:.5*y:b?Math.max(.5*y,x/2+(b?c:a)/2+p+.001):x/2+a/2+p+.001,S=X7(g,n.direction)+f*v,I=V7(g,n.direction)+d*_*.5,C=W7(S,I,n.direction),P=c/2+a/2+p+.001+u*(a+p),M=h\u0026\u0026y\u003e=P+c/2+p,N=M?W7(S+f*P,I,n.direction):C,w=W7(M?X7(N,n.direction):S+f*Math.abs(i-I),i,n.direction),T=m?C:W7(r,i,n.direction),R=[],E=[];let A;if(E.push({route_type:\"wire\",x:g.x,y:g.y,width:a,layer:e.sourceLayer,start_pcb_port_id:e.sourcePoint.pcb_port_id}),ett(R,g,C,a,e.sourceLayer),E.push({route_type:\"wire\",x:C.x,y:C.y,width:a,layer:e.sourceLayer}),o!==e.sourceLayer){const t=L8(e.sourceLayer,o,s);A={center:C,diameter:c,holeDiameter:l,fromLayer:e.sourceLayer,toLayer:o,spanLayers:t},E.push({route_type:\"via\",x:C.x,y:C.y,from_layer:e.sourceLayer,to_layer:o,via_diameter:c,via_hole_diameter:l}),E.push({route_type:\"wire\",x:C.x,y:C.y,width:a,layer:o})}const O=m?[C]:M?function(t,e){if(t.length\u003c3)return t;const n=[t[0]];for(let o=1;o\u003ct.length-1;o++){const i=t[o-1],r=t[o],s=t[o+1],a=M8(i,r),c=M8(r,s);if(a\u003c1e-9||c\u003c1e-9)continue;const l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c},h=l.x*d.x+l.y*d.y;if(Math.abs(h)\u003e1e-6){n.push(r);continue}const u=Math.min(e,a/2,c/2);n.push({x:r.x-l.x*u,y:r.y-l.y*u}),n.push({x:r.x+d.x*u,y:r.y+d.y*u})}return n.push(t.at(-1)),n}([C,N,w,T],Math.max(a+p,2*a)):[C,w,T];for(let t=1;t\u003cO.length;t++){const e=O[t-1],n=O[t];ett(R,e,n,a,o),E.push({route_type:\"wire\",x:n.x,y:n.y,width:a,layer:o})}const k=x8({connectionName:e.connection.name,sourcePointIndex:e.sourcePointIndex});return{busId:n.busId,connectionName:e.connection.name,connectionIndex:e.connectionIndex,sourcePointIndex:e.sourcePointIndex,sourcePoint:e.sourcePoint,sourceObstacle:e.sourceObstacle,sourceLayer:e.sourceLayer,targetPoint:e.targetPoint,targetLayer:o,termination:n.termination,direction:n.direction,exitPoint:T,trace:{type:\"pcb_trace\",pcb_trace_id:k.traceId,connection_name:e.connection.name,connectsTo:[...e.sourcePoint.pointId?[e.sourcePoint.pointId]:[],...e.sourcePoint.pcb_port_id?[e.sourcePoint.pcb_port_id]:[],k.boundaryExitPointId],route:E},segments:R,via:A,length:R.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}function ott(t){const{preparedConnection:e,bus:n,viaDiameter:o,clearance:i}=t,{sourcePoint:r,targetPoint:s}=e,a=.5*Math.max(n.pitchX,n.pitchY);if(M8(r,s)\u003c=1e-6||M8(r,s)\u003ea)return[];const c=(()=\u003e{switch(n.direction){case\"left\":return{x:-1,y:0};case\"right\":return{x:1,y:0};case\"up\":return{x:0,y:1};case\"down\":return{x:0,y:-1}}})(),l=Math.SQRT1_2,d=[c,...[{x:l,y:l},{x:l,y:-l},{x:-l,y:l},{x:-l,y:-l},{x:1,y:0},{x:-1,y:0},{x:0,y:1},{x:0,y:-1}].toSorted((t,e)=\u003ee.x*c.x+e.y*c.y-(t.x*c.x+t.y*c.y))],h=Math.max(o,o/2+i),u=[h,Math.max(h,.5*Math.min(n.pitchX,n.pitchY)),Math.max(h,.625*Math.min(n.pitchX,n.pitchY)),Math.max(h,.75*Math.min(n.pitchX,n.pitchY))],p=[];for(const t of[r,s])for(const e of u)for(const n of d){const o={x:t.x+n.x*e,y:t.y+n.y*e};M8(o,r)\u003c=1e-6||M8(o,s)\u003c=1e-6||p.some(t=\u003eM8(t,o)\u003c=1e-6)||p.push(o)}return p}function itt(t){const{plan:e,preparedConnection:n,planeLayer:o,viaPoint:i,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c}=t,l={x:n.targetPoint.x,y:n.targetPoint.y},d=function(t){const e=\"layer\"in t?t.layer:t.layers[0];if(!e)throw new Error(\"FanoutSolver: plane endpoint has no copper layer\");return e}(n.targetPoint),h=L8(o,d,r);if(!h.includes(o))throw new Error(`FanoutSolver: via for \"${n.connection.name}\" does not cross plane ${o}`);const u=[{start:i,end:l,width:s,layer:d}],p={center:i,diameter:a,holeDiameter:c,fromLayer:o,toLayer:d,spanLayers:h},m=x8({connectionName:n.connection.name,sourcePointIndex:n.sourcePointIndex}),g={type:\"pcb_trace\",pcb_trace_id:m.planeEndpointTraceId,connection_name:n.connection.name,connectsTo:[...n.targetPoint.pointId?[n.targetPoint.pointId]:[],...n.targetPoint.pcb_port_id?[n.targetPoint.pcb_port_id]:[],m.planeEndpointPointId],route:[{route_type:\"wire\",...i,width:s,layer:o},{route_type:\"via\",...i,from_layer:o,to_layer:d,via_diameter:a,via_hole_diameter:c},{route_type:\"wire\",...i,width:s,layer:d},{route_type:\"wire\",...l,width:s,layer:d}]};return{...e,planeEndpointTrace:g,planeEndpointSegments:u,planeEndpointVia:p,length:e.length+u.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}function rtt(t){const{segment:e,plan:n,segmentIndex:o,srj:i,allowSameNetMerges:r,obstacles:s,clearance:a}=t;for(const t of s)if(t.layers.includes(e.layer)\u0026\u0026!t.connectedTo.includes(n.connectionName)\u0026\u0026!(r\u0026\u0026Y8(i,t,n.connectionName)||K8({inputSrj:i,segment:e,bodyObstacle:t,connectionName:n.connectionName})||0===o\u0026\u0026t===n.sourceObstacle\u0026\u0026e.layer===n.sourceLayer||!(A8(e,t)\u003ce.width/2+a-1e-9)))return!1;return!0}function stt(t){return[...t.segments,...t.planeEndpointSegments??[]]}function att(t){return[t.via,t.planeEndpointVia].filter(t=\u003eBoolean(t))}function ctt(t){const{plan:e,srj:n,sharedBoundary:o,clearance:i,allowSameNetMerges:r}=t,s=function(t,e){return{minX:Math.min(t.minX,e.minX),maxX:Math.max(t.maxX,e.maxX),minY:Math.min(t.minY,e.minY),maxY:Math.max(t.maxY,e.maxY)}}(n.bounds,o);if(!q7(e.exitPoint,s)||stt(e).some(t=\u003e!q7(t.start,s)||!q7(t.end,s)))return!1;const a=stt(e);for(let t=0;t\u003ca.length;t++)if(!rtt({segment:a[t],plan:e,segmentIndex:t\u003ce.segments.length?t:-1,srj:n,allowSameNetMerges:r,obstacles:n.obstacles,clearance:i}))return!1;for(const t of att(e))for(const o of n.obstacles)if(o.layers.some(e=\u003et.spanLayers.includes(e))\u0026\u0026(!r||!Y8(n,o,e.connectionName))\u0026\u0026E8(t.center,o)\u003ct.diameter/2+i-1e-9)return!1;return!0}function ltt(t){const{plan:e,otherPlans:n,staticClearanceCache:o,blockingBusCounts:i,cacheKey:r,srj:s,sharedBoundary:a,clearance:c,allowSameNetMerges:l}=t;let d=o?.get(r);return void 0===d\u0026\u0026(d=ctt({plan:e,srj:s,sharedBoundary:a,clearance:c,allowSameNetMerges:l}),o?.set(r,d)),d\u0026\u0026function(t){const{plan:e,otherPlans:n,srj:o,allowSameNetMerges:i,clearance:r,blockingBusCounts:s}=t;for(const t of n){if(i\u0026\u0026$8(o,e.connectionName,t.connectionName))continue;if(e.sourcePoint.pcb_port_id\u0026\u0026e.sourcePoint.pcb_port_id===t.sourcePoint.pcb_port_id||e.sourcePoint.pointId\u0026\u0026e.sourcePoint.pointId===t.sourcePoint.pointId)continue;const n=()=\u003e{t.busId!==e.busId\u0026\u0026s?.set(t.busId,(s.get(t.busId)??0)+1)},a=stt(e),c=stt(t),l=att(e),d=att(t);for(const t of a){for(const e of c)if(!O8(t,e,r))return n(),!1;for(const e of d)if(e.spanLayers.includes(t.layer)\u0026\u0026N8(e.center,t.start,t.end)\u003ce.diameter/2+t.width/2+r-1e-9)return n(),!1}for(const t of l){for(const e of c)if(t.spanLayers.includes(e.layer)\u0026\u0026N8(t.center,e.start,e.end)\u003ct.diameter/2+e.width/2+r-1e-9)return n(),!1;for(const e of d)if(t.spanLayers.some(t=\u003ee.spanLayers.includes(t))\u0026\u0026M8(t.center,e.center)\u003c(t.diameter+e.diameter)/2+r-1e-9)return n(),!1}}return!0}({plan:e,otherPlans:n,srj:s,allowSameNetMerges:l,clearance:c,blockingBusCounts:i})}function dtt(t,e=1){const{srj:n,bus:o,targetLayer:i,acceptedPlans:r,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,clearance:d,compactBusTracks:h,staticClearanceCache:u,blockingBusCounts:p,allowSameNetMerges:m=!1}=t;if(!Number.isInteger(e)||e\u003c1)throw new Error(`FanoutSolver: maxAlternatives must be a positive integer, received ${e}`);if(\"plane\"===o.termination.type){const e=function(t){const{srj:e,bus:n,targetLayer:o,acceptedPlans:i,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,clearance:l,staticClearanceCache:d,blockingBusCounts:h,allowSameNetMerges:u=!1}=t,p=n.connections[0]?.sourceObstacle;if(!p||\"plane\"!==n.termination.type)return null;const m=n.connections[0].sourceLayer;if(o===m)return null;const g=[n.direction,...[\"left\",\"right\",\"up\",\"down\"].filter(t=\u003et!==n.direction)];for(const t of g){const m=t===n.direction?n:{...n,direction:t},g=$7(t)?p.width:p.height,f=G7(m)/2-g/2\u003e=a/2+l-1e-9,y=f?[0]:[1,-1];for(const p of y)for(const g of ttt(m)){const y=[];let _=!0;for(const b of g){const g=V7(b.sourcePoint,t),x=ntt({preparedConnection:b,bus:m,targetLayer:o,track:g,exitAxis:H7(m),layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,viaHandedness:p,interstitialEscape:!f,spreadLaneIndex:0,clearance:l,terminateAtVia:!0}),v=[...ott({preparedConnection:b,bus:m,viaDiameter:a,clearance:l}).map(t=\u003eitt({plan:x,preparedConnection:b,planeLayer:o,viaPoint:t,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c})),x].find((r,s)=\u003eltt({plan:r,otherPlans:[...i,...y],staticClearanceCache:d,blockingBusCounts:h,cacheKey:`plane:${n.busId}:${o}:${t}:${b.connectionIndex}:${p}:${s}`,srj:e,sharedBoundary:n.sharedBoundary,clearance:l,allowSameNetMerges:u}));if(!v){_=!1;break}y.push(v)}if(_)return y}}return null}(t);return e?[e]:[]}const g=H7(o),f=o.connections[0]?.sourceObstacle;if(!f)return[[]];const y=$7(o.direction)?f.width:f.height,_=o.connections[0].sourceLayer,b=i!==_,x=U7(o),v=G7(o)/2-y/2\u003e=c/2+d-1e-9,S=b\u0026\u0026!x\u0026\u0026!v,I=b?v||x?[0]:[1,-1]:[0],C=[],P=new Set,M=(t,f,y,_)=\u003e{if(C.length\u003e=e)return;if(y\u003e=t.length)return void(t=\u003e{const e=t.map(t=\u003e`${t.connectionIndex}:${t.targetLayer}:${t.exitPoint.x}:${t.exitPoint.y}:${t.segments.map(t=\u003e`${t.start.x},${t.start.y},${t.end.x},${t.end.y},${t.layer}`).join(\";\")}`).join(\"|\");P.has(e)||(P.add(e),C.push(t))})(_);const x=t[y],v=Z7(o,x),I=[K7({bus:o,connection:x,traceWidth:a}),Q7({bus:o,connection:x,targetUsesVia:b,interstitialEscape:S,compactBusTracks:h,traceWidth:a,viaDiameter:c,clearance:d})].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e-t)\u003c1e-9)===e).flatMap(t=\u003efunction(t){const{bus:e,connection:n,preferredTrack:o,traceWidth:i,clearance:r}=t,s=($7(e.direction)?e.yCoordinates:e.xCoordinates).toSorted((t,e)=\u003et-e),a=Math.max(...e.componentObstacles.map(t=\u003e$7(e.direction)?t.height/2:t.width/2)),c=$7(e.direction)?e.sharedBoundary.minY:e.sharedBoundary.minX,l=$7(e.direction)?e.sharedBoundary.maxY:e.sharedBoundary.maxX,d=l-c,h=l,u=[{value:o,kind:\"preferred\"},...J7(c,s[0]-a,i,r,\"margin\")];for(let t=0;t\u003cs.length;t++)u.push({value:s[t],kind:\"corridor\"}),t\u003cs.length-1\u0026\u0026u.push(...J7(s[t]+a,s[t+1]-a,i,r,\"gap\"));u.push(...J7(s.at(-1)+a,h,i,r,\"margin\"));const p=V7(n.sourcePoint,e.direction),m=(s[0]+s.at(-1))/2;return u.filter(t=\u003eMath.abs(t.value-p)\u003c=d+1e-9).filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e.value-t.value)\u003c1e-9)===e).sort((t,e)=\u003eMath.abs(t.value-o)-Math.abs(e.value-o)-.001*(Math.abs(t.value-m)-Math.abs(e.value-m)))}({bus:o,connection:x,preferredTrack:t,traceWidth:a,clearance:d})).filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e.value-t.value)\u003c1e-9)===e);for(let h=0;h\u003cI.length;h++){const b=I[h],P=ntt({preparedConnection:x,bus:o,targetLayer:i,track:b.value,exitAxis:g,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,viaHandedness:f,interstitialEscape:S,spreadLaneIndex:Math.min(v,o.connections.length-v-1),clearance:d,terminateAtVia:!1});if(ltt({plan:P,otherPlans:[...r,..._],staticClearanceCache:u,blockingBusCounts:p,cacheKey:`boundary:${o.busId}:${i}:${x.connectionIndex}:${f}:${h}`,srj:n,sharedBoundary:o.sharedBoundary,clearance:d,allowSameNetMerges:m})){if(M(t,f,y+1,[..._,P]),C.length\u003e=e)return;if(1===e)return}}};for(const t of I)for(const n of ttt(o))if(M(n,t,0,[]),C.length\u003e=e)return C;return C}function htt(t){return dtt(t,1)[0]??null}var utt=1e-9,ptt=\"1\"===globalThis.process?.env?.FANOUT_FLOW_DEBUG;function mtt(t){const e=t.connection;return t.sourceObstacle.connectedTo.find(t=\u003et.startsWith(\"connectivity_net\"))??e.netConnectionName??t.connection.name.replace(/::fanout:\\d+$/,\"\")}function gtt(t,e){return t===e.connection.sourceObstacle||t.connectedTo.includes(e.connection.connection.name)||t.connectedTo.includes(e.netKey)}function ftt(t,e){const n=e.x-t.x,o=e.y-t.y,i=Math.abs(n),r=Math.abs(o);return i\u003cutt||r\u003cutt||Math.abs(i-r)\u003cutt?[t,e]:i\u003er?[t,{x:t.x+Math.sign(n)*r,y:e.y},e]:[t,{x:e.x,y:t.y+Math.sign(o)*i},e]}function ytt(t){if(t.length\u003c2)return t;const e=[t[0]];for(const n of t.slice(1)){const t=e.at(-1),o=Math.abs(n.x-t.x),i=Math.abs(n.y-t.y);o\u003cutt||i\u003cutt||Math.abs(o-i)\u003cutt?e.push(n):e.push(...ftt(n,t).reverse().slice(1))}return _tt(e)}function _tt(t){if(t.length\u003c3)return t;const e=[t[0]];for(let n=1;n\u003ct.length-1;n++){const o=e.at(-1),i=t[n],r=t[n+1];Math.sign(i.x-o.x)===Math.sign(r.x-i.x)\u0026\u0026Math.sign(i.y-o.y)===Math.sign(r.y-i.y)||e.push(i)}return e.push(t.at(-1)),e}function btt(t,e){if(t.length\u003c3)return t;const n=[t[0]];for(let o=1;o\u003ct.length-1;o++){const i=t[o-1],r=t[o],s=t[o+1],a=M8(i,r),c=M8(r,s);if(a\u003cutt||c\u003cutt)continue;const l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c};if(Math.abs(l.x*d.x+l.y*d.y)\u003e1e-6){n.push(r);continue}const h=Math.min(e,a/2,c/2);n.push({x:r.x-l.x*h,y:r.y-l.y*h}),n.push({x:r.x+d.x*h,y:r.y+d.y*h})}return n.push(t.at(-1)),_tt(n)}function xtt(t,e){const n=[];for(let o=1;o\u003ct.length;o++)M8(t[o-1],t[o])\u003cutt||n.push({start:t[o-1],end:t[o],width:e,layer:\"top\"});return n}var vtt=class{edges;levels;nextEdges;constructor(t){this.edges=Array.from({length:t},()=\u003e[]),this.levels=new Int32Array(t),this.nextEdges=new Int32Array(t)}addEdge(t,e,n,o={}){const i={to:e,reverseIndex:this.edges[e].length,capacity:n,initialCapacity:n,...o},r={to:t,reverseIndex:this.edges[t].length,capacity:0,initialCapacity:0};this.edges[t].push(i),this.edges[e].push(r)}buildLevels(t,e){this.levels.fill(-1);const n=new Int32Array(this.edges.length);let o=0,i=0;for(n[i++]=t,this.levels[t]=0;o\u003ci;){const t=n[o++];for(const e of this.edges[t])e.capacity\u003c=0||this.levels[e.to]\u003e=0||(this.levels[e.to]=this.levels[t]+1,n[i++]=e.to)}return this.levels[e]\u003e=0}sendFlow(t,e){if(t===e)return 1;for(let n=this.nextEdges[t];n\u003cthis.edges[t].length;n++,this.nextEdges[t]=n){const o=this.edges[t][n];if(o.capacity\u003c=0||this.levels[o.to]!==this.levels[t]+1)continue;const i=this.sendFlow(o.to,e);if(0!==i)return o.capacity-=i,this.edges[o.to][o.reverseIndex].capacity+=i,i}return 0}maximumFlow(t,e,n){let o=0;for(;o\u003cn\u0026\u0026this.buildLevels(t,e);)for(this.nextEdges.fill(0);o\u003cn;){const n=this.sendFlow(t,e);if(0===n)break;o+=n}return o}};function Stt(t){const{direction:e,availableDirections:n,items:o,grid:i,obstacles:r,traceWidth:s,clearance:a,occupiedNodes:c,acceptedSegments:l,connectorSelectionOffset:d=0}=t;if(0===o.length)return{routes:[],usedNodes:[],unmatchedItems:[]};const{boundary:h,step:u,columnCount:p,rowCount:m,nodeCount:g}=i,f=t=\u003ei.points[t],y=s/2+a,_=s+a,b=new Uint8Array(g);for(let t=0;t\u003cg;t++)!c[t]\u0026\u0026i.obstacleFreeNodes[t]\u0026\u0026(b[t]=1);const x=(t,e)=\u003e{const n=xtt(t,s);return n.every(t=\u003er.every(n=\u003egtt(n,e)||A8(t,n)\u003e=y-utt))\u0026\u0026n.every(t=\u003el.every(e=\u003eT8(t.start,t.end,e.start,e.end)\u003e=_-utt))},v=new Map;for(const t of o){const e=`${t.source.x.toFixed(6)}:${t.source.y.toFixed(6)}:${t.netKey}`,n=v.get(e)??[];n.push(t),v.set(e,n)}const S=Array.from({length:3721},(t,e)=\u003e{const n=e%61-30,o=Math.floor(e/61)-30;return{x:n,y:o,distanceSquared:n*n+o*o}}).sort((t,e)=\u003et.distanceSquared-e.distanceSquared),I=[];for(const t of v.values()){const e=t[0],n=Math.hypot(e.connection.sourceObstacle.width/2,e.connection.sourceObstacle.height/2)+a+2*u,o=Math.round((e.source.x-h.minX)/u),i=Math.round((e.source.y-h.minY)/u),r=[],s=new Set;for(const t of S){const a=o+t.x,c=i+t.y;if(a\u003c0||a\u003e=p||c\u003c0||c\u003e=m)continue;const l=c*p+a;if(!b[l]||s.has(l))continue;if(M8(e.source,f(l))\u003en)continue;const d=ftt(e.source,f(l));if(x(d,e)\u0026\u0026(s.add(l),r.push({node:l,connectorPoints:d}),r.length\u003e=12))break}if(0===r.length)return null;I.push({item:e,equivalentItems:t,candidates:r})}const C=[];for(const t of[...I].sort((t,e)=\u003et.candidates.length-e.candidates.length)){const e=0===t.candidates.length?0:d%t.candidates.length,n=[...t.candidates.slice(e),...t.candidates.slice(0,e)].find(e=\u003e{const n=xtt(e.connectorPoints,s);return C.every(e=\u003ee.netKey===t.item.netKey||n.every(t=\u003ee.segments.every(e=\u003eT8(t.start,t.end,e.start,e.end)\u003e=_-utt)))});if(!n)return null;t.candidates=[n],C.push({netKey:t.item.netKey,segments:xtt(n.connectorPoints,s)})}const P=new Set(I.map(t=\u003et.candidates[0].node));for(const t of C)for(const e of t.segments){const t=Math.max(0,Math.floor((Math.min(e.start.x,e.end.x)-_-h.minX)/u)),n=Math.min(p-1,Math.ceil((Math.max(e.start.x,e.end.x)+_-h.minX)/u)),o=Math.max(0,Math.floor((Math.min(e.start.y,e.end.y)-_-h.minY)/u)),i=Math.min(m-1,Math.ceil((Math.max(e.start.y,e.end.y)+_-h.minY)/u));for(let r=o;r\u003c=i;r++)for(let o=t;o\u003c=n;o++){const t=r*p+o;if(!b[t]||P.has(t))continue;const n=f(t);T8(e.start,e.end,n,n)\u003c_-utt\u0026\u0026(b[t]=0)}}const M=1+I.length,N=M+g,w=N+g,T=new vtt(w+1);for(let t=0;t\u003cI.length;t++){const e=1+t;T.addEdge(0,e,1);for(const n of I[t].candidates)T.addEdge(e,M+n.node,1,{gridNode:n.node})}for(let t=0;t\u003cg;t++){if(!b[t])continue;T.addEdge(M+t,N+t,1);const o=t%p,r=Math.floor(t/p);for(const e of i.neighbors[t])b[e]\u0026\u0026T.addEdge(N+t,M+e,1,{gridNode:e});(\"any\"===e\u0026\u0026((!n||n.has(\"left\"))\u0026\u00260===o||(!n||n.has(\"right\"))\u0026\u0026o===p-1||(!n||n.has(\"down\"))\u0026\u00260===r||(!n||n.has(\"up\"))\u0026\u0026r===m-1)||\"left\"===e\u0026\u00260===o||\"right\"===e\u0026\u0026o===p-1||\"down\"===e\u0026\u00260===r||\"up\"===e\u0026\u0026r===m-1)\u0026\u0026T.addEdge(N+t,w,1,{isSink:!0})}const R=T.maximumFlow(0,w,I.length),E=t=\u003e{const e=1+t;return T.edges[0].some(t=\u003et.to===e\u0026\u00261===t.initialCapacity\u0026\u00260===t.capacity)};if(R!==I.length\u0026\u0026ptt){const t=I.flatMap((t,e)=\u003eE(e)?[]:[t.item.connection.connection.name]);console.error(\"single-layer flow group failed\",{direction:e,achievedFlow:R,requiredFlow:I.length,unmatchedConnections:t})}const A=[],O=[],k=[];for(let t=0;t\u003cI.length;t++){const e=I[t];if(!E(t)){k.push(...e.equivalentItems);continue}const n=1+t,o=T.edges[n].find(t=\u003e1===t.initialCapacity\u0026\u00260===t.capacity\u0026\u0026void 0!==t.gridNode);if(void 0===o?.gridNode)return null;const i=e.candidates.find(t=\u003et.node===o.gridNode);if(!i)return null;const r=[f(i.node)];let a=i.node;const c=[a];for(let t=0;t\u003c=g;t++){const t=N+a,e=T.edges[t].find(t=\u003e1===t.initialCapacity\u0026\u00260===t.capacity\u0026\u0026(void 0!==t.gridNode||t.isSink));if(!e)return null;if(e.isSink)break;if(void 0===e.gridNode)return null;a=e.gridNode,c.push(a),r.push(f(a))}O.push(...c);const l=ytt(btt(_tt([...i.connectorPoints,...r.slice(1)]),u/2)),d=xtt(l,s);for(const t of e.equivalentItems)A.push({item:t,points:l,segments:d})}return{routes:A,usedNodes:O,unmatchedItems:k}}function Itt(t,e){const n=ftt(t,e),o=ftt(e,t).reverse();return n.length===o.length\u0026\u0026n.every((t,e)=\u003eM8(t,o[e])\u003cutt)?[n]:[n,o]}function Ctt(t,e){return Math.abs(t.x-e.minX)\u003cutt?\"left\":Math.abs(t.x-e.maxX)\u003cutt?\"right\":Math.abs(t.y-e.minY)\u003cutt?\"down\":Math.abs(t.y-e.maxY)\u003cutt?\"up\":null}function Ptt(t){const{items:e,grid:n,obstacles:o,traceWidth:i,clearance:r,availableBoundaryRegions:s}=t,a=s?new Set(s.map(t=\u003et.direction)):void 0,c=new Set(e.filter(t=\u003et.connection.sourceObstacle.width\u003e2\u0026\u0026t.connection.sourceObstacle.height\u003e2));let l=null;for(let t=0;t\u003c4;t++){const t=e.filter(t=\u003e!c.has(t));let s=null;for(let e=0;e\u003c4;e++){const c=Stt({direction:\"any\",availableDirections:a,items:t,grid:n,obstacles:o,traceWidth:i,clearance:r,occupiedNodes:new Uint8Array(n.nodeCount),acceptedSegments:[],connectorSelectionOffset:e});if(c\u0026\u0026((!s||c.routes.length\u003es.routes.length)\u0026\u0026(s=c),c.routes.length===t.length))break}if(!s)return null;if(s.routes.length===t.length){l=s;break}const d=new Map;for(const e of t)d.set(e.netKey,(d.get(e.netKey)??0)+1);let h=!1;for(const t of s.unmatchedItems)(d.get(t.netKey)??0)\u003c2||(c.add(t),h=!0);if(!h)return null}if(!l)return null;const d=[...l.routes],h=i/2+r,u=i+r;for(const t of c){const e=d.filter(e=\u003ee.item.netKey===t.netKey).flatMap(t=\u003et.points.map((e,n)=\u003e({route:t,point:e,pointIndex:n}))).sort((e,n)=\u003eNumber(n.route.item.bus.componentId===t.bus.componentId)-Number(e.route.item.bus.componentId===t.bus.componentId)||M8(t.source,e.point)-M8(t.source,n.point));let n=null;for(const r of e){for(const e of Itt(t.source,r.point)){const s=xtt(e,i),a=s.every(e=\u003eo.every(n=\u003egtt(n,t)||A8(e,n)\u003e=h-utt)),c=s.every(e=\u003ed.every(n=\u003en.item.netKey===t.netKey||n.segments.every(t=\u003eT8(e.start,e.end,t.start,t.end)\u003e=u-utt)));if(!a||!c)continue;const l=ytt(_tt([...e,...r.route.points.slice(r.pointIndex+1)]));n={item:t,points:l,segments:xtt(l,i)};break}if(n)break}if(!n)return null;d.push(n)}const p=d.map(t=\u003efunction(t,e){const{item:n,points:o,segments:i}=t,r=o.map((t,o)=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:e,layer:\"top\",...0===o\u0026\u0026n.connection.sourcePoint.pcb_port_id?{start_pcb_port_id:n.connection.sourcePoint.pcb_port_id}:{}})),s=x8({connectionName:n.connection.connection.name,sourcePointIndex:n.connection.sourcePointIndex});return{busId:n.bus.busId,connectionName:n.connection.connection.name,connectionIndex:n.connection.connectionIndex,sourcePointIndex:n.connection.sourcePointIndex,sourcePoint:n.connection.sourcePoint,sourceObstacle:n.connection.sourceObstacle,sourceLayer:n.connection.sourceLayer,targetPoint:n.connection.targetPoint,targetLayer:\"top\",termination:n.bus.termination,direction:n.bus.direction,exitPoint:o.at(-1),trace:{type:\"pcb_trace\",pcb_trace_id:s.traceId,connection_name:n.connection.connection.name,connectsTo:[...n.connection.sourcePoint.pointId?[n.connection.sourcePoint.pointId]:[],...n.connection.sourcePoint.pcb_port_id?[n.connection.sourcePoint.pcb_port_id]:[],s.boundaryExitPointId],route:r},segments:i,length:i.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}(t,i));if(!function(t){const{plans:e,items:n,obstacles:o,traceWidth:i,clearance:r}=t,s=new Map(n.map(t=\u003e[t.connection.connection.name,t.netKey])),a=new Map,c=new Map;for(const t of e){const e=s.get(t.connectionName),n=a.get(e)??[],o=c.get(e)??new Set;for(const e of t.segments){const t=[e.start,e.end].map(t=\u003e`${t.x.toFixed(6)}:${t.y.toFixed(6)}`).sort().join(\":\");o.has(t)||(o.add(t),n.push(e))}a.set(e,n),c.set(e,o)}const l=i/2+r;for(const[t,e]of a)for(const n of e)for(const e of o)if(!(e.connectedTo.includes(t)||A8(n,e)\u003e=l-utt))return ptt\u0026\u0026console.error(\"single-layer route violates obstacle clearance\",{netKey:t,segment:n,obstacleId:e.obstacleId,distance:A8(n,e),requiredObstacleDistance:l}),!1;const d=i+r,h=[...a];for(let t=0;t\u003ch.length;t++)for(let e=t+1;e\u003ch.length;e++)for(const n of h[t][1])for(const o of h[e][1])if(T8(n.start,n.end,o.start,o.end)\u003cd-utt)return ptt\u0026\u0026console.error(\"single-layer routes violate copper clearance\",{firstNetKey:h[t][0],secondNetKey:h[e][0],first:n,second:o,distance:T8(n.start,n.end,o.start,o.end),requiredRouteDistance:d}),!1;return!0}({plans:p,items:e,obstacles:o,traceWidth:i,clearance:r}))return ptt\u0026\u0026console.error(\"single-layer adaptive exits failed exact clearance\"),null;for(const t of p){const o=Ctt(t.exitPoint,n.boundary);if(!o||a\u0026\u0026!a.has(o))return null;const i=e.find(e=\u003ee.connection.connection.name===t.connectionName);i.bus.direction=o;const r=s?.filter(t=\u003et.direction===o),c=\"up\"===o||\"down\"===o?t.exitPoint.x:t.exitPoint.y;i.bus.preferredExit=r?.toSorted((t,e)=\u003eMath.abs(c-D7(t,n.boundary))-Math.abs(c-D7(e,n.boundary)))[0]?.preferredExit??(\"up\"===o?\"top\":\"down\"===o?\"bottom\":o),t.direction=o}const m=new Map(p.map(t=\u003e[t.connectionName,t]));return e.map(t=\u003em.get(t.connection.connection.name))}function Mtt(t){const{srj:e,buses:n,traceWidth:o,clearance:i,availableBoundaryRegions:r}=t;if(n.some(t=\u003e1!==t.connections.length))return null;const s=n.flatMap(t=\u003et.connections.map(e=\u003e({bus:t,connection:e,source:{x:e.sourcePoint.x,y:e.sourcePoint.y},netKey:mtt(e)}))),a=e.obstacles.filter(t=\u003et.layers.includes(\"top\")),c=n[0]?.sharedBoundary;if(!c)return[];const l=function(t){const{boundary:e,obstacles:n,traceWidth:o,clearance:i}=t,r=o+i,s=Math.round((e.maxX-e.minX)/r)+1,a=Math.round((e.maxY-e.minY)/r)+1,c=s*a,l=Array.from({length:c},(t,n)=\u003e({x:e.minX+n%s*r,y:e.minY+Math.floor(n/s)*r})),d=o/2+i,h=new Map;for(let t=0;t\u003cn.length;t++){const e=n[t],o=Math.floor((e.center.x-e.width/2-d)/1),i=Math.floor((e.center.x+e.width/2+d)/1),r=Math.floor((e.center.y-e.height/2-d)/1),s=Math.floor((e.center.y+e.height/2+d)/1);for(let e=o;e\u003c=i;e++)for(let n=r;n\u003c=s;n++){const o=`${e}:${n}`,i=h.get(o)??[];i.push(t),h.set(o,i)}}const u=(t,e=t)=\u003e{const o=Math.floor(Math.min(t.x,e.x)/1),i=Math.floor(Math.max(t.x,e.x)/1),r=Math.floor(Math.min(t.y,e.y)/1),s=Math.floor(Math.max(t.y,e.y)/1),a=new Set;for(let t=o;t\u003c=i;t++)for(let e=r;e\u003c=s;e++)for(const n of h.get(`${t}:${e}`)??[])a.add(n);return[...a].map(t=\u003en[t])},p=new Uint8Array(c);for(let t=0;t\u003cc;t++){const e=l[t];u(e).every(t=\u003eE8(e,t)\u003e=d-utt)\u0026\u0026(p[t]=1)}const m=Array.from({length:c},()=\u003e[]);for(let t=0;t\u003cc;t++){if(!p[t])continue;const e=t%s,n=Math.floor(t/s);for(const[i,r]of[[1,0],[0,1]]){const c=e+i,h=n+r;if(c\u003e=s||h\u003e=a)continue;const g=h*s+c;if(!p[g])continue;const f={start:l[t],end:l[g],width:o,layer:\"top\"};u(f.start,f.end).some(t=\u003eA8(f,t)\u003cd-utt)||(m[t].push(g),m[g].push(t))}}return{boundary:e,step:r,columnCount:s,rowCount:a,nodeCount:c,points:l,obstacleFreeNodes:p,neighbors:m}}({boundary:c,obstacles:a,traceWidth:o,clearance:i});ptt\u0026\u0026console.error(\"single-layer adaptive-exit grid ready\",{nodeCount:l.nodeCount});const d=Ptt({items:s,grid:l,obstacles:a,traceWidth:o,clearance:i,availableBoundaryRegions:r});return d||null}function Ntt(t){return\"left\"===t||\"right\"===t}function wtt(t){return\"right\"===t||\"up\"===t?1:-1}function Ttt(t,e){return Ntt(e)?t.x:t.y}function Rtt(t,e){return Ntt(e)?t.y:t.x}function Ett(t,e,n){return Ntt(n)?{x:t,y:e}:{x:e,y:t}}function Att(t){switch(t.direction){case\"right\":return t.sharedBoundary.maxX;case\"left\":return t.sharedBoundary.minX;case\"up\":return t.sharedBoundary.maxY;case\"down\":return t.sharedBoundary.minY}}function Ott(t){if(t.length\u003c3)return t;const e=[t[0]];for(let n=1;n\u003ct.length-1;n++){const o=e.at(-1),i=t[n],r=t[n+1],s={x:Math.sign(i.x-o.x),y:Math.sign(i.y-o.y)},a={x:Math.sign(r.x-i.x),y:Math.sign(r.y-i.y)};s.x===a.x\u0026\u0026s.y===a.y||e.push(i)}return e.push(t.at(-1)),e}function ktt(t,e){const n=[];for(let o=1;o\u003ct.length;o++)M8(t[o-1],t[o])\u003c1e-9||n.push({start:t[o-1],end:t[o],width:e,layer:\"top\"});return n}function Ltt(t){const{item:e,srj:n,acceptedSegments:o,traceWidth:i,clearance:r}=t,s=e.cornerChannelPrefixes;if(!s)return null;const a=e.direction,c=wtt(a),l=Att(e.bus),d=i+r,h=i/2+r,u=Ntt(a)?e.bus.sharedBoundary.minY:e.bus.sharedBoundary.minX,p=Ntt(a)?e.bus.sharedBoundary.maxY:e.bus.sharedBoundary.maxX,m=u+i/2,g=p-i/2,f=Rtt(e.connection.exitTargetPoint??e.connection.targetPoint,a),y=d/2,_=new Set([Math.max(m,Math.min(g,f))]);for(let t=Math.ceil(m/y)*y;t\u003c=g+1e-9;t+=y)_.add(Number(t.toFixed(9)));const b=[..._].toSorted((t,e)=\u003eMath.abs(t-f)-Math.abs(e-f));for(const t of s){const s=t.at(-1),u=Rtt(s,a);for(const p of b){const m=Math.abs(p-u),g=Ett(Ttt(s,a)+c*d,u,a),f=Ett(Ttt(g,a)+c*m,p,a);if(c*(l-Ttt(f,a))\u003c-1e-9)continue;const y=Ett(l,p,a),_=[...t,g,...m\u003e1e-9?[f]:[]];M8(_.at(-1),y)\u003e1e-9\u0026\u0026_.push(y);const b=Ott(_),x=ktt(b,i);if(!x.every(t=\u003en.obstacles.every(n=\u003en===e.connection.sourceObstacle||!n.layers.includes(\"top\")||A8(t,n)\u003e=h-1e-9)))continue;if(x.every(t=\u003eo.every(e=\u003eT8(t.start,t.end,e.start,e.end)\u003e=i+r-1e-9)))return{item:e,points:b,track:p}}}return null}function Dtt(t){const{route:e,direction:n,exitAxis:o,signedShift:i,maximumShift:r,obstacles:s,requiredObstacleDistance:a}=t;if(r\u003c=1e-9||Math.abs(i)\u003c=1e-9)return 0;const c=Math.sign(i),l=t=\u003e{if(t\u003c=1e-9)return!0;const i={start:Ett(o-wtt(n)*t,e.track,n),end:Ett(o,e.track+c*t,n),width:0,layer:\"top\"};return s.every(t=\u003et===e.item.connection.sourceObstacle||!t.layers.includes(\"top\")||A8(i,t)\u003e=a-1e-9)};if(l(r))return r;let d=0,h=r;for(let t=0;t\u003c32;t++){const t=(d+h)/2;l(t)?d=t:h=t}return d}function ztt(t){const{requestedTracks:e,currentTracks:n,candidateTracks:o,maximumShifts:i}=t,r=e.length+1,s=o.length+1,a=Array.from({length:r},()=\u003enew Float64Array(s).fill(Number.POSITIVE_INFINITY)),c=Array.from({length:r},()=\u003enew Uint8Array(s));a[0].fill(0);for(let t=1;t\u003cr;t++)for(let r=1;r\u003cs;r++){const s=a[t][r-1],l=Math.abs(e[t-1]-o[r-1]),d=Math.abs(n[t-1]-o[r-1])\u003ei[t-1]+1e-9?Number.POSITIVE_INFINITY:a[t-1][r-1]+l;d\u003cs?(a[t][r]=d,c[t][r]=1):a[t][r]=s}if(!Number.isFinite(a.at(-1).at(-1)))return null;const l=[];let d=e.length,h=o.length;for(;d\u003e0\u0026\u0026h\u003e0;)c[d][h]\u0026\u0026(l.push(o[h-1]),d--),h--;return d\u003e0?null:l.reverse()}function Ftt(t){const{direction:e,activeRoutes:n,obstacles:o,boundaryMinimum:i,boundaryMaximum:r,traceWidth:s,clearance:a,requestedTracks:c,maximumShifts:l}=t,d=s+a,h=s/2+a;let u=null,p=Number.POSITIVE_INFINITY;for(const t of Array.from({length:Math.round(d/s)},(t,e)=\u003ee*s)){const a=[];for(let n=Math.ceil((i-t)/d)*d+t;n\u003c=r+1e-9;n+=d){const t=Math.round(n/s)*s;o.every(n=\u003e{const o=Rtt(n.center,e),i=Ntt(e)?n.height:n.width;return Math.abs(t-o)\u003e=i/2+h-1e-9})\u0026\u0026a.push(t)}const m=ztt({requestedTracks:c,currentTracks:n.map(t=\u003et.track),candidateTracks:a,maximumShifts:l});if(!m)continue;const g=m.reduce((t,e,n)=\u003et+Math.abs(e-c[n]),0);g\u003cp\u0026\u0026(p=g,u=m)}return u}function Btt(t,e){switch(e){case\"up\":return\"top-left\"===t?\"minimum\":\"top-right\"===t?\"maximum\":null;case\"down\":return\"bottom-left\"===t?\"minimum\":\"bottom-right\"===t?\"maximum\":null;case\"left\":return\"bottom-left\"===t?\"minimum\":\"top-left\"===t?\"maximum\":null;case\"right\":return\"bottom-right\"===t?\"minimum\":\"top-right\"===t?\"maximum\":null}}function jtt(t){const{items:e,direction:n,boundaryMinimum:o,boundaryMaximum:i,traceWidth:r,clearance:s,borderDistribution:a,currentTrackByConnectionName:c}=t,l=t=\u003ec.get(t.connection.connection.name)??Rtt(t.source,n),d=[...e].toSorted((t,e)=\u003el(t)-l(e)||t.connection.connection.name.localeCompare(e.connection.connection.name)),h=r+s,u=o+r/2,p=i-r/2;if(p-u\u003ch*Math.max(d.length-1,0)-1e-9)return null;const m=d.map(l);let g=[...m],f=h;const y=new Set;if(\"even\"===a\u0026\u0026d.length\u003e1){const t=m[0],e=m.at(-1),n=Math.max(h,(e-t)/(d.length-1)),o=t=\u003e{const e=[...m],n=Math.floor(d.length/2),o=d.length%2==0?n-1:n;if(o!==n){const i=e[n]-e[o];if(i\u003ct){const r=(t-i)/2;e[o]=e[o]-r,e[n]=e[n]+r}}for(let n=o-1;n\u003e=0;n--)e[n]=Math.min(e[n],e[n+1]-t);for(let o=n+1;o\u003ce.length;o++)e[o]=Math.max(e[o],e[o-1]+t);return e},i=t=\u003et[0]\u003e=u-1e-9\u0026\u0026t.at(-1)\u003c=p+1e-9;if(g=o(n),i(g))f=n;else{let t=h,e=n;if(g=o(t),!i(g))return null;for(let n=0;n\u003c32;n++){const n=(t+e)/2,r=o(n);i(r)?(t=n,g=r):e=n}f=t}for(const t of d)y.add(t.connection.connection.name)}const _=[],b=[];for(let t=0;t\u003cd.length;t++){const e=d[t],o=e.bus.preferredExit;if(!o?.includes(\"-\"))continue;const i=Btt(o,n);if(!i)return null;y.add(e.connection.connection.name),\"minimum\"===i?_.push(t):b.push(t)}if(_.some((t,e)=\u003et!==e)||b.some((t,e)=\u003et!==d.length-b.length+e))return null;const x=2*h;if(_.length\u003e0){g[0]=u+x;for(let t=1;t\u003c_.length;t++){const e=Math.max(f,m[t]-m[t-1]);g[t]=g[t-1]+e}}if(b.length\u003e0){const t=d.length-1;g[t]=p-x;for(let e=t-1;e\u003e=d.length-b.length;e--){const t=Math.max(f,m[e+1]-m[e]);g[e]=g[e+1]-t}}return{byConnectionName:new Map(d.map((t,e)=\u003e[t.connection.connection.name,g[e]])),enforcedConnectionNames:y}}function $tt(t){const{item:e,points:n,segments:o}=t,i=n.map((t,n)=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:o[0]?.width??.1,layer:\"top\",...0===n\u0026\u0026e.connection.sourcePoint.pcb_port_id?{start_pcb_port_id:e.connection.sourcePoint.pcb_port_id}:{}})),r=x8({connectionName:e.connection.connection.name,sourcePointIndex:e.connection.sourcePointIndex});return{busId:e.bus.busId,connectionName:e.connection.connection.name,connectionIndex:e.connection.connectionIndex,sourcePointIndex:e.connection.sourcePointIndex,sourcePoint:e.connection.sourcePoint,sourceObstacle:e.connection.sourceObstacle,sourceLayer:e.connection.sourceLayer,targetPoint:e.connection.targetPoint,targetLayer:\"top\",termination:e.bus.termination,direction:e.direction,exitPoint:n.at(-1),trace:{type:\"pcb_trace\",pcb_trace_id:r.traceId,connection_name:e.connection.connection.name,connectsTo:[...e.connection.sourcePoint.pointId?[e.connection.sourcePoint.pointId]:[],...e.connection.sourcePoint.pcb_port_id?[e.connection.sourcePoint.pcb_port_id]:[],r.boundaryExitPointId],route:i},segments:o,length:o.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}function Ytt(t){const{srj:e,buses:n,traceWidth:o,clearance:i,borderDistribution:r}=t,s=o/2+i,a=new Map,c=new Map,l=n.flatMap(t=\u003et.connections.map(n=\u003e{const r={x:n.sourcePoint.x,y:n.sourcePoint.y},s=function(t){const{srj:e,bus:n,connection:o,traceWidth:i,clearance:r}=t,s=n.direction,a=wtt(s),c={x:o.sourcePoint.x,y:o.sourcePoint.y},l=Ttt(c,s),d=Rtt(c,s),h=i/2+r,u=(()=\u003e{switch(s){case\"right\":return n.componentBounds.maxX+h;case\"left\":return n.componentBounds.minX-h;case\"up\":return n.componentBounds.maxY+h;case\"down\":return n.componentBounds.minY-h}})(),p=t=\u003eMath.min(...e.obstacles.filter(t=\u003et!==o.sourceObstacle\u0026\u0026t.layers.includes(\"top\")).map(e=\u003eA8(t,e))),m={start:c,end:Ett(u,d,s),width:i,layer:\"top\"};if(p(m)\u003e=h-1e-9)return null;const g=Ntt(s)?{minimum:n.componentBounds.minY,maximum:n.componentBounds.maxY}:{minimum:n.componentBounds.minX,maximum:n.componentBounds.maxX},f=a*(u-l),y=Rtt(o.exitTargetPoint??o.targetPoint,s),_=i+r,b=Att(n),x=[-1,1].map(t=\u003e{const e=t*((t\u003c0?g.minimum-h:g.maximum+h)-d),o=Math.max(f,e),r=Ett(l+a*o,d+t*o,s);if(a*(b-Ttt(r,s))\u003c_-1e-9)return null;const u=[c,r];if(!u.every(t=\u003et.x\u003e=n.sharedBoundary.minX-1e-9\u0026\u0026t.x\u003c=n.sharedBoundary.maxX+1e-9\u0026\u0026t.y\u003e=n.sharedBoundary.minY-1e-9\u0026\u0026t.y\u003c=n.sharedBoundary.maxY+1e-9))return null;const m=Math.min(...ktt(u,i).map(p));return m\u003ch-1e-9?null:{points:u,obstacleDistance:m,targetDistance:Math.abs(Rtt(r,s)-y)}}).filter(t=\u003enull!==t).toSorted((t,e)=\u003ee.obstacleDistance-t.obstacleDistance||t.targetDistance-e.targetDistance);return x.length\u003e0?x.map(t=\u003et.points):null}({srj:e,bus:t,connection:n,traceWidth:o,clearance:i});return{bus:t,connection:n,direction:t.direction,source:r,...s?{cornerChannelPrefixes:s}:{}}}));for(const t of[\"left\",\"right\",\"up\",\"down\"]){const n=wtt(t),d=l.filter(e=\u003ee.direction===t\u0026\u0026!e.cornerChannelPrefixes);if(0===d.length)continue;const h=Ntt(t)?d[0].bus.sharedBoundary.minY:d[0].bus.sharedBoundary.minX,u=Ntt(t)?d[0].bus.sharedBoundary.maxY:d[0].bus.sharedBoundary.maxX,p=Att(d[0].bus),m=new Map,g=new Map,f=new Map;for(const e of d){const n=Ttt(e.source,t),o=n.toFixed(6);f.set(o,n);const i=m.get(o)??[];i.push(e),m.set(o,i)}for(const[n,o]of m){const i=f.get(n),r=new Set(o.map(t=\u003et.bus.componentId));g.set(n,e.obstacles.filter(e=\u003ee.layers.includes(\"top\")\u0026\u0026!!e.componentId\u0026\u0026r.has(e.componentId)\u0026\u0026Math.abs(Ttt(e.center,t)-i)\u003c1e-6))}const y=[...f.values()].toSorted((t,e)=\u003en*(t-e)),_=new Map;for(let e=0;e\u003cy.length;e++){const r=y[e],a=r.toFixed(6);for(const e of m.get(a)??[]){const o=Ntt(t)?e.connection.sourceObstacle.width:e.connection.sourceObstacle.height,i=Math.max(e.connection.sourceObstacle.width,e.connection.sourceObstacle.height)\u003c1.5?o/2+s:0,a=Ett(r+n*i,Rtt(e.source,t),t);_.set(e.connection.connection.name,{item:e,points:M8(e.source,a)\u003e1e-9?[e.source,a]:[e.source],track:Rtt(e.source,t)})}const c=y[e+1]??p;if(0===_.size||n*(c-r)\u003c=1e-9)continue;const l=[..._.values()].toSorted((t,e)=\u003et.track-e.track||t.item.connection.connection.name.localeCompare(e.item.connection.connection.name)),d=y.slice(e+1,e+3).flatMap(t=\u003eg.get(t.toFixed(6))??[]),f=l.map(e=\u003eMath.abs(c-Ttt(e.points.at(-1),t))),b=Ftt({direction:t,activeRoutes:l,obstacles:d,boundaryMinimum:h,boundaryMaximum:u,traceWidth:o,clearance:i,requestedTracks:l.map(t=\u003et.track),maximumShifts:f});if(!b)return null;for(let e=0;e\u003cl.length;e++){const o=l[e],i=b[e],r=Math.abs(i-o.track),s=Ett(Ttt(o.points.at(-1),t)+n*r,i,t);M8(o.points.at(-1),s)\u003e1e-9\u0026\u0026o.points.push(s);const a=Ett(c,i,t);M8(o.points.at(-1),a)\u003e1e-9\u0026\u0026o.points.push(a),o.track=i}}const b=jtt({items:d,direction:t,boundaryMinimum:h,boundaryMaximum:u,traceWidth:o,clearance:i,borderDistribution:r,currentTrackByConnectionName:new Map([..._.values()].map(t=\u003e[t.item.connection.connection.name,t.track]))});if(!b)return null;const x=[..._.values()].toSorted((t,e)=\u003et.track-e.track||t.item.connection.connection.name.localeCompare(e.item.connection.connection.name)),v=new Map,S=o+i;let I=S;for(const t of x){const e=t.item.connection.connection.name;if(!b.enforcedConnectionNames.has(e))continue;b.byConnectionName.get(e)-t.track\u003e=-1e-9||(v.set(e,I),I+=2*S)}let C=S;for(let t=x.length-1;t\u003e=0;t--){const e=x[t],n=e.item.connection.connection.name;if(!b.enforcedConnectionNames.has(n))continue;b.byConnectionName.get(n)-e.track\u003c=1e-9||(v.set(n,C),C+=2*S)}for(const o of x){const i=o.item.connection.connection.name,r=b.byConnectionName.get(i)??o.track,a=v.get(i)??0,c=o.points.at(-2),l=c?n*(p-Ttt(c,t)):0,d=r-o.track,h=Math.min(Math.abs(d),Math.max(0,l-a)),u=Dtt({route:o,direction:t,exitAxis:p,signedShift:d,maximumShift:h,obstacles:e.obstacles,requiredObstacleDistance:s}),m=Math.sign(d)*u;b.byConnectionName.set(i,o.track+m)}for(const t of b.enforcedConnectionNames)c.set(t,b.byConnectionName.get(t));for(const e of x){const o=e.item.connection.connection.name,i=b.byConnectionName.get(o)??e.track,r=Math.abs(i-e.track),s=v.get(o)??0,a=p-n*(r\u003e1e-9?s+r:0),c=e.points.at(-1);if(Math.abs(Ttt(c,t)-p)\u003e1e-6)return null;const l=e.points.at(-2);if(l\u0026\u0026(Math.abs(Rtt(l,t)-e.track)\u003e1e-6||n*(a-Ttt(l,t))\u003c-1e-6))return null;const d=Ett(a,e.track,t);l\u0026\u0026M8(l,d)\u003c1e-9?e.points.pop():e.points[e.points.length-1]=d}for(const e of x){const o=e.item.connection.connection.name,i=b.byConnectionName.get(o)??e.track,r=Math.abs(i-e.track),s=v.get(o)??0;r\u003e1e-9\u0026\u0026s\u003e1e-9\u0026\u0026e.points.push(Ett(Ttt(e.points.at(-1),t)+n*s,e.track,t)),r\u003e1e-9\u0026\u0026(e.points.push(Ett(Ttt(e.points.at(-1),t)+n*r,i,t)),e.track=i);const c=Ett(p,e.track,t);if(M8(e.points.at(-1),c)\u003e1e-9){if(n*(p-Ttt(e.points.at(-1),t))\u003c-1e-6)return null;e.points.push(c)}a.set(o,e)}}const d=[...a.values()].flatMap(t=\u003ektt(Ott(t.points),o));for(const t of l){if(!t.cornerChannelPrefixes)continue;const n=Ltt({item:t,srj:e,acceptedSegments:d,traceWidth:o,clearance:i});if(!n)return null;a.set(t.connection.connection.name,n),d.push(...ktt(Ott(n.points),o))}if(a.size!==l.length)return null;const h=(o+i)/2+1e-6;for(const[t,e]of c){const n=a.get(t);if(!n||Math.abs(n.track-e)\u003eh)return null}const u=l.map(t=\u003e{const e=Ott(a.get(t.connection.connection.name).points);return{item:t,points:e,segments:ktt(e,o)}});return function(t){const{paths:e,obstacles:n,traceWidth:o,clearance:i}=t,r=o/2+i,s=o+i;for(const t of e){if(Math.abs(Ttt(t.points.at(-1),t.item.direction)-Att(t.item.bus))\u003e1e-6)return!1;for(const e of t.segments)for(const o of n)if(o!==t.item.connection.sourceObstacle\u0026\u0026o.layers.includes(\"top\")\u0026\u0026A8(e,o)\u003cr-1e-9)return!1}for(let t=0;t\u003ce.length;t++)for(let n=t+1;n\u003ce.length;n++)for(const o of e[t].segments)for(const t of e[n].segments)if(T8(o.start,o.end,t.start,t.end)\u003cs-1e-9)return!1;return!0}({paths:u,obstacles:e.obstacles,traceWidth:o,clearance:i})?u.map($tt):null}var Xtt=1e-6;function Vtt(t,e){return M8(t,e)\u003c=Xtt}function Wtt(t){return\"layer\"in t?[t.layer]:t.layers}function Htt(t){return[...t.segments,...t.planeEndpointSegments??[]]}function Gtt(t){return[t.via,t.planeEndpointVia].filter(t=\u003eBoolean(t))}function Utt(t,e){return Vtt(t,e)\u0026\u0026Wtt(t).join(\"\\0\")===Wtt(e).join(\"\\0\")\u0026\u0026t.pointId===e.pointId\u0026\u0026t.pcb_port_id===e.pcb_port_id}function Ztt(t,e){const n=t.x\u003e=e.minX-Xtt\u0026\u0026t.x\u003c=e.maxX+Xtt\u0026\u0026t.y\u003e=e.minY-Xtt\u0026\u0026t.y\u003c=e.maxY+Xtt,o=Math.abs(t.x-e.minX)\u003c=Xtt||Math.abs(t.x-e.maxX)\u003c=Xtt||Math.abs(t.y-e.minY)\u003c=Xtt||Math.abs(t.y-e.maxY)\u003c=Xtt;return n\u0026\u0026o}function qtt(t,e){return t.x\u003e=e.minX-Xtt\u0026\u0026t.x\u003c=e.maxX+Xtt\u0026\u0026t.y\u003e=e.minY-Xtt\u0026\u0026t.y\u003c=e.maxY+Xtt}function Jtt(t,e,n,o,i){t.push({code:e,message:n,...o?{connectionName:o.connectionName,busId:o.busId}:{},...i?{otherConnectionName:i}:{}})}function Ktt(t){const{trace:e,plan:n,issues:o}=t,i=[];let r,s;for(const t of e.route)\"via\"!==t.route_type?\"wire\"===t.route_type?s?(Vtt(t,s)\u0026\u0026t.layer===s.to_layer||Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} does not continue from its via on ${s.to_layer}`,n),r=t,s=void 0):(r\u0026\u0026(r.layer!==t.layer?Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} changes from ${r.layer} to ${t.layer} without a via`,n):Vtt(r,t)||i.push({start:{x:r.x,y:r.y},end:{x:t.x,y:t.y},width:t.width,layer:t.layer})),r=t):Jtt(o,\"unsupported-route-point\",`Trace ${e.pcb_trace_id} contains unsupported ${t.route_type} geometry`,n):(r\u0026\u0026Vtt(r,t)\u0026\u0026r.layer===t.from_layer||Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} reaches a via without a matching ${t.from_layer} wire endpoint`,n),s=t);return s\u0026\u0026Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} ends at a via without a wire on ${s.to_layer}`,n),i}function Qtt(t){const{plan:e,preparedBus:n,inputSrj:o,outputSrj:i,sharedBoundary:r,issues:s}=t,a=o.connections[e.connectionIndex];if(!a||a.name!==e.connectionName)return void Jtt(s,\"connection-mismatch\",`Plan index ${e.connectionIndex} does not identify connection ${e.connectionName}`,e);const c=n?.connections.find(t=\u003et.connectionIndex===e.connectionIndex);if(c\u0026\u0026c.sourcePointIndex===e.sourcePointIndex\u0026\u0026Utt(c.sourcePoint,e.sourcePoint)\u0026\u0026c.sourceObstacle.obstacleId===e.sourceObstacle.obstacleId||Jtt(s,\"source-mismatch\",`Plan ${e.connectionName} does not start at its prepared component endpoint`,e),n?.termination.type!==e.termination.type\u0026\u0026Jtt(s,\"termination-mismatch\",`Plan ${e.connectionName} does not use its bus termination`,e),0===e.segments.length||e.length\u003c=Xtt)Jtt(s,\"not-broken-out\",`Plan ${e.connectionName} has no non-zero escape geometry`,e);else{const t={minX:Math.min(o.bounds.minX,r.minX),maxX:Math.max(o.bounds.maxX,r.maxX),minY:Math.min(o.bounds.minY,r.minY),maxY:Math.max(o.bounds.maxY,r.maxY)};e.segments.some(e=\u003e!qtt(e.start,t)||!qtt(e.end,t))\u0026\u0026Jtt(s,\"outside-routing-bounds\",`Plan ${e.connectionName} leaves the routable SRJ/shared-boundary area`,e),Vtt(e.segments[0].start,e.sourcePoint)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} does not start at its source pad`,e),Vtt(e.segments.at(-1).end,e.exitPoint)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} does not end at its declared exit`,e);for(let t=1;t\u003ce.segments.length;t++){const n=e.segments[t-1],o=e.segments[t];Vtt(n.end,o.start)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} has a gap between route segments`,e),n.layer===o.layer||e.via\u0026\u0026Vtt(n.end,e.via.center)\u0026\u0026e.via.spanLayers.includes(n.layer)\u0026\u0026e.via.spanLayers.includes(o.layer)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} changes layers without a connecting via`,e)}}const l=Ktt({trace:e.trace,plan:e,issues:s});if((l.length!==e.segments.length||l.some((t,n)=\u003e{const o=e.segments[n];return!o||t.layer!==o.layer||Math.abs(t.width-o.width)\u003eXtt||!Vtt(t.start,o.start)||!Vtt(t.end,o.end)}))\u0026\u0026Jtt(s,\"trace-plan-mismatch\",`Trace ${e.trace.pcb_trace_id} does not encode its declared route segments`,e),e.planeEndpointTrace||e.planeEndpointSegments||e.planeEndpointVia)if(e.planeEndpointTrace\u0026\u0026e.planeEndpointSegments\u0026\u0026e.planeEndpointVia){const t=Ktt({trace:e.planeEndpointTrace,plan:e,issues:s});(t.length!==e.planeEndpointSegments.length||t.some((t,n)=\u003e{const o=e.planeEndpointSegments?.[n];return!o||t.layer!==o.layer||Math.abs(t.width-o.width)\u003eXtt||!Vtt(t.start,o.start)||!Vtt(t.end,o.end)})||M8(e.planeEndpointVia.center,e.targetPoint)\u003c=Xtt)\u0026\u0026Jtt(s,\"trace-plan-mismatch\",`Trace ${e.planeEndpointTrace.pcb_trace_id} does not encode a valid offset plane-to-endpoint dogbone`,e)}else Jtt(s,\"trace-plan-mismatch\",`Plane endpoint geometry for ${e.connectionName} is incomplete`,e);const d=e.trace.route.find(t=\u003e\"x\"in t\u0026\u0026\"y\"in t),h=[...e.trace.route].reverse().find(t=\u003e\"x\"in t\u0026\u0026\"y\"in t);d\u0026\u0026h\u0026\u0026Vtt(d,e.sourcePoint)\u0026\u0026Vtt(h,e.exitPoint)||Jtt(s,\"disconnected-trace\",`Trace ${e.trace.pcb_trace_id} does not span its source and exit`,e);const u=i.connections.find(t=\u003et.name===e.connectionName);if(\"boundary\"===e.termination.type)if(u){const t=u.pointsToConnect[e.sourcePointIndex];t\u0026\u0026Vtt(t,e.exitPoint)\u0026\u0026\"layer\"in t\u0026\u0026t.layer===e.targetLayer||Jtt(s,\"output-exit-mismatch\",`Output connection ${e.connectionName} is not attached to its fanout exit`,e);for(let t=0;t\u003ca.pointsToConnect.length;t++){if(t===e.sourcePointIndex)continue;const n=a.pointsToConnect[t],o=u.pointsToConnect[t];n\u0026\u0026o\u0026\u0026Utt(n,o)||Jtt(s,\"downstream-endpoint-lost\",`Output connection ${e.connectionName} did not retain downstream endpoint ${t}`,e)}}else Jtt(s,\"output-connection-missing\",`Boundary connection ${e.connectionName} was removed from the output`,e);else u\u0026\u0026Jtt(s,\"plane-connection-retained\",`Plane-terminated connection ${e.connectionName} remains in the output`,e)}function tet(t,e){const n=Htt(t),o=Htt(e),i=Gtt(t),r=Gtt(e);for(const t of n){for(const e of o)if(t.layer===e.layer\u0026\u0026T8(t.start,t.end,e.start,e.end)\u003c=(t.width+e.width)/2+Xtt)return!0;for(const e of r)if(e.spanLayers.includes(t.layer)\u0026\u0026N8(e.center,t.start,t.end)\u003c=e.diameter/2+t.width/2+Xtt)return!0}for(const t of i){for(const e of o)if(t.spanLayers.includes(e.layer)\u0026\u0026N8(t.center,e.start,e.end)\u003c=t.diameter/2+e.width/2+Xtt)return!0;for(const e of r)if(t.spanLayers.some(t=\u003ee.spanLayers.includes(t))\u0026\u0026M8(t.center,e.center)\u003c=(t.diameter+e.diameter)/2+Xtt)return!0}return!1}function eet(t){const{inputSrj:e,outputSrj:n,plans:o,preparedBuses:i,sharedBoundary:r,clearance:s}=t,a=[],c=new Map,l=new Map(i.map(t=\u003e[t.busId,t]));for(const t of o){const e=c.get(t.connectionName)??[];e.push(t),c.set(t.connectionName,e)}for(const t of e.connections){const e=c.get(t.name)??[];0===e.length?Jtt(a,\"missing-plan\",`Connection ${t.name} has no fanout plan`):e.length\u003e1\u0026\u0026Jtt(a,\"duplicate-plan\",`Connection ${t.name} has ${e.length} fanout plans`,e[0])}for(const t of o)e.connections.some(e=\u003ee.name===t.connectionName)?Qtt({plan:t,preparedBus:l.get(t.busId),inputSrj:e,outputSrj:n,sharedBoundary:r,issues:a}):Jtt(a,\"unknown-plan\",`Plan ${t.connectionName} is not an input connection`,t);const d=function(t){const{plans:e,inputSrj:n,sharedBoundary:o,issues:i}=t,r=new Set,s=new Map;for(const t of e)s.set(t,[]);for(let t=0;t\u003ce.length;t++){const i=e[t];(\"plane\"===i.termination.type?Boolean(i.via):i.segments.some(t=\u003eZtt(t.start,o)||Ztt(t.end,o)))\u0026\u0026r.add(i);for(let o=t+1;o\u003ce.length;o++){const t=e[o];$8(n,i.connectionName,t.connectionName)\u0026\u0026tet(i,t)\u0026\u0026(s.get(i).push(t),s.get(t).push(i))}}const a=[...r];for(;a.length\u003e0;){const t=a.shift();for(const e of s.get(t)??[])r.has(e)||(r.add(e),a.push(e))}for(const t of e)r.has(t)||Jtt(i,\"not-broken-out\",\"boundary\"===t.termination.type?`Connection ${t.connectionName} has no continuous same-net copper path to the shared boundary`:`Plane connection ${t.connectionName} has no terminating via`,t);return r}({plans:o,inputSrj:e,sharedBoundary:r,issues:a});return function(t){const{plans:e,inputSrj:n,clearance:o,issues:i}=t;for(const t of e){const e=Htt(t);for(let r=0;r\u003ce.length;r++){const s=e[r];for(const e of n.obstacles){if(!e.layers.includes(s.layer))continue;if(Y8(n,e,t.connectionName))continue;if(0===r\u0026\u0026e.obstacleId===t.sourceObstacle.obstacleId\u0026\u0026s.layer===t.sourceLayer)continue;if(K8({inputSrj:n,segment:s,bodyObstacle:e,connectionName:t.connectionName}))continue;const a=A8(s,e),c=s.width/2+o;a\u003cc-1e-9\u0026\u0026Jtt(i,\"obstacle-clearance\",`Trace ${t.connectionName} on ${s.layer} is ${a.toFixed(4)}mm from different-net obstacle ${e.obstacleId}; ${c.toFixed(4)}mm is required`,t)}}for(const e of Gtt(t))for(const r of n.obstacles){if(!r.layers.some(t=\u003ee.spanLayers.includes(t))||Y8(n,r,t.connectionName))continue;const s=E8(e.center,r),a=e.diameter/2+o;s\u003ca-1e-9\u0026\u0026Jtt(i,\"via-obstacle-clearance\",`Via ${t.connectionName} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId} on its layer span; ${a.toFixed(4)}mm is required`,t)}}for(let t=0;t\u003ce.length;t++){const r=e[t];for(let s=t+1;s\u003ce.length;s++){const t=e[s];if($8(n,r.connectionName,t.connectionName))continue;const a=Htt(r),c=Htt(t),l=Gtt(r),d=Gtt(t);for(const e of a){for(const n of c)O8(e,n,o)||Jtt(i,\"different-net-trace-clearance\",`Different-net traces ${r.connectionName} and ${t.connectionName} intersect or violate clearance on ${e.layer}`,r,t.connectionName);for(const n of d)n.spanLayers.includes(e.layer)\u0026\u0026N8(n.center,e.start,e.end)\u003cn.diameter/2+e.width/2+o-1e-9\u0026\u0026Jtt(i,\"different-net-trace-via-clearance\",`Trace ${r.connectionName} violates via clearance to ${t.connectionName} on ${e.layer}`,r,t.connectionName)}for(const e of l){for(const n of c)e.spanLayers.includes(n.layer)\u0026\u0026N8(e.center,n.start,n.end)\u003ce.diameter/2+n.width/2+o-1e-9\u0026\u0026Jtt(i,\"different-net-trace-via-clearance\",`Via ${r.connectionName} violates trace clearance to ${t.connectionName} on ${n.layer}`,r,t.connectionName);for(const n of d)e.spanLayers.some(t=\u003en.spanLayers.includes(t))\u0026\u0026M8(e.center,n.center)\u003c(e.diameter+n.diameter)/2+o-1e-9\u0026\u0026Jtt(i,\"different-net-via-clearance\",`Vias ${r.connectionName} and ${t.connectionName} violate clearance on an overlapping layer span`,r,t.connectionName)}}}}({plans:o,inputSrj:e,clearance:s,issues:a}),{valid:0===a.length,checkedConnectionCount:e.connections.length,brokenOutConnectionCount:new Set([...d].map(t=\u003et.connectionName)).size,issues:a}}var net=[\"#ef4444\",\"#2563eb\",\"#16a34a\",\"#9333ea\",\"#f59e0b\",\"#0891b2\",\"#db2777\",\"#65a30d\",\"#4f46e5\",\"#ea580c\"];function oet(t){if(!Number.isInteger(t)||t\u003c0)throw new Error(`FanoutSolver: copper layer index must be a non-negative integer, received ${t}`);return net[t%net.length]}var iet=new Set([\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\",\"inner7\",\"inner8\"]),ret={\"0603\":{padLength:.8,padWidth:.95},1206:{padLength:.6,padWidth:1.6},\"1206x4_pair\":{padLength:.8,padWidth:.5}},set=(t,e)=\u003e{const n=t.indexOf(e);if(n\u003c0)throw new Error(`FanoutSolver: cannot visualize unknown copper layer \"${e}\"`);return n},aet=(t,e)=\u003e`z${[...new Set(e.map(e=\u003eset(t,e)))].sort((t,e)=\u003et-e).join(\",\")}`,cet=t=\u003e{const e=\"layers\"in t?t.layers:void 0;return e\u0026\u0026e.length\u003e0?e:[t.layer]},det=(t,e)=\u003et.__zLayers\u0026\u0026t.__zLayers.length\u003e0?[...new Set(t.__zLayers)].filter(t=\u003eNumber.isInteger(t)\u0026\u0026t\u003e=0\u0026\u0026t\u003ce.length).sort((t,e)=\u003et-e):[...new Set(t.layers.map(t=\u003eset(e,t)))].sort((t,e)=\u003et-e),het=(t,e,n)=\u003e{const o=set(t,e),i=set(t,n);return t.slice(Math.min(o,i),Math.max(o,i)+1)},uet=(...t)=\u003et.find(t=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)),pet=t=\u003e{const e=uet(t.min_via_hole_diameter,t.minViaHoleDiameter),n=uet(t.min_via_pad_diameter,t.minViaPadDiameter,t.minViaDiameter);return Math.max(n??t.minViaDiameter??.3,e??0)},met=(t,e)=\u003e{let n={blue:[0,0,255],orange:[255,165,0],purple:[128,0,128],red:[255,0,0]}[t],o=1;const i=/^rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)$/.exec(t);i\u0026\u0026(n=[Number(i[1]),Number(i[2]),Number(i[3])],o=void 0===i[4]?1:Number(i[4]));const r=/^hsl\\(\\s*([\\d.-]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%\\s*\\)$/.exec(t);if(r\u0026\u0026(n=((t,e,n)=\u003e{const o=(1-Math.abs(2*n-1))*e,i=(t%360+360)%360/60,r=o*(1-Math.abs(i%2-1)),[s,a,c]=i\u003c1?[o,r,0]:i\u003c2?[r,o,0]:i\u003c3?[0,o,r]:i\u003c4?[0,r,o]:i\u003c5?[r,0,o]:[o,0,r],l=n-o/2;return[s,a,c].map(t=\u003eMath.round(255*(t+l)))})(Number(r[1]),Number(r[2])/100,Number(r[3])/100)),!n)return t;const s=+Math.max(0,100*o-100*e).toFixed(2)/100;if(s\u003e=1){const t=n.map(t=\u003eMath.round(t).toString(16).padStart(2,\"0\")).join(\"\");return t[0]===t[1]\u0026\u0026t[2]===t[3]\u0026\u0026t[4]===t[5]?`#${t[0]}${t[2]}${t[4]}`:`#${t}`}return`rgba(${n.join(\",\")},${s})`},get=t=\u003e{const e=new Map,n=(t,n)=\u003e{if(!t)return;const o=e.get(t)??[];o.includes(n)||o.push(n),e.set(t,o)};for(const e of t.connections){const t=e.__rootConnectionNames??[e.name];for(const o of t){n(e.name,o),n(o,o),n(e.__netConnectionName,o);for(const t of e.pointsToConnect)n(t.pointId,o),n(t.pcb_port_id,o)}}return t=\u003e{const n=(t=\u003e{const e=new Set;return t.filter(t=\u003e!e.has(t)\u0026\u0026(e.add(t),!0))})([...t.connectedTo.flatMap(t=\u003ee.get(t)??[]),...(t.offBoardConnectsTo??[]).flatMap(t=\u003ee.get(t)??[])]).join(\", \");return t.layers.map(t=\u003en?`${t}\\n${n}`:t).join(\"\\n\")}};function fet(t){const e=k8(t.layerCount),n=(t.traces??[]).some(t=\u003et.route.some((e,n)=\u003e{const o=t.route[n+1];return\"wire\"===e.route_type\u0026\u0026\"wire\"===o?.route_type\u0026\u0026o.layer===e.layer\u0026\u0026!iet.has(e.layer)})),o=new Set(t.connections.map(({name:t})=\u003et)),i=n?[...new Set((t.traces??[]).map(({connection_name:t})=\u003et).filter(t=\u003et\u0026\u0026!o.has(t)))].map(t=\u003e({name:t,pointsToConnect:[]})):[],r=[...t.connections,...i],s=(a=r,Object.fromEntries(a.map((t,e)=\u003e[t.name,`hsl(${340*e/a.length}, 100%, 50%)`])));var a;const c=get({...t,connections:r}),l=[],d=[],h=[],u=[];for(const t of r)for(const n of t.pointsToConnect){const o=cet(n),i=t.__rootConnectionNames??[t.name];u.push({x:n.x,y:n.y,color:s[t.name],layer:aet(e,o),label:[t.name,i.join(\", \"),o.join(\",\")].join(\"\\n\")})}for(const o of t.traces??[]){const i=o.route.filter(t=\u003e\"jumper\"===t.route_type),r=(t,e)=\u003ei.some(n=\u003e{const o=.01;return Math.abs(t.x-n.start.x)\u003co\u0026\u0026Math.abs(t.y-n.start.y)\u003co\u0026\u0026Math.abs(e.x-n.end.x)\u003co\u0026\u0026Math.abs(e.y-n.end.y)\u003co||Math.abs(t.x-n.end.x)\u003co\u0026\u0026Math.abs(t.y-n.end.y)\u003co\u0026\u0026Math.abs(e.x-n.start.x)\u003co\u0026\u0026Math.abs(e.y-n.start.y)\u003co});for(const i of o.route)if(\"via\"===i.route_type){const r=het(e,i.from_layer,i.to_layer);d.push({center:{x:i.x,y:i.y},radius:(i.via_diameter??pet(t))/2,fill:n?s[o.connection_name]:\"blue\",stroke:\"none\",layer:aet(e,r)})}else\"through_obstacle\"===i.route_type\u0026\u0026l.push({points:[i.start,i.end],strokeColor:met(s[o.connection_name]??\"purple\",.35),strokeWidth:i.width,strokeDash:[.1,.1],layer:aet(e,[i.from_layer,i.to_layer]),label:`${o.connection_name} through_obstacle`});for(let t=0;t\u003co.route.length-1;t++){const i=o.route[t],a=o.route[t+1];if(\"jumper\"===i.route_type){const t=s[o.connection_name]??\"rgba(255, 165, 0, 0.8)\",n=ret[\"1206x4_pair\"===i.footprint?\"1206x4_pair\":\"0603\"],r=Math.abs(i.end.x-i.start.x)\u003eMath.abs(i.end.y-i.start.y),a=r?n.padLength:n.padWidth,c=r?n.padWidth:n.padLength,d=aet(e,[i.layer]);for(const e of[i.start,i.end])h.push({center:e,width:a,height:c,fill:met(t,.5),stroke:\"rgba(0, 0, 0, 0.5)\",layer:d});l.push({points:[i.start,i.end],strokeColor:\"rgba(100, 100, 100, 0.8)\",strokeWidth:.3*n.padWidth,layer:d})}else if(\"wire\"===i.route_type\u0026\u0026\"wire\"===a.route_type\u0026\u0026a.layer===i.layer\u0026\u0026!r(i,a)){const t=set(e,i.layer);l.push({points:[{x:i.x,y:i.y},{x:a.x,y:a.y}],layer:`z${t}`,strokeWidth:i.width,strokeColor:oet(t),...n?{label:o.connection_name}:{}})}}}for(const n of t.obstacles){if(n.isCopperPour)continue;const t=det(n,e);if(0===t.length)throw new Error(`FanoutSolver: cannot visualize obstacle \"${n.obstacleId??\"unknown\"}\" without a valid layer`);const o=1===t.length?e[t[0]]:void 0,i=met(\"bottom\"===o?\"blue\":\"red\",.5**t.length),r=n.shape,s={center:n.center,fill:i,layer:`z${t.join(\",\")}`,label:c(n)};\"circle\"===r?d.push({...s,radius:Math.min(n.width,n.height)/2}):h.push({...s,width:n.width,height:n.height,ccwRotationDegrees:n.ccwRotationDegrees})}for(const n of t.jumpers??[])for(const t of n.pads)h.push({center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.3)\",stroke:\"rgba(255, 165, 0, 0.8)\",layer:aet(e,t.layers)});return{rects:h,circles:d,lines:l,points:u}}function yet(t,e){if(!Number.isFinite(e)||e\u003c=0)throw new Error(`FanoutSolver: ${t} must be a positive number, received ${e}`);return e}function _et(t,e,n){const o=new Map(e.map(t=\u003e[t.busId,t.connections.length])),i=new Map;for(const[e,r]of Object.entries(t))i.set(r,(i.get(r)??0)+(n?o.get(e)??1:1));return[...i.values()].reduce((t,e)=\u003et+e*e,0)}function bet(t){return t.balanceLayerLoadByConnectionCount?.25:.01}function xet(t){return t.reduce((t,e)=\u003et+Number(Boolean(e.via))+Number(Boolean(e.planeEndpointVia)),0)}function vet(t){const e=t.connections.reduce((e,n)=\u003ee+(\"left\"===t.direction||\"right\"===t.direction?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length;switch(t.direction){case\"right\":return t.sharedBoundary.maxX-e;case\"left\":return e-t.sharedBoundary.minX;case\"up\":return t.sharedBoundary.maxY-e;case\"down\":return e-t.sharedBoundary.minY}}function Iet(t){const e=\"left\"===t.direction||\"right\"===t.direction;return t.connections.some(t=\u003e{const n=t.exitTargetPoint??t.targetPoint,o=e?t.sourcePoint.y:t.sourcePoint.x,i=e?n.y:n.x;return Math.abs(o-i)\u003e1e-6})}function Cet(t){const e=\"left\"===t.direction||\"right\"===t.direction,n=e?t.xCoordinates:t.yCoordinates,o=t.connections.reduce((t,n)=\u003et+(e?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length,i=\"right\"===t.direction||\"up\"===t.direction?Math.max(...n):Math.min(...n);return Math.abs(o-i)\u003c1e-6}function Pet(t){const e=\"left\"===t.direction||\"right\"===t.direction,n=e?t.xCoordinates:t.yCoordinates,o=t.connections.reduce((t,n)=\u003et+(e?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length,i=\"right\"===t.direction||\"up\"===t.direction?Math.max(...n):Math.min(...n),r=e?t.pitchX:t.pitchY;return Math.round(Math.abs(o-i)/r)}function Met(t){const{buses:e,escapeLayers:n,escapeLayersByBusId:o}=t,i={},r=new Map;let s=0;for(const t of e){const e=r.get(t.componentId)??new Set;e.add(t.direction),r.set(t.componentId,e)}for(const t of e){const e=t.connections[0]?.sourceLayer;if(!e)throw new Error(`FanoutSolver: bus \"${t.busId}\" has no connections`);if(\"plane\"===t.termination.type){i[t.busId]=t.termination.layer;continue}const a=o[t.busId]??n,c=a.filter(t=\u003et!==e);if(a.includes(e)\u0026\u0026(Iet(t)||Cet(t)))i[t.busId]=e;else if(c.length\u003e0){const e=r.get(t.componentId);if(e.has(\"left\")\u0026\u0026e.has(\"right\")||e.has(\"up\")\u0026\u0026e.has(\"down\")){const e=Pet(t);i[t.busId]=c[Math.max(e-1,0)%c.length]}else i[t.busId]=c[s%c.length],s++}else i[t.busId]=e}return i}function Net(t){const{bus:e,srj:n,config:o,staticClearanceCache:i}=t,r=o.escapeLayers.filter(t=\u003enull!==htt({srj:n,bus:e,targetLayer:t,acceptedPlans:[],layerNames:o.layerNames,traceWidth:o.traceWidth,viaDiameter:o.viaDiameter,viaHoleDiameter:o.viaHoleDiameter,clearance:o.clearance,compactBusTracks:o.compactBusTracks,allowSameNetMerges:o.allowSameNetMerges,staticClearanceCache:i}));return r.length\u003e0?r:o.escapeLayers}var wet=class extends b8{constructor(t,e={}){super(),this.inputSrj=t,this.options=e,this.config=function(t,e){const n=yet(\"traceWidth\",e.traceWidth??t.nominalTraceWidth??t.minTraceWidth),o=yet(\"viaDiameter\",e.viaDiameter??t.minViaPadDiameter??t.min_via_pad_diameter??t.minViaDiameter??Math.max(2*n,.3)),i=yet(\"viaHoleDiameter\",e.viaHoleDiameter??t.minViaHoleDiameter??t.min_via_hole_diameter??.5*o);if(i\u003e=o)throw new Error(`FanoutSolver: viaHoleDiameter ${i} must be smaller than viaDiameter ${o}`);const r=yet(\"clearance\",e.clearance??t.minViaEdgeToPadEdgeClearance??t.minTraceToPadEdgeClearance??t.defaultObstacleMargin??t.minTraceWidth),s=k8(t.layerCount),a=e.escapeLayers??s;for(const e of a)if(!s.includes(e))throw new Error(`FanoutSolver: escape layer \"${e}\" is not available in a ${t.layerCount}-layer SimpleRouteJson`);if(new Set(a).size!==a.length)throw new Error(\"FanoutSolver: escapeLayers contains duplicates\");const c=e.borderDistribution??\"preserve\";if(\"preserve\"!==c\u0026\u0026\"even\"!==c)throw new Error(`FanoutSolver: borderDistribution must be \"preserve\" or \"even\", received \"${c}\"`);return{traceWidth:n,viaDiameter:o,viaHoleDiameter:i,clearance:r,compactBusTracks:e.compactBusTracks??!1,allowSameNetMerges:e.allowSameNetMerges??!1,singleLayerPushAndShove:e.singleLayerPushAndShove??!1,singleLayerAdaptiveExits:e.singleLayerAdaptiveExits??!1,borderDistribution:c,layerNames:s,escapeLayers:a,maxLayerCombinations:void 0===e.maxLayerCombinations?256:yet(\"maxLayerCombinations\",e.maxLayerCombinations),balanceLayerLoadByConnectionCount:e.balanceLayerLoadByConnectionCount??!1}}(t,e),this.preparedBuses=j7(t,e);for(const t of this.preparedBuses){if(\"plane\"!==t.termination.type)continue;const e=t.termination.layer;if(!this.config.layerNames.includes(e))throw new Error(`FanoutSolver: plane-terminated bus \"${t.busId}\" targets unavailable layer \"${e}\"`);if(t.connections.some(t=\u003et.sourceLayer===e))throw new Error(`FanoutSolver: plane-terminated bus \"${t.busId}\" must target a layer below its source pad`)}const n=this.preparedBuses.filter(t=\u003e\"boundary\"===t.termination.type).map(t=\u003et.busId),o=Object.fromEntries(this.preparedBuses.flatMap(t=\u003e\"plane\"===t.termination.type?[[t.busId,t.termination.layer]]:[])),i=Object.fromEntries(this.preparedBuses.flatMap(e=\u003e\"plane\"===e.termination.type?[]:[[e.busId,Net({bus:e,srj:t,config:this.config,staticClearanceCache:this.routeStaticClearanceCache})]]));this.escapeLayersByBusId=i;const r=function(t){const{busIds:e,layers:n,layersByBusId:o,maxAssignments:i}=t;if(0===n.length)throw new Error(\"FanoutSolver: no escape layers are available\");if(!Number.isInteger(i)||i\u003c1)throw new Error(`FanoutSolver: maxLayerCombinations must be positive, received ${i}`);const r=e.map(t=\u003eo?.[t]??n),s=r.findIndex(t=\u003e0===t.length);if(s\u003e=0)throw new Error(`FanoutSolver: no escape layers are available for bus \"${e[s]}\"`);const a=r.reduce((t,e)=\u003et*e.length,1),c=Math.min(i,Number.isFinite(a)?a:i),l=[],d=new Set;function h(t){const n={};for(let o=0;o\u003ce.length;o++)n[e[o]]=r[o][t[o]];const o=JSON.stringify(n);d.has(o)||(d.add(o),l.push(n))}if(a\u003c=i){for(let t=0;t\u003cc;t++){const n=[];let o=t;for(let t=0;t\u003ce.length;t++){const e=r[t].length,i=o%e;o=Math.floor(o/e),n.push((i+t)%e)}h(n)}return l}function u(t){let e=0|t;return e=Math.imul(e^e\u003e\u003e\u003e16,569420461),e=Math.imul(e^e\u003e\u003e\u003e15,1935289751),(e^e\u003e\u003e\u003e15)\u003e\u003e\u003e0}const p=e.map((t,e)=\u003ee%r[e].length);h(p);const m=Math.max(...r.map(t=\u003et.length));for(let t=1;t\u003cm\u0026\u0026l.length\u003cc;t++)h(p.map((e,n)=\u003e(e+t)%r[n].length));for(let t=0;t\u003ce.length\u0026\u0026l.length\u003cc;t++)for(let e=1;e\u003cr[t].length\u0026\u0026l.length\u003cc;e++){const n=[...p];n[t]=(p[t]+e)%r[t].length,h(n)}for(let t=1;l.length\u003cc\u0026\u0026t\u003c20*c;t++)h(e.map((e,n)=\u003eu(2654435761*t+2246822507*n)%r[n].length));return l}({busIds:n,layers:this.config.escapeLayers,layersByBusId:i,maxAssignments:this.config.maxLayerCombinations}).map(t=\u003e({...t,...o}));this.layerAssignments=function(t){const{preferredAssignment:e,generatedAssignments:n,maxAssignments:o}=t,i=JSON.stringify(e);return[e,...n.filter(t=\u003eJSON.stringify(t)!==i)].slice(0,o)}({preferredAssignment:Met({buses:this.preparedBuses,escapeLayers:this.config.escapeLayers,escapeLayersByBusId:i}),generatedAssignments:r,maxAssignments:this.config.maxLayerCombinations}),this.MAX_ITERATIONS=this.config.maxLayerCombinations+2}inputSrj;options;preparedBuses;attempts=[];layerAssignments;config;escapeLayersByBusId;evaluatedAssignmentKeys=new Set;queuedAssignmentKeys=new Set;assignmentRepairDepthByKey=new Map;pendingRepairAssignments=[];routeStaticClearanceCache=new Map;routingPrefixCache=new Map;groupedBeamEvaluated=!1;nextAssignmentIndex=0;nextGeneratedAssignmentIndex=0;bestAttempt=null;endpointCompletion=null;getSolverName(){return\"FanoutSolver\"}completeBestAttemptEndpoints(){this.options.completeOriginalEndpoints\u0026\u0026!this.endpointCompletion\u0026\u0026this.bestAttempt\u0026\u0026(this.endpointCompletion=y7({inputSrj:this.inputSrj,fanoutSrj:this.bestAttempt.outputSrj,plans:this.bestAttempt.plans,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,effort:this.options.endpointCompletionEffort,routeDownstreamConnections:this.options.routeDownstreamConnections}))}getValidationBoundary(){if(this.options.sharedBoundary)return this.options.sharedBoundary;const t=this.preparedBuses[0]?.sharedBoundary;return t?this.preparedBuses.slice(1).reduce((t,e)=\u003e({minX:Math.min(t.minX,e.sharedBoundary.minX),maxX:Math.max(t.maxX,e.sharedBoundary.maxX),minY:Math.min(t.minY,e.sharedBoundary.minY),maxY:Math.max(t.maxY,e.sharedBoundary.maxY)}),{...t}):this.inputSrj.bounds}validateCompletePlans(t,e){return eet({inputSrj:this.inputSrj,outputSrj:e,plans:t,preparedBuses:this.preparedBuses,sharedBoundary:this.getValidationBoundary(),clearance:this.config.clearance})}evaluateAssignmentWithStrategy(t,e,n){let o=[],i=[],r=new Map;const s=1===this.config.escapeLayers.length;if(s\u0026\u0026this.config.singleLayerPushAndShove){const t={srj:this.inputSrj,buses:this.preparedBuses,traceWidth:this.config.traceWidth,clearance:this.config.clearance,borderDistribution:this.config.borderDistribution},e=Ytt(t)??(this.config.singleLayerAdaptiveExits?Mtt({...t,availableBoundaryRegions:R7(this.options.availableCornersAndSides)}):null);e?o.push(...e):i.push(...this.preparedBuses.map(t=\u003et.busId))}const a=[...this.preparedBuses].sort((t,o)=\u003eNumber(\"plane\"===o.termination.type)-Number(\"plane\"===t.termination.type)||(\"group-by-layer\"===n?(e[t.busId]??\"\").localeCompare(e[o.busId]??\"\"):0)||o.componentObstacles.length-t.componentObstacles.length||(s?vet(o)-vet(t):o.connections.length-t.connections.length||(\"deep-first\"===n?vet(o)-vet(t):vet(t)-vet(o))));let c,l=`${n}|`;for(const n of s\u0026\u0026this.config.singleLayerPushAndShove?[]:a){const s=e[n.busId];if(!s)throw new Error(`FanoutSolver: assignment ${t} has no layer for bus \"${n.busId}\"`);l+=`${n.busId.length}:${n.busId};${s.length}:${s};`;const a=this.routingPrefixCache.get(l);if(a){o=[...a.plans],i=[...a.failedBusIds],r=new Map(a.blockingBusCounts);continue}const c=new Map,d=htt({srj:this.inputSrj,bus:n,targetLayer:s,acceptedPlans:o,layerNames:this.config.layerNames,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,compactBusTracks:this.config.compactBusTracks,allowSameNetMerges:this.config.allowSameNetMerges,staticClearanceCache:this.routeStaticClearanceCache,blockingBusCounts:c});if(d)o.push(...d);else{i.push(n.busId);for(const[t,e]of c)r.set(t,(r.get(t)??0)+e)}this.routingPrefixCache.set(l,{plans:[...o],failedBusIds:[...i],blockingBusCounts:new Map(r)})}let d=S8({inputSrj:this.inputSrj,plans:o,layerNames:this.config.layerNames});const h=o.length===this.inputSrj.connections.length?this.validateCompletePlans(o,d):null;h\u0026\u0026!h.valid\u0026\u0026(c=h.issues,o=[],i=this.preparedBuses.map(t=\u003et.busId),r.clear(),d=S8({inputSrj:this.inputSrj,plans:o,layerNames:this.config.layerNames}));const u=this.preparedBuses.length-i.length,p=o.reduce((t,e)=\u003et+e.length,0),m=1e6*(this.inputSrj.connections.length-o.length)+1e5*i.length+p+.1*xet(o)+_et(e,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config);return{summary:{assignmentIndex:t,busLayerAssignments:e,routedBusCount:u,routedConnectionCount:o.length,failedBusIds:i,score:m,...c?{validationIssues:c}:{}},plans:o,blockingBusIds:[...r.entries()].toSorted(([,t],[,e])=\u003ee-t).map(([t])=\u003et),outputSrj:d}}evaluateAssignment(t,e){let n=this.evaluateAssignmentWithStrategy(t,e,\"default\");if(n.summary.routedConnectionCount===this.inputSrj.connections.length)return n;for(const o of[\"group-by-layer\",\"deep-first\"]){const i=this.evaluateAssignmentWithStrategy(t,e,o);if(i.summary.score\u003cn.summary.score\u0026\u0026(n=i),n.summary.routedConnectionCount===this.inputSrj.connections.length)return n}return n}evaluateGroupedBeam(t,e=!1){if(this.config.escapeLayers.length\u003c2)return null;if(this.preparedBuses.length\u003e56)return null;const n=this.inputSrj.connections.length;if(n\u003e64)return null;if(1!==new Set(this.preparedBuses.map(t=\u003et.componentId)).size)return null;const o=[...this.preparedBuses].sort((t,n)=\u003e{const o=\"plane\"===t.termination.type?1:this.escapeLayersByBusId[t.busId]?.length??this.config.escapeLayers.length,i=\"plane\"===n.termination.type?1:this.escapeLayersByBusId[n.busId]?.length??this.config.escapeLayers.length;return Number(\"plane\"===n.termination.type)-Number(\"plane\"===t.termination.type)||(e?t.direction.localeCompare(n.direction):0)||o-i||n.componentObstacles.length-t.componentObstacles.length||n.connections.length-t.connections.length||Pet(n)-Pet(t)||t.busId.localeCompare(n.busId)}),i=n\u003c=24,r=this.preparedBuses.some(t=\u003et.connections.length\u003e1),s=i?48:n\u003c=32?24:12,a=i\u0026\u0026!r?4:1;let c=[{assignment:{},plans:[]}];const l=t=\u003et.plans.reduce((t,e)=\u003et+e.length,0)+.1*xet(t.plans)+1e4*this.preparedBuses.reduce((e,n)=\u003e{if(\"boundary\"!==n.termination.type||!Iet(n))return e;const o=n.connections[0]?.sourceLayer;return t.assignment[n.busId]===o?e:e+n.connections.length},0)+_et(t.assignment,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config);for(const t of o){const e=[];for(const n of c){const o=\"plane\"===t.termination.type?[t.termination.layer]:this.escapeLayersByBusId[t.busId]??this.config.escapeLayers,i=new Map;for(const[t,e]of Object.entries(n.assignment)){const n=this.preparedBuses.find(e=\u003ee.busId===t);i.set(e,(i.get(e)??0)+(this.config.balanceLayerLoadByConnectionCount?n?.connections.length??1:1))}const r=t.connections[0]?.sourceLayer,s=Iet(t),c=o.toSorted((t,e)=\u003e(i.get(t)??0)-(i.get(e)??0)||(s?Number(e===r)-Number(t===r):Number(t===r)-Number(e===r))||t.localeCompare(e));for(const o of c){const i=dtt({srj:this.inputSrj,bus:t,targetLayer:o,acceptedPlans:n.plans,layerNames:this.config.layerNames,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,compactBusTracks:this.config.compactBusTracks,allowSameNetMerges:this.config.allowSameNetMerges,staticClearanceCache:this.routeStaticClearanceCache},a);for(const r of i)e.push({assignment:{...n.assignment,[t.busId]:o},plans:[...n.plans,...r]})}}if(0===e.length)return null;e.sort((t,e)=\u003e{const n=l(t)-l(e);return Math.abs(n)\u003e1e-9?n:JSON.stringify(t.assignment).localeCompare(JSON.stringify(e.assignment))});const n=new Map;c=[];for(const t of e){const e=JSON.stringify(t.assignment),o=n.get(e)??0;if(!(o\u003e=2)\u0026\u0026(n.set(e,o+1),c.push(t),c.length\u003e=s))break}}const d=c[0];if(!d)return null;const h=S8({inputSrj:this.inputSrj,plans:d.plans,layerNames:this.config.layerNames});if(d.plans.length===this.inputSrj.connections.length\u0026\u0026!this.validateCompletePlans(d.plans,h).valid)return null;const u=d.plans.length===this.inputSrj.connections.length?d.plans.reduce((t,e)=\u003et+e.length,0)+.1*xet(d.plans)+_et(d.assignment,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config):Number.POSITIVE_INFINITY;if(!Number.isFinite(u))return null;return{summary:{assignmentIndex:t,busLayerAssignments:d.assignment,routedBusCount:this.preparedBuses.length,routedConnectionCount:d.plans.length,failedBusIds:[],score:u},plans:d.plans,blockingBusIds:[],outputSrj:h}}prioritizeFailedBusRepairs(t,e,n){const o=JSON.stringify(t),i=this.assignmentRepairDepthByKey.get(o)??0;if(i\u003e=2)return;const r=[],s=new Set,a=t=\u003e{const e=JSON.stringify(t);s.has(e)||this.evaluatedAssignmentKeys.has(e)||this.queuedAssignmentKeys.has(e)||(s.add(e),this.queuedAssignmentKeys.add(e),this.assignmentRepairDepthByKey.set(e,i+1),r.push(t))},c=[];for(let t=0;t\u003cMath.max(e.length,n.length);t++){const o=e[t],i=n[t];o\u0026\u0026!c.includes(o)\u0026\u0026c.push(o),i\u0026\u0026!c.includes(i)\u0026\u0026c.push(i)}for(const o of e){const e=t[o],i=this.escapeLayersByBusId[o];if(e\u0026\u0026i){for(const s of n.slice(0,4)){const n=t[s],c=this.escapeLayersByBusId[s];if(n\u0026\u0026c\u0026\u0026i.includes(n)\u0026\u0026c.includes(e)\u0026\u0026(a({...t,[o]:n,[s]:e}),r.length\u003e=8))break}if(r.length\u003e=8)break}}for(const e of c){const n=t[e],o=this.escapeLayersByBusId[e];if(!n||!o)continue;const i=o.indexOf(n);for(let s=1;s\u003co.length;s++){const c=o[(Math.max(i,0)+s)%o.length];if(c!==n\u0026\u0026(a({...t,[e]:c}),r.length\u003e=8))break}if(r.length\u003e=8)break}this.pendingRepairAssignments.push(...r)}hasCompleteBestAttempt(){return this.bestAttempt?.summary.routedConnectionCount===this.inputSrj.connections.length}shouldEvaluateGroupedBeam(){if(this.groupedBeamEvaluated||0===this.nextAssignmentIndex)return!1;return this.hasCompleteBestAttempt()||0===this.pendingRepairAssignments.length||this.nextAssignmentIndex\u003e=this.config.maxLayerCombinations}_step(){if(this.shouldEvaluateGroupedBeam()){this.groupedBeamEvaluated=!0;let t=this.evaluateGroupedBeam(-1);if(t||(t=this.evaluateGroupedBeam(-1,!0)),t){this.attempts.push(t.summary),(!this.bestAttempt||t.summary.score\u003cthis.bestAttempt.summary.score)\u0026\u0026(this.bestAttempt=t);const e=this.bestAttempt.summary;return this.stats={assignment:e.assignmentIndex\u003c0?0:e.assignmentIndex+1,assignmentCount:this.config.maxLayerCombinations,routedBuses:`${e.routedBusCount}/${this.preparedBuses.length}`,routedConnections:`${e.routedConnectionCount}/${this.inputSrj.connections.length}`,failedBuses:\"none\",bestScore:e.score},this.completeBestAttemptEndpoints(),void(this.solved=!0)}if(this.hasCompleteBestAttempt())return this.completeBestAttemptEndpoints(),void(this.solved=!0)}let t;for(;!t\u0026\u0026this.nextAssignmentIndex\u003cthis.config.maxLayerCombinations;){const e=this.nextAssignmentIndex%3==0;let n,o=!1;if(!this.groupedBeamEvaluated\u0026\u0026this.nextAssignmentIndex\u003e0?(n=this.pendingRepairAssignments.pop(),o=void 0!==n):e?n=this.layerAssignments[this.nextGeneratedAssignmentIndex++]:(n=this.pendingRepairAssignments.pop(),o=void 0!==n),n||!this.groupedBeamEvaluated\u0026\u00260!==this.nextAssignmentIndex||(n=e?this.pendingRepairAssignments.pop():this.layerAssignments[this.nextGeneratedAssignmentIndex++],o=e\u0026\u0026void 0!==n),!n)break;const i=JSON.stringify(n);o\u0026\u0026this.queuedAssignmentKeys.delete(i),this.evaluatedAssignmentKeys.has(i)||(t=n)}if(!t\u0026\u0026!this.groupedBeamEvaluated)return;if(!t)return void(this.hasCompleteBestAttempt()?(this.completeBestAttemptEndpoints(),this.solved=!0):(this.failed=!0,this.error=this.bestAttempt?`FanoutSolver: best layer assignment routed ${this.bestAttempt.summary.routedConnectionCount}/${this.inputSrj.connections.length} connections`:\"FanoutSolver: no layer assignment could be evaluated\"));const e=this.evaluateAssignment(this.nextAssignmentIndex,t);this.nextAssignmentIndex++,this.evaluatedAssignmentKeys.add(JSON.stringify(t)),(!this.bestAttempt||e.summary.routedConnectionCount\u003e=this.bestAttempt.summary.routedConnectionCount)\u0026\u0026this.prioritizeFailedBusRepairs(t,e.summary.failedBusIds,e.blockingBusIds),this.attempts.push(e.summary),(!this.bestAttempt||e.summary.score\u003cthis.bestAttempt.summary.score)\u0026\u0026(this.bestAttempt=e),this.stats={assignment:e.summary.assignmentIndex+1,assignmentCount:this.config.maxLayerCombinations,routedBuses:`${e.summary.routedBusCount}/${this.preparedBuses.length}`,routedConnections:`${e.summary.routedConnectionCount}/${this.inputSrj.connections.length}`,failedBuses:e.summary.failedBusIds.join(\", \")||\"none\",bestScore:this.bestAttempt.summary.score},this.groupedBeamEvaluated\u0026\u0026e.summary.routedConnectionCount===this.inputSrj.connections.length\u0026\u0026(this.completeBestAttemptEndpoints(),this.solved=!0)}computeProgress(){return this.solved||this.failed?1:this.nextAssignmentIndex/this.config.maxLayerCombinations}getConstructorParams(){return[this.inputSrj,this.options]}getOutput(){if(!this.solved||!this.bestAttempt)throw new Error(\"FanoutSolver: getOutput() called before a complete fanout was solved\");const t=this.validateCompletePlans(this.bestAttempt.plans,this.bestAttempt.outputSrj);if(!t.valid)throw new Error(`FanoutSolver: completed output failed validation: ${t.issues[0]?.message??\"unknown validation error\"}`);const e=this.endpointCompletion?.simpleRouteJson??this.bestAttempt.outputSrj,n=new Map((e.traces??[]).map(t=\u003e[t.pcb_trace_id,t]));return{simpleRouteJson:this.endpointCompletion?.simpleRouteJson??this.bestAttempt.outputSrj,fanoutTraces:this.bestAttempt.plans.flatMap(t=\u003e[n.get(t.trace.pcb_trace_id)??t.trace,...t.planeEndpointTrace?[n.get(t.planeEndpointTrace.pcb_trace_id)??t.planeEndpointTrace]:[]]),completionTraces:this.endpointCompletion?.traces??[],...this.endpointCompletion?{endpointCompletion:this.endpointCompletion.report}:{},planeTerminations:this.bestAttempt.plans.flatMap(t=\u003e\"plane\"===t.termination.type\u0026\u0026t.via?[{busId:t.busId,connectionName:t.connectionName,layer:t.termination.layer,via:t.via}]:[]),busLayerAssignments:this.bestAttempt.summary.busLayerAssignments,busDirections:Object.fromEntries(this.preparedBuses.map(t=\u003e[t.busId,t.direction])),attempts:[...this.attempts],validation:t}}getOutputSimpleRouteJson(){return this.getOutput().simpleRouteJson}visualize(){return fet(this.endpointCompletion?.simpleRouteJson??this.bestAttempt?.outputSrj??this.inputSrj)}};function Tet(t){const{minX:e,maxX:n}=t.bounds,o=(e+n)/2;if(!Number.isFinite(o))throw new Error(`Detected component ${t.componentId} has bad bounds`);return o}function Ret(t){const{minY:e,maxY:n}=t.bounds,o=(e+n)/2;if(!Number.isFinite(o))throw new Error(`Detected component ${t.componentId} has bad bounds`);return o}function Eet(t,e){const n=(function(t,e){const[n,o]=Tet(t)\u003cTet(e)?[t,e]:[e,t];return o.bounds.minX-n.bounds.maxX}(t,e)-2)/2;return Math.min(4.5,n)}function Aet(t,e){const n=e.filter(t=\u003e\"bga\"===t.componentKind).map(e=\u003efunction(t,e){const n=t.obstacles.filter(t=\u003et.componentId===e.componentId);if(0===n.length)throw new Error(`Detected component ${e.componentId} has no physical obstacles`);return{...e,bounds:{__type:\"rect\",minX:Math.min(...n.map(t=\u003et.center.x-t.width/2)),maxX:Math.max(...n.map(t=\u003et.center.x+t.width/2)),minY:Math.min(...n.map(t=\u003et.center.y-t.height/2)),maxY:Math.max(...n.map(t=\u003et.center.y+t.height/2))}}}(t,e)).toSorted((t,e)=\u003eTet(t)-Tet(e));if(2!==n.length)throw new Error(`Pipeline 10 requires exactly two detected BGAs; found ${n.map(t=\u003et.componentId).join(\", \")||\"none\"}`);const[o,i]=n;if(o.componentId===i.componentId)throw new Error(\"Pipeline 10 requires two distinct BGA component IDs\");if(Eet(o,i)\u003c2)throw new Error(\"Pipeline 10 cannot provide 2mm fanout margins while retaining a 2mm routing corridor\");return{first:o,second:i}}function Oet(t,e){const{minX:n,maxX:o,minY:i,maxY:r}=t.bounds;return{minX:n-e,maxX:o+e,minY:i-e,maxY:r+e}}function ket(t){const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds;return{minX:e,maxX:n,minY:o,maxY:i}}function Let({inputSrj:t,source:e,target:n}){const o=Eet(e,n),i=Oet(e,o),r=Tet(n)\u003eTet(e)?\"right\":\"left\",s=\"right\"===r?\"left\":\"right\";return t.connections.map((t,n)=\u003e{const a=t.pointsToConnect.filter(t=\u003et.x\u003e=e.bounds.minX\u0026\u0026t.x\u003c=e.bounds.maxX\u0026\u0026t.y\u003e=e.bounds.minY\u0026\u0026t.y\u003c=e.bounds.maxY);if(1!==a.length)throw new Error(`Connection ${t.name} must touch ${e.componentId} exactly once before fanout`);const c=a[0],l=\"right\"===r?i.maxX-c.x:c.x-i.minX,d=[{direction:\"up\",distance:i.maxY-c.y},{direction:\"down\",distance:c.y-i.minY},{direction:s,distance:\"right\"===s?i.maxX-c.x:c.x-i.minX}].toSorted((t,e)=\u003et.distance-e.distance)[0].direction,h=l\u003c=o+1.2?r:d;let u=\"up\"===h?\"top\":\"down\"===h?\"bottom\":h;return\"up\"===h?u=c.x\u003cTet(e)?\"top-left\":\"top-right\":\"down\"===h?u=c.x\u003cTet(e)?\"bottom-left\":\"bottom-right\":c.y\u003eRet(e)+1e-6?u=\"right\"===h?\"top-right\":\"top-left\":c.y\u003cRet(e)-1e-6\u0026\u0026(u=\"right\"===h?\"bottom-right\":\"bottom-left\"),{busId:`pipeline10_fanout:${e.componentId}:${n}`,connectionNames:[t.name],sourceComponentId:e.componentId,direction:h,preferredExit:u,termination:{type:\"boundary\"}}})}function Det({inputSrj:t,source:e,target:n}){const o=Eet(e,n);return{buses:Let({inputSrj:t,source:e,target:n}),sourceComponentId:e.componentId,availableCornersAndSides:[\"top_left\",\"top_middle\",\"top_right\",\"right_top\",\"right_middle\",\"right_bottom\",\"bottom_right\",\"bottom_middle\",\"bottom_left\",\"left_bottom\",\"left_middle\",\"left_top\"],componentBounds:{[e.componentId]:ket(e)},sharedBoundary:Oet(e,o),maxLayerCombinations:256,balanceLayerLoadByConnectionCount:!0,compactBusTracks:!0,borderDistribution:\"even\"}}var zet=class extends kt{constructor(t){super(),this.inputProblem=t,this.fanoutSolver=new wet(t.inputSrj,t.options),this.activeSubSolver=this.fanoutSolver,this.MAX_ITERATIONS=this.fanoutSolver.MAX_ITERATIONS+1}inputProblem;fanoutSolver;_step(){if(this.fanoutSolver.step(),this.progress=this.fanoutSolver.progress,this.stats={...this.fanoutSolver.stats},this.fanoutSolver.failed)return this.error=this.fanoutSolver.error??\"Fanout solver failed\",this.failed=!0,void(this.activeSubSolver=null);this.fanoutSolver.solved\u0026\u0026(this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.fanoutSolver.getOutput()}getOutputSimpleRouteJson(){return this.fanoutSolver.getOutputSimpleRouteJson()}visualize(){return this.fanoutSolver.visualize()}preview(){return this.fanoutSolver.preview()}},Fet=class extends kt{constructor(t){super(),this.inputProblem=t,this.autoroutingPipelineSolver=new H9(t.inputSrj,t.options),this.activeSubSolver=this.autoroutingPipelineSolver,this.MAX_ITERATIONS=this.autoroutingPipelineSolver.MAX_ITERATIONS+1}inputProblem;autoroutingPipelineSolver;_step(){if(this.autoroutingPipelineSolver.step(),this.progress=this.autoroutingPipelineSolver.progress,this.stats={...this.autoroutingPipelineSolver.stats},this.autoroutingPipelineSolver.failed)return this.error=this.autoroutingPipelineSolver.error??\"Autorouting pipeline failed\",this.failed=!0,void(this.activeSubSolver=null);this.autoroutingPipelineSolver.solved\u0026\u0026(this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.autoroutingPipelineSolver.getOutputSimpleRouteJson()}visualize(){return this.autoroutingPipelineSolver.visualize()}preview(){return this.autoroutingPipelineSolver.preview()}},Bet=class extends Dt{componentDetectionSolver;firstBgaFanoutSolver;secondBgaFanoutSolver;autoroutingPipelineSolver;get currentPipelineStepIndex(){return this.currentPipelineStageIndex}get startTimeOfPhase(){return this.startTimeOfStage}get timeSpentOnPhase(){return this.timeSpentOnStage}pipelineDef=[Lt(\"componentDetectionSolver\",UZ,t=\u003e[{inputSrj:t.inputProblem.inputSrj}]),Lt(\"firstBgaFanoutSolver\",zet,t=\u003e{const e=Aet(t.inputProblem.inputSrj,t.componentDetectionSolver.getOutput());return[{inputSrj:t.inputProblem.inputSrj,options:Det({inputSrj:t.inputProblem.inputSrj,source:e.first,target:e.second})}]}),Lt(\"secondBgaFanoutSolver\",zet,t=\u003e{const e=Aet(t.inputProblem.inputSrj,t.componentDetectionSolver.getOutput()),n=t.firstBgaFanoutSolver.getOutputSimpleRouteJson();return[{inputSrj:n,options:Det({inputSrj:n,source:e.second,target:e.first})}]}),Lt(\"autoroutingPipelineSolver\",Fet,t=\u003e[{inputSrj:t.secondBgaFanoutSolver.getOutputSimpleRouteJson(),options:t.inputProblem.options}])];constructor(t,e={}){super({inputSrj:t,options:e}),this.MAX_ITERATIONS=1e8*(e.effort??1)+1024}getSolverName(){return\"AutoroutingPipelineSolver10_BgaFanout\"}getConstructorParams(){return[this.inputProblem.inputSrj,this.inputProblem.options]}getOutput(){if(!this.autoroutingPipelineSolver?.solved)throw new Error(\"Pipeline 10 has not solved yet\");return this.autoroutingPipelineSolver.getOutput()}getOutputSimpleRouteJson(){return this.getOutput()}getOutputSimplifiedPcbTraces(){return this.getOutput().traces??[]}get srjWithPointPairs(){return this.autoroutingPipelineSolver?.autoroutingPipelineSolver.srjWithPointPairs}initialVisualize(){return Ho(this.inputProblem.inputSrj)}finalVisualize(){return Ho(this.getOutput())}},jet=class extends kt{constructor(t){super(),this.inputProblem=t,this.simplifiedRouteByTraceId=new Map(t.simplifiedHdRoutes.map(t=\u003e[t.connectionName,t])),this.MAX_ITERATIONS=t.preparedInput.preparedTraces.length+1}inputProblem;simplifiedRouteByTraceId;outputTraces=[];nextTraceIndex=0;getSolverName(){return\"ApplyTraceSimplificationSolver\"}_step(){const t=this.inputProblem.preparedInput.preparedTraces,e=t[this.nextTraceIndex];e?(this.outputTraces.push(this.applyTrace(e)),this.nextTraceIndex++,this.progress=this.nextTraceIndex/Math.max(1,t.length)):this.finishApplication()}applyTrace(t){if(!t.mutableHdRoute)return structuredClone(t.originalTrace);const e=this.simplifiedRouteByTraceId.get(t.originalTrace.pcb_trace_id);if(!e||void 0===t.uniformTraceWidth)throw new Error(`Simplification removed trace \"${t.originalTrace.pcb_trace_id}\"`);const n=Mo(e,this.inputProblem.preparedInput.srj.layerCount,{defaultViaHoleDiameter:t.viaHoleDiameter,obstacles:this.inputProblem.preparedInput.srj.obstacles,connMap:this.inputProblem.preparedInput.connMap}),o=n.filter(t=\u003e\"jumper\"===t.route_type),i=((t,e)=\u003et.map(t=\u003e\"wire\"===t.route_type||\"through_obstacle\"===t.route_type?{...t,width:e}:t))([...structuredClone(t.leadingTerminalVias),...n.filter(t=\u003e\"jumper\"!==t.route_type),...structuredClone(t.trailingTerminalVias),...o],t.uniformTraceWidth);return((t,e)=\u003e{const n=t.filter(t=\u003e\"wire\"===t.route_type);e.startPcbPortId\u0026\u0026n[0]\u0026\u0026(n[0].start_pcb_port_id=e.startPcbPortId),e.endPcbPortId\u0026\u0026n.at(-1)\u0026\u0026(n.at(-1).end_pcb_port_id=e.endPcbPortId)})(i,e),{...structuredClone(t.originalTrace),route:i}}finishApplication(){const t=this.inputProblem.preparedInput.preparedTraces;this.stats={inputTraceCount:t.length,outputTraceCount:this.outputTraces.length,inputRoutePointCount:t.reduce((t,e)=\u003et+e.originalTrace.route.length,0),outputRoutePointCount:this.outputTraces.reduce((t,e)=\u003et+e.route.length,0)},this.progress=1,this.solved=!0}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error(\"Cannot get applied traces before conversion completes\");return{...structuredClone(this.inputProblem.preparedInput.originalSrj),traces:structuredClone(this.outputTraces)}}},$et=(t,e)=\u003e{const n=t.at(-1);if(n\u0026\u0026(o=n,i=e,Math.abs(o.x-i.x)\u003c=1e-9\u0026\u0026Math.abs(o.y-i.y)\u003c=1e-9\u0026\u0026o.z===i.z))return void 0!==e.traceThickness\u0026\u0026(n.traceThickness=e.traceThickness),void(void 0!==e.pcb_port_id\u0026\u0026(n.pcb_port_id=e.pcb_port_id));var o,i;t.push(e)},Yet=(t,e,n)=\u003e{for(let o=e+1;o\u003ct.length;o++){const e=t[o];if(\"wire\"===e.route_type)return ko(e.layer,n);if(\"through_obstacle\"===e.route_type)return ko(e.from_layer,n)}},Xet=({fromZ:t,toZ:e,previousZ:n,nextZ:o})=\u003en===t?[t,e]:n===e?[e,t]:o===e?[t,e]:o===t?[e,t]:[t,e],Vet=(t,e)=\u003e{for(const e of t)if(\"via\"===e.route_type\u0026\u0026void 0!==e.via_diameter)return e.via_diameter;return e},Wet=(t,e)=\u003e{const n=\"start\"===e?t:[...t].reverse();for(const t of n){if(\"wire\"!==t.route_type)continue;const n=\"start\"===e?t.start_pcb_port_id:t.end_pcb_port_id;if(n)return n}},Het=t=\u003e({route_type:\"jumper\",start:{...t.start},end:{...t.end},footprint:t.footprint}),Get=(t,e)=\u003e{for(const e of t.route)if(\"via\"===e.route_type\u0026\u0026void 0!==e.via_hole_diameter)return e.via_hole_diameter;return e},Uet=class extends kt{preparedInput;seenTraceIds=new Set;nextTraceIndex=0;constructor(t){super();const e=structuredClone(t.inputSrj),n=fX(e),o=ii(n);this.preparedInput={originalSrj:e,srj:n,connMap:o,colorMap:wo(n,o),immutableHdRoutes:[],mutableHdRoutes:[],netByConnectionName:new Map,options:{...t.options},preparedTraces:[]},this.MAX_ITERATIONS=(n.traces?.length??0)+1}getSolverName(){return\"PrepareTraceSimplificationSolver\"}_step(){const t=this.preparedInput.srj.traces??[],e=t[this.nextTraceIndex];if(!e)return this.stats={inputTraceCount:t.length,mutableTraceCount:this.preparedInput.mutableHdRoutes.length,immutableTraceCount:t.length-this.preparedInput.mutableHdRoutes.length},this.progress=1,void(this.solved=!0);this.prepareTrace(e,this.nextTraceIndex),this.nextTraceIndex++,this.progress=this.nextTraceIndex/Math.max(1,t.length)}prepareTrace(t,e){if(this.seenTraceIds.has(t.pcb_trace_id))throw new Error(`Duplicate pcb_trace_id \"${t.pcb_trace_id}\"`);this.seenTraceIds.add(t.pcb_trace_id);const n=Yo(this.preparedInput.srj),o=(t=\u003e{const e=t.route.flatMap(t=\u003e\"wire\"===t.route_type||\"through_obstacle\"===t.route_type?[t.width]:[]),n=e[0];if(void 0!==n\u0026\u0026!e.some(t=\u003eMath.abs(t-n)\u003e1e-9))return n})(t),{traceToSimplify:i,leadingTerminalVias:r,trailingTerminalVias:s}=(t=\u003e{let e=0;for(;\"via\"===t.route[e]?.route_type;)e++;let n=t.route.length;for(;\"jumper\"===t.route[n-1]?.route_type;)n--;let o=n;for(;o\u003ee\u0026\u0026\"via\"===t.route[o-1]?.route_type;)o--;return{traceToSimplify:{...t,route:[...t.route.slice(e,o),...t.route.slice(n)]},leadingTerminalVias:t.route.slice(0,e),trailingTerminalVias:t.route.slice(o,n)}})(t),a=this.preparedInput.connMap.getNetConnectedToId(t.connection_name)??t.connection_name,c=void 0===o?void 0:((t,e)=\u003e{const n=[],o=[],i=[],r=((t,e)=\u003e{for(const e of t)if(\"wire\"===e.route_type||\"through_obstacle\"===e.route_type)return e.width;return e})(t.route,e.defaultTraceThickness);for(let s=0;s\u003ct.route.length;s++){const a=t.route[s];if(\"jumper\"===a.route_type){i.push(Het(a));continue}if(\"wire\"===a.route_type){$et(n,{x:a.x,y:a.y,z:ko(a.layer,e.layerCount),traceThickness:a.width,pcb_port_id:a.start_pcb_port_id??a.end_pcb_port_id});continue}const c=ko(a.from_layer,e.layerCount),l=ko(a.to_layer,e.layerCount),[d,h]=Xet({fromZ:c,toZ:l,previousZ:n.at(-1)?.z,nextZ:Yet(t.route,s,e.layerCount)});if(\"via\"===a.route_type){$et(n,{x:a.x,y:a.y,z:d,traceThickness:r}),$et(n,{x:a.x,y:a.y,z:h,traceThickness:r}),o.push({x:a.x,y:a.y});continue}const u=d===c,p=u?a.start:a.end,m=u?a.end:a.start;$et(n,{...p,z:d,traceThickness:a.width,toNextSegmentType:\"through_obstacle\",...a.circuitJsonMetadata?{toNextSegmentCircuitJsonMetadata:a.circuitJsonMetadata}:{}}),$et(n,{...m,z:h,traceThickness:a.width})}return{connectionName:t.pcb_trace_id,rootConnectionName:e.rootConnectionName,startPcbPortId:Wet(t.route,\"start\"),endPcbPortId:Wet(t.route,\"end\"),traceThickness:r,viaDiameter:Vet(t.route,e.defaultViaDiameter),route:n,vias:o,...i.length\u003e0?{jumpers:i}:{}}})(i,{layerCount:this.preparedInput.srj.layerCount,defaultTraceThickness:o,defaultViaDiameter:n.padDiameter,rootConnectionName:a}),l=c\u0026\u0026c.route.length\u003e=2?c:void 0;if(this.preparedInput.preparedTraces.push({originalTrace:t,mutableHdRoute:l,leadingTerminalVias:r,trailingTerminalVias:s,uniformTraceWidth:o,viaHoleDiameter:Get(t,n.holeDiameter)}),!l)return void this.preparedInput.immutableHdRoutes.push(...oQ(t,e,this.preparedInput.srj.layerCount,n.padDiameter,this.preparedInput.connMap));this.preparedInput.mutableHdRoutes.push(l),this.preparedInput.netByConnectionName.set(l.connectionName,a),this.preparedInput.colorMap[l.connectionName]=this.preparedInput.colorMap[a]??this.preparedInput.colorMap[t.connection_name]??\"#2563eb\";const d={...t,route:[...r,...s]};this.preparedInput.immutableHdRoutes.push(...oQ(d,e,this.preparedInput.srj.layerCount,n.padDiameter,this.preparedInput.connMap))}getOutput(){if(!this.solved)throw new Error(\"Cannot get prepared traces before preparation completes\");return this.preparedInput}},Zet=class extends kt{constructor(t){super(),this.inputProblem=t;const e=t.preparedInput,n=Yo(e.srj);this.traceSimplificationSolver=new vc({hdRoutes:e.mutableHdRoutes,otherHdRoutes:e.immutableHdRoutes,obstacles:e.srj.obstacles,connMap:e.connMap,colorMap:e.colorMap,outline:e.srj.outline,defaultViaDiameter:n.padDiameter,layerCount:e.srj.layerCount,minTraceToPadEdgeClearance:e.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:e.srj.minBoardEdgeClearance,netByConnectionName:e.netByConnectionName,enableCrossingViaReduction:e.options.enableCrossingViaReduction??!0,preserveRouteEndpoints:!0,useTraceWidthAwareClearance:!0,enableVertexShortcuts:e.options.enableVertexShortcuts??!0}),this.traceSimplificationSolver.MAX_SIMPLIFICATION_PIPELINE_LOOPS=e.options.iterations??2,this.activeSubSolver=this.traceSimplificationSolver,this.MAX_ITERATIONS=this.traceSimplificationSolver.MAX_ITERATIONS+1}inputProblem;traceSimplificationSolver;getSolverName(){return\"TraceSimplificationStageSolver\"}_step(){if(this.traceSimplificationSolver.step(),this.progress=this.traceSimplificationSolver.progress,this.stats={...this.traceSimplificationSolver.stats},this.traceSimplificationSolver.failed)return this.error=this.traceSimplificationSolver.error??\"Trace simplification failed\",this.failed=!0,void(this.activeSubSolver=null);this.traceSimplificationSolver.solved\u0026\u0026(this.progress=1,this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error(\"Cannot get simplified routes before cleanup completes\");return structuredClone(this.traceSimplificationSolver.simplifiedHdRoutes)}visualize(){return this.traceSimplificationSolver.visualize()}preview(){return this.traceSimplificationSolver.preview()}},qet=class extends kt{constructor(t){super(),this.inputProblem=t;const e=t.preparedInput;this.drcEngine=new s_(e.srj,{connMap:e.connMap,traceClearance:e.srj.minTraceToPadEdgeClearance??.1,viaClearance:.1}),this.MAX_ITERATIONS=3}inputProblem;drcEngine;phase=\"baseline\";baselineErrorCounts={};outputErrorCounts={};getSolverName(){return\"ValidateTraceSimplificationSolver\"}_step(){return\"baseline\"===this.phase?(this.baselineErrorCounts=this.evaluateErrorCounts(this.inputProblem.preparedInput.originalSrj),this.phase=\"output\",void(this.progress=1/3)):\"output\"===this.phase?(this.outputErrorCounts=this.evaluateErrorCounts(this.inputProblem.outputSrj),this.phase=\"compare\",void(this.progress=2/3)):(this.assertNoNewDrcErrors(),this.stats={baselineErrorCounts:this.baselineErrorCounts,outputErrorCounts:this.outputErrorCounts},this.progress=1,void(this.solved=!0))}evaluateErrorCounts(t){return(t=\u003e{const e={};for(const n of t.errors)e[n.type]=(e[n.type]??0)+1;return e})(this.drcEngine.evaluate(t.traces??[]))}assertNoNewDrcErrors(){const t=[...new Set([...Object.keys(this.baselineErrorCounts),...Object.keys(this.outputErrorCounts)])].filter(t=\u003e(this.outputErrorCounts[t]??0)\u003e(this.baselineErrorCounts[t]??0));if(0===t.length)return;const e=t.map(t=\u003e`${t}: ${this.baselineErrorCounts[t]??0} -\u003e ${this.outputErrorCounts[t]??0}`).join(\", \");throw new Error(`Pipeline 11 simplification introduced DRC errors (${e})`)}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error(\"Cannot get Pipeline 11 output before DRC validation\");return structuredClone(this.inputProblem.outputSrj)}},Jet=class extends Dt{prepareTraceSimplificationSolver;traceSimplificationStageSolver;applyTraceSimplificationSolver;validateTraceSimplificationSolver;pipelineDef=[Lt(\"prepareTraceSimplificationSolver\",Uet,t=\u003e[{inputSrj:t.inputProblem.inputSrj,options:t.inputProblem.options}]),Lt(\"traceSimplificationStageSolver\",Zet,t=\u003e[{preparedInput:t.prepareTraceSimplificationSolver.getOutput()}]),Lt(\"applyTraceSimplificationSolver\",jet,t=\u003e[{preparedInput:t.prepareTraceSimplificationSolver.getOutput(),simplifiedHdRoutes:t.traceSimplificationStageSolver.getOutput()}]),Lt(\"validateTraceSimplificationSolver\",qet,t=\u003e[{preparedInput:t.prepareTraceSimplificationSolver.getOutput(),outputSrj:t.applyTraceSimplificationSolver.getOutput()}])];constructor(t,e={}){if(void 0!==e.iterations\u0026\u0026(!Number.isInteger(e.iterations)||e.iterations\u003c1))throw new Error(\"Simplification iterations must be a positive integer\");super({inputSrj:t,options:{...e}}),this.MAX_ITERATIONS=1e8}getSolverName(){return\"AutoroutingPipelineSolver11_Simplification\"}getConstructorParams(){return[this.inputProblem.inputSrj,this.inputProblem.options]}getOutput(){if(!this.validateTraceSimplificationSolver?.solved)throw new Error(\"Pipeline 11 simplification has not solved yet\");return this.validateTraceSimplificationSolver.getOutput()}getOutputSimpleRouteJson(){return this.getOutput()}getOutputSimplifiedPcbTraces(){return structuredClone(this.getOutput().traces??[])}initialVisualize(){return Ho(this.inputProblem.inputSrj)}finalVisualize(){return Ho(this.getOutput())}},Ket=class extends kc{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e}srj;opts;MAX_SIZE_FOR_SINGLE_LAYER_NODES=2;isObstacleAssignable(t){return Boolean(t?.netIsAssignable)}getOverlappingAssignableObstacles(t){return this.getXYZOverlappingObstacles(t).filter(t=\u003ethis.isObstacleAssignable(t))}shouldNodeBeXYSubdivided(t){return!(t._depth\u003e=this.MAX_DEPTH)\u0026\u0026(!!t._containsTarget||(!(!t._containsObstacle||t._completelyInsideObstacle)||1===t.availableZ.length\u0026\u0026(t.width\u003ethis.MAX_SIZE_FOR_SINGLE_LAYER_NODES||t.height\u003ethis.MAX_SIZE_FOR_SINGLE_LAYER_NODES)))}shouldFilterNodeForObstacle(t){if(!t._containsObstacle)return!1;return!(this.getOverlappingAssignableObstacles(t).length\u003e0)\u0026\u0026(1!==t.availableZ.length||this.shouldFilterSingleLayerNodeForObstacle(t))}insertAssignableObstaclesAsNodes(){const t=this.srj.obstacles.filter(t=\u003ethis.isObstacleAssignable(t)),e=new Map;for(const n of t){const t=[];for(const e of this.finishedNodes){this.getXYZOverlappingObstacles(e).some(t=\u003et===n)\u0026\u0026t.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=\u003e!n.has(t));for(const n of t){const t=e.get(n)||[],o=n.layers\u0026\u0026n.layers.length\u003e0?Array.from(new Set(n.layers.map(t=\u003eko(t,this.srj.layerCount)))).sort((t,e)=\u003et-e):Array.from({length:this.srj.layerCount},(t,e)=\u003ethis.srj.layerCount-e-1);let i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=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,o=e.center.y-e.height/2,c=e.center.y+e.height/2;i=Math.min(i,t),r=Math.max(r,n),s=Math.min(s,o),a=Math.max(a,c)}const c=r-i,l=a-s,d=(i+r)/2,h=(s+a)/2;let u=!1;for(const t of this.srj.connections){for(const e of t.pointsToConnect)if(e.x\u003e=i\u0026\u0026e.x\u003c=r\u0026\u0026e.y\u003e=s\u0026\u0026e.y\u003c=a){u=!0;break}if(u)break}const p={capacityMeshNodeId:`assignable_via_${n.center.x}_${n.center.y}`,center:{x:d,y:h},width:c,height:l,layer:1===o.length?`z${o[0]}`:`z${o.join(\",\")}`,availableZ:o,_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=[],o=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),i=t.availableZ.length\u003e1\u0026\u0026!e;if(e)o.push(t);else{if(i){const e=this.getZSubdivisionChildNodes(t);for(const t of e)!t._containsTarget\u0026\u0026this.shouldFilterNodeForObstacle(t)||(this.shouldNodeBeXYSubdivided(t)?o.push(t):(t._containsObstacle=!1,n.push(t)));continue}this.shouldFilterNodeForObstacle(t)\u0026\u0026!t._containsTarget||n.push(t)}}this.unfinishedNodes.push(...o),this.finishedNodes.push(...n)}},Qet=.005,tnt=class extends si{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\u003e1?(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)=\u003et[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])=\u003et.capacityMeshNodeId),this.nextBatchNodeIds=[],this.batchHadModifications=!1}computeAdjacentNodeIdsForFirstBatch(t){const e=Math.max(...t.map(t=\u003eMath.max(...t.availableZ))),n=[];for(let o=0;o\u003c=e;o++)n.push(new hi(t.filter(t=\u003et.availableZ[0]===o)));for(const e of t){const t=[],o=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of o)n._containsTarget\u0026\u0026n._targetConnectionName!==e._targetConnectionName||e._containsTarget\u0026\u0026(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId\u0026\u0026li(e,n)\u0026\u0026t.push(n);e._adjacentNodeIds=t.map(t=\u003et.capacityMeshNodeId)}}getAdjacentSameLayerUnprocessedNodes(t){const e=[],n=Array.from(new Set((t._adjacentNodeIds??[]).map(t=\u003ethis.nodeMap.get(t)))).filter(e=\u003ee\u0026\u0026e.capacityMeshNodeId!==t.capacityMeshNodeId);n.sort((t,e)=\u003et.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=\u003ethis.nodeMap.get(t))),this.hasComputedAdjacentNodeIds=!0);let t=this.currentBatchNodeIds.pop();for(;t\u0026\u0026this.absorbedNodeIds.has(t);)t=this.currentBatchNodeIds.pop();if(!t)return this.batchHadModifications?(this.currentBatchNodeIds=this.nextBatchNodeIds.sort((t,e)=\u003e{const n=this.nodeMap.get(t),o=this.nodeMap.get(e);return n.width*n.height-o.width*o.height}),this.nextBatchNodeIds=[],void(this.batchHadModifications=!1)):(this.solved=!0,void this.newNodes.push(...this.nextBatchNodeIds.map(t=\u003ethis.nodeMap.get(t))));const e=this.nodeMap.get(t);let n=!1;const o=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===o.length)return void this.nextBatchNodeIds.push(t);const i=t=\u003e{for(const e of t)this.absorbedNodeIds.add(e.capacityMeshNodeId);e._adjacentNodeIds=Array.from(new Set([...e._adjacentNodeIds??[],...t.flatMap(t=\u003et._adjacentNodeIds??[])].filter(t=\u003et!==e.capacityMeshNodeId\u0026\u0026!this.absorbedNodeIds.has(t))))},r=o.filter(t=\u003et.center.x\u003ce.center.x\u0026\u0026Math.abs(t.center.y-e.center.y)\u003ce.height/2);if(r.length\u003e0){const{width:t,height:o}=r[0],s=r.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(r.reduce((t,e)=\u003et+e.height,0)-e.height)\u003cQet\u0026\u0026s\u0026\u0026(e.width+=t,e.center.x=e.center.x-t/2,i(r),n=!0)}const s=o.filter(t=\u003et.center.x\u003ee.center.x\u0026\u0026Math.abs(t.center.y-e.center.y)\u003ce.height/2);if(s.length\u003e0\u0026\u0026!n){const{width:t,height:o}=s[0],r=s.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(s.reduce((t,e)=\u003et+e.height,0)-e.height)\u003cQet\u0026\u0026r\u0026\u0026(e.width+=t,e.center.x=e.center.x+t/2,i(s),n=!0)}const a=o.filter(t=\u003et.center.y\u003ee.center.y\u0026\u0026Math.abs(t.center.x-e.center.x)\u003ce.width/2);if(a.length\u003e0\u0026\u0026!n){const{width:t,height:o}=a[0],r=a.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(a.reduce((t,e)=\u003et+e.width,0)-e.width)\u003cQet\u0026\u0026r\u0026\u0026(e.height+=o,e.center.y=e.center.y+o/2,i(a),n=!0)}const c=o.filter(t=\u003et.center.y\u003ce.center.y\u0026\u0026Math.abs(t.center.x-e.center.x)\u003ce.width/2);if(c.length\u003e0\u0026\u0026!n){const{width:t,height:o}=c[0],r=c.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(c.reduce((t,e)=\u003et+e.width,0)-e.width)\u003cQet\u0026\u0026r\u0026\u0026(e.height+=o,e.center.y=e.center.y-o/2,i(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(Dc(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e\u0026\u0026(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const o of this.currentBatchNodeIds){const i=this.nodeMap.get(o);if(!this.absorbedNodeIds.has(o)\u0026\u0026i){const r=Dc(i,{rectMargin:.01});o===e?r.stroke=\"rgba(0, 255, 0, 0.8)\":n?.some(t=\u003et.capacityMeshNodeId===o)?r.stroke=\"rgba(128, 0, 128, 0.8)\":r.stroke=\"rgba(255, 165, 0, 0.8)\",r.layer=`z${i.availableZ.join(\",\")}`,r.label=`${r.label}\\n(unprocessed)`,t.rects.push(r)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)\u0026\u0026n){const e=Dc(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}},ent=class extends si{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,o=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;const s=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,l=t.center.y-t.height/2,d=t.center.y+t.height/2;n=Math.min(n,e),o=Math.max(o,c),i=Math.min(i,l),r=Math.max(r,d);for(const e of t.availableZ)s.add(e);t._containsTarget\u0026\u0026(a=!0)}const c=o-n,l=r-i,d=(n+o)/2,h=(i+r)/2,u=Array.from(s).sort((t,e)=\u003et-e),p={capacityMeshNodeId:`merged_via_${t.center.x}_${t.center.y}`,center:{x:d,y:h},width:c,height:l,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=Dc(e);e._assignedViaObstacle\u0026\u0026(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=Dc(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}},nnt=class extends si{constructor(t){const{simpleRouteJson:e,nodes:n,edges:o,colorMap:i,MAX_ITERATIONS:r=1e6,hyperParameters:s={}}=t;super(),this.inputParams=t,this.hyperParameters=s,this.MAX_ITERATIONS=r,this.simpleRouteJson=e,this.nodes=n,this.edges=o,this.colorMap=i??{},this.nodeMap=new Map(this.nodes.map(t=\u003e[t.capacityMeshNodeId,t])),this.nodeEdgeMap=ai(this.edges);const a=this.nodes.filter(t=\u003et._containsTarget);this.unprocessedConnectionPairs=Xi(this.simpleRouteJson.connections.map(t=\u003e{const[e,n]=t.pointsToConnect;return{start:a.find(t=\u003exe(t.center,e)\u003ct.width/2),end:a.find(t=\u003exe(t.center,n)\u003ct.width/2),connection:t}}),this.hyperParameters.SHUFFLE_SEED??0),this.viaNodes=this.nodes.filter(t=\u003et.availableZ.length\u003e1)}inputParams;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=\u003e!t._completelyInsideObstacle\u0026\u0026!t._containsObstacle).filter(t=\u003e!this.usedNodeMap.has(t.capacityMeshNodeId));if(e.length\u003e0){const n=e.reduce((e,n)=\u003e{const o=this._dist(e,t.start);return this._dist(n,t.start)\u003co?n:e});this.closestViaForConnectionStartMap.set(t,n);const o=e.reduce((e,n)=\u003e{const o=this._dist(e,t.end);return this._dist(n,t.end)\u003co?n:e});this.closestViaForConnectionEndMap.set(t,o)}}}_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\u0026\u0026!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\u0026\u0026(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\u0026\u00260===this.visitedNodes.size){const t=this._dist(e,n),o={prevCandidate:null,node:e,g:0,h:t,f:this.GREEDY_MULTIPLIER*t};this.queuedCandidateNodes.push(o)}let o;for(this.queuedCandidateNodes.sort((t,e)=\u003et.f-e.f);this.queuedCandidateNodes.length\u0026\u0026!o;){const t=this.queuedCandidateNodes.shift();this.visitedNodes.has(t.node.capacityMeshNodeId)||(o=t)}if(!o)return this.failed=!0,void(this.error=\"No viable candidates left\");if(this.visitedNodes.add(o.node.capacityMeshNodeId),o.node.capacityMeshNodeId===n.capacityMeshNodeId){const e=[];let n=o;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 i=this.getNeighbors(o.node);for(const t of i){const e=t.capacityMeshNodeId;if(this.visitedNodes.has(e))continue;const i=this.computeG(o,t,n),r=this.computeH(o,t,n),s=i+this.GREEDY_MULTIPLIER*r,a=this.queuedCandidateNodes.findIndex(t=\u003et.node.capacityMeshNodeId===e);if(a\u003e=0){if(this.queuedCandidateNodes[a].g\u003c=i)continue;this.queuedCandidateNodes.splice(a,1)}this.queuedCandidateNodes.push({prevCandidate:o,node:t,g:i,h:r,f:s})}}getNeighbors(t){const e=new Set,n=this.nodeEdgeMap.get(t.capacityMeshNodeId)??[];for(const o of n){const[n,i]=o.nodeIds,r=n===t.capacityMeshNodeId?i:n,s=this.nodeMap.get(r);s\u0026\u0026e.add(s)}const o=this.activeSubpath?.layer;return Array.from(e).filter(t=\u003e!(t.capacityMeshNodeId!==this.activeSubpath?.end.capacityMeshNodeId)||!t._containsObstacle\u0026\u0026(!t._containsTarget\u0026\u0026(!this.usedNodeMap.has(t.capacityMeshNodeId)\u0026\u0026!(void 0!==o\u0026\u0026!t.availableZ.includes(o)))))}clearCandidateNodes(){this.queuedCandidateNodes=[],this.visitedNodes=new Set}computeG(t,e,n){const o=this._dist(t.node,e);return t.g+o}computeH(t,e,n){return this._dist(e,n)}createSolvedRoute(t,e){const n=[];for(let e=0;e\u003ct.length;e++){const o=t[e];o.path?0===e?n.push(...o.path):n.push(...o.path.slice(1)):(0===e\u0026\u0026n.push(o.start),e===t.length-1\u0026\u0026n.push(o.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,$i(e.reduce((t,e)=\u003et+16807*e%2147483647,0))()\u003cn))return[{start:t.start,end:t.end,solved:!1,layer:t.start.availableZ[0]??0}];const o=this.getClosestVia(t.start),i=this.getFarVia(o,t.end),r=t.start.availableZ[0]??0,s=t.end.availableZ[0]??0,a=[];return a.push({start:t.start,end:o,solved:!1,layer:r}),r===s?(a.push({start:o,end:i,solved:!1,layer:0===r?1:0}),a.push({start:i,end:t.end,solved:!1,layer:s})):a.push({start:o,end:t.end,solved:!1,layer:s}),a}getClosestVia(t){if(0===this.viaNodes.length)return t;const e=new Set;for(const[t,n]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair\u0026\u0026e.add(n.capacityMeshNodeId);for(const[t,n]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair\u0026\u0026e.add(n.capacityMeshNodeId);const n=this.viaNodes.filter(t=\u003e!t._completelyInsideObstacle\u0026\u0026!t._containsObstacle).filter(t=\u003e!this.usedNodeMap.has(t.capacityMeshNodeId)).filter(t=\u003e!e.has(t.capacityMeshNodeId));if(0===n.length){const e=this.viaNodes.filter(t=\u003e!t._completelyInsideObstacle\u0026\u0026!t._containsObstacle).filter(t=\u003e!this.usedNodeMap.has(t.capacityMeshNodeId));return 0===e.length?t:(e.sort((e,n)=\u003ethis._dist(e,t)-this._dist(n,t)),e[0])}n.sort((e,n)=\u003ethis._dist(e,t)-this._dist(n,t));const o=this.hyperParameters.MAX_CLOSEST_VIA_SKIP??0;if(o\u003e0\u0026\u0026n.length\u003e1){const t=$i((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length),e=Math.floor(t()*(o+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,o=new Set;for(const[t,e]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair\u0026\u0026o.add(e.capacityMeshNodeId);for(const[t,e]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair\u0026\u0026o.add(e.capacityMeshNodeId);const i=this.viaNodes.filter(e=\u003e!this.usedNodeMap.has(e.capacityMeshNodeId)\u0026\u0026e.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026!e._completelyInsideObstacle\u0026\u0026!e._containsObstacle\u0026\u0026!o.has(e.capacityMeshNodeId)\u0026\u0026this._dist(e,t)\u003e=n);if(0===i.length){const o=this.viaNodes.filter(e=\u003ee.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026!e._completelyInsideObstacle\u0026\u0026!e._containsObstacle\u0026\u0026!this.usedNodeMap.has(e.capacityMeshNodeId)\u0026\u0026this._dist(e,t)\u003e=n).sort((t,n)=\u003ethis._dist(t,e)-this._dist(n,e));if(o.length\u003e0)return o[0];return this.viaNodes.filter(e=\u003ee.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026!e._completelyInsideObstacle\u0026\u0026!e._containsObstacle\u0026\u0026!this.usedNodeMap.has(e.capacityMeshNodeId)).sort((t,n)=\u003ethis._dist(t,e)-this._dist(n,e))[0]??t}i.sort((t,n)=\u003ethis._dist(t,e)-this._dist(n,e));const r=this.hyperParameters.MAX_FURTHEST_VIA_SKIP??0;if(r\u003e0\u0026\u0026i.length\u003e1){const t=$i((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length+1e3),e=Math.floor(t()*(r+1));return i[Math.min(e,i.length-1)]}return i[0]}getCapacityPaths(){const t=[];for(const e of this.solvedRoutes){const n=e.path;n\u0026\u0026n.length\u003e0\u0026\u0026t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,nodeIds:n.map(t=\u003et.capacityMeshNodeId)})}return t}visualize(){const t={lines:[],points:[],rects:[],circles:[]},e=t=\u003e!!t\u0026\u0026\"number\"==typeof t.x\u0026\u0026\"number\"==typeof t.y\u0026\u0026!Number.isNaN(t.x)\u0026\u0026!Number.isNaN(t.y)\u0026\u0026Number.isFinite(t.x)\u0026\u0026Number.isFinite(t.y),n=t=\u003e\"number\"==typeof t\u0026\u0026!Number.isNaN(t)\u0026\u0026Number.isFinite(t);for(const o of this.nodes){const i=this.queuedCandidateNodes.some(t=\u003et.node.capacityMeshNodeId===o.capacityMeshNodeId),r=this.queuedCandidateNodes.find(t=\u003et.node.capacityMeshNodeId===o.capacityMeshNodeId);if(e(o.center)\u0026\u0026n(o.width)\u0026\u0026n(o.height)){const e=Dc(o,{rectMargin:.025,zOffset:.01});t.rects.push({...e,fill:i?\"rgba(255, 128, 255, 0.5)\":o._containsTarget?\"rgba(0, 150, 255, 0.15)\":o._containsObstacle?\"rgba(255, 0, 0, 0.1)\":\"rgba(200, 200, 200, 0.05)\",label:[`ID: ${o.capacityMeshNodeId}`,`Size: ${o.width.toFixed(2)}x${o.height.toFixed(2)}`,`Z: ${o.availableZ.join(\", \")}`,r?`g: ${r.g.toFixed(2)}`:\"\",r?`h: ${r.h.toFixed(2)}`:\"\",r?`f: ${r.f.toFixed(2)}`:\"\",o._containsTarget?\"TARGET\":\"\",o._containsObstacle?\"OBSTACLE\":\"\"].filter(t=\u003et).join(\"\\n\")})}}for(const n of this.edges){const[o,i]=n.nodeIds,r=this.nodeMap.get(o),s=this.nodeMap.get(i);r?.center\u0026\u0026s?.center\u0026\u0026e(r.center)\u0026\u0026e(s.center)\u0026\u0026t.lines.push({points:[r.center,s.center],strokeColor:\"rgba(150, 150, 150, 0.2)\"})}for(let n=0;n\u003cthis.solvedRoutes.length;n++){const o=this.solvedRoutes[n],i=o.path,r=\"blue\";for(let o=0;o\u003ci.length-1;o++){const s=i[o],a=i[o+1];if(s?.center\u0026\u0026a?.center\u0026\u0026e(s.center)\u0026\u0026e(a.center)){const e=s.availableZ.includes(1)\u0026\u0026a.availableZ.includes(1),o=n%5*.02;t.lines.push({points:[{x:s.center.x+o,y:s.center.y+o},{x:a.center.x+o,y:a.center.y+o}],strokeColor:r,strokeDash:e?\"5 5\":void 0})}}if(i.length\u003e0){const n=i[0],r=i[i.length-1];n?.center\u0026\u0026e(n.center)\u0026\u0026t.points.push({x:n.center.x,y:n.center.y,label:`START: ${o.connection.name}`}),r?.center\u0026\u0026e(r.center)\u0026\u0026t.points.push({x:r.center.x,y:r.center.y,label:`END: ${o.connection.name}`})}}if(this.solvedSubpaths)for(let n=0;n\u003cthis.solvedSubpaths.length;n++){const o=this.solvedSubpaths[n];if(o.path\u0026\u0026o.path.length\u003e1)for(let n=0;n\u003co.path.length-1;n++){const i=o.path[n],r=o.path[n+1];i?.center\u0026\u0026r?.center\u0026\u0026e(i.center)\u0026\u0026e(r.center)\u0026\u0026t.lines.push({points:[i.center,r.center],strokeColor:\"green\",strokeDash:1===o.layer?\"3 3\":void 0})}}if(this.activeSubpath){const n=this.activeSubpath.start?.center,o=this.activeSubpath.end?.center;n\u0026\u0026o\u0026\u0026e(n)\u0026\u0026e(o)\u0026\u0026(t.lines.push({points:[n,o],strokeColor:\"orange\",strokeDash:\"5 5\"}),t.points.push({x:n.x,y:n.y,label:\"ACTIVE START\"}),t.points.push({x:o.x,y:o.y,label:\"ACTIVE END\"}))}const o=this.queuedCandidateNodes.slice(0,10).sort((t,e)=\u003et.f-e.f);for(let n=0;n\u003co.length;n++){const i=.6*(1-n/10),r=[];let s=o[n];for(;s;)r.push(s.node),s=s.prevCandidate;if(r.reverse(),r.length\u003e1){const n=r.map(t=\u003et.center).filter(t=\u003ee(t));n.length\u003e1\u0026\u0026t.lines.push({points:n,strokeColor:To(\"purple\",1-i),strokeDash:1===this.activeSubpath?.layer?\"4 2\":void 0})}}if(this.activeConnectionPair){const n=this.activeConnectionPair.start?.center,o=this.activeConnectionPair.end?.center;n\u0026\u0026o\u0026\u0026e(n)\u0026\u0026e(o)\u0026\u0026t.lines.push({points:[n,o],strokeColor:\"cyan\",strokeDash:\"20 5\"})}if(this.ogUnprocessedSubpaths\u0026\u00263===this.ogUnprocessedSubpaths.length){const[,o]=this.ogUnprocessedSubpaths;if(o.start?.center\u0026\u0026e(o.start.center)){const e=Math.max(o.start.width||0,o.start.height||0);n(e)\u0026\u0026e\u003e0\u0026\u0026(t.circles.push({center:o.start.center,radius:e,stroke:\"blue\"}),t.points.push({x:o.start.center.x,y:o.start.center.y,label:\"DIRECTIVE VIA 1\"}))}if(o.end?.center\u0026\u0026e(o.end.center)){const e=Math.max(o.end.width||0,o.end.height||0);n(e)\u0026\u0026e\u003e0\u0026\u0026(t.circles.push({center:o.end.center,radius:e,stroke:\"purple\"}),t.points.push({x:o.end.center.x,y:o.end.center.y,label:\"DIRECTIVE VIA 2\"}))}}if(this.queuedCandidateNodes.length\u003e0)for(const n of this.queuedCandidateNodes){const o=n.node;o?.center\u0026\u0026e(o.center)\u0026\u0026t.circles.push({center:o.center,radius:.05,fill:\"rgba(255, 255, 0, 0.6)\",stroke:\"yellow\"})}if(this.visitedNodes.size\u003e0)for(const n of this.visitedNodes){const o=this.nodeMap.get(n);o?.center\u0026\u0026e(o.center)\u0026\u0026t.circles.push({center:o.center,radius:.08,fill:\"rgba(128, 128, 128, 0.5)\",stroke:\"gray\"})}return t}},ont=class extends ys{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,o=e\u003e0?n/e:0;return t.iterations/t.MAX_ITERATIONS+(1-o)}computeH(t){const e=t.unprocessedConnectionPairs.length+t.solvedRoutes.length+(t.activeConnectionPair?1:0),n=t.solvedRoutes.length;return e\u003e0?1-n/e:0}generateSolver(t){return new nnt({...this.constructorParams,hyperParameters:{...this.constructorParams.hyperParameters,...t}})}};function int(t){const e=new Map;for(const n of t)e.set(n.capacityMeshNodeId,n);return e}function rnt(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}var snt=class extends si{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=int(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\u0026\u0026e.offBoardConnectsTo.length\u003e0\u0026\u0026this.assignableNodes.push(t)}}initializePendingEdges(){const t=new Map;for(const e of this.assignableNodes){const n=e._assignedViaObstacle;if(n?.offBoardConnectsTo)for(const o of n.offBoardConnectsTo)t.has(o)||t.set(o,[]),t.get(o).push(e)}this.pendingEdges=[];for(const[e,n]of t)if(n.length\u003e1)for(let t=0;t\u003cn.length;t++)for(let o=t+1;o\u003cn.length;o++)this.pendingEdges.push({node1:n[t],node2:n[o],netName:e})}_step(){switch(this.animationState){case\"showing_nodes\":if(this.assignableNodes.length\u003e0){const t=this.assignableNodes.shift();this.shownNodes.push(t)}else this.animationState=\"showing_edges\";break;case\"showing_edges\":if(this.pendingEdges.length\u003e0){const{node1:t,node2:e,netName:n}=this.pendingEdges.shift(),o=this.createOffboardEdge(t,e,n);this.enhancedEdges.push(o),this.createdEdges.push(o)}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=[],o=new Set(this.shownNodes.map(t=\u003et.capacityMeshNodeId));for(const e of this.capacityEdges){if(e.isOffboardEdge)continue;if(o.has(e.nodeIds[0])||o.has(e.nodeIds[1])){const n=this.nodeMap.get(e.nodeIds[0]),o=this.nodeMap.get(e.nodeIds[1]);n\u0026\u0026o\u0026\u0026t.push({points:[n.center,o.center],strokeColor:\"rgba(0, 200, 0, 0.5)\",strokeWidth:.05})}}for(let t=0;t\u003cthis.shownNodes.length;t++){const o=this.shownNodes[t],i=o._assignedViaObstacle,r=t===this.shownNodes.length-1\u0026\u0026\"showing_nodes\"===this.animationState;n.push({center:o.center,width:o.width,height:o.height,fill:r?\"rgba(255, 165, 0, 0.5)\":\"rgba(173, 216, 230, 0.5)\",stroke:r?\"orange\":\"blue\",strokeWidth:r?.15:.1}),e.push({x:o.center.x,y:o.center.y,color:r?\"orange\":\"blue\",label:`${r?\"NEW: \":\"\"}${o.capacityMeshNodeId}\\n${i?.offBoardConnectsTo?.join(\", \")||\"\"}`})}for(let n=0;n\u003cthis.createdEdges.length;n++){const o=this.createdEdges[n],i=n===this.createdEdges.length-1\u0026\u0026\"showing_edges\"===this.animationState,r=this.nodeMap.get(o.nodeIds[0]),s=this.nodeMap.get(o.nodeIds[1]);if(r\u0026\u0026s){t.push({points:[r.center,s.center],strokeColor:i?\"red\":\"orange\",strokeWidth:i?.2:.1,strokeDasharray:\"0.3,0.15\"});const n=rnt(r.center,s.center);e.push({x:n.x,y:n.y,color:i?\"red\":\"orange\",label:`${i?\"NEW: \":\"\"}⚡ ${o.offboardNetName}`})}}let i=\"Offboard Capacity Node Solver\";switch(this.animationState){case\"showing_nodes\":i+=` - Showing nodes (${this.shownNodes.length}/${this.shownNodes.length+this.assignableNodes.length})`;break;case\"showing_edges\":i+=` - Creating edges (${this.createdEdges.length}/${this.createdEdges.length+this.pendingEdges.length})`;break;case\"done\":i+=` - Done (${this.shownNodes.length} nodes, ${this.createdEdges.length} edges)`}return{lines:t,points:e,rects:n,title:i}}getVirtualOffboardNodes(){return[]}getOffboardEdges(){return this.enhancedEdges.filter(t=\u003et.isOffboardEdge)}},ant=class extends si{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:o}){super(),this.inputPaths=[...t],this.capacityEdges=e,this.originalConnections=o,this.nodeMap=int(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=\u003et.isFragmentedPath)?this.animationState=\"showing_fragment\":this.fragmentedPaths.push(...this.currentFragments);break;case\"showing_fragment\":if(this.currentFragmentIndex\u003cthis.currentFragments.length){const t=this.currentFragments[this.currentFragmentIndex];this.fragmentedPaths.push(t),this.currentFragmentIndex++}else this.currentPath\u0026\u0026(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=\u003ee.name===t.connectionName);if(n)for(let t=0;t\u003ce.length;t++){const o=e[t];if(!o.isFragmentedPath)continue;const i=n.pointsToConnect.filter(t=\u003e{for(const e of o.nodeIds){const n=this.nodeMap.get(e);if(n\u0026\u0026Xj(t,n))return!0}return!1}),r=0===t,s=r?o.nodeIds[o.nodeIds.length-1]:o.nodeIds[0],a=this.nodeMap.get(s);if(i.length\u003e0\u0026\u0026a){const t=i[0],e={x:a.center.x,y:a.center.y,layer:bo(t)},s=r?[...i,e]:[e,...i];this.fragmentedConnections.push({name:o.connectionName,pointsToConnect:s,__netConnectionName:n.__netConnectionName,__rootConnectionNames:n.__rootConnectionNames})}}}splitPath(t){const{nodeIds:e}=t;if(e.length\u003c2)return[t];const n=[];for(let t=0;t\u003ce.length-1;t++){const o=this.capacityEdges.find(n=\u003en.nodeIds[0]===e[t]\u0026\u0026n.nodeIds[1]===e[t+1]||n.nodeIds[0]===e[t+1]\u0026\u0026n.nodeIds[1]===e[t]);o\u0026\u0026o.isOffboardEdge\u0026\u0026n.push(t)}if(0===n.length)return[t];const o=[];let i=0,r=0;for(const s of n){const n=e.slice(i,s+1);if(n.length\u003e=1){const e=this.nextFragmentId++;o.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${r++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}i=s+1}if(i\u003ce.length){const n=e.slice(i);if(n.length\u003e=1){const e=this.nextFragmentId++;o.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${r++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}}return o.length\u003e0?o:[t]}getFragmentedPaths(){return this.fragmentedPaths}getFragmentedConnections(){return this.fragmentedConnections}getFragmentedOriginalConnectionNames(){return this.fragmentedOriginalConnectionNames}visualize(){const t=[],e=[],n=[];if(\"showing_original_path\"===this.animationState\u0026\u0026this.currentPath\u0026\u0026this.drawPath({path:this.currentPath,color:\"gray\",lines:t,points:e,rects:n,labelPrefix:\"Original: \"}),this.fragmentedPaths.forEach((o,i)=\u003e{if(o.isFragmentedPath){const r=i%2==0?\"blue\":\"red\";this.drawPath({path:o,color:r,lines:t,points:e,rects:n,labelPrefix:`Frag ${i}: `})}else this.drawPath({path:o,color:\"green\",lines:t,points:e,rects:n,labelPrefix:\"\"})}),\"showing_fragment\"===this.animationState\u0026\u0026this.currentFragmentIndex\u003e0){const o=this.fragmentedPaths.length-1;if(o\u003e=0){const i=this.fragmentedPaths[o];i.isFragmentedPath\u0026\u0026this.drawPath({path:i,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]),o=this.nodeMap.get(e.nodeIds[1]);n\u0026\u0026o\u0026\u0026t.push({points:[n.center,o.center],strokeColor:\"orange\",strokeWidth:.15,strokeDasharray:\"0.3,0.15\"})}let o=\"Offboard Path Fragment Solver\";return\"showing_original_path\"===this.animationState?o+=\" - Analyzing path...\":\"showing_fragment\"===this.animationState?o+=` - Fragment ${this.currentFragmentIndex}/${this.currentFragments.length}`:o+=` - Done (${this.fragmentedPaths.filter(t=\u003et.isFragmentedPath).length} fragments)`,{lines:t,points:e,rects:n,title:o}}drawPath(t){const{path:e,color:n,lines:o,points:i,rects:r,labelPrefix:s}=t,a=[];for(let t=0;t\u003ce.nodeIds.length;t++){const o=e.nodeIds[t],c=this.nodeMap.get(o);c\u0026\u0026(a.push(c.center),r.push({center:c.center,width:.8*c.width,height:.8*c.height,stroke:n,strokeWidth:.05,fill:`${n}33`}),0!==t\u0026\u0026t!==e.nodeIds.length-1||i.push({x:c.center.x,y:c.center.y,color:n,label:`${s}${e.connectionName}\\n${o}`}))}a.length\u003e1\u0026\u0026o.push({points:a,strokeColor:n,strokeWidth:.1})}};function cnt(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var lnt=class extends si{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,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),r=n.targetMinCapacity??.5;n.capacityDepth=$s(i,r)}this.connMap=ii(t),this.colorMap=wo(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;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=[cnt(\"netToPointPairsSolver\",ma,t=\u003e[t.srj,t.colorMap,ri(t.srj)],{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,this.connMap),t.connMap=ii(t.srjWithPointPairs)}}),cnt(\"nodeSolver\",Ket,t=\u003e[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=\u003e{t.capacityNodes=t.nodeSolver?.finishedNodes}}),cnt(\"mergeAssignableViaNodes\",ent,t=\u003e[t.nodeSolver?.finishedNodes],{onSolved:t=\u003e{t.capacityNodes=t.mergeAssignableViaNodes?.newNodes}}),cnt(\"singleLayerNodeMerger\",tnt,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),cnt(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),cnt(\"offboardCapacityNodeSolver\",snt,t=\u003e[{capacityNodes:t.capacityNodes,capacityEdges:t.capacityEdges||[]}],{onSolved:t=\u003e{t.capacityEdges=t.offboardCapacityNodeSolver?.enhancedEdges||t.capacityEdges}}),cnt(\"deadEndSolver\",Qc,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges}],{onSolved:t=\u003e{const e=t.deadEndSolver?.removedNodeIds;t.capacityNodes=t.capacityNodes.filter(t=\u003e!e.has(t.capacityMeshNodeId)),t.capacityEdges=t.capacityEdges.filter(t=\u003et.nodeIds.every(t=\u003e!e.has(t)))}}),cnt(\"initialPathingHyperSolver\",ont,t=\u003e[{simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,hyperParameters:{MAX_CAPACITY_FACTOR:1}}],{onSolved:t=\u003e{const e=t.initialPathingHyperSolver?.winningSolver;e\u0026\u0026(t.initialPathingSolver=e)}}),cnt(\"offboardPathFragmentSolver\",ant,t=\u003e[{capacityPaths:t.initialPathingSolver?.getCapacityPaths()||[],capacityEdges:t.capacityEdges||[],capacityNodes:t.capacityNodes||[],connections:t.srjWithPointPairs?.connections||[]}],{onSolved:t=\u003e{const e=t.offboardPathFragmentSolver;if(!e)return;const n=e.getFragmentedPaths();for(const e of n)if(e.isFragmentedPath\u0026\u0026e.mstPairConnectionName){const n=t.colorMap[e.mstPairConnectionName];n\u0026\u0026!t.colorMap[e.connectionName]\u0026\u0026(t.colorMap[e.connectionName]=n)}const o=e.getFragmentedOriginalConnectionNames(),i=e.getFragmentedConnections();o.size\u003e0\u0026\u0026t.srjWithPointPairs\u0026\u0026(t.srjWithPointPairs={...t.srjWithPointPairs,connections:[...t.srjWithPointPairs.connections.filter(t=\u003e!o.has(t.name)),...i]},t.connMap=ii(t.srjWithPointPairs))}}),cnt(\"edgeToPortSegmentSolver\",Nc,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.offboardPathFragmentSolver?.getFragmentedPaths()||t.initialPathingSolver?.getCapacityPaths()||[],colorMap:t.colorMap}]),cnt(\"segmentToPointSolver\",Lc,t=\u003e{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments\u0026\u0026t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=\u003e{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),cnt(\"unravelMultiSectionSolver\",gl,t=\u003e[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),cnt(\"highDensityRouteSolver\",zs,t=\u003e[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap}]),cnt(\"highDensityStitchSolver\",Ca,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),cnt(\"uselessViaRemovalSolver1\",Xa,t=\u003e[{unsimplifiedHdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount,connMap:t.connMap}]),cnt(\"multiSimplifiedPathSolver1\",Za,t=\u003e[{unsimplifiedHdRoutes:t.uselessViaRemovalSolver1?.getOptimizedHdRoutes()||t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline}]),cnt(\"uselessViaRemovalSolver2\",Xa,t=\u003e[{unsimplifiedHdRoutes:t.multiSimplifiedPathSolver1.simplifiedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount,connMap:t.connMap}]),cnt(\"multiSimplifiedPathSolver2\",Za,t=\u003e[{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\u0026\u0026(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\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),o=this.mergeAssignableViaNodes?.visualize(),i=this.singleLayerNodeMerger?.visualize(),r=this.strawSolver?.visualize(),s=this.edgeSolver?.visualize(),a=(this.offboardCapacityNodeSolver?.visualize(),this.deadEndSolver?.visualize()),c=this.initialPathingSolver?.visualize(),l=this.offboardPathFragmentSolver?.visualize(),d=this.pathingOptimizer?.visualize(),h=this.edgeToPortSegmentSolver?.visualize(),u=this.segmentToPointSolver?.visualize(),p=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),m=this.highDensityRouteSolver?.visualize(),g=this.highDensityStitchSolver?.visualize(),f=this.uselessViaRemovalSolver1?.visualize(),y=this.uselessViaRemovalSolver2?.visualize(),_=this.multiSimplifiedPathSolver1?.visualize(),b=this.multiSimplifiedPathSolver2?.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\u0026\u0026x.length\u003e=2){const t=x.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const S=Oo(this.srj),I={points:[...this.srj.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,this.srj.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(this.srj.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,this.srj.layerCount),label:S(t)}))],lines:v},C=[I,t,e,n,o,i,r,s,a,c,l,d,h,u,p,m?pi(I,m):null,g,f,_,y,b,this.solved?pi({lines:v},Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...C)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}if(this.pathingOptimizer){const t=[];for(const e of this.pathingOptimizer.connectionsWithNodes)e.path\u0026\u0026t.push({points:e.path.map(t=\u003e({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 o of n){const n=o.__netConnectionName,i=o.__rootConnectionNames?.[0],r=e.filter(t=\u003et.connectionName===o.name);for(let e=0;e\u003cr.length;e++){const s=r[e],a={type:\"pcb_trace\",pcb_trace_id:`${o.name}_${e}`,connection_name:n??i??o.name,route:Mo(s,this.srj.layerCount)};t.push(a)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},dnt=1e-9,hnt=t=\u003e(t=\u003e\"wire\"===t.route_type)(t)||(t=\u003e\"via\"===t.route_type)(t)?t:(t=\u003e\"through_obstacle\"===t.route_type)(t)\u0026\u0026Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y)\u003c=dnt?{route_type:t.route_type,x:t.start.x,y:t.start.y,from_layer:t.from_layer,to_layer:t.to_layer,width:t.width}:null,unt=(t,e)=\u003et.layer??e.layer??t.to_layer??e.from_layer??t.from_layer??e.to_layer??\"top\",pnt=(t,e,n)=\u003et.width??e.width??n,mnt=(t,e,n,o,i)=\u003e({x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n,layer:o,width:i}),gnt=(t,e)=\u003e({...t,x:Math.abs(t.x-e.minX)\u003c1e-6?e.minX:Math.abs(t.x-e.maxX)\u003c1e-6?e.maxX:t.x,y:Math.abs(t.y-e.minY)\u003c1e-6?e.minY:Math.abs(t.y-e.maxY)\u003c1e-6?e.maxY:t.y}),fnt=({x:t,y:e,layer:n})=\u003e({x:t,y:e,layer:n}),ynt=({x:t,y:e,layer:n,width:o})=\u003e({route_type:\"wire\",x:t,y:e,layer:n,width:o}),_nt=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;let r=0,s=1;const a=(t,e)=\u003e{if(Math.abs(t)\u003cdnt)return e\u003e=0;const n=e/t;if(t\u003c0){if(n\u003es)return!1;n\u003er\u0026\u0026(r=n)}else{if(n\u003cr)return!1;n\u003cs\u0026\u0026(s=n)}return!0};return a(-o,t.x-n.minX)\u0026\u0026a(o,n.maxX-t.x)\u0026\u0026a(-i,t.y-n.minY)\u0026\u0026a(i,n.maxY-t.y)?{startT:r,endT:s}:null},bnt=(t,e)=\u003et.x\u003e=e.minX-1e-6\u0026\u0026t.x\u003c=e.maxX+1e-6\u0026\u0026t.y\u003e=e.minY-1e-6\u0026\u0026t.y\u003c=e.maxY+1e-6\u0026\u0026(Math.abs(t.x-e.minX)\u003c=1e-6||Math.abs(t.x-e.maxX)\u003c=1e-6||Math.abs(t.y-e.minY)\u003c=1e-6||Math.abs(t.y-e.maxY)\u003c=1e-6),xnt=(t,e,n,o,i)=\u003e{var r,s;(r=o,s=i,Math.hypot(r.x-s.x,r.y-s.y)\u003c=dnt)||t.push({type:\"pcb_trace\",pcb_trace_id:`${e.pcb_trace_id}_keep_${n}`,connection_name:e.connection_name,route:[ynt(o),ynt(i)]})},vnt=({obstacleId:t,start:e,end:n,layer:o,width:i})=\u003e{const r=n.x-e.x,s=n.y-e.y,a=Math.hypot(r,s);return a\u003ei+dnt?null:{obstacleId:t,type:\"rect\",layers:[o],center:{x:(e.x+n.x)/2,y:(e.y+n.y)/2},width:a,height:i,ccwRotationDegrees:180*Math.atan2(s,r)/Math.PI,connectedTo:[]}},Snt=({connection:t,point:e,endpointIndex:n})=\u003e({obstacleId:`${t.name}_route_endpoint_${n}`,type:\"rect\",layers:[e.layer],center:{x:e.x,y:e.y},width:e.width,height:e.width,connectedTo:[t.name,t.__rootConnectionNames?.[0]??t.name]}),Int=({trace:t,ripIndex:e,start:n,end:o,region:i,allowInteriorStart:r,allowInteriorEnd:s})=\u003e{if(!r\u0026\u0026!bnt(n,i)||!s\u0026\u0026!bnt(o,i))return null;const a=(({trace:t,ripIndex:e,start:n,end:o})=\u003e({name:`${t.connection_name}_reroute_${t.pcb_trace_id}_${e}`,__rootConnectionNames:[t.connection_name],pointsToConnect:[fnt(n),fnt(o)]}))({trace:t,ripIndex:e,start:n,end:o});return{connection:a,endpointObstacles:[Snt({connection:a,point:n,endpointIndex:0}),Snt({connection:a,point:o,endpointIndex:1})]}},Cnt=(t,e,n)=\u003e{const o=[],i=[],r=[],s=[];let a=null,c=!1,l=0,d=!1;for(let h=0;h\u003ct.route.length-1;h++){const u=hnt(t.route[h]),p=hnt(t.route[h+1]);if(!u||!p)return null;const m=unt(u,p),g=pnt(u,p,n),f=_nt(u,p,e),y=mnt(u,p,0,m,g),_=mnt(u,p,1,m,g),b=0===h;if(!f){xnt(o,t,l++,y,_);continue}if(d=!0,f.startT\u003ednt){const e=mnt(u,p,f.startT,m,g),n=vnt({obstacleId:`${t.pcb_trace_id}_keep_${l}_bounds`,start:y,end:e,layer:m,width:g});n\u0026\u0026s.push(n),xnt(o,t,l++,y,e)}const x=mnt(u,p,f.endT,m,g),v=gnt(mnt(u,p,f.startT,m,g),e),S=gnt(mnt(u,p,f.endT,m,g),e);if(a||(a=v,c=b\u0026\u0026f.startT\u003c=dnt),f.endT\u003c.999999999){const n=Int({trace:t,ripIndex:i.length,start:a,end:S,region:e,allowInteriorStart:c});n\u0026\u0026(i.push(n.connection),r.push(...n.endpointObstacles)),a=null,c=!1;const d=vnt({obstacleId:`${t.pcb_trace_id}_keep_${l}_bounds`,start:x,end:_,layer:m,width:g});d\u0026\u0026s.push(d),xnt(o,t,l++,x,_)}}if(a){const n=t.route.slice().reverse().map(hnt).find(t=\u003eBoolean(t));if(n){const o=Int({trace:t,ripIndex:i.length,start:a,end:{x:n.x,y:n.y,layer:n.layer??n.from_layer??a.layer,width:a.width},region:e,allowInteriorStart:c,allowInteriorEnd:!0});o\u0026\u0026(i.push(o.connection),r.push(...o.endpointObstacles))}}return{keptTraces:o,rerouteConnections:i,rerouteEndpointObstacles:r,clippedTraceSegmentObstacles:s,hadIntersection:d}},Pnt=(t,e)=\u003e{const n=structuredClone(t),o=[],i=[],r=[],s=[];for(const n of t.traces??[]){const a=Cnt(n,e,t.minTraceWidth);a?a.hadIntersection?(o.push(...a.keptTraces),i.push(...a.rerouteConnections),r.push(...a.rerouteEndpointObstacles),s.push(...a.clippedTraceSegmentObstacles)):o.push(structuredClone(n)):o.push(structuredClone(n))}const a=((t,e)=\u003e{const n={minX:t.minX,maxX:t.maxX,minY:t.minY,maxY:t.maxY};for(const t of e){const e=Ee(t);n.minX=Math.min(n.minX,e.minX),n.maxX=Math.max(n.maxX,e.maxX),n.minY=Math.min(n.minY,e.minY),n.maxY=Math.max(n.maxY,e.maxY)}return n})(e,[...r,...s]);return{...n,bounds:a,obstacles:[...n.obstacles,...r],traces:o,connections:i}},Mnt=(t,e)=\u003e{const n=new Map(e.connections.map(t=\u003e[t.name,t.__rootConnectionNames?.[0]??t.name])),o=(e.traces??[]).map(t=\u003e{const e=n.get(t.connection_name);return e?{...structuredClone(t),connection_name:e}:structuredClone(t)});return{...structuredClone(t),traces:o,jumpers:e.jumpers?structuredClone(e.jumpers):structuredClone(t.jumpers)}},Nnt=(t,e,n=[])=\u003e[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join(\"\\n\"),wnt=1.8,Tnt=.95,Rnt=.8,Ent=.95,Ant=class extends si{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;regionId;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.regionId=t.regionId,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=xe(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\u0026\u0026this.existingJumpers.push(...t.jumpers);const n=Math.ceil(5*(this.numRoutes+1));let o=this.boundsSize.width/this.cellStep,i=this.boundsSize.height/this.cellStep;for(;o*i\u003en**2\u0026\u0026!(this.cellStep\u003et.minDistBetweenEnteringPoints);)this.cellStep*=2,o=this.boundsSize.width/this.cellStep,i=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR;const r=Math.abs(this.A.x-this.bounds.minX)\u003c.001\u0026\u0026Math.abs(this.B.x-this.bounds.minX)\u003c.001||Math.abs(this.A.x-this.bounds.maxX)\u003c.001\u0026\u0026Math.abs(this.B.x-this.bounds.maxX)\u003c.001||Math.abs(this.A.y-this.bounds.minY)\u003c.001\u0026\u0026Math.abs(this.B.y-this.bounds.minY)\u003c.001||Math.abs(this.A.y-this.bounds.maxY)\u003c.001\u0026\u0026Math.abs(this.B.y-this.bounds.maxY)\u003c.001;this.futureConnections\u0026\u00260===this.futureConnections.length\u0026\u00260===this.obstacleRoutes.length\u0026\u0026!r\u0026\u0026this.handleSimpleCases();const s={x:t.A.x,y:t.A.y};this.initialNodeGridOffset={x:s.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:s.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 Wi([{...t.A,...s,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,regionId:this.regionId,route:[{x:t.x,y:t.y,z:0},{x:e.x,y:e.y,z:0}],traceThickness:this.traceThickness,jumpers:[]}}get jumperPenaltyDistance(){return wnt+this.straightLineDistance*this.JUMPER_PENALTY_FACTOR}isNodeTooCloseToObstacle(t,e){e??=this.obstacleMargin;for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){const o=Ont(n);for(const n of o)if(be(t,n.A,n.B)\u003cthis.traceThickness+e)return!0}for(const o of n.jumpers||[])if(this.isNodeTooCloseToJumper(t,o,e))return!0}return!1}isNodeTooCloseToJumper(t,e,n){const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=Math.abs(o)\u003eMath.abs(i),s=(r?Rnt:Ent)/2+n,a=(r?Ent:Rnt)/2+n;return Math.abs(t.x-e.start.x)\u003cs\u0026\u0026Math.abs(t.y-e.start.y)\u003ca||Math.abs(t.x-e.end.x)\u003cs\u0026\u0026Math.abs(t.y-e.end.y)\u003ca}isNodeTooCloseToEdge(t){const e=t.gComponents?.distFromStart??0\u003cthis.obstacleMargin/2?-this.obstacleMargin/2:this.obstacleMargin/2,n=t.x\u003cthis.bounds.minX+e||t.x\u003ethis.bounds.maxX-e||t.y\u003cthis.bounds.minY+e||t.y\u003ethis.bounds.maxY-e;return(!n||!(xe(t,this.B)\u003c2*e||xe(t,this.A)\u003c2*e))\u0026\u0026n}doesPathToParentIntersectObstacle(t){const e=t.parent;if(!e)return!1;for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){for(const o of Ont(n))if(fe(t,e,o.A,o.B))return!0;for(const o of n.jumpers||[])if(this.doesSegmentIntersectJumperPads(t,e,o))return!0}}return!1}doesSegmentIntersectJumperPads(t,e,n){const o=this.obstacleMargin,i=n.end.x-n.start.x,r=n.end.y-n.start.y,s=Math.abs(i)\u003eMath.abs(r),a=(s?Rnt:Ent)/2+o,c=(s?Ent:Rnt)/2+o;return!!this.doesSegmentIntersectRect(t,e,n.start,a,c)||!!this.doesSegmentIntersectRect(t,e,n.end,a,c)}doesSegmentIntersectRect(t,e,n,o,i){const r=n.x-o,s=n.x+o,a=n.y-i,c=n.y+i;if(t.x\u003e=r\u0026\u0026t.x\u003c=s\u0026\u0026t.y\u003e=a\u0026\u0026t.y\u003c=c)return!0;if(e.x\u003e=r\u0026\u0026e.x\u003c=s\u0026\u0026e.y\u003e=a\u0026\u0026e.y\u003c=c)return!0;const l=[{A:{x:r,y:a},B:{x:s,y:a}},{A:{x:s,y:a},B:{x:s,y:c}},{A:{x:s,y:c},B:{x:r,y:c}},{A:{x:r,y:c},B:{x:r,y:a}}];for(const n of l)if(fe(t,e,n.A,n.B))return!0;return!1}findObstaclesBetween(t,e){const n=[];for(const o of this.obstacleRoutes){const i=this.connMap?.areIdsConnected?.(this.connectionName,o.connectionName);if(!i)for(const i of Ont(o))fe(t,e,i.A,i.B)\u0026\u0026n.push({A:i.A,B:i.B})}return n}computeHComponents(t){const e=xe(t,this.roundedGoalPosition),n=this.getObstacleProximityPenalty(t),o=this.getEdgeProximityPenalty(t),i=this.getFutureConnectionStartEndPenalty(t),r=this.getFutureConnectionLinePenalty(t),s=t.parent,a=s?.hComponents,c=s?xe(t,s):0,l=(t,n)=\u003e{if(void 0===n||c\u003c1e-9||e\u003c1e-9)return t;const o=(t-n)/c;return(t+Math.max(0,t+o*e))/2},d=l(n,a?.obstacleProximityRate),h=l(o,a?.edgeProximityRate),u=l(i,a?.futureConnectionStartEndProximityRate),p=l(r,a?.futureConnectionLineRate),m=d*e,g=h*e,f=u*e,y=p*e;return{distanceToGoal:e,obstacleProximity:m,edgeProximity:g,futureConnectionStartEndProximityPenalty:f,futureConnectionLine:y,total:e+m+g+f+y,obstacleProximityRate:n,edgeProximityRate:o,futureConnectionStartEndProximityRate:i,futureConnectionLineRate:r}}computeH(t){return this.computeHComponents(t).total}computeGComponents(t){const e=t.parent,n=e?xe(t,e):0,o=e?.gComponents??{distFromStart:0,weightedMmNearObstacle:0,weightedMmNearEdge:0,weightedMmNearFutureConnectionStartEnd:0,weightedMmNearFutureConnectionLine:0,jumperPenalty:0,jumperPadFutureConnectionPenalty:0,total:0},i=o.distFromStart+n,r=o.weightedMmNearObstacle+this.getObstacleProximityPenalty(t)*n,s=o.weightedMmNearEdge+this.getEdgeProximityPenalty(t)*n,a=o.weightedMmNearFutureConnectionStartEnd+this.getFutureConnectionStartEndPenalty(t)*n,c=o.weightedMmNearFutureConnectionLine+this.getFutureConnectionLinePenalty(t)*n;let l=o.jumperPenalty,d=o.jumperPadFutureConnectionPenalty;t.isJumperExit\u0026\u0026(l+=this.jumperPenaltyDistance,d+=this.getJumperPadFutureConnectionPenalty(t));return{distFromStart:i,weightedMmNearObstacle:r,weightedMmNearEdge:s,weightedMmNearFutureConnectionStartEnd:a,weightedMmNearFutureConnectionLine:c,jumperPenalty:l,jumperPadFutureConnectionPenalty:d,total:i+r+s+a+c+l+d}}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 o of this.futureConnections)for(const i of o.points){const o=xe(t,i);o\u003ce\u0026\u0026(e=o,n=i)}return n}getFutureConnectionStartEndPenalty(t){let e=0;const n=this.getClosestFutureConnectionPoint(t);if(n){const o=xe(t,n);if(o\u003ethis.FUTURE_CONNECTION_START_END_PROXIMITY)return 0;const i=o/this.FUTURE_CONNECTION_START_END_PROXIMITY;e=this.FUTURE_CONNECTION_START_END_PENALTY*(1-i)**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\u003c2)continue;const o=be(t,n.points[0],n.points[n.points.length-1]);e=Math.min(e,o)}if(e*=n,e\u003cthis.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 o=1/0;for(const t of this.futureConnections)for(const i of t.points){const t=xe(e,i),r=xe(n,i),s=Math.min(t,r);o=Math.min(o,s)}if(o\u003cthis.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY){const t=o/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 o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){for(const o of Ont(n))e=Math.min(e,be(t,o.A,o.B));for(const o of n.jumpers||[])e=Math.min(e,this.distanceToJumperPads(t,o))}}return e}distanceToJumperPads(t,e){const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.abs(n)\u003eMath.abs(o),r=(i?Rnt:Ent)/2,s=(i?Ent:Rnt)/2;return Math.min(this.pointToRectDistance(t,e.start,r,s),this.pointToRectDistance(t,e.end,r,s))}pointToRectDistance(t,e,n,o){const i=Math.max(Math.abs(t.x-e.x)-n,0),r=Math.max(Math.abs(t.y-e.y)-o,0);return Math.hypot(i,r)}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)),o=this.OBSTACLE_PROX_SIGMA;return this.OBSTACLE_PROX_PENALTY_FACTOR*Math.exp(-n/o)}getEdgeProximityPenalty(t){const e=this.getClearanceToEdge(t),n=this.EDGE_PROX_SIGMA;if(e\u003e2*this.EDGE_PROX_SIGMA)return 0;const o=xe(t,this.B),i=Math.min(1,o/(2*this.EDGE_PROX_SIGMA));return this.EDGE_PROX_PENALTY_FACTOR*Math.exp(-e/n)*i}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)\u003cthis.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 o of n){const n=2*wnt,i=t.x+o.dx*n,r=t.y+o.dy*n,s=this.findObstaclesBetween(t,{x:i,y:r});if(s.length\u003e0)for(const n of s){const i=this.calculateJumperExit(t,n,o);i\u0026\u0026!this.exploredNodes.has(this.getNodeKey(i))\u0026\u0026(this.isNodeTooCloseToObstacle(i)||this.isNodeTooCloseToEdge(i)||!this.isJumperPlacementValid(t,i)||(i.gComponents=this.computeGComponents(i),i.hComponents=this.computeHComponents(i),i.g=i.gComponents.total,i.h=i.hComponents.total,i.f=this.computeF(i.g,i.h),e.push(i)))}}return e}calculateJumperExit(t,e,n){const o=wnt,i=Math.sqrt(n.dx*n.dx+n.dy*n.dy),r=n.dx/i,s=n.dy/i,a=t.x+r*o,c=t.y+s*o;return a\u003cthis.bounds.minX||a\u003ethis.bounds.maxX||c\u003cthis.bounds.minY||c\u003ethis.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,o=e.y-t.y,i=Math.abs(n)\u003eMath.abs(o),r=(i?Rnt:Ent)/2,s=(i?Ent:Rnt)/2,a=this.obstacleMargin,c=[t,e];for(const t of c){const e=[t,{x:t.x-r,y:t.y-s},{x:t.x+r,y:t.y-s},{x:t.x-r,y:t.y+s},{x:t.x+r,y:t.y+s},{x:t.x-r,y:t.y},{x:t.x+r,y:t.y},{x:t.x,y:t.y-s},{x:t.x,y:t.y+s}];for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(o)continue;const i=Ont(n);for(const n of i){for(const t of e)if(be(t,n.A,n.B)\u003cthis.traceThickness+a)return!0;if(this.doesSegmentIntersectRect(n.A,n.B,t,r+a,s+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 o=this.getJumpersInPath(t);for(const t of o)if(this.doJumpersOverlap(n,t))return!1;return!0}doJumpersOverlap(t,e){const n=this.obstacleMargin,o=Math.min(t.start.x,t.end.x)-Tnt/2-n,i=Math.max(t.start.x,t.end.x)+Tnt/2+n,r=Math.min(t.start.y,t.end.y)-Tnt/2-n,s=Math.max(t.start.y,t.end.y)+Tnt/2+n,a=Math.min(e.start.x,e.end.x)-Tnt/2-n,c=Math.max(e.start.x,e.end.x)+Tnt/2+n,l=Math.min(e.start.y,e.end.y)-Tnt/2-n,d=Math.max(e.start.y,e.end.y)+Tnt/2+n;return!(i\u003ca||o\u003ec||s\u003cl||r\u003ed)}getJumpersInPath(t){const e=[];let n=t;for(;n\u0026\u0026n.parent;)n.isJumperExit\u0026\u0026n.jumperEntry\u0026\u0026e.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:o,maxY:i,minY:r}=this.bounds;for(let s=-1;s\u003c=1;s++)for(let a=-1;a\u003c=1;a++){if(0===s\u0026\u00260===a)continue;if(!this.ALLOW_DIAGONAL\u0026\u00260!==s\u0026\u00260!==a)continue;const c=t.x+s*this.cellStep,l=t.y+a*this.cellStep,d=knt(c,o,n),h=knt(l,r,i),u={...t,parent:t,x:d,y:h,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 s=this.getJumperNeighbors(t);return e.push(...s),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\u003ce.length;t++){const o=e[t];o.isJumperExit\u0026\u0026o.jumperEntry\u0026\u0026n.push({route_type:\"jumper\",start:o.jumperEntry,end:{x:o.x,y:o.y},footprint:\"0603\"})}this.solvedPath={connectionName:this.connectionName,rootConnectionName:this.rootConnectionName,regionId:this.regionId,traceThickness:this.traceThickness,route:e.map(t=\u003e({x:t.x,y:t.y,z:0})).concat([{x:this.B.x,y:this.B.y,z:0}]),jumpers:n}}computeProgress(t,e){if(void 0===e)return Number.NaN;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\u0026\u0026e\u0026\u0026this.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=xe(t,this.roundedGoalPosition);this.progress=this.computeProgress(t,n),n\u003c=this.cellStep*Math.SQRT2\u0026\u0026!this.doesPathToParentIntersectObstacle({...t,parent:t,x:this.B.x,y:this.B.y})\u0026\u0026(this.solved=!0,this.setSolvedPath(t));const o=this.getNeighbors(t);for(const t of o)this.candidates.enqueue(t)}drawJumperPads(t,e,n,o,i,r){const s=e.end.x-e.start.x,a=e.end.y-e.start.y,c=Rnt,l=Ent,d=Math.abs(s)\u003eMath.abs(a),h=d?c:l,u=d?l:c;t.rects.push({center:{x:e.start.x,y:e.start.y},width:h,height:u,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:o??\"jumper\",step:i,label:r}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:h,height:u,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:o??\"jumper\",step:i,label:r}),t.lines.push({points:[e.start,e.end],strokeColor:\"rgba(100, 100, 100, 0.8)\",strokeWidth:.3*l,layer:o??\"jumper-body\",step:i,label:r})}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:Nnt(this.connectionName,this.rootConnectionName,[\"Input A\",`z: ${this.A.z}`]),color:\"orange\"}),t.points.push({x:this.B.x,y:this.B.y,label:Nnt(this.connectionName,this.rootConnectionName,[\"Input B\",`z: ${this.B.z}`]),color:\"orange\"}),t.lines.push({points:[this.A,this.B],strokeColor:\"rgba(255, 0, 0, 0.5)\",label:Nnt(this.connectionName,this.rootConnectionName,[\"Direct Input Connection\"])});for(let e=0;e\u003cthis.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let o=0;o\u003cn.route.length-1;o++)t.lines.push({points:[n.route[o],n.route[o+1]],strokeColor:\"rgba(255, 0, 0, 0.75)\",strokeWidth:n.traceThickness,label:Nnt(n.connectionName,n.rootConnectionName,[\"Obstacle Route\"]),layer:`obstacle${e.toString()}`});for(const o of n.jumpers||[])this.drawJumperPads(t,o,\"rgba(255, 0, 0, 0.5)\",`obstacle-jumper-${e}`,void 0,Nnt(n.connectionName,n.rootConnectionName,[\"Obstacle Jumper\"]))}for(let e=0;e\u003cthis.futureConnections.length;e++){const n=this.futureConnections[e];if(n.points.length\u003c2)continue;const o=n.points[0],i=n.points[n.points.length-1];t.lines.push({points:[o,i],strokeColor:\"rgba(0, 100, 255, 0.6)\",strokeWidth:this.traceThickness,label:Nnt(n.connectionName,n.rootConnectionName,[\"Future\"]),layer:`future-connection-${e}`})}for(let e=0;e\u003cthis.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[o,i]=n.split(\",\").map(Number),r=n.endsWith(\"_j\"),s=this.debug_exploredNodeValues.get(n),a=s?.gComponents,c=s?.hComponents,l=c?.distanceToGoal??0,d=[r?\"Explored (jumper)\":\"Explored\"];d.push(`g.distFromStart: ${a?.distFromStart.toFixed(2)??\"?\"}`),d.push(`g.nearObstacle: ${a?.weightedMmNearObstacle.toFixed(2)??\"?\"}`),d.push(`g.nearEdge: ${a?.weightedMmNearEdge.toFixed(2)??\"?\"}`),d.push(`g.nearFutStrtEnd: ${a?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??\"?\"}`),d.push(`g.nearFutLine: ${a?.weightedMmNearFutureConnectionLine.toFixed(2)??\"?\"}`),d.push(`g.jumper: ${a?.jumperPenalty.toFixed(2)??\"?\"}`),d.push(`g.jumperPadFutPenalty: ${a?.jumperPadFutureConnectionPenalty.toFixed(2)??\"?\"}`),d.push(`h.goalDist: ${l.toFixed(2)}`),d.push(`h.obstacleProx: ${c?.obstacleProximity.toFixed(2)??\"?\"} (${l\u003e0?((c?.obstacleProximity??0)/l).toFixed(3):0}/mm)`),d.push(`h.edgeProx: ${c?.edgeProximity.toFixed(2)??\"?\"} (${l\u003e0?((c?.edgeProximity??0)/l).toFixed(3):0}/mm)`),d.push(`h.futureConnPt: ${c?.futureConnectionStartEndProximityPenalty.toFixed(2)??\"?\"} (${l\u003e0?((c?.futureConnectionStartEndProximityPenalty??0)/l).toFixed(3):0}/mm)`),d.push(`h.futureConnLine: ${c?.futureConnectionLine.toFixed(2)??\"?\"} (${l\u003e0?((c?.futureConnectionLine??0)/l).toFixed(3):0}/mm)`),d.push(`g: ${s?.g.toFixed(2)??\"?\"}`),d.push(`h: ${s?.h.toFixed(2)??\"?\"}`),d.push(`f: ${s?.f.toFixed(2)??\"?\"}`);const h=d.join(\"\\n\");t.rects.push({center:{x:o+this.initialNodeGridOffset.x,y:i+this.initialNodeGridOffset.y},fill:r?`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:h})}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\u003ce.length;n++){const o=e[n],i=o.isJumperExit??!1,r=o.gComponents,s=o.hComponents,a=s?.distanceToGoal??0,c=[`Candidate #${n+1}${i?\" (jumper)\":\"\"}`];c.push(`g.distFromStart: ${r?.distFromStart.toFixed(2)??\"?\"}`),c.push(`g.nearObstacle: ${r?.weightedMmNearObstacle.toFixed(2)??\"?\"}`),c.push(`g.nearEdge: ${r?.weightedMmNearEdge.toFixed(2)??\"?\"}`),c.push(`g.nearFutureConnPt: ${r?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??\"?\"}`),c.push(`g.nearFutureConnLine: ${r?.weightedMmNearFutureConnectionLine.toFixed(2)??\"?\"}`),c.push(`g.jumper: ${r?.jumperPenalty.toFixed(2)??\"?\"}`),c.push(`g.jumperPadFutureConn: ${r?.jumperPadFutureConnectionPenalty.toFixed(2)??\"?\"}`),c.push(`g: ${o.g.toFixed(2)}`),c.push(`h.goalDist: ${a.toFixed(2)}`),c.push(`h.obstacleProx: ${s?.obstacleProximity.toFixed(2)??\"?\"} (${a\u003e0?((s?.obstacleProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.edgeProx: ${s?.edgeProximity.toFixed(2)??\"?\"} (${a\u003e0?((s?.edgeProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnPt: ${s?.futureConnectionStartEndProximityPenalty.toFixed(2)??\"?\"} (${a\u003e0?((s?.futureConnectionStartEndProximityPenalty??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnLine: ${s?.futureConnectionLine.toFixed(2)??\"?\"} (${a\u003e0?((s?.futureConnectionLine??0)/a).toFixed(3):0}/mm)`),c.push(`h: ${o.h.toFixed(2)}`),c.push(`f: ${o.f.toFixed(2)}`);const l=c.join(\"\\n\");t.points.push({x:o.x,y:o.y,color:\"gray\",label:l})}if(this.solvedPath){t.lines.push({points:this.solvedPath.route,strokeColor:\"green\",label:Nnt(this.solvedPath.connectionName,this.solvedPath.rootConnectionName,[\"Solved Route\"]),strokeWidth:this.traceThickness});for(const e of this.solvedPath.jumpers)this.drawJumperPads(t,e,\"rgba(0, 200, 0, 0.8)\",\"solved-jumper\",void 0,Nnt(this.solvedPath.connectionName,this.solvedPath.rootConnectionName,[\"Solved Jumper\"]))}const{minX:n,minY:o,maxX:i,maxY:r}=this.bounds;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:r},{x:n,y:r},{x:n,y:o}],strokeColor:\"rgba(255, 0, 0, 0.25)\",strokeDash:\"4 4\",layer:\"border\"}),t}};function Ont(t){const e=[];for(let n=0;n\u003ct.route.length-1;n++)if(t.route[n].z===t.route[n+1].z){const o=t.route[n],i=t.route[n+1],r=t.jumpers?.some(t=\u003e{const e=Math.abs(t.start.x-o.x)\u003c.001\u0026\u0026Math.abs(t.start.y-o.y)\u003c.001\u0026\u0026Math.abs(t.end.x-i.x)\u003c.001\u0026\u0026Math.abs(t.end.y-i.y)\u003c.001,n=Math.abs(t.start.x-i.x)\u003c.001\u0026\u0026Math.abs(t.start.y-i.y)\u003c.001\u0026\u0026Math.abs(t.end.x-o.x)\u003c.001\u0026\u0026Math.abs(t.end.y-o.y)\u003c.001;return e||n});r||e.push({z:o.z,A:o,B:i})}return e}function knt(t,e,n){return Math.max(e,Math.min(t,n))}var Lnt=.8,Dnt=.95,znt=(t,e,n=[])=\u003e[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join(\"\\n\"),Fnt=class extends si{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 o=new Map;for(const t of e.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}this.unsolvedConnections=[];for(const[t,e]of o){const n=Dr(e);for(const[e,o]of n)this.unsolvedConnections.push({connectionName:t,rootConnectionName:e.rootConnectionName??o.rootConnectionName,points:[{x:e.x,y:e.y,z:0},{x:o.x,y:o.y,z:0}]});if(0===n.length\u0026\u00261===e.length){const[n]=e;this.unsolvedConnections.push({connectionName:t,rootConnectionName:n?.rootConnectionName,points:n?[{x:n.x,y:n.y,z:0}]:[]})}}this.hyperParameters.SHUFFLE_SEED\u0026\u0026(this.unsolvedConnections=Xi(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=\u003e({...e,points:Xi(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Vi(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\u0026\u0026(this.failedSubSolvers.push(this.activeSubSolver),this.lastActiveSubSolver=this.activeSubSolver,this.activeSubSolver=null,this.error=this.failedSubSolvers.map(t=\u003et.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,o=Math.abs(e.x-n.x)\u003c1e-6,i=Math.abs(e.y-n.y)\u003c1e-6;if(o\u0026\u0026i)return}const{connectionName:e,rootConnectionName:n,points:o}=t;this.activeSubSolver=new Ant({connectionName:e,rootConnectionName:n,regionId:this.nodeWithPortPoints.capacityMeshNodeId,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:ro(this.nodeWithPortPoints),A:{x:o[0].x,y:o[0].y,z:0},B:{x:o[o.length-1].x,y:o[o.length-1].y,z:0},obstacleRoutes:this.solvedRoutes.filter(t=\u003e(!n||t.rootConnectionName!==n)\u0026\u0026!this.connMap?.areIdsConnected(t.connectionName,e)),futureConnections:this.unsolvedConnections,hyperParameters:this.hyperParameters,connMap:this.connMap,traceThickness:this.traceWidth})}drawJumperPads(t,e,n,o,i){const r=e.end.x-e.start.x,s=e.end.y-e.start.y,a=Lnt,c=Dnt,l=Math.abs(r)\u003eMath.abs(s),d=l?a:c,h=l?c:a;t.rects.push({center:{x:e.start.x,y:e.start.y},width:d,height:h,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:\"jumper\",label:i}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:d,height:h,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:\"jumper\",label:i}),t.lines.push({points:[e.start,e.end],strokeColor:\"rgba(100, 100, 100, 0.8)\",strokeWidth:.3*c,layer:\"jumper-body\",label:i})}visualize(){if(this.activeSubSolver\u0026\u0026!this.solved)return this.activeSubSolver.visualize();if(this.failed\u0026\u0026this.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:znt(e.connectionName,e.rootConnectionName,[\"layer: 0 (single-layer)\"]),color:this.colorMap[e.connectionName]??\"blue\"});for(let e=0;e\u003cthis.solvedRoutes.length;e++){const n=this.solvedRoutes[e];if(n.route.length\u003e0){const o=this.colorMap[n.connectionName]??\"blue\";for(let e=0;e\u003cn.route.length-1;e++){const i=n.route[e],r=n.route[e+1];t.lines.push({points:[i,r],strokeColor:To(o,.2),layer:\"route-layer-0\",strokeWidth:n.traceThickness,label:znt(n.connectionName,n.rootConnectionName,[\"layer: 0\"])})}for(const i of n.jumpers)this.drawJumperPads(t,i,To(o,.5),e,znt(n.connectionName,n.rootConnectionName,[\"jumper\"]))}}const e=ro(this.nodeWithPortPoints),{minX:n,minY:o,maxX:i,maxY:r}=e;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:r},{x:n,y:r},{x:n,y:o}],strokeColor:\"rgba(255, 0, 0, 0.25)\",strokeDash:\"4 4\",layer:\"border\"}),t}},Bnt=Ss;export{G9 as AUTOROUTER_VERSION,lnt as AssignableAutoroutingPipeline1Solver,Wl as AssignableAutoroutingPipeline2,ef as AssignableAutoroutingPipeline3,JX as AttachProjectedRectsSolver,yl as AutoroutingPipeline1_OriginalUnravel,rK as AutoroutingPipelineSolver,Bet as AutoroutingPipelineSolver10_BgaFanout,Jet as AutoroutingPipelineSolver11_Simplification,Pc as AutoroutingPipelineSolver2_PortPointPathing,Nf as AutoroutingPipelineSolver3_HgPortPointPathing,xX as AutoroutingPipelineSolver4,xX as AutoroutingPipelineSolver4_TinyHypergraph,EX as AutoroutingPipelineSolver5,EX as AutoroutingPipelineSolver5_HdCache,rG as AutoroutingPipelineSolver6,rG as AutoroutingPipelineSolver6_PolyHypergraph,rK as AutoroutingPipelineSolver7_MultiGraph,lK as AutoroutingPipelineSolver8,y8 as AutoroutingPipelineSolver9_Networked,H9 as AutoroutingPipelineSolver9_PreloadedTraceGraph,Mc as CapacityMeshSolver,Pd as CurvyIntraNodeSolver,n8 as DEFAULT_HD_CACHE2_SERVER_URL,wz as GlobalDrcBranchPortfolioSolver,Nz as GlobalDrcForceImproveSolver,Ls as GrowShrinkHighDensityIntraNodeSolver,Qg as HighDensitySolver,Bnt as HyperSingleIntraNodeSolver,Qn as InMemoryCache,Fnt as IntraNodeSolverWithJumpers,eo as LocalStorageCache,g8 as PIPELINE9_NETWORKED_SOLVE_POLICY,QX as PolyHighDensitySolver,KX as PolyIntraNodeSolver,KX as PolySingleIntraNodeSolver,Ss as PortfolioSingleIntraNodeSolver,oG as ProjectHighDensityToPolygonSolver,Ant as SingleHighDensityRouteWithJumpersSolver,$s as calculateOptimalCapacityDepth,Ho as convertSrjToGraphicsObject,oo as getGlobalInMemoryCache,no as getGlobalLocalStorageCache,Pnt as getRerouteSimpleRouteJson,js as getTunedTotalCapacity1,Mnt as reconnectReroutedSimpleRouteJsonRegion,io as setupGlobalCaches,_8 as solvePipeline9NetworkedHighDensityNode};\n/*! Bundled license information:\n\nis-buffer/index.js:\n (*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh \u003chttps://feross.org\u003e\n * @license MIT\n *)\n\ndeep-rename-keys/index.js:\n (*!\n * deep-rename-keys \u003chttps://github.com/jonschlinkert/deep-rename-keys\u003e\n *\n * Copyright (c) 2015 Jon Schlinkert, contributors.\n * Licensed under the MIT license.\n *)\n\n@tscircuit/curvy-trace-solver/dist/index.js:\n@tscircuit/find-convex-regions/dist/index.js:\n (*! Bundled license information:\n \n is-buffer/index.js:\n (*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh \u003chttps://feross.org\u003e\n * @license MIT\n *)\n \n deep-rename-keys/index.js:\n (*!\n * deep-rename-keys \u003chttps://github.com/jonschlinkert/deep-rename-keys\u003e\n *\n * Copyright (c) 2015 Jon Schlinkert, contributors.\n * Licensed under the MIT license.\n *)\n *)\n\n@tscircuit/hypergraph/dist/index.js:\n (*! Bundled license information:\n \n @tscircuit/find-convex-regions/dist/index.js:\n (*! Bundled license information:\n \n is-buffer/index.js:\n (*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh \u003chttps://feross.org\u003e\n * @license MIT\n *)\n \n deep-rename-keys/index.js:\n (*!\n * deep-rename-keys \u003chttps://github.com/jonschlinkert/deep-rename-keys\u003e\n *\n * Copyright (c) 2015 Jon Schlinkert, contributors.\n * Licensed under the MIT license.\n *)\n *)\n *)\n*///# sourceMappingURL=index.js.map","content_mimetype":"text/javascript","created_at":"2026-09-08T16:51:04.318Z"}; window.SSR_PACKAGE_RELEASES = [{"package_release_id":"dadcc3e3-2713-4e98-887f-4b6137bd5354","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.21","github_commit_sha":null,"is_locked":false,"is_latest":true,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-09-08T16:51:00.213Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-c972a675127a917f4275e6ed2e8d118e","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=dadcc3e3-2713-4e98-887f-4b6137bd5354\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=dadcc3e3-2713-4e98-887f-4b6137bd5354\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=dadcc3e3-2713-4e98-887f-4b6137bd5354\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"87ce88af-6ebc-4d18-8566-4157e21ea81e","user_code_job_started_at":"2026-09-08T16:52:33.622Z","user_code_job_completed_at":"2026-09-08T16:59:59.297Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=d6b4ee33048d45c49f3c2aa07288211b524699d6de79c1297a7ac825a214cef2","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"1bd43346-33f3-4cde-bfc0-0d0f5ef7be46","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.20","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-09-08T15:16:56.192Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-d11498066a18b91f14cfef35200ce692","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1bd43346-33f3-4cde-bfc0-0d0f5ef7be46\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1bd43346-33f3-4cde-bfc0-0d0f5ef7be46\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1bd43346-33f3-4cde-bfc0-0d0f5ef7be46\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"25ade5eb-73d1-47ce-9823-5f98374536ec","user_code_job_started_at":"2026-09-08T15:18:02.030Z","user_code_job_completed_at":"2026-09-08T15:25:40.398Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=89a479e0fa012d7b67eda0b76d5ebc3715268e252699e7ddd07a3464689ff513","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8c74453a-83e2-4172-bcda-666d01f22b9f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.19","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-09-08T15:06:14.644Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-d91e0490b469149ed15fbb1a51ebd6c4","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"1eb0a04c-ecf7-497e-af22-0e9b9527afed","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.18","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-09-08T14:59:07.818Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-d29c5c93da4790e226795ec61a311545","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"310748ea-1f54-4e0b-bcb0-e26de0418bbe","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.17","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-20T09:08:27.021Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-3ab68ad76231274fced8daa9b4d216d1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"31871f8c-83e2-47f0-968e-30522688d9b6","user_code_job_started_at":"2026-09-07T20:49:28.128Z","user_code_job_completed_at":"2026-09-07T21:05:41.129Z","user_code_job_error":{"message":"Your code failed to build (exit code 1), see build logs for the error details","error_code":"user_code_build_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=295f4c032a00680940217b249f3b3f4fc21ade71a404fb9d8dd81770696f8397","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"de03c299-1b05-400b-9a9e-29d42c16b2bc","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.16","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-17T16:56:08.078Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-d8dbda73d7ae6158f52f028821fc56ee","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"3bf37cdc-0107-4eac-9892-f247c5e18661","user_code_job_started_at":"2026-08-17T16:58:40.245Z","user_code_job_completed_at":"2026-08-17T17:28:41.191Z","user_code_job_error":{"message":"Build timed out after 30 minutes","error_code":"user_code_job_timeout"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=76d319070ca1fa7f302a7515628d2639daeeecb6a5981c696f85e46107e3b9b9","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"0e701bc3-f617-464c-b79c-8117d2c86339","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.15","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-12T16:15:42.323Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-1d696f35b011352aeb71a3a73b619442","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0e701bc3-f617-464c-b79c-8117d2c86339\u0026file_path=dist%2Fleft%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0e701bc3-f617-464c-b79c-8117d2c86339\u0026file_path=dist%2Fleft%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0e701bc3-f617-464c-b79c-8117d2c86339\u0026file_path=dist%2Fleft%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"b70c43ef-2eed-47b4-b330-04f89859db6a","user_code_job_started_at":"2026-08-12T19:18:18.738Z","user_code_job_completed_at":"2026-08-12T19:28:03.200Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=12aa44a3f0616a1a15b3a1b0b9f58c05bbb5a610306d691dd1254f2acd6c484b","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"051bc4bf-1895-4c06-848e-06f0dca2393d","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.14","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-12T15:57:48.194Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-0c5e9892ec1ff3b912eed0a8c52f86d6","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"27e8a9f6-e7eb-447a-8734-0d94020b0275","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.13","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-12T15:50:05.533Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-9c0370a7e35c6d29e28e2ecfd1a35f0d","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"09680cad-cb3a-43bc-b3d9-3977d56d794c","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.12","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-12T15:44:02.661Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-5db3a4d5fec54b23a1879189c3ae3cbb","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"9800209a-d5a4-4a4b-940a-d0269c8f63b6","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.11","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-11T15:04:42.562Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-566054e353ef8fe7b66172bc2fae98b0","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9800209a-d5a4-4a4b-940a-d0269c8f63b6\u0026file_path=dist%2Fleft%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9800209a-d5a4-4a4b-940a-d0269c8f63b6\u0026file_path=dist%2Fleft%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9800209a-d5a4-4a4b-940a-d0269c8f63b6\u0026file_path=dist%2Fleft%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"30a6cf6d-8331-40a2-88c1-c288ec518721","user_code_job_started_at":"2026-08-12T06:03:29.394Z","user_code_job_completed_at":"2026-08-12T06:05:35.547Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=9786155159a44073aca7f275639c5bba8096798efe9ea7bbec0ac5bff5dbbff4","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"dfee26ad-0833-46ab-80ba-c79f11c42204","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.10","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-11T15:00:53.088Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-3323412296cadec0032dc46d61871214","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"ab72b3d5-3b6f-492c-97d2-683e46ee727f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.9","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-10T12:08:14.180Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-c3f01b7ce05c51934f420bc6f5a6bef2","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ab72b3d5-3b6f-492c-97d2-683e46ee727f\u0026file_path=dist%2Fleft%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ab72b3d5-3b6f-492c-97d2-683e46ee727f\u0026file_path=dist%2Fleft%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ab72b3d5-3b6f-492c-97d2-683e46ee727f\u0026file_path=dist%2Fleft%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"a09c97ff-fc3a-43f6-adb6-fdecc09ac5a4","user_code_job_started_at":"2026-08-10T12:14:11.619Z","user_code_job_completed_at":"2026-08-10T12:22:41.299Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=bd272eacf6b19c9d8bca9ff7025a50289e8cc5dcce91b374d4398239f9b8fdc6","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"aab741d2-66d6-4141-a56f-dec9a93f0745","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.8","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T12:05:54.107Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":null,"circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8d099371-81f4-4556-9b50-06c5ff43530c","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.7","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T12:01:26.302Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-90b8b592fc532bc050dfa0051f22721d","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"b5644906-1850-4f7e-bc7f-384131bc85d5","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.6","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T11:57:22.892Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-645c7d3e9b78aedbd409f63ea760ff03","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"bf68f755-3410-47ae-a8f7-bf1842ede84f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.5","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-10T10:36:56.206Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-fae103c87d843cdbb7d5853edd5e00a1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"62b3be01-12c5-415f-af59-2eb8cd87f0a2","user_code_job_started_at":"2026-08-10T10:39:53.625Z","user_code_job_completed_at":"2026-08-10T10:46:01.744Z","user_code_job_error":{"message":"Your code failed to build (exit code 1), see build logs for the error details","error_code":"user_code_build_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=5b7af5faf2794cb43b7c2ef0edf4af78aee1d8f2cbf54dc1148ababea99e1991","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"12026e15-765c-488a-9886-a89e93409099","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.4","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T10:32:18.439Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-640370fe7412c50c2a81985dc4c85ea1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"49831c5f-ff27-4706-b8d9-7a0fe1662179","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.3","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T10:28:40.595Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-abd2412878570b9cbce9d060b8e64f90","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"2bbe2022-8ce9-4466-bce4-9d3460eb7620","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T10:24:34.733Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-0c6ef3495ed62c8311da6c2a4a5ce1f1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"511d059e-9f7c-4d44-b609-44cd623b4972","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-09T20:30:50.584Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-932b3b7914f4275cc095769b0f588268","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"af3b8d2e-6b0e-4354-9c73-14b62b65bd8d","user_code_job_started_at":"2026-08-10T09:05:50.472Z","user_code_job_completed_at":"2026-08-10T09:11:56.569Z","user_code_job_error":{"message":"Your code failed to build (exit code 1), see build logs for the error details","error_code":"user_code_build_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=858f0f5564ef737003bbfa6e781aeca055df3ed980065067ac7a494d91462263","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"0c2b43a3-54ff-41cc-9c2a-3c072a4bfce4","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-09T20:27:15.716Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-09c3251b45a913a702805e1ecccbb7b5","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"6243441b-092b-4166-b003-a232a9cb59ff","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.3","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-06T14:45:44.407Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-f8665c2de359b48d96d3d32c1ca7d0f8","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"3fcb8ef5-0e39-440c-a18f-1c682ef1e73d","user_code_job_started_at":"2026-08-06T14:45:50.004Z","user_code_job_completed_at":"2026-08-06T14:49:33.535Z","user_code_job_error":{"message":"There was an error running the job on our infrastructure, this is probably not your code, see build logs","error_code":"user_code_job_infrastructure_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=cbd18a5931f35b3cf6d4679c66ba2eeffba4e991283dff69751626b4d0c8bd62","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8c27b90d-b11f-403c-8691-41f218374a8f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-06T13:40:38.469Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-e220e519e921d21de687f0af4239252c","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"ea20fb0d-e807-43f9-ba83-8978b2a9cd04","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-06T13:38:39.968Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-234591a7f9c087d813fd8d5ecbda0d46","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ea20fb0d-e807-43f9-ba83-8978b2a9cd04\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ea20fb0d-e807-43f9-ba83-8978b2a9cd04\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ea20fb0d-e807-43f9-ba83-8978b2a9cd04\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"5155b2ea-d7ed-41fc-80c6-d6311b4b55b4","user_code_job_started_at":"2026-08-06T13:38:48.763Z","user_code_job_completed_at":"2026-08-06T13:40:21.516Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=2d9c8a936d46c3ed4f25c54515d1eb4ff16872ade7b430062b7a024bd40f6dee","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-06T13:15:02.283Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-1def03398d147a237eb937a952295e79","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"97b18410-03ef-4231-98d7-89ecd9b787a4","user_code_job_started_at":"2026-08-06T13:15:08.904Z","user_code_job_completed_at":"2026-08-06T13:16:24.373Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=279a064e6ac1ab57ef793fb8ad3a32d71e6b5262e3dd6104e362a8d55c2f7b68","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null}]; window.SSR_PACKAGE_BUILDS = []; window.SSR_RELATED_PACKAGES = [{"package_id":"307fe261-5d71-417c-bc01-7835cd4f4abe","creator_account_id":"96f144ef-7dfe-4068-aac0-8753c8ab5f62","latest_package_release_id":"3c938c18-451d-4aea-8ecc-b5e5f561e6c6","last_built_release_id":"3c938c18-451d-4aea-8ecc-b5e5f561e6c6","latest_package_release_fs_sha":"md5-d17042528d94ca0759bc1345f41464bb","latest_pcb_preview_image_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.2","license":"unset","owner_org_id":"f46c84e5-2ffb-44f6-a4fa-47ad19769e7a","org_owner_tscircuit_handle":"test-1","owner_github_username":"test-1","github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"imrishabh18/boost-converter","unscoped_name":"boost-converter","star_count":0,"created_at":"2026-05-18T12:43:26.451Z","updated_at":"2026-05-19T18:52:38.681Z","ai_description":"This code defines a PCB schematic and 3D model layout focusing on a power conversion circuit with components like USB-C connector, MT3608 step-up regulator, inductor, diode, input/output capacitors, and resistors arranged on a double-layer PCB.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"same_author","thumbnail_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2Fpcb.svg"},{"package_id":"1bb71080-c9d9-4806-8dad-9546e8b9913b","creator_account_id":"03854e77-22c2-44a0-9cfc-2d4ed6741105","latest_package_release_id":"92d10956-aa95-4eba-8e98-42e66c16f463","last_built_release_id":"92d10956-aa95-4eba-8e98-42e66c16f463","latest_package_release_fs_sha":"md5-73c7349eef4667e7cbc7beecb7e35036","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.5","license":"unset","owner_org_id":"7978967e-b956-4ac2-b813-667a08f6310a","org_owner_tscircuit_handle":"abse","owner_github_username":null,"github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"abse/boostxl-uln2003","unscoped_name":"boostxl-uln2003","star_count":0,"created_at":"2026-08-12T10:10:06.978Z","updated_at":"2026-08-12T22:29:23.783Z","ai_description":"This code defines a React component that models a through-hole or surface-mount LED with specified pin labels, footprint, silkscreen, and 3D CAD model for PCB layout.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"similar_ai_description","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2Fpcb.svg"},{"package_id":"7065b9a6-03de-43a1-ba42-2a0ead33b548","creator_account_id":"1f745cb8-1b99-4215-905f-f8e3dc29bc28","latest_package_release_id":"5746ef1e-d91a-4043-9db3-2cc17f89d777","last_built_release_id":"5746ef1e-d91a-4043-9db3-2cc17f89d777","latest_package_release_fs_sha":"md5-27fc15676f25d1e3a229466d1de0fe7a","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.1","license":"unset","owner_org_id":"60917f07-d371-4c51-854f-e2bd7dab9e5a","org_owner_tscircuit_handle":"hrithik18k","owner_github_username":null,"github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"hrithik18k/smart-switch-pcb","unscoped_name":"smart-switch-pcb","star_count":0,"created_at":"2026-09-09T11:12:10.428Z","updated_at":"2026-09-09T11:56:59.112Z","ai_description":"The AO3400A component models a SOT-23 N-channel MOSFET with labeled pins for Gate, Source, and Drain, including 3D CAD models and schematic symbols for electronic circuit design.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"random","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fpcb.svg"}]; window.SSR_PACKAGE_ROUTE = {"author":"imrishabh18","packageName":"corne-keyboard","packageNameWithScope":"imrishabh18/corne-keyboard","version":null,"isLegacyRoute":false,"kind":"file","filePath":"debug-autorouter.mjs"};
),{});a(k_,{BRAND:()=>mx,DIRTY:()=>J_,EMPTY_PATH:()=>W_,INVALID:()=>q_,NEVER:()=>cv,OK:()=>K_,ParseStatus:()=>Z_,Schema:()=>ab,ZodAny:()=>Bb,ZodArray:()=>Xb,ZodBigInt:()=>Ob,ZodBoolean:()=>kb,ZodBranded:()=>gx,ZodCatch:()=>ux,ZodDate:()=>Lb,ZodDefault:()=>hx,ZodDiscriminatedUnion:()=>Ub,ZodEffects:()=>cx,ZodEnum:()=>rx,ZodError:()=>B_,ZodFirstPartyTypeKind:()=>xx,ZodFunction:()=>ex,ZodIntersection:()=>qb,ZodIssueCode:()=>z_,ZodLazy:()=>nx,ZodLiteral:()=>ox,ZodMap:()=>Qb,ZodNaN:()=>px,ZodNativeEnum:()=>sx,ZodNever:()=>$b,ZodNull:()=>Fb,ZodNullable:()=>dx,ZodNumber:()=>Ab,ZodObject:()=>Wb,ZodOptional:()=>lx,ZodParsedType:()=>L_,ZodPipeline:()=>fx,ZodPromise:()=>ax,ZodReadonly:()=>yx,ZodRecord:()=>Kb,ZodSchema:()=>ab,ZodSet:()=>tx,ZodString:()=>Rb,ZodSymbol:()=>Db,ZodTransformer:()=>cx,ZodTuple:()=>Jb,ZodType:()=>ab,ZodUndefined:()=>zb,ZodUnion:()=>Hb,ZodUnknown:()=>jb,ZodVoid:()=>Yb,addIssueToContext:()=>H_,any:()=>Ox,array:()=>zx,bigint:()=>Nx,boolean:()=>wx,coerce:()=>av,custom:()=>bx,date:()=>Tx,datetimeRegex:()=>Mb,defaultErrorMap:()=>j_,discriminatedUnion:()=>$x,effect:()=>Qx,enum:()=>qx,function:()=>Gx,getErrorMap:()=>X_,getParsedType:()=>D_,instanceof:()=>Ix,intersection:()=>Yx,isAborted:()=>Q_,isAsync:()=>nb,isDirty:()=>tb,isValid:()=>eb,late:()=>Sx,lazy:()=>Ux,literal:()=>Zx,makeIssue:()=>V_,map:()=>Wx,nan:()=>Mx,nativeEnum:()=>Jx,never:()=>Lx,null:()=>Ax,nullable:()=>ev,number:()=>Px,object:()=>Fx,objectUtil:()=>A_,oboolean:()=>sv,onumber:()=>rv,optional:()=>tv,ostring:()=>iv,pipeline:()=>ov,preprocess:()=>nv,promise:()=>Kx,quotelessJson:()=>F_,record:()=>Vx,set:()=>Hx,setErrorMap:()=>Y_,strictObject:()=>Bx,string:()=>Cx,symbol:()=>Rx,transformer:()=>Qx,tuple:()=>Xx,undefined:()=>Ex,union:()=>jx,unknown:()=>kx,util:()=>R_,void:()=>Dx}),(E_=R_||(R_={})).assertEqual=t=>{},E_.assertIs=function(t){},E_.assertNever=function(t){throw new Error},E_.arrayToEnum=t=>{const e={};for(const n of t)e[n]=n;return e},E_.getValidEnumValues=t=>{const e=E_.objectKeys(t).filter(e=>"number"!=typeof t[t[e]]),n={};for(const o of e)n[o]=t[o];return E_.objectValues(n)},E_.objectValues=t=>E_.objectKeys(t).map(function(e){return t[e]}),E_.objectKeys="function"==typeof Object.keys?t=>Object.keys(t):t=>{const e=[];for(const n in t)Object.prototype.hasOwnProperty.call(t,n)&&e.push(n);return e},E_.find=(t,e)=>{for(const n of t)if(e(n))return n},E_.isInteger="function"==typeof Number.isInteger?t=>Number.isInteger(t):t=>"number"==typeof t&&Number.isFinite(t)&&Math.floor(t)===t,E_.joinValues=function(t,e=" | "){return t.map(t=>"string"==typeof t?`'${t}'`:t).join(e)},E_.jsonStringifyReplacer=(t,e)=>"bigint"==typeof e?e.toString():e,(A_||(A_={})).mergeShapes=(t,e)=>({...t,...e});var L_=R_.arrayToEnum(["string","nan","number","integer","float","boolean","date","bigint","symbol","function","undefined","null","array","object","unknown","promise","void","never","map","set"]),D_=t=>{switch(typeof t){case"undefined":return L_.undefined;case"string":return L_.string;case"number":return Number.isNaN(t)?L_.nan:L_.number;case"boolean":return L_.boolean;case"function":return L_.function;case"bigint":return L_.bigint;case"symbol":return L_.symbol;case"object":return Array.isArray(t)?L_.array:null===t?L_.null:t.then&&"function"==typeof t.then&&t.catch&&"function"==typeof t.catch?L_.promise:"undefined"!=typeof Map&&t instanceof Map?L_.map:"undefined"!=typeof Set&&t instanceof Set?L_.set:"undefined"!=typeof Date&&t instanceof Date?L_.date:L_.object;default:return L_.unknown}},z_=R_.arrayToEnum(["invalid_type","invalid_literal","custom","invalid_union","invalid_union_discriminator","invalid_enum_value","unrecognized_keys","invalid_arguments","invalid_return_type","invalid_date","invalid_string","too_small","too_big","invalid_intersection_types","not_multiple_of","not_finite"]),F_=t=>JSON.stringify(t,null,2).replace(/"([^"]+)":/g,"$1:"),B_=class t extends Error{get errors(){return this.issues}constructor(t){super(),this.issues=[],this.addIssue=t=>{this.issues=[...this.issues,t]},this.addIssues=(t=[])=>{this.issues=[...this.issues,...t]};const e=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,e):this.__proto__=e,this.name="ZodError",this.issues=t}format(t){const e=t||function(t){return t.message},n={_errors:[]},o=t=>{for(const i of t.issues)if("invalid_union"===i.code)i.unionErrors.map(o);else if("invalid_return_type"===i.code)o(i.returnTypeError);else if("invalid_arguments"===i.code)o(i.argumentsError);else if(0===i.path.length)n._errors.push(e(i));else{let t=n,o=0;for(;o<i.path.length;){const n=i.path[o];o===i.path.length-1?(t[n]=t[n]||{_errors:[]},t[n]._errors.push(e(i))):t[n]=t[n]||{_errors:[]},t=t[n],o++}}};return o(this),n}static assert(e){if(!(e instanceof t))throw new Error(`Not a ZodError: ${e}`)}toString(){return this.message}get message(){return JSON.stringify(this.issues,R_.jsonStringifyReplacer,2)}get isEmpty(){return 0===this.issues.length}flatten(t=t=>t.message){const e={},n=[];for(const o of this.issues)if(o.path.length>0){const n=o.path[0];e[n]=e[n]||[],e[n].push(t(o))}else n.push(t(o));return{formErrors:n,fieldErrors:e}}get formErrors(){return this.flatten()}};B_.create=t=>new B_(t);var j_=(t,e)=>{let n;switch(t.code){case z_.invalid_type:n=t.received===L_.undefined?"Required":`Expected ${t.expected}, received ${t.received}`;break;case z_.invalid_literal:n=`Invalid literal value, expected ${JSON.stringify(t.expected,R_.jsonStringifyReplacer)}`;break;case z_.unrecognized_keys:n=`Unrecognized key(s) in object: ${R_.joinValues(t.keys,", ")}`;break;case z_.invalid_union:n="Invalid input";break;case z_.invalid_union_discriminator:n=`Invalid discriminator value. Expected ${R_.joinValues(t.options)}`;break;case z_.invalid_enum_value:n=`Invalid enum value. Expected ${R_.joinValues(t.options)}, received '${t.received}'`;break;case z_.invalid_arguments:n="Invalid function arguments";break;case z_.invalid_return_type:n="Invalid function return type";break;case z_.invalid_date:n="Invalid date";break;case z_.invalid_string:"object"==typeof t.validation?"includes"in t.validation?(n=`Invalid input: must include "${t.validation.includes}"`,"number"==typeof t.validation.position&&(n=`${n} at one or more positions greater than or equal to ${t.validation.position}`)):"startsWith"in t.validation?n=`Invalid input: must start with "${t.validation.startsWith}"`:"endsWith"in t.validation?n=`Invalid input: must end with "${t.validation.endsWith}"`:R_.assertNever(t.validation):n="regex"!==t.validation?`Invalid ${t.validation}`:"Invalid";break;case z_.too_small:n="array"===t.type?`Array must contain ${t.exact?"exactly":t.inclusive?"at least":"more than"} ${t.minimum} element(s)`:"string"===t.type?`String must contain ${t.exact?"exactly":t.inclusive?"at least":"over"} ${t.minimum} character(s)`:"number"===t.type||"bigint"===t.type?`Number must be ${t.exact?"exactly equal to ":t.inclusive?"greater than or equal to ":"greater than "}${t.minimum}`:"date"===t.type?`Date must be ${t.exact?"exactly equal to ":t.inclusive?"greater than or equal to ":"greater than "}${new Date(Number(t.minimum))}`:"Invalid input";break;case z_.too_big:n="array"===t.type?`Array must contain ${t.exact?"exactly":t.inclusive?"at most":"less than"} ${t.maximum} element(s)`:"string"===t.type?`String must contain ${t.exact?"exactly":t.inclusive?"at most":"under"} ${t.maximum} character(s)`:"number"===t.type?`Number must be ${t.exact?"exactly":t.inclusive?"less than or equal to":"less than"} ${t.maximum}`:"bigint"===t.type?`BigInt must be ${t.exact?"exactly":t.inclusive?"less than or equal to":"less than"} ${t.maximum}`:"date"===t.type?`Date must be ${t.exact?"exactly":t.inclusive?"smaller than or equal to":"smaller than"} ${new Date(Number(t.maximum))}`:"Invalid input";break;case z_.custom:n="Invalid input";break;case z_.invalid_intersection_types:n="Intersection results could not be merged";break;case z_.not_multiple_of:n=`Number must be a multiple of ${t.multipleOf}`;break;case z_.not_finite:n="Number must be finite";break;default:n=e.defaultError,R_.assertNever(t)}return{message:n}},$_=j_;function Y_(t){$_=t}function X_(){return $_}var V_=t=>{const{data:e,path:n,errorMaps:o,issueData:i}=t,r=[...n,...i.path||[]],s={...i,path:r};if(void 0!==i.message)return{...i,path:r,message:i.message};let a="";const c=o.filter(t=>!!t).slice().reverse();for(const t of c)a=t(s,{data:e,defaultError:a}).message;return{...i,path:r,message:a}},W_=[];function H_(t,e){const n=X_(),o=V_({issueData:e,data:t.data,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,n,n===j_?void 0:j_].filter(t=>!!t)});t.common.issues.push(o)}var G_,U_,Z_=class t{constructor(){this.value="valid"}dirty(){"valid"===this.value&&(this.value="dirty")}abort(){"aborted"!==this.value&&(this.value="aborted")}static mergeArray(t,e){const n=[];for(const o of e){if("aborted"===o.status)return q_;"dirty"===o.status&&t.dirty(),n.push(o.value)}return{status:t.value,value:n}}static async mergeObjectAsync(e,n){const o=[];for(const t of n){const e=await t.key,n=await t.value;o.push({key:e,value:n})}return t.mergeObjectSync(e,o)}static mergeObjectSync(t,e){const n={};for(const o of e){const{key:e,value:i}=o;if("aborted"===e.status)return q_;if("aborted"===i.status)return q_;"dirty"===e.status&&t.dirty(),"dirty"===i.status&&t.dirty(),"__proto__"===e.value||void 0===i.value&&!o.alwaysSet||(n[e.value]=i.value)}return{status:t.value,value:n}}},q_=Object.freeze({status:"aborted"}),J_=t=>({status:"dirty",value:t}),K_=t=>({status:"valid",value:t}),Q_=t=>"aborted"===t.status,tb=t=>"dirty"===t.status,eb=t=>"valid"===t.status,nb=t=>"undefined"!=typeof Promise&&t instanceof Promise;(U_=G_||(G_={})).errToObj=t=>"string"==typeof t?{message:t}:t||{},U_.toString=t=>"string"==typeof t?t:t?.message;var ob=class{constructor(t,e,n,o){this._cachedPath=[],this.parent=t,this.data=e,this._path=n,this._key=o}get path(){return this._cachedPath.length||(Array.isArray(this._key)?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}},ib=(t,e)=>{if(eb(e))return{success:!0,data:e.value};if(!t.common.issues.length)throw new Error("Validation failed but no issues detected.");return{success:!1,get error(){if(this._error)return this._error;const e=new B_(t.common.issues);return this._error=e,this._error}}};function rb(t){if(!t)return{};const{errorMap:e,invalid_type_error:n,required_error:o,description:i}=t;if(e&&(n||o))throw new Error('Can\'t use "invalid_type_error" or "required_error" in conjunction with custom error map.');if(e)return{errorMap:e,description:i};return{errorMap:(e,i)=>{const{message:r}=t;return"invalid_enum_value"===e.code?{message:r??i.defaultError}:void 0===i.data?{message:r??o??i.defaultError}:"invalid_type"!==e.code?{message:i.defaultError}:{message:r??n??i.defaultError}},description:i}}var sb,ab=class{get description(){return this._def.description}_getType(t){return D_(t.data)}_getOrReturnCtx(t,e){return e||{common:t.parent.common,data:t.data,parsedType:D_(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}_processInputParams(t){return{status:new Z_,ctx:{common:t.parent.common,data:t.data,parsedType:D_(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}}_parseSync(t){const e=this._parse(t);if(nb(e))throw new Error("Synchronous parse encountered promise.");return e}_parseAsync(t){const e=this._parse(t);return Promise.resolve(e)}parse(t,e){const n=this.safeParse(t,e);if(n.success)return n.data;throw n.error}safeParse(t,e){const n={common:{issues:[],async:e?.async??!1,contextualErrorMap:e?.errorMap},path:e?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)},o=this._parseSync({data:t,path:n.path,parent:n});return ib(n,o)}"~validate"(t){const e={common:{issues:[],async:!!this["~standard"].async},path:[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)};if(!this["~standard"].async)try{const n=this._parseSync({data:t,path:[],parent:e});return eb(n)?{value:n.value}:{issues:e.common.issues}}catch(t){t?.message?.toLowerCase()?.includes("encountered")&&(this["~standard"].async=!0),e.common={issues:[],async:!0}}return this._parseAsync({data:t,path:[],parent:e}).then(t=>eb(t)?{value:t.value}:{issues:e.common.issues})}async parseAsync(t,e){const n=await this.safeParseAsync(t,e);if(n.success)return n.data;throw n.error}async safeParseAsync(t,e){const n={common:{issues:[],contextualErrorMap:e?.errorMap,async:!0},path:e?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)},o=this._parse({data:t,path:n.path,parent:n}),i=await(nb(o)?o:Promise.resolve(o));return ib(n,i)}refine(t,e){const n=t=>"string"==typeof e||void 0===e?{message:e}:"function"==typeof e?e(t):e;return this._refinement((e,o)=>{const i=t(e),r=()=>o.addIssue({code:z_.custom,...n(e)});return"undefined"!=typeof Promise&&i instanceof Promise?i.then(t=>!!t||(r(),!1)):!!i||(r(),!1)})}refinement(t,e){return this._refinement((n,o)=>!!t(n)||(o.addIssue("function"==typeof e?e(n,o):e),!1))}_refinement(t){return new cx({schema:this,typeName:xx.ZodEffects,effect:{type:"refinement",refinement:t}})}superRefine(t){return this._refinement(t)}constructor(t){this.spa=this.safeParseAsync,this._def=t,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this),this["~standard"]={version:1,vendor:"zod",validate:t=>this["~validate"](t)}}optional(){return lx.create(this,this._def)}nullable(){return dx.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return Xb.create(this)}promise(){return ax.create(this,this._def)}or(t){return Hb.create([this,t],this._def)}and(t){return qb.create(this,t,this._def)}transform(t){return new cx({...rb(this._def),schema:this,typeName:xx.ZodEffects,effect:{type:"transform",transform:t}})}default(t){const e="function"==typeof t?t:()=>t;return new hx({...rb(this._def),innerType:this,defaultValue:e,typeName:xx.ZodDefault})}brand(){return new gx({typeName:xx.ZodBranded,type:this,...rb(this._def)})}catch(t){const e="function"==typeof t?t:()=>t;return new ux({...rb(this._def),innerType:this,catchValue:e,typeName:xx.ZodCatch})}describe(t){return new(0,this.constructor)({...this._def,description:t})}pipe(t){return fx.create(this,t)}readonly(){return yx.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}},cb=/^c[^\s-]{8,}$/i,lb=/^[0-9a-z]+$/,db=/^[0-9A-HJKMNP-TV-Z]{26}$/i,hb=/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i,ub=/^[a-z0-9_-]{21}$/i,pb=/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/,mb=/^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/,gb=/^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i,fb=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,yb=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/,_b=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,bb=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,xb=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,vb=/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,Sb="((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))",Ib=new RegExp(`^${Sb}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
),{});a(k_,{BRAND:()=\u003emx,DIRTY:()=\u003eJ_,EMPTY_PATH:()=\u003eW_,INVALID:()=\u003eq_,NEVER:()=\u003ecv,OK:()=\u003eK_,ParseStatus:()=\u003eZ_,Schema:()=\u003eab,ZodAny:()=\u003eBb,ZodArray:()=\u003eXb,ZodBigInt:()=\u003eOb,ZodBoolean:()=\u003ekb,ZodBranded:()=\u003egx,ZodCatch:()=\u003eux,ZodDate:()=\u003eLb,ZodDefault:()=\u003ehx,ZodDiscriminatedUnion:()=\u003eUb,ZodEffects:()=\u003ecx,ZodEnum:()=\u003erx,ZodError:()=\u003eB_,ZodFirstPartyTypeKind:()=\u003exx,ZodFunction:()=\u003eex,ZodIntersection:()=\u003eqb,ZodIssueCode:()=\u003ez_,ZodLazy:()=\u003enx,ZodLiteral:()=\u003eox,ZodMap:()=\u003eQb,ZodNaN:()=\u003epx,ZodNativeEnum:()=\u003esx,ZodNever:()=\u003e$b,ZodNull:()=\u003eFb,ZodNullable:()=\u003edx,ZodNumber:()=\u003eAb,ZodObject:()=\u003eWb,ZodOptional:()=\u003elx,ZodParsedType:()=\u003eL_,ZodPipeline:()=\u003efx,ZodPromise:()=\u003eax,ZodReadonly:()=\u003eyx,ZodRecord:()=\u003eKb,ZodSchema:()=\u003eab,ZodSet:()=\u003etx,ZodString:()=\u003eRb,ZodSymbol:()=\u003eDb,ZodTransformer:()=\u003ecx,ZodTuple:()=\u003eJb,ZodType:()=\u003eab,ZodUndefined:()=\u003ezb,ZodUnion:()=\u003eHb,ZodUnknown:()=\u003ejb,ZodVoid:()=\u003eYb,addIssueToContext:()=\u003eH_,any:()=\u003eOx,array:()=\u003ezx,bigint:()=\u003eNx,boolean:()=\u003ewx,coerce:()=\u003eav,custom:()=\u003ebx,date:()=\u003eTx,datetimeRegex:()=\u003eMb,defaultErrorMap:()=\u003ej_,discriminatedUnion:()=\u003e$x,effect:()=\u003eQx,enum:()=\u003eqx,function:()=\u003eGx,getErrorMap:()=\u003eX_,getParsedType:()=\u003eD_,instanceof:()=\u003eIx,intersection:()=\u003eYx,isAborted:()=\u003eQ_,isAsync:()=\u003enb,isDirty:()=\u003etb,isValid:()=\u003eeb,late:()=\u003eSx,lazy:()=\u003eUx,literal:()=\u003eZx,makeIssue:()=\u003eV_,map:()=\u003eWx,nan:()=\u003eMx,nativeEnum:()=\u003eJx,never:()=\u003eLx,null:()=\u003eAx,nullable:()=\u003eev,number:()=\u003ePx,object:()=\u003eFx,objectUtil:()=\u003eA_,oboolean:()=\u003esv,onumber:()=\u003erv,optional:()=\u003etv,ostring:()=\u003eiv,pipeline:()=\u003eov,preprocess:()=\u003env,promise:()=\u003eKx,quotelessJson:()=\u003eF_,record:()=\u003eVx,set:()=\u003eHx,setErrorMap:()=\u003eY_,strictObject:()=\u003eBx,string:()=\u003eCx,symbol:()=\u003eRx,transformer:()=\u003eQx,tuple:()=\u003eXx,undefined:()=\u003eEx,union:()=\u003ejx,unknown:()=\u003ekx,util:()=\u003eR_,void:()=\u003eDx}),(E_=R_||(R_={})).assertEqual=t=\u003e{},E_.assertIs=function(t){},E_.assertNever=function(t){throw new Error},E_.arrayToEnum=t=\u003e{const e={};for(const n of t)e[n]=n;return e},E_.getValidEnumValues=t=\u003e{const e=E_.objectKeys(t).filter(e=\u003e\"number\"!=typeof t[t[e]]),n={};for(const o of e)n[o]=t[o];return E_.objectValues(n)},E_.objectValues=t=\u003eE_.objectKeys(t).map(function(e){return t[e]}),E_.objectKeys=\"function\"==typeof Object.keys?t=\u003eObject.keys(t):t=\u003e{const e=[];for(const n in t)Object.prototype.hasOwnProperty.call(t,n)\u0026\u0026e.push(n);return e},E_.find=(t,e)=\u003e{for(const n of t)if(e(n))return n},E_.isInteger=\"function\"==typeof Number.isInteger?t=\u003eNumber.isInteger(t):t=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)\u0026\u0026Math.floor(t)===t,E_.joinValues=function(t,e=\" | \"){return t.map(t=\u003e\"string\"==typeof t?`'${t}'`:t).join(e)},E_.jsonStringifyReplacer=(t,e)=\u003e\"bigint\"==typeof e?e.toString():e,(A_||(A_={})).mergeShapes=(t,e)=\u003e({...t,...e});var L_=R_.arrayToEnum([\"string\",\"nan\",\"number\",\"integer\",\"float\",\"boolean\",\"date\",\"bigint\",\"symbol\",\"function\",\"undefined\",\"null\",\"array\",\"object\",\"unknown\",\"promise\",\"void\",\"never\",\"map\",\"set\"]),D_=t=\u003e{switch(typeof t){case\"undefined\":return L_.undefined;case\"string\":return L_.string;case\"number\":return Number.isNaN(t)?L_.nan:L_.number;case\"boolean\":return L_.boolean;case\"function\":return L_.function;case\"bigint\":return L_.bigint;case\"symbol\":return L_.symbol;case\"object\":return Array.isArray(t)?L_.array:null===t?L_.null:t.then\u0026\u0026\"function\"==typeof t.then\u0026\u0026t.catch\u0026\u0026\"function\"==typeof t.catch?L_.promise:\"undefined\"!=typeof Map\u0026\u0026t instanceof Map?L_.map:\"undefined\"!=typeof Set\u0026\u0026t instanceof Set?L_.set:\"undefined\"!=typeof Date\u0026\u0026t instanceof Date?L_.date:L_.object;default:return L_.unknown}},z_=R_.arrayToEnum([\"invalid_type\",\"invalid_literal\",\"custom\",\"invalid_union\",\"invalid_union_discriminator\",\"invalid_enum_value\",\"unrecognized_keys\",\"invalid_arguments\",\"invalid_return_type\",\"invalid_date\",\"invalid_string\",\"too_small\",\"too_big\",\"invalid_intersection_types\",\"not_multiple_of\",\"not_finite\"]),F_=t=\u003eJSON.stringify(t,null,2).replace(/\"([^\"]+)\":/g,\"$1:\"),B_=class t extends Error{get errors(){return this.issues}constructor(t){super(),this.issues=[],this.addIssue=t=\u003e{this.issues=[...this.issues,t]},this.addIssues=(t=[])=\u003e{this.issues=[...this.issues,...t]};const e=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,e):this.__proto__=e,this.name=\"ZodError\",this.issues=t}format(t){const e=t||function(t){return t.message},n={_errors:[]},o=t=\u003e{for(const i of t.issues)if(\"invalid_union\"===i.code)i.unionErrors.map(o);else if(\"invalid_return_type\"===i.code)o(i.returnTypeError);else if(\"invalid_arguments\"===i.code)o(i.argumentsError);else if(0===i.path.length)n._errors.push(e(i));else{let t=n,o=0;for(;o\u003ci.path.length;){const n=i.path[o];o===i.path.length-1?(t[n]=t[n]||{_errors:[]},t[n]._errors.push(e(i))):t[n]=t[n]||{_errors:[]},t=t[n],o++}}};return o(this),n}static assert(e){if(!(e instanceof t))throw new Error(`Not a ZodError: ${e}`)}toString(){return this.message}get message(){return JSON.stringify(this.issues,R_.jsonStringifyReplacer,2)}get isEmpty(){return 0===this.issues.length}flatten(t=t=\u003et.message){const e={},n=[];for(const o of this.issues)if(o.path.length\u003e0){const n=o.path[0];e[n]=e[n]||[],e[n].push(t(o))}else n.push(t(o));return{formErrors:n,fieldErrors:e}}get formErrors(){return this.flatten()}};B_.create=t=\u003enew B_(t);var j_=(t,e)=\u003e{let n;switch(t.code){case z_.invalid_type:n=t.received===L_.undefined?\"Required\":`Expected ${t.expected}, received ${t.received}`;break;case z_.invalid_literal:n=`Invalid literal value, expected ${JSON.stringify(t.expected,R_.jsonStringifyReplacer)}`;break;case z_.unrecognized_keys:n=`Unrecognized key(s) in object: ${R_.joinValues(t.keys,\", \")}`;break;case z_.invalid_union:n=\"Invalid input\";break;case z_.invalid_union_discriminator:n=`Invalid discriminator value. Expected ${R_.joinValues(t.options)}`;break;case z_.invalid_enum_value:n=`Invalid enum value. Expected ${R_.joinValues(t.options)}, received '${t.received}'`;break;case z_.invalid_arguments:n=\"Invalid function arguments\";break;case z_.invalid_return_type:n=\"Invalid function return type\";break;case z_.invalid_date:n=\"Invalid date\";break;case z_.invalid_string:\"object\"==typeof t.validation?\"includes\"in t.validation?(n=`Invalid input: must include \"${t.validation.includes}\"`,\"number\"==typeof t.validation.position\u0026\u0026(n=`${n} at one or more positions greater than or equal to ${t.validation.position}`)):\"startsWith\"in t.validation?n=`Invalid input: must start with \"${t.validation.startsWith}\"`:\"endsWith\"in t.validation?n=`Invalid input: must end with \"${t.validation.endsWith}\"`:R_.assertNever(t.validation):n=\"regex\"!==t.validation?`Invalid ${t.validation}`:\"Invalid\";break;case z_.too_small:n=\"array\"===t.type?`Array must contain ${t.exact?\"exactly\":t.inclusive?\"at least\":\"more than\"} ${t.minimum} element(s)`:\"string\"===t.type?`String must contain ${t.exact?\"exactly\":t.inclusive?\"at least\":\"over\"} ${t.minimum} character(s)`:\"number\"===t.type||\"bigint\"===t.type?`Number must be ${t.exact?\"exactly equal to \":t.inclusive?\"greater than or equal to \":\"greater than \"}${t.minimum}`:\"date\"===t.type?`Date must be ${t.exact?\"exactly equal to \":t.inclusive?\"greater than or equal to \":\"greater than \"}${new Date(Number(t.minimum))}`:\"Invalid input\";break;case z_.too_big:n=\"array\"===t.type?`Array must contain ${t.exact?\"exactly\":t.inclusive?\"at most\":\"less than\"} ${t.maximum} element(s)`:\"string\"===t.type?`String must contain ${t.exact?\"exactly\":t.inclusive?\"at most\":\"under\"} ${t.maximum} character(s)`:\"number\"===t.type?`Number must be ${t.exact?\"exactly\":t.inclusive?\"less than or equal to\":\"less than\"} ${t.maximum}`:\"bigint\"===t.type?`BigInt must be ${t.exact?\"exactly\":t.inclusive?\"less than or equal to\":\"less than\"} ${t.maximum}`:\"date\"===t.type?`Date must be ${t.exact?\"exactly\":t.inclusive?\"smaller than or equal to\":\"smaller than\"} ${new Date(Number(t.maximum))}`:\"Invalid input\";break;case z_.custom:n=\"Invalid input\";break;case z_.invalid_intersection_types:n=\"Intersection results could not be merged\";break;case z_.not_multiple_of:n=`Number must be a multiple of ${t.multipleOf}`;break;case z_.not_finite:n=\"Number must be finite\";break;default:n=e.defaultError,R_.assertNever(t)}return{message:n}},$_=j_;function Y_(t){$_=t}function X_(){return $_}var V_=t=\u003e{const{data:e,path:n,errorMaps:o,issueData:i}=t,r=[...n,...i.path||[]],s={...i,path:r};if(void 0!==i.message)return{...i,path:r,message:i.message};let a=\"\";const c=o.filter(t=\u003e!!t).slice().reverse();for(const t of c)a=t(s,{data:e,defaultError:a}).message;return{...i,path:r,message:a}},W_=[];function H_(t,e){const n=X_(),o=V_({issueData:e,data:t.data,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,n,n===j_?void 0:j_].filter(t=\u003e!!t)});t.common.issues.push(o)}var G_,U_,Z_=class t{constructor(){this.value=\"valid\"}dirty(){\"valid\"===this.value\u0026\u0026(this.value=\"dirty\")}abort(){\"aborted\"!==this.value\u0026\u0026(this.value=\"aborted\")}static mergeArray(t,e){const n=[];for(const o of e){if(\"aborted\"===o.status)return q_;\"dirty\"===o.status\u0026\u0026t.dirty(),n.push(o.value)}return{status:t.value,value:n}}static async mergeObjectAsync(e,n){const o=[];for(const t of n){const e=await t.key,n=await t.value;o.push({key:e,value:n})}return t.mergeObjectSync(e,o)}static mergeObjectSync(t,e){const n={};for(const o of e){const{key:e,value:i}=o;if(\"aborted\"===e.status)return q_;if(\"aborted\"===i.status)return q_;\"dirty\"===e.status\u0026\u0026t.dirty(),\"dirty\"===i.status\u0026\u0026t.dirty(),\"__proto__\"===e.value||void 0===i.value\u0026\u0026!o.alwaysSet||(n[e.value]=i.value)}return{status:t.value,value:n}}},q_=Object.freeze({status:\"aborted\"}),J_=t=\u003e({status:\"dirty\",value:t}),K_=t=\u003e({status:\"valid\",value:t}),Q_=t=\u003e\"aborted\"===t.status,tb=t=\u003e\"dirty\"===t.status,eb=t=\u003e\"valid\"===t.status,nb=t=\u003e\"undefined\"!=typeof Promise\u0026\u0026t instanceof Promise;(U_=G_||(G_={})).errToObj=t=\u003e\"string\"==typeof t?{message:t}:t||{},U_.toString=t=\u003e\"string\"==typeof t?t:t?.message;var ob=class{constructor(t,e,n,o){this._cachedPath=[],this.parent=t,this.data=e,this._path=n,this._key=o}get path(){return this._cachedPath.length||(Array.isArray(this._key)?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}},ib=(t,e)=\u003e{if(eb(e))return{success:!0,data:e.value};if(!t.common.issues.length)throw new Error(\"Validation failed but no issues detected.\");return{success:!1,get error(){if(this._error)return this._error;const e=new B_(t.common.issues);return this._error=e,this._error}}};function rb(t){if(!t)return{};const{errorMap:e,invalid_type_error:n,required_error:o,description:i}=t;if(e\u0026\u0026(n||o))throw new Error('Can\\'t use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.');if(e)return{errorMap:e,description:i};return{errorMap:(e,i)=\u003e{const{message:r}=t;return\"invalid_enum_value\"===e.code?{message:r??i.defaultError}:void 0===i.data?{message:r??o??i.defaultError}:\"invalid_type\"!==e.code?{message:i.defaultError}:{message:r??n??i.defaultError}},description:i}}var sb,ab=class{get description(){return this._def.description}_getType(t){return D_(t.data)}_getOrReturnCtx(t,e){return e||{common:t.parent.common,data:t.data,parsedType:D_(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}_processInputParams(t){return{status:new Z_,ctx:{common:t.parent.common,data:t.data,parsedType:D_(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}}_parseSync(t){const e=this._parse(t);if(nb(e))throw new Error(\"Synchronous parse encountered promise.\");return e}_parseAsync(t){const e=this._parse(t);return Promise.resolve(e)}parse(t,e){const n=this.safeParse(t,e);if(n.success)return n.data;throw n.error}safeParse(t,e){const n={common:{issues:[],async:e?.async??!1,contextualErrorMap:e?.errorMap},path:e?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)},o=this._parseSync({data:t,path:n.path,parent:n});return ib(n,o)}\"~validate\"(t){const e={common:{issues:[],async:!!this[\"~standard\"].async},path:[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)};if(!this[\"~standard\"].async)try{const n=this._parseSync({data:t,path:[],parent:e});return eb(n)?{value:n.value}:{issues:e.common.issues}}catch(t){t?.message?.toLowerCase()?.includes(\"encountered\")\u0026\u0026(this[\"~standard\"].async=!0),e.common={issues:[],async:!0}}return this._parseAsync({data:t,path:[],parent:e}).then(t=\u003eeb(t)?{value:t.value}:{issues:e.common.issues})}async parseAsync(t,e){const n=await this.safeParseAsync(t,e);if(n.success)return n.data;throw n.error}async safeParseAsync(t,e){const n={common:{issues:[],contextualErrorMap:e?.errorMap,async:!0},path:e?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)},o=this._parse({data:t,path:n.path,parent:n}),i=await(nb(o)?o:Promise.resolve(o));return ib(n,i)}refine(t,e){const n=t=\u003e\"string\"==typeof e||void 0===e?{message:e}:\"function\"==typeof e?e(t):e;return this._refinement((e,o)=\u003e{const i=t(e),r=()=\u003eo.addIssue({code:z_.custom,...n(e)});return\"undefined\"!=typeof Promise\u0026\u0026i instanceof Promise?i.then(t=\u003e!!t||(r(),!1)):!!i||(r(),!1)})}refinement(t,e){return this._refinement((n,o)=\u003e!!t(n)||(o.addIssue(\"function\"==typeof e?e(n,o):e),!1))}_refinement(t){return new cx({schema:this,typeName:xx.ZodEffects,effect:{type:\"refinement\",refinement:t}})}superRefine(t){return this._refinement(t)}constructor(t){this.spa=this.safeParseAsync,this._def=t,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this),this[\"~standard\"]={version:1,vendor:\"zod\",validate:t=\u003ethis[\"~validate\"](t)}}optional(){return lx.create(this,this._def)}nullable(){return dx.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return Xb.create(this)}promise(){return ax.create(this,this._def)}or(t){return Hb.create([this,t],this._def)}and(t){return qb.create(this,t,this._def)}transform(t){return new cx({...rb(this._def),schema:this,typeName:xx.ZodEffects,effect:{type:\"transform\",transform:t}})}default(t){const e=\"function\"==typeof t?t:()=\u003et;return new hx({...rb(this._def),innerType:this,defaultValue:e,typeName:xx.ZodDefault})}brand(){return new gx({typeName:xx.ZodBranded,type:this,...rb(this._def)})}catch(t){const e=\"function\"==typeof t?t:()=\u003et;return new ux({...rb(this._def),innerType:this,catchValue:e,typeName:xx.ZodCatch})}describe(t){return new(0,this.constructor)({...this._def,description:t})}pipe(t){return fx.create(this,t)}readonly(){return yx.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}},cb=/^c[^\\s-]{8,}$/i,lb=/^[0-9a-z]+$/,db=/^[0-9A-HJKMNP-TV-Z]{26}$/i,hb=/^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i,ub=/^[a-z0-9_-]{21}$/i,pb=/^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$/,mb=/^[-+]?P(?!$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??$/,gb=/^(?!\\.)(?!.*\\.\\.)([A-Z0-9_'+\\-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i,fb=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,yb=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/(3[0-2]|[12]?[0-9])$/,_b=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,bb=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,xb=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,vb=/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,Sb=\"((\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\\\d|30)|(02)-(0[1-9]|1\\\\d|2[0-8])))\",Ib=new RegExp(`^${Sb}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
);function Cb(t){let e=\"[0-5]\\\\d\";t.precision?e=`${e}\\\\.\\\\d{${t.precision}}`:null==t.precision\u0026\u0026(e=`${e}(\\\\.\\\\d+)?`);return`([01]\\\\d|2[0-3]):[0-5]\\\\d(:${e})${t.precision?\"+\":\"?\"}`}function Pb(t){return new RegExp(`^${Cb(t)}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
)}function Mb(t){let e=`${Sb}T${Cb(t)}`;const n=[];return n.push(t.local?\"Z?\":\"Z\"),t.offset\u0026\u0026n.push(\"([+-]\\\\d{2}:?\\\\d{2})\"),e=`${e}(${n.join(\"|\")})`,new RegExp(`^${e}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
)}function Nb(t,e){return!(\"v4\"!==e\u0026\u0026e||!fb.test(t))||!(\"v6\"!==e\u0026\u0026e||!_b.test(t))}function wb(t,e){if(!pb.test(t))return!1;try{const[n]=t.split(\".\");if(!n)return!1;const o=n.replace(/-/g,\"+\").replace(/_/g,\"/\").padEnd(n.length+(4-n.length%4)%4,\"=\"),i=JSON.parse(atob(o));return\"object\"==typeof i\u0026\u0026null!==i\u0026\u0026((!(\"typ\"in i)||\"JWT\"===i?.typ)\u0026\u0026(!!i.alg\u0026\u0026(!e||i.alg===e)))}catch{return!1}}function Tb(t,e){return!(\"v4\"!==e\u0026\u0026e||!yb.test(t))||!(\"v6\"!==e\u0026\u0026e||!bb.test(t))}var Rb=class t extends ab{_parse(t){this._def.coerce\u0026\u0026(t.data=String(t.data));if(this._getType(t)!==L_.string){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.string,received:e.parsedType}),q_}const e=new Z_;let n;for(const o of this._def.checks)if(\"min\"===o.kind)t.data.length\u003co.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_small,minimum:o.value,type:\"string\",inclusive:!0,exact:!1,message:o.message}),e.dirty());else if(\"max\"===o.kind)t.data.length\u003eo.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_big,maximum:o.value,type:\"string\",inclusive:!0,exact:!1,message:o.message}),e.dirty());else if(\"length\"===o.kind){const i=t.data.length\u003eo.value,r=t.data.length\u003co.value;(i||r)\u0026\u0026(n=this._getOrReturnCtx(t,n),i?H_(n,{code:z_.too_big,maximum:o.value,type:\"string\",inclusive:!0,exact:!0,message:o.message}):r\u0026\u0026H_(n,{code:z_.too_small,minimum:o.value,type:\"string\",inclusive:!0,exact:!0,message:o.message}),e.dirty())}else if(\"email\"===o.kind)gb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"email\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"emoji\"===o.kind)sb||(sb=new RegExp(\"^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+$\",\"u\")),sb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"emoji\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"uuid\"===o.kind)hb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"uuid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"nanoid\"===o.kind)ub.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"nanoid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"cuid\"===o.kind)cb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"cuid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"cuid2\"===o.kind)lb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"cuid2\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"ulid\"===o.kind)db.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"ulid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"url\"===o.kind)try{new URL(t.data)}catch{n=this._getOrReturnCtx(t,n),H_(n,{validation:\"url\",code:z_.invalid_string,message:o.message}),e.dirty()}else if(\"regex\"===o.kind){o.regex.lastIndex=0;o.regex.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"regex\",code:z_.invalid_string,message:o.message}),e.dirty())}else if(\"trim\"===o.kind)t.data=t.data.trim();else if(\"includes\"===o.kind)t.data.includes(o.value,o.position)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{includes:o.value,position:o.position},message:o.message}),e.dirty());else if(\"toLowerCase\"===o.kind)t.data=t.data.toLowerCase();else if(\"toUpperCase\"===o.kind)t.data=t.data.toUpperCase();else if(\"startsWith\"===o.kind)t.data.startsWith(o.value)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{startsWith:o.value},message:o.message}),e.dirty());else if(\"endsWith\"===o.kind)t.data.endsWith(o.value)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{endsWith:o.value},message:o.message}),e.dirty());else if(\"datetime\"===o.kind){Mb(o).test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:\"datetime\",message:o.message}),e.dirty())}else if(\"date\"===o.kind){Ib.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:\"date\",message:o.message}),e.dirty())}else if(\"time\"===o.kind){Pb(o).test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:\"time\",message:o.message}),e.dirty())}else\"duration\"===o.kind?mb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"duration\",code:z_.invalid_string,message:o.message}),e.dirty()):\"ip\"===o.kind?Nb(t.data,o.version)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"ip\",code:z_.invalid_string,message:o.message}),e.dirty()):\"jwt\"===o.kind?wb(t.data,o.alg)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"jwt\",code:z_.invalid_string,message:o.message}),e.dirty()):\"cidr\"===o.kind?Tb(t.data,o.version)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"cidr\",code:z_.invalid_string,message:o.message}),e.dirty()):\"base64\"===o.kind?xb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"base64\",code:z_.invalid_string,message:o.message}),e.dirty()):\"base64url\"===o.kind?vb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"base64url\",code:z_.invalid_string,message:o.message}),e.dirty()):R_.assertNever(o);return{status:e.value,value:t.data}}_regex(t,e,n){return this.refinement(e=\u003et.test(e),{validation:e,code:z_.invalid_string,...G_.errToObj(n)})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}email(t){return this._addCheck({kind:\"email\",...G_.errToObj(t)})}url(t){return this._addCheck({kind:\"url\",...G_.errToObj(t)})}emoji(t){return this._addCheck({kind:\"emoji\",...G_.errToObj(t)})}uuid(t){return this._addCheck({kind:\"uuid\",...G_.errToObj(t)})}nanoid(t){return this._addCheck({kind:\"nanoid\",...G_.errToObj(t)})}cuid(t){return this._addCheck({kind:\"cuid\",...G_.errToObj(t)})}cuid2(t){return this._addCheck({kind:\"cuid2\",...G_.errToObj(t)})}ulid(t){return this._addCheck({kind:\"ulid\",...G_.errToObj(t)})}base64(t){return this._addCheck({kind:\"base64\",...G_.errToObj(t)})}base64url(t){return this._addCheck({kind:\"base64url\",...G_.errToObj(t)})}jwt(t){return this._addCheck({kind:\"jwt\",...G_.errToObj(t)})}ip(t){return this._addCheck({kind:\"ip\",...G_.errToObj(t)})}cidr(t){return this._addCheck({kind:\"cidr\",...G_.errToObj(t)})}datetime(t){return\"string\"==typeof t?this._addCheck({kind:\"datetime\",precision:null,offset:!1,local:!1,message:t}):this._addCheck({kind:\"datetime\",precision:void 0===t?.precision?null:t?.precision,offset:t?.offset??!1,local:t?.local??!1,...G_.errToObj(t?.message)})}date(t){return this._addCheck({kind:\"date\",message:t})}time(t){return\"string\"==typeof t?this._addCheck({kind:\"time\",precision:null,message:t}):this._addCheck({kind:\"time\",precision:void 0===t?.precision?null:t?.precision,...G_.errToObj(t?.message)})}duration(t){return this._addCheck({kind:\"duration\",...G_.errToObj(t)})}regex(t,e){return this._addCheck({kind:\"regex\",regex:t,...G_.errToObj(e)})}includes(t,e){return this._addCheck({kind:\"includes\",value:t,position:e?.position,...G_.errToObj(e?.message)})}startsWith(t,e){return this._addCheck({kind:\"startsWith\",value:t,...G_.errToObj(e)})}endsWith(t,e){return this._addCheck({kind:\"endsWith\",value:t,...G_.errToObj(e)})}min(t,e){return this._addCheck({kind:\"min\",value:t,...G_.errToObj(e)})}max(t,e){return this._addCheck({kind:\"max\",value:t,...G_.errToObj(e)})}length(t,e){return this._addCheck({kind:\"length\",value:t,...G_.errToObj(e)})}nonempty(t){return this.min(1,G_.errToObj(t))}trim(){return new t({...this._def,checks:[...this._def.checks,{kind:\"trim\"}]})}toLowerCase(){return new t({...this._def,checks:[...this._def.checks,{kind:\"toLowerCase\"}]})}toUpperCase(){return new t({...this._def,checks:[...this._def.checks,{kind:\"toUpperCase\"}]})}get isDatetime(){return!!this._def.checks.find(t=\u003e\"datetime\"===t.kind)}get isDate(){return!!this._def.checks.find(t=\u003e\"date\"===t.kind)}get isTime(){return!!this._def.checks.find(t=\u003e\"time\"===t.kind)}get isDuration(){return!!this._def.checks.find(t=\u003e\"duration\"===t.kind)}get isEmail(){return!!this._def.checks.find(t=\u003e\"email\"===t.kind)}get isURL(){return!!this._def.checks.find(t=\u003e\"url\"===t.kind)}get isEmoji(){return!!this._def.checks.find(t=\u003e\"emoji\"===t.kind)}get isUUID(){return!!this._def.checks.find(t=\u003e\"uuid\"===t.kind)}get isNANOID(){return!!this._def.checks.find(t=\u003e\"nanoid\"===t.kind)}get isCUID(){return!!this._def.checks.find(t=\u003e\"cuid\"===t.kind)}get isCUID2(){return!!this._def.checks.find(t=\u003e\"cuid2\"===t.kind)}get isULID(){return!!this._def.checks.find(t=\u003e\"ulid\"===t.kind)}get isIP(){return!!this._def.checks.find(t=\u003e\"ip\"===t.kind)}get isCIDR(){return!!this._def.checks.find(t=\u003e\"cidr\"===t.kind)}get isBase64(){return!!this._def.checks.find(t=\u003e\"base64\"===t.kind)}get isBase64url(){return!!this._def.checks.find(t=\u003e\"base64url\"===t.kind)}get minLength(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return t}get maxLength(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return t}};function Eb(t,e){const n=(t.toString().split(\".\")[1]||\"\").length,o=(e.toString().split(\".\")[1]||\"\").length,i=n\u003eo?n:o;return Number.parseInt(t.toFixed(i).replace(\".\",\"\"))%Number.parseInt(e.toFixed(i).replace(\".\",\"\"))/10**i}Rb.create=t=\u003enew Rb({checks:[],typeName:xx.ZodString,coerce:t?.coerce??!1,...rb(t)});var Ab=class t extends ab{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(t){this._def.coerce\u0026\u0026(t.data=Number(t.data));if(this._getType(t)!==L_.number){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.number,received:e.parsedType}),q_}let e;const n=new Z_;for(const o of this._def.checks)if(\"int\"===o.kind)R_.isInteger(t.data)||(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.invalid_type,expected:\"integer\",received:\"float\",message:o.message}),n.dirty());else if(\"min\"===o.kind){(o.inclusive?t.data\u003co.value:t.data\u003c=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_small,minimum:o.value,type:\"number\",inclusive:o.inclusive,exact:!1,message:o.message}),n.dirty())}else if(\"max\"===o.kind){(o.inclusive?t.data\u003eo.value:t.data\u003e=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_big,maximum:o.value,type:\"number\",inclusive:o.inclusive,exact:!1,message:o.message}),n.dirty())}else\"multipleOf\"===o.kind?0!==Eb(t.data,o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_multiple_of,multipleOf:o.value,message:o.message}),n.dirty()):\"finite\"===o.kind?Number.isFinite(t.data)||(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_finite,message:o.message}),n.dirty()):R_.assertNever(o);return{status:n.value,value:t.data}}gte(t,e){return this.setLimit(\"min\",t,!0,G_.toString(e))}gt(t,e){return this.setLimit(\"min\",t,!1,G_.toString(e))}lte(t,e){return this.setLimit(\"max\",t,!0,G_.toString(e))}lt(t,e){return this.setLimit(\"max\",t,!1,G_.toString(e))}setLimit(e,n,o,i){return new t({...this._def,checks:[...this._def.checks,{kind:e,value:n,inclusive:o,message:G_.toString(i)}]})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}int(t){return this._addCheck({kind:\"int\",message:G_.toString(t)})}positive(t){return this._addCheck({kind:\"min\",value:0,inclusive:!1,message:G_.toString(t)})}negative(t){return this._addCheck({kind:\"max\",value:0,inclusive:!1,message:G_.toString(t)})}nonpositive(t){return this._addCheck({kind:\"max\",value:0,inclusive:!0,message:G_.toString(t)})}nonnegative(t){return this._addCheck({kind:\"min\",value:0,inclusive:!0,message:G_.toString(t)})}multipleOf(t,e){return this._addCheck({kind:\"multipleOf\",value:t,message:G_.toString(e)})}finite(t){return this._addCheck({kind:\"finite\",message:G_.toString(t)})}safe(t){return this._addCheck({kind:\"min\",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:G_.toString(t)})._addCheck({kind:\"max\",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:G_.toString(t)})}get minValue(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return t}get maxValue(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return t}get isInt(){return!!this._def.checks.find(t=\u003e\"int\"===t.kind||\"multipleOf\"===t.kind\u0026\u0026R_.isInteger(t.value))}get isFinite(){let t=null,e=null;for(const n of this._def.checks){if(\"finite\"===n.kind||\"int\"===n.kind||\"multipleOf\"===n.kind)return!0;\"min\"===n.kind?(null===e||n.value\u003ee)\u0026\u0026(e=n.value):\"max\"===n.kind\u0026\u0026(null===t||n.value\u003ct)\u0026\u0026(t=n.value)}return Number.isFinite(e)\u0026\u0026Number.isFinite(t)}};Ab.create=t=\u003enew Ab({checks:[],typeName:xx.ZodNumber,coerce:t?.coerce||!1,...rb(t)});var Ob=class t extends ab{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(t){if(this._def.coerce)try{t.data=BigInt(t.data)}catch{return this._getInvalidInput(t)}if(this._getType(t)!==L_.bigint)return this._getInvalidInput(t);let e;const n=new Z_;for(const o of this._def.checks)if(\"min\"===o.kind){(o.inclusive?t.data\u003co.value:t.data\u003c=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_small,type:\"bigint\",minimum:o.value,inclusive:o.inclusive,message:o.message}),n.dirty())}else if(\"max\"===o.kind){(o.inclusive?t.data\u003eo.value:t.data\u003e=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_big,type:\"bigint\",maximum:o.value,inclusive:o.inclusive,message:o.message}),n.dirty())}else\"multipleOf\"===o.kind?t.data%o.value!==BigInt(0)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_multiple_of,multipleOf:o.value,message:o.message}),n.dirty()):R_.assertNever(o);return{status:n.value,value:t.data}}_getInvalidInput(t){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.bigint,received:e.parsedType}),q_}gte(t,e){return this.setLimit(\"min\",t,!0,G_.toString(e))}gt(t,e){return this.setLimit(\"min\",t,!1,G_.toString(e))}lte(t,e){return this.setLimit(\"max\",t,!0,G_.toString(e))}lt(t,e){return this.setLimit(\"max\",t,!1,G_.toString(e))}setLimit(e,n,o,i){return new t({...this._def,checks:[...this._def.checks,{kind:e,value:n,inclusive:o,message:G_.toString(i)}]})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}positive(t){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!1,message:G_.toString(t)})}negative(t){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!1,message:G_.toString(t)})}nonpositive(t){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!0,message:G_.toString(t)})}nonnegative(t){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!0,message:G_.toString(t)})}multipleOf(t,e){return this._addCheck({kind:\"multipleOf\",value:t,message:G_.toString(e)})}get minValue(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return t}get maxValue(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return t}};Ob.create=t=\u003enew Ob({checks:[],typeName:xx.ZodBigInt,coerce:t?.coerce??!1,...rb(t)});var kb=class extends ab{_parse(t){this._def.coerce\u0026\u0026(t.data=Boolean(t.data));if(this._getType(t)!==L_.boolean){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.boolean,received:e.parsedType}),q_}return K_(t.data)}};kb.create=t=\u003enew kb({typeName:xx.ZodBoolean,coerce:t?.coerce||!1,...rb(t)});var Lb=class t extends ab{_parse(t){this._def.coerce\u0026\u0026(t.data=new Date(t.data));if(this._getType(t)!==L_.date){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.date,received:e.parsedType}),q_}if(Number.isNaN(t.data.getTime())){return H_(this._getOrReturnCtx(t),{code:z_.invalid_date}),q_}const e=new Z_;let n;for(const o of this._def.checks)\"min\"===o.kind?t.data.getTime()\u003co.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_small,message:o.message,inclusive:!0,exact:!1,minimum:o.value,type:\"date\"}),e.dirty()):\"max\"===o.kind?t.data.getTime()\u003eo.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_big,message:o.message,inclusive:!0,exact:!1,maximum:o.value,type:\"date\"}),e.dirty()):R_.assertNever(o);return{status:e.value,value:new Date(t.data.getTime())}}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}min(t,e){return this._addCheck({kind:\"min\",value:t.getTime(),message:G_.toString(e)})}max(t,e){return this._addCheck({kind:\"max\",value:t.getTime(),message:G_.toString(e)})}get minDate(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return null!=t?new Date(t):null}get maxDate(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return null!=t?new Date(t):null}};Lb.create=t=\u003enew Lb({checks:[],coerce:t?.coerce||!1,typeName:xx.ZodDate,...rb(t)});var Db=class extends ab{_parse(t){if(this._getType(t)!==L_.symbol){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.symbol,received:e.parsedType}),q_}return K_(t.data)}};Db.create=t=\u003enew Db({typeName:xx.ZodSymbol,...rb(t)});var zb=class extends ab{_parse(t){if(this._getType(t)!==L_.undefined){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.undefined,received:e.parsedType}),q_}return K_(t.data)}};zb.create=t=\u003enew zb({typeName:xx.ZodUndefined,...rb(t)});var Fb=class extends ab{_parse(t){if(this._getType(t)!==L_.null){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.null,received:e.parsedType}),q_}return K_(t.data)}};Fb.create=t=\u003enew Fb({typeName:xx.ZodNull,...rb(t)});var Bb=class extends ab{constructor(){super(...arguments),this._any=!0}_parse(t){return K_(t.data)}};Bb.create=t=\u003enew Bb({typeName:xx.ZodAny,...rb(t)});var jb=class extends ab{constructor(){super(...arguments),this._unknown=!0}_parse(t){return K_(t.data)}};jb.create=t=\u003enew jb({typeName:xx.ZodUnknown,...rb(t)});var $b=class extends ab{_parse(t){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.never,received:e.parsedType}),q_}};$b.create=t=\u003enew $b({typeName:xx.ZodNever,...rb(t)});var Yb=class extends ab{_parse(t){if(this._getType(t)!==L_.undefined){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.void,received:e.parsedType}),q_}return K_(t.data)}};Yb.create=t=\u003enew Yb({typeName:xx.ZodVoid,...rb(t)});var Xb=class t extends ab{_parse(t){const{ctx:e,status:n}=this._processInputParams(t),o=this._def;if(e.parsedType!==L_.array)return H_(e,{code:z_.invalid_type,expected:L_.array,received:e.parsedType}),q_;if(null!==o.exactLength){const t=e.data.length\u003eo.exactLength.value,i=e.data.length\u003co.exactLength.value;(t||i)\u0026\u0026(H_(e,{code:t?z_.too_big:z_.too_small,minimum:i?o.exactLength.value:void 0,maximum:t?o.exactLength.value:void 0,type:\"array\",inclusive:!0,exact:!0,message:o.exactLength.message}),n.dirty())}if(null!==o.minLength\u0026\u0026e.data.length\u003co.minLength.value\u0026\u0026(H_(e,{code:z_.too_small,minimum:o.minLength.value,type:\"array\",inclusive:!0,exact:!1,message:o.minLength.message}),n.dirty()),null!==o.maxLength\u0026\u0026e.data.length\u003eo.maxLength.value\u0026\u0026(H_(e,{code:z_.too_big,maximum:o.maxLength.value,type:\"array\",inclusive:!0,exact:!1,message:o.maxLength.message}),n.dirty()),e.common.async)return Promise.all([...e.data].map((t,n)=\u003eo.type._parseAsync(new ob(e,t,e.path,n)))).then(t=\u003eZ_.mergeArray(n,t));const i=[...e.data].map((t,n)=\u003eo.type._parseSync(new ob(e,t,e.path,n)));return Z_.mergeArray(n,i)}get element(){return this._def.type}min(e,n){return new t({...this._def,minLength:{value:e,message:G_.toString(n)}})}max(e,n){return new t({...this._def,maxLength:{value:e,message:G_.toString(n)}})}length(e,n){return new t({...this._def,exactLength:{value:e,message:G_.toString(n)}})}nonempty(t){return this.min(1,t)}};function Vb(t){if(t instanceof Wb){const e={};for(const n in t.shape){const o=t.shape[n];e[n]=lx.create(Vb(o))}return new Wb({...t._def,shape:()=\u003ee})}return t instanceof Xb?new Xb({...t._def,type:Vb(t.element)}):t instanceof lx?lx.create(Vb(t.unwrap())):t instanceof dx?dx.create(Vb(t.unwrap())):t instanceof Jb?Jb.create(t.items.map(t=\u003eVb(t))):t}Xb.create=(t,e)=\u003enew Xb({type:t,minLength:null,maxLength:null,exactLength:null,typeName:xx.ZodArray,...rb(e)});var Wb=class t extends ab{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(null!==this._cached)return this._cached;const t=this._def.shape(),e=R_.objectKeys(t);return this._cached={shape:t,keys:e},this._cached}_parse(t){if(this._getType(t)!==L_.object){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.object,received:e.parsedType}),q_}const{status:e,ctx:n}=this._processInputParams(t),{shape:o,keys:i}=this._getCached(),r=[];if(!(this._def.catchall instanceof $b\u0026\u0026\"strip\"===this._def.unknownKeys))for(const t in n.data)i.includes(t)||r.push(t);const s=[];for(const t of i){const e=o[t],i=n.data[t];s.push({key:{status:\"valid\",value:t},value:e._parse(new ob(n,i,n.path,t)),alwaysSet:t in n.data})}if(this._def.catchall instanceof $b){const t=this._def.unknownKeys;if(\"passthrough\"===t)for(const t of r)s.push({key:{status:\"valid\",value:t},value:{status:\"valid\",value:n.data[t]}});else if(\"strict\"===t)r.length\u003e0\u0026\u0026(H_(n,{code:z_.unrecognized_keys,keys:r}),e.dirty());else if(\"strip\"!==t)throw new Error(\"Internal ZodObject error: invalid unknownKeys value.\")}else{const t=this._def.catchall;for(const e of r){const o=n.data[e];s.push({key:{status:\"valid\",value:e},value:t._parse(new ob(n,o,n.path,e)),alwaysSet:e in n.data})}}return n.common.async?Promise.resolve().then(async()=\u003e{const t=[];for(const e of s){const n=await e.key,o=await e.value;t.push({key:n,value:o,alwaysSet:e.alwaysSet})}return t}).then(t=\u003eZ_.mergeObjectSync(e,t)):Z_.mergeObjectSync(e,s)}get shape(){return this._def.shape()}strict(e){return G_.errToObj,new t({...this._def,unknownKeys:\"strict\",...void 0!==e?{errorMap:(t,n)=\u003e{const o=this._def.errorMap?.(t,n).message??n.defaultError;return\"unrecognized_keys\"===t.code?{message:G_.errToObj(e).message??o}:{message:o}}}:{}})}strip(){return new t({...this._def,unknownKeys:\"strip\"})}passthrough(){return new t({...this._def,unknownKeys:\"passthrough\"})}extend(e){return new t({...this._def,shape:()=\u003e({...this._def.shape(),...e})})}merge(e){return new t({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=\u003e({...this._def.shape(),...e._def.shape()}),typeName:xx.ZodObject})}setKey(t,e){return this.augment({[t]:e})}catchall(e){return new t({...this._def,catchall:e})}pick(e){const n={};for(const t of R_.objectKeys(e))e[t]\u0026\u0026this.shape[t]\u0026\u0026(n[t]=this.shape[t]);return new t({...this._def,shape:()=\u003en})}omit(e){const n={};for(const t of R_.objectKeys(this.shape))e[t]||(n[t]=this.shape[t]);return new t({...this._def,shape:()=\u003en})}deepPartial(){return Vb(this)}partial(e){const n={};for(const t of R_.objectKeys(this.shape)){const o=this.shape[t];e\u0026\u0026!e[t]?n[t]=o:n[t]=o.optional()}return new t({...this._def,shape:()=\u003en})}required(e){const n={};for(const t of R_.objectKeys(this.shape))if(e\u0026\u0026!e[t])n[t]=this.shape[t];else{let e=this.shape[t];for(;e instanceof lx;)e=e._def.innerType;n[t]=e}return new t({...this._def,shape:()=\u003en})}keyof(){return ix(R_.objectKeys(this.shape))}};Wb.create=(t,e)=\u003enew Wb({shape:()=\u003et,unknownKeys:\"strip\",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)}),Wb.strictCreate=(t,e)=\u003enew Wb({shape:()=\u003et,unknownKeys:\"strict\",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)}),Wb.lazycreate=(t,e)=\u003enew Wb({shape:t,unknownKeys:\"strip\",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)});var Hb=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n=this._def.options;if(e.common.async)return Promise.all(n.map(async t=\u003e{const n={...e,common:{...e.common,issues:[]},parent:null};return{result:await t._parseAsync({data:e.data,path:e.path,parent:n}),ctx:n}})).then(function(t){for(const e of t)if(\"valid\"===e.result.status)return e.result;for(const n of t)if(\"dirty\"===n.result.status)return e.common.issues.push(...n.ctx.common.issues),n.result;const n=t.map(t=\u003enew B_(t.ctx.common.issues));return H_(e,{code:z_.invalid_union,unionErrors:n}),q_});{let t;const o=[];for(const i of n){const n={...e,common:{...e.common,issues:[]},parent:null},r=i._parseSync({data:e.data,path:e.path,parent:n});if(\"valid\"===r.status)return r;\"dirty\"!==r.status||t||(t={result:r,ctx:n}),n.common.issues.length\u0026\u0026o.push(n.common.issues)}if(t)return e.common.issues.push(...t.ctx.common.issues),t.result;const i=o.map(t=\u003enew B_(t));return H_(e,{code:z_.invalid_union,unionErrors:i}),q_}}get options(){return this._def.options}};Hb.create=(t,e)=\u003enew Hb({options:t,typeName:xx.ZodUnion,...rb(e)});var Gb=t=\u003et instanceof nx?Gb(t.schema):t instanceof cx?Gb(t.innerType()):t instanceof ox?[t.value]:t instanceof rx?t.options:t instanceof sx?R_.objectValues(t.enum):t instanceof hx?Gb(t._def.innerType):t instanceof zb?[void 0]:t instanceof Fb?[null]:t instanceof lx?[void 0,...Gb(t.unwrap())]:t instanceof dx?[null,...Gb(t.unwrap())]:t instanceof gx||t instanceof yx?Gb(t.unwrap()):t instanceof ux?Gb(t._def.innerType):[],Ub=class t extends ab{_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.object)return H_(e,{code:z_.invalid_type,expected:L_.object,received:e.parsedType}),q_;const n=this.discriminator,o=e.data[n],i=this.optionsMap.get(o);return i?e.common.async?i._parseAsync({data:e.data,path:e.path,parent:e}):i._parseSync({data:e.data,path:e.path,parent:e}):(H_(e,{code:z_.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[n]}),q_)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,n,o){const i=new Map;for(const t of n){const n=Gb(t.shape[e]);if(!n.length)throw new Error(`A discriminator value for key \\`${e}\\` could not be extracted from all schema options`);for(const o of n){if(i.has(o))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(o)}`);i.set(o,t)}}return new t({typeName:xx.ZodDiscriminatedUnion,discriminator:e,options:n,optionsMap:i,...rb(o)})}};function Zb(t,e){const n=D_(t),o=D_(e);if(t===e)return{valid:!0,data:t};if(n===L_.object\u0026\u0026o===L_.object){const n=R_.objectKeys(e),o=R_.objectKeys(t).filter(t=\u003e-1!==n.indexOf(t)),i={...t,...e};for(const n of o){const o=Zb(t[n],e[n]);if(!o.valid)return{valid:!1};i[n]=o.data}return{valid:!0,data:i}}if(n===L_.array\u0026\u0026o===L_.array){if(t.length!==e.length)return{valid:!1};const n=[];for(let o=0;o\u003ct.length;o++){const i=Zb(t[o],e[o]);if(!i.valid)return{valid:!1};n.push(i.data)}return{valid:!0,data:n}}return n===L_.date\u0026\u0026o===L_.date\u0026\u0026+t===+e?{valid:!0,data:t}:{valid:!1}}var qb=class extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t),o=(t,o)=\u003e{if(Q_(t)||Q_(o))return q_;const i=Zb(t.value,o.value);return i.valid?((tb(t)||tb(o))\u0026\u0026e.dirty(),{status:e.value,value:i.data}):(H_(n,{code:z_.invalid_intersection_types}),q_)};return n.common.async?Promise.all([this._def.left._parseAsync({data:n.data,path:n.path,parent:n}),this._def.right._parseAsync({data:n.data,path:n.path,parent:n})]).then(([t,e])=\u003eo(t,e)):o(this._def.left._parseSync({data:n.data,path:n.path,parent:n}),this._def.right._parseSync({data:n.data,path:n.path,parent:n}))}};qb.create=(t,e,n)=\u003enew qb({left:t,right:e,typeName:xx.ZodIntersection,...rb(n)});var Jb=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.array)return H_(n,{code:z_.invalid_type,expected:L_.array,received:n.parsedType}),q_;if(n.data.length\u003cthis._def.items.length)return H_(n,{code:z_.too_small,minimum:this._def.items.length,inclusive:!0,exact:!1,type:\"array\"}),q_;!this._def.rest\u0026\u0026n.data.length\u003ethis._def.items.length\u0026\u0026(H_(n,{code:z_.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:\"array\"}),e.dirty());const o=[...n.data].map((t,e)=\u003e{const o=this._def.items[e]||this._def.rest;return o?o._parse(new ob(n,t,n.path,e)):null}).filter(t=\u003e!!t);return n.common.async?Promise.all(o).then(t=\u003eZ_.mergeArray(e,t)):Z_.mergeArray(e,o)}get items(){return this._def.items}rest(e){return new t({...this._def,rest:e})}};Jb.create=(t,e)=\u003e{if(!Array.isArray(t))throw new Error(\"You must pass an array of schemas to z.tuple([ ... ])\");return new Jb({items:t,typeName:xx.ZodTuple,rest:null,...rb(e)})};var Kb=class t extends ab{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.object)return H_(n,{code:z_.invalid_type,expected:L_.object,received:n.parsedType}),q_;const o=[],i=this._def.keyType,r=this._def.valueType;for(const t in n.data)o.push({key:i._parse(new ob(n,t,n.path,t)),value:r._parse(new ob(n,n.data[t],n.path,t)),alwaysSet:t in n.data});return n.common.async?Z_.mergeObjectAsync(e,o):Z_.mergeObjectSync(e,o)}get element(){return this._def.valueType}static create(e,n,o){return new t(n instanceof ab?{keyType:e,valueType:n,typeName:xx.ZodRecord,...rb(o)}:{keyType:Rb.create(),valueType:e,typeName:xx.ZodRecord,...rb(n)})}},Qb=class extends ab{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.map)return H_(n,{code:z_.invalid_type,expected:L_.map,received:n.parsedType}),q_;const o=this._def.keyType,i=this._def.valueType,r=[...n.data.entries()].map(([t,e],r)=\u003e({key:o._parse(new ob(n,t,n.path,[r,\"key\"])),value:i._parse(new ob(n,e,n.path,[r,\"value\"]))}));if(n.common.async){const t=new Map;return Promise.resolve().then(async()=\u003e{for(const n of r){const o=await n.key,i=await n.value;if(\"aborted\"===o.status||\"aborted\"===i.status)return q_;\"dirty\"!==o.status\u0026\u0026\"dirty\"!==i.status||e.dirty(),t.set(o.value,i.value)}return{status:e.value,value:t}})}{const t=new Map;for(const n of r){const o=n.key,i=n.value;if(\"aborted\"===o.status||\"aborted\"===i.status)return q_;\"dirty\"!==o.status\u0026\u0026\"dirty\"!==i.status||e.dirty(),t.set(o.value,i.value)}return{status:e.value,value:t}}}};Qb.create=(t,e,n)=\u003enew Qb({valueType:e,keyType:t,typeName:xx.ZodMap,...rb(n)});var tx=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.set)return H_(n,{code:z_.invalid_type,expected:L_.set,received:n.parsedType}),q_;const o=this._def;null!==o.minSize\u0026\u0026n.data.size\u003co.minSize.value\u0026\u0026(H_(n,{code:z_.too_small,minimum:o.minSize.value,type:\"set\",inclusive:!0,exact:!1,message:o.minSize.message}),e.dirty()),null!==o.maxSize\u0026\u0026n.data.size\u003eo.maxSize.value\u0026\u0026(H_(n,{code:z_.too_big,maximum:o.maxSize.value,type:\"set\",inclusive:!0,exact:!1,message:o.maxSize.message}),e.dirty());const i=this._def.valueType;function r(t){const n=new Set;for(const o of t){if(\"aborted\"===o.status)return q_;\"dirty\"===o.status\u0026\u0026e.dirty(),n.add(o.value)}return{status:e.value,value:n}}const s=[...n.data.values()].map((t,e)=\u003ei._parse(new ob(n,t,n.path,e)));return n.common.async?Promise.all(s).then(t=\u003er(t)):r(s)}min(e,n){return new t({...this._def,minSize:{value:e,message:G_.toString(n)}})}max(e,n){return new t({...this._def,maxSize:{value:e,message:G_.toString(n)}})}size(t,e){return this.min(t,e).max(t,e)}nonempty(t){return this.min(1,t)}};tx.create=(t,e)=\u003enew tx({valueType:t,minSize:null,maxSize:null,typeName:xx.ZodSet,...rb(e)});var ex=class t extends ab{constructor(){super(...arguments),this.validate=this.implement}_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.function)return H_(e,{code:z_.invalid_type,expected:L_.function,received:e.parsedType}),q_;function n(t,n){return V_({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,X_(),j_].filter(t=\u003e!!t),issueData:{code:z_.invalid_arguments,argumentsError:n}})}function o(t,n){return V_({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,X_(),j_].filter(t=\u003e!!t),issueData:{code:z_.invalid_return_type,returnTypeError:n}})}const i={errorMap:e.common.contextualErrorMap},r=e.data;if(this._def.returns instanceof ax){const t=this;return K_(async function(...e){const s=new B_([]),a=await t._def.args.parseAsync(e,i).catch(t=\u003e{throw s.addIssue(n(e,t)),s}),c=await Reflect.apply(r,this,a);return await t._def.returns._def.type.parseAsync(c,i).catch(t=\u003e{throw s.addIssue(o(c,t)),s})})}{const t=this;return K_(function(...e){const s=t._def.args.safeParse(e,i);if(!s.success)throw new B_([n(e,s.error)]);const a=Reflect.apply(r,this,s.data),c=t._def.returns.safeParse(a,i);if(!c.success)throw new B_([o(a,c.error)]);return c.data})}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new t({...this._def,args:Jb.create(e).rest(jb.create())})}returns(e){return new t({...this._def,returns:e})}implement(t){return this.parse(t)}strictImplement(t){return this.parse(t)}static create(e,n,o){return new t({args:e||Jb.create([]).rest(jb.create()),returns:n||jb.create(),typeName:xx.ZodFunction,...rb(o)})}},nx=class extends ab{get schema(){return this._def.getter()}_parse(t){const{ctx:e}=this._processInputParams(t);return this._def.getter()._parse({data:e.data,path:e.path,parent:e})}};nx.create=(t,e)=\u003enew nx({getter:t,typeName:xx.ZodLazy,...rb(e)});var ox=class extends ab{_parse(t){if(t.data!==this._def.value){const e=this._getOrReturnCtx(t);return H_(e,{received:e.data,code:z_.invalid_literal,expected:this._def.value}),q_}return{status:\"valid\",value:t.data}}get value(){return this._def.value}};function ix(t,e){return new rx({values:t,typeName:xx.ZodEnum,...rb(e)})}ox.create=(t,e)=\u003enew ox({value:t,typeName:xx.ZodLiteral,...rb(e)});var rx=class t extends ab{_parse(t){if(\"string\"!=typeof t.data){const e=this._getOrReturnCtx(t),n=this._def.values;return H_(e,{expected:R_.joinValues(n),received:e.parsedType,code:z_.invalid_type}),q_}if(this._cache||(this._cache=new Set(this._def.values)),!this._cache.has(t.data)){const e=this._getOrReturnCtx(t),n=this._def.values;return H_(e,{received:e.data,code:z_.invalid_enum_value,options:n}),q_}return K_(t.data)}get options(){return this._def.values}get enum(){const t={};for(const e of this._def.values)t[e]=e;return t}get Values(){const t={};for(const e of this._def.values)t[e]=e;return t}get Enum(){const t={};for(const e of this._def.values)t[e]=e;return t}extract(e,n=this._def){return t.create(e,{...this._def,...n})}exclude(e,n=this._def){return t.create(this.options.filter(t=\u003e!e.includes(t)),{...this._def,...n})}};rx.create=ix;var sx=class extends ab{_parse(t){const e=R_.getValidEnumValues(this._def.values),n=this._getOrReturnCtx(t);if(n.parsedType!==L_.string\u0026\u0026n.parsedType!==L_.number){const t=R_.objectValues(e);return H_(n,{expected:R_.joinValues(t),received:n.parsedType,code:z_.invalid_type}),q_}if(this._cache||(this._cache=new Set(R_.getValidEnumValues(this._def.values))),!this._cache.has(t.data)){const t=R_.objectValues(e);return H_(n,{received:n.data,code:z_.invalid_enum_value,options:t}),q_}return K_(t.data)}get enum(){return this._def.values}};sx.create=(t,e)=\u003enew sx({values:t,typeName:xx.ZodNativeEnum,...rb(e)});var ax=class extends ab{unwrap(){return this._def.type}_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.promise\u0026\u0026!1===e.common.async)return H_(e,{code:z_.invalid_type,expected:L_.promise,received:e.parsedType}),q_;const n=e.parsedType===L_.promise?e.data:Promise.resolve(e.data);return K_(n.then(t=\u003ethis._def.type.parseAsync(t,{path:e.path,errorMap:e.common.contextualErrorMap})))}};ax.create=(t,e)=\u003enew ax({type:t,typeName:xx.ZodPromise,...rb(e)});var cx=class extends ab{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===xx.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(t){const{status:e,ctx:n}=this._processInputParams(t),o=this._def.effect||null,i={addIssue:t=\u003e{H_(n,t),t.fatal?e.abort():e.dirty()},get path(){return n.path}};if(i.addIssue=i.addIssue.bind(i),\"preprocess\"===o.type){const t=o.transform(n.data,i);if(n.common.async)return Promise.resolve(t).then(async t=\u003e{if(\"aborted\"===e.value)return q_;const o=await this._def.schema._parseAsync({data:t,path:n.path,parent:n});return\"aborted\"===o.status?q_:\"dirty\"===o.status||\"dirty\"===e.value?J_(o.value):o});{if(\"aborted\"===e.value)return q_;const o=this._def.schema._parseSync({data:t,path:n.path,parent:n});return\"aborted\"===o.status?q_:\"dirty\"===o.status||\"dirty\"===e.value?J_(o.value):o}}if(\"refinement\"===o.type){const t=t=\u003e{const e=o.refinement(t,i);if(n.common.async)return Promise.resolve(e);if(e instanceof Promise)throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");return t};if(!1===n.common.async){const o=this._def.schema._parseSync({data:n.data,path:n.path,parent:n});return\"aborted\"===o.status?q_:(\"dirty\"===o.status\u0026\u0026e.dirty(),t(o.value),{status:e.value,value:o.value})}return this._def.schema._parseAsync({data:n.data,path:n.path,parent:n}).then(n=\u003e\"aborted\"===n.status?q_:(\"dirty\"===n.status\u0026\u0026e.dirty(),t(n.value).then(()=\u003e({status:e.value,value:n.value}))))}if(\"transform\"===o.type){if(!1===n.common.async){const t=this._def.schema._parseSync({data:n.data,path:n.path,parent:n});if(!eb(t))return q_;const r=o.transform(t.value,i);if(r instanceof Promise)throw new Error(\"Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.\");return{status:e.value,value:r}}return this._def.schema._parseAsync({data:n.data,path:n.path,parent:n}).then(t=\u003eeb(t)?Promise.resolve(o.transform(t.value,i)).then(t=\u003e({status:e.value,value:t})):q_)}R_.assertNever(o)}};cx.create=(t,e,n)=\u003enew cx({schema:t,typeName:xx.ZodEffects,effect:e,...rb(n)}),cx.createWithPreprocess=(t,e,n)=\u003enew cx({schema:e,effect:{type:\"preprocess\",transform:t},typeName:xx.ZodEffects,...rb(n)});var lx=class extends ab{_parse(t){return this._getType(t)===L_.undefined?K_(void 0):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}};lx.create=(t,e)=\u003enew lx({innerType:t,typeName:xx.ZodOptional,...rb(e)});var dx=class extends ab{_parse(t){return this._getType(t)===L_.null?K_(null):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}};dx.create=(t,e)=\u003enew dx({innerType:t,typeName:xx.ZodNullable,...rb(e)});var hx=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t);let n=e.data;return e.parsedType===L_.undefined\u0026\u0026(n=this._def.defaultValue()),this._def.innerType._parse({data:n,path:e.path,parent:e})}removeDefault(){return this._def.innerType}};hx.create=(t,e)=\u003enew hx({innerType:t,typeName:xx.ZodDefault,defaultValue:\"function\"==typeof e.default?e.default:()=\u003ee.default,...rb(e)});var ux=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n={...e,common:{...e.common,issues:[]}},o=this._def.innerType._parse({data:n.data,path:n.path,parent:{...n}});return nb(o)?o.then(t=\u003e({status:\"valid\",value:\"valid\"===t.status?t.value:this._def.catchValue({get error(){return new B_(n.common.issues)},input:n.data})})):{status:\"valid\",value:\"valid\"===o.status?o.value:this._def.catchValue({get error(){return new B_(n.common.issues)},input:n.data})}}removeCatch(){return this._def.innerType}};ux.create=(t,e)=\u003enew ux({innerType:t,typeName:xx.ZodCatch,catchValue:\"function\"==typeof e.catch?e.catch:()=\u003ee.catch,...rb(e)});var px=class extends ab{_parse(t){if(this._getType(t)!==L_.nan){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.nan,received:e.parsedType}),q_}return{status:\"valid\",value:t.data}}};px.create=t=\u003enew px({typeName:xx.ZodNaN,...rb(t)});var mx=Symbol(\"zod_brand\"),gx=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n=e.data;return this._def.type._parse({data:n,path:e.path,parent:e})}unwrap(){return this._def.type}},fx=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.common.async){return(async()=\u003e{const t=await this._def.in._parseAsync({data:n.data,path:n.path,parent:n});return\"aborted\"===t.status?q_:\"dirty\"===t.status?(e.dirty(),J_(t.value)):this._def.out._parseAsync({data:t.value,path:n.path,parent:n})})()}{const t=this._def.in._parseSync({data:n.data,path:n.path,parent:n});return\"aborted\"===t.status?q_:\"dirty\"===t.status?(e.dirty(),{status:\"dirty\",value:t.value}):this._def.out._parseSync({data:t.value,path:n.path,parent:n})}}static create(e,n){return new t({in:e,out:n,typeName:xx.ZodPipeline})}},yx=class extends ab{_parse(t){const e=this._def.innerType._parse(t),n=t=\u003e(eb(t)\u0026\u0026(t.value=Object.freeze(t.value)),t);return nb(e)?e.then(t=\u003en(t)):n(e)}unwrap(){return this._def.innerType}};function _x(t,e){const n=\"function\"==typeof t?t(e):\"string\"==typeof t?{message:t}:t;return\"string\"==typeof n?{message:n}:n}function bx(t,e={},n){return t?Bb.create().superRefine((o,i)=\u003e{const r=t(o);if(r instanceof Promise)return r.then(t=\u003e{if(!t){const t=_x(e,o),r=t.fatal??n??!0;i.addIssue({code:\"custom\",...t,fatal:r})}});if(!r){const t=_x(e,o),r=t.fatal??n??!0;i.addIssue({code:\"custom\",...t,fatal:r})}}):Bb.create()}yx.create=(t,e)=\u003enew yx({innerType:t,typeName:xx.ZodReadonly,...rb(e)});var xx,vx,Sx={object:Wb.lazycreate};(vx=xx||(xx={})).ZodString=\"ZodString\",vx.ZodNumber=\"ZodNumber\",vx.ZodNaN=\"ZodNaN\",vx.ZodBigInt=\"ZodBigInt\",vx.ZodBoolean=\"ZodBoolean\",vx.ZodDate=\"ZodDate\",vx.ZodSymbol=\"ZodSymbol\",vx.ZodUndefined=\"ZodUndefined\",vx.ZodNull=\"ZodNull\",vx.ZodAny=\"ZodAny\",vx.ZodUnknown=\"ZodUnknown\",vx.ZodNever=\"ZodNever\",vx.ZodVoid=\"ZodVoid\",vx.ZodArray=\"ZodArray\",vx.ZodObject=\"ZodObject\",vx.ZodUnion=\"ZodUnion\",vx.ZodDiscriminatedUnion=\"ZodDiscriminatedUnion\",vx.ZodIntersection=\"ZodIntersection\",vx.ZodTuple=\"ZodTuple\",vx.ZodRecord=\"ZodRecord\",vx.ZodMap=\"ZodMap\",vx.ZodSet=\"ZodSet\",vx.ZodFunction=\"ZodFunction\",vx.ZodLazy=\"ZodLazy\",vx.ZodLiteral=\"ZodLiteral\",vx.ZodEnum=\"ZodEnum\",vx.ZodEffects=\"ZodEffects\",vx.ZodNativeEnum=\"ZodNativeEnum\",vx.ZodOptional=\"ZodOptional\",vx.ZodNullable=\"ZodNullable\",vx.ZodDefault=\"ZodDefault\",vx.ZodCatch=\"ZodCatch\",vx.ZodPromise=\"ZodPromise\",vx.ZodBranded=\"ZodBranded\",vx.ZodPipeline=\"ZodPipeline\",vx.ZodReadonly=\"ZodReadonly\";var Ix=(t,e={message:`Input not instance of ${t.name}`})=\u003ebx(e=\u003ee instanceof t,e),Cx=Rb.create,Px=Ab.create,Mx=px.create,Nx=Ob.create,wx=kb.create,Tx=Lb.create,Rx=Db.create,Ex=zb.create,Ax=Fb.create,Ox=Bb.create,kx=jb.create,Lx=$b.create,Dx=Yb.create,zx=Xb.create,Fx=Wb.create,Bx=Wb.strictCreate,jx=Hb.create,$x=Ub.create,Yx=qb.create,Xx=Jb.create,Vx=Kb.create,Wx=Qb.create,Hx=tx.create,Gx=ex.create,Ux=nx.create,Zx=ox.create,qx=rx.create,Jx=sx.create,Kx=ax.create,Qx=cx.create,tv=lx.create,ev=dx.create,nv=cx.createWithPreprocess,ov=fx.create,iv=()=\u003eCx().optional(),rv=()=\u003ePx().optional(),sv=()=\u003ewx().optional(),av={string:t=\u003eRb.create({...t,coerce:!0}),number:t=\u003eAb.create({...t,coerce:!0}),boolean:t=\u003ekb.create({...t,coerce:!0}),bigint:t=\u003eOb.create({...t,coerce:!0}),date:t=\u003eLb.create({...t,coerce:!0})},cv=q_,lv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"Ω\").value),dv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"F\").value).transform(t=\u003eNumber.parseFloat(t.toPrecision(12))),hv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"H\").value),uv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"V\").value),pv=k_.string().or(k_.number()).transform(t=\u003eT_(t).value),mv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"Hz\").value),gv=pv,fv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"A\").value),yv=k_.string().or(k_.number()).transform(t=\u003eT_(t).value),_v=yv,bv=yv,xv=k_.string().datetime(),vv=k_.string().or(k_.number()).transform(t=\u003e\"number\"==typeof t?t:t.endsWith(\"deg\")?Number.parseFloat(t.split(\"deg\")[0]):t.endsWith(\"rad\")?180*Number.parseFloat(t.split(\"rad\")[0])/Math.PI:Number.parseFloat(t)),Sv=k_.number().or(k_.string().endsWith(\"mAh\")).transform(t=\u003e{if(\"string\"==typeof t){const e=t.replace(\"mAh\",\"\"),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error(\"Invalid capacity\");return n}return t}).describe(\"Battery capacity in mAh\"),Iv=k_.object({x:gv,y:gv}),Cv=Iv,Pv=k_.object({x:gv,y:gv,z:gv}),Mv=Pv,Nv=k_.object({width:k_.number(),height:k_.number()}),wv=t=\u003ek_.string().optional().default(()=\u003e`${t}_${(t=\u003e{const e=\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";return Array.from({length:t},()=\u003ee[Math.floor(62*Math.random())]).join(\"\")})(10)}`),Tv=k_.enum([\"top_left\",\"top_center\",\"top_right\",\"center_left\",\"center\",\"center_right\",\"bottom_left\",\"bottom_center\",\"bottom_right\"]),Rv=k_.enum([\"top_silkscreen\",\"bottom_silkscreen\",\"top_copper\",\"bottom_copper\",\"top_soldermask\",\"bottom_soldermask\",\"top_fabrication_note\",\"bottom_fabrication_note\",\"top_user_note\",\"bottom_user_note\",\"top_courtyard\",\"bottom_courtyard\",\"inner1_copper\",\"inner2_copper\",\"inner3_copper\",\"inner4_copper\",\"inner5_copper\",\"inner6_copper\",\"inner7_copper\",\"inner8_copper\",\"edge_cuts\",\"drill\"]),Ev=k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()}),Av=Iv.extend({rotation:vv.optional()}),Ov=k_.object({size:Iv.optional(),thickness:gv.optional()}),kv=k_.object({font:Ov.optional()}),Lv=k_.object({value:k_.string(),at:Av.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:kv.optional()}),Dv=k_.object({Reference:Lv.optional(),Value:Lv.optional(),Datasheet:Lv.optional(),Description:Lv.optional()}),zv=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),Fv=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:Av.optional(),size:Iv.optional(),drill:gv.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),Bv=k_.object({path:k_.string(),offset:Pv.optional(),scale:Pv.optional(),rotate:Pv.optional()}),jv=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:Dv.optional(),attributes:zv.optional(),pads:k_.array(Fv).optional(),embeddedFonts:k_.boolean().optional(),model:Bv.optional()}),$v=k_.object({hide:k_.boolean().optional()}),Yv=k_.object({offset:gv.optional(),hide:k_.boolean().optional()}),Xv=k_.object({font:Ov.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),Vv=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:Av.optional(),effects:Xv.optional()}),Wv=k_.object({Reference:Vv.optional(),Value:Vv.optional(),Footprint:Vv.optional(),Datasheet:Vv.optional(),Description:Vv.optional(),ki_keywords:Vv.optional(),ki_fp_filters:Vv.optional()}),Hv=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:$v.optional(),pinNames:Yv.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:Wv.optional(),embeddedFonts:k_.boolean().optional()}),Gv=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),Uv=k_.enum([\"jlcpcb\",\"macrofab\",\"pcbway\",\"digikey\",\"mouser\",\"lcsc\"]),Zv=k_.object({type:k_.literal(\"source_component\"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(Uv,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),qv=Zv.extend({ftype:k_.literal(\"simple_capacitor\"),capacitance:dv,max_voltage_rating:uv.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:gv.optional()}),Jv=Zv.extend({ftype:k_.literal(\"simple_resistor\"),resistance:lv,display_resistance:k_.string().optional()}),Kv=Zv.extend({ftype:k_.literal(\"simple_diode\")}),Qv=Zv.extend({ftype:k_.literal(\"simple_fiducial\")}),tS=Kv.extend({ftype:k_.literal(\"simple_led\"),color:k_.string().optional(),wavelength:k_.string().optional()}),eS=Zv.extend({ftype:k_.literal(\"simple_ground\")}),nS=Zv.extend({ftype:k_.literal(\"simple_chip\")}),oS=Zv.extend({ftype:k_.literal(\"simple_power_source\"),voltage:uv}),iS=Zv.extend({ftype:k_.literal(\"simple_current_source\"),current:fv,frequency:mv.optional(),peak_to_peak_current:fv.optional(),wave_shape:k_.enum([\"sine\",\"square\",\"triangle\",\"sawtooth\",\"dc\"]).optional().default(\"dc\"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),rS=Zv.extend({ftype:k_.literal(\"simple_fuse\"),current_rating_amps:k_.number().describe(\"Nominal current in amps the fuse is rated for\"),voltage_rating_volts:k_.number().describe(\"Voltage rating in volts, e.g. ±5V would be 5\")}),sS=Zv.extend({ftype:k_.literal(\"simple_ammeter\")}),aS=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),cS=Zv.extend({ftype:k_.literal(\"simple_battery\"),capacity:Sv}),lS=Zv.extend({ftype:k_.literal(\"simple_inductor\"),inductance:hv,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),dS=Zv.extend({ftype:k_.literal(\"simple_push_button\")}),hS=Zv.extend({ftype:k_.literal(\"simple_potentiometer\"),max_resistance:lv,display_max_resistance:k_.string().optional()}),uS=Zv.extend({ftype:k_.literal(\"simple_crystal\"),frequency:k_.number().describe(\"Frequency in Hz\"),load_capacitance:k_.number().optional().describe(\"Load capacitance in pF\"),pin_variant:k_.enum([\"two_pin\",\"four_pin\"]).optional()}),pS=Zv.extend({ftype:k_.literal(\"simple_pin_header\"),pin_count:k_.number(),gender:k_.enum([\"male\",\"female\"]).optional().default(\"male\")}),mS=Zv.extend({ftype:k_.literal(\"simple_connector\"),standard:k_.enum([\"usb_c\",\"m2\"]).optional()}),gS=Zv.extend({ftype:k_.literal(\"simple_pinout\")}),fS=Zv.extend({ftype:k_.literal(\"simple_resonator\"),load_capacitance:dv,equivalent_series_resistance:lv.optional(),frequency:mv}),yS=Zv.extend({ftype:k_.literal(\"simple_transistor\"),transistor_type:k_.enum([\"npn\",\"pnp\"])}),_S=Zv.extend({ftype:k_.literal(\"simple_test_point\"),footprint_variant:k_.enum([\"pad\",\"through_hole\"]).optional(),pad_shape:k_.enum([\"rect\",\"circle\"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),bS=Zv.extend({ftype:k_.literal(\"simple_mosfet\"),channel_type:k_.enum([\"n\",\"p\"]),mosfet_mode:k_.enum([\"enhancement\",\"depletion\"])}),xS=Zv.extend({ftype:k_.literal(\"simple_op_amp\")}),vS=Zv.extend({ftype:k_.literal(\"simple_switch\")}),SS=k_.object({type:k_.literal(\"source_project_metadata\"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),source_filesystem_md5_hash:k_.string().optional(),created_at:xv.optional()}),IS=Gv.extend({type:k_.literal(\"source_missing_property_error\"),source_missing_property_error_id:wv(\"source_missing_property_error\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_missing_property_error\").default(\"source_missing_property_error\")}).describe(\"The source code is missing a property\"),CS=Gv.extend({type:k_.literal(\"source_failed_to_create_component_error\"),source_failed_to_create_component_error_id:wv(\"source_failed_to_create_component_error\"),error_type:k_.literal(\"source_failed_to_create_component_error\").default(\"source_failed_to_create_component_error\"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe(\"Error emitted when a component fails to be constructed\"),PS=Gv.extend({type:k_.literal(\"source_invalid_component_property_error\"),source_invalid_component_property_error_id:wv(\"source_invalid_component_property_error\"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_invalid_component_property_error\").default(\"source_invalid_component_property_error\")}).describe(\"The source component property is invalid\"),MS=Gv.extend({type:k_.literal(\"source_trace_not_connected_error\"),source_trace_not_connected_error_id:wv(\"source_trace_not_connected_error\"),error_type:k_.literal(\"source_trace_not_connected_error\").default(\"source_trace_not_connected_error\"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe(\"Occurs when a source trace selector does not match any ports\"),NS=k_.object({type:k_.literal(\"source_property_ignored_warning\"),source_property_ignored_warning_id:wv(\"source_property_ignored_warning\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_property_ignored_warning\").default(\"source_property_ignored_warning\"),message:k_.string()}).describe(\"The source property was ignored\"),wS=k_.object({type:k_.literal(\"source_pin_missing_trace_warning\"),source_pin_missing_trace_warning_id:wv(\"source_pin_missing_trace_warning\"),warning_type:k_.literal(\"source_pin_missing_trace_warning\").default(\"source_pin_missing_trace_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component pin is missing a trace connection\"),TS=k_.object({type:k_.literal(\"source_missing_manufacturer_part_number_warning\"),source_missing_manufacturer_part_number_warning_id:wv(\"source_missing_manufacturer_part_number_warning\"),warning_type:k_.literal(\"source_missing_manufacturer_part_number_warning\").default(\"source_missing_manufacturer_part_number_warning\"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a standard connector is missing manufacturer part number\"),RS=k_.object({type:k_.literal(\"source_refdes_convention_warning\"),source_refdes_convention_warning_id:wv(\"source_refdes_convention_warning\"),warning_type:k_.literal(\"source_refdes_convention_warning\").default(\"source_refdes_convention_warning\"),message:k_.string(),source_component_id:k_.string(),refdes:k_.string(),source_component_ftype:k_.string(),expected_prefixes:k_.array(k_.string()),actual_prefix:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component reference designator does not match the component type convention\"),ES=Zv.extend({ftype:k_.literal(\"simple_voltage_probe\")}),AS=Zv.extend({ftype:k_.literal(\"interconnect\")}),OS=Gv.extend({type:k_.literal(\"source_i2c_misconfigured_error\"),source_i2c_misconfigured_error_id:wv(\"source_i2c_misconfigured_error\"),error_type:k_.literal(\"source_i2c_misconfigured_error\").default(\"source_i2c_misconfigured_error\"),source_port_ids:k_.array(k_.string())}).describe(\"Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net\"),kS=Gv.extend({type:k_.literal(\"source_component_misconfigured_error\"),source_component_misconfigured_error_id:wv(\"source_component_misconfigured_error\"),error_type:k_.literal(\"source_component_misconfigured_error\").default(\"source_component_misconfigured_error\"),source_component_ids:k_.array(k_.string()),source_port_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when one or more source components have an invalid or conflicting configuration\"),LS=Zv.extend({ftype:k_.literal(\"simple_voltage_source\"),voltage:uv,frequency:mv.optional(),peak_to_peak_voltage:uv.optional(),wave_shape:k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]).optional(),phase:vv.optional(),duty_cycle:k_.number().optional().describe(\"Duty cycle as a fraction (0 to 1)\"),pulse_delay:bv.optional(),rise_time:bv.optional(),fall_time:bv.optional(),pulse_width:bv.optional(),period:bv.optional()}),DS=k_.union([Jv,qv,Kv,Qv,tS,eS,nS,oS,iS,sS,cS,lS,dS,hS,uS,pS,mS,gS,fS,vS,yS,_S,bS,xS,rS,ES,AS,LS,SS,IS,PS,CS,MS,NS,wS,TS,RS,OS,kS]),zS=k_.object({type:k_.literal(\"source_port\"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(aS),FS=k_.object({type:k_.literal(\"source_component_internal_connection\"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),BS=k_.object({type:k_.literal(\"source_trace\"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),name:k_.string().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),jS=k_.object({type:k_.literal(\"source_group\"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),$S=k_.object({type:k_.literal(\"source_net\"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),YS=k_.object({type:k_.literal(\"source_board\"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe(\"Defines a board in the source domain\"),XS=Gv.extend({type:k_.literal(\"source_ambiguous_port_reference\"),source_ambiguous_port_reference_id:wv(\"source_ambiguous_port_reference\"),error_type:k_.literal(\"source_ambiguous_port_reference\").default(\"source_ambiguous_port_reference\"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous\"),VS=k_.object({type:k_.literal(\"source_pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane in the source domain\"),WS=[\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\",\"inner7\",\"inner8\"],HS=k_.enum(WS),GS=HS.or(k_.object({name:HS})).transform(t=\u003e\"string\"==typeof t?t:t.name),US=k_.enum([\"top\",\"bottom\"]),ZS=k_.object({type:k_.literal(\"source_manually_placed_via\"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe(\"Defines a via that is manually placed in the source domain\"),qS=k_.object({type:k_.literal(\"source_unnamed_trace_warning\"),source_unnamed_trace_warning_id:wv(\"source_unnamed_trace_warning\"),warning_type:k_.literal(\"source_unnamed_trace_warning\").default(\"source_unnamed_trace_warning\"),message:k_.string(),source_trace_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source trace is missing a name\"),JS=k_.object({type:k_.literal(\"source_no_power_pin_defined_warning\"),source_no_power_pin_defined_warning_id:wv(\"source_no_power_pin_defined_warning\"),warning_type:k_.literal(\"source_no_power_pin_defined_warning\").default(\"source_no_power_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports with requires_power=true\"),KS=k_.object({type:k_.literal(\"source_no_ground_pin_defined_warning\"),source_no_ground_pin_defined_warning_id:wv(\"source_no_ground_pin_defined_warning\"),warning_type:k_.literal(\"source_no_ground_pin_defined_warning\").default(\"source_no_ground_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports marked as ground pins\"),QS=k_.object({type:k_.literal(\"source_component_pins_underspecified_warning\"),source_component_pins_underspecified_warning_id:wv(\"source_component_pins_underspecified_warning\"),warning_type:k_.literal(\"source_component_pins_underspecified_warning\").default(\"source_component_pins_underspecified_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when all ports on a source component are underspecified\"),tI=Gv.extend({type:k_.literal(\"source_pin_must_be_connected_error\"),source_pin_must_be_connected_error_id:wv(\"source_pin_must_be_connected_error\"),error_type:k_.literal(\"source_pin_must_be_connected_error\").default(\"source_pin_must_be_connected_error\"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pin with mustBeConnected attribute is not connected to any trace\"),eI=Gv.extend({type:k_.literal(\"unknown_error_finding_part\"),unknown_error_finding_part_id:wv(\"unknown_error_finding_part\"),error_type:k_.literal(\"unknown_error_finding_part\").default(\"unknown_error_finding_part\"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when an unexpected error occurs while finding a part\"),nI=k_.object({type:k_.literal(\"source_part_not_found_warning\"),source_part_not_found_warning_id:wv(\"source_part_not_found_warning\"),warning_type:k_.literal(\"source_part_not_found_warning\").default(\"source_part_not_found_warning\"),message:k_.string(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:Uv.optional(),manufacturer_part_number:k_.string().optional(),supplier_part_number:k_.string().optional(),part_name:k_.string().optional()}).describe(\"Warning emitted when a requested part can not be found\"),oI=k_.object({type:k_.literal(\"schematic_box\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:gv,height:gv,is_dashed:k_.boolean().default(!1),x:gv,y:gv,subcircuit_id:k_.string().optional()}).describe(\"Draws a box on the schematic\"),iI=k_.object({type:k_.literal(\"schematic_path\"),schematic_path_id:wv(\"schematic_path\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),is_dashed:k_.boolean().default(!1),stroke_width:gv.nullable().optional(),stroke_color:k_.string().optional(),dash_length:gv.optional(),dash_gap:gv.optional(),points:k_.array(Iv),subcircuit_id:k_.string().optional()}),rI=k_.record(k_.object({left_margin:pv.optional(),right_margin:pv.optional(),top_margin:pv.optional(),bottom_margin:pv.optional()})),sI=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),aI=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional()}),cI=k_.union([sI,aI]),lI=k_.object({type:k_.literal(\"schematic_component\"),size:Nv,center:Iv,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_sheet_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),pin_spacing:pv.optional(),pin_styles:rI.optional(),box_width:pv.optional(),symbol_name:k_.string().optional(),port_arrangement:cI.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),dI=k_.object({kicad_symbol:Hv.optional()}).catchall(k_.unknown()),hI=k_.object({type:k_.literal(\"schematic_symbol\"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:dI.optional()}).describe(\"Defines a named schematic symbol that can be referenced by components.\"),uI=k_.object({type:k_.literal(\"schematic_line\"),schematic_line_id:wv(\"schematic_line\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:gv,y1:gv,x2:gv,y2:gv,stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),dash_length:gv.optional(),dash_gap:gv.optional(),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled line on the schematic\"),pI=k_.object({type:k_.literal(\"schematic_rect\"),schematic_rect_id:wv(\"schematic_rect\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,width:gv,height:gv,rotation:vv.default(0),stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled rectangle on the schematic\"),mI=k_.object({type:k_.literal(\"schematic_circle\"),schematic_circle_id:wv(\"schematic_circle\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,radius:gv,stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled circle on the schematic\"),gI=k_.object({type:k_.literal(\"schematic_arc\"),schematic_arc_id:wv(\"schematic_arc\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,radius:gv,start_angle_degrees:vv,end_angle_degrees:vv,direction:k_.enum([\"clockwise\",\"counterclockwise\"]).default(\"counterclockwise\"),stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled arc on the schematic\"),fI=k_.object({type:k_.literal(\"schematic_trace\"),schematic_trace_id:k_.string(),schematic_sheet_id:k_.string().optional(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),yI=k_.enum([\"center\",\"left\",\"right\",\"top\",\"bottom\"]),_I=k_.object({type:k_.literal(\"schematic_text\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:gv,y:gv}),rotation:k_.number().default(0),anchor:k_.union([yI.describe(\"legacy\"),Tv]).default(\"center\"),color:k_.string().default(\"#000000\"),subcircuit_id:k_.string().optional()}),bI=k_.object({type:k_.literal(\"schematic_port\"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),center:Iv,facing_direction:k_.enum([\"up\",\"down\",\"left\",\"right\"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe(\"Defines a port on a schematic component\"),xI=k_.object({type:k_.literal(\"schematic_net_label\"),schematic_net_label_id:wv(\"schematic_net_label\"),schematic_sheet_id:k_.string().optional(),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:Iv,anchor_position:Iv.optional(),anchor_side:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),vI=Gv.extend({type:k_.literal(\"schematic_error\"),schematic_error_id:k_.string(),error_type:k_.literal(\"schematic_port_not_found\").default(\"schematic_port_not_found\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic error on the schematic\"),SI=Gv.extend({type:k_.literal(\"schematic_layout_error\"),schematic_layout_error_id:wv(\"schematic_layout_error\"),error_type:k_.literal(\"schematic_layout_error\").default(\"schematic_layout_error\"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when schematic layout fails for a group\"),II=k_.object({type:k_.literal(\"schematic_debug_object\"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),CI=II.extend({shape:k_.literal(\"rect\"),center:Iv,size:Nv}),PI=II.extend({shape:k_.literal(\"line\"),start:Iv,end:Iv}),MI=II.extend({shape:k_.literal(\"point\"),center:Iv}),NI=k_.discriminatedUnion(\"shape\",[CI,PI,MI]),wI=k_.object({type:k_.literal(\"schematic_voltage_probe\"),schematic_voltage_probe_id:k_.string(),schematic_sheet_id:k_.string().optional(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:Iv,schematic_trace_id:k_.string(),voltage:uv.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:Tv.optional()}).describe(\"Defines a voltage probe measurement point on a schematic trace\"),TI=k_.object({type:k_.literal(\"schematic_manual_edit_conflict_warning\"),schematic_manual_edit_conflict_warning_id:wv(\"schematic_manual_edit_conflict_warning\"),warning_type:k_.literal(\"schematic_manual_edit_conflict_warning\").default(\"schematic_manual_edit_conflict_warning\"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit schX/schY coordinates\"),RI=k_.object({type:k_.literal(\"schematic_group\"),schematic_group_id:wv(\"schematic_group\"),schematic_sheet_id:k_.string().optional(),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:pv,height:pv,center:Iv,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe(\"Defines a group of components on the schematic\"),EI=k_.object({type:k_.literal(\"schematic_table\"),schematic_table_id:wv(\"schematic_table\"),schematic_sheet_id:k_.string().optional(),anchor_position:Iv,column_widths:k_.array(gv),row_heights:k_.array(gv),cell_padding:gv.optional(),border_width:gv.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:Tv.optional()}).describe(\"Defines a table on the schematic\"),AI=k_.object({type:k_.literal(\"schematic_table_cell\"),schematic_table_cell_id:wv(\"schematic_table_cell\"),schematic_sheet_id:k_.string().optional(),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:Iv,width:gv,height:gv,horizontal_align:k_.enum([\"left\",\"center\",\"right\"]).optional(),vertical_align:k_.enum([\"top\",\"middle\",\"bottom\"]).optional(),font_size:gv.optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a cell within a schematic_table\"),OI=k_.object({type:k_.literal(\"schematic_sheet\"),schematic_sheet_id:wv(\"schematic_sheet\"),name:k_.string().optional(),sheet_index:k_.number().optional(),subcircuit_id:k_.string().optional(),outline_color:k_.string().optional()}).describe(\"Defines a schematic sheet or page that components can be placed on\"),kI=k_.object({x:gv,y:gv,bulge:k_.number().optional()}),LI=k_.object({vertices:k_.array(kI)}),DI=k_.object({outer_ring:LI,inner_rings:k_.array(LI).default([])}),zI=k_.object({x:gv,y:gv,via:k_.boolean().optional(),via_to_layer:GS.optional()}),FI=k_.array(zI),BI=k_.object({x:gv,y:gv,via:k_.boolean().optional(),to_layer:GS.optional(),trace_width:gv.optional()}),jI=k_.object({min_trace_width:pv.optional(),min_board_edge_clearance:pv.optional(),min_via_hole_edge_to_via_hole_edge_clearance:pv.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:pv.optional(),min_trace_to_pad_edge_clearance:pv.optional(),min_pad_edge_to_pad_edge_clearance:pv.optional(),min_same_net_trace_edge_to_trace_edge_clearance:pv.optional(),min_different_net_trace_edge_to_trace_edge_clearance:pv.optional(),min_via_edge_to_pad_edge_clearance:pv.optional(),min_via_hole_diameter:pv.optional(),min_via_pad_diameter:pv.optional()}),$I=k_.object({type:k_.literal(\"pcb_component\"),pcb_component_id:wv(\"pcb_component\"),source_component_id:k_.string(),center:Iv,layer:GS,rotation:vv,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this part, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this part, usually corresponding with how the user specified it\"),width:pv,height:pv,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"relative_to_another_component\",\"none\"]).optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:Iv.optional(),insertion_direction:k_.enum([\"from_above\",\"from_left\",\"from_right\",\"from_front\",\"from_back\"]).optional(),metadata:k_.object({kicad_footprint:jv.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe(\"Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath\")}).describe(\"Defines a component on the PCB\"),YI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),hole_diameter:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),XI=YI.describe(\"Defines a circular hole on the PCB\"),VI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),WI=VI.describe(\"Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.\"),HI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"square\"]),hole_diameter:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),GI=HI.describe(\"Defines a circular or square hole on the PCB\"),UI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"oval\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),ZI=UI.describe(\"Defines an oval hole on the PCB\"),qI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),JI=qI.describe(\"Defines a pill-shaped hole on the PCB\"),KI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,ccw_rotation:vv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),QI=KI.describe(\"Defines a rotated pill-shaped hole on the PCB\"),tC=HI.or(UI).or(qI).or(KI).or(YI).or(VI),eC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),nC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.enum([\"oval\",\"pill\"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,ccw_rotation:vv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),oC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circular_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),pad_shape:k_.literal(\"rect\"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:vv.optional()}),iC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),rC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"rotated_pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:vv,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:vv,hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),sC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"hole_with_polygon_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"oval\",\"pill\",\"rotated_pill\"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:gv,y:gv})).min(3),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),ccw_rotation:vv.optional()}),aC=k_.union([eC,nC,oC,iC,rC,sC]),cC=k_.object({type:k_.literal(\"pcb_port\"),pcb_port_id:wv(\"pcb_port\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:gv,y:gv,layers:k_.array(GS),is_board_pinout:k_.boolean().optional()}).describe(\"Defines a port on the PCB\"),lC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"circle\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,radius:k_.number(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),dC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rect\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),hC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_rect\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:vv,layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),uC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"pill\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),pC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_pill\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:vv,layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),mC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"polygon\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(Iv),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),gC=k_.discriminatedUnion(\"shape\",[lC,dC,hC,pC,uC,mC]).describe(\"Defines an SMT pad on the PCB\"),fC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"circle\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,radius:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),yC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rect\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),_C=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"pill\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),bC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rotated_rect\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),ccw_rotation:gv,layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),xC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"oval\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),vC=k_.union([fC,yC,_C,bC,xC]).describe(\"Defines solderpaste on the PCB\"),SC=k_.object({type:k_.literal(\"pcb_text\"),pcb_text_id:wv(\"pcb_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:Iv,layer:GS,width:pv,height:pv,lines:k_.number(),align:k_.enum([\"bottom-left\"])}).describe(\"Defines text on the PCB\"),IC=k_.object({route_type:k_.literal(\"wire\"),x:gv,y:gv,width:gv,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:GS}),CC=k_.object({route_type:k_.literal(\"via\"),x:gv,y:gv,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:gv.optional(),outer_diameter:gv.optional(),from_layer:GS,to_layer:GS}),PC=k_.object({route_type:k_.literal(\"through_pad\"),start:Iv,end:Iv,width:gv,start_layer:GS,end_layer:GS,pcb_smtpad_id:k_.string().optional(),pcb_plated_hole_id:k_.string().optional()}),MC=k_.union([IC,CC,PC]),NC=k_.object({type:k_.literal(\"pcb_trace\"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:wv(\"pcb_trace\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum([\"constant\",\"interpolated\"]).default(\"constant\").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(MC)}).describe(\"Defines a trace on the PCB\"),wC=k_.object({type:k_.literal(\"pcb_trace_warning\"),pcb_trace_warning_id:wv(\"pcb_trace_warning\"),warning_type:k_.literal(\"pcb_trace_warning\").default(\"pcb_trace_warning\"),message:k_.string(),center:Iv.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace warning on the PCB\"),TC=k_.object({type:k_.literal(\"pcb_trace_too_long_warning\"),pcb_trace_too_long_warning_id:wv(\"pcb_trace_too_long_warning\"),warning_type:k_.literal(\"pcb_trace_too_long_warning\").default(\"pcb_trace_too_long_warning\"),message:k_.string(),pcb_trace_id:k_.string(),source_net_id:k_.string().optional(),source_trace_id:k_.string().optional(),actual_trace_length:gv,maximum_trace_length:gv,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a PCB trace is longer than its maximum allowed length\"),RC=Gv.extend({type:k_.literal(\"pcb_trace_error\"),pcb_trace_error_id:wv(\"pcb_trace_error\"),error_type:k_.literal(\"pcb_trace_error\").default(\"pcb_trace_error\"),center:Iv.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB\"),EC=Gv.extend({type:k_.literal(\"pcb_trace_missing_error\"),pcb_trace_missing_error_id:wv(\"pcb_trace_missing_error\"),error_type:k_.literal(\"pcb_trace_missing_error\").default(\"pcb_trace_missing_error\"),center:Iv.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a source trace has no corresponding PCB trace\"),AC=Gv.extend({type:k_.literal(\"pcb_port_not_matched_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_port_not_matched_error\").default(\"pcb_port_not_matched_error\"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB where a port is not matched\"),OC=Gv.extend({type:k_.literal(\"pcb_port_not_connected_error\"),pcb_port_not_connected_error_id:wv(\"pcb_port_not_connected_error\"),error_type:k_.literal(\"pcb_port_not_connected_error\").default(\"pcb_port_not_connected_error\"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a pcb port is not connected to any trace\"),kC=k_.object({type:k_.literal(\"pcb_net\"),pcb_net_id:wv(\"pcb_net\"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe(\"Defines a net on the PCB\"),LC=k_.object({type:k_.literal(\"pcb_via\"),pcb_via_id:wv(\"pcb_via\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:gv,y:gv,outer_diameter:gv.default(\"0.6mm\"),hole_diameter:gv.default(\"0.25mm\"),from_layer:GS.optional(),to_layer:GS.optional(),layers:k_.array(GS),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe(\"Defines a via on the PCB\"),DC=k_.object({type:k_.literal(\"pcb_board\"),pcb_board_id:wv(\"pcb_board\"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:pv.optional(),height:pv.optional(),center:Iv,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this board, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this board, usually corresponding with how the user specified it\"),thickness:pv.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(Iv).optional(),shape:k_.enum([\"rect\",\"polygon\"]).optional(),material:k_.enum([\"fr4\",\"fr1\"]).default(\"fr4\"),solder_mask_color:k_.string().optional(),silkscreen_color:k_.string().optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.optional(),position_mode:k_.enum([\"relative_to_panel_anchor\",\"none\"]).optional()}).merge(jI).describe(\"Defines the board outline of the PCB\"),zC=k_.object({type:k_.literal(\"pcb_panel\"),pcb_panel_id:wv(\"pcb_panel\"),width:pv,height:pv,center:Iv,thickness:pv.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe(\"Defines a PCB panel that can contain multiple boards\"),FC=Gv.extend({type:k_.literal(\"pcb_placement_error\"),pcb_placement_error_id:wv(\"pcb_placement_error\"),error_type:k_.literal(\"pcb_placement_error\").default(\"pcb_placement_error\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a placement error on the PCB\"),BC=Gv.extend({type:k_.literal(\"pcb_panelization_placement_error\"),pcb_panelization_placement_error_id:wv(\"pcb_panelization_placement_error\"),error_type:k_.literal(\"pcb_panelization_placement_error\").default(\"pcb_panelization_placement_error\"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a panelization placement error on the PCB\"),jC=k_.object({type:k_.literal(\"pcb_trace_hint\"),pcb_trace_hint_id:wv(\"pcb_trace_hint\"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(BI),subcircuit_id:k_.string().optional()}).describe(\"A hint that can be used during generation of a PCB trace\"),$C=k_.object({type:k_.literal(\"pcb_silkscreen_line\"),pcb_silkscreen_line_id:wv(\"pcb_silkscreen_line\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:gv.default(\"0.1mm\"),x1:gv,y1:gv,x2:gv,y2:gv,layer:US}).describe(\"Defines a silkscreen line on the PCB\"),YC=k_.object({type:k_.literal(\"pcb_silkscreen_path\"),pcb_silkscreen_path_id:wv(\"pcb_silkscreen_path\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,route:k_.array(Iv),stroke_width:pv}).describe(\"Defines a silkscreen path on the PCB\"),XC=k_.object({type:k_.literal(\"pcb_silkscreen_text\"),pcb_silkscreen_text_id:wv(\"pcb_silkscreen_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:pv,top:pv,bottom:pv,right:pv}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:GS,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:Tv.default(\"center\")}).describe(\"Defines silkscreen text on the PCB\"),VC=k_.object({type:k_.literal(\"pcb_copper_text\"),pcb_copper_text_id:wv(\"pcb_copper_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:pv,top:pv,bottom:pv,right:pv}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:GS,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:Tv.default(\"center\")}).describe(\"Defines copper text on the PCB\"),WC=k_.object({type:k_.literal(\"pcb_silkscreen_rect\"),pcb_silkscreen_rect_id:wv(\"pcb_silkscreen_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:GS,stroke_width:pv.default(\"1mm\"),corner_radius:pv.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen rect on the PCB\"),HC=k_.object({type:k_.literal(\"pcb_silkscreen_circle\"),pcb_silkscreen_circle_id:wv(\"pcb_silkscreen_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:pv,layer:US,stroke_width:pv.default(\"1mm\"),is_filled:k_.boolean().optional()}).describe(\"Defines a silkscreen circle on the PCB\"),GC=k_.object({type:k_.literal(\"pcb_silkscreen_oval\"),pcb_silkscreen_oval_id:wv(\"pcb_silkscreen_oval\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius_x:gv,radius_y:gv,layer:US,ccw_rotation:vv.optional()}).describe(\"Defines a silkscreen oval on the PCB\"),UC=k_.object({type:k_.literal(\"pcb_silkscreen_graphic\"),pcb_silkscreen_graphic_id:wv(\"pcb_silkscreen_graphic\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,image_asset:Ev.optional()}).extend({shape:k_.literal(\"brep\"),brep_shape:DI}).describe(\"Defines a BRep silkscreen graphic on the PCB\"),ZC=k_.discriminatedUnion(\"shape\",[UC]).describe(\"Defines a silkscreen graphic on the PCB\"),qC=k_.object({type:k_.literal(\"pcb_silkscreen_pill\"),pcb_silkscreen_pill_id:wv(\"pcb_silkscreen_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:GS,ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen pill on the PCB\"),JC=k_.object({type:k_.literal(\"pcb_fabrication_note_text\"),pcb_fabrication_note_text_id:wv(\"pcb_fabrication_note_text\"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"1mm\"),pcb_component_id:k_.string(),text:k_.string(),ccw_rotation:k_.number().optional(),layer:US,anchor_position:Iv.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),color:k_.string().optional()}).describe(\"Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators\"),KC=k_.object({type:k_.literal(\"pcb_fabrication_note_path\"),pcb_fabrication_note_path_id:wv(\"pcb_fabrication_note_path\"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:GS,route:k_.array(Iv),stroke_width:pv,color:k_.string().optional()}).describe(\"Defines a fabrication path on the PCB for fabricators or assemblers\"),QC=k_.object({type:k_.literal(\"pcb_fabrication_note_rect\"),pcb_fabrication_note_rect_id:wv(\"pcb_fabrication_note_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US,stroke_width:pv.default(\"0.1mm\"),corner_radius:pv.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a fabrication note rectangle on the PCB\"),tP=k_.object({type:k_.literal(\"pcb_fabrication_note_dimension\"),pcb_fabrication_note_dimension_id:wv(\"pcb_fabrication_note_dimension\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,from:Iv,to:Iv,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:pv.optional(),offset_distance:pv.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:pv.default(\"1mm\"),color:k_.string().optional(),arrow_size:pv.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB fabrication notes\"),eP=k_.object({type:k_.literal(\"pcb_note_text\"),pcb_note_text_id:wv(\"pcb_note_text\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"1mm\"),text:k_.string().optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),layer:US.default(\"top\"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a documentation note in text on the PCB\"),nP=k_.object({type:k_.literal(\"pcb_note_rect\"),pcb_note_rect_id:wv(\"pcb_note_rect\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US.default(\"top\"),stroke_width:pv.default(\"0.1mm\"),corner_radius:pv.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a rectangular documentation note on the PCB\"),oP=k_.object({type:k_.literal(\"pcb_note_path\"),pcb_note_path_id:wv(\"pcb_note_path\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(Iv),layer:US.default(\"top\"),stroke_width:pv.default(\"0.1mm\"),color:k_.string().optional()}).describe(\"Defines a polyline documentation note on the PCB\"),iP=k_.object({type:k_.literal(\"pcb_note_line\"),pcb_note_line_id:wv(\"pcb_note_line\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:gv,y1:gv,x2:gv,y2:gv,layer:US.default(\"top\"),stroke_width:gv.default(\"0.1mm\"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe(\"Defines a straight documentation note line on the PCB\"),rP=k_.object({type:k_.literal(\"pcb_note_dimension\"),pcb_note_dimension_id:wv(\"pcb_note_dimension\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:Iv,to:Iv,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:pv.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:pv.default(\"1mm\"),layer:US.default(\"top\"),color:k_.string().optional(),arrow_size:pv.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB documentation notes\"),sP=Gv.extend({type:k_.literal(\"pcb_footprint_overlap_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_footprint_overlap_error\").default(\"pcb_footprint_overlap_error\"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when a pcb footprint overlaps with another element\"),aP=Gv.extend({type:k_.literal(\"pcb_courtyard_overlap_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_courtyard_overlap_error\").default(\"pcb_courtyard_overlap_error\"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe(\"Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another\"),cP=k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"rect\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:gv,height:gv,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:gv,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),lP=k_.object({type:k_.literal(\"pcb_cutout\"),pcb_cutout_id:wv(\"pcb_cutout\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),dP=lP.extend({shape:k_.literal(\"rect\"),center:Iv,width:pv,height:pv,rotation:vv.optional(),corner_radius:pv.optional()}),hP=lP.extend({shape:k_.literal(\"circle\"),center:Iv,radius:pv}),uP=lP.extend({shape:k_.literal(\"polygon\"),points:k_.array(Iv)}),pP=lP.extend({shape:k_.literal(\"path\"),route:k_.array(Iv),slot_width:pv,slot_length:pv.optional(),space_between_slots:pv.optional(),slot_corner_radius:pv.optional()}),mP=k_.discriminatedUnion(\"shape\",[dP,hP,uP,pP]).describe(\"Defines a cutout on the PCB, removing board material.\"),gP=Gv.extend({type:k_.literal(\"pcb_missing_footprint_error\"),pcb_missing_footprint_error_id:wv(\"pcb_missing_footprint_error\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"pcb_missing_footprint_error\").default(\"pcb_missing_footprint_error\"),source_component_id:k_.string()}).describe(\"Defines a missing footprint error on the PCB\"),fP=Gv.extend({type:k_.literal(\"external_footprint_load_error\"),external_footprint_load_error_id:wv(\"external_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal(\"external_footprint_load_error\").default(\"external_footprint_load_error\")}).describe(\"Defines an error when an external footprint fails to load\"),yP=Gv.extend({type:k_.literal(\"circuit_json_footprint_load_error\"),circuit_json_footprint_load_error_id:wv(\"circuit_json_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"circuit_json_footprint_load_error\").default(\"circuit_json_footprint_load_error\"),circuit_json:k_.array(k_.any()).optional()}).describe(\"Defines an error when a circuit JSON footprint fails to load\"),_P=k_.object({type:k_.literal(\"pcb_group\"),pcb_group_id:wv(\"pcb_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:pv.optional(),height:pv.optional(),center:Iv,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this group, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this group, usually corresponding with how the user specified it\"),outline:k_.array(Iv).optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.default(\"center\"),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"none\"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum([\"packed\",\"none\"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:pv}).optional(),autorouter_used_string:k_.string().optional()}).describe(\"Defines a group of components on the PCB\"),bP=Gv.extend({type:k_.literal(\"pcb_autorouting_error\"),pcb_error_id:wv(\"pcb_autorouting_error\"),error_type:k_.literal(\"pcb_autorouting_error\").default(\"pcb_autorouting_error\"),subcircuit_id:k_.string().optional()}).describe(\"The autorouting has failed to route a portion of the board\"),xP=k_.object({type:k_.literal(\"pcb_manual_edit_conflict_warning\"),pcb_manual_edit_conflict_warning_id:wv(\"pcb_manual_edit_conflict_warning\"),warning_type:k_.literal(\"pcb_manual_edit_conflict_warning\").default(\"pcb_manual_edit_conflict_warning\"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates\"),vP=k_.enum([\"x-\",\"x+\",\"y+\",\"y-\"]),SP=k_.object({type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\"),pcb_connector_not_in_accessible_orientation_warning_id:wv(\"pcb_connector_not_in_accessible_orientation_warning\"),warning_type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\").default(\"pcb_connector_not_in_accessible_orientation_warning\"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:vP,recommended_facing_direction:vP,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction\"),IP=k_.object({type:k_.literal(\"supplier_footprint_mismatch_warning\"),supplier_footprint_mismatch_warning_id:wv(\"supplier_footprint_mismatch_warning\"),warning_type:k_.literal(\"supplier_footprint_mismatch_warning\").default(\"supplier_footprint_mismatch_warning\"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:Uv.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe(\"Warning emitted when a supplier part footprint does not match the expected footprint\"),CP=k_.object({type:k_.literal(\"pcb_breakout_point\"),pcb_breakout_point_id:wv(\"pcb_breakout_point\"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:gv,y:gv}).describe(\"Defines a routing target within a pcb_group for a source_trace or source_net\"),PP=k_.object({type:k_.literal(\"pcb_ground_plane\"),pcb_ground_plane_id:wv(\"pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane on the PCB\"),MP=k_.object({type:k_.literal(\"pcb_ground_plane_region\"),pcb_ground_plane_region_id:wv(\"pcb_ground_plane_region\"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:GS,points:k_.array(Iv)}).describe(\"Defines a polygon region of a ground plane\"),NP=k_.object({type:k_.literal(\"pcb_thermal_spoke\"),pcb_thermal_spoke_id:wv(\"pcb_thermal_spoke\"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:gv,spoke_inner_diameter:gv,spoke_outer_diameter:gv,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Pattern for connecting a ground plane to a plated hole\"),wP=k_.object({type:k_.literal(\"pcb_copper_pour\"),pcb_copper_pour_id:wv(\"pcb_copper_pour\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:GS,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),TP=wP.extend({shape:k_.literal(\"rect\"),center:Iv,width:pv,height:pv,rotation:vv.optional()}),RP=wP.extend({shape:k_.literal(\"brep\"),brep_shape:DI}),EP=wP.extend({shape:k_.literal(\"polygon\"),points:k_.array(Iv)}),AP=k_.discriminatedUnion(\"shape\",[TP,RP,EP]).describe(\"Defines a copper pour on the PCB.\"),OP=Gv.extend({type:k_.literal(\"pcb_component_outside_board_error\"),pcb_component_outside_board_error_id:wv(\"pcb_component_outside_board_error\"),error_type:k_.literal(\"pcb_component_outside_board_error\").default(\"pcb_component_outside_board_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Iv,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a PCB component is placed outside the board boundaries\"),kP=Gv.extend({type:k_.literal(\"pcb_component_not_on_board_edge_error\"),pcb_component_not_on_board_edge_error_id:wv(\"pcb_component_not_on_board_edge_error\"),error_type:k_.literal(\"pcb_component_not_on_board_edge_error\").default(\"pcb_component_not_on_board_edge_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Iv,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component that must be placed on the board edge is centered away from the edge\"),LP=Gv.extend({type:k_.literal(\"pcb_component_invalid_layer_error\"),pcb_component_invalid_layer_error_id:wv(\"pcb_component_invalid_layer_error\"),error_type:k_.literal(\"pcb_component_invalid_layer_error\").default(\"pcb_component_invalid_layer_error\"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:GS,subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)\"),DP=Gv.extend({type:k_.literal(\"pcb_via_clearance_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_via_clearance_error\").default(\"pcb_via_clearance_error\"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when vias are closer than the allowed clearance\"),zP=Gv.extend({type:k_.literal(\"pcb_via_trace_clearance_error\"),pcb_via_trace_clearance_error_id:wv(\"pcb_via_trace_clearance_error\"),error_type:k_.literal(\"pcb_via_trace_clearance_error\").default(\"pcb_via_trace_clearance_error\"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a via and trace are closer than the allowed clearance\"),FP=Gv.extend({type:k_.literal(\"pcb_pad_pad_clearance_error\"),pcb_pad_pad_clearance_error_id:wv(\"pcb_pad_pad_clearance_error\"),error_type:k_.literal(\"pcb_pad_pad_clearance_error\").default(\"pcb_pad_pad_clearance_error\"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when pads are closer than the allowed clearance\"),BP=Gv.extend({type:k_.literal(\"pcb_pad_trace_clearance_error\"),pcb_pad_trace_clearance_error_id:wv(\"pcb_pad_trace_clearance_error\"),error_type:k_.literal(\"pcb_pad_trace_clearance_error\").default(\"pcb_pad_trace_clearance_error\"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pad and trace are closer than allowed clearance\"),jP=k_.object({type:k_.literal(\"pcb_courtyard_rect\"),pcb_courtyard_rect_id:wv(\"pcb_courtyard_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US,ccw_rotation:vv.optional(),color:k_.string().optional()}).describe(\"Defines a courtyard rectangle on the PCB\"),$P=k_.object({type:k_.literal(\"pcb_courtyard_outline\"),pcb_courtyard_outline_id:wv(\"pcb_courtyard_outline\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,outline:k_.array(Iv).min(2)}).describe(\"Defines a courtyard outline on the PCB\"),YP=k_.object({type:k_.literal(\"pcb_courtyard_polygon\"),pcb_courtyard_polygon_id:wv(\"pcb_courtyard_polygon\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,points:k_.array(Iv).min(3),color:k_.string().optional()}).describe(\"Defines a courtyard polygon on the PCB\"),XP=k_.object({type:k_.literal(\"pcb_courtyard_circle\"),pcb_courtyard_circle_id:wv(\"pcb_courtyard_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:pv,layer:US,color:k_.string().optional()}).describe(\"Defines a courtyard circle on the PCB\"),VP=k_.object({type:k_.literal(\"pcb_courtyard_pill\"),pcb_courtyard_pill_id:wv(\"pcb_courtyard_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,radius:pv,layer:US,color:k_.string().optional()}).describe(\"Defines a courtyard pill on the PCB\"),WP=[\"obj\",\"stl\",\"3mf\",\"gltf\",\"glb\",\"step\",\"wrl\"],HP=[\"x+\",\"x-\",\"y+\",\"y-\",\"z+\",\"z-\"],GP={obj:\"z+\",stl:\"z+\",\"3mf\":\"z+\",gltf:\"y+\",glb:\"y+\",step:\"z+\",wrl:\"y+\"},UP=k_.object({type:k_.literal(\"cad_component\"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:Pv,rotation:Pv.optional(),size:Pv.optional(),layer:GS.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:Ev.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum(HP).optional().describe('The direction in the model\\'s coordinate space that is considered \"up\" or \"coming out of the board surface\"'),model_origin_position:Pv.optional(),model_origin_alignment:k_.enum([\"unknown\",\"center\",\"center_of_component_on_board_surface\",\"bottom_center_of_component\"]).optional(),model_object_fit:k_.enum([\"contain_within_bounds\",\"fill_bounds\"]).optional().default(\"contain_within_bounds\"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),show_as_bounding_box:k_.boolean().optional(),anchor_alignment:k_.enum([\"center\",\"center_of_component_on_board_surface\"]).optional().default(\"center\")}).describe(\"Defines a component on the PCB\"),ZP=k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]),qP=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),JP=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:wv(\"simulation_voltage_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:uv}).describe(\"Defines a DC voltage source for simulation\"),KP=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:wv(\"simulation_voltage_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:uv.optional(),frequency:mv.optional(),peak_to_peak_voltage:uv.optional(),wave_shape:ZP.optional(),phase:vv.optional(),duty_cycle:qP.optional(),pulse_delay:bv.optional(),rise_time:bv.optional(),fall_time:bv.optional(),pulse_width:bv.optional(),period:bv.optional()}).describe(\"Defines an AC voltage source for simulation\"),QP=k_.union([JP,KP]).describe(\"Defines a voltage source for simulation\"),tM=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),eM=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:wv(\"simulation_current_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:fv}).describe(\"Defines a DC current source for simulation\"),nM=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:wv(\"simulation_current_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:fv.optional(),frequency:mv.optional(),peak_to_peak_current:fv.optional(),wave_shape:ZP.optional(),phase:vv.optional(),duty_cycle:tM.optional()}).describe(\"Defines an AC current source for simulation\"),oM=k_.union([eM,nM]).describe(\"Defines a current source for simulation\"),iM=k_.union([k_.literal(\"spice_dc_sweep\"),k_.literal(\"spice_dc_operating_point\"),k_.literal(\"spice_transient_analysis\"),k_.literal(\"spice_ac_analysis\")]),rM=k_.object({method:k_.enum([\"trap\",\"gear\"]).optional(),reltol:k_.union([k_.number(),k_.string()]).optional(),abstol:k_.union([k_.number(),k_.string()]).optional(),vntol:k_.union([k_.number(),k_.string()]).optional()}).describe(\"SPICE solver options for a simulation experiment\"),sM=k_.object({type:k_.literal(\"simulation_experiment\"),simulation_experiment_id:wv(\"simulation_experiment\"),name:k_.string(),experiment_type:iM,time_per_step:yv.optional(),start_time_ms:bv.optional(),end_time_ms:bv.optional(),spice_options:rM.optional()}).describe(\"Defines a simulation experiment configuration\"),aM=k_.object({type:k_.literal(\"simulation_transient_voltage_graph\"),simulation_transient_voltage_graph_id:wv(\"simulation_transient_voltage_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:yv,start_time_ms:bv,end_time_ms:bv,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores voltage measurements over time for a simulation\"),cM=k_.object({type:k_.literal(\"simulation_transient_current_graph\"),simulation_transient_current_graph_id:wv(\"simulation_transient_current_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),current_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:yv,start_time_ms:bv,end_time_ms:bv,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores current measurements over time for a simulation\"),lM=k_.object({type:k_.literal(\"simulation_switch\"),simulation_switch_id:wv(\"simulation_switch\"),source_component_id:k_.string().optional(),closes_at:bv.optional(),opens_at:bv.optional(),starts_closed:k_.boolean().optional(),switching_frequency:mv.optional()}).describe(\"Defines a switch for simulation timing control\"),dM=k_.object({type:k_.literal(\"simulation_voltage_probe\"),simulation_voltage_probe_id:wv(\"simulation_voltage_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.\").superRefine((t,e)=\u003e{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n\u0026\u0026o?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a differential probe.\"}):n?t.signal_input_source_port_id\u0026\u0026t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id.\"}):o\u0026\u0026(t.signal_input_source_net_id\u0026\u0026t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id.\"}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id.\"})}),hM=k_.object({type:k_.literal(\"simulation_current_probe\"),simulation_current_probe_id:wv(\"simulation_current_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a current probe for simulation. It measures current flowing from the positive endpoint to the negative endpoint.\").superRefine((t,e)=\u003e{const n=!!t.positive_source_port_id,o=!!t.negative_source_port_id,i=!!t.positive_source_net_id,r=!!t.negative_source_net_id,s=n||o,a=i||r;s\u0026\u0026a?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a current probe.\"}):s?n\u0026\u0026o||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Current probe using source ports requires both positive_source_port_id and negative_source_port_id.\"}):a?i\u0026\u0026r||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Current probe using source nets requires both positive_source_net_id and negative_source_net_id.\"}):e.addIssue({code:k_.ZodIssueCode.custom,message:\"A current probe must have either positive/negative source port ids or positive/negative source net ids.\"})}),uM=Gv.extend({type:k_.literal(\"simulation_unknown_experiment_error\"),simulation_unknown_experiment_error_id:wv(\"simulation_unknown_experiment_error\"),error_type:k_.literal(\"simulation_unknown_experiment_error\").default(\"simulation_unknown_experiment_error\"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"An unknown error occurred during the simulation experiment.\"),pM=k_.object({type:k_.literal(\"simulation_op_amp\"),simulation_op_amp_id:wv(\"simulation_op_amp\"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe(\"Defines a simple ideal operational amplifier for simulation\"),mM=k_.object({type:k_.literal(\"simulation_spice_subcircuit\"),simulation_spice_subcircuit_id:wv(\"simulation_spice_subcircuit\"),source_component_id:k_.string(),spice_pin_to_source_port_map:k_.record(k_.string(),k_.string()),subcircuit_source:k_.string()}).describe(\"Defines a custom SPICE subcircuit model for simulation\"),gM=t=\u003evoid 0!==t,fM=k_.object({type:k_.literal(\"simulation_oscilloscope_trace\"),simulation_oscilloscope_trace_id:wv(\"simulation_oscilloscope_trace\"),simulation_transient_voltage_graph_id:k_.string().optional(),simulation_transient_current_graph_id:k_.string().optional(),simulation_voltage_probe_id:k_.string().optional(),simulation_current_probe_id:k_.string().optional(),display_name:k_.string().optional(),color:k_.string().optional(),display_center_value:k_.number().optional(),display_center_offset_divs:k_.number().optional(),volts_per_div:k_.number().positive().optional(),amps_per_div:k_.number().positive().optional()}).describe(\"Defines how a simulation measurement is rendered as an oscilloscope-style trace.\").superRefine((t,e)=\u003e{const n=[t.simulation_transient_voltage_graph_id,t.simulation_voltage_probe_id].filter(gM).length,o=[t.simulation_transient_current_graph_id,t.simulation_current_probe_id].filter(gM).length;n+o!==1\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"An oscilloscope trace must reference exactly one voltage graph, current graph, voltage probe, or current probe.\"}),n\u003e0\u0026\u0026void 0!==t.amps_per_div\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"Voltage oscilloscope traces must use volts_per_div, not amps_per_div.\"}),o\u003e0\u0026\u0026void 0!==t.volts_per_div\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"Current oscilloscope traces must use amps_per_div, not volts_per_div.\"})}),yM=k_.union([BS,zS,FS,DS,$S,jS,nS,qv,Kv,tS,Jv,oS,cS,lS,pS,gS,fS,vS,yS,_S,bS,xS,hS,dS,VS,ZS,YS,SS,PS,MS,wS,qS,TS,RS,JS,KS,QS,tI,eI,nI,OS,kS,XS,$I,tC,gP,fP,yP,xP,SP,IP,aC,cP,cC,kC,SC,NC,wC,TC,LC,gC,vC,DC,zC,_P,jC,$C,YC,XC,qC,VC,WC,HC,GC,ZC,RC,EC,FC,BC,AC,OC,DP,zP,FP,BP,KC,JC,QC,tP,eP,nP,oP,iP,rP,bP,sP,aP,CP,mP,PP,MP,NP,AP,OP,kP,LP,jP,$P,YP,XP,VP,oI,_I,uI,pI,mI,gI,lI,hI,bI,fI,iI,vI,SI,xI,NI,wI,TI,RI,OI,EI,AI,UP,QP,oM,sM,aM,cM,lM,dM,hM,fM,uM,pM,mM]),_M=yM;function bM(t,e,n){if(!e||!n)return;let o=t.get(e);o||(o=new Set,t.set(e,o)),o.add(n);let i=t.get(n);i||(i=new Set,t.set(n,i)),i.add(e)}var xM=(t,e={})=\u003e{const n=t;let o=n._internal_store;if(!o){o={counts:{},editCount:0},n._internal_store=o;for(const t of n){const e=t.type,n=t[`${e}_id`];if(!n)continue;const i=Number.parseInt(n.split(\"_\").pop());Number.isNaN(i)||(o.counts[e]=Math.max(o.counts[e]??0,i))}}const i=new Proxy({},{get:(t,r)=\u003e{if(\"toArray\"===r)return()=\u003e(n.editCount=o.editCount,n);if(\"editCount\"===r)return o.editCount;if(\"subtree\"===r)return t=\u003exM(function(t,e){if(!e.subcircuit_id\u0026\u0026!e.source_group_id)return[...t];let n=e;if(e.subcircuit_id){const o=new Set([e.subcircuit_id]),i=new Map,r=new Map;for(const e of t)if(\"source_group\"===e.type){const t=e.source_group_id,n=e.subcircuit_id;n\u0026\u0026r.set(t,n);const o=e.parent_source_group_id;o\u0026\u0026(i.has(o)||i.set(o,[]),i.get(o).push(t))}let s;for(const[t,n]of r)if(n===e.subcircuit_id){s=t;break}if(s){const t=e=\u003e{const n=i.get(e)||[];for(const e of n){const n=r.get(e);n\u0026\u0026o.add(n),t(e)}};t(s),n={...e,subcircuit_ids:Array.from(o)}}}const o=new Map;for(const e of t){const t=e[`${e.type}_id`];\"string\"==typeof t\u0026\u0026o.set(t,e)}const i=new Map;for(const e of t){const t=Object.entries(e);for(const[n,r]of t)if(\"parent_source_group_id\"!==n)if(n.endsWith(\"_id\")\u0026\u0026\"string\"==typeof r)bM(i,e,o.get(r));else if(n.endsWith(\"_ids\")\u0026\u0026Array.isArray(r))for(const t of r)\"string\"==typeof t\u0026\u0026bM(i,e,o.get(t))}const r=[],s=new Set;for(const e of t){let t=!1;(n.subcircuit_id\u0026\u0026\"subcircuit_id\"in e\u0026\u0026e.subcircuit_id===n.subcircuit_id||n.subcircuit_ids\u0026\u0026\"subcircuit_id\"in e\u0026\u0026e.subcircuit_id\u0026\u0026n.subcircuit_ids.includes(e.subcircuit_id)||n.source_group_id\u0026\u0026\"source_group_id\"in e\u0026\u0026e.source_group_id===n.source_group_id||n.source_group_id\u0026\u0026\"member_source_group_ids\"in e\u0026\u0026Array.isArray(e.member_source_group_ids)\u0026\u0026e.member_source_group_ids.includes(n.source_group_id))\u0026\u0026(t=!0),t\u0026\u0026(r.push(e),s.add(e))}for(;r.length\u003e0;){const t=r.shift(),e=i.get(t);if(e)for(const t of e)s.has(t)||(s.add(t),r.push(t))}return t.filter(t=\u003es.has(t))}(n,t),e);if(\"insert\"===r)return t=\u003e{const i=t.type;if(!i)throw new Error(\"insert requires an element with a type\");o.counts[i]??=-1,o.counts[i]++;const r=o.counts[i],s={...t,type:i,[`${i}_id`]:`${i}_${r}`};if(e.validateInserts){(S_[i]??_M).parse(s)}return n.push(s),o.editCount++,s};if(\"insertAll\"===r)return t=\u003et.map(t=\u003ei.insert(t));const s=r;return{get:t=\u003en.find(e=\u003ee.type===s\u0026\u0026e[`${s}_id`]===t),getUsing:t=\u003e{const e=Object.keys(t);if(1!==e.length)throw new Error(\"getUsing requires exactly one key, e.g. { pcb_component_id }\");const o=e[0],i=o.replace(\"_id\",\"\"),r=n.find(e=\u003ee.type===i\u0026\u0026e[o]===t[o]);return r?n.find(t=\u003et.type===s\u0026\u0026t[`${s}_id`]===r[`${s}_id`]):null},getWhere:t=\u003e{const e=Object.keys(t);return n.find(n=\u003en.type===s\u0026\u0026e.every(e=\u003en[e]===t[e]))},list:t=\u003e{const e=t?Object.keys(t):[];return n.filter(n=\u003en.type===s\u0026\u0026e.every(e=\u003en[e]===t[e]))},insert:t=\u003e{o.counts[s]??=-1,o.counts[s]++;const i=o.counts[s],r={type:s,[`${s}_id`]:`${s}_${i}`,...t};if(e.validateInserts){(S_[s]??_M).parse(r)}return n.push(r),o.editCount++,r},delete:t=\u003e{const e=n.find(e=\u003ee[`${s}_id`]===t);e\u0026\u0026(n.splice(n.indexOf(e),1),o.editCount++)},update:(t,e)=\u003e{const i=n.find(e=\u003ee.type===s\u0026\u0026e[`${s}_id`]===t);return i?(Object.assign(i,e),o.editCount++,i):null},select:t=\u003e{if(\"source_component\"===s)return n.find(e=\u003e\"source_component\"===e.type\u0026\u0026e.name===t.replace(/\\./g,\"\"));if(\"pcb_port\"===s||\"source_port\"===s||\"schematic_port\"===s){const[e,o]=t.replace(/\\./g,\"\").split(/[\\s\\\u003e]+/),i=n.find(t=\u003e\"source_component\"===t.type\u0026\u0026t.name===e);if(!i)return null;const r=n.find(t=\u003e\"source_port\"===t.type\u0026\u0026t.source_component_id===i.source_component_id\u0026\u0026(t.name===o||(t.port_hints??[]).includes(o)));if(!r)return null;if(\"source_port\"===s)return r;if(\"pcb_port\"===s)return n.find(t=\u003e\"pcb_port\"===t.type\u0026\u0026t.source_port_id===r.source_port_id);if(\"schematic_port\"===s)return n.find(t=\u003e\"schematic_port\"===t.type\u0026\u0026t.source_port_id===r.source_port_id)}}}}});return i};xM.unparsed=xM;var vM=xM;function SM(t){const e=t.type;return`${e}:${t[`${e}_id`]}`}var IM=(t,e={})=\u003e{let n=t._internal_store_indexed;if(!n){n={counts:{},editCount:0,indexes:{}};for(const e of t){const t=e.type,o=e[`${t}_id`];if(!o)continue;const i=Number.parseInt(o.split(\"_\").pop()||\"\");Number.isNaN(i)||(n.counts[t]=Math.max(n.counts[t]??0,i))}const o=e.indexConfig||{},i=n.indexes;if(o.byId\u0026\u0026(i.byId=new Map),o.byType\u0026\u0026(i.byType=new Map),o.byRelation\u0026\u0026(i.byRelation=new Map),o.bySubcircuit\u0026\u0026(i.bySubcircuit=new Map),o.byCustomField\u0026\u0026o.byCustomField.length\u003e0){i.byCustomField=new Map;for(const t of o.byCustomField)i.byCustomField.set(t,new Map)}for(const e of t){if(o.byId){const t=SM(e);i.byId.set(t,e)}if(o.byType){const t=i.byType.get(e.type)||[];t.push(e),i.byType.set(e.type,t)}if(o.byRelation){const t=Object.entries(e);for(const[n,o]of t)if(n.endsWith(\"_id\")\u0026\u0026n!==`${e.type}_id`\u0026\u0026\"string\"==typeof o){const t=i.byRelation.get(n)||new Map,r=t.get(o)||[];r.push(e),t.set(o,r),i.byRelation.set(n,t)}}if(o.bySubcircuit\u0026\u0026\"subcircuit_id\"in e){const t=e.subcircuit_id;if(t\u0026\u0026\"string\"==typeof t){const n=i.bySubcircuit.get(t)||[];n.push(e),i.bySubcircuit.set(t,n)}}if(o.byCustomField\u0026\u0026i.byCustomField)for(const t of o.byCustomField)if(t in e){const n=e[t];if(void 0!==n\u0026\u0026(\"string\"==typeof n||\"number\"==typeof n)){const o=String(n),r=i.byCustomField.get(t),s=r.get(o)||[];s.push(e),r.set(o,s)}}}t._internal_store_indexed=n}return new Proxy({},{get:(o,i)=\u003e{if(\"toArray\"===i)return()=\u003e(t.editCount=n.editCount,t);if(\"editCount\"===i)return n.editCount;const r=i;return{get:o=\u003e{const i=e.indexConfig||{};if(i.byId\u0026\u0026n.indexes.byId)return n.indexes.byId.get(`${r}:${o}`)||null;if(i.byType\u0026\u0026n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=\u003et[`${r}_id`]===o)||null}return t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===o)||null},getUsing:o=\u003e{const i=e.indexConfig||{},s=Object.keys(o);if(1!==s.length)throw new Error(\"getUsing requires exactly one key, e.g. { pcb_component_id }\");const a=s[0],c=a.replace(\"_id\",\"\");if(i.byRelation\u0026\u0026n.indexes.byRelation){const e=n.indexes.byRelation.get(a);if(e){const s=(e.get(o[a])||[]).find(t=\u003et.type===c);if(!s)return null;const l=s[`${r}_id`];if(i.byId\u0026\u0026n.indexes.byId)return n.indexes.byId.get(`${r}:${l}`)||null;if(i.byType\u0026\u0026n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=\u003et[`${r}_id`]===l)||null}return t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===l)||null}}const l=t.find(t=\u003et.type===c\u0026\u0026t[a]===o[a]);return l\u0026\u0026t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===l[`${r}_id`])||null},getWhere:o=\u003e{const i=e.indexConfig||{},s=Object.keys(o);if(1===s.length\u0026\u0026i.byCustomField\u0026\u0026n.indexes.byCustomField){const t=s[0],e=n.indexes.byCustomField.get(t);if(e){const n=String(o[t]);return(e.get(n)||[]).find(t=\u003et.type===r)||null}}if(\"subcircuit_id\"in o\u0026\u0026i.bySubcircuit\u0026\u0026n.indexes.bySubcircuit){const t=o.subcircuit_id;return(n.indexes.bySubcircuit.get(t)||[]).find(t=\u003et.type===r\u0026\u0026s.every(e=\u003et[e]===o[e]))||null}if(i.byType\u0026\u0026n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=\u003es.every(e=\u003et[e]===o[e]))||null}return t.find(t=\u003et.type===r\u0026\u0026s.every(e=\u003et[e]===o[e]))||null},list:o=\u003e{const i=e.indexConfig||{},s=o?Object.keys(o):[];if(0===s.length\u0026\u0026i.byType\u0026\u0026n.indexes.byType)return n.indexes.byType.get(r)||[];if(1===s.length\u0026\u0026\"subcircuit_id\"===s[0]\u0026\u0026i.bySubcircuit\u0026\u0026n.indexes.bySubcircuit){const t=o.subcircuit_id;return(n.indexes.bySubcircuit.get(t)||[]).filter(t=\u003et.type===r)}let a;return a=i.byType\u0026\u0026n.indexes.byType?n.indexes.byType.get(r)||[]:t.filter(t=\u003et.type===r),s.length\u003e0?a.filter(t=\u003es.every(e=\u003et[e]===o[e])):a},insert:o=\u003e{n.counts[r]??=-1,n.counts[r]++;const i=n.counts[r],s={type:r,[`${r}_id`]:`${r}_${i}`,...o};if(e.validateInserts){(S_[r]??_M).parse(s)}t.push(s),n.editCount++;const a=e.indexConfig||{};if(a.byId\u0026\u0026n.indexes.byId){const t=SM(s);n.indexes.byId.set(t,s)}if(a.byType\u0026\u0026n.indexes.byType){const t=n.indexes.byType.get(r)||[];t.push(s),n.indexes.byType.set(r,t)}if(a.byRelation\u0026\u0026n.indexes.byRelation){const t=Object.entries(s);for(const[e,o]of t)if(e.endsWith(\"_id\")\u0026\u0026e!==`${s.type}_id`\u0026\u0026\"string\"==typeof o){const t=n.indexes.byRelation.get(e)||new Map,i=t.get(o)||[];i.push(s),t.set(o,i),n.indexes.byRelation.set(e,t)}}if(a.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in s){const t=s.subcircuit_id;if(t\u0026\u0026\"string\"==typeof t){const e=n.indexes.bySubcircuit.get(t)||[];e.push(s),n.indexes.bySubcircuit.set(t,e)}}if(a.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of a.byCustomField)if(t in s){const e=s[t];if(void 0!==e\u0026\u0026(\"string\"==typeof e||\"number\"==typeof e)){const o=String(e),i=n.indexes.byCustomField.get(t),r=i.get(o)||[];r.push(s),i.set(o,r)}}return s},delete:o=\u003e{const i=e.indexConfig||{};let s;if(i.byId\u0026\u0026n.indexes.byId)s=n.indexes.byId.get(`${r}:${o}`);else if(i.byType\u0026\u0026n.indexes.byType){const t=n.indexes.byType.get(r)||[];s=t.find(t=\u003et[`${r}_id`]===o)}else s=t.find(t=\u003et[`${r}_id`]===o);if(!s)return;const a=t.indexOf(s);if(a\u003e=0\u0026\u0026(t.splice(a,1),n.editCount++),i.byId\u0026\u0026n.indexes.byId){const t=SM(s);n.indexes.byId.delete(t)}if(i.byType\u0026\u0026n.indexes.byType){const t=(n.indexes.byType.get(r)||[]).filter(t=\u003et[`${r}_id`]!==o);n.indexes.byType.set(r,t)}if(i.byRelation\u0026\u0026n.indexes.byRelation)for(const[t,e]of n.indexes.byRelation.entries())for(const[t,n]of e.entries()){const o=n.filter(t=\u003et!==s);0===o.length?e.delete(t):e.set(t,o)}if(i.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in s){const t=s.subcircuit_id;if(t){const e=(n.indexes.bySubcircuit.get(t)||[]).filter(t=\u003et!==s);0===e.length?n.indexes.bySubcircuit.delete(t):n.indexes.bySubcircuit.set(t,e)}}if(i.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of n.indexes.byCustomField.values())for(const[e,n]of t.entries()){const o=n.filter(t=\u003et!==s);0===o.length?t.delete(e):t.set(e,o)}},update:(o,i)=\u003e{const s=e.indexConfig||{};let a;if(s.byId\u0026\u0026n.indexes.byId)a=n.indexes.byId.get(`${r}:${o}`);else if(s.byType\u0026\u0026n.indexes.byType){const t=n.indexes.byType.get(r)||[];a=t.find(t=\u003et[`${r}_id`]===o)}else a=t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===o);if(!a)return null;if(s.byRelation\u0026\u0026n.indexes.byRelation){const t=Object.entries(a);for(const[e,o]of t)if(e.endsWith(\"_id\")\u0026\u0026e!==`${a.type}_id`\u0026\u0026\"string\"==typeof o\u0026\u0026e in i\u0026\u0026i[e]!==o){const t=n.indexes.byRelation.get(e);if(t){const e=(t.get(o)||[]).filter(t=\u003et!==a);0===e.length?t.delete(o):t.set(o,e)}}}if(s.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in a\u0026\u0026\"subcircuit_id\"in i){const t=a.subcircuit_id;if(t!==i.subcircuit_id){const e=(n.indexes.bySubcircuit.get(t)||[]).filter(t=\u003et!==a);0===e.length?n.indexes.bySubcircuit.delete(t):n.indexes.bySubcircuit.set(t,e)}}if(s.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of s.byCustomField)if(t in a\u0026\u0026t in i\u0026\u0026a[t]!==i[t]){const e=n.indexes.byCustomField.get(t);if(e){const n=String(a[t]),o=(e.get(n)||[]).filter(t=\u003et!==a);0===o.length?e.delete(n):e.set(n,o)}}if(Object.assign(a,i),n.editCount++,s.byRelation\u0026\u0026n.indexes.byRelation){const t=Object.entries(a);for(const[e,o]of t)if(e.endsWith(\"_id\")\u0026\u0026e!==`${a.type}_id`\u0026\u0026\"string\"==typeof o\u0026\u0026e in i){const t=n.indexes.byRelation.get(e)||new Map,i=t.get(o)||[];i.includes(a)||(i.push(a),t.set(o,i),n.indexes.byRelation.set(e,t))}}if(s.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in a\u0026\u0026\"subcircuit_id\"in i){const t=a.subcircuit_id;if(t\u0026\u0026\"string\"==typeof t){const e=n.indexes.bySubcircuit.get(t)||[];e.includes(a)||(e.push(a),n.indexes.bySubcircuit.set(t,e))}}if(s.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of s.byCustomField)if(t in a\u0026\u0026t in i){const e=a[t];if(void 0!==e\u0026\u0026(\"string\"==typeof e||\"number\"==typeof e)){const o=String(e),i=n.indexes.byCustomField.get(t),r=i.get(o)||[];r.includes(a)||(r.push(a),i.set(o,r))}}return a},select:e=\u003e{if(\"source_component\"===r)return t.find(t=\u003e\"source_component\"===t.type\u0026\u0026t.name===e.replace(/\\./g,\"\"))||null;if(\"pcb_port\"===r||\"source_port\"===r||\"schematic_port\"===r){const[n,o]=e.replace(/\\./g,\"\").split(/[\\s\\\u003e]+/),i=t.find(t=\u003e\"source_component\"===t.type\u0026\u0026t.name===n);if(!i)return null;const s=t.find(t=\u003e\"source_port\"===t.type\u0026\u0026t.source_component_id===i.source_component_id\u0026\u0026(t.name===o||(t.port_hints??[]).includes(o)));if(!s)return null;if(\"source_port\"===r)return s;if(\"pcb_port\"===r)return t.find(t=\u003e\"pcb_port\"===t.type\u0026\u0026t.source_port_id===s.source_port_id)||null;if(\"schematic_port\"===r)return t.find(t=\u003e\"schematic_port\"===t.type\u0026\u0026t.source_port_id===s.source_port_id)||null}return null}}}})};IM.unparsed=IM;var CM=t=\u003et[`${t.type}_id`];function PM(t,e){const n=xM(t).pcb_trace.get(e);if(!n)return`trace[${e}]`;const o=n.route.flatMap(t=\u003e[t.start_pcb_port_id,t.end_pcb_port_id]).filter(Boolean);if(0===o.length)return`trace[${e}]`;return`trace[${o.map(e=\u003e{const n=function(e){const n=xM(t).pcb_port.get(e);if(!n)return null;const o=n.pcb_component_id?xM(t).pcb_component.get(n.pcb_component_id):void 0;if(!o)return null;const i=xM(t).source_component.get(o.source_component_id);if(!i)return null;const r=xM(t).source_port.get(n.source_port_id),s=r?.port_hints?r.port_hints[1]:\"\";return{componentName:i.name,portHint:s}}(e);return n?`.${n.componentName} \u003e port.${n.portHint}`:`port[${e}]`}).join(\", \")}]`}var MM=(t,e)=\u003e{const n=xM(t).pcb_port.get(e);if(!n)return`pcb_port[#${e}]`;const o=n.pcb_component_id?xM(t).pcb_component.get(n.pcb_component_id):void 0;if(!o)return`pcb_port[#${e}]`;const i=xM(t).source_component.get(o.source_component_id);if(!i)return`pcb_port[#${e}]`;const r=xM(t).source_port.get(n.source_port_id);if(!r)return`pcb_port[#${e}]`;let s;return s=r?.port_hints\u0026\u0026r.port_hints.length\u003e0||r.port_hints\u0026\u0026r.port_hints.length\u003e0?r.port_hints[0]:e,`pcb_port[.${i.name} \u003e .${s}]`};var NM=(t,e)=\u003e{if(\"string\"==typeof e){const n=((t,e)=\u003et.find(t=\u003eCM(t)===e)??null)(t,e);return NM(t,n)}switch(e.type){case\"pcb_port\":return MM(t,e.pcb_port_id);case\"pcb_smtpad\":return function(t,e){const n=xM(t).pcb_smtpad.get(e);return n\u0026\u0026n.pcb_port_id?MM(t,n.pcb_port_id):`smtpad[${e}]`}(t,e.pcb_smtpad_id);case\"pcb_trace\":return PM(t,e.pcb_trace_id);case\"source_component\":return`source_component[${e.name}]`;default:return`${e.type}[#${CM(e)}]`}},wM=(t,e)=\u003e({minX:Math.min(t.minX,e.minX),minY:Math.min(t.minY,e.minY),maxX:Math.max(t.maxX,e.maxX),maxY:Math.max(t.maxY,e.maxY)}),TM=(t,e,n)=\u003e{const o=n/2;return{minX:t-o,minY:e-o,maxX:t+o,maxY:e+o}},RM=(t,e,n,o,i)=\u003e{const r=n/2,s=o/2,a=i*Math.PI/180,c=Math.cos(a),l=Math.sin(a),d=[{x:-r,y:-s},{x:r,y:-s},{x:r,y:s},{x:-r,y:s}].map(n=\u003e({x:t+n.x*c-n.y*l,y:e+n.x*l+n.y*c}));return{minX:Math.min(...d.map(t=\u003et.x)),minY:Math.min(...d.map(t=\u003et.y)),maxX:Math.max(...d.map(t=\u003et.x)),maxY:Math.max(...d.map(t=\u003et.y))}},EM=t=\u003e{let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t){if(!r.type.startsWith(\"pcb_\"))continue;if(\"pcb_smtpad\"===r.type\u0026\u0026\"polygon\"===r.shape\u0026\u0026Array.isArray(r.points)){for(const t of r.points)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);continue}if(\"pcb_hole\"===r.type\u0026\u0026\"circle\"===r.hole_shape){const t=TM(r.x,r.y,r.hole_diameter);e=Math.min(e,t.minX),n=Math.min(n,t.minY),o=Math.max(o,t.maxX),i=Math.max(i,t.maxY);continue}if(\"pcb_plated_hole\"===r.type){let t;if(\"outer_diameter\"in r\u0026\u0026\"number\"==typeof r.outer_diameter?t=TM(r.x,r.y,r.outer_diameter):\"hole_diameter\"in r\u0026\u0026\"number\"==typeof r.hole_diameter\u0026\u0026(t=TM(r.x,r.y,r.hole_diameter)),\"rect_pad_width\"in r\u0026\u0026\"number\"==typeof r.rect_pad_width\u0026\u0026\"rect_pad_height\"in r\u0026\u0026\"number\"==typeof r.rect_pad_height){const e=RM(r.x,r.y,r.rect_pad_width,r.rect_pad_height,\"rect_ccw_rotation\"in r?r.rect_ccw_rotation??0:0);t=t?wM(t,e):e}if(\"hole_diameter\"in r\u0026\u0026\"number\"==typeof r.hole_diameter){const e=TM(r.x+(\"hole_offset_x\"in r?r.hole_offset_x??0:0),r.y+(\"hole_offset_y\"in r?r.hole_offset_y??0:0),r.hole_diameter);t=t?wM(t,e):e}if(t){e=Math.min(e,t.minX),n=Math.min(n,t.minY),o=Math.max(o,t.maxX),i=Math.max(i,t.maxY);continue}}let t,s,a,c;if(\"x\"in r\u0026\u0026\"y\"in r\u0026\u0026(t=Number(r.x),s=Number(r.y)),\"outer_diameter\"in r\u0026\u0026(a=Number(r.outer_diameter),c=Number(r.outer_diameter)),\"width\"in r\u0026\u0026(a=Number(r.width)),\"height\"in r\u0026\u0026(c=Number(r.height)),\"center\"in r\u0026\u0026(t=r.center.x,s=r.center.y),void 0!==t\u0026\u0026void 0!==s)e=Math.min(e,t),n=Math.min(n,s),o=Math.max(o,t),i=Math.max(i,s),void 0!==a\u0026\u0026void 0!==c\u0026\u0026(e=Math.min(e,t-a/2),n=Math.min(n,s-c/2),o=Math.max(o,t+a/2),i=Math.max(i,s+c/2)),\"radius\"in r\u0026\u0026(e=Math.min(e,t-r.radius),n=Math.min(n,s-r.radius),o=Math.max(o,t+r.radius),i=Math.max(i,s+r.radius));else if(\"pcb_trace\"===r.type)for(const t of r.route)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);else if(\"pcb_courtyard_outline\"===r.type)for(const t of r.outline)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);else if(\"pcb_courtyard_polygon\"===r.type)for(const t of r.points)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y)}return{minX:e,minY:n,maxX:o,maxY:i}},AM=t=\u003et[`${t.type}_id`],OM={Hz:{baseUnit:\"Hz\",variants:{MHz:1e6,kHz:1e3,Hz:1}},g:{baseUnit:\"g\",variants:{kg:1e3,g:1}},\"Ω\":{baseUnit:\"Ω\",variants:{\"mΩ\":.001,\"Ω\":1,\"kΩ\":1e3,\"KΩ\":1e3,kohm:1e3,\"MΩ\":1e6,\"GΩ\":1e9,\"TΩ\":1e12}},V:{baseUnit:\"V\",variants:{mV:.001,V:1,kV:1e3,KV:1e3,MV:1e6,GV:1e9,TV:1e12}},A:{baseUnit:\"A\",variants:{\"µA\":1e-6,mA:.001,ma:.001,A:1,kA:1e3,MA:1e6}},F:{baseUnit:\"F\",variants:{pF:1e-12,nF:1e-9,\"µF\":1e-6,uF:1e-6,mF:.001,F:1}},ml:{baseUnit:\"ml\",variants:{ml:1,mL:1,l:1e3,L:1e3}},deg:{baseUnit:\"deg\",variants:{rad:180/Math.PI}},ms:{baseUnit:\"ms\",variants:{fs:1e-12,ps:1e-9,ns:1e-6,us:.001,\"µs\":.001,ms:1,s:1e3}},mm:{baseUnit:\"mm\",variants:{nm:1e-6,\"µm\":.001,um:.001,mm:1,cm:10,dm:100,m:1e3,km:1e6,in:25.4,ft:304.8,IN:25.4,FT:304.8,yd:914.4,mi:1609344,mil:.0254}}},kM=new Set;for(const[t,e]of Object.entries(OM)){kM.add(t);for(const t of Object.keys(e.variants))kM.add(t)}var LM={tera:1e12,T:1e12,giga:1e9,G:1e9,mega:1e6,M:1e6,kilo:1e3,k:1e3,deci:.1,d:.1,centi:.01,c:.01,milli:.001,m:.001,micro:1e-6,u:1e-6,\"µ\":1e-6,nano:1e-9,n:1e-9,pico:1e-12,p:1e-12};function DM(t){if(null==t)return{parsedUnit:null,unitOfValue:null,value:null};if(\"string\"==typeof t\u0026\u0026t.match(/^-?[\\d\\.]+$/))return{value:Number.parseFloat(t),parsedUnit:null,unitOfValue:null};if(\"number\"==typeof t)return{value:t,parsedUnit:null,unitOfValue:null};if(\"object\"==typeof t\u0026\u0026\"x\"in t\u0026\u0026\"y\"in t){const{parsedUnit:e,unitOfValue:n}=DM(t.x),o=DM(t.x),i=DM(t.y);return null===o.value||null===i.value?{parsedUnit:null,unitOfValue:null,value:null}:{parsedUnit:e,unitOfValue:n,value:{x:o.value,y:i.value}}}const e=t.toString().split(\"\").reverse().join(\"\"),n=e.match(/[^\\d\\s]+/)?.[0];if(!n)throw new Error(`Could not determine unit: \"${t}\"`);const o=n.split(\"\").reverse().join(\"\"),i=t.slice(0,-o.length);if(o in LM\u0026\u0026!kM.has(o)){const t=LM[o];return{parsedUnit:null,unitOfValue:null,value:Number.parseFloat(i)*t}}const{baseUnit:r,conversionFactor:s}=function(t){for(const[e,n]of Object.entries(OM))if(t in n.variants)return{baseUnit:n.baseUnit,conversionFactor:n.variants[t]};return{baseUnit:t,conversionFactor:1}}(o);return{parsedUnit:o,unitOfValue:r,value:s*Number.parseFloat(i)}}var zM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),FM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value).transform(t=\u003eNumber.parseFloat(t.toPrecision(12))),BM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),jM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),$M=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),YM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),XM=$M,VM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),WM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),HM=WM,GM=k_.string().datetime(),UM=k_.string().or(k_.number()).transform(t=\u003e\"number\"==typeof t?t:t.endsWith(\"deg\")?Number.parseFloat(t.split(\"deg\")[0]):t.endsWith(\"rad\")?180*Number.parseFloat(t.split(\"rad\")[0])/Math.PI:Number.parseFloat(t)),ZM=k_.number().or(k_.string().endsWith(\"mAh\")).transform(t=\u003e{if(\"string\"==typeof t){const e=t.replace(\"mAh\",\"\"),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error(\"Invalid capacity\");return n}return t}).describe(\"Battery capacity in mAh\"),qM=k_.object({x:XM,y:XM}),JM=k_.object({x:XM,y:XM,z:XM}),KM=k_.object({width:k_.number(),height:k_.number()}),QM=t=\u003ek_.string().optional().default(()=\u003e`${t}_${(t=\u003e{const e=\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";return Array.from({length:t},()=\u003ee[Math.floor(62*Math.random())]).join(\"\")})(10)}`),tN=k_.enum([\"top_left\",\"top_center\",\"top_right\",\"center_left\",\"center\",\"center_right\",\"bottom_left\",\"bottom_center\",\"bottom_right\"]),eN=(k_.enum([\"top_silkscreen\",\"bottom_silkscreen\",\"top_copper\",\"bottom_copper\",\"top_soldermask\",\"bottom_soldermask\",\"top_fabrication_note\",\"bottom_fabrication_note\",\"top_user_note\",\"bottom_user_note\",\"top_courtyard\",\"bottom_courtyard\",\"inner1_copper\",\"inner2_copper\",\"inner3_copper\",\"inner4_copper\",\"inner5_copper\",\"inner6_copper\",\"edge_cuts\",\"drill\"]),k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()})),nN=qM.extend({rotation:UM.optional()}),oN=k_.object({size:qM.optional(),thickness:XM.optional()}),iN=k_.object({font:oN.optional()}),rN=k_.object({value:k_.string(),at:nN.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:iN.optional()}),sN=k_.object({Reference:rN.optional(),Value:rN.optional(),Datasheet:rN.optional(),Description:rN.optional()}),aN=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),cN=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:nN.optional(),size:qM.optional(),drill:XM.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),lN=k_.object({path:k_.string(),offset:JM.optional(),scale:JM.optional(),rotate:JM.optional()}),dN=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:sN.optional(),attributes:aN.optional(),pads:k_.array(cN).optional(),embeddedFonts:k_.boolean().optional(),model:lN.optional()}),hN=k_.object({hide:k_.boolean().optional()}),uN=k_.object({offset:XM.optional(),hide:k_.boolean().optional()}),pN=k_.object({font:oN.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),mN=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:nN.optional(),effects:pN.optional()}),gN=k_.object({Reference:mN.optional(),Value:mN.optional(),Footprint:mN.optional(),Datasheet:mN.optional(),Description:mN.optional(),ki_keywords:mN.optional(),ki_fp_filters:mN.optional()}),fN=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:hN.optional(),pinNames:uN.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:gN.optional(),embeddedFonts:k_.boolean().optional()}),yN=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),_N=k_.enum([\"jlcpcb\",\"macrofab\",\"pcbway\",\"digikey\",\"mouser\",\"lcsc\"]),bN=k_.object({type:k_.literal(\"source_component\"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(_N,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),xN=bN.extend({ftype:k_.literal(\"simple_capacitor\"),capacitance:FM,max_voltage_rating:jM.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:XM.optional()}),vN=bN.extend({ftype:k_.literal(\"simple_resistor\"),resistance:zM,display_resistance:k_.string().optional()}),SN=bN.extend({ftype:k_.literal(\"simple_diode\")}),IN=bN.extend({ftype:k_.literal(\"simple_fiducial\")}),CN=SN.extend({ftype:k_.literal(\"simple_led\"),color:k_.string().optional(),wavelength:k_.string().optional()}),PN=bN.extend({ftype:k_.literal(\"simple_ground\")}),MN=bN.extend({ftype:k_.literal(\"simple_chip\")}),NN=bN.extend({ftype:k_.literal(\"simple_power_source\"),voltage:jM}),wN=bN.extend({ftype:k_.literal(\"simple_current_source\"),current:VM,frequency:YM.optional(),peak_to_peak_current:VM.optional(),wave_shape:k_.enum([\"sine\",\"square\",\"triangle\",\"sawtooth\",\"dc\"]).optional().default(\"dc\"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),TN=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),RN=bN.extend({ftype:k_.literal(\"simple_fuse\"),current_rating_amps:k_.number().describe(\"Nominal current in amps the fuse is rated for\"),voltage_rating_volts:k_.number().describe(\"Voltage rating in volts, e.g. ±5V would be 5\")}),EN=bN.extend({ftype:k_.literal(\"simple_battery\"),capacity:ZM}),AN=bN.extend({ftype:k_.literal(\"simple_inductor\"),inductance:BM,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),ON=bN.extend({ftype:k_.literal(\"simple_push_button\")}),kN=bN.extend({ftype:k_.literal(\"simple_potentiometer\"),max_resistance:zM,display_max_resistance:k_.string().optional()}),LN=bN.extend({ftype:k_.literal(\"simple_crystal\"),frequency:k_.number().describe(\"Frequency in Hz\"),load_capacitance:k_.number().optional().describe(\"Load capacitance in pF\"),pin_variant:k_.enum([\"two_pin\",\"four_pin\"]).optional()}),DN=bN.extend({ftype:k_.literal(\"simple_pin_header\"),pin_count:k_.number(),gender:k_.enum([\"male\",\"female\"]).optional().default(\"male\")}),zN=bN.extend({ftype:k_.literal(\"simple_connector\"),standard:k_.enum([\"usb_c\",\"m2\"]).optional()}),FN=bN.extend({ftype:k_.literal(\"simple_pinout\")}),BN=bN.extend({ftype:k_.literal(\"simple_resonator\"),load_capacitance:FM,equivalent_series_resistance:zM.optional(),frequency:YM}),jN=bN.extend({ftype:k_.literal(\"simple_transistor\"),transistor_type:k_.enum([\"npn\",\"pnp\"])}),$N=bN.extend({ftype:k_.literal(\"simple_test_point\"),footprint_variant:k_.enum([\"pad\",\"through_hole\"]).optional(),pad_shape:k_.enum([\"rect\",\"circle\"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),YN=bN.extend({ftype:k_.literal(\"simple_mosfet\"),channel_type:k_.enum([\"n\",\"p\"]),mosfet_mode:k_.enum([\"enhancement\",\"depletion\"])}),XN=bN.extend({ftype:k_.literal(\"simple_op_amp\")}),VN=bN.extend({ftype:k_.literal(\"simple_switch\")}),WN=k_.object({type:k_.literal(\"source_project_metadata\"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),created_at:GM.optional()}),HN=yN.extend({type:k_.literal(\"source_missing_property_error\"),source_missing_property_error_id:QM(\"source_missing_property_error\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_missing_property_error\").default(\"source_missing_property_error\")}).describe(\"The source code is missing a property\"),GN=yN.extend({type:k_.literal(\"source_failed_to_create_component_error\"),source_failed_to_create_component_error_id:QM(\"source_failed_to_create_component_error\"),error_type:k_.literal(\"source_failed_to_create_component_error\").default(\"source_failed_to_create_component_error\"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe(\"Error emitted when a component fails to be constructed\"),UN=yN.extend({type:k_.literal(\"source_invalid_component_property_error\"),source_invalid_component_property_error_id:QM(\"source_invalid_component_property_error\"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_invalid_component_property_error\").default(\"source_invalid_component_property_error\")}).describe(\"The source component property is invalid\"),ZN=yN.extend({type:k_.literal(\"source_trace_not_connected_error\"),source_trace_not_connected_error_id:QM(\"source_trace_not_connected_error\"),error_type:k_.literal(\"source_trace_not_connected_error\").default(\"source_trace_not_connected_error\"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe(\"Occurs when a source trace selector does not match any ports\"),qN=k_.object({type:k_.literal(\"source_property_ignored_warning\"),source_property_ignored_warning_id:QM(\"source_property_ignored_warning\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_property_ignored_warning\").default(\"source_property_ignored_warning\"),message:k_.string()}).describe(\"The source property was ignored\"),JN=k_.object({type:k_.literal(\"source_pin_missing_trace_warning\"),source_pin_missing_trace_warning_id:QM(\"source_pin_missing_trace_warning\"),warning_type:k_.literal(\"source_pin_missing_trace_warning\").default(\"source_pin_missing_trace_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component pin is missing a trace connection\"),KN=k_.object({type:k_.literal(\"source_missing_manufacturer_part_number_warning\"),source_missing_manufacturer_part_number_warning_id:QM(\"source_missing_manufacturer_part_number_warning\"),warning_type:k_.literal(\"source_missing_manufacturer_part_number_warning\").default(\"source_missing_manufacturer_part_number_warning\"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a standard connector is missing manufacturer part number\"),QN=bN.extend({ftype:k_.literal(\"simple_voltage_probe\")}),tw=bN.extend({ftype:k_.literal(\"interconnect\")}),ew=yN.extend({type:k_.literal(\"source_i2c_misconfigured_error\"),source_i2c_misconfigured_error_id:QM(\"source_i2c_misconfigured_error\"),error_type:k_.literal(\"source_i2c_misconfigured_error\").default(\"source_i2c_misconfigured_error\"),source_port_ids:k_.array(k_.string())}).describe(\"Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net\"),nw=bN.extend({ftype:k_.literal(\"simple_voltage_source\"),voltage:jM,frequency:YM.optional(),peak_to_peak_voltage:jM.optional(),wave_shape:k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]).optional(),phase:UM.optional(),duty_cycle:k_.number().optional().describe(\"Duty cycle as a fraction (0 to 1)\")}),ow=k_.union([vN,xN,SN,IN,CN,PN,MN,NN,wN,EN,AN,ON,kN,LN,DN,zN,FN,BN,VN,jN,$N,YN,XN,RN,QN,tw,nw,WN,HN,UN,GN,ZN,qN,JN,KN,ew]),iw=k_.object({type:k_.literal(\"source_port\"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(TN),rw=k_.object({type:k_.literal(\"source_component_internal_connection\"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),sw=k_.object({type:k_.literal(\"source_trace\"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),aw=k_.object({type:k_.literal(\"source_group\"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),cw=k_.object({type:k_.literal(\"source_net\"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),lw=k_.object({type:k_.literal(\"source_board\"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe(\"Defines a board in the source domain\"),dw=yN.extend({type:k_.literal(\"source_ambiguous_port_reference\"),source_ambiguous_port_reference_id:QM(\"source_ambiguous_port_reference\"),error_type:k_.literal(\"source_ambiguous_port_reference\").default(\"source_ambiguous_port_reference\"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous\"),hw=k_.object({type:k_.literal(\"source_pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane in the source domain\"),uw=[\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\"],pw=k_.enum(uw),mw=pw.or(k_.object({name:pw})).transform(t=\u003e\"string\"==typeof t?t:t.name),gw=k_.enum([\"top\",\"bottom\"]),fw=k_.object({type:k_.literal(\"source_manually_placed_via\"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe(\"Defines a via that is manually placed in the source domain\"),yw=k_.object({type:k_.literal(\"source_no_power_pin_defined_warning\"),source_no_power_pin_defined_warning_id:QM(\"source_no_power_pin_defined_warning\"),warning_type:k_.literal(\"source_no_power_pin_defined_warning\").default(\"source_no_power_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports with requires_power=true\"),_w=k_.object({type:k_.literal(\"source_no_ground_pin_defined_warning\"),source_no_ground_pin_defined_warning_id:QM(\"source_no_ground_pin_defined_warning\"),warning_type:k_.literal(\"source_no_ground_pin_defined_warning\").default(\"source_no_ground_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports marked as ground pins\"),bw=k_.object({type:k_.literal(\"source_component_pins_underspecified_warning\"),source_component_pins_underspecified_warning_id:QM(\"source_component_pins_underspecified_warning\"),warning_type:k_.literal(\"source_component_pins_underspecified_warning\").default(\"source_component_pins_underspecified_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when all ports on a source component are underspecified\"),xw=yN.extend({type:k_.literal(\"source_pin_must_be_connected_error\"),source_pin_must_be_connected_error_id:QM(\"source_pin_must_be_connected_error\"),error_type:k_.literal(\"source_pin_must_be_connected_error\").default(\"source_pin_must_be_connected_error\"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pin with mustBeConnected attribute is not connected to any trace\"),vw=yN.extend({type:k_.literal(\"unknown_error_finding_part\"),unknown_error_finding_part_id:QM(\"unknown_error_finding_part\"),error_type:k_.literal(\"unknown_error_finding_part\").default(\"unknown_error_finding_part\"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when an unexpected error occurs while finding a part\"),Sw=k_.object({type:k_.literal(\"schematic_box\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:XM,height:XM,is_dashed:k_.boolean().default(!1),x:XM,y:XM,subcircuit_id:k_.string().optional()}).describe(\"Draws a box on the schematic\"),Iw=k_.object({type:k_.literal(\"schematic_path\"),schematic_path_id:QM(\"schematic_path\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),stroke_width:XM.nullable().optional(),stroke_color:k_.string().optional(),points:k_.array(qM),subcircuit_id:k_.string().optional()}),Cw=k_.record(k_.object({left_margin:$M.optional(),right_margin:$M.optional(),top_margin:$M.optional(),bottom_margin:$M.optional()})),Pw=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),Mw=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional()}),Nw=k_.union([Pw,Mw]),ww=k_.object({type:k_.literal(\"schematic_component\"),size:KM,center:qM,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_symbol_id:k_.string().optional(),pin_spacing:$M.optional(),pin_styles:Cw.optional(),box_width:$M.optional(),symbol_name:k_.string().optional(),port_arrangement:Nw.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),Tw=k_.object({kicad_symbol:fN.optional()}).catchall(k_.unknown()),Rw=k_.object({type:k_.literal(\"schematic_symbol\"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:Tw.optional()}).describe(\"Defines a named schematic symbol that can be referenced by components.\"),Ew=k_.object({type:k_.literal(\"schematic_line\"),schematic_line_id:QM(\"schematic_line\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:XM,y1:XM,x2:XM,y2:XM,stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled line on the schematic\"),Aw=k_.object({type:k_.literal(\"schematic_rect\"),schematic_rect_id:QM(\"schematic_rect\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,width:XM,height:XM,rotation:UM.default(0),stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled rectangle on the schematic\"),Ow=k_.object({type:k_.literal(\"schematic_circle\"),schematic_circle_id:QM(\"schematic_circle\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,radius:XM,stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled circle on the schematic\"),kw=k_.object({type:k_.literal(\"schematic_arc\"),schematic_arc_id:QM(\"schematic_arc\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,radius:XM,start_angle_degrees:UM,end_angle_degrees:UM,direction:k_.enum([\"clockwise\",\"counterclockwise\"]).default(\"counterclockwise\"),stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled arc on the schematic\"),Lw=k_.object({type:k_.literal(\"schematic_trace\"),schematic_trace_id:k_.string(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),Dw=k_.enum([\"center\",\"left\",\"right\",\"top\",\"bottom\"]),zw=k_.object({type:k_.literal(\"schematic_text\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:XM,y:XM}),rotation:k_.number().default(0),anchor:k_.union([Dw.describe(\"legacy\"),tN]).default(\"center\"),color:k_.string().default(\"#000000\"),subcircuit_id:k_.string().optional()}),Fw=k_.object({type:k_.literal(\"schematic_port\"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_component_id:k_.string().optional(),center:qM,facing_direction:k_.enum([\"up\",\"down\",\"left\",\"right\"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe(\"Defines a port on a schematic component\"),Bw=k_.object({type:k_.literal(\"schematic_net_label\"),schematic_net_label_id:QM(\"schematic_net_label\"),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:qM,anchor_position:qM.optional(),anchor_side:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),jw=yN.extend({type:k_.literal(\"schematic_error\"),schematic_error_id:k_.string(),error_type:k_.literal(\"schematic_port_not_found\").default(\"schematic_port_not_found\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic error on the schematic\"),$w=yN.extend({type:k_.literal(\"schematic_layout_error\"),schematic_layout_error_id:QM(\"schematic_layout_error\"),error_type:k_.literal(\"schematic_layout_error\").default(\"schematic_layout_error\"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when schematic layout fails for a group\"),Yw=k_.object({type:k_.literal(\"schematic_debug_object\"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),Xw=Yw.extend({shape:k_.literal(\"rect\"),center:qM,size:KM}),Vw=Yw.extend({shape:k_.literal(\"line\"),start:qM,end:qM}),Ww=Yw.extend({shape:k_.literal(\"point\"),center:qM}),Hw=k_.discriminatedUnion(\"shape\",[Xw,Vw,Ww]),Gw=k_.object({type:k_.literal(\"schematic_voltage_probe\"),schematic_voltage_probe_id:k_.string(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:qM,schematic_trace_id:k_.string(),voltage:jM.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:tN.optional()}).describe(\"Defines a voltage probe measurement point on a schematic trace\"),Uw=k_.object({type:k_.literal(\"schematic_manual_edit_conflict_warning\"),schematic_manual_edit_conflict_warning_id:QM(\"schematic_manual_edit_conflict_warning\"),warning_type:k_.literal(\"schematic_manual_edit_conflict_warning\").default(\"schematic_manual_edit_conflict_warning\"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit schX/schY coordinates\"),Zw=k_.object({type:k_.literal(\"schematic_group\"),schematic_group_id:QM(\"schematic_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:$M,height:$M,center:qM,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe(\"Defines a group of components on the schematic\"),qw=k_.object({type:k_.literal(\"schematic_table\"),schematic_table_id:QM(\"schematic_table\"),anchor_position:qM,column_widths:k_.array(XM),row_heights:k_.array(XM),cell_padding:XM.optional(),border_width:XM.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:tN.optional()}).describe(\"Defines a table on the schematic\"),Jw=k_.object({type:k_.literal(\"schematic_table_cell\"),schematic_table_cell_id:QM(\"schematic_table_cell\"),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:qM,width:XM,height:XM,horizontal_align:k_.enum([\"left\",\"center\",\"right\"]).optional(),vertical_align:k_.enum([\"top\",\"middle\",\"bottom\"]).optional(),font_size:XM.optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a cell within a schematic_table\"),Kw=k_.object({type:k_.literal(\"schematic_sheet\"),schematic_sheet_id:QM(\"schematic_sheet\"),name:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic sheet or page that components can be placed on\"),Qw=k_.object({x:XM,y:XM,bulge:k_.number().optional()}),tT=k_.object({vertices:k_.array(Qw)}),eT=k_.object({outer_ring:tT,inner_rings:k_.array(tT).default([])}),nT=k_.object({x:XM,y:XM,via:k_.boolean().optional(),via_to_layer:mw.optional()}),oT=(k_.array(nT),k_.object({x:XM,y:XM,via:k_.boolean().optional(),to_layer:mw.optional(),trace_width:XM.optional()})),iT=k_.object({min_trace_width:$M.optional(),min_board_edge_clearance:$M.optional(),min_via_hole_edge_to_via_hole_edge_clearance:$M.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:$M.optional(),min_trace_to_pad_edge_clearance:$M.optional(),min_pad_edge_to_pad_edge_clearance:$M.optional(),min_same_net_trace_edge_to_trace_edge_clearance:$M.optional(),min_different_net_trace_edge_to_trace_edge_clearance:$M.optional(),min_via_hole_diameter:$M.optional(),min_via_pad_diameter:$M.optional()}),rT=k_.object({type:k_.literal(\"pcb_component\"),pcb_component_id:QM(\"pcb_component\"),source_component_id:k_.string(),center:qM,layer:mw,rotation:UM,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this part, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this part, usually corresponding with how the user specified it\"),width:$M,height:$M,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"relative_to_another_component\",\"none\"]).optional(),anchor_position:qM.optional(),anchor_alignment:tN.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:qM.optional(),insertion_direction:k_.enum([\"from_above\",\"from_left\",\"from_right\",\"from_front\",\"from_back\"]).optional(),metadata:k_.object({kicad_footprint:dN.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe(\"Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath\")}).describe(\"Defines a component on the PCB\"),sT=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),hole_diameter:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),aT=(sT.describe(\"Defines a circular hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),cT=(aT.describe(\"Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"square\"]),hole_diameter:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),lT=(cT.describe(\"Defines a circular or square hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"oval\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),dT=(lT.describe(\"Defines an oval hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),hT=(dT.describe(\"Defines a pill-shaped hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,ccw_rotation:UM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),uT=(hT.describe(\"Defines a rotated pill-shaped hole on the PCB\"),cT.or(lT).or(dT).or(hT).or(sT).or(aT)),pT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),mT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.enum([\"oval\",\"pill\"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,ccw_rotation:UM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),gT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circular_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),pad_shape:k_.literal(\"rect\"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:UM.optional()}),fT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),yT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"rotated_pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:UM,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:UM,hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),_T=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"hole_with_polygon_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"oval\",\"pill\",\"rotated_pill\"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:XM,y:XM})).min(3),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),ccw_rotation:UM.optional()}),bT=k_.union([pT,mT,gT,fT,yT,_T]),xT=k_.object({type:k_.literal(\"pcb_port\"),pcb_port_id:QM(\"pcb_port\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:XM,y:XM,layers:k_.array(mw),is_board_pinout:k_.boolean().optional()}).describe(\"Defines a port on the PCB\"),vT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"circle\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,radius:k_.number(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),ST=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rect\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),IT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_rect\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:UM,layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),CT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"pill\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),PT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_pill\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:UM,layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),MT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"polygon\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(qM),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),NT=k_.discriminatedUnion(\"shape\",[vT,ST,IT,PT,CT,MT]).describe(\"Defines an SMT pad on the PCB\"),wT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"circle\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,radius:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),TT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rect\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),RT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"pill\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),ET=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rotated_rect\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),ccw_rotation:XM,layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),AT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"oval\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),OT=k_.union([wT,TT,RT,ET,AT]).describe(\"Defines solderpaste on the PCB\"),kT=k_.object({type:k_.literal(\"pcb_text\"),pcb_text_id:QM(\"pcb_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:qM,layer:mw,width:$M,height:$M,lines:k_.number(),align:k_.enum([\"bottom-left\"])}).describe(\"Defines text on the PCB\"),LT=k_.object({route_type:k_.literal(\"wire\"),x:XM,y:XM,width:XM,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:mw}),DT=k_.object({route_type:k_.literal(\"via\"),x:XM,y:XM,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:XM.optional(),outer_diameter:XM.optional(),from_layer:mw,to_layer:mw}),zT=k_.union([LT,DT]),FT=k_.object({type:k_.literal(\"pcb_trace\"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:QM(\"pcb_trace\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum([\"constant\",\"interpolated\"]).default(\"constant\").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(zT)}).describe(\"Defines a trace on the PCB\"),BT=k_.object({type:k_.literal(\"pcb_trace_warning\"),pcb_trace_warning_id:QM(\"pcb_trace_warning\"),warning_type:k_.literal(\"pcb_trace_warning\").default(\"pcb_trace_warning\"),message:k_.string(),center:qM.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace warning on the PCB\"),jT=yN.extend({type:k_.literal(\"pcb_trace_error\"),pcb_trace_error_id:QM(\"pcb_trace_error\"),error_type:k_.literal(\"pcb_trace_error\").default(\"pcb_trace_error\"),center:qM.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB\"),$T=yN.extend({type:k_.literal(\"pcb_trace_missing_error\"),pcb_trace_missing_error_id:QM(\"pcb_trace_missing_error\"),error_type:k_.literal(\"pcb_trace_missing_error\").default(\"pcb_trace_missing_error\"),center:qM.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a source trace has no corresponding PCB trace\"),YT=yN.extend({type:k_.literal(\"pcb_port_not_matched_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_port_not_matched_error\").default(\"pcb_port_not_matched_error\"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB where a port is not matched\"),XT=yN.extend({type:k_.literal(\"pcb_port_not_connected_error\"),pcb_port_not_connected_error_id:QM(\"pcb_port_not_connected_error\"),error_type:k_.literal(\"pcb_port_not_connected_error\").default(\"pcb_port_not_connected_error\"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a pcb port is not connected to any trace\"),VT=k_.object({type:k_.literal(\"pcb_net\"),pcb_net_id:QM(\"pcb_net\"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe(\"Defines a net on the PCB\"),WT=k_.object({type:k_.literal(\"pcb_via\"),pcb_via_id:QM(\"pcb_via\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:XM,y:XM,outer_diameter:XM.default(\"0.6mm\"),hole_diameter:XM.default(\"0.25mm\"),from_layer:mw.optional(),to_layer:mw.optional(),layers:k_.array(mw),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe(\"Defines a via on the PCB\"),HT=k_.object({type:k_.literal(\"pcb_board\"),pcb_board_id:QM(\"pcb_board\"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:$M.optional(),height:$M.optional(),center:qM,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this board, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this board, usually corresponding with how the user specified it\"),thickness:$M.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(qM).optional(),shape:k_.enum([\"rect\",\"polygon\"]).optional(),material:k_.enum([\"fr4\",\"fr1\"]).default(\"fr4\"),anchor_position:qM.optional(),anchor_alignment:tN.optional(),position_mode:k_.enum([\"relative_to_panel_anchor\",\"none\"]).optional()}).merge(iT).describe(\"Defines the board outline of the PCB\"),GT=k_.object({type:k_.literal(\"pcb_panel\"),pcb_panel_id:QM(\"pcb_panel\"),width:$M,height:$M,center:qM,thickness:$M.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe(\"Defines a PCB panel that can contain multiple boards\"),UT=yN.extend({type:k_.literal(\"pcb_placement_error\"),pcb_placement_error_id:QM(\"pcb_placement_error\"),error_type:k_.literal(\"pcb_placement_error\").default(\"pcb_placement_error\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a placement error on the PCB\"),ZT=yN.extend({type:k_.literal(\"pcb_panelization_placement_error\"),pcb_panelization_placement_error_id:QM(\"pcb_panelization_placement_error\"),error_type:k_.literal(\"pcb_panelization_placement_error\").default(\"pcb_panelization_placement_error\"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a panelization placement error on the PCB\"),qT=k_.object({type:k_.literal(\"pcb_trace_hint\"),pcb_trace_hint_id:QM(\"pcb_trace_hint\"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(oT),subcircuit_id:k_.string().optional()}).describe(\"A hint that can be used during generation of a PCB trace\"),JT=k_.object({type:k_.literal(\"pcb_silkscreen_line\"),pcb_silkscreen_line_id:QM(\"pcb_silkscreen_line\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:XM.default(\"0.1mm\"),x1:XM,y1:XM,x2:XM,y2:XM,layer:gw}).describe(\"Defines a silkscreen line on the PCB\"),KT=k_.object({type:k_.literal(\"pcb_silkscreen_path\"),pcb_silkscreen_path_id:QM(\"pcb_silkscreen_path\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,route:k_.array(qM),stroke_width:$M}).describe(\"Defines a silkscreen path on the PCB\"),QT=k_.object({type:k_.literal(\"pcb_silkscreen_text\"),pcb_silkscreen_text_id:QM(\"pcb_silkscreen_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:$M,top:$M,bottom:$M,right:$M}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:mw,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:tN.default(\"center\")}).describe(\"Defines silkscreen text on the PCB\"),tR=k_.object({type:k_.literal(\"pcb_copper_text\"),pcb_copper_text_id:QM(\"pcb_copper_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:$M,top:$M,bottom:$M,right:$M}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:mw,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:tN.default(\"center\")}).describe(\"Defines copper text on the PCB\"),eR=k_.object({type:k_.literal(\"pcb_silkscreen_rect\"),pcb_silkscreen_rect_id:QM(\"pcb_silkscreen_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:mw,stroke_width:$M.default(\"1mm\"),corner_radius:$M.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen rect on the PCB\"),nR=k_.object({type:k_.literal(\"pcb_silkscreen_circle\"),pcb_silkscreen_circle_id:QM(\"pcb_silkscreen_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:$M,layer:gw,stroke_width:$M.default(\"1mm\"),is_filled:k_.boolean().optional()}).describe(\"Defines a silkscreen circle on the PCB\"),oR=k_.object({type:k_.literal(\"pcb_silkscreen_oval\"),pcb_silkscreen_oval_id:QM(\"pcb_silkscreen_oval\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius_x:XM,radius_y:XM,layer:gw,ccw_rotation:UM.optional()}).describe(\"Defines a silkscreen oval on the PCB\"),iR=k_.object({type:k_.literal(\"pcb_silkscreen_pill\"),pcb_silkscreen_pill_id:QM(\"pcb_silkscreen_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:mw,ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen pill on the PCB\"),rR=k_.object({type:k_.literal(\"pcb_fabrication_note_text\"),pcb_fabrication_note_text_id:QM(\"pcb_fabrication_note_text\"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"1mm\"),pcb_component_id:k_.string(),text:k_.string(),layer:gw,anchor_position:qM.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),color:k_.string().optional()}).describe(\"Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators\"),sR=k_.object({type:k_.literal(\"pcb_fabrication_note_path\"),pcb_fabrication_note_path_id:QM(\"pcb_fabrication_note_path\"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:mw,route:k_.array(qM),stroke_width:$M,color:k_.string().optional()}).describe(\"Defines a fabrication path on the PCB for fabricators or assemblers\"),aR=k_.object({type:k_.literal(\"pcb_fabrication_note_rect\"),pcb_fabrication_note_rect_id:QM(\"pcb_fabrication_note_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw,stroke_width:$M.default(\"0.1mm\"),corner_radius:$M.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a fabrication note rectangle on the PCB\"),cR=k_.object({type:k_.literal(\"pcb_fabrication_note_dimension\"),pcb_fabrication_note_dimension_id:QM(\"pcb_fabrication_note_dimension\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,from:qM,to:qM,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:$M.optional(),offset_distance:$M.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:$M.default(\"1mm\"),color:k_.string().optional(),arrow_size:$M.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB fabrication notes\"),lR=k_.object({type:k_.literal(\"pcb_note_text\"),pcb_note_text_id:QM(\"pcb_note_text\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"1mm\"),text:k_.string().optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),layer:gw.default(\"top\"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a documentation note in text on the PCB\"),dR=k_.object({type:k_.literal(\"pcb_note_rect\"),pcb_note_rect_id:QM(\"pcb_note_rect\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw.default(\"top\"),stroke_width:$M.default(\"0.1mm\"),corner_radius:$M.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a rectangular documentation note on the PCB\"),hR=k_.object({type:k_.literal(\"pcb_note_path\"),pcb_note_path_id:QM(\"pcb_note_path\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(qM),layer:gw.default(\"top\"),stroke_width:$M.default(\"0.1mm\"),color:k_.string().optional()}).describe(\"Defines a polyline documentation note on the PCB\"),uR=k_.object({type:k_.literal(\"pcb_note_line\"),pcb_note_line_id:QM(\"pcb_note_line\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:XM,y1:XM,x2:XM,y2:XM,layer:gw.default(\"top\"),stroke_width:XM.default(\"0.1mm\"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe(\"Defines a straight documentation note line on the PCB\"),pR=k_.object({type:k_.literal(\"pcb_note_dimension\"),pcb_note_dimension_id:QM(\"pcb_note_dimension\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:qM,to:qM,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:$M.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:$M.default(\"1mm\"),layer:gw.default(\"top\"),color:k_.string().optional(),arrow_size:$M.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB documentation notes\"),mR=yN.extend({type:k_.literal(\"pcb_footprint_overlap_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_footprint_overlap_error\").default(\"pcb_footprint_overlap_error\"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when a pcb footprint overlaps with another element\"),gR=yN.extend({type:k_.literal(\"pcb_courtyard_overlap_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_courtyard_overlap_error\").default(\"pcb_courtyard_overlap_error\"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe(\"Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another\"),fR=k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"rect\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:XM,height:XM,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:XM,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),yR=k_.object({type:k_.literal(\"pcb_cutout\"),pcb_cutout_id:QM(\"pcb_cutout\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),_R=yR.extend({shape:k_.literal(\"rect\"),center:qM,width:$M,height:$M,rotation:UM.optional(),corner_radius:$M.optional()}),bR=yR.extend({shape:k_.literal(\"circle\"),center:qM,radius:$M}),xR=yR.extend({shape:k_.literal(\"polygon\"),points:k_.array(qM)}),vR=yR.extend({shape:k_.literal(\"path\"),route:k_.array(qM),slot_width:$M,slot_length:$M.optional(),space_between_slots:$M.optional(),slot_corner_radius:$M.optional()}),SR=k_.discriminatedUnion(\"shape\",[_R,bR,xR,vR]).describe(\"Defines a cutout on the PCB, removing board material.\"),IR=yN.extend({type:k_.literal(\"pcb_missing_footprint_error\"),pcb_missing_footprint_error_id:QM(\"pcb_missing_footprint_error\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"pcb_missing_footprint_error\").default(\"pcb_missing_footprint_error\"),source_component_id:k_.string()}).describe(\"Defines a missing footprint error on the PCB\"),CR=yN.extend({type:k_.literal(\"external_footprint_load_error\"),external_footprint_load_error_id:QM(\"external_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal(\"external_footprint_load_error\").default(\"external_footprint_load_error\")}).describe(\"Defines an error when an external footprint fails to load\"),PR=yN.extend({type:k_.literal(\"circuit_json_footprint_load_error\"),circuit_json_footprint_load_error_id:QM(\"circuit_json_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"circuit_json_footprint_load_error\").default(\"circuit_json_footprint_load_error\"),circuit_json:k_.array(k_.any()).optional()}).describe(\"Defines an error when a circuit JSON footprint fails to load\"),MR=k_.object({type:k_.literal(\"pcb_group\"),pcb_group_id:QM(\"pcb_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:$M.optional(),height:$M.optional(),center:qM,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this group, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this group, usually corresponding with how the user specified it\"),outline:k_.array(qM).optional(),anchor_position:qM.optional(),anchor_alignment:tN.default(\"center\"),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"none\"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum([\"packed\",\"none\"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:$M}).optional(),autorouter_used_string:k_.string().optional()}).describe(\"Defines a group of components on the PCB\"),NR=yN.extend({type:k_.literal(\"pcb_autorouting_error\"),pcb_error_id:QM(\"pcb_autorouting_error\"),error_type:k_.literal(\"pcb_autorouting_error\").default(\"pcb_autorouting_error\"),subcircuit_id:k_.string().optional()}).describe(\"The autorouting has failed to route a portion of the board\"),wR=k_.object({type:k_.literal(\"pcb_manual_edit_conflict_warning\"),pcb_manual_edit_conflict_warning_id:QM(\"pcb_manual_edit_conflict_warning\"),warning_type:k_.literal(\"pcb_manual_edit_conflict_warning\").default(\"pcb_manual_edit_conflict_warning\"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates\"),TR=k_.enum([\"x-\",\"x+\",\"y+\",\"y-\"]),RR=k_.object({type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\"),pcb_connector_not_in_accessible_orientation_warning_id:QM(\"pcb_connector_not_in_accessible_orientation_warning\"),warning_type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\").default(\"pcb_connector_not_in_accessible_orientation_warning\"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:TR,recommended_facing_direction:TR,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction\"),ER=k_.object({type:k_.literal(\"supplier_footprint_mismatch_warning\"),supplier_footprint_mismatch_warning_id:QM(\"supplier_footprint_mismatch_warning\"),warning_type:k_.literal(\"supplier_footprint_mismatch_warning\").default(\"supplier_footprint_mismatch_warning\"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:_N.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe(\"Warning emitted when a supplier part footprint does not match the expected footprint\"),AR=k_.object({type:k_.literal(\"pcb_breakout_point\"),pcb_breakout_point_id:QM(\"pcb_breakout_point\"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:XM,y:XM}).describe(\"Defines a routing target within a pcb_group for a source_trace or source_net\"),OR=k_.object({type:k_.literal(\"pcb_ground_plane\"),pcb_ground_plane_id:QM(\"pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane on the PCB\"),kR=k_.object({type:k_.literal(\"pcb_ground_plane_region\"),pcb_ground_plane_region_id:QM(\"pcb_ground_plane_region\"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:mw,points:k_.array(qM)}).describe(\"Defines a polygon region of a ground plane\"),LR=k_.object({type:k_.literal(\"pcb_thermal_spoke\"),pcb_thermal_spoke_id:QM(\"pcb_thermal_spoke\"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:XM,spoke_inner_diameter:XM,spoke_outer_diameter:XM,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Pattern for connecting a ground plane to a plated hole\"),DR=k_.object({type:k_.literal(\"pcb_copper_pour\"),pcb_copper_pour_id:QM(\"pcb_copper_pour\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:mw,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),zR=DR.extend({shape:k_.literal(\"rect\"),center:qM,width:$M,height:$M,rotation:UM.optional()}),FR=DR.extend({shape:k_.literal(\"brep\"),brep_shape:eT}),BR=DR.extend({shape:k_.literal(\"polygon\"),points:k_.array(qM)}),jR=k_.discriminatedUnion(\"shape\",[zR,FR,BR]).describe(\"Defines a copper pour on the PCB.\"),$R=yN.extend({type:k_.literal(\"pcb_component_outside_board_error\"),pcb_component_outside_board_error_id:QM(\"pcb_component_outside_board_error\"),error_type:k_.literal(\"pcb_component_outside_board_error\").default(\"pcb_component_outside_board_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:qM,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a PCB component is placed outside the board boundaries\"),YR=yN.extend({type:k_.literal(\"pcb_component_not_on_board_edge_error\"),pcb_component_not_on_board_edge_error_id:QM(\"pcb_component_not_on_board_edge_error\"),error_type:k_.literal(\"pcb_component_not_on_board_edge_error\").default(\"pcb_component_not_on_board_edge_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:qM,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component that must be placed on the board edge is centered away from the edge\"),XR=yN.extend({type:k_.literal(\"pcb_component_invalid_layer_error\"),pcb_component_invalid_layer_error_id:QM(\"pcb_component_invalid_layer_error\"),error_type:k_.literal(\"pcb_component_invalid_layer_error\").default(\"pcb_component_invalid_layer_error\"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:mw,subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)\"),VR=yN.extend({type:k_.literal(\"pcb_via_clearance_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_via_clearance_error\").default(\"pcb_via_clearance_error\"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when vias are closer than the allowed clearance\"),WR=yN.extend({type:k_.literal(\"pcb_via_trace_clearance_error\"),pcb_via_trace_clearance_error_id:QM(\"pcb_via_trace_clearance_error\"),error_type:k_.literal(\"pcb_via_trace_clearance_error\").default(\"pcb_via_trace_clearance_error\"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a via and trace are closer than the allowed clearance\"),HR=yN.extend({type:k_.literal(\"pcb_pad_pad_clearance_error\"),pcb_pad_pad_clearance_error_id:QM(\"pcb_pad_pad_clearance_error\"),error_type:k_.literal(\"pcb_pad_pad_clearance_error\").default(\"pcb_pad_pad_clearance_error\"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when pads are closer than the allowed clearance\"),GR=yN.extend({type:k_.literal(\"pcb_pad_trace_clearance_error\"),pcb_pad_trace_clearance_error_id:QM(\"pcb_pad_trace_clearance_error\"),error_type:k_.literal(\"pcb_pad_trace_clearance_error\").default(\"pcb_pad_trace_clearance_error\"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pad and trace are closer than allowed clearance\"),UR=k_.object({type:k_.literal(\"pcb_courtyard_rect\"),pcb_courtyard_rect_id:QM(\"pcb_courtyard_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw,ccw_rotation:UM.optional(),color:k_.string().optional()}).describe(\"Defines a courtyard rectangle on the PCB\"),ZR=k_.object({type:k_.literal(\"pcb_courtyard_outline\"),pcb_courtyard_outline_id:QM(\"pcb_courtyard_outline\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,outline:k_.array(qM).min(2)}).describe(\"Defines a courtyard outline on the PCB\"),qR=k_.object({type:k_.literal(\"pcb_courtyard_polygon\"),pcb_courtyard_polygon_id:QM(\"pcb_courtyard_polygon\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,points:k_.array(qM).min(3),color:k_.string().optional()}).describe(\"Defines a courtyard polygon on the PCB\"),JR=k_.object({type:k_.literal(\"pcb_courtyard_circle\"),pcb_courtyard_circle_id:QM(\"pcb_courtyard_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:$M,layer:gw,color:k_.string().optional()}).describe(\"Defines a courtyard circle on the PCB\"),KR=k_.object({type:k_.literal(\"cad_component\"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:JM,rotation:JM.optional(),size:JM.optional(),layer:mw.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:eN.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum([\"x+\",\"x-\",\"y+\",\"y-\",\"z+\",\"z-\"]).optional().describe('The direction in the model\\'s coordinate space that is considered \"up\" or \"coming out of the board surface\"'),model_origin_position:JM.optional(),model_origin_alignment:k_.enum([\"unknown\",\"center\",\"center_of_component_on_board_surface\",\"bottom_center_of_component\"]).optional(),model_object_fit:k_.enum([\"contain_within_bounds\",\"fill_bounds\"]).optional().default(\"contain_within_bounds\"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),anchor_alignment:k_.enum([\"center\",\"center_of_component_on_board_surface\"]).optional().default(\"center\")}).describe(\"Defines a component on the PCB\"),QR=k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]),tE=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),eE=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:QM(\"simulation_voltage_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:jM}).describe(\"Defines a DC voltage source for simulation\"),nE=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:QM(\"simulation_voltage_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:jM.optional(),frequency:YM.optional(),peak_to_peak_voltage:jM.optional(),wave_shape:QR.optional(),phase:UM.optional(),duty_cycle:tE.optional()}).describe(\"Defines an AC voltage source for simulation\"),oE=k_.union([eE,nE]).describe(\"Defines a voltage source for simulation\"),iE=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),rE=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:QM(\"simulation_current_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:VM}).describe(\"Defines a DC current source for simulation\"),sE=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:QM(\"simulation_current_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:VM.optional(),frequency:YM.optional(),peak_to_peak_current:VM.optional(),wave_shape:QR.optional(),phase:UM.optional(),duty_cycle:iE.optional()}).describe(\"Defines an AC current source for simulation\"),aE=k_.union([rE,sE]).describe(\"Defines a current source for simulation\"),cE=k_.union([k_.literal(\"spice_dc_sweep\"),k_.literal(\"spice_dc_operating_point\"),k_.literal(\"spice_transient_analysis\"),k_.literal(\"spice_ac_analysis\")]),lE=k_.object({type:k_.literal(\"simulation_experiment\"),simulation_experiment_id:QM(\"simulation_experiment\"),name:k_.string(),experiment_type:cE,time_per_step:WM.optional(),start_time_ms:HM.optional(),end_time_ms:HM.optional()}).describe(\"Defines a simulation experiment configuration\"),dE=k_.object({type:k_.literal(\"simulation_transient_voltage_graph\"),simulation_transient_voltage_graph_id:QM(\"simulation_transient_voltage_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:WM,start_time_ms:HM,end_time_ms:HM,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores voltage measurements over time for a simulation\"),hE=k_.object({type:k_.literal(\"simulation_switch\"),simulation_switch_id:QM(\"simulation_switch\"),source_component_id:k_.string().optional(),closes_at:HM.optional(),opens_at:HM.optional(),starts_closed:k_.boolean().optional(),switching_frequency:YM.optional()}).describe(\"Defines a switch for simulation timing control\"),uE=k_.object({type:k_.literal(\"simulation_voltage_probe\"),simulation_voltage_probe_id:QM(\"simulation_voltage_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.\").superRefine((t,e)=\u003e{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n\u0026\u0026o?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a differential probe.\"}):n?t.signal_input_source_port_id\u0026\u0026t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id.\"}):o\u0026\u0026(t.signal_input_source_net_id\u0026\u0026t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id.\"}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id.\"})}),pE=yN.extend({type:k_.literal(\"simulation_unknown_experiment_error\"),simulation_unknown_experiment_error_id:QM(\"simulation_unknown_experiment_error\"),error_type:k_.literal(\"simulation_unknown_experiment_error\").default(\"simulation_unknown_experiment_error\"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"An unknown error occurred during the simulation experiment.\"),mE=k_.object({type:k_.literal(\"simulation_op_amp\"),simulation_op_amp_id:QM(\"simulation_op_amp\"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe(\"Defines a simple ideal operational amplifier for simulation\"),gE=(k_.union([sw,iw,rw,ow,cw,aw,MN,xN,SN,CN,vN,NN,EN,AN,DN,FN,BN,VN,jN,$N,YN,XN,kN,ON,hw,fw,lw,WN,UN,ZN,JN,KN,yw,_w,bw,xw,vw,ew,dw,rT,uT,IR,CR,PR,wR,RR,ER,bT,fR,xT,VT,kT,FT,BT,WT,NT,OT,HT,GT,MR,qT,JT,KT,QT,iR,tR,eR,nR,oR,jT,$T,UT,ZT,YT,XT,VR,WR,HR,GR,sR,rR,aR,cR,lR,dR,hR,uR,pR,NR,mR,gR,AR,SR,OR,kR,LR,jR,$R,YR,XR,UR,ZR,qR,JR,Sw,zw,Ew,Aw,Ow,kw,ww,Rw,Fw,Lw,Iw,jw,$w,Bw,Hw,Gw,Uw,Zw,Kw,qw,Jw,KR,oE,aE,lE,dE,hE,uE,pE,mE]),!0),fE={CCW:-1,CW:1,NOT_ORIENTABLE:0},yE=2*Math.PI,_E=Object.freeze({__proto__:null,BOUNDARY:2,CCW:gE,CONTAINS:3,CW:!1,END_VERTEX:2,INSIDE:1,INTERLACE:4,NOT_VERTEX:0,ORIENTATION:fE,OUTSIDE:0,OVERLAP_OPPOSITE:2,OVERLAP_SAME:1,PIx2:yE,START_VERTEX:1}),bE=1e-6;function xE(t){bE=t}function vE(){return bE}function SE(t){return t\u003cbE\u0026\u0026t\u003e-bE}function IE(t,e){return t-e\u003cbE\u0026\u0026t-e\u003e-bE}function CE(t,e){return t-e\u003ebE}function PE(t,e){return t-e\u003c-bE}var ME={Utils:Object.freeze({__proto__:null,DECIMALS:3,EQ:IE,EQ_0:SE,GE:function(t,e){return t-e\u003e-bE},GT:CE,LE:function(t,e){return t-e\u003cbE},LT:PE,getTolerance:vE,setTolerance:xE}),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 _E)ME[t]=_E[t];Object.defineProperty(ME,\"DP_TOL\",{get:function(){return vE()},set:function(t){xE(t)}});var NE=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\")}};ME.Errors=NE;var wE=class{constructor(t,e){this.first=t,this.last=e||this.first}[Symbol.iterator](){let t;return{next:()=\u003e(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=[],o=t||this.first,i=e||this.last,r=o;if(void 0===r)return n;do{n.push(r),r=r.next}while(r!==i.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\u0026\u0026(n.prev=t),t.prev=e,t.next=n,this.last===e\u0026\u0026(this.last=t)}return this.last.next=void 0,this.first.prev=void 0,this}remove(t){return t===this.first\u0026\u0026t===this.last?(this.first=void 0,this.last=void 0):(t.prev\u0026\u0026(t.prev.next=t.next),t.next\u0026\u0026(t.next.prev=t.prev),t===this.first\u0026\u0026(this.first=t.next),t===this.last\u0026\u0026(this.last=t.prev)),this}isEmpty(){return void 0===this.first}static testInfiniteLoop(t){let e=t,n=t;do{if(e!=t\u0026\u0026e===n)throw NE.INFINITE_LOOP;e=e.next,n=n.next.next}while(e!=t)}},TE={stroke:\"black\"},RE=class{constructor(t=TE){for(const e in t)this[e]=t[e];this.stroke=t.stroke??TE.stroke}toAttributesString(){return Object.keys(this).reduce((t,e)=\u003et+(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 EE(t){return new RE(t).toAttributesString()}function AE(t,e){let n=[],[o,i,r]=t.standard,[s,a,c]=e.standard,l=o*a-i*s,d=r*a-i*c,h=o*c-r*s;if(!ME.Utils.EQ_0(l)){let t,e;0===i?(t=r/o,e=h/l):0===a?(t=c/s,e=h/l):0===o?(t=d/l,e=r/i):0===s?(t=d/l,e=c/a):(t=d/l,e=h/l),n.push(new ME.Point(t,e))}return n}function OE(t,e){let n=[],o=e.pc.projectionOn(t),i=e.pc.distanceTo(o)[0];if(ME.Utils.EQ(i,e.r))n.push(o);else if(ME.Utils.LT(i,e.r)){let r,s,a=Math.sqrt(e.r*e.r-i*i);r=t.norm.rotate90CCW().multiply(a),s=o.translate(r),n.push(s),r=t.norm.rotate90CW().multiply(a),s=o.translate(r),n.push(s)}return n}function kE(t,e){let n=[];for(let o of e.toSegments()){let e=DE(o,t);for(let t of e)eA(t,n)||n.push(t)}return n}function LE(t,e){let n=[];if(0===kE(t,e.box).length)return n;let o=OE(t,new ME.Circle(e.pc,e.r));for(let t of o)t.on(e)\u0026\u0026n.push(t);return n}function DE(t,e){let n=[];return t.ps.on(e)\u0026\u0026n.push(t.ps),t.pe.on(e)\u0026\u0026!t.isZeroLength()\u0026\u0026n.push(t.pe),n.length\u003e0||t.isZeroLength()||t.ps.leftTo(e)\u0026\u0026t.pe.leftTo(e)||!t.ps.leftTo(e)\u0026\u0026!t.pe.leftTo(e)?n:AE(new ME.Line(t.ps,t.pe),e)}function zE(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)\u0026\u0026n.push(t.ps),n;if(e.isZeroLength())return e.ps.on(t)\u0026\u0026n.push(e.ps),n;let o=new ME.Line(t.ps,t.pe),i=new ME.Line(e.ps,e.pe);if(o.incidentTo(i))t.ps.on(e)\u0026\u0026n.push(t.ps),t.pe.on(e)\u0026\u0026n.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 if(o.parallelTo(i)){const o=new ME.Vector(t.ps,t.pe),i=new ME.Vector(e.ps,e.pe),r=new ME.Vector(t.ps,e.ps),s=o.cross(i);if(!ME.Utils.EQ_0(s)){const a=r.cross(i)/s,c=r.cross(o)/s;ME.Utils.GE(a,0)\u0026\u0026ME.Utils.LE(a,1)\u0026\u0026ME.Utils.GE(c,0)\u0026\u0026ME.Utils.LE(c,1)\u0026\u0026n.push(FE(t.ps.translate(o.multiply(a)),t,e))}}else{let r=AE(o,i);r.length\u003e0\u0026\u0026BE(r[0],t)\u0026\u0026BE(r[0],e)\u0026\u0026n.push(FE(r[0],t,e))}return n}function FE(t,e,n){for(const o of[e.ps,e.pe,n.ps,n.pe])if(t.equalTo(o))return o;return t}function BE(t,e){const n=e.box;return ME.Utils.LE(t.x,n.xmax)\u0026\u0026ME.Utils.GE(t.x,n.xmin)\u0026\u0026ME.Utils.LE(t.y,n.ymax)\u0026\u0026ME.Utils.GE(t.y,n.ymin)}function jE(t,e){let n=[];if(t.isZeroLength()){let[o,i]=t.ps.distanceTo(e.pc);return ME.Utils.EQ(o,e.r)\u0026\u0026n.push(t.ps),n}let o=OE(new ME.Line(t.ps,t.pe),e);for(let e of o)e.on(t)\u0026\u0026n.push(e);return n}function $E(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)\u0026\u0026n.push(t.ps),n;let o=OE(new ME.Line(t.ps,t.pe),new ME.Circle(e.pc,e.r));for(let i of o)i.on(t)\u0026\u0026i.on(e)\u0026\u0026n.push(i);return n}function YE(t,e){let n=[],o=new ME.Vector(t.pc,e.pc),i=t.r,r=e.r;if(ME.Utils.EQ_0(i)||ME.Utils.EQ_0(r))return n;if(ME.Utils.EQ_0(o.x)\u0026\u0026ME.Utils.EQ_0(o.y)\u0026\u0026ME.Utils.EQ(i,r))return n.push(t.pc.translate(-i,0)),n;let s,a=t.pc.distanceTo(e.pc)[0];if(ME.Utils.GT(a,i+r))return n;if(ME.Utils.LT(a,Math.abs(i-r)))return n;if(o.x/=a,o.y/=a,ME.Utils.EQ(a,i+r)||ME.Utils.EQ(a,Math.abs(i-r)))return s=t.pc.translate(i*o.x,i*o.y),n.push(s),n;let c=i*i/(2*a)-r*r/(2*a)+a/2,l=t.pc.translate(c*o.x,c*o.y),d=Math.sqrt(i*i-c*c);return s=l.translate(o.rotate90CCW().multiply(d)),n.push(s),s=l.translate(o.rotate90CW().multiply(d)),n.push(s),n}function XE(t,e){let n=[];if(t.pc.equalTo(e.pc)\u0026\u0026ME.Utils.EQ(t.r,e.r)){let o;return o=t.start,o.on(e)\u0026\u0026n.push(o),o=t.end,o.on(e)\u0026\u0026n.push(o),o=e.start,o.on(t)\u0026\u0026n.push(o),o=e.end,o.on(t)\u0026\u0026n.push(o),n}let o=new ME.Circle(t.pc,t.r),i=new ME.Circle(e.pc,e.r),r=o.intersect(i);for(let o of r)o.on(t)\u0026\u0026o.on(e)\u0026\u0026n.push(o);return n}function VE(t,e){let n=[];if(e.pc.equalTo(t.pc)\u0026\u0026ME.Utils.EQ(e.r,t.r))return n.push(t.start),n.push(t.end),n;let o=YE(e,new ME.Circle(t.pc,t.r));for(let e of o)e.on(t)\u0026\u0026n.push(e);return n}function WE(t,e){return t.isSegment?zE(t.shape,e):$E(e,t.shape)}function HE(t,e){return t.isSegment?$E(t.shape,e):XE(t.shape,e)}function GE(t,e){return t.isSegment?DE(t.shape,e):LE(e,t.shape)}function UE(t,e){return t.isSegment?jE(t.shape,e):VE(t.shape,e)}function ZE(t,e){let n=[];for(let o of e.edges)for(let e of WE(o,t))n.push(e);return n}function qE(t,e){let n=[];for(let o of e.edges)for(let e of HE(o,t))n.push(e);return n}function JE(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of GE(o,t))eA(e,n)||n.push(e);return t.sortPoints(n)}function KE(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of UE(o,t))n.push(e);return n}function QE(t,e){return t.isSegment?WE(e,t.shape):t.isArc?HE(e,t.shape):t.isLine?GE(e,t.shape):t.isRay?(n=e,o=t.shape,n.isSegment?oA(o,n.shape):iA(o,n.shape)):[];var n,o}function tA(t,e){let n=[];if(e.isEmpty()||t.shape.box.not_intersect(e.box))return n;let o=e.edges.search(t.shape.box);for(let e of o)n=[...n,...QE(t,e)];return n}function eA(t,e){return e.some(e=\u003ee.equalTo(t))}function nA(t){return new ME.Line(t.start,t.norm)}function oA(t,e){return DE(e,nA(t)).filter(e=\u003et.contains(e))}function iA(t,e){return LE(nA(t),e).filter(e=\u003et.contains(e))}function rA(t,e){return OE(nA(t),e).filter(e=\u003et.contains(e))}function sA(t,e){return AE(nA(t),e).filter(e=\u003et.contains(e))}function aA(t,e){return JE(nA(t),e).filter(e=\u003et.contains(e))}function cA(t,e){if(t.intersect\u0026\u0026t.intersect instanceof Function)return t.intersect(e);throw NE.UNSUPPORTED_SHAPE_TYPE}function lA(t,e){let n=[];for(let o of e)n=[...n,...cA(t,o.shape)];return n}var dA=class t extends wE{constructor(...t){if(super(),this.isInfinite=!1,1===t.length\u0026\u0026t[0]instanceof Array\u0026\u0026t[0].length\u003e0){const e=t[0],n=e.length,o=t=\u003et instanceof ME.Segment||t instanceof ME.Arc||t instanceof ME.Ray,i=t=\u003et instanceof ME.Segment||t instanceof ME.Arc;if(!(1===n\u0026\u0026(t=\u003et instanceof ME.Segment||t instanceof ME.Arc||t instanceof ME.Ray||t instanceof ME.Line)(e[0])||n\u003e1\u0026\u0026o(e[0])\u0026\u0026o(e[n-1])\u0026\u0026e.slice(1,n-1).every(i)))throw ME.Errors.ILLEGAL_PARAMETERS;this.isInfinite=e.some(t=\u003et instanceof ME.Ray||t instanceof ME.Line);for(let t of e){let e=new ME.Edge(t);this.append(e)}this.setArcLength()}}get edges(){return[...this]}get box(){return this.edges.reduce((t,e)=\u003et.merge(e.box),new ME.Box)}get vertices(){let t=this.edges.map(t=\u003et.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\u003ethis.length||t\u003c0)return null;if(this.isInfinite)return null;let e=null;for(let n of this)if(t\u003e=n.arc_length\u0026\u0026(n===this.last||t\u003cn.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 o=new ME.Edge(n[0]),i=e.prev;return this.insert(o,i),e.shape=n[1],o}getChain(t,e){let n=[];for(let o=t;o!==e.next;o=o.next)n.push(o);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 ME.Point){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Line){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Circle){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Segment){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Arc){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Box){const[e,n]=ME.Distance.shape2multiline(new ME.Polygon(t),this);return[e,n.reverse()]}if(t instanceof ME.Multiline)return ME.Distance.multiline2multiline(this,t);throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}intersect(t){return t instanceof ME.Multiline?function(t,e){let n=[];for(let o of t)for(let t of e)n=[...n,...cA(o.shape,t.shape)];return n}(this,t):lA(t,this)}contains(t){if(t instanceof ME.Point)return this.edges.some(e=\u003ee.shape.contains(t));throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}translate(e){return new t(this.edges.map(t=\u003et.shape.translate(e)))}rotate(e=0,n=new ME.Point){return new t(this.edges.map(t=\u003et.shape.rotate(e,n)))}transform(e=new ME.Matrix){return new t(this.edges.map(t=\u003et.shape.transform(e)))}toShapes(){return this.edges.map(t=\u003et.shape.clone())}toJSON(){return this.edges.map(t=\u003et.toJSON())}svgPoints(){return this.vertices.map(t=\u003e`${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\u003cpath ${EE({fill:\"none\",...t})} d=\"`;e+=`\\nM${this.first.start.x},${this.first.start.y}`;for(let t of this)e+=t.svg();return e+='\" \u003e\\n\u003c/path\u003e',e}};ME.Multiline=dA;function hA(t,e,n){let o=n.length,i=t.shape.split(e);if(0===i.length)return;let r=0;r=null===i[0]?0:null===i[1]?t.shape.length:i[0].length;let s,a=0;IE(r,0)\u0026\u0026(a|=1),IE(r,t.shape.length)\u0026\u0026(a|=2),s=r===1/0?i[0].coord(e):2\u0026a\u0026\u0026t.next\u0026\u00260===t.next.arc_length?0:t.arc_length+r,n.push({id:o,pt:e,arc_length:s,edge_before:t,edge_after:void 0,face:t.face,is_vertex:a})}function uA(t){t.int_points1_sorted=pA(t.int_points1),t.int_points2_sorted=pA(t.int_points2)}function pA(t){let e=new Map,n=0;for(let o of t)e.has(o.face)||(e.set(o.face,n),n++);for(let n of t)n.faceId=e.get(n.face);return t.slice().sort(mA)}function mA(t,e){return t.faceId\u003ce.faceId?-1:t.faceId\u003ee.faceId?1:t.arc_length\u003ce.arc_length?-1:t.arc_length\u003ee.arc_length?1:0}function gA(t){if(t.int_points1.length\u003c2)return;let e,n,o,i,r=!1;for(let s=0;s\u003ct.int_points1_sorted.length;s++)if(-1!==t.int_points1_sorted[s].id){e=t.int_points1_sorted[s],n=t.int_points2[e.id];for(let a=s+1;a\u003ct.int_points1_sorted.length\u0026\u0026(o=t.int_points1_sorted[a],IE(o.arc_length,e.arc_length));a++)-1!==o.id\u0026\u0026(i=t.int_points2[o.id],-1!==i.id\u0026\u0026o.edge_before===e.edge_before\u0026\u0026o.edge_after===e.edge_after\u0026\u0026i.edge_before===n.edge_before\u0026\u0026i.edge_after===n.edge_after\u0026\u0026(o.id=-1,i.id=-1,r=!0))}n=t.int_points2_sorted[0],e=t.int_points1[n.id];for(let o=1;o\u003ct.int_points2_sorted.length;o++){let i=t.int_points2_sorted[o];if(-1===i.id)continue;if(-1===n.id||!IE(i.arc_length,n.arc_length)){n=i,e=t.int_points1[n.id];continue}let s=t.int_points1[i.id];s.edge_before===e.edge_before\u0026\u0026s.edge_after===e.edge_after\u0026\u0026i.edge_before===n.edge_before\u0026\u0026i.edge_after===n.edge_after\u0026\u0026(s.id=-1,i.id=-1,r=!0)}r\u0026\u0026(t.int_points1=t.int_points1.filter(t=\u003et.id\u003e=0),t.int_points2=t.int_points2.filter(t=\u003et.id\u003e=0),t.int_points1.forEach((t,e)=\u003et.id=e),t.int_points2.forEach((t,e)=\u003et.id=e))}function fA(t){for(let e of t)e.edge_before\u0026\u0026(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\u0026\u0026(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\u0026\u0026(e.edge_before.bvEnd=2),e.edge_after\u0026\u0026(e.edge_after.bvStart=2)}function yA(t,e){for(let n of t)n.edge_before\u0026\u0026n.edge_before.setInclusion(e),n.edge_after\u0026\u0026n.edge_after.setInclusion(e)}function _A(t,e,n){let o,i,r=1;if(1===t.length)return 1;o=t[e];for(let s=e+1;s\u003ct.length\u0026\u0026o.face===n\u0026\u0026(i=t[s],i.pt.equalTo(o.pt)\u0026\u0026i.edge_before===o.edge_before\u0026\u0026i.edge_after===o.edge_after);s++)r++;return r}function bA(t,e){if(e){for(let n of e){let e=n.edge_before;if(n.is_vertex=0,e.shape.start\u0026\u0026e.shape.start.equalTo(n.pt)\u0026\u0026(n.is_vertex|=1),e.shape.end\u0026\u0026e.shape.end.equalTo(n.pt)\u0026\u0026(n.is_vertex|=2),1\u0026n.is_vertex){n.edge_before=e.prev,e.prev\u0026\u0026(n.is_vertex=2);continue}if(2\u0026n.is_vertex)continue;let o=t.addVertex(n.pt,e);n.edge_before=o}for(let n of e)n.edge_before?n.edge_after=n.edge_before.next:t instanceof dA\u0026\u00261\u0026n.is_vertex\u0026\u0026(n.edge_after=t.first)}}function xA(t,e,n){const o=t.edge_before,i=e.edge_after,r=n.length;o.next=n[0],n[0].prev=o,n[r-1].next=i,i.prev=n[r-1]}ME.multiline=(...t)=\u003enew ME.Multiline(...t);var{INSIDE:vA,OUTSIDE:SA,BOUNDARY:IA,OVERLAP_SAME:CA,OVERLAP_OPPOSITE:PA}=_E,{NOT_VERTEX:MA,START_VERTEX:NA,END_VERTEX:wA}=_E;function TA(t,e){let n=e.clone().reverse(),[o,i]=LA(t,n,3,!0);return o}function RA(t,e){let[n,o]=LA(t,e,2,!0);return n}function EA(t,e){let[n,o]=LA(t,e,2,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=\u003et.shape)];let r=[];for(let t of o.faces)r=[...r,...[...t.edges].map(t=\u003et.shape)];return[i,r]}function AA(t,e){let[n,o]=LA(t,e,3,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=\u003et.shape)];return i}function OA(t,e){let n=t.clone(),o=e.clone(),i=DA(n,o);return uA(i),bA(n,i.int_points1_sorted),bA(o,i.int_points2_sorted),gA(i),uA(i),[i.int_points1_sorted.map(t=\u003et.pt),i.int_points2_sorted.map(t=\u003et.pt)]}function kA(t,e,n,o){let i=zA(t,n.int_points1),r=zA(e,n.int_points2);for(FA(i,e),FA(r,t),fA(n.int_points1),fA(n.int_points2),yA(n.int_points1,e),yA(n.int_points2,t);BA(t,e,n.int_points1,n.int_points1_sorted,n.int_points2,n););!function(t){let e,n,o,i=t.int_points1.length;for(let r=0;r\u003ci;r++){let s=t.int_points1_sorted[r];s.face!==e\u0026\u0026(n=r,e=s.face);let a,c=r,l=_A(t.int_points1_sorted,r,e);a=c+l\u003ci\u0026\u0026t.int_points1_sorted[c+l].face===e?c+l:n;let d=_A(t.int_points1_sorted,a,e);o=null;for(let n=a;n\u003ca+d;n++){let i=t.int_points1_sorted[n];if(i.face===e\u0026\u0026t.int_points2[i.id].face===t.int_points2[s.id].face){o=i;break}}if(null===o)continue;let h=s.edge_after,u=o.edge_before;if(2!==h.bv||2!==u.bv)continue;if(h!==u)continue;let p=t.int_points2[s.id],m=t.int_points2[o.id],g=p.edge_after,f=m.edge_before;2===g.bv\u0026\u00262===f.bv\u0026\u0026g===f||(p=t.int_points2[o.id],m=t.int_points2[s.id],g=p.edge_after,f=m.edge_before),2===g.bv\u0026\u00262===f.bv\u0026\u0026g===f\u0026\u0026h.setOverlap(g)}}(n),jA(t,o,n.int_points1_sorted,!0),jA(e,o,n.int_points2_sorted,!1),XA(t,i,o,!0),XA(e,r,o,!1)}function LA(t,e,n,o){let i=t.clone(),r=e.clone(),s=DA(i,r);return uA(s),bA(i,s.int_points1_sorted),bA(r,s.int_points2_sorted),gA(s),uA(s),kA(i,r,s,n),o\u0026\u0026function(t,e,n){!function(t,e,n,o){for(let n of e.faces){for(let e of n)t.edges.add(e);void 0===o.find(t=\u003et.face===n)\u0026\u0026t.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\u003cn.int_points1.length;t++){let e=n.int_points1[t],o=n.int_points2[t];if(void 0!==e.edge_before\u0026\u0026void 0===e.edge_after\u0026\u0026void 0===o.edge_before\u0026\u0026void 0!==o.edge_after\u0026\u0026(e.edge_before.next=o.edge_after,o.edge_after.prev=e.edge_before,e.edge_after=o.edge_after,o.edge_before=e.edge_before),void 0!==o.edge_before\u0026\u0026void 0===o.edge_after\u0026\u0026void 0===e.edge_before\u0026\u0026void 0!==e.edge_after\u0026\u0026(o.edge_before.next=e.edge_after,e.edge_after.prev=o.edge_before,o.edge_after=e.edge_after,e.edge_before=o.edge_before),void 0!==e.edge_before\u0026\u0026void 0===e.edge_after)for(let t of n.int_points1_sorted)t!==e\u0026\u0026void 0===t.edge_before\u0026\u0026void 0!==t.edge_after\u0026\u0026t.pt.equalTo(e.pt)\u0026\u0026(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!==o.edge_before\u0026\u0026void 0===o.edge_after)for(let t of n.int_points2_sorted)t!==o\u0026\u0026void 0===t.edge_before\u0026\u0026void 0!==t.edge_after\u0026\u0026t.pt.equalTo(o.pt)\u0026\u0026(o.edge_before.next=t.edge_after,t.edge_after.prev=o.edge_before,o.edge_after=t.edge_after,t.edge_before=o.edge_before)}}(0,0,n),$A(t,n.int_points1),$A(e,n.int_points2),YA(t,n.int_points1,n.int_points2),YA(t,n.int_points2,n.int_points1),VA(t),VA(e)}(i,r,s),[i,r]}function DA(t,e){let n={int_points1:[],int_points2:[]};for(let o of t.edges){let t=e.edges.search(o.box);for(let e of t){let t=o.shape.intersect(e.shape);for(let i of t)hA(o,i,n.int_points1),hA(e,i,n.int_points2)}}return n}function zA(t,e){let n=[];for(let o of t.faces)e.find(t=\u003et.face===o)||n.push(o);return n}function FA(t,e){for(let n of t)n.first.bv=n.first.bvStart=n.first.bvEnd=void 0,n.first.setInclusion(e)}function BA(t,e,n,o,i,r){let s,a,c,l=o.length,d=!1;for(let h=0;h\u003cl;h++){let u=o[h];u.face!==s\u0026\u0026(a=h,s=u.face);let p,m=h,g=_A(o,h,s);p=m+g\u003cl\u0026\u0026o[m+g].face===s?m+g:a;let f=_A(o,p,s);c=null;for(let t=p;t\u003cp+f;t++){let e=o[t];if(e.face===s\u0026\u0026i[e.id].face===i[u.id].face){c=e;break}}if(null===c)continue;let y=u.edge_after,_=c.edge_before;if(y.bv!==IA||_.bv==IA)if(y.bv==IA||_.bv!==IA){if(y.bv===IA\u0026\u0026_.bv===IA\u0026\u0026y!=_||y.bv===vA\u0026\u0026_.bv===SA||y.bv===SA\u0026\u0026_.bv===vA){let t=y.next;for(;t!=_;)t.bvStart=void 0,t.bvEnd=void 0,t.bv=void 0,t.setInclusion(e),t=t.next}if(y.bv===IA\u0026\u0026_.bv===IA\u0026\u0026y!=_){let t,e=y.next;for(;e!=_;){if(e.bv!=IA)if(void 0===t)t=e.bv;else if(e.bv!=t)throw NE.UNRESOLVED_BOUNDARY_CONFLICT;e=e.next}null!=t\u0026\u0026(y.bv=t,_.bv=t);continue}if(y.bv===vA\u0026\u0026_.bv===SA||y.bv===SA\u0026\u0026_.bv===vA){let o=y;for(;o!=_;){if(o.bvStart===y.bv\u0026\u0026o.bvEnd===_.bv){let[s,a]=o.shape.distanceTo(e);if(s\u003c10*ME.DP_TOL){hA(o,a.ps,n);let s=n[n.length-1];if(s.is_vertex\u0026NA)s.edge_after=o,s.edge_before=o.prev,o.bvStart=IA,o.bv=void 0,o.setInclusion(e);else if(s.is_vertex\u0026wA)s.edge_after=o.next,o.bvEnd=IA,o.bv=void 0,o.setInclusion(e);else{let t=e.addVertex(s.pt,o);s.edge_before=t,s.edge_after=t.next,t.setInclusion(e),t.next.bvStart=IA,t.next.bvEnd=void 0,t.next.bv=void 0,t.next.setInclusion(e)}let c=e.findEdgeByPoint(a.pe);hA(c,a.pe,i);let l=i[i.length-1];if(l.is_vertex\u0026NA)l.edge_after=c,l.edge_before=c.prev;else if(l.is_vertex\u0026wA)l.edge_after=c.next;else{let n=i.find(t=\u003et.edge_after===c),o=e.addVertex(l.pt,c);l.edge_before=o,l.edge_after=o.next,n\u0026\u0026(n.edge_after=o),o.bvStart=void 0,o.bvEnd=IA,o.bv=void 0,o.setInclusion(t),o.next.bvStart=IA,o.next.bvEnd=void 0,o.next.bv=void 0,o.next.setInclusion(t)}uA(r),d=!0;break}}o=o.next}if(d)break;throw NE.UNRESOLVED_BOUNDARY_CONFLICT}}else _.bv=y.bv;else y.bv=_.bv}return d}function jA(t,e,n,o){if(!n)return;let i,r,s,a;for(let c=0;c\u003cn.length;c++){if(s=n[c],s.face!==i\u0026\u0026(r=c,i=s.face),i.isEmpty())continue;let l,d=c,h=_A(n,c,i);l=d+h\u003cn.length\u0026\u0026n[d+h].face===s.face?d+h:r,a=n[l];let u=l,p=_A(n,u,i),m=s.edge_after,g=a.edge_before;if(m.bv===vA\u0026\u0026g.bv===vA\u0026\u00261===e||m.bv===SA\u0026\u0026g.bv===SA\u0026\u00262===e||(m.bv===SA||g.bv===SA)\u0026\u00263===e\u0026\u0026!o||(m.bv===vA||g.bv===vA)\u0026\u00263===e\u0026\u0026o||m.bv===IA\u0026\u0026g.bv===IA\u0026\u0026m.overlap\u0026CA\u0026\u0026o||m.bv===IA\u0026\u0026g.bv===IA\u0026\u0026m.overlap\u0026PA){t.removeChain(i,m,g);for(let t=d;t\u003cd+h;t++)n[t].edge_after=void 0;for(let t=u;t\u003cu+p;t++)n[t].edge_before=void 0}c+=h-1}}function $A(t,e){for(let n of e)t.faces.delete(n.face),n.face=void 0,n.edge_before\u0026\u0026(n.edge_before.face=void 0),n.edge_after\u0026\u0026(n.edge_after.face=void 0)}function YA(t,e,n){for(let o of e){if(void 0===o.edge_before||void 0===o.edge_after)continue;if(o.face)continue;if(o.edge_after.face||o.edge_before.face)continue;let i=o.edge_after,r=o.edge_before;try{wE.testInfiniteLoop(i)}catch(t){throw NE.CANNOT_COMPLETE_BOOLEAN_OPERATION}let s=t.addFace(i,r);for(let t of e)t.edge_before\u0026\u0026t.edge_after\u0026\u0026t.edge_before.face===s\u0026\u0026t.edge_after.face===s\u0026\u0026(t.face=s);for(let t of n)t.edge_before\u0026\u0026t.edge_after\u0026\u0026t.edge_before.face===s\u0026\u0026t.edge_after.face===s\u0026\u0026(t.face=s)}}function XA(t,e,n,o){for(let i of e){let e=i.first.bv;(1===n\u0026\u0026e===vA||3===n\u0026\u0026e===vA\u0026\u0026o||3===n\u0026\u0026e===SA\u0026\u0026!o||2===n\u0026\u0026e===SA)\u0026\u0026t.deleteFace(i)}}function VA(t){const e=[];for(const n of t.edges)n.face\u0026\u0026t.faces.has(n.face)||e.push(n);for(const n of e)t.edges.delete(n)}var WA=Object.freeze({__proto__:null,BOOLEAN_INTERSECT:2,BOOLEAN_SUBTRACT:3,BOOLEAN_UNION:1,calculateIntersections:OA,innerClip:EA,intersect:RA,outerClip:AA,removeNotRelevantChains:jA,removeOldFaces:$A,restoreFaces:YA,subtract:TA,unify:function(t,e){let[n,o]=LA(t,e,1,!0);return n}}),HA=RegExp(\"T.F..FFF.|T.F...F..\"),GA=RegExp(\"T........|.T.......|...T.....|....T....\"),UA=RegExp(\"FT.......|F..T.....|F...T....\"),ZA=RegExp(\"T.F..F...\"),qA=RegExp(\"T.F..F...|.TF..F...|..FT.F...|..F.TF...\"),JA=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=\u003et instanceof Array\u0026\u0026t.length\u003e0?\"T\":t instanceof Array\u0026\u00260===t.length?\"F\":\"*\").join(\"\")}equal(){return HA.test(this.toString())}intersect(){return GA.test(this.toString())}touch(){return UA.test(this.toString())}inside(){return ZA.test(this.toString())}covered(){return qA.test(this.toString())}};function KA(t,e){let n,o=new ME.Ray(e),i=new ME.Line(o.pt,o.norm);const r=new ME.Box(o.box.xmin-ME.DP_TOL,o.box.ymin-ME.DP_TOL,o.box.xmax+ME.DP_TOL,o.box.ymax+ME.DP_TOL);if(t.box.not_intersect(r))return ME.OUTSIDE;let s=t.edges.search(r);if(0===s.length)return ME.OUTSIDE;for(let t of s)if(t.shape.contains(e))return ME.BOUNDARY;let a=[...t.faces],c=[];for(let t of s)for(let n of o.intersect(t.shape)){if(n.equalTo(e))return ME.BOUNDARY;c.push({pt:n,edge:t,face_index:a.indexOf(t.face)})}c.sort((t,e)=\u003ePE(t.pt.x,e.pt.x)?-1:CE(t.pt.x,e.pt.x)?1:t.face_index\u003ce.face_index?-1:t.face_index\u003ee.face_index?1:t.edge.arc_length\u003ce.edge.arc_length?-1:t.edge.arc_length\u003ee.edge.arc_length?1:0);let l=0;for(let t=0;t\u003cc.length;t++){let e=c[t];if(e.pt.equalTo(e.edge.shape.start)){if(t\u003e0\u0026\u0026e.pt.equalTo(c[t-1].pt)\u0026\u0026e.face_index===c[t-1].face_index\u0026\u0026e.edge.prev===c[t-1].edge)continue;let n=e.edge.prev;for(;SE(n.length);)n=n.prev;let o=n.shape.tangentInEnd(),r=e.pt.translate(o),s=e.edge.shape.tangentInStart(),a=e.pt.translate(s),d=r.leftTo(i),h=a.leftTo(i);(d\u0026\u0026!h||!d\u0026\u0026h)\u0026\u0026l++}else if(e.pt.equalTo(e.edge.shape.end)){if(t\u003e0\u0026\u0026e.pt.equalTo(c[t-1].pt)\u0026\u0026e.face_index===c[t-1].face_index\u0026\u0026e.edge.next===c[t-1].edge)continue;let n=e.edge.next;for(;SE(n.length);)n=n.next;let o=n.shape.tangentInStart(),r=e.pt.translate(o),s=e.edge.shape.tangentInEnd(),a=e.pt.translate(s),d=r.leftTo(i),h=a.leftTo(i);(d\u0026\u0026!h||!d\u0026\u0026h)\u0026\u0026l++}else if(e.edge.shape instanceof ME.Segment)l++;else{let t=e.edge.shape.box;IE(e.pt.y,t.ymin)||IE(e.pt.y,t.ymax)||l++}}return n=l%2==1?1:0,n}function QA(t,e){return oO(t,e).intersect()}function tO(t,e){return oO(t,e).inside()}function eO(t,e){return oO(t,e).covered()}function nO(t,e){return eO(e,t)}function oO(t,e){return t instanceof ME.Line\u0026\u0026e instanceof ME.Line?function(t,e){let n=new JA,o=AE(t,e);0===o.length?t.contains(e.pt)\u0026\u0026e.contains(t.pt)?(n.I2I=[t],n.I2E=[],n.E2I=[]):(n.I2I=[],n.I2E=[t],n.E2I=[e]):(n.I2I=o,n.I2E=t.split(o),n.E2I=e.split(o));return n}(t,e):t instanceof ME.Line\u0026\u0026e instanceof ME.Circle?function(t,e){let n=new JA,o=OE(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new dA([t]),r=t.sortPoints(o);i.split(r);let s=i.toShapes();n.I2I=[s[1]],n.I2B=r,n.I2E=[s[0],s[2]],n.E2I=new ME.Polygon([e.toArc()]).cutWithLine(t)}return n}(t,e):t instanceof ME.Line\u0026\u0026e instanceof ME.Box?function(t,e){let n=new JA,o=kE(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new dA([t]),r=t.sortPoints(o);i.split(r);let s=i.toShapes();e.toSegments().some(t=\u003et.contains(o[0])\u0026\u0026t.contains(o[1]))?(n.I2I=[],n.I2B=[s[1]],n.I2E=[s[0],s[2]],n.E2I=[e]):(n.I2I=[s[1]],n.I2B=r,n.I2E=[s[0],s[2]],n.E2I=new ME.Polygon(e.toSegments()).cutWithLine(t))}return n}(t,e):t instanceof ME.Line\u0026\u0026e instanceof ME.Polygon?function(t,e){let n=new JA,o=JE(t,e),i=new dA([t]),r=o.length\u003e0?o.slice():t.sortPoints(o);return i.split(r),[...i].forEach(t=\u003et.setInclusion(e)),n.I2I=[...i].filter(t=\u003et.bv===ME.INSIDE).map(t=\u003et.shape),n.I2B=[...i].slice(1).map(t=\u003et.bv===ME.BOUNDARY?t.shape:t.shape.start),n.I2E=[...i].filter(t=\u003et.bv===ME.OUTSIDE).map(t=\u003et.shape),n.E2I=e.cutWithLine(t),n}(t,e):(t instanceof ME.Segment||t instanceof ME.Arc)\u0026\u0026e instanceof ME.Polygon?iO(t,e):(t instanceof ME.Segment||t instanceof ME.Arc)\u0026\u0026(e instanceof ME.Circle||e instanceof ME.Box)?iO(t,new ME.Polygon(e)):t instanceof ME.Polygon\u0026\u0026e instanceof ME.Polygon?rO(t,e):(t instanceof ME.Circle||t instanceof ME.Box)\u0026\u0026(e instanceof ME.Circle||e instanceof ME.Box)?rO(new ME.Polygon(t),new ME.Polygon(e)):(t instanceof ME.Circle||t instanceof ME.Box)\u0026\u0026e instanceof ME.Polygon?rO(new ME.Polygon(t),e):t instanceof ME.Polygon\u0026\u0026(e instanceof ME.Circle||e instanceof ME.Box)?rO(t,new ME.Polygon(e)):void 0}function iO(t,e){let n=new JA,o=function(t,e){return t instanceof ME.Line?JE(t,e):t instanceof ME.Segment?ZE(t,e):t instanceof ME.Arc?qE(t,e):[]}(t,e),i=o.length\u003e0?o.slice():t.sortPoints(o),r=new dA([t]);r.split(i),[...r].forEach(t=\u003et.setInclusion(e)),n.I2I=[...r].filter(t=\u003et.bv===ME.INSIDE).map(t=\u003et.shape),n.I2B=[...r].slice(1).map(t=\u003et.bv===ME.BOUNDARY?t.shape:t.shape.start),n.I2E=[...r].filter(t=\u003et.bv===ME.OUTSIDE).map(t=\u003et.shape),n.B2I=[],n.B2B=[],n.B2E=[];for(let o of[t.start,t.end])switch(KA(e,o)){case ME.INSIDE:n.B2I.push(o);break;case ME.BOUNDARY:n.B2B.push(o);break;case ME.OUTSIDE:n.B2E.push(o)}return n}function rO(t,e){let n=new JA,[o,i]=OA(t,e),r=RA(t,e),s=TA(t,e),a=TA(e,t),[c,l]=EA(t,e),d=AA(t,e),h=AA(e,t);return n.I2I=r.isEmpty()?[]:[r],n.I2B=l,n.I2E=s.isEmpty()?[]:[s],n.B2I=c,n.B2B=o,n.B2E=d,n.E2I=a.isEmpty()?[]:[a],n.E2B=h,n}var sO=Object.freeze({__proto__:null,contain:function(t,e){return tO(e,t)},cover:nO,covered:eO,disjoint:function(t,e){return!QA(t,e)},equal:function(t,e){return oO(t,e).equal()},inside:tO,intersect:QA,relate:oO,touch:function(t,e){return oO(t,e).touch()}}),aO=class t{constructor(t=1,e=0,n=0,o=1,i=0,r=0){this.a=t,this.b=e,this.c=n,this.d=o,this.tx=i,this.ty=r}fromMatrix3x3(e){const[n,o,i]=e[0],[r,s,a]=e[1];return new t(n,r,o,s,i,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,o;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 NE.ILLEGAL_PARAMETERS;n=e[0],o=e[1]}else n=e[0].x,o=e[0].y;return this.multiply(new t(1,0,0,1,n,o))}rotate(e,n=0,o=0){let i=Math.cos(e),r=Math.sin(e);return this.translate(n,o).multiply(new t(i,r,-r,i,0,0)).translate(-n,-o)}scale(e,n){return this.multiply(new t(e,0,0,n,0,0))}equalTo(t){return!!ME.Utils.EQ(this.tx,t.tx)\u0026\u0026(!!ME.Utils.EQ(this.ty,t.ty)\u0026\u0026(!!ME.Utils.EQ(this.a,t.a)\u0026\u0026(!!ME.Utils.EQ(this.b,t.b)\u0026\u0026(!!ME.Utils.EQ(this.c,t.c)\u0026\u0026!!ME.Utils.EQ(this.d,t.d)))))}};ME.Matrix=aO;ME.matrix=(...t)=\u003enew ME.Matrix(...t);var cO=class{constructor(t,e){this.low=t,this.high=e}get max(){return this.clone()}less_than(t){return this.low\u003ct.low||this.low===t.low\u0026\u0026this.high\u003ct.high}equal_to(t){return this.low===t.low\u0026\u0026this.high===t.high}intersect(t){return!this.not_intersect(t)}not_intersect(t){return this.high\u003ct.low||t.high\u003cthis.low}merge(t){const e=void 0===this.low?t.low:this.low\u003ct.low?this.low:t.low,n=void 0===this.high?t.high:this.high\u003et.high?this.high:t.high,o=this.clone();return o.low=e,o.high=n,o}output(){return[this.low,this.high]}comparable_less_than(t,e){return t\u003ce}},lO=class t extends cO{clone(){return new t(this.low,this.high)}},dO=class{constructor(t,e,n=null,o=null,i=null,r=0){if(this.left=n,this.right=o,this.parent=i,this.color=r,this.item={key:void 0,values:[]},void 0!==e\u0026\u0026this.item.values.push(e),void 0!==t)if(Array.isArray(t)){const[e,n]=t;if(!Number.isNaN(e)\u0026\u0026!Number.isNaN(n)){let t=e,o=n;t\u003eo\u0026\u0026([t,o]=[o,t]),this.item.key=new lO(t,o)}}else this.item.key=t;this.max=this.item.key?this.item.key.max:void 0}isNil(){return void 0===this.item.key\u0026\u00260===this.item.values.length\u0026\u0026null===this.left\u0026\u0026null===this.right\u0026\u00260===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\u0026\u0026n\u0026\u0026e.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\u0026\u0026this.right.max\u0026\u0026(this.max=this.max?this.max.merge(this.right.max):this.right.max),this.left\u0026\u0026this.left.max\u0026\u0026(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(),o=t.requireKey();return n.comparable_less_than(e,o.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(),o=t.requireKey();return n.comparable_less_than(o.high,e)}},hO=class t{constructor(){this.root=null,this.nil_node=new dO}get size(){let t=0;return this.tree_walk(this.root,e=\u003et+=e.item.values.length),t}get keys(){const t=[];return this.tree_walk(this.root,e=\u003et.push(e.item.key.output())),t}get values(){const t=[];return this.tree_walk(this.root,e=\u003e{for(const n of e.item.values)t.push(n)}),t}get items(){const t=[];return this.tree_walk(this.root,e=\u003e{const n=e.item.key.output();for(const o of e.item.values)t.push({key:n,value:o})}),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 dO(t));if(n)return n.item.values.push(e),n;const o=new dO(t,e,this.nil_node,this.nil_node,null,1);return this.tree_insert(o),this.recalc_max(o),o}exist(t,e=t){const n=this.tree_search(this.root,new dO(t));return!!n\u0026\u0026(arguments.length\u003c2||e===t||n.item.values.some(t=\u003et\u0026\u0026t.equal_to?t.equal_to(e):t===e))}remove(t,e=t){const n=this.tree_search(this.root,new dO(t));if(!n)return;if(arguments.length\u003c2)return this.tree_delete(n),n;const o=n.item.values.findIndex(t=\u003et\u0026\u0026t.equal_to?t.equal_to(e):t===e);return o\u003e=0?(n.item.values.splice(o,1),0===n.item.values.length\u0026\u0026this.tree_delete(n),n):void 0}search(t,e=(t,e)=\u003et===e?e.output():t){const n=new dO(t),o=[];this.tree_search_interval(this.root,n,o);const i=[];for(const t of o)for(const n of t.item.values)i.push(e(n,t.item.key));return i}intersect_any(t){const e=new dO(t);return this.tree_find_any_interval(this.root,e)}forEach(t){this.tree_walk(this.root,e=\u003e{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=\u003e{for(const o of t.item.values)n.insert(t.item.key,e(o,t.item.key))}),n}*iterate(t,e=(t,e)=\u003et===e?e.output():t){let n=null;for(t?n=this.tree_search_nearest_forward(this.root,new dO(t)):this.root\u0026\u0026(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\u0026\u00261===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\u0026\u0026(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\u0026\u0026(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\u0026\u0026(t.copy_data(e),t.update_max(),this.recalc_max(t)),0===e.color\u0026\u0026this.delete_fixup(n)}delete_fixup(t){let e,n=t;for(;n!==this.root\u0026\u0026null!=n.parent\u0026\u00260===n.color;)n===n.parent.left?(e=n.parent.right,1===e.color\u0026\u0026(e.color=0,n.parent.color=1,this.rotate_left(n.parent),e=n.parent.right),0===e.left.color\u0026\u00260===e.right.color?(e.color=1,n=n.parent):(0===e.right.color\u0026\u0026(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\u0026\u0026(e.color=0,n.parent.color=1,this.rotate_right(n.parent),e=n.parent.left),0===e.left.color\u0026\u00260===e.right.color?(e.color=1,n=n.parent):(0===e.left.color\u0026\u0026(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\u0026\u0026t!==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,o=t;for(;o\u0026\u0026o!==this.nil_node;)o.less_than(e)?o.intersect(e)?(n=o,o=o.left):o=o.right:(n\u0026\u0026!o.less_than(n)||(n=o),o=o.left);return n||null}tree_search_interval(t,e,n){null!=t\u0026\u0026t!==this.nil_node\u0026\u0026(t.left===this.nil_node||t.not_intersect_left_subtree(e)||this.tree_search_interval(t.left,e,n),t.intersect(e)\u0026\u0026n.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\u0026\u0026t!==this.nil_node\u0026\u0026(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\u0026\u0026e.left!==this.nil_node;)e=e.left;return e}local_maximum(t){let e=t;for(;null!=e.right\u0026\u0026e.right!==this.nil_node;)e=e.right;return e}tree_successor(t){let e,n,o;if(t.right!==this.nil_node)e=this.local_minimum(t.right);else{for(n=t,o=t.parent;null!=o\u0026\u0026o.right===n;)n=o,o=o.parent;e=o}return e}rotate_left(t){const e=t.right;t.right=e.left,e.left!==this.nil_node\u0026\u0026(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\u0026\u0026t!==this.nil_node\u0026\u0026t.update_max(),null!=e\u0026\u0026e!==this.nil_node\u0026\u0026e.update_max()}rotate_right(t){const e=t.left;t.left=e.right,e.right!==this.nil_node\u0026\u0026(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\u0026\u0026t!==this.nil_node\u0026\u0026t.update_max(),null!=e\u0026\u0026e!==this.nil_node\u0026\u0026e.update_max()}tree_walk(t,e){null!=t\u0026\u0026t!==this.nil_node\u0026\u0026(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\u0026\u0026(0===e.left.color\u0026\u00260===e.right.color||(t=!1))}),t}testBlackHeightProperty(t){let e=0,n=0,o=0;if(0===t.color\u0026\u0026e++,n=t.left!==this.nil_node?this.testBlackHeightProperty(t.left):1,o=t.right!==this.nil_node?this.testBlackHeightProperty(t.right):1,n!==o)throw new Error(\"Red-black height property violated\");return e+=n,e}},uO=class extends Set{constructor(t){super(t),this.index=new hO,this.forEach(t=\u003ethis.index.insert(t))}add(t){let e=this.size;const{key:n,value:o}=t,i=n||t.box,r=o||t;return super.add(r),this.size\u003ee\u0026\u0026this.index.insert(i,r),this}delete(t){const{key:e,value:n}=t,o=e||t.box,i=n||t;let r=super.delete(i);return r\u0026\u0026this.index.remove(o,i),r}clear(){super.clear(),this.index=new hO}search(t){return this.index.search(t)}hit(t){let e=new ME.Box(t.x-1,t.y-1,t.x+1,t.y+1);return this.index.search(e).filter(e=\u003et.on(e))}svg(){return[...this].reduce((t,e)=\u003et+e.svg(),\"\")}};ME.PlanarSet=uO;var pO=class{get name(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform((new aO).translate(...t))}rotate(t,e=new ME.Point){return this.transform((new aO).rotate(t,e.x,e.y))}scale(t,e){return this.transform((new aO).scale(t,e))}transform(...t){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}};ME.Point=class t extends pO{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length\u0026\u0026t[0]instanceof Array\u0026\u00262===t[0].length){let e=t[0];if(\"number\"==typeof e[0]\u0026\u0026\"number\"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"point\"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(2===t.length\u0026\u0026\"number\"==typeof t[0]\u0026\u0026\"number\"==typeof t[1])return this.x=t[0],void(this.y=t[1]);throw NE.ILLEGAL_PARAMETERS}}get box(){return new ME.Box(this.x,this.y,this.x,this.y)}clone(){return new ME.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return ME.Utils.EQ(this.x,t.x)\u0026\u0026ME.Utils.EQ(this.y,t.y)}lessThan(t){return!!ME.Utils.LT(this.y,t.y)||!(!ME.Utils.EQ(this.y,t.y)||!ME.Utils.LT(this.x,t.x))}transform(t){return new ME.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let e=new ME.Vector(this,t.pt);if(ME.Utils.EQ_0(e.cross(t.norm)))return t.pt.clone();let n=e.dot(t.norm),o=t.norm.multiply(n);return this.translate(o)}leftTo(t){let e=new ME.Vector(t.pt,this);return ME.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 ME.Segment(this,e)]}return e instanceof ME.Line?ME.Distance.point2line(this,e):e instanceof ME.Circle?ME.Distance.point2circle(this,e):e instanceof ME.Segment?ME.Distance.point2segment(this,e):e instanceof ME.Arc?ME.Distance.point2arc(this,e):e instanceof ME.Box?ME.Distance.point2polygon(this,new ME.Polygon(e)):e instanceof ME.Polygon?ME.Distance.point2polygon(this,e):e instanceof ME.PlanarSet?ME.Distance.shape2planarSet(this,e):e instanceof ME.Multiline?ME.Distance.shape2multiline(this,e):void 0}on(t){if(t instanceof ME.Point)return this.equalTo(t);if(t.contains\u0026\u0026t.contains instanceof Function)return t.contains(this);throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}get name(){return\"point\"}svg(t={}){const e=t.r??3;return`\\n\u003ccircle cx=\"${this.x}\" cy=\"${this.y}\" r=\"${e}\"\\n ${EE({fill:\"red\",...t})} /\u003e`}};var mO=(...t)=\u003enew ME.Point(...t);ME.point=mO;ME.Vector=class extends pO{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length\u0026\u0026t[0]instanceof Array\u0026\u00262===t[0].length){let e=t[0];if(\"number\"==typeof e[0]\u0026\u0026\"number\"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"vector\"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"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\u0026\u0026\"number\"==typeof n)return this.x=e,void(this.y=n);if(e instanceof ME.Point\u0026\u0026n instanceof ME.Point)return this.x=n.x-e.x,void(this.y=n.y-e.y)}throw NE.ILLEGAL_PARAMETERS}}clone(){return new ME.Vector(this.x,this.y)}get slope(){let t=Math.atan2(this.y,this.x);return t\u003c0\u0026\u0026(t=2*Math.PI+t),t}get length(){return Math.sqrt(this.dot(this))}isZeroLength(){return ME.Utils.EQ_0(this.length)}equalTo(t){return ME.Utils.EQ(this.x,t.x)\u0026\u0026ME.Utils.EQ(this.y,t.y)}multiply(t){return new ME.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 NE.ZERO_DIVISION;return new ME.Vector(this.x/this.length,this.y/this.length)}rotate(t,e=new ME.Point){if(0===e.x\u0026\u00260===e.y)return this.transform((new aO).rotate(t));throw NE.OPERATION_IS_NOT_SUPPORTED}transform(t){return new ME.Vector(t.transform([this.x,this.y]))}rotate90CCW(){return new ME.Vector(-this.y,this.x)}rotate90CW(){return new ME.Vector(this.y,-this.x)}invert(){return new ME.Vector(-this.x,-this.y)}add(t){return new ME.Vector(this.x+t.x,this.y+t.y)}subtract(t){return new ME.Vector(this.x-t.x,this.y-t.y)}angleTo(t){let e=this.normalize(),n=t.normalize(),o=Math.atan2(e.cross(n),e.dot(n));return o\u003c0\u0026\u0026(o+=2*Math.PI),o}projectionOn(t){let e=t.normalize(),n=this.dot(e);return e.multiply(n)}get name(){return\"vector\"}};var gO=(...t)=\u003enew ME.Vector(...t);ME.vector=gO;ME.Segment=class t extends pO{constructor(...t){if(super(),this.ps=new ME.Point,this.pe=new ME.Point,0!==t.length){if(1===t.length\u0026\u0026t[0]instanceof Array\u0026\u00264===t[0].length){let e=t[0];return this.ps=new ME.Point(e[0],e[1]),void(this.pe=new ME.Point(e[2],e[3]))}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"segment\"===t[0].name){let{ps:e,pe:n}=t[0];return this.ps=new ME.Point(e.x,e.y),void(this.pe=new ME.Point(n.x,n.y))}if(!(1===t.length\u0026\u0026t[0]instanceof ME.Point)){if(2===t.length\u0026\u0026t[0]instanceof ME.Point\u0026\u0026t[1]instanceof ME.Point)return this.ps=t[0].clone(),void(this.pe=t[1].clone());if(4===t.length)return this.ps=new ME.Point(t[0],t[1]),void(this.pe=new ME.Point(t[2],t[3]));throw NE.ILLEGAL_PARAMETERS}this.ps=t[0].clone()}}clone(){return new ME.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 ME.Vector(this.start,this.end).slope}get box(){return new ME.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)\u0026\u0026this.pe.equalTo(t.pe)}contains(t){return ME.Utils.EQ_0(this.distanceToPoint(t))}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?DE(this,t):t instanceof ME.Ray?oA(t,this):t instanceof ME.Segment?zE(this,t):t instanceof ME.Circle?jE(this,t):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=zE(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?$E(this,t):t instanceof ME.Polygon?ZE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2segment(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.segment2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.segment2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2segment(this,t);return[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.segment2arc(this,t);return[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline)return ME.Distance.shape2multiline(this,t)}tangentInStart(){return new ME.Vector(this.start,this.end).normalize()}tangentInEnd(){return new ME.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 ME.Segment(this.start,t),new ME.Segment(t,this.end)]}middle(){return new ME.Point((this.start.x+this.end.x)/2,(this.start.y+this.end.y)/2)}pointAtLength(t){if(t\u003ethis.length||t\u003c0)return null;if(0==t)return this.start;if(t==this.length)return this.end;let e=t/this.length;return new ME.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]=ME.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 ME.Matrix){return new t(this.ps.transform(e),this.pe.transform(e))}isZeroLength(){return this.ps.equalTo(this.pe)}sortPoints(t){return new ME.Line(this.start,this.end).sortPoints(t)}get name(){return\"segment\"}svg(t={}){return`\\n\u003cline x1=\"${this.start.x}\" y1=\"${this.start.y}\" x2=\"${this.end.x}\" y2=\"${this.end.y}\" ${EE(t)} /\u003e`}};var fO=(...t)=\u003enew ME.Segment(...t);ME.segment=fO;var{vector:yO}=ME;ME.Line=class t extends pO{constructor(...e){if(super(),this.pt=new ME.Point,this.norm=new ME.Vector(0,1),0!==e.length){if(1===e.length\u0026\u0026e[0]instanceof Object\u0026\u0026\"line\"===e[0].name){let{pt:t,norm:n}=e[0];return this.pt=new ME.Point(t),void(this.norm=new ME.Vector(n))}if(2===e.length){let n=e[0],o=e[1];if(n instanceof ME.Point\u0026\u0026o instanceof ME.Point)return this.pt=n,this.norm=t.points2norm(n,o),void(this.norm.dot(yO(this.pt.x,this.pt.y))\u003e=0\u0026\u0026this.norm.invert());if(n instanceof ME.Point\u0026\u0026o instanceof ME.Vector){if(ME.Utils.EQ_0(o.x)\u0026\u0026ME.Utils.EQ_0(o.y))throw NE.ILLEGAL_PARAMETERS;return this.pt=n.clone(),this.norm=o.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(yO(this.pt.x,this.pt.y))\u003e=0\u0026\u0026this.norm.invert())}if(n instanceof ME.Vector\u0026\u0026o instanceof ME.Point){if(ME.Utils.EQ_0(n.x)\u0026\u0026ME.Utils.EQ_0(n.y))throw NE.ILLEGAL_PARAMETERS;return this.pt=o.clone(),this.norm=n.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(yO(this.pt.x,this.pt.y))\u003e=0\u0026\u0026this.norm.invert())}}throw NE.ILLEGAL_PARAMETERS}}clone(){return new ME.Line(this.pt,this.norm)}get start(){}get end(){}get length(){return Number.POSITIVE_INFINITY}get box(){return new ME.Box(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)}get middle(){}get slope(){return new ME.Vector(this.norm.y,-this.norm.x).slope}get standard(){return[this.norm.x,this.norm.y,this.norm.dot(yO(this.pt.x,this.pt.y))]}parallelTo(t){return ME.Utils.EQ_0(this.norm.cross(t.norm))}incidentTo(t){return this.parallelTo(t)\u0026\u0026this.pt.on(t)}contains(t){if(this.pt.equalTo(t))return!0;let e=new ME.Vector(this.pt,t);return ME.Utils.EQ_0(this.norm.dot(e))}coord(t){return yO(t.x,t.y).cross(this.norm)}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?AE(this,t):t instanceof ME.Ray?sA(t,this):t instanceof ME.Circle?OE(this,t):t instanceof ME.Box?kE(this,t):t instanceof ME.Segment?DE(t,this):t instanceof ME.Arc?LE(this,t):t instanceof ME.Polygon?JE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.circle2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2line(t,this);return[e,n.reverse()]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2line(t,this);return[e,n.reverse()]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}}split(t){if(t instanceof ME.Point)return[new ME.Ray(t,this.norm),new ME.Ray(t,this.norm)];{let e=new ME.Multiline([this]),n=this.sortPoints(t);return e.split(n),e.toShapes()}}rotate(t,e=new ME.Point){return new ME.Line(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new ME.Line(this.pt.transform(t),this.norm.clone())}sortPoints(t){return t.slice().sort((t,e)=\u003ethis.coord(t)\u003cthis.coord(e)?-1:this.coord(t)\u003ethis.coord(e)?1:0)}get name(){return\"line\"}svg(t,e={}){let n=kE(this,t);if(0===n.length)return\"\";let o=n[0],i=2===n.length?n[1]:n.find(t=\u003e!t.equalTo(o));return void 0===i\u0026\u0026(i=o),new ME.Segment(o,i).svg(e)}static points2norm(t,e){if(t.equalTo(e))throw NE.ILLEGAL_PARAMETERS;return new ME.Vector(t,e).normalize().rotate90CCW()}};var _O=(...t)=\u003enew ME.Line(...t);ME.line=_O;ME.Circle=class extends pO{constructor(...t){if(super(),this.pc=new ME.Point,this.r=1,1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"circle\"===t[0].name){let{pc:e,r:n}=t[0];this.pc=new ME.Point(e),this.r=n}else{let[e,n]=[...t];e\u0026\u0026e instanceof ME.Point\u0026\u0026(this.pc=e.clone()),void 0!==n\u0026\u0026(this.r=n)}}clone(){return new ME.Circle(this.pc.clone(),this.r)}get center(){return this.pc}get box(){return new ME.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 ME.Point?ME.Utils.LE(t.distanceTo(this.center)[0],this.r):t instanceof ME.Segment?ME.Utils.LE(t.start.distanceTo(this.center)[0],this.r)\u0026\u0026ME.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof ME.Arc?0===this.intersect(t).length\u0026\u0026ME.Utils.LE(t.start.distanceTo(this.center)[0],this.r)\u0026\u0026ME.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof ME.Circle?0===this.intersect(t).length\u0026\u0026ME.Utils.LE(t.r,this.r)\u0026\u0026ME.Utils.LE(t.center.distanceTo(this.center)[0],this.r):void 0}toArc(t=!0){return new ME.Arc(this.center,this.r,Math.PI,-Math.PI,t)}scale(t,e){if(t!==e)throw NE.OPERATION_IS_NOT_SUPPORTED;if(0!==this.pc.x||0!==this.pc.y)throw NE.OPERATION_IS_NOT_SUPPORTED;return new ME.Circle(this.pc,this.r*t)}transform(t=new ME.Matrix){return new ME.Circle(this.pc.transform(t),this.r)}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?OE(t,this):t instanceof ME.Ray?rA(t,this):t instanceof ME.Segment?jE(t,this):t instanceof ME.Circle?YE(t,this):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=jE(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?VE(t,this):t instanceof ME.Polygon?KE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.circle2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.circle2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline){let[e,n]=ME.Distance.shape2multiline(this,t);return[e,n]}}get name(){return\"circle\"}svg(t={}){return`\\n\u003ccircle cx=\"${this.pc.x}\" cy=\"${this.pc.y}\" r=\"${this.r}\"\\n ${EE({fill:\"none\",...t})} /\u003e`}};ME.circle=(...t)=\u003enew ME.Circle(...t);ME.Arc=class extends pO{constructor(...t){if(super(),this.pc=new ME.Point,this.r=1,this.startAngle=0,this.endAngle=2*Math.PI,this.counterClockwise=!0,0!==t.length)if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"arc\"===t[0].name){let{pc:e,r:n,startAngle:o,endAngle:i,counterClockwise:r}=t[0];this.pc=new ME.Point(e.x,e.y),this.r=n,this.startAngle=o,this.endAngle=i,this.counterClockwise=r}else{let[e,n,o,i,r]=[...t];e\u0026\u0026e instanceof ME.Point\u0026\u0026(this.pc=e.clone()),void 0!==n\u0026\u0026(this.r=n),void 0!==o\u0026\u0026(this.startAngle=o),void 0!==i\u0026\u0026(this.endAngle=i),void 0!==r\u0026\u0026(this.counterClockwise=r)}}clone(){return new ME.Arc(this.pc.clone(),this.r,this.startAngle,this.endAngle,this.counterClockwise)}get sweep(){let t=this.startAngle,e=this.endAngle;if(ME.Utils.EQ(Math.abs(t-e),ME.PIx2))return ME.PIx2;Math.abs(t)\u003eME.PIx2\u0026\u0026(t-=Math.trunc(t/ME.PIx2)*ME.PIx2),t\u003c0\u0026\u0026(t+=ME.PIx2),Math.abs(e)\u003eME.PIx2\u0026\u0026(e-=Math.trunc(e/ME.PIx2)*ME.PIx2),e\u003c0\u0026\u0026(e+=ME.PIx2);let n=this.counterClockwise?e-t:t-e;return n\u003c0\u0026\u0026(n+=ME.PIx2),n}get start(){return new ME.Point(this.pc.x+this.r,this.pc.y).rotate(this.startAngle,this.pc)}get end(){return new ME.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)=\u003et.merge(e.start.box),new ME.Box);return t=t.merge(this.end.box),t}contains(t){if(!ME.Utils.EQ(this.pc.distanceTo(t)[0],this.r))return!1;if(t.equalTo(this.start))return!0;let e=new ME.Vector(this.pc,t).slope,n=new ME.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise);return ME.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 ME.Vector(this.pc,t).slope;return[new ME.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise),new ME.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 ME.Arc(this.pc,this.r,this.startAngle,t,this.counterClockwise).end}pointAtLength(t){if(t\u003ethis.length||t\u003c0)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 ME.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 ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?LE(t,this):t instanceof ME.Ray?iA(t,this):t instanceof ME.Circle?VE(this,t):t instanceof ME.Segment?$E(t,this):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=$E(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?XE(this,t):t instanceof ME.Polygon?qE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.arc2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.arc2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2arc(this,t);return[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline)return ME.Distance.shape2multiline(this,t)}breakToFunctional(){let t=[],e=[0,Math.PI/2,Math.PI,3*Math.PI/2],n=this.startAngle,o=this.endAngle;ME.Utils.EQ(Math.abs(n-o),ME.PIx2)\u0026\u0026(o=n),Math.abs(n)\u003eME.PIx2\u0026\u0026(n-=Math.trunc(n/ME.PIx2)*ME.PIx2),n\u003c0\u0026\u0026(n+=ME.PIx2),Math.abs(o)\u003eME.PIx2\u0026\u0026(o-=Math.trunc(o/ME.PIx2)*ME.PIx2),o\u003c0\u0026\u0026(o+=ME.PIx2);let i,r,s,a=n;this.counterClockwise?(r=Math.ceil(n/(Math.PI/2))%4,s=1):(r=Math.floor(n/(Math.PI/2))%4,s=-1);for(let o=0,c=r;o\u003c4;o++,c=(c+s+4)%4){if(i=e[c],i===a)continue;let o=this.counterClockwise?i-n:n-i;if(o\u003c0\u0026\u0026(o+=ME.PIx2),o\u003ethis.sweep)break;t.push(new ME.Arc(this.pc,this.r,a,i,this.counterClockwise)),a=i}return 0===t.length?(t.push(this),t):(i=o,a!==i\u0026\u0026t.push(new ME.Arc(this.pc,this.r,a,i,this.counterClockwise)),t)}tangentInStart(){let t=new ME.Vector(this.pc,this.start),e=this.counterClockwise?Math.PI/2:-Math.PI/2;return t.rotate(e).normalize()}tangentInEnd(){let t=new ME.Vector(this.pc,this.end),e=this.counterClockwise?-Math.PI/2:Math.PI/2;return t.rotate(e).normalize()}reverse(){return new ME.Arc(this.pc,this.r,this.endAngle,this.startAngle,!this.counterClockwise)}transform(t=new ME.Matrix){let e=this.start.transform(t),n=this.end.transform(t),o=this.pc.transform(t),i=this.counterClockwise;return t.a*t.d\u003c0\u0026\u0026(i=!i),ME.Arc.arcSE(o,e,n,i)}static arcSE(t,e,n,o){let{vector:i}=ME,r=i(t,e).slope,s=i(t,n).slope;ME.Utils.EQ(r,s)\u0026\u0026(s+=2*Math.PI,o=!0);let a=i(t,e).length;return new ME.Arc(t,a,r,s,o)}definiteIntegral(t=0){return this.breakToFunctional().reduce((e,n)=\u003ee+n.circularSegmentDefiniteIntegral(t),0)}circularSegmentDefiniteIntegral(t){let e=new ME.Segment(this.start,this.end).definiteIntegral(t),n=ME.Utils.EQ(this.sweep,ME.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}=ME;return t.slice().sort((t,n)=\u003e{let o=e(this.pc,t).slope,i=e(this.pc,n).slope;return o\u003ci?-1:o\u003ei?1:0})}get name(){return\"arc\"}svg(t={}){let e=this.sweep\u003c=Math.PI?\"0\":\"1\",n=this.counterClockwise?\"1\":\"0\";if(ME.Utils.EQ(this.sweep,2*Math.PI)){return new ME.Circle(this.pc,this.r).svg(t)}return`\\n\u003cpath d=\"M${this.start.x},${this.start.y}\\n A${this.r},${this.r} 0 ${e},${n} ${this.end.x},${this.end.y}\"\\n ${EE({fill:\"none\",...t})} /\u003e`}};ME.arc=(...t)=\u003enew ME.Arc(...t);ME.Box=class t extends pO{constructor(t=void 0,e=void 0,n=void 0,o=void 0){super(),this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}clone(){return new t(this.xmin,this.ymin,this.xmax,this.ymax)}get low(){return new ME.Point(this.xmin,this.ymin)}get high(){return new ME.Point(this.xmax,this.ymax)}get max(){return this.clone()}get center(){return new ME.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\u003ct.xmin||this.xmin\u003et.xmax||this.ymax\u003ct.ymin||this.ymin\u003et.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)\u0026\u0026this.high.equalTo(t.high)}output(){return this.clone()}comparable_less_than(t,e){return t.lessThan(e)}set(t,e,n,o){this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}extend(e){return e\u003c=0?this.clone():new t(this.xmin-e,this.ymin-e,this.xmax+e,this.ymax+e)}toPoints(){return[new ME.Point(this.xmin,this.ymin),new ME.Point(this.xmax,this.ymin),new ME.Point(this.xmax,this.ymax),new ME.Point(this.xmin,this.ymax)]}toSegments(){let t=this.toPoints();return[new ME.Segment(t[0],t[1]),new ME.Segment(t[1],t[2]),new ME.Segment(t[2],t[3]),new ME.Segment(t[3],t[0])]}rotate(t,e=new ME.Point){throw NE.OPERATION_IS_NOT_SUPPORTED}transform(e=new ME.Matrix){return this.toPoints().map(t=\u003et.transform(e)).reduce((t,e)=\u003et.merge(e.box),new t)}contains(t){return t instanceof ME.Point?t.x\u003e=this.xmin\u0026\u0026t.x\u003c=this.xmax\u0026\u0026t.y\u003e=this.ymin\u0026\u0026t.y\u003c=this.ymax:t instanceof ME.Segment?t.vertices.every(t=\u003ethis.contains(t)):t instanceof ME.Box?t.toSegments().every(t=\u003ethis.contains(t)):t instanceof ME.Circle?this.contains(t.box):t instanceof ME.Arc?t.vertices.every(t=\u003ethis.contains(t))\u0026\u0026this.toSegments().every(e=\u003e0===$E(e,t).length):!(t instanceof ME.Line||t instanceof ME.Ray)\u0026\u0026(t instanceof ME.Multiline?t.toShapes().every(t=\u003ethis.contains(t)):t instanceof ME.Polygon?this.contains(t.box):void 0)}distanceTo(t){const e=this.toSegments().map(e=\u003ee.distanceTo(t));let n=[Number.MAX_SAFE_INTEGER,null];return e.forEach(t=\u003e{t[0]\u003cn[0]\u0026\u0026(n=t)}),n}get name(){return\"box\"}svg(t={}){const e=this.xmax-this.xmin,n=this.ymax-this.ymin;return`\\n\u003crect x=\"${this.xmin}\" y=\"${this.ymin}\" width=\"${e}\" height=\"${n}\"\\n ${EE({fill:\"none\",...t})} /\u003e`}};ME.box=(...t)=\u003enew ME.Box(...t);ME.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 ME.Segment}get isArc(){return this.shape instanceof ME.Arc}get isLine(){return this.shape instanceof ME.Line}get isRay(){return this.shape instanceof ME.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 ME.Line||this.shape instanceof ME.Ray)return this.bv=ME.OUTSIDE,this.bv;if(void 0===this.bvStart\u0026\u0026(this.bvStart=KA(t,this.start)),void 0===this.bvEnd\u0026\u0026(this.bvEnd=KA(t,this.end)),this.bvStart===ME.OUTSIDE||this.bvEnd==ME.OUTSIDE)this.bv=ME.OUTSIDE;else if(this.bvStart===ME.INSIDE||this.bvEnd==ME.INSIDE)this.bv=ME.INSIDE;else{let e=KA(t,this.middle());this.bv=e}return this.bv}setOverlap(t){let e,n=this.shape,o=t.shape;n instanceof ME.Segment\u0026\u0026o instanceof ME.Segment?n.start.equalTo(o.start)\u0026\u0026n.end.equalTo(o.end)?e=ME.OVERLAP_SAME:n.start.equalTo(o.end)\u0026\u0026n.end.equalTo(o.start)\u0026\u0026(e=ME.OVERLAP_OPPOSITE):(n instanceof ME.Arc\u0026\u0026o instanceof ME.Arc||n instanceof ME.Segment\u0026\u0026o instanceof ME.Arc||n instanceof ME.Arc\u0026\u0026o instanceof ME.Segment)\u0026\u0026(n.start.equalTo(o.start)\u0026\u0026n.end.equalTo(o.end)\u0026\u0026n.middle().equalTo(o.middle())?e=ME.OVERLAP_SAME:n.start.equalTo(o.end)\u0026\u0026n.end.equalTo(o.start)\u0026\u0026n.middle().equalTo(o.middle())\u0026\u0026(e=ME.OVERLAP_OPPOSITE)),void 0===this.overlap\u0026\u0026(this.overlap=e),void 0===t.overlap\u0026\u0026(t.overlap=e)}svg(){if(this.shape instanceof ME.Segment)return` L${this.shape.end.x},${this.shape.end.y}`;if(this.shape instanceof ME.Arc){let t,e=this.shape,n=e.counterClockwise?\"1\":\"0\";if(ME.Utils.EQ(e.sweep,2*Math.PI)){let o=e.counterClockwise?1:-1,i=new ME.Arc(e.pc,e.r,e.startAngle,e.startAngle+o*Math.PI,e.counterClockwise),r=new ME.Arc(e.pc,e.r,e.startAngle+o*Math.PI,e.endAngle,e.counterClockwise);return t=\"0\",` A${i.r},${i.r} 0 ${t},${n} ${i.end.x},${i.end.y}\\n A${r.r},${r.r} 0 ${t},${n} ${r.end.x},${r.end.y}`}return t=e.sweep\u003c=Math.PI?\"0\":\"1\",` A${e.r},${e.r} 0 ${t},${n} ${e.end.x},${e.end.y}`}}toJSON(){return this.shape.toJSON()}};var bO=class extends wE{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:()=\u003e{let e=t||this.first,n=!this.first||!!t\u0026\u0026t===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}};ME.Face=class t extends bO{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 o=n[0];if(0===o.length)return;if(o.every(t=\u003et instanceof ME.Point)){let n=t.points2segments(o);this.shapes2face(e.edges,n)}else if(o.every(t=\u003et instanceof Array\u0026\u00262===t.length)){let n=o.map(t=\u003enew ME.Point(t[0],t[1])),i=t.points2segments(n);this.shapes2face(e.edges,i)}else if(o.every(t=\u003et instanceof ME.Segment||t instanceof ME.Arc))this.shapes2face(e.edges,o);else if(o.every(t=\u003e\"segment\"===t.name||\"arc\"===t.name)){let t=[];for(let e of o){let n;n=\"segment\"===e.name?new ME.Segment(e):new ME.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 ME.Circle)this.shapes2face(e.edges,[n[0].toArc(gE)]);else if(n[0]instanceof ME.Box){let t=n[0];this.shapes2face(e.edges,[new ME.Segment(new ME.Point(t.xmin,t.ymin),new ME.Point(t.xmax,t.ymin)),new ME.Segment(new ME.Point(t.xmax,t.ymin),new ME.Point(t.xmax,t.ymax)),new ME.Segment(new ME.Point(t.xmax,t.ymax),new ME.Point(t.xmin,t.ymax)),new ME.Segment(new ME.Point(t.xmin,t.ymax),new ME.Point(t.xmin,t.ymin))])}2===n.length\u0026\u0026n[0]instanceof ME.Edge\u0026\u0026n[1]instanceof ME.Edge\u0026\u0026(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=\u003et.shape.start.clone())}get shapes(){return this.edges.map(t=\u003et.shape.clone())}get box(){if(void 0===this._box){let t=new ME.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\u003ethis.perimeter||t\u003c0)return null;let e=null;for(let n of this)if(t\u003e=n.arc_length\u0026\u0026(n===this.last||t\u003cn.next.arc_length)){e=n.pointAtLength(t-n.arc_length);break}return e}static points2segments(t){let e=[];for(let n=0;n\u003ct.length;n++)t[n].equalTo(t[(n+1)%t.length])||e.push(new ME.Segment(t[n],t[(n+1)%t.length]));return e}shapes2face(t,e){for(let n of e){let e=new ME.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\u0026\u0026(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();ME.Utils.EQ_0(t)?this._orientation=fE.NOT_ORIENTABLE:ME.Utils.LT(t,0)?this._orientation=fE.CCW:this._orientation=fE.CW}return this._orientation}isSimple(e){return 0===t.getSelfIntersections(this,e,!0).length}static getSelfIntersections(t,e,n=!1){let o=[];for(let i of t){let r=e.search(i.box);for(let e of r){if(i===e)continue;if(e.face!==t)continue;if(i.shape instanceof ME.Segment\u0026\u0026e.shape instanceof ME.Segment\u0026\u0026(i.next===e||i.prev===e))continue;let r=i.shape.intersect(e.shape);for(let t of r)if((!t.equalTo(i.start)||!t.equalTo(e.end)||e!==i.prev)\u0026\u0026(!t.equalTo(i.end)||!t.equalTo(e.start)||e!==i.next)\u0026\u0026(o.push(t),n))break;if(o.length\u003e0\u0026\u0026n)break}if(o.length\u003e0\u0026\u0026n)break}return o}findEdgeByPoint(t){let e;for(let n of this)if(!t.equalTo(n.shape.start)\u0026\u0026(t.equalTo(n.shape.end)||n.shape.contains(t))){e=n;break}return e}toPolygon(){return new ME.Polygon(this.shapes)}toJSON(){return this.edges.map(t=\u003et.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}};ME.Ray=class t extends pO{constructor(...t){if(super(),this.pt=new ME.Point,this.norm=new ME.Vector(0,1),0!==t.length\u0026\u0026(t.length\u003e=1\u0026\u0026t[0]instanceof ME.Point\u0026\u0026(this.pt=t[0].clone()),1!==t.length)){if(!(2===t.length\u0026\u0026t[1]instanceof ME.Vector))throw NE.ILLEGAL_PARAMETERS;this.norm=t[1].clone()}}clone(){return new t(this.pt,this.norm)}get slope(){return new ME.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new ME.Box(t\u003eMath.PI/2\u0026\u0026t\u003c3*Math.PI/2?Number.NEGATIVE_INFINITY:this.pt.x,t\u003e=0\u0026\u0026t\u003c=Math.PI?this.pt.y:Number.NEGATIVE_INFINITY,t\u003e=Math.PI/2\u0026\u0026t\u003c=3*Math.PI/2?this.pt.x:Number.POSITIVE_INFINITY,t\u003e=Math.PI\u0026\u0026t\u003c=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 ME.Vector(this.pt,t);return ME.Utils.EQ_0(this.norm.dot(e))\u0026\u0026ME.Utils.GE(e.cross(this.norm),0)}coord(t){return gO(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new ME.Segment(this.pt,t),new ME.Ray(t,this.norm)]:[]}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Segment?oA(this,t):t instanceof ME.Arc?iA(this,t):t instanceof ME.Line?sA(this,t):t instanceof ME.Ray?(n=t,AE(nA(e=this),nA(n)).filter(t=\u003ee.contains(t)).filter(t=\u003en.contains(t))):t instanceof ME.Circle?rA(this,t):t instanceof ME.Box?(i=t,kE(nA(o=this),i).filter(t=\u003eo.contains(t))):t instanceof ME.Polygon?aA(this,t):t instanceof ME.Multiline?lA(this,t):void 0;var e,n,o,i}rotate(t,e=new ME.Point){return new ME.Ray(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new ME.Ray(this.pt.transform(t),this.norm.clone())}get name(){return\"ray\"}svg(t,e={}){let n=kE(new ME.Line(this.pt,this.norm),t);return n=n.filter(t=\u003ethis.contains(t)),0===n.length||2===n.length?\"\":new ME.Segment(this.pt,n[0]).svg(e)}};ME.ray=(...t)=\u003enew ME.Ray(...t);var xO=class t{constructor(){this.faces=new ME.PlanarSet,this.edges=new ME.PlanarSet;let t=[...arguments];if(1===t.length\u0026\u0026(t[0]instanceof Array\u0026\u0026t[0].length\u003e0||t[0]instanceof ME.Circle||t[0]instanceof ME.Box)){let e=t[0];if(t[0]instanceof Array\u0026\u0026t[0].every(t=\u003et instanceof Array))if(e.every(t=\u003et instanceof Array\u0026\u00262===t.length\u0026\u0026\"number\"==typeof t[0]\u0026\u0026\"number\"==typeof t[1]))this.faces.add(new ME.Face(this,e));else for(let t of e)if(t instanceof Array\u0026\u0026t[0]instanceof Array\u0026\u0026t[0].every(t=\u003et instanceof Array\u0026\u00262===t.length\u0026\u0026\"number\"==typeof t[0]\u0026\u0026\"number\"==typeof t[1]))for(let e of t)this.faces.add(new ME.Face(this,e));else this.faces.add(new ME.Face(this,t));else this.faces.add(new ME.Face(this,e))}}get box(){return[...this.faces].reduce((t,e)=\u003et.merge(e.box),new ME.Box)}get vertices(){return[...this.faces].flatMap(t=\u003et.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=\u003e[...t.faces].forEach(t=\u003en.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)=\u003et+e.signedArea(),0);return Math.abs(t)}addFace(...t){let e=new ME.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 o=e;o!==n.next;o=o.next)if(t.remove(o),this.edges.delete(o),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 o=new ME.Edge(n[0]),i=e.prev;return e.face.insert(o,i),this.edges.delete(e),this.edges.add(o),e.shape=n[1],this.edges.add(e),o}removeEndVertex(t){const e=t.next;e!==t\u0026\u0026(t.face.merge_with_next_edge(t),this.edges.delete(e))}cut(t){const e=this.splitToIslands().flatMap(e=\u003ee._cutSingleIsland(t)).filter(t=\u003et.isValid()\u0026\u0026!1===t.isEmpty());return this.createFromArray(e)}_cutSingleIsland(t){let e=this.clone();const n=t.clone();let o,i,r={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let t of n.edges)for(let n of e.edges){let e=QE(t,n);for(let o of e)hA(t,o,r.int_points1),hA(n,o,r.int_points2)}if(0===r.int_points1.length)return e;r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2),bA(n,r.int_points1_sorted),bA(e,r.int_points2_sorted),gA(r),r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2),fA(r.int_points1),yA(r.int_points1,e);for(let t of r.int_points1_sorted)t.edge_before\u0026\u0026t.edge_after\u0026\u0026t.edge_before.bv===t.edge_after.bv\u0026\u0026(r.int_points2[t.id]=-1,t.id=-1);if(r.int_points1=r.int_points1.filter(t=\u003et.id\u003e=0),r.int_points2=r.int_points2.filter(t=\u003et.id\u003e=0),r.int_points1.forEach((t,e)=\u003e{t.id=e}),r.int_points2.forEach((t,e)=\u003e{t.id=e}),0===r.int_points1.length)return e;r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2);for(let t=1;t\u003cr.int_points1_sorted.length;t++)if(i=r.int_points1_sorted[t],o=r.int_points1_sorted[t-1],i.edge_before\u0026\u00261===i.edge_before.bv){let t=o.edge_after,s=i.edge_before,a=n.getChain(t,s);xA(r.int_points2[o.id],r.int_points2[i.id],a),a.forEach(t=\u003ee.edges.add(t)),a=a.reverse().map(t=\u003enew ME.Edge(t.shape.reverse()));for(let t=0;t\u003ca.length-1;t++)a[t].next=a[t+1],a[t+1].prev=a[t];xA(r.int_points2[i.id],r.int_points2[o.id],a),a.forEach(t=\u003ee.edges.add(t))}return e.recreateFaces(),e}cutWithLine(t){let e=new dA([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)=\u003ee.area()-t.area());let e=[...t[0].faces][0].orientation(),n=t.filter(t=\u003e[...t.faces][0].orientation()===e);for(let o of t){let t=[...o.faces][0];if(t.orientation()!==e)for(let e of n)if(t.shapes.every(t=\u003ee.contains(t))){e.addFace(t.shapes);break}}return n}rearrange(){if(this.faces.size\u003c=1)return this.clone();const e=this.splitToIslands(),n=new t;return e.forEach(t=\u003e{t.faces.forEach(t=\u003en.addFace(t.shapes))}),n}orientation(){return this.isEmpty()?fE.NOT_ORIENTABLE:[...this.faces][0].orientation()}isOuter(t){return t.orientation()===this.orientation()}isMultiPolygon(){let t=0;return this.faces.forEach(e=\u003e{this.isOuter(e)\u0026\u0026t++}),t\u003e1}reverse(){for(let t of this.faces)t.reverse();return this}contains(t){if(t instanceof ME.Point){let e=KA(this,t);return 1===e||2===e}return nO(this,t)}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle||t instanceof ME.Line||t instanceof ME.Segment||t instanceof ME.Arc){let[e,n]=ME.Distance.shape2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Box)return this.distanceTo(new ME.Polygon(t));if(t instanceof ME.Polygon){let e,n,o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of this.edges){let r=o[0];[e,n]=ME.Distance.shape2planarSet(i.shape,t.edges,r),ME.Utils.LT(e,r)\u0026\u0026(o=[e,n])}return o}}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?JE(t,this):t instanceof ME.Ray?aA(t,this):t instanceof ME.Circle?KE(t,this):t instanceof ME.Segment?ZE(t,this):t instanceof ME.Arc?qE(t,this):t instanceof ME.Polygon?function(t,e){let n=[];if(t.isEmpty()||e.isEmpty())return n;if(t.box.not_intersect(e.box))return n;for(let o of t.edges)n=[...n,...tA(o,e)];return n}(t,this):t instanceof ME.Multiline?function(t,e){let n=[];if(e.isEmpty()||0===t.size)return n;for(let o of t)n=[...n,...tA(o,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=\u003et.translate(e)));return n}rotate(e=0,n=new ME.Point){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=\u003et.rotate(e,n)));return o}scale(e,n){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=\u003et.scale(e,n)));return o}transform(e=new ME.Matrix){let n=new t;for(let t of this.faces)n.addFace(t.shapes.map(t=\u003et.transform(e)));return n}toJSON(){return[...this.faces].map(t=\u003et.toJSON())}toArray(){return[...this.faces].map(t=\u003et.toPolygon())}dpath(){return[...this.faces].reduce((t,e)=\u003et+e.svg(),\"\")}svg(t={}){let e=`\\n\u003cpath ${EE({fillRule:\"evenodd\",fill:\"lightcyan\",...t})} d=\"`;for(let t of this.faces)e+=`\\n${t.svg()}`;return e+='\" \u003e\\n\u003c/path\u003e',e}};ME.Polygon=xO;ME.polygon=(...t)=\u003enew ME.Polygon(...t);var{Circle:vO,Line:SO,Point:IO,Vector:CO,Utils:PO}=ME;ME.Inversion=class t{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,e){const n=new CO(t.pc,e),o=t.r*t.r,i=n.dot(n);return PO.EQ_0(i)?new IO(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY):t.pc.translate(n.multiply(o/i))}static inverseCircle(t,e){const n=t.pc.distanceTo(e.pc)[0];if(PO.EQ(n,e.r)){let n=t.r*t.r/(2*e.r),o=new CO(t.pc,e.pc);o=o.normalize();let i=t.pc.translate(o.multiply(n));return new SO(i,o)}{let n=new CO(t.pc,e.pc),o=t.r*t.r/(n.dot(n)-e.r*e.r),i=t.pc.translate(n.multiply(o)),r=Math.abs(o)*e.r;return new vO(i,r)}}static inverseLine(t,e){const[n,o]=t.pc.distanceTo(e);if(PO.EQ_0(n))return e.clone();{let e=t.r*t.r/(2*n),i=new CO(t.pc,o.end);return i=i.multiply(e/n),new vO(t.pc.translate(i),e)}}inverse(e){return e instanceof IO?t.inversePoint(this.circle,e):e instanceof vO?t.inverseCircle(this.circle,e):e instanceof SO?t.inverseLine(this.circle,e):void 0}};ME.inversion=t=\u003enew ME.Inversion(t);ME.Distance=class t{static point2point(t,e){return t.distanceTo(e)}static point2line(t,e){let n=t.projectionOn(e);return[new ME.Vector(t,n).length,new ME.Segment(t,n)]}static point2circle(t,e){let[n,o]=t.distanceTo(e.center);if(ME.Utils.EQ_0(n))return[e.r,new ME.Segment(t,e.toArc().start)];{let o=Math.abs(n-e.r),i=new ME.Vector(e.pc,t).normalize().multiply(e.r),r=e.pc.translate(i);return[o,new ME.Segment(t,r)]}}static point2segment(e,n){if(n.start.equalTo(n.end))return t.point2point(e,n.start);let o,i,r=new ME.Vector(n.start,n.end),s=new ME.Vector(n.start,e),a=new ME.Vector(n.end,e),c=r.dot(s),l=-r.dot(a);if(ME.Utils.GE(c,0)\u0026\u0026ME.Utils.GE(l,0)){let t=n.tangentInStart();return o=Math.abs(t.cross(s)),i=n.start.translate(t.multiply(t.dot(s))),[o,new ME.Segment(e,i)]}return c\u003c0?e.distanceTo(n.start):e.distanceTo(n.end)}static point2arc(e,n){let o,i,r=new ME.Circle(n.pc,n.r),s=[];return[o,i]=t.point2circle(e,r),i.end.on(n)\u0026\u0026s.push(t.point2circle(e,r)),s.push(t.point2point(e,n.start)),s.push(t.point2point(e,n.end)),t.sort(s),s[0]}static point2edge(e,n){return n.shape instanceof ME.Segment?t.point2segment(e,n.shape):t.point2arc(e,n.shape)}static segment2line(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=[];return i.push(t.point2line(e.start,n)),i.push(t.point2line(e.end,n)),t.sort(i),i[0]}static segment2segment(e,n){let o=zE(e,n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i,r,s=[];return[i,r]=t.point2segment(n.start,e),s.push([i,r.reverse()]),[i,r]=t.point2segment(n.end,e),s.push([i,r.reverse()]),s.push(t.point2segment(e.start,n)),s.push(t.point2segment(e.end,n)),t.sort(s),s[0]}static segment2circle(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Line(e.ps,e.pe),[r,s]=t.point2line(n.center,i);if(ME.Utils.GE(r,n.r)\u0026\u0026s.end.on(e))return t.point2circle(s.end,n);{let[o,i]=t.point2circle(e.start,n),[r,s]=t.point2circle(e.end,n);return ME.Utils.LT(o,r)?[o,i]:[r,s]}}static segment2arc(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Line(e.ps,e.pe),r=new ME.Circle(n.pc,n.r),[s,a]=t.point2line(r.center,i);if(ME.Utils.GE(s,r.r)\u0026\u0026a.end.on(e)){let[e,o]=t.point2circle(a.end,r);if(o.end.on(n))return[e,o]}let c,l,d=[];return d.push(t.point2arc(e.start,n)),d.push(t.point2arc(e.end,n)),[c,l]=t.point2segment(n.start,e),d.push([c,l.reverse()]),[c,l]=t.point2segment(n.end,e),d.push([c,l.reverse()]),t.sort(d),d[0]}static circle2circle(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];if(e.center.equalTo(n.center)){let o=e.toArc(),i=n.toArc();return t.point2point(o.start,i.start)}{let o=new ME.Line(e.center,n.center),i=o.intersect(e),r=o.intersect(n),s=[];return s.push(t.point2point(i[0],r[0])),s.push(t.point2point(i[0],r[1])),s.push(t.point2point(i[1],r[0])),s.push(t.point2point(i[1],r[1])),t.sort(s),s[0]}}static circle2line(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let[i,r]=t.point2line(e.center,n),[s,a]=t.point2circle(r.end,e);return a=a.reverse(),[s,a]}static arc2line(e,n){let o=n.intersect(e);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),[r,s]=t.point2line(i.center,n);if(!ME.Utils.GE(r,i.r)){let o=[];return o.push(t.point2line(e.start,n)),o.push(t.point2line(e.end,n)),t.sort(o),o[0]}{let[n,o]=t.point2circle(s.end,i);if(o.end.on(e))return[n,o]}}static arc2circle(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),[r,s]=t.circle2circle(i,n);if(s.start.on(e))return[r,s];{let o=[];return o.push(t.point2circle(e.start,n)),o.push(t.point2circle(e.end,n)),t.sort(o),o[0]}}static arc2arc(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),r=new ME.Circle(n.center,n.r),[s,a]=t.circle2circle(i,r);if(a.start.on(e)\u0026\u0026a.end.on(n))return[s,a];{let o,i,r=[];return[o,i]=t.point2arc(e.start,n),i.end.on(n)\u0026\u0026r.push([o,i]),[o,i]=t.point2arc(e.end,n),i.end.on(n)\u0026\u0026r.push([o,i]),[o,i]=t.point2arc(n.start,e),i.end.on(e)\u0026\u0026r.push([o,i.reverse()]),[o,i]=t.point2arc(n.end,e),i.end.on(e)\u0026\u0026r.push([o,i.reverse()]),[o,i]=t.point2point(e.start,n.start),r.push([o,i]),[o,i]=t.point2point(e.start,n.end),r.push([o,i]),[o,i]=t.point2point(e.end,n.start),r.push([o,i]),[o,i]=t.point2point(e.end,n.end),r.push([o,i]),t.sort(r),r[0]}}static point2polygon(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of n.edges){let[n,r]=t.point2edge(e,i);ME.Utils.LT(n,o[0])\u0026\u0026(o=[n,r])}return o}static shape2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new ME.Segment];for(let o of e.edges){let[e,i]=t.distanceTo(o.shape);ME.Utils.LT(e,n[0])\u0026\u0026(n=[e,i])}return n}static polygon2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new ME.Segment];for(let o of t.edges)for(let t of e.edges){let[e,i]=o.shape.distanceTo(t.shape);ME.Utils.LT(e,n[0])\u0026\u0026(n=[e,i])}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)),o=Math.max(Math.max(t.ymin-e.ymax,0),Math.max(e.ymin-t.ymax,0)),i=n*n+o*o,r=t.merge(e),s=r.xmax-r.xmin,a=r.ymax-r.ymin;return[i,s*s+a*a]}static minmax_tree_process_level(e,n,o,i){let r,s;for(let a of n){[r,s]=t.box2box_minmax(e.box,a.item.key);for(let t of a.item.values)t instanceof ME.Edge?i.insert([r,s],t.shape):i.insert([r,s],t);ME.Utils.LT(s,o)\u0026\u0026(o=s)}if(0===n.length)return o;let a=[...n.map(t=\u003et.left.isNil()?void 0:t.left).filter(t=\u003evoid 0!==t),...n.map(t=\u003et.right.isNil()?void 0:t.right).filter(t=\u003evoid 0!==t)].filter(n=\u003e{let[i,r]=t.box2box_minmax(e.box,n.max);return ME.Utils.LE(i,o)});return o=t.minmax_tree_process_level(e,a,o,i)}static minmax_tree(e,n,o){let i=new hO,r=[n.index.root],s=o\u003cNumber.POSITIVE_INFINITY?o*o:Number.POSITIVE_INFINITY;return s=t.minmax_tree_process_level(e,r,s,i),i}static minmax_tree_calc_distance(e,n,o){let i,r;if(null!=n\u0026\u0026!n.isNil()){if([i,r]=t.minmax_tree_calc_distance(e,n.left,o),r)return[i,r];if(ME.Utils.LT(i[0],Math.sqrt(n.item.key.low)))return[i,!0];let[s,a]=t.distanceToArray(e,n.item.values);return ME.Utils.LT(s,i[0])\u0026\u0026(i=[s,a]),[i,r]=t.minmax_tree_calc_distance(e,n.right,i),[i,r]}return[o,!1]}static shape2planarSet(e,n,o=Number.POSITIVE_INFINITY){let i=[o,new ME.Segment],r=!1;if(n instanceof ME.PlanarSet){let s=t.minmax_tree(e,n,o);[i,r]=t.minmax_tree_calc_distance(e,s.root,i)}return i}static sort(t){t.sort((t,e)=\u003eME.Utils.LT(t[0],e[0])?-1:ME.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 ME.Segment];for(let o of e){let[e,i]=t.distanceTo(o);ME.Utils.LT(e,n[0])\u0026\u0026(n=[e,i])}return n}static shape2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of n){let[n,r]=t.distance(e,i.shape);ME.Utils.LT(n,o[0])\u0026\u0026(o=[n,r])}return o}static multiline2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of e)for(let e of n){let[n,r]=t.distance(i.shape,e.shape);ME.Utils.LT(n,o[0])\u0026\u0026(o=[n,r])}return o}};var{Multiline:MO,Point:NO,Segment:wO,Polygon:TO}=ME;function RO(t){return new NO(t.split(\" \").map(Number))}function EO(t){return t.split(\", \").map(RO)}function AO(t){const e=EO(t);let n=[];for(let t=0;t\u003ce.length-1;t++)n.push(new wO(e[t],e[t+1]));return new MO(n)}function OO(t){const e=t.replace(/\\(\\(/,\"\").replace(/\\)\\)$/,\"\").split(\"), (\"),n=new TO;let o;return e.forEach((t,e)=\u003e{let i=t.split(\", \").map(t=\u003enew NO(t.split(\" \").map(Number)));const r=n.addFace(i);0===e?o=r.orientation():r.orientation()===o\u0026\u0026r.reverse()}),n}function kO(t){if(t.startsWith(\"POLYGON\")){return OO(t.replace(/^POLYGON /,\"\"))}return function(t){const e=t.split(/\\)\\), \\(\\(/).map(t=\u003e\"((\"+t+\"))\").map(OO),n=new TO;return e.reduce((t,e)=\u003e[...t,...e?.faces],[]).forEach(t=\u003en.addFace([...t?.shapes])),n}(t.replace(/^MULTIPOLYGON \\(\\(\\((.*)\\)\\)\\)$/,\"$1\"))}function LO(t){return t.split(\"\\n\")?.every(t=\u003et.includes(\"POINT\"))}function DO(t){return t.split(\"\\n\")?.every(t=\u003et.includes(\"LINESTRING\"))}function zO(t,e,n,o){return Math.sqrt((n-t)**2+(o-e)**2)}ME.isWktString=function(t){return t.startsWith(\"POINT\")||LO(t)||t.startsWith(\"LINESTRING\")||DO(t)||t.startsWith(\"MULTILINESTRING\")||t.startsWith(\"POLYGON\")||t.startsWith(\"MULTIPOINT\")||t.startsWith(\"MULTIPOLYGON\")||t.startsWith(\"GEOMETRYCOLLECTION\")},ME.parseWKT=function t(e){if(e.startsWith(\"POINT\")){return RO(e.replace(/^POINT \\(/,\"\").replace(/\\)$/,\"\"))}if(e.startsWith(\"MULTIPOINT\")){return EO(e.replace(/^MULTIPOINT \\(/,\"\").replace(/\\)$/,\"\"))}if(e.startsWith(\"LINESTRING\")){return AO(e.replace(/^LINESTRING \\(/,\"\").replace(/\\)$/,\"\"))}if(e.startsWith(\"MULTILINESTRING\")){return function(t){return t.replace(/\\(\\(/,\"\").replace(/\\)\\)$/,\"\").split(\"), (\").map(AO)}(e.replace(/^MULTILINESTRING /,\"\"))}if(e.startsWith(\"POLYGON\")||e.startsWith(\"MULTIPOLYGON\"))return kO(e);if(e.startsWith(\"GEOMETRYCOLLECTION\")){const n=/(?\u003ctype\u003ePOINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \\((?:[^\\(\\)]|\\([^\\)]*\\))*\\)/g,o=e.match(n);o[0].startsWith(\"GEOMETRYCOLLECTION\")\u0026\u0026(o[0]=o[0].replace(\"GEOMETRYCOLLECTION (\",\"\"));return o.map(t).map(t=\u003et instanceof Array?t:[t]).reduce((t,e)=\u003e[...t,...e],[])}return LO(e)?function(t){return t.split(\"\\n\").map(t=\u003et.match(/\\(([^)]+)\\)/)[1]).map(RO)}(e):DO(e)?function(t){return t.split(\"\\n\").map(t=\u003et.match(/\\(([^)]+)\\)/)[1]).map(AO).reduce((t,e)=\u003e[...t,...e],[])}(e):[]},ME.BooleanOperations=WA,ME.Relations=sO;var FO=class{buckets;objectsById;getBounds;getId;CELL_SIZE=.4;constructor({objects:t,getBounds:e,getId:n,CELL_SIZE:o}){this.buckets=new Map,this.objectsById=new Map,this.getBounds=e,this.getId=n??(()=\u003ethis._getNextId()),this.CELL_SIZE=o??this.CELL_SIZE;for(const e of t)this.addObject(e)}_idCounter=0;_getNextId(){return\"\"+this._idCounter++}addObject(t){const e=this.getBounds(t),n=this.getId(t),o={...t,spatialIndexId:n};this.objectsById.set(n,o);const i=Math.floor(e.minX/this.CELL_SIZE),r=Math.floor(e.minY/this.CELL_SIZE),s=Math.floor(e.maxX/this.CELL_SIZE),a=Math.floor(e.maxY/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const n=`${t}x${e}`,i=this.buckets.get(n);i?i.push(o):this.buckets.set(n,[o])}}removeObject(t){const e=this.objectsById.get(t);if(!e)return!1;this.objectsById.delete(t);const n=this.getBounds(e),o=Math.floor(n.minX/this.CELL_SIZE),i=Math.floor(n.minY/this.CELL_SIZE),r=Math.floor(n.maxX/this.CELL_SIZE),s=Math.floor(n.maxY/this.CELL_SIZE);for(let e=o;e\u003c=r;e++)for(let n=i;n\u003c=s;n++){const o=`${e}x${n}`,i=this.buckets.get(o);if(i){const e=i.findIndex(e=\u003ee.spatialIndexId===t);-1!==e\u0026\u0026(i.splice(e,1),0===i.length\u0026\u0026this.buckets.delete(o))}}return!0}getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getObjectsInBounds(t,e=0){const n=[],o=new Set,i=Math.floor((t.minX-e)/this.CELL_SIZE),r=Math.floor((t.minY-e)/this.CELL_SIZE),s=Math.floor((t.maxX+e)/this.CELL_SIZE),a=Math.floor((t.maxY+e)/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const i=`${t}x${e}`,r=this.buckets.get(i)||[];for(const t of r){const e=t.spatialIndexId;o.has(e)||(o.add(e),n.push(t))}}return n}},BO=.1,jO=.1,$O=BO,YO=BO,XO=.005;function VO(t){return\"pcb_trace_segment\"===t.type||\"pcb_smtpad\"===t.type?[t.layer]:\"pcb_plated_hole\"===t.type?Array.isArray(t.layers)?t.layers:[...uw]:\"pcb_hole\"===t.type?[...uw]:\"pcb_via\"===t.type?Array.isArray(t.layers)?t.layers:[...uw]:\"pcb_keepout\"===t.type\u0026\u0026Array.isArray(t.layers)?t.layers:[]}var WO=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=e.minX,r=e.minY,s=e.maxX,a=e.maxY;if(n.x===o.x\u0026\u0026n.y===o.y){const t=Math.max(i,Math.min(s,n.x)),e=Math.max(r,Math.min(a,n.y));return t===n.x\u0026\u0026e===n.y?{x:n.x,y:n.y}:{x:t,y:e}}const c=o.x-n.x,l=o.y-n.y,d=0!==c?(i-n.x)/c:Number.NEGATIVE_INFINITY,h=0!==c?(s-n.x)/c:Number.POSITIVE_INFINITY,u=0!==l?(r-n.y)/l:Number.NEGATIVE_INFINITY,p=0!==l?(a-n.y)/l:Number.POSITIVE_INFINITY,m=Math.max(Math.min(d,h),Math.min(u,p)),g=Math.min(Math.max(d,h),Math.max(u,p));if(m\u003c=g\u0026\u0026g\u003e=0\u0026\u0026m\u003c=1){const t=Math.max(0,Math.min(1,m));return{x:n.x+t*c,y:n.y+t*l}}const f={x:Math.max(i,Math.min(s,n.x)),y:Math.max(r,Math.min(a,n.y))},y={x:Math.max(i,Math.min(s,o.x)),y:Math.max(r,Math.min(a,o.y))},_=(f.x-n.x)**2+(f.y-n.y)**2,b=(y.x-o.x)**2+(y.y-o.y)**2,x=[{start:{x:i,y:r},end:{x:s,y:r}},{start:{x:s,y:r},end:{x:s,y:a}},{start:{x:s,y:a},end:{x:i,y:a}},{start:{x:i,y:a},end:{x:i,y:r}}];let v=Math.min(_,b),S=_\u003c=b?f:y;const I=(t,e,n)=\u003eMath.max(e,Math.min(n,t));for(const t of x){const e={x:o.x-n.x,y:o.y-n.y},i={x:t.end.x-t.start.x,y:t.end.y-t.start.y},r={x:n.x-t.start.x,y:n.y-t.start.y},s=e.x*e.x+e.y*e.y,a=e.x*i.x+e.y*i.y,c=e.x*r.x+e.y*r.y,l=i.x*i.x+i.y*i.y,d=i.x*r.x+i.y*r.y,h=s*l-a*a;if(Math.abs(h)\u003c1e-10)continue;let u=(a*d-l*c)/h,p=(s*d-a*c)/h;u=I(u,0,1),p=I(p,0,1);const m={x:n.x+u*e.x,y:n.y+u*e.y},g={x:t.start.x+p*i.x,y:t.start.y+p*i.y},f=m.x-g.x,y=m.y-g.y,_=f*f+y*y;_\u003cv\u0026\u0026(v=_,S={x:(m.x+g.x)/2,y:(m.y+g.y)/2})}return S},HO=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i={x:e.x1,y:e.y1},r={x:e.x2,y:e.y2},s={x:o.x-n.x,y:o.y-n.y},a={x:r.x-i.x,y:r.y-i.y},c=s.x*s.x+s.y*s.y,l=a.x*a.x+a.y*a.y;if(0===c||0===l){if(0===c\u0026\u00260===l)return{x:(n.x+i.x)/2,y:(n.y+i.y)/2};if(0===c){const t=UO(((n.x-i.x)*a.x+(n.y-i.y)*a.y)/l,0,1),e={x:i.x+t*a.x,y:i.y+t*a.y};return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}}const t=UO(((i.x-n.x)*s.x+(i.y-n.y)*s.y)/c,0,1),e={x:n.x+t*s.x,y:n.y+t*s.y};return{x:(e.x+i.x)/2,y:(e.y+i.y)/2}}const d=n.x-i.x,h=n.y-i.y,u=s.x*s.x+s.y*s.y,p=s.x*a.x+s.y*a.y,m=s.x*d+s.y*h,g=a.x*a.x+a.y*a.y,f=a.x*d+a.y*h,y=u*g-p*p;if(y\u003c1e-10)return GO(n,o,i,r,s,a,c,l);let _=(p*f-g*m)/y,b=(u*f-p*m)/y;_=UO(_,0,1),b=UO(b,0,1),b=(_*p+f)/g,b=UO(b,0,1),_=(b*p-m)/u,_=UO(_,0,1);const x=n.x+_*s.x,v=n.y+_*s.y,S=i.x+b*a.x,I=i.y+b*a.y,C=x-S,P=v-I;Math.sqrt(C*C+P*P);return{x:(x+S)/2,y:(v+I)/2}},GO=(t,e,n,o,i,r,s,a)=\u003e{let c=((n.x-t.x)*i.x+(n.y-t.y)*i.y)/s;c=UO(c,0,1);const l={x:t.x+c*i.x,y:t.y+c*i.y};let d=((o.x-t.x)*i.x+(o.y-t.y)*i.y)/s;d=UO(d,0,1);const h={x:t.x+d*i.x,y:t.y+d*i.y};let u=((t.x-n.x)*r.x+(t.y-n.y)*r.y)/a;u=UO(u,0,1);const p={x:n.x+u*r.x,y:n.y+u*r.y};let m=((e.x-n.x)*r.x+(e.y-n.y)*r.y)/a;m=UO(m,0,1);const g={x:n.x+m*r.x,y:n.y+m*r.y},f=[{pointA:l,pointB:n,distance:Math.sqrt((l.x-n.x)**2+(l.y-n.y)**2)},{pointA:h,pointB:o,distance:Math.sqrt((h.x-o.x)**2+(h.y-o.y)**2)},{pointA:t,pointB:p,distance:Math.sqrt((t.x-p.x)**2+(t.y-p.y)**2)},{pointA:e,pointB:g,distance:Math.sqrt((e.x-g.x)**2+(e.y-g.y)**2)}].reduce((t,e)=\u003ee.distance\u003ct.distance?e:t);return{x:(f.pointA.x+f.pointB.x)/2,y:(f.pointA.y+f.pointB.y)/2}},UO=(t,e,n)=\u003eMath.max(e,Math.min(n,t)),ZO=t=\u003e\"pcb_trace_segment\"===t.type?{minX:Math.min(t.x1,t.x2),minY:Math.min(t.y1,t.y2),maxX:Math.max(t.x1,t.x2),maxY:Math.max(t.y1,t.y2)}:EM([t]);function qO(t){const e=new Set;for(const n of t.route)\"wire\"===n.route_type\u0026\u0026(n.start_pcb_port_id\u0026\u0026e.add(n.start_pcb_port_id),n.end_pcb_port_id\u0026\u0026e.add(n.end_pcb_port_id));return Array.from(e)}function JO(t){const e=new Set;for(const n of t)for(const t of qO(n))e.add(t);return Array.from(e)}var KO=t=\u003e{if(\"pcb_via\"===t.type)return t.outer_diameter/2;if(\"pcb_plated_hole\"===t.type\u0026\u0026\"circle\"===t.shape)return t.outer_diameter/2;if(\"pcb_hole\"===t.type\u0026\u0026\"circle\"===t.hole_shape)return t.hole_diameter/2;if(\"pcb_smtpad\"===t.type\u0026\u0026\"circle\"===t.shape)return t.radius;throw new Error(`Could not determine radius of element: ${JSON.stringify(t)}`)};function QO(t,{connMap:e,minClearance:n=.1}={}){const o=[];(t=\u003e{const e=t.filter(t=\u003e\"pcb_port\"===t.type),n=t.filter(t=\u003e\"pcb_smtpad\"===t.type),o=t.filter(t=\u003e\"pcb_trace\"===t.type);function i(t,o={}){const i=o.traceWidth||0,r=e.find(e=\u003ezO(e.x,e.y,t.x,t.y)\u003c.01);if(r)return r.pcb_port_id;if(o.isFirstOrLastPoint){const e=n.find(e=\u003e\"rect\"===e.shape?Math.abs(t.x-e.x)\u003ce.width/2+i/2\u0026\u0026Math.abs(t.y-e.y)\u003ce.height/2+i/2:\"circle\"===e.shape?zO(t.x,t.y,e.x,e.y)\u003ce.radius:void 0);if(e)return e.pcb_port_id??null}return null}for(const t of o)for(let e=0;e\u003ct.route.length;e++){const n=t.route[e],o=0===e||e===t.route.length-1;if(\"wire\"===n.route_type){if(!n.start_pcb_port_id\u0026\u00260===e){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.start_pcb_port_id=t)}if(!n.end_pcb_port_id\u0026\u0026e===t.route.length-1){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.end_pcb_port_id=t)}}}})(t),e??=v_(t);const i=vM(t).pcb_trace.list().flatMap(t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];\"wire\"===o.route_type\u0026\u0026(\"wire\"===i.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({type:\"pcb_trace_segment\",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:\"width\"in o?o.width:\"width\"in i?i.width:jO,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),r=vM(t).pcb_smtpad.list(),s=vM(t).pcb_plated_hole.list(),a=vM(t).pcb_hole.list(),c=vM(t).pcb_via.list(),l=vM(t).pcb_keepout.list(),d=[...i,...r,...s,...a,...c,...l],h=new FO({objects:d,getBounds:ZO}),u=e=\u003eNM(t,e),p=(t,e,n)=\u003en\u003c0?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,m=new Set;for(const t of i){const i=n,r=ZO(t),s=h.getObjectsInBounds(r,i+t.thickness/2);if(t.x1!==t.x2||t.y1!==t.y2)for(const r of s){if(!VO(r).includes(t.layer))continue;if(\"pcb_trace_segment\"===r.type){const i=r;if(t.layer!==i.layer)continue;if(e.areIdsConnected(t.pcb_trace_id,i.pcb_trace_id))continue;const s=Oe({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:i.x1,y:i.y1},{x:i.x2,y:i.y2})-t.thickness/2-i.thickness/2;if(s\u003en-XO)continue;const a=`overlap_${t.pcb_trace_id}_${i.pcb_trace_id}`,c=`overlap_${i.pcb_trace_id}_${t.pcb_trace_id}`;if(m.has(a))continue;if(m.has(c))continue;m.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:p(u(t.pcb_trace_id),u(i.pcb_trace_id),s),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[],center:HO(t,i),pcb_port_ids:JO([t._pcbTrace,i._pcbTrace])});continue}const s=AM(r);if(e.areIdsConnected(t.pcb_trace_id,\"pcb_trace_id\"in r?r.pcb_trace_id:s))continue;if(\"pcb_via\"===r.type||\"pcb_plated_hole\"===r.type\u0026\u0026\"circle\"===r.shape||\"pcb_hole\"===r.type||\"pcb_smtpad\"===r.type\u0026\u0026\"circle\"===r.shape){const e=KO(r),i=De({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:r.x,y:r.y,radius:e})-t.thickness/2;if(i\u003en-XO)continue;const a=`overlap_${t.pcb_trace_id}_${s}`;if(m.has(a))continue;m.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:p(u(t.pcb_trace_id),`${r.type} \"${u(AM(r))}\"`,i),pcb_trace_id:t.pcb_trace_id,center:WO(t,ZO(r)),source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...JO([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}const a=ke({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},ZO(r))-t.thickness/2;if(a+XO\u003ci){const e=`overlap_${t.pcb_trace_id}_${s}`;if(m.has(e))continue;m.add(e),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:p(u(t.pcb_trace_id),`${r.type} \"${u(AM(r))}\"`,a),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:e,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),center:WO(t,ZO(r)),pcb_port_ids:[...JO([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}}}return o}function tk(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function ek(t,e){return tk(t,e)\u003c=XO}function nk(t,{connMap:e,minClearance:n=$O}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];e??=v_(t);const i=[],r=new Set;for(let s=0;s\u003co.length;s++)for(let a=s+1;a\u003co.length;a++){const c=o[s],l=o[a];if(ek(c,l))continue;if(!e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=tk(c,l)-c.outer_diameter/2-l.outer_diameter/2;if(d+XO\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");r.has(h)||(r.add(h),i.push({type:\"pcb_via_clearance_error\",pcb_error_id:`same_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return i}function ok(t,{connMap:e,minClearance:n=YO}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];e??=v_(t);const i=[],r=new Set;for(let s=0;s\u003co.length;s++)for(let a=s+1;a\u003co.length;a++){const c=o[s],l=o[a];if(ek(c,l))continue;if(e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=tk(c,l)-c.outer_diameter/2-l.outer_diameter/2;if(d+XO\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");r.has(h)||(r.add(h),i.push({type:\"pcb_via_clearance_error\",pcb_error_id:`different_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} from different nets are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return i}var ik=t=\u003e({minSpacing:t,minClearance:t}),rk={traceClearance:.1,viaClearance:.1},sk=t=\u003e(t=\u003e\"layer\"in t)(t)?[t.layer]:t.layers;function ak(t,e,n){let o,i=Number.POSITIVE_INFINITY;for(const r of e){const e=n.get(r);if(!e)continue;const s=Math.hypot(e.x-t.x,e.y-t.y);s\u003ci\u0026\u0026(i=s,o=r)}return o??e[0]}function ck(t){const e=[],n=new Set,o=new Set,i=function(t){const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{x:t.x,y:t.y});return e}(t);for(const r of t.obstacles){const t=r.connectedTo,s=t.find(t=\u003et.startsWith(\"pcb_smtpad_\")),a=t.find(t=\u003et.startsWith(\"pcb_plated_hole_\")),c=t.filter(t=\u003et.startsWith(\"pcb_port_\")),l=ak(r.center,c,i);if(!s\u0026\u0026!a\u0026\u0026!l)continue;const d=r.layers;if(0===d.length)continue;const h=r.width,u=r.height,p=r.center.x,m=r.center.y,g=r.ccwRotationDegrees,f=\"number\"==typeof g\u0026\u0026Number.isFinite(g);if(d.length\u003e1){const t=a??`pcb_plated_hole_${p.toFixed(3)}_${m.toFixed(3)}`;if(o.has(t))continue;if(o.add(t),f){const n=Math.max(.5*Math.min(h,u),.1);e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"rotated_pill_hole_with_rect_pad\",hole_shape:\"rotated_pill\",pad_shape:\"rect\",hole_width:n,hole_height:n,hole_ccw_rotation:g,rect_pad_width:h,rect_pad_height:u,rect_ccw_rotation:g,hole_offset_x:0,hole_offset_y:0,x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}if(Math.abs(h-u)\u003c.001){e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circle\",outer_diameter:Math.max(h,u),hole_diameter:Math.max(.5*Math.min(h,u),.1),x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circular_hole_with_rect_pad\",hole_shape:\"circle\",hole_diameter:Math.max(.5*Math.min(h,u),.1),rect_pad_width:h,rect_pad_height:u,hole_offset_x:0,hole_offset_y:0,x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}const y=s??`pcb_smtpad_${p.toFixed(3)}_${m.toFixed(3)}`;n.has(y)||(n.add(y),f?e.push({type:\"pcb_smtpad\",pcb_smtpad_id:y,layer:d[0],shape:\"rotated_rect\",x:p,y:m,width:h,height:u,ccw_rotation:g,...l?{pcb_port_id:l}:{}}):e.push({type:\"pcb_smtpad\",pcb_smtpad_id:y,layer:d[0],shape:\"rect\",width:h,height:u,x:p,y:m,...l?{pcb_port_id:l}:{}}))}return e}function lk(t,e,n=.1,o=t.minViaDiameter??.3){const i=[];i.push(...function(t,e){const n=[];return t.connections.forEach(o=\u003e{const i=o.pointsToConnect.filter(t=\u003et.pcb_port_id).map(t=\u003et.pcb_port_id).filter(Boolean),r=o.netConnectionName||o.rootConnectionName||o.name,s=[],a=e.find(t=\u003e(t.connection_name??t.connectionName)===o.name);if(a){const e=t=\u003e\"route_type\"in t\u0026\u0026\"jumper\"===t.route_type?t.start:\"x\"in t\u0026\u0026\"y\"in t?{x:t.x,y:t.y}:{x:0,y:0},n=[e(a.route[0]),e(a.route[a.route.length-1])];for(const e of n)for(const n of t.obstacles)Be(e,n)\u003c=0\u0026\u0026s.push(n)}const c=n.find(t=\u003e\"source_trace\"===t.type\u0026\u0026t.source_trace_id===r);if(c){const t=c;t.connected_source_port_ids=[...new Set([...t.connected_source_port_ids,...i])]}else n.push({type:\"source_trace\",source_trace_id:r,connected_source_port_ids:i.concat(s.flatMap(t=\u003e[`obstacle_${t.center.x.toFixed(3)}_${t.center.y.toFixed(3)}_${t.layers.join(\".\")}`,...t.connectedTo])),connected_source_net_ids:[]})}),n}(t,e)),i.push(...function(t){const e=new Map;return t.connections.forEach(t=\u003e{t.pointsToConnect.forEach(t=\u003e{t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{type:\"pcb_port\",pcb_port_id:t.pcb_port_id,source_port_id:t.pcb_port_id,x:t.x,y:t.y,layers:sk(t)})})}),Array.from(e.values())}(t)),i.push(...ck(t)),i.push(...function(t,e,n=.3){const o=[],i=new Set;return t.length\u003e0\u0026\u0026(\"type\"in t[0]\u0026\u0026\"pcb_trace\"===t[0].type?t.forEach(t=\u003e{t.route.forEach(r=\u003e{if(\"via\"===r.route_type){const s=r.via_diameter??n,a=`${r.x},${r.y},${r.from_layer},${r.to_layer}`;i.has(a)||(o.push({type:\"pcb_via\",pcb_via_id:`via_${o.length}`,pcb_trace_id:t.pcb_trace_id,x:r.x,y:r.y,outer_diameter:s,hole_diameter:.5*s,layers:Wy(r,e)}),i.add(a))}})}):t.forEach((t,r)=\u003e{const s=`trace_${r}`,a=t.viaDiameter??n;for(let n=1;n\u003ct.route.length;n++){const r=t.route[n-1],c=t.route[n];if(r.z!==c.z\u0026\u0026Math.abs(r.x-c.x)\u003c.01\u0026\u0026Math.abs(r.y-c.y)\u003c.01){const t=Vy(r.z,e),n=Vy(c.z,e),l=`${c.x},${c.y},${t},${n}`;i.has(l)||(o.push({type:\"pcb_via\",pcb_via_id:`via_${o.length}`,pcb_trace_id:s,x:c.x,y:c.y,outer_diameter:a,hole_diameter:.5*a,layers:Wy({from_layer:t,to_layer:n},e)}),i.add(l))}}})),o}(e,t.layerCount,o));const r=new Map;return t.connections.forEach(t=\u003e{r.set(t.name,t.netConnectionName||t.rootConnectionName||t.name)}),e.length\u003e0\u0026\u0026(\"type\"in e[0]\u0026\u0026\"pcb_trace\"===e[0].type?e.forEach(t=\u003e{const e=t.connection_name;i.push(function(t,e){return{type:\"pcb_trace\",pcb_trace_id:t.pcb_trace_id,source_trace_id:e,route:t.route.map(t=\u003e\"wire\"===t.route_type?{route_type:\"wire\",x:t.x,y:t.y,width:t.width,layer:t.layer,start_pcb_port_id:t.start_pcb_port_id,end_pcb_port_id:t.end_pcb_port_id}:\"via\"===t.route_type?{route_type:\"via\",x:t.x,y:t.y,from_layer:t.from_layer,to_layer:t.to_layer}:null).filter(t=\u003enull!==t)}}(t,r.get(e)||e))}):e.forEach((e,o)=\u003e{const s=e.connectionName,a=function(t,e,n,o=.1,i){const r=[];if(!t.jumpers||0===t.jumpers.length)return[{type:\"pcb_trace\",pcb_trace_id:e,source_trace_id:n,route:t.route.map((e,n)=\u003e{const r=0===n,s=n===t.route.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:o,layer:Vy(e.z,i),...r\u0026\u0026e.pcb_port_id?{start_pcb_port_id:e.pcb_port_id}:{},...s\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})}];const s=[];for(const e of t.jumpers){let n=-1,o=-1;for(let i=0;i\u003ct.route.length;i++){const r=t.route[i];Math.abs(r.x-e.start.x)\u003c.01\u0026\u0026Math.abs(r.y-e.start.y)\u003c.01\u0026\u0026(n=i),Math.abs(r.x-e.end.x)\u003c.01\u0026\u0026Math.abs(r.y-e.end.y)\u003c.01\u0026\u0026(o=i)}-1!==n\u0026\u0026-1!==o\u0026\u0026(n\u003eo\u0026\u0026([n,o]=[o,n]),s.push({startIdx:n,endIdx:o}))}s.sort((t,e)=\u003et.startIdx-e.startIdx);let a=0,c=0;for(const{startIdx:l,endIdx:d}of s){if(l\u003e=a){const s=t.route.slice(a,l+1);s.length\u003e0\u0026\u0026(r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((t,e)=\u003e{const n=0===e\u0026\u00260===a;return{route_type:\"wire\",x:t.x,y:t.y,width:o,layer:Vy(t.z,i),...n\u0026\u0026t.pcb_port_id?{start_pcb_port_id:t.pcb_port_id}:{}}})}),c++)}a=d}if(a\u003ct.route.length){const s=t.route.slice(a);if(s.length\u003e0){const t=!0;r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((e,n)=\u003e{const r=t\u0026\u0026n===s.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:o,layer:Vy(e.z,i),...r\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})})}}return r}(e,`trace_${o}`,r.get(s)||s,n,t.layerCount);i.push(...a)})),i}var dk=t=\u003et.rootConnectionName??t.connectionName,hk=(t,e)=\u003e{if(t\u0026\u0026e)return t.getNetConnectedToId(e)},uk=(t,e,n)=\u003e{if(!e)return!1;if(t===e)return!0;if(n?.areIdsConnected(t,e))return!0;const o=hk(n,t),i=hk(n,e);return!(!o||o!==e\u0026\u0026o!==i)||!(!i||i!==t\u0026\u0026i!==o)},pk=(t,e,n)=\u003ee.connectedTo?.some(e=\u003euk(t,e,n))??!1,mk=(t,e,n)=\u003eMath.max(e,Math.min(t,n)),gk=(t,e)=\u003e{t.x=mk(t.x,e.minX,e.maxX),t.y=mk(t.y,e.minY,e.maxY)},fk=(t,e)=\u003e({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),yk=(t,e)=\u003e({minCellX:Math.floor(t.minX/e),maxCellX:Math.floor(t.maxX/e),minCellY:Math.floor(t.minY/e),maxCellY:Math.floor(t.maxY/e)}),_k=(t,e)=\u003e`${t}:${e}`,bk=(t,e,n)=\u003e{const o=new Map;for(let i=0;i\u003ct.length;i+=1){const r=t[i];if(!r)continue;const s=yk(e(r),n);for(let t=s.minCellX;t\u003c=s.maxCellX;t+=1)for(let e=s.minCellY;e\u003c=s.maxCellY;e+=1){const n=_k(t,e),r=o.get(n);r?r.push(i):o.set(n,[i])}}return o},xk=(t,e,n)=\u003e{const o=new Set,i=yk(e,n);for(let e=i.minCellX;e\u003c=i.maxCellX;e+=1)for(let n=i.minCellY;n\u003c=i.maxCellY;n+=1){const i=t.get(_k(e,n));if(i)for(const t of i)o.add(t)}return[...o].sort((t,e)=\u003et-e)},vk=1e-6,Sk=(t,e,n)=\u003e{if(0===t.length)return[];const o=n?.traceThickness??.1,i=t[0],r=t.at(-1),s=t=\u003e{if(t.pcb_port_id)return t.pcb_port_id;const o=Vy(t.z,e);return n?.connectionPoints?.find(e=\u003e{return e.pcb_port_id\u0026\u0026(n=e,i=t,Math.abs(n.x-i.x)\u003c=vk\u0026\u0026Math.abs(n.y-i.y)\u003c=vk)\u0026\u0026sk(e).includes(o);var n,i})?.pcb_port_id},a=s(i),c=s(r),l=[{route_type:\"wire\",x:i.x,y:i.y,width:o,layer:Vy(i.z,e),...a?{start_pcb_port_id:a}:{},...1===t.length\u0026\u0026c?{end_pcb_port_id:c}:{}}];for(let i=1;i\u003ct.length;i+=1){const r=t[i-1],s=t[i];r\u0026\u0026s\u0026\u0026(r.z!==s.z\u0026\u0026r.x===s.x\u0026\u0026r.y===s.y\u0026\u0026l.push({route_type:\"via\",x:s.x,y:s.y,from_layer:Vy(r.z,e),to_layer:Vy(s.z,e),...n?.viaDiameter?{via_diameter:n.viaDiameter}:{}}),l.push({route_type:\"wire\",x:s.x,y:s.y,width:o,layer:Vy(s.z,e),...i===t.length-1\u0026\u0026c?{end_pcb_port_id:c}:{}}))}return l},Ik=(t,e)=\u003e({x:Ae(t.x,e.minX,e.maxX),y:Ae(t.y,e.minY,e.maxY)}),Ck=(t,e)=\u003e{const n=t.x-e.center.x,o=t.y-e.center.y;return e.circular?Math.max(0,Math.hypot(n,o)-e.halfWidth):je(R(e.worldToLocal,t),{minX:-e.halfWidth,maxX:e.halfWidth,minY:-e.halfHeight,maxY:e.halfHeight})},Pk=(t,e)=\u003e({kind:\"line\",start:t,end:e,bounds:We([t,e])}),Mk=(t,e)=\u003e({kind:\"circle\",center:t,radius:e,bounds:Ve({center:t,width:2*e,height:2*e})}),Nk=t=\u003e{const e=t.clearance+h_;if(t.circular)return[Mk(t.center,t.halfWidth+e)];const n=(e,n)=\u003eR(t.localToWorld,{x:e,y:n}),{halfWidth:o,halfHeight:i}=t;return[Pk(n(-o,-i-e),n(o,-i-e)),Pk(n(o+e,-i),n(o+e,i)),Pk(n(o,i+e),n(-o,i+e)),Pk(n(-o-e,i),n(-o-e,-i)),Mk(n(-o,-i),e),Mk(n(o,-i),e),Mk(n(o,i),e),Mk(n(-o,i),e)]},wk=(t,e)=\u003e{if(\"circle\"===e.kind){const n=t.x-e.center.x,o=t.y-e.center.y,i=Math.hypot(n,o);return 0===i?[{x:e.center.x+e.radius,y:e.center.y},{x:e.center.x-e.radius,y:e.center.y},{x:e.center.x,y:e.center.y+e.radius},{x:e.center.x,y:e.center.y-e.radius}]:[{x:e.center.x+n*e.radius/i,y:e.center.y+o*e.radius/i}]}return[e.start,e.end,ze(t,e.start,e.end)]},Tk=(t,e)=\u003e{const n=t.end.x-t.start.x,o=t.end.y-t.start.y,i=t.start.x-e.center.x,r=t.start.y-e.center.y,s=n*n+o*o;if(0===s)return[];const a=2*(i*n+r*o),c=a*a-4*s*(i*i+r*r-e.radius*e.radius);if(c\u003c0)return[];const l=Math.sqrt(c);return[(-a-l)/(2*s),(-a+l)/(2*s)].filter(t=\u003et\u003e=0\u0026\u0026t\u003c=1).map(e=\u003e({x:t.start.x+n*e,y:t.start.y+o*e}))},Rk=(t,e)=\u003e{if(\"line\"===t.kind\u0026\u0026\"circle\"===e.kind)return Tk(t,e);if(\"circle\"===t.kind\u0026\u0026\"line\"===e.kind)return Tk(e,t);if(\"line\"===t.kind\u0026\u0026\"line\"===e.kind){const n=ve(t.start,t.end,e.start,e.end);return n?[n]:[]}if(\"circle\"!==t.kind||\"circle\"!==e.kind)return[];const n=e.center.x-t.center.x,o=e.center.y-t.center.y,i=Math.hypot(n,o);if(0===i||i\u003et.radius+e.radius||i\u003cMath.abs(t.radius-e.radius))return[];const r=(t.radius**2-e.radius**2+i**2)/(2*i),s=Math.sqrt(Math.max(0,t.radius**2-r**2)),a=t.center.x+n*r/i,c=t.center.y+o*r/i;return[{x:a-o*s/i,y:c+n*s/i},{x:a+o*s/i,y:c-n*s/i}]},Ek=(t,e,n,o,i)=\u003e{const r=new Set(function(t,e,n=1){if(0===n)throw new Error(\"step cannot be 0\");let o,i;void 0===e?(o=0,i=t):(o=t,i=e);const r=[];if(n\u003e0)for(let t=o;t\u003ci;t+=n)r.push(t);else for(let t=o;t\u003ei;t+=n)r.push(t);return r}(Math.min(...o),Math.max(...o)+1).map(e=\u003eVy(e,t.layerCount)));return t.obstacles.filter(t=\u003e!t.isCopperPour\u0026\u0026t.layers.some(t=\u003er.has(t))).map(o=\u003e{const r=\"number\"==typeof o.ccwRotationDegrees\u0026\u0026Number.isFinite(o.ccwRotationDegrees),s=!r\u0026\u0026o.layers.length\u003e1\u0026\u0026Math.abs(o.width-o.height)\u003c.001,a=D(k(o.center.x,o.center.y),j(r?o.ccwRotationDegrees:0)),c=s?Math.max(o.width,o.height)/2:o.width/2,l=s?c:o.height/2,d=pk(dk(e),o,i)||pk(e.connectionName,o,i),h=n+(d?0:y_(t)),u=We(E(a,[{x:-c,y:-l},{x:c,y:-l},{x:c,y:l},{x:-c,y:l}])),p=h+h_;return{center:o.center,halfWidth:c,halfHeight:l,localToWorld:a,worldToLocal:A(a),circular:s,clearance:h,bounds:{minX:u.minX-p,maxX:u.maxX+p,minY:u.minY-p,maxY:u.maxY+p}}})},Ak=(t,e,n,o)=\u003e{const i=Math.min(...t.zLayers),r=Math.max(...t.zLayers),s=e.filter(e=\u003ee.z\u003e=i\u0026\u0026e.z\u003c=r\u0026\u0026!uk(t.rootConnectionName,e.rootConnectionName,o)).map(e=\u003e({segment:e,required:t.radius+e.radius+n})).filter(({segment:e,required:n})=\u003ebe(t,e.start,e.end)\u003c=n+p_),a=s.flatMap(({segment:t,required:e})=\u003e{const{start:n,end:o}=t,i=Math.sqrt(Ye(n,o));if(i\u003c=h_)return[];const r=e+h_,s=(o.y-n.y)/i*r,a=(n.x-o.x)/i*r;return[Pk({x:n.x+s,y:n.y+a},{x:o.x+s,y:o.y+a}),Pk({x:n.x-s,y:n.y-a},{x:o.x-s,y:o.y-a}),Mk(n,r),Mk(o,r)]}).filter(e=\u003eje(t,e.bounds)\u003c=p_),c=[],l=e=\u003e{Ye(e,t)\u003ep_**2||c.some(t=\u003eYe(t,e)\u003c1e-12)||s.some(({segment:t,required:n})=\u003ebe(e,t.start,t.end)\u003cn)||c.push(e)};l(t);for(let e=0;e\u003ca.length;e+=1){const n=a[e];for(const e of wk(t,n))l(e);for(let t=e+1;t\u003ca.length;t+=1){const e=a[t];if(Xe(n.bounds,e.bounds))for(const t of Rk(n,e))l(t)}}return c.sort((e,n)=\u003eYe(e,t)-Ye(n,t))},Ok=t=\u003e({...t,route:t.route.map(t=\u003e({...t})),vias:t.vias.map(t=\u003e({...t}))}),kk=t=\u003et.map(Ok),Lk=(t,e)=\u003e{const n=new Set(e);return t.map((t,e)=\u003en.has(e)?Ok(t):t)},Dk=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=u_\u0026\u0026Math.abs(t.y-e.y)\u003c=u_,zk=[\"pcb_smtpad\",\"pcb_plated_hole\",\"pcb_hole\",\"pcb_keepout\"],Fk=t=\u003e\"string\"==typeof t.type?t.type:\"string\"==typeof t.error_type?t.error_type:void 0,Bk=t=\u003e{if(\"pcb_pad_trace_clearance_error\"===Fk(t))return!0;const e=\"string\"==typeof t.message?t.message.toLowerCase():\"\";return(e.includes(\"pcb_trace\")||e.includes(\"pcb trace\"))\u0026\u0026zk.some(t=\u003ee.includes(t))},jk=t=\u003e{const e=\"string\"==typeof t.message?t.message:\"\",n=e.match(/gap: (-?\\d+(?:\\.\\d+)?)mm/),o=e.match(/required: (-?\\d+(?:\\.\\d+)?)mm/);if(n\u0026\u0026o){const t=Number.parseFloat(n[1]),e=Number.parseFloat(o[1]);if(Number.isFinite(t)\u0026\u0026Number.isFinite(e))return Math.max(0,e-t)}if(n){const t=Number.parseFloat(n[1]),e=rk.traceClearance??.1;if(Number.isFinite(t))return Math.max(0,e-t)}return 1},$k={projectEngineError:t=\u003e({...t,center:\"object\"==typeof t.first_contact_center?t.first_contact_center:t.center,message:\"string\"==typeof t.first_contact_message?t.first_contact_message:t.message,actual_clearance:\"number\"==typeof t.first_actual_clearance?t.first_actual_clearance:t.actual_clearance}),getErrorSeverity:jk},Yk={projectEngineError:t=\u003et,getErrorSeverity:t=\u003e{const e=Number(t.minimum_clearance),n=Number(t.worst_actual_clearance);return Number.isFinite(e)\u0026\u0026Number.isFinite(n)?Math.max(0,e-n):jk(t)}},Xk=(t,e=jk)=\u003et.reduce((t,n)=\u003et+e(n),0),Vk=(t,e,n,o,i,r=$k)=\u003e{const s=i\u0026\u0026!n?t:((t,e)=\u003ee?{...t,connections:t.connections.map(t=\u003e{const n=hk(e,t.name)??hk(e,t.rootConnectionName)??t.netConnectionName;return n?{...t,netConnectionName:n}:t}),obstacles:t.obstacles.map(t=\u003e{const n=new Set(t.connectedTo);for(const o of t.connectedTo){const t=hk(e,o);t\u0026\u0026n.add(t)}return{...t,connectedTo:[...n]}})}:t)(t,o),{traces:a,traceRouteIndexById:c}=((t,e)=\u003e{const n=[],o=new Map,i=new Map;for(let t=0;t\u003ce.length;t+=1){const n=e[t];if(!n)continue;const o=i.get(n.connectionName);o?o.push({route:n,routeIndex:t}):i.set(n.connectionName,[{route:n,routeIndex:t}])}for(const e of t.connections){const r=i.get(e.name)??[];for(let i=0;i\u003cr.length;i+=1){const s=r[i];if(!s)continue;const a=`${e.name}_${i}`;n.push({type:\"pcb_trace\",pcb_trace_id:a,connection_name:e.netConnectionName??e.rootConnectionName??e.name,route:Sk(s.route.route,t.layerCount,{traceThickness:s.route.traceThickness??e.nominalTraceWidth??t.nominalTraceWidth??t.minTraceWidth,viaDiameter:s.route.viaDiameter??t.minViaDiameter,connectionPoints:e.pointsToConnect})}),o.set(a,s.routeIndex)}}return{traces:n,traceRouteIndexById:o}})(s,e),l=n?.({srj:s,routes:e,traces:a});if(l){const t=Array.isArray(l)?l:l.errors,e=Array.isArray(l)?l:l.errorsWithCenters??l.errors;return{errors:e,count:t.length,issueScore:Xk(e,r.getErrorSeverity),legacyIssueScore:Xk(e.filter(t=\u003e!uD(t)),r.getErrorSeverity),traceRouteIndexById:c}}const d=i?.evaluate(a)??((t,e={})=\u003e{const n=Math.max(e.viaClearance??.1,.1),o=[...QO(t,ik(e.traceClearance)),...nk(t,ik(n)),...ok(t,ik(n))],i=t.filter(t=\u003e\"pcb_via\"===t.type),r=new Map(i.map(t=\u003e[t.pcb_via_id,t])),s=o.map(t=\u003e{if(\"center\"in t\u0026\u0026t.center)return t;if(\"pcb_center\"in t\u0026\u0026t.pcb_center)return{...t,center:t.pcb_center};if(\"pcb_via_ids\"in t\u0026\u0026Array.isArray(t.pcb_via_ids)){const[e,n]=t.pcb_via_ids;if(\"string\"!=typeof e||\"string\"!=typeof n)return t;const o=r.get(e),i=r.get(n);if(o\u0026\u0026i)return{...t,center:{x:(o.x+i.x)/2,y:(o.y+i.y)/2}}}if(\"pcb_error_id\"in t\u0026\u0026\"string\"==typeof t.pcb_error_id\u0026\u0026(t.pcb_error_id.startsWith(\"same_net_vias_close_\")||t.pcb_error_id.startsWith(\"different_net_vias_close_\"))){const e=t.pcb_error_id.replace(\"same_net_vias_close_\",\"\").replace(\"different_net_vias_close_\",\"\").split(\"_\").filter(Boolean);if(2===e.length){const n=e[0],o=e[1];if(!n||!o)return t;const i=r.get(n),s=r.get(o);if(i\u0026\u0026s)return{...t,center:{x:(i.x+s.x)/2,y:(i.y+s.y)/2}}}}return t}),a=s.filter(t=\u003eBoolean(t.center));return{errors:o,errorsWithCenters:s,locationAwareErrors:a}})(lk(s,a,s.minTraceWidth,s.minViaDiameter),{...rk,traceClearance:s.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:s.minTraceToPadEdgeClearance??rk.viaClearance}),h=d.errors,u=(d.errorsWithCenters.length\u003e0?d.errorsWithCenters:d.errors).map(t=\u003er.projectEngineError(t));return{errors:u,count:h.length,issueScore:Xk(u,r.getErrorSeverity),legacyIssueScore:Xk(u.filter(t=\u003e!uD(t)),r.getErrorSeverity),traceRouteIndexById:c}},Wk=(t,e,n,o,i)=\u003eVk(t,e,n,o,i,$k),Hk=(t,e,n,o,i)=\u003eVk(t,e,n,o,i,Yk),Gk=(t,e=.3)=\u003e{const n=[];for(let o=0;o\u003ct.length;o+=1){const i=t[o];if(!i)continue;const r=new Set;for(let t=0;t\u003ci.route.length-1;t+=1){const s=i.route[t],a=i.route[t+1];if(!s||!a)continue;if(s.z===a.z||!Dk(s,a))continue;const c=[t,t+1];for(let e=t-1;e\u003e=0;e-=1){const t=i.route[e];if(!t||!Dk(t,s))break;c.push(e)}for(let e=t+2;e\u003ci.route.length;e+=1){const t=i.route[e];if(!t||!Dk(t,s))break;c.push(e)}const l=[...new Set(c)];if(l.some(t=\u003er.has(t)))continue;for(const t of l)r.add(t);const d=l.filter(t=\u003e0===t||t===i.route.length-1),h=d.some(t=\u003eBoolean(i.route[t]?.pcb_port_id));n.push({routeIndex:o,rootConnectionName:dk(i),pointIndexes:l,zLayers:[...new Set(l.map(t=\u003ei.route[t].z))],x:s.x,y:s.y,radius:(i.viaDiameter??e)/2,movable:0===d.length,canCanonicalize:0===d.length||!h})}}return n},Uk=(t,e)=\u003e{const n=[];for(let o=0;o\u003ct.route.length-1;o+=1){const i=t.route[o],r=t.route[o+1];i\u0026\u0026r\u0026\u0026(i.z!==r.z||Dk(i,r)||n.push({routeIndex:e,rootConnectionName:dk(t),startIndex:o,endIndex:o+1,start:i,end:r,z:i.z,radius:(t.traceThickness??.1)/2}))}return n},Zk=t=\u003et.flatMap((t,e)=\u003eUk(t,e)),qk=t=\u003e({minX:t.x,minY:t.y,maxX:t.x,maxY:t.y}),Jk=t=\u003e({minX:Math.min(t.start.x,t.end.x),minY:Math.min(t.start.y,t.end.y),maxX:Math.max(t.start.x,t.end.x),maxY:Math.max(t.start.y,t.end.y)}),Kk=t=\u003e({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}),Qk=(t,e)=\u003e{if(t.zLayers\u0026\u0026t.zLayers.length\u003e0)return t.zLayers;const n=Array.from({length:e},(t,e)=\u003ee).filter(n=\u003et.layers.includes(Vy(n,e)));return n.length\u003e0?n:Array.from({length:e},(t,e)=\u003ee)},tL=(t,e,n)=\u003e{const o=e.reduce((t,e)=\u003eMath.max(t,e.radius),(t.minViaDiameter??.3)/2),i=n.reduce((t,e)=\u003eMath.max(t,e.radius),t.minTraceWidth/2),r=(rk.traceClearance??.1)+g_;return Math.max(2*o+.2+g_,o+i+r,2*i+r,i+f_(t)+g_,o+y_(t)+g_)},eL=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c=h_)return{x:e.x,y:e.y,t:0};const s=mk(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return{x:e.x+o*s,y:e.y+i*s,t:s}},nL=(t,e)=\u003eeL(t,e.start,e.end),oL=(t,e)=\u003e{const n=e.width/2,o=e.height/2,i=Math.max(Math.abs(t.x-e.center.x)-n,0),r=Math.max(Math.abs(t.y-e.center.y)-o,0);return Math.hypot(i,r)},iL=(t,e)=\u003et.x\u003e=e.center.x-e.width/2-u_\u0026\u0026t.x\u003c=e.center.x+e.width/2+u_\u0026\u0026t.y\u003e=e.center.y-e.height/2-u_\u0026\u0026t.y\u003c=e.center.y+e.height/2+u_,rL=(t,e,n,o)=\u003et.obstacles.find(i=\u003epk(dk(e),i,o)\u0026\u0026Qk(i,t.layerCount).includes(n.z)\u0026\u0026iL(n,i)),sL=(t,e,n=.6,o)=\u003e{let i;for(const r of t.obstacles){if(o\u0026\u0026!o(r))continue;const t=oL(e,r);t\u003en||(!i||t\u003ci.distance)\u0026\u0026(i={obstacle:r,distance:t})}return i?.obstacle},aL=(t,e,n)=\u003e{const o=e.width/2,i=e.height/2,r=mk(t.x,e.center.x-o,e.center.x+o),s=mk(t.y,e.center.y-i,e.center.y+i);let a=t.x-r,c=t.y-s,l=Math.hypot(a,c);if(l\u003c=h_){o-Math.abs(t.x-e.center.x)\u003ci-Math.abs(t.y-e.center.y)?(a=t.x\u003e=e.center.x?1:-1,c=0,l=0):(a=0,c=t.y\u003e=e.center.y?1:-1,l=0)}const d=n-l;if(d\u003c=0)return;const h=Math.hypot(a,c);return{direction:{x:h\u003eh_?a/h:1,y:h\u003eh_?c/h:0},penetration:d}},cL=(t,e,n,o)=\u003e{const i=e.message;if(\"string\"!=typeof i||!i.includes(\"pcb_\"))return n;const r=Array.isArray(e.pcb_pad_ids)?e.pcb_pad_ids.filter(t=\u003e\"string\"==typeof t):[],s=t.obstacles.find(t=\u003er.some(e=\u003et.connectedTo.includes(e))\u0026\u0026(o?.(t)??!0));return s?s.center:sL(t,n,.6,o)?.center??n},lL=(t,e)=\u003e{const n=t.route[e];if(!n)return[];const o=[e];for(let i=e-1;i\u003e=0;i-=1){const e=t.route[i];if(!e||!Dk(e,n))break;o.push(i)}for(let i=e+1;i\u003ct.route.length;i+=1){const e=t.route[i];if(!e||!Dk(e,n))break;o.push(i)}return[...new Set(o)]},dL=(t,e)=\u003e{if(e\u003c=0||e\u003e=t.route.length-1)return;const n=lL(t,e);return n.includes(0)||n.includes(t.route.length-1)?void 0:n},hL=(t,e)=\u003et.x\u003e=e.minX-u_\u0026\u0026t.x\u003c=e.maxX+u_\u0026\u0026t.y\u003e=e.minY-u_\u0026\u0026t.y\u003c=e.maxY+u_,uL=(t,e)=\u003eMath.min(t.x-e.minX,e.maxX-t.x,t.y-e.minY,e.maxY-t.y),pL=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=t.x-e.x,s=o*(t.y-e.y)-i*r;if(Math.abs(s)\u003eu_)return!1;const a=Math.min(e.x,n.x)-u_,c=Math.max(e.x,n.x)+u_,l=Math.min(e.y,n.y)-u_,d=Math.max(e.y,n.y)+u_;return t.x\u003e=a\u0026\u0026t.x\u003c=c\u0026\u0026t.y\u003e=l\u0026\u0026t.y\u003c=d},mL=(t,e)=\u003e{if(e.length\u003c3)return!0;for(let n=0;n\u003ce.length;n+=1){const o=e[n],i=e[(n+1)%e.length];if(o\u0026\u0026i\u0026\u0026pL(t,o,i))return!0}let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o,o+=1){const r=e[o],s=e[i];if(!r||!s)continue;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n},gL=(t,e)=\u003e{const n=Math.hypot(t,e);if(!(n\u003c=h_))return{x:t/n,y:e/n}},fL=(t,e)=\u003et.outline\u0026\u0026t.outline.length\u003e=3?((t,e)=\u003e{const n=mL(t,e);let o;for(let n=0;n\u003ce.length;n+=1){const i=e[n],r=e[(n+1)%e.length];if(!i||!r)continue;const s=eL(t,i,r),a=Math.hypot(t.x-s.x,t.y-s.y);(!o||a\u003co.distance)\u0026\u0026(o={projection:s,start:i,end:r,distance:a})}if(!o)return;const i=gL(n?t.x-o.projection.x:o.projection.x-t.x,n?t.y-o.projection.y:o.projection.y-t.y);if(i)return i;const r=o.end.x-o.start.x,s=o.end.y-o.start.y,a=Math.hypot(r,s);if(a\u003c=h_)return;const c=(t=\u003e{let e=0;for(let n=0;n\u003ct.length;n+=1){const o=t[n],i=t[(n+1)%t.length];o\u0026\u0026i\u0026\u0026(e+=o.x*i.y-i.x*o.y)}return e/2})(e)\u003e=0;return{x:c?-s/a:s/a,y:c?r/a:-r/a}})(e,t.outline):((t,e)=\u003e{const n=t.x-e.minX,o=e.maxX-t.x,i=t.y-e.minY,r=e.maxY-t.y,s=Math.min(n,o,i,r);let a=0,c=0;return n\u003c=s+u_\u0026\u0026(a+=1),o\u003c=s+u_\u0026\u0026(a-=1),i\u003c=s+u_\u0026\u0026(c+=1),r\u003c=s+u_\u0026\u0026(c-=1),gL(a,c)})(e,t.bounds),yL=(t,e)=\u003et.outline\u0026\u0026t.outline.length\u003e=3?mL(e,t.outline):hL(e,t.bounds),_L=(t,e)=\u003e{if(t.outline\u0026\u0026t.outline.length\u003e=3){const n=((t,e)=\u003e{let n=Number.POSITIVE_INFINITY;for(let o=0;o\u003ce.length;o+=1){const i=e[o],r=e[(o+1)%e.length];i\u0026\u0026r\u0026\u0026(n=Math.min(n,be(t,i,r)))}return n})(e,t.outline);return mL(e,t.outline)?n:-n}return uL(e,t.bounds)},bL=(t,e,n)=\u003e{if(Math.abs(e.x-n.x)\u003c=u_\u0026\u0026Math.abs(e.y-n.y)\u003c=u_)return Math.min(_L(t,e),_L(t,n));if(t.outline\u0026\u0026t.outline.length\u003e=3){if(!mL(e,t.outline)||!mL(n,t.outline))return Math.min(_L(t,e),_L(t,n));let o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ct.outline.length;i+=1){const r=t.outline[i],s=t.outline[(i+1)%t.outline.length];r\u0026\u0026s\u0026\u0026(o=Math.min(o,Oe(e,n,r,s)))}return o}return hL(e,t.bounds)\u0026\u0026hL(n,t.bounds)?Math.min(uL(e,t.bounds),uL(n,t.bounds)):Math.min(_L(t,e),_L(t,n))},xL=(t,e)=\u003ee+Math.max(.16,t.defaultObstacleMargin??0,rk.traceClearance??.1),vL=(t,e,n)=\u003ee\u003ct-u_\u0026\u0026Math.min(t,e)\u003c=n+u_,SL=(t,e,n,o,i)=\u003e{const r=t*n.x+e*n.y,s=-Math.max(0,o-i);if(r\u003e=s-u_)return{x:t,y:e};const a=s-r;return{x:t+n.x*a,y:e+n.y*a}},IL=(t,e,n,o,i)=\u003e{const r=fL(t,e);return r?SL(n,o,r,_L(t,e),xL(t,i)):{x:n,y:o}},CL=(t,e,n,o)=\u003e{const i=[...new Set(n)].sort((t,e)=\u003et-e);if(0===i.length)return Number.POSITIVE_INFINITY;const r=new Set(i),s=t=\u003eo?.get(t)??e.route[t];let a=Number.POSITIVE_INFINITY;for(const e of i){const n=s(e);n\u0026\u0026(a=Math.min(a,_L(t,n)))}for(let n=0;n\u003ce.route.length-1;n+=1){if(!r.has(n)\u0026\u0026!r.has(n+1))continue;const e=s(n),o=s(n+1);e\u0026\u0026o\u0026\u0026(a=Math.min(a,bL(t,e,o)))}return a},PL=(t,e,n,o,i,r)=\u003e{const s=[...new Set(n)].sort((t,e)=\u003et-e);if(0===s.length)return;const a=((t,e,n,o,i,r)=\u003e{const s=[...new Set(n)].sort((t,e)=\u003et-e);let a={x:o,y:i};const c=xL(t,r);for(let n=0;n\u003cMath.max(1,s.length);n+=1){let n=!1;for(const o of s){const i=e.route[o];if(!i)continue;const r=fL(t,i);if(!r)continue;const s=SL(a.x,a.y,r,_L(t,i),c);(Math.abs(s.x-a.x)\u003eh_||Math.abs(s.y-a.y)\u003eh_)\u0026\u0026(a=s,n=!0)}if(!n)break}return a})(t,e,s,o,i,r);if(Math.abs(a.x)\u003c=h_\u0026\u0026Math.abs(a.y)\u003c=h_)return;const c=new Map;for(const t of s){const n=e.route[t];if(!n)continue;const o={x:n.x+a.x,y:n.y+a.y};c.set(t,o)}const l=CL(t,e,s),d=CL(t,e,s,c);if(d\u003cr-u_)return;const h=xL(t,r);return vL(l,d,h)?void 0:a},ML=(t,e,n,o,i,r,s)=\u003e{const a=t[e];if(!a)return!1;const c=dL(a,n);if(!c)return!1;const l=PL(r,a,c,o,i,s);if(!l)return!1;let d=!1;for(const t of c){const e=a.route[t];e\u0026\u0026(e.x+=l.x,e.y+=l.y,gk(e,r.bounds),d=!0)}return d},NL=(t,e,n,o,i,r)=\u003edL(e,n)??((t,e,n,o,i,r)=\u003e{const s=e.route[n];if(!s||s.pcb_port_id||0!==n\u0026\u0026n!==e.route.length-1)return;const a=rL(t,e,s,r);if(!a)return;const c={...s,x:s.x+o,y:s.y+i};return yL(t,c)\u0026\u0026iL(c,a)?lL(e,n):void 0})(t,e,n,o,i,r),wL=(t,e,n,o,i,r)=\u003e{const s=PL(i,t,e,n,o,r);if(!s)return!1;let a=!1;for(const n of e){const e=t.route[n];e\u0026\u0026(e.x+=s.x,e.y+=s.y,gk(e,i.bounds),a=!0)}return a},TL=(t,e,n,o,i,r)=\u003e{const s=e.route[n];if(!s)return!1;if(s.pcb_port_id)return!1;const a=rL(t,e,s,r);return!!a\u0026\u0026iL({...s,x:s.x+o,y:s.y+i},a)},RL=(t,e,n,o)=\u003e{const i=e.route[n];if(i\u0026\u0026!i.pcb_port_id)return rL(t,e,i,o)},EL=(t,e,n,o,i,r,s)=\u003e{const a=t[e];if(!a||0===a.route.length)return!1;const c=((t,e,n,o,i)=\u003e{let r=Number.NEGATIVE_INFINITY,s=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY,c=Number.POSITIVE_INFINITY;for(const n of[0,e.route.length-1]){const o=e.route[n],l=RL(t,e,n,i);if(!o||!l)return;r=Math.max(r,l.center.x-l.width/2-o.x),s=Math.min(s,l.center.x+l.width/2-o.x),a=Math.max(a,l.center.y-l.height/2-o.y),c=Math.min(c,l.center.y+l.height/2-o.y)}if(!(r\u003es||a\u003ec))return{x:mk(n,r,s),y:mk(o,a,c)}})(i,a,n,o,s);if(!c)return!1;const l=a.route.map((t,e)=\u003ee),d=PL(i,a,l,c.x,c.y,r);if(!d)return!1;const h=a.route.length-1;if(!TL(i,a,0,d.x,d.y,s)||!TL(i,a,h,d.x,d.y,s))return!1;let u=!1;for(const t of a.route)t.x+=d.x,t.y+=d.y,gk(t,i.bounds),u=!0;return u},AL=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y,r=n.x-e.x,s=n.y-e.y;return Math.abs(o*s-i*r)\u003c=u_},OL=(t,e)=\u003e{if(t.z!==e.z)return!1;const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=t.x-e.start.x,r=t.y-e.start.y;return Math.abs(n*r-o*i)\u003c=u_},kL=(t,e)=\u003e{const n=((t,e)=\u003e{const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.max(u_,.12*(t.traceThickness??.1)),r=Math.abs(o)\u003c=i,s=Math.abs(n)\u003c=i;let a=e.startIndex,c=e.endIndex;if(r||s){const n=r?(e.start.y+e.end.y)/2:(e.start.x+e.end.x)/2;for(;a\u003e0;){const o=t.route[a-1];if(!o||o.z!==e.z||Math.abs((r?o.y:o.x)-n)\u003ei)break;a-=1}for(;c\u003ct.route.length-1;){const o=t.route[c+1];if(!o||o.z!==e.z||Math.abs((r?o.y:o.x)-n)\u003ei)break;c+=1}return Array.from({length:c-a+1},(t,e)=\u003ea+e)}for(;a\u003e0;){const n=t.route[a-1],o=t.route[a],i=t.route[a+1];if(!(n\u0026\u0026o\u0026\u0026i\u0026\u0026n.z===e.z\u0026\u0026OL(n,e)\u0026\u0026AL(n,o,i)))break;a-=1}for(;c\u003ct.route.length-1;){const n=t.route[c-1],o=t.route[c],i=t.route[c+1];if(!(n\u0026\u0026o\u0026\u0026i\u0026\u0026i.z===e.z\u0026\u0026OL(i,e)\u0026\u0026AL(n,o,i)))break;c+=1}return Array.from({length:c-a+1},(t,e)=\u003ea+e)})(t,e);if(n.length\u003c=2)return;const o=[];for(const e of n){const n=dL(t,e);if(!n)return;o.push(...n)}return[...new Set(o)]},LL=(t,e)=\u003ee\u003e0\u0026\u0026e\u003ct.route.length-1\u0026\u0026!((t,e)=\u003e{const n=t.route[e];if(!n)return!1;const o=t.route[e-1],i=t.route[e+1];return o\u0026\u0026o.z!==n.z\u0026\u0026Dk(o,n)||i\u0026\u0026i.z!==n.z\u0026\u0026Dk(i,n)})(t,e),DL=(t,e,n)=\u003e{const o=t.route[e.startIndex],i=t.route[e.endIndex];return!(!o||!i)\u0026\u0026(o.z===e.z\u0026\u0026i.z===e.z\u0026\u0026(!!((t,e)=\u003eJk(t).maxX\u003e=e.minX-u_\u0026\u0026Jk(t).minX\u003c=e.maxX+u_\u0026\u0026Jk(t).maxY\u003e=e.minY-u_\u0026\u0026Jk(t).minY\u003c=e.maxY+u_)(e,n)\u0026\u0026(LL(t,e.startIndex)||LL(t,e.endIndex))))},zL=(t,e,n,o,i,r,s)=\u003e{const a=t[e.routeIndex];if(!a)return!1;const c=((t,e,n,o)=\u003e{const i=fk(Kk(n),o);let r=e.startIndex,s=e.startIndex;for(;r\u003e0;){const n={...e,startIndex:r-1,endIndex:r,start:t.route[r-1],end:t.route[r]};if(!t.route[r-1]||!DL(t,n,i))break;r-=1}for(;s\u003ct.route.length-2;){const n={...e,startIndex:s+1,endIndex:s+2,start:t.route[s+1],end:t.route[s+2]};if(!t.route[s+2]||!DL(t,n,i))break;s+=1}const a=[];for(let e=r;e\u003c=s+1;e+=1)LL(t,e)\u0026\u0026a.push(e);return[...new Set(a)]})(a,e,n,o);return!(c.length\u003c=2)\u0026\u0026wL(a,c,i,r,s,e.radius)},FL=(t,e)=\u003e{const n=nL(e,t),o=n.x-e.x,i=n.y-e.y,r=Math.hypot(o,i),s=t.end.x-t.start.x,a=t.end.y-t.start.y,c=Math.hypot(s,a),l=t.routeIndex%2==0?1:-1;return{projection:n,direction:r\u003eh_?{x:o/r,y:i/r}:c\u003eh_?{x:-a/c*l,y:s/c*l}:{x:1,y:0}}},BL=(t,e,n,o,i)=\u003e{const r=t[e.routeIndex];if(!r)return!1;const s=IL(i,e,n,o,e.radius);if(Math.abs(s.x)\u003c=h_\u0026\u0026Math.abs(s.y)\u003c=h_)return!1;const a={x:e.x+s.x,y:e.y+s.y},c=_L(i,e),l=_L(i,a);if(l\u003ce.radius-u_)return!1;const d=xL(i,e.radius);if(vL(c,l,d))return!1;e.x+=s.x,e.y+=s.y,gk(e,i.bounds);for(const t of e.pointIndexes){const n=r.route[t];n\u0026\u0026(n.x=e.x,n.y=e.y)}return!0},jL=(t,e)=\u003e{const n=Gk(t),o=n.find(t=\u003et.routeIndex===e.routeIndex\u0026\u0026t.pointIndexes.some(t=\u003ee.pointIndexes.includes(t)));return o?n.filter(t=\u003et.rootConnectionName===o.rootConnectionName\u0026\u0026Math.hypot(t.x-o.x,t.y-o.y)\u003c=u_):[]},$L=(t,e,n,o,i)=\u003ee.movable\u0026\u0026jL(t,e).length\u003c=1\u0026\u0026BL(t,e,n,o,i),YL=(t,e,n,o,i=1)=\u003e{const{projection:r,direction:s}=FL(e,n),a=p_*i,c=1-r.t,l=r.t,d=ML(t,e.routeIndex,e.startIndex,s.x*a*c,s.y*a*c,o,e.radius),h=ML(t,e.routeIndex,e.endIndex,s.x*a*l,s.y*a*l,o,e.radius);return!(!d\u0026\u0026!h)||((t,e,n,o,i)=\u003e{const r=t[e.routeIndex];if(!r)return!1;const{projection:s,direction:a}=FL(e,n),c=IL(o,s,a.x*p_*i,a.y*p_*i,e.radius);if(Math.abs(c.x)\u003c=h_\u0026\u0026Math.abs(c.y)\u003c=h_)return!1;const l={...r.route[e.startIndex],x:s.x+c.x,y:s.y+c.y};if(gk(l,o.bounds),be(l,e.start,e.end)\u003c=u_)return!1;const d=r.route[e.startIndex],h=r.route[e.endIndex];if(!d||!h)return!1;const u=bL(o,d,h),p=Math.min(_L(o,l),bL(o,d,l),bL(o,l,h));if(p\u003ce.radius-u_)return!1;const m=xL(o,e.radius);return!vL(u,p,m)\u0026\u0026(r.route.splice(e.endIndex,0,l),!0)})(t,e,n,o,i)},XL=(t,e,n,o,i,r=1)=\u003e{const s=e.radius+f_(o)+g_,a=nD(e,n,s);if(!a)return!1;const c=Math.min(.3*Math.abs(r),a.penetration+g_),l=a.direction.x*c,d=a.direction.y*c,h=t[e.routeIndex];if(!h)return!1;const u=!(t=\u003e{for(let e=0;e\u003ct.route.length-1;e+=1){const n=t.route[e],o=t.route[e+1];if(n\u0026\u0026o\u0026\u0026n.z!==o.z\u0026\u0026Dk(n,o))return!0}return!1})(h);if(u\u0026\u0026EL(t,e.routeIndex,l,d,o,e.radius,i))return!0;const p=zL(t,e,n,s,l,d,o)||((t,e,n,o,i)=\u003e{const r=t[e.routeIndex];if(!r)return!1;const s=kL(r,e);return!!s\u0026\u0026wL(r,s,n,o,i,e.radius)})(t,e,l,d,o)||((t,e,n,o,i,r)=\u003e{const s=t[e.routeIndex];if(!s)return!1;const a=NL(i,s,e.startIndex,n,o,r),c=NL(i,s,e.endIndex,n,o,r);if(!a||!c)return!1;const l=[...new Set([...a,...c])],d=PL(i,s,l,n,o,e.radius);if(!d)return!1;let h=!1;for(const t of l){const e=s.route[t];e\u0026\u0026(e.x+=d.x,e.y+=d.y,gk(e,i.bounds),h=!0)}return h})(t,e,l,d,o,i);if(p)return!0;if(!u\u0026\u0026EL(t,e.routeIndex,l,d,o,e.radius,i))return!0;const m=n.width/2,g=n.height/2,f=(Math.abs(a.direction.y)\u003e=Math.abs(a.direction.x)?[{...h.route[e.startIndex],x:n.center.x-m-s,y:n.center.y+a.direction.y*(g+s)},{...h.route[e.startIndex],x:n.center.x+m+s,y:n.center.y+a.direction.y*(g+s)}]:[{...h.route[e.startIndex],x:n.center.x+a.direction.x*(m+s),y:n.center.y-g-s},{...h.route[e.startIndex],x:n.center.x+a.direction.x*(m+s),y:n.center.y+g+s}]).map(t=\u003e{const{t:n}=nL(t,e),i={x:e.start.x+(e.end.x-e.start.x)*n,y:e.start.y+(e.end.y-e.start.y)*n},r=IL(o,i,t.x-i.x,t.y-i.y,e.radius);return t.x=i.x+r.x,t.y=i.y+r.y,gk(t,o.bounds),{point:t,t:n,moved:Math.abs(r.x)\u003eh_||Math.abs(r.y)\u003eh_,awayFromObstacleMotion:r.x*a.direction.x+r.y*a.direction.y}}).sort((t,e)=\u003et.t-e.t);if(!f.some(({moved:t})=\u003et))return!1;if(!f.some(({awayFromObstacleMotion:t})=\u003et\u003eu_))return!1;const y=f.map(({point:t})=\u003et);if(y.every(t=\u003ebe(t,e.start,e.end)\u003c=u_))return!1;if(y.some(t=\u003e!yL(o,t)))return!1;const _=h.route[e.startIndex],b=h.route[e.endIndex],x=y[0],v=y[1];if(!(_\u0026\u0026b\u0026\u0026x\u0026\u0026v))return!1;const S=bL(o,_,b),I=Math.min(_L(o,x),_L(o,v),bL(o,_,x),bL(o,x,v),bL(o,v,b));if(I\u003ce.radius-u_)return!1;const C=xL(o,e.radius);return!vL(S,I,C)\u0026\u0026(h.route.splice(e.endIndex,0,...y),!0)},VL=(t,e,n)=\u003e{let o;for(const i of t){if(void 0!==n\u0026\u0026i.routeIndex!==n)continue;const t=nL(e,i),r=Math.hypot(t.x-e.x,t.y-e.y);(!o||r\u003co.distance)\u0026\u0026(o={segment:i,distance:r})}return o?.segment},WL=(t,e,n)=\u003e{let o;for(const i of t){if(void 0!==n\u0026\u0026i.routeIndex!==n)continue;const t=Math.hypot(i.x-e.x,i.y-e.y);(!o||t\u003co.distance)\u0026\u0026(o={via:i,distance:t})}return o?.via},HL=(t,e)=\u003e{const n=t.map(t=\u003e({via:t,distance:Math.hypot(t.x-e.x,t.y-e.y)})).sort((t,e)=\u003et.distance-e.distance).slice(0,2).map(({via:t})=\u003et);return 2===n.length?n:void 0},GL=(t,e,n,o)=\u003e{const i=e.x-n.x,r=e.y-n.y,s=Math.hypot(i,r);return $L(t,e,(s\u003eh_?i/s:1)*p_,(s\u003eh_?r/s:0)*p_,o)},UL=(t,e)=\u003e{const n=nL(t.start,e),o=nL(t.end,e),i=nL(e.start,t),r=nL(e.end,t);return[{leftT:0,rightT:n.t,leftPoint:t.start,rightPoint:n},{leftT:1,rightT:o.t,leftPoint:t.end,rightPoint:o},{leftT:i.t,rightT:0,leftPoint:i,rightPoint:e.start},{leftT:r.t,rightT:1,leftPoint:r,rightPoint:e.end}].sort((t,e)=\u003eMath.hypot(t.leftPoint.x-t.rightPoint.x,t.leftPoint.y-t.rightPoint.y)-Math.hypot(e.leftPoint.x-e.rightPoint.x,e.leftPoint.y-e.rightPoint.y))},ZL=(t,e,n,o,i,r)=\u003e{const s=mk(r,0,1),a=1-s,c=s,l=ML(t,e.routeIndex,e.startIndex,n*a,o*a,i,e.radius),d=ML(t,e.routeIndex,e.endIndex,n*c,o*c,i,e.radius);return l||d},qL=(t,e,n,o,i,r=.035,s=!1)=\u003e{if(!s\u0026\u0026uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const a=e.radius+n.radius+.2+g_,c=e.x-n.x,l=e.y-n.y,d=Math.hypot(c,l),h=a-d;if(h\u003c=0)return!1;const u=1.618*(97*e.routeIndex+13*n.routeIndex),p=d\u003eh_?c/d:Math.cos(u),m=d\u003eh_?l/d:Math.sin(u),g=Number(e.movable)+Number(n.movable);if(0===g)return!1;const f=Math.min(r,h/g),y=$L(t,e,p*f,m*f,o),_=$L(t,n,-p*f,-m*f,o);return y||_},JL=(t,e,n,o,i)=\u003e{if(!uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const[r,s]=e.canCanonicalize?n.canCanonicalize\u0026\u0026e.routeIndex\u003c=n.routeIndex?[e,n]:[n,e]:[e,n];return((t,e,n,o)=\u003e{if(!n.canCanonicalize)return!1;const i=e.x-n.x,r=e.y-n.y;if(!n.movable\u0026\u0026Math.hypot(i,r)\u003en.radius+u_)return!1;const s=t[n.routeIndex];if(!s)return!1;const a={x:n.x,y:n.y},c=n.pointIndexes.map(t=\u003e{const e=s.route[t];return e?{pointIndex:t,x:e.x,y:e.y}:void 0});if(BL(t,n,i,r,o)\u0026\u0026Dk(n,e))return!0;n.x=a.x,n.y=a.y;for(const t of c){if(!t)continue;const e=s.route[t.pointIndex];e\u0026\u0026(e.x=t.x,e.y=t.y)}return!1})(t,r,s,o)},KL=(t,e,n,o,i,r=.035,s=2,a=!1)=\u003e{if(uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const c=nL(e,n),l=e.x-c.x,d=e.y-c.y,h=Math.hypot(l,d),u=e.radius+n.radius+(rk.traceClearance??.1)+g_-h;if(u\u003c=0)return!1;const p=n.end.x-n.start.x,m=n.end.y-n.start.y,g=Math.hypot(p,m),f=e.routeIndex%2==0?1:-1,y=h\u003eh_?l/h:g\u003eh_?-m/g*f:1,_=h\u003eh_?d/h:g\u003eh_?p/g*f:0,b=Math.min(r,u/s),x=a?((t,e,n,o,i)=\u003e{const r=jL(t,e);if(0===r.length||r.some(e=\u003e!e.movable||void 0===t[e.routeIndex]))return!1;const s=r.reduce((t,e)=\u003ee.radius\u003et.radius?e:t);if(!BL(t,s,n,o,i))return!1;for(const e of r){if(e===s)continue;e.x=s.x,e.y=s.y;const n=t[e.routeIndex];for(const t of e.pointIndexes){const e=n.route[t];e\u0026\u0026(e.x=s.x,e.y=s.y)}}return!0})(t,e,y*b,_*b,o):$L(t,e,y*b,_*b,o),v=ZL(t,n,-y*b,-_*b,o,c.t);return x||v},QL=(t,e,n,o,i)=\u003e{if(e.z!==n.z||uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const[r]=UL(e,n);if(!r)return!1;const s=r.leftPoint.x-r.rightPoint.x,a=r.leftPoint.y-r.rightPoint.y,c=Math.hypot(s,a),l=e.radius+n.radius+(rk.traceClearance??.1)+g_-c;if(l\u003c=0)return!1;const d=e.end.x-e.start.x,h=e.end.y-e.start.y,u=Math.hypot(d,h),p=(e.routeIndex+n.routeIndex)%2==0?1:-1,m=c\u003eh_?s/c:u\u003eh_?-h/u*p:1,g=c\u003eh_?a/c:u\u003eh_?d/u*p:0,f=Math.min(m_,l/2),y=ZL(t,e,m*f,g*f,o,r.leftT),_=ZL(t,n,-m*f,-g*f,o,r.rightT);return y||_},tD=(t,e,n)=\u003eQk(t,n).includes(e.z),eD=(t,e,n,o,i)=\u003e{const r=e[n];if(!r)return;const s=Uk(r,n);if(0===s.length)return;const a=dk(r),c=VL(s,o);if(!c)return;const l=sL(t,o,.6,e=\u003e!pk(a,e,i)\u0026\u0026tD(e,c,t.layerCount));if(l)return{obstacle:l,segment:c};const d=sL(t,o,.6,e=\u003e!pk(a,e,i)\u0026\u0026s.some(n=\u003etD(e,n,t.layerCount)));if(!d)return;const h=VL(s.filter(e=\u003etD(d,e,t.layerCount)),o);return h?{obstacle:d,segment:h}:void 0},nD=(t,e,n)=\u003e{const o=e.width/2,i=e.height/2,r=[{x:e.center.x-o,y:e.center.y-i},{x:e.center.x+o,y:e.center.y-i},{x:e.center.x+o,y:e.center.y+i},{x:e.center.x-o,y:e.center.y+i}],s=[e.center,...r].map(e=\u003enL(e,t)),a=[{point:t.start,t:0},{point:t.end,t:1},{point:{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2},t:.5},...s.map(t=\u003e({point:{x:t.x,y:t.y},t:t.t}))];let c;const l=Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y);for(const o of a){const i=aL(o.point,e,n);if(!i)continue;const r=l\u003eh_?Math.abs(((t.end.x-t.start.x)*i.direction.y-(t.end.y-t.start.y)*i.direction.x)/l):0;(!c||i.penetration\u003ec.penetration+h_||Math.abs(i.penetration-c.penetration)\u003c=h_\u0026\u0026r\u003ec.normality)\u0026\u0026(c={...i,normality:r,t:o.t})}return c},oD=(t,e,n,o=!1)=\u003e{let i=!1;const r=Gk(e),s=Zk(e),a=tL(t,r,s),c=Math.max(1,2*a),l=bk(r,qk,c),d=bk(s,Jk,c);for(let s=0;s\u003cr.length;s+=1){const d=r[s];if(!d)continue;const h=xk(l,fk(qk(d),a),c);for(const a of h){if(a\u003c=s)continue;const c=r[a];c\u0026\u0026(i=qL(e,d,c,t,n,m_,o)||i)}}for(let o=0;o\u003cr.length;o+=1){const l=r[o];if(!l)continue;const h=xk(d,fk(qk(l),a),c);for(const o of h){const r=s[o];r\u0026\u0026(i=KL(e,l,r,t,n)||i)}}for(let o=0;o\u003cs.length;o+=1){const r=s[o];if(!r)continue;const l=xk(d,fk(Jk(r),a),c);for(const a of l){if(a\u003c=o)continue;const c=s[a];c\u0026\u0026(i=QL(e,r,c,t,n)||i)}}return((t,e,n,o,i,r,s,a)=\u003e{let c=!1;const l=t.minTraceWidth/2+f_(t)+g_,d=(t.minViaDiameter??.3)/2+y_(t)+g_;for(const h of t.obstacles){if(h.isCopperPour)continue;const u=Kk(h),p=xk(i,fk(u,d),s);for(const o of p){const i=n[o];if(!i)continue;if(pk(i.rootConnectionName,h,a))continue;const r=aL(i,h,d);if(!r)continue;const s=Math.min(m_,r.penetration);c=$L(e,i,r.direction.x*s,r.direction.y*s,t)||c}const m=xk(r,fk(u,l),s);for(const n of m){const i=o[n];if(!i)continue;if(pk(i.rootConnectionName,h,a)||!tD(h,i,t.layerCount))continue;const r=nD(i,h,l);if(!r)continue;const s=Math.min(m_,r.penetration);c=ZL(e,i,r.direction.x*s,r.direction.y*s,t,r.t)||c}}return c})(t,e,r,s,l,d,c,n)||i},iD=(t,e,n,o=1,i,r=!1,s=!0)=\u003e{const a=kk(e),c=Math.max(2,Math.round(12*Math.max(1,n)*o));let l=!1;for(let e=0;e\u003cc;e+=1){if(!oD(t,a,i,r))break;l=!0}return l\u0026\u0026s\u0026\u0026((t,e,n)=\u003e{let o=!1;const i=Gk(e),r=Zk(e),s=tL(t,i,r),a=Math.max(1,2*s),c=bk(r,Jk,a);for(const l of i){const i=xk(c,fk(qk(l),s),a);for(const s of i){const i=r[s];i\u0026\u0026(o=KL(e,l,i,t,n,m_,1.75)||o)}}})(t,a,i),l?aD(a):e},rD=t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n+=1){const o=t.route[n],i=t.route[n+1];if(!o||!i)continue;if(\"through_obstacle\"===o.toNextSegmentType)continue;if(o.z===i.z||!Dk(o,i))continue;const r={x:o.x,y:o.y},s=e.at(-1);s\u0026\u0026Dk(s,r)||e.push(r)}return e},sD=t=\u003e({...t,vias:rD(t)}),aD=t=\u003et.map(sD),cD=(t,e)=\u003e{const n=new Set(e);return t.map((t,e)=\u003en.has(e)?sD(t):t)},lD=t=\u003e{const e=t.pcb_trace_id;if(\"string\"!=typeof e)return;const n=e.match(/^trace_(\\d+)/);return n?Number.parseInt(n[1],10):void 0},dD=t=\u003e{const e=t.center??t.pcb_center;if(!e||\"object\"!=typeof e)return;const n=e;return\"number\"==typeof n.x\u0026\u0026\"number\"==typeof n.y?{x:n.x,y:n.y}:void 0},hD=(t,e=!0)=\u003et.errors.filter(t=\u003e(t=\u003e\"pcb_via_clearance_error\"===Fk(t)||Array.isArray(t.pcb_via_ids))(t)\u0026\u0026(e||!uD(t))).length,uD=t=\u003e\"pcb_pad_pad_clearance_error\"===Fk(t)\u0026\u0026Array.isArray(t.pcb_via_ids)\u0026\u00261===t.pcb_via_ids.length,pD=t=\u003e{const e=Object.entries(t).filter(([t,e])=\u003e\"source_trace_id\"!==t\u0026\u0026(t.endsWith(\"_id\")||t.endsWith(\"_ids\"))\u0026\u0026void 0!==e\u0026\u0026\"\"!==e).sort(([t],[e])=\u003et.localeCompare(e)),n=\"string\"==typeof t.message?t.message.replace(/-?\\d+\\.\\d+/g,\"#\"):\"\";return JSON.stringify([Fk(t),e,n])},mD=t=\u003eMath.max(t.errors.filter(t=\u003e!uD(t)).length,t.count-t.errors.filter(uD).length),gD=t=\u003e{const e=mD(t);return e\u003e0?e:t.count},fD=t=\u003e{if(0===mD(t))return t.issueScore;const e=t.errors.filter(t=\u003e!uD(t));return t.errors.some(uD)?Xk(e):t.legacyIssueScore??Xk(e)},yD=(t,e)=\u003e{const n=mD(t),o=mD(e);return n!==o?n\u003co:!(n\u003e0)\u0026\u0026t.count\u003ce.count},_D=t=\u003e{const e=t.filter(t=\u003e!uD(t));return e.length\u003e0?e:t},bD=(t,e)=\u003e{const n=t.pcb_trace_id;return\"string\"==typeof n?e.get(n)??lD(t):lD(t)},xD=(t,e,n,o,i)=\u003e{const r=n.pcb_port_id;if(!r)return!1;const s=(i??e.viaDiameter)/2;return t.obstacles.some(i=\u003e{const a=Qk(i,t.layerCount);return!(1!==a.length||a[0]!==n.z||!i.connectedTo.includes(r)||n.x-s\u003ci.center.x-i.width/2-h_||n.x+s\u003ei.center.x+i.width/2+h_||n.y-s\u003ci.center.y-i.height/2-h_||n.y+s\u003ei.center.y+i.height/2+h_)\u0026\u0026(pk(dk(e),i,o)||pk(e.connectionName,i,o))})},vD=[0,1,-1,2,-2,3,-3,4],SD=vD.flatMap(t=\u003evD.map(e=\u003e[t,e])).sort(([t,e],[n,o])=\u003eMath.abs(t)+Math.abs(e)-Math.abs(n)-Math.abs(o)),ID=SD.length,CD=(t,e,n)=\u003et.x-e\u003e=n.minX-h_\u0026\u0026t.x+e\u003c=n.maxX+h_\u0026\u0026t.y-e\u003e=n.minY-h_\u0026\u0026t.y+e\u003c=n.maxY+h_,PD=(t,e)=\u003e{const n=t.at(-1);n\u0026\u0026Dk(n,e)\u0026\u0026n.z===e.z\u0026\u0026n.pcb_port_id===e.pcb_port_id||t.push(e)},MD=(t,e,n,o,i,r,s,a=0,c=!1)=\u003e{const l=Fk(n);if(\"pcb_pad_trace_clearance_error\"!==l\u0026\u0026\"pcb_trace_error\"!==l)return!1;if(i\u003c0||i\u003e=t.layerCount)return!1;const d=e[o];if(!d||d.route.length\u003c2)return!1;const h=d.route.map(t=\u003e({...t})),u=h[0],p=h.at(-1);if(!u||!p)return!1;const m=dD(n);if(!m)return!1;const g=Bk(n),f=g?eD(t,e,o,m,s):void 0,y=g?f?.segment:VL(Uk(d,o),m);if(!y||y.z===i)return!1;let _=y.startIndex,b=y.endIndex;const x=\"full\"===r?h.length:r;for(let t=0;t\u003cx;t+=1){let t=!1;const e=h[_-1];e?.z===y.z\u0026\u0026(_-=1,t=!0);const n=h[b+1];if(n?.z===y.z\u0026\u0026(b+=1,t=!0),!t)break}const v=0===_\u0026\u0026u.pcb_port_id,S=b===h.length-1\u0026\u0026p.pcb_port_id,I=d.viaDiameter/2,C=SD[a%ID];let P=!1;const M=e=\u003e{const n=\"start\"===e?u:p,o=((t,e,n,o)=\u003e{const i=n.pcb_port_id;if(i)return t.obstacles.find(r=\u003e{const s=Qk(r,t.layerCount);return!(1!==s.length||s[0]!==n.z||!r.connectedTo.includes(i)||!iL(n,r))\u0026\u0026(pk(dk(e),r,o)||pk(e.connectionName,r,o))})})(t,d,n,s),r=((t,e)=\u003e{const n=\"start\"===e?t[0]:t.at(-1);if(!n)return;const o=\"start\"===e?Array.from({length:t.length-1},(t,e)=\u003ee+1):Array.from({length:t.length-1},(e,n)=\u003et.length-n-2);for(const e of o){const o=t[e];if(!o)continue;const i=o.x-n.x,r=o.y-n.y,s=Math.hypot(i,r);if(!(s\u003c=h_))return{x:i/s,y:r/s}}})(h,e);if(!o||!r)return;const a=((t,e,n,o)=\u003e{let i=0,r=Math.hypot(e.width,e.height)+2*o;const s=o+h_,a=e=\u003e({x:t.x+n.x*e,y:t.y+n.y*e});if(!(oL(a(r),e)\u003cs)){for(;r-i\u003eh_;){const t=(i+r)/2;oL(a(t),e)\u003e=s?r=t:i=t}return a(r)}})(n,o,((t,e)=\u003e{const n=e*Math.PI/4,o=Math.cos(n),i=Math.sin(n);return{x:t.x*o-t.y*i,y:t.x*i+t.y*o}})(r,\"start\"===e?C[0]:C[1]),I);if(!a||!CD(a,I,t.bounds)||oL(a,o)+h_\u003cI)return;if(!c)return a;const l=((t,e,n,o,i,r)=\u003e{const s=o+(t.minBoardEdgeClearance??0),a={minX:t.bounds.minX+s,maxX:t.bounds.maxX-s,minY:t.bounds.minY+s,maxY:t.bounds.maxY-s};if(a.minX\u003ea.maxX||a.minY\u003ea.maxY)return;const c=Ek(t,e,o,i,r),l=t=\u003eMe(t,a)\u0026\u0026c.every(e=\u003eCk(t,e)\u003e=e.clearance),d=Ik(n,a);if(l(d))return Me(n,a)?n:d;const h=c.filter(t=\u003eCk(d,t)\u003ct.clearance),u=new Set(h);for(let t=0;t\u003ch.length;t+=1)for(const e of c)!u.has(e)\u0026\u0026Xe(h[t].bounds,e.bounds)\u0026\u0026(u.add(e),h.push(e));const p=h.flatMap(Nk),m={x:a.minX,y:a.minY},g={x:a.maxX,y:a.minY},f={x:a.maxX,y:a.maxY},y={x:a.minX,y:a.maxY};let _;p.push(Pk(m,g),Pk(g,f),Pk(f,y),Pk(y,m));let b=Number.POSITIVE_INFINITY;const x=t=\u003e{const e=Ye(t,n);e\u003cb\u0026\u0026l(t)\u0026\u0026(_=t,b=e)};for(const t of p)for(const e of wk(n,t))x(e);for(let t=0;t\u003cp.length;t+=1){const e=p[t];if(!(Ye(n,Ik(n,e.bounds))\u003eb))for(let o=t+1;o\u003cp.length;o+=1){const t=p[o];if(Xe(e.bounds,t.bounds)\u0026\u0026!(Ye(n,Ik(n,t.bounds))\u003eb))for(const n of Rk(e,t))x(n)}}return _})(t,d,a,I,[y.z,i],s);return P||=void 0!==l\u0026\u0026l!==a,l},N=v?M(\"start\"):void 0,w=S?M(\"end\"):void 0;if(v\u0026\u0026!N||S\u0026\u0026!w||c\u0026\u0026!P)return!1;const T=[];for(let t=0;t\u003c_;t+=1)PD(T,h[t]);const R=h[_],E=_\u003e0\u0026\u0026Dk(h[_-1],R),A=h[b],O=b\u003ch.length-1\u0026\u0026Dk(h[b+1],A);v?(PD(T,u),PD(T,{...u,...N,pcb_port_id:void 0}),PD(T,{...u,...N,z:i,pcb_port_id:void 0})):(E||PD(T,{...R,pcb_port_id:void 0}),PD(T,{...R,z:i,pcb_port_id:void 0}));const k=S?b-1:b;for(let t=_+1;t\u003c=k;t+=1)PD(T,{...h[t],z:i,pcb_port_id:void 0});S?(PD(T,{...p,...w,z:i,pcb_port_id:void 0}),PD(T,{...p,...w,pcb_port_id:void 0}),PD(T,p)):O||PD(T,{...A,pcb_port_id:void 0});for(let t=b+1;t\u003ch.length;t+=1)PD(T,h[t]);for(let t=1;t\u003cT.length-1;t+=1)T[t].pcb_port_id=void 0;const L=t.minBoardEdgeClearance??.2,D=Uk(d,o),z=Gk([d]);for(let e=1;e\u003cT.length;e+=1){const n=T[e-1],o=T[e];if(n.z===o.z\u0026\u0026!D.some(t=\u003epL(n,t.start,t.end)\u0026\u0026pL(o,t.start,t.end))\u0026\u0026bL(t,n,o)\u003cd.traceThickness/2+L)return!1;if(n.z!==o.z\u0026\u0026\"through_obstacle\"!==n.toNextSegmentType\u0026\u0026!z.some(t=\u003eDk(t,o)\u0026\u0026t.radius\u003e=I)\u0026\u0026_L(t,o)\u003cI+L)return!1}return d.route=T,!0},ND=(t,e,n,o,i,r,s)=\u003e{const a=Fk(n);if(\"pcb_pad_trace_clearance_error\"!==a\u0026\u0026\"pcb_trace_error\"!==a)return!1;if(i\u003c0||i\u003e=t.layerCount)return!1;const c=bD(n,o);if(void 0===c)return!1;const l=e[c];if(!l||l.route.length\u003c2)return!1;const d=l.route[0],h=l.route.at(-1);if(!d||!h||d.z!==h.z||i===d.z)return!1;if(l.route.some(t=\u003et.z!==d.z))return!1;if(!d.pcb_port_id||!h.pcb_port_id)return!1;if(!xD(t,l,d,r,s)||!xD(t,l,h,r,s))return!1;const u=l.route.map(t=\u003e({...t}));return l.route=[u[0],{...u[0],z:i,pcb_port_id:void 0},...u.slice(1,-1).map(t=\u003e({...t,z:i})),{...u.at(-1),z:i,pcb_port_id:void 0},u.at(-1)],!0},wD=(t,e,n,o,i,r,s)=\u003e{if(\"pcb_pad_trace_clearance_error\"!==Fk(n))return!1;const a=bD(n,o);if(void 0===a)return!1;const c=e[a];if(!c||c.route.length\u003c4)return!1;const l=c.route.map(t=\u003e({...t}));if(\"start\"===i){const e=l[0];if(!xD(t,c,e,r,s))return!1;let n=-1;for(let t=1;t\u003cl.length;t+=1)if(l[t].z!==e.z){n=t;break}if(n\u003c=0)return!1;const o=n-1;if(!Dk(l[o],l[n]))return!1;let i=n;for(;i+1\u003cl.length\u0026\u0026Dk(l[n],l[i+1]);)i+=1;const a=l[i].z,d=l.slice(o,i+1).map(t=\u003et.z);return c.route=[e,...d.slice(1).map(t=\u003e({...e,z:t,pcb_port_id:void 0})),...l.slice(1,o+1).map(t=\u003e({...t,z:a})),...l.slice(i+1)],!0}const d=l.at(-1);if(!xD(t,c,d,r,s))return!1;let h=-1;for(let t=l.length-2;t\u003e=0;t-=1)if(l[t].z!==d.z){h=t;break}if(h\u003c0||h\u003e=l.length-1)return!1;const u=h+1;if(!Dk(l[h],l[u]))return!1;let p=h;for(;p-1\u003e=0\u0026\u0026Dk(l[h],l[p-1]);)p-=1;const m=l[p].z,g=l.slice(p,u+1).map(t=\u003et.z);return c.route=[...l.slice(0,p+1),...l.slice(u+1,-1).map(t=\u003e({...t,z:m})),{...d,z:m,pcb_port_id:void 0},...g.slice(1,-1).map(t=\u003e({...d,z:t,pcb_port_id:void 0})),d],!0},TD=(t,e)=\u003e{const n=t.pcb_trace_id;if(\"string\"!=typeof n)return;if(Array.isArray(t.pcb_via_ids)\u0026\u0026t.pcb_via_ids.length\u003e0)return;const o=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],i=t.pcb_trace_error_id,r=`overlap_${n}_`,s=\"string\"==typeof i\u0026\u0026i.startsWith(r)?i.slice(r.length):void 0,a=[n,...o,...s?[s]:[]],c=[...new Set(a.map(t=\u003ee.get(t)).filter(t=\u003evoid 0!==t))];return c.length\u003e=2?[c[0],c[1]]:void 0},RD=(t,e,n,o,i)=\u003e{if(\"pcb_trace_error\"!==Fk(n))return;const r=TD(n,o);if(!r)return;const s=n.worst_contact_center??n.center;if(!s||\"object\"!=typeof s)return;const a=s;if(\"number\"!=typeof a.x||\"number\"!=typeof a.y)return;const c={x:a.x,y:a.y},l=Zk(e),d=VL(l,c,r[0]),h=VL(l,c,r[1]);if(!d||!h||d.z!==h.z)return;const[u]=UL(d,h);if(!u)return;const p=u.leftPoint.x-u.rightPoint.x,m=u.leftPoint.y-u.rightPoint.y,g=Math.hypot(p,m),f=Number(n.minimum_clearance),y=Number.isFinite(f)?f:rk.traceClearance??.1,_=d.radius+h.radius+y-g;if(_\u003c=h_)return;const b=0===i?d:h,x=0===i?u.leftT:u.rightT,v=(1-x)**2+x**2;if(v\u003c=h_)return;const S=_/v,I=0===i?u.leftPoint:u.rightPoint,C=0===i?u.rightPoint:u.leftPoint,P=0===i?1:-1,M=b.end.x-b.start.x,N=b.end.y-b.start.y,w=Math.hypot(M,N),T=(b.routeIndex+(0===i?h.routeIndex:d.routeIndex))%2==0?1:-1,R=g\u003eh_?(I.x-C.x)/g:w\u003eh_?-N/w*T*P:P,E=g\u003eh_?(I.y-C.y)/g:w\u003eh_?M/w*T*P:0;return ZL(e,b,R*S,E*S,t,x)?{movedRouteIndex:b.routeIndex}:void 0},ED=t=\u003e{const{srj:e,via:n,segment:o,segments:i,initialTarget:r,requiredTraceDistance:s,requiredObstacleDistance:a,connMap:c}=t,l=Math.min(...n.zLayers),d=Math.max(...n.zLayers),h=e.obstacles.filter(t=\u003e!t.isCopperPour\u0026\u0026!pk(n.rootConnectionName,t,c)\u0026\u0026Qk(t,e.layerCount).some(t=\u003et\u003e=l\u0026\u0026t\u003c=d)),u=h.filter(t=\u003eBoolean(aL(r,t,a))),p=[r,...Ak(n,i,s-n.radius-o.radius,c),...u.flatMap(t=\u003e(t=\u003e{const{point:e,obstacle:n,requiredDistance:o}=t,i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=n.center.y-n.height/2,a=n.center.y+n.height/2,c=Math.max(i-e.x,e.x-r,0),l=Math.max(s-e.y,e.y-a,0),d=[];if(c\u003co){const t=Math.sqrt(o*o-c*c);d.push({x:e.x,y:s-t-h_},{x:e.x,y:a+t+h_})}if(l\u003co){const t=Math.sqrt(o*o-l*l);d.push({x:i-t-h_,y:e.y},{x:r+t+h_,y:e.y})}return d})({point:r,obstacle:t,requiredDistance:a}))];return p.filter(t=\u003e{if(!CD(t,n.radius,e.bounds))return!1;const r=nL(t,o);return!(Math.hypot(t.x-r.x,t.y-r.y)\u003cs-h_)\u0026\u0026(!i.some(e=\u003ee.z\u003e=l\u0026\u0026e.z\u003c=d\u0026\u0026!uk(n.rootConnectionName,e.rootConnectionName,c)\u0026\u0026be(t,e.start,e.end)\u003cs+e.radius-o.radius-h_)\u0026\u0026h.every(e=\u003eoL(t,e)\u003e=a-h_))}).sort((t,e)=\u003eMath.hypot(t.x-n.x,t.y-n.y)-Math.hypot(e.x-n.x,e.y-n.y))[0]},AD=(t,e,n,o,i,r)=\u003e{if(\"pcb_trace_error\"!==Fk(n))return!1;const s=\"string\"==typeof n.pcb_trace_error_id?n.pcb_trace_error_id.toLowerCase():\"\",a=\"string\"==typeof n.message?n.message.toLowerCase():\"\";if(!(\"string\"==typeof n.pcb_via_id||Array.isArray(n.pcb_via_ids)||s.includes(\"_via_\")||a.includes(\"via\")))return!1;if(bD(n,o)!==i)return!1;if(TD(n,o))return!1;const c=n.worst_contact_center??n.center;if(!c||\"object\"!=typeof c)return!1;const l=c;if(\"number\"!=typeof l.x||\"number\"!=typeof l.y)return!1;const d={x:l.x,y:l.y},h=Zk(e),u=VL(h,d,i),p=Array.isArray(n.pcb_trace_ids)?n.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t\u0026\u0026t!==n.pcb_trace_id):[],m=p.map(t=\u003eo.get(t)).filter(t=\u003evoid 0!==t),g=Gk(e),f=WL(p.length\u003e0?g.filter(t=\u003em.includes(t.routeIndex)):g,d);if(!u||!f||!f.movable||uk(f.rootConnectionName,u.rootConnectionName,r))return!1;const y=nL(f,u),_=f.x-y.x,b=f.y-y.y,x=Math.hypot(_,b),v=Number(n.minimum_clearance),S=Number.isFinite(v)?v:rk.traceClearance??.1,I=f.radius+u.radius+S-x;if(I\u003c=h_)return!1;const C=u.end.x-u.start.x,P=u.end.y-u.start.y,M=Math.hypot(C,P),N=f.routeIndex%2==0?1:-1,w=x\u003eh_?_/x:M\u003eh_?-P/M*N:1,T=x\u003eh_?b/x:M\u003eh_?C/M*N:0,R=f.radius+u.radius+S,E=f.radius+y_(t)+g_,A={x:f.x+w*(I+g_),y:f.y+T*(I+g_)},O=ED({srj:t,via:f,segment:u,segments:h,initialTarget:A,requiredTraceDistance:R,requiredObstacleDistance:E,connMap:r});return!!O\u0026\u0026$L(e,f,O.x-f.x,O.y-f.y,t)},OD=(t,e,n)=\u003e{if(\"pcb_trace_error\"!==Fk(e))return;const o=dD(e),i=t[n];if(!o||!i)return;const r=VL(Uk(i,n),o);return r?{center:o,route:i,segment:r}:void 0},kD=(t,e,n,o)=\u003e{const i=OD(t,e,n);if(!i)return;const{route:r,segment:s}=i,a=Math.max(0,s.startIndex-o),c=Math.min(r.route.length-1,s.endIndex+o),l=r.route.slice(a,c+1),d=l[0],h=l.at(-1);return d\u0026\u0026h\u0026\u0026!l.some(t=\u003et.z!==d.z)\u0026\u0026d.z===h.z?{route:r,spanStartIndex:a,spanEndIndex:c,start:d,end:h}:void 0},LD=(t,e,n,o,i,r,s=0,a,c)=\u003e{if(r\u003c0||r\u003e=t.layerCount)return!1;const l=TD(n,o);if(!l)return!1;const d=l[i],h=OD(e,n,d);if(!h||h.segment.z===r)return!1;const{route:u,segment:p}=h;let m=p.startIndex,g=p.endIndex;for(let t=0;t\u003cs;t+=1){const t=u.route[m-1];t?.z===p.z\u0026\u0026(m-=1);const e=u.route[g+1];e?.z===p.z\u0026\u0026(g+=1)}if(0===m\u0026\u0026u.route[0]?.pcb_port_id\u0026\u0026!xD(t,u,u.route[0],a,c)||g===u.route.length-1\u0026\u0026u.route.at(-1)?.pcb_port_id\u0026\u0026!xD(t,u,u.route.at(-1),a,c))return!1;const f=u.route[m],y=u.route[g];if(!f||!y||f.z!==y.z)return!1;const _=u.route.slice(m,g+1).map(t=\u003e({...t,z:r,pcb_port_id:void 0}));return u.route.splice(m,g-m+1,{...f},..._,{...y}),!0},DD=(t,e,n,o,i,r)=\u003e{if(o\u003c=0||i\u003c=0)return!1;const s=OD(t,e,n);if(!s)return!1;const{center:a,route:c,segment:l}=s,d=l.end.x-l.start.x,h=l.end.y-l.start.y,u=Math.hypot(d,h);if(u\u003c=h_)return!1;const p=nL(a,l),m=mk(p.t-o/u,.02,.98),g=mk(p.t+o/u,.02,.98);if(m\u003e=g)return!1;const f=t=\u003e({x:l.start.x+d*t,y:l.start.y+h*t,z:l.z}),y=f(m),_=f(g),b=-h/u*r,x=d/u*r,v=c.route[l.startIndex],S=c.route[l.endIndex];return c.route.splice(l.startIndex,2,{...v},y,{...y,x:y.x+b*i,y:y.y+x*i},{..._,x:_.x+b*i,y:_.y+x*i},_,{...S}),!0},zD=(t,e,n,o,i,r,s,a=!1)=\u003e{if(!Number.isInteger(i)||i\u003c0||i\u003e=t.layerCount)return!1;const c=dD(n),l=e[o],d=l?.route[0],h=l?.route.at(-1);if(!l||!c||!d||!h||d.z!==h.z||d.z===i||l.jumpers?.length||l.route.some(t=\u003et.z!==d.z||\"through_obstacle\"===t.toNextSegmentType))return!1;const u=h.x-d.x,p=h.y-d.y,m=Math.hypot(u,p);if(m\u003c=h_||m\u003e8)return!1;const g=u/m,f=p/m,y=f*r,_=-g*r,b=t=\u003e(t.x-c.x)*g+(t.y-c.y)*f,x=(t,e,n)=\u003e({x:c.x+g*t+y*e,y:c.y+f*t+_*e,z:n}),v=(l.viaDiameter??t.minViaDiameter??.3)+(t.minTraceToPadEdgeClearance??rk.traceClearance??.1),S=(a?1.25:-.75)*v,I=(a?-.75:1.25)*v,C=b(d)+.5*v*s,P=b(h)+v*s,M=x(C,S,d.z),N=x(P,I,d.z),w=x(C,2*v,i),T=x(P,2*v,i),R=[{...d},M,{...M,z:i},w,T,{...N,z:i},N,{...h}],E=t.minBoardEdgeClearance??0,A=(l.viaDiameter??t.minViaDiameter??.3)/2,O=l.traceThickness/2;if([M,N].some(e=\u003e_L(t,e)+u_\u003cA+E))return!1;for(let e=0;e\u003cR.length-1;e+=1){const n=R[e],o=R[e+1];if(n.z===o.z\u0026\u0026bL(t,n,o)+u_\u003cO+E)return!1}return l.route.splice(0,l.route.length,...R),!0},FD=(t,e,n,o,i,r,s)=\u003e{if(!Number.isInteger(i)||i\u003c1||r\u003c=0)return!1;const a=kD(e,n,o,i);if(!a)return!1;const{route:c,spanStartIndex:l,spanEndIndex:d,start:h,end:u}=a,p=u.x-h.x,m=u.y-h.y,g=Math.hypot(p,m);if(g\u003c=h_)return!1;const f=-m/g*s*r,y=p/g*s*r,_={...h,x:h.x+f,y:h.y+y,pcb_port_id:void 0},b={...u,x:u.x+f,y:u.y+y,pcb_port_id:void 0};return!(!hL(_,t.bounds)||!hL(b,t.bounds))\u0026\u0026(c.route.splice(l,d-l+1,{...h},_,b,{...u}),!0)},BD=(t,e,n,o,i,r)=\u003e{if(!Number.isInteger(i)||i\u003c0)return!1;const s=kD(e,n,o,i);if(!s)return!1;const{route:a,spanStartIndex:c,spanEndIndex:l,start:d,end:h}=s;return!(Math.hypot(r.x-d.x,r.y-d.y)\u003c=h_||Math.hypot(r.x-h.x,r.y-h.y)\u003c=h_||!hL(r,t.bounds))\u0026\u0026(a.route.splice(c,l-c+1,{...d},{x:r.x,y:r.y,z:d.z},{...h}),!0)},jD=(t,e,n,o,i,r)=\u003e{if(r){const e=mD(t),n=mD(r);if(e!==n)return e\u003cn}const s=gD(t),a=fD(t);return s\u003cn||s===n\u0026\u0026a\u003co||s===n\u0026\u0026e\u003ci},$D=(t,e,n,o,i,r,s=!0,a=!1,c=!0,l=!1)=\u003e{let d=!1;const h=Gk(e),u=Zk(e);for(const p of n){const n=dD(p);if(!n)continue;let m=n;const g=p.pcb_via_ids,f=\"pcb_via_clearance_error\"===Fk(p),y=uD(p),_=Array.isArray(g)\u0026\u0026g.length\u003e0,b=!f\u0026\u0026!y\u0026\u0026_\u0026\u0026(\"string\"==typeof p.pcb_trace_id||Array.isArray(p.pcb_trace_ids)),x=l\u0026\u0026b;if(_\u0026\u0026!b){m=cL(t,p,n);const c=bD(p,o),l=g.length\u003e1?HL(h,n):void 0;if(l){const n=a\u0026\u0026\"pcb_via_clearance_error\"===Fk(p)\u0026\u0026\"same_net\"===p.pcb_via_pair_net_relation,o=s\u0026\u0026\"pcb_via_clearance_error\"===Fk(p);d=(n?JL(e,l[0],l[1],t,r):qL(e,l[0],l[1],t,r,.16*Math.abs(i),o))||d}else{const o=WL(h,n,c);o\u0026\u0026(d=GL(e,o,m,t)||d)}continue}const v=p.pcb_trace_id,S=bD(p,o);if(x\u0026\u0026void 0===S)continue;const I=Array.isArray(p.pcb_trace_ids)?p.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[];if(x\u0026\u0026\"string\"==typeof v\u0026\u0026void 0!==S\u0026\u0026I.includes(v)\u0026\u0026I.some(t=\u003et!==v\u0026\u0026!o.has(t))){const o=WL(h,n,S);if(o){d=GL(e,o,n,t)||d;continue}}const C=s\u0026\u0026!b?TD(p,o):void 0;if(C){const o=VL(u,n,C[0]),i=VL(u,n,C[1]);if(o\u0026\u0026i\u0026\u0026QL(e,o,i,t,r)){d=!0;continue}}const P=Bk(p),M=P\u0026\u0026void 0!==S?eD(t,e,S,n,r):void 0,N=P?M?.segment:VL(u,n,S);if(N){const o=P?M?.obstacle:sL(t,n);if(P\u0026\u0026!o)continue;m=P?o?.center??n:cL(t,p,n);const s=x?void 0:WL(h,n),a=\"pcb_via_trace_clearance_error\"===Fk(p),l=\"string\"==typeof p.pcb_trace_error_id?p.pcb_trace_error_id.toLowerCase():\"\",u=\"string\"==typeof p.message?p.message.toLowerCase():\"\",g=a||\"string\"==typeof p.pcb_via_id||Array.isArray(p.pcb_via_ids)||l.includes(\"_via_\")||u.includes(\"via\"),f=Array.isArray(p.pcb_port_ids)\u0026\u0026p.pcb_port_ids.length\u003e0;if(s\u0026\u0026!uk(s.rootConnectionName,N.rootConnectionName,r)\u0026\u0026(a||Math.hypot(s.x-n.x,s.y-n.y)\u003c.45)){if(KL(e,s,N,t,r,.3*Math.abs(i),1,c)\u0026\u0026(d=!0,g\u0026\u0026!f))continue}d=(void 0!==o\u0026\u0026(P||!pk(N.rootConnectionName,o,r)\u0026\u0026tD(o,N,t.layerCount))?XL(e,N,o,t,r,i):YL(e,N,m,t,i))||d}const w=x?void 0:WL(h,n);w\u0026\u0026Math.hypot(w.x-n.x,w.y-n.y)\u003c.35\u0026\u0026(d=GL(e,w,m,t)||d)}return d},YD=1e-6,XD=.006,VD=[1,.5,.25,.1,.05,.025],WD=(t,e)=\u003e(e.traceThickness??t.minTraceWidth)/2,HD=t=\u003et.minTraceToPadEdgeClearance??.1,GD=(t,e)=\u003ee.viaDiameter??t.minViaDiameter??.3,UD=(t,e)=\u003exe(t,e)\u003cYD,ZD=t=\u003e{const e=[],n=t=\u003e{e.some(e=\u003eUD(e,t))||e.push({x:t.x,y:t.y})};for(const e of t.vias)n(e);for(let e=0;e\u003ct.route.length-1;e+=1){const o=t.route[e],i=t.route[e+1];o\u0026\u0026i\u0026\u0026o.z!==i.z\u0026\u0026(UD(o,i)\u0026\u0026n(o))}return e},qD=t=\u003exe({x:0,y:0},t)\u003cYD?{x:0,y:0}:Fe({x:0,y:0},t),JD=(t,e)=\u003e{if(t.zLayers\u0026\u0026t.zLayers.length\u003e0)return t.zLayers;const n=Array.from({length:e},(t,e)=\u003ee).filter(n=\u003et.layers.includes(Vy(n,e)));return n.length\u003e0?n:Array.from({length:e},(t,e)=\u003ee)},KD=(t,e,n)=\u003euk(dk(t),dk(e),n)||uk(dk(t),e.connectionName,n)||uk(t.connectionName,dk(e),n)||uk(t.connectionName,e.connectionName,n),QD=(t,e,n)=\u003epk(dk(t),e,n)||pk(t.connectionName,e,n),tz=(t,e,n,o)=\u003e!n.pcb_port_id\u0026\u0026t.obstacles.some(i=\u003eQD(e,i,o)\u0026\u0026JD(i,t.layerCount).includes(n.z)\u0026\u0026((t,e)=\u003et.x\u003e=e.center.x-e.width/2-YD\u0026\u0026t.x\u003c=e.center.x+e.width/2+YD\u0026\u0026t.y\u003e=e.center.y-e.height/2-YD\u0026\u0026t.y\u003c=e.center.y+e.height/2+YD)(n,i)),ez=(t,e,n,o,i)=\u003e{if(!((t,e)=\u003et.zLayers.includes(e))(i,n.z))return Number.POSITIVE_INFINITY;const r=WD(t,e);return\"pad\"===i.kind?Le(n,o,i.obstacle)-(HD(t)+r+XD):be(i.center,n,o)-(HD(t)+r+i.diameter/2+XD)},nz=(t,e,n)=\u003e{const o=\"pad\"===n.kind?n.obstacle.center:n.center,i=ze(o,t,e);let r=qD({x:i.x-o.x,y:i.y-o.y});if(Math.abs(r.x)\u003cYD\u0026\u0026Math.abs(r.y)\u003cYD){const n=e.x-t.x,i=e.y-t.y,s=$e(t,e),a=qD({x:-i,y:n}),c={x:-a.x,y:-a.y};r=xe({x:s.x+a.x,y:s.y+a.y},o)\u003e=xe({x:s.x+c.x,y:s.y+c.y},o)?a:c}return r},oz=(t,e,n,o)=\u003e{if(n\u003c=0||n\u003e=e.route.length-1){const i=e.route[n];return!i||!tz(t,e,i,o)}const i=e.route[n];if(!i||i.insideJumperPad)return!0;const r=e.route[n-1],s=e.route[n+1];return!(!r||r.z===i.z)||(!(!s||s.z===i.z)||e.vias.some(t=\u003eUD(t,i)))},iz=(t,e,n)=\u003e{let o=0;for(let i=0;i\u003ce.route.length-1;i+=1){const r=e.route[i],s=e.route[i+1];if(r\u0026\u0026s\u0026\u0026r.z===s.z\u0026\u0026!UD(r,s))for(const i of n){const n=ez(t,e,r,s,i);if(!(n\u003e=0)\u0026\u0026(o+=n*n,\"pad\"===i.kind)){if(Le(r,s,i.obstacle)\u003cYD){o+=.01/(be(i.obstacle.center,r,s)+.01)}}}}return o},rz=(t,e,n,o)=\u003e{let i=0;for(let r=0;r\u003ce.route.length-1;r+=1){const s=e.route[r],a=e.route[r+1];if(s\u0026\u0026a\u0026\u0026s.z===a.z\u0026\u0026!UD(s,a))for(const r of n)if(!KD(e,r,o)){for(let n=0;n\u003cr.route.length-1;n+=1){const o=r.route[n],c=r.route[n+1];if(!o||!c||o.z!==s.z||c.z!==s.z||UD(o,c))continue;const l=Oe(s,a,o,c)-WD(t,e)-WD(t,r),d=HD(t)+XD-l;d\u003e0\u0026\u0026(i+=d*d)}for(const n of ZD(r)){const o=be(n,s,a)-WD(t,e)-GD(t,r)/2,c=HD(t)+XD-o;c\u003e0\u0026\u0026(i+=c*c)}}}return i},sz=(t,e,n,o,i)=\u003e{const r=e.route.map(()=\u003e({x:0,y:0}));for(let s=0;s\u003ce.route.length-1;s+=1){const a=e.route[s],c=e.route[s+1];if(a\u0026\u0026c\u0026\u0026a.z===c.z\u0026\u0026!UD(a,c)){for(const o of n){const n=ez(t,e,a,c,o);if(n\u003e=0)continue;const l=nz(a,c,o);if(Math.abs(l.x)\u003cYD\u0026\u0026Math.abs(l.y)\u003cYD)continue;const d=!oz(t,e,s,i),h=!oz(t,e,s+1,i);if(!d\u0026\u0026!h)continue;const u=-n,p=d\u0026\u0026h?.5:d?1:0,m=d\u0026\u0026h?.5:h?1:0;r[s].x+=l.x*u*p,r[s].y+=l.y*u*p,r[s+1].x+=l.x*u*m,r[s+1].y+=l.y*u*m}for(const n of o)if(!KD(e,n,i))for(let o=0;o\u003cn.route.length-1;o+=1){const l=n.route[o],d=n.route[o+1];if(!l||!d||l.z!==a.z||d.z!==a.z||UD(l,d))continue;const h=Oe(a,c,l,d)-WD(t,e)-WD(t,n),u=t.minTraceToPadEdgeClearance+XD-h;if(u\u003c=0)continue;const p=$e(a,c),m=ze(p,l,d);let g=qD({x:p.x-m.x,y:p.y-m.y});if(Math.abs(g.x)\u003cYD\u0026\u0026Math.abs(g.y)\u003cYD){const t=c.x-a.x,e=c.y-a.y;g=qD({x:-e,y:t})}const f=!oz(t,e,s,i),y=!oz(t,e,s+1,i);if(!f\u0026\u0026!y)continue;const _=f\u0026\u0026y?.5:f?1:0,b=f\u0026\u0026y?.5:y?1:0;r[s].x+=g.x*u*_,r[s].y+=g.y*u*_,r[s+1].x+=g.x*u*b,r[s+1].y+=g.y*u*b}}}return r},az=(t,e,n,o,i)=\u003e({...e,route:e.route.map((r,s)=\u003e{if(oz(t,e,s,i))return{...r};const a=((t,e)=\u003e{const n=xe({x:0,y:0},t);if(n\u003c=e||n\u003cYD)return t;const o=e/n;return{x:t.x*o,y:t.y*o}})(n[s]??{x:0,y:0},.5);return{...r,x:r.x+a.x*o,y:r.y+a.y*o}}),vias:e.vias.map(t=\u003e({...t})),jumpers:e.jumpers?[...e.jumpers]:void 0}),cz=(t,e)=\u003ee.route.every(e=\u003ee.x\u003e=t.bounds.minX-YD\u0026\u0026e.x\u003c=t.bounds.maxX+YD\u0026\u0026e.y\u003e=t.bounds.minY-YD\u0026\u0026e.y\u003c=t.bounds.maxY+YD),lz=(t,e,n,o,i)=\u003e{const r=((t,e,n,o)=\u003e{const i=[];for(const e of t.obstacles)e.isCopperPour||QD(n,e,o)||i.push({kind:\"pad\",obstacle:e,zLayers:JD(e,t.layerCount)});const r=Array.from({length:t.layerCount},(t,e)=\u003ee);for(const s of e)if(s!==n\u0026\u0026!KD(n,s,o))for(const e of ZD(s))i.push({kind:\"via\",center:{x:e.x,y:e.y},diameter:GD(t,s),zLayers:r,connectionName:s.connectionName,rootConnectionName:s.rootConnectionName});return i})(t,e,n,i),s=e.filter((t,e)=\u003ee!==o\u0026\u0026t!==n);let a=n,c=iz(t,a,r)+rz(t,a,s,i);for(let e=0;e\u003c160\u0026\u0026!(c\u003c=YD);e+=1){const e=sz(t,a,r,s,i);if(e.every(t=\u003exe(t,{x:0,y:0})\u003c1e-9))break;let n=null,o=c;for(const l of VD){const d=az(t,a,e,l,i),h=iz(t,d,r)+rz(t,d,s,i);if(h\u003cc-1e-6\u0026\u0026cz(t,d)){n=d,o=h;break}}if(!n)break;a=n,c=o}return a},dz=1e-6,hz=[1,.5,.25,.1,.05,.025],uz=(t,e)=\u003et.some(t=\u003ee.includes(t)),pz=(t,e,n,o)=\u003e(pk(t.rootConnectionName,n,o)||pk(e.connectionName,n,o))\u0026\u0026oL(t,n)\u003c=dz,mz=(t,e,n,o)=\u003e{const i=[],r=e[n.routeIndex];if(!r)return i;for(const e of t.obstacles){if(e.isCopperPour||pz(n,r,e,o))continue;const s=Qk(e,t.layerCount);uz(n.zLayers,s)\u0026\u0026i.push({obstacle:e})}return i},gz=(t,e,n)=\u003eoL(e,n.obstacle)-(e.radius+t.minViaEdgeToPadEdgeClearance+.006),fz=(t,e,n,o)=\u003eGk(e,t.minViaDiameter).filter(t=\u003et.routeIndex===n).reduce((n,i)=\u003en+((t,e,n,o)=\u003e{let i=0;for(const r of mz(t,e,n,o)){const e=gz(t,n,r);!(e\u003e=0)\u0026\u0026(i+=e*e,oL(n,r.obstacle)\u003cdz)\u0026\u0026(i+=.01/(xe(n,r.obstacle.center)+.01))}return i})(t,e,i,o),0),yz=(t,e,n,o)=\u003e{const i=e[n];if(!i)return[];const r=i.route.map(()=\u003e({x:0,y:0})),s=Gk(e,t.minViaDiameter).filter(t=\u003et.routeIndex===n);for(const n of s)if(n.movable)for(const i of mz(t,e,n,o)){const e=n.radius+t.minViaEdgeToPadEdgeClearance+.006,o=aL(n,i.obstacle,e);if(o)for(const t of n.pointIndexes)r[t].x+=o.direction.x*o.penetration,r[t].y+=o.direction.y*o.penetration}return r},_z=(t,e,n,o)=\u003e{const i=new Set(Gk([e],t.minViaDiameter).flatMap(t=\u003et.movable?t.pointIndexes:[]));return{...e,route:e.route.map((t,e)=\u003e{if(!i.has(e))return{...t};const r=((t,e)=\u003e{const n=xe({x:0,y:0},t);if(n\u003c=e||n\u003cdz)return t;const o=e/n;return{x:t.x*o,y:t.y*o}})(n[e]??{x:0,y:0},.5);return{...t,x:t.x+r.x*o,y:t.y+r.y*o}}),vias:e.vias.map(t=\u003e({...t})),jumpers:e.jumpers?[...e.jumpers]:void 0}},bz=(t,e)=\u003ee.route.every(e=\u003ee.x\u003e=t.bounds.minX-dz\u0026\u0026e.x\u003c=t.bounds.maxX+dz\u0026\u0026e.y\u003e=t.bounds.minY-dz\u0026\u0026e.y\u003c=t.bounds.maxY+dz),xz=(t,e,n,o,i)=\u003e{let r=n,s=fz(t,e,o,i);for(let n=0;n\u003c160\u0026\u0026!(s\u003c=dz);n+=1){const n=yz(t,e,o,i);if(n.every(t=\u003exe(t,{x:0,y:0})\u003c1e-9))break;let a=null,c=s;for(const l of hz){const d=_z(t,r,n,l),h=[...e];h[o]=d;const u=fz(t,h,o,i);if(u\u003cs-1e-6\u0026\u0026bz(t,d)){a=d,c=u;break}}if(!a)break;e[o]=a,r=a,s=c}return r},vz=[.2,.4,.8,1.2].flatMap(t=\u003e[.2,.3,.45,.6].flatMap(e=\u003e[-1,1].map(n=\u003e({halfSpan:t,offset:e,directionSign:n})))),Sz=vz.flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,...t}))),Iz=[1,-1].flatMap(t=\u003e[1,-1].flatMap(e=\u003e[!1,!0].flatMap(n=\u003e[0,1].map(o=\u003e({routeSide:o,normalDirectionSign:t,tangentDirectionSign:e,reverseEndpointOffsets:n}))))),Cz=[0,1].map(t=\u003e({kind:\"displacementChain\",routeSide:t})),Pz=[...Cz,...[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,halfSpan:.4,offset:1.2,directionSign:t}))),...[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"span\",routeSide:e,spanExpansion:3,offset:1.8,directionSign:t}))),...[{dx:-2.4,dy:-.4},{dx:-2.4,dy:.4},{dx:2.4,dy:-.4},{dx:2.4,dy:.4},{dx:-.4,dy:-2.4},{dx:-.4,dy:2.4},{dx:.4,dy:-2.4},{dx:.4,dy:2.4}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:2,...t}))),...[{dx:-.17,dy:0},{dx:.17,dy:0},{dx:0,dy:-.17},{dx:0,dy:.17}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:0,...t}))),...Sz],Mz=[0,1,2],Nz=class extends kt{srj;inputHdRoutes;guardedInputHdRoutes;connMap;effort;drcEvaluator;referenceDrcEvaluator;autoroutingDrcEngine;viaHoleDiameter;configuredMaxIterations;enableBroadFallback;enableLargeBoardBroadFallback;enableTargetedErrorSweep;enablePostSolveClearanceRelaxation;enableSafeTraceLayerMoves;enableViaInPadLayerMoves;enableTraceViaOwnerTargeting;outputHdRoutes;initialDrcIssueCount;initialRepairDrcIssueCount;initialLowCountErrorsHaveMovableTraces=!1;broadForceAccepted=!1;targetedForceAccepted=!1;candidateAttempts=0;viaInPadCandidateAttempts=0;viaInPadCandidatesAccepted=0;padTopologyErrorCursor=0;safeTraceLayerCursorByErrorId=new Map;traceLayerCorridorCursorByErrorId=new Map;tracePairDetourCursorByErrorId=new Map;errorCursor=0;stalledIterations=0;bestDrcIssueCountSeen;bestDrcIssueScoreSeen;lastDrcCountImprovementCheckIteration=0;drcCountPlateauChecks=0;largeBoardBroadFallbackMisses=0;outputSnapshot;legacyCleanCheckpoint;viaPadRepairRolledBack=!1;referenceInputDrcIssueCount;referenceCandidateDrcIssueCount;referenceCandidateRolledBack=!1;referenceInputSnapshot;inputSnapshot;constructor(t){if(super(),this.srj=t.srj,this.inputHdRoutes=t.hdRoutes,this.guardedInputHdRoutes=aD(kk(t.hdRoutes)),this.connMap=t.connMap,this.effort=t.effort??1,this.drcEvaluator=t.drcEvaluator,this.referenceDrcEvaluator=t.referenceDrcEvaluator,this.autoroutingDrcEngine=t.autoroutingDrcEngine??(t.drcEvaluator?void 0:new s_(t.srj,{connMap:t.connMap,traceClearance:t.srj.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:t.srj.minTraceToPadEdgeClearance??rk.viaClearance,includeTraceViaOwnerMetadata:t.enableTraceViaOwnerTargeting??!1})),void 0!==t.viaHoleDiameter\u0026\u0026(!Number.isFinite(t.viaHoleDiameter)||t.viaHoleDiameter\u003c=0))throw new Error(\"viaHoleDiameter must be a positive finite number\");this.viaHoleDiameter=t.viaHoleDiameter,this.configuredMaxIterations=t.maxIterations,this.enableBroadFallback=t.enableBroadFallback??!0,this.enableLargeBoardBroadFallback=t.enableLargeBoardBroadFallback??!0,this.enableTargetedErrorSweep=t.enableTargetedErrorSweep??!1,this.enablePostSolveClearanceRelaxation=t.enablePostSolveClearanceRelaxation??!0,this.enableSafeTraceLayerMoves=t.enableSafeTraceLayerMoves??!1,this.enableViaInPadLayerMoves=t.enableViaInPadLayerMoves??!1,this.enableTraceViaOwnerTargeting=t.enableTraceViaOwnerTargeting??!1,this.outputHdRoutes=t.hdRoutes,this.referenceDrcEvaluator\u0026\u0026(this.referenceInputSnapshot=this.getReferenceDrcSnapshot(this.inputHdRoutes)),this.MAX_ITERATIONS=this.configuredMaxIterations??__(this.effort)}getConstructorParams(){return[{srj:this.srj,hdRoutes:this.inputHdRoutes,connMap:this.connMap,effort:this.effort,drcEvaluator:this.drcEvaluator,referenceDrcEvaluator:this.referenceDrcEvaluator,autoroutingDrcEngine:this.autoroutingDrcEngine,viaHoleDiameter:this.viaHoleDiameter,maxIterations:this.configuredMaxIterations,enableBroadFallback:this.enableBroadFallback,enableLargeBoardBroadFallback:this.enableLargeBoardBroadFallback,enableTargetedErrorSweep:this.enableTargetedErrorSweep,enablePostSolveClearanceRelaxation:this.enablePostSolveClearanceRelaxation,enableSafeTraceLayerMoves:this.enableSafeTraceLayerMoves,enableViaInPadLayerMoves:this.enableViaInPadLayerMoves,enableTraceViaOwnerTargeting:this.enableTraceViaOwnerTargeting}]}updateStats(t){this.stats={initialDrcIssueCount:this.initialDrcIssueCount??t.count,finalDrcIssueCount:t.count,globalDrcForceImproveMaxIterations:this.MAX_ITERATIONS,globalDrcForceImproveBroadForceAccepted:this.broadForceAccepted,globalDrcForceImproveTargetedForceAccepted:this.targetedForceAccepted,globalDrcForceImproveCandidateAttempts:this.candidateAttempts,globalDrcForceImproveViaInPadCandidateAttempts:this.viaInPadCandidateAttempts,globalDrcForceImproveViaInPadCandidatesAccepted:this.viaInPadCandidatesAccepted,globalDrcForceImproveStalledIterations:this.stalledIterations,globalDrcForceImproveBestDrcIssueCountSeen:this.bestDrcIssueCountSeen??t.count,globalDrcForceImproveBestDrcIssueScoreSeen:this.bestDrcIssueScoreSeen??t.issueScore,globalDrcForceImproveDrcCountPlateauChecks:this.drcCountPlateauChecks,globalDrcForceImproveLargeBoardBroadFallbackMisses:this.largeBoardBroadFallbackMisses,globalDrcForceImproveViaPadRepairRolledBack:this.viaPadRepairRolledBack,globalDrcForceImproveReferenceInputDrcIssueCount:this.referenceInputDrcIssueCount,globalDrcForceImproveReferenceCandidateDrcIssueCount:this.referenceCandidateDrcIssueCount,globalDrcForceImproveReferenceCandidateRolledBack:this.referenceCandidateRolledBack}}finishAtLegacyCleanCheckpoint(){const t=this.legacyCleanCheckpoint;return!!t\u0026\u0026(this.outputHdRoutes=t.routes,this.outputSnapshot=t.snapshot,this.viaPadRepairRolledBack=!0,this.updateStats(t.snapshot),this.solved=!0,!0)}increaseMaxIterationsForDrcIssueCount(t){void 0===this.configuredMaxIterations?this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,((t,e)=\u003eMath.max(__(e),Math.ceil(t*d_*Math.max(1,e))))(t,this.effort),((t,e)=\u003et\u003e120\u0026\u0026e\u003e0?192:48)(this.inputHdRoutes.length,t)):this.MAX_ITERATIONS=this.configuredMaxIterations}getSnapshot(t){return(this.initialLowCountErrorsHaveMovableTraces?Hk:Wk)(this.srj,t,this.drcEvaluator,this.connMap,this.autoroutingDrcEngine)}getReferenceDrcSnapshot(t){const e={traces:[],srj:this.srj,routes:t,hdRoutes:t},n=this.referenceDrcEvaluator?.getCachedResult?.(e);if(n){const t=Array.isArray(n)?n:n.errors;return{errors:t,count:t.length}}return Wk(this.srj,t,this.referenceDrcEvaluator,this.connMap,this.autoroutingDrcEngine)}getViaIssueCount(t){return hD(t)}getRepairIssueCount(t){return gD(t)}getRepairIssueScore(t){return fD(t)}acceptSolvedRoutes(t,e){const n=this.enablePostSolveClearanceRelaxation?((t,e,n)=\u003e{if(void 0===t.minTraceToPadEdgeClearance||t.minTraceToPadEdgeClearance\u003c=0)return e;let o=!1;const i=kk(e);for(let e=0;e\u003c4;e+=1)for(let e=0;e\u003ci.length;e+=1){const r=i[e];if(!r)continue;const s=lz(t,i,r,e,n);s!==r\u0026\u0026(i[e]=s,o=!0)}return o?i:e})(this.srj,t,this.connMap):t,o=this.enablePostSolveClearanceRelaxation?((t,e,n)=\u003e{if(void 0===t.minViaEdgeToPadEdgeClearance||t.minViaEdgeToPadEdgeClearance\u003c=0)return e;let o=!1;const i=kk(e);for(let e=0;e\u003c4;e+=1)for(let e=0;e\u003ci.length;e+=1){const r=i[e];if(!r)continue;const s=xz(t,i,r,e,n);s!==r\u0026\u0026(i[e]=s,o=!0)}return o?aD(i):e})(this.srj,n,this.connMap):t,i=o===t?e:this.getSnapshot(o),r=i.count\u003ce.count||i.count===e.count\u0026\u0026i.issueScore\u003c=e.issueScore;let s=r?o:t,a=r?i:e;const c=this.inputSnapshot??this.getSnapshot(this.guardedInputHdRoutes);if(this.referenceDrcEvaluator){const t=this.referenceInputSnapshot,e=this.getReferenceDrcSnapshot(s);this.referenceInputDrcIssueCount=t.count,this.referenceCandidateDrcIssueCount=e.count,e.count\u003et.count\u0026\u0026(s=this.guardedInputHdRoutes,a=c,this.referenceCandidateRolledBack=!0)}this.outputHdRoutes=s,this.outputSnapshot=a,this.stalledIterations=0,this.updateStats(a),this.solved=!0}updateDrcCountPlateauState(t){const e=this.getRepairIssueCount(t),n=this.getRepairIssueScore(t);this.bestDrcIssueCountSeen??=e,this.bestDrcIssueScoreSeen??=n;const o=this.initialRepairDrcIssueCount??e,i=this.inputHdRoutes.length\u003e120\u0026\u0026o\u003e0;if((o\u003e=20||i)\u0026\u0026this.iterations\u003c192)return(e\u003cthis.bestDrcIssueCountSeen||e===this.bestDrcIssueCountSeen\u0026\u0026n\u003cthis.bestDrcIssueScoreSeen)\u0026\u0026(this.bestDrcIssueCountSeen=e,this.bestDrcIssueScoreSeen=n),void(i\u0026\u0026this.largeBoardBroadFallbackMisses\u003e=2\u0026\u0026(this.solved=!0));const r=(t=\u003et\u003e=20?8:t\u003c=2?1:2)(o);if(!(this.iterations-this.lastDrcCountImprovementCheckIteration\u003cr)){if(this.lastDrcCountImprovementCheckIteration=this.iterations,e\u003cthis.bestDrcIssueCountSeen||e===this.bestDrcIssueCountSeen\u0026\u0026n\u003cthis.bestDrcIssueScoreSeen)return this.bestDrcIssueCountSeen=e,this.bestDrcIssueScoreSeen=n,void(this.drcCountPlateauChecks=0);this.drcCountPlateauChecks+=1,this.drcCountPlateauChecks\u003e=2\u0026\u0026(this.solved=!0)}}_step(){let t=this.outputHdRoutes,e=this.outputSnapshot??this.getSnapshot(t);const n=mD(e);if(this.legacyCleanCheckpoint\u0026\u0026n\u003e0)return void this.finishAtLegacyCleanCheckpoint();if(!this.legacyCleanCheckpoint\u0026\u00260===n\u0026\u0026e.errors.some(uD)\u0026\u0026(this.legacyCleanCheckpoint={routes:aD(kk(t)),snapshot:e}),void 0===this.initialDrcIssueCount){this.inputSnapshot=e,this.initialDrcIssueCount=e.count,this.initialRepairDrcIssueCount=this.getRepairIssueCount(e);const n=_D(e.errors);this.initialLowCountErrorsHaveMovableTraces=this.initialRepairDrcIssueCount\u003e0\u0026\u0026this.initialRepairDrcIssueCount\u003c=3\u0026\u0026n.every(t=\u003evoid 0!==bD(t,e.traceRouteIndexById)),this.initialLowCountErrorsHaveMovableTraces\u0026\u0026(e=this.getSnapshot(t)),this.bestDrcIssueCountSeen=this.getRepairIssueCount(e),this.bestDrcIssueScoreSeen=this.getRepairIssueScore(e),this.increaseMaxIterationsForDrcIssueCount(this.getRepairIssueCount(e))}if(0===e.count)return void this.acceptSolvedRoutes(t,e);let o=this.getRepairIssueCount(e),i=this.getRepairIssueScore(e),r=this.getViaIssueCount(e);const s=e.errors.filter(t=\u003eBoolean(dD(t)));if(0===s.length)return void this.acceptSolvedRoutes(t,e);const a=(c=this.effort,Math.max(1,Math.round(3*Math.max(1,c))));var c;let l=0,d=0,h=!1,u=!1,p=!1;const m=_D(s),g=this.enableTargetedErrorSweep?m.find(t=\u003e\"pcb_via_clearance_error\"===t.type\u0026\u0026\"same_net\"===t.pcb_via_pair_net_relation):void 0,f=this.enableTargetedErrorSweep\u0026\u0026(this.iterations-1)%8==0,y=g??(f?m.find(t=\u003e\"pcb_via_clearance_error\"===t.type):void 0),_=y?[y,...m.filter(t=\u003et!==y)]:m,b=Math.min(_.length,Math.max(1,Math.ceil(this.effort))),x=y?0:this.errorCursor%_.length,v=this.enableTargetedErrorSweep?((t,e)=\u003e{const n=Math.max(2,Math.round(12*Math.max(1,e)));return t.filter(t=\u003e\"pcb_trace_error\"===Fk(t)).slice(0,n)})(s,this.effort):[],S=o\u003c=1||this.initialLowCountErrorsHaveMovableTraces,I=!this.initialLowCountErrorsHaveMovableTraces\u0026\u0026o\u003c=8\u0026\u0026this.srj.layerCount\u003e1,C=y?[]:s.filter(t=\u003e\"pcb_pad_trace_clearance_error\"===t.type||(this.enableSafeTraceLayerMoves||S||I)\u0026\u0026\"pcb_trace_error\"===t.type),P=C.map((t,e)=\u003eC[(this.padTopologyErrorCursor+e)%C.length]);for(const n of this.enableSafeTraceLayerMoves||this.enableViaInPadLayerMoves?P:[]){const s=!this.enableSafeTraceLayerMoves||d\u003e=a,c=!this.enableViaInPadLayerMoves||l\u003e=a;if(u||s\u0026\u0026c)break;let p;this.padTopologyErrorCursor=(C.indexOf(n)+1)%C.length;const m=\"string\"==typeof n.pcb_trace_error_id?n.pcb_trace_error_id:\"string\"==typeof n.pcb_trace_id?n.pcb_trace_id:void 0,g=bD(n,e.traceRouteIndexById),f=TD(n,e.traceRouteIndexById);if(this.enableTraceViaOwnerTargeting\u0026\u0026void 0!==g\u0026\u0026Array.isArray(n.pcb_via_ids)\u0026\u00261===n.pcb_via_ids.length\u0026\u0026l\u003ca){const o=kk(t);if(AD(this.srj,o,n,e.traceRouteIndexById,g,this.connMap)){const t=aD(o),n=this.getSnapshot(t),i=this.getViaIssueCount(n);l+=1,this.candidateAttempts+=1,i\u003c=r\u0026\u0026yD(n,e)\u0026\u0026(p={routes:t,snapshot:n,viaIssueCount:i,usesViaInPad:!1})}}if(this.enableSafeTraceLayerMoves\u0026\u0026void 0!==g){const o=f??[g],i=o.length*this.srj.layerCount*Mz.length,s=o.length*this.srj.layerCount*ID,c=i+s,l=Bk(n),h=l?0:i,u=l?s:0;let y=m?this.safeTraceLayerCursorByErrorId.get(m)??0:0,_=0;for(;d\u003ca\u0026\u0026_\u003cc;){const i=y;y=(y+1)%c,_+=1;const a=i\u003e=h\u0026\u0026i\u003ch+s,l=i-(a?h:u),m=l%o.length,g=Math.floor(l/o.length),f=g%this.srj.layerCount,b=a?\"full\":Mz[Math.floor(g/this.srj.layerCount)%Mz.length],x=a?Math.floor(g/this.srj.layerCount):0,v=o[m];let S=!1;for(const o of[!1,!0]){const i=Lk(t,[v]);if(!MD(this.srj,i,n,v,f,b,this.connMap,x,o))continue;const s=cD(i,[v]);S=!0,this.candidateAttempts+=1;const a=this.getSnapshot(s),c=this.getViaIssueCount(a),l=p?.snapshot??e;c\u003c=(p?.viaIssueCount??r)\u0026\u0026(yD(a,l)||void 0!==p\u0026\u0026gD(a)===gD(l)\u0026\u0026a.count\u003cl.count)\u0026\u0026(p={routes:s,snapshot:a,viaIssueCount:c,usesViaInPad:!1})}S\u0026\u0026(d+=1)}m\u0026\u0026this.safeTraceLayerCursorByErrorId.set(m,y)}if(this.enableSafeTraceLayerMoves\u0026\u0026I\u0026\u0026m\u0026\u0026f){let o=this.traceLayerCorridorCursorByErrorId.get(m)??0,i=0;for(;l\u003ca\u0026\u0026i\u003cIz.length;){const s=Iz[o%Iz.length];o+=1,i+=1;const a=f[s.routeSide],c=t[a]?.route[0]?.z;if(void 0===c)continue;const d=(c+1)%this.srj.layerCount,h=Lk(t,[a]);if(!zD(this.srj,h,n,a,d,s.normalDirectionSign,s.tangentDirectionSign,s.reverseEndpointOffsets))continue;const u=cD(h,[a]);l+=1,this.candidateAttempts+=1;const m=this.getSnapshot(u),g=this.getViaIssueCount(m),y=p?.snapshot??e;g\u003c=(p?.viaIssueCount??r)\u0026\u0026yD(m,y)\u0026\u0026(p={routes:u,snapshot:m,viaIssueCount:g,usesViaInPad:!1})}this.traceLayerCorridorCursorByErrorId.set(m,o)}if(this.enableSafeTraceLayerMoves\u0026\u0026m\u0026\u0026(this.initialLowCountErrorsHaveMovableTraces\u0026\u0026(f||void 0!==g)||!this.initialLowCountErrorsHaveMovableTraces\u0026\u0026f)){const s=this.initialLowCountErrorsHaveMovableTraces?Pz:S?[...Cz,...Sz]:Cz,c=f??[g];let d=this.tracePairDetourCursorByErrorId.get(m)??0,u=0;for(;l\u003ca\u0026\u0026u\u003cs.length;){const m=s[d%s.length];d+=1,u+=1;const g=c[m.routeSide];if(void 0===g)continue;const f=this.initialLowCountErrorsHaveMovableTraces\u0026\u0026n.worst_contact_center?{...n,center:n.worst_contact_center,message:n.worst_contact_message??n.message,actual_clearance:n.worst_actual_clearance??n.actual_clearance}:n;if(\"displacementChain\"===m.kind){const n=kk(t),s=RD(this.srj,n,f,e.traceRouteIndexById,m.routeSide);if(!s)continue;h=!0,l+=1,this.candidateAttempts+=1;let c=aD(n),d=this.getSnapshot(c),u=this.getViaIssueCount(d),g=this.getRepairIssueCount(d);if(g\u003e0\u0026\u0026l\u003ca){const t=kk(c);let e=!1;for(const n of d.errors)e=AD(this.srj,t,n,d.traceRouteIndexById,s.movedRouteIndex,this.connMap)||e;if(e){l+=1,this.candidateAttempts+=1;const e=aD(t),n=this.getSnapshot(e),o=this.getViaIssueCount(n);jD(n,o,g,this.getRepairIssueScore(d),u,d)\u0026\u0026(c=e,d=n,u=o,g=this.getRepairIssueCount(d))}}const y=p?this.getRepairIssueCount(p.snapshot):o,_=p?this.getRepairIssueScore(p.snapshot):i,b=p?.viaIssueCount??r;if(u\u003c=b\u0026\u0026jD(d,u,y,_,b,p?.snapshot??e)\u0026\u0026(p={routes:c,snapshot:d,viaIssueCount:u,usesViaInPad:!1}),0===g)break;continue}const y=Lk(t,[g]);if(!(\"segment\"===m.kind?DD(y,f,g,m.halfSpan,m.offset,m.directionSign):\"span\"===m.kind?FD(this.srj,y,f,g,m.spanExpansion,m.offset,m.directionSign):BD(this.srj,y,f,g,m.spanExpansion,{x:f.center.x+m.dx,y:f.center.y+m.dy})))continue;const _=cD(y,[g]);h=!0,l+=1,this.candidateAttempts+=1;const b=this.getSnapshot(_),x=this.getViaIssueCount(b),v=p?this.getRepairIssueCount(p.snapshot):o,S=p?this.getRepairIssueScore(p.snapshot):i,I=p?.viaIssueCount??r;(this.initialLowCountErrorsHaveMovableTraces?jD(b,x,v,S,I,p?.snapshot??e):x\u003c=I\u0026\u0026yD(b,p?.snapshot??e))\u0026\u0026(p={routes:_,snapshot:b,viaIssueCount:x,usesViaInPad:!1})}this.tracePairDetourCursorByErrorId.set(m,d)}for(const s of this.enableViaInPadLayerMoves?[\"start\",\"end\"]:[]){if(l\u003e=a)break;if(void 0===g)break;const c=Lk(t,[g]);if(!wD(this.srj,c,n,e.traceRouteIndexById,s,this.connMap,this.viaHoleDiameter))continue;const d=cD(c,[g]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const h=this.getSnapshot(d),u=this.getViaIssueCount(h),m=p?this.getRepairIssueCount(p.snapshot):o,f=p?this.getRepairIssueScore(p.snapshot):i;jD(h,u,m,f,p?.viaIssueCount??r,p?.snapshot??e)\u0026\u0026(p={routes:d,snapshot:h,viaIssueCount:u,usesViaInPad:!0})}const y=this.enableViaInPadLayerMoves?this.srj.layerCount:0;for(let s=0;s\u003cy\u0026\u0026!(l\u003e=a)\u0026\u0026void 0!==g;s+=1){const a=Lk(t,[g]);if(!ND(this.srj,a,n,e.traceRouteIndexById,s,this.connMap,this.viaHoleDiameter))continue;const c=cD(a,[g]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const d=this.getSnapshot(c),h=this.getViaIssueCount(d),u=p?this.getRepairIssueCount(p.snapshot):o,m=p?this.getRepairIssueScore(p.snapshot):i;jD(d,h,u,m,p?.viaIssueCount??r,p?.snapshot??e)\u0026\u0026(p={routes:c,snapshot:d,viaIssueCount:h,usesViaInPad:!0})}if(this.enableViaInPadLayerMoves\u0026\u0026S\u0026\u0026f){const s=this.iterations%2==0?[0,1]:[1,0],c=this.iterations%3;for(const d of s)for(let s=0;s\u003cthis.srj.layerCount\u0026\u0026!(l\u003e=a);s+=1){const a=f[d],h=Lk(t,[a]);if(!LD(this.srj,h,n,e.traceRouteIndexById,d,s,c,this.connMap,this.viaHoleDiameter))continue;const u=cD(h,[a]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const m=this.getSnapshot(u),g=this.getViaIssueCount(m),y=p?this.getRepairIssueCount(p.snapshot):o,_=p?this.getRepairIssueScore(p.snapshot):i;jD(m,g,y,_,p?.viaIssueCount??r,p?.snapshot??e)\u0026\u0026(p={routes:u,snapshot:m,viaIssueCount:g,usesViaInPad:!0})}}p\u0026\u0026(t=p.routes,e=p.snapshot,o=this.getRepairIssueCount(e),i=this.getRepairIssueScore(e),r=p.viaIssueCount,this.targetedForceAccepted=!0,p.usesViaInPad\u0026\u0026(this.viaInPadCandidatesAccepted+=1),u=!0)}if(!u\u0026\u0026v.length\u003e=2){const n=kk(t);let s=!1;for(const t of v)s=$D(this.srj,n,[t],e.traceRouteIndexById,1,this.connMap,!0,this.enableTargetedErrorSweep,!1,this.enableTraceViaOwnerTargeting)||s;if(s){const s=aD(n);l+=1,this.candidateAttempts+=1;const a=this.getSnapshot(s),c=this.getViaIssueCount(a);if(jD(a,c,o,i,r,e)\u0026\u0026(t=s,e=a,o=this.getRepairIssueCount(a),i=this.getRepairIssueScore(a),r=c,this.targetedForceAccepted=!0,u=!0,0===a.count))return void this.acceptSolvedRoutes(t,e)}}for(let n=0;n\u003cb\u0026\u0026l\u003ca\u0026\u0026!u;n+=1){const s=(x+n)%_.length,c=_[s];if(!c)continue;this.errorCursor=(s+1)%_.length;const d=1===o;for(const n of b_(this.effort)){if(l\u003e=a)break;const s=kk(t);if(!$D(this.srj,s,[c],e.traceRouteIndexById,n,this.connMap,!0,this.enableTargetedErrorSweep,d,this.enableTraceViaOwnerTargeting))continue;const h=aD(s);l+=1,this.candidateAttempts+=1;const p=this.getSnapshot(h),m=this.getViaIssueCount(p);if(jD(p,m,o,i,r,e)){if(t=h,e=p,o=this.getRepairIssueCount(p),i=this.getRepairIssueScore(p),r=m,this.targetedForceAccepted=!0,u=!0,0===p.count)return void this.acceptSolvedRoutes(t,e);break}}if(u)break}const M=t.length\u003c=120,N=(w=s.length,Math.max(16,Math.min(64,2*w)));var w;const T=this.enableLargeBoardBroadFallback\u0026\u0026this.MAX_ITERATIONS\u003e=192\u0026\u0026!M\u0026\u0026this.stalledIterations\u003e0\u0026\u0026this.stalledIterations%N===0;if(this.enableBroadFallback\u0026\u0026!u\u0026\u0026(M||this.effort\u003e=2\u0026\u0026this.stalledIterations\u003e=2||T)){p=T;for(const n of[1,2]){const s=iD(this.srj,t,this.effort,n,this.connMap,void 0===this.drcEvaluator,!1);if(s===t)continue;const a=this.getSnapshot(s),c=this.getViaIssueCount(a);if(jD(a,c,o,i,r,e)\u0026\u0026(t=s,e=a,o=this.getRepairIssueCount(a),i=this.getRepairIssueScore(a),r=c,this.broadForceAccepted=!0,u=!0,0===a.count))return void this.acceptSolvedRoutes(t,e)}}u?this.largeBoardBroadFallbackMisses=0:p\u0026\u0026(this.largeBoardBroadFallbackMisses+=1),this.outputHdRoutes=t,this.outputSnapshot=e,this.stalledIterations=u?0:this.stalledIterations+1,h||this.updateDrcCountPlateauState(e),this.updateStats(e),(this.solved||0===o)\u0026\u0026this.acceptSolvedRoutes(t,e)}tryFinalAcceptance(){const t=this.outputSnapshot??this.getSnapshot(this.outputHdRoutes);this.legacyCleanCheckpoint\u0026\u0026mD(t)\u003e0\u0026\u0026this.finishAtLegacyCleanCheckpoint()||this.acceptSolvedRoutes(this.outputHdRoutes,t)}getOutput(){return this.outputHdRoutes}visualize(){return super.visualize()}preview(){return this.visualize()}},wz=class extends kt{params;inputHdRoutes;guardedInputHdRoutes;broadMaxIterations;broadPassMultiplier;autoroutingDrcEngine;legacyDrcEvaluator;outputHdRoutes;phase=\"start\";inputSnapshot;baselineSolver;baselineSnapshot;broadInputSnapshot;broadSnapshot;broadSolver;safeTraceLayerInputRoutes;safeTraceLayerInputSnapshot;safeTraceLayerSolver;safeTraceLayerPhaseAccepted=!1;mixedSafeTraceLayerSolver;mixedSafeTraceLayerPhaseAccepted=!1;legacySafeTraceLayerRoutes;legacySafeTraceLayerSnapshot;legacySafeTraceLayerSelectedSolver;viaInPadSolver;portfolioSelectedSolver;selectedSolver;referenceInputDrcIssueCount;referenceCandidateDrcIssueCount;referenceCandidateRolledBack=!1;mixedReferenceInputDrcIssueCount;mixedReferenceCandidateDrcIssueCount;referenceInputSnapshot;constructor(t){if(super(),!Number.isFinite(t.broadPassMultiplier))throw new Error(\"broadPassMultiplier must be a finite number\");if(t.broadPassMultiplier\u003c=0)throw new Error(\"broadPassMultiplier must be greater than zero\");if(!Number.isInteger(t.broadMaxIterations))throw new Error(\"broadMaxIterations must be an integer\");if(t.broadMaxIterations\u003c=0)throw new Error(\"broadMaxIterations must be greater than zero\");if(void 0!==t.viaInPadMaxIterations\u0026\u0026!Number.isInteger(t.viaInPadMaxIterations))throw new Error(\"viaInPadMaxIterations must be an integer\");if(void 0!==t.viaInPadMaxIterations\u0026\u0026t.viaInPadMaxIterations\u003c=0)throw new Error(\"viaInPadMaxIterations must be greater than zero\");this.autoroutingDrcEngine=t.autoroutingDrcEngine??(t.drcEvaluator?void 0:new s_(t.srj,{connMap:t.connMap,traceClearance:t.srj.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:t.srj.minTraceToPadEdgeClearance??rk.viaClearance,includeTraceViaOwnerMetadata:t.enableTraceViaOwnerTargeting??!1})),this.legacyDrcEvaluator=e=\u003e{const n=t.drcEvaluator?.evaluateLegacy??t.drcEvaluator,o=n?n(e):this.autoroutingDrcEngine.evaluateLegacy(e.traces),i=Array.isArray(o)?o:o.errors,r=Array.isArray(o)?o:o.errorsWithCenters??o.errors;return{errors:i.filter(t=\u003e!uD(t)),errorsWithCenters:r.filter(t=\u003e!uD(t))}},this.params={...t,autoroutingDrcEngine:this.autoroutingDrcEngine},this.inputHdRoutes=t.hdRoutes,this.guardedInputHdRoutes=aD(kk(t.hdRoutes)),this.broadMaxIterations=t.broadMaxIterations,this.broadPassMultiplier=t.broadPassMultiplier,this.outputHdRoutes=t.hdRoutes,this.params.referenceDrcEvaluator\u0026\u0026(this.referenceInputSnapshot=this.getReferenceDrcSnapshot(this.inputHdRoutes))}getConstructorParams(){return[{...this.params,hdRoutes:this.inputHdRoutes}]}stepBranch(t,e){if(this.activeSubSolver=t,t.step(),t.failed)throw new Error(`${e} DRC repair branch failed: ${t.error}`)}getReferenceDrcSnapshot(t){const e={traces:[],srj:this.params.srj,routes:t,hdRoutes:t},n=this.params.referenceDrcEvaluator?.getCachedResult?.(e);if(n){const t=Array.isArray(n)?n:n.errors;return{errors:t,count:t.length}}return Wk(this.params.srj,t,this.params.referenceDrcEvaluator,this.params.connMap,this.autoroutingDrcEngine)}finishWithOutput(t,e,n){let o=t,i=e;if(this.params.referenceDrcEvaluator){const t=this.referenceInputSnapshot,e=this.getReferenceDrcSnapshot(o);this.referenceInputDrcIssueCount=t.count,this.referenceCandidateDrcIssueCount=e.count,(e.count\u003et.count||e.count===t.count\u0026\u0026((t,e)=\u003e{const n=new Set(e.map(pD));return t.some(t=\u003e!n.has(pD(t)))})(e.errors,t.errors))\u0026\u0026(o=this.guardedInputHdRoutes,i=this.inputSnapshot,this.referenceCandidateRolledBack=!0)}this.outputHdRoutes=o,this.selectedSolver=n,this.activeSubSolver=null,this.phase=\"done\",this.progress=1,this.stats={...this.portfolioSelectedSolver?.stats??{},...n?.stats??{},finalDrcIssueCount:i.count,drcBranchPortfolioInitialDrcIssueCount:this.inputSnapshot?.count??e.count,drcBranchPortfolioBaselineDrcIssueCount:this.baselineSnapshot?.count??e.count,drcBranchPortfolioBroadInitialDrcIssueCount:this.broadInputSnapshot?.count,drcBranchPortfolioBroadFinalDrcIssueCount:this.broadSnapshot?.count,drcBranchPortfolioBroadMaxIterations:this.broadMaxIterations,drcBranchPortfolioBroadBranchAttempted:Boolean(this.broadSolver),drcBranchPortfolioBroadBranchAccepted:void 0!==this.portfolioSelectedSolver\u0026\u0026this.portfolioSelectedSolver===this.broadSolver,drcBranchPortfolioSafeTraceLayerPhaseAttempted:Boolean(this.safeTraceLayerSolver),drcBranchPortfolioSafeTraceLayerPhaseAccepted:this.safeTraceLayerPhaseAccepted,drcBranchPortfolioMixedSafeTraceLayerPhaseAttempted:Boolean(this.mixedSafeTraceLayerSolver),drcBranchPortfolioMixedSafeTraceLayerPhaseAccepted:this.mixedSafeTraceLayerPhaseAccepted,drcBranchPortfolioViaInPadPhaseAttempted:Boolean(this.viaInPadSolver),drcBranchPortfolioViaInPadMaxIterations:this.params.viaInPadMaxIterations,drcBranchPortfolioFinalNonViaPadDrcIssueCount:mD(i),drcBranchPortfolioReferenceInputDrcIssueCount:this.referenceInputDrcIssueCount,drcBranchPortfolioReferenceCandidateDrcIssueCount:this.referenceCandidateDrcIssueCount,drcBranchPortfolioReferenceCandidateRolledBack:this.referenceCandidateRolledBack,drcBranchPortfolioMixedReferenceInputDrcIssueCount:this.mixedReferenceInputDrcIssueCount,drcBranchPortfolioMixedReferenceCandidateDrcIssueCount:this.mixedReferenceCandidateDrcIssueCount},this.solved=!0}startBaselineBranch(){this.baselineSolver=new Nz({...this.params,hdRoutes:this.inputHdRoutes,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.baselineSolver,this.phase=\"baseline\"}startSafeTraceLayerPhase(t,e,n){this.portfolioSelectedSolver=n,this.params.enableSafeTraceLayerMoves?(this.safeTraceLayerInputRoutes=t,this.safeTraceLayerInputSnapshot=e,this.safeTraceLayerSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.safeTraceLayerSolver,this.phase=\"safeTraceLayer\"):this.startViaInPadPhase(t,e,n)}startViaInPadPhase(t,e,n){this.portfolioSelectedSolver=n;const o=this.params.enableViaInPadLayerMoves\u0026\u0026void 0!==this.params.viaInPadDrcEvaluator;e.errors.some(uD)||o?(this.viaInPadSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.params.viaInPadDrcEvaluator??this.params.drcEvaluator,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:this.params.enableViaInPadLayerMoves}),this.activeSubSolver=this.viaInPadSolver,this.phase=\"viaInPad\"):this.finishWithOutput(t,e,n)}startMixedSafeTraceLayerPhase(t,e,n){this.legacySafeTraceLayerRoutes=t,this.legacySafeTraceLayerSnapshot=e,this.legacySafeTraceLayerSelectedSolver=n,this.mixedSafeTraceLayerSolver=new Nz({...this.params,hdRoutes:this.safeTraceLayerInputRoutes,drcEvaluator:this.params.drcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.mixedSafeTraceLayerSolver,this.phase=\"mixedSafeTraceLayer\"}startBroadBranch(){const t=iD(this.params.srj,this.inputHdRoutes,this.params.effort??1,this.broadPassMultiplier,this.params.connMap);this.broadInputSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),yD(this.broadInputSnapshot,this.baselineSnapshot)?(this.broadSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.broadMaxIterations,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.broadSolver,this.phase=\"broad\"):this.startSafeTraceLayerPhase(this.baselineSolver.getOutput(),this.baselineSnapshot,this.baselineSolver)}_step(){if(\"start\"===this.phase)return this.inputSnapshot=Wk(this.params.srj,this.inputHdRoutes,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),0===mD(this.inputSnapshot)?void this.startViaInPadPhase(this.inputHdRoutes,this.inputSnapshot):void this.startBaselineBranch();if(\"baseline\"===this.phase){if(this.stepBranch(this.baselineSolver,\"baseline\"),!this.baselineSolver.solved)return;const t=this.baselineSolver.getOutput();return this.baselineSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),0===mD(this.baselineSnapshot)?void this.startViaInPadPhase(t,this.baselineSnapshot,this.baselineSolver):void(this.params.enableSafeTraceLayerMoves\u0026\u0026this.baselineSnapshot.count\u003c=3?this.startSafeTraceLayerPhase(t,this.baselineSnapshot,this.baselineSolver):this.startBroadBranch())}if(\"broad\"===this.phase){if(this.stepBranch(this.broadSolver,\"broad\"),!this.broadSolver.solved)return;const t=this.broadSolver.getOutput();return this.broadSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),yD(this.broadSnapshot,this.baselineSnapshot)?void this.startSafeTraceLayerPhase(t,this.broadSnapshot,this.broadSolver):void this.startSafeTraceLayerPhase(this.baselineSolver.getOutput(),this.baselineSnapshot,this.baselineSolver)}if(\"safeTraceLayer\"===this.phase){if(this.stepBranch(this.safeTraceLayerSolver,\"safe trace-layer\"),!this.safeTraceLayerSolver.solved)return;const t=this.safeTraceLayerSolver.getOutput(),e=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),n=hD(this.safeTraceLayerInputSnapshot,!1),o=hD(e,!1);this.safeTraceLayerPhaseAccepted=o\u003c=n\u0026\u0026jD(e,o,this.safeTraceLayerInputSnapshot.count,this.safeTraceLayerInputSnapshot.issueScore,n,this.safeTraceLayerInputSnapshot);const i=this.safeTraceLayerPhaseAccepted?t:this.safeTraceLayerInputRoutes,r=this.safeTraceLayerPhaseAccepted?e:this.safeTraceLayerInputSnapshot,s=this.safeTraceLayerPhaseAccepted?this.safeTraceLayerSolver:this.portfolioSelectedSolver;return r.count\u003e0\u0026\u0026!this.broadInputSnapshot?void this.startBroadBranch():mD(r)\u003e0\u0026\u0026this.safeTraceLayerInputSnapshot.errors.some(uD)?void this.startMixedSafeTraceLayerPhase(i,r,s):void this.startViaInPadPhase(i,r,s)}if(\"mixedSafeTraceLayer\"===this.phase){if(this.stepBranch(this.mixedSafeTraceLayerSolver,\"mixed safe trace-layer\"),!this.mixedSafeTraceLayerSolver.solved)return;const t=this.mixedSafeTraceLayerSolver.getOutput(),e=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),n=mD(e)\u003c=mD(this.legacySafeTraceLayerSnapshot);let o=!0;if(this.params.referenceDrcEvaluator){const e=this.getReferenceDrcSnapshot(this.legacySafeTraceLayerRoutes),n=this.getReferenceDrcSnapshot(t);this.mixedReferenceInputDrcIssueCount=e.count,this.mixedReferenceCandidateDrcIssueCount=n.count,o=n.count\u003c=e.count}return this.mixedSafeTraceLayerPhaseAccepted=n\u0026\u0026o,void this.startViaInPadPhase(this.mixedSafeTraceLayerPhaseAccepted?t:this.legacySafeTraceLayerRoutes,this.mixedSafeTraceLayerPhaseAccepted?e:this.legacySafeTraceLayerSnapshot,this.mixedSafeTraceLayerPhaseAccepted?this.mixedSafeTraceLayerSolver:this.legacySafeTraceLayerSelectedSolver)}if(\"viaInPad\"===this.phase){if(this.stepBranch(this.viaInPadSolver,\"via-in-pad\"),!this.viaInPadSolver.solved)return;const t=this.viaInPadSolver.getOutput(),e=Wk(this.params.srj,t,this.params.viaInPadDrcEvaluator??this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine);this.finishWithOutput(t,e,this.viaInPadSolver)}}getOutput(){return this.outputHdRoutes}visualize(){const t=this.activeSubSolver??this.selectedSolver;return t?.visualize()??super.visualize()}preview(){const t=this.activeSubSolver??this.selectedSolver;return t?.preview()??this.visualize()}},Tz=class extends si{constructor(t,e,n=Number.POSITIVE_INFINITY,o=.010000000000000002){super(),this.nodes=t,this.maxNodeDimension=e,this.maxNodeRatio=n,this.minNodeArea=o,this.outputNodes=[]}nodes;maxNodeDimension;maxNodeRatio;minNodeArea;outputNodes;getSolverName(){return\"NodeDimensionSubdivisionSolver\"}getSubdivisionGrid(t){const e=Number.isFinite(this.maxNodeDimension)\u0026\u0026this.maxNodeDimension\u003e0,n=Number.isFinite(this.maxNodeRatio)\u0026\u0026this.maxNodeRatio\u003e0;let o=e?Math.max(1,Math.ceil(t.width/this.maxNodeDimension)):1,i=e?Math.max(1,Math.ceil(t.height/this.maxNodeDimension)):1;if(n\u0026\u0026t.width\u003e0\u0026\u0026t.height\u003e0)for(;;){const e=t.width/o,n=t.height/i;if((e\u003e=n?e/n:n/e)\u003c=this.maxNodeRatio)break;e\u003e=n?o++:i++}return{cols:o,rows:i}}shouldRemoveNode(t){const e=Number.isFinite(this.minNodeArea)\u0026\u0026this.minNodeArea\u003e0;if(!Number.isFinite(t.width)||!Number.isFinite(t.height))return!0;if(!e||t.width*t.height\u003e=this.minNodeArea)return!1;if(Math.min(t.width,t.height)\u003c.002)return!0;if(t._containsTarget)return!1;let n=0;for(const e of this.nodes)if(e.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026t.availableZ.some(t=\u003ee.availableZ.includes(t))\u0026\u0026li(t,e)){if(e._containsTarget)return!1;if(n++,n\u003e=2)return!1}return!0}subdivideNode(t){if(this.shouldRemoveNode(t))return[];const{cols:e,rows:n}=this.getSubdivisionGrid(t);if(1===e\u0026\u00261===n)return[t];const o=t.width/e,i=t.height/n,r=t.center.x-t.width/2,s=t.center.y-t.height/2,a=[];for(let c=0;c\u003cn;c++)for(let n=0;n\u003ce;n++)a.push({...t,capacityMeshNodeId:`${t.capacityMeshNodeId}__sub_${c}_${n}`,center:{x:r+o*(n+.5),y:s+i*(c+.5)},width:o,height:i,availableZ:[...t.availableZ]});return a}_step(){const t=this.nodes.length;let e=0,n=0,o=0;for(const t of this.nodes){const i=!Number.isFinite(t.width)||!Number.isFinite(t.height),r=this.subdivideNode(t);0!==r.length?(r.length\u003e1\u0026\u0026e++,this.outputNodes.push(...r)):i?o++:n++}this.stats={inputNodeCount:t,outputNodeCount:this.outputNodes.length,subdividedNodeCount:e,removedSmallNodeCount:n,removedInvalidNodeCount:o,maxNodeDimension:this.maxNodeDimension,maxNodeRatio:this.maxNodeRatio,minNodeArea:this.minNodeArea},this.solved=!0}visualize(){return{rects:this.outputNodes.map(t=\u003e({center:t.center,width:t.width,height:t.height,label:`${t.capacityMeshNodeId}\\n${t.width.toFixed(2)}x${t.height.toFixed(2)}`,layer:`z${t.availableZ.join(\",\")}`,fill:\"rgba(0, 200, 255, 0.08)\",stroke:\"rgba(0, 120, 180, 0.5)\"}))}}},Rz=t=\u003e{const e=[...new Set(t.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0))].sort((t,e)=\u003et-e);if(0!==e.length)return`z${e.join(\",\")}`},Ez=t=\u003e{const e=[];for(let n=0;n\u003c31;n++)t\u00261\u003c\u003cn\u0026\u0026e.push(n);return e},Az=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,Oz=t=\u003eAz(t)?{...t}:void 0===t?{}:{value:t},kz=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];if(Az(n)){if(\"string\"==typeof n.serializedRegionId)return n.serializedRegionId;if(\"string\"==typeof n.regionId)return n.regionId;if(\"string\"==typeof n.capacityMeshNodeId)return n.capacityMeshNodeId}return`region-${e}`},Lz=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];if(Az(n)){if(\"string\"==typeof n.serializedPortId)return n.serializedPortId;if(\"string\"==typeof n.portId)return(o=n.portId).includes(\"::\")?o.slice(0,o.indexOf(\"::\")):o}var o;return`port-${e}`},Dz=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return Az(n)\u0026\u0026\"string\"==typeof n.connectionId?n.connectionId:`route-${e}`},zz=(t,e)=\u003e{const n=Oz(t.topology.regionMetadata?.[e]);if(Az(n.center)||(n.center={x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),\"number\"!=typeof n.width\u0026\u0026(n.width=t.topology.regionWidth[e]),\"number\"!=typeof n.height\u0026\u0026(n.height=t.topology.regionHeight[e]),!Array.isArray(n.availableZ)){const o=t.topology.regionAvailableZMask?.[e]??0;0!==o\u0026\u0026(n.availableZ=Ez(o))}return n.layer=Rz(Array.isArray(n.availableZ)?n.availableZ:[])??Rz((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))??\"z0\",n},Fz=(t,e)=\u003e{const n=Oz(t.topology.portMetadata?.[e]);return\"number\"!=typeof n.x\u0026\u0026(n.x=t.topology.portX[e]),\"number\"!=typeof n.y\u0026\u0026(n.y=t.topology.portY[e]),\"number\"!=typeof n.z\u0026\u0026(n.z=t.topology.portZ[e]),n.layer=Rz([t.topology.portZ[e]])??\"z0\",n},Bz=(t,e,n)=\u003e{const o=(t.topology.incidentPortRegion[e]??[]).find(t=\u003et!==n);if(void 0===o)throw new Error(`Port ${e} is not incident to a region outside route region ${n}`);return o},jz=(t,e,n)=\u003e{const{orderedPortIds:o,orderedRegionIds:i}=((t,e,n)=\u003e{if(0===n.length)throw new Error(`Route ${e} has no solved segments`);const o=t.problem.routeStartPort[e],i=t.problem.routeEndPort[e],r=new Map;n.forEach((t,e)=\u003e{const n={...t,segmentIndex:e},o=r.get(t.fromPortId)??[];o.push(n),r.set(t.fromPortId,o);const i=r.get(t.toPortId)??[];i.push(n),r.set(t.toPortId,i)});const s=[o],a=[],c=(t,e,n)=\u003e{if(t===i)return!0;for(const o of r.get(t)??[]){if(e.has(o.segmentIndex))continue;const i=o.fromPortId===t?o.toPortId:o.fromPortId;if(!n.has(i)){if(e.add(o.segmentIndex),n.add(i),a.push(o.regionId),s.push(i),c(i,e,n))return!0;s.pop(),a.pop(),n.delete(i),e.delete(o.segmentIndex)}}return!1};if(!c(o,new Set,new Set([o])))throw new Error(`Route ${e} is not a single ordered path from ${o} to ${i}`);return{orderedPortIds:s,orderedRegionIds:a}})(t,e,n),r=i[0],s=i[i.length-1];if(void 0===r||void 0===s)throw new Error(`Route ${e} could not determine endpoint regions`);const a=kz(t,Bz(t,o[0],r)),c=kz(t,Bz(t,o[o.length-1],s)),l=((t,e,n,o)=\u003e{const i=t.problem.routeMetadata?.[e];return{connectionId:Dz(t,e),startRegionId:(Az(i)\u0026\u0026\"string\"==typeof i.startRegionId?i.startRegionId:void 0)??n,endRegionId:(Az(i)\u0026\u0026\"string\"==typeof i.endRegionId?i.endRegionId:void 0)??o,mutuallyConnectedNetworkId:(Az(i)\u0026\u0026\"string\"==typeof i.mutuallyConnectedNetworkId?i.mutuallyConnectedNetworkId:void 0)??`net-${t.problem.routeNet[e]}`}})(t,e,a,c),d=o.map((e,n)=\u003e{const r={portId:Lz(t,e),g:n,h:0,f:n,hops:n,ripRequired:!1,nextRegionId:n\u003ci.length?kz(t,i[n]):l.endRegionId};return n\u003e0\u0026\u0026(r.lastPortId=Lz(t,o[n-1]),r.lastRegionId=kz(t,i[n-1])),r});return{connection:l,solvedRoute:{connection:l,path:d,requiredRip:!1}}},$z=t=\u003e{if(!t.solved||t.failed)throw new Error(\"convertToSerializedHyperGraph requires a solved, non-failed solver\");const{topology:e}=t,n=(t=\u003e{const e=Array.from({length:t.problem.routeCount},()=\u003e[]);return t.state.regionSegments.forEach((t,n)=\u003e{for(const[o,i,r]of t)e[o].push({regionId:n,fromPortId:i,toPortId:r})}),e})(t),o=Array.from({length:e.regionCount},(n,o)=\u003e{const i=t.state.regionSegments[o].map(([e,n,o])=\u003e({regionPort1Id:Lz(t,n),regionPort2Id:Lz(t,o),connectionId:Dz(t,e)}));return{regionId:kz(t,o),pointIds:e.regionIncidentPorts[o].map(e=\u003eLz(t,e)),d:zz(t,o),...i.length\u003e0\u0026\u0026{assignments:i}}}),i=Array.from({length:e.portCount},(n,o)=\u003e{const[i,r]=e.incidentPortRegion[o]??[];if(void 0===i||void 0===r)throw new Error(`Port ${o} is missing incident regions`);return{portId:Lz(t,o),region1Id:kz(t,i),region2Id:kz(t,r),d:Fz(t,o)}}),r=n.map((e,n)=\u003ejz(t,n,e));return{regions:o,ports:i,connections:r.map(({connection:t})=\u003et),solvedRoutes:r.map(({solvedRoute:t})=\u003et)}},Yz=.3,Xz=t=\u003et\u003e0\u0026\u0026!(t\u0026t-1),Vz=(t,e,n,o,i,r=0,s=.3,a=0)=\u003e(2*e+1*n+1*o)*(s+.15)**2*(1+i/5)/t+(Xz(r)?10*e:0)+a*(i/Wz(r))**2*.1**2/t,Wz=t=\u003e{if(0===t)return 2;let e=t\u003e\u003e\u003e0,n=0;for(;0!==e;)n+=1\u0026e,e\u003e\u003e\u003e=1;return n},Hz=(t,e,n,o,i,r)=\u003e{const{netIds:s,lesserAngles:a,greaterAngles:c,layerMasks:l}=t;let d=0,h=0;for(let t=0;t\u003cs.length;t++){if(e===s[t])continue;(n\u003ca[t]\u0026\u0026a[t]\u003co)!==(n\u003cc[t]\u0026\u0026c[t]\u003co)\u0026\u0026(0!==(i\u0026l[t])?d++:h++)}return[d,h,r]},Gz=(t,e,n)=\u003e{const o=t.routeStartPort[e],i=t.routeEndPort[e],r=new Map;for(const{fromPortId:t,toPortId:e}of n){const n=r.get(t)??new Set;n.add(e),r.set(t,n);const o=r.get(e)??new Set;o.add(t),r.set(e,o)}const s=new Set,a=[o];for(;a.length\u003e0;){const t=a.pop();if(!s.has(t)){s.add(t);for(const e of r.get(t)??[])a.push(e)}}if(!s.has(i))throw new Error(`Initial assignments for route ${e} do not connect ${o} to ${i}`);if(n.some(({fromPortId:t,toPortId:e})=\u003e!s.has(t)||!s.has(e)))throw new Error(`Initial assignments for route ${e} contain disconnected segments`)},Uz=({topology:t,problem:e,state:n,routeSuccessCountByRouteId:o,appendSegmentToRegionCache:i})=\u003e{const r=e.initialAssignments??[];if(0===r.length)return;const s=new Map;for(const n of r){const{routeId:o,regionId:i,fromPortId:r,toPortId:a}=n;if(!Number.isInteger(o)||o\u003c0||o\u003e=e.routeCount)throw new Error(`Initial assignment references invalid route ${o}`);if(!Number.isInteger(i)||i\u003c0||i\u003e=t.regionCount)throw new Error(`Initial assignment references invalid region ${i}`);for(const e of[r,a]){if(!Number.isInteger(e)||e\u003c0||e\u003e=t.portCount)throw new Error(`Initial assignment references invalid port ${e}`);if(!t.incidentPortRegion[e]?.includes(i))throw new Error(`Initial assignment port ${e} is not incident to region ${i}`)}const c=s.get(o)??[];c.push(n),s.set(o,c)}for(const[t,n]of s)Gz(e,t,n);const a=new Set(s.keys());for(const{routeId:t,regionId:o,fromPortId:s,toPortId:a}of r){const r=e.routeNet[t];for(const t of[s,a]){const e=n.portAssignment[t];if(-1!==e\u0026\u0026e!==r)throw new Error(`Initial assignment port ${t} is assigned to multiple nets`);n.portAssignment[t]=r}n.currentRouteNetId=r,n.regionSegments[o].push([t,s,a]),i(o,s,a)}n.currentRouteNetId=void 0,n.unroutedRoutes=n.unroutedRoutes.filter(t=\u003e!a.has(t));for(const t of a)o[t]=1;return{initialAssignmentCount:r.length,initiallyRoutedRouteCount:a.size}},Zz=class{constructor(t,e){this.items=t,this.compare=e}items;compare;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0}queue(t){this.items.push(t),this.siftUp(this.items.length-1)}dequeue(){const t=this.items[0];if(void 0===t)return;const e=this.items.pop();return this.items.length\u003e0\u0026\u0026(this.items[0]=e,this.siftDown(0)),t}siftUp(t){let e=t;for(;e\u003e0;){const t=e-1\u003e\u003e1,n=this.items[t],o=this.items[e];if(this.compare(n,o)\u003c=0)return;this.items[t]=o,this.items[e]=n,e=t}}siftDown(t){let e=t;const n=this.items.length;for(;;){const t=2*e+1;if(t\u003e=n)return;const o=t+1;let i=t;o\u003cn\u0026\u0026this.compare(this.items[o],this.items[t])\u003c0\u0026\u0026(i=o);const r=this.items[e],s=this.items[i];if(this.compare(r,s)\u003c=0)return;this.items[e]=s,this.items[i]=r,e=i}}},qz=(t,e)=\u003e{const n=[...t],o=(t=\u003e{let e=t\u003e\u003e\u003e0;return()=\u003e{e+=1831565813;let t=e;return t=Math.imul(t^t\u003e\u003e\u003e15,1|t),t^=t+Math.imul(t^t\u003e\u003e\u003e7,61|t),((t^t\u003e\u003e\u003e14)\u003e\u003e\u003e0)/4294967296}})(e);for(let t=n.length-1;t\u003e0;t--){const e=Math.floor(o()*(t+1));[n[t],n[e]]=[n[e],n[t]]}return n},Jz=(t,e)=\u003et.routeMetadata?.[e],Kz=t=\u003et?.simpleRouteConnection?.pointsToConnect?.map(({pointId:t})=\u003e\"string\"==typeof t?t:null).filter(t=\u003enull!==t)??[],Qz=(t,e)=\u003e{const n=Jz(t,e)?.connectionId;return\"string\"==typeof n?n:`route-${e}`},tF=(t,e,n)=\u003e{const o=t.portEndpointNetIds[n];if(!o)return!1;for(const t of o)if(t!==e)return!0;return!1},eF=(t,e,n)=\u003e{const o=t.regionNetId[n];return-1!==o\u0026\u0026o!==e},nF=t=\u003e[...new Set(t.routeIds)].filter(e=\u003e!((t,e)=\u003e{const{topology:n,problem:o,problemSetup:i,portAssignment:r,maxPrecheckHops:s}=t,a=o.routeNet[e],c=o.routeStartPort[e],l=o.routeEndPort[e];if(c===l)return!0;const d=t.getStartingNextRegionId(e,c);if(void 0===d)return!1;const h=[{portId:c,nextRegionId:d}],u=new Set([c*n.regionCount+d]);for(let t=0;t\u003ch.length;t++){const e=h[t];if(!eF(o,a,e.nextRegionId))for(const t of n.regionIncidentPorts[e.nextRegionId]??[]){const c=r[t];if(tF(i,a,t))continue;if(t===l){if(-1!==c\u0026\u0026c!==a)continue;return!0}if(t===e.portId)continue;if(-1!==c\u0026\u0026c!==a)continue;if(0===o.portSectionMask[t])continue;const d=n.incidentPortRegion[t]??[],p=d[0]===e.nextRegionId?d[1]:d[0];if(void 0===p||eF(o,a,p))continue;const m=t*n.regionCount+p;if(!u.has(m)){if(u.size\u003e=s)return!0;u.add(m),h.push({portId:t,nextRegionId:p})}}}return!1})(t,e)).map(e=\u003et.getRouteSummary(e)),oF=t=\u003e{const e=new Array(t);for(let n=0;n\u003ct;n++)e[n]=n;return e},iF=\"rgba(220, 38, 38, 0.98)\",rF=\"rgba(220, 38, 38, 0.18)\",sF=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),aF=(t,e)=\u003e{const n=.005*t.topology.portZ[e];return{x:t.topology.portX[e]+n,y:t.topology.portY[e]+n}},cF=(t,e)=\u003eRz([t.topology.portZ[e]])??\"z0\",lF=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},dF=(t,e)=\u003e`z: ${t.topology.portZ[e]}`,hF=(t,e)=\u003e((t,e,n)=\u003e{const o=t.topology.portZ[e],i=t.topology.portZ[n];return o===i?`z: ${o}`:`z: ${o} -\u003e ${i}`})(t,t.problem.routeStartPort[e],t.problem.routeEndPort[e]),uF=(t,e)=\u003e`net: ${t.problem.routeNet[e]}`,pF=.05,mF={r:255,g:64,b:64,a:.72},gF=\"rgba(220, 38, 38, 0.98)\",fF=\"rgba(220, 38, 38, 0.12)\",yF=\"10 6\",_F=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),bF=t=\u003eMath.min(1,Math.max(0,t)),xF=(t,e,n)=\u003eMath.round(t+(e-t)*n),vF=({r:t,g:e,b:n,a:o})=\u003e`rgba(${t}, ${e}, ${n}, ${o})`,SF=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},IF=t=\u003e\"number\"==typeof t.centerRouteId,CF=(t,e)=\u003eIF(t)?e===t.centerRouteId?1:.5:1,PF=(t,e)=\u003e{const n=t.match(/^(rgba|hsla)\\((.*),\\s*([0-9]*\\.?[0-9]+)\\)$/);if(!n)return t;const[,o,i,r]=n,s=bF(Number(r)*e);return`${o}(${i}, ${Number(s.toFixed(3))})`},MF=(t,e,n=.8)=\u003e((t,e,n=.8)=\u003e{const o=`${t.problem.routeNet[e]}:${SF(t,e)}`;let i=0;for(let t=0;t\u003co.length;t++)i=17777*o.charCodeAt(t)+((i\u003c\u003c5)-i);return`hsla(${Math.abs(i)%360}, 70%, 50%, ${n})`})(t,e,n*CF(t,e)),NF=(t,e)=\u003e`net: ${t.problem.routeNet[e]}`,wF=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=n?.polygon;if(Array.isArray(o)\u0026\u0026o.length\u003e=3){const t=o.map(t=\u003et.x),e=o.map(t=\u003et.y);return{minX:Math.min(...t),maxX:Math.max(...t),minY:Math.min(...e),maxY:Math.max(...e)}}const i=n?.bounds;if(i\u0026\u0026\"number\"==typeof i.minX\u0026\u0026\"number\"==typeof i.maxX\u0026\u0026\"number\"==typeof i.minY\u0026\u0026\"number\"==typeof i.maxY)return i;const r=t.topology.regionWidth[e],s=t.topology.regionHeight[e],a=t.topology.regionCenterX[e],c=t.topology.regionCenterY[e];return{minX:a-r/2,maxX:a+r/2,minY:c-s/2,maxY:c+s/2}},TF=(t,e)=\u003e({x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),RF=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=Array.isArray(n?.availableZ)?n.availableZ.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0):[];if(o.length\u003e0)return Rz(o)??\"z0\";const i=Ez(t.topology.regionAvailableZMask?.[e]??0);if(i.length\u003e0)return Rz(i)??\"z0\";const r=[...new Set((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))].sort((t,e)=\u003et-e);return Rz(r)??\"z0\"},EF=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e],o=n?.existingRegionCost??0,i=t.state.regionCongestionCost[e]??0,r=t.problem.regionNetId[e];return _F(`region: region-${e}`,`net: ${-1===r?\"free\":`${r}`}`,t.getAdditionalRegionLabel(e),`cost: ${o.toFixed(3)}`,`congestion: ${i.toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},AF=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];return n?.isConnectionRegion?{r:255,g:100,b:255,a:.6}:n?.isThroughJumper?{r:100,g:200,b:100,a:.5}:n?.isPad?{r:255,g:200,b:100,a:.5}:\"bottom\"===n?.layer?{r:52,g:152,b:219,a:.08}:{r:200,g:200,b:255,a:.1}},OF=(t,e)=\u003e{const n=AF(t,e),o=bF(t.state.regionIntersectionCaches[e]?.existingRegionCost??0);return vF((r=mF,s=o**.8,{r:xF((i=n).r,r.r,s),g:xF(i.g,r.g,s),b:xF(i.b,r.b,s),a:Number((i.a+(r.a-i.a)*s).toFixed(3))}));var i,r,s},kF=(t,e)=\u003e{const n=((t,e)=\u003e({x:t.topology.portX[e],y:t.topology.portY[e]}))(t,e),o=.005*t.topology.portZ[e];return{x:n.x+o,y:n.y+o}},LF=kF,DF=(t,e)=\u003eRz([t.topology.portZ[e]])??\"z0\",zF=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},FF=(t,e,n)=\u003e{if(void 0!==n)return`net: ${t.problem.routeNet[n]}`;const o=t.state.portAssignment[e];if(o\u003e=0)return`net: ${o}`;const i=new Set;for(let n=0;n\u003ct.problem.routeCount;n++)t.problem.routeStartPort[n]!==e\u0026\u0026t.problem.routeEndPort[n]!==e||i.add(t.problem.routeNet[n]);return 0!==i.size?`net: ${Array.from(i).sort((t,e)=\u003et-e).join(\", \")}`:void 0},BF=(t,e)=\u003e`z: ${t.topology.portZ[e]}`,jF=(t,e,n)=\u003e{const o=t.topology.portZ[e],i=t.topology.portZ[n];return o===i?`z: ${o}`:`z: ${o} -\u003e ${i}`},$F=(t,e)=\u003ejF(t,t.problem.routeStartPort[e],t.problem.routeEndPort[e]),YF=(t,e,n)=\u003e_F(zF(t,e),((t,e)=\u003e{const n=t.topology.incidentPortRegion[e]?.[0],o=t.topology.incidentPortRegion[e]?.[1];return`connects: region-${n??\"?\"} \u003c-\u003e region-${o??\"?\"}`})(t,e),FF(t,e,n)),XF=(t,e,n,o)=\u003e{const i=t.topology.portZ[n];return i!==t.topology.portZ[o]?{strokeColor:PF(\"rgba(22, 160, 133, 0.95)\",CF(t,e)),strokeDash:\"2 4 2\"}:i\u003e0?{strokeColor:PF(\"rgba(52, 152, 219, 0.95)\",CF(t,e)),strokeDash:\"3 2\"}:{strokeColor:MF(t,e)}},VF=(t,e)=\u003e{for(let n=0;n\u003ct.state.regionSegments.length;n++){const o=t.state.regionSegments[n]??[];for(const[i,r,s]of o)e.lines.push({points:[kF(t,r),kF(t,s)],label:_F(`route: ${SF(t,i)}`,`region: region-${n}`,jF(t,r,s)),layer:DF(t,r),...XF(t,i,r,s)})}},WF=(t,e)=\u003e{const n=new Set;for(let o=0;o\u003ct.state.regionSegments.length;o++){const i=t.state.regionSegments[o]??[];for(const[o,r,s]of i)for(const i of[r,s]){const r=`${o}:${i}`;if(n.has(r))continue;n.add(r);const s=kF(t,i);e.points.push({x:s.x,y:s.y,color:MF(t,o,1),layer:DF(t,i),label:_F(`route: ${SF(t,o)}`,zF(t,i),FF(t,i,o),BF(t,i))})}}},HF=(t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++)if(t.problem.routeStartPort[n]===e||t.problem.routeEndPort[n]===e)return!0;return!1},GF=(t,e,n)=\u003e{const o=((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ce.length;o++)if(1===e[o])for(const e of t.topology.incidentPortRegion[o]??[])n.add(e);return n})(t,n),i=\"rgba(245, 158, 11, 0.95)\",r=\"rgba(245, 158, 11, 0.08)\";for(const n of o){const o=t.topology.regionMetadata?.[n],s=o?.polygon,a=wF(t,n),c=TF(t,n),l=a.maxX-a.minX,d=a.maxY-a.minY,h=RF(t,n),u=_F(\"section region\",EF(t,n));Array.isArray(s)\u0026\u0026s.length\u003e=3?e.polygons.push({points:s,fill:r,stroke:i,strokeWidth:2,layer:h,label:u}):e.rects.push({center:c,width:Math.max(l-pF,.05),height:Math.max(d-pF,.05),fill:r,stroke:i,layer:h,label:u})}for(let o=0;o\u003cn.length;o++)1===n[o]\u0026\u0026e.circles.push({center:LF(t,o),radius:.07,fill:\"rgba(251, 191, 36, 0.18)\",stroke:i,layer:DF(t,o),label:_F(YF(t,o),BF(t,o),\"section port\")})},UF=(t,e={})=\u003e{const n={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:\"Tiny HyperGraph\",coordinateSystem:\"cartesian\"},o=((t,e)=\u003e{if(!e?.highlightSectionMask)return;const n=e.sectionPortMask??t.problem.portSectionMask;if(n.length!==t.topology.portCount)return;let o=0,i=0;for(let t=0;t\u003cn.length;t++)1===n[t]?o+=1:i+=1;return 0!==o\u0026\u00260!==i?n:void 0})(t,e),i=(t=\u003e{const e=t.getStaticallyUnroutableRoutes();if(0!==e.length)return new Set(e.map(t=\u003et.routeId))})(t);for(let e=0;e\u003ct.topology.regionCount;e++){const o=t.topology.regionMetadata?.[e],i=o?.polygon,r=wF(t,e),s=TF(t,e),a=r.maxX-r.minX,c=r.maxY-r.minY,l=RF(t,e),d=vF(AF(t,e));Array.isArray(i)\u0026\u0026i.length\u003e=3?n.polygons.push({points:i,fill:d,layer:l}):n.rects.push({center:s,width:Math.max(a-pF,.05),height:Math.max(c-pF,.05),fill:OF(t,e),layer:l,label:EF(t,e)})}if(((t,e,n)=\u003e{for(let o=0;o\u003ct.problem.routeCount;o++){if(n\u0026\u0026!n.has(o))continue;const i=t.problem.routeStartPort[o],r=t.problem.routeEndPort[o],s=kF(t,i),a=kF(t,r),c=MF(t,o),l=SF(t,o),d=NF(t,o);e.points.push({x:s.x,y:s.y,color:c,layer:DF(t,i),label:_F(`route: ${l}`,d,\"endpoint: start\",zF(t,i),BF(t,i))}),e.points.push({x:a.x,y:a.y,color:c,layer:DF(t,r),label:_F(`route: ${l}`,d,\"endpoint: end\",zF(t,r),BF(t,r))})}})(t,n,i),0===t.iterations){for(const t of n.polygons)t.stroke=\"rgba(128, 128, 128, 0.5)\";for(const t of n.rects)t.stroke=\"rgba(128, 128, 128, 0.5)\"}if(0===t.iterations){for(let i=0;i\u003ct.topology.portCount;i++){const r=1===o?.[i];e.showOnlySectionPortsOnIdle\u0026\u0026!r||n.circles.push({center:LF(t,i),radius:.05,fill:t.topology.portZ[i]\u003e0?\"rgba(52, 152, 219, 0.55)\":\"rgba(128, 128, 128, 0.5)\",layer:DF(t,i),label:_F(YF(t,i),BF(t,i))})}if(i)((t,e)=\u003e{for(const n of t.getStaticallyUnroutableRoutes()){const{routeId:o,connectionId:i,startPortId:r,endPortId:s}=n,a=aF(t,r),c=aF(t,s),l=sF(`static reachability failed: ${i}`,uF(t,o),n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0,n.pointIds.length\u003e=2?`points: ${n.pointIds.join(\" -\u003e \")}`:void 0,hF(t,o));e.lines.push({points:[a,c],strokeColor:iF,strokeDash:\"8 4\",label:l}),e.circles.push({center:a,radius:.12,fill:rF,stroke:iF,layer:cF(t,r),label:sF(l,\"endpoint: start\",lF(t,r),dF(t,r))}),e.circles.push({center:c,radius:.12,fill:rF,stroke:iF,layer:cF(t,s),label:sF(l,\"endpoint: end\",lF(t,s),dF(t,s))})}})(t,n);else{const o=new Set;for(const e of t.state.regionSegments)for(const[t]of e)o.add(t);if(o.size\u003e0\u0026\u0026(VF(t,n),WF(t,n)),!1!==e.showInitialRouteHints){const e=new Set(t.state.unroutedRoutes);void 0!==t.state.currentRouteId\u0026\u0026e.add(t.state.currentRouteId),((t,e,n)=\u003e{for(let o=0;o\u003ct.problem.routeCount;o++){if(n\u0026\u0026!n.has(o))continue;const i=t.problem.routeStartPort[o],r=t.problem.routeEndPort[o],s=kF(t,i),a=kF(t,r),c={x:(s.x+a.x)/2,y:(s.y+a.y)/2};e.lines.push({points:[s,a],strokeColor:MF(t,o),strokeDash:\"3 3\",layer:DF(t,i),label:_F(SF(t,o),$F(t,o))}),e.points.push({x:c.x,y:c.y,color:MF(t,o,1),layer:DF(t,i),label:_F(SF(t,o),$F(t,o))})}})(t,n,e)}}}else VF(t,n),WF(t,n),(t=\u003eIF(t)\u0026\u0026!0===t.showUnassignedPortsInVisualization)(t)\u0026\u0026((t,e)=\u003e{for(let n=0;n\u003ct.topology.portCount;n++)t.state.portAssignment[n]\u003e=0||HF(t,n)||e.circles.push({center:LF(t,n),radius:.04,fill:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.2)\":\"rgba(128, 128, 128, 0.2)\",stroke:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.6)\":\"rgba(128, 128, 128, 0.6)\",layer:DF(t,n),label:_F(YF(t,n),BF(t,n),\"state: unassigned\")})})(t,n),IF(t)||(((t,e)=\u003e{const n=t.state.currentRouteId;if(void 0===n||t.solved)return;const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=kF(t,o),s=kF(t,i),a=MF(t,n),c=SF(t,n);e.lines.push({points:[r,s],strokeColor:a,strokeDash:\"10 5\",label:_F(c,$F(t,n))})})(t,n),((t,e)=\u003e{if(t.solved)return;const n=t.state.currentRouteId,o=t.state.candidateQueue.toArray().sort((t,e)=\u003et.f-e.f).slice(0,10);for(let i=0;i\u003co.length;i++){const r=o[i],s=kF(t,r.portId),a=0===i;e.points.push({x:s.x,y:s.y,color:a?\"green\":\"rgba(128, 128, 128, 0.25)\",layer:DF(t,r.portId),label:_F(YF(t,r.portId,n),BF(t,r.portId),`g: ${r.g.toFixed(2)}`,`h: ${r.h.toFixed(2)}`,`f: ${r.f.toFixed(2)}`)})}const i=o[0];if(!i)return;const r=[];let s=i;for(;s;)r.unshift(kF(t,s.portId)),s=s.prevCandidate;r.length\u003e1\u0026\u0026e.lines.push({points:r,strokeColor:void 0!==n?MF(t,n):\"rgba(0, 160, 120, 0.9)\"})})(t,n));o\u0026\u0026GF(t,n,o),((t,e)=\u003e{if(t.failed)for(const n of t.getNeverSuccessfullyRoutedRoutes()){const{routeId:o,connectionId:i,attempts:r,startPortId:s,endPortId:a}=n,c=NF(t,o),l=LF(t,s),d=LF(t,a),h=_F(`never routed: ${i}`,`attempts: ${r}`,c,n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0);e.lines.push({points:[{x:0,y:0},{x:l.x,y:l.y}],strokeColor:gF,strokeDash:yF,layer:DF(t,s),label:_F(h,\"origin guide\",\"endpoint: start\")}),e.circles.push({center:l,radius:1,fill:fF,stroke:gF,layer:DF(t,s),label:_F(h,\"endpoint: start\",zF(t,s),BF(t,s))}),e.lines.push({points:[{x:0,y:0},{x:d.x,y:d.y}],strokeColor:gF,strokeDash:yF,layer:DF(t,a),label:_F(h,\"origin guide\",\"endpoint: end\")}),e.circles.push({center:d,radius:1,fill:fF,stroke:gF,layer:DF(t,a),label:_F(h,\"endpoint: end\",zF(t,a),BF(t,a))})}})(t,n);const r=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1),s=o?o.reduce((t,e)=\u003et+Number(1===e),0):0;return n.title=[\"Tiny HyperGraph\",`iter=${t.iterations}`,`pending=${r}`,o?`sectionPorts=${s}`:void 0,i?`staticReachabilityFailed=${i.size}`:void 0,t.failed?\"failed\":t.solved?\"solved\":\"running\"].filter(Boolean).join(\" | \"),n},ZF=5e4,qF=()=\u003e({netIds:new Int32Array(0),lesserAngles:new Int32Array(0),greaterAngles:new Int32Array(0),layerMasks:new Int32Array(0),existingCrossingLayerIntersections:0,existingSameLayerIntersections:0,existingEntryExitLayerChanges:0,existingRegionCost:0,existingSegmentCount:0}),JF=t=\u003e({netIds:new Int32Array(t.netIds),lesserAngles:new Int32Array(t.lesserAngles),greaterAngles:new Int32Array(t.greaterAngles),layerMasks:new Int32Array(t.layerMasks),existingCrossingLayerIntersections:t.existingCrossingLayerIntersections,existingSameLayerIntersections:t.existingSameLayerIntersections,existingEntryExitLayerChanges:t.existingEntryExitLayerChanges,existingRegionCost:t.existingRegionCost,existingSegmentCount:t.existingSegmentCount}),KF=t=\u003e{return{portAssignment:new Int32Array(t.portAssignment),regionSegments:(e=t.regionSegments,e.map(t=\u003et.map(([t,e,n])=\u003e[t,e,n]))),regionIntersectionCaches:t.regionIntersectionCaches.map(JF),regionCongestionCost:new Float64Array(t.regionCongestionCost),ripCount:t.ripCount};var e},QF=(t,e)=\u003e{e\u0026\u0026(void 0!==e.minViaPadDiameter\u0026\u0026(t.minViaPadDiameter=e.minViaPadDiameter),void 0!==e.DISTANCE_TO_COST\u0026\u0026(t.DISTANCE_TO_COST=e.DISTANCE_TO_COST),void 0!==e.RIP_THRESHOLD_START\u0026\u0026(t.RIP_THRESHOLD_START=e.RIP_THRESHOLD_START),void 0!==e.RIP_THRESHOLD_END\u0026\u0026(t.RIP_THRESHOLD_END=e.RIP_THRESHOLD_END),void 0!==e.RIP_THRESHOLD_RAMP_ATTEMPTS\u0026\u0026(t.RIP_THRESHOLD_RAMP_ATTEMPTS=e.RIP_THRESHOLD_RAMP_ATTEMPTS),void 0!==e.RIP_CONGESTION_REGION_COST_FACTOR\u0026\u0026(t.RIP_CONGESTION_REGION_COST_FACTOR=e.RIP_CONGESTION_REGION_COST_FACTOR),void 0!==e.TRACE_DENSITY_COST_FACTOR\u0026\u0026(t.TRACE_DENSITY_COST_FACTOR=Math.max(0,e.TRACE_DENSITY_COST_FACTOR)),void 0!==e.USE_LAZY_ROUTE_HEURISTIC\u0026\u0026(t.USE_LAZY_ROUTE_HEURISTIC=e.USE_LAZY_ROUTE_HEURISTIC),void 0!==e.USE_SPARSE_CANDIDATE_STORAGE\u0026\u0026(t.USE_SPARSE_CANDIDATE_STORAGE=e.USE_SPARSE_CANDIDATE_STORAGE),void 0!==e.MAX_ITERATIONS\u0026\u0026(t.MAX_ITERATIONS=e.MAX_ITERATIONS),void 0!==e.VERBOSE\u0026\u0026(t.VERBOSE=e.VERBOSE),void 0!==e.STATIC_REACHABILITY_PRECHECK\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK=e.STATIC_REACHABILITY_PRECHECK),void 0!==e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS=e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),void 0!==e.ACCEPT_BEST_SOLUTION_ON_TIMEOUT\u0026\u0026(t.ACCEPT_BEST_SOLUTION_ON_TIMEOUT=e.ACCEPT_BEST_SOLUTION_ON_TIMEOUT),void 0!==e.GREEDY_FINAL_ROUTE_ITERS\u0026\u0026(t.GREEDY_FINAL_ROUTE_ITERS=e.GREEDY_FINAL_ROUTE_ITERS),void 0!==e.PARTIAL_RIP_ENABLED\u0026\u0026(t.PARTIAL_RIP_ENABLED=e.PARTIAL_RIP_ENABLED),void 0!==e.PARTIAL_RIP_MIN_ROUTE_COUNT\u0026\u0026(t.PARTIAL_RIP_MIN_ROUTE_COUNT=e.PARTIAL_RIP_MIN_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_MAX_ROUTE_COUNT\u0026\u0026(t.PARTIAL_RIP_MAX_ROUTE_COUNT=e.PARTIAL_RIP_MAX_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_MAX_DISTANCE\u0026\u0026(t.PARTIAL_RIP_MAX_DISTANCE=e.PARTIAL_RIP_MAX_DISTANCE),void 0!==e.PARTIAL_RIP_QUALITY_MAX_DISTANCE\u0026\u0026(t.PARTIAL_RIP_QUALITY_MAX_DISTANCE=e.PARTIAL_RIP_QUALITY_MAX_DISTANCE),void 0!==e.PARTIAL_RIP_MAX_ATTEMPTS\u0026\u0026(t.PARTIAL_RIP_MAX_ATTEMPTS=e.PARTIAL_RIP_MAX_ATTEMPTS),void 0!==e.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS\u0026\u0026(t.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS=e.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS),void 0!==e.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT\u0026\u0026(t.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT=e.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO\u0026\u0026(t.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO=e.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO),void 0!==e.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO\u0026\u0026(t.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO=e.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO),void 0!==e.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO\u0026\u0026(t.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO=e.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO),void 0!==e.OUTSIDE_IN_ROUTING\u0026\u0026(t.OUTSIDE_IN_ROUTING=e.OUTSIDE_IN_ROUTING),void 0!==e.OUTSIDE_IN_MAX_DISTANCE\u0026\u0026(t.OUTSIDE_IN_MAX_DISTANCE=e.OUTSIDE_IN_MAX_DISTANCE))},tB=t=\u003e({minViaPadDiameter:t.minViaPadDiameter,DISTANCE_TO_COST:t.DISTANCE_TO_COST,RIP_THRESHOLD_START:t.RIP_THRESHOLD_START,RIP_THRESHOLD_END:t.RIP_THRESHOLD_END,RIP_THRESHOLD_RAMP_ATTEMPTS:t.RIP_THRESHOLD_RAMP_ATTEMPTS,RIP_CONGESTION_REGION_COST_FACTOR:t.RIP_CONGESTION_REGION_COST_FACTOR,TRACE_DENSITY_COST_FACTOR:t.TRACE_DENSITY_COST_FACTOR,USE_LAZY_ROUTE_HEURISTIC:t.USE_LAZY_ROUTE_HEURISTIC,USE_SPARSE_CANDIDATE_STORAGE:t.USE_SPARSE_CANDIDATE_STORAGE,MAX_ITERATIONS:t.MAX_ITERATIONS,VERBOSE:t.VERBOSE,STATIC_REACHABILITY_PRECHECK:t.STATIC_REACHABILITY_PRECHECK,STATIC_REACHABILITY_PRECHECK_MAX_HOPS:t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:t.ACCEPT_BEST_SOLUTION_ON_TIMEOUT,GREEDY_FINAL_ROUTE_ITERS:t.GREEDY_FINAL_ROUTE_ITERS,PARTIAL_RIP_ENABLED:t.PARTIAL_RIP_ENABLED,PARTIAL_RIP_MIN_ROUTE_COUNT:t.PARTIAL_RIP_MIN_ROUTE_COUNT,PARTIAL_RIP_MAX_ROUTE_COUNT:t.PARTIAL_RIP_MAX_ROUTE_COUNT,PARTIAL_RIP_MAX_DISTANCE:t.PARTIAL_RIP_MAX_DISTANCE,PARTIAL_RIP_QUALITY_MAX_DISTANCE:t.PARTIAL_RIP_QUALITY_MAX_DISTANCE,PARTIAL_RIP_MAX_ATTEMPTS:t.PARTIAL_RIP_MAX_ATTEMPTS,PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS:t.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:t.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT,PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO:t.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO,PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO:t.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO,PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO:t.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO,OUTSIDE_IN_ROUTING:t.OUTSIDE_IN_ROUTING,OUTSIDE_IN_MAX_DISTANCE:t.OUTSIDE_IN_MAX_DISTANCE}),eB=(t,e)=\u003et.f-e.f,nB=class extends kt{constructor(t,e,n){super(),this.topology=t,this.problem=e,QF(this,n);let o=1;const i=new Int32Array(t.portCount).fill(-1),r=new Int32Array(t.portCount).fill(-1);for(let e=0;e\u003ct.portCount;e++){const n=t.incidentPortRegion[e]??[];n.length\u003eo\u0026\u0026(o=n.length),i[e]=n[0]??-1,r[e]=n[1]??-1}this.candidateHopSlotStride=o,this.candidateFirstRegionByPortId=i,this.candidateSecondRegionByPortId=r;const s=t.portCount*o;this.candidateHopCapacity=s,this.state={portAssignment:new Int32Array(t.portCount).fill(-1),regionSegments:Array.from({length:t.regionCount},()=\u003e[]),regionIntersectionCaches:Array.from({length:t.regionCount},()=\u003eqF()),currentRouteId:void 0,currentRouteNetId:void 0,unroutedRoutes:oF(e.routeCount),candidateQueue:new Zz([],eB),candidateBestCostByHopId:this.USE_SPARSE_CANDIDATE_STORAGE?new Map:new Float64Array(s),candidateBestCostGenerationByHopId:this.USE_SPARSE_CANDIDATE_STORAGE?new Map:new Uint32Array(s),candidateBestCostGeneration:1,goalPortId:-1,ripCount:0,regionCongestionCost:new Float64Array(t.regionCount).fill(0)},this.routeAttemptCountByRouteId=new Uint32Array(e.routeCount),this.routeSuccessCountByRouteId=new Uint32Array(e.routeCount);const a=Uz({topology:t,problem:e,state:this.state,routeSuccessCountByRouteId:this.routeSuccessCountByRouteId,appendSegmentToRegionCache:(t,e,n)=\u003ethis.appendSegmentToRegionCache(t,e,n)});a\u0026\u0026(this.stats={...this.stats,...a})}topology;problem;state;candidateHopSlotStride;candidateHopCapacity;candidateFirstRegionByPortId;candidateSecondRegionByPortId;candidateOverflowBestCost;_problemSetup;routeAttemptCountByRouteId;routeSuccessCountByRouteId;bestSolvedStateSnapshot;bestSolvedStateSummary;hasLoggedNeverSuccessfullyRoutedRoutes=!1;staticallyUnroutableRoutes=[];segmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};ADD_SEGMENT_DISTANCE_TO_G=!1;DISTANCE_TO_COST=.05;minViaPadDiameter=Yz;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;RIP_CONGESTION_REGION_COST_FACTOR=.1;TRACE_DENSITY_COST_FACTOR=0;USE_LAZY_ROUTE_HEURISTIC=!1;USE_SPARSE_CANDIDATE_STORAGE=!1;MAX_ITERATIONS=1e6;VERBOSE=!1;STATIC_REACHABILITY_PRECHECK=!0;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;ACCEPT_BEST_SOLUTION_ON_TIMEOUT=!0;GREEDY_FINAL_ROUTE_ITERS=4;PARTIAL_RIP_ENABLED=!1;PARTIAL_RIP_MIN_ROUTE_COUNT=0;PARTIAL_RIP_MAX_ROUTE_COUNT=Number.POSITIVE_INFINITY;PARTIAL_RIP_MAX_DISTANCE=12;PARTIAL_RIP_QUALITY_MAX_DISTANCE;PARTIAL_RIP_MAX_ATTEMPTS=Number.POSITIVE_INFINITY;PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS=0;PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT=Number.POSITIVE_INFINITY;PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO=0;PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO=.2;PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO=.1;OUTSIDE_IN_ROUTING=!1;OUTSIDE_IN_MAX_DISTANCE=24;get problemSetup(){return this._problemSetup||(this._problemSetup=this.computeProblemSetup()),this._problemSetup}computeProblemSetup(){const{topology:t,problem:e}=this,n=this.USE_LAZY_ROUTE_HEURISTIC?void 0:new Float64Array(t.portCount*e.routeCount),o=t.portX,i=t.portY,r=Array.from({length:t.portCount},()=\u003enew Set),s=new Int32Array(t.portCount).fill(-1),a=(t,e)=\u003e{r[t].add(e);const n=s[t];-1===n?s[t]=e:n!==e\u0026\u0026(s[t]=-2)};for(let r=0;r\u003ce.routeCount;r++){const s=e.routeNet[r];if(a(e.routeStartPort[r],s),a(e.routeEndPort[r],s),n){const s=e.routeEndPort[r],a=o[s],c=i[s];for(let s=0;s\u003ct.portCount;s++){const t=o[s]-a,l=i[s]-c;n[s*e.routeCount+r]=Math.sqrt(t*t+l*l)*this.DISTANCE_TO_COST}}}return{portHCostToEndOfRoute:n,portEndpointNetIds:r,portEndpointReservationNetId:s}}_setup(){if(this.problemSetup,this.STATIC_REACHABILITY_PRECHECK){const t=nF({topology:this.topology,problem:this.problem,problemSetup:this.problemSetup,portAssignment:this.state.portAssignment,routeIds:this.state.unroutedRoutes,maxPrecheckHops:Math.max(0,this.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),getStartingNextRegionId:(t,e)=\u003ethis.getStartingNextRegionId(t,e),getRouteSummary:t=\u003ethis.getRouteSummary(t)});this.staticallyUnroutableRoutes=t,t.length\u003e0\u0026\u0026(this.failed=!0,this.error=(t=\u003e{const e=t.slice(0,5).map(t=\u003e{const e=t.pointIds.length\u003e=2?`${t.pointIds[0]}-\u003e${t.pointIds[1]}`:`${t.startPortId}-\u003e${t.endPortId}`;return`${t.connectionId} (${e})`}).join(\", \"),n=t.length-5;return[\"Static reachability precheck failed:\",`${t.length} route(s) have no legal path under the current reservation and start-region rules`,n\u003e0?`${e}, +${n} more`:e].join(\" \")})(t),this.stats={...this.stats,staticallyUnroutableRouteCount:t.length})}}_step(){const{problem:t,topology:e,state:n}=this;if(void 0===n.currentRouteId){if(0===n.unroutedRoutes.length)return void this.onAllRoutesRouted();n.currentRouteId=n.unroutedRoutes.shift(),n.currentRouteNetId=t.routeNet[n.currentRouteId],this.routeAttemptCountByRouteId[n.currentRouteId]+=1,this.resetCandidateBestCosts();const e=this.getRouteStartPortId(n.currentRouteId);n.candidateQueue.clear();const o=this.getStartingNextRegionId(n.currentRouteId,e);if(void 0===o)return this.failed=!0,void(this.error=`Start port ${e} has no incident regions`);this.setCandidateBestCost(this.getHopId(e,o),0),n.candidateQueue.queue({nextRegionId:o,portId:e,f:0,g:0,h:0}),n.goalPortId=this.getRouteEndPortId(n.currentRouteId)}const o=n.candidateQueue.dequeue();if(!o)return void this.onOutOfCandidates();const i=this.getHopId(o.portId,o.nextRegionId);if(o.g\u003ethis.getCandidateBestCost(i))return;if(this.isRegionReservedForDifferentNet(o.nextRegionId))return;const r=e.regionIncidentPorts[o.nextRegionId];for(const i of r){const r=n.portAssignment[i];if(this.isPortReservedForDifferentNet(i))continue;if(i===n.goalPortId){if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;return void this.onPathFound(o)}if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;if(i===o.portId)continue;if(0===t.portSectionMask[i])continue;const s=e.incidentPortRegion[i][0]===o.nextRegionId?e.incidentPortRegion[i][1]:e.incidentPortRegion[i][0];if(void 0===s||this.isRegionReservedForDifferentNet(s))continue;const a=this.getHopId(i,s);if(!0===n.candidateQueue.isClosedHop?.(i,s))continue;const c=this.getCandidateBestCost(a);if(o.g\u003e=c)continue;const l=this.computeG(o,i,c);if(!Number.isFinite(l)||l\u003e=c)continue;const d=this.computeH(i),h={prevRegionId:o.nextRegionId,nextRegionId:s,portId:i,g:l,h:d,f:l+d,prevCandidate:o};if(i===n.goalPortId)return void this.onPathFound(h);this.setCandidateBestCost(a,l),n.candidateQueue.queue(h)}}resetCandidateBestCosts(){const{state:t}=this;if(this.candidateOverflowBestCost?.clear(),4294967295===t.candidateBestCostGeneration)return t.candidateBestCostByHopId instanceof Map\u0026\u0026t.candidateBestCostByHopId.clear(),t.candidateBestCostGenerationByHopId instanceof Map?t.candidateBestCostGenerationByHopId.clear():t.candidateBestCostGenerationByHopId.fill(0),void(t.candidateBestCostGeneration=1);t.candidateBestCostGeneration+=1}getCandidateBestCost(t){if(t\u003c0)return this.candidateOverflowBestCost?.get(t)??Number.POSITIVE_INFINITY;const{state:e}=this,n=e.candidateBestCostGenerationByHopId;return(n instanceof Map?n.get(t):n[t])===e.candidateBestCostGeneration?e.candidateBestCostByHopId instanceof Map?e.candidateBestCostByHopId.get(t):e.candidateBestCostByHopId[t]:Number.POSITIVE_INFINITY}setCandidateBestCost(t,e){if(t\u003c0)return this.candidateOverflowBestCost||(this.candidateOverflowBestCost=new Map),void this.candidateOverflowBestCost.set(t,e);const{state:n}=this;n.candidateBestCostGenerationByHopId instanceof Map?n.candidateBestCostGenerationByHopId.set(t,n.candidateBestCostGeneration):n.candidateBestCostGenerationByHopId[t]=n.candidateBestCostGeneration,n.candidateBestCostByHopId instanceof Map?n.candidateBestCostByHopId.set(t,e):n.candidateBestCostByHopId[t]=e}getHopId(t,e){const n=t*this.candidateHopSlotStride;if(this.candidateFirstRegionByPortId[t]===e)return n;if(this.candidateSecondRegionByPortId[t]===e)return n+1;const o=this.topology.incidentPortRegion[t];for(let t=2;t\u003c(o?.length??0);t++)if(o[t]===e)return n+t;return-(t*this.topology.regionCount+e)-1}getStartingNextRegionId(t,e){const n=this.topology.incidentPortRegion[e]??[],o=this.problem.routeNet[t];return n.find(t=\u003e-1===this.problem.regionNetId[t])??n.find(t=\u003ethis.problem.regionNetId[t]===o)??n[0]}getRouteStartPortId(t){return this.problem.routeStartPort[t]}getRouteEndPortId(t){return this.problem.routeEndPort[t]}isPortReservedForDifferentNet(t){const e=this.problemSetup.portEndpointReservationNetId[t]??-1;return-2===e||-1!==e\u0026\u0026e!==this.state.currentRouteNetId}isRegionReservedForDifferentNet(t){const e=this.problem.regionNetId[t];return-1!==e\u0026\u0026e!==this.state.currentRouteNetId}isKnownSingleLayerRegion(t){const e=this.topology.regionAvailableZMask?.[t]??0;return Xz(e)}computeRegionCostForRegion(t,e,n,o,i){return((t,e,n,o,i,r,s=0,a=.3,c=0)=\u003eVz(t*e,n,o,i,r,s,a,c))(this.topology.regionWidth[t],this.topology.regionHeight[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0,this.minViaPadDiameter,this.TRACE_DENSITY_COST_FACTOR)}populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.segmentGeometryScratch,r=this.candidateFirstRegionByPortId[e]===t||this.candidateSecondRegionByPortId[e]!==t?o.portAngleForRegion1[e]:o.portAngleForRegion2?.[e]??o.portAngleForRegion1[e],s=this.candidateFirstRegionByPortId[n]===t||this.candidateSecondRegionByPortId[n]!==t?o.portAngleForRegion1[n]:o.portAngleForRegion2?.[n]??o.portAngleForRegion1[n],a=o.portZ[e],c=o.portZ[n];return i.lesserAngle=r\u003cs?r:s,i.greaterAngle=r\u003cs?s:r,i.layerMask=1\u003c\u003ca|1\u003c\u003cc,i.entryExitLayerChanges=a!==c?1:0,i}appendSegmentToRegionCache(t,e,n){const{state:o}=this,i=o.regionIntersectionCaches[t],r=this.populateSegmentGeometryScratch(t,e,n),[s,a,c]=Hz(i,o.currentRouteNetId,r.lesserAngle,r.greaterAngle,r.layerMask,r.entryExitLayerChanges),l=i.netIds.length+1,d=new Int32Array(l);d.set(i.netIds),d[l-1]=o.currentRouteNetId;const h=new Int32Array(l);h.set(i.lesserAngles),h[l-1]=r.lesserAngle;const u=new Int32Array(l);u.set(i.greaterAngles),u[l-1]=r.greaterAngle;const p=new Int32Array(l);p.set(i.layerMasks),p[l-1]=r.layerMask;const m=i.existingSameLayerIntersections+s,g=i.existingCrossingLayerIntersections+a,f=i.existingEntryExitLayerChanges+c,y=h.length;o.regionIntersectionCaches[t]={netIds:d,lesserAngles:h,greaterAngles:u,layerMasks:p,existingSameLayerIntersections:m,existingCrossingLayerIntersections:g,existingEntryExitLayerChanges:f,existingSegmentCount:y,existingRegionCost:this.computeRegionCostForRegion(t,m,g,f,y)}}getSolvedPathSegments(t){const{state:e}=this,n=[];let o=t;for(;o;)n.unshift(o),o=o.prevCandidate;const i=[];for(let t=1;t\u003cn.length;t++)i.push({regionId:n[t-1].nextRegionId,fromPortId:n[t-1].portId,toPortId:n[t].portId});const r=n[n.length-1];return r\u0026\u0026r.portId!==e.goalPortId\u0026\u0026i.push({regionId:r.nextRegionId,fromPortId:r.portId,toPortId:e.goalPortId}),i}resetRoutingStateForRerip(){const{topology:t,problem:e,state:n}=this;n.portAssignment.fill(-1),n.regionSegments=Array.from({length:t.regionCount},()=\u003e[]),n.regionIntersectionCaches=Array.from({length:t.regionCount},()=\u003eqF()),n.currentRouteNetId=void 0,n.currentRouteId=void 0,n.unroutedRoutes=qz(oF(e.routeCount),n.ripCount),n.candidateQueue.clear(),this.resetCandidateBestCosts(),n.goalPortId=-1}getMaxRegionCost(){const{topology:t,state:e}=this;let n=0;for(let o=0;o\u003ct.regionCount;o++){const t=e.regionIntersectionCaches[o]?.existingRegionCost??0;n=Math.max(n,t)}return n}getRouteMetadata(t){return this.problem.routeMetadata?.[t]}getRouteConnectionId(t){const e=this.getRouteMetadata(t)?.connectionId;return\"string\"==typeof e?e:`route-${t}`}getRouteSummary(t){return(({problem:t,routeId:e,getRouteMetadata:n,getRouteConnectionId:o})=\u003e{const i=n?.(e)??Jz(t,e);return{routeId:e,connectionId:o?.(e)??Qz(t,e),startPortId:t.routeStartPort[e],endPortId:t.routeEndPort[e],startRegionId:\"string\"==typeof i?.startRegionId?i.startRegionId:void 0,endRegionId:\"string\"==typeof i?.endRegionId?i.endRegionId:void 0,pointIds:Kz(i)}})({problem:this.problem,routeId:t,getRouteMetadata:t=\u003ethis.getRouteMetadata(t),getRouteConnectionId:t=\u003ethis.getRouteConnectionId(t)})}getAdditionalRegionLabel(t){}getNeverSuccessfullyRoutedRoutes(){const t=[];for(let e=0;e\u003cthis.problem.routeCount;e++){const n=this.routeAttemptCountByRouteId[e];0===n||this.routeSuccessCountByRouteId[e]\u003e0||t.push({...this.getRouteSummary(e),attempts:n})}return t}getStaticallyUnroutableRoutes(){return this.staticallyUnroutableRoutes}logNeverSuccessfullyRoutedRoutes(){if(!this.VERBOSE||this.hasLoggedNeverSuccessfullyRoutedRoutes)return;const t=this.getNeverSuccessfullyRoutedRoutes();if(this.hasLoggedNeverSuccessfullyRoutedRoutes=!0,0!==t.length){console.log([\"[TinyHyperGraphSolver:never-routed-summary]\",`count=${t.length}`].join(\" \"));for(const e of t){const t=e.pointIds.length\u003e=2?`${e.pointIds[0]}-\u003e${e.pointIds[1]}`:\"unknown\";console.log([\"[TinyHyperGraphSolver:never-routed]\",`routeId=${e.routeId}`,`connectionId=${e.connectionId}`,`attempts=${e.attempts}`,`pointPath=${t}`,`startRegionId=${e.startRegionId??\"unknown\"}`,`endRegionId=${e.endRegionId??\"unknown\"}`].join(\" \"))}}}logRipEvent(t,e,n={}){this.VERBOSE\u0026\u0026console.log([\"[TinyHyperGraphSolver:rip]\",`ripCount=${this.state.ripCount}`,`maxRegionCostBeforeRip=${e.toFixed(3)}`,`reason=${t}`,...Object.entries(n).map(([t,e])=\u003e`${t}=${\"number\"==typeof e?Number.isInteger(e)?String(e):e.toFixed(3):e}`)].join(\" \"))}compareRegionCostSummaries(t,e){return t.maxRegionCost!==e.maxRegionCost?t.maxRegionCost-e.maxRegionCost:t.totalRegionCost-e.totalRegionCost}captureBestSolvedState(t){this.bestSolvedStateSummary\u0026\u0026this.compareRegionCostSummaries(t,this.bestSolvedStateSummary)\u003e=0||this.replaceBestSolvedState(t)}replaceBestSolvedState(t){this.bestSolvedStateSummary=t,this.bestSolvedStateSnapshot=KF({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches,regionCongestionCost:this.state.regionCongestionCost,ripCount:this.state.ripCount})}restoreBestSolvedState(){if(!this.bestSolvedStateSnapshot)return;const t=KF(this.bestSolvedStateSnapshot);this.state.portAssignment=t.portAssignment,this.state.regionSegments=t.regionSegments,this.state.regionIntersectionCaches=t.regionIntersectionCaches,this.state.regionCongestionCost=t.regionCongestionCost,this.state.ripCount=t.ripCount,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1}getRemainingRouteIdsForGreedyFinalRoute(){const t=new Set(this.state.unroutedRoutes);return void 0!==this.state.currentRouteId\u0026\u0026t.add(this.state.currentRouteId),[...t]}applySnapshotToGreedyFinalRouteSolver(t,e,n){const o=KF(e);t.state.portAssignment=o.portAssignment,t.state.regionSegments=o.regionSegments,t.state.regionIntersectionCaches=o.regionIntersectionCaches,t.state.regionCongestionCost=o.regionCongestionCost,t.state.ripCount=0,t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.state.unroutedRoutes=[...n],t.state.candidateQueue.clear(),t.resetCandidateBestCosts(),t.state.goalPortId=-1}summarizeSolvedState(t){let e=0,n=0;for(const o of t.state.regionIntersectionCaches){const t=o.existingRegionCost;e=Math.max(e,t),n+=t}return{maxRegionCost:e,totalRegionCost:n}}tryGreedyFinalRouteAcceptance(){const t=Math.max(0,Math.floor(this.GREEDY_FINAL_ROUTE_ITERS));if(0===t)return!1;const e=this.getRemainingRouteIdsForGreedyFinalRoute();if(0===e.length)return!1;const n=KF({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches,regionCongestionCost:this.state.regionCongestionCost,ripCount:this.state.ripCount});for(let o=0;o\u003ct;o++){const t=0===o?e:qz(e,this.state.ripCount+o),i=new oB(this.topology,this.problem,{...tB(this),ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!1,GREEDY_FINAL_ROUTE_ITERS:0,MAX_ITERATIONS:ZF,RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!1});if(this.applySnapshotToGreedyFinalRouteSolver(i,n,t),i.solve(),i.solved\u0026\u0026!i.failed)return this.bestSolvedStateSnapshot=KF({portAssignment:i.state.portAssignment,regionSegments:i.state.regionSegments,regionIntersectionCaches:i.state.regionIntersectionCaches,regionCongestionCost:i.state.regionCongestionCost,ripCount:i.state.ripCount}),this.bestSolvedStateSummary=this.summarizeSolvedState(i),this.restoreBestSolvedState(),this.stats={...this.stats,acceptedGreedyFinalRouteOnTimeout:!0,greedyFinalRouteIter:o,greedyFinalRouteRemainingRouteCount:e.length,greedyFinalRouteMaxIterations:ZF,neverSuccessfullyRoutedRouteCount:0,maxRegionCost:this.bestSolvedStateSummary.maxRegionCost,totalRegionCost:this.bestSolvedStateSummary.totalRegionCost,bestMaxRegionCost:this.bestSolvedStateSummary.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary.totalRegionCost},this.solved=!0,this.failed=!1,this.error=null,!0}return this.stats={...this.stats,greedyFinalRouteAttemptCount:t,greedyFinalRouteRemainingRouteCount:e.length,greedyFinalRouteMaxIterations:ZF},!1}onAllRoutesRouted(){const{topology:t,state:e}=this,n=this.RIP_THRESHOLD_RAMP_ATTEMPTS\u003c=0?1:Math.min(1,e.ripCount/this.RIP_THRESHOLD_RAMP_ATTEMPTS),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(t.regionCount);let s=0,a=0;for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;r[n]=t,s=Math.max(s,t),a+=t,t\u003eo\u0026\u0026i.push(n)}if(this.captureBestSolvedState({maxRegionCost:s,totalRegionCost:a}),this.stats={...this.stats,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:s,totalRegionCost:a,bestMaxRegionCost:this.bestSolvedStateSummary?.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary?.totalRegionCost,ripCount:e.ripCount},0===i.length||e.ripCount\u003e=this.RIP_THRESHOLD_RAMP_ATTEMPTS)this.solved=!0;else{for(let n=0;n\u003ct.regionCount;n++)e.regionCongestionCost[n]+=r[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCostBeforeRip:s,reripRegionCount:i.length},this.logRipEvent(\"hot_regions\",s,{hotRegionCount:i.length,currentRipThreshold:o})}}onOutOfCandidates(){const{topology:t,state:e}=this,n=e.currentRouteId,o=this.getMaxRegionCost();for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;e.regionCongestionCost[n]+=t*this.RIP_CONGESTION_REGION_COST_FACTOR}e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCost:o,maxRegionCostBeforeRip:o,reripReason:\"out_of_candidates\"},this.logRipEvent(\"out_of_candidates\",o,{...void 0===n?{}:{routeId:n,connectionId:this.getRouteConnectionId(n)}})}onPathFound(t){const{state:e}=this,n=e.currentRouteId;if(void 0===n)return;this.routeSuccessCountByRouteId[n]+=1;const o=this.getSolvedPathSegments(t);for(const{regionId:t,fromPortId:i,toPortId:r}of o)e.regionSegments[t].push([n,i,r]),e.portAssignment[i]=e.currentRouteNetId,e.portAssignment[r]=e.currentRouteNetId,this.appendSegmentToRegionCache(t,i,r);e.candidateQueue.clear(),e.currentRouteNetId=void 0,e.currentRouteId=void 0}computeG(t,e,n=Number.POSITIVE_INFINITY,o){const{state:i,topology:r}=this,s=t.nextRegionId,a=i.regionIntersectionCaches[s];let c=0;if(this.ADD_SEGMENT_DISTANCE_TO_G){let n=o;if(void 0===n){const o=r.portX[t.portId]-r.portX[e],i=r.portY[t.portId]-r.portY[e];n=Math.sqrt(o*o+i*i)}c=n*this.DISTANCE_TO_COST}if(t.g+i.regionCongestionCost[s]+(this.problem.portPenalty?.[e]??0)+c\u003en+1e-9)return Number.POSITIVE_INFINITY;const l=t.portId,d=this.candidateFirstRegionByPortId[l]===s||this.candidateSecondRegionByPortId[l]!==s?r.portAngleForRegion1[l]:r.portAngleForRegion2?.[l]??r.portAngleForRegion1[l],h=this.candidateFirstRegionByPortId[e]===s||this.candidateSecondRegionByPortId[e]!==s?r.portAngleForRegion1[e]:r.portAngleForRegion2?.[e]??r.portAngleForRegion1[e],u=d\u003ch?d:h,p=d\u003ch?h:d,m=r.portZ[l],g=r.portZ[e],f=1\u003c\u003cm|1\u003c\u003cg,y=m!==g?1:0,[_,b,x]=Hz(a,i.currentRouteNetId,u,p,f,y);if(_\u003e0\u0026\u0026this.isKnownSingleLayerRegion(s))return Number.POSITIVE_INFINITY;const v=this.computeRegionCostForRegion(s,a.existingSameLayerIntersections+_,a.existingCrossingLayerIntersections+b,a.existingEntryExitLayerChanges+x,a.existingSegmentCount+1)-a.existingRegionCost;return t.g+v+i.regionCongestionCost[s]+(this.problem.portPenalty?.[e]??0)+c}tryFinalAcceptance(){const t=this.getNeverSuccessfullyRoutedRoutes();if(this.stats={...this.stats,neverSuccessfullyRoutedRouteCount:t.length},this.ACCEPT_BEST_SOLUTION_ON_TIMEOUT\u0026\u0026this.bestSolvedStateSnapshot\u0026\u0026this.bestSolvedStateSummary)return this.restoreBestSolvedState(),this.stats={...this.stats,acceptedBestSolutionOnTimeout:!0,maxRegionCost:this.bestSolvedStateSummary.maxRegionCost,totalRegionCost:this.bestSolvedStateSummary.totalRegionCost,bestMaxRegionCost:this.bestSolvedStateSummary.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary.totalRegionCost},this.solved=!0,this.failed=!1,void(this.error=null);this.ACCEPT_BEST_SOLUTION_ON_TIMEOUT\u0026\u0026this.tryGreedyFinalRouteAcceptance()||this.logNeverSuccessfullyRoutedRoutes()}computeH(t){const e=this.problemSetup.portHCostToEndOfRoute;if(e)return e[t*this.problem.routeCount+this.state.currentRouteId];const n=this.getRouteEndPortId(this.state.currentRouteId),o=this.topology.portX[t]-this.topology.portX[n],i=this.topology.portY[t]-this.topology.portY[n];return Math.sqrt(o*o+i*i)*this.DISTANCE_TO_COST}visualize(){return UF(this)}getOutput(){return $z(this)}},oB=class extends nB{computeG(t,e){return t.g}},iB=class{constructor(t,e){this.regionCount=t,this.compactHopIndex=e,e\u0026\u0026(this.hopStateGeneration=new Uint32Array(e.hopCapacity),this.hopIndexOrClosed=new Int32Array(e.hopCapacity))}regionCount;compactHopIndex;items=[];indexByHopId=new Map;closedHopIds=new Set;hopStateGeneration;hopIndexOrClosed;currentHopStateGeneration=1;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0,this.indexByHopId.clear(),this.closedHopIds.clear(),this.hopStateGeneration\u0026\u0026(4294967295===this.currentHopStateGeneration?(this.hopStateGeneration.fill(0),this.currentHopStateGeneration=1):this.currentHopStateGeneration+=1)}isClosedHop(t,e){return this.isHopClosed(this.getHopIdFromValues(t,e))}queue(t){const e=this.getHopId(t);if(this.isHopClosed(e))return;const n=this.getQueuedHopIndex(e);if(void 0!==n){const e=this.items[n];if(t.g\u003e=e.g)return;return this.items[n]=t,void(t.f\u003c=e.f?this.siftUp(n):this.siftDown(n))}const o=this.items.length;this.items.push(t),this.siftUp(o)}dequeue(){const t=this.items[0];if(!t)return;const e=this.getHopId(t);this.closeHop(e);const n=this.items.pop();return this.items.length\u003e0\u0026\u0026(this.items[0]=n,this.siftDown(0)),t}getHopId(t){return this.getHopIdFromValues(t.portId,t.nextRegionId)}getHopIdFromValues(t,e){const n=this.compactHopIndex;if(!n)return t*this.regionCount+e;const o=t*n.hopSlotStride;if(n.firstRegionByPortId[t]===e)return o;if(n.secondRegionByPortId[t]===e)return o+1;const i=n.incidentPortRegion[t];for(let t=2;t\u003c(i?.length??0);t++)if(i[t]===e)return o+t;return-(t*this.regionCount+e)-1}getQueuedHopIndex(t){if(t\u003e=0\u0026\u0026this.hopStateGeneration?.[t]===this.currentHopStateGeneration){const e=this.hopIndexOrClosed[t];return e\u003e=0?e:void 0}return this.indexByHopId.get(t)}isHopClosed(t){return t\u003e=0\u0026\u0026this.hopStateGeneration?.[t]===this.currentHopStateGeneration?-1===this.hopIndexOrClosed[t]:this.closedHopIds.has(t)}setQueuedHopIndex(t,e){if(t\u003e=0\u0026\u0026this.hopStateGeneration)return this.hopStateGeneration[t]=this.currentHopStateGeneration,void(this.hopIndexOrClosed[t]=e);this.indexByHopId.set(t,e)}closeHop(t){if(t\u003e=0\u0026\u0026this.hopStateGeneration)return this.hopStateGeneration[t]=this.currentHopStateGeneration,void(this.hopIndexOrClosed[t]=-1);this.indexByHopId.delete(t),this.closedHopIds.add(t)}siftUp(t){const e=this.items[t];let n=t;for(;n\u003e0;){const t=n-1\u003e\u003e1,o=this.items[t];if(o.f\u003c=e.f)break;this.items[n]=o,this.setQueuedHopIndex(this.getHopId(o),n),n=t}this.items[n]=e,this.setQueuedHopIndex(this.getHopId(e),n)}siftDown(t){const e=this.items[t];let n=t;for(;;){const t=2*n+1;if(t\u003e=this.items.length)break;const o=t+1,i=o\u003cthis.items.length\u0026\u0026this.items[o].f\u003cthis.items[t].f?o:t,r=this.items[i];if(e.f\u003c=r.f)break;this.items[n]=r,this.setQueuedHopIndex(this.getHopId(r),n),n=i}this.items[n]=e,this.setQueuedHopIndex(this.getHopId(e),n)}},rB=class extends nB{constructor(t,e,n){super(t,e,n),this.ADD_SEGMENT_DISTANCE_TO_G=!0}_setup(){super._setup(),this.state.candidateQueue=new iB(this.topology.regionCount,{hopCapacity:this.candidateHopCapacity,hopSlotStride:this.candidateHopSlotStride,firstRegionByPortId:this.candidateFirstRegionByPortId,secondRegionByPortId:this.candidateSecondRegionByPortId,incidentPortRegion:this.topology.incidentPortRegion})}onPathFound(t){const e=this.state.goalPortId;if(t.portId===e)return void super.onPathFound(t);const n=this.computeG(t,e);if(!Number.isFinite(n))return;const o=this.getHopId(e,t.nextRegionId);n\u003e=this.getCandidateBestCost(o)||(this.setCandidateBestCost(o,n),this.state.candidateQueue.queue({prevRegionId:t.nextRegionId,nextRegionId:t.nextRegionId,portId:e,g:n,h:0,f:n,prevCandidate:t}))}},sB=new Set,aB=class extends rB{partialRipRoutePlans=new Map;outsideInRouteSearch;oneSidedFallbackRouteId;partialRipWindowDistance;partialRipCount=0;partiallyRippedRouteCount=0;partiallyRippedSegmentCount=0;retainedPartialRipSegmentCount=0;outsideInRouteCount=0;outsideInCompletedRouteCount=0;outsideInFallbackRouteCount=0;outsideInForwardExpansionCount=0;outsideInReverseExpansionCount=0;outsideInDistancePruneCount=0;completedRoundSummaries=[];firstCompletedRoundSummary;partialRipQualityBaselineSummary;bestSolvedRoundSummary;partialRipTargetReached=!1;useComplexityAwareSelection=!1;constructor(t,e,n){super(t,e,n),void 0===n?.PARTIAL_RIP_ENABLED\u0026\u0026(this.PARTIAL_RIP_ENABLED=!0),void 0===n?.OUTSIDE_IN_ROUTING\u0026\u0026(this.OUTSIDE_IN_ROUTING=!0),this.PARTIAL_RIP_ENABLED\u0026\u0026void 0===n?.PARTIAL_RIP_MAX_ATTEMPTS\u0026\u0026(this.PARTIAL_RIP_MAX_ATTEMPTS=10),(e.routeCount\u003cMath.max(0,this.PARTIAL_RIP_MIN_ROUTE_COUNT)||e.routeCount\u003eMath.max(0,this.PARTIAL_RIP_MAX_ROUTE_COUNT))\u0026\u0026(this.PARTIAL_RIP_ENABLED=!1,this.OUTSIDE_IN_ROUTING=!1),this.useComplexityAwareSelection=e.routeCount\u003e=Math.max(0,this.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT)}getRouteStartPortId(t){return this.PARTIAL_RIP_ENABLED?this.partialRipRoutePlans.get(t)?.activeStartPortId??super.getRouteStartPortId(t):super.getRouteStartPortId(t)}getRouteEndPortId(t){return this.PARTIAL_RIP_ENABLED?this.partialRipRoutePlans.get(t)?.activeEndPortId??super.getRouteEndPortId(t):super.getRouteEndPortId(t)}getStartingNextRegionId(t,e){if(!this.PARTIAL_RIP_ENABLED)return super.getStartingNextRegionId(t,e);const n=this.partialRipRoutePlans.get(t);return n\u0026\u0026n.activeStartPortId===e?n.forcedStartRegionId:super.getStartingNextRegionId(t,e)}getEndingNextRegionId(t,e){const n=this.partialRipRoutePlans.get(t);return n\u0026\u0026n.activeEndPortId===e?n.forcedEndRegionId:super.getStartingNextRegionId(t,e)}computeH(t){if(!this.PARTIAL_RIP_ENABLED)return super.computeH(t);const e=this.state.currentRouteId;if(void 0===e||!this.partialRipRoutePlans.has(e))return super.computeH(t);const n=this.getRouteEndPortId(e),o=this.topology.portX[t]-this.topology.portX[n],i=this.topology.portY[t]-this.topology.portY[n];return Math.sqrt(o*o+i*i)*this.DISTANCE_TO_COST}onPathFound(t){if(!this.PARTIAL_RIP_ENABLED\u0026\u0026!this.OUTSIDE_IN_ROUTING)return void super.onPathFound(t);const e=this.state.currentRouteId,n=void 0!==e\u0026\u0026this.outsideInRouteSearch?.routeId===e;super.onPathFound(t),void 0!==e\u0026\u0026void 0===this.state.currentRouteId\u0026\u0026(this.partialRipRoutePlans.delete(e),n\u0026\u0026(this.outsideInCompletedRouteCount+=1),this.oneSidedFallbackRouteId===e\u0026\u0026(this.oneSidedFallbackRouteId=void 0)),this.outsideInRouteSearch=void 0,this.publishOutsideInStats()}resetRoutingStateForRerip(){this.PARTIAL_RIP_ENABLED||this.OUTSIDE_IN_ROUTING?(this.partialRipRoutePlans.clear(),this.outsideInRouteSearch=void 0,this.oneSidedFallbackRouteId=void 0,super.resetRoutingStateForRerip()):super.resetRoutingStateForRerip()}clearPartialRipPlans(t){for(const e of t)this.partialRipRoutePlans.delete(e)}getRouteIdsPreferredForPreservation(){return sB}getCommittedRouteSegments(t){const e=[];for(let n=0;n\u003cthis.state.regionSegments.length;n++)for(const[o,i,r]of this.state.regionSegments[n]??[])o===t\u0026\u0026e.push({segmentIndex:e.length,regionId:n,fromPortId:i,toPortId:r});if(0===e.length)return;const n=new Map;for(const t of e)for(const e of[t.fromPortId,t.toPortId]){const o=n.get(e)??[];o.push(t.segmentIndex),n.set(e,o)}const o=this.problem.routeEndPort[t],i=[],r=new Set,s=new Set([this.problem.routeStartPort[t]]),a=t=\u003e{if(t===o)return!0;for(const o of n.get(t)??[]){if(r.has(o))continue;const n=e[o],c=n.fromPortId===t?n.toPortId:n.fromPortId;if(!s.has(c)){if(r.add(o),s.add(c),i.push({regionId:n.regionId,fromPortId:t,toPortId:c}),a(c))return!0;i.pop(),s.delete(c),r.delete(o)}}return!1};return a(this.problem.routeStartPort[t])\u0026\u0026r.size===e.length?i:void 0}getSegmentDistance(t){const e=this.topology.portX[t.fromPortId]-this.topology.portX[t.toPortId],n=this.topology.portY[t.fromPortId]-this.topology.portY[t.toPortId];return Math.sqrt(e*e+n*n)}getPartialRipWindow(t,e,n){let o,i=Number.NEGATIVE_INFINITY;for(let r=0;r\u003ct.length;r++){const s=t[r];if(!e.has(s.regionId))continue;const a=n[s.regionId]??0;a\u003ei\u0026\u0026(i=a,o=r)}if(void 0===o)return;const r=Math.max(0,this.partialRipWindowDistance??this.PARTIAL_RIP_MAX_DISTANCE);let s=o,a=o,c=this.getSegmentDistance(t[o])/2,l=c;for(;s\u003e0;){const e=this.getSegmentDistance(t[s-1]);if(c+e\u003er)break;s-=1,c+=e}for(;a+1\u003ct.length;){const e=this.getSegmentDistance(t[a+1]);if(l+e\u003er)break;a+=1,l+=e}return{startIndex:s,endIndex:a}}appendRetainedSegment(t,e,n){t[n.regionId].push([e,n.fromPortId,n.toPortId])}preparePartialRip(t,e){if(!this.PARTIAL_RIP_ENABLED||0===t.length)return!1;const n=new Set(t);if(void 0===this.partialRipWindowDistance){let n=0;for(const o of t)n=Math.max(n,e[o]??0);const o=Math.max(0,this.PARTIAL_RIP_MAX_DISTANCE),i=Math.max(o,this.PARTIAL_RIP_QUALITY_MAX_DISTANCE??2*o);this.partialRipWindowDistance=n\u003c=1.5*this.RIP_THRESHOLD_END?i:o}const o=new Set;for(const e of t)for(const[t]of this.state.regionSegments[e]??[])o.add(t);if(0===o.size)return!1;const i=this.getRouteIdsPreferredForPreservation(),r=[...o].some(t=\u003e!i.has(t)),s=Array.from({length:this.topology.regionCount},()=\u003e[]),a=new Map;let c=0,l=0;for(let t=0;t\u003cthis.problem.routeCount;t++){const d=this.getCommittedRouteSegments(t);if(!d)return!1;if(!o.has(t)||r\u0026\u0026i.has(t)){for(const e of d)this.appendRetainedSegment(s,t,e),l+=1;continue}const h=this.getPartialRipWindow(d,n,e);if(!h)return!1;for(let e=0;e\u003cd.length;e++){const n=d[e];e\u003e=h.startIndex\u0026\u0026e\u003c=h.endIndex?c+=1:(this.appendRetainedSegment(s,t,n),l+=1)}const u=d[h.startIndex],p=d[h.endIndex];a.set(t,{routeId:t,activeStartPortId:u.fromPortId,activeEndPortId:p.toPortId,forcedStartRegionId:u.regionId,forcedEndRegionId:p.regionId,rippedSegmentCount:h.endIndex-h.startIndex+1,retainedSegmentCount:d.length-(h.endIndex-h.startIndex+1)})}return 0!==a.size\u0026\u00260!==c\u0026\u0026(this.partialRipRoutePlans=a,this.rebuildRetainedRoutingState(s,[...a.keys()]),this.partialRipCount+=1,this.partiallyRippedRouteCount+=a.size,this.partiallyRippedSegmentCount+=c,this.retainedPartialRipSegmentCount+=l,this.publishPartialRipStats(),!0)}rebuildRetainedRoutingState(t,e){this.state.portAssignment.fill(-1),this.state.regionSegments=Array.from({length:this.topology.regionCount},()=\u003e[]),this.state.regionIntersectionCaches=Array.from({length:this.topology.regionCount},()=\u003eqF()),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=e,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.outsideInRouteSearch=void 0,this.oneSidedFallbackRouteId=void 0;for(let e=0;e\u003ct.length;e++)for(const[n,o,i]of t[e]??[]){const t=this.problem.routeNet[n];this.state.currentRouteNetId=t;for(const e of[o,i]){const n=this.state.portAssignment[e];if(-1!==n\u0026\u0026n!==t)throw new Error(`OutsideInPartialRipTinyHyperGraphSolver: retained port ${e} belongs to multiple nets`);this.state.portAssignment[e]=t}this.state.regionSegments[e].push([n,o,i]),this.appendSegmentToRegionCache(e,o,i)}this.state.currentRouteNetId=void 0}publishPartialRipStats(){this.stats={...this.stats,partialRipCount:this.partialRipCount,partiallyRippedRouteCount:this.partiallyRippedRouteCount,partiallyRippedSegmentCount:this.partiallyRippedSegmentCount,retainedPartialRipSegmentCount:this.retainedPartialRipSegmentCount,partialRipMaxDistance:this.partialRipWindowDistance??this.PARTIAL_RIP_MAX_DISTANCE,partialRipBaseMaxDistance:this.PARTIAL_RIP_MAX_DISTANCE,partialRipQualityMaxDistance:this.PARTIAL_RIP_QUALITY_MAX_DISTANCE??2*this.PARTIAL_RIP_MAX_DISTANCE,partialRipMaxAttempts:this.PARTIAL_RIP_MAX_ATTEMPTS}}publishOutsideInStats(){this.stats={...this.stats,outsideInRouteCount:this.outsideInRouteCount,outsideInCompletedRouteCount:this.outsideInCompletedRouteCount,outsideInFallbackRouteCount:this.outsideInFallbackRouteCount,outsideInForwardExpansionCount:this.outsideInForwardExpansionCount,outsideInReverseExpansionCount:this.outsideInReverseExpansionCount,outsideInDistancePruneCount:this.outsideInDistancePruneCount,outsideInMaxDistance:this.OUTSIDE_IN_MAX_DISTANCE}}createOutsideInFrontier(t,e,n){const o=new Zz([],(t,e)=\u003et.f===e.f?t.g-e.g:t.f-e.f),i=this.topology.portX[t]-this.topology.portX[n],r=this.topology.portY[t]-this.topology.portY[n],s=Math.sqrt(i*i+r*r)*this.DISTANCE_TO_COST,a={portId:t,nextRegionId:e,f:s,g:0,h:s,travelDistance:0};return o.queue(a),{queue:o,bestCostByHopId:new Map([[this.getHopId(t,e),0]]),settledByPortId:new Map,settledByRegionId:new Map,targetPortId:n}}startOutsideInRouteSearch(t){const e=this.getRouteStartPortId(t),n=this.getRouteEndPortId(t),o=this.getStartingNextRegionId(t,e),i=this.getEndingNextRegionId(t,n);return void 0!==o\u0026\u0026void 0!==i\u0026\u0026(this.state.goalPortId=n,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.outsideInRouteSearch={routeId:t,forward:this.createOutsideInFrontier(e,o,n),reverse:this.createOutsideInFrontier(n,i,e),expandForwardNext:!0,distanceLimitHit:!1,bestJoinedCost:Number.POSITIVE_INFINITY},this.outsideInRouteCount+=1,this.publishOutsideInStats(),!0)}dequeueFreshCandidate(t){for(;t.queue.length\u003e0;){const e=t.queue.dequeue(),n=this.getHopId(e.portId,e.nextRegionId);if(e.g\u003c=(t.bestCostByHopId.get(n)??1/0))return e}}recordSettledCandidate(t,e){const n=t.settledByPortId.get(e.portId);(!n||e.g\u003cn.g)\u0026\u0026t.settledByPortId.set(e.portId,e);const o=t.settledByRegionId.get(e.nextRegionId)??[];o.push(e),o.sort((t,e)=\u003et.g-e.g),o.length\u003e16\u0026\u0026(o.length=16),t.settledByRegionId.set(e.nextRegionId,o)}getCandidatePath(t){const e=[];let n=t;for(;n;)e.push(n),n=n.prevCandidate;return e.reverse(),e}buildJoinedCandidate(t,e){const n=this.getCandidatePath(t),o=this.getCandidatePath(e),i=n.map(({portId:t})=\u003et),r=n.slice(0,-1).map(({nextRegionId:t})=\u003et);if(t.portId!==e.portId){if(t.nextRegionId!==e.nextRegionId)return;const n=this.topology.portX[t.portId]-this.topology.portX[e.portId],o=this.topology.portY[t.portId]-this.topology.portY[e.portId],s=Math.sqrt(n*n+o*o);if(t.travelDistance+e.travelDistance+s\u003e2*this.OUTSIDE_IN_MAX_DISTANCE)return;const a=this.computeG(t,e.portId);if(!Number.isFinite(a))return;r.push(t.nextRegionId),i.push(e.portId)}for(let t=o.length-2;t\u003e=0;t--){const e=o[t];r.push(e.nextRegionId),i.push(e.portId)}if(new Set(i).size!==i.length||r.length+1!==i.length)return;let s={portId:i[0],nextRegionId:r[0],f:0,g:0,h:0};for(let t=1;t\u003ci.length;t++)s={portId:i[t],prevRegionId:r[t-1],nextRegionId:r[t]??r[t-1],prevCandidate:s,f:0,g:0,h:0};const a=t.portId===e.portId?0:this.computeG(t,e.portId)-t.g;return{candidate:s,cost:t.g+e.g+a}}considerOutsideInJoins(t,e){const n=this.outsideInRouteSearch,o=e?n.reverse:n.forward,i=t=\u003e{!t||t.cost\u003e=n.bestJoinedCost||(n.bestJoinedCandidate=t.candidate,n.bestJoinedCost=t.cost,n.remainingPostMeetingExpansions=24)},r=o.settledByPortId.get(t.portId);r\u0026\u0026i(e?this.buildJoinedCandidate(t,r):this.buildJoinedCandidate(r,t));for(const n of o.settledByRegionId.get(t.nextRegionId)??[])i(e?this.buildJoinedCandidate(t,n):this.buildJoinedCandidate(n,t))}commitBestOutsideInJoin(){const t=this.outsideInRouteSearch?.bestJoinedCandidate;return!!t\u0026\u0026(this.onPathFound(t),!0)}expandOutsideInFrontier(t){const e=this.outsideInRouteSearch,n=t?e.forward:e.reverse,o=this.dequeueFreshCandidate(n);if(!o)return!1;if(t?this.outsideInForwardExpansionCount+=1:this.outsideInReverseExpansionCount+=1,this.isRegionReservedForDifferentNet(o.nextRegionId))return!0;this.recordSettledCandidate(n,o),this.considerOutsideInJoins(o,t);for(const t of this.topology.regionIncidentPorts[o.nextRegionId]??[]){if(t===o.portId)continue;if(this.isPortReservedForDifferentNet(t))continue;const i=this.state.portAssignment[t];if(-1!==i\u0026\u0026i!==this.state.currentRouteNetId)continue;if(t!==n.targetPortId\u0026\u00260===this.problem.portSectionMask[t])continue;const r=this.topology.portX[o.portId]-this.topology.portX[t],s=this.topology.portY[o.portId]-this.topology.portY[t],a=Math.sqrt(r*r+s*s),c=o.travelDistance+a;if(c\u003ethis.OUTSIDE_IN_MAX_DISTANCE){e.distanceLimitHit=!0,this.outsideInDistancePruneCount+=1;continue}const l=this.topology.incidentPortRegion[t]?.[0]===o.nextRegionId?this.topology.incidentPortRegion[t]?.[1]:this.topology.incidentPortRegion[t]?.[0];if(void 0===l||this.isRegionReservedForDifferentNet(l))continue;const d=this.getHopId(t,l),h=n.bestCostByHopId.get(d)??1/0;if(o.g\u003e=h)continue;const u=this.computeG(o,t,h,a);if(!Number.isFinite(u)||u\u003e=h)continue;n.bestCostByHopId.set(d,u);const p=this.topology.portX[t]-this.topology.portX[n.targetPortId],m=this.topology.portY[t]-this.topology.portY[n.targetPortId],g=Math.sqrt(p*p+m*m)*this.DISTANCE_TO_COST;n.queue.queue({portId:t,prevRegionId:o.nextRegionId,nextRegionId:l,prevCandidate:o,f:u+g,g:u,h:g,travelDistance:c})}return!0}fallBackToOneSidedRouteSearch(){const t=this.state.currentRouteId;void 0!==t\u0026\u0026(this.outsideInRouteSearch=void 0,this.outsideInFallbackRouteCount+=1,this.oneSidedFallbackRouteId=t,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.goalPortId=-1,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.unroutedRoutes.unshift(t),this.publishOutsideInStats())}_step(){if(!this.OUTSIDE_IN_ROUTING)return void super._step();const t=this.state.currentRouteId??this.state.unroutedRoutes[0];if(void 0!==t\u0026\u0026!this.partialRipRoutePlans.has(t))return void super._step();if(void 0!==this.oneSidedFallbackRouteId)return void super._step();if(void 0===this.state.currentRouteId){if(0===this.state.unroutedRoutes.length)return void this.onAllRoutesRouted();const t=this.state.unroutedRoutes.shift();if(this.state.currentRouteId=t,this.state.currentRouteNetId=this.problem.routeNet[t],this.routeAttemptCountByRouteId[t]+=1,!this.startOutsideInRouteSearch(t))return this.failed=!0,void(this.error=`Route ${t} has an endpoint without an incident region`)}const e=this.outsideInRouteSearch;if(!e)return;let n=this.expandOutsideInFrontier(e.expandForwardNext);if(void 0!==this.state.currentRouteId\u0026\u0026(n||(n=this.expandOutsideInFrontier(!e.expandForwardNext),void 0!==this.state.currentRouteId)))if(e.expandForwardNext=!e.expandForwardNext,e.bestJoinedCandidate\u0026\u0026(e.remainingPostMeetingExpansions=(e.remainingPostMeetingExpansions??1)-1,(e.remainingPostMeetingExpansions??0)\u003c=0))this.commitBestOutsideInJoin();else{if(!n\u0026\u00260===e.forward.queue.length\u0026\u00260===e.reverse.queue.length){if(this.commitBestOutsideInJoin())return;this.outsideInRouteSearch=void 0,e.distanceLimitHit?this.fallBackToOneSidedRouteSearch():this.onOutOfCandidates()}this.publishOutsideInStats()}}shouldReplaceBestSolvedState(t){const e=this.bestSolvedRoundSummary;if(!e)return!0;if(!this.useComplexityAwareSelection)return this.compareRegionCostSummaries(t,e)\u003c0;const n=this.partialRipQualityBaselineSummary;if(!n)return this.compareRegionCostSummaries(t,e)\u003c0;const o=this.firstCompletedRoundSummary??n,i=o.maxRegionCost*(1+Math.max(0,this.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO)),r=o.totalRegionCost*(1+Math.max(0,this.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO)),s=t.maxRegionCost\u003c=i\u0026\u0026t.totalRegionCost\u003c=r;return s!==(e.maxRegionCost\u003c=i\u0026\u0026e.totalRegionCost\u003c=r)?s:s\u0026\u0026t.segmentCount!==e.segmentCount?t.segmentCount\u003ce.segmentCount:this.compareRegionCostSummaries(t,e)\u003c0}onAllRoutesRouted(){if(!this.PARTIAL_RIP_ENABLED)return void super.onAllRoutesRouted();const{state:t,topology:e}=this,n=Math.min(this.RIP_THRESHOLD_RAMP_ATTEMPTS,this.PARTIAL_RIP_MAX_ATTEMPTS),o=Math.max(0,this.RIP_THRESHOLD_RAMP_ATTEMPTS),i=o\u003c=0?1:Math.min(1,t.ripCount/o),r=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*i,s=new Float64Array(e.regionCount),a=[];let c=0,l=0,d=0,h=0,u=0;for(let n=0;n\u003ce.regionCount;n++){const e=t.regionIntersectionCaches[n]?.existingRegionCost??0;s[n]=e,c=Math.max(c,e),l+=e;const o=t.regionSegments[n]?.length??0;d+=o,h=Math.max(h,o),u+=o*o,e\u003er\u0026\u0026a.push(n)}const p={maxRegionCost:c,totalRegionCost:l},m={...p,ripCount:t.ripCount,segmentCount:d,maxRegionSegmentCount:h,squaredRegionSegmentCount:u};this.completedRoundSummaries.push(m),this.firstCompletedRoundSummary??=m,void 0===this.partialRipQualityBaselineSummary\u0026\u0026t.ripCount\u003e=Math.max(0,this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS)\u0026\u0026(this.partialRipQualityBaselineSummary=m);this.shouldReplaceBestSolvedState(m)\u0026\u0026(this.replaceBestSolvedState(p),this.bestSolvedRoundSummary=m);const g=this.firstCompletedRoundSummary,f=this.partialRipQualityBaselineSummary??g,y=Math.max(0,this.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO),_=Math.max(0,this.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO),b=f.maxRegionCost*(1-y),x=f.totalRegionCost*(1+_),v=this.useComplexityAwareSelection\u0026\u0026t.ripCount\u003ef.ripCount\u0026\u0026y\u003e0\u0026\u0026c\u003c=b\u0026\u0026l\u003c=x\u0026\u0026d\u003c=f.segmentCount;if(v\u0026\u0026(this.partialRipTargetReached=!0),this.stats={...this.stats,currentRipThreshold:r,hotRegionCount:a.length,maxRegionCost:c,totalRegionCost:l,bestMaxRegionCost:this.bestSolvedStateSummary?.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary?.totalRegionCost,ripCount:t.ripCount,completedRoundSummaries:this.completedRoundSummaries.map(t=\u003e({...t})),firstMaxRegionCost:g.maxRegionCost,firstTotalRegionCost:g.totalRegionCost,firstSegmentCount:g.segmentCount,firstMaxRegionSegmentCount:g.maxRegionSegmentCount,firstSquaredRegionSegmentCount:g.squaredRegionSegmentCount,partialRipQualityBaselineRipCount:f.ripCount,partialRipQualityBaselineMaxRegionCost:f.maxRegionCost,partialRipQualityBaselineTotalRegionCost:f.totalRegionCost,partialRipQualityBaselineSegmentCount:f.segmentCount,partialRipQualityBaselineMaxRegionSegmentCount:f.maxRegionSegmentCount,partialRipQualityBaselineSquaredRegionSegmentCount:f.squaredRegionSegmentCount,bestSolvedSegmentCount:this.bestSolvedRoundSummary?.segmentCount,bestSolvedMaxRegionSegmentCount:this.bestSolvedRoundSummary?.maxRegionSegmentCount,bestSolvedSquaredRegionSegmentCount:this.bestSolvedRoundSummary?.squaredRegionSegmentCount,partialRipTargetMaxRegionCost:b,partialRipMaxTargetTotalRegionCost:x,partialRipComplexityAwareSelection:this.useComplexityAwareSelection,partialRipComplexitySelectionMinRouteCount:this.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT,partialRipMaxRegionCostGrowthRatio:this.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO,partialRipTargetReached:this.partialRipTargetReached},this.publishPartialRipStats(),0===a.length||v||t.ripCount\u003e=n)return this.restoreBestSolvedState(),void(this.solved=!0);for(let n=0;n\u003ce.regionCount;n++)t.regionCongestionCost[n]+=s[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;const S=t.ripCount\u003cMath.max(0,this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS);t.ripCount+=1;const I=!S\u0026\u0026this.preparePartialRip(a,s);I||this.resetRoutingStateForRerip();const C=S?\"warmup_full\":I?\"partial\":\"full_fallback\";this.stats={...this.stats,ripCount:t.ripCount,maxRegionCostBeforeRip:c,reripRegionCount:a.length,reripMode:C,partialRipWarmupFullRipAttempts:this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS},this.logRipEvent(\"hot_regions\",c,{hotRegionCount:a.length,currentRipThreshold:r,reripMode:C,partialRouteCount:I?this.partialRipRoutePlans.size:0})}},cB=t=\u003e{const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;return Number.isFinite(e)?e:void 0},lB=t=\u003e{const e=new Set;for(const n of t.connections??[])e.add(n.startRegionId),e.add(n.endRegionId);const n=new Set(t.regions.filter(t=\u003e(t=\u003e{if(!0!==t.d?._containsObstacle)return!1;const e=cB(t);return void 0===e||-1===e})(t)\u0026\u0026!e.has(t.regionId)).map(t=\u003et.regionId));if(0===n.size)return t;const o=t.ports.filter(t=\u003e!n.has(t.region1Id)\u0026\u0026!n.has(t.region2Id)),i=(t.connections??[]).find(t=\u003en.has(t.startRegionId)||n.has(t.endRegionId));if(i)throw new Error(`Connection \"${i.connectionId}\" references full-obstacle region`);return{...t,regions:t.regions.filter(t=\u003e!n.has(t.regionId)),ports:o}},dB=t=\u003e{const e=t.d?.bounds;if(e)return e;const n=t.d?.center,o=t.d?.width,i=t.d?.height;return n\u0026\u0026\"number\"==typeof n.x\u0026\u0026\"number\"==typeof n.y\u0026\u0026\"number\"==typeof o\u0026\u0026\"number\"==typeof i?{minX:n.x-o/2,maxX:n.x+o/2,minY:n.y-i/2,maxY:n.y+i/2}:{minX:0,maxX:0,minY:0,maxY:0}},hB=t=\u003eNumber(t.d?.x??0),uB=t=\u003eNumber(t.d?.y??0),pB=(t,e)=\u003e{if(!e)return 0;const n=dB(e),o=hB(t),i=uB(t),r=n.minX\u003c=o\u0026\u0026o\u003c=n.maxX,s=n.minY\u003c=i\u0026\u0026i\u003c=n.maxY;if(s\u0026\u0026o\u003e=n.maxX){const t=Math.max(n.maxY-n.minY,1e-9),e=(i-n.minY)/t;return Math.round(9e3*e)}if(r\u0026\u0026i\u003e=n.maxY){const t=Math.max(n.maxX-n.minX,1e-9),e=(n.maxX-o)/t;return 9e3+Math.round(9e3*e)}if(s\u0026\u0026o\u003c=n.minX){const t=Math.max(n.maxY-n.minY,1e-9),e=(n.maxY-i)/t;return 18e3+Math.round(9e3*e)}if(r\u0026\u0026i\u003c=n.minY){const t=Math.max(n.maxX-n.minX,1e-9),e=(o-n.minX)/t;return 27e3+Math.round(9e3*e)}const a=Math.abs(o-n.minX),c=Math.abs(o-n.maxX),l=Math.abs(i-n.minY),d=Math.abs(i-n.maxY),h=Math.min(a,c,l,d),u=Math.max(n.maxX-n.minX,1e-9),p=Math.max(n.maxY-n.minY,1e-9);if(h===c){const t=(i-n.minY)/p;return Math.round(9e3*t)}if(h===d){const t=(n.maxX-o)/u;return 9e3+Math.round(9e3*t)}if(h===a){const t=(n.maxY-i)/p;return 18e3+Math.round(9e3*t)}const m=(o-n.minX)/u;return 27e3+Math.round(9e3*m)},mB=(t,e)=\u003e{if(!t)return;return[...t.pointIds].sort((t,n)=\u003e{const o=e.get(t),i=e.get(n),r=Number(o?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY),s=Number(i?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY);if(r!==s)return r-s;const a=Number(o?.d?.z??0),c=Number(i?.d?.z??0);return a!==c?a-c:t.localeCompare(n)})[0]},gB=t=\u003e{const e=lB(t),n=new Map,o=new Map,i=new Map,r=new Map((e.solvedRoutes??[]).map(t=\u003e[t.connection.connectionId,t]));e.regions.forEach((t,e)=\u003e{n.set(t.regionId,e)}),e.ports.forEach((t,e)=\u003e{o.set(t.portId,e),i.set(t.portId,t)});const s=e.regions.length,a=e.ports.length,c=e.regions.map(t=\u003et.pointIds.map(t=\u003eo.get(t)).filter(t=\u003evoid 0!==t)),l=Array.from({length:a},()=\u003e[]),d=new Float64Array(s),h=new Float64Array(s),u=new Float64Array(s),p=new Float64Array(s),m=new Int32Array(s),g=new Int32Array(s).fill(-1),f=new Int8Array(s);e.regions.forEach((t,e)=\u003e{const n=(t=\u003e{const e=dB(t),n=\"number\"==typeof t.d?.width?t.d.width:e.maxX-e.minX,o=\"number\"==typeof t.d?.height?t.d.height:e.maxY-e.minY;return{centerX:\"number\"==typeof t.d?.center?.x?t.d.center.x:(e.minX+e.maxX)/2,centerY:\"number\"==typeof t.d?.center?.y?t.d.center.y:(e.minY+e.maxY)/2,width:n,height:o}})(t);d[e]=n.width,h[e]=n.height,u[e]=n.centerX,p[e]=n.centerY,m[e]=(t=\u003e{const e=t.d?.availableZ;if(!Array.isArray(e))return 0;let n=0;for(const t of e)!Number.isInteger(t)||t\u003c0||t\u003e=31||(n|=1\u003c\u003ct);return n})(t);const o=cB(t);void 0!==o\u0026\u0026(g[e]=o,f[e]=1)});const y=new Int32Array(a),_=new Int32Array(a),b=new Float64Array(a),x=new Float64Array(a),v=new Int32Array(a);e.ports.forEach((t,o)=\u003e{const i=n.get(t.region1Id),r=n.get(t.region2Id);if(void 0===i||void 0===r)throw new Error(`Port \"${t.portId}\" references missing regions \"${t.region1Id}\" or \"${t.region2Id}\"`);l[o]=[i,r],b[o]=hB(t),x[o]=uB(t),v[o]=(t=\u003e{const e=Number(t.d?.z??0);return Number.isFinite(e)?e:0})(t),y[o]=pB(t,e.regions[i]),_[o]=pB(t,e.regions[r])});const S=e.regions.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedRegionId\",{value:t.regionId,enumerable:!1,configurable:!0,writable:!0}),n})(t,(t=\u003eRz(Ez(m[t]))??Rz((c[t]??[]).map(t=\u003ev[t]))??\"z0\")(e))),I=e.ports.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedPortId\",{value:t.portId,enumerable:!1,configurable:!0,writable:!0}),n})(t,Rz([v[e]])??\"z0\")),C=e.connections??[],P=new Map;let M=0;const N=t=\u003e{const e=t.mutuallyConnectedNetworkId??t.connectionId;let n=P.get(e);return void 0===n\u0026\u0026(n=M++,P.set(e,n)),n},w=Array.from({length:s},()=\u003enew Set),T=(t,e)=\u003e{const o=n.get(t);if(void 0===o)throw new Error(`Connection references missing region \"${t}\"`);w[o].add(e)};C.forEach(t=\u003e{const e=N(t);T(t.startRegionId,e),T(t.endRegionId,e)}),w.forEach((t,e)=\u003e{1!==f[e]\u0026\u00261===t.size\u0026\u0026(g[e]=[...t][0])});const R=C.map(t=\u003e{const n=r.get(t.connectionId),o=((t,e)=\u003et.ports.filter(t=\u003et.region1Id===e.startRegionId\u0026\u0026t.region2Id===e.endRegionId||t.region2Id===e.startRegionId\u0026\u0026t.region1Id===e.endRegionId).map(t=\u003et.portId))(e,t);return{connection:t,solvedRoute:n,sharedPortIds:o}}).filter(({solvedRoute:t,sharedPortIds:e})=\u003e0===e.length||(t?.path.length??0)\u003e1),E=R.length,A=new Map(R.map(({connection:t},e)=\u003e[t.connectionId,e])),O=new Int8Array(a).fill(1),k=new Int32Array(E),L=new Int32Array(E),D=new Int32Array(E);R.forEach(({connection:t,solvedRoute:n},r)=\u003e{const s=mB(e.regions.find(e=\u003ee.regionId===t.startRegionId),i),a=mB(e.regions.find(e=\u003ee.regionId===t.endRegionId),i),c=n?.path[0]?.portId??s,l=n?.path[n.path.length-1]?.portId??a,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)throw new Error(`Connection \"${t.connectionId}\" could not be mapped to route endpoints`);k[r]=d,L[r]=h,D[r]=N(t)});const z={portCount:a,regionCount:s,regionIncidentPorts:c,incidentPortRegion:l,regionWidth:d,regionHeight:h,regionCenterX:u,regionCenterY:p,regionAvailableZMask:m,regionMetadata:S,portAngleForRegion1:y,portAngleForRegion2:_,portX:b,portY:x,portZ:v,portMetadata:I},F=e.regions.flatMap((t,e)=\u003e(t.assignments??[]).map(n=\u003e{const i=A.get(n.connectionId);if(void 0===i)throw new Error(`Region \"${t.regionId}\" assignment references unknown routable connection \"${n.connectionId}\"`);const r=o.get(n.regionPort1Id),s=o.get(n.regionPort2Id);if(void 0===r||void 0===s)throw new Error(`Region \"${t.regionId}\" assignment references missing port \"${void 0===r?n.regionPort1Id:n.regionPort2Id}\"`);if(!c[e]?.includes(r)||!c[e]?.includes(s))throw new Error(`Region \"${t.regionId}\" assignment ports must both belong to the region`);return{routeId:i,regionId:e,fromPortId:r,toPortId:s}})),B=Float64Array.from(e.ports,t=\u003e{const e=Number(t.d?.tinyHypergraphPortPenalty??0);return Number.isFinite(e)\u0026\u0026e\u003e0?e:0}),j=B.some(t=\u003et\u003e0),$={routeCount:E,portSectionMask:O,routeMetadata:R.map(({connection:t})=\u003et),routeStartPort:k,routeEndPort:L,routeNet:D,regionNetId:g,...F.length\u003e0\u0026\u0026{initialAssignments:F},...j\u0026\u0026{portPenalty:B}},Y=[],X=[];for(const{solvedRoute:t}of R){if(!t){Y.push([]),X.push([]);continue}const e=[],i=[];for(let r=1;r\u003ct.path.length;r++){const s=t.path[r-1],a=t.path[r],c=s?.portId,l=a?.portId,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)continue;const u=\"string\"==typeof s?.nextRegionId?s.nextRegionId:\"string\"==typeof a?.lastRegionId?a.lastRegionId:void 0;e.push([d,h]),i.push(void 0!==u?n.get(u):void 0)}Y.push(e),X.push(i)}return{topology:z,problem:$,solution:{solvedRoutePathSegments:Y,solvedRoutePathRegionIds:X}}},fB=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,yB=t=\u003eArray.isArray(t)?t.map(t=\u003eyB(t)):fB(t)?Object.fromEntries(Object.entries(t).map(([t,e])=\u003e[t,yB(e)])):t,_B=t=\u003efB(t)?{...t}:void 0===t?{}:{value:t},bB=(t,e=0)=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)?t:e,xB=t=\u003e({x:bB(t.d?.x),y:bB(t.d?.y)}),vB=t=\u003e[t.region1Id,t.region2Id].sort().join(\"\\0\"),SB=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y),IB=t=\u003e{const e=Math.hypot(t.x,t.y);if(!(e\u003c=1e-9))return{x:t.x/e,y:t.y/e}},CB=t=\u003e{const e=t?.d?.center;if(fB(e))return{x:bB(e.x),y:bB(e.y)};const n=(t=\u003e{const e=t?.d?.bounds;if(fB(e)\u0026\u0026\"number\"==typeof e.minX\u0026\u0026\"number\"==typeof e.maxX\u0026\u0026\"number\"==typeof e.minY\u0026\u0026\"number\"==typeof e.maxY)return{minX:e.minX,maxX:e.maxX,minY:e.minY,maxY:e.maxY};const n=t?.d?.center,o=bB(t?.d?.width),i=bB(t?.d?.height);if(fB(n)){const t=bB(n.x),e=bB(n.y);return{minX:t-o/2,maxX:t+o/2,minY:e-i/2,maxY:e+i/2}}return{minX:0,maxX:0,minY:0,maxY:0}})(t);return{x:(n.minX+n.maxX)/2,y:(n.minY+n.maxY)/2}},PB=(t,e)=\u003e{const n=vB(t),o=xB(t);let i,r=Number.POSITIVE_INFINITY;for(const s of e){if(s.portId===t.portId)continue;if(vB(s)!==n)continue;const e=SB(o,xB(s));e\u003c=1e-9||e\u003e=r||(i=s,r=e)}return i},MB=(t,e,n)=\u003e{const o=xB(t);if(e){const t=xB(e),n=IB({x:o.x-t.x,y:o.y-t.y});if(n)return n}return((t,e)=\u003e{const n=CB(e.get(t.region1Id)),o=CB(e.get(t.region2Id));return IB({x:-(o.y-n.y),y:o.x-n.x})??{x:1,y:0}})(t,n)},NB=(t,e,n)=\u003e{const o=`${t}::dup${e}`;if(!n.has(o))return n.add(o),o;for(let t=2;;t++){const e=`${o}-${t}`;if(!n.has(e))return n.add(e),e}},wB=(t,e,n)=\u003e{const o=t.indexOf(e);-1!==o?t.splice(o+1,0,...n):t.push(...n)},TB=(t,e)=\u003e{const n=t.portMetadata?.[e];if(fB(n)){if(\"string\"==typeof n.serializedPortId)return n.serializedPortId;if(\"string\"==typeof n.portId)return n.portId}return`port-${e}`},RB=(t,e)=\u003e({routeCount:1,portSectionMask:new Int8Array(t.portSectionMask),routeMetadata:void 0===t.routeMetadata?void 0:[t.routeMetadata[e]],routeStartPort:Int32Array.from([t.routeStartPort[e]]),routeEndPort:Int32Array.from([t.routeEndPort[e]]),routeNet:Int32Array.from([t.routeNet[e]]),regionNetId:new Int32Array(t.regionNetId),portPenalty:void 0===t.portPenalty?void 0:new Float64Array(t.portPenalty)}),EB=t=\u003e{const e=new Set;for(const n of t.state.regionSegments)for(const[,t,o]of n)e.add(t),e.add(o);return 0===e.size\u0026\u00261===t.problem.routeCount\u0026\u0026(e.add(t.problem.routeStartPort[0]),e.add(t.problem.routeEndPort[0])),e},AB=class extends kt{constructor(t,e={}){super(),this.serializedHyperGraph=t,this.options=e}serializedHyperGraph;options;revisedSerializedHyperGraph;report={portUseCounts:{},duplicatedPorts:[]};getDuplicatePortProximity(){return this.options.duplicatePortProximity??.05}getIndividualRouteSolveOptions(){return{RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!1,...this.options.routeSolveOptions}}getPortUseCounts(){const{topology:t,problem:e}=gB(this.serializedHyperGraph);!1===this.options.useSerializedPortPenalties\u0026\u0026(e.portPenalty=void 0);const n=new Map;for(let o=0;o\u003ce.routeCount;o++){const i=RB(e,o),r=new nB(t,i,this.getIndividualRouteSolveOptions());if(r.solve(),!r.solved||r.failed)throw new Error(`Route ${o} could not be solved independently: ${r.error??\"unknown error\"}`);for(const e of EB(r)){const o=TB(t,e);n.set(o,(n.get(o)??0)+1)}}return n}duplicateCongestedPorts(t){const e=this.getDuplicatePortProximity();if(!(e\u003e0))throw new Error(\"duplicatePortProximity must be greater than zero\");const{solvedRoutes:n,...o}=this.serializedHyperGraph,i=this.serializedHyperGraph.regions.map(t=\u003e({...t,pointIds:[...t.pointIds],d:yB(t.d)})),r=this.serializedHyperGraph.ports.map(t=\u003e({...t,d:yB(t.d)})),s=new Map(i.map(t=\u003e[t.regionId,t])),a=new Map(r.map(t=\u003e[t.portId,t])),c=new Set(r.map(t=\u003et.portId)),l=[];for(const[n,o]of[...t.entries()].sort(([t],[e])=\u003et.localeCompare(e))){if(o\u003c=1)continue;const t=a.get(n);if(!t)continue;const i=o-1,d=PB(t,this.serializedHyperGraph.ports),h=MB(t,d,s),u=xB(t),p=[];for(let s=1;s\u003c=i;s++){const a=NB(n,s,c),l=e*s/(i+1),d=_B(yB(t.d));d.x=u.x+h.x*l,d.y=u.y+h.y*l,d.duplicatedFromPortId=n,d.duplicateIndex=s,d.duplicatePortUseCount=o,d.duplicatePortProximity=e,d.repairReason=\"congested-port\",r.push({...t,portId:a,d:d}),p.push(a)}for(const e of[t.region1Id,t.region2Id]){const t=s.get(e);t\u0026\u0026wB(t.pointIds,n,p)}l.push({sourcePortId:n,duplicatePortIds:p,useCount:o})}return this.report={portUseCounts:Object.fromEntries([...t.entries()].sort()),duplicatedPorts:l},{...o,regions:i,ports:r,connections:void 0===this.serializedHyperGraph.connections?void 0:yB(this.serializedHyperGraph.connections)}}_setup(){try{const t=this.getPortUseCounts();this.revisedSerializedHyperGraph=this.duplicateCongestedPorts(t),this.stats={...this.stats,duplicateSourcePortCount:this.report.duplicatedPorts.length,duplicatedPortCount:this.report.duplicatedPorts.reduce((t,e)=\u003et+e.duplicatePortIds.length,0)},this.solved=!0}catch(t){this.failed=!0,this.error=t instanceof Error?t.message:String(t)}}_step(){this.failed||(this.solved=!0)}getOutput(){if(!this.revisedSerializedHyperGraph||this.failed)throw new Error(\"DuplicateCongestedPortSolver does not have a repaired topology output\");return this.revisedSerializedHyperGraph}},OB=(t,e)=\u003e{const n=t.owners.size-e.owners.size;if(0!==n)return n;const o=t.distance-e.distance;return 0!==o?o:t.queueOrder-e.queueOrder},kB=class{heap=[];push(t){this.heap.push(t);let e=this.heap.length-1;for(;e\u003e0;){const t=Math.floor((e-1)/2);if(OB(this.heap[t],this.heap[e])\u003c=0)break;[this.heap[t],this.heap[e]]=[this.heap[e],this.heap[t]],e=t}}pop(){const t=this.heap[0],e=this.heap.pop();if(!t||!e)return null;if(0===this.heap.length)return t;this.heap[0]=e;let n=0;for(;;){const t=2*n+1,e=t+1;let o=n;if(t\u003cthis.heap.length\u0026\u0026OB(this.heap[t],this.heap[o])\u003c0\u0026\u0026(o=t),e\u003cthis.heap.length\u0026\u0026OB(this.heap[e],this.heap[o])\u003c0\u0026\u0026(o=e),o===n)break;[this.heap[n],this.heap[o]]=[this.heap[o],this.heap[n]],n=o}return t}},LB=(t,e)=\u003e!(t.distance\u003ee.distance)\u0026\u0026((t,e)=\u003e{if(t.size\u003ee.size)return!1;for(const n of t)if(!e.has(n))return!1;return!0})(t.owners,e.owners),DB=(t,e)=\u003e{const n=[],o=[];let i=t;for(;null!==i;)n.push(i.state),null!==i.incomingHop\u0026\u0026o.push(i.incomingHop),i=i.parent;return n.reverse(),o.reverse(),{found:!0,states:n,hops:o,owners:new Set(t.owners),distance:t.distance,expandedLabelCount:e}},zB=t=\u003e{for(;;){const e=t.pop();if(null===e)return null;if(e.active)return e}},FB=(t,e)=\u003e{QF(t,e),e\u0026\u0026(void 0!==e.MAX_RIPS\u0026\u0026(t.MAX_RIPS=e.MAX_RIPS),void 0!==e.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT\u0026\u0026(t.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=e.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT),void 0!==e.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST\u0026\u0026(t.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=e.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST))},BB=t=\u003et.map(t=\u003et.map(([t,e,n])=\u003e[t,e,n])),jB=t=\u003e({netIds:new Int32Array(t.netIds),lesserAngles:new Int32Array(t.lesserAngles),greaterAngles:new Int32Array(t.greaterAngles),layerMasks:new Int32Array(t.layerMasks),existingCrossingLayerIntersections:t.existingCrossingLayerIntersections,existingSameLayerIntersections:t.existingSameLayerIntersections,existingEntryExitLayerChanges:t.existingEntryExitLayerChanges,existingRegionCost:t.existingRegionCost,existingSegmentCount:t.existingSegmentCount}),$B=t=\u003e({portAssignment:new Int32Array(t.portAssignment),regionSegments:BB(t.regionSegments),regionIntersectionCaches:t.regionIntersectionCaches.map(jB)}),YB=(t,e)=\u003e{const n=$B(e);t.state.portAssignment=n.portAssignment,t.state.regionSegments=n.regionSegments,t.state.regionIntersectionCaches=n.regionIntersectionCaches},XB=t=\u003e{let e=0,n=0;for(let o=0;o\u003ct.length;o++){const i=t[o]?.existingRegionCost??0;e=Math.max(e,i),n+=i}return{maxRegionCost:e,totalRegionCost:n}},VB=(t,e)=\u003et.maxRegionCost!==e.maxRegionCost?t.maxRegionCost-e.maxRegionCost:t.totalRegionCost-e.totalRegionCost,WB=(t,e,n)=\u003e{const o=t.incidentPortRegion[e]??[],i=t.incidentPortRegion[n]??[],r=o.find(t=\u003ei.includes(t));if(void 0===r)throw new Error(`Ports ${e} and ${n} do not share a region`);return r},HB=(t,e,n,o)=\u003e{const i=n.solvedRoutePathSegments[o]??[],r=n.solvedRoutePathRegionIds?.[o]??[],s=e.routeStartPort[o],a=e.routeEndPort[o];if(0===i.length){if(s===a)return{orderedPortIds:[s],orderedRegionIds:[]};throw new Error(`Route ${o} does not have an existing solved path`)}const c=new Map;i.forEach(([t,e],n)=\u003e{const o={segmentIndex:n,fromPortId:t,toPortId:e,regionId:r[n]},i=c.get(t)??[];i.push(o),c.set(t,i);const s=c.get(e)??[];s.push(o),c.set(e,s)});const l=[s],d=[],h=new Set;let u,p=s;for(;p!==a;){const e=(c.get(p)??[]).filter(({segmentIndex:t,fromPortId:e,toPortId:n})=\u003e{if(h.has(t))return!1;return(e===p?n:e)!==u});if(1!==e.length)throw new Error(`Route ${o} is not a single ordered path from ${s} to ${a}`);const n=e[0],i=n.fromPortId===p?n.toPortId:n.fromPortId;h.add(n.segmentIndex),d.push(n.regionId??WB(t,n.fromPortId,n.toPortId)),l.push(i),u=p,p=i}if(h.size!==i.length)throw new Error(`Route ${o} contains disconnected solved segments`);return{orderedPortIds:l,orderedRegionIds:d}},GB=(t,e,n,o)=\u003e{const i=new nB(t,e,o);return((t,e)=\u003e{t.state.portAssignment.fill(-1),t.state.regionSegments=Array.from({length:t.topology.regionCount},()=\u003e[]),t.state.regionIntersectionCaches=Array.from({length:t.topology.regionCount},()=\u003eqF()),t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.state.unroutedRoutes=[],t.state.candidateQueue.clear(),t.resetCandidateBestCosts(),t.state.goalPortId=-1,t.state.ripCount=0,t.state.regionCongestionCost.fill(0);for(let n=0;n\u003ce.length;n++)for(const[o,i,r]of e[n]??[])t.state.currentRouteNetId=t.problem.routeNet[o],t.state.regionSegments[n].push([o,i,r]),t.state.portAssignment[i]=t.state.currentRouteNetId,t.state.portAssignment[r]=t.state.currentRouteNetId,t.appendSegmentToRegionCache(n,i,r);t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.solved=!0,t.failed=!1,t.error=null})(i,n),i},UB=(t,e,n)=\u003e{const o=new Int32Array(e.routeStartPort),i=new Int32Array(e.routeEndPort),r=Array.from({length:e.routeCount},(t,e)=\u003e({routeId:e,fixedSegments:[]})),s=[];for(let a=0;a\u003ce.routeCount;a++){const c=r[a],{orderedPortIds:l,orderedRegionIds:d}=HB(t,e,n,a),h=[];let u;for(let t=0;t\u003cl.length;t++){const n=l[t],o=1===e.portSectionMask[n];o\u0026\u0026void 0===u?u=t:o||void 0===u||(h.push({startIndex:u,endIndex:t-1}),u=void 0)}if(void 0!==u\u0026\u0026h.push({startIndex:u,endIndex:l.length-1}),0===h.length){for(let t=1;t\u003cl.length;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});continue}if(h.length\u003e1)throw new Error(`Route ${a} enters the section multiple times; only one contiguous section span is currently supported`);const p=h[0],m=Math.max(0,p.startIndex-1),g=Math.min(l.length-1,p.endIndex+1);if(g\u003c=m)throw new Error(`Route ${a} does not have a valid section span`);for(let t=1;t\u003c=m;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});for(let t=g+1;t\u003cl.length;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});c.activeStartPortId=l[m],c.activeEndPortId=l[g],c.forcedStartRegionId=d[m],o[a]=c.activeStartPortId,i[a]=c.activeEndPortId,s.push(a)}return{sectionProblem:{routeCount:e.routeCount,portSectionMask:new Int8Array(e.portSectionMask),routeMetadata:e.routeMetadata,routeStartPort:o,routeEndPort:i,routeNet:new Int32Array(e.routeNet),regionNetId:new Int32Array(e.regionNetId),portPenalty:void 0===e.portPenalty?void 0:new Float64Array(e.portPenalty)},routePlans:r,activeRouteIds:s}},ZB=(t,e,n)=\u003eUB(t,e,n).activeRouteIds,qB=class extends nB{constructor(t,e,n,o,i,r,s,a){super(t,e,a),this.routePlans=n,this.activeRouteIds=o,this.mutableRegionIds=i,this.immutableRegionSummary=r,this.baselineSummary=s,FB(this,a),this.state.unroutedRoutes=[...o],this.applyFixedSegments(),this.fixedSnapshot=$B({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches})}routePlans;activeRouteIds;mutableRegionIds;immutableRegionSummary;baselineSummary;bestSnapshot;fixedSnapshot;bestSummary;baselineBeatRipCount;previousBestMaxRegionCost=Number.POSITIVE_INFINITY;ripsSinceBestMaxRegionCostImprovement=0;MAX_RIPS=Number.POSITIVE_INFINITY;MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=Number.POSITIVE_INFINITY;EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=Number.POSITIVE_INFINITY;applyFixedSegments(){for(const t of this.routePlans)for(const{regionId:e,fromPortId:n,toPortId:o}of t.fixedSegments)this.state.currentRouteNetId=this.problem.routeNet[t.routeId],this.state.regionSegments[e].push([t.routeId,n,o]),this.state.portAssignment[n]=this.state.currentRouteNetId,this.state.portAssignment[o]=this.state.currentRouteNetId,this.appendSegmentToRegionCache(e,n,o);this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0}captureBestState(t){this.bestSummary\u0026\u0026VB(t,this.bestSummary)\u003e=0||(this.bestSummary=t,this.bestSnapshot=$B({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches}))}restoreBestState(){this.bestSnapshot\u0026\u0026(YB(this,this.bestSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1)}getStartingNextRegionId(t,e){const n=this.routePlans[t]?.forcedStartRegionId;return void 0!==n?n:super.getStartingNextRegionId(t,e)}resetRoutingStateForRerip(){if(!this.fixedSnapshot)return super.resetRoutingStateForRerip(),this.state.unroutedRoutes=qz([...this.activeRouteIds],this.state.ripCount),void this.applyFixedSegments();YB(this,this.fixedSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=qz([...this.activeRouteIds],this.state.ripCount),this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1}onAllRoutesRouted(){const{state:t}=this,e=Math.min(this.MAX_RIPS,this.RIP_THRESHOLD_RAMP_ATTEMPTS),n=e\u003c=0?1:Math.min(1,t.ripCount/e),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(this.mutableRegionIds.length);let s=0,a=0;for(let e=0;e\u003cthis.mutableRegionIds.length;e++){const n=this.mutableRegionIds[e],c=t.regionIntersectionCaches[n]?.existingRegionCost??0;r[e]=c,s=Math.max(s,c),a+=c,c\u003eo\u0026\u0026i.push(n)}const c=Math.max(this.immutableRegionSummary.maxRegionCost,s),l=this.immutableRegionSummary.totalRegionCost+a;this.captureBestState({maxRegionCost:c,totalRegionCost:l});const d=this.bestSummary??{maxRegionCost:c,totalRegionCost:l};if(d.maxRegionCost\u003cthis.previousBestMaxRegionCost-Number.EPSILON?(this.previousBestMaxRegionCost=d.maxRegionCost,this.ripsSinceBestMaxRegionCostImprovement=0):this.ripsSinceBestMaxRegionCostImprovement+=1,void 0===this.baselineBeatRipCount\u0026\u0026d.maxRegionCost\u003cthis.baselineSummary.maxRegionCost-Number.EPSILON\u0026\u0026(this.baselineBeatRipCount=t.ripCount),this.stats={...this.stats,activeRouteCount:this.activeRouteIds.length,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:c,totalRegionCost:l,bestMaxRegionCost:d.maxRegionCost,bestTotalRegionCost:d.totalRegionCost,ripCount:t.ripCount},0===i.length||t.ripCount\u003e=e||this.ripsSinceBestMaxRegionCostImprovement\u003e=this.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT||void 0!==this.baselineBeatRipCount\u0026\u0026t.ripCount-this.baselineBeatRipCount\u003e=this.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST)return this.restoreBestState(),void(this.solved=!0);for(let e=0;e\u003cthis.mutableRegionIds.length;e++){const n=this.mutableRegionIds[e];t.regionCongestionCost[n]+=r[e]*this.RIP_CONGESTION_REGION_COST_FACTOR}t.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:t.ripCount,reripRegionCount:i.length}}onOutOfCandidates(){const{state:t}=this;for(const e of this.mutableRegionIds){const n=t.regionIntersectionCaches[e]?.existingRegionCost??0;t.regionCongestionCost[e]+=n*this.RIP_CONGESTION_REGION_COST_FACTOR}t.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:t.ripCount,reripReason:\"out_of_candidates\"}}tryFinalAcceptance(){if(this.bestSnapshot)return this.restoreBestState(),void(this.solved=!0);this.fixedSnapshot\u0026\u0026YB(this,this.fixedSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[...this.activeRouteIds],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.stats={...this.stats,acceptedFixedSectionStateOnTimeout:!0},this.solved=!0}visualize(){return UF(this,{highlightSectionMask:!0,showInitialRouteHints:!1,showOnlySectionPortsOnIdle:!0})}},JB=class extends kt{constructor(t,e,n,o){super(),this.topology=t,this.problem=e,this.initialSolution=n,FB(this,o),this.baselineSolver=((t,e,n,o)=\u003e{const i=Array.from({length:t.regionCount},()=\u003e[]);for(let o=0;o\u003ce.routeCount;o++){const{orderedPortIds:r,orderedRegionIds:s}=HB(t,e,n,o);for(let t=1;t\u003cr.length;t++){const e=r[t-1],n=r[t];i[s[t-1]].push([o,e,n])}}return GB(t,e,i,o)})(t,e,n,tB(this)),this.baselineSummary=XB(this.baselineSolver.state.regionIntersectionCaches),this.sectionRegionIds=((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ce.portSectionMask.length;o++)if(1===e.portSectionMask[o])for(const e of t.incidentPortRegion[o]??[])n.add(e);return[...n]})(t,e),this.sectionBaselineSummary=((t,e)=\u003e{let n=0,o=0;for(const i of e){const e=t[i]?.existingRegionCost??0;n=Math.max(n,e),o+=e}return{maxRegionCost:n,totalRegionCost:o}})(this.baselineSolver.state.regionIntersectionCaches,this.sectionRegionIds),this.outsideSectionBaselineSummary=((t,e)=\u003e{const n=new Set(e);let o=0,i=0;for(let e=0;e\u003ct.length;e++){if(n.has(e))continue;const r=t[e]?.existingRegionCost??0;o=Math.max(o,r),i+=r}return{maxRegionCost:o,totalRegionCost:i}})(this.baselineSolver.state.regionIntersectionCaches,this.sectionRegionIds),this.applySectionRipPolicy()}topology;problem;initialSolution;baselineSolver;baselineSummary;sectionBaselineSummary;outsideSectionBaselineSummary;sectionRegionIds;optimizedSolver;sectionSolver;activeRouteIds=[];DISTANCE_TO_COST=.05;minViaPadDiameter=Yz;VERBOSE=!1;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;MAX_RIPS=Number.POSITIVE_INFINITY;MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=10;EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=10;RIP_CONGESTION_REGION_COST_FACTOR=.1;MAX_ITERATIONS=1e6;STATIC_REACHABILITY_PRECHECK=!1;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;ACCEPT_BEST_SOLUTION_ON_TIMEOUT=!0;GREEDY_FINAL_ROUTE_ITERS=4;applySectionRipPolicy(){this.RIP_THRESHOLD_START=.05,this.RIP_THRESHOLD_END=Math.max(this.RIP_THRESHOLD_START,this.sectionBaselineSummary.maxRegionCost),this.MAX_RIPS=Math.min(this.MAX_RIPS,20)}_setup(){this.applySectionRipPolicy();const{sectionProblem:t,routePlans:e,activeRouteIds:n}=UB(this.topology,this.problem,this.initialSolution);if(this.activeRouteIds=n,0===n.length)return this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,activeRouteCount:0,initialMaxRegionCost:this.baselineSummary.maxRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,optimized:!1},void(this.solved=!0);var o;this.sectionSolver=new qB(this.topology,t,e,n,this.sectionRegionIds,this.outsideSectionBaselineSummary,this.baselineSummary,{...tB(o=this),MAX_RIPS:o.MAX_RIPS,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:o.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:o.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST}),this.activeSubSolver=this.sectionSolver,this.stats={...this.stats,sectionBaselineMaxRegionCost:this.sectionBaselineSummary.maxRegionCost,sectionBaselineTotalRegionCost:this.sectionBaselineSummary.totalRegionCost,effectiveRipThresholdStart:this.RIP_THRESHOLD_START,effectiveRipThresholdEnd:this.RIP_THRESHOLD_END,effectiveMaxRips:this.MAX_RIPS}}_step(){if(!this.sectionSolver)return void(this.solved=!0);if(this.sectionSolver.step(),this.stats={...this.stats,...this.sectionSolver.stats,activeRouteCount:this.activeRouteIds.length},this.sectionSolver.failed)return this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,finalTotalRegionCost:this.baselineSummary.totalRegionCost,optimized:!1,sectionSearchFailedFallbackToBaseline:!0,sectionSearchError:this.sectionSolver.error},void(this.solved=!0);if(!this.sectionSolver.solved)return;const t=GB(this.topology,this.problem,BB(this.sectionSolver.state.regionSegments),tB(this)),e=XB(t.state.regionIntersectionCaches),n=VB(e,this.baselineSummary)\u003c0;this.optimizedSolver=n?t:this.baselineSolver;const o=n?e:this.baselineSummary;this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,candidateMaxRegionCost:e.maxRegionCost,candidateTotalRegionCost:e.totalRegionCost,finalMaxRegionCost:o.maxRegionCost,finalTotalRegionCost:o.totalRegionCost,optimized:n},this.solved=!0}tryFinalAcceptance(){this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,finalTotalRegionCost:this.baselineSummary.totalRegionCost,optimized:!1,sectionSolverTimeoutFallbackToBaseline:!0},this.solved=!0,this.failed=!1,this.error=null}getSolvedSolver(){if(!this.solved||this.failed||!this.optimizedSolver)throw new Error(\"TinyHyperGraphSectionSolver does not have a solved output yet\");return this.optimizedSolver}visualize(){return this.optimizedSolver?UF(this.optimizedSolver,{highlightSectionMask:!0}):this.sectionSolver?this.sectionSolver.visualize():UF(this.baselineSolver,{highlightSectionMask:!0,showInitialRouteHints:!1,showOnlySectionPortsOnIdle:!0})}getOutput(){return this.getSolvedSolver().getOutput()}},KB=[\"self-touch\",\"onehop-all\",\"onehop-touch\",\"twohop-all\",\"twohop-touch\"],QB={\"self-all\":0,\"self-touch\":0,\"onehop-all\":1,\"onehop-touch\":1,\"twohop-all\":2,\"twohop-touch\":2,\"threehop-all\":3,\"threehop-touch\":3,\"fourhop-all\":4,\"fourhop-touch\":4},tj=(t,e)=\u003e{const n=new Set(e);for(const o of e)for(const e of t.regionIncidentPorts[o]??[])for(const o of t.incidentPortRegion[e]??[])n.add(o);return[...n]},ej=(t,e,n)=\u003e{let o=[...new Set(e)];for(let e=0;e\u003cn;e+=1)o=tj(t,o);return o},nj=(t,e,n)=\u003ee.flatMap(e=\u003en.map(n=\u003e((t,e,n)=\u003e({label:`hot-${e}-${n}`,family:n,regionIds:ej(t,[e],QB[n]),portSelectionRule:n.endsWith(\"-all\")?\"all-incident-regions-selected\":\"touches-selected-region\"}))(t,e,n))),oj={RIP_THRESHOLD_RAMP_ATTEMPTS:5},ij={DISTANCE_TO_COST:.05,RIP_THRESHOLD_RAMP_ATTEMPTS:16,RIP_CONGESTION_REGION_COST_FACTOR:.1,MAX_ITERATIONS:5e4,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:6,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:Number.POSITIVE_INFINITY},rj=t=\u003et.state.regionIntersectionCaches.reduce((t,e)=\u003eMath.max(t,e.existingRegionCost),0),sj=(t,e)=\u003e{const n=gB(t),o=new JB(n.topology,n.problem,n.solution,e);return rj(o.baselineSolver)},aj=(t,e,n)=\u003e{const o=new Set(e);return Int8Array.from({length:t.portCount},(e,i)=\u003e{const r=t.incidentPortRegion[i]??[];return\"touches-selected-region\"===n?r.some(t=\u003eo.has(t))?1:0:r.length\u003e0\u0026\u0026r.every(t=\u003eo.has(t))?1:0})},cj=(t,e)=\u003e({routeCount:t.routeCount,portSectionMask:e,routeMetadata:t.routeMetadata,routeStartPort:new Int32Array(t.routeStartPort),routeEndPort:new Int32Array(t.routeEndPort),routeNet:new Int32Array(t.routeNet),regionNetId:new Int32Array(t.regionNetId),portPenalty:void 0===t.portPenalty?void 0:new Float64Array(t.portPenalty)}),lj=(t,e,n,o,i,r)=\u003e{const s=performance.now(),a=performance.now(),c=new JB(e,n,o,r),l=rj(c.baselineSolver),d=performance.now()-a;let h,u,p=l,m=new Int8Array(e.portCount),g=0,f=0,y=0,_=0,b=0,x=0,v=0;const S=new Set,I=i?.maxHotRegions??r.MAX_HOT_REGIONS??2;for(const s of((t,e,n,o)=\u003e{const i=t.state.regionIntersectionCaches.map((t,e)=\u003e({regionId:e,regionCost:t.existingRegionCost})).filter(({regionCost:t})=\u003et\u003e0).sort((t,e)=\u003ee.regionCost-t.regionCost).slice(0,n).map(({regionId:t})=\u003et);return nj(e,i,o)})(t,e,I,i?.candidateFamilies??[...KB])){const t=cj(n,aj(e,s.regionIds,s.portSelectionRule));g+=1;const i=t.portSectionMask.join(\",\");if(S.has(i))y+=1;else{S.add(i);try{const n=performance.now(),i=ZB(e,t,o);if(_+=performance.now()-n,0===i.length)continue;f+=1;const a=performance.now(),c=new JB(e,t,o,r);b+=performance.now()-a;const l=performance.now();if(c.solve(),x+=performance.now()-l,c.failed||!c.solved)continue;if(Number(c.stats.finalMaxRegionCost??rj(c.getSolvedSolver()))\u003cp-1e-9){const e=performance.now(),n=sj(c.getOutput(),r);v+=performance.now()-e,n\u003cp-1e-9\u0026\u0026(p=n,m=new Int8Array(t.portSectionMask),h=s.label,u=s.family)}}catch{}}}return{portSectionMask:m,baselineMaxRegionCost:l,finalMaxRegionCost:p,generatedCandidateCount:g,candidateCount:f,duplicateCandidateCount:y,totalMs:performance.now()-s,baselineEvaluationMs:d,candidateEligibilityMs:_,candidateInitMs:b,candidateSolveMs:x,candidateReplayScoreMs:v,winningCandidateLabel:h,winningCandidateFamily:u}},dj=class extends Dt{initialVisualizationSolver;selectedSectionMask;selectedSectionCandidateLabel;selectedSectionCandidateFamily;constructor(t){super(t),this.MAX_ITERATIONS=2e5}loadHyperGraph(t){return gB(t)}getSolveGraphOptions(){return{...oj,...void 0===this.inputProblem.minViaPadDiameter?{}:{minViaPadDiameter:this.inputProblem.minViaPadDiameter},...this.inputProblem.solveGraphOptions}}getSectionSolverOptions(){return{...ij,...void 0===this.inputProblem.minViaPadDiameter?{}:{minViaPadDiameter:this.inputProblem.minViaPadDiameter},...this.inputProblem.sectionSolverOptions}}pipelineDef=[{solverName:\"solveGraph\",solverClass:nB,getConstructorParams:t=\u003e{const{topology:e,problem:n}=t.loadHyperGraph(t.inputProblem.serializedHyperGraph);return[e,n,t.getSolveGraphOptions()]}},{solverName:\"optimizeSection\",solverClass:JB,getConstructorParams:t=\u003et.getSectionStageParams()}];getSectionStageParams(){const t=this.getStageOutput(\"solveGraph\");if(!t)throw new Error(\"solveGraph did not produce a solved serialized hypergraph\");const e=this.getSolver(\"solveGraph\");if(!e)throw new Error(\"solveGraph solver is unavailable\");const n=this.getSectionSolverOptions(),{topology:o,problem:i,solution:r}=this.loadHyperGraph(t),s=this.inputProblem.createSectionMask?this.inputProblem.createSectionMask({serializedHyperGraph:this.inputProblem.serializedHyperGraph,solvedSerializedHyperGraph:t,solvedSolver:e,topology:o,problem:i,solution:r}):(()=\u003e{const t=lj(e,o,i,r,this.inputProblem.sectionSearchConfig,n);return this.selectedSectionCandidateLabel=t.winningCandidateLabel,this.selectedSectionCandidateFamily=t.winningCandidateFamily,this.stats={...this.stats,sectionSearchGeneratedCandidateCount:t.generatedCandidateCount,sectionSearchCandidateCount:t.candidateCount,sectionSearchDuplicateCandidateCount:t.duplicateCandidateCount,sectionSearchBaselineMaxRegionCost:t.baselineMaxRegionCost,sectionSearchFinalMaxRegionCost:t.finalMaxRegionCost,sectionSearchDelta:t.baselineMaxRegionCost-t.finalMaxRegionCost,selectedSectionCandidateLabel:t.winningCandidateLabel??null,selectedSectionCandidateFamily:t.winningCandidateFamily??null,sectionSearchMs:t.totalMs,sectionSearchBaselineEvaluationMs:t.baselineEvaluationMs,sectionSearchCandidateEligibilityMs:t.candidateEligibilityMs,sectionSearchCandidateInitMs:t.candidateInitMs,sectionSearchCandidateSolveMs:t.candidateSolveMs,sectionSearchCandidateReplayScoreMs:t.candidateReplayScoreMs},t.portSectionMask})();return this.selectedSectionMask=new Int8Array(s),i.portSectionMask=new Int8Array(s),this.stats={...this.stats,sectionMaskPortCount:[...s].filter(t=\u003e1===t).length},[o,i,r,n]}getInitialVisualizationSolver(){if(!this.initialVisualizationSolver){const{topology:t,problem:e}=this.loadHyperGraph(this.inputProblem.serializedHyperGraph);this.initialVisualizationSolver=new nB(t,e,this.getSolveGraphOptions())}return this.initialVisualizationSolver}initialVisualize(){return this.getInitialVisualizationSolver().visualize()}visualize(){return 0===this.iterations?this.initialVisualize()??super.visualize():super.visualize()}getOutput(){return this.getStageOutput(\"optimizeSection\")??this.getStageOutput(\"solveGraph\")??null}tryFinalAcceptance(){this.getStageOutput(\"solveGraph\")\u0026\u0026(this.stats={...this.stats,acceptedSolveGraphOutputOnSectionPipelineTimeout:!0},this.activeSubSolver=void 0,this.solved=!0,this.failed=!1,this.error=null)}};var hj=class extends aB{failedOwnerPairCounts=new Map;selectiveReripStats={selectiveRipCount:0,selectivelyRippedRouteCount:0,globalReripCount:0,alternateBlockerSearchCount:0,alternateOwnerCount:0,failedOwnerPairCount:0,maxFailedOwnerPairCount:0,failedOwnerPairs:[],lastDirectOwnerRouteIds:[],lastRepeatedOwnerRouteIds:[],lastAlternateOwnerRouteIds:[],lastRippedRouteIds:[],lastRelaxedSearchExpandedLabelCount:0,lastAlternateSearchExpandedLabelCount:0};selectiveReripCongestionUpdateCount=0;constructor(t,e,n){super(t,e,n)}getSelectiveReripStats(){return{...this.selectiveReripStats,failedOwnerPairs:this.selectiveReripStats.failedOwnerPairs.map(t=\u003e({...t})),lastDirectOwnerRouteIds:[...this.selectiveReripStats.lastDirectOwnerRouteIds],lastRepeatedOwnerRouteIds:[...this.selectiveReripStats.lastRepeatedOwnerRouteIds],lastAlternateOwnerRouteIds:[...this.selectiveReripStats.lastAlternateOwnerRouteIds],lastRippedRouteIds:[...this.selectiveReripStats.lastRippedRouteIds]}}onOutOfCandidates(){const t=this.state.currentRouteId;if(void 0===t)throw new Error(\"SelectiveReripTinyHyperGraphSolver: candidate search exhausted without a current route\");const e=this.findRelaxedBlockerPathPreferringPreservedRoutes();if(!e.found||0===e.owners.size)return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=e.found?\"no_blocker_path\":e.reason,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=[],this.selectiveReripStats.lastRepeatedOwnerRouteIds=[],this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=0,super.onOutOfCandidates(),void this.publishSelectiveReripStats();const n=[...e.owners],o=[];for(const e of n){this.incrementFailedOwnerPair(t,e)\u003e=2\u0026\u0026o.push(e)}if(n.some(e=\u003ethis.hasFailedOwnerPath(e,t)))return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=\"failed_owner_cycle\",this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=0,this.failedOwnerPairCounts.clear(),super.onOutOfCandidates(),void this.publishSelectiveReripStats();let i;if(o.length\u003e0\u0026\u0026(this.selectiveReripStats.alternateBlockerSearchCount+=1,i=this.findRelaxedBlockerPathPreferringPreservedRoutes(new Set(o)),!i.found))return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=i.reason,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=i.expandedLabelCount,super.onOutOfCandidates(),void this.publishSelectiveReripStats();const r=i?.found?[...i.owners]:void 0,s=function(t){const e=new Set(t.alternateOwnerRouteIds??t.directOwnerRouteIds);if(e.delete(t.failedRouteId),0===e.size)throw new Error(`SelectiveReripTinyHyperGraphSolver: route ${t.failedRouteId} has blocker resources but no distinct committed owner can be reripped`);return e}({failedRouteId:t,directOwnerRouteIds:n,alternateOwnerRouteIds:r});this.clearPartialRipPlans(s);const a=(r??[]).filter(t=\u003e!e.owners.has(t));this.selectiveReripCongestionUpdateCount\u003c1\u0026\u0026(this.addCongestionCostForSelectiveRerip(),this.selectiveReripCongestionUpdateCount+=1),this.rebuildCommittedState(s),this.state.ripCount+=1,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=function(t){const e=t.pendingRouteIds.filter(e=\u003ee!==t.failedRouteId\u0026\u0026!t.rippedRouteIds.has(e)),n=[...t.rippedRouteIds].filter(e=\u003ee!==t.failedRouteId);return[t.failedRouteId,...e,...n]}({failedRouteId:t,pendingRouteIds:this.state.unroutedRoutes,rippedRouteIds:s}),this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.selectiveReripStats.selectiveRipCount+=1,this.selectiveReripStats.selectivelyRippedRouteCount+=s.size,this.selectiveReripStats.alternateOwnerCount+=a.length,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=a,this.selectiveReripStats.lastRippedRouteIds=[...s],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=i?.expandedLabelCount??0,this.publishSelectiveReripStats()}addCongestionCostForSelectiveRerip(){for(let t=0;t\u003cthis.topology.regionCount;t++){const e=this.state.regionIntersectionCaches[t]?.existingRegionCost??0;this.state.regionCongestionCost[t]+=e*this.RIP_CONGESTION_REGION_COST_FACTOR}}findRelaxedBlockerPath(t=new Set){const e=this.state.currentRouteId,n=this.state.currentRouteNetId;if(void 0===e||void 0===n)throw new Error(\"SelectiveReripTinyHyperGraphSolver: blocker search requires a current route and net\");const o=this.getRouteStartPortId(e),i=this.getRouteEndPortId(e),r=this.getStartingNextRegionId(e,o);if(void 0===r)throw new Error(`SelectiveReripTinyHyperGraphSolver: route ${this.describeRoute(e)} has no starting region for blocker search`);const s=this.getPortOwners();return(t=\u003e{const e=t.maxExpandedLabels??Number.POSITIVE_INFINITY;if(e!==Number.POSITIVE_INFINITY\u0026\u0026(!Number.isInteger(e)||e\u003c0))throw new Error(\"maxExpandedLabels must be a non-negative integer\");const n=new Map,o=new kB;let i=0,r=0;const s={state:t.start,stateKey:t.getStateKey(t.start),owners:new Set,distance:0,parent:null,incomingHop:null,queueOrder:i++,active:!0};for(n.set(s.stateKey,[s]),o.push(s);;){const s=zB(o);if(null===s)return{found:!1,reason:\"no_path\",expandedLabelCount:r};if(t.isGoal(s.state))return DB(s,r);if(r\u003e=e)return{found:!1,reason:\"expansion_limit\",expandedLabelCount:r};r++;for(const e of t.getHops(s.state)){if(!Number.isFinite(e.distance)||e.distance\u003c0)throw new Error(\"Distinct-owner blocker hops require finite distances \u003e= 0\");const r=new Set(s.owners);for(const t of e.owners??[])r.add(t);const a=s.distance+e.distance;if(!Number.isFinite(a))throw new Error(\"Distinct-owner blocker path distance overflowed\");const c={state:e.state,stateKey:t.getStateKey(e.state),owners:r,distance:a,parent:s,incomingHop:e,queueOrder:i++,active:!0},l=n.get(c.stateKey)??[];if(l.some(t=\u003eLB(t,c)))continue;const d=[];for(const t of l)LB(c,t)?t.active=!1:d.push(t);d.push(c),n.set(c.stateKey,d),o.push(c)}}})({start:{portId:o,nextRegionId:r},getStateKey:({portId:t,nextRegionId:e})=\u003ethis.getHopId(t,e),isGoal:({portId:t})=\u003et===i,getHops:e=\u003ethis.getRelaxedSearchHops({state:e,goalPortId:i,routeNetId:n,portOwners:s,forbiddenOwnerRouteIds:t}),maxExpandedLabels:this.getRelaxedSearchExpansionLimit()})}findRelaxedBlockerPathPreferringPreservedRoutes(t=new Set){const e=this.getRouteIdsPreferredForPreservation();if(0===e.size)return this.findRelaxedBlockerPath(t);const n=new Set(t);for(const t of e)n.add(t);const o=this.findRelaxedBlockerPath(n);return o.found\u0026\u0026o.owners.size\u003e0?o:this.findRelaxedBlockerPath(t)}getRelaxedSearchExpansionLimit(){let t=0;for(const e of this.topology.incidentPortRegion)t+=e.length;const e=Math.max(4,Math.ceil(Math.log2(this.problem.routeCount+1)));return Math.max(4096,t*e*4)}getRelaxedSearchHops(t){const{state:e,goalPortId:n,routeNetId:o}=t;if(this.isRegionReservedForDifferentNet(e.nextRegionId))return[];const i=[];for(const r of this.topology.regionIncidentPorts[e.nextRegionId]??[]){if(r===e.portId)continue;if(this.isPortReservedForDifferentNet(r))continue;if(r!==n\u0026\u00260===this.problem.portSectionMask[r])continue;const s=this.getHopBlockerResources({regionId:e.nextRegionId,fromPortId:e.portId,toPortId:r,routeNetId:o,portOwners:t.portOwners}),a=[...new Set(s.flatMap(t=\u003et.owners))];if(a.some(e=\u003et.forbiddenOwnerRouteIds.has(e)))continue;let c=e.nextRegionId;if(r!==n){const[t,n]=this.topology.incidentPortRegion[r]??[];if(c=t===e.nextRegionId?n:t,void 0===c||this.isRegionReservedForDifferentNet(c))continue}i.push({state:{portId:r,nextRegionId:c},distance:Math.hypot(this.topology.portX[e.portId]-this.topology.portX[r],this.topology.portY[e.portId]-this.topology.portY[r]),owners:a,data:{resources:s}})}return i}getHopBlockerResources(t){const e=[],n=this.state.portAssignment[t.toPortId];if(-1!==n\u0026\u0026n!==t.routeNetId){const o=[...t.portOwners.get(t.toPortId)??new Set].filter(e=\u003ethis.problem.routeNet[e]!==t.routeNetId);if(0===o.length)throw new Error(`SelectiveReripTinyHyperGraphSolver: port ${t.toPortId} is assigned to foreign net ${n} without a committed route owner`);e.push({kind:\"port\",portId:t.toPortId,owners:o})}const o=this.getHardBlockedCrossingOwners(t.regionId,t.fromPortId,t.toPortId);return o.length\u003e0\u0026\u0026e.push({kind:\"same_layer_intersection\",regionId:t.regionId,fromPortId:t.fromPortId,toPortId:t.toPortId,owners:o}),e}getPortOwners(){const t=new Map;for(const e of this.state.regionSegments)for(const[n,o,i]of e)for(const e of[o,i]){const o=t.get(e)??new Set;o.add(n),t.set(e,o)}return t}getHardBlockedCrossingOwners(t,e,n){if(!this.isKnownSingleLayerRegion(t))return[];const o=this.state.currentRouteNetId;if(void 0===o)throw new Error(\"SelectiveReripTinyHyperGraphSolver: crossing ownership requires a current route net\");const i=new Set;for(const[r,s,a]of this.state.regionSegments[t]??[])this.problem.routeNet[r]!==o\u0026\u0026this.segmentsCrossOnSameLayer(t,e,n,s,a)\u0026\u0026i.add(r);return[...i]}segmentsCrossOnSameLayer(t,e,n,o,i){const r={...this.populateSegmentGeometryScratch(t,e,n)},s={...this.populateSegmentGeometryScratch(t,o,i)};if(0===(r.layerMask\u0026s.layerMask))return!1;if(r.lesserAngle===s.lesserAngle||r.lesserAngle===s.greaterAngle||r.greaterAngle===s.lesserAngle||r.greaterAngle===s.greaterAngle)return!1;return(r.lesserAngle\u003cs.lesserAngle\u0026\u0026s.lesserAngle\u003cr.greaterAngle)!==(r.lesserAngle\u003cs.greaterAngle\u0026\u0026s.greaterAngle\u003cr.greaterAngle)}rebuildCommittedState(t){this.state.regionSegments=this.state.regionSegments.map(e=\u003ee.filter(([e])=\u003e!t.has(e))),this.state.portAssignment.fill(-1),this.state.regionIntersectionCaches=Array.from({length:this.topology.regionCount},()=\u003eqF());for(let t=0;t\u003cthis.state.regionSegments.length;t++)for(const[e,n,o]of this.state.regionSegments[t]){const i=this.problem.routeNet[e];this.state.currentRouteNetId=i;for(const t of[n,o]){const e=this.state.portAssignment[t];if(-1!==e\u0026\u0026e!==i)throw new Error(`SelectiveReripTinyHyperGraphSolver: rebuilding committed routes found cross-net ownership at port ${t} between net ${e} and net ${i}`);this.state.portAssignment[t]=i}this.appendSegmentToRegionCache(t,n,o)}this.state.currentRouteNetId=void 0}incrementFailedOwnerPair(t,e){const n=this.failedOwnerPairCounts.get(t)??new Map,o=(n.get(e)??0)+1;return n.set(e,o),this.failedOwnerPairCounts.set(t,n),o}hasFailedOwnerPath(t,e){const n=[t],o=new Set;for(;n.length\u003e0;){const t=n.pop();if(t===e)return!0;o.has(t)||(o.add(t),n.push(...this.failedOwnerPairCounts.get(t)?.keys()??[]))}return!1}publishSelectiveReripStats(){const t=[];for(const[e,n]of this.failedOwnerPairCounts)for(const[o,i]of n)t.push({failedRouteId:e,ownerRouteId:o,count:i});t.sort((t,e)=\u003et.failedRouteId-e.failedRouteId||t.ownerRouteId-e.ownerRouteId),this.selectiveReripStats.failedOwnerPairs=t,this.selectiveReripStats.failedOwnerPairCount=t.length,this.selectiveReripStats.maxFailedOwnerPairCount=Math.max(0,...t.map(({count:t})=\u003et)),this.stats={...this.stats,...this.getSelectiveReripStats()}}describeRoute(t){const e=this.problem.routeMetadata?.[t]?.connectionId;return void 0===e?String(t):`${t} (${String(e)})`}};new Int32Array(0);var uj=class extends hj{initialAssignmentRouteIds;getRouteIdsPreferredForPreservation(){return this.initialAssignmentRouteIds||(this.initialAssignmentRouteIds=new Set((this.problem.initialAssignments??[]).map(t=\u003et.routeId))),this.initialAssignmentRouteIds}resetRoutingStateForRerip(){super.resetRoutingStateForRerip(),this.problem.initialAssignments?.length\u0026\u0026Uz({topology:this.topology,problem:this.problem,state:this.state,routeSuccessCountByRouteId:this.routeSuccessCountByRouteId,appendSegmentToRegionCache:(t,e,n)=\u003ethis.appendSegmentToRegionCache(t,e,n)})}},pj=t=\u003e{if(\"object\"!=typeof t||null===t)return!1;const e=t,n=e.preloadedTraceSection;return\"string\"==typeof e.connectionId\u0026\u0026\"string\"==typeof n?.traceId\u0026\u0026\"number\"==typeof n.startRoutePosition\u0026\u0026\"number\"==typeof n.endRoutePosition\u0026\u0026\"number\"==typeof n.startPoint?.x\u0026\u0026\"number\"==typeof n.startPoint.y\u0026\u0026\"number\"==typeof n.startPoint.z\u0026\u0026\"number\"==typeof n.endPoint?.x\u0026\u0026\"number\"==typeof n.endPoint.y\u0026\u0026\"number\"==typeof n.endPoint.z},mj=(t,e)=\u003e`__tscircuit_preloaded_trace__:${JSON.stringify([t,e])}`,gj=t=\u003e[t.region1Id,t.region2Id],fj=(t,e)=\u003e{const n=new Set(gj(e));return gj(t).filter(t=\u003en.has(t))},yj=(t,e,n)=\u003e{const o=t[e],i=t[e+1],r=fj(o.port,i.port);if(0===r.length)return;if(1===r.length)return r[0];const s=t[e+2];if(s){const t=new Set(fj(i.port,s.port)),e=r.find(e=\u003et.has(e));if(e)return e}return n\u0026\u0026r.includes(n)?n:[...r].sort()[0]},_j=(t,e)=\u003egj(t).find(t=\u003et!==e)??e,bj=t=\u003e{const e=new Set((t.connections??[]).filter(pj).map(t=\u003et.connectionId)),n=t.ports.filter(t=\u003e(t.d?._preloadedTracePortAssignments?.length??0)\u003e0).length,o=t.regions.reduce((t,n)=\u003et+(n.assignments??[]).filter(t=\u003ee.has(t.connectionId)).length,0);return{preloadedTraceCount:e.size,preloadedPortCount:n,preloadedAssignmentCount:o}},xj=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},vj=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},Sj=1e-6,Ij={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,PARTIAL_RIP_MIN_ROUTE_COUNT:100,PARTIAL_RIP_MAX_ROUTE_COUNT:350,PARTIAL_RIP_MAX_ATTEMPTS:7,PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS:1,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:100,PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO:.02,PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO:.05,PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO:.1},Cj={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:6,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:Number.POSITIVE_INFINITY},Pj=t=\u003eMath.max(t,.01),Mj=t=\u003eNumber.isFinite(t)?{minViaPadDiameter:t}:{},Nj=(t,e)=\u003e{const n=Pj(t);return{...Ij,...Mj(e),USE_SPARSE_CANDIDATE_STORAGE:!1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.ceil(10*n),MAX_ITERATIONS:Math.ceil(2e6*n)}},wj=(t,e)=\u003e{const n=Pj(t);return{...Cj,...Mj(e),USE_SPARSE_CANDIDATE_STORAGE:!1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.ceil(16*n),MAX_ITERATIONS:Math.ceil(1e6*n)}},Tj=t=\u003e(t.solveGraphOptions?.MAX_ITERATIONS??1e6)+(t.sectionSolverOptions?.MAX_ITERATIONS??1e6)+1e6,Rj=t=\u003et.mutuallyConnectedNetworkId,Ej=(t,e)=\u003et.simpleRouteConnection?.pointsToConnect[e],Aj=t=\u003e{const e=Ej(t.routeMetadata,t.endpointIndex);if(!e)return t.fallbackZ;const n=xo(e).map(e=\u003eko(e,t.layerCount));return t.regionAvailableZ.find(t=\u003en.includes(t))??t.fallbackZ},Oj=(t,e)=\u003e{const n=t.d,o=n.bounds;return{capacityMeshNodeId:t.d.capacityMeshNodeId,center:{x:t.d.center.x,y:t.d.center.y},width:t.d.width,height:t.d.height,availableZ:[...t.d.availableZ],...o?{bounds:{minX:o.minX,maxX:o.maxX,minY:o.minY,maxY:o.maxY}}:{},_containsObstacle:t.d._containsObstacle,_containsTarget:t.d._containsTarget,_offBoardConnectionId:t.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:void 0===t.d._offBoardConnectedCapacityMeshNodeIds?void 0:[...t.d._offBoardConnectedCapacityMeshNodeIds],_qfpRegionType:n._qfpRegionType,_isNarrowQfpPadGap:n._isNarrowQfpPadGap,...void 0!==e?{netId:e}:{}}},kj=t=\u003e{const e=t.d;return{portId:t.d.portId,x:t.d.x,y:t.d.y,z:t.d.z,prevPortPointId:e.prevPortPointId,nextPortPointId:e.nextPortPointId,distToCentermostPortOnZ:t.d.distToCentermostPortOnZ,tinyHypergraphPortPenalty:t.d.tinyHypergraphPortPenalty,cramped:t.d.cramped,_preloadedFixedNetIds:t.d._preloadedFixedNetIds,_preloadedTracePortAssignments:t.d._preloadedTracePortAssignments}},Lj=t=\u003e{const e=function(){const t=new Map;return e=\u003e{const n=e.mutuallyConnectedNetworkId;let o=t.get(n);return void 0===o\u0026\u0026(o=t.size,t.set(n,o)),o}}(),n=function(t){const e=new Map,n=new Set,o=new Map;for(const i of t.params.connections){const r=i.mutuallyConnectedNetworkId,s=t.getNetIndex({connectionId:i.connectionId,mutuallyConnectedNetworkId:r});for(const t of[i.connectionId,r])o.set(t,s);for(const o of i.simpleRouteConnection.pointsToConnect)for(const i of t.params.graph.regions){if(!gf({point:o,region:i,layerCount:t.params.layerCount}))continue;if(void 0===o.pcb_port_id\u0026\u0026!0!==i.d._containsTarget){n.add(i.regionId);continue}let r=e.get(i.regionId);r||(r=new Set,e.set(i.regionId,r)),r.add(s)}}for(const n of t.params.graph.regions)for(const t of n.d._connectedTo??[]){const i=o.get(t);if(void 0===i)continue;let r=e.get(n.regionId);r||(r=new Set,e.set(n.regionId,r)),r.add(i)}const i=new Map;for(const t of n)i.set(t,-1);for(const[t,n]of e)1===n.size\u0026\u0026i.set(t,[...n][0]);return i}({params:t,getNetIndex:e}),o=t.graph.regions.map(t=\u003e({regionId:t.regionId,pointIds:t.ports.map(t=\u003et.d.portId),d:Oj(t,n.get(t.regionId))})),i=t.graph.ports.map(t=\u003e({portId:t.d.portId,region1Id:t.region1.regionId,region2Id:t.region2.regionId,d:kj(t)})),r=t.connections.map(t=\u003e({connectionId:t.connectionId,mutuallyConnectedNetworkId:t.mutuallyConnectedNetworkId,startRegionId:t.startRegion.regionId,endRegionId:t.endRegion.regionId,simpleRouteConnection:t.simpleRouteConnection})),s=[];for(const n of t.connections){const r={connectionId:n.connectionId,mutuallyConnectedNetworkId:n.mutuallyConnectedNetworkId,simpleRouteConnection:n.simpleRouteConnection},a=e(r),c=Ej(r,0),l=Ej(r,1),d=n.startRegion.d.availableZ[0]??0,h=n.endRegion.d.availableZ[0]??0,u=Aj({routeMetadata:r,endpointIndex:0,fallbackZ:d,regionAvailableZ:n.startRegion.d.availableZ,layerCount:t.layerCount}),p=Aj({routeMetadata:r,endpointIndex:1,fallbackZ:h,regionAvailableZ:n.endRegion.d.availableZ,layerCount:t.layerCount}),m=`tiny-terminal:start-region:${n.connectionId}`,g=`tiny-terminal:end-region:${n.connectionId}`,f=`tiny-terminal:start-port:${n.connectionId}`,y=`tiny-terminal:end-port:${n.connectionId}`;o.push({regionId:m,pointIds:[f],d:{capacityMeshNodeId:m,center:{x:c?.x??n.startRegion.d.center.x,y:c?.y??n.startRegion.d.center.y},width:Sj,height:Sj,availableZ:[u],_containsTarget:!0,_tinyTerminal:!0,_tinyTerminalNetId:n.mutuallyConnectedNetworkId,netId:a}}),o.push({regionId:g,pointIds:[y],d:{capacityMeshNodeId:g,center:{x:l?.x??n.endRegion.d.center.x,y:l?.y??n.endRegion.d.center.y},width:Sj,height:Sj,availableZ:[p],_containsTarget:!0,_tinyTerminal:!0,_tinyTerminalNetId:n.mutuallyConnectedNetworkId,netId:a}}),i.push({portId:f,region1Id:n.startRegion.regionId,region2Id:m,d:{portId:f,x:c?.x??n.startRegion.d.center.x,y:c?.y??n.startRegion.d.center.y,z:u,distToCentermostPortOnZ:0,_tinyTerminal:!0,...t.preserveTerminalPcbPortIds\u0026\u0026c?.pcb_port_id?{pcb_port_id:c.pcb_port_id}:{}}}),i.push({portId:y,region1Id:n.endRegion.regionId,region2Id:g,d:{portId:y,x:l?.x??n.endRegion.d.center.x,y:l?.y??n.endRegion.d.center.y,z:p,distToCentermostPortOnZ:0,_tinyTerminal:!0,...t.preserveTerminalPcbPortIds\u0026\u0026l?.pcb_port_id?{pcb_port_id:l.pcb_port_id}:{}}});const _=o.find(t=\u003et.regionId===n.startRegion.regionId),b=o.find(t=\u003et.regionId===n.endRegion.regionId);_?.pointIds.push(f),b?.pointIds.push(y),s.push({connection:{connectionId:n.connectionId},path:[{portId:f},{portId:y}]})}const a={regions:o,ports:i,connections:r,solvedRoutes:s};return(t=\u003e{const e=new Map,n=new Map,o=new Set((t.connections??[]).flatMap(t=\u003e[t.startRegionId,t.endRegionId])),i=new Set(t.regions.filter(t=\u003e{const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;return!0===t.d?._containsObstacle\u0026\u0026(void 0===e||-1===e)\u0026\u0026!o.has(t.regionId)}).map(t=\u003et.regionId));let r=0;for(const o of t.ports){const t=o.d,s=t?._preloadedTracePortAssignments??[];if(s.length\u003e0\u0026\u0026r++,!i.has(o.region1Id)\u0026\u0026!i.has(o.region2Id))for(const t of s){const i=n.get(t.traceId);if(void 0!==i\u0026\u0026i!==t.fixedNetId)throw new Error(`Preloaded trace \"${t.traceId}\" maps to multiple canonical nets`);n.set(t.traceId,t.fixedNetId);const r=e.get(t.traceId)??[];r.push({port:o,assignment:t}),e.set(t.traceId,r)}}const s=new Map(t.regions.map(t=\u003e[t.regionId,t])),a=t.connections??=[],c=t.solvedRoutes??=[];let l=0,d=0;for(const[t,o]of e){o.sort((t,e)=\u003et.assignment.routePosition-e.assignment.routePosition||t.assignment.z-e.assignment.z||t.port.portId.localeCompare(e.port.portId));const e=o.filter(({port:t},e)=\u003e0===e||t.portId!==o[e-1].port.portId);if(e.length\u003c2)continue;const i=[];let r;for(let t=0;t\u003ce.length-1;t++){const n=e[t],o=e[t+1];if(n.assignment.z===o.assignment.z\u0026\u0026Math.abs(n.assignment.routePosition-o.assignment.routePosition)\u003c=1e-6){r=void 0;continue}const s=yj(e,t,r);s?(i.push({regionId:s,from:n,to:o}),r=s):r=void 0}const h=[];for(const t of i){const e=h.at(-1);e\u0026\u0026e.at(-1).to.port.portId===t.from.port.portId?e.push(t):h.push([t])}for(const[e,o]of h.entries()){const i=mj(t,e);for(const e of o){const n=s.get(e.regionId);if(!n)throw new Error(`Preloaded trace \"${t}\" references missing region \"${e.regionId}\"`);n.assignments=[...n.assignments??[],{regionPort1Id:e.from.port.portId,regionPort2Id:e.to.port.portId,connectionId:i}],d++}const r=o[0],l=o.at(-1),h=r.from.port,u=l.to.port,p={connectionId:i,mutuallyConnectedNetworkId:n.get(t)??t,startRegionId:_j(h,r.regionId),endRegionId:_j(u,l.regionId),preloadedTraceSection:{traceId:t,startRoutePosition:r.from.assignment.routePosition,endRoutePosition:l.to.assignment.routePosition,startPoint:{x:r.from.assignment.tracePoint.x,y:r.from.assignment.tracePoint.y,z:r.from.assignment.z},endPoint:{x:l.to.assignment.tracePoint.x,y:l.to.assignment.tracePoint.y,z:l.to.assignment.z}}};a.push(p),c.push({requiredRip:!1,connection:p,path:[h,u].map(t=\u003e({portId:t.portId,g:0,h:0,f:0,hops:0,ripRequired:!1}))})}h.length\u003e0\u0026\u0026l++}})(a),a},Dj=t=\u003e{const e=new Map;for(let n=0;n\u003ct.problem.routeNet.length;n++){const o=t.problem.routeMetadata?.[n],i=o?.mutuallyConnectedNetworkId;if(\"string\"!=typeof i||0===i.length)throw new Error(`Tiny hypergraph route ${n} is missing a net ID`);e.set(i,t.problem.routeNet[n])}for(let n=0;n\u003ct.problem.regionNetId.length;n++){const o=t.topology.regionMetadata?.[n]?._tinyTerminalNetId;if(\"string\"!=typeof o)continue;const i=e.get(o);void 0!==i\u0026\u0026(t.problem.regionNetId[n]=i)}},zj=t=\u003e{const e=new Map;t.topology.regionMetadata?.forEach((t,n)=\u003e{\"string\"==typeof t.serializedRegionId\u0026\u0026e.set(t.serializedRegionId,n)});const n=new Set;for(const e of t.problem.routeMetadata??[])pj(e)||(\"string\"==typeof e.startRegionId\u0026\u0026n.add(e.startRegionId),\"string\"==typeof e.endRegionId\u0026\u0026n.add(e.endRegionId));for(const o of t.problem.routeMetadata??[])if(pj(o))for(const i of[o.startRegionId,o.endRegionId]){if(\"string\"!=typeof i||n.has(i))continue;const o=e.get(i);if(void 0===o)continue;const r=t.topology.regionMetadata?.[o];\"number\"==typeof r?.netId||\"number\"==typeof r?.NetId||(t.problem.regionNetId[o]=-1)}},Fj=t=\u003e{if(t.problem.metadataPortPenaltiesApplied)return 0;let e=0,n=void 0!==t.problem.portPenalty;for(let o=0;o\u003ct.topology.portCount;o++){const i=Number(t.topology.portMetadata?.[o]?.tinyHypergraphPortPenalty),r=Number.isFinite(i)\u0026\u0026i\u003e0?i:0;r\u003e0\u0026\u0026e++,t.problem.portPenalty?.[o]!==r\u0026\u0026(n=!1)}if(n)return t.problem.metadataPortPenaltiesApplied=!0,e;e=0;const o=t.problem.portPenalty?new Float64Array(t.problem.portPenalty):new Float64Array(t.topology.portCount);for(let n=0;n\u003ct.topology.portCount;n++){const i=Number(t.topology.portMetadata?.[n]?.tinyHypergraphPortPenalty);!Number.isFinite(i)||i\u003c=0||(o[n]+=i,e++)}return e\u003e0\u0026\u0026(t.problem.portPenalty=o),t.problem.metadataPortPenaltiesApplied=!0,e},Bj=class extends dj{configuredSolvers=new WeakSet;duplicatePortPenaltyCount=0;metadataPortPenaltyCount=0;crampedPortPenaltyCount=0;preloadedPortCount=0;preloadedFixedSegmentCount=0;crampedPortTraversalPenalty;useSelectiveReripRouting;constructor(t,e){super(t),this.useSelectiveReripRouting=e,this.crampedPortTraversalPenalty=150;const n=bj(t.serializedHyperGraph);if(this.preloadedPortCount=n.preloadedPortCount,this.preloadedFixedSegmentCount=n.preloadedAssignmentCount,e){const t=this.pipelineDef.find(t=\u003e\"solveGraph\"===t.solverName);if(!t)throw new Error(\"Tiny hypergraph pipeline is missing the solveGraph stage\");t.solverClass=uj}this.MAX_ITERATIONS=Tj(t)}loadHyperGraph(t){const e=super.loadHyperGraph(t);((t,e)=\u003e{const n=new Map;for(const t of e.connections??[])pj(t)\u0026\u0026n.set(t.connectionId,t.preloadedTraceSection);for(const e of t.problem.routeMetadata??[]){const t=n.get(e.connectionId);t\u0026\u0026(e.preloadedTraceSection=t)}})(e,this.inputProblem.serializedHyperGraph);const n=Fj(e),{duplicatePortPenaltyCount:o,crampedPortPenaltyCount:i}=((t,e)=\u003e{let n=0,o=0;const i=t.problem.portPenalty?new Float64Array(t.problem.portPenalty):new Float64Array(t.topology.portCount);for(let r=0;r\u003ct.topology.portCount;r++){const s=t.topology.portMetadata?.[r];\"string\"==typeof s?.duplicatedFromPortId\u0026\u0026(i[r]+=150,n++),s?.cramped\u0026\u0026e\u003e0\u0026\u0026(i[r]+=e,o++)}return(n\u003e0||o\u003e0)\u0026\u0026(t.problem.portPenalty=i),{duplicatePortPenaltyCount:n,crampedPortPenaltyCount:o}})(e,this.crampedPortTraversalPenalty);return Dj(e),zj(e),this.metadataPortPenaltyCount=Math.max(this.metadataPortPenaltyCount,n),this.duplicatePortPenaltyCount=Math.max(this.duplicatePortPenaltyCount,o),this.crampedPortPenaltyCount=Math.max(this.crampedPortPenaltyCount,i),e}_step(){super._step(),this.configureSolver(this.activeSubSolver)}getInitialVisualizationSolver(){if(this.useSelectiveReripRouting\u0026\u0026!this.initialVisualizationSolver){const{topology:t,problem:e}=this.loadHyperGraph(this.inputProblem.serializedHyperGraph);this.initialVisualizationSolver=new uj(t,e,this.getSolveGraphOptions())}const t=super.getInitialVisualizationSolver();return this.configureSolver(t),t}getSolvedTinySolver(){const t=this.getSolver(\"optimizeSection\");if(t?.solved\u0026\u0026!t.failed)return t.getSolvedSolver();const e=this.getSolver(\"solveGraph\");if(e?.solved\u0026\u0026!e.failed)return e;throw new Error(\"TinyHyperGraph section pipeline does not have a solved graph\")}configureSolver(t){if(t\u0026\u0026!this.configuredSolvers.has(t)){if(t instanceof JB||t instanceof nB){const e=t;Fj(e),Dj(e),zj(e)}this.configuredSolvers.add(t)}}},jj=class extends si{constructor(t){super(),this.params=t;const e=(t=\u003et.map(t=\u003e{const e=t.simpleRouteConnection;if(!e)throw new Error(`TinyHypergraphPortPointPathingSolver requires a SimpleRouteConnection for \"${t.connectionId}\"`);const n=t.mutuallyConnectedNetworkId;if(!n)throw new Error(`TinyHypergraphPortPointPathingSolver requires a net ID for \"${t.connectionId}\"`);return{...t,mutuallyConnectedNetworkId:n,simpleRouteConnection:e}}))(t.connections),n=t.flags.USE_SELECTIVE_RERIP_ROUTING?function(t,e){const n=new Map;for(const o of t){const t=e(o);n.set(t,(n.get(t)??0)+1)}return t.map((t,e)=\u003e({connection:t,index:e})).sort((t,o)=\u003e(n.get(e(o.connection))??0)-(n.get(e(t.connection))??0)||t.index-o.index).map(({connection:t})=\u003et)}(e,Rj):e;this.rootConnectionNameByConnectionId=new Map(n.map(t=\u003e[t.connectionId,t.simpleRouteConnection.__rootConnectionNames?.[0]]));const o=Lj({...t,connections:n});this.originalPreloadedSegmentKeysByConnectionId=(t=\u003e{const e=new Map;for(const n of t.connections??[])pj(n)\u0026\u0026e.set(n.connectionId,new Set);for(const n of t.regions)for(const t of n.assignments??[]){const o=e.get(t.connectionId);if(!o)continue;const[i,r]=[t.regionPort1Id,t.regionPort2Id].sort();o.add(JSON.stringify([n.regionId,i,r]))}return e})(o);const i=bj(o),r=i.preloadedPortCount\u003e0,s=r\u0026\u0026!0===t.flags.USE_PARTIAL_RIP_ROUTING_WITH_PRELOADED_TRACES,a=s?Math.max(o.connections?.length??0,i.preloadedAssignmentCount):void 0;let c=o;if(n.length\u003c=180){const e=new AB(o,{duplicatePortProximity:.05,useSerializedPortPenalties:!1,routeSolveOptions:{...Mj(t.minViaPadDiameter),USE_SPARSE_CANDIDATE_STORAGE:!1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,MAX_ITERATIONS:Math.ceil(2e6*Pj(t.effort)),RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!0}});if(e.solve(),e.failed)this.duplicateCongestedPortError=e.error??\"unknown error\";else{this.duplicateCongestedPortReport=e.report,c=e.getOutput();for(const t of c.ports){const e=vj(t.d);\"string\"==typeof e.duplicatedFromPortId\u0026\u0026(delete e._preloadedFixedNetIds,delete e._preloadedTracePortAssignments)}}}else this.duplicateCongestedPortError=`Skipped for ${n.length} connections`;this.duplicatedPortCount=this.duplicateCongestedPortReport?.duplicatedPorts.reduce((t,e)=\u003et+e.duplicatePortIds.length,0)??0;const l=((t,e,n,o=!0,i)=\u003e{const r=t.connections?.length??0,s=i??r,a=Ij.PARTIAL_RIP_MIN_ROUTE_COUNT??0,c=Ij.PARTIAL_RIP_MAX_ROUTE_COUNT??Number.POSITIVE_INFINITY,l=o\u0026\u0026s\u003e=a\u0026\u0026s\u003c=c;return{serializedHyperGraph:t,createSectionMask:({topology:t})=\u003enew Int8Array(t.portCount),solveGraphOptions:{...Nj(e,n),...l?{PARTIAL_RIP_MIN_ROUTE_COUNT:0,PARTIAL_RIP_MAX_ROUTE_COUNT:Number.POSITIVE_INFINITY,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:0}:{PARTIAL_RIP_ENABLED:!1,OUTSIDE_IN_ROUTING:!1}},sectionSolverOptions:wj(e,n)}})({...c,solvedRoutes:o.solvedRoutes},t.effort,t.minViaPadDiameter,!r||s,a);this.tinyPipelineSolver=new Bj(l,!0===t.flags.USE_SELECTIVE_RERIP_ROUTING),this.primaryTinyPipelineSolver=this.tinyPipelineSolver,n.length\u003e=30\u0026\u0026n.length\u003c=99\u0026\u0026(this.alternativeTinyPipelineInput={...l,solveGraphOptions:{...l.solveGraphOptions,TRACE_DENSITY_COST_FACTOR:1}}),this.MAX_ITERATIONS=Tj(l)*(this.alternativeTinyPipelineInput?2:1),this.originalRegionById=new Map(t.graph.regions.map(t=\u003e[t.regionId,t])),this.originalRegionIds=new Set(this.originalRegionById.keys()),this.inputNodeWithPortPoints=((t,e)=\u003e{const n=new Map(e.regions.map(t=\u003e[t.regionId,t])),o=new Map(e.ports.map(t=\u003e[t.portId,t]));return t.graph.regions.map(t=\u003e{const e=n.get(t.regionId),i=(e?.pointIds??t.ports.map(t=\u003et.d.portId)).map(t=\u003eo.get(t)).filter(t=\u003et\u0026\u0026!vj(t.d)._tinyTerminal).map(t=\u003e{const e=t,o=vj(e.d),i=n.get(e.region1Id),r=n.get(e.region2Id),s=Boolean(xj(i?.d)._offBoardConnectionId??xj(r?.d)._offBoardConnectionId);return{portPointId:e.portId,x:Number(o.x??0),y:Number(o.y??0),z:Number(o.z??0),prevPortPointId:\"string\"==typeof o.prevPortPointId?o.prevPortPointId:void 0,nextPortPointId:\"string\"==typeof o.nextPortPointId?o.nextPortPointId:void 0,connectionNodeIds:[e.region1Id,e.region2Id],distToCentermostPortOnZ:Number(o.distToCentermostPortOnZ??0),cramped:Boolean(o.cramped),connectsToOffBoardNode:s}});return{capacityMeshNodeId:t.d.capacityMeshNodeId,center:t.d.center,width:t.d.width,height:t.d.height,portPoints:i,availableZ:t.d.availableZ,_containsObstacle:t.d._containsObstacle,_containsTarget:t.d._containsTarget,_offBoardConnectionId:t.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t.d._offBoardConnectedCapacityMeshNodeIds,_qfpRegionType:t.d._qfpRegionType,_isNarrowQfpPadGap:t.d._isNarrowQfpPadGap}})})(t,c)}params;tinyPipelineSolver;primaryTinyPipelineSolver;alternativeTinyPipelineSolver;alternativeTinyPipelineInput;candidatePortfolioPhase=\"primary\";primaryCandidateSummary;alternativeCandidateSummary;alternativeCandidateEvaluated=!1;selectedCandidate=\"primary\";duplicateCongestedPortReport;duplicateCongestedPortError;duplicatedPortCount=0;inputNodeWithPortPoints;originalRegionById;originalRegionIds;rootConnectionNameByConnectionId;originalPreloadedSegmentKeysByConnectionId;getSolverName(){return\"TinyHypergraphPortPointPathingSolver\"}getChangedPreloadedRouteIds(t){const e=new Map,n=new Map;for(let o=0;o\u003ct.problem.routeCount;o++){const i=this.getRouteMetadata(t,o);pj(i)\u0026\u0026(e.set(i.connectionId,o),n.set(o,new Set))}for(let e=0;e\u003ct.state.regionSegments.length;e++){const o=t.topology.regionMetadata?.[e]?.serializedRegionId;for(const[i,r,s]of t.state.regionSegments[e]??[]){const e=n.get(i);if(!e)continue;const a=t.topology.portMetadata?.[r]?.serializedPortId,c=t.topology.portMetadata?.[s]?.serializedPortId;if(\"string\"!=typeof o||\"string\"!=typeof a||\"string\"!=typeof c)throw new Error(`Tiny hypergraph preloaded route ${i} has a segment without serialized topology IDs`);const[l,d]=[a,c].sort();e.add(JSON.stringify([o,l,d]))}}const o=new Set;for(const[t,i]of this.originalPreloadedSegmentKeysByConnectionId){const r=e.get(t);if(void 0===r)throw new Error(`Tiny hypergraph lost preloaded trace section \"${t}\"`);const s=n.get(r);if(i.size\u003e0\u0026\u00260===s.size)throw new Error(`Tiny hypergraph lost preloaded trace section \"${t}\"`);(i.size!==s.size||[...i].some(t=\u003e!s.has(t)))\u0026\u0026o.add(r)}return o}summarizePipelineCandidate(t){const e=t.getSolvedTinySolver();let n=0,o=0,i=0,r=0,s=0,a=0;const c=e.topology.regionMetadata??[];for(let t=0;t\u003ce.state.regionSegments.length;t++){const l=e.state.regionSegments[t];s+=l.length;for(const[,t,n]of l)e.topology.portZ[t]!==e.topology.portZ[n]\u0026\u0026(a+=1);const d=c[t]?.capacityMeshNodeId;if(!d||!this.originalRegionIds.has(d))continue;const h=this.originalRegionById.get(d);if(!h||0===l.length)continue;const u=l.map(([t,n,o])=\u003e[this.createAssignedPortPoint(e,t,n),this.createAssignedPortPoint(e,t,o)]),p={capacityMeshNodeId:h.d.capacityMeshNodeId,center:h.d.center,width:h.d.width,height:h.d.height,portPoints:u.flat(),portPointsInPairs:u,availableZ:h.d.availableZ},m=Ms(p),g=Ys(h.d,m.numSameLayerCrossings,m.numEntryExitLayerChanges,m.numTransitionPairCrossings);n+=g,o+=g*g,i=Math.max(i,g),r+=p.portPoints.length**2}return{nodePfSum:n,nodePfSquaredSum:o,nodePfMax:i,squaredNodePortPointCount:r,segmentCount:s,layerChangeCount:a,changedPreloadedTraceSectionCount:this.getChangedPreloadedRouteIds(e).size}}shouldEvaluateAlternative(t){const e=this.primaryTinyPipelineSolver.getSolvedTinySolver().problem.routeCount;return void 0!==this.alternativeTinyPipelineInput\u0026\u0026((t,e)=\u003et.nodePfSum\u003e4\u0026\u0026t.nodePfMax\u003e1\u0026\u0026t.squaredNodePortPointCount/Math.max(1,e)\u003e=125)(t,e)}shouldSelectAlternative(t,e){return((t,e,n)=\u003e{if(e.changedPreloadedTraceSectionCount\u003et.changedPreloadedTraceSectionCount)return!1;const o=n\u003e40?.92:.95,i=e.nodePfSum\u003c=.9*t.nodePfSum\u0026\u0026e.nodePfSquaredSum\u003c=.85*t.nodePfSquaredSum\u0026\u0026e.nodePfMax\u003c=.85*t.nodePfMax\u0026\u0026e.squaredNodePortPointCount\u003c.98*t.squaredNodePortPointCount\u0026\u0026e.segmentCount\u003c=.97*t.segmentCount;return e.nodePfSum\u003c=1.03*t.nodePfSum\u0026\u0026e.nodePfSquaredSum\u003c=1.06*t.nodePfSquaredSum\u0026\u0026(e.squaredNodePortPointCount\u003ct.squaredNodePortPointCount*o||i)})(t,e,this.primaryTinyPipelineSolver.getSolvedTinySolver().problem.routeCount)}finishCandidatePortfolio(){this.candidatePortfolioPhase=\"complete\",this.solved=this.tinyPipelineSolver.solved,this.failed=this.tinyPipelineSolver.failed,this.error=this.tinyPipelineSolver.error??null}getSolveGraphBenchmarkMetrics(){const t=this.tinyPipelineSolver.getSolver(\"solveGraph\");if(!t)return;const e=t.state.regionSegments.map(t=\u003et.length),n=\"alternative\"===this.selectedCandidate?this.alternativeCandidateSummary:this.primaryCandidateSummary,o=t.stats,i=this.tinyPipelineSolver.getStageStats().solveGraph;return{routeCount:t.problem.routeCount,traceDensityCandidateEvaluated:this.alternativeCandidateEvaluated,traceDensityCandidateSelected:\"alternative\"===this.selectedCandidate,downstreamNodePfSum:n?.nodePfSum,downstreamNodePfSquaredSum:n?.nodePfSquaredSum,downstreamNodePfMax:n?.nodePfMax,downstreamSquaredNodePortPointCount:n?.squaredNodePortPointCount,changedPreloadedTraceSectionCount:n?.changedPreloadedTraceSectionCount,iterations:t.iterations,timeMs:i?.timeSpent,ripCount:o.ripCount,partialRipCount:o.partialRipCount,partiallyRippedRouteCount:o.partiallyRippedRouteCount,partiallyRippedSegmentCount:o.partiallyRippedSegmentCount,retainedPartialRipSegmentCount:o.retainedPartialRipSegmentCount,firstMaxRegionCost:o.firstMaxRegionCost,bestMaxRegionCost:o.bestMaxRegionCost,firstTotalRegionCost:o.firstTotalRegionCost,bestTotalRegionCost:o.bestTotalRegionCost,firstSegmentCount:o.firstSegmentCount,bestSolvedSegmentCount:o.bestSolvedSegmentCount,bestSolvedMaxRegionSegmentCount:o.bestSolvedMaxRegionSegmentCount,bestSolvedSquaredRegionSegmentCount:o.bestSolvedSquaredRegionSegmentCount,finalMaxRegionSegmentCount:Math.max(0,...e),finalSquaredRegionSegmentCount:e.reduce((t,e)=\u003et+e*e,0),finalSegmentCount:n?.segmentCount,finalLayerChangeCount:n?.layerChangeCount,warmupFullRipAttempts:o.partialRipWarmupFullRipAttempts,complexityAwareSelection:o.partialRipComplexityAwareSelection,targetReached:o.partialRipTargetReached,outsideInCompletedRouteCount:o.outsideInCompletedRouteCount,outsideInFallbackRouteCount:o.outsideInFallbackRouteCount,outsideInForwardExpansionCount:o.outsideInForwardExpansionCount,outsideInReverseExpansionCount:o.outsideInReverseExpansionCount}}_step(){this.tinyPipelineSolver.step(),\"primary\"===this.candidatePortfolioPhase\u0026\u0026this.primaryTinyPipelineSolver.failed?(this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio()):\"primary\"===this.candidatePortfolioPhase\u0026\u0026this.primaryTinyPipelineSolver.solved?(this.primaryCandidateSummary=this.summarizePipelineCandidate(this.primaryTinyPipelineSolver),this.shouldEvaluateAlternative(this.primaryCandidateSummary)?(this.alternativeCandidateEvaluated=!0,this.alternativeTinyPipelineSolver=new Bj(this.alternativeTinyPipelineInput,!0===this.params.flags.USE_SELECTIVE_RERIP_ROUTING),this.tinyPipelineSolver=this.alternativeTinyPipelineSolver,this.candidatePortfolioPhase=\"alternative\"):(this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio())):\"alternative\"===this.candidatePortfolioPhase\u0026\u0026(this.tinyPipelineSolver.solved||this.tinyPipelineSolver.failed)\u0026\u0026(this.tinyPipelineSolver.solved\u0026\u0026!this.tinyPipelineSolver.failed\u0026\u0026(this.alternativeCandidateSummary=this.summarizePipelineCandidate(this.tinyPipelineSolver)),this.alternativeCandidateSummary\u0026\u0026this.primaryCandidateSummary\u0026\u0026this.shouldSelectAlternative(this.primaryCandidateSummary,this.alternativeCandidateSummary)?(this.selectedCandidate=\"alternative\",this.primaryTinyPipelineSolver=void 0,this.alternativeTinyPipelineSolver=void 0):(this.tinyPipelineSolver=this.primaryTinyPipelineSolver,this.alternativeTinyPipelineSolver=void 0),this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio());const t=this.tinyPipelineSolver.getSolver(\"optimizeSection\"),e=this.getCurrentTinySolver();this.solved=\"complete\"===this.candidatePortfolioPhase\u0026\u0026this.tinyPipelineSolver.solved,this.failed=\"complete\"===this.candidatePortfolioPhase\u0026\u0026this.tinyPipelineSolver.failed,this.error=this.failed?this.tinyPipelineSolver.error??null:null,this.progress=\"complete\"===this.candidatePortfolioPhase?1:\"alternative\"===this.candidatePortfolioPhase?.5+.5*this.tinyPipelineSolver.progress:this.alternativeTinyPipelineInput?.5*this.tinyPipelineSolver.progress:this.tinyPipelineSolver.progress,this.stats={duplicateCongestedPortSourceCount:this.duplicateCongestedPortReport?.duplicatedPorts.length??0,duplicateCongestedPortCount:this.duplicateCongestedPortReport?.duplicatedPorts.reduce((t,e)=\u003et+e.duplicatePortIds.length,0)??0,duplicateCongestedPortFallbackToOriginal:Boolean(this.duplicateCongestedPortError),duplicateCongestedPortPenalty:this.duplicatedPortCount\u003e0?150:0,duplicateCongestedPortPenaltyCount:this.tinyPipelineSolver.duplicatePortPenaltyCount,metadataPortPenaltyCount:this.tinyPipelineSolver.metadataPortPenaltyCount,crampedPortPenalty:this.tinyPipelineSolver.crampedPortTraversalPenalty,crampedPortPenaltyCount:this.tinyPipelineSolver.crampedPortPenaltyCount,preloadedPortCount:this.tinyPipelineSolver.preloadedPortCount,preloadedFixedSegmentCount:this.tinyPipelineSolver.preloadedFixedSegmentCount,duplicateCongestedPortError:this.duplicateCongestedPortError,candidatePortfolioPhase:this.candidatePortfolioPhase,candidatePortfolioSelectedCandidate:this.selectedCandidate,candidatePortfolioPrimarySummary:this.primaryCandidateSummary,candidatePortfolioAlternativeSummary:this.alternativeCandidateSummary,...this.tinyPipelineSolver.stats??{},...e?.stats??{},...t?.stats??{},currentStage:this.tinyPipelineSolver.getCurrentStageName(),stageStats:this.tinyPipelineSolver.getStageStats()},this.activeSubSolver=this.tinyPipelineSolver.activeSubSolver??null}preview(){return this.visualize()}getCurrentTinySolver(){const t=this.tinyPipelineSolver.getSolver(\"optimizeSection\");if(t?.solved\u0026\u0026!t.failed)return t.getSolvedSolver();const e=this.tinyPipelineSolver.getSolver(\"solveGraph\");return e||void 0}getSolvedTinySolver(){return this.tinyPipelineSolver.getSolvedTinySolver()}getRouteMetadata(t,e){return t.problem.routeMetadata?.[e]}createAssignedPortPoint(t,e,n){const o=this.getRouteMetadata(t,e),i=o?(t=\u003et.simpleRouteConnection?.name??t.connectionId)(o):`route-${e}`,r=o?this.rootConnectionNameByConnectionId.get(o.connectionId)??o.mutuallyConnectedNetworkId:void 0,s=t.topology.portMetadata?.[n];return{portPointId:String(s?.serializedPortId??s?.portId??`tiny-port-${n}`),x:t.topology.portX[n],y:t.topology.portY[n],z:t.topology.portZ[n],connectionName:i,rootConnectionName:r,...this.params.preserveTerminalPcbPortIds\u0026\u0026\"string\"==typeof s?.pcb_port_id?{pcb_port_id:s.pcb_port_id}:{},prevPortPointId:\"string\"==typeof s?.prevPortPointId?s.prevPortPointId:void 0,nextPortPointId:\"string\"==typeof s?.nextPortPointId?s.nextPortPointId:void 0}}getOutput(){const t=this.getSolvedTinySolver(),e=[],n=t.state.regionSegments,o=t.topology.regionMetadata??[],i=this.getChangedPreloadedRouteIds(t);for(let r=0;r\u003cn.length;r++){const s=o[r]?.capacityMeshNodeId;if(!s||!this.originalRegionIds.has(s))continue;const a=this.originalRegionById.get(s);if(!a)continue;const c=n[r].filter(([e])=\u003e{const n=this.getRouteMetadata(t,e);return!pj(n)||i.has(e)}).map(([e,n,o])=\u003e{const i=this.createAssignedPortPoint(t,e,n),r=this.createAssignedPortPoint(t,e,o);return i.portPointId\u0026\u0026r.portPointId\u0026\u0026(i.nextPortPointId=r.portPointId,r.prevPortPointId=i.portPointId),[i,r]}),l=c.flat();0!==l.length\u0026\u0026e.push({capacityMeshNodeId:a.d.capacityMeshNodeId,center:a.d.center,width:a.d.width,height:a.d.height,portPoints:l,portPointsInPairs:c,availableZ:a.d.availableZ})}const r=[...i].map(e=\u003e{const n=this.getRouteMetadata(t,e);if(!pj(n))throw new Error(`Changed preloaded hypergraph route ${e} is missing section metadata`);const o=n.preloadedTraceSection;return{connectionName:n.connectionId,traceId:o.traceId,startRoutePosition:o.startRoutePosition,endRoutePosition:o.endRoutePosition,connection:{name:n.connectionId,__rootConnectionNames:[n.mutuallyConnectedNetworkId],pointsToConnect:[{x:o.startPoint.x,y:o.startPoint.y,layer:vo(o.startPoint.z,this.params.layerCount)},{x:o.endPoint.x,y:o.endPoint.y,layer:vo(o.endPoint.z,this.params.layerCount)}]}}});return this.stats.changedPreloadedTraceSectionCount=r.length,{nodesWithPortPoints:e,inputNodeWithPortPoints:this.inputNodeWithPortPoints,changedPreloadedTraceSections:r}}computeNodePf(t){const e=this.getOutput().nodesWithPortPoints.find(e=\u003ee.capacityMeshNodeId===t.capacityMeshNodeId),n=this.originalRegionById.get(t.capacityMeshNodeId);if(!e||!n)return null;const o=Ms(e);return Ys(n.d,o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.numTransitionPairCrossings)}tryFinalAcceptance(){}getConstructorParams(){return[this.params]}visualize(){return this.tinyPipelineSolver.visualize()}},$j=(t,e)=\u003e{if(!t||\"none\"===t)return t;try{const n=gt(t);return`rgba(${n.red},${n.green},${n.blue},${e})`}catch{return To(t,1-e)}},Yj=({srj:t,opacity:e=.25,visualizationOptions:n={}})=\u003e{const o=Ho({...t,obstacles:[]},n);return{...o,points:[],lines:o.lines?.map(t=\u003e({...t,strokeColor:$j(t.strokeColor,e)})),rects:o.rects?.map(t=\u003e({...t,fill:$j(t.fill,e),stroke:$j(t.stroke,e)})),circles:o.circles?.map(t=\u003e({...t,fill:$j(t.fill,e),stroke:$j(t.stroke,e)}))}};function Xj(t,e){return t.x\u003e=e.center.x-e.width/2\u0026\u0026t.x\u003c=e.center.x+e.width/2\u0026\u0026t.y\u003e=e.center.y-e.height/2\u0026\u0026t.y\u003c=e.center.y+e.height/2}var Vj=\"escape-via:\",Wj=1e-4,Hj=t=\u003et.obstacleId??[t.layers.join(\".\"),t.center.x.toFixed(4),t.center.y.toFixed(4),t.width.toFixed(4),t.height.toFixed(4)].join(\":\"),Gj=(t,e,n=1e-4)=\u003exe(t,e)\u003c=n,Uj=class extends si{constructor(t,e={}){super(),this.ogSrj=t,this.viaDiameter=e.viaDiameter??Yo(t).padDiameter,this.viaRadius=this.viaDiameter/2,this.minTraceWidth=e.minTraceWidth??t.minTraceWidth,this.obstacleMargin=e.obstacleMargin??t.defaultObstacleMargin??.15,this.requiredViaToPadClearance=Math.max(this.obstacleMargin,t.minViaEdgeToPadEdgeClearance??0),this.escapeOffset=this.viaRadius+Math.max(this.minTraceWidth/2,this.requiredViaToPadClearance),this.requiredTraceClearance=this.minTraceWidth/2+this.obstacleMargin/2,this.requiredViaToViaClearance=this.viaDiameter+this.obstacleMargin,this.outputSrj=t,this.escapeViaMetadataByPointId=new Map,this.createdEscapeVias=[]}ogSrj;getSolverName(){return\"EscapeViaLocationSolver\"}viaDiameter;viaRadius;minTraceWidth;obstacleMargin;escapeOffset;requiredTraceClearance;requiredViaToPadClearance;requiredViaToViaClearance;outputSrj;escapeViaMetadataByPointId;createdEscapeVias;nextEscapeViaIndex=0;getConnectionNetIds(t){return new Set([t.name,...t.__rootConnectionNames??[],t.__netConnectionName].filter(t=\u003eBoolean(t)))}obstacleMatchesConnectionNet(t,e){return t.connectedTo.some(t=\u003ee.has(t))}getObstacleZs(t){return t.__zLayers\u0026\u0026t.__zLayers.length\u003e0?t.__zLayers:t.layers.map(t=\u003eko(t,this.ogSrj.layerCount))}getViaSpanLayers(t,e){const n=ko(t,this.ogSrj.layerCount),o=ko(e,this.ogSrj.layerCount),i=Math.min(n,o),r=Math.max(n,o),s=Array.from({length:r-i+1},(t,e)=\u003ei+e);return{__zLayers:s,layers:s.map(t=\u003evo(t,this.ogSrj.layerCount))}}createEscapeViaObstacle(t){const{escapeVia:e,connectionNetIds:n}=t,{layers:o,__zLayers:i}=this.getViaSpanLayers(e.sourceLayer,e.targetLayer);return{obstacleId:`escape-via-obstacle:${e.pointId}`,type:\"rect\",layers:o,__zLayers:i,center:{x:e.x,y:e.y},width:this.viaDiameter,height:this.viaDiameter,connectedTo:Array.from(n)}}selectSourceObstacle(t){const{point:e,sourceLayer:n,connectionNetIds:o}=t;return this.ogSrj.obstacles.filter(t=\u003e!t.isCopperPour\u0026\u0026t.layers.includes(n)\u0026\u0026Xj(e,t)).sort((t,n)=\u003e{const i=t.connectedTo.includes(e.pointId??\"\")||t.connectedTo.includes(e.pcb_port_id??\"\")||this.obstacleMatchesConnectionNet(t,o);return i!==(n.connectedTo.includes(e.pointId??\"\")||n.connectedTo.includes(e.pcb_port_id??\"\")||this.obstacleMatchesConnectionNet(n,o))?i?-1:1:t.width*t.height-n.width*n.height})[0]}getCandidatePositions(t,e){if(!e)return this.dedupeCandidatePositions([{x:t.x+this.escapeOffset,y:t.y},{x:t.x-this.escapeOffset,y:t.y},{x:t.x,y:t.y+this.escapeOffset},{x:t.x,y:t.y-this.escapeOffset},{x:t.x+this.escapeOffset,y:t.y+this.escapeOffset},{x:t.x+this.escapeOffset,y:t.y-this.escapeOffset},{x:t.x-this.escapeOffset,y:t.y+this.escapeOffset},{x:t.x-this.escapeOffset,y:t.y-this.escapeOffset}]);const n=e.center.x-e.width/2,o=e.center.x+e.width/2,i=e.center.y-e.height/2,r=e.center.y+e.height/2,s=n-this.escapeOffset,a=o+this.escapeOffset,c=i-this.escapeOffset,l=r+this.escapeOffset,d=this.getEdgeSamples(i,r,t.y),h=this.getEdgeSamples(n,o,t.x),u=[];for(const t of d)u.push({x:s,y:t},{x:a,y:t});for(const t of h)u.push({x:t,y:c},{x:t,y:l});return this.dedupeCandidatePositions(u)}dedupeCandidatePositions(t){const e=[];for(const n of t)e.some(t=\u003eGj(t,n))||e.push(n);return e}pushEdgeSample(t,e,n,o){const i=Math.max(n,Math.min(o,e));t.some(t=\u003eMath.abs(t-i)\u003c=Wj)||t.push(i)}getEdgeSamples(t,e,n){const o=[],i=e-t;if(this.pushEdgeSample(o,n,t,e),i\u003c=Wj)return o;this.pushEdgeSample(o,t,t,e),this.pushEdgeSample(o,e,t,e),this.pushEdgeSample(o,(t+e)/2,t,e);const r=Math.max(t,Math.min(e,n)),s=Math.max(this.requiredViaToViaClearance,Wj),a=Math.ceil(i/s);for(let n=1;n\u003c=a;n++){const i=n*s;this.pushEdgeSample(o,r+i,t,e),this.pushEdgeSample(o,r-i,t,e)}return o}isInsideBoard(t){return!!(t.x\u003e=this.ogSrj.bounds.minX+this.viaRadius\u0026\u0026t.x\u003c=this.ogSrj.bounds.maxX-this.viaRadius\u0026\u0026t.y\u003e=this.ogSrj.bounds.minY+this.viaRadius\u0026\u0026t.y\u003c=this.ogSrj.bounds.maxY-this.viaRadius)\u0026\u0026(!(this.ogSrj.outline\u0026\u0026this.ogSrj.outline.length\u003e=3)||za(t,this.ogSrj.outline))}hasClearEscapePath(t){const{sourcePoint:e,candidate:n,sourceLayer:o,sourceObstacle:i}=t;if(this.ogSrj.outline\u0026\u0026this.ogSrj.outline.length\u003e=3){if(Fa({start:e,end:n,polygon:this.ogSrj.outline,margin:this.requiredTraceClearance}))return!1}for(const t of this.ogSrj.obstacles){if(t===i)continue;if(!t.layers.includes(o))continue;if(Xj(n,t))return!1;const r=Cl(t);if(Math.min(...r.map(t=\u003eRa(e,n,t.start,t.end)))+Wj\u003cthis.requiredTraceClearance)return!1}return!0}getBoardBoundarySegments(){if(this.ogSrj.outline\u0026\u0026this.ogSrj.outline.length\u003e=3)return this.ogSrj.outline.map((t,e)=\u003e({start:t,end:this.ogSrj.outline[(e+1)%this.ogSrj.outline.length]}));const{minX:t,maxX:e,minY:n,maxY:o}=this.ogSrj.bounds;return[{start:{x:t,y:n},end:{x:e,y:n}},{start:{x:e,y:n},end:{x:e,y:o}},{start:{x:e,y:o},end:{x:t,y:o}},{start:{x:t,y:o},end:{x:t,y:n}}]}getRayProbeDistance(){const{minX:t,maxX:e,minY:n,maxY:o}=this.ogSrj.bounds;return 2*Math.hypot(e-t,o-n)+this.viaDiameter}getRayIntersectionDistance(t){const{rayStart:e,rayEnd:n,segmentStart:o,segmentEnd:i}=t;if(!fe(e,n,o,i))return null;const r=ve(e,n,o,i);if(!r)return null;const s=xe(e,r);return s\u003c=Wj?null:s}getProjectedFreeSpace(t){const{sourcePoint:e,candidate:n}=t,o=n.x-e.x,i=n.y-e.y;return Math.abs(o)\u003c=Wj||Math.abs(i)\u003c=Wj?this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:o,y:i},travelDistance:xe(e,n)}):Math.min(this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:0,y:Math.sign(i)},travelDistance:Math.abs(i)}),this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:Math.sign(o),y:Math.sign(i)},travelDistance:xe(e,n)}),this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:Math.sign(o),y:0},travelDistance:Math.abs(o)}))}getProjectedFreeSpaceAlongDirection(t){const{sourcePoint:e,sourceLayer:n,sourceObstacle:o,direction:i,travelDistance:r}=t,s=Math.hypot(i.x,i.y);if(s\u003c=Wj||r\u003c=Wj)return 0;const a=this.getRayProbeDistance(),c=i.x/s,l=i.y/s,d={x:e.x+c*a,y:e.y+l*a};let h=Number.POSITIVE_INFINITY;for(const t of this.ogSrj.obstacles)if(t!==o\u0026\u0026t.layers.includes(n))for(const n of Cl(t)){const t=this.getRayIntersectionDistance({rayStart:e,rayEnd:d,segmentStart:n.start,segmentEnd:n.end});null!==t\u0026\u0026(h=Math.min(h,t))}for(const t of this.getBoardBoundarySegments()){const n=this.getRayIntersectionDistance({rayStart:e,rayEnd:d,segmentStart:t.start,segmentEnd:t.end});null!==n\u0026\u0026(h=Math.min(h,n))}return Number.isFinite(h)?Math.max(0,h-r):0}getMinBlockingClearance(t){const{candidate:e,connectionNetIds:n,sourceZ:o,targetZ:i}=t,r=Math.min(o,i),s=Math.max(o,i);let a=Number.POSITIVE_INFINITY;for(const t of this.ogSrj.obstacles){const n=this.getObstacleZs(t);if(!n.some(t=\u003et\u003e=r\u0026\u0026t\u003c=s))continue;if(t.isCopperPour\u0026\u0026!n.includes(o))continue;const i=Be(e,t)-this.viaRadius;if(a=Math.min(a,i),a+Wj\u003cthis.requiredViaToPadClearance)return a}return a}getMinPlacedEscapeViaClearance(t){let e=Number.POSITIVE_INFINITY;for(const n of this.createdEscapeVias){const o=xe(t,n)-this.viaDiameter;if(e=Math.min(e,o),e+Wj\u003cthis.obstacleMargin)return e}return e}selectPointOwner(t){const{point:e,groupConnections:n,matchingCopperPours:o}=t,i=ua(e),r=n.map(t=\u003e({connection:t,pointIndex:t.pointsToConnect.findIndex(t=\u003eua(t)===i)})).filter(t=\u003e-1!==t.pointIndex);return 0===r.length?null:(r.sort((t,e)=\u003e{const n=o.some(e=\u003ethis.obstacleMatchesConnectionNet(e,this.getConnectionNetIds(t.connection)));return n!==o.some(t=\u003ethis.obstacleMatchesConnectionNet(t,this.getConnectionNetIds(e.connection)))?n?-1:1:t.pointIndex-e.pointIndex}),r[0])}findBestEscapeViaCandidate(t){const{connection:e,point:n,pointIndex:o,matchingCopperPours:i,connectionNetIds:r,sourceObstacle:s}=t;if(!_o(n))return null;const a=n.layer,c=ko(a,this.ogSrj.layerCount),l=s??this.selectSourceObstacle({point:n,sourceLayer:a,connectionNetIds:r}),d=this.getCandidatePositions(n,l);let h=null;for(const t of i){const i=t.layers[0];if(!i||i===a)continue;const s=ko(i,this.ogSrj.layerCount),u=Hj(t);for(const p of d){if(!this.isInsideBoard(p))continue;if(!Xj(p,t))continue;if(!this.hasClearEscapePath({sourcePoint:n,candidate:p,sourceLayer:a,sourceObstacle:l}))continue;const d=this.getMinBlockingClearance({candidate:p,connectionNetIds:r,sourceZ:c,targetZ:s});if(d+Wj\u003cthis.requiredViaToPadClearance)continue;const m=this.getMinPlacedEscapeViaClearance(p);if(m+Wj\u003cthis.obstacleMargin)continue;const g=this.getProjectedFreeSpace({sourcePoint:n,candidate:p,sourceLayer:a,sourceObstacle:l}),f=Math.min(g,3),y=100*d-xe(n,p)-.5*Math.abs(s-c)+2*f+(Number.isFinite(m)?10*Math.min(m,this.requiredViaToViaClearance):0);(!h||y\u003eh.score)\u0026\u0026(h={pointId:`${Vj}${e.name}:${n.pointId??`p${o}`}:${i}:${this.nextEscapeViaIndex++}`,x:p.x,y:p.y,connectionName:e.name,rootConnectionName:e.__rootConnectionNames?.[0]??e.name,sourcePointIndex:o,sourcePointId:n.pointId,sourceLayer:a,targetLayer:i,targetPourKey:u,score:y})}}return h}buildPointPlacementPlans(t){const{mergedConnection:e,groupConnections:n,matchingCopperPours:o,connectionNetIds:i}=t,r=[];for(const t of e.pointsToConnect){const e=this.selectPointOwner({point:t,groupConnections:n,matchingCopperPours:o});if(!e)continue;const s=_o(t)?this.selectSourceObstacle({point:t,sourceLayer:t.layer,connectionNetIds:i}):void 0,a=_o(t)?this.getCandidatePositions(t,s).length:0;r.push({point:t,pointOwner:e,sourceObstacle:s,candidateCount:a})}return r.sort((t,e)=\u003e{if(t.candidateCount!==e.candidateCount)return t.candidateCount-e.candidateCount;const n=(t.sourceObstacle?.width??0)*(t.sourceObstacle?.height??0),o=(e.sourceObstacle?.width??0)*(e.sourceObstacle?.height??0);return n!==o?n-o:t.pointOwner.pointIndex-e.pointOwner.pointIndex})}_step(){const t=this.ogSrj.obstacles.filter(t=\u003et.isCopperPour),e=this.ogSrj.connections,n=e.map(t=\u003estructuredClone(t)),o=new Map(n.map(t=\u003e[t.name,t])),i=structuredClone(this.ogSrj.obstacles),r=pa([...e]);for(const n of r){const r=new Set(n.__rootConnectionNames??[n.name]),s=e.filter(t=\u003e(t.__rootConnectionNames??[t.name]).some(t=\u003er.has(t)));if(0===s.length)continue;const a=new Set;for(const t of s)for(const e of this.getConnectionNetIds(t))a.add(e);const c=t.filter(t=\u003ethis.obstacleMatchesConnectionNet(t,a));if(0===c.length)continue;const l=new Map,d=new Map,h=this.buildPointPlacementPlans({mergedConnection:n,groupConnections:s,matchingCopperPours:c,connectionNetIds:a});for(const{point:t,pointOwner:e,sourceObstacle:n}of h){const r=this.findBestEscapeViaCandidate({connection:e.connection,point:t,pointIndex:e.pointIndex,matchingCopperPours:c,connectionNetIds:a,sourceObstacle:n});if(!r)continue;const s=o.get(e.connection.name);if(!s)continue;if(s.pointsToConnect.some(t=\u003e_o(t)\u0026\u0026t.layer===r.sourceLayer\u0026\u0026Gj(t,r)))continue;s.pointsToConnect.push({x:r.x,y:r.y,layer:r.sourceLayer,pointId:r.pointId,terminalVia:{toLayer:r.targetLayer,viaDiameter:this.viaDiameter}}),this.escapeViaMetadataByPointId.set(r.pointId,r),this.createdEscapeVias.push(r),i.push(this.createEscapeViaObstacle({escapeVia:r,connectionNetIds:this.getConnectionNetIds(e.connection)}));const h=l.get(r.targetPourKey);h?h.push(r.pointId):l.set(r.targetPourKey,[r.pointId]),d.has(r.targetPourKey)||d.set(r.targetPourKey,e.connection.name)}for(const[t,e]of l.entries()){if(e.length\u003c=1)continue;const n=d.get(t);if(!n)continue;const i=o.get(n);i\u0026\u0026(i.externallyConnectedPointIds=[...i.externallyConnectedPointIds??[],e])}}this.outputSrj={...structuredClone(this.ogSrj),connections:n,obstacles:i},this.solved=!0}getOutputSimpleRouteJson(){return structuredClone(this.outputSrj)}getEscapeViaMetadataByPointId(){return new Map(this.escapeViaMetadataByPointId)}visualize(){return{title:\"Escape Via Location Solver\",points:this.outputSrj.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({x:e.x,y:e.y,color:!0===e.pointId?.startsWith(Vj)?\"#0f766e\":\"#dc2626\",label:!0===e.pointId?.startsWith(Vj)?`${t.name}\\nescape via`:t.name}))),lines:this.createdEscapeVias.map(t=\u003e{const e=this.outputSrj.connections.find(e=\u003ee.name===t.connectionName)?.pointsToConnect[t.sourcePointIndex]??null;return{points:e?[{x:e.x,y:e.y},{x:t.x,y:t.y}]:[{x:t.x,y:t.y}],strokeColor:\"#0f766e\"}}),circles:this.createdEscapeVias.map(t=\u003e({center:{x:t.x,y:t.y},radius:this.viaRadius,strokeColor:\"#0f766e\",label:`${t.connectionName}\\n${t.targetLayer}`})),rects:this.outputSrj.obstacles.filter(t=\u003e!t.isCopperPour).map(t=\u003e({...t,fill:\"rgba(220,38,38,0.12)\"}))}}},Zj=t=\u003e({...t}),qj=t=\u003e({...t,route:t.route?.map(Zj),vias:t.vias?.map(t=\u003e({...t}))}),Jj=t=\u003et.map(qj),Kj=\"#0000FF\",Qj=.15,t$=1e-6,e$=.1,n$=[\"top\",\"bottom\",\"left\",\"right\"],o$=t=\u003et.x*t.x+t.y*t.y,i$=(t,e)=\u003e({x:t.x-e.x,y:t.y-e.y}),r$=(t,e,n)=\u003e{const o=i$(n,e),i=o$(o);if(i\u003c=t$)return Math.sqrt(o$(i$(t,e)));const r=(a=i$(t,e),c=o,s=(a.x*c.x+a.y*c.y)/i,Math.max(0,Math.min(1,s)));var s,a,c;const l={x:e.x+o.x*r,y:e.y+o.y*r};return Math.sqrt(o$(i$(t,l)))},s$=t=\u003e1===t?.z?\"bottom\":\"top\",a$=(t,e,n)=\u003e(t.z??0)===(e.z??0)\u0026\u0026((e.z??0)===(n.z??0)\u0026\u0026(t.x===e.x\u0026\u0026e.x===n.x||t.y===e.y\u0026\u0026e.y===n.y)),c$=(t,e,n)=\u003e{const o=n?.get(t);if(o)return o;const i=t.route??[],r=t.traceThickness??Qj;let s=Number.POSITIVE_INFINITY,a=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY,l=Number.NEGATIVE_INFINITY,d=!1;const h=(t,e,n)=\u003e{s=Math.min(s,t-n),a=Math.min(a,e-n),c=Math.max(c,t+n),l=Math.max(l,e+n),d=!0},u={segments:[],segmentsByLayer:{top:[],bottom:[]},vias:(t.vias??[]).map(n=\u003e{const o=(n.diameter??t.viaDiameter??.3)/2;return h(n.x,n.y,o),{center:{x:n.x,y:n.y},radius:o,routeIndex:e}}),bounds:{minX:0,minY:0,maxX:0,maxY:0}};for(let t=0;t\u003ci.length-1;){const n=i[t];let o=t+1,s=i[o];const a=r/2;for(n\u0026\u0026h(n.x,n.y,a),s\u0026\u0026h(s.x,s.y,a);o\u003ci.length-1;){const t=i[o],e=i[o+1];if(!n||!t||!e)break;if(s$(n)!==s$(t))break;if(s$(t)!==s$(e))break;if(!a$(n,t,e))break;o+=1,s=e,h(e.x,e.y,a)}if(!n||!s){t+=1;continue}const c=s$(n),l={start:n,end:s,routeIndex:e,pointIndex:t,endPointIndex:o,thickness:r,halfThickness:a,layer:c,minX:Math.min(n.x,s.x)-a,maxX:Math.max(n.x,s.x)+a,minY:Math.min(n.y,s.y)-a,maxY:Math.max(n.y,s.y)+a};u.segments.push(l),u.segmentsByLayer[c].push(l),t=o}if(!d)for(const t of i)h(t.x,t.y,r/2);return u.bounds=d?{minX:s,minY:a,maxX:c,maxY:l}:{minX:0,minY:0,maxX:0,maxY:0},n?.set(t,u),u},l$=(t,e,n)=\u003ee.x\u003c=Math.max(t.x,n.x)+t$\u0026\u0026e.x\u003e=Math.min(t.x,n.x)-t$\u0026\u0026e.y\u003c=Math.max(t.y,n.y)+t$\u0026\u0026e.y\u003e=Math.min(t.y,n.y)-t$,d$=(t,e,n)=\u003e(e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y),h$=(t,e,n,o)=\u003e((t,e,n,o)=\u003e{const i=d$(t,e,n),r=d$(t,e,o),s=d$(n,o,t),a=d$(n,o,e);return!!(Math.abs(i)\u003c=t$\u0026\u0026l$(t,n,e))||!!(Math.abs(r)\u003c=t$\u0026\u0026l$(t,o,e))||!!(Math.abs(s)\u003c=t$\u0026\u0026l$(n,t,o))||!!(Math.abs(a)\u003c=t$\u0026\u0026l$(n,e,o))||i\u003e0!=r\u003e0\u0026\u0026s\u003e0!=a\u003e0})(t,e,n,o)?0:Math.min(r$(t,n,o),r$(e,n,o),r$(n,t,e),r$(o,t,e)),u$=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=t$\u0026\u0026Math.abs(t.y-e.y)\u003c=t$,p$=(t,e)=\u003eu$(t.start,e.start)||u$(t.start,e.end)||u$(t.end,e.start)||u$(t.end,e.end),m$=t=\u003e{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))},g$=(t,e)=\u003e{const n=m$(t),o=m$(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))},f$=(t,e,n)=\u003et.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY,y$=(t,e,n)=\u003e{const o=n+t.halfThickness+e.halfThickness-t$;return t.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY\u0026\u0026o\u003e0},_$=(t,e,n,o)=\u003e{const i=o+n.halfThickness+e-t$,r=t.x-i,s=t.x+i,a=t.y-i,c=t.y+i;return r\u003c=n.maxX\u0026\u0026s\u003e=n.minX\u0026\u0026a\u003c=n.maxY\u0026\u0026c\u003e=n.minY},b$=(t,e)=\u003e{const n=new WeakMap,o=t.map((t,e)=\u003ec$(t,e,n)),i=[],r=new Set,s=t=\u003e{r.has(t.label)||(r.add(t.label),i.push(t))};for(let n=0;n\u003co.length;n+=1){const i=o[n];if(i)for(let r=n+1;r\u003co.length;r+=1){const a=o[r];if(a\u0026\u0026(!g$(t[n],t[r])\u0026\u0026f$(i.bounds,a.bounds,e))){for(const t of[\"top\",\"bottom\"]){const o=i.segmentsByLayer[t],c=a.segmentsByLayer[t];for(const i of o)for(const o of c){if(p$(i,o))continue;if(!y$(i,o,e))continue;const a=e+(i.thickness+o.thickness)/2-t$;if(h$(i.start,i.end,o.start,o.end)\u003e=a)continue;s({center:{x:(Math.max(i.minX-e,o.minX-e)+Math.min(i.maxX+e,o.maxX+e))/2,y:(Math.max(i.minY-e,o.minY-e)+Math.min(i.maxY+e,o.maxY+e))/2},label:`trace-violation:${n}:s${i.pointIndex}:${r}:s${o.pointIndex}:${t}`})}}for(const t of i.segments)for(const[o,i]of a.vias.entries()){if(!_$(i.center,i.radius,t,e))continue;const a=e+t.halfThickness+i.radius-t$;r$(i.center,t.start,t.end)\u003e=a||s({center:i.center,label:`trace-violation:${n}:s${t.pointIndex}:${r}:v${o}`})}for(const t of a.segments)for(const[o,a]of i.vias.entries()){if(!_$(a.center,a.radius,t,e))continue;const i=e+t.halfThickness+a.radius-t$;r$(a.center,t.start,t.end)\u003e=i||s({center:a.center,label:`trace-violation:${n}:v${o}:${r}:s${t.pointIndex}`})}}}}return(t=\u003e{const e=[];for(const n of t){const t=e.find(t=\u003e{return e=t.center,o=n.center,Math.hypot(e.x-o.x,e.y-o.y)\u003c=.28;var e,o});t?(t.center={x:(t.center.x*t.count+n.center.x)/(t.count+1),y:(t.center.y*t.count+n.center.y)/(t.count+1)},t.labels.push(n.label),t.count+=1):e.push({center:n.center,labels:[n.label],count:1})}return e.map((t,e)=\u003e({center:t.center,radius:Math.min(.3,.2+.035*Math.sqrt(t.count-1)),stroke:\"#f59e0b\",fill:\"rgba(245, 158, 11, 0.46)\",label:1===t.count?t.labels[0]:`trace-violations:${e}:count-${t.count}`}))})(i)},x$=({routeIndexes:t,layers:e,routePointIndexes:n})=\u003e`${t[0]}:${e[0]}:${n[0].join(\",\")}:${t[1]}:${e[1]}:${n[1].join(\",\")}`,v$=(t,e,n,o,i,r,s)=\u003e{const a=((t,e,n,o,i,r)=\u003et\u003cn?`${t}:${e}:${i.join(\",\")}:${n}:${o}:${r.join(\",\")}`:`${n}:${o}:${r.join(\",\")}:${t}:${e}:${i.join(\",\")}`)(e,n,o,i,r,s),c=t.get(a);if(c){const[t,n]=e\u003co?[r,s]:[s,r];for(const e of t)c.routePointIndexes[0].includes(e)||c.routePointIndexes[0].push(e);for(const t of n)c.routePointIndexes[1].includes(t)||c.routePointIndexes[1].push(t);return c.routePointIndexes[0].sort((t,e)=\u003et-e),void c.routePointIndexes[1].sort((t,e)=\u003et-e)}e\u003co?t.set(a,{routeIndexes:[e,o],layers:[n,i],routePointIndexes:[[...new Set(r)].sort((t,e)=\u003et-e),[...new Set(s)].sort((t,e)=\u003et-e)]}):t.set(a,{routeIndexes:[o,e],layers:[i,n],routePointIndexes:[[...new Set(s)].sort((t,e)=\u003et-e),[...new Set(r)].sort((t,e)=\u003et-e)]})},S$=t=\u003e{const e=[];for(let n=t.pointIndex;n\u003c=t.endPointIndex;n+=1)e.push(n);return e},I$=(t,e)=\u003e!e||t.some(t=\u003ee.has(t)),C$=(t,e)=\u003e{const n=t.route??[],o=[];for(let t=0;t\u003cn.length;t+=1){const i=n[t];i\u0026\u0026(Math.abs(i.x-e.center.x)\u003c=t$\u0026\u0026Math.abs(i.y-e.center.y)\u003c=t$\u0026\u0026o.push(t))}return o},P$=(t,e,n)=\u003et.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY,M$=(t,e,n)=\u003e{const o=n+t.halfThickness+e.halfThickness-t$;return t.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY\u0026\u0026o\u003e0},N$=(t,e,n,o)=\u003e{const i=o+n.halfThickness+e-t$,r=t.x-i,s=t.x+i,a=t.y-i,c=t.y+i;return r\u003c=n.maxX\u0026\u0026s\u003e=n.minX\u0026\u0026a\u003c=n.maxY\u0026\u0026c\u003e=n.minY},w$=(t,e,n)=\u003e{const o=n+t.radius+e.radius-t$;return Math.abs(t.center.x-e.center.x)\u003c=o\u0026\u0026Math.abs(t.center.y-e.center.y)\u003c=o},T$=(t,e,n,o,i)=\u003e{const r=t.map((t,e)=\u003ec$(t,e,o)),s=new Map;if(0===e.size)return[];const a=Array.from(e),c=new Map,l=t=\u003e{const e=c.get(t);if(e)return e;const o=r[t];if(!o)return[];const i=[];for(let e=0;e\u003cr.length;e+=1){if(e===t)continue;const s=r[e];s\u0026\u0026(P$(o.bounds,s.bounds,n)\u0026\u0026i.push(e))}return c.set(t,i),i};for(const t of a){const o=r[t];if(!o)continue;const a=l(t),c=i?.get(t);for(const l of o.segments){const o=S$(l);if(I$(o,c))for(const c of a){if(t\u003ec\u0026\u0026e.has(c))continue;const a=r[c];if(!a)continue;const d=i?.get(c),h=a.segmentsByLayer[l.layer];for(const t of h){const e=S$(t);if(!I$(e,d))continue;if(p$(l,t))continue;if(!M$(l,t,n))continue;const i=n+(l.thickness+t.thickness)/2-t$;h$(l.start,l.end,t.start,t.end)\u003ci\u0026\u0026v$(s,l.routeIndex,l.layer,t.routeIndex,t.layer,o,e)}}}}for(const o of a){const a=r[o];if(!a)continue;const c=l(o),d=i?.get(o);for(const l of a.vias){const a=C$(t[l.routeIndex],l);if(I$(a,d))for(const t of c){if(o\u003et\u0026\u0026e.has(t))continue;const c=r[t];if(!c)continue;const d=i?.get(t);for(const t of c.segments){const e=S$(t);if(!I$(e,d))continue;if(!N$(l.center,l.radius,t,n))continue;const o=n+t.thickness/2+l.radius-t$;r$(l.center,t.start,t.end)\u003co\u0026\u0026v$(s,t.routeIndex,t.layer,l.routeIndex,\"via\",e,a)}}}}for(const e of a){const o=r[e];if(!o)continue;const a=l(e),c=i?.get(e);for(const e of o.segments){const o=S$(e);if(I$(o,c))for(const c of a){const a=r[c];if(!a)continue;const l=i?.get(c);for(const i of a.vias){const r=C$(t[i.routeIndex],i);if(!I$(r,l))continue;if(!N$(i.center,i.radius,e,n))continue;const a=n+e.thickness/2+i.radius-t$;r$(i.center,e.start,e.end)\u003ca\u0026\u0026v$(s,e.routeIndex,e.layer,i.routeIndex,\"via\",o,r)}}}}for(const o of a){const a=r[o];if(!a)continue;const c=l(o),d=i?.get(o);for(const l of a.vias){const a=C$(t[l.routeIndex],l);if(I$(a,d))for(const d of c){if(o\u003ed\u0026\u0026e.has(d))continue;const c=r[d];if(!c)continue;const h=i?.get(d);for(const e of c.vias){const o=C$(t[e.routeIndex],e);if(!I$(o,h))continue;if(!w$(l,e,n))continue;const i=n+l.radius+e.radius-t$;Math.hypot(l.center.x-e.center.x,l.center.y-e.center.y)\u003ci\u0026\u0026v$(s,l.routeIndex,\"via\",e.routeIndex,\"via\",a,o)}}}}return Array.from(s.values())},R$=(t,e)=\u003et.x\u003e=e.minX-t$\u0026\u0026t.x\u003c=e.maxX+t$\u0026\u0026t.y\u003e=e.minY-t$\u0026\u0026t.y\u003c=e.maxY+t$,E$=(t,e,n)=\u003e{switch(e){case\"left\":return{minX:t.minX,maxX:t.minX+n,minY:t.minY,maxY:t.maxY};case\"right\":return{minX:t.maxX-n,maxX:t.maxX,minY:t.minY,maxY:t.maxY};case\"top\":return{minX:t.minX,maxX:t.maxX,minY:t.maxY-n,maxY:t.maxY};case\"bottom\":return{minX:t.minX,maxX:t.maxX,minY:t.minY,maxY:t.minY+n}}},A$=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;let r=0,s=1;const a=(t,e)=\u003e{if(Math.abs(t)\u003c=t$)return e\u003e=-1e-6;const n=e/t;return t\u003c0?!(n\u003es)\u0026\u0026(n\u003er\u0026\u0026(r=n),!0):!(n\u003cr)\u0026\u0026(n\u003cs\u0026\u0026(s=n),!0)};if(!(a(-o,t.x-n.minX)\u0026\u0026a(o,n.maxX-t.x)\u0026\u0026a(-i,t.y-n.minY)\u0026\u0026a(i,n.maxY-t.y)))return 0;const c=Math.hypot(o,i);return Math.max(0,s-r)*c},O$=(t,e)=\u003en$.filter(n=\u003e{switch(n){case\"left\":return Math.abs(t.x-e.minX)\u003c=t$;case\"right\":return Math.abs(t.x-e.maxX)\u003c=t$;case\"top\":return Math.abs(t.y-e.maxY)\u003c=t$;case\"bottom\":return Math.abs(t.y-e.minY)\u003c=t$}return!1}),k$=(t,e)=\u003e{const n=[];return t.x\u003ce.minX-t$\u0026\u0026n.push(\"left\"),t.x\u003ee.maxX+t$\u0026\u0026n.push(\"right\"),t.y\u003ee.maxY+t$\u0026\u0026n.push(\"top\"),t.y\u003ce.minY-t$\u0026\u0026n.push(\"bottom\"),n},L$=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;switch(n){case\"left\":case\"right\":return Math.abs(o)\u003c=t$\u0026\u0026Math.abs(i)\u003et$;case\"top\":case\"bottom\":return Math.abs(i)\u003c=t$\u0026\u0026Math.abs(o)\u003et$}},D$=(t,e,n)=\u003e{const o=[],i=Math.max(n,t$),r=Math.min(.1,i/4);for(let n=0;n\u003ct.length;n+=1){const s=t[n],a=s?.route??[];for(let t=0;t\u003ca.length-1;t+=1){const c=a[t],l=a[t+1];if(!c||!l)continue;const d=k$(c,e),h=k$(l,e),u=O$(c,e),p=O$(l,e),m=n$.filter(t=\u003e{if(s.connectedPadSides?.includes(t))return!1;return!(A$(c,l,E$(e,t,i))\u003c=r)\u0026\u0026!!L$(c,l,t)}),g=!R$(c,e)||!R$(l,e),f=Array.from(new Set([...m,...d,...h]));(g||0!==f.length)\u0026\u0026o.push({routeIndex:n,connectionName:s.connectionName??s.rootConnectionName??`route-${n}`,segmentIndex:t,touchedSides:f,startSides:u,endSides:p,start:c,end:l})}}return o},z$=t=\u003et?.center\u0026\u0026t.width\u0026\u0026t.height?{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,width:t.width,height:t.height,center:t.center}:null,F$=t=\u003e\"bottom\"===t?Kj:\"#FF0000\",B$=t=\u003e{const e=t.route??[],n=[];if(e.length\u003c2)return n;let o=s$(e[0]),i=[e[0]];for(let r=1;r\u003ce.length;r+=1){const s=e[r],a=s$(s);a===o?i.push(s):(i.length\u003e=2\u0026\u0026n.push({points:i,strokeColor:F$(o),strokeWidth:t.traceThickness??Qj,label:t.connectionName??\"route\"}),o=a,i=[e[r-1],s])}return i.length\u003e=2\u0026\u0026n.push({points:i,strokeColor:F$(o),strokeWidth:t.traceThickness??Qj,label:t.connectionName??\"route\"}),n},j$=(t,e)=\u003e({title:`HighDensityRepair02 Initial State (margin=${e})`,routes:t}),$=t=\u003e{const e=[];for(const n of t){const t=e[e.length-1];t\u0026\u0026t.z===n.z\u0026\u0026u$(t,n)||e.push(n)}return e},Y$=(t,e,n)=\u003e{const o=Math.max(0,t.minX-e.maxX,e.minX-t.maxX),i=Math.max(0,t.minY-e.maxY,e.minY-t.maxY);return Math.hypot(o,i)\u003c=n+t$},X$=(t,e)=\u003e{let n=Number.POSITIVE_INFINITY;for(const o of t.segments)for(const t of e.segments){if(o.layer!==t.layer)continue;const e=h$(o.start,o.end,t.start,t.end)-(o.thickness+t.thickness)/2;n=Math.min(n,e)}return n},V$=({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,maximumAllowedClearance:o})=\u003e{const i=new WeakMap,r=new WeakMap,s=[],a=Array.from(n).sort((t,e)=\u003et-e),c=t.map((t,e)=\u003ec$(t,e,i)),l=e.map((t,e)=\u003ec$(t,e,r)),d=new Set;for(const t of a)for(let n=0;n\u003ce.length;n+=1){if(n===t)continue;const e=Math.min(t,n),i=Math.max(t,n),r=`${e}:${i}`;if(d.has(r))continue;d.add(r);const a=l[e],h=l[i];if(!a||!h||!Y$(a.bounds,h.bounds,o))continue;const u=X$(a,h);if(!Number.isFinite(u)||u\u003eo+t$||!c[e]||!c[i])continue;const p=X$(c[e],c[i]);!Number.isFinite(p)||u\u003e=p-t$||s.push({routeIndexes:[e,i],previousClearance:p,nextClearance:u})}return s},W$=.001,H$=(t,e)=\u003et.map(t=\u003e{const n=t.route??[];return 0===n.length?t:{...t,route:n.map((t,o)=\u003e0===o||o===n.length-1?((t,e)=\u003e{const n={...t};return Math.abs(n.x-e.minX)\u003c=W$?n.x=e.minX:Math.abs(n.x-e.maxX)\u003c=W$\u0026\u0026(n.x=e.maxX),Math.abs(n.y-e.minY)\u003c=W$?n.y=e.minY:Math.abs(n.y-e.maxY)\u003c=W$\u0026\u0026(n.y=e.maxY),n})(t,e):t)}}),G$=(t,e)=\u003eArray.from(e).flatMap(e=\u003eB$(t[e]).map(t=\u003e({...t,strokeColor:\"#000000\",strokeWidth:t.strokeWidth,label:`candidate:${t.label}`}))),U$=(t,e,n,o,i)=\u003e{const r=\"rgba(0, 0, 0, 0)\";switch(e){case\"left\":return{center:{x:t.minX+n/2,y:t.center.y},width:n,height:t.height,stroke:r,fill:o,label:i};case\"right\":return{center:{x:t.maxX-n/2,y:t.center.y},width:n,height:t.height,stroke:r,fill:o,label:i};case\"top\":return{center:{x:t.center.x,y:t.maxY-n/2},width:t.width,height:n,stroke:r,fill:o,label:i};case\"bottom\":return{center:{x:t.center.x,y:t.minY+n/2},width:t.width,height:n,stroke:r,fill:o,label:i}}},Z$=({routes:t,candidateRoutes:e,candidateRouteIndexes:n,originalRoutes:o,boundary:i,side:r,margin:s,rejected:a,rejectionReason:c})=\u003e{const l=Array.from(n).map(t=\u003ee[t].connectionName??`route-${t}`);return{title:a?`${r} move rejected (${c})`:`${r} move accepted`,routes:a?t:e,originalRoutes:o,activeSide:r,candidateRouteNames:l,overlayLines:a?G$(e,n):[],overlayRects:[U$(i,r,s,a?\"rgba(220, 38, 38, 0.14)\":\"rgba(16, 185, 129, 0.14)\",a?`rejected:${r}`:`accepted:${r}`)]}},q$=(t,e,n,o)=\u003e{const i=(t?.adjacentObstacles??[]).some(t=\u003e((t,e,n,o)=\u003e{const i=(t=\u003et.center\u0026\u0026t.width\u0026\u0026t.height?{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}:null)(t);if(!i)return!1;switch(n){case\"left\":return i.maxX\u003e=e.minX-t$\u0026\u0026i.minX\u003c=e.minX+o+t$;case\"right\":return i.minX\u003c=e.maxX+t$\u0026\u0026i.maxX\u003e=e.maxX-o-t$;case\"top\":return i.minY\u003c=e.maxY+t$\u0026\u0026i.maxY\u003e=e.maxY-o-t$;case\"bottom\":return i.maxY\u003e=e.minY-t$\u0026\u0026i.minY\u003c=e.minY+o+t$}})(t,e,n,o));return{hasObstacle:i,moveAmount:i?o:o/2}},J$=({start:t,end:e,side:n,boundary:o,amount:i,targetAxisValue:r})=\u003e{const s=(({side:t,boundary:e,amount:n,targetAxisValue:o})=\u003e{const i=o??(()=\u003e{switch(t){case\"left\":return e.minX+n;case\"right\":return e.maxX-n;case\"top\":return e.maxY-n;case\"bottom\":return e.minY+n}})();switch(t){case\"left\":case\"right\":return Math.min(Math.max(i,e.minX),e.maxX);case\"top\":case\"bottom\":return Math.min(Math.max(i,e.minY),e.maxY)}})({side:n,boundary:o,amount:i,targetAxisValue:r});switch(n){case\"left\":case\"right\":return $([t,{x:s,y:t.y,z:t.z},{x:s,y:e.y,z:e.z},e]);case\"top\":case\"bottom\":return $([t,{x:t.x,y:s,z:t.z},{x:e.x,y:s,z:e.z},e])}},K$=(t,e,n,o,i,r,s,a=!1)=\u003e{const c=t.route??[];if(c.length\u003c2||0===e.length)return qj(t);const l=a?i:Math.max(i,r),d=((t,e)=\u003e{switch(t){case\"left\":return{x:e,y:0};case\"right\":return{x:-e,y:0};case\"top\":return{x:0,y:-e};case\"bottom\":return{x:0,y:e}}})(o,l);if(a||(t.vias?.length??0)\u003e0||c.length\u003e2){const n=qj(t),o=n.route??[];for(const t of e){const e=o[t];e\u0026\u0026(o[t]={...e,x:e.x+d.x,y:e.y+d.y})}for(const o of n.vias??[]){e.some(e=\u003e{const n=t.route?.[e];return!!n\u0026\u0026u$(n,o)})\u0026\u0026(o.x+=d.x,o.y+=d.y)}return n}const h=qj(t);if(2===c.length\u0026\u00262===e.length\u0026\u00260===e[0]\u0026\u00261===e[1]){const e=c[0],i=c[1];return qj({...t,route:J$({start:e,end:i,side:o,boundary:n,amount:l,targetAxisValue:s})})}return h},Q$=(t,e,n)=\u003e{switch(n){case\"left\":return t.x-e.minX;case\"right\":return e.maxX-t.x;case\"top\":return e.maxY-t.y;case\"bottom\":return t.y-e.minY}},tY=(t,e,n)=\u003e{const o=(t=\u003e{const e=t.route??[];if(0===e.length)return[];const n=[];for(let t=0;t\u003ce.length;t+=1){const o=e[t];if(!o)continue;0===t||t===e.length-1||n.push(o);const i=e[t+1];i\u0026\u0026n.push({x:(o.x+i.x)/2,y:(o.y+i.y)/2})}return n})(t);return 0===o.length?Number.POSITIVE_INFINITY:o.reduce((t,o)=\u003eMath.min(t,Q$(o,e,n)),Number.POSITIVE_INFINITY)},eY=(t,e,n=[])=\u003e{const o=t.route??[],i=[],r=new Set,s=0===e.length||e.includes(\"via\");if(2===o.length)return[0,1];const a=t=\u003e{if(t\u003c=0||t\u003e=o.length-1)return;if(r.has(t))return;const n=o[t];n\u0026\u0026(s||e.includes(s$(n)))\u0026\u0026(r.add(t),i.push(t))};if(n.length\u003e0)for(const t of n)a(t);else for(let t=1;t\u003co.length-1;t+=1)a(t);for(let t=0;t\u003ci.length;t+=1){const e=i[t],n=o[e];if(n)for(let t=1;t\u003co.length-1;t+=1){if(r.has(t))continue;const e=o[t];e\u0026\u0026(e.z!==n.z\u0026\u0026u$(e,n)\u0026\u0026(r.add(t),i.push(t)))}}return i.sort((t,e)=\u003et-e),i},nY=(t,e)=\u003eMath.max(0,...(t.route??[]).map(t=\u003eMath.max(e.minX-t.x,t.x-e.maxX,e.minY-t.y,t.y-e.maxY,0))),oY=(t,e,n,o)=\u003eQ$(t,e,n)\u003c=o+t$,iY=(t,e,n,o)=\u003e{const i=t.route??[],r=[],s=new Set;let a=1,c=i.length-2;for(;a\u003ci.length-1\u0026\u0026u$(i[a],i[0]);)a+=1;for(;c\u003e0\u0026\u0026u$(i[c],i[i.length-1]);)c-=1;for(let t=a;t\u003c=c;t+=1)oY(i[t],e,n,o)\u0026\u0026(s.add(t),r.push(t));for(let t=0;t\u003cr.length;t+=1){const e=i[r[t]];if(e)for(let t=a;t\u003c=c;t+=1){if(s.has(t))continue;const n=i[t];n\u0026\u0026(n.z!==e.z\u0026\u0026u$(n,e)\u0026\u0026(s.add(t),r.push(t)))}}return 0===r.length\u0026\u00262===i.length\u0026\u0026i.some(t=\u003eoY(t,e,n,o))?[0,1]:(r.sort((t,e)=\u003et-e),r)},rY=(t,e,n)=\u003e{const o=t.route??[],i=0===n?o[0]:o[o.length-1];return i?n$.filter(t=\u003eQ$(i,e,t)\u003c=t$):[]},sY=(t,e,n)=\u003e{const o=t.route??[],i=e.route??[];if(0===o.length||0===i.length)return!0;for(const e of[0,-1]){const o=rY(t,n,e);if(0===o.length)continue;const r=0===e?i[0]:i[i.length-1];if(!r)return!1;for(const t of o)if(Q$(r,n,t)\u003et$)return!1}return!0},aY=(t,e)=\u003eMath.hypot(e.x-t.x,e.y-t.y),cY=(t,e,n,o)=\u003e{const i=t.route??[];if(0===i.length)return\"none\";let r=!1;for(let t=0;t\u003ci.length;t+=1){const s=i[t];if(s\u0026\u0026oY(s,e,n,o)){if(0!==t\u0026\u0026t!==i.length-1)return\"interior\";r=!0}}for(let t=0;t\u003ci.length-1;t+=1){const r=i[t],s=i[t+1];if(r\u0026\u0026s\u0026\u0026(oY(r,e,n,o)\u0026\u0026oY(s,e,n,o)\u0026\u0026!(aY(r,s)\u003c=t$)))return\"interior\"}return r?\"endpoint\":\"none\"},lY=({currentRoutes:t,routeIndex:e,side:n,moveSide:o=n,boundary:i,margin:r,moveAmount:s,geometryCache:a})=\u003e{const c=t[e],l=2===(c.route?.length??0),d=iY(c,i,n,r);if(0===d.length)return null;const h=new Set,u=new Map,p=new Set,m=t.slice();let g=!1,f=\"overlap\";const y=new Set([e]),_=new Map([[e,new Set]]),b=new Map([[e,new Set]]),x=[e];let v=0,S=null,I=null,C=null,P=null;const M=t=\u003enew Set(t.map(t=\u003ex$(t))),N=()=\u003eS||(S=T$(t,h,r,a,u),S),w=()=\u003eC||(C=T$(t,h,0,a,u),C),T=()=\u003eP||(P=T$(m,h,0,a,u),P);for(;v\u003cx.length\u0026\u0026!g;){const c=x[v];if(v+=1,y.delete(c),h.has(c))continue;const l=m[c],d=Array.from(_.get(c)??[]),w=Array.from(b.get(c)??[]);_.delete(c),b.delete(c);const T=c===e?iY(l,i,n,r):eY(l,d,w);if(0===T.length){if(c===e)return null;g=!0,f=\"eventual-overlap\";break}const R=l.route??[],E=c===e?void 0:\"left\"===o||\"right\"===o?(R[T[0]]?.x??0)+(\"left\"===o?s:-s):(R[T[0]]?.y??0)+(\"top\"===o?-s:s);m[c]=K$(l,T,i,o,s,r,E,c!==e),h.add(c),u.set(c,new Set(T)),S=null,I=null,C=null,P=null,2===(l.route?.length??0)\u0026\u0026p.add(c);const A=nY(t[c],i);if(nY(m[c],i)\u003eA+1e-6){g=!0,f=\"boundary\";break}if(!sY(t[c],m[c],i)){g=!0,f=\"endpoint-boundary\";break}const O=T$(m,new Set([c]),r,a,new Map([[c,new Set(T)]]));for(const t of O){if(M(N()).has(x$(t)))continue;const[e,n]=t.routeIndexes,o=h.has(e),i=h.has(n);if(o\u0026\u0026i)continue;const r=o?n:e,s=o?t.layers[1]:t.layers[0],a=o?t.routePointIndexes[1]:t.routePointIndexes[0];if(h.has(r)||y.has(r)){if(y.has(r)){const t=_.get(r)??new Set;t.add(s),_.set(r,t);const e=b.get(r)??new Set;for(const t of a)e.add(t);b.set(r,e)}}else y.add(r),x.push(r),_.set(r,new Set([s])),b.set(r,new Set(a))}}if(!g\u0026\u0026h.size\u003e1){const t=M(N()),e=M(I||(I=T$(m,h,r,a,u),I));for(const n of e)if(!t.has(n)){g=!0,f=\"eventual-overlap\";break}}if(!g\u0026\u0026h.size\u003e1){const t=M(w()),e=M(T());for(const n of e)if(!t.has(n)){g=!0,f=\"eventual-overlap\";break}}if(!g){const e=new Set(T$(t,h,0,a).map(t=\u003ex$(t))),n=T$(m,h,0,a);for(const t of n){const n=x$(t);if(!e.has(n)){g=!0,f=\"eventual-overlap\";break}}}if(!g){const e=(({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,boundary:o,activeSide:i})=\u003e{const r=n$.filter(t=\u003et!==i),s=[];for(const i of n){const n=t[i],a=e[i];if(n\u0026\u0026a)for(const t of r){const e=tY(n,o,t),r=tY(a,o,t);e\u003et$\u0026\u0026r\u003c=t$\u0026\u0026s.push({routeIndex:i,side:t,previousClearance:e,nextClearance:r})}}return s})({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,boundary:i,activeSide:n});e.length\u003e0\u0026\u0026(g=!0,f=\"boundary-touch\")}if(!g){const e=(({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,geometryCache:o,currentConflicts:i,candidateConflicts:r})=\u003e{const s=i??T$(t,n,0,o),a=r??T$(e,n,0,o),c=new Set(s.map(t=\u003ex$(t)));return a.filter(t=\u003e{const o=x$(t);if(c.has(o))return!1;const[i,r]=t.routeIndexes,[s,a]=t.layers,l=n.has(i),d=n.has(r);if(l\u0026\u0026d)return!1;const h=l?a:s,u=e[l?r:i];return!!u\u0026\u00260===eY(u,[h]).length})})({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,geometryCache:a,currentConflicts:w(),candidateConflicts:T()});e.length\u003e0\u0026\u0026(g=!0,f=\"fixed-trace-touch\")}if(!g){V$({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,maximumAllowedClearance:Math.min(r/2,e$)}).length\u003e0\u0026\u0026(g=!0,f=\"trace-clearance\")}return!g\u0026\u0026((t,e,n,o,i,r)=\u003eArray.from(n).some(n=\u003e{const s=t[n],a=e[n];return n$.filter(t=\u003et!==i).some(t=\u003e{const e=cY(s,o,t,r),n=cY(a,o,t,r);return\"none\"===e\u0026\u0026\"none\"!==n})}))(t,m,h,i,n,r)\u0026\u0026(g=!0,f=\"side-regression\"),{isTwoPointRoute:l,movableIndexes:d,candidateRouteIndexes:h,movedTwoPointRouteIndexes:p,candidateRoutes:m,rejected:g,rejectionReason:f}},dY=(t,e,n,o,i)=\u003e{const r=t.route??[];if(0===e.length)return null;if(\"top\"===o||\"bottom\"===o){const t=e.reduce((t,e)=\u003et+(r[e]?.x??n.center.x),0)/e.length;return t\u003cn.center.x-i/2?\"right\":t\u003en.center.x+i/2?\"left\":null}const s=e.reduce((t,e)=\u003et+(r[e]?.y??n.center.y),0)/e.length;return s\u003en.center.y+i/2?\"bottom\":s\u003cn.center.y-i/2?\"top\":null},hY=({side:t,sample:e,boundary:n,margin:o,repairedRoutes:i,frames:r,captureProgressFrames:s,lockedTwoPointRoutes:a,geometryCache:c,allowTwoPointWithoutObstacle:l=!1})=\u003e{const{hasObstacle:d,moveAmount:h}=q$(e,n,t,o);s\u0026\u0026r.push(((t,e,n,o,i,r)=\u003e({title:`${n} boundary analysis: move=${i.toFixed(3)} (${r?\"obstacle-side\":\"clear-side\"})`,routes:t,activeSide:n,overlayRects:[U$(e,n,o,\"rgba(245, 158, 11, 0.16)\",`strip:${n}`)]}))(Jj(i),n,t,o,h,d));const u=new Set;let p=0;for(let e=0;e\u003ci.length;e+=1){if(u.has(e))continue;if(a.has(e))continue;const m=i[e];if(m.connectedPadSides?.includes(t))continue;if(2===(m.route?.length??0)\u0026\u0026!d\u0026\u0026!l)continue;let g=lY({currentRoutes:i,routeIndex:e,side:t,boundary:n,margin:o,moveAmount:h,geometryCache:c});if(g){if(g.rejected){const r=dY(m,g.movableIndexes,n,t,o);if(r){const s=lY({currentRoutes:i,routeIndex:e,side:t,moveSide:r,boundary:n,margin:o,moveAmount:h,geometryCache:c});s\u0026\u0026!s.rejected\u0026\u0026(g=s)}}if(s\u0026\u0026r.push(Z$({routes:Jj(i),candidateRoutes:g.candidateRoutes,candidateRouteIndexes:g.candidateRouteIndexes,originalRoutes:g.rejected?void 0:Array.from(g.candidateRouteIndexes).map(t=\u003eqj(i[t])),boundary:n,side:t,margin:o,rejected:g.rejected,rejectionReason:g.rejectionReason})),!g.rejected){i.splice(0,i.length,...g.candidateRoutes);for(const t of g.movedTwoPointRouteIndexes)a.add(t);p+=1}u.add(e)}}return{movesAccepted:p}},uY=(t,e,n,o)=\u003eoY(t,e,n,o),pY=(t,e,n,o)=\u003e{switch(n){case\"left\":return{...t,x:Math.min(e.minX+o,e.maxX)};case\"right\":return{...t,x:Math.max(e.maxX-o,e.minX)};case\"top\":return{...t,y:Math.max(e.maxY-o,e.minY)};case\"bottom\":return{...t,y:Math.min(e.minY+o,e.maxY)}}},mY=t=\u003e`${t.routeIndexes[0]}:${t.layers[0]}:${t.routeIndexes[1]}:${t.layers[1]}`,gY=t=\u003e{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))},fY=(t,e)=\u003e{const n=gY(t),o=gY(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))},yY=(t,e,n)=\u003et?D$([t],e,n).length:0,_Y=(t,e,n,o)=\u003e{const i=new Set(T$(t,new Set([n]),o).map(x$));return T$(e,new Set([n]),o).some(t=\u003e!i.has(x$(t)))},bY=(t,e,n)=\u003eD$(t,e,n).length,xY=t=\u003e{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))},vY=(t,e)=\u003eT$(t,new Set(t.map((t,e)=\u003ee)),e$,e).filter(e=\u003e!(\"via\"===e.layers[0]\u0026\u0026\"via\"===e.layers[1]||((t,e)=\u003e{const n=xY(t),o=xY(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))})(t[e.routeIndexes[0]],t[e.routeIndexes[1]]))).length,SY=t=\u003e{const e=n$;return[...e.slice(t%e.length),...e.slice(0,t%e.length)]},IY=(t,e,n=!1)=\u003e{const o=z$(t?.nodeWithPortPoints),i=o?((t,e)=\u003et.map(t=\u003e{const n=t.route??[];let o=!1;const i=n.map(t=\u003e{let n=t.x,i=t.y;return n\u003ce.minX?n=e.minX:n\u003ee.maxX\u0026\u0026(n=e.maxX),i\u003ce.minY?i=e.minY:i\u003ee.maxY\u0026\u0026(i=e.maxY),n===t.x\u0026\u0026i===t.y?t:(o=!0,{...t,x:n,y:i})});return o?{...t,route:i}:t}))(H$(Jj(t?.nodeHdRoutes??[]),o),o):Jj(t?.nodeHdRoutes??[]),r=Math.max(e??.4,.05),s=Jj(i);if(!o)return{boundary:null,baseRoutes:i,repairedRoutes:s,margin:r,frames:[{title:\"HighDensityRepair02 Missing Boundary\",routes:s}]};const a=n?[j$(Jj(s),r)]:[],c=new WeakMap;let l=bY(s,o,r);for(let e=0;e\u003c1;e+=1){const i=new Set;let d=0;for(const l of SY(e)){const{movesAccepted:h}=hY({side:l,sample:t,boundary:o,frames:a,margin:r,repairedRoutes:s,captureProgressFrames:n,lockedTwoPointRoutes:i,geometryCache:c,allowTwoPointWithoutObstacle:e\u003e=1});d+=h}const h=bY(s,o,r);if(0===d)break;if(0===h)break;if(h\u003e=l)break;l=h}const d=Jj(s),h=vY(s,c);(({routes:t,boundary:e,margin:n,geometryCache:o})=\u003e{const i=D$(t,e,n);if(0===i.length)return{movesAccepted:0};const r=new Map;for(const t of i){const e=r.get(t.routeIndex)??new Set;for(const n of t.touchedSides)e.add(n);r.set(t.routeIndex,e)}const s=[8e-6,.01,n/4,n/2,n+8e-6];let a=0;const c=(i,r,s)=\u003e{const a=r.route??[];if(a.length\u003c2)return!1;const c={...r,route:$(a)};if((c.route?.length??0)\u003c2)return!1;const l=t.slice();if(l[i]=c,yY(l[i],e,n)\u003e=s)return!1;const d=e=\u003efY(t[e.routeIndexes[0]],t[e.routeIndexes[1]]),h=new Set(T$(t,new Set([i]),0,o).filter(t=\u003e!d(t)).map(mY));return!T$(l,new Set([i]),0,o).filter(t=\u003e!d(t)).some(t=\u003e!h.has(mY(t)))\u0026\u0026!(V$({currentRoutes:t,candidateRoutes:l,candidateRouteIndexes:new Set([i]),maximumAllowedClearance:Math.min(n/2,e$)}).filter(e=\u003e!fY(t[e.routeIndexes[0]],t[e.routeIndexes[1]])).length\u003e0||(t[i]=c,0))},l=(n,o,i,r)=\u003e{if(0===o.length)return!1;for(const a of s){const s=t[n],l=qj(s),d=l.route??[];let h=!1;for(const t of o){const n=d[t];n\u0026\u0026(d[t]=pY(n,e,i,a),h=!0)}if(!h)return!1;if(c(n,l,r))return!0}return!1},d=(t,n)=\u003e{const o=[];return\"top\"===n||\"bottom\"===n?(Math.abs(t.x-e.minX)\u003c=t$\u0026\u0026o.push(\"left\"),Math.abs(t.x-e.maxX)\u003c=t$\u0026\u0026o.push(\"right\")):(Math.abs(t.y-e.minY)\u003c=t$\u0026\u0026o.push(\"bottom\"),Math.abs(t.y-e.maxY)\u003c=t$\u0026\u0026o.push(\"top\")),o},h=(o,i,r)=\u003e{const a=t[o],l=a.route??[];if(2!==l.length)return!1;const[h,u]=l;if(!uY(h,e,i,n))return!1;if(!uY(u,e,i,n))return!1;const p=d(h,i),m=d(u,i);for(const t of s){let n=pY(h,e,i,t),s=pY(u,e,i,t);for(const o of p)n=pY(n,e,o,t);for(const n of m)s=pY(s,e,n,t);const l={...a,route:[h,n,s,u]};if(c(o,l,r))return!0}return!1};for(const[o,i]of r)if(t[o])for(const r of i){let i=!0;for(;i;){i=!1;const s=t[o].route??[];if(2===s.length){const i=yY(t[o],e,n);i\u003e0\u0026\u0026h(o,r,i)\u0026\u0026(a+=1);break}if(s.length\u003c3)break;const c=yY(t[o],e,n);if(0===c)break;const d=[];for(let t=1;t\u003cs.length-1;t+=1){const o=s[t];o\u0026\u0026uY(o,e,r,n)\u0026\u0026d.push(t)}if(0===d.length)break;if(l(o,d,r,c)){a+=1,i=!0;continue}let u=!1,p=c,m=0;for(;m\u003cd.length;){let i=m;for(;i+1\u003cd.length\u0026\u0026d[i+1]===d[i]+1;)i+=1;l(o,d.slice(m,i+1),r,p)\u0026\u0026(a+=1,u=!0,p=yY(t[o],e,n)),m=i+1}if(!u){const i=t[o].route??[];let s=c;for(let c=1;c\u003ci.length-1;c+=1){const d=i[c];d\u0026\u0026uY(d,e,r,n)\u0026\u0026l(o,[c],r,s)\u0026\u0026(a+=1,u=!0,s=yY(t[o],e,n))}}u\u0026\u0026(i=!0)}}for(const[o,i]of r){const r=t[o];if(!r)continue;const s=r.route??[];if(s.length\u003c=2)continue;const c=yY(t[o],e,n);if(0!==c)for(const l of i){if(!s.every(t=\u003euY(t,e,l,n)))continue;const i=s[0]?.z;if(!s.every(t=\u003et.z===i))continue;const d={...r,route:[s[0],s[s.length-1]]},u=t[o];t[o]=d,h(o,l,c)?a+=1:t[o]=u;break}}})({routes:d,boundary:o,margin:r,geometryCache:c});return vY(d,c)\u003c=h\u0026\u0026s.splice(0,s.length,...d),(({routes:t,boundary:e,clearanceMargin:n})=\u003e{for(let o=0;o\u003ct.length;o+=1){const i=t[o];if((i.route??[]).length\u003c=2)continue;const r=n,s=Math.max(e.width/2-t$,0),a=Math.max(e.height/2-t$,0),c=Math.min(r,s),l=Math.min(r,a),d=i.connectedPadSides??[],h=e.minX+(d.includes(\"left\")?0:c),u=e.maxX-(d.includes(\"right\")?0:c),p=e.minY+(d.includes(\"bottom\")?0:l),m=e.maxY-(d.includes(\"top\")?0:l),g=qj(i),f=g.route??[];let y=!1;for(let t=1;t\u003cf.length-1;t+=1){const e=f[t];if(!e)continue;const n=Math.min(Math.max(e.x,h),u),o=Math.min(Math.max(e.y,p),m);(Math.abs(n-e.x)\u003et$||Math.abs(o-e.y)\u003et$)\u0026\u0026(e.x=n,e.y=o,y=!0)}if(!y)continue;if(g.route=$(f),(g.route?.length??0)\u003c2)continue;const _=Jj(t);_[o]=g;const b=_Y(t,_,o,0),x=_Y(t,_,o,n),v=V$({currentRoutes:t,candidateRoutes:_,candidateRouteIndexes:new Set([o]),maximumAllowedClearance:n}).length\u003e0;b||x||v||(t[o]=g)}})({routes:s,boundary:o,clearanceMargin:r}),a.push(((t,e,n)=\u003e({title:`HighDensityRepair02 Final State (margin=${n})`,routes:t,originalRoutes:e}))(Jj(s),Jj(i),r)),{boundary:o,baseRoutes:i,repairedRoutes:s,frames:a,margin:r}},CY=class extends kt{constructor(t={}){super(),this.params=t,this.showBoundryViolationMarkers=t.showBoundryViolationMarkers??!1}params;frames=[];currentFrameIndex=0;showBoundryViolationMarkers;repairedRoutes=[];_setup(){this.buildFrames();const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();this.stats={boundryViolationCount:t,traceViolationCount:e,margin:this.params.margin??.4,frames:this.frames.length,currentFrame:this.currentFrameIndex}}_step(){if(this.frames.length\u003c=1){const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();return this.showBoundryViolationMarkers=!0,this.stats={...this.stats,boundryViolationCount:t,traceViolationCount:e},void(this.solved=!0)}this.currentFrameIndex\u003cthis.frames.length-1\u0026\u0026(this.currentFrameIndex+=1);const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();this.stats={boundryViolationCount:t,traceViolationCount:e,margin:this.params.margin??.4,frames:this.frames.length,currentFrame:this.currentFrameIndex,title:this.frames[this.currentFrameIndex]?.title},this.currentFrameIndex\u003e=this.frames.length-1\u0026\u0026(this.showBoundryViolationMarkers=!0,this.solved=!0)}getConstructorParams(){return[this.params]}getOutput(){const t=this.getCurrentTraceViolationCount();return{margin:this.params.margin??.4,repairedRoutes:this.repairedRoutes,frameCount:this.frames.length,traceViolationCount:t}}setShowBoundryViolationMarkers(t){this.showBoundryViolationMarkers=t}buildFrames(){const t=IY(this.params.sample,this.params.margin,this.params.captureProgressFrames??!1);this.frames=t.frames,this.repairedRoutes=t.repairedRoutes}getCurrentFrame(){const t=this.params.sample;return this.frames[this.currentFrameIndex]??{title:\"HighDensityRepair02\",routes:Jj(t?.nodeHdRoutes??[])}}getBoundryViolationsForFrame(t){const e=z$(this.params.sample?.nodeWithPortPoints);return e?D$(t.routes,e,this.params.margin??.4):[]}getCurrentBoundryViolationCount(){return this.getBoundryViolationsForFrame(this.getCurrentFrame()).length}getRouteNetNames(t){if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))}areRoutesSameNet(t,e){const n=this.getRouteNetNames(t),o=this.getRouteNetNames(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))}getCurrentTraceViolationCount(){const t=this.getCurrentFrame().routes,e=new Set(t.map((t,e)=\u003ee));return T$(t,e,e$).filter(e=\u003e!(\"via\"===e.layers[0]\u0026\u0026\"via\"===e.layers[1]||this.areRoutesSameNet(t[e.routeIndexes[0]],t[e.routeIndexes[1]]))).length}visualize(){const t=this.params.sample,e=t?.nodeWithPortPoints,n=t?.adjacentObstacles??[],o=this.getCurrentFrame(),i=z$(e),r=i\u0026\u0026e?.capacityMeshNodeId?[{center:i.center,width:i.width,height:i.height,stroke:\"#1d4ed8\",fill:\"rgba(29, 78, 216, 0.08)\",label:e.capacityMeshNodeId}]:i?[{center:i.center,width:i.width,height:i.height,stroke:\"#1d4ed8\",fill:\"rgba(29, 78, 216, 0.08)\",label:\"capacity-node\"}]:[],s=n.filter(t=\u003et.center\u0026\u0026t.width\u0026\u0026t.height).map((t,e)=\u003e({center:t.center,width:t.width,height:t.height,stroke:\"oval\"===t.type?\"#a855f7\":\"#dc2626\",fill:\"oval\"===t.type?\"rgba(168, 85, 247, 0.12)\":\"rgba(220, 38, 38, 0.08)\",label:t.type?`obstacle:${t.type}:${e}`:`obstacle:${e}`})),a=this.showBoundryViolationMarkers\u0026\u0026i?this.getBoundryViolationsForFrame(o).map(t=\u003e{const e=t.end.x-t.start.x,n=t.end.y-t.start.y,o=Math.max(Math.hypot(e,n),.2),i=Math.abs(e)\u003e=Math.abs(n);return{center:{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2},width:i?o:.18,height:i?.18:o,stroke:\"#b45309\",fill:\"rgba(250, 204, 21, 0.45)\",label:`boundry-violation:${t.routeIndex}:${t.segmentIndex}`}}):[];const c=this.showBoundryViolationMarkers?b$(o.routes,e$):[],l=[...(e?.portPoints??[]).map(t=\u003e({x:t.x,y:t.y,color:\"#0f766e\",label:t.connectionName??t.portPointId??\"port-point\"})),...o.routes.flatMap(t=\u003et.route??[]).map(t=\u003e({x:t.x,y:t.y,color:\"bottom\"===s$(t)?Kj:\"#0ea5e9\",label:\"\"})),...o.overlayPoints??[]],d=[...(o.originalRoutes??[]).flatMap(t=\u003eB$(t).map(t=\u003e({...t,strokeColor:\"#111111\",strokeWidth:Math.max(.6*t.strokeWidth,.05),label:`original:${t.label}`}))),...o.routes.filter(t=\u003e(t.route?.length??0)\u003e=2).flatMap(t=\u003eB$(t)),...o.overlayLines??[]],h=o.routes.flatMap(t=\u003e(t.vias??[]).map(e=\u003e({center:{x:e.x,y:e.y},radius:(e.diameter??t.viaDiameter??.3)/2,stroke:\"#7c3aed\",fill:\"rgba(124, 58, 237, 0.2)\",label:t.connectionName?`via:${t.connectionName}`:\"via\"})));return h.push(...c),{coordinateSystem:\"cartesian\",title:o.title,rects:[...r,...s,...o.overlayRects??[],...a],points:l,lines:d,circles:h,arrows:o.overlayArrows}}},PY=(t,e,n,o)=\u003e{const i=.001,r=new Set;for(const s of[e.route[0],e.route.at(-1)]){if(!s)continue;n.some(t=\u003et.__zLayers.includes(s.z)\u0026\u0026fo(t,e,o)\u0026\u0026Math.abs(s.x-t.center.x)\u003c=t.width/2+i\u0026\u0026Math.abs(s.y-t.center.y)\u003c=t.height/2+i)\u0026\u0026(Math.abs(s.x-(t.center.x-t.width/2))\u003c=i\u0026\u0026r.add(\"left\"),Math.abs(s.x-(t.center.x+t.width/2))\u003c=i\u0026\u0026r.add(\"right\"),Math.abs(s.y-(t.center.y-t.height/2))\u003c=i\u0026\u0026r.add(\"bottom\"),Math.abs(s.y-(t.center.y+t.height/2))\u003c=i\u0026\u0026r.add(\"top\"))}return[...r]},MY=(t,e=0)=\u003e({minX:t.center.x-t.width/2-e,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2-e,maxY:t.center.y+t.height/2+e}),NY=(t,e,n=0)=\u003e{const o=MY(e,n);return t.x\u003e=o.minX\u0026\u0026t.x\u003c=o.maxX\u0026\u0026t.y\u003e=o.minY\u0026\u0026t.y\u003c=o.maxY},wY=(t,e,n)=\u003et.route.length\u003e0\u0026\u0026e.some(e=\u003e(t=\u003e(t.__zLayers?.length??t.layers?.length??0)\u003e1)(e)\u0026\u0026fo(e,t,n)\u0026\u0026t.route.every(t=\u003e((t,e)=\u003e{const n=e.width/2,o=e.height/2;return Math.abs(t.x-e.center.x)\u003c=n\u0026\u0026Math.abs(t.y-e.center.y)\u003c=o})(t,e))),TY=(t,e,n)=\u003e{if(t.regionId){const n=e.findIndex(e=\u003ee.capacityMeshNodeId===t.regionId);if(-1!==n)return n}const o=[...t.route.map(({x:t,y:e})=\u003e({x:t,y:e})),...t.vias.map(({x:t,y:e})=\u003e({x:t,y:e}))];for(let t=0;t\u003ce.length;t++){const i=e[t];if(o.every(t=\u003eNY(t,i,n)))return t}return-1},RY=(t,e)=\u003e({connectionName:t.connectionName??e.connectionName,rootConnectionName:t.rootConnectionName??e.rootConnectionName,...e.startPcbPortId?{startPcbPortId:e.startPcbPortId}:{},...e.endPcbPortId?{endPcbPortId:e.endPcbPortId}:{},regionId:t.capacityMeshNodeId??e.regionId,traceThickness:t.traceThickness??e.traceThickness,viaDiameter:t.viaDiameter??e.viaDiameter,route:t.route?.map(t=\u003e({x:t.x,y:t.y,z:t.z??0}))??e.route,vias:t.vias?.map(t=\u003e({x:t.x,y:t.y}))??e.vias,jumpers:e.jumpers}),EY=(t,e,n,o,i)=\u003e{const r=MY(t,n);return e.search(r).filter(t=\u003e{return e=r,n=(t=\u003e({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}))(t),e.minX\u003c=n.maxX\u0026\u0026e.maxX\u003e=n.minX\u0026\u0026e.minY\u003c=n.maxY\u0026\u0026e.maxY\u003e=n.minY;var e,n}).filter(t=\u003e!i||!o.some(e=\u003efo(t,e,i))).map(t=\u003e({type:t.type,center:t.center,width:t.width,height:t.height}))},AY=class extends si{repairMargin;sampleEntries;originalHdRoutes;originalNodeWithPortPoints;originalObstacles;obstacleSHI;colorMap;connMap;repairedRoutesByIndex=new Map;activeSampleIndex=0;activeSubSolver=null;latestVisualization={};constructor(t){super(),this.repairMargin=t.repairMargin??.2,this.originalHdRoutes=t.hdRoutes,this.originalNodeWithPortPoints=t.nodeWithPortPoints,this.originalObstacles=t.obstacles,this.obstacleSHI=new Na(\"flatbush\",this.originalObstacles),this.colorMap=t.colorMap??{},this.connMap=t.connMap;const e=new Map;for(let n=0;n\u003ct.hdRoutes.length;n++){if(wY(t.hdRoutes[n],t.obstacles,t.connMap))continue;const o=TY(t.hdRoutes[n],t.nodeWithPortPoints,this.repairMargin);if(-1===o)continue;const i=e.get(o)??[];i.push(n),e.set(o,i)}const n=Kr(t.obstacles,Math.max(2,...t.nodeWithPortPoints.flatMap(t=\u003et.availableZ?.map(t=\u003et+1)??[]))),o=Array.from(e.entries()).map(([e,o])=\u003e{const i=t.nodeWithPortPoints[e];return{node:i,routeIndexes:o,sample:{nodeWithPortPoints:{capacityMeshNodeId:i.capacityMeshNodeId,center:i.center,width:i.width,height:i.height,portPoints:i.portPoints.map(t=\u003e({x:t.x,y:t.y,z:t.z,connectionName:t.connectionName,portPointId:t.portPointId,prevPortPointId:t.prevPortPointId,nextPortPointId:t.nextPortPointId}))},nodeHdRoutes:o.map(e=\u003e{return{...(o=t.hdRoutes[e],{capacityMeshNodeId:o.regionId,connectionName:o.connectionName,rootConnectionName:o.rootConnectionName,route:o.route.map(t=\u003e({x:t.x,y:t.y,z:t.z})),traceThickness:o.traceThickness,vias:o.vias.map(t=\u003e({x:t.x,y:t.y,diameter:o.viaDiameter})),viaDiameter:o.viaDiameter}),...t.connMap?{connectedPadSides:PY(i,t.hdRoutes[e],n,t.connMap)}:{}};var o}),adjacentObstacles:EY(i,this.obstacleSHI,this.repairMargin,o.map(e=\u003et.hdRoutes[e]),t.connMap)}}});this.sampleEntries=void 0!==t.maxSampleEntries\u0026\u0026o.length\u003et.maxSampleEntries?[]:o,this.MAX_ITERATIONS=Math.max(1e3*this.sampleEntries.length,1e5),this.stats={sampleCount:this.sampleEntries.length,skippedSampleCount:o.length\u003ethis.sampleEntries.length?o.length:0,repairedNodeCount:0,repairedRouteCount:0}}getSolverName(){return\"Pipeline4HighDensityRepairSolver\"}getConstructorParams(){return[{nodeWithPortPoints:this.sampleEntries.map(t=\u003et.node),hdRoutes:this.originalHdRoutes,obstacles:this.originalObstacles,repairMargin:this.repairMargin,colorMap:this.colorMap,connMap:this.connMap}]}_step(){const t=this.sampleEntries[this.activeSampleIndex];if(t){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.latestVisualization=this.activeSubSolver.visualize(),this.activeSubSolver.failed)return this.failed=!0,this.error=this.activeSubSolver.error??`High density repair failed for node ${t.node.capacityMeshNodeId}`,void(this.activeSubSolver=null);if(!this.activeSubSolver.solved)return;const e=this.activeSubSolver.getOutput().repairedRoutes;for(let n=0;n\u003ct.routeIndexes.length;n++){const o=t.routeIndexes[n],i=this.originalHdRoutes[o],r=e[n];this.repairedRoutesByIndex.set(o,r?RY(r,i):i)}return this.activeSubSolver=null,this.activeSampleIndex+=1,this.stats={sampleCount:this.sampleEntries.length,repairedNodeCount:this.activeSampleIndex,repairedRouteCount:this.repairedRoutesByIndex.size},void(this.activeSampleIndex\u003e=this.sampleEntries.length\u0026\u0026(this.solved=!0))}this.activeSubSolver=new CY({sample:t.sample,margin:this.repairMargin}),this.latestVisualization=this.activeSubSolver.visualize()}else this.solved=!0}getOutput(){return this.originalHdRoutes.map((t,e)=\u003ethis.repairedRoutesByIndex.get(e)??t)}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();if(!this.solved)return this.latestVisualization;const t=[],e=[];for(const n of this.getOutput()){const o=this.colorMap[n.connectionName]??\"#0ea5e9\";for(let e=0;e\u003cn.route.length-1;e++){const i=n.route[e],r=n.route[e+1];i.z===r.z\u0026\u0026t.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:0===i.z?o:To(o,.5),strokeWidth:n.traceThickness,layer:`z${i.z}`,strokeDash:0!==i.z?[.1,.3]:void 0})}for(const t of n.vias)e.push({center:{x:t.x,y:t.y},radius:n.viaDiameter/2,stroke:o,fill:\"rgba(14,165,233,0.12)\"})}return{title:\"Pipeline4 High Density Repair\",lines:t,circles:e}}},OY=1e-6,kY=({startGap:t,endGap:e,segmentGap:n,requiredGap:o})=\u003e{const i=t\u003co\u0026\u0026e\u003e=o-OY\u0026\u0026n\u003e=t-OY,r=e\u003co\u0026\u0026t\u003e=o-OY\u0026\u0026n\u003e=e-OY,s=t\u003co\u0026\u0026e\u003co\u0026\u0026n\u003e=Math.min(t,e)-OY;return i||r||s},LY=class{minClearance;rootsByConnection=new Map;sameNetCache=new Map;segments=[];vias=[];segmentIndexesByLayer;viaIndex;constructor({hdRoutes:t,minClearance:e=.1}){this.minClearance=e;for(const e of t)this.addRoute(e);this.buildSpatialIndexes()}addRoute(t){const e=this.rootsByConnection.get(t.connectionName)??new Set;e.add(t.rootConnectionName??t.connectionName),this.rootsByConnection.set(t.connectionName,e),this.sameNetCache.clear();for(let e=0;e\u003ct.route.length-1;e+=1){const n=t.route[e],o=t.route[e+1];if(n.z!==o.z)continue;if(n.insideJumperPad\u0026\u0026o.insideJumperPad)continue;const i={connectionName:t.connectionName,start:n,end:o,traceThickness:t.traceThickness};this.segments.push(i),this.insertSegmentIntoSpatialIndex(i)}for(const e of t.vias){const n={connectionName:t.connectionName,x:e.x,y:e.y,diameter:t.viaDiameter};this.vias.push(n),this.insertViaIntoSpatialIndex(n)}}insertSegmentIntoSpatialIndex(t){if(!this.segmentIndexesByLayer)return;let e=this.segmentIndexesByLayer.get(t.start.z);e||(e=new Pa,this.segmentIndexesByLayer.set(t.start.z,e));const n=t.traceThickness/2;e.insert(t,Math.min(t.start.x,t.end.x)-n,Math.min(t.start.y,t.end.y)-n,Math.max(t.start.x,t.end.x)+n,Math.max(t.start.y,t.end.y)+n)}insertViaIntoSpatialIndex(t){if(!this.viaIndex)return;const e=t.diameter/2;this.viaIndex.insert(t,t.x-e,t.y-e,t.x+e,t.y+e)}buildSpatialIndexes(){this.segmentIndexesByLayer=new Map;const t=new Map;for(const e of this.segments){const n=t.get(e.start.z);n?n.push(e):t.set(e.start.z,[e])}for(const[e,n]of t){const t=new Pa;t.bulkLoad(n.map(t=\u003e{const e=t.traceThickness/2;return{item:t,minX:Math.min(t.start.x,t.end.x)-e,minY:Math.min(t.start.y,t.end.y)-e,maxX:Math.max(t.start.x,t.end.x)+e,maxY:Math.max(t.start.y,t.end.y)+e}})),this.segmentIndexesByLayer.set(e,t)}this.viaIndex=new Pa,this.viaIndex.bulkLoad(this.vias.map(t=\u003e{const e=t.diameter/2;return{item:t,minX:t.x-e,minY:t.y-e,maxX:t.x+e,maxY:t.y+e}}))}areSameNet(t,e){if(t===e)return!0;const n=this.sameNetCache.get(t)?.get(e);if(void 0!==n)return n;const o=this.rootsByConnection.get(t),i=this.rootsByConnection.get(e);let r=!1;if(o\u0026\u0026i)for(const t of o)if(i.has(t)){r=!0;break}let s=this.sameNetCache.get(t);return s||(s=new Map,this.sameNetCache.set(t,s)),s.set(e,r),r}isSegmentClear({connectionName:t,start:e,end:n,traceThickness:o}){const i=o/2,r=this.minClearance+i,s=Math.min(e.x,n.x)-r,a=Math.min(e.y,n.y)-r,c=Math.max(e.x,n.x)+r,l=Math.max(e.y,n.y)+r,d=this.segmentIndexesByLayer?.get(e.z)?.search(s,a,c,l)??[];for(const o of d){if(this.areSameNet(t,o.connectionName))continue;const r=this.minClearance+i+o.traceThickness/2,s=Ra(e,n,o.start,o.end);if(s\u003cr\u0026\u0026!kY({startGap:be(e,o.start,o.end),endGap:be(n,o.start,o.end),segmentGap:s,requiredGap:r}))return!1}const h=this.viaIndex?.search(s,a,c,l)??[];for(const o of h){if(this.areSameNet(t,o.connectionName))continue;const r=this.minClearance+i+o.diameter/2,s=be(o,e,n);if(s\u003cr\u0026\u0026!kY({startGap:Math.hypot(e.x-o.x,e.y-o.y),endGap:Math.hypot(n.x-o.x,n.y-o.y),segmentGap:s,requiredGap:r}))return!1}return!0}},DY=1e-9,zY=1.25,FY=(t,e)=\u003et\u003ce?-1:t\u003ee?1:0,BY=(t,e)=\u003eFY(t.z,e.z)||FY(t.x,e.x)||FY(t.y,e.y),jY=t=\u003e`${t.z.toFixed(6)}:${t.x.toFixed(6)}:${t.y.toFixed(6)}`,$Y=t=\u003e{const e=t.route.map(jY).join(\"|\"),n=[...t.route].reverse().map(jY).join(\"|\");return e\u003c=n?e:n},YY=(t,e)=\u003e{const n=t.connectionName.localeCompare(e.connectionName);if(0!==n)return n;const o=(t.rootConnectionName??\"\").localeCompare(e.rootConnectionName??\"\");if(0!==o)return o;const i=$Y(t).localeCompare($Y(e));return 0!==i?i:FY(t.traceThickness,e.traceThickness)||FY(t.viaDiameter,e.viaDiameter)||FY(t.route.length,e.route.length)||FY(t.vias.length,e.vias.length)||FY(t.jumpers?.length??0,e.jumpers?.length??0)},XY=1e5,VY=.001,WY=1.000000001,HY=class extends si{getSolverName(){return\"SingleHighDensityRouteStitchSolver3\"}mergedHdRoute;remainingHdRoutes;start;end;colorMap;allowedLayerTransitionPointKeys;isStitchSegmentClear;stitchClearanceMode;isPlanarStitchClear(t,e){return this.isStitchSegmentClear({connectionName:this.mergedHdRoute.connectionName,start:t,end:e,traceThickness:this.mergedHdRoute.traceThickness})}constructor(t){super();const e=[...t.hdRoutes].sort(YY);if(this.remainingHdRoutes=e,this.colorMap=t.colorMap??{},this.allowedLayerTransitionPointKeys=t.allowedLayerTransitionPointKeys,this.isStitchSegmentClear=t.isStitchSegmentClear,this.stitchClearanceMode=t.stitchClearanceMode,0===e.length){this.start=t.start,this.end=t.end;const n=t.defaultTraceThickness??.15,o=[{x:t.start.x,y:t.start.y,z:t.start.z}],i=[];if(t.start.z!==t.end.z){if(t.allowedLayerTransitionPointKeys\u0026\u0026!t.allowedLayerTransitionPointKeys.has(af(t.start)))return this.failed=!0,void(this.error=`Layer transition at ${af(t.start)} is not allowed`);o.push({x:t.start.x,y:t.start.y,z:t.end.z}),i.push({x:t.start.x,y:t.start.y})}const r=o[o.length-1],s={x:t.end.x,y:t.end.y,z:t.end.z},a={connectionName:t.connectionName,start:r,end:s,traceThickness:n};return xe(r,s)\u003eVY\u0026\u0026!this.isStitchSegmentClear(a)\u0026\u0026\"require_clear\"===this.stitchClearanceMode?(this.failed=!0,void(this.error=`Terminal stitch for \"${t.connectionName}\" violates copper clearance`)):(o.push(s),this.mergedHdRoute={connectionName:t.connectionName,...t.preserveTerminalPcbPortIds\u0026\u0026t.start.pcb_port_id?{startPcbPortId:t.start.pcb_port_id}:{},...t.preserveTerminalPcbPortIds\u0026\u0026t.end.pcb_port_id?{endPcbPortId:t.end.pcb_port_id}:{},rootConnectionName:e[0]?.rootConnectionName,route:o,vias:i,jumpers:[],viaDiameter:t.defaultViaDiameter??.3,traceThickness:n},void(this.solved=!0))}const n=new Set((t.preserveTerminalPcbPortIds?[t.start.pcb_port_id,t.end.pcb_port_id]:[]).filter(t=\u003evoid 0!==t));if(t.preserveTerminalPcbPortIds\u0026\u0026t.start.pcb_port_id\u0026\u0026t.start.pcb_port_id===t.end.pcb_port_id)throw new Error(`SingleHighDensityRouteStitchSolver3 received duplicate PCB terminal \"${t.start.pcb_port_id}\" for \"${t.connectionName}\"`);const o=e.flatMap(t=\u003e[t.startPcbPortId,t.endPcbPortId]).filter(t=\u003evoid 0!==t);if(n.size\u003e0)for(const e of o)if(!n.has(e))throw new Error(`SingleHighDensityRouteStitchSolver3 found unknown PCB terminal \"${e}\" on \"${t.connectionName}\"`);let i=1/0,r=e[0],s=\"start-to-end\";for(const n of e){const e=n.route[0],o=n.route[n.route.length-1],a=xe(t.start,e),c=xe(t.start,o),l=xe(t.end,e),d=xe(t.end,o),h=Math.min(a,c,l,d);(h\u003ci-DY||Math.abs(h-i)\u003c=DY\u0026\u0026YY(n,r)\u003c0)\u0026\u0026(i=h,r=n,s=Math.min(l,d)\u003cMath.min(a,c)-DY||Math.abs(Math.min(l,d)-Math.min(a,c))\u003c=DY\u0026\u0026BY(t.end,t.start)\u003c0?\"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 a=r.route[0],c=r.route[r.route.length-1],l=xe(this.start,a),d=xe(this.start,c),h=l\u003cd-DY||Math.abs(l-d)\u003c=DY\u0026\u0026BY(a,c)\u003c=0?a:c,u=h===a?r.startPcbPortId:r.endPcbPortId;if(u\u0026\u0026this.start.pcb_port_id\u0026\u0026u!==this.start.pcb_port_id)throw new Error(`SingleHighDensityRouteStitchSolver3 terminal identity disagrees with route orientation for \"${t.connectionName}\"`);this.mergedHdRoute={connectionName:t.connectionName,...t.preserveTerminalPcbPortIds\u0026\u0026this.start.pcb_port_id?{startPcbPortId:this.start.pcb_port_id}:{},...t.preserveTerminalPcbPortIds\u0026\u0026this.end.pcb_port_id?{endPcbPortId:this.end.pcb_port_id}:{},rootConnectionName:r.rootConnectionName,route:[{x:this.start.x,y:this.start.y,z:h.z}],vias:[],jumpers:[],viaDiameter:r.viaDiameter,traceThickness:r.traceThickness}}getDisjointedRoute(){for(const t of this.remainingHdRoutes){if([t.route[0],t.route[t.route.length-1]].some(e=\u003e!this.remainingHdRoutes.some(n=\u003e{if(n===t)return!1;return[n.route[0],n.route[n.route.length-1]].some(t=\u003et.z===e.z\u0026\u0026xe(e,t)\u003c.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],e={...this.end,z:t.z},n=xe(t,e);if(n\u003eVY\u0026\u0026n\u003c=zY){if(!this.isPlanarStitchClear(t,e)\u0026\u0026\"require_clear\"===this.stitchClearanceMode)return this.failed=!0,void(this.error=`Terminal stitch for \"${this.mergedHdRoute.connectionName}\" violates copper clearance`);this.mergedHdRoute.route.push({x:this.end.x,y:this.end.y,z:t.z})}return void(this.solved=!0)}const t=this.mergedHdRoute.route[this.mergedHdRoute.route.length-1];let e=-1,n=\"first\",o=1/0,i=!1;for(let r=0;r\u003cthis.remainingHdRoutes.length;r++){const s=this.remainingHdRoutes[r],a=s.route[0],c=s.route[s.route.length-1],l=xe(t,a),d=xe(t,c);let h=1/0;if(t.z===a.z){if(l\u003cVY)h=l;else if(l\u003c=1){const e=this.isPlanarStitchClear(t,a);if(e||\"prefer_clear\"===this.stitchClearanceMode){h=XY+(e?0:WY)+l}else i=!0}}else l\u003cVY\u0026\u0026(!this.allowedLayerTransitionPointKeys||this.allowedLayerTransitionPointKeys.has(af(a)))\u0026\u0026(h=1e3+l);h\u003co\u0026\u0026(o=h,e=r,n=\"first\");let u=1/0;if(t.z===c.z){if(d\u003cVY)u=d;else if(d\u003c=1){const e=this.isPlanarStitchClear(t,c);if(e||\"prefer_clear\"===this.stitchClearanceMode){u=XY+(e?0:WY)+d}else i=!0}}else d\u003cVY\u0026\u0026(!this.allowedLayerTransitionPointKeys||this.allowedLayerTransitionPointKeys.has(af(c)))\u0026\u0026(u=1e3+d);u\u003co\u0026\u0026(o=u,e=r,n=\"last\")}if(-1===e)return i?(this.failed=!0,void(this.error=`Route stitch for \"${this.mergedHdRoute.connectionName}\" violates copper clearance`)):void(this.remainingHdRoutes=[]);const r=this.remainingHdRoutes[e];let s;this.remainingHdRoutes.splice(e,1),s=\"first\"===n?r.route:(t=\u003e{const e=[...t].reverse().map(t=\u003e{const{toNextSegmentType:e,...n}=t;return n});for(let n=0;n\u003ct.length-1;n++){const o=t[n]?.toNextSegmentType;if(!o)continue;const i=t.length-n-2;e[i]={...e[i],toNextSegmentType:o}}return e})(r.route),s.length\u003e0\u0026\u0026xe(t,s[0])\u003cVY\u0026\u0026t.z===s[0].z?(s[0].toNextSegmentType\u0026\u0026(t.toNextSegmentType=s[0].toNextSegmentType),this.mergedHdRoute.route.push(...s.slice(1))):this.mergedHdRoute.route.push(...s),this.mergedHdRoute.vias.push(...r.vias),r.jumpers\u0026\u0026this.mergedHdRoute.jumpers.push(...r.jumpers)}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:\"Single High Density Route Stitch Solver 3\"};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\u0026\u0026this.mergedHdRoute.route.length\u003e1){t.lines?.push({points:this.mergedHdRoute.route.map(t=\u003e({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\u0026\u0026this.mergedHdRoute.jumpers.length\u003e0){const e=_a(this.mergedHdRoute.jumpers,{color:\"green\",label:this.mergedHdRoute.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const e of this.remainingHdRoutes){t.lines?.push({points:e.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:\"orange\"});for(const n of e.route)t.points?.push({x:n.x,y:n.y,color:\"orange\"});for(const n of e.vias)t.circles?.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:\"orange\"});if(e.jumpers\u0026\u0026e.jumpers.length\u003e0){const n=_a(e.jumpers,{color:\"orange\",label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}return t}},GY=class{constructor(t=!1){this.preferSameLayerTerminalEndpoints=t}preferSameLayerTerminalEndpoints;endpointClusters=new Map;getEndpointKey(t,e){const n=this.endpointClusters.get(t)??[];let o,i=1/0;for(const t of n){if(t.point.z!==e.z)continue;const n=xe(t.point,e);n\u003c=.1\u0026\u0026(n\u003ci-DY||Math.abs(n-i)\u003c=DY\u0026\u0026(!o||BY(t.point,o.point)\u003c0))\u0026\u0026(o=t,i=n)}if(o)return o.key;const r=`${t}:endpoint_${n.length}`;return n.push({key:r,point:{x:e.x,y:e.y,z:e.z}}),this.endpointClusters.set(t,n),r}getClusters(t){return this.endpointClusters.get(t)??[]}getClosestEndpointKey(t,e,n){const o=e.flatMap(t=\u003e[t.route[0],t.route[t.route.length-1]]),i=o.filter(t=\u003et.z===n.z),r=this.preferSameLayerTerminalEndpoints\u0026\u0026i.length\u003e0?i:o;let s=null,a=null,c=1/0;for(const e of r){const o=xe(n,e),i=this.getEndpointKey(t,e);(o\u003cc-DY||Math.abs(o-c)\u003c=DY\u0026\u0026(null===s||i.localeCompare(s)\u003c0||i===s\u0026\u0026null!==a\u0026\u0026BY(e,a)\u003c0))\u0026\u0026(c=o,s=i,a=e)}return s}},UY=(t,e,n)=\u003e{const o=t.get(e)??[];o.some(t=\u003et.nextHash===n.nextHash\u0026\u0026t.routeIndex===n.routeIndex)||(o.push(n),t.set(e,o))},ZY=t=\u003e{const e=[...t.possibleEndpoints].sort(BY),n=e.reduce((e,n)=\u003e{const o=xe(n,t.globalStart),i=xe(e,t.globalStart);return o\u003ci-DY||Math.abs(o-i)\u003c=DY\u0026\u0026BY(n,e)\u003c0?n:e}),o=e.filter(t=\u003et!==n),i=(o.length\u003e0?o:t.possibleEndpoints).reduce((e,n)=\u003e{const o=xe(n,t.globalEnd),i=xe(e,t.globalEnd);return o\u003ci-DY||Math.abs(o-i)\u003c=DY\u0026\u0026BY(n,e)\u003c0?n:e});return{start:n,end:i}},qY=t=\u003e{const e=[...t.terminals].sort(BY);let n=e[0],o=xe(t.islandEndpoint,n);for(const i of e.slice(1)){const e=xe(t.islandEndpoint,i);(e\u003co-DY||Math.abs(e-o)\u003c=DY\u0026\u0026BY(i,n)\u003c0)\u0026\u0026(n=i,o=e)}return o\u003c=zY?n:t.islandEndpoint},JY=t=\u003e{if(t.hdRoutes.length\u003c=2)return t.hdRoutes;const e=[...t.hdRoutes].sort(YY),n=t.endpointIndex.getClosestEndpointKey(t.connectionName,e,t.start),o=t.endpointIndex.getClosestEndpointKey(t.connectionName,e,t.end);if(!n||!o||n===o)return e;const i=new Map;for(let n=0;n\u003ce.length;n++){const o=e[n],r=t.endpointIndex.getEndpointKey(t.connectionName,o.route[0]),s=t.endpointIndex.getEndpointKey(t.connectionName,o.route[o.route.length-1]);UY(i,r,{nextHash:s,routeIndex:n}),UY(i,s,{nextHash:r,routeIndex:n})}const r=[...t.endpointIndex.getClusters(t.connectionName)].sort((t,e)=\u003eBY(t.point,e.point));for(let t=0;t\u003cr.length;t++){const e=r[t];for(let n=t+1;n\u003cr.length;n++){const t=r[n];e.point.z===t.point.z\u0026\u0026(xe(e.point,t.point)\u003e1||(UY(i,e.key,{nextHash:t.key,routeIndex:null}),UY(i,t.key,{nextHash:e.key,routeIndex:null})))}}for(const[t,n]of i.entries())i.set(t,[...n].sort((t,n)=\u003e{if(null===t.routeIndex\u0026\u0026null!==n.routeIndex)return 1;if(null!==t.routeIndex\u0026\u0026null===n.routeIndex)return-1;if(null!==t.routeIndex\u0026\u0026null!==n.routeIndex){const o=YY(e[t.routeIndex],e[n.routeIndex]);if(0!==o)return o}return t.nextHash.localeCompare(n.nextHash)}));const s=[n],a=new Set([n]),c=new Map;for(;s.length\u003e0;){const t=s.shift();if(t===o)break;for(const e of i.get(t)??[])a.has(e.nextHash)||(a.add(e.nextHash),c.set(e.nextHash,{prevHash:t,routeIndex:e.routeIndex}),s.push(e.nextHash))}if(!a.has(o))return e;const l=[];let d=o;for(;d!==n;){const t=c.get(d);if(!t)return e;null!==t.routeIndex\u0026\u0026l.push(t.routeIndex),d=t.prevHash}if(0===l.length)return t.hdRoutes;const h=l.reverse().map(t=\u003ee[t]);return h.length\u003e0\u0026\u0026!t.canStitchBetweenTerminals({connectionName:t.connectionName,hdRoutes:h,start:t.start,end:t.end})?e:h},KY=class extends si{getSolverName(){return\"MultipleHighDensityRouteStitchSolver3\"}unsolvedRoutes;activeSolver=null;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;allowedLayerTransitionPointKeys;preserveTerminalPcbPortIds;endpointIndex;clearanceValidator;canStitchBetweenTerminals(t){const e=new HY({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter,allowedLayerTransitionPointKeys:this.allowedLayerTransitionPointKeys,preserveTerminalPcbPortIds:this.preserveTerminalPcbPortIds,isStitchSegmentClear:t=\u003ethis.clearanceValidator.isSegmentClear(t),stitchClearanceMode:\"require_clear\"});for(;!e.solved\u0026\u0026!e.failed\u0026\u0026e.iterations\u003ce.MAX_ITERATIONS;)e.step();if(e.failed)return!1;const n=e.mergedHdRoute.route[0],o=e.mergedHdRoute.route[e.mergedHdRoute.route.length-1],i=xe(n,t.start)+xe(o,t.end),r=xe(n,t.end)+xe(o,t.start);return Math.min(i,r)\u003c=zY}getSharedRootPathRoutes(t){const e=t.rootConnectionName;if(!e)return null;const n=new Set(t.hdRoutes),o=t.allHdRoutes.filter(t=\u003e(t.rootConnectionName??t.connectionName)===e);if(o.every(t=\u003en.has(t)))return null;const i=JY({connectionName:t.connectionName,hdRoutes:o,start:t.start,end:t.end,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=\u003ethis.canStitchBetweenTerminals(t)});return!i.some(t=\u003e!n.has(t))||i.length\u003e=o.length?null:i}constructor(t){super(),this.endpointIndex=new GY(t.preferSameLayerTerminalEndpoints),this.colorMap=t.colorMap??{},this.allowedLayerTransitionPointKeys=t.allowedLayerTransitionPointKeys,this.preserveTerminalPcbPortIds=t.preserveTerminalPcbPortIds??!1;const e=[...t.hdRoutes].sort(YY);this.clearanceValidator=new LY({hdRoutes:e});const n=e[0];this.defaultTraceThickness=n?.traceThickness??.15,this.defaultViaDiameter=n?.viaDiameter??t.defaultViaDiameter??.3;const o=new fa({}),i=[],r=new Map;for(let t=0;t\u003ce.length;t++){const n=e[t],o=n.route[0],r=n.route[n.route.length-1];i.push([`route_island_${t}`,this.endpointIndex.getEndpointKey(n.connectionName,o),this.endpointIndex.getEndpointKey(n.connectionName,r)])}o.addConnections(i);for(const t of i)for(const e of t.slice(1))r.set(e,(r.get(e)??0)+1);this.unsolvedRoutes=[];const s=Array.from(new Set(Object.values(o.idToNetMap)));for(const n of s){const i=o.getIdsConnectedToNet(n),s=e.filter((t,e)=\u003ei.includes(`route_island_${e}`));if(0===s.length)continue;const a=t.connections.find(t=\u003et.name===s[0].connectionName),c=s.flatMap(t=\u003e[t.route[0],t.route[t.route.length-1]]),l=new Map,d=[];for(const t of c){const e=this.endpointIndex.getEndpointKey(s[0].connectionName,t);l.has(e)||l.set(e,t),1===r.get(e)\u0026\u0026d.push(t)}const h=d.length\u003e0?d:[...l.values()];if(0===h.length)continue;let u,p;if(h.length\u003e=2){const e={...a.pointsToConnect[0],z:ko(bo(a.pointsToConnect[0]),t.layerCount)},n={...a.pointsToConnect[1],z:ko(bo(a.pointsToConnect[1]),t.layerCount)};({start:u,end:p}=ZY({possibleEndpoints:h,globalStart:e,globalEnd:n})),xe(u,a.pointsToConnect[1])\u003cxe(p,a.pointsToConnect[0])\u0026\u0026([u,p]=[p,u]),u=qY({islandEndpoint:u,terminals:[e,n]}),p=qY({islandEndpoint:p,terminals:[e,n]})}else u={...a.pointsToConnect[0],z:ko(bo(a.pointsToConnect[0]),t.layerCount)},p={...a.pointsToConnect[1],z:ko(bo(a.pointsToConnect[1]),t.layerCount)};const m=JY({connectionName:s[0].connectionName,hdRoutes:s,start:u,end:p,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=\u003ethis.canStitchBetweenTerminals(t)});this.unsolvedRoutes.push({connectionName:s[0].connectionName,hdRoutes:m,start:u,end:p})}const a=new Map;for(const t of this.unsolvedRoutes){const e=a.get(t.connectionName);e?e.push(t):a.set(t.connectionName,[t])}this.unsolvedRoutes=Array.from(a.entries()).flatMap(([n,o])=\u003e{const i=t.connections.find(t=\u003et.name===n),r=o.some(t=\u003et.hdRoutes.some(t=\u003et.route.length\u003c2)),s=o.length\u003e1\u0026\u0026(t=\u003e{for(let e=0;e\u003ct.length;e++)for(let n=e+1;n\u003ct.length;n++){const o=[t[e].start,t[e].end],i=[t[n].start,t[n].end];for(const t of o)for(const e of i)if(t.z===e.z\u0026\u0026xe(t,e)\u003c=1)return!0}return!1})(o);if(!i)return o;const a={...i.pointsToConnect[0],z:ko(bo(i.pointsToConnect[0]),t.layerCount)},c={...i.pointsToConnect[1],z:ko(bo(i.pointsToConnect[1]),t.layerCount)},l=o.flatMap(t=\u003et.hdRoutes),d=o.length\u003e1?this.getSharedRootPathRoutes({connectionName:n,rootConnectionName:i.__rootConnectionNames?.[0]??l[0]?.rootConnectionName,hdRoutes:l,allHdRoutes:e,start:a,end:c}):null;return r||s||d?[{connectionName:n,hdRoutes:d??JY({connectionName:n,hdRoutes:l,start:a,end:c,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=\u003ethis.canStitchBetweenTerminals(t)}),start:a,end:c}]:o}),this.MAX_ITERATIONS=1e5}_step(){if(this.activeSolver)return this.activeSolver.step(),void(this.activeSolver.solved?(this.activeSolver instanceof HY\u0026\u0026(this.clearanceValidator.addRoute(this.activeSolver.mergedHdRoute),this.mergedHdRoutes.push(this.activeSolver.mergedHdRoute)),this.activeSolver=null):this.activeSolver.failed\u0026\u0026(this.failed=!0,this.error=this.activeSolver.error));const t=this.unsolvedRoutes.pop();t?this.activeSolver=new HY({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter,allowedLayerTransitionPointKeys:this.allowedLayerTransitionPointKeys,preserveTerminalPcbPortIds:this.preserveTerminalPcbPortIds,isStitchSegmentClear:t=\u003ethis.clearanceValidator.isSegmentClear(t),stitchClearanceMode:\"prefer_clear\"}):this.solved=!0}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:\"Multiple High Density Route Stitch Solver 3\"};if(this.activeSolver){const e=this.activeSolver.visualize();e.points?.length\u0026\u0026t.points?.push(...e.points),e.lines?.length\u0026\u0026t.lines?.push(...e.lines),e.circles?.length\u0026\u0026t.circles?.push(...e.circles),e.rects?.length\u0026\u0026(t.rects||(t.rects=[]),t.rects.push(...e.rects))}for(const[e,n]of this.mergedHdRoutes.entries()){const o=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e\u003cn.route.length-1;e++){const i=n.route[e],r=n.route[e+1],s=0!==i.z?To(o,.5):o;t.lines?.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:s,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?To(o,.5):o;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:o});if(n.jumpers\u0026\u0026n.jumpers.length\u003e0){const e=_a(n.jumpers,{color:o,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}return t}},QY=t=\u003e(t%360+360)%360,tX=(t,e)=\u003e{const{ccwRotationDegrees:n,...o}=t,i=(t=\u003e{const e=QY(t),n=[0,90,180,270];for(const t of n)if(Math.min(Math.abs(e-t),360-Math.abs(e-t))\u003c=.01)return t;return null})(e);return 90===i||270===i?{...o,width:t.height,height:t.width}:o},eX=t=\u003e\"layers\"in t?t.layers:[t.layer],nX=(t,e)=\u003e!(eX(t).length\u003e0\u0026\u0026!eX(t).some(t=\u003ee.layers.includes(t)))\u0026\u0026Me(t,Ve(e)),oX=(t,e)=\u003e{const{minX:n,maxX:o,minY:i,maxY:r}=Ve(e);return{x:Math.max(n,Math.min(o,t.x)),y:Math.max(i,Math.min(r,t.y))}},iX=(t,e)=\u003et.obstacleId??`${t.componentId??\"obstacle\"}_${e}`;function rX(t,e=2){const{center:n,width:o,height:i,rotation:r}=t,s=[],a=Math.max(1,Math.ceil(e)),c=r*Math.PI/180,l=Math.cos(c),d=Math.sin(c);if(o\u003e=i){const t=o/a;for(let e=0;e\u003ca;e++){const o=(e-a/2+.5)*t,r=o*l,c=o*d,h=Math.abs(t*l)+Math.abs(i*d),u=Math.abs(t*d)+Math.abs(i*l);s.push({center:{x:n.x+r,y:n.y+c},width:h,height:u})}}else{const t=i/a;for(let e=0;e\u003ca;e++){const i=(e-a/2+.5)*t,r=-i*d,c=i*l,h=Math.abs(o*l)+Math.abs(t*d),u=Math.abs(o*d)+Math.abs(t*l);s.push({center:{x:n.x+r,y:n.y+c},width:h,height:u})}}return s}var sX=t=\u003e{if(\"oval\"===t.type)return sX({...t,type:\"rect\"});const e=t.ccwRotationDegrees;if(\"number\"!=typeof e||!Number.isFinite(e))return[t];if((t=\u003e{const e=QY(t);return[0,90,180,270].some(t=\u003eMath.min(Math.abs(e-t),360-Math.abs(e-t))\u003c=.01)})(e))return[tX(t,e)];const{ccwRotationDegrees:n,...o}=t,i={center:t.center,width:t.width,height:t.height,rotation:e},r=(t=\u003e{const e=Math.max(t.width,t.height),n=Math.min(t.width,t.height);return t.obstacleId?.startsWith(\"trace_obstacle_\")?Math.max(2,Math.ceil(e/.75)):n\u003c=0?2:e/n\u003c2||n\u003e=.9?null:Math.max(2,Math.ceil(e/.75))})(t),s=t.connectedTo.length\u003e0\u0026\u0026!t.obstacleId?.startsWith(\"trace_obstacle_\")?(t=\u003e{const e=t.rotation*Math.PI/180,n=Math.cos(e),o=Math.sin(e),i=[-1,1].flatMap(e=\u003e[-1,1].map(i=\u003e{const r=e*(t.width/2),s=i*(t.height/2);return{x:t.center.x+r*n-s*o,y:t.center.y+r*o+s*n}})),r=[i[0],i[2],i[3],i[1]],s=Math.min(...r.map(t=\u003et.x)),a=Math.max(...r.map(t=\u003et.x)),c=Math.min(...r.map(t=\u003et.y)),l=Math.max(...r.map(t=\u003et.y)),d=a-s\u003c=l-c?\"x\":\"y\",h=\"x\"===d?s:c,u=\"x\"===d?a:l,p=Math.max(1,Math.ceil((u-h)/.4)),m=(u-h)/p,g=(t,e,n)=\u003e{const o=[],i=t=\u003et[d];for(let r=0;r\u003ct.length;r++){const s=t[r],a=t[(r+1)%t.length],c=i(s),l=i(a),d=n?c\u003e=e:c\u003c=e,h=n?l\u003e=e:l\u003c=e;if(d\u0026\u0026o.push(s),d===h)continue;const u=(e-c)/(l-c);o.push({x:s.x+(a.x-s.x)*u,y:s.y+(a.y-s.y)*u})}return o},f=[];for(let t=0;t\u003cp;t++){const e=h+t*m,n=t===p-1?u:e+m,o=g(g(r,e,!0),n,!1);if(0===o.length)continue;const i=Math.min(...o.map(t=\u003et.x)),s=Math.max(...o.map(t=\u003et.x)),a=Math.min(...o.map(t=\u003et.y)),c=Math.max(...o.map(t=\u003et.y));f.push({center:{x:(i+s)/2,y:(a+c)/2},width:s-i,height:c-a})}return f})(i):null===r?((t,e)=\u003e{const{center:n,width:o,height:i,rotation:r}=t,s=Math.max(1,Math.ceil(o/e)),a=Math.max(1,Math.ceil(i/e)),c=o/s,l=i/a,d=r*Math.PI/180,h=Math.cos(d),u=Math.sin(d),p=[];for(let t=0;t\u003cs;t++){const e=(t-s/2+.5)*c;for(let t=0;t\u003ca;t++){const o=(t-a/2+.5)*l;p.push({center:{x:n.x+e*h-o*u,y:n.y+e*u+o*h},width:Math.abs(c*h)+Math.abs(l*u),height:Math.abs(c*u)+Math.abs(l*h)})}}return p})(i,(t=\u003et.obstacleId?.startsWith(\"trace_obstacle_\")?.75:.4)(t)):t.obstacleId?.startsWith(\"trace_obstacle_\")?rX(i,r):((t,e)=\u003e{const{center:n,width:o,height:i,rotation:r}=t,s=Math.max(o,i),a=Math.min(o,i),c=Math.max(1,Math.ceil(e)),l=s/c,d=r*Math.PI/180,h=Math.cos(d),u=Math.sin(d),p=Math.max(l,.75*a),m=[];for(let t=0;t\u003cc;t++){const e=(t-c/2+.5)*l,r=o\u003e=i?e*h:-e*u,s=o\u003e=i?e*u:e*h;m.push({center:{x:n.x+r,y:n.y+s},width:p,height:p})}return m})(i,r),a=t.connectedTo.length\u003e0?s.reduce((e,n,o)=\u003e{const i=s[e],r=(i.center.x-t.center.x)**2+(i.center.y-t.center.y)**2;return(n.center.x-t.center.x)**2+(n.center.y-t.center.y)**2\u003cr?o:e},0):-1;return s.map((t,e)=\u003e({...o,obstacleId:e===a?o.obstacleId:o.obstacleId?`${o.obstacleId}_approx_${e}`:void 0,connectedTo:o.connectedTo,center:t.center,width:t.width,height:t.height}))},aX=t=\u003e{const e=new Map,n=new Map,o=new Map;for(const[i,r]of t.obstacles.entries()){const t=sX(r),s=iX(r,i);n.set(s,t),o.set(s,r);for(const n of t){const t=[n.center.x.toFixed(6),n.center.y.toFixed(6),n.width.toFixed(6),n.height.toFixed(6),n.layers.join(\",\")].join(\":\"),o=e.get(t);o?o.connectedTo=[...new Set([...o.connectedTo,...n.connectedTo])]:e.set(t,n)}}const i=t.connections.map(t=\u003e({...t,pointsToConnect:t.pointsToConnect.map(t=\u003e{const e=(t=\u003e[t.pointId,t.pcb_port_id].filter(t=\u003eBoolean(t)))(t);if(0===e.length)return t;for(const[i,r]of o){if(!e.some(t=\u003er.connectedTo.includes(t)))continue;if(!nX(t,r))continue;const o=n.get(i)??[];if(0===o.length)continue;if(o.some(e=\u003enX(t,e)))return t;let s=o[0],a=Number.POSITIVE_INFINITY;for(const e of o){const n=xe(oX(t,e),t);n\u003ca\u0026\u0026(a=n,s=e)}return{...t,...oX(t,s)}}return t})}));return{...t,connections:i,obstacles:[...e.values()]}},cX=.001,lX=t=\u003e\"wire\"===t.route_type,dX=t=\u003e\"via\"===t.route_type,hX=t=\u003e\"through_obstacle\"===t.route_type,uX=(t,e,n)=\u003e{const o=ko(t,n),i=ko(e,n),r=Math.min(o,i),s=Math.max(o,i);return Array.from({length:s-r+1},(t,e)=\u003evo(r+e,n))},pX=({obstacleId:t,start:e,end:n,width:o,layer:i,connectedTo:r})=\u003e{const s=n.x-e.x,a=n.y-e.y,c=Math.hypot(s,a);return c\u003c=cX?null:{obstacleId:t,type:\"rect\",layers:[i],center:{x:(e.x+n.x)/2,y:(e.y+n.y)/2},width:c,height:Math.max(o,cX),ccwRotationDegrees:180*Math.atan2(a,s)/Math.PI,connectedTo:r}};function mX(t){if(!t)return t;const e=(t=\u003e{if(!t)return[];const e=[],n=Yo(t);for(const[o,i]of(t.traces??[]).entries()){const r=i.connectsTo??[];for(let s=0;s\u003ci.route.length;s++){const a=i.route[s];if(dX(a)){const c=a.via_diameter??n.padDiameter;e.push({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${s}_via`,type:\"rect\",layers:uX(a.from_layer,a.to_layer,t.layerCount),center:{x:a.x,y:a.y},width:Math.max(c,cX),height:Math.max(c,cX),connectedTo:r});continue}if(hX(a)){const n=pX({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${s}_through`,start:a.start,end:a.end,width:a.width,layer:a.from_layer,connectedTo:r});n\u0026\u0026(n.layers=uX(a.from_layer,a.to_layer,t.layerCount),e.push(n))}}for(let t=0;t\u003ci.route.length-1;t++){const n=i.route[t],s=i.route[t+1];if(!lX(n)||!lX(s)||n.layer!==s.layer)continue;const a=pX({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${t}_wire`,start:n,end:s,width:n.width,layer:n.layer,connectedTo:r});a\u0026\u0026e.push(a)}}return e})(t);return 0===e.length?t:{...t,obstacles:[...t.obstacles??[],...e]}}function gX(t,e){const n=function(t,e){const n=Lo(t.__zLayers??t.zLayers??[],e);if(n.length\u003e0)return n;const o=Do(t.layers,e);if(o.length\u003e0)return o;throw new Error(`Obstacle \"${t.obstacleId??\"unknown\"}\" has no layers on this ${e}-layer board`)}(t,e);return{...t,layers:n.map(t=\u003evo(t,e)),zLayers:n,__zLayers:n}}function fX(t){return{...t,obstacles:t.obstacles.map(e=\u003egX(e,t.layerCount)),jumpers:t.jumpers?.map(e=\u003e({...e,pads:e.pads.map(e=\u003egX(e,t.layerCount))}))}}var yX=t=\u003e{const e=t.obstacles.filter(e=\u003e!((t,e)=\u003e!(t=\u003e(t.connectedTo?.length??0)\u003e0||(t.offBoardConnectsTo?.length??0)\u003e0||!0===t.netIsAssignable)(t)\u0026\u0026(e.outline\u0026\u0026e.outline.length\u003e=3?!Te(t,e.outline):!Xe({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.bounds)))(e,t)),n=e.length!==t.obstacles.length,o=n\u0026\u0026t.outline\u0026\u0026t.outline.length\u003e=3?(t=\u003e{if(t.width\u0026\u0026t.height\u0026\u0026t.center){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,width:t.width,height:t.height,center:{x:t.center.x,y:t.center.y}}}if(!t.outline||0===t.outline.length)throw new Error(\"Unable to compute board bounds. pcb_board must include width/height/center or a non-empty outline.\");let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t.outline)e=Math.min(e,r.x),n=Math.min(n,r.y),o=Math.max(o,r.x),i=Math.max(i,r.y);const r=o-e,s=i-n;return{minX:e,minY:n,maxX:o,maxY:i,width:r,height:s,center:{x:e+r/2,y:n+s/2}}})({type:\"pcb_board\",pcb_board_id:\"__autorouting_board_outline__\",center:{x:0,y:0},thickness:1,num_layers:t.layerCount,material:\"fr4\",outline:t.outline}):t.bounds;return n?{...t,obstacles:e,bounds:o}:t},_X=class extends si{constructor(t,e={}){super(),this.inputSrj=t,this.visualizationOptions=e,this.MAX_ITERATIONS=1}inputSrj;visualizationOptions;outputSrj;_step(){const t=fX(this.inputSrj),e=mX(t)??t,n=aX(yX(e));this.outputSrj=fX(n),this.solved=!0}getOutputSimpleRouteJson(){if(!this.outputSrj)throw new Error(\"PreprocessSimpleRouteJsonSolver has not solved yet\");return this.outputSrj}getConstructorParams(){return[this.inputSrj,this.visualizationOptions]}visualize(){return this.outputSrj?pi(Ho({...this.outputSrj,traces:[]},this.visualizationOptions),Yj({srj:this.outputSrj,visualizationOptions:this.visualizationOptions})):{lines:[],points:[],rects:[],circles:[]}}};function bX(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var xX=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;nodeSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[bX(\"preprocessSimpleRouteJsonSolver\",_X,t=\u003e[t.originalSrj],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),bX(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),bX(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),bX(\"nodeSolver\",Kn,t=\u003e[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=\u003e{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),bX(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver?.outputNodes??[]}}),bX(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),bX(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),bX(\"necessaryCrampedPortPointSolver\",sf,t=\u003e[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),bX(\"portPointPathingSolver\",jj,t=\u003e{const e=t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),bX(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),bX(\"highDensityRouteSolver\",zs,t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=(e.length\u003e0?e:n).map(e=\u003ews(e)?{...e,availableZ:Array.from({length:t.srj.layerCount},(t,e)=\u003ee)}:e);return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0}]}),bX(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,totalStepsPerNode:Math.max(20,Math.round(60*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),bX(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2}]),bX(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),bX(\"traceSimplificationSolver\",vc,t=\u003e[{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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,iterations:2}]),bX(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),bX(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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\u0026\u0026(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\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.nodeSolver?.visualize(),o=this.nodeDimensionSubdivisionSolver?.visualize(),i=this.nodeTargetMerger?.visualize(),r=this.singleLayerNodeMerger?.visualize(),s=this.strawSolver?.visualize(),a=this.edgeSolver?.visualize(),c=this.deadEndSolver?.visualize(),l=this.availableSegmentPointSolver?.visualize(),d=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),u=this.uniformPortDistributionSolver?.visualize(),p=this.highDensityRouteSolver?.visualize(),m=this.highDensityForceImproveSolver?.visualize(),g=this.highDensityRepairSolver?.visualize(),f=this.highDensityStitchSolver?.visualize(),y=this.traceSimplificationSolver?.visualize(),_=this.necessaryCrampedPortPointSolver?.visualize(),b=(this.highDensityRouteSolver?.visualize(),this.originalSrj),x=b.outline,v=[];if(v.push({points:[{x:b.bounds?.minX??-50,y:b.bounds?.minY??-50},{x:b.bounds?.maxX??50,y:b.bounds?.minY??-50},{x:b.bounds?.maxX??50,y:b.bounds?.maxY??50},{x:b.bounds?.minX??-50,y:b.bounds?.maxY??50},{x:b.bounds?.minX??-50,y:b.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),x\u0026\u0026x.length\u003e=2){const t=x.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const S=Oo(b),I={points:[...b.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,b.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(b.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,b.layerCount),label:S(t)}))],lines:v},C=Yj({srj:b}),P=[pi(I,C),t,e,n,o,i,r,s,a,c,l,_,d,h,u,p?pi(I,p):null,m,g,f,y,this.solved?pi({lines:v},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...P)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){return this.globalDrcForceImproveSolver?.getOutput()??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 o=n.__netConnectionName??this.originalSrj.connections.find(t=\u003et.name===n.name)?.__netConnectionName,i=e.filter(t=\u003et.connectionName===n.name);for(let e=0;e\u003ci.length;e++){const r=i[e],s={type:\"pcb_trace\",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.srj.obstacles,connMap:this.connMap})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},vX=t=\u003e{const e=[];let n=t;for(;n;)e.push(n),n=n.activeSubSolver;for(let t=e.length-1;t\u003e=0;t--){const n=e[t]?.pendingEffects?.filter(Boolean)??[];if(n.length\u003e0)return n}return[]},SX=t=\u003e/\\/solve\\/?$/.test(t)?t.replace(/\\/+$/,\"\"):`${t.replace(/\\/+$/,\"\")}/solve`,IX=(t,e,n)=\u003e{const o=(t=\u003e{const e=new Map;for(const n of t.portPoints)n.rootConnectionName\u0026\u0026!e.has(n.connectionName)\u0026\u0026e.set(n.connectionName,n.rootConnectionName);return e})(t);return e.map(t=\u003e({connectionName:t.connectionName,rootConnectionName:t.rootConnectionName??o.get(t.connectionName)??void 0,traceThickness:t.traceThickness??n.traceWidth,viaDiameter:t.viaDiameter??n.viaDiameter,route:(t.route??[]).map(t=\u003e({x:t.x,y:t.y,z:t.z,...t.insideJumperPad?{insideJumperPad:!0}:{}})),vias:(t.vias??[]).map(t=\u003e({x:t.x,y:t.y})),...t.jumpers?{jumpers:t.jumpers}:{}}))},CX=(t,e)=\u003e{if(0===t.length)return null;const n=Math.min(Math.max(e,0),1),o=(t.length-1)*n,i=Math.floor(o),r=Math.ceil(o),s=t[i],a=t[r];return i===r?s:s+(a-s)*(o-i)},PX=t=\u003enew Set(t.portPoints.map(t=\u003et.connectionName)).size,MX=t=\u003e!(PX(t)\u003c3)\u0026\u00261!==(t.availableZ?.length??0),NX=t=\u003et?.MULTI_HEAD_POLYLINE_SOLVER?\"MultiHeadPolyLineIntraNodeSolver3\":t?.CLOSED_FORM_SINGLE_TRANSITION?\"SingleTransitionIntraNodeSolver\":t?.CLOSED_FORM_TWO_TRACE_SAME_LAYER?\"TwoCrossingRoutesHighDensitySolver\":t?.CLOSED_FORM_TWO_TRACE_TRANSITION_CROSSING?\"SingleTransitionCrossingRouteSolver\":t?.HIGH_DENSITY_A01?\"HighDensitySolverA01\":t?.HIGH_DENSITY_A03?\"HighDensitySolverA03\":\"SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost\",wX=t=\u003e{if(t instanceof rr){const e=NX(t.hyperParameters);return t.cacheHit?`${e} [cached]`:e}if(t instanceof er)return NX(t.hyperParameters);if(t\u0026\u0026\"object\"==typeof t\u0026\u0026\"getSolverName\"in t\u0026\u0026\"function\"==typeof t.getSolverName)return t.getSolverName();const e=t?.constructor;return\"string\"==typeof e?.name?e.name:\"unknown\"},TX=t=\u003et.winningSolver?wX(t.winningSolver):wX(t),RX=class extends si{getSolverName(){return\"Pipeline5HdCacheHighDensitySolver\"}unsolvedNodePortPoints;colorMap;connMap;viaDiameter;traceWidth;obstacleMargin;obstacles;layerCount;hdCacheBaseUrl;fetchImpl;nodePfById;routes=[];nodeSolveMetadataById=new Map;launchedRemoteSolves=!1;solvedRoutesByNodeIndex=new Map;failedNodeResults=[];remoteResponseMeasurements=[];constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,obstacles:s,layerCount:a,nodePfById:c,hdCacheBaseUrl:l,fetchImpl:d}){super(),this.unsolvedNodePortPoints=t,this.colorMap=e??{},this.connMap=n,this.viaDiameter=o??.3,this.traceWidth=i??.15,this.obstacleMargin=r??.15,this.obstacles=s??[],this.layerCount=a??2,this.hdCacheBaseUrl=l??\"https://hd-cache.tscircuit.com\",this.fetchImpl=(d??globalThis.fetch).bind(globalThis),this.nodePfById=c instanceof Map?new Map(c):new Map(Object.entries(c??{})),this.pendingEffects=[],this.stats={localDirectNodeCount:0,localSolvedNodeCount:0,localFallbackNodeCount:0,remoteFallbackNodeCount:0,remoteRequestsStarted:0,remoteRequestsCompleted:0,remoteResponseSampleCount:0,remoteKOrderSampleCount:0,slowestRemoteResponseMs:null,slowestRemoteResponseNodeId:null,p50RemoteResponseMs:null,p50RemoteKOrder:null,p95RemoteKOrder:null,remoteSources:{}}}computeProgress(){return 0===this.unsolvedNodePortPoints.length?1:this.nodeSolveMetadataById.size/this.unsolvedNodePortPoints.length}solveNodeLocally(t,e,n={}){const o=new Ss({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,obstacles:this.obstacles,layerCount:this.layerCount});if(o.solve(),o.failed){const e=o.error??`Local intra-node solver failed for ${t.capacityMeshNodeId}`,i=PX(t);return this.failedNodeResults.push({node:t,error:n.remoteFailure\u0026\u0026\"local-fallback\"===n.resolution?`Remote solve failed (${n.remoteFailure}); local fallback failed (${e})`:e}),void this.recordNodeSolveMetadata(t,{status:\"failed\",resolution:\"failed\",solverType:TX(o),supervisorType:o.getSolverName(),iterations:o.iterations,pairCount:i,routeCount:0,remoteAttempt:\"local-fallback\"===n.resolution?{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:\"error\",durationMs:n.remoteDurationMs,error:n.remoteFailure??e}:{attempted:!1},error:e})}this.solvedRoutesByNodeIndex.set(e,o.solvedRoutes);const i=PX(t);this.recordNodeSolveMetadata(t,{status:\"solved\",resolution:n.resolution??\"local\",solverType:TX(o),supervisorType:o.getSolverName(),iterations:o.iterations,pairCount:i,routeCount:o.solvedRoutes.length,remoteAttempt:\"local-fallback\"===n.resolution?{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:\"error\",durationMs:n.remoteDurationMs,error:n.remoteFailure}:{attempted:!1}}),\"local-fallback\"===n.resolution?(this.stats.localFallbackNodeCount+=1,this.stats.remoteFallbackNodeCount+=1):this.stats.localDirectNodeCount+=1,this.stats.localSolvedNodeCount+=1}async solveNodeViaHdCache(t,e){const n=SX(this.hdCacheBaseUrl),o={\"content-type\":\"application/json\"},i={nodeWithPortPoints:t},r=JSON.stringify(i),s=Date.now();let a,c,l,d=null,h=null;try{const i=await this.fetchImpl(n,{method:\"POST\",headers:o,body:r});if(a=i.status,c=i.ok,l=await i.text(),d=Date.now()-s,h=l?JSON.parse(l):null,!i.ok)throw new Error(h?.message??l??`hd-cache request failed with status ${i.status}`);if(!h?.ok||null===h.routes)throw new Error(h?.message??`hd-cache returned no routes for ${t.capacityMeshNodeId}`);const u=IX(t,h.routes,{traceWidth:this.traceWidth,viaDiameter:this.viaDiameter});this.solvedRoutesByNodeIndex.set(e,u),this.recordNodeSolveMetadata(t,{status:\"solved\",resolution:\"remote\",solverType:`hd-cache.tscircuit.com [${h.source}]`,iterations:null,pairCount:PX(t),routeCount:u.length,remoteAttempt:{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:h.source,durationMs:d}}),this.recordRemoteSource(h.source)}catch(u){d??=Date.now()-s;const p=(t=\u003et instanceof Error?t.message:String(t))(u);this.recordFailedHdCacheRequest({nodeId:t.capacityMeshNodeId,pairCount:PX(t),failedAt:(new Date).toISOString(),durationMs:d,error:p,url:n,request:{method:\"POST\",headers:o,body:r,bodyJson:i},response:void 0!==a||void 0!==c||void 0!==l||null!==h?{status:a,ok:c,text:l,body:h}:void 0}),this.recordRemoteSource(\"error\"),this.solveNodeLocally(t,e,{resolution:\"local-fallback\",remoteFailure:p,remoteDurationMs:d})}finally{this.recordRemoteResponseMetrics(t.capacityMeshNodeId,d??Date.now()-s,(u=h?.kOrder,\"number\"==typeof u\u0026\u0026Number.isFinite(u)?h.kOrder:null)),this.stats.remoteRequestsCompleted+=1}var u}launchRemoteSolves(){const t=[];this.unsolvedNodePortPoints.forEach((e,n)=\u003e{if(!MX(e))return void this.solveNodeLocally(e,n);const o={name:`hd-cache:${e.capacityMeshNodeId}`,promise:Promise.resolve()};o.promise=this.solveNodeViaHdCache(e,n).finally(()=\u003e{this.pendingEffects=this.pendingEffects?.filter(t=\u003et!==o)}),t.push(o)}),this.pendingEffects=t,this.stats.remoteRequestsStarted=t.length}recordRemoteSource(t){this.stats.remoteSources[t]=(this.stats.remoteSources[t]??0)+1}recordRemoteResponseMetrics(t,e,n){this.remoteResponseMeasurements.push({nodeId:t,durationMs:e,kOrder:n}),this.stats.remoteResponseSampleCount=this.remoteResponseMeasurements.length,this.stats.remoteKOrderSampleCount=this.remoteResponseMeasurements.filter(t=\u003enull!==t.kOrder).length;let o=null;for(const t of this.remoteResponseMeasurements)(!o||t.durationMs\u003eo.durationMs)\u0026\u0026(o=t);this.stats.slowestRemoteResponseMs=o?.durationMs??null,this.stats.slowestRemoteResponseNodeId=o?.nodeId??null;const i=this.remoteResponseMeasurements.map(t=\u003et.durationMs).sort((t,e)=\u003et-e);this.stats.p50RemoteResponseMs=CX(i,.5);const r=this.remoteResponseMeasurements.map(t=\u003et.kOrder).filter(t=\u003enull!==t).sort((t,e)=\u003et-e);this.stats.p50RemoteKOrder=CX(r,.5),this.stats.p95RemoteKOrder=CX(r,.95)}recordFailedHdCacheRequest(t){const e=(()=\u003e{if(\"undefined\"==typeof window)return null;const t=window;return Array.isArray(t.__FAILED_HD_CACHE_REQUESTS)||(t.__FAILED_HD_CACHE_REQUESTS=[]),t.__FAILED_HD_CACHE_REQUESTS})();e\u0026\u0026e.push(t)}recordNodeSolveMetadata(t,e){this.nodeSolveMetadataById.set(t.capacityMeshNodeId,{...e,node:t,nodePf:this.nodePfById.get(t.capacityMeshNodeId)??null})}ensureFailedNodeMetadata(){for(const t of this.failedNodeResults)this.nodeSolveMetadataById.has(t.node.capacityMeshNodeId)||this.recordNodeSolveMetadata(t.node,{status:\"failed\",resolution:\"failed\",solverType:\"unknown\",iterations:null,pairCount:PX(t.node),routeCount:0,remoteAttempt:{attempted:MX(t.node),source:\"error\",error:t.error},error:t.error})}getVisibleRoutes(){if(this.solved)return this.routes;const t=[];for(let e=0;e\u003cthis.unsolvedNodePortPoints.length;e++)t.push(...this.solvedRoutesByNodeIndex.get(e)??[]);return t}createNodeMarkerLabel(t,e){return[\"hd_node_marker\",`node: ${t}`,`status: ${e.status}`,`resolution: ${e.resolution}`,`solver: ${e.solverType}`,...e.supervisorType?[`supervisor: ${e.supervisorType}`]:[],...null!==e.iterations?[`iterations: ${e.iterations}`]:[],`pairCount: ${e.pairCount}`,`routes: ${e.routeCount}`,`nodePf: ${e.nodePf??\"n/a\"}`,\"remoteAttempted: \"+(e.remoteAttempt.attempted?\"yes\":\"no\"),...e.remoteAttempt.source?[`remoteSource: ${e.remoteAttempt.source}`]:[],...void 0!==e.remoteAttempt.durationMs?[`remoteDurationMs: ${e.remoteAttempt.durationMs}`]:[],...e.remoteAttempt.error?[`remoteError: ${e.remoteAttempt.error}`]:[],`portPoints: ${e.node.portPoints.length}`,...e.error?[`error: ${e.error}`]:[]].join(\"\\n\")}_step(){if(!this.launchedRemoteSolves)return this.launchedRemoteSolves=!0,void this.launchRemoteSolves();if(!((this.pendingEffects?.length??0)\u003e0)){if(this.failedNodeResults.length\u003e0){this.ensureFailedNodeMetadata();const t=this.failedNodeResults[0];return this.failed=!0,void(this.error=`Failed to solve ${this.failedNodeResults.length} nodes via hd-cache. First failure: ${t?.node.capacityMeshNodeId} (${t?.error})`)}this.routes=[];for(let t=0;t\u003cthis.unsolvedNodePortPoints.length;t++)this.routes.push(...this.solvedRoutesByNodeIndex.get(t)??[]);this.solved=!0}}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.getVisibleRoutes()){const n=mi(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const o of n)t.lines.push({points:o.points,label:o.connectionName,strokeColor:0===o.z?o.color:To(o.color,.75),layer:`z${o.z}`,strokeWidth:e.traceThickness,strokeDash:0!==o.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,n]of this.nodeSolveMetadataById){const o=n.node.center.x-n.node.width/2,i=n.node.center.x+n.node.width/2,r=n.node.center.y-n.node.height/2,s=n.node.center.y+n.node.height/2,a=this.createNodeMarkerLabel(e,n),c=\"solved\"===n.status?\"blue\":\"red\",l=\"solved\"===n.status?.03:.08;if(t.lines.push({points:[{x:o,y:r},{x:i,y:r}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a},{points:[{x:i,y:r},{x:i,y:s}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a},{points:[{x:i,y:s},{x:o,y:s}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a},{points:[{x:o,y:s},{x:o,y:r}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a}),\"solved\"===n.status)t.points.push({x:n.node.center.x,y:n.node.center.y,color:c,layer:\"hd_node_markers\",label:a});else{t.lines.push({points:[{x:0,y:0},{x:n.node.center.x,y:n.node.center.y}],layer:\"hd_failed_node_guides\",strokeColor:c,strokeDash:\"8, 6\",strokeWidth:.05,label:a});const e=Math.max(n.node.width,1.2),o=Math.max(n.node.height,1.2),i=e/2,r=o/2;t.rects.push({center:n.node.center,layer:\"hd_node_markers\",width:e,height:o,fill:\"rgba(255, 0, 0, 0.3)\",stroke:c,label:a}),t.circles.push({center:n.node.center,radius:Math.max(.6*Math.max(e,o),1.1),layer:\"hd_node_markers\",fill:\"rgba(255, 0, 0, 0.08)\",stroke:c,label:a}),t.lines.push({points:[{x:n.node.center.x-i,y:n.node.center.y-r},{x:n.node.center.x+i,y:n.node.center.y+r}],layer:\"hd_node_markers\",strokeColor:c,strokeWidth:.16,label:a},{points:[{x:n.node.center.x-i,y:n.node.center.y+r},{x:n.node.center.x+i,y:n.node.center.y-r}],layer:\"hd_node_markers\",strokeColor:c,strokeWidth:.16,label:a})}}return t}},EX=class extends xX{hdCacheBaseUrl;hdCacheFetch;constructor(t,e={}){super(t,{...e,maxNodeDimension:e.maxNodeDimension??7,maxNodeRatio:e.maxNodeRatio??4}),this.hdCacheBaseUrl=e.hdCacheBaseUrl??\"https://hd-cache.tscircuit.com\",this.hdCacheFetch=e.hdCacheFetch,this.replaceHighDensityPipelineStep()}replaceHighDensityPipelineStep(){const t=this.pipelineDef.findIndex(t=\u003e\"highDensityRouteSolver\"===t.solverName);if(-1===t)throw new Error(\"Pipeline4 highDensityRouteSolver step is missing\");this.pipelineDef[t]={...this.pipelineDef[t],solverClass:RX,getConstructorParams:t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length\u003e0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,hdCacheBaseUrl:t.hdCacheBaseUrl,fetchImpl:t.hdCacheFetch}]}}}async stepAsync(){if(this.solved||this.failed)return;this.step();const t=vX(this);0!==t.length\u0026\u0026(await Promise.race(t.map(t=\u003et.promise.then(()=\u003et.name,()=\u003et.name))),this.solved||this.failed||this.step())}async solveAsync(){const t=Date.now();for(;!this.solved\u0026\u0026!this.failed;)await this.stepAsync();this.timeToSolve=Date.now()-t}solve(){throw new Error(\"AutoroutingPipelineSolver5_HdCache requires async execution. Use solveAsync() or stepAsync().\")}},AX=1e-9,OX=Math.PI/2,kX=(t,e)=\u003et.x*e.y-t.y*e.x,LX=(t,e)=\u003et.x*e.x+t.y*e.y,DX=t=\u003e{let e=t%OX;return e\u003c0\u0026\u0026(e+=OX),OX-e\u003c1e-8?0:e},zX=t=\u003e{const e=Math.cos(t),n=Math.sin(t);return{u:{x:e,y:n},v:{x:-n,y:e}}},FX=t=\u003e{let e=0;for(let n=0;n\u003ct.length;n++){const o=t[n],i=t[(n+1)%t.length];e+=o.x*i.y-i.x*o.y}return e/2},BX=t=\u003eMath.abs(FX(t)),jX=t=\u003e{const e=FX(t);if(Math.abs(e)\u003cAX){const e=t.reduce((t,e)=\u003e({x:t.x+e.x,y:t.y+e.y}),{x:0,y:0});return{x:e.x/Math.max(1,t.length),y:e.y/Math.max(1,t.length)}}let n=0,o=0;for(let e=0;e\u003ct.length;e++){const i=t[e],r=t[(e+1)%t.length],s=i.x*r.y-r.x*i.y;n+=(i.x+r.x)*s,o+=(i.y+r.y)*s}const i=1/(6*e);return{x:n*i,y:o*i}},$X=t=\u003eFX(t)\u003e=0?[...t]:[...t].reverse(),YX=(t,e)=\u003e{const n=new Set;n.add(0);for(let t=0;t\u003c90;t++)n.add(t/90*OX);for(let e=0;e\u003ct.length;e++){const o=t[e],i=t[(e+1)%t.length],r=Math.atan2(i.y-o.y,i.x-o.x);n.add(DX(r)),n.add(DX(r+OX))}const o=n=\u003e{const o=((t,e=jX(t),n=0)=\u003e{const o=$X(t),{u:i,v:r}=zX(n),s=o.map((t,n)=\u003e{const s=o[(n+1)%o.length],a=s.x-t.x,c=s.y-t.y,l={x:a,y:c};return{hxCoeff:Math.abs(kX(l,i)),hyCoeff:Math.abs(kX(l,r)),limit:a*(e.y-t.y)-c*(e.x-t.x)}});if(s.some(t=\u003et.limit\u003c-1e-7))throw new Error(\"Projected rect center is outside polygon\");let a=Number.POSITIVE_INFINITY;for(const t of s)t.hxCoeff\u003eAX\u0026\u0026(a=Math.min(a,t.limit/t.hxCoeff));if(!Number.isFinite(a)||a\u003c=AX)return{center:e,width:1e-6,height:1e-6,ccwRotationRadians:n,ccwRotationDegrees:180*n/Math.PI};const c=t=\u003e{let e=Number.POSITIVE_INFINITY;for(const n of s){const o=n.limit-n.hxCoeff*t;if(o\u003c-1e-8)return 0;n.hyCoeff\u003eAX\u0026\u0026(e=Math.min(e,o/n.hyCoeff))}return Number.isFinite(e)?Math.max(0,e):0},l=t=\u003et*c(t);let d=0,h=a;for(let t=0;t\u003c80;t++){const t=d+(h-d)/3,e=h-(h-d)/3;l(t)\u003cl(e)?d=t:h=e}const u=(d+h)/2,p=c(u);return{center:e,width:Math.max(1e-6,2*u),height:Math.max(1e-6,2*p),ccwRotationRadians:n,ccwRotationDegrees:180*n/Math.PI}})(t,e,n);return{rect:o,area:o.width*o.height}};let i=o(0),r=0;for(const t of n){const e=o(t);e.area\u003ei.area+1e-8\u0026\u0026(i=e,r=t)}const s=OX/90;let a=r-s,c=r+s;for(let t=0;t\u003c60;t++){const t=a+(c-a)/3,e=c-(c-a)/3;o(t).area\u003co(e).area?a=t:c=e}const l=o(DX((a+c)/2));return l.area\u003ei.area+1e-8?l.rect:i.rect},XX=(t,e,n,o)=\u003e{const i=o.x-n.x,r=o.y-n.y,s=e.x*r-e.y*i;if(Math.abs(s)\u003cAX)return;const a=n.x-t.x,c=n.y-t.y,l=(a*r-c*i)/s,d=(a*e.y-c*e.x)/s;return l\u003c-1e-8||d\u003c-1e-8||d\u003e1+1e-8?void 0:{x:t.x+e.x*l,y:t.y+e.y*l,rayT:l}},VX=(t,e)=\u003e{const n=[],o=[];for(let i=0;i\u003c4;i++){const{x:r,y:s}=t[i],a=e[i].x,c=e[i].y;n.push([r,s,1,0,0,0,-a*r,-a*s]),o.push(a),n.push([0,0,0,r,s,1,-c*r,-c*s]),o.push(c)}const i=((t,e)=\u003e{const n=e.length,o=t.map((t,n)=\u003e[...t,e[n]]);for(let t=0;t\u003cn;t++){let e=t;for(let i=t+1;i\u003cn;i++)Math.abs(o[i][t])\u003eMath.abs(o[e][t])\u0026\u0026(e=i);if(Math.abs(o[e][t])\u003cAX)throw new Error(\"Could not solve homography\");[o[t],o[e]]=[o[e],o[t]];const i=o[t][t];for(let e=t;e\u003c=n;e++)o[t][e]=o[t][e]/i;for(let e=0;e\u003cn;e++){if(e===t)continue;const i=o[e][t];for(let r=t;r\u003c=n;r++)o[e][r]=o[e][r]-i*o[t][r]}}return o.map(t=\u003et[n])})(n,o);return[i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7],1]},WX=(t,e)=\u003e{const n=Math.cos(e),o=Math.sin(e);return[n,-o,t.x-n*t.x+o*t.y,o,n,t.y-o*t.x-n*t.y,0,0,1]},HX=(t,e)=\u003e{const n=t[6]*e.x+t[7]*e.y+t[8];return Math.abs(n)\u003cAX?{x:e.x,y:e.y}:{x:(t[0]*e.x+t[1]*e.y+t[2])/n,y:(t[3]*e.x+t[4]*e.y+t[5])/n}},GX=(t,e,n)=\u003e{const{u:o,v:i}=zX(n);return{x:e.x+t.x*o.x+t.y*i.x,y:e.y+t.x*o.y+t.y*i.y}},UX=(t,e)=\u003eGX({x:t.x-e.center.x,y:t.y-e.center.y},e.center,e.ccwRotationRadians),ZX=(t,e)=\u003e{const n=((t,e,n)=\u003e{const{u:o,v:i}=zX(n),r={x:t.x-e.x,y:t.y-e.y};return{x:LX(r,o),y:LX(r,i)}})(t,e.center,e.ccwRotationRadians);if(Math.abs(n.x)\u003cAX\u0026\u0026Math.abs(n.y)\u003cAX)return{...e.center};const o=e.width/2,i=e.height/2,r=Math.abs(n.x)\u003eAX?o/Math.abs(n.x):1/0,s=Math.abs(n.y)\u003eAX?i/Math.abs(n.y):1/0,a=Math.min(r,s);return{x:e.center.x+n.x*a,y:e.center.y+n.y*a}},qX=(t,e=0,n=0)=\u003e{const o=((t,e)=\u003e{const n=$X(e);for(let e=0;e\u003cn.length;e++){const o=n[e],i=n[(e+1)%n.length];if((i.x-o.x)*(t.y-o.y)-(i.y-o.y)*(t.x-o.x)\u003c-1e-7)return!1}return!0})(jX(t),t)?[...t]:(t=\u003e{const e=[...t].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e.x-t.x)\u003c1e-9\u0026\u0026Math.abs(e.y-t.y)\u003c1e-9)===e).sort((t,e)=\u003et.x-e.x||t.y-e.y);if(e.length\u003c=3)return e;const n=(t,e,n)=\u003e(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),o=[];for(const t of e){for(;o.length\u003e=2\u0026\u0026n(o[o.length-2],o[o.length-1],t)\u003c=1e-9;)o.pop();o.push(t)}const i=[];for(let t=e.length-1;t\u003e=0;t--){const o=e[t];for(;i.length\u003e=2\u0026\u0026n(i[i.length-2],i[i.length-1],o)\u003c=1e-9;)i.pop();i.push(o)}return o.pop(),i.pop(),[...o,...i]})(t),i=jX(o),r=YX(o,i),s=BX(o),a=r.width*r.height,c=(l=e,Math.max(0,l));var l;const d=a+Math.max(0,s-a)*c,h=a\u003eAX\u0026\u0026d\u003ea?Math.sqrt(d/a):1,u=Math.max(0,n),p=Math.max(r.width*h,u),m=Math.max(r.height*h,u),g=DX(r.ccwRotationRadians),f=180*g/Math.PI,y=(t=\u003e{const e=t.width/2,n=t.height/2;return[{x:t.center.x-e,y:t.center.y-n},{x:t.center.x+e,y:t.center.y-n},{x:t.center.x+e,y:t.center.y+n},{x:t.center.x-e,y:t.center.y+n}]})({center:i,width:p,height:m}),_=(t=\u003e{const e=t.width/2,n=t.height/2;return[GX({x:-e,y:-n},t.center,t.ccwRotationRadians),GX({x:e,y:-n},t.center,t.ccwRotationRadians),GX({x:e,y:n},t.center,t.ccwRotationRadians),GX({x:-e,y:n},t.center,t.ccwRotationRadians)]})({center:i,width:p,height:m,ccwRotationRadians:g}),b=_.map(t=\u003e{const e={x:t.x-i.x,y:t.y-i.y},n=((t,e,n)=\u003e{let o;for(let i=0;i\u003cn.length;i++){const r=XX(t,e,n[i],n[(i+1)%n.length]);r\u0026\u0026(!o||r.rayT\u003co.rayT)\u0026\u0026(o=r)}return o})(i,e,o);return n?{x:n.x,y:n.y}:t});let x=BX(b)\u003eAX?b:_;let v,S;try{v=VX(y,x),S=(t=\u003e{const[e,n,o,i,r,s,a,c,l]=t,d=r*l-s*c,h=-(i*l-s*a),u=i*c-r*a,p=-(n*l-o*c),m=e*l-o*a,g=-(e*c-n*a),f=n*s-o*r,y=-(e*s-o*i),_=e*r-n*i,b=e*d+n*h+o*u;if(Math.abs(b)\u003cAX)throw new Error(\"Cannot invert singular 3x3 matrix\");const x=1/b;return[d*x,p*x,f*x,h*x,m*x,y*x,u*x,g*x,_*x]})(v)}catch{x=_,v=WX(i,g),S=WX(i,-g)}return{center:i,width:p,height:m,innerWidth:r.width,innerHeight:r.height,ccwRotationDegrees:f,ccwRotationRadians:g,polygonArea:s,equivalentAreaExpansionFactor:c,targetQuad:x,rectToPolygonMatrix:v,polygonToRectMatrix:S}},JX=class extends si{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1}params;getSolverName(){return\"AttachProjectedRectsSolver\"}outputNodes=[];projectionAdjustmentByNodeId=new Map;_step(){this.projectionAdjustmentByNodeId.clear(),this.outputNodes=this.params.nodesWithPortPoints.map(t=\u003e{const e=this.params.equivalentAreaExpansionFactor??0,n=this.params.minProjectedRectDimension??0,o=(({traceWidth:t,viaDiameter:e,obstacleMargin:n,minProjectedRectDimension:o})=\u003eMath.max(o,e??0,(t??0)+2*(n??0)))({traceWidth:this.params.traceWidth,viaDiameter:this.params.viaDiameter,obstacleMargin:this.params.obstacleMargin,minProjectedRectDimension:n});let i=qX(t.polygon,e,n);if(Math.min(i.width,i.height)\u003eo+(this.params.traceWidth??0))return{...t,center:i.center,width:i.width,height:i.height,projectedRect:i};const r=qX(t.polygon,1,n);return(({node:t,projectedRect:e,conservativeProjectedRect:n,requiredRoutingCorridorWidth:o,traceWidth:i})=\u003e{if(o\u003c=0)return!1;const r=Math.min(e.width,e.height),s=Math.min(n.width,n.height),a=Math.max(e.width,e.height),c=Math.max(n.width,n.height),l=o+(i??0),d=Math.floor(r/o),h=Math.floor(s/o);return new Set(t.portPoints.map(t=\u003et.connectionName)).size\u003e1\u0026\u0026d\u003c=h\u0026\u0026r\u003c=l\u0026\u0026a-c\u003e=o\u0026\u0026e.equivalentAreaExpansionFactor\u003e1})({node:t,projectedRect:i,conservativeProjectedRect:r,requiredRoutingCorridorWidth:o,traceWidth:this.params.traceWidth})\u0026\u0026(i=r,this.projectionAdjustmentByNodeId.set(t.capacityMeshNodeId,\"corridor-expansion-factor-1\")),{...t,center:i.center,width:i.width,height:i.height,projectedRect:i}}),this.solved=!0}getOutput(){return this.outputNodes}getConstructorParams(){return[this.params]}visualize(){const t=this.outputNodes.length\u003e0?this.outputNodes:this.params.nodesWithPortPoints;return{polygons:t.map(t=\u003e({points:t.polygon,fill:\"rgba(40, 140, 220, 0.06)\",stroke:\"rgba(20, 70, 160, 0.95)\",strokeWidth:.04,label:`${t.capacityMeshNodeId} polygon`})),lines:t.map(t=\u003e({points:[...t.polygon,t.polygon[0]],strokeColor:\"rgba(20, 70, 160, 0.95)\",strokeWidth:.04,label:`${t.capacityMeshNodeId} polygon outline`})),rects:t.flatMap(t=\u003et.projectedRect?[{center:t.projectedRect.center,width:t.projectedRect.width,height:t.projectedRect.height,ccwRotationDegrees:t.projectedRect.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.16)\",stroke:\"rgba(255, 140, 0, 0.8)\",label:`${t.capacityMeshNodeId} projectedRect`}]:[]),points:t.flatMap(t=\u003et.portPoints.map(t=\u003e({x:t.x,y:t.y,color:\"rgba(30, 30, 30, 0.85)\",label:t.connectionName})))}}},KX=class extends si{constructor(t){super(),this.params=t;const{nodeWithPortPoints:e}=t;if(!e.projectedRect)throw new Error(\"Poly node is missing projectedRect\");this.projectedPorts=e.portPoints.map(t=\u003e{const n=ZX(t,e.projectedRect);return{original:t,projected:{...t,x:n.x,y:n.y}}}),this.projectedNode={capacityMeshNodeId:e.capacityMeshNodeId,center:e.projectedRect.center,width:e.projectedRect.width,height:e.projectedRect.height,availableZ:e.availableZ,portPoints:this.projectedPorts.map(({projected:t})=\u003et)},this.highDensitySolver=new Ss({nodeWithPortPoints:this.projectedNode,colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort}),this.activeSubSolver=this.highDensitySolver,this.MAX_ITERATIONS=this.highDensitySolver.MAX_ITERATIONS+1e3}params;getSolverName(){return\"PolySingleIntraNodeSolver\"}highDensitySolver;projectedNode;solvedRoutes=[];projectedPorts;_step(){this.highDensitySolver.step(),this.progress=this.highDensitySolver.progress,this.stats=this.highDensitySolver.stats,this.highDensitySolver.solved?(this.solvedRoutes=this.highDensitySolver.solvedRoutes,this.solved=!0,this.activeSubSolver=null):this.highDensitySolver.failed\u0026\u0026(this.error=this.highDensitySolver.error,this.failed=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.params]}visualize(){const t=this.params.nodeWithPortPoints,e=t.projectedRect,n={polygons:[{points:t.polygon,fill:\"rgba(60, 160, 220, 0.10)\",stroke:\"rgba(40, 90, 150, 0.7)\",label:`${t.capacityMeshNodeId} polygon`},...e?[{points:e.targetQuad,fill:\"rgba(255, 165, 0, 0.08)\",stroke:\"rgba(255, 120, 0, 0.65)\",label:`${t.capacityMeshNodeId} distortion target`}]:[]],rects:e?[{center:e.center,width:e.width,height:e.height,ccwRotationDegrees:e.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.14)\",stroke:\"rgba(255, 120, 0, 0.8)\",label:`${t.capacityMeshNodeId} projectedRect`}]:[],points:[...t.portPoints.map(t=\u003e({x:t.x,y:t.y,color:\"rgba(0, 80, 160, 0.85)\",label:`${t.connectionName} original`})),...this.projectedPorts.map(({projected:t})=\u003e({x:t.x,y:t.y,color:\"rgba(255, 120, 0, 0.85)\",label:`${t.connectionName} projected`}))]};return pi(n,this.highDensitySolver.visualize())}},QX=class extends si{getSolverName(){return\"PolyHighDensitySolver\"}unsolvedNodePortPoints;nodePortPoints;routes=[];routesByNodeId=new Map;failedSolvers=[];activeSubSolver=null;colorMap;connMap;viaDiameter;traceWidth;obstacleMargin;effort;nodePfById;constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a}){super(),this.nodePortPoints=[...t],this.unsolvedNodePortPoints=[...t],this.colorMap=e??{},this.connMap=n,this.viaDiameter=o??.3,this.traceWidth=i??.15,this.obstacleMargin=r??.15,this.effort=s??1,this.MAX_ITERATIONS=1e7*this.effort,this.nodePfById=a instanceof Map?new Map(a):new Map(Object.entries(a??{}))}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){const t=this.activeSubSolver.params.nodeWithPortPoints.capacityMeshNodeId,e=this.activeSubSolver.solvedRoutes;this.routesByNodeId.set(t,[...this.routesByNodeId.get(t)??[],...e]),this.routes.push(...this.activeSubSolver.solvedRoutes),this.activeSubSolver=null}else this.activeSubSolver.failed\u0026\u0026(this.failedSolvers.push(this.activeSubSolver),this.activeSubSolver=null);return}if(0===this.unsolvedNodePortPoints.length)return this.failedSolvers.length\u003e0?(this.failed=!0,void(this.error=`Failed to solve ${this.failedSolvers.length} poly nodes, ${this.failedSolvers.slice(0,5).map(t=\u003et.params.nodeWithPortPoints.capacityMeshNodeId).join(\", \")}. err0: ${this.failedSolvers[0]?.error}`)):void(this.solved=!0);const t=this.unsolvedNodePortPoints.pop();this.activeSubSolver=new KX({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort})}computeProgress(){const t=this.routes.length+this.failedSolvers.length+this.unsolvedNodePortPoints.length+(this.activeSubSolver?1:0);return 0===t?1:(this.routes.length+this.failedSolvers.length+(this.activeSubSolver?.progress??0))/t}getConstructorParams(){return[{nodePortPoints:this.nodePortPoints,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById}]}visualize(){const t={polygons:this.nodePortPoints.map(t=\u003e({points:t.polygon,fill:\"rgba(180, 180, 180, 0.05)\",stroke:\"rgba(120, 120, 120, 0.25)\",label:`${t.capacityMeshNodeId} polygon`})),rects:this.nodePortPoints.flatMap(t=\u003et.projectedRect?[{center:t.projectedRect.center,width:t.projectedRect.width,height:t.projectedRect.height,ccwRotationDegrees:t.projectedRect.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.08)\",stroke:\"rgba(255, 120, 0, 0.65)\",label:`${t.capacityMeshNodeId} projectedRect`}]:[]),lines:[],circles:[],points:this.nodePortPoints.flatMap(t=\u003et.portPoints.map(t=\u003e({x:t.x,y:t.y,color:\"rgba(80, 80, 80, 0.5)\",label:`${t.connectionName} original`})))};for(const[e,n]of this.routesByNodeId){const o=this.nodePortPoints.find(t=\u003et.capacityMeshNodeId===e),i=o?.projectedRect;if(i)for(const e of n){const n=this.colorMap[e.connectionName]??\"#0000ff\",o={...e,route:e.route.map(t=\u003e({...t,...UX(t,i)})),vias:e.vias.map(t=\u003eUX(t,i))},r=mi(o.route,e.connectionName,n);for(const n of r)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:To(n.color,.5),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?[.1,.3]:void 0});for(const i of o.vias)t.circles.push({center:i,layer:\"z0,1\",radius:e.viaDiameter/2,fill:n,label:`${e.connectionName} via`})}}const e=this.activeSubSolver?.visualize();return e\u0026\u0026t.polygons.push(...this.unsolvedNodePortPoints.map(t=\u003e({points:t.polygon,fill:\"rgba(180, 180, 180, 0.08)\",stroke:\"rgba(120, 120, 120, 0.4)\",label:t.capacityMeshNodeId}))),e?pi(t,e):t}},tV=t=\u003e{const{o:e,a:n,b:o}=t;return(n.x-e.x)*(o.y-e.y)-(n.y-e.y)*(o.x-e.x)},eV=(t,e)=\u003e{const n=[...new Set(t)].map(t=\u003e{const n=e[t];return n?{i:t,x:n.x,y:n.y}:null}).filter(t=\u003enull!==t);if(n.sort((t,e)=\u003et.x-e.x||t.y-e.y),n.length\u003c=2)return n.map(t=\u003et.i);const o=[],i=[];for(const t of n){for(;o.length\u003e=2;){const e=o[o.length-2],n=o[o.length-1];if(!e||!n||tV({o:e,a:n,b:t})\u003e1e-10)break;o.pop()}o.push(t)}for(let t=n.length-1;t\u003e=0;t--){const e=n[t];if(e){for(;i.length\u003e=2;){const t=i[i.length-2],n=i[i.length-1];if(!t||!n||tV({o:t,a:n,b:e})\u003e1e-10)break;i.pop()}i.push(e)}}return o.pop(),i.pop(),o.concat(i).map(t=\u003et.i)},nV=t=\u003e{const e=Math.max(0,Math.min(30,Math.floor(t)));return 0===e?0:(1\u003c\u003ce)-1},oV=(t,e=31)=\u003e{const n=[],o=Math.max(0,Math.min(31,Math.floor(e)));for(let e=0;e\u003co;e++)t\u00261\u003c\u003ce\u0026\u0026n.push(e);return n},iV=t=\u003e{let e=0;for(const n of t)Number.isInteger(n)\u0026\u0026n\u003e=0\u0026\u0026n\u003c31\u0026\u0026(e|=1\u003c\u003cn);return e},rV=(t,e)=\u003e{const n=t.trim().toLowerCase();if(\"top\"===n)return 0;if(\"bottom\"===n)return Math.max(0,e-1);const o=n.match(/^inner(\\d+)$/);if(o?.[1]){const t=Number(o[1]);return t\u003e=0\u0026\u0026t\u003ce?t:void 0}const i=n.match(/^layer(\\d+)$/);if(i?.[1]){const t=Number(i[1])-1;return t\u003e=0\u0026\u0026t\u003ce?t:void 0}const r=n.match(/^z(\\d+)$/);if(r?.[1]){const t=Number(r[1]);return t\u003e=0\u0026\u0026t\u003ce?t:void 0}},sV=(t,e)=\u003e{const n=nV(e),o=t.zLayers;if(Array.isArray(o)\u0026\u0026o.length\u003e0)return iV(o)\u0026n;const i=t.layers;if(Array.isArray(i)\u0026\u0026i.length\u003e0){let t=0;for(const n of i){const o=rV(n,e);void 0!==o\u0026\u0026(t|=1\u003c\u003co)}return t\u0026n}return n},aV=.1,cV=.15,lV=aV+cV,dV=3*lV/4,hV=5,uV=1e-9,pV=t=\u003eMath.round(1e6*t)/1e6,mV=t=\u003e`${pV(t.x)},${pV(t.y)}`,gV=(t,e)=\u003e{const n=mV(t),o=mV(e);return n\u003co?`${n}|${o}`:`${o}|${n}`},fV=t=\u003e{let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t)e=Math.min(e,r.x),n=Math.max(n,r.x),o=Math.min(o,r.y),i=Math.max(i,r.y);return{minX:e,maxX:n,minY:o,maxY:i}},yV=(t,e)=\u003e{const n=t.x\u003ce.minX?e.minX-t.x:t.x\u003ee.maxX?t.x-e.maxX:0,o=t.y\u003ce.minY?e.minY-t.y:t.y\u003ee.maxY?t.y-e.maxY:0;return n*n+o*o},_V=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c1e-18)return!1;const s=((t.x-e.x)*o+(t.y-e.y)*i)/r;if(s\u003c-1e-9||s\u003e1+1e-9)return!1;const a=e.x+s*o,c=e.y+s*i;return(t.x-a)**2+(t.y-c)**2\u003c1e-12},bV=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003cuV)return(t.x-e.x)**2+(t.y-e.y)**2;const s=Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r)),a=e.x+s*o,c=e.y+s*i;return(t.x-a)**2+(t.y-c)**2},xV=(t,e)=\u003e({x:(t.x+e.x)/2,y:(t.y+e.y)/2}),vV=(t,e,n,o=.001)=\u003e{const i=o*o;return((t,e)=\u003e{let n=Number.POSITIVE_INFINITY;for(let o=0;o\u003ce.length;o++){const i=e[o],r=e[(o+1)%e.length];n=Math.min(n,bV(t,i,r))}return n})(xV(t,e),n)\u003c=i},SV=(t,e)=\u003e{let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];if(_V(t,r,s))return!0;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y+1e-12)+r.x\u0026\u0026(n=!n)}return n},IV=(t,e,n,o)=\u003e{const i=e.x-t.x,r=e.y-t.y,s=o.x-n.x,a=o.y-n.y,c=i*a-r*s;if(Math.abs(c)\u003cuV){for(const i of[t,e])if(_V(i,n,o))return i;for(const i of[n,o])if(_V(i,t,e))return i;return}const l=((n.x-t.x)*a-(n.y-t.y)*s)/c,d=((n.x-t.x)*r-(n.y-t.y)*i)/c;if(!(l\u003c-1e-9||l\u003e1.000000001||d\u003c-1e-9||d\u003e1.000000001))return{x:t.x+l*i,y:t.y+l*r}},CV=(t,e)=\u003e{for(const n of t)if(SV(n,e))return n;for(const n of e)if(SV(n,t))return n;for(let n=0;n\u003ct.length;n++){const o=t[n],i=t[(n+1)%t.length];for(let t=0;t\u003ce.length;t++){const n=e[t],r=e[(t+1)%e.length],s=IV(o,i,n,r);if(s)return s}}},PV=(t,e=1e-6)=\u003e[{x:t.x-e,y:t.y-e},{x:t.x+e,y:t.y-e},{x:t.x,y:t.y+e}],MV=(t,e,n,o,i)=\u003e{const r=e.x-t.x,s=e.y-t.y,a=Math.hypot(r,s);if(a\u003cuV)return[];const c=Number.isFinite(n)\u0026\u0026n\u003euV?n:lV,l=Number.isFinite(o)?Math.max(0,o):dV,d=Math.min(l,a/2),h=a-2*d;if(h\u003c=.75*c)return[{x:(t.x+e.x)/2,y:(t.y+e.y)/2,distToCentermostPortOnZ:0,cramped:!0}];const u=Math.max(1,Math.floor(h/c)+1),p=Number.isFinite(i)\u0026\u0026i\u003e0?Math.floor(i):hV,m=u\u003ep?p+Math.floor(u/4):u;if(m\u003c=1)return[{x:(t.x+e.x)/2,y:(t.y+e.y)/2,distToCentermostPortOnZ:0,cramped:!1}];const g=a/2,f=Array.from({length:m},(e,n)=\u003e{const o=d+h*n/(m-1),i=o/a;return{x:t.x+r*i,y:t.y+s*i,distanceFromStart:o}}),y=f.reduce((t,e)=\u003eMath.abs(e.distanceFromStart-g)\u003cMath.abs(t-g)?e.distanceFromStart:t,f[0].distanceFromStart);return f.map(({x:t,y:e,distanceFromStart:n})=\u003e({x:t,y:e,distToCentermostPortOnZ:Math.abs(n-y),cramped:!1}))},NV=(t,e)=\u003e{if(!(Math.hypot(e.x-t.x,e.y-t.y)\u003cuV))return{...xV(t,e),distToCentermostPortOnZ:0,cramped:!1}},wV=(t,e)=\u003e{if(\"object\"!=typeof t||null===t)return;const n=t[e];return\"string\"==typeof n?n:void 0},TV=t=\u003e{const e=new Set,n=t=\u003e{\"string\"==typeof t\u0026\u0026t.length\u003e0\u0026\u0026e.add(t)},o=t=\u003e{n(t.pointId),n(t.pcb_port_id)};n(t.connectionId),n(t.mutuallyConnectedNetworkId),o(t.start),o(t.end);const i=t.simpleRouteConnection;n(wV(i,\"name\")),n(wV(i,\"source_trace_id\")),n(wV(i,\"rootConnectionName\"));const r=\"object\"==typeof i\u0026\u0026null!==i?i.pointsToConnect:void 0;if(Array.isArray(r))for(const t of r)o(t);return e},RV=t=\u003e{const{regions:e,availableZ:n,layerCount:o,connections:i=[],obstacleRegions:r=[],regionIdPrefix:s=\"free\",portIdPrefix:a=\"shared-port\",traceWidth:c=aV,obstacleMargin:l=cV,portSpacing:d=c+l,portMarginFromSegmentEndpoint:h=3*d/4,maxDensePortsBeforeDecimation:u=hV}=t,p=Array.from({length:o},(t,e)=\u003ee),m=new Map,g=new Map,f=t=\u003et.mutuallyConnectedNetworkId??t.connectionId;for(const t of i){const e=f(t);let n=m.get(e);void 0===n\u0026\u0026(n=m.size,m.set(e,n));for(const e of TV(t))g.has(e)||g.set(e,n)}const y=e.map((t,e)=\u003e{const o=fV(t);return{regionId:`${s}-${e}`,pointIds:[],d:{polygon:t,availableZ:n?.[e]??p,center:{x:(o.minX+o.maxX)/2,y:(o.minY+o.maxY)/2},width:o.maxX-o.minX,height:o.maxY-o.minY}}}),_=y.map((t,e)=\u003e({regionId:t.regionId,serializedRegionIndex:e,polygon:t.d.polygon,availableZ:t.d.availableZ,bounds:fV(t.d.polygon),isObstacle:!1,netId:void 0})),b=r.flatMap((t,e)=\u003e{if(t.polygon.length\u003c3)return[];const n=(t=\u003e{if(Number.isInteger(t.netId)\u0026\u0026t.netId\u003e=0)return t.netId;if(\"string\"==typeof t.mutuallyConnectedNetworkId)return m.get(t.mutuallyConnectedNetworkId);for(const e of t.connectedTo??[]){const t=g.get(e);if(void 0!==t)return t}})(t);if(void 0===n)return[];const o=t.polygon,i=fV(o),r=t.availableZ??p,s=t.regionId??`obstacle-${e}`,a=y.length;y.push({regionId:s,pointIds:[],d:{...t.d??{},polygon:o,availableZ:r,center:{x:(i.minX+i.maxX)/2,y:(i.minY+i.maxY)/2},width:i.maxX-i.minX,height:i.maxY-i.minY,_containsObstacle:!0,_containsTarget:!0,netId:n}});const c={regionId:s,serializedRegionIndex:a,polygon:o,availableZ:r,bounds:i,isObstacle:!0,netId:n};return _.push(c),[c]}),x=[],v=new Map;for(let t=0;t\u003ce.length;t++){const n=e[t];for(let e=0;e\u003cn.length;e++){const o=n[e],i=n[(e+1)%n.length],r=gV(o,i),s=v.get(r)??[];s.push({regionIndex:t,a:o,b:i}),v.set(r,s)}}let S=0;const I=t=\u003e{const{region1Id:e,region2Id:n,pointIndex:o,portPoint:i,z:r,portIdSuffix:s}=t,c=`${a}-${String(S).padStart(5,\"0\")}::p${o}::z${r}${s??\"\"}`;return x.push({portId:c,region1Id:e,region2Id:n,d:{portId:c,x:i.x,y:i.y,z:r,distToCentermostPortOnZ:i.distToCentermostPortOnZ,...i.cramped?{cramped:!0}:{}}}),S+=1,c};for(const t of v.values()){if(2!==t.length)continue;const[e,o]=t,i=n?.[e.regionIndex]??p,r=n?.[o.regionIndex]??p,a=i.filter(t=\u003er.includes(t));if(0===a.length)continue;const c=MV(e.a,e.b,d,h,u);if(0!==c.length)for(let t=0;t\u003cc.length;t++){const n=c[t];for(const i of a){if(b.some(t=\u003et.availableZ.includes(i)\u0026\u0026vV(e.a,e.b,t.polygon)))continue;const r=I({region1Id:`${s}-${e.regionIndex}`,region2Id:`${s}-${o.regionIndex}`,pointIndex:t,portPoint:n,z:i});y[e.regionIndex].pointIds.push(r),y[o.regionIndex].pointIds.push(r)}}}for(const t of b)for(const e of v.values())for(const o of e){if(!vV(o.a,o.b,t.polygon))continue;const e=(n?.[o.regionIndex]??p).filter(e=\u003et.availableZ.includes(e));if(0===e.length)continue;const i=NV(o.a,o.b);if(i)for(const n of e){const e=I({region1Id:`${s}-${o.regionIndex}`,region2Id:t.regionId,pointIndex:0,portPoint:i,z:n,portIdSuffix:\"::obstacle\"});y[o.regionIndex].pointIds.push(e),y[t.serializedRegionIndex].pointIds.push(e)}}for(let t=0;t\u003cb.length;t++){const e=b[t];for(let n=t+1;n\u003cb.length;n++){const t=b[n];if(e.netId!==t.netId)continue;const o=e.availableZ.filter(e=\u003et.availableZ.includes(e));if(0===o.length)continue;const i=CV(e.polygon,t.polygon);if(i)for(const n of o){const o=I({region1Id:e.regionId,region2Id:t.regionId,pointIndex:0,portPoint:{x:i.x,y:i.y,distToCentermostPortOnZ:0},z:n,portIdSuffix:\"::obstacle-contact\"});y[e.serializedRegionIndex].pointIds.push(o),y[t.serializedRegionIndex].pointIds.push(o)}}}const C=(t,e)=\u003e{const n=((t,e)=\u003e{if(Number.isInteger(t.z)\u0026\u0026t.z\u003e=0\u0026\u0026t.z\u003ce)return[t.z];if(Array.isArray(t.zLayers)\u0026\u0026t.zLayers.length\u003e0)return t.zLayers.filter(t=\u003eNumber.isInteger(t)\u0026\u0026t\u003e=0\u0026\u0026t\u003ce);if(\"string\"==typeof t.layer){const n=rV(t.layer,e);return void 0===n?[]:[n]}return Array.isArray(t.layers)\u0026\u0026t.layers.length\u003e0?t.layers.map(t=\u003erV(t,e)).filter(t=\u003evoid 0!==t):[0]})(t,o);let i;const r=_.filter(t=\u003et.isObstacle\u0026\u0026(void 0===e||t.netId===e));for(const e of r){const o=n.find(t=\u003ee.availableZ.includes(t))??e.availableZ[0];if(void 0!==o\u0026\u0026SV(t,e.polygon))return{regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o}}for(const e of _.filter(t=\u003e!t.isObstacle)){const o=n.find(t=\u003ee.availableZ.includes(t))??e.availableZ[0];if(void 0===o)continue;if(SV(t,e.polygon))return{regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o};const r=yV(t,e.bounds);(!i||r\u003ci.distanceSq)\u0026\u0026(i={regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o,distanceSq:r})}return i},P=[];for(const t of i){const e=m.get(f(t)),n=C(t.start,e),o=C(t.end,e);if(!n||!o)throw new Error(`Could not map connection \"${t.connectionId}\" endpoint into a generated region`);const i=`terminal-start-${t.connectionId}`,r=`terminal-end-${t.connectionId}`,s=`terminal-start-port-${t.connectionId}`,a=`terminal-end-port-${t.connectionId}`;y.push({regionId:i,pointIds:[s],d:{polygon:PV(t.start),availableZ:[n.z],center:{x:t.start.x,y:t.start.y},width:1e-6,height:1e-6,_containsTarget:!0}}),y.push({regionId:r,pointIds:[a],d:{polygon:PV(t.end),availableZ:[o.z],center:{x:t.end.x,y:t.end.y},width:1e-6,height:1e-6,_containsTarget:!0}}),x.push({portId:s,region1Id:n.regionId,region2Id:i,d:{portId:s,x:t.start.x,y:t.start.y,z:n.z,distToCentermostPortOnZ:0}}),x.push({portId:a,region1Id:o.regionId,region2Id:r,d:{portId:a,x:t.end.x,y:t.end.y,z:o.z,distToCentermostPortOnZ:0}}),y[n.serializedRegionIndex].pointIds.push(s),y[o.serializedRegionIndex].pointIds.push(a),P.push({connectionId:t.connectionId,mutuallyConnectedNetworkId:t.mutuallyConnectedNetworkId,startRegionId:i,endRegionId:r,simpleRouteConnection:t.simpleRouteConnection})}return{regions:y,ports:x,connections:P}},EV=t=\u003e{const{polygon:e,clearance:n,verticesOnly:o=!1}=t,i=e.points,r=i.length;if(r\u003c3)return[];const s=new xO(i.map(t=\u003emO(t.x,t.y))).orientation()===fE.CCW,a=[];for(let t=0;t\u003cr;t++){const e=i[t],o=i[(t+1)%r],c=gO(o.x-e.x,o.y-e.y);if(0===c.length){a.push(_O(mO(e.x,e.y),gO(1,0)));continue}const l=c.normalize(),d=s?gO(l.y,-l.x):gO(-l.y,l.x),h=mO(e.x+n*d.x,e.y+n*d.y);a.push(_O(h,d))}const c=[];for(let t=0;t\u003cr;t++){const e=a[(t-1+r)%r],n=a[t],o=e.intersect(n);if(o.length\u003e0){const t=o[0];c.push({x:t.x,y:t.y})}else c.push({x:n.pt.x,y:n.pt.y})}if(o)return c;const l=[];for(let t=0;t\u003cr;t++){const e=c[t],n=c[(t+1)%r],o=fO(mO(e.x,e.y),mO(n.x,n.y)).length,i=Math.max(2,Math.ceil(o/20));for(let t=0;t\u003ci;t++){const o=t/i;l.push({x:e.x+o*(n.x-e.x),y:e.y+o*(n.y-e.y)})}}return l},AV=t=\u003e{const{localX:e,localY:n,rect:o}=t,i=Math.cos(o.ccwRotation),r=Math.sin(o.ccwRotation);return{x:o.center.x+e*i-n*r,y:o.center.y+e*r+n*i}},OV=t=\u003enew xO(t.map(t=\u003emO(t.x,t.y))),kV=t=\u003e{const e=[];for(const n of t.faces){const t=[];for(const e of n.vertices)t.push({x:e.x,y:e.y});t.length\u003e=3\u0026\u0026e.push(t)}return e},LV=(t,e,n)=\u003e{const o=e.length;e.push(...t);const i=t.length;for(let t=0;t\u003ci;t++)n.push([o+t,o+(t+1)%i])},DV=t=\u003e{const{bounds:e,vias:n,clearance:o,rects:i,polygons:r=[],viaSegments:s=8,preserveObstacleBoundaries:a=!1}=t,c=[],l=[],d=[],{minX:h,maxX:u,minY:p,maxY:m}=e,g=10,f=[];for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:h+e*(u-h),y:p})}for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:u,y:p+e*(m-p)})}for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:u-e*(u-h),y:m})}for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:h,y:m-e*(m-p)})}d.push(l.length),LV(f,c,l);const y=[];for(const t of n){const e=t.diameter/2+o,n=[];for(let o=0;o\u003cs;o++){const i=2*Math.PI*o/s;n.push({x:t.center.x+e*Math.cos(i),y:t.center.y+e*Math.sin(i)})}y.push(n)}for(const t of i){const e=t.width/2+o,n=t.height/2+o,i=[AV({localX:-e,localY:-n,rect:t}),AV({localX:e,localY:-n,rect:t}),AV({localX:e,localY:n,rect:t}),AV({localX:-e,localY:n,rect:t})];y.push(i)}for(const t of r){if(t.points.length\u003c3)continue;const e=EV({polygon:t,clearance:o,verticesOnly:!0});y.push(e)}const _=a?y:(t=\u003e{if(t.length\u003c=1)return t;try{let e=t.map(OV);for(let t=0;t\u003c2;t++){const t=[],n=new Set;for(let o=0;o\u003ce.length;o++){if(n.has(o))continue;let i=e[o];for(let t=o+1;t\u003ce.length;t++){if(n.has(t))continue;const o=i.box,r=e[t].box;if(!(o.xmin\u003er.xmax+1e-6||o.xmax\u003cr.xmin-1e-6||o.ymin\u003er.ymax+1e-6||o.ymax\u003cr.ymin-1e-6))try{const o=WA.unify(i,e[t]);o.faces.size\u003e0\u0026\u0026(i=o,n.add(t))}catch{}}t.push(i),n.add(o)}e=t}const n=[];for(const t of e){const e=kV(t);n.push(...e)}return n.length\u003e0?n:t}catch{return t}})(y);for(const t of _)d.push(l.length),LV(t,c,l);const b=((t,e,n)=\u003e{const o=new Array(e.length);for(let t=0;t\u003ce.length;t++)for(let e=n.length-1;e\u003e=0;e--)if(t\u003e=n[e]){o[t]=e;break}const i=new Map,r=t.slice();for(let t=0;t\u003ce.length;t++)for(let n=t+1;n\u003ce.length;n++){if(o[t]===o[n])continue;const[s,a]=e[t],[c,l]=e[n],d=r[s],h=r[a],u=r[c],p=r[l],m=h.x-d.x,g=h.y-d.y,f=p.x-u.x,y=p.y-u.y,_=m*y-g*f;if(Math.abs(_)\u003c1e-10)continue;const b=((u.x-d.x)*y-(u.y-d.y)*f)/_,x=((u.x-d.x)*g-(u.y-d.y)*m)/_;if(b\u003e1e-6\u0026\u0026b\u003c.999999\u0026\u0026x\u003e1e-6\u0026\u0026x\u003c.999999){const e=d.x+b*m,o=d.y+b*g,s=r.length;r.push({x:e,y:o}),i.has(t)||i.set(t,[]),i.get(t).push({t:b,idx:s}),i.has(n)||i.set(n,[]),i.get(n).push({t:x,idx:s})}}if(0===i.size)return{pts:t,constraintEdges:e,hadCrossings:!1};const s=[];for(let t=0;t\u003ce.length;t++){const n=i.get(t);if(!n||0===n.length){s.push(e[t]);continue}n.sort((t,e)=\u003et.t-e.t);const[o,r]=e[t];let a=o;for(const t of n)s.push([a,t.idx]),a=t.idx;s.push([a,r])}return{pts:r,constraintEdges:s,hadCrossings:!0}})(c,l,d);return{pts:b.pts.map((t,e)=\u003e({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)})),constraintEdges:b.constraintEdges,hadCrossings:b.hadCrossings}},zV=t=\u003e{const{p:e,a:n,b:o}=t,i=o.x-n.x,r=o.y-n.y,s=i*i+r*r;if(s\u003c1e-10)return Math.hypot(e.x-n.x,e.y-n.y);let a=((e.x-n.x)*i+(e.y-n.y)*r)/s;return a=Math.max(0,Math.min(1,a)),Math.hypot(e.x-n.x-a*i,e.y-n.y-a*r)},FV=(t,e)=\u003e{if(t.length\u003c=3)return 0;const n=eV(t,e),o=new Set(n),i=n.map(t=\u003ee[t]).filter(t=\u003eBoolean(t));let r=0;for(const n of t){if(o.has(n))continue;const t=e[n];if(!t)continue;let s=Number.POSITIVE_INFINITY;for(let e=0;e\u003ci.length;e++){const n=i[e],o=i[(e+1)%i.length];n\u0026\u0026o\u0026\u0026(s=Math.min(s,zV({p:t,a:n,b:o})))}r=Math.max(r,s)}return r},BV=(t,e)=\u003et\u003ce?1e5*t+e:1e5*e+t,jV=(t,e)=\u003e{const n=t.map((e,n)=\u003e[e,t[(n+1)%t.length]]),o=e.map((t,n)=\u003e[t,e[(n+1)%e.length]]),i=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,r]of o)void 0!==r\u0026\u0026t===r\u0026\u0026e===n\u0026\u0026i.add(BV(t,e));if(0===i.size)return null;const r=[];for(const[t,e]of n)void 0!==e\u0026\u0026(i.has(BV(t,e))||r.push([t,e]));for(const[t,e]of o)void 0!==e\u0026\u0026(i.has(BV(t,e))||r.push([t,e]));if(0===r.length)return null;const s=new Map;for(const[t,e]of r)s.set(t,e);const a=r[0]?.[0];if(void 0===a)return null;const c=[a];let l=s.get(a),d=0;for(;void 0!==l\u0026\u0026l!==a\u0026\u0026d++\u003cr.length+5;)c.push(l),l=s.get(l);return l!==a||c.length!==r.length?null:c},$V=(t,e)=\u003et\u003ce?1e5*t+e:1e5*e+t,YV=(t,e)=\u003et\u003ce?1e5*t+e:1e5*e+t,XV=c(T(),1),VV=t=\u003e{const{a:e,b:n,c:o}=t,i=2*(e.x*(n.y-o.y)+n.x*(o.y-e.y)+o.x*(e.y-n.y));if(Math.abs(i)\u003c1e-10)return{x:0,y:0,r2:1e18};const r=e.x*e.x+e.y*e.y,s=n.x*n.x+n.y*n.y,a=o.x*o.x+o.y*o.y,c=(r*(n.y-o.y)+s*(o.y-e.y)+a*(e.y-n.y))/i,l=(r*(o.x-n.x)+s*(e.x-o.x)+a*(n.x-e.x))/i;return{x:c,y:l,r2:(e.x-c)**2+(e.y-l)**2}},WV=(t,e,n)=\u003e[t.a,t.b,t.c].includes(e)\u0026\u0026[t.a,t.b,t.c].includes(n),HV=t=\u003e{const{px:e,py:n,polygonPoints:o,clearance:i}=t;if(o.length\u003c3)return!1;const r=o.map(t=\u003emO(t.x,t.y)),s=[];for(let t=0;t\u003cr.length;t++){const e=r[t],n=r[(t+1)%r.length];s.push(fO(e,n))}const a=new xO;a.addFace(s);const c=mO(e,n);if(a.contains(c))return!0;const[l]=a.distanceTo(c);return l\u003ci-.1},GV=t=\u003e{const{point:e,via:n,clearance:o}=t,i=e.x-n.center.x,r=e.y-n.center.y,s=n.diameter/2+o;return i*i+r*r\u003c=s*s+1e-9},UV=t=\u003e{const{point:e,rect:n,clearance:o}=t,i=Math.cos(-n.ccwRotation),r=Math.sin(-n.ccwRotation),s=e.x-n.center.x,a=e.y-n.center.y,c=s*i-a*r,l=s*r+a*i;return Math.abs(c)\u003c=n.width/2+o+1e-9\u0026\u0026Math.abs(l)\u003c=n.height/2+o+1e-9},ZV=t=\u003eHV({px:t.point.x,py:t.point.y,polygonPoints:t.polygon.points,clearance:t.clearance}),qV=(t,e)=\u003et.x\u003e=e.minX-1e-9\u0026\u0026t.x\u003c=e.maxX+1e-9\u0026\u0026t.y\u003e=e.minY-1e-9\u0026\u0026t.y\u003c=e.maxY+1e-9,JV=t=\u003e{const{point:e,vias:n,rects:o,polygons:i,clearance:r,layerCount:s}=t;let a=0;for(const t of n)GV({point:e,via:t,clearance:r})\u0026\u0026(a|=sV(t,s));for(const t of o)UV({point:e,rect:t,clearance:r})\u0026\u0026(a|=sV(t,s));for(const t of i)ZV({point:e,polygon:t,clearance:r})\u0026\u0026(a|=sV(t,s));return a},KV=t=\u003e{const{triangles:e,pts:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a,layerCount:c}=t,l=nV(c),d=[],h=[];for(const[t,u,p]of e){const e=n[t],m=n[u],g=n[p];if(!e||!m||!g)continue;const f={x:(e.x+m.x+g.x)/3,y:(e.y+m.y+g.y)/3};if(!qV(f,o))continue;const y=l\u0026~JV({point:f,vias:i,rects:s,polygons:a,clearance:r,layerCount:c});0!==y\u0026\u0026(d.push([t,u,p]),h.push(oV(y,c)))}return{triangles:d,triangleAvailableZ:h}},QV=t=\u003e{const{triangles:e,pts:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a}=t;return e.filter(([t,e,c])=\u003e{const l=n[t],d=n[e],h=n[c];if(!l||!d||!h)return!1;if(!(t=\u003e{const{px:e,py:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a}=t,{minX:c,maxX:l,minY:d,maxY:h}=o,u=1e-6*Math.max(l-c,h-d,1);if(e\u003cc-u||e\u003el+u||n\u003cd-u||n\u003eh+u)return!1;for(const t of i){const o=t.diameter/2+r,i=Math.max(0,o-u);if((e-t.center.x)**2+(n-t.center.y)**2\u003ci*i)return!1}for(const t of s){const o=t.width/2+r,i=t.height/2+r,s=Math.max(0,o-u),a=Math.max(0,i-u),c=e-t.center.x,l=n-t.center.y,d=Math.cos(t.ccwRotation),h=Math.sin(t.ccwRotation),p=c*d+l*h,m=-c*h+l*d;if(Math.abs(p)\u003cs\u0026\u0026Math.abs(m)\u003ca)return!1}for(const t of a)if(HV({px:e,py:n,polygonPoints:t.points,clearance:r}))return!1;return!0})({px:(l.x+d.x+h.x)/3,py:(l.y+d.y+h.y)/3,bounds:o,vias:i,clearance:r,rects:s,polygons:a}))return!1;if(a.length\u003e0){const t=[l,d,h,{x:(l.x+d.x)/2,y:(l.y+d.y)/2},{x:(d.x+h.x)/2,y:(d.y+h.y)/2},{x:(h.x+l.x)/2,y:(h.y+l.y)/2}];for(const e of t)for(const t of a)if(HV({px:e.x,py:e.y,polygonPoints:t.points,clearance:r}))return!1}return!0})},tW=t=\u003evoid 0!==t,eW=t=\u003e{const{bounds:e,clearance:n,concavityTolerance:o}=t,i=t.vias??[],r=t.rects??[],s=t.polygons??[];let a,c,l;if(!1!==t.useConstrainedDelaunay){const o=DV({bounds:e,vias:i,clearance:n,rects:r,polygons:s,viaSegments:t.viaSegments,preserveObstacleBoundaries:void 0!==t.layerCount});a=o.pts;const d=((t,e,n={})=\u003e{const o=t.map(t=\u003e[t.x,t.y]);return(0,XV.default)(o,e,{exterior:!!n.includeConstraintInteriors})})(a,o.constraintEdges,{includeConstraintInteriors:void 0!==t.layerCount});if(void 0!==t.layerCount){const o=KV({triangles:d,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s,layerCount:t.layerCount});c=o.triangles,l=o.triangleAvailableZ}else{c=i.length\u003e0||r.length\u003e0||s.length\u003e0?QV({triangles:d,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s}):d}}else{a=(t=\u003e{const{bounds:e,vias:n,clearance:o,rects:i,polygons:r=[],viaSegments:s=24}=t,a=[],{minX:c,maxX:l,minY:d,maxY:h}=e;a.push({x:c,y:d},{x:l,y:d},{x:l,y:h},{x:c,y:h});for(let t=1;t\u003c10;t++){const e=t/10;a.push({x:c+e*(l-c),y:d}),a.push({x:l,y:d+e*(h-d)}),a.push({x:l-e*(l-c),y:h}),a.push({x:c,y:h-e*(h-d)})}for(const t of n){const e=t.diameter/2+o;for(let n=0;n\u003cs;n++){const o=2*Math.PI*n/s;a.push({x:t.center.x+e*Math.cos(o),y:t.center.y+e*Math.sin(o)})}}for(const t of i){const e=t.width/2+o,n=t.height/2+o,i=Math.max(2,Math.ceil(Math.max(2*e,2*n)/20));for(let o=0;o\u003ci;o++){const r=o/i;a.push(AV({localX:2*r*e-e,localY:-n,rect:t})),a.push(AV({localX:e,localY:2*r*n-n,rect:t})),a.push(AV({localX:e-2*r*e,localY:n,rect:t})),a.push(AV({localX:-e,localY:n-2*r*n,rect:t}))}}for(const t of r){if(t.points.length\u003c3)continue;const e=EV({polygon:t,clearance:o});a.push(...e)}return a.map((t,e)=\u003e({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))})({bounds:e,vias:i,clearance:n,rects:r,polygons:s,viaSegments:t.viaSegments});const o=(t=\u003e{const e=t.map((t,e)=\u003e({...t,i:e}));if(e.length\u003c3)return[];let n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),o=Math.min(o,t.y),i=Math.max(i,t.x),r=Math.max(r,t.y);const s=Math.max(i-n,r-o)||1,a=(n+i)/2,c=(o+r)/2,l={x:a-30*s,y:c-s,i:-1},d={x:a,y:c+30*s,i:-2},h={x:a+30*s,y:c-s,i:-3};let u=[{a:l,b:d,c:h,cc:VV({a:l,b:d,c:h})}];for(const t of e){const e=u.filter(e=\u003e{const n=t.x-e.cc.x,o=t.y-e.cc.y;return n*n+o*o\u003ce.cc.r2+1e-6}),n=new Set(e),o=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[i,r]of n){let n=!1;for(const o of e)if(o!==t\u0026\u0026WV(o,i,r)){n=!0;break}n||o.push([i,r])}}u=u.filter(t=\u003e!n.has(t));for(const[e,n]of o)u.push({a:e,b:n,c:t,cc:VV({a:e,b:n,c:t})})}return u.filter(t=\u003et.a.i\u003e=0\u0026\u0026t.b.i\u003e=0\u0026\u0026t.c.i\u003e=0).map(t=\u003e[t.a.i,t.b.i,t.c.i])})(a);if(void 0!==t.layerCount){const d=KV({triangles:o,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s,layerCount:t.layerCount});c=d.triangles,l=d.triangleAvailableZ}else c=QV({triangles:o,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s})}const{cells:d,depths:h,availableZ:u}=!1!==t.usePolyanyaMerge?(t=\u003e{const{triangles:e,pts:n,cellAvailableZ:o,layerMergeMode:i=\"same\"}=t;if(!e.length)return{cells:[],depths:[]};const r=e.length,s=e.map(([t,e,o])=\u003e{const i=n[t],r=n[e],s=n[o];return i\u0026\u0026r\u0026\u0026s\u0026\u0026tV({o:i,a:r,b:s})\u003c0?[t,o,e]:[t,e,o]}),a=o?.map(iV),c=new Array(r).fill(null);for(let t=0;t\u003cr;t++)c[t]=new Map;function l(){for(let t=0;t\u003cc.length;t++)c[t]\u0026\u0026c[t].clear();const t=new Map;for(let e=0;e\u003cs.length;e++){const n=s[e];if(n)for(let o=0;o\u003cn.length;o++){const i=n[o],r=n[(o+1)%n.length],s=YV(i,r),a=t.get(s);a?(c[e].set(o,{neighbor:a.cellIdx,neighborEdge:a.edgePos}),c[a.cellIdx].set(a.edgePos,{neighbor:e,neighborEdge:o})):t.set(s,{cellIdx:e,edgePos:o})}}}function d(t){let e=0;for(let o=0;o\u003ct.length;o++){const i=n[t[o]],r=n[t[(o+1)%t.length]];e+=i.x*r.y-r.x*i.y}return Math.abs(e)/2}function h(t,e){const n=s[t],o=c[t],i=n.length;let r=-1;for(const[t,n]of o)if(n.neighbor===e){r=t;break}if(-1===r)return null;let a=r;for(;;){const t=(a-1+i)%i;if(t===r)break;const n=o.get(t);if(!n||n.neighbor!==e)break;a=t}let l=r;for(;;){const t=(l+1)%i;if(t===a)break;const n=o.get(t);if(!n||n.neighbor!==e)break;l=t}return{firstK:a,lastK:l,sharedCount:(l-a+i)%i+1}}function u(t,e){const o=s[t],r=s[e],c=h(t,e);if(!c)return!1;const{firstK:l,lastK:d,sharedCount:u}=c,p=o.length,m=r.length,g=o[l],f=o[(d+1)%p];let y=-1;for(let t=0;t\u003cm;t++)if(r[t]===g){y=t;break}if(-1===y)return!1;const _=(y-u+m)%m;if(r[_]!==f)return!1;const b=n[o[(l-1+p)%p]],x=n[g],v=n[r[(y+1)%m]];if(tV({o:b,a:x,b:v})\u003c-1e-8)return!1;const S=n[r[(_-1+m)%m]],I=n[f],C=n[o[(d+2)%p]];if(tV({o:S,a:I,b:C})\u003c-1e-8)return!1;if(a){if(0===(a[t]\u0026a[e]))return!1;if(\"same\"===i\u0026\u0026a[t]!==a[e])return!1}return!0}function p(t,e){const n=s[t],o=s[e],i=h(t,e),{firstK:r,lastK:c,sharedCount:l}=i,d=n.length,u=o.length,p=n[r],m=n[(c+1)%d];let g=-1;for(let t=0;t\u003cu;t++)if(o[t]===p){g=t;break}const f=[];f.push(p);const y=u-l-1;for(let t=1;t\u003c=y;t++)f.push(o[(g+t)%u]);f.push(m);const _=d-l-1;for(let t=2;t\u003c=_+1;t++)f.push(n[(c+t)%d]);s[t]=f,s[e]=null,a\u0026\u0026(a[t]=a[t]\u0026a[e],a[e]=0)}l();let m=!0;for(;m;){m=!1,l();for(let t=0;t\u003cs.length;t++){if(!s[t])continue;const e=c[t],n=new Set;for(const[,t]of e)s[t.neighbor]\u0026\u0026n.add(t.neighbor);if(1===n.size){const e=n.values().next().value;u(t,e)\u0026\u0026(p(t,e),m=!0)}}}l();const g=new Array(s.length).fill(0);for(let t=0;t\u003cs.length;t++)s[t]\u0026\u0026(g[t]=d(s[t]));const f=[];function y(t){f.push(t);let e=f.length-1;for(;e\u003e0;){const t=e-1\u003e\u003e1;if(f[t].area\u003e=f[e].area)break;const n=f[t];f[t]=f[e],f[e]=n,e=t}}function _(){if(0===f.length)return;const t=f[0],e=f.pop();if(f.length\u003e0){f[0]=e;let t=0;for(;;){let e=t;const n=2*t+1,o=2*t+2;if(n\u003cf.length\u0026\u0026f[n].area\u003ef[e].area\u0026\u0026(e=n),o\u003cf.length\u0026\u0026f[o].area\u003ef[e].area\u0026\u0026(e=o),e===t)break;const i=f[t];f[t]=f[e],f[e]=i,t=e}}return t}const b=new Set;for(let t=0;t\u003cs.length;t++){if(!s[t])continue;const e=c[t],n=new Set;for(const[,t]of e)s[t.neighbor]\u0026\u0026n.add(t.neighbor);for(const e of n){const n=t\u003ce?1e5*t+e:1e5*e+t;b.has(n)||(b.add(n),u(t,e)\u0026\u0026y({area:g[t]+g[e],xIdx:t,yIdx:e}))}}for(;f.length\u003e0;){const t=_(),{xIdx:e,yIdx:n}=t;if(!s[e]||!s[n])continue;const o=g[e]+g[n];if(Math.abs(o-t.area)\u003e1e-10){u(e,n)\u0026\u0026y({area:o,xIdx:e,yIdx:n});continue}if(!u(e,n))continue;p(e,n),g[e]=d(s[e]),l();const i=c[e],r=new Set;for(const[,t]of i)s[t.neighbor]\u0026\u0026r.add(t.neighbor);for(const t of r)u(e,t)\u0026\u0026y({area:g[e]+g[t],xIdx:e,yIdx:t})}const x=s.filter(t=\u003enull!==t),v=a?s.flatMap((t,e)=\u003enull===t?[]:[oV(a[e])]):void 0,S=x.map(()=\u003e0);return{cells:x,depths:S,...v?{availableZ:v}:{}}})({triangles:c,pts:a,cellAvailableZ:l,layerMergeMode:t.layerMergeMode}):(t=\u003e{const{triangles:e,pts:n,concavityTolerance:o,cellAvailableZ:i,layerMergeMode:r=\"same\"}=t;if(!e.length)return{cells:[],depths:[]};const s=e.map(([t,e,o])=\u003e{const i=n[t],r=n[e],s=n[o];return i\u0026\u0026r\u0026\u0026s\u0026\u0026tV({o:i,a:r,b:s})\u003c0?[t,o,e]:[t,e,o]}),a=i?.map(iV),c=(t,e)=\u003e{if(!a)return;const n=a[t]\u0026a[e];return 0===n||\"same\"===r\u0026\u0026a[t]!==a[e]?0:n};let l=!0,d=0;for(;l\u0026\u0026d++\u003c800;){l=!1;const t=new Map,e=s.map(()=\u003enew Set);for(let n=0;n\u003cs.length;n++){const o=s[n];if(o)for(let i=0;i\u003co.length;i++){const r=o[i],s=o[(i+1)%o.length];if(void 0===r||void 0===s)continue;const a=$V(r,s);if(t.has(a)){const o=t.get(a);void 0!==o\u0026\u0026(e[n]?.add(o),e[o]?.add(n))}else t.set(a,n)}}let i=-1,r=-1,d=null,h=Number.POSITIVE_INFINITY;for(let t=0;t\u003cs.length;t++){const a=e[t];if(a)for(const e of a){if(e\u003c=t)continue;const a=jV(s[t]??[],s[e]??[]);if(!a)continue;if(0===c(t,e))continue;const l=FV(a,n);l\u003c=o+1e-6\u0026\u0026l\u003ch\u0026\u0026(h=l,i=t,r=e,d=a)}}if(i\u003c0||r\u003c0||!d)break;s[i]=d,a\u0026\u0026(a[i]=c(i,r),a.splice(r,1)),s.splice(r,1),l=!0}const h=s.map(t=\u003eFV(t,n));return{cells:s,depths:h,...a?{availableZ:a.map(t=\u003eoV(t))}:{}}})({triangles:c,pts:a,concavityTolerance:o,cellAvailableZ:l,layerMergeMode:t.layerMergeMode}),p=a.map(t=\u003e((t,e)=\u003e({x:Math.min(e.maxX,Math.max(e.minX,t.x)),y:Math.min(e.maxY,Math.max(e.minY,t.y))}))(t,e)),m=d.map(t=\u003et.map(t=\u003ep[t]).filter(tW)),g=d.map(t=\u003eeV(t,p).map(t=\u003ep[t]).filter(tW));return{pts:p,validTris:c,regions:m,hulls:g,depths:h,...u?{availableZ:u}:{}}},nW=t=\u003e{const e=[...new Set(t.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0))].sort((t,e)=\u003et-e);if(0!==e.length)return`z${e.join(\",\")}`},oW=t=\u003e{const e=[];for(let n=0;n\u003c31;n++)t\u00261\u003c\u003cn\u0026\u0026e.push(n);return e},iW=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,rW=t=\u003eiW(t)?{...t}:void 0===t?{}:{value:t},sW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];if(iW(n)){if(\"string\"==typeof n.serializedRegionId)return n.serializedRegionId;if(\"string\"==typeof n.regionId)return n.regionId;if(\"string\"==typeof n.capacityMeshNodeId)return n.capacityMeshNodeId}return`region-${e}`},aW=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];if(iW(n)){if(\"string\"==typeof n.serializedPortId)return n.serializedPortId;if(\"string\"==typeof n.portId)return(o=n.portId).includes(\"::\")?o.slice(0,o.indexOf(\"::\")):o}var o;return`port-${e}`},cW=(t,e)=\u003e{const n=rW(t.topology.regionMetadata?.[e]);if(iW(n.center)||(n.center={x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),\"number\"!=typeof n.width\u0026\u0026(n.width=t.topology.regionWidth[e]),\"number\"!=typeof n.height\u0026\u0026(n.height=t.topology.regionHeight[e]),!Array.isArray(n.availableZ)){const o=t.topology.regionAvailableZMask?.[e]??0;0!==o\u0026\u0026(n.availableZ=oW(o))}return n.layer=nW(Array.isArray(n.availableZ)?n.availableZ:[])??nW((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))??\"z0\",n},lW=(t,e)=\u003e{const n=rW(t.topology.portMetadata?.[e]);return\"number\"!=typeof n.x\u0026\u0026(n.x=t.topology.portX[e]),\"number\"!=typeof n.y\u0026\u0026(n.y=t.topology.portY[e]),\"number\"!=typeof n.z\u0026\u0026(n.z=t.topology.portZ[e]),n.layer=nW([t.topology.portZ[e]])??\"z0\",n},dW=(t,e,n)=\u003e{const o=(t.topology.incidentPortRegion[e]??[]).find(t=\u003et!==n);if(void 0===o)throw new Error(`Port ${e} is not incident to a region outside route region ${n}`);return o},hW=(t,e,n)=\u003e{const{orderedPortIds:o,orderedRegionIds:i}=((t,e,n)=\u003e{if(0===n.length)throw new Error(`Route ${e} has no solved segments`);const o=t.problem.routeStartPort[e],i=t.problem.routeEndPort[e],r=new Map;n.forEach((t,e)=\u003e{const n={...t,segmentIndex:e},o=r.get(t.fromPortId)??[];o.push(n),r.set(t.fromPortId,o);const i=r.get(t.toPortId)??[];i.push(n),r.set(t.toPortId,i)});const s=[o],a=[],c=new Set;let l,d=o;for(;d!==i;){const t=(r.get(d)??[]).filter(t=\u003e!c.has(t.segmentIndex)\u0026\u0026(t.fromPortId===d?t.toPortId:t.fromPortId)!==l);if(1!==t.length)throw new Error(`Route ${e} is not a single ordered path from ${o} to ${i}`);const n=t[0],h=n.fromPortId===d?n.toPortId:n.fromPortId;c.add(n.segmentIndex),a.push(n.regionId),s.push(h),l=d,d=h}if(c.size!==n.length)throw new Error(`Route ${e} contains disconnected solved segments`);return{orderedPortIds:s,orderedRegionIds:a}})(t,e,n),r=i[0],s=i[i.length-1];if(void 0===r||void 0===s)throw new Error(`Route ${e} could not determine endpoint regions`);const a=sW(t,dW(t,o[0],r)),c=sW(t,dW(t,o[o.length-1],s)),l=((t,e,n,o)=\u003e{const i=t.problem.routeMetadata?.[e];return{connectionId:(iW(i)\u0026\u0026\"string\"==typeof i.connectionId?i.connectionId:void 0)??`route-${e}`,startRegionId:(iW(i)\u0026\u0026\"string\"==typeof i.startRegionId?i.startRegionId:void 0)??n,endRegionId:(iW(i)\u0026\u0026\"string\"==typeof i.endRegionId?i.endRegionId:void 0)??o,mutuallyConnectedNetworkId:(iW(i)\u0026\u0026\"string\"==typeof i.mutuallyConnectedNetworkId?i.mutuallyConnectedNetworkId:void 0)??`net-${t.problem.routeNet[e]}`}})(t,e,a,c),d=o.map((e,n)=\u003e{const r={portId:aW(t,e),g:n,h:0,f:n,hops:n,ripRequired:!1,nextRegionId:n\u003ci.length?sW(t,i[n]):l.endRegionId};return n\u003e0\u0026\u0026(r.lastPortId=aW(t,o[n-1]),r.lastRegionId=sW(t,i[n-1])),r});return{connection:l,solvedRoute:{connection:l,path:d,requiredRip:!1}}},uW=t=\u003e{if(!t.solved||t.failed)throw new Error(\"convertToSerializedHyperGraph requires a solved, non-failed solver\");const{topology:e}=t,n=(t=\u003e{const e=Array.from({length:t.problem.routeCount},()=\u003e[]);return t.state.regionSegments.forEach((t,n)=\u003e{for(const[o,i,r]of t)e[o].push({regionId:n,fromPortId:i,toPortId:r})}),e})(t),o=Array.from({length:e.regionCount},(n,o)=\u003e({regionId:sW(t,o),pointIds:e.regionIncidentPorts[o].map(e=\u003eaW(t,e)),d:cW(t,o)})),i=Array.from({length:e.portCount},(n,o)=\u003e{const[i,r]=e.incidentPortRegion[o]??[];if(void 0===i||void 0===r)throw new Error(`Port ${o} is missing incident regions`);return{portId:aW(t,o),region1Id:sW(t,i),region2Id:sW(t,r),d:lW(t,o)}}),r=n.map((e,n)=\u003ehW(t,n,e));return{regions:o,ports:i,connections:r.map(({connection:t})=\u003et),solvedRoutes:r.map(({solvedRoute:t})=\u003et)}},pW=t=\u003et\u003e0\u0026\u0026!(t\u0026t-1),mW=(t,e,n,o,i,r=0)=\u003e.2025*(2*e+1*n+1*o)*(1+i/5)/t+(pW(r)?10*e:0),gW=(t,e,n,o,i,r)=\u003e{const{netIds:s,lesserAngles:a,greaterAngles:c,layerMasks:l}=t;let d=0,h=0;for(let t=0;t\u003cs.length;t++){if(e===s[t])continue;(n\u003ca[t]\u0026\u0026a[t]\u003co)!==(n\u003cc[t]\u0026\u0026c[t]\u003co)\u0026\u0026(0!==(i\u0026l[t])?d++:h++)}return[d,h,r]},fW=class{constructor(t,e){this.items=t,this.compare=e}items;compare;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0}queue(t){this.items.push(t),this.siftUp(this.items.length-1)}dequeue(){const t=this.items[0];if(void 0===t)return;const e=this.items.pop();return this.items.length\u003e0\u0026\u0026(this.items[0]=e,this.siftDown(0)),t}siftUp(t){let e=t;for(;e\u003e0;){const t=e-1\u003e\u003e1,n=this.items[t],o=this.items[e];if(this.compare(n,o)\u003c=0)return;this.items[t]=o,this.items[e]=n,e=t}}siftDown(t){let e=t;const n=this.items.length;for(;;){const t=2*e+1;if(t\u003e=n)return;const o=t+1;let i=t;o\u003cn\u0026\u0026this.compare(this.items[o],this.items[t])\u003c0\u0026\u0026(i=o);const r=this.items[e],s=this.items[i];if(this.compare(r,s)\u003c=0)return;this.items[e]=s,this.items[i]=r,e=i}}},yW=(t,e)=\u003e{const n=[...t],o=(t=\u003e{let e=t\u003e\u003e\u003e0;return()=\u003e{e+=1831565813;let t=e;return t=Math.imul(t^t\u003e\u003e\u003e15,1|t),t^=t+Math.imul(t^t\u003e\u003e\u003e7,61|t),((t^t\u003e\u003e\u003e14)\u003e\u003e\u003e0)/4294967296}})(e);for(let t=n.length-1;t\u003e0;t--){const e=Math.floor(o()*(t+1));[n[t],n[e]]=[n[e],n[t]]}return n},_W=(t,e)=\u003et.routeMetadata?.[e],bW=t=\u003et?.simpleRouteConnection?.pointsToConnect?.map(({pointId:t})=\u003e\"string\"==typeof t?t:null).filter(t=\u003enull!==t)??[],xW=(t,e)=\u003e{const n=_W(t,e)?.connectionId;return\"string\"==typeof n?n:`route-${e}`},vW=(t,e,n)=\u003e{const o=t.portEndpointNetIds[n];if(!o)return!1;for(const t of o)if(t!==e)return!0;return!1},SW=(t,e,n)=\u003e{const o=t.regionNetId[n];return-1!==o\u0026\u0026o!==e},IW=t=\u003e[...new Set(t.routeIds)].filter(e=\u003e!((t,e)=\u003e{const{topology:n,problem:o,problemSetup:i,portAssignment:r,maxPrecheckHops:s}=t,a=o.routeNet[e],c=o.routeStartPort[e],l=o.routeEndPort[e];if(c===l)return!0;const d=t.getStartingNextRegionId(e,c);if(void 0===d)return!1;const h=[{portId:c,nextRegionId:d}],u=new Set([c*n.regionCount+d]);for(let t=0;t\u003ch.length;t++){const e=h[t];if(!SW(o,a,e.nextRegionId))for(const t of n.regionIncidentPorts[e.nextRegionId]??[]){const c=r[t];if(vW(i,a,t))continue;if(t===l){if(-1!==c\u0026\u0026c!==a)continue;return!0}if(t===e.portId)continue;if(-1!==c\u0026\u0026c!==a)continue;if(0===o.portSectionMask[t])continue;const d=n.incidentPortRegion[t]??[],p=d[0]===e.nextRegionId?d[1]:d[0];if(void 0===p||SW(o,a,p))continue;const m=t*n.regionCount+p;if(!u.has(m)){if(u.size\u003e=s)return!0;u.add(m),h.push({portId:t,nextRegionId:p})}}}return!1})(t,e)).map(e=\u003et.getRouteSummary(e)),CW=t=\u003e{const e=new Array(t);for(let n=0;n\u003ct;n++)e[n]=n;return e},PW=.05,MW={r:255,g:64,b:64,a:.72},NW=\"rgba(220, 38, 38, 0.98)\",wW=\"rgba(220, 38, 38, 0.12)\",TW=\"10 6\",RW=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),EW=t=\u003eMath.min(1,Math.max(0,t)),AW=(t,e,n)=\u003eMath.round(t+(e-t)*n),OW=({r:t,g:e,b:n,a:o})=\u003e`rgba(${t}, ${e}, ${n}, ${o})`,kW=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},LW=t=\u003e\"number\"==typeof t.centerRouteId,DW=(t,e)=\u003eLW(t)?e===t.centerRouteId?1:.5:1,zW=(t,e)=\u003e{const n=t.match(/^(rgba|hsla)\\((.*),\\s*([0-9]*\\.?[0-9]+)\\)$/);if(!n)return t;const[,o,i,r]=n,s=EW(Number(r)*e);return`${o}(${i}, ${Number(s.toFixed(3))})`},FW=(t,e,n=.8)=\u003e((t,e,n=.8)=\u003e{const o=`${t.problem.routeNet[e]}:${kW(t,e)}`;let i=0;for(let t=0;t\u003co.length;t++)i=17777*o.charCodeAt(t)+((i\u003c\u003c5)-i);return`hsla(${Math.abs(i)%360}, 70%, 50%, ${n})`})(t,e,n*DW(t,e)),BW=(t,e)=\u003e`net: ${t.problem.routeNet[e]}`,jW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=n?.polygon;if(Array.isArray(o)\u0026\u0026o.length\u003e=3){const t=o.map(t=\u003et.x),e=o.map(t=\u003et.y);return{minX:Math.min(...t),maxX:Math.max(...t),minY:Math.min(...e),maxY:Math.max(...e)}}const i=n?.bounds;if(i\u0026\u0026\"number\"==typeof i.minX\u0026\u0026\"number\"==typeof i.maxX\u0026\u0026\"number\"==typeof i.minY\u0026\u0026\"number\"==typeof i.maxY)return i;const r=t.topology.regionWidth[e],s=t.topology.regionHeight[e],a=t.topology.regionCenterX[e],c=t.topology.regionCenterY[e];return{minX:a-r/2,maxX:a+r/2,minY:c-s/2,maxY:c+s/2}},$W=(t,e)=\u003e({x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),YW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=Array.isArray(n?.availableZ)?n.availableZ.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0):[];if(o.length\u003e0)return nW(o)??\"z0\";const i=oW(t.topology.regionAvailableZMask?.[e]??0);if(i.length\u003e0)return nW(i)??\"z0\";const r=[...new Set((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))].sort((t,e)=\u003et-e);return nW(r)??\"z0\"},XW=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e],o=n?.existingRegionCost??0,i=t.state.regionCongestionCost[e]??0,r=t.problem.regionNetId[e];return RW(`region: region-${e}`,`net: ${-1===r?\"free\":`${r}`}`,t.getAdditionalRegionLabel(e),`cost: ${o.toFixed(3)}`,`congestion: ${i.toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},VW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];return n?.isConnectionRegion?{r:255,g:100,b:255,a:.6}:n?.isThroughJumper?{r:100,g:200,b:100,a:.5}:n?.isPad?{r:255,g:200,b:100,a:.5}:\"bottom\"===n?.layer?{r:52,g:152,b:219,a:.08}:{r:200,g:200,b:255,a:.1}},WW=(t,e)=\u003e{const n=VW(t,e),o=EW(t.state.regionIntersectionCaches[e]?.existingRegionCost??0),i=Math.pow(o,.8);return OW((s=MW,a=i,{r:AW((r=n).r,s.r,a),g:AW(r.g,s.g,a),b:AW(r.b,s.b,a),a:Number((r.a+(s.a-r.a)*a).toFixed(3))}));var r,s,a},HW=(t,e)=\u003e({x:t.topology.portX[e],y:t.topology.portY[e]}),GW=HW,UW=HW,ZW=(t,e)=\u003enW([t.topology.portZ[e]])??\"z0\",qW=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},JW=(t,e,n)=\u003e{if(void 0!==n)return`net: ${t.problem.routeNet[n]}`;const o=t.state.portAssignment[e];if(o\u003e=0)return`net: ${o}`;const i=new Set;for(let n=0;n\u003ct.problem.routeCount;n++)t.problem.routeStartPort[n]!==e\u0026\u0026t.problem.routeEndPort[n]!==e||i.add(t.problem.routeNet[n]);return 0!==i.size?`net: ${Array.from(i).sort((t,e)=\u003et-e).join(\", \")}`:void 0},KW=(t,e)=\u003e`z: ${t.topology.portZ[e]}`,QW=(t,e,n)=\u003eRW(qW(t,e),((t,e)=\u003e{const n=t.topology.incidentPortRegion[e]?.[0],o=t.topology.incidentPortRegion[e]?.[1];return`connects: region-${n??\"?\"} \u003c-\u003e region-${o??\"?\"}`})(t,e),JW(t,e,n)),tH=(t,e,n,o)=\u003e{const i=t.topology.portZ[n],r=t.topology.portZ[o];return i\u003e0\u0026\u0026r\u003e0?{strokeColor:zW(\"rgba(52, 152, 219, 0.95)\",DW(t,e)),strokeDash:\"3 2\"}:i!==r?{strokeColor:zW(\"rgba(22, 160, 133, 0.95)\",DW(t,e)),strokeDash:\"2 4 2\"}:{strokeColor:FW(t,e)}},eH=(t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++)if(t.problem.routeStartPort[n]===e||t.problem.routeEndPort[n]===e)return!0;return!1},nH=(t,e,n)=\u003e{const o=((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ce.length;o++)if(1===e[o])for(const e of t.topology.incidentPortRegion[o]??[])n.add(e);return n})(t,n),i=\"rgba(245, 158, 11, 0.95)\",r=\"rgba(245, 158, 11, 0.08)\";for(const n of o){const o=t.topology.regionMetadata?.[n],s=o?.polygon,a=jW(t,n),c=$W(t,n),l=a.maxX-a.minX,d=a.maxY-a.minY,h=YW(t,n),u=RW(\"section region\",XW(t,n));Array.isArray(s)\u0026\u0026s.length\u003e=3?e.polygons.push({points:s,fill:r,stroke:i,strokeWidth:2,layer:h,label:u}):e.rects.push({center:c,width:Math.max(l-PW,.05),height:Math.max(d-PW,.05),fill:r,stroke:i,layer:h,label:u})}for(let o=0;o\u003cn.length;o++)1===n[o]\u0026\u0026e.circles.push({center:UW(t,o),radius:.07,fill:\"rgba(251, 191, 36, 0.18)\",stroke:i,layer:ZW(t,o),label:RW(QW(t,o),KW(t,o),\"section port\")})},oH=(t,e={})=\u003e{const n={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:\"Tiny HyperGraph\",coordinateSystem:\"cartesian\"},o=((t,e)=\u003e{if(!e?.highlightSectionMask)return;const n=e.sectionPortMask??t.problem.portSectionMask;if(n.length!==t.topology.portCount)return;let o=0,i=0;for(let t=0;t\u003cn.length;t++)1===n[t]?o+=1:i+=1;return 0!==o\u0026\u00260!==i?n:void 0})(t,e);for(let e=0;e\u003ct.topology.regionCount;e++){const o=t.topology.regionMetadata?.[e],i=o?.polygon,r=jW(t,e),s=$W(t,e),a=r.maxX-r.minX,c=r.maxY-r.minY,l=YW(t,e),d=OW(VW(t,e));Array.isArray(i)\u0026\u0026i.length\u003e=3?n.polygons.push({points:i,fill:d,layer:l}):n.rects.push({center:s,width:Math.max(a-PW,.05),height:Math.max(c-PW,.05),fill:WW(t,e),layer:l,label:XW(t,e)})}if(((t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a=FW(t,n),c=kW(t,n),l=BW(t,n);e.points.push({x:r.x,y:r.y,color:a,layer:ZW(t,o),label:RW(`route: ${c}`,l,\"endpoint: start\",qW(t,o),KW(t,o))}),e.points.push({x:s.x,y:s.y,color:a,layer:ZW(t,i),label:RW(`route: ${c}`,l,\"endpoint: end\",qW(t,i),KW(t,i))})}})(t,n),0===t.iterations){for(const t of n.polygons)t.stroke=\"rgba(128, 128, 128, 0.5)\";for(const t of n.rects)t.stroke=\"rgba(128, 128, 128, 0.5)\"}if(0===t.iterations){for(let i=0;i\u003ct.topology.portCount;i++){const r=1===o?.[i];e.showOnlySectionPortsOnIdle\u0026\u0026!r||n.circles.push({center:UW(t,i),radius:.05,fill:t.topology.portZ[i]\u003e0?\"rgba(52, 152, 219, 0.55)\":\"rgba(128, 128, 128, 0.5)\",layer:ZW(t,i),label:RW(QW(t,i),KW(t,i))})}!1!==e.showInitialRouteHints\u0026\u0026((t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a={x:(r.x+s.x)/2,y:(r.y+s.y)/2};e.lines.push({points:[r,s],strokeColor:FW(t,n),strokeDash:\"3 3\",label:kW(t,n)}),e.points.push({x:a.x,y:a.y,color:FW(t,n,1),label:kW(t,n)})}})(t,n)}else((t,e)=\u003e{for(let n=0;n\u003ct.state.regionSegments.length;n++){const o=t.state.regionSegments[n]??[];for(const[i,r,s]of o)e.lines.push({points:[GW(t,r),GW(t,s)],label:RW(`route: ${kW(t,i)}`,`region: region-${n}`),...tH(t,i,r,s)})}})(t,n),((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ct.state.regionSegments.length;o++){const i=t.state.regionSegments[o]??[];for(const[o,r,s]of i)for(const i of[r,s]){const r=`${o}:${i}`;if(n.has(r))continue;n.add(r);const s=GW(t,i);e.points.push({x:s.x,y:s.y,color:FW(t,o,1),layer:ZW(t,i),label:RW(`route: ${kW(t,o)}`,qW(t,i),JW(t,i,o),KW(t,i))})}}})(t,n),(t=\u003eLW(t)\u0026\u0026!0===t.showUnassignedPortsInVisualization)(t)\u0026\u0026((t,e)=\u003e{for(let n=0;n\u003ct.topology.portCount;n++)t.state.portAssignment[n]\u003e=0||eH(t,n)||e.circles.push({center:UW(t,n),radius:.04,fill:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.2)\":\"rgba(128, 128, 128, 0.2)\",stroke:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.6)\":\"rgba(128, 128, 128, 0.6)\",layer:ZW(t,n),label:RW(QW(t,n),KW(t,n),\"state: unassigned\")})})(t,n),LW(t)||(((t,e)=\u003e{const n=t.state.currentRouteId;if(void 0===n||t.solved)return;const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a=FW(t,n),c=kW(t,n);e.lines.push({points:[r,s],strokeColor:a,strokeDash:\"10 5\",label:c})})(t,n),((t,e)=\u003e{if(t.solved)return;const n=t.state.currentRouteId,o=t.state.candidateQueue.toArray().sort((t,e)=\u003et.f-e.f).slice(0,10);for(let i=0;i\u003co.length;i++){const r=o[i],s=GW(t,r.portId),a=0===i;e.points.push({x:s.x,y:s.y,color:a?\"green\":\"rgba(128, 128, 128, 0.25)\",layer:ZW(t,r.portId),label:RW(QW(t,r.portId,n),KW(t,r.portId),`g: ${r.g.toFixed(2)}`,`h: ${r.h.toFixed(2)}`,`f: ${r.f.toFixed(2)}`)})}const i=o[0];if(!i)return;const r=[];let s=i;for(;s;)r.unshift(GW(t,s.portId)),s=s.prevCandidate;r.length\u003e1\u0026\u0026e.lines.push({points:r,strokeColor:void 0!==n?FW(t,n):\"rgba(0, 160, 120, 0.9)\"})})(t,n));o\u0026\u0026nH(t,n,o),((t,e)=\u003e{if(t.failed)for(const n of t.getNeverSuccessfullyRoutedRoutes()){const{routeId:o,connectionId:i,attempts:r,startPortId:s,endPortId:a}=n,c=BW(t,o),l=UW(t,s),d=UW(t,a),h=RW(`never routed: ${i}`,`attempts: ${r}`,c,n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0);e.lines.push({points:[{x:0,y:0},{x:l.x,y:l.y}],strokeColor:NW,strokeDash:TW,layer:ZW(t,s),label:RW(h,\"origin guide\",\"endpoint: start\")}),e.circles.push({center:l,radius:1,fill:wW,stroke:NW,layer:ZW(t,s),label:RW(h,\"endpoint: start\",qW(t,s),KW(t,s))}),e.lines.push({points:[{x:0,y:0},{x:d.x,y:d.y}],strokeColor:NW,strokeDash:TW,layer:ZW(t,a),label:RW(h,\"origin guide\",\"endpoint: end\")}),e.circles.push({center:d,radius:1,fill:wW,stroke:NW,layer:ZW(t,a),label:RW(h,\"endpoint: end\",qW(t,a),KW(t,a))})}})(t,n);const i=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1),r=o?o.reduce((t,e)=\u003et+Number(1===e),0):0;return n.title=[\"Tiny HyperGraph\",`iter=${t.iterations}`,`pending=${i}`,o?`sectionPorts=${r}`:void 0,t.failed?\"failed\":t.solved?\"solved\":\"running\"].filter(Boolean).join(\" | \"),n},iH=()=\u003e({netIds:new Int32Array(0),lesserAngles:new Int32Array(0),greaterAngles:new Int32Array(0),layerMasks:new Int32Array(0),existingCrossingLayerIntersections:0,existingSameLayerIntersections:0,existingEntryExitLayerChanges:0,existingRegionCost:0,existingSegmentCount:0}),rH=(t,e)=\u003et.f-e.f,sH=class extends kt{constructor(t,e,n){super(),this.topology=t,this.problem=e,((t,e)=\u003e{e\u0026\u0026(void 0!==e.DISTANCE_TO_COST\u0026\u0026(t.DISTANCE_TO_COST=e.DISTANCE_TO_COST),void 0!==e.RIP_THRESHOLD_START\u0026\u0026(t.RIP_THRESHOLD_START=e.RIP_THRESHOLD_START),void 0!==e.RIP_THRESHOLD_END\u0026\u0026(t.RIP_THRESHOLD_END=e.RIP_THRESHOLD_END),void 0!==e.RIP_THRESHOLD_RAMP_ATTEMPTS\u0026\u0026(t.RIP_THRESHOLD_RAMP_ATTEMPTS=e.RIP_THRESHOLD_RAMP_ATTEMPTS),void 0!==e.RIP_CONGESTION_REGION_COST_FACTOR\u0026\u0026(t.RIP_CONGESTION_REGION_COST_FACTOR=e.RIP_CONGESTION_REGION_COST_FACTOR),void 0!==e.MAX_ITERATIONS\u0026\u0026(t.MAX_ITERATIONS=e.MAX_ITERATIONS),void 0!==e.VERBOSE\u0026\u0026(t.VERBOSE=e.VERBOSE),void 0!==e.STATIC_REACHABILITY_PRECHECK\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK=e.STATIC_REACHABILITY_PRECHECK),void 0!==e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS=e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS))})(this,n),this.state={portAssignment:new Int32Array(t.portCount).fill(-1),regionSegments:Array.from({length:t.regionCount},()=\u003e[]),regionIntersectionCaches:Array.from({length:t.regionCount},()=\u003eiH()),currentRouteId:void 0,currentRouteNetId:void 0,unroutedRoutes:CW(e.routeCount),candidateQueue:new fW([],rH),candidateBestCostByHopId:new Float64Array(t.portCount*t.regionCount),candidateBestCostGenerationByHopId:new Uint32Array(t.portCount*t.regionCount),candidateBestCostGeneration:1,goalPortId:-1,ripCount:0,regionCongestionCost:new Float64Array(t.regionCount).fill(0)},this.routeAttemptCountByRouteId=new Uint32Array(e.routeCount),this.routeSuccessCountByRouteId=new Uint32Array(e.routeCount)}topology;problem;state;_problemSetup;routeAttemptCountByRouteId;routeSuccessCountByRouteId;hasLoggedNeverSuccessfullyRoutedRoutes=!1;segmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};DISTANCE_TO_COST=.05;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;RIP_CONGESTION_REGION_COST_FACTOR=.1;MAX_ITERATIONS=1e6;VERBOSE=!1;STATIC_REACHABILITY_PRECHECK=!0;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;get problemSetup(){return this._problemSetup||(this._problemSetup=this.computeProblemSetup()),this._problemSetup}computeProblemSetup(){const{topology:t,problem:e}=this,n=t.portX,o=t.portY,i=new Float64Array(t.portCount*e.routeCount),r=Array.from({length:t.portCount},()=\u003enew Set);for(let s=0;s\u003ce.routeCount;s++){r[e.routeStartPort[s]].add(e.routeNet[s]),r[e.routeEndPort[s]].add(e.routeNet[s]);const a=e.routeEndPort[s],c=n[a],l=o[a];for(let r=0;r\u003ct.portCount;r++){const t=n[r]-c,a=o[r]-l;i[r*e.routeCount+s]=Math.hypot(t,a)*this.DISTANCE_TO_COST}}return{portHCostToEndOfRoute:i,portEndpointNetIds:r}}_setup(){if(this.problemSetup,this.STATIC_REACHABILITY_PRECHECK){const t=IW({topology:this.topology,problem:this.problem,problemSetup:this.problemSetup,portAssignment:this.state.portAssignment,routeIds:this.state.unroutedRoutes,maxPrecheckHops:Math.max(0,this.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),getStartingNextRegionId:(t,e)=\u003ethis.getStartingNextRegionId(t,e),getRouteSummary:t=\u003ethis.getRouteSummary(t)});t.length\u003e0\u0026\u0026(this.failed=!0,this.error=(t=\u003e{const e=t.slice(0,5).map(t=\u003e{const e=t.pointIds.length\u003e=2?`${t.pointIds[0]}-\u003e${t.pointIds[1]}`:`${t.startPortId}-\u003e${t.endPortId}`;return`${t.connectionId} (${e})`}).join(\", \"),n=t.length-5;return[\"Static reachability precheck failed:\",`${t.length} route(s) have no legal path under the current reservation and start-region rules`,n\u003e0?`${e}, +${n} more`:e].join(\" \")})(t),this.stats={...this.stats,staticallyUnroutableRouteCount:t.length})}}_step(){const{problem:t,topology:e,state:n}=this;if(void 0===n.currentRouteId){if(0===n.unroutedRoutes.length)return void this.onAllRoutesRouted();n.currentRouteId=n.unroutedRoutes.shift(),n.currentRouteNetId=t.routeNet[n.currentRouteId],this.routeAttemptCountByRouteId[n.currentRouteId]+=1,this.resetCandidateBestCosts();const e=t.routeStartPort[n.currentRouteId];n.candidateQueue.clear();const o=this.getStartingNextRegionId(n.currentRouteId,e);if(void 0===o)return this.failed=!0,void(this.error=`Start port ${e} has no incident regions`);this.setCandidateBestCost(this.getHopId(e,o),0),n.candidateQueue.queue({nextRegionId:o,portId:e,f:0,g:0,h:0}),n.goalPortId=t.routeEndPort[n.currentRouteId]}const o=n.candidateQueue.dequeue();if(!o)return void this.onOutOfCandidates();const i=this.getHopId(o.portId,o.nextRegionId);if(o.g\u003ethis.getCandidateBestCost(i))return;if(this.isRegionReservedForDifferentNet(o.nextRegionId))return;const r=e.regionIncidentPorts[o.nextRegionId];for(const i of r){const r=n.portAssignment[i];if(this.isPortReservedForDifferentNet(i))continue;if(i===n.goalPortId){if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;return void this.onPathFound(o)}if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;if(i===o.portId)continue;if(0===t.portSectionMask[i])continue;const s=this.computeG(o,i);if(!Number.isFinite(s))continue;const a=this.computeH(i),c=e.incidentPortRegion[i][0]===o.nextRegionId?e.incidentPortRegion[i][1]:e.incidentPortRegion[i][0];if(void 0===c||this.isRegionReservedForDifferentNet(c))continue;const l={prevRegionId:o.nextRegionId,nextRegionId:c,portId:i,g:s,h:a,f:s+a,prevCandidate:o};if(i===n.goalPortId)return void this.onPathFound(l);const d=this.getHopId(i,c);s\u003e=this.getCandidateBestCost(d)||(this.setCandidateBestCost(d,s),n.candidateQueue.queue(l))}}resetCandidateBestCosts(){const{state:t}=this;if(4294967295===t.candidateBestCostGeneration)return t.candidateBestCostGenerationByHopId.fill(0),void(t.candidateBestCostGeneration=1);t.candidateBestCostGeneration+=1}getCandidateBestCost(t){const{state:e}=this;return e.candidateBestCostGenerationByHopId[t]===e.candidateBestCostGeneration?e.candidateBestCostByHopId[t]:Number.POSITIVE_INFINITY}setCandidateBestCost(t,e){const{state:n}=this;n.candidateBestCostGenerationByHopId[t]=n.candidateBestCostGeneration,n.candidateBestCostByHopId[t]=e}getHopId(t,e){return t*this.topology.regionCount+e}getStartingNextRegionId(t,e){const n=this.topology.incidentPortRegion[e]??[],o=this.problem.routeNet[t];return n.find(t=\u003e-1===this.problem.regionNetId[t])??n.find(t=\u003ethis.problem.regionNetId[t]===o)??n[0]}isPortReservedForDifferentNet(t){const e=this.problemSetup.portEndpointNetIds[t];if(!e)return!1;for(const t of e)if(t!==this.state.currentRouteNetId)return!0;return!1}isRegionReservedForDifferentNet(t){const e=this.problem.regionNetId[t];return-1!==e\u0026\u0026e!==this.state.currentRouteNetId}isKnownSingleLayerRegion(t){const e=this.topology.regionAvailableZMask?.[t]??0;return pW(e)}computeRegionCostForRegion(t,e,n,o,i){return((t,e,n,o,i,r,s=0)=\u003emW(t*e,n,o,i,r,s))(this.topology.regionWidth[t],this.topology.regionHeight[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0)}populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.segmentGeometryScratch,r=o.incidentPortRegion[e],s=o.incidentPortRegion[n],a=r[0]===t||r[1]!==t?o.portAngleForRegion1[e]:o.portAngleForRegion2?.[e]??o.portAngleForRegion1[e],c=s[0]===t||s[1]!==t?o.portAngleForRegion1[n]:o.portAngleForRegion2?.[n]??o.portAngleForRegion1[n],l=o.portZ[e],d=o.portZ[n];return i.lesserAngle=a\u003cc?a:c,i.greaterAngle=a\u003cc?c:a,i.layerMask=1\u003c\u003cl|1\u003c\u003cd,i.entryExitLayerChanges=l!==d?1:0,i}appendSegmentToRegionCache(t,e,n){const{topology:o,state:i}=this,r=i.regionIntersectionCaches[t],s=this.populateSegmentGeometryScratch(t,e,n),[a,c,l]=gW(r,i.currentRouteNetId,s.lesserAngle,s.greaterAngle,s.layerMask,s.entryExitLayerChanges),d=r.netIds.length+1,h=new Int32Array(d);h.set(r.netIds),h[d-1]=i.currentRouteNetId;const u=new Int32Array(d);u.set(r.lesserAngles),u[d-1]=s.lesserAngle;const p=new Int32Array(d);p.set(r.greaterAngles),p[d-1]=s.greaterAngle;const m=new Int32Array(d);m.set(r.layerMasks),m[d-1]=s.layerMask;const g=r.existingSameLayerIntersections+a,f=r.existingCrossingLayerIntersections+c,y=r.existingEntryExitLayerChanges+l,_=u.length;i.regionIntersectionCaches[t]={netIds:h,lesserAngles:u,greaterAngles:p,layerMasks:m,existingSameLayerIntersections:g,existingCrossingLayerIntersections:f,existingEntryExitLayerChanges:y,existingSegmentCount:_,existingRegionCost:this.computeRegionCostForRegion(t,g,f,y,_)}}getSolvedPathSegments(t){const{state:e}=this,n=[];let o=t;for(;o;)n.unshift(o),o=o.prevCandidate;const i=[];for(let t=1;t\u003cn.length;t++)i.push({regionId:n[t-1].nextRegionId,fromPortId:n[t-1].portId,toPortId:n[t].portId});const r=n[n.length-1];return r\u0026\u0026r.portId!==e.goalPortId\u0026\u0026i.push({regionId:r.nextRegionId,fromPortId:r.portId,toPortId:e.goalPortId}),i}resetRoutingStateForRerip(){const{topology:t,problem:e,state:n}=this;n.portAssignment.fill(-1),n.regionSegments=Array.from({length:t.regionCount},()=\u003e[]),n.regionIntersectionCaches=Array.from({length:t.regionCount},()=\u003eiH()),n.currentRouteNetId=void 0,n.currentRouteId=void 0,n.unroutedRoutes=yW(CW(e.routeCount),n.ripCount),n.candidateQueue.clear(),this.resetCandidateBestCosts(),n.goalPortId=-1}getMaxRegionCost(){const{topology:t,state:e}=this;let n=0;for(let o=0;o\u003ct.regionCount;o++){const t=e.regionIntersectionCaches[o]?.existingRegionCost??0;n=Math.max(n,t)}return n}getRouteMetadata(t){return this.problem.routeMetadata?.[t]}getRouteConnectionId(t){const e=this.getRouteMetadata(t)?.connectionId;return\"string\"==typeof e?e:`route-${t}`}getRouteSummary(t){return(({problem:t,routeId:e,getRouteMetadata:n,getRouteConnectionId:o})=\u003e{const i=n?.(e)??_W(t,e);return{routeId:e,connectionId:o?.(e)??xW(t,e),startPortId:t.routeStartPort[e],endPortId:t.routeEndPort[e],startRegionId:\"string\"==typeof i?.startRegionId?i.startRegionId:void 0,endRegionId:\"string\"==typeof i?.endRegionId?i.endRegionId:void 0,pointIds:bW(i)}})({problem:this.problem,routeId:t,getRouteMetadata:t=\u003ethis.getRouteMetadata(t),getRouteConnectionId:t=\u003ethis.getRouteConnectionId(t)})}getAdditionalRegionLabel(t){}getNeverSuccessfullyRoutedRoutes(){const t=[];for(let e=0;e\u003cthis.problem.routeCount;e++){const n=this.routeAttemptCountByRouteId[e];0===n||this.routeSuccessCountByRouteId[e]\u003e0||t.push({...this.getRouteSummary(e),attempts:n})}return t}logNeverSuccessfullyRoutedRoutes(){if(!this.VERBOSE||this.hasLoggedNeverSuccessfullyRoutedRoutes)return;const t=this.getNeverSuccessfullyRoutedRoutes();if(this.hasLoggedNeverSuccessfullyRoutedRoutes=!0,0!==t.length){console.log([\"[TinyHyperGraphSolver:never-routed-summary]\",`count=${t.length}`].join(\" \"));for(const e of t){const t=e.pointIds.length\u003e=2?`${e.pointIds[0]}-\u003e${e.pointIds[1]}`:\"unknown\";console.log([\"[TinyHyperGraphSolver:never-routed]\",`routeId=${e.routeId}`,`connectionId=${e.connectionId}`,`attempts=${e.attempts}`,`pointPath=${t}`,`startRegionId=${e.startRegionId??\"unknown\"}`,`endRegionId=${e.endRegionId??\"unknown\"}`].join(\" \"))}}}logRipEvent(t,e,n={}){this.VERBOSE\u0026\u0026console.log([\"[TinyHyperGraphSolver:rip]\",`ripCount=${this.state.ripCount}`,`maxRegionCostBeforeRip=${e.toFixed(3)}`,`reason=${t}`,...Object.entries(n).map(([t,e])=\u003e`${t}=${\"number\"==typeof e?Number.isInteger(e)?String(e):e.toFixed(3):e}`)].join(\" \"))}onAllRoutesRouted(){const{topology:t,state:e}=this,n=this.RIP_THRESHOLD_RAMP_ATTEMPTS\u003c=0?1:Math.min(1,e.ripCount/this.RIP_THRESHOLD_RAMP_ATTEMPTS),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(t.regionCount);let s=0;for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;r[n]=t,s=Math.max(s,t),t\u003eo\u0026\u0026i.push(n)}if(this.stats={...this.stats,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:s,ripCount:e.ripCount},0===i.length||e.ripCount\u003e=this.RIP_THRESHOLD_RAMP_ATTEMPTS)this.solved=!0;else{for(let n=0;n\u003ct.regionCount;n++)e.regionCongestionCost[n]+=r[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCostBeforeRip:s,reripRegionCount:i.length},this.logRipEvent(\"hot_regions\",s,{hotRegionCount:i.length,currentRipThreshold:o})}}onOutOfCandidates(){const{topology:t,state:e}=this,n=e.currentRouteId,o=this.getMaxRegionCost();for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;e.regionCongestionCost[n]+=t*this.RIP_CONGESTION_REGION_COST_FACTOR}e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCost:o,maxRegionCostBeforeRip:o,reripReason:\"out_of_candidates\"},this.logRipEvent(\"out_of_candidates\",o,{...void 0===n?{}:{routeId:n,connectionId:this.getRouteConnectionId(n)}})}onPathFound(t){const{state:e}=this,n=e.currentRouteId;if(void 0===n)return;this.routeSuccessCountByRouteId[n]+=1;const o=this.getSolvedPathSegments(t);for(const{regionId:t,fromPortId:i,toPortId:r}of o)e.regionSegments[t].push([n,i,r]),e.portAssignment[i]=e.currentRouteNetId,e.portAssignment[r]=e.currentRouteNetId,this.appendSegmentToRegionCache(t,i,r);e.candidateQueue.clear(),e.currentRouteNetId=void 0,e.currentRouteId=void 0}computeG(t,e){const{topology:n,state:o}=this,i=t.nextRegionId,r=o.regionIntersectionCaches[i],s=this.populateSegmentGeometryScratch(i,t.portId,e),[a,c,l]=gW(r,o.currentRouteNetId,s.lesserAngle,s.greaterAngle,s.layerMask,s.entryExitLayerChanges);if(a\u003e0\u0026\u0026this.isKnownSingleLayerRegion(i))return Number.POSITIVE_INFINITY;const d=this.computeRegionCostForRegion(i,r.existingSameLayerIntersections+a,r.existingCrossingLayerIntersections+c,r.existingEntryExitLayerChanges+l,r.existingSegmentCount+1)-r.existingRegionCost;return t.g+d+o.regionCongestionCost[i]}tryFinalAcceptance(){const t=this.getNeverSuccessfullyRoutedRoutes();this.stats={...this.stats,neverSuccessfullyRoutedRouteCount:t.length},this.logNeverSuccessfullyRoutedRoutes()}computeH(t){return this.problemSetup.portHCostToEndOfRoute[t*this.problem.routeCount+this.state.currentRouteId]}visualize(){return oH(this)}getOutput(){return uW(this)}},aH=t=\u003e{const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;return Number.isFinite(e)?e:void 0},cH=t=\u003e{const e=new Set;for(const n of t.connections??[])e.add(n.startRegionId),e.add(n.endRegionId);const n=new Set(t.regions.filter(t=\u003e(t=\u003e{if(!0!==t.d?._containsObstacle)return!1;if(!0!==t.d?._containsTarget)return!0;const e=aH(t);return void 0===e||-1===e})(t)\u0026\u0026!e.has(t.regionId)).map(t=\u003et.regionId));if(0===n.size)return t;const o=t.ports.filter(t=\u003e!n.has(t.region1Id)\u0026\u0026!n.has(t.region2Id)),i=(t.connections??[]).find(t=\u003en.has(t.startRegionId)||n.has(t.endRegionId));if(i)throw new Error(`Connection \"${i.connectionId}\" references full-obstacle region`);return{...t,regions:t.regions.filter(t=\u003e!n.has(t.regionId)),ports:o}},lH=t=\u003e{const e=t.d?.bounds;if(e)return e;const n=t.d?.center,o=t.d?.width,i=t.d?.height;return n\u0026\u0026\"number\"==typeof n.x\u0026\u0026\"number\"==typeof n.y\u0026\u0026\"number\"==typeof o\u0026\u0026\"number\"==typeof i?{minX:n.x-o/2,maxX:n.x+o/2,minY:n.y-i/2,maxY:n.y+i/2}:{minX:0,maxX:0,minY:0,maxY:0}},dH=t=\u003e{const e=Number(t.d?.z??0);return Number.isFinite(e)?e:0},hH=t=\u003e.005*dH(t),uH=t=\u003eNumber(t.d?.x??0)+hH(t),pH=t=\u003eNumber(t.d?.y??0)+hH(t),mH=(t,e)=\u003e{if(!e)return 0;const n=lH(e),o=uH(t),i=pH(t),r=n.minX\u003c=o\u0026\u0026o\u003c=n.maxX,s=n.minY\u003c=i\u0026\u0026i\u003c=n.maxY;if(s\u0026\u0026o\u003e=n.maxX){const t=Math.max(n.maxY-n.minY,1e-9),e=(i-n.minY)/t;return Math.round(9e3*e)}if(r\u0026\u0026i\u003e=n.maxY){const t=Math.max(n.maxX-n.minX,1e-9),e=(n.maxX-o)/t;return 9e3+Math.round(9e3*e)}if(s\u0026\u0026o\u003c=n.minX){const t=Math.max(n.maxY-n.minY,1e-9),e=(n.maxY-i)/t;return 18e3+Math.round(9e3*e)}if(r\u0026\u0026i\u003c=n.minY){const t=Math.max(n.maxX-n.minX,1e-9),e=(o-n.minX)/t;return 27e3+Math.round(9e3*e)}const a=Math.abs(o-n.minX),c=Math.abs(o-n.maxX),l=Math.abs(i-n.minY),d=Math.abs(i-n.maxY),h=Math.min(a,c,l,d),u=Math.max(n.maxX-n.minX,1e-9),p=Math.max(n.maxY-n.minY,1e-9);if(h===c){const t=(i-n.minY)/p;return Math.round(9e3*t)}if(h===d){const t=(n.maxX-o)/u;return 9e3+Math.round(9e3*t)}if(h===a){const t=(n.maxY-i)/p;return 18e3+Math.round(9e3*t)}const m=(o-n.minX)/u;return 27e3+Math.round(9e3*m)},gH=(t,e)=\u003e{if(!t)return;return[...t.pointIds].sort((t,n)=\u003e{const o=e.get(t),i=e.get(n),r=Number(o?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY),s=Number(i?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY);if(r!==s)return r-s;const a=Number(o?.d?.z??0),c=Number(i?.d?.z??0);return a!==c?a-c:t.localeCompare(n)})[0]},fH=t=\u003e{const e=cH(t),n=new Map,o=new Map,i=new Map,r=new Map((e.solvedRoutes??[]).map(t=\u003e[t.connection.connectionId,t]));e.regions.forEach((t,e)=\u003e{n.set(t.regionId,e)}),e.ports.forEach((t,e)=\u003e{o.set(t.portId,e),i.set(t.portId,t)});const s=e.regions.length,a=e.ports.length,c=e.regions.map(t=\u003et.pointIds.map(t=\u003eo.get(t)).filter(t=\u003evoid 0!==t)),l=Array.from({length:a},()=\u003e[]),d=new Float64Array(s),h=new Float64Array(s),u=new Float64Array(s),p=new Float64Array(s),m=new Int32Array(s),g=new Int32Array(s).fill(-1),f=new Int8Array(s);e.regions.forEach((t,e)=\u003e{const n=(t=\u003e{const e=lH(t),n=\"number\"==typeof t.d?.width?t.d.width:e.maxX-e.minX,o=\"number\"==typeof t.d?.height?t.d.height:e.maxY-e.minY;return{centerX:\"number\"==typeof t.d?.center?.x?t.d.center.x:(e.minX+e.maxX)/2,centerY:\"number\"==typeof t.d?.center?.y?t.d.center.y:(e.minY+e.maxY)/2,width:n,height:o}})(t);d[e]=n.width,h[e]=n.height,u[e]=n.centerX,p[e]=n.centerY,m[e]=(t=\u003e{const e=t.d?.availableZ;if(!Array.isArray(e))return 0;let n=0;for(const t of e)!Number.isInteger(t)||t\u003c0||t\u003e=31||(n|=1\u003c\u003ct);return n})(t);const o=aH(t);void 0!==o\u0026\u0026(g[e]=o,f[e]=1)});const y=new Int32Array(a),_=new Int32Array(a),b=new Float64Array(a),x=new Float64Array(a),v=new Int32Array(a);e.ports.forEach((t,o)=\u003e{const i=n.get(t.region1Id),r=n.get(t.region2Id);if(void 0===i||void 0===r)throw new Error(`Port \"${t.portId}\" references missing regions \"${t.region1Id}\" or \"${t.region2Id}\"`);l[o]=[i,r],b[o]=uH(t),x[o]=pH(t),v[o]=dH(t),y[o]=mH(t,e.regions[i]),_[o]=mH(t,e.regions[r])});const S=e.regions.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedRegionId\",{value:t.regionId,enumerable:!1,configurable:!0,writable:!0}),n})(t,(t=\u003enW(oW(m[t]))??nW((c[t]??[]).map(t=\u003ev[t]))??\"z0\")(e))),I=e.ports.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedPortId\",{value:t.portId,enumerable:!1,configurable:!0,writable:!0}),n})(t,nW([v[e]])??\"z0\")),C=e.connections??[],P=new Map;let M=0;const N=t=\u003e{const e=t.mutuallyConnectedNetworkId??t.connectionId;let n=P.get(e);return void 0===n\u0026\u0026(n=M++,P.set(e,n)),n},w=Array.from({length:s},()=\u003enew Set),T=(t,e)=\u003e{const o=n.get(t);if(void 0===o)throw new Error(`Connection references missing region \"${t}\"`);w[o].add(e)};C.forEach(t=\u003e{const e=N(t);T(t.startRegionId,e),T(t.endRegionId,e)}),w.forEach((t,e)=\u003e{1!==f[e]\u0026\u00261===t.size\u0026\u0026(g[e]=[...t][0])});const R=C.map(t=\u003e{const n=r.get(t.connectionId),o=((t,e)=\u003et.ports.filter(t=\u003et.region1Id===e.startRegionId\u0026\u0026t.region2Id===e.endRegionId||t.region2Id===e.startRegionId\u0026\u0026t.region1Id===e.endRegionId).map(t=\u003et.portId))(e,t);return{connection:t,solvedRoute:n,sharedPortIds:o}}).filter(({solvedRoute:t,sharedPortIds:e})=\u003e0===e.length||(t?.path.length??0)\u003e1),E=R.length,A=new Int8Array(a).fill(1),O=new Int32Array(E),k=new Int32Array(E),L=new Int32Array(E);R.forEach(({connection:t,solvedRoute:n},r)=\u003e{const s=gH(e.regions.find(e=\u003ee.regionId===t.startRegionId),i),a=gH(e.regions.find(e=\u003ee.regionId===t.endRegionId),i),c=n?.path[0]?.portId??s,l=n?.path[n.path.length-1]?.portId??a,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)throw new Error(`Connection \"${t.connectionId}\" could not be mapped to route endpoints`);O[r]=d,k[r]=h,L[r]=N(t)});const D={portCount:a,regionCount:s,regionIncidentPorts:c,incidentPortRegion:l,regionWidth:d,regionHeight:h,regionCenterX:u,regionCenterY:p,regionAvailableZMask:m,regionMetadata:S,portAngleForRegion1:y,portAngleForRegion2:_,portX:b,portY:x,portZ:v,portMetadata:I},z={routeCount:E,portSectionMask:A,routeMetadata:R.map(({connection:t})=\u003et),routeStartPort:O,routeEndPort:k,routeNet:L,regionNetId:g},F=[],B=[];for(const{solvedRoute:t}of R){if(!t){F.push([]),B.push([]);continue}const e=[],i=[];for(let r=1;r\u003ct.path.length;r++){const s=t.path[r-1],a=t.path[r],c=s?.portId,l=a?.portId,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)continue;const u=\"string\"==typeof s?.nextRegionId?s.nextRegionId:\"string\"==typeof a?.lastRegionId?a.lastRegionId:void 0;e.push([d,h]),i.push(void 0!==u?n.get(u):void 0)}F.push(e),B.push(i)}return{topology:D,problem:z,solution:{solvedRoutePathSegments:F,solvedRoutePathRegionIds:B}}},yH=(Number.POSITIVE_INFINITY,1e-9),_H=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,bH=(t,e=0)=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)?t:e,xH=t=\u003e{const e=(t=\u003e{const e=Math.min(t.minX,t.maxX),n=Math.max(t.minX,t.maxX),o=Math.min(t.minY,t.maxY),i=Math.max(t.minY,t.maxY);return{minX:e,maxX:n\u003ee?n:e+yH,minY:o,maxY:i\u003eo?i:o+yH}})(t);return[{x:e.maxX,y:e.minY},{x:e.maxX,y:e.maxY},{x:e.minX,y:e.maxY},{x:e.minX,y:e.minY}]},vH=(t,e)=\u003e{const n=t.filter(t=\u003eNumber.isFinite(t.x)\u0026\u0026Number.isFinite(t.y)),o=n.length\u003e=3?n:xH(e),i=(t=\u003e{let e=0;for(let n=0;n\u003ct.length;n++){const o=t[n],i=t[(n+1)%t.length];e+=o.x*i.y-o.y*i.x}return e})(o);if(Math.abs(i)\u003c=Number.EPSILON)return xH(e);return(t=\u003e{if(t.length\u003c3)throw new Error(\"Convex polygon requires at least three points\");return t})(i\u003c0?[...o].reverse():[...o])},SH=t=\u003e{const e=(t=\u003e{const e=t.d,n=e?.bounds;if(n\u0026\u0026\"number\"==typeof n.minX\u0026\u0026\"number\"==typeof n.maxX\u0026\u0026\"number\"==typeof n.minY\u0026\u0026\"number\"==typeof n.maxY)return{minX:n.minX,maxX:n.maxX,minY:n.minY,maxY:n.maxY};const o=e?.center,i=bH(e?.width,0),r=bH(e?.height,0);return o\u0026\u0026\"number\"==typeof o.x\u0026\u0026\"number\"==typeof o.y?{minX:o.x-i/2,maxX:o.x+i/2,minY:o.y-r/2,maxY:o.y+r/2}:{minX:0,maxX:yH,minY:0,maxY:yH}})(t);return vH((t=\u003e{const e=t.d,n=e?.polygon??e?.points??e?.vertices;if(!Array.isArray(n))return;const o=n.map(t=\u003e{if(!_H(t))return;const e=t.x,n=t.y;return\"number\"==typeof e\u0026\u0026\"number\"==typeof n?{x:e,y:n}:void 0}).filter(t=\u003evoid 0!==t);if(o.length\u003e1){const t=o[0],e=o[o.length-1];t.x===e.x\u0026\u0026t.y===e.y\u0026\u0026o.pop()}return o.length\u003e=3?o:void 0})(t)??xH(e),e)},IH=t=\u003e{let e=0,n=0,o=0,i=0,r=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,a=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY;for(let l=0;l\u003ct.length;l++){const d=t[l],h=t[(l+1)%t.length],u=d.x*h.y-h.x*d.y;e+=u,n+=(d.x+h.x)*u,o+=(d.y+h.y)*u,i+=Math.hypot(h.x-d.x,h.y-d.y),r=Math.min(r,d.x),s=Math.max(s,d.x),a=Math.min(a,d.y),c=Math.max(c,d.y)}const l=Math.abs(e)/2,d=Math.abs(e)\u003eNumber.EPSILON?3*e:Number.NaN,h=t.reduce((e,n)=\u003e({x:e.x+n.x/t.length,y:e.y+n.y/t.length}),{x:0,y:0});return{area:l,perimeter:i,centerX:Number.isFinite(d)?n/d:h.x,centerY:Number.isFinite(d)?o/d:h.y,bounds:{minX:r,maxX:s,minY:a,maxY:c}}},CH=(t,e,n,o)=\u003e{if(n\u003c=0)return{boundaryPosition:0,edgeIndex:0,edgeT:0};let i=Number.POSITIVE_INFINITY,r=0,s=0,a=0,c=0;for(let n=0;n\u003ce.length;n++){const o=e[n],l=e[(n+1)%e.length],d=l.x-o.x,h=l.y-o.y,u=d*d+h*h,p=Math.sqrt(u),m=u\u003c=Number.EPSILON?0:((t.x-o.x)*d+(t.y-o.y)*h)/u,g=Math.min(1,Math.max(0,m)),f=o.x+d*g,y=o.y+h*g,_=t.x-f,b=t.y-y,x=_*_+b*b;x\u003ci\u0026\u0026(i=x,r=n,s=g,a=c+p*g),c+=p}return{boundaryPosition:Math.round(a/n*o)%o,edgeIndex:r,edgeT:s}},PH=(t,e)=\u003e{const n=t.regionMetadata?.[e];return _H(n)\u0026\u0026\"string\"==typeof n.serializedRegionId?n.serializedRegionId:`region-${e}`},MH=(t,e)=\u003e{const n=t.portMetadata?.[e];return _H(n)\u0026\u0026\"string\"==typeof n.serializedPortId?n.serializedPortId:`port-${e}`},NH=(t,e,n,o)=\u003e{const i={..._H(t)?{...t}:void 0===t?{}:{value:t},polygon:n,sourceBounds:o};return Object.defineProperty(i,\"serializedRegionId\",{value:e,enumerable:!1,configurable:!0,writable:!0}),i},wH=(t,e)=\u003e{const n=new Map,o=new Map,i=new Map,r=new Map;for(let e=0;e\u003ct.regionCount;e++)n.set(PH(t,e),e);for(let e=0;e\u003ct.portCount;e++)o.set(MH(t,e),e);for(let t=0;t\u003ce.routeCount;t++){const n=e.routeMetadata?.[t];if(!_H(n))continue;\"string\"==typeof n.connectionId\u0026\u0026i.set(n.connectionId,t);const o=\"string\"==typeof n.mutuallyConnectedNetworkId?n.mutuallyConnectedNetworkId:\"string\"==typeof n.connectionId?n.connectionId:void 0;void 0!==o\u0026\u0026r.set(o,e.routeNet[t])}return{serializedRegionIdToRegionId:n,serializedPortIdToPortId:o,connectionIdToRouteId:i,netIdToNetIndex:r}},TH=(t,e,n)=\u003e{const o=t.incidentPortRegion[e];return o[0]===n||o[1]!==n?t.portBoundaryPositionForRegion1[e]:t.portBoundaryPositionForRegion2[e]},RH=class extends sH{constructor(t,e,n){super(t,e,n),this.topology=t,this.problem=e}topology;problem;polySegmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.polySegmentGeometryScratch,r=TH(o,e,t),s=TH(o,n,t),a=o.portZ[e],c=o.portZ[n];return i.lesserAngle=r\u003cs?r:s,i.greaterAngle=r\u003cs?s:r,i.layerMask=1\u003c\u003ca|1\u003c\u003cc,i.entryExitLayerChanges=a!==c?1:0,i}computeRegionCostForRegion(t,e,n,o,i){return mW(this.topology.regionArea[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0)}visualize(){return $H(this)}},EH=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),AH=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},OH=(t,e,n=.85)=\u003e{const o=`${t.problem.routeNet[e]}:${AH(t,e)}`;let i=0;for(let t=0;t\u003co.length;t++)i=17777*o.charCodeAt(t)+((i\u003c\u003c5)-i);return`hsla(${Math.abs(i)%360}, 70%, 45%, ${n})`},kH=(t,e)=\u003e{const n=t.regionVertexStart[e],o=t.regionVertexCount[e],i=[];for(let e=0;e\u003co;e++){const o=n+e;i.push({x:t.regionVertexX[o],y:t.regionVertexY[o]})}return i},LH=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e]?.existingRegionCost??0,o=Math.min(1,Math.max(0,Math.pow(n,.8))),i=Math.round(245-105*o);return`rgba(245, ${Math.round(248-168*o)}, ${i}, ${.18+.48*o})`},DH=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e],o=PH(t.topology,e),i=t.problem.regionNetId[e];return EH(`region: ${o}`,`net: ${-1===i?\"free\":i}`,`area: ${t.topology.regionArea[e].toFixed(3)}`,`cost: ${(n?.existingRegionCost??0).toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},zH=(t,e)=\u003enW(oW(t.topology.regionAvailableZMask?.[e]??0))??nW((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))??\"z0\",FH=(t,e)=\u003e({x:t.topology.portX[e],y:t.topology.portY[e]}),BH=(t,e)=\u003enW([t.topology.portZ[e]])??\"z0\",jH=(t,e)=\u003e{const[n,o]=t.topology.incidentPortRegion[e]??[];return EH(`port: ${MH(t.topology,e)}`,`connects: ${n??\"?\"} \u003c-\u003e ${o??\"?\"}`,`z: ${t.topology.portZ[e]}`)},$H=t=\u003e{const e={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:\"Poly HyperGraph\",coordinateSystem:\"cartesian\"};for(let n=0;n\u003ct.topology.regionCount;n++)e.polygons.push({points:kH(t.topology,n),fill:LH(t,n),stroke:\"rgba(80, 80, 120, 0.55)\",layer:zH(t,n),label:DH(t,n)});for(let n=0;n\u003ct.topology.portCount;n++)e.circles.push({center:FH(t,n),radius:.05,fill:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.55)\":\"rgba(80, 80, 80, 0.45)\",layer:BH(t,n),label:jH(t,n)});((t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=AH(t,n),s=OH(t,n);e.points.push({...FH(t,o),color:s,layer:BH(t,o),label:EH(`route: ${r}`,\"endpoint: start\",jH(t,o))}),e.points.push({...FH(t,i),color:s,layer:BH(t,i),label:EH(`route: ${r}`,\"endpoint: end\",jH(t,i))})}})(t,e),((t,e)=\u003e{for(let n=0;n\u003ct.state.regionSegments.length;n++)for(const[o,i,r]of t.state.regionSegments[n]??[])e.lines.push({points:[FH(t,i),FH(t,r)],strokeColor:OH(t,o),layer:nW([t.topology.portZ[i],t.topology.portZ[r]])??\"z0\",label:EH(`route: ${AH(t,o)}`,`region: ${PH(t.topology,n)}`)})})(t,e),((t,e)=\u003e{if(t.solved)return;const n=t.state.candidateQueue.toArray().sort((t,e)=\u003et.f-e.f).slice(0,10);for(let o=0;o\u003cn.length;o++){const i=n[o];e.points.push({...FH(t,i.portId),color:0===o?\"green\":\"rgba(128, 128, 128, 0.4)\",layer:BH(t,i.portId),label:EH(jH(t,i.portId),`g: ${i.g.toFixed(2)}`,`h: ${i.h.toFixed(2)}`,`f: ${i.f.toFixed(2)}`)})}const o=n[0];if(!o)return;const i=[];let r=o;for(;r;)i.unshift(FH(t,r.portId)),r=r.prevCandidate;if(i.length\u003c=1)return;const s=t.state.currentRouteId;e.lines.push({points:i,strokeColor:void 0!==s?OH(t,s,.95):\"rgba(0, 160, 120, 0.95)\",strokeDash:\"4 3\",layer:BH(t,o.portId),label:EH(void 0!==s?`route: ${AH(t,s)}`:void 0,\"active candidate path\",`candidate port: ${MH(t.topology,o.portId)}`)})})(t,e);const n=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1);return e.title=[\"Poly HyperGraph\",`iter=${t.iterations}`,`pending=${n}`,t.failed?\"failed\":t.solved?\"solved\":\"running\"].join(\" | \"),e},YH=(new Int32Array(0),t=\u003e(t.ccwRotationDegrees??0)*Math.PI/180),XH=(t,e=8)=\u003e{const n=t.width/2,o=t.height/2,i=YH(t),r=Math.cos(i),s=Math.sin(i);return Array.from({length:e},(i,a)=\u003e{const c=2*Math.PI*a/e,l=n*Math.cos(c),d=o*Math.sin(c);return{x:t.center.x+l*r-d*s,y:t.center.y+l*s+d*r}})},VH=t=\u003e(t.obstacles??[]).filter(t=\u003e\"oval\"===t.type).map(t=\u003e({points:XH(t),layers:t.layers,zLayers:t.__zLayers,isCopperPour:t.isCopperPour})),WH=(t,e)=\u003e(t.obstacles??[]).flatMap((n,o)=\u003e{if(!Array.isArray(n.connectedTo)||0===n.connectedTo.length)return[];const i=oV(sV(n,t.layerCount),t.layerCount);if(0===i.length)return[];let r;const s=n.type;if(\"rect\"===s)r=((t,e=0)=\u003e{const n=t.width/2+e,o=t.height/2+e,i=YH(t),r=Math.cos(i),s=Math.sin(i);return[{localX:-n,localY:-o},{localX:n,localY:-o},{localX:n,localY:o},{localX:-n,localY:o}].map(({localX:e,localY:n})=\u003e({x:t.center.x+e*r-n*s,y:t.center.y+e*s+n*r}))})(n,e);else{if(\"oval\"!==s)return[];r=EV({polygon:{points:XH(n),layers:n.layers,zLayers:n.__zLayers,isCopperPour:n.isCopperPour},clearance:e,verticesOnly:!0})}return[{regionId:`connected-obstacle-${o}`,polygon:r,availableZ:i,connectedTo:n.connectedTo,d:{obstacleIndex:o,obstacleType:s,connectedTo:n.connectedTo}}]}),HH=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},GH=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},UH=(t,e)=\u003e{const n=HH(t).serializedRegionId;return\"string\"==typeof n?n:`region-${e}`},ZH=(t,e)=\u003e{const n=GH(t);return\"string\"==typeof n.serializedPortId?n.serializedPortId:\"string\"==typeof n.portId?n.portId:`poly-port-${e}`},qH=t=\u003e{const e=GH(t);return{prevPortPointId:\"string\"==typeof e.prevPortPointId?e.prevPortPointId:void 0,nextPortPointId:\"string\"==typeof e.nextPortPointId?e.nextPortPointId:void 0}},JH=t=\u003e{const e=HH(t).polygon;if(Array.isArray(e)\u0026\u0026!(e.length\u003c3))return e.every(t=\u003e\"object\"==typeof t\u0026\u0026null!==t\u0026\u0026\"number\"==typeof t.x\u0026\u0026\"number\"==typeof t.y)?e:void 0},KH=class extends si{constructor(t){super(),this.params=t,this.effort=t.effort??1,this.clearance=t.srj.defaultObstacleMargin??t.srj.minTraceWidth;const e=e=\u003e{return eW({bounds:t.srj.bounds,rects:(n=t.srj,(n.obstacles??[]).filter(t=\u003e\"rect\"===t.type).map(t=\u003e({center:t.center,width:t.width,height:t.height,ccwRotation:YH(t),layers:t.layers,zLayers:t.__zLayers,isCopperPour:t.isCopperPour}))),polygons:VH(t.srj),clearance:this.clearance,concavityTolerance:t.concavityTolerance??0,layerCount:t.srj.layerCount,layerMergeMode:t.layerMergeMode??\"same\",useConstrainedDelaunay:e,usePolyanyaMerge:t.usePolyanyaMerge??!1,viaSegments:t.viaSegments??8});var n},n=t.useConstrainedDelaunay??!0;try{this.convexRegions=e(n)}catch(t){if(!n)throw t;this.usedUnconstrainedDelaunayFallback=!0,this.convexRegions=e(!1)}var o;this.serializedGraph=RV({regions:this.convexRegions.regions,availableZ:this.convexRegions.availableZ,layerCount:t.srj.layerCount,connections:(o=t.srj,o.connections.flatMap(t=\u003e{const e=t.pointsToConnect??[];if(e.length\u003c2)return[];const n=e[0];return e.slice(1).map((e,o)=\u003e{const i=((t,e,n,o)=\u003e{const i=2===t.pointsToConnect.length?t.name:`${t.name}::${o}`;return{...t,name:i,__rootConnectionNames:t.__rootConnectionNames??[t.name],pointsToConnect:[e,n]}})(t,n,e,o);return{connectionId:i.name,mutuallyConnectedNetworkId:i.__rootConnectionNames?.[0]??i.name,start:n,end:e,simpleRouteConnection:i}})})),obstacleRegions:WH(t.srj,this.clearance),portSpacing:t.portSpacing??lV,portMarginFromSegmentEndpoint:t.portMarginFromSegmentEndpoint??dV}),this.loaded=((t,e={})=\u003e{const n=e.boundaryCoordinateScale??36e3,o=fH(t),{topology:i,problem:r,solution:s}=o,a=new Map(t.regions.map(t=\u003e[t.regionId,t])),c=[];for(let t=0;t\u003ci.regionCount;t++){const e=PH(i,t),n=a.get(e),o=n?SH(n):xH({minX:i.regionCenterX[t]-i.regionWidth[t]/2,maxX:i.regionCenterX[t]+i.regionWidth[t]/2,minY:i.regionCenterY[t]-i.regionHeight[t]/2,maxY:i.regionCenterY[t]+i.regionHeight[t]/2});c.push(o)}const l=c.reduce((t,e)=\u003et+e.length,0),d=new Int32Array(i.regionCount),h=new Int32Array(i.regionCount),u=new Float64Array(l),p=new Float64Array(l),m=new Float64Array(i.regionCount),g=new Float64Array(i.regionCount),f=new Float64Array(i.regionCount),y=new Float64Array(i.regionCount),_=new Float64Array(i.regionCount),b=new Float64Array(i.regionCount),x=new Float64Array(i.regionCount),v=new Float64Array(i.regionCount),S=new Float64Array(i.regionCount),I=new Float64Array(i.regionCount),C=new Array(i.regionCount);let P=0;for(let t=0;t\u003ci.regionCount;t++){const e=c[t],n=IH(e),o=Math.sqrt(Math.max(n.area,yH));d[t]=P,h[t]=e.length,m[t]=n.area,g[t]=n.perimeter,f[t]=n.centerX,y[t]=n.centerY,_[t]=n.bounds.minX,b[t]=n.bounds.maxX,x[t]=n.bounds.minY,v[t]=n.bounds.maxY,S[t]=o,I[t]=o,C[t]=NH(i.regionMetadata?.[t],PH(i,t),e,n.bounds);for(const t of e)u[P]=t.x,p[P]=t.y,P+=1}const M=new Int32Array(i.portCount),N=new Int32Array(i.portCount),w=new Int32Array(i.portCount),T=new Int32Array(i.portCount),R=new Float64Array(i.portCount),E=new Float64Array(i.portCount);for(let t=0;t\u003ci.portCount;t++){const e={x:i.portX[t],y:i.portY[t]},[o,r]=i.incidentPortRegion[t]??[];if(void 0!==o){const i=CH(e,c[o],g[o],n);M[t]=i.boundaryPosition,w[t]=i.edgeIndex,R[t]=i.edgeT}if(void 0!==r){const o=CH(e,c[r],g[r],n);N[t]=o.boundaryPosition,T[t]=o.edgeIndex,E[t]=o.edgeT}}for(let t=0;t\u003ci.regionCount;t++)C[t].layer=nW(oW(i.regionAvailableZMask?.[t]??0))??nW((i.regionIncidentPorts[t]??[]).map(t=\u003ei.portZ[t]))??\"z0\";const A={...i,regionWidth:S,regionHeight:I,regionCenterX:f,regionCenterY:y,regionMetadata:C,portAngleForRegion1:M,portAngleForRegion2:N,regionVertexStart:d,regionVertexCount:h,regionVertexX:u,regionVertexY:p,regionArea:m,regionPerimeter:g,regionBoundsMinX:_,regionBoundsMaxX:b,regionBoundsMinY:x,regionBoundsMaxY:v,portBoundaryPositionForRegion1:M,portBoundaryPositionForRegion2:N,portEdgeIndexForRegion1:w,portEdgeIndexForRegion2:T,portEdgeTForRegion1:R,portEdgeTForRegion2:E};return{topology:A,problem:r,solution:s,mapping:wH(A,r)}})(this.serializedGraph),this.reservedRegionCount=((t,e)=\u003e{const n=t.problem.regionNetId;if(!n)return 0;const o=new Map;for(const t of e.regions){const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;Number.isInteger(e)\u0026\u0026e\u003e=0\u0026\u0026o.set(t.regionId,e)}let i=0;for(let e=0;e\u003ct.topology.regionCount;e++){const r=t.topology.regionMetadata?.[e],s=\"object\"==typeof r\u0026\u0026null!==r?r.serializedRegionId:void 0;if(\"string\"!=typeof s)continue;const a=o.get(s);void 0!==a\u0026\u0026(n[e]=a,i+=1)}return i})(this.loaded,this.serializedGraph);const i={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.max(1,Math.ceil(10*this.effort)),MAX_ITERATIONS:Math.max(1e5,Math.ceil(1e7*this.effort))};this.polySolver=new RH(this.loaded.topology,this.loaded.problem,i),this.activeSubSolver=this.polySolver,this.MAX_ITERATIONS=i.MAX_ITERATIONS+1e3,this.inputNodeWithPortPoints=this.createInputNodesWithPortPoints()}params;getSolverName(){return\"PolyHypergraphPortPointPathingSolver\"}convexRegions;serializedGraph;loaded;polySolver;inputNodeWithPortPoints=[];nodesWithPortPoints=[];reservedRegionCount=0;clearance;effort;usedUnconstrainedDelaunayFallback=!1;createInputNodesWithPortPoints(){const{topology:t}=this.loaded,e=[];for(let n=0;n\u003ct.regionCount;n++){const o=HH(t.regionMetadata?.[n]??{}),i=UH(o,n);if(i.startsWith(\"terminal-\"))continue;const r=(t.regionIncidentPorts[n]??[]).map(e=\u003e{const n=t.incidentPortRegion[e]??[],o=t.portMetadata?.[e];return{portPointId:ZH(o,e),x:t.portX[e],y:t.portY[e],z:t.portZ[e],...qH(o),connectionNodeIds:n.map(e=\u003eUH(t.regionMetadata?.[e],e)),distToCentermostPortOnZ:t.portMetadata?.[e]?.distToCentermostPortOnZ??0,connectsToOffBoardNode:!1}});e.push({capacityMeshNodeId:i,center:{x:t.regionCenterX[n],y:t.regionCenterY[n]},width:t.regionWidth[n],height:t.regionHeight[n],portPoints:r,availableZ:o.availableZ??Array.from({length:this.params.srj.layerCount},(t,e)=\u003ee),_containsObstacle:Boolean(o._containsObstacle),_containsTarget:Boolean(o._containsTarget)})}return e}createAssignedPortPoint(t,e){const n=this.polySolver.problem.routeMetadata?.[t],o=n?(t=\u003et.simpleRouteConnection?.name??t.connectionId)(n):`route-${t}`,i=n?(t=\u003et.simpleRouteConnection?.rootConnectionName??t.mutuallyConnectedNetworkId)(n):void 0,r=this.polySolver.topology.portMetadata?.[e];return{portPointId:ZH(r,e),x:this.polySolver.topology.portX[e],y:this.polySolver.topology.portY[e],z:this.polySolver.topology.portZ[e],connectionName:o,rootConnectionName:i,...qH(r)}}buildOutputNodes(){const{topology:t,state:e}=this.polySolver,n=[];for(let o=0;o\u003ce.regionSegments.length;o++){const i=HH(t.regionMetadata?.[o]??{}),r=UH(i,o);if(r.startsWith(\"terminal-\"))continue;const s=JH(i);if(!s)continue;const a=(e.regionSegments[o]??[]).flatMap(([t,e,n])=\u003e{const o=this.createAssignedPortPoint(t,e),i=this.createAssignedPortPoint(t,n);return o.portPointId\u0026\u0026i.portPointId\u0026\u0026(o.nextPortPointId=i.portPointId,i.prevPortPointId=o.portPointId),[o,i]});0!==a.length\u0026\u0026n.push({capacityMeshNodeId:r,center:{x:t.regionCenterX[o],y:t.regionCenterY[o]},width:t.regionWidth[o],height:t.regionHeight[o],polygon:s,portPoints:a,availableZ:i.availableZ})}this.nodesWithPortPoints=n}_step(){this.polySolver.step(),this.progress=this.polySolver.progress,this.stats={...this.polySolver.stats??{},reservedRegionCount:this.reservedRegionCount,usedUnconstrainedDelaunayFallback:this.usedUnconstrainedDelaunayFallback,regionCount:this.loaded.topology.regionCount,portCount:this.loaded.topology.portCount,routeCount:this.loaded.problem.routeCount},this.polySolver.solved?(this.buildOutputNodes(),this.solved=!0,this.activeSubSolver=null):this.polySolver.failed\u0026\u0026(this.error=this.polySolver.error,this.failed=!0,this.activeSubSolver=null)}getOutput(){return{nodesWithPortPoints:this.nodesWithPortPoints,inputNodeWithPortPoints:this.inputNodeWithPortPoints}}computeNodePf(t){const e=this.nodesWithPortPoints.find(e=\u003ee.capacityMeshNodeId===t.capacityMeshNodeId);if(!e)return null;const n=Ms(e);return Ys({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,layer:\"top\",availableZ:e.availableZ??[]},n.numSameLayerCrossings,n.numEntryExitLayerChanges,n.numTransitionPairCrossings)}getConstructorParams(){return[this.params]}preview(){return this.visualize()}visualize(){return this.polySolver.visualize()}},QH=class extends si{constructor(t){super(),this.inputSrj=t,this.MAX_ITERATIONS=1}inputSrj;outputSrj;_step(){this.outputSrj=mX(this.inputSrj)??this.inputSrj,this.solved=!0}getOutputSimpleRouteJson(){if(!this.outputSrj)throw new Error(\"PreprocessSimpleRouteJsonSolver has not solved yet\");return this.outputSrj}getConstructorParams(){return[this.inputSrj]}visualize(){return this.outputSrj?pi(Ho({...this.outputSrj,traces:[]}),Yj({srj:this.outputSrj})):{lines:[],points:[],rects:[],circles:[]}}},tG=(t,e)=\u003e(t.x-e.x)**2+(t.y-e.y)**2,eG=(t,e,n)=\u003e{if(!n)return;const o=t.filter(({projected:t})=\u003et.connectionName===e\u0026\u0026(void 0===n.z||t.z===n.z));return 0!==o.length?o.reduce((t,e)=\u003etG(e.projected,n)\u003ctG(t.projected,n)?e:t).original:void 0},nG=(t,e)=\u003e{const n=e.projectedRect;if(!n)throw new Error(\"Poly node is missing projectedRect\");const o=n.rectToPolygonMatrix,i=(t=\u003e{if(!t.projectedRect)throw new Error(\"Poly node is missing projectedRect\");return t.portPoints.map(e=\u003e{const n=ZX(e,t.projectedRect);return{original:e,projected:{...e,x:n.x,y:n.y}}})})(e),r=t.route.map(t=\u003e({...t,...HX(o,t)})),s=t.vias.map(t=\u003eHX(o,t)),a=eG(i,t.connectionName,t.route[0]),c=eG(i,t.connectionName,t.route[t.route.length-1]);return a\u0026\u0026r[0]\u0026\u0026(r[0]={...r[0],x:a.x,y:a.y,z:a.z}),c\u0026\u0026r[r.length-1]\u0026\u0026(r[r.length-1]={...r[r.length-1],x:c.x,y:c.y,z:c.z}),{...t,route:r,vias:s,jumpers:t.jumpers?.map(t=\u003e({...t,start:HX(o,t.start),end:HX(o,t.end)}))}},oG=class extends si{getSolverName(){return\"ProjectHighDensityToPolygonSolver\"}routes=[];routesByNodeId=new Map;colorMap;nodePortPoints;rawRoutesByNodeId;constructor({nodePortPoints:t,routesByNodeId:e,colorMap:n}){super(),this.MAX_ITERATIONS=1,this.nodePortPoints=t,this.rawRoutesByNodeId=e instanceof Map?new Map(e):new Map(Object.entries(e)),this.colorMap=n??{}}_step(){this.routes=[],this.routesByNodeId=new Map;for(const t of this.nodePortPoints){const e=(this.rawRoutesByNodeId.get(t.capacityMeshNodeId)??[]).map(e=\u003enG(e,t));e.length\u003e0\u0026\u0026(this.routesByNodeId.set(t.capacityMeshNodeId,e),this.routes.push(...e))}this.solved=!0}getOutput(){return this.routes}getConstructorParams(){return[{nodePortPoints:this.nodePortPoints,routesByNodeId:this.rawRoutesByNodeId,colorMap:this.colorMap}]}visualize(){const t={polygons:this.nodePortPoints.flatMap(t=\u003e[{points:t.polygon,fill:\"rgba(40, 140, 220, 0.06)\",stroke:\"rgba(20, 70, 160, 0.65)\",label:`${t.capacityMeshNodeId} polygon`},...t.projectedRect?[{points:t.projectedRect.targetQuad,fill:\"rgba(255, 165, 0, 0.05)\",stroke:\"rgba(255, 120, 0, 0.45)\",label:`${t.capacityMeshNodeId} projection target`}]:[]]),lines:[],circles:[]};for(const e of this.routes){const n=this.colorMap[e.connectionName]??\"#0000ff\",o=mi(e.route,e.connectionName,n);for(const n of o)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:To(n.color,.5),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?[.1,.3]:void 0});for(const o of e.vias)t.circles.push({center:o,layer:\"z0,1\",radius:e.viaDiameter/2,fill:n,label:`${e.connectionName} via`})}return t}};function iG(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var rG=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),this.equivalentAreaExpansionFactor=n.equivalentAreaExpansionFactor??2,this.minProjectedRectDimension=n.minProjectedRectDimension??3*this.minTraceWidth,void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;polyGraphSolver;attachProjectedRectsSolver;highDensityRouteSolver;projectHighDensityToPolgonSolver;highDensityStitchSolver;traceSimplificationSolver;traceWidthSolver;globalDrcForceImproveSolver;colorMap;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;equivalentAreaExpansionFactor;minProjectedRectDimension;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;highDensityNodePortPoints;projectedHighDensityNodePortPoints;cacheProvider=null;pipelineDef=[iG(\"preprocessSimpleRouteJsonSolver\",QH,t=\u003e[t.originalSrj],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),iG(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),iG(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),iG(\"polyGraphSolver\",KH,t=\u003e[{srj:t.srjWithPointPairs,effort:t.effort,concavityTolerance:t.opts.polyConcavityTolerance,portSpacing:t.opts.polyPortSpacing,portMarginFromSegmentEndpoint:t.opts.polyPortMarginFromSegmentEndpoint}],{onSolved:t=\u003e{t.highDensityNodePortPoints=t.polyGraphSolver?.getOutput().nodesWithPortPoints??[]}}),iG(\"attachProjectedRectsSolver\",JX,t=\u003e[{nodesWithPortPoints:t.highDensityNodePortPoints??[],equivalentAreaExpansionFactor:t.equivalentAreaExpansionFactor,minProjectedRectDimension:t.minProjectedRectDimension,traceWidth:t.minTraceWidth,viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.projectedHighDensityNodePortPoints=t.attachProjectedRectsSolver?.getOutput()??[]}}),iG(\"highDensityRouteSolver\",QX,t=\u003e[{nodePortPoints:t.projectedHighDensityNodePortPoints??[],nodePfById:new Map((t.polyGraphSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.polyGraphSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,effort:t.effort}]),iG(\"projectHighDensityToPolgonSolver\",oG,t=\u003e[{nodePortPoints:t.projectedHighDensityNodePortPoints??[],routesByNodeId:t.highDensityRouteSolver.routesByNodeId,colorMap:t.colorMap}]),iG(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.projectHighDensityToPolgonSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),iG(\"traceSimplificationSolver\",vc,t=\u003e[{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}]),iG(\"traceWidthSolver\",Ic,t=\u003e[{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}]),iG(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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\u0026\u0026(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\"}getProblemVisualization({includeRoutes:t=!0}={}){const e=this.originalSrj,n=[{points:[{x:e.bounds?.minX??-50,y:e.bounds?.minY??-50},{x:e.bounds?.maxX??50,y:e.bounds?.minY??-50},{x:e.bounds?.maxX??50,y:e.bounds?.maxY??50},{x:e.bounds?.minX??-50,y:e.bounds?.maxY??50},{x:e.bounds?.minX??-50,y:e.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}];if(e.outline\u0026\u0026e.outline.length\u003e=2){const t=e.outline.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),n.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const o=Oo(e),i={points:[...e.connections.flatMap(t=\u003et.pointsToConnect.map(n=\u003e({...n,layer:Fo(n,e.layerCount),label:`${t.name} ${n.pcb_port_id??\"\"}`})))],rects:[...(e.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,e.layerCount),label:o(t)}))],lines:n};if(!t)return i;const r=Yj({srj:e});return pi(i,r)}visualize(){if(!this.solved\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.getProblemVisualization(),e=this.getProblemVisualization({includeRoutes:!1}),n=this.polyGraphSolver?.visualize(),o=this.attachProjectedRectsSolver?.visualize(),i=this.highDensityRouteSolver?.visualize(),r=this.projectHighDensityToPolgonSolver?.visualize(),s=this.highDensityStitchSolver?.visualize(),a=this.traceSimplificationSolver?.visualize();return pi(...[t,this.escapeViaLocationSolver?.visualize(),this.netToPointPairsSolver?.visualize(),n,o,i?pi(e,i):null,r?pi(e,r):null,s,a,this.solved?pi({lines:e.lines},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean))}preview(){if(this.projectHighDensityToPolgonSolver){const t=[];for(let e=this.projectHighDensityToPolgonSolver.routes.length-1;e\u003e=0;e--){const n=this.projectHighDensityToPolgonSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.polyGraphSolver?this.polyGraphSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){return this.globalDrcForceImproveSolver?.getOutput()??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 o=n.__netConnectionName??this.originalSrj.connections.find(t=\u003et.name===n.name)?.__netConnectionName,i=e.filter(t=\u003et.connectionName===n.name);for(let e=0;e\u003ci.length;e++){const r=i[e],s={type:\"pcb_trace\",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},sG=t=\u003et.rootConnectionName??t.connectionName,aG=(t,e)=\u003et.flatMap((t,n)=\u003esG(t)===e?[n]:[]),cG=(t,e,n,o)=\u003e{const i=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=t.x-e.x,s=t.y-e.y,a=o**2+i**2,c=0===a?0:Math.max(0,Math.min(1,(r*o+s*i)/a));return Math.hypot(t.x-(e.x+c*o),t.y-(e.y+c*i))},r={x:e.x-t.x,y:e.y-t.y},s={x:o.x-n.x,y:o.y-n.y},a={x:n.x-t.x,y:n.y-t.y},c=(t,e)=\u003et.x*e.y-t.y*e.x,l=c(r,s),d=Math.hypot(r.x,r.y),h=1e-12*(d*Math.hypot(s.x,s.y)+1);if(Math.abs(l)\u003eh){const t=c(a,s)/l,e=c(a,r)/l;if(t\u003e=-1e-12\u0026\u0026t\u003c=1+1e-12\u0026\u0026e\u003e=-1e-12\u0026\u0026e\u003c=1+1e-12)return 0}else if(d\u003e1e-12\u0026\u0026Math.abs(c(a,r))\u003c=h){const i=Math.abs(r.x)\u003e=Math.abs(r.y),s=Math.min(i?t.x:t.y,i?e.x:e.y),a=Math.max(i?t.x:t.y,i?e.x:e.y),c=Math.min(i?n.x:n.y,i?o.x:o.y),l=Math.max(i?n.x:n.y,i?o.x:o.y);if(Math.max(s,c)\u003c=Math.min(a,l)+1e-12)return 0}return Math.min(i(t,n,o),i(e,n,o),i(n,t,e),i(o,t,e))},lG=(t,e)=\u003eMath.hypot(e.x-t.x,e.y-t.y),dG=t=\u003e{let e=0;for(let n=0;n\u003ct.route.length-1;n++)e+=lG(t.route[n],t.route[n+1]);return e},hG=(t,e)=\u003ee.reduce((e,n)=\u003ee+dG(t[n]),0),uG=(t,e)=\u003e{const n=t.__zLayers,o=t.zLayers,i=void 0!==n?n:o;if(void 0!==i){if(!Array.isArray(i)||0===i.length||i.some(t=\u003e!Number.isInteger(t)||t\u003c0||t\u003e=e))throw new Error(\"Obstacle has invalid z-layer indexes\");return i}if(0===t.layers.length)throw new Error(\"Obstacle has no declared layers\");return t.layers.map(t=\u003e{if(\"top\"===t)return 0;if(\"bottom\"===t)return e-1;const n=/^inner(\\d+)$/.exec(t),o=n?Number(n[1]):-1;if(o\u003c=0||o\u003e=e-1)throw new Error(`Obstacle has invalid layer name \"${t}\"`);return o})},pG=t=\u003e{const e=(t,e,n,o)=\u003e{const i=n.center.x-n.width/2-o,r=n.center.x+n.width/2+o,s=n.center.y-n.height/2-o,a=n.center.y+n.height/2+o;if(t.x\u003e=i\u0026\u0026t.x\u003c=r\u0026\u0026t.y\u003e=s\u0026\u0026t.y\u003c=a||e.x\u003e=i\u0026\u0026e.x\u003c=r\u0026\u0026e.y\u003e=s\u0026\u0026e.y\u003c=a)return!0;const c=[{x:i,y:s},{x:r,y:s},{x:r,y:a},{x:i,y:a}];return c.some((n,o)=\u003e0===cG(t,e,n,c[(o+1)%c.length]))};if(t.bounds\u0026\u0026t.meanderPoints.some(e=\u003ee.x\u003ct.bounds.minX||e.x\u003et.bounds.maxX||e.y\u003ct.bounds.minY||e.y\u003et.bounds.maxY))return!1;const n=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},o=sG(t.route),i=t.route.traceThickness/2+t.obstacleMargin;for(let r=0;r\u003ct.meanderPoints.length-1;r++){const s=t.meanderPoints[r],a=t.meanderPoints[r+1];for(const n of t.obstacles){if(!uG(n,t.layerCount).includes(s.z))continue;const c=0===r||r===t.meanderPoints.length-2;if((!n.connectedTo.includes(o)||!c)\u0026\u0026e(s,a,n,i))return!1}for(const e of t.routedRoutes){const i=sG(e)===o;for(const o of e.vias){if(o.zLayers\u0026\u0026!o.zLayers.includes(s.z))continue;const r=Math.hypot(o.x-s.x,o.y-s.y)\u003c=1e-8||Math.hypot(o.x-a.x,o.y-a.y)\u003c=1e-8,c=t.route.traceThickness/2+e.viaDiameter/2+t.obstacleMargin;if((!i||!r)\u0026\u0026n(o,s,a)\u003cc)return!1}if(!i)for(let n=0;n\u003ce.route.length-1;n++){const o=e.route[n],i=e.route[n+1];if(s.z!==o.z||s.z!==i.z)continue;const r=t.route.traceThickness/2+e.traceThickness/2+t.obstacleMargin;if(cG(s,a,o,i)\u003cr)return!1}}}return!0},mG=t=\u003e{const e=[];for(const n of t.routeIndexes){const o=t.routes[n],i=t.minMeanderGap??Math.max(.3,2*o.traceThickness),r=o.traceThickness+i,s=Math.max(t.minimumToothPitch??0,2*r),a=t.minMeanderHeight??r;for(let i=0;i\u003co.route.length-1;i++){const r=o.route[i],c=o.route[i+1],l=lG(r,c);if(l\u003c=0||r.z!==c.z)continue;const d=Math.min(Math.max(0,Math.floor(l/s)-1),t.maxToothCount);for(let o=1;o\u003c=d;o++){const r=l/(o+1),c=[r,Math.sqrt(s*r),s].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e-t)\u003c1e-9)===e),d=o%2==0?[\"balanced\",\"negative\",\"positive\"]:[\"negative\",\"positive\"];for(const r of c)for(const s of d)e.push({routeIndex:n,segmentIndex:i,segmentLength:l,toothCount:o,maximumDepth:t.maximumDepth,minimumHeight:a,toothPitch:r,placement:s,heightProfile:o\u003e1?\"tapered\":\"uniform\"})}}}const n={balanced:0,negative:1,positive:2};return e.sort((t,e)=\u003et.toothCount-e.toothCount||n[t.placement]-n[e.placement]||e.toothPitch-t.toothPitch||e.segmentLength-t.segmentLength)},gG=t=\u003e{if(null===t.centerlineDistanceCost)return 0;const e=t.predictedToothDepths.flatMap((t,e)=\u003et\u003e0?[e]:[]);if(0===e.length)return 0;const n=e.map(e=\u003et.predictedToothDepths[e]),o=Math.max(...n),i=n.reduce((t,e)=\u003et+e,0)/n.length,r=Math.sqrt(n.reduce((t,e)=\u003et+(e-i)**2,0)/n.length),s=e[0],a=(e.at(-1)-s+1)*t.toothPitch,c=o/(t.toothPitch/2),l=t.addedLength/a,d=c/(1+c)*40,h=l/(1+l)*30,u=t.predictedToothDepths.map((e,n)=\u003eMath.sin(Math.PI*(n+1)/(t.predictedToothDepths.length+1))),p=Math.max(...u),m=Math.sqrt(t.predictedToothDepths.reduce((t,e,n)=\u003et+(e-o*u[n]/p)**2,0)/t.predictedToothDepths.length),g=100-d-h-Math.min(10,(\"tapered\"===t.heightProfile?m:r)/i*10)-2*(n.length-1)-7*Math.min(1,t.addedLength/t.segmentLength)-100*t.centerlineDistanceCost,f=t.centerlineDistanceCost\u003e0?g:Math.max(0,g);return Math.round(1e6*f)/1e6},fG=t=\u003e{if(t.toothDepths.length!==t.toothCount)throw new Error(`LengthMatchingSolver: expected ${t.toothCount} tooth depths, received ${t.toothDepths.length}`);if(t.toothDepths.some(t=\u003e!Number.isFinite(t)||t\u003c0))throw new Error(\"LengthMatchingSolver: every meander tooth depth must be a non-negative finite number\");const e=t.route.route[t.segmentIndex],n=t.route.route[t.segmentIndex+1],o=lG(e,n),i=(n.x-e.x)/o,r=(n.y-e.y)/o,s=(o-(t.toothCount-.5)*t.toothPitch)/2,a=[{...e}];for(let n=0;n\u003ct.toothCount;n++){const o=t.toothDepths[n];if(0===o)continue;const c=\"balanced\"===t.placement?n%2==0?-1:1:\"negative\"===t.placement?-1:1,l={x:-r*c,y:i*c},d=s+n*t.toothPitch,h=d+t.toothPitch/2,u={...e,x:e.x+i*d,y:e.y+r*d};a.push(u,{...u,x:u.x+l.x*o,y:u.y+l.y*o},{...e,x:e.x+i*h+l.x*o,y:e.y+r*h+l.y*o},{...e,x:e.x+i*h,y:e.y+r*h})}return a.push({...n}),(t=\u003e{if(t.length\u003c3)return t;const e=[{...t[0]}];for(let n=1;n\u003ct.length-1;n++){const o=t[n-1],i=t[n],r=t[n+1],s=Math.hypot(i.x-o.x,i.y-o.y),a=Math.hypot(r.x-i.x,r.y-i.y);if(0===s||0===a)throw new Error(\"LengthMatchingSolver: meander contains a zero-length segment\");const c={x:(i.x-o.x)/s,y:(i.y-o.y)/s},l={x:(r.x-i.x)/a,y:(r.y-i.y)/a};if(Math.abs(c.x*l.y-c.y*l.x)\u003c1e-9){e.push({...i});continue}const d=Math.min(s,a)/2,h={...i,x:i.x-c.x*d,y:i.y-c.y*d},u={...i,x:i.x+l.x*d,y:i.y+l.y*d},p=e.at(-1);h.x===p.x\u0026\u0026h.y===p.y||e.push(h);for(let t=1;t\u003c6;t++){const n=t/6,o=1-n;e.push({...i,x:o**2*h.x+2*o*n*i.x+n**2*u.x,y:o**2*h.y+2*o*n*i.y+n**2*u.y})}e.push(u)}return e.push({...t[t.length-1]}),e})(a)},yG=t=\u003e[...t.route.route.slice(0,t.segmentIndex),...fG(t),...t.route.route.slice(t.segmentIndex+2)],_G=t=\u003e{const e=dG(t.route),n=(()=\u003e{const e=[];for(let n=0;n\u003ct.candidate.toothCount;n++){const o=Array(t.candidate.toothCount).fill(0);o[n]=t.candidate.maximumDepth;const i=fG({...t.candidate,route:t.route,toothDepths:o});if(t.isGeometryValid(i)){e.push(t.candidate.maximumDepth);continue}let r=0,s=t.candidate.maximumDepth;for(let e=0;e\u003c32;e++){const e=(r+s)/2,o=Array(t.candidate.toothCount).fill(0);o[n]=e;const i=fG({...t.candidate,route:t.route,toothDepths:o});t.isGeometryValid(i)?r=e:s=e}e.push(r)}return e})(),o=(t=\u003e{if(\"tapered\"!==t.heightProfile)return Array(t.toothCount).fill(1);const e=Array.from({length:t.toothCount},(e,n)=\u003eMath.sin(Math.PI*(n+1)/(t.toothCount+1))),n=Math.max(...e);return e.map(t=\u003et/n)})(t.candidate),i=t.candidate.maximumDepth,r=n.map((t,e)=\u003eMath.min(t,i*o[e])),s=[.25,.75],a=r.map(t=\u003et*s[0]),c=r.map(t=\u003et*s[1]),l=yG({...t.candidate,route:t.route,toothDepths:a}),d=yG({...t.candidate,route:t.route,toothDepths:c}),h=[dG({...t.route,route:l})-e,dG({...t.route,route:d})-e],u=yG({...t.candidate,route:t.route,toothDepths:r}),p=dG({...t.route,route:u})-e,m=(h[1]-h[0])/(s[1]-s[0]),g=h[0]-m*s[0],f=m\u003e0\u0026\u0026Number.isFinite(m)?(t.targetAddedLength-g)/m:0,y=Math.min(t.targetAddedLength,p),_=t.targetAddedLength\u003e0\u0026\u0026y\u003e0?(e=\u003e{let n=0,o=t.candidate.maximumDepth;for(let i=0;i\u003c32;i++){const i=(n+o)/2,r=e.maximumToothDepths.map((t,n)=\u003eMath.min(t,i*e.toothHeightWeights[n])),s=yG({...t.candidate,route:t.route,toothDepths:r}),a=dG({...t.route,route:s})-e.originalLength,c=fG({...t.candidate,route:t.route,toothDepths:r});t.isGeometryValid(c)?a\u003ce.targetAddedLength?n=i:o=i:o=i}const i=(n+o)/2;return{depthLevel:i,toothDepths:e.maximumToothDepths.map((t,n)=\u003eMath.min(t,i*e.toothHeightWeights[n]))}})({maximumToothDepths:n,toothHeightWeights:o,originalLength:e,targetAddedLength:y}):{depthLevel:f*i,toothDepths:r.map(t=\u003eMath.max(0,t*f))},b=_.depthLevel/i,x=_.toothDepths,v=yG({...t.candidate,route:t.route,toothDepths:x}),S=dG({...t.route,route:v})-e,I=Math.abs(y-S),C=fG({...t.candidate,route:t.route,toothDepths:x});let P=0;if(t.getCenterlineDistanceCost\u0026\u0026(P=t.getCenterlineDistanceCost(C)),null!==P\u0026\u0026(!Number.isFinite(P)||P\u003c0))throw new Error(\"LengthMatchingSolver: meander centerline distance cost must be a non-negative finite number\");const M=Number.isFinite(b)\u0026\u0026b\u003e0\u0026\u0026b\u003c=1,N=x.every(e=\u003e0===e||e\u003e=t.candidate.minimumHeight),w=t.isGeometryValid(C);let T,R=null;null===P?R=\"no-paired-same-layer-geometry\":M?I\u003et.lengthTolerance?R=\"target-error\":w?N||(R=\"below-minimum-height\"):R=\"invalid-geometry\":R=\"invalid-scale\",T=R?{valid:!1,invalidReason:R}:{valid:!0,invalidReason:null};const E={...t.candidate,connectionName:t.connectionName,maximumToothDepths:n,sampleScaleFactors:s,sampleAddedLengths:h,slope:m,intercept:g,predictedScaleFactor:b,predictedToothDepths:x,predictedRoute:v,addedLength:S,maximumAddedLength:p,resultingError:I,testedSegment:[{...t.route.route[t.candidate.segmentIndex]},{...t.route.route[t.candidate.segmentIndex+1]}],meanderPoints:C,centerlineDistanceCost:P,qualityScore:0,...T};return{...E,qualityScore:gG(E)}},bG=t=\u003e{const e=(t=\u003e{if(\"tapered\"!==t.heightProfile)return Array(t.toothCount).fill(1);const e=Array.from({length:t.toothCount},(e,n)=\u003eMath.sin(Math.PI*(n+1)/(t.toothCount+1))),n=Math.max(...e);return e.map(t=\u003et/n)})(t.candidate),n=Math.max(...e.map(e=\u003et.candidate.minimumHeight/e)),o=t.candidate.maximumDepth/2**30,i=e.map(t=\u003et*(n+o));if(i.some(e=\u003ee\u003et.candidate.maximumDepth))return null;const r=fG({...t.candidate,route:t.route,toothDepths:i});if(!t.isGeometryValid(r))return null;const s=yG({...t.candidate,route:t.route,toothDepths:i}),a=dG({...t.route,route:s})-dG(t.route),c=_G({...t,targetAddedLength:a});return c.valid?c:null},xG=t=\u003e{const e=(t,e)=\u003e{const n=t[e.routeIndex];if(!n)throw new Error(`LengthMatchingSolver: dual meander references missing route ${e.routeIndex}`);const o=[...t];return o[e.routeIndex]={...n,route:e.predictedRoute},o},n=(()=\u003e{if(t.targetAddedLength+t.config.lengthTolerance\u003ct.plan.minimumAddedLength||t.targetAddedLength-t.config.lengthTolerance\u003et.plan.maximumAddedLength)return null;const e=t.plan.attemptOptions.map(t=\u003eMath.min(...t.map(t=\u003et.attempt.addedLength)));let n=Math.max(0,t.targetAddedLength-t.plan.minimumAddedLength),o=e.map((t,e)=\u003ee);for(;n\u003e1e-9\u0026\u0026o.length\u003e0;){const i=n/o.length;let r=0;const s=[];for(const n of o){const o=Math.max(...t.plan.attemptOptions[n].map(t=\u003et.attempt.maximumAddedLength))-e[n],a=Math.min(o,i);e[n]+=a,r+=a,o-a\u003e1e-9\u0026\u0026s.push(n)}if(r\u003c=1e-9)break;n-=r,o=s}return n\u003c=t.config.lengthTolerance?e:null})();if(!n)return null;const o=t.plan.attemptOptions.map((t,e)=\u003e({attemptOptions:t,targetAddedLength:n[e]})).sort((t,e)=\u003ee.attemptOptions[0].candidate.routeIndex-t.attemptOptions[0].candidate.routeIndex||e.attemptOptions[0].candidate.segmentIndex-t.attemptOptions[0].candidate.segmentIndex);let i=[...t.routes];const r=[];for(const n of o){const o=n.attemptOptions[0]?.candidate;if(!o)throw new Error(\"LengthMatchingSolver: empty dual-meander segment options\");const s=i[o.routeIndex];if(!s)throw new Error(`LengthMatchingSolver: missing planned dual-meander route ${o.routeIndex}`);let a=null;for(const e of n.attemptOptions){if(e.attempt.addedLength-t.config.lengthTolerance\u003en.targetAddedLength||e.attempt.maximumAddedLength+t.config.lengthTolerance\u003cn.targetAddedLength)continue;const o=_G({candidate:e.candidate,route:s,connectionName:t.connectionName,targetAddedLength:n.targetAddedLength,lengthTolerance:t.config.lengthTolerance,isGeometryValid:e=\u003epG({route:s,meanderPoints:e,routedRoutes:t.excludedConnectionName?i.filter(e=\u003esG(e)!==t.excludedConnectionName):i,...t.config})});o.valid\u0026\u0026(!a||o.qualityScore\u003ea.qualityScore)\u0026\u0026(a=o)}if(!a)return null;i=e(i,a),r.push(a)}const s=r.reduce((t,e)=\u003et+e.addedLength,0);if(Math.abs(s-t.targetAddedLength)\u003et.config.lengthTolerance)return null;const a=r[0];if(!a)throw new Error(\"LengthMatchingSolver: fitted an empty dual-meander plan\");return{attempts:[a,...r.slice(1)],routes:i,addedLength:s}},vG=t=\u003e{if(0===t.length)throw new Error(\"LengthMatchingSolver: cannot score an empty meander plan\");return t.reduce((t,e)=\u003et+e.qualityScore,0)/t.length-3*(t.length-1)},SG=t=\u003e{const e=t=\u003e[t.candidate.toothCount,t.candidate.placement,t.candidate.heightProfile].join(\":\"),n=new Map;for(const o of t){const t=e(o),i=`${o.candidate.routeIndex}:${o.candidate.segmentIndex}`,r=n.get(t);if(!r){n.set(t,new Map([[i,[o]]]));continue}const s=r.get(i);s?s.push(o):r.set(i,[o])}const o=[];for(const t of n.values()){const e=[...t.values()].map(t=\u003e({attempts:t,maximumAddedLength:Math.max(...t.map(t=\u003et.attempt.maximumAddedLength)),minimumAddedLength:Math.min(...t.map(t=\u003et.attempt.addedLength)),rankingAttempt:t.reduce((t,e)=\u003ee.attempt.qualityScore\u003et.attempt.qualityScore?e:t)})).sort((t,e)=\u003ee.maximumAddedLength-t.maximumAddedLength);for(const t of e)o.push({attempts:[t.rankingAttempt],attemptOptions:[t.attempts],minimumAddedLength:t.minimumAddedLength,maximumAddedLength:t.maximumAddedLength,rankingQualityScore:t.rankingAttempt.attempt.qualityScore});for(let t=2;t\u003c=e.length;t++){const n=e.slice(0,t),i=n.map(t=\u003et.rankingAttempt);o.push({attempts:i,attemptOptions:n.map(t=\u003et.attempts),minimumAddedLength:n.reduce((t,e)=\u003et+e.minimumAddedLength,0),maximumAddedLength:n.reduce((t,e)=\u003et+e.maximumAddedLength,0),rankingQualityScore:vG(i.map(t=\u003et.attempt))})}}return o},IG=class extends Error{connectionName;reason;constructor(t){super(t.message),this.name=\"LengthMatchingNoSolutionError\",this.connectionName=t.connectionName,this.reason=t.reason}},CG=t=\u003e[t.routeIndex,t.segmentIndex,t.toothCount,t.placement,t.toothPitch,t.heightProfile,t.maximumDepth,t.minimumHeight].join(\":\"),PG=t=\u003e{const e=new Map,n=[...t.attempts].sort((t,e)=\u003et.addedLength-e.addedLength);let o=t.targetAddedLength;for(let t=0;t\u003cn.length;t++){const i=n[t],r=Math.min(i.addedLength,o/(n.length-t));e.set(CG(i),{routeIndex:i.routeIndex,segmentIndex:i.segmentIndex,targetAddedLength:r}),o-=r}return e},MG=(t,e)=\u003e`z${uG(t,e).join(\",\")}`,NG=t=\u003e`z${t}`,wG=t=\u003e{if(!t.showAttempt)return;if(!t.attempt)return void(t=\u003e{const e=t.activePair?.candidates[t.activePair.candidateIndex];if(!e)return;const n=t.routes[e.routeIndex];if(!n)return;const o=n.route[e.segmentIndex],i=n.route[e.segmentIndex+1];o\u0026\u0026i\u0026\u0026t.graphics.lines.push({points:[o,i],strokeColor:\"rgba(234, 179, 8, 0.6)\",strokeWidth:2*n.traceThickness,strokeDash:[.1,.1],layer:NG(o.z)})})(t);const e=t.routes[t.attempt.routeIndex],[n,o]=t.attempt.testedSegment,i=t.theme.getConnectionColor(t.attempt.connectionName);t.graphics.lines.push({points:[n,o],strokeColor:t.theme.getTestedSegmentColor(i),strokeWidth:e.traceThickness,strokeDash:[.15,.15],layer:NG(n.z)}),t.attempt.valid?t.graphics.lines.push({points:t.attempt.meanderPoints.map(({x:t,y:e})=\u003e({x:t,y:e})),strokeColor:\"rgba(234, 179, 8, 0.6)\",strokeWidth:2*e.traceThickness,strokeDash:[.1,.1],layer:NG(n.z)}):t.graphics.lines.push({points:t.attempt.meanderPoints.map(({x:t,y:e})=\u003e({x:t,y:e})),strokeColor:t.theme.getRejectedCandidateColor(i),strokeWidth:e.traceThickness,strokeDash:[.1,.1],layer:NG(n.z)}),t.graphics.points.push({x:n.x,y:n.y,color:i,layer:NG(n.z)},{x:o.x,y:o.y,color:i,layer:NG(o.z)})},TG=t=\u003e{const e={lines:[],points:[],rects:[],circles:[]},n=(t=\u003e{for(const e of Object.values(t))Tt(0,e);return{getConnectionColor:(e,n)=\u003et[e]??(n?t[n]:void 0)??(t=\u003et?`hsl(${300*t.split(\"\").reduce((t,e)=\u003et+e.charCodeAt(0),0)/t.length%360}, 100%, 50%)`:\"rgba(0, 0, 0, 0.5)\")(e),getInnerLayerConnectionColor:t=\u003eTt(.5,t),getTestedSegmentColor:t=\u003eTt(.55,t),getRejectedCandidateColor:t=\u003eTt(.45,t),boardBounds:{fill:\"rgba(30,41,59,0.03)\",stroke:\"rgba(30,41,59,0.55)\"},obstacle:{fill:\"rgba(255,0,0,0.25)\",stroke:\"rgba(255,0,0,0.5)\"},via:{fill:\"blue\",stroke:\"none\"}}})(t.colorMap);return(t=\u003e{for(const e of t.routes){const n=sG(e),o=t.theme.getConnectionColor(n,e.connectionName);for(let n=0;n\u003ce.route.length-1;n++){const i=e.route[n],r=e.route[n+1];i.z===r.z\u0026\u0026t.graphics.lines.push({points:[i,r],strokeColor:0===i.z?o:t.theme.getInnerLayerConnectionColor(o),strokeWidth:e.traceThickness,...0===i.z?{}:{strokeDash:[.2,.2]},layer:NG(i.z)})}const i=[...new Set(e.route.map(t=\u003et.z))];for(const n of e.vias)t.graphics.circles.push({center:n,radius:e.viaDiameter/2,fill:t.theme.via.fill,stroke:t.theme.via.stroke,layer:`z${(n.zLayers??i).join(\",\")}`})}})({routes:t.routes,theme:n,graphics:e}),(t=\u003e{if(t.bounds){const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds;t.graphics.rects.push({center:{x:(e+n)/2,y:(o+i)/2},width:n-e,height:i-o,fill:t.theme.boardBounds.fill,stroke:t.theme.boardBounds.stroke,layer:`z${Array.from({length:t.layerCount},(t,e)=\u003ee).join(\",\")}`})}for(const e of t.obstacles)t.graphics.rects.push({center:e.center,width:e.width,height:e.height,ccwRotationDegrees:e.ccwRotationDegrees,fill:t.theme.obstacle.fill,stroke:t.theme.obstacle.stroke,layer:MG(e,t.layerCount)})})({obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,theme:n,graphics:e}),wG({routes:t.routes,attempt:t.currentAttempt,activePair:t.activePair,showAttempt:!t.solved,theme:n,graphics:e}),{...e}},RG=class extends kt{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1e5,this.matchedHdRoutes=t.hdRoutes.map(t=\u003e({...t,route:t.route.map(t=\u003e({...t}))})),this.pairs=t.differentialPairs??[]}params;matchedHdRoutes;pairs;nextPairIndex=0;activePair=null;currentAttempt=null;config=null;candidatesTried=0;getSolverName(){return\"LengthMatchingSolver\"}startNextPair(){const t=this.pairs[this.nextPairIndex++];if(!t)return void(this.solved=!0);((t,e)=\u003e{if(t.connectionNames[0]===t.connectionNames[1])throw new Error(\"LengthMatchingSolver: a differential pair must reference two distinct connections\");if(!Number.isFinite(t.lengthTolerance)||t.lengthTolerance\u003c0)throw new Error(\"LengthMatchingSolver: differential pair lengthTolerance must be a non-negative finite number\");for(const e of[t.minimumCenterlineDistance,t.maximumCenterlineDistance])if(void 0!==e\u0026\u0026(!Number.isFinite(e)||e\u003c=0))throw new Error(\"LengthMatchingSolver: differential pair centerline distances must be positive finite numbers\");if(void 0!==t.minimumCenterlineDistance\u0026\u0026void 0!==t.maximumCenterlineDistance\u0026\u0026t.minimumCenterlineDistance\u003et.maximumCenterlineDistance)throw new Error(\"LengthMatchingSolver: differential pair minimumCenterlineDistance cannot exceed maximumCenterlineDistance\");const n=new Map(e.map(t=\u003e[t.name,t]));for(const e of t.connectionNames){const t=n.get(e);if(!t)throw new Error(`LengthMatchingSolver: differential pair references unknown connection \"${e}\"`);if(2!==t.pointsToConnect.length)throw new Error(`LengthMatchingSolver: differential pair connection \"${e}\" must have exactly two points before MST splitting`)}})(t,this.params.originalConnections);const e=aG(this.matchedHdRoutes,t.connectionNames[0]),n=aG(this.matchedHdRoutes,t.connectionNames[1]);if(0===e.length\u0026\u00260===n.length)return;if(0===e.length||0===n.length)throw new Error(`LengthMatchingSolver: differential pair ${t.connectionNames.join(\"/\")} has routed geometry for only one connection`);const o=hG(this.matchedHdRoutes,e),i=hG(this.matchedHdRoutes,n),r=Math.abs(o-i);if(r\u003c=t.lengthTolerance)return;const s=o\u003ci,a=t.connectionNames[s?0:1],c=t.connectionNames[s?1:0],l=mG({routes:this.matchedHdRoutes,routeIndexes:s?e:n,maximumDepth:this.getConfig().maximumMeanderDepth,minimumToothPitch:this.getConfig().minimumToothPitch,minMeanderGap:this.getConfig().minMeanderGap,minMeanderHeight:this.getConfig().minMeanderHeight,maxToothCount:this.getConfig().maxToothCount});if(0===l.length)throw new IG({message:`LengthMatchingSolver: no same-layer straight segment can tune connection \"${a}\"`,connectionName:a,reason:\"no-meander-candidate\"});this.activePair={pair:t,longerConnectionName:c,longerRouteIndexes:s?n:e,shorterConnectionName:a,targetAddedLength:r,remainingAddedLength:r,candidates:l,candidateIndex:0,lastMatchedSegmentIndexByRoute:new Map,partialAttempts:[],fullAttempts:[],plannedAttemptTargets:null,hasMinimumHeightBlockedAttempt:!1}}acceptAttempt(t,e){const n=this.matchedHdRoutes[e.routeIndex];this.matchedHdRoutes[e.routeIndex]={...n,route:e.predictedRoute},t.remainingAddedLength-=e.addedLength,t.lastMatchedSegmentIndexByRoute.set(e.routeIndex,e.segmentIndex),t.candidateIndex=0,t.partialAttempts=[],t.fullAttempts=[],t.plannedAttemptTargets?.delete(CG(e)),0===t.plannedAttemptTargets?.size\u0026\u0026(t.plannedAttemptTargets=null),t.remainingAddedLength\u003c=t.pair.lengthTolerance\u0026\u0026(this.activePair=null)}tryCandidate(t){let e;for(;!e;){const n=t.candidates[t.candidateIndex++];if(!n)break;const o=t.lastMatchedSegmentIndexByRoute.get(n.routeIndex);(void 0===o||n.segmentIndex\u003co)\u0026\u0026(!t.plannedAttemptTargets||t.plannedAttemptTargets.has(CG(n))\u0026\u0026![...t.plannedAttemptTargets.values()].some(t=\u003et.routeIndex===n.routeIndex\u0026\u0026t.segmentIndex\u003en.segmentIndex))\u0026\u0026(e=n)}if(!e){const e=t.fullAttempts.reduce((t,e)=\u003e!t||e.qualityScore\u003et.qualityScore?e:t,null),n=(t=\u003e{const e=t=\u003e[t.toothCount,t.placement,t.heightProfile].join(\":\"),n=new Map;for(const o of t.attempts){const t=`${o.routeIndex}:${o.segmentIndex}`,i=e(o),r=n.get(i);if(!r){n.set(i,new Map([[t,[o]]]));continue}const s=r.get(t);s?s.push(o):r.set(t,[o])}let o=null;for(const e of n.values()){const n=[...e.values()].map(t=\u003e({attempts:t,maximumCapacityAttempt:t.reduce((t,e)=\u003ee.addedLength\u003et.addedLength?e:t)})).sort((t,e)=\u003ee.maximumCapacityAttempt.addedLength-t.maximumCapacityAttempt.addedLength);let i=0;for(let e=0;e\u003cn.length;e++){if(i+=n[e].maximumCapacityAttempt.addedLength,i+t.lengthTolerance\u003ct.targetAddedLength)continue;const r=n.slice(0,e+1),s=r.map(t=\u003et.maximumCapacityAttempt),a=PG({attempts:s,targetAddedLength:t.targetAddedLength}),c=r.map(e=\u003e{const n=a.get(CG(e.maximumCapacityAttempt));if(!n)throw new Error(`LengthMatchingSolver: missing capacity target for ${CG(e.maximumCapacityAttempt)}`);const o=e.attempts.filter(e=\u003ee.addedLength+t.lengthTolerance\u003e=n.targetAddedLength);if(0===o.length)throw new Error(`LengthMatchingSolver: no pitch can supply planned target for route ${e.maximumCapacityAttempt.routeIndex} segment ${e.maximumCapacityAttempt.segmentIndex}`);return o.reduce((t,e)=\u003ee.qualityScore\u003et.qualityScore||e.qualityScore===t.qualityScore\u0026\u0026e.toothPitch\u003et.toothPitch?e:t)}),l=vG(c);if(!o){o={attempts:c};break}const d=vG(o.attempts);(c.length\u003co.attempts.length||c.length===o.attempts.length\u0026\u0026l\u003ed)\u0026\u0026(o={attempts:c});break}}return o})({attempts:t.partialAttempts,targetAddedLength:t.remainingAddedLength,lengthTolerance:t.pair.lengthTolerance});if(e\u0026\u0026(!n||e.qualityScore\u003e=vG(n.attempts)))return void this.acceptAttempt(t,e);if(!n){if(!(t.hasMinimumHeightBlockedAttempt\u0026\u0026null===t.plannedAttemptTargets\u0026\u00260===t.lastMatchedSegmentIndexByRoute.size))throw new IG({message:`LengthMatchingSolver: linear regression exhausted all segment/tooth combinations for \"${t.shorterConnectionName}\"; required ${t.targetAddedLength.toFixed(4)}mm`,connectionName:t.shorterConnectionName,reason:\"meander-search-exhausted\"});return this.tryDualMeanderPlan(t)}return t.plannedAttemptTargets=PG({attempts:n.attempts,targetAddedLength:t.remainingAddedLength}),t.candidateIndex=0,t.partialAttempts=[],void(t.fullAttempts=[])}const n=this.matchedHdRoutes[e.routeIndex],o=this.getConfig(),i=t.plannedAttemptTargets?.get(CG(e));if(null!==t.plannedAttemptTargets\u0026\u0026void 0===i)throw new Error(`LengthMatchingSolver: missing planned target for ${CG(e)}`);this.currentAttempt=_G({candidate:e,route:n,connectionName:t.shorterConnectionName,targetAddedLength:void 0===i?t.remainingAddedLength:i.targetAddedLength,lengthTolerance:t.pair.lengthTolerance,isGeometryValid:t=\u003epG({route:n,meanderPoints:t,routedRoutes:this.matchedHdRoutes,obstacles:o.obstacles,bounds:o.bounds,layerCount:o.layerCount,obstacleMargin:o.obstacleMargin}),getCenterlineDistanceCost:void 0===t.pair.minimumCenterlineDistance\u0026\u0026void 0===t.pair.maximumCenterlineDistance?void 0:e=\u003e(t=\u003e{let e=0,n=0;for(let o=0;o\u003ct.meanderPoints.length-1;o++){const i=t.meanderPoints[o],r=t.meanderPoints[o+1],s=Math.hypot(r.x-i.x,r.y-i.y);if(0!==s){for(let e=0;e\u003c4;e++){const o=(e+.5)/4,a={x:i.x+(r.x-i.x)*o,y:i.y+(r.y-i.y)*o},c=[];for(const e of t.pairedRoutes)for(let t=0;t\u003ce.route.length-1;t++){const n=e.route[t],o=e.route[t+1];i.z===n.z\u0026\u0026i.z===o.z\u0026\u0026c.push(cG(a,a,n,o))}if(0===c.length)return null;const l=Math.min(...c);n+=s*Math.max(0,(t.minimumCenterlineDistance??Number.NEGATIVE_INFINITY)-l,l-(t.maximumCenterlineDistance??Number.POSITIVE_INFINITY))/4}e+=s}}if(0===e)throw new Error(\"LengthMatchingSolver: cannot measure a zero-length meander centerline\");return n/e})({meanderPoints:e,pairedRoutes:t.longerRouteIndexes.map(t=\u003ethis.matchedHdRoutes[t]),minimumCenterlineDistance:t.pair.minimumCenterlineDistance,maximumCenterlineDistance:t.pair.maximumCenterlineDistance})}),this.candidatesTried++,\"below-minimum-height\"===this.currentAttempt.invalidReason\u0026\u0026(t.hasMinimumHeightBlockedAttempt=!0),this.stats={pair:`${t.pair.connectionNames[0]}/${t.pair.connectionNames[1]}`,candidatesTried:this.candidatesTried,segmentIndex:e.segmentIndex,toothCount:e.toothCount,toothPitch:e.toothPitch,placement:e.placement,predictedScaleFactor:this.currentAttempt.predictedScaleFactor,predictedToothDepths:this.currentAttempt.predictedToothDepths,resultingError:this.currentAttempt.resultingError,qualityScore:this.currentAttempt.qualityScore,accepted:this.currentAttempt.valid},this.currentAttempt.valid\u0026\u0026(null===t.plannedAttemptTargets?t.remainingAddedLength-this.currentAttempt.addedLength\u003c=t.pair.lengthTolerance?t.fullAttempts.push(this.currentAttempt):t.partialAttempts.push(this.currentAttempt):this.acceptAttempt(t,this.currentAttempt))}tryDualMeanderPlan(t){if(t.remainingAddedLength!==t.targetAddedLength)throw new Error(`LengthMatchingSolver: cannot start a dual-meander plan after partially tuning \"${t.shorterConnectionName}\"`);const e=this.getConfig(),n=mG({routes:this.matchedHdRoutes,routeIndexes:t.longerRouteIndexes,maximumDepth:e.maximumMeanderDepth,minimumToothPitch:e.minimumToothPitch,minMeanderGap:e.minMeanderGap,minMeanderHeight:e.minMeanderHeight,maxToothCount:e.maxToothCount}),o=(t=\u003e{const e=(t,e)=\u003et.rankingQualityScore!==e.rankingQualityScore?t.rankingQualityScore\u003ee.rankingQualityScore:t.leftIndex!==e.leftIndex?t.leftIndex\u003ce.leftIndex:t.rightIndex\u003ce.rightIndex,n=(t,n)=\u003e{t.push(n);let o=t.length-1;for(;o\u003e0;){const i=Math.floor((o-1)/2),r=t[i];if(e(r,n))break;t[o]=r,o=i}t[o]=n},o=t=\u003e{const n=t[0],o=t.pop();if(!n||!o||0===t.length)return n;let i=0;for(;;){const n=2*i+1,r=n+1;if(n\u003e=t.length)break;const s=r\u003ct.length\u0026\u0026e(t[r],t[n])?r:n,a=t[s];if(e(o,a))break;t[i]=a,i=s}return t[i]=o,n},i=function*(t){const e=[...t.leftOptions].sort((e,n)=\u003et.getLeftQualityScore(n)-t.getLeftQualityScore(e)),i=[...t.rightOptions].sort((e,n)=\u003et.getRightQualityScore(n)-t.getRightQualityScore(e)),r=[];for(let o=0;o\u003ce.length;o++){const s=i[0];if(!s)break;n(r,{leftIndex:o,rightIndex:0,rankingQualityScore:(t.getLeftQualityScore(e[o])+t.getRightQualityScore(s))/2})}for(;r.length\u003e0;){const s=o(r);yield[e[s.leftIndex],i[s.rightIndex]];const a=s.rightIndex+1,c=i[a];c\u0026\u0026n(r,{leftIndex:s.leftIndex,rightIndex:a,rankingQualityScore:(t.getLeftQualityScore(e[s.leftIndex])+t.getRightQualityScore(c))/2})}},r=(t,e)=\u003e{const n=t[e.routeIndex];if(!n)throw new Error(`LengthMatchingSolver: dual meander references missing route ${e.routeIndex}`);const o=[...t];return o[e.routeIndex]={...n,route:e.predictedRoute},o},s=t=\u003e{const e=t.routes[t.attempt.routeIndex];if(!e)throw new Error(`LengthMatchingSolver: cannot validate missing dual-meander route ${t.attempt.routeIndex}`);return pG({route:e,meanderPoints:t.attempt.meanderPoints,routedRoutes:t.routes,...t.config})},a=t=\u003e{const e=t.routes.filter(e=\u003esG(e)!==t.counterpartConnectionName),n=[];for(const o of t.candidates){const i=t.routes[o.routeIndex];if(!i)throw new Error(`LengthMatchingSolver: dual-meander candidate references missing route ${o.routeIndex}`);const r=bG({candidate:o,route:i,connectionName:t.connectionName,lengthTolerance:t.config.lengthTolerance,isGeometryValid:n=\u003epG({route:i,meanderPoints:n,routedRoutes:e,...t.config})});r\u0026\u0026n.push({candidate:o,attempt:r})}return n},c={obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,obstacleMargin:t.obstacleMargin},l=a({candidates:t.shorterCandidates,routes:t.routes,connectionName:t.shorterConnectionName,counterpartConnectionName:t.longerConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(0===l.length)return null;const d=a({candidates:t.longerCandidates,routes:t.routes,connectionName:t.longerConnectionName,counterpartConnectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}}),h=i({leftOptions:d,rightOptions:l,getLeftQualityScore:t=\u003et.attempt.qualityScore,getRightQualityScore:t=\u003et.attempt.qualityScore});for(const[e,n]of h){const o=Math.max(e.attempt.addedLength,n.attempt.addedLength-t.originalLengthDifference),i=o+t.originalLengthDifference;if(o-t.lengthTolerance\u003ee.attempt.maximumAddedLength||i-t.lengthTolerance\u003en.attempt.maximumAddedLength)continue;const a=t.routes[e.candidate.routeIndex];if(!a)throw new Error(`LengthMatchingSolver: missing longer route ${e.candidate.routeIndex}`);const l=t.routes[n.candidate.routeIndex];if(!l)throw new Error(`LengthMatchingSolver: missing shorter route ${n.candidate.routeIndex}`);const d=t.routes.filter(e=\u003esG(e)!==t.shorterConnectionName),h=_G({candidate:e.candidate,route:a,connectionName:t.longerConnectionName,targetAddedLength:o,lengthTolerance:t.lengthTolerance,isGeometryValid:t=\u003epG({route:a,meanderPoints:t,routedRoutes:d,...c})});if(!h.valid||Math.abs(h.addedLength-o)\u003et.lengthTolerance)continue;const u=r(t.routes,h),p=h.addedLength+t.originalLengthDifference,m=_G({candidate:n.candidate,route:l,connectionName:t.shorterConnectionName,targetAddedLength:p,lengthTolerance:t.lengthTolerance,isGeometryValid:t=\u003epG({route:l,meanderPoints:t,routedRoutes:u,...c})});if(!m.valid)continue;const g=r(u,m),f=aG(g,t.longerConnectionName),y=aG(g,t.shorterConnectionName);if(!(Math.abs(hG(g,y)-hG(g,f))\u003et.lengthTolerance)\u0026\u0026s({attempt:h,routes:g,config:c})\u0026\u0026s({attempt:m,routes:g,config:c}))return{longerAttempts:[h],shorterAttempts:[m]}}const u=i({leftOptions:SG(d),rightOptions:SG(l),getLeftQualityScore:t=\u003et.rankingQualityScore,getRightQualityScore:t=\u003et.rankingQualityScore});for(const[e,n]of u){if(1===e.attempts.length\u0026\u00261===n.attempts.length)continue;const o=Math.max(e.minimumAddedLength,n.minimumAddedLength-t.originalLengthDifference),i=o+t.originalLengthDifference;if(o-t.lengthTolerance\u003ee.maximumAddedLength||i-t.lengthTolerance\u003en.maximumAddedLength)continue;const r=xG({plan:e,targetAddedLength:o,routes:t.routes,connectionName:t.longerConnectionName,excludedConnectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(!r)continue;const a=xG({plan:n,targetAddedLength:r.addedLength+t.originalLengthDifference,routes:r.routes,connectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(!a)continue;const l=aG(a.routes,t.longerConnectionName),d=aG(a.routes,t.shorterConnectionName),h=Math.abs(hG(a.routes,d)-hG(a.routes,l)),u=[...r.attempts,...a.attempts];if(!(h\u003et.lengthTolerance||u.some(t=\u003e!s({attempt:t,routes:a.routes,config:c}))))return{longerAttempts:r.attempts,shorterAttempts:a.attempts}}return null})({routes:this.matchedHdRoutes,longerConnectionName:t.longerConnectionName,shorterConnectionName:t.shorterConnectionName,originalLengthDifference:t.targetAddedLength,lengthTolerance:t.pair.lengthTolerance,longerCandidates:n,shorterCandidates:t.candidates,obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,obstacleMargin:e.obstacleMargin});if(!o)throw new IG({message:`LengthMatchingSolver: linear regression exhausted all segment/tooth combinations for \"${t.shorterConnectionName}\"; required ${t.targetAddedLength.toFixed(4)}mm`,connectionName:t.shorterConnectionName,reason:\"meander-search-exhausted\"});const i=[...this.matchedHdRoutes];for(const t of[...o.longerAttempts,...o.shorterAttempts]){const e=this.matchedHdRoutes[t.routeIndex];if(!e)throw new Error(`LengthMatchingSolver: cannot commit dual meander to missing route ${t.routeIndex}`);i[t.routeIndex]={...e,route:t.predictedRoute}}this.matchedHdRoutes=i,this.currentAttempt=o.shorterAttempts[0];const r=o.longerAttempts.reduce((t,e)=\u003et+e.addedLength,0),s=o.shorterAttempts.reduce((t,e)=\u003et+e.addedLength,0);this.stats={pair:`${t.pair.connectionNames[0]}/${t.pair.connectionNames[1]}`,mode:\"dual-meander\",longerAddedLength:r,shorterAddedLength:s,resultingError:Math.abs(s-r-t.targetAddedLength)},this.activePair=null}getConfig(){return this.config||(this.config=(t=\u003e{const e=t.maximumMeanderDepth??5,n=t.maxToothCount??12;if(!Number.isFinite(e)||e\u003c=0)throw new Error(\"LengthMatchingSolver: maximumMeanderDepth must be a positive finite number\");if(void 0!==t.minimumToothPitch\u0026\u0026(!Number.isFinite(t.minimumToothPitch)||t.minimumToothPitch\u003c=0))throw new Error(\"LengthMatchingSolver: minimumToothPitch must be a positive finite number\");if(void 0!==t.minMeanderGap\u0026\u0026(!Number.isFinite(t.minMeanderGap)||t.minMeanderGap\u003c=0))throw new Error(\"LengthMatchingSolver: minMeanderGap must be a positive finite number\");if(void 0!==t.minMeanderHeight\u0026\u0026(!Number.isFinite(t.minMeanderHeight)||t.minMeanderHeight\u003c=0))throw new Error(\"LengthMatchingSolver: minMeanderHeight must be a positive finite number\");if(void 0!==t.minMeanderHeight\u0026\u0026t.minMeanderHeight\u003ee)throw new Error(\"LengthMatchingSolver: minMeanderHeight cannot exceed maximumMeanderDepth\");if(!Number.isFinite(n)||!Number.isInteger(n)||n\u003c=0)throw new Error(\"LengthMatchingSolver: maxToothCount must be a positive finite integer\");return{maximumMeanderDepth:e,minimumToothPitch:t.minimumToothPitch,minMeanderGap:t.minMeanderGap,minMeanderHeight:t.minMeanderHeight,maxToothCount:n,obstacles:t.obstacles??[],bounds:t.bounds,obstacleMargin:t.obstacleMargin??.15,layerCount:t.layerCount??2,colorMap:t.colorMap??{}}})(this.params)),this.config}_step(){this.getConfig(),this.activePair?this.tryCandidate(this.activePair):this.startNextPair()}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved)throw new Error(\"LengthMatchingSolver: getOutput() called before the solver completed\");return{matchedHdRoutes:this.matchedHdRoutes}}getBestEffortOutput(){const t=structuredClone(this.matchedHdRoutes),e=this.activePair?.fullAttempts??[];let n=null;for(const t of e)(!n||t.qualityScore\u003en.qualityScore)\u0026\u0026(n=t);if(!n)for(const t of this.activePair?.partialAttempts??[])(!n||t.addedLength\u003en.addedLength||t.addedLength===n.addedLength\u0026\u0026t.qualityScore\u003en.qualityScore)\u0026\u0026(n=t);if(n){const e=t[n.routeIndex];e\u0026\u0026(t[n.routeIndex]={...e,route:structuredClone(n.predictedRoute)})}return{matchedHdRoutes:t}}computeProgress(){if(this.solved)return 1;if(0===this.pairs.length)return this.config?1:0;const t=Math.max(0,this.nextPairIndex-1),e=this.activePair?this.activePair.candidateIndex/this.activePair.candidates.length:0;return Math.min(.99,(t+e)/this.pairs.length)}visualize(){const t=this.getConfig();return TG({routes:this.matchedHdRoutes,obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,colorMap:t.colorMap,activePair:this.activePair,currentAttempt:this.currentAttempt,solved:this.solved})}},EG=(t,e)=\u003e{if(\"top\"===t)return 0;if(\"bottom\"===t)return e-1;const n=/^inner(\\d+)$/.exec(t);if(!n)return-1;const o=Number(n[1]);return o\u003e0\u0026\u0026o\u003ce-1?o:-1},AG=(t,e)=\u003e0===t?\"top\":t===e-1?\"bottom\":`inner${t}`,OG=(t,e,n)=\u003e{const o=EG(t,n),i=EG(e,n);if(o\u003c0||i\u003c0)return[];const r=Math.min(o,i),s=Math.max(o,i);return Array.from({length:s-r+1},(t,e)=\u003eAG(r+e,n))},kG=1e-8,LG=(t,e)=\u003e{if(0===t.route.length)throw new Error(`trace \"${t.connection_name}\" has an empty route`);if(t.route.some(t=\u003e\"wire\"!==t.route_type\u0026\u0026\"via\"!==t.route_type))throw new Error(`trace \"${t.connection_name}\" contains unsupported jumper or through-obstacle geometry`);const n=t.route.findIndex(t=\u003e\"wire\"===t.route_type),o=t.route[n],i=t.route.findLast(t=\u003e\"wire\"===t.route_type);if(\"wire\"!==o?.route_type||!i)throw new Error(`trace \"${t.connection_name}\" must contain a wire point`);const r=[],s=[],a=[],c=[];let l=null,d=o.width;if(n\u003e0){let e=o.layer;for(let o=n-1;o\u003e=0;o--){const n=t.route[o];if(\"via\"!==n?.route_type)throw new Error(`trace \"${t.connection_name}\" has unsupported geometry before its first wire`);if(e===n.to_layer)e=n.from_layer;else{if(e!==n.from_layer)throw new Error(`trace \"${t.connection_name}\" has discontinuous leading vias`);e=n.to_layer}}const i=t.route[0];if(\"via\"!==i.route_type)throw new Error(`trace \"${t.connection_name}\" has an invalid leading entry`);l={x:i.x,y:i.y,layer:e,width:o.width},r.push(l)}for(const n of t.route){if(\"wire\"===n.route_type){if(!Number.isFinite(n.x)||!Number.isFinite(n.y)||!Number.isFinite(n.width)||n.width\u003c=0||EG(n.layer,e)\u003c0)throw new Error(`trace \"${t.connection_name}\" has an invalid wire point`);d=Math.max(d,n.width);const o={x:n.x,y:n.y,layer:n.layer,width:n.width};if(l){if(l.layer!==o.layer)throw new Error(`trace \"${t.connection_name}\" changes layers without a via`);Math.hypot(l.x-o.x,l.y-o.y)\u003ekG\u0026\u0026s.push({start:l,end:o,layer:o.layer,width:Math.max(l.width,o.width),connectionName:t.connection_name,terminal:null})}r.push(o),l=o;continue}if(\"via\"!==n.route_type)throw new Error(`trace \"${t.connection_name}\" contains unsupported route geometry`);if(!l)throw new Error(`trace \"${t.connection_name}\" has a leading via`);const o=EG(n.from_layer,e),i=EG(n.to_layer,e),h=n.via_diameter??l.width;if(!Number.isFinite(n.x)||!Number.isFinite(n.y)||o\u003c0||i\u003c0||o===i||void 0!==n.via_diameter\u0026\u0026(!Number.isFinite(n.via_diameter)||n.via_diameter\u003c=0)||void 0!==n.via_hole_diameter\u0026\u0026(!Number.isFinite(n.via_hole_diameter)||n.via_hole_diameter\u003c=0||n.via_hole_diameter\u003e=h))throw new Error(`trace \"${t.connection_name}\" has an invalid via`);const u=l.layer===n.from_layer?n.from_layer:l.layer===n.to_layer?n.to_layer:null;if(!u)throw new Error(`trace \"${t.connection_name}\" has a discontinuous via transition`);Math.hypot(l.x-n.x,l.y-n.y)\u003ekG\u0026\u0026s.push({start:l,end:n,layer:l.layer,width:l.width,connectionName:t.connection_name,terminal:null});const p=u===n.from_layer?n.to_layer:n.from_layer;c.push({...n,from_layer:u,to_layer:p}),a.push({x:n.x,y:n.y,layers:OG(u,p,e),diameter:h,connectionName:t.connection_name,terminal:1===r.length?\"start\":null}),l={x:n.x,y:n.y,layer:p,width:l.width},r.push(l)}if(r.length\u003c2||0===s.length)throw new Error(`trace \"${t.connection_name}\" does not contain a routable path`);s[0].terminal=1===s.length?\"both\":\"start\",s[s.length-1].terminal=1===s.length?\"both\":\"end\";const h=a.at(-1);return h\u0026\u0026Math.hypot(h.x-i.x,h.y-i.y)\u003c=kG\u0026\u0026(h.terminal=\"end\"),{source:t,points:r,segments:s,vias:a,transitions:c,width:d,viaDiameter:t.__postProcessingViaDiameter??d,...o.start_pcb_port_id?{startPortId:o.start_pcb_port_id}:{},...i.end_pcb_port_id?{endPortId:i.end_pcb_port_id}:{}}},DG=(t,e)=\u003e{const n=[],o=[],i=t.route.find(t=\u003e\"wire\"===t.route_type),r=\"wire\"===i?.route_type?i.width:null,s={\"0603\":.95,1206:1.8,\"1206x4_pair\":1.8};let a=null;for(let i=0;i\u003ct.route.length;i++){const c=t.route[i];if(\"wire\"===c.route_type){if(!Number.isFinite(c.x)||!Number.isFinite(c.y)||!Number.isFinite(c.width)||c.width\u003c=0||EG(c.layer,e)\u003c0)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has an invalid wire`);if(a\u0026\u0026a.layer!==c.layer)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" changes layer without a transition`);a\u0026\u0026n.push({start:a,end:c,layer:c.layer,width:Math.max(a.width,c.width),connectionName:t.connection_name,terminal:null}),a=c;continue}if(\"via\"===c.route_type){const s=OG(c.from_layer,c.to_layer,e),l=a,d=c.via_diameter??l?.width??r;if(!Number.isFinite(c.x)||!Number.isFinite(c.y)||s.length\u003c2||null===d||!Number.isFinite(d)||d\u003c=0||void 0!==c.via_hole_diameter\u0026\u0026(!Number.isFinite(c.via_hole_diameter)||c.via_hole_diameter\u003c=0||null!==d\u0026\u0026c.via_hole_diameter\u003e=d))throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has an invalid via`);l\u0026\u0026Math.hypot(l.x-c.x,l.y-c.y)\u003e1e-8\u0026\u0026n.push({start:l,end:c,layer:l.layer,width:l.width,connectionName:t.connection_name,terminal:null}),o.push({x:c.x,y:c.y,layers:s,diameter:d,connectionName:t.connection_name,terminal:0===i?\"start\":i===t.route.length-1?\"end\":null});const h=t.route.slice(i+1).find(t=\u003e\"wire\"===t.route_type),u=l?.layer===c.from_layer?c.to_layer:l?.layer===c.to_layer?c.from_layer:\"wire\"!==h?.route_type||h.layer!==c.from_layer\u0026\u0026h.layer!==c.to_layer?null:h.layer;if(!u)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has a discontinuous via`);a={x:c.x,y:c.y,layer:u,width:l?.width??r??d};continue}if(\"jumper\"===c.route_type){const o=s[c.footprint];if(!Number.isFinite(c.start.x)||!Number.isFinite(c.start.y)||!Number.isFinite(c.end.x)||!Number.isFinite(c.end.y)||EG(c.layer,e)\u003c0)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has an invalid jumper`);if(a\u0026\u0026(a.layer!==c.layer||Math.hypot(a.x-c.start.x,a.y-c.start.y)\u003e1e-8))throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has a discontinuous jumper`);n.push({start:c.start,end:c.end,layer:c.layer,width:o,connectionName:t.connection_name,terminal:null}),a={...c.end,layer:c.layer,width:o};continue}const l=OG(c.from_layer,c.to_layer,e);if(!Number.isFinite(c.start.x)||!Number.isFinite(c.start.y)||!Number.isFinite(c.end.x)||!Number.isFinite(c.end.y)||!Number.isFinite(c.width)||c.width\u003c=0||l.length\u003c2)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has invalid through-obstacle copper`);if(a\u0026\u0026(a.layer!==c.from_layer\u0026\u0026a.layer!==c.to_layer||Math.hypot(a.x-c.start.x,a.y-c.start.y)\u003e1e-8))throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has discontinuous through-obstacle copper`);for(const e of l)n.push({start:c.start,end:c.end,layer:e,width:c.width,connectionName:t.connection_name,terminal:null});const d=a,h=d?.layer===c.to_layer?c.from_layer:c.to_layer;a={...c.end,layer:h,width:c.width}}return{segments:n,vias:o}},zG=(t,e)=\u003e{const n=DG(t,e);return[...n.segments.map((n,o)=\u003e({connectionName:`${t.connection_name}#immutable-segment-${o}`,rootConnectionName:t.connection_name,traceThickness:n.width,viaDiameter:n.width,route:[{x:n.start.x,y:n.start.y,z:EG(n.layer,e),traceThickness:n.width},{x:n.end.x,y:n.end.y,z:EG(n.layer,e),traceThickness:n.width}],vias:[]})),...n.vias.map((n,o)=\u003e({connectionName:`${t.connection_name}#immutable-via-${o}`,rootConnectionName:t.connection_name,traceThickness:n.diameter,viaDiameter:n.diameter,route:[],vias:[{x:n.x,y:n.y,zLayers:n.layers.map(t=\u003eEG(t,e))}]}))]},FG=t=\u003et.segments.reduce((t,e)=\u003et+Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),0),BG=t=\u003e{const{simpleRouteJson:e}=t.params,n=(t=\u003e{const e=new Set(t.reroutedPairs.map(t=\u003et.connectionNames.join(\"\\0\")));return t.declaredPairs.filter(n=\u003e{const o=n.connectionNames.map(e=\u003et.traces.filter(t=\u003et.connection_name===e));if(o.some(t=\u003e1!==t.length))return!1;if(e.has(n.connectionNames.join(\"\\0\")))return!0;const i=o.map(t=\u003et[0]);if(i.some(t=\u003et.route.length\u003c2||\"wire\"!==t.route[0]?.route_type||!t.route.every(t=\u003e\"wire\"===t.route_type||\"via\"===t.route_type)))return!1;const r=i.map(e=\u003eFG(LG(e,t.layerCount)));return Math.abs(r[0]-r[1])\u003en.lengthTolerance+1e-7}).map(t=\u003estructuredClone(t))})({traces:t.result.traces,declaredPairs:e.differentialPairs,reroutedPairs:t.result.reroutedPairs,layerCount:e.layerCount}),o=new Set(n.flatMap(t=\u003et.connectionNames)),i=[],r=[],s=[],a=new Set;for(let n=0;n\u003ct.result.traces.length;n++){const c=t.result.traces[n];if(!o.has(c.connection_name))continue;const l=c.route.every(t=\u003e\"wire\"===t.route_type||\"via\"===t.route_type),d=\"wire\"===c.route[0]?.route_type;if(!l||!d)throw new Error(`PostProcessingSolver: rerouted connection \"${c.connection_name}\" cannot be bound to LengthMatchingSolver`);const h=LG(c,e.layerCount),u=c.route[0];if(\"wire\"!==u.route_type)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" lost its first wire during binding`);const p=[{x:u.x,y:u.y,z:EG(u.layer,e.layerCount),traceThickness:u.width}],m=[],g=[];let f=u.layer,y=u.width;for(const t of c.route.slice(1)){if(\"wire\"===t.route_type){if(t.layer!==f)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" changes layers without a via while binding`);p.push({x:t.x,y:t.y,z:EG(t.layer,e.layerCount),traceThickness:t.width}),y=t.width;continue}if(\"via\"!==t.route_type)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" contains unsupported bound geometry`);const n=f===t.from_layer?t.to_layer:f===t.to_layer?t.from_layer:null;if(!n)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" has a discontinuous bound via`);const o=p.at(-1);Math.hypot(o.x-t.x,o.y-t.y)\u003e1e-8\u0026\u0026p.push({x:t.x,y:t.y,z:EG(f,e.layerCount),traceThickness:y}),p.push({x:t.x,y:t.y,z:EG(n,e.layerCount),traceThickness:y}),m.push({x:t.x,y:t.y,zLayers:OG(t.from_layer,t.to_layer,e.layerCount).map(t=\u003eEG(t,e.layerCount))}),g.push({...t}),f=n}if(p.length\u003c2)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" has no bound copper segments`);const _=Math.max(...p.map(t=\u003et.traceThickness??h.width)),b=h.viaDiameter,x=i.length;i.push({connectionName:c.connection_name,traceThickness:_,viaDiameter:b,route:p,vias:m});const v=p[0],S=p.at(-1);r.push({name:c.connection_name,pointsToConnect:[{x:v.x,y:v.y,layer:u.layer,...h.startPortId?{pcb_port_id:h.startPortId}:{}},{x:S.x,y:S.y,layer:h.points.at(-1).layer,...h.endPortId?{pcb_port_id:h.endPortId}:{}}]}),s.push({traceIndex:n,matchedRouteIndex:x,viaTemplates:g,startEndpoint:{...v},endEndpoint:{...S},...h.startPortId?{startPortId:h.startPortId}:{},...h.endPortId?{endPortId:h.endPortId}:{}}),a.add(c.connection_name)}for(const t of o)if(!a.has(t))throw new Error(`PostProcessingSolver: missing LengthMatchingSolver binding for rerouted connection \"${t}\"`);for(const n of t.result.traces)o.has(n.connection_name)||i.push(...zG(n,e.layerCount));const c=e.minTraceToPadEdgeClearance??Math.max(0,...i.filter(t=\u003et.route.length\u003e=2).map(t=\u003et.traceThickness));return{solverParams:{hdRoutes:i,originalConnections:r,differentialPairs:n,obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,obstacleMargin:c},traceBindings:s,baseTraces:structuredClone(t.result.traces)}},jG=t=\u003e{const e=new Map;for(const n of t.differentialPairs)for(const o of n.connectionNames){const n=t.hdRoutes.map((t,e)=\u003e({route:t,hdRouteIndex:e})).filter(({route:t})=\u003et.connectionName===o);1===n.length\u0026\u0026e.set(n[0].hdRouteIndex,o)}const n=t.hdRoutes.map((e,n)=\u003e{const o=[],i=new Map;for(let t=0;t\u003c(e.jumpers?.length??0);t++){const n=e.jumpers[t],o=e.route.map((t,e)=\u003e({point:t,index:e})).filter(({point:t})=\u003eMath.hypot(t.x-n.start.x,t.y-n.start.y)\u003c=1e-8).map(({index:t})=\u003et),r=e.route.map((t,e)=\u003e({point:t,index:e})).filter(({point:t})=\u003eMath.hypot(t.x-n.end.x,t.y-n.end.y)\u003c=1e-8).map(({index:t})=\u003et),s=[...o.flatMap(t=\u003er.filter(e=\u003ee\u003et).map(e=\u003e({startIndex:t,endIndex:e}))),...r.flatMap(t=\u003eo.filter(e=\u003ee\u003et).map(e=\u003e({startIndex:t,endIndex:e})))];if(1!==s.length)throw new Error(`PostProcessingSolver: immutable HD route \"${e.connectionName}\" has an ambiguous jumper traversal`);const a=s[0];if(i.has(a.startIndex)||[...i.values()].some(({endIndex:t})=\u003ea.startIndex\u003ct||a.endIndex\u003c=t))throw new Error(`PostProcessingSolver: immutable HD route \"${e.connectionName}\" has overlapping or unordered jumpers`);i.set(a.startIndex,{endIndex:a.endIndex,jumperIndex:t})}if(e.route.length\u003e0){const n=e.route[0];o.push({route_type:\"wire\",x:n.x,y:n.y,width:n.traceThickness??e.traceThickness,layer:AG(n.z,t.layerCount)});for(let n=0;n\u003ce.route.length-1;n++){const r=e.route[n],s=i.get(n);if(s){const i=e.route[s.endIndex],a=e.jumpers[s.jumperIndex];if(r.z!==i.z)throw new Error(`PostProcessingSolver: immutable HD route \"${e.connectionName}\" changes layers through a jumper`);o.push({route_type:\"jumper\",start:{x:r.x,y:r.y},end:{x:i.x,y:i.y},footprint:a.footprint,layer:AG(r.z,t.layerCount)}),o.push({route_type:\"wire\",x:i.x,y:i.y,width:i.traceThickness??e.traceThickness,layer:AG(i.z,t.layerCount)}),n=s.endIndex-1;continue}const a=e.route[n+1],c=AG(r.z,t.layerCount),l=AG(a.z,t.layerCount);r.z!==a.z\u0026\u0026(\"through_obstacle\"===r.toNextSegmentType?o.push({route_type:\"through_obstacle\",start:{x:r.x,y:r.y},end:{x:a.x,y:a.y},from_layer:c,to_layer:l,width:r.traceThickness??e.traceThickness}):o.push({route_type:\"via\",x:a.x,y:a.y,from_layer:c,to_layer:l,via_diameter:e.viaDiameter})),o.push({route_type:\"wire\",x:a.x,y:a.y,width:a.traceThickness??e.traceThickness,layer:l})}const r=o.filter(t=\u003e\"wire\"===t.route_type),s=e.startPcbPortId??e.route[0]?.pcb_port_id,a=e.endPcbPortId??e.route.at(-1)?.pcb_port_id;s\u0026\u0026r[0]\u0026\u0026(r[0].start_pcb_port_id=s),a\u0026\u0026r.at(-1)\u0026\u0026(r.at(-1).end_pcb_port_id=a)}return{type:\"pcb_trace\",pcb_trace_id:`post_processing_hd_route_${n}`,connection_name:e.connectionName,__postProcessingViaDiameter:e.viaDiameter,route:o}}),o=structuredClone(t.obstacles);for(let n=0;n\u003ct.hdRoutes.length;n++){const i=t.hdRoutes[n],r=new Set([i.connectionName,i.rootConnectionName,i.startPcbPortId,i.endPcbPortId,i.route[0]?.pcb_port_id,i.route.at(-1)?.pcb_port_id,e.get(n)].filter(t=\u003evoid 0!==t));for(const t of o)t.connectedTo.some(t=\u003er.has(t))\u0026\u0026(t.connectedTo=[...new Set([...t.connectedTo,...r])])}return{params:{simpleRouteJson:{traces:n,differentialPairs:structuredClone(t.differentialPairs),obstacles:o,bounds:structuredClone(t.bounds),layerCount:t.layerCount,minTraceToPadEdgeClearance:t.minTraceToPadEdgeClearance},...t.routingGrid?{routingGrid:structuredClone(t.routingGrid)}:{}},routeBindings:[...e.entries()].map(([t,e])=\u003e({hdRouteIndex:t,traceIndex:t,internalConnectionName:e})),sourceHdRoutes:structuredClone(t.hdRoutes)}};function $G(t){const e=structuredClone(t.model.sourceHdRoutes);for(const n of t.model.routeBindings){const o=t.binding.traceBindings.find(t=\u003et.traceIndex===n.traceIndex);if(!o)continue;const i=t.result.matchedHdRoutes[o.matchedRouteIndex],r=e[n.hdRouteIndex];if(!i||!r)throw new Error(`PostProcessingSolver: missing matched or source HD route for \"${n.internalConnectionName}\"`);if(i.connectionName!==n.internalConnectionName)throw new Error(`PostProcessingSolver: matched HD binding changed \"${n.internalConnectionName}\" to \"${i.connectionName}\"`);const s=i.route.map(t=\u003e({...t})),a=(e,o)=\u003e{if(e\u0026\u0026o\u0026\u0026(o.pcb_port_id\u0026\u0026(e.pcb_port_id=o.pcb_port_id),o.insideJumperPad\u0026\u0026t.rejectInsideJumperPad))throw new Error(`PostProcessingSolver: cannot restore jumper-pad metadata on rerouted connection \"${n.internalConnectionName}\"`)};a(s[0],r.route[0]),a(s.at(-1),r.route.at(-1)),e[n.hdRouteIndex]={...r,route:s,vias:structuredClone(i.vias)}}return{hdRoutes:e,postProcessingErrors:[]}}var YG=class extends Error{connectionNames;reason;constructor(t){super(`PostProcessingSolver: differential pair ${t.connectionNames.join(\"/\")} ${t.message}`),this.name=\"DifferentialPairRoutingError\",this.connectionNames=[t.connectionNames[0],t.connectionNames[1]],this.reason=t.reason}},XG=class extends Error{connectionNames;reason;constructor(t){super(t.message),this.name=\"PostProcessingConstraintError\",this.connectionNames=[...t.connectionNames],this.reason=t.reason}},VG=class extends Error{reason=\"grid-capacity-exhausted\";constructor(t){super(t),this.name=\"PostProcessingGridCapacityError\"}},WG=t=\u003e{const e=75e3*t.simpleRouteJson.differentialPairs.length;if(!Number.isSafeInteger(e))throw new Error(\"PostProcessingSolver: derived rerouting iteration bound exceeds the safe integer range\");const n=Math.min(e,8e4);return Math.max(1,n)},HG=t=\u003estructuredClone(t),GG=(t,e,n)=\u003e{const o=t=\u003e{const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}},i=o(t.start),r=o(t.end),s=e.width/2+n,a=e.height/2+n;if(Math.abs(i.x)\u003c=s\u0026\u0026Math.abs(i.y)\u003c=a||Math.abs(r.x)\u003c=s\u0026\u0026Math.abs(r.y)\u003c=a)return!0;const c=[{x:-s,y:-a},{x:s,y:-a},{x:s,y:a},{x:-s,y:a}];return c.some((t,e)=\u003ecG(i,r,t,c[(e+1)%c.length])\u003c=1e-7)},UG=t=\u003e{const e=[],n=[];for(const o of t.immutableTraces){const i=DG(o,t.layerCount);e.push(...i.segments),n.push(...i.vias)}const o=Array.from({length:t.layerCount},()=\u003e[]);for(const n of e){const e=EG(n.layer,t.layerCount);o[e].push(n)}const i=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y)\u003c=1e-8,r=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-e.x-o*s,t.y-e.y-i*s)},s=(t,e,n)=\u003e{const o=-(e.ccwRotationDegrees??0)*Math.PI/180,i=t.x-e.center.x,r=t.y-e.center.y,s=i*Math.cos(o)-r*Math.sin(o),a=i*Math.sin(o)+r*Math.cos(o);return Math.abs(s)\u003c=e.width/2+n\u0026\u0026Math.abs(a)\u003c=e.height/2+n},a=(e,n)=\u003e{const o=EG(n,t.layerCount);return uG(e,t.layerCount).includes(o)},c=(e,n,o)=\u003e{const i=((e,n,o)=\u003e{const i=Math.hypot(n.x,n.y);if(i\u003c=1e-10)throw new Error(\"PostProcessingSolver: cannot orient terminal fanout on a zero-length spine\");const r=-n.y/i*t.side*t.centerlineSpacing/2,s=n.x/i*t.side*t.centerlineSpacing/2,a=\"start\"===o?[t.firstStartTerminal,t.secondStartTerminal]:[t.firstEndTerminal,t.secondEndTerminal],c=[t.firstWidth,t.secondWidth],l=[t.firstConnectionName,t.secondConnectionName];return a.map((t,n)=\u003e{const i=0===n?1:-1,a={x:e.x+r*i,y:e.y+s*i};return{start:\"start\"===o?t:a,end:\"start\"===o?a:t,layer:e.layer,width:c[n],connectionName:l[n],terminal:o}})})(e,n,o),r=i.map(t=\u003e\"start\"===o?t.end:t.start);return i.every(l)\u0026\u0026r.every((n,o)=\u003et.obstacles.every(r=\u003e!a(r,e.layer)||!s(n,r,1.5*i[o].width+(t.terminalMiterMargin??0))))\u0026\u0026cG(i[0].start,i[0].end,i[1].start,i[1].end)\u003e=i[0].width/2+i[1].width/2-1e-7},l=e=\u003e{const i=e.width/2,c=i+(t.minTraceToPadEdgeClearance??e.width),l=EG(e.layer,t.layerCount),d=Math.min(e.start.x,e.end.x),h=Math.max(e.start.x,e.end.x),u=Math.min(e.start.y,e.end.y),p=Math.max(e.start.y,e.end.y);for(const n of[e.start,e.end])if(n.x-i\u003ct.bounds.minX||n.x+i\u003et.bounds.maxX||n.y-i\u003ct.bounds.minY||n.y+i\u003et.bounds.maxY)return!1;for(const n of t.obstacles){if(!a(n,e.layer))continue;const o=Math.hypot(n.width/2+c,n.height/2+c);if(h\u003cn.center.x-o||d\u003en.center.x+o||p\u003cn.center.y-o||u\u003en.center.y+o)continue;const[i,r]=e.connectionName===t.firstConnectionName?[t.firstStartTerminal,t.firstEndTerminal]:[t.secondStartTerminal,t.secondEndTerminal],l=s(i,n,0)\u0026\u0026(s(e.start,n,c)||s(e.end,n,c))\u0026\u0026Math.hypot(e.end.x-i.x,e.end.y-i.y)\u003e=Math.hypot(e.start.x-i.x,e.start.y-i.y),m=s(r,n,0)\u0026\u0026(s(e.start,n,c)||s(e.end,n,c))\u0026\u0026Math.hypot(e.end.x-r.x,e.end.y-r.y)\u003c=Math.hypot(e.start.x-r.x,e.start.y-r.y);if(!(n.connectedTo.includes(e.connectionName)\u0026\u0026(l||m))\u0026\u0026GG(e,n,c))return!1}for(const t of o[l]){const n=e.width/2+t.width/2+Math.max(e.width,t.width);if(!(h+n\u003cMath.min(t.start.x,t.end.x)||d-n\u003eMath.max(t.start.x,t.end.x)||p+n\u003cMath.min(t.start.y,t.end.y)||u-n\u003eMath.max(t.start.y,t.end.y))\u0026\u0026cG(e.start,e.end,t.start,t.end)\u003cn)return!1}for(const t of n)if(t.layers.includes(e.layer)\u0026\u0026r(t,e.start,e.end)\u003ce.width/2+t.diameter/2+e.width)return!1;return!0},d=o=\u003e{const i=o.diameter/2;if(o.x-i\u003ct.bounds.minX||o.x+i\u003et.bounds.maxX||o.y-i\u003ct.bounds.minY||o.y+i\u003et.bounds.maxY)return!1;for(const e of t.obstacles){if(!o.layers.some(t=\u003ea(e,t)))continue;if(!(null!==o.terminal\u0026\u0026e.connectedTo.includes(o.connectionName)\u0026\u0026s(o,e,0))\u0026\u0026s(o,e,i+o.diameter))return!1}for(const t of e){if(!o.layers.includes(t.layer))continue;const e=i+t.width/2+Math.max(o.diameter,t.width);if(r(o,t.start,t.end)\u003ce)return!1}for(const t of n){if(!t.layers.some(t=\u003eo.layers.includes(t)))continue;const e=i+t.diameter/2+Math.max(o.diameter,t.diameter);if(Math.hypot(o.x-t.x,o.y-t.y)\u003ce)return!1}return!0};return{isEdgeValid:(e,n)=\u003e{if(e.layer!==n.layer||!((e,n)=\u003e{const o=Math.hypot(n.x-e.x,n.y-e.y);if(0===o)return[];const r=-(n.y-e.y)/o*t.side*t.centerlineSpacing/2,s=(n.x-e.x)/o*t.side*t.centerlineSpacing/2,a=i(e,t.start),c=i(n,t.end),l=t.terminalFanout?a\u0026\u0026c?\"both\":a?\"start\":c?\"end\":null:null,d=a\u0026\u0026t.terminalFanout?t.firstStartTerminal:{x:e.x+r,y:e.y+s},h=c\u0026\u0026t.terminalFanout?t.firstEndTerminal:{x:n.x+r,y:n.y+s},u=a\u0026\u0026t.terminalFanout?t.secondStartTerminal:{x:e.x-r,y:e.y-s},p=c\u0026\u0026t.terminalFanout?t.secondEndTerminal:{x:n.x-r,y:n.y-s};return[{start:d,end:h,layer:e.layer,width:t.firstWidth,connectionName:t.firstConnectionName,terminal:l},{start:u,end:p,layer:e.layer,width:t.secondWidth,connectionName:t.secondConnectionName,terminal:l}]})(e,n).every(l))return!1;if(t.terminalFanout||void 0===t.terminalMiterMargin)return!0;const o={x:n.x-e.x,y:n.y-e.y};return!(i(e,t.start)\u0026\u0026!c(e,o,\"start\"))\u0026\u0026!(i(n,t.end)\u0026\u0026!c(n,o,\"end\"))},isTerminalFanoutValid:c,isViaValid:(e,n,o)=\u003e{const r=Math.hypot(o.x,o.y);if(r\u003c=1e-10)throw new Error(\"PostProcessingSolver: cannot orient a coupled via on a zero-length spine\");const s=OG(e.layer,n,t.layerCount),a=-o.y/r*t.side*t.centerlineSpacing/2,c=o.x/r*t.side*t.centerlineSpacing/2,l=i(e,t.start)?\"start\":i(e,t.end)?\"end\":null;return[{x:e.x+a,y:e.y+c,layers:s,diameter:t.firstViaDiameter,connectionName:t.firstConnectionName,terminal:l},{x:e.x-a,y:e.y-c,layers:s,diameter:t.secondViaDiameter,connectionName:t.secondConnectionName,terminal:l}].every(d)}}},ZG=(t,e,n)=\u003e{const o=1e-7,i=(t,e)=\u003e{const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}},r=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},s=(t,e,n)=\u003e{const o=EG(e,n);return uG(t,n).includes(o)},a=(t,e,n)=\u003e{const a=t.width/2;if(t.start.x-a\u003ce.bounds.minX-o||t.start.x+a\u003ee.bounds.maxX+o||t.start.y-a\u003ce.bounds.minY-o||t.start.y+a\u003ee.bounds.maxY+o||t.end.x-a\u003ce.bounds.minX-o||t.end.x+a\u003ee.bounds.maxX+o||t.end.y-a\u003ce.bounds.minY-o||t.end.y+a\u003ee.bounds.maxY+o)return!1;for(const n of e.obstacles){if(!s(n,t.layer,e.layerCount))continue;const r=\"both\"===t.terminal?[t.start,t.end]:\"start\"===t.terminal?[t.start]:\"end\"===t.terminal?[t.end]:[];if(!(n.connectedTo.includes(t.connectionName)\u0026\u0026r.some(t=\u003e{const e=i(t,n);return Math.abs(e.x)\u003c=n.width/2+o\u0026\u0026Math.abs(e.y)\u003c=n.height/2+o}))\u0026\u0026GG(t,n,a+(e.minTraceToPadEdgeClearance??t.width)))return!1}for(const e of n.segments){if(e.layer!==t.layer)continue;const n=t.width/2+e.width/2+Math.max(t.width,e.width);if(cG(t.start,t.end,e.start,e.end)\u003cn-o)return!1}for(const e of n.vias){if(!e.layers.includes(t.layer))continue;const n=t.width/2+e.diameter/2+t.width;if(r(e,t.start,t.end)\u003cn-o)return!1}return!0},c=(t,e,n)=\u003e{const a=t.diameter/2;if(t.x-a\u003ce.bounds.minX-o||t.x+a\u003ee.bounds.maxX+o||t.y-a\u003ce.bounds.minY-o||t.y+a\u003ee.bounds.maxY+o)return!1;for(const n of e.obstacles){if(!t.layers.some(t=\u003es(n,t,e.layerCount)))continue;const r=i(t,n);if(!(null!==t.terminal\u0026\u0026n.connectedTo.includes(t.connectionName)\u0026\u0026Math.abs(r.x)\u003c=n.width/2+o\u0026\u0026Math.abs(r.y)\u003c=n.height/2+o)\u0026\u0026Math.abs(r.x)\u003c=n.width/2+a+t.diameter\u0026\u0026Math.abs(r.y)\u003c=n.height/2+a+t.diameter)return!1}for(const e of n.segments){if(!t.layers.includes(e.layer))continue;const n=a+e.width/2+Math.max(t.diameter,e.width);if(r(t,e.start,e.end)\u003cn-o)return!1}for(const e of n.vias){if(!e.layers.some(e=\u003et.layers.includes(e)))continue;const n=a+e.diameter/2+Math.max(t.diameter,e.diameter);if(Math.hypot(t.x-e.x,t.y-e.y)\u003cn-o)return!1}return!0},l=t=\u003e{for(let e=0;e\u003ct.segments.length;e++){const n=t.segments[e];for(let i=e+2;i\u003ct.segments.length;i++){const r=t.segments[i];if(n.layer!==r.layer)continue;if(!(t.segments.slice(e+1,i).reduce((t,e)=\u003et+Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),0)\u003c=n.width+r.width+o)\u0026\u0026cG(n.start,n.end,r.start,r.end)\u003cn.width/2+r.width/2-o)return!0}}for(const e of t.vias)for(const n of t.segments){if(!e.layers.includes(n.layer))continue;if(!(Math.hypot(e.x-n.start.x,e.y-n.start.y)\u003c=o||Math.hypot(e.x-n.end.x,e.y-n.end.y)\u003c=o)\u0026\u0026r(e,n.start,n.end)\u003ce.diameter/2+n.width/2-o)return!0}return!1},d=((t,e)=\u003e{const n=[],o=[];for(const i of t){const t=DG(i,e);n.push(...t.segments),o.push(...t.vias)}return{segments:n,vias:o}})(n.immutableTraces,n.layerCount);if(!((t,e)=\u003e{for(const n of t.segments)for(const t of e.segments){if(n.layer!==t.layer)continue;const e=n.width/2+t.width/2;if(cG(n.start,n.end,t.start,t.end)\u003ce-o)return!1}for(const[n,i]of[[t.vias,e.segments],[e.vias,t.segments]])for(const t of n)for(const e of i)if(t.layers.includes(e.layer)\u0026\u0026r(t,e.start,e.end)\u003ct.diameter/2+e.width/2-o)return!1;for(const n of t.vias)for(const t of e.vias)if(n.layers.some(e=\u003et.layers.includes(e))\u0026\u0026Math.hypot(n.x-t.x,n.y-t.y)\u003cn.diameter/2+t.diameter/2-o)return!1;return!0})(t,e)||l(t)||l(e))return!1;for(const o of[t,e])if(o.segments.some(t=\u003e!a(t,n,d))||o.vias.some(t=\u003e!c(t,n,d)))return!1;return!0},qG=[{x:1,y:0},{x:1,y:1},{x:0,y:1},{x:-1,y:1},{x:-1,y:0},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1}],JG=class{constructor(t){this.input=t;const{bounds:e,grid:n}=t,o={minX:e.minX+n.outerPerimeterWidth,maxX:e.maxX-n.outerPerimeterWidth,minY:e.minY+n.outerPerimeterWidth,maxY:e.maxY-n.outerPerimeterWidth},i=this.createAxis(e.minX,e.maxX,n.outerGridStep,[o.minX,o.maxX]),r=this.createAxis(e.minY,e.maxY,n.outerGridStep,[o.minY,o.maxY]),s=this.createAxis(o.minX,o.maxX,n.innerGridStep,[],t.start.x),a=this.createAxis(o.minY,o.maxY,n.innerGridStep,[],t.start.y),c=this.createGrid(i,r,t=\u003et.x\u003c=o.minX||t.x\u003e=o.maxX||t.y\u003c=o.minY||t.y\u003e=o.maxY),l=this.createGrid(s,a,()=\u003e!0);this.connectLocalNeighbors(c),this.connectLocalNeighbors(l);for(const t of[\"left\",\"right\",\"bottom\",\"top\"])this.connectBoundaries(t,c,l,o);const d=this.nodes.map((t,e)=\u003ee);this.connectEndpoint(t.start,d),this.connectEndpoint(t.end,d)}input;nodes=[];nodeIdByPoint=new Map;endpointNodeIdByPoint=new Map;getPlanarNeighbors(t){const e=this.endpointNodeIdByPoint.get(this.exactKeyFor(t))??this.nodeIdByPoint.get(this.keyFor(t));if(void 0===e)throw new Error(`PostProcessingSolver: coupled path point (${t.x}, ${t.y}) is not on the composite grid`);return[...this.nodes[e].neighborIds].map(e=\u003e({...this.nodes[e].point,layer:t.layer}))}getNodeCount(){return this.nodes.length}getSearchStateCountUpperBound(t){const e=this.nodes.reduce((t,e)=\u003et+e.neighborIds.size,0)*t+1;if(!Number.isSafeInteger(e))throw new Error(\"PostProcessingSolver: composite-grid search-state bound exceeds the safe integer range\");return e}createAxis(t,e,n,o,i=t){const r=[t,e,...o].map(t=\u003e({value:t,fixed:!0}));for(let o=Math.ceil((t-i)/n);i+o*n\u003ce-1e-8;o++)r.push({value:i+o*n,fixed:!1});r.sort((t,e)=\u003et.value-e.value||Number(e.fixed)-Number(t.fixed));const s=[];for(const t of r){const e=s.at(-1);!e||Math.abs(t.value-e.value)\u003e1e-8?s.push(t):t.fixed\u0026\u0026!e.fixed\u0026\u0026(s[s.length-1]=t)}return s.map(t=\u003et.value)}createGrid(t,e,n){return e.map(e=\u003et.map(t=\u003e{const o={x:t,y:e};return n(o)?this.addNode(o):null}))}connectLocalNeighbors(t){for(let e=0;e\u003ct.length;e++)for(let n=0;n\u003c(t[e]?.length??0);n++){const o=t[e][n];if(null!==o)for(const i of qG){const r=t[e+i.y]?.[n+i.x];null!=r\u0026\u0026this.connect(o,r)}}}connectBoundaries(t,e,n,o){const i=\"left\"===t?o.minX:\"right\"===t?o.maxX:\"bottom\"===t?o.minY:o.maxY,r=\"left\"===t||\"right\"===t,s=t=\u003eMath.abs((r?t.x:t.y)-i)\u003c=1e-8,a=t=\u003e{const e=new Set;for(const n of t)for(const t of n)null!==t\u0026\u0026s(this.nodes[t].point)\u0026\u0026e.add(t);return[...e].sort((t,e)=\u003e{const n=this.nodes[t].point,o=this.nodes[e].point;return(r?n.y-o.y:n.x-o.x)||t-e})},c=a(e),l=a(n);if(0===c.length||0===l.length)throw new Error(`PostProcessingSolver: composite grid has no ${t} boundary bridge candidates`);for(const t of c)this.connect(t,this.findNearestAlongBoundary(t,l,r));for(const t of l)this.connect(t,this.findNearestAlongBoundary(t,c,r))}findNearestAlongBoundary(t,e,n){const o=this.nodes[t].point;let i=e[0],r=Number.POSITIVE_INFINITY;for(const t of e){const e=this.nodes[t].point,s=Math.abs(n?o.y-e.y:o.x-e.x);(s\u003cr-1e-8||Math.abs(s-r)\u003c=1e-8\u0026\u0026t\u003ci)\u0026\u0026(r=s,i=t)}return i}connectEndpoint(t,e){const n=this.nodeIdByPoint.get(this.keyFor(t)),o=void 0===n?null:this.nodes[n].point,i=o?.x===t.x\u0026\u0026o.y===t.y?n:this.nodes.push({point:{x:t.x,y:t.y},neighborIds:new Set})-1;this.endpointNodeIdByPoint.set(this.exactKeyFor(t),i);const r=(t,n)=\u003e{const o=this.nodes[t].point,i=e.filter(e=\u003ee!==t).map(t=\u003e({nodeId:t,distance:Math.hypot(this.nodes[t].point.x-o.x,this.nodes[t].point.y-o.y)})).filter(({distance:t})=\u003et\u003e1e-10).sort((t,e)=\u003et.distance-e.distance||t.nodeId-e.nodeId).slice(0,n);if(0===i.length)throw new Error(\"PostProcessingSolver: composite grid has no endpoint connection candidates\");for(const{nodeId:e}of i)this.connect(t,e)};r(i,8);for(const e of qG){const n={x:t.x+e.x*this.input.grid.innerGridStep,y:t.y+e.y*this.input.grid.innerGridStep};if(n.x\u003cthis.input.bounds.minX||n.x\u003ethis.input.bounds.maxX||n.y\u003cthis.input.bounds.minY||n.y\u003ethis.input.bounds.maxY)continue;const o=this.addNode(n);this.connect(i,o),r(o,4)}}addNode(t){const e=this.keyFor(t),n=this.nodeIdByPoint.get(e);if(void 0!==n)return n;const o=this.nodes.length;return this.nodes.push({point:{x:t.x,y:t.y},neighborIds:new Set}),this.nodeIdByPoint.set(e,o),o}connect(t,e){if(t===e)return;const n=this.nodes[t],o=this.nodes[e];n.neighborIds.add(e),o.neighborIds.add(t)}keyFor(t){const e=Object.is(t.x,-0)?0:t.x,n=Object.is(t.y,-0)?0:t.y;return`${e.toFixed(12)}:${n.toFixed(12)}`}exactKeyFor(t){return`${Object.is(t.x,-0)?0:t.x}:${Object.is(t.y,-0)?0:t.y}`}},KG=class{constructor(t){if(this.input=t,this.startLayer=EG(t.start.layer,t.layerCount),this.endLayer=EG(t.end.layer,t.layerCount),this.grid=new JG(t),this.maxSearchStates=this.grid.getSearchStateCountUpperBound(t.layerCount),this.exploredStateLimit=Math.min(this.maxSearchStates,2e4),this.startLayer\u003c0||this.endLayer\u003c0)return this.queue=[],void(this.status=\"exhausted\");const e={point:t.start,direction:null,cost:0,estimate:this.estimate(t.start),parent:null,sequence:0};this.queue=[e],this.bestCosts.set(this.keyFor(t.start,null),0)}input;queue;bestCosts=new Map;startLayer;endLayer;grid;maxSearchStates;exploredStateLimit;current=null;result=null;status=\"searching\";explored=0;nextSequence=1;isComplete(){return\"searching\"!==this.status}getPath(){return this.result}getPreviewPath(){return this.current?this.createPath(this.current):[this.input.start]}getExploredCount(){return this.explored}getProgress(){return\"searching\"!==this.status?1:Math.min(.99,this.explored/this.exploredStateLimit)}getGridNodeCount(){return this.grid.getNodeCount()}step(){if(\"searching\"!==this.status)return;const t=this.popQueue();if(!t)return void(this.status=\"exhausted\");const e=this.bestCosts.get(this.keyFor(t.point,t.direction));if(void 0===e)throw new Error(\"PostProcessingSolver: coupled path queue contains an untracked state\");if(t.cost\u003ee+1e-10)0===this.queue.length\u0026\u0026(this.status=\"exhausted\");else{if(this.current=t,this.explored++,this.explored\u003ethis.maxSearchStates)throw new Error(`PostProcessingSolver: coupled path search exceeded its ${this.maxSearchStates}-state graph invariant limit`);if(this.isEnd(t.point)){const e=this.createPath(t);return e[e.length-1]=this.input.end,this.result=this.simplifyPath(e),void(this.status=\"found\")}this.explored\u003e=this.exploredStateLimit?this.status=\"exhausted\":(this.enqueuePlanarNeighbors(t),this.enqueueViaNeighbors(t),0===this.queue.length\u0026\u0026(this.status=\"exhausted\"))}}isEnd(t){return t.layer===this.input.end.layer\u0026\u0026t.x===this.input.end.x\u0026\u0026t.y===this.input.end.y}estimate(t){return Math.hypot(t.x-this.input.end.x,t.y-this.input.end.y)+3*Math.abs(EG(t.layer,this.input.layerCount)-this.endLayer)}keyFor(t,e){return`${Object.is(t.x,-0)?0:t.x}:${Object.is(t.y,-0)?0:t.y}:${t.layer}:${e?.key??\"start\"}`}createDirection(t,e){const n=e.x-t.x,o=e.y-t.y,i=Math.hypot(n,o);if(i\u003c=1e-10)throw new Error(\"PostProcessingSolver: composite grid produced a zero-length planar edge\");const r=n/i,s=o/i;return{x:r,y:s,key:`${r.toFixed(6)}:${s.toFixed(6)}`}}createPath(t){const e=[];let n=t;for(;n;)e.push(n.point),n=n.parent;return e.reverse()}simplifyPath(t){return t.filter((e,n)=\u003e{if(0===n||n===t.length-1)return!0;const o=t[n-1],i=t[n+1],r={x:e.x-o.x,y:e.y-o.y},s={x:i.x-e.x,y:i.y-e.y},a=r.x*s.y-r.y*s.x,c=Math.hypot(r.x,r.y)*Math.hypot(s.x,s.y);return Math.abs(a)\u003e1e-10*c||e.layer!==o.layer||e.layer!==i.layer})}hasHigherQueuePriority(t,e){return t.estimate!==e.estimate?t.estimate\u003ce.estimate:t.cost!==e.cost?t.cost\u003ce.cost:t.point.x!==e.point.x?t.point.x\u003ce.point.x:t.point.y!==e.point.y?t.point.y\u003ce.point.y:t.point.layer!==e.point.layer?t.point.layer\u003ce.point.layer:t.sequence\u003ce.sequence}pushQueue(t){this.queue.push(t);let e=this.queue.length-1;for(;e\u003e0;){const n=Math.floor((e-1)/2),o=this.queue[n];if(!this.hasHigherQueuePriority(t,o))break;this.queue[e]=o,e=n}this.queue[e]=t}popQueue(){const t=this.queue[0],e=this.queue.pop();if(!t||!e||0===this.queue.length)return t;let n=0;for(;;){const t=2*n+1;if(t\u003e=this.queue.length)break;const o=t+1;let i=t;o\u003cthis.queue.length\u0026\u0026this.hasHigherQueuePriority(this.queue[o],this.queue[t])\u0026\u0026(i=o);const r=this.queue[i];if(!this.hasHigherQueuePriority(r,e))break;this.queue[n]=r,n=i}return this.queue[n]=e,t}enqueuePlanarNeighbors(t){for(const e of this.grid.getPlanarNeighbors(t.point)){if(!this.input.isEdgeValid(t.point,e))continue;const n=this.createDirection(t.point,e),o=null===t.direction||t.direction.key===n.key?0:.18,i=t.cost+Math.hypot(e.x-t.point.x,e.y-t.point.y)+o,r=this.keyFor(e,n);(this.bestCosts.get(r)??Number.POSITIVE_INFINITY)\u003c=i||(this.bestCosts.set(r,i),this.pushQueue({point:e,direction:n,cost:i,estimate:i+this.estimate(e),parent:t,sequence:this.nextSequence++}))}}enqueueViaNeighbors(t){if(!t.direction)return;const e=EG(t.point.layer,this.input.layerCount);for(const n of[e-1,e+1]){if(n\u003c0||n\u003e=this.input.layerCount)continue;const e=AG(n,this.input.layerCount);if(!this.input.isViaValid(t.point,e,t.direction))continue;const o={...t.point,layer:e},i=t.cost+4,r=this.keyFor(o,t.direction);(this.bestCosts.get(r)??Number.POSITIVE_INFINITY)\u003c=i||(this.bestCosts.set(r,i),this.pushQueue({point:o,direction:t.direction,cost:i,estimate:i+this.estimate(o),parent:t,sequence:this.nextSequence++}))}}},QG=t=\u003e{const e=Math.min(t.bounds.maxX-t.bounds.minX,t.bounds.maxY-t.bounds.minY),n=t.config?.innerGridStep??t.defaultInnerGridStep,o=t.config?.outerGridStep??4*n,i=t.config?.outerPerimeterWidth??Math.min(o,e/4);if(!Number.isFinite(n)||n\u003c1e-4)throw new Error(\"PostProcessingSolver: routingGrid.innerGridStep must be finite and at least 0.0001\");if(!Number.isFinite(o)||o\u003c=n)throw new Error(\"PostProcessingSolver: routingGrid.outerGridStep must be finite and greater than innerGridStep\");if(!Number.isFinite(i)||i\u003c=0||2*i\u003e=e)throw new Error(\"PostProcessingSolver: routingGrid.outerPerimeterWidth must be finite, positive, and less than half the smaller board extent\");const r=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY;if((Math.ceil(r/o)+4)*(Math.ceil(s/o)+4)+(Math.ceil((r-2*i)/n)+2)*(Math.ceil((s-2*i)/n)+2)+18\u003e25e4)throw new VG(\"PostProcessingSolver: valid input exceeds the 250000-node optimization grid capacity\");return{innerGridStep:n,outerGridStep:o,outerPerimeterWidth:i}},tU=t=\u003e{const e=-t.pathDirection.y,n=t.pathDirection.x,o=Math.tan(t.maximumTurnDegrees*Math.PI/180),i=Math.max(0,...t.lanes.map(({point:i,polarity:r})=\u003e{const s=i.x-t.anchor.x,a=i.y-t.anchor.y,c=s*t.escapeDirection.x+a*t.escapeDirection.y,l=s*e+a*n,d=r*t.side*t.centerlineSpacing/2;return c+Math.abs(l-d)/o})),r=t.maxUncoupledLength??i;if(i\u003er+1e-8)return null;const s=Math.max(.05,Math.min(.25,t.searchStep/2)),a=Math.max(1,Math.ceil((r-i)/s)+1);for(let o=0;o\u003ca;o++){const a=Math.min(r,i+o*s),c={x:t.anchor.x+t.escapeDirection.x*a,y:t.anchor.y+t.escapeDirection.y*a,layer:t.anchor.layer};if(t.lanes.every(({point:o,polarity:i})=\u003e{const r=i*t.side*t.centerlineSpacing/2,s=c.x+e*r,a=c.y+n*r;return void 0===t.maxUncoupledLength||Math.hypot(s-o.x,a-o.y)\u003c=t.maxUncoupledLength+1e-8})\u0026\u0026t.isValid(c))return c}return null},eU=[.75,.5,1,.25,1.25],nU=100,oU=class{constructor(t){this.input=t,this.pairName=t.pair.connectionNames.join(\"/\"),this.prepared=this.prepare()}input;pairName;prepared;candidates=[];result=null;search=null;nextAttempt=0;exploredNodeCount=0;isComplete(){return null!==this.result}getResult(){if(!this.result)throw new Error(`PostProcessingSolver: differential pair ${this.pairName} is not complete`);return this.result}getPreviewPath(){return this.search?.getPreviewPath()??null}getProgress(){if(this.result)return 1;const t=this.prepared.attempts.length,e=this.search?.getProgress()??0;return Math.min(.99,(this.nextAttempt+e)/t)}getStats(){return{phase:this.search?\"searching\":\"candidate-selection\",pair:this.pairName,attemptIndex:this.nextAttempt,attemptCount:this.prepared.attempts.length,exploredNodeCount:this.exploredNodeCount+(this.search?.getExploredCount()??0),gridNodeCount:this.search?.getGridNodeCount()??0,acceptedCandidateCount:this.candidates.length}}step(){if(this.result)return;const t=this.prepared;if(!this.search){const e=t.attempts[this.nextAttempt];return e?void(this.search=new KG(e.input)):void this.complete()}if(this.search.step(),!this.search.isComplete())return;const e=this.search.getPath();this.exploredNodeCount+=this.search.getExploredCount();const n=t.attempts[this.nextAttempt];if(!n)throw new Error(`PostProcessingSolver: differential pair ${this.pairName} lost its active attempt`);if(this.search=null,this.nextAttempt++,!e)return;const o=(t=\u003e{const e=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y)\u003c=1e-8;if(t.path.length\u003c2)throw new Error(\"PostProcessingSolver: coupled path has fewer than two stations\");const n=(n,o)=\u003e{for(let i=n+o;i\u003e=0\u0026\u0026i\u003ct.path.length;i+=o){const o=t.path[i];if(!e(o,t.path[n]))return o}return null},o=e=\u003e{const o=t.path[e],i=n(e,-1),r=n(e,1),s=(t,e)=\u003e{const n=e.x-t.x,o=e.y-t.y,i=Math.hypot(n,o);if(i\u003c=1e-10)throw new Error(\"PostProcessingSolver: cannot offset a zero-length spine\");return{x:-o/i,y:n/i}},a=t.side*t.centerlineSpacing/2;if(!i||!r){const t=s(i??o,r??o);return{x:t.x*a,y:t.y*a}}if(t.terminalFanout\u0026\u00261===e)return s(i,o);if(t.terminalFanout\u0026\u0026e===t.path.length-2)return s(o,r);if(t.terminalFanout\u0026\u0026t.path[e+1]?.layer!==o.layer)return s(i,o);const c=s(i,o),l=s(o,r),d={x:c.x+l.x,y:c.y+l.y},h=Math.hypot(d.x,d.y);if(h\u003c=1e-10)return null;const u=d.x/h,p=d.y/h,m=a/(u*c.x+p*c.y);return{x:u*m,y:p*m}},i=t.first.points[0],r=t.first.points.at(-1),s=t.reverseSecond?t.second.points.at(-1):t.second.points[0],a=t.reverseSecond?t.second.points[0]:t.second.points.at(-1),c=[[{route_type:\"wire\",x:i.x,y:i.y,width:i.width,layer:i.layer}],[{route_type:\"wire\",x:s.x,y:s.y,width:s.width,layer:s.layer}]],l=[t.first.transitions[0],t.second.transitions[0]];let d=0;const h=t.terminalFanout?1:0,u=t.path.length-2,p=t.path[u],m=t.path[u-1],g=t.terminalFanout\u0026\u0026p?.layer===r.layer\u0026\u0026m?.layer===p.layer,f=t.terminalFanout?g?u-1:t.path.length-1:t.path.length;for(let n=h;n\u003cf;n++){const i=t.path[n],r=o(n);if(!r)return null;for(const o of[0,1]){const s=0===o?1:-1,a={x:i.x+r.x*s,y:i.y+r.y*s},d=c[o],h=t.path[n-1];if(h\u0026\u0026h.layer!==i.layer){if(!e(h,i))throw new Error(\"PostProcessingSolver: a coupled layer transition moved in the plane\");const n=[...d].reverse().find(t=\u003e\"wire\"===t.route_type);if(!n)throw new Error(\"PostProcessingSolver: generated via has no preceding wire\");const r=l[o];d.push({route_type:\"via\",x:n.x,y:n.y,from_layer:h.layer,to_layer:i.layer,via_diameter:r?.via_diameter??(0===o?t.first.viaDiameter:t.second.viaDiameter),...void 0!==r?.via_hole_diameter?{via_hole_diameter:r.via_hole_diameter}:{}}),d.push({route_type:\"wire\",x:n.x,y:n.y,width:0===o?t.first.width:t.second.width,layer:i.layer})}else{const n=d.at(-1);\"wire\"===n?.route_type\u0026\u0026e(n,a)\u0026\u0026n.layer===i.layer||d.push({route_type:\"wire\",...a,width:0===o?t.first.width:t.second.width,layer:i.layer})}}t.path[n-1]?.layer!==i.layer\u0026\u0026n\u003e0\u0026\u0026d++}const y=(e,n)=\u003e{const o=e.at(-1);if(!o||\"wire\"!==o.route_type)throw new Error(\"PostProcessingSolver: terminal fanout has no preceding wire\");const i=e.at(-2);let r=!1;if(\"wire\"===i?.route_type\u0026\u0026i.layer===o.layer\u0026\u0026o.layer===n.layer){const t={x:o.x-i.x,y:o.y-i.y},e={x:n.x-o.x,y:n.y-o.y},s=Math.hypot(t.x,t.y),a=Math.hypot(e.x,e.y);if(s\u003e1e-8\u0026\u0026a\u003e1e-8\u0026\u0026Math.abs(t.x*e.x+t.y*e.y)\u003c=1e-8){const e={x:o.x-t.x/s*a,y:o.y-t.y/s*a};(e.x-i.x)*(t.x/s)+(e.y-i.y)*(t.y/s)\u003e1e-8\u0026\u0026(o.x=e.x,o.y=e.y,r=!0)}}t.terminalFanout\u0026\u0026!r\u0026\u0026o.x!==n.x\u0026\u0026o.y!==n.y\u0026\u0026e.push({route_type:\"wire\",x:n.x,y:o.y,width:n.width,layer:n.layer}),e.push({route_type:\"wire\",x:n.x,y:n.y,width:n.width,layer:n.layer})};y(c[0],r),y(c[1],a),t.reverseSecond\u0026\u0026(c[1]=c[1].reverse().map(t=\u003e\"via\"===t.route_type?{...t,from_layer:t.to_layer,to_layer:t.from_layer}:t));const _=(t,e)=\u003e{const n=t.filter(t=\u003e\"wire\"===t.route_type);for(const t of n)delete t.start_pcb_port_id,delete t.end_pcb_port_id;e.startPortId\u0026\u0026(n[0].start_pcb_port_id=e.startPortId),e.endPortId\u0026\u0026(n.at(-1).end_pcb_port_id=e.endPortId)};_(c[0],t.first),_(c[1],t.second);const b={...t.first.source,route:c[0]},x={...t.second.source,route:c[1]};return{first:b,second:x,firstParsed:LG(b,t.layerCount),secondParsed:LG(x,t.layerCount),edgeGap:t.edgeGap,centerlineDistance:t.centerlineSpacing,bendCount:Math.max(0,t.path.length-d-2),viaPairCount:d}})({first:t.first,second:t.second,reverseSecond:t.reverseSecond,path:e,centerlineSpacing:n.edgeGap+t.first.width/2+t.second.width/2,edgeGap:n.edgeGap,side:n.side,layerCount:this.input.layerCount,terminalFanout:t.terminalFanout});o\u0026\u0026ZG(o.firstParsed,o.secondParsed,t.context)\u0026\u0026this.candidates.push(o)}prepare(){const t=this.input.traces.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:t})=\u003et.connection_name===this.input.pair.connectionNames[0]),e=this.input.traces.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:t})=\u003et.connection_name===this.input.pair.connectionNames[1]);if(1!==t.length||1!==e.length)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"trace-resolution-failure\",message:\"must resolve each connection_name to exactly one non-branching trace\"});if(t[0].index===e[0].index)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"trace-resolution-failure\",message:\"resolved both members to one trace\"});let n,o;try{n=LG(t[0].trace,this.input.layerCount),o=LG(e[0].trace,this.input.layerCount)}catch(t){throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"invalid-routed-geometry\",message:`has unsupported or invalid routed geometry: ${t instanceof Error?t.message:String(t)}`})}const i=n.points[0],r=n.points.at(-1),s=Math.hypot(i.x-o.points[0].x,i.y-o.points[0].y)+Math.hypot(r.x-o.points.at(-1).x,r.y-o.points.at(-1).y),a=Math.hypot(i.x-o.points.at(-1).x,i.y-o.points.at(-1).y)+Math.hypot(r.x-o.points[0].x,r.y-o.points[0].y)+1e-8\u003cs,c=a?o.points.at(-1):o.points[0],l=a?o.points[0]:o.points.at(-1);if(i.layer!==c.layer||r.layer!==l.layer)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"terminal-layer-mismatch\",message:\"does not have common paired layers at both terminal stations\"});const d={x:(i.x+c.x)/2,y:(i.y+c.y)/2,layer:i.layer},h={x:(r.x+l.x)/2,y:(r.y+l.y)/2,layer:r.layer},u=Math.hypot(h.x-d.x,h.y-d.y);if(u\u003c1e-6)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"coincident-terminal-midpoints\",message:\"has coincident terminal-pair midpoints\"});const p={x:-(h.y-d.y)/u,y:(h.x-d.x)/u},m=i.x-c.x,g=i.y-c.y,f=m*p.x+g*p.y\u003e=0?1:-1,y=(t,e)=\u003e{const n=t.x-e.x,o=t.y-e.y,i=Math.hypot(n,o);return i\u003e1e-8\u0026\u0026Math.abs(n*p.x+o*p.y)/i\u003c.5},_=y(i,c)\u0026\u0026y(r,l),b={x:p.y,y:-p.x},x=[i,c].some(t=\u003e(t.x-d.x)*b.x+(t.y-d.y)*b.y\u003e1e-8),v={immutableTraces:this.input.traces.filter((n,o)=\u003eo!==t[0].index\u0026\u0026o!==e[0].index),obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,minTraceToPadEdgeClearance:this.input.minTraceToPadEdgeClearance},S=(t=\u003e{const{minimumCenterlineDistance:e,maximumCenterlineDistance:n}=t;if(void 0===e\u0026\u0026void 0===n)return t.legacyCenterlineDistances;const o=[...void 0!==e\u0026\u0026void 0!==n?[(e+n)/2,e,n,e-.25,n+.25]:void 0!==e?[e,e+.25,e+.5,e-.25,e+1]:[n,n-.25,n-.5,n+.25,n-1],...t.legacyCenterlineDistances];return o.filter((e,n)=\u003ee\u003et.minimumPhysicalDistance\u0026\u0026o.findIndex(t=\u003eMath.abs(t-e)\u003c1e-8)===n)})({minimumCenterlineDistance:this.input.pair.minimumCenterlineDistance,maximumCenterlineDistance:this.input.pair.maximumCenterlineDistance,minimumPhysicalDistance:n.width/2+o.width/2,legacyCenterlineDistances:eU.map(t=\u003et+n.width/2+o.width/2)}).flatMap(t=\u003e{const e=t-n.width/2-o.width/2;return[f,1===f?-1:1].flatMap(s=\u003e{const a=QG({config:this.input.routingGrid,bounds:this.input.bounds,defaultInnerGridStep:Math.max(.25,Math.min(.5,t/2))}),u=(e,a)=\u003eUG({...v,start:e,end:a,firstConnectionName:n.source.connection_name,secondConnectionName:o.source.connection_name,firstStartTerminal:i,firstEndTerminal:r,secondStartTerminal:c,secondEndTerminal:l,firstWidth:n.width,secondWidth:o.width,firstViaDiameter:n.transitions[0]?.via_diameter??n.viaDiameter,secondViaDiameter:o.transitions[0]?.via_diameter??o.viaDiameter,centerlineSpacing:t,side:s,terminalFanout:_,terminalMiterMargin:void 0===this.input.pair.maxUncoupledLength?void 0:t/2});let m=void 0===this.input.pair.maxUncoupledLength?((t,e)=\u003e{if(!x||_)return d;const n=[{terminal:i,offset:e*t/2},{terminal:c,offset:-e*t/2}],o=Math.tan(55*Math.PI/180),r=Math.max(...n.map(({terminal:t,offset:e})=\u003e{const n=(t.x-d.x)*b.x+(t.y-d.y)*b.y,i=(t.x-d.x)*p.x+(t.y-d.y)*p.y;return n+Math.abs(i-e)/o}));return{x:d.x+b.x*r,y:d.y+b.y*r,layer:d.layer}})(t,s):d,g=h;if(!_\u0026\u0026void 0!==this.input.pair.maxUncoupledLength){const e=u(d,h),n=tU({anchor:d,escapeDirection:b,pathDirection:b,centerlineSpacing:t,side:s,lanes:[{point:i,polarity:1},{point:c,polarity:-1}],maxUncoupledLength:this.input.pair.maxUncoupledLength,maximumTurnDegrees:55,searchStep:a.innerGridStep,isValid:t=\u003ee.isTerminalFanoutValid(t,b,\"start\")}),o=tU({anchor:h,escapeDirection:{x:-b.x,y:-b.y},pathDirection:b,centerlineSpacing:t,side:s,lanes:[{point:r,polarity:1},{point:l,polarity:-1}],maxUncoupledLength:this.input.pair.maxUncoupledLength,maximumTurnDegrees:45,searchStep:a.innerGridStep,isValid:t=\u003ee.isTerminalFanoutValid(t,b,\"end\")});if(!n||!o)return[];m=n,g=o;if((g.x-m.x)*b.x+(g.y-m.y)*b.y\u003c=a.innerGridStep)return[]}const f=u(m,g);return[{edgeGap:e,side:s,input:{start:m,end:g,bounds:this.input.bounds,layerCount:this.input.layerCount,grid:a,...f}}]})});return{first:n,second:o,reverseSecond:a,terminalFanout:_,context:v,attempts:S}}complete(){if(0===this.candidates.length)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"no-valid-candidate\",message:\"could not be improved without violating bounds, copper clearance, or coupled-via constraints\"});this.candidates.sort((t,e)=\u003ethis.score(t)-this.score(e)||t.edgeGap-e.edgeGap),this.result={status:\"accepted\",candidate:this.candidates[0]}}score(t){return(void 0!==this.input.pair.minimumCenterlineDistance||void 0!==this.input.pair.maximumCenterlineDistance?Math.max(0,(this.input.pair.minimumCenterlineDistance??Number.NEGATIVE_INFINITY)-t.centerlineDistance)*nU+Math.max(0,t.centerlineDistance-(this.input.pair.maximumCenterlineDistance??Number.POSITIVE_INFINITY))*nU:t.edgeGap\u003c.5?(.5-t.edgeGap)*nU:t.edgeGap\u003e1?(t.edgeGap-1)*nU:0)+FG(t.firstParsed)+FG(t.secondParsed)+.15*t.bendCount+8*t.viaPairCount}},iU=t=\u003e{const e={lines:[],points:[],rects:[],circles:[]};e.rects.push({center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,fill:\"rgba(30, 70, 120, 0.04)\",stroke:\"rgba(30, 70, 120, 0.55)\",layer:`z${Array.from({length:t.layerCount},(t,e)=\u003ee).join(\",\")}`});for(const n of t.obstacles){const o=uG(n,t.layerCount);e.rects.push({center:n.center,width:n.width,height:n.height,ccwRotationDegrees:n.ccwRotationDegrees,fill:\"rgba(220, 60, 60, 0.16)\",stroke:\"rgba(190, 40, 40, 0.75)\",layer:`z${o.join(\",\")}`})}for(let n=0;n\u003c(t.previewPath?.length??0)-1;n++){const o=t.previewPath[n],i=t.previewPath[n+1];if(o.layer!==i.layer)continue;const r=EG(o.layer,t.layerCount);e.lines.push({points:[o,i],strokeColor:\"#16a34a\",strokeWidth:.08,strokeDash:[.18,.12],layer:`z${r}`})}for(const n of t.traces){if(t.activeConnectionNames?.includes(n.connection_name))continue;const o=\"#2563eb\";let i=null;for(const r of n.route)if(\"wire\"===r.route_type){if(i\u0026\u0026i.layer===r.layer){const n=EG(r.layer,t.layerCount);e.lines.push({points:[i,r],strokeColor:o,strokeWidth:Math.max(i.width,r.width),...0===n?{}:{strokeDash:[.2,.16]},layer:`z${n}`})}i=r}else if(\"via\"===r.route_type){const n=OG(r.from_layer,r.to_layer,t.layerCount).map(e=\u003eEG(e,t.layerCount));if(e.circles.push({center:r,radius:(r.via_diameter??i?.width??.2)/2,fill:\"rgba(37, 99, 235, 0.45)\",stroke:o,layer:`z${n.join(\",\")}`}),i){const t=i.width;i={x:r.x,y:r.y,layer:r.to_layer,width:t}}}}return e},rU=class extends kt{constructor(t){super(),this.params=t,this.outputTraces=HG(t.simpleRouteJson.traces),this.MAX_ITERATIONS=WG(t)}params;outputTraces;reroutedPairs=[];failures=[];nextPairIndex=0;activeConnectionNames=null;activeSession=null;getSolverName(){return\"DifferentialPairReroutingSolver\"}_step(){const t=this.params.simpleRouteJson.differentialPairs[this.nextPairIndex];if(!t)return void this.finish();this.activeConnectionNames=t.connectionNames;try{if(!this.activeSession)return this.activeSession=new oU({pair:t,traces:this.outputTraces,obstacles:this.params.simpleRouteJson.obstacles,bounds:this.params.simpleRouteJson.bounds,layerCount:this.params.simpleRouteJson.layerCount,minTraceToPadEdgeClearance:this.params.simpleRouteJson.minTraceToPadEdgeClearance,routingGrid:this.params.routingGrid}),void(this.stats=this.activeSession.getStats());this.activeSession.step()}catch(e){if(!(e instanceof YG))throw e;return void this.skipFailedPair(t,e)}if(this.stats=this.activeSession.getStats(),!this.activeSession.isComplete())return;const e=this.activeSession.getResult();this.activeSession=null;for(const t of[e.candidate.first,e.candidate.second]){const e=this.outputTraces.findIndex(e=\u003ee.connection_name===t.connection_name);if(e\u003c0)throw new Error(`DifferentialPairReroutingSolver: accepted replacement for unknown connection \"${t.connection_name}\"`);this.outputTraces[e]=t}this.reroutedPairs.push(t),this.nextPairIndex++,this.nextPairIndex!==this.params.simpleRouteJson.differentialPairs.length?this.stats={phase:\"accepted\",pair:t.connectionNames.join(\"/\"),pairIndex:this.nextPairIndex-1,pairCount:this.params.simpleRouteJson.differentialPairs.length}:this.finish()}finish(){this.activeConnectionNames=null,this.solved=!0,this.stats={phase:\"complete\",acceptedPairCount:this.reroutedPairs.length,skippedPairCount:this.failures.length}}skipFailedPair(t,e){this.failures.push({connectionNames:[...t.connectionNames],reason:e.reason,message:e.message}),this.activeSession=null,this.nextPairIndex++,this.nextPairIndex!==this.params.simpleRouteJson.differentialPairs.length?this.stats={phase:\"skipped\",pair:t.connectionNames.join(\"/\"),pairIndex:this.nextPairIndex-1,pairCount:this.params.simpleRouteJson.differentialPairs.length,skippedPairCount:this.failures.length}:this.finish()}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved)throw new Error(\"DifferentialPairReroutingSolver: getOutput() called before completion\");return this.getBestEffortOutput()}getBestEffortOutput(){return{traces:HG(this.outputTraces),reroutedPairs:this.reroutedPairs.map(t=\u003e({...t,connectionNames:[...t.connectionNames]})),failures:this.failures.map(t=\u003e({...t,connectionNames:[...t.connectionNames]}))}}computeProgress(){return this.solved?1:0===this.params.simpleRouteJson.differentialPairs.length?0:(this.nextPairIndex+(this.activeSession?.getProgress()??0))/this.params.simpleRouteJson.differentialPairs.length}visualize(){return iU({traces:this.outputTraces,obstacles:this.params.simpleRouteJson.obstacles,bounds:this.params.simpleRouteJson.bounds,layerCount:this.params.simpleRouteJson.layerCount,activeConnectionNames:this.activeConnectionNames,previewPath:this.activeSession?.getPreviewPath()??null})}},sU=1e-8,aU=class extends kt{constructor(t){super(),this.input=t,this.traces=HG(t.traces),this.MAX_ITERATIONS=Math.max(1,t.reroutedPairs.length+1)}input;traces;nextPairIndex=0;getSolverName(){return\"FortyFiveDegreeSimplificationSolver\"}_step(){const t=this.input.reroutedPairs[this.nextPairIndex];if(!t)return this.solved=!0,void(this.stats={phase:\"complete\",simplifiedPairCount:this.nextPairIndex});this.traces=(t=\u003e{const e=t.pair.connectionNames.join(\"/\"),n=t.pair.connectionNames.map(e=\u003et.traces.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:t})=\u003et.connection_name===e));if(1!==n[0].length||1!==n[1].length)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} must resolve to exactly two traces`);const o=n[0][0].index,i=n[1][0].index;if(o===i)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} resolved both members to one trace`);const r=structuredClone(t.traces),s={immutableTraces:r.filter((t,e)=\u003ee!==o\u0026\u0026e!==i),obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,minTraceToPadEdgeClearance:t.minTraceToPadEdgeClearance},a=n=\u003e{const r=LG(n[o],t.layerCount),s=LG(n[i],t.layerCount);let a=0;for(const[t,n]of[[r.segments,s.segments],[s.segments,r.segments]])for(const o of t){if(null!==o.terminal)continue;const t=n.filter(t=\u003et.layer===o.layer);if(0===t.length)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} lost common-layer interior copper`);a=Math.max(a,Math.min(...t.map(t=\u003ecG(o.start,o.end,t.start,t.end))))}return a},c=e=\u003e{const n=LG(e[o],t.layerCount),r=LG(e[i],t.layerCount);let s=Number.POSITIVE_INFINITY;for(const[t,e]of[[n.segments,r.segments],[r.segments,n.segments]])for(const n of t)if(null===n.terminal)for(const t of e)t.layer===n.layer\u0026\u0026(s=Math.min(s,cG(n.start,n.end,t.start,t.end)-n.width/2-t.width/2));return Number.isFinite(s)?s:null},l=e=\u003e{const n=LG(e[o],t.layerCount),r=LG(e[i],t.layerCount);return ZG(n,r,s)};if(!l(r))throw new Error(`FortyFiveDegreeSimplificationSolver: rerouted pair ${e} has invalid complete copper before simplification`);if(void 0!==t.pair.maxUncoupledLength\u0026\u0026void 0!==t.pair.minimumCenterlineDistance\u0026\u0026void 0!==t.pair.maximumCenterlineDistance\u0026\u0026Math.abs(t.pair.minimumCenterlineDistance-t.pair.maximumCenterlineDistance)\u003c=sU)return r;const d=LG(r[o],t.layerCount),h=LG(r[i],t.layerCount),u=Math.abs(FG(d)-FG(h)),p=c(r),m=t.pair.maximumCenterlineDistance??1+d.width/2+h.width/2,g=Math.min(a(r),m),f=t=\u003e{if(!l(t))return!1;if(a(t)\u003eg+sU)return!1;const e=c(t);return null===p||null===e||e\u003e=p-sU},y=(t,e)=\u003e{const n=Math.abs(e.x-t.x),o=Math.abs(e.y-t.y),i=e.x\u003e=t.x?1:-1,r=e.y\u003e=t.y?1:-1,s=[],a={x:e.x-i*o,y:t.y};(a.x-t.x)*i\u003e=-1e-8\u0026\u0026(a.x-e.x)*i\u003c=sU\u0026\u0026s.push([t,a,e]);const c={x:t.x,y:e.y-r*n};(c.y-t.y)*r\u003e=-1e-8\u0026\u0026(c.y-e.y)*r\u003c=sU\u0026\u0026s.push([t,c,e]);const l={x:t.x+i*Math.min(n,o),y:t.y+r*Math.min(n,o)};return s.push([t,l,e]),s.map((t,e)=\u003e{const n=t.filter((e,n)=\u003e0===n||Math.hypot(e.x-t[n-1].x,e.y-t[n-1].y)\u003esU),o=n.slice(0,-1).map((t,e)=\u003e{const o=n[e+1],i=Math.abs(o.x-t.x),r=Math.abs(o.y-t.y);return{length:Math.hypot(i,r),straight:i\u003c=sU||r\u003c=sU?Math.hypot(i,r):0}});return{points:n,usableStraightLength:Math.max(0,...o.map(t=\u003et.straight)),bendCount:Math.max(0,n.length-2),priority:e}}).filter((t,e,n)=\u003en.findIndex(e=\u003eJSON.stringify(e.points)===JSON.stringify(t.points))===e).sort((t,e)=\u003ee.usableStraightLength-t.usableStraightLength||t.bendCount-e.bendCount||t.priority-e.priority)},_=t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n];if(\"wire\"===o?.route_type)for(let i=t.route.length-1;i\u003e=n+1;i--){if(0===n||i===t.route.length-1)continue;const r=t.route[i];\"wire\"===r?.route_type\u0026\u0026r.layer===o.layer\u0026\u0026(t.route.slice(n+1,i).some(t=\u003e\"wire\"!==t.route_type||t.layer!==o.layer)||e.push({startIndex:n,endIndex:i,skippedPointCount:i-n-1}))}}return e.sort((t,e)=\u003ee.skippedPointCount-t.skippedPointCount||t.startIndex-e.startIndex||e.endIndex-t.endIndex)},b=(t,e,n)=\u003e{const o=t.route[e.startIndex],i=t.route[e.endIndex],r=Math.max(o.width,i.width),s=n.points.slice(1,-1).map(t=\u003e({route_type:\"wire\",...t,width:r,layer:o.layer}));return{...t,route:[...t.route.slice(0,e.startIndex+1),...s,...t.route.slice(e.endIndex)]}};for(const t of[o,i]){let e=!0;for(;e;){e=!1;const n=r[t];for(const s of _(n)){const a=n.route[s.startIndex],c=n.route[s.endIndex],l=n.route.slice(s.startIndex,s.endIndex+1),d=l.slice(0,-1).every((t,e)=\u003e{const n=l[e+1],o=Math.abs(n.x-t.x),i=Math.abs(n.y-t.y);return o\u003c=sU||i\u003c=sU||Math.abs(o-i)\u003c=sU});for(const h of y(a,c)){if(h.points.length\u003e=l.length\u0026\u0026d)continue;const a=b(n,s,h),c=[...r];if(c[t]=a,JSON.stringify(a.route)===JSON.stringify(n.route))continue;if(f(c)){r[t]=a,e=!0;break}const u=t===o?i:o,p=r[u],m=_(p).find(t=\u003et.startIndex===s.startIndex\u0026\u0026t.endIndex===s.endIndex);if(!m)continue;const g=p.route[m.startIndex],x=p.route[m.endIndex];for(const n of y(g,x)){const o=b(p,m,n),i=[...c];if(i[u]=o,f(i)){r[t]=a,r[u]=o,e=!0;break}}if(e)break}if(e)break}}}if(!f(r))throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} produced invalid complete copper`);const x=LG(r[o],t.layerCount),v=LG(r[i],t.layerCount),S=Math.abs(FG(x)-FG(v));return Math.abs(S-u)\u003et.pair.lengthTolerance+sU?structuredClone(t.traces):r})({traces:this.traces,pair:t,obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,minTraceToPadEdgeClearance:this.input.minTraceToPadEdgeClearance}),this.nextPairIndex++,this.stats={phase:\"simplifying\",pair:t.connectionNames.join(\"/\"),pairIndex:this.nextPairIndex-1,pairCount:this.input.reroutedPairs.length}}getConstructorParams(){return[this.input]}getOutput(){if(!this.solved)throw new Error(\"FortyFiveDegreeSimplificationSolver: getOutput() called before completion\");return this.getBestEffortOutput()}getBestEffortOutput(){return{traces:HG(this.traces),reroutedPairs:this.input.reroutedPairs.map(t=\u003e({...t,connectionNames:[...t.connectionNames]}))}}computeProgress(){return this.solved?1:0===this.input.reroutedPairs.length?0:this.nextPairIndex/this.input.reroutedPairs.length}visualize(){return iU({traces:this.traces,obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,activeConnectionNames:this.input.reroutedPairs[this.nextPairIndex]?.connectionNames??null,previewPath:null})}},cU=class extends kt{constructor(t){super(),this.input=t}input;output=null;visualizationTraces=null;getSolverName(){return\"HdRouteReconstructionSolver\"}_step(){this.visualizationTraces=(t=\u003e{const{simpleRouteJson:e}=t.params;if(t.result.matchedHdRoutes.length!==t.binding.solverParams.hdRoutes.length)throw new Error(\"PostProcessingSolver: LengthMatchingSolver changed the search route count\");const n=structuredClone(t.binding.baseTraces);for(const o of t.binding.traceBindings){const i=t.result.matchedHdRoutes[o.matchedRouteIndex];if(!i)throw new Error(`PostProcessingSolver: missing matched route at index ${o.matchedRouteIndex}`);const r=n[o.traceIndex];if(!r)throw new Error(`PostProcessingSolver: missing simplified trace binding at index ${o.traceIndex}`);if(r.connection_name!==i.connectionName)throw new Error(`PostProcessingSolver: route binding changed connection \"${r.connection_name}\" to \"${i.connectionName}\"`);if(i.route.length\u003c2)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" has incomplete geometry`);const s=i.route[0],a=i.route.at(-1);if(Math.hypot(s.x-o.startEndpoint.x,s.y-o.startEndpoint.y)\u003e1e-8||s.z!==o.startEndpoint.z||Math.hypot(a.x-o.endEndpoint.x,a.y-o.endEndpoint.y)\u003e1e-8||a.z!==o.endEndpoint.z)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" moved a preserved endpoint`);const c=[];let l=0;const d=t=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:t.traceThickness??i.traceThickness,layer:AG(t.z,e.layerCount)});c.push(d(i.route[0]));for(let t=1;t\u003ci.route.length;t++){const n=i.route[t-1],r=i.route[t];if(n.z===r.z){c.push(d(r));continue}if(Math.hypot(n.x-r.x,n.y-r.y)\u003e1e-8)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" moves while changing layers`);const s=o.viaTemplates[l++];if(!s)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" added an unbound via`);if(Math.hypot(s.x-r.x,s.y-r.y)\u003e1e-8)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" moved a preserved via`);const a=AG(n.z,e.layerCount),h=AG(r.z,e.layerCount),u=new Set([s.from_layer,s.to_layer]);if(!u.has(a)||!u.has(h))throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" changed a preserved via span`);c.push({...s}),c.push(d(r))}if(l!==o.viaTemplates.length)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" removed a preserved via`);const h=c.filter(t=\u003e\"wire\"===t.route_type);for(const t of h)delete t.start_pcb_port_id,delete t.end_pcb_port_id;o.startPortId\u0026\u0026(h[0].start_pcb_port_id=o.startPortId),o.endPortId\u0026\u0026(h.at(-1).end_pcb_port_id=o.endPortId),n[o.traceIndex]={...r,route:c}}for(const o of t.binding.solverParams.differentialPairs){const t=o.connectionNames.join(\"/\"),i=o.connectionNames.map(t=\u003en.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:e})=\u003ee.connection_name===t));if(1!==i[0].length||1!==i[1].length)throw new Error(`PostProcessingSolver: reconstructed pair ${t} does not resolve to complete copper`);const r=i[0][0],s=i[1][0],a=LG(r.trace,e.layerCount),c=LG(s.trace,e.layerCount),l=Math.abs(FG(a)-FG(c));if(l\u003eo.lengthTolerance+1e-7)throw new XG({message:`PostProcessingSolver: reconstructed pair ${t} exceeds length tolerance ${o.lengthTolerance} with error ${l}`,connectionNames:[...o.connectionNames],reason:\"length-tolerance-unsatisfied\"});if(!ZG(a,c,{immutableTraces:n.filter((t,e)=\u003ee!==r.index\u0026\u0026e!==s.index),obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,minTraceToPadEdgeClearance:e.minTraceToPadEdgeClearance}))throw new XG({message:`PostProcessingSolver: length matching produced invalid complete copper for pair ${t}`,connectionNames:[...o.connectionNames],reason:\"invalid-final-copper\"})}return n})(this.input),this.output=$G({...this.input,rejectInsideJumperPad:!0}),this.stats={phase:\"complete\",routeCount:this.output.hdRoutes.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){if(!this.output||!this.solved)throw new Error(\"HdRouteReconstructionSolver: getOutput() called before completion\");return structuredClone(this.output)}visualize(){const t=this.visualizationTraces??this.input.simplified.traces,{obstacles:e,bounds:n,layerCount:o}=this.input.params.simpleRouteJson;return iU({traces:t,obstacles:e,bounds:n,layerCount:o,activeConnectionNames:null,previewPath:null})}};var lU=class extends Dt{differentialPairReroutingSolver;fortyFiveDegreeSimplificationSolver;lengthMatchingSolver;hdRouteReconstructionSolver;lengthMatchingBinding=null;model;fallbackOutput=null;postProcessingErrors=[];pipelineDef=[Lt(\"differentialPairReroutingSolver\",rU,t=\u003e[t.model.params]),Lt(\"fortyFiveDegreeSimplificationSolver\",aU,t=\u003e{const e=t.getStageOutput(\"differentialPairReroutingSolver\");if(!e)throw new Error(\"PostProcessingSolver: rerouting stage completed without output\");const{obstacles:n,bounds:o,layerCount:i,minTraceToPadEdgeClearance:r}=t.model.params.simpleRouteJson;return[{...e,obstacles:n,bounds:o,layerCount:i,minTraceToPadEdgeClearance:r}]}),Lt(\"lengthMatchingSolver\",RG,t=\u003e{const e=t.getStageOutput(\"fortyFiveDegreeSimplificationSolver\");if(!e)throw new Error(\"PostProcessingSolver: 45-degree simplification stage completed without output\");return t.lengthMatchingBinding=BG({result:e,params:t.model.params}),[t.lengthMatchingBinding.solverParams]}),Lt(\"hdRouteReconstructionSolver\",cU,t=\u003e{const e=t.getStageOutput(\"fortyFiveDegreeSimplificationSolver\"),n=t.getStageOutput(\"lengthMatchingSolver\");if(!e||!n||!t.lengthMatchingBinding)throw new Error(\"PostProcessingSolver: reconstruction stage is missing a required binding or output\");return[{binding:t.lengthMatchingBinding,result:n,simplified:e,params:t.model.params,model:t.model}]},{onSolved:t=\u003e{const e=t.getStageOutput(\"differentialPairReroutingSolver\");if(!e)throw new Error(\"PostProcessingSolver: cannot summarize missing rerouting output\");t.stats={phase:\"complete\",acceptedPairCount:e.reroutedPairs.length},e.failures.length\u003e0\u0026\u0026(t.stats.skippedPairCount=e.failures.length,t.stats.postProcessingErrorCount=e.failures.length)}})];constructor(t){super(structuredClone(t));let e=null;try{!function(t){if(!t||\"object\"!=typeof t)throw new Error(\"PostProcessingSolver: params must be an object\");if(!Array.isArray(t.hdRoutes))throw new Error(\"PostProcessingSolver: hdRoutes must be an array\");if(!Array.isArray(t.differentialPairs))throw new Error(\"PostProcessingSolver: differentialPairs must be an array\");if(!Array.isArray(t.obstacles))throw new Error(\"PostProcessingSolver: obstacles must be an array\");if(void 0!==t.minTraceToPadEdgeClearance\u0026\u0026(!Number.isFinite(t.minTraceToPadEdgeClearance)||t.minTraceToPadEdgeClearance\u003c0))throw new Error(\"PostProcessingSolver: minTraceToPadEdgeClearance must be finite and nonnegative\");if(!Number.isInteger(t.layerCount)||t.layerCount\u003c1)throw new Error(\"PostProcessingSolver: layerCount must be a positive integer\");for(const e of t.obstacles){if(!e||\"object\"!=typeof e||\"rect\"!==e.type||!e.center||!Number.isFinite(e.center.x)||!Number.isFinite(e.center.y)||!Number.isFinite(e.width)||e.width\u003c=0||!Number.isFinite(e.height)||e.height\u003c=0||!Array.isArray(e.layers)||e.layers.some(t=\u003e\"string\"!=typeof t)||!Array.isArray(e.connectedTo)||e.connectedTo.some(t=\u003e\"string\"!=typeof t||0===t.length)||void 0!==e.ccwRotationDegrees\u0026\u0026!Number.isFinite(e.ccwRotationDegrees))throw new Error(\"PostProcessingSolver: obstacle declaration is invalid\");uG(e,t.layerCount)}const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds??{};if(![e,n,o,i].every(Number.isFinite)||e\u003e=n||o\u003e=i)throw new Error(\"PostProcessingSolver: bounds must have finite positive extents\");const r=new Set(t.differentialPairs.flatMap(t=\u003et.connectionNames));for(const e of t.hdRoutes){if(!e||\"object\"!=typeof e||\"string\"!=typeof e.connectionName||0===e.connectionName.length||void 0!==e.rootConnectionName\u0026\u0026(\"string\"!=typeof e.rootConnectionName||0===e.rootConnectionName.length)||!Number.isFinite(e.traceThickness)||e.traceThickness\u003c=0||!Number.isFinite(e.viaDiameter)||e.viaDiameter\u003c0||0===e.viaDiameter\u0026\u0026r.has(e.connectionName)||!Array.isArray(e.route)||!Array.isArray(e.vias)||void 0!==e.jumpers\u0026\u0026!Array.isArray(e.jumpers))throw new Error(\"PostProcessingSolver: HD route declaration is invalid\");if(void 0!==e.startPcbPortId\u0026\u0026(\"string\"!=typeof e.startPcbPortId||0===e.startPcbPortId.length)||void 0!==e.endPcbPortId\u0026\u0026(\"string\"!=typeof e.endPcbPortId||0===e.endPcbPortId.length))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has invalid terminal metadata`);for(const n of e.route)if(!n||\"object\"!=typeof n||!Number.isFinite(n.x)||!Number.isFinite(n.y)||!Number.isInteger(n.z)||n.z\u003c0||n.z\u003e=t.layerCount||void 0!==n.traceThickness\u0026\u0026(!Number.isFinite(n.traceThickness)||n.traceThickness\u003c=0))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has an invalid route point`);for(const n of e.vias)if(!n||\"object\"!=typeof n||!Number.isFinite(n.x)||!Number.isFinite(n.y)||void 0!==n.zLayers\u0026\u0026(!Array.isArray(n.zLayers)||n.zLayers.some(e=\u003e!Number.isInteger(e)||e\u003c0||e\u003e=t.layerCount)))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has an invalid via`);if(e.vias.length\u003e0\u0026\u0026e.viaDiameter\u003c=0)throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has a non-positive via diameter`);for(const t of e.jumpers??[])if(!(t\u0026\u0026\"object\"==typeof t\u0026\u0026\"jumper\"===t.route_type\u0026\u0026Number.isFinite(t.start?.x)\u0026\u0026Number.isFinite(t.start?.y)\u0026\u0026Number.isFinite(t.end?.x)\u0026\u0026Number.isFinite(t.end?.y)\u0026\u0026[\"0603\",\"1206\",\"1206x4_pair\"].includes(t.footprint)))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has an invalid jumper`)}const s=new Set;for(const e of t.differentialPairs){if(!e||\"object\"!=typeof e||!Array.isArray(e.connectionNames)||2!==e.connectionNames.length||e.connectionNames[0]===e.connectionNames[1]||!e.connectionNames.every(t=\u003e\"string\"==typeof t\u0026\u0026t.length\u003e0)||!Number.isFinite(e.lengthTolerance)||e.lengthTolerance\u003c0)throw new Error(\"PostProcessingSolver: differential pair declaration is invalid\");for(const t of[e.minimumCenterlineDistance,e.maximumCenterlineDistance])if(void 0!==t\u0026\u0026(!Number.isFinite(t)||t\u003c=0))throw new Error(\"PostProcessingSolver: differential pair centerline distances must be positive finite numbers\");if(void 0!==e.maxUncoupledLength\u0026\u0026(!Number.isFinite(e.maxUncoupledLength)||e.maxUncoupledLength\u003c0))throw new Error(\"PostProcessingSolver: differential pair maxUncoupledLength must be a non-negative finite number\");if(void 0!==e.minimumCenterlineDistance\u0026\u0026void 0!==e.maximumCenterlineDistance\u0026\u0026e.minimumCenterlineDistance\u003ee.maximumCenterlineDistance)throw new Error(\"PostProcessingSolver: differential pair minimumCenterlineDistance cannot exceed maximumCenterlineDistance\");for(const t of e.connectionNames){if(s.has(t))throw new Error(`PostProcessingSolver: connection \"${t}\" belongs to multiple differential pairs`);s.add(t)}}for(const e of[.25,.5])QG({config:t.routingGrid,bounds:t.bounds,defaultInnerGridStep:e})}(t)}catch(t){if(!(t instanceof VG))throw t;e=t}if(this.model=jG(t),e)return void this.finishWithBestEffortOutput({stage:\"differentialPairReroutingSolver\",message:e.message,reason:e.reason});const n=WG(this.model.params)+Math.max(1,t.differentialPairs.length+1)+1e5+10;if(!Number.isSafeInteger(n))throw new Error(\"PostProcessingSolver: derived pipeline iteration bound exceeds the safe integer range\");this.MAX_ITERATIONS=n}getSolverName(){return\"PostProcessingSolver\"}getConstructorParams(){return[structuredClone(this.inputProblem)]}_step(){const t=this.getCurrentStageName();try{super._step()}catch(e){const n=this.classifyOptimizationFailure(e,t);if(!n)throw e;return void this.finishWithBestEffortOutput(n)}if(!this.failed)return;const e=this.classifyIterationFailure(this.error,t);if(!e)throw new Error(this.error??\"PostProcessingSolver failed without an error message\");this.finishWithBestEffortOutput(e)}tryFinalAcceptance(){const t=this.getCurrentStageName();\"differentialPairReroutingSolver\"!==t\u0026\u0026\"lengthMatchingSolver\"!==t||this.finishWithBestEffortOutput({stage:t,message:\"PostProcessingSolver reached its iteration limit\",reason:\"iteration-limit-exhausted\"})}classifyOptimizationFailure(t,e){return\"lengthMatchingSolver\"===e\u0026\u0026t instanceof IG?{stage:e,message:t.message,connectionName:t.connectionName,reason:t.reason}:\"hdRouteReconstructionSolver\"===e\u0026\u0026t instanceof XG||\"differentialPairReroutingSolver\"===e\u0026\u0026t instanceof YG\u0026\u0026\"no-valid-candidate\"===t.reason?{stage:e,message:t.message,connectionNames:[...t.connectionNames],reason:t.reason}:null}classifyIterationFailure(t,e){return\"differentialPairReroutingSolver\"!==e\u0026\u0026\"lengthMatchingSolver\"!==e?null:t\u0026\u0026t.endsWith(\"ran out of iterations\")?{stage:e,message:t,reason:\"iteration-limit-exhausted\"}:null}createBestEffortOutput(t){let e=this.lengthMatchingBinding;if(!e){const t=this.getStageOutput(\"fortyFiveDegreeSimplificationSolver\")??this.fortyFiveDegreeSimplificationSolver?.getBestEffortOutput(),n=this.getStageOutput(\"differentialPairReroutingSolver\")??this.differentialPairReroutingSolver?.getBestEffortOutput(),o=t??n;o\u0026\u0026(e=BG({result:o,params:this.model.params}))}if(!e)return{output:{hdRoutes:structuredClone(this.inputProblem.hdRoutes),postProcessingErrors:[]},source:\"input-hd-routes\"};let n=this.getStageOutput(\"lengthMatchingSolver\");return n||(n=this.lengthMatchingSolver?.getBestEffortOutput()),n\u0026\u0026\"invalid-final-copper\"!==t.reason||(n={matchedHdRoutes:e.solverParams.hdRoutes}),{output:$G({binding:e,result:n,model:this.model}),source:\"best-effort-hd-routes\"}}finishWithBestEffortOutput(t){const e=this.createBestEffortOutput(t),n={type:\"post_processing_error\",...t,returnedRouteSource:e.source};this.postProcessingErrors.push(n),this.fallbackOutput=e.output,this.activeSubSolver=null,this.error=null,this.failed=!1,this.solved=!0,this.progress=1,this.stats={phase:\"complete\",postProcessingErrorCount:this.postProcessingErrors.length}}getOutput(){if(!this.solved)throw new Error(\"PostProcessingSolver: getOutput() called before the solver completed\");const t=this.fallbackOutput??this.getStageOutput(\"hdRouteReconstructionSolver\");if(!t)throw new Error(\"PostProcessingSolver: completed pipeline is missing reconstruction output\");const e=this.getStageOutput(\"differentialPairReroutingSolver\")??this.differentialPairReroutingSolver?.getBestEffortOutput(),n=e?.failures??[];let o=\"input-hd-routes\";(e?.reroutedPairs.length??0)\u003e0\u0026\u0026(o=\"best-effort-hd-routes\");const i=[...n.map(t=\u003e({type:\"post_processing_error\",stage:\"differentialPairReroutingSolver\",message:t.message,connectionNames:[...t.connectionNames],reason:t.reason,returnedRouteSource:o})),...this.postProcessingErrors],r=structuredClone(t);return r.postProcessingErrors=structuredClone(i),r}initialVisualize(){if(this.fallbackOutput)return{lines:this.fallbackOutput.hdRoutes.map(t=\u003e({points:t.route.map(({x:t,y:e})=\u003e({x:t,y:e})),strokeWidth:t.traceThickness}))};const{traces:t,obstacles:e,bounds:n,layerCount:o}=this.model.params.simpleRouteJson;return iU({traces:structuredClone(t),obstacles:e,bounds:n,layerCount:o,activeConnectionNames:null,previewPath:null})}finalVisualize(){if(this.fallbackOutput)return this.initialVisualize();const t=jG({...this.inputProblem,hdRoutes:this.getOutput().hdRoutes}),{traces:e,obstacles:n,bounds:o,layerCount:i}=t.params.simpleRouteJson;return iU({traces:e,obstacles:n,bounds:o,layerCount:i,activeConnectionNames:null,previewPath:null})}},dU=class t{static generators=new Map;static register(e){t.generators.set(e.componentKind,e)}static create(e){const n=e.detectedComponent.componentKind,o=t.generators.get(n);if(!o)throw new Error(`No topology generator registered for component kind \"${n}\"`);return new o(e)}},hU=t=\u003e[t.obstacle.obstacleId??t.obstacle.componentId??\"obstacle\",t.start.x.toFixed(4),t.start.y.toFixed(4),t.end.x.toFixed(4),t.end.y.toFixed(4),t.expansionDirection.x,t.expansionDirection.y].join(\":\"),uU=t=\u003e{let e=0;for(const n of t)e=31*e+n.charCodeAt(0)\u003e\u003e\u003e0;return e},pU=(t,e)=\u003e`hsla(${uU(hU(t))%360},72%,36%,${e})`,mU=t=\u003e{const e=t.expansionDirection;return e.x\u003c0?\"left\":e.x\u003e0?\"right\":e.y\u003c0?\"bottom\":\"top\"},gU=t=\u003e({x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2}),fU=t=\u003e{const e=/^bga-gapfill-(\\d+)-/.exec(t.capacityMeshNodeId);return e?Number.parseInt(e[1],10):null},yU=(t,e)=\u003e{const n=gU(t),o=gU(e),i=n.y-o.y;if(Math.abs(i)\u003e1e-6)return i;const r=n.x-o.x;return Math.abs(r)\u003e1e-6?r:hU(t).localeCompare(hU(e))},_U=t=\u003e{const e=[...t].sort(yU),n=[];let o=e.shift();for(;o\u0026\u0026(n.push(o),0!==e.length);){const t=gU(o);let n=0,i=Number.POSITIVE_INFINITY;for(let o=0;o\u003ce.length;o++){const r=e[o],s=gU(r),a=(s.x-t.x)**2+(s.y-t.y)**2;a\u003ci-1e-9?(i=a,n=o):Math.abs(a-i)\u003c=1e-9\u0026\u0026yU(r,e[n])\u003c0\u0026\u0026(n=o)}o=e.splice(n,1)[0]}return n},bU=(t,e)=\u003e{const n=hU(t),o=e.findIndex(t=\u003ehU(t)===n);return o\u003e=0?`E${o+1}`:`E${uU(n).toString(36).slice(0,4)}`},xU=t=\u003et.flatMap(t=\u003e{const e=Ve(t);return[{obstacle:t,start:{x:e.minX,y:e.minY},end:{x:e.minX,y:e.maxY},expansionDirection:{x:-1,y:0}},{obstacle:t,start:{x:e.maxX,y:e.minY},end:{x:e.maxX,y:e.maxY},expansionDirection:{x:1,y:0}},{obstacle:t,start:{x:e.minX,y:e.minY},end:{x:e.maxX,y:e.minY},expansionDirection:{x:0,y:-1}},{obstacle:t,start:{x:e.minX,y:e.maxY},end:{x:e.maxX,y:e.maxY},expansionDirection:{x:0,y:1}}]}),vU=.001,SU=.001,IU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;meshIndex;allEdges=[];queueEdges=[];disconnectedEdges=[];currentEdge=null;lastSearchBounds=null;lastCandidateMeshNodes=[];lastMatchedMeshNode=null;_setup(){const t=Math.max(this.inputProblem.meshNodes.length,1);this.meshIndex=new Bt(t);for(const t of this.inputProblem.meshNodes){const e=Ve(t);this.meshIndex.add(e.minX,e.minY,e.maxX,e.maxY)}this.meshIndex.finish();const e=xU(this.inputProblem.unmarkedComponentObstacles);this.queueEdges=e,this.allEdges=_U(e),this.currentEdge=null,this.lastSearchBounds=null,this.lastCandidateMeshNodes=[],this.lastMatchedMeshNode=null}_step(){const t=this.queueEdges.shift();if(!t)return this.currentEdge=null,this.lastSearchBounds=null,this.lastCandidateMeshNodes=[],this.lastMatchedMeshNode=null,void(this.solved=!0);this.currentEdge=t,this.lastMatchedMeshNode=null;const e=Math.abs(t.start.x-t.end.x)\u003c=vU,n=e?{minX:t.start.x-SU,maxX:t.start.x+SU,minY:Math.min(t.start.y,t.end.y),maxY:Math.max(t.start.y,t.end.y)}:{minX:Math.min(t.start.x,t.end.x),maxX:Math.max(t.start.x,t.end.x),minY:t.start.y-SU,maxY:t.start.y+SU};this.lastSearchBounds=n;const o=this.meshIndex.search(n.minX,n.minY,n.maxX,n.maxY);this.lastCandidateMeshNodes=o.map(t=\u003ethis.inputProblem.meshNodes[t]);let i=!1;for(const n of o){const o=this.inputProblem.meshNodes[n],r=Ve(o);if(e){if(!(Math.min(r.maxY,Math.max(t.start.y,t.end.y))-Math.max(r.minY,Math.min(t.start.y,t.end.y))\u003evU))continue;if(-1===t.expansionDirection.x\u0026\u0026Math.abs(r.maxX-t.start.x)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}if(1===t.expansionDirection.x\u0026\u0026Math.abs(r.minX-t.start.x)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}continue}if(Math.min(r.maxX,Math.max(t.start.x,t.end.x))-Math.max(r.minX,Math.min(t.start.x,t.end.x))\u003evU){if(-1===t.expansionDirection.y\u0026\u0026Math.abs(r.maxY-t.start.y)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}if(1===t.expansionDirection.y\u0026\u0026Math.abs(r.minY-t.start.y)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}}}i||this.disconnectedEdges.push(t)}getOutput(){return this.disconnectedEdges}visualize(){const t=this.disconnectedEdges,e=this.allEdges.length\u003e0?this.allEdges:[...t,...this.currentEdge?[this.currentEdge]:[]],n=this.currentEdge?pU(this.currentEdge,.88):\"rgba(40,40,40,0.4)\",o=this.inputProblem.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(120,120,120,0.18)\":\"rgba(120,120,120,0.08)\",stroke:t._containsObstacle?\"rgba(120,120,120,0.42)\":\"rgba(120,120,120,0.24)\"})),i=this.lastSearchBounds\u0026\u0026this.currentEdge?[{center:(r=this.lastSearchBounds,{x:(r.minX+r.maxX)/2,y:(r.minY+r.maxY)/2}),width:this.lastSearchBounds.maxX-this.lastSearchBounds.minX,height:this.lastSearchBounds.maxY-this.lastSearchBounds.minY,fill:pU(this.currentEdge,.1),stroke:pU(this.currentEdge,.36),label:[bU(this.currentEdge,e),\"search band\"].join(\" \")}]:[];var r;const s=this.lastCandidateMeshNodes.map(t=\u003e({...Dc(t,{rectMargin:.018}),fill:t===this.lastMatchedMeshNode?\"rgba(0,180,90,0.24)\":this.currentEdge?pU(this.currentEdge,.16):\"rgba(80,120,160,0.16)\",stroke:t===this.lastMatchedMeshNode?\"rgba(0,150,80,0.88)\":n,label:[t===this.lastMatchedMeshNode?\"matched\":\"candidate\",t.capacityMeshNodeId,`z:${t.availableZ.join(\",\")}`].join(\"\\n\")})),a=this.inputProblem.unmarkedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(160,160,160,0.10)\",stroke:\"rgba(160,160,160,0.40)\",label:t.obstacleId??t.componentId??\"obstacle\"})),c=t.map(t=\u003e({points:[t.start,t.end],strokeColor:pU(t,.14),strokeWidth:.01,strokeDash:\"5 4\",label:[bU(t,e),mU(t),\"disconnected\"].join(\" \")})),l=[],d=[];if(this.currentEdge){const t=gU(this.currentEdge);l.push({points:[this.currentEdge.start,this.currentEdge.end],strokeColor:pU(this.currentEdge,1),strokeWidth:.06,label:[bU(this.currentEdge,e),mU(this.currentEdge),\"checking\"].join(\" \")},{points:[t,{x:t.x+.16*this.currentEdge.expansionDirection.x,y:t.y+.16*this.currentEdge.expansionDirection.y}],strokeColor:pU(this.currentEdge,.82),strokeWidth:.02,strokeDash:\"3 3\"}),d.push({...t,color:pU(this.currentEdge,1),label:bU(this.currentEdge,e)})}return{rects:[...o,...i,...s,...a],lines:[...c,...l],points:d}}},CU=.001,PU=.001,MU=1e-6,NU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;meshIndex;meshBounds;expandedNodes=[];_setup(){const t=Math.max(this.inputProblem.meshNodes.length,1);this.meshIndex=new Bt(t);let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const t of this.inputProblem.meshNodes){const r=Ve(t);this.meshIndex.add(r.minX,r.minY,r.maxX,r.maxY),e=Math.min(e,r.minX),n=Math.max(n,r.maxX),o=Math.min(o,r.minY),i=Math.max(i,r.maxY)}this.meshIndex.finish(),this.meshBounds=this.inputProblem.meshNodes.length?{minX:e,maxX:n,minY:o,maxY:i}:{minX:0,maxX:0,minY:0,maxY:0}}getObstacleAvailableZ(t){return t.__zLayers??t.layers.map(t=\u003eko(t,this.inputProblem.layerCount))}getSharedOverlapArea(t,e){if(!t.availableZ.some(t=\u003ee.availableZ.includes(t)))return 0;const n=Ve(t),o=Ve(e),i=Math.min(n.maxX,o.maxX)-Math.max(n.minX,o.minX),r=Math.min(n.maxY,o.maxY)-Math.max(n.minY,o.minY);return i\u003c=MU||r\u003c=MU?0:i*r}getNodeObstacleOverlapArea(t,e){const n=this.getObstacleAvailableZ(e);if(!t.availableZ.some(t=\u003en.includes(t)))return 0;const o=Ve(t),i=Ve(e),r=Math.min(o.maxX,i.maxX)-Math.max(o.minX,i.minX),s=Math.min(o.maxY,i.maxY)-Math.max(o.minY,i.minY);return r\u003c=MU||s\u003c=MU?0:r*s}getClosestMeshNode(t,e){const n=Math.abs(t.start.x-t.end.x)\u003c=CU,o=this.getObstacleAvailableZ(t.obstacle),i=n?t.expansionDirection.x\u003c0?{minX:this.meshBounds.minX,maxX:t.start.x,minY:Math.min(t.start.y,t.end.y)-PU,maxY:Math.max(t.start.y,t.end.y)+PU}:{minX:t.start.x,maxX:this.meshBounds.maxX,minY:Math.min(t.start.y,t.end.y)-PU,maxY:Math.max(t.start.y,t.end.y)+PU}:t.expansionDirection.y\u003c0?{minX:Math.min(t.start.x,t.end.x)-PU,maxX:Math.max(t.start.x,t.end.x)+PU,minY:this.meshBounds.minY,maxY:t.start.y}:{minX:Math.min(t.start.x,t.end.x)-PU,maxX:Math.max(t.start.x,t.end.x)+PU,minY:t.start.y,maxY:this.meshBounds.maxY},r=this.meshIndex.search(i.minX,i.minY,i.maxX,i.maxY);let s=null,a=Number.POSITIVE_INFINITY;const c=[...r.map(t=\u003ethis.inputProblem.meshNodes[t]),...e];for(const e of c){if(e._containsObstacle)continue;if(!e.availableZ.some(t=\u003eo.includes(t)))continue;const i=Ve(e);if((n?Math.min(Math.max(t.start.y,t.end.y),i.maxY)-Math.max(Math.min(t.start.y,t.end.y),i.minY):Math.min(Math.max(t.start.x,t.end.x),i.maxX)-Math.max(Math.min(t.start.x,t.end.x),i.minX))\u003c=CU)continue;const r=n?t.expansionDirection.x\u003c0?t.start.x-i.maxX:i.minX-t.start.x:t.expansionDirection.y\u003c0?t.start.y-i.maxY:i.minY-t.start.y;r\u003cCU||(r\u003e=a||(a=r,s=e))}return s}createExpandedNode(t,e,n){const o=Ve(e),i=this.getObstacleAvailableZ(t.obstacle);if(Math.abs(t.start.x-t.end.x)\u003c=CU){const r=Math.max(Math.min(t.start.y,t.end.y),o.minY),s=Math.min(Math.max(t.start.y,t.end.y),o.maxY),a=t.expansionDirection.x\u003c0?o.maxX:t.start.x,c=t.expansionDirection.x\u003c0?t.start.x:o.minX;return c-a\u003c=CU||s-r\u003c=CU?null:{capacityMeshNodeId:`bga-gapfill-${n}-${t.obstacle.obstacleId??\"no-obstacle\"}-${e.capacityMeshNodeId}`,center:{x:(a+c)/2,y:(r+s)/2},width:c-a,height:s-r,layer:`z${i.join(\",\")}`,availableZ:i}}const r=Math.max(Math.min(t.start.x,t.end.x),o.minX),s=Math.min(Math.max(t.start.x,t.end.x),o.maxX),a=t.expansionDirection.y\u003c0?o.maxY:t.start.y,c=t.expansionDirection.y\u003c0?t.start.y:o.minY;return s-r\u003c=CU||c-a\u003c=CU?null:{capacityMeshNodeId:`bga-gapfill-${n}-${t.obstacle.obstacleId??\"no-obstacle\"}-${e.capacityMeshNodeId}`,center:{x:(r+s)/2,y:(a+c)/2},width:s-r,height:c-a,layer:`z${i.join(\",\")}`,availableZ:i}}overlapsExistingGeometry(t,e){for(const e of this.inputProblem.meshNodes)if(this.getSharedOverlapArea(t,e)\u003e0)return!0;for(const n of e)if(this.getSharedOverlapArea(t,n)\u003e0)return!0;for(const e of this.inputProblem.edgesWithObstacle)if(this.getNodeObstacleOverlapArea(t,e.obstacle)\u003e0)return!0;return!1}_step(){const t=[];for(const[e,n]of this.inputProblem.edgesWithObstacle.entries()){const o=this.getClosestMeshNode(n,t);if(!o)continue;const i=this.createExpandedNode(n,o,e);i\u0026\u0026(this.overlapsExistingGeometry(i,t)||t.push(i))}this.expandedNodes=t,this.solved=!0}getOutput(){return this.expandedNodes}visualize(){const t=this.inputProblem.edgesWithObstacle,e=_U(t);return{rects:[...this.inputProblem.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.16)\":\"rgba(0,120,255,0.08)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.35)\":\"rgba(0,120,255,0.28)\"})),...this.expandedNodes.map(n=\u003e{const o=fU(n),i=null===o?null:t[o]??null;return{...Dc(n,{rectMargin:.012,zOffset:.01}),fill:i?pU(i,.24):\"rgba(0,160,100,0.24)\",stroke:i?pU(i,.72):\"rgba(0,160,100,0.68)\",label:[i?bU(i,e):\"E?\",\"expanded\",n.capacityMeshNodeId,`z:${n.availableZ.join(\",\")}`].join(\"\\n\")}})],lines:[...this.inputProblem.edgesWithObstacle.map(t=\u003e({points:[t.start,t.end],strokeColor:pU(t,.9),strokeWidth:.034,label:[bU(t,e),mU(t)].join(\" \")})),...this.inputProblem.edgesWithObstacle.map(t=\u003e{const e=gU(t);return{points:[e,{x:e.x+.16*t.expansionDirection.x,y:e.y+.16*t.expansionDirection.y}],strokeColor:pU(t,.7),strokeWidth:.016,strokeDash:\"3 3\"}})],points:this.inputProblem.edgesWithObstacle.map(t=\u003e({...gU(t),color:pU(t,.95),label:bU(t,e)}))}}},wU=.001,TU=class extends Dt{constructor(t){super(t),this.inputProblem=t}inputProblem;detectEdgesNotConnectedToMesh;expandUnconnectedEdgesToMesh;pipelineDef=[Lt(\"detectEdgesNotConnectedToMesh\",IU,t=\u003e[t.inputProblem]),Lt(\"expandUnconnectedEdgesToMesh\",NU,t=\u003e[{meshNodes:t.inputProblem.meshNodes,edgesWithObstacle:t.detectEdgesNotConnectedToMesh.getOutput(),layerCount:t.inputProblem.layerCount}])];getOutput(){return[...this.inputProblem.meshNodes,...this.expandUnconnectedEdgesToMesh.getOutput()]}getExpandedNodes(){return this.expandUnconnectedEdgesToMesh.getOutput()}getObstacleLayer(t){return`z${(t.obstacle.__zLayers??t.obstacle.layers.map(t=\u003eko(t,this.inputProblem.layerCount))).join(\",\")}`}getObstacleRects(){return this.inputProblem.unmarkedComponentObstacles.map(t=\u003e{const e=t.__zLayers??t.layers.map(t=\u003eko(t,this.inputProblem.layerCount));return{center:t.center,width:t.width,height:t.height,fill:\"rgba(150,150,150,0.08)\",stroke:\"rgba(90,90,90,0.42)\",label:t.obstacleId??t.componentId??\"bga obstacle\",layer:`z${e.join(\",\")}`}})}getBaseMeshRects(){return this.inputProblem.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.025,zOffset:.01}),fill:t._containsObstacle?\"rgba(210,60,60,0.14)\":\"rgba(80,120,160,0.08)\",stroke:t._containsObstacle?\"rgba(190,40,40,0.42)\":\"rgba(80,120,160,0.28)\",label:`mesh ${t.capacityMeshNodeId}\\nz:${t.availableZ.join(\",\")}`}))}initialVisualize(){const t=xU(this.inputProblem.unmarkedComponentObstacles),e=_U(t),n=[...t.map(t=\u003e({points:[t.start,t.end],strokeColor:pU(t,.72),strokeWidth:.018,strokeDash:\"0.05 0.035\",layer:this.getObstacleLayer(t),label:[bU(t,e),mU(t)].join(\" \")})),...t.map(t=\u003e{const e=gU(t);return{points:[e,{x:e.x+.18*t.expansionDirection.x,y:e.y+.18*t.expansionDirection.y}],strokeColor:pU(t,.64),strokeWidth:.012,strokeDash:\"0.035 0.025\",layer:this.getObstacleLayer(t)}})];return{title:\"BGA GapFill: candidate obstacle edges\",rects:[...this.getBaseMeshRects(),...this.getObstacleRects()],lines:n}}finalVisualize(){const t=this.getStageOutput(\"detectEdgesNotConnectedToMesh\")??[],e=this.getStageOutput(\"expandUnconnectedEdgesToMesh\")??[],n=_U(xU(this.inputProblem.unmarkedComponentObstacles)),o=new Map;for(const t of e){const e=fU(t);null!==e\u0026\u0026o.set(e,t)}const i=e.map(e=\u003e{const o=fU(e),i=null===o?null:t[o]??null,r=i?(({expandedNode:t,edge:e,meshNodes:n})=\u003e{const o=Ve(t),i=Math.abs(e.start.x-e.end.x)\u003c=wU;return n.filter(n=\u003e{if(n._containsObstacle)return!1;if(!t.availableZ.some(t=\u003en.availableZ.includes(t)))return!1;const r=Ve(n);return i?!(Math.min(o.maxY,r.maxY)-Math.max(o.minY,r.minY)\u003c=wU)\u0026\u0026(e.expansionDirection.x\u003c0?Math.abs(r.maxX-o.minX)\u003c=wU:Math.abs(r.minX-o.maxX)\u003c=wU):!(Math.min(o.maxX,r.maxX)-Math.max(o.minX,r.minX)\u003c=wU)\u0026\u0026(e.expansionDirection.y\u003c0?Math.abs(r.maxY-o.minY)\u003c=wU:Math.abs(r.minY-o.maxY)\u003c=wU)}).map(t=\u003et.capacityMeshNodeId)})({expandedNode:e,edge:i,meshNodes:this.inputProblem.meshNodes}):[],s=i?bU(i,n):\"E?\",a=null===i?\"rgba(0,160,100,0.72)\":pU(i,.72);return{...Dc(e,{rectMargin:.012,zOffset:.01}),fill:null===i?\"rgba(0,160,100,0.24)\":pU(i,.16),stroke:a,label:[`${s} gap fill`,r.length\u003e0?`to ${r.join(\",\")}`:\"target mesh not adjacent\",`z:${e.availableZ.join(\",\")}`].join(\"\\n\")}}),r=t.map((t,e)=\u003e{const i=o.get(e);return{points:[t.start,t.end],strokeColor:i?pU(t,.68):\"rgba(80,80,80,0.14)\",strokeWidth:i?.026:.008,...i?{}:{strokeDash:\"5 4\"},layer:this.getObstacleLayer(t),label:[[bU(t,n),mU(t)].join(\" \"),i?\"filled\":\"no fill created\"].join(\"\\n\")}}),s=t.flatMap((t,e)=\u003e{const n=gU(t),i=o.get(e);return i?[{points:[n,i.center],strokeColor:pU(t,.42),strokeWidth:.012,strokeDash:\"0.035 0.025\",layer:this.getObstacleLayer(t)}]:[]}),a=t.flatMap((t,e)=\u003eo.has(e)?[{...gU(t),color:pU(t,.82),label:bU(t,n),layer:this.getObstacleLayer(t)}]:[]);return{title:\"BGA GapFill: disconnected edges and created mesh\",rects:[...this.getBaseMeshRects(),...this.getObstacleRects(),...i],lines:[...r,...s],points:a}}};function RU(t,e){const n=[];for(let o=0;o\u003ct.length;o++){const i=t[o];n.push(i);const r=t[o+1];if(void 0===r)continue;const s=Math.round((r-i)/e);if(!(s\u003c=1))for(let t=1;t\u003cs;t++){const e=t/s;n.push(Number((i+(r-i)*e).toFixed(6)))}}return n}var EU=.001;function AU(t){const e=[];for(let n=1;n\u003ct.length;n++){const o=t[n]-t[n-1];o\u003eEU\u0026\u0026e.push(o)}if(0===e.length)return null;const n=Math.min(...e),o=e.filter(t=\u003et\u003c=1.5*n).sort((t,e)=\u003et-e),i=Math.floor(o.length/2);return o.length%2==0?(o[i-1]+o[i])/2:o[i]}function OU(t){return[...new Set(t)].sort((t,e)=\u003et-e)}function kU(t){return Number(t.toFixed(6))}var LU=class t{static fromObstacles(e){if(0===e.length)return null;const n=OU(e.map(t=\u003et.center.x)),o=OU(e.map(t=\u003et.center.y)),i=AU(n),r=AU(o);return null===i||null===r?null:new t({obstacles:e,xCoordinates:RU(n,i),yCoordinates:RU(o,r),pitchX:i,pitchY:r})}xCoordinates;yCoordinates;pitchX;pitchY;originX;originY;rowCount;colCount;padWidth;padHeight;slots=new Map;constructor(t){this.xCoordinates=t.xCoordinates,this.yCoordinates=t.yCoordinates,this.pitchX=t.pitchX,this.pitchY=t.pitchY,this.originX=this.xCoordinates[0],this.originY=this.yCoordinates[0],this.colCount=this.xCoordinates.length,this.rowCount=this.yCoordinates.length,this.padWidth=t.obstacles[0].width,this.padHeight=t.obstacles[0].height;for(const e of t.obstacles){const t=this.getSlotForObstacle(e);t\u0026\u0026this.slots.set(this.getSlotKey(t.row,t.col),{...t,obstacle:e})}}getSlotKey(t,e){return`${t}:${e}`}getAxisIndex(t,e){let n=-1,o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ct.length;i++){const r=Math.abs(t[i]-e);r\u003co\u0026\u0026(o=r,n=i)}return o\u003c=EU?n:null}getAxisCoordinate(t,e){return t[e]}hasPadAt(t,e){return this.slots.has(this.getSlotKey(t,e))}getSlotForObstacle(t){const e=this.getAxisIndex(this.yCoordinates,t.center.y),n=this.getAxisIndex(this.xCoordinates,t.center.x);return null===e||null===n||e\u003c0||e\u003e=this.rowCount||n\u003c0||n\u003e=this.colCount?null:{row:e,col:n}}getSlotCenter(t,e){return{x:this.getAxisCoordinate(this.xCoordinates,e),y:this.getAxisCoordinate(this.yCoordinates,t)}}getHorizontalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t,e+1),i=Math.abs(o.x-n.x);return{orientation:\"horizontal\",row:t,col:e,center:{x:kU((n.x+o.x)/2),y:n.y},width:i-this.padWidth,height:this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)\u0026\u0026this.hasPadAt(t,e+1)}}getVerticalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t+1,e),i=Math.abs(o.y-n.y);return{orientation:\"vertical\",row:t,col:e,center:{x:n.x,y:kU((n.y+o.y)/2)},width:this.padWidth,height:i-this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)\u0026\u0026this.hasPadAt(t+1,e)}}getDiagonalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t+1,e+1),i=Math.abs(o.x-n.x),r=Math.abs(o.y-n.y);return{orientation:\"diagonal\",row:t,col:e,center:{x:kU((n.x+o.x)/2),y:kU((n.y+o.y)/2)},width:i-this.padWidth,height:r-this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)\u0026\u0026this.hasPadAt(t+1,e+1)}}getDiagonalGaps(){const t=[];for(let e=0;e\u003cthis.rowCount-1;e++)for(let n=0;n\u003cthis.colCount-1;n++)t.push(this.getDiagonalGap(e,n));return t.filter(t=\u003et.width\u003eEU\u0026\u0026t.height\u003eEU)}getAxisGaps(){const t=[];for(let e=0;e\u003cthis.rowCount;e++)for(let n=0;n\u003cthis.colCount-1;n++)t.push(this.getHorizontalGap(e,n));for(let e=0;e\u003cthis.rowCount-1;e++)for(let n=0;n\u003cthis.colCount;n++)t.push(this.getVerticalGap(e,n));return t.filter(t=\u003et.width\u003eEU\u0026\u0026t.height\u003eEU)}getMissingSlots(){const t=[];for(let e=0;e\u003cthis.rowCount;e++)for(let n=0;n\u003cthis.colCount;n++)this.hasPadAt(e,n)||t.push({row:e,col:n,center:this.getSlotCenter(e,n),width:this.padWidth,height:this.padHeight});return t}};function DU(t){if([t.point.pointId,t.point.pcb_port_id].filter(t=\u003e\"string\"==typeof t).some(e=\u003et.obstacle.connectedTo.includes(e)))return!0;if(0===t.obstacle.connectedTo.length)return!1;if(Be(t.point,t.obstacle)\u003e.001)return!1;const e=xo(t.point).map(e=\u003eko(e,t.layerCount)),n=t.obstacle.layers.map(e=\u003eko(e,t.layerCount));return e.some(t=\u003en.includes(t))}function zU(t){return t.obstacleId??[t.componentId??\"no-component\",t.center.x,t.center.y,t.width,t.height,t.layers.join(\",\")].join(\":\")}function FU({componentId:t,orientationKey:e,row:n,col:o,center:i,width:r,height:s}){return[\"cmn\",e,t,n,o,i.x,i.y,r,s].join(\"_\")}function BU(t){const{componentId:e,bgaGap:n,freeLayers:o,multiLayerThreshold:i}=t,r=n.width\u003ei\u0026\u0026n.height\u003ei;let s=\"d\";\"horizontal\"===n.orientation\u0026\u0026(s=\"h\"),\"vertical\"===n.orientation\u0026\u0026(s=\"v\");const a=FU({componentId:e,orientationKey:s,row:n.row,col:n.col,center:n.center,width:n.width,height:n.height});return\"diagonal\"===n.orientation\u0026\u0026r||!n.isBetweenTwoPads\u0026\u0026r?[{center:n.center,width:n.width,height:n.height,availableZ:[...o],capacityMeshNodeId:`${a}_all`,layer:\"\"}]:o.map(t=\u003e({center:n.center,width:n.width,height:n.height,availableZ:[t],capacityMeshNodeId:`${a}_${t}`,layer:\"\"}))}function jU(t){const{componentId:e,obstacle:n,freeLayers:o,layerCount:i}=t,r=n.layers.map(t=\u003eko(t,i)),s=o.filter(t=\u003e!r.includes(t)),a=zU(n);return s.map(t=\u003e({capacityMeshNodeId:`free-${e}-${a}-${t}`,center:n.center,width:n.width,height:n.height,layer:`z${t}`,availableZ:[t]}))}function $U(t,e,n){const o=e.layers.map(t=\u003eko(t,n.layerCount)),i=zU(e),r=function(t){for(const e of t.srj.connections)for(const n of e.pointsToConnect)if(DU({point:n,obstacle:t.obstacle,layerCount:t.srj.layerCount}))return e.__rootConnectionNames?.[0]??e.name}({obstacle:e,srj:n});return{capacityMeshNodeId:`obstacle-${t}-${i}-${o.join(\",\")}-${e.center.x}-${e.center.y}`,_containsObstacle:!0,...r?{_containsTarget:!0,_targetConnectionName:r}:{},center:e.center,width:e.width,height:e.height,layer:`z${o.join(\",\")}`,availableZ:o}}var YU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;componentObstacles=[];meshNodes=[];getConstructorParams(){return[this.inputProblem]}_step(){const{srj:t,componentBounds:e,componentId:n,markedComponentObstacles:o,unmarkedComponentObstacles:i}=this.inputProblem,r=t.obstacles.filter(t=\u003e!0===t.isCopperPour).filter(t=\u003eXe(Ve(t),e)).flatMap(e=\u003ee.layers.map(e=\u003eko(e,t.layerCount))),s=Array.from({length:t.layerCount},(t,e)=\u003ee).filter(t=\u003e!r.includes(t));if(this.componentObstacles=o,0===o.length||0===s.length)return void(this.solved=!0);const a=LU.fromObstacles(o);if(!a)return void(this.solved=!0);const c=a.getAxisGaps(),l=a.getDiagonalGaps(),d=a.getMissingSlots(),h=1.2*(this.inputProblem.viaDiameter??Yo(t).padDiameter);this.meshNodes=[...c.flatMap(t=\u003eBU({componentId:n,bgaGap:t,freeLayers:s,multiLayerThreshold:h})),...l.flatMap(t=\u003eBU({componentId:n,bgaGap:t,freeLayers:s,multiLayerThreshold:h})),...d.flatMap(t=\u003efunction(t){const{componentId:e,missingBgaSlot:n,freeLayers:o,multiLayerThreshold:i}=t,r=FU({componentId:e,orientationKey:\"missing\",row:n.row,col:n.col,center:n.center,width:n.width,height:n.height});return n.width\u003ei\u0026\u0026n.height\u003ei?[{center:n.center,width:n.width,height:n.height,availableZ:[...o],capacityMeshNodeId:`${r}_all`,layer:\"\"}]:o.map(t=\u003e({center:n.center,width:n.width,height:n.height,availableZ:[t],capacityMeshNodeId:`${r}_${t}`,layer:\"\"}))}({componentId:n,missingBgaSlot:t,freeLayers:s,multiLayerThreshold:h})),...o.flatMap(e=\u003e[...jU({componentId:n,obstacle:e,freeLayers:s,layerCount:t.layerCount}),$U(n,e,t)]),...i.flatMap(e=\u003e[$U(n,e,t)])],this.meshNodes=function(t){const e=new Map;return t.map(t=\u003e{const n=e.get(t.capacityMeshNodeId)??0;return e.set(t.capacityMeshNodeId,n+1),0===n?t:{...t,capacityMeshNodeId:`${t.capacityMeshNodeId}__dup${n}`}})}(this.meshNodes),this.solved=!0}getOutput(){return this.meshNodes}visualize(){return{rects:[{center:{x:(this.inputProblem.componentBounds.minX+this.inputProblem.componentBounds.maxX)/2,y:(this.inputProblem.componentBounds.minY+this.inputProblem.componentBounds.maxY)/2},width:this.inputProblem.componentBounds.maxX-this.inputProblem.componentBounds.minX,height:this.inputProblem.componentBounds.maxY-this.inputProblem.componentBounds.minY,fill:\"rgba(0,0,0,0)\",stroke:\"rgba(30,30,30,0.65)\",label:`component ${this.inputProblem.componentId}`},...this.inputProblem.markedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,0,0,0.18)\",stroke:\"rgba(255,0,0,0.52)\",label:`pad ${t.obstacleId??\"obstacle\"}`})),...this.inputProblem.unmarkedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.14)\",stroke:\"rgba(255,140,0,0.42)\",label:`foreign ${t.obstacleId??\"obstacle\"}`})),...this.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.14)\":t.capacityMeshNodeId.includes(\"missing\")?\"rgba(0,200,120,0.18)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.36)\":t.capacityMeshNodeId.includes(\"missing\")?\"rgba(0,200,120,0.52)\":\"rgba(0,120,255,0.38)\"}))]}}};function XU(t){return t.capacityMeshNodeId.startsWith(\"bga-gapfill-\")}function VU(t){return JSON.stringify({availableZ:[...t.availableZ].sort((t,e)=\u003et-e),_containsTarget:t._containsTarget??!1,_targetConnectionName:t._targetConnectionName??null,_depth:t._depth??null,_strawNode:t._strawNode??!1,_strawParentCapacityMeshNodeId:t._strawParentCapacityMeshNodeId??null,_qfpRegionType:t._qfpRegionType??null,_isNarrowQfpPadGap:t._isNarrowQfpPadGap??!1,_soicRegionType:t._soicRegionType??null,_offBoardConnectionId:t._offBoardConnectionId??null,_offboardNetName:t._offboardNetName??null,_isVirtualOffboard:t._isVirtualOffboard??!1,_containsObstacle:t._containsObstacle??!1})}function WU(t,e){const n=Ve(t);for(const o of e){if(!t.availableZ.some(t=\u003eo.availableZ.includes(t)))continue;const e=Ve(o);if(Xe(n,e))return!0}return!1}function HU(t){const e=t[0];if(!e)throw new Error(\"createMergedNode requires at least one source node\");let n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const e of t){const t=Ve(e);n=Math.min(n,t.minX),o=Math.max(o,t.maxX),i=Math.min(i,t.minY),r=Math.max(r,t.maxY)}return{...e,capacityMeshNodeId:`merge:${t.map(t=\u003et.capacityMeshNodeId).join(\":\")}`,center:{x:(n+o)/2,y:(i+r)/2},width:o-n,height:r-i}}function GU(t,e,n){return{center:t.center,width:t.width,height:t.height,fill:e,stroke:e,label:n}}var UU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;obstacleNodes=[];passthroughNodes=[];mergedNodes=[];pendingGroups=[];totalGroupCount=0;processedGroupCount=0;debugFilteredNodes=[];debugMergeEvents=[];currentGroupKey=null;currentRootNodeId=null;lastMergedNodeId=null;_setup(){this.obstacleNodes=this.inputProblem.meshNodes.filter(t=\u003e!0===t._containsObstacle),this.passthroughNodes=[],this.mergedNodes=[],this.pendingGroups=[],this.totalGroupCount=0,this.processedGroupCount=0,this.debugFilteredNodes=[],this.debugMergeEvents=[],this.currentGroupKey=null,this.currentRootNodeId=null,this.lastMergedNodeId=null;const t=new Map;for(const e of this.inputProblem.meshNodes){if(!0===e._containsObstacle){this.passthroughNodes.push(e),this.debugFilteredNodes.push({type:\"preserved-obstacle\",node:e,reason:\"contains-obstacle\"});continue}if(XU(e)){this.passthroughNodes.push(e);continue}if(e.availableZ.length!==this.inputProblem.layerCount){this.passthroughNodes.push(e);continue}let n=!1;for(let t=0;t\u003cthis.inputProblem.layerCount;t+=1)if(!e.availableZ.includes(t)){n=!0;break}if(n){this.passthroughNodes.push(e);continue}if(WU(e,this.obstacleNodes)){this.passthroughNodes.push(e),this.debugFilteredNodes.push({type:\"preserved-overlap\",node:e,reason:\"overlaps-obstacle\"});continue}const o=VU(e),i=t.get(o);i?i.push(e):t.set(o,[e])}for(const[e,n]of t.entries())n.length\u003c=1?this.passthroughNodes.push(...n):this.pendingGroups.push({groupKey:e,nodes:n});this.pendingGroups.sort((t,e)=\u003ee.nodes.length-t.nodes.length),this.totalGroupCount=this.pendingGroups.length,this.updateStats(\"setup\")}_step(){const t=this.pendingGroups.shift();if(!t)return this.currentGroupKey=null,this.currentRootNodeId=null,this.solved=!0,void this.updateStats(\"done\");const e=t.nodes[0];this.currentGroupKey=t.groupKey,this.currentRootNodeId=e?e.capacityMeshNodeId:null;const n=function(t){if(!t.nodes[0])return{outputNodes:[],mergeEvents:[]};let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.POSITIVE_INFINITY;for(const r of t.nodes){e=Math.min(e,r.width),n=Math.min(n,r.height);const t=Ve(r);o=Math.min(o,t.minX),i=Math.min(i,t.minY)}const r=new Map,s=[];for(const a of t.nodes){const t=Ve(a),c=Math.round((t.minX-o)/e),l=Math.round((t.minY-i)/n),d=Math.max(1,Math.round(a.width/e)),h=Math.max(1,Math.round(a.height/n));for(let t=0;t\u003ch;t+=1)for(let e=0;e\u003cd;e+=1)r.set(`${c+e},${l+t}`,a);s.push({col:c,row:l})}s.sort((t,e)=\u003et.row-e.row||t.col-e.col);const a=new Set,c=[],l=[];for(const o of s){const i=`${o.col},${o.row}`;if(a.has(i))continue;let s=0;for(;;){const t=`${o.col+s},${o.row}`;if(!r.has(t))break;if(a.has(t))break;s+=1}let d=s,h=1,u=1,p=1;for(let t=1;;t+=1){const i=o.row+t-1;let s=0;for(;s\u003cd;){const t=`${o.col+s},${i}`;if(!r.has(t))break;if(a.has(t))break;s+=1}if(0===s)break;d=Math.min(d,s);for(let o=d;o\u003e=1;o-=1){const i=o*e,r=t*n,s=Math.min(i,r);if((s\u003c=1e-6?Number.POSITIVE_INFINITY:Math.max(i,r)/s)\u003e4)continue;const a=o*t;a\u003ep\u0026\u0026(p=a,h=o,u=t);break}}const m=new Map;for(let t=0;t\u003cu;t+=1)for(let e=0;e\u003ch;e+=1){const n=`${o.col+e},${o.row+t}`,i=r.get(n);i\u0026\u0026(a.add(n),m.set(i.capacityMeshNodeId,i))}const g=[...m.values()];if(g.length\u003c=1){const t=g[0];t\u0026\u0026c.push(t);continue}const f=HU(g);c.push(f),l.push({type:\"merge\",groupKey:t.groupKey,sourceNodes:g,mergedNode:f})}return{outputNodes:c,mergeEvents:l}}(t);this.mergedNodes.push(...n.outputNodes),this.processedGroupCount+=1,this.debugMergeEvents.push(...n.mergeEvents);const o=n.mergeEvents[n.mergeEvents.length-1];o\u0026\u0026(this.lastMergedNodeId=o.mergedNode.capacityMeshNodeId),this.updateStats(n.mergeEvents.length\u003e0?\"merged-group\":\"passthrough-group\")}computeProgress(){return 0===this.totalGroupCount?1:this.processedGroupCount/this.totalGroupCount}updateStats(t){const e=new Set(this.debugMergeEvents.map(t=\u003et.groupKey)),n={lastAction:t,totalGroupCount:this.totalGroupCount,processedGroupCount:this.processedGroupCount,pendingGroupCount:this.pendingGroups.length,mergedNodeCount:this.mergedNodes.length,passthroughNodeCount:this.passthroughNodes.length,gapFillNodeCount:this.passthroughNodes.filter(XU).length,preservedObstacleNodeCount:this.debugFilteredNodes.filter(t=\u003e\"preserved-obstacle\"===t.type).length,preservedOverlapNodeCount:this.debugFilteredNodes.filter(t=\u003e\"preserved-overlap\"===t.type).length,mergeCount:this.debugMergeEvents.length,mergedGroupCount:e.size,currentGroupKey:this.currentGroupKey,currentRootNodeId:this.currentRootNodeId,lastMergedNodeId:this.lastMergedNodeId};this.stats=n}getConstructorParams(){return[this.inputProblem]}getOutput(){return[...this.mergedNodes,...this.passthroughNodes]}visualize(){const t=this.getOutput(),e=this.currentRootNodeId?t.find(t=\u003et.capacityMeshNodeId===this.currentRootNodeId)??null:null,n=this.lastMergedNodeId?t.find(t=\u003et.capacityMeshNodeId===this.lastMergedNodeId)??null:null;return{rects:[...this.debugFilteredNodes.map(t=\u003eGU(t.node,\"preserved-obstacle\"===t.type?\"rgba(255,64,64,0.35)\":\"rgba(255,160,64,0.35)\",t.reason)),...this.passthroughNodes.map(t=\u003eGU(t,t._containsObstacle?\"rgba(255,0,0,0.35)\":XU(t)?\"rgba(0,120,255,0.18)\":\"rgba(160,160,160,0.12)\")),...this.mergedNodes.map(t=\u003eGU(t,\"rgba(120,120,120,0.14)\")),...e?[GU(e,\"rgba(255,215,0,0.35)\",\"active-group\")]:[],...n?[GU(n,\"rgba(0,200,120,0.28)\",\"merged\")]:[]]}}},ZU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;obstacleQueue=[];obstacleQueueIndex=0;meshNodes=[];_setup(){this.obstacleQueue=this.inputProblem.obstacles,this.obstacleQueueIndex=0,this.meshNodes=[...this.inputProblem.meshNodes]}_step(){if(this.obstacleQueueIndex\u003e=this.obstacleQueue.length)return void(this.solved=!0);const t=this.obstacleQueue[this.obstacleQueueIndex],e=t.layers.map(t=\u003eko(t,this.inputProblem.layerCount)),n=[];for(const o of this.meshNodes){if(o._containsObstacle){n.push(o);continue}if(!e.some(t=\u003eo.availableZ.includes(t))){n.push(o);continue}if(!Xe(Ve(o),Ve(t))){n.push(o);continue}if(1===o.availableZ.length)continue;const i=o.availableZ.filter(t=\u003e!e.includes(t));for(const t of i){const e={...o,capacityMeshNodeId:`${o.capacityMeshNodeId}:z${t}`,availableZ:[t],layer:`z${t}`};n.push(e)}}this.meshNodes=n,this.obstacleQueueIndex+=1,this.stats={obstaclesProcessed:this.obstacleQueueIndex,obstacleCount:this.obstacleQueue.length,meshNodeCount:this.meshNodes.length}}computeProgress(){return 0===this.obstacleQueue.length?1:this.obstacleQueueIndex/this.obstacleQueue.length}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.meshNodes}visualize(){const t=this.obstacleQueueIndex\u003cthis.obstacleQueue.length?this.obstacleQueue[this.obstacleQueueIndex]??null:null,e=this.obstacleQueue.slice(0,this.obstacleQueueIndex),n=t?this.obstacleQueue.slice(this.obstacleQueueIndex+1):[];return{rects:[...e.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(160,160,160,0.10)\",stroke:\"rgba(160,160,160,0.35)\",label:`processed ${t.obstacleId??\"obstacle\"}`})),...t?[{center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.22)\",stroke:\"rgba(255,140,0,0.75)\",label:`active ${t.obstacleId??\"obstacle\"}`}]:[],...n.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,0,0,0.05)\",stroke:\"rgba(255,0,0,0.22)\",label:`pending ${t.obstacleId??\"obstacle\"}`})),...this.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.18)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.45)\":\"rgba(0,120,255,0.45)\"}))]}}};dU.register(class extends Dt{constructor(t){super(t),this.inputProblem=t}inputProblem;static componentKind=\"bga\";initialTopologySolver;removeMeshNodeOverlappingWithUnmarkedObstacle;gapfillDueToNodeRemoval;mergeMeshNodes;markedComponentObstacles=[];unmarkedComponentObstacles=[];pipelineDef=[Lt(\"initialTopologySolver\",YU,t=\u003e[{srj:t.inputProblem.inputSrj,componentBounds:t.inputProblem.detectedComponent.bounds,componentId:t.inputProblem.detectedComponent.componentId,markedComponentObstacles:t.markedComponentObstacles,unmarkedComponentObstacles:t.unmarkedComponentObstacles,viaDiameter:t.inputProblem.viaDiameter}]),Lt(\"removeMeshNodeOverlappingWithUnmarkedObstacle\",ZU,t=\u003e[{meshNodes:t.initialTopologySolver.getOutput(),obstacles:t.unmarkedComponentObstacles,layerCount:t.inputProblem.inputSrj.layerCount}]),Lt(\"gapfillDueToNodeRemoval\",TU,t=\u003e[{meshNodes:t.removeMeshNodeOverlappingWithUnmarkedObstacle.getOutput(),unmarkedComponentObstacles:t.unmarkedComponentObstacles,layerCount:t.inputProblem.inputSrj.layerCount}]),Lt(\"mergeMeshNodes\",UU,t=\u003e[{meshNodes:t.gapfillDueToNodeRemoval.getOutput(),layerCount:t.inputProblem.inputSrj.layerCount}])];_setup(){const t=this.inputProblem.detectedComponent.bounds,e=this.inputProblem.detectedComponent.componentId,n=[],o=[];for(const i of this.inputProblem.inputSrj.obstacles){const r=Ve(i);Xe(t,r)\u0026\u0026(i.componentId!==e?o.push(i):n.push(i))}this.markedComponentObstacles=n,this.unmarkedComponentObstacles=o}getConstructorParams(){return[this.inputProblem]}getOutput(){return{routingRegions:this.mergeMeshNodes?.getOutput()??this.gapfillDueToNodeRemoval?.getOutput()??this.removeMeshNodeOverlappingWithUnmarkedObstacle?.getOutput()??[]}}initialVisualize(){return{rects:[{center:{x:(this.inputProblem.detectedComponent.bounds.minX+this.inputProblem.detectedComponent.bounds.maxX)/2,y:(this.inputProblem.detectedComponent.bounds.minY+this.inputProblem.detectedComponent.bounds.maxY)/2},width:this.inputProblem.detectedComponent.bounds.maxX-this.inputProblem.detectedComponent.bounds.minX,height:this.inputProblem.detectedComponent.bounds.maxY-this.inputProblem.detectedComponent.bounds.minY,fill:\"rgba(0,0,0,0)\",stroke:\"rgba(30,30,30,0.65)\",label:`bga ${this.inputProblem.detectedComponent.componentId}`},...this.markedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,0,0,0.18)\",stroke:\"rgba(255,0,0,0.52)\",label:`pad ${t.obstacleId??\"obstacle\"}`})),...this.unmarkedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.14)\",stroke:\"rgba(255,140,0,0.42)\",label:`foreign ${t.obstacleId??\"obstacle\"}`}))]}}finalVisualize(){return{rects:this.getOutput().routingRegions.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.16)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.36)\":\"rgba(0,120,255,0.42)\"}))}}});var qU=1e-6;function JU(t,e){return t.__zLayers\u0026\u0026t.__zLayers.length\u003e0?Lo(t.__zLayers,e):Do(t.layers,e)}function KU(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(let t=1;t\u003ce.length;t++){const o=e[t]-e[t-1];o\u003eqU\u0026\u0026n.push(o)}const o=n.length\u003e0?Math.max(qU,Math.min(...n)/4):.001,i=[];for(const t of e){const e=i[i.length-1];(void 0===e||Math.abs(t-e)\u003eo)\u0026\u0026i.push(t)}return i}function QU(t){return Array.from({length:Math.max(0,t)},(t,e)=\u003ee)}var tZ=1e-6;function eZ(t){return t.maxX-t.minX\u003etZ\u0026\u0026t.maxY-t.minY\u003etZ}function nZ(t){return function(t){const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return e\u003c=0?0:n/e}(t)\u003e=1.5}function oZ(t,e){const n=[{side:\"top\",distance:Math.abs(t.center.y-e.minY)},{side:\"right\",distance:Math.abs(e.maxX-t.center.x)},{side:\"bottom\",distance:Math.abs(e.maxY-t.center.y)},{side:\"left\",distance:Math.abs(t.center.x-e.minX)}];return n.sort((t,e)=\u003et.distance-e.distance),n[0].side}function iZ(t,e){return t.map((t,n)=\u003e({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e)}))}function rZ(t,e){return t.map((t,n)=\u003e({key:`thermal-pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e)}))}function sZ(t,e){return!!eZ(t)\u0026\u0026Math.min(t.maxX-t.minX,t.maxY-t.minY)\u003c=e}function aZ({side:t,sideObstacles:e,bounds:n,innerBounds:o,narrowThreshold:i}){const r=[];for(let s=0;s\u003ce.length-1;s++){const a=Ee(e[s]),c=Ee(e[s+1]);let l;l=\"top\"===t?{minX:a.maxX,maxX:c.minX,minY:n.minY,maxY:o.minY}:\"right\"===t?{minX:o.maxX,maxX:n.maxX,minY:a.maxY,maxY:c.minY}:\"bottom\"===t?{minX:a.maxX,maxX:c.minX,minY:o.maxY,maxY:n.maxY}:{minX:n.minX,maxX:o.minX,minY:a.maxY,maxY:c.minY},r.push({key:`${t}-gap-${s}`,bounds:l,regionType:\"pad-gap\",isNarrowPadGap:sZ(l,i)})}return r}function cZ({side:t,sideObstacles:e,thermalPadBounds:n,narrowThreshold:o}){const i=[];for(let r=0;r\u003ce.length;r++){const s=Ee(e[r]),a=e[r-1]?Ee(e[r-1]):null,c=e[r+1]?Ee(e[r+1]):null;let l;l=\"top\"===t?{minX:a?(a.maxX+s.minX)/2:s.minX,maxX:c?(s.maxX+c.minX)/2:s.maxX,minY:s.maxY,maxY:n.minY}:\"right\"===t?{minX:n.maxX,maxX:s.minX,minY:a?(a.maxY+s.minY)/2:s.minY,maxY:c?(s.maxY+c.minY)/2:s.maxY}:\"bottom\"===t?{minX:a?(a.maxX+s.minX)/2:s.minX,maxX:c?(s.maxX+c.minX)/2:s.maxX,minY:n.maxY,maxY:s.minY}:{minX:s.maxX,maxX:n.minX,minY:a?(a.maxY+s.minY)/2:s.minY,maxY:c?(s.maxY+c.minY)/2:s.maxY},i.push({key:`inner-${t}-pad-${r}`,bounds:l,regionType:\"pad-gap\",isNarrowPadGap:sZ(l,o)})}return i}function lZ({bounds:t,innerBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:\"corner-nw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-top\",regionType:\"corner\",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:\"corner-ne-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-top\",regionType:\"corner\",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:\"corner-se-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-se-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:\"corner-se-bottom\",regionType:\"corner\",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-bottom\",regionType:\"corner\",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}function dZ({innerBounds:t,thermalPadBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:\"inner-corner-nw-core\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-nw-top\",regionType:\"corner\",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-nw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:\"inner-corner-ne-core\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-ne-top\",regionType:\"corner\",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-ne-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:\"inner-corner-se-core\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-se-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:\"inner-corner-se-bottom\",regionType:\"corner\",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-sw-core\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-sw-bottom\",regionType:\"corner\",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-sw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind=\"qfp_thermalpad\";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=\u003et.componentId===o),s=r.length\u003e0?r:e,{padRingObstacles:a,thermalPadObstacles:c}=function(t){return{padRingObstacles:t.filter(nZ),thermalPadObstacles:t.filter(t=\u003e!nZ(t))}}(s),l=function(t,e){const n={top:[],right:[],bottom:[],left:[]};for(const o of t)n[oZ(o,e)].push(o);return n.top.sort((t,e)=\u003et.center.x-e.center.x),n.bottom.sort((t,e)=\u003et.center.x-e.center.x),n.left.sort((t,e)=\u003et.center.y-e.center.y),n.right.sort((t,e)=\u003et.center.y-e.center.y),n}(a,n),d=function({bounds:t,sideGroups:e}){return{minX:e.left.length\u003e0?Math.max(...e.left.map(t=\u003eEe(t).maxX)):t.minX,maxX:e.right.length\u003e0?Math.min(...e.right.map(t=\u003eEe(t).minX)):t.maxX,minY:e.top.length\u003e0?Math.max(...e.top.map(t=\u003eEe(t).maxY)):t.minY,maxY:e.bottom.length\u003e0?Math.min(...e.bottom.map(t=\u003eEe(t).minY)):t.maxY}}({bounds:n,sideGroups:l}),h=function(t){return 0===t.length?null:t.reduce((t,e)=\u003e{const n=Ee(e);return{minX:Math.min(t.minX,n.minX),maxX:Math.max(t.maxX,n.maxX),minY:Math.min(t.minY,n.minY),maxY:Math.max(t.maxY,n.maxY)}},Ee(t[0]))}(c);if(!h)return this.failed=!0,void(this.error=\"QfpThermalPadTopologyGeneratorSolver requires a thermal pad\");const u=o,p=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,m=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,g=p+2*m,f=this.inputProblem.inputSrj.minTraceWidth+2*m,y=[...iZ(a,t),...rZ(c,t),...aZ({side:\"top\",sideObstacles:l.top,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:\"right\",sideObstacles:l.right,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:\"bottom\",sideObstacles:l.bottom,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:\"left\",sideObstacles:l.left,bounds:n,innerBounds:d,narrowThreshold:f}),...cZ({side:\"top\",sideObstacles:l.top,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:\"right\",sideObstacles:l.right,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:\"bottom\",sideObstacles:l.bottom,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:\"left\",sideObstacles:l.left,thermalPadBounds:h,narrowThreshold:f}),...dZ({innerBounds:d,thermalPadBounds:h,sideGroups:l}),...lZ({bounds:n,innerBounds:d,sideGroups:l})].flatMap(t=\u003efunction({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,isNarrowPadGap:r=!1,obstacleZ:s=[]}){if(!eZ(e))return[];const a=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),c=Math.min(a.width,a.height)\u003eo,l=c?[{availableZ:n.filter(t=\u003e!s.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=\u003es.includes(t)),containsObstacle:!0}].filter(t=\u003et.availableZ.length\u003e0):n.map(t=\u003e({availableZ:[t],containsObstacle:s.includes(t)}));return l.map(e=\u003e({capacityMeshNodeId:1===l.length?t:c?`${t}:${e.containsObstacle?\"obstacle\":\"free\"}`:`${t}:z${e.availableZ[0]}`,center:a.center,width:a.width,height:a.height,layer:`z${e.availableZ.join(\",\")}`,availableZ:e.availableZ,_qfpRegionType:i,_isNarrowQfpPadGap:r,_containsObstacle:e.containsObstacle}))}({nodeId:`qfp_thermalpad:${u}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:g,regionType:t.regionType,isNarrowPadGap:t.isNarrowPadGap,obstacleZ:t.obstacleZ}));this.output={routingRegions:y},this.stats={componentId:o,layerCount:t,viaDiameter:p,obstacleMargin:m,multiLayerThreshold:g,narrowPadGapThreshold:f,thermalPadCount:c.length,perimeterPadCount:a.length,innerCornerRectCount:y.filter(t=\u003et.capacityMeshNodeId.includes(\":inner-corner-\")).length,narrowPadGapNodeCount:y.filter(t=\u003et._isNarrowQfpPadGap).length,topPadCount:l.top.length,rightPadCount:l.right.length,bottomPadCount:l.bottom.length,leftPadCount:l.left.length,multiLayerNodeCount:y.filter(t=\u003et.availableZ.length\u003e1).length,totalMeshNodeCount:y.length},this.solved=!0}getOutput(){if(!this.output)throw new Error(\"QfpThermalPadTopologyGeneratorSolver has not solved yet\");return this.output}});var hZ=1e-6;function uZ(t){return t.maxX-t.minX\u003ehZ\u0026\u0026t.maxY-t.minY\u003ehZ}function pZ(t,e){const n=[{side:\"top\",distance:Math.abs(t.center.y-e.minY)},{side:\"right\",distance:Math.abs(e.maxX-t.center.x)},{side:\"bottom\",distance:Math.abs(e.maxY-t.center.y)},{side:\"left\",distance:Math.abs(t.center.x-e.minX)}];return n.sort((t,e)=\u003et.distance-e.distance),n[0].side}function mZ(t,e){return t.map((t,n)=\u003e({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e),connectedTo:[...t.connectedTo]}))}function gZ(t,e){return!!uZ(t)\u0026\u0026Math.min(t.maxX-t.minX,t.maxY-t.minY)\u003c=e}function fZ({side:t,sideObstacles:e,bounds:n,centralBounds:o,narrowThreshold:i}){const r=[];for(let s=0;s\u003ce.length-1;s++){const a=Ee(e[s]),c=Ee(e[s+1]);let l;l=\"top\"===t?{minX:a.maxX,maxX:c.minX,minY:n.minY,maxY:o.minY}:\"right\"===t?{minX:o.maxX,maxX:n.maxX,minY:a.maxY,maxY:c.minY}:\"bottom\"===t?{minX:a.maxX,maxX:c.minX,minY:o.maxY,maxY:n.maxY}:{minX:n.minX,maxX:o.minX,minY:a.maxY,maxY:c.minY},r.push({key:`${t}-gap-${s}`,bounds:l,regionType:\"pad-gap\",isNarrowPadGap:gZ(l,i)})}return r}function yZ({bounds:t,centralBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:\"corner-nw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-top\",regionType:\"corner\",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:\"corner-ne-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-top\",regionType:\"corner\",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:\"corner-se-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-se-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:\"corner-se-bottom\",regionType:\"corner\",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-bottom\",regionType:\"corner\",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind=\"qfp\";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=\u003et.componentId===o),s=r.length\u003e0?r:e,a=function(t,e){const n={top:[],right:[],bottom:[],left:[]};for(const o of t)n[pZ(o,e)].push(o);return n.top.sort((t,e)=\u003et.center.x-e.center.x),n.bottom.sort((t,e)=\u003et.center.x-e.center.x),n.left.sort((t,e)=\u003et.center.y-e.center.y),n.right.sort((t,e)=\u003et.center.y-e.center.y),n}(s,n),c=function({bounds:t,sideGroups:e}){return{minX:e.left.length\u003e0?Math.max(...e.left.map(t=\u003eEe(t).maxX)):t.minX,maxX:e.right.length\u003e0?Math.min(...e.right.map(t=\u003eEe(t).minX)):t.maxX,minY:e.top.length\u003e0?Math.max(...e.top.map(t=\u003eEe(t).maxY)):t.minY,maxY:e.bottom.length\u003e0?Math.min(...e.bottom.map(t=\u003eEe(t).minY)):t.maxY}}({bounds:n,sideGroups:a}),l=o,d=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,h=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,u=d+2*h,p=this.inputProblem.inputSrj.minTraceWidth+2*h,m=[{key:\"center\",bounds:c,regionType:\"center\"},...mZ(s,t),...fZ({side:\"top\",sideObstacles:a.top,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:\"right\",sideObstacles:a.right,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:\"bottom\",sideObstacles:a.bottom,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:\"left\",sideObstacles:a.left,bounds:n,centralBounds:c,narrowThreshold:p}),...yZ({bounds:n,centralBounds:c,sideGroups:a})].flatMap(t=\u003efunction({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,isNarrowPadGap:r=!1,obstacleZ:s=[],connectedTo:a}){if(!uZ(e))return[];const c=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),l=Math.min(c.width,c.height)\u003eo,d=l?[{availableZ:n.filter(t=\u003e!s.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=\u003es.includes(t)),containsObstacle:!0}].filter(t=\u003et.availableZ.length\u003e0):n.map(t=\u003e({availableZ:[t],containsObstacle:s.includes(t)}));return d.map(e=\u003e({capacityMeshNodeId:1===d.length?t:l?`${t}:${e.containsObstacle?\"obstacle\":\"free\"}`:`${t}:z${e.availableZ[0]}`,center:c.center,width:c.width,height:c.height,layer:`z${e.availableZ.join(\",\")}`,availableZ:e.availableZ,_qfpRegionType:i,_isNarrowQfpPadGap:r,_containsObstacle:e.containsObstacle,_connectedTo:e.containsObstacle?a:void 0}))}({nodeId:`qfp:${l}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:u,regionType:t.regionType,isNarrowPadGap:t.isNarrowPadGap,obstacleZ:t.obstacleZ,connectedTo:t.connectedTo}));this.output={routingRegions:m},this.stats={componentId:o,layerCount:t,viaDiameter:d,obstacleMargin:h,multiLayerThreshold:u,narrowPadGapThreshold:p,narrowPadGapNodeCount:m.filter(t=\u003et._isNarrowQfpPadGap).length,topPadCount:a.top.length,rightPadCount:a.right.length,bottomPadCount:a.bottom.length,leftPadCount:a.left.length,multiLayerNodeCount:m.filter(t=\u003et.availableZ.length\u003e1).length,totalMeshNodeCount:m.length},this.solved=!0}getOutput(){if(!this.output)throw new Error(\"QfpTopologyGeneratorSolver has not solved yet\");return this.output}});var _Z=1e-6;function bZ({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,obstacleZ:r=[],connectedTo:s}){if(!function(t){return t.maxX-t.minX\u003e_Z\u0026\u0026t.maxY-t.minY\u003e_Z}(e))return[];const a=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),c=Math.min(a.width,a.height)\u003eo,l=c?[{availableZ:n.filter(t=\u003e!r.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=\u003er.includes(t)),containsObstacle:!0}].filter(t=\u003et.availableZ.length\u003e0):n.map(t=\u003e({availableZ:[t],containsObstacle:r.includes(t)}));return l.map(e=\u003e({capacityMeshNodeId:1===l.length?t:c?`${t}:${e.containsObstacle?\"obstacle\":\"free\"}`:`${t}:z${e.availableZ[0]}`,center:a.center,width:a.width,height:a.height,layer:`z${e.availableZ.join(\",\")}`,availableZ:e.availableZ,_soicRegionType:i,_containsObstacle:e.containsObstacle,_connectedTo:e.containsObstacle?s:void 0}))}function xZ(t,e){let n=0,o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ce.length;i++){const r=Math.abs(t-e[i]);r\u003co\u0026\u0026(n=i,o=r)}return n}function vZ(t,e){return t.map((t,n)=\u003e({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e),connectedTo:[...t.connectedTo]}))}function SZ(t,e){if(t.componentId!==e.componentId)return!1;const{bounds:n}=e;return t.center.x\u003e=n.minX\u0026\u0026t.center.x\u003c=n.maxX\u0026\u0026t.center.y\u003e=n.minY\u0026\u0026t.center.y\u003c=n.maxY}function IZ({detectedComponent:t,inputSrj:e}){const n=e.obstacles.filter(e=\u003eSZ(e,t)),o=Array.from({length:e.layerCount},(t,e)=\u003ee),i=o.map(t=\u003evo(t,e.layerCount)),r=Array.from(new Set(n.flatMap(t=\u003et.connectedTo))),{bounds:s}=t;return{obstacleId:`${t.componentId}_component_bounds`,componentId:t.componentId,type:\"rect\",layers:i,__zLayers:o,center:{x:(s.minX+s.maxX)/2,y:(s.minY+s.maxY)/2},width:s.maxX-s.minX,height:s.maxY-s.minY,connectedTo:r}}function CZ(t){if(0===t.length)return{minX:0,maxX:0,minY:0,maxY:0};let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t){const t=Ee(r);e=Math.min(e,t.minX),n=Math.max(n,t.maxX),o=Math.min(o,t.minY),i=Math.max(i,t.maxY)}return{minX:e,maxX:n,minY:o,maxY:i}}function PZ(t){const e=t.componentDetectionOutput??[],n=function({detectedComponents:t,inputSrj:e}){return t.map(t=\u003e{const n=e.obstacles.filter(e=\u003eSZ(e,t));return{componentId:t.componentId,componentKind:t.componentKind,memberObstacleIds:n.map((e,n)=\u003ee.obstacleId??`${t.componentId}:member:${n}`),memberObstacles:n,replacementObstacle:IZ({detectedComponent:t,inputSrj:e})}})}({detectedComponents:e,inputSrj:t.inputSrj}),o=t.globalNoConnectionSrj??(e.length\u003e0?function({detectedComponents:t,inputSrj:e}){return{...structuredClone(e),obstacles:[...e.obstacles.filter(e=\u003e!t.some(t=\u003eSZ(e,t))),...t.map(t=\u003eIZ({detectedComponent:t,inputSrj:e}))]}}({detectedComponents:e,inputSrj:t.inputSrj}):t.inputSrj)??t.brokenSrj?.componentsAsObstaclesSrj,i=t.components??n??t.brokenSrj?.components??[];if(!o)throw new Error(\"MultiGraphTopologyPlannerSolver requires globalNoConnectionSrj or detected components\");return{globalNoConnectionSrj:o,components:i}}function MZ({rects:t,components:e}){return t\u0026\u00260!==e.length?t.filter(t=\u003e!function(t){return\"string\"==typeof t.label\u0026\u0026t.label.startsWith(\"node \")}(t)||!e.some(e=\u003efunction({rect:t,obstacle:e}){if(!t.center||void 0===t.width||void 0===t.height)return!1;const n=1e-9,o=Ve({center:t.center,width:t.width,height:t.height}),i=Ve({center:e.center,width:e.width,height:e.height});return NZ({bounds:o,outerBounds:i,epsilon:n})}({rect:t,obstacle:e.replacementObstacle}))):t}function NZ({bounds:t,outerBounds:e,epsilon:n}){return t.minX\u003e=e.minX-n\u0026\u0026t.maxX\u003c=e.maxX+n\u0026\u0026t.minY\u003e=e.minY-n\u0026\u0026t.maxY\u003c=e.maxY+n}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind=\"soic\";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=\u003et.componentId===o),s=r.length\u003e0?r:e,a=function(t){const e=KU(t.map(t=\u003et.center.y)).length;return 2===KU(t.map(t=\u003et.center.x)).length\u0026\u00262!==e?\"vertical-columns\":\"horizontal-rows\"}(s),c=function({obstacles:t,orientation:e}){const n={left:[],right:[],top:[],bottom:[]};if(\"vertical-columns\"===e){const e=KU(t.map(t=\u003et.center.x));for(const o of t)n[0===xZ(o.center.x,e)?\"left\":\"right\"].push(o);return n.left.sort((t,e)=\u003et.center.y-e.center.y),n.right.sort((t,e)=\u003et.center.y-e.center.y),n}const o=KU(t.map(t=\u003et.center.y));for(const e of t)n[0===xZ(e.center.y,o)?\"top\":\"bottom\"].push(e);return n.top.sort((t,e)=\u003et.center.x-e.center.x),n.bottom.sort((t,e)=\u003et.center.x-e.center.x),n}({obstacles:s,orientation:a}),l=function({bounds:t,orientation:e,sideGroups:n}){return\"vertical-columns\"===e?{minX:Math.max(...n.left.map(t=\u003eEe(t).maxX)),maxX:Math.min(...n.right.map(t=\u003eEe(t).minX)),minY:t.minY,maxY:t.maxY}:{minX:t.minX,maxX:t.maxX,minY:Math.max(...n.top.map(t=\u003eEe(t).maxY)),maxY:Math.min(...n.bottom.map(t=\u003eEe(t).minY))}}({bounds:n,orientation:a,sideGroups:c}),d=o,h=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,u=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,p=2*(h+u),m=\"vertical-columns\"===a?[\"left\",\"right\"]:[\"top\",\"bottom\"],g=[{key:\"center\",bounds:l,regionType:\"center\"},...vZ(s,t),...m.flatMap(t=\u003efunction({side:t,sideObstacles:e,bounds:n,centralBounds:o}){const i=[];for(let r=0;r\u003ce.length-1;r++){const s=Ee(e[r]),a=Ee(e[r+1]);let c;c=\"left\"===t?{minX:n.minX,maxX:o.minX,minY:s.maxY,maxY:a.minY}:\"right\"===t?{minX:o.maxX,maxX:n.maxX,minY:s.maxY,maxY:a.minY}:\"top\"===t?{minX:s.maxX,maxX:a.minX,minY:n.minY,maxY:o.minY}:{minX:s.maxX,maxX:a.minX,minY:o.maxY,maxY:n.maxY},i.push({key:`${t}-gap-${r}`,bounds:c,regionType:\"pad-gap\"})}return i}({side:t,sideObstacles:c[t],bounds:n,centralBounds:l}))],f=g.flatMap(t=\u003ebZ({nodeId:`soic:${d}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:p,regionType:t.regionType,obstacleZ:t.obstacleZ,connectedTo:t.connectedTo}));this.output={routingRegions:f},this.stats={componentId:o,layerCount:t,orientation:a,viaDiameter:h,obstacleMargin:u,multiLayerThreshold:p,firstSidePadCount:c[m[0]].length,secondSidePadCount:c[m[1]].length,multiLayerNodeCount:f.filter(t=\u003et.availableZ.length\u003e1).length,totalMeshNodeCount:f.length},this.solved=!0}getOutput(){if(!this.output)throw new Error(\"SoicTopologyGeneratorSolver has not solved yet\");return this.output}});var wZ=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;activeSubSolver=null;currentIndex=0;componentMeshNodes=[];getConstructorParams(){return[this.inputProblem]}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.failed)return this.error=this.activeSubSolver.error,this.failed=!0,void(this.activeSubSolver=null);if(!this.activeSubSolver.solved)return;return this.componentMeshNodes.push(this.activeSubSolver.getOutput().routingRegions),this.currentIndex+=1,void(this.activeSubSolver=null)}if(this.currentIndex\u003e=this.inputProblem.componentSrjs.length)return void(this.solved=!0);const t=this.inputProblem.componentKinds[this.currentIndex],e=this.inputProblem.componentSrjs[this.currentIndex],n={inputSrj:e,detectedComponent:{componentId:this.inputProblem.componentIds[this.currentIndex],componentKind:t,bounds:{__type:\"rect\",...e.bounds}},viaDiameter:this.inputProblem.viaDiameter,obstacleMargin:this.inputProblem.obstacleMargin};this.activeSubSolver=dU.create(n)}getOutput(){return{componentMeshNodes:this.componentMeshNodes}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.inputProblem.componentSrjs[this.currentIndex]??null,e=this.componentMeshNodes.flatMap(t=\u003et);return{rects:[...t?[{center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,fill:\"rgba(0,0,0,0)\",stroke:\"rgba(255,140,0,0.72)\",label:`active component ${this.inputProblem.componentIds[this.currentIndex]??this.currentIndex}`},...t.obstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.10)\",stroke:\"rgba(255,140,0,0.30)\",label:t.obstacleId??t.componentId??\"obstacle\"}))]:[],...e.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.14)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.34)\":\"rgba(0,120,255,0.38)\"}))]}}},TZ=.001;function RZ(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(const t of e){const e=n[n.length-1];(void 0===e||Math.abs(t-e)\u003eTZ)\u0026\u0026n.push(t)}return n}function EZ(t){const e=Math.min(...t),n=Math.max(...t);return!(e\u003c=0)\u0026\u0026n/e\u003c=1.01}function AZ(t){if(!function(t){return EZ(t.map(t=\u003et.width))\u0026\u0026EZ(t.map(t=\u003et.height))}(t))return!1;if(!function(t){return t.every(t=\u003e{const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return!(e\u003c=0)\u0026\u0026n/e\u003c=1.5})}(t))return!1;const e=RZ(t.map(t=\u003et.center.y)),n=RZ(t.map(t=\u003et.center.x)),o=e.length,i=n.length;if(o\u003c3||i\u003c3)return!1;const r=o*i;return!((r\u003e0?t.length/r:0)\u003c.5)\u0026\u0026!!function(t,e,n){if(e.length\u003c3)return!1;if(n.length\u003c3)return!1;const o=new Set(e.slice(1,-1)),i=new Set(n.slice(1,-1));let r=0;for(const e of t)o.has(e.center.y)\u0026\u0026i.has(e.center.x)\u0026\u0026(r+=1);return r\u003e=1}(t,e,n)}function OZ(t){return[Math.round(t.width/TZ),Math.round(t.height/TZ),t.layers.join(\",\")].join(\":\")}function kZ(t){if(t.length\u003c3)return!1;const e=[...t].sort((t,e)=\u003et-e),n=e[1]-e[0];return!(n\u003c=TZ)\u0026\u0026e.every((t,o)=\u003e0===o||Math.abs(t-e[o-1]-n)\u003c=TZ)}function LZ(t){const e=function(t){const e=new Map;for(const n of t){const t=Math.round(n.center.y/TZ),o=Math.round(n.center.x/TZ),i=e.get(t)??{y:n.center.y,obstaclesByX:new Map};i.obstaclesByX.set(o,n),e.set(t,i)}return[...e.values()]}(t);let n=[];for(const t of e){const o=[...t.obstaclesByX.keys()];if(!kZ([...t.obstaclesByX.values()].map(t=\u003et.center.x)))continue;const i=e.filter(t=\u003eo.every(e=\u003et.obstaclesByX.has(e)));if(!kZ(i.map(t=\u003et.y)))continue;const r=i.flatMap(t=\u003eo.map(e=\u003et.obstaclesByX.get(e)));r.length\u003en.length\u0026\u0026(n=r)}return n}function DZ(t){if(AZ(t))return t;const e=Map.groupBy(t,OZ);let n=[];for(const t of e.values()){const e=LZ(t);e.length\u003en.length\u0026\u0026(n=e)}return n.length\u003e0?n:null}function zZ(t){const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return e\u003e0\u0026\u0026n/e\u003e=1.5}function FZ({perimeterPadObstacles:t,thermalPadObstacles:e}){if(0===e.length)return!0;if(e.length\u003e4)return!1;const n=CZ(t),o=n.maxX-n.minX,i=n.maxY-n.minY,r=n.minX+.2*o,s=n.maxX-.2*o,a=n.minY+.2*i,c=n.maxY-.2*i,l=Math.min(...t.map(t=\u003eMath.min(t.width,t.height)));return e.every(t=\u003e{const e=Math.min(t.width,t.height);return t.center.x\u003e=r\u0026\u0026t.center.x\u003c=s\u0026\u0026t.center.y\u003e=a\u0026\u0026t.center.y\u003c=c\u0026\u0026e\u003el})}function BZ(t){if(t.length\u003c12)return!1;if(t.length\u003e32)return!1;const{counts:e,maxNearestSideRatio:n}=function(t){const e=CZ(t),n=e.maxX-e.minX,o=e.maxY-e.minY,i={top:0,right:0,bottom:0,left:0};if(n\u003c=0||o\u003c=0)return{counts:i,maxNearestSideRatio:1};let r=0;for(const s of t){const t=s.width\u003es.height,a=[{side:\"top\",distance:Math.abs(s.center.y-e.minY),axisSpan:o,orientationMatches:!t},{side:\"right\",distance:Math.abs(e.maxX-s.center.x),axisSpan:n,orientationMatches:t},{side:\"bottom\",distance:Math.abs(e.maxY-s.center.y),axisSpan:o,orientationMatches:!t},{side:\"left\",distance:Math.abs(s.center.x-e.minX),axisSpan:n,orientationMatches:t}].filter(t=\u003et.orientationMatches).sort((t,e)=\u003et.distance-e.distance)[0];i[a.side]+=1,r=Math.max(r,a.distance/a.axisSpan)}return{counts:i,maxNearestSideRatio:r}}(t);return e.top\u003e=3\u0026\u0026e.right\u003e=3\u0026\u0026e.bottom\u003e=3\u0026\u0026e.left\u003e=3\u0026\u0026n\u003c=.25}function jZ(t){const e=function(t){return t.filter(zZ)}(t);return{perimeterPadObstacles:e,thermalPadObstacles:t.filter(t=\u003e!zZ(t))}}function $Z(t){const e=Math.min(...t),n=Math.max(...t);return!(e\u003c=0)\u0026\u0026n/e\u003c=1.01}function YZ(t,e){let n=0,o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ce.length;i++){const r=Math.abs(t-e[i]);r\u003co\u0026\u0026(n=i,o=r)}return n}function XZ({memberObstacles:t,inputSrj:e}){if(!function(t){return $Z(t.map(t=\u003et.width))\u0026\u0026$Z(t.map(t=\u003et.height))}(t))return!1;const n=RZ(t.map(t=\u003et.center.y)),o=RZ(t.map(t=\u003et.center.x));if(!(2===n.length\u0026\u0026o.length\u003e=4||2===o.length\u0026\u0026n.length\u003e=4))return!1;const i=function({memberObstacles:t,rowAxisValues:e,columnAxisValues:n}){if(2===e.length\u0026\u0026n.length\u003e=4){const n=[[],[]];for(const o of t)n[YZ(o.center.y,e)].push(o);return Math.min(...n[1].map(t=\u003et.center.y-t.height/2))-Math.max(...n[0].map(t=\u003et.center.y+t.height/2))}if(2===n.length\u0026\u0026e.length\u003e=4){const e=[[],[]];for(const o of t)e[YZ(o.center.x,n)].push(o);return Math.min(...e[1].map(t=\u003et.center.x-t.width/2))-Math.max(...e[0].map(t=\u003et.center.x+t.width/2))}return null}({memberObstacles:t,rowAxisValues:n,columnAxisValues:o});if(null===i)return!1;return i\u003e2*(Yo(e).padDiameter+(e.defaultObstacleMargin??.15))}var VZ=[class t{constructor(t){this.params=t}params;static componentKind=\"qfp_thermalpad\";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){const{perimeterPadObstacles:e,thermalPadObstacles:n}=jZ(t);return 0!==n.length\u0026\u0026!!BZ(e)\u0026\u0026FZ({perimeterPadObstacles:e,thermalPadObstacles:n})}(t)}},class t{constructor(t){this.params=t}params;static componentKind=\"qfp\";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){const{perimeterPadObstacles:e,thermalPadObstacles:n}=jZ(t);return!(n.length\u003e0)\u0026\u0026!!FZ({perimeterPadObstacles:e,thermalPadObstacles:n})\u0026\u0026BZ(e)}(t)}},class t{constructor(t){this.params=t}params;static componentKind=\"soic\";componentKind=t.componentKind;static isMatch(t){return XZ(t)}},class t{constructor(t){this.params=t}params;static componentKind=\"bga\";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){return null!==DZ(t)}(t)}}];function WZ(t){return function(t){for(const e of VZ)if(e.isMatch(t))return new e(t);return null}(t)?.componentKind??null}var HZ=class extends kt{inputSrj;initialized=!1;groupedComponentObstacles={};groupedComponentKinds={};unprocessedComponentIds=[];detectedComponents=[];currentComponentId=null;currentMemberObstacles=[];output=null;constructor({inputSrj:t}){super(),this.inputSrj=t}getConstructorParams(){return[{inputSrj:this.inputSrj}]}_step(){this.initialized?this.output?this.solved=!0:null!==this.currentComponentId||this.unprocessedComponentIds.length\u003e0?this.processNextComponent():(this.finalizeOutput(),this.solved=!0):this.initializeDetectionState()}getOutput(){if(!this.output)throw new Error(\"ComponentDetectionSolver has not solved yet\");return this.output}visualize(){const t=[];t.push(...this.inputSrj.obstacles.filter(t=\u003e!t.componentId).map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(120, 120, 120, 0.10)\",stroke:\"rgba(120, 120, 120, 0.40)\",label:t.obstacleId,layer:t.layers.join(\",\"),step:0})));const e=new Set(this.detectedComponents.map(t=\u003et.componentId));for(const n of this.inputSrj.obstacles){if(!n.componentId)continue;if(e.has(n.componentId))continue;const o=n.componentId===this.currentComponentId,i=Ro(n.componentId),r=this.groupedComponentKinds[n.componentId];t.push({center:n.center,width:n.width,height:n.height,fill:To(i,o?.55:.82),stroke:To(i,o?.1:.45),label:r?`${n.componentId} ${r.toUpperCase()}`:n.componentId,layer:n.layers.join(\",\"),step:o?1:0})}for(const e of this.detectedComponents){const n=Ro(e.componentId);t.push({center:{x:(e.bounds.minX+e.bounds.maxX)/2,y:(e.bounds.minY+e.bounds.maxY)/2},width:e.bounds.maxX-e.bounds.minX,height:e.bounds.maxY-e.bounds.minY,fill:To(n,.88),stroke:To(n,.1),label:`${e.componentId} ${e.componentKind.toUpperCase()} region`,step:2})}return{title:this.getVisualizationTitle(),rects:t,lines:[],points:[],circles:[]}}preview(){return this.visualize()}initializeDetectionState(){this.initialized=!0,this.groupedComponentKinds={},this.groupedComponentObstacles=this.groupObstaclesByComponentId({obstacles:this.inputSrj.obstacles}),this.unprocessedComponentIds=Object.keys(this.groupedComponentObstacles).sort(),this.detectedComponents=[],this.currentComponentId=null,this.currentMemberObstacles=[],this.output=null}processNextComponent(){if(!this.currentComponentId){const t=this.unprocessedComponentIds.shift();return t?(this.currentComponentId=t,void(this.currentMemberObstacles=this.groupedComponentObstacles[t]??[])):(this.currentComponentId=null,void(this.currentMemberObstacles=[]))}if(0===this.currentMemberObstacles.length)return this.currentComponentId=null,void(this.currentMemberObstacles=[]);this.detectedComponents.push(this.createDetectedComponent({componentId:this.currentComponentId,componentKind:this.groupedComponentKinds[this.currentComponentId],memberObstacles:this.currentMemberObstacles})),this.currentComponentId=null,this.currentMemberObstacles=[]}finalizeOutput(){this.output=this.detectedComponents.map(t=\u003e({...t,bounds:{...t.bounds}})),this.stats={initialized:this.initialized,totalComponentCount:Object.keys(this.groupedComponentObstacles).length,detectedComponentCount:this.detectedComponents.length,detectedBgaComponentCount:this.detectedComponents.filter(t=\u003e\"bga\"===t.componentKind).length,detectedQfpComponentCount:this.detectedComponents.filter(t=\u003e\"qfp\"===t.componentKind).length,detectedQfpComponentIds:this.detectedComponents.filter(t=\u003e\"qfp\"===t.componentKind).map(t=\u003et.componentId),detectedQfpThermalPadComponentCount:this.detectedComponents.filter(t=\u003e\"qfp_thermalpad\"===t.componentKind).length,detectedQfpThermalPadComponentIds:this.detectedComponents.filter(t=\u003e\"qfp_thermalpad\"===t.componentKind).map(t=\u003et.componentId),detectedSoicComponentCount:this.detectedComponents.filter(t=\u003e\"soic\"===t.componentKind).length,detectedSoicComponentIds:this.detectedComponents.filter(t=\u003e\"soic\"===t.componentKind).map(t=\u003et.componentId),remainingComponentCount:this.unprocessedComponentIds.length,hasActiveComponent:null!==this.currentComponentId}}groupObstaclesByComponentId({obstacles:t}){const e={},n={};for(const n of t)n.componentId\u0026\u0026(e[n.componentId]??=[],e[n.componentId].push(n));const o=Object.entries(e).flatMap(([t,e])=\u003e{const o=this.inputSrj.bounds;if(e.some(t=\u003e!NZ({bounds:Ee(t),outerBounds:o,epsilon:0})))return[];const i=WZ({memberObstacles:e,inputSrj:this.inputSrj});if(!i)return[];n[t]=i;return[[t,\"bga\"===i?DZ(e):e]]});return this.groupedComponentKinds=n,Object.fromEntries(o)}createDetectedComponent({componentId:t,componentKind:e,memberObstacles:n}){return{componentId:t,componentKind:e,bounds:{__type:\"rect\",...CZ(n)}}}getVisualizationTitle(){const t=Object.keys(this.groupedComponentObstacles).length||new Set(this.inputSrj.obstacles.map(t=\u003et.componentId).filter(t=\u003eBoolean(t))).size,e=this.detectedComponents.length;return this.initialized?this.output||this.solved?`Component Detection: done ${e}/${t}`:null!==this.currentComponentId||this.unprocessedComponentIds.length\u003e0?`Component Detection: ${e}/${t} processed`:`Component Detection: finalizing ${e}/${t}`:\"Component Detection: setup\"}},GZ=t=\u003et.componentId\u0026\u0026t.obstacleId?`${t.componentId}\\n${t.obstacleId}`:t.componentId??t.obstacleId??\"obstacle\",UZ=class extends Dt{rectBoundsComponentDetection;pipelineDef=[Lt(\"rectBoundsComponentDetection\",HZ,t=\u003e[{inputSrj:t.inputProblem.inputSrj}])];getConstructorParams(){return[this.inputProblem]}getOutput(){const t=this.getStageOutput(\"rectBoundsComponentDetection\");if(!t)throw new Error(\"ComponentDetectionSolver has not solved yet\");return t}initialVisualize(){const{bounds:t}=this.inputProblem.inputSrj;return{title:\"Component Detection: board and grouped component pads\",rects:[{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,fill:\"rgba(0, 0, 0, 0)\",stroke:\"rgba(40, 40, 40, 0.7)\",label:\"Board bounds\",step:0},...this.inputProblem.inputSrj.obstacles.map(t=\u003e{const e=t.componentId?Ro(t.componentId):null;return{center:t.center,width:t.width,height:t.height,fill:e?To(e,.72):\"rgba(120, 120, 120, 0.10)\",stroke:e?To(e,.28):\"rgba(120, 120, 120, 0.40)\",label:GZ(t),layer:t.layers.join(\",\"),step:t.componentId?1:0}})],lines:[],points:[],circles:[]}}},ZZ=1e-9;function qZ(t){return Ve({center:t.center,width:t.width,height:t.height})}function JZ(t,e){const n={minX:Math.max(t.minX,e.minX),maxX:Math.min(t.maxX,e.maxX),minY:Math.max(t.minY,e.minY),maxY:Math.min(t.maxY,e.maxY)};return KZ(n)?n:null}function KZ(t){const e=t.maxX-t.minX,n=t.maxY-t.minY,o=Number.isFinite(e)\u0026\u0026e\u003eZZ,i=Number.isFinite(n)\u0026\u0026n\u003eZZ;return o\u0026\u0026i}function QZ(t){!function(t){if(!Number.isInteger(t.layerCount))throw new Error(\"TopologyMergingSolver: layerCount must be an integer\");if(t.layerCount\u003c=0)throw new Error(\"TopologyMergingSolver: layerCount must be positive\");if(0===t.nodeGroups.length)throw new Error(\"TopologyMergingSolver: at least one node group is required\");const e=new Set;let n=0;for(const o of t.nodeGroups){if(e.has(o.groupId))throw new Error(`TopologyMergingSolver: duplicate topology group id \"${o.groupId}\"`);if(e.add(o.groupId),n+=o.nodes.length,0===o.nodes.length)throw new Error(`TopologyMergingSolver: topology group \"${o.groupId}\" is empty`);const i=new Set;for(const e of o.nodes){if(i.has(e.capacityMeshNodeId))throw new Error(`TopologyMergingSolver: duplicate node id \"${e.capacityMeshNodeId}\" in group \"${o.groupId}\"`);i.add(e.capacityMeshNodeId),tq({node:e,groupId:o.groupId,layerCount:t.layerCount})}}if(0===n)throw new Error(\"TopologyMergingSolver: topology node groups are empty\")}(t);const e=[],n=new Map;for(let o=0;o\u003ct.nodeGroups.length;o++){const i=t.nodeGroups[o];for(const t of i.nodes){const r={sourceKey:`${i.groupId}:${t.capacityMeshNodeId}`,groupIndex:o,node:t,bounds:qZ(t)};e.push(r),n.set(r.sourceKey,r)}}return{preparedNodes:e,preparedNodeBySourceKey:n}}function tq({node:t,groupId:e,layerCount:n}){if(!KZ(qZ(t)))throw new Error(`TopologyMergingSolver: node \"${t.capacityMeshNodeId}\" in group \"${e}\" has invalid bounds`);if(0===t.availableZ.length)throw new Error(`TopologyMergingSolver: node \"${t.capacityMeshNodeId}\" in group \"${e}\" has no available layers`);const o=[...new Set(t.availableZ)].sort((t,e)=\u003et-e),i=o.some(t=\u003e!Number.isInteger(t)||t\u003c0||t\u003e=n),r=o.length===t.availableZ.length\u0026\u0026o.every((e,n)=\u003ee===t.availableZ[n]);if(i||!r)throw new Error(`TopologyMergingSolver: node \"${t.capacityMeshNodeId}\" in group \"${e}\" has invalid or unsorted availableZ`)}var eq=1e-5,nq=4e-5;function oq({regions:t,preparedNodeBySourceKey:e,nodeGroups:n,provenance:o,preserveSourceIds:i=!0}){i\u0026\u0026(o.groupIndexesByNodeId.clear(),o.sourceKeysByNodeId.clear());const r=[...t].sort((t,e)=\u003et.bounds.minX-e.bounds.minX||t.bounds.minY-e.bounds.minY||t.bounds.maxX-e.bounds.maxX||t.bounds.maxY-e.bounds.maxY||t.availableZ[0]-e.availableZ[0]),s=new Set;return r.map((t,r)=\u003e{const a=t.sourceKeys.map(t=\u003e{const n=e.get(t);if(!n)throw new Error(`TopologyMergingSolver: missing source node for \"${t}\"`);return n}),c=a.map(({node:t})=\u003et),l=function({sourceNodes:t,isComponentTopologyNode:e}){if(1===t.length)return{_isComponentTopologyNode:!!e||t[0]._isComponentTopologyNode};const n=t.map(t=\u003et.capacityMeshNodeId),o=iq(t.map(t=\u003et._targetConnectionName),\"target connection\",n),i=iq(t.map(t=\u003et._offBoardConnectionId),\"off-board connection\",n),r=iq(t.map(t=\u003et._offboardNetName),\"off-board net\",n),s=Array.from(new Set(t.flatMap(t=\u003et._offBoardConnectedCapacityMeshNodeIds??[]))),a=Array.from(new Set(t.flatMap(t=\u003et._connectedTo??[])));return{_containsObstacle:t.some(t=\u003et._containsObstacle)||void 0,_completelyInsideObstacle:t.some(t=\u003et._completelyInsideObstacle)||void 0,_containsTarget:t.some(t=\u003et._containsTarget)||void 0,_targetConnectionName:o,_isVirtualOffboard:t.some(t=\u003et._isVirtualOffboard)||void 0,_offboardNetName:r,_offBoardConnectionId:i,_offBoardConnectedCapacityMeshNodeIds:s.length\u003e0?s:void 0,_qfpRegionType:rq(t.map(t=\u003et._qfpRegionType)),_isNarrowQfpPadGap:t.some(t=\u003et._isNarrowQfpPadGap)||void 0,_soicRegionType:rq(t.map(t=\u003et._soicRegionType)),_isComponentTopologyNode:e||void 0,_connectedTo:a.length\u003e0?a:void 0}}({sourceNodes:c,isComponentTopologyNode:a.some(({groupIndex:t})=\u003en[t].isComponent)}),d=i\u0026\u00261===a.length?a[0].node:null,h=Boolean(d\u0026\u0026function({region:t,sourceNode:e,usedNodeIds:n}){const o=qZ(e),i=Math.abs(t.bounds.minX-o.minX)\u003c=eq\u0026\u0026Math.abs(t.bounds.maxX-o.maxX)\u003c=eq\u0026\u0026Math.abs(t.bounds.minY-o.minY)\u003c=eq\u0026\u0026Math.abs(t.bounds.maxY-o.maxY)\u003c=eq,r=t.availableZ.length===e.availableZ.length\u0026\u0026t.availableZ.every((t,n)=\u003et===e.availableZ[n]);return i\u0026\u0026r\u0026\u0026!n.has(e.capacityMeshNodeId)}({region:t,sourceNode:d,usedNodeIds:s}));let u=h?d.capacityMeshNodeId:`topology_merge_${r}`;for(;s.has(u);)u=`${u}_next`;return s.add(u),i\u0026\u0026(o.groupIndexesByNodeId.set(u,[...new Set(a.map(({groupIndex:t})=\u003et))]),o.sourceKeysByNodeId.set(u,[...t.sourceKeys])),{...d??c[0],...l,capacityMeshNodeId:u,center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,layer:`z${t.availableZ.join(\",\")}`,availableZ:[...t.availableZ],_adjacentNodeIds:void 0,_parent:void 0,_strawNode:void 0,_strawParentCapacityMeshNodeId:void 0}})}function iq(t,e,n){const o=Array.from(new Set(t.filter(t=\u003evoid 0!==t)));if(o.length\u003e1)throw new Error(`TopologyMergingSolver: conflicting ${e} values for overlapping source nodes ${n.join(\", \")}`);return o[0]}function rq(t){const e=Array.from(new Set(t.filter(t=\u003evoid 0!==t)));return 1===e.length?e[0]:void 0}function sq({node:t,sourceKey:e,preparedNodeBySourceKey:n}){const o=n.get(e);if(!o)throw new Error(`TopologyMergingSolver: missing source node for output \"${t.capacityMeshNodeId}\"`);const i=qZ(t),r=i.minX\u003e=o.bounds.minX-nq\u0026\u0026i.maxX\u003c=o.bounds.maxX+nq\u0026\u0026i.minY\u003e=o.bounds.minY-nq\u0026\u0026i.maxY\u003c=o.bounds.maxY+nq,s=t.availableZ.every(t=\u003eo.node.availableZ.includes(t));if(!r||!s)throw new Error(`TopologyMergingSolver: output node \"${t.capacityMeshNodeId}\" escapes its source geometry or layers`)}function aq({groupIndexesA:t,groupIndexesB:e,sourceKeysA:n,sourceKeysB:o,sharedLayers:i,preparedNodeBySourceKey:r}){if(1!==t.length||1!==e.length||t[0]!==e[0]||1!==n.length||1!==o.length||n[0]===o[0])return!1;const s=r.get(n[0]),a=r.get(o[0]);if(!s||!a||0===i.length)return!1;return i.some(t=\u003es.node.availableZ.includes(t)\u0026\u0026a.node.availableZ.includes(t))\u0026\u0026null!==JZ(s.bounds,a.bounds)}function cq(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(const t of e){const e=n[n.length-1];(void 0===e||Math.abs(t-e)\u003eeq)\u0026\u0026n.push(t)}return n}function lq(t,e){return e.x\u003e=t.minX-eq\u0026\u0026e.x\u003c=t.maxX+eq\u0026\u0026e.y\u003e=t.minY-eq\u0026\u0026e.y\u003c=t.maxY+eq}function dq({coveringNodes:t,nodeGroups:e,layerCount:n}){const o=new Map;for(let i=0;i\u003cn;i++){const n=t.filter(({node:t})=\u003et.availableZ.includes(i)).sort((t,e)=\u003et.sourceKey.localeCompare(e.sourceKey));if(0===n.length)continue;const r=new Set(n.map(({groupIndex:t})=\u003et)),s=n.filter(({node:t})=\u003et._containsObstacle\u0026\u0026t._containsTarget),a=s.filter(({groupIndex:t})=\u003e!e[t].isComponent),c=new Set(s.map(({groupIndex:t})=\u003et)),l=s.length\u003e0?a.length\u003e0||1===c.size?\"target-passthrough\":\"target-merged\":1===r.size?\"passthrough\":\"merged\",d=gq({topologyMode:l,nodesOnLayer:n,targetObstacleNodes:s,globalTargetObstacleNodes:a});for(const t of d){const e=JSON.stringify({mode:l,sourceKeys:t}),n=o.get(e);n?n.availableZ.push(i):o.set(e,{availableZ:[i],sourceKeys:t,topologyMode:l,topologySignature:e})}}return[...o.values()]}function hq(t){return JSON.stringify({availableZ:t.availableZ,topologySignature:t.topologySignature})}function uq(t){return JSON.stringify({mergeKey:hq(t),minY:t.bounds.minY.toPrecision(15),maxY:t.bounds.maxY.toPrecision(15)})}function pq(t){return JSON.stringify({mergeKey:hq(t),minX:t.bounds.minX.toPrecision(15),maxX:t.bounds.maxX.toPrecision(15)})}function mq(t,e){const n=new Map;for(const o of t){const t=\"horizontal\"===e?uq(o):pq(o),i=n.get(t)??[];i.push(o),n.set(t,i)}return[...n.values()].flatMap(t=\u003efunction(t,e){const n=[...t].sort((t,n)=\u003e\"horizontal\"===e?t.bounds.minX-n.bounds.minX:t.bounds.minY-n.bounds.minY),o=[];for(const t of n){const n=o[o.length-1],i=void 0!==n\u0026\u0026(\"horizontal\"===e?Math.abs(n.bounds.maxX-t.bounds.minX)\u003c=eq:Math.abs(n.bounds.maxY-t.bounds.minY)\u003c=eq);n\u0026\u0026i?\"horizontal\"===e?n.bounds.maxX=t.bounds.maxX:n.bounds.maxY=t.bounds.maxY:o.push({...t,bounds:{...t.bounds},availableZ:[...t.availableZ],sourceKeys:[...t.sourceKeys]})}return o}(t,e))}function gq({topologyMode:t,nodesOnLayer:e,targetObstacleNodes:n,globalTargetObstacleNodes:o}){if(\"target-passthrough\"===t){return(o.length\u003e0?o:n).map(({sourceKey:t})=\u003e[t])}return\"target-merged\"===t?[n.map(({sourceKey:t})=\u003et).sort()]:\"passthrough\"===t?e.map(({sourceKey:t})=\u003e[t]):[e.map(({sourceKey:t})=\u003et).sort()]}var fq=class extends kt{constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e5;const{preparedNodes:e,preparedNodeBySourceKey:n}=QZ(t);this.preparedNodes=e,this.preparedNodeBySourceKey=n,this.xCoordinates=cq(this.preparedNodes.flatMap(({bounds:t})=\u003e[t.minX,t.maxX])),this.stats={inputNodeCount:this.preparedNodes.length,xSlabCount:Math.max(0,this.xCoordinates.length-1),processedXSlabCount:0,atomicRegionCount:0,outputNodeCount:0}}inputProblem;preparedNodes;preparedNodeBySourceKey;outputProvenance={groupIndexesByNodeId:new Map,sourceKeysByNodeId:new Map};xCoordinates;atomicRegions=[];outputNodes=[];currentXIndex=0;getConstructorParams(){return[this.inputProblem]}_step(){if(1===this.inputProblem.nodeGroups.length)return void this.completePassthroughTopology();if(this.currentXIndex\u003cthis.xCoordinates.length-1)return this.processCurrentXSlab(),this.currentXIndex+=1,this.stats.processedXSlabCount=this.currentXIndex,void(this.stats.atomicRegionCount=this.atomicRegions.length);const t=function(t){let e=t;for(;;){const t=mq(e,\"horizontal\"),n=mq(t,\"vertical\");if(n.length===e.length)return n;e=n}}(function({regions:t,preparedNodeBySourceKey:e}){const n=new Map;for(const e of t)for(const t of e.sourceKeys){const o=n.get(t)??new Set;o.add(e.topologyMode),n.set(t,o)}const o=new Set([...n.entries()].filter(([,t])=\u003e1===t.size\u0026\u0026t.has(\"target-passthrough\")).map(([t])=\u003et));return 0===o.size?t:[...t.filter(t=\u003e\"target-passthrough\"!==t.topologyMode||!o.has(t.sourceKeys[0])),...[...o].map(t=\u003e{const n=e.get(t);if(!n)throw new Error(`TopologyMergingSolver: missing authoritative target source \"${t}\"`);return{bounds:{...n.bounds},availableZ:[...n.node.availableZ],sourceKeys:[t],topologyMode:\"target-passthrough\",topologySignature:JSON.stringify({mode:\"target-passthrough\",sourceKeys:[t]})}})]}({regions:this.atomicRegions,preparedNodeBySourceKey:this.preparedNodeBySourceKey}));this.outputNodes=oq({regions:t,preparedNodeBySourceKey:this.preparedNodeBySourceKey,nodeGroups:this.inputProblem.nodeGroups,provenance:this.outputProvenance}),function({nodes:t,preparedNodeBySourceKey:e,provenance:n}){const o=new Set;for(const i of t){if(o.has(i.capacityMeshNodeId))throw new Error(`TopologyMergingSolver: duplicate output node id \"${i.capacityMeshNodeId}\"`);if(o.add(i.capacityMeshNodeId),!KZ(qZ(i)))throw new Error(`TopologyMergingSolver: output node \"${i.capacityMeshNodeId}\" has invalid bounds`);if(0===i.availableZ.length)throw new Error(`TopologyMergingSolver: output node \"${i.capacityMeshNodeId}\" has no available layers`);const t=n.sourceKeysByNodeId.get(i.capacityMeshNodeId);if(!t)throw new Error(`TopologyMergingSolver: missing output provenance for node \"${i.capacityMeshNodeId}\"`);1===t.length\u0026\u0026sq({node:i,sourceKey:t[0],preparedNodeBySourceKey:e})}for(let o=0;o\u003ct.length;o++){const i=t[o];for(let r=o+1;r\u003ct.length;r++){const o=t[r],s=i.availableZ.filter(t=\u003eo.availableZ.includes(t));if(0===s.length)continue;const a=JZ(qZ(i),qZ(o));if(!a)continue;const c=a.maxX-a.minX,l=a.maxY-a.minY;if(c\u003c=nq||l\u003c=nq)continue;const d=n.groupIndexesByNodeId.get(i.capacityMeshNodeId),h=n.groupIndexesByNodeId.get(o.capacityMeshNodeId);if(!d||!h)throw new Error(`TopologyMergingSolver: missing output provenance for overlapping nodes \"${i.capacityMeshNodeId}\" and \"${o.capacityMeshNodeId}\"`);const u=n.sourceKeysByNodeId.get(i.capacityMeshNodeId),p=n.sourceKeysByNodeId.get(o.capacityMeshNodeId);if(!u||!p)throw new Error(`TopologyMergingSolver: missing source provenance for overlapping nodes \"${i.capacityMeshNodeId}\" and \"${o.capacityMeshNodeId}\"`);if(!aq({groupIndexesA:d,groupIndexesB:h,sourceKeysA:u,sourceKeysB:p,sharedLayers:s,preparedNodeBySourceKey:e}))throw new Error(`TopologyMergingSolver: output nodes \"${i.capacityMeshNodeId}\" and \"${o.capacityMeshNodeId}\" have an unresolved inter-group overlap on a shared layer`)}}}({nodes:this.outputNodes,preparedNodeBySourceKey:this.preparedNodeBySourceKey,provenance:this.outputProvenance}),this.stats.outputNodeCount=this.outputNodes.length,this.stats.compactedRegionCount=t.length,this.solved=!0}getOutput(){if(!this.solved)throw new Error(\"TopologyMergingSolver: getOutput() called before the solver completed\");return this.outputNodes}computeProgress(){const t=Math.max(1,this.xCoordinates.length-1);return this.solved?1:Math.min(.99,this.currentXIndex/t)}visualize(){const t=this.solved?this.outputNodes:oq({regions:this.atomicRegions,preparedNodeBySourceKey:this.preparedNodeBySourceKey,nodeGroups:this.inputProblem.nodeGroups,provenance:this.outputProvenance,preserveSourceIds:!1});return{title:`Topology Merging: ${t.length} refined regions`,coordinateSystem:\"cartesian\",rects:t.map(t=\u003e({...Dc(t,{rectMargin:.01,zOffset:.02}),label:`${t.capacityMeshNodeId}\\navailableZ: ${t.availableZ.join(\",\")}\\ncomponent: ${t._isComponentTopologyNode?\"yes\":\"no\"}`})),lines:[],points:[],circles:[],texts:[]}}completePassthroughTopology(){const t=this.inputProblem.nodeGroups[0];this.outputNodes=t.nodes;for(const e of this.outputNodes)this.outputProvenance.groupIndexesByNodeId.set(e.capacityMeshNodeId,[0]),this.outputProvenance.sourceKeysByNodeId.set(e.capacityMeshNodeId,[`${t.groupId}:${e.capacityMeshNodeId}`]);this.stats.processedXSlabCount=this.stats.xSlabCount,this.stats.atomicRegionCount=0,this.stats.compactedRegionCount=0,this.stats.outputNodeCount=this.outputNodes.length,this.stats.passthroughNodeCount=this.outputNodes.length,this.solved=!0}processCurrentXSlab(){const t=this.xCoordinates[this.currentXIndex],e=this.xCoordinates[this.currentXIndex+1];if(e-t\u003c=eq)return;const n=(t+e)/2,o=this.preparedNodes.filter(({bounds:t})=\u003en\u003e=t.minX-eq\u0026\u0026n\u003c=t.maxX+eq),i=cq(o.flatMap(({bounds:t})=\u003e[t.minY,t.maxY]));for(let r=0;r\u003ci.length-1;r++){const s=i[r],a=i[r+1];if(a-s\u003c=eq)continue;const c={x:n,y:(s+a)/2},l=o.filter(({bounds:t})=\u003elq(t,c));if(0===l.length)continue;const d=dq({coveringNodes:l,nodeGroups:this.inputProblem.nodeGroups,layerCount:this.inputProblem.layerCount});for(const n of d)this.atomicRegions.push({bounds:{minX:t,maxX:e,minY:s,maxY:a},availableZ:n.availableZ,sourceKeys:n.sourceKeys,topologyMode:n.topologyMode,topologySignature:n.topologySignature})}}};function yq({meshNodes:t,components:e}){return 0===e.length?t:t.map(t=\u003e{const n=e.some(e=\u003efunction({node:t,component:e}){const{replacementObstacle:n}=e,o=Math.abs(t.center.x-n.center.x)\u003c=ZZ\u0026\u0026Math.abs(t.center.y-n.center.y)\u003c=ZZ\u0026\u0026Math.abs(t.width-n.width)\u003c=ZZ\u0026\u0026Math.abs(t.height-n.height)\u003c=ZZ;if(\"qfp\"!==e.componentKind\u0026\u0026\"qfp_thermalpad\"!==e.componentKind\u0026\u0026\"soic\"!==e.componentKind)return o;const i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=n.center.y-n.height/2,a=n.center.y+n.height/2,c=t.center.x\u003e=i-ZZ\u0026\u0026t.center.x\u003c=r+ZZ\u0026\u0026t.center.y\u003e=s-ZZ\u0026\u0026t.center.y\u003c=a+ZZ,l=t.width*t.height,d=n.width*n.height,h=c\u0026\u0026l\u003e=.2*d;return o||h}({node:t,component:e}));return n?{...t,_containsObstacle:void 0,_completelyInsideObstacle:void 0,_containsTarget:void 0,_targetConnectionName:void 0,_connectedTo:void 0}:t})}var _q=class extends Dt{globalTopologySolver;componentTopologyBatchSolver;normalizedInput;pipelineDef=[Lt(\"globalTopologySolver\",Kn,t=\u003e[t.getGlobalTopologySolverInput()]),Lt(\"componentTopologyBatchSolver\",wZ,t=\u003e[{componentSrjs:t.getComponentNoConnectionSrjs(),componentIds:t.normalizedInput.components.map(t=\u003et.componentId),componentKinds:t.normalizedInput.components.map(t=\u003et.componentKind),viaDiameter:t.inputProblem.viaDiameter,obstacleMargin:t.inputProblem.obstacleMargin}])];constructor(t){super(t),this.normalizedInput=PZ(t)}getConstructorParams(){return[this.inputProblem]}getOutput(){const t=yq({meshNodes:this.getStageOutput(\"globalTopologySolver\")?.meshNodes??[],components:this.normalizedInput.components}),e=this.getStageOutput(\"componentTopologyBatchSolver\")?.componentMeshNodes??[],n=this.getComponentNoConnectionSrjs();return{globalNoConnectionSrj:this.normalizedInput.globalNoConnectionSrj,componentNoConnectionSrjs:n,globalMeshNodes:t,componentMeshNodes:e}}finalVisualize(){const t=this.getOutput();return{title:\"Topology Planning: generated topology groups\",rects:[...t.componentNoConnectionSrjs.flatMap((t,e)=\u003e{const n=this.normalizedInput.components[e]??null;return t.obstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(120, 120, 120, 0.06)\",stroke:\"rgba(120, 120, 120, 0.35)\",label:t.obstacleId??n?.componentId??\"component-pad\",layer:t.layers.join(\",\")}))}),...[...t.globalMeshNodes,...t.componentMeshNodes.flat()].map(t=\u003e{const e=this.normalizedInput.components.find(e=\u003et.capacityMeshNodeId.includes(e.componentId));return{...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?To(\"red\",.82):\"rgba(0, 120, 255, 0.12)\",stroke:t._containsObstacle?To(\"red\",.3):\"rgba(0, 120, 255, 0.55)\",label:e?`${e.componentKind.toUpperCase()} ${t.capacityMeshNodeId}`:t.capacityMeshNodeId}})],lines:[],points:[],circles:[],texts:[]}}visualize(){return this.filterGlobalRectDiffNodesFromVisualization({visualization:super.visualize()})}preview(){return this.filterGlobalRectDiffNodesFromVisualization({visualization:super.preview()})}getComponentNoConnectionSrjs(){return this.normalizedInput.components.map(t=\u003efunction({inputSrj:t,component:e}){const n=CZ(e.memberObstacles),o=Math.max(t.minViaPadDiameter??t.min_via_pad_diameter??t.minViaDiameter??.3,t.defaultObstacleMargin??.15,2*t.minTraceWidth),i=new Set(e.memberObstacles.flatMap(t=\u003et.connectedTo)),r=t.connections.flatMap(t=\u003et.pointsToConnect.filter(t=\u003e{const e=[t.pointId,t.pcb_port_id].filter(t=\u003e\"string\"==typeof t).some(t=\u003ei.has(t)),r=t.x\u003e=n.minX-o\u0026\u0026t.x\u003c=n.maxX+o\u0026\u0026t.y\u003e=n.minY-o\u0026\u0026t.y\u003c=n.maxY+o;return e\u0026\u0026r})).reduce((t,e)=\u003e({minX:Math.min(t.minX,e.x),maxX:Math.max(t.maxX,e.x),minY:Math.min(t.minY,e.y),maxY:Math.max(t.maxY,e.y)}),n),s=t.obstacles.filter(t=\u003eXe(Ee(t),r)).map(t=\u003e({...t}));return{...structuredClone(t),bounds:r,obstacles:s}}({inputSrj:this.inputProblem.inputSrj,component:t}))}getGlobalTopologySolverInput(){return{simpleRouteJson:this.normalizedInput.globalNoConnectionSrj,maxGapFillPasses:4}}filterGlobalRectDiffNodesFromVisualization({visualization:t}){return{...t,rects:MZ({rects:t.rects,components:this.normalizedInput.components})}}},bq=(t,e)=\u003e{if(t)return Object.entries(e).sort(([t],[e])=\u003ee.length-t.length).find(([e])=\u003et.includes(e))?.[1]},xq=(t,e)=\u003e({...t,points:t.points?.map(t=\u003e({...t,color:bq(t.label,e)??t.color})),lines:t.lines?.map(t=\u003e({...t,strokeColor:bq(t.label,e)??t.strokeColor})),circles:t.circles?.map(t=\u003e{const n=bq(t.label,e);return n?{...t,fill:n,stroke:n}:t})}),vq=class extends si{constructor(t){super(),this.topologyPlanningSolver=t,this.solved=t.solved,this.failed=t.failed,this.error=t.error,this.stats=t.stats}topologyPlanningSolver;getOutput(){return this.topologyPlanningSolver.getOutput().componentMeshNodes.flat()}visualize(){return this.topologyPlanningSolver.finalVisualize()??this.topologyPlanningSolver.visualize()}preview(){return this.visualize()}},Sq=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\u0026\u0026!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026this.tryFinalAcceptance(),!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),\"computeProgress\"in this\u0026\u0026(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error(\"getConstructorParams not implemented\")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved\u0026\u0026!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:[]}}},Iq=t=\u003et.filter(t=\u003eBoolean(t)),Cq=(t,e,n)=\u003e{const o=`${Math.round(100*t.x)},${Math.round(100*t.y)}`,i=e.map(t=\u003e((t,e)=\u003e\"top\"===t?0:\"bottom\"===t?e-1:Number.parseInt(t.slice(5),10))(t,n)).sort().join(\"-\");return`${o}:${i}`},Pq=class{parent=new Map;constructor(t,e=t.traces??[],n={}){for(const e of t.connections)this.unionAll(Iq([e.name,e.source_trace_id,e.rootConnectionName,e.netConnectionName,...e.mergedConnectionNames??[],...e.pointsToConnect.flatMap(e=\u003e[e.pointId,e.pcb_port_id,...n.includePhysicalPositionAliases?[Cq(e,e.layers??[e.layer],t.layerCount)]:[]])]));for(const n of[...e,...t.fixedTraces??[]])this.unionAll(Iq([n.pcb_trace_id,n.connection_name,n.source_trace_id,n.rootConnectionName,...n.mergedConnectionNames??[],...n.connectsTo??[]]));for(const e of t.obstacles)this.unionAll(n.includePhysicalPositionAliases?Iq([e.obstacleId,...e.connectedTo,...e.offBoardConnectsTo??[],Cq(e.center,e.layers,t.layerCount)]):e.connectedTo)}canonicalize(t){return[...new Set(t.map(t=\u003ethis.find(t)))]}unionAll(t){const e=t[0];if(e){this.add(e);for(let n=1;n\u003ct.length;n++)this.union(e,t[n])}}add(t){this.parent.has(t)||this.parent.set(t,t)}find(t){this.add(t);const e=this.parent.get(t);if(e===t)return t;const n=this.find(e);return this.parent.set(t,n),n}union(t,e){const n=this.find(t),o=this.find(e);n!==o\u0026\u0026this.parent.set(o,n)}},Mq=1e-6,Nq=(t,e)=\u003eMath.hypot(e.x-t.x,e.y-t.y),wq=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c=1e-12)return Nq(t,e);const s=Rq(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return Math.hypot(t.x-(e.x+o*s),t.y-(e.y+i*s))},Tq=(t,e,n=1e-6)=\u003eMath.abs(t.x-e.x)\u003c=n\u0026\u0026Math.abs(t.y-e.y)\u003c=n,Rq=(t,e,n)=\u003eMath.max(e,Math.min(n,t)),Eq=(t,e,n)=\u003e(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),Aq=(t,e,n)=\u003eMath.abs(Eq(e,n,t))\u003c=1e-9\u0026\u0026t.x\u003e=Math.min(e.x,n.x)-1e-9\u0026\u0026t.x\u003c=Math.max(e.x,n.x)+1e-9\u0026\u0026t.y\u003e=Math.min(e.y,n.y)-1e-9\u0026\u0026t.y\u003c=Math.max(e.y,n.y)+1e-9,Oq=(t,e,n,o)=\u003e((t,e,n,o)=\u003e{const i=Eq(t,e,n),r=Eq(t,e,o),s=Eq(n,o,t),a=Eq(n,o,e);return i*r\u003c0\u0026\u0026s*a\u003c0||Math.abs(i)\u003c=1e-9\u0026\u0026Aq(n,t,e)||Math.abs(r)\u003c=1e-9\u0026\u0026Aq(o,t,e)||Math.abs(s)\u003c=1e-9\u0026\u0026Aq(t,n,o)||Math.abs(a)\u003c=1e-9\u0026\u0026Aq(e,n,o)})(t,e,n,o)?0:Math.min(wq(t,n,o),wq(e,n,o),wq(n,t,e),wq(o,t,e)),kq=(t,e)=\u003e{let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];if(Aq(t,s,r))return!0;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n},Lq=(t,e,n)=\u003e{if(kq(t,n)||kq(e,n))return 0;let o=Number.POSITIVE_INFINITY;for(let i=0;i\u003cn.length;i++){const r=n[i],s=n[(i+1)%n.length];o=Math.min(o,Oq(t,e,r,s))}return o};function Dq(t,e,n){let o=0,i=1;const r=e.x-t.x,s=e.y-t.y,a=[[-r,t.x-n.minX],[r,n.maxX-t.x],[-s,t.y-n.minY],[s,n.maxY-t.y]];for(const[t,e]of a){if(Math.abs(t)\u003c1e-12){if(e\u003c0)return!1;continue}const n=e/t;if(t\u003c0?o=Math.max(o,n):i=Math.min(i,n),o\u003ei)return!1}return!0}function zq({start:t,end:e,width:n,base:o}){const i=Nq(t,e),r=(t=\u003eRq(1.25*t,.25,.75))(n),s=Math.max(1,Math.ceil(i/r)),a=n/2,c=[];for(let i=0;i\u003cs;i++){const r=i/s,l=(i+1)/s,d=t.x+(e.x-t.x)*r,h=t.y+(e.y-t.y)*r,u=t.x+(e.x-t.x)*l,p=t.y+(e.y-t.y)*l;c.push({...o,minX:Math.min(d,u)-a,minY:Math.min(h,p)-a,maxX:Math.max(d,u)+a,maxY:Math.max(h,p)+a,exactShape:{type:\"segment\",start:{x:d,y:h},end:{x:u,y:p},width:n}})}return c}var Fq=(t,e,n)=\u003e{const o=Math.cos(n),i=Math.sin(n),r=t.x-e.x,s=t.y-e.y;return{x:e.x+r*o-s*i,y:e.y+r*i+s*o}};var Bq=class{nodeIndices=[];priorities=[];get size(){return this.nodeIndices.length}push(t,e){let n=this.nodeIndices.length;for(this.nodeIndices.push(t),this.priorities.push(e);n\u003e0;){const t=n-1\u003e\u003e1;if(this.priorities[t]\u003c=e)break;this.swap(n,t),n=t}}pop(){const t=this.nodeIndices[0],e=this.nodeIndices.pop(),n=this.priorities.pop();if(0===this.nodeIndices.length)return t;this.nodeIndices[0]=e,this.priorities[0]=n;let o=0;for(;;){const t=2*o+1,e=t+1;if(t\u003e=this.nodeIndices.length)break;let n=t;if(e\u003cthis.nodeIndices.length\u0026\u0026this.priorities[e]\u003cthis.priorities[t]\u0026\u0026(n=e),this.priorities[o]\u003c=this.priorities[n])break;this.swap(o,n),o=n}return t}swap(t,e){[this.nodeIndices[t],this.nodeIndices[e]]=[this.nodeIndices[e],this.nodeIndices[t]],[this.priorities[t],this.priorities[e]]=[this.priorities[e],this.priorities[t]]}},jq=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]],$q=[\"#d53535\",\"#3478c8\",\"#8e44ad\",\"#15956f\"],Yq=class extends Sq{problem;searchBounds;rows;columns;origin;nodes=[];open=new Bq;bestCost=new Map;closed=new Set;baseStateCount;stateSpaceUpperBound;endLayerIndices;targetCell;segmentWidthCache=new Map;closedStateCount=0;output=null;constructor(t){super(),this.problem=t;const e=Math.max(t.traceWidth,t.viaDiameter)/2+t.obstacleIndex.clearance,n=Rq(Math.min(t.start.x,t.end.x)-t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),o=Rq(Math.max(t.start.x,t.end.x)+t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),i=Rq(Math.min(t.start.y,t.end.y)-t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),r=Rq(Math.max(t.start.y,t.end.y)+t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),s=Math.floor((n-t.gridOffset.x)/t.gridSize)*t.gridSize+t.gridOffset.x,a=Math.floor((i-t.gridOffset.y)/t.gridSize)*t.gridSize+t.gridOffset.y;this.origin={x:s,y:a},this.columns=Math.max(2,Math.floor((o-s)/t.gridSize)+1),this.rows=Math.max(2,Math.floor((r-a)/t.gridSize)+1),this.searchBounds={minX:s,minY:a,maxX:s+(this.columns-1)*t.gridSize,maxY:a+(this.rows-1)*t.gridSize};const c=this.rows*this.columns*t.layers.length*(t.maxViaCount+1);this.baseStateCount=c,this.stateSpaceUpperBound=c*(this.rows*this.columns+1),this.targetCell=this.pointToCell(t.end),this.endLayerIndices=new Set(t.endLayers.map(e=\u003et.layers.indexOf(e)).filter(t=\u003et\u003e=0));const l=this.pointToCell(t.start);for(const e of t.startLayers){const n=t.layers.indexOf(e);if(n\u003c0||this.endpointCollides(t.start,n))continue;const o={...l,...t.start,layerIndex:n,viaCount:0,viaPoints:[],g:0,f:this.heuristic(t.start),parentIndex:-1},i=this.nodes.length;this.nodes.push(o),this.open.push(i,o.f),this.bestCost.set(this.toStateIndex(o),0)}0!==this.open.size\u0026\u00260!==this.endLayerIndices.size||(this.failed=!0,this.error=\"No collision-free multilayer route endpoint\"),this.MAX_ITERATIONS=Math.min(15e3,Math.max(2e3,2*c)),this.stats=this.createStats()}getSolverName(){return`LayerAwareGridRouteSolver(${this.problem.gridSize.toFixed(3)}mm)`}_step(){if(0===this.open.size)return this.failed=!0,void(this.error=\"No collision-free multilayer grid route found\");const t=this.open.pop(),e=this.nodes[t],n=this.toStateIndex(e);if(!this.closed.has(n)){if(this.closed.add(n),this.closedStateCount++,e.row===this.targetCell.row\u0026\u0026e.column===this.targetCell.column\u0026\u0026this.endLayerIndices.has(e.layerIndex)\u0026\u0026e.viaCount\u003e=this.problem.minViaCount\u0026\u0026!this.segmentCollides(e,this.problem.end))return this.output=this.reconstructRoute(t),this.solved=!0,void(this.stats=this.createStats());this.expandPlanarMoves(t,e),this.expandViaMoves(t,e),this.stats=this.createStats()}}expandPlanarMoves(t,e){for(const[n,o]of jq){const i=e.row+n,r=e.column+o;if(i\u003c0||i\u003e=this.rows||r\u003c0||r\u003e=this.columns)continue;const s=this.cellToPoint(i,r),a=this.getSafeSegmentWidth(e,s);if(a\u003c=0)continue;const c=this.problem.gridSize*(0!==n\u0026\u00260!==o?Math.SQRT2:1)*Math.max(1,(this.problem.traceWidth/a)**this.problem.neckPenaltyExponent);this.enqueueNode({row:i,column:r,...s,layerIndex:e.layerIndex,viaCount:e.viaCount,viaPoints:e.viaPoints,g:e.g+c,parentIndex:t})}}expandViaMoves(t,e){if(e.viaCount\u003e=this.problem.maxViaCount)return;const n=.5*this.problem.gridSize;if(Nq(e,this.problem.start)\u003cn-1e-9||Nq(e,this.problem.end)\u003cn-1e-9)return;const o=e.parentIndex\u003e=0?this.nodes[e.parentIndex]:void 0;if(!o||o.layerIndex===e.layerIndex||!Tq(o,e))for(let n=0;n\u003cthis.problem.layers.length;n++)n!==e.layerIndex\u0026\u0026(this.problem.obstacleIndex.collidesVia({point:e,layers:this.problem.layers,padDiameter:this.problem.viaDiameter,holeDiameter:this.problem.viaHoleDiameter,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreTraceIndices:this.problem.softTraceIndices,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance,blockSameNetObstacles:!0,sameNetObstacleClearance:0,otherNewViaPoints:e.viaPoints,fixedVias:this.problem.fixedVias})||this.enqueueNode({row:e.row,column:e.column,x:e.x,y:e.y,layerIndex:n,viaCount:e.viaCount+1,viaPoints:[...e.viaPoints,{x:e.x,y:e.y}],g:e.g+this.problem.viaCost,parentIndex:t}))}enqueueNode(t){const e=this.toStateIndex(t);if(this.closed.has(e)||t.g\u003e=(this.bestCost.get(e)??Number.POSITIVE_INFINITY))return;this.bestCost.set(e,t.g);const n=t.g+this.heuristic(t),o=this.nodes.length;this.nodes.push({...t,f:n}),this.open.push(o,n)}endpointCollides(t,e){return this.getSafeSegmentWidth({...t,layerIndex:e,viaCount:0},t)\u003c=0}segmentCollides(t,e){return this.getSafeSegmentWidth(t,e)\u003c=0}getSafeSegmentWidth(t,e){const n=this.problem.layers[t.layerIndex],o=1===this.problem.startLayers.length\u0026\u00260===t.viaCount\u0026\u0026n===this.problem.originalStartLayer\u0026\u0026Nq(this.problem.start,t)\u003c=this.problem.maxStartNeckLength+1e-9\u0026\u0026Nq(this.problem.start,e)\u003c=this.problem.maxStartNeckLength+1e-9,i=1===this.problem.endLayers.length\u0026\u0026n===this.problem.originalEndLayer\u0026\u0026Nq(this.problem.end,t)\u003c=this.problem.maxEndNeckLength+1e-9\u0026\u0026Nq(this.problem.end,e)\u003c=this.problem.maxEndNeckLength+1e-9,r=Math.max(o?this.problem.startNeckWidth:0,i?this.problem.endNeckWidth:0),s=[t.x,t.y,e.x,e.y,t.layerIndex,t.viaCount,r].join(\":\"),a=this.segmentWidthCache.get(s);if(void 0!==a)return a;const c=o=\u003e!this.problem.obstacleIndex.collides({start:t,end:e,layer:n,width:o,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreTraceIndices:this.problem.softTraceIndices,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance});let l=0;if(o||i){const t=.025;let e=Math.ceil((r-1e-9)/t),n=Math.floor((this.problem.traceWidth+1e-9)/t);for(;e\u003c=n;){const o=Math.floor((e+n)/2),i=Number((o*t).toFixed(6));c(i)?(l=i,e=o+1):n=o-1}l\u003cr-1e-9\u0026\u0026c(r)\u0026\u0026(l=r)}else l=c(this.problem.traceWidth)?this.problem.traceWidth:0;return this.segmentWidthCache.set(s,l),l}reconstructRoute(t){const e=[];let n=t;for(;n\u003e=0;){const t=this.nodes[n];e.push(t),n=t.parentIndex}e.reverse();const o=e[e.length-1];Tq(o,this.problem.end)||e.push({...o,...this.problem.end,row:this.targetCell.row,column:this.targetCell.column,parentIndex:-1});const i=[];let r=[e[0]];for(let t=1;t\u003ce.length;t++){const n=e[t-1],o=e[t];o.layerIndex!==n.layerIndex?(i.push(r),r=[o]):r.push(o)}i.push(r);const s=[];for(let t=0;t\u003ci.length;t++){const e=this.simplifySection(i[t]),n=e.slice(0,-1).map((t,n)=\u003ethis.getSafeSegmentWidth(t,e[n+1])),o=e.map((t,o)=\u003e({route_type:\"wire\",x:t.x,y:t.y,layer:this.problem.layers[t.layerIndex],width:0===n.length?Math.min(this.problem.startNeckWidth,this.problem.endNeckWidth):0===o?n[0]:o===e.length-1?n[n.length-1]:Math.min(n[o-1],n[o])}));s.push(...o);const r=i[t+1];if(r){const t=this.problem.layers[e.at(-1).layerIndex],n=this.problem.layers[r[0].layerIndex],o=e.at(-1);s.push({route_type:\"via\",x:o.x,y:o.y,from_layer:t,to_layer:n,via_diameter:this.problem.viaDiameter,via_hole_diameter:this.problem.viaHoleDiameter})}}return{route:s,traceWidth:this.problem.traceWidth,startNeckWidth:this.problem.startNeckWidth,endNeckWidth:this.problem.endNeckWidth,gridSize:this.problem.gridSize,gridOffset:this.problem.gridOffset,viaCount:i.length-1}}simplifySection(t){return t.length\u003c=2?t:this.problem.neckPenaltyExponent\u003e1?this.simplifyStrictSection(t):this.simplifyWidthPreservingSection(t)}simplifyStrictSection(t){const e=t.slice(0,-1).map((e,n)=\u003ethis.getSafeSegmentWidth(e,t[n+1])),n=[0];for(let o=0;o\u003ce.length;o++)n.push(n[o]+this.getWidthPenalizedCost(t[o],t[o+1],e[o]));const o=[t[0]];let i=0;for(;i\u003ct.length-1;){let r=t.length-1;for(;r\u003ei+1\u0026\u0026!this.shortcutPreservesRouteQuality(t,e,n,i,r);)r--;o.push(t[r]),i=r}return this.removeRedundantCollinearPoints(o)}shortcutPreservesRouteQuality(t,e,n,o,i){const r=this.getSafeSegmentWidth(t[o],t[i]);if(r\u003c=0)return!1;let s=Number.POSITIVE_INFINITY;for(let t=o;t\u003ci;t++)s=Math.min(s,e[t]);const a=n[i]-n[o];return r\u003e=s-1e-9\u0026\u0026this.getWidthPenalizedCost(t[o],t[i],r)\u003c=a+1e-9}getWidthPenalizedCost(t,e,n){return Nq(t,e)*Math.max(1,(this.problem.traceWidth/n)**this.problem.neckPenaltyExponent)}simplifyWidthPreservingSection(t){const e=t.slice(0,-1).map((e,n)=\u003ethis.getSafeSegmentWidth(e,t[n+1])),n=[0];for(let o=0;o\u003ce.length;o++)n.push(n[o]+Nq(t[o],t[o+1])*Math.max(1,(this.problem.traceWidth/e[o])**this.problem.neckPenaltyExponent));const o=new Float64Array(t.length).fill(Number.POSITIVE_INFINITY),i=new Float64Array(t.length).fill(Number.POSITIVE_INFINITY),r=new Int32Array(t.length).fill(-1);o[0]=0,i[0]=0;for(let s=1;s\u003ct.length;s++){let a=Number.POSITIVE_INFINITY;for(let c=s-1;c\u003e=0;c--){if(a=Math.min(a,e[c]),!Number.isFinite(o[c]))continue;const l=this.getSafeSegmentWidth(t[c],t[s]);if(l\u003ca-1e-9)continue;const d=Nq(t[c],t[s]);if(d*Math.max(1,(this.problem.traceWidth/l)**this.problem.neckPenaltyExponent)\u003en[s]-n[c]+1e-9)continue;const h=o[c]+d*Math.max(0,this.problem.traceWidth-l),u=i[c]+d;(h\u003co[s]-1e-9||Math.abs(h-o[s])\u003c=1e-9\u0026\u0026u\u003ci[s]-1e-9)\u0026\u0026(o[s]=h,i[s]=u,r[s]=c)}}const s=[];let a=t.length-1;for(;a\u003e=0\u0026\u0026(s.push(t[a]),0!==a);)if(a=r[a],a\u003c0)return t;return s.reverse(),this.removeRedundantCollinearPoints(s)}removeRedundantCollinearPoints(t){return t.filter((t,e,n)=\u003e{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x),s=Math.abs(this.getSafeSegmentWidth(o,t)-this.getSafeSegmentWidth(t,i))\u003c1e-9;return Math.abs(r)\u003e1e-8||!s})}pointToCell(t){return{column:Rq(Math.round((t.x-this.origin.x)/this.problem.gridSize),0,this.columns-1),row:Rq(Math.round((t.y-this.origin.y)/this.problem.gridSize),0,this.rows-1)}}cellToPoint(t,e){return{x:this.origin.x+e*this.problem.gridSize,y:this.origin.y+t*this.problem.gridSize}}toStateIndex(t){const e=((t.viaCount*this.problem.layers.length+t.layerIndex)*this.rows+t.row)*this.columns+t.column;if(1!==t.viaCount||0===t.viaPoints.length||Nq(t,t.viaPoints[0])\u003e=this.problem.viaHoleDiameter+this.problem.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance-1e-9)return e;const n=this.pointToCell(t.viaPoints[0]);return e+(1+n.row*this.columns+n.column)*this.baseStateCount}heuristic(t){return Nq(t,this.problem.end)}createStats(){return{phase:\"layer-aware-grid-search\",gridSize:this.problem.gridSize,traceWidth:this.problem.traceWidth,startNeckWidth:this.problem.startNeckWidth,endNeckWidth:this.problem.endNeckWidth,maxViaCount:this.problem.maxViaCount,minViaCount:this.problem.minViaCount,openStates:this.open.size,closedStates:this.closedStateCount,trackedStates:this.bestCost.size,stateSpaceUpperBound:this.stateSpaceUpperBound}}computeProgress(){return Math.min(.99,this.iterations/this.MAX_ITERATIONS)}getOutput(){return this.output}getConstructorParams(){const{obstacleIndex:t,...e}=this.problem;return[e]}visualize(){const t=this.nodes.filter(t=\u003ethis.closed.has(this.toStateIndex(t))).slice(-2e3).map(t=\u003e({x:t.x,y:t.y,color:`${$q[t.layerIndex%$q.length]}55`})),e=[],n=[],o=this.output?.route??[];for(let t=0;t\u003co.length-1;t++){const i=o[t],r=o[t+1];if(\"wire\"===i?.route_type\u0026\u0026\"wire\"===r?.route_type\u0026\u0026i.layer===r.layer){const t=this.problem.layers.indexOf(i.layer);e.push({points:[i,r],strokeColor:$q[t%$q.length]??\"#333\",strokeWidth:i.width})}\"via\"===i?.route_type\u0026\u0026n.push({center:i,radius:(i.via_diameter??this.problem.viaDiameter)/2,fill:\"#d4a017\"})}return{coordinateSystem:\"cartesian\",title:this.getSolverName(),rects:[{center:{x:(this.searchBounds.minX+this.searchBounds.maxX)/2,y:(this.searchBounds.minY+this.searchBounds.maxY)/2},width:this.searchBounds.maxX-this.searchBounds.minX,height:this.searchBounds.maxY-this.searchBounds.minY,stroke:\"#777\"}],points:[...t,{...this.problem.start,color:\"green\",label:\"reroute start\"},{...this.problem.end,color:\"purple\",label:\"reroute target\"}],lines:e,circles:n,texts:[]}}},Xq=[{direction:1,strength:.7},{direction:-1,strength:.7},{direction:1,strength:1},{direction:-1,strength:1}],Vq=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c=1e-12)return{...e};const s=Rq(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return{x:e.x+o*s,y:e.y+i*s}},Wq=class extends Sq{problem;phase=\"prepare-candidate\";variantCursor=0;relaxationIteration=0;candidatePoints=[];sampledPoints;output=null;constructor(t){super(),this.problem=t,this.sampledPoints=this.sampleRoute(),this.MAX_ITERATIONS=100,this.stats=this.createStats()}getSolverName(){return\"ElasticTracePushSolver\"}_step(){switch(this.phase){case\"prepare-candidate\":if(this.variantCursor\u003e=Xq.length)return this.failed=!0,void(this.error=\"No collision-free elastic displacement found\");this.candidatePoints=this.sampledPoints.map(t=\u003e({...t})),this.relaxationIteration=0,this.phase=\"relax-candidate\";break;case\"relax-candidate\":this.relaxCandidate(),this.relaxationIteration++,this.relaxationIteration\u003e=10\u0026\u0026(this.phase=\"validate-candidate\");break;case\"validate-candidate\":{const t=this.simplifyCandidate(this.candidatePoints);this.pathCollides(t)?(this.variantCursor++,this.phase=\"prepare-candidate\"):(this.output={points:t,traceWidth:this.problem.traceWidth},this.phase=\"complete\");break}case\"complete\":this.solved=!0}this.stats=this.createStats()}sampleRoute(){const t=[],e=Rq(2*this.problem.traceWidth,.2,.45),n=this.problem.trace.route;for(let o=this.problem.range.startIndex;o\u003cthis.problem.range.endIndex;o++){const i=n[o],r=n[o+1];if(\"wire\"!==i?.route_type||\"wire\"!==r?.route_type||i.layer!==r.layer)continue;0===t.length\u0026\u0026t.push({x:i.x,y:i.y});const s=Nq(i,r),a=Math.max(1,Math.ceil(s/e));for(let e=1;e\u003c=a;e++){const n=e/a;t.push({x:i.x+(r.x-i.x)*n,y:i.y+(r.y-i.y)*n})}}return t}relaxCandidate(){const t=Xq[this.variantCursor],e=this.candidatePoints.map(t=\u003e({...t})),n=new Uint8Array(this.candidatePoints.length);for(let o=1;o\u003cthis.candidatePoints.length-1;o++){const i=this.candidatePoints[o],r=this.findNearestCorridorSegment(i);if(!r)continue;const s=Nq(r.segment.start,r.segment.end);if(s\u003c=1e-9)continue;const a=r.segment.width/2+this.problem.traceWidth/2+this.problem.obstacleIndex.clearance+.025;if(r.distance\u003ea+.35)continue;const c={x:(r.segment.start.y-r.segment.end.y)/s*t.direction,y:(r.segment.end.x-r.segment.start.x)/s*t.direction},l=a-((i.x-r.closest.x)*c.x+(i.y-r.closest.y)*c.y);if(l\u003c=0)continue;const d=Math.min(.35,l*t.strength);e[o]={x:i.x+c.x*d,y:i.y+c.y*d},n[o]=1}for(let t=1;t\u003ce.length-1;t++){if(!n[t])continue;const o=e[t-1],i=e[t],r=e[t+1];e[t]={x:.85*i.x+(o.x+r.x)/2*.15,y:.85*i.y+(o.y+r.y)/2*.15}}this.candidatePoints=e}findNearestCorridorSegment(t){let e;for(const n of this.problem.corridor){if(n.layer!==this.problem.layer)continue;const o=Vq(t,n.start,n.end),i=Nq(t,o);(!e||i\u003ce.distance)\u0026\u0026(e={segment:n,closest:o,distance:i})}return e}simplifyCandidate(t){if(t.length\u003c=2)return t;const e=[t[0]];let n=0;for(;n\u003ct.length-1;){let o=t.length-1;for(;o\u003en+1\u0026\u0026this.segmentCollides(t[n],t[o]);)o--;e.push(t[o]),n=o}return e.filter((t,e,n)=\u003e0===e||!Tq(t,n[e-1]))}pathCollides(t){if(t.length\u003c2)return!0;for(let e=0;e\u003ct.length-1;e++)if(this.segmentCollides(t[e],t[e+1]))return!0;return!1}segmentCollides(t,e){return this.problem.obstacleIndex.collides({start:t,end:e,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:-1})}createStats(){const t=Xq[this.variantCursor];return{phase:this.phase,direction:t?.direction,strength:t?.strength,variantCursor:this.variantCursor,relaxationIteration:this.relaxationIteration,sampledPointCount:this.sampledPoints.length}}computeProgress(){return Math.min(.99,(this.variantCursor+this.relaxationIteration/12)/Xq.length)}getOutput(){return this.output}getConstructorParams(){return[this.problem]}visualize(){return{coordinateSystem:\"cartesian\",title:`Elastic trace push: ${this.phase}`,lines:[...this.problem.corridor.map(t=\u003e({points:[t.start,t.end],strokeColor:\"rgba(255, 128, 0, 0.6)\",strokeWidth:t.width})),...this.candidatePoints.length\u003e1?[{points:this.candidatePoints,strokeColor:\"#1769d2\",strokeWidth:this.problem.traceWidth}]:[]],points:[],rects:[],circles:[],texts:[]}}},Hq=(t,e)=\u003e{const n=Math.abs(e.x-t.x),o=Math.abs(e.y-t.y);return n\u003c=Mq||o\u003c=Mq||Math.abs(n-o)\u003c=Mq},Gq=t=\u003e{let e=0;for(let n=0;n\u003ct.length-1;n++)Hq(t[n],t[n+1])||e++;return e},Uq=t=\u003e{let e=0;for(let n=0;n\u003ct.length-1;n++)e+=Nq(t[n],t[n+1]);return e},Zq=t=\u003et.filter((e,n)=\u003e0===n||!Tq(e,t[n-1])),qq=(t,e)=\u003e{const n=e.x-t.x,o=e.y-t.y,i=Math.abs(n),r=Math.abs(o),s=Math.sign(n),a=Math.sign(o),c=[];Hq(t,e)\u0026\u0026c.push([t,e]),c.push([t,{x:e.x,y:t.y},e],[t,{x:t.x,y:e.y},e]),i\u003e=r?c.push([t,{x:e.x-s*r,y:t.y},e],[t,{x:t.x+s*r,y:e.y},e]):c.push([t,{x:t.x,y:e.y-a*i},e],[t,{x:e.x,y:t.y+a*i},e]);const l=new Map;for(const t of c){const e=Zq(t);if(e.length\u003c2||e.some((t,n)=\u003en\u003ce.length-1\u0026\u0026!Hq(t,e[n+1])))continue;const n=e.map(t=\u003e`${t.x.toFixed(6)},${t.y.toFixed(6)}`).join(\";\");l.set(n,e)}return[...l.values()].sort((t,e)=\u003eUq(t)-Uq(e)||t.length-e.length)},Jq=class{nodeIndices=[];priorities=[];get size(){return this.nodeIndices.length}push(t,e){let n=this.nodeIndices.length;for(this.nodeIndices.push(t),this.priorities.push(e);n\u003e0;){const t=n-1\u003e\u003e1;if(this.priorities[t]\u003c=e)break;this.swap(n,t),n=t}}pop(){const t=this.nodeIndices[0],e=this.nodeIndices.pop(),n=this.priorities.pop();if(0===this.nodeIndices.length)return t;this.nodeIndices[0]=e,this.priorities[0]=n;let o=0;for(;;){const t=2*o+1,e=t+1;if(t\u003e=this.nodeIndices.length)break;let n=t;if(e\u003cthis.nodeIndices.length\u0026\u0026this.priorities[e]\u003cthis.priorities[t]\u0026\u0026(n=e),this.priorities[o]\u003c=this.priorities[n])break;this.swap(o,n),o=n}return t}swap(t,e){[this.nodeIndices[t],this.nodeIndices[e]]=[this.nodeIndices[e],this.nodeIndices[t]],[this.priorities[t],this.priorities[e]]=[this.priorities[e],this.priorities[t]]}},Kq=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]],Qq=class extends Sq{problem;searchBounds;rows;columns;origin;nodes=[];open=new Jq;bestCost;closed;closedCellCount=0;targetCell;output=null;constructor(t){super(),this.problem=t;const e=t.traceWidth/2+t.obstacleIndex.clearance,n=Rq(Math.min(t.start.x,t.end.x)-t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),o=Rq(Math.max(t.start.x,t.end.x)+t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),i=Rq(Math.min(t.start.y,t.end.y)-t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),r=Rq(Math.max(t.start.y,t.end.y)+t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),s=Math.floor((n-t.gridOffset.x)/t.gridSize)*t.gridSize+t.gridOffset.x,a=Math.floor((i-t.gridOffset.y)/t.gridSize)*t.gridSize+t.gridOffset.y;if(this.origin={x:s,y:a},this.columns=Math.max(2,Math.floor((o-s)/t.gridSize)+1),this.rows=Math.max(2,Math.floor((r-a)/t.gridSize)+1),this.searchBounds={minX:s,minY:a,maxX:s+(this.columns-1)*t.gridSize,maxY:a+(this.rows-1)*t.gridSize},this.bestCost=new Float64Array(this.rows*this.columns).fill(Number.POSITIVE_INFINITY),this.closed=new Uint8Array(this.rows*this.columns),this.endpointCollides(t.start)||this.endpointCollides(t.end))return this.failed=!0,this.error=\"Grid-route endpoint violates obstacle clearance\",this.targetCell={row:0,column:0},this.MAX_ITERATIONS=1,void(this.stats=this.createStats());const c=this.pointToCell(t.start);this.targetCell=this.pointToCell(t.end);const l={...c,x:t.start.x,y:t.start.y,g:0,f:this.heuristic(t.start),parentIndex:-1};this.nodes.push(l),this.open.push(0,l.f),this.bestCost[this.toFlatIndex(c.row,c.column)]=0,this.MAX_ITERATIONS=Math.min(5e3,Math.max(1e3,this.rows*this.columns*2)),this.stats=this.createStats()}endpointCollides(t){return this.problem.obstacleIndex.collides({start:t,end:t,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance})}getSolverName(){return`ObstacleAwareGridRouteSolver(${this.problem.gridSize.toFixed(3)}mm)`}_step(){if(0===this.open.size)return this.failed=!0,void(this.error=\"No collision-free grid route found\");const t=this.open.pop(),e=this.nodes[t],n=this.toFlatIndex(e.row,e.column);if(!this.closed[n]){if(this.closed[n]=1,this.closedCellCount++,e.row===this.targetCell.row\u0026\u0026e.column===this.targetCell.column\u0026\u0026null!==this.getAllowedConnector(e,this.problem.end))return this.output={points:this.reconstructPath(t),traceWidth:this.problem.traceWidth,gridSize:this.problem.gridSize,gridOffset:this.problem.gridOffset},this.solved=!0,void(this.stats=this.createStats());for(const[n,o]of Kq){const i=e.row+n,r=e.column+o;if(i\u003c0||i\u003e=this.rows||r\u003c0||r\u003e=this.columns)continue;const s=this.toFlatIndex(i,r);if(this.closed[s])continue;const a=this.cellToPoint(i,r),c=this.getAllowedConnector(e,a);if(null===c)continue;const l=-1===e.parentIndex\u0026\u0026this.problem.requireOctilinear?Uq(c):this.problem.gridSize*(0!==n\u0026\u00260!==o?Math.SQRT2:1),d=e.g+l;if(d\u003e=this.bestCost[s])continue;this.bestCost[s]=d;const h=d+this.heuristic(a),u=this.nodes.length;this.nodes.push({row:i,column:r,...a,g:d,f:h,parentIndex:t}),this.open.push(u,h)}this.stats=this.createStats()}}segmentCollides(t,e){return this.problem.obstacleIndex.collides({start:t,end:e,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance})}getAllowedConnector(t,e){return this.problem.requireOctilinear\u0026\u0026(\"parentIndex\"in t\u0026\u0026-1===t.parentIndex||Tq(e,this.problem.end))?qq(t,e).find(t=\u003et.slice(0,-1).every((e,n)=\u003e!this.segmentCollides(e,t[n+1])))??null:this.segmentCollides(t,e)?null:[t,e]}pointToCell(t){return{column:Rq(Math.round((t.x-this.origin.x)/this.problem.gridSize),0,this.columns-1),row:Rq(Math.round((t.y-this.origin.y)/this.problem.gridSize),0,this.rows-1)}}cellToPoint(t,e){return{x:this.origin.x+e*this.problem.gridSize,y:this.origin.y+t*this.problem.gridSize}}toFlatIndex(t,e){return t*this.columns+e}heuristic(t){return Math.hypot(this.problem.end.x-t.x,this.problem.end.y-t.y)}reconstructPath(t){const e=[];let n=t;for(;n\u003e=0;){const t=this.nodes[n];e.push({x:t.x,y:t.y}),n=t.parentIndex}if(e.reverse(),Tq(e[0],this.problem.start)||e.unshift({...this.problem.start}),Tq(e[e.length-1],this.problem.end)||e.push({...this.problem.end}),this.problem.requireOctilinear){const t=[e[0]];for(let n=0;n\u003ce.length-1;n++){const o=e[n],i=e[n+1],r=0===n||n===e.length-2?this.getAllowedConnector(0===n?{...o,parentIndex:-1}:o,i):[o,i];if(!r)return e;t.push(...r.slice(1))}return t.filter((t,e,n)=\u003e{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x);return Math.abs(r)\u003e1e-8||!Hq(o,i)})}const o=[e[0]];let i=0;for(;i\u003ce.length-1;){let t=e.length-1;for(;t\u003ei+1\u0026\u0026this.segmentCollides(e[i],e[t]);)t--;o.push(e[t]),i=t}return o.filter((t,e,n)=\u003e{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x);return Math.abs(r)\u003e1e-8})}createStats(){return{phase:\"obstacle-aware-grid-search\",gridSize:this.problem.gridSize,traceWidth:this.problem.traceWidth,gridOffset:this.problem.gridOffset,openCells:this.open.size,closedCells:this.closedCellCount,gridCells:this.rows*this.columns}}computeProgress(){return Math.min(.99,this.iterations/this.MAX_ITERATIONS)}getOutput(){return this.output}getConstructorParams(){const{obstacleIndex:t,...e}=this.problem;return[e]}visualize(){const t=this.nodes.filter(t=\u003ethis.closed[this.toFlatIndex(t.row,t.column)]).slice(-2e3).map(t=\u003e({x:t.x,y:t.y,color:\"rgba(0,90,255,0.22)\"})),e=this.output?.points??[];return{coordinateSystem:\"cartesian\",title:this.getSolverName(),rects:[{center:{x:(this.searchBounds.minX+this.searchBounds.maxX)/2,y:(this.searchBounds.minY+this.searchBounds.maxY)/2},width:this.searchBounds.maxX-this.searchBounds.minX,height:this.searchBounds.maxY-this.searchBounds.minY,stroke:\"#777\"}],points:[...t,{...this.problem.start,color:\"green\",label:\"reroute start\"},{...this.problem.end,color:\"purple\",label:\"reroute target\"}],lines:e.length\u003e1?[{points:e,strokeColor:\"#00a050\",strokeWidth:this.problem.traceWidth}]:[],circles:[],texts:[]}}},tJ=class{items;clearance;boardEdgeClearance;boardLayers;minViaHoleEdgeToViaHoleEdgeClearance;defaultViaHoleDiameter;bounds;maxIndexedViaHoleDiameter;index;connectionNameSets;copperObjectIds;connectionNameResolver;connectedPads;dynamicTraceIndex;constructor(t,e,n,o=[],i=new Pq(t,e)){var r;this.bounds=t.bounds,this.boardLayers=(r=t.layerCount,[\"top\",...Array.from({length:Math.max(0,r-2)},(t,e)=\u003e`inner${e+1}`),...r\u003e1?[\"bottom\"]:[]]),this.dynamicTraceIndex=n,this.clearance=Math.max(t.defaultObstacleMargin??0,t.minTraceToPadEdgeClearance??0,.1),this.boardEdgeClearance=t.minBoardEdgeClearance??this.clearance,this.minViaHoleEdgeToViaHoleEdgeClearance=Math.max(t.minViaHoleEdgeToViaHoleEdgeClearance??0,.1),this.defaultViaHoleDiameter=t.min_via_hole_diameter??t.minViaHoleDiameter??.3,this.items=[...t.obstacles.flatMap((t,e)=\u003efunction(t,e=.6){const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.max(1,Math.ceil(t.width/e)),i=Math.max(1,Math.ceil(t.height/e)),r=t.width/o,s=t.height/i,a=[];for(let e=0;e\u003ci;e++)for(let i=0;i\u003co;i++){const o={x:t.center.x-t.width/2+(i+.5)*r,y:t.center.y-t.height/2+(e+.5)*s},c=r/2,l=s/2,d=[{x:o.x-c,y:o.y-l},{x:o.x+c,y:o.y-l},{x:o.x+c,y:o.y+l},{x:o.x-c,y:o.y+l}].map(e=\u003eFq(e,t.center,n));a.push({minX:Math.min(...d.map(t=\u003et.x)),minY:Math.min(...d.map(t=\u003et.y)),maxX:Math.max(...d.map(t=\u003et.x)),maxY:Math.max(...d.map(t=\u003et.y)),layers:t.layers,kind:\"obstacle\",obstacleKind:t.connectedTo[0]?.startsWith(\"pcb_via_\")?\"via\":t.connectedTo[0]?.startsWith(\"pcb_smtpad_\")||t.connectedTo[0]?.startsWith(\"pcb_plated_hole_\")?\"pad\":\"other\",connectionNames:t.connectedTo,exactShape:{type:\"polygon\",points:d}})}return a}(t).map(t=\u003e({...t,copperObjectId:`obstacle:${e}`}))),...this.createTraceItems(t.fixedTraces??[],!0),...this.createTraceItems(e),...o],this.maxIndexedViaHoleDiameter=this.items.reduce((t,e)=\u003e\"via\"===e.kind?Math.max(t,e.viaHoleDiameter??this.defaultViaHoleDiameter):t,this.defaultViaHoleDiameter),this.connectionNameResolver=i,this.connectionNameSets=this.items.map(t=\u003enew Set(i.canonicalize(t.connectionNames))),this.copperObjectIds=this.items.map((t,e)=\u003et.copperObjectId??`indexed-item:${e}`),this.connectedPads=t.obstacles.flatMap(t=\u003et.connectedTo.some(t=\u003et.startsWith(\"pcb_smtpad_\")||t.startsWith(\"pcb_plated_hole_\"))?[{obstacle:t,canonicalConnectionNames:new Set(i.canonicalize(t.connectedTo))}]:[]),this.index=this.items.length\u003e0?new Bt(this.items.length):null;for(const t of this.items)this.index.add(t.minX,t.minY,t.maxX,t.maxY);this.index?.finish()}createTraceItems(t,e=!1){const n=[];for(let o=0;o\u003ct.length;o++){const i=t[o],r=e?void 0:o,s=`${e?\"fixed-trace\":\"trace\"}:${o}`,a=!e\u0026\u0026o===this.dynamicTraceIndex,c=[i.connection_name,i.source_trace_id,i.rootConnectionName,...i.mergedConnectionNames??[],...i.connectsTo??[]].filter(t=\u003eBoolean(t));for(let t=0;t\u003ci.route.length;t++){const e=i.route[t];if(\"via\"===e.route_type){const o=e.via_diameter??.6;n.push({minX:e.x-o/2,minY:e.y-o/2,maxX:e.x+o/2,maxY:e.y+o/2,layers:this.boardLayers,kind:\"via\",connectionNames:c,copperObjectId:s,traceIndex:r,routeStartIndex:t,routeEndIndex:t,viaHoleDiameter:e.via_hole_diameter??this.defaultViaHoleDiameter,exactShape:{type:\"circle\",center:{x:e.x,y:e.y},radius:o/2}});continue}if(a)continue;const o=i.route[t+1];\"wire\"===e.route_type\u0026\u0026\"wire\"===o?.route_type\u0026\u0026e.layer===o.layer\u0026\u0026n.push(...zq({start:e,end:o,width:e.width,base:{layers:[e.layer],kind:\"trace\",connectionNames:c,copperObjectId:s,traceIndex:r,routeStartIndex:t,routeEndIndex:t+1}}))}}return n}collides(t){if(this.isOutsideBounds(t))return!0;const{radius:e,candidates:n,canonicalConnectionNames:o}=this.getCollisionCandidates(t);for(const i of n)if(this.itemCollides(i,t,e,o))return!0;return!1}findCollisions(t){const{radius:e,candidates:n,canonicalConnectionNames:o}=this.getCollisionCandidates(t),i=[];for(const r of n)this.itemCollides(r,t,e,o)\u0026\u0026i.push(this.items[r]);return i}getSameNetCopperContactIds(t){const e=t.width/2,n=this.index?.search(Math.min(t.start.x,t.end.x)-e,Math.min(t.start.y,t.end.y)-e,Math.max(t.start.x,t.end.x)+e,Math.max(t.start.y,t.end.y)+e)??[],o=new Set(this.connectionNameResolver.canonicalize(t.connectionNames)),i=new Set;for(const r of n){const n=this.items[r];n.layers.includes(t.layer)\u0026\u0026(n.traceIndex===t.ignoreTraceIndex||t.ignoreTraceIndices?.includes(n.traceIndex??-1)||[...this.connectionNameSets[r]].some(t=\u003eo.has(t))\u0026\u0026this.itemCopperTouches(n,t,e)\u0026\u0026i.add(this.copperObjectIds[r]))}return i}getConnectedPadWidthLimit(t){if(Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y)\u003c=1e-5)return null;const e=this.getConnectedPadWidthLimitAtPoint(t,t.start),n=this.getConnectedPadWidthLimitAtPoint(t,t.end);return null===e?n:null===n?e:Math.min(e,n)}getConnectedPadWidthLimitAtPoint(t,e){const n=this.getConnectedPadsAtPoint(t,e);return 0===n.length?null:Math.max(...n.map(({obstacle:e})=\u003ethis.getPadWidthNormalToQuery(e,t)))}getConnectedPadEndpointWidthLimitAtPoint(t,e){const n=this.getConnectedPadsAtPoint(t,e);return 0===n.length?null:Math.max(...n.map(({obstacle:t})=\u003e{const n=this.getObstacleLocalPoint(e,t);return Math.max(0,2*Math.min(t.width/2-Math.abs(n.x),t.height/2-Math.abs(n.y)))}))}getConnectedPadBoundaryPoint(t,e){const n=\"start\"===e?t.start:t.end,o=\"start\"===e?t.end:t.start,i=this.getConnectedPadsAtPoint(t,n).sort((e,n)=\u003ethis.getPadWidthNormalToQuery(n.obstacle,t)-this.getPadWidthNormalToQuery(e.obstacle,t))[0];return!i||this.pointIsInsideObstacle(o,i.obstacle)?null:this.getObstacleBoundaryPoint(n,o,i.obstacle)}getConnectedPadsAtPoint(t,e){const n=new Set(this.connectionNameResolver.canonicalize(t.connectionNames));return this.connectedPads.filter(({obstacle:o,canonicalConnectionNames:i})=\u003eo.layers.includes(t.layer)\u0026\u0026[...i].some(t=\u003en.has(t))\u0026\u0026this.pointIsInsideObstacle(e,o))}pointIsInsideObstacle(t,e){const{x:n,y:o}=this.getObstacleLocalPoint(t,e);return Math.abs(n)\u003c=e.width/2+1e-9\u0026\u0026Math.abs(o)\u003c=e.height/2+1e-9}getObstacleLocalPoint(t,e){const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=Math.cos(n),i=Math.sin(n),r=t.x-e.center.x,s=t.y-e.center.y;return{x:r*o-s*i,y:r*i+s*o}}getPadWidthNormalToQuery(t,e){const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.hypot(n,o);if(i\u003c=1e-9)return Math.min(t.width,t.height);const r=-o/i,s=n/i,a=-(t.ccwRotationDegrees??0)*Math.PI/180,c=Math.cos(a),l=Math.sin(a),d=r*c-s*l,h=r*l+s*c;return Math.abs(d)*t.width+Math.abs(h)*t.height}getObstacleBoundaryPoint(t,e,n){const o=-(n.ccwRotationDegrees??0)*Math.PI/180,i=Math.cos(o),r=Math.sin(o),s=t=\u003e{const e=t.x-n.center.x,o=t.y-n.center.y;return{x:e*i-o*r,y:e*r+o*i}},a=s(t),c=s(e),l={x:c.x-a.x,y:c.y-a.y},d=[];if(Math.abs(l.x)\u003e1e-12){const t=l.x\u003e0?n.width/2:-n.width/2;d.push((t-a.x)/l.x)}if(Math.abs(l.y)\u003e1e-12){const t=l.y\u003e0?n.height/2:-n.height/2;d.push((t-a.y)/l.y)}const h=Math.min(...d.filter(t=\u003et\u003e=0\u0026\u0026t\u003c=1));return Number.isFinite(h)?{x:t.x+(e.x-t.x)*h,y:t.y+(e.y-t.y)*h}:null}getConnectedLayersAtPoint(t,e){const n=new Set(this.connectionNameResolver.canonicalize(e)),o=new Set,i=this.index?.search(t.x,t.y,t.x,t.y)??[];for(const e of i){const i=this.items[e];if(\"obstacle\"!==i.kind)continue;if(![...this.connectionNameSets[e]].some(t=\u003en.has(t)))continue;if(\"polygon\"===i.exactShape?.type?Lq(t,t,i.exactShape.points)\u003c=1e-9:\"circle\"===i.exactShape?.type?Math.hypot(i.exactShape.center.x-t.x,i.exactShape.center.y-t.y)\u003c=i.exactShape.radius+1e-9:t.x\u003e=i.minX-1e-9\u0026\u0026t.x\u003c=i.maxX+1e-9\u0026\u0026t.y\u003e=i.minY-1e-9\u0026\u0026t.y\u003c=i.maxY+1e-9)for(const t of i.layers)o.add(t)}return[...o]}collidesVia(t){return this.getViaViolationSignatures(t).size\u003e0}getViaViolationSignatures(t){const e=new Set;for(const n of t.layers){const o={start:t.point,end:t.point,layer:n,width:t.padDiameter,connectionNames:t.connectionNames,ignoreTraceIndex:t.ignoreTraceIndex,ignoreTraceIndices:t.ignoreTraceIndices,ignoreRouteRange:t.ignoreRouteRange,obstacleClearance:t.obstacleClearance,blockSameNetObstacles:t.blockSameNetObstacles,sameNetObstacleClearance:t.sameNetObstacleClearance};this.isOutsideBounds(o)\u0026\u0026e.add(`board-edge:${n}`);const{radius:i,candidates:r,canonicalConnectionNames:s}=this.getCollisionCandidates(o);for(const t of r)this.itemCollides(t,o,i,s)\u0026\u0026e.add(`copper:${n}:${this.getViolationObjectId(t)}`)}const n=t.holeDiameter+this.minViaHoleEdgeToViaHoleEdgeClearance;for(const o of t.otherNewViaPoints??[])Math.hypot(o.x-t.point.x,o.y-t.point.y)\u003cn-1e-9\u0026\u0026e.add(`new-via-drill:${o.x},${o.y}:${t.holeDiameter}`);const o=t.fixedVias??[];for(let n=0;n\u003co.length;n++){const i=o[n],r=t.holeDiameter/2+i.holeDiameter/2+this.minViaHoleEdgeToViaHoleEdgeClearance;Math.hypot(i.point.x-t.point.x,i.point.y-t.point.y)\u003cr-1e-9\u0026\u0026e.add(`fixed-via-drill:${n}:${i.point.x},${i.point.y}:${i.holeDiameter}`)}const i=t.holeDiameter/2+this.maxIndexedViaHoleDiameter/2+this.minViaHoleEdgeToViaHoleEdgeClearance,r=this.index?.search(t.point.x-i,t.point.y-i,t.point.x+i,t.point.y+i)??[],s=new Set;for(const n of r){const o=this.items[n];if(\"via\"!==o.kind||\"circle\"!==o.exactShape?.type)continue;if(o.traceIndex===t.ignoreTraceIndex\u0026\u0026t.ignoreRouteRange\u0026\u0026(o.routeEndIndex??-1)\u003e=t.ignoreRouteRange.start\u0026\u0026(o.routeStartIndex??Number.POSITIVE_INFINITY)\u003c=t.ignoreRouteRange.end)continue;if(t.ignoreTraceIndices?.includes(o.traceIndex??-1))continue;const i=`${this.copperObjectIds[n]??\"unknown\"}:${o.routeStartIndex??-1}`;if(s.has(i))continue;s.add(i);const r=o.viaHoleDiameter??this.defaultViaHoleDiameter,a=t.holeDiameter/2+r/2+this.minViaHoleEdgeToViaHoleEdgeClearance;Math.hypot(o.exactShape.center.x-t.point.x,o.exactShape.center.y-t.point.y)\u003ca-1e-9\u0026\u0026e.add(`indexed-via-drill:${this.getViolationObjectId(n)}`)}return e}getViolationObjectId(t){const e=this.items[t],n=this.copperObjectIds[t],o=`${e.routeStartIndex??\"\"}-${e.routeEndIndex??\"\"}`;if(\"obstacle\"===e.kind)return n;if(\"segment\"===e.exactShape?.type){const{start:t,end:i,width:r}=e.exactShape;return`${n}:${e.kind}:${o}:${t.x},${t.y}:${i.x},${i.y}:${r}`}if(\"circle\"===e.exactShape?.type){const{center:t,radius:i}=e.exactShape;return`${n}:${e.kind}:${o}:${t.x},${t.y}:${i}`}return\"polygon\"===e.exactShape?.type?`${n}:${e.kind}:${o}:${e.exactShape.points.map(t=\u003e`${t.x},${t.y}`).join(\";\")}`:`${n}:${e.kind}:${o}:${e.minX},${e.minY},${e.maxX},${e.maxY}`}getCollisionCandidates(t){const e=Math.max(this.clearance,t.obstacleClearance??this.clearance,t.sameNetObstacleClearance??0),n=t.width/2+e,o={minX:Math.min(t.start.x,t.end.x)-n,minY:Math.min(t.start.y,t.end.y)-n,maxX:Math.max(t.start.x,t.end.x)+n,maxY:Math.max(t.start.y,t.end.y)+n};return{radius:n,candidates:this.index?.search(o.minX,o.minY,o.maxX,o.maxY)??[],canonicalConnectionNames:this.connectionNameResolver.canonicalize(t.connectionNames)}}itemCollides(t,e,n,o){const i=this.items[t];if(!i.layers.includes(e.layer))return!1;const r=this.connectionNameSets[t],s=o.some(t=\u003er.has(t));if(s\u0026\u0026(!e.blockSameNetObstacles||\"obstacle\"!==i.kind||\"via\"===i.obstacleKind))return!1;if(\"trace\"===i.kind\u0026\u0026e.ignoreTraceIndices?.includes(i.traceIndex??-1))return!1;if(\"trace\"===i.kind\u0026\u0026i.traceIndex===e.ignoreTraceIndex\u0026\u0026e.ignoreRouteRange\u0026\u0026(i.routeEndIndex??-1)\u003e=e.ignoreRouteRange.start\u0026\u0026(i.routeStartIndex??Number.POSITIVE_INFINITY)\u003c=e.ignoreRouteRange.end)return!1;const a=\"obstacle\"===i.kind\u0026\u0026\"pad\"===i.obstacleKind?s\u0026\u0026e.blockSameNetObstacles?e.sameNetObstacleClearance??e.obstacleClearance??this.clearance:e.obstacleClearance??this.clearance:this.clearance,c=e.width/2+a;return\"segment\"===i.exactShape?.type?Oq(e.start,e.end,i.exactShape.start,i.exactShape.end)\u003c=c+i.exactShape.width/2+1e-9:\"polygon\"===i.exactShape?.type?Lq(e.start,e.end,i.exactShape.points)\u003c=c+1e-9:\"circle\"===i.exactShape?.type?wq(i.exactShape.center,e.start,e.end)\u003c=c+i.exactShape.radius+1e-9:Dq(e.start,e.end,{minX:i.minX-c,minY:i.minY-c,maxX:i.maxX+c,maxY:i.maxY+c})}itemCopperTouches(t,e,n){return\"segment\"===t.exactShape?.type?Oq(e.start,e.end,t.exactShape.start,t.exactShape.end)\u003c=n+t.exactShape.width/2+1e-9:\"polygon\"===t.exactShape?.type?Lq(e.start,e.end,t.exactShape.points)\u003c=n+1e-9:\"circle\"===t.exactShape?.type?wq(t.exactShape.center,e.start,e.end)\u003c=n+t.exactShape.radius+1e-9:Dq(e.start,e.end,{minX:t.minX-n,minY:t.minY-n,maxX:t.maxX+n,maxY:t.maxY+n})}isOutsideBounds(t){const e=t.width/2+this.boardEdgeClearance;return Math.min(t.start.x,t.end.x)-e\u003cthis.bounds.minX||Math.max(t.start.x,t.end.x)+e\u003ethis.bounds.maxX||Math.min(t.start.y,t.end.y)-e\u003cthis.bounds.minY||Math.max(t.start.y,t.end.y)+e\u003ethis.bounds.maxY}},eJ=[{x:0,y:0},{x:.5,y:0},{x:0,y:.5},{x:.5,y:.5}],nJ=t=\u003e\"wire\"===t?.route_type,oJ=class extends Sq{inputProblem;traces;corridor;phase=\"scan-corridor\";corridorCursor=0;blockerCursor=0;offsetCursor=0;resolutionCursor=0;attemptedGridCount=0;blockerIndex;connectionNameResolver;connectionByTraceId=new Map;mutableTraceIndices;blockersByTrace=new Map;blockers=[];currentBlocker=null;currentRange=null;currentTraceWidth=0;gridResolutions=[];currentObstacleIndex=null;output=null;constructor(t,e=new Pq(t.simpleRouteJson,t.traces)){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.corridor=structuredClone(t.corridor),this.mutableTraceIndices=t.mutableTraceIndices?new Set(t.mutableTraceIndices):null,this.connectionNameResolver=e,this.blockerIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,t.powerTraceIndex,[],this.connectionNameResolver),this.activeSubSolver=null,this.MAX_ITERATIONS=25e3,this.stats=this.createStats()}getSolverName(){return\"LocalTraceInflationSolver\"}_step(){if(this.activeSubSolver)return this.stepActiveSubSolver(),void(this.stats=this.createStats());switch(this.phase){case\"scan-corridor\":this.scanNextCorridorSegment();break;case\"select-blocker\":this.selectNextBlocker();break;case\"try-elastic-push\":break;case\"try-grid-candidate\":this.startNextGridCandidate();break;case\"complete\":this.output?this.solved=!0:(this.failed=!0,this.error=\"No locally reroutable trace blocks the power corridor\")}this.stats=this.createStats()}scanNextCorridorSegment(){const t=this.corridor[this.corridorCursor];if(!t)return this.blockers=[...this.blockersByTrace.values()].sort((t,e)=\u003et.traceIndex-e.traceIndex),void(this.phase=\"select-blocker\");const e=this.traces[this.inputProblem.powerTraceIndex],n=this.blockerIndex.findCollisions({start:t.start,end:t.end,layer:t.layer,width:t.width,connectionNames:e?this.getTraceConnectionNames(e):[]});for(const t of n)this.recordBlockingTrace(t);this.corridorCursor++}recordBlockingTrace(t){if(\"trace\"!==t.kind||void 0===t.traceIndex||void 0===t.routeStartIndex||void 0===t.routeEndIndex||t.traceIndex===this.inputProblem.powerTraceIndex||null!==this.mutableTraceIndices\u0026\u0026!this.mutableTraceIndices.has(t.traceIndex))return;const e=this.traces[t.traceIndex];if(!e)return;const n=this.findConnectionForTrace(e);if((n?this.resolveNominalTraceWidth(n):this.getTraceNominalWidth(e))\u003e=(this.inputProblem.pushOnlyNominalWidthsBelow??this.inputProblem.nominalPowerWidth)-Mq)return;const o=this.blockersByTrace.get(t.traceIndex);if(o)return o.firstRouteIndex=Math.min(o.firstRouteIndex,t.routeStartIndex),void(o.lastRouteIndex=Math.max(o.lastRouteIndex,t.routeEndIndex));this.blockersByTrace.set(t.traceIndex,{traceIndex:t.traceIndex,firstRouteIndex:t.routeStartIndex,lastRouteIndex:t.routeEndIndex})}selectNextBlocker(){if(this.currentBlocker=this.blockers[this.blockerCursor]??null,!this.currentBlocker)return void(this.phase=\"complete\");const t=this.findStableAnchorRange(this.currentBlocker);if(!t)return void this.blockerCursor++;const e=this.traces[this.currentBlocker.traceIndex];this.currentRange=t,this.currentTraceWidth=this.getRangeWidth(e,t),this.gridResolutions=this.getGridResolutions(this.currentTraceWidth),this.resolutionCursor=0,this.offsetCursor=0,this.currentObstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,this.currentBlocker.traceIndex,this.createInflatedCorridorItems(),this.connectionNameResolver),this.activeSubSolver=new Wq({trace:e,range:t,layer:e.route[t.startIndex].layer,traceWidth:this.currentTraceWidth,corridor:this.corridor,obstacleIndex:this.currentObstacleIndex,connectionNames:this.getTraceConnectionNames(e)}),this.phase=\"try-elastic-push\"}findStableAnchorRange(t){const e=this.traces[t.traceIndex];if(!e)return null;let n=t.firstRouteIndex,o=t.lastRouteIndex;for(;n\u003e0;){const t=e.route[n];if(nJ(t)\u0026\u0026this.pointClearsCorridor(t))break;n--}for(;o\u003ce.route.length-1;){const t=e.route[o];if(nJ(t)\u0026\u0026this.pointClearsCorridor(t))break;o++}const i=e.route[n],r=e.route[o];if(!nJ(i)||!nJ(r)||i.layer!==r.layer||!this.pointClearsCorridor(i)||!this.pointClearsCorridor(r)||n\u003e=o)return null;const s={startIndex:n,endIndex:o},a=this.getRangeLength(e,s);return!Number.isFinite(a)||a\u003e(this.inputProblem.maxRerouteLength??10)+Mq?null:s}pointClearsCorridor(t){return this.corridor.every(e=\u003e{if(e.layer!==t.layer)return!0;const n=e.width/2+t.width/2+this.blockerIndex.clearance;return wq(t,e.start,e.end)\u003e=n-Mq})}startNextGridCandidate(){if(!this.currentBlocker||!this.currentRange)return void(this.phase=\"select-blocker\");if(this.resolutionCursor\u003e=this.gridResolutions.length)return this.blockerCursor++,void(this.phase=\"select-blocker\");if(this.offsetCursor\u003e=eJ.length)return this.resolutionCursor++,void(this.offsetCursor=0);const t=this.traces[this.currentBlocker.traceIndex],e=t.route[this.currentRange.startIndex],n=t.route[this.currentRange.endIndex];if(!nJ(e)||!nJ(n))return this.blockerCursor++,void(this.phase=\"select-blocker\");const o=this.gridResolutions[this.resolutionCursor],i=eJ[this.offsetCursor],r=this.currentObstacleIndex;if(!r)return this.blockerCursor++,void(this.phase=\"select-blocker\");this.attemptedGridCount++,this.activeSubSolver=new Qq({start:e,end:n,layer:e.layer,traceWidth:this.currentTraceWidth,gridSize:o,gridOffset:{x:i.x*o,y:i.y*o},connectionNames:this.getTraceConnectionNames(t),obstacleIndex:r,ignoreTraceIndex:this.currentBlocker.traceIndex,ignoreRouteRange:{start:this.currentRange.startIndex,end:this.currentRange.endIndex},bounds:this.inputProblem.simpleRouteJson.bounds,searchPadding:Rq(2.5*this.inputProblem.nominalPowerWidth,1.5,4)})}stepActiveSubSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e)return this.applyRoute(e,t instanceof Wq?\"elastic\":\"grid\"),this.activeSubSolver=null,void(this.phase=\"complete\")}this.failedSubSolvers??=[],this.failedSubSolvers.push(t),this.activeSubSolver=null,t instanceof Wq?this.phase=\"try-grid-candidate\":this.offsetCursor++}}applyRoute(t,e){const n=this.currentBlocker,o=this.currentRange,i=this.traces[n.traceIndex],r=i.route[o.startIndex],s=i.route[o.endIndex],a=t.points.map(t=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:this.currentTraceWidth,layer:r.layer}));a[0].width=Math.max(a[0].width,r.width),a[a.length-1].width=Math.max(a[a.length-1].width,s.width),i.route.splice(o.startIndex,o.endIndex-o.startIndex+1,...a),this.output={traces:this.traces,pushedTraceIndex:n.traceIndex,replacedRange:o,strategy:e}}createInflatedCorridorItems(){return this.corridor.flatMap(t=\u003ezq({start:t.start,end:t.end,width:t.width,base:{layers:[t.layer],kind:\"obstacle\",connectionNames:[]}}))}getGridResolutions(t){return[Rq(1.5*t,.1,.3),Rq(.75*t,.08,.18)].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e-t)\u003cMq)===e)}getRangeWidth(t,e){let n=this.inputProblem.simpleRouteJson.minTraceWidth;for(let o=e.startIndex;o\u003c=e.endIndex;o++){const e=t.route[o];nJ(e)\u0026\u0026(n=Math.max(n,e.width))}return n}getRangeLength(t,e){let n=0;for(let o=e.startIndex;o\u003ce.endIndex;o++){const e=t.route[o],i=t.route[o+1];if(!nJ(e)||!nJ(i)||e.layer!==i.layer)return Number.POSITIVE_INFINITY;n+=Nq(e,i)}return n}resolveNominalTraceWidth(t){return Math.max(t.nominalTraceWidth??t.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.inputProblem.simpleRouteJson.minTraceWidth,this.inputProblem.simpleRouteJson.minTraceWidth)}getTraceNominalWidth(t){return t.route.reduce((t,e)=\u003e\"wire\"===e.route_type?Math.max(t,e.width):t,this.inputProblem.simpleRouteJson.minTraceWidth)}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=this.getTraceConnectionNames(t),o=this.inputProblem.simpleRouteJson.connections.find(t=\u003e[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t)).some(t=\u003en.includes(t)))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getTraceConnectionNames(t){return[t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))}createStats(){return{phase:this.phase,corridorSegment:this.corridorCursor,corridorSegmentCount:this.corridor.length,blockingTraceCount:this.blockersByTrace.size,blockerCursor:this.blockerCursor,pushedTraceIndex:this.currentBlocker?.traceIndex,anchorRange:this.currentRange,traceWidth:this.currentTraceWidth,gridSize:this.gridResolutions[this.resolutionCursor],gridOffsetVariant:this.offsetCursor,attemptedGridCount:this.attemptedGridCount}}computeProgress(){return\"scan-corridor\"===this.phase?0===this.corridor.length?.25:this.corridorCursor/this.corridor.length*.25:0===this.blockers.length?.5:Math.min(.99,.25+this.blockerCursor/this.blockers.length)}getOutput(){return this.output}getConstructorParams(){return[this.inputProblem]}visualize(){const t=[];for(let e=0;e\u003cthis.traces.length;e++){const n=this.traces[e];for(let o=0;o\u003cn.route.length-1;o++){const i=n.route[o],r=n.route[o+1];nJ(i)\u0026\u0026nJ(r)\u0026\u0026i.layer===r.layer\u0026\u0026t.push({points:[i,r],strokeColor:e===this.currentBlocker?.traceIndex?\"#1769d2\":\"#777\",strokeWidth:Math.max(i.width,r.width)})}}for(const e of this.corridor)t.push({points:[e.start,e.end],strokeColor:\"rgba(255, 128, 0, 0.55)\",strokeWidth:e.width});return{coordinateSystem:\"cartesian\",title:this.getSolverName(),lines:t,points:[],rects:[],circles:[],texts:[]}}},iJ=1e-6,rJ=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y),sJ=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r\u003c=1e-12?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},aJ=(t,e,n)=\u003e(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),cJ=(t,e,n,o)=\u003e((t,e,n,o)=\u003e{const i=aJ(n,o,t),r=aJ(n,o,e),s=aJ(t,e,n),a=aJ(t,e,o);return(i\u003e0\u0026\u0026r\u003c0||i\u003c0\u0026\u0026r\u003e0)\u0026\u0026(s\u003e0\u0026\u0026a\u003c0||s\u003c0\u0026\u0026a\u003e0)})(t,e,n,o)?0:Math.min(sJ(t,n,o),sJ(e,n,o),sJ(n,t,e),sJ(o,t,e)),lJ=t=\u003e{const e=(t.ccwRotationDegrees??0)*Math.PI/180,n=Math.cos(e),o=Math.sin(e);return[{x:-t.width/2,y:-t.height/2},{x:t.width/2,y:-t.height/2},{x:t.width/2,y:t.height/2},{x:-t.width/2,y:t.height/2}].map(e=\u003e({x:t.center.x+e.x*n-e.y*o,y:t.center.y+e.x*o+e.y*n}))},dJ=t=\u003e{if(!(\"oval\"===t.type||\"circle\"===t.shape))return!1;if(Math.abs(t.width-t.height)\u003eiJ)throw new Error(`Physical connectivity does not yet support non-circular oval obstacle ${t.obstacleId??\"\u003cunknown\u003e\"}`);return!0},hJ=(t,e)=\u003e{for(let n=0;n\u003ce.length;n++)if(sJ(t,e[n],e[(n+1)%e.length])\u003c=iJ)return!0;let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n},uJ=(t,e)=\u003e{if(dJ(e))return Math.max(0,rJ(t,e.center)-e.width/2);const n=lJ(e);return hJ(t,n)?0:Math.min(...n.map((e,o)=\u003esJ(t,e,n[(o+1)%n.length])))},pJ=(t,e)=\u003e{if(dJ(t))return dJ(e)?Math.max(0,rJ(t.center,e.center)-t.width/2-e.width/2):Math.max(0,uJ(t.center,e)-t.width/2);if(dJ(e))return pJ(e,t);const n=lJ(t),o=lJ(e);if(hJ(n[0],o)||hJ(o[0],n))return 0;let i=Number.POSITIVE_INFINITY;for(let t=0;t\u003cn.length;t++)for(let e=0;e\u003co.length;e++)i=Math.min(i,cJ(n[t],n[(t+1)%n.length],o[e],o[(e+1)%o.length]));return i},mJ=(t,e)=\u003e({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),gJ=t=\u003e({minX:t.x,minY:t.y,maxX:t.x,maxY:t.y}),fJ=t=\u003e{if(dJ(t))return mJ(gJ(t.center),t.width/2);const e=lJ(t);return{minX:Math.min(...e.map(t=\u003et.x)),minY:Math.min(...e.map(t=\u003et.y)),maxX:Math.max(...e.map(t=\u003et.x)),maxY:Math.max(...e.map(t=\u003et.y))}},yJ=(t,e)=\u003e{if(!((t,e)=\u003et.layers.some(t=\u003ee.layers.includes(t)))(t,e)||!((t,e)=\u003et.maxX+iJ\u003e=e.minX\u0026\u0026e.maxX+iJ\u003e=t.minX\u0026\u0026t.maxY+iJ\u003e=e.minY\u0026\u0026e.maxY+iJ\u003e=t.minY)(t.bounds,e.bounds))return!1;if(\"bridge-pad\"===t.kind){const n={kind:\"obstacle\",obstacle:t.obstacle,layers:t.layers,bounds:t.bounds};return\"bridge-pad\"===e.kind?yJ(n,{kind:\"obstacle\",obstacle:e.obstacle,layers:e.layers,bounds:e.bounds}):yJ(n,e)}return\"bridge-pad\"===e.kind?yJ(e,t):\"endpoint\"===t.kind?\"endpoint\"===e.kind?rJ(t.point,e.point)\u003c=iJ:\"obstacle\"===e.kind?uJ(t.point,e.obstacle)\u003c=iJ:\"segment\"===e.kind?sJ(t.point,e.start,e.end)\u003c=e.width/2+iJ:rJ(t.point,e.center)\u003c=e.diameter/2+iJ:\"endpoint\"===e.kind?yJ(e,t):\"obstacle\"===t.kind?\"obstacle\"===e.kind?pJ(t.obstacle,e.obstacle)\u003c=iJ:\"segment\"===e.kind?((t,e,n)=\u003e{if(dJ(n))return Math.max(0,sJ(n.center,t,e)-n.width/2);const o=lJ(n);return hJ(t,o)||hJ(e,o)?0:Math.min(...o.map((n,i)=\u003ecJ(t,e,n,o[(i+1)%o.length])))})(e.start,e.end,t.obstacle)\u003c=e.width/2+iJ:uJ(e.center,t.obstacle)\u003c=e.diameter/2+iJ:\"obstacle\"===e.kind?yJ(e,t):\"segment\"===t.kind?\"segment\"===e.kind?cJ(t.start,t.end,e.start,e.end)\u003c=(t.width+e.width)/2+iJ:sJ(e.center,t.start,t.end)\u003c=t.width/2+e.diameter/2+iJ:\"segment\"===e.kind?yJ(e,t):rJ(t.center,e.center)\u003c=(t.diameter+e.diameter)/2+iJ},_J=class{parent;constructor(t){this.parent=Array.from({length:t},(t,e)=\u003ee)}find(t){const e=this.parent[t];if(e===t)return t;const n=this.find(e);return this.parent[t]=n,n}union(t,e){const n=this.find(t),o=this.find(e);n!==o\u0026\u0026(this.parent[o]=n)}},bJ=(t,e)=\u003e{const n=e.indexOf(t.from_layer),o=e.indexOf(t.to_layer);return n\u003c0||o\u003c0?[...new Set([t.from_layer,t.to_layer])]:e.slice(Math.min(n,o),Math.max(n,o)+1)},xJ=t=\u003e[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=\u003eBoolean(t)),vJ=t=\u003e[t.name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],t.netConnectionName,...t.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])].filter(t=\u003eBoolean(t)),SJ=t=\u003e[t.obstacleId,...t.connectedTo,...t.offBoardConnectsTo??[]].filter(t=\u003eBoolean(t)),IJ=(t,e,n,o)=\u003e({kind:\"bridge-contact\",center:{x:t.x,y:t.y},diameter:e,layers:n,bridgeId:o,bounds:mJ(gJ(t),e/2)}),CJ=.01,PJ={\"0603\":{horizontalWidth:.8,horizontalHeight:.95,centerSpacings:[1.65,1.8]},1206:{horizontalWidth:.6,horizontalHeight:1.6,centerSpacings:[3.2]},\"1206x4_pair\":{horizontalWidth:.8,horizontalHeight:.5,centerSpacings:[2.7]}},MJ=(t,e,n)=\u003e{if(!t.layer)throw new Error(`Jumper ${n} is missing its layer`);const o=PJ[t.footprint];if(!o)throw new Error(`Unsupported jumper footprint ${String(t.footprint)} on ${n}`);const i=Math.abs(t.end.x-t.start.x),r=Math.abs(t.end.y-t.start.y),s=t=\u003eo.centerSpacings.some(e=\u003eMath.abs(t-e)\u003cCJ),a=r\u003cCJ\u0026\u0026s(i),c=i\u003cCJ\u0026\u0026s(r);if(!a\u0026\u0026!c)throw new Error(`Jumper ${n} does not match ${t.footprint} pad spacing`);const l={type:\"rect\",center:{...e},width:a?o.horizontalWidth:o.horizontalHeight,height:a?o.horizontalHeight:o.horizontalWidth,layers:[t.layer],connectedTo:[]};return{kind:\"bridge-pad\",obstacle:l,layers:l.layers,bridgeId:n,bounds:fJ(l)}},NJ=(t,e,n)=\u003e{if(t.layer!==n.layer||e.layer!==n.layer)return!1;const o=(t,e)=\u003eMath.abs(t.x-e.x)\u003cCJ\u0026\u0026Math.abs(t.y-e.y)\u003cCJ,i=o(t,n.start)\u0026\u0026o(e,n.end),r=o(t,n.end)\u0026\u0026o(e,n.start);return i||r},wJ=(t,e,n,o)=\u003e{const i=[],r=t.route.flatMap((t,e)=\u003e\"jumper\"===t.route_type?[{routePoint:t,routePointIndex:e}]:[]),s=new Map;for(const e of r){const n=[];for(let o=1;o\u003ct.route.length;o++){const i=t.route[o-1],r=t.route[o];\"wire\"===i?.route_type\u0026\u0026\"wire\"===r?.route_type\u0026\u0026NJ(i,r,e.routePoint)\u0026\u0026n.push(o)}if(1!==n.length)throw new Error(`Jumper ${t.pcb_trace_id}:${e.routePointIndex} matched ${n.length} placeholder wire segments`);const o=n[0];if(s.has(o))throw new Error(`Multiple jumpers matched placeholder segment ${o} on ${t.pcb_trace_id}`);s.set(o,e)}let a;for(let r=0;r\u003ct.route.length;r++){const c=t.route[r];if(\"wire\"===c.route_type){if(a\u0026\u0026a.layer===c.layer\u0026\u0026rJ(a,c)\u003eiJ){const t=a;if(s.get(r));else{const e=t.width/2;i.push({kind:\"segment\",start:{x:t.x,y:t.y},end:{x:c.x,y:c.y},width:t.width,layers:[t.layer],bounds:mJ({minX:Math.min(t.x,c.x),minY:Math.min(t.y,c.y),maxX:Math.max(t.x,c.x),maxY:Math.max(t.y,c.y)},e)})}}a=c;continue}if(a=void 0,\"via\"===c.route_type){const o=t.route[r-1],s=t.route[r+1];for(const e of[o,s])if(\"wire\"===e?.route_type\u0026\u0026rJ(e,c)\u003eiJ)throw new Error(`Via ${t.pcb_trace_id}:${r} is adjacent to a non-colocated wire endpoint`);const a=c.via_diameter??n;i.push({kind:\"via\",center:{x:c.x,y:c.y},diameter:a,layers:bJ(c,e),bounds:mJ(gJ(c),a/2)});continue}const l=`${t.pcb_trace_id}:${r}:${c.route_type}`;if(\"jumper\"===c.route_type){i.push(MJ(c,c.start,l),MJ(c,c.end,l));continue}if(\"through_obstacle\"===c.route_type){if(!o.find(t=\u003et.layers.includes(c.from_layer)\u0026\u0026t.layers.includes(c.to_layer)\u0026\u0026uJ(c.start,t)\u003c=iJ\u0026\u0026uJ(c.end,t)\u003c=iJ))throw new Error(`Through-obstacle marker ${l} has no same-net multilayer obstacle witness`);i.push(IJ(c.start,0,[c.from_layer],l),IJ(c.end,0,[c.to_layer],l));continue}throw new Error(`Unsupported route primitive: ${String(c.route_type)}`)}return i},TJ=(t,e,n)=\u003e{const o=t.pointsToConnect[n];return o.pointId??o.pcb_port_id??`${t.name}[${e}:${n}]`},RJ=t=\u003e{const e={},n={},o=[];for(let i=0;i\u003ct.connections.length;i++){const r=t.connections[i];for(let t=0;t\u003cr.pointsToConnect.length;t++){const s=`${i}:${t}`;e[s]=TJ(r,i,t),n[s]=s,o.push([s])}}return{endpointCount:Object.keys(e).length,endpointLabels:e,componentByEndpointKey:n,endpointComponents:o}},EJ=t=\u003e{if(null===t||\"object\"!=typeof t)return JSON.stringify(t)??String(t);if(Array.isArray(t))return`[${t.map(t=\u003eEJ(t)).join(\",\")}]`;const e=t;return`{${Object.keys(e).sort().map(t=\u003e`${JSON.stringify(t)}:${EJ(e[t])}`).join(\",\")}}`},AJ=(t,e)=\u003e{const n=new Pq(t,e,{includePhysicalPositionAliases:!0}),o=(i=t.layerCount)\u003c=1?[\"top\"]:2===i?[\"top\",\"bottom\"]:[\"top\",...Array.from({length:i-2},(t,e)=\u003e`inner${e+1}`),\"bottom\"];var i;const r=(t=\u003e{const e=t.min_via_hole_diameter??t.minViaHoleDiameter??0;return Math.max(e,t.min_via_pad_diameter??t.minViaPadDiameter??t.minViaDiameter??.6)})(t),s=new Map,a=new Map,c={},l=(t,e)=\u003e{const n=s.get(t)??[];n.push(e),s.set(t,n)};for(let e=0;e\u003ct.connections.length;e++){const o=t.connections[e],i=n.canonicalize(vJ(o));if(1!==i.length)throw new Error(`Connection ${o.name} resolved to ${i.length} canonical nets`);for(let t=0;t\u003co.pointsToConnect.length;t++){const n=o.pointsToConnect[t],r=`${e}:${t}`,s=TJ(o,e,t);c[r]=s;const a={kind:\"endpoint\",endpointKey:r,endpointLabel:s,point:{x:n.x,y:n.y},layers:n.layers??[n.layer],bounds:gJ(n)};for(const t of i)l(t,a)}}for(const e of t.obstacles){const t={kind:\"obstacle\",obstacle:e,layers:e.layers,bounds:fJ(e)};for(const o of n.canonicalize(SJ(e))){const n=a.get(o)??[];n.push(e),a.set(o,n),s.has(o)\u0026\u0026l(o,t)}}for(const i of[...e,...t.fixedTraces??[]]){const t=n.canonicalize(xJ(i));if(1!==t.length)throw new Error(`Trace ${i.pcb_trace_id} resolved to ${t.length} canonical nets`);const e=a.get(t[0])??[],c=wJ(i,o,r,e);for(const e of t)if(s.has(e))for(const t of c)l(e,t)}const d={},h=[];for(const t of s.values()){const e=new _J(t.length),n=new Map;for(let o=0;o\u003ct.length;o++){const i=t[o];if(\"bridge-contact\"!==i.kind\u0026\u0026\"bridge-pad\"!==i.kind)continue;const r=n.get(i.bridgeId);void 0===r?n.set(i.bridgeId,o):e.union(r,o)}const o=t.length\u003e0?new Bt(t.length):null;if(o){for(const e of t)o.add(e.bounds.minX,e.bounds.minY,e.bounds.maxX,e.bounds.maxY);o.finish()}for(let n=0;n\u003ct.length;n++){const i=t[n],r=o?.search(i.bounds.minX-iJ,i.bounds.minY-iJ,i.bounds.maxX+iJ,i.bounds.maxY+iJ)??[];for(const o of r)o\u003c=n||yJ(i,t[o])\u0026\u0026e.union(n,o)}const i=new Map;for(let n=0;n\u003ct.length;n++){const o=t[n];if(\"endpoint\"!==o.kind)continue;const r=e.find(n),s=i.get(r)??[];s.push(o.endpointKey),i.set(r,s)}for(const t of i.values()){t.sort();const e=t[0];h.push(t);for(const n of t){if(void 0!==d[n])throw new Error(`Endpoint ${n} was assigned to multiple canonical nets`);d[n]=e}}}return h.sort(([t=\"\"],[e=\"\"])=\u003et.localeCompare(e)),{endpointCount:Object.keys(c).length,endpointLabels:c,componentByEndpointKey:d,endpointComponents:h}},OJ=class{baseline;inputProblem;baselineCaptureError;baselineTraceSignature;constructor(t,e){this.inputProblem=t,this.baselineTraceSignature=EJ(e);try{this.baseline=AJ(t,e),this.baselineCaptureError=null}catch(e){this.baseline=RJ(t),this.baselineCaptureError=e instanceof Error?e.message:String(e)}}validate(t){if(this.baselineCaptureError){const e=EJ(t)===this.baselineTraceSignature;return{safe:e,candidate:this.baseline,regressions:[],validationError:e?`Connectivity validation is limited to exact trace preservation: ${this.baselineCaptureError}`:`Connectivity validation failed closed: ${this.baselineCaptureError}`}}let e;try{e=AJ(this.inputProblem,t)}catch(t){return{safe:!1,candidate:RJ(this.inputProblem),regressions:[],validationError:`Connectivity validation failed closed: ${t instanceof Error?t.message:String(t)}`}}const n=[];for(const t of this.baseline.endpointComponents){if(t.length\u003c2)continue;const o=new Map;for(const n of t){const t=e.componentByEndpointKey[n]??`missing:${n}`,i=o.get(t)??[];i.push(n),o.set(t,i)}o.size\u003c=1||n.push({baselineEndpointKeys:[...t],baselineEndpointLabels:t.map(t=\u003ethis.baseline.endpointLabels[t]),candidateComponents:[...o.values()]})}return{safe:0===n.length,candidate:e,regressions:n}}},kJ=[{x:0,y:0},{x:.5,y:.5}],LJ=[.15,.2,.25,.3,.4,.5],DJ=t=\u003e\"wire\"===t?.route_type,zJ=t=\u003e\"via\"===t?.route_type,FJ=Array.from({length:24},(t,e)=\u003e{const n=e*Math.PI/12;return{x:Math.cos(n),y:Math.sin(n)}}),BJ=t=\u003e[...new Set(t.map(t=\u003eNumber(t.toFixed(6))))].sort((t,e)=\u003ee-t),jJ=class extends Sq{inputProblem;traces;obstacleIndex;phase=\"repair-vias\";traceCursor=0;routeCursor=0;candidateCursor=0;clearanceTierCursor=0;attemptedCandidateCount=0;attemptedClearanceShoveCount=0;attemptedViaGridCount=0;committedClearanceShoveCount=0;viaPairCountRemoved=0;viaCountRemoved=0;simplifiedPathCount=0;normalizedSegmentCount=0;achievedExtraClearanceCount=0;relocatedViaCount=0;unresolvedViaCount=0;attemptedPushedViaRepairCount=0;committedPushedViaRepairCount=0;padClearanceRerouteCount=0;unresolvedPadClearanceCount=0;initialPadClearanceViolationCount=0;remainingPadClearanceViolationCount=0;initialPadClearanceViolationCountByClearance={};remainingPadClearanceViolationCountByClearance={};budgetLimited=!1;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;connectionNameResolver;connectionByTraceId=new Map;connectivityInvariant;initialConnectivitySafeTraces;mutableTraceIndices;mutableTraceIndexSet;viaRepairTraceIndices;traceIndices;maxRerouteLength;clearancePaddingTiers;desiredPadClearance;initialTraceLengths=new Map;candidates=[];candidateShoveCount=0;rollbackTraces=null;baseCandidateValidated=!1;activeShovePadding=0;viaGridAttempt=null;candidateSetMayUseGridFallback=!1;pendingPushedViaRepair=null;alternatePushedViaRepairs=[];pushedViaRepairRollbackTraces=null;connectivityFinalized=!1;finalizedMutatedTraceIndices=[];resumePhase=\"scan-via-pairs\";constructor(t){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.initialConnectivitySafeTraces=structuredClone(t.traces),this.connectivityInvariant=new OJ(this.inputProblem.simpleRouteJson,this.initialConnectivitySafeTraces),this.connectionNameResolver=new Pq(t.simpleRouteJson,this.traces),this.maxRerouteLength=t.maxRerouteLength??10,this.desiredPadClearance=t.desiredPadClearance,this.clearancePaddingTiers=BJ([...t.clearancePaddingTiers??[.1,.05,0],0]).filter(t=\u003et\u003e=0);const e=this.traces.map((t,e)=\u003ee),n=(t,e,n)=\u003e{const o=[...new Set(t??n)];for(const t of o)if(!Number.isInteger(t)||t\u003c0||t\u003e=this.traces.length)throw new RangeError(`Invalid cleanup ${e} index: ${t}`);return o},o=n(t.traceIndices,\"trace\",e);this.viaRepairTraceIndices=n(t.viaRepairTraceIndices,\"via repair trace\",o),this.mutableTraceIndices=n(t.mutableTraceIndices,\"mutable trace\",o),this.mutableTraceIndexSet=new Set(this.mutableTraceIndices),this.traceIndices=o.filter(t=\u003ethis.resolveNominalTraceWidth(this.traces[t])\u003e=.499999);for(const t of this.traceIndices)this.initialTraceLengths.set(t,this.measureTraceLength(this.traces[t]));this.obstacleIndex=this.createObstacleIndex(),this.initialPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCount=this.initialPadClearanceViolationCount,this.initialPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.remainingPadClearanceViolationCountByClearance={...this.initialPadClearanceViolationCountByClearance},this.activeSubSolver=null,this.MAX_ITERATIONS=1e6,this.stats=this.createStats()}getSolverName(){return\"PowerTraceCleanupSolver\"}_step(){if(this.activeSubSolver)return this.stepActiveShoveSolver(),void(this.stats=this.createStats());switch(this.phase){case\"repair-vias\":this.repairNextVia();break;case\"scan-via-pairs\":this.scanNextViaPair();break;case\"scan-pad-clearance\":this.scanNextPadClearance();break;case\"scan-simplification\":this.scanNextSimplification();break;case\"evaluate-candidate\":this.evaluateCurrentCandidate();break;case\"shove-clearance\":break;case\"route-via-pair\":this.startNextViaGridCandidate();break;case\"complete\":this.ensureConnectivitySafeOutput(),this.solved=!0}this.stats=this.createStats()}repairNextVia(){const t=this.viaRepairTraceIndices[this.traceCursor],e=void 0===t?void 0:this.traces[t];if(!e)return this.traceCursor=0,this.routeCursor=0,this.phase=\"scan-via-pairs\",void this.rebuildObstacleIndex();const n=e.route.findIndex((t,e)=\u003ee\u003e=this.routeCursor\u0026\u0026zJ(t));if(-1===n)return this.traceCursor++,void(this.routeCursor=0);this.routeCursor=n+1;const o=e.route[n],i=e.route[n-1],r=e.route[n+1];if(!zJ(o)||!DJ(i)||!DJ(r))return;const s=this.getTraceConnectionNames(e),a=this.getBaseObstacleClearance();if(!this.obstacleIndex.collidesVia({point:o,layers:this.obstacleIndex.boardLayers,padDiameter:o.via_diameter??.6,holeDiameter:o.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,connectionNames:s,ignoreTraceIndex:t,ignoreRouteRange:{start:n,end:n},obstacleClearance:a,blockSameNetObstacles:!0,sameNetObstacleClearance:0}))return;const c=this.findViaRepair(e,n,a);if(!c){const t=this.findPushableViaRepairs(e,n,a),o=t.shift();return o?(this.alternatePushedViaRepairs=t,void this.startPushedViaRepair(o)):void this.unresolvedViaCount++}e.route.splice(c.startIndex,c.endIndex-c.startIndex+1,...c.route),this.relocatedViaCount++,this.routeCursor=c.startIndex+c.route.length,this.rebuildObstacleIndex()}findViaRepair(t,e,n){const o=this.createViaRepairContext(t,e);if(!o)return null;const i=o.candidates.map(t=\u003e({point:t,movedLength:Nq(o.leftAnchor,t)+Nq(t,o.rightAnchor)})).filter(({movedLength:t})=\u003et\u003c=o.originalLength+Math.min(6,this.maxRerouteLength)+Mq);i.sort((t,e)=\u003et.movedLength-e.movedLength||Nq(t.point,o.via)-Nq(e.point,o.via));for(const t of i)if(this.isViaRepairPointSafe(o,t.point,n))return this.createViaRepairReplacement(o,t.point);return null}findPushableViaRepairs(t,e,n){const o=this.viaRepairTraceIndices[this.traceCursor];if(void 0===o)return[];const i=this.createViaRepairContext(t,e);if(!i)return[];const r=i.candidates.flatMap(t=\u003e{const e=Nq(i.leftAnchor,t)+Nq(t,i.rightAnchor);if(e\u003ei.originalLength+Math.min(6,this.maxRerouteLength)+Mq)return[];const r=new Set,s=this.getViaRepairCollisionQueries(i,t,n);for(const t of s)for(const e of this.obstacleIndex.findCollisions(t)){if(\"trace\"!==e.kind||void 0===e.traceIndex||e.traceIndex===o||!this.mutableTraceIndexSet.has(e.traceIndex))return[];r.add(e.traceIndex)}if(0===r.size||r.size\u003e2)return[];const a=[...r];return this.isViaRepairPointSafe(i,t,n,a)?[{point:t,movedLength:e,blockerCount:r.size,blockerKey:[...r].sort((t,e)=\u003et-e).join(\",\")}]:[]});r.sort((t,e)=\u003et.blockerCount-e.blockerCount||t.movedLength-e.movedLength||Nq(t.point,i.via)-Nq(e.point,i.via));return[...new Map([...r].reverse().map(t=\u003e[t.blockerKey,t])).values(),...r].filter((t,e,n)=\u003en.findIndex(e=\u003ee.point.x===t.point.x\u0026\u0026e.point.y===t.point.y)===e).slice(0,12).map(t=\u003e({traceIndex:o,viaIndex:e,point:t.point,padClearance:n,corridor:[{start:i.leftAnchor,end:t.point,layer:i.leftWire.layer,width:i.leftWire.width},{start:t.point,end:i.rightAnchor,layer:i.rightWire.layer,width:i.rightWire.width},...this.obstacleIndex.boardLayers.map(e=\u003e({start:t.point,end:t.point,layer:e,width:i.viaDiameter}))]}))}createViaRepairContext(t,e){const n=t.route[e],o=t.route[e-1],i=t.route[e+1];if(!zJ(n)||!DJ(o)||!DJ(i))return null;const r=e-1==0||!DJ(t.route[e-2]),s=e+1===t.route.length-1||!DJ(t.route[e+2]),a=r?o:t.route[e-2],c=s?i:t.route[e+2],l=Nq(a,n)+Nq(n,c),d=this.getTraceConnectionNames(t),h=n.via_diameter??.6,u=n.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,p=Math.max(.3,u+this.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance+.05),m=[p,p+.15,p+.3,p+.5,p+.75,p+1,p+1.5,p+2].flatMap(t=\u003eFJ.map(e=\u003e({x:.025*Math.round((n.x+e.x*t)/.025),y:.025*Math.round((n.y+e.y*t)/.025)}))),g=[...m,...m.flatMap(t=\u003e[{x:t.x,y:Math.floor(10*n.y)/10},{x:t.x,y:Math.ceil(10*n.y)/10},{x:Math.floor(10*n.x)/10,y:t.y},{x:Math.ceil(10*n.x)/10,y:t.y}])].filter((t,e,n)=\u003en.findIndex(e=\u003ee.x===t.x\u0026\u0026e.y===t.y)===e);return{trace:t,viaIndex:e,via:n,leftWire:o,rightWire:i,leftIsEndpoint:r,rightIsEndpoint:s,leftAnchor:a,rightAnchor:c,originalLength:l,connectionNames:d,viaDiameter:h,holeDiameter:u,ignoreRouteRange:{start:Math.max(0,e-2),end:Math.min(t.route.length-1,e+2)},candidates:g}}getViaRepairCollisionQueries(t,e,n,o){const i=this.viaRepairTraceIndices[this.traceCursor],r={connectionNames:t.connectionNames,ignoreTraceIndex:i,ignoreTraceIndices:o,ignoreRouteRange:t.ignoreRouteRange,obstacleClearance:n};return[...this.obstacleIndex.boardLayers.map(n=\u003e({...r,start:e,end:e,layer:n,width:t.viaDiameter,blockSameNetObstacles:!0,sameNetObstacleClearance:0})),{...r,start:t.leftAnchor,end:e,layer:t.leftWire.layer,width:t.leftWire.width},{...r,start:e,end:t.rightAnchor,layer:t.rightWire.layer,width:t.rightWire.width}]}isViaRepairPointSafe(t,e,n,o){const i=this.viaRepairTraceIndices[this.traceCursor];return!this.obstacleIndex.collidesVia({point:e,layers:this.obstacleIndex.boardLayers,padDiameter:t.viaDiameter,holeDiameter:t.holeDiameter,connectionNames:t.connectionNames,ignoreTraceIndex:i,ignoreTraceIndices:o,ignoreRouteRange:{start:t.viaIndex,end:t.viaIndex},obstacleClearance:n,blockSameNetObstacles:!0,sameNetObstacleClearance:0})\u0026\u0026!this.getViaRepairCollisionQueries(t,e,n,o).slice(this.obstacleIndex.boardLayers.length).some(t=\u003ethis.obstacleIndex.collides(t))}createViaRepairReplacement(t,e){const n={...t.leftWire,...e},o={...t.via,...e},i={...t.rightWire,...e};return{startIndex:t.viaIndex-1,endIndex:t.viaIndex+1,route:[...t.leftIsEndpoint?[t.leftWire]:[],n,o,i,...t.rightIsEndpoint?[t.rightWire]:[]]}}startPushedViaRepair(t){this.pendingPushedViaRepair=t,this.pushedViaRepairRollbackTraces=structuredClone(this.traces),this.attemptedPushedViaRepairCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem.simpleRouteJson,traces:this.traces,powerTraceIndex:t.traceIndex,nominalPowerWidth:Math.max(...t.corridor.map(t=\u003et.width)),pushOnlyNominalWidthsBelow:Number.POSITIVE_INFINITY,mutableTraceIndices:this.mutableTraceIndices,corridor:t.corridor,maxRerouteLength:this.maxRerouteLength},this.connectionNameResolver)}finishPushedViaRepairSolver(t){const e=this.pendingPushedViaRepair;if(this.activeSubSolver=null,!e)return;if(t.solved){const n=t.getOutput();if(n){this.traces=n.traces,this.rebuildObstacleIndex();const t=this.traces[e.traceIndex],o=t?this.createViaRepairContext(t,e.viaIndex):null;if(o\u0026\u0026this.isViaRepairPointSafe(o,e.point,e.padClearance)){const n=this.createViaRepairReplacement(o,e.point);return t.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...n.route),this.relocatedViaCount++,this.committedPushedViaRepairCount++,this.routeCursor=n.startIndex+n.route.length,this.pendingPushedViaRepair=null,this.alternatePushedViaRepairs=[],this.pushedViaRepairRollbackTraces=null,void this.rebuildObstacleIndex()}}}this.pushedViaRepairRollbackTraces\u0026\u0026(this.traces=this.pushedViaRepairRollbackTraces),this.pendingPushedViaRepair=null,this.pushedViaRepairRollbackTraces=null;const n=this.alternatePushedViaRepairs.shift();if(n)return this.rebuildObstacleIndex(),void this.startPushedViaRepair(n);this.alternatePushedViaRepairs=[],this.unresolvedViaCount++,this.rebuildObstacleIndex()}scanNextViaPair(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.traceCursor=0,this.routeCursor=0,void(this.phase=\"scan-pad-clearance\");const e=this.traces[t],n=e.route.findIndex((t,e)=\u003ee\u003e=this.routeCursor\u0026\u0026\"via\"===t.route_type);if(-1===n)return void this.advanceTrace();const o=e.route.slice(n+1).findIndex(t=\u003e\"via\"===t.route_type);if(-1===o)return void this.advanceTrace();const i=n-1,r=n+1+o+1,s=e.route[i],a=e.route[r];if(this.routeCursor=n+1,!DJ(s)||!DJ(a)||s.layer!==a.layer||Nq(s,a)\u003ethis.maxRerouteLength+Mq)return;const c=this.createCandidates({kind:\"via-pair\",traceIndex:t,startIndex:i,endIndex:r}),l=c[0]?.width??Math.max(s.width,a.width),d=c[0]?.padClearance??this.getCandidatePadClearance(\"via-pair\",t,i,r),h=n=\u003e{const o=e.route[n];return!!DJ(o)\u0026\u0026this.obstacleIndex.findCollisions({start:o,end:o,layer:o.layer,width:l,connectionNames:this.getTraceConnectionNames(e),ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,i-1),end:Math.min(e.route.length-1,r+1)},obstacleClearance:d}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind)},u=e.route[i-1],p=e.route[r+1],m=c.length\u003e0\u0026\u0026h(i)\u0026\u0026DJ(u)\u0026\u0026u.layer===s.layer?i-1:i,g=c.length\u003e0\u0026\u0026h(r)\u0026\u0026DJ(p)\u0026\u0026p.layer===a.layer?r+1:r,f=[{startIndex:i,endIndex:r},{startIndex:m,endIndex:r},{startIndex:i,endIndex:g},{startIndex:m,endIndex:g}].filter((t,e,n)=\u003en.findIndex(e=\u003ee.startIndex===t.startIndex\u0026\u0026e.endIndex===t.endIndex)===e).flatMap(e=\u003ee.startIndex===i\u0026\u0026e.endIndex===r?c:this.createCandidates({kind:\"via-pair\",traceIndex:t,startIndex:e.startIndex,endIndex:e.endIndex}));0!==f.length\u0026\u0026this.beginCandidates(f,\"scan-via-pairs\",!0)}scanNextPadClearance(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.traceCursor=0,this.routeCursor=0,void(this.phase=\"scan-simplification\");const e=this.traces[t];if(this.resolveNominalTraceWidth(e)\u003c.499999)return void this.advanceTrace();const n=this.routeCursor,o=e.route[n],i=e.route[n+1];if(!DJ(o)||!DJ(i)||o.layer!==i.layer)return void(n\u003e=e.route.length-1?this.advanceTrace():this.routeCursor++);if(this.routeCursor++,!this.segmentHasPadClearanceViolation(t,n))return;const r=this.getPadClearanceIntervals(e,n).flatMap(e=\u003ethis.getImprovedPadClearanceTiers(t,e.startIndex,e.endIndex).flatMap(n=\u003ethis.createCandidates({kind:\"pad-clearance\",traceIndex:t,startIndex:e.startIndex,endIndex:e.endIndex,padClearance:n}).slice(0,8)));0!==r.length?this.beginCandidates(r.slice(0,72),\"scan-pad-clearance\",!0):this.unresolvedPadClearanceCount++}segmentHasPadClearanceViolation(t,e){const n=this.traces[t],o=n.route[e],i=n.route[e+1];return!(!DJ(o)||!DJ(i)||o.layer!==i.layer)\u0026\u0026this.obstacleIndex.findCollisions({start:o,end:i,layer:o.layer,width:Math.max(o.width,i.width),connectionNames:this.getTraceConnectionNames(n),ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,e-1),end:Math.min(n.route.length-1,e+2)},obstacleClearance:this.getPadClearanceForTrace(n)}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind)}getPadClearanceIntervals(t,e){const n=t.route[e];if(!DJ(n))return[];const o=[e];let i=0;for(let r=e-1;r\u003e=0;r--){const e=t.route[r],s=t.route[r+1];if(!DJ(e)||!DJ(s)||e.layer!==n.layer||s.layer!==n.layer)break;if(i+=Nq(e,s),i\u003ethis.maxRerouteLength/2+Mq)break;o.push(r)}const r=[e+1];i=0;for(let o=e+1;o\u003ct.route.length-1;o++){const e=t.route[o],s=t.route[o+1];if(!DJ(e)||!DJ(s)||e.layer!==n.layer||s.layer!==n.layer)break;if(i+=Nq(e,s),i\u003ethis.maxRerouteLength/2+Mq)break;r.push(o+1)}return o.flatMap(e=\u003er.map(n=\u003e({startIndex:e,endIndex:n,length:this.measureRouteRange(t,e,n).length}))).filter(t=\u003et.length\u003c=this.maxRerouteLength+Mq\u0026\u0026t.startIndex\u003ct.endIndex).sort((t,e)=\u003ee.length-t.length).slice(0,8)}scanNextSimplification(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),void(this.phase=\"complete\");const e=this.traces[t],n=this.routeCursor,o=e.route[n];if(!DJ(o)||n\u003e=e.route.length-1)return void(n\u003e=e.route.length-1?this.advanceTrace():this.routeCursor++);let i=0;const r=[];for(let t=n+1;t\u003ce.route.length;t++){const s=e.route[t-1],a=e.route[t];if(!DJ(s)||!DJ(a)||s.layer!==o.layer||a.layer!==o.layer)break;if(i+=Nq(s,a),i\u003ethis.maxRerouteLength+Mq)break;const c=this.measureRouteRange(e,n,t);(c.nonOctilinearSegmentCount\u003e0||c.pointCount\u003e3)\u0026\u0026r.push(t)}const s=r.slice(-6).reverse().flatMap(e=\u003ethis.createCandidates({kind:\"simplification\",traceIndex:t,startIndex:n,endIndex:e}));0!==s.length?this.beginCandidates(s,\"scan-simplification\"):this.routeCursor++}createCandidates({kind:t,traceIndex:e,startIndex:n,endIndex:o,padClearance:i}){const r=this.traces[e],s=r.route[n],a=r.route[o];if(!DJ(s)||!DJ(a)||s.layer!==a.layer)return[];const c=this.resolveNominalTraceWidth(r),l=this.measureRouteRange(r,n,o),d=i??this.getCandidatePadClearance(t,e,n,o),h=[],u=qq(s,a);if(\"pad-clearance\"===t\u0026\u00260===Gq([s,a])){const t=Nq(s,a);if(t\u003eMq){const e={x:-(a.y-s.y)/t,y:(a.x-s.x)/t};for(const t of[.25,.5,.75,1,1.5,2])for(const n of[-1,1])u.push([s,{x:s.x+e.x*t*n,y:s.y+e.y*t*n},{x:a.x+e.x*t*n,y:a.y+e.y*t*n},a])}}const p=new Map(u.map(t=\u003e[t.map(t=\u003e`${t.x.toFixed(6)},${t.y.toFixed(6)}`).join(\";\"),t]));for(const i of p.values()){const u=Uq(i);if(u\u003ethis.maxRerouteLength+Mq||\"pad-clearance\"===t\u0026\u0026u\u003e1.35*l.length+.5||\"simplification\"===t\u0026\u0026(u\u003e1.1*l.length+Mq||this.measureTraceLength(r)-l.length+u\u003e1.01*(this.initialTraceLengths.get(e)??this.measureTraceLength(r))+Mq))continue;const p=u\u003c=Mq?c:c-l.deficitArea/u;if(p\u003ec+Mq)continue;const m=.05*Math.ceil(Math.max(this.inputProblem.simpleRouteJson.minTraceWidth,p)/.05-Mq),g=BJ([c,Math.min(c,m),Math.min(c,Math.max(this.inputProblem.simpleRouteJson.minTraceWidth,p))].map(t=\u003eMath.max(t,s.width)));for(const r of g){const u=this.measureCandidate(i,r,c,a.width,s.width);u.deficitArea\u003el.deficitArea+Mq||u.conservativeDeficitArea\u003el.conservativeDeficitArea+Mq||!this.preservesCoverage(u,l)||(\"simplification\"!==t||0!==l.nonOctilinearSegmentCount||u.pointCount\u003cl.pointCount\u0026\u0026u.length\u003cl.length-Mq)\u0026\u0026h.push({kind:t,traceIndex:e,startIndex:n,endIndex:o,layer:s.layer,points:i,width:r,padClearance:d,originalQuality:l})}}return h.slice(0,18)}beginCandidates(t,e,n=!1){this.candidates=t,this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.rollbackTraces=null,this.baseCandidateValidated=!1,this.resumePhase=e,this.candidateSetMayUseGridFallback=n,this.phase=\"evaluate-candidate\"}evaluateCurrentCandidate(){const t=this.candidates[this.candidateCursor];if(!t)return void this.finishCandidateSet(!1);if(!this.baseCandidateValidated){if(!this.candidateCollides(t,0))return this.candidateShoveCount\u003e0?void this.applyCandidate(t,0):(this.baseCandidateValidated=!0,void(this.clearanceTierCursor=0));return this.getPushableTraceIndices(t,0)\u0026\u0026this.candidateShoveCount\u003c2\u0026\u0026this.attemptedClearanceShoveCount\u003c48?void this.startClearanceShove(t,0):void this.advanceCandidate()}const e=this.clearancePaddingTiers[this.clearanceTierCursor];if(void 0===e||e\u003c=Mq)return void this.applyCandidate(t,0);if(this.attemptedCandidateCount++,!this.candidateCollides(t,e))return void this.applyCandidate(t,e);this.getPushableTraceIndices(t,e)\u0026\u0026this.candidateShoveCount\u003c2\u0026\u0026this.attemptedClearanceShoveCount\u003c48?this.startClearanceShove(t,e):(this.rollbackCandidateShoves(),this.clearanceTierCursor++,this.candidateShoveCount=0)}advanceCandidate(){this.rollbackCandidateShoves(),this.candidateCursor++,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1}candidateCollides(t,e){const n=this.traces[t.traceIndex],o=this.getTraceConnectionNames(n);for(let i=0;i\u003ct.points.length-1;i++){const r=this.getCandidateSegmentWidth(t,i);if(this.obstacleIndex.collides({start:t.points[i],end:t.points[i+1],layer:t.layer,width:r+2*e,connectionNames:o,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(n.route.length-1,t.endIndex+1)},obstacleClearance:t.padClearance}))return!0}return!1}getPushableTraceIndices(t,e){const n=this.traces[t.traceIndex],o=this.getTraceConnectionNames(n),i=new Set;for(let r=0;r\u003ct.points.length-1;r++){const s=this.getCandidateSegmentWidth(t,r),a={start:t.points[r],end:t.points[r+1],layer:t.layer,width:s+2*e,connectionNames:o,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(n.route.length-1,t.endIndex+1)},obstacleClearance:t.padClearance};if(!this.obstacleIndex.collides(a))continue;const c=this.obstacleIndex.findCollisions(a);if(0===c.length)return null;for(const e of c){if(\"trace\"!==e.kind||void 0===e.traceIndex||e.traceIndex===t.traceIndex||!this.mutableTraceIndexSet.has(e.traceIndex))return null;const n=this.traces[e.traceIndex];if(!n||this.resolveNominalTraceWidth(n)\u003e=t.width-Mq)return null;i.add(e.traceIndex)}}return i.size\u003e0\u0026\u0026i.size\u003c=2?[...i]:null}startClearanceShove(t,e){this.rollbackTraces??=structuredClone(this.traces),this.activeShovePadding=e;const n=t.width+2*e,o=t.points.slice(0,-1).map((n,o)=\u003e({start:n,end:t.points[o+1],layer:t.layer,width:this.getCandidateSegmentWidth(t,o)+2*e}));this.attemptedClearanceShoveCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem.simpleRouteJson,traces:this.traces,powerTraceIndex:t.traceIndex,nominalPowerWidth:n,pushOnlyNominalWidthsBelow:t.width,mutableTraceIndices:this.mutableTraceIndices,corridor:o,maxRerouteLength:this.maxRerouteLength},this.connectionNameResolver),this.phase=\"shove-clearance\"}getCandidateSegmentWidth(t,e){const n=this.traces[t.traceIndex],o=n.route[t.startIndex],i=n.route[t.endIndex],r=0===e\u0026\u0026DJ(o)?o.width:t.width,s=e===t.points.length-2\u0026\u0026DJ(i)?i.width:t.width;return Math.max(r,s)}stepActiveShoveSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed)if(this.pendingPushedViaRepair\u0026\u0026t instanceof oJ)this.finishPushedViaRepairSolver(t);else if(t instanceof Qq)this.finishViaGridSolver(t);else{if(this.activeSubSolver=null,this.phase=\"evaluate-candidate\",t.solved){const e=t.getOutput();if(e)return this.traces=e.traces,this.candidateShoveCount++,void this.rebuildObstacleIndex()}this.failedSubSolvers??=[],this.failedSubSolvers.push(t),this.rollbackCandidateShoves(),this.activeShovePadding\u003c=Mq?this.advanceCandidate():this.clearanceTierCursor++,this.candidateShoveCount=0}}rollbackCandidateShoves(){this.rollbackTraces\u0026\u0026(this.traces=this.rollbackTraces,this.rollbackTraces=null,this.rebuildObstacleIndex())}applyCandidate(t,e){const n=this.traces[t.traceIndex],o=n.route[t.startIndex],i=n.route[t.endIndex],r=t.points.map((e,n)=\u003e({...0===n?o:n===t.points.length-1?i:{route_type:\"wire\",layer:t.layer,width:t.width},x:e.x,y:e.y,layer:t.layer,width:0===n?o.width:n===t.points.length-1?i.width:t.width})),s=n.route.slice(t.startIndex,t.endIndex+1),a=t.originalQuality.nonOctilinearSegmentCount;if(n.route.splice(t.startIndex,t.endIndex-t.startIndex+1,...r),\"via-pair\"===t.kind){const e=s.filter(t=\u003e\"via\"===t.route_type).length;this.viaPairCountRemoved++,this.viaCountRemoved+=e,this.routeCursor=Math.max(0,t.startIndex-1)}else\"pad-clearance\"===t.kind?(this.padClearanceRerouteCount++,this.routeCursor=t.startIndex+Math.max(1,r.length-1)):(this.simplifiedPathCount++,this.normalizedSegmentCount+=a,this.routeCursor=t.startIndex+Math.max(1,r.length-1));this.committedClearanceShoveCount+=this.candidateShoveCount,e\u003eMq\u0026\u0026this.achievedExtraClearanceCount++,this.rollbackTraces=null,this.candidateShoveCount=0,this.rebuildObstacleIndex(),this.finishCandidateSet(!0)}finishCandidateSet(t){const e=this.candidates[0],n=BJ(this.candidates.filter(t=\u003et.kind===e?.kind).map(t=\u003et.width)),o=BJ(this.candidates.filter(t=\u003et.kind===e?.kind\u0026\u0026t.traceIndex===e.traceIndex\u0026\u0026t.startIndex===e.startIndex\u0026\u0026t.endIndex===e.endIndex).map(t=\u003et.padClearance));if(this.rollbackCandidateShoves(),this.candidates=[],this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1,!t\u0026\u0026this.candidateSetMayUseGridFallback\u0026\u0026e)return this.candidateSetMayUseGridFallback=!1,void this.beginViaGridAttempt(e,n,o);this.candidateSetMayUseGridFallback=!1,t||this.routeCursor++,this.phase=this.resumePhase}beginViaGridAttempt(t,e,n=[t.padClearance]){this.viaGridAttempt={kind:t.kind,traceIndex:t.traceIndex,startIndex:t.startIndex,endIndex:t.endIndex,layer:t.layer,padClearances:n,padClearanceCursor:0,originalQuality:t.originalQuality,widths:e,widthCursor:0,gridSizes:[],gridSizeCursor:0,offsetCursor:0},this.phase=\"route-via-pair\"}startNextViaGridCandidate(){const t=this.viaGridAttempt;if(!t)return void(this.phase=this.resumePhase);if(t.padClearanceCursor\u003e=t.padClearances.length)return\"pad-clearance\"===t.kind\u0026\u0026this.unresolvedPadClearanceCount++,this.viaGridAttempt=null,this.routeCursor++,void(this.phase=this.resumePhase);if(t.widthCursor\u003e=t.widths.length)return t.padClearanceCursor++,t.widthCursor=0,t.gridSizes=[],t.gridSizeCursor=0,void(t.offsetCursor=0);const e=t.widths[t.widthCursor],n=t.padClearances[t.padClearanceCursor];if(0===t.gridSizes.length\u0026\u0026(t.gridSizes=BJ([Rq(e/2,.2,.4),Rq(e/3,.15,.25)])),t.gridSizeCursor\u003e=t.gridSizes.length)return t.widthCursor++,t.gridSizes=[],t.gridSizeCursor=0,void(t.offsetCursor=0);if(t.offsetCursor\u003e=kJ.length)return t.gridSizeCursor++,void(t.offsetCursor=0);const o=this.traces[t.traceIndex],i=o.route[t.startIndex],r=o.route[t.endIndex];if(!DJ(i)||!DJ(r))return this.viaGridAttempt=null,this.routeCursor++,void(this.phase=this.resumePhase);const s=t.gridSizes[t.gridSizeCursor],a=kJ[t.offsetCursor];this.attemptedViaGridCount++,this.activeSubSolver=new Qq({start:i,end:r,layer:t.layer,traceWidth:e,gridSize:s,gridOffset:{x:a.x*s,y:a.y*s},connectionNames:this.getTraceConnectionNames(o),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(o.route.length-1,t.endIndex+1)},bounds:this.inputProblem.simpleRouteJson.bounds,obstacleClearance:n,searchPadding:Math.min(4,Math.max(2,Nq(i,r)/2,3*e)),requireOctilinear:!0})}finishViaGridSolver(t){const e=this.viaGridAttempt;if(this.activeSubSolver=null,t.solved\u0026\u0026e){const n=t.getOutput(),o=this.traces[e.traceIndex];if(n\u0026\u0026o){const t=this.resolveNominalTraceWidth(o),i=this.measureCandidate(n.points,n.traceWidth,t,o.route[e.endIndex].width,o.route[e.startIndex].width);if(0===i.nonOctilinearSegmentCount\u0026\u0026i.length\u003c=this.maxRerouteLength+Mq\u0026\u0026i.deficitArea\u003c=e.originalQuality.deficitArea+Mq\u0026\u0026i.conservativeDeficitArea\u003c=e.originalQuality.conservativeDeficitArea+Mq\u0026\u0026this.preservesCoverage(i,e.originalQuality)){const t={kind:e.kind,traceIndex:e.traceIndex,startIndex:e.startIndex,endIndex:e.endIndex,layer:e.layer,points:n.points,width:n.traceWidth,padClearance:e.padClearances[e.padClearanceCursor],originalQuality:e.originalQuality};return this.viaGridAttempt=null,void this.beginCandidates([t],this.resumePhase,!1)}}}t.failed\u0026\u0026(this.failedSubSolvers??=[],this.failedSubSolvers.push(t)),e\u0026\u0026e.offsetCursor++,this.phase=\"route-via-pair\"}measureRouteRange(t,e,n){const o=this.resolveNominalTraceWidth(t);let i=0,r=0,s=0,a=0,c=0,l=0,d=0;for(let h=e;h\u003c=n;h++){if(DJ(t.route[h])\u0026\u0026d++,h\u003e=n)continue;const e=t.route[h],u=t.route[h+1];if(!DJ(e)||!DJ(u)||e.layer!==u.layer)continue;const p=Nq(e,u);i+=p,r+=p*Math.max(0,o-e.width),e.width\u003e=o-Mq\u0026\u0026(a+=p),s+=p*Math.max(0,o-Math.min(e.width,u.width)),Math.min(e.width,u.width)\u003e=o-Mq\u0026\u0026(c+=p),l+=Gq([e,u])}return{length:i,deficitArea:r,conservativeDeficitArea:s,nominalLength:a,conservativeNominalLength:c,nonOctilinearSegmentCount:l,pointCount:d}}measureTraceLength(t){let e=0;for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];DJ(o)\u0026\u0026DJ(i)\u0026\u0026o.layer===i.layer\u0026\u0026(e+=Nq(o,i))}return e}measureCandidate(t,e,n,o=e,i=e){const r=Uq(t);let s=0,a=0,c=0,l=0;for(let r=0;r\u003ct.length-1;r++){const d=Nq(t[r],t[r+1]),h=0===r?i:e,u=r===t.length-2?o:e,p=Math.min(h,u);s+=d*Math.max(0,n-h),a+=d*Math.max(0,n-p),h\u003e=n-Mq\u0026\u0026(c+=d),p\u003e=n-Mq\u0026\u0026(l+=d)}return{length:r,deficitArea:s,conservativeDeficitArea:a,nominalLength:c,conservativeNominalLength:l,nonOctilinearSegmentCount:Gq(t),pointCount:t.length}}preservesCoverage(t,e){const n=e.length\u003c=Mq?1:e.nominalLength/e.length,o=t.length\u003c=Mq?1:t.nominalLength/t.length,i=e.length\u003c=Mq?1:e.conservativeNominalLength/e.length,r=t.length\u003c=Mq?1:t.conservativeNominalLength/t.length;return!(o+Mq\u003cn||r+Mq\u003ci)\u0026\u0026!(t.length\u003ee.length+Mq\u0026\u0026o\u003c.999999)}advanceTrace(){this.traceCursor++,this.routeCursor=0,this.rebuildObstacleIndex()}createObstacleIndex(){return new tJ(this.inputProblem.simpleRouteJson,this.traces,\"repair-vias\"===this.phase?void 0:this.traceIndices?.[this.traceCursor],[],this.connectionNameResolver)}rebuildObstacleIndex(){this.obstacleIndex=this.createObstacleIndex()}resolveNominalTraceWidth(t){const e=this.findConnectionForTrace(t);return Math.max(e?.nominalTraceWidth??e?.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.inputProblem.simpleRouteJson.minTraceWidth,this.inputProblem.simpleRouteJson.minTraceWidth)}getPadClearanceForTrace(t){const e=this.getBaseObstacleClearance();return this.resolveNominalTraceWidth(t)\u003e=.499999?Math.max(e,this.desiredPadClearance??this.resolveNominalTraceWidth(t)/2):e}getBaseObstacleClearance(){return Math.max(this.inputProblem.simpleRouteJson.defaultObstacleMargin??0,this.inputProblem.simpleRouteJson.minTraceToPadEdgeClearance??0,.1)}getCandidatePadClearance(t,e,n,o){const i=this.traces[e],r=this.getBaseObstacleClearance(),s=this.getPadClearanceForTrace(i);if(\"pad-clearance\"===t)return s;const a=\"via-pair\"===t?Math.min(s,Math.max(r,.15)):s;return this.findExistingPadClearance(e,n,o,r,a)}getImprovedPadClearanceTiers(t,e,n){const o=this.traces[t],i=this.getBaseObstacleClearance(),r=this.getPadClearanceForTrace(o),s=this.findExistingPadClearance(t,e,n,i,r),a=Math.max(.025,Math.min(.05,r/10)),c=[r];for(let t=r-a;t\u003es+a/2;t-=a)c.push(t);return BJ(c).filter(t=\u003et\u003es+Mq)}findExistingPadClearance(t,e,n,o,i){if(this.routeRangeHasPadClearanceViolation(t,e,n,o))return o;if(!this.routeRangeHasPadClearanceViolation(t,e,n,i))return i;let r=o,s=i;for(let o=0;o\u003c7;o++){const o=(r+s)/2;this.routeRangeHasPadClearanceViolation(t,e,n,o)?s=o:r=o}return Math.max(o,Number((r-.001).toFixed(6)))}routeRangeHasPadClearanceViolation(t,e,n,o){const i=this.traces[t],r=this.getTraceConnectionNames(i);for(let s=e;s\u003cn;s++){const a=i.route[s],c=i.route[s+1];if(!DJ(a)||!DJ(c)||a.layer!==c.layer)continue;if(this.obstacleIndex.findCollisions({start:a,end:c,layer:a.layer,width:Math.max(a.width,c.width),connectionNames:r,ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,e-1),end:Math.min(i.route.length-1,n+1)},obstacleClearance:o}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind))return!0}return!1}countPadClearanceViolations(t){let e=0;for(const n of this.traceIndices){const o=this.traces[n];if(!o)continue;const i=this.getTraceConnectionNames(o);for(let r=0;r\u003co.route.length-1;r++){const s=o.route[r],a=o.route[r+1];if(!DJ(s)||!DJ(a)||s.layer!==a.layer)continue;this.obstacleIndex.findCollisions({start:s,end:a,layer:s.layer,width:Math.max(s.width,a.width),connectionNames:i,ignoreTraceIndex:n,ignoreRouteRange:{start:Math.max(0,r-1),end:Math.min(o.route.length-1,r+2)},obstacleClearance:t??this.getPadClearanceForTrace(o)}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind)\u0026\u0026e++}}return e}countPadClearanceViolationsByTier(){return Object.fromEntries(LJ.map(t=\u003e[t.toFixed(2),this.countPadClearanceViolations(t)]))}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=new Set(this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t))),o=this.inputProblem.simpleRouteJson.connections.find(t=\u003ethis.connectionNameResolver.canonicalize(this.getConnectionNames(t)).some(t=\u003en.has(t)))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getConnectionNames(t){return[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))}getTraceConnectionNames(t){return[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=\u003eBoolean(t))}ensureConnectivitySafeOutput(){if(!this.connectivityFinalized){this.connectivityFinalized=!0,this.connectivityValidationCount++;try{const t=this.connectivityInvariant.validate(this.traces);if(this.connectivityValidationError??=t.validationError??null,t.safe)return void(this.finalizedMutatedTraceIndices=this.getMutatedTraceIndices());this.connectivityRegressionEndpointIds=[...new Set(t.regressions.flatMap(t=\u003et.baselineEndpointLabels))]}catch(t){this.connectivityValidationError=t instanceof Error?t.message:String(t)}this.connectivityRollbackCount++,this.connectivityRollbackMutationStats={committedClearanceShoveCount:this.committedClearanceShoveCount,viaPairCountRemoved:this.viaPairCountRemoved,viaCountRemoved:this.viaCountRemoved,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,achievedExtraClearanceCount:this.achievedExtraClearanceCount,relocatedViaCount:this.relocatedViaCount,committedPushedViaRepairCount:this.committedPushedViaRepairCount,padClearanceRerouteCount:this.padClearanceRerouteCount},this.committedClearanceShoveCount=0,this.viaPairCountRemoved=0,this.viaCountRemoved=0,this.simplifiedPathCount=0,this.normalizedSegmentCount=0,this.achievedExtraClearanceCount=0,this.relocatedViaCount=0,this.committedPushedViaRepairCount=0,this.padClearanceRerouteCount=0,this.traces=structuredClone(this.initialConnectivitySafeTraces),this.obstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,void 0,[],this.connectionNameResolver),this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.finalizedMutatedTraceIndices=this.getMutatedTraceIndices()}}getMutatedTraceIndices(){const t=Math.max(this.initialConnectivitySafeTraces.length,this.traces.length);return Array.from({length:t},(t,e)=\u003ee).filter(t=\u003eJSON.stringify(this.initialConnectivitySafeTraces[t])!==JSON.stringify(this.traces[t]))}createStats(){const t=this.candidates[this.candidateCursor],e=\"repair-vias\"===this.phase?this.viaRepairTraceIndices:this.traceIndices;return{phase:this.phase,budgetLimited:this.budgetLimited,completionReason:\"complete\"===this.phase||this.solved?this.connectivityRollbackCount\u003e0?\"connectivity_rollback\":this.budgetLimited?\"iteration_budget\":this.connectivityValidationError?\"connectivity_validation_unavailable\":\"completed\":null,resultStatus:this.connectivityRollbackCount\u003e0||this.budgetLimited||null!==this.connectivityValidationError?\"best_effort\":\"complete\",traceCursor:this.traceCursor,traceCount:e.length,traceIndex:e[this.traceCursor],routeCursor:this.routeCursor,candidateCursor:this.candidateCursor,candidateCount:this.candidates.length,candidateKind:t?.kind,candidateWidth:t?.width,candidatePointCount:t?.points.length,clearancePadding:this.clearancePaddingTiers[this.clearanceTierCursor],candidateShoveCount:this.candidateShoveCount,attemptedCandidateCount:this.attemptedCandidateCount,attemptedClearanceShoveCount:this.attemptedClearanceShoveCount,attemptedViaGridCount:this.attemptedViaGridCount,committedClearanceShoveCount:this.committedClearanceShoveCount,viaPairCountRemoved:this.viaPairCountRemoved,viaCountRemoved:this.viaCountRemoved,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,achievedExtraClearanceCount:this.achievedExtraClearanceCount,relocatedViaCount:this.relocatedViaCount,unresolvedViaCount:this.unresolvedViaCount,attemptedPushedViaRepairCount:this.attemptedPushedViaRepairCount,committedPushedViaRepairCount:this.committedPushedViaRepairCount,padClearanceRerouteCount:this.padClearanceRerouteCount,unresolvedPadClearanceCount:this.unresolvedPadClearanceCount,initialPadClearanceViolationCount:this.initialPadClearanceViolationCount,remainingPadClearanceViolationCount:this.remainingPadClearanceViolationCount,initialPadClearanceViolationCountByClearance:{...this.initialPadClearanceViolationCountByClearance},remainingPadClearanceViolationCountByClearance:{...this.remainingPadClearanceViolationCountByClearance},connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},mutatedTraceIndices:[...this.finalizedMutatedTraceIndices],spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){if(this.solved||\"complete\"===this.phase)return 1;const t=\"repair-vias\"===this.phase?this.viaRepairTraceIndices:this.traceIndices;if(0===t.length)return 1;const e=\"scan-via-pairs\"===this.resumePhase?0:.5;return Math.min(.99,e+this.traceCursor/t.length*.5)}getConstructorParams(){return[this.inputProblem]}tryFinalAcceptance(){const t=this.pushedViaRepairRollbackTraces??this.rollbackTraces;t\u0026\u0026(this.traces=t),this.activeSubSolver=null,this.rollbackTraces=null,this.pushedViaRepairRollbackTraces=null,this.pendingPushedViaRepair=null,this.alternatePushedViaRepairs=[],this.viaGridAttempt=null,this.candidates=[],this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1,this.candidateSetMayUseGridFallback=!1,this.ensureConnectivitySafeOutput(),this.obstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,void 0,[],this.connectionNameResolver),this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.budgetLimited=!0,this.phase=\"complete\",this.solved=!0,this.progress=1,this.stats=this.createStats()}getOutput(){return structuredClone(this.solved?this.traces:this.initialConnectivitySafeTraces)}visualize(){const t=[],e=[],n=this.candidates[this.candidateCursor];for(let n=0;n\u003cthis.traces.length;n++){const o=this.traces[n];for(const t of o.route)\"via\"===t.route_type\u0026\u0026e.push({center:t,radius:(t.via_diameter??.6)/2,fill:\"#d4a017\",stroke:\"#7a5700\"});for(let e=0;e\u003co.route.length-1;e++){const n=o.route[e],i=o.route[e+1];DJ(n)\u0026\u0026DJ(i)\u0026\u0026n.layer===i.layer\u0026\u0026t.push({points:[n,i],strokeColor:\"bottom\"===n.layer?\"#376fc4\":\"#777\",strokeWidth:n.width})}}if(n)for(let e=0;e\u003cn.points.length-1;e++)t.push({points:[n.points[e],n.points[e+1]],strokeColor:\"#ff7400\",strokeWidth:n.width+2*(this.clearancePaddingTiers[this.clearanceTierCursor]??0)});return{coordinateSystem:\"cartesian\",title:`Power trace cleanup: ${this.phase}`,lines:t,points:[],circles:e,rects:[],texts:[]}}},$J=t=\u003e\"wire\"===t?.route_type,YJ=class extends Sq{inputProblem;traces;obstacleIndex;traceCursor=0;routeCursor=0;repairedSegmentCount=0;repairedPadNeckSegmentCount=0;unresolvedSegmentCount=0;totalWidthReduction=0;budgetLimited=!1;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;connectionNameResolver;nominalWidthByTraceId=new Map;connectivityInvariant;initialConnectivitySafeTraces;minimumTraceWidth;traceIndices;connectivityFinalized=!1;constructor(t){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.initialConnectivitySafeTraces=structuredClone(t.traces),this.connectivityInvariant=new OJ(this.inputProblem.simpleRouteJson,this.initialConnectivitySafeTraces),this.connectionNameResolver=new Pq(t.simpleRouteJson,this.traces),this.minimumTraceWidth=t.simpleRouteJson.minTraceWidth;const e=t.traceIndices?[...new Set(t.traceIndices)]:this.traces.map((t,e)=\u003ee);for(const t of e)if(!Number.isInteger(t)||t\u003c0||t\u003e=this.traces.length)throw new RangeError(`Invalid clearance-repair trace index: ${t}`);this.traceIndices=e,this.obstacleIndex=this.createConservativeObstacleIndex();const n=this.traceIndices.reduce((t,e)=\u003et+Math.max(0,this.traces[e].route.length-1),0);this.MAX_ITERATIONS=Math.max(10,8*n+2*this.traceIndices.length),this.stats=this.createStats()}getSolverName(){return\"PowerTraceClearanceRepairSolver\"}_step(){const t=this.traceIndices[this.traceCursor],e=void 0===t?void 0:this.traces[t];if(!e)return this.ensureConnectivitySafeOutput(),this.solved=!0,void(this.stats=this.createStats());if(this.routeCursor\u003e=e.route.length-1)return this.traceCursor++,this.routeCursor=0,void(this.stats=this.createStats());const n=this.routeCursor++,o=e.route[n],i=e.route[n+1];if(!$J(o)||!$J(i)||o.layer!==i.layer)return void(this.stats=this.createStats());const r=Math.max(o.width,i.width),s={start:o,end:i,layer:o.layer,width:r,connectionNames:this.getTraceConnectionNames(e),ignoreTraceIndex:t,ignoreRouteRange:{start:n,end:n+1}};if(this.repairConnectedPadNeck(e,n,s))return void(this.stats=this.createStats());if(!this.segmentHasForeignTraceCollision(n,r))return void(this.stats=this.createStats());if(this.segmentHasForeignTraceCollision(n,this.minimumTraceWidth))return this.unresolvedSegmentCount++,void(this.stats=this.createStats());let a=this.minimumTraceWidth,c=r;for(let t=0;t\u003c10;t++){const t=(a+c)/2;this.segmentHasForeignTraceCollision(n,t)?c=t:a=t}const l=r\u003e=.5?.025:.0125,d=Math.max(this.minimumTraceWidth,Math.floor((a+Mq)/l)*l),h=this.segmentHasForeignTraceCollision(n,d)?a:d,u=o.width,p=i.width;o.width=Math.min(o.width,h),i.width=Math.min(i.width,h);const m=u-o.width+(p-i.width);if(m\u003c=Mq)return this.unresolvedSegmentCount++,void(this.stats=this.createStats());this.repairedSegmentCount++,this.totalWidthReduction+=m,this.obstacleIndex=this.createConservativeObstacleIndex(),this.routeCursor=Math.max(0,n-1),this.stats=this.createStats()}repairConnectedPadNeck(t,e,n){const o=t.route[e],i=t.route[e+1];if(!$J(o)||!$J(i))return!1;let r=this.obstacleIndex.getConnectedPadWidthLimitAtPoint(n,o),s=this.obstacleIndex.getConnectedPadWidthLimitAtPoint(n,i);0===e\u0026\u0026(r=this.getSmallerLimit(r,this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(n,o))),e+1===t.route.length-1\u0026\u0026(s=this.getSmallerLimit(s,this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(n,i)));const a=r,c=s;if((null===a||o.width\u003c=a+Mq)\u0026\u0026(null===c||i.width\u003c=c+Mq))return!1;const l=o.width,d=i.width;if(null!==a\u0026\u0026(o.width=Math.min(o.width,a)),null!==c\u0026\u0026(i.width=Math.min(i.width,c)),null!==a\u0026\u0026null===c)this.insertPadBoundaryTransition(t,e,n,\"start\",o.width,d);else if(null===a\u0026\u0026null!==c)this.insertPadBoundaryTransition(t,e,n,\"end\",i.width,l);else if(null!==a\u0026\u0026null!==c){const r=this.obstacleIndex.getConnectedPadBoundaryPoint(n,\"start\"),s=this.obstacleIndex.getConnectedPadBoundaryPoint(n,\"end\");r\u0026\u0026s\u0026\u0026(this.insertPadBoundaryTransition(t,e,n,\"start\",o.width,d),this.insertPadBoundaryTransition(t,e+2,n,\"end\",i.width,l))}return this.totalWidthReduction+=l-o.width+(d-i.width),this.repairedPadNeckSegmentCount++,this.obstacleIndex=this.createConservativeObstacleIndex(),this.routeCursor=Math.max(0,e-1),!0}getSmallerLimit(t,e){return null===t?e:null===e?t:Math.min(t,e)}insertPadBoundaryTransition(t,e,n,o,i,r){const s=this.obstacleIndex.getConnectedPadBoundaryPoint(n,o);if(!s)return;const a=\"start\"===o?n.start:n.end,c=\"start\"===o?n.end:n.start,l=Math.hypot(c.x-a.x,c.y-a.y);if(l\u003c=1e-9)return;const d=Math.min(1e-6,l/4),h=(c.x-a.x)/l,u=(c.y-a.y)/l,p={route_type:\"wire\",x:s.x-h*d,y:s.y-u*d,width:i,layer:n.layer},m={...p,x:s.x+h*d,y:s.y+u*d,width:r},g=\"start\"===o?t.route[e+1]:t.route[e],f=\"start\"===o?t.route[e+2]:t.route[e-1];if($J(g)\u0026\u0026\"via\"===f?.route_type){const e=this.resolveNominalTraceWidth(t);this.obstacleIndex.collides({...n,start:g,end:m,width:e})||(g.width=Math.max(g.width,e),m.width=g.width)}t.route.splice(e+1,0,...\"start\"===o?[p,m]:[m,p])}resolveNominalTraceWidth(t){const e=this.nominalWidthByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e;const n=new Set(this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t))),o=this.inputProblem.simpleRouteJson.connections.find(t=\u003ethis.connectionNameResolver.canonicalize([t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))).some(t=\u003en.has(t))),i=Math.max(o?.nominalTraceWidth??o?.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.minimumTraceWidth,this.minimumTraceWidth);return this.nominalWidthByTraceId.set(t.pcb_trace_id,i),i}segmentHasForeignTraceCollision(t,e){const n=this.traceIndices[this.traceCursor],o=void 0===n?void 0:this.traces[n],i=o?.route[t],r=o?.route[t+1];return!!(o\u0026\u0026$J(i)\u0026\u0026$J(r)\u0026\u0026i.layer===r.layer)\u0026\u0026this.obstacleIndex.findCollisions({start:i,end:r,layer:i.layer,width:e,connectionNames:this.getTraceConnectionNames(o),ignoreTraceIndex:n,ignoreRouteRange:{start:t,end:t+1}}).some(t=\u003e\"trace\"===t.kind\u0026\u0026void 0!==t.traceIndex\u0026\u0026t.traceIndex!==n)}createConservativeObstacleIndex(){const t=structuredClone(this.traces);for(const e of t)for(let t=0;t\u003ce.route.length-1;t++){const n=e.route[t],o=e.route[t+1];$J(n)\u0026\u0026$J(o)\u0026\u0026n.layer===o.layer\u0026\u0026(n.width=Math.max(n.width,o.width))}return new tJ(this.inputProblem.simpleRouteJson,t,void 0,[],this.connectionNameResolver)}getTraceConnectionNames(t){return[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=\u003eBoolean(t))}ensureConnectivitySafeOutput(){if(!this.connectivityFinalized){this.connectivityFinalized=!0,this.connectivityValidationCount++;try{const t=this.connectivityInvariant.validate(this.traces);if(this.connectivityValidationError??=t.validationError??null,t.safe)return;this.connectivityRegressionEndpointIds=[...new Set(t.regressions.flatMap(t=\u003et.baselineEndpointLabels))]}catch(t){this.connectivityValidationError=t instanceof Error?t.message:String(t)}this.connectivityRollbackCount++,this.connectivityRollbackMutationStats={repairedSegmentCount:this.repairedSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,totalWidthReduction:this.totalWidthReduction},this.repairedSegmentCount=0,this.repairedPadNeckSegmentCount=0,this.totalWidthReduction=0,this.traces=structuredClone(this.initialConnectivitySafeTraces),this.obstacleIndex=this.createConservativeObstacleIndex()}}createStats(){return{phase:this.solved?\"complete\":\"repair-trace-clearance\",budgetLimited:this.budgetLimited,completionReason:this.solved?this.connectivityRollbackCount\u003e0?\"connectivity_rollback\":this.budgetLimited?\"iteration_budget\":this.connectivityValidationError?\"connectivity_validation_unavailable\":\"completed\":null,resultStatus:this.connectivityRollbackCount\u003e0||this.budgetLimited||null!==this.connectivityValidationError?\"best_effort\":\"complete\",traceCursor:this.traceCursor,traceCount:this.traceIndices.length,traceIndex:this.traceIndices[this.traceCursor],routeCursor:this.routeCursor,repairedSegmentCount:this.repairedSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,unresolvedSegmentCount:this.unresolvedSegmentCount,totalWidthReduction:this.totalWidthReduction,connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){return this.solved||0===this.traceIndices.length?1:Math.min(.99,this.traceCursor/this.traceIndices.length)}tryFinalAcceptance(){this.ensureConnectivitySafeOutput(),this.budgetLimited=!0,this.solved=!0,this.progress=1,this.stats=this.createStats()}getConstructorParams(){return[this.inputProblem]}getOutput(){return structuredClone(this.solved?this.traces:this.initialConnectivitySafeTraces)}visualize(){const t=[];for(let e=0;e\u003cthis.traces.length;e++){const n=this.traces[e];for(let o=0;o\u003cn.route.length-1;o++){const i=n.route[o],r=n.route[o+1];$J(i)\u0026\u0026$J(r)\u0026\u0026i.layer===r.layer\u0026\u0026t.push({points:[i,r],strokeColor:e===this.traceIndices[this.traceCursor]\u0026\u0026o===this.routeCursor?\"#ff7400\":\"bottom\"===i.layer?\"#376fc4\":\"#777\",strokeWidth:Math.max(i.width,r.width)})}}return{coordinateSystem:\"cartesian\",title:\"Power trace direction-independent clearance repair\",lines:t,points:[],circles:[],rects:[],texts:[]}}},XJ=[{x:0,y:0},{x:.5,y:0},{x:0,y:.5},{x:.5,y:.5}],VJ=[{offset:{x:0,y:0},strictNecking:!0},{offset:{x:.5,y:.5},strictNecking:!0},{offset:{x:0,y:0},strictNecking:!1},{offset:{x:.5,y:.5},strictNecking:!1}],WJ=t=\u003e[...new Set(t.map(t=\u003eNumber(t.toFixed(6))))].sort((t,e)=\u003ee-t),HJ=t=\u003e\"wire\"===t?.route_type,GJ=class extends Sq{inputProblem;options;traces;obstacleIndex;connectionNameResolver;connectionByTraceId=new Map;connectivityInvariant;lastConnectivitySafeTraces;traceOrder;selectedOwnedTraceIndices;selectedCleanupTraceIndices;selectedViaRepairTraceIndices;mutableBlockerTraceIndices;immutableTraceIndices;initialImmutableTraceSignatures=new Map;traceOrderCursor=-1;maxPassCount=4;previousWidthDeficit=0;passIndex=0;completedPassCount=0;lastNormalizedWidthDeficitGain=0;normalizedWidthDeficitGainByPass=[];plateauReached=!1;phase=\"scan-trace\";traceIndex=-1;routeSegmentIndex=0;nominalTraceWidth=0;currentIntervals=[];intervalCursor=0;candidateWidths=[];widthCursor=0;gridResolutions=[];resolutionCursor=0;offsetCursor=0;keptTraceCount=0;recreatedTraceCount=0;expandedSegmentCount=0;intermediateExpandedSegmentCount=0;pathWidthUpgradeCount=0;inPlaceWidthProbeCount=0;reroutedSegmentCount=0;unresolvedSegmentCount=0;attemptedGridCount=0;attemptedLayerGridCount=0;attemptedInflationCount=0;pushedTraceCount=0;elasticPushedTraceCount=0;layerReroutedTraceCount=0;insertedViaCount=0;neckedLayerSegmentCount=0;removedViaPairCount=0;removedViaCount=0;simplifiedPathCount=0;normalizedSegmentCount=0;cleanupClearanceShoveCount=0;relocatedViaCount=0;unresolvedViaCount=0;initialImmutableViaViolationCount=0;remainingImmutableViaViolationCount=0;initialImmutableViaViolationPairCount=0;remainingImmutableViaViolationPairCount=0;immutableTraceMutationIds=[];lastSafeImmutableViaViolationSignatures=new Set;immutableViaViolationRollbackCount=0;attemptedImmutableViaViolationCount=null;attemptedImmutableViaViolationPairCount=null;immutableViaViolationRegressionIds=[];padClearanceRerouteCount=0;unresolvedPadClearanceCount=0;repairedTraceClearanceSegmentCount=0;repairedPadNeckSegmentCount=0;unresolvedTraceClearanceSegmentCount=0;sameNetContactRejectionCount=0;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRollbackPhases=[];immutableSafetyRollbackCount=0;immutableSafetyRollbackPhases=[];connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;immutableSafetyRollbackMutationStats=null;discardedExpansionMutationStats=null;initialPadClearanceViolationCount=0;remainingPadClearanceViolationCount=0;initialPadClearanceViolationCountByClearance={};remainingPadClearanceViolationCountByClearance={};budgetLimitedExpansion=!1;finalAcceptanceUsed=!1;cleanupCompleted=!1;clearanceRepairCompleted=!1;cleanupBestEffortAccepted=!1;clearanceRepairBestEffortAccepted=!1;cleanupIterationBudget=0;clearanceRepairIterationBudget=0;expansionPushedTraceIndices=new Set;cleanupMutatedTraceIndices=[];failedSubSolverCount=0;inflationAttemptsBySegment=new Map;layerAttemptCountByTrace=new Map;layerRerouteCountByTrace=new Map;activeInflationKey=null;activeInflationWidth=null;layerAttempt=null;pendingLayerOutput=null;pendingLayerPushCount=0;constructor(t,e={}){super(),this.inputProblem=structuredClone(t),this.options=structuredClone(e),this.traces=structuredClone(t.traces??[]),this.connectionNameResolver=new Pq(this.inputProblem,this.traces),this.lastConnectivitySafeTraces=structuredClone(this.traces),this.connectivityInvariant=new OJ(this.inputProblem,this.lastConnectivitySafeTraces);const n=e.onlyConnectionNames?new Set(this.connectionNameResolver.canonicalize([...e.onlyConnectionNames])):null,o=this.traces.flatMap((t,e)=\u003e{if(!n)return[e];return this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t)).some(t=\u003en.has(t))?[e]:[]}),i=new Map(o.map(t=\u003e[t,this.getInitialTracePriority(this.traces[t])]));this.traceOrder=o.sort((t,e)=\u003ei.get(e)-i.get(t)||t-e),this.selectedOwnedTraceIndices=this.traceOrder.filter(t=\u003ethis.findConnectionForTrace(this.traces[t])),this.selectedCleanupTraceIndices=[...this.selectedOwnedTraceIndices],this.selectedViaRepairTraceIndices=[...this.selectedOwnedTraceIndices],this.mutableBlockerTraceIndices=this.traces.flatMap((t,e)=\u003ethis.findConnectionForTrace(t)?[e]:[]);const r=new Set(this.mutableBlockerTraceIndices);this.immutableTraceIndices=this.traces.flatMap((t,e)=\u003er.has(e)?[]:(this.initialImmutableTraceSignatures.set(e,JSON.stringify(t)),[e])),this.previousWidthDeficit=this.calculateWidthDeficit().deficit,this.obstacleIndex=new tJ(this.inputProblem,this.traces,this.traceIndex\u003e=0?this.traceIndex:void 0,[],this.connectionNameResolver),this.lastSafeImmutableViaViolationSignatures=this.getImmutableViaViolationSignatures(this.traces),this.initialImmutableViaViolationCount=this.countViolatingImmutableVias(this.lastSafeImmutableViaViolationSignatures),this.remainingImmutableViaViolationCount=this.initialImmutableViaViolationCount,this.initialImmutableViaViolationPairCount=this.lastSafeImmutableViaViolationSignatures.size,this.remainingImmutableViaViolationPairCount=this.initialImmutableViaViolationPairCount,this.activeSubSolver=null,this.MAX_ITERATIONS=8e6,this.stats=this.createStats()}getSolverName(){return\"PowerTraceExpanderSolver\"}_step(){if(this.shouldStartBudgetFinalization())return this.startBudgetFinalization(),void(this.stats=this.createStats());if(this.activeSubSolver)return this.stepActiveGridSolver(),void(this.stats=this.createStats());switch(this.phase){case\"scan-trace\":this.scanNextTrace();break;case\"evaluate-segment\":this.evaluateNextSegment();break;case\"try-trace-inflation\":case\"cleanup\":case\"repair-trace-clearance\":break;case\"try-layer-candidate\":this.startNextLayerCandidate();break;case\"try-grid-candidate\":this.startNextGridCandidate();break;case\"complete\":this.acceptConnectivityCheckpoint(this.traces,\"final\"),this.solved=!0}this.stats=this.createStats()}scanNextTrace(){if(this.traceOrderCursor++,this.routeSegmentIndex=0,this.traceOrderCursor\u003e=this.traceOrder.length)return void this.finishOrStartNextPass();this.traceIndex=this.traceOrder[this.traceOrderCursor];const t=this.traces[this.traceIndex];this.findConnectionForTrace(t)?(this.nominalTraceWidth=this.resolveNominalTraceWidth(t),this.traceMeetsNominalWidth(t,this.nominalTraceWidth)?this.keptTraceCount++:(this.rebuildObstacleIndex(),t.route=function(t,e){if(t.length\u003c2)return t.map(t=\u003e({...t}));const n=[];for(let o=0;o\u003ct.length-1;o++){const i=t[o],r=t[o+1];if(n.push({...i}),\"wire\"!==i.route_type||\"wire\"!==r.route_type||i.layer!==r.layer||i.width\u003e=e-Mq)continue;const s=Nq(i,r),a=Math.max(1,Math.ceil(s/e));for(let t=1;t\u003ca;t++){const e=t/a;n.push({route_type:\"wire\",x:i.x+(r.x-i.x)*e,y:i.y+(r.y-i.y)*e,width:i.width,layer:i.layer})}}return n.push({...t[t.length-1]}),n}(t.route,this.nominalTraceWidth),this.recreatedTraceCount++,this.phase=\"evaluate-segment\")):this.keptTraceCount++}finishOrStartNextPass(){const{deficit:t,nominalArea:e}=this.calculateWidthDeficit(),n=this.previousWidthDeficit-t;if(this.lastNormalizedWidthDeficitGain=e\u003c=Mq?0:n/e,this.normalizedWidthDeficitGainByPass.push(this.lastNormalizedWidthDeficitGain),this.plateauReached=this.lastNormalizedWidthDeficitGain\u003c.001,this.completedPassCount=this.passIndex+1,this.passIndex+1\u003cthis.maxPassCount\u0026\u0026this.lastNormalizedWidthDeficitGain\u003e=.001)return this.previousWidthDeficit=t,this.passIndex++,this.traceOrderCursor=-1,this.traceIndex=-1,this.routeSegmentIndex=0,this.inflationAttemptsBySegment.clear(),void(this.phase=\"scan-trace\");this.startCleanup()}startCleanup(){this.acceptConnectivityCheckpoint(this.traces,\"expansion\"),this.traceIndex=this.traces.length,this.phase=\"cleanup\";const t=new jJ({simpleRouteJson:this.inputProblem,traces:this.traces,traceIndices:this.selectedCleanupTraceIndices,viaRepairTraceIndices:this.selectedViaRepairTraceIndices,mutableTraceIndices:this.mutableBlockerTraceIndices,maxRerouteLength:10,desiredPadClearance:this.options.powerTraceToPadClearance}),e=this.getRemainingParentIterationsAfterCurrentStep(),n=0===e?0:Math.max(1,Math.floor(.75*e));t.MAX_ITERATIONS=Math.min(t.MAX_ITERATIONS,n),this.cleanupIterationBudget=t.MAX_ITERATIONS,this.activeSubSolver=t}shouldStartBudgetFinalization(){return!this.budgetLimitedExpansion\u0026\u0026(\"cleanup\"!==this.phase\u0026\u0026\"repair-trace-clearance\"!==this.phase\u0026\u0026\"complete\"!==this.phase\u0026\u0026this.iterations\u003e=this.getExpansionIterationBudget())}getFinalizationIterationReserve(){return Math.min(Math.max(0,this.MAX_ITERATIONS-1),Math.max(1,Math.floor(.125*this.MAX_ITERATIONS)))}getExpansionIterationBudget(){return Math.max(1,this.MAX_ITERATIONS-this.getFinalizationIterationReserve())}startBudgetFinalization(){this.budgetLimitedExpansion=!0,this.activeSubSolver=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.activeInflationKey=null,this.activeInflationWidth=null,this.layerAttempt=null,this.discardInFlightExpansion(),this.startCleanup()}discardInFlightExpansion(){this.discardedExpansionMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}rollbackConnectivityRegressedExpansion(){this.connectivityRollbackMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}rollbackImmutableUnsafeExpansion(){this.immutableSafetyRollbackMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}captureAndResetExpansionMutationStats(){const t={recreatedTraceCount:this.recreatedTraceCount,expandedSegmentCount:this.expandedSegmentCount,intermediateExpandedSegmentCount:this.intermediateExpandedSegmentCount,pathWidthUpgradeCount:this.pathWidthUpgradeCount,reroutedSegmentCount:this.reroutedSegmentCount,pushedTraceCount:this.pushedTraceCount,elasticPushedTraceCount:this.elasticPushedTraceCount,layerReroutedTraceCount:this.layerReroutedTraceCount,insertedViaCount:this.insertedViaCount,neckedLayerSegmentCount:this.neckedLayerSegmentCount};return this.recreatedTraceCount=0,this.expandedSegmentCount=0,this.intermediateExpandedSegmentCount=0,this.pathWidthUpgradeCount=0,this.reroutedSegmentCount=0,this.pushedTraceCount=0,this.elasticPushedTraceCount=0,this.layerReroutedTraceCount=0,this.insertedViaCount=0,this.neckedLayerSegmentCount=0,this.expansionPushedTraceIndices.clear(),t}restoreLastConnectivitySafeTraces(){this.traces=structuredClone(this.lastConnectivitySafeTraces),this.rebuildObstacleIndex()}getRemainingParentIterationsAfterCurrentStep(){return Math.max(0,this.MAX_ITERATIONS-this.iterations-1)}calculateWidthDeficit(){let t=0,e=0;for(const n of this.traceOrder){const o=this.traces[n];if(!this.findConnectionForTrace(o))continue;const i=this.resolveNominalTraceWidth(o);for(let n=0;n\u003co.route.length-1;n++){const r=o.route[n],s=o.route[n+1];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)continue;const a=Nq(r,s),c=r.width;e+=a*i,t+=a*Math.max(0,i-c)}}return{deficit:t,nominalArea:e}}getInitialTracePriority(t){const e=this.resolveNominalTraceWidth(t);let n=0;for(let o=0;o\u003ct.route.length-1;o++){const i=t.route[o],r=t.route[o+1];HJ(i)\u0026\u0026HJ(r)\u0026\u0026i.layer===r.layer\u0026\u0026(n+=Nq(i,r)*Math.max(0,e-Math.min(i.width,r.width)))}return e*n}evaluateNextSegment(){const t=this.traces[this.traceIndex];if(!t)return void(this.phase=\"scan-trace\");const e=this.findNextUnderWidthSegment(t,this.routeSegmentIndex,this.nominalTraceWidth);if(-1===e)return void(this.phase=\"scan-trace\");this.routeSegmentIndex=e;const n=t.route[e],o=t.route[e+1];if(!HJ(n)||!HJ(o))return void this.routeSegmentIndex++;const i=this.getTraceConnectionNames(t),r=Math.min(n.width,o.width),s=this.findMaximumSafeInPlaceWidth(t,e,i);if(s\u003er+Mq){if(n.width=Math.max(n.width,s),o.width=Math.max(o.width,s),s\u003e=this.nominalTraceWidth-Mq)return this.expandedSegmentCount++,void this.routeSegmentIndex++;this.intermediateExpandedSegmentCount++}this.startTraceInflation(t,e)||this.prepareLayerRouteAttempt(t,e)||this.prepareRegularGridCandidates(t,e)}prepareRegularGridCandidates(t,e){if(this.currentIntervals=this.getExponentialIntervalCandidates(t,e,this.nominalTraceWidth),this.intervalCursor=0,this.candidateWidths=this.getCandidateWidths(this.nominalTraceWidth),this.widthCursor=0,this.gridResolutions=[],this.resolutionCursor=0,this.offsetCursor=0,0===this.currentIntervals.length)return this.unresolvedSegmentCount++,void this.routeSegmentIndex++;this.phase=\"try-grid-candidate\"}prepareLayerRouteAttempt(t,e){if(this.nominalTraceWidth\u003c.499999)return!1;const n=!1!==this.options.allowNewVias\u0026\u0026this.inputProblem.layerCount\u003e=2,o=n?2:this.maxPassCount,i=this.layerAttemptCountByTrace.get(this.traceIndex)??0,r=this.layerRerouteCountByTrace.get(this.traceIndex)??0;if(r\u003e=o||i\u003e=o||i\u003ethis.passIndex||i\u003e0\u0026\u00260===r)return!1;const s=t.route[e],a=t.route[e+1];if(!HJ(s)||!HJ(a)||Math.min(s.width,a.width)\u003e=.5*this.nominalTraceWidth-Mq)return!1;const c=this.getExponentialIntervalCandidates(t,e,this.nominalTraceWidth).filter(e=\u003ethis.intervalSupportsLayerRouting(t,e)).sort((e,n)=\u003en.endIndex-e.endIndex||e.startIndex-n.startIndex||this.getRouteIntervalLength(t,n.startIndex,n.endIndex)-this.getRouteIntervalLength(t,e.startIndex,e.endIndex))[0];if(!c)return!1;const l=this.getRouteQuality(t.route.slice(c.startIndex,c.endIndex+1));if(l.deficitArea\u003cthis.nominalTraceWidth)return!1;if(i\u003e0\u0026\u0026l.deficitArea/Math.max(l.length,Mq)\u003c.25)return!1;const d=t.route[c.startIndex],h=t.route[c.endIndex],u=this.getTraceConnectionNames(t),p=n?this.getEndpointLayers(d,u):[d.layer],m=n?this.getEndpointLayers(h,u):[h.layer],g=Math.min(this.nominalTraceWidth,Math.max(d.width,this.findMaximumSafeInPlaceWidth(t,c.startIndex,u))),f=Math.min(this.nominalTraceWidth,Math.max(h.width,this.findMaximumSafeInPlaceWidth(t,c.endIndex-1,u))),y=this.getSoftTraceIndices(this.nominalTraceWidth);return this.layerAttemptCountByTrace.set(this.traceIndex,i+1),this.layerAttempt={interval:c,minViaCount:n?1:0,maxViaCount:n?2:0,candidateWidths:[this.nominalTraceWidth],widthCursor:0,gridResolutions:[Rq(this.nominalTraceWidth/4,.2,.3)],resolutionCursor:0,offsetCursor:0,startLayers:p,endLayers:m,startNeckWidth:g,endNeckWidth:f,softTraceIndices:y},this.phase=\"try-layer-candidate\",!0}intervalSupportsLayerRouting(t,e){if(e.startIndex\u003e=e.endIndex)return!1;for(let n=e.startIndex;n\u003c=e.endIndex;n++){const e=t.route[n];if(!HJ(e))return!1}const n=t.route[e.startIndex],o=t.route[e.endIndex];return n.layer===o.layer}getEndpointLayers(t,e){return[...new Set([t.layer,...this.obstacleIndex.getConnectedLayersAtPoint({x:t.x,y:t.y},e)])].filter(t=\u003ethis.obstacleIndex.boardLayers.includes(t))}getSoftTraceIndices(t){const e=[];for(let n=0;n\u003cthis.traces.length;n++){if(n===this.traceIndex)continue;const o=this.traces[n],i=this.findConnectionForTrace(o);if(!i)continue;Math.max(i.nominalTraceWidth??i.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth,this.inputProblem.minTraceWidth)\u003ct-Mq\u0026\u0026e.push(n)}return e}startNextLayerCandidate(){const t=this.layerAttempt,e=this.traces[this.traceIndex];if(!t||!e)return this.layerAttempt=null,void(this.phase=\"evaluate-segment\");if(t.widthCursor\u003e=t.candidateWidths.length){const t=this.routeSegmentIndex;return this.layerAttempt=null,void this.prepareRegularGridCandidates(e,t)}const n=t.candidateWidths[t.widthCursor];if(0===t.gridResolutions.length\u0026\u0026(t.gridResolutions=this.getGridResolutions(n)),t.resolutionCursor\u003e=t.gridResolutions.length)return t.widthCursor++,t.gridResolutions=[],t.resolutionCursor=0,void(t.offsetCursor=0);if(t.offsetCursor\u003e=VJ.length)return t.resolutionCursor++,void(t.offsetCursor=0);const o=e.route[t.interval.startIndex],i=e.route[t.interval.endIndex];if(!HJ(o)||!HJ(i))return this.layerAttempt=null,void this.prepareRegularGridCandidates(e,this.routeSegmentIndex);const r=t.gridResolutions[t.resolutionCursor],s=VJ[t.offsetCursor],a=s.offset,c=Math.min(t.startNeckWidth,t.endNeckWidth),l=this.inputProblem.min_via_hole_diameter??this.inputProblem.minViaHoleDiameter??.3,d=Math.max(l,this.inputProblem.min_via_pad_diameter??this.inputProblem.minViaPadDiameter??this.inputProblem.minViaDiameter??.6),h=Math.max(this.inputProblem.minTraceWidth,Math.min(s.strictNecking?t.startNeckWidth:c,n)),u=Math.max(this.inputProblem.minTraceWidth,Math.min(s.strictNecking?t.endNeckWidth:c,n)),p=Rq(3*this.nominalTraceWidth,1.5,3);t.maxViaCount\u003e0?this.attemptedLayerGridCount++:this.attemptedGridCount++,this.activeSubSolver=new Yq({start:o,end:i,originalStartLayer:o.layer,originalEndLayer:i.layer,startLayers:t.startLayers,endLayers:t.endLayers,layers:this.obstacleIndex.boardLayers,traceWidth:n,startNeckWidth:h,endNeckWidth:u,maxStartNeckLength:p,maxEndNeckLength:p,neckPenaltyExponent:s.strictNecking?2:1,viaDiameter:d,viaHoleDiameter:l,minViaCount:t.minViaCount,maxViaCount:t.maxViaCount,viaCost:Math.max(1,2*this.nominalTraceWidth),gridSize:r,gridOffset:{x:a.x*r,y:a.y*r},connectionNames:this.getTraceConnectionNames(e),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,t.interval.startIndex-1),end:Math.min(e.route.length-1,t.interval.endIndex+1)},softTraceIndices:t.softTraceIndices,fixedVias:this.getFixedViasOutsideInterval(e,t.interval),bounds:this.inputProblem.bounds,obstacleClearance:this.getDesiredPadClearance(n),searchPadding:Math.min(5,Math.max(2.5,Nq(o,i)/2,4*n))})}startNextGridCandidate(){const t=this.traces[this.traceIndex];if(!t)return void(this.phase=\"scan-trace\");if(this.widthCursor\u003e=this.candidateWidths.length)return this.unresolvedSegmentCount++,this.routeSegmentIndex++,void(this.phase=\"evaluate-segment\");if(this.intervalCursor\u003e=this.currentIntervals.length)return this.widthCursor++,this.intervalCursor=0,this.gridResolutions=[],this.resolutionCursor=0,void(this.offsetCursor=0);const e=this.candidateWidths[this.widthCursor],n=t.route[this.routeSegmentIndex],o=t.route[this.routeSegmentIndex+1];if(HJ(n)\u0026\u0026HJ(o)\u0026\u0026e\u003c=Math.min(n.width,o.width)+Mq)return void(this.widthCursor=this.candidateWidths.length);if(0===this.gridResolutions.length\u0026\u0026(this.gridResolutions=this.getGridResolutions(e)),this.resolutionCursor\u003e=this.gridResolutions.length)return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);if(this.offsetCursor\u003e=XJ.length)return this.resolutionCursor++,void(this.offsetCursor=0);const i=this.currentIntervals[this.intervalCursor],r=t.route[i.startIndex],s=t.route[i.endIndex];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);if(this.endpointCollides(t,i,r,e)||this.endpointCollides(t,i,s,e))return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);const a=this.gridResolutions[this.resolutionCursor],c=XJ[this.offsetCursor],l={x:c.x*a,y:c.y*a};this.attemptedGridCount++,this.activeSubSolver=new Qq({start:r,end:s,layer:r.layer,traceWidth:e,gridSize:a,gridOffset:l,connectionNames:this.getTraceConnectionNames(t),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,i.startIndex-1),end:Math.min(t.route.length-1,i.endIndex+1)},bounds:this.inputProblem.bounds,obstacleClearance:this.getDesiredPadClearance(e),searchPadding:Math.min(5,Math.max(1.5,Nq(r,s)/2,3*e))})}endpointCollides(t,e,n,o){return this.obstacleIndex.collides({start:n,end:n,layer:n.layer,width:o,connectionNames:this.getTraceConnectionNames(t),ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,e.startIndex-1),end:Math.min(t.route.length-1,e.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(o)})}stepActiveGridSolver(){if(this.activeSubSolver instanceof YJ)return void this.stepActiveTraceClearanceRepairSolver();if(this.activeSubSolver instanceof jJ)return void this.stepActiveCleanupSolver();if(this.activeSubSolver instanceof oJ)return void this.stepActiveInflationSolver();if(this.activeSubSolver instanceof Yq)return void this.stepActiveLayerSolver();const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e){const t=this.gridRouteReplacementCollides(e)||this.gridRouteBoundaryCollides(e);if(!t\u0026\u0026this.gridRoutePreservesSameNetContacts(e))return this.applyGridRoute(this.maximizeGridRouteWidth(e)),void(this.activeSubSolver=null);t||this.sameNetContactRejectionCount++}}this.retainFailedSubSolver(t),this.activeSubSolver=null,this.offsetCursor++}}stepActiveCleanupSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved)return this.adoptCleanupOutput(t),this.activeSubSolver=null,void this.startTraceClearanceRepair();this.retainFailedSubSolver(t),this.activeSubSolver=null,this.startTraceClearanceRepair()}}adoptCleanupOutput(t){const e=this.acceptConnectivityCheckpoint(t.getOutput(),\"cleanup\");this.cleanupCompleted=!t.budgetLimited;const n=t.stats;this.connectivityValidationError??=n.connectivityValidationError??null,this.connectivityValidationCount+=Number(n.connectivityValidationCount??0);const o=Number(n.connectivityRollbackCount??0);o\u003e0\u0026\u0026(this.connectivityRollbackCount+=o,this.connectivityRollbackPhases.includes(\"cleanup\")||this.connectivityRollbackPhases.push(\"cleanup\"),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...n.connectivityRegressionEndpointIds??[]])]);const i=e\u0026\u00260===o;this.cleanupBestEffortAccepted=t.budgetLimited\u0026\u0026i,this.cleanupMutatedTraceIndices=i?[...n.mutatedTraceIndices??[]]:[],this.removedViaPairCount=i?Number(n.viaPairCountRemoved??0):0,this.removedViaCount=i?Number(n.viaCountRemoved??0):0,this.simplifiedPathCount=i?Number(n.simplifiedPathCount??0):0,this.normalizedSegmentCount=i?Number(n.normalizedSegmentCount??0):0,this.cleanupClearanceShoveCount=i?Number(n.committedClearanceShoveCount??0):0,this.relocatedViaCount=i?Number(n.relocatedViaCount??0):0,this.unresolvedViaCount=Number(n.unresolvedViaCount??0),this.padClearanceRerouteCount=i?Number(n.padClearanceRerouteCount??0):0,this.unresolvedPadClearanceCount=Number(n.unresolvedPadClearanceCount??0),this.initialPadClearanceViolationCount=Number(n.initialPadClearanceViolationCount??0),this.remainingPadClearanceViolationCount=Number(n.remainingPadClearanceViolationCount??0),this.initialPadClearanceViolationCountByClearance={...n.initialPadClearanceViolationCountByClearance??{}},this.remainingPadClearanceViolationCountByClearance={...n.remainingPadClearanceViolationCountByClearance??{}},this.rebuildObstacleIndex()}startTraceClearanceRepair(){this.phase=\"repair-trace-clearance\";const t=[...new Set([...this.getOwnedTraceIndices(),...this.expansionPushedTraceIndices,...this.cleanupMutatedTraceIndices])],e=new YJ({simpleRouteJson:this.inputProblem,traces:this.traces,traceIndices:t});e.MAX_ITERATIONS=Math.min(e.MAX_ITERATIONS,this.getRemainingParentIterationsAfterCurrentStep()),this.clearanceRepairIterationBudget=e.MAX_ITERATIONS,this.activeSubSolver=e}stepActiveTraceClearanceRepairSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved)return this.adoptClearanceRepairOutput(t),this.activeSubSolver=null,void(this.phase=\"complete\");this.retainFailedSubSolver(t),this.activeSubSolver=null,this.phase=\"complete\"}}adoptClearanceRepairOutput(t){const e=this.acceptConnectivityCheckpoint(t.getOutput(),\"clearance-repair\");this.clearanceRepairCompleted=!t.budgetLimited;const n=t.stats;this.connectivityValidationError??=n.connectivityValidationError??null,this.connectivityValidationCount+=Number(n.connectivityValidationCount??0);const o=Number(n.connectivityRollbackCount??0);o\u003e0\u0026\u0026(this.connectivityRollbackCount+=o,this.connectivityRollbackPhases.includes(\"clearance-repair\")||this.connectivityRollbackPhases.push(\"clearance-repair\"),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...n.connectivityRegressionEndpointIds??[]])]);const i=e\u0026\u00260===o;this.clearanceRepairBestEffortAccepted=t.budgetLimited\u0026\u0026i,this.repairedTraceClearanceSegmentCount=i?Number(n.repairedSegmentCount??0):0,this.repairedPadNeckSegmentCount=i?Number(n.repairedPadNeckSegmentCount??0):0,this.unresolvedTraceClearanceSegmentCount=Number(n.unresolvedSegmentCount??0),this.rebuildObstacleIndex()}stepActiveLayerSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e){const t=!this.layerRouteReplacementCollides(e,!0)\u0026\u0026this.layerRouteImprovesInterval(e),n=t\u0026\u0026this.layerRoutePreservesSameNetContacts(e);if(n){if(this.activeSubSolver=null,this.pendingLayerOutput=e,this.pendingLayerPushCount=0,!this.layerRouteReplacementCollides(e,!1))return void this.applyLayerRoute(e);if(this.startPendingLayerInflation())return;this.pendingLayerOutput=null}t\u0026\u0026!n\u0026\u0026this.sameNetContactRejectionCount++}}this.retainFailedSubSolver(t),this.activeSubSolver=null,this.layerAttempt\u0026\u0026this.layerAttempt.offsetCursor++,this.phase=\"try-layer-candidate\"}}layerRouteReplacementCollides(t,e){const n=this.traces[this.traceIndex],o=this.layerAttempt;if(!n||!o)return!0;const i=this.getTraceConnectionNames(n),r=e?o.softTraceIndices:void 0,s={start:Math.max(0,o.interval.startIndex-1),end:Math.min(n.route.length-1,o.interval.endIndex+1)},a=this.getFixedViasOutsideInterval(n,o.interval);for(let e=0;e\u003ct.route.length;e++){const n=t.route[e];if(\"via\"===n?.route_type){if(this.obstacleIndex.collidesVia({point:n,layers:this.obstacleIndex.boardLayers,padDiameter:n.via_diameter??.6,holeDiameter:n.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,connectionNames:i,ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:r,otherNewViaPoints:t.route.slice(0,e).filter(t=\u003e\"via\"===t.route_type).map(t=\u003e({x:t.x,y:t.y})),fixedVias:a,ignoreRouteRange:s,obstacleClearance:this.getDesiredPadClearance(t.traceWidth),blockSameNetObstacles:!0,sameNetObstacleClearance:0}))return!0;continue}const o=t.route[e+1];if(\"wire\"===n?.route_type\u0026\u0026\"wire\"===o?.route_type\u0026\u0026n.layer===o.layer\u0026\u0026this.obstacleIndex.collides({start:n,end:o,layer:n.layer,width:Math.max(n.width,o.width),connectionNames:i,ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:r,ignoreRouteRange:s,obstacleClearance:this.getDesiredPadClearance(t.traceWidth)}))return!0}return this.layerRouteBoundaryCollides(t,e)}getFixedViasOutsideInterval(t,e){return t.route.flatMap((t,n)=\u003e\"via\"!==t.route_type||n\u003e=e.startIndex\u0026\u0026n\u003c=e.endIndex?[]:[{point:{x:t.x,y:t.y},padDiameter:t.via_diameter??.6,holeDiameter:t.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter}])}layerRouteBoundaryCollides(t,e){const n=this.traces[this.traceIndex],o=this.layerAttempt,i=t.route.find(t=\u003e\"wire\"===t.route_type);let r;for(let e=t.route.length-1;e\u003e=0;e--){const n=t.route[e];if(\"wire\"===n?.route_type){r=n;break}}if(!i||!r)return!0;const s=[{outside:n.route[o.interval.startIndex-1],inside:i},{outside:n.route[o.interval.endIndex+1],inside:r}];for(const i of s)if(HJ(i.outside)\u0026\u0026i.outside.layer===i.inside.layer\u0026\u0026this.obstacleIndex.collides({start:i.outside,end:i.inside,layer:i.inside.layer,width:Math.max(i.outside.width,i.inside.width),connectionNames:this.getTraceConnectionNames(n),ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:e?o.softTraceIndices:void 0,ignoreRouteRange:{start:Math.max(0,o.interval.startIndex-1),end:Math.min(n.route.length-1,o.interval.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(t.traceWidth)}))return!0;return!1}layerRouteImprovesInterval(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=this.getRouteQuality(e.route.slice(n.startIndex,n.endIndex+1)),i=this.getRouteQuality(t.route);return i.length\u003c=o.length+10+Mq\u0026\u0026i.deficitArea\u003c=o.deficitArea-Math.max(.05,.1*o.deficitArea)}getRouteQuality(t){let e=0,n=0;for(let o=0;o\u003ct.length-1;o++){const i=t[o],r=t[o+1];if(!HJ(i)||!HJ(r)||i.layer!==r.layer)continue;const s=Nq(i,r),a=Math.min(i.width,r.width);e+=s,n+=s*Math.max(0,this.nominalTraceWidth-a)}return{length:e,deficitArea:n}}getLayerInflationCorridor(t){const e=[];for(let n=0;n\u003ct.route.length;n++){const o=t.route[n];if(\"via\"===o?.route_type){for(const t of this.obstacleIndex.boardLayers)e.push({start:o,end:o,layer:t,width:o.via_diameter??.6});continue}const i=t.route[n+1];\"wire\"===o?.route_type\u0026\u0026\"wire\"===i?.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({start:o,end:i,layer:o.layer,width:Math.max(o.width,i.width)})}return e}startPendingLayerInflation(){const t=this.pendingLayerOutput;if(!t||this.pendingLayerPushCount\u003e=2)return!1;const e=this.getLayerInflationCorridor(t);return 0!==e.length\u0026\u0026(this.pendingLayerPushCount++,this.attemptedInflationCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem,traces:this.traces,powerTraceIndex:this.traceIndex,nominalPowerWidth:t.traceWidth,mutableTraceIndices:this.mutableBlockerTraceIndices,corridor:e,maxRerouteLength:10},this.connectionNameResolver),this.phase=\"try-trace-inflation\",!0)}applyLayerRoute(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=this.createLayerRouteReplacement(t);e.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...o),t.viaCount\u003e0\u0026\u0026this.layerReroutedTraceCount++,this.layerRerouteCountByTrace.set(this.traceIndex,(this.layerRerouteCountByTrace.get(this.traceIndex)??0)+1),this.reroutedSegmentCount++,this.insertedViaCount+=t.viaCount,t.viaCount\u003e0\u0026\u0026(this.neckedLayerSegmentCount+=o.filter(t=\u003e\"wire\"===t.route_type\u0026\u0026t.width\u003cthis.nominalTraceWidth-Mq).length),this.routeSegmentIndex=n.startIndex,this.currentIntervals=[],this.layerAttempt=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.phase=\"evaluate-segment\"}createLayerRouteReplacement(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=e.route[n.startIndex],i=e.route[n.endIndex],r=structuredClone(t.route),s=r.findIndex(t=\u003e\"wire\"===t.route_type);let a=-1;for(let t=r.length-1;t\u003e=0;t--)if(\"wire\"===r[t]?.route_type){a=t;break}return s\u003e=0\u0026\u0026(r[s]={...o,...r[s]}),a\u003e=0\u0026\u0026(r[a]={...i,...r[a]}),r}layerRoutePreservesSameNetContacts(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval;return this.routeReplacementPreservesSameNetContacts(e,n,this.createLayerRouteReplacement(t))}startTraceInflation(t,e){const n=t.route[e],o=t.route[e+1];if(!HJ(n)||!HJ(o))return!1;const i=Math.min(n.width,o.width),r=this.findBestPushableInflationWidth(t,e,i);if(!r)return!1;const s=this.getLocalInflationCorridor(t,e,r);if(0===s.length)return!1;const a=[this.traceIndex,n.x,n.y,o.x,o.y].join(\":\"),c=this.inflationAttemptsBySegment.get(a)??0;return!(c\u003e=2)\u0026\u0026(this.inflationAttemptsBySegment.set(a,c+1),this.activeInflationKey=a,this.activeInflationWidth=r,this.attemptedInflationCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem,traces:this.traces,powerTraceIndex:this.traceIndex,nominalPowerWidth:r,mutableTraceIndices:this.mutableBlockerTraceIndices,corridor:s,maxRerouteLength:10},this.connectionNameResolver),this.phase=\"try-trace-inflation\",!0)}hasOnlyPushableTraceBlockers(t,e,n){const o=Math.max(0,e-1),i=Math.min(t.route.length-2,e+1),r=new Set;for(let e=o;e\u003c=i;e++){const s=t.route[e],a=t.route[e+1];if(!HJ(s)||!HJ(a)||s.layer!==a.layer)continue;const c={start:s,end:a,layer:s.layer,width:n,connectionNames:this.getTraceConnectionNames(t),ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:o,end:i+1},obstacleClearance:this.getDesiredPadClearance(n)},l=this.obstacleIndex.findCollisions(c);if(0===l.length\u0026\u0026this.obstacleIndex.collides(c))return!1;for(const t of l){if(\"trace\"!==t.kind||void 0===t.traceIndex)return!1;const e=this.traces[t.traceIndex];if(!e)return!1;const o=this.findConnectionForTrace(e);if(!o||(o.nominalTraceWidth??o.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth)\u003e=n-Mq)return!1;r.add(t.traceIndex)}}return r.size\u003e0\u0026\u0026r.size\u003c=2}findBestPushableInflationWidth(t,e,n){const o=this.nominalTraceWidth\u003e=.5?.05:.0125;for(let i=this.nominalTraceWidth;i\u003en+Mq;i-=o){const n=Number(i.toFixed(6));if(this.hasOnlyPushableTraceBlockers(t,e,n))return n}return null}stepActiveInflationSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput(),n=e\u0026\u0026this.sameNetContactsArePreserved(this.traces[e.pushedTraceIndex].route,e.traces[e.pushedTraceIndex].route,this.getTraceConnectionNames(this.traces[e.pushedTraceIndex]),e.pushedTraceIndex);if(e\u0026\u0026n){if(this.traces=e.traces,this.pushedTraceCount++,this.expansionPushedTraceIndices.add(e.pushedTraceIndex),\"elastic\"===e.strategy\u0026\u0026this.elasticPushedTraceCount++,this.activeSubSolver=null,this.activeInflationKey=null,this.activeInflationWidth=null,this.rebuildObstacleIndex(),this.pendingLayerOutput){if(!this.layerRouteReplacementCollides(this.pendingLayerOutput,!1)\u0026\u0026this.layerRoutePreservesSameNetContacts(this.pendingLayerOutput))return void this.applyLayerRoute(this.pendingLayerOutput);if(this.startPendingLayerInflation())return;return this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.layerAttempt\u0026\u0026this.layerAttempt.offsetCursor++,void(this.phase=\"try-layer-candidate\")}return void(this.phase=\"evaluate-segment\")}e\u0026\u0026!n\u0026\u0026this.sameNetContactRejectionCount++}if(this.retainFailedSubSolver(t),this.activeInflationKey\u0026\u0026this.inflationAttemptsBySegment.set(this.activeInflationKey,2),this.activeInflationKey=null,this.activeInflationWidth=null,this.activeSubSolver=null,this.pendingLayerOutput)return this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.layerAttempt\u0026\u0026this.layerAttempt.offsetCursor++,void(this.phase=\"try-layer-candidate\");this.phase=\"evaluate-segment\"}}getLocalInflationCorridor(t,e,n){const o=t.route[e],i=t.route[e+1];if(!HJ(o)||!HJ(i)||o.layer!==i.layer)return[];const r=Rq(4*n,2,4),s=r/2;let a=e,c=0;for(;a\u003e0;){const e=t.route[a-1],n=t.route[a];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(c+o\u003es+Mq)break;c+=o,a--}let l=e+1,d=0;for(;l\u003ct.route.length-1;){const e=t.route[l],n=t.route[l+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(d+o\u003es+Mq)break;d+=o,l++}let h=r-c-d;for(;h\u003eMq\u0026\u0026a\u003e0;){const e=t.route[a-1],n=t.route[a];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(o\u003eh+Mq)break;h-=o,a--}for(;h\u003eMq\u0026\u0026l\u003ct.route.length-1;){const e=t.route[l],n=t.route[l+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(o\u003eh+Mq)break;h-=o,l++}const u=[];for(let e=a;e\u003cl;e++){const o=t.route[e],i=t.route[e+1];HJ(o)\u0026\u0026HJ(i)\u0026\u0026o.layer===i.layer\u0026\u0026u.push({start:o,end:i,layer:o.layer,width:n})}return u}applyGridRoute(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=this.createGridRouteReplacement(t);e.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...o),this.reroutedSegmentCount++,this.routeSegmentIndex=n.startIndex+o.length-1,this.currentIntervals=[],this.phase=\"evaluate-segment\"}createGridRouteReplacement(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=e.route[n.startIndex],i=e.route[n.endIndex],r=t.points.map(e=\u003e({route_type:\"wire\",x:e.x,y:e.y,width:t.traceWidth,layer:o.layer}));return r[0].width=Math.max(o.width,t.traceWidth),r[r.length-1].width=Math.max(i.width,t.traceWidth),r}gridRoutePreservesSameNetContacts(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor];return this.routeReplacementPreservesSameNetContacts(e,n,this.createGridRouteReplacement(t))}routeReplacementPreservesSameNetContacts(t,e,n){const o=this.getTraceConnectionNames(t),i=this.getSameNetContactIds(t.route.slice(e.startIndex,e.endIndex+1),o,this.traceIndex),r=new Set([...this.getSameNetContactIds(t.route.slice(0,e.startIndex+1),o,this.traceIndex),...this.getSameNetContactIds(t.route.slice(e.endIndex),o,this.traceIndex)]),s=new Set([...i].filter(t=\u003e!r.has(t)));if(0===s.size)return!0;const a=this.getSameNetContactIds(n,o,this.traceIndex);return[...s].every(t=\u003ea.has(t))}sameNetContactsArePreserved(t,e,n,o){const i=this.getSameNetContactIds(t,n,o);if(0===i.size)return!0;const r=this.getSameNetContactIds(e,n,o);return[...i].every(t=\u003er.has(t))}getSameNetContactIds(t,e,n){const o=new Set;for(let i=0;i\u003ct.length;i++){const r=t[i];if(\"via\"===r?.route_type){for(const t of this.getViaLayers(r))for(const i of this.obstacleIndex.getSameNetCopperContactIds({start:r,end:r,layer:t,width:r.via_diameter??.6,connectionNames:e,ignoreTraceIndex:n}))o.add(i);continue}const s=t[i+1];if(\"wire\"===r?.route_type\u0026\u0026\"wire\"===s?.route_type\u0026\u0026r.layer===s.layer)for(const t of this.obstacleIndex.getSameNetCopperContactIds({start:r,end:s,layer:r.layer,width:Math.min(r.width,s.width),connectionNames:e,ignoreTraceIndex:n}))o.add(t)}return o}getViaLayers(t){const e=this.obstacleIndex.boardLayers.indexOf(t.from_layer),n=this.obstacleIndex.boardLayers.indexOf(t.to_layer);return e\u003c0||n\u003c0?this.obstacleIndex.boardLayers:this.obstacleIndex.boardLayers.slice(Math.min(e,n),Math.max(e,n)+1)}gridRouteReplacementCollides(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=e.route[n.startIndex],i=e.route[n.endIndex],r=this.getTraceConnectionNames(e);for(let s=0;s\u003ct.points.length-1;s++){const a=Math.max(t.traceWidth,0===s?o.width:0,s===t.points.length-2?i.width:0);if(this.obstacleIndex.collides({start:t.points[s],end:t.points[s+1],layer:o.layer,width:a,connectionNames:r,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,n.startIndex-1),end:Math.min(e.route.length-1,n.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(a)}))return!0}return!1}gridRouteBoundaryCollides(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=this.getTraceConnectionNames(e),i=[{startIndex:n.startIndex-1,endIndex:n.startIndex},{startIndex:n.endIndex,endIndex:n.endIndex+1}];for(const n of i){const i=e.route[n.startIndex],r=e.route[n.endIndex];if(HJ(i)\u0026\u0026HJ(r)\u0026\u0026i.layer===r.layer\u0026\u0026this.obstacleIndex.collides({start:i,end:r,layer:i.layer,width:Math.max(i.width,r.width,t.traceWidth),connectionNames:o,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:n.startIndex,end:n.endIndex},obstacleClearance:this.getDesiredPadClearance(Math.max(i.width,r.width,t.traceWidth))}))return!0}return!1}canExpandSegmentAndEndpoints(t,e,n,o=this.nominalTraceWidth){const i=Math.max(0,e-1),r=Math.min(t.route.length-2,e+1);for(let s=i;s\u003c=r;s++){const a=t.route[s],c=t.route[s+1];if(!HJ(a)||!HJ(c)||a.layer!==c.layer)continue;const l=s\u003c=e+1\u0026\u0026s+1\u003e=e,d=Math.max(a.width,c.width,l?o:0);if(this.obstacleIndex.collides({start:a,end:c,layer:a.layer,width:d,connectionNames:n,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:i,end:r+1},obstacleClearance:this.getDesiredPadClearance(d)}))return!1}return!0}findMaximumSafeInPlaceWidth(t,e,n){const o=t.route[e],i=t.route[e+1];if(!HJ(o)||!HJ(i))return 0;const r=Math.min(o.width,i.width);if(this.probeInPlaceWidth(t,e,n,this.nominalTraceWidth))return this.nominalTraceWidth;let s=r,a=this.nominalTraceWidth;for(let o=0;o\u003c7;o++){const o=(s+a)/2;if(o\u003c=s+Mq)break;this.probeInPlaceWidth(t,e,n,o)?s=o:a=o}const c=this.nominalTraceWidth\u003e=.5?.025:.0125,l=Math.max(r,Math.floor((s+Mq)/c)*c);return l\u003er+Mq\u0026\u0026this.probeInPlaceWidth(t,e,n,l)?l:r}probeInPlaceWidth(t,e,n,o){return this.inPlaceWidthProbeCount++,this.canExpandSegmentAndEndpoints(t,e,n,o)}maximizeGridRouteWidth(t){if(t.traceWidth\u003e=this.nominalTraceWidth-Mq)return t;let e=t.traceWidth,n=this.nominalTraceWidth;for(let o=0;o\u003c7;o++){const o=(e+n)/2,i={...t,traceWidth:o};this.gridRouteReplacementCollides(i)||this.gridRouteBoundaryCollides(i)?n=o:e=o}const o=this.nominalTraceWidth\u003e=.5?.025:.0125,i=Math.max(t.traceWidth,Math.floor((e+Mq)/o)*o);if(i\u003et.traceWidth+Mq){const e={...t,traceWidth:i};if(!this.gridRouteReplacementCollides(e)\u0026\u0026!this.gridRouteBoundaryCollides(e))return this.pathWidthUpgradeCount++,e}return t}getExponentialIntervalCandidates(t,e,n){const o=this.getExponentialIndices(t,e,-1,n,5),i=this.getExponentialIndices(t,e,1,n,10).filter(t=\u003et\u003ee),r=[];for(const e of o)for(const n of i){const o=this.getRouteIntervalLength(t,e,n);o\u003e10.000001||r.push({startIndex:e,endIndex:n,routeLength:o})}return r.sort((t,e)=\u003et.routeLength-e.routeLength).filter((t,e,n)=\u003en.findIndex(e=\u003ee.startIndex===t.startIndex\u0026\u0026e.endIndex===t.endIndex)===e).slice(0,10).map(({startIndex:t,endIndex:e})=\u003e({startIndex:t,endIndex:e}))}getExponentialIndices(t,e,n,o,i){const r=[e];let s=0,a=Math.max(o,.3),c=e,l=e;for(;;){const e=c+n;if(e\u003c0||e\u003e=t.route.length)break;const o=t.route[c],d=t.route[e];if(!HJ(o)||!HJ(d)||o.layer!==d.layer)break;const h=Nq(o,d);if(s+h\u003ei+Mq)break;s+=h,c=e,l=e,s+Mq\u003e=a\u0026\u0026(r.push(e),a*=2)}return r.includes(l)||r.push(l),r}getRouteIntervalLength(t,e,n){let o=0;for(let i=e;i\u003cn;i++){const e=t.route[i],n=t.route[i+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)return Number.POSITIVE_INFINITY;o+=Nq(e,n)}return o}getCandidateWidths(t){const e=this.inputProblem.minTraceWidth;return WJ([t,.875*t,.75*t,.625*t,.5*t,.375*t,.25*t,e]).filter(t=\u003et\u003e=e-Mq)}getGridResolutions(t){return WJ([Math.max(.1,Math.min(.5,t/2)),Math.max(.1,Math.min(.25,t/3))])}resolveNominalTraceWidth(t){const e=this.findConnectionForTrace(t);return Math.max(e?.nominalTraceWidth??e?.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth,this.inputProblem.minTraceWidth)}getDesiredPadClearance(t=this.nominalTraceWidth){const e=Math.max(this.inputProblem.defaultObstacleMargin??0,this.inputProblem.minTraceToPadEdgeClearance??0,.1);return t\u003c.499999||\"cleanup\"!==this.phase?e:Math.max(e,this.options.powerTraceToPadClearance??t/2)}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=this.getTraceConnectionNames(t),o=this.inputProblem.connections.find(t=\u003ethis.connectionMatchesTrace(t,n))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getOwnedTraceIndices(){return[...this.selectedOwnedTraceIndices]}connectionMatchesTrace(t,e){return[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t)).some(t=\u003ee.includes(t))}getTraceConnectionNames(t){return[t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))}traceMeetsNominalWidth(t,e){return t.route.every(t=\u003e\"wire\"!==t.route_type||t.width\u003e=e-Mq)}findNextUnderWidthSegment(t,e,n){for(let o=e;o\u003ct.route.length-1;o++){const e=t.route[o],i=t.route[o+1];if(HJ(e)\u0026\u0026HJ(i)\u0026\u0026e.layer===i.layer\u0026\u0026(e.width\u003cn-Mq||i.width\u003cn-Mq))return o}return-1}getMutatedImmutableTraceIds(t){return this.immutableTraceIndices.flatMap(e=\u003e{const n=t[e];return JSON.stringify(n)===this.initialImmutableTraceSignatures.get(e)?[]:[n?.pcb_trace_id??this.traces[e]?.pcb_trace_id??String(e)]})}getImmutableViaViolationSignatures(t){const e=new Set;if(0===this.immutableTraceIndices.length)return e;const n=new Pq(this.inputProblem,t),o=new tJ(this.inputProblem,t,void 0,[],n);for(const n of this.immutableTraceIndices){const i=t[n];if(!i)continue;const r=[i.pcb_trace_id,i.connection_name,i.source_trace_id,i.rootConnectionName,...i.mergedConnectionNames??[],...i.connectsTo??[]].filter(t=\u003eBoolean(t));for(let t=0;t\u003ci.route.length;t++){const s=i.route[t];if(\"via\"!==s?.route_type)continue;const a=`${i.pcb_trace_id}:${t}`,c=o.getViaViolationSignatures({point:s,layers:o.boardLayers,padDiameter:s.via_diameter??this.inputProblem.min_via_pad_diameter??this.inputProblem.minViaPadDiameter??this.inputProblem.minViaDiameter??.6,holeDiameter:s.via_hole_diameter??o.defaultViaHoleDiameter,connectionNames:r,ignoreTraceIndex:n,ignoreRouteRange:{start:t,end:t},blockSameNetObstacles:!0,sameNetObstacleClearance:0});for(const t of c)e.add(`${a}|${t}`)}}return e}countViolatingImmutableVias(t){return new Set([...t].map(t=\u003et.split(\"|\")[0])).size}acceptConnectivityCheckpoint(t,e){this.connectivityValidationCount++;let n=!1,o=!1;try{const e=this.connectivityInvariant.validate(t),i=this.getMutatedImmutableTraceIds(t),r=this.getImmutableViaViolationSignatures(t),s=[...r].filter(t=\u003e!this.lastSafeImmutableViaViolationSignatures.has(t)),a=s.length\u003e0;if(n=!e.safe,o=i.length\u003e0||a,this.connectivityValidationError??=e.validationError??null,!n\u0026\u0026!o)return this.traces=structuredClone(t),this.lastConnectivitySafeTraces=structuredClone(t),this.remainingImmutableViaViolationCount=this.countViolatingImmutableVias(r),this.remainingImmutableViaViolationPairCount=r.size,this.lastSafeImmutableViaViolationSignatures=r,this.connectivityInvariant=new OJ(this.inputProblem,this.lastConnectivitySafeTraces),!0;this.immutableTraceMutationIds=[...new Set([...this.immutableTraceMutationIds,...i])],a\u0026\u0026(this.immutableViaViolationRollbackCount++,this.attemptedImmutableViaViolationCount=this.countViolatingImmutableVias(r),this.attemptedImmutableViaViolationPairCount=r.size,this.immutableViaViolationRegressionIds=[...new Set([...this.immutableViaViolationRegressionIds,...s])]),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...e.regressions.flatMap(t=\u003et.baselineEndpointLabels)])]}catch(t){n=!0,this.connectivityValidationError=t instanceof Error?t.message:String(t)}return n\u0026\u0026(this.connectivityRollbackCount++,this.connectivityRollbackPhases.includes(e)||this.connectivityRollbackPhases.push(e)),o\u0026\u0026(this.immutableSafetyRollbackCount++,this.immutableSafetyRollbackPhases.includes(e)||this.immutableSafetyRollbackPhases.push(e)),\"expansion\"===e?n?this.rollbackConnectivityRegressedExpansion():this.rollbackImmutableUnsafeExpansion():this.restoreLastConnectivitySafeTraces(),this.remainingImmutableViaViolationCount=this.countViolatingImmutableVias(this.lastSafeImmutableViaViolationSignatures),this.remainingImmutableViaViolationPairCount=this.lastSafeImmutableViaViolationSignatures.size,!1}rebuildObstacleIndex(){this.obstacleIndex=new tJ(this.inputProblem,this.traces,this.traceIndex,[],this.connectionNameResolver)}retainFailedSubSolver(t){this.failedSubSolverCount++,this.failedSubSolvers??=[],this.failedSubSolvers.length\u003c16?this.failedSubSolvers.push(t):this.failedSubSolvers[15]=t}tryFinalAcceptance(){this.finalAcceptanceUsed=!0;let t=!1;this.activeSubSolver instanceof jJ?(this.activeSubSolver.tryFinalAcceptance(),this.adoptCleanupOutput(this.activeSubSolver),t=!0):this.activeSubSolver instanceof YJ\u0026\u0026(this.activeSubSolver.tryFinalAcceptance(),this.adoptClearanceRepairOutput(this.activeSubSolver),t=!0),t||\"cleanup\"===this.phase||\"repair-trace-clearance\"===this.phase||\"complete\"===this.phase||this.discardInFlightExpansion(),this.activeSubSolver=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.activeInflationKey=null,this.activeInflationWidth=null,this.layerAttempt=null,this.acceptConnectivityCheckpoint(this.traces,\"final\"),this.traceIndex=this.traces.length,this.phase=\"complete\",this.rebuildObstacleIndex(),this.progress=1,this.solved=!0,this.stats=this.createStats()}createStats(){return{phase:this.phase,pass:this.passIndex+1,completedPassCount:this.completedPassCount,lastNormalizedWidthDeficitGain:this.lastNormalizedWidthDeficitGain,normalizedWidthDeficitGainByPass:[...this.normalizedWidthDeficitGainByPass],plateauReached:this.plateauReached,traceIndex:this.traceIndex,traceCount:this.traces.length,selectedTraceCount:this.traceOrder.length,routeSegmentIndex:this.routeSegmentIndex,nominalTraceWidth:this.nominalTraceWidth,intervalCursor:this.intervalCursor,intervalCount:this.currentIntervals.length,candidateWidth:this.candidateWidths[this.widthCursor],gridSize:this.gridResolutions[this.resolutionCursor],gridOffsetVariant:this.offsetCursor,keptTraceCount:this.keptTraceCount,recreatedTraceCount:this.recreatedTraceCount,expandedSegmentCount:this.expandedSegmentCount,intermediateExpandedSegmentCount:this.intermediateExpandedSegmentCount,pathWidthUpgradeCount:this.pathWidthUpgradeCount,inPlaceWidthProbeCount:this.inPlaceWidthProbeCount,reroutedSegmentCount:this.reroutedSegmentCount,unresolvedSegmentCount:this.unresolvedSegmentCount,attemptedGridCount:this.attemptedGridCount,attemptedLayerGridCount:this.attemptedLayerGridCount,attemptedInflationCount:this.attemptedInflationCount,activeInflationWidth:this.activeInflationWidth,pushedTraceCount:this.pushedTraceCount,elasticPushedTraceCount:this.elasticPushedTraceCount,layerReroutedTraceCount:this.layerReroutedTraceCount,insertedViaCount:this.insertedViaCount,neckedLayerSegmentCount:this.neckedLayerSegmentCount,removedViaPairCount:this.removedViaPairCount,removedViaCount:this.removedViaCount,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,cleanupClearanceShoveCount:this.cleanupClearanceShoveCount,relocatedViaCount:this.relocatedViaCount,unresolvedViaCount:this.unresolvedViaCount,initialImmutableViaViolationCount:this.initialImmutableViaViolationCount,remainingImmutableViaViolationCount:this.remainingImmutableViaViolationCount,initialImmutableViaViolationPairCount:this.initialImmutableViaViolationPairCount,remainingImmutableViaViolationPairCount:this.remainingImmutableViaViolationPairCount,skippedImmutableViaRepairCount:this.remainingImmutableViaViolationCount,immutableViaViolationRollbackCount:this.immutableViaViolationRollbackCount,attemptedImmutableViaViolationCount:this.attemptedImmutableViaViolationCount,attemptedImmutableViaViolationPairCount:this.attemptedImmutableViaViolationPairCount,immutableViaViolationRegressionIds:[...this.immutableViaViolationRegressionIds],immutableTraceMutationIds:[...this.immutableTraceMutationIds],padClearanceRerouteCount:this.padClearanceRerouteCount,unresolvedPadClearanceCount:this.unresolvedPadClearanceCount,repairedTraceClearanceSegmentCount:this.repairedTraceClearanceSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,unresolvedTraceClearanceSegmentCount:this.unresolvedTraceClearanceSegmentCount,sameNetContactRejectionCount:this.sameNetContactRejectionCount,connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRollbackPhases:[...this.connectivityRollbackPhases],immutableSafetyRollbackCount:this.immutableSafetyRollbackCount,immutableSafetyRollbackPhases:[...this.immutableSafetyRollbackPhases],connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},immutableSafetyRollbackMutationStats:null===this.immutableSafetyRollbackMutationStats?null:{...this.immutableSafetyRollbackMutationStats},expansionPushedTraceIndices:[...this.expansionPushedTraceIndices],cleanupMutatedTraceIndices:[...this.cleanupMutatedTraceIndices],discardedExpansionMutationStats:null===this.discardedExpansionMutationStats?null:{...this.discardedExpansionMutationStats},initialPadClearanceViolationCount:this.initialPadClearanceViolationCount,remainingPadClearanceViolationCount:this.remainingPadClearanceViolationCount,initialPadClearanceViolationCountByClearance:{...this.initialPadClearanceViolationCountByClearance},remainingPadClearanceViolationCountByClearance:{...this.remainingPadClearanceViolationCountByClearance},budgetLimitedExpansion:this.budgetLimitedExpansion,finalAcceptanceUsed:this.finalAcceptanceUsed,cleanupCompleted:this.cleanupCompleted,clearanceRepairCompleted:this.clearanceRepairCompleted,cleanupBestEffortAccepted:this.cleanupBestEffortAccepted,clearanceRepairBestEffortAccepted:this.clearanceRepairBestEffortAccepted,cleanupStatus:this.connectivityRollbackPhases.includes(\"cleanup\")?\"connectivity_rollback\":this.immutableSafetyRollbackPhases.includes(\"cleanup\")?\"immutable_safety_rollback\":this.cleanupBestEffortAccepted?\"budget_limited\":this.cleanupCompleted?\"completed\":\"cleanup\"===this.phase?\"in_progress\":\"not_started\",clearanceRepairStatus:this.connectivityRollbackPhases.includes(\"clearance-repair\")?\"connectivity_rollback\":this.immutableSafetyRollbackPhases.includes(\"clearance-repair\")?\"immutable_safety_rollback\":this.clearanceRepairBestEffortAccepted?\"budget_limited\":this.clearanceRepairCompleted?\"completed\":\"repair-trace-clearance\"===this.phase?\"in_progress\":\"not_started\",cleanupIterationBudget:this.cleanupIterationBudget,clearanceRepairIterationBudget:this.clearanceRepairIterationBudget,completionReason:\"complete\"===this.phase||this.solved?this.connectivityRollbackCount\u003e0?\"connectivity_rollback\":this.immutableSafetyRollbackCount\u003e0?\"immutable_safety_rollback\":this.connectivityValidationError?\"connectivity_validation_unavailable\":this.finalAcceptanceUsed?\"total_iteration_budget\":this.budgetLimitedExpansion?\"expansion_budget\":this.cleanupBestEffortAccepted?\"cleanup_budget\":this.clearanceRepairBestEffortAccepted?\"clearance_repair_budget\":this.remainingImmutableViaViolationCount\u003e0?\"immutable_via_violations_preserved\":\"completed\":null,resultStatus:this.finalAcceptanceUsed||this.budgetLimitedExpansion||this.cleanupBestEffortAccepted||this.clearanceRepairBestEffortAccepted||this.connectivityRollbackCount\u003e0||this.immutableSafetyRollbackCount\u003e0||null!==this.connectivityValidationError||this.remainingImmutableViaViolationCount\u003e0?\"best_effort\":\"complete\",failedSubSolverCount:this.failedSubSolverCount,retainedFailedSubSolverCount:this.failedSubSolvers?.length??0,expansionIterationBudget:this.getExpansionIterationBudget(),finalizationIterationReserve:this.getFinalizationIterationReserve(),spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){return this.solved||\"complete\"===this.phase?1:this.budgetLimitedExpansion?.99:0===this.traceOrder.length?1:Math.min(.99,(this.passIndex+Math.max(0,this.traceOrderCursor)/this.traceOrder.length)/this.maxPassCount)}getConstructorParams(){return[this.inputProblem,this.options]}getOutput(){return structuredClone(this.lastConnectivitySafeTraces)}visualize(){const t=[],e=[];for(let n=0;n\u003cthis.traces.length;n++){const o=this.traces[n],i=this.resolveNominalTraceWidth(o);for(const t of o.route)\"via\"===t.route_type\u0026\u0026e.push({center:t,radius:(t.via_diameter??.6)/2,fill:\"#d4a017\",stroke:\"#7a5700\"});for(let e=0;e\u003co.route.length-1;e++){const r=o.route[e],s=o.route[e+1];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)continue;const a=n===this.traceIndex\u0026\u0026e===this.routeSegmentIndex,c=r.width\u003e=i-Mq\u0026\u0026s.width\u003e=i-Mq,l=\"bottom\"===r.layer;t.push({points:[r,s],strokeColor:a?\"#ff8c00\":c?l?\"#2468c7\":\"#169c45\":l?\"#8b4bb8\":\"#cc3344\",strokeWidth:Math.max(r.width,s.width)})}}return{coordinateSystem:\"cartesian\",title:`Power trace expander: ${this.phase}`,lines:t,points:[],circles:e,rects:this.obstacleIndex.items.filter(t=\u003e\"obstacle\"===t.kind).slice(0,2e3).map(t=\u003e({center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,fill:\"rgba(80,80,80,0.12)\",stroke:\"rgba(80,80,80,0.35)\"})),texts:[]}}},UJ=class extends si{constructor(t,e={}){if(super(),this.inputSrj=t,this.options=e,this.powerTraceExpanderSolver=new GJ(t,e),0===e.onlyConnectionNames?.length)return this.MAX_ITERATIONS=1,this.progress=1,this.solved=!0,void(this.stats={selectedTraceCount:0,bypassed:!0});this.MAX_ITERATIONS=this.powerTraceExpanderSolver.MAX_ITERATIONS+1}inputSrj;options;powerTraceExpanderSolver;_step(){const t=this.powerTraceExpanderSolver;if(t.step(),this.progress=t.progress,this.stats=t.stats,t.failed)return this.error=t.error,void(this.failed=!0);t.solved\u0026\u0026(this.solved=!0)}getConstructorParams(){return[this.inputSrj,this.options]}getOutput(){if(!this.solved)throw new Error(\"Cannot get power trace expansion output before solving\");return this.powerTraceExpanderSolver.getOutput()}visualize(){return Ho({...this.inputSrj,traces:this.getOutput()},{traceColorMode:\"layer\"})}},ZJ=({connections:t,originalConnections:e,layerCount:n,obstacles:o,defaultViaHoleDiameter:i,connMap:r})=\u003e{const s=new Map;for(const t of e)s.has(t.name)||s.set(t.name,t.__netConnectionName);const a=t.map(t=\u003e{if(2!==t.pointsToConnect.length)throw new Error(`Expected Pipeline7 output connection \"${t.name}\" to have two points, got ${t.pointsToConnect.length}`);const[e,n]=t.pointsToConnect;return{connection:t,connectsTo:[e?.pointId,n?.pointId].filter(t=\u003eBoolean(t)),outputConnectionName:t.__netConnectionName??s.get(t.name)??t.__rootConnectionNames?.[0]??t.name}}),c=o.filter(t=\u003e(t.__zLayers?.length??t.layers?.length??0)\u003e1),l=new Map,d=t=\u003e{let e=l.get(t.connectionName);e||(e=new Map,l.set(t.connectionName,e));const n=e.get(t.rootConnectionName);if(n)return n;const o=c.filter(e=\u003efo(e,t,r));return e.set(t.rootConnectionName,o),o};return t=\u003e{const e=[],o=new Map;for(const e of t){const t=o.get(e.connectionName);t?t.push(e):o.set(e.connectionName,[e])}for(const{connection:t,connectsTo:s,outputConnectionName:c}of a){const a=o.get(t.name)??[];for(let o=0;o\u003ca.length;o+=1){const l=a[o];e.push({type:\"pcb_trace\",pcb_trace_id:`${t.name}_${o}`,connection_name:c,connectsTo:s,route:Mo(l,n,{connectionPoints:t.pointsToConnect,defaultViaHoleDiameter:i,connectedMultilayerObstacles:d(l),connMap:r})})}}return e}},qJ=({connections:t,originalConnections:e,hdRoutes:n,layerCount:o,obstacles:i,defaultViaHoleDiameter:r,connMap:s})=\u003eZJ({connections:t,originalConnections:e,layerCount:o,obstacles:i,defaultViaHoleDiameter:r,connMap:s})(n),JJ=t=\u003e{const e=Math.max(t.minTraceWidth+.1,2*t.minTraceWidth);return t.connections.flatMap(n=\u003e(n.nominalTraceWidth??t.nominalTraceWidth??t.minTraceWidth)+1e-6\u003e=e?[n.name]:[])},KJ=(t,e,n=new Map(t.map(t=\u003e[t.connectionName,t])))=\u003e{const o=new Map(e.map(t=\u003e[t.name,t]));return t.map(t=\u003e{if(0===t.route.length)throw new Error(`Cannot lock PCB terminals for empty route \"${t.connectionName}\"`);const e=o.get(t.connectionName);if(!e)throw new Error(`Cannot lock PCB terminals: connection \"${t.connectionName}\" was not found`);if(2!==e.pointsToConnect.length)throw new Error(`Cannot lock PCB terminals for \"${t.connectionName}\": expected 2 connection points, found ${e.pointsToConnect.length}`);const i=n.get(t.connectionName)??t,r=new Map;for(const n of e.pointsToConnect)if(n.pcb_port_id){if(r.has(n.pcb_port_id))throw new Error(`Cannot lock duplicate PCB terminal \"${n.pcb_port_id}\" for \"${t.connectionName}\"`);r.set(n.pcb_port_id,n)}if(0===r.size)return t;const s=[i.startPcbPortId,i.endPcbPortId].filter(t=\u003evoid 0!==t);if(0===s.length)return t;if(new Set(s).size!==s.length||s.some(t=\u003e!r.has(t)))throw new Error(`Cannot lock PCB terminals for \"${t.connectionName}\": route endpoint IDs do not match connection terminal IDs`);const a=i.startPcbPortId?r.get(i.startPcbPortId):void 0,c=i.endPcbPortId?r.get(i.endPcbPortId):void 0,l=t.route.map((e,n)=\u003e{if(0===n\u0026\u0026a)return{...e,x:a.x,y:a.y,pcb_port_id:a.pcb_port_id};if(n===t.route.length-1\u0026\u0026c)return{...e,x:c.x,y:c.y,pcb_port_id:c.pcb_port_id};const o={...e};return delete o.pcb_port_id,o});return{...t,route:l}})},QJ=({originalSrj:t,newlyRoutedTraces:e,currentPreloadedTraces:n,expandedConnectionNames:o,resolveConnectedTraceAliases:i=!1})=\u003e{const r=n??t.traces??[],s=i?tK({originalSrj:t,newlyRoutedTraces:e,preloadedTraces:r,expandedConnectionNames:o}):new Set(r.filter(t=\u003eo.includes(t.connection_name))),a=r.filter(t=\u003e!s.has(t)),c=new Set([...e.map(t=\u003et.pcb_trace_id),...a.map(t=\u003et.pcb_trace_id)]),l=r.filter(t=\u003es.has(t)).map(t=\u003e{const e=t.pcb_trace_id;let n=e,o=2;for(;c.has(n);)n=`${e}_power_expansion_${o++}`;return c.add(n),{...t,pcb_trace_id:n,__replaces_pcb_trace_id:t.__replaces_pcb_trace_id??t.pcb_trace_id}});return{...t,traces:[...e,...l],fixedTraces:a}},tK=({originalSrj:t,newlyRoutedTraces:e,preloadedTraces:n,expandedConnectionNames:o})=\u003e{const i=new Set(n.map(t=\u003et.pcb_trace_id)),r=new Set([...i,...e.map(t=\u003et.pcb_trace_id)]),s=e.map((t,e)=\u003e{if(!i.has(t.pcb_trace_id))return t;const n=`__pipeline7_new_trace_${e}_${t.pcb_trace_id}`;let o=n,s=2;for(;r.has(o);)o=`${n}_${s++}`;return r.add(o),{...t,pcb_trace_id:o}}),a=new Pq({...t,traces:[...s,...n]}),c=new Set(a.canonicalize([...o]));return new Set(n.filter(t=\u003ea.canonicalize([t.connection_name]).some(t=\u003ec.has(t))))};function eK(t){return new Set((t??[]).filter(t=\u003et._isComponentTopologyNode).map(t=\u003et.capacityMeshNodeId))}function nK(t,e){return t.nodeIds.some(t=\u003ee.has(t))}function oK({sharedEdgeSegments:t,componentCapacityMeshNodeIds:e}){return t.filter(t=\u003e!nK(t,e))}function iK(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var rK=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e;const n=fX(t);this.originalSrj=n,this.opts={...e};const o=this.opts;if(this.effort=o.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=o.maxNodeDimension??16,this.maxNodeRatio=o.maxNodeRatio??6,this.minNodeArea=o.minNodeArea??.1**2,this.visualizationTraceColorMode=o.visualizationTraceColorMode??\"layer\",this.setSimpleRouteJson(n),void 0===o.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,n=Math.max(t,e),i=o.targetMinCapacity??.5;o.capacityDepth=$s(n,i)}this.cacheProvider=void 0===o.cacheProvider?oo():null===o.cacheProvider?null:o.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;getSolverName(){return\"AutoroutingPipelineSolver7_MultiGraph\"}preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;componentTopologyGeneratorSolver;topologyPlanningSolver;topologyMergingSolver;globalTopologyGeneratorSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;exactGeometryDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;lengthMatchingPostProcessingSolver;powerTraceExpansionSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;componentDetectionSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;visualizationTraceColorMode;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;sharedEdgeSegmentsWithNecessaryCrampedPortPoints;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[iK(\"preprocessSimpleRouteJsonSolver\",_X,t=\u003e[t.originalSrj,{traceColorMode:t.visualizationTraceColorMode}],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),iK(\"componentDetectionSolver\",UZ,t=\u003e[{inputSrj:t.srj}]),iK(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),iK(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),iK(\"topologyPlanningSolver\",_q,t=\u003e[{inputSrj:t.srjWithPointPairs,componentDetectionOutput:t.componentDetectionSolver.getOutput(),viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.topologyPlanningSolver.getOutput();t.globalTopologyGeneratorSolver=t.topologyPlanningSolver.globalTopologySolver,t.componentTopologyGeneratorSolver=new vq(t.topologyPlanningSolver)}}),iK(\"topologyMergingSolver\",fq,t=\u003e{const e=t.topologyPlanningSolver.getOutput();return[{layerCount:t.srj.layerCount,nodeGroups:[{groupId:\"global\",nodes:e.globalMeshNodes,isComponent:!1},...e.componentMeshNodes.map((t,e)=\u003e({groupId:`component-${e}`,nodes:t,isComponent:!0}))]}]},{onSolved:t=\u003e{t.capacityNodes=t.topologyMergingSolver.getOutput()}}),iK(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver.outputNodes}}),iK(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),iK(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),iK(\"necessaryCrampedPortPointSolver\",sf,t=\u003e{const e=eK(t.capacityNodes);return[{capacityMeshNodes:t.capacityNodes.filter(t=\u003e!e.has(t.capacityMeshNodeId)),sharedEdgeSegments:oK({sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),componentCapacityMeshNodeIds:e}),simpleRouteJson:t.srjWithPointPairs}]},{onSolved:t=\u003e{const e=eK(t.capacityNodes);t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints=function({originalSharedEdgeSegments:t,filteredSharedEdgeSegments:e,componentCapacityMeshNodeIds:n}){const o=new Map(e.map(t=\u003e[t.edgeId,t]));return t.map(t=\u003enK(t,n)?t:o.get(t.edgeId)??t)}({originalSharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),filteredSharedEdgeSegments:t.necessaryCrampedPortPointSolver.getOutput(),componentCapacityMeshNodeIds:e})}}),iK(\"portPointPathingSolver\",jj,t=\u003e{const e=t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints??t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,preserveTerminalPcbPortIds:!0,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0,USE_SELECTIVE_RERIP_ROUTING:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),iK(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),iK(\"highDensityRouteSolver\",zs,t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length\u003e0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!0,growShrinkFallbackToInvalidGeometryOnFailure:!0,captureSearchDebug:!1}]}),iK(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),iK(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2,maxSampleEntries:80}]),iK(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,preserveTerminalPcbPortIds:!0}]),iK(\"traceSimplificationSolver\",vc,t=\u003e[{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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,enableCrossingViaReduction:!0,iterations:2}]),iK(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),iK(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:KJ(t.traceWidthSolver.getHdRoutesWithWidths(),t.netToPointPairsSolver?.newConnections??[],new Map((t.highDensityStitchSolver?.mergedHdRoutes??[]).map(t=\u003e[t.connectionName,t]))),connMap:t.connMap,effort:t.effort,maxIterations:16,enableLargeBoardBroadFallback:!1,enablePostSolveClearanceRelaxation:!1}]),iK(\"exactGeometryDrcForceImproveSolver\",wz,t=\u003e{const e=t.globalDrcForceImproveSolver.getOutput(),n=(t=\u003e{const e={...t.srjWithPointPairs,obstacles:t.originalSrj.obstacles,minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter??t.srjWithPointPairs.minViaDiameter},n=Math.max(Yo(t.originalSrj).padDiameter,e.minTraceWidth)+Math.max(.1,.1),o=new s_(e,{connMap:t.connMap,includeTraceViaOwnerMetadata:!0,traceClearance:.1,viaClearance:.1,spatialCellSize:n}),i=ZJ(t),r=t.originalSrj.traces??[];return({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline7 autorouting DRC evaluation requires HD routes\");const s=i(n),a=r.length?[...r,...s]:s;return o.evaluate(a)}})({connections:t.netToPointPairsSolver?.newConnections??[],originalConnections:t.originalSrj.connections,layerCount:t.srj.layerCount,obstacles:t.srj.obstacles,defaultViaHoleDiameter:t.viaHoleDiameter,connMap:t.connMap,srjWithPointPairs:t.srjWithPointPairs,originalSrj:t.originalSrj});return[{srj:t.srjWithPointPairs,hdRoutes:e,connMap:t.connMap,effort:t.effort,viaHoleDiameter:t.viaHoleDiameter,drcEvaluator:n,viaInPadDrcEvaluator:n,maxIterations:32,enableLargeBoardBroadFallback:!1,enableBroadFallback:!1,enableTargetedErrorSweep:!0,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:t.originalSrj.allowViaInPad??!1,viaInPadMaxIterations:32,broadMaxIterations:12,broadPassMultiplier:3}]}),iK(\"lengthMatchingPostProcessingSolver\",lU,t=\u003e{const e=t.netToPointPairsSolver;if(!e)throw new Error(\"Pipeline7: length-matching post-processing requires NetToPointPairsSolver output\");const n=e.newConnections,o=new Map;for(const e of t.srj.differentialPairs??[])for(const t of e.connectionNames){const e=n.filter(e=\u003ee.name===t||e.__rootConnectionNames?.includes(t)||e.__netConnectionName===t);if(1!==e.length)throw new Error(`Pipeline7: differential pair connection \"${t}\" must resolve to exactly one final point-pair connection, got ${e.length}`);o.set(t,e[0].name)}const i=t.exactGeometryDrcForceImproveSolver.getOutput(),r=(t.srj.differentialPairs??[]).map(t=\u003e{const e=t.connectionNames.map(t=\u003e{const e=o.get(t);if(!e)throw new Error(`Pipeline7: differential pair connection \"${t}\" is missing from final routed output`);return e});if(e[0]===e[1])throw new Error(`Pipeline7: differential pair ${t.connectionNames.join(\"/\")} resolves both members to \"${e[0]}\"`);if(void 0===t.traceGap)return{connectionNames:e,lengthTolerance:t.lengthTolerance,maxUncoupledLength:t.maxUncoupledLength};const n=e.map(t=\u003e{const e=i.filter(e=\u003ee.connectionName===t);if(1!==e.length)throw new Error(`Pipeline7: differential pair connection \"${t}\" must resolve to exactly one final HD route, got ${e.length}`);return e[0]}),r=t.traceGap+n.reduce((t,e)=\u003et+e.traceThickness/2,0);return{connectionNames:e,lengthTolerance:t.lengthTolerance,maxUncoupledLength:t.maxUncoupledLength,minimumCenterlineDistance:r,maximumCenterlineDistance:r}});return[{hdRoutes:i,differentialPairs:r,obstacles:t.srj.obstacles,bounds:t.srj.bounds,layerCount:t.srj.layerCount}]}),iK(\"powerTraceExpansionSolver\",UJ,t=\u003e{const e=t.opts.powerTraceExpansion??{},n=e.onlyConnectionNames??JJ(t.originalSrj);return[QJ({originalSrj:t.originalSrj,newlyRoutedTraces:t.getPrePowerTraceOutputSimplifiedPcbTraces(),expandedConnectionNames:n}),{allowNewVias:!1,...e,onlyConnectionNames:n}]})];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;computeProgress(){const t=this.activeSubSolver?.progress??0;return(this.currentPipelineStepIndex+t)/this.pipelineDef.length}_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\u0026\u0026(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),\"lengthMatchingPostProcessingSolver\"!==t.solverName\u0026\u0026\"powerTraceExpansionSolver\"!==t.solverName||(this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,this.iterations+this.activeSubSolver.MAX_ITERATIONS+1)),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\u0026\u0026this.activeSubSolver)return this.visualizeStage(this.activeSubSolver);const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.componentDetectionSolver?.visualize(),o=this.componentTopologyGeneratorSolver?.visualize(),i=this.globalTopologyGeneratorSolver?.visualize(),r=this.topologyMergingSolver?.visualize(),s=this.nodeDimensionSubdivisionSolver?.visualize(),a=this.nodeTargetMerger?.visualize(),c=this.singleLayerNodeMerger?.visualize(),l=this.strawSolver?.visualize(),d=this.edgeSolver?.visualize(),h=this.deadEndSolver?.visualize(),u=this.availableSegmentPointSolver?.visualize(),p=this.portPointPathingSolver?.visualize(),m=this.multiSectionPortPointOptimizer?.visualize(),g=this.uniformPortDistributionSolver?.visualize(),f=this.highDensityRouteSolver?.visualize(),y=this.highDensityForceImproveSolver?.visualize(),_=this.highDensityRepairSolver?.visualize(),b=this.highDensityStitchSolver?.visualize(),x=this.traceSimplificationSolver?.visualize(),v=this.lengthMatchingPostProcessingSolver?.visualize(),S=this.traceWidthSolver?.visualize(),I=this.necessaryCrampedPortPointSolver?.visualize(),C=(this.highDensityRouteSolver?.visualize(),this.originalSrj),P=C.outline,M=[];if(M.push({points:[{x:C.bounds?.minX??-50,y:C.bounds?.minY??-50},{x:C.bounds?.maxX??50,y:C.bounds?.minY??-50},{x:C.bounds?.maxX??50,y:C.bounds?.maxY??50},{x:C.bounds?.minX??-50,y:C.bounds?.maxY??50},{x:C.bounds?.minX??-50,y:C.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),P\u0026\u0026P.length\u003e=2){const t=P.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),M.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const N=Oo(C),w={points:[...C.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,C.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(C.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,C.layerCount),label:N(t)}))],lines:M},T={traceColorMode:this.visualizationTraceColorMode},R=Yj({srj:C,visualizationOptions:T}),E=pi(w,R),A=this.preprocessSimpleRouteJsonSolver?.visualize(),O=this.globalDrcForceImproveSolver?.visualize(),k=this.exactGeometryDrcForceImproveSolver?.visualize(),L=[E,A,n,o,t,e,i,r,s,a,c,l,d,h,u,I,p,m,g,f?pi(w,f):null,y,_,b,x,S,O,k,v,this.solved?pi({lines:M},Yj({srj:this.originalSrj,visualizationOptions:T}),this.visualizeFinalOutput()):null].filter(Boolean),D=pi(...L);return\"net\"===this.visualizationTraceColorMode?xq(D,this.colorMap):D}visualizeStage(t){const e=t.visualize();return\"net\"===this.visualizationTraceColorMode?xq(e,this.colorMap):e}visualizeFinalOutput(){const t=this.visualizationTraceColorMode,e=this.getOutputSimpleRouteJson();return Ho(e,{traceColorMode:t})}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.componentTopologyGeneratorSolver?this.componentTopologyGeneratorSolver.visualize():this.componentDetectionSolver?this.componentDetectionSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){if(this.lengthMatchingPostProcessingSolver){const{hdRoutes:t}=this.lengthMatchingPostProcessingSolver.getOutput();return t}return this.exactGeometryDrcForceImproveSolver?.getOutput()??this.globalDrcForceImproveSolver?.getOutput()??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\");return this.powerTraceExpansionSolver?this.powerTraceExpansionSolver.getOutput():this.getPrePowerTraceOutputSimplifiedPcbTraces()}getPrePowerTraceOutputSimplifiedPcbTraces(){return qJ({connections:this.netToPointPairsSolver?.newConnections??[],originalConnections:this.originalSrj.connections,hdRoutes:this._getOutputHdRoutes(),layerCount:this.srj.layerCount,obstacles:this.srj.obstacles,defaultViaHoleDiameter:this.viaHoleDiameter,connMap:this.connMap})}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},sK=t=\u003e[...new Set(t)].sort((t,e)=\u003et-e),aK=class extends si{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1}params;outputNodes=[];outputSharedEdgeSegments=[];nodeIdByOriginalAndZ=new Map;getSolverName(){return\"SplitNodesIntoSingleLayerNodeSolver\"}_step(){this.outputNodes=this.params.capacityMeshNodes.flatMap(t=\u003esK(t.availableZ).map(e=\u003e{const n=((t,e)=\u003e`${t}__z${e}`)(t.capacityMeshNodeId,e);return this.nodeIdByOriginalAndZ.set(`${t.capacityMeshNodeId}:${e}`,n),{...t,capacityMeshNodeId:n,layer:`z${e}`,availableZ:[e],_parent:t}})),this.outputSharedEdgeSegments=this.params.sharedEdgeSegments.flatMap(t=\u003ethis.splitSharedEdgeSegment(t)),this.stats={inputNodeCount:this.params.capacityMeshNodes.length,outputNodeCount:this.outputNodes.length,inputPortPointCount:this.params.sharedEdgeSegments.reduce((t,e)=\u003et+e.portPoints.length,0),outputPortPointCount:this.outputSharedEdgeSegments.reduce((t,e)=\u003et+e.portPoints.length,0)},this.solved=!0}getSplitNodeId(t,e){return this.nodeIdByOriginalAndZ.get(`${t}:${e}`)}splitPortPoint(t){return sK(t.availableZ).flatMap(e=\u003e{const n=t.nodeIds.map(t=\u003ethis.getSplitNodeId(t,e));return n[0]\u0026\u0026n[1]?[{...t,segmentPortPointId:`${t.segmentPortPointId}__z${e}`,availableZ:[e],nodeIds:[n[0],n[1]]}]:[]})}splitSharedEdgeSegment(t){const e=new Map;for(const n of t.portPoints.flatMap(t=\u003ethis.splitPortPoint(t))){const t=n.availableZ[0];if(void 0===t)continue;const o=e.get(t)??[];o.push(n),e.set(t,o)}return[...e.entries()].map(([e,n])=\u003e({...t,edgeId:`${t.edgeId}__z${e}`,nodeIds:n[0].nodeIds,availableZ:[e],portPoints:n}))}getOutput(){return{capacityMeshNodes:this.outputNodes,sharedEdgeSegments:this.outputSharedEdgeSegments}}getConstructorParams(){return[this.params]}visualize(){return{rects:this.outputNodes.map(t=\u003e({...Dc(t),label:`${t.capacityMeshNodeId}\\n${t.layer}`})),points:this.outputSharedEdgeSegments.flatMap(t=\u003et.portPoints.map(t=\u003e({x:t.x,y:t.y,label:`${t.segmentPortPointId}\\nz${t.availableZ.join(\",\")}`})))}}};function cK(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var lK=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;nodeSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityForceImproveRoutes;highDensityRepairSolver;highDensityRepairRoutes;highDensityStitchSolver;globalDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;splitNodesIntoSingleLayerNodeSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[cK(\"preprocessSimpleRouteJsonSolver\",_X,t=\u003e[t.originalSrj],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),cK(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),cK(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),cK(\"nodeSolver\",Kn,t=\u003e[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=\u003e{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),cK(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver?.outputNodes??[]}}),cK(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),cK(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),cK(\"necessaryCrampedPortPointSolver\",sf,t=\u003e[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),cK(\"splitNodesIntoSingleLayerNodeSolver\",aK,t=\u003e[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput()}],{onSolved:t=\u003e{t.capacityNodes=t.splitNodesIntoSingleLayerNodeSolver.getOutput().capacityMeshNodes}}),cK(\"portPointPathingSolver\",jj,t=\u003e{const e=t.splitNodesIntoSingleLayerNodeSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:e.capacityMeshNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.sharedEdgeSegments.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections,assignableViaObstacles:t.originalSrj.obstacles});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),cK(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),cK(\"highDensityRouteSolver\",zs,t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length\u003e0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]}),cK(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.getHighDensityNodePortPointsWithAssignableViasFirst(),hdRoutes:t.getMovableHighDensityRoutes(t.highDensityRouteSolver.routes),colorMap:t.colorMap,totalStepsPerNode:Math.max(20,Math.round(60*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}],{onSolved:t=\u003e{t.highDensityForceImproveRoutes=t.mergeMovableHighDensityRoutesBack(t.highDensityRouteSolver.routes,t.highDensityForceImproveSolver.getOutput())}}),cK(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.getHighDensityNodePortPointsWithAssignableViasFirst(),hdRoutes:t.getMovableHighDensityRoutes(t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes),obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2}],{onSolved:t=\u003e{const e=t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes;t.highDensityRepairRoutes=t.mergeMovableHighDensityRoutesBack(e,t.highDensityRepairSolver.getOutput())}}),cK(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairRoutes??t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,allowedLayerTransitionPointKeys:uf(t.originalSrj.obstacles)}]),cK(\"traceSimplificationSolver\",vc,t=\u003e[{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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,iterations:2}]),cK(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),cK(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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\u0026\u0026(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\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.nodeSolver?.visualize(),o=this.nodeDimensionSubdivisionSolver?.visualize(),i=this.nodeTargetMerger?.visualize(),r=this.singleLayerNodeMerger?.visualize(),s=this.strawSolver?.visualize(),a=this.edgeSolver?.visualize(),c=this.deadEndSolver?.visualize(),l=this.availableSegmentPointSolver?.visualize(),d=this.splitNodesIntoSingleLayerNodeSolver?.visualize(),h=this.portPointPathingSolver?.visualize(),u=this.multiSectionPortPointOptimizer?.visualize(),p=this.uniformPortDistributionSolver?.visualize(),m=this.highDensityRouteSolver?.visualize(),g=this.highDensityForceImproveSolver?.visualize(),f=this.highDensityRepairSolver?.visualize(),y=this.highDensityStitchSolver?.visualize(),_=this.traceSimplificationSolver?.visualize(),b=this.necessaryCrampedPortPointSolver?.visualize(),x=(this.highDensityRouteSolver?.visualize(),this.originalSrj),v=x.outline,S=[];if(S.push({points:[{x:x.bounds?.minX??-50,y:x.bounds?.minY??-50},{x:x.bounds?.maxX??50,y:x.bounds?.minY??-50},{x:x.bounds?.maxX??50,y:x.bounds?.maxY??50},{x:x.bounds?.minX??-50,y:x.bounds?.maxY??50},{x:x.bounds?.minX??-50,y:x.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),v\u0026\u0026v.length\u003e=2){const t=v.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),S.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const I=Oo(x),C={points:[...x.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,x.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(x.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,x.layerCount),label:I(t)}))],lines:S},P=Yj({srj:x}),M=[pi(C,P),t,e,n,o,i,r,s,a,c,l,b,d,h,u,p,m?pi(C,m):null,g,f,y,_,this.solved?pi({lines:S},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...M)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){const t=this.globalDrcForceImproveSolver?.getOutput();return t\u0026\u0026this.routesOnlyUsePreplacedVias(t)?t:this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityRepairRoutes??this.highDensityForceImproveRoutes??this.highDensityStitchSolver.mergedHdRoutes}routesOnlyUsePreplacedVias(t){const e=uf(this.originalSrj.obstacles);return 0===e.size||t.every(t=\u003et.vias.every(t=\u003ee.has(af(t))))}getHighDensityNodePortPointsWithAssignableViasFirst(){return[...this.highDensityNodePortPoints??[]].sort((t,e)=\u003e{const n=t.capacityMeshNodeId.startsWith(\"assignable-via:\");return n===e.capacityMeshNodeId.startsWith(\"assignable-via:\")?0:n?-1:1})}getPreplacedAssignableViaObstacles(){return this.originalSrj.obstacles.filter(t=\u003e!0===t.netIsAssignable\u0026\u0026(t.layers?.length??0)\u003e1)}isFixedPreplacedViaRoute(t){const e=this.getPreplacedAssignableViaObstacles();return 0!==e.length\u0026\u00260!==t.vias.length\u0026\u0026e.some(e=\u003e[...t.route,...t.vias].every(t=\u003eBe(t,e)\u003c=0))}getMovableHighDensityRouteIndexes(t){return t.map((t,e)=\u003ethis.isFixedPreplacedViaRoute(t)?-1:e).filter(t=\u003e-1!==t)}getMovableHighDensityRoutes(t){return this.getMovableHighDensityRouteIndexes(t).map(e=\u003et[e])}mergeMovableHighDensityRoutesBack(t,e){const n=this.getMovableHighDensityRouteIndexes(t),o=[...t];for(let t=0;t\u003cn.length;t++)o[n[t]]=e[t];return o}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 o=n.__netConnectionName??this.originalSrj.connections.find(t=\u003et.name===n.name)?.__netConnectionName,i=e.filter(t=\u003et.connectionName===n.name);for(let e=0;e\u003ci.length;e++){const r=i[e],s={type:\"pcb_trace\",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.srj.obstacles,connMap:this.connMap})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},dK=(t,e)=\u003e{const n=t.filter(t=\u003e(t.rootConnectionName??t.connectionName)===e);if(0!==n.length)return n.reduce((t,e)=\u003et+e.route.slice(1).reduce((t,n,o)=\u003e{const i=e.route[o];return t+Math.hypot(n.x-i.x,n.y-i.y)},0),0)},hK=(t,e)=\u003e{const n=new Set(t.flatMap(t=\u003evoid 0===t.maxLengthSkew?[]:t.connectionNames));return e.flatMap(t=\u003e{if(!n.has(t.name))return[];const e=t.pointsToConnect[0],o=t.pointsToConnect.at(-1);if(!e||!o||e===o)throw new Error(`Length matching: bus connection \"${t.name}\" needs at least two points`);return[{...t,pointsToConnect:[e,o]}]})},uK=class extends si{constructor(t){super(),this.params=t,this.differentialPairSolver=new lU({hdRoutes:t.hdRoutes,differentialPairs:t.differentialPairs,obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,minTraceToPadEdgeClearance:t.obstacleMargin}),this.MAX_ITERATIONS=this.differentialPairSolver.MAX_ITERATIONS+1e5+10}params;differentialPairSolver;busLengthMatchingSolver;outputHdRoutes;getSolverName(){return\"LengthMatchingPostProcessingSolver\"}_step(){if(!this.differentialPairSolver.solved)return this.differentialPairSolver.step(),void(this.differentialPairSolver.failed\u0026\u0026(this.failed=!0,this.error=this.differentialPairSolver.error));if(!this.busLengthMatchingSolver){const n=this.differentialPairSolver.getOutput().hdRoutes,o=(t=this.params.buses,e=n,t.flatMap(t=\u003e{const n=t.maxLengthSkew;if(void 0===n||t.connectionNames.length\u003c2)return[];const o=t.connectionNames.map(n=\u003e{const o=dK(e,n);if(void 0===o)throw new Error(`Length matching: bus \"${t.busId}\" has no routed geometry for connection \"${n}\"`);return{connectionName:n,length:o}}),i=o.reduce((t,e)=\u003ee.length\u003et.length?e:t);return o.flatMap(t=\u003et.connectionName===i.connectionName?[]:[{connectionNames:[t.connectionName,i.connectionName],lengthTolerance:n}])}));return 0===o.length?(this.outputHdRoutes=n,void(this.solved=!0)):void(this.busLengthMatchingSolver=new RG({hdRoutes:n,originalConnections:hK(this.params.buses,this.params.connections),differentialPairs:o,obstacles:this.params.obstacles,bounds:this.params.bounds,layerCount:this.params.layerCount,obstacleMargin:this.params.obstacleMargin}))}var t,e;if(this.busLengthMatchingSolver.step(),this.busLengthMatchingSolver.failed)return this.failed=!0,void(this.error=this.busLengthMatchingSolver.error);this.busLengthMatchingSolver.solved\u0026\u0026(this.outputHdRoutes=this.busLengthMatchingSolver.getOutput().matchedHdRoutes,((t,e)=\u003e{for(const n of t){if(void 0===n.maxLengthSkew||n.connectionNames.length\u003c2)continue;const t=n.connectionNames.map(t=\u003e{const o=dK(e,t);if(void 0===o)throw new Error(`Length matching: bus \"${n.busId}\" lost routed geometry for connection \"${t}\"`);return o}),o=Math.max(...t)-Math.min(...t);if(o\u003en.maxLengthSkew+1e-6)throw new Error(`Length matching: bus \"${n.busId}\" routed length skew ${o.toFixed(4)}mm exceeds ${n.maxLengthSkew.toFixed(4)}mm`)}})(this.params.buses,this.outputHdRoutes),this.solved=!0)}getOutput(){if(!this.solved||!this.outputHdRoutes)throw new Error(\"LengthMatchingPostProcessingSolver output requested before completion\");return{hdRoutes:this.outputHdRoutes}}visualize(){return this.busLengthMatchingSolver?.visualize()??this.differentialPairSolver.visualize()}},pK=1e-9,mK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=pK\u0026\u0026Math.abs(t.y-e.y)\u003c=pK\u0026\u0026t.z===e.z,gK=(t,e)=\u003e{if(0===t.length)return void t.push(...e.route);const n=t.at(-1);if(e.route[0]\u0026\u0026mK(n,e.route[0]))t.push(...e.route.slice(1));else{if(!e.route.at(-1)||!mK(n,e.route.at(-1)))throw new Error(`Pipeline9 could not reconnect mutated preloaded segment \"${e.connectionName}\"`);t.push(...e.route.slice(0,-1).reverse())}},fK=(t,e)=\u003e{const n=t.preloadedRoutePositionStart??t.preloadedRouteIndex,o=e.preloadedRoutePositionStart??e.preloadedRouteIndex,i=t.preloadedRoutePositionEnd??n,r=e.preloadedRoutePositionEnd??o;return n-o||i-r||t.preloadedRouteIndex-e.preloadedRouteIndex||t.connectionName.localeCompare(e.connectionName)},yK=t=\u003e{const e=t.route.flatMap(t=\u003e\"wire\"===t.route_type||\"through_obstacle\"===t.route_type?[t.width]:[]);return e.length\u003e0?Math.max(...e):void 0},_K=({trace:t,updatedTraceRoutes:e,layerCount:n,defaultViaHoleDiameter:o,obstacles:i,connMap:r})=\u003e{if(0===e.length)throw new Error(`Pipeline9 lost every fixed route for mutated trace \"${t.pcb_trace_id}\"`);const s=[];let a,c=0,l=0;for(const t of[...e].sort(fK))gK(s,t),c=Math.max(c,t.traceThickness),l=Math.max(l,t.viaDiameter),a??=t.rootConnectionName;const d={connectionName:t.connection_name,rootConnectionName:a,traceThickness:yK(t)??c,viaDiameter:l,route:s,vias:s.slice(0,-1).flatMap((t,e)=\u003e{const n=s[e+1];return t.z!==n.z\u0026\u0026Math.abs(t.x-n.x)\u003c=pK\u0026\u0026Math.abs(t.y-n.y)\u003c=pK?[{x:n.x,y:n.y}]:[]})};return Mo(d,n,{defaultViaHoleDiameter:o,obstacles:i,connMap:r})},bK=(t,e)=\u003et.filter(t=\u003e{if(!0===t.isThroughObstacle)return!1;const n=t.preloadedRoutePositionStart,o=t.preloadedRoutePositionEnd;if(void 0===n||void 0===o)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" is missing route-position metadata`);const i=Math.min(n,o),r=Math.max(n,o);return i\u003e=e.routePositionStart-pK\u0026\u0026r\u003c=e.routePositionEnd+pK}),xK=({trace:t,originalTraceRoutes:e,updatedTraceRoutes:n,layerCount:o,defaultViaHoleDiameter:i,obstacles:r,connMap:s})=\u003e{if(0===n.length)throw new Error(`Pipeline9 lost every fixed route for mutated trace \"${t.pcb_trace_id}\"`);const a=(t=\u003e{const e=[];let n=0;for(let o=0;o\u003ct.route.length;o++)\"through_obstacle\"===t.route[o]?.route_type\u0026\u0026(n\u003co\u0026\u0026e.push({routePositionStart:n,routePositionEnd:o-1}),n=o+1);return n\u003ct.route.length\u0026\u0026e.push({routePositionStart:n,routePositionEnd:t.route.length-1}),e})(t),c=n.filter(t=\u003e!0!==t.isThroughObstacle);for(const t of c){if(1!==a.filter(e=\u003ebK([t],e).includes(t)).length)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" crosses an immutable through-obstacle primitive`)}const l=[];let d=0;for(const c of a){l.push(...t.route.slice(d,c.routePositionStart));const a=bK(e,c),h=bK(n,c);if(a.length\u003e0\u0026\u00260===h.length)throw new Error(`Pipeline9 lost every fixed route for an ordinary section of mutated trace \"${t.pcb_trace_id}\"`);l.push(...h.length\u003e0?_K({trace:t,updatedTraceRoutes:h,layerCount:o,defaultViaHoleDiameter:i,obstacles:r,connMap:s}):t.route.slice(c.routePositionStart,c.routePositionEnd+1)),d=c.routePositionEnd+1}return l.push(...t.route.slice(d)),l},vK=(t,e)=\u003e{const n=new Set(e.map(t=\u003et.pcb_trace_id));return t.map(t=\u003e{if(!n.has(t.pcb_trace_id))return n.add(t.pcb_trace_id),t;const e=`${t.pcb_trace_id}_routed`;let o=e,i=2;for(;n.has(o);)o=`${e}_${i}`,i+=1;return n.add(o),{...t,pcb_trace_id:o}})},SK=(t,e,n)=\u003e{const o=t=\u003e`${t.x}:${t.y}`,i=new Map;for(const t of e){const e=o(t.center),n=i.get(e)??[];n.push(t),i.set(e,n)}const r=new Map;for(const e of t)for(const t of e.pointsToConnect){if(!t.pcb_port_id)continue;const e=r.get(t.pcb_port_id)??new Set,s=\"layers\"in t?t.layers:[t.layer];for(const t of s)e.add(ko(t,n));for(const r of i.get(o(t))??[])if(!(r.layers.length\u003c=1)\u0026\u0026r.connectedTo.includes(t.pcb_port_id))for(const t of r.layers)e.add(ko(t,n));r.set(t.pcb_port_id,e)}return r},IK=(t,e)=\u003enew Map(t.flatMap(t=\u003e{const n=e.getNetConnectedToId(t.connectionName)??(t.rootConnectionName?e.getNetConnectedToId(t.rootConnectionName)??(e.netMap[t.rootConnectionName]?t.rootConnectionName:void 0):void 0);return n?[[t.connectionName,n]]:[]})),CK=1e-9,PK=1e-6,MK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=PK\u0026\u0026Math.abs(t.y-e.y)\u003c=PK\u0026\u0026t.z===e.z,NK=t=\u003enew Map(t.map((t,e)=\u003e[t.pcb_trace_id,e])),wK=(t,e)=\u003e{const n=t[0],o=t.at(-1);if(!n||!o)throw new Error(\"Pipeline9 cannot split an empty preloaded route\");if(n.z!==o.z)throw new Error(\"Pipeline9 cannot partially split a preloaded layer transition\");return{...n,x:n.x+(o.x-n.x)*e,y:n.y+(o.y-n.y)*e}},TK=({traces:t,fixedHdRoutes:e,sections:n})=\u003e{const o=(({traces:t,sections:e})=\u003e{const n=NK(t),o=new Map;for(const t of e){const e=n.get(t.traceId);if(void 0===e)throw new Error(`Pipeline9 hypergraph changed missing preloaded trace \"${t.traceId}\"`);const i=o.get(e)??[];i.push({start:Math.min(t.startRoutePosition,t.endRoutePosition),end:Math.max(t.startRoutePosition,t.endRoutePosition)}),o.set(e,i)}for(const t of o.values())t.sort((t,e)=\u003et.start-e.start||t.end-e.end);return o})({traces:t,sections:n});return e.flatMap(t=\u003e{const e=o.get(t.preloadedTraceIndex);if(!e?.length)return[t];const n=t.preloadedRoutePositionStart,i=t.preloadedRoutePositionEnd;if(void 0===n||void 0===i)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" is missing route-position metadata`);if(Math.abs(i-n)\u003c=CK)return e.some(t=\u003et.start-CK\u003c=n\u0026\u0026n\u003c=t.end+CK)?[]:[t];let r=[{start:n,end:i}];for(const t of e)r=r.flatMap(e=\u003e{if(t.end\u003c=e.start+CK||t.start\u003e=e.end-CK)return[e];const n=[];return t.start\u003ee.start+CK\u0026\u0026n.push({start:e.start,end:Math.min(t.start,e.end)}),t.end\u003ce.end-CK\u0026\u0026n.push({start:Math.max(t.end,e.start),end:e.end}),n});return r.map((e,o)=\u003e{const r=(e.start-n)/(i-n),s=(e.end-n)/(i-n);return{...t,connectionName:`${t.connectionName}_hypergraph_fixed_${o}`,preloadedRoutePositionStart:e.start,preloadedRoutePositionEnd:e.end,route:[wK(t.route,r),wK(t.route,s)],vias:[]}})})},RK=({traces:t,sections:e,stitchedHdRoutes:n,layerCount:o})=\u003e{const i=NK(t);return e.map((t,r)=\u003e{const s=i.get(t.traceId);if(void 0===s)throw new Error(`Pipeline9 cannot materialize missing preloaded trace \"${t.traceId}\"`);const[a,c]=((t,e)=\u003e{const n=t.connection.pointsToConnect.map(t=\u003e({x:t.x,y:t.y,z:ko(bo(t),e)}));if(!n[0]||!n[1])throw new Error(`Pipeline9 changed section \"${t.connectionName}\" is missing an endpoint`);return[n[0],n[1]]})(t,o),l=n.flatMap(e=\u003e{if(e.connectionName!==t.connectionName)return[];const n=(({route:t,sectionStart:e,sectionEnd:n})=\u003e{const o=t.route[0],i=t.route.at(-1);if(!o||!i)return null;const r=o.z===e.z\u0026\u0026i.z===n.z,s=o.z===n.z\u0026\u0026i.z===e.z,a=r?xe(o,e)+xe(i,n):Number.POSITIVE_INFINITY,c=s?xe(o,n)+xe(i,e):Number.POSITIVE_INFINITY;return Number.isFinite(a)||Number.isFinite(c)?a\u003c=c?{score:a,reverse:!1}:{score:c,reverse:!0}:null})({route:e,sectionStart:a,sectionEnd:c});return n?[{route:e,...n}]:[]});l.sort((t,e)=\u003et.score-e.score);const d=l[0],h=l[1];if(!d||h\u0026\u0026Math.abs(h.score-d.score)\u003c=PK)throw new Error(`Pipeline9 expected one nearest stitched route for changed preloaded section \"${t.connectionName}\", got ${l.length}`);const u=(({route:t,reverse:e,sectionStart:n,sectionEnd:o})=\u003e{const i=e?(t=\u003e{const e=[...t].reverse().map(t=\u003e{const{toNextSegmentType:e,...n}=t;return n});for(let n=0;n\u003ct.length-1;n++){const o=t[n]?.toNextSegmentType;o\u0026\u0026(e[t.length-n-2]={...e[t.length-n-2],toNextSegmentType:o})}return e})(t.route):[...t.route];if(!i[0]||!i.at(-1))throw new Error(`Pipeline9 cannot materialize empty route \"${t.connectionName}\"`);return MK(i[0],n)||i.unshift(n),MK(i.at(-1),o)||i.push(o),{...t,route:i}})({route:d.route,reverse:d.reverse,sectionStart:a,sectionEnd:c});return{...u,preloadedTraceIndex:s,preloadedRouteIndex:Number.MAX_SAFE_INTEGER-e.length+r,preloadedRoutePositionStart:t.startRoutePosition,preloadedRoutePositionEnd:t.endRoutePosition,isThroughObstacle:!1}})},EK=1e-6,AK=t=\u003et.map(t=\u003e{const e=[];for(const n of t.route){const o=e.at(-1);if(!o||o.z===n.z||\"through_obstacle\"===o.toNextSegmentType){e.push(n);continue}const i=Math.abs(o.x-n.x)\u003c=EK\u0026\u0026Math.abs(o.y-n.y)\u003c=EK,r=t.vias.some(t=\u003eMath.abs(t.x-o.x)\u003c=EK\u0026\u0026Math.abs(t.y-o.y)\u003c=EK),s=t.vias.some(t=\u003eMath.abs(t.x-n.x)\u003c=EK\u0026\u0026Math.abs(t.y-n.y)\u003c=EK);if(i)e.push(n);else{if(!r\u0026\u0026!s)throw new Error(`Pipeline9 route \"${t.connectionName}\" changes layers from z=${o.z} to z=${n.z} without an explicit via`);if(r===s)throw new Error(`Pipeline9 route \"${t.connectionName}\" has an ambiguous layer transition between (${o.x}, ${o.y}) and (${n.x}, ${n.y})`);r?e.push({x:o.x,y:o.y,z:n.z}):e.push({x:n.x,y:n.y,z:o.z}),e.push(n)}}return{...t,route:e}}),OK=1e-9,kK=t=\u003e({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}),LK=(t,e)=\u003et.x\u003e=e.minX-OK\u0026\u0026t.x\u003c=e.maxX+OK\u0026\u0026t.y\u003e=e.minY-OK\u0026\u0026t.y\u003c=e.maxY+OK,DK=(t,e,n)=\u003en\u003c=OK?t:n\u003e=.999999999?e:{x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n,z:t.z},zK=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;if(Math.abs(o)\u003c=OK\u0026\u0026Math.abs(i)\u003c=OK)return LK(t,n)\u0026\u0026LK(e,n)?{start:t,end:e}:null;let r=0,s=1;const a=[[-o,t.x-n.minX],[o,n.maxX-t.x],[-i,t.y-n.minY],[i,n.maxY-t.y]];for(const[t,e]of a){if(Math.abs(t)\u003c=OK){if(e\u003c0)return null;continue}const n=e/t;if(t\u003c0?r=Math.max(r,n):s=Math.min(s,n),r\u003es+OK)return null}return{start:DK(t,e,r),end:DK(t,e,s)}},FK=t=\u003e{const e=t.sourceRoutes[0],n=`pipeline9_fallback:${e.connectionName}`,o=`${n}:start`,i=`${n}:end`;return[{...t.start.point,portPointId:o,nextPortPointId:i,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName},{...t.end.point,portPointId:i,prevPortPointId:o,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName}]},BK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=OK\u0026\u0026Math.abs(t.y-e.y)\u003c=OK\u0026\u0026t.z===e.z,jK=(t,e)=\u003et.sourceRoute.preloadedTraceIndex===e.sourceRoute.preloadedTraceIndex\u0026\u0026BK(t.sourceRoute.route.at(-1),e.sourceRoute.route[0]),$K=(t,e,n=new Set)=\u003e{const o=new Map,i=[],r=new Set(t.portPoints.map(t=\u003et.z)),s=e.map(e=\u003e((t,e)=\u003e{const n=kK(e);let o,i;for(let e=0;e\u003ct.route.length-1;e++){const r=zK(t.route[e],t.route[e+1],n);r\u0026\u0026(o??={segmentIndex:e,point:r.start},i={segmentIndex:e,point:r.end})}return o\u0026\u0026i?Math.abs(o.point.x-i.point.x)\u003c=OK\u0026\u0026Math.abs(o.point.y-i.point.y)\u003c=OK\u0026\u0026o.point.z===i.point.z?null:{sourceRoute:t,start:o,end:i}:null})(e,t)).filter(t=\u003enull!==t),a=s.filter(t=\u003e!0!==t.sourceRoute.isThroughObstacle\u0026\u0026(((t,e)=\u003e0===e.size||[t.start.point,...t.sourceRoute.route.slice(t.start.segmentIndex+1,t.end.segmentIndex+1),t.end.point].some(t=\u003ee.has(t.z)))(t,r)||n.has(t.sourceRoute.connectionName))).sort((t,e)=\u003et.sourceRoute.preloadedTraceIndex-e.sourceRoute.preloadedTraceIndex||t.sourceRoute.preloadedRouteIndex-e.sourceRoute.preloadedRouteIndex),c=new Set(a.map(t=\u003et.sourceRoute)),l=s.map(t=\u003et.sourceRoute).filter(t=\u003e!c.has(t)),d=[];for(let t=0;t\u003ca.length;t++){const e=a[t],n=a[t-1],o=d.at(-1);n\u0026\u0026o\u0026\u0026jK(n,e)?(o.sourceRoutes.push(e.sourceRoute),o.end=e.end):d.push({sourceRoutes:[e.sourceRoute],start:e.start,end:e.end})}for(const t of d){const e=t.sourceRoutes[0].connectionName;if(o.has(e))throw new Error(`Pipeline9 regional fallback found duplicate fixed route section identity \"${e}\"`);o.set(e,t),i.push(FK(t))}return{nodeWithPortPoints:{...t,portPoints:[...t.portPoints,...i.flatMap(t=\u003et)],portPointsInPairs:[...t.portPointsInPairs??[],...i]},fixedRouteSectionsByConnectionName:o,fixedObstacleRoutes:l}},YK=t=\u003e{const e=[];for(let n=0;n\u003ct.length-1;n++){const o=t[n],i=t[n+1];o.z!==i.z\u0026\u0026Math.abs(o.x-i.x)\u003c=OK\u0026\u0026Math.abs(o.y-i.y)\u003c=OK\u0026\u0026e.push({x:i.x,y:i.y})}return e},XK=(t,e)=\u003eVK({section:t,replacement:e,sourceMutationMasks:new Map,replacementIsMutated:!1}).route,VK=({section:t,replacement:e,sourceMutationMasks:n,replacementIsMutated:o})=\u003e{const i=t.sourceRoutes[0],r=t.sourceRoutes.at(-1),s=((t,e)=\u003e{const n=t.route,o=n[0],i=n.at(-1);if(!o||!i)throw new Error(`Pipeline9 regional fallback produced an empty replacement for \"${e.sourceRoutes[0].connectionName}\"`);const r=Math.hypot(o.x-e.start.point.x,o.y-e.start.point.y)+Math.hypot(i.x-e.end.point.x,i.y-e.end.point.y);return Math.hypot(i.x-e.start.point.x,i.y-e.start.point.y)+Math.hypot(o.x-e.end.point.x,o.y-e.end.point.y)\u003cr?[...n].reverse():n})(e,t),a=[],c=[],l=(t,e)=\u003e{const o=n.get(t.connectionName);if(o\u0026\u0026o.length!==t.route.length-1)throw new Error(`Pipeline9 fixed route mutation mask for \"${t.connectionName}\" has ${o.length} segments, expected ${t.route.length-1}`);return o?.[e]??!1},d=(t,e)=\u003e{const n=a.at(-1);if(n){if(!BK(n,t)){if(n.z!==t.z\u0026\u0026(Math.abs(n.x-t.x)\u003eOK||Math.abs(n.y-t.y)\u003eOK)){const o={...t,z:n.z};BK(n,o)||(a.push(o),c.push(e))}BK(a.at(-1),t)||(a.push(t),c.push(e))}}else a.push(t)};d(i.route[0],!1);for(let e=1;e\u003c=t.start.segmentIndex;e++)d(i.route[e],l(i,e-1));d(t.start.point,l(i,t.start.segmentIndex));const h=c.length;for(const t of s.slice(1,-1))d(t,o);d(t.end.point,o);const u=c.length\u003eh;for(let e=t.end.segmentIndex+1;e\u003cr.route.length;e++)d(r.route[e],l(r,e-1));if(c.length!==a.length-1)throw new Error(`Pipeline9 produced an invalid mutation mask while splicing \"${i.connectionName}\"`);return{route:{...i,preloadedRoutePositionStart:i.preloadedRoutePositionStart,preloadedRoutePositionEnd:r.preloadedRoutePositionEnd,traceThickness:Math.max(...t.sourceRoutes.map(t=\u003et.traceThickness)),viaDiameter:Math.max(...t.sourceRoutes.map(t=\u003et.viaDiameter)),route:a,vias:YK(a)},mutatedSegments:c,replacementProducedSegment:u}},WK=1e-6,HK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=WK\u0026\u0026Math.abs(t.y-e.y)\u003c=WK\u0026\u0026t.z===e.z,GK=(t,e)=\u003e{for(const n of e)t.at(-1)\u0026\u0026HK(t.at(-1),n)||t.push(n)},UK=t=\u003et.slice(0,-1).flatMap((e,n)=\u003e{const o=t[n+1];return e.z!==o.z\u0026\u0026Math.abs(e.x-o.x)\u003c=WK\u0026\u0026Math.abs(e.y-o.y)\u003c=WK?[{x:o.x,y:o.y}]:[]}),ZK=t=\u003e{const e=t.preloadedRoutePositionStart,n=t.preloadedRoutePositionEnd;if(void 0===e||void 0===n)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" is missing route-position metadata`);return{start:Math.min(e,n),end:Math.max(e,n)}},qK=(t,e)=\u003e{const n=ZK(t),o=ZK(e);return t.preloadedTraceIndex-e.preloadedTraceIndex||n.start-o.start||n.end-o.end||t.preloadedRouteIndex-e.preloadedRouteIndex||t.connectionName.localeCompare(e.connectionName)},JK=(t,e)=\u003e{const n=t.route.at(-1),o=e.route[0];return Boolean(n\u0026\u0026o\u0026\u0026t.preloadedTraceIndex===e.preloadedTraceIndex\u0026\u0026HK(n,o))},KK=(t,e)=\u003e{const n=t.preloadedRoutePositionStart??t.preloadedRouteIndex;return n+((t.preloadedRoutePositionEnd??t.preloadedRouteIndex)-n)*e/(t.route.length-1)},QK=(t,e)=\u003et.route[e].z!==t.route[e+1].z,tQ=({updatedFixedRoutes:t,regionalMutationMasks:e})=\u003e{const n=[],o=(({updatedFixedRoutes:t,regionalMutationMasks:e})=\u003e{const n=new Map;for(const o of t){if(0===o.route.length)throw new Error(`Pipeline9 cannot normalize empty fixed route \"${o.connectionName}\"`);const t=o.route.length-1;if(n.has(o.connectionName))throw new Error(`Pipeline9 cannot normalize duplicate fixed route \"${o.connectionName}\"`);const i=e.get(o.connectionName);if(i\u0026\u0026i.length!==t)throw new Error(`Pipeline9 fixed route mutation mask for \"${o.connectionName}\" has ${i.length} segments, expected ${t}`);const r=!0!==o.isThroughObstacle\u0026\u00260===(o.jumpers?.length??0);n.set(o.connectionName,Array.from({length:t},(t,e)=\u003er\u0026\u0026(i?.[e]??!1)))}let o=[];const i=()=\u003e{for(;o[0]\u0026\u0026QK(o[0].route,o[0].segmentIndex);){const t=o.shift();n.get(t.route.connectionName)[t.segmentIndex]=!1}for(;o.at(-1)\u0026\u0026QK(o.at(-1).route,o.at(-1).segmentIndex);){const t=o.pop();n.get(t.route.connectionName)[t.segmentIndex]=!1}o=[]};let r;for(const e of[...t].sort(qK)){r\u0026\u0026!JK(r,e)\u0026\u0026i();const t=n.get(e.connectionName);if(0!==t.length){for(let n=0;n\u003ct.length;n++)t[n]?o.push({route:e,segmentIndex:n}):i();r=e}else i(),r=e}return i(),n})({updatedFixedRoutes:t,regionalMutationMasks:e});for(const e of t){const t=e.route.length-1,i=o.get(e.connectionName);if(0===t){n.push({route:e,mutated:!1});continue}const r=[];for(let e=0;e\u003ct;e++){const t=i[e],n=r.at(-1);n?.mutated===t?n.end=e+1:r.push({start:e,end:e+1,mutated:t})}for(const[t,o]of r.entries()){const i=e.route.slice(o.start,o.end+1),s={...e,connectionName:1===r.length?e.connectionName:`${e.connectionName}_mutation_fragment_${t}`,preloadedRouteIndex:e.preloadedRouteIndex+t/(r.length+1),preloadedRoutePositionStart:KK(e,o.start),preloadedRoutePositionEnd:KK(e,o.end),route:i,vias:UK(i)};n.push({route:s,mutated:o.mutated})}}return n},eQ=({updatedFixedRoutes:t,regionalMutationMasks:e})=\u003e{const n=tQ({updatedFixedRoutes:t,regionalMutationMasks:e}),o=n.map(({route:t})=\u003et),i=(t=\u003e{const e=[];let n;for(const o of[...t].sort((t,e)=\u003eqK(t.route,e.route))){const t=o.route;if(!o.mutated){n=void 0;continue}const i=t.route[0],r=t.route.at(-1);if(!i||!r||t.route.length\u003c2)throw new Error(`Pipeline9 cannot simplify empty fixed route \"${t.connectionName}\"`);const s=n?.sourceRoutes.at(-1);n\u0026\u0026s\u0026\u0026JK(s,t)?(n.sourceRoutes.push(t),n.end={segmentIndex:t.route.length-2,point:r}):(n={sourceRoutes:[t],start:{segmentIndex:0,point:i},end:{segmentIndex:t.route.length-2,point:r}},e.push(n))}return e})(n),r=i.map((t,e)=\u003e{const n=((t,e)=\u003e{const n=t.sourceRoutes[0],o=t.sourceRoutes.at(-1);if(!n||!o)throw new Error(\"Pipeline9 cannot simplify an empty mutation section\");const i=[t.start.point];for(const[e,n]of t.sourceRoutes.entries()){const o=0===e,r=e===t.sourceRoutes.length-1,s=o?t.start.segmentIndex+1:0,a=r?t.end.segmentIndex+1:n.route.length;GK(i,n.route.slice(s,a))}if(GK(i,[t.end.point]),i.length\u003c2)throw new Error(`Pipeline9 mutation section for \"${n.connectionName}\" has no routable span`);return{connectionName:`pipeline9_mutated_preload_${n.preloadedTraceIndex}_${e}`,rootConnectionName:n.rootConnectionName,traceThickness:Math.max(...t.sourceRoutes.map(t=\u003et.traceThickness)),viaDiameter:Math.max(...t.sourceRoutes.map(t=\u003et.viaDiameter)),route:i,vias:UK(i)}})(t,e);return{connectionName:n.connectionName,section:t,hdRoute:n}}),s=new Set(r.flatMap(({section:t})=\u003et.sourceRoutes.map(t=\u003et.connectionName)));return{sections:r,immutableHdRoutes:o.filter(t=\u003e!s.has(t.connectionName)),normalizedFixedRoutes:o}},nQ=1e-9,oQ=(t,e,n,o,i)=\u003e{const r=i.getNetConnectedToId(t.connection_name)??t.connection_name,s=[],a=(n,i,a=o,c=[],l,d,h=!1)=\u003e{n.length\u003c2||s.push({connectionName:`${t.connection_name}_fixed_${e}_${s.length}`,rootConnectionName:r,preloadedTraceIndex:e,preloadedRouteIndex:s.length,preloadedRoutePositionStart:l,preloadedRoutePositionEnd:d,isThroughObstacle:h,traceThickness:Math.max(nQ,i),viaDiameter:Math.max(nQ,a),route:n,vias:c})};for(let e=0;e\u003ct.route.length;e++){const i=t.route[e];if(\"via\"===i.route_type){a([{x:i.x,y:i.y,z:ko(i.from_layer,n)},{x:i.x,y:i.y,z:ko(i.to_layer,n)}],nQ,i.via_diameter??o,[{x:i.x,y:i.y}],e,e);continue}if(\"through_obstacle\"===i.route_type){const t=ko(i.from_layer,n),r=ko(i.to_layer,n);for(let n=Math.min(t,r);n\u003c=Math.max(t,r);n++)a([{...i.start,z:n},{...i.end,z:n}],i.width,o,[],e,e+1,!0);continue}const r=t.route[e+1];\"wire\"===i.route_type\u0026\u0026\"wire\"===r?.route_type\u0026\u0026i.layer===r.layer\u0026\u0026a([{x:i.x,y:i.y,z:ko(i.layer,n)},{x:r.x,y:r.y,z:ko(r.layer,n)}],Math.max(i.width,r.width),o,[],e,e+1)}return s};function iQ(t,e){return{x:t.a*e.x+t.b*e.y+t.c,y:t.d*e.x+t.e*e.y+t.f}}var rQ={highResolutionCellSize:.1,highResolutionCellThickness:8,lowResolutionCellSize:.4,traceMargin:.15,traceThickness:.1,viaDiameter:.3,viaMinDistFromBorder:.15},sQ={...rQ},aQ=(t,e,n)=\u003e{const[o,i]=t;if(o===i)return;const r=((t,e)=\u003e{const n=t.portPointId??`${t.connectionName}:${t.x}:${t.y}:${t.z}`,o=e.portPointId??`${e.connectionName}:${e.x}:${e.y}:${e.z}`;return n\u003co?`${n}|${o}`:`${o}|${n}`})(o,i);e.has(r)||(e.add(r),n.push(t))},cQ=(t,e,n)=\u003e{for(let o=0;o\u003ct.length-1;o++)aQ([t[o],t[o+1]],e,n)},lQ=t=\u003e{const e=[],n=new Set,o=(t=\u003e{const e=new Map;for(const n of t)n.portPointId\u0026\u0026e.set(n.portPointId,n);return e})(t);for(const i of t){if(i.prevPortPointId){const t=o.get(i.prevPortPointId);t\u0026\u0026t.connectionName===i.connectionName\u0026\u0026aQ([t,i],n,e)}if(i.nextPortPointId){const t=o.get(i.nextPortPointId);t\u0026\u0026t.connectionName===i.connectionName\u0026\u0026aQ([i,t],n,e)}}if(0===e.length)return cQ(t,n,e),e;const i=(t=\u003e{const e=new Set;for(const[n,o]of t)n.portPointId\u0026\u0026e.add(n.portPointId),o.portPointId\u0026\u0026e.add(o.portPointId);return e})(e),r=t.filter(t=\u003e!t.portPointId||!i.has(t.portPointId));return cQ(r,n,e),e};function dQ(t,e,n){return Math.max(e,Math.min(n,t))}var hQ=[\"left\",\"top\",\"right\",\"bottom\",\"middle\"],uQ=class{f=new Float64Array(1024);seq=new Uint32Array(1024);id=new Int32Array(1024);n=0;push(t,e,n){this.ensureCapacity(this.n+1);let o=this.n++;for(this.f[o]=t,this.seq[o]=e,this.id[o]=n;o\u003e0;){const t=o-1\u003e\u003e1;if(this.less(t,o))break;this.swap(o,t),o=t}}pop(){const t=this.id[0];return this.n--,this.n\u003e0\u0026\u0026(this.f[0]=this.f[this.n],this.seq[0]=this.seq[this.n],this.id[0]=this.id[this.n],this.siftDown(0)),t}get size(){return this.n}clear(){this.n=0}ensureCapacity(t){if(t\u003c=this.f.length)return;let e=this.f.length;for(;e\u003ct;)e*=2;const n=new Float64Array(e);n.set(this.f),this.f=n;const o=new Uint32Array(e);o.set(this.seq),this.seq=o;const i=new Int32Array(e);i.set(this.id),this.id=i}siftDown(t){for(;;){const e=2*t+1,n=e+1;if(e\u003e=this.n)return;let o=e;if(n\u003cthis.n\u0026\u0026!this.less(e,n)\u0026\u0026(o=n),this.less(t,o))return;this.swap(t,o),t=o}}less(t,e){const n=this.f[t],o=this.f[e];return n!==o?n\u003co:this.seq[t]\u003cthis.seq[e]}swap(t,e){const n=this.f[t];this.f[t]=this.f[e],this.f[e]=n;const o=this.seq[t];this.seq[t]=this.seq[e],this.seq[e]=o;const i=this.id[t];this.id[t]=this.id[e],this.id[e]=i}},pQ=class{z=new Int32Array(1024);cellId=new Int32Array(1024);g=new Float64Array(1024);parent=new Int32Array(1024);ripHead=new Int32Array(1024).fill(-1);ripCount=new Int32Array(1024);length=0;clear(){this.length=0}push(t,e,n,o,i,r){this.ensureCapacity(this.length+1);const s=this.length++;return this.z[s]=t,this.cellId[s]=e,this.g[s]=n,this.parent[s]=o,this.ripHead[s]=i,this.ripCount[s]=r,s}ensureCapacity(t){if(t\u003c=this.z.length)return;let e=this.z.length;for(;e\u003ct;)e*=2;const n=new Int32Array(e);n.set(this.z),this.z=n;const o=new Int32Array(e);o.set(this.cellId),this.cellId=o;const i=new Float64Array(e);i.set(this.g),this.g=i;const r=new Int32Array(e);r.set(this.parent),this.parent=r;const s=new Int32Array(e);s.fill(-1),s.set(this.ripHead.subarray(0,this.length)),this.ripHead=s;const a=new Int32Array(e);a.set(this.ripCount.subarray(0,this.length)),this.ripCount=a}},mQ=class{connId=new Int32Array(1024);prev=new Int32Array(1024).fill(-1);length=0;clear(){this.length=0}append(t,e){this.ensureCapacity(this.length+1);const n=this.length++;return this.connId[n]=e,this.prev[n]=t,n}contains(t,e){for(let n=t;n\u003e=0;n=this.prev[n])if(this.connId[n]===e)return!0;return!1}collect(t,e){e.length=0;for(let n=t;n\u003e=0;n=this.prev[n])e.push(this.connId[n])}ensureCapacity(t){if(t\u003c=this.connId.length)return;let e=this.connId.length;for(;e\u003ct;)e*=2;const n=new Int32Array(e);n.set(this.connId),this.connId=n;const o=new Int32Array(e);o.fill(-1),o.set(this.prev.subarray(0,this.length)),this.prev=o}};function gQ(t,e){return e??t.replace(/_mst\\d+$/,\"\")}function fQ(t,e){const n=t.x-e.center.x,o=t.y-e.center.y,i=Math.cos(-e.rotationRadians),r=Math.sin(-e.rotationRadians);return{x:n*i-o*r,y:n*r+o*i}}function yQ(t){return{minX:-t.width/2,minY:-t.height/2,maxX:t.width/2,maxY:t.height/2}}function _Q(t,e,n){return Math.max(e,Math.min(n,t))}function bQ(t,e){for(let n=0;n\u003ct.length;n++)if(t[n]===e)return;t.push(e)}function xQ(t,e){for(let n=0;n\u003ct.length;n++)if(t[n].cellId===e.cellId)return;t.push(e)}function vQ(t,e,n,o,i,r,s){const a=t-_Q(t,o,r),c=e-_Q(e,i,s);return a*a+c*c\u003c=n*n}function SQ(t){const e=t.segmentEnd.x-t.segmentStart.x,n=t.segmentEnd.y-t.segmentStart.y,o=e**2+n**2;if(0===o)return(t.point.x-t.segmentStart.x)**2+(t.point.y-t.segmentStart.y)**2;const i=_Q(((t.point.x-t.segmentStart.x)*e+(t.point.y-t.segmentStart.y)*n)/o,0,1),r=t.segmentStart.x+i*e,s=t.segmentStart.y+i*n;return(t.point.x-r)**2+(t.point.y-s)**2}function IQ(t){const e=_Q(t.point.x,t.rect.minX,t.rect.maxX),n=_Q(t.point.y,t.rect.minY,t.rect.maxY),o=t.point.x-e,i=t.point.y-n;return o*o+i*i}function CQ(t){return(t.second.x-t.first.x)*(t.third.y-t.first.y)-(t.second.y-t.first.y)*(t.third.x-t.first.x)}function PQ(t){return!(Math.abs(CQ({first:t.segmentStart,second:t.segmentEnd,third:t.point}))\u003e1e-9)\u0026\u0026(t.point.x\u003e=Math.min(t.segmentStart.x,t.segmentEnd.x)\u0026\u0026t.point.x\u003c=Math.max(t.segmentStart.x,t.segmentEnd.x)\u0026\u0026t.point.y\u003e=Math.min(t.segmentStart.y,t.segmentEnd.y)\u0026\u0026t.point.y\u003c=Math.max(t.segmentStart.y,t.segmentEnd.y))}function MQ(t){const e=CQ({first:t.firstStart,second:t.firstEnd,third:t.secondStart}),n=CQ({first:t.firstStart,second:t.firstEnd,third:t.secondEnd}),o=CQ({first:t.secondStart,second:t.secondEnd,third:t.firstStart}),i=CQ({first:t.secondStart,second:t.secondEnd,third:t.firstEnd});return e*n\u003c0\u0026\u0026o*i\u003c0||(PQ({point:t.secondStart,segmentStart:t.firstStart,segmentEnd:t.firstEnd})||PQ({point:t.secondEnd,segmentStart:t.firstStart,segmentEnd:t.firstEnd})||PQ({point:t.firstStart,segmentStart:t.secondStart,segmentEnd:t.secondEnd})||PQ({point:t.firstEnd,segmentStart:t.secondStart,segmentEnd:t.secondEnd}))}function NQ(t){return MQ(t)?0:Math.min(SQ({point:t.firstStart,segmentStart:t.secondStart,segmentEnd:t.secondEnd}),SQ({point:t.firstEnd,segmentStart:t.secondStart,segmentEnd:t.secondEnd}),SQ({point:t.secondStart,segmentStart:t.firstStart,segmentEnd:t.firstEnd}),SQ({point:t.secondEnd,segmentStart:t.firstStart,segmentEnd:t.firstEnd}))}function wQ(t){if(function(t){if(0===IQ({point:t.segmentStart,rect:t.rect})||0===IQ({point:t.segmentEnd,rect:t.rect}))return!0;const e=[{x:t.rect.minX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.maxY},{x:t.rect.minX,y:t.rect.maxY}];for(let n=0;n\u003ce.length;n++){const o=(n+1)%e.length;if(MQ({firstStart:t.segmentStart,firstEnd:t.segmentEnd,secondStart:e[n],secondEnd:e[o]}))return!0}return!1}(t))return!0;const e=t.radius**2;if(IQ({point:t.segmentStart,rect:t.rect})\u003c=e||IQ({point:t.segmentEnd,rect:t.rect})\u003c=e)return!0;return[{x:t.rect.minX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.maxY},{x:t.rect.minX,y:t.rect.maxY}].some(n=\u003eSQ({point:n,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd})\u003c=e)}var TQ=class extends kt{getSolverName(){return\"HighDensitySolverB01\"}nodeWithPortPoints;obstacles;highResolutionCellSize;highResolutionCellThickness;lowResolutionCellSize;viaDiameter;MAX_RIPS;maxCellCount;traceThickness;traceMargin;obstacleClearanceMargin;viaMinDistFromBorder;showPenaltyMap;showUsedCellMap;effort;stepMultiplier;hyperParameters;initialPenaltyFn;boundsMinX;boundsMaxX;boundsMinY;boundsMaxY;gridToBoundsTransform;availableZ;zToLayer;layerToZ;layers;fineRows;fineCols;lowScale;bandRows;bandCols;regions;planeSize;cellCenterX;cellCenterY;cellMinX;cellMinY;cellMaxX;cellMaxY;cellWidth;cellHeight;cellRegion;cellRow;cellCol;viaAllowed;neighborOffset;neighborIds;neighborCosts;usedCellsFlat;sharedCellsFlat;portOwnerFlat;penalty2d;ripStateBuckets;visitedStamp;bestGStamp;bestGValue;visitedFlatStamp;sharedCrossRootPortFlat;stamp=0;connNameToId;connIdToName;connIdToRootNet;overlapFriendlyRootNets;usedIndicesByConn;unsolvedSegs;solvedRoutes;activeConnSeg=null;activeConnId=-1;nodePool;heap;ripChain;seqCounter=0;_viaOccs=[];_cellOccs=[];_rippedIds=[];ripCount;totalRipEvents=0;searchIterations=0;consecutiveSkips=0;penaltyCap;baseSearchBudgetIters;_moveCost=0;_moveRippedHead=-1;_moveRipCount=0;traceKeepoutRadius;viaKeepoutRadius;obstacleTraceRootIdsFlat;obstacleViaRootIdsByCell;obstacleRootNameToId;obstacleRootNames;obstacleTracePrimitives;obstacleViaPrimitives;obstacleRectPrimitives;obstacleTraceBlockedCellCount=0;obstacleViaBlockedCellCount=0;get unsolvedConnections(){return this.unsolvedSegs}get solvedConnectionsMap(){const t=new Map;for(let e=0;e\u003cthis.solvedRoutes.length;e++){const n=this.getSolvedRoutesForConn(e);n.length\u003e0\u0026\u0026t.set(e,n)}return t}get activeConnection(){if(!this.activeConnSeg)return null;const t=this.activeConnSeg.startCellId,e=this.activeConnSeg.endCellId;return{connectionName:this.connIdToName[this.activeConnSeg.connId]??\"\",start:{cellId:t,region:hQ[this.cellRegion[t]],row:this.cellRow[t],col:this.cellCol[t],x:this.cellCenterX[t],y:this.cellCenterY[t],z:this.activeConnSeg.startZ},end:{cellId:e,region:hQ[this.cellRegion[e]],row:this.cellRow[e],col:this.cellCol[e],x:this.cellCenterX[e],y:this.cellCenterY[e],z:this.activeConnSeg.endZ}}}get openSet(){return{length:this.heap?.size??0}}get gridStats(){return{cells:this.planeSize||0,layers:this.layers||0,states:(this.planeSize||0)*(this.layers||0),ripStateBuckets:this.ripStateBuckets||0,neighborEdges:this.neighborIds?.length??0,regionCounts:this.regions?Object.fromEntries(this.regions.map(t=\u003e[t.name,t.rows*t.cols])):{},obstacleTraceBlockedCells:this.obstacleTraceBlockedCellCount,obstacleViaBlockedCells:this.obstacleViaBlockedCellCount,obstacleRootCount:this.obstacleRootNames?.length??0,obstacleRectCount:this.obstacleRectPrimitives?.length??0}}constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.obstacles=t.obstacles,this.highResolutionCellSize=t.highResolutionCellSize??.1,this.highResolutionCellThickness=Math.max(1,Math.floor(t.highResolutionCellThickness??8)),this.lowResolutionCellSize=t.lowResolutionCellSize??.4,this.viaDiameter=t.viaDiameter,this.maxCellCount=t.maxCellCount,this.traceThickness=t.traceThickness??.1,this.traceMargin=t.traceMargin??.15,this.obstacleClearanceMargin=t.obstacleClearanceMargin??0,this.viaMinDistFromBorder=t.viaMinDistFromBorder??.15,this.showPenaltyMap=t.showPenaltyMap??!1,this.showUsedCellMap=t.showUsedCellMap??!1,this.effort=t.effort??1,this.stepMultiplier=Math.max(1,Math.floor(t.stepMultiplier??1)),this.hyperParameters={shuffleSeed:0,ripCost:8,ripTracePenalty:.5,ripViaPenalty:.75,viaBaseCost:.1,greedyMultiplier:1.5,sameRootObstacleCostMultiplier:1,...t.hyperParameters},this.MAX_ITERATIONS=1e8,this.MAX_RIPS=200,this.initialPenaltyFn=t.initialPenaltyFn}getConstructorParams(){return[{nodeWithPortPoints:this.nodeWithPortPoints,obstacles:this.obstacles,highResolutionCellSize:this.highResolutionCellSize,highResolutionCellThickness:this.highResolutionCellThickness,lowResolutionCellSize:this.lowResolutionCellSize,viaDiameter:this.viaDiameter,maxCellCount:this.maxCellCount,stepMultiplier:this.stepMultiplier,traceThickness:this.traceThickness,traceMargin:this.traceMargin,obstacleClearanceMargin:this.obstacleClearanceMargin,viaMinDistFromBorder:this.viaMinDistFromBorder,showPenaltyMap:this.showPenaltyMap,showUsedCellMap:this.showUsedCellMap,effort:this.effort,hyperParameters:this.hyperParameters,initialPenaltyFn:this.initialPenaltyFn}]}_setup(){const{nodeWithPortPoints:t}=this,{width:e,height:n,center:o}=t;if(e\u003e15||n\u003e15)return this.error=`HighDensitySolverB01 only supports routing windows up to 15x15mm; received ${e}x${n}mm`,void(this.failed=!0);const i=this.lowResolutionCellSize/this.highResolutionCellSize,r=Math.round(i);if(!Number.isFinite(i)||i\u003c=0||Math.abs(i-r)\u003e1e-9)return this.error=\"lowResolutionCellSize must be a positive integer multiple of highResolutionCellSize\",void(this.failed=!0);this.lowScale=Math.max(1,r),this.availableZ=t.availableZ??[...new Set(t.portPoints.map(t=\u003et.z))].sort((t,e)=\u003et-e),this.layers=this.availableZ.length,this.zToLayer=new Map,this.layerToZ=new Map;for(let t=0;t\u003cthis.availableZ.length;t++){const e=this.availableZ[t];this.zToLayer.set(e,t),this.layerToZ.set(t,e)}this.boundsMinX=o.x-e/2,this.boundsMaxX=o.x+e/2,this.boundsMinY=o.y-n/2,this.boundsMaxY=o.y+n/2,this.traceKeepoutRadius=this.traceMargin+this.traceThickness/2,this.viaKeepoutRadius=this.viaDiameter/2+this.traceKeepoutRadius,this.buildFiveRegionGrid(e,n),this.gridToBoundsTransform=this.computeGridToBoundsTransform();const s=this.layers*this.planeSize;if(void 0!==this.maxCellCount\u0026\u0026s\u003ethis.maxCellCount)return this.error=`Cell count ${s} exceeds maxCellCount ${this.maxCellCount}`,void(this.failed=!0);this.connNameToId=new Map,this.connIdToName=[],this.connIdToRootNet=[],this.overlapFriendlyRootNets=new Set,this.unsolvedSegs=this.buildConnectionSegs(),this.penalty2d=new Float64Array(this.planeSize);const a=e\u003e0?1/e:0,c=n\u003e0?1/n:0;for(let t=0;t\u003cthis.planeSize;t++){let e=0;this.initialPenaltyFn\u0026\u0026(e+=this.initialPenaltyFn({x:this.cellCenterX[t],y:this.cellCenterY[t],px:(this.cellCenterX[t]-this.boundsMinX)*a,py:(this.cellCenterY[t]-this.boundsMinY)*c,cellId:t,region:hQ[this.cellRegion[t]],row:this.cellRow[t],col:this.cellCol[t]})),this.penalty2d[t]=e}this.usedCellsFlat=new Int32Array(s).fill(-1),this.sharedCellsFlat=Array.from({length:s},()=\u003e{}),this.portOwnerFlat=new Int32Array(s).fill(-1),this.sharedCrossRootPortFlat=new Uint8Array(s),this.obstacleTraceRootIdsFlat=Array.from({length:s},()=\u003e{}),this.obstacleViaRootIdsByCell=Array.from({length:this.planeSize},()=\u003e{}),this.obstacleRootNameToId=new Map,this.obstacleRootNames=[],this.obstacleTracePrimitives=[],this.obstacleViaPrimitives=[],this.obstacleRectPrimitives=[];const l=this.rasterizeObstacles();if(l)return this.error=l,void(this.failed=!0);this.ripStateBuckets=1;const d=s;this.visitedStamp=new Uint32Array(d),this.bestGStamp=new Uint32Array(d),this.bestGValue=new Float64Array(d),this.visitedFlatStamp=new Uint32Array(s),this.stamp=0;const h=new Map;for(const t of this.nodeWithPortPoints.portPoints){const e=this.connNameToId.get(t.connectionName);if(void 0===e)continue;const n=this.pointToCell(t),o=n.z*this.planeSize+n.cellId,i=this.connIdToRootNet[e],r=h.get(o);void 0===r?h.set(o,i):r!==i\u0026\u0026(this.sharedCrossRootPortFlat[o]=1);const s=this.portOwnerFlat[o];this.portOwnerFlat[o]=-1===s||s===e?e:-2}this.solvedRoutes=[],this.usedIndicesByConn=[],this.ripCount=[],this.consecutiveSkips=0,this.penaltyCap=.5*this.hyperParameters.ripCost,this.shuffleConnections();const u=function(t){const e=t.planeSize*t.layers,n=t.connectionCount,o=Math.sqrt(n),i=Math.max(1,t.maxIterations),r=dQ(Math.round(e*(8+1.2*o)),15e4,12e6),s=dQ(Math.round(r*t.effort),15e4,12e6),a=dQ(Math.round(.2*i),15e4,2e6);return{maxIterationsIters:Math.max(1,Math.min(i,Math.max(a,s))),baseSearchBudgetIters:dQ(Math.round(e*(10+.8*o)*t.effort),5e4,4e6)}}({planeSize:this.planeSize,layers:this.layers,connectionCount:this.unsolvedSegs.length,effort:this.effort,maxIterations:this.MAX_ITERATIONS});this.baseSearchBudgetIters=u.baseSearchBudgetIters,this.MAX_ITERATIONS=u.maxIterationsIters,this.activeConnSeg=null,this.activeConnId=-1,this.nodePool=new pQ,this.heap=new uQ,this.ripChain=new mQ,this.seqCounter=0}_step(){for(let t=0;t\u003cthis.stepMultiplier;t++){if(this.solved||this.failed)return;this.stepOnce()}}rasterizeObstacles(){for(let t=0;t\u003cthis.obstacles.length;t++){const e=this.obstacles[t];if(\"rect\"===e.type){const n=this.rasterizeRectObstacle(e,t);if(n)return n;continue}if(e.traceThickness\u003c=0||e.viaDiameter\u003c=0||e.route.length\u003c2)return`Obstacle ${t} must have positive trace/via sizes and at least two route points`;const n=gQ(e.connectionName,e.rootConnectionName),o=this.internObstacleRootName(n);for(let n=1;n\u003ce.route.length;n++){const i=e.route[n-1],r=e.route[n];if(!(Number.isFinite(i.x)\u0026\u0026Number.isFinite(i.y)\u0026\u0026Number.isFinite(i.z)\u0026\u0026Number.isFinite(r.x)\u0026\u0026Number.isFinite(r.y)\u0026\u0026Number.isFinite(r.z)))return`Obstacle ${t} contains non-finite route coordinates`;if(i.z===r.z){const n=this.zToLayer.get(i.z);if(void 0===n)return`Obstacle ${t} uses unavailable layer z=${i.z}`;this.rasterizeObstacleTraceSegment({segmentStart:i,segmentEnd:r,layer:n,obstacleRootId:o,obstacleTraceThickness:e.traceThickness})}else if(!e.vias.some(t=\u003et.x===r.x\u0026\u0026t.y===r.y)){const n=this.rasterizeObstacleVia({center:r,obstacleRootId:o,obstacleViaDiameter:e.viaDiameter,zStart:i.z,zEnd:r.z,obstacleIndex:t});if(n)return n}}for(const n of e.vias){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))return`Obstacle ${t} contains non-finite via coordinates`;const i=this.rasterizeObstacleVia({center:n,obstacleRootId:o,obstacleViaDiameter:e.viaDiameter,zStart:n.zStart,zEnd:n.zEnd,obstacleIndex:t});if(i)return i}}return this.obstacleTraceBlockedCellCount=this.obstacleTraceRootIdsFlat.reduce((t,e)=\u003et+(e?1:0),0),this.obstacleViaBlockedCellCount=this.obstacleViaRootIdsByCell.reduce((t,e)=\u003et+(e?1:0),0),null}rasterizeRectObstacle(t,e){if(!Number.isFinite(t.center.x)||!Number.isFinite(t.center.y)||!Number.isFinite(t.width)||!Number.isFinite(t.height)||t.width\u003c=0||t.height\u003c=0)return`Rect obstacle ${e} must have finite geometry and positive dimensions`;const n=[];for(const o of t.zLayers){const t=this.zToLayer.get(o);if(void 0===t)return`Rect obstacle ${e} uses unavailable layer z=${o}`;bQ(n,t)}if(0===n.length)return`Rect obstacle ${e} must apply to at least one layer`;const o=this.internObstacleRootName(gQ(t.connectionName,t.rootConnectionName)),i={rootId:o,center:t.center,width:t.width,height:t.height,rotationRadians:(t.ccwRotationDegrees??0)*Math.PI/180,layers:n};this.obstacleRectPrimitives.push(i);const r=this.transformBoundsPointToGrid(t.center),s=Math.hypot(t.width/2,t.height/2),a=this.getConservativeGridRadius(s+this.traceThickness/2+this.traceMargin);this.forEachCellNearCircle(r.x,r.y,a,t=\u003e{for(const e of n)this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:e*this.planeSize+t,obstacleRootId:o})});const c=this.getConservativeGridRadius(s+this.viaDiameter/2+this.traceMargin);return this.forEachCellNearCircle(r.x,r.y,c,t=\u003e{this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:t,obstacleRootId:o})}),null}internObstacleRootName(t){const e=this.obstacleRootNameToId.get(t);if(void 0!==e)return e;const n=this.obstacleRootNames.length;return this.obstacleRootNames.push(t),this.obstacleRootNameToId.set(t,n),n}rasterizeObstacleTraceSegment(t){this.obstacleTracePrimitives.push({rootId:t.obstacleRootId,layer:t.layer,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd,traceRadius:t.obstacleTraceThickness/2});const e=this.transformBoundsPointToGrid(t.segmentStart),n=this.transformBoundsPointToGrid(t.segmentEnd),o=this.getConservativeGridRadius(t.obstacleTraceThickness/2+this.traceMargin),i=this.getConservativeGridRadius(t.obstacleTraceThickness/2+this.viaDiameter/2+this.traceMargin);this.forEachCellNearSegment({segmentStart:e,segmentEnd:n,radius:o},e=\u003e{this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:t.layer*this.planeSize+e,obstacleRootId:t.obstacleRootId})}),this.forEachCellNearSegment({segmentStart:e,segmentEnd:n,radius:i},e=\u003e{this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:e,obstacleRootId:t.obstacleRootId})})}rasterizeObstacleVia(t){if(void 0===t.zStart!=(void 0===t.zEnd))return`Obstacle ${t.obstacleIndex} via must provide both zStart and zEnd`;let e=Array.from({length:this.layers},(t,e)=\u003ee);if(void 0!==t.zStart\u0026\u0026void 0!==t.zEnd){if(!Number.isFinite(t.zStart)||!Number.isFinite(t.zEnd))return`Obstacle ${t.obstacleIndex} contains a non-finite via layer span`;const n=Math.min(t.zStart,t.zEnd),o=Math.max(t.zStart,t.zEnd);e=this.availableZ.flatMap((t,e)=\u003et\u003e=n\u0026\u0026t\u003c=o?[e]:[])}if(0===e.length)return null;this.obstacleViaPrimitives.push({rootId:t.obstacleRootId,center:t.center,viaRadius:t.obstacleViaDiameter/2,layers:e});const n=this.transformBoundsPointToGrid(t.center),o=this.getConservativeGridRadius(t.obstacleViaDiameter/2+this.traceThickness/2+this.traceMargin),i=this.getConservativeGridRadius(t.obstacleViaDiameter/2+this.viaDiameter/2+this.traceMargin);return this.forEachCellNearCircle(n.x,n.y,Math.max(o,i),r=\u003e{const s=this.getCellRect(r);if(vQ(n.x,n.y,o,s.minX,s.minY,s.maxX,s.maxY))for(const n of e)this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:n*this.planeSize+r,obstacleRootId:t.obstacleRootId});vQ(n.x,n.y,i,s.minX,s.minY,s.maxX,s.maxY)\u0026\u0026this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:r,obstacleRootId:t.obstacleRootId})}),null}forEachCellNearSegment(t,e){const n={x:(t.segmentStart.x+t.segmentEnd.x)/2,y:(t.segmentStart.y+t.segmentEnd.y)/2},o=Math.hypot(t.segmentEnd.x-t.segmentStart.x,t.segmentEnd.y-t.segmentStart.y)/2+t.radius;this.forEachCellNearCircle(n.x,n.y,o,n=\u003e{wQ({segmentStart:t.segmentStart,segmentEnd:t.segmentEnd,radius:t.radius,rect:this.getCellRect(n)})\u0026\u0026e(n)})}getCellRect(t){return{minX:this.cellMinX[t],minY:this.cellMinY[t],maxX:this.cellMaxX[t],maxY:this.cellMaxY[t]}}transformBoundsPointToGrid(t){const e=this.gridToBoundsTransform;return{x:(t.x-e.c)/e.a,y:(t.y-e.f)/e.e}}getConservativeGridRadius(t){return t/Math.min(Math.abs(this.gridToBoundsTransform.a),Math.abs(this.gridToBoundsTransform.e))}addObstacleRootId(t){let e=t.rootIdsByCell[t.cellIndex];e||(e=[],t.rootIdsByCell[t.cellIndex]=e),bQ(e,t.obstacleRootId)}isBlockedByObstacleRoots(t,e){if(!t)return!1;const n=this.connIdToRootNet[e];for(const e of t)if(this.obstacleRootNames[e]!==n)return!0;return!1}hasSameRootObstacle(t,e){if(!t)return!1;const n=this.connIdToRootNet[e];return t.some(t=\u003ethis.obstacleRootNames[t]===n)}isLateralMoveBlockedByObstacleGeometry(t){const e=this.connIdToRootNet[t.activeConn],n=this.activeConnSeg,o=n\u0026\u0026t.layer===n.startZ\u0026\u0026t.fromCellId===n.startCellId?n.startPoint:iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.fromCellId],y:this.cellCenterY[t.fromCellId]}),i=n\u0026\u0026t.layer===n.endZ\u0026\u0026t.toCellId===n.endCellId?n.endPoint:iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.toCellId],y:this.cellCenterY[t.toCellId]});for(const n of this.obstacleTracePrimitives){if(n.layer!==t.layer||this.obstacleRootNames[n.rootId]===e)continue;const r=n.traceRadius+this.traceThickness/2+this.obstacleClearanceMargin;if(NQ({firstStart:o,firstEnd:i,secondStart:n.segmentStart,secondEnd:n.segmentEnd})\u003cr*r)return!0}for(const n of this.obstacleViaPrimitives){if(!n.layers.includes(t.layer)||this.obstacleRootNames[n.rootId]===e)continue;const r=n.viaRadius+this.traceThickness/2+this.obstacleClearanceMargin;if(SQ({point:n.center,segmentStart:o,segmentEnd:i})\u003cr*r)return!0}for(const n of this.obstacleRectPrimitives)if(n.layers.includes(t.layer)\u0026\u0026this.obstacleRootNames[n.rootId]!==e\u0026\u0026wQ({segmentStart:fQ(o,n),segmentEnd:fQ(i,n),radius:this.traceThickness/2+this.obstacleClearanceMargin,rect:yQ(n)}))return!0;return!1}isViaMoveBlockedByObstacleGeometry(t){const e=this.connIdToRootNet[t.activeConn],n=iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.cellId],y:this.cellCenterY[t.cellId]});for(const t of this.obstacleTracePrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=t.traceRadius+this.viaDiameter/2+this.obstacleClearanceMargin;if(SQ({point:n,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd})\u003co*o)return!0}for(const t of this.obstacleViaPrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=t.viaRadius+this.viaDiameter/2+this.obstacleClearanceMargin;if((n.x-t.center.x)**2+(n.y-t.center.y)**2\u003co*o)return!0}for(const t of this.obstacleRectPrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=fQ(n,t),i=this.viaDiameter/2+this.obstacleClearanceMargin;if(IQ({point:o,rect:yQ(t)})\u003ci*i)return!0}return!1}buildFiveRegionGrid(t,e){this.fineCols=Math.max(1,Math.ceil(t/this.highResolutionCellSize)),this.fineRows=Math.max(1,Math.ceil(e/this.highResolutionCellSize)),this.bandCols=Math.min(this.highResolutionCellThickness,Math.floor(this.fineCols/2)),this.bandRows=Math.min(this.highResolutionCellThickness,Math.floor(this.fineRows/2));const n=Math.max(0,this.fineCols-2*this.bandCols),o=Math.max(0,this.fineRows-2*this.bandRows),i=n,r=n;this.regions=[{id:0,name:\"left\",fineOriginRow:0,fineOriginCol:0,fineRows:this.fineRows,fineCols:this.bandCols,cellScale:1,rows:this.fineRows,cols:this.bandCols,offset:0},{id:1,name:\"top\",fineOriginRow:0,fineOriginCol:this.bandCols,fineRows:this.bandRows,fineCols:i,cellScale:1,rows:this.bandRows,cols:i,offset:0},{id:2,name:\"right\",fineOriginRow:0,fineOriginCol:this.fineCols-this.bandCols,fineRows:this.fineRows,fineCols:this.bandCols,cellScale:1,rows:this.fineRows,cols:this.bandCols,offset:0},{id:3,name:\"bottom\",fineOriginRow:this.fineRows-this.bandRows,fineOriginCol:this.bandCols,fineRows:this.bandRows,fineCols:r,cellScale:1,rows:this.bandRows,cols:r,offset:0},{id:4,name:\"middle\",fineOriginRow:this.bandRows,fineOriginCol:this.bandCols,fineRows:o,fineCols:n,cellScale:this.lowScale,rows:o\u003e0?Math.ceil(o/this.lowScale):0,cols:n\u003e0?Math.ceil(n/this.lowScale):0,offset:0}];let s=0;for(let t=0;t\u003cthis.regions.length;t++)this.regions[t].offset=s,s+=this.regions[t].rows*this.regions[t].cols;this.planeSize=s,this.cellCenterX=new Float64Array(this.planeSize),this.cellCenterY=new Float64Array(this.planeSize),this.cellMinX=new Float64Array(this.planeSize),this.cellMinY=new Float64Array(this.planeSize),this.cellMaxX=new Float64Array(this.planeSize),this.cellMaxY=new Float64Array(this.planeSize),this.cellWidth=new Float64Array(this.planeSize),this.cellHeight=new Float64Array(this.planeSize),this.cellRegion=new Uint8Array(this.planeSize),this.cellRow=new Int32Array(this.planeSize),this.cellCol=new Int32Array(this.planeSize),this.viaAllowed=new Uint8Array(this.planeSize);for(let t=0;t\u003cthis.regions.length;t++){const e=this.regions[t];for(let t=0;t\u003ce.rows;t++){const n=e.fineOriginRow+t*e.cellScale,o=Math.min(e.fineOriginRow+e.fineRows,n+e.cellScale),i=this.boundsMinY+n*this.highResolutionCellSize,r=Math.min(this.boundsMaxY,this.boundsMinY+o*this.highResolutionCellSize);for(let n=0;n\u003ce.cols;n++){const o=e.fineOriginCol+n*e.cellScale,s=Math.min(e.fineOriginCol+e.fineCols,o+e.cellScale),a=this.boundsMinX+o*this.highResolutionCellSize,c=Math.min(this.boundsMaxX,this.boundsMinX+s*this.highResolutionCellSize),l=this.cellIdFor(e.id,t,n);this.cellCenterX[l]=(a+c)/2,this.cellCenterY[l]=(i+r)/2,this.cellMinX[l]=a,this.cellMinY[l]=i,this.cellMaxX[l]=c,this.cellMaxY[l]=r,this.cellWidth[l]=c-a,this.cellHeight[l]=r-i,this.cellRegion[l]=e.id,this.cellRow[l]=t,this.cellCol[l]=n;const d=Math.min(this.cellCenterX[l]-this.boundsMinX,this.boundsMaxX-this.cellCenterX[l],this.cellCenterY[l]-this.boundsMinY,this.boundsMaxY-this.cellCenterY[l]);this.viaAllowed[l]=d\u003e=this.viaMinDistFromBorder?1:0}}}const a=Array.from({length:this.planeSize},()=\u003e[]),c=(t,e)=\u003e{if(t===e||t\u003c0||e\u003c0)return;const n=this.cellCenterX[t]-this.cellCenterX[e],o=this.cellCenterY[t]-this.cellCenterY[e],i=Math.hypot(n,o);xQ(a[t],{cellId:e,cost:i}),xQ(a[e],{cellId:t,cost:i})};for(let t=0;t\u003cthis.regions.length;t++){const e=this.regions[t];for(let t=0;t\u003ce.rows;t++)for(let n=0;n\u003ce.cols;n++){const o=this.cellIdFor(e.id,t,n);t+1\u003ce.rows\u0026\u0026c(o,this.cellIdFor(e.id,t+1,n)),n+1\u003ce.cols\u0026\u0026c(o,this.cellIdFor(e.id,t,n+1))}}const l=this.regions[0],d=this.regions[1],h=this.regions[2],u=this.regions[3],p=this.regions[4],m=l.rows\u003e0\u0026\u0026l.cols\u003e0,g=d.rows\u003e0\u0026\u0026d.cols\u003e0,f=h.rows\u003e0\u0026\u0026h.cols\u003e0,y=u.rows\u003e0\u0026\u0026u.cols\u003e0,_=p.rows\u003e0\u0026\u0026p.cols\u003e0;if(m\u0026\u0026g)for(let t=0;t\u003cthis.bandRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(1,t,0));if(g\u0026\u0026f)for(let t=0;t\u003cthis.bandRows;t++)c(this.cellIdFor(1,t,d.cols-1),this.cellIdFor(2,t,0));if(m\u0026\u0026y)for(let t=this.fineRows-this.bandRows;t\u003cthis.fineRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(3,t-(this.fineRows-this.bandRows),0));if(y\u0026\u0026f)for(let t=this.fineRows-this.bandRows;t\u003cthis.fineRows;t++)c(this.cellIdFor(3,t-(this.fineRows-this.bandRows),u.cols-1),this.cellIdFor(2,t,0));if(m\u0026\u0026_)for(let t=this.bandRows;t\u003cthis.fineRows-this.bandRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(4,Math.floor((t-this.bandRows)/this.lowScale),0));if(f\u0026\u0026_)for(let t=this.bandRows;t\u003cthis.fineRows-this.bandRows;t++)c(this.cellIdFor(4,Math.floor((t-this.bandRows)/this.lowScale),p.cols-1),this.cellIdFor(2,t,0));if(g\u0026\u0026_)for(let t=this.bandCols;t\u003cthis.fineCols-this.bandCols;t++)c(this.cellIdFor(1,d.rows-1,t-this.bandCols),this.cellIdFor(4,0,Math.floor((t-this.bandCols)/this.lowScale)));if(y\u0026\u0026_)for(let t=this.bandCols;t\u003cthis.fineCols-this.bandCols;t++)c(this.cellIdFor(4,p.rows-1,Math.floor((t-this.bandCols)/this.lowScale)),this.cellIdFor(3,0,t-this.bandCols));if(!_\u0026\u0026!g\u0026\u0026!y\u0026\u0026m\u0026\u0026f)for(let t=0;t\u003cMath.min(l.rows,h.rows);t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(2,t,0));if(!_\u0026\u0026!m\u0026\u0026!f\u0026\u0026g\u0026\u0026y)for(let t=0;t\u003cMath.min(d.cols,u.cols);t++)c(this.cellIdFor(1,d.rows-1,t),this.cellIdFor(3,0,t));const b=this.flattenNeighborLists(a);this.neighborOffset=b.offset,this.neighborIds=b.ids,this.neighborCosts=b.costs}cellIdFor(t,e,n){const o=this.regions[t];return o.offset+e*o.cols+n}stepOnce(){if(!this.activeConnSeg){if(0===this.unsolvedSegs.length)return void(this.solved=!0);const t=this.unsolvedSegs.shift();this.activeConnSeg=t,this.activeConnId=t.connId,this.nodePool.clear(),this.ripChain.clear(),this.heap.clear(),this.seqCounter=0,this.searchIterations=0,this.nextStamp();const e=this.computeH(t.startZ,t.startCellId,t.endZ,t.endCellId)*this.hyperParameters.greedyMultiplier,n=this.nodePool.push(t.startZ,t.startCellId,0,-1,-1,0),o=t.startZ*this.planeSize+t.startCellId,i=this.getSearchStateIdx(o,0);return this.bestGStamp[i]=this.stamp,this.bestGValue[i]=0,void this.heap.push(e,this.seqCounter++,n)}this.searchIterations++;const t=this.ripCount[this.activeConnId]??0,e=Math.round(this.baseSearchBudgetIters*(1+.25*Math.min(t,10)));if(this.searchIterations\u003ee){const t=this.penalty2d;for(let e=0;e\u003ct.length;e++)t[e]=.9*t[e];return this.unsolvedSegs.push(this.activeConnSeg),this.activeConnSeg=null,this.activeConnId=-1,this.heap.clear(),this.nodePool.clear(),this.consecutiveSkips++,void(this.consecutiveSkips\u003e=Math.max(3,3*this.unsolvedSegs.length)\u0026\u0026(this.error=`Convergence failure: ${this.unsolvedSegs.length} connections stuck`,this.failed=!0))}if(0===this.heap.size)return this.error=`No path found for ${this.connIdToName[this.activeConnId]}`,void(this.failed=!0);const n=this.heap.pop(),o=this.nodePool.z[n],i=this.nodePool.cellId[n],r=this.nodePool.g[n],s=this.nodePool.ripHead[n],a=this.nodePool.ripCount[n],c=o*this.planeSize+i,l=this.getSearchStateIdx(c,a);if(this.visitedStamp[l]===this.stamp)return;this.visitedStamp[l]=this.stamp,this.visitedFlatStamp[c]=this.stamp;const d=this.activeConnSeg;if(o===d.endZ\u0026\u0026i===d.endCellId)return this.finalizeRoute(n),this.activeConnSeg=null,void(this.activeConnId=-1);const h=this.visitedStamp,u=this.stamp,p=this.activeConnId,m=d.endZ,g=d.endCellId,f=this.neighborOffset[i],y=this.neighborOffset[i+1];for(let t=f;t\u003cy;t++){const e=this.neighborIds[t],c=o*this.planeSize+e;if(this.computeMoveCostAndRips(p,o,i,e,!1,s,a,this.neighborCosts[t]),this._moveCost\u003c0)continue;const l=this.getSearchStateIdx(c,this._moveRipCount);if(h[l]===u)continue;const d=r+this._moveCost;if(this.bestGStamp[l]===u\u0026\u0026d\u003e=this.bestGValue[l])continue;this.bestGStamp[l]=u,this.bestGValue[l]=d;const f=d+this.computeH(o,e,m,g)*this.hyperParameters.greedyMultiplier,y=this.nodePool.push(o,e,d,n,this._moveRippedHead,this._moveRipCount);this.heap.push(f,this.seqCounter++,y)}if(this.viaAllowed[i])for(let t=0;t\u003cthis.layers;t++){if(t===o)continue;const e=t*this.planeSize+i;if(this.computeMoveCostAndRips(p,t,i,i,!0,s,a,0),this._moveCost\u003c0)continue;const c=this.getSearchStateIdx(e,this._moveRipCount);if(h[c]===u)continue;const l=r+this._moveCost;if(this.bestGStamp[c]===u\u0026\u0026l\u003e=this.bestGValue[c])continue;this.bestGStamp[c]=u,this.bestGValue[c]=l;const d=l+this.computeH(t,i,m,g)*this.hyperParameters.greedyMultiplier,f=this.nodePool.push(t,i,l,n,this._moveRippedHead,this._moveRipCount);this.heap.push(d,this.seqCounter++,f)}}computeMoveCostAndRips(t,e,n,o,i,r,s,a){let c=0,l=r,d=s;const h=e*this.planeSize+o,u=i?this.obstacleViaRootIdsByCell[o]:[...this.obstacleTraceRootIdsFlat[e*this.planeSize+n]??[],...this.obstacleTraceRootIdsFlat[h]??[]];if(this.isBlockedByObstacleRoots(u,t)\u0026\u0026(i?this.isViaMoveBlockedByObstacleGeometry({activeConn:t,cellId:o}):this.isLateralMoveBlockedByObstacleGeometry({activeConn:t,layer:e,fromCellId:n,toCellId:o})))return this._moveCost=-1,this._moveRippedHead=l,void(this._moveRipCount=d);const p=this.hasSameRootObstacle(u,t);if(i){c+=this.hyperParameters.viaBaseCost,c+=Math.min(this.penalty2d[o],this.penaltyCap);const n=this.portOwnerFlat[h],i=this.allowSharedUse(t,n),r=this.activeConnSeg,s=!!r\u0026\u0026e===r.endZ\u0026\u0026o===r.endCellId;if(n\u003e=0\u0026\u0026n!==t\u0026\u0026!i\u0026\u0026!s)return this._moveCost=-1,void(this._moveRippedHead=l);this.fillViaOccupants(o,t);const a=this._viaOccs;for(let t=0;t\u003ca.length;t++){const e=a[t];this.ripChain.contains(l,e)||(c+=this.hyperParameters.ripCost,l=this.ripChain.append(l,e),d++),c+=this.hyperParameters.ripViaPenalty}}else{c+=a,c+=Math.min(this.penalty2d[o],this.penaltyCap);const n=this.portOwnerFlat[h],i=this.allowSharedUse(t,n),r=this.activeConnSeg,s=!!r\u0026\u0026e===r.endZ\u0026\u0026o===r.endCellId;if(n\u003e=0\u0026\u0026n!==t\u0026\u0026!i\u0026\u0026!s)return this._moveCost=-1,void(this._moveRippedHead=l);this.fillTraceOccupants(h,t,this._cellOccs);for(let t=0;t\u003cthis._cellOccs.length;t++){const e=this._cellOccs[t];this.ripChain.contains(l,e)||(c+=this.hyperParameters.ripCost,l=this.ripChain.append(l,e),d++),c+=this.hyperParameters.ripTracePenalty}}p\u0026\u0026(c*=this.hyperParameters.sameRootObstacleCostMultiplier),this._moveCost=c,this._moveRippedHead=l,this._moveRipCount=d}fillViaOccupants(t,e){const n=this._viaOccs;n.length=0;const o=this.cellCenterX[t],i=this.cellCenterY[t];this.forEachCellNearCircle(o,i,this.viaKeepoutRadius,t=\u003e{if(vQ(o,i,this.viaKeepoutRadius,this.cellMinX[t],this.cellMinY[t],this.cellMaxX[t],this.cellMaxY[t]))for(let o=0;o\u003cthis.layers;o++)this.pushFlatOccupants(o*this.planeSize+t,e,n)})}fillTraceOccupants(t,e,n){n.length=0,this.pushFlatOccupants(t,e,n)}pushFlatOccupants(t,e,n){const o=this.usedCellsFlat[t];-1===o||o===e||this.allowSharedUse(e,o)||bQ(n,o);const i=this.sharedCellsFlat[t];if(i)for(let t=0;t\u003ci.length;t++){const o=i[t];o!==e\u0026\u0026(this.allowSharedUse(e,o)||bQ(n,o))}}addSharedOccupant(t,e){if(this.usedCellsFlat[t]===e)return;let n=this.sharedCellsFlat[t];n||(n=[],this.sharedCellsFlat[t]=n),bQ(n,e)}replaceOccupants(t,e){this.usedCellsFlat[t]=e,this.sharedCellsFlat[t]=void 0}removeOccupant(t,e){const n=this.sharedCellsFlat[t];if(this.usedCellsFlat[t]===e)return void(n\u0026\u0026n.length\u003e0?(this.usedCellsFlat[t]=n.pop(),0===n.length\u0026\u0026(this.sharedCellsFlat[t]=void 0)):this.usedCellsFlat[t]=-1);if(!n)return;const o=n.indexOf(e);-1!==o\u0026\u0026(n.splice(o,1),0===n.length\u0026\u0026(this.sharedCellsFlat[t]=void 0))}allowSharedUse(t,e){if(e\u003c0)return!1;return this.connIdToRootNet[e]===this.connIdToRootNet[t]}shouldSkipFixedPortHalo(t,e){const n=this.portOwnerFlat[t];return n!==e\u0026\u0026(-2===n||!(n\u003c0)\u0026\u0026!this.allowSharedUse(e,n))}nextStamp(){this.stamp=this.stamp+1\u003e\u003e\u003e0,0===this.stamp\u0026\u0026(this.visitedStamp.fill(0),this.bestGStamp.fill(0),this.visitedFlatStamp.fill(0),this.stamp=1)}getSearchStateIdx(t,e){return t}computeH(t,e,n,o){const i=Math.hypot(this.cellCenterX[e]-this.cellCenterX[o],this.cellCenterY[e]-this.cellCenterY[o]);return t===n?i:i+this.hyperParameters.viaBaseCost}internConn(t,e){const n=this.connNameToId.get(t);if(void 0!==n)return n;const o=this.connIdToName.length;return this.connIdToName.push(t),this.connIdToRootNet.push(gQ(t,e)),this.connNameToId.set(t,o),o}buildConnectionSegs(){const t=new Map;for(const e of this.nodeWithPortPoints.portPoints){const n=e.connectionName;t.has(n)||t.set(n,{points:[],rootConnectionName:e.rootConnectionName}),t.get(n).points.push(e)}const e=[],n=new Map;for(const[o,i]of t){const t=i.points,r=lQ(t);if(0===r.length)continue;const s=this.internConn(o,i.rootConnectionName);for(const[t,i]of r){const r=this.pointToCell(t),a=this.pointToCell(i),c=`${r.z}:${r.cellId}`,l=`${a.z}:${a.cellId}`,d=c\u003cl?`${c}|${l}`:`${l}|${c}`,h=this.connIdToRootNet[s],u=`${h}|${d}`,p=n.get(u);if(p){if(this.overlapFriendlyRootNets.add(h),!p.connectionAliases.some(t=\u003et.connectionName===o)){const e=p.startZ===r.z\u0026\u0026p.startCellId===r.cellId\u0026\u0026p.endZ===a.z\u0026\u0026p.endCellId===a.cellId,n=p.startZ===a.z\u0026\u0026p.startCellId===a.cellId\u0026\u0026p.endZ===r.z\u0026\u0026p.endCellId===r.cellId;if(!e\u0026\u0026!n)throw new Error(`Connection alias ${o} does not match canonical segment ${u}`);p.connectionAliases.push({connectionName:o,rootConnectionName:h,startPoint:t,endPoint:i,reversedFromCanonical:!e\u0026\u0026n})}continue}const m={connId:s,startZ:r.z,startCellId:r.cellId,startPoint:t,endZ:a.z,endCellId:a.cellId,endPoint:i,connectionAliases:[{connectionName:o,rootConnectionName:h,startPoint:t,endPoint:i,reversedFromCanonical:!1}]};n.set(u,m),e.push(m)}}return e}pointToCell(t){const e=_Q(Math.floor((t.x-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),n=_Q(Math.floor((t.y-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1);let o=4;e\u003cthis.bandCols?o=0:e\u003e=this.fineCols-this.bandCols?o=2:n\u003cthis.bandRows?o=1:n\u003e=this.fineRows-this.bandRows\u0026\u0026(o=3);const i=this.regions[o],r=n-i.fineOriginRow,s=e-i.fineOriginCol,a=_Q(Math.floor(r/i.cellScale),0,Math.max(0,i.rows-1)),c=_Q(Math.floor(s/i.cellScale),0,Math.max(0,i.cols-1));return{z:this.zToLayer.get(t.z)??0,cellId:this.cellIdFor(o,a,c)}}shuffleConnections(){const t=this.unsolvedSegs;let e=this.hyperParameters.shuffleSeed\u003e\u003e\u003e0;const n=()=\u003e(e=Math.imul(e,1664525)+1013904223\u003e\u003e\u003e0,e/4294967295);for(let e=t.length-1;e\u003e0;e--){const o=Math.floor(n()*(e+1)),i=t[e];t[e]=t[o],t[o]=i}}finalizeRoute(t){this.consecutiveSkips=Math.max(0,this.consecutiveSkips-1);const e=[];let n=t;for(;n\u003e=0;){const t=this.nodePool.z[n],o=this.nodePool.cellId[n];e.push(t*this.planeSize+o),n=this.nodePool.parent[n]}for(e.reverse();e.length\u003e1\u0026\u0026this.sharedCrossRootPortFlat[e[0]];)e.shift();for(;e.length\u003e1\u0026\u0026this.sharedCrossRootPortFlat[e[e.length-1]];)e.pop();const o=this.extractViaCellIds(e),i=this.activeConnId;this.ripChain.collect(this.nodePool.ripHead[t],this._rippedIds);for(let t=0;t\u003cthis._rippedIds.length;t++)if(this.ripTrace(this._rippedIds[t]),this.failed)return;const r=[];for(let t=0;t\u003ce.length;t++){const n=e[t],o=Math.floor(n/this.planeSize),s=n-o*this.planeSize;this.markTraceFootprint(i,o,s,r)}const s=[];for(let t=0;t\u003co.length;t++)this.markViaFootprint(i,o[t],r,s);for(;this.usedIndicesByConn.length\u003c=i;)this.usedIndicesByConn.push(void 0);const a=this.usedIndicesByConn[i]??[];for(a.push(...r),this.usedIndicesByConn[i]=a;this.solvedRoutes.length\u003c=i;)this.solvedRoutes.push(void 0);const c=this.solvedRoutes[i]??[];c.push({connId:i,states:Int32Array.from(e),viaCellIds:Int32Array.from(o),startPoint:this.activeConnSeg.startPoint,endPoint:this.activeConnSeg.endPoint,connectionAliases:this.activeConnSeg.connectionAliases}),this.solvedRoutes[i]=c;for(let t=0;t\u003cs.length;t++)if(this.ripTrace(s[t]),this.failed)return;if(this._rippedIds.length\u003e0||s.length\u003e0){const t=this.penalty2d,e=this.penaltyCap;if(this.totalRipEvents\u003e50)for(let e=0;e\u003ct.length;e++)t[e]=.99*t[e];else for(let n=0;n\u003ct.length;n++)t[n]\u003ee\u0026\u0026(t[n]=.5*t[n])}}extractViaCellIds(t){const e=[];for(let n=1;n\u003ct.length;n++){const o=t[n-1],i=t[n],r=Math.floor(o/this.planeSize),s=Math.floor(i/this.planeSize);r!==s\u0026\u0026e.push(i-s*this.planeSize)}return e}markTraceFootprint(t,e,n,o){const i=this.cellCenterX[n],r=this.cellCenterY[n];this.forEachCellNearCircle(i,r,this.traceKeepoutRadius,s=\u003e{if(!vQ(i,r,this.traceKeepoutRadius,this.cellMinX[s],this.cellMinY[s],this.cellMaxX[s],this.cellMaxY[s]))return;const a=e*this.planeSize+s;if(s!==n\u0026\u0026this.shouldSkipFixedPortHalo(a,t))return;const c=this.usedCellsFlat[a],l=this.allowSharedUse(t,c);(-1===c||c===t||l)\u0026\u0026(-1!==c\u0026\u0026c!==t?this.addSharedOccupant(a,t):this.usedCellsFlat[a]=t,o.push(a))})}markViaFootprint(t,e,n,o){const i=this.cellCenterX[e],r=this.cellCenterY[e];this.forEachCellNearCircle(i,r,this.viaKeepoutRadius,s=\u003e{if(vQ(i,r,this.viaKeepoutRadius,this.cellMinX[s],this.cellMinY[s],this.cellMaxX[s],this.cellMaxY[s]))for(let i=0;i\u003cthis.layers;i++){const r=i*this.planeSize+s;if(s!==e\u0026\u0026this.shouldSkipFixedPortHalo(r,t))continue;if(this.fillTraceOccupants(r,t,this._cellOccs),this._cellOccs.length\u003e0){for(let t=0;t\u003cthis._cellOccs.length;t++)bQ(o,this._cellOccs[t]);this.replaceOccupants(r,t),n.push(r);continue}const a=this.usedCellsFlat[r];-1!==a\u0026\u0026a!==t?this.addSharedOccupant(r,t):this.usedCellsFlat[r]=t,n.push(r)}})}forEachCellNearCircle(t,e,n,o){const i=_Q(Math.floor((t-n-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),r=_Q(Math.floor((t+n-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),s=_Q(Math.floor((e-n-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1),a=_Q(Math.floor((e+n-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1);for(let t=0;t\u003cthis.regions.length;t++){const e=this.regions[t];if(0===e.rows||0===e.cols)continue;const n=Math.max(s,e.fineOriginRow),c=Math.min(a,e.fineOriginRow+e.fineRows-1),l=Math.max(i,e.fineOriginCol),d=Math.min(r,e.fineOriginCol+e.fineCols-1);if(n\u003ec)continue;if(l\u003ed)continue;const h=Math.floor((n-e.fineOriginRow)/e.cellScale),u=Math.floor((c-e.fineOriginRow)/e.cellScale),p=Math.floor((l-e.fineOriginCol)/e.cellScale),m=Math.floor((d-e.fineOriginCol)/e.cellScale);for(let t=h;t\u003c=u;t++)for(let n=p;n\u003c=m;n++)o(this.cellIdFor(e.id,t,n))}}ripTrace(t){for(;this.ripCount.length\u003c=t;)this.ripCount.push(0);if(this.ripCount[t]++,this.totalRipEvents++,this.totalRipEvents\u003e=this.MAX_RIPS)return this.error=`Convergence failure: exceeded MAX_RIPS ${this.MAX_RIPS}`,void(this.failed=!0);const e=this.getSolvedRoutesForConn(t);if(e.length\u003e0)for(const t of e){for(let e=0;e\u003ct.states.length;e++){const n=t.states[e]%this.planeSize;this.penalty2d[n]=this.penalty2d[n]+this.hyperParameters.ripTracePenalty}for(let e=0;e\u003ct.viaCellIds.length;e++){const n=t.viaCellIds[e];this.penalty2d[n]=this.penalty2d[n]+this.hyperParameters.ripViaPenalty}}const n=this.usedIndicesByConn[t];if(n){for(let e=0;e\u003cn.length;e++)this.removeOccupant(n[e],t);this.usedIndicesByConn[t]=void 0}if(e.length\u003e0){this.solvedRoutes[t]=void 0;for(const n of e){const e=n.states[0],o=n.states[n.states.length-1],i=Math.floor(e/this.planeSize),r=Math.floor(o/this.planeSize);this.unsolvedSegs.push({connId:t,startZ:i,startCellId:e-i*this.planeSize,startPoint:n.startPoint,endZ:r,endCellId:o-r*this.planeSize,endPoint:n.endPoint,connectionAliases:n.connectionAliases})}}}flattenNeighborLists(t){const e=new Int32Array(t.length+1);let n=0;for(let o=0;o\u003ct.length;o++)e[o]=n,n+=t[o].length;e[t.length]=n;const o=new Int32Array(n),i=new Float32Array(n);let r=0;for(let e=0;e\u003ct.length;e++){const n=t[e];for(let t=0;t\u003cn.length;t++){const e=n[t];o[r]=e.cellId,i[r]=e.cost,r++}}return{offset:e,ids:o,costs:i}}visualize(){const t=[\"red\",\"blue\",\"orange\",\"green\"],e=this.gridToBoundsTransform,n=[],o=[],i=[],r=[];r.push({center:{x:this.nodeWithPortPoints.center.x,y:this.nodeWithPortPoints.center.y},width:this.nodeWithPortPoints.width,height:this.nodeWithPortPoints.height,stroke:\"gray\"});const s=({route:e,connectionName:n,strokeWidth:i,strokeDash:r,labelPrefix:s})=\u003e{if(e.length\u003c2)return;let a=0;for(let c=1;c\u003ce.length;c+=1){const l=e[c-1];e[c].z!==l.z\u0026\u0026(c-a\u003e=2\u0026\u0026o.push({points:e.slice(a,c).map(t=\u003e({x:t.x,y:t.y})),strokeColor:t[l.z]??\"rgba(128,128,128,0.75)\",strokeWidth:i,strokeDash:r,label:`${s} ${n} z=${l.z}`}),a=c)}if(e.length-a\u003c2)return;const c=e[a].z;o.push({points:e.slice(a).map(t=\u003e({x:t.x,y:t.y})),strokeColor:t[c]??\"rgba(128,128,128,0.75)\",strokeWidth:i,strokeDash:r,label:`${s} ${n} z=${c}`})};for(const t of this.obstacles)if(\"rect\"!==t.type){s({route:t.route,connectionName:t.connectionName,strokeWidth:t.traceThickness,strokeDash:[.12,.08],labelPrefix:\"fixed obstacle\"});for(const e of t.vias)i.push({center:{x:e.x,y:e.y},radius:t.viaDiameter/2,fill:\"rgba(128,0,128,0.25)\",stroke:\"purple\",label:`fixed obstacle ${t.connectionName} via`})}else r.push({center:t.center,width:t.width,height:t.height,fill:\"rgba(128,0,128,0.12)\",stroke:\"purple\",label:`fixed obstacle ${t.connectionName}`});if(this.showPenaltyMap\u0026\u0026this.penalty2d){let t=0;for(let e=0;e\u003cthis.penalty2d.length;e++)this.penalty2d[e]\u003et\u0026\u0026(t=this.penalty2d[e]);if(t\u003e0)for(let n=0;n\u003cthis.planeSize;n++){const o=this.penalty2d[n];if(o\u003c=0)continue;const i=iQ(e,{x:this.cellCenterX[n],y:this.cellCenterY[n]}),s=Math.min(.6,o/t*.6);r.push({center:i,width:this.cellWidth[n]*e.a,height:this.cellHeight[n]*e.e,fill:`rgba(255,165,0,${s.toFixed(3)})`})}}if(this.showUsedCellMap\u0026\u0026this.usedCellsFlat)for(let t=0;t\u003cthis.layers;t++){const n=t*this.planeSize;for(let t=0;t\u003cthis.planeSize;t++){if(-1===this.usedCellsFlat[n+t])continue;const o=iQ(e,{x:this.cellCenterX[t],y:this.cellCenterY[t]});r.push({center:o,width:this.cellWidth[t]*e.a,height:this.cellHeight[t]*e.e,fill:\"rgba(0,0,255,0.5)\"})}}for(const e of this.nodeWithPortPoints.portPoints)n.push({x:e.x,y:e.y,color:t[e.z]??\"gray\",label:e.connectionName});const a=this.getOutput();for(const t of a)s({route:t.route,connectionName:t.connectionName,strokeWidth:this.traceThickness,labelPrefix:\"B01 route\"});for(const t of a)for(const e of t.vias)i.push({center:{x:e.x,y:e.y},radius:this.viaDiameter/2,fill:\"rgba(0,0,0,0.3)\",stroke:\"black\",label:`B01 route ${t.connectionName} via`});if(this.activeConnSeg\u0026\u0026this.visitedFlatStamp){const t=this.stamp;for(let o=0;o\u003cthis.layers;o++){const i=o*this.planeSize;for(let o=0;o\u003cthis.planeSize;o++){if(this.visitedFlatStamp[i+o]!==t)continue;const r=iQ(e,{x:this.cellCenterX[o],y:this.cellCenterY[o]});n.push({x:r.x,y:r.y,color:\"rgba(0,0,255,0.2)\"})}}}return{points:n,lines:o,circles:i,rects:r,coordinateSystem:\"cartesian\",title:`HighDensityB01 [${this.getSolvedRouteCount()} solved, ${this.unsolvedSegs?.length??0} remaining]`}}getOutput(){const t=this.gridToBoundsTransform,e=[];for(let n=0;n\u003cthis.solvedRoutes.length;n++){const o=this.getSolvedRoutesForConn(n);if(0!==o.length)for(const n of o){const o=Array.from(n.states,e=\u003e{const n=Math.floor(e/this.planeSize),o=e-n*this.planeSize,i=iQ(t,{x:this.cellCenterX[o],y:this.cellCenterY[o]});return{x:i.x,y:i.y,z:this.layerToZ.get(n)??n}}),i=Array.from(n.viaCellIds,e=\u003eiQ(t,{x:this.cellCenterX[e],y:this.cellCenterY[e]}));for(const t of n.connectionAliases){const n=(t.reversedFromCanonical?[...o].reverse():o).map(t=\u003e({...t}));n.length\u003e0\u0026\u0026(n[0]={...t.startPoint},n.length\u003e1\u0026\u0026(n[n.length-1]={...t.endPoint})),e.push({connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,regionId:this.nodeWithPortPoints.capacityMeshNodeId,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,route:n,vias:i.map(t=\u003e({...t}))})}}}return e}getSolvedRoutesForConn(t){const e=this.solvedRoutes[t];return e?Array.isArray(e)?e:[e]:[]}getSolvedRouteCount(){let t=0;for(let e=0;e\u003cthis.solvedRoutes.length;e++)t+=this.getSolvedRoutesForConn(e).length;return t}computeGridToBoundsTransform(){let t=1/0,e=-1/0,n=1/0,o=-1/0;for(let i=0;i\u003cthis.planeSize;i++){const r=this.cellCenterX[i],s=this.cellCenterY[i];r\u003ct\u0026\u0026(t=r),r\u003ee\u0026\u0026(e=r),s\u003cn\u0026\u0026(n=s),s\u003eo\u0026\u0026(o=s)}const i=e-t,r=o-n,s=this.boundsMaxX-this.boundsMinX,a=this.boundsMaxY-this.boundsMinY,c=i\u003e0?s/i:1,l=r\u003e0?a/r:1;return{a:c,b:0,c:i\u003e0?this.boundsMinX-c*t:(this.boundsMinX+this.boundsMaxX)/2-t,d:0,e:l,f:r\u003e0?this.boundsMinY-l*n:(this.boundsMinY+this.boundsMaxY)/2-n}}},RQ=new WeakMap,EQ=t=\u003e{const e=RQ.get(t);if(e)return e;const n=[],o=[];for(let e=1;e\u003ct.route.length;e++){const i=t.route[e-1],r=t.route[e],s=Math.hypot(r.x-i.x,r.y-i.y),a=Math.max(i.traceThickness??t.traceThickness,r.traceThickness??t.traceThickness);if(i.z!==r.z\u0026\u0026\"through_obstacle\"===i.toNextSegmentType){const e=Math.min(i.z,r.z),c=Math.max(i.z,r.z);if(s\u003c=1e-9){const n=t.vias.some(t=\u003eMath.hypot(t.x-r.x,t.y-r.y)\u003c=1e-9);o.push({center:{x:r.x,y:r.y},minZ:e,maxZ:c,diameter:n?t.viaDiameter:a});continue}for(let t=e;t\u003c=c;t++)n.push({start:{...i,z:t},end:{...r,z:t},z:t,width:a});continue}s\u003e1e-9\u0026\u0026n.push({start:i,end:i.z===r.z?r:{...r,z:i.z},z:i.z,width:a}),i.z!==r.z\u0026\u0026o.push({center:{x:r.x,y:r.y},minZ:Math.min(i.z,r.z),maxZ:Math.max(i.z,r.z),diameter:t.viaDiameter})}const i={wireSegments:n,viaSpans:o};return RQ.set(t,i),i},AQ=(t,e,n)=\u003e{const o=t.end.x-t.start.x,i=t.end.y-t.start.y,r=Math.hypot(o,i),s={x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2};return Math.abs(o)\u003c=1e-9||Math.abs(i)\u003c=1e-9?[{center:s,width:Math.abs(o)\u003eMath.abs(i)?r:t.width,height:Math.abs(o)\u003eMath.abs(i)?t.width:r}]:rX({center:s,width:r,height:t.width,rotation:180*Math.atan2(i,o)/Math.PI},Math.max(n,Math.ceil(r/e)))},OQ=({fixedObstacleRoutes:t,layerCount:e})=\u003et.flatMap((t,n)=\u003e{const o=[t.connectionName,t.rootConnectionName].filter(t=\u003e\"string\"==typeof t),i=EQ(t);return[...i.wireSegments.flatMap((t,i)=\u003eAQ(t,.75,2).map((r,s)=\u003e({obstacleId:`pipeline9_fixed_obstacle_${n}_wire_${i}_${s}`,type:\"rect\",layers:[vo(t.z,e)],center:r.center,width:r.width,height:r.height,connectedTo:o}))),...i.viaSpans.map((t,i)=\u003e({obstacleId:`pipeline9_fixed_obstacle_${n}_via_${i}`,type:\"rect\",layers:Array.from({length:t.maxZ-t.minZ+1},(n,o)=\u003evo(t.minZ+o,e)),center:t.center,width:t.diameter,height:t.diameter,connectedTo:o}))]}),kQ=(t,e,n)=\u003e{const o=[t.connectionName,t.rootConnectionName].filter(t=\u003e\"string\"==typeof t),i=[e.connectionName,e.rootConnectionName].filter(t=\u003e\"string\"==typeof t);return o.some(t=\u003ei.some(e=\u003et===e||n.areIdsConnected(t,e)))},LQ=(t,e)=\u003et.minX\u003c=e.maxX\u0026\u0026t.maxX\u003e=e.minX\u0026\u0026t.minY\u003c=e.maxY\u0026\u0026t.maxY\u003e=e.minY,DQ=({left:t,right:e,clearance:n,leftBounds:o})=\u003e{const i=EQ(t),r=EQ(e),s=o?i.wireSegments.filter(t=\u003e((t,e)=\u003e{const n={minX:Math.min(t.start.x,t.end.x)-t.width/2,maxX:Math.max(t.start.x,t.end.x)+t.width/2,minY:Math.min(t.start.y,t.end.y)-t.width/2,maxY:Math.max(t.start.y,t.end.y)+t.width/2};return LQ(n,e)})(t,o)):i.wireSegments,a=o?i.viaSpans.filter(t=\u003e((t,e)=\u003e{const n={minX:t.center.x-t.diameter/2,maxX:t.center.x+t.diameter/2,minY:t.center.y-t.diameter/2,maxY:t.center.y+t.diameter/2};return LQ(n,e)})(t,o)):i.viaSpans;for(const t of s){for(const e of r.wireSegments){if(t.z!==e.z)continue;const o=t.width/2+e.width/2+n;if(Ra(t.start,t.end,e.start,e.end)\u003co)return!0}for(const e of r.viaSpans){if(t.z\u003ce.minZ||t.z\u003ee.maxZ)continue;const o=t.width/2+e.diameter/2+n;if(Ra(t.start,t.end,e.center,e.center)\u003co)return!0}}for(const t of a){for(const e of r.wireSegments){if(e.z\u003ct.minZ||e.z\u003et.maxZ)continue;const o=t.diameter/2+e.width/2+n;if(Ra(t.center,t.center,e.start,e.end)\u003co)return!0}for(const e of r.viaSpans){if(t.minZ\u003ee.maxZ||e.minZ\u003et.maxZ)continue;const o=t.diameter/2+e.diameter/2+n;if(Math.hypot(t.center.x-e.center.x,t.center.y-e.center.y)\u003co)return!0}}return!1},zQ=({routes:t,movablePreloadedConnectionNames:e,boardObstacles:n,connMap:o,layerCount:i,viaToPadClearance:r})=\u003et.some(t=\u003e{if(!e.has(t.connectionName))return!1;return EQ(t).viaSpans.some(e=\u003en.some(n=\u003e{if(fo(n,t,o))return!1;const s=((t,e)=\u003e{const n=t.__zLayers??t.zLayers;return n||t.layers.map(t=\u003eko(t,e))})(n,i);return!!s.some(t=\u003et\u003e=e.minZ\u0026\u0026t\u003c=e.maxZ)\u0026\u0026((t,e)=\u003e{const n=-1*(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y,r=o*Math.cos(n)-i*Math.sin(n),s=o*Math.sin(n)+i*Math.cos(n),a=Math.max(Math.abs(r)-e.width/2,0),c=Math.max(Math.abs(s)-e.height/2,0);return Math.hypot(a,c)})(e.center,n)\u003ce.diameter/2+r}))}),FQ=class extends si{params;highDensitySolver;forceImproveSolver;repairSolver;phase=\"route\";constructor(t){super(),this.params=t,this.stats={preloadedViaCandidateRejectionCount:0,forceImproveCandidateRejectionCount:0,repairCandidateRejectionCount:0},this.highDensitySolver=new zs({nodePortPoints:[t.nodeWithPortPoints],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:t.nodePfById,obstacles:t.obstacles,layerCount:t.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!1,growShrinkFallbackToInvalidGeometryOnFailure:!1,growShrinkSolutionValidator:t.boardObstacles\u0026\u0026t.movablePreloadedConnectionNames\u0026\u0026void 0!==t.viaToPadClearance?t=\u003ethis.validateCandidateRoutes(t):void 0}),this.activeSubSolver=this.highDensitySolver,this.MAX_ITERATIONS=1e8*t.effort}getSolverName(){return\"Pipeline9RegionalFallbackSolver\"}validateCandidateRoutes(t){const{boardObstacles:e,movablePreloadedConnectionNames:n,viaToPadClearance:o}=this.params;if(!e||!n||void 0===o)return!0;const i=zQ({routes:t,movablePreloadedConnectionNames:n,boardObstacles:e,connMap:this.params.connMap,layerCount:this.params.layerCount,viaToPadClearance:o});return i\u0026\u0026(this.stats.preloadedViaCandidateRejectionCount=Number(this.stats.preloadedViaCandidateRejectionCount??0)+1),!i}_step(){if(\"route\"===this.phase){if(this.highDensitySolver.step(),this.highDensitySolver.failed)return this.error=this.highDensitySolver.error,void(this.failed=!0);if(!this.highDensitySolver.solved)return;const t=AK(this.highDensitySolver.routes);return this.validateCandidateRoutes(t)?(this.forceImproveSolver=new Yy({nodeWithPortPoints:[this.params.nodeWithPortPoints],hdRoutes:t,colorMap:this.params.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*this.params.effort)),nodeAssignmentMargin:this.params.obstacleMargin}),this.activeSubSolver=this.forceImproveSolver,void(this.phase=\"improve\")):(this.error=\"Pipeline9 regional route output failed its candidate validator\",void(this.failed=!0))}if(\"improve\"===this.phase){if(this.forceImproveSolver.step(),this.forceImproveSolver.failed)return this.error=this.forceImproveSolver.error,void(this.failed=!0);if(!this.forceImproveSolver.solved)return;const t=this.forceImproveSolver.getOutput();return this.validateCandidateRoutes(t)?(this.repairSolver=new AY({nodeWithPortPoints:[this.params.nodeWithPortPoints],hdRoutes:t,obstacles:this.params.obstacles,colorMap:this.params.colorMap,repairMargin:this.params.obstacleMargin,maxSampleEntries:80,connMap:this.params.connMap}),this.activeSubSolver=this.repairSolver,void(this.phase=\"repair\")):(this.stats.forceImproveCandidateRejectionCount=Number(this.stats.forceImproveCandidateRejectionCount??0)+1,this.error=\"Pipeline9 regional force-improve output failed its candidate validator\",void(this.failed=!0))}if(\"repair\"===this.phase){if(this.repairSolver.step(),this.repairSolver.failed)return this.error=this.repairSolver.error,void(this.failed=!0);if(!this.repairSolver.solved)return;const t=this.repairSolver.getOutput();return this.validateCandidateRoutes(t)?(this.activeSubSolver=null,this.phase=\"done\",void(this.solved=!0)):(this.stats.repairCandidateRejectionCount=Number(this.stats.repairCandidateRejectionCount??0)+1,this.error=\"Pipeline9 regional repair output failed its candidate validator\",void(this.failed=!0))}}getOutput(){return this.repairSolver?.getOutput()??this.forceImproveSolver?.getOutput()??this.highDensitySolver.routes}visualize(){return this.repairSolver?.visualize()??this.forceImproveSolver?.visualize()??this.highDensitySolver.visualize()}},BQ=(t,e)=\u003e({minX:t.center.x-t.width/2-e,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2-e,maxY:t.center.y+t.height/2+e}),jQ=(t,e,n)=\u003e{const o=Math.max(n.minX-t.x,0,t.x-n.maxX),i=Math.max(n.minY-t.y,0,t.y-n.maxY);return o*o+i*i\u003c=e*e},$Q=(t,e,n,o)=\u003eMath.min(t.x,e.x)-n\u003c=o.maxX\u0026\u0026Math.max(t.x,e.x)+n\u003e=o.minX\u0026\u0026Math.min(t.y,e.y)-n\u003c=o.maxY\u0026\u0026Math.max(t.y,e.y)+n\u003e=o.minY,YQ=(t,e)=\u003e{const n=t=\u003e({...t,rootConnectionName:e.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName});return{...t,portPoints:t.portPoints.map(n),portPointsInPairs:t.portPointsInPairs?.map(([t,e])=\u003e[n(t),n(e)])}},XQ=({nodeWithPortPoints:t,connMap:e,colorMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a,obstacles:c,layerCount:l})=\u003enew zs({nodePortPoints:[YQ(t,e)],colorMap:n,connMap:e,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a,obstacles:c,layerCount:l,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!1,growShrinkFallbackToInvalidGeometryOnFailure:!1,captureSearchDebug:!1}),VQ=class extends si{fixedHdRoutes;connMap;colorMap;obstacles;layerCount;viaDiameter;traceWidth;obstacleMargin;viaToPadClearance;effort;nodePfById;preserveTerminalPcbPortIds;includeBoardObstacles;enableRegionalFallback;maxB01Rips;routes=[];failedSolvers=[];unsolvedNodePortPoints;fixedRouteReplacements=new Map;removedFixedRouteConnectionNames=new Set;preloadedTraceMutationMasks=new Map;activeRegularSolver=null;activeB01Solver=null;activeFallbackSolver=null;activeFallbackFixedRouteSections=new Map;activeFallbackFixedObstacleRoutes=[];activeFallbackPromotedFixedRouteConnectionNames=new Set;activeFallbackReason=null;activeNode=null;constructor(t){super(),this.fixedHdRoutes=t.fixedHdRoutes,this.connMap=t.connMap,this.colorMap=t.colorMap??{},this.obstacles=t.obstacles,this.layerCount=t.layerCount,this.viaDiameter=t.viaDiameter,this.traceWidth=t.traceWidth,this.obstacleMargin=t.obstacleMargin,this.viaToPadClearance=t.viaToPadClearance,this.effort=t.effort,this.nodePfById=t.nodePfById instanceof Map?new Map(t.nodePfById):new Map(Object.entries(t.nodePfById??{})),this.preserveTerminalPcbPortIds=t.preserveTerminalPcbPortIds??!1,this.includeBoardObstacles=t.includeBoardObstacles??!1,this.enableRegionalFallback=t.enableRegionalFallback??!0,this.maxB01Rips=t.maxB01Rips,this.unsolvedNodePortPoints=[...t.nodePortPoints],this.MAX_ITERATIONS=1e8*this.effort,this.stats={nodeCount:t.nodePortPoints.length,solvedNodeCount:0,fixedObstacleCount:t.fixedHdRoutes.length,fixedObstacleUses:0,boardObstacleUses:0,fallbackNodeCount:0,regularNodeCount:0,b01NodeCount:0,reroutedFixedRouteCount:0,reroutedFixedRouteSectionCount:0,promotedFallbackAttemptCount:0,promotedFixedRouteCount:0,regionalPreloadedViaCandidateRejectionCount:0,regionalForceImproveCandidateRejectionCount:0,regionalRepairCandidateRejectionCount:0}}getSolverName(){return\"Pipeline9HighDensitySolver\"}getUpdatedFixedHdRoutes(){return this.fixedHdRoutes.flatMap(t=\u003ethis.removedFixedRouteConnectionNames.has(t.connectionName)?[]:[this.fixedRouteReplacements.get(t.connectionName)??t])}finishActiveNode(t){const e=this.activeNode?((t,e)=\u003et.map(t=\u003e({...t,rootConnectionName:e.portPoints.find(e=\u003ee.connectionName===t.connectionName)?.rootConnectionName??t.rootConnectionName})))(t,this.activeNode):t;this.routes.push(...this.preserveTerminalPcbPortIds\u0026\u0026this.activeNode?((t,e)=\u003e{const n=e.portPoints.filter(t=\u003evoid 0!==t.pcb_port_id);return t.map(t=\u003e{const e=t.route[0],o=t.route.at(-1),i=n.find(n=\u003evoid 0!==e\u0026\u0026n.connectionName===t.connectionName\u0026\u0026n.x===e.x\u0026\u0026n.y===e.y\u0026\u0026n.z===e.z),r=n.find(e=\u003evoid 0!==o\u0026\u0026e.connectionName===t.connectionName\u0026\u0026e.x===o.x\u0026\u0026e.y===o.y\u0026\u0026e.z===o.z);return{...t,startPcbPortId:i?.pcb_port_id,endPcbPortId:r?.pcb_port_id}})})(e,this.activeNode):e),this.stats.solvedNodeCount=Number(this.stats.solvedNodeCount??0)+1,this.activeB01Solver=null,this.activeRegularSolver=null,this.activeFallbackSolver=null,this.activeFallbackFixedRouteSections.clear(),this.activeFallbackFixedObstacleRoutes=[],this.activeFallbackPromotedFixedRouteConnectionNames.clear(),this.activeFallbackReason=null,this.activeNode=null}startRegularSolver(t){this.activeNode=t,this.activeRegularSolver=XQ({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById,obstacles:this.obstacles,layerCount:this.layerCount}),this.stats.regularNodeCount=Number(this.stats.regularNodeCount??0)+1}startRegionalFallback(t=new Set){if(!this.activeNode)throw new Error(\"Pipeline9 cannot start a regional fallback without an active node\");const e={...YQ(this.activeNode,this.connMap),availableZ:Array.from({length:this.layerCount},(t,e)=\u003ee)},n=$K(e,this.getUpdatedFixedHdRoutes(),t),o=new Set([...n.fixedRouteSectionsByConnectionName.values()].flatMap(t=\u003et.sourceRoutes.map(t=\u003et.connectionName)));for(const e of t)if(!o.has(e))throw new Error(`Pipeline9 could not promote fixed route \"${e}\" into the active regional fallback`);const i=[...t].filter(t=\u003e!this.activeFallbackPromotedFixedRouteConnectionNames.has(t)).length;this.activeFallbackFixedRouteSections=n.fixedRouteSectionsByConnectionName,this.activeFallbackFixedObstacleRoutes=n.fixedObstacleRoutes,this.activeFallbackPromotedFixedRouteConnectionNames=new Set(t);const r=OQ({fixedObstacleRoutes:this.activeFallbackFixedObstacleRoutes,layerCount:this.layerCount});this.activeFallbackSolver=new FQ({nodeWithPortPoints:n.nodeWithPortPoints,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById,obstacles:[...this.obstacles,...r],boardObstacles:this.obstacles,movablePreloadedConnectionNames:o,viaToPadClearance:this.viaToPadClearance,layerCount:this.layerCount}),0===t.size?this.stats.fallbackNodeCount=Number(this.stats.fallbackNodeCount??0)+1:(this.stats.promotedFallbackAttemptCount=Number(this.stats.promotedFallbackAttemptCount??0)+1,this.stats.promotedFixedRouteCount=Number(this.stats.promotedFixedRouteCount??0)+i)}finishRegionalFallback(){if(!this.activeFallbackSolver)return;if(!this.activeNode)throw new Error(\"Pipeline9 cannot finish a regional fallback without an active node\");this.recordRegionalCandidateRejections();const t=[],e=new Map;for(const n of this.activeFallbackSolver.getOutput()){if(!this.activeFallbackFixedRouteSections.has(n.connectionName)){t.push(n);continue}const o=e.get(n.connectionName)??[];o.push(n),e.set(n.connectionName,o)}const n=[],o=[];for(const[t,i]of this.activeFallbackFixedRouteSections){const r=e.get(t)??[];if(0===r.length){o.push(i);continue}if(r.length\u003e1)return this.error=`Pipeline9 regional fallback expected one replacement for fixed route \"${t}\", got ${r.length}`,void(this.failed=!0);const s=VK({section:i,replacement:r[0],sourceMutationMasks:this.preloadedTraceMutationMasks,replacementIsMutated:!0});n.push({connectionName:t,section:i,replacement:s.route,mutatedSegments:s.mutatedSegments,replacementProducedSegment:s.replacementProducedSegment})}const i=[...t,...n.map(({replacement:t})=\u003et)],r=[...this.activeFallbackFixedObstacleRoutes,...o.flatMap(t=\u003et.sourceRoutes)],s=BQ(this.activeNode,this.obstacleMargin+Math.max(this.traceWidth,this.viaDiameter)/2),a=new Map;for(const t of i)for(const e of r)kQ(t,e,this.connMap)||DQ({left:t,right:e,clearance:this.obstacleMargin,leftBounds:s})\u0026\u0026a.set(e.connectionName,e);if(a.size\u003e0){const t=[...a.keys()],e=[...a].flatMap(([t,e])=\u003e!0===e.isThroughObstacle?[]:[t]),n=new Set(this.activeFallbackPromotedFixedRouteConnectionNames);for(const t of e)n.add(t);if(n.size===this.activeFallbackPromotedFixedRouteConnectionNames.size){const e=[...a].flatMap(([t,e])=\u003e!0===e.isThroughObstacle?[t]:[]);return this.error=e.length\u003e0?`Pipeline9 regional fallback conflicts with immutable through-obstacle route(s): ${e.join(\", \")}`:`Pipeline9 promoted regional fallback could not resolve immutable fixed route conflict(s): ${t.join(\", \")}`,void(this.failed=!0)}return void this.startRegionalFallback(n)}const c=new Map;for(const{section:t,replacementProducedSegment:e}of n)if(e)for(const e of t.sourceRoutes){const t=e.preloadedRoutePositionStart,n=e.preloadedRoutePositionEnd;if(void 0===t!=(void 0===n))throw new Error(`Pipeline9 fixed route \"${e.connectionName}\" has incomplete route-position metadata`);const o=Math.min(t??e.preloadedRouteIndex,n??e.preloadedRouteIndex),i=Math.max(t??e.preloadedRouteIndex,n??e.preloadedRouteIndex),r=c.get(e.preloadedTraceIndex);c.set(e.preloadedTraceIndex,{start:Math.min(r?.start??o,o),end:Math.max(r?.end??i,i)})}for(const{connectionName:t,section:e,replacement:o,mutatedSegments:i}of n){this.fixedRouteReplacements.set(t,o),this.preloadedTraceMutationMasks.set(t,i);for(const t of e.sourceRoutes.slice(1))this.removedFixedRouteConnectionNames.add(t.connectionName),this.preloadedTraceMutationMasks.delete(t.connectionName)}const l=$K({...YQ(this.activeNode,this.connMap),portPoints:[],portPointsInPairs:[],availableZ:Array.from({length:this.layerCount},(t,e)=\u003ee)},this.getUpdatedFixedHdRoutes()),d=new Set;for(const t of l.fixedRouteSectionsByConnectionName.values()){const e=t.sourceRoutes[0];if(!e)continue;const n=c.get(e.preloadedTraceIndex);if(n)for(const[o,i]of t.sourceRoutes.entries()){const r=i.preloadedRoutePositionStart??i.preloadedRouteIndex,s=i.preloadedRoutePositionEnd??i.preloadedRouteIndex,a={start:Math.min(r,s),end:Math.max(r,s)},c=a.start===a.end,l=n.start===n.end;if(!(c||l?a.start\u003c=n.end\u0026\u0026n.start\u003c=a.end:a.start\u003cn.end\u0026\u0026n.start\u003ca.end))continue;d.add(e.preloadedTraceIndex);const h=[...this.preloadedTraceMutationMasks.get(i.connectionName)??Array(i.route.length-1).fill(!1)];if(h.length!==i.route.length-1)throw new Error(`Pipeline9 fixed route mutation mask for \"${i.connectionName}\" has ${h.length} segments, expected ${i.route.length-1}`);const u=0===o?t.start.segmentIndex:0,p=o===t.sourceRoutes.length-1?t.end.segmentIndex:i.route.length-2;for(let t=u;t\u003c=p;t++)h[t]=!0;this.preloadedTraceMutationMasks.set(i.connectionName,h)}}for(const t of c.keys())if(!d.has(t))throw new Error(`Pipeline9 could not capture accepted mutation provenance for trace ${t}`);const h=n.reduce((t,{section:e})=\u003et+e.sourceRoutes.length,0);this.stats.reroutedFixedRouteCount=Number(this.stats.reroutedFixedRouteCount??0)+h,this.stats.reroutedFixedRouteSectionCount=Number(this.stats.reroutedFixedRouteSectionCount??0)+n.length,this.finishActiveNode(t)}recordRegionalCandidateRejections(){if(!this.activeFallbackSolver)return;const t=this.activeFallbackSolver.stats;this.stats.regionalPreloadedViaCandidateRejectionCount=Number(this.stats.regionalPreloadedViaCandidateRejectionCount??0)+Number(t.preloadedViaCandidateRejectionCount??0),this.stats.regionalForceImproveCandidateRejectionCount=Number(this.stats.regionalForceImproveCandidateRejectionCount??0)+Number(t.forceImproveCandidateRejectionCount??0),this.stats.regionalRepairCandidateRejectionCount=Number(this.stats.regionalRepairCandidateRejectionCount??0)+Number(t.repairCandidateRejectionCount??0)}finishRegularSolverFailure(t){if(this.activeFallbackReason=`regular high-density routing failed: ${t}`,this.activeRegularSolver=null,!this.enableRegionalFallback)return this.error=`Pipeline9 ${this.activeFallbackReason}`,this.failed=!0,void(this.activeNode=null);this.startRegionalFallback()}_step(){if(this.activeFallbackSolver){if(this.activeFallbackSolver.step(),this.activeFallbackSolver.failed)return this.recordRegionalCandidateRejections(),this.error=[`Pipeline9 primary high-density routing failed: ${this.activeFallbackReason??\"unknown error\"}`,`regional fallback failed: ${this.activeFallbackSolver.error??\"unknown error\"}`].join(\"; \"),this.failed=!0,this.activeFallbackSolver=null,this.activeFallbackFixedRouteSections.clear(),this.activeFallbackFixedObstacleRoutes=[],this.activeFallbackPromotedFixedRouteConnectionNames.clear(),void(this.activeNode=null);if(!this.activeFallbackSolver.solved)return;return void this.finishRegionalFallback()}if(this.activeRegularSolver){if(this.activeRegularSolver.step(),this.activeRegularSolver.failed)return void this.finishRegularSolverFailure(this.activeRegularSolver.error??\"unknown error\");if(!this.activeRegularSolver.solved)return;return void this.finishActiveNode(this.activeRegularSolver.routes)}if(this.activeB01Solver){if(this.activeB01Solver.step(),this.activeB01Solver.failed)return this.failedSolvers.push(this.activeB01Solver),this.activeFallbackReason=`B01 failed: ${this.activeB01Solver.error??\"unknown error\"}`,this.activeB01Solver=null,this.enableRegionalFallback?void this.startRegionalFallback():(this.error=`Pipeline9 ${this.activeFallbackReason}`,this.failed=!0,void(this.activeNode=null));if(!this.activeB01Solver.solved)return;return void this.finishActiveNode(this.activeB01Solver.getOutput())}const t=this.unsolvedNodePortPoints.pop();if(!t)return void(this.solved=!0);const e=BQ(t,this.obstacleMargin),n=Math.max(this.traceWidth,this.viaDiameter)/2,o=this.getUpdatedFixedHdRoutes().filter(o=\u003e((t,e,n,o)=\u003e{const i=new Set(e.availableZ??e.portPoints.map(t=\u003et.z));for(let e=1;e\u003ct.route.length;e++){const r=t.route[e-1],s=t.route[e];if(r.z===s.z){if(i.has(r.z)\u0026\u0026$Q(r,s,t.traceThickness/2+o,n))return!0;continue}const a=Math.min(r.z,s.z),c=Math.max(r.z,s.z);if([...i].some(t=\u003et\u003e=a\u0026\u0026t\u003c=c)\u0026\u0026jQ(s,t.viaDiameter/2+o,n))return!0}return!1})(o,t,e,n)).flatMap(e=\u003e((t,e)=\u003e{const n=new Set(e.availableZ??e.portPoints.map(t=\u003et.z));if(0===n.size)throw new Error(`Pipeline9 B01 node \"${e.capacityMeshNodeId}\" has no available layers`);const o={type:\"route\",connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,traceThickness:t.traceThickness,viaDiameter:t.viaDiameter},i=[];for(let e=1;e\u003ct.route.length;e++){const r=t.route[e-1],s=t.route[e];if(r.z===s.z){if(!n.has(r.z))continue;i.push({...o,route:[r,s],vias:[]});continue}const a=Math.min(r.z,s.z),c=Math.max(r.z,s.z);[...n].some(t=\u003et\u003e=a\u0026\u0026t\u003c=c)\u0026\u0026i.push({...o,route:[r,s],vias:[{x:s.x,y:s.y,zStart:r.z,zEnd:s.z}]})}return i})(e,t));if(this.stats.fixedObstacleUses=Number(this.stats.fixedObstacleUses??0)+o.length,0===o.length)return void this.startRegularSolver(t);const i=(this.includeBoardObstacles?this.obstacles:[]).filter(t=\u003e((t,e)=\u003e{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.abs(Math.cos(n)),i=Math.abs(Math.sin(n)),r=t.width/2*o+t.height/2*i,s=t.width/2*i+t.height/2*o;return t.center.x-r\u003c=e.maxX\u0026\u0026t.center.x+r\u003e=e.minX\u0026\u0026t.center.y-s\u003c=e.maxY\u0026\u0026t.center.y+s\u003e=e.minY})(t,e)).map(e=\u003e(({obstacle:t,node:e,connMap:n,layerCount:o})=\u003e{const i=new Set(e.availableZ??e.portPoints.map(t=\u003et.z)),r=(t.zLayers??t.layers.map(t=\u003eko(t,o))).filter(t=\u003ei.has(t));if(0===r.length)return;const s=t.connectedTo[0]??t.obstacleId??`pipeline9_obstacle_${t.center.x}_${t.center.y}`;return{type:\"rect\",connectionName:s,rootConnectionName:n.getNetConnectedToId(s)??s,center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,zLayers:r}})({obstacle:e,node:t,connMap:this.connMap,layerCount:this.layerCount})).filter(t=\u003evoid 0!==t);if(this.stats.boardObstacleUses=Number(this.stats.boardObstacleUses??0)+i.length,this.activeNode=t,t.width\u003e15||t.height\u003e15)return this.activeFallbackReason=`B01 node \"${t.capacityMeshNodeId}\" exceeds the 15x15mm routing limit (${t.width}x${t.height}mm)`,void this.startRegionalFallback();const r=YQ(t,this.connMap);this.stats.b01NodeCount=Number(this.stats.b01NodeCount??0)+1,this.activeB01Solver=new TQ({...sQ,nodeWithPortPoints:r,obstacles:[...o,...i],viaDiameter:this.viaDiameter,viaMinDistFromBorder:this.viaDiameter/2,traceThickness:this.traceWidth,traceMargin:this.obstacleMargin,obstacleClearanceMargin:.15,effort:this.effort}),void 0!==this.maxB01Rips\u0026\u0026(this.activeB01Solver.MAX_RIPS=this.maxB01Rips)}visualize(){return this.activeFallbackSolver?.visualize()??this.activeRegularSolver?.visualize()??this.activeB01Solver?.visualize()??{lines:this.routes.flatMap(t=\u003et.route.slice(0,-1).map((e,n)=\u003e({points:[e,t.route[n+1]],strokeWidth:t.traceThickness,layer:`z${e.z}`,label:t.connectionName}))),points:[],rects:[],circles:[]}}},WQ=(t,e)=\u003e{const n=e*Math.PI/180;return{x:t.x*Math.cos(n)-t.y*Math.sin(n),y:t.x*Math.sin(n)+t.y*Math.cos(n)}},HQ=({x:t,y:e,width:n,height:o,ccwRotation:i})=\u003e{const r=n/2,s=o/2;return[{x:-r,y:-s},{x:r,y:-s},{x:r,y:s},{x:-r,y:s}].map(n=\u003e{const o=WQ(n,i);return{x:t+o.x,y:e+o.y}})},GQ=t=\u003e{const e=\"rotated_pill\"===t.shape?t.ccw_rotation:0,n=Math.max(Math.max(t.width,t.height)/2-t.radius,0),o=t.width\u003e=t.height?{x:n,y:0}:{x:0,y:n},i=WQ(o,e);return{start:{x:t.x-i.x,y:t.y-i.y},end:{x:t.x+i.x,y:t.y+i.y},radius:t.radius}},UQ=t=\u003e{if(\"pcb_smtpad\"===t.type){if(\"polygon\"===t.shape)return t.points;if(\"rotated_rect\"===t.shape)return HQ({x:t.x,y:t.y,width:t.width,height:t.height,ccwRotation:t.ccw_rotation})}if(\"pcb_plated_hole\"===t.type\u0026\u0026\"rect_pad_width\"in t\u0026\u0026\"rect_pad_height\"in t)return HQ({x:t.x,y:t.y,width:t.rect_pad_width,height:t.rect_pad_height,ccwRotation:\"rect_ccw_rotation\"in t\u0026\u0026\"number\"==typeof t.rect_ccw_rotation?t.rect_ccw_rotation:0});throw new Error(`Expected polygonal pad geometry, got ${t.type} with shape \"${t.shape}\"`)},ZQ=t=\u003et.map((e,n)=\u003e[e,t[(n+1)%t.length]]),qQ=(t,e,n,o)=\u003e{const i=ve(t,e,n,o);if(i)return{distance:0,pointOnA:i,pointOnB:i,center:i};const r=[{pointOnA:t,pointOnB:ze(t,n,o)},{pointOnA:e,pointOnB:ze(e,n,o)},{pointOnA:ze(n,t,e),pointOnB:n},{pointOnA:ze(o,t,e),pointOnB:o}];let s=r[0],a=Ye(s.pointOnA,s.pointOnB);for(const t of r.slice(1)){const e=Ye(t.pointOnA,t.pointOnB);e\u003ca\u0026\u0026(s=t,a=e)}return{distance:Oe(t,e,n,o),pointOnA:s.pointOnA,pointOnB:s.pointOnB,center:{x:(s.pointOnA.x+s.pointOnB.x)/2,y:(s.pointOnA.y+s.pointOnB.y)/2}}};function JQ(t,e){return Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2)}var KQ=1e-9,QQ=1e-9;function t0(t,e){const n=(t.y-e.start.y)*(e.end.x-e.start.x)-(t.x-e.start.x)*(e.end.y-e.start.y);if(Math.abs(n)\u003eKQ)return!1;const o=(t.x-e.start.x)*(e.end.x-e.start.x)+(t.y-e.start.y)*(e.end.y-e.start.y);if(o\u003c-1e-9)return!1;return o\u003c=(e.end.x-e.start.x)**2+(e.end.y-e.start.y)**2+KQ}function e0(t,e){let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];if(t0(t,{start:r,end:s}))return!0;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n}function n0(t,e){if(\"pcb_smtpad\"===e.type){if(\"circle\"===e.shape)return JQ(t,e)\u003c=e.radius+QQ;if(\"rect\"===e.shape){const n=e.width/2,o=e.height/2;return Math.abs(t.x-e.x)\u003c=n+QQ\u0026\u0026Math.abs(t.y-e.y)\u003c=o+QQ}if(\"rotated_rect\"===e.shape)return e0(t,UQ(e));if(\"pill\"===e.shape||\"rotated_pill\"===e.shape){if(\"rotated_pill\"===e.shape){const n=GQ(e);return be(t,n.start,n.end)\u003c=n.radius+QQ}const n=e.width/2,o=e.height/2,i=e.radius;if(Math.abs(t.x-e.x)\u003c=n-i+QQ\u0026\u0026Math.abs(t.y-e.y)\u003c=o+QQ)return!0;const r=Math.max(Math.abs(t.x-e.x)-(n-i),0),s=Math.max(Math.abs(t.y-e.y)-(o-i),0),a=i+QQ;return r*r+s*s\u003c=a*a}if(\"polygon\"===e.shape)return e0(t,e.points)}if(\"pcb_plated_hole\"===e.type){if(\"circle\"===e.shape)return JQ(t,e)\u003c=e.outer_diameter/2+QQ;if(\"rect_pad_width\"in e\u0026\u0026\"rect_pad_height\"in e)return e0(t,UQ(e));if(\"oval\"===e.shape||\"pill\"===e.shape)return Math.abs(t.x-e.x)\u003c=e.outer_width/2+QQ\u0026\u0026Math.abs(t.y-e.y)\u003c=e.outer_height/2+QQ}return!1}function o0(t,e,n,o){return Math.sqrt((n-t)**2+(o-e)**2)}var i0=.1,r0=.1,s0=.2,a0=.1,c0=.005,l0=t=\u003et.find(t=\u003e\"pcb_board\"===t.type),d0=(t,e)=\u003et?.[e],h0=t=\u003eEM([t]),u0=t=\u003e{const e=h0(t);return Math.min(e.maxX-e.minX,e.maxY-e.minY)/2},p0=t=\u003e{const e=(t=\u003e{const e=h0(t);return $e({x:e.minX,y:e.minY},{x:e.maxX,y:e.maxY})})(t);return{kind:\"circle\",x:e.x,y:e.y,radius:u0(t)}},m0=t=\u003evM(t).pcb_trace.list().flatMap(t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];\"wire\"===o.route_type\u0026\u0026(\"wire\"===i.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({type:\"pcb_trace_segment\",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:\"width\"in o?o.width:\"width\"in i?i.width:a0,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),g0=t=\u003e{const e=t._pcbTrace.route.flatMap(t=\u003e\"through_pad\"===t.route_type?[t.start,t.end]:[{x:t.x,y:t.y}]),n=e[0],o=e[e.length-1];return n\u0026\u0026o?$e(n,o):$e({x:t.x1,y:t.y1},{x:t.x2,y:t.y2})},f0=({tracePoint:t,obstaclePoint:e,traceRadius:n,obstacleRadius:o})=\u003e{const i=e.x-t.x,r=e.y-t.y,s=Math.hypot(i,r);if(0===s)return $e(t,e);const a=i/s,c=r/s;return $e({x:t.x+a*n,y:t.y+c*n},{x:e.x-a*o,y:e.y-c*o})},y0=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=t.thickness/2;if(\"pcb_via\"===e.type||(\"pcb_via\"===(r=e).type||\"circle\"===r.shape)){const t=\"pcb_via\"===e.type?{x:e.x,y:e.y,radius:e.outer_diameter/2}:p0(e),r=ze(t,n,o);return{gap:De(n,o,t)-i,center:f0({tracePoint:r,obstaclePoint:t,traceRadius:i,obstacleRadius:t.radius})}}var r;if((t=\u003e\"pcb_smtpad\"===t.type\u0026\u0026(\"pill\"===t.shape||\"rotated_pill\"===t.shape))(e)){const n=((t,e)=\u003e{const n=GQ(e),o=qQ({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},n.start,n.end);return{distance:o.distance,center:o.center,radius:n.radius,tracePoint:o.pointOnA,obstaclePoint:o.pointOnB}})(t,e);return{gap:n.distance-i-n.radius,center:f0({tracePoint:n.tracePoint,obstaclePoint:n.obstaclePoint,traceRadius:i,obstacleRadius:n.radius})}}const s=((t,e,n)=\u003e{if(n.length\u003c3)return{distance:Number.POSITIVE_INFINITY,center:t,tracePoint:t,obstaclePoint:t};const o=ZQ(n).map(([n,o])=\u003eve(t,e,n,o)).filter(t=\u003enull!==t);if(o.length\u003e0){const n=e.x-t.x,i=e.y-t.y,r=n*n+i*i;return o.sort((e,o)=\u003e((e.x-t.x)*n+(e.y-t.y)*i)/r-((o.x-t.x)*n+(o.y-t.y)*i)/r),{distance:0,center:o[0],tracePoint:o[0],obstaclePoint:o[0]}}if(Ne(t,n)||Ne(e,n)){const n={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return{distance:0,center:n,tracePoint:n,obstaclePoint:n}}let i=qQ(t,e,n[0],n[1]);for(const[o,r]of ZQ(n).slice(1)){const n=qQ(t,e,o,r);n.distance\u003ci.distance\u0026\u0026(i=n)}return{distance:i.distance,center:i.center,tracePoint:i.pointOnA,obstaclePoint:i.pointOnB}})(n,o,(t=\u003e{if(\"pcb_smtpad\"===t.type\u0026\u0026(\"polygon\"===t.shape||\"rotated_rect\"===t.shape))return{kind:\"polygon\",points:UQ(t)};if(\"pcb_plated_hole\"===t.type\u0026\u0026\"rect_pad_width\"in t\u0026\u0026\"rect_pad_height\"in t)return{kind:\"polygon\",points:UQ(t)};const e=h0(t);return{kind:\"polygon\",points:[{x:e.minX,y:e.minY},{x:e.maxX,y:e.minY},{x:e.maxX,y:e.maxY},{x:e.minX,y:e.maxY}]}})(e).points);return{gap:s.distance-i,center:f0({tracePoint:s.tracePoint,obstaclePoint:s.obstaclePoint,traceRadius:i,obstacleRadius:0})}},_0=t=\u003et\u003c=0,b0=class{buckets;objectsById;getBounds;getId;CELL_SIZE=.4;constructor({objects:t,getBounds:e,getId:n,CELL_SIZE:o}){this.buckets=new Map,this.objectsById=new Map,this.getBounds=e,this.getId=n??(()=\u003ethis._getNextId()),this.CELL_SIZE=o??this.CELL_SIZE;for(const e of t)this.addObject(e)}_idCounter=0;_getNextId(){return\"\"+this._idCounter++}addObject(t){const e=this.getBounds(t),n=this.getId(t),o={...t,spatialIndexId:n};this.objectsById.set(n,o);const i=Math.floor(e.minX/this.CELL_SIZE),r=Math.floor(e.minY/this.CELL_SIZE),s=Math.floor(e.maxX/this.CELL_SIZE),a=Math.floor(e.maxY/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const n=`${t}x${e}`,i=this.buckets.get(n);i?i.push(o):this.buckets.set(n,[o])}}removeObject(t){const e=this.objectsById.get(t);if(!e)return!1;this.objectsById.delete(t);const n=this.getBounds(e),o=Math.floor(n.minX/this.CELL_SIZE),i=Math.floor(n.minY/this.CELL_SIZE),r=Math.floor(n.maxX/this.CELL_SIZE),s=Math.floor(n.maxY/this.CELL_SIZE);for(let e=o;e\u003c=r;e++)for(let n=i;n\u003c=s;n++){const o=`${e}x${n}`,i=this.buckets.get(o);if(i){const e=i.findIndex(e=\u003ee.spatialIndexId===t);-1!==e\u0026\u0026(i.splice(e,1),0===i.length\u0026\u0026this.buckets.delete(o))}}return!0}getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getObjectsInBounds(t,e=0){const n=[],o=new Set,i=Math.floor((t.minX-e)/this.CELL_SIZE),r=Math.floor((t.minY-e)/this.CELL_SIZE),s=Math.floor((t.maxX+e)/this.CELL_SIZE),a=Math.floor((t.maxY+e)/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const i=`${t}x${e}`,r=this.buckets.get(i)||[];for(const t of r){const e=t.spatialIndexId;o.has(e)||(o.add(e),n.push(t))}}return n}};function x0(t){return\"pcb_trace_segment\"===t.type||\"pcb_smtpad\"===t.type?[t.layer]:\"pcb_plated_hole\"===t.type?Array.isArray(t.layers)?t.layers:[...WS]:\"pcb_hole\"===t.type?[...WS]:\"pcb_via\"===t.type?Array.isArray(t.layers)?t.layers:[...WS]:\"pcb_keepout\"===t.type\u0026\u0026Array.isArray(t.layers)?t.layers:[]}var v0=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=e.minX,r=e.minY,s=e.maxX,a=e.maxY;if(n.x===o.x\u0026\u0026n.y===o.y){const t=Math.max(i,Math.min(s,n.x)),e=Math.max(r,Math.min(a,n.y));return t===n.x\u0026\u0026e===n.y?{x:n.x,y:n.y}:{x:t,y:e}}const c=o.x-n.x,l=o.y-n.y,d=0!==c?(i-n.x)/c:Number.NEGATIVE_INFINITY,h=0!==c?(s-n.x)/c:Number.POSITIVE_INFINITY,u=0!==l?(r-n.y)/l:Number.NEGATIVE_INFINITY,p=0!==l?(a-n.y)/l:Number.POSITIVE_INFINITY,m=Math.max(Math.min(d,h),Math.min(u,p)),g=Math.min(Math.max(d,h),Math.max(u,p));if(m\u003c=g\u0026\u0026g\u003e=0\u0026\u0026m\u003c=1){const t=Math.max(0,Math.min(1,m));return{x:n.x+t*c,y:n.y+t*l}}const f={x:Math.max(i,Math.min(s,n.x)),y:Math.max(r,Math.min(a,n.y))},y={x:Math.max(i,Math.min(s,o.x)),y:Math.max(r,Math.min(a,o.y))},_=(f.x-n.x)**2+(f.y-n.y)**2,b=(y.x-o.x)**2+(y.y-o.y)**2,x=[{start:{x:i,y:r},end:{x:s,y:r}},{start:{x:s,y:r},end:{x:s,y:a}},{start:{x:s,y:a},end:{x:i,y:a}},{start:{x:i,y:a},end:{x:i,y:r}}];let v=Math.min(_,b),S=_\u003c=b?f:y;const I=(t,e,n)=\u003eMath.max(e,Math.min(n,t));for(const t of x){const e={x:o.x-n.x,y:o.y-n.y},i={x:t.end.x-t.start.x,y:t.end.y-t.start.y},r={x:n.x-t.start.x,y:n.y-t.start.y},s=e.x*e.x+e.y*e.y,a=e.x*i.x+e.y*i.y,c=e.x*r.x+e.y*r.y,l=i.x*i.x+i.y*i.y,d=i.x*r.x+i.y*r.y,h=s*l-a*a;if(Math.abs(h)\u003c1e-10)continue;let u=(a*d-l*c)/h,p=(s*d-a*c)/h;u=I(u,0,1),p=I(p,0,1);const m={x:n.x+u*e.x,y:n.y+u*e.y},g={x:t.start.x+p*i.x,y:t.start.y+p*i.y},f=m.x-g.x,y=m.y-g.y,_=f*f+y*y;_\u003cv\u0026\u0026(v=_,S={x:(m.x+g.x)/2,y:(m.y+g.y)/2})}return S},S0=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i={x:e.x1,y:e.y1},r={x:e.x2,y:e.y2},s={x:o.x-n.x,y:o.y-n.y},a={x:r.x-i.x,y:r.y-i.y},c=s.x*s.x+s.y*s.y,l=a.x*a.x+a.y*a.y;if(0===c||0===l){if(0===c\u0026\u00260===l)return{x:(n.x+i.x)/2,y:(n.y+i.y)/2};if(0===c){const t=C0(((n.x-i.x)*a.x+(n.y-i.y)*a.y)/l,0,1),e={x:i.x+t*a.x,y:i.y+t*a.y};return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}}const t=C0(((i.x-n.x)*s.x+(i.y-n.y)*s.y)/c,0,1),e={x:n.x+t*s.x,y:n.y+t*s.y};return{x:(e.x+i.x)/2,y:(e.y+i.y)/2}}const d=n.x-i.x,h=n.y-i.y,u=s.x*s.x+s.y*s.y,p=s.x*a.x+s.y*a.y,m=s.x*d+s.y*h,g=a.x*a.x+a.y*a.y,f=a.x*d+a.y*h,y=u*g-p*p;if(y\u003c1e-10)return I0(n,o,i,r,s,a,c,l);let _=(p*f-g*m)/y,b=(u*f-p*m)/y;_=C0(_,0,1),b=C0(b,0,1),b=(_*p+f)/g,b=C0(b,0,1),_=(b*p-m)/u,_=C0(_,0,1);const x=n.x+_*s.x,v=n.y+_*s.y,S=i.x+b*a.x,I=i.y+b*a.y,C=x-S,P=v-I;Math.sqrt(C*C+P*P);return{x:(x+S)/2,y:(v+I)/2}},I0=(t,e,n,o,i,r,s,a)=\u003e{let c=((n.x-t.x)*i.x+(n.y-t.y)*i.y)/s;c=C0(c,0,1);const l={x:t.x+c*i.x,y:t.y+c*i.y};let d=((o.x-t.x)*i.x+(o.y-t.y)*i.y)/s;d=C0(d,0,1);const h={x:t.x+d*i.x,y:t.y+d*i.y};let u=((t.x-n.x)*r.x+(t.y-n.y)*r.y)/a;u=C0(u,0,1);const p={x:n.x+u*r.x,y:n.y+u*r.y};let m=((e.x-n.x)*r.x+(e.y-n.y)*r.y)/a;m=C0(m,0,1);const g={x:n.x+m*r.x,y:n.y+m*r.y},f=[{pointA:l,pointB:n,distance:Math.sqrt((l.x-n.x)**2+(l.y-n.y)**2)},{pointA:h,pointB:o,distance:Math.sqrt((h.x-o.x)**2+(h.y-o.y)**2)},{pointA:t,pointB:p,distance:Math.sqrt((t.x-p.x)**2+(t.y-p.y)**2)},{pointA:e,pointB:g,distance:Math.sqrt((e.x-g.x)**2+(e.y-g.y)**2)}].reduce((t,e)=\u003ee.distance\u003ct.distance?e:t);return{x:(f.pointA.x+f.pointB.x)/2,y:(f.pointA.y+f.pointB.y)/2}},C0=(t,e,n)=\u003eMath.max(e,Math.min(n,t)),P0=t=\u003e{if(\"pcb_trace_segment\"===t.type)return{minX:Math.min(t.x1,t.x2),minY:Math.min(t.y1,t.y2),maxX:Math.max(t.x1,t.x2),maxY:Math.max(t.y1,t.y2)};if(\"pcb_smtpad\"===t.type||\"pcb_plated_hole\"===t.type){if(\"pcb_smtpad\"===t.type\u0026\u0026(\"rotated_rect\"===t.shape||\"polygon\"===t.shape)||\"pcb_plated_hole\"===t.type\u0026\u0026\"rect_pad_width\"in t\u0026\u0026\"rect_pad_height\"in t){const e=UQ(t);return{minX:Math.min(...e.map(t=\u003et.x)),minY:Math.min(...e.map(t=\u003et.y)),maxX:Math.max(...e.map(t=\u003et.x)),maxY:Math.max(...e.map(t=\u003et.y))}}if(\"pcb_smtpad\"===t.type\u0026\u0026\"rotated_pill\"===t.shape){const e=GQ(t);return{minX:Math.min(e.start.x,e.end.x)-e.radius,minY:Math.min(e.start.y,e.end.y)-e.radius,maxX:Math.max(e.start.x,e.end.x)+e.radius,maxY:Math.max(e.start.y,e.end.y)+e.radius}}}return EM([t])};function M0(t){return\"wire\"!==t.route_type?[]:[t.start_pcb_port_id,t.end_pcb_port_id].filter(t=\u003eBoolean(t))}function N0(t){const e=new Set;for(const n of t.route)for(const t of M0(n))e.add(t);return Array.from(e)}function w0(t){const e=new Set;for(const n of t)for(const t of N0(n))e.add(t);return Array.from(e)}var T0=t=\u003e{if(\"pcb_via\"===t.type)return t.outer_diameter/2;if(\"pcb_plated_hole\"===t.type\u0026\u0026\"circle\"===t.shape)return t.outer_diameter/2;if(\"pcb_hole\"===t.type\u0026\u0026\"circle\"===t.hole_shape)return t.hole_diameter/2;if(\"pcb_smtpad\"===t.type\u0026\u0026\"circle\"===t.shape)return t.radius;throw new Error(`Could not determine radius of element: ${JSON.stringify(t)}`)},R0=t=\u003e\"pcb_port\"===t.type?t.pcb_port_id:\"pcb_smtpad\"===t.type?t.pcb_smtpad_id:t.pcb_plated_hole_id;function E0(t,{connMap:e,minClearance:n}={}){const o=[];(t=\u003e{const e=t.filter(t=\u003e\"pcb_port\"===t.type),n=t.filter(t=\u003e\"pcb_smtpad\"===t.type),o=t.filter(t=\u003e\"pcb_trace\"===t.type);function i(t,o={}){const i=o.traceWidth||0,r=e.find(e=\u003eo0(e.x,e.y,t.x,t.y)\u003c.01);if(r)return r.pcb_port_id;if(o.isFirstOrLastPoint){const e=n.find(e=\u003e\"rect\"===e.shape?Math.abs(t.x-e.x)\u003ce.width/2+i/2\u0026\u0026Math.abs(t.y-e.y)\u003ce.height/2+i/2:\"circle\"===e.shape?o0(t.x,t.y,e.x,e.y)\u003ce.radius:\"pill\"===e.shape||\"rotated_pill\"===e.shape?n0(t,e):void 0);if(e)return e.pcb_port_id??null}return null}for(const t of o)for(let e=0;e\u003ct.route.length;e++){const n=t.route[e],o=0===e||e===t.route.length-1;if(\"wire\"===n.route_type){if(!n.start_pcb_port_id\u0026\u00260===e){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.start_pcb_port_id=t)}if(!n.end_pcb_port_id\u0026\u0026e===t.route.length-1){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.end_pcb_port_id=t)}}}})(t),e??=ei(t);const i=l0(t);n??=d0(i,\"min_trace_to_pad_edge_clearance\")??.1;const r=vM(t).pcb_trace.list().flatMap(t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];\"wire\"===o.route_type\u0026\u0026(\"wire\"===i.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({type:\"pcb_trace_segment\",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:\"width\"in o?o.width:\"width\"in i?i.width:a0,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),s=vM(t).pcb_smtpad.list(),a=vM(t).pcb_plated_hole.list(),c=vM(t).pcb_port.list(),l=vM(t).pcb_hole.list(),d=vM(t).pcb_via.list(),h=vM(t).pcb_keepout.list(),u=[...c,...s,...a],p=new Map;for(const t of h){const e=new Set(t.excluded_pcb_component_ids??[]);0!==e.size\u0026\u0026p.set(t.pcb_keepout_id,u.filter(t=\u003et.pcb_component_id\u0026\u0026e.has(t.pcb_component_id)).map(R0))}const m=[...r,...s,...a,...l,...d,...h],g=new b0({objects:m,getBounds:P0}),f=e=\u003eNM(t,e),y=(t,e,n)=\u003e_0(n)?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,_=new Set;for(const t of r){const i=n,r=P0(t),s=g.getObjectsInBounds(r,i+t.thickness/2);if(t.x1!==t.x2||t.y1!==t.y2)for(const r of s){if(!x0(r).includes(t.layer))continue;if(\"pcb_keepout\"===r.type\u0026\u0026(p.get(r.pcb_keepout_id)??[]).some(n=\u003ee.areIdsConnected(t.pcb_trace_id,n)))continue;if(\"pcb_trace_segment\"===r.type){const i=r;if(t.layer!==i.layer)continue;if(e.areIdsConnected(t.pcb_trace_id,i.pcb_trace_id))continue;const s=Oe({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:i.x1,y:i.y1},{x:i.x2,y:i.y2})-t.thickness/2-i.thickness/2;if(s\u003en-c0)continue;const a=`overlap_${t.pcb_trace_id}_${i.pcb_trace_id}`,c=`overlap_${i.pcb_trace_id}_${t.pcb_trace_id}`;if(_.has(a))continue;if(_.has(c))continue;_.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),f(i.pcb_trace_id),s),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[],center:S0(t,i),pcb_port_ids:w0([t._pcbTrace,i._pcbTrace])});continue}const s=AM(r);if(e.areIdsConnected(t.pcb_trace_id,\"pcb_trace_id\"in r?r.pcb_trace_id:s))continue;if(\"pcb_smtpad\"===r.type||\"pcb_plated_hole\"===r.type||\"pcb_via\"===r.type){const{gap:e,center:n}=y0(t,r);if(!_0(e))continue;const i=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(i))continue;_.add(i),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),`${r.type} \"${f(s)}\"`,e),pcb_trace_id:t.pcb_trace_id,center:n,source_trace_id:\"\",pcb_trace_error_id:i,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...w0([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)});continue}if(\"pcb_hole\"===r.type){const e=T0(r),i=De({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:r.x,y:r.y,radius:e})-t.thickness/2;if(i\u003en-c0)continue;const a=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(a))continue;_.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),`${r.type} \"${f(AM(r))}\"`,i),pcb_trace_id:t.pcb_trace_id,center:v0(t,P0(r)),source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...w0([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}const a=ke({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},P0(r))-t.thickness/2;if(a+c0\u003ci){const e=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(e))continue;_.add(e),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),`${r.type} \"${f(AM(r))}\"`,a),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:e,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),center:v0(t,P0(r)),pcb_port_ids:[...w0([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}}}return o}function A0(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function O0(t,e){return A0(t,e)\u003c=c0}function k0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];const i=l0(t);n??=d0(i,\"min_via_hole_edge_to_via_hole_edge_clearance\")??i0,e??=ei(t);const r=[],s=new Set;for(let i=0;i\u003co.length;i++)for(let a=i+1;a\u003co.length;a++){const c=o[i],l=o[a];if(O0(c,l))continue;if(!e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=A0(c,l)-c.hole_diameter/2-l.hole_diameter/2;if(d+c0\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");s.has(h)||(s.add(h),r.push({type:\"pcb_via_clearance_error\",pcb_error_id:`same_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return r}function L0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];const i=l0(t);n??=d0(i,\"min_via_hole_edge_to_via_hole_edge_clearance\")??i0,e??=ei(t);const r=[],s=new Set;for(let i=0;i\u003co.length;i++)for(let a=i+1;a\u003co.length;a++){const c=o[i],l=o[a];if(O0(c,l))continue;if(e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=A0(c,l)-c.hole_diameter/2-l.hole_diameter/2;if(d+c0\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");s.has(h)||(s.add(h),r.push({type:\"pcb_via_clearance_error\",pcb_error_id:`different_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} from different nets are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return r}function D0(t){return\"through_pad\"===t.route_type?{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2}:{x:t.x,y:t.y}}function z0(t,e,n,o){return\"wire\"===t.route_type\u0026\u0026e.some(e=\u003e{if(!e.pcb_port_id||e.pcb_port_id===n)return!1;const i=o.get(e.pcb_port_id);return i?.some(e=\u003en0({x:t.x,y:t.y},e))??!1})}function F0({firstPoint:t,lastPoint:e,port:n,expectedPorts:o,padMap:i}){let r;const s=\"wire\"===t.route_type?t:void 0,a=\"wire\"===e.route_type?e:void 0,c=M0(t).includes(n.pcb_port_id),l=M0(e).includes(n.pcb_port_id);c\u0026\u0026s?r=s:l\u0026\u0026a||z0(t,o,n.pcb_port_id,i)\u0026\u0026a?r=a:z0(e,o,n.pcb_port_id,i)\u0026\u0026s?r=s:s\u0026\u0026a?r=A0(s,n)\u003c=A0(a,n)?s:a:s?r=s:a\u0026\u0026(r=a);const d=D0(t),h=D0(e);return r?{x:r.x,y:r.y}:{x:(d.x+h.x)/2,y:(d.y+h.y)/2}}function B0(t){const e=[],n=t.filter(t=\u003e\"pcb_port\"===t.type),o=t.filter(t=\u003e\"pcb_trace\"===t.type),i=t.filter(t=\u003e\"source_trace\"===t.type),r=t.filter(t=\u003e\"pcb_smtpad\"===t.type),s=t.filter(t=\u003e\"pcb_plated_hole\"===t.type),a=new Map,c=new ni(t),l=new Set;for(const t of r)t.pcb_port_id\u0026\u0026a.set(t.pcb_port_id,[...a.get(t.pcb_port_id)??[],t]);for(const t of s)t.pcb_port_id\u0026\u0026a.set(t.pcb_port_id,[...a.get(t.pcb_port_id)??[],t]);for(const r of o){if(0===r.route.length)continue;const s=r.route[0],d=r.route[r.route.length-1],h=i.find(t=\u003et.source_trace_id===r.source_trace_id),u=h?n.filter(t=\u003eh.connected_source_port_ids?.includes(t.source_port_id)):[];for(let n=1;n\u003cr.route.length-1;n++){const o=r.route[n-1],i=r.route[n],s=r.route[n+1];if(\"via\"===i.route_type){const a=\"wire\"===o.route_type,c=\"wire\"===s.route_type;if(a\u0026\u0026c){const a=Math.abs(o.x-i.x)\u003c.01\u0026\u0026Math.abs(o.y-i.y)\u003c.01,c=Math.abs(s.x-i.x)\u003c.01\u0026\u0026Math.abs(s.y-i.y)\u003c.01;if(!a||!c){const o=PM(t,r.pcb_trace_id);e.push({type:\"pcb_trace_error\",message:`Via in trace [${o}] is misaligned at position {x: ${i.x}, y: ${i.y}}.`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`misaligned_via_${r.pcb_trace_id}_${n}`,pcb_component_ids:[],pcb_port_ids:[]})}}}}const p=PM(t,r.pcb_trace_id);if(h\u0026\u0026u.length\u003e0){if(l.has(h.source_trace_id))continue;l.add(h.source_trace_id)}for(const n of u){if(!n.pcb_port_id)continue;const l=a.get(n.pcb_port_id);if(!l?.length)continue;let m=!1;const g=[...c.getAllTracesConnectedToTrace(r.pcb_trace_id),...o.filter(t=\u003et.source_trace_id===h?.source_trace_id)];for(const t of g){if(t.pcb_trace_id===r.pcb_trace_id)continue;if(!t.source_trace_id)continue;const e=i.find(e=\u003ee.source_trace_id===t.source_trace_id);if(!h||t.source_trace_id!==h.source_trace_id\u0026\u0026!e?.connected_source_port_ids.includes(n.source_port_id))continue;const o=t.route[0],s=t.route.at(-1);if(N0(t).includes(n.pcb_port_id)||\"wire\"===o?.route_type\u0026\u0026l.some(t=\u003en0(o,t))||\"wire\"===s?.route_type\u0026\u0026l.some(t=\u003en0(s,t))){m=!0;break}}if(m)continue;const f=\"wire\"===s.route_type\u0026\u0026l.some(t=\u003en0({x:s.x,y:s.y},t)),y=\"wire\"===d.route_type\u0026\u0026l.some(t=\u003en0({x:d.x,y:d.y},t));if(!f\u0026\u0026!y){const o=MM(t,n.pcb_port_id).replace(\"pcb_port\",\"\"),i=l[0].type.replace(/pcb_/,\"\"),c=F0({firstPoint:s,lastPoint:d,port:n,expectedPorts:u,padMap:a});e.push({type:\"pcb_trace_error\",message:`Trace [${p}] is missing a connection to ${i}${o}`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`missing_connection_${r.pcb_trace_id}_${n.pcb_port_id}`,center:c,pcb_component_ids:[],pcb_port_ids:[n.pcb_port_id]})}}if(0===u.length){let t=!1,n=!1;const o=\"wire\"===s.route_type\u0026\u0026\"wire\"===d.route_type\u0026\u0026Math.abs(s.x-d.x)\u003c.01\u0026\u0026Math.abs(s.y-d.y)\u003c.01;for(const e of a.values())\"wire\"===s.route_type\u0026\u0026e.some(t=\u003en0({x:s.x,y:s.y},t))\u0026\u0026(t=!0),\"wire\"===d.route_type\u0026\u0026e.some(t=\u003en0({x:d.x,y:d.y},t))\u0026\u0026(n=!0);t||\"wire\"!==s.route_type||e.push({type:\"pcb_trace_error\",message:`Trace [${p}] has disconnected endpoint at (${s.x.toFixed(2)}, ${s.y.toFixed(2)})`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`disconnected_endpoint_${r.pcb_trace_id}_start`,center:{x:s.x,y:s.y},pcb_component_ids:[],pcb_port_ids:[]}),n||\"wire\"!==d.route_type||o\u0026\u0026!t||e.push({type:\"pcb_trace_error\",message:`Trace [${p}] has disconnected endpoint at (${d.x.toFixed(2)}, ${d.y.toFixed(2)})`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`disconnected_endpoint_${r.pcb_trace_id}_end`,center:{x:d.x,y:d.y},pcb_component_ids:[],pcb_port_ids:[]})}}return e}function j0(t,e={}){const n=[],o=l0(t);if(!o)return n;const i=e.margin??d0(o,\"min_board_edge_clearance\")??s0,r=function(t){if(t.outline\u0026\u0026t.outline.length\u003e0)return t.outline.map(t=\u003e({x:t.x,y:t.y}));if(t.center\u0026\u0026\"number\"==typeof t.width\u0026\u0026\"number\"==typeof t.height){const e=t.center.x,n=t.center.y,o=t.width/2,i=t.height/2;return[{x:e-o,y:n-i},{x:e+o,y:n-i},{x:e+o,y:n+i},{x:e-o,y:n+i}]}return null}(o);if(!r)return n;const s=vM(t).pcb_trace.list();for(const t of s)if(!(t.route.length\u003c2))for(let e=0;e\u003ct.route.length-1;e++){const o=t.route[e],s=t.route[e+1];if(\"wire\"!==o.route_type||\"wire\"!==s.route_type)continue;const a=\"width\"in o?o.width:\"width\"in s?s.width:.1,c={x:o.x,y:o.y},l={x:s.x,y:s.y};let d=Number.POSITIVE_INFINITY;for(let t=0;t\u003cr.length;t++){const e=Oe(c,l,r[t],r[(t+1)%r.length]);e\u003cd\u0026\u0026(d=e)}const h=a/2+i;if(d\u003ch){const o={type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",pcb_trace_error_id:`trace_too_close_to_board_${t.pcb_trace_id}_segment_${e}`,message:`Trace too close to board edge (${d.toFixed(3)}mm \u003c ${h.toFixed(3)}mm required, margin: ${i}mm)`,pcb_trace_id:t.pcb_trace_id,source_trace_id:t.source_trace_id||\"\",center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2},pcb_component_ids:[],pcb_port_ids:[]};n.push(o)}}return n}function $0(t,{connMap:e,minClearance:n}={}){const o=(t=\u003e[...vM(t).pcb_smtpad.list(),...vM(t).pcb_plated_hole.list()])(t),i=m0(t);if(0===o.length||0===i.length)return[];const r=l0(t);n??=d0(r,\"min_trace_to_pad_edge_clearance\")??r0,e??=ei(t);const s=new b0({objects:o,getBounds:h0,getId:t=\u003eAM(t)}),a=new Map,c=new Set;for(const o of i){const i=s.getObjectsInBounds(P0(o),n+o.thickness/2);for(const r of i){const i=AM(r);if(!x0(r).includes(o.layer))continue;if(e.areIdsConnected(o.pcb_trace_id,i))continue;const s=`${i}_${o.pcb_trace_id}`,{gap:l}=y0(o,r);if(_0(l)){a.delete(s),c.add(s);continue}if(c.has(s))continue;if(l+c0\u003e=n)continue;const d={type:\"pcb_pad_trace_clearance_error\",pcb_pad_trace_clearance_error_id:`pad_trace_clearance_${s}`,error_type:\"pcb_pad_trace_clearance_error\",message:`Pad ${NM(t,i)} and trace ${NM(t,o.pcb_trace_id)} are too close (clearance: ${I_(l)}, minimum: ${I_(n)})`,pcb_pad_id:i,pcb_trace_id:o.pcb_trace_id,minimum_clearance:n,actual_clearance:l,center:g0(o)},h=a.get(s);(!h||l\u003ch.gap)\u0026\u0026a.set(s,{error:d,gap:l})}}return Array.from(a.values()).map(({error:t})=\u003et)}function Y0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type),i=m0(t);if(0===o.length||0===i.length)return[];const r=l0(t);n??=d0(r,\"min_trace_to_pad_edge_clearance\")??r0,e??=ei(t);const s=new Map,a=new Set;for(const r of o)for(const o of i){if(!x0(r).includes(o.layer))continue;if(e.areIdsConnected(o.pcb_trace_id,r.pcb_via_id))continue;const i=`${r.pcb_via_id}_${o.pcb_trace_id}`,{gap:c}=y0(o,r);if(_0(c)){s.delete(i),a.add(i);continue}if(a.has(i))continue;if(c+c0\u003e=n)continue;const l={type:\"pcb_via_trace_clearance_error\",pcb_via_trace_clearance_error_id:`via_trace_clearance_${i}`,error_type:\"pcb_via_trace_clearance_error\",message:`Via ${NM(t,r.pcb_via_id)} and trace ${NM(t,o.pcb_trace_id)} are too close (clearance: ${I_(c)}, minimum: ${I_(n)})`,pcb_via_id:r.pcb_via_id,pcb_trace_id:o.pcb_trace_id,minimum_clearance:n,actual_clearance:c,center:g0(o)},d=s.get(i);(!d||c\u003cd.gap)\u0026\u0026s.set(i,{error:l,gap:c})}return Array.from(s.values()).map(({error:t})=\u003et)}var X0=(t,e={})=\u003e{const n=(t=\u003e{const e=ei(t),n=t.filter(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_trace_id).map(t=\u003e[t.pcb_via_id,t.pcb_trace_id]);return e.addConnections(n),e})(t),o=Math.max(e.viaClearance??.1,.1),i=E0(t,{connMap:n,minClearance:e.traceClearance}),r=!1!==e.includeTypedTraceClearance,s=r?Y0(t,{connMap:n,minClearance:e.traceClearance}):[],a=r?$0(t,{connMap:n,minClearance:e.traceClearance}):[],c=[...k0(t,{connMap:n,minClearance:o}),...L0(t,{connMap:n,minClearance:o})],l=[...i,...j0(t),...!1===e.includeTraceContinuity?[]:B0(t),...s,...a,...c],d=t.filter(t=\u003e\"pcb_via\"===t.type),h=new Map(d.map(t=\u003e[t.pcb_via_id,t])),u=l.map(t=\u003e{if(\"pcb_via_trace_clearance_error\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id){const e=h.get(t.pcb_via_id);if(e)return{...t,center:{x:e.x,y:e.y}}}if(\"center\"in t\u0026\u0026t.center)return t;if(\"pcb_center\"in t\u0026\u0026t.pcb_center)return{...t,center:t.pcb_center};if(\"pcb_via_ids\"in t\u0026\u0026Array.isArray(t.pcb_via_ids)){const[e,n]=t.pcb_via_ids,o=h.get(e),i=h.get(n);if(o\u0026\u0026i)return{...t,center:{x:(o.x+i.x)/2,y:(o.y+i.y)/2}}}if(\"pcb_error_id\"in t\u0026\u0026\"string\"==typeof t.pcb_error_id\u0026\u0026(t.pcb_error_id.startsWith(\"same_net_vias_close_\")||t.pcb_error_id.startsWith(\"different_net_vias_close_\"))){const e=t.pcb_error_id.replace(\"same_net_vias_close_\",\"\").replace(\"different_net_vias_close_\",\"\").split(\"_\").filter(Boolean);if(2===e.length){const n=h.get(e[0]),o=h.get(e[1]);if(n\u0026\u0026o)return{...t,center:{x:(n.x+o.x)/2,y:(n.y+o.y)/2}}}}return t}),p=u.filter(t=\u003eBoolean(t.center));return{errors:l,errorsWithCenters:u,locationAwareErrors:p}},V0={traceClearance:.1,viaClearance:.1};var W0=t=\u003et.circuitJsonMetadata??{},H0=({connections:t,obstacles:e})=\u003enew Set([...t.flatMap(t=\u003et.pointsToConnect.flatMap(t=\u003et.pcb_port_id?[t.pcb_port_id]:[])),...e.flatMap(t=\u003e{const e=W0(t).pcb_port_id;return e?[e]:[]})]),G0=t=\u003et.__netConnectionName??t.__rootConnectionNames?.[0]??t.name,U0=t=\u003eArray.from(new Set([t.name,t.__netConnectionName,...t.__rootConnectionNames??[],...t.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])])).filter(t=\u003eBoolean(t)),Z0=(t,e)=\u003e{const n=new Map,o=new Set,i=new Map;for(const r of t){const t=G0(r);for(const e of U0(r)){const i=n.get(e);i\u0026\u0026i!==t?(n.delete(e),o.add(e)):o.has(e)||n.set(e,t)}const s=e.getNetConnectedToId(r.name);if(!s)continue;const a=s,c=i.get(a)??new Set;c.add(t),i.set(a,c)}return{connMap:e,circuitJsonSourceTraceIdBySrjDeclaredConnectionReference:n,circuitJsonSourceTraceIdsByConnectivityNetId:i}},q0=(t,e)=\u003e{const n=t.circuitJsonSourceTraceIdBySrjDeclaredConnectionReference.get(e);if(n)return n;const o=t.connMap.getNetConnectedToId(e);if(!o)return;const i=t.circuitJsonSourceTraceIdsByConnectivityNetId.get(o);return 1===i?.size?i.values().next().value:void 0};function J0(t,e,n=t){const o=[],i=n===t?t.connections:[...t.connections,...n.connections],r=n===t?t.obstacles:n.obstacles,s=Z0(i,ii(n===t?t:{...n,connections:i})),a=H0({connections:i,obstacles:r});if(i.forEach(t=\u003e{const n=t.pointsToConnect.map(t=\u003et.pcb_port_id).filter(t=\u003eBoolean(t)),i=new Set(n),a=t=\u003e(t=\u003eArray.from(new Set(t.flatMap(t=\u003et.connectedTo))))(t).filter(t=\u003e!i.has(t)),c=t.pointsToConnect.map(t=\u003et.pointId).filter(t=\u003eBoolean(t)),l=q0(s,t.name)??G0(t),d=[],h=e.find(e=\u003e(e.connection_name??e.connectionName)===t.name);if(h){const t=t=\u003e\"route_type\"in t\u0026\u0026\"jumper\"===t.route_type?t.start:\"x\"in t\u0026\u0026\"y\"in t?{x:t.x,y:t.y}:{x:0,y:0},e=[t(h.route[0]),t(h.route[h.route.length-1])];for(const t of e)for(const e of r)Be(t,e)\u003c=0\u0026\u0026d.push(e)}const u=o.find(t=\u003e\"source_trace\"===t.type\u0026\u0026t.source_trace_id===l);if(u){const t=u;t.connected_source_port_ids=[...new Set([...t.connected_source_port_ids,...n])],t.connected_source_net_ids=[...new Set([...t.connected_source_net_ids??[],...c,...a(d)])]}else o.push({type:\"source_trace\",source_trace_id:l,connected_source_port_ids:n,connected_source_net_ids:a(d).concat(c)})}),e[0]\u0026\u0026\"type\"in e[0]){const t=new Map(i.map(t=\u003e[t.name,t]));for(const n of e){const e=[...new Set((n.connectsTo??[]).filter(t=\u003ea.has(t)))],i=new Set(e),r=[...new Set((n.connectsTo??[]).filter(t=\u003e!i.has(t)))];if(0===e.length\u0026\u00260===r.length)continue;const c=t.get(n.connection_name),l=q0(s,n.connection_name)??n.connectsTo?.map(t=\u003eq0(s,t)).find(t=\u003evoid 0!==t)??(c?G0(c):n.connection_name),d=o.find(t=\u003e\"source_trace\"===t.type\u0026\u0026t.source_trace_id===l);\"source_trace\"!==d?.type?o.push({type:\"source_trace\",source_trace_id:l,connected_source_port_ids:e,connected_source_net_ids:r}):(d.connected_source_port_ids=[...new Set([...d.connected_source_port_ids,...e])],d.connected_source_net_ids=[...new Set([...d.connected_source_net_ids??[],...r])])}}return o}function K0(t,e,n){let o,i=Number.POSITIVE_INFINITY;for(const r of e){const e=n.get(r);if(!e)continue;const s=Math.hypot(e.x-t.x,e.y-t.y);s\u003ci\u0026\u0026(i=s,o=r)}return o??e[0]}var Q0=new Set([\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\",\"inner7\",\"inner8\"]),t1=t=\u003eQ0.has(t);function e1(t){const e=[],n=new Set,o=new Set,i=function(t){const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{x:t.x,y:t.y});return e}(t),r=H0(t);for(const s of t.obstacles){const t=s.connectedTo,a=W0(s);if(a.pcb_via_id)continue;const c=a.pcb_smtpad_id,l=a.pcb_plated_hole_id,d=[...new Set([...a.pcb_port_id?[a.pcb_port_id]:[],...t.filter(t=\u003er.has(t))])],h=K0(s.center,d,i);if(!c\u0026\u0026!l\u0026\u0026!h)continue;const u=s.layers.filter(t1);if(0===u.length)continue;const p=s.width,m=s.height,g=s.center.x,f=s.center.y,y=s.ccwRotationDegrees;if(Boolean(l)||u.length\u003e1){const t=l??`pcb_plated_hole_${g.toFixed(3)}_${f.toFixed(3)}`;if(o.has(t))continue;if(o.add(t),\"number\"==typeof y\u0026\u0026Number.isFinite(y)){const n=Math.max(.5*Math.min(p,m),.1);e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"rotated_pill_hole_with_rect_pad\",hole_shape:\"rotated_pill\",pad_shape:\"rect\",hole_width:n,hole_height:n,hole_ccw_rotation:y,rect_pad_width:p,rect_pad_height:m,rect_ccw_rotation:y,hole_offset_x:0,hole_offset_y:0,x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}if(Math.abs(p-m)\u003c.001){e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circle\",outer_diameter:Math.max(p,m),hole_diameter:Math.max(.5*Math.min(p,m),.1),x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circular_hole_with_rect_pad\",hole_shape:\"circle\",hole_diameter:Math.max(.5*Math.min(p,m),.1),rect_pad_width:p,rect_pad_height:m,hole_offset_x:0,hole_offset_y:0,x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}const _=c??`pcb_smtpad_${g.toFixed(3)}_${f.toFixed(3)}`;n.has(_)||(n.add(_),\"number\"==typeof y\u0026\u0026Number.isFinite(y)?e.push({type:\"pcb_smtpad\",pcb_smtpad_id:_,layer:u[0],shape:\"rotated_rect\",x:g,y:f,width:p,height:m,ccw_rotation:y,...h?{pcb_port_id:h}:{}}):e.push({type:\"pcb_smtpad\",pcb_smtpad_id:_,layer:u[0],shape:\"rect\",width:p,height:m,x:g,y:f,...h?{pcb_port_id:h}:{}}))}return e}function n1(t,e,n={}){const{minTraceWidth:o=.1,minViaDiameter:i,minViaHoleDiameter:r,originalSrj:s,includeOriginalConnections:a=!1}=n,c=Yo(t),l=i??c.padDiameter,d=t.min_via_hole_diameter??t.minViaHoleDiameter,h=r??d??(void 0!==i?.5*l:c.holeDiameter),u=[];u.push(...J0(t,e,a\u0026\u0026s?s:t)),u.push(...function(t){const e=new Map;return t.connections.forEach(t=\u003e{t.pointsToConnect.forEach(t=\u003e{t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{type:\"pcb_port\",pcb_port_id:t.pcb_port_id,source_port_id:t.pcb_port_id,x:t.x,y:t.y,layers:xo(t)})})}),Array.from(e.values())}(a\u0026\u0026s?s:t)),u.push(...e1(s??t)),u.push(...function(t,e,n=.3,o=.5*n){const i=[],r=new Set;return t.length\u003e0\u0026\u0026(\"type\"in t[0]\u0026\u0026\"pcb_trace\"===t[0].type?t.forEach(t=\u003e{t.route.forEach(s=\u003e{if(\"via\"===s.route_type){if(!t1(s.from_layer)||!t1(s.to_layer))return;const a=s.via_diameter??n,c=s.via_hole_diameter??o,l=`${s.x},${s.y},${s.from_layer},${s.to_layer}`;r.has(l)||(i.push({type:\"pcb_via\",pcb_via_id:`via_${i.length}`,pcb_trace_id:t.pcb_trace_id,x:s.x,y:s.y,outer_diameter:a,hole_diameter:c,layers:Wy(s,e)}),r.add(l))}})}):t.forEach((t,s)=\u003e{const a=`trace_${s}`,c=t.viaDiameter??n,l=o;for(let n=1;n\u003ct.route.length;n++){const o=t.route[n-1],s=t.route[n];if(o.z!==s.z\u0026\u0026Math.abs(o.x-s.x)\u003c.01\u0026\u0026Math.abs(o.y-s.y)\u003c.01){const t=vo(o.z,e),n=vo(s.z,e),d=`${s.x},${s.y},${t},${n}`;r.has(d)||(i.push({type:\"pcb_via\",pcb_via_id:`via_${i.length}`,pcb_trace_id:a,x:s.x,y:s.y,outer_diameter:c,hole_diameter:l,layers:Wy({from_layer:t,to_layer:n},e)}),r.add(d))}}})),i}(e,t.layerCount,l,h));const p=Z0(t.connections,ii(t));return e.length\u003e0\u0026\u0026(\"type\"in e[0]\u0026\u0026\"pcb_trace\"===e[0].type?e.forEach(t=\u003e{const e=q0(p,t.connection_name)??t.connectsTo?.map(t=\u003eq0(p,t)).find(t=\u003eBoolean(t))??t.connection_name;u.push(function(t,e){return{type:\"pcb_trace\",pcb_trace_id:t.pcb_trace_id,source_trace_id:e,route:t.route.map(t=\u003e{if(\"wire\"===t.route_type){if(!t1(t.layer))return null;const e=\"start_pcb_port_id\"in t\u0026\u0026\"string\"==typeof t.start_pcb_port_id?t.start_pcb_port_id:void 0,n=\"end_pcb_port_id\"in t\u0026\u0026\"string\"==typeof t.end_pcb_port_id?t.end_pcb_port_id:void 0;return{route_type:\"wire\",x:t.x,y:t.y,width:t.width,layer:t.layer,...e?{start_pcb_port_id:e}:{},...n?{end_pcb_port_id:n}:{}}}return\"via\"===t.route_type\u0026\u0026t1(t.from_layer)\u0026\u0026t1(t.to_layer)?{route_type:\"via\",x:t.x,y:t.y,from_layer:t.from_layer,to_layer:t.to_layer}:null}).filter(t=\u003enull!==t)}}(t,e))}):e.forEach((e,n)=\u003e{const i=function(t,e,n,o,i=.1){const r=[];if(!t.jumpers||0===t.jumpers.length)return[{type:\"pcb_trace\",pcb_trace_id:e,source_trace_id:n,route:t.route.map((e,n)=\u003e{const r=0===n,s=n===t.route.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:e.traceThickness??i,layer:vo(e.z,o),...r\u0026\u0026e.pcb_port_id?{start_pcb_port_id:e.pcb_port_id}:{},...s\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})}];const s=[];for(const e of t.jumpers){let n=-1,o=-1;for(let i=0;i\u003ct.route.length;i++){const r=t.route[i];Math.abs(r.x-e.start.x)\u003c.01\u0026\u0026Math.abs(r.y-e.start.y)\u003c.01\u0026\u0026(n=i),Math.abs(r.x-e.end.x)\u003c.01\u0026\u0026Math.abs(r.y-e.end.y)\u003c.01\u0026\u0026(o=i)}-1!==n\u0026\u0026-1!==o\u0026\u0026(n\u003eo\u0026\u0026([n,o]=[o,n]),s.push({startIdx:n,endIdx:o}))}s.sort((t,e)=\u003et.startIdx-e.startIdx);let a=0,c=0;for(const{startIdx:l,endIdx:d}of s){if(l\u003e=a){const s=t.route.slice(a,l+1);s.length\u003e0\u0026\u0026(r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((t,e)=\u003e{const n=0===e\u0026\u00260===a;return{route_type:\"wire\",x:t.x,y:t.y,width:t.traceThickness??i,layer:vo(t.z,o),...n\u0026\u0026t.pcb_port_id?{start_pcb_port_id:t.pcb_port_id}:{}}})}),c++)}a=d}if(a\u003ct.route.length){const s=t.route.slice(a);if(s.length\u003e0){const t=!0;r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((e,n)=\u003e{const r=t\u0026\u0026n===s.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:e.traceThickness??i,layer:vo(e.z,o),...r\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})})}}return r}(e,`trace_${n}`,q0(p,e.connectionName)??e.connectionName,t.layerCount,o);u.push(...i)})),u}var o1=(t,e)=\u003e{const n=new Set(e.flatMap(t=\u003et.__replaces_pcb_trace_id?[t.__replaces_pcb_trace_id]:[]));return[...t.filter(t=\u003e!n.has(t.pcb_trace_id)),...e]},i1=({inputSrj:t,srjWithPointPairs:e,routedTraces:n,drcOptions:o})=\u003e{const i=t.traces??[],r=n1(e,o1(i,n),{minTraceWidth:t.minTraceWidth,minViaDiameter:t.minViaDiameter,originalSrj:t,includeOriginalConnections:!0});return{circuitJson:r,...X0(r,{...V0,...o})}},r1=(t,e)=\u003e{const n=t({hdRoutes:e,traces:[]});return Array.isArray(n)?n:n.errorsWithCenters??n.errors},s1=t=\u003e{const e=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,n=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],o=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids:[]].filter(t=\u003e\"string\"==typeof t),i=e?`overlap_${e}_`:void 0,r=i\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0;if(n.length\u003e0){const t=e\u0026\u0026!n.includes(e)?[e,...n]:[...n];return t.length\u003c2\u0026\u0026r\u0026\u0026!o.includes(r)\u0026\u0026t.push(r),t}return[e,r].filter(t=\u003e\"string\"==typeof t\u0026\u0026!o.includes(t))},a1=t=\u003es1(t).filter((t,e,n)=\u003en.indexOf(t)===e),c1=t=\u003et.reduce((t,e)=\u003e{if(\"number\"==typeof e.actual_clearance\u0026\u0026\"number\"==typeof e.minimum_clearance)return t+Math.max(0,e.minimum_clearance-e.actual_clearance);const n=(\"string\"==typeof e.message?e.message:\"\").match(/gap: (-?\\d+(?:\\.\\d+)?)mm/);return n?t+Math.max(0,.1-Number.parseFloat(n[1])):t+1},0),l1=(t,e)=\u003et.length\u003ce.length||t.length===e.length\u0026\u0026c1(t)\u003cc1(e)-1e-9,d1=({routes:t,newConnections:e,syntheticConnectionNames:n})=\u003e{const o=new Set([...e.map(t=\u003et.name),...n]),i=new Map,r=new Map;for(let e=0;e\u003ct.length;e++){const n=t[e];if(!o.has(n.connectionName))continue;const s=i.get(n.connectionName)??0;i.set(n.connectionName,s+1),r.set(`${n.connectionName}_${s}`,e)}return r},h1=[.03,.1,.25],u1=t=\u003e{let e=0;for(const n of t){if(\"number\"!=typeof n.actual_clearance||!Number.isFinite(n.actual_clearance)||\"number\"!=typeof n.minimum_clearance||!Number.isFinite(n.minimum_clearance))return;if(e+=Math.max(0,n.minimum_clearance-n.actual_clearance),!Number.isFinite(e))return}return e},p1=({errors:t,errorsWithCenters:e,routeIndexByTraceId:n,padPositionById:o})=\u003e{const i=[];let r=0;for(const s of t){const t=\"pcb_via_trace_clearance_error\"===s.type,a=\"pcb_pad_trace_clearance_error\"===s.type;if(!t\u0026\u0026!a||\"string\"!=typeof s.pcb_trace_id||!n.has(s.pcb_trace_id)||\"number\"!=typeof s.actual_clearance||!Number.isFinite(s.actual_clearance)||\"number\"!=typeof s.minimum_clearance||!Number.isFinite(s.minimum_clearance))return;const c=a1(s);if(t\u0026\u0026c.length\u003c2||c.some(t=\u003e!n.has(t)))return;const l=e.find(t=\u003et.type===s.type\u0026\u0026t.pcb_trace_id===s.pcb_trace_id\u0026\u0026t.pcb_pad_id===s.pcb_pad_id\u0026\u0026t.pcb_via_id===s.pcb_via_id),d=a?\"string\"==typeof s.pcb_pad_id?o.get(s.pcb_pad_id):void 0:l?.center??s.center;if(!d||\"object\"!=typeof d)return;if(!(\"x\"in d\u0026\u0026\"y\"in d\u0026\u0026\"number\"==typeof d.x\u0026\u0026Number.isFinite(d.x)\u0026\u0026\"number\"==typeof d.y\u0026\u0026Number.isFinite(d.y)))return;const h={...s,pcb_trace_id:s.pcb_trace_id,actual_clearance:s.actual_clearance,minimum_clearance:s.minimum_clearance,center:{x:d.x,y:d.y}};if(t){if(\"string\"!=typeof s.pcb_via_id)return;i.push({...h,type:\"pcb_via_trace_clearance_error\",pcb_via_id:s.pcb_via_id,pcb_pad_id:void 0})}else{if(\"string\"!=typeof s.pcb_pad_id)return;i.push({...h,type:\"pcb_pad_trace_clearance_error\",pcb_pad_id:s.pcb_pad_id,pcb_via_id:void 0})}if(r+=Math.max(0,s.minimum_clearance-s.actual_clearance),!Number.isFinite(r))return}return{errors:i,deficit:r}},m1=(t,e)=\u003e{const n=[];for(let o=0;o\u003ct.route.length;o+=1){const i=t.route[o];if(\"via\"!==i.route_type){n.push(structuredClone(i));continue}const r=n[n.length-1],s=t.route[o+1],a=\"wire\"===r?.route_type?r.width:\"wire\"===s?.route_type?s.width:e,c=\"wire\"===s?.route_type?s.width:a;\"wire\"===r?.route_type\u0026\u0026r.x===i.x\u0026\u0026r.y===i.y\u0026\u0026r.layer===i.from_layer||n.push({route_type:\"wire\",x:i.x,y:i.y,layer:i.from_layer,width:a}),n.push(structuredClone(i)),\"wire\"===s?.route_type\u0026\u0026s.x===i.x\u0026\u0026s.y===i.y\u0026\u0026s.layer===i.to_layer||n.push({route_type:\"wire\",x:i.x,y:i.y,layer:i.to_layer,width:c})}return{...structuredClone(t),route:n}};function g1(t){const{srj:e,routes:n,routeIndex:o,start:i,end:r,bounds:s,traceThickness:a}=t;if(void 0!==t.maxNodes\u0026\u0026(!Number.isSafeInteger(t.maxNodes)||t.maxNodes\u003c1))throw new Error(\"repair04: maxNodes must be a positive safe integer\");if(t.stats\u0026\u0026(t.stats.nodesPopped=0,t.stats.completionReason=\"no-path\"),!1===t.allowLayerChanges\u0026\u0026i.z!==r.z)return null;const c=n[o],l=new Map,d=t=\u003e{const e=l.get(t);if(void 0===e||e===t)return t;const n=d(e);return l.set(t,n),n},h=t=\u003e{const e=t.filter(t=\u003eBoolean(t));if(!e.length)return;const n=d(e[0]);for(const t of e)l.set(d(t),n)};for(const t of e.connections){const e=t;h([e.name,e.rootConnectionName,e.netConnectionName,e.__netConnectionName,...e.mergedConnectionNames??[],...e.__rootConnectionNames??[],...e.pointsToConnect.flatMap(t=\u003e[t.pcb_port_id,t.pointId])])}for(const t of e.obstacles)h(t.connectedTo);for(const t of n)h([t.connectionName,t.rootConnectionName]);const u=d(c.connectionName),p=t=\u003e\"top\"===t?0:\"bottom\"===t?e.layerCount-1:Number(t.slice(5)),m=[s.minX,s.maxX,s.minY,s.maxY,i.x,i.y,r.x,r.y,a,c.viaDiameter,t.traceClearance,t.viaClearance,e.defaultObstacleMargin??0,e.minTraceToPadEdgeClearance??0,e.minViaEdgeToPadEdgeClearance??0].every(t=\u003eNumber.isFinite(t)\u0026\u0026Math.abs(t)\u003c=1e4),g=[],f=(t,e,n,o,i=!1)=\u003e{const r=o?Math.hypot(o.width,o.height)/2:n,s=o?Math.cos(o.rotation):1,a=o?Math.sin(o.rotation):0,c={minX:Math.min(t.x,e.x)-r,maxX:Math.max(t.x,e.x)+r,minY:Math.min(t.y,e.y)-r,maxY:Math.max(t.y,e.y)+r},l=o\u0026\u0026m?((t,e,n,o,i,r)=\u003e{if(t.x!==e.x||t.y!==e.y||!Number.isFinite(n.rotation)||n.width\u003c=0||n.height\u003c=0||![t.x,t.y,n.width,n.height,r.minX,r.maxX,r.minY,r.maxY].every(t=\u003eNumber.isFinite(t)\u0026\u0026Math.abs(t)\u003c=1e4))return r;const s=o*o+i*i;if(!Number.isFinite(s)||Math.abs(s-1)\u003e1e-12)return r;const a=n.width/2,c=n.height/2,l=(Math.abs(o)*a+Math.abs(i)*c)/s+1e-8,d=(Math.abs(i)*a+Math.abs(o)*c)/s+1e-8,h={minX:t.x-l,maxX:t.x+l,minY:t.y-d,maxY:t.y+d};return h.minX\u003cr.minX||h.maxX\u003er.maxX||h.minY\u003cr.minY||h.maxY\u003er.maxY?r:h})(t,e,o,s,a,c):c;g.push({a:t,b:e,radius:n,rect:o,viaOnly:i,rectCos:s,rectSin:a,rectBounds:o?{minX:-o.width/2,maxX:o.width/2,minY:-o.height/2,maxY:o.height/2}:void 0,visitedQuery:0,...l,minZ:Math.min(t.z,e.z),maxZ:Math.max(t.z,e.z)})};for(const t of e.obstacles){const e=t.connectedTo.some(t=\u003ed(t)===u),n=t.__zLayers??t.zLayers??t.layers.map(p);for(const o of n)f({...t.center,z:o},{...t.center,z:o},0,{width:t.width,height:t.height,rotation:(t.ccwRotationDegrees??0)*Math.PI/180},e)}for(const t of n)if(d(t.connectionName)!==u)for(let e=1;e\u003ct.route.length;e++){const n=t.route[e-1],o=t.route[e];\"through_obstacle\"!==n.toNextSegmentType\u0026\u0026f(n,o,n.z!==o.z?t.viaDiameter/2:Math.max(n.traceThickness??t.traceThickness,o.traceThickness??t.traceThickness)/2)}for(const t of e.traces??[]){if(d(t.connection_name)===u)continue;const n=m1(t,e.minTraceWidth);for(let t=1;t\u003cn.route.length;t++){const e=n.route[t-1],o=n.route[t];\"wire\"===e.route_type\u0026\u0026\"wire\"===o.route_type\u0026\u0026e.layer===o.layer\u0026\u0026f({x:e.x,y:e.y,z:p(e.layer)},{x:o.x,y:o.y,z:p(o.layer)},Math.max(e.width,o.width)/2),\"via\"===o.route_type\u0026\u0026f({x:o.x,y:o.y,z:p(o.from_layer)},{x:o.x,y:o.y,z:p(o.to_layer)},(o.via_diameter??c.viaDiameter)/2)}}const y=new Map,_=Math.max(c.viaDiameter,a)/2+Math.max(t.traceClearance,t.viaClearance,e.defaultObstacleMargin??0,e.minTraceToPadEdgeClearance??0,e.minViaEdgeToPadEdgeClearance??0)+1e-5;for(const t of g)for(let e=Math.floor(Math.max(t.minX,s.minX-_));e\u003c=Math.floor(Math.min(t.maxX,s.maxX+_));e++){let n=y.get(e);for(let o=Math.floor(Math.max(t.minY,s.minY-_));o\u003c=Math.floor(Math.min(t.maxY,s.maxY+_));o++){n||(n=new Map,y.set(e,n));const i=n.get(o);i?i.push(t):n.set(o,[t])}}let b=0;const x={x:0,y:0},v={x:0,y:0},S=(n,o)=\u003e{const i=n.z!==o.z,r=i?c.viaDiameter/2:a/2,s=Math.max(i?t.viaClearance:t.traceClearance,e.defaultObstacleMargin??0,i?e.minViaEdgeToPadEdgeClearance??0:e.minTraceToPadEdgeClearance??0),l=r+s+1e-5,d=++b,h=Math.min(n.x,o.x),u=Math.max(n.x,o.x),p=Math.min(n.y,o.y),m=Math.max(n.y,o.y),g=Math.min(n.z,o.z),f=Math.max(n.z,o.z);for(let e=Math.floor(h-l);e\u003c=Math.floor(u+l);e++){const a=y.get(e);if(a)for(let e=Math.floor(p-l);e\u003c=Math.floor(m+l);e++){const c=a.get(e);if(c)for(const e of c){if(e.viaOnly\u0026\u0026!i)continue;if(e.visitedQuery===d)continue;if(e.visitedQuery=d,e.maxZ\u003cg||e.minZ\u003ef)continue;const a=r+(e.rect?s:i\u0026\u0026e.minZ!==e.maxZ?t.viaClearance:t.traceClearance)+1e-5;if(u+a\u003ce.minX||h-a\u003ee.maxX||m+a\u003ce.minY||p-a\u003ee.maxY)continue;let c;if(e.rect?(x.x=(n.x-e.a.x)*e.rectCos+(n.y-e.a.y)*e.rectSin,x.y=-(n.x-e.a.x)*e.rectSin+(n.y-e.a.y)*e.rectCos,v.x=(o.x-e.a.x)*e.rectCos+(o.y-e.a.y)*e.rectSin,v.y=-(o.x-e.a.x)*e.rectSin+(o.y-e.a.y)*e.rectCos,c=ke(x,v,e.rectBounds)):c=Oe(n,o,e.a,e.b)-e.radius,c\u003ca)return!1}}}return!0};if(!S(i,i)||!S(r,r))return null;const I=t.gridSize??.1;if(!Number.isFinite(I)||I\u003c=0)throw new Error(\"repair04: clearance grid size must be positive and finite\");const C=Math.floor((s.maxX-s.minX)/I),P=Math.floor((s.maxY-s.minY)/I),M=t=\u003e({x:s.minX+(t%C+.5)*I,y:s.minY+(Math.floor(t/C)%P+.5)*I,z:Math.floor(t/(C*P)),traceThickness:a}),N=(t,e,n)=\u003e(n*P+e)*C+t,w=t=\u003eMath.hypot(t.x-r.x,t.y-r.y)+(t.z===r.z?0:1),T=[],R=t=\u003e{T.push(t);let e=T.length-1;for(;e\u003e0;){const n=Math.floor((e-1)/2);if(T[n].priority\u003c=t.priority)break;T[e]=T[n],e=n}T[e]=t},E=()=\u003e{const t=T[0],e=T.pop();if(T.length){let t=0;for(;2*t+1\u003cT.length;){let n=2*t+1;if(n+1\u003cT.length\u0026\u0026T[n+1].priority\u003cT[n].priority\u0026\u0026n++,T[n].priority\u003e=e.priority)break;T[t]=T[n],t=n}T[t]=e}return t},A=new Map,O=new Map,k=(z=i,N(Math.max(0,Math.min(C-1,Math.floor((z.x-s.minX)/I))),Math.max(0,Math.min(P-1,Math.floor((z.y-s.minY)/I))),z.z)),L=k%C,D=Math.floor(k/C)%P;var z;for(let t=-2;t\u003c=2;t++)for(let e=-2;e\u003c=2;e++){const n=L+t,o=D+e;if(n\u003c0||n\u003e=C||o\u003c0||o\u003e=P)continue;const r=N(n,o,i.z),s=M(r);if(!S(i,s))continue;const a=Math.hypot(s.x-i.x,s.y-i.y);A.set(r,a),O.set(r,-1),R({id:r,cost:a,priority:a+w(s)})}const F=C*P*e.layerCount,B=C\u003e0\u0026\u0026P\u003e0\u0026\u0026Number.isSafeInteger(e.layerCount)\u0026\u0026Number.isSafeInteger(F)\u0026\u0026F\u003e0\u0026\u0026Number.isSafeInteger(F*F-1)\u0026\u0026Number.isInteger(i.z)\u0026\u0026i.z\u003e=0\u0026\u0026i.z\u003ce.layerCount,j=new Map;let $=0;for(;T.length\u0026\u0026$\u003c(t.maxNodes??3e4);){const n=E();if($++,t.stats\u0026\u0026(t.stats.nodesPopped=$),n.cost!==A.get(n.id))continue;const o=M(n.id);if(o.z===r.z\u0026\u0026Math.hypot(o.x-r.x,o.y-r.y)\u003c3*I\u0026\u0026S(o,r)){const e=[r];for(let t=n.id;-1!==t;t=O.get(t))e.push(M(t));e.push(i);const o=e.reverse(),s=[i];for(let t=1;t\u003co.length;){let e=t;if(o[t].z===s.at(-1).z)for(let n=t+1;n\u003co.length\u0026\u0026o[n].z===o[t].z;n++)S(s.at(-1),o[n])\u0026\u0026(e=n);s.push(o[e]),t=e+1}return t.stats\u0026\u0026(t.stats.completionReason=\"found\"),s}const s=n.id%C,a=Math.floor(n.id/C)%P,c=[];for(let t=-1;t\u003c=1;t++)for(let e=-1;e\u003c=1;e++)0===t\u0026\u00260===e||s+t\u003c0||s+t\u003e=C||a+e\u003c0||a+e\u003e=P||c.push(N(s+t,a+e,o.z));if(!1!==t.allowLayerChanges)for(let t=0;t\u003ce.layerCount;t++)t!==o.z\u0026\u0026c.push(N(s,a,t));for(const t of c){const e=M(t),i=n.cost+(o.z===e.z?Math.hypot(o.x-e.x,o.y-e.y):1);if(i\u003e=(A.get(t)??1/0))continue;const r=Math.min(n.id,t),s=Math.max(n.id,t),a=B?r*F+s:`${r},${s}`;let c=j.get(a);void 0===c\u0026\u0026(c=S(o,e),j.set(a,c)),c\u0026\u0026(A.set(t,i),O.set(t,n.id),R({id:t,cost:i,priority:i+w(e)}))}}return t.stats\u0026\u0026(t.stats.completionReason=T.length?\"node-limit\":\"no-path\"),null}var f1=(t,e)=\u003e{if(!Number.isInteger(e)||e\u003c1)throw new Error(`Invalid board layer count: ${e}`);const n=Array.from({length:e},(t,n)=\u003e((t,e)=\u003e0===t?\"top\":t===e-1?\"bottom\":`inner${t}`)(n,e)),o=n.findIndex(e=\u003ee===t.from_layer),i=n.findIndex(e=\u003ee===t.to_layer);if(o\u003c0||i\u003c0)throw new Error(`Via span ${t.from_layer} -\u003e ${t.to_layer} is outside the board`);return n.slice(Math.min(o,i),Math.max(o,i)+1)},y1=.005,_1=1e-6,b1=(t,e)=\u003e({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),x1=t=\u003eb1({minX:Math.min(t.start.x,t.end.x),minY:Math.min(t.start.y,t.end.y),maxX:Math.max(t.start.x,t.end.x),maxY:Math.max(t.start.y,t.end.y)},t.width/2),v1=t=\u003e{const e=t.diameter/2;return{minX:t.x-e,minY:t.y-e,maxX:t.x+e,maxY:t.y+e}},S1=t=\u003e({minX:t.x-t.width/2,minY:t.y-t.height/2,maxX:t.x+t.width/2,maxY:t.y+t.height/2}),I1=(t,e)=\u003e`${t}:${e}`,C1=class{constructor(t){this.cellSize=t}cellSize;cells=new Map;insert(t,e){const n=Math.floor(e.minX/this.cellSize),o=Math.floor(e.maxX/this.cellSize),i=Math.floor(e.minY/this.cellSize),r=Math.floor(e.maxY/this.cellSize);for(let e=n;e\u003c=o;e+=1)for(let n=i;n\u003c=r;n+=1){const o=I1(e,n),i=this.cells.get(o);i?i.push(t):this.cells.set(o,[t])}}insertWithCellKeys(t,e){for(const n of e){const e=this.cells.get(n);e?e.push(t):this.cells.set(n,[t])}}getCellKeys(t){const e=Math.floor(t.minX/this.cellSize),n=Math.floor(t.maxX/this.cellSize),o=Math.floor(t.minY/this.cellSize),i=Math.floor(t.maxY/this.cellSize),r=[];for(let t=e;t\u003c=n;t+=1)for(let e=o;e\u003c=i;e+=1)r.push(I1(t,e));return r}queryWithCellKeys(t){const e=new Set;for(const n of t){const t=this.cells.get(n);if(t)for(const n of t)e.add(n)}return[...e]}queryWithCellKeysUsingOrder(t,e){const n=[];for(const o of t){const t=this.cells.get(o);if(t)for(const o of t)o.lastDynamicQueryOrder!==e\u0026\u0026(o.lastDynamicQueryOrder=e,n.push(o))}return n}query(t){const e=Math.floor(t.minX/this.cellSize),n=Math.floor(t.maxX/this.cellSize),o=Math.floor(t.minY/this.cellSize),i=Math.floor(t.maxY/this.cellSize),r=new Set;for(let t=e;t\u003c=n;t+=1)for(let e=o;e\u003c=i;e+=1){const n=this.cells.get(I1(t,e));if(n)for(const t of n)r.add(t)}return[...r]}},P1=(t,e)=\u003e{const n=ve(t.start,t.end,e.start,e.end);if(n)return n;const o=[{left:t.start,right:ze(t.start,e.start,e.end)},{left:t.end,right:ze(t.end,e.start,e.end)},{left:ze(e.start,t.start,t.end),right:e.start},{left:ze(e.end,t.start,t.end),right:e.end}];let i={left:t.start,right:e.start},r=Number.POSITIVE_INFINITY;for(const t of o){const e=Math.hypot(t.left.x-t.right.x,t.left.y-t.right.y);e\u003cr\u0026\u0026(i=t,r=e)}return{x:(i.left.x+i.right.x)/2,y:(i.left.y+i.right.y)/2}},M1=(t,e)=\u003e{const n=ze(e,t.start,t.end);return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}},N1=(t,e)=\u003e{const n=ze({x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},t.start,t.end),o=Math.max(e.minX,Math.min(e.maxX,n.x)),i=Math.max(e.minY,Math.min(e.maxY,n.y));return{x:(n.x+o)/2,y:(n.y+i)/2}},w1=t=\u003e{const e=new Set;for(const n of t.route)\"wire\"===n.route_type\u0026\u0026(n.start_pcb_port_id\u0026\u0026e.add(n.start_pcb_port_id),n.end_pcb_port_id\u0026\u0026e.add(n.end_pcb_port_id));return[...e]},T1=(t,e,n)=\u003en\u003c0?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,R1=class{constructor(t,e={}){if(this.srj=t,this.cacheImmutableTraceGeometry=e.cacheImmutableTraceGeometry??!1,this.useConservativeRectObstaclePrecheck=e.useConservativeRectObstaclePrecheck??!1,this.useTransientDynamicQueryMarkers=e.useTransientDynamicQueryMarkers??!1,this.traceClearance=e.traceClearance??.1,this.viaClearance=Math.max(e.viaClearance??.1,.1),this.viaToPadClearance=e.viaToPadClearance??this.srj.minViaEdgeToPadEdgeClearance??.1,this.connMap=e.connMap,this.includeTraceViaOwnerMetadata=e.includeTraceViaOwnerMetadata??!1,this.cellSize=e.spatialCellSize??this.getDefaultSpatialCellSize(),!Number.isFinite(this.traceClearance)||this.traceClearance\u003c0)throw new Error(\"traceClearance must be a non-negative finite number\");if(!Number.isFinite(this.viaClearance))throw new Error(\"viaClearance must be a finite number\");if(!Number.isFinite(this.viaToPadClearance)||this.viaToPadClearance\u003c0)throw new Error(\"viaToPadClearance must be a non-negative finite number\");if(!Number.isFinite(this.cellSize)||this.cellSize\u003c=0)throw new Error(\"spatialCellSize must be a positive finite number\");if(e.cacheStaticObstacleNetMembership\u0026\u0026this.connMap)throw new Error(\"cacheStaticObstacleNetMembership cannot be combined with connMap\");if(this.cacheImmutableTraceGeometry\u0026\u0026this.connMap)throw new Error(\"cacheImmutableTraceGeometry cannot be combined with connMap\");if(this.useTransientDynamicQueryMarkers\u0026\u0026!this.cacheImmutableTraceGeometry)throw new Error(\"useTransientDynamicQueryMarkers requires cacheImmutableTraceGeometry\");this.compileConnectionAliases(),this.obstacles=this.compileStaticObstacles(),e.cacheStaticObstacleNetMembership\u0026\u0026(this.staticObstacleNets=new Map(this.obstacles.map(t=\u003e[t,new Set(t.connectedTo.map(t=\u003ethis.resolveNetId(t)))]))),this.indexStaticObstacles()}srj;cacheImmutableTraceGeometry;useConservativeRectObstaclePrecheck;useTransientDynamicQueryMarkers;immutableTraceGeometry=new WeakMap;immutableDynamicCellKeys=new WeakMap;immutableDynamicQueryCellKeys=new WeakMap;immutableStaticCandidates=new WeakMap;immutableStaticClearance=new WeakMap;traceClearance;viaClearance;viaToPadClearance;cellSize;connMap;includeTraceViaOwnerMetadata;canonicalNetByAlias=new Map;connMapNetByCanonicalNet=new Map;obstacles;staticObstacleNets;obstacleIndexesByLayer=new Map;lastRunStats={traceCount:0,segmentCount:0,viaCount:0,obstacleCount:0,broadPhaseCandidateCount:0,exactCheckCount:0};getDefaultSpatialCellSize(){const t=Math.max(0,this.srj.bounds.maxX-this.srj.bounds.minX),e=Math.max(0,this.srj.bounds.maxY-this.srj.bounds.minY);return Math.max(.25,Math.max(t,e)/64,(this.srj.minViaDiameter??.3)+Math.max(this.traceClearance,this.viaToPadClearance))}compileConnectionAliases(){const t=new Map;for(const e of this.srj.connections){const n=e.netConnectionName??e.rootConnectionName??e.name,o=[e.name,e.rootConnectionName,e.netConnectionName,...e.mergedConnectionNames??[],...e.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])];for(const e of o){if(!e)continue;this.canonicalNetByAlias.set(e,n);const o=this.connMap?.getNetConnectedToId(e);if(!o)continue;let i=t.get(n);i||(i=new Set,t.set(n,i)),i.add(o)}this.canonicalNetByAlias.set(n,n)}for(const[e,n]of t)1===n.size\u0026\u0026this.connMapNetByCanonicalNet.set(e,n.values().next().value)}resolveNetId(t){const e=this.connMap?.getNetConnectedToId(t);if(e)return e;const n=this.canonicalNetByAlias.get(t);return n?this.connMapNetByCanonicalNet.get(n)??n:t}areConnected(t,e){return t===e||(!!this.connMap?.areIdsConnected(t,e)||this.resolveNetId(t)===this.resolveNetId(e))}compileStaticObstacles(){const t=[],e=new Set,n=new Set;for(const o of this.srj.obstacles){if(0===o.layers.length)continue;const i=o.connectedTo.find(t=\u003et.startsWith(\"pcb_smtpad_\")),r=o.connectedTo.find(t=\u003et.startsWith(\"pcb_plated_hole_\")),s=o.connectedTo.find(t=\u003et.startsWith(\"pcb_port_\"));if(!i\u0026\u0026!r\u0026\u0026!s)continue;const a=o.layers.length\u003e1,c=a?\"pcb_plated_hole\":\"pcb_smtpad\",l=a?r??`pcb_plated_hole_${o.center.x.toFixed(3)}_${o.center.y.toFixed(3)}`:i??`pcb_smtpad_${o.center.x.toFixed(3)}_${o.center.y.toFixed(3)}`,d=a?n:e;if(d.has(l))continue;d.add(l);const h=a\u0026\u0026Math.abs(o.width-o.height)\u003c.001;t.push({kind:\"obstacle\",obstacleType:c,obstacleId:l,connectedTo:o.connectedTo,x:o.center.x,y:o.center.y,width:o.width,height:o.height,...h?{radius:Math.max(o.width,o.height)/2}:{},layers:o.layers,...s?{pcbPortId:s}:{}})}return t}indexStaticObstacles(){for(const t of this.obstacles){const e=b1(S1(t),Math.max(this.traceClearance,this.viaToPadClearance));for(const n of t.layers){let o=this.obstacleIndexesByLayer.get(n);o||(o=new C1(this.cellSize),this.obstacleIndexesByLayer.set(n,o)),o.insert(t,e)}}}getImmutableTraceGeometry(t){const e=this.immutableTraceGeometry.get(t);if(e)return e;const n=this.resolveNetId(t.connection_name),o=w1(t),i=[];for(let e=0;e\u003ct.route.length-1;e++){const r=t.route[e],s=t.route[e+1];\"wire\"===r?.route_type\u0026\u0026\"wire\"===s?.route_type\u0026\u0026r.layer===s.layer\u0026\u0026(Math.abs(r.x-s.x)\u003c=_1\u0026\u0026Math.abs(r.y-s.y)\u003c=_1||i.push({geometryKey:{},kind:\"trace_segment\",traceId:t.pcb_trace_id,netId:n,start:{x:r.x,y:r.y},end:{x:s.x,y:s.y},width:E1(r,s),layer:r.layer,pcbPortIds:o}))}const r=[];for(const e of t.route)\"via\"===e.route_type\u0026\u0026r.push({locationKey:`${e.x},${e.y},${e.from_layer},${e.to_layer}`,point:e,geometryKey:{}});const s={segments:i,vias:r,traceId:t.pcb_trace_id,netId:n};return this.immutableTraceGeometry.set(t,s),s}collectImmutableDynamicGeometry(t){const e=[],n=[],o=new Set;for(const i of t){const t=this.getImmutableTraceGeometry(i);for(const n of t.segments)e.push({geometryKey:n.geometryKey,kind:\"trace_segment\",traceId:n.traceId,netId:n.netId,start:n.start,end:n.end,width:n.width,layer:n.layer,pcbPortIds:n.pcbPortIds,order:e.length});for(const e of t.vias){if(o.has(e.locationKey))continue;o.add(e.locationKey);const i=e.point,r=e.prepared??={geometryKey:e.geometryKey,kind:\"via\",traceId:t.traceId,netId:t.netId,x:i.x,y:i.y,diameter:i.via_diameter??this.srj.minViaDiameter??.3,layers:f1(i,this.srj.layerCount)};n.push({geometryKey:r.geometryKey,kind:\"via\",traceId:r.traceId,netId:r.netId,x:r.x,y:r.y,diameter:r.diameter,layers:r.layers,order:n.length,viaId:`via_${n.length}`})}}return{segments:e,vias:n}}collectDynamicGeometry(t){if(this.cacheImmutableTraceGeometry)return this.collectImmutableDynamicGeometry(t);const e=[],n=[],o=new Set;for(const i of t){const t=this.resolveNetId(i.connection_name),r=w1(i);for(let n=0;n\u003ci.route.length-1;n+=1){const o=i.route[n],s=i.route[n+1];\"wire\"===o?.route_type\u0026\u0026\"wire\"===s?.route_type\u0026\u0026o.layer===s.layer\u0026\u0026(Math.abs(o.x-s.x)\u003c=_1\u0026\u0026Math.abs(o.y-s.y)\u003c=_1||e.push({kind:\"trace_segment\",order:e.length,traceId:i.pcb_trace_id,netId:t,start:{x:o.x,y:o.y},end:{x:s.x,y:s.y},width:E1(o,s),layer:o.layer,pcbPortIds:r}))}for(const e of i.route){if(\"via\"!==e.route_type)continue;const r=`${e.x},${e.y},${e.from_layer},${e.to_layer}`;o.has(r)||(o.add(r),n.push({kind:\"via\",order:n.length,viaId:`via_${n.length}`,traceId:i.pcb_trace_id,netId:t,x:e.x,y:e.y,diameter:e.via_diameter??this.srj.minViaDiameter??.3,layers:f1(e,this.srj.layerCount)}))}}return{segments:e,vias:n}}getImmutableDynamicCellKeys(t,e){const n=t.geometryKey;if(!n)throw new Error(\"Immutable spatial cache requires private entity identities\");let o=this.immutableDynamicCellKeys.get(n);if(!o){const i=\"trace_segment\"===t.kind?x1(t):v1(t);o=e.getCellKeys(b1(i,this.traceClearance)),this.immutableDynamicCellKeys.set(n,o)}return o}getImmutableDynamicQueryCellKeys(t,e,n){const o=t.geometryKey;if(!o)throw new Error(\"Immutable spatial cache requires private entity identities\");let i=this.immutableDynamicQueryCellKeys.get(o);return i||(i=e.getCellKeys(n),this.immutableDynamicQueryCellKeys.set(o,i)),i}getStaticObstacleCandidates(t,e){const n=t.geometryKey;if(!n)throw new Error(\"Immutable spatial cache requires private entity identities\");let o=this.immutableStaticCandidates.get(n);o||(o=new Map,this.immutableStaticCandidates.set(n,o));let i=o.get(e);if(!i){const n=\"trace_segment\"===t.kind?x1(t):v1(t);i=this.obstacleIndexesByLayer.get(e)?.query(n)??[],o.set(e,i)}return i}buildImmutableDynamicIndexes(t,e){const n=new Map,o=(t,e)=\u003e{let o=n.get(t);o||(o=new C1(this.cellSize),n.set(t,o)),o.insertWithCellKeys(e,this.getImmutableDynamicCellKeys(e,o))};for(const e of t)o(e.layer,e);for(const t of e)for(const e of t.layers)o(e,t);return n}buildDynamicIndexes(t,e){if(this.cacheImmutableTraceGeometry)return this.buildImmutableDynamicIndexes(t,e);const n=new Map,o=(t,e,o)=\u003e{let i=n.get(t);i||(i=new C1(this.cellSize),n.set(t,i)),i.insert(e,b1(o,this.traceClearance))};for(const e of t)o(e.layer,e,x1(e));for(const t of e)for(const e of t.layers)o(e,t,v1(t));return n}obstacleSharesNet(t,e){return this.staticObstacleNets?this.staticObstacleNets.get(e).has(this.resolveNetId(t)):e.connectedTo.some(e=\u003ethis.areConnected(t,e))}checkTracePair(t,e){if(this.areConnected(t.netId,e.netId))return;this.lastRunStats.exactCheckCount+=1;const n=Oe(t.start,t.end,e.start,e.end)-t.width/2-e.width/2;if(n\u003ethis.traceClearance-y1)return;const o=`overlap_${t.traceId}_${e.traceId}`;return{type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:T1(t.traceId,`PCB trace ${e.traceId}`,n),pcb_trace_id:t.traceId,source_trace_id:\"\",pcb_trace_error_id:o,minimum_clearance:this.traceClearance,actual_clearance:n,pcb_component_ids:[],pcb_port_ids:[...new Set([...t.pcbPortIds,...e.pcbPortIds])],center:this.cacheImmutableTraceGeometry?{...P1(t,e)}:P1(t,e)}}checkTraceVia(t,e){if(this.areConnected(t.netId,e.netId))return;this.lastRunStats.exactCheckCount+=1;const n=De(t.start,t.end,{x:e.x,y:e.y,radius:e.diameter/2})-t.width/2;if(n\u003ethis.traceClearance-y1)return;const o=`overlap_${t.traceId}_${e.viaId}`;return{type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:T1(t.traceId,`pcb_via \"${e.viaId}\"`,n),pcb_trace_id:t.traceId,...this.includeTraceViaOwnerMetadata?{pcb_trace_ids:[t.traceId,e.traceId],pcb_via_id:e.viaId,pcb_via_ids:[e.viaId]}:{},source_trace_id:\"\",pcb_trace_error_id:o,minimum_clearance:this.traceClearance,actual_clearance:n,pcb_component_ids:[],pcb_port_ids:this.cacheImmutableTraceGeometry?[...t.pcbPortIds]:t.pcbPortIds,center:M1(t,e)}}checkTraceObstacle(t,e){if(this.obstacleSharesNet(t.netId,e))return;this.lastRunStats.exactCheckCount+=1;const n=S1(e);if(this.useConservativeRectObstaclePrecheck\u0026\u0026void 0===e.radius\u0026\u0026((t,e,n)=\u003e{const o=t.width/2+n-y1;return Math.max(e.minX-Math.max(t.start.x,t.end.x),Math.min(t.start.x,t.end.x)-e.maxX,e.minY-Math.max(t.start.y,t.end.y),Math.min(t.start.y,t.end.y)-e.maxY)\u003eo+1e-9\u0026\u0026e.minX\u003c=e.maxX\u0026\u0026e.minY\u003c=e.maxY\u0026\u0026Number.isFinite(o)\u0026\u0026Math.abs(t.start.x)\u003c=1e4\u0026\u0026Math.abs(t.start.y)\u003c=1e4\u0026\u0026Math.abs(t.end.x)\u003c=1e4\u0026\u0026Math.abs(t.end.y)\u003c=1e4\u0026\u0026Math.abs(e.minX)\u003c=1e4\u0026\u0026Math.abs(e.minY)\u003c=1e4\u0026\u0026Math.abs(e.maxX)\u003c=1e4\u0026\u0026Math.abs(e.maxY)\u003c=1e4})(t,n,this.traceClearance))return;const o=(void 0===e.radius?ke(t.start,t.end,n):De(t.start,t.end,{x:e.x,y:e.y,radius:e.radius}))-t.width/2;if(o+y1\u003e=this.traceClearance)return;const i=`overlap_${t.traceId}_${e.obstacleId}`;return{type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:T1(t.traceId,`${e.obstacleType} \"${e.obstacleId}\"`,o),pcb_trace_id:t.traceId,source_trace_id:\"\",pcb_trace_error_id:i,minimum_clearance:this.traceClearance,actual_clearance:o,pcb_component_ids:[],pcb_port_ids:[...new Set([...t.pcbPortIds,...e.pcbPortId?[e.pcbPortId]:[]])],center:void 0===e.radius?N1(t,n):M1(t,e)}}appendTraceObstacleErrors(t,e){const n=this.cacheImmutableTraceGeometry?t.geometryKey:void 0,o=n?this.immutableStaticClearance.get(n):void 0;if(o)return this.lastRunStats.broadPhaseCandidateCount+=o.broadPhaseCandidateCount,void(this.lastRunStats.exactCheckCount+=o.exactCheckCount);const i=this.cacheImmutableTraceGeometry?this.getStaticObstacleCandidates(t,t.layer):this.obstacleIndexesByLayer.get(t.layer)?.query(x1(t))??[],r=e.length,s=this.lastRunStats.exactCheckCount;for(const n of i){this.lastRunStats.broadPhaseCandidateCount+=1;const o=this.checkTraceObstacle(t,n);o\u0026\u0026e.push(o)}n\u0026\u0026e.length===r\u0026\u0026this.immutableStaticClearance.set(n,{broadPhaseCandidateCount:i.length,exactCheckCount:this.lastRunStats.exactCheckCount-s})}checkViaObstacle(t,e){if(this.obstacleSharesNet(t.netId,e))return;this.lastRunStats.exactCheckCount+=1;const n=S1(e),o=(void 0===e.radius?Math.hypot(Math.max(n.minX-t.x,0,t.x-n.maxX),Math.max(n.minY-t.y,0,t.y-n.maxY)):Math.hypot(t.x-e.x,t.y-e.y)-e.radius)-t.diameter/2;if(o+y1\u003e=this.viaToPadClearance)return;const i=`via_pad_clearance_${t.viaId}_${e.obstacleId}`,r={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return{type:\"pcb_pad_pad_clearance_error\",error_type:\"pcb_pad_pad_clearance_error\",pcb_pad_pad_clearance_error_id:i,message:`pcb_via \"${t.viaId}\" and ${e.obstacleType} \"${e.obstacleId}\" are too close (gap: ${o.toFixed(3)}mm)`,pcb_trace_id:t.traceId,pcb_pad_ids:[t.viaId,e.obstacleId],pcb_via_ids:[t.viaId],minimum_clearance:this.viaToPadClearance,actual_clearance:o,center:r}}checkViaPairs(t){if(t.length\u003c2)return[];const e=[],n=new C1(this.cellSize);for(const e of t)n.insert(e,b1(v1(e),this.viaClearance));for(const o of t)for(const t of n.query(v1(o))){if(this.lastRunStats.broadPhaseCandidateCount+=1,t.order\u003c=o.order)continue;this.lastRunStats.exactCheckCount+=1;const n=Math.hypot(o.x-t.x,o.y-t.y);if(n\u003c=_1)continue;const i=n-o.diameter/2-t.diameter/2;if(i+y1\u003e=this.viaClearance)continue;const r=this.areConnected(o.netId,t.netId),s=[o.viaId,t.viaId].sort().join(\"_\"),a={x:(o.x+t.x)/2,y:(o.y+t.y)/2};e.push({type:\"pcb_via_clearance_error\",error_type:\"pcb_via_clearance_error\",pcb_error_id:`${r?\"same_net\":\"different_net\"}_vias_close_${s}`,message:`Vias ${o.viaId} and ${t.viaId}${r?\"\":\" from different nets\"} are too close together (gap: ${i.toFixed(3)}mm)`,pcb_via_ids:[o.viaId,t.viaId],...this.includeTraceViaOwnerMetadata?{pcb_trace_ids:[o.traceId,t.traceId]}:{},pcb_via_pair_net_relation:r?\"same_net\":\"different_net\",minimum_clearance:this.viaClearance,actual_clearance:i,pcb_center:a,center:a})}return e}evaluate(t){return this.evaluateInternal(t,!0)}evaluateLegacy(t){return this.evaluateInternal(t,!1)}evaluateInternal(t,e){const{segments:n,vias:o}=this.collectDynamicGeometry(t),i=this.buildDynamicIndexes(n,o),r=[],s=[];this.lastRunStats={traceCount:t.length,segmentCount:n.length,viaCount:o.length,obstacleCount:this.obstacles.length,broadPhaseCandidateCount:0,exactCheckCount:0};for(const t of n){const e=x1(t),n=i.get(t.layer),o=n?this.cacheImmutableTraceGeometry?this.useTransientDynamicQueryMarkers?n.queryWithCellKeysUsingOrder(this.getImmutableDynamicQueryCellKeys(t,n,e),t.order):n.queryWithCellKeys(this.getImmutableDynamicQueryCellKeys(t,n,e)):n.query(e):[];for(const e of o){if(this.lastRunStats.broadPhaseCandidateCount+=1,\"trace_segment\"===e.kind\u0026\u0026e.order\u003c=t.order)continue;const n=\"trace_segment\"===e.kind?this.checkTracePair(t,e):this.checkTraceVia(t,e);n\u0026\u0026r.push(n)}this.appendTraceObstacleErrors(t,r)}const a=this.checkViaPairs(o);if(e)for(const t of o){const e=new Set;for(const n of t.layers){const o=this.cacheImmutableTraceGeometry?this.getStaticObstacleCandidates(t,n):this.obstacleIndexesByLayer.get(n)?.query(v1(t))??[];for(const n of o){if(e.has(n))continue;e.add(n),this.lastRunStats.broadPhaseCandidateCount+=1;const o=this.checkViaObstacle(t,n);o\u0026\u0026s.push(o)}}}const c=new Map;for(const t of r){const e=String(t.pcb_trace_error_id),n=c.get(e),o=Number(t.actual_clearance);if(!n){c.set(e,{...t,first_contact_center:t.center,first_contact_message:t.message,first_actual_clearance:o,worst_contact_center:t.center,worst_contact_message:t.message,worst_actual_clearance:o});continue}const i=Number(n.worst_actual_clearance);(o\u003ci||!Number.isFinite(i))\u0026\u0026(n.worst_contact_center=t.center,n.worst_contact_message=t.message,n.worst_actual_clearance=o)}const l=[...c.values()].map(t=\u003e({...t,center:\"object\"==typeof t.worst_contact_center?t.worst_contact_center:t.center,message:\"string\"==typeof t.worst_contact_message?t.worst_contact_message:t.message,actual_clearance:\"number\"==typeof t.worst_actual_clearance?t.worst_actual_clearance:t.actual_clearance}));l.push(...s),l.push(...a);const d=l.filter(t=\u003et.center);return{errors:l,errorsWithCenters:d,locationAwareErrors:d}}},E1=(t,e)=\u003et.width??e.width??.1,A1={Hz:{baseUnit:\"Hz\",variants:{MHz:1e6,kHz:1e3,Hz:1}},g:{baseUnit:\"g\",variants:{kg:1e3,g:1}},\"Ω\":{baseUnit:\"Ω\",variants:{\"mΩ\":.001,\"Ω\":1,\"kΩ\":1e3,\"KΩ\":1e3,kohm:1e3,\"MΩ\":1e6,\"GΩ\":1e9,\"TΩ\":1e12}},V:{baseUnit:\"V\",variants:{mV:.001,V:1,kV:1e3,KV:1e3,MV:1e6,GV:1e9,TV:1e12}},A:{baseUnit:\"A\",variants:{\"µA\":1e-6,mA:.001,ma:.001,A:1,kA:1e3,MA:1e6}},F:{baseUnit:\"F\",variants:{pF:1e-12,nF:1e-9,\"µF\":1e-6,uF:1e-6,mF:.001,F:1}},ml:{baseUnit:\"ml\",variants:{ml:1,mL:1,l:1e3,L:1e3}},deg:{baseUnit:\"deg\",variants:{rad:180/Math.PI}},ms:{baseUnit:\"ms\",variants:{fs:1e-12,ps:1e-9,ns:1e-6,us:.001,\"µs\":.001,ms:1,s:1e3}},mm:{baseUnit:\"mm\",variants:{nm:1e-6,\"µm\":.001,um:.001,mm:1,cm:10,dm:100,m:1e3,km:1e6,in:25.4,ft:304.8,IN:25.4,FT:304.8,yd:914.4,mi:1609344,mil:.0254}}},O1=new Set;for(const[t,e]of Object.entries(A1)){O1.add(t);for(const t of Object.keys(e.variants))O1.add(t)}var k1={tera:1e12,T:1e12,giga:1e9,G:1e9,mega:1e6,M:1e6,kilo:1e3,k:1e3,deci:.1,d:.1,centi:.01,c:.01,milli:.001,m:.001,micro:1e-6,u:1e-6,\"µ\":1e-6,nano:1e-9,n:1e-9,pico:1e-12,p:1e-12};function L1(t){if(null==t)return{parsedUnit:null,unitOfValue:null,value:null};if(\"string\"==typeof t\u0026\u0026t.match(/^-?[\\d\\.]+$/))return{value:Number.parseFloat(t),parsedUnit:null,unitOfValue:null};if(\"number\"==typeof t)return{value:t,parsedUnit:null,unitOfValue:null};if(\"object\"==typeof t\u0026\u0026\"x\"in t\u0026\u0026\"y\"in t){const{parsedUnit:e,unitOfValue:n}=L1(t.x),o=L1(t.x),i=L1(t.y);return null===o.value||null===i.value?{parsedUnit:null,unitOfValue:null,value:null}:{parsedUnit:e,unitOfValue:n,value:{x:o.value,y:i.value}}}const e=t.toString().split(\"\").reverse().join(\"\"),n=e.match(/[^\\d\\s]+/)?.[0];if(!n)throw new Error(`Could not determine unit: \"${t}\"`);const o=n.split(\"\").reverse().join(\"\"),i=t.slice(0,-o.length);if(o in k1\u0026\u0026!O1.has(o)){const t=k1[o];return{parsedUnit:null,unitOfValue:null,value:Number.parseFloat(i)*t}}const{baseUnit:r,conversionFactor:s}=function(t){for(const[e,n]of Object.entries(A1))if(t in n.variants)return{baseUnit:n.baseUnit,conversionFactor:n.variants[t]};return{baseUnit:t,conversionFactor:1}}(o);return{parsedUnit:o,unitOfValue:r,value:s*Number.parseFloat(i)}}var D1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),z1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value).transform(t=\u003eNumber.parseFloat(t.toPrecision(12))),F1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),B1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),j1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),$1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),Y1=j1,X1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),V1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),W1=V1,H1=k_.string().datetime(),G1=k_.string().or(k_.number()).transform(t=\u003e\"number\"==typeof t?t:t.endsWith(\"deg\")?Number.parseFloat(t.split(\"deg\")[0]):t.endsWith(\"rad\")?180*Number.parseFloat(t.split(\"rad\")[0])/Math.PI:Number.parseFloat(t)),U1=k_.number().or(k_.string().endsWith(\"mAh\")).transform(t=\u003e{if(\"string\"==typeof t){const e=t.replace(\"mAh\",\"\"),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error(\"Invalid capacity\");return n}return t}).describe(\"Battery capacity in mAh\"),Z1=k_.object({x:Y1,y:Y1}),q1=k_.object({x:Y1,y:Y1,z:Y1}),J1=k_.object({width:k_.number(),height:k_.number()}),K1=t=\u003ek_.string().optional().default(()=\u003e`${t}_${(t=\u003e{const e=\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";return Array.from({length:t},()=\u003ee[Math.floor(62*Math.random())]).join(\"\")})(10)}`),Q1=k_.enum([\"top_left\",\"top_center\",\"top_right\",\"center_left\",\"center\",\"center_right\",\"bottom_left\",\"bottom_center\",\"bottom_right\"]),t2=(k_.enum([\"top_silkscreen\",\"bottom_silkscreen\",\"top_copper\",\"bottom_copper\",\"top_soldermask\",\"bottom_soldermask\",\"top_fabrication_note\",\"bottom_fabrication_note\",\"top_user_note\",\"bottom_user_note\",\"top_courtyard\",\"bottom_courtyard\",\"inner1_copper\",\"inner2_copper\",\"inner3_copper\",\"inner4_copper\",\"inner5_copper\",\"inner6_copper\",\"edge_cuts\",\"drill\"]),k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()})),e2=Z1.extend({rotation:G1.optional()}),n2=k_.object({size:Z1.optional(),thickness:Y1.optional()}),o2=k_.object({font:n2.optional()}),i2=k_.object({value:k_.string(),at:e2.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:o2.optional()}),r2=k_.object({Reference:i2.optional(),Value:i2.optional(),Datasheet:i2.optional(),Description:i2.optional()}),s2=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),a2=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:e2.optional(),size:Z1.optional(),drill:Y1.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),c2=k_.object({path:k_.string(),offset:q1.optional(),scale:q1.optional(),rotate:q1.optional()}),l2=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:r2.optional(),attributes:s2.optional(),pads:k_.array(a2).optional(),embeddedFonts:k_.boolean().optional(),model:c2.optional()}),d2=k_.object({hide:k_.boolean().optional()}),h2=k_.object({offset:Y1.optional(),hide:k_.boolean().optional()}),u2=k_.object({font:n2.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),p2=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:e2.optional(),effects:u2.optional()}),m2=k_.object({Reference:p2.optional(),Value:p2.optional(),Footprint:p2.optional(),Datasheet:p2.optional(),Description:p2.optional(),ki_keywords:p2.optional(),ki_fp_filters:p2.optional()}),g2=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:d2.optional(),pinNames:h2.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:m2.optional(),embeddedFonts:k_.boolean().optional()}),f2=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),y2=k_.enum([\"jlcpcb\",\"macrofab\",\"pcbway\",\"digikey\",\"mouser\",\"lcsc\"]),_2=k_.object({type:k_.literal(\"source_component\"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(y2,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),b2=_2.extend({ftype:k_.literal(\"simple_capacitor\"),capacitance:z1,max_voltage_rating:B1.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:Y1.optional()}),x2=_2.extend({ftype:k_.literal(\"simple_resistor\"),resistance:D1,display_resistance:k_.string().optional()}),v2=_2.extend({ftype:k_.literal(\"simple_diode\")}),S2=_2.extend({ftype:k_.literal(\"simple_fiducial\")}),I2=v2.extend({ftype:k_.literal(\"simple_led\"),color:k_.string().optional(),wavelength:k_.string().optional()}),C2=_2.extend({ftype:k_.literal(\"simple_ground\")}),P2=_2.extend({ftype:k_.literal(\"simple_chip\")}),M2=_2.extend({ftype:k_.literal(\"simple_power_source\"),voltage:B1}),N2=_2.extend({ftype:k_.literal(\"simple_current_source\"),current:X1,frequency:$1.optional(),peak_to_peak_current:X1.optional(),wave_shape:k_.enum([\"sine\",\"square\",\"triangle\",\"sawtooth\",\"dc\"]).optional().default(\"dc\"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),w2=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),T2=_2.extend({ftype:k_.literal(\"simple_fuse\"),current_rating_amps:k_.number().describe(\"Nominal current in amps the fuse is rated for\"),voltage_rating_volts:k_.number().describe(\"Voltage rating in volts, e.g. ±5V would be 5\")}),R2=_2.extend({ftype:k_.literal(\"simple_battery\"),capacity:U1}),E2=_2.extend({ftype:k_.literal(\"simple_inductor\"),inductance:F1,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),A2=_2.extend({ftype:k_.literal(\"simple_push_button\")}),O2=_2.extend({ftype:k_.literal(\"simple_potentiometer\"),max_resistance:D1,display_max_resistance:k_.string().optional()}),k2=_2.extend({ftype:k_.literal(\"simple_crystal\"),frequency:k_.number().describe(\"Frequency in Hz\"),load_capacitance:k_.number().optional().describe(\"Load capacitance in pF\"),pin_variant:k_.enum([\"two_pin\",\"four_pin\"]).optional()}),L2=_2.extend({ftype:k_.literal(\"simple_pin_header\"),pin_count:k_.number(),gender:k_.enum([\"male\",\"female\"]).optional().default(\"male\")}),D2=_2.extend({ftype:k_.literal(\"simple_connector\"),standard:k_.enum([\"usb_c\",\"m2\"]).optional()}),z2=_2.extend({ftype:k_.literal(\"simple_pinout\")}),F2=_2.extend({ftype:k_.literal(\"simple_resonator\"),load_capacitance:z1,equivalent_series_resistance:D1.optional(),frequency:$1}),B2=_2.extend({ftype:k_.literal(\"simple_transistor\"),transistor_type:k_.enum([\"npn\",\"pnp\"])}),j2=_2.extend({ftype:k_.literal(\"simple_test_point\"),footprint_variant:k_.enum([\"pad\",\"through_hole\"]).optional(),pad_shape:k_.enum([\"rect\",\"circle\"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),$2=_2.extend({ftype:k_.literal(\"simple_mosfet\"),channel_type:k_.enum([\"n\",\"p\"]),mosfet_mode:k_.enum([\"enhancement\",\"depletion\"])}),Y2=_2.extend({ftype:k_.literal(\"simple_op_amp\")}),X2=_2.extend({ftype:k_.literal(\"simple_switch\")}),V2=k_.object({type:k_.literal(\"source_project_metadata\"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),created_at:H1.optional()}),W2=f2.extend({type:k_.literal(\"source_missing_property_error\"),source_missing_property_error_id:K1(\"source_missing_property_error\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_missing_property_error\").default(\"source_missing_property_error\")}).describe(\"The source code is missing a property\"),H2=f2.extend({type:k_.literal(\"source_failed_to_create_component_error\"),source_failed_to_create_component_error_id:K1(\"source_failed_to_create_component_error\"),error_type:k_.literal(\"source_failed_to_create_component_error\").default(\"source_failed_to_create_component_error\"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe(\"Error emitted when a component fails to be constructed\"),G2=f2.extend({type:k_.literal(\"source_invalid_component_property_error\"),source_invalid_component_property_error_id:K1(\"source_invalid_component_property_error\"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_invalid_component_property_error\").default(\"source_invalid_component_property_error\")}).describe(\"The source component property is invalid\"),U2=f2.extend({type:k_.literal(\"source_trace_not_connected_error\"),source_trace_not_connected_error_id:K1(\"source_trace_not_connected_error\"),error_type:k_.literal(\"source_trace_not_connected_error\").default(\"source_trace_not_connected_error\"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe(\"Occurs when a source trace selector does not match any ports\"),Z2=k_.object({type:k_.literal(\"source_property_ignored_warning\"),source_property_ignored_warning_id:K1(\"source_property_ignored_warning\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_property_ignored_warning\").default(\"source_property_ignored_warning\"),message:k_.string()}).describe(\"The source property was ignored\"),q2=k_.object({type:k_.literal(\"source_pin_missing_trace_warning\"),source_pin_missing_trace_warning_id:K1(\"source_pin_missing_trace_warning\"),warning_type:k_.literal(\"source_pin_missing_trace_warning\").default(\"source_pin_missing_trace_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component pin is missing a trace connection\"),J2=k_.object({type:k_.literal(\"source_missing_manufacturer_part_number_warning\"),source_missing_manufacturer_part_number_warning_id:K1(\"source_missing_manufacturer_part_number_warning\"),warning_type:k_.literal(\"source_missing_manufacturer_part_number_warning\").default(\"source_missing_manufacturer_part_number_warning\"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a standard connector is missing manufacturer part number\"),K2=_2.extend({ftype:k_.literal(\"simple_voltage_probe\")}),Q2=_2.extend({ftype:k_.literal(\"interconnect\")}),t5=f2.extend({type:k_.literal(\"source_i2c_misconfigured_error\"),source_i2c_misconfigured_error_id:K1(\"source_i2c_misconfigured_error\"),error_type:k_.literal(\"source_i2c_misconfigured_error\").default(\"source_i2c_misconfigured_error\"),source_port_ids:k_.array(k_.string())}).describe(\"Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net\"),e5=_2.extend({ftype:k_.literal(\"simple_voltage_source\"),voltage:B1,frequency:$1.optional(),peak_to_peak_voltage:B1.optional(),wave_shape:k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]).optional(),phase:G1.optional(),duty_cycle:k_.number().optional().describe(\"Duty cycle as a fraction (0 to 1)\")}),n5=k_.union([x2,b2,v2,S2,I2,C2,P2,M2,N2,R2,E2,A2,O2,k2,L2,D2,z2,F2,X2,B2,j2,$2,Y2,T2,K2,Q2,e5,V2,W2,G2,H2,U2,Z2,q2,J2,t5]),o5=k_.object({type:k_.literal(\"source_port\"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(w2),i5=k_.object({type:k_.literal(\"source_component_internal_connection\"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),r5=k_.object({type:k_.literal(\"source_trace\"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),s5=k_.object({type:k_.literal(\"source_group\"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),a5=k_.object({type:k_.literal(\"source_net\"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),c5=k_.object({type:k_.literal(\"source_board\"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe(\"Defines a board in the source domain\"),l5=f2.extend({type:k_.literal(\"source_ambiguous_port_reference\"),source_ambiguous_port_reference_id:K1(\"source_ambiguous_port_reference\"),error_type:k_.literal(\"source_ambiguous_port_reference\").default(\"source_ambiguous_port_reference\"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous\"),d5=k_.object({type:k_.literal(\"source_pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane in the source domain\"),h5=k_.enum([\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\"]),u5=h5.or(k_.object({name:h5})).transform(t=\u003e\"string\"==typeof t?t:t.name),p5=k_.enum([\"top\",\"bottom\"]),m5=k_.object({type:k_.literal(\"source_manually_placed_via\"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe(\"Defines a via that is manually placed in the source domain\"),g5=k_.object({type:k_.literal(\"source_no_power_pin_defined_warning\"),source_no_power_pin_defined_warning_id:K1(\"source_no_power_pin_defined_warning\"),warning_type:k_.literal(\"source_no_power_pin_defined_warning\").default(\"source_no_power_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports with requires_power=true\"),f5=k_.object({type:k_.literal(\"source_no_ground_pin_defined_warning\"),source_no_ground_pin_defined_warning_id:K1(\"source_no_ground_pin_defined_warning\"),warning_type:k_.literal(\"source_no_ground_pin_defined_warning\").default(\"source_no_ground_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports marked as ground pins\"),y5=k_.object({type:k_.literal(\"source_component_pins_underspecified_warning\"),source_component_pins_underspecified_warning_id:K1(\"source_component_pins_underspecified_warning\"),warning_type:k_.literal(\"source_component_pins_underspecified_warning\").default(\"source_component_pins_underspecified_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when all ports on a source component are underspecified\"),_5=f2.extend({type:k_.literal(\"source_pin_must_be_connected_error\"),source_pin_must_be_connected_error_id:K1(\"source_pin_must_be_connected_error\"),error_type:k_.literal(\"source_pin_must_be_connected_error\").default(\"source_pin_must_be_connected_error\"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pin with mustBeConnected attribute is not connected to any trace\"),b5=f2.extend({type:k_.literal(\"unknown_error_finding_part\"),unknown_error_finding_part_id:K1(\"unknown_error_finding_part\"),error_type:k_.literal(\"unknown_error_finding_part\").default(\"unknown_error_finding_part\"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when an unexpected error occurs while finding a part\"),x5=k_.object({type:k_.literal(\"schematic_box\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:Y1,height:Y1,is_dashed:k_.boolean().default(!1),x:Y1,y:Y1,subcircuit_id:k_.string().optional()}).describe(\"Draws a box on the schematic\"),v5=k_.object({type:k_.literal(\"schematic_path\"),schematic_path_id:K1(\"schematic_path\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),stroke_width:Y1.nullable().optional(),stroke_color:k_.string().optional(),points:k_.array(Z1),subcircuit_id:k_.string().optional()}),S5=k_.record(k_.object({left_margin:j1.optional(),right_margin:j1.optional(),top_margin:j1.optional(),bottom_margin:j1.optional()})),I5=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),C5=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional()}),P5=k_.union([I5,C5]),M5=k_.object({type:k_.literal(\"schematic_component\"),size:J1,center:Z1,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_symbol_id:k_.string().optional(),pin_spacing:j1.optional(),pin_styles:S5.optional(),box_width:j1.optional(),symbol_name:k_.string().optional(),port_arrangement:P5.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),N5=k_.object({kicad_symbol:g2.optional()}).catchall(k_.unknown()),w5=k_.object({type:k_.literal(\"schematic_symbol\"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:N5.optional()}).describe(\"Defines a named schematic symbol that can be referenced by components.\"),T5=k_.object({type:k_.literal(\"schematic_line\"),schematic_line_id:K1(\"schematic_line\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:Y1,y1:Y1,x2:Y1,y2:Y1,stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled line on the schematic\"),R5=k_.object({type:k_.literal(\"schematic_rect\"),schematic_rect_id:K1(\"schematic_rect\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,width:Y1,height:Y1,rotation:G1.default(0),stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled rectangle on the schematic\"),E5=k_.object({type:k_.literal(\"schematic_circle\"),schematic_circle_id:K1(\"schematic_circle\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,radius:Y1,stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled circle on the schematic\"),A5=k_.object({type:k_.literal(\"schematic_arc\"),schematic_arc_id:K1(\"schematic_arc\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,radius:Y1,start_angle_degrees:G1,end_angle_degrees:G1,direction:k_.enum([\"clockwise\",\"counterclockwise\"]).default(\"counterclockwise\"),stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled arc on the schematic\"),O5=k_.object({type:k_.literal(\"schematic_trace\"),schematic_trace_id:k_.string(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),k5=k_.enum([\"center\",\"left\",\"right\",\"top\",\"bottom\"]),L5=k_.object({type:k_.literal(\"schematic_text\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:Y1,y:Y1}),rotation:k_.number().default(0),anchor:k_.union([k5.describe(\"legacy\"),Q1]).default(\"center\"),color:k_.string().default(\"#000000\"),subcircuit_id:k_.string().optional()}),D5=k_.object({type:k_.literal(\"schematic_port\"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_component_id:k_.string().optional(),center:Z1,facing_direction:k_.enum([\"up\",\"down\",\"left\",\"right\"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe(\"Defines a port on a schematic component\"),z5=k_.object({type:k_.literal(\"schematic_net_label\"),schematic_net_label_id:K1(\"schematic_net_label\"),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:Z1,anchor_position:Z1.optional(),anchor_side:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),F5=f2.extend({type:k_.literal(\"schematic_error\"),schematic_error_id:k_.string(),error_type:k_.literal(\"schematic_port_not_found\").default(\"schematic_port_not_found\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic error on the schematic\"),B5=f2.extend({type:k_.literal(\"schematic_layout_error\"),schematic_layout_error_id:K1(\"schematic_layout_error\"),error_type:k_.literal(\"schematic_layout_error\").default(\"schematic_layout_error\"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when schematic layout fails for a group\"),j5=k_.object({type:k_.literal(\"schematic_debug_object\"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),$5=j5.extend({shape:k_.literal(\"rect\"),center:Z1,size:J1}),Y5=j5.extend({shape:k_.literal(\"line\"),start:Z1,end:Z1}),X5=j5.extend({shape:k_.literal(\"point\"),center:Z1}),V5=k_.discriminatedUnion(\"shape\",[$5,Y5,X5]),W5=k_.object({type:k_.literal(\"schematic_voltage_probe\"),schematic_voltage_probe_id:k_.string(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:Z1,schematic_trace_id:k_.string(),voltage:B1.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:Q1.optional()}).describe(\"Defines a voltage probe measurement point on a schematic trace\"),H5=k_.object({type:k_.literal(\"schematic_manual_edit_conflict_warning\"),schematic_manual_edit_conflict_warning_id:K1(\"schematic_manual_edit_conflict_warning\"),warning_type:k_.literal(\"schematic_manual_edit_conflict_warning\").default(\"schematic_manual_edit_conflict_warning\"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit schX/schY coordinates\"),G5=k_.object({type:k_.literal(\"schematic_group\"),schematic_group_id:K1(\"schematic_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:j1,height:j1,center:Z1,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe(\"Defines a group of components on the schematic\"),U5=k_.object({type:k_.literal(\"schematic_table\"),schematic_table_id:K1(\"schematic_table\"),anchor_position:Z1,column_widths:k_.array(Y1),row_heights:k_.array(Y1),cell_padding:Y1.optional(),border_width:Y1.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:Q1.optional()}).describe(\"Defines a table on the schematic\"),Z5=k_.object({type:k_.literal(\"schematic_table_cell\"),schematic_table_cell_id:K1(\"schematic_table_cell\"),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:Z1,width:Y1,height:Y1,horizontal_align:k_.enum([\"left\",\"center\",\"right\"]).optional(),vertical_align:k_.enum([\"top\",\"middle\",\"bottom\"]).optional(),font_size:Y1.optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a cell within a schematic_table\"),q5=k_.object({type:k_.literal(\"schematic_sheet\"),schematic_sheet_id:K1(\"schematic_sheet\"),name:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic sheet or page that components can be placed on\"),J5=k_.object({x:Y1,y:Y1,bulge:k_.number().optional()}),K5=k_.object({vertices:k_.array(J5)}),Q5=k_.object({outer_ring:K5,inner_rings:k_.array(K5).default([])}),t3=k_.object({x:Y1,y:Y1,via:k_.boolean().optional(),via_to_layer:u5.optional()}),e3=(k_.array(t3),k_.object({x:Y1,y:Y1,via:k_.boolean().optional(),to_layer:u5.optional(),trace_width:Y1.optional()})),n3=k_.object({min_trace_width:j1.optional(),min_board_edge_clearance:j1.optional(),min_via_hole_edge_to_via_hole_edge_clearance:j1.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:j1.optional(),min_trace_to_pad_edge_clearance:j1.optional(),min_pad_edge_to_pad_edge_clearance:j1.optional(),min_same_net_trace_edge_to_trace_edge_clearance:j1.optional(),min_different_net_trace_edge_to_trace_edge_clearance:j1.optional(),min_via_hole_diameter:j1.optional(),min_via_pad_diameter:j1.optional()}),o3=k_.object({type:k_.literal(\"pcb_component\"),pcb_component_id:K1(\"pcb_component\"),source_component_id:k_.string(),center:Z1,layer:u5,rotation:G1,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this part, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this part, usually corresponding with how the user specified it\"),width:j1,height:j1,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"relative_to_another_component\",\"none\"]).optional(),anchor_position:Z1.optional(),anchor_alignment:Q1.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:Z1.optional(),insertion_direction:k_.enum([\"from_above\",\"from_left\",\"from_right\",\"from_front\",\"from_back\"]).optional(),metadata:k_.object({kicad_footprint:l2.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe(\"Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath\")}).describe(\"Defines a component on the PCB\"),i3=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),hole_diameter:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),r3=(i3.describe(\"Defines a circular hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),s3=(r3.describe(\"Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"square\"]),hole_diameter:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),a3=(s3.describe(\"Defines a circular or square hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"oval\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),c3=(a3.describe(\"Defines an oval hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),l3=(c3.describe(\"Defines a pill-shaped hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,ccw_rotation:G1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),d3=(l3.describe(\"Defines a rotated pill-shaped hole on the PCB\"),s3.or(a3).or(c3).or(l3).or(i3).or(r3)),h3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),u3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.enum([\"oval\",\"pill\"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,ccw_rotation:G1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),p3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circular_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),pad_shape:k_.literal(\"rect\"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:G1.optional()}),m3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),g3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"rotated_pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:G1,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:G1,hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),f3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"hole_with_polygon_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"oval\",\"pill\",\"rotated_pill\"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:Y1,y:Y1})).min(3),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),ccw_rotation:G1.optional()}),y3=k_.union([h3,u3,p3,m3,g3,f3]),_3=k_.object({type:k_.literal(\"pcb_port\"),pcb_port_id:K1(\"pcb_port\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:Y1,y:Y1,layers:k_.array(u5),is_board_pinout:k_.boolean().optional()}).describe(\"Defines a port on the PCB\"),b3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"circle\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,radius:k_.number(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),x3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rect\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),v3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_rect\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:G1,layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),S3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"pill\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),I3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_pill\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:G1,layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),C3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"polygon\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(Z1),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),P3=k_.discriminatedUnion(\"shape\",[b3,x3,v3,I3,S3,C3]).describe(\"Defines an SMT pad on the PCB\"),M3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"circle\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,radius:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),N3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rect\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),w3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"pill\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),T3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rotated_rect\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),ccw_rotation:Y1,layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),R3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"oval\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),E3=k_.union([M3,N3,w3,T3,R3]).describe(\"Defines solderpaste on the PCB\"),A3=k_.object({type:k_.literal(\"pcb_text\"),pcb_text_id:K1(\"pcb_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:Z1,layer:u5,width:j1,height:j1,lines:k_.number(),align:k_.enum([\"bottom-left\"])}).describe(\"Defines text on the PCB\"),O3=k_.object({route_type:k_.literal(\"wire\"),x:Y1,y:Y1,width:Y1,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:u5}),k3=k_.object({route_type:k_.literal(\"via\"),x:Y1,y:Y1,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:Y1.optional(),outer_diameter:Y1.optional(),from_layer:u5,to_layer:u5}),L3=k_.union([O3,k3]),D3=k_.object({type:k_.literal(\"pcb_trace\"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:K1(\"pcb_trace\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum([\"constant\",\"interpolated\"]).default(\"constant\").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(L3)}).describe(\"Defines a trace on the PCB\"),z3=k_.object({type:k_.literal(\"pcb_trace_warning\"),pcb_trace_warning_id:K1(\"pcb_trace_warning\"),warning_type:k_.literal(\"pcb_trace_warning\").default(\"pcb_trace_warning\"),message:k_.string(),center:Z1.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace warning on the PCB\"),F3=f2.extend({type:k_.literal(\"pcb_trace_error\"),pcb_trace_error_id:K1(\"pcb_trace_error\"),error_type:k_.literal(\"pcb_trace_error\").default(\"pcb_trace_error\"),center:Z1.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB\"),B3=f2.extend({type:k_.literal(\"pcb_trace_missing_error\"),pcb_trace_missing_error_id:K1(\"pcb_trace_missing_error\"),error_type:k_.literal(\"pcb_trace_missing_error\").default(\"pcb_trace_missing_error\"),center:Z1.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a source trace has no corresponding PCB trace\"),j3=f2.extend({type:k_.literal(\"pcb_port_not_matched_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_port_not_matched_error\").default(\"pcb_port_not_matched_error\"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB where a port is not matched\"),$3=f2.extend({type:k_.literal(\"pcb_port_not_connected_error\"),pcb_port_not_connected_error_id:K1(\"pcb_port_not_connected_error\"),error_type:k_.literal(\"pcb_port_not_connected_error\").default(\"pcb_port_not_connected_error\"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a pcb port is not connected to any trace\"),Y3=k_.object({type:k_.literal(\"pcb_net\"),pcb_net_id:K1(\"pcb_net\"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe(\"Defines a net on the PCB\"),X3=k_.object({type:k_.literal(\"pcb_via\"),pcb_via_id:K1(\"pcb_via\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:Y1,y:Y1,outer_diameter:Y1.default(\"0.6mm\"),hole_diameter:Y1.default(\"0.25mm\"),from_layer:u5.optional(),to_layer:u5.optional(),layers:k_.array(u5),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe(\"Defines a via on the PCB\"),V3=k_.object({type:k_.literal(\"pcb_board\"),pcb_board_id:K1(\"pcb_board\"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:j1.optional(),height:j1.optional(),center:Z1,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this board, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this board, usually corresponding with how the user specified it\"),thickness:j1.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(Z1).optional(),shape:k_.enum([\"rect\",\"polygon\"]).optional(),material:k_.enum([\"fr4\",\"fr1\"]).default(\"fr4\"),anchor_position:Z1.optional(),anchor_alignment:Q1.optional(),position_mode:k_.enum([\"relative_to_panel_anchor\",\"none\"]).optional()}).merge(n3).describe(\"Defines the board outline of the PCB\"),W3=k_.object({type:k_.literal(\"pcb_panel\"),pcb_panel_id:K1(\"pcb_panel\"),width:j1,height:j1,center:Z1,thickness:j1.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe(\"Defines a PCB panel that can contain multiple boards\"),H3=f2.extend({type:k_.literal(\"pcb_placement_error\"),pcb_placement_error_id:K1(\"pcb_placement_error\"),error_type:k_.literal(\"pcb_placement_error\").default(\"pcb_placement_error\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a placement error on the PCB\"),G3=f2.extend({type:k_.literal(\"pcb_panelization_placement_error\"),pcb_panelization_placement_error_id:K1(\"pcb_panelization_placement_error\"),error_type:k_.literal(\"pcb_panelization_placement_error\").default(\"pcb_panelization_placement_error\"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a panelization placement error on the PCB\"),U3=k_.object({type:k_.literal(\"pcb_trace_hint\"),pcb_trace_hint_id:K1(\"pcb_trace_hint\"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(e3),subcircuit_id:k_.string().optional()}).describe(\"A hint that can be used during generation of a PCB trace\"),Z3=k_.object({type:k_.literal(\"pcb_silkscreen_line\"),pcb_silkscreen_line_id:K1(\"pcb_silkscreen_line\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:Y1.default(\"0.1mm\"),x1:Y1,y1:Y1,x2:Y1,y2:Y1,layer:p5}).describe(\"Defines a silkscreen line on the PCB\"),q3=k_.object({type:k_.literal(\"pcb_silkscreen_path\"),pcb_silkscreen_path_id:K1(\"pcb_silkscreen_path\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,route:k_.array(Z1),stroke_width:j1}).describe(\"Defines a silkscreen path on the PCB\"),J3=k_.object({type:k_.literal(\"pcb_silkscreen_text\"),pcb_silkscreen_text_id:K1(\"pcb_silkscreen_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:j1,top:j1,bottom:j1,right:j1}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:u5,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:Q1.default(\"center\")}).describe(\"Defines silkscreen text on the PCB\"),K3=k_.object({type:k_.literal(\"pcb_copper_text\"),pcb_copper_text_id:K1(\"pcb_copper_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:j1,top:j1,bottom:j1,right:j1}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:u5,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:Q1.default(\"center\")}).describe(\"Defines copper text on the PCB\"),Q3=k_.object({type:k_.literal(\"pcb_silkscreen_rect\"),pcb_silkscreen_rect_id:K1(\"pcb_silkscreen_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:u5,stroke_width:j1.default(\"1mm\"),corner_radius:j1.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen rect on the PCB\"),t4=k_.object({type:k_.literal(\"pcb_silkscreen_circle\"),pcb_silkscreen_circle_id:K1(\"pcb_silkscreen_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:j1,layer:p5,stroke_width:j1.default(\"1mm\"),is_filled:k_.boolean().optional()}).describe(\"Defines a silkscreen circle on the PCB\"),e4=k_.object({type:k_.literal(\"pcb_silkscreen_oval\"),pcb_silkscreen_oval_id:K1(\"pcb_silkscreen_oval\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius_x:Y1,radius_y:Y1,layer:p5,ccw_rotation:G1.optional()}).describe(\"Defines a silkscreen oval on the PCB\"),n4=k_.object({type:k_.literal(\"pcb_silkscreen_pill\"),pcb_silkscreen_pill_id:K1(\"pcb_silkscreen_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:u5,ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen pill on the PCB\"),o4=k_.object({type:k_.literal(\"pcb_fabrication_note_text\"),pcb_fabrication_note_text_id:K1(\"pcb_fabrication_note_text\"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"1mm\"),pcb_component_id:k_.string(),text:k_.string(),layer:p5,anchor_position:Z1.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),color:k_.string().optional()}).describe(\"Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators\"),i4=k_.object({type:k_.literal(\"pcb_fabrication_note_path\"),pcb_fabrication_note_path_id:K1(\"pcb_fabrication_note_path\"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:u5,route:k_.array(Z1),stroke_width:j1,color:k_.string().optional()}).describe(\"Defines a fabrication path on the PCB for fabricators or assemblers\"),r4=k_.object({type:k_.literal(\"pcb_fabrication_note_rect\"),pcb_fabrication_note_rect_id:K1(\"pcb_fabrication_note_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5,stroke_width:j1.default(\"0.1mm\"),corner_radius:j1.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a fabrication note rectangle on the PCB\"),s4=k_.object({type:k_.literal(\"pcb_fabrication_note_dimension\"),pcb_fabrication_note_dimension_id:K1(\"pcb_fabrication_note_dimension\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,from:Z1,to:Z1,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:j1.optional(),offset_distance:j1.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:j1.default(\"1mm\"),color:k_.string().optional(),arrow_size:j1.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB fabrication notes\"),a4=k_.object({type:k_.literal(\"pcb_note_text\"),pcb_note_text_id:K1(\"pcb_note_text\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"1mm\"),text:k_.string().optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),layer:p5.default(\"top\"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a documentation note in text on the PCB\"),c4=k_.object({type:k_.literal(\"pcb_note_rect\"),pcb_note_rect_id:K1(\"pcb_note_rect\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5.default(\"top\"),stroke_width:j1.default(\"0.1mm\"),corner_radius:j1.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a rectangular documentation note on the PCB\"),l4=k_.object({type:k_.literal(\"pcb_note_path\"),pcb_note_path_id:K1(\"pcb_note_path\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(Z1),layer:p5.default(\"top\"),stroke_width:j1.default(\"0.1mm\"),color:k_.string().optional()}).describe(\"Defines a polyline documentation note on the PCB\"),d4=k_.object({type:k_.literal(\"pcb_note_line\"),pcb_note_line_id:K1(\"pcb_note_line\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:Y1,y1:Y1,x2:Y1,y2:Y1,layer:p5.default(\"top\"),stroke_width:Y1.default(\"0.1mm\"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe(\"Defines a straight documentation note line on the PCB\"),h4=k_.object({type:k_.literal(\"pcb_note_dimension\"),pcb_note_dimension_id:K1(\"pcb_note_dimension\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:Z1,to:Z1,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:j1.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:j1.default(\"1mm\"),layer:p5.default(\"top\"),color:k_.string().optional(),arrow_size:j1.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB documentation notes\"),u4=f2.extend({type:k_.literal(\"pcb_footprint_overlap_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_footprint_overlap_error\").default(\"pcb_footprint_overlap_error\"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when a pcb footprint overlaps with another element\"),p4=f2.extend({type:k_.literal(\"pcb_courtyard_overlap_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_courtyard_overlap_error\").default(\"pcb_courtyard_overlap_error\"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe(\"Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another\"),m4=k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"rect\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:Y1,height:Y1,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:Y1,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),g4=k_.object({type:k_.literal(\"pcb_cutout\"),pcb_cutout_id:K1(\"pcb_cutout\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),f4=g4.extend({shape:k_.literal(\"rect\"),center:Z1,width:j1,height:j1,rotation:G1.optional(),corner_radius:j1.optional()}),y4=g4.extend({shape:k_.literal(\"circle\"),center:Z1,radius:j1}),_4=g4.extend({shape:k_.literal(\"polygon\"),points:k_.array(Z1)}),b4=g4.extend({shape:k_.literal(\"path\"),route:k_.array(Z1),slot_width:j1,slot_length:j1.optional(),space_between_slots:j1.optional(),slot_corner_radius:j1.optional()}),x4=k_.discriminatedUnion(\"shape\",[f4,y4,_4,b4]).describe(\"Defines a cutout on the PCB, removing board material.\"),v4=f2.extend({type:k_.literal(\"pcb_missing_footprint_error\"),pcb_missing_footprint_error_id:K1(\"pcb_missing_footprint_error\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"pcb_missing_footprint_error\").default(\"pcb_missing_footprint_error\"),source_component_id:k_.string()}).describe(\"Defines a missing footprint error on the PCB\"),S4=f2.extend({type:k_.literal(\"external_footprint_load_error\"),external_footprint_load_error_id:K1(\"external_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal(\"external_footprint_load_error\").default(\"external_footprint_load_error\")}).describe(\"Defines an error when an external footprint fails to load\"),I4=f2.extend({type:k_.literal(\"circuit_json_footprint_load_error\"),circuit_json_footprint_load_error_id:K1(\"circuit_json_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"circuit_json_footprint_load_error\").default(\"circuit_json_footprint_load_error\"),circuit_json:k_.array(k_.any()).optional()}).describe(\"Defines an error when a circuit JSON footprint fails to load\"),C4=k_.object({type:k_.literal(\"pcb_group\"),pcb_group_id:K1(\"pcb_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:j1.optional(),height:j1.optional(),center:Z1,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this group, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this group, usually corresponding with how the user specified it\"),outline:k_.array(Z1).optional(),anchor_position:Z1.optional(),anchor_alignment:Q1.default(\"center\"),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"none\"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum([\"packed\",\"none\"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:j1}).optional(),autorouter_used_string:k_.string().optional()}).describe(\"Defines a group of components on the PCB\"),P4=f2.extend({type:k_.literal(\"pcb_autorouting_error\"),pcb_error_id:K1(\"pcb_autorouting_error\"),error_type:k_.literal(\"pcb_autorouting_error\").default(\"pcb_autorouting_error\"),subcircuit_id:k_.string().optional()}).describe(\"The autorouting has failed to route a portion of the board\"),M4=k_.object({type:k_.literal(\"pcb_manual_edit_conflict_warning\"),pcb_manual_edit_conflict_warning_id:K1(\"pcb_manual_edit_conflict_warning\"),warning_type:k_.literal(\"pcb_manual_edit_conflict_warning\").default(\"pcb_manual_edit_conflict_warning\"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates\"),N4=k_.enum([\"x-\",\"x+\",\"y+\",\"y-\"]),w4=k_.object({type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\"),pcb_connector_not_in_accessible_orientation_warning_id:K1(\"pcb_connector_not_in_accessible_orientation_warning\"),warning_type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\").default(\"pcb_connector_not_in_accessible_orientation_warning\"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:N4,recommended_facing_direction:N4,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction\"),T4=k_.object({type:k_.literal(\"supplier_footprint_mismatch_warning\"),supplier_footprint_mismatch_warning_id:K1(\"supplier_footprint_mismatch_warning\"),warning_type:k_.literal(\"supplier_footprint_mismatch_warning\").default(\"supplier_footprint_mismatch_warning\"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:y2.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe(\"Warning emitted when a supplier part footprint does not match the expected footprint\"),R4=k_.object({type:k_.literal(\"pcb_breakout_point\"),pcb_breakout_point_id:K1(\"pcb_breakout_point\"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:Y1,y:Y1}).describe(\"Defines a routing target within a pcb_group for a source_trace or source_net\"),E4=k_.object({type:k_.literal(\"pcb_ground_plane\"),pcb_ground_plane_id:K1(\"pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane on the PCB\"),A4=k_.object({type:k_.literal(\"pcb_ground_plane_region\"),pcb_ground_plane_region_id:K1(\"pcb_ground_plane_region\"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:u5,points:k_.array(Z1)}).describe(\"Defines a polygon region of a ground plane\"),O4=k_.object({type:k_.literal(\"pcb_thermal_spoke\"),pcb_thermal_spoke_id:K1(\"pcb_thermal_spoke\"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:Y1,spoke_inner_diameter:Y1,spoke_outer_diameter:Y1,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Pattern for connecting a ground plane to a plated hole\"),k4=k_.object({type:k_.literal(\"pcb_copper_pour\"),pcb_copper_pour_id:K1(\"pcb_copper_pour\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:u5,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),L4=k4.extend({shape:k_.literal(\"rect\"),center:Z1,width:j1,height:j1,rotation:G1.optional()}),D4=k4.extend({shape:k_.literal(\"brep\"),brep_shape:Q5}),z4=k4.extend({shape:k_.literal(\"polygon\"),points:k_.array(Z1)}),F4=k_.discriminatedUnion(\"shape\",[L4,D4,z4]).describe(\"Defines a copper pour on the PCB.\"),B4=f2.extend({type:k_.literal(\"pcb_component_outside_board_error\"),pcb_component_outside_board_error_id:K1(\"pcb_component_outside_board_error\"),error_type:k_.literal(\"pcb_component_outside_board_error\").default(\"pcb_component_outside_board_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Z1,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a PCB component is placed outside the board boundaries\"),j4=f2.extend({type:k_.literal(\"pcb_component_not_on_board_edge_error\"),pcb_component_not_on_board_edge_error_id:K1(\"pcb_component_not_on_board_edge_error\"),error_type:k_.literal(\"pcb_component_not_on_board_edge_error\").default(\"pcb_component_not_on_board_edge_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Z1,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component that must be placed on the board edge is centered away from the edge\"),$4=f2.extend({type:k_.literal(\"pcb_component_invalid_layer_error\"),pcb_component_invalid_layer_error_id:K1(\"pcb_component_invalid_layer_error\"),error_type:k_.literal(\"pcb_component_invalid_layer_error\").default(\"pcb_component_invalid_layer_error\"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:u5,subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)\"),Y4=f2.extend({type:k_.literal(\"pcb_via_clearance_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_via_clearance_error\").default(\"pcb_via_clearance_error\"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when vias are closer than the allowed clearance\"),X4=f2.extend({type:k_.literal(\"pcb_via_trace_clearance_error\"),pcb_via_trace_clearance_error_id:K1(\"pcb_via_trace_clearance_error\"),error_type:k_.literal(\"pcb_via_trace_clearance_error\").default(\"pcb_via_trace_clearance_error\"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a via and trace are closer than the allowed clearance\"),V4=f2.extend({type:k_.literal(\"pcb_pad_pad_clearance_error\"),pcb_pad_pad_clearance_error_id:K1(\"pcb_pad_pad_clearance_error\"),error_type:k_.literal(\"pcb_pad_pad_clearance_error\").default(\"pcb_pad_pad_clearance_error\"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when pads are closer than the allowed clearance\"),W4=f2.extend({type:k_.literal(\"pcb_pad_trace_clearance_error\"),pcb_pad_trace_clearance_error_id:K1(\"pcb_pad_trace_clearance_error\"),error_type:k_.literal(\"pcb_pad_trace_clearance_error\").default(\"pcb_pad_trace_clearance_error\"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pad and trace are closer than allowed clearance\"),H4=k_.object({type:k_.literal(\"pcb_courtyard_rect\"),pcb_courtyard_rect_id:K1(\"pcb_courtyard_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5,ccw_rotation:G1.optional(),color:k_.string().optional()}).describe(\"Defines a courtyard rectangle on the PCB\"),G4=k_.object({type:k_.literal(\"pcb_courtyard_outline\"),pcb_courtyard_outline_id:K1(\"pcb_courtyard_outline\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,outline:k_.array(Z1).min(2)}).describe(\"Defines a courtyard outline on the PCB\"),U4=k_.object({type:k_.literal(\"pcb_courtyard_polygon\"),pcb_courtyard_polygon_id:K1(\"pcb_courtyard_polygon\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,points:k_.array(Z1).min(3),color:k_.string().optional()}).describe(\"Defines a courtyard polygon on the PCB\"),Z4=k_.object({type:k_.literal(\"pcb_courtyard_circle\"),pcb_courtyard_circle_id:K1(\"pcb_courtyard_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:j1,layer:p5,color:k_.string().optional()}).describe(\"Defines a courtyard circle on the PCB\"),q4=k_.object({type:k_.literal(\"cad_component\"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:q1,rotation:q1.optional(),size:q1.optional(),layer:u5.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:t2.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum([\"x+\",\"x-\",\"y+\",\"y-\",\"z+\",\"z-\"]).optional().describe('The direction in the model\\'s coordinate space that is considered \"up\" or \"coming out of the board surface\"'),model_origin_position:q1.optional(),model_origin_alignment:k_.enum([\"unknown\",\"center\",\"center_of_component_on_board_surface\",\"bottom_center_of_component\"]).optional(),model_object_fit:k_.enum([\"contain_within_bounds\",\"fill_bounds\"]).optional().default(\"contain_within_bounds\"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),anchor_alignment:k_.enum([\"center\",\"center_of_component_on_board_surface\"]).optional().default(\"center\")}).describe(\"Defines a component on the PCB\"),J4=k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]),K4=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),Q4=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:K1(\"simulation_voltage_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:B1}).describe(\"Defines a DC voltage source for simulation\"),t6=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:K1(\"simulation_voltage_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:B1.optional(),frequency:$1.optional(),peak_to_peak_voltage:B1.optional(),wave_shape:J4.optional(),phase:G1.optional(),duty_cycle:K4.optional()}).describe(\"Defines an AC voltage source for simulation\"),e6=k_.union([Q4,t6]).describe(\"Defines a voltage source for simulation\"),n6=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),o6=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:K1(\"simulation_current_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:X1}).describe(\"Defines a DC current source for simulation\"),i6=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:K1(\"simulation_current_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:X1.optional(),frequency:$1.optional(),peak_to_peak_current:X1.optional(),wave_shape:J4.optional(),phase:G1.optional(),duty_cycle:n6.optional()}).describe(\"Defines an AC current source for simulation\"),r6=k_.union([o6,i6]).describe(\"Defines a current source for simulation\"),s6=k_.union([k_.literal(\"spice_dc_sweep\"),k_.literal(\"spice_dc_operating_point\"),k_.literal(\"spice_transient_analysis\"),k_.literal(\"spice_ac_analysis\")]),a6=k_.object({type:k_.literal(\"simulation_experiment\"),simulation_experiment_id:K1(\"simulation_experiment\"),name:k_.string(),experiment_type:s6,time_per_step:V1.optional(),start_time_ms:W1.optional(),end_time_ms:W1.optional()}).describe(\"Defines a simulation experiment configuration\"),c6=k_.object({type:k_.literal(\"simulation_transient_voltage_graph\"),simulation_transient_voltage_graph_id:K1(\"simulation_transient_voltage_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:V1,start_time_ms:W1,end_time_ms:W1,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores voltage measurements over time for a simulation\"),l6=k_.object({type:k_.literal(\"simulation_switch\"),simulation_switch_id:K1(\"simulation_switch\"),source_component_id:k_.string().optional(),closes_at:W1.optional(),opens_at:W1.optional(),starts_closed:k_.boolean().optional(),switching_frequency:$1.optional()}).describe(\"Defines a switch for simulation timing control\"),d6=k_.object({type:k_.literal(\"simulation_voltage_probe\"),simulation_voltage_probe_id:K1(\"simulation_voltage_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.\").superRefine((t,e)=\u003e{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n\u0026\u0026o?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a differential probe.\"}):n?t.signal_input_source_port_id\u0026\u0026t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id.\"}):o\u0026\u0026(t.signal_input_source_net_id\u0026\u0026t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id.\"}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id.\"})}),h6=f2.extend({type:k_.literal(\"simulation_unknown_experiment_error\"),simulation_unknown_experiment_error_id:K1(\"simulation_unknown_experiment_error\"),error_type:k_.literal(\"simulation_unknown_experiment_error\").default(\"simulation_unknown_experiment_error\"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"An unknown error occurred during the simulation experiment.\"),u6=k_.object({type:k_.literal(\"simulation_op_amp\"),simulation_op_amp_id:K1(\"simulation_op_amp\"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe(\"Defines a simple ideal operational amplifier for simulation\"),p6=(k_.union([r5,o5,i5,n5,a5,s5,P2,b2,v2,I2,x2,M2,R2,E2,L2,z2,F2,X2,B2,j2,$2,Y2,O2,A2,d5,m5,c5,V2,G2,U2,q2,J2,g5,f5,y5,_5,b5,t5,l5,o3,d3,v4,S4,I4,M4,w4,T4,y3,m4,_3,Y3,A3,D3,z3,X3,P3,E3,V3,W3,C4,U3,Z3,q3,J3,n4,K3,Q3,t4,e4,F3,B3,H3,G3,j3,$3,Y4,X4,V4,W4,i4,o4,r4,s4,a4,c4,l4,d4,h4,P4,u4,p4,R4,x4,E4,A4,O4,F4,B4,j4,$4,H4,G4,U4,Z4,x5,L5,T5,R5,E5,A5,M5,w5,D5,O5,v5,F5,B5,z5,V5,W5,H5,G5,q5,U5,Z5,q4,e6,r6,a6,c6,l6,d6,h6,u6]),[0,1,-1,2,-2,3,-3,4]),m6=(p6.flatMap(t=\u003ep6.map(e=\u003e[t,e])).sort(([t,e],[n,o])=\u003eMath.abs(t)+Math.abs(e)-Math.abs(n)-Math.abs(o)).length,[.2,.4,.8,1.2].flatMap(t=\u003e[.2,.3,.45,.6].flatMap(e=\u003e[-1,1].map(n=\u003e({halfSpan:t,offset:e,directionSign:n})))).flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,...t}))));[1,-1].flatMap(t=\u003e[1,-1].flatMap(e=\u003e[!1,!0].flatMap(n=\u003e[0,1].map(o=\u003e({routeSide:o,normalDirectionSign:t,tangentDirectionSign:e,reverseEndpointOffsets:n}))))),[0,1].map(t=\u003e({kind:\"displacementChain\",routeSide:t})),[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,halfSpan:.4,offset:1.2,directionSign:t}))),[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"span\",routeSide:e,spanExpansion:3,offset:1.8,directionSign:t}))),[{dx:-2.4,dy:-.4},{dx:-2.4,dy:.4},{dx:2.4,dy:-.4},{dx:2.4,dy:.4},{dx:-.4,dy:-2.4},{dx:-.4,dy:2.4},{dx:.4,dy:-2.4},{dx:.4,dy:2.4}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:2,...t}))),[{dx:-.17,dy:0},{dx:.17,dy:0},{dx:0,dy:-.17},{dx:0,dy:.17}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:0,...t})));var g6=1e-8,f6=(t,e,n=0)=\u003et.x\u003e=e.minX+n-g6\u0026\u0026t.x\u003c=e.maxX-n+g6\u0026\u0026t.y\u003e=e.minY+n-g6\u0026\u0026t.y\u003c=e.maxY-n+g6,y6=(t,e,n)=\u003e{let o=0,i=1;for(const[r,s,a,c]of[[t.x,e.x-t.x,n.minX,n.maxX],[t.y,e.y-t.y,n.minY,n.maxY]]){if(void 0===r||void 0===s||void 0===a||void 0===c)throw new Error(\"Invalid segment clipping axis\");if(Math.abs(s)\u003c=g6){if(r\u003ca-g6||r\u003ec+g6)return;continue}const t=(a-r)/s,e=(c-r)/s;if(o=Math.max(o,Math.min(t,e)),i=Math.min(i,Math.max(t,e)),i\u003co-g6)return}return[Math.max(0,o),Math.min(1,i)]},_6=(t,e,n)=\u003e{if(n\u003c=g6)return structuredClone(t);if(n\u003e=.99999999)return structuredClone(e);const o={...structuredClone(t),x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n};return delete o.pcb_port_id,o},b6=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=g6\u0026\u0026Math.abs(t.y-e.y)\u003c=g6\u0026\u0026t.z===e.z,x6=t=\u003eArray.isArray(t)?`[${t.map(x6).join(\",\")}]`:null!==t\u0026\u0026\"object\"==typeof t?`{${Object.keys(t).filter(e=\u003evoid 0!==t[e]).sort().map(e=\u003e`${JSON.stringify(e)}:${x6(t[e])}`).join(\",\")}}`:JSON.stringify(t)??\"undefined\",v6=(t,e,n)=\u003e{if(1===t.route.length)return structuredClone(t.route);const o=e=\u003e{const n=Math.min(Math.floor(e),t.route.length-2);return _6(t.route[n],t.route[n+1],e-n)},i=[o(e)];for(let o=Math.floor(e)+1;o\u003cn-g6;o+=1)i.push(structuredClone(t.route[o]));return n\u003ee+g6\u0026\u0026i.push(o(n)),i},S6=(t,e,n)=\u003e{const o=v6(t,e,n),i=Object.fromEntries(Object.entries(t).filter(([t])=\u003e\"route\"!==t\u0026\u0026\"vias\"!==t)),r=t.vias.filter(t=\u003eo.some(e=\u003eMath.hypot(e.x-t.x,e.y-t.y)\u003c=g6));return x6({metadata:i,points:o,vias:r})},I6=(t,e)=\u003e{const n=t.__zLayers;if(n)return new Set(n);if(t.zLayers)return new Set(t.zLayers);const o=new Set;for(const n of t.layers){const t=\"top\"===n?0:\"bottom\"===n?e-1:/^inner\\d+$/.test(n)?Number(n.slice(5)):-1;if(t\u003c0||t\u003e=e)throw new Error(`repair04 obstacle has an unknown layer: ${n}`);o.add(t)}return o},C6=({srj:t,routes:e,traceClearance:n=.1,viaClearance:o=.1})=\u003e{let i;const r=new Map,s=[];let a=!1;return c=\u003e{const l=i??=((t,e)=\u003e{const n=new Map,o=t=\u003e{const e=n.get(t);if(void 0===e)return n.set(t,t),t;if(e===t)return t;const i=o(e);return n.set(t,i),i},i=t=\u003e{const e=t.filter(t=\u003e\"string\"==typeof t\u0026\u0026t.length\u003e0);if(0===e.length)return;const i=o(e[0]);for(const t of e)n.set(o(t),i)};for(const e of t.connections){const t=e;i([t.name,t.rootConnectionName,t.netConnectionName,t.__netConnectionName,...t.mergedConnectionNames??[],...t.__rootConnectionNames??[],...t.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])])}for(const e of t.obstacles)i(e.connectedTo);for(const t of e)i([t.connectionName,t.rootConnectionName]);for(const t of n.keys())n.set(t,o(t));return n})(t,e),d=new Map,h=a?s:function*(e){for(let i=0;i\u003ct.obstacles.length;i++){if(r.has(i)){const t=r.get(i);t\u0026\u0026(yield t);continue}const a=t.obstacles[i],c=a.connectedTo.some(t=\u003e/^(pcb_smtpad_|pcb_plated_hole_|pcb_port_)/.test(t)),l=Math.abs((a.ccwRotationDegrees??0)%180)\u003e1e-8,d=\"rect\"===a.type\u0026\u0026a.layers.length\u003e1\u0026\u0026Math.abs(a.width-a.height)\u003c.001;if(c\u0026\u0026!l\u0026\u0026!d){r.set(i,null);continue}if(![a.center.x,a.center.y,a.width,a.height,a.ccwRotationDegrees??0].every(Number.isFinite)||a.width\u003c0||a.height\u003c0)throw new Error(\"repair04 fixed obstacle geometry must be finite and nonnegative\");const h=I6(a,t.layerCount),u=new Set(a.connectedTo.map(t=\u003ee.get(t)??t)),p={minX:-a.width/2,maxX:a.width/2,minY:-a.height/2,maxY:a.height/2},m=(a.ccwRotationDegrees??0)*Math.PI/180,g=Math.cos(m),f=Math.sin(m),y=Math.hypot(a.width,a.height)/2,_=t=\u003e{const e=t.x-a.center.x,n=t.y-a.center.y;return{x:e*g+n*f,y:-e*f+n*g}},b=(t,e,n)=\u003eMath.max(t.x,e.x)+n\u003ca.center.x-y||Math.min(t.x,e.x)-n\u003ea.center.x+y||Math.max(t.y,e.y)+n\u003ca.center.y-y||Math.min(t.y,e.y)-n\u003ea.center.y+y,x=!0===a.obstacleId?.startsWith(\"repair04_board_edge_\"),v=x?0:Math.max(n,t.defaultObstacleMargin??0,t.minTraceToPadEdgeClearance??0),S=x?0:Math.max(o,t.defaultObstacleMargin??0,t.minViaEdgeToPadEdgeClearance??0),I={obstacleIndex:i,obstacle:a,zLayers:h,obstacleNets:u,obstacleBounds:p,toLocal:_,separated:b,wireGap:v,viaGap:S};r.set(i,I),s.push(I),yield I}a=!0}(l);for(const{obstacleIndex:t,obstacle:e,zLayers:n,obstacleNets:o,obstacleBounds:i,toLocal:r,separated:s,wireGap:a,viaGap:u}of h)for(let h=0;h\u003cc.length;h+=1){const p=c[h];if(!(p.route.length\u003c2)\u0026\u0026![p.connectionName,p.rootConnectionName].some(t=\u003evoid 0!==t\u0026\u0026o.has(l.get(t)??t)))for(let o=1;o\u003cp.route.length;o+=1){const c=p.route[o-1],l=p.route[o];if(\"through_obstacle\"===c.toNextSegmentType)continue;if(c.z!==l.z){if(!Array.from(n).some(t=\u003et\u003e=Math.min(c.z,l.z)\u0026\u0026t\u003c=Math.max(c.z,l.z)))continue;if(Math.abs(c.x-l.x)\u003e1e-8||Math.abs(c.y-l.y)\u003e1e-8)throw new Error(\"repair04 found a non-colocated via transition: \"+JSON.stringify({route:p,from:c,to:l}));if(s(c,c,p.viaDiameter/2+u+1e-8))continue;const e=r(c),o=ke(e,e,i),a=p.viaDiameter/2+u-o;if(a\u003c=1e-8)continue;const m=`fixed-obstacle:${h}:${t}:via`;(d.get(m)?.severity??-1/0)\u003ca\u0026\u0026d.set(m,{key:m,center:{x:c.x,y:c.y},routeIndex:h,obstacleIndex:t,kind:\"via\",severity:a});continue}if(!n.has(c.z))continue;const m=Math.max(c.traceThickness??p.traceThickness,l.traceThickness??p.traceThickness)/2;if(s(c,l,m+a+1e-8))continue;const g=m+a-ke(r(c),r(l),i);if(g\u003c=1e-8)continue;const f=`fixed-obstacle:${h}:${t}:wire`;(d.get(f)?.severity??-1/0)\u003cg\u0026\u0026d.set(f,{key:f,center:ze(e.center,c,l),routeIndex:h,obstacleIndex:t,kind:\"wire\",severity:g})}}return Array.from(d.values())}},P6=t=\u003eC6(t)(t.routes),M6=(t,e)=\u003e{const n=[];for(let o=1;o\u003ct.route.length;o++){const i=t.route[o-1],r=t.route[o];if(i.z===r.z||\"through_obstacle\"===i.toNextSegmentType)continue;if(i.x!==r.x||i.y!==r.y||![i.x,i.y,i.z,r.z,t.viaDiameter].every(Number.isFinite)||!Number.isInteger(i.z)||!Number.isInteger(r.z)||Math.min(i.z,r.z)\u003c0||Math.max(i.z,r.z)\u003e=e||t.viaDiameter\u003c=0)throw new Error(\"repair04 new-via guard requires valid colocated vias\");const s=o-1,a=[i.z,r.z];let c=Math.min(i.z,r.z),l=Math.max(i.z,r.z);for(;o+1\u003ct.route.length\u0026\u0026\"through_obstacle\"!==t.route[o].toNextSegmentType;){const n=t.route[o+1];if(n.x!==r.x||n.y!==r.y)break;if(!Number.isInteger(n.z)||n.z\u003c0||n.z\u003e=e)throw new Error(\"repair04 new-via guard found an invalid layer span\");n.z!==a.at(-1)\u0026\u0026a.push(n.z),c=Math.min(c,n.z),l=Math.max(l,n.z),o++}n.push({pointIndices:Array.from({length:o-s+1},(t,e)=\u003es+e),layerSequence:a,x:r.x,y:r.y,minZ:c,maxZ:l,diameter:t.viaDiameter,identity:JSON.stringify([r.x,r.y,c,l,t.viaDiameter])})}return n},N6=({srj:t,viaClearance:e=.1})=\u003e{const n=new Map,o=new Map,i=[e,t.defaultObstacleMargin??0,t.minViaEdgeToPadEdgeClearance??0],r=Math.max(...i),s=e=\u003e{const i=o.get(e.identity);if(i)return i;const s=[];for(let o=0;o\u003ct.obstacles.length;o++){const i=t.obstacles[o];let a=n.get(o);if(!a){const e=i.__zLayers??i.zLayers??i.layers.map(e=\u003e\"top\"===e?0:\"bottom\"===e?t.layerCount-1:/^inner\\d+$/.test(e)?Number(e.slice(5)):-1);if(e.some(e=\u003e!Number.isInteger(e)||e\u003c0||e\u003e=t.layerCount))throw new Error(\"repair04 new-via guard found an unknown obstacle layer\");a={zs:e},n.set(o,a)}if(!a.zs.some(t=\u003et\u003e=e.minZ\u0026\u0026t\u003c=e.maxZ))continue;if(!a.geometry){if(![i.center.x,i.center.y,i.width,i.height,i.ccwRotationDegrees??0].every(Number.isFinite)||i.width\u003c0||i.height\u003c0)throw new Error(\"repair04 new-via guard found invalid obstacle geometry\");const t=(i.ccwRotationDegrees??0)*Math.PI/180;a.geometry={x:i.center.x,y:i.center.y,cosine:Math.cos(t),sine:Math.sin(t),extent:Math.hypot(i.width,i.height)/2,bounds:{minX:-i.width/2,maxX:i.width/2,minY:-i.height/2,maxY:i.height/2}}}const c=a.geometry,l=c.extent+e.diameter/2+r+1e-8;if(Math.abs(e.x-c.x)\u003el||Math.abs(e.y-c.y)\u003el)continue;const d=e.x-c.x,h=e.y-c.y,u={x:d*c.cosine+h*c.sine,y:-d*c.sine+h*c.cosine},p=ke(u,u,c.bounds),m=e.diameter/2+r-p;m\u003c=1e-8||s.push({obstacleIndex:o,severity:m})}return o.set(e.identity,s),s};return({previousRoutes:e,routes:n,includeExistingVias:o=[]})=\u003e{if(e.length!==n.length)throw new Error(\"repair04 new-via guard requires matching route ordering\");if(i.some(t=\u003e!Number.isFinite(t)||t\u003c0))throw new Error(\"repair04 new-via guard requires nonnegative finite margins\");const r=[];for(let i=0;i\u003cn.length;i++){const a=n[i],c=e[i],l=new Set(a.connectionName===c.connectionName\u0026\u0026a.rootConnectionName===c.rootConnectionName?M6(c,t.layerCount).map(t=\u003et.identity):[]),d=M6(a,t.layerCount);for(let t=0;t\u003cd.length;t++){const e=d[t];if(!l.has(e.identity)||o.some(e=\u003ee.routeIndex===i\u0026\u0026e.viaIndex===t))for(const n of s(e))r.push({key:`new-via-pad:${i}:${n.obstacleIndex}:${t}`,routeIndex:i,obstacleIndex:n.obstacleIndex,center:{x:e.x,y:e.y},kind:\"via\",severity:n.severity})}}return r}},w6=t=\u003eN6(t)(t);function T6(t,e){return t.x\u003ee.minX+4e-8\u0026\u0026t.x\u003ce.maxX-4e-8\u0026\u0026t.y\u003ee.minY+4e-8\u0026\u0026t.y\u003ce.maxY-4e-8}function R6(t){const e=[];for(let n=1;n\u003ct.route.length;n++){const o=t.route[n-1],i=t.route[n];if(o.z!==i.z\u0026\u0026\"through_obstacle\"!==o.toNextSegmentType){if(o.x!==i.x||o.y!==i.y)throw new Error(\"repair04: a layer transition must have coincident endpoints\");e.some(t=\u003et.x===i.x\u0026\u0026t.y===i.y)||e.push({x:i.x,y:i.y})}}return{...t,vias:e}}function E6(t){const e=[];for(let n=1;n\u003ct.route.length;n++){const o=t.route[n-1],i=t.route[n];o.z!==i.z\u0026\u0026\"through_obstacle\"!==o.toNextSegmentType\u0026\u0026e.push([o.x,o.y,o.z,i.z])}return JSON.stringify([t.viaDiameter,e])}var A6=class extends kt{input;mutableBounds;engine;fixedTraces;routes;score=null;candidates=null;bestAdjustment=null;lockedPoints;evaluated=0;accepted=0;maxCandidates;candidateAttempts=0;pathSearchNodes=0;pathSearchCalls=0;viaBlockerPathSearchCalls=0;coupledPathSearchCalls=0;threeRoutePathSearchCalls=0;threeRoutePathSearchNodes=0;candidateScores=new Map;routeCache=new WeakMap;fixedObstacleNetContext;fixedObstacleEvaluator;viaPadEvaluator;viaGeometryCache=new WeakMap;constructor(t){if(super(),!Number.isFinite(t.boundaryMargin)||t.boundaryMargin\u003c=0)throw new Error(\"repair04: boundaryMargin must be positive and finite\");const e=t.bounds;if(![e.minX,e.maxX,e.minY,e.maxY].every(Number.isFinite)||e.maxX-e.minX\u003c10-1e-8||e.maxY-e.minY\u003c10-1e-8)throw new Error(\"repair04: bounds must be finite and at least 10 × 10 mm\");if(this.input=structuredClone(t),this.viaPadEvaluator=(({srj:t,viaClearance:e})=\u003eN6({srj:{layerCount:t.layerCount,obstacles:structuredClone(t.obstacles),defaultObstacleMargin:t.defaultObstacleMargin,minViaEdgeToPadEdgeClearance:t.minViaEdgeToPadEdgeClearance},viaClearance:e}))({srj:this.input.srj,viaClearance:this.input.viaClearance}),this.routes=structuredClone(t.routes),this.fixedObstacleNetContext=this.input.routes.map(t=\u003e({...t,route:[]})),this.fixedObstacleEvaluator=(t=\u003eC6({...t,srj:structuredClone(t.srj),routes:t.routes.map(t=\u003e({...t,route:[]}))}))({srj:this.input.srj,routes:this.fixedObstacleNetContext,traceClearance:this.input.traceClearance,viaClearance:this.input.viaClearance}),this.fixedTraces=(t.srj.traces??[]).map(e=\u003em1(e,t.srj.minTraceWidth)),this.mutableBounds={minX:e.minX+t.boundaryMargin,minY:e.minY+t.boundaryMargin,maxX:e.maxX-t.boundaryMargin,maxY:e.maxY-t.boundaryMargin},this.mutableBounds.minX\u003e=this.mutableBounds.maxX||this.mutableBounds.minY\u003e=this.mutableBounds.maxY)throw new Error(\"repair04: boundary collar leaves no mutable area\");if(t.lockedPointIndices.length!==t.routes.length)throw new Error(\"repair04: every route requires a lock mask\");this.lockedPoints=this.routes.map((e,n)=\u003e{if(t.lockedPointIndices[n].length!==e.route.length)throw new Error(\"repair04: lock mask length must match its route\");for(let t=1;t\u003ce.route.length;t++){const n=y6(e.route[t-1],e.route[t],this.mutableBounds);if(n?.some(t=\u003et\u003e1e-8\u0026\u0026t\u003c1-1e-8))throw new Error(\"repair04: boundary crossings require fixed cut points; use extractRepairRegion\")}return e.route.filter((o,i)=\u003et.lockedPointIndices[n][i]||0===i||i===e.route.length-1||o.pcb_port_id||o.insideJumperPad||o.toNextSegmentType||!T6(o,this.mutableBounds))});for(const e of t.movableVias??[]){const n=this.routes[e.routeIndex],o=n\u0026\u0026M6(n,t.srj.layerCount)[e.viaIndex];if(!o||o.pointIndices.some(t=\u003ethis.isLocked(e.routeIndex,n.route[t])))throw new Error(\"repair04: movable via must identify an unlocked existing via\")}for(const e of[\"maxCandidateAttempts\",\"maxPathSearchNodes\"]){const n=t[e];if(void 0!==n\u0026\u0026(!Number.isSafeInteger(n)||n\u003c1))throw new Error(`repair04: ${e} must be a positive safe integer`)}if(this.maxCandidates=t.maxCandidates??8e3,!Number.isInteger(this.maxCandidates)||this.maxCandidates\u003c1)throw new Error(\"repair04: maxCandidates must be a positive integer\");this.MAX_ITERATIONS=2*this.maxCandidates+4,this.engine=new R1(this.input.srj,{cacheStaticObstacleNetMembership:!0,cacheImmutableTraceGeometry:!0,useTransientDynamicQueryMarkers:!0,useConservativeRectObstaclePrecheck:!0,traceClearance:t.traceClearance??.1,viaClearance:t.viaClearance??.1,includeTraceViaOwnerMetadata:!0})}getWorkLimitReason(){return void 0!==this.input.maxCandidateAttempts\u0026\u0026this.candidateAttempts\u003e=this.input.maxCandidateAttempts?\"candidate-attempt-limit\":void 0!==this.input.maxPathSearchNodes\u0026\u0026this.pathSearchNodes\u003e=this.input.maxPathSearchNodes?\"path-search-node-limit\":null}updateWorkStats(t){void 0===this.input.maxCandidateAttempts\u0026\u0026void 0===this.input.maxPathSearchNodes||(this.stats={...this.stats,candidateAttempts:this.candidateAttempts,pathSearchNodes:this.pathSearchNodes,pathSearchCalls:this.pathSearchCalls,...void 0===t?{}:{completionReason:t}})}finishSearch(t){this.bestAdjustment\u0026\u0026(this.routes=this.bestAdjustment.routes,this.candidateScores.clear(),this.score=this.bestAdjustment.score,this.accepted++,this.bestAdjustment=null,this.stats={...this.stats,finalErrorCount:this.score.count,accepted:this.accepted}),this.updateWorkStats(t),this.solved=!0}getRouteCache(t,e){let n=this.routeCache.get(e);n||(n=new Map,this.routeCache.set(e,n));let o=n.get(t);return o||(o={},n.set(t,o)),o}getViaGeometry(t){let e=this.viaGeometryCache.get(t);return e||(e=M6(t,this.input.srj.layerCount),this.viaGeometryCache.set(t,e)),e}getViaPadViolations(t,e){return 0===t.length?this.viaPadEvaluator({previousRoutes:[],routes:[]}):t.flatMap((t,n)=\u003e{const o=this.getRouteCache(n,t),i=e?\"scoredViaViolations\":\"newViaViolations\";if(!o[i]){const r=e?!0!==this.input.allowLayerChanges||this.input.movableVias?.length?(this.input.movableVias??[]).filter(t=\u003et.routeIndex===n).map(t=\u003e({routeIndex:0,viaIndex:t.viaIndex})):this.getViaGeometry(t).flatMap((e,o)=\u003ee.pointIndices.every(e=\u003e!this.isLocked(n,t.route[e]))?[{routeIndex:0,viaIndex:o}]:[]):[];o[i]=this.viaPadEvaluator({previousRoutes:[e?t:this.input.routes[n]],routes:[t],includeExistingVias:r}).map(t=\u003e({...t,routeIndex:n,key:t.key.replace(\"new-via-pad:0:\",`new-via-pad:${n}:`)}))}return o[i]})}getFixedViolations(t){if(0===t.length)return this.fixedObstacleEvaluator(t);const e=t.flatMap((t,e)=\u003evoid 0===this.getRouteCache(e,t).fixedViolations?[e]:[]);if(e.length){const n=this.fixedObstacleNetContext.slice();for(const o of e)n[o]=t[o];const o=this.fixedObstacleEvaluator(n);for(const n of e)this.getRouteCache(n,t[n]).fixedViolations=[];for(const e of o)this.getRouteCache(e.routeIndex,t[e.routeIndex]).fixedViolations.push(e)}return t.flatMap((t,e)=\u003ethis.getRouteCache(e,t).fixedViolations).sort((t,e)=\u003et.obstacleIndex-e.obstacleIndex||t.routeIndex-e.routeIndex)}evaluate(t){const{errors:e}=this.engine.evaluate([...this.fixedTraces,...t.map((t,e)=\u003e{const n=this.getRouteCache(e,t);return n.trace||(n.trace=function(t,e){const n=t=\u003e0===t?\"top\":t===e-1?\"bottom\":`inner${t}`;return t.map((t,e)=\u003e{const o=[];for(let e=0;e\u003ct.route.length;e++){const i=t.route[e],r=t.route[e-1];r\u0026\u0026\"through_obstacle\"!==r.toNextSegmentType\u0026\u0026r.z!==i.z\u0026\u0026r.x===i.x\u0026\u0026r.y===i.y\u0026\u0026o.push({route_type:\"via\",x:i.x,y:i.y,from_layer:n(r.z),to_layer:n(i.z),via_diameter:t.viaDiameter});const s=i.traceThickness??t.traceThickness;o.push({route_type:\"wire\",x:i.x,y:i.y,layer:n(i.z),width:s,...0===e\u0026\u0026i.pcb_port_id?{start_pcb_port_id:i.pcb_port_id}:{},...e===t.route.length-1\u0026\u0026i.pcb_port_id?{end_pcb_port_id:i.pcb_port_id}:{}})}return{type:\"pcb_trace\",pcb_trace_id:`repair04_${e}`,connection_name:t.rootConnectionName??t.connectionName,route:o}})}([t],this.input.srj.layerCount)[0],n.trace.pcb_trace_id=`repair04_${e}`),n.trace})]),n=new Map;for(const o of this.getFixedViolations(t))n.set(o.key,o.severity),e.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:`repair04 fixed obstacle clearance: ${o.key}`,center:o.center,minimum_clearance:o.severity,actual_clearance:0,pcb_trace_id:`repair04_${o.routeIndex}`,pcb_trace_error_id:o.key});for(const n of this.getViaPadViolations(t,!0))e.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:`repair04 selected existing via pad clearance: ${n.key}`,center:n.center,minimum_clearance:n.severity,actual_clearance:0,pcb_trace_id:`repair04_${n.routeIndex}`,pcb_trace_error_id:n.key});let o=0;for(const t of e){const e=/gap: (-?[\\d.]+)/.exec(t.message),n=\"number\"==typeof t.actual_clearance?t.actual_clearance:e?Number(e[1]):null,i=\"number\"==typeof t.minimum_clearance?t.minimum_clearance:.1;o+=null!==n?Math.max(0,i-n):1}return{count:e.length,severity:o,errors:e,fixedViolations:n}}isLocked(t,e){return!T6(e,this.mutableBounds)||this.lockedPoints[t].some(t=\u003et.x===e.x\u0026\u0026t.y===e.y)}*generateTaperedSegmentCandidates(t){const e=new Set;for(const{ri:n,pi:o}of t){if(!this.score.errors.some(t=\u003et.pcb_trace_id===`repair04_${n}`))continue;const t=this.routes[n];for(const[i,r]of[[o-2,o+1],[o-2,o],[o-1,o+1],[o-1,o]]){if(e.size\u003e=8)return;if(i\u003c=0||r\u003e=t.route.length-1)continue;const o=`${n}:${i}:${r}`;if(e.has(o))continue;const s=t.route.slice(i,r+1),a=s[0].z;if(!T6(t.route[i-1],this.mutableBounds)||!T6(t.route[r+1],this.mutableBounds)||t.route[i-1].z!==a||t.route[r+1].z!==a||s.some(e=\u003ee.z!==a||this.isLocked(n,e)||Boolean(e.portPointId)||t.vias.some(t=\u003et.x===e.x\u0026\u0026t.y===e.y)))continue;if(!(new Set(s.map(e=\u003ee.traceThickness??t.traceThickness)).size\u003c2)){e.add(o);for(const e of[.1,.05])for(let o=0;o\u003c8;o++){const a=e*Math.cos(o*Math.PI/4),c=e*Math.sin(o*Math.PI/4),l=s.map(t=\u003e({...t,x:t.x+a,y:t.y+c}));l.some(t=\u003e!T6(t,this.mutableBounds))||(yield{routeIndex:n,route:{...t,route:[...t.route.slice(0,i),...l,...t.route.slice(r+1)]}})}}}}}*generateCrossingPairCandidates(){if(this.coupledPathSearchCalls\u003e=4||this.getWorkLimitReason())return;const t=new Set,e=this.score.errors.filter(t=\u003e\"pcb_trace_error\"===t.type\u0026\u0026\"number\"==typeof t.actual_clearance\u0026\u0026t.actual_clearance\u003c0\u0026\u0026void 0!==t.center);for(const n of e){const e=n.center,o=[];for(let t=0;t\u003cthis.routes.length;t++){const n=this.routes[t];if(!n.jumpers?.length)for(let i=1;i\u003cn.route.length;i++){const r=n.route[i-1],s=n.route[i],a=s.x-r.x,c=s.y-r.y,l=a*a+c*c;if(r.z!==s.z||l\u003c1e-12)continue;const d=((e.x-r.x)*a+(e.y-r.y)*c)/l;d\u003c0||d\u003e1||Math.hypot(e.x-r.x-d*a,e.y-r.y-d*c)\u003c1e-6\u0026\u0026o.push({ri:t,pi:i,a:r,b:s})}}for(let e=0;e\u003co.length;e++)for(let i=e+1;i\u003co.length;i++){let r=o[e],s=o[i];if(r.ri===s.ri||r.a.z!==s.a.z)continue;const a=n.pcb_trace_error_id;if(a!==`overlap_repair04_${r.ri}_repair04_${s.ri}`\u0026\u0026a!==`overlap_repair04_${s.ri}_repair04_${r.ri}`)continue;0===this.routes[r.ri].vias.length\u0026\u0026([r,s]=[s,r]);const c=this.routes[r.ri],l=this.routes[s.ri];if(0===c.vias.length||0!==l.vias.length)continue;const d=`${r.ri}:${s.ri}`;if(t.has(d))continue;t.add(d);let h=s.pi-1,u=s.pi;for(;h\u003e0\u0026\u0026!this.isLocked(s.ri,l.route[h]);)h--;for(;u\u003cl.route.length-1\u0026\u0026!this.isLocked(s.ri,l.route[u]);)u++;if(u-h\u003e64||u-h\u003c2||!T6(l.route[h],this.mutableBounds)||!T6(l.route[u],this.mutableBounds))continue;const p=l.route[h].traceThickness??l.traceThickness;if(l.route.slice(h,u+1).some(t=\u003et.z!==s.a.z||t.toNextSegmentType||t.insideJumperPad||(t.traceThickness??l.traceThickness)!==p))continue;const m=this.getViaGeometry(c),g=m.map((t,e)=\u003e({via:t,viaIndex:e,distance:Math.min(...t.pointIndices.map(t=\u003eMath.abs(t-r.pi)))})).sort((t,e)=\u003et.distance-e.distance)[0];if(!g||g.via.pointIndices.some(t=\u003ethis.isLocked(r.ri,c.route[t]))||this.input.movableVias?.length\u0026\u0026!this.input.movableVias.some(t=\u003et.routeIndex===r.ri\u0026\u0026t.viaIndex===g.viaIndex))continue;const f=Math.max(...g.via.pointIndices);let y=r.pi-1;for(;y\u003e0\u0026\u0026!this.isLocked(r.ri,c.route[y]);)y--;if(y\u003e=Math.min(...g.via.pointIndices))continue;const _=s.b.x-s.a.x,b=s.b.y-s.a.y,x=Math.abs(b)\u003e=Math.abs(_)?{x:1,y:0}:{x:0,y:1},v=2*(this.input.traceClearance??.1)+p;for(const t of[-1,1])for(const e of[2,1]){if(this.coupledPathSearchCalls\u003e=4||this.getWorkLimitReason())return;const n=f+e;if(n\u003e=c.route.length)continue;if(c.route.slice(y+1,n).some(t=\u003ethis.isLocked(r.ri,t)))continue;if(!T6(c.route[y],this.mutableBounds)||!T6(c.route[n],this.mutableBounds))continue;const o=c.route[y].traceThickness??c.traceThickness;if(c.route.slice(y,n+1).some(t=\u003et.toNextSegmentType||t.insideJumperPad||(t.traceThickness??c.traceThickness)!==o))continue;const i={...l,route:l.route.map((e,n)=\u003en\u003eh\u0026\u0026n\u003cu?{...e,x:e.x+t*x.x*v,y:e.y+t*x.y*v}:e)};if(i.route.some((t,e)=\u003ee\u003eh\u0026\u0026e\u003cu\u0026\u0026!T6(t,this.mutableBounds)))continue;const a=this.routes.slice();a[s.ri]=i;const d={nodesPopped:0,completionReason:\"no-path\"},p=Math.min(3e4,void 0===this.input.maxPathSearchNodes?3e4:this.input.maxPathSearchNodes-this.pathSearchNodes);if(p\u003c1)return;const g=g1({srj:this.input.srj,routes:a,routeIndex:r.ri,start:c.route[y],end:c.route[n],bounds:this.mutableBounds,traceThickness:o,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,gridSize:o\u003c=.1?o/2:.1,allowLayerChanges:!0,maxNodes:p,stats:d});if(this.coupledPathSearchCalls++,this.pathSearchCalls++,this.pathSearchNodes+=d.nodesPopped,this.updateWorkStats(),!g)continue;const _=R6({...c,route:[...c.route.slice(0,y),...g,...c.route.slice(n+1)]}),b=this.getViaGeometry(_);b.length!==m.length||b.some((t,e)=\u003et.diameter!==m[e].diameter||JSON.stringify(t.layerSequence)!==JSON.stringify(m[e].layerSequence))||(yield{routeIndex:r.ri,route:_,additionalRoutes:[{routeIndex:s.ri,route:i}]})}}}}*generateClearanceCandidates(t,e){const n=new Set;for(const{ri:o,pi:i}of t){if(n.size\u003e=12)break;const t=this.routes[o],r=n=\u003e{const i=t.route[n];return this.isLocked(o,i)||!e\u0026\u0026(n\u003e0\u0026\u0026t.route[n-1].z!==i.z||n+1\u003ct.route.length\u0026\u0026t.route[n+1].z!==i.z)};let s=i-1,a=i;for(;s\u003e0\u0026\u0026!r(s);)s--;for(;a\u003ct.route.length-1\u0026\u0026!r(a);)a++;const c=`${o}:${s}:${a}`;if(n.has(c))continue;n.add(c);const l=t.route[s],d=t.route[a];if(l.x===d.x\u0026\u0026l.y===d.y)continue;const h=t=\u003et.x\u003e=this.mutableBounds.minX-g6\u0026\u0026t.x\u003c=this.mutableBounds.maxX+g6\u0026\u0026t.y\u003e=this.mutableBounds.minY-g6\u0026\u0026t.y\u003c=this.mutableBounds.maxY+g6;if(!h(l)||!h(d))continue;const u=new Set(t.route.slice(s,a+1).map(e=\u003ee.traceThickness??t.traceThickness));if(1!==u.size)continue;const p=[...u][0];if(\"path-search-node-limit\"===this.getWorkLimitReason())return;const m={nodesPopped:0,completionReason:\"no-path\"},g=g1({maxNodes:void 0===this.input.maxPathSearchNodes?void 0:Math.min(3e4,this.input.maxPathSearchNodes-this.pathSearchNodes),stats:m,allowLayerChanges:e,srj:this.input.srj,routes:this.routes,routeIndex:o,start:l,end:d,bounds:this.mutableBounds,traceThickness:p,gridSize:p\u003c=.1?p/2:.1,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1});this.pathSearchCalls++,this.pathSearchNodes+=m.nodesPopped,this.updateWorkStats(),g\u0026\u0026(yield{routeIndex:o,route:R6({...t,route:[...t.route.slice(0,s),...g,...t.route.slice(a+1)]})})}}preservesViaPermissions(t,e){const n=this.input.routes[t],o=this.getViaGeometry(n),i=this.getViaGeometry(e);return e.connectionName===n.connectionName\u0026\u0026e.rootConnectionName===n.rootConnectionName\u0026\u0026e.viaDiameter===n.viaDiameter\u0026\u0026o.length===i.length\u0026\u0026o.every((e,n)=\u003e{const o=i[n];if(JSON.stringify(e.layerSequence)!==JSON.stringify(o.layerSequence)||e.diameter!==o.diameter)return!1;const r=this.input.movableVias?.some(e=\u003ee.routeIndex===t\u0026\u0026e.viaIndex===n);return!0===r||e.x===o.x\u0026\u0026e.y===o.y})}getIndexedViaIds(t,e,n){const o=new Set;if(1!==this.getViaGeometry(e).filter(t=\u003et.x===n.x\u0026\u0026t.y===n.y\u0026\u0026t.identity===n.identity).length)return o;const i=t=\u003e0===t?\"top\":t===this.input.srj.layerCount-1?\"bottom\":`inner${t}`,r=new Set;for(let t=1;t\u003cn.layerSequence.length;t++)r.add(`${n.x},${n.y},${i(n.layerSequence[t-1])},${i(n.layerSequence[t])}`);const s=this.routes.map((n,o)=\u003e{const i=this.getRouteCache(o,o===t?e:n).trace;if(!i)throw new Error(\"repair04: indexed via mapping requires an evaluated route\");return i}),a=new Set;for(const e of[...this.fixedTraces,...s])for(const n of e.route){if(\"via\"!==n.route_type)continue;const i=`${n.x},${n.y},${n.from_layer},${n.to_layer}`;if(a.has(i))continue;const c=`via_${a.size}`;a.add(i),e===s[t]\u0026\u0026r.has(i)\u0026\u0026o.add(c)}return o.size===r.size?o:new Set}*generateViaBlockerCandidates(t,e,n={}){if(this.viaBlockerPathSearchCalls\u003e=4||this.getWorkLimitReason())return;const o=e.evaluatedScore;if(!o||!this.score||e.additionalRoutes?.length||e.routeIndex!==t.routeIndex)return;if(!this.input.movableVias?.some(e=\u003ee.routeIndex===t.routeIndex\u0026\u0026e.viaIndex===t.viaIndex)||!this.preservesViaPermissions(t.routeIndex,e.route))return;if([...o.fixedViolations].some(([t,e])=\u003e!this.score.fixedViolations.has(t)||e\u003ethis.score.fixedViolations.get(t)+g6))return;const i=this.routes[t.routeIndex],r=this.getViaGeometry(i)[t.viaIndex],s=this.getViaGeometry(e.route)[t.viaIndex],a=n.oldIds??=this.getIndexedViaIds(t.routeIndex,i,r);if(!a.size)return;const c=`repair04_${t.routeIndex}`,l=(t,e)=\u003e{const n=t.pcb_via_id,o=t.pcb_trace_id;if(\"pcb_trace_error\"===t.type\u0026\u0026\"string\"==typeof n\u0026\u0026e.has(n)\u0026\u0026\"string\"==typeof o\u0026\u0026o!==c\u0026\u0026t.pcb_trace_error_id===`overlap_${o}_${n}`\u0026\u0026Array.isArray(t.pcb_trace_ids)\u0026\u00262===t.pcb_trace_ids.length\u0026\u0026t.pcb_trace_ids.includes(c)\u0026\u0026t.pcb_trace_ids.includes(o))return o},d=(t,e)=\u003e{const n=new Set;for(const o of t){const t=l(o,e);void 0!==t\u0026\u0026n.add(t)}return n},h=n.oldContacts??=d(this.score.errors,a);if(!h.size)return;if(n.oldNeighborFixed??=this.getFixedViolations(this.routes).some(t=\u003e\"wire\"===t.kind\u0026\u0026h.has(`repair04_${t.routeIndex}`)))return;const u=this.getIndexedViaIds(t.routeIndex,e.route,s);if(a.size!==u.size)return;for(const t of o.errors){if([t.pcb_via_id,...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids:[],...Array.isArray(t.pcb_pad_ids)?t.pcb_pad_ids:[]].some(t=\u003e\"string\"==typeof t\u0026\u0026u.has(t))\u0026\u0026void 0===l(t,u))return}const p=d(o.errors,u);if(1!==p.size||[...p].some(t=\u003eh.has(t)))return;const m=[...p][0];if(!/^repair04_(0|[1-9][0-9]*)$/.test(m))return;const g=Number(m.slice(9)),f=this.routes[g];if(!f||g===t.routeIndex||f.jumpers?.length||f.connectionName===i.connectionName||f.rootConnectionName\u0026\u0026f.rootConnectionName===i.rootConnectionName||f.route.some(t=\u003eBoolean(t.toNextSegmentType||t.insideJumperPad)))return;let y=-1,_=1/0;for(let t=1;t\u003cf.route.length;t++){const e=f.route[t-1],n=f.route[t];if(e.z!==n.z||e.z\u003cs.minZ||e.z\u003es.maxZ)continue;const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,a=r?Math.max(0,Math.min(1,((s.x-e.x)*o+(s.y-e.y)*i)/r)):0,c=Math.hypot(s.x-e.x-a*o,s.y-e.y-a*i);c\u003c_\u0026\u0026(_=c,y=t)}if(y\u003c1)return;const b=t=\u003e{const e=f.route[t];return this.isLocked(g,e)||t\u003e0\u0026\u0026f.route[t-1].z!==e.z||t+1\u003cf.route.length\u0026\u0026f.route[t+1].z!==e.z};let x=y-1,v=y;for(;x\u003e0\u0026\u0026!b(x);)x--;for(;v\u003cf.route.length-1\u0026\u0026!b(v);)v++;const S=f.route[x],I=f.route[v],C=t=\u003et.x\u003e=this.mutableBounds.minX-g6\u0026\u0026t.x\u003c=this.mutableBounds.maxX+g6\u0026\u0026t.y\u003e=this.mutableBounds.minY-g6\u0026\u0026t.y\u003c=this.mutableBounds.maxY+g6;if(S.z!==I.z||!C(S)||!C(I))return;const P=S.traceThickness??f.traceThickness;if(f.route.slice(x,v+1).some(t=\u003e(t.traceThickness??f.traceThickness)!==P))return;const M=Math.min(3e4,void 0===this.input.maxPathSearchNodes?3e4:this.input.maxPathSearchNodes-this.pathSearchNodes);if(M\u003c1)return;const N=this.routes.slice();N[t.routeIndex]=e.route;const w={nodesPopped:0,completionReason:\"no-path\"},T=g1({srj:this.input.srj,routes:N,routeIndex:g,start:I,end:S,bounds:this.mutableBounds,traceThickness:P,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,gridSize:Math.max(.025,P/4),allowLayerChanges:!1,maxNodes:M,stats:w});if(this.viaBlockerPathSearchCalls++,this.pathSearchCalls++,this.pathSearchNodes+=w.nodesPopped,this.updateWorkStats(),!T)return;T.reverse();const R={...f,route:[...f.route.slice(0,x),...T,...f.route.slice(v+1)]};E6(R)===E6(f)\u0026\u0026(yield{routeIndex:e.routeIndex,route:e.route,additionalRoutes:[{routeIndex:g,route:R}]})}*generateExistingViaCandidates(){for(const t of this.input.movableVias??[]){const e=this.routes[t.routeIndex],n=this.getViaGeometry(e)[t.viaIndex];if(n.pointIndices.some(n=\u003ethis.isLocked(t.routeIndex,e.route[n])))continue;const o={};for(const i of[.025,.05,.1,.2,.35,.5,.8,1.2])for(let r=0;r\u003c16;r++){const s=n.x+i*Math.cos(r*Math.PI/8),a=n.y+i*Math.sin(r*Math.PI/8);if(!T6({x:s,y:a,z:n.minZ},this.mutableBounds))continue;const c=e.route.map((t,e)=\u003en.pointIndices.includes(e)?{...t,x:s,y:a}:t),l={routeIndex:t.routeIndex,route:R6({...e,route:c})};yield l,yield*this.generateViaBlockerCandidates(t,l,o)}}}*generateCandidates(){yield*this.generateExistingViaCandidates();for(const t of!0===this.input.allowLayerChanges?!1===this.input.traceOnlyFirst?[!0]:[!1,!0]:[!1]){if(\"path-search-node-limit\"===this.getWorkLimitReason())return;const e=!0===this.input.allowLayerChanges?Math.min(512,Math.floor(this.maxCandidates/4)):Number.MAX_SAFE_INTEGER;if(!t\u0026\u00260===e)continue;let n=0;for(const o of this.generateCandidatesForMode(t)){if(!t){if([o,...o.additionalRoutes??[]].some(({routeIndex:t,route:e})=\u003ethis.input.movableVias?.length?!this.preservesViaPermissions(t,e):E6(e)!==E6(this.routes[t])))continue;if(n++\u003e=e)break}yield o}}}*generateCandidatesForMode(t){const e=this.score.errors.flatMap(t=\u003e{const e=t.center??t.pcb_center;return e?[e]:[]}),n=[];for(let t=0;t\u003cthis.routes.length;t++){const o=this.routes[t];if(!o.jumpers?.length\u0026\u0026!o.route.some(t=\u003et.toNextSegmentType||t.insideJumperPad))for(let i=1;i\u003co.route.length;i++){const r=o.route[i-1],s=o.route[i];if(r.toNextSegmentType||r.insideJumperPad||s.insideJumperPad)continue;let a=1/0,c=.5;const l=s.x-r.x,d=s.y-r.y,h=l*l+d*d;for(const t of e){const e=h?Math.max(0,Math.min(1,((t.x-r.x)*l+(t.y-r.y)*d)/h)):0,n=Math.hypot(t.x-r.x-e*l,t.y-r.y-e*d);n\u003ca\u0026\u0026(a=n,c=e)}a\u003c1.5\u0026\u0026n.push({ri:t,pi:i,distance:a,t:c})}}if(n.sort((t,e)=\u003et.distance-e.distance||t.ri-e.ri||t.pi-e.pi),this.threeRoutePathSearchCalls\u003c18\u0026\u0026!this.getWorkLimitReason()){const t=function*(t){const{routes:e}=t,n=t.violations.filter(t=\u003e\"wire\"===t.kind).sort((t,e)=\u003ee.severity-t.severity||t.routeIndex-e.routeIndex||t.obstacleIndex-e.obstacleIndex);if(!n.length||t.maxSearchCalls\u003c=0||t.remainingNodes()\u003c=0)return;const o=[];let i=0;const r=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r?Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r)):0;return Math.hypot(t.x-e.x-s*o,t.y-e.y-s*i)},s=(t,e)=\u003e{const n=t.route[e],o=t.route[e-1],i=t.route[e+1];return void 0!==o\u0026\u0026o.z!==n.z||void 0!==i\u0026\u0026i.z!==n.z},a=e=\u003e{const n=t.bounds;return e.x\u003e=n.minX-1e-8\u0026\u0026e.x\u003c=n.maxX+1e-8\u0026\u0026e.y\u003e=n.minY-1e-8\u0026\u0026e.y\u003c=n.maxY+1e-8};for(let n=0;n\u003ce.length;n++){const i=e[n];if(i.jumpers?.length||i.route.some(t=\u003eBoolean(t.toNextSegmentType||t.insideJumperPad)))continue;const r=e=\u003et.isLocked(n,e)||s(i,e);for(let t=0;t\u003ci.route.length-1;){let e=t+1;if(i.route[t].z!==i.route[e].z){t=e;continue}for(;e\u003ci.route.length-1\u0026\u0026!r(e)\u0026\u0026i.route[e+1].z===i.route[t].z;)e++;const c=i.route[t].traceThickness??i.traceThickness;e\u003et\u0026\u0026a(i.route[t])\u0026\u0026a(i.route[e])\u0026\u0026i.route.slice(t,e+1).every(t=\u003e(t.traceThickness??i.traceThickness)===c)\u0026\u0026o.push({ri:n,a:t,b:e,z:i.route[t].z,width:c,distance:1/0,viaEnds:Number(s(i,t))+Number(s(i,e))}),t=e}}const c=new Set;for(const s of n){for(const t of o){t.distance=1/0;const n=e[t.ri];for(let e=t.a+1;e\u003c=t.b;e++)t.distance=Math.min(t.distance,r(s.center,n.route[e-1],n.route[e]))}const n=o.filter(t=\u003et.ri===s.routeIndex).sort((t,e)=\u003et.distance-e.distance||t.a-e.a)[0];if(!n||n.distance\u003e.5)continue;const a=e[n.ri],l=o.filter(t=\u003et.ri!==n.ri\u0026\u0026t.z===n.z\u0026\u0026t.distance\u003c1.5\u0026\u0026e[t.ri].connectionName!==a.connectionName\u0026\u0026(!a.rootConnectionName||e[t.ri].rootConnectionName!==a.rootConnectionName)).sort((t,e)=\u003et.distance-e.distance||t.ri-e.ri||t.a-e.a),d=l[0],h=l.find(t=\u003et.ri!==d?.ri);if(!d||!h)continue;const u=[n,d,h],p=u.map(t=\u003e`${t.ri}:${t.a}:${t.b}`).join(\"|\");if(c.has(p))continue;c.add(p);const m=d.viaEnds\u003e=h.viaEnds?1:2,g=3-m,f=[[m,0,g],[0,1,2],[0,2,1],[1,2,0],[2,1,0],[g,0,m]],y=new Set;for(const n of f){if(y.has(n.join()))continue;y.add(n.join());const o=e.map(t=\u003e({...t}));for(const t of u){const n=e[t.ri];o[t.ri]={...n,route:n.route.slice(0,t.a+1)},o.push({...n,route:n.route.slice(t.b)})}let r=!0;for(const s of n){if(i\u003e=t.maxSearchCalls||t.remainingNodes()\u003c=0)return;const n=u[s],a=e[n.ri],c={nodesPopped:0,completionReason:\"no-path\"},l=g1({srj:t.srj,routes:o,routeIndex:n.ri,start:a.route[n.b],end:a.route[n.a],bounds:t.bounds,traceThickness:n.width,traceClearance:t.traceClearance,viaClearance:t.viaClearance,gridSize:Math.max(.025,n.width/4),allowLayerChanges:!1,maxNodes:Math.min(3e4,t.remainingNodes()),stats:c});if(i++,t.onSearch(c),!l){r=!1;break}l.reverse(),o[n.ri]={...a,route:[...a.route.slice(0,n.a),...l,...a.route.slice(n.b+1)]},o[e.length+s].route=[]}r\u0026\u0026(yield u.map(t=\u003e({routeIndex:t.ri,route:o[t.ri]})))}}}({srj:this.input.srj,routes:this.routes,bounds:this.mutableBounds,violations:this.getFixedViolations(this.routes),isLocked:(t,e)=\u003ethis.isLocked(t,this.routes[t].route[e]),traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,maxSearchCalls:18-this.threeRoutePathSearchCalls,remainingNodes:()=\u003eMath.min(5e5-this.threeRoutePathSearchNodes,void 0===this.input.maxPathSearchNodes?Number.MAX_SAFE_INTEGER:this.input.maxPathSearchNodes-this.pathSearchNodes),onSearch:t=\u003e{this.threeRoutePathSearchCalls++,this.threeRoutePathSearchNodes+=t.nodesPopped,this.pathSearchCalls++,this.pathSearchNodes+=t.nodesPopped,this.updateWorkStats()}});for(const[e,...n]of t)e\u0026\u0026(yield{...e,additionalRoutes:n})}if(t\u0026\u0026(yield*this.generateCrossingPairCandidates()),yield*this.generateTaperedSegmentCandidates(n),yield*this.generateClearanceCandidates(n,t),\"path-search-node-limit\"===this.getWorkLimitReason())return;const o=new Set;for(const{ri:e,pi:i}of n.slice(0,80)){const n=this.routes[e];for(const r of[2,4,8,16]){const s=Math.max(0,i-r),a=Math.min(n.route.length-1,i+r),c=`${e}:${s}:${a}`;if(o.has(c))continue;o.add(c);const l=n.route[s],d=n.route[a];if(l.z!==d.z||!T6(l,this.mutableBounds)||!T6(d,this.mutableBounds))continue;if(n.route.slice(s+1,a).some(t=\u003ethis.isLocked(e,t)))continue;const h=new Set(n.route.slice(s,a+1).map(t=\u003et.traceThickness??n.traceThickness));if(1!==h.size)continue;const u=[...h][0],p=d.x-l.x,m=d.y-l.y,g=Math.hypot(p,m);if(!(g\u003c.1)){yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),...n.route.slice(a)]})};for(const t of[.15,-.15,.35,-.35,.7,-.7,1.5,-1.5])for(const o of[.2,0]){const i={x:l.x+p*o-m/g*t,y:l.y+m*o+p/g*t,z:l.z,traceThickness:u},r={x:l.x+p*(1-o)-m/g*t,y:l.y+m*(1-o)+p/g*t,z:l.z,traceThickness:u};T6(i,this.mutableBounds)\u0026\u0026T6(r,this.mutableBounds)\u0026\u0026(yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),i,r,...n.route.slice(a)]})})}if(t\u0026\u0026g\u003e2*n.viaDiameter+.3)for(let t=0;t\u003cthis.input.srj.layerCount;t++){if(t===l.z)continue;const o={x:l.x+.2*p,y:l.y+.2*m,z:l.z,traceThickness:u},i={x:l.x+.8*p,y:l.y+.8*m,z:l.z,traceThickness:u};yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),o,{...o,z:t},{...i,z:t},i,...n.route.slice(a)]})}}}}}const i=new Set;for(const{ri:e,pi:o,t:r}of n){const n=this.routes[e],s=n.route[o-1],a=n.route[o];for(const t of[o-1,o]){const o=n.route[t],r=`${e}:${o.x}:${o.y}`;if(i.has(r))continue;i.add(r);const s=n.route.map((t,e)=\u003et.x===o.x\u0026\u0026t.y===o.y?e:-1).filter(t=\u003et\u003e=0);if(!s.some(t=\u003ethis.isLocked(e,n.route[t])))for(const t of[.025,.05,.1,.2,.35,.5,.8,1.2])for(let o=0;o\u003c16;o++){const i=t*Math.cos(o*Math.PI/8),r=t*Math.sin(o*Math.PI/8),a=n.route.map((t,e)=\u003es.includes(e)?{...t,x:t.x+i,y:t.y+r}:t);s.some(t=\u003e!T6(a[t],this.mutableBounds))||(yield{routeIndex:e,route:R6({...n,route:a})})}}const c=t=\u003et.x\u003e=this.mutableBounds.minX-1e-8\u0026\u0026t.x\u003c=this.mutableBounds.maxX+1e-8\u0026\u0026t.y\u003e=this.mutableBounds.minY-1e-8\u0026\u0026t.y\u003c=this.mutableBounds.maxY+1e-8;if(s.z!==a.z||!c(s)||!c(a))continue;const l=a.x-s.x,d=a.y-s.y,h=Math.hypot(l,d);if(h\u003c.02)continue;const u=Math.max(s.traceThickness??n.traceThickness,a.traceThickness??n.traceThickness),p=l/h,m=d/h;for(const i of[.4,.8,1.5,3]){const a=Math.max(0,r*h-i),c=Math.min(h,r*h+i);for(const t of[.12,-.12,.25,-.25,.5,-.5,1,-1]){const i={x:s.x+p*a-m*t,y:s.y+m*a+p*t,z:s.z,traceThickness:u},r={x:s.x+p*c-m*t,y:s.y+m*c+p*t,z:s.z,traceThickness:u};T6(i,this.mutableBounds)\u0026\u0026T6(r,this.mutableBounds)\u0026\u0026(yield{routeIndex:e,route:{...n,route:[...n.route.slice(0,o),i,r,...n.route.slice(o)]}})}if(!t||c-a\u003cn.viaDiameter+.15)continue;const l={x:s.x+p*a,y:s.y+m*a,z:s.z,traceThickness:u},d={x:s.x+p*c,y:s.y+m*c,z:s.z,traceThickness:u};if(T6(l,this.mutableBounds)\u0026\u0026T6(d,this.mutableBounds))for(let t=0;t\u003cthis.input.srj.layerCount;t++){if(t===s.z)continue;const i=[l,{...l,z:t},{...d,z:t},d];yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,o),...i,...n.route.slice(o)]})}}}}}_step(){this.score||(this.score=this.evaluate(this.routes),this.stats={initialErrorCount:this.score.count,finalErrorCount:this.score.count,candidates:0,accepted:0},this.candidates=this.generateCandidates(),this.updateWorkStats());const t=this.getWorkLimitReason();if(0===this.score.count||this.evaluated\u003e=this.maxCandidates||t)return void this.finishSearch(0===this.score.count?\"clean\":this.evaluated\u003e=this.maxCandidates?\"candidate-limit\":t);const e=this.candidates.next();if(e.done){const t=this.getWorkLimitReason();return t?void this.finishSearch(t):void(this.bestAdjustment?(this.routes=this.bestAdjustment.routes,this.candidateScores.clear(),this.score=this.bestAdjustment.score,this.bestAdjustment=null,this.accepted++,this.candidates=this.generateCandidates()):(this.updateWorkStats(\"search-exhausted\"),this.solved=!0))}this.candidateAttempts++,this.updateWorkStats();const n=[e.value,...e.value.additionalRoutes??[]];if((!0!==this.input.allowLayerChanges||this.input.movableVias?.length)\u0026\u0026n.some(({routeIndex:t,route:e})=\u003e!this.preservesViaPermissions(t,e)))return;const o=this.routes.slice();for(const{routeIndex:t,route:e}of n)o[t]=e;const i=new Map;for(const t of this.getFixedViolations(o))i.set(t.key,t.severity);const r=[...i].every(([t,e])=\u003ethis.score.fixedViolations.has(t)\u0026\u0026e\u003c=this.score.fixedViolations.get(t)+g6),s=0===this.getViaPadViolations(o,!1).length;let a;if(s\u0026\u0026r){const t=JSON.stringify([e.value.routeIndex,e.value.route,...e.value.additionalRoutes??[]]);a=this.candidateScores.get(t),a||(a=this.evaluate(o),this.candidateScores.size\u003e=128\u0026\u0026this.candidateScores.delete(this.candidateScores.keys().next().value),this.candidateScores.set(t,a))}e.value.evaluatedScore=a,this.evaluated++,a\u0026\u0026s\u0026\u0026r\u0026\u0026a.count\u003cthis.score.count?(this.routes=o,this.candidateScores.clear(),this.score=a,this.accepted++,this.bestAdjustment=null,this.candidates=this.generateCandidates()):a\u0026\u0026r\u0026\u0026s\u0026\u0026a.count===this.score.count\u0026\u0026a.severity\u003c(this.bestAdjustment?.score.severity??this.score.severity)-1e-6\u0026\u0026(this.bestAdjustment={routes:o,score:a}),this.stats={...this.stats,finalErrorCount:this.score.count,candidates:this.evaluated,accepted:this.accepted},this.progress=this.evaluated/this.maxCandidates}getConstructorParams(){return[structuredClone(this.input)]}getOutput(){if(!this.solved||this.failed)throw new Error(\"repair04: getOutput requires a completed solve\");return structuredClone(this.routes)}visualize(){const t=this.input.bounds,e=this.mutableBounds;return{title:\"repair04 — fixed boundary, local copper repair\",rects:[{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,stroke:\"#64748b\",fill:\"rgba(148,163,184,0.15)\"},{center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,stroke:\"#0891b2\",fill:\"transparent\"},...this.input.srj.obstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,fill:\"rgba(239,68,68,0.22)\",stroke:\"#b91c1c\",layer:`z${t.layers.map(t=\u003e\"top\"===t?0:\"bottom\"===t?this.input.srj.layerCount-1:Number(t.slice(5))).join(\",\")}`}))],lines:this.routes.flatMap(t=\u003et.route.slice(1).flatMap((e,n)=\u003ee.z===t.route[n].z?[{points:[t.route[n],e],strokeColor:0===e.z?\"#dc2626\":\"rgba(37,99,235,0.65)\",strokeWidth:e.traceThickness??t.traceThickness,...0===e.z?{}:{strokeDash:[.2,.12]},layer:`z${e.z}`}]:[])),circles:this.routes.flatMap(t=\u003et.vias.map(e=\u003e{const n=t.route.filter(t=\u003et.x===e.x\u0026\u0026t.y===e.y).map(t=\u003et.z),o=Math.min(...n),i=Math.max(...n);return{center:e,radius:t.viaDiameter/2,fill:\"rgba(37,99,235,0.65)\",stroke:\"#1e40af\",layer:`z${Array.from({length:i-o+1},(t,e)=\u003eo+e).join(\",\")}`}})),points:this.lockedPoints.flat().map(t=\u003e({...t,color:\"#0f172a\",layer:`z${t.z}`}))}}},O6=(t,e,n)=\u003e{if(n\u003c=g6)return structuredClone(t);if(n\u003e=.99999999)return structuredClone(e);const o={...structuredClone(t),x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n};return delete o.start_pcb_port_id,delete o.end_pcb_port_id,o},k6=(t,e)=\u003e{const n=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,s=e.start.x-t.start.x,a=e.start.y-t.start.y,c=n*r-o*i,l=(t,e)=\u003e({x:t.start.x+(t.end.x-t.start.x)*e,y:t.start.y+(t.end.y-t.start.y)*e}),d=(t,e)=\u003e{const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=n*n+o*o,r=i\u003e10000000000000001e-32?Math.max(0,Math.min(1,((t.x-e.start.x)*n+(t.y-e.start.y)*o)/i)):0;return l(e,r)};if(Math.abs(c)\u003eg6){const e=(s*r-a*i)/c,d=(s*o-a*n)/c;if(e\u003e=0\u0026\u0026e\u003c=1\u0026\u0026d\u003e=0\u0026\u0026d\u003c=1){const n=l(t,e);return[n,n]}}else{const i=n*n+o*o;if(i\u003e10000000000000001e-32){const r=(s*n+a*o)/i,c=((e.end.x-t.start.x)*n+(e.end.y-t.start.y)*o)/i,h=Math.max(0,Math.min(r,c)),u=Math.min(1,Math.max(r,c));if(h\u003c=u){const n=l(t,(h+u)/2);return[n,d(n,e)]}}}const h=[[t.start,d(t.start,e)],[t.end,d(t.end,e)],[d(e.start,t),e.start],[d(e.end,t),e.end]];return h.sort((t,e)=\u003eMath.hypot(t[0].x-t[1].x,t[0].y-t[1].y)-Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y)),h[0]},L6=(t,e)=\u003e{const n=\"top\"===t?0:\"bottom\"===t?e-1:/^inner\\d+$/.test(t)?Number(t.slice(5)):-1;if(!Number.isInteger(n)||n\u003c0||n\u003e=e)throw new Error(`repair04 preload has an unknown layer: ${t}`);return n},D6=(t,e,n)=\u003e{const o=((t,e)=\u003e{const n=new Map,o=t=\u003e{const e=n.get(t);if(void 0===e||e===t)return t;const i=o(e);return n.set(t,i),i},i=t=\u003e{const e=t.filter(t=\u003e\"string\"==typeof t\u0026\u0026t.length\u003e0);if(0===e.length)return;const i=o(e[0]);for(const t of e)n.set(o(t),i)};for(const e of t.connections){const t=e;i([t.name,t.rootConnectionName,t.netConnectionName,t.__netConnectionName,...t.mergedConnectionNames??[],...t.__rootConnectionNames??[]])}for(const t of e)i([t.connectionName,t.rootConnectionName]);for(const e of t.traces??[])i([e.connection_name,...e.connectsTo??[]]);return o})(t,e),i=e.map((t,e)=\u003ee),r=t=\u003e{const e=i[t];if(e===t)return t;const n=r(e);return i[t]=n,n},s=new Map;for(let t=0;t\u003ce.length;t+=1){const n=e[t];for(const e of[n.route[0],n.route.at(-1)]){if(!e?.pcb_port_id)continue;const a=JSON.stringify([o(n.connectionName),e.pcb_port_id,e.x,e.y,e.z]),c=s.get(a);void 0===c?s.set(a,t):i[r(t)]=r(c)}}const a=(t,e)=\u003e!(!t.startsWith(\"route:\")||!e.startsWith(\"route:\"))\u0026\u0026r(Number(t.slice(6)))===r(Number(e.slice(6))),c=[],l=[],d=[],h=e.map(()=\u003e({segmentTimes:new Map,viaPositions:[]})),u=t=\u003e{if(f6(t,n)){d.push(t);for(let e=t.minZ;e\u003c=t.maxZ;e+=1)c.push({x:t.x,y:t.y,z:e,radius:t.radius,net:t.net,source:t.source,...void 0!==t.routeIndex?{viaOwner:t.routeIndex}:{}})}};for(let t=0;t\u003ce.length;t+=1){const i=e[t],r=o(i.connectionName),s=`route:${t}`;for(let e=0;e\u003ci.route.length;e+=1){const o=i.route[e];if((0===e||e===i.route.length-1||o.pcb_port_id)\u0026\u0026f6(o,n)\u0026\u0026c.push({x:o.x,y:o.y,z:o.z,radius:(o.traceThickness??i.traceThickness)/2,net:r,source:s}),0===e)continue;const a=i.route[e-1];\"through_obstacle\"!==a.toNextSegmentType\u0026\u0026(a.z===o.z?l.push({start:a,end:o,z:o.z,radius:Math.max(a.traceThickness??i.traceThickness,o.traceThickness??i.traceThickness)/2,net:r,source:s,routeIndex:t,segmentIndex:e-1}):u({x:o.x,y:o.y,minZ:Math.min(a.z,o.z),maxZ:Math.max(a.z,o.z),radius:i.viaDiameter/2,net:r,source:s,routeIndex:t}))}}for(let e=0;e\u003c(t.traces??[]).length;e+=1){const i=m1(t.traces[e],t.minTraceWidth),r=o(i.connection_name),s=`fixed:${e}`;for(let e=0;e\u003ci.route.length;e+=1){const o=i.route[e],a=i.route[e-1];if(\"wire\"===o.route_type){const d=L6(o.layer,t.layerCount);(0===e||e===i.route.length-1||o.start_pcb_port_id||o.end_pcb_port_id)\u0026\u0026f6(o,n)\u0026\u0026c.push({x:o.x,y:o.y,z:d,radius:o.width/2,net:r,source:s}),\"wire\"===a?.route_type\u0026\u0026a.layer===o.layer\u0026\u0026l.push({start:a,end:o,z:d,radius:Math.max(a.width,o.width)/2,net:r,source:s})}else if(\"via\"===o.route_type){const e=L6(o.from_layer,t.layerCount),n=L6(o.to_layer,t.layerCount);u({x:o.x,y:o.y,minZ:Math.min(e,n),maxZ:Math.max(e,n),radius:(o.via_diameter??t.minViaDiameter??.3)/2,net:r,source:s})}}}const p=new Map;for(const t of c){const e=JSON.stringify([t.net,t.z]),n=p.get(e)??[];n.push(t),p.set(e,n)}const m=(t,e)=\u003e{if(void 0===t)return;const n=h[t].viaPositions;n.some(t=\u003eMath.hypot(t.x-e.x,t.y-e.y)\u003c=g6)||n.push({x:e.x,y:e.y})};for(const t of l){if(!y6(t.start,t.end,n))continue;const e=t.end.x-t.start.x,o=t.end.y-t.start.y,i=e*e+o*o;if(!(i\u003c=10000000000000001e-32))for(const r of p.get(JSON.stringify([t.net,t.z]))??[]){if(r.source===t.source||a(r.source,t.source))continue;const s=Math.max(0,Math.min(1,((r.x-t.start.x)*e+(r.y-t.start.y)*o)/i)),c={x:t.start.x+e*s,y:t.start.y+o*s};if(f6(c,n)\u0026\u0026!(Math.hypot(c.x-r.x,c.y-r.y)\u003et.radius+r.radius+g6)){if(void 0!==t.routeIndex\u0026\u0026void 0!==t.segmentIndex){const e=h[t.routeIndex].segmentTimes.get(t.segmentIndex)??[];e.some(t=\u003eMath.abs(t-s)\u003c=g6)||e.push(s),h[t.routeIndex].segmentTimes.set(t.segmentIndex,e)}m(r.viaOwner,r)}}}for(const t of d)for(let e=t.minZ;e\u003c=t.maxZ;e+=1)for(const n of p.get(JSON.stringify([t.net,e]))??[])n.source===t.source||a(n.source,t.source)||Math.hypot(t.x-n.x,t.y-n.y)\u003et.radius+n.radius+g6||(m(t.routeIndex,t),m(n.viaOwner,n));return((t,e,n,o)=\u003e{const i=new Map,r=new Set,s=[],a=(t,e)=\u003e{if(void 0===t.routeIndex||void 0===t.segmentIndex)return;const o=t.end.x-t.start.x,i=t.end.y-t.start.y,r=o*o+i*i;if(r\u003c=10000000000000001e-32)return;const s=Math.max(0,Math.min(1,((e.x-t.start.x)*o+(e.y-t.start.y)*i)/r)),a=n[t.routeIndex].segmentTimes.get(t.segmentIndex)??[];a.some(t=\u003eMath.abs(t-s)\u003c=g6)||a.push(s),n[t.routeIndex].segmentTimes.set(t.segmentIndex,a)};for(const n of t){const t=y6(n.start,n.end,e);if(!t||t[1]-t[0]\u003c=g6)continue;const c=t=\u003e({x:n.start.x+(n.end.x-n.start.x)*t,y:n.start.y+(n.end.y-n.start.y)*t}),l={...n,start:c(t[0]),end:c(t[1])},d=s.length;s.push({original:n,clipped:l});const h=Math.floor((Math.min(l.start.x,l.end.x)-l.radius)/2),u=Math.floor((Math.max(l.start.x,l.end.x)+l.radius)/2),p=Math.floor((Math.min(l.start.y,l.end.y)-l.radius)/2),m=Math.floor((Math.max(l.start.y,l.end.y)+l.radius)/2);for(let t=h;t\u003c=u;t+=1)for(let e=p;e\u003c=m;e+=1){const c=JSON.stringify([l.net,l.z,t,e]),h=i.get(c)??[];for(const t of h){const e=s[t];if(e.original.source===n.source||o(e.original.source,n.source)||void 0===e.original.routeIndex\u0026\u0026void 0===n.routeIndex)continue;const i=`${t}:${d}`;if(r.has(i))continue;r.add(i);const[c,h]=k6(l,e.clipped);Math.hypot(c.x-h.x,c.y-h.y)\u003el.radius+e.clipped.radius+g6||(a(n,c),a(e.original,h))}h.push(d),i.set(c,h)}}})(l,n,h,a),h},z6=(t,e)=\u003e({minX:t.minX-e,maxX:t.maxX+e,minY:t.minY-e,maxY:t.maxY+e}),F6=(t,e,n,o)=\u003e{const i=[];let r;const s=t.route,a=t=\u003e0===t||t===s.length-1||void 0!==s[t]?.pcb_port_id,c=()=\u003e{void 0!==r\u0026\u0026r.points.length\u003e0\u0026\u0026(r.locks[0]=!0,r.locks[r.points.length-1]=!0,i.push(r)),r=void 0};if(1===s.length\u0026\u0026s[0]\u0026\u0026f6(s[0],e))return[{points:structuredClone(s),locks:[!0],start:{segmentIndex:0,t:0},end:{segmentIndex:0,t:0}}];for(let i=0;i\u003cs.length-1;i+=1){const l=s[i],d=s[i+1];if(!l||!d)throw new Error(\"repair04 found a missing route point\");if(![l.x,l.y,l.z,d.x,d.y,d.z].every(Number.isFinite))throw new Error(\"repair04 route coordinates must be finite\");if(l.z!==d.z\u0026\u0026!b6({x:l.x,y:l.y},{x:d.x,y:d.y})\u0026\u0026\"through_obstacle\"!==l.toNextSegmentType)throw new Error(\"repair04 requires colocated points at a via transition\");const h=y6(l,d,e);if(!h){c();continue}const[u,p]=h;if(p-u\u003c=g6\u0026\u0026!b6(l,d)){c();continue}const m=y6(l,d,n),g=[u,p],f=o.segmentTimes.get(i)??[];for(const t of f)t\u003e=u-g6\u0026\u0026t\u003c=p+g6\u0026\u0026g.push(Math.max(u,Math.min(p,t)));if(m\u0026\u0026l.z===d.z)for(const t of m)t\u003eu+g6\u0026\u0026t\u003cp-g6\u0026\u0026g.push(t);g.sort((t,e)=\u003et-e);const y=g.filter((t,e)=\u003e0===e||Math.abs(t-g[e-1])\u003eg6),_=_6(l,d,u);r\u0026\u0026!b6(r.points[r.points.length-1],_)\u0026\u0026c(),r||(r={points:[],locks:[],start:{segmentIndex:i,t:u},end:{segmentIndex:i,t:p}});for(const e of y){const s=_6(l,d,e),c=e\u003c=g6?i:e\u003e=.99999999?i+1:void 0,h=!f6(s,n,4e-8)||f.some(t=\u003eMath.abs(t-e)\u003c=g6)||o.viaPositions.some(t=\u003eMath.hypot(t.x-s.x,t.y-s.y)\u003c=g6)||void 0!==c\u0026\u0026a(c)||\"through_obstacle\"===l.toNextSegmentType||\"through_obstacle\"===s.toNextSegmentType||!0===l.insideJumperPad||!0===d.insideJumperPad||(t.jumpers??[]).some(t=\u003eb6(s,{...t.start,z:s.z})||b6(s,{...t.end,z:s.z})),u=r.points[r.points.length-1];u\u0026\u0026b6(u,s)?r.locks[r.locks.length-1]=r.locks[r.locks.length-1]||h:(r.points.push(s),r.locks.push(h))}r.end={segmentIndex:i,t:p},p\u003c.99999999\u0026\u0026c()}c();for(const t of i)for(let e=1;e\u003ct.points.length;e+=1){const n=t.points[e-1],o=t.points[e];if(n.z!==o.z\u0026\u0026(t.locks[e-1]||t.locks[e])){let n=e-1,i=e;for(;n\u003e0\u0026\u0026b6({x:t.points[n-1].x,y:t.points[n-1].y},{x:o.x,y:o.y});)n-=1;for(;i+1\u003ct.points.length\u0026\u0026b6({x:t.points[i+1].x,y:t.points[i+1].y},{x:o.x,y:o.y});)i+=1;for(let e=n;e\u003c=i;e+=1)t.locks[e]=!0}}return i},B6=(t,e)=\u003e{const n=t.bounds,o=t.outline\u0026\u0026t.outline.length\u003e=3?t.outline:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}],i=[];for(let n=0;n\u003co.length;n+=1){const r=o[n],s=o[(n+1)%o.length],a=y6(r,s,e);if(!a)continue;const c=s.x-r.x,l=s.y-r.y,d=Math.hypot(c,l);if(d\u003c=g6)continue;const h=(a[0]+a[1])/2;i.push({obstacleId:`repair04_board_edge_${n}`,type:\"rect\",center:{x:r.x+c*h,y:r.y+l*h},width:d*(a[1]-a[0]),height:Math.max(2*(t.minBoardEdgeClearance??0),g6),ccwRotationDegrees:180*Math.atan2(l,c)/Math.PI,layers:Array.from({length:t.layerCount},(e,n)=\u003e0===n?\"top\":n===t.layerCount-1?\"bottom\":`inner${n}`),zLayers:Array.from({length:t.layerCount},(t,e)=\u003ee),connectedTo:[]})}return i},j6=({srj:t,routes:e,bounds:n,boundaryMargin:o=.5,clearanceHalo:i})=\u003e{if((t=\u003e{if(!Object.values(t).every(Number.isFinite))throw new Error(\"repair04 bounds must contain finite coordinates\");if(t.maxX-t.minX\u003c9.99999999||t.maxY-t.minY\u003c9.99999999)throw new Error(\"repair04 requires bounds at least 10 mm by 10 mm\")})(n),!Number.isFinite(o)||o\u003c0||void 0!==i\u0026\u0026(!Number.isFinite(i)||i\u003c0))throw new Error(\"repair04 collar and halo must be finite and nonnegative\");const r=Math.max(t.defaultObstacleMargin??.2,t.minTraceToPadEdgeClearance??0,t.minViaEdgeToPadEdgeClearance??0);let s=Math.max(t.minTraceWidth,t.minViaDiameter??0);for(const t of e){s=Math.max(s,t.traceThickness,t.viaDiameter);for(const e of t.route)s=Math.max(s,e.traceThickness??0)}for(const e of t.traces??[])for(const n of e.route)\"wire\"===n.route_type\u0026\u0026(s=Math.max(s,n.width)),\"via\"===n.route_type\u0026\u0026(s=Math.max(s,n.via_diameter??t.minViaDiameter??.3));if(!Number.isFinite(s)||s\u003c=0)throw new Error(\"repair04 requires finite positive copper widths\");const a=Math.max(o,s+r);if(2*a\u003e=Math.min(n.maxX-n.minX,n.maxY-n.minY))throw new Error(\"repair04 bounds are too small for their required copper safety collar\");const c=z6(n,Math.max(i??a,r+s)),l=z6(n,-a),d=D6(t,e,c),h=((t,e,n)=\u003e{const o=[];for(const i of t){const t=m1(i,n),r=[];let s=[];const a=()=\u003e{s.length\u003e0\u0026\u0026r.push(s),s=[]},c=t=\u003e{x6(s[s.length-1])!==x6(t)\u0026\u0026s.push(structuredClone(t))};for(let n=0;n\u003ct.route.length;n+=1){const o=t.route[n],i=t.route[n-1];if(\"wire\"===o.route_type\u0026\u0026\"wire\"===i?.route_type\u0026\u0026o.layer===i.layer){const t=y6(i,o,e);if(!t){a();continue}const n=O6(i,o,t[0]),r=O6(i,o,t[1]),l=s[s.length-1];\"wire\"===l?.route_type\u0026\u0026(l.layer!==n.layer||Math.hypot(l.x-n.x,l.y-n.y)\u003eg6)\u0026\u0026a(),c(n),c(r),t[1]\u003c.99999999\u0026\u0026a()}else if(\"via\"===o.route_type){if(!f6(o,e)){a();continue}if(\"wire\"!==i?.route_type)throw new Error(\"repair04 normalized preload via has no incoming wire\");c(i),c(o);const r=t.route[n+1];if(\"wire\"!==r?.route_type)throw new Error(\"repair04 normalized preload via has no outgoing wire\");c(r)}else if(\"wire\"===o.route_type)f6(o,e)\u0026\u0026c(o);else if(\"start\"in o\u0026\u0026\"end\"in o){const t=y6(o.start,o.end,e);if(!t){a();continue}const n=t=\u003e({x:o.start.x+(o.end.x-o.start.x)*t,y:o.start.y+(o.end.y-o.start.y)*t});c({...structuredClone(o),start:n(t[0]),end:n(t[1])}),t[1]\u003c.99999999\u0026\u0026a()}}a();for(let t=0;t\u003cr.length;t+=1)o.push({...structuredClone(i),pcb_trace_id:1===r.length?i.pcb_trace_id:`${i.pcb_trace_id}__repair04_fixed_${t}`,route:r[t]})}return o})(t.traces??[],c,t.minTraceWidth),u=[],p=[],m=[];for(let t=0;t\u003ce.length;t+=1){const n=e[t];for(const e of F6(n,c,l,d[t])){const o={...structuredClone(Object.fromEntries(Object.entries(n).filter(([t])=\u003e\"route\"!==t\u0026\u0026\"vias\"!==t\u0026\u0026\"jumpers\"!==t))),connectionName:n.connectionName,traceThickness:n.traceThickness,viaDiameter:n.viaDiameter,route:e.points,vias:n.vias.filter(t=\u003ee.points.some(e=\u003eMath.abs(e.x-t.x)\u003c=g6\u0026\u0026Math.abs(e.y-t.y)\u003c=g6)).map(t=\u003estructuredClone(t)),...void 0!==n.jumpers?{jumpers:n.jumpers.filter(t=\u003evoid 0!==y6(t.start,t.end,c)).map(t=\u003estructuredClone(t))}:{}};u.push(o),p.push(e.locks),m.push({sourceRouteIndex:t,start:e.start,end:e.end,sourceGeometryKey:S6(n,e.start.segmentIndex+e.start.t,e.end.segmentIndex+e.end.t),originalFragment:structuredClone(o)})}}const g=new Set([...u.flatMap(t=\u003e[t.connectionName,...t.rootConnectionName?[t.rootConnectionName]:[]]),...h.map(t=\u003et.connection_name)]),f=t.connections.filter(t=\u003eg.has(t.name)||t.pointsToConnect.some(t=\u003ef6(t,c))).map(t=\u003e({...structuredClone(Object.fromEntries(Object.entries(t).filter(([t])=\u003e\"pointsToConnect\"!==t))),name:t.name,pointsToConnect:t.pointsToConnect.filter(t=\u003ef6(t,c)).map(t=\u003estructuredClone(t))}));for(let e=0;e\u003cu.length;e+=1){const n=u[e];let o=f.find(t=\u003et.name===n.connectionName);o||(o={name:n.connectionName,...n.rootConnectionName?{rootConnectionName:n.rootConnectionName}:{},pointsToConnect:[]},f.push(o));for(const[i,r]of[[\"start\",n.route[0]],[\"end\",n.route[n.route.length-1]]]){if(!r)continue;const n=0===r.z?\"top\":r.z===t.layerCount-1?\"bottom\":`inner${r.z}`;o.pointsToConnect.some(t=\u003eMath.abs(t.x-r.x)\u003c=g6\u0026\u0026Math.abs(t.y-r.y)\u003c=g6\u0026\u0026(\"layer\"in t?t.layer===n:t.layers.includes(n)))||o.pointsToConnect.push({x:r.x,y:r.y,layer:n,pointId:`repair04_${e}_${i}`,...r.pcb_port_id?{pcb_port_id:r.pcb_port_id}:{}})}}const y={...Object.fromEntries(Object.entries(t).filter(([t,e])=\u003e\"sourceCircuitJson\"!==t\u0026\u0026\"sourceKicadPcb\"!==t\u0026\u0026(\"number\"==typeof e||\"boolean\"==typeof e||\"string\"==typeof e))),layerCount:t.layerCount,minTraceWidth:t.minTraceWidth,bounds:structuredClone(c),obstacles:[...t.obstacles.filter(t=\u003e((t,e)=\u003e{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=(Math.abs(t.width*Math.cos(n))+Math.abs(t.height*Math.sin(n)))/2,i=(Math.abs(t.width*Math.sin(n))+Math.abs(t.height*Math.cos(n)))/2;return t.center.x+o\u003e=e.minX\u0026\u0026t.center.x-o\u003c=e.maxX\u0026\u0026t.center.y+i\u003e=e.minY\u0026\u0026t.center.y-i\u003c=e.maxY})(t,c)).map(t=\u003estructuredClone(t)),...B6(t,c)],connections:f,...void 0!==t.traces?{traces:h}:{},...void 0!==t.allowJumpers?{allowJumpers:t.allowJumpers}:{},...t.availableJumperTypes?{availableJumperTypes:structuredClone(t.availableJumperTypes)}:{}};return{srj:y,routes:u,bounds:structuredClone(n),contextBounds:c,mutableBounds:l,boundaryMargin:a,lockedPointIndices:p,routeMappings:m}},$6=t=\u003ex6(Object.fromEntries(Object.entries(t).filter(([t])=\u003e\"route\"!==t\u0026\u0026\"vias\"!==t))),Y6=(t,e)=\u003e{const n=[];for(let o=1;o\u003ct.route.length;o+=1){const i=t.route[o-1],r=t.route[o],s=y6(i,r,e),a=s?[...s[0]\u003eg6?[[0,s[0]]]:[],...s[1]\u003c.99999999?[[s[1],1]]:[]]:[[0,1]];s\u0026\u0026!f6(_6(i,r,.5),e,4e-8)\u0026\u00260===a.length\u0026\u0026a.push([0,1]);for(const[t,e]of a)n.push(x6([_6(i,r,t),_6(i,r,e)]))}return n},X6=(t,e,n,o,i,r)=\u003e{if($6(t)!==$6(e))throw new Error(\"repair04 merge rejected changed net, width, jumper, or route metadata\");if(n.length!==t.route.length)throw new Error(\"repair04 merge received an invalid lock mask\");if(0===e.route.length)throw new Error(\"repair04 merge rejected an empty replacement route\");if(x6(t.route[0])!==x6(e.route[0])||x6(t.route[t.route.length-1])!==x6(e.route[e.route.length-1]))throw new Error(\"repair04 merge rejected a moved fragment endpoint\");let s=0;for(let o=0;o\u003ct.route.length;o+=1){if(!n[o])continue;const i=x6(t.route[o]);for(;s\u003ce.route.length\u0026\u0026x6(e.route[s])!==i;)s+=1;if(s===e.route.length)throw new Error(\"repair04 merge rejected a moved or removed locked point\");s+=1}if(x6(Y6(t,o))!==x6(Y6(e,o)))throw new Error(\"repair04 merge rejected modified geometry in the fixed boundary collar\");for(let n=1;n\u003ct.route.length;n+=1){const o=t.route[n-1],i=t.route[n];if(!(\"through_obstacle\"===o.toNextSegmentType||!0===o.insideJumperPad||!0===i.insideJumperPad||(t.jumpers??[]).some(t=\u003eb6(o,{...t.start,z:o.z})\u0026\u0026b6(i,{...t.end,z:i.z})||b6(o,{...t.end,z:o.z})\u0026\u0026b6(i,{...t.start,z:i.z}))))continue;const r=x6([o,i]);if(!e.route.some((t,n)=\u003en+1\u003ce.route.length\u0026\u0026x6([t,e.route[n+1]])===r))throw new Error(\"repair04 merge rejected a changed atomic jumper or through-obstacle span\")}for(const n of e.route){if(![n.x,n.y,n.z].every(Number.isFinite)||!Number.isInteger(n.z)||n.z\u003c0||n.z\u003e=r||!f6(n,i))throw new Error(\"repair04 merge rejected invalid or out-of-region geometry\");if((void 0!==n.pcb_port_id||!0===n.insideJumperPad||void 0!==n.toNextSegmentCircuitJsonMetadata)\u0026\u0026!t.route.some(t=\u003ex6(t)===x6(n)))throw new Error(\"repair04 merge rejected invented or moved terminal/circuit metadata\");if(void 0!==n.traceThickness\u0026\u0026(!Number.isFinite(n.traceThickness)||n.traceThickness\u003c=0||n.traceThickness\u003eMath.max(t.traceThickness,...t.route.map(t=\u003et.traceThickness??0))+g6))throw new Error(\"repair04 merge rejected increased per-point copper width\")}for(let n=1;n\u003ce.route.length;n+=1){const o=e.route[n-1],i=e.route[n];if(\"through_obstacle\"===o.toNextSegmentType\u0026\u0026!t.route.some((e,n)=\u003en+1\u003ct.route.length\u0026\u0026x6([e,t.route[n+1]])===x6([o,i])))throw new Error(\"repair04 merge rejected an invented through-obstacle span\");if(o.z!==i.z\u0026\u0026\"through_obstacle\"!==o.toNextSegmentType\u0026\u0026(Math.abs(o.x-i.x)\u003eg6||Math.abs(o.y-i.y)\u003eg6||!e.vias.some(t=\u003eMath.abs(t.x-o.x)\u003c=g6\u0026\u0026Math.abs(t.y-o.y)\u003c=g6)))throw new Error(\"repair04 merge rejected a disconnected or missing via\")}for(const n of e.vias){if(!(Number.isFinite(n.x)\u0026\u0026Number.isFinite(n.y)\u0026\u0026f6(n,i)\u0026\u0026e.route.some(t=\u003eMath.abs(t.x-n.x)\u003c=g6\u0026\u0026Math.abs(t.y-n.y)\u003c=g6)))throw new Error(\"repair04 merge rejected an invalid via position\");if(!f6(n,o,4e-8)\u0026\u0026!t.vias.some(t=\u003ex6(t)===x6(n)))throw new Error(\"repair04 merge rejected a new via in the boundary collar\")}for(const n of t.vias)if(!f6(n,o,4e-8)\u0026\u0026!e.vias.some(t=\u003ex6(t)===x6(n)))throw new Error(\"repair04 merge rejected a changed via in the boundary collar\")},V6=(t,e)=\u003e{for(const n of e){const e=t[t.length-1];e\u0026\u0026b6(e,n)\u0026\u0026x6(e)===x6(n)||t.push(structuredClone(n))}},W6=(t,e,n)=\u003e{const o=new Set(e.route.map(x6)),i=new Set(n.flatMap(t=\u003et.originalFragment.route.map(x6)).filter(t=\u003e!o.has(t))),r=[];for(const e of t)for(r.push(e);r.length\u003e=3;){const t=r[r.length-3],e=r[r.length-2],n=r[r.length-1];if(!i.has(x6(e)))break;if(t.z!==e.z||e.z!==n.z\u0026\u0026\"through_obstacle\"!==t.toNextSegmentType)break;if(t.toNextSegmentType!==e.toNextSegmentType||t.insideJumperPad!==e.insideJumperPad||t.traceThickness!==e.traceThickness||x6(t.toNextSegmentCircuitJsonMetadata)!==x6(e.toNextSegmentCircuitJsonMetadata))break;const o=n.x-t.x,s=n.y-t.y,a=o*o+s*s;if(a\u003c=10000000000000001e-32)break;const c=(e.x-t.x)*s-(e.y-t.y)*o,l=((e.x-t.x)*o+(e.y-t.y)*s)/a;if(Math.abs(c)\u003eg6*Math.sqrt(a)||l\u003c0||l\u003e1)break;r.splice(r.length-2,1)}return r},H6=t=\u003e{if(!Number.isInteger(t.segmentIndex)||t.segmentIndex\u003c0||!Number.isFinite(t.t)||t.t\u003c0||t.t\u003e1)throw new Error(\"repair04 merge received invalid fragment provenance\");return t.segmentIndex+t.t},G6=({routes:t,region:e,repairedRoutes:n})=\u003e{if(n.length!==e.routeMappings.length||e.lockedPointIndices.length!==n.length)throw new Error(\"repair04 merge requires exactly one replacement for every extracted fragment\");const o=new Map;for(let i=0;i\u003cn.length;i+=1){const r=e.routeMappings[i],s=n[i];if(!t[r.sourceRouteIndex])throw new Error(\"repair04 merge source route no longer exists\");if(X6(r.originalFragment,s,e.lockedPointIndices[i],e.mutableBounds,e.contextBounds,e.srj.layerCount),x6(r.originalFragment)===x6(s))continue;const a=o.get(r.sourceRouteIndex)??[];a.push({mapping:r,repaired:s}),o.set(r.sourceRouteIndex,a)}return t.map((t,e)=\u003e{const n=o.get(e);if(!n)return t;n.sort((t,e)=\u003eH6(t.mapping.start)-H6(e.mapping.start));const i=[];let r=0;for(const{mapping:e,repaired:o}of n){const n=H6(e.start),s=H6(e.end);if(n\u003cr-g6||s\u003cn||s\u003et.route.length-1+g6)throw new Error(\"repair04 merge received overlapping or stale fragment provenance\");if(S6(t,n,s)!==e.sourceGeometryKey)throw new Error(\"repair04 merge rejected stale source geometry\");V6(i,v6(t,r,n)),V6(i,o.route),r=s}V6(i,v6(t,r,t.route.length-1));const s=new Set(n.flatMap(({mapping:t})=\u003et.originalFragment.vias.map(t=\u003e`${t.x},${t.y}`))),a=t.vias.filter(t=\u003e!s.has(`${t.x},${t.y}`)).map(t=\u003estructuredClone(t));for(const{repaired:t}of n)for(const e of t.vias)a.some(t=\u003eMath.abs(t.x-e.x)\u003c=g6\u0026\u0026Math.abs(t.y-e.y)\u003c=g6)||a.push(structuredClone(e));return{...t,route:W6(i,t,n.map(({mapping:t})=\u003et)),vias:a}})},U6=12e4,Z6=[10,16],q6=[3,4,5,6,8],J6=(t,e)=\u003e{const n=\"string\"==typeof t.pcb_pad_id?t.pcb_pad_id:\"string\"==typeof t.pcb_trace_error_id?t.pcb_trace_error_id.match(/(pcb_(?:smtpad|plated_hole|hole|keepout)_\\d+)$/)?.[1]:void 0;if(n){const t=e.obstacles.find(t=\u003et.obstacleId===n||t.connectedTo[0]===n);if(t)return t.center}return(t=\u003e{const e=t.center;return e\u0026\u0026\"object\"==typeof e\u0026\u0026\"x\"in e\u0026\u0026\"y\"in e\u0026\u0026\"number\"==typeof e.x\u0026\u0026\"number\"==typeof e.y?{x:e.x,y:e.y}:void 0})(t)},K6=({error:t,routeIndexByTraceId:e})=\u003e{const n=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,o=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]],i=n?`overlap_${n}_`:void 0,r=i\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0,s=void 0!==r\u0026\u0026o.includes(r);return[n,...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids:[],s?void 0:r].filter(t=\u003e\"string\"==typeof t\u0026\u0026e.has(t)).filter((t,e,n)=\u003en.indexOf(t)===e)},Q6=t=\u003et.filter(t=\u003e\"pcb_via_clearance_error\"===t.type||Array.isArray(t.pcb_via_ids)).length,t9=(t,e)=\u003e{const n=new Map;for(const e of t)n.set(e.connectionName,(n.get(e.connectionName)??0)+1);return t.map((t,o)=\u003e{const i=n.get(t.connectionName)\u003e1?`${t.connectionName}_regional_${o}`:t.connectionName;return i!==t.connectionName\u0026\u0026e.addConnections([[i,t.connectionName,t.rootConnectionName??t.connectionName]]),{...t,connectionName:i,preloadedTraceId:`pipeline9_joint_candidate_${o}`,preloadedTraceIndex:o,preloadedRouteIndex:0,isThroughObstacle:!1}})},e9=(t,e)=\u003et.minX\u003c=e.maxX\u0026\u0026t.maxX\u003e=e.minX\u0026\u0026t.minY\u003c=e.maxY\u0026\u0026t.maxY\u003e=e.minY,n9=t=\u003e({minX:t.center.x-t.diameter/2,maxX:t.center.x+t.diameter/2,minY:t.center.y-t.diameter/2,maxY:t.center.y+t.diameter/2}),o9=t=\u003e({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}),i9=(t,e)=\u003e{const n=EQ(t);return n.wireSegments.some(t=\u003ee9((t=\u003e({minX:Math.min(t.start.x,t.end.x)-t.width/2,maxX:Math.max(t.start.x,t.end.x)+t.width/2,minY:Math.min(t.start.y,t.end.y)-t.width/2,maxY:Math.max(t.start.y,t.end.y)+t.width/2}))(t),e))||n.viaSpans.some(t=\u003ee9(n9(t),e))},r9=({routes:t,fixedObstacleRoutes:e,routeIndex:n,center:o,regionSize:i,srj:r,connMap:s,colorMap:a,viaDiameter:c,traceWidth:l,obstacleMargin:d,effort:h})=\u003e{const u=t9(t,s),p=u[n];if(!p)return;const m={capacityMeshNodeId:`pipeline9_joint_drc_${n}_${i}`,center:o,width:i,height:i,availableZ:Array.from({length:r.layerCount},(t,e)=\u003ee),portPoints:[],portPointsInPairs:[]},g=$K(m,[p]),f=g.fixedRouteSectionsByConnectionName.get(p.connectionName);if(!f)return;const y=u.filter((t,e)=\u003ee!==n),_=new VQ({nodePortPoints:[g.nodeWithPortPoints],fixedHdRoutes:[...y,...e].map(t=\u003e({...t,rootConnectionName:s.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName})),connMap:s,colorMap:a,obstacles:r.obstacles,layerCount:r.layerCount,viaDiameter:c,traceWidth:l,obstacleMargin:d,effort:h,preserveTerminalPcbPortIds:!0,includeBoardObstacles:!0,enableRegionalFallback:!1,maxB01Rips:120});if(_.solve(),!_.solved||_.failed)return;const b=_.routes.find(t=\u003et.connectionName===p.connectionName);return b?{routes:t.map((t,e)=\u003ee===n?{...XK(f,b),connectionName:t.connectionName}:t),usedFallback:Number(_.stats.fallbackNodeCount??0)\u003e0}:void 0},s9=({routes:t,fixedRouteCopperSpatialIndex:e,center:n,regionSize:o,srj:i,connMap:r,colorMap:s,viaDiameter:a,traceWidth:c,obstacleMargin:l,effort:d})=\u003e{const h=t9(t,r),u={capacityMeshNodeId:\"pipeline9_joint_drc_regular_fallback\",center:n,width:o,height:o,availableZ:Array.from({length:i.layerCount},(t,e)=\u003ee),portPoints:[],portPointsInPairs:[]},p=$K(u,h);if(0===p.fixedRouteSectionsByConnectionName.size)return;if(!(t=\u003e{const e=kK(t);return t.portPoints.every(t=\u003e\"on-boundary\"===rs({point:t,bounds:e}))})(p.nodeWithPortPoints))return;const m=[...p.fixedRouteSectionsByConnectionName.values()].flatMap(t=\u003et.sourceRoutes).reduce((t,e)=\u003e{const n=EQ(e);return Math.max(t,e.viaDiameter/2,...n.wireSegments.map(t=\u003et.width/2),...n.viaSpans.map(t=\u003et.diameter/2))},Math.max(c/2,a/2)),g={minX:n.x-o/2-l-m,maxX:n.x+o/2+l+m,minY:n.y-o/2-l-m,maxY:n.y+o/2+l+m},f=e.getRoutesOverlappingBounds(g),y=OQ({fixedObstacleRoutes:f,layerCount:i.layerCount}),_=new FQ({nodeWithPortPoints:p.nodeWithPortPoints,colorMap:s,connMap:r,viaDiameter:a,traceWidth:c,obstacleMargin:l,effort:d,obstacles:[...i.obstacles,...y],layerCount:i.layerCount});if(_.solve(),!_.solved||_.failed)return;const b=_.getOutput(),x=new Map(b.map(t=\u003e[t.connectionName,t])),v=new Map,S=new Set;for(const[t,e]of p.fixedRouteSectionsByConnectionName){const n=x.get(t);if(!n)return;v.set(e.sourceRoutes[0].preloadedTraceIndex,XK(e,n));for(const t of e.sourceRoutes.slice(1))S.add(t.preloadedTraceIndex)}const I=h.flatMap((e,n)=\u003eS.has(n)?[]:[{...v.get(n)??e,connectionName:t[n].connectionName}]);return(({candidateRoutes:t,fixedObstacleRoutes:e,obstacleMargin:n,connMap:o,candidateBounds:i})=\u003e{for(const r of t)for(const t of e)if(!kQ(r,t,o)\u0026\u0026DQ({left:r,right:t,clearance:n,leftBounds:i}))return!0;return!1})({candidateRoutes:I,fixedObstacleRoutes:f,obstacleMargin:l,connMap:r,candidateBounds:g})?void 0:I},a9=({srj:t,routes:e,fixedObstacleRoutes:n,newConnections:o,syntheticConnectionNames:i,drcEvaluator:r,initialErrors:s,allowTracePairRepair:a=!1,preloadRepairTraceIds:c,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m})=\u003e{let g=e,f=s??r1(r,g),y=0,_=0,b=0,x=0,v=!1;const S=(t=\u003e{if(!Number.isInteger(t)||t\u003c0)throw new Error(\"Pipeline9 regional repair route count must be nonnegative\");const e=Math.floor(7e3/Math.max(1,t));return Math.max(16,Math.min(192,e))})(e.length),I=f.filter(t=\u003e(({error:t,preloadRepairTraceIds:e})=\u003e!!s1(t).some(t=\u003ee.has(t))||(t.__collapsed_trace_participants??[]).flatMap(t=\u003enew Set(t.evaluationTraceIds).size\u003e1?[t.solverTraceId]:[]).some(t=\u003ee.collidingFixedTraceIds?.has(t)))({error:t,preloadRepairTraceIds:c})).length,C=d1({routes:g,newConnections:o,syntheticConnectionNames:i}),P=a\u0026\u0026f.some(t=\u003e((t,e)=\u003e!(\"pcb_trace_error\"!==t.type||\"string\"==typeof t.pcb_via_id||Array.isArray(t.pcb_via_ids)\u0026\u0026t.pcb_via_ids.length\u003e0)\u0026\u00262===K6({error:t,routeIndexByTraceId:e}).length)(t,C));if(0===I\u0026\u0026!P)return{routes:g,attemptedCandidateCount:y,acceptedCandidateCount:_,fallbackCandidateCount:b,candidateSearchCount:x,candidateSearchBudget:S,candidateSearchBudgetExhausted:v,safeTraceLayerRepairSkippedForBudget:!1,remainingDrcIssueCount:f.length,preloadEligibleDrcIssueCount:I,preloadRepairAttempted:!1};const M=(t=\u003e{const e=new Map,n=(t,n)=\u003e{const o=Math.floor(n.minX/4),i=Math.floor(n.maxX/4),r=Math.floor(n.minY/4),s=Math.floor(n.maxY/4);for(let n=o;n\u003c=i;n++)for(let o=r;o\u003c=s;o++){const i=`${n}:${o}`,r=e.get(i)??new Set;r.add(t),e.set(i,r)}};for(let e=0;e\u003ct.length;e++){const o=EQ(t[e]);for(const t of o.wireSegments)for(const o of AQ(t,4,1))n(e,o9(o));for(const t of o.viaSpans)n(e,n9(t))}return{getRoutesOverlappingBounds:n=\u003e{const o=new Set,i=Math.floor(n.minX/4),r=Math.floor(n.maxX/4),s=Math.floor(n.minY/4),a=Math.floor(n.maxY/4);for(let t=i;t\u003c=r;t++)for(let n=s;n\u003c=a;n++)for(const i of e.get(`${t}:${n}`)??[])o.add(i);return[...o].sort((t,e)=\u003et-e).map(e=\u003et[e]).filter(t=\u003ei9(t,n))}}})(n);for(let e=0;e\u003c2\u0026\u0026!v;e++){let e=!1;const s=d1({routes:g,newConnections:o,syntheticConnectionNames:i}),a=f.filter(t=\u003e(\"pcb_trace_error\"===t.type||\"pcb_pad_trace_clearance_error\"===t.type||\"pcb_via_trace_clearance_error\"===t.type||\"pcb_via_clearance_error\"===t.type)\u0026\u0026\"string\"==typeof t.pcb_trace_id);for(const o of a){if(v)break;const i=J6(o,t),a=K6({error:o,routeIndexByTraceId:s});if(!i)continue;let c=g,I=f;for(const e of a.slice(0,2)){if(v)break;const o=s.get(e);if(void 0!==o){for(const e of q6){if(x\u003e=S){v=!0;break}x++;const s=r9({routes:g,fixedObstacleRoutes:n,routeIndex:o,center:i,regionSize:e,srj:t,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m});if(!s)continue;y++,s.usedFallback\u0026\u0026b++;const a=r1(r,s.routes);if(l1(a,I)\u0026\u0026(c=s.routes,I=a),0===I.length)break}if(0===I.length)break}}if(c!==g||v||(x\u003e=S?v=!0:x++),c===g\u0026\u0026!v){const e=s9({routes:g,fixedRouteCopperSpatialIndex:M,center:i,regionSize:3,srj:t,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m});if(e){y++,b++;const t=r1(r,e);l1(t,I)\u0026\u0026(c=e,I=t)}}if(c!==g\u0026\u0026(g=c,f=I,_++,e=!0),v)break}if(!e||0===f.length)break}if(_\u003e0\u0026\u0026f.length\u003e0){const e=iD({...t,traces:void 0},g,m,1,l);if(e!==g){const t=r1(r,e);Q6(t)\u003c=Q6(f)\u0026\u0026l1(t,f)\u0026\u0026(g=e,f=t)}}const N=f.some(t=\u003e\"pcb_trace_error\"===t.type||\"pcb_pad_trace_clearance_error\"===t.type),w=N\u0026\u0026v;if(N\u0026\u0026!v){const e=new Nz({srj:{...t,traces:void 0},hdRoutes:g,connMap:l,effort:m,drcEvaluator:r,maxIterations:8,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1});if(e.solve(),e.failed)throw new Error(`Pipeline9 post-regional safe trace-layer repair failed: ${e.error??\"unknown error\"}`);const n=e.getOutput(),o=r1(r,n);l1(o,f)\u0026\u0026(g=n,f=o)}return{routes:g,attemptedCandidateCount:y,acceptedCandidateCount:_,fallbackCandidateCount:b,candidateSearchCount:x,candidateSearchBudget:S,candidateSearchBudgetExhausted:v,safeTraceLayerRepairSkippedForBudget:w,remainingDrcIssueCount:f.length,preloadEligibleDrcIssueCount:I,preloadRepairAttempted:I\u003e0}},c9=[.9,.72],l9=Array.from({length:16},(t,e)=\u003ee*Math.PI/8),d9=t=\u003e\"pcb_pad_trace_clearance_error\"===t.type||\"pcb_trace_error\"===t.type\u0026\u0026!(Array.isArray(t.pcb_trace_ids)\u0026\u0026t.pcb_trace_ids.length\u003e=2),h9=t=\u003e{if(\"string\"==typeof t.pcb_pad_id)return t.pcb_pad_id;if(\"string\"==typeof t.pcb_trace_error_id){const e=t.pcb_trace_error_id.match(/(pcb_(?:smtpad|plated_hole|hole|keepout)_\\d+)$/)?.[1];if(e)return e}const e=\"string\"==typeof t.message?t.message:\"\";return e.match(/(?:pcb_smtpad|pcb_plated_hole|pcb_hole|pcb_keepout)\\[#?([^\\]\"]+)\\]/)?.[1]},u9=(t,e)=\u003e{if(!e)return;const n=e.startsWith(\"pcb_\")?e:`pcb_${e}`;return t.obstacles.find(t=\u003et.obstacleId===n||t.connectedTo[0]===n)},p9=({srj:t,pcbPortId:e,z:n,portPositionMap:o})=\u003e{const i=vo(n,t.layerCount),r=o.get(e),s=t.obstacles.filter(t=\u003et.layers.includes(i)\u0026\u0026t.connectedTo.includes(e));return r?s.reduce((t,e)=\u003et?Math.hypot(e.center.x-r.x,e.center.y-r.y)\u003cMath.hypot(t.center.x-r.x,t.center.y-r.y)?e:t:e,void 0):s[0]},m9=({terminalObstacle:t,conflictingObstacle:e,traceRadius:n})=\u003e{const o=Math.max(0,t.width/2-n),i=Math.max(0,t.height/2-n),r=(t.ccwRotationDegrees??0)*Math.PI/180;return c9.flatMap(e=\u003el9.map(n=\u003e{const s={x:Math.cos(n)*o*e,y:Math.sin(n)*i*e},a=(l=r,{x:(c=s).x*Math.cos(l)-c.y*Math.sin(l),y:c.x*Math.sin(l)+c.y*Math.cos(l)});var c,l;return{x:t.center.x+a.x,y:t.center.y+a.y}})).sort((t,n)=\u003eMath.hypot(n.x-e.center.x,n.y-e.center.y)-Math.hypot(t.x-e.center.x,t.y-e.center.y)).slice(0,16)},g9=({routes:t,routeIndex:e,endpointIndex:n,point:o,bounds:i,collapseAdjacent:r})=\u003e{const s=(t=\u003et.map(t=\u003e({...t,route:t.route.map(t=\u003e({...t})),vias:t.vias.map(t=\u003e({...t}))})))(t),a=s[e];if(!a||a.route.length\u003c2)return;const c=0===n?0:a.route.length-1,l=0===n?1:c-1,d=a.route[c],h=a.route[l];if(!d||!h||d.z!==h.z)return;const u=a.traceThickness/2;if(!(o.x-u\u003ci.minX||o.x+u\u003ei.maxX||o.y-u\u003ci.minY||o.y+u\u003ei.maxY)){if(a.route[c]={...d,...o},r){const t=0===n?l+1:l-1,e=a.route[t],i=a.vias.some(t=\u003et.x===h.x\u0026\u0026t.y===h.y);if(!e||e.z!==d.z||void 0!==h.pcb_port_id||i)return;a.route[l]={...h,...o}}return s}},f9=({srj:t,originalSrj:e,routes:n,newConnections:o,syntheticConnectionNames:i,drcEvaluator:r})=\u003e{let s=n,a=r1(r,s),c=0,l=0;const d=(t=\u003e{const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,t);return e})(e);for(let n=0;n\u003c2;n++){let n=!1;const h=d1({routes:s,newConnections:o,syntheticConnectionNames:i});for(const o of a.filter(d9)){if(c\u003e=256)break;if(\"string\"!=typeof o.pcb_trace_id)continue;const i=h.get(o.pcb_trace_id),u=u9(t,h9(o));if(void 0===i||!u)continue;const p=s[i];let m=s,g=a;t:for(const n of[0,-1]){const o=0===n?p.route[0]:p.route.at(-1);if(!o||\"string\"!=typeof o.pcb_port_id)continue;const a=p9({srj:e,pcbPortId:o.pcb_port_id,z:o.z,portPositionMap:d});if(!a||a===u)continue;const l=Math.hypot(u.width,u.height)/2+Math.hypot(a.width,a.height)/2+.5;if(!(Math.hypot(o.x-u.center.x,o.y-u.center.y)\u003el))for(const e of m9({terminalObstacle:a,conflictingObstacle:u,traceRadius:p.traceThickness/2}))for(const o of[!1,!0]){if(c\u003e=256)break t;const a=g9({routes:s,routeIndex:i,endpointIndex:n,point:e,bounds:t.bounds,collapseAdjacent:o});if(!a)continue;c++;const l=r1(r,a);l1(l,g)\u0026\u0026(m=a,g=l)}}m!==s\u0026\u0026(s=m,a=g,l++,n=!0)}if(!n||0===a.length)break}return{routes:s,attemptedCandidateCount:c,acceptedCandidateCount:l,remainingErrors:a}},y9=[\"pcb_trace_error_id\",\"pcb_error_id\",\"pcb_via_trace_clearance_error_id\",\"pcb_pad_trace_clearance_error_id\"],_9=(t,e)=\u003e{let n=t;const o=[...e].sort(([t],[e])=\u003ee.length-t.length);for(const[t,e]of o)n=n.replaceAll(t,e);return n},b9=(t,e)=\u003e{const n=String(t.type??t.error_type??\"unknown\");if(\"pcb_via_clearance_error\"===n)return((t,e)=\u003e{const n=[...\"string\"==typeof t.pcb_trace_id?[t.pcb_trace_id]:[],...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[]].map(t=\u003e_9(t,e)).filter((t,e,n)=\u003en.indexOf(t)===e).sort(),o=t.center\u0026\u0026\"object\"==typeof t.center?t.center:t.pcb_center\u0026\u0026\"object\"==typeof t.pcb_center?t.pcb_center:void 0,i=\"number\"==typeof o?.x\u0026\u0026\"number\"==typeof o.y?{x:o.x,y:o.y}:void 0,r=\"string\"==typeof t.pcb_via_pair_net_relation?t.pcb_via_pair_net_relation:void 0;if(0!==n.length\u0026\u0026i\u0026\u0026r)return`pcb_via_clearance_error:${JSON.stringify({traceIds:n,center:i,netRelation:r})}`})(t,e);for(const o of y9){const i=t[o];if(\"string\"==typeof i)return`${n}:${_9(i,e)}`}const o=Object.fromEntries(Object.entries(t).filter(([t,e])=\u003e(t.endsWith(\"_id\")||t.endsWith(\"_ids\"))\u0026\u0026(\"string\"==typeof e||Array.isArray(e))).sort(([t],[e])=\u003et.localeCompare(e)).map(([t,n])=\u003e[t,\"string\"==typeof n?_9(n,e):n]));return`${n}:${JSON.stringify(o)}`},x9=({errors:t,baselineErrors:e,originalTraceIdByPreparedTraceId:n=new Map})=\u003e{const o=new Set(e.filter(t=\u003e!(t=\u003e\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(\"missing_connection_\"))(t)).map(t=\u003eb9(t,new Map)));return o.delete(void 0),t.filter(t=\u003e{const e=b9(t,n);return void 0===e||!o.has(e)})},v9=1.5,S9=({errorsWithCenters:t,traces:e,layerCount:n,defaultViaDiameter:o,connMap:i})=\u003e{const r=(t=\u003et.flatMap(t=\u003e{if(\"pcb_trace_error\"!==t.type||!Array.isArray(t.pcb_port_ids)||t.pcb_port_ids.length\u003c4)return[];const e=t.center;return e\u0026\u0026\"object\"==typeof e\u0026\u0026\"x\"in e\u0026\u0026\"y\"in e\u0026\u0026\"number\"==typeof e.x\u0026\u0026\"number\"==typeof e.y?[{x:e.x,y:e.y}]:[]}))(t),s=new Set;for(let t=0;t\u003ce.length;t++){const a=e[t],c=oQ(a,t,n,o,i);r.some(t=\u003ec.some(e=\u003e{const n=e.route.map(t=\u003et.x),o=e.route.map(t=\u003et.y);return Math.min(...n)\u003c=t.x+v9\u0026\u0026Math.max(...n)\u003e=t.x-v9\u0026\u0026Math.min(...o)\u003c=t.y+v9\u0026\u0026Math.max(...o)\u003e=t.y-v9}))\u0026\u0026s.add(a.pcb_trace_id)}return s},I9=({routes:t,otherHdRoutes:e,obstacles:n,colorMap:o,layerCount:i,connMap:r})=\u003e{const s=IK([...t,...e],r),a=new tc({inputHdRoutes:t,otherHdRoutes:e,netByConnectionName:s,obstacles:n,colorMap:o,layerCount:i,connMap:r});if(a.solve(),a.failed)throw new Error(`Pipeline9 could not merge movable preloaded vias: ${a.error??\"unknown error\"}`);return a.getMergedViaHdRoutes()??t},C9=({errors:t,circuitJson:e,newTraceIds:n})=\u003e{const o=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.map(t=\u003e{const e=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,i=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],r=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]].filter((t,e,n)=\u003en.indexOf(t)===e);if(e\u0026\u0026\"string\"==typeof t.pcb_trace_error_id){const s=`overlap_${e}_`,a=t.pcb_trace_error_id.startsWith(s)?t.pcb_trace_error_id.slice(s.length):void 0,c=void 0!==a\u0026\u0026(r.includes(a)||o.has(a)\u0026\u0026!i.includes(a)),l=i.find(t=\u003et!==e\u0026\u0026n.has(t))??(a\u0026\u0026!c?a:void 0);if(!n.has(e)\u0026\u00260===r.length\u0026\u0026l\u0026\u0026n.has(l)){const n=[l,e,...i].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,pcb_trace_id:l,pcb_trace_ids:n,pcb_trace_error_id:`overlap_${l}_${e}`}}}const s=r.flatMap(t=\u003e{const e=o.get(t);return e?[e]:[]}).filter((t,e,n)=\u003en.indexOf(t)===e),a=s.length\u003e0?s:i.filter(t=\u003et!==e),c=a.find(t=\u003en.has(t));if(c\u0026\u0026(!e||!n.has(e))){const n=[c,...e?[e]:[],...i,...a].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,pcb_trace_id:c,pcb_trace_ids:n,pcb_via_id:r[0],pcb_via_ids:r}}if(r.length\u003e0){const n=[...e?[e]:[],...i,...a].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,pcb_trace_ids:n,pcb_via_id:r[0],pcb_via_ids:r}}return t})},P9=1e-9,M9=t=\u003e{const e=new Set,n=[];for(const o of t)for(const t of o.route){if(\"via\"!==t.route_type)continue;const i=`${t.x},${t.y},${t.from_layer},${t.to_layer}`;e.has(i)||(e.add(i),n.push({type:\"pcb_via\",pcb_via_id:`via_${n.length}`,pcb_trace_id:o.pcb_trace_id}))}return n},N9=({errors:t,circuitJson:e,evaluatedTraceIds:n})=\u003e{const o=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.map(t=\u003e{const e=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]],i=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,r=i?`overlap_${i}_`:void 0,s=r\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(r)?t.pcb_trace_error_id.slice(r.length):void 0,a=\"string\"==typeof t.pcb_trace_error_id?t.pcb_trace_error_id.match(/_(via_\\d+)$/)?.[1]:void 0,c=0!==e.length||!a||!o.has(a)||s\u0026\u0026n.has(s)?void 0:a,l=[...e,...c?[c]:[]].filter((t,e,n)=\u003en.indexOf(t)===e),d=[...\"string\"==typeof t.pcb_trace_id?[t.pcb_trace_id]:[],...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],...l.flatMap(t=\u003e{const e=o.get(t);return e?[e]:[]})].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,...l.length\u003e0?{pcb_via_id:l[0],pcb_via_ids:l}:{},...l.length\u003e0\u0026\u0026d.length\u003e0?{pcb_trace_ids:d}:{}}})},w9=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=P9\u0026\u0026Math.abs(t.y-e.y)\u003c=P9\u0026\u0026t.z===e.z,T9=({trace:t,sectionGroup:e,syntheticConnectionName:n,connMap:o})=\u003e{const i=e.routes;if(0===i.length)throw new Error(`Pipeline9 cannot exactly repair empty preloaded section for trace \"${t.pcb_trace_id}\"`);const r=[];for(const e of i){if(0===r.length){r.push(...e.route);continue}const n=r.at(-1);if(e.route[0]\u0026\u0026w9(n,e.route[0]))r.push(...e.route.slice(1));else{if(!e.route.at(-1)||!w9(n,e.route.at(-1)))throw new Error(`Pipeline9 cannot reconnect preloaded trace \"${t.pcb_trace_id}\" for exact repair`);r.push(...e.route.slice(0,-1).reverse())}}const s=0===e.routePositionStart,a=e.routePositionEnd===t.route.length-1,c=s?t.connectsTo?.[0]:null,l=a?t.connectsTo?.at(-1):null;return c\u0026\u0026r[0]\u0026\u0026(r[0]={...r[0],pcb_port_id:c}),l\u0026\u0026r.at(-1)\u0026\u0026(r[r.length-1]={...r.at(-1),pcb_port_id:l}),{connectionName:n,rootConnectionName:o.getNetConnectedToId(t.connection_name)??t.connection_name,traceThickness:Math.max(...i.map(t=\u003et.traceThickness)),viaDiameter:Math.max(...i.map(t=\u003et.viaDiameter)),route:r,vias:r.slice(0,-1).flatMap((t,e)=\u003e{const n=r[e+1];return t.z!==n.z\u0026\u0026(o=t,i=n,Math.abs(o.x-i.x)\u003c=P9\u0026\u0026Math.abs(o.y-i.y)\u003c=P9)?[{x:n.x,y:n.y}]:[];var o,i})}},R9=({trace:t,traceIndex:e,layerCount:n,defaultViaDiameter:o,connMap:i})=\u003e{const r=t.route.flatMap((t,e)=\u003e\"through_obstacle\"===t.route_type?[e]:[]),s=new Map,a=oQ(t,e,n,o,i);for(const e of a){const n=e.preloadedRoutePositionStart,o=e.preloadedRoutePositionEnd;if(void 0===n||void 0===o)throw new Error(`Pipeline9 preloaded trace section is missing route positions for \"${t.pcb_trace_id}\"`);if(\"through_obstacle\"===t.route[n]?.route_type)continue;const i=r.filter(t=\u003et\u003cn).length,a=s.get(i)??{routePositionStart:n,routePositionEnd:o,routes:[]};a.routePositionStart=Math.min(a.routePositionStart,n),a.routePositionEnd=Math.max(a.routePositionEnd,o),a.routes.push(e),s.set(i,a)}return[...s.values()]},E9=(t,e)=\u003et.map(t=\u003e{const n=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],o=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,i=o?`overlap_${o}_`:void 0,r=i\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0,s=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]],a=void 0!==r\u0026\u0026s.includes(r),c=[o,...n,a?void 0:r].filter(t=\u003e\"string\"==typeof t),l=new Map;for(const t of c){const n=e.get(t)??t,o=l.get(n)??new Set;o.add(t),l.set(n,o)}const d=[...l].flatMap(([t,e])=\u003ee.size\u003e1?[{solverTraceId:t,evaluationTraceIds:[...e]}]:[]),h=o?e.get(o)??o:void 0,u=n.map(t=\u003ee.get(t)??t),p=r?a?r:e.get(r)??r:void 0;return h!==o||u.some((t,e)=\u003et!==n[e])||p!==r?{...t,...o?{pcb_trace_id:h}:{},...Array.isArray(t.pcb_trace_ids)?{pcb_trace_ids:u}:{},...h\u0026\u0026p?{pcb_trace_error_id:`overlap_${h}_${p}`}:{},...d.length\u003e0?{__collapsed_trace_participants:d}:{}}:t}),A9=(t,e)=\u003e{const n=t.hdRoute.route[0],o=t.hdRoute.route.at(-1);return{name:t.syntheticConnectionName,rootConnectionName:t.hdRoute.rootConnectionName,__netConnectionName:t.originalTrace.connection_name,nominalTraceWidth:t.hdRoute.traceThickness,pointsToConnect:[{x:n.x,y:n.y,layer:vo(n.z,e),pointId:`${t.syntheticConnectionName}:start`},{x:o.x,y:o.y,layer:vo(o.z,e),pointId:`${t.syntheticConnectionName}:end`}]}},O9=({originalTrace:t,repairedSections:e})=\u003e{const n=[];let o=0;for(const i of[...e].sort((t,e)=\u003et.routePositionStart-e.routePositionStart)){if(i.routePositionStart\u003co)throw new Error(`Pipeline9 found overlapping repaired sections for preloaded trace \"${t.pcb_trace_id}\"`);n.push(...t.route.slice(o,i.routePositionStart),...i.route),o=i.routePositionEnd+1}return n.push(...t.route.slice(o)),{...t,__replaces_pcb_trace_id:t.pcb_trace_id,route:n}},k9=class extends si{params;inputNewHdRoutes;inputUpdatedPreloadedTraces;movablePreloadedSections;fixedPreloadedObstacleRoutes;syntheticConnectionNames;exactRepairSolver;drcEvaluator;cachedReferenceDrcEvaluator;clearancePrecisionDrcEvaluator;clearancePrecisionIndexedDrcEvaluator;clearanceMarginDrcEvaluator;referenceDrcValidationCount=0;referenceDrcFalseNegativeCount=0;indexedDrcEvaluationCount=0;indexedDrcCacheHitCount=0;indexedDrcEvaluationTimeMs=0;indexedDrcCandidateCache=new Map;combinedOutput;cacheIndexedDrcResult(t,e){if(this.indexedDrcCandidateCache.size\u003e=64){const t=this.indexedDrcCandidateCache.keys().next().value;void 0!==t\u0026\u0026this.indexedDrcCandidateCache.delete(t)}this.indexedDrcCandidateCache.set(t,e)}constructor(t){super(),this.params=t,this.inputNewHdRoutes=t.newHdRoutes,this.inputUpdatedPreloadedTraces=t.updatedPreloadedTraces;const e=t.updatedPreloadedTraces.filter(e=\u003et.mutatedPreloadedTraceIds.has(e.pcb_trace_id)),n=ZJ({connections:t.newConnections,originalConnections:t.originalSrj.connections,layerCount:t.layerCount,obstacles:t.obstacles,defaultViaHoleDiameter:t.defaultViaHoleDiameter,connMap:t.connMap}),o=n(t.newHdRoutes),i=new Set(o.map(t=\u003et.pcb_trace_id)),r=(({originalPreloadedTraces:t,mutatedPreloadedTraces:e,newTraces:n})=\u003e{const o=new Set(n.map(t=\u003et.pcb_trace_id)),i=new Map(e.map(t=\u003e[t.pcb_trace_id,t])),r=new Set([...t.map(t=\u003et.pcb_trace_id),...o]),s=new Map;return{routedTraces:[...t.filter(t=\u003eo.has(t.pcb_trace_id)).map(t=\u003e{const e=i.get(t.pcb_trace_id)??t,n=`${t.pcb_trace_id}_preloaded`;let o=n,a=2;for(;r.has(o);)o=`${n}_${a}`,a+=1;return r.add(o),s.set(o,t.pcb_trace_id),{...e,pcb_trace_id:o,__replaces_pcb_trace_id:t.pcb_trace_id}}),...e.filter(t=\u003e!o.has(t.pcb_trace_id)),...n],originalPreloadedTraceIdByPreparedTraceId:s}})({originalPreloadedTraces:t.originalSrj.traces??[],mutatedPreloadedTraces:e,newTraces:o}),s=t.originalSrj.minTraceToPadEdgeClearance??V0.traceClearance??.1,a=V0.viaClearance??.1,c=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:[],drcOptions:{traceClearance:s}}),l=new Set((t.originalSrj.traces??[]).map(t=\u003et.pcb_trace_id)),d=N9({errors:c.errors,circuitJson:c.circuitJson,evaluatedTraceIds:l}),h=N9({errors:c.errorsWithCenters,circuitJson:c.circuitJson,evaluatedTraceIds:l}),u=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:r.routedTraces,drcOptions:{traceClearance:s}}),p=new Set(o1(t.originalSrj.traces??[],r.routedTraces).map(t=\u003et.pcb_trace_id)),m=N9({errors:u.errors,circuitJson:u.circuitJson,evaluatedTraceIds:p}),g=N9({errors:u.errorsWithCenters,circuitJson:u.circuitJson,evaluatedTraceIds:p}),f={...u,errors:x9({errors:m,baselineErrors:d,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId}),errorsWithCenters:x9({errors:g,baselineErrors:h,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId})},y=(({errors:t,circuitJson:e})=\u003e{const n=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[])),o=new Set;for(const e of t){const t=\"string\"==typeof e.pcb_trace_id?e.pcb_trace_id:void 0,i=[...\"string\"==typeof e.pcb_via_id?[e.pcb_via_id]:[],...Array.isArray(e.pcb_via_ids)?e.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]];if(\"string\"==typeof e.pcb_trace_id\u0026\u0026o.add(e.pcb_trace_id),Array.isArray(e.pcb_trace_ids))for(const t of e.pcb_trace_ids)\"string\"==typeof t\u0026\u0026o.add(t);if(\"string\"==typeof e.pcb_via_id){const t=n.get(e.pcb_via_id);t\u0026\u0026o.add(t)}if(Array.isArray(e.pcb_via_ids))for(const t of e.pcb_via_ids){if(\"string\"!=typeof t)continue;const e=n.get(t);e\u0026\u0026o.add(e)}const r=t?`overlap_${t}_`:void 0;if(r\u0026\u0026\"string\"==typeof e.pcb_trace_error_id\u0026\u0026e.pcb_trace_error_id.startsWith(r)){const t=e.pcb_trace_error_id.slice(r.length);i.includes(t)||o.add(t)}}return o})({errors:f.errors,circuitJson:f.circuitJson}),_=new Map(t.updatedPreloadedTraces.map(t=\u003e[t.pcb_trace_id,t])),b=new Set;for(const t of y){const e=r.originalPreloadedTraceIdByPreparedTraceId.get(t);e\u0026\u0026_.has(e)?b.add(e):!i.has(t)\u0026\u0026_.has(t)\u0026\u0026b.add(t)}for(const e of S9({errorsWithCenters:f.errorsWithCenters,traces:t.updatedPreloadedTraces,layerCount:t.layerCount,defaultViaDiameter:t.defaultViaDiameter,connMap:t.connMap}))b.add(e);this.movablePreloadedSections=[];for(const e of b){const n=_.get(e);if(!n)throw new Error(`Pipeline9 cannot find preloaded trace \"${e}\" selected for exact repair`);const o=t.updatedPreloadedTraces.findIndex(t=\u003et.pcb_trace_id===e),i=R9({trace:n,traceIndex:o,layerCount:t.layerCount,defaultViaDiameter:t.defaultViaDiameter,connMap:t.connMap});for(const[e,o]of i.entries()){const i=`pipeline9_preloaded_drc_${this.movablePreloadedSections.length}`;this.movablePreloadedSections.push({originalTrace:n,originalRoutePositionStart:o.routePositionStart,originalRoutePositionEnd:o.routePositionEnd,syntheticConnectionName:i,evaluationTraceId:`${n.pcb_trace_id}__pipeline9_section_${e}`,hdRoute:T9({trace:n,sectionGroup:o,syntheticConnectionName:i,connMap:t.connMap})})}}this.syntheticConnectionNames=new Set(this.movablePreloadedSections.map(t=\u003et.syntheticConnectionName));const x=new Set(this.movablePreloadedSections.map(t=\u003et.originalTrace.pcb_trace_id));this.fixedPreloadedObstacleRoutes=t.updatedPreloadedTraces.flatMap((e,n)=\u003e{const o=oQ(e,n,t.layerCount,t.defaultViaDiameter,t.connMap);return x.has(e.pcb_trace_id)?o.filter(t=\u003e{const n=t.preloadedRoutePositionStart;return void 0!==n\u0026\u0026\"through_obstacle\"===e.route[n]?.route_type}):o});const v=new Map;for(const[t,e]of this.movablePreloadedSections.entries()){const n=e.originalTrace.pcb_trace_id,o=v.get(n)??[];o.push(t),v.set(n,o)}for(const e of(({errors:t,circuitJson:e,originalTraceIdByPreparedTraceId:n})=\u003e{const o=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.flatMap(t=\u003e{if(\"pcb_via_clearance_error\"!==t.type||!Array.isArray(t.pcb_via_ids)||\"number\"!=typeof t.actual_clearance||t.actual_clearance\u003e=0)return[];const e=t.pcb_via_ids.flatMap(t=\u003e{if(\"string\"!=typeof t)return[];const e=o.get(t);return e?[n.get(e)??e]:[]}).filter((t,e,n)=\u003en.indexOf(t)===e);return e.length\u003e0?[e]:[]})})({errors:f.errors,circuitJson:f.circuitJson,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId})){const n=e.flatMap(t=\u003ev.get(t)??[]).filter((t,e,n)=\u003en.indexOf(t)===e);if(0===n.length)continue;const o=new Set(n),i=I9({routes:n.map(t=\u003ethis.movablePreloadedSections[t].hdRoute),otherHdRoutes:[...t.newHdRoutes,...this.fixedPreloadedObstacleRoutes,...this.movablePreloadedSections.flatMap((t,e)=\u003eo.has(e)?[]:[t.hdRoute])],obstacles:t.obstacles,colorMap:t.colorMap,layerCount:t.layerCount,connMap:t.connMap});for(let t=0;t\u003cn.length;t++)this.movablePreloadedSections[n[t]].hdRoute=i[t]}if(this.stats={initialJointDrcIssueCount:f.errors.length,baselineJointDrcIssueCount:c.errors.length,initialJointDrcIssueCountByType:f.errors.reduce((t,e)=\u003e{const n=String(e.type??e.error_type??\"unknown\");return t[n]=(t[n]??0)+1,t},{}),movablePreloadedTraceCount:x.size,movablePreloadedSectionCount:this.movablePreloadedSections.length,exactRepairConfiguredMaxIterations:32,exactRepairConfiguredViaInPadMaxIterations:32,exactRepairConfiguredBroadMaxIterations:12},0===f.errors.length)return void(this.solved=!0);const S=new Set(this.movablePreloadedSections.map(t=\u003et.originalTrace.pcb_trace_id)),I=e.filter(t=\u003e!S.has(t.pcb_trace_id)),C=new Map(this.movablePreloadedSections.map(e=\u003e[e.syntheticConnectionName,A9(e,t.layerCount)])),{traces:P,...M}=t.srjWithPointPairs,N={...M,connections:[...t.srjWithPointPairs.connections,...C.values()]},w=new s_({...N,obstacles:t.originalSrj.obstacles,minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter??t.defaultViaDiameter},{connMap:t.connMap,traceClearance:s,viaClearance:a,includeTraceViaOwnerMetadata:!0,spatialCellSize:Math.max(t.defaultViaDiameter,t.originalSrj.minTraceWidth)+Math.max(s,a)}),T=w.evaluate(t.originalSrj.traces??[]),R=M9(t.originalSrj.traces??[]),E={...T,errors:N9({errors:T.errors,circuitJson:R,evaluatedTraceIds:l}),errorsWithCenters:N9({errors:T.errorsWithCenters,circuitJson:R,evaluatedTraceIds:l})};let A;const O=e=\u003e{const o=e.filter(t=\u003e!this.syntheticConnectionNames.has(t.connectionName)),i=n(o),r=vK(i,t.originalSrj.traces??[]),s=new Set,a=new Map,c=this.movablePreloadedSections.map(n=\u003e{const o=e.find(t=\u003et.connectionName===n.syntheticConnectionName);if(!o)throw new Error(`Pipeline9 joint DRC repair lost preloaded section \"${n.syntheticConnectionName}\"`);const i=n.originalTrace.pcb_trace_id;a.set(n.evaluationTraceId,i);const r=!s.has(i);return s.add(i),{...n.originalTrace,pcb_trace_id:n.evaluationTraceId,...r?{__replaces_pcb_trace_id:i}:{__replaces_pcb_trace_id:void 0},route:Mo(o,t.layerCount,{defaultViaHoleDiameter:t.defaultViaHoleDiameter,obstacles:t.obstacles,connMap:t.connMap})}}),l=new Map;for(let t=0;t\u003ci.length;t++)l.set(r[t].pcb_trace_id,i[t].pcb_trace_id);for(const t of this.movablePreloadedSections)l.set(t.evaluationTraceId,`${t.syntheticConnectionName}_0`);const d=new Set(l.values()),h=[...I,...c,...r];return{evaluatedTraces:o1(t.originalSrj.traces??[],h),movableTraceIds:d,originalTraceIdByEvaluationTraceId:a,routedTraces:h,solverTraceIdByEvaluationTraceId:l}},k=({errors:t,errorsWithCenters:e,circuitJson:n,movableTraceIds:o,solverTraceIdByEvaluationTraceId:i})=\u003e{const r=n.map(t=\u003e{if(!(\"pcb_trace_id\"in t)||\"string\"!=typeof t.pcb_trace_id)return t;const e=i.get(t.pcb_trace_id);return e?{...t,pcb_trace_id:e}:t});return{errors:C9({errors:E9(t,i),circuitJson:r,newTraceIds:o}),errorsWithCenters:C9({errors:E9(e,i),circuitJson:r,newTraceIds:o})}},L=({routes:e,hdRoutes:n},o=!0)=\u003e{const i=e??n;if(!i)throw new Error(\"Pipeline9 reference DRC repair requires HD routes\");const r=O(i),a=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:r.routedTraces,drcOptions:{traceClearance:s,includeTraceContinuity:o}}),c=new Set(r.evaluatedTraces.map(t=\u003et.pcb_trace_id)),l=N9({errors:a.errors,circuitJson:a.circuitJson,evaluatedTraceIds:c}),u=N9({errors:a.errorsWithCenters,circuitJson:a.circuitJson,evaluatedTraceIds:c}),p=x9({errors:l,baselineErrors:d,originalTraceIdByPreparedTraceId:r.originalTraceIdByEvaluationTraceId}),m=x9({errors:u,baselineErrors:h,originalTraceIdByPreparedTraceId:r.originalTraceIdByEvaluationTraceId});return k({errors:p,errorsWithCenters:m,circuitJson:a.circuitJson,movableTraceIds:r.movableTraceIds,solverTraceIdByEvaluationTraceId:r.solverTraceIdByEvaluationTraceId})},D=({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline9 cached reference DRC requires HD routes\");const o=JSON.stringify(n);if(A?.candidateKey===o)return A.result;this.referenceDrcValidationCount+=1;const i=L({traces:[],routes:n,hdRoutes:n});return A={candidateKey:o,result:i},i};this.cachedReferenceDrcEvaluator=D,this.clearancePrecisionDrcEvaluator=({routes:t,hdRoutes:e})=\u003eL({traces:[],routes:t,hdRoutes:e},!1);const z=e=\u003e{const n=O(e);return n1(t.srjWithPointPairs,n.routedTraces,{minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter,originalSrj:t.originalSrj,includeOriginalConnections:!0})};let F;this.clearanceMarginDrcEvaluator=(t,e,n)=\u003e(F?.routes!==n\u0026\u0026(F={routes:n,circuitJson:z(n)}),(({circuitJson:t,originalCircuitJson:e,targets:n})=\u003e{const o=new Map(t.filter(t=\u003e\"pcb_trace\"===t.type).map(t=\u003e[t.pcb_trace_id,t])),i=new Map(e.filter(t=\u003e\"pcb_trace\"===t.type).map(t=\u003e[t.pcb_trace_id,t])),r=t.filter(t=\u003e\"pcb_via\"===t.type),s=new Map;for(const e of t)\"pcb_via\"===e.type?s.set(e.pcb_via_id,e):\"pcb_smtpad\"===e.type?s.set(e.pcb_smtpad_id,e):\"pcb_plated_hole\"===e.type\u0026\u0026s.set(e.pcb_plated_hole_id,e);const a=[];for(const t of n){const n=\"pcb_via_trace_clearance_error\"===t.type,c=n?t.pcb_via_id:t.pcb_pad_id;if(!n\u0026\u0026\"pcb_pad_trace_clearance_error\"!==t.type||\"string\"!=typeof t.pcb_trace_id||\"string\"!=typeof c||\"number\"!=typeof t.minimum_clearance||!Number.isFinite(t.minimum_clearance)||t.minimum_clearance\u003c=0)throw new Error(\"Pipeline9 clearance margin requires a valid target pair\");const l=i.get(t.pcb_trace_id),d=e.find(t=\u003en?\"pcb_via\"===t.type\u0026\u0026t.pcb_via_id===c:\"pcb_smtpad\"===t.type\u0026\u0026t.pcb_smtpad_id===c||\"pcb_plated_hole\"===t.type\u0026\u0026t.pcb_plated_hole_id===c);if(!l||!d)throw new Error(`Pipeline9 clearance margin has no original target ${c}/${t.pcb_trace_id}`);const h=o.get(t.pcb_trace_id);let u=s.get(c);if(n){if(\"pcb_via\"!==d.type||\"string\"!=typeof d.pcb_trace_id)throw new Error(\"Pipeline9 clearance margin requires the original via owner\");const t=i.get(d.pcb_trace_id);if(!t)throw new Error(\"Pipeline9 clearance margin lost the original via owner\");const e=t.route.filter(t=\u003e\"via\"===t.route_type),n=e.map((t,e)=\u003e({segment:t,index:e})).filter(({segment:t})=\u003et.x===d.x\u0026\u0026t.y===d.y\u0026\u0026d.layers.includes(t.from_layer)\u0026\u0026d.layers.includes(t.to_layer)\u0026\u0026(t.from_layer===d.layers[0]\u0026\u0026t.to_layer===d.layers.at(-1)||t.to_layer===d.layers[0]\u0026\u0026t.from_layer===d.layers.at(-1))).filter(({segment:t},e,n)=\u003en.findIndex(e=\u003ee.segment.from_layer===t.from_layer\u0026\u0026e.segment.to_layer===t.to_layer)===e);if(0===n.length)throw new Error(\"Pipeline9 clearance margin lost the original via transition\");if(1!==n.length)return{status:\"unsupported-identity\"};const s=n[0].index,a=o.get(d.pcb_trace_id),c=a?.route.filter(t=\u003e\"via\"===t.route_type);if(!c||c.length!==e.length||c.some((t,n)=\u003et.from_layer!==e[n].from_layer||t.to_layer!==e[n].to_layer))return{status:\"unsupported-identity\"};const l=c[s];u=r.filter(t=\u003et.x===l.x\u0026\u0026t.y===l.y\u0026\u0026t.layers.join()===d.layers.join()).reduce((t,e)=\u003e!t||e.outer_diameter\u003et.outer_diameter?e:t,void 0)}if(!(h\u0026\u0026u\u0026\u0026\"x\"in u\u0026\u0026\"y\"in u))return{status:\"unsupported-identity\"};const p={minClearance:t.minimum_clearance+1},m=n?Y0([h,u],p):$0([h,u],p),g=t.minimum_clearance+.01;for(const e of m){const n=e.actual_clearance;if(\"number\"!=typeof n||!Number.isFinite(n))throw new Error(\"Pipeline9 clearance margin requires a finite measurement\");n\u003e=g||a.push({...t,...\"pcb_via\"===u.type?{pcb_via_id:u.pcb_via_id,pcb_via_ids:[u.pcb_via_id]}:{},actual_clearance:n,minimum_clearance:g,center:{x:u.x,y:u.y}})}}return{status:\"measured\",errors:a}})({circuitJson:z(t),originalCircuitJson:F.circuitJson,targets:e})),this.clearancePrecisionIndexedDrcEvaluator=({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline9 clearance ranking requires HD routes\");const o=O(n);return w.evaluate(o.evaluatedTraces)};const B=({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline9 joint DRC repair requires HD routes\");const o=JSON.stringify(n),i=this.indexedDrcCandidateCache.get(o);if(void 0!==i)return this.indexedDrcCacheHitCount+=1,i;const r=performance.now();this.indexedDrcEvaluationCount+=1;const s=O(n),a=w.evaluate(s.evaluatedTraces),c=M9(s.evaluatedTraces),l=new Set(s.evaluatedTraces.map(t=\u003et.pcb_trace_id)),d=N9({errors:a.errors,circuitJson:c,evaluatedTraceIds:l}),h=N9({errors:a.errorsWithCenters,circuitJson:c,evaluatedTraceIds:l}),u=x9({errors:d,baselineErrors:E.errors,originalTraceIdByPreparedTraceId:s.originalTraceIdByEvaluationTraceId}),p=x9({errors:h,baselineErrors:E.errorsWithCenters,originalTraceIdByPreparedTraceId:s.originalTraceIdByEvaluationTraceId});if(0===u.length){const t=this.referenceDrcValidationCount,e=D({traces:[],routes:n,hdRoutes:n}),i=Array.isArray(e)?e:e.errors;return this.referenceDrcValidationCount\u003et\u0026\u0026i.length\u003e0\u0026\u0026(this.referenceDrcFalseNegativeCount+=1),this.indexedDrcEvaluationTimeMs+=performance.now()-r,this.cacheIndexedDrcResult(o,e),e}const m=k({errors:u,errorsWithCenters:p,circuitJson:c,movableTraceIds:s.movableTraceIds,solverTraceIdByEvaluationTraceId:s.solverTraceIdByEvaluationTraceId});return this.indexedDrcEvaluationTimeMs+=performance.now()-r,this.cacheIndexedDrcResult(o,m),m};this.drcEvaluator=B,this.exactRepairSolver=new wz({srj:N,hdRoutes:[...t.newHdRoutes,...this.movablePreloadedSections.map(t=\u003et.hdRoute)],connMap:t.connMap,effort:t.effort,viaHoleDiameter:t.defaultViaHoleDiameter,drcEvaluator:B,viaInPadDrcEvaluator:B,maxIterations:32,enableBroadFallback:!1,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!0,enableTraceViaOwnerTargeting:!0,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:t.originalSrj.allowViaInPad??!1,viaInPadMaxIterations:32,broadMaxIterations:12,broadPassMultiplier:3}),this.activeSubSolver=this.exactRepairSolver,this.MAX_ITERATIONS=this.exactRepairSolver.MAX_ITERATIONS+1}getSolverName(){return\"Pipeline9JointDrcRepairSolver\"}_step(){if(!this.exactRepairSolver)return void(this.solved=!0);if(this.exactRepairSolver.step(),this.progress=this.exactRepairSolver.progress,this.exactRepairSolver.failed)return this.failed=!0,void(this.error=this.exactRepairSolver.error);if(!this.exactRepairSolver.solved)return;let t=this.exactRepairSolver.getOutput();const e=this.exactRepairSolver.stats.finalDrcIssueCount,n=\"number\"==typeof e\u0026\u0026Number.isFinite(e)\u0026\u0026e\u003e=0?e:void 0;let o,i=0,r=0,s=0,a=!1;const c=this.cachedReferenceDrcEvaluator({traces:[],routes:t,hdRoutes:t}),l=Array.isArray(c)?c:c.errors;if(o=l.length,l.length\u003e0){const e=(({srj:t,routes:e,newConnections:n,syntheticConnectionNames:o,connMap:i,indexedDrcEvaluator:r,candidateDrcEvaluator:s,marginDrcEvaluator:a,drcEvaluator:c,initialErrors:l,initialErrorsWithCenters:d=l})=\u003e{const h={routes:e,attemptedCandidateCount:0,candidateValidationCount:0,referenceValidationCount:0,repaired:!1};if((t.traces?.length??0)\u003e0||o.size\u003e0)return h;if(0===l.length)return h;const u=d1({routes:e,newConnections:n,syntheticConnectionNames:o}),p=new Map;for(const e of t.obstacles)for(const t of[e.obstacleId,e.circuitJsonMetadata?.pcb_smtpad_id,e.circuitJsonMetadata?.pcb_plated_hole_id,e.connectedTo[0]])\"string\"==typeof t\u0026\u0026p.set(t,e.center);const m=p1({errors:l,errorsWithCenters:d,routeIndexByTraceId:u,padPositionById:p});if(!m)return h;let g=m;const f=m.errors,y=m.errors.map(t=\u003e({...t,minimum_clearance:t.minimum_clearance+.01})),_=u1(y);if(void 0===_)return h;let b={errors:y,deficit:_},x=e,v=0,S=0,I=0;for(let n=0;n\u003c8;n++){const n=new Map;for(const t of[...b.errors,...g.errors]){const e=JSON.stringify([t.type,t.pcb_trace_id,t.pcb_pad_id,t.pcb_via_id]);n.set(e,t)}const o=[...n.values()];let l;for(const e of h1){const n=kk(x);if(!$D(t,n,o,u,e,i,!0,!0,!0,!1))continue;const s=aD(n);v++;const a=r({traces:[],routes:s,hdRoutes:s}),c=u1(Array.isArray(a)?a:a.errors);void 0!==c\u0026\u0026(!l||c\u003cl.deficit)\u0026\u0026(l={routes:s,deficit:c})}if(!l)break;S++;const d=s({traces:[],routes:l.routes,hdRoutes:l.routes}),h=Array.isArray(d)?d:d.errors,m=p1({errors:h,errorsWithCenters:Array.isArray(d)?d:d.errorsWithCenters??d.errors,routeIndexByTraceId:u,padPositionById:p});if(!m)break;const y=a(l.routes,f,e);if(\"unsupported-identity\"===y.status)break;const _=y.errors,C=p1({errors:_,errorsWithCenters:_,routeIndexByTraceId:u,padPositionById:p});if(!C)break;if(0===h.length\u0026\u00260===_.length){I++;const t=c({traces:[],routes:l.routes,hdRoutes:l.routes});if(0===(Array.isArray(t)?t:t.errors).length)return{routes:l.routes,attemptedCandidateCount:v,candidateValidationCount:S,referenceValidationCount:I,repaired:!0};break}if(m.deficit+C.deficit\u003e=g.deficit+b.deficit-1e-9)break;x=l.routes,g=m,b=C}return{routes:e,attemptedCandidateCount:v,candidateValidationCount:S,referenceValidationCount:I,repaired:!1}})({srj:this.params.srj,routes:t,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,connMap:this.params.connMap,indexedDrcEvaluator:this.clearancePrecisionIndexedDrcEvaluator,candidateDrcEvaluator:this.clearancePrecisionDrcEvaluator,marginDrcEvaluator:this.clearanceMarginDrcEvaluator,drcEvaluator:this.cachedReferenceDrcEvaluator,initialErrors:l,initialErrorsWithCenters:Array.isArray(c)?c:c.errorsWithCenters??c.errors});i=e.attemptedCandidateCount,r=e.candidateValidationCount,s=e.referenceValidationCount,a=e.repaired,e.repaired\u0026\u0026(t=e.routes,o=0)}if(0===o)return this.combinedOutput=t,this.stats={...this.stats,...this.exactRepairSolver.stats,postExactIndexedDrcIssueCount:n,postExactReferenceValidationAttempted:!0,postExactReferenceDrcIssueCount:0,postExactReferenceAccepted:!0,clearancePrecisionCandidateCount:i,clearancePrecisionCandidateValidationCount:r,clearancePrecisionReferenceValidationCount:s,clearancePrecisionRepaired:a,boundedRegionalRepairAttemptedRegionCount:0,boundedRegionalRepairAcceptedRegionCount:0,boundedRegionalRepairCandidateAttemptCount:0,boundedRegionalRepairPathSearchNodeCount:0,boundedRegionalRepairReferenceValidationCount:0,boundedRegionalRepairRepaired:!1,boundedRegionalRepairTimeMs:0,regionalB01RepairCandidateCount:0,regionalB01RepairAcceptedCount:0,regionalB01RepairFallbackCandidateCount:0,regionalB01RepairCandidateSearchCount:0,regionalB01RepairCandidateSearchBudget:0,regionalB01RepairCandidateSearchBudgetExhausted:!1,regionalB01RepairSafeTraceLayerSkippedForBudget:!1,regionalB01RepairRemainingDrcIssueCount:0,regionalB01RepairPreloadEligibleDrcIssueCount:0,regionalB01RepairAttempted:!1,regionalB01RepairTraceIdCount:0,terminalEscapeCandidateCount:0,terminalEscapeAcceptedCount:0,referenceDrcValidationCount:this.referenceDrcValidationCount,referenceDrcFalseNegativeCount:this.referenceDrcFalseNegativeCount,indexedDrcEvaluationCount:this.indexedDrcEvaluationCount,indexedDrcCacheHitCount:this.indexedDrcCacheHitCount,indexedDrcEvaluationTimeMs:this.indexedDrcEvaluationTimeMs,indexedDrcCandidateCacheSize:this.indexedDrcCandidateCache.size,indexedDrcCandidateCacheCapacity:64},void(this.solved=!0);const d=f9({srj:this.params.srj,originalSrj:this.params.originalSrj,routes:t,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.drcEvaluator}),h=(({routes:t,newConnections:e,syntheticConnectionNames:n,fixedPreloadedObstacleRoutes:o,updatedPreloadedTraces:i})=\u003e{const r=new Set,s=Object.assign(new Set,{collidingFixedTraceIds:r}),a=d1({routes:t,newConnections:e,syntheticConnectionNames:n}),c=new Set;for(const[e,o]of a)n.has(t[o].connectionName)?s.add(e):c.add(e);for(const t of o){const e=i[t.preloadedTraceIndex];if(!e)throw new Error(`Pipeline9 fixed preload route has invalid trace index ${t.preloadedTraceIndex}`);c.has(e.pcb_trace_id)?r.add(e.pcb_trace_id):s.add(e.pcb_trace_id)}return s})({routes:d.routes,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,fixedPreloadedObstacleRoutes:this.fixedPreloadedObstacleRoutes,updatedPreloadedTraces:this.params.updatedPreloadedTraces}),u=a9({srj:this.params.srj,routes:d.routes,fixedObstacleRoutes:this.fixedPreloadedObstacleRoutes,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.drcEvaluator,initialErrors:d.remainingErrors,allowTracePairRepair:!0,preloadRepairTraceIds:h,connMap:this.params.connMap,colorMap:this.params.colorMap,viaDiameter:this.params.defaultViaDiameter,traceWidth:this.params.srj.minTraceWidth,obstacleMargin:this.params.srj.defaultObstacleMargin??this.params.srj.minTraceToPadEdgeClearance??.15,effort:this.params.effort}),p=performance.now(),m=(({originalSrj:t,routes:e,syntheticConnectionNames:n,drcEvaluator:o})=\u003e{const i={routes:e,attemptedRegionCount:0,acceptedRegionCount:0,candidateAttemptCount:0,pathSearchNodeCount:0,referenceValidationCount:0,initialDrcIssueCount:void 0,finalDrcIssueCount:void 0,repaired:!1};if(t.traces?.length||n.size\u003e0)return i;const r=Math.max(t.defaultObstacleMargin??.2,t.minTraceToPadEdgeClearance??0,t.minViaEdgeToPadEdgeClearance??0);let s=Math.max(t.minTraceWidth,t.minViaDiameter??0);for(const t of e){s=Math.max(s,t.traceThickness,t.viaDiameter);for(const e of t.route)s=Math.max(s,e.traceThickness??0)}const a=Math.max(.5,s+r),c=Z6.filter(t=\u003e!Number.isFinite(a)||2*a\u003ct);if(0===c.length)return i;let l=e,d=o({traces:[],routes:e,hdRoutes:e});i.referenceValidationCount++;let h=Array.isArray(d)?d:d.errors;if(i.initialDrcIssueCount=h.length,i.finalDrcIssueCount=h.length,0===h.length)return i;const u={...fX(t),traces:void 0},p=[];let m=new Map(P6({srj:u,routes:l}).map(t=\u003e[t.key,t.severity]));for(;i.attemptedRegionCount\u003c4;){const t=(Array.isArray(d)?d:d.errorsWithCenters??d.errors).map(t=\u003et.center??t.pcb_center).filter(t=\u003enull!==t\u0026\u0026\"object\"==typeof t\u0026\u0026\"x\"in t\u0026\u0026\"y\"in t\u0026\u0026\"number\"==typeof t.x\u0026\u0026\"number\"==typeof t.y\u0026\u0026Number.isFinite(t.x)\u0026\u0026Number.isFinite(t.y));let e;for(const n of c){const o=t.find(({x:t,y:e})=\u003e!p.some(({bounds:o,size:i})=\u003en===i\u0026\u0026t\u003e=o.minX\u0026\u0026t\u003c=o.maxX\u0026\u0026e\u003e=o.minY\u0026\u0026e\u003c=o.maxY));if(o){e={center:o,size:n};break}}if(!e)break;const{center:n,size:r}=e,s=j6({srj:u,routes:l,bounds:{minX:n.x-r/2,maxX:n.x+r/2,minY:n.y-r/2,maxY:n.y+r/2}});if(p.push({bounds:s.mutableBounds,size:r}),i.attemptedRegionCount++,0===s.routes.length)continue;const a=new A6({srj:s.srj,routes:s.routes,bounds:s.bounds,boundaryMargin:s.boundaryMargin,lockedPointIndices:s.lockedPointIndices,maxCandidates:256,maxCandidateAttempts:256,maxPathSearchNodes:U6,allowLayerChanges:!0,traceOnlyFirst:!1});if(a.solve(),a.failed)throw new Error(`Pipeline9 bounded regional repair failed: ${a.error}`);const{candidateAttempts:g,pathSearchNodes:f}=a.stats;if(!Number.isSafeInteger(g)||g\u003c0||g\u003e256||!Number.isSafeInteger(f)||f\u003c0||f\u003eU6)throw new Error(\"Pipeline9 bounded regional repair exceeded its work budget\");i.candidateAttemptCount+=g,i.pathSearchNodeCount+=f;const y=G6({routes:l,region:s,repairedRoutes:a.getOutput()});if(y.every((t,e)=\u003et===l[e]))continue;const _=P6({srj:u,routes:y});if(!_.every(({key:t,severity:e})=\u003em.has(t)\u0026\u0026e\u003c=m.get(t)+1e-8)||w6({srj:u,previousRoutes:l,routes:y}).length\u003e0)continue;const b=o({traces:[],routes:y,hdRoutes:y});i.referenceValidationCount++;const x=Array.isArray(b)?b:b.errors;if(!(x.length\u003e=h.length)\u0026\u0026(l=y,h=x,d=b,m=new Map(_.map(t=\u003e[t.key,t.severity])),i.acceptedRegionCount++,i.finalDrcIssueCount=h.length,0===h.length))return i.routes=l,i.repaired=!0,i}return i})({originalSrj:this.params.originalSrj,routes:u.routes,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.cachedReferenceDrcEvaluator});this.combinedOutput=m.routes,this.stats={...this.stats,...this.exactRepairSolver.stats,postExactIndexedDrcIssueCount:n,postExactReferenceValidationAttempted:!0,postExactReferenceDrcIssueCount:o,postExactReferenceAccepted:!1,clearancePrecisionCandidateCount:i,clearancePrecisionCandidateValidationCount:r,clearancePrecisionReferenceValidationCount:s,clearancePrecisionRepaired:a,boundedRegionalRepairAttemptedRegionCount:m.attemptedRegionCount,boundedRegionalRepairAcceptedRegionCount:m.acceptedRegionCount,boundedRegionalRepairCandidateAttemptCount:m.candidateAttemptCount,boundedRegionalRepairPathSearchNodeCount:m.pathSearchNodeCount,boundedRegionalRepairReferenceValidationCount:m.referenceValidationCount,boundedRegionalRepairRepaired:m.repaired,boundedRegionalRepairTimeMs:performance.now()-p,regionalB01RepairCandidateCount:u.attemptedCandidateCount,regionalB01RepairAcceptedCount:u.acceptedCandidateCount,regionalB01RepairFallbackCandidateCount:u.fallbackCandidateCount,regionalB01RepairCandidateSearchCount:u.candidateSearchCount,regionalB01RepairCandidateSearchBudget:u.candidateSearchBudget,regionalB01RepairCandidateSearchBudgetExhausted:u.candidateSearchBudgetExhausted,regionalB01RepairSafeTraceLayerSkippedForBudget:u.safeTraceLayerRepairSkippedForBudget,regionalB01RepairRemainingDrcIssueCount:u.remainingDrcIssueCount,regionalB01RepairPreloadEligibleDrcIssueCount:u.preloadEligibleDrcIssueCount,regionalB01RepairAttempted:u.preloadRepairAttempted,regionalB01RepairTraceIdCount:h.size+(h.collidingFixedTraceIds?.size??0),terminalEscapeCandidateCount:d.attemptedCandidateCount,terminalEscapeAcceptedCount:d.acceptedCandidateCount,referenceDrcValidationCount:this.referenceDrcValidationCount,referenceDrcFalseNegativeCount:this.referenceDrcFalseNegativeCount,indexedDrcEvaluationCount:this.indexedDrcEvaluationCount,indexedDrcCacheHitCount:this.indexedDrcCacheHitCount,indexedDrcEvaluationTimeMs:this.indexedDrcEvaluationTimeMs,indexedDrcCandidateCacheSize:this.indexedDrcCandidateCache.size,indexedDrcCandidateCacheCapacity:64},this.solved=!0}getCombinedOutput(){return this.combinedOutput??this.exactRepairSolver?.getOutput()??this.inputNewHdRoutes}getOutput(){return this.getCombinedOutput().filter(t=\u003e!this.syntheticConnectionNames.has(t.connectionName))}getUpdatedPreloadedTraces(){const t=new Map(this.getCombinedOutput().map(t=\u003e[t.connectionName,t])),e=new Map;for(const n of this.movablePreloadedSections){const o=t.get(n.syntheticConnectionName);if(!o)throw new Error(`Pipeline9 joint DRC repair output is missing \"${n.syntheticConnectionName}\"`);const i=n.originalTrace.pcb_trace_id,r=e.get(i)??[];r.push({routePositionStart:n.originalRoutePositionStart,routePositionEnd:n.originalRoutePositionEnd,route:Mo(o,this.params.layerCount,{defaultViaHoleDiameter:this.params.defaultViaHoleDiameter,obstacles:this.params.obstacles,connMap:this.params.connMap})}),e.set(i,r)}const n=new Map([...e].map(([t,e])=\u003e{const n=this.inputUpdatedPreloadedTraces.find(e=\u003ee.pcb_trace_id===t);if(!n)throw new Error(`Pipeline9 cannot find preloaded trace \"${t}\" while rebuilding repaired sections`);return[t,O9({originalTrace:n,repairedSections:e})]}));return this.inputUpdatedPreloadedTraces.map(t=\u003en.get(t.pcb_trace_id)??t)}getMutatedPreloadedTraces(){const t=new Set([...this.params.mutatedPreloadedTraceIds,...this.movablePreloadedSections.map(t=\u003et.originalTrace.pcb_trace_id)]);return this.getUpdatedPreloadedTraces().filter(e=\u003et.has(e.pcb_trace_id))}visualize(){return this.exactRepairSolver?.visualize()??{}}},L9=1e-6,D9=(t,e,n)=\u003e{const o=ko(t,n),i=ko(e,n);return Array.from({length:Math.abs(i-o)+1},(t,e)=\u003eMath.min(o,i)+e)},z9=t=\u003e\"wire\"===t.route_type,F9=(t,e,n)=\u003et.portPoints.filter(t=\u003et.availableZ.includes(n)\u0026\u0026!(t._preloadedTracePortAssignments??[]).some(t=\u003et.z===n\u0026\u0026t.fixedNetId!==e.fixedNetId)).map(t=\u003e({portPoint:t,distance:be(t,e.start,e.end)})).sort((t,e)=\u003et.distance-e.distance||t.portPoint.distToCentermostPortOnZ-e.portPoint.distToCentermostPortOnZ||t.portPoint.segmentPortPointId.localeCompare(e.portPoint.segmentPortPointId))[0]?.portPoint,B9=(t,e,n)=\u003e{t._preloadedFixedNetIds=[...new Set([...t._preloadedFixedNetIds??[],e.fixedNetId])].sort();const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.start.x)*o+(t.y-e.start.y)*i)/r)),a={traceId:e.traceId,fixedNetId:e.fixedNetId,routePosition:e.routePositionStart+s*(e.routePositionEnd-e.routePositionStart),tracePoint:{x:e.start.x+s*o,y:e.start.y+s*i},z:n},c=t._preloadedTracePortAssignments??[];c.some(t=\u003et.traceId===a.traceId\u0026\u0026t.fixedNetId===a.fixedNetId\u0026\u0026t.z===a.z\u0026\u0026Math.abs(t.routePosition-a.routePosition)\u003c=L9)||(t._preloadedTracePortAssignments=[...c,a].sort((t,e)=\u003et.traceId.localeCompare(e.traceId)||t.routePosition-e.routePosition||t.z-e.z))},j9=class extends si{constructor(t,e){super(),this.sharedEdgeSegments=t,this.srj=e,this.MAX_ITERATIONS=1,this.primitives=(t=\u003e{const e=[],n=ii(t);for(const o of t.traces??[]){if(!o.connection_name)throw new Error(`Preloaded trace \"${o.pcb_trace_id}\" is missing a connection name`);const i=n.getNetConnectedToId(o.connection_name)??o.connection_name;for(const[n,r]of o.route.entries())if(\"via\"===r.route_type)e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n,zLayers:D9(r.from_layer,r.to_layer,t.layerCount),start:r,end:r});else if(\"through_obstacle\"===r.route_type)e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n+1,zLayers:D9(r.from_layer,r.to_layer,t.layerCount),start:r.start,end:r.end});else if(\"jumper\"===r.route_type){const s=ko(r.layer,t.layerCount);for(const[t,a]of[r.start,r.end].entries())e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n+t,routePositionEnd:n+t,zLayers:[s],start:a,end:a})}for(let n=0;n\u003co.route.length-1;n++){const r=o.route[n],s=o.route[n+1];z9(r)\u0026\u0026z9(s)\u0026\u0026r.layer===s.layer\u0026\u0026e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n+1,zLayers:[ko(r.layer,t.layerCount)],start:r,end:s})}}return e})(e)}sharedEdgeSegments;srj;primitives;getSolverName(){return\"PreloadedTraceGraphSolver\"}_step(){for(const t of this.primitives)for(const e of this.sharedEdgeSegments)if(!(Ra(t.start,t.end,e.start,e.end)\u003eL9))for(const n of t.zLayers){if(!e.availableZ.includes(n))continue;const o=F9(e,t,n);o\u0026\u0026B9(o,t,n)}const t=this.sharedEdgeSegments.flatMap(t=\u003et.portPoints),e=t.filter(t=\u003e(t._preloadedFixedNetIds?.length??0)\u003e0);this.stats={preloadedTraceCount:this.srj.traces?.length??0,preloadedTraceShapeCount:this.primitives.length,inputBoundaryCount:this.sharedEdgeSegments.length,outputBoundaryCount:this.sharedEdgeSegments.length,inputPortCount:t.length,outputPortCount:t.length,preloadedPortCount:e.length,tracePortAssignmentCount:e.reduce((t,e)=\u003et+(e._preloadedTracePortAssignments?.length??0),0),topologyChanged:!1},this.solved=!0}getOutput(){if(!this.solved)throw new Error(\"PreloadedTraceGraphSolver has not solved yet\");return this.sharedEdgeSegments}},$9=class extends _X{_step(){const{traces:t,...e}=this.inputSrj,n=fX(e),o=fX(aX(yX(n)));this.outputSrj=void 0===t?o:{...o,traces:t},this.solved=!0}};function Y9(t){return new Set((t??[]).filter(t=\u003et._isComponentTopologyNode).map(t=\u003et.capacityMeshNodeId))}function X9(t,e){return t.nodeIds.some(t=\u003ee.has(t))}function V9({sharedEdgeSegments:t,componentCapacityMeshNodeIds:e}){return t.filter(t=\u003e!X9(t,e))}function W9(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var H9=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e;const n=fX(t);this.originalSrj=n,this.opts={...e};const o=this.opts;if(this.effort=o.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=o.maxNodeDimension??15,this.maxNodeRatio=o.maxNodeRatio??6,this.minNodeArea=o.minNodeArea??.1**2,this.visualizationTraceColorMode=o.visualizationTraceColorMode??\"layer\",this.setSimpleRouteJson(n),void 0===o.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,n=Math.max(t,e),i=o.targetMinCapacity??.5;o.capacityDepth=$s(n,i)}this.cacheProvider=void 0===o.cacheProvider?oo():null===o.cacheProvider?null:o.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;getSolverName(){return\"AutoroutingPipelineSolver9_PreloadedTraceGraph\"}preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;componentTopologyGeneratorSolver;topologyPlanningSolver;topologyMergingSolver;globalTopologyGeneratorSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;pipeline9JointDrcRepairSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;mutatedPreloadedTraceSimplificationSolver;lengthMatchingPostProcessingSolver;powerTraceExpansionSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;preloadedTraceGraphSolver;componentDetectionSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;visualizationTraceColorMode;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;sharedEdgeSegmentsWithNecessaryCrampedPortPoints;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[W9(\"preprocessSimpleRouteJsonSolver\",$9,t=\u003e[t.originalSrj,{traceColorMode:t.visualizationTraceColorMode}],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),W9(\"componentDetectionSolver\",UZ,t=\u003e[{inputSrj:t.srj}]),W9(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),W9(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),W9(\"topologyPlanningSolver\",_q,t=\u003e[{inputSrj:t.srjWithPointPairs,componentDetectionOutput:t.componentDetectionSolver.getOutput(),viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.topologyPlanningSolver.getOutput();t.globalTopologyGeneratorSolver=t.topologyPlanningSolver.globalTopologySolver,t.componentTopologyGeneratorSolver=new vq(t.topologyPlanningSolver)}}),W9(\"topologyMergingSolver\",fq,t=\u003e{const e=t.topologyPlanningSolver.getOutput();return[{layerCount:t.srj.layerCount,nodeGroups:[{groupId:\"global\",nodes:e.globalMeshNodes,isComponent:!1},...e.componentMeshNodes.map((t,e)=\u003e({groupId:`component-${e}`,nodes:t,isComponent:!0}))]}]},{onSolved:t=\u003e{t.capacityNodes=t.topologyMergingSolver.getOutput()}}),W9(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver.outputNodes}}),W9(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),W9(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),W9(\"necessaryCrampedPortPointSolver\",sf,t=\u003e{const e=Y9(t.capacityNodes);return[{capacityMeshNodes:t.capacityNodes.filter(t=\u003e!e.has(t.capacityMeshNodeId)),sharedEdgeSegments:V9({sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),componentCapacityMeshNodeIds:e}),simpleRouteJson:t.srjWithPointPairs}]},{onSolved:t=\u003e{const e=Y9(t.capacityNodes);t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints=function({originalSharedEdgeSegments:t,filteredSharedEdgeSegments:e,componentCapacityMeshNodeIds:n}){const o=new Map(e.map(t=\u003e[t.edgeId,t]));return t.map(t=\u003eX9(t,n)?t:o.get(t.edgeId)??t)}({originalSharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),filteredSharedEdgeSegments:t.necessaryCrampedPortPointSolver.getOutput(),componentCapacityMeshNodeIds:e})}}),W9(\"preloadedTraceGraphSolver\",j9,t=\u003e[t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints,t.srjWithPointPairs]),W9(\"portPointPathingSolver\",jj,t=\u003e{const e=t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints??t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,preserveTerminalPcbPortIds:!0,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0,USE_SELECTIVE_RERIP_ROUTING:!0,USE_PARTIAL_RIP_ROUTING_WITH_PRELOADED_TRACES:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),W9(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),W9(\"highDensityRouteSolver\",VQ,t=\u003e{const e=t.portPointPathingSolver;if(!e)throw new Error(\"Pipeline9 invariant violated: high-density routing requires the completed port-point pathing solver\");const n=e.getOutput(),o=t.uniformPortDistributionSolver?.getOutput()??[],i=n.nodesWithPortPoints,r=o.length\u003e0?o:i;t.highDensityNodePortPoints=structuredClone(r);const s=(t.originalSrj.traces??[]).flatMap((e,n)=\u003eoQ(e,n,t.originalSrj.layerCount,t.viaDiameter,t.connMap));return[{nodePortPoints:r,fixedHdRoutes:TK({traces:t.originalSrj.traces??[],fixedHdRoutes:s,sections:t.getChangedPreloadedTraceSections()}),connMap:t.connMap,colorMap:t.colorMap,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,viaToPadClearance:t.srj.minViaEdgeToPadEdgeClearance,effort:t.effort,includeBoardObstacles:!0,nodePfById:new Map(n.inputNodeWithPortPoints.map(t=\u003e[t.capacityMeshNodeId,e.computeNodePf(t)])),preserveTerminalPcbPortIds:!0}]}),W9(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:AK(t.highDensityRouteSolver.routes),colorMap:t.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),W9(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2,maxSampleEntries:80,connMap:t.connMap}]),W9(\"highDensityStitchSolver\",KY,t=\u003e[{connections:[...t.srjWithPointPairs.connections,...t.getChangedPreloadedTraceSections().map(t=\u003et.connection)],hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,preserveTerminalPcbPortIds:!0,preferSameLayerTerminalEndpoints:!0}]),W9(\"traceSimplificationSolver\",vc,t=\u003e{const e=t.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces.flatMap((e,n)=\u003eoQ(e,n,t.originalSrj.layerCount,t.viaDiameter,t.connMap).map(t=\u003e({...t,rootConnectionName:e.connection_name}))),n=new Set(t.getChangedPreloadedTraceSections().map(t=\u003et.connectionName)),o=t.highDensityStitchSolver.mergedHdRoutes.filter(t=\u003e!n.has(t.connectionName)),i=IK([...o,...e],t.connMap);return[{hdRoutes:o,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,otherHdRoutes:e,netByConnectionName:i,enableCrossingViaReduction:!0,terminalLayerIndicesByPcbPortId:SK(t.srj.connections,t.srj.obstacles,t.srj.layerCount),iterations:2}]}),W9(\"mutatedPreloadedTraceSimplificationSolver\",vc,t=\u003e{const e=t.getPreparedMutatedPreloadedTraceSections(),n=e.sections.map(t=\u003et.hdRoute),o=[...e.immutableHdRoutes,...t.traceSimplificationSolver.simplifiedHdRoutes];return[{hdRoutes:n,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,otherHdRoutes:o,netByConnectionName:IK([...n,...o],t.connMap),enableCrossingViaReduction:!0,preserveRouteEndpoints:!0,iterations:2}]}),W9(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srjWithPointPairs.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),W9(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.getSrjWithMaterializedPreloadedTraces(),hdRoutes:KJ(t.traceWidthSolver.getHdRoutesWithWidths(),t.netToPointPairsSolver?.newConnections??[],new Map((t.highDensityStitchSolver?.mergedHdRoutes??[]).map(t=\u003e[t.connectionName,t]))),connMap:t.connMap,effort:t.effort,maxIterations:16,enableLargeBoardBroadFallback:!1,enablePostSolveClearanceRelaxation:!1}]),W9(\"pipeline9JointDrcRepairSolver\",k9,t=\u003e{const e=t.getPreloadedTraceUpdatesAfterHighDensity(),n=t.getSrjWithMaterializedPreloadedTraces();return[{srj:n,srjWithPointPairs:n,originalSrj:t.originalSrj,newConnections:t.netToPointPairsSolver?.newConnections??[],newHdRoutes:t.globalDrcForceImproveSolver.getOutput(),updatedPreloadedTraces:e.updatedPreloadedTraces,mutatedPreloadedTraceIds:new Set(e.mutatedPreloadedTraces.map(t=\u003et.pcb_trace_id)),connMap:t.connMap,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,defaultViaHoleDiameter:t.viaHoleDiameter,effort:t.effort,colorMap:t.colorMap}]}),W9(\"lengthMatchingPostProcessingSolver\",uK,t=\u003e{const e=t.netToPointPairsSolver;if(!e)throw new Error(\"Pipeline9: length-matching post-processing requires NetToPointPairsSolver output\");const n=e.newConnections,o=new Map;for(const e of t.srj.differentialPairs??[])for(const t of e.connectionNames){const e=n.filter(e=\u003ee.name===t||e.__rootConnectionNames?.includes(t)||e.__netConnectionName===t);if(1!==e.length)throw new Error(`Pipeline9: differential pair connection \"${t}\" must resolve to exactly one final point-pair connection, got ${e.length}`);o.set(t,e[0].name)}const i=t.pipeline9JointDrcRepairSolver.getOutput(),r=(t.srj.differentialPairs??[]).map(t=\u003e{const e=t.connectionNames.map(t=\u003e{const e=o.get(t);if(!e)throw new Error(`Pipeline9: differential pair connection \"${t}\" is missing from final routed output`);return e});if(e[0]===e[1])throw new Error(`Pipeline9: differential pair ${t.connectionNames.join(\"/\")} resolves both members to \"${e[0]}\"`);if(void 0===t.traceGap)return{connectionNames:e,lengthTolerance:t.lengthTolerance};const n=e.map(t=\u003e{const e=i.filter(e=\u003ee.connectionName===t);if(1!==e.length)throw new Error(`Pipeline9: differential pair connection \"${t}\" must resolve to exactly one final HD route, got ${e.length}`);return e[0]}),r=t.traceGap+n.reduce((t,e)=\u003et+e.traceThickness/2,0);return{connectionNames:e,lengthTolerance:t.lengthTolerance,minimumCenterlineDistance:r,maximumCenterlineDistance:r}});return[{hdRoutes:i,differentialPairs:r,buses:t.srj.buses??[],connections:t.srj.connections,obstacles:t.srj.obstacles,bounds:t.srj.bounds,layerCount:t.srj.layerCount,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15}]}),W9(\"powerTraceExpansionSolver\",UJ,t=\u003e{const e=t.opts.powerTraceExpansion??{},n=e.onlyConnectionNames??JJ(t.originalSrj);return[QJ({originalSrj:t.originalSrj,newlyRoutedTraces:t.getNewTracesBeforePowerExpansion(),currentPreloadedTraces:t.getUpdatedPreloadedTraces(),expandedConnectionNames:n,resolveConnectedTraceAliases:!0}),{allowNewVias:!1,...e,onlyConnectionNames:n}]})];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;computeProgress(){const t=this.activeSubSolver?.progress??0;return(this.currentPipelineStepIndex+t)/this.pipelineDef.length}_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\u0026\u0026(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),\"lengthMatchingPostProcessingSolver\"!==t.solverName\u0026\u0026\"powerTraceExpansionSolver\"!==t.solverName||(this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,this.iterations+this.activeSubSolver.MAX_ITERATIONS+1)),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\u0026\u0026this.activeSubSolver)return this.visualizeStage(this.activeSubSolver);const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.componentDetectionSolver?.visualize(),o=this.componentTopologyGeneratorSolver?.visualize(),i=this.globalTopologyGeneratorSolver?.visualize(),r=this.topologyMergingSolver?.visualize(),s=this.nodeDimensionSubdivisionSolver?.visualize(),a=this.nodeTargetMerger?.visualize(),c=this.singleLayerNodeMerger?.visualize(),l=this.strawSolver?.visualize(),d=this.edgeSolver?.visualize(),h=this.deadEndSolver?.visualize(),u=this.availableSegmentPointSolver?.visualize(),p=this.portPointPathingSolver?.visualize(),m=this.multiSectionPortPointOptimizer?.visualize(),g=this.uniformPortDistributionSolver?.visualize(),f=this.highDensityRouteSolver?.visualize(),y=this.highDensityForceImproveSolver?.visualize(),_=this.highDensityRepairSolver?.visualize(),b=this.highDensityStitchSolver?.visualize(),x=this.traceSimplificationSolver?.visualize(),v=this.mutatedPreloadedTraceSimplificationSolver?.visualize(),S=this.lengthMatchingPostProcessingSolver?.visualize(),I=this.powerTraceExpansionSolver?.visualize(),C=this.traceWidthSolver?.visualize(),P=this.necessaryCrampedPortPointSolver?.visualize(),M=(this.highDensityRouteSolver?.visualize(),this.originalSrj),N=M.outline,w=[];if(w.push({points:[{x:M.bounds?.minX??-50,y:M.bounds?.minY??-50},{x:M.bounds?.maxX??50,y:M.bounds?.minY??-50},{x:M.bounds?.maxX??50,y:M.bounds?.maxY??50},{x:M.bounds?.minX??-50,y:M.bounds?.maxY??50},{x:M.bounds?.minX??-50,y:M.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),N\u0026\u0026N.length\u003e=2){const t=N.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),w.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const T=Oo(M),R={points:[...M.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,M.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(M.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,M.layerCount),label:T(t)}))],lines:w},E={traceColorMode:this.visualizationTraceColorMode},A=Yj({srj:M,visualizationOptions:E}),O=pi(R,A),k=this.preprocessSimpleRouteJsonSolver?.visualize(),L=this.globalDrcForceImproveSolver?.visualize(),D=this.pipeline9JointDrcRepairSolver?.visualize(),z=[O,k,n,o,t,e,i,r,s,a,c,l,d,h,u,P,p,m,g,f?pi(R,f):null,y,_,b,x,v,C,L,D,S,I,this.solved?pi({lines:w},Yj({srj:this.originalSrj,visualizationOptions:E}),this.visualizeFinalOutput()):null].filter(Boolean),F=pi(...z);return\"net\"===this.visualizationTraceColorMode?xq(F,this.colorMap):F}visualizeStage(t){const e=t.visualize();return\"net\"===this.visualizationTraceColorMode?xq(e,this.colorMap):e}visualizeFinalOutput(){const t=this.visualizationTraceColorMode,e=this.getOutputSimpleRouteJson();return Ho(e,{traceColorMode:t})}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.componentTopologyGeneratorSolver?this.componentTopologyGeneratorSolver.visualize():this.componentDetectionSolver?this.componentDetectionSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){if(((this.originalSrj.differentialPairs?.length??0)\u003e0||(this.originalSrj.buses??[]).some(t=\u003evoid 0!==t.maxLengthSkew))\u0026\u0026this.lengthMatchingPostProcessingSolver){const{hdRoutes:t}=this.lengthMatchingPostProcessingSolver.getOutput();return t}return this.pipeline9JointDrcRepairSolver?.getOutput()??this.globalDrcForceImproveSolver?.getOutput()??this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOriginalFixedHdRoutes(){return(this.originalSrj.traces??[]).flatMap((t,e)=\u003eoQ(t,e,this.originalSrj.layerCount,this.viaDiameter,this.connMap))}getChangedPreloadedTraceSections(){return this.portPointPathingSolver?.getOutput().changedPreloadedTraceSections??[]}getPreloadedFixedRouteStateAfterHighDensity(){const t=this.getOriginalFixedHdRoutes(),e=this.getChangedPreloadedTraceSections(),n=TK({traces:this.originalSrj.traces??[],fixedHdRoutes:t,sections:e}),o=0===e.length?[]:RK({traces:this.originalSrj.traces??[],sections:e,stitchedHdRoutes:this.highDensityStitchSolver?.mergedHdRoutes??[],layerCount:this.originalSrj.layerCount}),i=new Set(e.map(t=\u003et.traceId)),r=t.filter(t=\u003ei.has(this.originalSrj.traces?.[t.preloadedTraceIndex]?.pcb_trace_id??\"\")).map(t=\u003et.connectionName);return{originalFixedRoutes:t,updatedFixedRoutes:[...this.highDensityRouteSolver?.getUpdatedFixedHdRoutes()??n,...o],replacedConnectionNames:new Set([...this.highDensityRouteSolver?.fixedRouteReplacements.keys()??[],...r]),mutationMasks:new Map([...this.highDensityRouteSolver?.preloadedTraceMutationMasks??[],...o.map(t=\u003e[t.connectionName,Array(t.route.length-1).fill(!0)])])}}getPreparedMutatedPreloadedTraceSections(){const t=this.getPreloadedFixedRouteStateAfterHighDensity();return eQ({updatedFixedRoutes:t.updatedFixedRoutes,regionalMutationMasks:t.mutationMasks})}getPreloadedTraceUpdatesAfterHighDensity(){const t=this.getPreloadedFixedRouteStateAfterHighDensity(),e=this.getPreparedMutatedPreloadedTraceSections(),n=!0===this.mutatedPreloadedTraceSimplificationSolver?.solved?(({updatedFixedRoutes:t,sections:e,simplifiedHdRoutes:n})=\u003e{const o=new Set(e.map(t=\u003et.connectionName)),i=new Map(n.map(t=\u003e[t.connectionName,t]));if(i.size!==e.length||n.some(t=\u003e!o.has(t.connectionName)))throw new Error(`Pipeline9 trace simplification changed the mutation-section set (expected ${e.length}, got ${n.length})`);const r=new Map,s=new Set;for(const t of e){const e=i.get(t.connectionName);if(!e)throw new Error(`Pipeline9 trace simplification lost mutation section \"${t.connectionName}\"`);const n=e.route[0],o=e.route.at(-1);if(!(n\u0026\u0026o\u0026\u0026HK(n,t.section.start.point)\u0026\u0026HK(o,t.section.end.point)))throw new Error(`Pipeline9 trace simplification changed mutation-section boundary \"${t.connectionName}\"`);const a=XK(t.section,e),c=t.section.sourceRoutes[0];s.add(c.connectionName);for(const e of t.section.sourceRoutes){if(r.has(e.connectionName))throw new Error(`Pipeline9 attempted to simplify fixed route \"${e.connectionName}\" more than once`);r.set(e.connectionName,a)}}return t.flatMap(t=\u003e{const e=r.get(t.connectionName);return e?s.has(t.connectionName)?[e]:[]:[t]})})({updatedFixedRoutes:e.normalizedFixedRoutes,sections:e.sections,simplifiedHdRoutes:this.mutatedPreloadedTraceSimplificationSolver.simplifiedHdRoutes}):t.updatedFixedRoutes;return(({originalTraces:t,originalFixedRoutes:e,updatedFixedRoutes:n,replacedConnectionNames:o,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a})=\u003e{const c=new Map,l=new Map;for(const t of e){const e=c.get(t.preloadedTraceIndex)??[];e.push(t),c.set(t.preloadedTraceIndex,e)}for(const t of n){const e=l.get(t.preloadedTraceIndex)??[];e.push(t),l.set(t.preloadedTraceIndex,e)}const d=[];return{updatedPreloadedTraces:t.map((t,e)=\u003e{const n=(c.get(e)??[]).sort(fK);if(!n.some(t=\u003eo.has(t.connectionName)))return t;const h=(l.get(e)??[]).sort(fK),u=t.route.some(t=\u003e\"through_obstacle\"===t.route_type),p={...t,__replaces_pcb_trace_id:t.pcb_trace_id,route:u?xK({trace:t,originalTraceRoutes:n,updatedTraceRoutes:h,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a}):_K({trace:t,updatedTraceRoutes:h,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a})};return d.push(p),p}),mutatedPreloadedTraces:d}})({originalTraces:this.originalSrj.traces??[],originalFixedRoutes:t.originalFixedRoutes,updatedFixedRoutes:n,replacedConnectionNames:t.replacedConnectionNames,layerCount:this.originalSrj.layerCount,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.originalSrj.obstacles,connMap:this.connMap})}getSrjWithMaterializedPreloadedTraces(){return{...this.srjWithPointPairs,traces:this.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces}}getUpdatedPreloadedTraces(){return this.pipeline9JointDrcRepairSolver?.getUpdatedPreloadedTraces()??this.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces}getMutatedPreloadedTraces(){return this.pipeline9JointDrcRepairSolver?.getMutatedPreloadedTraces()??this.getPreloadedTraceUpdatesAfterHighDensity().mutatedPreloadedTraces}getNewTracesBeforePowerExpansion(){if(!this.highDensityRouteSolver)throw new Error(\"Cannot get new traces before high-density routing\");const t=qJ({connections:this.netToPointPairsSolver?.newConnections??[],originalConnections:this.originalSrj.connections,hdRoutes:this._getOutputHdRoutes(),layerCount:this.srj.layerCount,obstacles:this.srj.obstacles,defaultViaHoleDiameter:this.viaHoleDiameter,connMap:this.connMap});return vK(t,this.originalSrj.traces??[])}getPowerTraceExpansionFixedTraces(){if(!this.powerTraceExpansionSolver)throw new Error(\"Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver\");return this.powerTraceExpansionSolver.inputSrj.fixedTraces}getOutputSimplifiedPcbTraces(){if(!this.solved)throw new Error(\"Cannot get output before solving is complete\");if(!this.powerTraceExpansionSolver)throw new Error(\"Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver\");return[...this.getPowerTraceExpansionFixedTraces().filter(t=\u003evoid 0!==t.__replaces_pcb_trace_id),...this.powerTraceExpansionSolver.getOutput()]}getOutputSimpleRouteJson(){if(!this.solved)throw new Error(\"Cannot get output before solving is complete\");if(!this.powerTraceExpansionSolver)throw new Error(\"Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver\");const t=[...this.getPowerTraceExpansionFixedTraces(),...this.powerTraceExpansionSolver.getOutput()];return{...this.originalSrj,traces:t}}},G9=String(\"0.0.886\"),U9=({nodeWithPortPoints:t,obstacleMargin:e,traceWidth:n,viaDiameter:o})=\u003e{const i=ro(t),r=e+Math.max(n,o)/2+1e-6;return{minX:t.center.x+8*(i.minX-t.center.x)-r,maxX:t.center.x+8*(i.maxX-t.center.x)+r,minY:t.center.y+8*(i.minY-t.center.y)-r,maxY:t.center.y+8*(i.maxY-t.center.y)+r}},Z9=(t,e)=\u003e{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.abs(Math.cos(n)),i=Math.abs(Math.sin(n)),r=t.width/2,s=t.height/2,a=Math.max(r,r*o+s*i),c=Math.max(s,r*i+s*o);return t.center.x-a\u003c=e.maxX\u0026\u0026t.center.x+a\u003e=e.minX\u0026\u0026t.center.y-c\u003c=e.maxY\u0026\u0026t.center.y+c\u003e=e.minY},q9=(t,e)=\u003e{for(const n of[e.connectionName,e.rootConnectionName,e.portPointId,e.pcb_port_id,e.prevPortPointId,e.nextPortPointId])void 0!==n\u0026\u0026t.add(n)},J9=(t,e)=\u003eObject.fromEntries(Object.entries(t.netMap).flatMap(([t,n])=\u003e{const o=n.filter(t=\u003ee.has(t));return o.length\u003e0||e.has(t)?[[t,o]]:[]})),K9=({obstacle:t,connectedTo:e,preserveRotation:n})=\u003e({type:\"rect\",layers:t.layers,...void 0===t.zLayers?{}:{zLayers:t.zLayers},...void 0===t.__zLayers?{}:{__zLayers:t.__zLayers},center:t.center,width:t.width,height:t.height,...n\u0026\u0026void 0!==t.ccwRotationDegrees?{ccwRotationDegrees:t.ccwRotationDegrees}:{},connectedTo:e,...void 0===t.circuitJsonMetadata?{}:{circuitJsonMetadata:t.circuitJsonMetadata}});function Q9({nodeWithPortPoints:t,connMap:e,obstacles:n,obstacleMargin:o,traceWidth:i,viaDiameter:r}){const s=U9({nodeWithPortPoints:t,obstacleMargin:o,traceWidth:i,viaDiameter:r}),a=new Set;for(const e of t.portPoints)q9(a,e);for(const e of t.portPointsInPairs??[])q9(a,e[0]),q9(a,e[1]);const c=n.flatMap(n=\u003e{if(!Z9(n,s))return[];const o=(({obstacle:t,nodeWithPortPoints:e,connMap:n})=\u003e{const o=new Set(e.portPoints.flatMap(t=\u003e{const e=n.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName;return[t.connectionName,e]})),i=new Set(t.connectedTo.filter(t=\u003eo.has(t))),r=new Map;for(const t of o){const e=n.getNetConnectedToId(t)??t,o=r.get(e)??[];o.push(t),r.set(e,o)}for(const e of r.values()){if([...i].some(t=\u003ee.some(e=\u003ee===t||n.areIdsConnected(e,t))))continue;const o=t.connectedTo.find(t=\u003ee.some(e=\u003ee===t||n.areIdsConnected(e,t)));void 0!==o\u0026\u0026i.add(o)}return[...i]})({obstacle:n,nodeWithPortPoints:t,connMap:e});for(const t of o)a.add(t);return[K9({obstacle:n,connectedTo:o,preserveRotation:!0})]});return{connectivityNetMap:J9(e,a),obstacles:c}}var t8=(...t)=\u003e{const e=new Map;for(const n of t)for(const[t,o]of Object.entries(n)){const n=e.get(t)??new Set;for(const t of o)n.add(t);e.set(t,n)}return Object.fromEntries([...e].map(([t,e])=\u003e[t,[...e]]))};function e8({nodeWithPortPoints:t,connMap:e,colorMap:n,obstacles:o,obstacleMargin:i,traceWidth:r,viaDiameter:s}){const a=U9({nodeWithPortPoints:t,obstacleMargin:i,traceWidth:r,viaDiameter:s}),c=(t=\u003e[...new Set(t.portPoints.map(t=\u003et.connectionName))])(t),l=o.flatMap(t=\u003e{if(!Z9(t,a))return[];const n=c.filter(n=\u003et.connectedTo.some(t=\u003et===n||e.areIdsConnected(n,t)));return 0===n.length?[]:[K9({obstacle:t,connectedTo:n,preserveRotation:!1})]}),d=new Set;for(const e of t.portPoints)q9(d,e);for(const e of t.portPointsInPairs??[])q9(d,e[0]),q9(d,e[1]);for(const t of l)for(const e of[t.circuitJsonMetadata?.pcb_smtpad_id,t.circuitJsonMetadata?.pcb_plated_hole_id,t.circuitJsonMetadata?.pcb_port_id,t.circuitJsonMetadata?.pcb_via_id,...t.connectedTo??[]])void 0!==e\u0026\u0026d.add(e);return{connectivityNetMap:J9(e,d),colorMap:Object.fromEntries(Object.entries(n??{}).filter(([t])=\u003ed.has(t))),obstacles:l}}var n8=\"https://hd-cache2.tscircuit.com\",o8=31e4,i8=1835008,r8=16777216,s8=class extends Error{constructor(t,e){super(e),this.reason=t,this.name=\"HdCache2RequestError\"}reason},a8=t=\u003et instanceof Error?t.message:String(t),c8=new Set([\"pcb_smtpad_id\",\"pcb_plated_hole_id\",\"pcb_port_id\",\"pcb_via_id\",\"source_component_name\",\"source_port_name\"]),l8=t=\u003e!(!t||\"object\"!=typeof t||Array.isArray(t))\u0026\u0026Object.entries(t).every(([t,e])=\u003ec8.has(t)\u0026\u0026\"string\"==typeof e),d8=(t,e)=\u003eMath.abs(t-e)\u003c=1e-9*Math.max(1,Math.abs(t),Math.abs(e)),h8=1e-6,u8=(t,e)=\u003e{const n=\"ordinary\"===e?h8:.001,o=new Set;for(let i=0;i\u003ct.route.length-1;i++){const r=t.route[i],s=t.route[i+1],a=r.z!==s.z;if(\"through_obstacle\"===r.toNextSegmentType){if(!a)return!1;continue}if(void 0!==r.toNextSegmentCircuitJsonMetadata)return!1;if(!a)continue;const c=[],l=[];for(const[e,o]of t.vias.entries())Math.hypot(o.x-r.x,o.y-r.y)\u003c=n\u0026\u0026c.push(e),Math.hypot(o.x-s.x,o.y-s.y)\u003c=n\u0026\u0026l.push(e);if(Math.hypot(r.x-s.x,r.y-s.y)\u003c=h8){if(0===c.length)return!1;for(const t of c)o.add(t)}else{if(\"regional-fallback\"===e)return!1;if(0===c.length==(0===l.length))return!1;for(const t of[...c,...l])o.add(t)}}const i=t.route.at(-1);return void 0===i.toNextSegmentType\u0026\u0026void 0===i.toNextSegmentCircuitJsonMetadata\u0026\u0026t.vias.every((t,e)=\u003eo.has(e))},p8=(t,e,n)=\u003e{if(!Array.isArray(t))return!1;const o=new Map;for(const t of e.nodeWithPortPoints.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}const i=new Set(e.nodeWithPortPoints.availableZ??e.nodeWithPortPoints.portPoints.map(t=\u003et.z)),r=U9({nodeWithPortPoints:e.nodeWithPortPoints,obstacleMargin:e.obstacleMargin,traceWidth:e.traceWidth,viaDiameter:e.viaDiameter}),s=(t,e)=\u003e(o.get(e)??[]).some(e=\u003e\"number\"==typeof t.x\u0026\u0026d8(t.x,e.x)\u0026\u0026\"number\"==typeof t.y\u0026\u0026d8(t.y,e.y)\u0026\u0026t.z===e.z);for(const a of t){if(!a||\"object\"!=typeof a)return!1;const t=a;if(\"string\"!=typeof t.connectionName||0===t.connectionName.length||!o.has(t.connectionName)||\"number\"!=typeof t.traceThickness||!Number.isFinite(t.traceThickness)||t.traceThickness\u003c=0||\"number\"!=typeof t.viaDiameter||!Number.isFinite(t.viaDiameter)||t.viaDiameter\u003c=0||!d8(t.viaDiameter,e.viaDiameter)||!Array.isArray(t.route)||t.route.length\u003c2||!Array.isArray(t.vias))return!1;for(const e of[t.rootConnectionName,t.startPcbPortId,t.endPcbPortId,t.regionId])if(void 0!==e\u0026\u0026\"string\"!=typeof e)return!1;for(const o of t.route){if(!o||\"object\"!=typeof o)return!1;const t=o;if(\"number\"!=typeof t.x||!Number.isFinite(t.x)||\"number\"!=typeof t.y||!Number.isFinite(t.y)||t.x\u003cr.minX||t.x\u003er.maxX||t.y\u003cr.minY||t.y\u003er.maxY||\"number\"!=typeof t.z||!Number.isInteger(t.z)||t.z\u003c0||t.z\u003e=e.layerCount||\"ordinary\"===n\u0026\u0026!i.has(t.z))return!1;if(void 0!==t.traceThickness\u0026\u0026(\"number\"!=typeof t.traceThickness||!Number.isFinite(t.traceThickness)||t.traceThickness\u003c=0))return!1;if(void 0!==t.pcb_port_id\u0026\u0026\"string\"!=typeof t.pcb_port_id)return!1;if(void 0!==t.insideJumperPad\u0026\u0026\"boolean\"!=typeof t.insideJumperPad)return!1;if(void 0!==t.toNextSegmentType\u0026\u0026\"through_obstacle\"!==t.toNextSegmentType)return!1;if(void 0!==t.toNextSegmentCircuitJsonMetadata\u0026\u0026!l8(t.toNextSegmentCircuitJsonMetadata))return!1}const c=t.route;if(!(\"ordinary\"!==n||s(c[0],t.connectionName)\u0026\u0026s(c.at(-1),t.connectionName)))return!1;for(const e of t.vias){if(!e||\"object\"!=typeof e)return!1;const t=e;if(\"number\"!=typeof t.x||!Number.isFinite(t.x)||\"number\"!=typeof t.y||!Number.isFinite(t.y)||t.x\u003cr.minX||t.x\u003er.maxX||t.y\u003cr.minY||t.y\u003er.maxY)return!1}if(!u8(t,n))return!1;if(void 0!==t.jumpers){if(!Array.isArray(t.jumpers))return!1;for(const e of t.jumpers){if(!e||\"object\"!=typeof e)return!1;const t=e,n=t.start,o=t.end;if(\"jumper\"!==t.route_type||\"0603\"!==t.footprint\u0026\u0026\"1206\"!==t.footprint\u0026\u0026\"1206x4_pair\"!==t.footprint||!n||\"number\"!=typeof n.x||!Number.isFinite(n.x)||\"number\"!=typeof n.y||!Number.isFinite(n.y)||!o||\"number\"!=typeof o.x||!Number.isFinite(o.x)||\"number\"!=typeof o.y||!Number.isFinite(o.y)||n.x\u003cr.minX||n.x\u003er.maxX||n.y\u003cr.minY||n.y\u003er.maxY||o.x\u003cr.minX||o.x\u003er.maxX||o.y\u003cr.minY||o.y\u003er.maxY)return!1}}}const a=t;return\"ordinary\"===n?((t,e)=\u003e{const n=e.portPointsInPairs??[];if(n.length\u003e0){for(const[e,o]of n)if(!xs(t,e.connectionName,_s(e)).has(_s(o)))return!1;return!0}const o=new Map;for(const t of e.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}for(const[e,n]of o)for(const[o,i]of Dr(n))if(!xs(t,e,_s(o)).has(_s(i)))return!1;return!0})(a,e.nodeWithPortPoints):((t,e)=\u003e{const n=(t,e)=\u003e{if(t.z!==e.z)return!1;const n=t.x-e.x,o=t.y-e.y;return Math.hypot(n,o)\u003c=.001},o=new Map;for(const i of t){const t=i.route.some((t,e)=\u003e{const n=i.route[e+1];return!(void 0===n||d8(t.x,n.x)\u0026\u0026d8(t.y,n.y)\u0026\u0026t.z===n.z)}),r=i.route[0],s=i.route.at(-1);if(!t||!r||!s)return!1;const a=e.portPoints.filter(t=\u003et.connectionName===i.connectionName);if(!a.some(t=\u003en(r,t))||!a.some(t=\u003en(s,t)))return!1;const c=o.get(i.connectionName)??[];c.push({start:r,end:s}),o.set(i.connectionName,c)}const i=(t,e,i)=\u003e{if(n(e,i))return!0;const r=o.get(t)??[],s=[],a=new Set;for(const[t,o]of r.entries())(n(e,o.start)||n(e,o.end))\u0026\u0026(s.push(t),a.add(t));for(;s.length\u003e0;){const t=r[s.pop()];if(n(i,t.start)||n(i,t.end))return!0;for(const[e,o]of r.entries())a.has(e)||(n(t.start,o.start)||n(t.start,o.end)||n(t.end,o.start)||n(t.end,o.end))\u0026\u0026(a.add(e),s.push(e))}return!1},r=e.portPointsInPairs??[];if(r.length\u003e0)return r.every(([t,e])=\u003ei(t.connectionName,t,e));const s=new Map;for(const t of e.portPoints){const e=s.get(t.connectionName)??[];e.push(t),s.set(t.connectionName,e)}return[...s].every(([,t])=\u003eDr(t).every(([t,e])=\u003ei(t.connectionName,t,e)))})(a,e.nodeWithPortPoints)},m8=class{constructor(t,e=n8,n={}){this.autorouterVersion=t,this.serverUrl=e;const{cacheVersion:o}=n;if(void 0!==o\u0026\u00260===o.trim().length)throw new Error(\"hd-cache2 cacheVersion must not be empty\");this.cacheVersion=o}autorouterVersion;serverUrl;cacheVersion;stats={batchRequestsStarted:0,batchRequestsCompleted:0,batchItemsStarted:0,batchBodyBytesStarted:0,batchMaxBodyBytes:0,batchCacheMisses:0,singleRequestsStarted:0,batchInvalidLines:0,batchUnknownRequestIds:0,batchDuplicateRequestIds:0};solveMany(t){const e=t.map((t,e)=\u003ethis.createPendingSolve(String(e),t)),n=e.filter(t=\u003enull!==t.serializedItem),{batches:o,singletonSolves:i}=this.prepareBatches(n);for(const t of o)this.fetchBatch(t);for(const t of i)this.launchSingleSolve(t);return e.map(t=\u003et.promise)}createPendingSolve(t,e){let n;const o={requestId:t,input:e,serializedItem:null,promise:new Promise(t=\u003e{n=t}),resolve:n,settled:!1,singleSolveStarted:!1};try{o.serializedItem=JSON.stringify({requestId:t,input:e})}catch(t){this.settleWithFallback(o,\"request_serialization_error\",a8(t))}return o}settle(t,e){t.settled||(t.settled=!0,t.resolve(e))}settleWithFallback(t,e,n){this.settle(t,{kind:\"local-fallback\",reason:e,error:n})}parseSuccessfulResponse(t,e){if(!t||\"object\"!=typeof t||Array.isArray(t))throw new s8(\"invalid_response\",\"hd-cache2 returned a non-object response\");const n=t;if(!0!==n.ok)throw new s8(\"remote_error\",\"string\"==typeof n.message?n.message:\"hd-cache2 returned an unsuccessful response\");if(n.autorouterVersion!==this.autorouterVersion)throw new s8(\"version_mismatch\",`hd-cache2 returned autorouter version ${String(n.autorouterVersion)}, expected ${this.autorouterVersion}`);if(n.cacheVersion!==this.cacheVersion)throw new s8(\"cache_version_mismatch\",`hd-cache2 returned cache version ${String(n.cacheVersion)}, expected ${String(this.cacheVersion)}`);if(\"cache\"!==n.source\u0026\u0026\"solver\"!==n.source)throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid cache source\");if(\"ordinary\"!==n.solutionStage\u0026\u0026\"regional-fallback\"!==n.solutionStage)throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid solution stage\");if(\"regional-fallback\"===n.solutionStage\u0026\u0026(!e.enableRegionalFallback||\"string\"!=typeof n.ordinaryFailure||0===n.ordinaryFailure.length))throw new s8(\"invalid_response\",\"hd-cache2 returned invalid regional fallback metadata\");if(\"ordinary\"===n.solutionStage\u0026\u0026Object.prototype.hasOwnProperty.call(n,\"ordinaryFailure\"))throw new s8(\"invalid_response\",\"hd-cache2 returned regional metadata on an ordinary result\");if(\"ordinary\"===n.solutionStage\u0026\u0026\"failed\"===n.status\u0026\u0026e.enableRegionalFallback)throw new s8(\"invalid_response\",\"hd-cache2 returned an intermediate ordinary failure\");if(\"solved\"===n.status\u0026\u0026p8(n.routes,e,n.solutionStage))return n;if(\"failed\"===n.status\u0026\u0026\"string\"==typeof n.error\u0026\u0026n.error.length\u003e0)return n;throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid solve result\")}parseBatchCacheMiss(t){if(!1!==t.ok||\"CACHE_MISS\"!==t.code)return null;if(t.autorouterVersion!==this.autorouterVersion)throw new s8(\"version_mismatch\",`hd-cache2 returned autorouter version ${String(t.autorouterVersion)}, expected ${this.autorouterVersion}`);if(t.cacheVersion!==this.cacheVersion)throw new s8(\"cache_version_mismatch\",`hd-cache2 returned cache version ${String(t.cacheVersion)}, expected ${String(this.cacheVersion)}`);if(\"string\"!=typeof t.message)throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid cache miss response\");return t}async fetchSingle(t){const e=new AbortController;let n=!1;const o=setTimeout(()=\u003e{n=!0,e.abort(new Error(\"hd-cache2 transport timed out after 310000ms\"))},o8);o.unref?.();try{const n={autorouterVersion:this.autorouterVersion,...void 0===this.cacheVersion?{}:{cacheVersion:this.cacheVersion},input:t.input};let o;try{o=JSON.stringify(n)}catch(t){throw new s8(\"request_serialization_error\",a8(t))}const r=await fetch((i=this.serverUrl,/\\/solve\\/?$/.test(i)?i.replace(/\\/+$/,\"\"):`${i.replace(/\\/+$/,\"\")}/solve`),{method:\"POST\",headers:{accept:\"application/json\",\"content-type\":\"application/json\"},body:o,signal:e.signal}),s=await r.text();let a=null;try{a=s?JSON.parse(s):null}catch{if(!r.ok)throw new s8(\"http_error\",`hd-cache2 request failed with status ${r.status}`);throw new s8(\"invalid_json\",`hd-cache2 returned invalid JSON with status ${r.status}`)}if(!r.ok){const t=a\u0026\u0026\"object\"==typeof a\u0026\u0026\"message\"in a\u0026\u0026\"string\"==typeof a.message?a.message:`hd-cache2 request failed with status ${r.status}`;throw new s8(\"http_error\",t)}this.settle(t,{kind:\"remote\",response:this.parseSuccessfulResponse(a,t.input)})}catch(e){const o=e instanceof s8?e.reason:n?\"transport_timeout\":\"transport_error\";this.settleWithFallback(t,o,a8(e))}finally{clearTimeout(o)}var i}launchSingleSolve(t){t.singleSolveStarted||t.settled||(t.singleSolveStarted=!0,this.stats.singleRequestsStarted+=1,this.fetchSingle(t))}handleBatchResponseLine(t,e,n){if(0===t.trim().length)return;if(t.length\u003er8)throw new s8(\"response_too_large\",\"hd-cache2 returned an oversized batch result line\");let o;try{o=JSON.parse(t)}catch{return void(this.stats.batchInvalidLines+=1)}if(!o||\"object\"!=typeof o||Array.isArray(o))return void(this.stats.batchInvalidLines+=1);const i=o,r=i.requestId;if(\"string\"!=typeof r)return void(this.stats.batchInvalidLines+=1);const s=e.get(r);if(s)if(n.has(r))this.stats.batchDuplicateRequestIds+=1;else{n.add(r);try{if(this.parseBatchCacheMiss(i))return this.stats.batchCacheMisses+=1,void this.launchSingleSolve(s);this.settle(s,{kind:\"remote\",response:this.parseSuccessfulResponse(i,s.input)})}catch(t){this.stats.batchInvalidLines+=1,this.settleWithFallback(s,t instanceof s8?t.reason:\"invalid_response\",a8(t))}}else this.stats.batchUnknownRequestIds+=1}async readBatchResponse(t,e){if(!t.body)throw new s8(\"invalid_response\",\"hd-cache2 returned an empty batch response body\");const n=new Map(e.items.map(t=\u003e[t.requestId,t])),o=new Set,i=new TextDecoder,r=t.body.getReader();let s=\"\";for(;o.size\u003ce.items.length;){const{done:t,value:e}=await r.read();if(s+=i.decode(e,{stream:!t}),s.length\u003er8\u0026\u0026!s.includes(\"\\n\"))throw new s8(\"response_too_large\",\"hd-cache2 returned an oversized unterminated batch result line\");let a=s.indexOf(\"\\n\");for(;a\u003e=0;){const t=s.slice(0,a);s=s.slice(a+1),this.handleBatchResponseLine(t,n,o),a=s.indexOf(\"\\n\")}if(t){s.trim().length\u003e0\u0026\u0026this.handleBatchResponseLine(s,n,o);break}}if(o.size!==e.items.length)for(const t of e.items)o.has(t.requestId)||this.settleWithFallback(t,\"missing_response\",`hd-cache2 batch ended without result ${t.requestId}`);else await r.cancel().catch(()=\u003e{})}async fetchBatch(t){const e=new AbortController;let n=!1;const o=setTimeout(()=\u003e{n=!0,e.abort(new Error(\"hd-cache2 batch transport timed out after 310000ms\"))},o8);o.unref?.(),this.stats.batchRequestsStarted+=1,this.stats.batchItemsStarted+=t.items.length,this.stats.batchBodyBytesStarted+=t.bodyBytes,this.stats.batchMaxBodyBytes=Math.max(this.stats.batchMaxBodyBytes,t.bodyBytes);try{const n=await fetch((t=\u003e{const e=t.replace(/\\/+$/,\"\");return/\\/solve-batch$/.test(e)?e:/\\/solve$/.test(e)?e.replace(/\\/solve$/,\"/solve-batch\"):`${e}/solve-batch`})(this.serverUrl),{method:\"POST\",headers:{accept:\"application/x-ndjson\",\"content-type\":\"application/json\"},body:t.body,signal:e.signal});if(!n.ok){const t=await n.text().catch(()=\u003e\"\");let e=`hd-cache2 batch request failed with status ${n.status}`;try{const n=t?JSON.parse(t):null;n\u0026\u0026\"object\"==typeof n\u0026\u0026\"message\"in n\u0026\u0026\"string\"==typeof n.message\u0026\u0026(e=n.message)}catch{}throw new s8(\"http_error\",e)}await this.readBatchResponse(n,t)}catch(e){const o=e instanceof s8?e.reason:n?\"transport_timeout\":\"transport_error\";for(const n of t.items)n.singleSolveStarted||this.settleWithFallback(n,o,a8(e))}finally{clearTimeout(o),this.stats.batchRequestsCompleted+=1}}prepareBatches(t){const e=new TextEncoder,n=void 0===this.cacheVersion?\"\":`,\"cacheVersion\":${JSON.stringify(this.cacheVersion)}`,o=`{\"autorouterVersion\":${JSON.stringify(this.autorouterVersion)}${n},\"items\":[`,i=e.encode(o+\"]}\").byteLength,r=[],s=[];let a=[],c=i;const l=()=\u003e{0!==a.length\u0026\u0026(r.push({body:`${o}${a.map(t=\u003et.serializedItem).join(\",\")}]}`,bodyBytes:c,items:a}),a=[],c=i)};for(const n of t){const t=e.encode(n.serializedItem).byteLength,o=0===a.length?0:1;i+t\u003ei8?(l(),s.push(n)):((a.length\u003e=100||c+o+t\u003ei8)\u0026\u0026l(),a.push(n),c+=(1===a.length?0:1)+t)}return l(),{batches:r,singletonSolves:s}}},g8=\"ordinary_then_regional_without_fixed_copper_v1\",f8=class extends VQ{autorouterVersion;hdCache2ServerUrl;hdCache2CacheVersion;requestTimeoutMs;hdCache2Client;launchedRemoteSolves=!1;waitingForRemoteNode=null;remoteRequestByNode=new Map;remoteResultByNode=new Map;logicallyTimedOutNodes=new Set;constructor({autorouterVersion:t,hdCache2ServerUrl:e,hdCache2CacheVersion:n,requestTimeoutMs:o,...i}){if(super(i),1!==i.effort)throw new Error(`Pipeline9 networked high-density routing requires effort=1, received ${i.effort}`);if(this.requestTimeoutMs=o??3e4,!Number.isFinite(this.requestTimeoutMs)||this.requestTimeoutMs\u003c=0)throw new Error(`Pipeline9 network request timeout must be a positive number, received ${this.requestTimeoutMs}`);this.autorouterVersion=t,this.hdCache2ServerUrl=e??n8,this.hdCache2CacheVersion=n,this.hdCache2Client=new m8(this.autorouterVersion,this.hdCache2ServerUrl,{cacheVersion:n}),this.pendingEffects=[],this.stats={...this.stats,remoteRequestsStarted:0,remoteRequestsCompleted:0,remoteBatchRequestsStarted:0,remoteBatchRequestsCompleted:0,remoteBatchItemsStarted:0,remoteBatchBodyBytesStarted:0,remoteBatchMaxBodyBytes:0,remoteBatchCacheMisses:0,remoteSingleRequestsStarted:0,remoteBatchInvalidLines:0,remoteBatchUnknownRequestIds:0,remoteBatchDuplicateRequestIds:0,remoteCacheHits:0,remoteSolverResults:0,remoteSolvedResults:0,remoteFailedResults:0,remoteOrdinaryResults:0,remoteRegionalFallbackResults:0,remoteRegionalFallbackResultsApplied:0,remoteRegionalFallbackResultsDeferredToLocal:0,remoteTransportFallbacks:0,remoteLogicalTimeoutFallbacks:0,remoteFallbackReasonCounts:{}}}getSolverName(){return\"Pipeline9NetworkedHighDensitySolver\"}async waitForAllRemoteRequests(){const t=[...this.remoteRequestByNode.values()];0!==t.length?(await Promise.all(t.map(({promise:t})=\u003et)),this.syncClientStats()):this.syncClientStats()}createNodeInput(t){const e=this.enableRegionalFallback?Q9({nodeWithPortPoints:t,connMap:this.connMap,obstacles:this.obstacles,obstacleMargin:this.obstacleMargin,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter}):{connectivityNetMap:{},obstacles:[]},n=e8({nodeWithPortPoints:t,connMap:this.connMap,colorMap:this.colorMap,obstacles:this.enableRegionalFallback?e.obstacles:this.obstacles,obstacleMargin:this.obstacleMargin,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter});return{solvePolicy:g8,enableRegionalFallback:this.enableRegionalFallback,nodeWithPortPoints:t,connectivityNetMap:t8(n.connectivityNetMap,e.connectivityNetMap),colorMap:n.colorMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:1,obstacles:n.obstacles,regionalObstacles:e.obstacles,layerCount:this.layerCount,nodePf:this.nodePfById.get(t.capacityMeshNodeId)??null}}syncClientStats(){const t=this.hdCache2Client.stats;this.stats.remoteBatchRequestsStarted=t.batchRequestsStarted,this.stats.remoteBatchRequestsCompleted=t.batchRequestsCompleted,this.stats.remoteBatchItemsStarted=t.batchItemsStarted,this.stats.remoteBatchBodyBytesStarted=t.batchBodyBytesStarted,this.stats.remoteBatchMaxBodyBytes=t.batchMaxBodyBytes,this.stats.remoteBatchCacheMisses=t.batchCacheMisses,this.stats.remoteSingleRequestsStarted=t.singleRequestsStarted,this.stats.remoteBatchInvalidLines=t.batchInvalidLines,this.stats.remoteBatchUnknownRequestIds=t.batchUnknownRequestIds,this.stats.remoteBatchDuplicateRequestIds=t.batchDuplicateRequestIds}recordFallbackReason(t){const e=this.stats.remoteFallbackReasonCounts;e[t]=(e[t]??0)+1}trackRemoteSolve(t,e){const n=performance.now()+this.requestTimeoutMs;this.stats.remoteRequestsStarted+=1;const o=e.then(e=\u003e{const n=this.logicallyTimedOutNodes.has(t);n||this.remoteResultByNode.set(t,e),\"remote\"===e.kind?(\"cache\"===e.response.source\u0026\u0026(this.stats.remoteCacheHits+=1),\"solver\"===e.response.source\u0026\u0026(this.stats.remoteSolverResults+=1),\"solved\"===e.response.status?this.stats.remoteSolvedResults+=1:this.stats.remoteFailedResults+=1):n||(this.stats.remoteTransportFallbacks+=1,this.recordFallbackReason(e.reason)),this.stats.remoteRequestsCompleted+=1,this.syncClientStats()});this.remoteRequestByNode.set(t,{promise:o,deadlineAt:n})}launchRemoteSolves(){const t=[],e=[...this.unsolvedNodePortPoints].reverse();for(const n of e)try{t.push({node:n,input:this.createNodeInput(n)})}catch(t){this.trackRemoteSolve(n,Promise.resolve({kind:\"local-fallback\",reason:\"request_serialization_error\",error:t instanceof Error?t.message:String(t)}))}const n=this.hdCache2Client.solveMany(t.map(({input:t})=\u003et));for(const[e,o]of n.entries())this.trackRemoteSolve(t[e].node,o);this.syncClientStats()}async waitForCurrentRemoteNode(t,e){const n=e.deadlineAt-performance.now();if(n\u003c=0)return void this.recordLogicalTimeout(t);let o;const i=await Promise.race([e.promise.then(()=\u003e\"request-settled\"),new Promise(t=\u003e{o=setTimeout(()=\u003et(\"logical-timeout\"),n)})]);void 0!==o\u0026\u0026clearTimeout(o),\"logical-timeout\"===i\u0026\u0026this.recordLogicalTimeout(t)}recordLogicalTimeout(t){this.logicallyTimedOutNodes.add(t),this.stats.remoteLogicalTimeoutFallbacks+=1,this.stats.remoteTransportFallbacks+=1,this.recordFallbackReason(\"logical_timeout\")}startRegularSolver(t){const e=this.remoteResultByNode.get(t);if(!e){const e=this.remoteRequestByNode.get(t);if(e){this.waitingForRemoteNode=t;const n=this.waitForCurrentRemoteNode(t,e);n.then(()=\u003e{this.waitingForRemoteNode===t\u0026\u0026(this.pendingEffects=[])});const o={name:`hd-cache2:${t.capacityMeshNodeId}`,promise:n};return void(this.pendingEffects=[o])}return void super.startRegularSolver(t)}this.applyRemoteResultToRegularNode(t,e)}applyRemoteResultToRegularNode(t,e){if(\"local-fallback\"!==e.kind){if(this.stats.regularNodeCount=Number(this.stats.regularNodeCount??0)+1,this.activeNode=t,\"regional-fallback\"===e.response.solutionStage){if(this.stats.remoteRegionalFallbackResults+=1,!this.canUseNoFixedCopperRegionalResult(t))return this.stats.remoteRegionalFallbackResultsDeferredToLocal+=1,void this.finishRegularSolverFailure(e.response.ordinaryFailure);this.stats.remoteRegionalFallbackResultsApplied+=1,this.stats.fallbackNodeCount=Number(this.stats.fallbackNodeCount??0)+1}else this.stats.remoteOrdinaryResults+=1;if(\"failed\"===e.response.status)return this.error=e.response.error,this.failed=!0,void(this.activeNode=null);this.finishActiveNode(e.response.routes)}else super.startRegularSolver(t)}canUseNoFixedCopperRegionalResult(t){const e={...YQ(t,this.connMap),availableZ:Array.from({length:this.layerCount},(t,e)=\u003ee)},n=$K(e,this.getUpdatedFixedHdRoutes());return 0===n.fixedRouteSectionsByConnectionName.size\u0026\u00260===n.fixedObstacleRoutes.length}_step(){if(this.syncClientStats(),this.launchedRemoteSolves||(this.launchedRemoteSolves=!0,this.launchRemoteSolves()),this.waitingForRemoteNode){const t=this.waitingForRemoteNode;if(this.logicallyTimedOutNodes.has(t))return this.waitingForRemoteNode=null,this.pendingEffects=[],void super.startRegularSolver(t);const e=this.remoteResultByNode.get(t);if(!e)return;return this.waitingForRemoteNode=null,this.pendingEffects=[],void this.applyRemoteResultToRegularNode(t,e)}super._step()}},y8=class extends H9{hdCache2ServerUrl;hdCache2CacheVersion;getSolverName(){return\"AutoroutingPipelineSolver9_Networked\"}constructor(t,e={}){if(super(t,e),1!==this.effort)throw new Error(`AutoroutingPipelineSolver9_Networked is only available at effort=1, received ${this.effort}`);this.hdCache2ServerUrl=e.hdCache2ServerUrl??n8,this.hdCache2CacheVersion=e.hdCache2CacheVersion,this.replaceHighDensityPipelineStep()}replaceHighDensityPipelineStep(){const t=this.pipelineDef.findIndex(t=\u003e\"highDensityRouteSolver\"===t.solverName),e=this.pipelineDef[t];if(!e)throw new Error(\"Pipeline9 highDensityRouteSolver step is missing\");const n=e.getConstructorParams;this.pipelineDef[t]={...e,solverClass:f8,getConstructorParams:t=\u003e{const[e]=n(t);return[{...e,autorouterVersion:G9,hdCache2ServerUrl:t.hdCache2ServerUrl,hdCache2CacheVersion:t.hdCache2CacheVersion}]}}}async stepAsync(){if(this.solved||this.failed)return;this.step();const t=vX(this);0!==t.length\u0026\u0026(await Promise.race(t.map(t=\u003et.promise.then(()=\u003et.name,()=\u003et.name))),this.solved||this.failed||this.step())}async solveAsync(){const t=Date.now();for(;!this.solved\u0026\u0026!this.failed;)await this.stepAsync();this.timeToSolve=Date.now()-t}async solveUntilPhaseAsync(t){for(;this.getCurrentPhase()!==t\u0026\u0026!this.solved\u0026\u0026!this.failed;)await this.stepAsync()}solve(){throw new Error(\"AutoroutingPipelineSolver9_Networked requires async execution. Use solveAsync() or stepAsync().\")}solveUntilPhase(t){throw new Error(\"AutoroutingPipelineSolver9_Networked requires solveUntilPhaseAsync().\")}};function _8(t){if(t.solvePolicy!==g8)throw new Error(`Unsupported Pipeline9 networked solve policy ${String(t.solvePolicy)}`);if(1!==t.effort)throw new Error(`Pipeline9 networked high-density solving requires effort=1, received ${t.effort}`);const e=new ti(t.connectivityNetMap),n=(({input:t,connMap:e})=\u003e{const n=XQ({nodeWithPortPoints:t.nodeWithPortPoints,colorMap:t.colorMap,connMap:e,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:{[t.nodeWithPortPoints.capacityMeshNodeId]:t.nodePf},obstacles:t.obstacles,layerCount:t.layerCount});return n.solve(),n.solved?{status:\"solved\",routes:n.routes}:{status:\"failed\",error:n.error||\"Pipeline9 ordinary high-density solver failed\"}})({input:t,connMap:e});if(\"solved\"===n.status)return{status:\"solved\",solutionStage:\"ordinary\",routes:n.routes};const o=n.error;if(!t.enableRegionalFallback)return{status:\"failed\",solutionStage:\"ordinary\",error:`Pipeline9 regular high-density routing failed: ${o}`};const i=YQ(t.nodeWithPortPoints,e),r=$K({...i,availableZ:Array.from({length:t.layerCount},(t,e)=\u003ee)},[]),s=new FQ({nodeWithPortPoints:r.nodeWithPortPoints,colorMap:t.colorMap,connMap:e,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:{[t.nodeWithPortPoints.capacityMeshNodeId]:t.nodePf},obstacles:t.regionalObstacles,layerCount:t.layerCount});if(s.solve(),s.solved)return{status:\"solved\",solutionStage:\"regional-fallback\",ordinaryFailure:o,routes:s.getOutput()};return{status:\"failed\",solutionStage:\"regional-fallback\",ordinaryFailure:o,error:[`Pipeline9 primary high-density routing failed: regular high-density routing failed: ${o}`,`regional fallback failed: ${s.error||\"Pipeline9 regional fallback solver failed\"}`].join(\"; \")}}var b8=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\u0026\u0026!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026this.tryFinalAcceptance(),!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),\"computeProgress\"in this\u0026\u0026(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error(\"getConstructorParams not implemented\")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved\u0026\u0026!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 x8(t){const e=`${t.connectionName}:source-${t.sourcePointIndex}`;return{boundaryExitPointId:`fanout-exit:${e}`,planeExitPointId:`fanout-plane:${e}`,traceId:`fanout:${e}`,viaObstacleId:`fanout-via:${e}`,planeEndpointPointId:`fanout-plane-endpoint-point:${e}`,planeEndpointTraceId:`fanout-plane-endpoint:${e}`,planeEndpointViaObstacleId:`fanout-plane-endpoint-via:${e}`}}function v8(t,e,n=!1){const o=n?t.planeEndpointVia:t.via;if(!o)return null;const i=o.spanLayers.map(n=\u003e{const o=e.indexOf(n);if(o\u003c0)throw new Error(`FanoutSolver: via for \"${t.connectionName}\" uses unknown layer \"${n}\"`);return o}),r=x8(t);return{obstacleId:n?r.planeEndpointViaObstacleId:r.viaObstacleId,type:\"rect\",center:o.center,width:o.diameter,height:o.diameter,layers:o.spanLayers,zLayers:i,__zLayers:i,connectedTo:[t.connectionName,t.trace.pcb_trace_id]}}function S8(t){const{inputSrj:e,plans:n,layerNames:o}=t,i=e.connections.map(t=\u003e({...t,pointsToConnect:t.pointsToConnect.map(t=\u003e({...t}))})),r=[],s=new Set;for(const t of n){const e=i[t.connectionIndex];if(!e)throw new Error(`FanoutSolver: output connection index ${t.connectionIndex} is missing`);const n=x8(t);e.pointsToConnect[t.sourcePointIndex]={x:t.exitPoint.x,y:t.exitPoint.y,layer:t.targetLayer,pointId:\"plane\"===t.termination.type?n.planeExitPointId:n.boundaryExitPointId},\"plane\"===t.termination.type\u0026\u0026s.add(t.connectionName);const a=v8(t,o);a\u0026\u0026r.push(a);const c=v8(t,o,!0);c\u0026\u0026r.push(c)}const a=n.flatMap(t=\u003e[t.trace,...t.planeEndpointTrace?[t.planeEndpointTrace]:[]]),c=a.flatMap(t=\u003et.route.filter(t=\u003e\"x\"in t\u0026\u0026\"y\"in t)),l=Math.max(e.defaultObstacleMargin??0,e.minTraceWidth),d=0===c.length?{...e.bounds}:{minX:Math.min(e.bounds.minX,...c.map(t=\u003et.x-l)),maxX:Math.max(e.bounds.maxX,...c.map(t=\u003et.x+l)),minY:Math.min(e.bounds.minY,...c.map(t=\u003et.y-l)),maxY:Math.max(e.bounds.maxY,...c.map(t=\u003et.y+l))};return{...e,fanoutPlaneConnectivity:n.flatMap(t=\u003e\"plane\"===t.termination.type?[{connectionName:t.connectionName,layer:t.termination.layer}]:[]),bounds:d,connections:i.filter(t=\u003e!s.has(t.name)),buses:e.buses?.map(t=\u003e({...t,connectionNames:t.connectionNames.filter(t=\u003e!s.has(t))})).filter(t=\u003et.connectionNames.length\u003e0),obstacles:[...e.obstacles.map(t=\u003e({...t,center:{...t.center},layers:[...t.layers],connectedTo:[...t.connectedTo]})),...r],traces:[...(e.traces??[]).map(t=\u003e({...t,route:t.route.map(t=\u003e({...t}))})),...a]}}var I8=1e-9;function C8(t){return\"circle\"===t.shape}function P8(t,e){const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}}function M8(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function N8(t,e,n){const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r\u003cI8?0:((t.x-e.x)*o+(t.y-e.y)*i)/r,a=Math.max(0,Math.min(1,s));return Math.hypot(t.x-(e.x+a*o),t.y-(e.y+a*i))}function w8(t,e,n){return(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x)}function T8(t,e,n,o){return function(t,e,n,o){const i=w8(n,o,t),r=w8(n,o,e),s=w8(t,e,n),a=w8(t,e,o);return(i\u003e0\u0026\u0026r\u003c0||i\u003c0\u0026\u0026r\u003e0)\u0026\u0026(s\u003e0\u0026\u0026a\u003c0||s\u003c0\u0026\u0026a\u003e0)}(t,e,n,o)?0:Math.min(N8(t,n,o),N8(e,n,o),N8(n,t,e),N8(o,t,e))}function R8(t,e,n=1e-9){if(C8(e))return M8(t,e.center)\u003c=e.width/2+n;const o=P8(t,e);return Math.abs(o.x)\u003c=e.width/2+n\u0026\u0026Math.abs(o.y)\u003c=e.height/2+n}function E8(t,e){if(C8(e))return Math.max(0,M8(t,e.center)-e.width/2);const n=P8(t,e),o=Math.max(Math.abs(n.x)-e.width/2,0),i=Math.max(Math.abs(n.y)-e.height/2,0);return Math.hypot(o,i)}function A8(t,e){if(C8(e))return Math.max(0,N8(e.center,t.start,t.end)-e.width/2);const n=P8(t.start,e),o=P8(t.end,e);if(Math.abs(n.x)\u003c=e.width/2+I8\u0026\u0026Math.abs(n.y)\u003c=e.height/2+I8)return 0;if(Math.abs(o.x)\u003c=e.width/2+I8\u0026\u0026Math.abs(o.y)\u003c=e.height/2+I8)return 0;const i=-e.width/2,r=e.width/2,s=-e.height/2,a=e.height/2,c=[{x:i,y:s},{x:r,y:s},{x:r,y:a},{x:i,y:a}];let l=Number.POSITIVE_INFINITY;for(let t=0;t\u003cc.length;t++)l=Math.min(l,T8(n,o,c[t],c[(t+1)%c.length]));return l}function O8(t,e,n){if(t.layer!==e.layer)return!0;const o=(t.width+e.width)/2+n;return T8(t.start,t.end,e.start,e.end)\u003e=o-I8}function k8(t){if(!Number.isInteger(t)||t\u003c1)throw new Error(`FanoutSolver: layerCount must be a positive integer, received ${t}`);return 1===t?[\"top\"]:2===t?[\"top\",\"bottom\"]:[\"top\",...Array.from({length:t-2},(t,e)=\u003e`inner${e+1}`),\"bottom\"]}function L8(t,e,n){const o=n.indexOf(t),i=n.indexOf(e);if(o\u003c0||i\u003c0)throw new Error(`FanoutSolver: cannot build via span from \"${t}\" to \"${e}\"`);const r=Math.min(o,i),s=Math.max(o,i);return n.slice(r,s+1)}var D8=new WeakMap;function z8(t){return t.netConnectionName??t.rootConnectionName??t.name}function F8(t,e,n){if(!e)return!1;const o=t.get(e)??new Set,i=o.size;return o.add(n),t.set(e,o),o.size!==i}function B8(t,e){const n=new Set;for(const o of e)for(const e of t.get(o)??[])n.add(e);return n}function j8(t){const e=D8.get(t);if(e)return e;const n=function(t){const e=new Map,n=new Map;for(const o of t.connections){const t=z8(o);e.set(o.name,t),F8(n,o.name,t),F8(n,o.rootConnectionName,t),F8(n,o.netConnectionName,t);for(const e of o.pointsToConnect)F8(n,e.pointId,t),F8(n,e.pcb_port_id,t)}for(const o of t.traces??[]){const t=o.connection_name?e.get(o.connection_name):void 0;if(t){F8(n,o.pcb_trace_id,t);for(const e of o.connectsTo??[])F8(n,e,t)}}for(let e=0;e\u003c2;e++){let e=!1;for(const o of t.obstacles){const t=B8(n,o.connectedTo);if(1!==t.size)continue;const i=[...t][0];for(const t of o.connectedTo)e=F8(n,t,i)||e}if(!e)break}const o=new Map,i=t=\u003e{const e=o.get(t)??t;if(o.set(t,e),e===t)return t;const n=i(e);return o.set(t,n),n},r=(t,e)=\u003e{const n=i(t),r=i(e);n!==r\u0026\u0026o.set(r,n)};for(const t of n.values()){const[e,...n]=[...t];if(e)for(const t of n)r(e,t)}for(const e of[...t.obstacles.map(t=\u003et.connectedTo),...(t.traces??[]).map(t=\u003et.connectsTo??[])]){const[t,...o]=[...B8(n,e)];if(t)for(const e of o)r(t,e)}for(const[t,n]of e)e.set(t,i(n));for(const[t,e]of n)n.set(t,new Set([...e].map(t=\u003ei(t))));return{connectionNetKeys:e,tokenNetKeys:n}}(t);return D8.set(t,n),n}function $8(t,e,n){const o=j8(t),i=o.connectionNetKeys.get(e),r=o.connectionNetKeys.get(n);return void 0!==i\u0026\u0026i===r}function Y8(t,e,n){const o=j8(t),i=o.connectionNetKeys.get(n);return!!i\u0026\u0026e.connectedTo.some(t=\u003eo.tokenNetKeys.get(t)?.has(i))}var X8=1e-6;function V8(t){return\"layer\"in t?[t.layer]:t.layers}function W8(t,e){return t.some(t=\u003ee.includes(t))}function H8(t,e){const n=[];let o;for(const i of t.route)\"via\"!==i.route_type?\"wire\"===i.route_type\u0026\u0026(o\u0026\u0026o.layer===i.layer\u0026\u0026M8(o,i)\u003eX8\u0026\u0026n.push({type:\"segment\",segment:{start:{x:o.x,y:o.y},end:{x:i.x,y:i.y},width:i.width,layer:i.layer}}),o=i):(n.push({type:\"via\",center:{x:i.x,y:i.y},diameter:i.via_diameter??0,layers:L8(i.from_layer,i.to_layer,e)}),o=void 0);return n}function G8(t,e){return\"plane\"===t.type\u0026\u0026\"plane\"===e.type?t.layer===e.layer:\"plane\"===t.type\u0026\u0026\"via\"===e.type?e.layers.includes(t.layer):\"via\"===t.type\u0026\u0026\"plane\"===e.type?G8(e,t):\"plane\"===t.type\u0026\u0026\"segment\"===e.type?t.layer===e.segment.layer:\"segment\"===t.type\u0026\u0026\"plane\"===e.type?G8(e,t):\"endpoint\"===t.type\u0026\u0026\"endpoint\"===e.type?W8(t.layers,e.layers)\u0026\u0026M8(t.point,e.point)\u003c=X8:\"endpoint\"===t.type\u0026\u0026\"obstacle\"===e.type?W8(t.layers,e.obstacle.layers)\u0026\u0026R8(t.point,e.obstacle,X8):\"obstacle\"===t.type\u0026\u0026\"endpoint\"===e.type?G8(e,t):\"endpoint\"===t.type\u0026\u0026\"segment\"===e.type?t.layers.includes(e.segment.layer)\u0026\u0026N8(t.point,e.segment.start,e.segment.end)\u003c=e.segment.width/2+X8:\"segment\"===t.type\u0026\u0026\"endpoint\"===e.type?G8(e,t):\"endpoint\"===t.type\u0026\u0026\"via\"===e.type?W8(t.layers,e.layers)\u0026\u0026M8(t.point,e.center)\u003c=e.diameter/2+X8:\"via\"===t.type\u0026\u0026\"endpoint\"===e.type?G8(e,t):\"obstacle\"===t.type\u0026\u0026\"segment\"===e.type?t.obstacle.layers.includes(e.segment.layer)\u0026\u0026A8(e.segment,t.obstacle)\u003c=e.segment.width/2+X8:\"segment\"===t.type\u0026\u0026\"obstacle\"===e.type?G8(e,t):\"obstacle\"===t.type\u0026\u0026\"via\"===e.type?W8(t.obstacle.layers,e.layers)\u0026\u0026E8(e.center,t.obstacle)\u003c=e.diameter/2+X8:\"via\"===t.type\u0026\u0026\"obstacle\"===e.type?G8(e,t):\"segment\"===t.type\u0026\u0026\"segment\"===e.type?t.segment.layer===e.segment.layer\u0026\u0026T8(t.segment.start,t.segment.end,e.segment.start,e.segment.end)\u003c=(t.segment.width+e.segment.width)/2+X8:\"segment\"===t.type\u0026\u0026\"via\"===e.type?e.layers.includes(t.segment.layer)\u0026\u0026N8(e.center,t.segment.start,t.segment.end)\u003c=e.diameter/2+t.segment.width/2+X8:\"via\"===t.type\u0026\u0026\"segment\"===e.type?G8(e,t):\"via\"===t.type\u0026\u0026\"via\"===e.type\u0026\u0026(W8(t.layers,e.layers)\u0026\u0026M8(t.center,e.center)\u003c=(t.diameter+e.diameter)/2+X8)}var U8=class{parent;constructor(t){this.parent=Array.from({length:t},(t,e)=\u003ee)}find(t){const e=this.parent[t];if(e===t)return t;const n=this.find(e);return this.parent[t]=n,n}union(t,e){const n=this.find(t),o=this.find(e);n!==o\u0026\u0026(this.parent[o]=n)}};function Z8(t,e,n){return Boolean(e.connection_name\u0026\u0026$8(t,e.connection_name,n.name))}function q8(t){const{inputSrj:e,routedSrj:n}=t,o=n.fanoutPlaneConnectivity,i=k8(n.layerCount),r=new Map;for(const t of e.connections){const e=z8(t),n=r.get(e)??[];n.push(t),r.set(e,n)}const s=[];let a=0,c=0;for(const t of r.values()){const r=t[0],l=t.flatMap(t=\u003et.pointsToConnect.map((e,n)=\u003e({type:\"endpoint\",connectionName:t.name,endpointIndex:n,point:e,layers:V8(e)}))),d=e.obstacles.filter(t=\u003eY8(e,t,r.name)).map(t=\u003e({type:\"obstacle\",obstacle:t})),h=(n.traces??[]).filter(t=\u003eZ8(e,t,r)).flatMap(t=\u003eH8(t,i)),u=[...new Set((o??[]).flatMap(t=\u003e$8(e,t.connectionName,r.name)?[t.layer]:[]))].map(t=\u003e({type:\"plane\",layer:t})),p=[...l,...d,...h,...u],m=new U8(p.length);for(let t=0;t\u003cp.length;t++)for(let e=t+1;e\u003cp.length;e++)G8(p[t],p[e])\u0026\u0026m.union(t,e);const g=new Map;for(let t=0;t\u003cl.length;t++){const e=l[t],n=g.get(e.connectionName)??[];n[e.endpointIndex]=t,g.set(e.connectionName,n)}for(const e of t){const t=g.get(e.name)??[],n=t[0],o=void 0===n?void 0:m.find(n),i=t.flatMap((t,e)=\u003evoid 0===o||m.find(t)!==o?[e]:[]);c+=t.length-i.length,0===i.length?a++:s.push({code:\"original-endpoints-disconnected\",connectionName:e.name,disconnectedEndpointIndices:i,message:`Connection ${e.name} has no physical copper path from endpoint 0 to original endpoint${1===i.length?\"\":\"s\"} ${i.join(\", \")}`})}}const l=e.connections.reduce((t,e)=\u003et+e.pointsToConnect.length,0);return{valid:0===s.length,checkedConnectionCount:e.connections.length,connectedConnectionCount:a,checkedEndpointCount:l,connectedEndpointCount:c,issues:s}}var J8=1e-6;function K8(t){const{inputSrj:e,segment:n,bodyObstacle:o,connectionName:i}=t;if(o.connectedTo.length\u003e0||!o.componentId)return!1;const r=e.obstacles.filter(t=\u003et.componentId===o.componentId\u0026\u0026t.layers.includes(n.layer)\u0026\u0026Y8(e,t,i));for(const t of r)for(const[e,i]of[[n.start,n.end],[n.end,n.start]]){if(!R8(e,t,J8))continue;const n={x:e.x-o.center.x,y:e.y-o.center.y},r={x:i.x-e.x,y:i.y-e.y};if(n.x*r.x+n.y*r.y\u003eJ8)return!0}return!1}function Q8(t,e){return M8(t,e)\u003c=J8}function t7(t,e){t.push(e)}function e7(t){const{srj:e,trace:n,connectionName:o,layerNames:i,issues:r}=t,s=[],a=[];let c,l;for(const t of n.route){if(\"via\"===t.route_type){const s=L8(t.from_layer,t.to_layer,i);a.push({center:{x:t.x,y:t.y},diameter:t.via_diameter??e.minViaPadDiameter??e.minTraceWidth,spanLayers:s}),c\u0026\u0026Q8(c,t)\u0026\u0026c.layer===t.from_layer||t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} reaches a via without a matching ${t.from_layer} wire endpoint`}),l=t;continue}\"wire\"===t.route_type?l?(Q8(t,l)\u0026\u0026t.layer===l.to_layer||t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} does not continue from its via on ${l.to_layer}`}),c=t,l=void 0):(c\u0026\u0026(c.layer!==t.layer?t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} changes from ${c.layer} to ${t.layer} without a via`}):Q8(c,t)||s.push({start:{x:c.x,y:c.y},end:{x:t.x,y:t.y},width:t.width,layer:t.layer})),c=t):(t7(r,{code:\"unsupported-route-point\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} contains unsupported ${t.route_type} geometry`}),c=void 0,l=void 0)}return l\u0026\u0026t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} ends at a via without a wire on ${l.to_layer}`}),{trace:n,connectionName:o,segments:s,vias:a}}function n7(t){const{inputSrj:e,routedSrj:n,clearance:o}=t,i=[],r=k8(n.layerCount),s=[],a=[e,n].flatMap(t=\u003et.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({connectionName:t.name,point:e}))));for(const t of n.traces??[]){const o=t.connection_name;o\u0026\u0026e.connections.some(t=\u003et.name===o)?s.push(e7({srj:n,trace:t,connectionName:o,layerNames:r,issues:i})):t7(i,{code:\"unknown-trace-connection\",traceId:t.pcb_trace_id,...o?{connectionName:o}:{},message:`Trace ${t.pcb_trace_id} does not identify an input connection`})}for(const t of s){for(const n of t.segments)for(const r of e.obstacles){if(!r.layers.includes(n.layer)||Y8(e,r,t.connectionName))continue;if(K8({inputSrj:e,segment:n,bodyObstacle:r,connectionName:t.connectionName}))continue;const s=A8(n,r),a=n.width/2+o;s\u003ca-J8\u0026\u0026t7(i,{code:\"trace-obstacle-clearance\",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,layer:n.layer,obstacleId:r.obstacleId,message:`Trace ${t.trace.pcb_trace_id} on ${n.layer} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId}; ${a.toFixed(4)}mm is required`})}for(const n of t.vias){const r=a.find(({point:t})=\u003eM8(n.center,t)\u003c=J8);r\u0026\u0026t7(i,{code:\"via-at-endpoint\",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,otherConnectionName:r.connectionName,message:`Via in ${t.trace.pcb_trace_id} is placed directly at an original or routed connection endpoint`});for(const r of e.obstacles){if(!r.layers.some(t=\u003en.spanLayers.includes(t))||Y8(e,r,t.connectionName))continue;const s=E8(n.center,r),a=n.diameter/2+o;s\u003ca-J8\u0026\u0026t7(i,{code:\"via-obstacle-clearance\",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,obstacleId:r.obstacleId,message:`Via in ${t.trace.pcb_trace_id} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId} on its layer span; ${a.toFixed(4)}mm is required`})}}}for(let t=0;t\u003cs.length;t++){const n=s[t];for(let r=t+1;r\u003cs.length;r++){const t=s[r];if(!$8(e,n.connectionName,t.connectionName)){for(const e of n.segments){for(const r of t.segments)O8(e,r,o)||t7(i,{code:\"different-net-trace-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:e.layer,message:`Different-net traces ${n.trace.pcb_trace_id} and ${t.trace.pcb_trace_id} intersect or violate clearance on ${e.layer}`});for(const r of t.vias)!r.spanLayers.includes(e.layer)||N8(r.center,e.start,e.end)\u003e=r.diameter/2+e.width/2+o-J8||t7(i,{code:\"different-net-trace-via-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:e.layer,message:`Trace ${n.trace.pcb_trace_id} violates via clearance to ${t.trace.pcb_trace_id} on ${e.layer}`})}for(const e of n.vias){for(const r of t.segments)!e.spanLayers.includes(r.layer)||N8(e.center,r.start,r.end)\u003e=e.diameter/2+r.width/2+o-J8||t7(i,{code:\"different-net-trace-via-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:r.layer,message:`Via in ${n.trace.pcb_trace_id} violates trace clearance to ${t.trace.pcb_trace_id} on ${r.layer}`});for(const r of t.vias)!e.spanLayers.some(t=\u003er.spanLayers.includes(t))||M8(e.center,r.center)\u003e=(e.diameter+r.diameter)/2+o-J8||t7(i,{code:\"different-net-via-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,message:`Different-net vias in ${n.trace.pcb_trace_id} and ${t.trace.pcb_trace_id} violate clearance on an overlapping layer span`})}}}}return{valid:0===i.length,checkedTraceCount:n.traces?.length??0,checkedSegmentCount:s.reduce((t,e)=\u003et+e.segments.length,0),checkedViaCount:s.reduce((t,e)=\u003et+e.vias.length,0),issues:i}}var o7=1e-9;function i7(t,e){if(\"layer\"in t)return t.layer;if(e\u0026\u0026t.layers.includes(e))return e;const n=t.layers[0];if(!n)throw new Error(\"Endpoint completion received a layerless point\");return n}function r7(t){const e=[];for(const n of t)e.at(-1)\u0026\u0026M8(e.at(-1),n)\u003co7||e.push(n);return e}function s7(t,e){const n=r7(t);if(n.length\u003c3)return n;const o=[n[0]];for(let t=1;t\u003cn.length-1;t++){const i=n[t-1],r=n[t],s=n[t+1],a=M8(i,r),c=M8(r,s),l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c};if(Math.abs(l.x*d.x+l.y*d.y)\u003e1e-6){o.push(r);continue}const h=Math.min(e,a/2,c/2);o.push({x:r.x-l.x*h,y:r.y-l.y*h}),o.push({x:r.x+d.x*h,y:r.y+d.y*h})}return o.push(n.at(-1)),r7(o)}function a7(t){const{inputSrj:e,plan:n}=t,o=i7(n.targetPoint),i=function(t){const{inputSrj:e,connectionName:n,target:o,targetLayer:i}=t;return e.obstacles.find(t=\u003et.layers.includes(i)\u0026\u0026Y8(e,t,n)\u0026\u0026R8(o,t,1e-6))}({inputSrj:e,connectionName:n.connectionName,target:n.targetPoint,targetLayer:o}),r=e.obstacles.find(t=\u003et.componentId===i?.componentId\u0026\u00260===t.connectedTo.length),s=r?{x:n.targetPoint.x-r.center.x,y:n.targetPoint.y-r.center.y}:{x:n.targetPoint.x-n.sourcePoint.x,y:n.targetPoint.y-n.sourcePoint.y},a=Math.hypot(s.x,s.y),c=a\u003eo7?{x:s.x/a,y:s.y/a}:{x:1,y:0};return{outward:c,perpendicular:{x:-c.y,y:c.x}}}function c7(t){const{plan:e,branchStart:n,viaPoint:o,assignedLayerPath:i,terminalApproach:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,candidateIndex:l,chamfer:d}=t,h=i7(e.targetPoint),u=s7(i,d),p=s7([o,...r?[r]:[],e.targetPoint],d),m=u.map(t=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:s,layer:n.layer}));n.layer!==h\u0026\u0026(m.push({route_type:\"via\",x:o.x,y:o.y,from_layer:n.layer,to_layer:h,via_diameter:a,via_hole_diameter:c}),m.push({route_type:\"wire\",x:o.x,y:o.y,width:s,layer:h}));for(const t of p.slice(1))m.push({route_type:\"wire\",x:t.x,y:t.y,width:s,layer:h});return{type:\"pcb_trace\",pcb_trace_id:(g={connectionName:e.connectionName,sourcePointIndex:e.sourcePointIndex,candidateIndex:l},`fanout-completion:${g.connectionName}:source-${g.sourcePointIndex}:${g.candidateIndex}`),connection_name:e.connectionName,route:m};var g}function l7(t,e){return!t.issues.some(t=\u003et.connectionName===e)}function d7(t){const{trace:e,endpointSrjs:n}=t,o=n.flatMap(t=\u003et.connections.flatMap(t=\u003et.pointsToConnect));return e.route.some(t=\u003e\"via\"===t.route_type\u0026\u0026o.some(e=\u003eM8(t,e)\u003c=1e-6))}function h7(t){const{inputSrj:e,fanoutSrj:n,plan:o,acceptedTraces:i,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,clearance:c}=t,{outward:l,perpendicular:d}=a7({inputSrj:e,plan:o}),h=[...o.via?[{x:o.via.center.x,y:o.via.center.y,layer:o.targetLayer}]:[],{x:o.sourcePoint.x,y:o.sourcePoint.y,layer:o.sourceLayer}];let u=[],p=Number.POSITIVE_INFINITY,m=0;const g=e.connections.length\u003e32?600:Number.POSITIVE_INFINITY,f=\"plane\"===o.termination.type?g7({trace:o.trace,endpoint:o.exitPoint,layer:o.sourceLayer,distances:[.2,.3,.4]}):[],y=[...\"plane\"===o.termination.type\u0026\u0026o.via?[{...o.via.center}]:[],...f,...[.4,.8,1.2,1.6].flatMap(t=\u003e[0,.4,-.4,.8,-.8,1.2,-1.2,1.6,-1.6].map(e=\u003e({x:o.sourcePoint.x+l.x*t+d.x*e,y:o.sourcePoint.y+l.y*t+d.y*e})))];for(const t of y){const y=[...\"plane\"===o.termination.type?[{...t,layer:o.targetLayer}]:[],...h,...f.flatMap(e=\u003eM8(e,t)\u003c=1e-6?[{...e,layer:o.sourceLayer}]:[])];for(const h of y){const f=M8(h,t)\u003c=1e-6?[[h]]:[[h,t],[h,{x:t.x,y:h.y},t],[h,{x:h.x,y:t.y},t],...[.4,-.4].map(e=\u003e[h,{x:h.x+e,y:h.y},{x:h.x+e,y:t.y},t])];for(const y of f){const f=[void 0,...[.4,.8].map(t=\u003e({x:o.targetPoint.x+l.x*t,y:o.targetPoint.y+l.y*t})),...[.4,-.4].map(t=\u003e({x:o.targetPoint.x+.4*l.x+d.x*t,y:o.targetPoint.y+.4*l.y+d.y*t}))];for(const l of f){if(m\u003e=g)return{blockingConnectionNames:u};const d=c7({plan:o,branchStart:h,viaPoint:t,assignedLayerPath:y,terminalApproach:l,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,candidateIndex:m++,chamfer:0});if(d7({trace:d,endpointSrjs:[e,n]}))continue;const f={...n,traces:[...n.traces??[],...i,d]},_=n7({inputSrj:e,routedSrj:f,clearance:c});if(!_.valid){_.issues.length\u003cp\u0026\u0026(p=_.issues.length,u=[...new Set(_.issues.flatMap(t=\u003e[t.connectionName,t.otherConnectionName].flatMap(t=\u003et\u0026\u0026t!==o.connectionName?[t]:[])))]);continue}if(l7(q8({inputSrj:e,routedSrj:f}),o.connectionName))return{trace:d,blockingConnectionNames:[]}}}}}return{blockingConnectionNames:u}}function u7(t){const{inputSrj:e,fanoutSrj:n,plans:o,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a}=t,c=[],l=[],d=new Set;for(const t of o){const o=h7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:c,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});if(o.trace)c.push(o.trace);else{l.push(t.connectionName);for(const t of o.blockingConnectionNames)d.add(t)}}const h={...n,traces:[...n.traces??[],...c]};return{traces:c,failedConnectionNames:l,blockingConnectionNames:[...d],connectivity:q8({inputSrj:e,routedSrj:h}),drc:n7({inputSrj:e,routedSrj:h,clearance:a})}}function p7(t){let e,n=0;for(const o of t.route)\"wire\"===o.route_type?(e?.layer===o.layer\u0026\u0026(n+=M8(e,o)),e=o):e=void 0;return n}function m7(t){const e=k8(t.layerCount),n=[];for(const o of t.traces??[]){let i;for(const r of o.route)if(\"via\"!==r.route_type)if(\"wire\"===r.route_type){if(i?.layer===r.layer){const t=M8(i,r);t\u003eo7\u0026\u0026n.push({obstacleId:`endpoint-completion-keepout:${o.pcb_trace_id}:segment:${n.length}`,type:\"rect\",center:{x:(i.x+r.x)/2,y:(i.y+r.y)/2},width:t,height:Math.max(i.width,r.width),ccwRotationDegrees:180*Math.atan2(r.y-i.y,r.x-i.x)/Math.PI,layers:[r.layer],connectedTo:[o.connection_name]})}i=r}else i=void 0;else n.push({obstacleId:`endpoint-completion-keepout:${o.pcb_trace_id}:via:${n.length}`,type:\"rect\",center:{x:r.x,y:r.y},width:r.via_diameter??t.minViaPadDiameter??.3,height:r.via_diameter??t.minViaPadDiameter??.3,layers:L8(r.from_layer,r.to_layer,e),connectedTo:[o.connection_name]}),i=void 0}return n}function g7(t){const{trace:e,endpoint:n,layer:o,distances:i}=t,r=e.route.findLastIndex(t=\u003e\"wire\"===t.route_type\u0026\u0026t.layer===o\u0026\u0026M8(t,n)\u003c=1e-6);return r\u003c0?[]:i.flatMap(t=\u003e{let i=t,s=n;for(let t=r-1;t\u003e=0;t--){const n=e.route[t];if(\"wire\"!==n?.route_type||n.layer!==o)break;const r=M8(s,n);if(!(r\u003c=o7)){if(i\u003cr-1e-6)return[{x:s.x+(n.x-s.x)*i/r,y:s.y+(n.y-s.y)*i/r}];i-=r,s=n}}return[]})}function f7(t){const{inputSrj:e,fanoutSrj:n,plan:o,acceptedTraces:i,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,clearance:c}=t,l={x:o.exitPoint.x,y:o.exitPoint.y,layer:o.targetLayer},d=o.targetPoint,h=i7(d);let u=0;const p=t=\u003e{const l=c7({plan:o,branchStart:t.start,viaPoint:t.viaPoint,assignedLayerPath:[t.start,t.viaPoint],terminalApproach:t.terminalApproach,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,candidateIndex:1e4+u++,chamfer:Math.max(r,.1)});if(d7({trace:l,endpointSrjs:[e,n]}))return;const d={...n,traces:[...n.traces??[],...i,l]};return n7({inputSrj:e,routedSrj:d,clearance:c}).valid\u0026\u0026l7(q8({inputSrj:e,routedSrj:d}),o.connectionName)?l:void 0};if(l.layer!==h){const t=g7({trace:o.trace,endpoint:o.exitPoint,layer:o.targetLayer,distances:[.4,.8,1.2,1.6]});for(const e of t){const t={...e,layer:o.targetLayer};for(const n of[void 0,{x:d.x,y:e.y},{x:e.x,y:d.y}]){const o=p({start:t,viaPoint:e,terminalApproach:n});if(o)return o}}}const m=[[d],[{x:d.x,y:l.y},d],[{x:l.x,y:d.y},d]];for(const t of m){const e=t[0],n=M8(l,e),o=l.layer===h?[0]:[.4,.8,1.2,1.6];for(const i of o){if(l.layer!==h\u0026\u0026(n\u003c=i+.2||i\u003c=1e-6))continue;const o=p({start:l,viaPoint:l.layer===h?{x:l.x,y:l.y}:{x:l.x+(e.x-l.x)*i/n,y:l.y+(e.y-l.y)*i/n},terminalApproach:t.length\u003e1?e:void 0});if(o)return o}}}function y7(t){const{inputSrj:e,fanoutSrj:n,plans:o,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a,effort:c=1,routeDownstreamConnections:l}=t,d=[],h=n7({inputSrj:e,routedSrj:n,clearance:a}),u=q8({inputSrj:e,routedSrj:n}),p=o.filter(t=\u003ei7(t.sourcePoint)!==i7(t.targetPoint)\u0026\u0026M8(t.sourcePoint,t.targetPoint)\u003c=.25\u0026\u0026!l7(u,t.connectionName));let m={traces:[],failedConnectionNames:p.map(t=\u003et.connectionName),blockingConnectionNames:[],connectivity:u,drc:h},g=0;if(h.valid){let t=[];const o=new Map(p.map((t,e)=\u003e[t.connectionName,e])),c=e.connections.length\u003e32?1:3;for(let l=0;l\u003cc;l++){const c=new Map(t.map((t,e)=\u003e[t,e])),l=u7({inputSrj:e,fanoutSrj:n,plans:p.toSorted((t,e)=\u003e(c.get(t.connectionName)??Number.MAX_SAFE_INTEGER)-(c.get(e.connectionName)??Number.MAX_SAFE_INTEGER)||(o.get(t.connectionName)??0)-(o.get(e.connectionName)??0)),traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});if(g++,l.drc.valid\u0026\u0026(l.connectivity.connectedConnectionCount\u003em.connectivity.connectedConnectionCount||l.connectivity.connectedConnectionCount===m.connectivity.connectedConnectionCount\u0026\u0026l.traces.length\u003cm.traces.length)\u0026\u0026(m=l),t=[...new Set([...l.failedConnectionNames,...l.blockingConnectionNames,...t])],0===l.failedConnectionNames.length)break}}else d.push(\"Fanout prefix failed emitted-copper DRC; skipped completion\");const f=new Set(p.map(t=\u003et.connectionName)),y=o.filter(t=\u003e!f.has(t.connectionName)\u0026\u0026!l7(u,t.connectionName)),_=[];if(h.valid)for(const t of y){const o=f7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:[...m.traces,..._],traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});o\u0026\u0026_.push(o)}const b={...n,traces:[...n.traces??[],...m.traces,..._]},x=new Set(q8({inputSrj:e,routedSrj:b}).issues.map(t=\u003et.connectionName)),v=n.connections.filter(t=\u003e!f.has(t.name)\u0026\u0026x.has(t.name));let S=[];if(h.valid\u0026\u0026v.length\u003e0\u0026\u0026v.length\u003c=12\u0026\u0026l){const t=new Set(v.map(t=\u003et.name)),o={...n,connections:v,buses:n.buses?.map(e=\u003e({...e,connectionNames:e.connectionNames.filter(e=\u003et.has(e))})).filter(t=\u003et.connectionNames.length\u003e0),obstacles:[...n.obstacles,...m7(n)],traces:[]};try{const i=l(o,{effort:c});S=function(t){const{inputSrj:e,fanoutSrj:n,localTraces:o,candidates:i,clearance:r}=t,s=[...n.traces??[],...o],a={...n,traces:s},c=q8({inputSrj:e,routedSrj:a}),l=i.filter(t=\u003et.route.length\u003e1\u0026\u0026t.route.every(t=\u003e\"wire\"===t.route_type||\"via\"===t.route_type)\u0026\u0026!d7({trace:t,endpointSrjs:[e,n]})).filter(t=\u003e{const o=q8({inputSrj:e,routedSrj:{...n,traces:[...s,t]}});return o.connectedConnectionCount\u003ec.connectedConnectionCount\u0026\u0026l7(o,t.connection_name)}),d={...n,traces:[...s,...l]};if(n7({inputSrj:e,routedSrj:d,clearance:r}).valid)return l;const h=[];for(const t of l.toSorted((t,e)=\u003ep7(t)-p7(e))){const o={...n,traces:[...s,...h,t]};if(!n7({inputSrj:e,routedSrj:o,clearance:r}).valid)continue;const i=q8({inputSrj:e,routedSrj:{...n,traces:[...s,...h]}}),a=q8({inputSrj:e,routedSrj:o});a.connectedConnectionCount\u003ei.connectedConnectionCount\u0026\u0026l7(a,t.connection_name)\u0026\u0026h.push(t)}return h}({inputSrj:e,fanoutSrj:n,localTraces:[...m.traces,..._],candidates:i.filter(e=\u003et.has(e.connection_name)),clearance:a})}catch(t){d.push(`Downstream router failed: ${t instanceof Error?t.message:String(t)}`)}}else!h.valid\u0026\u0026v.length\u003e0?d.push(\"Skipped downstream router because the endpoint-completion baseline failed emitted-copper DRC\"):v.length\u003e12?d.push(`Skipped downstream router for ${v.length} unresolved connections (bounded at 12)`):v.length\u003e0\u0026\u0026!l\u0026\u0026d.push(`Skipped downstream router for ${v.length} unresolved connections because no routeDownstreamConnections callback was provided`);const I=[...m.traces,..._,...S];for(const t of y){if(l7(q8({inputSrj:e,routedSrj:{...n,traces:[...n.traces??[],...I]}}),t.connectionName))continue;const o=f7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:I,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});o\u0026\u0026I.push(o)}const C=function(t){const{fanoutSrj:e,completionTraces:n}=t,o=new Map(n.flatMap(t=\u003e{const e=t.route.find(t=\u003e\"wire\"===t.route_type);return e?[[t.connection_name,{x:e.x,y:e.y,layer:e.layer}]]:[]})),i=(e.traces??[]).map(t=\u003e{if(!t.pcb_trace_id.startsWith(\"fanout:\"))return t;const e=o.get(t.connection_name);if(!e)return t;let n;for(let o=0;o\u003ct.route.length;o++){const i=t.route[o];if(\"wire\"===i?.route_type){if(void 0!==n){const o=t.route[n];if(\"wire\"===o?.route_type\u0026\u0026o.layer===e.layer\u0026\u0026i.layer===e.layer\u0026\u0026N8(e,o,i)\u003c=1e-6){const r=t.route.slice(0,n+1);return M8(o,e)\u003e1e-6\u0026\u0026r.push({route_type:\"wire\",x:e.x,y:e.y,width:i.width,layer:e.layer}),{...t,route:r}}}n=o}else n=void 0}return t});return{...e,traces:i}}({fanoutSrj:{...n,traces:[...n.traces??[],...I]},completionTraces:I}),P=q8({inputSrj:e,routedSrj:C}),M=n7({inputSrj:e,routedSrj:C,clearance:a});return M.valid?{simpleRouteJson:C,traces:I,report:{attemptedLocalConnectionCount:p.length,attemptedDownstreamConnectionCount:y.length,completionTraceCount:I.length,searchPassCount:g,errors:d,connectivity:P,drc:M}}:(d.push(\"Final endpoint-completion output failed emitted-copper DRC\"),{simpleRouteJson:n,traces:[],report:{attemptedLocalConnectionCount:p.length,attemptedDownstreamConnectionCount:y.length,completionTraceCount:0,searchPassCount:g,errors:d,connectivity:q8({inputSrj:e,routedSrj:n}),drc:h}})}var _7=new Set([\"left\",\"right\",\"top\",\"bottom\",\"top-left\",\"top-right\",\"bottom-left\",\"bottom-right\"]),b7={top_left:{direction:\"up\",preferredExit:\"top-left\"},top_middle:{direction:\"up\",preferredExit:\"top\"},top_right:{direction:\"up\",preferredExit:\"top-right\"},right_top:{direction:\"right\",preferredExit:\"top-right\"},right_middle:{direction:\"right\",preferredExit:\"right\"},right_bottom:{direction:\"right\",preferredExit:\"bottom-right\"},bottom_right:{direction:\"down\",preferredExit:\"bottom-right\"},bottom_middle:{direction:\"down\",preferredExit:\"bottom\"},bottom_left:{direction:\"down\",preferredExit:\"bottom-left\"},left_bottom:{direction:\"left\",preferredExit:\"bottom-left\"},left_middle:{direction:\"left\",preferredExit:\"left\"},left_top:{direction:\"left\",preferredExit:\"top-left\"},top:{direction:\"up\",preferredExit:\"top\"},right:{direction:\"right\",preferredExit:\"right\"},bottom:{direction:\"down\",preferredExit:\"bottom\"},left:{direction:\"left\",preferredExit:\"left\"}};function x7(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(const t of e)(0===n.length||Math.abs(n[n.length-1]-t)\u003e1e-6)\u0026\u0026n.push(t);return n}function v7(t){let e=Number.POSITIVE_INFINITY;for(let n=1;n\u003ct.length;n++){const o=t[n]-t[n-1];o\u003e1e-6\u0026\u0026(e=Math.min(e,o))}return e}function S7(t,e){const n=\"x\"===e?\"y\":\"x\";let o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ct.length;i++){const r=t[i];for(let s=i+1;s\u003ct.length;s++){const i=t[s];if(Math.abs(r.center[n]-i.center[n])\u003e1e-6)continue;const a=Math.abs(r.center[e]-i.center[e]);a\u003e1e-6\u0026\u0026(o=Math.min(o,a))}}return o}function I7(t){return{minX:Math.min(...t.map(t=\u003et.center.x-t.width/2)),maxX:Math.max(...t.map(t=\u003et.center.x+t.width/2)),minY:Math.min(...t.map(t=\u003et.center.y-t.height/2)),maxY:Math.max(...t.map(t=\u003et.center.y+t.height/2))}}function C7(t,e){const n=e.componentBounds?.[t.componentId];if(!n){const e=2.25*t.pitchX,n=2.25*t.pitchY;return{minX:t.bounds.minX-e,maxX:t.bounds.maxX+e,minY:t.bounds.minY-n,maxY:t.bounds.maxY+n}}if([n.minX,n.maxX,n.minY,n.maxY].some(t=\u003e!Number.isFinite(t))||n.minX\u003e=n.maxX||n.minY\u003e=n.maxY)throw new Error(`FanoutSolver: componentBounds for \"${t.componentId}\" must contain finite, increasing bounds`);if(n.minX\u003et.bounds.minX+1e-6||n.maxX\u003ct.bounds.maxX-1e-6||n.minY\u003et.bounds.minY+1e-6||n.maxY\u003ct.bounds.maxY-1e-6)throw new Error(`FanoutSolver: componentBounds for \"${t.componentId}\" must contain every component pad`);return{...n}}function P7(t,e){if([t.minX,t.maxX,t.minY,t.maxY].some(t=\u003e!Number.isFinite(t))||t.minX\u003e=t.maxX||t.minY\u003e=t.maxY)throw new Error(\"FanoutSolver: sharedBoundary must contain finite, increasing bounds\");for(const n of e)if(t.minX\u003en.bounds.minX+1e-6||t.maxX\u003cn.bounds.maxX-1e-6||t.minY\u003en.bounds.minY+1e-6||t.maxY\u003cn.bounds.maxY-1e-6)throw new Error(`FanoutSolver: sharedBoundary must contain every pad of component \"${n.componentId}\"`);return{...t}}function M7(t){return\"layer\"in t?[t.layer]:t.layers}function N7(t){const{point:e,connection:n,componentGrids:o}=t,i=M7(e),r=[];for(const t of o){const o=t.obstacles.filter(t=\u003et.layers.some(t=\u003ei.includes(t))).filter(t=\u003eR8(e,t,1e-5)).sort((t,o)=\u003e{const i=t.connectedTo.includes(n.name)||t.connectedTo.includes(e.pointId??\"\")||t.connectedTo.includes(e.pcb_port_id??\"\");return i!==(o.connectedTo.includes(n.name)||o.connectedTo.includes(e.pointId??\"\")||o.connectedTo.includes(e.pcb_port_id??\"\"))?i?-1:1:t.width*t.height-o.width*o.height});o[0]\u0026\u0026r.push({grid:t,obstacle:o[0]})}return r}function w7(t){for(const e of t.pointsToConnect)if(\"layers\"in e\u0026\u0026e.busId)return e.busId;const e=/^BUS[_:-]([^_:-]+)(?:[_:-]\\d+)?$/i.exec(t.name);return e?.[1]??null}function T7(t,e){if(void 0!==e){if(!_7.has(e))throw new Error(`FanoutSolver: bus \"${t}\" has invalid preferredExit \"${e}\"`);return e}}function R7(t){if(void 0===t)return;if(0===t.length)throw new Error(\"FanoutSolver: availableCornersAndSides must contain at least one boundary region\");const e=[],n=new Set;for(const o of t){const t=b7[o];if(!t)throw new Error(`FanoutSolver: invalid availableCornersAndSides value \"${o}\"`);const i=`${t.direction}:${t.preferredExit}`;n.has(i)||(n.add(i),e.push(t))}return e}function E7(t,e){if(void 0===e||\"boundary\"===e.type)return{type:\"boundary\"};if(\"plane\"!==e.type||\"string\"!=typeof e.layer||0===e.layer.length)throw new Error(`FanoutSolver: bus \"${t}\" has an invalid termination target`);return{type:\"plane\",layer:e.layer}}function A7(t,e,n,o){const i=e.pointsToConnect.filter((t,e)=\u003ee!==n).sort((e,n)=\u003eM8(t,n)-M8(t,e))[0];if(!i\u0026\u0026\"plane\"===o.type)return t;if(!i)throw new Error(`FanoutSolver: connection \"${e.name}\" has no target beyond its BGA pad`);return i}function O7(t,e){let n=0,o=0;for(const t of e){const e=t.exitTargetPoint??t.targetPoint;n+=e.x-t.sourcePoint.x,o+=e.y-t.sourcePoint.y}if(Math.abs(n)\u003c1e-9\u0026\u0026Math.abs(o)\u003c1e-9)throw new Error(`FanoutSolver: cannot infer an escape direction for bus \"${t}\"`);return Math.abs(n)\u003e=Math.abs(o)?n\u003e=0?\"right\":\"left\":o\u003e=0?\"up\":\"down\"}function k7(t){return{x:t.reduce((t,e)=\u003et+e.sourcePoint.x,0)/t.length,y:t.reduce((t,e)=\u003et+e.sourcePoint.y,0)/t.length}}function L7(t,e,n){switch(e){case\"left\":return t.x-n.minX;case\"right\":return n.maxX-t.x;case\"up\":return n.maxY-t.y;case\"down\":return t.y-n.minY}}function D7(t,e){return\"up\"===t.direction||\"down\"===t.direction?t.preferredExit.endsWith(\"left\")?e.minX:t.preferredExit.endsWith(\"right\")?e.maxX:(e.minX+e.maxX)/2:t.preferredExit.startsWith(\"top\")?e.maxY:t.preferredExit.startsWith(\"bottom\")?e.minY:(e.minY+e.maxY)/2}function z7(t,e){return\"up\"===e||\"down\"===e?t.x:t.y}function F7(t){const{busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s}=t,a=s.filter(t=\u003e!(void 0!==n\u0026\u0026t.direction!==n||void 0!==o\u0026\u0026t.preferredExit!==o));if(0===a.length)throw new Error(`FanoutSolver: bus \"${e}\" cannot use its requested exit with availableCornersAndSides`);const c=n?void 0:function(t,e){try{return O7(t,e)}catch{return}}(e,i),l=c?a.filter(t=\u003et.direction===c):[],d=l.length\u003e0?l:a,h=k7(i);return[...d].toSorted((t,e)=\u003eL7(h,t.direction,r)-L7(h,e.direction,r)||Math.abs(z7(h,t.direction)-D7(t,r))-Math.abs(z7(h,e.direction)-D7(e,r))||t.preferredExit.localeCompare(e.preferredExit))[0]}function B7(t){const{busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s}=t;if(s)return F7({busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s});if(!o)return{direction:n??O7(e,i)};const a=function(t){switch(t){case\"left\":return[\"left\"];case\"right\":return[\"right\"];case\"top\":return[\"up\"];case\"bottom\":return[\"down\"];case\"top-left\":return[\"up\",\"left\"];case\"top-right\":return[\"up\",\"right\"];case\"bottom-left\":return[\"down\",\"left\"];case\"bottom-right\":return[\"down\",\"right\"]}}(o);if(n){if(!a.includes(n))throw new Error(`FanoutSolver: bus \"${e}\" direction \"${n}\" is incompatible with preferredExit \"${o}\"`);return{direction:n,preferredExit:o}}if(1===a.length)return{direction:a[0],preferredExit:o};let c;try{c=O7(e,i)}catch{c=void 0}if(c\u0026\u0026a.includes(c))return{direction:c,preferredExit:o};const l=k7(i);return{direction:a.toSorted((t,e)=\u003eL7(l,t,r)-L7(l,e,r)||t.localeCompare(e))[0],preferredExit:o}}function j7(t,e){const n=function(t){const e=new Map;for(const n of t){if(!n.componentId||n.isCopperPour)continue;const t=e.get(n.componentId)??[];t.push(n),e.set(n.componentId,t)}const n=[];for(const[t,o]of e){const e=x7(o.map(t=\u003et.center.x)),i=x7(o.map(t=\u003et.center.y)),r=S7(o,\"x\"),s=S7(o,\"y\"),a=v7(e),c=v7(i),l=Math.min(...[r,s,a,c].filter(Number.isFinite)),d=Math.max(...o.flatMap(t=\u003e[t.width,t.height])),h=Number.isFinite(l)?l:d,u=Number.isFinite(r)?r:Number.isFinite(a)?a:h,p=Number.isFinite(s)?s:Number.isFinite(c)?c:h;n.push({componentId:t,obstacles:o,xCoordinates:e,yCoordinates:i,pitchX:u,pitchY:p,bounds:I7(o)})}return n}(t.obstacles);if(0===n.length\u0026\u0026t.connections.length\u003e0)throw new Error(\"FanoutSolver: no componentId-tagged pad footprint was found\");const o=new Map(t.connections.map((t,e)=\u003e[t.name,e])),i=function(t,e){const n=e.buses??t.buses,o=new Map,i=new Set,r=new Set(t.connections.map(t=\u003et.name));for(const t of n??[]){if(o.has(t.busId))throw new Error(`FanoutSolver: duplicate bus id \"${t.busId}\"`);for(const e of t.connectionNames){if(!r.has(e))throw new Error(`FanoutSolver: bus \"${t.busId}\" references unknown connection \"${e}\"`);if(i.has(e))throw new Error(`FanoutSolver: connection \"${e}\" belongs to more than one bus`);i.add(e)}const n=E7(t.busId,t.termination),s=T7(t.busId,e.busExitPreferences?.[t.busId]??t.preferredExit??e.defaultPreferredExit);if(\"plane\"===n.type\u0026\u0026void 0!==s)throw new Error(`FanoutSolver: plane-terminated bus \"${t.busId}\" cannot also specify preferredExit`);o.set(t.busId,{...t,sourceComponentId:t.sourceComponentId??e.sourceComponentId,direction:e.busDirections?.[t.busId]??t.direction??e.defaultDirection,preferredExit:s,termination:n})}for(const n of t.connections){if(i.has(n.name))continue;const t=w7(n);if(t){const i=o.get(t);o.set(t,{busId:t,connectionNames:[...i?.connectionNames??[],n.name],direction:e.busDirections?.[t]??i?.direction??e.defaultDirection,sourceComponentId:i?.sourceComponentId??e.sourceComponentId,preferredExit:T7(t,e.busExitPreferences?.[t]??i?.preferredExit??e.defaultPreferredExit),termination:i?.termination??{type:\"boundary\"}})}else{const t=`connection:${n.name}`;o.set(t,{busId:t,connectionNames:[n.name],sourceComponentId:e.sourceComponentId,direction:e.busDirections?.[t]??e.defaultDirection,preferredExit:T7(t,e.busExitPreferences?.[t]??e.defaultPreferredExit),termination:{type:\"boundary\"}})}}return[...o.values()]}(t,e).map(e=\u003e{for(const[t,n]of Object.entries(e.connectionExitTargets??{})){if(!e.connectionNames.includes(t))throw new Error(`FanoutSolver: connectionExitTargets contains connection \"${t}\" outside bus \"${e.busId}\"`);if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error(`FanoutSolver: connectionExitTargets for connection \"${t}\" must contain finite x and y coordinates`)}const i=e.connectionNames.map(e=\u003e{const n=o.get(e);if(void 0===n)throw new Error(`FanoutSolver: connection \"${e}\" is missing from the input`);return t.connections[n]}),r=function(t){const{busSpec:e,connections:n,componentGrids:o}=t,i=new Map;for(const t of n){const e=new Set;for(const n of t.pointsToConnect)for(const i of N7({point:n,connection:t,componentGrids:o}))e.add(i.grid.componentId);for(const t of e)i.set(t,(i.get(t)??0)+1)}const r=[...o].sort((t,e)=\u003e{const n=(i.get(e.componentId)??0)-(i.get(t.componentId)??0);return 0!==n?n:e.obstacles.length-t.obstacles.length})[0],s=e.sourceComponentId?o.find(t=\u003et.componentId===e.sourceComponentId):void 0;if(e.sourceComponentId\u0026\u0026!s)throw new Error(`FanoutSolver: source component \"${e.sourceComponentId}\" for bus \"${e.busId}\" was not found`);const a=s??r,c=a?i.get(a.componentId)??0:0;if(!a||c!==n.length)throw new Error(e.sourceComponentId?`FanoutSolver: source component \"${e.sourceComponentId}\" is not an endpoint on every connection in bus \"${e.busId}\"`:`FanoutSolver: bus \"${e.busId}\" does not have one component endpoint on every connection`);return a}({busSpec:e,connections:i,componentGrids:n}),s=i.map(t=\u003efunction(t){const{connection:e,connectionIndex:n,sourceGrid:o,componentGrids:i,termination:r,exitTargetPoint:s}=t;for(let t=0;t\u003ce.pointsToConnect.length;t++){const a=e.pointsToConnect[t],c=N7({point:a,connection:e,componentGrids:i}).find(t=\u003et.grid.componentId===o.componentId);if(!c)continue;const l=M7(a).find(t=\u003ec.obstacle.layers.includes(t));if(!l)throw new Error(`FanoutSolver: connection \"${e.name}\" has no source layer shared with its BGA pad`);const d=A7(a,e,t,r);return{connection:e,connectionIndex:n,sourcePoint:a,sourcePointIndex:t,sourceLayer:l,sourceObstacle:c.obstacle,targetPoint:d,exitTargetPoint:s??d}}throw new Error(`FanoutSolver: connection \"${e.name}\" does not touch component \"${o.componentId}\"`)}({connection:t,connectionIndex:o.get(t.name),sourceGrid:r,componentGrids:n,termination:e.termination??{type:\"boundary\"},exitTargetPoint:e.connectionExitTargets?.[t.name]}));return{busSpec:e,sourceGrid:r,preparedConnections:s}}),r=function(t,e){if(e.sharedBoundary)return P7(e.sharedBoundary,t);const n=t.map(t=\u003eC7(t,e)),o=2.25*Math.max(...t.flatMap(t=\u003e[t.pitchX,t.pitchY]));return P7({minX:Math.min(...n.map(t=\u003et.minX))-o,maxX:Math.max(...n.map(t=\u003et.maxX))+o,minY:Math.min(...n.map(t=\u003et.minY))-o,maxY:Math.max(...n.map(t=\u003et.maxY))+o},t)}([...new Map(i.map(({sourceGrid:t})=\u003e[t.componentId,t])).values()],e),s=R7(e.availableCornersAndSides),a=[];for(const{busSpec:t,sourceGrid:n,preparedConnections:o}of i){const i=B7({busId:t.busId,explicitDirection:t.direction??e.busDirections?.[t.busId],preferredExit:t.preferredExit,connections:o,sharedBoundary:r,availableRegions:\"plane\"===t.termination?.type?void 0:s});a.push({busId:t.busId,direction:i.direction,preferredExit:i.preferredExit,termination:t.termination??{type:\"boundary\"},connections:o,componentId:n.componentId,componentObstacles:n.obstacles,componentBounds:C7(n,e),sharedBoundary:r,xCoordinates:[...n.xCoordinates],yCoordinates:[...n.yCoordinates],pitchX:n.pitchX,pitchY:n.pitchY})}return a}function $7(t){return\"left\"===t||\"right\"===t}function Y7(t){return\"right\"===t||\"up\"===t?1:-1}function X7(t,e){return $7(e)?t.x:t.y}function V7(t,e){return $7(e)?t.y:t.x}function W7(t,e,n){return $7(n)?{x:t,y:e}:{x:e,y:t}}function H7(t){switch(t.direction){case\"right\":return t.sharedBoundary.maxX;case\"left\":return t.sharedBoundary.minX;case\"up\":return t.sharedBoundary.maxY;case\"down\":return t.sharedBoundary.minY}}function G7(t){return $7(t.direction)?t.pitchX:t.pitchY}function U7(t){const e=$7(t.direction)?t.xCoordinates:t.yCoordinates,n=t.connections.reduce((e,n)=\u003ee+X7(n.sourcePoint,t.direction),0)/t.connections.length,o=Y7(t.direction)\u003e0?Math.max(...e):Math.min(...e);return Math.abs(n-o)\u003c1e-6}function Z7(t,e){const n=[...t.connections].sort((e,n)=\u003eV7(e.sourcePoint,t.direction)-V7(n.sourcePoint,t.direction)).findIndex(t=\u003et.connectionIndex===e.connectionIndex);if(n\u003c0)throw new Error(`FanoutSolver: connection \"${e.connection.name}\" is missing from bus \"${t.busId}\"`);return n}function q7(t,e){return t.x\u003e=e.minX-1e-6\u0026\u0026t.x\u003c=e.maxX+1e-6\u0026\u0026t.y\u003e=e.minY-1e-6\u0026\u0026t.y\u003c=e.maxY+1e-6}function J7(t,e,n,o,i){const r=e-t,s=Math.floor((r-o)/(n+o)+1e-9);if(s\u003c1)return[];const a=t+(r-(s*n+(s-1)*o))/2+n/2;return Array.from({length:s},(t,e)=\u003e({value:a+e*(n+o),kind:i}))}function K7(t){const e=V7(t.connection.exitTargetPoint??t.connection.targetPoint,t.bus.direction),n=$7(t.bus.direction)?t.bus.sharedBoundary.minY:t.bus.sharedBoundary.minX,o=$7(t.bus.direction)?t.bus.sharedBoundary.maxY:t.bus.sharedBoundary.maxX;return Math.max(n+t.traceWidth/2,Math.min(o-t.traceWidth/2,e))}function Q7(t){const{bus:e,connection:n,targetUsesVia:o,interstitialEscape:i,compactBusTracks:r,traceWidth:s,viaDiameter:a,clearance:c}=t,l=($7(e.direction)?e.yCoordinates:e.xCoordinates).toSorted((t,e)=\u003et-e),d=V7(n.sourcePoint,e.direction);if(r){const t=Z7(e,n);return(l[0]+l.at(-1))/2+(t-(e.connections.length-1)/2)*(s+c)}if(!o||!i)return d;const h=function(t){const e=($7(t.direction)?t.xCoordinates:t.yCoordinates).toSorted((t,e)=\u003et-e),n=t.connections.reduce((e,n)=\u003ee+X7(n.sourcePoint,t.direction),0)/t.connections.length,o=Y7(t.direction)\u003e0?e.at(-1):e[0];return Math.abs(o-n)/G7(t)}(e),u=s+c,p=Math.ceil(e.connections.length/2),m=(p-1)*u,g=a/2+s/2+c+.001,f=Math.round(h)+1,y=f*g+(f-1)*m,_=Z7(e,n),b=l[0],x=l.at(-1),v=_\u003cp?b-y-(p-_-1)*u:x+y+(_-p)*u,S=$7(e.direction)?e.sharedBoundary.minY:e.sharedBoundary.minX,I=$7(e.direction)?e.sharedBoundary.maxY:e.sharedBoundary.maxX;return Math.max(S+s/2,Math.min(I-s/2,v))}function ttt(t){const e=Y7(t.direction),n=[...t.connections].sort((n,o)=\u003e{const i=e*(X7(o.sourcePoint,t.direction)-X7(n.sourcePoint,t.direction));return Math.abs(i)\u003e1e-6?i:V7(n.sourcePoint,t.direction)-V7(o.sourcePoint,t.direction)}),o=[...t.connections].sort((n,o)=\u003eV7(n.sourcePoint,t.direction)-V7(o.sourcePoint,t.direction)||e*(X7(o.sourcePoint,t.direction)-X7(n.sourcePoint,t.direction))),i=[n,[...n].reverse(),o,[...o].reverse()];for(let t=1;t\u003cMath.min(n.length,8);t++)i.push([...n.slice(t),...n.slice(0,t)]);return i}function ett(t,e,n,o,i){M8(e,n)\u003c1e-9||t.push({start:e,end:n,width:o,layer:i})}function ntt(t){const{preparedConnection:e,bus:n,targetLayer:o,track:i,exitAxis:r,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,viaHandedness:d,interstitialEscape:h,spreadLaneIndex:u,clearance:p,terminateAtVia:m}=t,g={x:e.sourcePoint.x,y:e.sourcePoint.y},f=Y7(n.direction),y=G7(n),_=function(t){return $7(t.direction)?t.pitchY:t.pitchX}(n),b=o!==e.sourceLayer,x=$7(n.direction)?e.sourceObstacle.width:e.sourceObstacle.height,v=b\u0026\u0026!U7(n)?x\u003e=y?x/2+c/2+p+.001:.5*y:b?Math.max(.5*y,x/2+(b?c:a)/2+p+.001):x/2+a/2+p+.001,S=X7(g,n.direction)+f*v,I=V7(g,n.direction)+d*_*.5,C=W7(S,I,n.direction),P=c/2+a/2+p+.001+u*(a+p),M=h\u0026\u0026y\u003e=P+c/2+p,N=M?W7(S+f*P,I,n.direction):C,w=W7(M?X7(N,n.direction):S+f*Math.abs(i-I),i,n.direction),T=m?C:W7(r,i,n.direction),R=[],E=[];let A;if(E.push({route_type:\"wire\",x:g.x,y:g.y,width:a,layer:e.sourceLayer,start_pcb_port_id:e.sourcePoint.pcb_port_id}),ett(R,g,C,a,e.sourceLayer),E.push({route_type:\"wire\",x:C.x,y:C.y,width:a,layer:e.sourceLayer}),o!==e.sourceLayer){const t=L8(e.sourceLayer,o,s);A={center:C,diameter:c,holeDiameter:l,fromLayer:e.sourceLayer,toLayer:o,spanLayers:t},E.push({route_type:\"via\",x:C.x,y:C.y,from_layer:e.sourceLayer,to_layer:o,via_diameter:c,via_hole_diameter:l}),E.push({route_type:\"wire\",x:C.x,y:C.y,width:a,layer:o})}const O=m?[C]:M?function(t,e){if(t.length\u003c3)return t;const n=[t[0]];for(let o=1;o\u003ct.length-1;o++){const i=t[o-1],r=t[o],s=t[o+1],a=M8(i,r),c=M8(r,s);if(a\u003c1e-9||c\u003c1e-9)continue;const l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c},h=l.x*d.x+l.y*d.y;if(Math.abs(h)\u003e1e-6){n.push(r);continue}const u=Math.min(e,a/2,c/2);n.push({x:r.x-l.x*u,y:r.y-l.y*u}),n.push({x:r.x+d.x*u,y:r.y+d.y*u})}return n.push(t.at(-1)),n}([C,N,w,T],Math.max(a+p,2*a)):[C,w,T];for(let t=1;t\u003cO.length;t++){const e=O[t-1],n=O[t];ett(R,e,n,a,o),E.push({route_type:\"wire\",x:n.x,y:n.y,width:a,layer:o})}const k=x8({connectionName:e.connection.name,sourcePointIndex:e.sourcePointIndex});return{busId:n.busId,connectionName:e.connection.name,connectionIndex:e.connectionIndex,sourcePointIndex:e.sourcePointIndex,sourcePoint:e.sourcePoint,sourceObstacle:e.sourceObstacle,sourceLayer:e.sourceLayer,targetPoint:e.targetPoint,targetLayer:o,termination:n.termination,direction:n.direction,exitPoint:T,trace:{type:\"pcb_trace\",pcb_trace_id:k.traceId,connection_name:e.connection.name,connectsTo:[...e.sourcePoint.pointId?[e.sourcePoint.pointId]:[],...e.sourcePoint.pcb_port_id?[e.sourcePoint.pcb_port_id]:[],k.boundaryExitPointId],route:E},segments:R,via:A,length:R.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}function ott(t){const{preparedConnection:e,bus:n,viaDiameter:o,clearance:i}=t,{sourcePoint:r,targetPoint:s}=e,a=.5*Math.max(n.pitchX,n.pitchY);if(M8(r,s)\u003c=1e-6||M8(r,s)\u003ea)return[];const c=(()=\u003e{switch(n.direction){case\"left\":return{x:-1,y:0};case\"right\":return{x:1,y:0};case\"up\":return{x:0,y:1};case\"down\":return{x:0,y:-1}}})(),l=Math.SQRT1_2,d=[c,...[{x:l,y:l},{x:l,y:-l},{x:-l,y:l},{x:-l,y:-l},{x:1,y:0},{x:-1,y:0},{x:0,y:1},{x:0,y:-1}].toSorted((t,e)=\u003ee.x*c.x+e.y*c.y-(t.x*c.x+t.y*c.y))],h=Math.max(o,o/2+i),u=[h,Math.max(h,.5*Math.min(n.pitchX,n.pitchY)),Math.max(h,.625*Math.min(n.pitchX,n.pitchY)),Math.max(h,.75*Math.min(n.pitchX,n.pitchY))],p=[];for(const t of[r,s])for(const e of u)for(const n of d){const o={x:t.x+n.x*e,y:t.y+n.y*e};M8(o,r)\u003c=1e-6||M8(o,s)\u003c=1e-6||p.some(t=\u003eM8(t,o)\u003c=1e-6)||p.push(o)}return p}function itt(t){const{plan:e,preparedConnection:n,planeLayer:o,viaPoint:i,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c}=t,l={x:n.targetPoint.x,y:n.targetPoint.y},d=function(t){const e=\"layer\"in t?t.layer:t.layers[0];if(!e)throw new Error(\"FanoutSolver: plane endpoint has no copper layer\");return e}(n.targetPoint),h=L8(o,d,r);if(!h.includes(o))throw new Error(`FanoutSolver: via for \"${n.connection.name}\" does not cross plane ${o}`);const u=[{start:i,end:l,width:s,layer:d}],p={center:i,diameter:a,holeDiameter:c,fromLayer:o,toLayer:d,spanLayers:h},m=x8({connectionName:n.connection.name,sourcePointIndex:n.sourcePointIndex}),g={type:\"pcb_trace\",pcb_trace_id:m.planeEndpointTraceId,connection_name:n.connection.name,connectsTo:[...n.targetPoint.pointId?[n.targetPoint.pointId]:[],...n.targetPoint.pcb_port_id?[n.targetPoint.pcb_port_id]:[],m.planeEndpointPointId],route:[{route_type:\"wire\",...i,width:s,layer:o},{route_type:\"via\",...i,from_layer:o,to_layer:d,via_diameter:a,via_hole_diameter:c},{route_type:\"wire\",...i,width:s,layer:d},{route_type:\"wire\",...l,width:s,layer:d}]};return{...e,planeEndpointTrace:g,planeEndpointSegments:u,planeEndpointVia:p,length:e.length+u.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}function rtt(t){const{segment:e,plan:n,segmentIndex:o,srj:i,allowSameNetMerges:r,obstacles:s,clearance:a}=t;for(const t of s)if(t.layers.includes(e.layer)\u0026\u0026!t.connectedTo.includes(n.connectionName)\u0026\u0026!(r\u0026\u0026Y8(i,t,n.connectionName)||K8({inputSrj:i,segment:e,bodyObstacle:t,connectionName:n.connectionName})||0===o\u0026\u0026t===n.sourceObstacle\u0026\u0026e.layer===n.sourceLayer||!(A8(e,t)\u003ce.width/2+a-1e-9)))return!1;return!0}function stt(t){return[...t.segments,...t.planeEndpointSegments??[]]}function att(t){return[t.via,t.planeEndpointVia].filter(t=\u003eBoolean(t))}function ctt(t){const{plan:e,srj:n,sharedBoundary:o,clearance:i,allowSameNetMerges:r}=t,s=function(t,e){return{minX:Math.min(t.minX,e.minX),maxX:Math.max(t.maxX,e.maxX),minY:Math.min(t.minY,e.minY),maxY:Math.max(t.maxY,e.maxY)}}(n.bounds,o);if(!q7(e.exitPoint,s)||stt(e).some(t=\u003e!q7(t.start,s)||!q7(t.end,s)))return!1;const a=stt(e);for(let t=0;t\u003ca.length;t++)if(!rtt({segment:a[t],plan:e,segmentIndex:t\u003ce.segments.length?t:-1,srj:n,allowSameNetMerges:r,obstacles:n.obstacles,clearance:i}))return!1;for(const t of att(e))for(const o of n.obstacles)if(o.layers.some(e=\u003et.spanLayers.includes(e))\u0026\u0026(!r||!Y8(n,o,e.connectionName))\u0026\u0026E8(t.center,o)\u003ct.diameter/2+i-1e-9)return!1;return!0}function ltt(t){const{plan:e,otherPlans:n,staticClearanceCache:o,blockingBusCounts:i,cacheKey:r,srj:s,sharedBoundary:a,clearance:c,allowSameNetMerges:l}=t;let d=o?.get(r);return void 0===d\u0026\u0026(d=ctt({plan:e,srj:s,sharedBoundary:a,clearance:c,allowSameNetMerges:l}),o?.set(r,d)),d\u0026\u0026function(t){const{plan:e,otherPlans:n,srj:o,allowSameNetMerges:i,clearance:r,blockingBusCounts:s}=t;for(const t of n){if(i\u0026\u0026$8(o,e.connectionName,t.connectionName))continue;if(e.sourcePoint.pcb_port_id\u0026\u0026e.sourcePoint.pcb_port_id===t.sourcePoint.pcb_port_id||e.sourcePoint.pointId\u0026\u0026e.sourcePoint.pointId===t.sourcePoint.pointId)continue;const n=()=\u003e{t.busId!==e.busId\u0026\u0026s?.set(t.busId,(s.get(t.busId)??0)+1)},a=stt(e),c=stt(t),l=att(e),d=att(t);for(const t of a){for(const e of c)if(!O8(t,e,r))return n(),!1;for(const e of d)if(e.spanLayers.includes(t.layer)\u0026\u0026N8(e.center,t.start,t.end)\u003ce.diameter/2+t.width/2+r-1e-9)return n(),!1}for(const t of l){for(const e of c)if(t.spanLayers.includes(e.layer)\u0026\u0026N8(t.center,e.start,e.end)\u003ct.diameter/2+e.width/2+r-1e-9)return n(),!1;for(const e of d)if(t.spanLayers.some(t=\u003ee.spanLayers.includes(t))\u0026\u0026M8(t.center,e.center)\u003c(t.diameter+e.diameter)/2+r-1e-9)return n(),!1}}return!0}({plan:e,otherPlans:n,srj:s,allowSameNetMerges:l,clearance:c,blockingBusCounts:i})}function dtt(t,e=1){const{srj:n,bus:o,targetLayer:i,acceptedPlans:r,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,clearance:d,compactBusTracks:h,staticClearanceCache:u,blockingBusCounts:p,allowSameNetMerges:m=!1}=t;if(!Number.isInteger(e)||e\u003c1)throw new Error(`FanoutSolver: maxAlternatives must be a positive integer, received ${e}`);if(\"plane\"===o.termination.type){const e=function(t){const{srj:e,bus:n,targetLayer:o,acceptedPlans:i,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,clearance:l,staticClearanceCache:d,blockingBusCounts:h,allowSameNetMerges:u=!1}=t,p=n.connections[0]?.sourceObstacle;if(!p||\"plane\"!==n.termination.type)return null;const m=n.connections[0].sourceLayer;if(o===m)return null;const g=[n.direction,...[\"left\",\"right\",\"up\",\"down\"].filter(t=\u003et!==n.direction)];for(const t of g){const m=t===n.direction?n:{...n,direction:t},g=$7(t)?p.width:p.height,f=G7(m)/2-g/2\u003e=a/2+l-1e-9,y=f?[0]:[1,-1];for(const p of y)for(const g of ttt(m)){const y=[];let _=!0;for(const b of g){const g=V7(b.sourcePoint,t),x=ntt({preparedConnection:b,bus:m,targetLayer:o,track:g,exitAxis:H7(m),layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,viaHandedness:p,interstitialEscape:!f,spreadLaneIndex:0,clearance:l,terminateAtVia:!0}),v=[...ott({preparedConnection:b,bus:m,viaDiameter:a,clearance:l}).map(t=\u003eitt({plan:x,preparedConnection:b,planeLayer:o,viaPoint:t,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c})),x].find((r,s)=\u003eltt({plan:r,otherPlans:[...i,...y],staticClearanceCache:d,blockingBusCounts:h,cacheKey:`plane:${n.busId}:${o}:${t}:${b.connectionIndex}:${p}:${s}`,srj:e,sharedBoundary:n.sharedBoundary,clearance:l,allowSameNetMerges:u}));if(!v){_=!1;break}y.push(v)}if(_)return y}}return null}(t);return e?[e]:[]}const g=H7(o),f=o.connections[0]?.sourceObstacle;if(!f)return[[]];const y=$7(o.direction)?f.width:f.height,_=o.connections[0].sourceLayer,b=i!==_,x=U7(o),v=G7(o)/2-y/2\u003e=c/2+d-1e-9,S=b\u0026\u0026!x\u0026\u0026!v,I=b?v||x?[0]:[1,-1]:[0],C=[],P=new Set,M=(t,f,y,_)=\u003e{if(C.length\u003e=e)return;if(y\u003e=t.length)return void(t=\u003e{const e=t.map(t=\u003e`${t.connectionIndex}:${t.targetLayer}:${t.exitPoint.x}:${t.exitPoint.y}:${t.segments.map(t=\u003e`${t.start.x},${t.start.y},${t.end.x},${t.end.y},${t.layer}`).join(\";\")}`).join(\"|\");P.has(e)||(P.add(e),C.push(t))})(_);const x=t[y],v=Z7(o,x),I=[K7({bus:o,connection:x,traceWidth:a}),Q7({bus:o,connection:x,targetUsesVia:b,interstitialEscape:S,compactBusTracks:h,traceWidth:a,viaDiameter:c,clearance:d})].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e-t)\u003c1e-9)===e).flatMap(t=\u003efunction(t){const{bus:e,connection:n,preferredTrack:o,traceWidth:i,clearance:r}=t,s=($7(e.direction)?e.yCoordinates:e.xCoordinates).toSorted((t,e)=\u003et-e),a=Math.max(...e.componentObstacles.map(t=\u003e$7(e.direction)?t.height/2:t.width/2)),c=$7(e.direction)?e.sharedBoundary.minY:e.sharedBoundary.minX,l=$7(e.direction)?e.sharedBoundary.maxY:e.sharedBoundary.maxX,d=l-c,h=l,u=[{value:o,kind:\"preferred\"},...J7(c,s[0]-a,i,r,\"margin\")];for(let t=0;t\u003cs.length;t++)u.push({value:s[t],kind:\"corridor\"}),t\u003cs.length-1\u0026\u0026u.push(...J7(s[t]+a,s[t+1]-a,i,r,\"gap\"));u.push(...J7(s.at(-1)+a,h,i,r,\"margin\"));const p=V7(n.sourcePoint,e.direction),m=(s[0]+s.at(-1))/2;return u.filter(t=\u003eMath.abs(t.value-p)\u003c=d+1e-9).filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e.value-t.value)\u003c1e-9)===e).sort((t,e)=\u003eMath.abs(t.value-o)-Math.abs(e.value-o)-.001*(Math.abs(t.value-m)-Math.abs(e.value-m)))}({bus:o,connection:x,preferredTrack:t,traceWidth:a,clearance:d})).filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e.value-t.value)\u003c1e-9)===e);for(let h=0;h\u003cI.length;h++){const b=I[h],P=ntt({preparedConnection:x,bus:o,targetLayer:i,track:b.value,exitAxis:g,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,viaHandedness:f,interstitialEscape:S,spreadLaneIndex:Math.min(v,o.connections.length-v-1),clearance:d,terminateAtVia:!1});if(ltt({plan:P,otherPlans:[...r,..._],staticClearanceCache:u,blockingBusCounts:p,cacheKey:`boundary:${o.busId}:${i}:${x.connectionIndex}:${f}:${h}`,srj:n,sharedBoundary:o.sharedBoundary,clearance:d,allowSameNetMerges:m})){if(M(t,f,y+1,[..._,P]),C.length\u003e=e)return;if(1===e)return}}};for(const t of I)for(const n of ttt(o))if(M(n,t,0,[]),C.length\u003e=e)return C;return C}function htt(t){return dtt(t,1)[0]??null}var utt=1e-9,ptt=\"1\"===globalThis.process?.env?.FANOUT_FLOW_DEBUG;function mtt(t){const e=t.connection;return t.sourceObstacle.connectedTo.find(t=\u003et.startsWith(\"connectivity_net\"))??e.netConnectionName??t.connection.name.replace(/::fanout:\\d+$/,\"\")}function gtt(t,e){return t===e.connection.sourceObstacle||t.connectedTo.includes(e.connection.connection.name)||t.connectedTo.includes(e.netKey)}function ftt(t,e){const n=e.x-t.x,o=e.y-t.y,i=Math.abs(n),r=Math.abs(o);return i\u003cutt||r\u003cutt||Math.abs(i-r)\u003cutt?[t,e]:i\u003er?[t,{x:t.x+Math.sign(n)*r,y:e.y},e]:[t,{x:e.x,y:t.y+Math.sign(o)*i},e]}function ytt(t){if(t.length\u003c2)return t;const e=[t[0]];for(const n of t.slice(1)){const t=e.at(-1),o=Math.abs(n.x-t.x),i=Math.abs(n.y-t.y);o\u003cutt||i\u003cutt||Math.abs(o-i)\u003cutt?e.push(n):e.push(...ftt(n,t).reverse().slice(1))}return _tt(e)}function _tt(t){if(t.length\u003c3)return t;const e=[t[0]];for(let n=1;n\u003ct.length-1;n++){const o=e.at(-1),i=t[n],r=t[n+1];Math.sign(i.x-o.x)===Math.sign(r.x-i.x)\u0026\u0026Math.sign(i.y-o.y)===Math.sign(r.y-i.y)||e.push(i)}return e.push(t.at(-1)),e}function btt(t,e){if(t.length\u003c3)return t;const n=[t[0]];for(let o=1;o\u003ct.length-1;o++){const i=t[o-1],r=t[o],s=t[o+1],a=M8(i,r),c=M8(r,s);if(a\u003cutt||c\u003cutt)continue;const l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c};if(Math.abs(l.x*d.x+l.y*d.y)\u003e1e-6){n.push(r);continue}const h=Math.min(e,a/2,c/2);n.push({x:r.x-l.x*h,y:r.y-l.y*h}),n.push({x:r.x+d.x*h,y:r.y+d.y*h})}return n.push(t.at(-1)),_tt(n)}function xtt(t,e){const n=[];for(let o=1;o\u003ct.length;o++)M8(t[o-1],t[o])\u003cutt||n.push({start:t[o-1],end:t[o],width:e,layer:\"top\"});return n}var vtt=class{edges;levels;nextEdges;constructor(t){this.edges=Array.from({length:t},()=\u003e[]),this.levels=new Int32Array(t),this.nextEdges=new Int32Array(t)}addEdge(t,e,n,o={}){const i={to:e,reverseIndex:this.edges[e].length,capacity:n,initialCapacity:n,...o},r={to:t,reverseIndex:this.edges[t].length,capacity:0,initialCapacity:0};this.edges[t].push(i),this.edges[e].push(r)}buildLevels(t,e){this.levels.fill(-1);const n=new Int32Array(this.edges.length);let o=0,i=0;for(n[i++]=t,this.levels[t]=0;o\u003ci;){const t=n[o++];for(const e of this.edges[t])e.capacity\u003c=0||this.levels[e.to]\u003e=0||(this.levels[e.to]=this.levels[t]+1,n[i++]=e.to)}return this.levels[e]\u003e=0}sendFlow(t,e){if(t===e)return 1;for(let n=this.nextEdges[t];n\u003cthis.edges[t].length;n++,this.nextEdges[t]=n){const o=this.edges[t][n];if(o.capacity\u003c=0||this.levels[o.to]!==this.levels[t]+1)continue;const i=this.sendFlow(o.to,e);if(0!==i)return o.capacity-=i,this.edges[o.to][o.reverseIndex].capacity+=i,i}return 0}maximumFlow(t,e,n){let o=0;for(;o\u003cn\u0026\u0026this.buildLevels(t,e);)for(this.nextEdges.fill(0);o\u003cn;){const n=this.sendFlow(t,e);if(0===n)break;o+=n}return o}};function Stt(t){const{direction:e,availableDirections:n,items:o,grid:i,obstacles:r,traceWidth:s,clearance:a,occupiedNodes:c,acceptedSegments:l,connectorSelectionOffset:d=0}=t;if(0===o.length)return{routes:[],usedNodes:[],unmatchedItems:[]};const{boundary:h,step:u,columnCount:p,rowCount:m,nodeCount:g}=i,f=t=\u003ei.points[t],y=s/2+a,_=s+a,b=new Uint8Array(g);for(let t=0;t\u003cg;t++)!c[t]\u0026\u0026i.obstacleFreeNodes[t]\u0026\u0026(b[t]=1);const x=(t,e)=\u003e{const n=xtt(t,s);return n.every(t=\u003er.every(n=\u003egtt(n,e)||A8(t,n)\u003e=y-utt))\u0026\u0026n.every(t=\u003el.every(e=\u003eT8(t.start,t.end,e.start,e.end)\u003e=_-utt))},v=new Map;for(const t of o){const e=`${t.source.x.toFixed(6)}:${t.source.y.toFixed(6)}:${t.netKey}`,n=v.get(e)??[];n.push(t),v.set(e,n)}const S=Array.from({length:3721},(t,e)=\u003e{const n=e%61-30,o=Math.floor(e/61)-30;return{x:n,y:o,distanceSquared:n*n+o*o}}).sort((t,e)=\u003et.distanceSquared-e.distanceSquared),I=[];for(const t of v.values()){const e=t[0],n=Math.hypot(e.connection.sourceObstacle.width/2,e.connection.sourceObstacle.height/2)+a+2*u,o=Math.round((e.source.x-h.minX)/u),i=Math.round((e.source.y-h.minY)/u),r=[],s=new Set;for(const t of S){const a=o+t.x,c=i+t.y;if(a\u003c0||a\u003e=p||c\u003c0||c\u003e=m)continue;const l=c*p+a;if(!b[l]||s.has(l))continue;if(M8(e.source,f(l))\u003en)continue;const d=ftt(e.source,f(l));if(x(d,e)\u0026\u0026(s.add(l),r.push({node:l,connectorPoints:d}),r.length\u003e=12))break}if(0===r.length)return null;I.push({item:e,equivalentItems:t,candidates:r})}const C=[];for(const t of[...I].sort((t,e)=\u003et.candidates.length-e.candidates.length)){const e=0===t.candidates.length?0:d%t.candidates.length,n=[...t.candidates.slice(e),...t.candidates.slice(0,e)].find(e=\u003e{const n=xtt(e.connectorPoints,s);return C.every(e=\u003ee.netKey===t.item.netKey||n.every(t=\u003ee.segments.every(e=\u003eT8(t.start,t.end,e.start,e.end)\u003e=_-utt)))});if(!n)return null;t.candidates=[n],C.push({netKey:t.item.netKey,segments:xtt(n.connectorPoints,s)})}const P=new Set(I.map(t=\u003et.candidates[0].node));for(const t of C)for(const e of t.segments){const t=Math.max(0,Math.floor((Math.min(e.start.x,e.end.x)-_-h.minX)/u)),n=Math.min(p-1,Math.ceil((Math.max(e.start.x,e.end.x)+_-h.minX)/u)),o=Math.max(0,Math.floor((Math.min(e.start.y,e.end.y)-_-h.minY)/u)),i=Math.min(m-1,Math.ceil((Math.max(e.start.y,e.end.y)+_-h.minY)/u));for(let r=o;r\u003c=i;r++)for(let o=t;o\u003c=n;o++){const t=r*p+o;if(!b[t]||P.has(t))continue;const n=f(t);T8(e.start,e.end,n,n)\u003c_-utt\u0026\u0026(b[t]=0)}}const M=1+I.length,N=M+g,w=N+g,T=new vtt(w+1);for(let t=0;t\u003cI.length;t++){const e=1+t;T.addEdge(0,e,1);for(const n of I[t].candidates)T.addEdge(e,M+n.node,1,{gridNode:n.node})}for(let t=0;t\u003cg;t++){if(!b[t])continue;T.addEdge(M+t,N+t,1);const o=t%p,r=Math.floor(t/p);for(const e of i.neighbors[t])b[e]\u0026\u0026T.addEdge(N+t,M+e,1,{gridNode:e});(\"any\"===e\u0026\u0026((!n||n.has(\"left\"))\u0026\u00260===o||(!n||n.has(\"right\"))\u0026\u0026o===p-1||(!n||n.has(\"down\"))\u0026\u00260===r||(!n||n.has(\"up\"))\u0026\u0026r===m-1)||\"left\"===e\u0026\u00260===o||\"right\"===e\u0026\u0026o===p-1||\"down\"===e\u0026\u00260===r||\"up\"===e\u0026\u0026r===m-1)\u0026\u0026T.addEdge(N+t,w,1,{isSink:!0})}const R=T.maximumFlow(0,w,I.length),E=t=\u003e{const e=1+t;return T.edges[0].some(t=\u003et.to===e\u0026\u00261===t.initialCapacity\u0026\u00260===t.capacity)};if(R!==I.length\u0026\u0026ptt){const t=I.flatMap((t,e)=\u003eE(e)?[]:[t.item.connection.connection.name]);console.error(\"single-layer flow group failed\",{direction:e,achievedFlow:R,requiredFlow:I.length,unmatchedConnections:t})}const A=[],O=[],k=[];for(let t=0;t\u003cI.length;t++){const e=I[t];if(!E(t)){k.push(...e.equivalentItems);continue}const n=1+t,o=T.edges[n].find(t=\u003e1===t.initialCapacity\u0026\u00260===t.capacity\u0026\u0026void 0!==t.gridNode);if(void 0===o?.gridNode)return null;const i=e.candidates.find(t=\u003et.node===o.gridNode);if(!i)return null;const r=[f(i.node)];let a=i.node;const c=[a];for(let t=0;t\u003c=g;t++){const t=N+a,e=T.edges[t].find(t=\u003e1===t.initialCapacity\u0026\u00260===t.capacity\u0026\u0026(void 0!==t.gridNode||t.isSink));if(!e)return null;if(e.isSink)break;if(void 0===e.gridNode)return null;a=e.gridNode,c.push(a),r.push(f(a))}O.push(...c);const l=ytt(btt(_tt([...i.connectorPoints,...r.slice(1)]),u/2)),d=xtt(l,s);for(const t of e.equivalentItems)A.push({item:t,points:l,segments:d})}return{routes:A,usedNodes:O,unmatchedItems:k}}function Itt(t,e){const n=ftt(t,e),o=ftt(e,t).reverse();return n.length===o.length\u0026\u0026n.every((t,e)=\u003eM8(t,o[e])\u003cutt)?[n]:[n,o]}function Ctt(t,e){return Math.abs(t.x-e.minX)\u003cutt?\"left\":Math.abs(t.x-e.maxX)\u003cutt?\"right\":Math.abs(t.y-e.minY)\u003cutt?\"down\":Math.abs(t.y-e.maxY)\u003cutt?\"up\":null}function Ptt(t){const{items:e,grid:n,obstacles:o,traceWidth:i,clearance:r,availableBoundaryRegions:s}=t,a=s?new Set(s.map(t=\u003et.direction)):void 0,c=new Set(e.filter(t=\u003et.connection.sourceObstacle.width\u003e2\u0026\u0026t.connection.sourceObstacle.height\u003e2));let l=null;for(let t=0;t\u003c4;t++){const t=e.filter(t=\u003e!c.has(t));let s=null;for(let e=0;e\u003c4;e++){const c=Stt({direction:\"any\",availableDirections:a,items:t,grid:n,obstacles:o,traceWidth:i,clearance:r,occupiedNodes:new Uint8Array(n.nodeCount),acceptedSegments:[],connectorSelectionOffset:e});if(c\u0026\u0026((!s||c.routes.length\u003es.routes.length)\u0026\u0026(s=c),c.routes.length===t.length))break}if(!s)return null;if(s.routes.length===t.length){l=s;break}const d=new Map;for(const e of t)d.set(e.netKey,(d.get(e.netKey)??0)+1);let h=!1;for(const t of s.unmatchedItems)(d.get(t.netKey)??0)\u003c2||(c.add(t),h=!0);if(!h)return null}if(!l)return null;const d=[...l.routes],h=i/2+r,u=i+r;for(const t of c){const e=d.filter(e=\u003ee.item.netKey===t.netKey).flatMap(t=\u003et.points.map((e,n)=\u003e({route:t,point:e,pointIndex:n}))).sort((e,n)=\u003eNumber(n.route.item.bus.componentId===t.bus.componentId)-Number(e.route.item.bus.componentId===t.bus.componentId)||M8(t.source,e.point)-M8(t.source,n.point));let n=null;for(const r of e){for(const e of Itt(t.source,r.point)){const s=xtt(e,i),a=s.every(e=\u003eo.every(n=\u003egtt(n,t)||A8(e,n)\u003e=h-utt)),c=s.every(e=\u003ed.every(n=\u003en.item.netKey===t.netKey||n.segments.every(t=\u003eT8(e.start,e.end,t.start,t.end)\u003e=u-utt)));if(!a||!c)continue;const l=ytt(_tt([...e,...r.route.points.slice(r.pointIndex+1)]));n={item:t,points:l,segments:xtt(l,i)};break}if(n)break}if(!n)return null;d.push(n)}const p=d.map(t=\u003efunction(t,e){const{item:n,points:o,segments:i}=t,r=o.map((t,o)=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:e,layer:\"top\",...0===o\u0026\u0026n.connection.sourcePoint.pcb_port_id?{start_pcb_port_id:n.connection.sourcePoint.pcb_port_id}:{}})),s=x8({connectionName:n.connection.connection.name,sourcePointIndex:n.connection.sourcePointIndex});return{busId:n.bus.busId,connectionName:n.connection.connection.name,connectionIndex:n.connection.connectionIndex,sourcePointIndex:n.connection.sourcePointIndex,sourcePoint:n.connection.sourcePoint,sourceObstacle:n.connection.sourceObstacle,sourceLayer:n.connection.sourceLayer,targetPoint:n.connection.targetPoint,targetLayer:\"top\",termination:n.bus.termination,direction:n.bus.direction,exitPoint:o.at(-1),trace:{type:\"pcb_trace\",pcb_trace_id:s.traceId,connection_name:n.connection.connection.name,connectsTo:[...n.connection.sourcePoint.pointId?[n.connection.sourcePoint.pointId]:[],...n.connection.sourcePoint.pcb_port_id?[n.connection.sourcePoint.pcb_port_id]:[],s.boundaryExitPointId],route:r},segments:i,length:i.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}(t,i));if(!function(t){const{plans:e,items:n,obstacles:o,traceWidth:i,clearance:r}=t,s=new Map(n.map(t=\u003e[t.connection.connection.name,t.netKey])),a=new Map,c=new Map;for(const t of e){const e=s.get(t.connectionName),n=a.get(e)??[],o=c.get(e)??new Set;for(const e of t.segments){const t=[e.start,e.end].map(t=\u003e`${t.x.toFixed(6)}:${t.y.toFixed(6)}`).sort().join(\":\");o.has(t)||(o.add(t),n.push(e))}a.set(e,n),c.set(e,o)}const l=i/2+r;for(const[t,e]of a)for(const n of e)for(const e of o)if(!(e.connectedTo.includes(t)||A8(n,e)\u003e=l-utt))return ptt\u0026\u0026console.error(\"single-layer route violates obstacle clearance\",{netKey:t,segment:n,obstacleId:e.obstacleId,distance:A8(n,e),requiredObstacleDistance:l}),!1;const d=i+r,h=[...a];for(let t=0;t\u003ch.length;t++)for(let e=t+1;e\u003ch.length;e++)for(const n of h[t][1])for(const o of h[e][1])if(T8(n.start,n.end,o.start,o.end)\u003cd-utt)return ptt\u0026\u0026console.error(\"single-layer routes violate copper clearance\",{firstNetKey:h[t][0],secondNetKey:h[e][0],first:n,second:o,distance:T8(n.start,n.end,o.start,o.end),requiredRouteDistance:d}),!1;return!0}({plans:p,items:e,obstacles:o,traceWidth:i,clearance:r}))return ptt\u0026\u0026console.error(\"single-layer adaptive exits failed exact clearance\"),null;for(const t of p){const o=Ctt(t.exitPoint,n.boundary);if(!o||a\u0026\u0026!a.has(o))return null;const i=e.find(e=\u003ee.connection.connection.name===t.connectionName);i.bus.direction=o;const r=s?.filter(t=\u003et.direction===o),c=\"up\"===o||\"down\"===o?t.exitPoint.x:t.exitPoint.y;i.bus.preferredExit=r?.toSorted((t,e)=\u003eMath.abs(c-D7(t,n.boundary))-Math.abs(c-D7(e,n.boundary)))[0]?.preferredExit??(\"up\"===o?\"top\":\"down\"===o?\"bottom\":o),t.direction=o}const m=new Map(p.map(t=\u003e[t.connectionName,t]));return e.map(t=\u003em.get(t.connection.connection.name))}function Mtt(t){const{srj:e,buses:n,traceWidth:o,clearance:i,availableBoundaryRegions:r}=t;if(n.some(t=\u003e1!==t.connections.length))return null;const s=n.flatMap(t=\u003et.connections.map(e=\u003e({bus:t,connection:e,source:{x:e.sourcePoint.x,y:e.sourcePoint.y},netKey:mtt(e)}))),a=e.obstacles.filter(t=\u003et.layers.includes(\"top\")),c=n[0]?.sharedBoundary;if(!c)return[];const l=function(t){const{boundary:e,obstacles:n,traceWidth:o,clearance:i}=t,r=o+i,s=Math.round((e.maxX-e.minX)/r)+1,a=Math.round((e.maxY-e.minY)/r)+1,c=s*a,l=Array.from({length:c},(t,n)=\u003e({x:e.minX+n%s*r,y:e.minY+Math.floor(n/s)*r})),d=o/2+i,h=new Map;for(let t=0;t\u003cn.length;t++){const e=n[t],o=Math.floor((e.center.x-e.width/2-d)/1),i=Math.floor((e.center.x+e.width/2+d)/1),r=Math.floor((e.center.y-e.height/2-d)/1),s=Math.floor((e.center.y+e.height/2+d)/1);for(let e=o;e\u003c=i;e++)for(let n=r;n\u003c=s;n++){const o=`${e}:${n}`,i=h.get(o)??[];i.push(t),h.set(o,i)}}const u=(t,e=t)=\u003e{const o=Math.floor(Math.min(t.x,e.x)/1),i=Math.floor(Math.max(t.x,e.x)/1),r=Math.floor(Math.min(t.y,e.y)/1),s=Math.floor(Math.max(t.y,e.y)/1),a=new Set;for(let t=o;t\u003c=i;t++)for(let e=r;e\u003c=s;e++)for(const n of h.get(`${t}:${e}`)??[])a.add(n);return[...a].map(t=\u003en[t])},p=new Uint8Array(c);for(let t=0;t\u003cc;t++){const e=l[t];u(e).every(t=\u003eE8(e,t)\u003e=d-utt)\u0026\u0026(p[t]=1)}const m=Array.from({length:c},()=\u003e[]);for(let t=0;t\u003cc;t++){if(!p[t])continue;const e=t%s,n=Math.floor(t/s);for(const[i,r]of[[1,0],[0,1]]){const c=e+i,h=n+r;if(c\u003e=s||h\u003e=a)continue;const g=h*s+c;if(!p[g])continue;const f={start:l[t],end:l[g],width:o,layer:\"top\"};u(f.start,f.end).some(t=\u003eA8(f,t)\u003cd-utt)||(m[t].push(g),m[g].push(t))}}return{boundary:e,step:r,columnCount:s,rowCount:a,nodeCount:c,points:l,obstacleFreeNodes:p,neighbors:m}}({boundary:c,obstacles:a,traceWidth:o,clearance:i});ptt\u0026\u0026console.error(\"single-layer adaptive-exit grid ready\",{nodeCount:l.nodeCount});const d=Ptt({items:s,grid:l,obstacles:a,traceWidth:o,clearance:i,availableBoundaryRegions:r});return d||null}function Ntt(t){return\"left\"===t||\"right\"===t}function wtt(t){return\"right\"===t||\"up\"===t?1:-1}function Ttt(t,e){return Ntt(e)?t.x:t.y}function Rtt(t,e){return Ntt(e)?t.y:t.x}function Ett(t,e,n){return Ntt(n)?{x:t,y:e}:{x:e,y:t}}function Att(t){switch(t.direction){case\"right\":return t.sharedBoundary.maxX;case\"left\":return t.sharedBoundary.minX;case\"up\":return t.sharedBoundary.maxY;case\"down\":return t.sharedBoundary.minY}}function Ott(t){if(t.length\u003c3)return t;const e=[t[0]];for(let n=1;n\u003ct.length-1;n++){const o=e.at(-1),i=t[n],r=t[n+1],s={x:Math.sign(i.x-o.x),y:Math.sign(i.y-o.y)},a={x:Math.sign(r.x-i.x),y:Math.sign(r.y-i.y)};s.x===a.x\u0026\u0026s.y===a.y||e.push(i)}return e.push(t.at(-1)),e}function ktt(t,e){const n=[];for(let o=1;o\u003ct.length;o++)M8(t[o-1],t[o])\u003c1e-9||n.push({start:t[o-1],end:t[o],width:e,layer:\"top\"});return n}function Ltt(t){const{item:e,srj:n,acceptedSegments:o,traceWidth:i,clearance:r}=t,s=e.cornerChannelPrefixes;if(!s)return null;const a=e.direction,c=wtt(a),l=Att(e.bus),d=i+r,h=i/2+r,u=Ntt(a)?e.bus.sharedBoundary.minY:e.bus.sharedBoundary.minX,p=Ntt(a)?e.bus.sharedBoundary.maxY:e.bus.sharedBoundary.maxX,m=u+i/2,g=p-i/2,f=Rtt(e.connection.exitTargetPoint??e.connection.targetPoint,a),y=d/2,_=new Set([Math.max(m,Math.min(g,f))]);for(let t=Math.ceil(m/y)*y;t\u003c=g+1e-9;t+=y)_.add(Number(t.toFixed(9)));const b=[..._].toSorted((t,e)=\u003eMath.abs(t-f)-Math.abs(e-f));for(const t of s){const s=t.at(-1),u=Rtt(s,a);for(const p of b){const m=Math.abs(p-u),g=Ett(Ttt(s,a)+c*d,u,a),f=Ett(Ttt(g,a)+c*m,p,a);if(c*(l-Ttt(f,a))\u003c-1e-9)continue;const y=Ett(l,p,a),_=[...t,g,...m\u003e1e-9?[f]:[]];M8(_.at(-1),y)\u003e1e-9\u0026\u0026_.push(y);const b=Ott(_),x=ktt(b,i);if(!x.every(t=\u003en.obstacles.every(n=\u003en===e.connection.sourceObstacle||!n.layers.includes(\"top\")||A8(t,n)\u003e=h-1e-9)))continue;if(x.every(t=\u003eo.every(e=\u003eT8(t.start,t.end,e.start,e.end)\u003e=i+r-1e-9)))return{item:e,points:b,track:p}}}return null}function Dtt(t){const{route:e,direction:n,exitAxis:o,signedShift:i,maximumShift:r,obstacles:s,requiredObstacleDistance:a}=t;if(r\u003c=1e-9||Math.abs(i)\u003c=1e-9)return 0;const c=Math.sign(i),l=t=\u003e{if(t\u003c=1e-9)return!0;const i={start:Ett(o-wtt(n)*t,e.track,n),end:Ett(o,e.track+c*t,n),width:0,layer:\"top\"};return s.every(t=\u003et===e.item.connection.sourceObstacle||!t.layers.includes(\"top\")||A8(i,t)\u003e=a-1e-9)};if(l(r))return r;let d=0,h=r;for(let t=0;t\u003c32;t++){const t=(d+h)/2;l(t)?d=t:h=t}return d}function ztt(t){const{requestedTracks:e,currentTracks:n,candidateTracks:o,maximumShifts:i}=t,r=e.length+1,s=o.length+1,a=Array.from({length:r},()=\u003enew Float64Array(s).fill(Number.POSITIVE_INFINITY)),c=Array.from({length:r},()=\u003enew Uint8Array(s));a[0].fill(0);for(let t=1;t\u003cr;t++)for(let r=1;r\u003cs;r++){const s=a[t][r-1],l=Math.abs(e[t-1]-o[r-1]),d=Math.abs(n[t-1]-o[r-1])\u003ei[t-1]+1e-9?Number.POSITIVE_INFINITY:a[t-1][r-1]+l;d\u003cs?(a[t][r]=d,c[t][r]=1):a[t][r]=s}if(!Number.isFinite(a.at(-1).at(-1)))return null;const l=[];let d=e.length,h=o.length;for(;d\u003e0\u0026\u0026h\u003e0;)c[d][h]\u0026\u0026(l.push(o[h-1]),d--),h--;return d\u003e0?null:l.reverse()}function Ftt(t){const{direction:e,activeRoutes:n,obstacles:o,boundaryMinimum:i,boundaryMaximum:r,traceWidth:s,clearance:a,requestedTracks:c,maximumShifts:l}=t,d=s+a,h=s/2+a;let u=null,p=Number.POSITIVE_INFINITY;for(const t of Array.from({length:Math.round(d/s)},(t,e)=\u003ee*s)){const a=[];for(let n=Math.ceil((i-t)/d)*d+t;n\u003c=r+1e-9;n+=d){const t=Math.round(n/s)*s;o.every(n=\u003e{const o=Rtt(n.center,e),i=Ntt(e)?n.height:n.width;return Math.abs(t-o)\u003e=i/2+h-1e-9})\u0026\u0026a.push(t)}const m=ztt({requestedTracks:c,currentTracks:n.map(t=\u003et.track),candidateTracks:a,maximumShifts:l});if(!m)continue;const g=m.reduce((t,e,n)=\u003et+Math.abs(e-c[n]),0);g\u003cp\u0026\u0026(p=g,u=m)}return u}function Btt(t,e){switch(e){case\"up\":return\"top-left\"===t?\"minimum\":\"top-right\"===t?\"maximum\":null;case\"down\":return\"bottom-left\"===t?\"minimum\":\"bottom-right\"===t?\"maximum\":null;case\"left\":return\"bottom-left\"===t?\"minimum\":\"top-left\"===t?\"maximum\":null;case\"right\":return\"bottom-right\"===t?\"minimum\":\"top-right\"===t?\"maximum\":null}}function jtt(t){const{items:e,direction:n,boundaryMinimum:o,boundaryMaximum:i,traceWidth:r,clearance:s,borderDistribution:a,currentTrackByConnectionName:c}=t,l=t=\u003ec.get(t.connection.connection.name)??Rtt(t.source,n),d=[...e].toSorted((t,e)=\u003el(t)-l(e)||t.connection.connection.name.localeCompare(e.connection.connection.name)),h=r+s,u=o+r/2,p=i-r/2;if(p-u\u003ch*Math.max(d.length-1,0)-1e-9)return null;const m=d.map(l);let g=[...m],f=h;const y=new Set;if(\"even\"===a\u0026\u0026d.length\u003e1){const t=m[0],e=m.at(-1),n=Math.max(h,(e-t)/(d.length-1)),o=t=\u003e{const e=[...m],n=Math.floor(d.length/2),o=d.length%2==0?n-1:n;if(o!==n){const i=e[n]-e[o];if(i\u003ct){const r=(t-i)/2;e[o]=e[o]-r,e[n]=e[n]+r}}for(let n=o-1;n\u003e=0;n--)e[n]=Math.min(e[n],e[n+1]-t);for(let o=n+1;o\u003ce.length;o++)e[o]=Math.max(e[o],e[o-1]+t);return e},i=t=\u003et[0]\u003e=u-1e-9\u0026\u0026t.at(-1)\u003c=p+1e-9;if(g=o(n),i(g))f=n;else{let t=h,e=n;if(g=o(t),!i(g))return null;for(let n=0;n\u003c32;n++){const n=(t+e)/2,r=o(n);i(r)?(t=n,g=r):e=n}f=t}for(const t of d)y.add(t.connection.connection.name)}const _=[],b=[];for(let t=0;t\u003cd.length;t++){const e=d[t],o=e.bus.preferredExit;if(!o?.includes(\"-\"))continue;const i=Btt(o,n);if(!i)return null;y.add(e.connection.connection.name),\"minimum\"===i?_.push(t):b.push(t)}if(_.some((t,e)=\u003et!==e)||b.some((t,e)=\u003et!==d.length-b.length+e))return null;const x=2*h;if(_.length\u003e0){g[0]=u+x;for(let t=1;t\u003c_.length;t++){const e=Math.max(f,m[t]-m[t-1]);g[t]=g[t-1]+e}}if(b.length\u003e0){const t=d.length-1;g[t]=p-x;for(let e=t-1;e\u003e=d.length-b.length;e--){const t=Math.max(f,m[e+1]-m[e]);g[e]=g[e+1]-t}}return{byConnectionName:new Map(d.map((t,e)=\u003e[t.connection.connection.name,g[e]])),enforcedConnectionNames:y}}function $tt(t){const{item:e,points:n,segments:o}=t,i=n.map((t,n)=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:o[0]?.width??.1,layer:\"top\",...0===n\u0026\u0026e.connection.sourcePoint.pcb_port_id?{start_pcb_port_id:e.connection.sourcePoint.pcb_port_id}:{}})),r=x8({connectionName:e.connection.connection.name,sourcePointIndex:e.connection.sourcePointIndex});return{busId:e.bus.busId,connectionName:e.connection.connection.name,connectionIndex:e.connection.connectionIndex,sourcePointIndex:e.connection.sourcePointIndex,sourcePoint:e.connection.sourcePoint,sourceObstacle:e.connection.sourceObstacle,sourceLayer:e.connection.sourceLayer,targetPoint:e.connection.targetPoint,targetLayer:\"top\",termination:e.bus.termination,direction:e.direction,exitPoint:n.at(-1),trace:{type:\"pcb_trace\",pcb_trace_id:r.traceId,connection_name:e.connection.connection.name,connectsTo:[...e.connection.sourcePoint.pointId?[e.connection.sourcePoint.pointId]:[],...e.connection.sourcePoint.pcb_port_id?[e.connection.sourcePoint.pcb_port_id]:[],r.boundaryExitPointId],route:i},segments:o,length:o.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}function Ytt(t){const{srj:e,buses:n,traceWidth:o,clearance:i,borderDistribution:r}=t,s=o/2+i,a=new Map,c=new Map,l=n.flatMap(t=\u003et.connections.map(n=\u003e{const r={x:n.sourcePoint.x,y:n.sourcePoint.y},s=function(t){const{srj:e,bus:n,connection:o,traceWidth:i,clearance:r}=t,s=n.direction,a=wtt(s),c={x:o.sourcePoint.x,y:o.sourcePoint.y},l=Ttt(c,s),d=Rtt(c,s),h=i/2+r,u=(()=\u003e{switch(s){case\"right\":return n.componentBounds.maxX+h;case\"left\":return n.componentBounds.minX-h;case\"up\":return n.componentBounds.maxY+h;case\"down\":return n.componentBounds.minY-h}})(),p=t=\u003eMath.min(...e.obstacles.filter(t=\u003et!==o.sourceObstacle\u0026\u0026t.layers.includes(\"top\")).map(e=\u003eA8(t,e))),m={start:c,end:Ett(u,d,s),width:i,layer:\"top\"};if(p(m)\u003e=h-1e-9)return null;const g=Ntt(s)?{minimum:n.componentBounds.minY,maximum:n.componentBounds.maxY}:{minimum:n.componentBounds.minX,maximum:n.componentBounds.maxX},f=a*(u-l),y=Rtt(o.exitTargetPoint??o.targetPoint,s),_=i+r,b=Att(n),x=[-1,1].map(t=\u003e{const e=t*((t\u003c0?g.minimum-h:g.maximum+h)-d),o=Math.max(f,e),r=Ett(l+a*o,d+t*o,s);if(a*(b-Ttt(r,s))\u003c_-1e-9)return null;const u=[c,r];if(!u.every(t=\u003et.x\u003e=n.sharedBoundary.minX-1e-9\u0026\u0026t.x\u003c=n.sharedBoundary.maxX+1e-9\u0026\u0026t.y\u003e=n.sharedBoundary.minY-1e-9\u0026\u0026t.y\u003c=n.sharedBoundary.maxY+1e-9))return null;const m=Math.min(...ktt(u,i).map(p));return m\u003ch-1e-9?null:{points:u,obstacleDistance:m,targetDistance:Math.abs(Rtt(r,s)-y)}}).filter(t=\u003enull!==t).toSorted((t,e)=\u003ee.obstacleDistance-t.obstacleDistance||t.targetDistance-e.targetDistance);return x.length\u003e0?x.map(t=\u003et.points):null}({srj:e,bus:t,connection:n,traceWidth:o,clearance:i});return{bus:t,connection:n,direction:t.direction,source:r,...s?{cornerChannelPrefixes:s}:{}}}));for(const t of[\"left\",\"right\",\"up\",\"down\"]){const n=wtt(t),d=l.filter(e=\u003ee.direction===t\u0026\u0026!e.cornerChannelPrefixes);if(0===d.length)continue;const h=Ntt(t)?d[0].bus.sharedBoundary.minY:d[0].bus.sharedBoundary.minX,u=Ntt(t)?d[0].bus.sharedBoundary.maxY:d[0].bus.sharedBoundary.maxX,p=Att(d[0].bus),m=new Map,g=new Map,f=new Map;for(const e of d){const n=Ttt(e.source,t),o=n.toFixed(6);f.set(o,n);const i=m.get(o)??[];i.push(e),m.set(o,i)}for(const[n,o]of m){const i=f.get(n),r=new Set(o.map(t=\u003et.bus.componentId));g.set(n,e.obstacles.filter(e=\u003ee.layers.includes(\"top\")\u0026\u0026!!e.componentId\u0026\u0026r.has(e.componentId)\u0026\u0026Math.abs(Ttt(e.center,t)-i)\u003c1e-6))}const y=[...f.values()].toSorted((t,e)=\u003en*(t-e)),_=new Map;for(let e=0;e\u003cy.length;e++){const r=y[e],a=r.toFixed(6);for(const e of m.get(a)??[]){const o=Ntt(t)?e.connection.sourceObstacle.width:e.connection.sourceObstacle.height,i=Math.max(e.connection.sourceObstacle.width,e.connection.sourceObstacle.height)\u003c1.5?o/2+s:0,a=Ett(r+n*i,Rtt(e.source,t),t);_.set(e.connection.connection.name,{item:e,points:M8(e.source,a)\u003e1e-9?[e.source,a]:[e.source],track:Rtt(e.source,t)})}const c=y[e+1]??p;if(0===_.size||n*(c-r)\u003c=1e-9)continue;const l=[..._.values()].toSorted((t,e)=\u003et.track-e.track||t.item.connection.connection.name.localeCompare(e.item.connection.connection.name)),d=y.slice(e+1,e+3).flatMap(t=\u003eg.get(t.toFixed(6))??[]),f=l.map(e=\u003eMath.abs(c-Ttt(e.points.at(-1),t))),b=Ftt({direction:t,activeRoutes:l,obstacles:d,boundaryMinimum:h,boundaryMaximum:u,traceWidth:o,clearance:i,requestedTracks:l.map(t=\u003et.track),maximumShifts:f});if(!b)return null;for(let e=0;e\u003cl.length;e++){const o=l[e],i=b[e],r=Math.abs(i-o.track),s=Ett(Ttt(o.points.at(-1),t)+n*r,i,t);M8(o.points.at(-1),s)\u003e1e-9\u0026\u0026o.points.push(s);const a=Ett(c,i,t);M8(o.points.at(-1),a)\u003e1e-9\u0026\u0026o.points.push(a),o.track=i}}const b=jtt({items:d,direction:t,boundaryMinimum:h,boundaryMaximum:u,traceWidth:o,clearance:i,borderDistribution:r,currentTrackByConnectionName:new Map([..._.values()].map(t=\u003e[t.item.connection.connection.name,t.track]))});if(!b)return null;const x=[..._.values()].toSorted((t,e)=\u003et.track-e.track||t.item.connection.connection.name.localeCompare(e.item.connection.connection.name)),v=new Map,S=o+i;let I=S;for(const t of x){const e=t.item.connection.connection.name;if(!b.enforcedConnectionNames.has(e))continue;b.byConnectionName.get(e)-t.track\u003e=-1e-9||(v.set(e,I),I+=2*S)}let C=S;for(let t=x.length-1;t\u003e=0;t--){const e=x[t],n=e.item.connection.connection.name;if(!b.enforcedConnectionNames.has(n))continue;b.byConnectionName.get(n)-e.track\u003c=1e-9||(v.set(n,C),C+=2*S)}for(const o of x){const i=o.item.connection.connection.name,r=b.byConnectionName.get(i)??o.track,a=v.get(i)??0,c=o.points.at(-2),l=c?n*(p-Ttt(c,t)):0,d=r-o.track,h=Math.min(Math.abs(d),Math.max(0,l-a)),u=Dtt({route:o,direction:t,exitAxis:p,signedShift:d,maximumShift:h,obstacles:e.obstacles,requiredObstacleDistance:s}),m=Math.sign(d)*u;b.byConnectionName.set(i,o.track+m)}for(const t of b.enforcedConnectionNames)c.set(t,b.byConnectionName.get(t));for(const e of x){const o=e.item.connection.connection.name,i=b.byConnectionName.get(o)??e.track,r=Math.abs(i-e.track),s=v.get(o)??0,a=p-n*(r\u003e1e-9?s+r:0),c=e.points.at(-1);if(Math.abs(Ttt(c,t)-p)\u003e1e-6)return null;const l=e.points.at(-2);if(l\u0026\u0026(Math.abs(Rtt(l,t)-e.track)\u003e1e-6||n*(a-Ttt(l,t))\u003c-1e-6))return null;const d=Ett(a,e.track,t);l\u0026\u0026M8(l,d)\u003c1e-9?e.points.pop():e.points[e.points.length-1]=d}for(const e of x){const o=e.item.connection.connection.name,i=b.byConnectionName.get(o)??e.track,r=Math.abs(i-e.track),s=v.get(o)??0;r\u003e1e-9\u0026\u0026s\u003e1e-9\u0026\u0026e.points.push(Ett(Ttt(e.points.at(-1),t)+n*s,e.track,t)),r\u003e1e-9\u0026\u0026(e.points.push(Ett(Ttt(e.points.at(-1),t)+n*r,i,t)),e.track=i);const c=Ett(p,e.track,t);if(M8(e.points.at(-1),c)\u003e1e-9){if(n*(p-Ttt(e.points.at(-1),t))\u003c-1e-6)return null;e.points.push(c)}a.set(o,e)}}const d=[...a.values()].flatMap(t=\u003ektt(Ott(t.points),o));for(const t of l){if(!t.cornerChannelPrefixes)continue;const n=Ltt({item:t,srj:e,acceptedSegments:d,traceWidth:o,clearance:i});if(!n)return null;a.set(t.connection.connection.name,n),d.push(...ktt(Ott(n.points),o))}if(a.size!==l.length)return null;const h=(o+i)/2+1e-6;for(const[t,e]of c){const n=a.get(t);if(!n||Math.abs(n.track-e)\u003eh)return null}const u=l.map(t=\u003e{const e=Ott(a.get(t.connection.connection.name).points);return{item:t,points:e,segments:ktt(e,o)}});return function(t){const{paths:e,obstacles:n,traceWidth:o,clearance:i}=t,r=o/2+i,s=o+i;for(const t of e){if(Math.abs(Ttt(t.points.at(-1),t.item.direction)-Att(t.item.bus))\u003e1e-6)return!1;for(const e of t.segments)for(const o of n)if(o!==t.item.connection.sourceObstacle\u0026\u0026o.layers.includes(\"top\")\u0026\u0026A8(e,o)\u003cr-1e-9)return!1}for(let t=0;t\u003ce.length;t++)for(let n=t+1;n\u003ce.length;n++)for(const o of e[t].segments)for(const t of e[n].segments)if(T8(o.start,o.end,t.start,t.end)\u003cs-1e-9)return!1;return!0}({paths:u,obstacles:e.obstacles,traceWidth:o,clearance:i})?u.map($tt):null}var Xtt=1e-6;function Vtt(t,e){return M8(t,e)\u003c=Xtt}function Wtt(t){return\"layer\"in t?[t.layer]:t.layers}function Htt(t){return[...t.segments,...t.planeEndpointSegments??[]]}function Gtt(t){return[t.via,t.planeEndpointVia].filter(t=\u003eBoolean(t))}function Utt(t,e){return Vtt(t,e)\u0026\u0026Wtt(t).join(\"\\0\")===Wtt(e).join(\"\\0\")\u0026\u0026t.pointId===e.pointId\u0026\u0026t.pcb_port_id===e.pcb_port_id}function Ztt(t,e){const n=t.x\u003e=e.minX-Xtt\u0026\u0026t.x\u003c=e.maxX+Xtt\u0026\u0026t.y\u003e=e.minY-Xtt\u0026\u0026t.y\u003c=e.maxY+Xtt,o=Math.abs(t.x-e.minX)\u003c=Xtt||Math.abs(t.x-e.maxX)\u003c=Xtt||Math.abs(t.y-e.minY)\u003c=Xtt||Math.abs(t.y-e.maxY)\u003c=Xtt;return n\u0026\u0026o}function qtt(t,e){return t.x\u003e=e.minX-Xtt\u0026\u0026t.x\u003c=e.maxX+Xtt\u0026\u0026t.y\u003e=e.minY-Xtt\u0026\u0026t.y\u003c=e.maxY+Xtt}function Jtt(t,e,n,o,i){t.push({code:e,message:n,...o?{connectionName:o.connectionName,busId:o.busId}:{},...i?{otherConnectionName:i}:{}})}function Ktt(t){const{trace:e,plan:n,issues:o}=t,i=[];let r,s;for(const t of e.route)\"via\"!==t.route_type?\"wire\"===t.route_type?s?(Vtt(t,s)\u0026\u0026t.layer===s.to_layer||Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} does not continue from its via on ${s.to_layer}`,n),r=t,s=void 0):(r\u0026\u0026(r.layer!==t.layer?Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} changes from ${r.layer} to ${t.layer} without a via`,n):Vtt(r,t)||i.push({start:{x:r.x,y:r.y},end:{x:t.x,y:t.y},width:t.width,layer:t.layer})),r=t):Jtt(o,\"unsupported-route-point\",`Trace ${e.pcb_trace_id} contains unsupported ${t.route_type} geometry`,n):(r\u0026\u0026Vtt(r,t)\u0026\u0026r.layer===t.from_layer||Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} reaches a via without a matching ${t.from_layer} wire endpoint`,n),s=t);return s\u0026\u0026Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} ends at a via without a wire on ${s.to_layer}`,n),i}function Qtt(t){const{plan:e,preparedBus:n,inputSrj:o,outputSrj:i,sharedBoundary:r,issues:s}=t,a=o.connections[e.connectionIndex];if(!a||a.name!==e.connectionName)return void Jtt(s,\"connection-mismatch\",`Plan index ${e.connectionIndex} does not identify connection ${e.connectionName}`,e);const c=n?.connections.find(t=\u003et.connectionIndex===e.connectionIndex);if(c\u0026\u0026c.sourcePointIndex===e.sourcePointIndex\u0026\u0026Utt(c.sourcePoint,e.sourcePoint)\u0026\u0026c.sourceObstacle.obstacleId===e.sourceObstacle.obstacleId||Jtt(s,\"source-mismatch\",`Plan ${e.connectionName} does not start at its prepared component endpoint`,e),n?.termination.type!==e.termination.type\u0026\u0026Jtt(s,\"termination-mismatch\",`Plan ${e.connectionName} does not use its bus termination`,e),0===e.segments.length||e.length\u003c=Xtt)Jtt(s,\"not-broken-out\",`Plan ${e.connectionName} has no non-zero escape geometry`,e);else{const t={minX:Math.min(o.bounds.minX,r.minX),maxX:Math.max(o.bounds.maxX,r.maxX),minY:Math.min(o.bounds.minY,r.minY),maxY:Math.max(o.bounds.maxY,r.maxY)};e.segments.some(e=\u003e!qtt(e.start,t)||!qtt(e.end,t))\u0026\u0026Jtt(s,\"outside-routing-bounds\",`Plan ${e.connectionName} leaves the routable SRJ/shared-boundary area`,e),Vtt(e.segments[0].start,e.sourcePoint)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} does not start at its source pad`,e),Vtt(e.segments.at(-1).end,e.exitPoint)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} does not end at its declared exit`,e);for(let t=1;t\u003ce.segments.length;t++){const n=e.segments[t-1],o=e.segments[t];Vtt(n.end,o.start)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} has a gap between route segments`,e),n.layer===o.layer||e.via\u0026\u0026Vtt(n.end,e.via.center)\u0026\u0026e.via.spanLayers.includes(n.layer)\u0026\u0026e.via.spanLayers.includes(o.layer)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} changes layers without a connecting via`,e)}}const l=Ktt({trace:e.trace,plan:e,issues:s});if((l.length!==e.segments.length||l.some((t,n)=\u003e{const o=e.segments[n];return!o||t.layer!==o.layer||Math.abs(t.width-o.width)\u003eXtt||!Vtt(t.start,o.start)||!Vtt(t.end,o.end)}))\u0026\u0026Jtt(s,\"trace-plan-mismatch\",`Trace ${e.trace.pcb_trace_id} does not encode its declared route segments`,e),e.planeEndpointTrace||e.planeEndpointSegments||e.planeEndpointVia)if(e.planeEndpointTrace\u0026\u0026e.planeEndpointSegments\u0026\u0026e.planeEndpointVia){const t=Ktt({trace:e.planeEndpointTrace,plan:e,issues:s});(t.length!==e.planeEndpointSegments.length||t.some((t,n)=\u003e{const o=e.planeEndpointSegments?.[n];return!o||t.layer!==o.layer||Math.abs(t.width-o.width)\u003eXtt||!Vtt(t.start,o.start)||!Vtt(t.end,o.end)})||M8(e.planeEndpointVia.center,e.targetPoint)\u003c=Xtt)\u0026\u0026Jtt(s,\"trace-plan-mismatch\",`Trace ${e.planeEndpointTrace.pcb_trace_id} does not encode a valid offset plane-to-endpoint dogbone`,e)}else Jtt(s,\"trace-plan-mismatch\",`Plane endpoint geometry for ${e.connectionName} is incomplete`,e);const d=e.trace.route.find(t=\u003e\"x\"in t\u0026\u0026\"y\"in t),h=[...e.trace.route].reverse().find(t=\u003e\"x\"in t\u0026\u0026\"y\"in t);d\u0026\u0026h\u0026\u0026Vtt(d,e.sourcePoint)\u0026\u0026Vtt(h,e.exitPoint)||Jtt(s,\"disconnected-trace\",`Trace ${e.trace.pcb_trace_id} does not span its source and exit`,e);const u=i.connections.find(t=\u003et.name===e.connectionName);if(\"boundary\"===e.termination.type)if(u){const t=u.pointsToConnect[e.sourcePointIndex];t\u0026\u0026Vtt(t,e.exitPoint)\u0026\u0026\"layer\"in t\u0026\u0026t.layer===e.targetLayer||Jtt(s,\"output-exit-mismatch\",`Output connection ${e.connectionName} is not attached to its fanout exit`,e);for(let t=0;t\u003ca.pointsToConnect.length;t++){if(t===e.sourcePointIndex)continue;const n=a.pointsToConnect[t],o=u.pointsToConnect[t];n\u0026\u0026o\u0026\u0026Utt(n,o)||Jtt(s,\"downstream-endpoint-lost\",`Output connection ${e.connectionName} did not retain downstream endpoint ${t}`,e)}}else Jtt(s,\"output-connection-missing\",`Boundary connection ${e.connectionName} was removed from the output`,e);else u\u0026\u0026Jtt(s,\"plane-connection-retained\",`Plane-terminated connection ${e.connectionName} remains in the output`,e)}function tet(t,e){const n=Htt(t),o=Htt(e),i=Gtt(t),r=Gtt(e);for(const t of n){for(const e of o)if(t.layer===e.layer\u0026\u0026T8(t.start,t.end,e.start,e.end)\u003c=(t.width+e.width)/2+Xtt)return!0;for(const e of r)if(e.spanLayers.includes(t.layer)\u0026\u0026N8(e.center,t.start,t.end)\u003c=e.diameter/2+t.width/2+Xtt)return!0}for(const t of i){for(const e of o)if(t.spanLayers.includes(e.layer)\u0026\u0026N8(t.center,e.start,e.end)\u003c=t.diameter/2+e.width/2+Xtt)return!0;for(const e of r)if(t.spanLayers.some(t=\u003ee.spanLayers.includes(t))\u0026\u0026M8(t.center,e.center)\u003c=(t.diameter+e.diameter)/2+Xtt)return!0}return!1}function eet(t){const{inputSrj:e,outputSrj:n,plans:o,preparedBuses:i,sharedBoundary:r,clearance:s}=t,a=[],c=new Map,l=new Map(i.map(t=\u003e[t.busId,t]));for(const t of o){const e=c.get(t.connectionName)??[];e.push(t),c.set(t.connectionName,e)}for(const t of e.connections){const e=c.get(t.name)??[];0===e.length?Jtt(a,\"missing-plan\",`Connection ${t.name} has no fanout plan`):e.length\u003e1\u0026\u0026Jtt(a,\"duplicate-plan\",`Connection ${t.name} has ${e.length} fanout plans`,e[0])}for(const t of o)e.connections.some(e=\u003ee.name===t.connectionName)?Qtt({plan:t,preparedBus:l.get(t.busId),inputSrj:e,outputSrj:n,sharedBoundary:r,issues:a}):Jtt(a,\"unknown-plan\",`Plan ${t.connectionName} is not an input connection`,t);const d=function(t){const{plans:e,inputSrj:n,sharedBoundary:o,issues:i}=t,r=new Set,s=new Map;for(const t of e)s.set(t,[]);for(let t=0;t\u003ce.length;t++){const i=e[t];(\"plane\"===i.termination.type?Boolean(i.via):i.segments.some(t=\u003eZtt(t.start,o)||Ztt(t.end,o)))\u0026\u0026r.add(i);for(let o=t+1;o\u003ce.length;o++){const t=e[o];$8(n,i.connectionName,t.connectionName)\u0026\u0026tet(i,t)\u0026\u0026(s.get(i).push(t),s.get(t).push(i))}}const a=[...r];for(;a.length\u003e0;){const t=a.shift();for(const e of s.get(t)??[])r.has(e)||(r.add(e),a.push(e))}for(const t of e)r.has(t)||Jtt(i,\"not-broken-out\",\"boundary\"===t.termination.type?`Connection ${t.connectionName} has no continuous same-net copper path to the shared boundary`:`Plane connection ${t.connectionName} has no terminating via`,t);return r}({plans:o,inputSrj:e,sharedBoundary:r,issues:a});return function(t){const{plans:e,inputSrj:n,clearance:o,issues:i}=t;for(const t of e){const e=Htt(t);for(let r=0;r\u003ce.length;r++){const s=e[r];for(const e of n.obstacles){if(!e.layers.includes(s.layer))continue;if(Y8(n,e,t.connectionName))continue;if(0===r\u0026\u0026e.obstacleId===t.sourceObstacle.obstacleId\u0026\u0026s.layer===t.sourceLayer)continue;if(K8({inputSrj:n,segment:s,bodyObstacle:e,connectionName:t.connectionName}))continue;const a=A8(s,e),c=s.width/2+o;a\u003cc-1e-9\u0026\u0026Jtt(i,\"obstacle-clearance\",`Trace ${t.connectionName} on ${s.layer} is ${a.toFixed(4)}mm from different-net obstacle ${e.obstacleId}; ${c.toFixed(4)}mm is required`,t)}}for(const e of Gtt(t))for(const r of n.obstacles){if(!r.layers.some(t=\u003ee.spanLayers.includes(t))||Y8(n,r,t.connectionName))continue;const s=E8(e.center,r),a=e.diameter/2+o;s\u003ca-1e-9\u0026\u0026Jtt(i,\"via-obstacle-clearance\",`Via ${t.connectionName} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId} on its layer span; ${a.toFixed(4)}mm is required`,t)}}for(let t=0;t\u003ce.length;t++){const r=e[t];for(let s=t+1;s\u003ce.length;s++){const t=e[s];if($8(n,r.connectionName,t.connectionName))continue;const a=Htt(r),c=Htt(t),l=Gtt(r),d=Gtt(t);for(const e of a){for(const n of c)O8(e,n,o)||Jtt(i,\"different-net-trace-clearance\",`Different-net traces ${r.connectionName} and ${t.connectionName} intersect or violate clearance on ${e.layer}`,r,t.connectionName);for(const n of d)n.spanLayers.includes(e.layer)\u0026\u0026N8(n.center,e.start,e.end)\u003cn.diameter/2+e.width/2+o-1e-9\u0026\u0026Jtt(i,\"different-net-trace-via-clearance\",`Trace ${r.connectionName} violates via clearance to ${t.connectionName} on ${e.layer}`,r,t.connectionName)}for(const e of l){for(const n of c)e.spanLayers.includes(n.layer)\u0026\u0026N8(e.center,n.start,n.end)\u003ce.diameter/2+n.width/2+o-1e-9\u0026\u0026Jtt(i,\"different-net-trace-via-clearance\",`Via ${r.connectionName} violates trace clearance to ${t.connectionName} on ${n.layer}`,r,t.connectionName);for(const n of d)e.spanLayers.some(t=\u003en.spanLayers.includes(t))\u0026\u0026M8(e.center,n.center)\u003c(e.diameter+n.diameter)/2+o-1e-9\u0026\u0026Jtt(i,\"different-net-via-clearance\",`Vias ${r.connectionName} and ${t.connectionName} violate clearance on an overlapping layer span`,r,t.connectionName)}}}}({plans:o,inputSrj:e,clearance:s,issues:a}),{valid:0===a.length,checkedConnectionCount:e.connections.length,brokenOutConnectionCount:new Set([...d].map(t=\u003et.connectionName)).size,issues:a}}var net=[\"#ef4444\",\"#2563eb\",\"#16a34a\",\"#9333ea\",\"#f59e0b\",\"#0891b2\",\"#db2777\",\"#65a30d\",\"#4f46e5\",\"#ea580c\"];function oet(t){if(!Number.isInteger(t)||t\u003c0)throw new Error(`FanoutSolver: copper layer index must be a non-negative integer, received ${t}`);return net[t%net.length]}var iet=new Set([\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\",\"inner7\",\"inner8\"]),ret={\"0603\":{padLength:.8,padWidth:.95},1206:{padLength:.6,padWidth:1.6},\"1206x4_pair\":{padLength:.8,padWidth:.5}},set=(t,e)=\u003e{const n=t.indexOf(e);if(n\u003c0)throw new Error(`FanoutSolver: cannot visualize unknown copper layer \"${e}\"`);return n},aet=(t,e)=\u003e`z${[...new Set(e.map(e=\u003eset(t,e)))].sort((t,e)=\u003et-e).join(\",\")}`,cet=t=\u003e{const e=\"layers\"in t?t.layers:void 0;return e\u0026\u0026e.length\u003e0?e:[t.layer]},det=(t,e)=\u003et.__zLayers\u0026\u0026t.__zLayers.length\u003e0?[...new Set(t.__zLayers)].filter(t=\u003eNumber.isInteger(t)\u0026\u0026t\u003e=0\u0026\u0026t\u003ce.length).sort((t,e)=\u003et-e):[...new Set(t.layers.map(t=\u003eset(e,t)))].sort((t,e)=\u003et-e),het=(t,e,n)=\u003e{const o=set(t,e),i=set(t,n);return t.slice(Math.min(o,i),Math.max(o,i)+1)},uet=(...t)=\u003et.find(t=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)),pet=t=\u003e{const e=uet(t.min_via_hole_diameter,t.minViaHoleDiameter),n=uet(t.min_via_pad_diameter,t.minViaPadDiameter,t.minViaDiameter);return Math.max(n??t.minViaDiameter??.3,e??0)},met=(t,e)=\u003e{let n={blue:[0,0,255],orange:[255,165,0],purple:[128,0,128],red:[255,0,0]}[t],o=1;const i=/^rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)$/.exec(t);i\u0026\u0026(n=[Number(i[1]),Number(i[2]),Number(i[3])],o=void 0===i[4]?1:Number(i[4]));const r=/^hsl\\(\\s*([\\d.-]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%\\s*\\)$/.exec(t);if(r\u0026\u0026(n=((t,e,n)=\u003e{const o=(1-Math.abs(2*n-1))*e,i=(t%360+360)%360/60,r=o*(1-Math.abs(i%2-1)),[s,a,c]=i\u003c1?[o,r,0]:i\u003c2?[r,o,0]:i\u003c3?[0,o,r]:i\u003c4?[0,r,o]:i\u003c5?[r,0,o]:[o,0,r],l=n-o/2;return[s,a,c].map(t=\u003eMath.round(255*(t+l)))})(Number(r[1]),Number(r[2])/100,Number(r[3])/100)),!n)return t;const s=+Math.max(0,100*o-100*e).toFixed(2)/100;if(s\u003e=1){const t=n.map(t=\u003eMath.round(t).toString(16).padStart(2,\"0\")).join(\"\");return t[0]===t[1]\u0026\u0026t[2]===t[3]\u0026\u0026t[4]===t[5]?`#${t[0]}${t[2]}${t[4]}`:`#${t}`}return`rgba(${n.join(\",\")},${s})`},get=t=\u003e{const e=new Map,n=(t,n)=\u003e{if(!t)return;const o=e.get(t)??[];o.includes(n)||o.push(n),e.set(t,o)};for(const e of t.connections){const t=e.__rootConnectionNames??[e.name];for(const o of t){n(e.name,o),n(o,o),n(e.__netConnectionName,o);for(const t of e.pointsToConnect)n(t.pointId,o),n(t.pcb_port_id,o)}}return t=\u003e{const n=(t=\u003e{const e=new Set;return t.filter(t=\u003e!e.has(t)\u0026\u0026(e.add(t),!0))})([...t.connectedTo.flatMap(t=\u003ee.get(t)??[]),...(t.offBoardConnectsTo??[]).flatMap(t=\u003ee.get(t)??[])]).join(\", \");return t.layers.map(t=\u003en?`${t}\\n${n}`:t).join(\"\\n\")}};function fet(t){const e=k8(t.layerCount),n=(t.traces??[]).some(t=\u003et.route.some((e,n)=\u003e{const o=t.route[n+1];return\"wire\"===e.route_type\u0026\u0026\"wire\"===o?.route_type\u0026\u0026o.layer===e.layer\u0026\u0026!iet.has(e.layer)})),o=new Set(t.connections.map(({name:t})=\u003et)),i=n?[...new Set((t.traces??[]).map(({connection_name:t})=\u003et).filter(t=\u003et\u0026\u0026!o.has(t)))].map(t=\u003e({name:t,pointsToConnect:[]})):[],r=[...t.connections,...i],s=(a=r,Object.fromEntries(a.map((t,e)=\u003e[t.name,`hsl(${340*e/a.length}, 100%, 50%)`])));var a;const c=get({...t,connections:r}),l=[],d=[],h=[],u=[];for(const t of r)for(const n of t.pointsToConnect){const o=cet(n),i=t.__rootConnectionNames??[t.name];u.push({x:n.x,y:n.y,color:s[t.name],layer:aet(e,o),label:[t.name,i.join(\", \"),o.join(\",\")].join(\"\\n\")})}for(const o of t.traces??[]){const i=o.route.filter(t=\u003e\"jumper\"===t.route_type),r=(t,e)=\u003ei.some(n=\u003e{const o=.01;return Math.abs(t.x-n.start.x)\u003co\u0026\u0026Math.abs(t.y-n.start.y)\u003co\u0026\u0026Math.abs(e.x-n.end.x)\u003co\u0026\u0026Math.abs(e.y-n.end.y)\u003co||Math.abs(t.x-n.end.x)\u003co\u0026\u0026Math.abs(t.y-n.end.y)\u003co\u0026\u0026Math.abs(e.x-n.start.x)\u003co\u0026\u0026Math.abs(e.y-n.start.y)\u003co});for(const i of o.route)if(\"via\"===i.route_type){const r=het(e,i.from_layer,i.to_layer);d.push({center:{x:i.x,y:i.y},radius:(i.via_diameter??pet(t))/2,fill:n?s[o.connection_name]:\"blue\",stroke:\"none\",layer:aet(e,r)})}else\"through_obstacle\"===i.route_type\u0026\u0026l.push({points:[i.start,i.end],strokeColor:met(s[o.connection_name]??\"purple\",.35),strokeWidth:i.width,strokeDash:[.1,.1],layer:aet(e,[i.from_layer,i.to_layer]),label:`${o.connection_name} through_obstacle`});for(let t=0;t\u003co.route.length-1;t++){const i=o.route[t],a=o.route[t+1];if(\"jumper\"===i.route_type){const t=s[o.connection_name]??\"rgba(255, 165, 0, 0.8)\",n=ret[\"1206x4_pair\"===i.footprint?\"1206x4_pair\":\"0603\"],r=Math.abs(i.end.x-i.start.x)\u003eMath.abs(i.end.y-i.start.y),a=r?n.padLength:n.padWidth,c=r?n.padWidth:n.padLength,d=aet(e,[i.layer]);for(const e of[i.start,i.end])h.push({center:e,width:a,height:c,fill:met(t,.5),stroke:\"rgba(0, 0, 0, 0.5)\",layer:d});l.push({points:[i.start,i.end],strokeColor:\"rgba(100, 100, 100, 0.8)\",strokeWidth:.3*n.padWidth,layer:d})}else if(\"wire\"===i.route_type\u0026\u0026\"wire\"===a.route_type\u0026\u0026a.layer===i.layer\u0026\u0026!r(i,a)){const t=set(e,i.layer);l.push({points:[{x:i.x,y:i.y},{x:a.x,y:a.y}],layer:`z${t}`,strokeWidth:i.width,strokeColor:oet(t),...n?{label:o.connection_name}:{}})}}}for(const n of t.obstacles){if(n.isCopperPour)continue;const t=det(n,e);if(0===t.length)throw new Error(`FanoutSolver: cannot visualize obstacle \"${n.obstacleId??\"unknown\"}\" without a valid layer`);const o=1===t.length?e[t[0]]:void 0,i=met(\"bottom\"===o?\"blue\":\"red\",.5**t.length),r=n.shape,s={center:n.center,fill:i,layer:`z${t.join(\",\")}`,label:c(n)};\"circle\"===r?d.push({...s,radius:Math.min(n.width,n.height)/2}):h.push({...s,width:n.width,height:n.height,ccwRotationDegrees:n.ccwRotationDegrees})}for(const n of t.jumpers??[])for(const t of n.pads)h.push({center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.3)\",stroke:\"rgba(255, 165, 0, 0.8)\",layer:aet(e,t.layers)});return{rects:h,circles:d,lines:l,points:u}}function yet(t,e){if(!Number.isFinite(e)||e\u003c=0)throw new Error(`FanoutSolver: ${t} must be a positive number, received ${e}`);return e}function _et(t,e,n){const o=new Map(e.map(t=\u003e[t.busId,t.connections.length])),i=new Map;for(const[e,r]of Object.entries(t))i.set(r,(i.get(r)??0)+(n?o.get(e)??1:1));return[...i.values()].reduce((t,e)=\u003et+e*e,0)}function bet(t){return t.balanceLayerLoadByConnectionCount?.25:.01}function xet(t){return t.reduce((t,e)=\u003et+Number(Boolean(e.via))+Number(Boolean(e.planeEndpointVia)),0)}function vet(t){const e=t.connections.reduce((e,n)=\u003ee+(\"left\"===t.direction||\"right\"===t.direction?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length;switch(t.direction){case\"right\":return t.sharedBoundary.maxX-e;case\"left\":return e-t.sharedBoundary.minX;case\"up\":return t.sharedBoundary.maxY-e;case\"down\":return e-t.sharedBoundary.minY}}function Iet(t){const e=\"left\"===t.direction||\"right\"===t.direction;return t.connections.some(t=\u003e{const n=t.exitTargetPoint??t.targetPoint,o=e?t.sourcePoint.y:t.sourcePoint.x,i=e?n.y:n.x;return Math.abs(o-i)\u003e1e-6})}function Cet(t){const e=\"left\"===t.direction||\"right\"===t.direction,n=e?t.xCoordinates:t.yCoordinates,o=t.connections.reduce((t,n)=\u003et+(e?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length,i=\"right\"===t.direction||\"up\"===t.direction?Math.max(...n):Math.min(...n);return Math.abs(o-i)\u003c1e-6}function Pet(t){const e=\"left\"===t.direction||\"right\"===t.direction,n=e?t.xCoordinates:t.yCoordinates,o=t.connections.reduce((t,n)=\u003et+(e?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length,i=\"right\"===t.direction||\"up\"===t.direction?Math.max(...n):Math.min(...n),r=e?t.pitchX:t.pitchY;return Math.round(Math.abs(o-i)/r)}function Met(t){const{buses:e,escapeLayers:n,escapeLayersByBusId:o}=t,i={},r=new Map;let s=0;for(const t of e){const e=r.get(t.componentId)??new Set;e.add(t.direction),r.set(t.componentId,e)}for(const t of e){const e=t.connections[0]?.sourceLayer;if(!e)throw new Error(`FanoutSolver: bus \"${t.busId}\" has no connections`);if(\"plane\"===t.termination.type){i[t.busId]=t.termination.layer;continue}const a=o[t.busId]??n,c=a.filter(t=\u003et!==e);if(a.includes(e)\u0026\u0026(Iet(t)||Cet(t)))i[t.busId]=e;else if(c.length\u003e0){const e=r.get(t.componentId);if(e.has(\"left\")\u0026\u0026e.has(\"right\")||e.has(\"up\")\u0026\u0026e.has(\"down\")){const e=Pet(t);i[t.busId]=c[Math.max(e-1,0)%c.length]}else i[t.busId]=c[s%c.length],s++}else i[t.busId]=e}return i}function Net(t){const{bus:e,srj:n,config:o,staticClearanceCache:i}=t,r=o.escapeLayers.filter(t=\u003enull!==htt({srj:n,bus:e,targetLayer:t,acceptedPlans:[],layerNames:o.layerNames,traceWidth:o.traceWidth,viaDiameter:o.viaDiameter,viaHoleDiameter:o.viaHoleDiameter,clearance:o.clearance,compactBusTracks:o.compactBusTracks,allowSameNetMerges:o.allowSameNetMerges,staticClearanceCache:i}));return r.length\u003e0?r:o.escapeLayers}var wet=class extends b8{constructor(t,e={}){super(),this.inputSrj=t,this.options=e,this.config=function(t,e){const n=yet(\"traceWidth\",e.traceWidth??t.nominalTraceWidth??t.minTraceWidth),o=yet(\"viaDiameter\",e.viaDiameter??t.minViaPadDiameter??t.min_via_pad_diameter??t.minViaDiameter??Math.max(2*n,.3)),i=yet(\"viaHoleDiameter\",e.viaHoleDiameter??t.minViaHoleDiameter??t.min_via_hole_diameter??.5*o);if(i\u003e=o)throw new Error(`FanoutSolver: viaHoleDiameter ${i} must be smaller than viaDiameter ${o}`);const r=yet(\"clearance\",e.clearance??t.minViaEdgeToPadEdgeClearance??t.minTraceToPadEdgeClearance??t.defaultObstacleMargin??t.minTraceWidth),s=k8(t.layerCount),a=e.escapeLayers??s;for(const e of a)if(!s.includes(e))throw new Error(`FanoutSolver: escape layer \"${e}\" is not available in a ${t.layerCount}-layer SimpleRouteJson`);if(new Set(a).size!==a.length)throw new Error(\"FanoutSolver: escapeLayers contains duplicates\");const c=e.borderDistribution??\"preserve\";if(\"preserve\"!==c\u0026\u0026\"even\"!==c)throw new Error(`FanoutSolver: borderDistribution must be \"preserve\" or \"even\", received \"${c}\"`);return{traceWidth:n,viaDiameter:o,viaHoleDiameter:i,clearance:r,compactBusTracks:e.compactBusTracks??!1,allowSameNetMerges:e.allowSameNetMerges??!1,singleLayerPushAndShove:e.singleLayerPushAndShove??!1,singleLayerAdaptiveExits:e.singleLayerAdaptiveExits??!1,borderDistribution:c,layerNames:s,escapeLayers:a,maxLayerCombinations:void 0===e.maxLayerCombinations?256:yet(\"maxLayerCombinations\",e.maxLayerCombinations),balanceLayerLoadByConnectionCount:e.balanceLayerLoadByConnectionCount??!1}}(t,e),this.preparedBuses=j7(t,e);for(const t of this.preparedBuses){if(\"plane\"!==t.termination.type)continue;const e=t.termination.layer;if(!this.config.layerNames.includes(e))throw new Error(`FanoutSolver: plane-terminated bus \"${t.busId}\" targets unavailable layer \"${e}\"`);if(t.connections.some(t=\u003et.sourceLayer===e))throw new Error(`FanoutSolver: plane-terminated bus \"${t.busId}\" must target a layer below its source pad`)}const n=this.preparedBuses.filter(t=\u003e\"boundary\"===t.termination.type).map(t=\u003et.busId),o=Object.fromEntries(this.preparedBuses.flatMap(t=\u003e\"plane\"===t.termination.type?[[t.busId,t.termination.layer]]:[])),i=Object.fromEntries(this.preparedBuses.flatMap(e=\u003e\"plane\"===e.termination.type?[]:[[e.busId,Net({bus:e,srj:t,config:this.config,staticClearanceCache:this.routeStaticClearanceCache})]]));this.escapeLayersByBusId=i;const r=function(t){const{busIds:e,layers:n,layersByBusId:o,maxAssignments:i}=t;if(0===n.length)throw new Error(\"FanoutSolver: no escape layers are available\");if(!Number.isInteger(i)||i\u003c1)throw new Error(`FanoutSolver: maxLayerCombinations must be positive, received ${i}`);const r=e.map(t=\u003eo?.[t]??n),s=r.findIndex(t=\u003e0===t.length);if(s\u003e=0)throw new Error(`FanoutSolver: no escape layers are available for bus \"${e[s]}\"`);const a=r.reduce((t,e)=\u003et*e.length,1),c=Math.min(i,Number.isFinite(a)?a:i),l=[],d=new Set;function h(t){const n={};for(let o=0;o\u003ce.length;o++)n[e[o]]=r[o][t[o]];const o=JSON.stringify(n);d.has(o)||(d.add(o),l.push(n))}if(a\u003c=i){for(let t=0;t\u003cc;t++){const n=[];let o=t;for(let t=0;t\u003ce.length;t++){const e=r[t].length,i=o%e;o=Math.floor(o/e),n.push((i+t)%e)}h(n)}return l}function u(t){let e=0|t;return e=Math.imul(e^e\u003e\u003e\u003e16,569420461),e=Math.imul(e^e\u003e\u003e\u003e15,1935289751),(e^e\u003e\u003e\u003e15)\u003e\u003e\u003e0}const p=e.map((t,e)=\u003ee%r[e].length);h(p);const m=Math.max(...r.map(t=\u003et.length));for(let t=1;t\u003cm\u0026\u0026l.length\u003cc;t++)h(p.map((e,n)=\u003e(e+t)%r[n].length));for(let t=0;t\u003ce.length\u0026\u0026l.length\u003cc;t++)for(let e=1;e\u003cr[t].length\u0026\u0026l.length\u003cc;e++){const n=[...p];n[t]=(p[t]+e)%r[t].length,h(n)}for(let t=1;l.length\u003cc\u0026\u0026t\u003c20*c;t++)h(e.map((e,n)=\u003eu(2654435761*t+2246822507*n)%r[n].length));return l}({busIds:n,layers:this.config.escapeLayers,layersByBusId:i,maxAssignments:this.config.maxLayerCombinations}).map(t=\u003e({...t,...o}));this.layerAssignments=function(t){const{preferredAssignment:e,generatedAssignments:n,maxAssignments:o}=t,i=JSON.stringify(e);return[e,...n.filter(t=\u003eJSON.stringify(t)!==i)].slice(0,o)}({preferredAssignment:Met({buses:this.preparedBuses,escapeLayers:this.config.escapeLayers,escapeLayersByBusId:i}),generatedAssignments:r,maxAssignments:this.config.maxLayerCombinations}),this.MAX_ITERATIONS=this.config.maxLayerCombinations+2}inputSrj;options;preparedBuses;attempts=[];layerAssignments;config;escapeLayersByBusId;evaluatedAssignmentKeys=new Set;queuedAssignmentKeys=new Set;assignmentRepairDepthByKey=new Map;pendingRepairAssignments=[];routeStaticClearanceCache=new Map;routingPrefixCache=new Map;groupedBeamEvaluated=!1;nextAssignmentIndex=0;nextGeneratedAssignmentIndex=0;bestAttempt=null;endpointCompletion=null;getSolverName(){return\"FanoutSolver\"}completeBestAttemptEndpoints(){this.options.completeOriginalEndpoints\u0026\u0026!this.endpointCompletion\u0026\u0026this.bestAttempt\u0026\u0026(this.endpointCompletion=y7({inputSrj:this.inputSrj,fanoutSrj:this.bestAttempt.outputSrj,plans:this.bestAttempt.plans,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,effort:this.options.endpointCompletionEffort,routeDownstreamConnections:this.options.routeDownstreamConnections}))}getValidationBoundary(){if(this.options.sharedBoundary)return this.options.sharedBoundary;const t=this.preparedBuses[0]?.sharedBoundary;return t?this.preparedBuses.slice(1).reduce((t,e)=\u003e({minX:Math.min(t.minX,e.sharedBoundary.minX),maxX:Math.max(t.maxX,e.sharedBoundary.maxX),minY:Math.min(t.minY,e.sharedBoundary.minY),maxY:Math.max(t.maxY,e.sharedBoundary.maxY)}),{...t}):this.inputSrj.bounds}validateCompletePlans(t,e){return eet({inputSrj:this.inputSrj,outputSrj:e,plans:t,preparedBuses:this.preparedBuses,sharedBoundary:this.getValidationBoundary(),clearance:this.config.clearance})}evaluateAssignmentWithStrategy(t,e,n){let o=[],i=[],r=new Map;const s=1===this.config.escapeLayers.length;if(s\u0026\u0026this.config.singleLayerPushAndShove){const t={srj:this.inputSrj,buses:this.preparedBuses,traceWidth:this.config.traceWidth,clearance:this.config.clearance,borderDistribution:this.config.borderDistribution},e=Ytt(t)??(this.config.singleLayerAdaptiveExits?Mtt({...t,availableBoundaryRegions:R7(this.options.availableCornersAndSides)}):null);e?o.push(...e):i.push(...this.preparedBuses.map(t=\u003et.busId))}const a=[...this.preparedBuses].sort((t,o)=\u003eNumber(\"plane\"===o.termination.type)-Number(\"plane\"===t.termination.type)||(\"group-by-layer\"===n?(e[t.busId]??\"\").localeCompare(e[o.busId]??\"\"):0)||o.componentObstacles.length-t.componentObstacles.length||(s?vet(o)-vet(t):o.connections.length-t.connections.length||(\"deep-first\"===n?vet(o)-vet(t):vet(t)-vet(o))));let c,l=`${n}|`;for(const n of s\u0026\u0026this.config.singleLayerPushAndShove?[]:a){const s=e[n.busId];if(!s)throw new Error(`FanoutSolver: assignment ${t} has no layer for bus \"${n.busId}\"`);l+=`${n.busId.length}:${n.busId};${s.length}:${s};`;const a=this.routingPrefixCache.get(l);if(a){o=[...a.plans],i=[...a.failedBusIds],r=new Map(a.blockingBusCounts);continue}const c=new Map,d=htt({srj:this.inputSrj,bus:n,targetLayer:s,acceptedPlans:o,layerNames:this.config.layerNames,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,compactBusTracks:this.config.compactBusTracks,allowSameNetMerges:this.config.allowSameNetMerges,staticClearanceCache:this.routeStaticClearanceCache,blockingBusCounts:c});if(d)o.push(...d);else{i.push(n.busId);for(const[t,e]of c)r.set(t,(r.get(t)??0)+e)}this.routingPrefixCache.set(l,{plans:[...o],failedBusIds:[...i],blockingBusCounts:new Map(r)})}let d=S8({inputSrj:this.inputSrj,plans:o,layerNames:this.config.layerNames});const h=o.length===this.inputSrj.connections.length?this.validateCompletePlans(o,d):null;h\u0026\u0026!h.valid\u0026\u0026(c=h.issues,o=[],i=this.preparedBuses.map(t=\u003et.busId),r.clear(),d=S8({inputSrj:this.inputSrj,plans:o,layerNames:this.config.layerNames}));const u=this.preparedBuses.length-i.length,p=o.reduce((t,e)=\u003et+e.length,0),m=1e6*(this.inputSrj.connections.length-o.length)+1e5*i.length+p+.1*xet(o)+_et(e,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config);return{summary:{assignmentIndex:t,busLayerAssignments:e,routedBusCount:u,routedConnectionCount:o.length,failedBusIds:i,score:m,...c?{validationIssues:c}:{}},plans:o,blockingBusIds:[...r.entries()].toSorted(([,t],[,e])=\u003ee-t).map(([t])=\u003et),outputSrj:d}}evaluateAssignment(t,e){let n=this.evaluateAssignmentWithStrategy(t,e,\"default\");if(n.summary.routedConnectionCount===this.inputSrj.connections.length)return n;for(const o of[\"group-by-layer\",\"deep-first\"]){const i=this.evaluateAssignmentWithStrategy(t,e,o);if(i.summary.score\u003cn.summary.score\u0026\u0026(n=i),n.summary.routedConnectionCount===this.inputSrj.connections.length)return n}return n}evaluateGroupedBeam(t,e=!1){if(this.config.escapeLayers.length\u003c2)return null;if(this.preparedBuses.length\u003e56)return null;const n=this.inputSrj.connections.length;if(n\u003e64)return null;if(1!==new Set(this.preparedBuses.map(t=\u003et.componentId)).size)return null;const o=[...this.preparedBuses].sort((t,n)=\u003e{const o=\"plane\"===t.termination.type?1:this.escapeLayersByBusId[t.busId]?.length??this.config.escapeLayers.length,i=\"plane\"===n.termination.type?1:this.escapeLayersByBusId[n.busId]?.length??this.config.escapeLayers.length;return Number(\"plane\"===n.termination.type)-Number(\"plane\"===t.termination.type)||(e?t.direction.localeCompare(n.direction):0)||o-i||n.componentObstacles.length-t.componentObstacles.length||n.connections.length-t.connections.length||Pet(n)-Pet(t)||t.busId.localeCompare(n.busId)}),i=n\u003c=24,r=this.preparedBuses.some(t=\u003et.connections.length\u003e1),s=i?48:n\u003c=32?24:12,a=i\u0026\u0026!r?4:1;let c=[{assignment:{},plans:[]}];const l=t=\u003et.plans.reduce((t,e)=\u003et+e.length,0)+.1*xet(t.plans)+1e4*this.preparedBuses.reduce((e,n)=\u003e{if(\"boundary\"!==n.termination.type||!Iet(n))return e;const o=n.connections[0]?.sourceLayer;return t.assignment[n.busId]===o?e:e+n.connections.length},0)+_et(t.assignment,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config);for(const t of o){const e=[];for(const n of c){const o=\"plane\"===t.termination.type?[t.termination.layer]:this.escapeLayersByBusId[t.busId]??this.config.escapeLayers,i=new Map;for(const[t,e]of Object.entries(n.assignment)){const n=this.preparedBuses.find(e=\u003ee.busId===t);i.set(e,(i.get(e)??0)+(this.config.balanceLayerLoadByConnectionCount?n?.connections.length??1:1))}const r=t.connections[0]?.sourceLayer,s=Iet(t),c=o.toSorted((t,e)=\u003e(i.get(t)??0)-(i.get(e)??0)||(s?Number(e===r)-Number(t===r):Number(t===r)-Number(e===r))||t.localeCompare(e));for(const o of c){const i=dtt({srj:this.inputSrj,bus:t,targetLayer:o,acceptedPlans:n.plans,layerNames:this.config.layerNames,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,compactBusTracks:this.config.compactBusTracks,allowSameNetMerges:this.config.allowSameNetMerges,staticClearanceCache:this.routeStaticClearanceCache},a);for(const r of i)e.push({assignment:{...n.assignment,[t.busId]:o},plans:[...n.plans,...r]})}}if(0===e.length)return null;e.sort((t,e)=\u003e{const n=l(t)-l(e);return Math.abs(n)\u003e1e-9?n:JSON.stringify(t.assignment).localeCompare(JSON.stringify(e.assignment))});const n=new Map;c=[];for(const t of e){const e=JSON.stringify(t.assignment),o=n.get(e)??0;if(!(o\u003e=2)\u0026\u0026(n.set(e,o+1),c.push(t),c.length\u003e=s))break}}const d=c[0];if(!d)return null;const h=S8({inputSrj:this.inputSrj,plans:d.plans,layerNames:this.config.layerNames});if(d.plans.length===this.inputSrj.connections.length\u0026\u0026!this.validateCompletePlans(d.plans,h).valid)return null;const u=d.plans.length===this.inputSrj.connections.length?d.plans.reduce((t,e)=\u003et+e.length,0)+.1*xet(d.plans)+_et(d.assignment,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config):Number.POSITIVE_INFINITY;if(!Number.isFinite(u))return null;return{summary:{assignmentIndex:t,busLayerAssignments:d.assignment,routedBusCount:this.preparedBuses.length,routedConnectionCount:d.plans.length,failedBusIds:[],score:u},plans:d.plans,blockingBusIds:[],outputSrj:h}}prioritizeFailedBusRepairs(t,e,n){const o=JSON.stringify(t),i=this.assignmentRepairDepthByKey.get(o)??0;if(i\u003e=2)return;const r=[],s=new Set,a=t=\u003e{const e=JSON.stringify(t);s.has(e)||this.evaluatedAssignmentKeys.has(e)||this.queuedAssignmentKeys.has(e)||(s.add(e),this.queuedAssignmentKeys.add(e),this.assignmentRepairDepthByKey.set(e,i+1),r.push(t))},c=[];for(let t=0;t\u003cMath.max(e.length,n.length);t++){const o=e[t],i=n[t];o\u0026\u0026!c.includes(o)\u0026\u0026c.push(o),i\u0026\u0026!c.includes(i)\u0026\u0026c.push(i)}for(const o of e){const e=t[o],i=this.escapeLayersByBusId[o];if(e\u0026\u0026i){for(const s of n.slice(0,4)){const n=t[s],c=this.escapeLayersByBusId[s];if(n\u0026\u0026c\u0026\u0026i.includes(n)\u0026\u0026c.includes(e)\u0026\u0026(a({...t,[o]:n,[s]:e}),r.length\u003e=8))break}if(r.length\u003e=8)break}}for(const e of c){const n=t[e],o=this.escapeLayersByBusId[e];if(!n||!o)continue;const i=o.indexOf(n);for(let s=1;s\u003co.length;s++){const c=o[(Math.max(i,0)+s)%o.length];if(c!==n\u0026\u0026(a({...t,[e]:c}),r.length\u003e=8))break}if(r.length\u003e=8)break}this.pendingRepairAssignments.push(...r)}hasCompleteBestAttempt(){return this.bestAttempt?.summary.routedConnectionCount===this.inputSrj.connections.length}shouldEvaluateGroupedBeam(){if(this.groupedBeamEvaluated||0===this.nextAssignmentIndex)return!1;return this.hasCompleteBestAttempt()||0===this.pendingRepairAssignments.length||this.nextAssignmentIndex\u003e=this.config.maxLayerCombinations}_step(){if(this.shouldEvaluateGroupedBeam()){this.groupedBeamEvaluated=!0;let t=this.evaluateGroupedBeam(-1);if(t||(t=this.evaluateGroupedBeam(-1,!0)),t){this.attempts.push(t.summary),(!this.bestAttempt||t.summary.score\u003cthis.bestAttempt.summary.score)\u0026\u0026(this.bestAttempt=t);const e=this.bestAttempt.summary;return this.stats={assignment:e.assignmentIndex\u003c0?0:e.assignmentIndex+1,assignmentCount:this.config.maxLayerCombinations,routedBuses:`${e.routedBusCount}/${this.preparedBuses.length}`,routedConnections:`${e.routedConnectionCount}/${this.inputSrj.connections.length}`,failedBuses:\"none\",bestScore:e.score},this.completeBestAttemptEndpoints(),void(this.solved=!0)}if(this.hasCompleteBestAttempt())return this.completeBestAttemptEndpoints(),void(this.solved=!0)}let t;for(;!t\u0026\u0026this.nextAssignmentIndex\u003cthis.config.maxLayerCombinations;){const e=this.nextAssignmentIndex%3==0;let n,o=!1;if(!this.groupedBeamEvaluated\u0026\u0026this.nextAssignmentIndex\u003e0?(n=this.pendingRepairAssignments.pop(),o=void 0!==n):e?n=this.layerAssignments[this.nextGeneratedAssignmentIndex++]:(n=this.pendingRepairAssignments.pop(),o=void 0!==n),n||!this.groupedBeamEvaluated\u0026\u00260!==this.nextAssignmentIndex||(n=e?this.pendingRepairAssignments.pop():this.layerAssignments[this.nextGeneratedAssignmentIndex++],o=e\u0026\u0026void 0!==n),!n)break;const i=JSON.stringify(n);o\u0026\u0026this.queuedAssignmentKeys.delete(i),this.evaluatedAssignmentKeys.has(i)||(t=n)}if(!t\u0026\u0026!this.groupedBeamEvaluated)return;if(!t)return void(this.hasCompleteBestAttempt()?(this.completeBestAttemptEndpoints(),this.solved=!0):(this.failed=!0,this.error=this.bestAttempt?`FanoutSolver: best layer assignment routed ${this.bestAttempt.summary.routedConnectionCount}/${this.inputSrj.connections.length} connections`:\"FanoutSolver: no layer assignment could be evaluated\"));const e=this.evaluateAssignment(this.nextAssignmentIndex,t);this.nextAssignmentIndex++,this.evaluatedAssignmentKeys.add(JSON.stringify(t)),(!this.bestAttempt||e.summary.routedConnectionCount\u003e=this.bestAttempt.summary.routedConnectionCount)\u0026\u0026this.prioritizeFailedBusRepairs(t,e.summary.failedBusIds,e.blockingBusIds),this.attempts.push(e.summary),(!this.bestAttempt||e.summary.score\u003cthis.bestAttempt.summary.score)\u0026\u0026(this.bestAttempt=e),this.stats={assignment:e.summary.assignmentIndex+1,assignmentCount:this.config.maxLayerCombinations,routedBuses:`${e.summary.routedBusCount}/${this.preparedBuses.length}`,routedConnections:`${e.summary.routedConnectionCount}/${this.inputSrj.connections.length}`,failedBuses:e.summary.failedBusIds.join(\", \")||\"none\",bestScore:this.bestAttempt.summary.score},this.groupedBeamEvaluated\u0026\u0026e.summary.routedConnectionCount===this.inputSrj.connections.length\u0026\u0026(this.completeBestAttemptEndpoints(),this.solved=!0)}computeProgress(){return this.solved||this.failed?1:this.nextAssignmentIndex/this.config.maxLayerCombinations}getConstructorParams(){return[this.inputSrj,this.options]}getOutput(){if(!this.solved||!this.bestAttempt)throw new Error(\"FanoutSolver: getOutput() called before a complete fanout was solved\");const t=this.validateCompletePlans(this.bestAttempt.plans,this.bestAttempt.outputSrj);if(!t.valid)throw new Error(`FanoutSolver: completed output failed validation: ${t.issues[0]?.message??\"unknown validation error\"}`);const e=this.endpointCompletion?.simpleRouteJson??this.bestAttempt.outputSrj,n=new Map((e.traces??[]).map(t=\u003e[t.pcb_trace_id,t]));return{simpleRouteJson:this.endpointCompletion?.simpleRouteJson??this.bestAttempt.outputSrj,fanoutTraces:this.bestAttempt.plans.flatMap(t=\u003e[n.get(t.trace.pcb_trace_id)??t.trace,...t.planeEndpointTrace?[n.get(t.planeEndpointTrace.pcb_trace_id)??t.planeEndpointTrace]:[]]),completionTraces:this.endpointCompletion?.traces??[],...this.endpointCompletion?{endpointCompletion:this.endpointCompletion.report}:{},planeTerminations:this.bestAttempt.plans.flatMap(t=\u003e\"plane\"===t.termination.type\u0026\u0026t.via?[{busId:t.busId,connectionName:t.connectionName,layer:t.termination.layer,via:t.via}]:[]),busLayerAssignments:this.bestAttempt.summary.busLayerAssignments,busDirections:Object.fromEntries(this.preparedBuses.map(t=\u003e[t.busId,t.direction])),attempts:[...this.attempts],validation:t}}getOutputSimpleRouteJson(){return this.getOutput().simpleRouteJson}visualize(){return fet(this.endpointCompletion?.simpleRouteJson??this.bestAttempt?.outputSrj??this.inputSrj)}};function Tet(t){const{minX:e,maxX:n}=t.bounds,o=(e+n)/2;if(!Number.isFinite(o))throw new Error(`Detected component ${t.componentId} has bad bounds`);return o}function Ret(t){const{minY:e,maxY:n}=t.bounds,o=(e+n)/2;if(!Number.isFinite(o))throw new Error(`Detected component ${t.componentId} has bad bounds`);return o}function Eet(t,e){const n=(function(t,e){const[n,o]=Tet(t)\u003cTet(e)?[t,e]:[e,t];return o.bounds.minX-n.bounds.maxX}(t,e)-2)/2;return Math.min(4.5,n)}function Aet(t,e){const n=e.filter(t=\u003e\"bga\"===t.componentKind).map(e=\u003efunction(t,e){const n=t.obstacles.filter(t=\u003et.componentId===e.componentId);if(0===n.length)throw new Error(`Detected component ${e.componentId} has no physical obstacles`);return{...e,bounds:{__type:\"rect\",minX:Math.min(...n.map(t=\u003et.center.x-t.width/2)),maxX:Math.max(...n.map(t=\u003et.center.x+t.width/2)),minY:Math.min(...n.map(t=\u003et.center.y-t.height/2)),maxY:Math.max(...n.map(t=\u003et.center.y+t.height/2))}}}(t,e)).toSorted((t,e)=\u003eTet(t)-Tet(e));if(2!==n.length)throw new Error(`Pipeline 10 requires exactly two detected BGAs; found ${n.map(t=\u003et.componentId).join(\", \")||\"none\"}`);const[o,i]=n;if(o.componentId===i.componentId)throw new Error(\"Pipeline 10 requires two distinct BGA component IDs\");if(Eet(o,i)\u003c2)throw new Error(\"Pipeline 10 cannot provide 2mm fanout margins while retaining a 2mm routing corridor\");return{first:o,second:i}}function Oet(t,e){const{minX:n,maxX:o,minY:i,maxY:r}=t.bounds;return{minX:n-e,maxX:o+e,minY:i-e,maxY:r+e}}function ket(t){const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds;return{minX:e,maxX:n,minY:o,maxY:i}}function Let({inputSrj:t,source:e,target:n}){const o=Eet(e,n),i=Oet(e,o),r=Tet(n)\u003eTet(e)?\"right\":\"left\",s=\"right\"===r?\"left\":\"right\";return t.connections.map((t,n)=\u003e{const a=t.pointsToConnect.filter(t=\u003et.x\u003e=e.bounds.minX\u0026\u0026t.x\u003c=e.bounds.maxX\u0026\u0026t.y\u003e=e.bounds.minY\u0026\u0026t.y\u003c=e.bounds.maxY);if(1!==a.length)throw new Error(`Connection ${t.name} must touch ${e.componentId} exactly once before fanout`);const c=a[0],l=\"right\"===r?i.maxX-c.x:c.x-i.minX,d=[{direction:\"up\",distance:i.maxY-c.y},{direction:\"down\",distance:c.y-i.minY},{direction:s,distance:\"right\"===s?i.maxX-c.x:c.x-i.minX}].toSorted((t,e)=\u003et.distance-e.distance)[0].direction,h=l\u003c=o+1.2?r:d;let u=\"up\"===h?\"top\":\"down\"===h?\"bottom\":h;return\"up\"===h?u=c.x\u003cTet(e)?\"top-left\":\"top-right\":\"down\"===h?u=c.x\u003cTet(e)?\"bottom-left\":\"bottom-right\":c.y\u003eRet(e)+1e-6?u=\"right\"===h?\"top-right\":\"top-left\":c.y\u003cRet(e)-1e-6\u0026\u0026(u=\"right\"===h?\"bottom-right\":\"bottom-left\"),{busId:`pipeline10_fanout:${e.componentId}:${n}`,connectionNames:[t.name],sourceComponentId:e.componentId,direction:h,preferredExit:u,termination:{type:\"boundary\"}}})}function Det({inputSrj:t,source:e,target:n}){const o=Eet(e,n);return{buses:Let({inputSrj:t,source:e,target:n}),sourceComponentId:e.componentId,availableCornersAndSides:[\"top_left\",\"top_middle\",\"top_right\",\"right_top\",\"right_middle\",\"right_bottom\",\"bottom_right\",\"bottom_middle\",\"bottom_left\",\"left_bottom\",\"left_middle\",\"left_top\"],componentBounds:{[e.componentId]:ket(e)},sharedBoundary:Oet(e,o),maxLayerCombinations:256,balanceLayerLoadByConnectionCount:!0,compactBusTracks:!0,borderDistribution:\"even\"}}var zet=class extends kt{constructor(t){super(),this.inputProblem=t,this.fanoutSolver=new wet(t.inputSrj,t.options),this.activeSubSolver=this.fanoutSolver,this.MAX_ITERATIONS=this.fanoutSolver.MAX_ITERATIONS+1}inputProblem;fanoutSolver;_step(){if(this.fanoutSolver.step(),this.progress=this.fanoutSolver.progress,this.stats={...this.fanoutSolver.stats},this.fanoutSolver.failed)return this.error=this.fanoutSolver.error??\"Fanout solver failed\",this.failed=!0,void(this.activeSubSolver=null);this.fanoutSolver.solved\u0026\u0026(this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.fanoutSolver.getOutput()}getOutputSimpleRouteJson(){return this.fanoutSolver.getOutputSimpleRouteJson()}visualize(){return this.fanoutSolver.visualize()}preview(){return this.fanoutSolver.preview()}},Fet=class extends kt{constructor(t){super(),this.inputProblem=t,this.autoroutingPipelineSolver=new H9(t.inputSrj,t.options),this.activeSubSolver=this.autoroutingPipelineSolver,this.MAX_ITERATIONS=this.autoroutingPipelineSolver.MAX_ITERATIONS+1}inputProblem;autoroutingPipelineSolver;_step(){if(this.autoroutingPipelineSolver.step(),this.progress=this.autoroutingPipelineSolver.progress,this.stats={...this.autoroutingPipelineSolver.stats},this.autoroutingPipelineSolver.failed)return this.error=this.autoroutingPipelineSolver.error??\"Autorouting pipeline failed\",this.failed=!0,void(this.activeSubSolver=null);this.autoroutingPipelineSolver.solved\u0026\u0026(this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.autoroutingPipelineSolver.getOutputSimpleRouteJson()}visualize(){return this.autoroutingPipelineSolver.visualize()}preview(){return this.autoroutingPipelineSolver.preview()}},Bet=class extends Dt{componentDetectionSolver;firstBgaFanoutSolver;secondBgaFanoutSolver;autoroutingPipelineSolver;get currentPipelineStepIndex(){return this.currentPipelineStageIndex}get startTimeOfPhase(){return this.startTimeOfStage}get timeSpentOnPhase(){return this.timeSpentOnStage}pipelineDef=[Lt(\"componentDetectionSolver\",UZ,t=\u003e[{inputSrj:t.inputProblem.inputSrj}]),Lt(\"firstBgaFanoutSolver\",zet,t=\u003e{const e=Aet(t.inputProblem.inputSrj,t.componentDetectionSolver.getOutput());return[{inputSrj:t.inputProblem.inputSrj,options:Det({inputSrj:t.inputProblem.inputSrj,source:e.first,target:e.second})}]}),Lt(\"secondBgaFanoutSolver\",zet,t=\u003e{const e=Aet(t.inputProblem.inputSrj,t.componentDetectionSolver.getOutput()),n=t.firstBgaFanoutSolver.getOutputSimpleRouteJson();return[{inputSrj:n,options:Det({inputSrj:n,source:e.second,target:e.first})}]}),Lt(\"autoroutingPipelineSolver\",Fet,t=\u003e[{inputSrj:t.secondBgaFanoutSolver.getOutputSimpleRouteJson(),options:t.inputProblem.options}])];constructor(t,e={}){super({inputSrj:t,options:e}),this.MAX_ITERATIONS=1e8*(e.effort??1)+1024}getSolverName(){return\"AutoroutingPipelineSolver10_BgaFanout\"}getConstructorParams(){return[this.inputProblem.inputSrj,this.inputProblem.options]}getOutput(){if(!this.autoroutingPipelineSolver?.solved)throw new Error(\"Pipeline 10 has not solved yet\");return this.autoroutingPipelineSolver.getOutput()}getOutputSimpleRouteJson(){return this.getOutput()}getOutputSimplifiedPcbTraces(){return this.getOutput().traces??[]}get srjWithPointPairs(){return this.autoroutingPipelineSolver?.autoroutingPipelineSolver.srjWithPointPairs}initialVisualize(){return Ho(this.inputProblem.inputSrj)}finalVisualize(){return Ho(this.getOutput())}},jet=class extends kt{constructor(t){super(),this.inputProblem=t,this.simplifiedRouteByTraceId=new Map(t.simplifiedHdRoutes.map(t=\u003e[t.connectionName,t])),this.MAX_ITERATIONS=t.preparedInput.preparedTraces.length+1}inputProblem;simplifiedRouteByTraceId;outputTraces=[];nextTraceIndex=0;getSolverName(){return\"ApplyTraceSimplificationSolver\"}_step(){const t=this.inputProblem.preparedInput.preparedTraces,e=t[this.nextTraceIndex];e?(this.outputTraces.push(this.applyTrace(e)),this.nextTraceIndex++,this.progress=this.nextTraceIndex/Math.max(1,t.length)):this.finishApplication()}applyTrace(t){if(!t.mutableHdRoute)return structuredClone(t.originalTrace);const e=this.simplifiedRouteByTraceId.get(t.originalTrace.pcb_trace_id);if(!e||void 0===t.uniformTraceWidth)throw new Error(`Simplification removed trace \"${t.originalTrace.pcb_trace_id}\"`);const n=Mo(e,this.inputProblem.preparedInput.srj.layerCount,{defaultViaHoleDiameter:t.viaHoleDiameter,obstacles:this.inputProblem.preparedInput.srj.obstacles,connMap:this.inputProblem.preparedInput.connMap}),o=n.filter(t=\u003e\"jumper\"===t.route_type),i=((t,e)=\u003et.map(t=\u003e\"wire\"===t.route_type||\"through_obstacle\"===t.route_type?{...t,width:e}:t))([...structuredClone(t.leadingTerminalVias),...n.filter(t=\u003e\"jumper\"!==t.route_type),...structuredClone(t.trailingTerminalVias),...o],t.uniformTraceWidth);return((t,e)=\u003e{const n=t.filter(t=\u003e\"wire\"===t.route_type);e.startPcbPortId\u0026\u0026n[0]\u0026\u0026(n[0].start_pcb_port_id=e.startPcbPortId),e.endPcbPortId\u0026\u0026n.at(-1)\u0026\u0026(n.at(-1).end_pcb_port_id=e.endPcbPortId)})(i,e),{...structuredClone(t.originalTrace),route:i}}finishApplication(){const t=this.inputProblem.preparedInput.preparedTraces;this.stats={inputTraceCount:t.length,outputTraceCount:this.outputTraces.length,inputRoutePointCount:t.reduce((t,e)=\u003et+e.originalTrace.route.length,0),outputRoutePointCount:this.outputTraces.reduce((t,e)=\u003et+e.route.length,0)},this.progress=1,this.solved=!0}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error(\"Cannot get applied traces before conversion completes\");return{...structuredClone(this.inputProblem.preparedInput.originalSrj),traces:structuredClone(this.outputTraces)}}},$et=(t,e)=\u003e{const n=t.at(-1);if(n\u0026\u0026(o=n,i=e,Math.abs(o.x-i.x)\u003c=1e-9\u0026\u0026Math.abs(o.y-i.y)\u003c=1e-9\u0026\u0026o.z===i.z))return void 0!==e.traceThickness\u0026\u0026(n.traceThickness=e.traceThickness),void(void 0!==e.pcb_port_id\u0026\u0026(n.pcb_port_id=e.pcb_port_id));var o,i;t.push(e)},Yet=(t,e,n)=\u003e{for(let o=e+1;o\u003ct.length;o++){const e=t[o];if(\"wire\"===e.route_type)return ko(e.layer,n);if(\"through_obstacle\"===e.route_type)return ko(e.from_layer,n)}},Xet=({fromZ:t,toZ:e,previousZ:n,nextZ:o})=\u003en===t?[t,e]:n===e?[e,t]:o===e?[t,e]:o===t?[e,t]:[t,e],Vet=(t,e)=\u003e{for(const e of t)if(\"via\"===e.route_type\u0026\u0026void 0!==e.via_diameter)return e.via_diameter;return e},Wet=(t,e)=\u003e{const n=\"start\"===e?t:[...t].reverse();for(const t of n){if(\"wire\"!==t.route_type)continue;const n=\"start\"===e?t.start_pcb_port_id:t.end_pcb_port_id;if(n)return n}},Het=t=\u003e({route_type:\"jumper\",start:{...t.start},end:{...t.end},footprint:t.footprint}),Get=(t,e)=\u003e{for(const e of t.route)if(\"via\"===e.route_type\u0026\u0026void 0!==e.via_hole_diameter)return e.via_hole_diameter;return e},Uet=class extends kt{preparedInput;seenTraceIds=new Set;nextTraceIndex=0;constructor(t){super();const e=structuredClone(t.inputSrj),n=fX(e),o=ii(n);this.preparedInput={originalSrj:e,srj:n,connMap:o,colorMap:wo(n,o),immutableHdRoutes:[],mutableHdRoutes:[],netByConnectionName:new Map,options:{...t.options},preparedTraces:[]},this.MAX_ITERATIONS=(n.traces?.length??0)+1}getSolverName(){return\"PrepareTraceSimplificationSolver\"}_step(){const t=this.preparedInput.srj.traces??[],e=t[this.nextTraceIndex];if(!e)return this.stats={inputTraceCount:t.length,mutableTraceCount:this.preparedInput.mutableHdRoutes.length,immutableTraceCount:t.length-this.preparedInput.mutableHdRoutes.length},this.progress=1,void(this.solved=!0);this.prepareTrace(e,this.nextTraceIndex),this.nextTraceIndex++,this.progress=this.nextTraceIndex/Math.max(1,t.length)}prepareTrace(t,e){if(this.seenTraceIds.has(t.pcb_trace_id))throw new Error(`Duplicate pcb_trace_id \"${t.pcb_trace_id}\"`);this.seenTraceIds.add(t.pcb_trace_id);const n=Yo(this.preparedInput.srj),o=(t=\u003e{const e=t.route.flatMap(t=\u003e\"wire\"===t.route_type||\"through_obstacle\"===t.route_type?[t.width]:[]),n=e[0];if(void 0!==n\u0026\u0026!e.some(t=\u003eMath.abs(t-n)\u003e1e-9))return n})(t),{traceToSimplify:i,leadingTerminalVias:r,trailingTerminalVias:s}=(t=\u003e{let e=0;for(;\"via\"===t.route[e]?.route_type;)e++;let n=t.route.length;for(;\"jumper\"===t.route[n-1]?.route_type;)n--;let o=n;for(;o\u003ee\u0026\u0026\"via\"===t.route[o-1]?.route_type;)o--;return{traceToSimplify:{...t,route:[...t.route.slice(e,o),...t.route.slice(n)]},leadingTerminalVias:t.route.slice(0,e),trailingTerminalVias:t.route.slice(o,n)}})(t),a=this.preparedInput.connMap.getNetConnectedToId(t.connection_name)??t.connection_name,c=void 0===o?void 0:((t,e)=\u003e{const n=[],o=[],i=[],r=((t,e)=\u003e{for(const e of t)if(\"wire\"===e.route_type||\"through_obstacle\"===e.route_type)return e.width;return e})(t.route,e.defaultTraceThickness);for(let s=0;s\u003ct.route.length;s++){const a=t.route[s];if(\"jumper\"===a.route_type){i.push(Het(a));continue}if(\"wire\"===a.route_type){$et(n,{x:a.x,y:a.y,z:ko(a.layer,e.layerCount),traceThickness:a.width,pcb_port_id:a.start_pcb_port_id??a.end_pcb_port_id});continue}const c=ko(a.from_layer,e.layerCount),l=ko(a.to_layer,e.layerCount),[d,h]=Xet({fromZ:c,toZ:l,previousZ:n.at(-1)?.z,nextZ:Yet(t.route,s,e.layerCount)});if(\"via\"===a.route_type){$et(n,{x:a.x,y:a.y,z:d,traceThickness:r}),$et(n,{x:a.x,y:a.y,z:h,traceThickness:r}),o.push({x:a.x,y:a.y});continue}const u=d===c,p=u?a.start:a.end,m=u?a.end:a.start;$et(n,{...p,z:d,traceThickness:a.width,toNextSegmentType:\"through_obstacle\",...a.circuitJsonMetadata?{toNextSegmentCircuitJsonMetadata:a.circuitJsonMetadata}:{}}),$et(n,{...m,z:h,traceThickness:a.width})}return{connectionName:t.pcb_trace_id,rootConnectionName:e.rootConnectionName,startPcbPortId:Wet(t.route,\"start\"),endPcbPortId:Wet(t.route,\"end\"),traceThickness:r,viaDiameter:Vet(t.route,e.defaultViaDiameter),route:n,vias:o,...i.length\u003e0?{jumpers:i}:{}}})(i,{layerCount:this.preparedInput.srj.layerCount,defaultTraceThickness:o,defaultViaDiameter:n.padDiameter,rootConnectionName:a}),l=c\u0026\u0026c.route.length\u003e=2?c:void 0;if(this.preparedInput.preparedTraces.push({originalTrace:t,mutableHdRoute:l,leadingTerminalVias:r,trailingTerminalVias:s,uniformTraceWidth:o,viaHoleDiameter:Get(t,n.holeDiameter)}),!l)return void this.preparedInput.immutableHdRoutes.push(...oQ(t,e,this.preparedInput.srj.layerCount,n.padDiameter,this.preparedInput.connMap));this.preparedInput.mutableHdRoutes.push(l),this.preparedInput.netByConnectionName.set(l.connectionName,a),this.preparedInput.colorMap[l.connectionName]=this.preparedInput.colorMap[a]??this.preparedInput.colorMap[t.connection_name]??\"#2563eb\";const d={...t,route:[...r,...s]};this.preparedInput.immutableHdRoutes.push(...oQ(d,e,this.preparedInput.srj.layerCount,n.padDiameter,this.preparedInput.connMap))}getOutput(){if(!this.solved)throw new Error(\"Cannot get prepared traces before preparation completes\");return this.preparedInput}},Zet=class extends kt{constructor(t){super(),this.inputProblem=t;const e=t.preparedInput,n=Yo(e.srj);this.traceSimplificationSolver=new vc({hdRoutes:e.mutableHdRoutes,otherHdRoutes:e.immutableHdRoutes,obstacles:e.srj.obstacles,connMap:e.connMap,colorMap:e.colorMap,outline:e.srj.outline,defaultViaDiameter:n.padDiameter,layerCount:e.srj.layerCount,minTraceToPadEdgeClearance:e.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:e.srj.minBoardEdgeClearance,netByConnectionName:e.netByConnectionName,enableCrossingViaReduction:e.options.enableCrossingViaReduction??!0,preserveRouteEndpoints:!0,useTraceWidthAwareClearance:!0,enableVertexShortcuts:e.options.enableVertexShortcuts??!0}),this.traceSimplificationSolver.MAX_SIMPLIFICATION_PIPELINE_LOOPS=e.options.iterations??2,this.activeSubSolver=this.traceSimplificationSolver,this.MAX_ITERATIONS=this.traceSimplificationSolver.MAX_ITERATIONS+1}inputProblem;traceSimplificationSolver;getSolverName(){return\"TraceSimplificationStageSolver\"}_step(){if(this.traceSimplificationSolver.step(),this.progress=this.traceSimplificationSolver.progress,this.stats={...this.traceSimplificationSolver.stats},this.traceSimplificationSolver.failed)return this.error=this.traceSimplificationSolver.error??\"Trace simplification failed\",this.failed=!0,void(this.activeSubSolver=null);this.traceSimplificationSolver.solved\u0026\u0026(this.progress=1,this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error(\"Cannot get simplified routes before cleanup completes\");return structuredClone(this.traceSimplificationSolver.simplifiedHdRoutes)}visualize(){return this.traceSimplificationSolver.visualize()}preview(){return this.traceSimplificationSolver.preview()}},qet=class extends kt{constructor(t){super(),this.inputProblem=t;const e=t.preparedInput;this.drcEngine=new s_(e.srj,{connMap:e.connMap,traceClearance:e.srj.minTraceToPadEdgeClearance??.1,viaClearance:.1}),this.MAX_ITERATIONS=3}inputProblem;drcEngine;phase=\"baseline\";baselineErrorCounts={};outputErrorCounts={};getSolverName(){return\"ValidateTraceSimplificationSolver\"}_step(){return\"baseline\"===this.phase?(this.baselineErrorCounts=this.evaluateErrorCounts(this.inputProblem.preparedInput.originalSrj),this.phase=\"output\",void(this.progress=1/3)):\"output\"===this.phase?(this.outputErrorCounts=this.evaluateErrorCounts(this.inputProblem.outputSrj),this.phase=\"compare\",void(this.progress=2/3)):(this.assertNoNewDrcErrors(),this.stats={baselineErrorCounts:this.baselineErrorCounts,outputErrorCounts:this.outputErrorCounts},this.progress=1,void(this.solved=!0))}evaluateErrorCounts(t){return(t=\u003e{const e={};for(const n of t.errors)e[n.type]=(e[n.type]??0)+1;return e})(this.drcEngine.evaluate(t.traces??[]))}assertNoNewDrcErrors(){const t=[...new Set([...Object.keys(this.baselineErrorCounts),...Object.keys(this.outputErrorCounts)])].filter(t=\u003e(this.outputErrorCounts[t]??0)\u003e(this.baselineErrorCounts[t]??0));if(0===t.length)return;const e=t.map(t=\u003e`${t}: ${this.baselineErrorCounts[t]??0} -\u003e ${this.outputErrorCounts[t]??0}`).join(\", \");throw new Error(`Pipeline 11 simplification introduced DRC errors (${e})`)}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error(\"Cannot get Pipeline 11 output before DRC validation\");return structuredClone(this.inputProblem.outputSrj)}},Jet=class extends Dt{prepareTraceSimplificationSolver;traceSimplificationStageSolver;applyTraceSimplificationSolver;validateTraceSimplificationSolver;pipelineDef=[Lt(\"prepareTraceSimplificationSolver\",Uet,t=\u003e[{inputSrj:t.inputProblem.inputSrj,options:t.inputProblem.options}]),Lt(\"traceSimplificationStageSolver\",Zet,t=\u003e[{preparedInput:t.prepareTraceSimplificationSolver.getOutput()}]),Lt(\"applyTraceSimplificationSolver\",jet,t=\u003e[{preparedInput:t.prepareTraceSimplificationSolver.getOutput(),simplifiedHdRoutes:t.traceSimplificationStageSolver.getOutput()}]),Lt(\"validateTraceSimplificationSolver\",qet,t=\u003e[{preparedInput:t.prepareTraceSimplificationSolver.getOutput(),outputSrj:t.applyTraceSimplificationSolver.getOutput()}])];constructor(t,e={}){if(void 0!==e.iterations\u0026\u0026(!Number.isInteger(e.iterations)||e.iterations\u003c1))throw new Error(\"Simplification iterations must be a positive integer\");super({inputSrj:t,options:{...e}}),this.MAX_ITERATIONS=1e8}getSolverName(){return\"AutoroutingPipelineSolver11_Simplification\"}getConstructorParams(){return[this.inputProblem.inputSrj,this.inputProblem.options]}getOutput(){if(!this.validateTraceSimplificationSolver?.solved)throw new Error(\"Pipeline 11 simplification has not solved yet\");return this.validateTraceSimplificationSolver.getOutput()}getOutputSimpleRouteJson(){return this.getOutput()}getOutputSimplifiedPcbTraces(){return structuredClone(this.getOutput().traces??[])}initialVisualize(){return Ho(this.inputProblem.inputSrj)}finalVisualize(){return Ho(this.getOutput())}},Ket=class extends kc{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e}srj;opts;MAX_SIZE_FOR_SINGLE_LAYER_NODES=2;isObstacleAssignable(t){return Boolean(t?.netIsAssignable)}getOverlappingAssignableObstacles(t){return this.getXYZOverlappingObstacles(t).filter(t=\u003ethis.isObstacleAssignable(t))}shouldNodeBeXYSubdivided(t){return!(t._depth\u003e=this.MAX_DEPTH)\u0026\u0026(!!t._containsTarget||(!(!t._containsObstacle||t._completelyInsideObstacle)||1===t.availableZ.length\u0026\u0026(t.width\u003ethis.MAX_SIZE_FOR_SINGLE_LAYER_NODES||t.height\u003ethis.MAX_SIZE_FOR_SINGLE_LAYER_NODES)))}shouldFilterNodeForObstacle(t){if(!t._containsObstacle)return!1;return!(this.getOverlappingAssignableObstacles(t).length\u003e0)\u0026\u0026(1!==t.availableZ.length||this.shouldFilterSingleLayerNodeForObstacle(t))}insertAssignableObstaclesAsNodes(){const t=this.srj.obstacles.filter(t=\u003ethis.isObstacleAssignable(t)),e=new Map;for(const n of t){const t=[];for(const e of this.finishedNodes){this.getXYZOverlappingObstacles(e).some(t=\u003et===n)\u0026\u0026t.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=\u003e!n.has(t));for(const n of t){const t=e.get(n)||[],o=n.layers\u0026\u0026n.layers.length\u003e0?Array.from(new Set(n.layers.map(t=\u003eko(t,this.srj.layerCount)))).sort((t,e)=\u003et-e):Array.from({length:this.srj.layerCount},(t,e)=\u003ethis.srj.layerCount-e-1);let i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=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,o=e.center.y-e.height/2,c=e.center.y+e.height/2;i=Math.min(i,t),r=Math.max(r,n),s=Math.min(s,o),a=Math.max(a,c)}const c=r-i,l=a-s,d=(i+r)/2,h=(s+a)/2;let u=!1;for(const t of this.srj.connections){for(const e of t.pointsToConnect)if(e.x\u003e=i\u0026\u0026e.x\u003c=r\u0026\u0026e.y\u003e=s\u0026\u0026e.y\u003c=a){u=!0;break}if(u)break}const p={capacityMeshNodeId:`assignable_via_${n.center.x}_${n.center.y}`,center:{x:d,y:h},width:c,height:l,layer:1===o.length?`z${o[0]}`:`z${o.join(\",\")}`,availableZ:o,_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=[],o=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),i=t.availableZ.length\u003e1\u0026\u0026!e;if(e)o.push(t);else{if(i){const e=this.getZSubdivisionChildNodes(t);for(const t of e)!t._containsTarget\u0026\u0026this.shouldFilterNodeForObstacle(t)||(this.shouldNodeBeXYSubdivided(t)?o.push(t):(t._containsObstacle=!1,n.push(t)));continue}this.shouldFilterNodeForObstacle(t)\u0026\u0026!t._containsTarget||n.push(t)}}this.unfinishedNodes.push(...o),this.finishedNodes.push(...n)}},Qet=.005,tnt=class extends si{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\u003e1?(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)=\u003et[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])=\u003et.capacityMeshNodeId),this.nextBatchNodeIds=[],this.batchHadModifications=!1}computeAdjacentNodeIdsForFirstBatch(t){const e=Math.max(...t.map(t=\u003eMath.max(...t.availableZ))),n=[];for(let o=0;o\u003c=e;o++)n.push(new hi(t.filter(t=\u003et.availableZ[0]===o)));for(const e of t){const t=[],o=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of o)n._containsTarget\u0026\u0026n._targetConnectionName!==e._targetConnectionName||e._containsTarget\u0026\u0026(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId\u0026\u0026li(e,n)\u0026\u0026t.push(n);e._adjacentNodeIds=t.map(t=\u003et.capacityMeshNodeId)}}getAdjacentSameLayerUnprocessedNodes(t){const e=[],n=Array.from(new Set((t._adjacentNodeIds??[]).map(t=\u003ethis.nodeMap.get(t)))).filter(e=\u003ee\u0026\u0026e.capacityMeshNodeId!==t.capacityMeshNodeId);n.sort((t,e)=\u003et.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=\u003ethis.nodeMap.get(t))),this.hasComputedAdjacentNodeIds=!0);let t=this.currentBatchNodeIds.pop();for(;t\u0026\u0026this.absorbedNodeIds.has(t);)t=this.currentBatchNodeIds.pop();if(!t)return this.batchHadModifications?(this.currentBatchNodeIds=this.nextBatchNodeIds.sort((t,e)=\u003e{const n=this.nodeMap.get(t),o=this.nodeMap.get(e);return n.width*n.height-o.width*o.height}),this.nextBatchNodeIds=[],void(this.batchHadModifications=!1)):(this.solved=!0,void this.newNodes.push(...this.nextBatchNodeIds.map(t=\u003ethis.nodeMap.get(t))));const e=this.nodeMap.get(t);let n=!1;const o=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===o.length)return void this.nextBatchNodeIds.push(t);const i=t=\u003e{for(const e of t)this.absorbedNodeIds.add(e.capacityMeshNodeId);e._adjacentNodeIds=Array.from(new Set([...e._adjacentNodeIds??[],...t.flatMap(t=\u003et._adjacentNodeIds??[])].filter(t=\u003et!==e.capacityMeshNodeId\u0026\u0026!this.absorbedNodeIds.has(t))))},r=o.filter(t=\u003et.center.x\u003ce.center.x\u0026\u0026Math.abs(t.center.y-e.center.y)\u003ce.height/2);if(r.length\u003e0){const{width:t,height:o}=r[0],s=r.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(r.reduce((t,e)=\u003et+e.height,0)-e.height)\u003cQet\u0026\u0026s\u0026\u0026(e.width+=t,e.center.x=e.center.x-t/2,i(r),n=!0)}const s=o.filter(t=\u003et.center.x\u003ee.center.x\u0026\u0026Math.abs(t.center.y-e.center.y)\u003ce.height/2);if(s.length\u003e0\u0026\u0026!n){const{width:t,height:o}=s[0],r=s.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(s.reduce((t,e)=\u003et+e.height,0)-e.height)\u003cQet\u0026\u0026r\u0026\u0026(e.width+=t,e.center.x=e.center.x+t/2,i(s),n=!0)}const a=o.filter(t=\u003et.center.y\u003ee.center.y\u0026\u0026Math.abs(t.center.x-e.center.x)\u003ce.width/2);if(a.length\u003e0\u0026\u0026!n){const{width:t,height:o}=a[0],r=a.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(a.reduce((t,e)=\u003et+e.width,0)-e.width)\u003cQet\u0026\u0026r\u0026\u0026(e.height+=o,e.center.y=e.center.y+o/2,i(a),n=!0)}const c=o.filter(t=\u003et.center.y\u003ce.center.y\u0026\u0026Math.abs(t.center.x-e.center.x)\u003ce.width/2);if(c.length\u003e0\u0026\u0026!n){const{width:t,height:o}=c[0],r=c.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(c.reduce((t,e)=\u003et+e.width,0)-e.width)\u003cQet\u0026\u0026r\u0026\u0026(e.height+=o,e.center.y=e.center.y-o/2,i(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(Dc(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e\u0026\u0026(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const o of this.currentBatchNodeIds){const i=this.nodeMap.get(o);if(!this.absorbedNodeIds.has(o)\u0026\u0026i){const r=Dc(i,{rectMargin:.01});o===e?r.stroke=\"rgba(0, 255, 0, 0.8)\":n?.some(t=\u003et.capacityMeshNodeId===o)?r.stroke=\"rgba(128, 0, 128, 0.8)\":r.stroke=\"rgba(255, 165, 0, 0.8)\",r.layer=`z${i.availableZ.join(\",\")}`,r.label=`${r.label}\\n(unprocessed)`,t.rects.push(r)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)\u0026\u0026n){const e=Dc(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}},ent=class extends si{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,o=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;const s=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,l=t.center.y-t.height/2,d=t.center.y+t.height/2;n=Math.min(n,e),o=Math.max(o,c),i=Math.min(i,l),r=Math.max(r,d);for(const e of t.availableZ)s.add(e);t._containsTarget\u0026\u0026(a=!0)}const c=o-n,l=r-i,d=(n+o)/2,h=(i+r)/2,u=Array.from(s).sort((t,e)=\u003et-e),p={capacityMeshNodeId:`merged_via_${t.center.x}_${t.center.y}`,center:{x:d,y:h},width:c,height:l,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=Dc(e);e._assignedViaObstacle\u0026\u0026(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=Dc(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}},nnt=class extends si{constructor(t){const{simpleRouteJson:e,nodes:n,edges:o,colorMap:i,MAX_ITERATIONS:r=1e6,hyperParameters:s={}}=t;super(),this.inputParams=t,this.hyperParameters=s,this.MAX_ITERATIONS=r,this.simpleRouteJson=e,this.nodes=n,this.edges=o,this.colorMap=i??{},this.nodeMap=new Map(this.nodes.map(t=\u003e[t.capacityMeshNodeId,t])),this.nodeEdgeMap=ai(this.edges);const a=this.nodes.filter(t=\u003et._containsTarget);this.unprocessedConnectionPairs=Xi(this.simpleRouteJson.connections.map(t=\u003e{const[e,n]=t.pointsToConnect;return{start:a.find(t=\u003exe(t.center,e)\u003ct.width/2),end:a.find(t=\u003exe(t.center,n)\u003ct.width/2),connection:t}}),this.hyperParameters.SHUFFLE_SEED??0),this.viaNodes=this.nodes.filter(t=\u003et.availableZ.length\u003e1)}inputParams;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=\u003e!t._completelyInsideObstacle\u0026\u0026!t._containsObstacle).filter(t=\u003e!this.usedNodeMap.has(t.capacityMeshNodeId));if(e.length\u003e0){const n=e.reduce((e,n)=\u003e{const o=this._dist(e,t.start);return this._dist(n,t.start)\u003co?n:e});this.closestViaForConnectionStartMap.set(t,n);const o=e.reduce((e,n)=\u003e{const o=this._dist(e,t.end);return this._dist(n,t.end)\u003co?n:e});this.closestViaForConnectionEndMap.set(t,o)}}}_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\u0026\u0026!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\u0026\u0026(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\u0026\u00260===this.visitedNodes.size){const t=this._dist(e,n),o={prevCandidate:null,node:e,g:0,h:t,f:this.GREEDY_MULTIPLIER*t};this.queuedCandidateNodes.push(o)}let o;for(this.queuedCandidateNodes.sort((t,e)=\u003et.f-e.f);this.queuedCandidateNodes.length\u0026\u0026!o;){const t=this.queuedCandidateNodes.shift();this.visitedNodes.has(t.node.capacityMeshNodeId)||(o=t)}if(!o)return this.failed=!0,void(this.error=\"No viable candidates left\");if(this.visitedNodes.add(o.node.capacityMeshNodeId),o.node.capacityMeshNodeId===n.capacityMeshNodeId){const e=[];let n=o;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 i=this.getNeighbors(o.node);for(const t of i){const e=t.capacityMeshNodeId;if(this.visitedNodes.has(e))continue;const i=this.computeG(o,t,n),r=this.computeH(o,t,n),s=i+this.GREEDY_MULTIPLIER*r,a=this.queuedCandidateNodes.findIndex(t=\u003et.node.capacityMeshNodeId===e);if(a\u003e=0){if(this.queuedCandidateNodes[a].g\u003c=i)continue;this.queuedCandidateNodes.splice(a,1)}this.queuedCandidateNodes.push({prevCandidate:o,node:t,g:i,h:r,f:s})}}getNeighbors(t){const e=new Set,n=this.nodeEdgeMap.get(t.capacityMeshNodeId)??[];for(const o of n){const[n,i]=o.nodeIds,r=n===t.capacityMeshNodeId?i:n,s=this.nodeMap.get(r);s\u0026\u0026e.add(s)}const o=this.activeSubpath?.layer;return Array.from(e).filter(t=\u003e!(t.capacityMeshNodeId!==this.activeSubpath?.end.capacityMeshNodeId)||!t._containsObstacle\u0026\u0026(!t._containsTarget\u0026\u0026(!this.usedNodeMap.has(t.capacityMeshNodeId)\u0026\u0026!(void 0!==o\u0026\u0026!t.availableZ.includes(o)))))}clearCandidateNodes(){this.queuedCandidateNodes=[],this.visitedNodes=new Set}computeG(t,e,n){const o=this._dist(t.node,e);return t.g+o}computeH(t,e,n){return this._dist(e,n)}createSolvedRoute(t,e){const n=[];for(let e=0;e\u003ct.length;e++){const o=t[e];o.path?0===e?n.push(...o.path):n.push(...o.path.slice(1)):(0===e\u0026\u0026n.push(o.start),e===t.length-1\u0026\u0026n.push(o.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,$i(e.reduce((t,e)=\u003et+16807*e%2147483647,0))()\u003cn))return[{start:t.start,end:t.end,solved:!1,layer:t.start.availableZ[0]??0}];const o=this.getClosestVia(t.start),i=this.getFarVia(o,t.end),r=t.start.availableZ[0]??0,s=t.end.availableZ[0]??0,a=[];return a.push({start:t.start,end:o,solved:!1,layer:r}),r===s?(a.push({start:o,end:i,solved:!1,layer:0===r?1:0}),a.push({start:i,end:t.end,solved:!1,layer:s})):a.push({start:o,end:t.end,solved:!1,layer:s}),a}getClosestVia(t){if(0===this.viaNodes.length)return t;const e=new Set;for(const[t,n]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair\u0026\u0026e.add(n.capacityMeshNodeId);for(const[t,n]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair\u0026\u0026e.add(n.capacityMeshNodeId);const n=this.viaNodes.filter(t=\u003e!t._completelyInsideObstacle\u0026\u0026!t._containsObstacle).filter(t=\u003e!this.usedNodeMap.has(t.capacityMeshNodeId)).filter(t=\u003e!e.has(t.capacityMeshNodeId));if(0===n.length){const e=this.viaNodes.filter(t=\u003e!t._completelyInsideObstacle\u0026\u0026!t._containsObstacle).filter(t=\u003e!this.usedNodeMap.has(t.capacityMeshNodeId));return 0===e.length?t:(e.sort((e,n)=\u003ethis._dist(e,t)-this._dist(n,t)),e[0])}n.sort((e,n)=\u003ethis._dist(e,t)-this._dist(n,t));const o=this.hyperParameters.MAX_CLOSEST_VIA_SKIP??0;if(o\u003e0\u0026\u0026n.length\u003e1){const t=$i((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length),e=Math.floor(t()*(o+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,o=new Set;for(const[t,e]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair\u0026\u0026o.add(e.capacityMeshNodeId);for(const[t,e]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair\u0026\u0026o.add(e.capacityMeshNodeId);const i=this.viaNodes.filter(e=\u003e!this.usedNodeMap.has(e.capacityMeshNodeId)\u0026\u0026e.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026!e._completelyInsideObstacle\u0026\u0026!e._containsObstacle\u0026\u0026!o.has(e.capacityMeshNodeId)\u0026\u0026this._dist(e,t)\u003e=n);if(0===i.length){const o=this.viaNodes.filter(e=\u003ee.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026!e._completelyInsideObstacle\u0026\u0026!e._containsObstacle\u0026\u0026!this.usedNodeMap.has(e.capacityMeshNodeId)\u0026\u0026this._dist(e,t)\u003e=n).sort((t,n)=\u003ethis._dist(t,e)-this._dist(n,e));if(o.length\u003e0)return o[0];return this.viaNodes.filter(e=\u003ee.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026!e._completelyInsideObstacle\u0026\u0026!e._containsObstacle\u0026\u0026!this.usedNodeMap.has(e.capacityMeshNodeId)).sort((t,n)=\u003ethis._dist(t,e)-this._dist(n,e))[0]??t}i.sort((t,n)=\u003ethis._dist(t,e)-this._dist(n,e));const r=this.hyperParameters.MAX_FURTHEST_VIA_SKIP??0;if(r\u003e0\u0026\u0026i.length\u003e1){const t=$i((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length+1e3),e=Math.floor(t()*(r+1));return i[Math.min(e,i.length-1)]}return i[0]}getCapacityPaths(){const t=[];for(const e of this.solvedRoutes){const n=e.path;n\u0026\u0026n.length\u003e0\u0026\u0026t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,nodeIds:n.map(t=\u003et.capacityMeshNodeId)})}return t}visualize(){const t={lines:[],points:[],rects:[],circles:[]},e=t=\u003e!!t\u0026\u0026\"number\"==typeof t.x\u0026\u0026\"number\"==typeof t.y\u0026\u0026!Number.isNaN(t.x)\u0026\u0026!Number.isNaN(t.y)\u0026\u0026Number.isFinite(t.x)\u0026\u0026Number.isFinite(t.y),n=t=\u003e\"number\"==typeof t\u0026\u0026!Number.isNaN(t)\u0026\u0026Number.isFinite(t);for(const o of this.nodes){const i=this.queuedCandidateNodes.some(t=\u003et.node.capacityMeshNodeId===o.capacityMeshNodeId),r=this.queuedCandidateNodes.find(t=\u003et.node.capacityMeshNodeId===o.capacityMeshNodeId);if(e(o.center)\u0026\u0026n(o.width)\u0026\u0026n(o.height)){const e=Dc(o,{rectMargin:.025,zOffset:.01});t.rects.push({...e,fill:i?\"rgba(255, 128, 255, 0.5)\":o._containsTarget?\"rgba(0, 150, 255, 0.15)\":o._containsObstacle?\"rgba(255, 0, 0, 0.1)\":\"rgba(200, 200, 200, 0.05)\",label:[`ID: ${o.capacityMeshNodeId}`,`Size: ${o.width.toFixed(2)}x${o.height.toFixed(2)}`,`Z: ${o.availableZ.join(\", \")}`,r?`g: ${r.g.toFixed(2)}`:\"\",r?`h: ${r.h.toFixed(2)}`:\"\",r?`f: ${r.f.toFixed(2)}`:\"\",o._containsTarget?\"TARGET\":\"\",o._containsObstacle?\"OBSTACLE\":\"\"].filter(t=\u003et).join(\"\\n\")})}}for(const n of this.edges){const[o,i]=n.nodeIds,r=this.nodeMap.get(o),s=this.nodeMap.get(i);r?.center\u0026\u0026s?.center\u0026\u0026e(r.center)\u0026\u0026e(s.center)\u0026\u0026t.lines.push({points:[r.center,s.center],strokeColor:\"rgba(150, 150, 150, 0.2)\"})}for(let n=0;n\u003cthis.solvedRoutes.length;n++){const o=this.solvedRoutes[n],i=o.path,r=\"blue\";for(let o=0;o\u003ci.length-1;o++){const s=i[o],a=i[o+1];if(s?.center\u0026\u0026a?.center\u0026\u0026e(s.center)\u0026\u0026e(a.center)){const e=s.availableZ.includes(1)\u0026\u0026a.availableZ.includes(1),o=n%5*.02;t.lines.push({points:[{x:s.center.x+o,y:s.center.y+o},{x:a.center.x+o,y:a.center.y+o}],strokeColor:r,strokeDash:e?\"5 5\":void 0})}}if(i.length\u003e0){const n=i[0],r=i[i.length-1];n?.center\u0026\u0026e(n.center)\u0026\u0026t.points.push({x:n.center.x,y:n.center.y,label:`START: ${o.connection.name}`}),r?.center\u0026\u0026e(r.center)\u0026\u0026t.points.push({x:r.center.x,y:r.center.y,label:`END: ${o.connection.name}`})}}if(this.solvedSubpaths)for(let n=0;n\u003cthis.solvedSubpaths.length;n++){const o=this.solvedSubpaths[n];if(o.path\u0026\u0026o.path.length\u003e1)for(let n=0;n\u003co.path.length-1;n++){const i=o.path[n],r=o.path[n+1];i?.center\u0026\u0026r?.center\u0026\u0026e(i.center)\u0026\u0026e(r.center)\u0026\u0026t.lines.push({points:[i.center,r.center],strokeColor:\"green\",strokeDash:1===o.layer?\"3 3\":void 0})}}if(this.activeSubpath){const n=this.activeSubpath.start?.center,o=this.activeSubpath.end?.center;n\u0026\u0026o\u0026\u0026e(n)\u0026\u0026e(o)\u0026\u0026(t.lines.push({points:[n,o],strokeColor:\"orange\",strokeDash:\"5 5\"}),t.points.push({x:n.x,y:n.y,label:\"ACTIVE START\"}),t.points.push({x:o.x,y:o.y,label:\"ACTIVE END\"}))}const o=this.queuedCandidateNodes.slice(0,10).sort((t,e)=\u003et.f-e.f);for(let n=0;n\u003co.length;n++){const i=.6*(1-n/10),r=[];let s=o[n];for(;s;)r.push(s.node),s=s.prevCandidate;if(r.reverse(),r.length\u003e1){const n=r.map(t=\u003et.center).filter(t=\u003ee(t));n.length\u003e1\u0026\u0026t.lines.push({points:n,strokeColor:To(\"purple\",1-i),strokeDash:1===this.activeSubpath?.layer?\"4 2\":void 0})}}if(this.activeConnectionPair){const n=this.activeConnectionPair.start?.center,o=this.activeConnectionPair.end?.center;n\u0026\u0026o\u0026\u0026e(n)\u0026\u0026e(o)\u0026\u0026t.lines.push({points:[n,o],strokeColor:\"cyan\",strokeDash:\"20 5\"})}if(this.ogUnprocessedSubpaths\u0026\u00263===this.ogUnprocessedSubpaths.length){const[,o]=this.ogUnprocessedSubpaths;if(o.start?.center\u0026\u0026e(o.start.center)){const e=Math.max(o.start.width||0,o.start.height||0);n(e)\u0026\u0026e\u003e0\u0026\u0026(t.circles.push({center:o.start.center,radius:e,stroke:\"blue\"}),t.points.push({x:o.start.center.x,y:o.start.center.y,label:\"DIRECTIVE VIA 1\"}))}if(o.end?.center\u0026\u0026e(o.end.center)){const e=Math.max(o.end.width||0,o.end.height||0);n(e)\u0026\u0026e\u003e0\u0026\u0026(t.circles.push({center:o.end.center,radius:e,stroke:\"purple\"}),t.points.push({x:o.end.center.x,y:o.end.center.y,label:\"DIRECTIVE VIA 2\"}))}}if(this.queuedCandidateNodes.length\u003e0)for(const n of this.queuedCandidateNodes){const o=n.node;o?.center\u0026\u0026e(o.center)\u0026\u0026t.circles.push({center:o.center,radius:.05,fill:\"rgba(255, 255, 0, 0.6)\",stroke:\"yellow\"})}if(this.visitedNodes.size\u003e0)for(const n of this.visitedNodes){const o=this.nodeMap.get(n);o?.center\u0026\u0026e(o.center)\u0026\u0026t.circles.push({center:o.center,radius:.08,fill:\"rgba(128, 128, 128, 0.5)\",stroke:\"gray\"})}return t}},ont=class extends ys{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,o=e\u003e0?n/e:0;return t.iterations/t.MAX_ITERATIONS+(1-o)}computeH(t){const e=t.unprocessedConnectionPairs.length+t.solvedRoutes.length+(t.activeConnectionPair?1:0),n=t.solvedRoutes.length;return e\u003e0?1-n/e:0}generateSolver(t){return new nnt({...this.constructorParams,hyperParameters:{...this.constructorParams.hyperParameters,...t}})}};function int(t){const e=new Map;for(const n of t)e.set(n.capacityMeshNodeId,n);return e}function rnt(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}var snt=class extends si{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=int(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\u0026\u0026e.offBoardConnectsTo.length\u003e0\u0026\u0026this.assignableNodes.push(t)}}initializePendingEdges(){const t=new Map;for(const e of this.assignableNodes){const n=e._assignedViaObstacle;if(n?.offBoardConnectsTo)for(const o of n.offBoardConnectsTo)t.has(o)||t.set(o,[]),t.get(o).push(e)}this.pendingEdges=[];for(const[e,n]of t)if(n.length\u003e1)for(let t=0;t\u003cn.length;t++)for(let o=t+1;o\u003cn.length;o++)this.pendingEdges.push({node1:n[t],node2:n[o],netName:e})}_step(){switch(this.animationState){case\"showing_nodes\":if(this.assignableNodes.length\u003e0){const t=this.assignableNodes.shift();this.shownNodes.push(t)}else this.animationState=\"showing_edges\";break;case\"showing_edges\":if(this.pendingEdges.length\u003e0){const{node1:t,node2:e,netName:n}=this.pendingEdges.shift(),o=this.createOffboardEdge(t,e,n);this.enhancedEdges.push(o),this.createdEdges.push(o)}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=[],o=new Set(this.shownNodes.map(t=\u003et.capacityMeshNodeId));for(const e of this.capacityEdges){if(e.isOffboardEdge)continue;if(o.has(e.nodeIds[0])||o.has(e.nodeIds[1])){const n=this.nodeMap.get(e.nodeIds[0]),o=this.nodeMap.get(e.nodeIds[1]);n\u0026\u0026o\u0026\u0026t.push({points:[n.center,o.center],strokeColor:\"rgba(0, 200, 0, 0.5)\",strokeWidth:.05})}}for(let t=0;t\u003cthis.shownNodes.length;t++){const o=this.shownNodes[t],i=o._assignedViaObstacle,r=t===this.shownNodes.length-1\u0026\u0026\"showing_nodes\"===this.animationState;n.push({center:o.center,width:o.width,height:o.height,fill:r?\"rgba(255, 165, 0, 0.5)\":\"rgba(173, 216, 230, 0.5)\",stroke:r?\"orange\":\"blue\",strokeWidth:r?.15:.1}),e.push({x:o.center.x,y:o.center.y,color:r?\"orange\":\"blue\",label:`${r?\"NEW: \":\"\"}${o.capacityMeshNodeId}\\n${i?.offBoardConnectsTo?.join(\", \")||\"\"}`})}for(let n=0;n\u003cthis.createdEdges.length;n++){const o=this.createdEdges[n],i=n===this.createdEdges.length-1\u0026\u0026\"showing_edges\"===this.animationState,r=this.nodeMap.get(o.nodeIds[0]),s=this.nodeMap.get(o.nodeIds[1]);if(r\u0026\u0026s){t.push({points:[r.center,s.center],strokeColor:i?\"red\":\"orange\",strokeWidth:i?.2:.1,strokeDasharray:\"0.3,0.15\"});const n=rnt(r.center,s.center);e.push({x:n.x,y:n.y,color:i?\"red\":\"orange\",label:`${i?\"NEW: \":\"\"}⚡ ${o.offboardNetName}`})}}let i=\"Offboard Capacity Node Solver\";switch(this.animationState){case\"showing_nodes\":i+=` - Showing nodes (${this.shownNodes.length}/${this.shownNodes.length+this.assignableNodes.length})`;break;case\"showing_edges\":i+=` - Creating edges (${this.createdEdges.length}/${this.createdEdges.length+this.pendingEdges.length})`;break;case\"done\":i+=` - Done (${this.shownNodes.length} nodes, ${this.createdEdges.length} edges)`}return{lines:t,points:e,rects:n,title:i}}getVirtualOffboardNodes(){return[]}getOffboardEdges(){return this.enhancedEdges.filter(t=\u003et.isOffboardEdge)}},ant=class extends si{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:o}){super(),this.inputPaths=[...t],this.capacityEdges=e,this.originalConnections=o,this.nodeMap=int(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=\u003et.isFragmentedPath)?this.animationState=\"showing_fragment\":this.fragmentedPaths.push(...this.currentFragments);break;case\"showing_fragment\":if(this.currentFragmentIndex\u003cthis.currentFragments.length){const t=this.currentFragments[this.currentFragmentIndex];this.fragmentedPaths.push(t),this.currentFragmentIndex++}else this.currentPath\u0026\u0026(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=\u003ee.name===t.connectionName);if(n)for(let t=0;t\u003ce.length;t++){const o=e[t];if(!o.isFragmentedPath)continue;const i=n.pointsToConnect.filter(t=\u003e{for(const e of o.nodeIds){const n=this.nodeMap.get(e);if(n\u0026\u0026Xj(t,n))return!0}return!1}),r=0===t,s=r?o.nodeIds[o.nodeIds.length-1]:o.nodeIds[0],a=this.nodeMap.get(s);if(i.length\u003e0\u0026\u0026a){const t=i[0],e={x:a.center.x,y:a.center.y,layer:bo(t)},s=r?[...i,e]:[e,...i];this.fragmentedConnections.push({name:o.connectionName,pointsToConnect:s,__netConnectionName:n.__netConnectionName,__rootConnectionNames:n.__rootConnectionNames})}}}splitPath(t){const{nodeIds:e}=t;if(e.length\u003c2)return[t];const n=[];for(let t=0;t\u003ce.length-1;t++){const o=this.capacityEdges.find(n=\u003en.nodeIds[0]===e[t]\u0026\u0026n.nodeIds[1]===e[t+1]||n.nodeIds[0]===e[t+1]\u0026\u0026n.nodeIds[1]===e[t]);o\u0026\u0026o.isOffboardEdge\u0026\u0026n.push(t)}if(0===n.length)return[t];const o=[];let i=0,r=0;for(const s of n){const n=e.slice(i,s+1);if(n.length\u003e=1){const e=this.nextFragmentId++;o.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${r++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}i=s+1}if(i\u003ce.length){const n=e.slice(i);if(n.length\u003e=1){const e=this.nextFragmentId++;o.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${r++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}}return o.length\u003e0?o:[t]}getFragmentedPaths(){return this.fragmentedPaths}getFragmentedConnections(){return this.fragmentedConnections}getFragmentedOriginalConnectionNames(){return this.fragmentedOriginalConnectionNames}visualize(){const t=[],e=[],n=[];if(\"showing_original_path\"===this.animationState\u0026\u0026this.currentPath\u0026\u0026this.drawPath({path:this.currentPath,color:\"gray\",lines:t,points:e,rects:n,labelPrefix:\"Original: \"}),this.fragmentedPaths.forEach((o,i)=\u003e{if(o.isFragmentedPath){const r=i%2==0?\"blue\":\"red\";this.drawPath({path:o,color:r,lines:t,points:e,rects:n,labelPrefix:`Frag ${i}: `})}else this.drawPath({path:o,color:\"green\",lines:t,points:e,rects:n,labelPrefix:\"\"})}),\"showing_fragment\"===this.animationState\u0026\u0026this.currentFragmentIndex\u003e0){const o=this.fragmentedPaths.length-1;if(o\u003e=0){const i=this.fragmentedPaths[o];i.isFragmentedPath\u0026\u0026this.drawPath({path:i,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]),o=this.nodeMap.get(e.nodeIds[1]);n\u0026\u0026o\u0026\u0026t.push({points:[n.center,o.center],strokeColor:\"orange\",strokeWidth:.15,strokeDasharray:\"0.3,0.15\"})}let o=\"Offboard Path Fragment Solver\";return\"showing_original_path\"===this.animationState?o+=\" - Analyzing path...\":\"showing_fragment\"===this.animationState?o+=` - Fragment ${this.currentFragmentIndex}/${this.currentFragments.length}`:o+=` - Done (${this.fragmentedPaths.filter(t=\u003et.isFragmentedPath).length} fragments)`,{lines:t,points:e,rects:n,title:o}}drawPath(t){const{path:e,color:n,lines:o,points:i,rects:r,labelPrefix:s}=t,a=[];for(let t=0;t\u003ce.nodeIds.length;t++){const o=e.nodeIds[t],c=this.nodeMap.get(o);c\u0026\u0026(a.push(c.center),r.push({center:c.center,width:.8*c.width,height:.8*c.height,stroke:n,strokeWidth:.05,fill:`${n}33`}),0!==t\u0026\u0026t!==e.nodeIds.length-1||i.push({x:c.center.x,y:c.center.y,color:n,label:`${s}${e.connectionName}\\n${o}`}))}a.length\u003e1\u0026\u0026o.push({points:a,strokeColor:n,strokeWidth:.1})}};function cnt(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var lnt=class extends si{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,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),r=n.targetMinCapacity??.5;n.capacityDepth=$s(i,r)}this.connMap=ii(t),this.colorMap=wo(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;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=[cnt(\"netToPointPairsSolver\",ma,t=\u003e[t.srj,t.colorMap,ri(t.srj)],{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,this.connMap),t.connMap=ii(t.srjWithPointPairs)}}),cnt(\"nodeSolver\",Ket,t=\u003e[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=\u003e{t.capacityNodes=t.nodeSolver?.finishedNodes}}),cnt(\"mergeAssignableViaNodes\",ent,t=\u003e[t.nodeSolver?.finishedNodes],{onSolved:t=\u003e{t.capacityNodes=t.mergeAssignableViaNodes?.newNodes}}),cnt(\"singleLayerNodeMerger\",tnt,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),cnt(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),cnt(\"offboardCapacityNodeSolver\",snt,t=\u003e[{capacityNodes:t.capacityNodes,capacityEdges:t.capacityEdges||[]}],{onSolved:t=\u003e{t.capacityEdges=t.offboardCapacityNodeSolver?.enhancedEdges||t.capacityEdges}}),cnt(\"deadEndSolver\",Qc,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges}],{onSolved:t=\u003e{const e=t.deadEndSolver?.removedNodeIds;t.capacityNodes=t.capacityNodes.filter(t=\u003e!e.has(t.capacityMeshNodeId)),t.capacityEdges=t.capacityEdges.filter(t=\u003et.nodeIds.every(t=\u003e!e.has(t)))}}),cnt(\"initialPathingHyperSolver\",ont,t=\u003e[{simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,hyperParameters:{MAX_CAPACITY_FACTOR:1}}],{onSolved:t=\u003e{const e=t.initialPathingHyperSolver?.winningSolver;e\u0026\u0026(t.initialPathingSolver=e)}}),cnt(\"offboardPathFragmentSolver\",ant,t=\u003e[{capacityPaths:t.initialPathingSolver?.getCapacityPaths()||[],capacityEdges:t.capacityEdges||[],capacityNodes:t.capacityNodes||[],connections:t.srjWithPointPairs?.connections||[]}],{onSolved:t=\u003e{const e=t.offboardPathFragmentSolver;if(!e)return;const n=e.getFragmentedPaths();for(const e of n)if(e.isFragmentedPath\u0026\u0026e.mstPairConnectionName){const n=t.colorMap[e.mstPairConnectionName];n\u0026\u0026!t.colorMap[e.connectionName]\u0026\u0026(t.colorMap[e.connectionName]=n)}const o=e.getFragmentedOriginalConnectionNames(),i=e.getFragmentedConnections();o.size\u003e0\u0026\u0026t.srjWithPointPairs\u0026\u0026(t.srjWithPointPairs={...t.srjWithPointPairs,connections:[...t.srjWithPointPairs.connections.filter(t=\u003e!o.has(t.name)),...i]},t.connMap=ii(t.srjWithPointPairs))}}),cnt(\"edgeToPortSegmentSolver\",Nc,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.offboardPathFragmentSolver?.getFragmentedPaths()||t.initialPathingSolver?.getCapacityPaths()||[],colorMap:t.colorMap}]),cnt(\"segmentToPointSolver\",Lc,t=\u003e{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments\u0026\u0026t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=\u003e{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),cnt(\"unravelMultiSectionSolver\",gl,t=\u003e[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),cnt(\"highDensityRouteSolver\",zs,t=\u003e[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap}]),cnt(\"highDensityStitchSolver\",Ca,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),cnt(\"uselessViaRemovalSolver1\",Xa,t=\u003e[{unsimplifiedHdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount,connMap:t.connMap}]),cnt(\"multiSimplifiedPathSolver1\",Za,t=\u003e[{unsimplifiedHdRoutes:t.uselessViaRemovalSolver1?.getOptimizedHdRoutes()||t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline}]),cnt(\"uselessViaRemovalSolver2\",Xa,t=\u003e[{unsimplifiedHdRoutes:t.multiSimplifiedPathSolver1.simplifiedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount,connMap:t.connMap}]),cnt(\"multiSimplifiedPathSolver2\",Za,t=\u003e[{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\u0026\u0026(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\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),o=this.mergeAssignableViaNodes?.visualize(),i=this.singleLayerNodeMerger?.visualize(),r=this.strawSolver?.visualize(),s=this.edgeSolver?.visualize(),a=(this.offboardCapacityNodeSolver?.visualize(),this.deadEndSolver?.visualize()),c=this.initialPathingSolver?.visualize(),l=this.offboardPathFragmentSolver?.visualize(),d=this.pathingOptimizer?.visualize(),h=this.edgeToPortSegmentSolver?.visualize(),u=this.segmentToPointSolver?.visualize(),p=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),m=this.highDensityRouteSolver?.visualize(),g=this.highDensityStitchSolver?.visualize(),f=this.uselessViaRemovalSolver1?.visualize(),y=this.uselessViaRemovalSolver2?.visualize(),_=this.multiSimplifiedPathSolver1?.visualize(),b=this.multiSimplifiedPathSolver2?.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\u0026\u0026x.length\u003e=2){const t=x.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const S=Oo(this.srj),I={points:[...this.srj.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,this.srj.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(this.srj.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,this.srj.layerCount),label:S(t)}))],lines:v},C=[I,t,e,n,o,i,r,s,a,c,l,d,h,u,p,m?pi(I,m):null,g,f,_,y,b,this.solved?pi({lines:v},Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...C)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}if(this.pathingOptimizer){const t=[];for(const e of this.pathingOptimizer.connectionsWithNodes)e.path\u0026\u0026t.push({points:e.path.map(t=\u003e({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 o of n){const n=o.__netConnectionName,i=o.__rootConnectionNames?.[0],r=e.filter(t=\u003et.connectionName===o.name);for(let e=0;e\u003cr.length;e++){const s=r[e],a={type:\"pcb_trace\",pcb_trace_id:`${o.name}_${e}`,connection_name:n??i??o.name,route:Mo(s,this.srj.layerCount)};t.push(a)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},dnt=1e-9,hnt=t=\u003e(t=\u003e\"wire\"===t.route_type)(t)||(t=\u003e\"via\"===t.route_type)(t)?t:(t=\u003e\"through_obstacle\"===t.route_type)(t)\u0026\u0026Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y)\u003c=dnt?{route_type:t.route_type,x:t.start.x,y:t.start.y,from_layer:t.from_layer,to_layer:t.to_layer,width:t.width}:null,unt=(t,e)=\u003et.layer??e.layer??t.to_layer??e.from_layer??t.from_layer??e.to_layer??\"top\",pnt=(t,e,n)=\u003et.width??e.width??n,mnt=(t,e,n,o,i)=\u003e({x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n,layer:o,width:i}),gnt=(t,e)=\u003e({...t,x:Math.abs(t.x-e.minX)\u003c1e-6?e.minX:Math.abs(t.x-e.maxX)\u003c1e-6?e.maxX:t.x,y:Math.abs(t.y-e.minY)\u003c1e-6?e.minY:Math.abs(t.y-e.maxY)\u003c1e-6?e.maxY:t.y}),fnt=({x:t,y:e,layer:n})=\u003e({x:t,y:e,layer:n}),ynt=({x:t,y:e,layer:n,width:o})=\u003e({route_type:\"wire\",x:t,y:e,layer:n,width:o}),_nt=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;let r=0,s=1;const a=(t,e)=\u003e{if(Math.abs(t)\u003cdnt)return e\u003e=0;const n=e/t;if(t\u003c0){if(n\u003es)return!1;n\u003er\u0026\u0026(r=n)}else{if(n\u003cr)return!1;n\u003cs\u0026\u0026(s=n)}return!0};return a(-o,t.x-n.minX)\u0026\u0026a(o,n.maxX-t.x)\u0026\u0026a(-i,t.y-n.minY)\u0026\u0026a(i,n.maxY-t.y)?{startT:r,endT:s}:null},bnt=(t,e)=\u003et.x\u003e=e.minX-1e-6\u0026\u0026t.x\u003c=e.maxX+1e-6\u0026\u0026t.y\u003e=e.minY-1e-6\u0026\u0026t.y\u003c=e.maxY+1e-6\u0026\u0026(Math.abs(t.x-e.minX)\u003c=1e-6||Math.abs(t.x-e.maxX)\u003c=1e-6||Math.abs(t.y-e.minY)\u003c=1e-6||Math.abs(t.y-e.maxY)\u003c=1e-6),xnt=(t,e,n,o,i)=\u003e{var r,s;(r=o,s=i,Math.hypot(r.x-s.x,r.y-s.y)\u003c=dnt)||t.push({type:\"pcb_trace\",pcb_trace_id:`${e.pcb_trace_id}_keep_${n}`,connection_name:e.connection_name,route:[ynt(o),ynt(i)]})},vnt=({obstacleId:t,start:e,end:n,layer:o,width:i})=\u003e{const r=n.x-e.x,s=n.y-e.y,a=Math.hypot(r,s);return a\u003ei+dnt?null:{obstacleId:t,type:\"rect\",layers:[o],center:{x:(e.x+n.x)/2,y:(e.y+n.y)/2},width:a,height:i,ccwRotationDegrees:180*Math.atan2(s,r)/Math.PI,connectedTo:[]}},Snt=({connection:t,point:e,endpointIndex:n})=\u003e({obstacleId:`${t.name}_route_endpoint_${n}`,type:\"rect\",layers:[e.layer],center:{x:e.x,y:e.y},width:e.width,height:e.width,connectedTo:[t.name,t.__rootConnectionNames?.[0]??t.name]}),Int=({trace:t,ripIndex:e,start:n,end:o,region:i,allowInteriorStart:r,allowInteriorEnd:s})=\u003e{if(!r\u0026\u0026!bnt(n,i)||!s\u0026\u0026!bnt(o,i))return null;const a=(({trace:t,ripIndex:e,start:n,end:o})=\u003e({name:`${t.connection_name}_reroute_${t.pcb_trace_id}_${e}`,__rootConnectionNames:[t.connection_name],pointsToConnect:[fnt(n),fnt(o)]}))({trace:t,ripIndex:e,start:n,end:o});return{connection:a,endpointObstacles:[Snt({connection:a,point:n,endpointIndex:0}),Snt({connection:a,point:o,endpointIndex:1})]}},Cnt=(t,e,n)=\u003e{const o=[],i=[],r=[],s=[];let a=null,c=!1,l=0,d=!1;for(let h=0;h\u003ct.route.length-1;h++){const u=hnt(t.route[h]),p=hnt(t.route[h+1]);if(!u||!p)return null;const m=unt(u,p),g=pnt(u,p,n),f=_nt(u,p,e),y=mnt(u,p,0,m,g),_=mnt(u,p,1,m,g),b=0===h;if(!f){xnt(o,t,l++,y,_);continue}if(d=!0,f.startT\u003ednt){const e=mnt(u,p,f.startT,m,g),n=vnt({obstacleId:`${t.pcb_trace_id}_keep_${l}_bounds`,start:y,end:e,layer:m,width:g});n\u0026\u0026s.push(n),xnt(o,t,l++,y,e)}const x=mnt(u,p,f.endT,m,g),v=gnt(mnt(u,p,f.startT,m,g),e),S=gnt(mnt(u,p,f.endT,m,g),e);if(a||(a=v,c=b\u0026\u0026f.startT\u003c=dnt),f.endT\u003c.999999999){const n=Int({trace:t,ripIndex:i.length,start:a,end:S,region:e,allowInteriorStart:c});n\u0026\u0026(i.push(n.connection),r.push(...n.endpointObstacles)),a=null,c=!1;const d=vnt({obstacleId:`${t.pcb_trace_id}_keep_${l}_bounds`,start:x,end:_,layer:m,width:g});d\u0026\u0026s.push(d),xnt(o,t,l++,x,_)}}if(a){const n=t.route.slice().reverse().map(hnt).find(t=\u003eBoolean(t));if(n){const o=Int({trace:t,ripIndex:i.length,start:a,end:{x:n.x,y:n.y,layer:n.layer??n.from_layer??a.layer,width:a.width},region:e,allowInteriorStart:c,allowInteriorEnd:!0});o\u0026\u0026(i.push(o.connection),r.push(...o.endpointObstacles))}}return{keptTraces:o,rerouteConnections:i,rerouteEndpointObstacles:r,clippedTraceSegmentObstacles:s,hadIntersection:d}},Pnt=(t,e)=\u003e{const n=structuredClone(t),o=[],i=[],r=[],s=[];for(const n of t.traces??[]){const a=Cnt(n,e,t.minTraceWidth);a?a.hadIntersection?(o.push(...a.keptTraces),i.push(...a.rerouteConnections),r.push(...a.rerouteEndpointObstacles),s.push(...a.clippedTraceSegmentObstacles)):o.push(structuredClone(n)):o.push(structuredClone(n))}const a=((t,e)=\u003e{const n={minX:t.minX,maxX:t.maxX,minY:t.minY,maxY:t.maxY};for(const t of e){const e=Ee(t);n.minX=Math.min(n.minX,e.minX),n.maxX=Math.max(n.maxX,e.maxX),n.minY=Math.min(n.minY,e.minY),n.maxY=Math.max(n.maxY,e.maxY)}return n})(e,[...r,...s]);return{...n,bounds:a,obstacles:[...n.obstacles,...r],traces:o,connections:i}},Mnt=(t,e)=\u003e{const n=new Map(e.connections.map(t=\u003e[t.name,t.__rootConnectionNames?.[0]??t.name])),o=(e.traces??[]).map(t=\u003e{const e=n.get(t.connection_name);return e?{...structuredClone(t),connection_name:e}:structuredClone(t)});return{...structuredClone(t),traces:o,jumpers:e.jumpers?structuredClone(e.jumpers):structuredClone(t.jumpers)}},Nnt=(t,e,n=[])=\u003e[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join(\"\\n\"),wnt=1.8,Tnt=.95,Rnt=.8,Ent=.95,Ant=class extends si{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;regionId;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.regionId=t.regionId,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=xe(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\u0026\u0026this.existingJumpers.push(...t.jumpers);const n=Math.ceil(5*(this.numRoutes+1));let o=this.boundsSize.width/this.cellStep,i=this.boundsSize.height/this.cellStep;for(;o*i\u003en**2\u0026\u0026!(this.cellStep\u003et.minDistBetweenEnteringPoints);)this.cellStep*=2,o=this.boundsSize.width/this.cellStep,i=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR;const r=Math.abs(this.A.x-this.bounds.minX)\u003c.001\u0026\u0026Math.abs(this.B.x-this.bounds.minX)\u003c.001||Math.abs(this.A.x-this.bounds.maxX)\u003c.001\u0026\u0026Math.abs(this.B.x-this.bounds.maxX)\u003c.001||Math.abs(this.A.y-this.bounds.minY)\u003c.001\u0026\u0026Math.abs(this.B.y-this.bounds.minY)\u003c.001||Math.abs(this.A.y-this.bounds.maxY)\u003c.001\u0026\u0026Math.abs(this.B.y-this.bounds.maxY)\u003c.001;this.futureConnections\u0026\u00260===this.futureConnections.length\u0026\u00260===this.obstacleRoutes.length\u0026\u0026!r\u0026\u0026this.handleSimpleCases();const s={x:t.A.x,y:t.A.y};this.initialNodeGridOffset={x:s.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:s.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 Wi([{...t.A,...s,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,regionId:this.regionId,route:[{x:t.x,y:t.y,z:0},{x:e.x,y:e.y,z:0}],traceThickness:this.traceThickness,jumpers:[]}}get jumperPenaltyDistance(){return wnt+this.straightLineDistance*this.JUMPER_PENALTY_FACTOR}isNodeTooCloseToObstacle(t,e){e??=this.obstacleMargin;for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){const o=Ont(n);for(const n of o)if(be(t,n.A,n.B)\u003cthis.traceThickness+e)return!0}for(const o of n.jumpers||[])if(this.isNodeTooCloseToJumper(t,o,e))return!0}return!1}isNodeTooCloseToJumper(t,e,n){const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=Math.abs(o)\u003eMath.abs(i),s=(r?Rnt:Ent)/2+n,a=(r?Ent:Rnt)/2+n;return Math.abs(t.x-e.start.x)\u003cs\u0026\u0026Math.abs(t.y-e.start.y)\u003ca||Math.abs(t.x-e.end.x)\u003cs\u0026\u0026Math.abs(t.y-e.end.y)\u003ca}isNodeTooCloseToEdge(t){const e=t.gComponents?.distFromStart??0\u003cthis.obstacleMargin/2?-this.obstacleMargin/2:this.obstacleMargin/2,n=t.x\u003cthis.bounds.minX+e||t.x\u003ethis.bounds.maxX-e||t.y\u003cthis.bounds.minY+e||t.y\u003ethis.bounds.maxY-e;return(!n||!(xe(t,this.B)\u003c2*e||xe(t,this.A)\u003c2*e))\u0026\u0026n}doesPathToParentIntersectObstacle(t){const e=t.parent;if(!e)return!1;for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){for(const o of Ont(n))if(fe(t,e,o.A,o.B))return!0;for(const o of n.jumpers||[])if(this.doesSegmentIntersectJumperPads(t,e,o))return!0}}return!1}doesSegmentIntersectJumperPads(t,e,n){const o=this.obstacleMargin,i=n.end.x-n.start.x,r=n.end.y-n.start.y,s=Math.abs(i)\u003eMath.abs(r),a=(s?Rnt:Ent)/2+o,c=(s?Ent:Rnt)/2+o;return!!this.doesSegmentIntersectRect(t,e,n.start,a,c)||!!this.doesSegmentIntersectRect(t,e,n.end,a,c)}doesSegmentIntersectRect(t,e,n,o,i){const r=n.x-o,s=n.x+o,a=n.y-i,c=n.y+i;if(t.x\u003e=r\u0026\u0026t.x\u003c=s\u0026\u0026t.y\u003e=a\u0026\u0026t.y\u003c=c)return!0;if(e.x\u003e=r\u0026\u0026e.x\u003c=s\u0026\u0026e.y\u003e=a\u0026\u0026e.y\u003c=c)return!0;const l=[{A:{x:r,y:a},B:{x:s,y:a}},{A:{x:s,y:a},B:{x:s,y:c}},{A:{x:s,y:c},B:{x:r,y:c}},{A:{x:r,y:c},B:{x:r,y:a}}];for(const n of l)if(fe(t,e,n.A,n.B))return!0;return!1}findObstaclesBetween(t,e){const n=[];for(const o of this.obstacleRoutes){const i=this.connMap?.areIdsConnected?.(this.connectionName,o.connectionName);if(!i)for(const i of Ont(o))fe(t,e,i.A,i.B)\u0026\u0026n.push({A:i.A,B:i.B})}return n}computeHComponents(t){const e=xe(t,this.roundedGoalPosition),n=this.getObstacleProximityPenalty(t),o=this.getEdgeProximityPenalty(t),i=this.getFutureConnectionStartEndPenalty(t),r=this.getFutureConnectionLinePenalty(t),s=t.parent,a=s?.hComponents,c=s?xe(t,s):0,l=(t,n)=\u003e{if(void 0===n||c\u003c1e-9||e\u003c1e-9)return t;const o=(t-n)/c;return(t+Math.max(0,t+o*e))/2},d=l(n,a?.obstacleProximityRate),h=l(o,a?.edgeProximityRate),u=l(i,a?.futureConnectionStartEndProximityRate),p=l(r,a?.futureConnectionLineRate),m=d*e,g=h*e,f=u*e,y=p*e;return{distanceToGoal:e,obstacleProximity:m,edgeProximity:g,futureConnectionStartEndProximityPenalty:f,futureConnectionLine:y,total:e+m+g+f+y,obstacleProximityRate:n,edgeProximityRate:o,futureConnectionStartEndProximityRate:i,futureConnectionLineRate:r}}computeH(t){return this.computeHComponents(t).total}computeGComponents(t){const e=t.parent,n=e?xe(t,e):0,o=e?.gComponents??{distFromStart:0,weightedMmNearObstacle:0,weightedMmNearEdge:0,weightedMmNearFutureConnectionStartEnd:0,weightedMmNearFutureConnectionLine:0,jumperPenalty:0,jumperPadFutureConnectionPenalty:0,total:0},i=o.distFromStart+n,r=o.weightedMmNearObstacle+this.getObstacleProximityPenalty(t)*n,s=o.weightedMmNearEdge+this.getEdgeProximityPenalty(t)*n,a=o.weightedMmNearFutureConnectionStartEnd+this.getFutureConnectionStartEndPenalty(t)*n,c=o.weightedMmNearFutureConnectionLine+this.getFutureConnectionLinePenalty(t)*n;let l=o.jumperPenalty,d=o.jumperPadFutureConnectionPenalty;t.isJumperExit\u0026\u0026(l+=this.jumperPenaltyDistance,d+=this.getJumperPadFutureConnectionPenalty(t));return{distFromStart:i,weightedMmNearObstacle:r,weightedMmNearEdge:s,weightedMmNearFutureConnectionStartEnd:a,weightedMmNearFutureConnectionLine:c,jumperPenalty:l,jumperPadFutureConnectionPenalty:d,total:i+r+s+a+c+l+d}}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 o of this.futureConnections)for(const i of o.points){const o=xe(t,i);o\u003ce\u0026\u0026(e=o,n=i)}return n}getFutureConnectionStartEndPenalty(t){let e=0;const n=this.getClosestFutureConnectionPoint(t);if(n){const o=xe(t,n);if(o\u003ethis.FUTURE_CONNECTION_START_END_PROXIMITY)return 0;const i=o/this.FUTURE_CONNECTION_START_END_PROXIMITY;e=this.FUTURE_CONNECTION_START_END_PENALTY*(1-i)**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\u003c2)continue;const o=be(t,n.points[0],n.points[n.points.length-1]);e=Math.min(e,o)}if(e*=n,e\u003cthis.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 o=1/0;for(const t of this.futureConnections)for(const i of t.points){const t=xe(e,i),r=xe(n,i),s=Math.min(t,r);o=Math.min(o,s)}if(o\u003cthis.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY){const t=o/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 o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){for(const o of Ont(n))e=Math.min(e,be(t,o.A,o.B));for(const o of n.jumpers||[])e=Math.min(e,this.distanceToJumperPads(t,o))}}return e}distanceToJumperPads(t,e){const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.abs(n)\u003eMath.abs(o),r=(i?Rnt:Ent)/2,s=(i?Ent:Rnt)/2;return Math.min(this.pointToRectDistance(t,e.start,r,s),this.pointToRectDistance(t,e.end,r,s))}pointToRectDistance(t,e,n,o){const i=Math.max(Math.abs(t.x-e.x)-n,0),r=Math.max(Math.abs(t.y-e.y)-o,0);return Math.hypot(i,r)}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)),o=this.OBSTACLE_PROX_SIGMA;return this.OBSTACLE_PROX_PENALTY_FACTOR*Math.exp(-n/o)}getEdgeProximityPenalty(t){const e=this.getClearanceToEdge(t),n=this.EDGE_PROX_SIGMA;if(e\u003e2*this.EDGE_PROX_SIGMA)return 0;const o=xe(t,this.B),i=Math.min(1,o/(2*this.EDGE_PROX_SIGMA));return this.EDGE_PROX_PENALTY_FACTOR*Math.exp(-e/n)*i}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)\u003cthis.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 o of n){const n=2*wnt,i=t.x+o.dx*n,r=t.y+o.dy*n,s=this.findObstaclesBetween(t,{x:i,y:r});if(s.length\u003e0)for(const n of s){const i=this.calculateJumperExit(t,n,o);i\u0026\u0026!this.exploredNodes.has(this.getNodeKey(i))\u0026\u0026(this.isNodeTooCloseToObstacle(i)||this.isNodeTooCloseToEdge(i)||!this.isJumperPlacementValid(t,i)||(i.gComponents=this.computeGComponents(i),i.hComponents=this.computeHComponents(i),i.g=i.gComponents.total,i.h=i.hComponents.total,i.f=this.computeF(i.g,i.h),e.push(i)))}}return e}calculateJumperExit(t,e,n){const o=wnt,i=Math.sqrt(n.dx*n.dx+n.dy*n.dy),r=n.dx/i,s=n.dy/i,a=t.x+r*o,c=t.y+s*o;return a\u003cthis.bounds.minX||a\u003ethis.bounds.maxX||c\u003cthis.bounds.minY||c\u003ethis.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,o=e.y-t.y,i=Math.abs(n)\u003eMath.abs(o),r=(i?Rnt:Ent)/2,s=(i?Ent:Rnt)/2,a=this.obstacleMargin,c=[t,e];for(const t of c){const e=[t,{x:t.x-r,y:t.y-s},{x:t.x+r,y:t.y-s},{x:t.x-r,y:t.y+s},{x:t.x+r,y:t.y+s},{x:t.x-r,y:t.y},{x:t.x+r,y:t.y},{x:t.x,y:t.y-s},{x:t.x,y:t.y+s}];for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(o)continue;const i=Ont(n);for(const n of i){for(const t of e)if(be(t,n.A,n.B)\u003cthis.traceThickness+a)return!0;if(this.doesSegmentIntersectRect(n.A,n.B,t,r+a,s+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 o=this.getJumpersInPath(t);for(const t of o)if(this.doJumpersOverlap(n,t))return!1;return!0}doJumpersOverlap(t,e){const n=this.obstacleMargin,o=Math.min(t.start.x,t.end.x)-Tnt/2-n,i=Math.max(t.start.x,t.end.x)+Tnt/2+n,r=Math.min(t.start.y,t.end.y)-Tnt/2-n,s=Math.max(t.start.y,t.end.y)+Tnt/2+n,a=Math.min(e.start.x,e.end.x)-Tnt/2-n,c=Math.max(e.start.x,e.end.x)+Tnt/2+n,l=Math.min(e.start.y,e.end.y)-Tnt/2-n,d=Math.max(e.start.y,e.end.y)+Tnt/2+n;return!(i\u003ca||o\u003ec||s\u003cl||r\u003ed)}getJumpersInPath(t){const e=[];let n=t;for(;n\u0026\u0026n.parent;)n.isJumperExit\u0026\u0026n.jumperEntry\u0026\u0026e.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:o,maxY:i,minY:r}=this.bounds;for(let s=-1;s\u003c=1;s++)for(let a=-1;a\u003c=1;a++){if(0===s\u0026\u00260===a)continue;if(!this.ALLOW_DIAGONAL\u0026\u00260!==s\u0026\u00260!==a)continue;const c=t.x+s*this.cellStep,l=t.y+a*this.cellStep,d=knt(c,o,n),h=knt(l,r,i),u={...t,parent:t,x:d,y:h,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 s=this.getJumperNeighbors(t);return e.push(...s),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\u003ce.length;t++){const o=e[t];o.isJumperExit\u0026\u0026o.jumperEntry\u0026\u0026n.push({route_type:\"jumper\",start:o.jumperEntry,end:{x:o.x,y:o.y},footprint:\"0603\"})}this.solvedPath={connectionName:this.connectionName,rootConnectionName:this.rootConnectionName,regionId:this.regionId,traceThickness:this.traceThickness,route:e.map(t=\u003e({x:t.x,y:t.y,z:0})).concat([{x:this.B.x,y:this.B.y,z:0}]),jumpers:n}}computeProgress(t,e){if(void 0===e)return Number.NaN;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\u0026\u0026e\u0026\u0026this.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=xe(t,this.roundedGoalPosition);this.progress=this.computeProgress(t,n),n\u003c=this.cellStep*Math.SQRT2\u0026\u0026!this.doesPathToParentIntersectObstacle({...t,parent:t,x:this.B.x,y:this.B.y})\u0026\u0026(this.solved=!0,this.setSolvedPath(t));const o=this.getNeighbors(t);for(const t of o)this.candidates.enqueue(t)}drawJumperPads(t,e,n,o,i,r){const s=e.end.x-e.start.x,a=e.end.y-e.start.y,c=Rnt,l=Ent,d=Math.abs(s)\u003eMath.abs(a),h=d?c:l,u=d?l:c;t.rects.push({center:{x:e.start.x,y:e.start.y},width:h,height:u,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:o??\"jumper\",step:i,label:r}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:h,height:u,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:o??\"jumper\",step:i,label:r}),t.lines.push({points:[e.start,e.end],strokeColor:\"rgba(100, 100, 100, 0.8)\",strokeWidth:.3*l,layer:o??\"jumper-body\",step:i,label:r})}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:Nnt(this.connectionName,this.rootConnectionName,[\"Input A\",`z: ${this.A.z}`]),color:\"orange\"}),t.points.push({x:this.B.x,y:this.B.y,label:Nnt(this.connectionName,this.rootConnectionName,[\"Input B\",`z: ${this.B.z}`]),color:\"orange\"}),t.lines.push({points:[this.A,this.B],strokeColor:\"rgba(255, 0, 0, 0.5)\",label:Nnt(this.connectionName,this.rootConnectionName,[\"Direct Input Connection\"])});for(let e=0;e\u003cthis.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let o=0;o\u003cn.route.length-1;o++)t.lines.push({points:[n.route[o],n.route[o+1]],strokeColor:\"rgba(255, 0, 0, 0.75)\",strokeWidth:n.traceThickness,label:Nnt(n.connectionName,n.rootConnectionName,[\"Obstacle Route\"]),layer:`obstacle${e.toString()}`});for(const o of n.jumpers||[])this.drawJumperPads(t,o,\"rgba(255, 0, 0, 0.5)\",`obstacle-jumper-${e}`,void 0,Nnt(n.connectionName,n.rootConnectionName,[\"Obstacle Jumper\"]))}for(let e=0;e\u003cthis.futureConnections.length;e++){const n=this.futureConnections[e];if(n.points.length\u003c2)continue;const o=n.points[0],i=n.points[n.points.length-1];t.lines.push({points:[o,i],strokeColor:\"rgba(0, 100, 255, 0.6)\",strokeWidth:this.traceThickness,label:Nnt(n.connectionName,n.rootConnectionName,[\"Future\"]),layer:`future-connection-${e}`})}for(let e=0;e\u003cthis.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[o,i]=n.split(\",\").map(Number),r=n.endsWith(\"_j\"),s=this.debug_exploredNodeValues.get(n),a=s?.gComponents,c=s?.hComponents,l=c?.distanceToGoal??0,d=[r?\"Explored (jumper)\":\"Explored\"];d.push(`g.distFromStart: ${a?.distFromStart.toFixed(2)??\"?\"}`),d.push(`g.nearObstacle: ${a?.weightedMmNearObstacle.toFixed(2)??\"?\"}`),d.push(`g.nearEdge: ${a?.weightedMmNearEdge.toFixed(2)??\"?\"}`),d.push(`g.nearFutStrtEnd: ${a?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??\"?\"}`),d.push(`g.nearFutLine: ${a?.weightedMmNearFutureConnectionLine.toFixed(2)??\"?\"}`),d.push(`g.jumper: ${a?.jumperPenalty.toFixed(2)??\"?\"}`),d.push(`g.jumperPadFutPenalty: ${a?.jumperPadFutureConnectionPenalty.toFixed(2)??\"?\"}`),d.push(`h.goalDist: ${l.toFixed(2)}`),d.push(`h.obstacleProx: ${c?.obstacleProximity.toFixed(2)??\"?\"} (${l\u003e0?((c?.obstacleProximity??0)/l).toFixed(3):0}/mm)`),d.push(`h.edgeProx: ${c?.edgeProximity.toFixed(2)??\"?\"} (${l\u003e0?((c?.edgeProximity??0)/l).toFixed(3):0}/mm)`),d.push(`h.futureConnPt: ${c?.futureConnectionStartEndProximityPenalty.toFixed(2)??\"?\"} (${l\u003e0?((c?.futureConnectionStartEndProximityPenalty??0)/l).toFixed(3):0}/mm)`),d.push(`h.futureConnLine: ${c?.futureConnectionLine.toFixed(2)??\"?\"} (${l\u003e0?((c?.futureConnectionLine??0)/l).toFixed(3):0}/mm)`),d.push(`g: ${s?.g.toFixed(2)??\"?\"}`),d.push(`h: ${s?.h.toFixed(2)??\"?\"}`),d.push(`f: ${s?.f.toFixed(2)??\"?\"}`);const h=d.join(\"\\n\");t.rects.push({center:{x:o+this.initialNodeGridOffset.x,y:i+this.initialNodeGridOffset.y},fill:r?`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:h})}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\u003ce.length;n++){const o=e[n],i=o.isJumperExit??!1,r=o.gComponents,s=o.hComponents,a=s?.distanceToGoal??0,c=[`Candidate #${n+1}${i?\" (jumper)\":\"\"}`];c.push(`g.distFromStart: ${r?.distFromStart.toFixed(2)??\"?\"}`),c.push(`g.nearObstacle: ${r?.weightedMmNearObstacle.toFixed(2)??\"?\"}`),c.push(`g.nearEdge: ${r?.weightedMmNearEdge.toFixed(2)??\"?\"}`),c.push(`g.nearFutureConnPt: ${r?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??\"?\"}`),c.push(`g.nearFutureConnLine: ${r?.weightedMmNearFutureConnectionLine.toFixed(2)??\"?\"}`),c.push(`g.jumper: ${r?.jumperPenalty.toFixed(2)??\"?\"}`),c.push(`g.jumperPadFutureConn: ${r?.jumperPadFutureConnectionPenalty.toFixed(2)??\"?\"}`),c.push(`g: ${o.g.toFixed(2)}`),c.push(`h.goalDist: ${a.toFixed(2)}`),c.push(`h.obstacleProx: ${s?.obstacleProximity.toFixed(2)??\"?\"} (${a\u003e0?((s?.obstacleProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.edgeProx: ${s?.edgeProximity.toFixed(2)??\"?\"} (${a\u003e0?((s?.edgeProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnPt: ${s?.futureConnectionStartEndProximityPenalty.toFixed(2)??\"?\"} (${a\u003e0?((s?.futureConnectionStartEndProximityPenalty??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnLine: ${s?.futureConnectionLine.toFixed(2)??\"?\"} (${a\u003e0?((s?.futureConnectionLine??0)/a).toFixed(3):0}/mm)`),c.push(`h: ${o.h.toFixed(2)}`),c.push(`f: ${o.f.toFixed(2)}`);const l=c.join(\"\\n\");t.points.push({x:o.x,y:o.y,color:\"gray\",label:l})}if(this.solvedPath){t.lines.push({points:this.solvedPath.route,strokeColor:\"green\",label:Nnt(this.solvedPath.connectionName,this.solvedPath.rootConnectionName,[\"Solved Route\"]),strokeWidth:this.traceThickness});for(const e of this.solvedPath.jumpers)this.drawJumperPads(t,e,\"rgba(0, 200, 0, 0.8)\",\"solved-jumper\",void 0,Nnt(this.solvedPath.connectionName,this.solvedPath.rootConnectionName,[\"Solved Jumper\"]))}const{minX:n,minY:o,maxX:i,maxY:r}=this.bounds;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:r},{x:n,y:r},{x:n,y:o}],strokeColor:\"rgba(255, 0, 0, 0.25)\",strokeDash:\"4 4\",layer:\"border\"}),t}};function Ont(t){const e=[];for(let n=0;n\u003ct.route.length-1;n++)if(t.route[n].z===t.route[n+1].z){const o=t.route[n],i=t.route[n+1],r=t.jumpers?.some(t=\u003e{const e=Math.abs(t.start.x-o.x)\u003c.001\u0026\u0026Math.abs(t.start.y-o.y)\u003c.001\u0026\u0026Math.abs(t.end.x-i.x)\u003c.001\u0026\u0026Math.abs(t.end.y-i.y)\u003c.001,n=Math.abs(t.start.x-i.x)\u003c.001\u0026\u0026Math.abs(t.start.y-i.y)\u003c.001\u0026\u0026Math.abs(t.end.x-o.x)\u003c.001\u0026\u0026Math.abs(t.end.y-o.y)\u003c.001;return e||n});r||e.push({z:o.z,A:o,B:i})}return e}function knt(t,e,n){return Math.max(e,Math.min(t,n))}var Lnt=.8,Dnt=.95,znt=(t,e,n=[])=\u003e[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join(\"\\n\"),Fnt=class extends si{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 o=new Map;for(const t of e.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}this.unsolvedConnections=[];for(const[t,e]of o){const n=Dr(e);for(const[e,o]of n)this.unsolvedConnections.push({connectionName:t,rootConnectionName:e.rootConnectionName??o.rootConnectionName,points:[{x:e.x,y:e.y,z:0},{x:o.x,y:o.y,z:0}]});if(0===n.length\u0026\u00261===e.length){const[n]=e;this.unsolvedConnections.push({connectionName:t,rootConnectionName:n?.rootConnectionName,points:n?[{x:n.x,y:n.y,z:0}]:[]})}}this.hyperParameters.SHUFFLE_SEED\u0026\u0026(this.unsolvedConnections=Xi(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=\u003e({...e,points:Xi(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Vi(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\u0026\u0026(this.failedSubSolvers.push(this.activeSubSolver),this.lastActiveSubSolver=this.activeSubSolver,this.activeSubSolver=null,this.error=this.failedSubSolvers.map(t=\u003et.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,o=Math.abs(e.x-n.x)\u003c1e-6,i=Math.abs(e.y-n.y)\u003c1e-6;if(o\u0026\u0026i)return}const{connectionName:e,rootConnectionName:n,points:o}=t;this.activeSubSolver=new Ant({connectionName:e,rootConnectionName:n,regionId:this.nodeWithPortPoints.capacityMeshNodeId,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:ro(this.nodeWithPortPoints),A:{x:o[0].x,y:o[0].y,z:0},B:{x:o[o.length-1].x,y:o[o.length-1].y,z:0},obstacleRoutes:this.solvedRoutes.filter(t=\u003e(!n||t.rootConnectionName!==n)\u0026\u0026!this.connMap?.areIdsConnected(t.connectionName,e)),futureConnections:this.unsolvedConnections,hyperParameters:this.hyperParameters,connMap:this.connMap,traceThickness:this.traceWidth})}drawJumperPads(t,e,n,o,i){const r=e.end.x-e.start.x,s=e.end.y-e.start.y,a=Lnt,c=Dnt,l=Math.abs(r)\u003eMath.abs(s),d=l?a:c,h=l?c:a;t.rects.push({center:{x:e.start.x,y:e.start.y},width:d,height:h,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:\"jumper\",label:i}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:d,height:h,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:\"jumper\",label:i}),t.lines.push({points:[e.start,e.end],strokeColor:\"rgba(100, 100, 100, 0.8)\",strokeWidth:.3*c,layer:\"jumper-body\",label:i})}visualize(){if(this.activeSubSolver\u0026\u0026!this.solved)return this.activeSubSolver.visualize();if(this.failed\u0026\u0026this.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:znt(e.connectionName,e.rootConnectionName,[\"layer: 0 (single-layer)\"]),color:this.colorMap[e.connectionName]??\"blue\"});for(let e=0;e\u003cthis.solvedRoutes.length;e++){const n=this.solvedRoutes[e];if(n.route.length\u003e0){const o=this.colorMap[n.connectionName]??\"blue\";for(let e=0;e\u003cn.route.length-1;e++){const i=n.route[e],r=n.route[e+1];t.lines.push({points:[i,r],strokeColor:To(o,.2),layer:\"route-layer-0\",strokeWidth:n.traceThickness,label:znt(n.connectionName,n.rootConnectionName,[\"layer: 0\"])})}for(const i of n.jumpers)this.drawJumperPads(t,i,To(o,.5),e,znt(n.connectionName,n.rootConnectionName,[\"jumper\"]))}}const e=ro(this.nodeWithPortPoints),{minX:n,minY:o,maxX:i,maxY:r}=e;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:r},{x:n,y:r},{x:n,y:o}],strokeColor:\"rgba(255, 0, 0, 0.25)\",strokeDash:\"4 4\",layer:\"border\"}),t}},Bnt=Ss;export{G9 as AUTOROUTER_VERSION,lnt as AssignableAutoroutingPipeline1Solver,Wl as AssignableAutoroutingPipeline2,ef as AssignableAutoroutingPipeline3,JX as AttachProjectedRectsSolver,yl as AutoroutingPipeline1_OriginalUnravel,rK as AutoroutingPipelineSolver,Bet as AutoroutingPipelineSolver10_BgaFanout,Jet as AutoroutingPipelineSolver11_Simplification,Pc as AutoroutingPipelineSolver2_PortPointPathing,Nf as AutoroutingPipelineSolver3_HgPortPointPathing,xX as AutoroutingPipelineSolver4,xX as AutoroutingPipelineSolver4_TinyHypergraph,EX as AutoroutingPipelineSolver5,EX as AutoroutingPipelineSolver5_HdCache,rG as AutoroutingPipelineSolver6,rG as AutoroutingPipelineSolver6_PolyHypergraph,rK as AutoroutingPipelineSolver7_MultiGraph,lK as AutoroutingPipelineSolver8,y8 as AutoroutingPipelineSolver9_Networked,H9 as AutoroutingPipelineSolver9_PreloadedTraceGraph,Mc as CapacityMeshSolver,Pd as CurvyIntraNodeSolver,n8 as DEFAULT_HD_CACHE2_SERVER_URL,wz as GlobalDrcBranchPortfolioSolver,Nz as GlobalDrcForceImproveSolver,Ls as GrowShrinkHighDensityIntraNodeSolver,Qg as HighDensitySolver,Bnt as HyperSingleIntraNodeSolver,Qn as InMemoryCache,Fnt as IntraNodeSolverWithJumpers,eo as LocalStorageCache,g8 as PIPELINE9_NETWORKED_SOLVE_POLICY,QX as PolyHighDensitySolver,KX as PolyIntraNodeSolver,KX as PolySingleIntraNodeSolver,Ss as PortfolioSingleIntraNodeSolver,oG as ProjectHighDensityToPolygonSolver,Ant as SingleHighDensityRouteWithJumpersSolver,$s as calculateOptimalCapacityDepth,Ho as convertSrjToGraphicsObject,oo as getGlobalInMemoryCache,no as getGlobalLocalStorageCache,Pnt as getRerouteSimpleRouteJson,js as getTunedTotalCapacity1,Mnt as reconnectReroutedSimpleRouteJsonRegion,io as setupGlobalCaches,_8 as solvePipeline9NetworkedHighDensityNode};\n/*! Bundled license information:\n\nis-buffer/index.js:\n (*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh \u003chttps://feross.org\u003e\n * @license MIT\n *)\n\ndeep-rename-keys/index.js:\n (*!\n * deep-rename-keys \u003chttps://github.com/jonschlinkert/deep-rename-keys\u003e\n *\n * Copyright (c) 2015 Jon Schlinkert, contributors.\n * Licensed under the MIT license.\n *)\n\n@tscircuit/curvy-trace-solver/dist/index.js:\n@tscircuit/find-convex-regions/dist/index.js:\n (*! Bundled license information:\n \n is-buffer/index.js:\n (*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh \u003chttps://feross.org\u003e\n * @license MIT\n *)\n \n deep-rename-keys/index.js:\n (*!\n * deep-rename-keys \u003chttps://github.com/jonschlinkert/deep-rename-keys\u003e\n *\n * Copyright (c) 2015 Jon Schlinkert, contributors.\n * Licensed under the MIT license.\n *)\n *)\n\n@tscircuit/hypergraph/dist/index.js:\n (*! Bundled license information:\n \n @tscircuit/find-convex-regions/dist/index.js:\n (*! Bundled license information:\n \n is-buffer/index.js:\n (*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh \u003chttps://feross.org\u003e\n * @license MIT\n *)\n \n deep-rename-keys/index.js:\n (*!\n * deep-rename-keys \u003chttps://github.com/jonschlinkert/deep-rename-keys\u003e\n *\n * Copyright (c) 2015 Jon Schlinkert, contributors.\n * Licensed under the MIT license.\n *)\n *)\n *)\n*///# sourceMappingURL=index.js.map","content_mimetype":"text/javascript","created_at":"2026-09-08T16:51:04.318Z"}; window.SSR_PACKAGE_RELEASES = [{"package_release_id":"dadcc3e3-2713-4e98-887f-4b6137bd5354","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.21","github_commit_sha":null,"is_locked":false,"is_latest":true,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-09-08T16:51:00.213Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-c972a675127a917f4275e6ed2e8d118e","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=dadcc3e3-2713-4e98-887f-4b6137bd5354\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=dadcc3e3-2713-4e98-887f-4b6137bd5354\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=dadcc3e3-2713-4e98-887f-4b6137bd5354\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"87ce88af-6ebc-4d18-8566-4157e21ea81e","user_code_job_started_at":"2026-09-08T16:52:33.622Z","user_code_job_completed_at":"2026-09-08T16:59:59.297Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=d6b4ee33048d45c49f3c2aa07288211b524699d6de79c1297a7ac825a214cef2","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"1bd43346-33f3-4cde-bfc0-0d0f5ef7be46","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.20","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-09-08T15:16:56.192Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-d11498066a18b91f14cfef35200ce692","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1bd43346-33f3-4cde-bfc0-0d0f5ef7be46\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1bd43346-33f3-4cde-bfc0-0d0f5ef7be46\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1bd43346-33f3-4cde-bfc0-0d0f5ef7be46\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"25ade5eb-73d1-47ce-9823-5f98374536ec","user_code_job_started_at":"2026-09-08T15:18:02.030Z","user_code_job_completed_at":"2026-09-08T15:25:40.398Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=89a479e0fa012d7b67eda0b76d5ebc3715268e252699e7ddd07a3464689ff513","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8c74453a-83e2-4172-bcda-666d01f22b9f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.19","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-09-08T15:06:14.644Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-d91e0490b469149ed15fbb1a51ebd6c4","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"1eb0a04c-ecf7-497e-af22-0e9b9527afed","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.18","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-09-08T14:59:07.818Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-d29c5c93da4790e226795ec61a311545","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"310748ea-1f54-4e0b-bcb0-e26de0418bbe","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.17","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-20T09:08:27.021Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-3ab68ad76231274fced8daa9b4d216d1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"31871f8c-83e2-47f0-968e-30522688d9b6","user_code_job_started_at":"2026-09-07T20:49:28.128Z","user_code_job_completed_at":"2026-09-07T21:05:41.129Z","user_code_job_error":{"message":"Your code failed to build (exit code 1), see build logs for the error details","error_code":"user_code_build_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=295f4c032a00680940217b249f3b3f4fc21ade71a404fb9d8dd81770696f8397","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"de03c299-1b05-400b-9a9e-29d42c16b2bc","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.16","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-17T16:56:08.078Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-d8dbda73d7ae6158f52f028821fc56ee","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"3bf37cdc-0107-4eac-9892-f247c5e18661","user_code_job_started_at":"2026-08-17T16:58:40.245Z","user_code_job_completed_at":"2026-08-17T17:28:41.191Z","user_code_job_error":{"message":"Build timed out after 30 minutes","error_code":"user_code_job_timeout"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=76d319070ca1fa7f302a7515628d2639daeeecb6a5981c696f85e46107e3b9b9","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"0e701bc3-f617-464c-b79c-8117d2c86339","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.15","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-12T16:15:42.323Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-1d696f35b011352aeb71a3a73b619442","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0e701bc3-f617-464c-b79c-8117d2c86339\u0026file_path=dist%2Fleft%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0e701bc3-f617-464c-b79c-8117d2c86339\u0026file_path=dist%2Fleft%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0e701bc3-f617-464c-b79c-8117d2c86339\u0026file_path=dist%2Fleft%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"b70c43ef-2eed-47b4-b330-04f89859db6a","user_code_job_started_at":"2026-08-12T19:18:18.738Z","user_code_job_completed_at":"2026-08-12T19:28:03.200Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=12aa44a3f0616a1a15b3a1b0b9f58c05bbb5a610306d691dd1254f2acd6c484b","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"051bc4bf-1895-4c06-848e-06f0dca2393d","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.14","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-12T15:57:48.194Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-0c5e9892ec1ff3b912eed0a8c52f86d6","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"27e8a9f6-e7eb-447a-8734-0d94020b0275","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.13","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-12T15:50:05.533Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-9c0370a7e35c6d29e28e2ecfd1a35f0d","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"09680cad-cb3a-43bc-b3d9-3977d56d794c","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.12","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-12T15:44:02.661Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-5db3a4d5fec54b23a1879189c3ae3cbb","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"9800209a-d5a4-4a4b-940a-d0269c8f63b6","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.11","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-11T15:04:42.562Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-566054e353ef8fe7b66172bc2fae98b0","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9800209a-d5a4-4a4b-940a-d0269c8f63b6\u0026file_path=dist%2Fleft%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9800209a-d5a4-4a4b-940a-d0269c8f63b6\u0026file_path=dist%2Fleft%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9800209a-d5a4-4a4b-940a-d0269c8f63b6\u0026file_path=dist%2Fleft%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"30a6cf6d-8331-40a2-88c1-c288ec518721","user_code_job_started_at":"2026-08-12T06:03:29.394Z","user_code_job_completed_at":"2026-08-12T06:05:35.547Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=9786155159a44073aca7f275639c5bba8096798efe9ea7bbec0ac5bff5dbbff4","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"dfee26ad-0833-46ab-80ba-c79f11c42204","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.10","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-11T15:00:53.088Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-3323412296cadec0032dc46d61871214","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"ab72b3d5-3b6f-492c-97d2-683e46ee727f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.9","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-10T12:08:14.180Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-c3f01b7ce05c51934f420bc6f5a6bef2","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ab72b3d5-3b6f-492c-97d2-683e46ee727f\u0026file_path=dist%2Fleft%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ab72b3d5-3b6f-492c-97d2-683e46ee727f\u0026file_path=dist%2Fleft%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ab72b3d5-3b6f-492c-97d2-683e46ee727f\u0026file_path=dist%2Fleft%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"a09c97ff-fc3a-43f6-adb6-fdecc09ac5a4","user_code_job_started_at":"2026-08-10T12:14:11.619Z","user_code_job_completed_at":"2026-08-10T12:22:41.299Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=bd272eacf6b19c9d8bca9ff7025a50289e8cc5dcce91b374d4398239f9b8fdc6","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"aab741d2-66d6-4141-a56f-dec9a93f0745","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.8","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T12:05:54.107Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":null,"circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8d099371-81f4-4556-9b50-06c5ff43530c","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.7","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T12:01:26.302Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-90b8b592fc532bc050dfa0051f22721d","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"b5644906-1850-4f7e-bc7f-384131bc85d5","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.6","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T11:57:22.892Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-645c7d3e9b78aedbd409f63ea760ff03","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"bf68f755-3410-47ae-a8f7-bf1842ede84f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.5","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-10T10:36:56.206Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-fae103c87d843cdbb7d5853edd5e00a1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"62b3be01-12c5-415f-af59-2eb8cd87f0a2","user_code_job_started_at":"2026-08-10T10:39:53.625Z","user_code_job_completed_at":"2026-08-10T10:46:01.744Z","user_code_job_error":{"message":"Your code failed to build (exit code 1), see build logs for the error details","error_code":"user_code_build_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=5b7af5faf2794cb43b7c2ef0edf4af78aee1d8f2cbf54dc1148ababea99e1991","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"12026e15-765c-488a-9886-a89e93409099","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.4","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T10:32:18.439Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-640370fe7412c50c2a81985dc4c85ea1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"49831c5f-ff27-4706-b8d9-7a0fe1662179","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.3","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T10:28:40.595Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-abd2412878570b9cbce9d060b8e64f90","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"2bbe2022-8ce9-4466-bce4-9d3460eb7620","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T10:24:34.733Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-0c6ef3495ed62c8311da6c2a4a5ce1f1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"511d059e-9f7c-4d44-b609-44cd623b4972","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-09T20:30:50.584Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-932b3b7914f4275cc095769b0f588268","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"af3b8d2e-6b0e-4354-9c73-14b62b65bd8d","user_code_job_started_at":"2026-08-10T09:05:50.472Z","user_code_job_completed_at":"2026-08-10T09:11:56.569Z","user_code_job_error":{"message":"Your code failed to build (exit code 1), see build logs for the error details","error_code":"user_code_build_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=858f0f5564ef737003bbfa6e781aeca055df3ed980065067ac7a494d91462263","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"0c2b43a3-54ff-41cc-9c2a-3c072a4bfce4","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-09T20:27:15.716Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-09c3251b45a913a702805e1ecccbb7b5","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"6243441b-092b-4166-b003-a232a9cb59ff","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.3","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-06T14:45:44.407Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-f8665c2de359b48d96d3d32c1ca7d0f8","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"3fcb8ef5-0e39-440c-a18f-1c682ef1e73d","user_code_job_started_at":"2026-08-06T14:45:50.004Z","user_code_job_completed_at":"2026-08-06T14:49:33.535Z","user_code_job_error":{"message":"There was an error running the job on our infrastructure, this is probably not your code, see build logs","error_code":"user_code_job_infrastructure_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=cbd18a5931f35b3cf6d4679c66ba2eeffba4e991283dff69751626b4d0c8bd62","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8c27b90d-b11f-403c-8691-41f218374a8f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-06T13:40:38.469Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-e220e519e921d21de687f0af4239252c","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"ea20fb0d-e807-43f9-ba83-8978b2a9cd04","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-06T13:38:39.968Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-234591a7f9c087d813fd8d5ecbda0d46","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ea20fb0d-e807-43f9-ba83-8978b2a9cd04\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ea20fb0d-e807-43f9-ba83-8978b2a9cd04\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ea20fb0d-e807-43f9-ba83-8978b2a9cd04\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"5155b2ea-d7ed-41fc-80c6-d6311b4b55b4","user_code_job_started_at":"2026-08-06T13:38:48.763Z","user_code_job_completed_at":"2026-08-06T13:40:21.516Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=2d9c8a936d46c3ed4f25c54515d1eb4ff16872ade7b430062b7a024bd40f6dee","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-06T13:15:02.283Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-1def03398d147a237eb937a952295e79","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"97b18410-03ef-4231-98d7-89ecd9b787a4","user_code_job_started_at":"2026-08-06T13:15:08.904Z","user_code_job_completed_at":"2026-08-06T13:16:24.373Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=279a064e6ac1ab57ef793fb8ad3a32d71e6b5262e3dd6104e362a8d55c2f7b68","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null}]; window.SSR_PACKAGE_BUILDS = []; window.SSR_RELATED_PACKAGES = [{"package_id":"307fe261-5d71-417c-bc01-7835cd4f4abe","creator_account_id":"96f144ef-7dfe-4068-aac0-8753c8ab5f62","latest_package_release_id":"3c938c18-451d-4aea-8ecc-b5e5f561e6c6","last_built_release_id":"3c938c18-451d-4aea-8ecc-b5e5f561e6c6","latest_package_release_fs_sha":"md5-d17042528d94ca0759bc1345f41464bb","latest_pcb_preview_image_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.2","license":"unset","owner_org_id":"f46c84e5-2ffb-44f6-a4fa-47ad19769e7a","org_owner_tscircuit_handle":"test-1","owner_github_username":"test-1","github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"imrishabh18/boost-converter","unscoped_name":"boost-converter","star_count":0,"created_at":"2026-05-18T12:43:26.451Z","updated_at":"2026-05-19T18:52:38.681Z","ai_description":"This code defines a PCB schematic and 3D model layout focusing on a power conversion circuit with components like USB-C connector, MT3608 step-up regulator, inductor, diode, input/output capacitors, and resistors arranged on a double-layer PCB.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"same_author","thumbnail_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2Fpcb.svg"},{"package_id":"1bb71080-c9d9-4806-8dad-9546e8b9913b","creator_account_id":"03854e77-22c2-44a0-9cfc-2d4ed6741105","latest_package_release_id":"92d10956-aa95-4eba-8e98-42e66c16f463","last_built_release_id":"92d10956-aa95-4eba-8e98-42e66c16f463","latest_package_release_fs_sha":"md5-73c7349eef4667e7cbc7beecb7e35036","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.5","license":"unset","owner_org_id":"7978967e-b956-4ac2-b813-667a08f6310a","org_owner_tscircuit_handle":"abse","owner_github_username":null,"github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"abse/boostxl-uln2003","unscoped_name":"boostxl-uln2003","star_count":0,"created_at":"2026-08-12T10:10:06.978Z","updated_at":"2026-08-12T22:29:23.783Z","ai_description":"This code defines a React component that models a through-hole or surface-mount LED with specified pin labels, footprint, silkscreen, and 3D CAD model for PCB layout.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"similar_ai_description","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2Fpcb.svg"},{"package_id":"7065b9a6-03de-43a1-ba42-2a0ead33b548","creator_account_id":"1f745cb8-1b99-4215-905f-f8e3dc29bc28","latest_package_release_id":"5746ef1e-d91a-4043-9db3-2cc17f89d777","last_built_release_id":"5746ef1e-d91a-4043-9db3-2cc17f89d777","latest_package_release_fs_sha":"md5-27fc15676f25d1e3a229466d1de0fe7a","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.1","license":"unset","owner_org_id":"60917f07-d371-4c51-854f-e2bd7dab9e5a","org_owner_tscircuit_handle":"hrithik18k","owner_github_username":null,"github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"hrithik18k/smart-switch-pcb","unscoped_name":"smart-switch-pcb","star_count":0,"created_at":"2026-09-09T11:12:10.428Z","updated_at":"2026-09-09T11:56:59.112Z","ai_description":"The AO3400A component models a SOT-23 N-channel MOSFET with labeled pins for Gate, Source, and Drain, including 3D CAD models and schematic symbols for electronic circuit design.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"random","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fpcb.svg"}]; window.SSR_PACKAGE_ROUTE = {"author":"imrishabh18","packageName":"corne-keyboard","packageNameWithScope":"imrishabh18/corne-keyboard","version":null,"isLegacyRoute":false,"kind":"file","filePath":"debug-autorouter.mjs"};
);function Cb(t){let e="[0-5]\\d";t.precision?e=`${e}\\.\\d{${t.precision}}`:null==t.precision&&(e=`${e}(\\.\\d+)?`);return`([01]\\d|2[0-3]):[0-5]\\d(:${e})${t.precision?"+":"?"}`}function Pb(t){return new RegExp(`^${Cb(t)}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
),{});a(k_,{BRAND:()=\u003emx,DIRTY:()=\u003eJ_,EMPTY_PATH:()=\u003eW_,INVALID:()=\u003eq_,NEVER:()=\u003ecv,OK:()=\u003eK_,ParseStatus:()=\u003eZ_,Schema:()=\u003eab,ZodAny:()=\u003eBb,ZodArray:()=\u003eXb,ZodBigInt:()=\u003eOb,ZodBoolean:()=\u003ekb,ZodBranded:()=\u003egx,ZodCatch:()=\u003eux,ZodDate:()=\u003eLb,ZodDefault:()=\u003ehx,ZodDiscriminatedUnion:()=\u003eUb,ZodEffects:()=\u003ecx,ZodEnum:()=\u003erx,ZodError:()=\u003eB_,ZodFirstPartyTypeKind:()=\u003exx,ZodFunction:()=\u003eex,ZodIntersection:()=\u003eqb,ZodIssueCode:()=\u003ez_,ZodLazy:()=\u003enx,ZodLiteral:()=\u003eox,ZodMap:()=\u003eQb,ZodNaN:()=\u003epx,ZodNativeEnum:()=\u003esx,ZodNever:()=\u003e$b,ZodNull:()=\u003eFb,ZodNullable:()=\u003edx,ZodNumber:()=\u003eAb,ZodObject:()=\u003eWb,ZodOptional:()=\u003elx,ZodParsedType:()=\u003eL_,ZodPipeline:()=\u003efx,ZodPromise:()=\u003eax,ZodReadonly:()=\u003eyx,ZodRecord:()=\u003eKb,ZodSchema:()=\u003eab,ZodSet:()=\u003etx,ZodString:()=\u003eRb,ZodSymbol:()=\u003eDb,ZodTransformer:()=\u003ecx,ZodTuple:()=\u003eJb,ZodType:()=\u003eab,ZodUndefined:()=\u003ezb,ZodUnion:()=\u003eHb,ZodUnknown:()=\u003ejb,ZodVoid:()=\u003eYb,addIssueToContext:()=\u003eH_,any:()=\u003eOx,array:()=\u003ezx,bigint:()=\u003eNx,boolean:()=\u003ewx,coerce:()=\u003eav,custom:()=\u003ebx,date:()=\u003eTx,datetimeRegex:()=\u003eMb,defaultErrorMap:()=\u003ej_,discriminatedUnion:()=\u003e$x,effect:()=\u003eQx,enum:()=\u003eqx,function:()=\u003eGx,getErrorMap:()=\u003eX_,getParsedType:()=\u003eD_,instanceof:()=\u003eIx,intersection:()=\u003eYx,isAborted:()=\u003eQ_,isAsync:()=\u003enb,isDirty:()=\u003etb,isValid:()=\u003eeb,late:()=\u003eSx,lazy:()=\u003eUx,literal:()=\u003eZx,makeIssue:()=\u003eV_,map:()=\u003eWx,nan:()=\u003eMx,nativeEnum:()=\u003eJx,never:()=\u003eLx,null:()=\u003eAx,nullable:()=\u003eev,number:()=\u003ePx,object:()=\u003eFx,objectUtil:()=\u003eA_,oboolean:()=\u003esv,onumber:()=\u003erv,optional:()=\u003etv,ostring:()=\u003eiv,pipeline:()=\u003eov,preprocess:()=\u003env,promise:()=\u003eKx,quotelessJson:()=\u003eF_,record:()=\u003eVx,set:()=\u003eHx,setErrorMap:()=\u003eY_,strictObject:()=\u003eBx,string:()=\u003eCx,symbol:()=\u003eRx,transformer:()=\u003eQx,tuple:()=\u003eXx,undefined:()=\u003eEx,union:()=\u003ejx,unknown:()=\u003ekx,util:()=\u003eR_,void:()=\u003eDx}),(E_=R_||(R_={})).assertEqual=t=\u003e{},E_.assertIs=function(t){},E_.assertNever=function(t){throw new Error},E_.arrayToEnum=t=\u003e{const e={};for(const n of t)e[n]=n;return e},E_.getValidEnumValues=t=\u003e{const e=E_.objectKeys(t).filter(e=\u003e\"number\"!=typeof t[t[e]]),n={};for(const o of e)n[o]=t[o];return E_.objectValues(n)},E_.objectValues=t=\u003eE_.objectKeys(t).map(function(e){return t[e]}),E_.objectKeys=\"function\"==typeof Object.keys?t=\u003eObject.keys(t):t=\u003e{const e=[];for(const n in t)Object.prototype.hasOwnProperty.call(t,n)\u0026\u0026e.push(n);return e},E_.find=(t,e)=\u003e{for(const n of t)if(e(n))return n},E_.isInteger=\"function\"==typeof Number.isInteger?t=\u003eNumber.isInteger(t):t=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)\u0026\u0026Math.floor(t)===t,E_.joinValues=function(t,e=\" | \"){return t.map(t=\u003e\"string\"==typeof t?`'${t}'`:t).join(e)},E_.jsonStringifyReplacer=(t,e)=\u003e\"bigint\"==typeof e?e.toString():e,(A_||(A_={})).mergeShapes=(t,e)=\u003e({...t,...e});var L_=R_.arrayToEnum([\"string\",\"nan\",\"number\",\"integer\",\"float\",\"boolean\",\"date\",\"bigint\",\"symbol\",\"function\",\"undefined\",\"null\",\"array\",\"object\",\"unknown\",\"promise\",\"void\",\"never\",\"map\",\"set\"]),D_=t=\u003e{switch(typeof t){case\"undefined\":return L_.undefined;case\"string\":return L_.string;case\"number\":return Number.isNaN(t)?L_.nan:L_.number;case\"boolean\":return L_.boolean;case\"function\":return L_.function;case\"bigint\":return L_.bigint;case\"symbol\":return L_.symbol;case\"object\":return Array.isArray(t)?L_.array:null===t?L_.null:t.then\u0026\u0026\"function\"==typeof t.then\u0026\u0026t.catch\u0026\u0026\"function\"==typeof t.catch?L_.promise:\"undefined\"!=typeof Map\u0026\u0026t instanceof Map?L_.map:\"undefined\"!=typeof Set\u0026\u0026t instanceof Set?L_.set:\"undefined\"!=typeof Date\u0026\u0026t instanceof Date?L_.date:L_.object;default:return L_.unknown}},z_=R_.arrayToEnum([\"invalid_type\",\"invalid_literal\",\"custom\",\"invalid_union\",\"invalid_union_discriminator\",\"invalid_enum_value\",\"unrecognized_keys\",\"invalid_arguments\",\"invalid_return_type\",\"invalid_date\",\"invalid_string\",\"too_small\",\"too_big\",\"invalid_intersection_types\",\"not_multiple_of\",\"not_finite\"]),F_=t=\u003eJSON.stringify(t,null,2).replace(/\"([^\"]+)\":/g,\"$1:\"),B_=class t extends Error{get errors(){return this.issues}constructor(t){super(),this.issues=[],this.addIssue=t=\u003e{this.issues=[...this.issues,t]},this.addIssues=(t=[])=\u003e{this.issues=[...this.issues,...t]};const e=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,e):this.__proto__=e,this.name=\"ZodError\",this.issues=t}format(t){const e=t||function(t){return t.message},n={_errors:[]},o=t=\u003e{for(const i of t.issues)if(\"invalid_union\"===i.code)i.unionErrors.map(o);else if(\"invalid_return_type\"===i.code)o(i.returnTypeError);else if(\"invalid_arguments\"===i.code)o(i.argumentsError);else if(0===i.path.length)n._errors.push(e(i));else{let t=n,o=0;for(;o\u003ci.path.length;){const n=i.path[o];o===i.path.length-1?(t[n]=t[n]||{_errors:[]},t[n]._errors.push(e(i))):t[n]=t[n]||{_errors:[]},t=t[n],o++}}};return o(this),n}static assert(e){if(!(e instanceof t))throw new Error(`Not a ZodError: ${e}`)}toString(){return this.message}get message(){return JSON.stringify(this.issues,R_.jsonStringifyReplacer,2)}get isEmpty(){return 0===this.issues.length}flatten(t=t=\u003et.message){const e={},n=[];for(const o of this.issues)if(o.path.length\u003e0){const n=o.path[0];e[n]=e[n]||[],e[n].push(t(o))}else n.push(t(o));return{formErrors:n,fieldErrors:e}}get formErrors(){return this.flatten()}};B_.create=t=\u003enew B_(t);var j_=(t,e)=\u003e{let n;switch(t.code){case z_.invalid_type:n=t.received===L_.undefined?\"Required\":`Expected ${t.expected}, received ${t.received}`;break;case z_.invalid_literal:n=`Invalid literal value, expected ${JSON.stringify(t.expected,R_.jsonStringifyReplacer)}`;break;case z_.unrecognized_keys:n=`Unrecognized key(s) in object: ${R_.joinValues(t.keys,\", \")}`;break;case z_.invalid_union:n=\"Invalid input\";break;case z_.invalid_union_discriminator:n=`Invalid discriminator value. Expected ${R_.joinValues(t.options)}`;break;case z_.invalid_enum_value:n=`Invalid enum value. Expected ${R_.joinValues(t.options)}, received '${t.received}'`;break;case z_.invalid_arguments:n=\"Invalid function arguments\";break;case z_.invalid_return_type:n=\"Invalid function return type\";break;case z_.invalid_date:n=\"Invalid date\";break;case z_.invalid_string:\"object\"==typeof t.validation?\"includes\"in t.validation?(n=`Invalid input: must include \"${t.validation.includes}\"`,\"number\"==typeof t.validation.position\u0026\u0026(n=`${n} at one or more positions greater than or equal to ${t.validation.position}`)):\"startsWith\"in t.validation?n=`Invalid input: must start with \"${t.validation.startsWith}\"`:\"endsWith\"in t.validation?n=`Invalid input: must end with \"${t.validation.endsWith}\"`:R_.assertNever(t.validation):n=\"regex\"!==t.validation?`Invalid ${t.validation}`:\"Invalid\";break;case z_.too_small:n=\"array\"===t.type?`Array must contain ${t.exact?\"exactly\":t.inclusive?\"at least\":\"more than\"} ${t.minimum} element(s)`:\"string\"===t.type?`String must contain ${t.exact?\"exactly\":t.inclusive?\"at least\":\"over\"} ${t.minimum} character(s)`:\"number\"===t.type||\"bigint\"===t.type?`Number must be ${t.exact?\"exactly equal to \":t.inclusive?\"greater than or equal to \":\"greater than \"}${t.minimum}`:\"date\"===t.type?`Date must be ${t.exact?\"exactly equal to \":t.inclusive?\"greater than or equal to \":\"greater than \"}${new Date(Number(t.minimum))}`:\"Invalid input\";break;case z_.too_big:n=\"array\"===t.type?`Array must contain ${t.exact?\"exactly\":t.inclusive?\"at most\":\"less than\"} ${t.maximum} element(s)`:\"string\"===t.type?`String must contain ${t.exact?\"exactly\":t.inclusive?\"at most\":\"under\"} ${t.maximum} character(s)`:\"number\"===t.type?`Number must be ${t.exact?\"exactly\":t.inclusive?\"less than or equal to\":\"less than\"} ${t.maximum}`:\"bigint\"===t.type?`BigInt must be ${t.exact?\"exactly\":t.inclusive?\"less than or equal to\":\"less than\"} ${t.maximum}`:\"date\"===t.type?`Date must be ${t.exact?\"exactly\":t.inclusive?\"smaller than or equal to\":\"smaller than\"} ${new Date(Number(t.maximum))}`:\"Invalid input\";break;case z_.custom:n=\"Invalid input\";break;case z_.invalid_intersection_types:n=\"Intersection results could not be merged\";break;case z_.not_multiple_of:n=`Number must be a multiple of ${t.multipleOf}`;break;case z_.not_finite:n=\"Number must be finite\";break;default:n=e.defaultError,R_.assertNever(t)}return{message:n}},$_=j_;function Y_(t){$_=t}function X_(){return $_}var V_=t=\u003e{const{data:e,path:n,errorMaps:o,issueData:i}=t,r=[...n,...i.path||[]],s={...i,path:r};if(void 0!==i.message)return{...i,path:r,message:i.message};let a=\"\";const c=o.filter(t=\u003e!!t).slice().reverse();for(const t of c)a=t(s,{data:e,defaultError:a}).message;return{...i,path:r,message:a}},W_=[];function H_(t,e){const n=X_(),o=V_({issueData:e,data:t.data,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,n,n===j_?void 0:j_].filter(t=\u003e!!t)});t.common.issues.push(o)}var G_,U_,Z_=class t{constructor(){this.value=\"valid\"}dirty(){\"valid\"===this.value\u0026\u0026(this.value=\"dirty\")}abort(){\"aborted\"!==this.value\u0026\u0026(this.value=\"aborted\")}static mergeArray(t,e){const n=[];for(const o of e){if(\"aborted\"===o.status)return q_;\"dirty\"===o.status\u0026\u0026t.dirty(),n.push(o.value)}return{status:t.value,value:n}}static async mergeObjectAsync(e,n){const o=[];for(const t of n){const e=await t.key,n=await t.value;o.push({key:e,value:n})}return t.mergeObjectSync(e,o)}static mergeObjectSync(t,e){const n={};for(const o of e){const{key:e,value:i}=o;if(\"aborted\"===e.status)return q_;if(\"aborted\"===i.status)return q_;\"dirty\"===e.status\u0026\u0026t.dirty(),\"dirty\"===i.status\u0026\u0026t.dirty(),\"__proto__\"===e.value||void 0===i.value\u0026\u0026!o.alwaysSet||(n[e.value]=i.value)}return{status:t.value,value:n}}},q_=Object.freeze({status:\"aborted\"}),J_=t=\u003e({status:\"dirty\",value:t}),K_=t=\u003e({status:\"valid\",value:t}),Q_=t=\u003e\"aborted\"===t.status,tb=t=\u003e\"dirty\"===t.status,eb=t=\u003e\"valid\"===t.status,nb=t=\u003e\"undefined\"!=typeof Promise\u0026\u0026t instanceof Promise;(U_=G_||(G_={})).errToObj=t=\u003e\"string\"==typeof t?{message:t}:t||{},U_.toString=t=\u003e\"string\"==typeof t?t:t?.message;var ob=class{constructor(t,e,n,o){this._cachedPath=[],this.parent=t,this.data=e,this._path=n,this._key=o}get path(){return this._cachedPath.length||(Array.isArray(this._key)?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}},ib=(t,e)=\u003e{if(eb(e))return{success:!0,data:e.value};if(!t.common.issues.length)throw new Error(\"Validation failed but no issues detected.\");return{success:!1,get error(){if(this._error)return this._error;const e=new B_(t.common.issues);return this._error=e,this._error}}};function rb(t){if(!t)return{};const{errorMap:e,invalid_type_error:n,required_error:o,description:i}=t;if(e\u0026\u0026(n||o))throw new Error('Can\\'t use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.');if(e)return{errorMap:e,description:i};return{errorMap:(e,i)=\u003e{const{message:r}=t;return\"invalid_enum_value\"===e.code?{message:r??i.defaultError}:void 0===i.data?{message:r??o??i.defaultError}:\"invalid_type\"!==e.code?{message:i.defaultError}:{message:r??n??i.defaultError}},description:i}}var sb,ab=class{get description(){return this._def.description}_getType(t){return D_(t.data)}_getOrReturnCtx(t,e){return e||{common:t.parent.common,data:t.data,parsedType:D_(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}_processInputParams(t){return{status:new Z_,ctx:{common:t.parent.common,data:t.data,parsedType:D_(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}}_parseSync(t){const e=this._parse(t);if(nb(e))throw new Error(\"Synchronous parse encountered promise.\");return e}_parseAsync(t){const e=this._parse(t);return Promise.resolve(e)}parse(t,e){const n=this.safeParse(t,e);if(n.success)return n.data;throw n.error}safeParse(t,e){const n={common:{issues:[],async:e?.async??!1,contextualErrorMap:e?.errorMap},path:e?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)},o=this._parseSync({data:t,path:n.path,parent:n});return ib(n,o)}\"~validate\"(t){const e={common:{issues:[],async:!!this[\"~standard\"].async},path:[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)};if(!this[\"~standard\"].async)try{const n=this._parseSync({data:t,path:[],parent:e});return eb(n)?{value:n.value}:{issues:e.common.issues}}catch(t){t?.message?.toLowerCase()?.includes(\"encountered\")\u0026\u0026(this[\"~standard\"].async=!0),e.common={issues:[],async:!0}}return this._parseAsync({data:t,path:[],parent:e}).then(t=\u003eeb(t)?{value:t.value}:{issues:e.common.issues})}async parseAsync(t,e){const n=await this.safeParseAsync(t,e);if(n.success)return n.data;throw n.error}async safeParseAsync(t,e){const n={common:{issues:[],contextualErrorMap:e?.errorMap,async:!0},path:e?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)},o=this._parse({data:t,path:n.path,parent:n}),i=await(nb(o)?o:Promise.resolve(o));return ib(n,i)}refine(t,e){const n=t=\u003e\"string\"==typeof e||void 0===e?{message:e}:\"function\"==typeof e?e(t):e;return this._refinement((e,o)=\u003e{const i=t(e),r=()=\u003eo.addIssue({code:z_.custom,...n(e)});return\"undefined\"!=typeof Promise\u0026\u0026i instanceof Promise?i.then(t=\u003e!!t||(r(),!1)):!!i||(r(),!1)})}refinement(t,e){return this._refinement((n,o)=\u003e!!t(n)||(o.addIssue(\"function\"==typeof e?e(n,o):e),!1))}_refinement(t){return new cx({schema:this,typeName:xx.ZodEffects,effect:{type:\"refinement\",refinement:t}})}superRefine(t){return this._refinement(t)}constructor(t){this.spa=this.safeParseAsync,this._def=t,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this),this[\"~standard\"]={version:1,vendor:\"zod\",validate:t=\u003ethis[\"~validate\"](t)}}optional(){return lx.create(this,this._def)}nullable(){return dx.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return Xb.create(this)}promise(){return ax.create(this,this._def)}or(t){return Hb.create([this,t],this._def)}and(t){return qb.create(this,t,this._def)}transform(t){return new cx({...rb(this._def),schema:this,typeName:xx.ZodEffects,effect:{type:\"transform\",transform:t}})}default(t){const e=\"function\"==typeof t?t:()=\u003et;return new hx({...rb(this._def),innerType:this,defaultValue:e,typeName:xx.ZodDefault})}brand(){return new gx({typeName:xx.ZodBranded,type:this,...rb(this._def)})}catch(t){const e=\"function\"==typeof t?t:()=\u003et;return new ux({...rb(this._def),innerType:this,catchValue:e,typeName:xx.ZodCatch})}describe(t){return new(0,this.constructor)({...this._def,description:t})}pipe(t){return fx.create(this,t)}readonly(){return yx.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}},cb=/^c[^\\s-]{8,}$/i,lb=/^[0-9a-z]+$/,db=/^[0-9A-HJKMNP-TV-Z]{26}$/i,hb=/^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i,ub=/^[a-z0-9_-]{21}$/i,pb=/^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$/,mb=/^[-+]?P(?!$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??$/,gb=/^(?!\\.)(?!.*\\.\\.)([A-Z0-9_'+\\-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i,fb=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,yb=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/(3[0-2]|[12]?[0-9])$/,_b=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,bb=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,xb=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,vb=/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,Sb=\"((\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\\\d|30)|(02)-(0[1-9]|1\\\\d|2[0-8])))\",Ib=new RegExp(`^${Sb}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
);function Cb(t){let e=\"[0-5]\\\\d\";t.precision?e=`${e}\\\\.\\\\d{${t.precision}}`:null==t.precision\u0026\u0026(e=`${e}(\\\\.\\\\d+)?`);return`([01]\\\\d|2[0-3]):[0-5]\\\\d(:${e})${t.precision?\"+\":\"?\"}`}function Pb(t){return new RegExp(`^${Cb(t)}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
)}function Mb(t){let e=`${Sb}T${Cb(t)}`;const n=[];return n.push(t.local?\"Z?\":\"Z\"),t.offset\u0026\u0026n.push(\"([+-]\\\\d{2}:?\\\\d{2})\"),e=`${e}(${n.join(\"|\")})`,new RegExp(`^${e}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
)}function Nb(t,e){return!(\"v4\"!==e\u0026\u0026e||!fb.test(t))||!(\"v6\"!==e\u0026\u0026e||!_b.test(t))}function wb(t,e){if(!pb.test(t))return!1;try{const[n]=t.split(\".\");if(!n)return!1;const o=n.replace(/-/g,\"+\").replace(/_/g,\"/\").padEnd(n.length+(4-n.length%4)%4,\"=\"),i=JSON.parse(atob(o));return\"object\"==typeof i\u0026\u0026null!==i\u0026\u0026((!(\"typ\"in i)||\"JWT\"===i?.typ)\u0026\u0026(!!i.alg\u0026\u0026(!e||i.alg===e)))}catch{return!1}}function Tb(t,e){return!(\"v4\"!==e\u0026\u0026e||!yb.test(t))||!(\"v6\"!==e\u0026\u0026e||!bb.test(t))}var Rb=class t extends ab{_parse(t){this._def.coerce\u0026\u0026(t.data=String(t.data));if(this._getType(t)!==L_.string){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.string,received:e.parsedType}),q_}const e=new Z_;let n;for(const o of this._def.checks)if(\"min\"===o.kind)t.data.length\u003co.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_small,minimum:o.value,type:\"string\",inclusive:!0,exact:!1,message:o.message}),e.dirty());else if(\"max\"===o.kind)t.data.length\u003eo.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_big,maximum:o.value,type:\"string\",inclusive:!0,exact:!1,message:o.message}),e.dirty());else if(\"length\"===o.kind){const i=t.data.length\u003eo.value,r=t.data.length\u003co.value;(i||r)\u0026\u0026(n=this._getOrReturnCtx(t,n),i?H_(n,{code:z_.too_big,maximum:o.value,type:\"string\",inclusive:!0,exact:!0,message:o.message}):r\u0026\u0026H_(n,{code:z_.too_small,minimum:o.value,type:\"string\",inclusive:!0,exact:!0,message:o.message}),e.dirty())}else if(\"email\"===o.kind)gb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"email\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"emoji\"===o.kind)sb||(sb=new RegExp(\"^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+$\",\"u\")),sb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"emoji\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"uuid\"===o.kind)hb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"uuid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"nanoid\"===o.kind)ub.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"nanoid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"cuid\"===o.kind)cb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"cuid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"cuid2\"===o.kind)lb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"cuid2\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"ulid\"===o.kind)db.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"ulid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"url\"===o.kind)try{new URL(t.data)}catch{n=this._getOrReturnCtx(t,n),H_(n,{validation:\"url\",code:z_.invalid_string,message:o.message}),e.dirty()}else if(\"regex\"===o.kind){o.regex.lastIndex=0;o.regex.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"regex\",code:z_.invalid_string,message:o.message}),e.dirty())}else if(\"trim\"===o.kind)t.data=t.data.trim();else if(\"includes\"===o.kind)t.data.includes(o.value,o.position)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{includes:o.value,position:o.position},message:o.message}),e.dirty());else if(\"toLowerCase\"===o.kind)t.data=t.data.toLowerCase();else if(\"toUpperCase\"===o.kind)t.data=t.data.toUpperCase();else if(\"startsWith\"===o.kind)t.data.startsWith(o.value)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{startsWith:o.value},message:o.message}),e.dirty());else if(\"endsWith\"===o.kind)t.data.endsWith(o.value)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{endsWith:o.value},message:o.message}),e.dirty());else if(\"datetime\"===o.kind){Mb(o).test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:\"datetime\",message:o.message}),e.dirty())}else if(\"date\"===o.kind){Ib.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:\"date\",message:o.message}),e.dirty())}else if(\"time\"===o.kind){Pb(o).test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:\"time\",message:o.message}),e.dirty())}else\"duration\"===o.kind?mb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"duration\",code:z_.invalid_string,message:o.message}),e.dirty()):\"ip\"===o.kind?Nb(t.data,o.version)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"ip\",code:z_.invalid_string,message:o.message}),e.dirty()):\"jwt\"===o.kind?wb(t.data,o.alg)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"jwt\",code:z_.invalid_string,message:o.message}),e.dirty()):\"cidr\"===o.kind?Tb(t.data,o.version)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"cidr\",code:z_.invalid_string,message:o.message}),e.dirty()):\"base64\"===o.kind?xb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"base64\",code:z_.invalid_string,message:o.message}),e.dirty()):\"base64url\"===o.kind?vb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"base64url\",code:z_.invalid_string,message:o.message}),e.dirty()):R_.assertNever(o);return{status:e.value,value:t.data}}_regex(t,e,n){return this.refinement(e=\u003et.test(e),{validation:e,code:z_.invalid_string,...G_.errToObj(n)})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}email(t){return this._addCheck({kind:\"email\",...G_.errToObj(t)})}url(t){return this._addCheck({kind:\"url\",...G_.errToObj(t)})}emoji(t){return this._addCheck({kind:\"emoji\",...G_.errToObj(t)})}uuid(t){return this._addCheck({kind:\"uuid\",...G_.errToObj(t)})}nanoid(t){return this._addCheck({kind:\"nanoid\",...G_.errToObj(t)})}cuid(t){return this._addCheck({kind:\"cuid\",...G_.errToObj(t)})}cuid2(t){return this._addCheck({kind:\"cuid2\",...G_.errToObj(t)})}ulid(t){return this._addCheck({kind:\"ulid\",...G_.errToObj(t)})}base64(t){return this._addCheck({kind:\"base64\",...G_.errToObj(t)})}base64url(t){return this._addCheck({kind:\"base64url\",...G_.errToObj(t)})}jwt(t){return this._addCheck({kind:\"jwt\",...G_.errToObj(t)})}ip(t){return this._addCheck({kind:\"ip\",...G_.errToObj(t)})}cidr(t){return this._addCheck({kind:\"cidr\",...G_.errToObj(t)})}datetime(t){return\"string\"==typeof t?this._addCheck({kind:\"datetime\",precision:null,offset:!1,local:!1,message:t}):this._addCheck({kind:\"datetime\",precision:void 0===t?.precision?null:t?.precision,offset:t?.offset??!1,local:t?.local??!1,...G_.errToObj(t?.message)})}date(t){return this._addCheck({kind:\"date\",message:t})}time(t){return\"string\"==typeof t?this._addCheck({kind:\"time\",precision:null,message:t}):this._addCheck({kind:\"time\",precision:void 0===t?.precision?null:t?.precision,...G_.errToObj(t?.message)})}duration(t){return this._addCheck({kind:\"duration\",...G_.errToObj(t)})}regex(t,e){return this._addCheck({kind:\"regex\",regex:t,...G_.errToObj(e)})}includes(t,e){return this._addCheck({kind:\"includes\",value:t,position:e?.position,...G_.errToObj(e?.message)})}startsWith(t,e){return this._addCheck({kind:\"startsWith\",value:t,...G_.errToObj(e)})}endsWith(t,e){return this._addCheck({kind:\"endsWith\",value:t,...G_.errToObj(e)})}min(t,e){return this._addCheck({kind:\"min\",value:t,...G_.errToObj(e)})}max(t,e){return this._addCheck({kind:\"max\",value:t,...G_.errToObj(e)})}length(t,e){return this._addCheck({kind:\"length\",value:t,...G_.errToObj(e)})}nonempty(t){return this.min(1,G_.errToObj(t))}trim(){return new t({...this._def,checks:[...this._def.checks,{kind:\"trim\"}]})}toLowerCase(){return new t({...this._def,checks:[...this._def.checks,{kind:\"toLowerCase\"}]})}toUpperCase(){return new t({...this._def,checks:[...this._def.checks,{kind:\"toUpperCase\"}]})}get isDatetime(){return!!this._def.checks.find(t=\u003e\"datetime\"===t.kind)}get isDate(){return!!this._def.checks.find(t=\u003e\"date\"===t.kind)}get isTime(){return!!this._def.checks.find(t=\u003e\"time\"===t.kind)}get isDuration(){return!!this._def.checks.find(t=\u003e\"duration\"===t.kind)}get isEmail(){return!!this._def.checks.find(t=\u003e\"email\"===t.kind)}get isURL(){return!!this._def.checks.find(t=\u003e\"url\"===t.kind)}get isEmoji(){return!!this._def.checks.find(t=\u003e\"emoji\"===t.kind)}get isUUID(){return!!this._def.checks.find(t=\u003e\"uuid\"===t.kind)}get isNANOID(){return!!this._def.checks.find(t=\u003e\"nanoid\"===t.kind)}get isCUID(){return!!this._def.checks.find(t=\u003e\"cuid\"===t.kind)}get isCUID2(){return!!this._def.checks.find(t=\u003e\"cuid2\"===t.kind)}get isULID(){return!!this._def.checks.find(t=\u003e\"ulid\"===t.kind)}get isIP(){return!!this._def.checks.find(t=\u003e\"ip\"===t.kind)}get isCIDR(){return!!this._def.checks.find(t=\u003e\"cidr\"===t.kind)}get isBase64(){return!!this._def.checks.find(t=\u003e\"base64\"===t.kind)}get isBase64url(){return!!this._def.checks.find(t=\u003e\"base64url\"===t.kind)}get minLength(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return t}get maxLength(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return t}};function Eb(t,e){const n=(t.toString().split(\".\")[1]||\"\").length,o=(e.toString().split(\".\")[1]||\"\").length,i=n\u003eo?n:o;return Number.parseInt(t.toFixed(i).replace(\".\",\"\"))%Number.parseInt(e.toFixed(i).replace(\".\",\"\"))/10**i}Rb.create=t=\u003enew Rb({checks:[],typeName:xx.ZodString,coerce:t?.coerce??!1,...rb(t)});var Ab=class t extends ab{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(t){this._def.coerce\u0026\u0026(t.data=Number(t.data));if(this._getType(t)!==L_.number){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.number,received:e.parsedType}),q_}let e;const n=new Z_;for(const o of this._def.checks)if(\"int\"===o.kind)R_.isInteger(t.data)||(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.invalid_type,expected:\"integer\",received:\"float\",message:o.message}),n.dirty());else if(\"min\"===o.kind){(o.inclusive?t.data\u003co.value:t.data\u003c=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_small,minimum:o.value,type:\"number\",inclusive:o.inclusive,exact:!1,message:o.message}),n.dirty())}else if(\"max\"===o.kind){(o.inclusive?t.data\u003eo.value:t.data\u003e=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_big,maximum:o.value,type:\"number\",inclusive:o.inclusive,exact:!1,message:o.message}),n.dirty())}else\"multipleOf\"===o.kind?0!==Eb(t.data,o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_multiple_of,multipleOf:o.value,message:o.message}),n.dirty()):\"finite\"===o.kind?Number.isFinite(t.data)||(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_finite,message:o.message}),n.dirty()):R_.assertNever(o);return{status:n.value,value:t.data}}gte(t,e){return this.setLimit(\"min\",t,!0,G_.toString(e))}gt(t,e){return this.setLimit(\"min\",t,!1,G_.toString(e))}lte(t,e){return this.setLimit(\"max\",t,!0,G_.toString(e))}lt(t,e){return this.setLimit(\"max\",t,!1,G_.toString(e))}setLimit(e,n,o,i){return new t({...this._def,checks:[...this._def.checks,{kind:e,value:n,inclusive:o,message:G_.toString(i)}]})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}int(t){return this._addCheck({kind:\"int\",message:G_.toString(t)})}positive(t){return this._addCheck({kind:\"min\",value:0,inclusive:!1,message:G_.toString(t)})}negative(t){return this._addCheck({kind:\"max\",value:0,inclusive:!1,message:G_.toString(t)})}nonpositive(t){return this._addCheck({kind:\"max\",value:0,inclusive:!0,message:G_.toString(t)})}nonnegative(t){return this._addCheck({kind:\"min\",value:0,inclusive:!0,message:G_.toString(t)})}multipleOf(t,e){return this._addCheck({kind:\"multipleOf\",value:t,message:G_.toString(e)})}finite(t){return this._addCheck({kind:\"finite\",message:G_.toString(t)})}safe(t){return this._addCheck({kind:\"min\",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:G_.toString(t)})._addCheck({kind:\"max\",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:G_.toString(t)})}get minValue(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return t}get maxValue(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return t}get isInt(){return!!this._def.checks.find(t=\u003e\"int\"===t.kind||\"multipleOf\"===t.kind\u0026\u0026R_.isInteger(t.value))}get isFinite(){let t=null,e=null;for(const n of this._def.checks){if(\"finite\"===n.kind||\"int\"===n.kind||\"multipleOf\"===n.kind)return!0;\"min\"===n.kind?(null===e||n.value\u003ee)\u0026\u0026(e=n.value):\"max\"===n.kind\u0026\u0026(null===t||n.value\u003ct)\u0026\u0026(t=n.value)}return Number.isFinite(e)\u0026\u0026Number.isFinite(t)}};Ab.create=t=\u003enew Ab({checks:[],typeName:xx.ZodNumber,coerce:t?.coerce||!1,...rb(t)});var Ob=class t extends ab{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(t){if(this._def.coerce)try{t.data=BigInt(t.data)}catch{return this._getInvalidInput(t)}if(this._getType(t)!==L_.bigint)return this._getInvalidInput(t);let e;const n=new Z_;for(const o of this._def.checks)if(\"min\"===o.kind){(o.inclusive?t.data\u003co.value:t.data\u003c=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_small,type:\"bigint\",minimum:o.value,inclusive:o.inclusive,message:o.message}),n.dirty())}else if(\"max\"===o.kind){(o.inclusive?t.data\u003eo.value:t.data\u003e=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_big,type:\"bigint\",maximum:o.value,inclusive:o.inclusive,message:o.message}),n.dirty())}else\"multipleOf\"===o.kind?t.data%o.value!==BigInt(0)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_multiple_of,multipleOf:o.value,message:o.message}),n.dirty()):R_.assertNever(o);return{status:n.value,value:t.data}}_getInvalidInput(t){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.bigint,received:e.parsedType}),q_}gte(t,e){return this.setLimit(\"min\",t,!0,G_.toString(e))}gt(t,e){return this.setLimit(\"min\",t,!1,G_.toString(e))}lte(t,e){return this.setLimit(\"max\",t,!0,G_.toString(e))}lt(t,e){return this.setLimit(\"max\",t,!1,G_.toString(e))}setLimit(e,n,o,i){return new t({...this._def,checks:[...this._def.checks,{kind:e,value:n,inclusive:o,message:G_.toString(i)}]})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}positive(t){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!1,message:G_.toString(t)})}negative(t){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!1,message:G_.toString(t)})}nonpositive(t){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!0,message:G_.toString(t)})}nonnegative(t){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!0,message:G_.toString(t)})}multipleOf(t,e){return this._addCheck({kind:\"multipleOf\",value:t,message:G_.toString(e)})}get minValue(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return t}get maxValue(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return t}};Ob.create=t=\u003enew Ob({checks:[],typeName:xx.ZodBigInt,coerce:t?.coerce??!1,...rb(t)});var kb=class extends ab{_parse(t){this._def.coerce\u0026\u0026(t.data=Boolean(t.data));if(this._getType(t)!==L_.boolean){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.boolean,received:e.parsedType}),q_}return K_(t.data)}};kb.create=t=\u003enew kb({typeName:xx.ZodBoolean,coerce:t?.coerce||!1,...rb(t)});var Lb=class t extends ab{_parse(t){this._def.coerce\u0026\u0026(t.data=new Date(t.data));if(this._getType(t)!==L_.date){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.date,received:e.parsedType}),q_}if(Number.isNaN(t.data.getTime())){return H_(this._getOrReturnCtx(t),{code:z_.invalid_date}),q_}const e=new Z_;let n;for(const o of this._def.checks)\"min\"===o.kind?t.data.getTime()\u003co.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_small,message:o.message,inclusive:!0,exact:!1,minimum:o.value,type:\"date\"}),e.dirty()):\"max\"===o.kind?t.data.getTime()\u003eo.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_big,message:o.message,inclusive:!0,exact:!1,maximum:o.value,type:\"date\"}),e.dirty()):R_.assertNever(o);return{status:e.value,value:new Date(t.data.getTime())}}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}min(t,e){return this._addCheck({kind:\"min\",value:t.getTime(),message:G_.toString(e)})}max(t,e){return this._addCheck({kind:\"max\",value:t.getTime(),message:G_.toString(e)})}get minDate(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return null!=t?new Date(t):null}get maxDate(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return null!=t?new Date(t):null}};Lb.create=t=\u003enew Lb({checks:[],coerce:t?.coerce||!1,typeName:xx.ZodDate,...rb(t)});var Db=class extends ab{_parse(t){if(this._getType(t)!==L_.symbol){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.symbol,received:e.parsedType}),q_}return K_(t.data)}};Db.create=t=\u003enew Db({typeName:xx.ZodSymbol,...rb(t)});var zb=class extends ab{_parse(t){if(this._getType(t)!==L_.undefined){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.undefined,received:e.parsedType}),q_}return K_(t.data)}};zb.create=t=\u003enew zb({typeName:xx.ZodUndefined,...rb(t)});var Fb=class extends ab{_parse(t){if(this._getType(t)!==L_.null){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.null,received:e.parsedType}),q_}return K_(t.data)}};Fb.create=t=\u003enew Fb({typeName:xx.ZodNull,...rb(t)});var Bb=class extends ab{constructor(){super(...arguments),this._any=!0}_parse(t){return K_(t.data)}};Bb.create=t=\u003enew Bb({typeName:xx.ZodAny,...rb(t)});var jb=class extends ab{constructor(){super(...arguments),this._unknown=!0}_parse(t){return K_(t.data)}};jb.create=t=\u003enew jb({typeName:xx.ZodUnknown,...rb(t)});var $b=class extends ab{_parse(t){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.never,received:e.parsedType}),q_}};$b.create=t=\u003enew $b({typeName:xx.ZodNever,...rb(t)});var Yb=class extends ab{_parse(t){if(this._getType(t)!==L_.undefined){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.void,received:e.parsedType}),q_}return K_(t.data)}};Yb.create=t=\u003enew Yb({typeName:xx.ZodVoid,...rb(t)});var Xb=class t extends ab{_parse(t){const{ctx:e,status:n}=this._processInputParams(t),o=this._def;if(e.parsedType!==L_.array)return H_(e,{code:z_.invalid_type,expected:L_.array,received:e.parsedType}),q_;if(null!==o.exactLength){const t=e.data.length\u003eo.exactLength.value,i=e.data.length\u003co.exactLength.value;(t||i)\u0026\u0026(H_(e,{code:t?z_.too_big:z_.too_small,minimum:i?o.exactLength.value:void 0,maximum:t?o.exactLength.value:void 0,type:\"array\",inclusive:!0,exact:!0,message:o.exactLength.message}),n.dirty())}if(null!==o.minLength\u0026\u0026e.data.length\u003co.minLength.value\u0026\u0026(H_(e,{code:z_.too_small,minimum:o.minLength.value,type:\"array\",inclusive:!0,exact:!1,message:o.minLength.message}),n.dirty()),null!==o.maxLength\u0026\u0026e.data.length\u003eo.maxLength.value\u0026\u0026(H_(e,{code:z_.too_big,maximum:o.maxLength.value,type:\"array\",inclusive:!0,exact:!1,message:o.maxLength.message}),n.dirty()),e.common.async)return Promise.all([...e.data].map((t,n)=\u003eo.type._parseAsync(new ob(e,t,e.path,n)))).then(t=\u003eZ_.mergeArray(n,t));const i=[...e.data].map((t,n)=\u003eo.type._parseSync(new ob(e,t,e.path,n)));return Z_.mergeArray(n,i)}get element(){return this._def.type}min(e,n){return new t({...this._def,minLength:{value:e,message:G_.toString(n)}})}max(e,n){return new t({...this._def,maxLength:{value:e,message:G_.toString(n)}})}length(e,n){return new t({...this._def,exactLength:{value:e,message:G_.toString(n)}})}nonempty(t){return this.min(1,t)}};function Vb(t){if(t instanceof Wb){const e={};for(const n in t.shape){const o=t.shape[n];e[n]=lx.create(Vb(o))}return new Wb({...t._def,shape:()=\u003ee})}return t instanceof Xb?new Xb({...t._def,type:Vb(t.element)}):t instanceof lx?lx.create(Vb(t.unwrap())):t instanceof dx?dx.create(Vb(t.unwrap())):t instanceof Jb?Jb.create(t.items.map(t=\u003eVb(t))):t}Xb.create=(t,e)=\u003enew Xb({type:t,minLength:null,maxLength:null,exactLength:null,typeName:xx.ZodArray,...rb(e)});var Wb=class t extends ab{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(null!==this._cached)return this._cached;const t=this._def.shape(),e=R_.objectKeys(t);return this._cached={shape:t,keys:e},this._cached}_parse(t){if(this._getType(t)!==L_.object){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.object,received:e.parsedType}),q_}const{status:e,ctx:n}=this._processInputParams(t),{shape:o,keys:i}=this._getCached(),r=[];if(!(this._def.catchall instanceof $b\u0026\u0026\"strip\"===this._def.unknownKeys))for(const t in n.data)i.includes(t)||r.push(t);const s=[];for(const t of i){const e=o[t],i=n.data[t];s.push({key:{status:\"valid\",value:t},value:e._parse(new ob(n,i,n.path,t)),alwaysSet:t in n.data})}if(this._def.catchall instanceof $b){const t=this._def.unknownKeys;if(\"passthrough\"===t)for(const t of r)s.push({key:{status:\"valid\",value:t},value:{status:\"valid\",value:n.data[t]}});else if(\"strict\"===t)r.length\u003e0\u0026\u0026(H_(n,{code:z_.unrecognized_keys,keys:r}),e.dirty());else if(\"strip\"!==t)throw new Error(\"Internal ZodObject error: invalid unknownKeys value.\")}else{const t=this._def.catchall;for(const e of r){const o=n.data[e];s.push({key:{status:\"valid\",value:e},value:t._parse(new ob(n,o,n.path,e)),alwaysSet:e in n.data})}}return n.common.async?Promise.resolve().then(async()=\u003e{const t=[];for(const e of s){const n=await e.key,o=await e.value;t.push({key:n,value:o,alwaysSet:e.alwaysSet})}return t}).then(t=\u003eZ_.mergeObjectSync(e,t)):Z_.mergeObjectSync(e,s)}get shape(){return this._def.shape()}strict(e){return G_.errToObj,new t({...this._def,unknownKeys:\"strict\",...void 0!==e?{errorMap:(t,n)=\u003e{const o=this._def.errorMap?.(t,n).message??n.defaultError;return\"unrecognized_keys\"===t.code?{message:G_.errToObj(e).message??o}:{message:o}}}:{}})}strip(){return new t({...this._def,unknownKeys:\"strip\"})}passthrough(){return new t({...this._def,unknownKeys:\"passthrough\"})}extend(e){return new t({...this._def,shape:()=\u003e({...this._def.shape(),...e})})}merge(e){return new t({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=\u003e({...this._def.shape(),...e._def.shape()}),typeName:xx.ZodObject})}setKey(t,e){return this.augment({[t]:e})}catchall(e){return new t({...this._def,catchall:e})}pick(e){const n={};for(const t of R_.objectKeys(e))e[t]\u0026\u0026this.shape[t]\u0026\u0026(n[t]=this.shape[t]);return new t({...this._def,shape:()=\u003en})}omit(e){const n={};for(const t of R_.objectKeys(this.shape))e[t]||(n[t]=this.shape[t]);return new t({...this._def,shape:()=\u003en})}deepPartial(){return Vb(this)}partial(e){const n={};for(const t of R_.objectKeys(this.shape)){const o=this.shape[t];e\u0026\u0026!e[t]?n[t]=o:n[t]=o.optional()}return new t({...this._def,shape:()=\u003en})}required(e){const n={};for(const t of R_.objectKeys(this.shape))if(e\u0026\u0026!e[t])n[t]=this.shape[t];else{let e=this.shape[t];for(;e instanceof lx;)e=e._def.innerType;n[t]=e}return new t({...this._def,shape:()=\u003en})}keyof(){return ix(R_.objectKeys(this.shape))}};Wb.create=(t,e)=\u003enew Wb({shape:()=\u003et,unknownKeys:\"strip\",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)}),Wb.strictCreate=(t,e)=\u003enew Wb({shape:()=\u003et,unknownKeys:\"strict\",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)}),Wb.lazycreate=(t,e)=\u003enew Wb({shape:t,unknownKeys:\"strip\",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)});var Hb=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n=this._def.options;if(e.common.async)return Promise.all(n.map(async t=\u003e{const n={...e,common:{...e.common,issues:[]},parent:null};return{result:await t._parseAsync({data:e.data,path:e.path,parent:n}),ctx:n}})).then(function(t){for(const e of t)if(\"valid\"===e.result.status)return e.result;for(const n of t)if(\"dirty\"===n.result.status)return e.common.issues.push(...n.ctx.common.issues),n.result;const n=t.map(t=\u003enew B_(t.ctx.common.issues));return H_(e,{code:z_.invalid_union,unionErrors:n}),q_});{let t;const o=[];for(const i of n){const n={...e,common:{...e.common,issues:[]},parent:null},r=i._parseSync({data:e.data,path:e.path,parent:n});if(\"valid\"===r.status)return r;\"dirty\"!==r.status||t||(t={result:r,ctx:n}),n.common.issues.length\u0026\u0026o.push(n.common.issues)}if(t)return e.common.issues.push(...t.ctx.common.issues),t.result;const i=o.map(t=\u003enew B_(t));return H_(e,{code:z_.invalid_union,unionErrors:i}),q_}}get options(){return this._def.options}};Hb.create=(t,e)=\u003enew Hb({options:t,typeName:xx.ZodUnion,...rb(e)});var Gb=t=\u003et instanceof nx?Gb(t.schema):t instanceof cx?Gb(t.innerType()):t instanceof ox?[t.value]:t instanceof rx?t.options:t instanceof sx?R_.objectValues(t.enum):t instanceof hx?Gb(t._def.innerType):t instanceof zb?[void 0]:t instanceof Fb?[null]:t instanceof lx?[void 0,...Gb(t.unwrap())]:t instanceof dx?[null,...Gb(t.unwrap())]:t instanceof gx||t instanceof yx?Gb(t.unwrap()):t instanceof ux?Gb(t._def.innerType):[],Ub=class t extends ab{_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.object)return H_(e,{code:z_.invalid_type,expected:L_.object,received:e.parsedType}),q_;const n=this.discriminator,o=e.data[n],i=this.optionsMap.get(o);return i?e.common.async?i._parseAsync({data:e.data,path:e.path,parent:e}):i._parseSync({data:e.data,path:e.path,parent:e}):(H_(e,{code:z_.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[n]}),q_)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,n,o){const i=new Map;for(const t of n){const n=Gb(t.shape[e]);if(!n.length)throw new Error(`A discriminator value for key \\`${e}\\` could not be extracted from all schema options`);for(const o of n){if(i.has(o))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(o)}`);i.set(o,t)}}return new t({typeName:xx.ZodDiscriminatedUnion,discriminator:e,options:n,optionsMap:i,...rb(o)})}};function Zb(t,e){const n=D_(t),o=D_(e);if(t===e)return{valid:!0,data:t};if(n===L_.object\u0026\u0026o===L_.object){const n=R_.objectKeys(e),o=R_.objectKeys(t).filter(t=\u003e-1!==n.indexOf(t)),i={...t,...e};for(const n of o){const o=Zb(t[n],e[n]);if(!o.valid)return{valid:!1};i[n]=o.data}return{valid:!0,data:i}}if(n===L_.array\u0026\u0026o===L_.array){if(t.length!==e.length)return{valid:!1};const n=[];for(let o=0;o\u003ct.length;o++){const i=Zb(t[o],e[o]);if(!i.valid)return{valid:!1};n.push(i.data)}return{valid:!0,data:n}}return n===L_.date\u0026\u0026o===L_.date\u0026\u0026+t===+e?{valid:!0,data:t}:{valid:!1}}var qb=class extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t),o=(t,o)=\u003e{if(Q_(t)||Q_(o))return q_;const i=Zb(t.value,o.value);return i.valid?((tb(t)||tb(o))\u0026\u0026e.dirty(),{status:e.value,value:i.data}):(H_(n,{code:z_.invalid_intersection_types}),q_)};return n.common.async?Promise.all([this._def.left._parseAsync({data:n.data,path:n.path,parent:n}),this._def.right._parseAsync({data:n.data,path:n.path,parent:n})]).then(([t,e])=\u003eo(t,e)):o(this._def.left._parseSync({data:n.data,path:n.path,parent:n}),this._def.right._parseSync({data:n.data,path:n.path,parent:n}))}};qb.create=(t,e,n)=\u003enew qb({left:t,right:e,typeName:xx.ZodIntersection,...rb(n)});var Jb=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.array)return H_(n,{code:z_.invalid_type,expected:L_.array,received:n.parsedType}),q_;if(n.data.length\u003cthis._def.items.length)return H_(n,{code:z_.too_small,minimum:this._def.items.length,inclusive:!0,exact:!1,type:\"array\"}),q_;!this._def.rest\u0026\u0026n.data.length\u003ethis._def.items.length\u0026\u0026(H_(n,{code:z_.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:\"array\"}),e.dirty());const o=[...n.data].map((t,e)=\u003e{const o=this._def.items[e]||this._def.rest;return o?o._parse(new ob(n,t,n.path,e)):null}).filter(t=\u003e!!t);return n.common.async?Promise.all(o).then(t=\u003eZ_.mergeArray(e,t)):Z_.mergeArray(e,o)}get items(){return this._def.items}rest(e){return new t({...this._def,rest:e})}};Jb.create=(t,e)=\u003e{if(!Array.isArray(t))throw new Error(\"You must pass an array of schemas to z.tuple([ ... ])\");return new Jb({items:t,typeName:xx.ZodTuple,rest:null,...rb(e)})};var Kb=class t extends ab{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.object)return H_(n,{code:z_.invalid_type,expected:L_.object,received:n.parsedType}),q_;const o=[],i=this._def.keyType,r=this._def.valueType;for(const t in n.data)o.push({key:i._parse(new ob(n,t,n.path,t)),value:r._parse(new ob(n,n.data[t],n.path,t)),alwaysSet:t in n.data});return n.common.async?Z_.mergeObjectAsync(e,o):Z_.mergeObjectSync(e,o)}get element(){return this._def.valueType}static create(e,n,o){return new t(n instanceof ab?{keyType:e,valueType:n,typeName:xx.ZodRecord,...rb(o)}:{keyType:Rb.create(),valueType:e,typeName:xx.ZodRecord,...rb(n)})}},Qb=class extends ab{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.map)return H_(n,{code:z_.invalid_type,expected:L_.map,received:n.parsedType}),q_;const o=this._def.keyType,i=this._def.valueType,r=[...n.data.entries()].map(([t,e],r)=\u003e({key:o._parse(new ob(n,t,n.path,[r,\"key\"])),value:i._parse(new ob(n,e,n.path,[r,\"value\"]))}));if(n.common.async){const t=new Map;return Promise.resolve().then(async()=\u003e{for(const n of r){const o=await n.key,i=await n.value;if(\"aborted\"===o.status||\"aborted\"===i.status)return q_;\"dirty\"!==o.status\u0026\u0026\"dirty\"!==i.status||e.dirty(),t.set(o.value,i.value)}return{status:e.value,value:t}})}{const t=new Map;for(const n of r){const o=n.key,i=n.value;if(\"aborted\"===o.status||\"aborted\"===i.status)return q_;\"dirty\"!==o.status\u0026\u0026\"dirty\"!==i.status||e.dirty(),t.set(o.value,i.value)}return{status:e.value,value:t}}}};Qb.create=(t,e,n)=\u003enew Qb({valueType:e,keyType:t,typeName:xx.ZodMap,...rb(n)});var tx=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.set)return H_(n,{code:z_.invalid_type,expected:L_.set,received:n.parsedType}),q_;const o=this._def;null!==o.minSize\u0026\u0026n.data.size\u003co.minSize.value\u0026\u0026(H_(n,{code:z_.too_small,minimum:o.minSize.value,type:\"set\",inclusive:!0,exact:!1,message:o.minSize.message}),e.dirty()),null!==o.maxSize\u0026\u0026n.data.size\u003eo.maxSize.value\u0026\u0026(H_(n,{code:z_.too_big,maximum:o.maxSize.value,type:\"set\",inclusive:!0,exact:!1,message:o.maxSize.message}),e.dirty());const i=this._def.valueType;function r(t){const n=new Set;for(const o of t){if(\"aborted\"===o.status)return q_;\"dirty\"===o.status\u0026\u0026e.dirty(),n.add(o.value)}return{status:e.value,value:n}}const s=[...n.data.values()].map((t,e)=\u003ei._parse(new ob(n,t,n.path,e)));return n.common.async?Promise.all(s).then(t=\u003er(t)):r(s)}min(e,n){return new t({...this._def,minSize:{value:e,message:G_.toString(n)}})}max(e,n){return new t({...this._def,maxSize:{value:e,message:G_.toString(n)}})}size(t,e){return this.min(t,e).max(t,e)}nonempty(t){return this.min(1,t)}};tx.create=(t,e)=\u003enew tx({valueType:t,minSize:null,maxSize:null,typeName:xx.ZodSet,...rb(e)});var ex=class t extends ab{constructor(){super(...arguments),this.validate=this.implement}_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.function)return H_(e,{code:z_.invalid_type,expected:L_.function,received:e.parsedType}),q_;function n(t,n){return V_({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,X_(),j_].filter(t=\u003e!!t),issueData:{code:z_.invalid_arguments,argumentsError:n}})}function o(t,n){return V_({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,X_(),j_].filter(t=\u003e!!t),issueData:{code:z_.invalid_return_type,returnTypeError:n}})}const i={errorMap:e.common.contextualErrorMap},r=e.data;if(this._def.returns instanceof ax){const t=this;return K_(async function(...e){const s=new B_([]),a=await t._def.args.parseAsync(e,i).catch(t=\u003e{throw s.addIssue(n(e,t)),s}),c=await Reflect.apply(r,this,a);return await t._def.returns._def.type.parseAsync(c,i).catch(t=\u003e{throw s.addIssue(o(c,t)),s})})}{const t=this;return K_(function(...e){const s=t._def.args.safeParse(e,i);if(!s.success)throw new B_([n(e,s.error)]);const a=Reflect.apply(r,this,s.data),c=t._def.returns.safeParse(a,i);if(!c.success)throw new B_([o(a,c.error)]);return c.data})}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new t({...this._def,args:Jb.create(e).rest(jb.create())})}returns(e){return new t({...this._def,returns:e})}implement(t){return this.parse(t)}strictImplement(t){return this.parse(t)}static create(e,n,o){return new t({args:e||Jb.create([]).rest(jb.create()),returns:n||jb.create(),typeName:xx.ZodFunction,...rb(o)})}},nx=class extends ab{get schema(){return this._def.getter()}_parse(t){const{ctx:e}=this._processInputParams(t);return this._def.getter()._parse({data:e.data,path:e.path,parent:e})}};nx.create=(t,e)=\u003enew nx({getter:t,typeName:xx.ZodLazy,...rb(e)});var ox=class extends ab{_parse(t){if(t.data!==this._def.value){const e=this._getOrReturnCtx(t);return H_(e,{received:e.data,code:z_.invalid_literal,expected:this._def.value}),q_}return{status:\"valid\",value:t.data}}get value(){return this._def.value}};function ix(t,e){return new rx({values:t,typeName:xx.ZodEnum,...rb(e)})}ox.create=(t,e)=\u003enew ox({value:t,typeName:xx.ZodLiteral,...rb(e)});var rx=class t extends ab{_parse(t){if(\"string\"!=typeof t.data){const e=this._getOrReturnCtx(t),n=this._def.values;return H_(e,{expected:R_.joinValues(n),received:e.parsedType,code:z_.invalid_type}),q_}if(this._cache||(this._cache=new Set(this._def.values)),!this._cache.has(t.data)){const e=this._getOrReturnCtx(t),n=this._def.values;return H_(e,{received:e.data,code:z_.invalid_enum_value,options:n}),q_}return K_(t.data)}get options(){return this._def.values}get enum(){const t={};for(const e of this._def.values)t[e]=e;return t}get Values(){const t={};for(const e of this._def.values)t[e]=e;return t}get Enum(){const t={};for(const e of this._def.values)t[e]=e;return t}extract(e,n=this._def){return t.create(e,{...this._def,...n})}exclude(e,n=this._def){return t.create(this.options.filter(t=\u003e!e.includes(t)),{...this._def,...n})}};rx.create=ix;var sx=class extends ab{_parse(t){const e=R_.getValidEnumValues(this._def.values),n=this._getOrReturnCtx(t);if(n.parsedType!==L_.string\u0026\u0026n.parsedType!==L_.number){const t=R_.objectValues(e);return H_(n,{expected:R_.joinValues(t),received:n.parsedType,code:z_.invalid_type}),q_}if(this._cache||(this._cache=new Set(R_.getValidEnumValues(this._def.values))),!this._cache.has(t.data)){const t=R_.objectValues(e);return H_(n,{received:n.data,code:z_.invalid_enum_value,options:t}),q_}return K_(t.data)}get enum(){return this._def.values}};sx.create=(t,e)=\u003enew sx({values:t,typeName:xx.ZodNativeEnum,...rb(e)});var ax=class extends ab{unwrap(){return this._def.type}_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.promise\u0026\u0026!1===e.common.async)return H_(e,{code:z_.invalid_type,expected:L_.promise,received:e.parsedType}),q_;const n=e.parsedType===L_.promise?e.data:Promise.resolve(e.data);return K_(n.then(t=\u003ethis._def.type.parseAsync(t,{path:e.path,errorMap:e.common.contextualErrorMap})))}};ax.create=(t,e)=\u003enew ax({type:t,typeName:xx.ZodPromise,...rb(e)});var cx=class extends ab{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===xx.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(t){const{status:e,ctx:n}=this._processInputParams(t),o=this._def.effect||null,i={addIssue:t=\u003e{H_(n,t),t.fatal?e.abort():e.dirty()},get path(){return n.path}};if(i.addIssue=i.addIssue.bind(i),\"preprocess\"===o.type){const t=o.transform(n.data,i);if(n.common.async)return Promise.resolve(t).then(async t=\u003e{if(\"aborted\"===e.value)return q_;const o=await this._def.schema._parseAsync({data:t,path:n.path,parent:n});return\"aborted\"===o.status?q_:\"dirty\"===o.status||\"dirty\"===e.value?J_(o.value):o});{if(\"aborted\"===e.value)return q_;const o=this._def.schema._parseSync({data:t,path:n.path,parent:n});return\"aborted\"===o.status?q_:\"dirty\"===o.status||\"dirty\"===e.value?J_(o.value):o}}if(\"refinement\"===o.type){const t=t=\u003e{const e=o.refinement(t,i);if(n.common.async)return Promise.resolve(e);if(e instanceof Promise)throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");return t};if(!1===n.common.async){const o=this._def.schema._parseSync({data:n.data,path:n.path,parent:n});return\"aborted\"===o.status?q_:(\"dirty\"===o.status\u0026\u0026e.dirty(),t(o.value),{status:e.value,value:o.value})}return this._def.schema._parseAsync({data:n.data,path:n.path,parent:n}).then(n=\u003e\"aborted\"===n.status?q_:(\"dirty\"===n.status\u0026\u0026e.dirty(),t(n.value).then(()=\u003e({status:e.value,value:n.value}))))}if(\"transform\"===o.type){if(!1===n.common.async){const t=this._def.schema._parseSync({data:n.data,path:n.path,parent:n});if(!eb(t))return q_;const r=o.transform(t.value,i);if(r instanceof Promise)throw new Error(\"Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.\");return{status:e.value,value:r}}return this._def.schema._parseAsync({data:n.data,path:n.path,parent:n}).then(t=\u003eeb(t)?Promise.resolve(o.transform(t.value,i)).then(t=\u003e({status:e.value,value:t})):q_)}R_.assertNever(o)}};cx.create=(t,e,n)=\u003enew cx({schema:t,typeName:xx.ZodEffects,effect:e,...rb(n)}),cx.createWithPreprocess=(t,e,n)=\u003enew cx({schema:e,effect:{type:\"preprocess\",transform:t},typeName:xx.ZodEffects,...rb(n)});var lx=class extends ab{_parse(t){return this._getType(t)===L_.undefined?K_(void 0):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}};lx.create=(t,e)=\u003enew lx({innerType:t,typeName:xx.ZodOptional,...rb(e)});var dx=class extends ab{_parse(t){return this._getType(t)===L_.null?K_(null):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}};dx.create=(t,e)=\u003enew dx({innerType:t,typeName:xx.ZodNullable,...rb(e)});var hx=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t);let n=e.data;return e.parsedType===L_.undefined\u0026\u0026(n=this._def.defaultValue()),this._def.innerType._parse({data:n,path:e.path,parent:e})}removeDefault(){return this._def.innerType}};hx.create=(t,e)=\u003enew hx({innerType:t,typeName:xx.ZodDefault,defaultValue:\"function\"==typeof e.default?e.default:()=\u003ee.default,...rb(e)});var ux=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n={...e,common:{...e.common,issues:[]}},o=this._def.innerType._parse({data:n.data,path:n.path,parent:{...n}});return nb(o)?o.then(t=\u003e({status:\"valid\",value:\"valid\"===t.status?t.value:this._def.catchValue({get error(){return new B_(n.common.issues)},input:n.data})})):{status:\"valid\",value:\"valid\"===o.status?o.value:this._def.catchValue({get error(){return new B_(n.common.issues)},input:n.data})}}removeCatch(){return this._def.innerType}};ux.create=(t,e)=\u003enew ux({innerType:t,typeName:xx.ZodCatch,catchValue:\"function\"==typeof e.catch?e.catch:()=\u003ee.catch,...rb(e)});var px=class extends ab{_parse(t){if(this._getType(t)!==L_.nan){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.nan,received:e.parsedType}),q_}return{status:\"valid\",value:t.data}}};px.create=t=\u003enew px({typeName:xx.ZodNaN,...rb(t)});var mx=Symbol(\"zod_brand\"),gx=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n=e.data;return this._def.type._parse({data:n,path:e.path,parent:e})}unwrap(){return this._def.type}},fx=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.common.async){return(async()=\u003e{const t=await this._def.in._parseAsync({data:n.data,path:n.path,parent:n});return\"aborted\"===t.status?q_:\"dirty\"===t.status?(e.dirty(),J_(t.value)):this._def.out._parseAsync({data:t.value,path:n.path,parent:n})})()}{const t=this._def.in._parseSync({data:n.data,path:n.path,parent:n});return\"aborted\"===t.status?q_:\"dirty\"===t.status?(e.dirty(),{status:\"dirty\",value:t.value}):this._def.out._parseSync({data:t.value,path:n.path,parent:n})}}static create(e,n){return new t({in:e,out:n,typeName:xx.ZodPipeline})}},yx=class extends ab{_parse(t){const e=this._def.innerType._parse(t),n=t=\u003e(eb(t)\u0026\u0026(t.value=Object.freeze(t.value)),t);return nb(e)?e.then(t=\u003en(t)):n(e)}unwrap(){return this._def.innerType}};function _x(t,e){const n=\"function\"==typeof t?t(e):\"string\"==typeof t?{message:t}:t;return\"string\"==typeof n?{message:n}:n}function bx(t,e={},n){return t?Bb.create().superRefine((o,i)=\u003e{const r=t(o);if(r instanceof Promise)return r.then(t=\u003e{if(!t){const t=_x(e,o),r=t.fatal??n??!0;i.addIssue({code:\"custom\",...t,fatal:r})}});if(!r){const t=_x(e,o),r=t.fatal??n??!0;i.addIssue({code:\"custom\",...t,fatal:r})}}):Bb.create()}yx.create=(t,e)=\u003enew yx({innerType:t,typeName:xx.ZodReadonly,...rb(e)});var xx,vx,Sx={object:Wb.lazycreate};(vx=xx||(xx={})).ZodString=\"ZodString\",vx.ZodNumber=\"ZodNumber\",vx.ZodNaN=\"ZodNaN\",vx.ZodBigInt=\"ZodBigInt\",vx.ZodBoolean=\"ZodBoolean\",vx.ZodDate=\"ZodDate\",vx.ZodSymbol=\"ZodSymbol\",vx.ZodUndefined=\"ZodUndefined\",vx.ZodNull=\"ZodNull\",vx.ZodAny=\"ZodAny\",vx.ZodUnknown=\"ZodUnknown\",vx.ZodNever=\"ZodNever\",vx.ZodVoid=\"ZodVoid\",vx.ZodArray=\"ZodArray\",vx.ZodObject=\"ZodObject\",vx.ZodUnion=\"ZodUnion\",vx.ZodDiscriminatedUnion=\"ZodDiscriminatedUnion\",vx.ZodIntersection=\"ZodIntersection\",vx.ZodTuple=\"ZodTuple\",vx.ZodRecord=\"ZodRecord\",vx.ZodMap=\"ZodMap\",vx.ZodSet=\"ZodSet\",vx.ZodFunction=\"ZodFunction\",vx.ZodLazy=\"ZodLazy\",vx.ZodLiteral=\"ZodLiteral\",vx.ZodEnum=\"ZodEnum\",vx.ZodEffects=\"ZodEffects\",vx.ZodNativeEnum=\"ZodNativeEnum\",vx.ZodOptional=\"ZodOptional\",vx.ZodNullable=\"ZodNullable\",vx.ZodDefault=\"ZodDefault\",vx.ZodCatch=\"ZodCatch\",vx.ZodPromise=\"ZodPromise\",vx.ZodBranded=\"ZodBranded\",vx.ZodPipeline=\"ZodPipeline\",vx.ZodReadonly=\"ZodReadonly\";var Ix=(t,e={message:`Input not instance of ${t.name}`})=\u003ebx(e=\u003ee instanceof t,e),Cx=Rb.create,Px=Ab.create,Mx=px.create,Nx=Ob.create,wx=kb.create,Tx=Lb.create,Rx=Db.create,Ex=zb.create,Ax=Fb.create,Ox=Bb.create,kx=jb.create,Lx=$b.create,Dx=Yb.create,zx=Xb.create,Fx=Wb.create,Bx=Wb.strictCreate,jx=Hb.create,$x=Ub.create,Yx=qb.create,Xx=Jb.create,Vx=Kb.create,Wx=Qb.create,Hx=tx.create,Gx=ex.create,Ux=nx.create,Zx=ox.create,qx=rx.create,Jx=sx.create,Kx=ax.create,Qx=cx.create,tv=lx.create,ev=dx.create,nv=cx.createWithPreprocess,ov=fx.create,iv=()=\u003eCx().optional(),rv=()=\u003ePx().optional(),sv=()=\u003ewx().optional(),av={string:t=\u003eRb.create({...t,coerce:!0}),number:t=\u003eAb.create({...t,coerce:!0}),boolean:t=\u003ekb.create({...t,coerce:!0}),bigint:t=\u003eOb.create({...t,coerce:!0}),date:t=\u003eLb.create({...t,coerce:!0})},cv=q_,lv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"Ω\").value),dv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"F\").value).transform(t=\u003eNumber.parseFloat(t.toPrecision(12))),hv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"H\").value),uv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"V\").value),pv=k_.string().or(k_.number()).transform(t=\u003eT_(t).value),mv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"Hz\").value),gv=pv,fv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"A\").value),yv=k_.string().or(k_.number()).transform(t=\u003eT_(t).value),_v=yv,bv=yv,xv=k_.string().datetime(),vv=k_.string().or(k_.number()).transform(t=\u003e\"number\"==typeof t?t:t.endsWith(\"deg\")?Number.parseFloat(t.split(\"deg\")[0]):t.endsWith(\"rad\")?180*Number.parseFloat(t.split(\"rad\")[0])/Math.PI:Number.parseFloat(t)),Sv=k_.number().or(k_.string().endsWith(\"mAh\")).transform(t=\u003e{if(\"string\"==typeof t){const e=t.replace(\"mAh\",\"\"),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error(\"Invalid capacity\");return n}return t}).describe(\"Battery capacity in mAh\"),Iv=k_.object({x:gv,y:gv}),Cv=Iv,Pv=k_.object({x:gv,y:gv,z:gv}),Mv=Pv,Nv=k_.object({width:k_.number(),height:k_.number()}),wv=t=\u003ek_.string().optional().default(()=\u003e`${t}_${(t=\u003e{const e=\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";return Array.from({length:t},()=\u003ee[Math.floor(62*Math.random())]).join(\"\")})(10)}`),Tv=k_.enum([\"top_left\",\"top_center\",\"top_right\",\"center_left\",\"center\",\"center_right\",\"bottom_left\",\"bottom_center\",\"bottom_right\"]),Rv=k_.enum([\"top_silkscreen\",\"bottom_silkscreen\",\"top_copper\",\"bottom_copper\",\"top_soldermask\",\"bottom_soldermask\",\"top_fabrication_note\",\"bottom_fabrication_note\",\"top_user_note\",\"bottom_user_note\",\"top_courtyard\",\"bottom_courtyard\",\"inner1_copper\",\"inner2_copper\",\"inner3_copper\",\"inner4_copper\",\"inner5_copper\",\"inner6_copper\",\"inner7_copper\",\"inner8_copper\",\"edge_cuts\",\"drill\"]),Ev=k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()}),Av=Iv.extend({rotation:vv.optional()}),Ov=k_.object({size:Iv.optional(),thickness:gv.optional()}),kv=k_.object({font:Ov.optional()}),Lv=k_.object({value:k_.string(),at:Av.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:kv.optional()}),Dv=k_.object({Reference:Lv.optional(),Value:Lv.optional(),Datasheet:Lv.optional(),Description:Lv.optional()}),zv=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),Fv=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:Av.optional(),size:Iv.optional(),drill:gv.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),Bv=k_.object({path:k_.string(),offset:Pv.optional(),scale:Pv.optional(),rotate:Pv.optional()}),jv=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:Dv.optional(),attributes:zv.optional(),pads:k_.array(Fv).optional(),embeddedFonts:k_.boolean().optional(),model:Bv.optional()}),$v=k_.object({hide:k_.boolean().optional()}),Yv=k_.object({offset:gv.optional(),hide:k_.boolean().optional()}),Xv=k_.object({font:Ov.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),Vv=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:Av.optional(),effects:Xv.optional()}),Wv=k_.object({Reference:Vv.optional(),Value:Vv.optional(),Footprint:Vv.optional(),Datasheet:Vv.optional(),Description:Vv.optional(),ki_keywords:Vv.optional(),ki_fp_filters:Vv.optional()}),Hv=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:$v.optional(),pinNames:Yv.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:Wv.optional(),embeddedFonts:k_.boolean().optional()}),Gv=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),Uv=k_.enum([\"jlcpcb\",\"macrofab\",\"pcbway\",\"digikey\",\"mouser\",\"lcsc\"]),Zv=k_.object({type:k_.literal(\"source_component\"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(Uv,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),qv=Zv.extend({ftype:k_.literal(\"simple_capacitor\"),capacitance:dv,max_voltage_rating:uv.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:gv.optional()}),Jv=Zv.extend({ftype:k_.literal(\"simple_resistor\"),resistance:lv,display_resistance:k_.string().optional()}),Kv=Zv.extend({ftype:k_.literal(\"simple_diode\")}),Qv=Zv.extend({ftype:k_.literal(\"simple_fiducial\")}),tS=Kv.extend({ftype:k_.literal(\"simple_led\"),color:k_.string().optional(),wavelength:k_.string().optional()}),eS=Zv.extend({ftype:k_.literal(\"simple_ground\")}),nS=Zv.extend({ftype:k_.literal(\"simple_chip\")}),oS=Zv.extend({ftype:k_.literal(\"simple_power_source\"),voltage:uv}),iS=Zv.extend({ftype:k_.literal(\"simple_current_source\"),current:fv,frequency:mv.optional(),peak_to_peak_current:fv.optional(),wave_shape:k_.enum([\"sine\",\"square\",\"triangle\",\"sawtooth\",\"dc\"]).optional().default(\"dc\"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),rS=Zv.extend({ftype:k_.literal(\"simple_fuse\"),current_rating_amps:k_.number().describe(\"Nominal current in amps the fuse is rated for\"),voltage_rating_volts:k_.number().describe(\"Voltage rating in volts, e.g. ±5V would be 5\")}),sS=Zv.extend({ftype:k_.literal(\"simple_ammeter\")}),aS=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),cS=Zv.extend({ftype:k_.literal(\"simple_battery\"),capacity:Sv}),lS=Zv.extend({ftype:k_.literal(\"simple_inductor\"),inductance:hv,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),dS=Zv.extend({ftype:k_.literal(\"simple_push_button\")}),hS=Zv.extend({ftype:k_.literal(\"simple_potentiometer\"),max_resistance:lv,display_max_resistance:k_.string().optional()}),uS=Zv.extend({ftype:k_.literal(\"simple_crystal\"),frequency:k_.number().describe(\"Frequency in Hz\"),load_capacitance:k_.number().optional().describe(\"Load capacitance in pF\"),pin_variant:k_.enum([\"two_pin\",\"four_pin\"]).optional()}),pS=Zv.extend({ftype:k_.literal(\"simple_pin_header\"),pin_count:k_.number(),gender:k_.enum([\"male\",\"female\"]).optional().default(\"male\")}),mS=Zv.extend({ftype:k_.literal(\"simple_connector\"),standard:k_.enum([\"usb_c\",\"m2\"]).optional()}),gS=Zv.extend({ftype:k_.literal(\"simple_pinout\")}),fS=Zv.extend({ftype:k_.literal(\"simple_resonator\"),load_capacitance:dv,equivalent_series_resistance:lv.optional(),frequency:mv}),yS=Zv.extend({ftype:k_.literal(\"simple_transistor\"),transistor_type:k_.enum([\"npn\",\"pnp\"])}),_S=Zv.extend({ftype:k_.literal(\"simple_test_point\"),footprint_variant:k_.enum([\"pad\",\"through_hole\"]).optional(),pad_shape:k_.enum([\"rect\",\"circle\"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),bS=Zv.extend({ftype:k_.literal(\"simple_mosfet\"),channel_type:k_.enum([\"n\",\"p\"]),mosfet_mode:k_.enum([\"enhancement\",\"depletion\"])}),xS=Zv.extend({ftype:k_.literal(\"simple_op_amp\")}),vS=Zv.extend({ftype:k_.literal(\"simple_switch\")}),SS=k_.object({type:k_.literal(\"source_project_metadata\"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),source_filesystem_md5_hash:k_.string().optional(),created_at:xv.optional()}),IS=Gv.extend({type:k_.literal(\"source_missing_property_error\"),source_missing_property_error_id:wv(\"source_missing_property_error\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_missing_property_error\").default(\"source_missing_property_error\")}).describe(\"The source code is missing a property\"),CS=Gv.extend({type:k_.literal(\"source_failed_to_create_component_error\"),source_failed_to_create_component_error_id:wv(\"source_failed_to_create_component_error\"),error_type:k_.literal(\"source_failed_to_create_component_error\").default(\"source_failed_to_create_component_error\"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe(\"Error emitted when a component fails to be constructed\"),PS=Gv.extend({type:k_.literal(\"source_invalid_component_property_error\"),source_invalid_component_property_error_id:wv(\"source_invalid_component_property_error\"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_invalid_component_property_error\").default(\"source_invalid_component_property_error\")}).describe(\"The source component property is invalid\"),MS=Gv.extend({type:k_.literal(\"source_trace_not_connected_error\"),source_trace_not_connected_error_id:wv(\"source_trace_not_connected_error\"),error_type:k_.literal(\"source_trace_not_connected_error\").default(\"source_trace_not_connected_error\"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe(\"Occurs when a source trace selector does not match any ports\"),NS=k_.object({type:k_.literal(\"source_property_ignored_warning\"),source_property_ignored_warning_id:wv(\"source_property_ignored_warning\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_property_ignored_warning\").default(\"source_property_ignored_warning\"),message:k_.string()}).describe(\"The source property was ignored\"),wS=k_.object({type:k_.literal(\"source_pin_missing_trace_warning\"),source_pin_missing_trace_warning_id:wv(\"source_pin_missing_trace_warning\"),warning_type:k_.literal(\"source_pin_missing_trace_warning\").default(\"source_pin_missing_trace_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component pin is missing a trace connection\"),TS=k_.object({type:k_.literal(\"source_missing_manufacturer_part_number_warning\"),source_missing_manufacturer_part_number_warning_id:wv(\"source_missing_manufacturer_part_number_warning\"),warning_type:k_.literal(\"source_missing_manufacturer_part_number_warning\").default(\"source_missing_manufacturer_part_number_warning\"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a standard connector is missing manufacturer part number\"),RS=k_.object({type:k_.literal(\"source_refdes_convention_warning\"),source_refdes_convention_warning_id:wv(\"source_refdes_convention_warning\"),warning_type:k_.literal(\"source_refdes_convention_warning\").default(\"source_refdes_convention_warning\"),message:k_.string(),source_component_id:k_.string(),refdes:k_.string(),source_component_ftype:k_.string(),expected_prefixes:k_.array(k_.string()),actual_prefix:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component reference designator does not match the component type convention\"),ES=Zv.extend({ftype:k_.literal(\"simple_voltage_probe\")}),AS=Zv.extend({ftype:k_.literal(\"interconnect\")}),OS=Gv.extend({type:k_.literal(\"source_i2c_misconfigured_error\"),source_i2c_misconfigured_error_id:wv(\"source_i2c_misconfigured_error\"),error_type:k_.literal(\"source_i2c_misconfigured_error\").default(\"source_i2c_misconfigured_error\"),source_port_ids:k_.array(k_.string())}).describe(\"Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net\"),kS=Gv.extend({type:k_.literal(\"source_component_misconfigured_error\"),source_component_misconfigured_error_id:wv(\"source_component_misconfigured_error\"),error_type:k_.literal(\"source_component_misconfigured_error\").default(\"source_component_misconfigured_error\"),source_component_ids:k_.array(k_.string()),source_port_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when one or more source components have an invalid or conflicting configuration\"),LS=Zv.extend({ftype:k_.literal(\"simple_voltage_source\"),voltage:uv,frequency:mv.optional(),peak_to_peak_voltage:uv.optional(),wave_shape:k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]).optional(),phase:vv.optional(),duty_cycle:k_.number().optional().describe(\"Duty cycle as a fraction (0 to 1)\"),pulse_delay:bv.optional(),rise_time:bv.optional(),fall_time:bv.optional(),pulse_width:bv.optional(),period:bv.optional()}),DS=k_.union([Jv,qv,Kv,Qv,tS,eS,nS,oS,iS,sS,cS,lS,dS,hS,uS,pS,mS,gS,fS,vS,yS,_S,bS,xS,rS,ES,AS,LS,SS,IS,PS,CS,MS,NS,wS,TS,RS,OS,kS]),zS=k_.object({type:k_.literal(\"source_port\"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(aS),FS=k_.object({type:k_.literal(\"source_component_internal_connection\"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),BS=k_.object({type:k_.literal(\"source_trace\"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),name:k_.string().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),jS=k_.object({type:k_.literal(\"source_group\"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),$S=k_.object({type:k_.literal(\"source_net\"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),YS=k_.object({type:k_.literal(\"source_board\"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe(\"Defines a board in the source domain\"),XS=Gv.extend({type:k_.literal(\"source_ambiguous_port_reference\"),source_ambiguous_port_reference_id:wv(\"source_ambiguous_port_reference\"),error_type:k_.literal(\"source_ambiguous_port_reference\").default(\"source_ambiguous_port_reference\"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous\"),VS=k_.object({type:k_.literal(\"source_pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane in the source domain\"),WS=[\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\",\"inner7\",\"inner8\"],HS=k_.enum(WS),GS=HS.or(k_.object({name:HS})).transform(t=\u003e\"string\"==typeof t?t:t.name),US=k_.enum([\"top\",\"bottom\"]),ZS=k_.object({type:k_.literal(\"source_manually_placed_via\"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe(\"Defines a via that is manually placed in the source domain\"),qS=k_.object({type:k_.literal(\"source_unnamed_trace_warning\"),source_unnamed_trace_warning_id:wv(\"source_unnamed_trace_warning\"),warning_type:k_.literal(\"source_unnamed_trace_warning\").default(\"source_unnamed_trace_warning\"),message:k_.string(),source_trace_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source trace is missing a name\"),JS=k_.object({type:k_.literal(\"source_no_power_pin_defined_warning\"),source_no_power_pin_defined_warning_id:wv(\"source_no_power_pin_defined_warning\"),warning_type:k_.literal(\"source_no_power_pin_defined_warning\").default(\"source_no_power_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports with requires_power=true\"),KS=k_.object({type:k_.literal(\"source_no_ground_pin_defined_warning\"),source_no_ground_pin_defined_warning_id:wv(\"source_no_ground_pin_defined_warning\"),warning_type:k_.literal(\"source_no_ground_pin_defined_warning\").default(\"source_no_ground_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports marked as ground pins\"),QS=k_.object({type:k_.literal(\"source_component_pins_underspecified_warning\"),source_component_pins_underspecified_warning_id:wv(\"source_component_pins_underspecified_warning\"),warning_type:k_.literal(\"source_component_pins_underspecified_warning\").default(\"source_component_pins_underspecified_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when all ports on a source component are underspecified\"),tI=Gv.extend({type:k_.literal(\"source_pin_must_be_connected_error\"),source_pin_must_be_connected_error_id:wv(\"source_pin_must_be_connected_error\"),error_type:k_.literal(\"source_pin_must_be_connected_error\").default(\"source_pin_must_be_connected_error\"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pin with mustBeConnected attribute is not connected to any trace\"),eI=Gv.extend({type:k_.literal(\"unknown_error_finding_part\"),unknown_error_finding_part_id:wv(\"unknown_error_finding_part\"),error_type:k_.literal(\"unknown_error_finding_part\").default(\"unknown_error_finding_part\"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when an unexpected error occurs while finding a part\"),nI=k_.object({type:k_.literal(\"source_part_not_found_warning\"),source_part_not_found_warning_id:wv(\"source_part_not_found_warning\"),warning_type:k_.literal(\"source_part_not_found_warning\").default(\"source_part_not_found_warning\"),message:k_.string(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:Uv.optional(),manufacturer_part_number:k_.string().optional(),supplier_part_number:k_.string().optional(),part_name:k_.string().optional()}).describe(\"Warning emitted when a requested part can not be found\"),oI=k_.object({type:k_.literal(\"schematic_box\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:gv,height:gv,is_dashed:k_.boolean().default(!1),x:gv,y:gv,subcircuit_id:k_.string().optional()}).describe(\"Draws a box on the schematic\"),iI=k_.object({type:k_.literal(\"schematic_path\"),schematic_path_id:wv(\"schematic_path\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),is_dashed:k_.boolean().default(!1),stroke_width:gv.nullable().optional(),stroke_color:k_.string().optional(),dash_length:gv.optional(),dash_gap:gv.optional(),points:k_.array(Iv),subcircuit_id:k_.string().optional()}),rI=k_.record(k_.object({left_margin:pv.optional(),right_margin:pv.optional(),top_margin:pv.optional(),bottom_margin:pv.optional()})),sI=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),aI=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional()}),cI=k_.union([sI,aI]),lI=k_.object({type:k_.literal(\"schematic_component\"),size:Nv,center:Iv,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_sheet_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),pin_spacing:pv.optional(),pin_styles:rI.optional(),box_width:pv.optional(),symbol_name:k_.string().optional(),port_arrangement:cI.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),dI=k_.object({kicad_symbol:Hv.optional()}).catchall(k_.unknown()),hI=k_.object({type:k_.literal(\"schematic_symbol\"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:dI.optional()}).describe(\"Defines a named schematic symbol that can be referenced by components.\"),uI=k_.object({type:k_.literal(\"schematic_line\"),schematic_line_id:wv(\"schematic_line\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:gv,y1:gv,x2:gv,y2:gv,stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),dash_length:gv.optional(),dash_gap:gv.optional(),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled line on the schematic\"),pI=k_.object({type:k_.literal(\"schematic_rect\"),schematic_rect_id:wv(\"schematic_rect\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,width:gv,height:gv,rotation:vv.default(0),stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled rectangle on the schematic\"),mI=k_.object({type:k_.literal(\"schematic_circle\"),schematic_circle_id:wv(\"schematic_circle\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,radius:gv,stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled circle on the schematic\"),gI=k_.object({type:k_.literal(\"schematic_arc\"),schematic_arc_id:wv(\"schematic_arc\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,radius:gv,start_angle_degrees:vv,end_angle_degrees:vv,direction:k_.enum([\"clockwise\",\"counterclockwise\"]).default(\"counterclockwise\"),stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled arc on the schematic\"),fI=k_.object({type:k_.literal(\"schematic_trace\"),schematic_trace_id:k_.string(),schematic_sheet_id:k_.string().optional(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),yI=k_.enum([\"center\",\"left\",\"right\",\"top\",\"bottom\"]),_I=k_.object({type:k_.literal(\"schematic_text\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:gv,y:gv}),rotation:k_.number().default(0),anchor:k_.union([yI.describe(\"legacy\"),Tv]).default(\"center\"),color:k_.string().default(\"#000000\"),subcircuit_id:k_.string().optional()}),bI=k_.object({type:k_.literal(\"schematic_port\"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),center:Iv,facing_direction:k_.enum([\"up\",\"down\",\"left\",\"right\"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe(\"Defines a port on a schematic component\"),xI=k_.object({type:k_.literal(\"schematic_net_label\"),schematic_net_label_id:wv(\"schematic_net_label\"),schematic_sheet_id:k_.string().optional(),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:Iv,anchor_position:Iv.optional(),anchor_side:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),vI=Gv.extend({type:k_.literal(\"schematic_error\"),schematic_error_id:k_.string(),error_type:k_.literal(\"schematic_port_not_found\").default(\"schematic_port_not_found\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic error on the schematic\"),SI=Gv.extend({type:k_.literal(\"schematic_layout_error\"),schematic_layout_error_id:wv(\"schematic_layout_error\"),error_type:k_.literal(\"schematic_layout_error\").default(\"schematic_layout_error\"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when schematic layout fails for a group\"),II=k_.object({type:k_.literal(\"schematic_debug_object\"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),CI=II.extend({shape:k_.literal(\"rect\"),center:Iv,size:Nv}),PI=II.extend({shape:k_.literal(\"line\"),start:Iv,end:Iv}),MI=II.extend({shape:k_.literal(\"point\"),center:Iv}),NI=k_.discriminatedUnion(\"shape\",[CI,PI,MI]),wI=k_.object({type:k_.literal(\"schematic_voltage_probe\"),schematic_voltage_probe_id:k_.string(),schematic_sheet_id:k_.string().optional(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:Iv,schematic_trace_id:k_.string(),voltage:uv.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:Tv.optional()}).describe(\"Defines a voltage probe measurement point on a schematic trace\"),TI=k_.object({type:k_.literal(\"schematic_manual_edit_conflict_warning\"),schematic_manual_edit_conflict_warning_id:wv(\"schematic_manual_edit_conflict_warning\"),warning_type:k_.literal(\"schematic_manual_edit_conflict_warning\").default(\"schematic_manual_edit_conflict_warning\"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit schX/schY coordinates\"),RI=k_.object({type:k_.literal(\"schematic_group\"),schematic_group_id:wv(\"schematic_group\"),schematic_sheet_id:k_.string().optional(),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:pv,height:pv,center:Iv,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe(\"Defines a group of components on the schematic\"),EI=k_.object({type:k_.literal(\"schematic_table\"),schematic_table_id:wv(\"schematic_table\"),schematic_sheet_id:k_.string().optional(),anchor_position:Iv,column_widths:k_.array(gv),row_heights:k_.array(gv),cell_padding:gv.optional(),border_width:gv.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:Tv.optional()}).describe(\"Defines a table on the schematic\"),AI=k_.object({type:k_.literal(\"schematic_table_cell\"),schematic_table_cell_id:wv(\"schematic_table_cell\"),schematic_sheet_id:k_.string().optional(),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:Iv,width:gv,height:gv,horizontal_align:k_.enum([\"left\",\"center\",\"right\"]).optional(),vertical_align:k_.enum([\"top\",\"middle\",\"bottom\"]).optional(),font_size:gv.optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a cell within a schematic_table\"),OI=k_.object({type:k_.literal(\"schematic_sheet\"),schematic_sheet_id:wv(\"schematic_sheet\"),name:k_.string().optional(),sheet_index:k_.number().optional(),subcircuit_id:k_.string().optional(),outline_color:k_.string().optional()}).describe(\"Defines a schematic sheet or page that components can be placed on\"),kI=k_.object({x:gv,y:gv,bulge:k_.number().optional()}),LI=k_.object({vertices:k_.array(kI)}),DI=k_.object({outer_ring:LI,inner_rings:k_.array(LI).default([])}),zI=k_.object({x:gv,y:gv,via:k_.boolean().optional(),via_to_layer:GS.optional()}),FI=k_.array(zI),BI=k_.object({x:gv,y:gv,via:k_.boolean().optional(),to_layer:GS.optional(),trace_width:gv.optional()}),jI=k_.object({min_trace_width:pv.optional(),min_board_edge_clearance:pv.optional(),min_via_hole_edge_to_via_hole_edge_clearance:pv.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:pv.optional(),min_trace_to_pad_edge_clearance:pv.optional(),min_pad_edge_to_pad_edge_clearance:pv.optional(),min_same_net_trace_edge_to_trace_edge_clearance:pv.optional(),min_different_net_trace_edge_to_trace_edge_clearance:pv.optional(),min_via_edge_to_pad_edge_clearance:pv.optional(),min_via_hole_diameter:pv.optional(),min_via_pad_diameter:pv.optional()}),$I=k_.object({type:k_.literal(\"pcb_component\"),pcb_component_id:wv(\"pcb_component\"),source_component_id:k_.string(),center:Iv,layer:GS,rotation:vv,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this part, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this part, usually corresponding with how the user specified it\"),width:pv,height:pv,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"relative_to_another_component\",\"none\"]).optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:Iv.optional(),insertion_direction:k_.enum([\"from_above\",\"from_left\",\"from_right\",\"from_front\",\"from_back\"]).optional(),metadata:k_.object({kicad_footprint:jv.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe(\"Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath\")}).describe(\"Defines a component on the PCB\"),YI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),hole_diameter:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),XI=YI.describe(\"Defines a circular hole on the PCB\"),VI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),WI=VI.describe(\"Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.\"),HI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"square\"]),hole_diameter:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),GI=HI.describe(\"Defines a circular or square hole on the PCB\"),UI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"oval\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),ZI=UI.describe(\"Defines an oval hole on the PCB\"),qI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),JI=qI.describe(\"Defines a pill-shaped hole on the PCB\"),KI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,ccw_rotation:vv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),QI=KI.describe(\"Defines a rotated pill-shaped hole on the PCB\"),tC=HI.or(UI).or(qI).or(KI).or(YI).or(VI),eC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),nC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.enum([\"oval\",\"pill\"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,ccw_rotation:vv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),oC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circular_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),pad_shape:k_.literal(\"rect\"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:vv.optional()}),iC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),rC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"rotated_pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:vv,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:vv,hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),sC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"hole_with_polygon_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"oval\",\"pill\",\"rotated_pill\"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:gv,y:gv})).min(3),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),ccw_rotation:vv.optional()}),aC=k_.union([eC,nC,oC,iC,rC,sC]),cC=k_.object({type:k_.literal(\"pcb_port\"),pcb_port_id:wv(\"pcb_port\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:gv,y:gv,layers:k_.array(GS),is_board_pinout:k_.boolean().optional()}).describe(\"Defines a port on the PCB\"),lC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"circle\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,radius:k_.number(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),dC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rect\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),hC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_rect\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:vv,layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),uC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"pill\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),pC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_pill\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:vv,layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),mC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"polygon\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(Iv),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),gC=k_.discriminatedUnion(\"shape\",[lC,dC,hC,pC,uC,mC]).describe(\"Defines an SMT pad on the PCB\"),fC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"circle\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,radius:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),yC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rect\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),_C=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"pill\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),bC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rotated_rect\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),ccw_rotation:gv,layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),xC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"oval\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),vC=k_.union([fC,yC,_C,bC,xC]).describe(\"Defines solderpaste on the PCB\"),SC=k_.object({type:k_.literal(\"pcb_text\"),pcb_text_id:wv(\"pcb_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:Iv,layer:GS,width:pv,height:pv,lines:k_.number(),align:k_.enum([\"bottom-left\"])}).describe(\"Defines text on the PCB\"),IC=k_.object({route_type:k_.literal(\"wire\"),x:gv,y:gv,width:gv,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:GS}),CC=k_.object({route_type:k_.literal(\"via\"),x:gv,y:gv,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:gv.optional(),outer_diameter:gv.optional(),from_layer:GS,to_layer:GS}),PC=k_.object({route_type:k_.literal(\"through_pad\"),start:Iv,end:Iv,width:gv,start_layer:GS,end_layer:GS,pcb_smtpad_id:k_.string().optional(),pcb_plated_hole_id:k_.string().optional()}),MC=k_.union([IC,CC,PC]),NC=k_.object({type:k_.literal(\"pcb_trace\"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:wv(\"pcb_trace\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum([\"constant\",\"interpolated\"]).default(\"constant\").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(MC)}).describe(\"Defines a trace on the PCB\"),wC=k_.object({type:k_.literal(\"pcb_trace_warning\"),pcb_trace_warning_id:wv(\"pcb_trace_warning\"),warning_type:k_.literal(\"pcb_trace_warning\").default(\"pcb_trace_warning\"),message:k_.string(),center:Iv.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace warning on the PCB\"),TC=k_.object({type:k_.literal(\"pcb_trace_too_long_warning\"),pcb_trace_too_long_warning_id:wv(\"pcb_trace_too_long_warning\"),warning_type:k_.literal(\"pcb_trace_too_long_warning\").default(\"pcb_trace_too_long_warning\"),message:k_.string(),pcb_trace_id:k_.string(),source_net_id:k_.string().optional(),source_trace_id:k_.string().optional(),actual_trace_length:gv,maximum_trace_length:gv,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a PCB trace is longer than its maximum allowed length\"),RC=Gv.extend({type:k_.literal(\"pcb_trace_error\"),pcb_trace_error_id:wv(\"pcb_trace_error\"),error_type:k_.literal(\"pcb_trace_error\").default(\"pcb_trace_error\"),center:Iv.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB\"),EC=Gv.extend({type:k_.literal(\"pcb_trace_missing_error\"),pcb_trace_missing_error_id:wv(\"pcb_trace_missing_error\"),error_type:k_.literal(\"pcb_trace_missing_error\").default(\"pcb_trace_missing_error\"),center:Iv.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a source trace has no corresponding PCB trace\"),AC=Gv.extend({type:k_.literal(\"pcb_port_not_matched_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_port_not_matched_error\").default(\"pcb_port_not_matched_error\"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB where a port is not matched\"),OC=Gv.extend({type:k_.literal(\"pcb_port_not_connected_error\"),pcb_port_not_connected_error_id:wv(\"pcb_port_not_connected_error\"),error_type:k_.literal(\"pcb_port_not_connected_error\").default(\"pcb_port_not_connected_error\"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a pcb port is not connected to any trace\"),kC=k_.object({type:k_.literal(\"pcb_net\"),pcb_net_id:wv(\"pcb_net\"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe(\"Defines a net on the PCB\"),LC=k_.object({type:k_.literal(\"pcb_via\"),pcb_via_id:wv(\"pcb_via\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:gv,y:gv,outer_diameter:gv.default(\"0.6mm\"),hole_diameter:gv.default(\"0.25mm\"),from_layer:GS.optional(),to_layer:GS.optional(),layers:k_.array(GS),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe(\"Defines a via on the PCB\"),DC=k_.object({type:k_.literal(\"pcb_board\"),pcb_board_id:wv(\"pcb_board\"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:pv.optional(),height:pv.optional(),center:Iv,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this board, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this board, usually corresponding with how the user specified it\"),thickness:pv.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(Iv).optional(),shape:k_.enum([\"rect\",\"polygon\"]).optional(),material:k_.enum([\"fr4\",\"fr1\"]).default(\"fr4\"),solder_mask_color:k_.string().optional(),silkscreen_color:k_.string().optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.optional(),position_mode:k_.enum([\"relative_to_panel_anchor\",\"none\"]).optional()}).merge(jI).describe(\"Defines the board outline of the PCB\"),zC=k_.object({type:k_.literal(\"pcb_panel\"),pcb_panel_id:wv(\"pcb_panel\"),width:pv,height:pv,center:Iv,thickness:pv.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe(\"Defines a PCB panel that can contain multiple boards\"),FC=Gv.extend({type:k_.literal(\"pcb_placement_error\"),pcb_placement_error_id:wv(\"pcb_placement_error\"),error_type:k_.literal(\"pcb_placement_error\").default(\"pcb_placement_error\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a placement error on the PCB\"),BC=Gv.extend({type:k_.literal(\"pcb_panelization_placement_error\"),pcb_panelization_placement_error_id:wv(\"pcb_panelization_placement_error\"),error_type:k_.literal(\"pcb_panelization_placement_error\").default(\"pcb_panelization_placement_error\"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a panelization placement error on the PCB\"),jC=k_.object({type:k_.literal(\"pcb_trace_hint\"),pcb_trace_hint_id:wv(\"pcb_trace_hint\"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(BI),subcircuit_id:k_.string().optional()}).describe(\"A hint that can be used during generation of a PCB trace\"),$C=k_.object({type:k_.literal(\"pcb_silkscreen_line\"),pcb_silkscreen_line_id:wv(\"pcb_silkscreen_line\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:gv.default(\"0.1mm\"),x1:gv,y1:gv,x2:gv,y2:gv,layer:US}).describe(\"Defines a silkscreen line on the PCB\"),YC=k_.object({type:k_.literal(\"pcb_silkscreen_path\"),pcb_silkscreen_path_id:wv(\"pcb_silkscreen_path\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,route:k_.array(Iv),stroke_width:pv}).describe(\"Defines a silkscreen path on the PCB\"),XC=k_.object({type:k_.literal(\"pcb_silkscreen_text\"),pcb_silkscreen_text_id:wv(\"pcb_silkscreen_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:pv,top:pv,bottom:pv,right:pv}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:GS,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:Tv.default(\"center\")}).describe(\"Defines silkscreen text on the PCB\"),VC=k_.object({type:k_.literal(\"pcb_copper_text\"),pcb_copper_text_id:wv(\"pcb_copper_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:pv,top:pv,bottom:pv,right:pv}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:GS,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:Tv.default(\"center\")}).describe(\"Defines copper text on the PCB\"),WC=k_.object({type:k_.literal(\"pcb_silkscreen_rect\"),pcb_silkscreen_rect_id:wv(\"pcb_silkscreen_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:GS,stroke_width:pv.default(\"1mm\"),corner_radius:pv.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen rect on the PCB\"),HC=k_.object({type:k_.literal(\"pcb_silkscreen_circle\"),pcb_silkscreen_circle_id:wv(\"pcb_silkscreen_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:pv,layer:US,stroke_width:pv.default(\"1mm\"),is_filled:k_.boolean().optional()}).describe(\"Defines a silkscreen circle on the PCB\"),GC=k_.object({type:k_.literal(\"pcb_silkscreen_oval\"),pcb_silkscreen_oval_id:wv(\"pcb_silkscreen_oval\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius_x:gv,radius_y:gv,layer:US,ccw_rotation:vv.optional()}).describe(\"Defines a silkscreen oval on the PCB\"),UC=k_.object({type:k_.literal(\"pcb_silkscreen_graphic\"),pcb_silkscreen_graphic_id:wv(\"pcb_silkscreen_graphic\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,image_asset:Ev.optional()}).extend({shape:k_.literal(\"brep\"),brep_shape:DI}).describe(\"Defines a BRep silkscreen graphic on the PCB\"),ZC=k_.discriminatedUnion(\"shape\",[UC]).describe(\"Defines a silkscreen graphic on the PCB\"),qC=k_.object({type:k_.literal(\"pcb_silkscreen_pill\"),pcb_silkscreen_pill_id:wv(\"pcb_silkscreen_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:GS,ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen pill on the PCB\"),JC=k_.object({type:k_.literal(\"pcb_fabrication_note_text\"),pcb_fabrication_note_text_id:wv(\"pcb_fabrication_note_text\"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"1mm\"),pcb_component_id:k_.string(),text:k_.string(),ccw_rotation:k_.number().optional(),layer:US,anchor_position:Iv.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),color:k_.string().optional()}).describe(\"Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators\"),KC=k_.object({type:k_.literal(\"pcb_fabrication_note_path\"),pcb_fabrication_note_path_id:wv(\"pcb_fabrication_note_path\"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:GS,route:k_.array(Iv),stroke_width:pv,color:k_.string().optional()}).describe(\"Defines a fabrication path on the PCB for fabricators or assemblers\"),QC=k_.object({type:k_.literal(\"pcb_fabrication_note_rect\"),pcb_fabrication_note_rect_id:wv(\"pcb_fabrication_note_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US,stroke_width:pv.default(\"0.1mm\"),corner_radius:pv.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a fabrication note rectangle on the PCB\"),tP=k_.object({type:k_.literal(\"pcb_fabrication_note_dimension\"),pcb_fabrication_note_dimension_id:wv(\"pcb_fabrication_note_dimension\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,from:Iv,to:Iv,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:pv.optional(),offset_distance:pv.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:pv.default(\"1mm\"),color:k_.string().optional(),arrow_size:pv.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB fabrication notes\"),eP=k_.object({type:k_.literal(\"pcb_note_text\"),pcb_note_text_id:wv(\"pcb_note_text\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"1mm\"),text:k_.string().optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),layer:US.default(\"top\"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a documentation note in text on the PCB\"),nP=k_.object({type:k_.literal(\"pcb_note_rect\"),pcb_note_rect_id:wv(\"pcb_note_rect\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US.default(\"top\"),stroke_width:pv.default(\"0.1mm\"),corner_radius:pv.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a rectangular documentation note on the PCB\"),oP=k_.object({type:k_.literal(\"pcb_note_path\"),pcb_note_path_id:wv(\"pcb_note_path\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(Iv),layer:US.default(\"top\"),stroke_width:pv.default(\"0.1mm\"),color:k_.string().optional()}).describe(\"Defines a polyline documentation note on the PCB\"),iP=k_.object({type:k_.literal(\"pcb_note_line\"),pcb_note_line_id:wv(\"pcb_note_line\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:gv,y1:gv,x2:gv,y2:gv,layer:US.default(\"top\"),stroke_width:gv.default(\"0.1mm\"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe(\"Defines a straight documentation note line on the PCB\"),rP=k_.object({type:k_.literal(\"pcb_note_dimension\"),pcb_note_dimension_id:wv(\"pcb_note_dimension\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:Iv,to:Iv,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:pv.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:pv.default(\"1mm\"),layer:US.default(\"top\"),color:k_.string().optional(),arrow_size:pv.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB documentation notes\"),sP=Gv.extend({type:k_.literal(\"pcb_footprint_overlap_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_footprint_overlap_error\").default(\"pcb_footprint_overlap_error\"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when a pcb footprint overlaps with another element\"),aP=Gv.extend({type:k_.literal(\"pcb_courtyard_overlap_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_courtyard_overlap_error\").default(\"pcb_courtyard_overlap_error\"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe(\"Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another\"),cP=k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"rect\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:gv,height:gv,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:gv,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),lP=k_.object({type:k_.literal(\"pcb_cutout\"),pcb_cutout_id:wv(\"pcb_cutout\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),dP=lP.extend({shape:k_.literal(\"rect\"),center:Iv,width:pv,height:pv,rotation:vv.optional(),corner_radius:pv.optional()}),hP=lP.extend({shape:k_.literal(\"circle\"),center:Iv,radius:pv}),uP=lP.extend({shape:k_.literal(\"polygon\"),points:k_.array(Iv)}),pP=lP.extend({shape:k_.literal(\"path\"),route:k_.array(Iv),slot_width:pv,slot_length:pv.optional(),space_between_slots:pv.optional(),slot_corner_radius:pv.optional()}),mP=k_.discriminatedUnion(\"shape\",[dP,hP,uP,pP]).describe(\"Defines a cutout on the PCB, removing board material.\"),gP=Gv.extend({type:k_.literal(\"pcb_missing_footprint_error\"),pcb_missing_footprint_error_id:wv(\"pcb_missing_footprint_error\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"pcb_missing_footprint_error\").default(\"pcb_missing_footprint_error\"),source_component_id:k_.string()}).describe(\"Defines a missing footprint error on the PCB\"),fP=Gv.extend({type:k_.literal(\"external_footprint_load_error\"),external_footprint_load_error_id:wv(\"external_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal(\"external_footprint_load_error\").default(\"external_footprint_load_error\")}).describe(\"Defines an error when an external footprint fails to load\"),yP=Gv.extend({type:k_.literal(\"circuit_json_footprint_load_error\"),circuit_json_footprint_load_error_id:wv(\"circuit_json_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"circuit_json_footprint_load_error\").default(\"circuit_json_footprint_load_error\"),circuit_json:k_.array(k_.any()).optional()}).describe(\"Defines an error when a circuit JSON footprint fails to load\"),_P=k_.object({type:k_.literal(\"pcb_group\"),pcb_group_id:wv(\"pcb_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:pv.optional(),height:pv.optional(),center:Iv,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this group, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this group, usually corresponding with how the user specified it\"),outline:k_.array(Iv).optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.default(\"center\"),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"none\"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum([\"packed\",\"none\"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:pv}).optional(),autorouter_used_string:k_.string().optional()}).describe(\"Defines a group of components on the PCB\"),bP=Gv.extend({type:k_.literal(\"pcb_autorouting_error\"),pcb_error_id:wv(\"pcb_autorouting_error\"),error_type:k_.literal(\"pcb_autorouting_error\").default(\"pcb_autorouting_error\"),subcircuit_id:k_.string().optional()}).describe(\"The autorouting has failed to route a portion of the board\"),xP=k_.object({type:k_.literal(\"pcb_manual_edit_conflict_warning\"),pcb_manual_edit_conflict_warning_id:wv(\"pcb_manual_edit_conflict_warning\"),warning_type:k_.literal(\"pcb_manual_edit_conflict_warning\").default(\"pcb_manual_edit_conflict_warning\"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates\"),vP=k_.enum([\"x-\",\"x+\",\"y+\",\"y-\"]),SP=k_.object({type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\"),pcb_connector_not_in_accessible_orientation_warning_id:wv(\"pcb_connector_not_in_accessible_orientation_warning\"),warning_type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\").default(\"pcb_connector_not_in_accessible_orientation_warning\"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:vP,recommended_facing_direction:vP,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction\"),IP=k_.object({type:k_.literal(\"supplier_footprint_mismatch_warning\"),supplier_footprint_mismatch_warning_id:wv(\"supplier_footprint_mismatch_warning\"),warning_type:k_.literal(\"supplier_footprint_mismatch_warning\").default(\"supplier_footprint_mismatch_warning\"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:Uv.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe(\"Warning emitted when a supplier part footprint does not match the expected footprint\"),CP=k_.object({type:k_.literal(\"pcb_breakout_point\"),pcb_breakout_point_id:wv(\"pcb_breakout_point\"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:gv,y:gv}).describe(\"Defines a routing target within a pcb_group for a source_trace or source_net\"),PP=k_.object({type:k_.literal(\"pcb_ground_plane\"),pcb_ground_plane_id:wv(\"pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane on the PCB\"),MP=k_.object({type:k_.literal(\"pcb_ground_plane_region\"),pcb_ground_plane_region_id:wv(\"pcb_ground_plane_region\"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:GS,points:k_.array(Iv)}).describe(\"Defines a polygon region of a ground plane\"),NP=k_.object({type:k_.literal(\"pcb_thermal_spoke\"),pcb_thermal_spoke_id:wv(\"pcb_thermal_spoke\"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:gv,spoke_inner_diameter:gv,spoke_outer_diameter:gv,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Pattern for connecting a ground plane to a plated hole\"),wP=k_.object({type:k_.literal(\"pcb_copper_pour\"),pcb_copper_pour_id:wv(\"pcb_copper_pour\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:GS,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),TP=wP.extend({shape:k_.literal(\"rect\"),center:Iv,width:pv,height:pv,rotation:vv.optional()}),RP=wP.extend({shape:k_.literal(\"brep\"),brep_shape:DI}),EP=wP.extend({shape:k_.literal(\"polygon\"),points:k_.array(Iv)}),AP=k_.discriminatedUnion(\"shape\",[TP,RP,EP]).describe(\"Defines a copper pour on the PCB.\"),OP=Gv.extend({type:k_.literal(\"pcb_component_outside_board_error\"),pcb_component_outside_board_error_id:wv(\"pcb_component_outside_board_error\"),error_type:k_.literal(\"pcb_component_outside_board_error\").default(\"pcb_component_outside_board_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Iv,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a PCB component is placed outside the board boundaries\"),kP=Gv.extend({type:k_.literal(\"pcb_component_not_on_board_edge_error\"),pcb_component_not_on_board_edge_error_id:wv(\"pcb_component_not_on_board_edge_error\"),error_type:k_.literal(\"pcb_component_not_on_board_edge_error\").default(\"pcb_component_not_on_board_edge_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Iv,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component that must be placed on the board edge is centered away from the edge\"),LP=Gv.extend({type:k_.literal(\"pcb_component_invalid_layer_error\"),pcb_component_invalid_layer_error_id:wv(\"pcb_component_invalid_layer_error\"),error_type:k_.literal(\"pcb_component_invalid_layer_error\").default(\"pcb_component_invalid_layer_error\"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:GS,subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)\"),DP=Gv.extend({type:k_.literal(\"pcb_via_clearance_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_via_clearance_error\").default(\"pcb_via_clearance_error\"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when vias are closer than the allowed clearance\"),zP=Gv.extend({type:k_.literal(\"pcb_via_trace_clearance_error\"),pcb_via_trace_clearance_error_id:wv(\"pcb_via_trace_clearance_error\"),error_type:k_.literal(\"pcb_via_trace_clearance_error\").default(\"pcb_via_trace_clearance_error\"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a via and trace are closer than the allowed clearance\"),FP=Gv.extend({type:k_.literal(\"pcb_pad_pad_clearance_error\"),pcb_pad_pad_clearance_error_id:wv(\"pcb_pad_pad_clearance_error\"),error_type:k_.literal(\"pcb_pad_pad_clearance_error\").default(\"pcb_pad_pad_clearance_error\"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when pads are closer than the allowed clearance\"),BP=Gv.extend({type:k_.literal(\"pcb_pad_trace_clearance_error\"),pcb_pad_trace_clearance_error_id:wv(\"pcb_pad_trace_clearance_error\"),error_type:k_.literal(\"pcb_pad_trace_clearance_error\").default(\"pcb_pad_trace_clearance_error\"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pad and trace are closer than allowed clearance\"),jP=k_.object({type:k_.literal(\"pcb_courtyard_rect\"),pcb_courtyard_rect_id:wv(\"pcb_courtyard_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US,ccw_rotation:vv.optional(),color:k_.string().optional()}).describe(\"Defines a courtyard rectangle on the PCB\"),$P=k_.object({type:k_.literal(\"pcb_courtyard_outline\"),pcb_courtyard_outline_id:wv(\"pcb_courtyard_outline\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,outline:k_.array(Iv).min(2)}).describe(\"Defines a courtyard outline on the PCB\"),YP=k_.object({type:k_.literal(\"pcb_courtyard_polygon\"),pcb_courtyard_polygon_id:wv(\"pcb_courtyard_polygon\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,points:k_.array(Iv).min(3),color:k_.string().optional()}).describe(\"Defines a courtyard polygon on the PCB\"),XP=k_.object({type:k_.literal(\"pcb_courtyard_circle\"),pcb_courtyard_circle_id:wv(\"pcb_courtyard_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:pv,layer:US,color:k_.string().optional()}).describe(\"Defines a courtyard circle on the PCB\"),VP=k_.object({type:k_.literal(\"pcb_courtyard_pill\"),pcb_courtyard_pill_id:wv(\"pcb_courtyard_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,radius:pv,layer:US,color:k_.string().optional()}).describe(\"Defines a courtyard pill on the PCB\"),WP=[\"obj\",\"stl\",\"3mf\",\"gltf\",\"glb\",\"step\",\"wrl\"],HP=[\"x+\",\"x-\",\"y+\",\"y-\",\"z+\",\"z-\"],GP={obj:\"z+\",stl:\"z+\",\"3mf\":\"z+\",gltf:\"y+\",glb:\"y+\",step:\"z+\",wrl:\"y+\"},UP=k_.object({type:k_.literal(\"cad_component\"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:Pv,rotation:Pv.optional(),size:Pv.optional(),layer:GS.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:Ev.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum(HP).optional().describe('The direction in the model\\'s coordinate space that is considered \"up\" or \"coming out of the board surface\"'),model_origin_position:Pv.optional(),model_origin_alignment:k_.enum([\"unknown\",\"center\",\"center_of_component_on_board_surface\",\"bottom_center_of_component\"]).optional(),model_object_fit:k_.enum([\"contain_within_bounds\",\"fill_bounds\"]).optional().default(\"contain_within_bounds\"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),show_as_bounding_box:k_.boolean().optional(),anchor_alignment:k_.enum([\"center\",\"center_of_component_on_board_surface\"]).optional().default(\"center\")}).describe(\"Defines a component on the PCB\"),ZP=k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]),qP=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),JP=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:wv(\"simulation_voltage_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:uv}).describe(\"Defines a DC voltage source for simulation\"),KP=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:wv(\"simulation_voltage_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:uv.optional(),frequency:mv.optional(),peak_to_peak_voltage:uv.optional(),wave_shape:ZP.optional(),phase:vv.optional(),duty_cycle:qP.optional(),pulse_delay:bv.optional(),rise_time:bv.optional(),fall_time:bv.optional(),pulse_width:bv.optional(),period:bv.optional()}).describe(\"Defines an AC voltage source for simulation\"),QP=k_.union([JP,KP]).describe(\"Defines a voltage source for simulation\"),tM=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),eM=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:wv(\"simulation_current_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:fv}).describe(\"Defines a DC current source for simulation\"),nM=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:wv(\"simulation_current_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:fv.optional(),frequency:mv.optional(),peak_to_peak_current:fv.optional(),wave_shape:ZP.optional(),phase:vv.optional(),duty_cycle:tM.optional()}).describe(\"Defines an AC current source for simulation\"),oM=k_.union([eM,nM]).describe(\"Defines a current source for simulation\"),iM=k_.union([k_.literal(\"spice_dc_sweep\"),k_.literal(\"spice_dc_operating_point\"),k_.literal(\"spice_transient_analysis\"),k_.literal(\"spice_ac_analysis\")]),rM=k_.object({method:k_.enum([\"trap\",\"gear\"]).optional(),reltol:k_.union([k_.number(),k_.string()]).optional(),abstol:k_.union([k_.number(),k_.string()]).optional(),vntol:k_.union([k_.number(),k_.string()]).optional()}).describe(\"SPICE solver options for a simulation experiment\"),sM=k_.object({type:k_.literal(\"simulation_experiment\"),simulation_experiment_id:wv(\"simulation_experiment\"),name:k_.string(),experiment_type:iM,time_per_step:yv.optional(),start_time_ms:bv.optional(),end_time_ms:bv.optional(),spice_options:rM.optional()}).describe(\"Defines a simulation experiment configuration\"),aM=k_.object({type:k_.literal(\"simulation_transient_voltage_graph\"),simulation_transient_voltage_graph_id:wv(\"simulation_transient_voltage_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:yv,start_time_ms:bv,end_time_ms:bv,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores voltage measurements over time for a simulation\"),cM=k_.object({type:k_.literal(\"simulation_transient_current_graph\"),simulation_transient_current_graph_id:wv(\"simulation_transient_current_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),current_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:yv,start_time_ms:bv,end_time_ms:bv,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores current measurements over time for a simulation\"),lM=k_.object({type:k_.literal(\"simulation_switch\"),simulation_switch_id:wv(\"simulation_switch\"),source_component_id:k_.string().optional(),closes_at:bv.optional(),opens_at:bv.optional(),starts_closed:k_.boolean().optional(),switching_frequency:mv.optional()}).describe(\"Defines a switch for simulation timing control\"),dM=k_.object({type:k_.literal(\"simulation_voltage_probe\"),simulation_voltage_probe_id:wv(\"simulation_voltage_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.\").superRefine((t,e)=\u003e{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n\u0026\u0026o?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a differential probe.\"}):n?t.signal_input_source_port_id\u0026\u0026t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id.\"}):o\u0026\u0026(t.signal_input_source_net_id\u0026\u0026t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id.\"}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id.\"})}),hM=k_.object({type:k_.literal(\"simulation_current_probe\"),simulation_current_probe_id:wv(\"simulation_current_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a current probe for simulation. It measures current flowing from the positive endpoint to the negative endpoint.\").superRefine((t,e)=\u003e{const n=!!t.positive_source_port_id,o=!!t.negative_source_port_id,i=!!t.positive_source_net_id,r=!!t.negative_source_net_id,s=n||o,a=i||r;s\u0026\u0026a?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a current probe.\"}):s?n\u0026\u0026o||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Current probe using source ports requires both positive_source_port_id and negative_source_port_id.\"}):a?i\u0026\u0026r||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Current probe using source nets requires both positive_source_net_id and negative_source_net_id.\"}):e.addIssue({code:k_.ZodIssueCode.custom,message:\"A current probe must have either positive/negative source port ids or positive/negative source net ids.\"})}),uM=Gv.extend({type:k_.literal(\"simulation_unknown_experiment_error\"),simulation_unknown_experiment_error_id:wv(\"simulation_unknown_experiment_error\"),error_type:k_.literal(\"simulation_unknown_experiment_error\").default(\"simulation_unknown_experiment_error\"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"An unknown error occurred during the simulation experiment.\"),pM=k_.object({type:k_.literal(\"simulation_op_amp\"),simulation_op_amp_id:wv(\"simulation_op_amp\"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe(\"Defines a simple ideal operational amplifier for simulation\"),mM=k_.object({type:k_.literal(\"simulation_spice_subcircuit\"),simulation_spice_subcircuit_id:wv(\"simulation_spice_subcircuit\"),source_component_id:k_.string(),spice_pin_to_source_port_map:k_.record(k_.string(),k_.string()),subcircuit_source:k_.string()}).describe(\"Defines a custom SPICE subcircuit model for simulation\"),gM=t=\u003evoid 0!==t,fM=k_.object({type:k_.literal(\"simulation_oscilloscope_trace\"),simulation_oscilloscope_trace_id:wv(\"simulation_oscilloscope_trace\"),simulation_transient_voltage_graph_id:k_.string().optional(),simulation_transient_current_graph_id:k_.string().optional(),simulation_voltage_probe_id:k_.string().optional(),simulation_current_probe_id:k_.string().optional(),display_name:k_.string().optional(),color:k_.string().optional(),display_center_value:k_.number().optional(),display_center_offset_divs:k_.number().optional(),volts_per_div:k_.number().positive().optional(),amps_per_div:k_.number().positive().optional()}).describe(\"Defines how a simulation measurement is rendered as an oscilloscope-style trace.\").superRefine((t,e)=\u003e{const n=[t.simulation_transient_voltage_graph_id,t.simulation_voltage_probe_id].filter(gM).length,o=[t.simulation_transient_current_graph_id,t.simulation_current_probe_id].filter(gM).length;n+o!==1\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"An oscilloscope trace must reference exactly one voltage graph, current graph, voltage probe, or current probe.\"}),n\u003e0\u0026\u0026void 0!==t.amps_per_div\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"Voltage oscilloscope traces must use volts_per_div, not amps_per_div.\"}),o\u003e0\u0026\u0026void 0!==t.volts_per_div\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"Current oscilloscope traces must use amps_per_div, not volts_per_div.\"})}),yM=k_.union([BS,zS,FS,DS,$S,jS,nS,qv,Kv,tS,Jv,oS,cS,lS,pS,gS,fS,vS,yS,_S,bS,xS,hS,dS,VS,ZS,YS,SS,PS,MS,wS,qS,TS,RS,JS,KS,QS,tI,eI,nI,OS,kS,XS,$I,tC,gP,fP,yP,xP,SP,IP,aC,cP,cC,kC,SC,NC,wC,TC,LC,gC,vC,DC,zC,_P,jC,$C,YC,XC,qC,VC,WC,HC,GC,ZC,RC,EC,FC,BC,AC,OC,DP,zP,FP,BP,KC,JC,QC,tP,eP,nP,oP,iP,rP,bP,sP,aP,CP,mP,PP,MP,NP,AP,OP,kP,LP,jP,$P,YP,XP,VP,oI,_I,uI,pI,mI,gI,lI,hI,bI,fI,iI,vI,SI,xI,NI,wI,TI,RI,OI,EI,AI,UP,QP,oM,sM,aM,cM,lM,dM,hM,fM,uM,pM,mM]),_M=yM;function bM(t,e,n){if(!e||!n)return;let o=t.get(e);o||(o=new Set,t.set(e,o)),o.add(n);let i=t.get(n);i||(i=new Set,t.set(n,i)),i.add(e)}var xM=(t,e={})=\u003e{const n=t;let o=n._internal_store;if(!o){o={counts:{},editCount:0},n._internal_store=o;for(const t of n){const e=t.type,n=t[`${e}_id`];if(!n)continue;const i=Number.parseInt(n.split(\"_\").pop());Number.isNaN(i)||(o.counts[e]=Math.max(o.counts[e]??0,i))}}const i=new Proxy({},{get:(t,r)=\u003e{if(\"toArray\"===r)return()=\u003e(n.editCount=o.editCount,n);if(\"editCount\"===r)return o.editCount;if(\"subtree\"===r)return t=\u003exM(function(t,e){if(!e.subcircuit_id\u0026\u0026!e.source_group_id)return[...t];let n=e;if(e.subcircuit_id){const o=new Set([e.subcircuit_id]),i=new Map,r=new Map;for(const e of t)if(\"source_group\"===e.type){const t=e.source_group_id,n=e.subcircuit_id;n\u0026\u0026r.set(t,n);const o=e.parent_source_group_id;o\u0026\u0026(i.has(o)||i.set(o,[]),i.get(o).push(t))}let s;for(const[t,n]of r)if(n===e.subcircuit_id){s=t;break}if(s){const t=e=\u003e{const n=i.get(e)||[];for(const e of n){const n=r.get(e);n\u0026\u0026o.add(n),t(e)}};t(s),n={...e,subcircuit_ids:Array.from(o)}}}const o=new Map;for(const e of t){const t=e[`${e.type}_id`];\"string\"==typeof t\u0026\u0026o.set(t,e)}const i=new Map;for(const e of t){const t=Object.entries(e);for(const[n,r]of t)if(\"parent_source_group_id\"!==n)if(n.endsWith(\"_id\")\u0026\u0026\"string\"==typeof r)bM(i,e,o.get(r));else if(n.endsWith(\"_ids\")\u0026\u0026Array.isArray(r))for(const t of r)\"string\"==typeof t\u0026\u0026bM(i,e,o.get(t))}const r=[],s=new Set;for(const e of t){let t=!1;(n.subcircuit_id\u0026\u0026\"subcircuit_id\"in e\u0026\u0026e.subcircuit_id===n.subcircuit_id||n.subcircuit_ids\u0026\u0026\"subcircuit_id\"in e\u0026\u0026e.subcircuit_id\u0026\u0026n.subcircuit_ids.includes(e.subcircuit_id)||n.source_group_id\u0026\u0026\"source_group_id\"in e\u0026\u0026e.source_group_id===n.source_group_id||n.source_group_id\u0026\u0026\"member_source_group_ids\"in e\u0026\u0026Array.isArray(e.member_source_group_ids)\u0026\u0026e.member_source_group_ids.includes(n.source_group_id))\u0026\u0026(t=!0),t\u0026\u0026(r.push(e),s.add(e))}for(;r.length\u003e0;){const t=r.shift(),e=i.get(t);if(e)for(const t of e)s.has(t)||(s.add(t),r.push(t))}return t.filter(t=\u003es.has(t))}(n,t),e);if(\"insert\"===r)return t=\u003e{const i=t.type;if(!i)throw new Error(\"insert requires an element with a type\");o.counts[i]??=-1,o.counts[i]++;const r=o.counts[i],s={...t,type:i,[`${i}_id`]:`${i}_${r}`};if(e.validateInserts){(S_[i]??_M).parse(s)}return n.push(s),o.editCount++,s};if(\"insertAll\"===r)return t=\u003et.map(t=\u003ei.insert(t));const s=r;return{get:t=\u003en.find(e=\u003ee.type===s\u0026\u0026e[`${s}_id`]===t),getUsing:t=\u003e{const e=Object.keys(t);if(1!==e.length)throw new Error(\"getUsing requires exactly one key, e.g. { pcb_component_id }\");const o=e[0],i=o.replace(\"_id\",\"\"),r=n.find(e=\u003ee.type===i\u0026\u0026e[o]===t[o]);return r?n.find(t=\u003et.type===s\u0026\u0026t[`${s}_id`]===r[`${s}_id`]):null},getWhere:t=\u003e{const e=Object.keys(t);return n.find(n=\u003en.type===s\u0026\u0026e.every(e=\u003en[e]===t[e]))},list:t=\u003e{const e=t?Object.keys(t):[];return n.filter(n=\u003en.type===s\u0026\u0026e.every(e=\u003en[e]===t[e]))},insert:t=\u003e{o.counts[s]??=-1,o.counts[s]++;const i=o.counts[s],r={type:s,[`${s}_id`]:`${s}_${i}`,...t};if(e.validateInserts){(S_[s]??_M).parse(r)}return n.push(r),o.editCount++,r},delete:t=\u003e{const e=n.find(e=\u003ee[`${s}_id`]===t);e\u0026\u0026(n.splice(n.indexOf(e),1),o.editCount++)},update:(t,e)=\u003e{const i=n.find(e=\u003ee.type===s\u0026\u0026e[`${s}_id`]===t);return i?(Object.assign(i,e),o.editCount++,i):null},select:t=\u003e{if(\"source_component\"===s)return n.find(e=\u003e\"source_component\"===e.type\u0026\u0026e.name===t.replace(/\\./g,\"\"));if(\"pcb_port\"===s||\"source_port\"===s||\"schematic_port\"===s){const[e,o]=t.replace(/\\./g,\"\").split(/[\\s\\\u003e]+/),i=n.find(t=\u003e\"source_component\"===t.type\u0026\u0026t.name===e);if(!i)return null;const r=n.find(t=\u003e\"source_port\"===t.type\u0026\u0026t.source_component_id===i.source_component_id\u0026\u0026(t.name===o||(t.port_hints??[]).includes(o)));if(!r)return null;if(\"source_port\"===s)return r;if(\"pcb_port\"===s)return n.find(t=\u003e\"pcb_port\"===t.type\u0026\u0026t.source_port_id===r.source_port_id);if(\"schematic_port\"===s)return n.find(t=\u003e\"schematic_port\"===t.type\u0026\u0026t.source_port_id===r.source_port_id)}}}}});return i};xM.unparsed=xM;var vM=xM;function SM(t){const e=t.type;return`${e}:${t[`${e}_id`]}`}var IM=(t,e={})=\u003e{let n=t._internal_store_indexed;if(!n){n={counts:{},editCount:0,indexes:{}};for(const e of t){const t=e.type,o=e[`${t}_id`];if(!o)continue;const i=Number.parseInt(o.split(\"_\").pop()||\"\");Number.isNaN(i)||(n.counts[t]=Math.max(n.counts[t]??0,i))}const o=e.indexConfig||{},i=n.indexes;if(o.byId\u0026\u0026(i.byId=new Map),o.byType\u0026\u0026(i.byType=new Map),o.byRelation\u0026\u0026(i.byRelation=new Map),o.bySubcircuit\u0026\u0026(i.bySubcircuit=new Map),o.byCustomField\u0026\u0026o.byCustomField.length\u003e0){i.byCustomField=new Map;for(const t of o.byCustomField)i.byCustomField.set(t,new Map)}for(const e of t){if(o.byId){const t=SM(e);i.byId.set(t,e)}if(o.byType){const t=i.byType.get(e.type)||[];t.push(e),i.byType.set(e.type,t)}if(o.byRelation){const t=Object.entries(e);for(const[n,o]of t)if(n.endsWith(\"_id\")\u0026\u0026n!==`${e.type}_id`\u0026\u0026\"string\"==typeof o){const t=i.byRelation.get(n)||new Map,r=t.get(o)||[];r.push(e),t.set(o,r),i.byRelation.set(n,t)}}if(o.bySubcircuit\u0026\u0026\"subcircuit_id\"in e){const t=e.subcircuit_id;if(t\u0026\u0026\"string\"==typeof t){const n=i.bySubcircuit.get(t)||[];n.push(e),i.bySubcircuit.set(t,n)}}if(o.byCustomField\u0026\u0026i.byCustomField)for(const t of o.byCustomField)if(t in e){const n=e[t];if(void 0!==n\u0026\u0026(\"string\"==typeof n||\"number\"==typeof n)){const o=String(n),r=i.byCustomField.get(t),s=r.get(o)||[];s.push(e),r.set(o,s)}}}t._internal_store_indexed=n}return new Proxy({},{get:(o,i)=\u003e{if(\"toArray\"===i)return()=\u003e(t.editCount=n.editCount,t);if(\"editCount\"===i)return n.editCount;const r=i;return{get:o=\u003e{const i=e.indexConfig||{};if(i.byId\u0026\u0026n.indexes.byId)return n.indexes.byId.get(`${r}:${o}`)||null;if(i.byType\u0026\u0026n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=\u003et[`${r}_id`]===o)||null}return t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===o)||null},getUsing:o=\u003e{const i=e.indexConfig||{},s=Object.keys(o);if(1!==s.length)throw new Error(\"getUsing requires exactly one key, e.g. { pcb_component_id }\");const a=s[0],c=a.replace(\"_id\",\"\");if(i.byRelation\u0026\u0026n.indexes.byRelation){const e=n.indexes.byRelation.get(a);if(e){const s=(e.get(o[a])||[]).find(t=\u003et.type===c);if(!s)return null;const l=s[`${r}_id`];if(i.byId\u0026\u0026n.indexes.byId)return n.indexes.byId.get(`${r}:${l}`)||null;if(i.byType\u0026\u0026n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=\u003et[`${r}_id`]===l)||null}return t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===l)||null}}const l=t.find(t=\u003et.type===c\u0026\u0026t[a]===o[a]);return l\u0026\u0026t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===l[`${r}_id`])||null},getWhere:o=\u003e{const i=e.indexConfig||{},s=Object.keys(o);if(1===s.length\u0026\u0026i.byCustomField\u0026\u0026n.indexes.byCustomField){const t=s[0],e=n.indexes.byCustomField.get(t);if(e){const n=String(o[t]);return(e.get(n)||[]).find(t=\u003et.type===r)||null}}if(\"subcircuit_id\"in o\u0026\u0026i.bySubcircuit\u0026\u0026n.indexes.bySubcircuit){const t=o.subcircuit_id;return(n.indexes.bySubcircuit.get(t)||[]).find(t=\u003et.type===r\u0026\u0026s.every(e=\u003et[e]===o[e]))||null}if(i.byType\u0026\u0026n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=\u003es.every(e=\u003et[e]===o[e]))||null}return t.find(t=\u003et.type===r\u0026\u0026s.every(e=\u003et[e]===o[e]))||null},list:o=\u003e{const i=e.indexConfig||{},s=o?Object.keys(o):[];if(0===s.length\u0026\u0026i.byType\u0026\u0026n.indexes.byType)return n.indexes.byType.get(r)||[];if(1===s.length\u0026\u0026\"subcircuit_id\"===s[0]\u0026\u0026i.bySubcircuit\u0026\u0026n.indexes.bySubcircuit){const t=o.subcircuit_id;return(n.indexes.bySubcircuit.get(t)||[]).filter(t=\u003et.type===r)}let a;return a=i.byType\u0026\u0026n.indexes.byType?n.indexes.byType.get(r)||[]:t.filter(t=\u003et.type===r),s.length\u003e0?a.filter(t=\u003es.every(e=\u003et[e]===o[e])):a},insert:o=\u003e{n.counts[r]??=-1,n.counts[r]++;const i=n.counts[r],s={type:r,[`${r}_id`]:`${r}_${i}`,...o};if(e.validateInserts){(S_[r]??_M).parse(s)}t.push(s),n.editCount++;const a=e.indexConfig||{};if(a.byId\u0026\u0026n.indexes.byId){const t=SM(s);n.indexes.byId.set(t,s)}if(a.byType\u0026\u0026n.indexes.byType){const t=n.indexes.byType.get(r)||[];t.push(s),n.indexes.byType.set(r,t)}if(a.byRelation\u0026\u0026n.indexes.byRelation){const t=Object.entries(s);for(const[e,o]of t)if(e.endsWith(\"_id\")\u0026\u0026e!==`${s.type}_id`\u0026\u0026\"string\"==typeof o){const t=n.indexes.byRelation.get(e)||new Map,i=t.get(o)||[];i.push(s),t.set(o,i),n.indexes.byRelation.set(e,t)}}if(a.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in s){const t=s.subcircuit_id;if(t\u0026\u0026\"string\"==typeof t){const e=n.indexes.bySubcircuit.get(t)||[];e.push(s),n.indexes.bySubcircuit.set(t,e)}}if(a.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of a.byCustomField)if(t in s){const e=s[t];if(void 0!==e\u0026\u0026(\"string\"==typeof e||\"number\"==typeof e)){const o=String(e),i=n.indexes.byCustomField.get(t),r=i.get(o)||[];r.push(s),i.set(o,r)}}return s},delete:o=\u003e{const i=e.indexConfig||{};let s;if(i.byId\u0026\u0026n.indexes.byId)s=n.indexes.byId.get(`${r}:${o}`);else if(i.byType\u0026\u0026n.indexes.byType){const t=n.indexes.byType.get(r)||[];s=t.find(t=\u003et[`${r}_id`]===o)}else s=t.find(t=\u003et[`${r}_id`]===o);if(!s)return;const a=t.indexOf(s);if(a\u003e=0\u0026\u0026(t.splice(a,1),n.editCount++),i.byId\u0026\u0026n.indexes.byId){const t=SM(s);n.indexes.byId.delete(t)}if(i.byType\u0026\u0026n.indexes.byType){const t=(n.indexes.byType.get(r)||[]).filter(t=\u003et[`${r}_id`]!==o);n.indexes.byType.set(r,t)}if(i.byRelation\u0026\u0026n.indexes.byRelation)for(const[t,e]of n.indexes.byRelation.entries())for(const[t,n]of e.entries()){const o=n.filter(t=\u003et!==s);0===o.length?e.delete(t):e.set(t,o)}if(i.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in s){const t=s.subcircuit_id;if(t){const e=(n.indexes.bySubcircuit.get(t)||[]).filter(t=\u003et!==s);0===e.length?n.indexes.bySubcircuit.delete(t):n.indexes.bySubcircuit.set(t,e)}}if(i.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of n.indexes.byCustomField.values())for(const[e,n]of t.entries()){const o=n.filter(t=\u003et!==s);0===o.length?t.delete(e):t.set(e,o)}},update:(o,i)=\u003e{const s=e.indexConfig||{};let a;if(s.byId\u0026\u0026n.indexes.byId)a=n.indexes.byId.get(`${r}:${o}`);else if(s.byType\u0026\u0026n.indexes.byType){const t=n.indexes.byType.get(r)||[];a=t.find(t=\u003et[`${r}_id`]===o)}else a=t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===o);if(!a)return null;if(s.byRelation\u0026\u0026n.indexes.byRelation){const t=Object.entries(a);for(const[e,o]of t)if(e.endsWith(\"_id\")\u0026\u0026e!==`${a.type}_id`\u0026\u0026\"string\"==typeof o\u0026\u0026e in i\u0026\u0026i[e]!==o){const t=n.indexes.byRelation.get(e);if(t){const e=(t.get(o)||[]).filter(t=\u003et!==a);0===e.length?t.delete(o):t.set(o,e)}}}if(s.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in a\u0026\u0026\"subcircuit_id\"in i){const t=a.subcircuit_id;if(t!==i.subcircuit_id){const e=(n.indexes.bySubcircuit.get(t)||[]).filter(t=\u003et!==a);0===e.length?n.indexes.bySubcircuit.delete(t):n.indexes.bySubcircuit.set(t,e)}}if(s.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of s.byCustomField)if(t in a\u0026\u0026t in i\u0026\u0026a[t]!==i[t]){const e=n.indexes.byCustomField.get(t);if(e){const n=String(a[t]),o=(e.get(n)||[]).filter(t=\u003et!==a);0===o.length?e.delete(n):e.set(n,o)}}if(Object.assign(a,i),n.editCount++,s.byRelation\u0026\u0026n.indexes.byRelation){const t=Object.entries(a);for(const[e,o]of t)if(e.endsWith(\"_id\")\u0026\u0026e!==`${a.type}_id`\u0026\u0026\"string\"==typeof o\u0026\u0026e in i){const t=n.indexes.byRelation.get(e)||new Map,i=t.get(o)||[];i.includes(a)||(i.push(a),t.set(o,i),n.indexes.byRelation.set(e,t))}}if(s.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in a\u0026\u0026\"subcircuit_id\"in i){const t=a.subcircuit_id;if(t\u0026\u0026\"string\"==typeof t){const e=n.indexes.bySubcircuit.get(t)||[];e.includes(a)||(e.push(a),n.indexes.bySubcircuit.set(t,e))}}if(s.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of s.byCustomField)if(t in a\u0026\u0026t in i){const e=a[t];if(void 0!==e\u0026\u0026(\"string\"==typeof e||\"number\"==typeof e)){const o=String(e),i=n.indexes.byCustomField.get(t),r=i.get(o)||[];r.includes(a)||(r.push(a),i.set(o,r))}}return a},select:e=\u003e{if(\"source_component\"===r)return t.find(t=\u003e\"source_component\"===t.type\u0026\u0026t.name===e.replace(/\\./g,\"\"))||null;if(\"pcb_port\"===r||\"source_port\"===r||\"schematic_port\"===r){const[n,o]=e.replace(/\\./g,\"\").split(/[\\s\\\u003e]+/),i=t.find(t=\u003e\"source_component\"===t.type\u0026\u0026t.name===n);if(!i)return null;const s=t.find(t=\u003e\"source_port\"===t.type\u0026\u0026t.source_component_id===i.source_component_id\u0026\u0026(t.name===o||(t.port_hints??[]).includes(o)));if(!s)return null;if(\"source_port\"===r)return s;if(\"pcb_port\"===r)return t.find(t=\u003e\"pcb_port\"===t.type\u0026\u0026t.source_port_id===s.source_port_id)||null;if(\"schematic_port\"===r)return t.find(t=\u003e\"schematic_port\"===t.type\u0026\u0026t.source_port_id===s.source_port_id)||null}return null}}}})};IM.unparsed=IM;var CM=t=\u003et[`${t.type}_id`];function PM(t,e){const n=xM(t).pcb_trace.get(e);if(!n)return`trace[${e}]`;const o=n.route.flatMap(t=\u003e[t.start_pcb_port_id,t.end_pcb_port_id]).filter(Boolean);if(0===o.length)return`trace[${e}]`;return`trace[${o.map(e=\u003e{const n=function(e){const n=xM(t).pcb_port.get(e);if(!n)return null;const o=n.pcb_component_id?xM(t).pcb_component.get(n.pcb_component_id):void 0;if(!o)return null;const i=xM(t).source_component.get(o.source_component_id);if(!i)return null;const r=xM(t).source_port.get(n.source_port_id),s=r?.port_hints?r.port_hints[1]:\"\";return{componentName:i.name,portHint:s}}(e);return n?`.${n.componentName} \u003e port.${n.portHint}`:`port[${e}]`}).join(\", \")}]`}var MM=(t,e)=\u003e{const n=xM(t).pcb_port.get(e);if(!n)return`pcb_port[#${e}]`;const o=n.pcb_component_id?xM(t).pcb_component.get(n.pcb_component_id):void 0;if(!o)return`pcb_port[#${e}]`;const i=xM(t).source_component.get(o.source_component_id);if(!i)return`pcb_port[#${e}]`;const r=xM(t).source_port.get(n.source_port_id);if(!r)return`pcb_port[#${e}]`;let s;return s=r?.port_hints\u0026\u0026r.port_hints.length\u003e0||r.port_hints\u0026\u0026r.port_hints.length\u003e0?r.port_hints[0]:e,`pcb_port[.${i.name} \u003e .${s}]`};var NM=(t,e)=\u003e{if(\"string\"==typeof e){const n=((t,e)=\u003et.find(t=\u003eCM(t)===e)??null)(t,e);return NM(t,n)}switch(e.type){case\"pcb_port\":return MM(t,e.pcb_port_id);case\"pcb_smtpad\":return function(t,e){const n=xM(t).pcb_smtpad.get(e);return n\u0026\u0026n.pcb_port_id?MM(t,n.pcb_port_id):`smtpad[${e}]`}(t,e.pcb_smtpad_id);case\"pcb_trace\":return PM(t,e.pcb_trace_id);case\"source_component\":return`source_component[${e.name}]`;default:return`${e.type}[#${CM(e)}]`}},wM=(t,e)=\u003e({minX:Math.min(t.minX,e.minX),minY:Math.min(t.minY,e.minY),maxX:Math.max(t.maxX,e.maxX),maxY:Math.max(t.maxY,e.maxY)}),TM=(t,e,n)=\u003e{const o=n/2;return{minX:t-o,minY:e-o,maxX:t+o,maxY:e+o}},RM=(t,e,n,o,i)=\u003e{const r=n/2,s=o/2,a=i*Math.PI/180,c=Math.cos(a),l=Math.sin(a),d=[{x:-r,y:-s},{x:r,y:-s},{x:r,y:s},{x:-r,y:s}].map(n=\u003e({x:t+n.x*c-n.y*l,y:e+n.x*l+n.y*c}));return{minX:Math.min(...d.map(t=\u003et.x)),minY:Math.min(...d.map(t=\u003et.y)),maxX:Math.max(...d.map(t=\u003et.x)),maxY:Math.max(...d.map(t=\u003et.y))}},EM=t=\u003e{let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t){if(!r.type.startsWith(\"pcb_\"))continue;if(\"pcb_smtpad\"===r.type\u0026\u0026\"polygon\"===r.shape\u0026\u0026Array.isArray(r.points)){for(const t of r.points)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);continue}if(\"pcb_hole\"===r.type\u0026\u0026\"circle\"===r.hole_shape){const t=TM(r.x,r.y,r.hole_diameter);e=Math.min(e,t.minX),n=Math.min(n,t.minY),o=Math.max(o,t.maxX),i=Math.max(i,t.maxY);continue}if(\"pcb_plated_hole\"===r.type){let t;if(\"outer_diameter\"in r\u0026\u0026\"number\"==typeof r.outer_diameter?t=TM(r.x,r.y,r.outer_diameter):\"hole_diameter\"in r\u0026\u0026\"number\"==typeof r.hole_diameter\u0026\u0026(t=TM(r.x,r.y,r.hole_diameter)),\"rect_pad_width\"in r\u0026\u0026\"number\"==typeof r.rect_pad_width\u0026\u0026\"rect_pad_height\"in r\u0026\u0026\"number\"==typeof r.rect_pad_height){const e=RM(r.x,r.y,r.rect_pad_width,r.rect_pad_height,\"rect_ccw_rotation\"in r?r.rect_ccw_rotation??0:0);t=t?wM(t,e):e}if(\"hole_diameter\"in r\u0026\u0026\"number\"==typeof r.hole_diameter){const e=TM(r.x+(\"hole_offset_x\"in r?r.hole_offset_x??0:0),r.y+(\"hole_offset_y\"in r?r.hole_offset_y??0:0),r.hole_diameter);t=t?wM(t,e):e}if(t){e=Math.min(e,t.minX),n=Math.min(n,t.minY),o=Math.max(o,t.maxX),i=Math.max(i,t.maxY);continue}}let t,s,a,c;if(\"x\"in r\u0026\u0026\"y\"in r\u0026\u0026(t=Number(r.x),s=Number(r.y)),\"outer_diameter\"in r\u0026\u0026(a=Number(r.outer_diameter),c=Number(r.outer_diameter)),\"width\"in r\u0026\u0026(a=Number(r.width)),\"height\"in r\u0026\u0026(c=Number(r.height)),\"center\"in r\u0026\u0026(t=r.center.x,s=r.center.y),void 0!==t\u0026\u0026void 0!==s)e=Math.min(e,t),n=Math.min(n,s),o=Math.max(o,t),i=Math.max(i,s),void 0!==a\u0026\u0026void 0!==c\u0026\u0026(e=Math.min(e,t-a/2),n=Math.min(n,s-c/2),o=Math.max(o,t+a/2),i=Math.max(i,s+c/2)),\"radius\"in r\u0026\u0026(e=Math.min(e,t-r.radius),n=Math.min(n,s-r.radius),o=Math.max(o,t+r.radius),i=Math.max(i,s+r.radius));else if(\"pcb_trace\"===r.type)for(const t of r.route)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);else if(\"pcb_courtyard_outline\"===r.type)for(const t of r.outline)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);else if(\"pcb_courtyard_polygon\"===r.type)for(const t of r.points)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y)}return{minX:e,minY:n,maxX:o,maxY:i}},AM=t=\u003et[`${t.type}_id`],OM={Hz:{baseUnit:\"Hz\",variants:{MHz:1e6,kHz:1e3,Hz:1}},g:{baseUnit:\"g\",variants:{kg:1e3,g:1}},\"Ω\":{baseUnit:\"Ω\",variants:{\"mΩ\":.001,\"Ω\":1,\"kΩ\":1e3,\"KΩ\":1e3,kohm:1e3,\"MΩ\":1e6,\"GΩ\":1e9,\"TΩ\":1e12}},V:{baseUnit:\"V\",variants:{mV:.001,V:1,kV:1e3,KV:1e3,MV:1e6,GV:1e9,TV:1e12}},A:{baseUnit:\"A\",variants:{\"µA\":1e-6,mA:.001,ma:.001,A:1,kA:1e3,MA:1e6}},F:{baseUnit:\"F\",variants:{pF:1e-12,nF:1e-9,\"µF\":1e-6,uF:1e-6,mF:.001,F:1}},ml:{baseUnit:\"ml\",variants:{ml:1,mL:1,l:1e3,L:1e3}},deg:{baseUnit:\"deg\",variants:{rad:180/Math.PI}},ms:{baseUnit:\"ms\",variants:{fs:1e-12,ps:1e-9,ns:1e-6,us:.001,\"µs\":.001,ms:1,s:1e3}},mm:{baseUnit:\"mm\",variants:{nm:1e-6,\"µm\":.001,um:.001,mm:1,cm:10,dm:100,m:1e3,km:1e6,in:25.4,ft:304.8,IN:25.4,FT:304.8,yd:914.4,mi:1609344,mil:.0254}}},kM=new Set;for(const[t,e]of Object.entries(OM)){kM.add(t);for(const t of Object.keys(e.variants))kM.add(t)}var LM={tera:1e12,T:1e12,giga:1e9,G:1e9,mega:1e6,M:1e6,kilo:1e3,k:1e3,deci:.1,d:.1,centi:.01,c:.01,milli:.001,m:.001,micro:1e-6,u:1e-6,\"µ\":1e-6,nano:1e-9,n:1e-9,pico:1e-12,p:1e-12};function DM(t){if(null==t)return{parsedUnit:null,unitOfValue:null,value:null};if(\"string\"==typeof t\u0026\u0026t.match(/^-?[\\d\\.]+$/))return{value:Number.parseFloat(t),parsedUnit:null,unitOfValue:null};if(\"number\"==typeof t)return{value:t,parsedUnit:null,unitOfValue:null};if(\"object\"==typeof t\u0026\u0026\"x\"in t\u0026\u0026\"y\"in t){const{parsedUnit:e,unitOfValue:n}=DM(t.x),o=DM(t.x),i=DM(t.y);return null===o.value||null===i.value?{parsedUnit:null,unitOfValue:null,value:null}:{parsedUnit:e,unitOfValue:n,value:{x:o.value,y:i.value}}}const e=t.toString().split(\"\").reverse().join(\"\"),n=e.match(/[^\\d\\s]+/)?.[0];if(!n)throw new Error(`Could not determine unit: \"${t}\"`);const o=n.split(\"\").reverse().join(\"\"),i=t.slice(0,-o.length);if(o in LM\u0026\u0026!kM.has(o)){const t=LM[o];return{parsedUnit:null,unitOfValue:null,value:Number.parseFloat(i)*t}}const{baseUnit:r,conversionFactor:s}=function(t){for(const[e,n]of Object.entries(OM))if(t in n.variants)return{baseUnit:n.baseUnit,conversionFactor:n.variants[t]};return{baseUnit:t,conversionFactor:1}}(o);return{parsedUnit:o,unitOfValue:r,value:s*Number.parseFloat(i)}}var zM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),FM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value).transform(t=\u003eNumber.parseFloat(t.toPrecision(12))),BM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),jM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),$M=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),YM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),XM=$M,VM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),WM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),HM=WM,GM=k_.string().datetime(),UM=k_.string().or(k_.number()).transform(t=\u003e\"number\"==typeof t?t:t.endsWith(\"deg\")?Number.parseFloat(t.split(\"deg\")[0]):t.endsWith(\"rad\")?180*Number.parseFloat(t.split(\"rad\")[0])/Math.PI:Number.parseFloat(t)),ZM=k_.number().or(k_.string().endsWith(\"mAh\")).transform(t=\u003e{if(\"string\"==typeof t){const e=t.replace(\"mAh\",\"\"),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error(\"Invalid capacity\");return n}return t}).describe(\"Battery capacity in mAh\"),qM=k_.object({x:XM,y:XM}),JM=k_.object({x:XM,y:XM,z:XM}),KM=k_.object({width:k_.number(),height:k_.number()}),QM=t=\u003ek_.string().optional().default(()=\u003e`${t}_${(t=\u003e{const e=\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";return Array.from({length:t},()=\u003ee[Math.floor(62*Math.random())]).join(\"\")})(10)}`),tN=k_.enum([\"top_left\",\"top_center\",\"top_right\",\"center_left\",\"center\",\"center_right\",\"bottom_left\",\"bottom_center\",\"bottom_right\"]),eN=(k_.enum([\"top_silkscreen\",\"bottom_silkscreen\",\"top_copper\",\"bottom_copper\",\"top_soldermask\",\"bottom_soldermask\",\"top_fabrication_note\",\"bottom_fabrication_note\",\"top_user_note\",\"bottom_user_note\",\"top_courtyard\",\"bottom_courtyard\",\"inner1_copper\",\"inner2_copper\",\"inner3_copper\",\"inner4_copper\",\"inner5_copper\",\"inner6_copper\",\"edge_cuts\",\"drill\"]),k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()})),nN=qM.extend({rotation:UM.optional()}),oN=k_.object({size:qM.optional(),thickness:XM.optional()}),iN=k_.object({font:oN.optional()}),rN=k_.object({value:k_.string(),at:nN.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:iN.optional()}),sN=k_.object({Reference:rN.optional(),Value:rN.optional(),Datasheet:rN.optional(),Description:rN.optional()}),aN=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),cN=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:nN.optional(),size:qM.optional(),drill:XM.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),lN=k_.object({path:k_.string(),offset:JM.optional(),scale:JM.optional(),rotate:JM.optional()}),dN=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:sN.optional(),attributes:aN.optional(),pads:k_.array(cN).optional(),embeddedFonts:k_.boolean().optional(),model:lN.optional()}),hN=k_.object({hide:k_.boolean().optional()}),uN=k_.object({offset:XM.optional(),hide:k_.boolean().optional()}),pN=k_.object({font:oN.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),mN=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:nN.optional(),effects:pN.optional()}),gN=k_.object({Reference:mN.optional(),Value:mN.optional(),Footprint:mN.optional(),Datasheet:mN.optional(),Description:mN.optional(),ki_keywords:mN.optional(),ki_fp_filters:mN.optional()}),fN=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:hN.optional(),pinNames:uN.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:gN.optional(),embeddedFonts:k_.boolean().optional()}),yN=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),_N=k_.enum([\"jlcpcb\",\"macrofab\",\"pcbway\",\"digikey\",\"mouser\",\"lcsc\"]),bN=k_.object({type:k_.literal(\"source_component\"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(_N,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),xN=bN.extend({ftype:k_.literal(\"simple_capacitor\"),capacitance:FM,max_voltage_rating:jM.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:XM.optional()}),vN=bN.extend({ftype:k_.literal(\"simple_resistor\"),resistance:zM,display_resistance:k_.string().optional()}),SN=bN.extend({ftype:k_.literal(\"simple_diode\")}),IN=bN.extend({ftype:k_.literal(\"simple_fiducial\")}),CN=SN.extend({ftype:k_.literal(\"simple_led\"),color:k_.string().optional(),wavelength:k_.string().optional()}),PN=bN.extend({ftype:k_.literal(\"simple_ground\")}),MN=bN.extend({ftype:k_.literal(\"simple_chip\")}),NN=bN.extend({ftype:k_.literal(\"simple_power_source\"),voltage:jM}),wN=bN.extend({ftype:k_.literal(\"simple_current_source\"),current:VM,frequency:YM.optional(),peak_to_peak_current:VM.optional(),wave_shape:k_.enum([\"sine\",\"square\",\"triangle\",\"sawtooth\",\"dc\"]).optional().default(\"dc\"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),TN=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),RN=bN.extend({ftype:k_.literal(\"simple_fuse\"),current_rating_amps:k_.number().describe(\"Nominal current in amps the fuse is rated for\"),voltage_rating_volts:k_.number().describe(\"Voltage rating in volts, e.g. ±5V would be 5\")}),EN=bN.extend({ftype:k_.literal(\"simple_battery\"),capacity:ZM}),AN=bN.extend({ftype:k_.literal(\"simple_inductor\"),inductance:BM,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),ON=bN.extend({ftype:k_.literal(\"simple_push_button\")}),kN=bN.extend({ftype:k_.literal(\"simple_potentiometer\"),max_resistance:zM,display_max_resistance:k_.string().optional()}),LN=bN.extend({ftype:k_.literal(\"simple_crystal\"),frequency:k_.number().describe(\"Frequency in Hz\"),load_capacitance:k_.number().optional().describe(\"Load capacitance in pF\"),pin_variant:k_.enum([\"two_pin\",\"four_pin\"]).optional()}),DN=bN.extend({ftype:k_.literal(\"simple_pin_header\"),pin_count:k_.number(),gender:k_.enum([\"male\",\"female\"]).optional().default(\"male\")}),zN=bN.extend({ftype:k_.literal(\"simple_connector\"),standard:k_.enum([\"usb_c\",\"m2\"]).optional()}),FN=bN.extend({ftype:k_.literal(\"simple_pinout\")}),BN=bN.extend({ftype:k_.literal(\"simple_resonator\"),load_capacitance:FM,equivalent_series_resistance:zM.optional(),frequency:YM}),jN=bN.extend({ftype:k_.literal(\"simple_transistor\"),transistor_type:k_.enum([\"npn\",\"pnp\"])}),$N=bN.extend({ftype:k_.literal(\"simple_test_point\"),footprint_variant:k_.enum([\"pad\",\"through_hole\"]).optional(),pad_shape:k_.enum([\"rect\",\"circle\"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),YN=bN.extend({ftype:k_.literal(\"simple_mosfet\"),channel_type:k_.enum([\"n\",\"p\"]),mosfet_mode:k_.enum([\"enhancement\",\"depletion\"])}),XN=bN.extend({ftype:k_.literal(\"simple_op_amp\")}),VN=bN.extend({ftype:k_.literal(\"simple_switch\")}),WN=k_.object({type:k_.literal(\"source_project_metadata\"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),created_at:GM.optional()}),HN=yN.extend({type:k_.literal(\"source_missing_property_error\"),source_missing_property_error_id:QM(\"source_missing_property_error\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_missing_property_error\").default(\"source_missing_property_error\")}).describe(\"The source code is missing a property\"),GN=yN.extend({type:k_.literal(\"source_failed_to_create_component_error\"),source_failed_to_create_component_error_id:QM(\"source_failed_to_create_component_error\"),error_type:k_.literal(\"source_failed_to_create_component_error\").default(\"source_failed_to_create_component_error\"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe(\"Error emitted when a component fails to be constructed\"),UN=yN.extend({type:k_.literal(\"source_invalid_component_property_error\"),source_invalid_component_property_error_id:QM(\"source_invalid_component_property_error\"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_invalid_component_property_error\").default(\"source_invalid_component_property_error\")}).describe(\"The source component property is invalid\"),ZN=yN.extend({type:k_.literal(\"source_trace_not_connected_error\"),source_trace_not_connected_error_id:QM(\"source_trace_not_connected_error\"),error_type:k_.literal(\"source_trace_not_connected_error\").default(\"source_trace_not_connected_error\"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe(\"Occurs when a source trace selector does not match any ports\"),qN=k_.object({type:k_.literal(\"source_property_ignored_warning\"),source_property_ignored_warning_id:QM(\"source_property_ignored_warning\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_property_ignored_warning\").default(\"source_property_ignored_warning\"),message:k_.string()}).describe(\"The source property was ignored\"),JN=k_.object({type:k_.literal(\"source_pin_missing_trace_warning\"),source_pin_missing_trace_warning_id:QM(\"source_pin_missing_trace_warning\"),warning_type:k_.literal(\"source_pin_missing_trace_warning\").default(\"source_pin_missing_trace_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component pin is missing a trace connection\"),KN=k_.object({type:k_.literal(\"source_missing_manufacturer_part_number_warning\"),source_missing_manufacturer_part_number_warning_id:QM(\"source_missing_manufacturer_part_number_warning\"),warning_type:k_.literal(\"source_missing_manufacturer_part_number_warning\").default(\"source_missing_manufacturer_part_number_warning\"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a standard connector is missing manufacturer part number\"),QN=bN.extend({ftype:k_.literal(\"simple_voltage_probe\")}),tw=bN.extend({ftype:k_.literal(\"interconnect\")}),ew=yN.extend({type:k_.literal(\"source_i2c_misconfigured_error\"),source_i2c_misconfigured_error_id:QM(\"source_i2c_misconfigured_error\"),error_type:k_.literal(\"source_i2c_misconfigured_error\").default(\"source_i2c_misconfigured_error\"),source_port_ids:k_.array(k_.string())}).describe(\"Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net\"),nw=bN.extend({ftype:k_.literal(\"simple_voltage_source\"),voltage:jM,frequency:YM.optional(),peak_to_peak_voltage:jM.optional(),wave_shape:k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]).optional(),phase:UM.optional(),duty_cycle:k_.number().optional().describe(\"Duty cycle as a fraction (0 to 1)\")}),ow=k_.union([vN,xN,SN,IN,CN,PN,MN,NN,wN,EN,AN,ON,kN,LN,DN,zN,FN,BN,VN,jN,$N,YN,XN,RN,QN,tw,nw,WN,HN,UN,GN,ZN,qN,JN,KN,ew]),iw=k_.object({type:k_.literal(\"source_port\"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(TN),rw=k_.object({type:k_.literal(\"source_component_internal_connection\"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),sw=k_.object({type:k_.literal(\"source_trace\"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),aw=k_.object({type:k_.literal(\"source_group\"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),cw=k_.object({type:k_.literal(\"source_net\"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),lw=k_.object({type:k_.literal(\"source_board\"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe(\"Defines a board in the source domain\"),dw=yN.extend({type:k_.literal(\"source_ambiguous_port_reference\"),source_ambiguous_port_reference_id:QM(\"source_ambiguous_port_reference\"),error_type:k_.literal(\"source_ambiguous_port_reference\").default(\"source_ambiguous_port_reference\"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous\"),hw=k_.object({type:k_.literal(\"source_pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane in the source domain\"),uw=[\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\"],pw=k_.enum(uw),mw=pw.or(k_.object({name:pw})).transform(t=\u003e\"string\"==typeof t?t:t.name),gw=k_.enum([\"top\",\"bottom\"]),fw=k_.object({type:k_.literal(\"source_manually_placed_via\"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe(\"Defines a via that is manually placed in the source domain\"),yw=k_.object({type:k_.literal(\"source_no_power_pin_defined_warning\"),source_no_power_pin_defined_warning_id:QM(\"source_no_power_pin_defined_warning\"),warning_type:k_.literal(\"source_no_power_pin_defined_warning\").default(\"source_no_power_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports with requires_power=true\"),_w=k_.object({type:k_.literal(\"source_no_ground_pin_defined_warning\"),source_no_ground_pin_defined_warning_id:QM(\"source_no_ground_pin_defined_warning\"),warning_type:k_.literal(\"source_no_ground_pin_defined_warning\").default(\"source_no_ground_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports marked as ground pins\"),bw=k_.object({type:k_.literal(\"source_component_pins_underspecified_warning\"),source_component_pins_underspecified_warning_id:QM(\"source_component_pins_underspecified_warning\"),warning_type:k_.literal(\"source_component_pins_underspecified_warning\").default(\"source_component_pins_underspecified_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when all ports on a source component are underspecified\"),xw=yN.extend({type:k_.literal(\"source_pin_must_be_connected_error\"),source_pin_must_be_connected_error_id:QM(\"source_pin_must_be_connected_error\"),error_type:k_.literal(\"source_pin_must_be_connected_error\").default(\"source_pin_must_be_connected_error\"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pin with mustBeConnected attribute is not connected to any trace\"),vw=yN.extend({type:k_.literal(\"unknown_error_finding_part\"),unknown_error_finding_part_id:QM(\"unknown_error_finding_part\"),error_type:k_.literal(\"unknown_error_finding_part\").default(\"unknown_error_finding_part\"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when an unexpected error occurs while finding a part\"),Sw=k_.object({type:k_.literal(\"schematic_box\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:XM,height:XM,is_dashed:k_.boolean().default(!1),x:XM,y:XM,subcircuit_id:k_.string().optional()}).describe(\"Draws a box on the schematic\"),Iw=k_.object({type:k_.literal(\"schematic_path\"),schematic_path_id:QM(\"schematic_path\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),stroke_width:XM.nullable().optional(),stroke_color:k_.string().optional(),points:k_.array(qM),subcircuit_id:k_.string().optional()}),Cw=k_.record(k_.object({left_margin:$M.optional(),right_margin:$M.optional(),top_margin:$M.optional(),bottom_margin:$M.optional()})),Pw=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),Mw=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional()}),Nw=k_.union([Pw,Mw]),ww=k_.object({type:k_.literal(\"schematic_component\"),size:KM,center:qM,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_symbol_id:k_.string().optional(),pin_spacing:$M.optional(),pin_styles:Cw.optional(),box_width:$M.optional(),symbol_name:k_.string().optional(),port_arrangement:Nw.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),Tw=k_.object({kicad_symbol:fN.optional()}).catchall(k_.unknown()),Rw=k_.object({type:k_.literal(\"schematic_symbol\"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:Tw.optional()}).describe(\"Defines a named schematic symbol that can be referenced by components.\"),Ew=k_.object({type:k_.literal(\"schematic_line\"),schematic_line_id:QM(\"schematic_line\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:XM,y1:XM,x2:XM,y2:XM,stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled line on the schematic\"),Aw=k_.object({type:k_.literal(\"schematic_rect\"),schematic_rect_id:QM(\"schematic_rect\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,width:XM,height:XM,rotation:UM.default(0),stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled rectangle on the schematic\"),Ow=k_.object({type:k_.literal(\"schematic_circle\"),schematic_circle_id:QM(\"schematic_circle\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,radius:XM,stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled circle on the schematic\"),kw=k_.object({type:k_.literal(\"schematic_arc\"),schematic_arc_id:QM(\"schematic_arc\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,radius:XM,start_angle_degrees:UM,end_angle_degrees:UM,direction:k_.enum([\"clockwise\",\"counterclockwise\"]).default(\"counterclockwise\"),stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled arc on the schematic\"),Lw=k_.object({type:k_.literal(\"schematic_trace\"),schematic_trace_id:k_.string(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),Dw=k_.enum([\"center\",\"left\",\"right\",\"top\",\"bottom\"]),zw=k_.object({type:k_.literal(\"schematic_text\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:XM,y:XM}),rotation:k_.number().default(0),anchor:k_.union([Dw.describe(\"legacy\"),tN]).default(\"center\"),color:k_.string().default(\"#000000\"),subcircuit_id:k_.string().optional()}),Fw=k_.object({type:k_.literal(\"schematic_port\"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_component_id:k_.string().optional(),center:qM,facing_direction:k_.enum([\"up\",\"down\",\"left\",\"right\"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe(\"Defines a port on a schematic component\"),Bw=k_.object({type:k_.literal(\"schematic_net_label\"),schematic_net_label_id:QM(\"schematic_net_label\"),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:qM,anchor_position:qM.optional(),anchor_side:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),jw=yN.extend({type:k_.literal(\"schematic_error\"),schematic_error_id:k_.string(),error_type:k_.literal(\"schematic_port_not_found\").default(\"schematic_port_not_found\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic error on the schematic\"),$w=yN.extend({type:k_.literal(\"schematic_layout_error\"),schematic_layout_error_id:QM(\"schematic_layout_error\"),error_type:k_.literal(\"schematic_layout_error\").default(\"schematic_layout_error\"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when schematic layout fails for a group\"),Yw=k_.object({type:k_.literal(\"schematic_debug_object\"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),Xw=Yw.extend({shape:k_.literal(\"rect\"),center:qM,size:KM}),Vw=Yw.extend({shape:k_.literal(\"line\"),start:qM,end:qM}),Ww=Yw.extend({shape:k_.literal(\"point\"),center:qM}),Hw=k_.discriminatedUnion(\"shape\",[Xw,Vw,Ww]),Gw=k_.object({type:k_.literal(\"schematic_voltage_probe\"),schematic_voltage_probe_id:k_.string(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:qM,schematic_trace_id:k_.string(),voltage:jM.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:tN.optional()}).describe(\"Defines a voltage probe measurement point on a schematic trace\"),Uw=k_.object({type:k_.literal(\"schematic_manual_edit_conflict_warning\"),schematic_manual_edit_conflict_warning_id:QM(\"schematic_manual_edit_conflict_warning\"),warning_type:k_.literal(\"schematic_manual_edit_conflict_warning\").default(\"schematic_manual_edit_conflict_warning\"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit schX/schY coordinates\"),Zw=k_.object({type:k_.literal(\"schematic_group\"),schematic_group_id:QM(\"schematic_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:$M,height:$M,center:qM,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe(\"Defines a group of components on the schematic\"),qw=k_.object({type:k_.literal(\"schematic_table\"),schematic_table_id:QM(\"schematic_table\"),anchor_position:qM,column_widths:k_.array(XM),row_heights:k_.array(XM),cell_padding:XM.optional(),border_width:XM.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:tN.optional()}).describe(\"Defines a table on the schematic\"),Jw=k_.object({type:k_.literal(\"schematic_table_cell\"),schematic_table_cell_id:QM(\"schematic_table_cell\"),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:qM,width:XM,height:XM,horizontal_align:k_.enum([\"left\",\"center\",\"right\"]).optional(),vertical_align:k_.enum([\"top\",\"middle\",\"bottom\"]).optional(),font_size:XM.optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a cell within a schematic_table\"),Kw=k_.object({type:k_.literal(\"schematic_sheet\"),schematic_sheet_id:QM(\"schematic_sheet\"),name:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic sheet or page that components can be placed on\"),Qw=k_.object({x:XM,y:XM,bulge:k_.number().optional()}),tT=k_.object({vertices:k_.array(Qw)}),eT=k_.object({outer_ring:tT,inner_rings:k_.array(tT).default([])}),nT=k_.object({x:XM,y:XM,via:k_.boolean().optional(),via_to_layer:mw.optional()}),oT=(k_.array(nT),k_.object({x:XM,y:XM,via:k_.boolean().optional(),to_layer:mw.optional(),trace_width:XM.optional()})),iT=k_.object({min_trace_width:$M.optional(),min_board_edge_clearance:$M.optional(),min_via_hole_edge_to_via_hole_edge_clearance:$M.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:$M.optional(),min_trace_to_pad_edge_clearance:$M.optional(),min_pad_edge_to_pad_edge_clearance:$M.optional(),min_same_net_trace_edge_to_trace_edge_clearance:$M.optional(),min_different_net_trace_edge_to_trace_edge_clearance:$M.optional(),min_via_hole_diameter:$M.optional(),min_via_pad_diameter:$M.optional()}),rT=k_.object({type:k_.literal(\"pcb_component\"),pcb_component_id:QM(\"pcb_component\"),source_component_id:k_.string(),center:qM,layer:mw,rotation:UM,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this part, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this part, usually corresponding with how the user specified it\"),width:$M,height:$M,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"relative_to_another_component\",\"none\"]).optional(),anchor_position:qM.optional(),anchor_alignment:tN.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:qM.optional(),insertion_direction:k_.enum([\"from_above\",\"from_left\",\"from_right\",\"from_front\",\"from_back\"]).optional(),metadata:k_.object({kicad_footprint:dN.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe(\"Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath\")}).describe(\"Defines a component on the PCB\"),sT=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),hole_diameter:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),aT=(sT.describe(\"Defines a circular hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),cT=(aT.describe(\"Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"square\"]),hole_diameter:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),lT=(cT.describe(\"Defines a circular or square hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"oval\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),dT=(lT.describe(\"Defines an oval hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),hT=(dT.describe(\"Defines a pill-shaped hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,ccw_rotation:UM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),uT=(hT.describe(\"Defines a rotated pill-shaped hole on the PCB\"),cT.or(lT).or(dT).or(hT).or(sT).or(aT)),pT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),mT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.enum([\"oval\",\"pill\"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,ccw_rotation:UM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),gT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circular_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),pad_shape:k_.literal(\"rect\"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:UM.optional()}),fT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),yT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"rotated_pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:UM,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:UM,hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),_T=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"hole_with_polygon_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"oval\",\"pill\",\"rotated_pill\"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:XM,y:XM})).min(3),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),ccw_rotation:UM.optional()}),bT=k_.union([pT,mT,gT,fT,yT,_T]),xT=k_.object({type:k_.literal(\"pcb_port\"),pcb_port_id:QM(\"pcb_port\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:XM,y:XM,layers:k_.array(mw),is_board_pinout:k_.boolean().optional()}).describe(\"Defines a port on the PCB\"),vT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"circle\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,radius:k_.number(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),ST=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rect\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),IT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_rect\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:UM,layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),CT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"pill\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),PT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_pill\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:UM,layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),MT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"polygon\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(qM),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),NT=k_.discriminatedUnion(\"shape\",[vT,ST,IT,PT,CT,MT]).describe(\"Defines an SMT pad on the PCB\"),wT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"circle\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,radius:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),TT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rect\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),RT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"pill\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),ET=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rotated_rect\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),ccw_rotation:XM,layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),AT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"oval\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),OT=k_.union([wT,TT,RT,ET,AT]).describe(\"Defines solderpaste on the PCB\"),kT=k_.object({type:k_.literal(\"pcb_text\"),pcb_text_id:QM(\"pcb_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:qM,layer:mw,width:$M,height:$M,lines:k_.number(),align:k_.enum([\"bottom-left\"])}).describe(\"Defines text on the PCB\"),LT=k_.object({route_type:k_.literal(\"wire\"),x:XM,y:XM,width:XM,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:mw}),DT=k_.object({route_type:k_.literal(\"via\"),x:XM,y:XM,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:XM.optional(),outer_diameter:XM.optional(),from_layer:mw,to_layer:mw}),zT=k_.union([LT,DT]),FT=k_.object({type:k_.literal(\"pcb_trace\"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:QM(\"pcb_trace\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum([\"constant\",\"interpolated\"]).default(\"constant\").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(zT)}).describe(\"Defines a trace on the PCB\"),BT=k_.object({type:k_.literal(\"pcb_trace_warning\"),pcb_trace_warning_id:QM(\"pcb_trace_warning\"),warning_type:k_.literal(\"pcb_trace_warning\").default(\"pcb_trace_warning\"),message:k_.string(),center:qM.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace warning on the PCB\"),jT=yN.extend({type:k_.literal(\"pcb_trace_error\"),pcb_trace_error_id:QM(\"pcb_trace_error\"),error_type:k_.literal(\"pcb_trace_error\").default(\"pcb_trace_error\"),center:qM.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB\"),$T=yN.extend({type:k_.literal(\"pcb_trace_missing_error\"),pcb_trace_missing_error_id:QM(\"pcb_trace_missing_error\"),error_type:k_.literal(\"pcb_trace_missing_error\").default(\"pcb_trace_missing_error\"),center:qM.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a source trace has no corresponding PCB trace\"),YT=yN.extend({type:k_.literal(\"pcb_port_not_matched_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_port_not_matched_error\").default(\"pcb_port_not_matched_error\"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB where a port is not matched\"),XT=yN.extend({type:k_.literal(\"pcb_port_not_connected_error\"),pcb_port_not_connected_error_id:QM(\"pcb_port_not_connected_error\"),error_type:k_.literal(\"pcb_port_not_connected_error\").default(\"pcb_port_not_connected_error\"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a pcb port is not connected to any trace\"),VT=k_.object({type:k_.literal(\"pcb_net\"),pcb_net_id:QM(\"pcb_net\"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe(\"Defines a net on the PCB\"),WT=k_.object({type:k_.literal(\"pcb_via\"),pcb_via_id:QM(\"pcb_via\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:XM,y:XM,outer_diameter:XM.default(\"0.6mm\"),hole_diameter:XM.default(\"0.25mm\"),from_layer:mw.optional(),to_layer:mw.optional(),layers:k_.array(mw),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe(\"Defines a via on the PCB\"),HT=k_.object({type:k_.literal(\"pcb_board\"),pcb_board_id:QM(\"pcb_board\"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:$M.optional(),height:$M.optional(),center:qM,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this board, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this board, usually corresponding with how the user specified it\"),thickness:$M.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(qM).optional(),shape:k_.enum([\"rect\",\"polygon\"]).optional(),material:k_.enum([\"fr4\",\"fr1\"]).default(\"fr4\"),anchor_position:qM.optional(),anchor_alignment:tN.optional(),position_mode:k_.enum([\"relative_to_panel_anchor\",\"none\"]).optional()}).merge(iT).describe(\"Defines the board outline of the PCB\"),GT=k_.object({type:k_.literal(\"pcb_panel\"),pcb_panel_id:QM(\"pcb_panel\"),width:$M,height:$M,center:qM,thickness:$M.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe(\"Defines a PCB panel that can contain multiple boards\"),UT=yN.extend({type:k_.literal(\"pcb_placement_error\"),pcb_placement_error_id:QM(\"pcb_placement_error\"),error_type:k_.literal(\"pcb_placement_error\").default(\"pcb_placement_error\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a placement error on the PCB\"),ZT=yN.extend({type:k_.literal(\"pcb_panelization_placement_error\"),pcb_panelization_placement_error_id:QM(\"pcb_panelization_placement_error\"),error_type:k_.literal(\"pcb_panelization_placement_error\").default(\"pcb_panelization_placement_error\"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a panelization placement error on the PCB\"),qT=k_.object({type:k_.literal(\"pcb_trace_hint\"),pcb_trace_hint_id:QM(\"pcb_trace_hint\"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(oT),subcircuit_id:k_.string().optional()}).describe(\"A hint that can be used during generation of a PCB trace\"),JT=k_.object({type:k_.literal(\"pcb_silkscreen_line\"),pcb_silkscreen_line_id:QM(\"pcb_silkscreen_line\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:XM.default(\"0.1mm\"),x1:XM,y1:XM,x2:XM,y2:XM,layer:gw}).describe(\"Defines a silkscreen line on the PCB\"),KT=k_.object({type:k_.literal(\"pcb_silkscreen_path\"),pcb_silkscreen_path_id:QM(\"pcb_silkscreen_path\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,route:k_.array(qM),stroke_width:$M}).describe(\"Defines a silkscreen path on the PCB\"),QT=k_.object({type:k_.literal(\"pcb_silkscreen_text\"),pcb_silkscreen_text_id:QM(\"pcb_silkscreen_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:$M,top:$M,bottom:$M,right:$M}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:mw,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:tN.default(\"center\")}).describe(\"Defines silkscreen text on the PCB\"),tR=k_.object({type:k_.literal(\"pcb_copper_text\"),pcb_copper_text_id:QM(\"pcb_copper_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:$M,top:$M,bottom:$M,right:$M}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:mw,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:tN.default(\"center\")}).describe(\"Defines copper text on the PCB\"),eR=k_.object({type:k_.literal(\"pcb_silkscreen_rect\"),pcb_silkscreen_rect_id:QM(\"pcb_silkscreen_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:mw,stroke_width:$M.default(\"1mm\"),corner_radius:$M.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen rect on the PCB\"),nR=k_.object({type:k_.literal(\"pcb_silkscreen_circle\"),pcb_silkscreen_circle_id:QM(\"pcb_silkscreen_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:$M,layer:gw,stroke_width:$M.default(\"1mm\"),is_filled:k_.boolean().optional()}).describe(\"Defines a silkscreen circle on the PCB\"),oR=k_.object({type:k_.literal(\"pcb_silkscreen_oval\"),pcb_silkscreen_oval_id:QM(\"pcb_silkscreen_oval\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius_x:XM,radius_y:XM,layer:gw,ccw_rotation:UM.optional()}).describe(\"Defines a silkscreen oval on the PCB\"),iR=k_.object({type:k_.literal(\"pcb_silkscreen_pill\"),pcb_silkscreen_pill_id:QM(\"pcb_silkscreen_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:mw,ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen pill on the PCB\"),rR=k_.object({type:k_.literal(\"pcb_fabrication_note_text\"),pcb_fabrication_note_text_id:QM(\"pcb_fabrication_note_text\"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"1mm\"),pcb_component_id:k_.string(),text:k_.string(),layer:gw,anchor_position:qM.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),color:k_.string().optional()}).describe(\"Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators\"),sR=k_.object({type:k_.literal(\"pcb_fabrication_note_path\"),pcb_fabrication_note_path_id:QM(\"pcb_fabrication_note_path\"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:mw,route:k_.array(qM),stroke_width:$M,color:k_.string().optional()}).describe(\"Defines a fabrication path on the PCB for fabricators or assemblers\"),aR=k_.object({type:k_.literal(\"pcb_fabrication_note_rect\"),pcb_fabrication_note_rect_id:QM(\"pcb_fabrication_note_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw,stroke_width:$M.default(\"0.1mm\"),corner_radius:$M.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a fabrication note rectangle on the PCB\"),cR=k_.object({type:k_.literal(\"pcb_fabrication_note_dimension\"),pcb_fabrication_note_dimension_id:QM(\"pcb_fabrication_note_dimension\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,from:qM,to:qM,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:$M.optional(),offset_distance:$M.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:$M.default(\"1mm\"),color:k_.string().optional(),arrow_size:$M.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB fabrication notes\"),lR=k_.object({type:k_.literal(\"pcb_note_text\"),pcb_note_text_id:QM(\"pcb_note_text\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"1mm\"),text:k_.string().optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),layer:gw.default(\"top\"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a documentation note in text on the PCB\"),dR=k_.object({type:k_.literal(\"pcb_note_rect\"),pcb_note_rect_id:QM(\"pcb_note_rect\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw.default(\"top\"),stroke_width:$M.default(\"0.1mm\"),corner_radius:$M.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a rectangular documentation note on the PCB\"),hR=k_.object({type:k_.literal(\"pcb_note_path\"),pcb_note_path_id:QM(\"pcb_note_path\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(qM),layer:gw.default(\"top\"),stroke_width:$M.default(\"0.1mm\"),color:k_.string().optional()}).describe(\"Defines a polyline documentation note on the PCB\"),uR=k_.object({type:k_.literal(\"pcb_note_line\"),pcb_note_line_id:QM(\"pcb_note_line\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:XM,y1:XM,x2:XM,y2:XM,layer:gw.default(\"top\"),stroke_width:XM.default(\"0.1mm\"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe(\"Defines a straight documentation note line on the PCB\"),pR=k_.object({type:k_.literal(\"pcb_note_dimension\"),pcb_note_dimension_id:QM(\"pcb_note_dimension\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:qM,to:qM,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:$M.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:$M.default(\"1mm\"),layer:gw.default(\"top\"),color:k_.string().optional(),arrow_size:$M.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB documentation notes\"),mR=yN.extend({type:k_.literal(\"pcb_footprint_overlap_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_footprint_overlap_error\").default(\"pcb_footprint_overlap_error\"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when a pcb footprint overlaps with another element\"),gR=yN.extend({type:k_.literal(\"pcb_courtyard_overlap_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_courtyard_overlap_error\").default(\"pcb_courtyard_overlap_error\"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe(\"Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another\"),fR=k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"rect\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:XM,height:XM,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:XM,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),yR=k_.object({type:k_.literal(\"pcb_cutout\"),pcb_cutout_id:QM(\"pcb_cutout\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),_R=yR.extend({shape:k_.literal(\"rect\"),center:qM,width:$M,height:$M,rotation:UM.optional(),corner_radius:$M.optional()}),bR=yR.extend({shape:k_.literal(\"circle\"),center:qM,radius:$M}),xR=yR.extend({shape:k_.literal(\"polygon\"),points:k_.array(qM)}),vR=yR.extend({shape:k_.literal(\"path\"),route:k_.array(qM),slot_width:$M,slot_length:$M.optional(),space_between_slots:$M.optional(),slot_corner_radius:$M.optional()}),SR=k_.discriminatedUnion(\"shape\",[_R,bR,xR,vR]).describe(\"Defines a cutout on the PCB, removing board material.\"),IR=yN.extend({type:k_.literal(\"pcb_missing_footprint_error\"),pcb_missing_footprint_error_id:QM(\"pcb_missing_footprint_error\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"pcb_missing_footprint_error\").default(\"pcb_missing_footprint_error\"),source_component_id:k_.string()}).describe(\"Defines a missing footprint error on the PCB\"),CR=yN.extend({type:k_.literal(\"external_footprint_load_error\"),external_footprint_load_error_id:QM(\"external_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal(\"external_footprint_load_error\").default(\"external_footprint_load_error\")}).describe(\"Defines an error when an external footprint fails to load\"),PR=yN.extend({type:k_.literal(\"circuit_json_footprint_load_error\"),circuit_json_footprint_load_error_id:QM(\"circuit_json_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"circuit_json_footprint_load_error\").default(\"circuit_json_footprint_load_error\"),circuit_json:k_.array(k_.any()).optional()}).describe(\"Defines an error when a circuit JSON footprint fails to load\"),MR=k_.object({type:k_.literal(\"pcb_group\"),pcb_group_id:QM(\"pcb_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:$M.optional(),height:$M.optional(),center:qM,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this group, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this group, usually corresponding with how the user specified it\"),outline:k_.array(qM).optional(),anchor_position:qM.optional(),anchor_alignment:tN.default(\"center\"),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"none\"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum([\"packed\",\"none\"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:$M}).optional(),autorouter_used_string:k_.string().optional()}).describe(\"Defines a group of components on the PCB\"),NR=yN.extend({type:k_.literal(\"pcb_autorouting_error\"),pcb_error_id:QM(\"pcb_autorouting_error\"),error_type:k_.literal(\"pcb_autorouting_error\").default(\"pcb_autorouting_error\"),subcircuit_id:k_.string().optional()}).describe(\"The autorouting has failed to route a portion of the board\"),wR=k_.object({type:k_.literal(\"pcb_manual_edit_conflict_warning\"),pcb_manual_edit_conflict_warning_id:QM(\"pcb_manual_edit_conflict_warning\"),warning_type:k_.literal(\"pcb_manual_edit_conflict_warning\").default(\"pcb_manual_edit_conflict_warning\"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates\"),TR=k_.enum([\"x-\",\"x+\",\"y+\",\"y-\"]),RR=k_.object({type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\"),pcb_connector_not_in_accessible_orientation_warning_id:QM(\"pcb_connector_not_in_accessible_orientation_warning\"),warning_type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\").default(\"pcb_connector_not_in_accessible_orientation_warning\"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:TR,recommended_facing_direction:TR,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction\"),ER=k_.object({type:k_.literal(\"supplier_footprint_mismatch_warning\"),supplier_footprint_mismatch_warning_id:QM(\"supplier_footprint_mismatch_warning\"),warning_type:k_.literal(\"supplier_footprint_mismatch_warning\").default(\"supplier_footprint_mismatch_warning\"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:_N.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe(\"Warning emitted when a supplier part footprint does not match the expected footprint\"),AR=k_.object({type:k_.literal(\"pcb_breakout_point\"),pcb_breakout_point_id:QM(\"pcb_breakout_point\"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:XM,y:XM}).describe(\"Defines a routing target within a pcb_group for a source_trace or source_net\"),OR=k_.object({type:k_.literal(\"pcb_ground_plane\"),pcb_ground_plane_id:QM(\"pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane on the PCB\"),kR=k_.object({type:k_.literal(\"pcb_ground_plane_region\"),pcb_ground_plane_region_id:QM(\"pcb_ground_plane_region\"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:mw,points:k_.array(qM)}).describe(\"Defines a polygon region of a ground plane\"),LR=k_.object({type:k_.literal(\"pcb_thermal_spoke\"),pcb_thermal_spoke_id:QM(\"pcb_thermal_spoke\"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:XM,spoke_inner_diameter:XM,spoke_outer_diameter:XM,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Pattern for connecting a ground plane to a plated hole\"),DR=k_.object({type:k_.literal(\"pcb_copper_pour\"),pcb_copper_pour_id:QM(\"pcb_copper_pour\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:mw,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),zR=DR.extend({shape:k_.literal(\"rect\"),center:qM,width:$M,height:$M,rotation:UM.optional()}),FR=DR.extend({shape:k_.literal(\"brep\"),brep_shape:eT}),BR=DR.extend({shape:k_.literal(\"polygon\"),points:k_.array(qM)}),jR=k_.discriminatedUnion(\"shape\",[zR,FR,BR]).describe(\"Defines a copper pour on the PCB.\"),$R=yN.extend({type:k_.literal(\"pcb_component_outside_board_error\"),pcb_component_outside_board_error_id:QM(\"pcb_component_outside_board_error\"),error_type:k_.literal(\"pcb_component_outside_board_error\").default(\"pcb_component_outside_board_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:qM,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a PCB component is placed outside the board boundaries\"),YR=yN.extend({type:k_.literal(\"pcb_component_not_on_board_edge_error\"),pcb_component_not_on_board_edge_error_id:QM(\"pcb_component_not_on_board_edge_error\"),error_type:k_.literal(\"pcb_component_not_on_board_edge_error\").default(\"pcb_component_not_on_board_edge_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:qM,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component that must be placed on the board edge is centered away from the edge\"),XR=yN.extend({type:k_.literal(\"pcb_component_invalid_layer_error\"),pcb_component_invalid_layer_error_id:QM(\"pcb_component_invalid_layer_error\"),error_type:k_.literal(\"pcb_component_invalid_layer_error\").default(\"pcb_component_invalid_layer_error\"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:mw,subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)\"),VR=yN.extend({type:k_.literal(\"pcb_via_clearance_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_via_clearance_error\").default(\"pcb_via_clearance_error\"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when vias are closer than the allowed clearance\"),WR=yN.extend({type:k_.literal(\"pcb_via_trace_clearance_error\"),pcb_via_trace_clearance_error_id:QM(\"pcb_via_trace_clearance_error\"),error_type:k_.literal(\"pcb_via_trace_clearance_error\").default(\"pcb_via_trace_clearance_error\"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a via and trace are closer than the allowed clearance\"),HR=yN.extend({type:k_.literal(\"pcb_pad_pad_clearance_error\"),pcb_pad_pad_clearance_error_id:QM(\"pcb_pad_pad_clearance_error\"),error_type:k_.literal(\"pcb_pad_pad_clearance_error\").default(\"pcb_pad_pad_clearance_error\"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when pads are closer than the allowed clearance\"),GR=yN.extend({type:k_.literal(\"pcb_pad_trace_clearance_error\"),pcb_pad_trace_clearance_error_id:QM(\"pcb_pad_trace_clearance_error\"),error_type:k_.literal(\"pcb_pad_trace_clearance_error\").default(\"pcb_pad_trace_clearance_error\"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pad and trace are closer than allowed clearance\"),UR=k_.object({type:k_.literal(\"pcb_courtyard_rect\"),pcb_courtyard_rect_id:QM(\"pcb_courtyard_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw,ccw_rotation:UM.optional(),color:k_.string().optional()}).describe(\"Defines a courtyard rectangle on the PCB\"),ZR=k_.object({type:k_.literal(\"pcb_courtyard_outline\"),pcb_courtyard_outline_id:QM(\"pcb_courtyard_outline\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,outline:k_.array(qM).min(2)}).describe(\"Defines a courtyard outline on the PCB\"),qR=k_.object({type:k_.literal(\"pcb_courtyard_polygon\"),pcb_courtyard_polygon_id:QM(\"pcb_courtyard_polygon\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,points:k_.array(qM).min(3),color:k_.string().optional()}).describe(\"Defines a courtyard polygon on the PCB\"),JR=k_.object({type:k_.literal(\"pcb_courtyard_circle\"),pcb_courtyard_circle_id:QM(\"pcb_courtyard_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:$M,layer:gw,color:k_.string().optional()}).describe(\"Defines a courtyard circle on the PCB\"),KR=k_.object({type:k_.literal(\"cad_component\"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:JM,rotation:JM.optional(),size:JM.optional(),layer:mw.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:eN.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum([\"x+\",\"x-\",\"y+\",\"y-\",\"z+\",\"z-\"]).optional().describe('The direction in the model\\'s coordinate space that is considered \"up\" or \"coming out of the board surface\"'),model_origin_position:JM.optional(),model_origin_alignment:k_.enum([\"unknown\",\"center\",\"center_of_component_on_board_surface\",\"bottom_center_of_component\"]).optional(),model_object_fit:k_.enum([\"contain_within_bounds\",\"fill_bounds\"]).optional().default(\"contain_within_bounds\"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),anchor_alignment:k_.enum([\"center\",\"center_of_component_on_board_surface\"]).optional().default(\"center\")}).describe(\"Defines a component on the PCB\"),QR=k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]),tE=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),eE=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:QM(\"simulation_voltage_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:jM}).describe(\"Defines a DC voltage source for simulation\"),nE=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:QM(\"simulation_voltage_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:jM.optional(),frequency:YM.optional(),peak_to_peak_voltage:jM.optional(),wave_shape:QR.optional(),phase:UM.optional(),duty_cycle:tE.optional()}).describe(\"Defines an AC voltage source for simulation\"),oE=k_.union([eE,nE]).describe(\"Defines a voltage source for simulation\"),iE=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),rE=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:QM(\"simulation_current_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:VM}).describe(\"Defines a DC current source for simulation\"),sE=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:QM(\"simulation_current_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:VM.optional(),frequency:YM.optional(),peak_to_peak_current:VM.optional(),wave_shape:QR.optional(),phase:UM.optional(),duty_cycle:iE.optional()}).describe(\"Defines an AC current source for simulation\"),aE=k_.union([rE,sE]).describe(\"Defines a current source for simulation\"),cE=k_.union([k_.literal(\"spice_dc_sweep\"),k_.literal(\"spice_dc_operating_point\"),k_.literal(\"spice_transient_analysis\"),k_.literal(\"spice_ac_analysis\")]),lE=k_.object({type:k_.literal(\"simulation_experiment\"),simulation_experiment_id:QM(\"simulation_experiment\"),name:k_.string(),experiment_type:cE,time_per_step:WM.optional(),start_time_ms:HM.optional(),end_time_ms:HM.optional()}).describe(\"Defines a simulation experiment configuration\"),dE=k_.object({type:k_.literal(\"simulation_transient_voltage_graph\"),simulation_transient_voltage_graph_id:QM(\"simulation_transient_voltage_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:WM,start_time_ms:HM,end_time_ms:HM,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores voltage measurements over time for a simulation\"),hE=k_.object({type:k_.literal(\"simulation_switch\"),simulation_switch_id:QM(\"simulation_switch\"),source_component_id:k_.string().optional(),closes_at:HM.optional(),opens_at:HM.optional(),starts_closed:k_.boolean().optional(),switching_frequency:YM.optional()}).describe(\"Defines a switch for simulation timing control\"),uE=k_.object({type:k_.literal(\"simulation_voltage_probe\"),simulation_voltage_probe_id:QM(\"simulation_voltage_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.\").superRefine((t,e)=\u003e{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n\u0026\u0026o?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a differential probe.\"}):n?t.signal_input_source_port_id\u0026\u0026t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id.\"}):o\u0026\u0026(t.signal_input_source_net_id\u0026\u0026t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id.\"}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id.\"})}),pE=yN.extend({type:k_.literal(\"simulation_unknown_experiment_error\"),simulation_unknown_experiment_error_id:QM(\"simulation_unknown_experiment_error\"),error_type:k_.literal(\"simulation_unknown_experiment_error\").default(\"simulation_unknown_experiment_error\"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"An unknown error occurred during the simulation experiment.\"),mE=k_.object({type:k_.literal(\"simulation_op_amp\"),simulation_op_amp_id:QM(\"simulation_op_amp\"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe(\"Defines a simple ideal operational amplifier for simulation\"),gE=(k_.union([sw,iw,rw,ow,cw,aw,MN,xN,SN,CN,vN,NN,EN,AN,DN,FN,BN,VN,jN,$N,YN,XN,kN,ON,hw,fw,lw,WN,UN,ZN,JN,KN,yw,_w,bw,xw,vw,ew,dw,rT,uT,IR,CR,PR,wR,RR,ER,bT,fR,xT,VT,kT,FT,BT,WT,NT,OT,HT,GT,MR,qT,JT,KT,QT,iR,tR,eR,nR,oR,jT,$T,UT,ZT,YT,XT,VR,WR,HR,GR,sR,rR,aR,cR,lR,dR,hR,uR,pR,NR,mR,gR,AR,SR,OR,kR,LR,jR,$R,YR,XR,UR,ZR,qR,JR,Sw,zw,Ew,Aw,Ow,kw,ww,Rw,Fw,Lw,Iw,jw,$w,Bw,Hw,Gw,Uw,Zw,Kw,qw,Jw,KR,oE,aE,lE,dE,hE,uE,pE,mE]),!0),fE={CCW:-1,CW:1,NOT_ORIENTABLE:0},yE=2*Math.PI,_E=Object.freeze({__proto__:null,BOUNDARY:2,CCW:gE,CONTAINS:3,CW:!1,END_VERTEX:2,INSIDE:1,INTERLACE:4,NOT_VERTEX:0,ORIENTATION:fE,OUTSIDE:0,OVERLAP_OPPOSITE:2,OVERLAP_SAME:1,PIx2:yE,START_VERTEX:1}),bE=1e-6;function xE(t){bE=t}function vE(){return bE}function SE(t){return t\u003cbE\u0026\u0026t\u003e-bE}function IE(t,e){return t-e\u003cbE\u0026\u0026t-e\u003e-bE}function CE(t,e){return t-e\u003ebE}function PE(t,e){return t-e\u003c-bE}var ME={Utils:Object.freeze({__proto__:null,DECIMALS:3,EQ:IE,EQ_0:SE,GE:function(t,e){return t-e\u003e-bE},GT:CE,LE:function(t,e){return t-e\u003cbE},LT:PE,getTolerance:vE,setTolerance:xE}),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 _E)ME[t]=_E[t];Object.defineProperty(ME,\"DP_TOL\",{get:function(){return vE()},set:function(t){xE(t)}});var NE=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\")}};ME.Errors=NE;var wE=class{constructor(t,e){this.first=t,this.last=e||this.first}[Symbol.iterator](){let t;return{next:()=\u003e(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=[],o=t||this.first,i=e||this.last,r=o;if(void 0===r)return n;do{n.push(r),r=r.next}while(r!==i.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\u0026\u0026(n.prev=t),t.prev=e,t.next=n,this.last===e\u0026\u0026(this.last=t)}return this.last.next=void 0,this.first.prev=void 0,this}remove(t){return t===this.first\u0026\u0026t===this.last?(this.first=void 0,this.last=void 0):(t.prev\u0026\u0026(t.prev.next=t.next),t.next\u0026\u0026(t.next.prev=t.prev),t===this.first\u0026\u0026(this.first=t.next),t===this.last\u0026\u0026(this.last=t.prev)),this}isEmpty(){return void 0===this.first}static testInfiniteLoop(t){let e=t,n=t;do{if(e!=t\u0026\u0026e===n)throw NE.INFINITE_LOOP;e=e.next,n=n.next.next}while(e!=t)}},TE={stroke:\"black\"},RE=class{constructor(t=TE){for(const e in t)this[e]=t[e];this.stroke=t.stroke??TE.stroke}toAttributesString(){return Object.keys(this).reduce((t,e)=\u003et+(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 EE(t){return new RE(t).toAttributesString()}function AE(t,e){let n=[],[o,i,r]=t.standard,[s,a,c]=e.standard,l=o*a-i*s,d=r*a-i*c,h=o*c-r*s;if(!ME.Utils.EQ_0(l)){let t,e;0===i?(t=r/o,e=h/l):0===a?(t=c/s,e=h/l):0===o?(t=d/l,e=r/i):0===s?(t=d/l,e=c/a):(t=d/l,e=h/l),n.push(new ME.Point(t,e))}return n}function OE(t,e){let n=[],o=e.pc.projectionOn(t),i=e.pc.distanceTo(o)[0];if(ME.Utils.EQ(i,e.r))n.push(o);else if(ME.Utils.LT(i,e.r)){let r,s,a=Math.sqrt(e.r*e.r-i*i);r=t.norm.rotate90CCW().multiply(a),s=o.translate(r),n.push(s),r=t.norm.rotate90CW().multiply(a),s=o.translate(r),n.push(s)}return n}function kE(t,e){let n=[];for(let o of e.toSegments()){let e=DE(o,t);for(let t of e)eA(t,n)||n.push(t)}return n}function LE(t,e){let n=[];if(0===kE(t,e.box).length)return n;let o=OE(t,new ME.Circle(e.pc,e.r));for(let t of o)t.on(e)\u0026\u0026n.push(t);return n}function DE(t,e){let n=[];return t.ps.on(e)\u0026\u0026n.push(t.ps),t.pe.on(e)\u0026\u0026!t.isZeroLength()\u0026\u0026n.push(t.pe),n.length\u003e0||t.isZeroLength()||t.ps.leftTo(e)\u0026\u0026t.pe.leftTo(e)||!t.ps.leftTo(e)\u0026\u0026!t.pe.leftTo(e)?n:AE(new ME.Line(t.ps,t.pe),e)}function zE(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)\u0026\u0026n.push(t.ps),n;if(e.isZeroLength())return e.ps.on(t)\u0026\u0026n.push(e.ps),n;let o=new ME.Line(t.ps,t.pe),i=new ME.Line(e.ps,e.pe);if(o.incidentTo(i))t.ps.on(e)\u0026\u0026n.push(t.ps),t.pe.on(e)\u0026\u0026n.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 if(o.parallelTo(i)){const o=new ME.Vector(t.ps,t.pe),i=new ME.Vector(e.ps,e.pe),r=new ME.Vector(t.ps,e.ps),s=o.cross(i);if(!ME.Utils.EQ_0(s)){const a=r.cross(i)/s,c=r.cross(o)/s;ME.Utils.GE(a,0)\u0026\u0026ME.Utils.LE(a,1)\u0026\u0026ME.Utils.GE(c,0)\u0026\u0026ME.Utils.LE(c,1)\u0026\u0026n.push(FE(t.ps.translate(o.multiply(a)),t,e))}}else{let r=AE(o,i);r.length\u003e0\u0026\u0026BE(r[0],t)\u0026\u0026BE(r[0],e)\u0026\u0026n.push(FE(r[0],t,e))}return n}function FE(t,e,n){for(const o of[e.ps,e.pe,n.ps,n.pe])if(t.equalTo(o))return o;return t}function BE(t,e){const n=e.box;return ME.Utils.LE(t.x,n.xmax)\u0026\u0026ME.Utils.GE(t.x,n.xmin)\u0026\u0026ME.Utils.LE(t.y,n.ymax)\u0026\u0026ME.Utils.GE(t.y,n.ymin)}function jE(t,e){let n=[];if(t.isZeroLength()){let[o,i]=t.ps.distanceTo(e.pc);return ME.Utils.EQ(o,e.r)\u0026\u0026n.push(t.ps),n}let o=OE(new ME.Line(t.ps,t.pe),e);for(let e of o)e.on(t)\u0026\u0026n.push(e);return n}function $E(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)\u0026\u0026n.push(t.ps),n;let o=OE(new ME.Line(t.ps,t.pe),new ME.Circle(e.pc,e.r));for(let i of o)i.on(t)\u0026\u0026i.on(e)\u0026\u0026n.push(i);return n}function YE(t,e){let n=[],o=new ME.Vector(t.pc,e.pc),i=t.r,r=e.r;if(ME.Utils.EQ_0(i)||ME.Utils.EQ_0(r))return n;if(ME.Utils.EQ_0(o.x)\u0026\u0026ME.Utils.EQ_0(o.y)\u0026\u0026ME.Utils.EQ(i,r))return n.push(t.pc.translate(-i,0)),n;let s,a=t.pc.distanceTo(e.pc)[0];if(ME.Utils.GT(a,i+r))return n;if(ME.Utils.LT(a,Math.abs(i-r)))return n;if(o.x/=a,o.y/=a,ME.Utils.EQ(a,i+r)||ME.Utils.EQ(a,Math.abs(i-r)))return s=t.pc.translate(i*o.x,i*o.y),n.push(s),n;let c=i*i/(2*a)-r*r/(2*a)+a/2,l=t.pc.translate(c*o.x,c*o.y),d=Math.sqrt(i*i-c*c);return s=l.translate(o.rotate90CCW().multiply(d)),n.push(s),s=l.translate(o.rotate90CW().multiply(d)),n.push(s),n}function XE(t,e){let n=[];if(t.pc.equalTo(e.pc)\u0026\u0026ME.Utils.EQ(t.r,e.r)){let o;return o=t.start,o.on(e)\u0026\u0026n.push(o),o=t.end,o.on(e)\u0026\u0026n.push(o),o=e.start,o.on(t)\u0026\u0026n.push(o),o=e.end,o.on(t)\u0026\u0026n.push(o),n}let o=new ME.Circle(t.pc,t.r),i=new ME.Circle(e.pc,e.r),r=o.intersect(i);for(let o of r)o.on(t)\u0026\u0026o.on(e)\u0026\u0026n.push(o);return n}function VE(t,e){let n=[];if(e.pc.equalTo(t.pc)\u0026\u0026ME.Utils.EQ(e.r,t.r))return n.push(t.start),n.push(t.end),n;let o=YE(e,new ME.Circle(t.pc,t.r));for(let e of o)e.on(t)\u0026\u0026n.push(e);return n}function WE(t,e){return t.isSegment?zE(t.shape,e):$E(e,t.shape)}function HE(t,e){return t.isSegment?$E(t.shape,e):XE(t.shape,e)}function GE(t,e){return t.isSegment?DE(t.shape,e):LE(e,t.shape)}function UE(t,e){return t.isSegment?jE(t.shape,e):VE(t.shape,e)}function ZE(t,e){let n=[];for(let o of e.edges)for(let e of WE(o,t))n.push(e);return n}function qE(t,e){let n=[];for(let o of e.edges)for(let e of HE(o,t))n.push(e);return n}function JE(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of GE(o,t))eA(e,n)||n.push(e);return t.sortPoints(n)}function KE(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of UE(o,t))n.push(e);return n}function QE(t,e){return t.isSegment?WE(e,t.shape):t.isArc?HE(e,t.shape):t.isLine?GE(e,t.shape):t.isRay?(n=e,o=t.shape,n.isSegment?oA(o,n.shape):iA(o,n.shape)):[];var n,o}function tA(t,e){let n=[];if(e.isEmpty()||t.shape.box.not_intersect(e.box))return n;let o=e.edges.search(t.shape.box);for(let e of o)n=[...n,...QE(t,e)];return n}function eA(t,e){return e.some(e=\u003ee.equalTo(t))}function nA(t){return new ME.Line(t.start,t.norm)}function oA(t,e){return DE(e,nA(t)).filter(e=\u003et.contains(e))}function iA(t,e){return LE(nA(t),e).filter(e=\u003et.contains(e))}function rA(t,e){return OE(nA(t),e).filter(e=\u003et.contains(e))}function sA(t,e){return AE(nA(t),e).filter(e=\u003et.contains(e))}function aA(t,e){return JE(nA(t),e).filter(e=\u003et.contains(e))}function cA(t,e){if(t.intersect\u0026\u0026t.intersect instanceof Function)return t.intersect(e);throw NE.UNSUPPORTED_SHAPE_TYPE}function lA(t,e){let n=[];for(let o of e)n=[...n,...cA(t,o.shape)];return n}var dA=class t extends wE{constructor(...t){if(super(),this.isInfinite=!1,1===t.length\u0026\u0026t[0]instanceof Array\u0026\u0026t[0].length\u003e0){const e=t[0],n=e.length,o=t=\u003et instanceof ME.Segment||t instanceof ME.Arc||t instanceof ME.Ray,i=t=\u003et instanceof ME.Segment||t instanceof ME.Arc;if(!(1===n\u0026\u0026(t=\u003et instanceof ME.Segment||t instanceof ME.Arc||t instanceof ME.Ray||t instanceof ME.Line)(e[0])||n\u003e1\u0026\u0026o(e[0])\u0026\u0026o(e[n-1])\u0026\u0026e.slice(1,n-1).every(i)))throw ME.Errors.ILLEGAL_PARAMETERS;this.isInfinite=e.some(t=\u003et instanceof ME.Ray||t instanceof ME.Line);for(let t of e){let e=new ME.Edge(t);this.append(e)}this.setArcLength()}}get edges(){return[...this]}get box(){return this.edges.reduce((t,e)=\u003et.merge(e.box),new ME.Box)}get vertices(){let t=this.edges.map(t=\u003et.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\u003ethis.length||t\u003c0)return null;if(this.isInfinite)return null;let e=null;for(let n of this)if(t\u003e=n.arc_length\u0026\u0026(n===this.last||t\u003cn.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 o=new ME.Edge(n[0]),i=e.prev;return this.insert(o,i),e.shape=n[1],o}getChain(t,e){let n=[];for(let o=t;o!==e.next;o=o.next)n.push(o);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 ME.Point){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Line){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Circle){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Segment){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Arc){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Box){const[e,n]=ME.Distance.shape2multiline(new ME.Polygon(t),this);return[e,n.reverse()]}if(t instanceof ME.Multiline)return ME.Distance.multiline2multiline(this,t);throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}intersect(t){return t instanceof ME.Multiline?function(t,e){let n=[];for(let o of t)for(let t of e)n=[...n,...cA(o.shape,t.shape)];return n}(this,t):lA(t,this)}contains(t){if(t instanceof ME.Point)return this.edges.some(e=\u003ee.shape.contains(t));throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}translate(e){return new t(this.edges.map(t=\u003et.shape.translate(e)))}rotate(e=0,n=new ME.Point){return new t(this.edges.map(t=\u003et.shape.rotate(e,n)))}transform(e=new ME.Matrix){return new t(this.edges.map(t=\u003et.shape.transform(e)))}toShapes(){return this.edges.map(t=\u003et.shape.clone())}toJSON(){return this.edges.map(t=\u003et.toJSON())}svgPoints(){return this.vertices.map(t=\u003e`${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\u003cpath ${EE({fill:\"none\",...t})} d=\"`;e+=`\\nM${this.first.start.x},${this.first.start.y}`;for(let t of this)e+=t.svg();return e+='\" \u003e\\n\u003c/path\u003e',e}};ME.Multiline=dA;function hA(t,e,n){let o=n.length,i=t.shape.split(e);if(0===i.length)return;let r=0;r=null===i[0]?0:null===i[1]?t.shape.length:i[0].length;let s,a=0;IE(r,0)\u0026\u0026(a|=1),IE(r,t.shape.length)\u0026\u0026(a|=2),s=r===1/0?i[0].coord(e):2\u0026a\u0026\u0026t.next\u0026\u00260===t.next.arc_length?0:t.arc_length+r,n.push({id:o,pt:e,arc_length:s,edge_before:t,edge_after:void 0,face:t.face,is_vertex:a})}function uA(t){t.int_points1_sorted=pA(t.int_points1),t.int_points2_sorted=pA(t.int_points2)}function pA(t){let e=new Map,n=0;for(let o of t)e.has(o.face)||(e.set(o.face,n),n++);for(let n of t)n.faceId=e.get(n.face);return t.slice().sort(mA)}function mA(t,e){return t.faceId\u003ce.faceId?-1:t.faceId\u003ee.faceId?1:t.arc_length\u003ce.arc_length?-1:t.arc_length\u003ee.arc_length?1:0}function gA(t){if(t.int_points1.length\u003c2)return;let e,n,o,i,r=!1;for(let s=0;s\u003ct.int_points1_sorted.length;s++)if(-1!==t.int_points1_sorted[s].id){e=t.int_points1_sorted[s],n=t.int_points2[e.id];for(let a=s+1;a\u003ct.int_points1_sorted.length\u0026\u0026(o=t.int_points1_sorted[a],IE(o.arc_length,e.arc_length));a++)-1!==o.id\u0026\u0026(i=t.int_points2[o.id],-1!==i.id\u0026\u0026o.edge_before===e.edge_before\u0026\u0026o.edge_after===e.edge_after\u0026\u0026i.edge_before===n.edge_before\u0026\u0026i.edge_after===n.edge_after\u0026\u0026(o.id=-1,i.id=-1,r=!0))}n=t.int_points2_sorted[0],e=t.int_points1[n.id];for(let o=1;o\u003ct.int_points2_sorted.length;o++){let i=t.int_points2_sorted[o];if(-1===i.id)continue;if(-1===n.id||!IE(i.arc_length,n.arc_length)){n=i,e=t.int_points1[n.id];continue}let s=t.int_points1[i.id];s.edge_before===e.edge_before\u0026\u0026s.edge_after===e.edge_after\u0026\u0026i.edge_before===n.edge_before\u0026\u0026i.edge_after===n.edge_after\u0026\u0026(s.id=-1,i.id=-1,r=!0)}r\u0026\u0026(t.int_points1=t.int_points1.filter(t=\u003et.id\u003e=0),t.int_points2=t.int_points2.filter(t=\u003et.id\u003e=0),t.int_points1.forEach((t,e)=\u003et.id=e),t.int_points2.forEach((t,e)=\u003et.id=e))}function fA(t){for(let e of t)e.edge_before\u0026\u0026(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\u0026\u0026(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\u0026\u0026(e.edge_before.bvEnd=2),e.edge_after\u0026\u0026(e.edge_after.bvStart=2)}function yA(t,e){for(let n of t)n.edge_before\u0026\u0026n.edge_before.setInclusion(e),n.edge_after\u0026\u0026n.edge_after.setInclusion(e)}function _A(t,e,n){let o,i,r=1;if(1===t.length)return 1;o=t[e];for(let s=e+1;s\u003ct.length\u0026\u0026o.face===n\u0026\u0026(i=t[s],i.pt.equalTo(o.pt)\u0026\u0026i.edge_before===o.edge_before\u0026\u0026i.edge_after===o.edge_after);s++)r++;return r}function bA(t,e){if(e){for(let n of e){let e=n.edge_before;if(n.is_vertex=0,e.shape.start\u0026\u0026e.shape.start.equalTo(n.pt)\u0026\u0026(n.is_vertex|=1),e.shape.end\u0026\u0026e.shape.end.equalTo(n.pt)\u0026\u0026(n.is_vertex|=2),1\u0026n.is_vertex){n.edge_before=e.prev,e.prev\u0026\u0026(n.is_vertex=2);continue}if(2\u0026n.is_vertex)continue;let o=t.addVertex(n.pt,e);n.edge_before=o}for(let n of e)n.edge_before?n.edge_after=n.edge_before.next:t instanceof dA\u0026\u00261\u0026n.is_vertex\u0026\u0026(n.edge_after=t.first)}}function xA(t,e,n){const o=t.edge_before,i=e.edge_after,r=n.length;o.next=n[0],n[0].prev=o,n[r-1].next=i,i.prev=n[r-1]}ME.multiline=(...t)=\u003enew ME.Multiline(...t);var{INSIDE:vA,OUTSIDE:SA,BOUNDARY:IA,OVERLAP_SAME:CA,OVERLAP_OPPOSITE:PA}=_E,{NOT_VERTEX:MA,START_VERTEX:NA,END_VERTEX:wA}=_E;function TA(t,e){let n=e.clone().reverse(),[o,i]=LA(t,n,3,!0);return o}function RA(t,e){let[n,o]=LA(t,e,2,!0);return n}function EA(t,e){let[n,o]=LA(t,e,2,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=\u003et.shape)];let r=[];for(let t of o.faces)r=[...r,...[...t.edges].map(t=\u003et.shape)];return[i,r]}function AA(t,e){let[n,o]=LA(t,e,3,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=\u003et.shape)];return i}function OA(t,e){let n=t.clone(),o=e.clone(),i=DA(n,o);return uA(i),bA(n,i.int_points1_sorted),bA(o,i.int_points2_sorted),gA(i),uA(i),[i.int_points1_sorted.map(t=\u003et.pt),i.int_points2_sorted.map(t=\u003et.pt)]}function kA(t,e,n,o){let i=zA(t,n.int_points1),r=zA(e,n.int_points2);for(FA(i,e),FA(r,t),fA(n.int_points1),fA(n.int_points2),yA(n.int_points1,e),yA(n.int_points2,t);BA(t,e,n.int_points1,n.int_points1_sorted,n.int_points2,n););!function(t){let e,n,o,i=t.int_points1.length;for(let r=0;r\u003ci;r++){let s=t.int_points1_sorted[r];s.face!==e\u0026\u0026(n=r,e=s.face);let a,c=r,l=_A(t.int_points1_sorted,r,e);a=c+l\u003ci\u0026\u0026t.int_points1_sorted[c+l].face===e?c+l:n;let d=_A(t.int_points1_sorted,a,e);o=null;for(let n=a;n\u003ca+d;n++){let i=t.int_points1_sorted[n];if(i.face===e\u0026\u0026t.int_points2[i.id].face===t.int_points2[s.id].face){o=i;break}}if(null===o)continue;let h=s.edge_after,u=o.edge_before;if(2!==h.bv||2!==u.bv)continue;if(h!==u)continue;let p=t.int_points2[s.id],m=t.int_points2[o.id],g=p.edge_after,f=m.edge_before;2===g.bv\u0026\u00262===f.bv\u0026\u0026g===f||(p=t.int_points2[o.id],m=t.int_points2[s.id],g=p.edge_after,f=m.edge_before),2===g.bv\u0026\u00262===f.bv\u0026\u0026g===f\u0026\u0026h.setOverlap(g)}}(n),jA(t,o,n.int_points1_sorted,!0),jA(e,o,n.int_points2_sorted,!1),XA(t,i,o,!0),XA(e,r,o,!1)}function LA(t,e,n,o){let i=t.clone(),r=e.clone(),s=DA(i,r);return uA(s),bA(i,s.int_points1_sorted),bA(r,s.int_points2_sorted),gA(s),uA(s),kA(i,r,s,n),o\u0026\u0026function(t,e,n){!function(t,e,n,o){for(let n of e.faces){for(let e of n)t.edges.add(e);void 0===o.find(t=\u003et.face===n)\u0026\u0026t.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\u003cn.int_points1.length;t++){let e=n.int_points1[t],o=n.int_points2[t];if(void 0!==e.edge_before\u0026\u0026void 0===e.edge_after\u0026\u0026void 0===o.edge_before\u0026\u0026void 0!==o.edge_after\u0026\u0026(e.edge_before.next=o.edge_after,o.edge_after.prev=e.edge_before,e.edge_after=o.edge_after,o.edge_before=e.edge_before),void 0!==o.edge_before\u0026\u0026void 0===o.edge_after\u0026\u0026void 0===e.edge_before\u0026\u0026void 0!==e.edge_after\u0026\u0026(o.edge_before.next=e.edge_after,e.edge_after.prev=o.edge_before,o.edge_after=e.edge_after,e.edge_before=o.edge_before),void 0!==e.edge_before\u0026\u0026void 0===e.edge_after)for(let t of n.int_points1_sorted)t!==e\u0026\u0026void 0===t.edge_before\u0026\u0026void 0!==t.edge_after\u0026\u0026t.pt.equalTo(e.pt)\u0026\u0026(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!==o.edge_before\u0026\u0026void 0===o.edge_after)for(let t of n.int_points2_sorted)t!==o\u0026\u0026void 0===t.edge_before\u0026\u0026void 0!==t.edge_after\u0026\u0026t.pt.equalTo(o.pt)\u0026\u0026(o.edge_before.next=t.edge_after,t.edge_after.prev=o.edge_before,o.edge_after=t.edge_after,t.edge_before=o.edge_before)}}(0,0,n),$A(t,n.int_points1),$A(e,n.int_points2),YA(t,n.int_points1,n.int_points2),YA(t,n.int_points2,n.int_points1),VA(t),VA(e)}(i,r,s),[i,r]}function DA(t,e){let n={int_points1:[],int_points2:[]};for(let o of t.edges){let t=e.edges.search(o.box);for(let e of t){let t=o.shape.intersect(e.shape);for(let i of t)hA(o,i,n.int_points1),hA(e,i,n.int_points2)}}return n}function zA(t,e){let n=[];for(let o of t.faces)e.find(t=\u003et.face===o)||n.push(o);return n}function FA(t,e){for(let n of t)n.first.bv=n.first.bvStart=n.first.bvEnd=void 0,n.first.setInclusion(e)}function BA(t,e,n,o,i,r){let s,a,c,l=o.length,d=!1;for(let h=0;h\u003cl;h++){let u=o[h];u.face!==s\u0026\u0026(a=h,s=u.face);let p,m=h,g=_A(o,h,s);p=m+g\u003cl\u0026\u0026o[m+g].face===s?m+g:a;let f=_A(o,p,s);c=null;for(let t=p;t\u003cp+f;t++){let e=o[t];if(e.face===s\u0026\u0026i[e.id].face===i[u.id].face){c=e;break}}if(null===c)continue;let y=u.edge_after,_=c.edge_before;if(y.bv!==IA||_.bv==IA)if(y.bv==IA||_.bv!==IA){if(y.bv===IA\u0026\u0026_.bv===IA\u0026\u0026y!=_||y.bv===vA\u0026\u0026_.bv===SA||y.bv===SA\u0026\u0026_.bv===vA){let t=y.next;for(;t!=_;)t.bvStart=void 0,t.bvEnd=void 0,t.bv=void 0,t.setInclusion(e),t=t.next}if(y.bv===IA\u0026\u0026_.bv===IA\u0026\u0026y!=_){let t,e=y.next;for(;e!=_;){if(e.bv!=IA)if(void 0===t)t=e.bv;else if(e.bv!=t)throw NE.UNRESOLVED_BOUNDARY_CONFLICT;e=e.next}null!=t\u0026\u0026(y.bv=t,_.bv=t);continue}if(y.bv===vA\u0026\u0026_.bv===SA||y.bv===SA\u0026\u0026_.bv===vA){let o=y;for(;o!=_;){if(o.bvStart===y.bv\u0026\u0026o.bvEnd===_.bv){let[s,a]=o.shape.distanceTo(e);if(s\u003c10*ME.DP_TOL){hA(o,a.ps,n);let s=n[n.length-1];if(s.is_vertex\u0026NA)s.edge_after=o,s.edge_before=o.prev,o.bvStart=IA,o.bv=void 0,o.setInclusion(e);else if(s.is_vertex\u0026wA)s.edge_after=o.next,o.bvEnd=IA,o.bv=void 0,o.setInclusion(e);else{let t=e.addVertex(s.pt,o);s.edge_before=t,s.edge_after=t.next,t.setInclusion(e),t.next.bvStart=IA,t.next.bvEnd=void 0,t.next.bv=void 0,t.next.setInclusion(e)}let c=e.findEdgeByPoint(a.pe);hA(c,a.pe,i);let l=i[i.length-1];if(l.is_vertex\u0026NA)l.edge_after=c,l.edge_before=c.prev;else if(l.is_vertex\u0026wA)l.edge_after=c.next;else{let n=i.find(t=\u003et.edge_after===c),o=e.addVertex(l.pt,c);l.edge_before=o,l.edge_after=o.next,n\u0026\u0026(n.edge_after=o),o.bvStart=void 0,o.bvEnd=IA,o.bv=void 0,o.setInclusion(t),o.next.bvStart=IA,o.next.bvEnd=void 0,o.next.bv=void 0,o.next.setInclusion(t)}uA(r),d=!0;break}}o=o.next}if(d)break;throw NE.UNRESOLVED_BOUNDARY_CONFLICT}}else _.bv=y.bv;else y.bv=_.bv}return d}function jA(t,e,n,o){if(!n)return;let i,r,s,a;for(let c=0;c\u003cn.length;c++){if(s=n[c],s.face!==i\u0026\u0026(r=c,i=s.face),i.isEmpty())continue;let l,d=c,h=_A(n,c,i);l=d+h\u003cn.length\u0026\u0026n[d+h].face===s.face?d+h:r,a=n[l];let u=l,p=_A(n,u,i),m=s.edge_after,g=a.edge_before;if(m.bv===vA\u0026\u0026g.bv===vA\u0026\u00261===e||m.bv===SA\u0026\u0026g.bv===SA\u0026\u00262===e||(m.bv===SA||g.bv===SA)\u0026\u00263===e\u0026\u0026!o||(m.bv===vA||g.bv===vA)\u0026\u00263===e\u0026\u0026o||m.bv===IA\u0026\u0026g.bv===IA\u0026\u0026m.overlap\u0026CA\u0026\u0026o||m.bv===IA\u0026\u0026g.bv===IA\u0026\u0026m.overlap\u0026PA){t.removeChain(i,m,g);for(let t=d;t\u003cd+h;t++)n[t].edge_after=void 0;for(let t=u;t\u003cu+p;t++)n[t].edge_before=void 0}c+=h-1}}function $A(t,e){for(let n of e)t.faces.delete(n.face),n.face=void 0,n.edge_before\u0026\u0026(n.edge_before.face=void 0),n.edge_after\u0026\u0026(n.edge_after.face=void 0)}function YA(t,e,n){for(let o of e){if(void 0===o.edge_before||void 0===o.edge_after)continue;if(o.face)continue;if(o.edge_after.face||o.edge_before.face)continue;let i=o.edge_after,r=o.edge_before;try{wE.testInfiniteLoop(i)}catch(t){throw NE.CANNOT_COMPLETE_BOOLEAN_OPERATION}let s=t.addFace(i,r);for(let t of e)t.edge_before\u0026\u0026t.edge_after\u0026\u0026t.edge_before.face===s\u0026\u0026t.edge_after.face===s\u0026\u0026(t.face=s);for(let t of n)t.edge_before\u0026\u0026t.edge_after\u0026\u0026t.edge_before.face===s\u0026\u0026t.edge_after.face===s\u0026\u0026(t.face=s)}}function XA(t,e,n,o){for(let i of e){let e=i.first.bv;(1===n\u0026\u0026e===vA||3===n\u0026\u0026e===vA\u0026\u0026o||3===n\u0026\u0026e===SA\u0026\u0026!o||2===n\u0026\u0026e===SA)\u0026\u0026t.deleteFace(i)}}function VA(t){const e=[];for(const n of t.edges)n.face\u0026\u0026t.faces.has(n.face)||e.push(n);for(const n of e)t.edges.delete(n)}var WA=Object.freeze({__proto__:null,BOOLEAN_INTERSECT:2,BOOLEAN_SUBTRACT:3,BOOLEAN_UNION:1,calculateIntersections:OA,innerClip:EA,intersect:RA,outerClip:AA,removeNotRelevantChains:jA,removeOldFaces:$A,restoreFaces:YA,subtract:TA,unify:function(t,e){let[n,o]=LA(t,e,1,!0);return n}}),HA=RegExp(\"T.F..FFF.|T.F...F..\"),GA=RegExp(\"T........|.T.......|...T.....|....T....\"),UA=RegExp(\"FT.......|F..T.....|F...T....\"),ZA=RegExp(\"T.F..F...\"),qA=RegExp(\"T.F..F...|.TF..F...|..FT.F...|..F.TF...\"),JA=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=\u003et instanceof Array\u0026\u0026t.length\u003e0?\"T\":t instanceof Array\u0026\u00260===t.length?\"F\":\"*\").join(\"\")}equal(){return HA.test(this.toString())}intersect(){return GA.test(this.toString())}touch(){return UA.test(this.toString())}inside(){return ZA.test(this.toString())}covered(){return qA.test(this.toString())}};function KA(t,e){let n,o=new ME.Ray(e),i=new ME.Line(o.pt,o.norm);const r=new ME.Box(o.box.xmin-ME.DP_TOL,o.box.ymin-ME.DP_TOL,o.box.xmax+ME.DP_TOL,o.box.ymax+ME.DP_TOL);if(t.box.not_intersect(r))return ME.OUTSIDE;let s=t.edges.search(r);if(0===s.length)return ME.OUTSIDE;for(let t of s)if(t.shape.contains(e))return ME.BOUNDARY;let a=[...t.faces],c=[];for(let t of s)for(let n of o.intersect(t.shape)){if(n.equalTo(e))return ME.BOUNDARY;c.push({pt:n,edge:t,face_index:a.indexOf(t.face)})}c.sort((t,e)=\u003ePE(t.pt.x,e.pt.x)?-1:CE(t.pt.x,e.pt.x)?1:t.face_index\u003ce.face_index?-1:t.face_index\u003ee.face_index?1:t.edge.arc_length\u003ce.edge.arc_length?-1:t.edge.arc_length\u003ee.edge.arc_length?1:0);let l=0;for(let t=0;t\u003cc.length;t++){let e=c[t];if(e.pt.equalTo(e.edge.shape.start)){if(t\u003e0\u0026\u0026e.pt.equalTo(c[t-1].pt)\u0026\u0026e.face_index===c[t-1].face_index\u0026\u0026e.edge.prev===c[t-1].edge)continue;let n=e.edge.prev;for(;SE(n.length);)n=n.prev;let o=n.shape.tangentInEnd(),r=e.pt.translate(o),s=e.edge.shape.tangentInStart(),a=e.pt.translate(s),d=r.leftTo(i),h=a.leftTo(i);(d\u0026\u0026!h||!d\u0026\u0026h)\u0026\u0026l++}else if(e.pt.equalTo(e.edge.shape.end)){if(t\u003e0\u0026\u0026e.pt.equalTo(c[t-1].pt)\u0026\u0026e.face_index===c[t-1].face_index\u0026\u0026e.edge.next===c[t-1].edge)continue;let n=e.edge.next;for(;SE(n.length);)n=n.next;let o=n.shape.tangentInStart(),r=e.pt.translate(o),s=e.edge.shape.tangentInEnd(),a=e.pt.translate(s),d=r.leftTo(i),h=a.leftTo(i);(d\u0026\u0026!h||!d\u0026\u0026h)\u0026\u0026l++}else if(e.edge.shape instanceof ME.Segment)l++;else{let t=e.edge.shape.box;IE(e.pt.y,t.ymin)||IE(e.pt.y,t.ymax)||l++}}return n=l%2==1?1:0,n}function QA(t,e){return oO(t,e).intersect()}function tO(t,e){return oO(t,e).inside()}function eO(t,e){return oO(t,e).covered()}function nO(t,e){return eO(e,t)}function oO(t,e){return t instanceof ME.Line\u0026\u0026e instanceof ME.Line?function(t,e){let n=new JA,o=AE(t,e);0===o.length?t.contains(e.pt)\u0026\u0026e.contains(t.pt)?(n.I2I=[t],n.I2E=[],n.E2I=[]):(n.I2I=[],n.I2E=[t],n.E2I=[e]):(n.I2I=o,n.I2E=t.split(o),n.E2I=e.split(o));return n}(t,e):t instanceof ME.Line\u0026\u0026e instanceof ME.Circle?function(t,e){let n=new JA,o=OE(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new dA([t]),r=t.sortPoints(o);i.split(r);let s=i.toShapes();n.I2I=[s[1]],n.I2B=r,n.I2E=[s[0],s[2]],n.E2I=new ME.Polygon([e.toArc()]).cutWithLine(t)}return n}(t,e):t instanceof ME.Line\u0026\u0026e instanceof ME.Box?function(t,e){let n=new JA,o=kE(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new dA([t]),r=t.sortPoints(o);i.split(r);let s=i.toShapes();e.toSegments().some(t=\u003et.contains(o[0])\u0026\u0026t.contains(o[1]))?(n.I2I=[],n.I2B=[s[1]],n.I2E=[s[0],s[2]],n.E2I=[e]):(n.I2I=[s[1]],n.I2B=r,n.I2E=[s[0],s[2]],n.E2I=new ME.Polygon(e.toSegments()).cutWithLine(t))}return n}(t,e):t instanceof ME.Line\u0026\u0026e instanceof ME.Polygon?function(t,e){let n=new JA,o=JE(t,e),i=new dA([t]),r=o.length\u003e0?o.slice():t.sortPoints(o);return i.split(r),[...i].forEach(t=\u003et.setInclusion(e)),n.I2I=[...i].filter(t=\u003et.bv===ME.INSIDE).map(t=\u003et.shape),n.I2B=[...i].slice(1).map(t=\u003et.bv===ME.BOUNDARY?t.shape:t.shape.start),n.I2E=[...i].filter(t=\u003et.bv===ME.OUTSIDE).map(t=\u003et.shape),n.E2I=e.cutWithLine(t),n}(t,e):(t instanceof ME.Segment||t instanceof ME.Arc)\u0026\u0026e instanceof ME.Polygon?iO(t,e):(t instanceof ME.Segment||t instanceof ME.Arc)\u0026\u0026(e instanceof ME.Circle||e instanceof ME.Box)?iO(t,new ME.Polygon(e)):t instanceof ME.Polygon\u0026\u0026e instanceof ME.Polygon?rO(t,e):(t instanceof ME.Circle||t instanceof ME.Box)\u0026\u0026(e instanceof ME.Circle||e instanceof ME.Box)?rO(new ME.Polygon(t),new ME.Polygon(e)):(t instanceof ME.Circle||t instanceof ME.Box)\u0026\u0026e instanceof ME.Polygon?rO(new ME.Polygon(t),e):t instanceof ME.Polygon\u0026\u0026(e instanceof ME.Circle||e instanceof ME.Box)?rO(t,new ME.Polygon(e)):void 0}function iO(t,e){let n=new JA,o=function(t,e){return t instanceof ME.Line?JE(t,e):t instanceof ME.Segment?ZE(t,e):t instanceof ME.Arc?qE(t,e):[]}(t,e),i=o.length\u003e0?o.slice():t.sortPoints(o),r=new dA([t]);r.split(i),[...r].forEach(t=\u003et.setInclusion(e)),n.I2I=[...r].filter(t=\u003et.bv===ME.INSIDE).map(t=\u003et.shape),n.I2B=[...r].slice(1).map(t=\u003et.bv===ME.BOUNDARY?t.shape:t.shape.start),n.I2E=[...r].filter(t=\u003et.bv===ME.OUTSIDE).map(t=\u003et.shape),n.B2I=[],n.B2B=[],n.B2E=[];for(let o of[t.start,t.end])switch(KA(e,o)){case ME.INSIDE:n.B2I.push(o);break;case ME.BOUNDARY:n.B2B.push(o);break;case ME.OUTSIDE:n.B2E.push(o)}return n}function rO(t,e){let n=new JA,[o,i]=OA(t,e),r=RA(t,e),s=TA(t,e),a=TA(e,t),[c,l]=EA(t,e),d=AA(t,e),h=AA(e,t);return n.I2I=r.isEmpty()?[]:[r],n.I2B=l,n.I2E=s.isEmpty()?[]:[s],n.B2I=c,n.B2B=o,n.B2E=d,n.E2I=a.isEmpty()?[]:[a],n.E2B=h,n}var sO=Object.freeze({__proto__:null,contain:function(t,e){return tO(e,t)},cover:nO,covered:eO,disjoint:function(t,e){return!QA(t,e)},equal:function(t,e){return oO(t,e).equal()},inside:tO,intersect:QA,relate:oO,touch:function(t,e){return oO(t,e).touch()}}),aO=class t{constructor(t=1,e=0,n=0,o=1,i=0,r=0){this.a=t,this.b=e,this.c=n,this.d=o,this.tx=i,this.ty=r}fromMatrix3x3(e){const[n,o,i]=e[0],[r,s,a]=e[1];return new t(n,r,o,s,i,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,o;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 NE.ILLEGAL_PARAMETERS;n=e[0],o=e[1]}else n=e[0].x,o=e[0].y;return this.multiply(new t(1,0,0,1,n,o))}rotate(e,n=0,o=0){let i=Math.cos(e),r=Math.sin(e);return this.translate(n,o).multiply(new t(i,r,-r,i,0,0)).translate(-n,-o)}scale(e,n){return this.multiply(new t(e,0,0,n,0,0))}equalTo(t){return!!ME.Utils.EQ(this.tx,t.tx)\u0026\u0026(!!ME.Utils.EQ(this.ty,t.ty)\u0026\u0026(!!ME.Utils.EQ(this.a,t.a)\u0026\u0026(!!ME.Utils.EQ(this.b,t.b)\u0026\u0026(!!ME.Utils.EQ(this.c,t.c)\u0026\u0026!!ME.Utils.EQ(this.d,t.d)))))}};ME.Matrix=aO;ME.matrix=(...t)=\u003enew ME.Matrix(...t);var cO=class{constructor(t,e){this.low=t,this.high=e}get max(){return this.clone()}less_than(t){return this.low\u003ct.low||this.low===t.low\u0026\u0026this.high\u003ct.high}equal_to(t){return this.low===t.low\u0026\u0026this.high===t.high}intersect(t){return!this.not_intersect(t)}not_intersect(t){return this.high\u003ct.low||t.high\u003cthis.low}merge(t){const e=void 0===this.low?t.low:this.low\u003ct.low?this.low:t.low,n=void 0===this.high?t.high:this.high\u003et.high?this.high:t.high,o=this.clone();return o.low=e,o.high=n,o}output(){return[this.low,this.high]}comparable_less_than(t,e){return t\u003ce}},lO=class t extends cO{clone(){return new t(this.low,this.high)}},dO=class{constructor(t,e,n=null,o=null,i=null,r=0){if(this.left=n,this.right=o,this.parent=i,this.color=r,this.item={key:void 0,values:[]},void 0!==e\u0026\u0026this.item.values.push(e),void 0!==t)if(Array.isArray(t)){const[e,n]=t;if(!Number.isNaN(e)\u0026\u0026!Number.isNaN(n)){let t=e,o=n;t\u003eo\u0026\u0026([t,o]=[o,t]),this.item.key=new lO(t,o)}}else this.item.key=t;this.max=this.item.key?this.item.key.max:void 0}isNil(){return void 0===this.item.key\u0026\u00260===this.item.values.length\u0026\u0026null===this.left\u0026\u0026null===this.right\u0026\u00260===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\u0026\u0026n\u0026\u0026e.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\u0026\u0026this.right.max\u0026\u0026(this.max=this.max?this.max.merge(this.right.max):this.right.max),this.left\u0026\u0026this.left.max\u0026\u0026(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(),o=t.requireKey();return n.comparable_less_than(e,o.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(),o=t.requireKey();return n.comparable_less_than(o.high,e)}},hO=class t{constructor(){this.root=null,this.nil_node=new dO}get size(){let t=0;return this.tree_walk(this.root,e=\u003et+=e.item.values.length),t}get keys(){const t=[];return this.tree_walk(this.root,e=\u003et.push(e.item.key.output())),t}get values(){const t=[];return this.tree_walk(this.root,e=\u003e{for(const n of e.item.values)t.push(n)}),t}get items(){const t=[];return this.tree_walk(this.root,e=\u003e{const n=e.item.key.output();for(const o of e.item.values)t.push({key:n,value:o})}),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 dO(t));if(n)return n.item.values.push(e),n;const o=new dO(t,e,this.nil_node,this.nil_node,null,1);return this.tree_insert(o),this.recalc_max(o),o}exist(t,e=t){const n=this.tree_search(this.root,new dO(t));return!!n\u0026\u0026(arguments.length\u003c2||e===t||n.item.values.some(t=\u003et\u0026\u0026t.equal_to?t.equal_to(e):t===e))}remove(t,e=t){const n=this.tree_search(this.root,new dO(t));if(!n)return;if(arguments.length\u003c2)return this.tree_delete(n),n;const o=n.item.values.findIndex(t=\u003et\u0026\u0026t.equal_to?t.equal_to(e):t===e);return o\u003e=0?(n.item.values.splice(o,1),0===n.item.values.length\u0026\u0026this.tree_delete(n),n):void 0}search(t,e=(t,e)=\u003et===e?e.output():t){const n=new dO(t),o=[];this.tree_search_interval(this.root,n,o);const i=[];for(const t of o)for(const n of t.item.values)i.push(e(n,t.item.key));return i}intersect_any(t){const e=new dO(t);return this.tree_find_any_interval(this.root,e)}forEach(t){this.tree_walk(this.root,e=\u003e{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=\u003e{for(const o of t.item.values)n.insert(t.item.key,e(o,t.item.key))}),n}*iterate(t,e=(t,e)=\u003et===e?e.output():t){let n=null;for(t?n=this.tree_search_nearest_forward(this.root,new dO(t)):this.root\u0026\u0026(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\u0026\u00261===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\u0026\u0026(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\u0026\u0026(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\u0026\u0026(t.copy_data(e),t.update_max(),this.recalc_max(t)),0===e.color\u0026\u0026this.delete_fixup(n)}delete_fixup(t){let e,n=t;for(;n!==this.root\u0026\u0026null!=n.parent\u0026\u00260===n.color;)n===n.parent.left?(e=n.parent.right,1===e.color\u0026\u0026(e.color=0,n.parent.color=1,this.rotate_left(n.parent),e=n.parent.right),0===e.left.color\u0026\u00260===e.right.color?(e.color=1,n=n.parent):(0===e.right.color\u0026\u0026(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\u0026\u0026(e.color=0,n.parent.color=1,this.rotate_right(n.parent),e=n.parent.left),0===e.left.color\u0026\u00260===e.right.color?(e.color=1,n=n.parent):(0===e.left.color\u0026\u0026(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\u0026\u0026t!==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,o=t;for(;o\u0026\u0026o!==this.nil_node;)o.less_than(e)?o.intersect(e)?(n=o,o=o.left):o=o.right:(n\u0026\u0026!o.less_than(n)||(n=o),o=o.left);return n||null}tree_search_interval(t,e,n){null!=t\u0026\u0026t!==this.nil_node\u0026\u0026(t.left===this.nil_node||t.not_intersect_left_subtree(e)||this.tree_search_interval(t.left,e,n),t.intersect(e)\u0026\u0026n.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\u0026\u0026t!==this.nil_node\u0026\u0026(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\u0026\u0026e.left!==this.nil_node;)e=e.left;return e}local_maximum(t){let e=t;for(;null!=e.right\u0026\u0026e.right!==this.nil_node;)e=e.right;return e}tree_successor(t){let e,n,o;if(t.right!==this.nil_node)e=this.local_minimum(t.right);else{for(n=t,o=t.parent;null!=o\u0026\u0026o.right===n;)n=o,o=o.parent;e=o}return e}rotate_left(t){const e=t.right;t.right=e.left,e.left!==this.nil_node\u0026\u0026(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\u0026\u0026t!==this.nil_node\u0026\u0026t.update_max(),null!=e\u0026\u0026e!==this.nil_node\u0026\u0026e.update_max()}rotate_right(t){const e=t.left;t.left=e.right,e.right!==this.nil_node\u0026\u0026(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\u0026\u0026t!==this.nil_node\u0026\u0026t.update_max(),null!=e\u0026\u0026e!==this.nil_node\u0026\u0026e.update_max()}tree_walk(t,e){null!=t\u0026\u0026t!==this.nil_node\u0026\u0026(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\u0026\u0026(0===e.left.color\u0026\u00260===e.right.color||(t=!1))}),t}testBlackHeightProperty(t){let e=0,n=0,o=0;if(0===t.color\u0026\u0026e++,n=t.left!==this.nil_node?this.testBlackHeightProperty(t.left):1,o=t.right!==this.nil_node?this.testBlackHeightProperty(t.right):1,n!==o)throw new Error(\"Red-black height property violated\");return e+=n,e}},uO=class extends Set{constructor(t){super(t),this.index=new hO,this.forEach(t=\u003ethis.index.insert(t))}add(t){let e=this.size;const{key:n,value:o}=t,i=n||t.box,r=o||t;return super.add(r),this.size\u003ee\u0026\u0026this.index.insert(i,r),this}delete(t){const{key:e,value:n}=t,o=e||t.box,i=n||t;let r=super.delete(i);return r\u0026\u0026this.index.remove(o,i),r}clear(){super.clear(),this.index=new hO}search(t){return this.index.search(t)}hit(t){let e=new ME.Box(t.x-1,t.y-1,t.x+1,t.y+1);return this.index.search(e).filter(e=\u003et.on(e))}svg(){return[...this].reduce((t,e)=\u003et+e.svg(),\"\")}};ME.PlanarSet=uO;var pO=class{get name(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform((new aO).translate(...t))}rotate(t,e=new ME.Point){return this.transform((new aO).rotate(t,e.x,e.y))}scale(t,e){return this.transform((new aO).scale(t,e))}transform(...t){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}};ME.Point=class t extends pO{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length\u0026\u0026t[0]instanceof Array\u0026\u00262===t[0].length){let e=t[0];if(\"number\"==typeof e[0]\u0026\u0026\"number\"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"point\"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(2===t.length\u0026\u0026\"number\"==typeof t[0]\u0026\u0026\"number\"==typeof t[1])return this.x=t[0],void(this.y=t[1]);throw NE.ILLEGAL_PARAMETERS}}get box(){return new ME.Box(this.x,this.y,this.x,this.y)}clone(){return new ME.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return ME.Utils.EQ(this.x,t.x)\u0026\u0026ME.Utils.EQ(this.y,t.y)}lessThan(t){return!!ME.Utils.LT(this.y,t.y)||!(!ME.Utils.EQ(this.y,t.y)||!ME.Utils.LT(this.x,t.x))}transform(t){return new ME.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let e=new ME.Vector(this,t.pt);if(ME.Utils.EQ_0(e.cross(t.norm)))return t.pt.clone();let n=e.dot(t.norm),o=t.norm.multiply(n);return this.translate(o)}leftTo(t){let e=new ME.Vector(t.pt,this);return ME.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 ME.Segment(this,e)]}return e instanceof ME.Line?ME.Distance.point2line(this,e):e instanceof ME.Circle?ME.Distance.point2circle(this,e):e instanceof ME.Segment?ME.Distance.point2segment(this,e):e instanceof ME.Arc?ME.Distance.point2arc(this,e):e instanceof ME.Box?ME.Distance.point2polygon(this,new ME.Polygon(e)):e instanceof ME.Polygon?ME.Distance.point2polygon(this,e):e instanceof ME.PlanarSet?ME.Distance.shape2planarSet(this,e):e instanceof ME.Multiline?ME.Distance.shape2multiline(this,e):void 0}on(t){if(t instanceof ME.Point)return this.equalTo(t);if(t.contains\u0026\u0026t.contains instanceof Function)return t.contains(this);throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}get name(){return\"point\"}svg(t={}){const e=t.r??3;return`\\n\u003ccircle cx=\"${this.x}\" cy=\"${this.y}\" r=\"${e}\"\\n ${EE({fill:\"red\",...t})} /\u003e`}};var mO=(...t)=\u003enew ME.Point(...t);ME.point=mO;ME.Vector=class extends pO{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length\u0026\u0026t[0]instanceof Array\u0026\u00262===t[0].length){let e=t[0];if(\"number\"==typeof e[0]\u0026\u0026\"number\"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"vector\"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"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\u0026\u0026\"number\"==typeof n)return this.x=e,void(this.y=n);if(e instanceof ME.Point\u0026\u0026n instanceof ME.Point)return this.x=n.x-e.x,void(this.y=n.y-e.y)}throw NE.ILLEGAL_PARAMETERS}}clone(){return new ME.Vector(this.x,this.y)}get slope(){let t=Math.atan2(this.y,this.x);return t\u003c0\u0026\u0026(t=2*Math.PI+t),t}get length(){return Math.sqrt(this.dot(this))}isZeroLength(){return ME.Utils.EQ_0(this.length)}equalTo(t){return ME.Utils.EQ(this.x,t.x)\u0026\u0026ME.Utils.EQ(this.y,t.y)}multiply(t){return new ME.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 NE.ZERO_DIVISION;return new ME.Vector(this.x/this.length,this.y/this.length)}rotate(t,e=new ME.Point){if(0===e.x\u0026\u00260===e.y)return this.transform((new aO).rotate(t));throw NE.OPERATION_IS_NOT_SUPPORTED}transform(t){return new ME.Vector(t.transform([this.x,this.y]))}rotate90CCW(){return new ME.Vector(-this.y,this.x)}rotate90CW(){return new ME.Vector(this.y,-this.x)}invert(){return new ME.Vector(-this.x,-this.y)}add(t){return new ME.Vector(this.x+t.x,this.y+t.y)}subtract(t){return new ME.Vector(this.x-t.x,this.y-t.y)}angleTo(t){let e=this.normalize(),n=t.normalize(),o=Math.atan2(e.cross(n),e.dot(n));return o\u003c0\u0026\u0026(o+=2*Math.PI),o}projectionOn(t){let e=t.normalize(),n=this.dot(e);return e.multiply(n)}get name(){return\"vector\"}};var gO=(...t)=\u003enew ME.Vector(...t);ME.vector=gO;ME.Segment=class t extends pO{constructor(...t){if(super(),this.ps=new ME.Point,this.pe=new ME.Point,0!==t.length){if(1===t.length\u0026\u0026t[0]instanceof Array\u0026\u00264===t[0].length){let e=t[0];return this.ps=new ME.Point(e[0],e[1]),void(this.pe=new ME.Point(e[2],e[3]))}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"segment\"===t[0].name){let{ps:e,pe:n}=t[0];return this.ps=new ME.Point(e.x,e.y),void(this.pe=new ME.Point(n.x,n.y))}if(!(1===t.length\u0026\u0026t[0]instanceof ME.Point)){if(2===t.length\u0026\u0026t[0]instanceof ME.Point\u0026\u0026t[1]instanceof ME.Point)return this.ps=t[0].clone(),void(this.pe=t[1].clone());if(4===t.length)return this.ps=new ME.Point(t[0],t[1]),void(this.pe=new ME.Point(t[2],t[3]));throw NE.ILLEGAL_PARAMETERS}this.ps=t[0].clone()}}clone(){return new ME.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 ME.Vector(this.start,this.end).slope}get box(){return new ME.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)\u0026\u0026this.pe.equalTo(t.pe)}contains(t){return ME.Utils.EQ_0(this.distanceToPoint(t))}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?DE(this,t):t instanceof ME.Ray?oA(t,this):t instanceof ME.Segment?zE(this,t):t instanceof ME.Circle?jE(this,t):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=zE(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?$E(this,t):t instanceof ME.Polygon?ZE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2segment(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.segment2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.segment2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2segment(this,t);return[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.segment2arc(this,t);return[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline)return ME.Distance.shape2multiline(this,t)}tangentInStart(){return new ME.Vector(this.start,this.end).normalize()}tangentInEnd(){return new ME.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 ME.Segment(this.start,t),new ME.Segment(t,this.end)]}middle(){return new ME.Point((this.start.x+this.end.x)/2,(this.start.y+this.end.y)/2)}pointAtLength(t){if(t\u003ethis.length||t\u003c0)return null;if(0==t)return this.start;if(t==this.length)return this.end;let e=t/this.length;return new ME.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]=ME.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 ME.Matrix){return new t(this.ps.transform(e),this.pe.transform(e))}isZeroLength(){return this.ps.equalTo(this.pe)}sortPoints(t){return new ME.Line(this.start,this.end).sortPoints(t)}get name(){return\"segment\"}svg(t={}){return`\\n\u003cline x1=\"${this.start.x}\" y1=\"${this.start.y}\" x2=\"${this.end.x}\" y2=\"${this.end.y}\" ${EE(t)} /\u003e`}};var fO=(...t)=\u003enew ME.Segment(...t);ME.segment=fO;var{vector:yO}=ME;ME.Line=class t extends pO{constructor(...e){if(super(),this.pt=new ME.Point,this.norm=new ME.Vector(0,1),0!==e.length){if(1===e.length\u0026\u0026e[0]instanceof Object\u0026\u0026\"line\"===e[0].name){let{pt:t,norm:n}=e[0];return this.pt=new ME.Point(t),void(this.norm=new ME.Vector(n))}if(2===e.length){let n=e[0],o=e[1];if(n instanceof ME.Point\u0026\u0026o instanceof ME.Point)return this.pt=n,this.norm=t.points2norm(n,o),void(this.norm.dot(yO(this.pt.x,this.pt.y))\u003e=0\u0026\u0026this.norm.invert());if(n instanceof ME.Point\u0026\u0026o instanceof ME.Vector){if(ME.Utils.EQ_0(o.x)\u0026\u0026ME.Utils.EQ_0(o.y))throw NE.ILLEGAL_PARAMETERS;return this.pt=n.clone(),this.norm=o.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(yO(this.pt.x,this.pt.y))\u003e=0\u0026\u0026this.norm.invert())}if(n instanceof ME.Vector\u0026\u0026o instanceof ME.Point){if(ME.Utils.EQ_0(n.x)\u0026\u0026ME.Utils.EQ_0(n.y))throw NE.ILLEGAL_PARAMETERS;return this.pt=o.clone(),this.norm=n.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(yO(this.pt.x,this.pt.y))\u003e=0\u0026\u0026this.norm.invert())}}throw NE.ILLEGAL_PARAMETERS}}clone(){return new ME.Line(this.pt,this.norm)}get start(){}get end(){}get length(){return Number.POSITIVE_INFINITY}get box(){return new ME.Box(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)}get middle(){}get slope(){return new ME.Vector(this.norm.y,-this.norm.x).slope}get standard(){return[this.norm.x,this.norm.y,this.norm.dot(yO(this.pt.x,this.pt.y))]}parallelTo(t){return ME.Utils.EQ_0(this.norm.cross(t.norm))}incidentTo(t){return this.parallelTo(t)\u0026\u0026this.pt.on(t)}contains(t){if(this.pt.equalTo(t))return!0;let e=new ME.Vector(this.pt,t);return ME.Utils.EQ_0(this.norm.dot(e))}coord(t){return yO(t.x,t.y).cross(this.norm)}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?AE(this,t):t instanceof ME.Ray?sA(t,this):t instanceof ME.Circle?OE(this,t):t instanceof ME.Box?kE(this,t):t instanceof ME.Segment?DE(t,this):t instanceof ME.Arc?LE(this,t):t instanceof ME.Polygon?JE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.circle2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2line(t,this);return[e,n.reverse()]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2line(t,this);return[e,n.reverse()]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}}split(t){if(t instanceof ME.Point)return[new ME.Ray(t,this.norm),new ME.Ray(t,this.norm)];{let e=new ME.Multiline([this]),n=this.sortPoints(t);return e.split(n),e.toShapes()}}rotate(t,e=new ME.Point){return new ME.Line(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new ME.Line(this.pt.transform(t),this.norm.clone())}sortPoints(t){return t.slice().sort((t,e)=\u003ethis.coord(t)\u003cthis.coord(e)?-1:this.coord(t)\u003ethis.coord(e)?1:0)}get name(){return\"line\"}svg(t,e={}){let n=kE(this,t);if(0===n.length)return\"\";let o=n[0],i=2===n.length?n[1]:n.find(t=\u003e!t.equalTo(o));return void 0===i\u0026\u0026(i=o),new ME.Segment(o,i).svg(e)}static points2norm(t,e){if(t.equalTo(e))throw NE.ILLEGAL_PARAMETERS;return new ME.Vector(t,e).normalize().rotate90CCW()}};var _O=(...t)=\u003enew ME.Line(...t);ME.line=_O;ME.Circle=class extends pO{constructor(...t){if(super(),this.pc=new ME.Point,this.r=1,1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"circle\"===t[0].name){let{pc:e,r:n}=t[0];this.pc=new ME.Point(e),this.r=n}else{let[e,n]=[...t];e\u0026\u0026e instanceof ME.Point\u0026\u0026(this.pc=e.clone()),void 0!==n\u0026\u0026(this.r=n)}}clone(){return new ME.Circle(this.pc.clone(),this.r)}get center(){return this.pc}get box(){return new ME.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 ME.Point?ME.Utils.LE(t.distanceTo(this.center)[0],this.r):t instanceof ME.Segment?ME.Utils.LE(t.start.distanceTo(this.center)[0],this.r)\u0026\u0026ME.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof ME.Arc?0===this.intersect(t).length\u0026\u0026ME.Utils.LE(t.start.distanceTo(this.center)[0],this.r)\u0026\u0026ME.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof ME.Circle?0===this.intersect(t).length\u0026\u0026ME.Utils.LE(t.r,this.r)\u0026\u0026ME.Utils.LE(t.center.distanceTo(this.center)[0],this.r):void 0}toArc(t=!0){return new ME.Arc(this.center,this.r,Math.PI,-Math.PI,t)}scale(t,e){if(t!==e)throw NE.OPERATION_IS_NOT_SUPPORTED;if(0!==this.pc.x||0!==this.pc.y)throw NE.OPERATION_IS_NOT_SUPPORTED;return new ME.Circle(this.pc,this.r*t)}transform(t=new ME.Matrix){return new ME.Circle(this.pc.transform(t),this.r)}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?OE(t,this):t instanceof ME.Ray?rA(t,this):t instanceof ME.Segment?jE(t,this):t instanceof ME.Circle?YE(t,this):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=jE(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?VE(t,this):t instanceof ME.Polygon?KE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.circle2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.circle2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline){let[e,n]=ME.Distance.shape2multiline(this,t);return[e,n]}}get name(){return\"circle\"}svg(t={}){return`\\n\u003ccircle cx=\"${this.pc.x}\" cy=\"${this.pc.y}\" r=\"${this.r}\"\\n ${EE({fill:\"none\",...t})} /\u003e`}};ME.circle=(...t)=\u003enew ME.Circle(...t);ME.Arc=class extends pO{constructor(...t){if(super(),this.pc=new ME.Point,this.r=1,this.startAngle=0,this.endAngle=2*Math.PI,this.counterClockwise=!0,0!==t.length)if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"arc\"===t[0].name){let{pc:e,r:n,startAngle:o,endAngle:i,counterClockwise:r}=t[0];this.pc=new ME.Point(e.x,e.y),this.r=n,this.startAngle=o,this.endAngle=i,this.counterClockwise=r}else{let[e,n,o,i,r]=[...t];e\u0026\u0026e instanceof ME.Point\u0026\u0026(this.pc=e.clone()),void 0!==n\u0026\u0026(this.r=n),void 0!==o\u0026\u0026(this.startAngle=o),void 0!==i\u0026\u0026(this.endAngle=i),void 0!==r\u0026\u0026(this.counterClockwise=r)}}clone(){return new ME.Arc(this.pc.clone(),this.r,this.startAngle,this.endAngle,this.counterClockwise)}get sweep(){let t=this.startAngle,e=this.endAngle;if(ME.Utils.EQ(Math.abs(t-e),ME.PIx2))return ME.PIx2;Math.abs(t)\u003eME.PIx2\u0026\u0026(t-=Math.trunc(t/ME.PIx2)*ME.PIx2),t\u003c0\u0026\u0026(t+=ME.PIx2),Math.abs(e)\u003eME.PIx2\u0026\u0026(e-=Math.trunc(e/ME.PIx2)*ME.PIx2),e\u003c0\u0026\u0026(e+=ME.PIx2);let n=this.counterClockwise?e-t:t-e;return n\u003c0\u0026\u0026(n+=ME.PIx2),n}get start(){return new ME.Point(this.pc.x+this.r,this.pc.y).rotate(this.startAngle,this.pc)}get end(){return new ME.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)=\u003et.merge(e.start.box),new ME.Box);return t=t.merge(this.end.box),t}contains(t){if(!ME.Utils.EQ(this.pc.distanceTo(t)[0],this.r))return!1;if(t.equalTo(this.start))return!0;let e=new ME.Vector(this.pc,t).slope,n=new ME.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise);return ME.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 ME.Vector(this.pc,t).slope;return[new ME.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise),new ME.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 ME.Arc(this.pc,this.r,this.startAngle,t,this.counterClockwise).end}pointAtLength(t){if(t\u003ethis.length||t\u003c0)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 ME.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 ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?LE(t,this):t instanceof ME.Ray?iA(t,this):t instanceof ME.Circle?VE(this,t):t instanceof ME.Segment?$E(t,this):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=$E(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?XE(this,t):t instanceof ME.Polygon?qE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.arc2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.arc2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2arc(this,t);return[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline)return ME.Distance.shape2multiline(this,t)}breakToFunctional(){let t=[],e=[0,Math.PI/2,Math.PI,3*Math.PI/2],n=this.startAngle,o=this.endAngle;ME.Utils.EQ(Math.abs(n-o),ME.PIx2)\u0026\u0026(o=n),Math.abs(n)\u003eME.PIx2\u0026\u0026(n-=Math.trunc(n/ME.PIx2)*ME.PIx2),n\u003c0\u0026\u0026(n+=ME.PIx2),Math.abs(o)\u003eME.PIx2\u0026\u0026(o-=Math.trunc(o/ME.PIx2)*ME.PIx2),o\u003c0\u0026\u0026(o+=ME.PIx2);let i,r,s,a=n;this.counterClockwise?(r=Math.ceil(n/(Math.PI/2))%4,s=1):(r=Math.floor(n/(Math.PI/2))%4,s=-1);for(let o=0,c=r;o\u003c4;o++,c=(c+s+4)%4){if(i=e[c],i===a)continue;let o=this.counterClockwise?i-n:n-i;if(o\u003c0\u0026\u0026(o+=ME.PIx2),o\u003ethis.sweep)break;t.push(new ME.Arc(this.pc,this.r,a,i,this.counterClockwise)),a=i}return 0===t.length?(t.push(this),t):(i=o,a!==i\u0026\u0026t.push(new ME.Arc(this.pc,this.r,a,i,this.counterClockwise)),t)}tangentInStart(){let t=new ME.Vector(this.pc,this.start),e=this.counterClockwise?Math.PI/2:-Math.PI/2;return t.rotate(e).normalize()}tangentInEnd(){let t=new ME.Vector(this.pc,this.end),e=this.counterClockwise?-Math.PI/2:Math.PI/2;return t.rotate(e).normalize()}reverse(){return new ME.Arc(this.pc,this.r,this.endAngle,this.startAngle,!this.counterClockwise)}transform(t=new ME.Matrix){let e=this.start.transform(t),n=this.end.transform(t),o=this.pc.transform(t),i=this.counterClockwise;return t.a*t.d\u003c0\u0026\u0026(i=!i),ME.Arc.arcSE(o,e,n,i)}static arcSE(t,e,n,o){let{vector:i}=ME,r=i(t,e).slope,s=i(t,n).slope;ME.Utils.EQ(r,s)\u0026\u0026(s+=2*Math.PI,o=!0);let a=i(t,e).length;return new ME.Arc(t,a,r,s,o)}definiteIntegral(t=0){return this.breakToFunctional().reduce((e,n)=\u003ee+n.circularSegmentDefiniteIntegral(t),0)}circularSegmentDefiniteIntegral(t){let e=new ME.Segment(this.start,this.end).definiteIntegral(t),n=ME.Utils.EQ(this.sweep,ME.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}=ME;return t.slice().sort((t,n)=\u003e{let o=e(this.pc,t).slope,i=e(this.pc,n).slope;return o\u003ci?-1:o\u003ei?1:0})}get name(){return\"arc\"}svg(t={}){let e=this.sweep\u003c=Math.PI?\"0\":\"1\",n=this.counterClockwise?\"1\":\"0\";if(ME.Utils.EQ(this.sweep,2*Math.PI)){return new ME.Circle(this.pc,this.r).svg(t)}return`\\n\u003cpath d=\"M${this.start.x},${this.start.y}\\n A${this.r},${this.r} 0 ${e},${n} ${this.end.x},${this.end.y}\"\\n ${EE({fill:\"none\",...t})} /\u003e`}};ME.arc=(...t)=\u003enew ME.Arc(...t);ME.Box=class t extends pO{constructor(t=void 0,e=void 0,n=void 0,o=void 0){super(),this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}clone(){return new t(this.xmin,this.ymin,this.xmax,this.ymax)}get low(){return new ME.Point(this.xmin,this.ymin)}get high(){return new ME.Point(this.xmax,this.ymax)}get max(){return this.clone()}get center(){return new ME.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\u003ct.xmin||this.xmin\u003et.xmax||this.ymax\u003ct.ymin||this.ymin\u003et.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)\u0026\u0026this.high.equalTo(t.high)}output(){return this.clone()}comparable_less_than(t,e){return t.lessThan(e)}set(t,e,n,o){this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}extend(e){return e\u003c=0?this.clone():new t(this.xmin-e,this.ymin-e,this.xmax+e,this.ymax+e)}toPoints(){return[new ME.Point(this.xmin,this.ymin),new ME.Point(this.xmax,this.ymin),new ME.Point(this.xmax,this.ymax),new ME.Point(this.xmin,this.ymax)]}toSegments(){let t=this.toPoints();return[new ME.Segment(t[0],t[1]),new ME.Segment(t[1],t[2]),new ME.Segment(t[2],t[3]),new ME.Segment(t[3],t[0])]}rotate(t,e=new ME.Point){throw NE.OPERATION_IS_NOT_SUPPORTED}transform(e=new ME.Matrix){return this.toPoints().map(t=\u003et.transform(e)).reduce((t,e)=\u003et.merge(e.box),new t)}contains(t){return t instanceof ME.Point?t.x\u003e=this.xmin\u0026\u0026t.x\u003c=this.xmax\u0026\u0026t.y\u003e=this.ymin\u0026\u0026t.y\u003c=this.ymax:t instanceof ME.Segment?t.vertices.every(t=\u003ethis.contains(t)):t instanceof ME.Box?t.toSegments().every(t=\u003ethis.contains(t)):t instanceof ME.Circle?this.contains(t.box):t instanceof ME.Arc?t.vertices.every(t=\u003ethis.contains(t))\u0026\u0026this.toSegments().every(e=\u003e0===$E(e,t).length):!(t instanceof ME.Line||t instanceof ME.Ray)\u0026\u0026(t instanceof ME.Multiline?t.toShapes().every(t=\u003ethis.contains(t)):t instanceof ME.Polygon?this.contains(t.box):void 0)}distanceTo(t){const e=this.toSegments().map(e=\u003ee.distanceTo(t));let n=[Number.MAX_SAFE_INTEGER,null];return e.forEach(t=\u003e{t[0]\u003cn[0]\u0026\u0026(n=t)}),n}get name(){return\"box\"}svg(t={}){const e=this.xmax-this.xmin,n=this.ymax-this.ymin;return`\\n\u003crect x=\"${this.xmin}\" y=\"${this.ymin}\" width=\"${e}\" height=\"${n}\"\\n ${EE({fill:\"none\",...t})} /\u003e`}};ME.box=(...t)=\u003enew ME.Box(...t);ME.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 ME.Segment}get isArc(){return this.shape instanceof ME.Arc}get isLine(){return this.shape instanceof ME.Line}get isRay(){return this.shape instanceof ME.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 ME.Line||this.shape instanceof ME.Ray)return this.bv=ME.OUTSIDE,this.bv;if(void 0===this.bvStart\u0026\u0026(this.bvStart=KA(t,this.start)),void 0===this.bvEnd\u0026\u0026(this.bvEnd=KA(t,this.end)),this.bvStart===ME.OUTSIDE||this.bvEnd==ME.OUTSIDE)this.bv=ME.OUTSIDE;else if(this.bvStart===ME.INSIDE||this.bvEnd==ME.INSIDE)this.bv=ME.INSIDE;else{let e=KA(t,this.middle());this.bv=e}return this.bv}setOverlap(t){let e,n=this.shape,o=t.shape;n instanceof ME.Segment\u0026\u0026o instanceof ME.Segment?n.start.equalTo(o.start)\u0026\u0026n.end.equalTo(o.end)?e=ME.OVERLAP_SAME:n.start.equalTo(o.end)\u0026\u0026n.end.equalTo(o.start)\u0026\u0026(e=ME.OVERLAP_OPPOSITE):(n instanceof ME.Arc\u0026\u0026o instanceof ME.Arc||n instanceof ME.Segment\u0026\u0026o instanceof ME.Arc||n instanceof ME.Arc\u0026\u0026o instanceof ME.Segment)\u0026\u0026(n.start.equalTo(o.start)\u0026\u0026n.end.equalTo(o.end)\u0026\u0026n.middle().equalTo(o.middle())?e=ME.OVERLAP_SAME:n.start.equalTo(o.end)\u0026\u0026n.end.equalTo(o.start)\u0026\u0026n.middle().equalTo(o.middle())\u0026\u0026(e=ME.OVERLAP_OPPOSITE)),void 0===this.overlap\u0026\u0026(this.overlap=e),void 0===t.overlap\u0026\u0026(t.overlap=e)}svg(){if(this.shape instanceof ME.Segment)return` L${this.shape.end.x},${this.shape.end.y}`;if(this.shape instanceof ME.Arc){let t,e=this.shape,n=e.counterClockwise?\"1\":\"0\";if(ME.Utils.EQ(e.sweep,2*Math.PI)){let o=e.counterClockwise?1:-1,i=new ME.Arc(e.pc,e.r,e.startAngle,e.startAngle+o*Math.PI,e.counterClockwise),r=new ME.Arc(e.pc,e.r,e.startAngle+o*Math.PI,e.endAngle,e.counterClockwise);return t=\"0\",` A${i.r},${i.r} 0 ${t},${n} ${i.end.x},${i.end.y}\\n A${r.r},${r.r} 0 ${t},${n} ${r.end.x},${r.end.y}`}return t=e.sweep\u003c=Math.PI?\"0\":\"1\",` A${e.r},${e.r} 0 ${t},${n} ${e.end.x},${e.end.y}`}}toJSON(){return this.shape.toJSON()}};var bO=class extends wE{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:()=\u003e{let e=t||this.first,n=!this.first||!!t\u0026\u0026t===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}};ME.Face=class t extends bO{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 o=n[0];if(0===o.length)return;if(o.every(t=\u003et instanceof ME.Point)){let n=t.points2segments(o);this.shapes2face(e.edges,n)}else if(o.every(t=\u003et instanceof Array\u0026\u00262===t.length)){let n=o.map(t=\u003enew ME.Point(t[0],t[1])),i=t.points2segments(n);this.shapes2face(e.edges,i)}else if(o.every(t=\u003et instanceof ME.Segment||t instanceof ME.Arc))this.shapes2face(e.edges,o);else if(o.every(t=\u003e\"segment\"===t.name||\"arc\"===t.name)){let t=[];for(let e of o){let n;n=\"segment\"===e.name?new ME.Segment(e):new ME.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 ME.Circle)this.shapes2face(e.edges,[n[0].toArc(gE)]);else if(n[0]instanceof ME.Box){let t=n[0];this.shapes2face(e.edges,[new ME.Segment(new ME.Point(t.xmin,t.ymin),new ME.Point(t.xmax,t.ymin)),new ME.Segment(new ME.Point(t.xmax,t.ymin),new ME.Point(t.xmax,t.ymax)),new ME.Segment(new ME.Point(t.xmax,t.ymax),new ME.Point(t.xmin,t.ymax)),new ME.Segment(new ME.Point(t.xmin,t.ymax),new ME.Point(t.xmin,t.ymin))])}2===n.length\u0026\u0026n[0]instanceof ME.Edge\u0026\u0026n[1]instanceof ME.Edge\u0026\u0026(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=\u003et.shape.start.clone())}get shapes(){return this.edges.map(t=\u003et.shape.clone())}get box(){if(void 0===this._box){let t=new ME.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\u003ethis.perimeter||t\u003c0)return null;let e=null;for(let n of this)if(t\u003e=n.arc_length\u0026\u0026(n===this.last||t\u003cn.next.arc_length)){e=n.pointAtLength(t-n.arc_length);break}return e}static points2segments(t){let e=[];for(let n=0;n\u003ct.length;n++)t[n].equalTo(t[(n+1)%t.length])||e.push(new ME.Segment(t[n],t[(n+1)%t.length]));return e}shapes2face(t,e){for(let n of e){let e=new ME.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\u0026\u0026(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();ME.Utils.EQ_0(t)?this._orientation=fE.NOT_ORIENTABLE:ME.Utils.LT(t,0)?this._orientation=fE.CCW:this._orientation=fE.CW}return this._orientation}isSimple(e){return 0===t.getSelfIntersections(this,e,!0).length}static getSelfIntersections(t,e,n=!1){let o=[];for(let i of t){let r=e.search(i.box);for(let e of r){if(i===e)continue;if(e.face!==t)continue;if(i.shape instanceof ME.Segment\u0026\u0026e.shape instanceof ME.Segment\u0026\u0026(i.next===e||i.prev===e))continue;let r=i.shape.intersect(e.shape);for(let t of r)if((!t.equalTo(i.start)||!t.equalTo(e.end)||e!==i.prev)\u0026\u0026(!t.equalTo(i.end)||!t.equalTo(e.start)||e!==i.next)\u0026\u0026(o.push(t),n))break;if(o.length\u003e0\u0026\u0026n)break}if(o.length\u003e0\u0026\u0026n)break}return o}findEdgeByPoint(t){let e;for(let n of this)if(!t.equalTo(n.shape.start)\u0026\u0026(t.equalTo(n.shape.end)||n.shape.contains(t))){e=n;break}return e}toPolygon(){return new ME.Polygon(this.shapes)}toJSON(){return this.edges.map(t=\u003et.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}};ME.Ray=class t extends pO{constructor(...t){if(super(),this.pt=new ME.Point,this.norm=new ME.Vector(0,1),0!==t.length\u0026\u0026(t.length\u003e=1\u0026\u0026t[0]instanceof ME.Point\u0026\u0026(this.pt=t[0].clone()),1!==t.length)){if(!(2===t.length\u0026\u0026t[1]instanceof ME.Vector))throw NE.ILLEGAL_PARAMETERS;this.norm=t[1].clone()}}clone(){return new t(this.pt,this.norm)}get slope(){return new ME.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new ME.Box(t\u003eMath.PI/2\u0026\u0026t\u003c3*Math.PI/2?Number.NEGATIVE_INFINITY:this.pt.x,t\u003e=0\u0026\u0026t\u003c=Math.PI?this.pt.y:Number.NEGATIVE_INFINITY,t\u003e=Math.PI/2\u0026\u0026t\u003c=3*Math.PI/2?this.pt.x:Number.POSITIVE_INFINITY,t\u003e=Math.PI\u0026\u0026t\u003c=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 ME.Vector(this.pt,t);return ME.Utils.EQ_0(this.norm.dot(e))\u0026\u0026ME.Utils.GE(e.cross(this.norm),0)}coord(t){return gO(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new ME.Segment(this.pt,t),new ME.Ray(t,this.norm)]:[]}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Segment?oA(this,t):t instanceof ME.Arc?iA(this,t):t instanceof ME.Line?sA(this,t):t instanceof ME.Ray?(n=t,AE(nA(e=this),nA(n)).filter(t=\u003ee.contains(t)).filter(t=\u003en.contains(t))):t instanceof ME.Circle?rA(this,t):t instanceof ME.Box?(i=t,kE(nA(o=this),i).filter(t=\u003eo.contains(t))):t instanceof ME.Polygon?aA(this,t):t instanceof ME.Multiline?lA(this,t):void 0;var e,n,o,i}rotate(t,e=new ME.Point){return new ME.Ray(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new ME.Ray(this.pt.transform(t),this.norm.clone())}get name(){return\"ray\"}svg(t,e={}){let n=kE(new ME.Line(this.pt,this.norm),t);return n=n.filter(t=\u003ethis.contains(t)),0===n.length||2===n.length?\"\":new ME.Segment(this.pt,n[0]).svg(e)}};ME.ray=(...t)=\u003enew ME.Ray(...t);var xO=class t{constructor(){this.faces=new ME.PlanarSet,this.edges=new ME.PlanarSet;let t=[...arguments];if(1===t.length\u0026\u0026(t[0]instanceof Array\u0026\u0026t[0].length\u003e0||t[0]instanceof ME.Circle||t[0]instanceof ME.Box)){let e=t[0];if(t[0]instanceof Array\u0026\u0026t[0].every(t=\u003et instanceof Array))if(e.every(t=\u003et instanceof Array\u0026\u00262===t.length\u0026\u0026\"number\"==typeof t[0]\u0026\u0026\"number\"==typeof t[1]))this.faces.add(new ME.Face(this,e));else for(let t of e)if(t instanceof Array\u0026\u0026t[0]instanceof Array\u0026\u0026t[0].every(t=\u003et instanceof Array\u0026\u00262===t.length\u0026\u0026\"number\"==typeof t[0]\u0026\u0026\"number\"==typeof t[1]))for(let e of t)this.faces.add(new ME.Face(this,e));else this.faces.add(new ME.Face(this,t));else this.faces.add(new ME.Face(this,e))}}get box(){return[...this.faces].reduce((t,e)=\u003et.merge(e.box),new ME.Box)}get vertices(){return[...this.faces].flatMap(t=\u003et.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=\u003e[...t.faces].forEach(t=\u003en.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)=\u003et+e.signedArea(),0);return Math.abs(t)}addFace(...t){let e=new ME.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 o=e;o!==n.next;o=o.next)if(t.remove(o),this.edges.delete(o),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 o=new ME.Edge(n[0]),i=e.prev;return e.face.insert(o,i),this.edges.delete(e),this.edges.add(o),e.shape=n[1],this.edges.add(e),o}removeEndVertex(t){const e=t.next;e!==t\u0026\u0026(t.face.merge_with_next_edge(t),this.edges.delete(e))}cut(t){const e=this.splitToIslands().flatMap(e=\u003ee._cutSingleIsland(t)).filter(t=\u003et.isValid()\u0026\u0026!1===t.isEmpty());return this.createFromArray(e)}_cutSingleIsland(t){let e=this.clone();const n=t.clone();let o,i,r={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let t of n.edges)for(let n of e.edges){let e=QE(t,n);for(let o of e)hA(t,o,r.int_points1),hA(n,o,r.int_points2)}if(0===r.int_points1.length)return e;r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2),bA(n,r.int_points1_sorted),bA(e,r.int_points2_sorted),gA(r),r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2),fA(r.int_points1),yA(r.int_points1,e);for(let t of r.int_points1_sorted)t.edge_before\u0026\u0026t.edge_after\u0026\u0026t.edge_before.bv===t.edge_after.bv\u0026\u0026(r.int_points2[t.id]=-1,t.id=-1);if(r.int_points1=r.int_points1.filter(t=\u003et.id\u003e=0),r.int_points2=r.int_points2.filter(t=\u003et.id\u003e=0),r.int_points1.forEach((t,e)=\u003e{t.id=e}),r.int_points2.forEach((t,e)=\u003e{t.id=e}),0===r.int_points1.length)return e;r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2);for(let t=1;t\u003cr.int_points1_sorted.length;t++)if(i=r.int_points1_sorted[t],o=r.int_points1_sorted[t-1],i.edge_before\u0026\u00261===i.edge_before.bv){let t=o.edge_after,s=i.edge_before,a=n.getChain(t,s);xA(r.int_points2[o.id],r.int_points2[i.id],a),a.forEach(t=\u003ee.edges.add(t)),a=a.reverse().map(t=\u003enew ME.Edge(t.shape.reverse()));for(let t=0;t\u003ca.length-1;t++)a[t].next=a[t+1],a[t+1].prev=a[t];xA(r.int_points2[i.id],r.int_points2[o.id],a),a.forEach(t=\u003ee.edges.add(t))}return e.recreateFaces(),e}cutWithLine(t){let e=new dA([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)=\u003ee.area()-t.area());let e=[...t[0].faces][0].orientation(),n=t.filter(t=\u003e[...t.faces][0].orientation()===e);for(let o of t){let t=[...o.faces][0];if(t.orientation()!==e)for(let e of n)if(t.shapes.every(t=\u003ee.contains(t))){e.addFace(t.shapes);break}}return n}rearrange(){if(this.faces.size\u003c=1)return this.clone();const e=this.splitToIslands(),n=new t;return e.forEach(t=\u003e{t.faces.forEach(t=\u003en.addFace(t.shapes))}),n}orientation(){return this.isEmpty()?fE.NOT_ORIENTABLE:[...this.faces][0].orientation()}isOuter(t){return t.orientation()===this.orientation()}isMultiPolygon(){let t=0;return this.faces.forEach(e=\u003e{this.isOuter(e)\u0026\u0026t++}),t\u003e1}reverse(){for(let t of this.faces)t.reverse();return this}contains(t){if(t instanceof ME.Point){let e=KA(this,t);return 1===e||2===e}return nO(this,t)}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle||t instanceof ME.Line||t instanceof ME.Segment||t instanceof ME.Arc){let[e,n]=ME.Distance.shape2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Box)return this.distanceTo(new ME.Polygon(t));if(t instanceof ME.Polygon){let e,n,o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of this.edges){let r=o[0];[e,n]=ME.Distance.shape2planarSet(i.shape,t.edges,r),ME.Utils.LT(e,r)\u0026\u0026(o=[e,n])}return o}}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?JE(t,this):t instanceof ME.Ray?aA(t,this):t instanceof ME.Circle?KE(t,this):t instanceof ME.Segment?ZE(t,this):t instanceof ME.Arc?qE(t,this):t instanceof ME.Polygon?function(t,e){let n=[];if(t.isEmpty()||e.isEmpty())return n;if(t.box.not_intersect(e.box))return n;for(let o of t.edges)n=[...n,...tA(o,e)];return n}(t,this):t instanceof ME.Multiline?function(t,e){let n=[];if(e.isEmpty()||0===t.size)return n;for(let o of t)n=[...n,...tA(o,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=\u003et.translate(e)));return n}rotate(e=0,n=new ME.Point){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=\u003et.rotate(e,n)));return o}scale(e,n){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=\u003et.scale(e,n)));return o}transform(e=new ME.Matrix){let n=new t;for(let t of this.faces)n.addFace(t.shapes.map(t=\u003et.transform(e)));return n}toJSON(){return[...this.faces].map(t=\u003et.toJSON())}toArray(){return[...this.faces].map(t=\u003et.toPolygon())}dpath(){return[...this.faces].reduce((t,e)=\u003et+e.svg(),\"\")}svg(t={}){let e=`\\n\u003cpath ${EE({fillRule:\"evenodd\",fill:\"lightcyan\",...t})} d=\"`;for(let t of this.faces)e+=`\\n${t.svg()}`;return e+='\" \u003e\\n\u003c/path\u003e',e}};ME.Polygon=xO;ME.polygon=(...t)=\u003enew ME.Polygon(...t);var{Circle:vO,Line:SO,Point:IO,Vector:CO,Utils:PO}=ME;ME.Inversion=class t{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,e){const n=new CO(t.pc,e),o=t.r*t.r,i=n.dot(n);return PO.EQ_0(i)?new IO(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY):t.pc.translate(n.multiply(o/i))}static inverseCircle(t,e){const n=t.pc.distanceTo(e.pc)[0];if(PO.EQ(n,e.r)){let n=t.r*t.r/(2*e.r),o=new CO(t.pc,e.pc);o=o.normalize();let i=t.pc.translate(o.multiply(n));return new SO(i,o)}{let n=new CO(t.pc,e.pc),o=t.r*t.r/(n.dot(n)-e.r*e.r),i=t.pc.translate(n.multiply(o)),r=Math.abs(o)*e.r;return new vO(i,r)}}static inverseLine(t,e){const[n,o]=t.pc.distanceTo(e);if(PO.EQ_0(n))return e.clone();{let e=t.r*t.r/(2*n),i=new CO(t.pc,o.end);return i=i.multiply(e/n),new vO(t.pc.translate(i),e)}}inverse(e){return e instanceof IO?t.inversePoint(this.circle,e):e instanceof vO?t.inverseCircle(this.circle,e):e instanceof SO?t.inverseLine(this.circle,e):void 0}};ME.inversion=t=\u003enew ME.Inversion(t);ME.Distance=class t{static point2point(t,e){return t.distanceTo(e)}static point2line(t,e){let n=t.projectionOn(e);return[new ME.Vector(t,n).length,new ME.Segment(t,n)]}static point2circle(t,e){let[n,o]=t.distanceTo(e.center);if(ME.Utils.EQ_0(n))return[e.r,new ME.Segment(t,e.toArc().start)];{let o=Math.abs(n-e.r),i=new ME.Vector(e.pc,t).normalize().multiply(e.r),r=e.pc.translate(i);return[o,new ME.Segment(t,r)]}}static point2segment(e,n){if(n.start.equalTo(n.end))return t.point2point(e,n.start);let o,i,r=new ME.Vector(n.start,n.end),s=new ME.Vector(n.start,e),a=new ME.Vector(n.end,e),c=r.dot(s),l=-r.dot(a);if(ME.Utils.GE(c,0)\u0026\u0026ME.Utils.GE(l,0)){let t=n.tangentInStart();return o=Math.abs(t.cross(s)),i=n.start.translate(t.multiply(t.dot(s))),[o,new ME.Segment(e,i)]}return c\u003c0?e.distanceTo(n.start):e.distanceTo(n.end)}static point2arc(e,n){let o,i,r=new ME.Circle(n.pc,n.r),s=[];return[o,i]=t.point2circle(e,r),i.end.on(n)\u0026\u0026s.push(t.point2circle(e,r)),s.push(t.point2point(e,n.start)),s.push(t.point2point(e,n.end)),t.sort(s),s[0]}static point2edge(e,n){return n.shape instanceof ME.Segment?t.point2segment(e,n.shape):t.point2arc(e,n.shape)}static segment2line(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=[];return i.push(t.point2line(e.start,n)),i.push(t.point2line(e.end,n)),t.sort(i),i[0]}static segment2segment(e,n){let o=zE(e,n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i,r,s=[];return[i,r]=t.point2segment(n.start,e),s.push([i,r.reverse()]),[i,r]=t.point2segment(n.end,e),s.push([i,r.reverse()]),s.push(t.point2segment(e.start,n)),s.push(t.point2segment(e.end,n)),t.sort(s),s[0]}static segment2circle(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Line(e.ps,e.pe),[r,s]=t.point2line(n.center,i);if(ME.Utils.GE(r,n.r)\u0026\u0026s.end.on(e))return t.point2circle(s.end,n);{let[o,i]=t.point2circle(e.start,n),[r,s]=t.point2circle(e.end,n);return ME.Utils.LT(o,r)?[o,i]:[r,s]}}static segment2arc(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Line(e.ps,e.pe),r=new ME.Circle(n.pc,n.r),[s,a]=t.point2line(r.center,i);if(ME.Utils.GE(s,r.r)\u0026\u0026a.end.on(e)){let[e,o]=t.point2circle(a.end,r);if(o.end.on(n))return[e,o]}let c,l,d=[];return d.push(t.point2arc(e.start,n)),d.push(t.point2arc(e.end,n)),[c,l]=t.point2segment(n.start,e),d.push([c,l.reverse()]),[c,l]=t.point2segment(n.end,e),d.push([c,l.reverse()]),t.sort(d),d[0]}static circle2circle(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];if(e.center.equalTo(n.center)){let o=e.toArc(),i=n.toArc();return t.point2point(o.start,i.start)}{let o=new ME.Line(e.center,n.center),i=o.intersect(e),r=o.intersect(n),s=[];return s.push(t.point2point(i[0],r[0])),s.push(t.point2point(i[0],r[1])),s.push(t.point2point(i[1],r[0])),s.push(t.point2point(i[1],r[1])),t.sort(s),s[0]}}static circle2line(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let[i,r]=t.point2line(e.center,n),[s,a]=t.point2circle(r.end,e);return a=a.reverse(),[s,a]}static arc2line(e,n){let o=n.intersect(e);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),[r,s]=t.point2line(i.center,n);if(!ME.Utils.GE(r,i.r)){let o=[];return o.push(t.point2line(e.start,n)),o.push(t.point2line(e.end,n)),t.sort(o),o[0]}{let[n,o]=t.point2circle(s.end,i);if(o.end.on(e))return[n,o]}}static arc2circle(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),[r,s]=t.circle2circle(i,n);if(s.start.on(e))return[r,s];{let o=[];return o.push(t.point2circle(e.start,n)),o.push(t.point2circle(e.end,n)),t.sort(o),o[0]}}static arc2arc(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),r=new ME.Circle(n.center,n.r),[s,a]=t.circle2circle(i,r);if(a.start.on(e)\u0026\u0026a.end.on(n))return[s,a];{let o,i,r=[];return[o,i]=t.point2arc(e.start,n),i.end.on(n)\u0026\u0026r.push([o,i]),[o,i]=t.point2arc(e.end,n),i.end.on(n)\u0026\u0026r.push([o,i]),[o,i]=t.point2arc(n.start,e),i.end.on(e)\u0026\u0026r.push([o,i.reverse()]),[o,i]=t.point2arc(n.end,e),i.end.on(e)\u0026\u0026r.push([o,i.reverse()]),[o,i]=t.point2point(e.start,n.start),r.push([o,i]),[o,i]=t.point2point(e.start,n.end),r.push([o,i]),[o,i]=t.point2point(e.end,n.start),r.push([o,i]),[o,i]=t.point2point(e.end,n.end),r.push([o,i]),t.sort(r),r[0]}}static point2polygon(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of n.edges){let[n,r]=t.point2edge(e,i);ME.Utils.LT(n,o[0])\u0026\u0026(o=[n,r])}return o}static shape2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new ME.Segment];for(let o of e.edges){let[e,i]=t.distanceTo(o.shape);ME.Utils.LT(e,n[0])\u0026\u0026(n=[e,i])}return n}static polygon2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new ME.Segment];for(let o of t.edges)for(let t of e.edges){let[e,i]=o.shape.distanceTo(t.shape);ME.Utils.LT(e,n[0])\u0026\u0026(n=[e,i])}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)),o=Math.max(Math.max(t.ymin-e.ymax,0),Math.max(e.ymin-t.ymax,0)),i=n*n+o*o,r=t.merge(e),s=r.xmax-r.xmin,a=r.ymax-r.ymin;return[i,s*s+a*a]}static minmax_tree_process_level(e,n,o,i){let r,s;for(let a of n){[r,s]=t.box2box_minmax(e.box,a.item.key);for(let t of a.item.values)t instanceof ME.Edge?i.insert([r,s],t.shape):i.insert([r,s],t);ME.Utils.LT(s,o)\u0026\u0026(o=s)}if(0===n.length)return o;let a=[...n.map(t=\u003et.left.isNil()?void 0:t.left).filter(t=\u003evoid 0!==t),...n.map(t=\u003et.right.isNil()?void 0:t.right).filter(t=\u003evoid 0!==t)].filter(n=\u003e{let[i,r]=t.box2box_minmax(e.box,n.max);return ME.Utils.LE(i,o)});return o=t.minmax_tree_process_level(e,a,o,i)}static minmax_tree(e,n,o){let i=new hO,r=[n.index.root],s=o\u003cNumber.POSITIVE_INFINITY?o*o:Number.POSITIVE_INFINITY;return s=t.minmax_tree_process_level(e,r,s,i),i}static minmax_tree_calc_distance(e,n,o){let i,r;if(null!=n\u0026\u0026!n.isNil()){if([i,r]=t.minmax_tree_calc_distance(e,n.left,o),r)return[i,r];if(ME.Utils.LT(i[0],Math.sqrt(n.item.key.low)))return[i,!0];let[s,a]=t.distanceToArray(e,n.item.values);return ME.Utils.LT(s,i[0])\u0026\u0026(i=[s,a]),[i,r]=t.minmax_tree_calc_distance(e,n.right,i),[i,r]}return[o,!1]}static shape2planarSet(e,n,o=Number.POSITIVE_INFINITY){let i=[o,new ME.Segment],r=!1;if(n instanceof ME.PlanarSet){let s=t.minmax_tree(e,n,o);[i,r]=t.minmax_tree_calc_distance(e,s.root,i)}return i}static sort(t){t.sort((t,e)=\u003eME.Utils.LT(t[0],e[0])?-1:ME.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 ME.Segment];for(let o of e){let[e,i]=t.distanceTo(o);ME.Utils.LT(e,n[0])\u0026\u0026(n=[e,i])}return n}static shape2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of n){let[n,r]=t.distance(e,i.shape);ME.Utils.LT(n,o[0])\u0026\u0026(o=[n,r])}return o}static multiline2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of e)for(let e of n){let[n,r]=t.distance(i.shape,e.shape);ME.Utils.LT(n,o[0])\u0026\u0026(o=[n,r])}return o}};var{Multiline:MO,Point:NO,Segment:wO,Polygon:TO}=ME;function RO(t){return new NO(t.split(\" \").map(Number))}function EO(t){return t.split(\", \").map(RO)}function AO(t){const e=EO(t);let n=[];for(let t=0;t\u003ce.length-1;t++)n.push(new wO(e[t],e[t+1]));return new MO(n)}function OO(t){const e=t.replace(/\\(\\(/,\"\").replace(/\\)\\)$/,\"\").split(\"), (\"),n=new TO;let o;return e.forEach((t,e)=\u003e{let i=t.split(\", \").map(t=\u003enew NO(t.split(\" \").map(Number)));const r=n.addFace(i);0===e?o=r.orientation():r.orientation()===o\u0026\u0026r.reverse()}),n}function kO(t){if(t.startsWith(\"POLYGON\")){return OO(t.replace(/^POLYGON /,\"\"))}return function(t){const e=t.split(/\\)\\), \\(\\(/).map(t=\u003e\"((\"+t+\"))\").map(OO),n=new TO;return e.reduce((t,e)=\u003e[...t,...e?.faces],[]).forEach(t=\u003en.addFace([...t?.shapes])),n}(t.replace(/^MULTIPOLYGON \\(\\(\\((.*)\\)\\)\\)$/,\"$1\"))}function LO(t){return t.split(\"\\n\")?.every(t=\u003et.includes(\"POINT\"))}function DO(t){return t.split(\"\\n\")?.every(t=\u003et.includes(\"LINESTRING\"))}function zO(t,e,n,o){return Math.sqrt((n-t)**2+(o-e)**2)}ME.isWktString=function(t){return t.startsWith(\"POINT\")||LO(t)||t.startsWith(\"LINESTRING\")||DO(t)||t.startsWith(\"MULTILINESTRING\")||t.startsWith(\"POLYGON\")||t.startsWith(\"MULTIPOINT\")||t.startsWith(\"MULTIPOLYGON\")||t.startsWith(\"GEOMETRYCOLLECTION\")},ME.parseWKT=function t(e){if(e.startsWith(\"POINT\")){return RO(e.replace(/^POINT \\(/,\"\").replace(/\\)$/,\"\"))}if(e.startsWith(\"MULTIPOINT\")){return EO(e.replace(/^MULTIPOINT \\(/,\"\").replace(/\\)$/,\"\"))}if(e.startsWith(\"LINESTRING\")){return AO(e.replace(/^LINESTRING \\(/,\"\").replace(/\\)$/,\"\"))}if(e.startsWith(\"MULTILINESTRING\")){return function(t){return t.replace(/\\(\\(/,\"\").replace(/\\)\\)$/,\"\").split(\"), (\").map(AO)}(e.replace(/^MULTILINESTRING /,\"\"))}if(e.startsWith(\"POLYGON\")||e.startsWith(\"MULTIPOLYGON\"))return kO(e);if(e.startsWith(\"GEOMETRYCOLLECTION\")){const n=/(?\u003ctype\u003ePOINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \\((?:[^\\(\\)]|\\([^\\)]*\\))*\\)/g,o=e.match(n);o[0].startsWith(\"GEOMETRYCOLLECTION\")\u0026\u0026(o[0]=o[0].replace(\"GEOMETRYCOLLECTION (\",\"\"));return o.map(t).map(t=\u003et instanceof Array?t:[t]).reduce((t,e)=\u003e[...t,...e],[])}return LO(e)?function(t){return t.split(\"\\n\").map(t=\u003et.match(/\\(([^)]+)\\)/)[1]).map(RO)}(e):DO(e)?function(t){return t.split(\"\\n\").map(t=\u003et.match(/\\(([^)]+)\\)/)[1]).map(AO).reduce((t,e)=\u003e[...t,...e],[])}(e):[]},ME.BooleanOperations=WA,ME.Relations=sO;var FO=class{buckets;objectsById;getBounds;getId;CELL_SIZE=.4;constructor({objects:t,getBounds:e,getId:n,CELL_SIZE:o}){this.buckets=new Map,this.objectsById=new Map,this.getBounds=e,this.getId=n??(()=\u003ethis._getNextId()),this.CELL_SIZE=o??this.CELL_SIZE;for(const e of t)this.addObject(e)}_idCounter=0;_getNextId(){return\"\"+this._idCounter++}addObject(t){const e=this.getBounds(t),n=this.getId(t),o={...t,spatialIndexId:n};this.objectsById.set(n,o);const i=Math.floor(e.minX/this.CELL_SIZE),r=Math.floor(e.minY/this.CELL_SIZE),s=Math.floor(e.maxX/this.CELL_SIZE),a=Math.floor(e.maxY/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const n=`${t}x${e}`,i=this.buckets.get(n);i?i.push(o):this.buckets.set(n,[o])}}removeObject(t){const e=this.objectsById.get(t);if(!e)return!1;this.objectsById.delete(t);const n=this.getBounds(e),o=Math.floor(n.minX/this.CELL_SIZE),i=Math.floor(n.minY/this.CELL_SIZE),r=Math.floor(n.maxX/this.CELL_SIZE),s=Math.floor(n.maxY/this.CELL_SIZE);for(let e=o;e\u003c=r;e++)for(let n=i;n\u003c=s;n++){const o=`${e}x${n}`,i=this.buckets.get(o);if(i){const e=i.findIndex(e=\u003ee.spatialIndexId===t);-1!==e\u0026\u0026(i.splice(e,1),0===i.length\u0026\u0026this.buckets.delete(o))}}return!0}getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getObjectsInBounds(t,e=0){const n=[],o=new Set,i=Math.floor((t.minX-e)/this.CELL_SIZE),r=Math.floor((t.minY-e)/this.CELL_SIZE),s=Math.floor((t.maxX+e)/this.CELL_SIZE),a=Math.floor((t.maxY+e)/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const i=`${t}x${e}`,r=this.buckets.get(i)||[];for(const t of r){const e=t.spatialIndexId;o.has(e)||(o.add(e),n.push(t))}}return n}},BO=.1,jO=.1,$O=BO,YO=BO,XO=.005;function VO(t){return\"pcb_trace_segment\"===t.type||\"pcb_smtpad\"===t.type?[t.layer]:\"pcb_plated_hole\"===t.type?Array.isArray(t.layers)?t.layers:[...uw]:\"pcb_hole\"===t.type?[...uw]:\"pcb_via\"===t.type?Array.isArray(t.layers)?t.layers:[...uw]:\"pcb_keepout\"===t.type\u0026\u0026Array.isArray(t.layers)?t.layers:[]}var WO=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=e.minX,r=e.minY,s=e.maxX,a=e.maxY;if(n.x===o.x\u0026\u0026n.y===o.y){const t=Math.max(i,Math.min(s,n.x)),e=Math.max(r,Math.min(a,n.y));return t===n.x\u0026\u0026e===n.y?{x:n.x,y:n.y}:{x:t,y:e}}const c=o.x-n.x,l=o.y-n.y,d=0!==c?(i-n.x)/c:Number.NEGATIVE_INFINITY,h=0!==c?(s-n.x)/c:Number.POSITIVE_INFINITY,u=0!==l?(r-n.y)/l:Number.NEGATIVE_INFINITY,p=0!==l?(a-n.y)/l:Number.POSITIVE_INFINITY,m=Math.max(Math.min(d,h),Math.min(u,p)),g=Math.min(Math.max(d,h),Math.max(u,p));if(m\u003c=g\u0026\u0026g\u003e=0\u0026\u0026m\u003c=1){const t=Math.max(0,Math.min(1,m));return{x:n.x+t*c,y:n.y+t*l}}const f={x:Math.max(i,Math.min(s,n.x)),y:Math.max(r,Math.min(a,n.y))},y={x:Math.max(i,Math.min(s,o.x)),y:Math.max(r,Math.min(a,o.y))},_=(f.x-n.x)**2+(f.y-n.y)**2,b=(y.x-o.x)**2+(y.y-o.y)**2,x=[{start:{x:i,y:r},end:{x:s,y:r}},{start:{x:s,y:r},end:{x:s,y:a}},{start:{x:s,y:a},end:{x:i,y:a}},{start:{x:i,y:a},end:{x:i,y:r}}];let v=Math.min(_,b),S=_\u003c=b?f:y;const I=(t,e,n)=\u003eMath.max(e,Math.min(n,t));for(const t of x){const e={x:o.x-n.x,y:o.y-n.y},i={x:t.end.x-t.start.x,y:t.end.y-t.start.y},r={x:n.x-t.start.x,y:n.y-t.start.y},s=e.x*e.x+e.y*e.y,a=e.x*i.x+e.y*i.y,c=e.x*r.x+e.y*r.y,l=i.x*i.x+i.y*i.y,d=i.x*r.x+i.y*r.y,h=s*l-a*a;if(Math.abs(h)\u003c1e-10)continue;let u=(a*d-l*c)/h,p=(s*d-a*c)/h;u=I(u,0,1),p=I(p,0,1);const m={x:n.x+u*e.x,y:n.y+u*e.y},g={x:t.start.x+p*i.x,y:t.start.y+p*i.y},f=m.x-g.x,y=m.y-g.y,_=f*f+y*y;_\u003cv\u0026\u0026(v=_,S={x:(m.x+g.x)/2,y:(m.y+g.y)/2})}return S},HO=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i={x:e.x1,y:e.y1},r={x:e.x2,y:e.y2},s={x:o.x-n.x,y:o.y-n.y},a={x:r.x-i.x,y:r.y-i.y},c=s.x*s.x+s.y*s.y,l=a.x*a.x+a.y*a.y;if(0===c||0===l){if(0===c\u0026\u00260===l)return{x:(n.x+i.x)/2,y:(n.y+i.y)/2};if(0===c){const t=UO(((n.x-i.x)*a.x+(n.y-i.y)*a.y)/l,0,1),e={x:i.x+t*a.x,y:i.y+t*a.y};return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}}const t=UO(((i.x-n.x)*s.x+(i.y-n.y)*s.y)/c,0,1),e={x:n.x+t*s.x,y:n.y+t*s.y};return{x:(e.x+i.x)/2,y:(e.y+i.y)/2}}const d=n.x-i.x,h=n.y-i.y,u=s.x*s.x+s.y*s.y,p=s.x*a.x+s.y*a.y,m=s.x*d+s.y*h,g=a.x*a.x+a.y*a.y,f=a.x*d+a.y*h,y=u*g-p*p;if(y\u003c1e-10)return GO(n,o,i,r,s,a,c,l);let _=(p*f-g*m)/y,b=(u*f-p*m)/y;_=UO(_,0,1),b=UO(b,0,1),b=(_*p+f)/g,b=UO(b,0,1),_=(b*p-m)/u,_=UO(_,0,1);const x=n.x+_*s.x,v=n.y+_*s.y,S=i.x+b*a.x,I=i.y+b*a.y,C=x-S,P=v-I;Math.sqrt(C*C+P*P);return{x:(x+S)/2,y:(v+I)/2}},GO=(t,e,n,o,i,r,s,a)=\u003e{let c=((n.x-t.x)*i.x+(n.y-t.y)*i.y)/s;c=UO(c,0,1);const l={x:t.x+c*i.x,y:t.y+c*i.y};let d=((o.x-t.x)*i.x+(o.y-t.y)*i.y)/s;d=UO(d,0,1);const h={x:t.x+d*i.x,y:t.y+d*i.y};let u=((t.x-n.x)*r.x+(t.y-n.y)*r.y)/a;u=UO(u,0,1);const p={x:n.x+u*r.x,y:n.y+u*r.y};let m=((e.x-n.x)*r.x+(e.y-n.y)*r.y)/a;m=UO(m,0,1);const g={x:n.x+m*r.x,y:n.y+m*r.y},f=[{pointA:l,pointB:n,distance:Math.sqrt((l.x-n.x)**2+(l.y-n.y)**2)},{pointA:h,pointB:o,distance:Math.sqrt((h.x-o.x)**2+(h.y-o.y)**2)},{pointA:t,pointB:p,distance:Math.sqrt((t.x-p.x)**2+(t.y-p.y)**2)},{pointA:e,pointB:g,distance:Math.sqrt((e.x-g.x)**2+(e.y-g.y)**2)}].reduce((t,e)=\u003ee.distance\u003ct.distance?e:t);return{x:(f.pointA.x+f.pointB.x)/2,y:(f.pointA.y+f.pointB.y)/2}},UO=(t,e,n)=\u003eMath.max(e,Math.min(n,t)),ZO=t=\u003e\"pcb_trace_segment\"===t.type?{minX:Math.min(t.x1,t.x2),minY:Math.min(t.y1,t.y2),maxX:Math.max(t.x1,t.x2),maxY:Math.max(t.y1,t.y2)}:EM([t]);function qO(t){const e=new Set;for(const n of t.route)\"wire\"===n.route_type\u0026\u0026(n.start_pcb_port_id\u0026\u0026e.add(n.start_pcb_port_id),n.end_pcb_port_id\u0026\u0026e.add(n.end_pcb_port_id));return Array.from(e)}function JO(t){const e=new Set;for(const n of t)for(const t of qO(n))e.add(t);return Array.from(e)}var KO=t=\u003e{if(\"pcb_via\"===t.type)return t.outer_diameter/2;if(\"pcb_plated_hole\"===t.type\u0026\u0026\"circle\"===t.shape)return t.outer_diameter/2;if(\"pcb_hole\"===t.type\u0026\u0026\"circle\"===t.hole_shape)return t.hole_diameter/2;if(\"pcb_smtpad\"===t.type\u0026\u0026\"circle\"===t.shape)return t.radius;throw new Error(`Could not determine radius of element: ${JSON.stringify(t)}`)};function QO(t,{connMap:e,minClearance:n=.1}={}){const o=[];(t=\u003e{const e=t.filter(t=\u003e\"pcb_port\"===t.type),n=t.filter(t=\u003e\"pcb_smtpad\"===t.type),o=t.filter(t=\u003e\"pcb_trace\"===t.type);function i(t,o={}){const i=o.traceWidth||0,r=e.find(e=\u003ezO(e.x,e.y,t.x,t.y)\u003c.01);if(r)return r.pcb_port_id;if(o.isFirstOrLastPoint){const e=n.find(e=\u003e\"rect\"===e.shape?Math.abs(t.x-e.x)\u003ce.width/2+i/2\u0026\u0026Math.abs(t.y-e.y)\u003ce.height/2+i/2:\"circle\"===e.shape?zO(t.x,t.y,e.x,e.y)\u003ce.radius:void 0);if(e)return e.pcb_port_id??null}return null}for(const t of o)for(let e=0;e\u003ct.route.length;e++){const n=t.route[e],o=0===e||e===t.route.length-1;if(\"wire\"===n.route_type){if(!n.start_pcb_port_id\u0026\u00260===e){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.start_pcb_port_id=t)}if(!n.end_pcb_port_id\u0026\u0026e===t.route.length-1){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.end_pcb_port_id=t)}}}})(t),e??=v_(t);const i=vM(t).pcb_trace.list().flatMap(t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];\"wire\"===o.route_type\u0026\u0026(\"wire\"===i.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({type:\"pcb_trace_segment\",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:\"width\"in o?o.width:\"width\"in i?i.width:jO,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),r=vM(t).pcb_smtpad.list(),s=vM(t).pcb_plated_hole.list(),a=vM(t).pcb_hole.list(),c=vM(t).pcb_via.list(),l=vM(t).pcb_keepout.list(),d=[...i,...r,...s,...a,...c,...l],h=new FO({objects:d,getBounds:ZO}),u=e=\u003eNM(t,e),p=(t,e,n)=\u003en\u003c0?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,m=new Set;for(const t of i){const i=n,r=ZO(t),s=h.getObjectsInBounds(r,i+t.thickness/2);if(t.x1!==t.x2||t.y1!==t.y2)for(const r of s){if(!VO(r).includes(t.layer))continue;if(\"pcb_trace_segment\"===r.type){const i=r;if(t.layer!==i.layer)continue;if(e.areIdsConnected(t.pcb_trace_id,i.pcb_trace_id))continue;const s=Oe({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:i.x1,y:i.y1},{x:i.x2,y:i.y2})-t.thickness/2-i.thickness/2;if(s\u003en-XO)continue;const a=`overlap_${t.pcb_trace_id}_${i.pcb_trace_id}`,c=`overlap_${i.pcb_trace_id}_${t.pcb_trace_id}`;if(m.has(a))continue;if(m.has(c))continue;m.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:p(u(t.pcb_trace_id),u(i.pcb_trace_id),s),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[],center:HO(t,i),pcb_port_ids:JO([t._pcbTrace,i._pcbTrace])});continue}const s=AM(r);if(e.areIdsConnected(t.pcb_trace_id,\"pcb_trace_id\"in r?r.pcb_trace_id:s))continue;if(\"pcb_via\"===r.type||\"pcb_plated_hole\"===r.type\u0026\u0026\"circle\"===r.shape||\"pcb_hole\"===r.type||\"pcb_smtpad\"===r.type\u0026\u0026\"circle\"===r.shape){const e=KO(r),i=De({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:r.x,y:r.y,radius:e})-t.thickness/2;if(i\u003en-XO)continue;const a=`overlap_${t.pcb_trace_id}_${s}`;if(m.has(a))continue;m.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:p(u(t.pcb_trace_id),`${r.type} \"${u(AM(r))}\"`,i),pcb_trace_id:t.pcb_trace_id,center:WO(t,ZO(r)),source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...JO([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}const a=ke({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},ZO(r))-t.thickness/2;if(a+XO\u003ci){const e=`overlap_${t.pcb_trace_id}_${s}`;if(m.has(e))continue;m.add(e),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:p(u(t.pcb_trace_id),`${r.type} \"${u(AM(r))}\"`,a),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:e,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),center:WO(t,ZO(r)),pcb_port_ids:[...JO([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}}}return o}function tk(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function ek(t,e){return tk(t,e)\u003c=XO}function nk(t,{connMap:e,minClearance:n=$O}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];e??=v_(t);const i=[],r=new Set;for(let s=0;s\u003co.length;s++)for(let a=s+1;a\u003co.length;a++){const c=o[s],l=o[a];if(ek(c,l))continue;if(!e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=tk(c,l)-c.outer_diameter/2-l.outer_diameter/2;if(d+XO\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");r.has(h)||(r.add(h),i.push({type:\"pcb_via_clearance_error\",pcb_error_id:`same_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return i}function ok(t,{connMap:e,minClearance:n=YO}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];e??=v_(t);const i=[],r=new Set;for(let s=0;s\u003co.length;s++)for(let a=s+1;a\u003co.length;a++){const c=o[s],l=o[a];if(ek(c,l))continue;if(e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=tk(c,l)-c.outer_diameter/2-l.outer_diameter/2;if(d+XO\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");r.has(h)||(r.add(h),i.push({type:\"pcb_via_clearance_error\",pcb_error_id:`different_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} from different nets are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return i}var ik=t=\u003e({minSpacing:t,minClearance:t}),rk={traceClearance:.1,viaClearance:.1},sk=t=\u003e(t=\u003e\"layer\"in t)(t)?[t.layer]:t.layers;function ak(t,e,n){let o,i=Number.POSITIVE_INFINITY;for(const r of e){const e=n.get(r);if(!e)continue;const s=Math.hypot(e.x-t.x,e.y-t.y);s\u003ci\u0026\u0026(i=s,o=r)}return o??e[0]}function ck(t){const e=[],n=new Set,o=new Set,i=function(t){const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{x:t.x,y:t.y});return e}(t);for(const r of t.obstacles){const t=r.connectedTo,s=t.find(t=\u003et.startsWith(\"pcb_smtpad_\")),a=t.find(t=\u003et.startsWith(\"pcb_plated_hole_\")),c=t.filter(t=\u003et.startsWith(\"pcb_port_\")),l=ak(r.center,c,i);if(!s\u0026\u0026!a\u0026\u0026!l)continue;const d=r.layers;if(0===d.length)continue;const h=r.width,u=r.height,p=r.center.x,m=r.center.y,g=r.ccwRotationDegrees,f=\"number\"==typeof g\u0026\u0026Number.isFinite(g);if(d.length\u003e1){const t=a??`pcb_plated_hole_${p.toFixed(3)}_${m.toFixed(3)}`;if(o.has(t))continue;if(o.add(t),f){const n=Math.max(.5*Math.min(h,u),.1);e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"rotated_pill_hole_with_rect_pad\",hole_shape:\"rotated_pill\",pad_shape:\"rect\",hole_width:n,hole_height:n,hole_ccw_rotation:g,rect_pad_width:h,rect_pad_height:u,rect_ccw_rotation:g,hole_offset_x:0,hole_offset_y:0,x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}if(Math.abs(h-u)\u003c.001){e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circle\",outer_diameter:Math.max(h,u),hole_diameter:Math.max(.5*Math.min(h,u),.1),x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circular_hole_with_rect_pad\",hole_shape:\"circle\",hole_diameter:Math.max(.5*Math.min(h,u),.1),rect_pad_width:h,rect_pad_height:u,hole_offset_x:0,hole_offset_y:0,x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}const y=s??`pcb_smtpad_${p.toFixed(3)}_${m.toFixed(3)}`;n.has(y)||(n.add(y),f?e.push({type:\"pcb_smtpad\",pcb_smtpad_id:y,layer:d[0],shape:\"rotated_rect\",x:p,y:m,width:h,height:u,ccw_rotation:g,...l?{pcb_port_id:l}:{}}):e.push({type:\"pcb_smtpad\",pcb_smtpad_id:y,layer:d[0],shape:\"rect\",width:h,height:u,x:p,y:m,...l?{pcb_port_id:l}:{}}))}return e}function lk(t,e,n=.1,o=t.minViaDiameter??.3){const i=[];i.push(...function(t,e){const n=[];return t.connections.forEach(o=\u003e{const i=o.pointsToConnect.filter(t=\u003et.pcb_port_id).map(t=\u003et.pcb_port_id).filter(Boolean),r=o.netConnectionName||o.rootConnectionName||o.name,s=[],a=e.find(t=\u003e(t.connection_name??t.connectionName)===o.name);if(a){const e=t=\u003e\"route_type\"in t\u0026\u0026\"jumper\"===t.route_type?t.start:\"x\"in t\u0026\u0026\"y\"in t?{x:t.x,y:t.y}:{x:0,y:0},n=[e(a.route[0]),e(a.route[a.route.length-1])];for(const e of n)for(const n of t.obstacles)Be(e,n)\u003c=0\u0026\u0026s.push(n)}const c=n.find(t=\u003e\"source_trace\"===t.type\u0026\u0026t.source_trace_id===r);if(c){const t=c;t.connected_source_port_ids=[...new Set([...t.connected_source_port_ids,...i])]}else n.push({type:\"source_trace\",source_trace_id:r,connected_source_port_ids:i.concat(s.flatMap(t=\u003e[`obstacle_${t.center.x.toFixed(3)}_${t.center.y.toFixed(3)}_${t.layers.join(\".\")}`,...t.connectedTo])),connected_source_net_ids:[]})}),n}(t,e)),i.push(...function(t){const e=new Map;return t.connections.forEach(t=\u003e{t.pointsToConnect.forEach(t=\u003e{t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{type:\"pcb_port\",pcb_port_id:t.pcb_port_id,source_port_id:t.pcb_port_id,x:t.x,y:t.y,layers:sk(t)})})}),Array.from(e.values())}(t)),i.push(...ck(t)),i.push(...function(t,e,n=.3){const o=[],i=new Set;return t.length\u003e0\u0026\u0026(\"type\"in t[0]\u0026\u0026\"pcb_trace\"===t[0].type?t.forEach(t=\u003e{t.route.forEach(r=\u003e{if(\"via\"===r.route_type){const s=r.via_diameter??n,a=`${r.x},${r.y},${r.from_layer},${r.to_layer}`;i.has(a)||(o.push({type:\"pcb_via\",pcb_via_id:`via_${o.length}`,pcb_trace_id:t.pcb_trace_id,x:r.x,y:r.y,outer_diameter:s,hole_diameter:.5*s,layers:Wy(r,e)}),i.add(a))}})}):t.forEach((t,r)=\u003e{const s=`trace_${r}`,a=t.viaDiameter??n;for(let n=1;n\u003ct.route.length;n++){const r=t.route[n-1],c=t.route[n];if(r.z!==c.z\u0026\u0026Math.abs(r.x-c.x)\u003c.01\u0026\u0026Math.abs(r.y-c.y)\u003c.01){const t=Vy(r.z,e),n=Vy(c.z,e),l=`${c.x},${c.y},${t},${n}`;i.has(l)||(o.push({type:\"pcb_via\",pcb_via_id:`via_${o.length}`,pcb_trace_id:s,x:c.x,y:c.y,outer_diameter:a,hole_diameter:.5*a,layers:Wy({from_layer:t,to_layer:n},e)}),i.add(l))}}})),o}(e,t.layerCount,o));const r=new Map;return t.connections.forEach(t=\u003e{r.set(t.name,t.netConnectionName||t.rootConnectionName||t.name)}),e.length\u003e0\u0026\u0026(\"type\"in e[0]\u0026\u0026\"pcb_trace\"===e[0].type?e.forEach(t=\u003e{const e=t.connection_name;i.push(function(t,e){return{type:\"pcb_trace\",pcb_trace_id:t.pcb_trace_id,source_trace_id:e,route:t.route.map(t=\u003e\"wire\"===t.route_type?{route_type:\"wire\",x:t.x,y:t.y,width:t.width,layer:t.layer,start_pcb_port_id:t.start_pcb_port_id,end_pcb_port_id:t.end_pcb_port_id}:\"via\"===t.route_type?{route_type:\"via\",x:t.x,y:t.y,from_layer:t.from_layer,to_layer:t.to_layer}:null).filter(t=\u003enull!==t)}}(t,r.get(e)||e))}):e.forEach((e,o)=\u003e{const s=e.connectionName,a=function(t,e,n,o=.1,i){const r=[];if(!t.jumpers||0===t.jumpers.length)return[{type:\"pcb_trace\",pcb_trace_id:e,source_trace_id:n,route:t.route.map((e,n)=\u003e{const r=0===n,s=n===t.route.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:o,layer:Vy(e.z,i),...r\u0026\u0026e.pcb_port_id?{start_pcb_port_id:e.pcb_port_id}:{},...s\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})}];const s=[];for(const e of t.jumpers){let n=-1,o=-1;for(let i=0;i\u003ct.route.length;i++){const r=t.route[i];Math.abs(r.x-e.start.x)\u003c.01\u0026\u0026Math.abs(r.y-e.start.y)\u003c.01\u0026\u0026(n=i),Math.abs(r.x-e.end.x)\u003c.01\u0026\u0026Math.abs(r.y-e.end.y)\u003c.01\u0026\u0026(o=i)}-1!==n\u0026\u0026-1!==o\u0026\u0026(n\u003eo\u0026\u0026([n,o]=[o,n]),s.push({startIdx:n,endIdx:o}))}s.sort((t,e)=\u003et.startIdx-e.startIdx);let a=0,c=0;for(const{startIdx:l,endIdx:d}of s){if(l\u003e=a){const s=t.route.slice(a,l+1);s.length\u003e0\u0026\u0026(r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((t,e)=\u003e{const n=0===e\u0026\u00260===a;return{route_type:\"wire\",x:t.x,y:t.y,width:o,layer:Vy(t.z,i),...n\u0026\u0026t.pcb_port_id?{start_pcb_port_id:t.pcb_port_id}:{}}})}),c++)}a=d}if(a\u003ct.route.length){const s=t.route.slice(a);if(s.length\u003e0){const t=!0;r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((e,n)=\u003e{const r=t\u0026\u0026n===s.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:o,layer:Vy(e.z,i),...r\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})})}}return r}(e,`trace_${o}`,r.get(s)||s,n,t.layerCount);i.push(...a)})),i}var dk=t=\u003et.rootConnectionName??t.connectionName,hk=(t,e)=\u003e{if(t\u0026\u0026e)return t.getNetConnectedToId(e)},uk=(t,e,n)=\u003e{if(!e)return!1;if(t===e)return!0;if(n?.areIdsConnected(t,e))return!0;const o=hk(n,t),i=hk(n,e);return!(!o||o!==e\u0026\u0026o!==i)||!(!i||i!==t\u0026\u0026i!==o)},pk=(t,e,n)=\u003ee.connectedTo?.some(e=\u003euk(t,e,n))??!1,mk=(t,e,n)=\u003eMath.max(e,Math.min(t,n)),gk=(t,e)=\u003e{t.x=mk(t.x,e.minX,e.maxX),t.y=mk(t.y,e.minY,e.maxY)},fk=(t,e)=\u003e({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),yk=(t,e)=\u003e({minCellX:Math.floor(t.minX/e),maxCellX:Math.floor(t.maxX/e),minCellY:Math.floor(t.minY/e),maxCellY:Math.floor(t.maxY/e)}),_k=(t,e)=\u003e`${t}:${e}`,bk=(t,e,n)=\u003e{const o=new Map;for(let i=0;i\u003ct.length;i+=1){const r=t[i];if(!r)continue;const s=yk(e(r),n);for(let t=s.minCellX;t\u003c=s.maxCellX;t+=1)for(let e=s.minCellY;e\u003c=s.maxCellY;e+=1){const n=_k(t,e),r=o.get(n);r?r.push(i):o.set(n,[i])}}return o},xk=(t,e,n)=\u003e{const o=new Set,i=yk(e,n);for(let e=i.minCellX;e\u003c=i.maxCellX;e+=1)for(let n=i.minCellY;n\u003c=i.maxCellY;n+=1){const i=t.get(_k(e,n));if(i)for(const t of i)o.add(t)}return[...o].sort((t,e)=\u003et-e)},vk=1e-6,Sk=(t,e,n)=\u003e{if(0===t.length)return[];const o=n?.traceThickness??.1,i=t[0],r=t.at(-1),s=t=\u003e{if(t.pcb_port_id)return t.pcb_port_id;const o=Vy(t.z,e);return n?.connectionPoints?.find(e=\u003e{return e.pcb_port_id\u0026\u0026(n=e,i=t,Math.abs(n.x-i.x)\u003c=vk\u0026\u0026Math.abs(n.y-i.y)\u003c=vk)\u0026\u0026sk(e).includes(o);var n,i})?.pcb_port_id},a=s(i),c=s(r),l=[{route_type:\"wire\",x:i.x,y:i.y,width:o,layer:Vy(i.z,e),...a?{start_pcb_port_id:a}:{},...1===t.length\u0026\u0026c?{end_pcb_port_id:c}:{}}];for(let i=1;i\u003ct.length;i+=1){const r=t[i-1],s=t[i];r\u0026\u0026s\u0026\u0026(r.z!==s.z\u0026\u0026r.x===s.x\u0026\u0026r.y===s.y\u0026\u0026l.push({route_type:\"via\",x:s.x,y:s.y,from_layer:Vy(r.z,e),to_layer:Vy(s.z,e),...n?.viaDiameter?{via_diameter:n.viaDiameter}:{}}),l.push({route_type:\"wire\",x:s.x,y:s.y,width:o,layer:Vy(s.z,e),...i===t.length-1\u0026\u0026c?{end_pcb_port_id:c}:{}}))}return l},Ik=(t,e)=\u003e({x:Ae(t.x,e.minX,e.maxX),y:Ae(t.y,e.minY,e.maxY)}),Ck=(t,e)=\u003e{const n=t.x-e.center.x,o=t.y-e.center.y;return e.circular?Math.max(0,Math.hypot(n,o)-e.halfWidth):je(R(e.worldToLocal,t),{minX:-e.halfWidth,maxX:e.halfWidth,minY:-e.halfHeight,maxY:e.halfHeight})},Pk=(t,e)=\u003e({kind:\"line\",start:t,end:e,bounds:We([t,e])}),Mk=(t,e)=\u003e({kind:\"circle\",center:t,radius:e,bounds:Ve({center:t,width:2*e,height:2*e})}),Nk=t=\u003e{const e=t.clearance+h_;if(t.circular)return[Mk(t.center,t.halfWidth+e)];const n=(e,n)=\u003eR(t.localToWorld,{x:e,y:n}),{halfWidth:o,halfHeight:i}=t;return[Pk(n(-o,-i-e),n(o,-i-e)),Pk(n(o+e,-i),n(o+e,i)),Pk(n(o,i+e),n(-o,i+e)),Pk(n(-o-e,i),n(-o-e,-i)),Mk(n(-o,-i),e),Mk(n(o,-i),e),Mk(n(o,i),e),Mk(n(-o,i),e)]},wk=(t,e)=\u003e{if(\"circle\"===e.kind){const n=t.x-e.center.x,o=t.y-e.center.y,i=Math.hypot(n,o);return 0===i?[{x:e.center.x+e.radius,y:e.center.y},{x:e.center.x-e.radius,y:e.center.y},{x:e.center.x,y:e.center.y+e.radius},{x:e.center.x,y:e.center.y-e.radius}]:[{x:e.center.x+n*e.radius/i,y:e.center.y+o*e.radius/i}]}return[e.start,e.end,ze(t,e.start,e.end)]},Tk=(t,e)=\u003e{const n=t.end.x-t.start.x,o=t.end.y-t.start.y,i=t.start.x-e.center.x,r=t.start.y-e.center.y,s=n*n+o*o;if(0===s)return[];const a=2*(i*n+r*o),c=a*a-4*s*(i*i+r*r-e.radius*e.radius);if(c\u003c0)return[];const l=Math.sqrt(c);return[(-a-l)/(2*s),(-a+l)/(2*s)].filter(t=\u003et\u003e=0\u0026\u0026t\u003c=1).map(e=\u003e({x:t.start.x+n*e,y:t.start.y+o*e}))},Rk=(t,e)=\u003e{if(\"line\"===t.kind\u0026\u0026\"circle\"===e.kind)return Tk(t,e);if(\"circle\"===t.kind\u0026\u0026\"line\"===e.kind)return Tk(e,t);if(\"line\"===t.kind\u0026\u0026\"line\"===e.kind){const n=ve(t.start,t.end,e.start,e.end);return n?[n]:[]}if(\"circle\"!==t.kind||\"circle\"!==e.kind)return[];const n=e.center.x-t.center.x,o=e.center.y-t.center.y,i=Math.hypot(n,o);if(0===i||i\u003et.radius+e.radius||i\u003cMath.abs(t.radius-e.radius))return[];const r=(t.radius**2-e.radius**2+i**2)/(2*i),s=Math.sqrt(Math.max(0,t.radius**2-r**2)),a=t.center.x+n*r/i,c=t.center.y+o*r/i;return[{x:a-o*s/i,y:c+n*s/i},{x:a+o*s/i,y:c-n*s/i}]},Ek=(t,e,n,o,i)=\u003e{const r=new Set(function(t,e,n=1){if(0===n)throw new Error(\"step cannot be 0\");let o,i;void 0===e?(o=0,i=t):(o=t,i=e);const r=[];if(n\u003e0)for(let t=o;t\u003ci;t+=n)r.push(t);else for(let t=o;t\u003ei;t+=n)r.push(t);return r}(Math.min(...o),Math.max(...o)+1).map(e=\u003eVy(e,t.layerCount)));return t.obstacles.filter(t=\u003e!t.isCopperPour\u0026\u0026t.layers.some(t=\u003er.has(t))).map(o=\u003e{const r=\"number\"==typeof o.ccwRotationDegrees\u0026\u0026Number.isFinite(o.ccwRotationDegrees),s=!r\u0026\u0026o.layers.length\u003e1\u0026\u0026Math.abs(o.width-o.height)\u003c.001,a=D(k(o.center.x,o.center.y),j(r?o.ccwRotationDegrees:0)),c=s?Math.max(o.width,o.height)/2:o.width/2,l=s?c:o.height/2,d=pk(dk(e),o,i)||pk(e.connectionName,o,i),h=n+(d?0:y_(t)),u=We(E(a,[{x:-c,y:-l},{x:c,y:-l},{x:c,y:l},{x:-c,y:l}])),p=h+h_;return{center:o.center,halfWidth:c,halfHeight:l,localToWorld:a,worldToLocal:A(a),circular:s,clearance:h,bounds:{minX:u.minX-p,maxX:u.maxX+p,minY:u.minY-p,maxY:u.maxY+p}}})},Ak=(t,e,n,o)=\u003e{const i=Math.min(...t.zLayers),r=Math.max(...t.zLayers),s=e.filter(e=\u003ee.z\u003e=i\u0026\u0026e.z\u003c=r\u0026\u0026!uk(t.rootConnectionName,e.rootConnectionName,o)).map(e=\u003e({segment:e,required:t.radius+e.radius+n})).filter(({segment:e,required:n})=\u003ebe(t,e.start,e.end)\u003c=n+p_),a=s.flatMap(({segment:t,required:e})=\u003e{const{start:n,end:o}=t,i=Math.sqrt(Ye(n,o));if(i\u003c=h_)return[];const r=e+h_,s=(o.y-n.y)/i*r,a=(n.x-o.x)/i*r;return[Pk({x:n.x+s,y:n.y+a},{x:o.x+s,y:o.y+a}),Pk({x:n.x-s,y:n.y-a},{x:o.x-s,y:o.y-a}),Mk(n,r),Mk(o,r)]}).filter(e=\u003eje(t,e.bounds)\u003c=p_),c=[],l=e=\u003e{Ye(e,t)\u003ep_**2||c.some(t=\u003eYe(t,e)\u003c1e-12)||s.some(({segment:t,required:n})=\u003ebe(e,t.start,t.end)\u003cn)||c.push(e)};l(t);for(let e=0;e\u003ca.length;e+=1){const n=a[e];for(const e of wk(t,n))l(e);for(let t=e+1;t\u003ca.length;t+=1){const e=a[t];if(Xe(n.bounds,e.bounds))for(const t of Rk(n,e))l(t)}}return c.sort((e,n)=\u003eYe(e,t)-Ye(n,t))},Ok=t=\u003e({...t,route:t.route.map(t=\u003e({...t})),vias:t.vias.map(t=\u003e({...t}))}),kk=t=\u003et.map(Ok),Lk=(t,e)=\u003e{const n=new Set(e);return t.map((t,e)=\u003en.has(e)?Ok(t):t)},Dk=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=u_\u0026\u0026Math.abs(t.y-e.y)\u003c=u_,zk=[\"pcb_smtpad\",\"pcb_plated_hole\",\"pcb_hole\",\"pcb_keepout\"],Fk=t=\u003e\"string\"==typeof t.type?t.type:\"string\"==typeof t.error_type?t.error_type:void 0,Bk=t=\u003e{if(\"pcb_pad_trace_clearance_error\"===Fk(t))return!0;const e=\"string\"==typeof t.message?t.message.toLowerCase():\"\";return(e.includes(\"pcb_trace\")||e.includes(\"pcb trace\"))\u0026\u0026zk.some(t=\u003ee.includes(t))},jk=t=\u003e{const e=\"string\"==typeof t.message?t.message:\"\",n=e.match(/gap: (-?\\d+(?:\\.\\d+)?)mm/),o=e.match(/required: (-?\\d+(?:\\.\\d+)?)mm/);if(n\u0026\u0026o){const t=Number.parseFloat(n[1]),e=Number.parseFloat(o[1]);if(Number.isFinite(t)\u0026\u0026Number.isFinite(e))return Math.max(0,e-t)}if(n){const t=Number.parseFloat(n[1]),e=rk.traceClearance??.1;if(Number.isFinite(t))return Math.max(0,e-t)}return 1},$k={projectEngineError:t=\u003e({...t,center:\"object\"==typeof t.first_contact_center?t.first_contact_center:t.center,message:\"string\"==typeof t.first_contact_message?t.first_contact_message:t.message,actual_clearance:\"number\"==typeof t.first_actual_clearance?t.first_actual_clearance:t.actual_clearance}),getErrorSeverity:jk},Yk={projectEngineError:t=\u003et,getErrorSeverity:t=\u003e{const e=Number(t.minimum_clearance),n=Number(t.worst_actual_clearance);return Number.isFinite(e)\u0026\u0026Number.isFinite(n)?Math.max(0,e-n):jk(t)}},Xk=(t,e=jk)=\u003et.reduce((t,n)=\u003et+e(n),0),Vk=(t,e,n,o,i,r=$k)=\u003e{const s=i\u0026\u0026!n?t:((t,e)=\u003ee?{...t,connections:t.connections.map(t=\u003e{const n=hk(e,t.name)??hk(e,t.rootConnectionName)??t.netConnectionName;return n?{...t,netConnectionName:n}:t}),obstacles:t.obstacles.map(t=\u003e{const n=new Set(t.connectedTo);for(const o of t.connectedTo){const t=hk(e,o);t\u0026\u0026n.add(t)}return{...t,connectedTo:[...n]}})}:t)(t,o),{traces:a,traceRouteIndexById:c}=((t,e)=\u003e{const n=[],o=new Map,i=new Map;for(let t=0;t\u003ce.length;t+=1){const n=e[t];if(!n)continue;const o=i.get(n.connectionName);o?o.push({route:n,routeIndex:t}):i.set(n.connectionName,[{route:n,routeIndex:t}])}for(const e of t.connections){const r=i.get(e.name)??[];for(let i=0;i\u003cr.length;i+=1){const s=r[i];if(!s)continue;const a=`${e.name}_${i}`;n.push({type:\"pcb_trace\",pcb_trace_id:a,connection_name:e.netConnectionName??e.rootConnectionName??e.name,route:Sk(s.route.route,t.layerCount,{traceThickness:s.route.traceThickness??e.nominalTraceWidth??t.nominalTraceWidth??t.minTraceWidth,viaDiameter:s.route.viaDiameter??t.minViaDiameter,connectionPoints:e.pointsToConnect})}),o.set(a,s.routeIndex)}}return{traces:n,traceRouteIndexById:o}})(s,e),l=n?.({srj:s,routes:e,traces:a});if(l){const t=Array.isArray(l)?l:l.errors,e=Array.isArray(l)?l:l.errorsWithCenters??l.errors;return{errors:e,count:t.length,issueScore:Xk(e,r.getErrorSeverity),legacyIssueScore:Xk(e.filter(t=\u003e!uD(t)),r.getErrorSeverity),traceRouteIndexById:c}}const d=i?.evaluate(a)??((t,e={})=\u003e{const n=Math.max(e.viaClearance??.1,.1),o=[...QO(t,ik(e.traceClearance)),...nk(t,ik(n)),...ok(t,ik(n))],i=t.filter(t=\u003e\"pcb_via\"===t.type),r=new Map(i.map(t=\u003e[t.pcb_via_id,t])),s=o.map(t=\u003e{if(\"center\"in t\u0026\u0026t.center)return t;if(\"pcb_center\"in t\u0026\u0026t.pcb_center)return{...t,center:t.pcb_center};if(\"pcb_via_ids\"in t\u0026\u0026Array.isArray(t.pcb_via_ids)){const[e,n]=t.pcb_via_ids;if(\"string\"!=typeof e||\"string\"!=typeof n)return t;const o=r.get(e),i=r.get(n);if(o\u0026\u0026i)return{...t,center:{x:(o.x+i.x)/2,y:(o.y+i.y)/2}}}if(\"pcb_error_id\"in t\u0026\u0026\"string\"==typeof t.pcb_error_id\u0026\u0026(t.pcb_error_id.startsWith(\"same_net_vias_close_\")||t.pcb_error_id.startsWith(\"different_net_vias_close_\"))){const e=t.pcb_error_id.replace(\"same_net_vias_close_\",\"\").replace(\"different_net_vias_close_\",\"\").split(\"_\").filter(Boolean);if(2===e.length){const n=e[0],o=e[1];if(!n||!o)return t;const i=r.get(n),s=r.get(o);if(i\u0026\u0026s)return{...t,center:{x:(i.x+s.x)/2,y:(i.y+s.y)/2}}}}return t}),a=s.filter(t=\u003eBoolean(t.center));return{errors:o,errorsWithCenters:s,locationAwareErrors:a}})(lk(s,a,s.minTraceWidth,s.minViaDiameter),{...rk,traceClearance:s.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:s.minTraceToPadEdgeClearance??rk.viaClearance}),h=d.errors,u=(d.errorsWithCenters.length\u003e0?d.errorsWithCenters:d.errors).map(t=\u003er.projectEngineError(t));return{errors:u,count:h.length,issueScore:Xk(u,r.getErrorSeverity),legacyIssueScore:Xk(u.filter(t=\u003e!uD(t)),r.getErrorSeverity),traceRouteIndexById:c}},Wk=(t,e,n,o,i)=\u003eVk(t,e,n,o,i,$k),Hk=(t,e,n,o,i)=\u003eVk(t,e,n,o,i,Yk),Gk=(t,e=.3)=\u003e{const n=[];for(let o=0;o\u003ct.length;o+=1){const i=t[o];if(!i)continue;const r=new Set;for(let t=0;t\u003ci.route.length-1;t+=1){const s=i.route[t],a=i.route[t+1];if(!s||!a)continue;if(s.z===a.z||!Dk(s,a))continue;const c=[t,t+1];for(let e=t-1;e\u003e=0;e-=1){const t=i.route[e];if(!t||!Dk(t,s))break;c.push(e)}for(let e=t+2;e\u003ci.route.length;e+=1){const t=i.route[e];if(!t||!Dk(t,s))break;c.push(e)}const l=[...new Set(c)];if(l.some(t=\u003er.has(t)))continue;for(const t of l)r.add(t);const d=l.filter(t=\u003e0===t||t===i.route.length-1),h=d.some(t=\u003eBoolean(i.route[t]?.pcb_port_id));n.push({routeIndex:o,rootConnectionName:dk(i),pointIndexes:l,zLayers:[...new Set(l.map(t=\u003ei.route[t].z))],x:s.x,y:s.y,radius:(i.viaDiameter??e)/2,movable:0===d.length,canCanonicalize:0===d.length||!h})}}return n},Uk=(t,e)=\u003e{const n=[];for(let o=0;o\u003ct.route.length-1;o+=1){const i=t.route[o],r=t.route[o+1];i\u0026\u0026r\u0026\u0026(i.z!==r.z||Dk(i,r)||n.push({routeIndex:e,rootConnectionName:dk(t),startIndex:o,endIndex:o+1,start:i,end:r,z:i.z,radius:(t.traceThickness??.1)/2}))}return n},Zk=t=\u003et.flatMap((t,e)=\u003eUk(t,e)),qk=t=\u003e({minX:t.x,minY:t.y,maxX:t.x,maxY:t.y}),Jk=t=\u003e({minX:Math.min(t.start.x,t.end.x),minY:Math.min(t.start.y,t.end.y),maxX:Math.max(t.start.x,t.end.x),maxY:Math.max(t.start.y,t.end.y)}),Kk=t=\u003e({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}),Qk=(t,e)=\u003e{if(t.zLayers\u0026\u0026t.zLayers.length\u003e0)return t.zLayers;const n=Array.from({length:e},(t,e)=\u003ee).filter(n=\u003et.layers.includes(Vy(n,e)));return n.length\u003e0?n:Array.from({length:e},(t,e)=\u003ee)},tL=(t,e,n)=\u003e{const o=e.reduce((t,e)=\u003eMath.max(t,e.radius),(t.minViaDiameter??.3)/2),i=n.reduce((t,e)=\u003eMath.max(t,e.radius),t.minTraceWidth/2),r=(rk.traceClearance??.1)+g_;return Math.max(2*o+.2+g_,o+i+r,2*i+r,i+f_(t)+g_,o+y_(t)+g_)},eL=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c=h_)return{x:e.x,y:e.y,t:0};const s=mk(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return{x:e.x+o*s,y:e.y+i*s,t:s}},nL=(t,e)=\u003eeL(t,e.start,e.end),oL=(t,e)=\u003e{const n=e.width/2,o=e.height/2,i=Math.max(Math.abs(t.x-e.center.x)-n,0),r=Math.max(Math.abs(t.y-e.center.y)-o,0);return Math.hypot(i,r)},iL=(t,e)=\u003et.x\u003e=e.center.x-e.width/2-u_\u0026\u0026t.x\u003c=e.center.x+e.width/2+u_\u0026\u0026t.y\u003e=e.center.y-e.height/2-u_\u0026\u0026t.y\u003c=e.center.y+e.height/2+u_,rL=(t,e,n,o)=\u003et.obstacles.find(i=\u003epk(dk(e),i,o)\u0026\u0026Qk(i,t.layerCount).includes(n.z)\u0026\u0026iL(n,i)),sL=(t,e,n=.6,o)=\u003e{let i;for(const r of t.obstacles){if(o\u0026\u0026!o(r))continue;const t=oL(e,r);t\u003en||(!i||t\u003ci.distance)\u0026\u0026(i={obstacle:r,distance:t})}return i?.obstacle},aL=(t,e,n)=\u003e{const o=e.width/2,i=e.height/2,r=mk(t.x,e.center.x-o,e.center.x+o),s=mk(t.y,e.center.y-i,e.center.y+i);let a=t.x-r,c=t.y-s,l=Math.hypot(a,c);if(l\u003c=h_){o-Math.abs(t.x-e.center.x)\u003ci-Math.abs(t.y-e.center.y)?(a=t.x\u003e=e.center.x?1:-1,c=0,l=0):(a=0,c=t.y\u003e=e.center.y?1:-1,l=0)}const d=n-l;if(d\u003c=0)return;const h=Math.hypot(a,c);return{direction:{x:h\u003eh_?a/h:1,y:h\u003eh_?c/h:0},penetration:d}},cL=(t,e,n,o)=\u003e{const i=e.message;if(\"string\"!=typeof i||!i.includes(\"pcb_\"))return n;const r=Array.isArray(e.pcb_pad_ids)?e.pcb_pad_ids.filter(t=\u003e\"string\"==typeof t):[],s=t.obstacles.find(t=\u003er.some(e=\u003et.connectedTo.includes(e))\u0026\u0026(o?.(t)??!0));return s?s.center:sL(t,n,.6,o)?.center??n},lL=(t,e)=\u003e{const n=t.route[e];if(!n)return[];const o=[e];for(let i=e-1;i\u003e=0;i-=1){const e=t.route[i];if(!e||!Dk(e,n))break;o.push(i)}for(let i=e+1;i\u003ct.route.length;i+=1){const e=t.route[i];if(!e||!Dk(e,n))break;o.push(i)}return[...new Set(o)]},dL=(t,e)=\u003e{if(e\u003c=0||e\u003e=t.route.length-1)return;const n=lL(t,e);return n.includes(0)||n.includes(t.route.length-1)?void 0:n},hL=(t,e)=\u003et.x\u003e=e.minX-u_\u0026\u0026t.x\u003c=e.maxX+u_\u0026\u0026t.y\u003e=e.minY-u_\u0026\u0026t.y\u003c=e.maxY+u_,uL=(t,e)=\u003eMath.min(t.x-e.minX,e.maxX-t.x,t.y-e.minY,e.maxY-t.y),pL=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=t.x-e.x,s=o*(t.y-e.y)-i*r;if(Math.abs(s)\u003eu_)return!1;const a=Math.min(e.x,n.x)-u_,c=Math.max(e.x,n.x)+u_,l=Math.min(e.y,n.y)-u_,d=Math.max(e.y,n.y)+u_;return t.x\u003e=a\u0026\u0026t.x\u003c=c\u0026\u0026t.y\u003e=l\u0026\u0026t.y\u003c=d},mL=(t,e)=\u003e{if(e.length\u003c3)return!0;for(let n=0;n\u003ce.length;n+=1){const o=e[n],i=e[(n+1)%e.length];if(o\u0026\u0026i\u0026\u0026pL(t,o,i))return!0}let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o,o+=1){const r=e[o],s=e[i];if(!r||!s)continue;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n},gL=(t,e)=\u003e{const n=Math.hypot(t,e);if(!(n\u003c=h_))return{x:t/n,y:e/n}},fL=(t,e)=\u003et.outline\u0026\u0026t.outline.length\u003e=3?((t,e)=\u003e{const n=mL(t,e);let o;for(let n=0;n\u003ce.length;n+=1){const i=e[n],r=e[(n+1)%e.length];if(!i||!r)continue;const s=eL(t,i,r),a=Math.hypot(t.x-s.x,t.y-s.y);(!o||a\u003co.distance)\u0026\u0026(o={projection:s,start:i,end:r,distance:a})}if(!o)return;const i=gL(n?t.x-o.projection.x:o.projection.x-t.x,n?t.y-o.projection.y:o.projection.y-t.y);if(i)return i;const r=o.end.x-o.start.x,s=o.end.y-o.start.y,a=Math.hypot(r,s);if(a\u003c=h_)return;const c=(t=\u003e{let e=0;for(let n=0;n\u003ct.length;n+=1){const o=t[n],i=t[(n+1)%t.length];o\u0026\u0026i\u0026\u0026(e+=o.x*i.y-i.x*o.y)}return e/2})(e)\u003e=0;return{x:c?-s/a:s/a,y:c?r/a:-r/a}})(e,t.outline):((t,e)=\u003e{const n=t.x-e.minX,o=e.maxX-t.x,i=t.y-e.minY,r=e.maxY-t.y,s=Math.min(n,o,i,r);let a=0,c=0;return n\u003c=s+u_\u0026\u0026(a+=1),o\u003c=s+u_\u0026\u0026(a-=1),i\u003c=s+u_\u0026\u0026(c+=1),r\u003c=s+u_\u0026\u0026(c-=1),gL(a,c)})(e,t.bounds),yL=(t,e)=\u003et.outline\u0026\u0026t.outline.length\u003e=3?mL(e,t.outline):hL(e,t.bounds),_L=(t,e)=\u003e{if(t.outline\u0026\u0026t.outline.length\u003e=3){const n=((t,e)=\u003e{let n=Number.POSITIVE_INFINITY;for(let o=0;o\u003ce.length;o+=1){const i=e[o],r=e[(o+1)%e.length];i\u0026\u0026r\u0026\u0026(n=Math.min(n,be(t,i,r)))}return n})(e,t.outline);return mL(e,t.outline)?n:-n}return uL(e,t.bounds)},bL=(t,e,n)=\u003e{if(Math.abs(e.x-n.x)\u003c=u_\u0026\u0026Math.abs(e.y-n.y)\u003c=u_)return Math.min(_L(t,e),_L(t,n));if(t.outline\u0026\u0026t.outline.length\u003e=3){if(!mL(e,t.outline)||!mL(n,t.outline))return Math.min(_L(t,e),_L(t,n));let o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ct.outline.length;i+=1){const r=t.outline[i],s=t.outline[(i+1)%t.outline.length];r\u0026\u0026s\u0026\u0026(o=Math.min(o,Oe(e,n,r,s)))}return o}return hL(e,t.bounds)\u0026\u0026hL(n,t.bounds)?Math.min(uL(e,t.bounds),uL(n,t.bounds)):Math.min(_L(t,e),_L(t,n))},xL=(t,e)=\u003ee+Math.max(.16,t.defaultObstacleMargin??0,rk.traceClearance??.1),vL=(t,e,n)=\u003ee\u003ct-u_\u0026\u0026Math.min(t,e)\u003c=n+u_,SL=(t,e,n,o,i)=\u003e{const r=t*n.x+e*n.y,s=-Math.max(0,o-i);if(r\u003e=s-u_)return{x:t,y:e};const a=s-r;return{x:t+n.x*a,y:e+n.y*a}},IL=(t,e,n,o,i)=\u003e{const r=fL(t,e);return r?SL(n,o,r,_L(t,e),xL(t,i)):{x:n,y:o}},CL=(t,e,n,o)=\u003e{const i=[...new Set(n)].sort((t,e)=\u003et-e);if(0===i.length)return Number.POSITIVE_INFINITY;const r=new Set(i),s=t=\u003eo?.get(t)??e.route[t];let a=Number.POSITIVE_INFINITY;for(const e of i){const n=s(e);n\u0026\u0026(a=Math.min(a,_L(t,n)))}for(let n=0;n\u003ce.route.length-1;n+=1){if(!r.has(n)\u0026\u0026!r.has(n+1))continue;const e=s(n),o=s(n+1);e\u0026\u0026o\u0026\u0026(a=Math.min(a,bL(t,e,o)))}return a},PL=(t,e,n,o,i,r)=\u003e{const s=[...new Set(n)].sort((t,e)=\u003et-e);if(0===s.length)return;const a=((t,e,n,o,i,r)=\u003e{const s=[...new Set(n)].sort((t,e)=\u003et-e);let a={x:o,y:i};const c=xL(t,r);for(let n=0;n\u003cMath.max(1,s.length);n+=1){let n=!1;for(const o of s){const i=e.route[o];if(!i)continue;const r=fL(t,i);if(!r)continue;const s=SL(a.x,a.y,r,_L(t,i),c);(Math.abs(s.x-a.x)\u003eh_||Math.abs(s.y-a.y)\u003eh_)\u0026\u0026(a=s,n=!0)}if(!n)break}return a})(t,e,s,o,i,r);if(Math.abs(a.x)\u003c=h_\u0026\u0026Math.abs(a.y)\u003c=h_)return;const c=new Map;for(const t of s){const n=e.route[t];if(!n)continue;const o={x:n.x+a.x,y:n.y+a.y};c.set(t,o)}const l=CL(t,e,s),d=CL(t,e,s,c);if(d\u003cr-u_)return;const h=xL(t,r);return vL(l,d,h)?void 0:a},ML=(t,e,n,o,i,r,s)=\u003e{const a=t[e];if(!a)return!1;const c=dL(a,n);if(!c)return!1;const l=PL(r,a,c,o,i,s);if(!l)return!1;let d=!1;for(const t of c){const e=a.route[t];e\u0026\u0026(e.x+=l.x,e.y+=l.y,gk(e,r.bounds),d=!0)}return d},NL=(t,e,n,o,i,r)=\u003edL(e,n)??((t,e,n,o,i,r)=\u003e{const s=e.route[n];if(!s||s.pcb_port_id||0!==n\u0026\u0026n!==e.route.length-1)return;const a=rL(t,e,s,r);if(!a)return;const c={...s,x:s.x+o,y:s.y+i};return yL(t,c)\u0026\u0026iL(c,a)?lL(e,n):void 0})(t,e,n,o,i,r),wL=(t,e,n,o,i,r)=\u003e{const s=PL(i,t,e,n,o,r);if(!s)return!1;let a=!1;for(const n of e){const e=t.route[n];e\u0026\u0026(e.x+=s.x,e.y+=s.y,gk(e,i.bounds),a=!0)}return a},TL=(t,e,n,o,i,r)=\u003e{const s=e.route[n];if(!s)return!1;if(s.pcb_port_id)return!1;const a=rL(t,e,s,r);return!!a\u0026\u0026iL({...s,x:s.x+o,y:s.y+i},a)},RL=(t,e,n,o)=\u003e{const i=e.route[n];if(i\u0026\u0026!i.pcb_port_id)return rL(t,e,i,o)},EL=(t,e,n,o,i,r,s)=\u003e{const a=t[e];if(!a||0===a.route.length)return!1;const c=((t,e,n,o,i)=\u003e{let r=Number.NEGATIVE_INFINITY,s=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY,c=Number.POSITIVE_INFINITY;for(const n of[0,e.route.length-1]){const o=e.route[n],l=RL(t,e,n,i);if(!o||!l)return;r=Math.max(r,l.center.x-l.width/2-o.x),s=Math.min(s,l.center.x+l.width/2-o.x),a=Math.max(a,l.center.y-l.height/2-o.y),c=Math.min(c,l.center.y+l.height/2-o.y)}if(!(r\u003es||a\u003ec))return{x:mk(n,r,s),y:mk(o,a,c)}})(i,a,n,o,s);if(!c)return!1;const l=a.route.map((t,e)=\u003ee),d=PL(i,a,l,c.x,c.y,r);if(!d)return!1;const h=a.route.length-1;if(!TL(i,a,0,d.x,d.y,s)||!TL(i,a,h,d.x,d.y,s))return!1;let u=!1;for(const t of a.route)t.x+=d.x,t.y+=d.y,gk(t,i.bounds),u=!0;return u},AL=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y,r=n.x-e.x,s=n.y-e.y;return Math.abs(o*s-i*r)\u003c=u_},OL=(t,e)=\u003e{if(t.z!==e.z)return!1;const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=t.x-e.start.x,r=t.y-e.start.y;return Math.abs(n*r-o*i)\u003c=u_},kL=(t,e)=\u003e{const n=((t,e)=\u003e{const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.max(u_,.12*(t.traceThickness??.1)),r=Math.abs(o)\u003c=i,s=Math.abs(n)\u003c=i;let a=e.startIndex,c=e.endIndex;if(r||s){const n=r?(e.start.y+e.end.y)/2:(e.start.x+e.end.x)/2;for(;a\u003e0;){const o=t.route[a-1];if(!o||o.z!==e.z||Math.abs((r?o.y:o.x)-n)\u003ei)break;a-=1}for(;c\u003ct.route.length-1;){const o=t.route[c+1];if(!o||o.z!==e.z||Math.abs((r?o.y:o.x)-n)\u003ei)break;c+=1}return Array.from({length:c-a+1},(t,e)=\u003ea+e)}for(;a\u003e0;){const n=t.route[a-1],o=t.route[a],i=t.route[a+1];if(!(n\u0026\u0026o\u0026\u0026i\u0026\u0026n.z===e.z\u0026\u0026OL(n,e)\u0026\u0026AL(n,o,i)))break;a-=1}for(;c\u003ct.route.length-1;){const n=t.route[c-1],o=t.route[c],i=t.route[c+1];if(!(n\u0026\u0026o\u0026\u0026i\u0026\u0026i.z===e.z\u0026\u0026OL(i,e)\u0026\u0026AL(n,o,i)))break;c+=1}return Array.from({length:c-a+1},(t,e)=\u003ea+e)})(t,e);if(n.length\u003c=2)return;const o=[];for(const e of n){const n=dL(t,e);if(!n)return;o.push(...n)}return[...new Set(o)]},LL=(t,e)=\u003ee\u003e0\u0026\u0026e\u003ct.route.length-1\u0026\u0026!((t,e)=\u003e{const n=t.route[e];if(!n)return!1;const o=t.route[e-1],i=t.route[e+1];return o\u0026\u0026o.z!==n.z\u0026\u0026Dk(o,n)||i\u0026\u0026i.z!==n.z\u0026\u0026Dk(i,n)})(t,e),DL=(t,e,n)=\u003e{const o=t.route[e.startIndex],i=t.route[e.endIndex];return!(!o||!i)\u0026\u0026(o.z===e.z\u0026\u0026i.z===e.z\u0026\u0026(!!((t,e)=\u003eJk(t).maxX\u003e=e.minX-u_\u0026\u0026Jk(t).minX\u003c=e.maxX+u_\u0026\u0026Jk(t).maxY\u003e=e.minY-u_\u0026\u0026Jk(t).minY\u003c=e.maxY+u_)(e,n)\u0026\u0026(LL(t,e.startIndex)||LL(t,e.endIndex))))},zL=(t,e,n,o,i,r,s)=\u003e{const a=t[e.routeIndex];if(!a)return!1;const c=((t,e,n,o)=\u003e{const i=fk(Kk(n),o);let r=e.startIndex,s=e.startIndex;for(;r\u003e0;){const n={...e,startIndex:r-1,endIndex:r,start:t.route[r-1],end:t.route[r]};if(!t.route[r-1]||!DL(t,n,i))break;r-=1}for(;s\u003ct.route.length-2;){const n={...e,startIndex:s+1,endIndex:s+2,start:t.route[s+1],end:t.route[s+2]};if(!t.route[s+2]||!DL(t,n,i))break;s+=1}const a=[];for(let e=r;e\u003c=s+1;e+=1)LL(t,e)\u0026\u0026a.push(e);return[...new Set(a)]})(a,e,n,o);return!(c.length\u003c=2)\u0026\u0026wL(a,c,i,r,s,e.radius)},FL=(t,e)=\u003e{const n=nL(e,t),o=n.x-e.x,i=n.y-e.y,r=Math.hypot(o,i),s=t.end.x-t.start.x,a=t.end.y-t.start.y,c=Math.hypot(s,a),l=t.routeIndex%2==0?1:-1;return{projection:n,direction:r\u003eh_?{x:o/r,y:i/r}:c\u003eh_?{x:-a/c*l,y:s/c*l}:{x:1,y:0}}},BL=(t,e,n,o,i)=\u003e{const r=t[e.routeIndex];if(!r)return!1;const s=IL(i,e,n,o,e.radius);if(Math.abs(s.x)\u003c=h_\u0026\u0026Math.abs(s.y)\u003c=h_)return!1;const a={x:e.x+s.x,y:e.y+s.y},c=_L(i,e),l=_L(i,a);if(l\u003ce.radius-u_)return!1;const d=xL(i,e.radius);if(vL(c,l,d))return!1;e.x+=s.x,e.y+=s.y,gk(e,i.bounds);for(const t of e.pointIndexes){const n=r.route[t];n\u0026\u0026(n.x=e.x,n.y=e.y)}return!0},jL=(t,e)=\u003e{const n=Gk(t),o=n.find(t=\u003et.routeIndex===e.routeIndex\u0026\u0026t.pointIndexes.some(t=\u003ee.pointIndexes.includes(t)));return o?n.filter(t=\u003et.rootConnectionName===o.rootConnectionName\u0026\u0026Math.hypot(t.x-o.x,t.y-o.y)\u003c=u_):[]},$L=(t,e,n,o,i)=\u003ee.movable\u0026\u0026jL(t,e).length\u003c=1\u0026\u0026BL(t,e,n,o,i),YL=(t,e,n,o,i=1)=\u003e{const{projection:r,direction:s}=FL(e,n),a=p_*i,c=1-r.t,l=r.t,d=ML(t,e.routeIndex,e.startIndex,s.x*a*c,s.y*a*c,o,e.radius),h=ML(t,e.routeIndex,e.endIndex,s.x*a*l,s.y*a*l,o,e.radius);return!(!d\u0026\u0026!h)||((t,e,n,o,i)=\u003e{const r=t[e.routeIndex];if(!r)return!1;const{projection:s,direction:a}=FL(e,n),c=IL(o,s,a.x*p_*i,a.y*p_*i,e.radius);if(Math.abs(c.x)\u003c=h_\u0026\u0026Math.abs(c.y)\u003c=h_)return!1;const l={...r.route[e.startIndex],x:s.x+c.x,y:s.y+c.y};if(gk(l,o.bounds),be(l,e.start,e.end)\u003c=u_)return!1;const d=r.route[e.startIndex],h=r.route[e.endIndex];if(!d||!h)return!1;const u=bL(o,d,h),p=Math.min(_L(o,l),bL(o,d,l),bL(o,l,h));if(p\u003ce.radius-u_)return!1;const m=xL(o,e.radius);return!vL(u,p,m)\u0026\u0026(r.route.splice(e.endIndex,0,l),!0)})(t,e,n,o,i)},XL=(t,e,n,o,i,r=1)=\u003e{const s=e.radius+f_(o)+g_,a=nD(e,n,s);if(!a)return!1;const c=Math.min(.3*Math.abs(r),a.penetration+g_),l=a.direction.x*c,d=a.direction.y*c,h=t[e.routeIndex];if(!h)return!1;const u=!(t=\u003e{for(let e=0;e\u003ct.route.length-1;e+=1){const n=t.route[e],o=t.route[e+1];if(n\u0026\u0026o\u0026\u0026n.z!==o.z\u0026\u0026Dk(n,o))return!0}return!1})(h);if(u\u0026\u0026EL(t,e.routeIndex,l,d,o,e.radius,i))return!0;const p=zL(t,e,n,s,l,d,o)||((t,e,n,o,i)=\u003e{const r=t[e.routeIndex];if(!r)return!1;const s=kL(r,e);return!!s\u0026\u0026wL(r,s,n,o,i,e.radius)})(t,e,l,d,o)||((t,e,n,o,i,r)=\u003e{const s=t[e.routeIndex];if(!s)return!1;const a=NL(i,s,e.startIndex,n,o,r),c=NL(i,s,e.endIndex,n,o,r);if(!a||!c)return!1;const l=[...new Set([...a,...c])],d=PL(i,s,l,n,o,e.radius);if(!d)return!1;let h=!1;for(const t of l){const e=s.route[t];e\u0026\u0026(e.x+=d.x,e.y+=d.y,gk(e,i.bounds),h=!0)}return h})(t,e,l,d,o,i);if(p)return!0;if(!u\u0026\u0026EL(t,e.routeIndex,l,d,o,e.radius,i))return!0;const m=n.width/2,g=n.height/2,f=(Math.abs(a.direction.y)\u003e=Math.abs(a.direction.x)?[{...h.route[e.startIndex],x:n.center.x-m-s,y:n.center.y+a.direction.y*(g+s)},{...h.route[e.startIndex],x:n.center.x+m+s,y:n.center.y+a.direction.y*(g+s)}]:[{...h.route[e.startIndex],x:n.center.x+a.direction.x*(m+s),y:n.center.y-g-s},{...h.route[e.startIndex],x:n.center.x+a.direction.x*(m+s),y:n.center.y+g+s}]).map(t=\u003e{const{t:n}=nL(t,e),i={x:e.start.x+(e.end.x-e.start.x)*n,y:e.start.y+(e.end.y-e.start.y)*n},r=IL(o,i,t.x-i.x,t.y-i.y,e.radius);return t.x=i.x+r.x,t.y=i.y+r.y,gk(t,o.bounds),{point:t,t:n,moved:Math.abs(r.x)\u003eh_||Math.abs(r.y)\u003eh_,awayFromObstacleMotion:r.x*a.direction.x+r.y*a.direction.y}}).sort((t,e)=\u003et.t-e.t);if(!f.some(({moved:t})=\u003et))return!1;if(!f.some(({awayFromObstacleMotion:t})=\u003et\u003eu_))return!1;const y=f.map(({point:t})=\u003et);if(y.every(t=\u003ebe(t,e.start,e.end)\u003c=u_))return!1;if(y.some(t=\u003e!yL(o,t)))return!1;const _=h.route[e.startIndex],b=h.route[e.endIndex],x=y[0],v=y[1];if(!(_\u0026\u0026b\u0026\u0026x\u0026\u0026v))return!1;const S=bL(o,_,b),I=Math.min(_L(o,x),_L(o,v),bL(o,_,x),bL(o,x,v),bL(o,v,b));if(I\u003ce.radius-u_)return!1;const C=xL(o,e.radius);return!vL(S,I,C)\u0026\u0026(h.route.splice(e.endIndex,0,...y),!0)},VL=(t,e,n)=\u003e{let o;for(const i of t){if(void 0!==n\u0026\u0026i.routeIndex!==n)continue;const t=nL(e,i),r=Math.hypot(t.x-e.x,t.y-e.y);(!o||r\u003co.distance)\u0026\u0026(o={segment:i,distance:r})}return o?.segment},WL=(t,e,n)=\u003e{let o;for(const i of t){if(void 0!==n\u0026\u0026i.routeIndex!==n)continue;const t=Math.hypot(i.x-e.x,i.y-e.y);(!o||t\u003co.distance)\u0026\u0026(o={via:i,distance:t})}return o?.via},HL=(t,e)=\u003e{const n=t.map(t=\u003e({via:t,distance:Math.hypot(t.x-e.x,t.y-e.y)})).sort((t,e)=\u003et.distance-e.distance).slice(0,2).map(({via:t})=\u003et);return 2===n.length?n:void 0},GL=(t,e,n,o)=\u003e{const i=e.x-n.x,r=e.y-n.y,s=Math.hypot(i,r);return $L(t,e,(s\u003eh_?i/s:1)*p_,(s\u003eh_?r/s:0)*p_,o)},UL=(t,e)=\u003e{const n=nL(t.start,e),o=nL(t.end,e),i=nL(e.start,t),r=nL(e.end,t);return[{leftT:0,rightT:n.t,leftPoint:t.start,rightPoint:n},{leftT:1,rightT:o.t,leftPoint:t.end,rightPoint:o},{leftT:i.t,rightT:0,leftPoint:i,rightPoint:e.start},{leftT:r.t,rightT:1,leftPoint:r,rightPoint:e.end}].sort((t,e)=\u003eMath.hypot(t.leftPoint.x-t.rightPoint.x,t.leftPoint.y-t.rightPoint.y)-Math.hypot(e.leftPoint.x-e.rightPoint.x,e.leftPoint.y-e.rightPoint.y))},ZL=(t,e,n,o,i,r)=\u003e{const s=mk(r,0,1),a=1-s,c=s,l=ML(t,e.routeIndex,e.startIndex,n*a,o*a,i,e.radius),d=ML(t,e.routeIndex,e.endIndex,n*c,o*c,i,e.radius);return l||d},qL=(t,e,n,o,i,r=.035,s=!1)=\u003e{if(!s\u0026\u0026uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const a=e.radius+n.radius+.2+g_,c=e.x-n.x,l=e.y-n.y,d=Math.hypot(c,l),h=a-d;if(h\u003c=0)return!1;const u=1.618*(97*e.routeIndex+13*n.routeIndex),p=d\u003eh_?c/d:Math.cos(u),m=d\u003eh_?l/d:Math.sin(u),g=Number(e.movable)+Number(n.movable);if(0===g)return!1;const f=Math.min(r,h/g),y=$L(t,e,p*f,m*f,o),_=$L(t,n,-p*f,-m*f,o);return y||_},JL=(t,e,n,o,i)=\u003e{if(!uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const[r,s]=e.canCanonicalize?n.canCanonicalize\u0026\u0026e.routeIndex\u003c=n.routeIndex?[e,n]:[n,e]:[e,n];return((t,e,n,o)=\u003e{if(!n.canCanonicalize)return!1;const i=e.x-n.x,r=e.y-n.y;if(!n.movable\u0026\u0026Math.hypot(i,r)\u003en.radius+u_)return!1;const s=t[n.routeIndex];if(!s)return!1;const a={x:n.x,y:n.y},c=n.pointIndexes.map(t=\u003e{const e=s.route[t];return e?{pointIndex:t,x:e.x,y:e.y}:void 0});if(BL(t,n,i,r,o)\u0026\u0026Dk(n,e))return!0;n.x=a.x,n.y=a.y;for(const t of c){if(!t)continue;const e=s.route[t.pointIndex];e\u0026\u0026(e.x=t.x,e.y=t.y)}return!1})(t,r,s,o)},KL=(t,e,n,o,i,r=.035,s=2,a=!1)=\u003e{if(uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const c=nL(e,n),l=e.x-c.x,d=e.y-c.y,h=Math.hypot(l,d),u=e.radius+n.radius+(rk.traceClearance??.1)+g_-h;if(u\u003c=0)return!1;const p=n.end.x-n.start.x,m=n.end.y-n.start.y,g=Math.hypot(p,m),f=e.routeIndex%2==0?1:-1,y=h\u003eh_?l/h:g\u003eh_?-m/g*f:1,_=h\u003eh_?d/h:g\u003eh_?p/g*f:0,b=Math.min(r,u/s),x=a?((t,e,n,o,i)=\u003e{const r=jL(t,e);if(0===r.length||r.some(e=\u003e!e.movable||void 0===t[e.routeIndex]))return!1;const s=r.reduce((t,e)=\u003ee.radius\u003et.radius?e:t);if(!BL(t,s,n,o,i))return!1;for(const e of r){if(e===s)continue;e.x=s.x,e.y=s.y;const n=t[e.routeIndex];for(const t of e.pointIndexes){const e=n.route[t];e\u0026\u0026(e.x=s.x,e.y=s.y)}}return!0})(t,e,y*b,_*b,o):$L(t,e,y*b,_*b,o),v=ZL(t,n,-y*b,-_*b,o,c.t);return x||v},QL=(t,e,n,o,i)=\u003e{if(e.z!==n.z||uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const[r]=UL(e,n);if(!r)return!1;const s=r.leftPoint.x-r.rightPoint.x,a=r.leftPoint.y-r.rightPoint.y,c=Math.hypot(s,a),l=e.radius+n.radius+(rk.traceClearance??.1)+g_-c;if(l\u003c=0)return!1;const d=e.end.x-e.start.x,h=e.end.y-e.start.y,u=Math.hypot(d,h),p=(e.routeIndex+n.routeIndex)%2==0?1:-1,m=c\u003eh_?s/c:u\u003eh_?-h/u*p:1,g=c\u003eh_?a/c:u\u003eh_?d/u*p:0,f=Math.min(m_,l/2),y=ZL(t,e,m*f,g*f,o,r.leftT),_=ZL(t,n,-m*f,-g*f,o,r.rightT);return y||_},tD=(t,e,n)=\u003eQk(t,n).includes(e.z),eD=(t,e,n,o,i)=\u003e{const r=e[n];if(!r)return;const s=Uk(r,n);if(0===s.length)return;const a=dk(r),c=VL(s,o);if(!c)return;const l=sL(t,o,.6,e=\u003e!pk(a,e,i)\u0026\u0026tD(e,c,t.layerCount));if(l)return{obstacle:l,segment:c};const d=sL(t,o,.6,e=\u003e!pk(a,e,i)\u0026\u0026s.some(n=\u003etD(e,n,t.layerCount)));if(!d)return;const h=VL(s.filter(e=\u003etD(d,e,t.layerCount)),o);return h?{obstacle:d,segment:h}:void 0},nD=(t,e,n)=\u003e{const o=e.width/2,i=e.height/2,r=[{x:e.center.x-o,y:e.center.y-i},{x:e.center.x+o,y:e.center.y-i},{x:e.center.x+o,y:e.center.y+i},{x:e.center.x-o,y:e.center.y+i}],s=[e.center,...r].map(e=\u003enL(e,t)),a=[{point:t.start,t:0},{point:t.end,t:1},{point:{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2},t:.5},...s.map(t=\u003e({point:{x:t.x,y:t.y},t:t.t}))];let c;const l=Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y);for(const o of a){const i=aL(o.point,e,n);if(!i)continue;const r=l\u003eh_?Math.abs(((t.end.x-t.start.x)*i.direction.y-(t.end.y-t.start.y)*i.direction.x)/l):0;(!c||i.penetration\u003ec.penetration+h_||Math.abs(i.penetration-c.penetration)\u003c=h_\u0026\u0026r\u003ec.normality)\u0026\u0026(c={...i,normality:r,t:o.t})}return c},oD=(t,e,n,o=!1)=\u003e{let i=!1;const r=Gk(e),s=Zk(e),a=tL(t,r,s),c=Math.max(1,2*a),l=bk(r,qk,c),d=bk(s,Jk,c);for(let s=0;s\u003cr.length;s+=1){const d=r[s];if(!d)continue;const h=xk(l,fk(qk(d),a),c);for(const a of h){if(a\u003c=s)continue;const c=r[a];c\u0026\u0026(i=qL(e,d,c,t,n,m_,o)||i)}}for(let o=0;o\u003cr.length;o+=1){const l=r[o];if(!l)continue;const h=xk(d,fk(qk(l),a),c);for(const o of h){const r=s[o];r\u0026\u0026(i=KL(e,l,r,t,n)||i)}}for(let o=0;o\u003cs.length;o+=1){const r=s[o];if(!r)continue;const l=xk(d,fk(Jk(r),a),c);for(const a of l){if(a\u003c=o)continue;const c=s[a];c\u0026\u0026(i=QL(e,r,c,t,n)||i)}}return((t,e,n,o,i,r,s,a)=\u003e{let c=!1;const l=t.minTraceWidth/2+f_(t)+g_,d=(t.minViaDiameter??.3)/2+y_(t)+g_;for(const h of t.obstacles){if(h.isCopperPour)continue;const u=Kk(h),p=xk(i,fk(u,d),s);for(const o of p){const i=n[o];if(!i)continue;if(pk(i.rootConnectionName,h,a))continue;const r=aL(i,h,d);if(!r)continue;const s=Math.min(m_,r.penetration);c=$L(e,i,r.direction.x*s,r.direction.y*s,t)||c}const m=xk(r,fk(u,l),s);for(const n of m){const i=o[n];if(!i)continue;if(pk(i.rootConnectionName,h,a)||!tD(h,i,t.layerCount))continue;const r=nD(i,h,l);if(!r)continue;const s=Math.min(m_,r.penetration);c=ZL(e,i,r.direction.x*s,r.direction.y*s,t,r.t)||c}}return c})(t,e,r,s,l,d,c,n)||i},iD=(t,e,n,o=1,i,r=!1,s=!0)=\u003e{const a=kk(e),c=Math.max(2,Math.round(12*Math.max(1,n)*o));let l=!1;for(let e=0;e\u003cc;e+=1){if(!oD(t,a,i,r))break;l=!0}return l\u0026\u0026s\u0026\u0026((t,e,n)=\u003e{let o=!1;const i=Gk(e),r=Zk(e),s=tL(t,i,r),a=Math.max(1,2*s),c=bk(r,Jk,a);for(const l of i){const i=xk(c,fk(qk(l),s),a);for(const s of i){const i=r[s];i\u0026\u0026(o=KL(e,l,i,t,n,m_,1.75)||o)}}})(t,a,i),l?aD(a):e},rD=t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n+=1){const o=t.route[n],i=t.route[n+1];if(!o||!i)continue;if(\"through_obstacle\"===o.toNextSegmentType)continue;if(o.z===i.z||!Dk(o,i))continue;const r={x:o.x,y:o.y},s=e.at(-1);s\u0026\u0026Dk(s,r)||e.push(r)}return e},sD=t=\u003e({...t,vias:rD(t)}),aD=t=\u003et.map(sD),cD=(t,e)=\u003e{const n=new Set(e);return t.map((t,e)=\u003en.has(e)?sD(t):t)},lD=t=\u003e{const e=t.pcb_trace_id;if(\"string\"!=typeof e)return;const n=e.match(/^trace_(\\d+)/);return n?Number.parseInt(n[1],10):void 0},dD=t=\u003e{const e=t.center??t.pcb_center;if(!e||\"object\"!=typeof e)return;const n=e;return\"number\"==typeof n.x\u0026\u0026\"number\"==typeof n.y?{x:n.x,y:n.y}:void 0},hD=(t,e=!0)=\u003et.errors.filter(t=\u003e(t=\u003e\"pcb_via_clearance_error\"===Fk(t)||Array.isArray(t.pcb_via_ids))(t)\u0026\u0026(e||!uD(t))).length,uD=t=\u003e\"pcb_pad_pad_clearance_error\"===Fk(t)\u0026\u0026Array.isArray(t.pcb_via_ids)\u0026\u00261===t.pcb_via_ids.length,pD=t=\u003e{const e=Object.entries(t).filter(([t,e])=\u003e\"source_trace_id\"!==t\u0026\u0026(t.endsWith(\"_id\")||t.endsWith(\"_ids\"))\u0026\u0026void 0!==e\u0026\u0026\"\"!==e).sort(([t],[e])=\u003et.localeCompare(e)),n=\"string\"==typeof t.message?t.message.replace(/-?\\d+\\.\\d+/g,\"#\"):\"\";return JSON.stringify([Fk(t),e,n])},mD=t=\u003eMath.max(t.errors.filter(t=\u003e!uD(t)).length,t.count-t.errors.filter(uD).length),gD=t=\u003e{const e=mD(t);return e\u003e0?e:t.count},fD=t=\u003e{if(0===mD(t))return t.issueScore;const e=t.errors.filter(t=\u003e!uD(t));return t.errors.some(uD)?Xk(e):t.legacyIssueScore??Xk(e)},yD=(t,e)=\u003e{const n=mD(t),o=mD(e);return n!==o?n\u003co:!(n\u003e0)\u0026\u0026t.count\u003ce.count},_D=t=\u003e{const e=t.filter(t=\u003e!uD(t));return e.length\u003e0?e:t},bD=(t,e)=\u003e{const n=t.pcb_trace_id;return\"string\"==typeof n?e.get(n)??lD(t):lD(t)},xD=(t,e,n,o,i)=\u003e{const r=n.pcb_port_id;if(!r)return!1;const s=(i??e.viaDiameter)/2;return t.obstacles.some(i=\u003e{const a=Qk(i,t.layerCount);return!(1!==a.length||a[0]!==n.z||!i.connectedTo.includes(r)||n.x-s\u003ci.center.x-i.width/2-h_||n.x+s\u003ei.center.x+i.width/2+h_||n.y-s\u003ci.center.y-i.height/2-h_||n.y+s\u003ei.center.y+i.height/2+h_)\u0026\u0026(pk(dk(e),i,o)||pk(e.connectionName,i,o))})},vD=[0,1,-1,2,-2,3,-3,4],SD=vD.flatMap(t=\u003evD.map(e=\u003e[t,e])).sort(([t,e],[n,o])=\u003eMath.abs(t)+Math.abs(e)-Math.abs(n)-Math.abs(o)),ID=SD.length,CD=(t,e,n)=\u003et.x-e\u003e=n.minX-h_\u0026\u0026t.x+e\u003c=n.maxX+h_\u0026\u0026t.y-e\u003e=n.minY-h_\u0026\u0026t.y+e\u003c=n.maxY+h_,PD=(t,e)=\u003e{const n=t.at(-1);n\u0026\u0026Dk(n,e)\u0026\u0026n.z===e.z\u0026\u0026n.pcb_port_id===e.pcb_port_id||t.push(e)},MD=(t,e,n,o,i,r,s,a=0,c=!1)=\u003e{const l=Fk(n);if(\"pcb_pad_trace_clearance_error\"!==l\u0026\u0026\"pcb_trace_error\"!==l)return!1;if(i\u003c0||i\u003e=t.layerCount)return!1;const d=e[o];if(!d||d.route.length\u003c2)return!1;const h=d.route.map(t=\u003e({...t})),u=h[0],p=h.at(-1);if(!u||!p)return!1;const m=dD(n);if(!m)return!1;const g=Bk(n),f=g?eD(t,e,o,m,s):void 0,y=g?f?.segment:VL(Uk(d,o),m);if(!y||y.z===i)return!1;let _=y.startIndex,b=y.endIndex;const x=\"full\"===r?h.length:r;for(let t=0;t\u003cx;t+=1){let t=!1;const e=h[_-1];e?.z===y.z\u0026\u0026(_-=1,t=!0);const n=h[b+1];if(n?.z===y.z\u0026\u0026(b+=1,t=!0),!t)break}const v=0===_\u0026\u0026u.pcb_port_id,S=b===h.length-1\u0026\u0026p.pcb_port_id,I=d.viaDiameter/2,C=SD[a%ID];let P=!1;const M=e=\u003e{const n=\"start\"===e?u:p,o=((t,e,n,o)=\u003e{const i=n.pcb_port_id;if(i)return t.obstacles.find(r=\u003e{const s=Qk(r,t.layerCount);return!(1!==s.length||s[0]!==n.z||!r.connectedTo.includes(i)||!iL(n,r))\u0026\u0026(pk(dk(e),r,o)||pk(e.connectionName,r,o))})})(t,d,n,s),r=((t,e)=\u003e{const n=\"start\"===e?t[0]:t.at(-1);if(!n)return;const o=\"start\"===e?Array.from({length:t.length-1},(t,e)=\u003ee+1):Array.from({length:t.length-1},(e,n)=\u003et.length-n-2);for(const e of o){const o=t[e];if(!o)continue;const i=o.x-n.x,r=o.y-n.y,s=Math.hypot(i,r);if(!(s\u003c=h_))return{x:i/s,y:r/s}}})(h,e);if(!o||!r)return;const a=((t,e,n,o)=\u003e{let i=0,r=Math.hypot(e.width,e.height)+2*o;const s=o+h_,a=e=\u003e({x:t.x+n.x*e,y:t.y+n.y*e});if(!(oL(a(r),e)\u003cs)){for(;r-i\u003eh_;){const t=(i+r)/2;oL(a(t),e)\u003e=s?r=t:i=t}return a(r)}})(n,o,((t,e)=\u003e{const n=e*Math.PI/4,o=Math.cos(n),i=Math.sin(n);return{x:t.x*o-t.y*i,y:t.x*i+t.y*o}})(r,\"start\"===e?C[0]:C[1]),I);if(!a||!CD(a,I,t.bounds)||oL(a,o)+h_\u003cI)return;if(!c)return a;const l=((t,e,n,o,i,r)=\u003e{const s=o+(t.minBoardEdgeClearance??0),a={minX:t.bounds.minX+s,maxX:t.bounds.maxX-s,minY:t.bounds.minY+s,maxY:t.bounds.maxY-s};if(a.minX\u003ea.maxX||a.minY\u003ea.maxY)return;const c=Ek(t,e,o,i,r),l=t=\u003eMe(t,a)\u0026\u0026c.every(e=\u003eCk(t,e)\u003e=e.clearance),d=Ik(n,a);if(l(d))return Me(n,a)?n:d;const h=c.filter(t=\u003eCk(d,t)\u003ct.clearance),u=new Set(h);for(let t=0;t\u003ch.length;t+=1)for(const e of c)!u.has(e)\u0026\u0026Xe(h[t].bounds,e.bounds)\u0026\u0026(u.add(e),h.push(e));const p=h.flatMap(Nk),m={x:a.minX,y:a.minY},g={x:a.maxX,y:a.minY},f={x:a.maxX,y:a.maxY},y={x:a.minX,y:a.maxY};let _;p.push(Pk(m,g),Pk(g,f),Pk(f,y),Pk(y,m));let b=Number.POSITIVE_INFINITY;const x=t=\u003e{const e=Ye(t,n);e\u003cb\u0026\u0026l(t)\u0026\u0026(_=t,b=e)};for(const t of p)for(const e of wk(n,t))x(e);for(let t=0;t\u003cp.length;t+=1){const e=p[t];if(!(Ye(n,Ik(n,e.bounds))\u003eb))for(let o=t+1;o\u003cp.length;o+=1){const t=p[o];if(Xe(e.bounds,t.bounds)\u0026\u0026!(Ye(n,Ik(n,t.bounds))\u003eb))for(const n of Rk(e,t))x(n)}}return _})(t,d,a,I,[y.z,i],s);return P||=void 0!==l\u0026\u0026l!==a,l},N=v?M(\"start\"):void 0,w=S?M(\"end\"):void 0;if(v\u0026\u0026!N||S\u0026\u0026!w||c\u0026\u0026!P)return!1;const T=[];for(let t=0;t\u003c_;t+=1)PD(T,h[t]);const R=h[_],E=_\u003e0\u0026\u0026Dk(h[_-1],R),A=h[b],O=b\u003ch.length-1\u0026\u0026Dk(h[b+1],A);v?(PD(T,u),PD(T,{...u,...N,pcb_port_id:void 0}),PD(T,{...u,...N,z:i,pcb_port_id:void 0})):(E||PD(T,{...R,pcb_port_id:void 0}),PD(T,{...R,z:i,pcb_port_id:void 0}));const k=S?b-1:b;for(let t=_+1;t\u003c=k;t+=1)PD(T,{...h[t],z:i,pcb_port_id:void 0});S?(PD(T,{...p,...w,z:i,pcb_port_id:void 0}),PD(T,{...p,...w,pcb_port_id:void 0}),PD(T,p)):O||PD(T,{...A,pcb_port_id:void 0});for(let t=b+1;t\u003ch.length;t+=1)PD(T,h[t]);for(let t=1;t\u003cT.length-1;t+=1)T[t].pcb_port_id=void 0;const L=t.minBoardEdgeClearance??.2,D=Uk(d,o),z=Gk([d]);for(let e=1;e\u003cT.length;e+=1){const n=T[e-1],o=T[e];if(n.z===o.z\u0026\u0026!D.some(t=\u003epL(n,t.start,t.end)\u0026\u0026pL(o,t.start,t.end))\u0026\u0026bL(t,n,o)\u003cd.traceThickness/2+L)return!1;if(n.z!==o.z\u0026\u0026\"through_obstacle\"!==n.toNextSegmentType\u0026\u0026!z.some(t=\u003eDk(t,o)\u0026\u0026t.radius\u003e=I)\u0026\u0026_L(t,o)\u003cI+L)return!1}return d.route=T,!0},ND=(t,e,n,o,i,r,s)=\u003e{const a=Fk(n);if(\"pcb_pad_trace_clearance_error\"!==a\u0026\u0026\"pcb_trace_error\"!==a)return!1;if(i\u003c0||i\u003e=t.layerCount)return!1;const c=bD(n,o);if(void 0===c)return!1;const l=e[c];if(!l||l.route.length\u003c2)return!1;const d=l.route[0],h=l.route.at(-1);if(!d||!h||d.z!==h.z||i===d.z)return!1;if(l.route.some(t=\u003et.z!==d.z))return!1;if(!d.pcb_port_id||!h.pcb_port_id)return!1;if(!xD(t,l,d,r,s)||!xD(t,l,h,r,s))return!1;const u=l.route.map(t=\u003e({...t}));return l.route=[u[0],{...u[0],z:i,pcb_port_id:void 0},...u.slice(1,-1).map(t=\u003e({...t,z:i})),{...u.at(-1),z:i,pcb_port_id:void 0},u.at(-1)],!0},wD=(t,e,n,o,i,r,s)=\u003e{if(\"pcb_pad_trace_clearance_error\"!==Fk(n))return!1;const a=bD(n,o);if(void 0===a)return!1;const c=e[a];if(!c||c.route.length\u003c4)return!1;const l=c.route.map(t=\u003e({...t}));if(\"start\"===i){const e=l[0];if(!xD(t,c,e,r,s))return!1;let n=-1;for(let t=1;t\u003cl.length;t+=1)if(l[t].z!==e.z){n=t;break}if(n\u003c=0)return!1;const o=n-1;if(!Dk(l[o],l[n]))return!1;let i=n;for(;i+1\u003cl.length\u0026\u0026Dk(l[n],l[i+1]);)i+=1;const a=l[i].z,d=l.slice(o,i+1).map(t=\u003et.z);return c.route=[e,...d.slice(1).map(t=\u003e({...e,z:t,pcb_port_id:void 0})),...l.slice(1,o+1).map(t=\u003e({...t,z:a})),...l.slice(i+1)],!0}const d=l.at(-1);if(!xD(t,c,d,r,s))return!1;let h=-1;for(let t=l.length-2;t\u003e=0;t-=1)if(l[t].z!==d.z){h=t;break}if(h\u003c0||h\u003e=l.length-1)return!1;const u=h+1;if(!Dk(l[h],l[u]))return!1;let p=h;for(;p-1\u003e=0\u0026\u0026Dk(l[h],l[p-1]);)p-=1;const m=l[p].z,g=l.slice(p,u+1).map(t=\u003et.z);return c.route=[...l.slice(0,p+1),...l.slice(u+1,-1).map(t=\u003e({...t,z:m})),{...d,z:m,pcb_port_id:void 0},...g.slice(1,-1).map(t=\u003e({...d,z:t,pcb_port_id:void 0})),d],!0},TD=(t,e)=\u003e{const n=t.pcb_trace_id;if(\"string\"!=typeof n)return;if(Array.isArray(t.pcb_via_ids)\u0026\u0026t.pcb_via_ids.length\u003e0)return;const o=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],i=t.pcb_trace_error_id,r=`overlap_${n}_`,s=\"string\"==typeof i\u0026\u0026i.startsWith(r)?i.slice(r.length):void 0,a=[n,...o,...s?[s]:[]],c=[...new Set(a.map(t=\u003ee.get(t)).filter(t=\u003evoid 0!==t))];return c.length\u003e=2?[c[0],c[1]]:void 0},RD=(t,e,n,o,i)=\u003e{if(\"pcb_trace_error\"!==Fk(n))return;const r=TD(n,o);if(!r)return;const s=n.worst_contact_center??n.center;if(!s||\"object\"!=typeof s)return;const a=s;if(\"number\"!=typeof a.x||\"number\"!=typeof a.y)return;const c={x:a.x,y:a.y},l=Zk(e),d=VL(l,c,r[0]),h=VL(l,c,r[1]);if(!d||!h||d.z!==h.z)return;const[u]=UL(d,h);if(!u)return;const p=u.leftPoint.x-u.rightPoint.x,m=u.leftPoint.y-u.rightPoint.y,g=Math.hypot(p,m),f=Number(n.minimum_clearance),y=Number.isFinite(f)?f:rk.traceClearance??.1,_=d.radius+h.radius+y-g;if(_\u003c=h_)return;const b=0===i?d:h,x=0===i?u.leftT:u.rightT,v=(1-x)**2+x**2;if(v\u003c=h_)return;const S=_/v,I=0===i?u.leftPoint:u.rightPoint,C=0===i?u.rightPoint:u.leftPoint,P=0===i?1:-1,M=b.end.x-b.start.x,N=b.end.y-b.start.y,w=Math.hypot(M,N),T=(b.routeIndex+(0===i?h.routeIndex:d.routeIndex))%2==0?1:-1,R=g\u003eh_?(I.x-C.x)/g:w\u003eh_?-N/w*T*P:P,E=g\u003eh_?(I.y-C.y)/g:w\u003eh_?M/w*T*P:0;return ZL(e,b,R*S,E*S,t,x)?{movedRouteIndex:b.routeIndex}:void 0},ED=t=\u003e{const{srj:e,via:n,segment:o,segments:i,initialTarget:r,requiredTraceDistance:s,requiredObstacleDistance:a,connMap:c}=t,l=Math.min(...n.zLayers),d=Math.max(...n.zLayers),h=e.obstacles.filter(t=\u003e!t.isCopperPour\u0026\u0026!pk(n.rootConnectionName,t,c)\u0026\u0026Qk(t,e.layerCount).some(t=\u003et\u003e=l\u0026\u0026t\u003c=d)),u=h.filter(t=\u003eBoolean(aL(r,t,a))),p=[r,...Ak(n,i,s-n.radius-o.radius,c),...u.flatMap(t=\u003e(t=\u003e{const{point:e,obstacle:n,requiredDistance:o}=t,i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=n.center.y-n.height/2,a=n.center.y+n.height/2,c=Math.max(i-e.x,e.x-r,0),l=Math.max(s-e.y,e.y-a,0),d=[];if(c\u003co){const t=Math.sqrt(o*o-c*c);d.push({x:e.x,y:s-t-h_},{x:e.x,y:a+t+h_})}if(l\u003co){const t=Math.sqrt(o*o-l*l);d.push({x:i-t-h_,y:e.y},{x:r+t+h_,y:e.y})}return d})({point:r,obstacle:t,requiredDistance:a}))];return p.filter(t=\u003e{if(!CD(t,n.radius,e.bounds))return!1;const r=nL(t,o);return!(Math.hypot(t.x-r.x,t.y-r.y)\u003cs-h_)\u0026\u0026(!i.some(e=\u003ee.z\u003e=l\u0026\u0026e.z\u003c=d\u0026\u0026!uk(n.rootConnectionName,e.rootConnectionName,c)\u0026\u0026be(t,e.start,e.end)\u003cs+e.radius-o.radius-h_)\u0026\u0026h.every(e=\u003eoL(t,e)\u003e=a-h_))}).sort((t,e)=\u003eMath.hypot(t.x-n.x,t.y-n.y)-Math.hypot(e.x-n.x,e.y-n.y))[0]},AD=(t,e,n,o,i,r)=\u003e{if(\"pcb_trace_error\"!==Fk(n))return!1;const s=\"string\"==typeof n.pcb_trace_error_id?n.pcb_trace_error_id.toLowerCase():\"\",a=\"string\"==typeof n.message?n.message.toLowerCase():\"\";if(!(\"string\"==typeof n.pcb_via_id||Array.isArray(n.pcb_via_ids)||s.includes(\"_via_\")||a.includes(\"via\")))return!1;if(bD(n,o)!==i)return!1;if(TD(n,o))return!1;const c=n.worst_contact_center??n.center;if(!c||\"object\"!=typeof c)return!1;const l=c;if(\"number\"!=typeof l.x||\"number\"!=typeof l.y)return!1;const d={x:l.x,y:l.y},h=Zk(e),u=VL(h,d,i),p=Array.isArray(n.pcb_trace_ids)?n.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t\u0026\u0026t!==n.pcb_trace_id):[],m=p.map(t=\u003eo.get(t)).filter(t=\u003evoid 0!==t),g=Gk(e),f=WL(p.length\u003e0?g.filter(t=\u003em.includes(t.routeIndex)):g,d);if(!u||!f||!f.movable||uk(f.rootConnectionName,u.rootConnectionName,r))return!1;const y=nL(f,u),_=f.x-y.x,b=f.y-y.y,x=Math.hypot(_,b),v=Number(n.minimum_clearance),S=Number.isFinite(v)?v:rk.traceClearance??.1,I=f.radius+u.radius+S-x;if(I\u003c=h_)return!1;const C=u.end.x-u.start.x,P=u.end.y-u.start.y,M=Math.hypot(C,P),N=f.routeIndex%2==0?1:-1,w=x\u003eh_?_/x:M\u003eh_?-P/M*N:1,T=x\u003eh_?b/x:M\u003eh_?C/M*N:0,R=f.radius+u.radius+S,E=f.radius+y_(t)+g_,A={x:f.x+w*(I+g_),y:f.y+T*(I+g_)},O=ED({srj:t,via:f,segment:u,segments:h,initialTarget:A,requiredTraceDistance:R,requiredObstacleDistance:E,connMap:r});return!!O\u0026\u0026$L(e,f,O.x-f.x,O.y-f.y,t)},OD=(t,e,n)=\u003e{if(\"pcb_trace_error\"!==Fk(e))return;const o=dD(e),i=t[n];if(!o||!i)return;const r=VL(Uk(i,n),o);return r?{center:o,route:i,segment:r}:void 0},kD=(t,e,n,o)=\u003e{const i=OD(t,e,n);if(!i)return;const{route:r,segment:s}=i,a=Math.max(0,s.startIndex-o),c=Math.min(r.route.length-1,s.endIndex+o),l=r.route.slice(a,c+1),d=l[0],h=l.at(-1);return d\u0026\u0026h\u0026\u0026!l.some(t=\u003et.z!==d.z)\u0026\u0026d.z===h.z?{route:r,spanStartIndex:a,spanEndIndex:c,start:d,end:h}:void 0},LD=(t,e,n,o,i,r,s=0,a,c)=\u003e{if(r\u003c0||r\u003e=t.layerCount)return!1;const l=TD(n,o);if(!l)return!1;const d=l[i],h=OD(e,n,d);if(!h||h.segment.z===r)return!1;const{route:u,segment:p}=h;let m=p.startIndex,g=p.endIndex;for(let t=0;t\u003cs;t+=1){const t=u.route[m-1];t?.z===p.z\u0026\u0026(m-=1);const e=u.route[g+1];e?.z===p.z\u0026\u0026(g+=1)}if(0===m\u0026\u0026u.route[0]?.pcb_port_id\u0026\u0026!xD(t,u,u.route[0],a,c)||g===u.route.length-1\u0026\u0026u.route.at(-1)?.pcb_port_id\u0026\u0026!xD(t,u,u.route.at(-1),a,c))return!1;const f=u.route[m],y=u.route[g];if(!f||!y||f.z!==y.z)return!1;const _=u.route.slice(m,g+1).map(t=\u003e({...t,z:r,pcb_port_id:void 0}));return u.route.splice(m,g-m+1,{...f},..._,{...y}),!0},DD=(t,e,n,o,i,r)=\u003e{if(o\u003c=0||i\u003c=0)return!1;const s=OD(t,e,n);if(!s)return!1;const{center:a,route:c,segment:l}=s,d=l.end.x-l.start.x,h=l.end.y-l.start.y,u=Math.hypot(d,h);if(u\u003c=h_)return!1;const p=nL(a,l),m=mk(p.t-o/u,.02,.98),g=mk(p.t+o/u,.02,.98);if(m\u003e=g)return!1;const f=t=\u003e({x:l.start.x+d*t,y:l.start.y+h*t,z:l.z}),y=f(m),_=f(g),b=-h/u*r,x=d/u*r,v=c.route[l.startIndex],S=c.route[l.endIndex];return c.route.splice(l.startIndex,2,{...v},y,{...y,x:y.x+b*i,y:y.y+x*i},{..._,x:_.x+b*i,y:_.y+x*i},_,{...S}),!0},zD=(t,e,n,o,i,r,s,a=!1)=\u003e{if(!Number.isInteger(i)||i\u003c0||i\u003e=t.layerCount)return!1;const c=dD(n),l=e[o],d=l?.route[0],h=l?.route.at(-1);if(!l||!c||!d||!h||d.z!==h.z||d.z===i||l.jumpers?.length||l.route.some(t=\u003et.z!==d.z||\"through_obstacle\"===t.toNextSegmentType))return!1;const u=h.x-d.x,p=h.y-d.y,m=Math.hypot(u,p);if(m\u003c=h_||m\u003e8)return!1;const g=u/m,f=p/m,y=f*r,_=-g*r,b=t=\u003e(t.x-c.x)*g+(t.y-c.y)*f,x=(t,e,n)=\u003e({x:c.x+g*t+y*e,y:c.y+f*t+_*e,z:n}),v=(l.viaDiameter??t.minViaDiameter??.3)+(t.minTraceToPadEdgeClearance??rk.traceClearance??.1),S=(a?1.25:-.75)*v,I=(a?-.75:1.25)*v,C=b(d)+.5*v*s,P=b(h)+v*s,M=x(C,S,d.z),N=x(P,I,d.z),w=x(C,2*v,i),T=x(P,2*v,i),R=[{...d},M,{...M,z:i},w,T,{...N,z:i},N,{...h}],E=t.minBoardEdgeClearance??0,A=(l.viaDiameter??t.minViaDiameter??.3)/2,O=l.traceThickness/2;if([M,N].some(e=\u003e_L(t,e)+u_\u003cA+E))return!1;for(let e=0;e\u003cR.length-1;e+=1){const n=R[e],o=R[e+1];if(n.z===o.z\u0026\u0026bL(t,n,o)+u_\u003cO+E)return!1}return l.route.splice(0,l.route.length,...R),!0},FD=(t,e,n,o,i,r,s)=\u003e{if(!Number.isInteger(i)||i\u003c1||r\u003c=0)return!1;const a=kD(e,n,o,i);if(!a)return!1;const{route:c,spanStartIndex:l,spanEndIndex:d,start:h,end:u}=a,p=u.x-h.x,m=u.y-h.y,g=Math.hypot(p,m);if(g\u003c=h_)return!1;const f=-m/g*s*r,y=p/g*s*r,_={...h,x:h.x+f,y:h.y+y,pcb_port_id:void 0},b={...u,x:u.x+f,y:u.y+y,pcb_port_id:void 0};return!(!hL(_,t.bounds)||!hL(b,t.bounds))\u0026\u0026(c.route.splice(l,d-l+1,{...h},_,b,{...u}),!0)},BD=(t,e,n,o,i,r)=\u003e{if(!Number.isInteger(i)||i\u003c0)return!1;const s=kD(e,n,o,i);if(!s)return!1;const{route:a,spanStartIndex:c,spanEndIndex:l,start:d,end:h}=s;return!(Math.hypot(r.x-d.x,r.y-d.y)\u003c=h_||Math.hypot(r.x-h.x,r.y-h.y)\u003c=h_||!hL(r,t.bounds))\u0026\u0026(a.route.splice(c,l-c+1,{...d},{x:r.x,y:r.y,z:d.z},{...h}),!0)},jD=(t,e,n,o,i,r)=\u003e{if(r){const e=mD(t),n=mD(r);if(e!==n)return e\u003cn}const s=gD(t),a=fD(t);return s\u003cn||s===n\u0026\u0026a\u003co||s===n\u0026\u0026e\u003ci},$D=(t,e,n,o,i,r,s=!0,a=!1,c=!0,l=!1)=\u003e{let d=!1;const h=Gk(e),u=Zk(e);for(const p of n){const n=dD(p);if(!n)continue;let m=n;const g=p.pcb_via_ids,f=\"pcb_via_clearance_error\"===Fk(p),y=uD(p),_=Array.isArray(g)\u0026\u0026g.length\u003e0,b=!f\u0026\u0026!y\u0026\u0026_\u0026\u0026(\"string\"==typeof p.pcb_trace_id||Array.isArray(p.pcb_trace_ids)),x=l\u0026\u0026b;if(_\u0026\u0026!b){m=cL(t,p,n);const c=bD(p,o),l=g.length\u003e1?HL(h,n):void 0;if(l){const n=a\u0026\u0026\"pcb_via_clearance_error\"===Fk(p)\u0026\u0026\"same_net\"===p.pcb_via_pair_net_relation,o=s\u0026\u0026\"pcb_via_clearance_error\"===Fk(p);d=(n?JL(e,l[0],l[1],t,r):qL(e,l[0],l[1],t,r,.16*Math.abs(i),o))||d}else{const o=WL(h,n,c);o\u0026\u0026(d=GL(e,o,m,t)||d)}continue}const v=p.pcb_trace_id,S=bD(p,o);if(x\u0026\u0026void 0===S)continue;const I=Array.isArray(p.pcb_trace_ids)?p.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[];if(x\u0026\u0026\"string\"==typeof v\u0026\u0026void 0!==S\u0026\u0026I.includes(v)\u0026\u0026I.some(t=\u003et!==v\u0026\u0026!o.has(t))){const o=WL(h,n,S);if(o){d=GL(e,o,n,t)||d;continue}}const C=s\u0026\u0026!b?TD(p,o):void 0;if(C){const o=VL(u,n,C[0]),i=VL(u,n,C[1]);if(o\u0026\u0026i\u0026\u0026QL(e,o,i,t,r)){d=!0;continue}}const P=Bk(p),M=P\u0026\u0026void 0!==S?eD(t,e,S,n,r):void 0,N=P?M?.segment:VL(u,n,S);if(N){const o=P?M?.obstacle:sL(t,n);if(P\u0026\u0026!o)continue;m=P?o?.center??n:cL(t,p,n);const s=x?void 0:WL(h,n),a=\"pcb_via_trace_clearance_error\"===Fk(p),l=\"string\"==typeof p.pcb_trace_error_id?p.pcb_trace_error_id.toLowerCase():\"\",u=\"string\"==typeof p.message?p.message.toLowerCase():\"\",g=a||\"string\"==typeof p.pcb_via_id||Array.isArray(p.pcb_via_ids)||l.includes(\"_via_\")||u.includes(\"via\"),f=Array.isArray(p.pcb_port_ids)\u0026\u0026p.pcb_port_ids.length\u003e0;if(s\u0026\u0026!uk(s.rootConnectionName,N.rootConnectionName,r)\u0026\u0026(a||Math.hypot(s.x-n.x,s.y-n.y)\u003c.45)){if(KL(e,s,N,t,r,.3*Math.abs(i),1,c)\u0026\u0026(d=!0,g\u0026\u0026!f))continue}d=(void 0!==o\u0026\u0026(P||!pk(N.rootConnectionName,o,r)\u0026\u0026tD(o,N,t.layerCount))?XL(e,N,o,t,r,i):YL(e,N,m,t,i))||d}const w=x?void 0:WL(h,n);w\u0026\u0026Math.hypot(w.x-n.x,w.y-n.y)\u003c.35\u0026\u0026(d=GL(e,w,m,t)||d)}return d},YD=1e-6,XD=.006,VD=[1,.5,.25,.1,.05,.025],WD=(t,e)=\u003e(e.traceThickness??t.minTraceWidth)/2,HD=t=\u003et.minTraceToPadEdgeClearance??.1,GD=(t,e)=\u003ee.viaDiameter??t.minViaDiameter??.3,UD=(t,e)=\u003exe(t,e)\u003cYD,ZD=t=\u003e{const e=[],n=t=\u003e{e.some(e=\u003eUD(e,t))||e.push({x:t.x,y:t.y})};for(const e of t.vias)n(e);for(let e=0;e\u003ct.route.length-1;e+=1){const o=t.route[e],i=t.route[e+1];o\u0026\u0026i\u0026\u0026o.z!==i.z\u0026\u0026(UD(o,i)\u0026\u0026n(o))}return e},qD=t=\u003exe({x:0,y:0},t)\u003cYD?{x:0,y:0}:Fe({x:0,y:0},t),JD=(t,e)=\u003e{if(t.zLayers\u0026\u0026t.zLayers.length\u003e0)return t.zLayers;const n=Array.from({length:e},(t,e)=\u003ee).filter(n=\u003et.layers.includes(Vy(n,e)));return n.length\u003e0?n:Array.from({length:e},(t,e)=\u003ee)},KD=(t,e,n)=\u003euk(dk(t),dk(e),n)||uk(dk(t),e.connectionName,n)||uk(t.connectionName,dk(e),n)||uk(t.connectionName,e.connectionName,n),QD=(t,e,n)=\u003epk(dk(t),e,n)||pk(t.connectionName,e,n),tz=(t,e,n,o)=\u003e!n.pcb_port_id\u0026\u0026t.obstacles.some(i=\u003eQD(e,i,o)\u0026\u0026JD(i,t.layerCount).includes(n.z)\u0026\u0026((t,e)=\u003et.x\u003e=e.center.x-e.width/2-YD\u0026\u0026t.x\u003c=e.center.x+e.width/2+YD\u0026\u0026t.y\u003e=e.center.y-e.height/2-YD\u0026\u0026t.y\u003c=e.center.y+e.height/2+YD)(n,i)),ez=(t,e,n,o,i)=\u003e{if(!((t,e)=\u003et.zLayers.includes(e))(i,n.z))return Number.POSITIVE_INFINITY;const r=WD(t,e);return\"pad\"===i.kind?Le(n,o,i.obstacle)-(HD(t)+r+XD):be(i.center,n,o)-(HD(t)+r+i.diameter/2+XD)},nz=(t,e,n)=\u003e{const o=\"pad\"===n.kind?n.obstacle.center:n.center,i=ze(o,t,e);let r=qD({x:i.x-o.x,y:i.y-o.y});if(Math.abs(r.x)\u003cYD\u0026\u0026Math.abs(r.y)\u003cYD){const n=e.x-t.x,i=e.y-t.y,s=$e(t,e),a=qD({x:-i,y:n}),c={x:-a.x,y:-a.y};r=xe({x:s.x+a.x,y:s.y+a.y},o)\u003e=xe({x:s.x+c.x,y:s.y+c.y},o)?a:c}return r},oz=(t,e,n,o)=\u003e{if(n\u003c=0||n\u003e=e.route.length-1){const i=e.route[n];return!i||!tz(t,e,i,o)}const i=e.route[n];if(!i||i.insideJumperPad)return!0;const r=e.route[n-1],s=e.route[n+1];return!(!r||r.z===i.z)||(!(!s||s.z===i.z)||e.vias.some(t=\u003eUD(t,i)))},iz=(t,e,n)=\u003e{let o=0;for(let i=0;i\u003ce.route.length-1;i+=1){const r=e.route[i],s=e.route[i+1];if(r\u0026\u0026s\u0026\u0026r.z===s.z\u0026\u0026!UD(r,s))for(const i of n){const n=ez(t,e,r,s,i);if(!(n\u003e=0)\u0026\u0026(o+=n*n,\"pad\"===i.kind)){if(Le(r,s,i.obstacle)\u003cYD){o+=.01/(be(i.obstacle.center,r,s)+.01)}}}}return o},rz=(t,e,n,o)=\u003e{let i=0;for(let r=0;r\u003ce.route.length-1;r+=1){const s=e.route[r],a=e.route[r+1];if(s\u0026\u0026a\u0026\u0026s.z===a.z\u0026\u0026!UD(s,a))for(const r of n)if(!KD(e,r,o)){for(let n=0;n\u003cr.route.length-1;n+=1){const o=r.route[n],c=r.route[n+1];if(!o||!c||o.z!==s.z||c.z!==s.z||UD(o,c))continue;const l=Oe(s,a,o,c)-WD(t,e)-WD(t,r),d=HD(t)+XD-l;d\u003e0\u0026\u0026(i+=d*d)}for(const n of ZD(r)){const o=be(n,s,a)-WD(t,e)-GD(t,r)/2,c=HD(t)+XD-o;c\u003e0\u0026\u0026(i+=c*c)}}}return i},sz=(t,e,n,o,i)=\u003e{const r=e.route.map(()=\u003e({x:0,y:0}));for(let s=0;s\u003ce.route.length-1;s+=1){const a=e.route[s],c=e.route[s+1];if(a\u0026\u0026c\u0026\u0026a.z===c.z\u0026\u0026!UD(a,c)){for(const o of n){const n=ez(t,e,a,c,o);if(n\u003e=0)continue;const l=nz(a,c,o);if(Math.abs(l.x)\u003cYD\u0026\u0026Math.abs(l.y)\u003cYD)continue;const d=!oz(t,e,s,i),h=!oz(t,e,s+1,i);if(!d\u0026\u0026!h)continue;const u=-n,p=d\u0026\u0026h?.5:d?1:0,m=d\u0026\u0026h?.5:h?1:0;r[s].x+=l.x*u*p,r[s].y+=l.y*u*p,r[s+1].x+=l.x*u*m,r[s+1].y+=l.y*u*m}for(const n of o)if(!KD(e,n,i))for(let o=0;o\u003cn.route.length-1;o+=1){const l=n.route[o],d=n.route[o+1];if(!l||!d||l.z!==a.z||d.z!==a.z||UD(l,d))continue;const h=Oe(a,c,l,d)-WD(t,e)-WD(t,n),u=t.minTraceToPadEdgeClearance+XD-h;if(u\u003c=0)continue;const p=$e(a,c),m=ze(p,l,d);let g=qD({x:p.x-m.x,y:p.y-m.y});if(Math.abs(g.x)\u003cYD\u0026\u0026Math.abs(g.y)\u003cYD){const t=c.x-a.x,e=c.y-a.y;g=qD({x:-e,y:t})}const f=!oz(t,e,s,i),y=!oz(t,e,s+1,i);if(!f\u0026\u0026!y)continue;const _=f\u0026\u0026y?.5:f?1:0,b=f\u0026\u0026y?.5:y?1:0;r[s].x+=g.x*u*_,r[s].y+=g.y*u*_,r[s+1].x+=g.x*u*b,r[s+1].y+=g.y*u*b}}}return r},az=(t,e,n,o,i)=\u003e({...e,route:e.route.map((r,s)=\u003e{if(oz(t,e,s,i))return{...r};const a=((t,e)=\u003e{const n=xe({x:0,y:0},t);if(n\u003c=e||n\u003cYD)return t;const o=e/n;return{x:t.x*o,y:t.y*o}})(n[s]??{x:0,y:0},.5);return{...r,x:r.x+a.x*o,y:r.y+a.y*o}}),vias:e.vias.map(t=\u003e({...t})),jumpers:e.jumpers?[...e.jumpers]:void 0}),cz=(t,e)=\u003ee.route.every(e=\u003ee.x\u003e=t.bounds.minX-YD\u0026\u0026e.x\u003c=t.bounds.maxX+YD\u0026\u0026e.y\u003e=t.bounds.minY-YD\u0026\u0026e.y\u003c=t.bounds.maxY+YD),lz=(t,e,n,o,i)=\u003e{const r=((t,e,n,o)=\u003e{const i=[];for(const e of t.obstacles)e.isCopperPour||QD(n,e,o)||i.push({kind:\"pad\",obstacle:e,zLayers:JD(e,t.layerCount)});const r=Array.from({length:t.layerCount},(t,e)=\u003ee);for(const s of e)if(s!==n\u0026\u0026!KD(n,s,o))for(const e of ZD(s))i.push({kind:\"via\",center:{x:e.x,y:e.y},diameter:GD(t,s),zLayers:r,connectionName:s.connectionName,rootConnectionName:s.rootConnectionName});return i})(t,e,n,i),s=e.filter((t,e)=\u003ee!==o\u0026\u0026t!==n);let a=n,c=iz(t,a,r)+rz(t,a,s,i);for(let e=0;e\u003c160\u0026\u0026!(c\u003c=YD);e+=1){const e=sz(t,a,r,s,i);if(e.every(t=\u003exe(t,{x:0,y:0})\u003c1e-9))break;let n=null,o=c;for(const l of VD){const d=az(t,a,e,l,i),h=iz(t,d,r)+rz(t,d,s,i);if(h\u003cc-1e-6\u0026\u0026cz(t,d)){n=d,o=h;break}}if(!n)break;a=n,c=o}return a},dz=1e-6,hz=[1,.5,.25,.1,.05,.025],uz=(t,e)=\u003et.some(t=\u003ee.includes(t)),pz=(t,e,n,o)=\u003e(pk(t.rootConnectionName,n,o)||pk(e.connectionName,n,o))\u0026\u0026oL(t,n)\u003c=dz,mz=(t,e,n,o)=\u003e{const i=[],r=e[n.routeIndex];if(!r)return i;for(const e of t.obstacles){if(e.isCopperPour||pz(n,r,e,o))continue;const s=Qk(e,t.layerCount);uz(n.zLayers,s)\u0026\u0026i.push({obstacle:e})}return i},gz=(t,e,n)=\u003eoL(e,n.obstacle)-(e.radius+t.minViaEdgeToPadEdgeClearance+.006),fz=(t,e,n,o)=\u003eGk(e,t.minViaDiameter).filter(t=\u003et.routeIndex===n).reduce((n,i)=\u003en+((t,e,n,o)=\u003e{let i=0;for(const r of mz(t,e,n,o)){const e=gz(t,n,r);!(e\u003e=0)\u0026\u0026(i+=e*e,oL(n,r.obstacle)\u003cdz)\u0026\u0026(i+=.01/(xe(n,r.obstacle.center)+.01))}return i})(t,e,i,o),0),yz=(t,e,n,o)=\u003e{const i=e[n];if(!i)return[];const r=i.route.map(()=\u003e({x:0,y:0})),s=Gk(e,t.minViaDiameter).filter(t=\u003et.routeIndex===n);for(const n of s)if(n.movable)for(const i of mz(t,e,n,o)){const e=n.radius+t.minViaEdgeToPadEdgeClearance+.006,o=aL(n,i.obstacle,e);if(o)for(const t of n.pointIndexes)r[t].x+=o.direction.x*o.penetration,r[t].y+=o.direction.y*o.penetration}return r},_z=(t,e,n,o)=\u003e{const i=new Set(Gk([e],t.minViaDiameter).flatMap(t=\u003et.movable?t.pointIndexes:[]));return{...e,route:e.route.map((t,e)=\u003e{if(!i.has(e))return{...t};const r=((t,e)=\u003e{const n=xe({x:0,y:0},t);if(n\u003c=e||n\u003cdz)return t;const o=e/n;return{x:t.x*o,y:t.y*o}})(n[e]??{x:0,y:0},.5);return{...t,x:t.x+r.x*o,y:t.y+r.y*o}}),vias:e.vias.map(t=\u003e({...t})),jumpers:e.jumpers?[...e.jumpers]:void 0}},bz=(t,e)=\u003ee.route.every(e=\u003ee.x\u003e=t.bounds.minX-dz\u0026\u0026e.x\u003c=t.bounds.maxX+dz\u0026\u0026e.y\u003e=t.bounds.minY-dz\u0026\u0026e.y\u003c=t.bounds.maxY+dz),xz=(t,e,n,o,i)=\u003e{let r=n,s=fz(t,e,o,i);for(let n=0;n\u003c160\u0026\u0026!(s\u003c=dz);n+=1){const n=yz(t,e,o,i);if(n.every(t=\u003exe(t,{x:0,y:0})\u003c1e-9))break;let a=null,c=s;for(const l of hz){const d=_z(t,r,n,l),h=[...e];h[o]=d;const u=fz(t,h,o,i);if(u\u003cs-1e-6\u0026\u0026bz(t,d)){a=d,c=u;break}}if(!a)break;e[o]=a,r=a,s=c}return r},vz=[.2,.4,.8,1.2].flatMap(t=\u003e[.2,.3,.45,.6].flatMap(e=\u003e[-1,1].map(n=\u003e({halfSpan:t,offset:e,directionSign:n})))),Sz=vz.flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,...t}))),Iz=[1,-1].flatMap(t=\u003e[1,-1].flatMap(e=\u003e[!1,!0].flatMap(n=\u003e[0,1].map(o=\u003e({routeSide:o,normalDirectionSign:t,tangentDirectionSign:e,reverseEndpointOffsets:n}))))),Cz=[0,1].map(t=\u003e({kind:\"displacementChain\",routeSide:t})),Pz=[...Cz,...[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,halfSpan:.4,offset:1.2,directionSign:t}))),...[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"span\",routeSide:e,spanExpansion:3,offset:1.8,directionSign:t}))),...[{dx:-2.4,dy:-.4},{dx:-2.4,dy:.4},{dx:2.4,dy:-.4},{dx:2.4,dy:.4},{dx:-.4,dy:-2.4},{dx:-.4,dy:2.4},{dx:.4,dy:-2.4},{dx:.4,dy:2.4}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:2,...t}))),...[{dx:-.17,dy:0},{dx:.17,dy:0},{dx:0,dy:-.17},{dx:0,dy:.17}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:0,...t}))),...Sz],Mz=[0,1,2],Nz=class extends kt{srj;inputHdRoutes;guardedInputHdRoutes;connMap;effort;drcEvaluator;referenceDrcEvaluator;autoroutingDrcEngine;viaHoleDiameter;configuredMaxIterations;enableBroadFallback;enableLargeBoardBroadFallback;enableTargetedErrorSweep;enablePostSolveClearanceRelaxation;enableSafeTraceLayerMoves;enableViaInPadLayerMoves;enableTraceViaOwnerTargeting;outputHdRoutes;initialDrcIssueCount;initialRepairDrcIssueCount;initialLowCountErrorsHaveMovableTraces=!1;broadForceAccepted=!1;targetedForceAccepted=!1;candidateAttempts=0;viaInPadCandidateAttempts=0;viaInPadCandidatesAccepted=0;padTopologyErrorCursor=0;safeTraceLayerCursorByErrorId=new Map;traceLayerCorridorCursorByErrorId=new Map;tracePairDetourCursorByErrorId=new Map;errorCursor=0;stalledIterations=0;bestDrcIssueCountSeen;bestDrcIssueScoreSeen;lastDrcCountImprovementCheckIteration=0;drcCountPlateauChecks=0;largeBoardBroadFallbackMisses=0;outputSnapshot;legacyCleanCheckpoint;viaPadRepairRolledBack=!1;referenceInputDrcIssueCount;referenceCandidateDrcIssueCount;referenceCandidateRolledBack=!1;referenceInputSnapshot;inputSnapshot;constructor(t){if(super(),this.srj=t.srj,this.inputHdRoutes=t.hdRoutes,this.guardedInputHdRoutes=aD(kk(t.hdRoutes)),this.connMap=t.connMap,this.effort=t.effort??1,this.drcEvaluator=t.drcEvaluator,this.referenceDrcEvaluator=t.referenceDrcEvaluator,this.autoroutingDrcEngine=t.autoroutingDrcEngine??(t.drcEvaluator?void 0:new s_(t.srj,{connMap:t.connMap,traceClearance:t.srj.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:t.srj.minTraceToPadEdgeClearance??rk.viaClearance,includeTraceViaOwnerMetadata:t.enableTraceViaOwnerTargeting??!1})),void 0!==t.viaHoleDiameter\u0026\u0026(!Number.isFinite(t.viaHoleDiameter)||t.viaHoleDiameter\u003c=0))throw new Error(\"viaHoleDiameter must be a positive finite number\");this.viaHoleDiameter=t.viaHoleDiameter,this.configuredMaxIterations=t.maxIterations,this.enableBroadFallback=t.enableBroadFallback??!0,this.enableLargeBoardBroadFallback=t.enableLargeBoardBroadFallback??!0,this.enableTargetedErrorSweep=t.enableTargetedErrorSweep??!1,this.enablePostSolveClearanceRelaxation=t.enablePostSolveClearanceRelaxation??!0,this.enableSafeTraceLayerMoves=t.enableSafeTraceLayerMoves??!1,this.enableViaInPadLayerMoves=t.enableViaInPadLayerMoves??!1,this.enableTraceViaOwnerTargeting=t.enableTraceViaOwnerTargeting??!1,this.outputHdRoutes=t.hdRoutes,this.referenceDrcEvaluator\u0026\u0026(this.referenceInputSnapshot=this.getReferenceDrcSnapshot(this.inputHdRoutes)),this.MAX_ITERATIONS=this.configuredMaxIterations??__(this.effort)}getConstructorParams(){return[{srj:this.srj,hdRoutes:this.inputHdRoutes,connMap:this.connMap,effort:this.effort,drcEvaluator:this.drcEvaluator,referenceDrcEvaluator:this.referenceDrcEvaluator,autoroutingDrcEngine:this.autoroutingDrcEngine,viaHoleDiameter:this.viaHoleDiameter,maxIterations:this.configuredMaxIterations,enableBroadFallback:this.enableBroadFallback,enableLargeBoardBroadFallback:this.enableLargeBoardBroadFallback,enableTargetedErrorSweep:this.enableTargetedErrorSweep,enablePostSolveClearanceRelaxation:this.enablePostSolveClearanceRelaxation,enableSafeTraceLayerMoves:this.enableSafeTraceLayerMoves,enableViaInPadLayerMoves:this.enableViaInPadLayerMoves,enableTraceViaOwnerTargeting:this.enableTraceViaOwnerTargeting}]}updateStats(t){this.stats={initialDrcIssueCount:this.initialDrcIssueCount??t.count,finalDrcIssueCount:t.count,globalDrcForceImproveMaxIterations:this.MAX_ITERATIONS,globalDrcForceImproveBroadForceAccepted:this.broadForceAccepted,globalDrcForceImproveTargetedForceAccepted:this.targetedForceAccepted,globalDrcForceImproveCandidateAttempts:this.candidateAttempts,globalDrcForceImproveViaInPadCandidateAttempts:this.viaInPadCandidateAttempts,globalDrcForceImproveViaInPadCandidatesAccepted:this.viaInPadCandidatesAccepted,globalDrcForceImproveStalledIterations:this.stalledIterations,globalDrcForceImproveBestDrcIssueCountSeen:this.bestDrcIssueCountSeen??t.count,globalDrcForceImproveBestDrcIssueScoreSeen:this.bestDrcIssueScoreSeen??t.issueScore,globalDrcForceImproveDrcCountPlateauChecks:this.drcCountPlateauChecks,globalDrcForceImproveLargeBoardBroadFallbackMisses:this.largeBoardBroadFallbackMisses,globalDrcForceImproveViaPadRepairRolledBack:this.viaPadRepairRolledBack,globalDrcForceImproveReferenceInputDrcIssueCount:this.referenceInputDrcIssueCount,globalDrcForceImproveReferenceCandidateDrcIssueCount:this.referenceCandidateDrcIssueCount,globalDrcForceImproveReferenceCandidateRolledBack:this.referenceCandidateRolledBack}}finishAtLegacyCleanCheckpoint(){const t=this.legacyCleanCheckpoint;return!!t\u0026\u0026(this.outputHdRoutes=t.routes,this.outputSnapshot=t.snapshot,this.viaPadRepairRolledBack=!0,this.updateStats(t.snapshot),this.solved=!0,!0)}increaseMaxIterationsForDrcIssueCount(t){void 0===this.configuredMaxIterations?this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,((t,e)=\u003eMath.max(__(e),Math.ceil(t*d_*Math.max(1,e))))(t,this.effort),((t,e)=\u003et\u003e120\u0026\u0026e\u003e0?192:48)(this.inputHdRoutes.length,t)):this.MAX_ITERATIONS=this.configuredMaxIterations}getSnapshot(t){return(this.initialLowCountErrorsHaveMovableTraces?Hk:Wk)(this.srj,t,this.drcEvaluator,this.connMap,this.autoroutingDrcEngine)}getReferenceDrcSnapshot(t){const e={traces:[],srj:this.srj,routes:t,hdRoutes:t},n=this.referenceDrcEvaluator?.getCachedResult?.(e);if(n){const t=Array.isArray(n)?n:n.errors;return{errors:t,count:t.length}}return Wk(this.srj,t,this.referenceDrcEvaluator,this.connMap,this.autoroutingDrcEngine)}getViaIssueCount(t){return hD(t)}getRepairIssueCount(t){return gD(t)}getRepairIssueScore(t){return fD(t)}acceptSolvedRoutes(t,e){const n=this.enablePostSolveClearanceRelaxation?((t,e,n)=\u003e{if(void 0===t.minTraceToPadEdgeClearance||t.minTraceToPadEdgeClearance\u003c=0)return e;let o=!1;const i=kk(e);for(let e=0;e\u003c4;e+=1)for(let e=0;e\u003ci.length;e+=1){const r=i[e];if(!r)continue;const s=lz(t,i,r,e,n);s!==r\u0026\u0026(i[e]=s,o=!0)}return o?i:e})(this.srj,t,this.connMap):t,o=this.enablePostSolveClearanceRelaxation?((t,e,n)=\u003e{if(void 0===t.minViaEdgeToPadEdgeClearance||t.minViaEdgeToPadEdgeClearance\u003c=0)return e;let o=!1;const i=kk(e);for(let e=0;e\u003c4;e+=1)for(let e=0;e\u003ci.length;e+=1){const r=i[e];if(!r)continue;const s=xz(t,i,r,e,n);s!==r\u0026\u0026(i[e]=s,o=!0)}return o?aD(i):e})(this.srj,n,this.connMap):t,i=o===t?e:this.getSnapshot(o),r=i.count\u003ce.count||i.count===e.count\u0026\u0026i.issueScore\u003c=e.issueScore;let s=r?o:t,a=r?i:e;const c=this.inputSnapshot??this.getSnapshot(this.guardedInputHdRoutes);if(this.referenceDrcEvaluator){const t=this.referenceInputSnapshot,e=this.getReferenceDrcSnapshot(s);this.referenceInputDrcIssueCount=t.count,this.referenceCandidateDrcIssueCount=e.count,e.count\u003et.count\u0026\u0026(s=this.guardedInputHdRoutes,a=c,this.referenceCandidateRolledBack=!0)}this.outputHdRoutes=s,this.outputSnapshot=a,this.stalledIterations=0,this.updateStats(a),this.solved=!0}updateDrcCountPlateauState(t){const e=this.getRepairIssueCount(t),n=this.getRepairIssueScore(t);this.bestDrcIssueCountSeen??=e,this.bestDrcIssueScoreSeen??=n;const o=this.initialRepairDrcIssueCount??e,i=this.inputHdRoutes.length\u003e120\u0026\u0026o\u003e0;if((o\u003e=20||i)\u0026\u0026this.iterations\u003c192)return(e\u003cthis.bestDrcIssueCountSeen||e===this.bestDrcIssueCountSeen\u0026\u0026n\u003cthis.bestDrcIssueScoreSeen)\u0026\u0026(this.bestDrcIssueCountSeen=e,this.bestDrcIssueScoreSeen=n),void(i\u0026\u0026this.largeBoardBroadFallbackMisses\u003e=2\u0026\u0026(this.solved=!0));const r=(t=\u003et\u003e=20?8:t\u003c=2?1:2)(o);if(!(this.iterations-this.lastDrcCountImprovementCheckIteration\u003cr)){if(this.lastDrcCountImprovementCheckIteration=this.iterations,e\u003cthis.bestDrcIssueCountSeen||e===this.bestDrcIssueCountSeen\u0026\u0026n\u003cthis.bestDrcIssueScoreSeen)return this.bestDrcIssueCountSeen=e,this.bestDrcIssueScoreSeen=n,void(this.drcCountPlateauChecks=0);this.drcCountPlateauChecks+=1,this.drcCountPlateauChecks\u003e=2\u0026\u0026(this.solved=!0)}}_step(){let t=this.outputHdRoutes,e=this.outputSnapshot??this.getSnapshot(t);const n=mD(e);if(this.legacyCleanCheckpoint\u0026\u0026n\u003e0)return void this.finishAtLegacyCleanCheckpoint();if(!this.legacyCleanCheckpoint\u0026\u00260===n\u0026\u0026e.errors.some(uD)\u0026\u0026(this.legacyCleanCheckpoint={routes:aD(kk(t)),snapshot:e}),void 0===this.initialDrcIssueCount){this.inputSnapshot=e,this.initialDrcIssueCount=e.count,this.initialRepairDrcIssueCount=this.getRepairIssueCount(e);const n=_D(e.errors);this.initialLowCountErrorsHaveMovableTraces=this.initialRepairDrcIssueCount\u003e0\u0026\u0026this.initialRepairDrcIssueCount\u003c=3\u0026\u0026n.every(t=\u003evoid 0!==bD(t,e.traceRouteIndexById)),this.initialLowCountErrorsHaveMovableTraces\u0026\u0026(e=this.getSnapshot(t)),this.bestDrcIssueCountSeen=this.getRepairIssueCount(e),this.bestDrcIssueScoreSeen=this.getRepairIssueScore(e),this.increaseMaxIterationsForDrcIssueCount(this.getRepairIssueCount(e))}if(0===e.count)return void this.acceptSolvedRoutes(t,e);let o=this.getRepairIssueCount(e),i=this.getRepairIssueScore(e),r=this.getViaIssueCount(e);const s=e.errors.filter(t=\u003eBoolean(dD(t)));if(0===s.length)return void this.acceptSolvedRoutes(t,e);const a=(c=this.effort,Math.max(1,Math.round(3*Math.max(1,c))));var c;let l=0,d=0,h=!1,u=!1,p=!1;const m=_D(s),g=this.enableTargetedErrorSweep?m.find(t=\u003e\"pcb_via_clearance_error\"===t.type\u0026\u0026\"same_net\"===t.pcb_via_pair_net_relation):void 0,f=this.enableTargetedErrorSweep\u0026\u0026(this.iterations-1)%8==0,y=g??(f?m.find(t=\u003e\"pcb_via_clearance_error\"===t.type):void 0),_=y?[y,...m.filter(t=\u003et!==y)]:m,b=Math.min(_.length,Math.max(1,Math.ceil(this.effort))),x=y?0:this.errorCursor%_.length,v=this.enableTargetedErrorSweep?((t,e)=\u003e{const n=Math.max(2,Math.round(12*Math.max(1,e)));return t.filter(t=\u003e\"pcb_trace_error\"===Fk(t)).slice(0,n)})(s,this.effort):[],S=o\u003c=1||this.initialLowCountErrorsHaveMovableTraces,I=!this.initialLowCountErrorsHaveMovableTraces\u0026\u0026o\u003c=8\u0026\u0026this.srj.layerCount\u003e1,C=y?[]:s.filter(t=\u003e\"pcb_pad_trace_clearance_error\"===t.type||(this.enableSafeTraceLayerMoves||S||I)\u0026\u0026\"pcb_trace_error\"===t.type),P=C.map((t,e)=\u003eC[(this.padTopologyErrorCursor+e)%C.length]);for(const n of this.enableSafeTraceLayerMoves||this.enableViaInPadLayerMoves?P:[]){const s=!this.enableSafeTraceLayerMoves||d\u003e=a,c=!this.enableViaInPadLayerMoves||l\u003e=a;if(u||s\u0026\u0026c)break;let p;this.padTopologyErrorCursor=(C.indexOf(n)+1)%C.length;const m=\"string\"==typeof n.pcb_trace_error_id?n.pcb_trace_error_id:\"string\"==typeof n.pcb_trace_id?n.pcb_trace_id:void 0,g=bD(n,e.traceRouteIndexById),f=TD(n,e.traceRouteIndexById);if(this.enableTraceViaOwnerTargeting\u0026\u0026void 0!==g\u0026\u0026Array.isArray(n.pcb_via_ids)\u0026\u00261===n.pcb_via_ids.length\u0026\u0026l\u003ca){const o=kk(t);if(AD(this.srj,o,n,e.traceRouteIndexById,g,this.connMap)){const t=aD(o),n=this.getSnapshot(t),i=this.getViaIssueCount(n);l+=1,this.candidateAttempts+=1,i\u003c=r\u0026\u0026yD(n,e)\u0026\u0026(p={routes:t,snapshot:n,viaIssueCount:i,usesViaInPad:!1})}}if(this.enableSafeTraceLayerMoves\u0026\u0026void 0!==g){const o=f??[g],i=o.length*this.srj.layerCount*Mz.length,s=o.length*this.srj.layerCount*ID,c=i+s,l=Bk(n),h=l?0:i,u=l?s:0;let y=m?this.safeTraceLayerCursorByErrorId.get(m)??0:0,_=0;for(;d\u003ca\u0026\u0026_\u003cc;){const i=y;y=(y+1)%c,_+=1;const a=i\u003e=h\u0026\u0026i\u003ch+s,l=i-(a?h:u),m=l%o.length,g=Math.floor(l/o.length),f=g%this.srj.layerCount,b=a?\"full\":Mz[Math.floor(g/this.srj.layerCount)%Mz.length],x=a?Math.floor(g/this.srj.layerCount):0,v=o[m];let S=!1;for(const o of[!1,!0]){const i=Lk(t,[v]);if(!MD(this.srj,i,n,v,f,b,this.connMap,x,o))continue;const s=cD(i,[v]);S=!0,this.candidateAttempts+=1;const a=this.getSnapshot(s),c=this.getViaIssueCount(a),l=p?.snapshot??e;c\u003c=(p?.viaIssueCount??r)\u0026\u0026(yD(a,l)||void 0!==p\u0026\u0026gD(a)===gD(l)\u0026\u0026a.count\u003cl.count)\u0026\u0026(p={routes:s,snapshot:a,viaIssueCount:c,usesViaInPad:!1})}S\u0026\u0026(d+=1)}m\u0026\u0026this.safeTraceLayerCursorByErrorId.set(m,y)}if(this.enableSafeTraceLayerMoves\u0026\u0026I\u0026\u0026m\u0026\u0026f){let o=this.traceLayerCorridorCursorByErrorId.get(m)??0,i=0;for(;l\u003ca\u0026\u0026i\u003cIz.length;){const s=Iz[o%Iz.length];o+=1,i+=1;const a=f[s.routeSide],c=t[a]?.route[0]?.z;if(void 0===c)continue;const d=(c+1)%this.srj.layerCount,h=Lk(t,[a]);if(!zD(this.srj,h,n,a,d,s.normalDirectionSign,s.tangentDirectionSign,s.reverseEndpointOffsets))continue;const u=cD(h,[a]);l+=1,this.candidateAttempts+=1;const m=this.getSnapshot(u),g=this.getViaIssueCount(m),y=p?.snapshot??e;g\u003c=(p?.viaIssueCount??r)\u0026\u0026yD(m,y)\u0026\u0026(p={routes:u,snapshot:m,viaIssueCount:g,usesViaInPad:!1})}this.traceLayerCorridorCursorByErrorId.set(m,o)}if(this.enableSafeTraceLayerMoves\u0026\u0026m\u0026\u0026(this.initialLowCountErrorsHaveMovableTraces\u0026\u0026(f||void 0!==g)||!this.initialLowCountErrorsHaveMovableTraces\u0026\u0026f)){const s=this.initialLowCountErrorsHaveMovableTraces?Pz:S?[...Cz,...Sz]:Cz,c=f??[g];let d=this.tracePairDetourCursorByErrorId.get(m)??0,u=0;for(;l\u003ca\u0026\u0026u\u003cs.length;){const m=s[d%s.length];d+=1,u+=1;const g=c[m.routeSide];if(void 0===g)continue;const f=this.initialLowCountErrorsHaveMovableTraces\u0026\u0026n.worst_contact_center?{...n,center:n.worst_contact_center,message:n.worst_contact_message??n.message,actual_clearance:n.worst_actual_clearance??n.actual_clearance}:n;if(\"displacementChain\"===m.kind){const n=kk(t),s=RD(this.srj,n,f,e.traceRouteIndexById,m.routeSide);if(!s)continue;h=!0,l+=1,this.candidateAttempts+=1;let c=aD(n),d=this.getSnapshot(c),u=this.getViaIssueCount(d),g=this.getRepairIssueCount(d);if(g\u003e0\u0026\u0026l\u003ca){const t=kk(c);let e=!1;for(const n of d.errors)e=AD(this.srj,t,n,d.traceRouteIndexById,s.movedRouteIndex,this.connMap)||e;if(e){l+=1,this.candidateAttempts+=1;const e=aD(t),n=this.getSnapshot(e),o=this.getViaIssueCount(n);jD(n,o,g,this.getRepairIssueScore(d),u,d)\u0026\u0026(c=e,d=n,u=o,g=this.getRepairIssueCount(d))}}const y=p?this.getRepairIssueCount(p.snapshot):o,_=p?this.getRepairIssueScore(p.snapshot):i,b=p?.viaIssueCount??r;if(u\u003c=b\u0026\u0026jD(d,u,y,_,b,p?.snapshot??e)\u0026\u0026(p={routes:c,snapshot:d,viaIssueCount:u,usesViaInPad:!1}),0===g)break;continue}const y=Lk(t,[g]);if(!(\"segment\"===m.kind?DD(y,f,g,m.halfSpan,m.offset,m.directionSign):\"span\"===m.kind?FD(this.srj,y,f,g,m.spanExpansion,m.offset,m.directionSign):BD(this.srj,y,f,g,m.spanExpansion,{x:f.center.x+m.dx,y:f.center.y+m.dy})))continue;const _=cD(y,[g]);h=!0,l+=1,this.candidateAttempts+=1;const b=this.getSnapshot(_),x=this.getViaIssueCount(b),v=p?this.getRepairIssueCount(p.snapshot):o,S=p?this.getRepairIssueScore(p.snapshot):i,I=p?.viaIssueCount??r;(this.initialLowCountErrorsHaveMovableTraces?jD(b,x,v,S,I,p?.snapshot??e):x\u003c=I\u0026\u0026yD(b,p?.snapshot??e))\u0026\u0026(p={routes:_,snapshot:b,viaIssueCount:x,usesViaInPad:!1})}this.tracePairDetourCursorByErrorId.set(m,d)}for(const s of this.enableViaInPadLayerMoves?[\"start\",\"end\"]:[]){if(l\u003e=a)break;if(void 0===g)break;const c=Lk(t,[g]);if(!wD(this.srj,c,n,e.traceRouteIndexById,s,this.connMap,this.viaHoleDiameter))continue;const d=cD(c,[g]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const h=this.getSnapshot(d),u=this.getViaIssueCount(h),m=p?this.getRepairIssueCount(p.snapshot):o,f=p?this.getRepairIssueScore(p.snapshot):i;jD(h,u,m,f,p?.viaIssueCount??r,p?.snapshot??e)\u0026\u0026(p={routes:d,snapshot:h,viaIssueCount:u,usesViaInPad:!0})}const y=this.enableViaInPadLayerMoves?this.srj.layerCount:0;for(let s=0;s\u003cy\u0026\u0026!(l\u003e=a)\u0026\u0026void 0!==g;s+=1){const a=Lk(t,[g]);if(!ND(this.srj,a,n,e.traceRouteIndexById,s,this.connMap,this.viaHoleDiameter))continue;const c=cD(a,[g]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const d=this.getSnapshot(c),h=this.getViaIssueCount(d),u=p?this.getRepairIssueCount(p.snapshot):o,m=p?this.getRepairIssueScore(p.snapshot):i;jD(d,h,u,m,p?.viaIssueCount??r,p?.snapshot??e)\u0026\u0026(p={routes:c,snapshot:d,viaIssueCount:h,usesViaInPad:!0})}if(this.enableViaInPadLayerMoves\u0026\u0026S\u0026\u0026f){const s=this.iterations%2==0?[0,1]:[1,0],c=this.iterations%3;for(const d of s)for(let s=0;s\u003cthis.srj.layerCount\u0026\u0026!(l\u003e=a);s+=1){const a=f[d],h=Lk(t,[a]);if(!LD(this.srj,h,n,e.traceRouteIndexById,d,s,c,this.connMap,this.viaHoleDiameter))continue;const u=cD(h,[a]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const m=this.getSnapshot(u),g=this.getViaIssueCount(m),y=p?this.getRepairIssueCount(p.snapshot):o,_=p?this.getRepairIssueScore(p.snapshot):i;jD(m,g,y,_,p?.viaIssueCount??r,p?.snapshot??e)\u0026\u0026(p={routes:u,snapshot:m,viaIssueCount:g,usesViaInPad:!0})}}p\u0026\u0026(t=p.routes,e=p.snapshot,o=this.getRepairIssueCount(e),i=this.getRepairIssueScore(e),r=p.viaIssueCount,this.targetedForceAccepted=!0,p.usesViaInPad\u0026\u0026(this.viaInPadCandidatesAccepted+=1),u=!0)}if(!u\u0026\u0026v.length\u003e=2){const n=kk(t);let s=!1;for(const t of v)s=$D(this.srj,n,[t],e.traceRouteIndexById,1,this.connMap,!0,this.enableTargetedErrorSweep,!1,this.enableTraceViaOwnerTargeting)||s;if(s){const s=aD(n);l+=1,this.candidateAttempts+=1;const a=this.getSnapshot(s),c=this.getViaIssueCount(a);if(jD(a,c,o,i,r,e)\u0026\u0026(t=s,e=a,o=this.getRepairIssueCount(a),i=this.getRepairIssueScore(a),r=c,this.targetedForceAccepted=!0,u=!0,0===a.count))return void this.acceptSolvedRoutes(t,e)}}for(let n=0;n\u003cb\u0026\u0026l\u003ca\u0026\u0026!u;n+=1){const s=(x+n)%_.length,c=_[s];if(!c)continue;this.errorCursor=(s+1)%_.length;const d=1===o;for(const n of b_(this.effort)){if(l\u003e=a)break;const s=kk(t);if(!$D(this.srj,s,[c],e.traceRouteIndexById,n,this.connMap,!0,this.enableTargetedErrorSweep,d,this.enableTraceViaOwnerTargeting))continue;const h=aD(s);l+=1,this.candidateAttempts+=1;const p=this.getSnapshot(h),m=this.getViaIssueCount(p);if(jD(p,m,o,i,r,e)){if(t=h,e=p,o=this.getRepairIssueCount(p),i=this.getRepairIssueScore(p),r=m,this.targetedForceAccepted=!0,u=!0,0===p.count)return void this.acceptSolvedRoutes(t,e);break}}if(u)break}const M=t.length\u003c=120,N=(w=s.length,Math.max(16,Math.min(64,2*w)));var w;const T=this.enableLargeBoardBroadFallback\u0026\u0026this.MAX_ITERATIONS\u003e=192\u0026\u0026!M\u0026\u0026this.stalledIterations\u003e0\u0026\u0026this.stalledIterations%N===0;if(this.enableBroadFallback\u0026\u0026!u\u0026\u0026(M||this.effort\u003e=2\u0026\u0026this.stalledIterations\u003e=2||T)){p=T;for(const n of[1,2]){const s=iD(this.srj,t,this.effort,n,this.connMap,void 0===this.drcEvaluator,!1);if(s===t)continue;const a=this.getSnapshot(s),c=this.getViaIssueCount(a);if(jD(a,c,o,i,r,e)\u0026\u0026(t=s,e=a,o=this.getRepairIssueCount(a),i=this.getRepairIssueScore(a),r=c,this.broadForceAccepted=!0,u=!0,0===a.count))return void this.acceptSolvedRoutes(t,e)}}u?this.largeBoardBroadFallbackMisses=0:p\u0026\u0026(this.largeBoardBroadFallbackMisses+=1),this.outputHdRoutes=t,this.outputSnapshot=e,this.stalledIterations=u?0:this.stalledIterations+1,h||this.updateDrcCountPlateauState(e),this.updateStats(e),(this.solved||0===o)\u0026\u0026this.acceptSolvedRoutes(t,e)}tryFinalAcceptance(){const t=this.outputSnapshot??this.getSnapshot(this.outputHdRoutes);this.legacyCleanCheckpoint\u0026\u0026mD(t)\u003e0\u0026\u0026this.finishAtLegacyCleanCheckpoint()||this.acceptSolvedRoutes(this.outputHdRoutes,t)}getOutput(){return this.outputHdRoutes}visualize(){return super.visualize()}preview(){return this.visualize()}},wz=class extends kt{params;inputHdRoutes;guardedInputHdRoutes;broadMaxIterations;broadPassMultiplier;autoroutingDrcEngine;legacyDrcEvaluator;outputHdRoutes;phase=\"start\";inputSnapshot;baselineSolver;baselineSnapshot;broadInputSnapshot;broadSnapshot;broadSolver;safeTraceLayerInputRoutes;safeTraceLayerInputSnapshot;safeTraceLayerSolver;safeTraceLayerPhaseAccepted=!1;mixedSafeTraceLayerSolver;mixedSafeTraceLayerPhaseAccepted=!1;legacySafeTraceLayerRoutes;legacySafeTraceLayerSnapshot;legacySafeTraceLayerSelectedSolver;viaInPadSolver;portfolioSelectedSolver;selectedSolver;referenceInputDrcIssueCount;referenceCandidateDrcIssueCount;referenceCandidateRolledBack=!1;mixedReferenceInputDrcIssueCount;mixedReferenceCandidateDrcIssueCount;referenceInputSnapshot;constructor(t){if(super(),!Number.isFinite(t.broadPassMultiplier))throw new Error(\"broadPassMultiplier must be a finite number\");if(t.broadPassMultiplier\u003c=0)throw new Error(\"broadPassMultiplier must be greater than zero\");if(!Number.isInteger(t.broadMaxIterations))throw new Error(\"broadMaxIterations must be an integer\");if(t.broadMaxIterations\u003c=0)throw new Error(\"broadMaxIterations must be greater than zero\");if(void 0!==t.viaInPadMaxIterations\u0026\u0026!Number.isInteger(t.viaInPadMaxIterations))throw new Error(\"viaInPadMaxIterations must be an integer\");if(void 0!==t.viaInPadMaxIterations\u0026\u0026t.viaInPadMaxIterations\u003c=0)throw new Error(\"viaInPadMaxIterations must be greater than zero\");this.autoroutingDrcEngine=t.autoroutingDrcEngine??(t.drcEvaluator?void 0:new s_(t.srj,{connMap:t.connMap,traceClearance:t.srj.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:t.srj.minTraceToPadEdgeClearance??rk.viaClearance,includeTraceViaOwnerMetadata:t.enableTraceViaOwnerTargeting??!1})),this.legacyDrcEvaluator=e=\u003e{const n=t.drcEvaluator?.evaluateLegacy??t.drcEvaluator,o=n?n(e):this.autoroutingDrcEngine.evaluateLegacy(e.traces),i=Array.isArray(o)?o:o.errors,r=Array.isArray(o)?o:o.errorsWithCenters??o.errors;return{errors:i.filter(t=\u003e!uD(t)),errorsWithCenters:r.filter(t=\u003e!uD(t))}},this.params={...t,autoroutingDrcEngine:this.autoroutingDrcEngine},this.inputHdRoutes=t.hdRoutes,this.guardedInputHdRoutes=aD(kk(t.hdRoutes)),this.broadMaxIterations=t.broadMaxIterations,this.broadPassMultiplier=t.broadPassMultiplier,this.outputHdRoutes=t.hdRoutes,this.params.referenceDrcEvaluator\u0026\u0026(this.referenceInputSnapshot=this.getReferenceDrcSnapshot(this.inputHdRoutes))}getConstructorParams(){return[{...this.params,hdRoutes:this.inputHdRoutes}]}stepBranch(t,e){if(this.activeSubSolver=t,t.step(),t.failed)throw new Error(`${e} DRC repair branch failed: ${t.error}`)}getReferenceDrcSnapshot(t){const e={traces:[],srj:this.params.srj,routes:t,hdRoutes:t},n=this.params.referenceDrcEvaluator?.getCachedResult?.(e);if(n){const t=Array.isArray(n)?n:n.errors;return{errors:t,count:t.length}}return Wk(this.params.srj,t,this.params.referenceDrcEvaluator,this.params.connMap,this.autoroutingDrcEngine)}finishWithOutput(t,e,n){let o=t,i=e;if(this.params.referenceDrcEvaluator){const t=this.referenceInputSnapshot,e=this.getReferenceDrcSnapshot(o);this.referenceInputDrcIssueCount=t.count,this.referenceCandidateDrcIssueCount=e.count,(e.count\u003et.count||e.count===t.count\u0026\u0026((t,e)=\u003e{const n=new Set(e.map(pD));return t.some(t=\u003e!n.has(pD(t)))})(e.errors,t.errors))\u0026\u0026(o=this.guardedInputHdRoutes,i=this.inputSnapshot,this.referenceCandidateRolledBack=!0)}this.outputHdRoutes=o,this.selectedSolver=n,this.activeSubSolver=null,this.phase=\"done\",this.progress=1,this.stats={...this.portfolioSelectedSolver?.stats??{},...n?.stats??{},finalDrcIssueCount:i.count,drcBranchPortfolioInitialDrcIssueCount:this.inputSnapshot?.count??e.count,drcBranchPortfolioBaselineDrcIssueCount:this.baselineSnapshot?.count??e.count,drcBranchPortfolioBroadInitialDrcIssueCount:this.broadInputSnapshot?.count,drcBranchPortfolioBroadFinalDrcIssueCount:this.broadSnapshot?.count,drcBranchPortfolioBroadMaxIterations:this.broadMaxIterations,drcBranchPortfolioBroadBranchAttempted:Boolean(this.broadSolver),drcBranchPortfolioBroadBranchAccepted:void 0!==this.portfolioSelectedSolver\u0026\u0026this.portfolioSelectedSolver===this.broadSolver,drcBranchPortfolioSafeTraceLayerPhaseAttempted:Boolean(this.safeTraceLayerSolver),drcBranchPortfolioSafeTraceLayerPhaseAccepted:this.safeTraceLayerPhaseAccepted,drcBranchPortfolioMixedSafeTraceLayerPhaseAttempted:Boolean(this.mixedSafeTraceLayerSolver),drcBranchPortfolioMixedSafeTraceLayerPhaseAccepted:this.mixedSafeTraceLayerPhaseAccepted,drcBranchPortfolioViaInPadPhaseAttempted:Boolean(this.viaInPadSolver),drcBranchPortfolioViaInPadMaxIterations:this.params.viaInPadMaxIterations,drcBranchPortfolioFinalNonViaPadDrcIssueCount:mD(i),drcBranchPortfolioReferenceInputDrcIssueCount:this.referenceInputDrcIssueCount,drcBranchPortfolioReferenceCandidateDrcIssueCount:this.referenceCandidateDrcIssueCount,drcBranchPortfolioReferenceCandidateRolledBack:this.referenceCandidateRolledBack,drcBranchPortfolioMixedReferenceInputDrcIssueCount:this.mixedReferenceInputDrcIssueCount,drcBranchPortfolioMixedReferenceCandidateDrcIssueCount:this.mixedReferenceCandidateDrcIssueCount},this.solved=!0}startBaselineBranch(){this.baselineSolver=new Nz({...this.params,hdRoutes:this.inputHdRoutes,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.baselineSolver,this.phase=\"baseline\"}startSafeTraceLayerPhase(t,e,n){this.portfolioSelectedSolver=n,this.params.enableSafeTraceLayerMoves?(this.safeTraceLayerInputRoutes=t,this.safeTraceLayerInputSnapshot=e,this.safeTraceLayerSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.safeTraceLayerSolver,this.phase=\"safeTraceLayer\"):this.startViaInPadPhase(t,e,n)}startViaInPadPhase(t,e,n){this.portfolioSelectedSolver=n;const o=this.params.enableViaInPadLayerMoves\u0026\u0026void 0!==this.params.viaInPadDrcEvaluator;e.errors.some(uD)||o?(this.viaInPadSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.params.viaInPadDrcEvaluator??this.params.drcEvaluator,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:this.params.enableViaInPadLayerMoves}),this.activeSubSolver=this.viaInPadSolver,this.phase=\"viaInPad\"):this.finishWithOutput(t,e,n)}startMixedSafeTraceLayerPhase(t,e,n){this.legacySafeTraceLayerRoutes=t,this.legacySafeTraceLayerSnapshot=e,this.legacySafeTraceLayerSelectedSolver=n,this.mixedSafeTraceLayerSolver=new Nz({...this.params,hdRoutes:this.safeTraceLayerInputRoutes,drcEvaluator:this.params.drcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.mixedSafeTraceLayerSolver,this.phase=\"mixedSafeTraceLayer\"}startBroadBranch(){const t=iD(this.params.srj,this.inputHdRoutes,this.params.effort??1,this.broadPassMultiplier,this.params.connMap);this.broadInputSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),yD(this.broadInputSnapshot,this.baselineSnapshot)?(this.broadSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.broadMaxIterations,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.broadSolver,this.phase=\"broad\"):this.startSafeTraceLayerPhase(this.baselineSolver.getOutput(),this.baselineSnapshot,this.baselineSolver)}_step(){if(\"start\"===this.phase)return this.inputSnapshot=Wk(this.params.srj,this.inputHdRoutes,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),0===mD(this.inputSnapshot)?void this.startViaInPadPhase(this.inputHdRoutes,this.inputSnapshot):void this.startBaselineBranch();if(\"baseline\"===this.phase){if(this.stepBranch(this.baselineSolver,\"baseline\"),!this.baselineSolver.solved)return;const t=this.baselineSolver.getOutput();return this.baselineSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),0===mD(this.baselineSnapshot)?void this.startViaInPadPhase(t,this.baselineSnapshot,this.baselineSolver):void(this.params.enableSafeTraceLayerMoves\u0026\u0026this.baselineSnapshot.count\u003c=3?this.startSafeTraceLayerPhase(t,this.baselineSnapshot,this.baselineSolver):this.startBroadBranch())}if(\"broad\"===this.phase){if(this.stepBranch(this.broadSolver,\"broad\"),!this.broadSolver.solved)return;const t=this.broadSolver.getOutput();return this.broadSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),yD(this.broadSnapshot,this.baselineSnapshot)?void this.startSafeTraceLayerPhase(t,this.broadSnapshot,this.broadSolver):void this.startSafeTraceLayerPhase(this.baselineSolver.getOutput(),this.baselineSnapshot,this.baselineSolver)}if(\"safeTraceLayer\"===this.phase){if(this.stepBranch(this.safeTraceLayerSolver,\"safe trace-layer\"),!this.safeTraceLayerSolver.solved)return;const t=this.safeTraceLayerSolver.getOutput(),e=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),n=hD(this.safeTraceLayerInputSnapshot,!1),o=hD(e,!1);this.safeTraceLayerPhaseAccepted=o\u003c=n\u0026\u0026jD(e,o,this.safeTraceLayerInputSnapshot.count,this.safeTraceLayerInputSnapshot.issueScore,n,this.safeTraceLayerInputSnapshot);const i=this.safeTraceLayerPhaseAccepted?t:this.safeTraceLayerInputRoutes,r=this.safeTraceLayerPhaseAccepted?e:this.safeTraceLayerInputSnapshot,s=this.safeTraceLayerPhaseAccepted?this.safeTraceLayerSolver:this.portfolioSelectedSolver;return r.count\u003e0\u0026\u0026!this.broadInputSnapshot?void this.startBroadBranch():mD(r)\u003e0\u0026\u0026this.safeTraceLayerInputSnapshot.errors.some(uD)?void this.startMixedSafeTraceLayerPhase(i,r,s):void this.startViaInPadPhase(i,r,s)}if(\"mixedSafeTraceLayer\"===this.phase){if(this.stepBranch(this.mixedSafeTraceLayerSolver,\"mixed safe trace-layer\"),!this.mixedSafeTraceLayerSolver.solved)return;const t=this.mixedSafeTraceLayerSolver.getOutput(),e=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),n=mD(e)\u003c=mD(this.legacySafeTraceLayerSnapshot);let o=!0;if(this.params.referenceDrcEvaluator){const e=this.getReferenceDrcSnapshot(this.legacySafeTraceLayerRoutes),n=this.getReferenceDrcSnapshot(t);this.mixedReferenceInputDrcIssueCount=e.count,this.mixedReferenceCandidateDrcIssueCount=n.count,o=n.count\u003c=e.count}return this.mixedSafeTraceLayerPhaseAccepted=n\u0026\u0026o,void this.startViaInPadPhase(this.mixedSafeTraceLayerPhaseAccepted?t:this.legacySafeTraceLayerRoutes,this.mixedSafeTraceLayerPhaseAccepted?e:this.legacySafeTraceLayerSnapshot,this.mixedSafeTraceLayerPhaseAccepted?this.mixedSafeTraceLayerSolver:this.legacySafeTraceLayerSelectedSolver)}if(\"viaInPad\"===this.phase){if(this.stepBranch(this.viaInPadSolver,\"via-in-pad\"),!this.viaInPadSolver.solved)return;const t=this.viaInPadSolver.getOutput(),e=Wk(this.params.srj,t,this.params.viaInPadDrcEvaluator??this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine);this.finishWithOutput(t,e,this.viaInPadSolver)}}getOutput(){return this.outputHdRoutes}visualize(){const t=this.activeSubSolver??this.selectedSolver;return t?.visualize()??super.visualize()}preview(){const t=this.activeSubSolver??this.selectedSolver;return t?.preview()??this.visualize()}},Tz=class extends si{constructor(t,e,n=Number.POSITIVE_INFINITY,o=.010000000000000002){super(),this.nodes=t,this.maxNodeDimension=e,this.maxNodeRatio=n,this.minNodeArea=o,this.outputNodes=[]}nodes;maxNodeDimension;maxNodeRatio;minNodeArea;outputNodes;getSolverName(){return\"NodeDimensionSubdivisionSolver\"}getSubdivisionGrid(t){const e=Number.isFinite(this.maxNodeDimension)\u0026\u0026this.maxNodeDimension\u003e0,n=Number.isFinite(this.maxNodeRatio)\u0026\u0026this.maxNodeRatio\u003e0;let o=e?Math.max(1,Math.ceil(t.width/this.maxNodeDimension)):1,i=e?Math.max(1,Math.ceil(t.height/this.maxNodeDimension)):1;if(n\u0026\u0026t.width\u003e0\u0026\u0026t.height\u003e0)for(;;){const e=t.width/o,n=t.height/i;if((e\u003e=n?e/n:n/e)\u003c=this.maxNodeRatio)break;e\u003e=n?o++:i++}return{cols:o,rows:i}}shouldRemoveNode(t){const e=Number.isFinite(this.minNodeArea)\u0026\u0026this.minNodeArea\u003e0;if(!Number.isFinite(t.width)||!Number.isFinite(t.height))return!0;if(!e||t.width*t.height\u003e=this.minNodeArea)return!1;if(Math.min(t.width,t.height)\u003c.002)return!0;if(t._containsTarget)return!1;let n=0;for(const e of this.nodes)if(e.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026t.availableZ.some(t=\u003ee.availableZ.includes(t))\u0026\u0026li(t,e)){if(e._containsTarget)return!1;if(n++,n\u003e=2)return!1}return!0}subdivideNode(t){if(this.shouldRemoveNode(t))return[];const{cols:e,rows:n}=this.getSubdivisionGrid(t);if(1===e\u0026\u00261===n)return[t];const o=t.width/e,i=t.height/n,r=t.center.x-t.width/2,s=t.center.y-t.height/2,a=[];for(let c=0;c\u003cn;c++)for(let n=0;n\u003ce;n++)a.push({...t,capacityMeshNodeId:`${t.capacityMeshNodeId}__sub_${c}_${n}`,center:{x:r+o*(n+.5),y:s+i*(c+.5)},width:o,height:i,availableZ:[...t.availableZ]});return a}_step(){const t=this.nodes.length;let e=0,n=0,o=0;for(const t of this.nodes){const i=!Number.isFinite(t.width)||!Number.isFinite(t.height),r=this.subdivideNode(t);0!==r.length?(r.length\u003e1\u0026\u0026e++,this.outputNodes.push(...r)):i?o++:n++}this.stats={inputNodeCount:t,outputNodeCount:this.outputNodes.length,subdividedNodeCount:e,removedSmallNodeCount:n,removedInvalidNodeCount:o,maxNodeDimension:this.maxNodeDimension,maxNodeRatio:this.maxNodeRatio,minNodeArea:this.minNodeArea},this.solved=!0}visualize(){return{rects:this.outputNodes.map(t=\u003e({center:t.center,width:t.width,height:t.height,label:`${t.capacityMeshNodeId}\\n${t.width.toFixed(2)}x${t.height.toFixed(2)}`,layer:`z${t.availableZ.join(\",\")}`,fill:\"rgba(0, 200, 255, 0.08)\",stroke:\"rgba(0, 120, 180, 0.5)\"}))}}},Rz=t=\u003e{const e=[...new Set(t.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0))].sort((t,e)=\u003et-e);if(0!==e.length)return`z${e.join(\",\")}`},Ez=t=\u003e{const e=[];for(let n=0;n\u003c31;n++)t\u00261\u003c\u003cn\u0026\u0026e.push(n);return e},Az=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,Oz=t=\u003eAz(t)?{...t}:void 0===t?{}:{value:t},kz=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];if(Az(n)){if(\"string\"==typeof n.serializedRegionId)return n.serializedRegionId;if(\"string\"==typeof n.regionId)return n.regionId;if(\"string\"==typeof n.capacityMeshNodeId)return n.capacityMeshNodeId}return`region-${e}`},Lz=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];if(Az(n)){if(\"string\"==typeof n.serializedPortId)return n.serializedPortId;if(\"string\"==typeof n.portId)return(o=n.portId).includes(\"::\")?o.slice(0,o.indexOf(\"::\")):o}var o;return`port-${e}`},Dz=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return Az(n)\u0026\u0026\"string\"==typeof n.connectionId?n.connectionId:`route-${e}`},zz=(t,e)=\u003e{const n=Oz(t.topology.regionMetadata?.[e]);if(Az(n.center)||(n.center={x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),\"number\"!=typeof n.width\u0026\u0026(n.width=t.topology.regionWidth[e]),\"number\"!=typeof n.height\u0026\u0026(n.height=t.topology.regionHeight[e]),!Array.isArray(n.availableZ)){const o=t.topology.regionAvailableZMask?.[e]??0;0!==o\u0026\u0026(n.availableZ=Ez(o))}return n.layer=Rz(Array.isArray(n.availableZ)?n.availableZ:[])??Rz((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))??\"z0\",n},Fz=(t,e)=\u003e{const n=Oz(t.topology.portMetadata?.[e]);return\"number\"!=typeof n.x\u0026\u0026(n.x=t.topology.portX[e]),\"number\"!=typeof n.y\u0026\u0026(n.y=t.topology.portY[e]),\"number\"!=typeof n.z\u0026\u0026(n.z=t.topology.portZ[e]),n.layer=Rz([t.topology.portZ[e]])??\"z0\",n},Bz=(t,e,n)=\u003e{const o=(t.topology.incidentPortRegion[e]??[]).find(t=\u003et!==n);if(void 0===o)throw new Error(`Port ${e} is not incident to a region outside route region ${n}`);return o},jz=(t,e,n)=\u003e{const{orderedPortIds:o,orderedRegionIds:i}=((t,e,n)=\u003e{if(0===n.length)throw new Error(`Route ${e} has no solved segments`);const o=t.problem.routeStartPort[e],i=t.problem.routeEndPort[e],r=new Map;n.forEach((t,e)=\u003e{const n={...t,segmentIndex:e},o=r.get(t.fromPortId)??[];o.push(n),r.set(t.fromPortId,o);const i=r.get(t.toPortId)??[];i.push(n),r.set(t.toPortId,i)});const s=[o],a=[],c=(t,e,n)=\u003e{if(t===i)return!0;for(const o of r.get(t)??[]){if(e.has(o.segmentIndex))continue;const i=o.fromPortId===t?o.toPortId:o.fromPortId;if(!n.has(i)){if(e.add(o.segmentIndex),n.add(i),a.push(o.regionId),s.push(i),c(i,e,n))return!0;s.pop(),a.pop(),n.delete(i),e.delete(o.segmentIndex)}}return!1};if(!c(o,new Set,new Set([o])))throw new Error(`Route ${e} is not a single ordered path from ${o} to ${i}`);return{orderedPortIds:s,orderedRegionIds:a}})(t,e,n),r=i[0],s=i[i.length-1];if(void 0===r||void 0===s)throw new Error(`Route ${e} could not determine endpoint regions`);const a=kz(t,Bz(t,o[0],r)),c=kz(t,Bz(t,o[o.length-1],s)),l=((t,e,n,o)=\u003e{const i=t.problem.routeMetadata?.[e];return{connectionId:Dz(t,e),startRegionId:(Az(i)\u0026\u0026\"string\"==typeof i.startRegionId?i.startRegionId:void 0)??n,endRegionId:(Az(i)\u0026\u0026\"string\"==typeof i.endRegionId?i.endRegionId:void 0)??o,mutuallyConnectedNetworkId:(Az(i)\u0026\u0026\"string\"==typeof i.mutuallyConnectedNetworkId?i.mutuallyConnectedNetworkId:void 0)??`net-${t.problem.routeNet[e]}`}})(t,e,a,c),d=o.map((e,n)=\u003e{const r={portId:Lz(t,e),g:n,h:0,f:n,hops:n,ripRequired:!1,nextRegionId:n\u003ci.length?kz(t,i[n]):l.endRegionId};return n\u003e0\u0026\u0026(r.lastPortId=Lz(t,o[n-1]),r.lastRegionId=kz(t,i[n-1])),r});return{connection:l,solvedRoute:{connection:l,path:d,requiredRip:!1}}},$z=t=\u003e{if(!t.solved||t.failed)throw new Error(\"convertToSerializedHyperGraph requires a solved, non-failed solver\");const{topology:e}=t,n=(t=\u003e{const e=Array.from({length:t.problem.routeCount},()=\u003e[]);return t.state.regionSegments.forEach((t,n)=\u003e{for(const[o,i,r]of t)e[o].push({regionId:n,fromPortId:i,toPortId:r})}),e})(t),o=Array.from({length:e.regionCount},(n,o)=\u003e{const i=t.state.regionSegments[o].map(([e,n,o])=\u003e({regionPort1Id:Lz(t,n),regionPort2Id:Lz(t,o),connectionId:Dz(t,e)}));return{regionId:kz(t,o),pointIds:e.regionIncidentPorts[o].map(e=\u003eLz(t,e)),d:zz(t,o),...i.length\u003e0\u0026\u0026{assignments:i}}}),i=Array.from({length:e.portCount},(n,o)=\u003e{const[i,r]=e.incidentPortRegion[o]??[];if(void 0===i||void 0===r)throw new Error(`Port ${o} is missing incident regions`);return{portId:Lz(t,o),region1Id:kz(t,i),region2Id:kz(t,r),d:Fz(t,o)}}),r=n.map((e,n)=\u003ejz(t,n,e));return{regions:o,ports:i,connections:r.map(({connection:t})=\u003et),solvedRoutes:r.map(({solvedRoute:t})=\u003et)}},Yz=.3,Xz=t=\u003et\u003e0\u0026\u0026!(t\u0026t-1),Vz=(t,e,n,o,i,r=0,s=.3,a=0)=\u003e(2*e+1*n+1*o)*(s+.15)**2*(1+i/5)/t+(Xz(r)?10*e:0)+a*(i/Wz(r))**2*.1**2/t,Wz=t=\u003e{if(0===t)return 2;let e=t\u003e\u003e\u003e0,n=0;for(;0!==e;)n+=1\u0026e,e\u003e\u003e\u003e=1;return n},Hz=(t,e,n,o,i,r)=\u003e{const{netIds:s,lesserAngles:a,greaterAngles:c,layerMasks:l}=t;let d=0,h=0;for(let t=0;t\u003cs.length;t++){if(e===s[t])continue;(n\u003ca[t]\u0026\u0026a[t]\u003co)!==(n\u003cc[t]\u0026\u0026c[t]\u003co)\u0026\u0026(0!==(i\u0026l[t])?d++:h++)}return[d,h,r]},Gz=(t,e,n)=\u003e{const o=t.routeStartPort[e],i=t.routeEndPort[e],r=new Map;for(const{fromPortId:t,toPortId:e}of n){const n=r.get(t)??new Set;n.add(e),r.set(t,n);const o=r.get(e)??new Set;o.add(t),r.set(e,o)}const s=new Set,a=[o];for(;a.length\u003e0;){const t=a.pop();if(!s.has(t)){s.add(t);for(const e of r.get(t)??[])a.push(e)}}if(!s.has(i))throw new Error(`Initial assignments for route ${e} do not connect ${o} to ${i}`);if(n.some(({fromPortId:t,toPortId:e})=\u003e!s.has(t)||!s.has(e)))throw new Error(`Initial assignments for route ${e} contain disconnected segments`)},Uz=({topology:t,problem:e,state:n,routeSuccessCountByRouteId:o,appendSegmentToRegionCache:i})=\u003e{const r=e.initialAssignments??[];if(0===r.length)return;const s=new Map;for(const n of r){const{routeId:o,regionId:i,fromPortId:r,toPortId:a}=n;if(!Number.isInteger(o)||o\u003c0||o\u003e=e.routeCount)throw new Error(`Initial assignment references invalid route ${o}`);if(!Number.isInteger(i)||i\u003c0||i\u003e=t.regionCount)throw new Error(`Initial assignment references invalid region ${i}`);for(const e of[r,a]){if(!Number.isInteger(e)||e\u003c0||e\u003e=t.portCount)throw new Error(`Initial assignment references invalid port ${e}`);if(!t.incidentPortRegion[e]?.includes(i))throw new Error(`Initial assignment port ${e} is not incident to region ${i}`)}const c=s.get(o)??[];c.push(n),s.set(o,c)}for(const[t,n]of s)Gz(e,t,n);const a=new Set(s.keys());for(const{routeId:t,regionId:o,fromPortId:s,toPortId:a}of r){const r=e.routeNet[t];for(const t of[s,a]){const e=n.portAssignment[t];if(-1!==e\u0026\u0026e!==r)throw new Error(`Initial assignment port ${t} is assigned to multiple nets`);n.portAssignment[t]=r}n.currentRouteNetId=r,n.regionSegments[o].push([t,s,a]),i(o,s,a)}n.currentRouteNetId=void 0,n.unroutedRoutes=n.unroutedRoutes.filter(t=\u003e!a.has(t));for(const t of a)o[t]=1;return{initialAssignmentCount:r.length,initiallyRoutedRouteCount:a.size}},Zz=class{constructor(t,e){this.items=t,this.compare=e}items;compare;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0}queue(t){this.items.push(t),this.siftUp(this.items.length-1)}dequeue(){const t=this.items[0];if(void 0===t)return;const e=this.items.pop();return this.items.length\u003e0\u0026\u0026(this.items[0]=e,this.siftDown(0)),t}siftUp(t){let e=t;for(;e\u003e0;){const t=e-1\u003e\u003e1,n=this.items[t],o=this.items[e];if(this.compare(n,o)\u003c=0)return;this.items[t]=o,this.items[e]=n,e=t}}siftDown(t){let e=t;const n=this.items.length;for(;;){const t=2*e+1;if(t\u003e=n)return;const o=t+1;let i=t;o\u003cn\u0026\u0026this.compare(this.items[o],this.items[t])\u003c0\u0026\u0026(i=o);const r=this.items[e],s=this.items[i];if(this.compare(r,s)\u003c=0)return;this.items[e]=s,this.items[i]=r,e=i}}},qz=(t,e)=\u003e{const n=[...t],o=(t=\u003e{let e=t\u003e\u003e\u003e0;return()=\u003e{e+=1831565813;let t=e;return t=Math.imul(t^t\u003e\u003e\u003e15,1|t),t^=t+Math.imul(t^t\u003e\u003e\u003e7,61|t),((t^t\u003e\u003e\u003e14)\u003e\u003e\u003e0)/4294967296}})(e);for(let t=n.length-1;t\u003e0;t--){const e=Math.floor(o()*(t+1));[n[t],n[e]]=[n[e],n[t]]}return n},Jz=(t,e)=\u003et.routeMetadata?.[e],Kz=t=\u003et?.simpleRouteConnection?.pointsToConnect?.map(({pointId:t})=\u003e\"string\"==typeof t?t:null).filter(t=\u003enull!==t)??[],Qz=(t,e)=\u003e{const n=Jz(t,e)?.connectionId;return\"string\"==typeof n?n:`route-${e}`},tF=(t,e,n)=\u003e{const o=t.portEndpointNetIds[n];if(!o)return!1;for(const t of o)if(t!==e)return!0;return!1},eF=(t,e,n)=\u003e{const o=t.regionNetId[n];return-1!==o\u0026\u0026o!==e},nF=t=\u003e[...new Set(t.routeIds)].filter(e=\u003e!((t,e)=\u003e{const{topology:n,problem:o,problemSetup:i,portAssignment:r,maxPrecheckHops:s}=t,a=o.routeNet[e],c=o.routeStartPort[e],l=o.routeEndPort[e];if(c===l)return!0;const d=t.getStartingNextRegionId(e,c);if(void 0===d)return!1;const h=[{portId:c,nextRegionId:d}],u=new Set([c*n.regionCount+d]);for(let t=0;t\u003ch.length;t++){const e=h[t];if(!eF(o,a,e.nextRegionId))for(const t of n.regionIncidentPorts[e.nextRegionId]??[]){const c=r[t];if(tF(i,a,t))continue;if(t===l){if(-1!==c\u0026\u0026c!==a)continue;return!0}if(t===e.portId)continue;if(-1!==c\u0026\u0026c!==a)continue;if(0===o.portSectionMask[t])continue;const d=n.incidentPortRegion[t]??[],p=d[0]===e.nextRegionId?d[1]:d[0];if(void 0===p||eF(o,a,p))continue;const m=t*n.regionCount+p;if(!u.has(m)){if(u.size\u003e=s)return!0;u.add(m),h.push({portId:t,nextRegionId:p})}}}return!1})(t,e)).map(e=\u003et.getRouteSummary(e)),oF=t=\u003e{const e=new Array(t);for(let n=0;n\u003ct;n++)e[n]=n;return e},iF=\"rgba(220, 38, 38, 0.98)\",rF=\"rgba(220, 38, 38, 0.18)\",sF=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),aF=(t,e)=\u003e{const n=.005*t.topology.portZ[e];return{x:t.topology.portX[e]+n,y:t.topology.portY[e]+n}},cF=(t,e)=\u003eRz([t.topology.portZ[e]])??\"z0\",lF=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},dF=(t,e)=\u003e`z: ${t.topology.portZ[e]}`,hF=(t,e)=\u003e((t,e,n)=\u003e{const o=t.topology.portZ[e],i=t.topology.portZ[n];return o===i?`z: ${o}`:`z: ${o} -\u003e ${i}`})(t,t.problem.routeStartPort[e],t.problem.routeEndPort[e]),uF=(t,e)=\u003e`net: ${t.problem.routeNet[e]}`,pF=.05,mF={r:255,g:64,b:64,a:.72},gF=\"rgba(220, 38, 38, 0.98)\",fF=\"rgba(220, 38, 38, 0.12)\",yF=\"10 6\",_F=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),bF=t=\u003eMath.min(1,Math.max(0,t)),xF=(t,e,n)=\u003eMath.round(t+(e-t)*n),vF=({r:t,g:e,b:n,a:o})=\u003e`rgba(${t}, ${e}, ${n}, ${o})`,SF=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},IF=t=\u003e\"number\"==typeof t.centerRouteId,CF=(t,e)=\u003eIF(t)?e===t.centerRouteId?1:.5:1,PF=(t,e)=\u003e{const n=t.match(/^(rgba|hsla)\\((.*),\\s*([0-9]*\\.?[0-9]+)\\)$/);if(!n)return t;const[,o,i,r]=n,s=bF(Number(r)*e);return`${o}(${i}, ${Number(s.toFixed(3))})`},MF=(t,e,n=.8)=\u003e((t,e,n=.8)=\u003e{const o=`${t.problem.routeNet[e]}:${SF(t,e)}`;let i=0;for(let t=0;t\u003co.length;t++)i=17777*o.charCodeAt(t)+((i\u003c\u003c5)-i);return`hsla(${Math.abs(i)%360}, 70%, 50%, ${n})`})(t,e,n*CF(t,e)),NF=(t,e)=\u003e`net: ${t.problem.routeNet[e]}`,wF=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=n?.polygon;if(Array.isArray(o)\u0026\u0026o.length\u003e=3){const t=o.map(t=\u003et.x),e=o.map(t=\u003et.y);return{minX:Math.min(...t),maxX:Math.max(...t),minY:Math.min(...e),maxY:Math.max(...e)}}const i=n?.bounds;if(i\u0026\u0026\"number\"==typeof i.minX\u0026\u0026\"number\"==typeof i.maxX\u0026\u0026\"number\"==typeof i.minY\u0026\u0026\"number\"==typeof i.maxY)return i;const r=t.topology.regionWidth[e],s=t.topology.regionHeight[e],a=t.topology.regionCenterX[e],c=t.topology.regionCenterY[e];return{minX:a-r/2,maxX:a+r/2,minY:c-s/2,maxY:c+s/2}},TF=(t,e)=\u003e({x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),RF=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=Array.isArray(n?.availableZ)?n.availableZ.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0):[];if(o.length\u003e0)return Rz(o)??\"z0\";const i=Ez(t.topology.regionAvailableZMask?.[e]??0);if(i.length\u003e0)return Rz(i)??\"z0\";const r=[...new Set((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))].sort((t,e)=\u003et-e);return Rz(r)??\"z0\"},EF=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e],o=n?.existingRegionCost??0,i=t.state.regionCongestionCost[e]??0,r=t.problem.regionNetId[e];return _F(`region: region-${e}`,`net: ${-1===r?\"free\":`${r}`}`,t.getAdditionalRegionLabel(e),`cost: ${o.toFixed(3)}`,`congestion: ${i.toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},AF=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];return n?.isConnectionRegion?{r:255,g:100,b:255,a:.6}:n?.isThroughJumper?{r:100,g:200,b:100,a:.5}:n?.isPad?{r:255,g:200,b:100,a:.5}:\"bottom\"===n?.layer?{r:52,g:152,b:219,a:.08}:{r:200,g:200,b:255,a:.1}},OF=(t,e)=\u003e{const n=AF(t,e),o=bF(t.state.regionIntersectionCaches[e]?.existingRegionCost??0);return vF((r=mF,s=o**.8,{r:xF((i=n).r,r.r,s),g:xF(i.g,r.g,s),b:xF(i.b,r.b,s),a:Number((i.a+(r.a-i.a)*s).toFixed(3))}));var i,r,s},kF=(t,e)=\u003e{const n=((t,e)=\u003e({x:t.topology.portX[e],y:t.topology.portY[e]}))(t,e),o=.005*t.topology.portZ[e];return{x:n.x+o,y:n.y+o}},LF=kF,DF=(t,e)=\u003eRz([t.topology.portZ[e]])??\"z0\",zF=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},FF=(t,e,n)=\u003e{if(void 0!==n)return`net: ${t.problem.routeNet[n]}`;const o=t.state.portAssignment[e];if(o\u003e=0)return`net: ${o}`;const i=new Set;for(let n=0;n\u003ct.problem.routeCount;n++)t.problem.routeStartPort[n]!==e\u0026\u0026t.problem.routeEndPort[n]!==e||i.add(t.problem.routeNet[n]);return 0!==i.size?`net: ${Array.from(i).sort((t,e)=\u003et-e).join(\", \")}`:void 0},BF=(t,e)=\u003e`z: ${t.topology.portZ[e]}`,jF=(t,e,n)=\u003e{const o=t.topology.portZ[e],i=t.topology.portZ[n];return o===i?`z: ${o}`:`z: ${o} -\u003e ${i}`},$F=(t,e)=\u003ejF(t,t.problem.routeStartPort[e],t.problem.routeEndPort[e]),YF=(t,e,n)=\u003e_F(zF(t,e),((t,e)=\u003e{const n=t.topology.incidentPortRegion[e]?.[0],o=t.topology.incidentPortRegion[e]?.[1];return`connects: region-${n??\"?\"} \u003c-\u003e region-${o??\"?\"}`})(t,e),FF(t,e,n)),XF=(t,e,n,o)=\u003e{const i=t.topology.portZ[n];return i!==t.topology.portZ[o]?{strokeColor:PF(\"rgba(22, 160, 133, 0.95)\",CF(t,e)),strokeDash:\"2 4 2\"}:i\u003e0?{strokeColor:PF(\"rgba(52, 152, 219, 0.95)\",CF(t,e)),strokeDash:\"3 2\"}:{strokeColor:MF(t,e)}},VF=(t,e)=\u003e{for(let n=0;n\u003ct.state.regionSegments.length;n++){const o=t.state.regionSegments[n]??[];for(const[i,r,s]of o)e.lines.push({points:[kF(t,r),kF(t,s)],label:_F(`route: ${SF(t,i)}`,`region: region-${n}`,jF(t,r,s)),layer:DF(t,r),...XF(t,i,r,s)})}},WF=(t,e)=\u003e{const n=new Set;for(let o=0;o\u003ct.state.regionSegments.length;o++){const i=t.state.regionSegments[o]??[];for(const[o,r,s]of i)for(const i of[r,s]){const r=`${o}:${i}`;if(n.has(r))continue;n.add(r);const s=kF(t,i);e.points.push({x:s.x,y:s.y,color:MF(t,o,1),layer:DF(t,i),label:_F(`route: ${SF(t,o)}`,zF(t,i),FF(t,i,o),BF(t,i))})}}},HF=(t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++)if(t.problem.routeStartPort[n]===e||t.problem.routeEndPort[n]===e)return!0;return!1},GF=(t,e,n)=\u003e{const o=((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ce.length;o++)if(1===e[o])for(const e of t.topology.incidentPortRegion[o]??[])n.add(e);return n})(t,n),i=\"rgba(245, 158, 11, 0.95)\",r=\"rgba(245, 158, 11, 0.08)\";for(const n of o){const o=t.topology.regionMetadata?.[n],s=o?.polygon,a=wF(t,n),c=TF(t,n),l=a.maxX-a.minX,d=a.maxY-a.minY,h=RF(t,n),u=_F(\"section region\",EF(t,n));Array.isArray(s)\u0026\u0026s.length\u003e=3?e.polygons.push({points:s,fill:r,stroke:i,strokeWidth:2,layer:h,label:u}):e.rects.push({center:c,width:Math.max(l-pF,.05),height:Math.max(d-pF,.05),fill:r,stroke:i,layer:h,label:u})}for(let o=0;o\u003cn.length;o++)1===n[o]\u0026\u0026e.circles.push({center:LF(t,o),radius:.07,fill:\"rgba(251, 191, 36, 0.18)\",stroke:i,layer:DF(t,o),label:_F(YF(t,o),BF(t,o),\"section port\")})},UF=(t,e={})=\u003e{const n={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:\"Tiny HyperGraph\",coordinateSystem:\"cartesian\"},o=((t,e)=\u003e{if(!e?.highlightSectionMask)return;const n=e.sectionPortMask??t.problem.portSectionMask;if(n.length!==t.topology.portCount)return;let o=0,i=0;for(let t=0;t\u003cn.length;t++)1===n[t]?o+=1:i+=1;return 0!==o\u0026\u00260!==i?n:void 0})(t,e),i=(t=\u003e{const e=t.getStaticallyUnroutableRoutes();if(0!==e.length)return new Set(e.map(t=\u003et.routeId))})(t);for(let e=0;e\u003ct.topology.regionCount;e++){const o=t.topology.regionMetadata?.[e],i=o?.polygon,r=wF(t,e),s=TF(t,e),a=r.maxX-r.minX,c=r.maxY-r.minY,l=RF(t,e),d=vF(AF(t,e));Array.isArray(i)\u0026\u0026i.length\u003e=3?n.polygons.push({points:i,fill:d,layer:l}):n.rects.push({center:s,width:Math.max(a-pF,.05),height:Math.max(c-pF,.05),fill:OF(t,e),layer:l,label:EF(t,e)})}if(((t,e,n)=\u003e{for(let o=0;o\u003ct.problem.routeCount;o++){if(n\u0026\u0026!n.has(o))continue;const i=t.problem.routeStartPort[o],r=t.problem.routeEndPort[o],s=kF(t,i),a=kF(t,r),c=MF(t,o),l=SF(t,o),d=NF(t,o);e.points.push({x:s.x,y:s.y,color:c,layer:DF(t,i),label:_F(`route: ${l}`,d,\"endpoint: start\",zF(t,i),BF(t,i))}),e.points.push({x:a.x,y:a.y,color:c,layer:DF(t,r),label:_F(`route: ${l}`,d,\"endpoint: end\",zF(t,r),BF(t,r))})}})(t,n,i),0===t.iterations){for(const t of n.polygons)t.stroke=\"rgba(128, 128, 128, 0.5)\";for(const t of n.rects)t.stroke=\"rgba(128, 128, 128, 0.5)\"}if(0===t.iterations){for(let i=0;i\u003ct.topology.portCount;i++){const r=1===o?.[i];e.showOnlySectionPortsOnIdle\u0026\u0026!r||n.circles.push({center:LF(t,i),radius:.05,fill:t.topology.portZ[i]\u003e0?\"rgba(52, 152, 219, 0.55)\":\"rgba(128, 128, 128, 0.5)\",layer:DF(t,i),label:_F(YF(t,i),BF(t,i))})}if(i)((t,e)=\u003e{for(const n of t.getStaticallyUnroutableRoutes()){const{routeId:o,connectionId:i,startPortId:r,endPortId:s}=n,a=aF(t,r),c=aF(t,s),l=sF(`static reachability failed: ${i}`,uF(t,o),n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0,n.pointIds.length\u003e=2?`points: ${n.pointIds.join(\" -\u003e \")}`:void 0,hF(t,o));e.lines.push({points:[a,c],strokeColor:iF,strokeDash:\"8 4\",label:l}),e.circles.push({center:a,radius:.12,fill:rF,stroke:iF,layer:cF(t,r),label:sF(l,\"endpoint: start\",lF(t,r),dF(t,r))}),e.circles.push({center:c,radius:.12,fill:rF,stroke:iF,layer:cF(t,s),label:sF(l,\"endpoint: end\",lF(t,s),dF(t,s))})}})(t,n);else{const o=new Set;for(const e of t.state.regionSegments)for(const[t]of e)o.add(t);if(o.size\u003e0\u0026\u0026(VF(t,n),WF(t,n)),!1!==e.showInitialRouteHints){const e=new Set(t.state.unroutedRoutes);void 0!==t.state.currentRouteId\u0026\u0026e.add(t.state.currentRouteId),((t,e,n)=\u003e{for(let o=0;o\u003ct.problem.routeCount;o++){if(n\u0026\u0026!n.has(o))continue;const i=t.problem.routeStartPort[o],r=t.problem.routeEndPort[o],s=kF(t,i),a=kF(t,r),c={x:(s.x+a.x)/2,y:(s.y+a.y)/2};e.lines.push({points:[s,a],strokeColor:MF(t,o),strokeDash:\"3 3\",layer:DF(t,i),label:_F(SF(t,o),$F(t,o))}),e.points.push({x:c.x,y:c.y,color:MF(t,o,1),layer:DF(t,i),label:_F(SF(t,o),$F(t,o))})}})(t,n,e)}}}else VF(t,n),WF(t,n),(t=\u003eIF(t)\u0026\u0026!0===t.showUnassignedPortsInVisualization)(t)\u0026\u0026((t,e)=\u003e{for(let n=0;n\u003ct.topology.portCount;n++)t.state.portAssignment[n]\u003e=0||HF(t,n)||e.circles.push({center:LF(t,n),radius:.04,fill:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.2)\":\"rgba(128, 128, 128, 0.2)\",stroke:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.6)\":\"rgba(128, 128, 128, 0.6)\",layer:DF(t,n),label:_F(YF(t,n),BF(t,n),\"state: unassigned\")})})(t,n),IF(t)||(((t,e)=\u003e{const n=t.state.currentRouteId;if(void 0===n||t.solved)return;const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=kF(t,o),s=kF(t,i),a=MF(t,n),c=SF(t,n);e.lines.push({points:[r,s],strokeColor:a,strokeDash:\"10 5\",label:_F(c,$F(t,n))})})(t,n),((t,e)=\u003e{if(t.solved)return;const n=t.state.currentRouteId,o=t.state.candidateQueue.toArray().sort((t,e)=\u003et.f-e.f).slice(0,10);for(let i=0;i\u003co.length;i++){const r=o[i],s=kF(t,r.portId),a=0===i;e.points.push({x:s.x,y:s.y,color:a?\"green\":\"rgba(128, 128, 128, 0.25)\",layer:DF(t,r.portId),label:_F(YF(t,r.portId,n),BF(t,r.portId),`g: ${r.g.toFixed(2)}`,`h: ${r.h.toFixed(2)}`,`f: ${r.f.toFixed(2)}`)})}const i=o[0];if(!i)return;const r=[];let s=i;for(;s;)r.unshift(kF(t,s.portId)),s=s.prevCandidate;r.length\u003e1\u0026\u0026e.lines.push({points:r,strokeColor:void 0!==n?MF(t,n):\"rgba(0, 160, 120, 0.9)\"})})(t,n));o\u0026\u0026GF(t,n,o),((t,e)=\u003e{if(t.failed)for(const n of t.getNeverSuccessfullyRoutedRoutes()){const{routeId:o,connectionId:i,attempts:r,startPortId:s,endPortId:a}=n,c=NF(t,o),l=LF(t,s),d=LF(t,a),h=_F(`never routed: ${i}`,`attempts: ${r}`,c,n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0);e.lines.push({points:[{x:0,y:0},{x:l.x,y:l.y}],strokeColor:gF,strokeDash:yF,layer:DF(t,s),label:_F(h,\"origin guide\",\"endpoint: start\")}),e.circles.push({center:l,radius:1,fill:fF,stroke:gF,layer:DF(t,s),label:_F(h,\"endpoint: start\",zF(t,s),BF(t,s))}),e.lines.push({points:[{x:0,y:0},{x:d.x,y:d.y}],strokeColor:gF,strokeDash:yF,layer:DF(t,a),label:_F(h,\"origin guide\",\"endpoint: end\")}),e.circles.push({center:d,radius:1,fill:fF,stroke:gF,layer:DF(t,a),label:_F(h,\"endpoint: end\",zF(t,a),BF(t,a))})}})(t,n);const r=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1),s=o?o.reduce((t,e)=\u003et+Number(1===e),0):0;return n.title=[\"Tiny HyperGraph\",`iter=${t.iterations}`,`pending=${r}`,o?`sectionPorts=${s}`:void 0,i?`staticReachabilityFailed=${i.size}`:void 0,t.failed?\"failed\":t.solved?\"solved\":\"running\"].filter(Boolean).join(\" | \"),n},ZF=5e4,qF=()=\u003e({netIds:new Int32Array(0),lesserAngles:new Int32Array(0),greaterAngles:new Int32Array(0),layerMasks:new Int32Array(0),existingCrossingLayerIntersections:0,existingSameLayerIntersections:0,existingEntryExitLayerChanges:0,existingRegionCost:0,existingSegmentCount:0}),JF=t=\u003e({netIds:new Int32Array(t.netIds),lesserAngles:new Int32Array(t.lesserAngles),greaterAngles:new Int32Array(t.greaterAngles),layerMasks:new Int32Array(t.layerMasks),existingCrossingLayerIntersections:t.existingCrossingLayerIntersections,existingSameLayerIntersections:t.existingSameLayerIntersections,existingEntryExitLayerChanges:t.existingEntryExitLayerChanges,existingRegionCost:t.existingRegionCost,existingSegmentCount:t.existingSegmentCount}),KF=t=\u003e{return{portAssignment:new Int32Array(t.portAssignment),regionSegments:(e=t.regionSegments,e.map(t=\u003et.map(([t,e,n])=\u003e[t,e,n]))),regionIntersectionCaches:t.regionIntersectionCaches.map(JF),regionCongestionCost:new Float64Array(t.regionCongestionCost),ripCount:t.ripCount};var e},QF=(t,e)=\u003e{e\u0026\u0026(void 0!==e.minViaPadDiameter\u0026\u0026(t.minViaPadDiameter=e.minViaPadDiameter),void 0!==e.DISTANCE_TO_COST\u0026\u0026(t.DISTANCE_TO_COST=e.DISTANCE_TO_COST),void 0!==e.RIP_THRESHOLD_START\u0026\u0026(t.RIP_THRESHOLD_START=e.RIP_THRESHOLD_START),void 0!==e.RIP_THRESHOLD_END\u0026\u0026(t.RIP_THRESHOLD_END=e.RIP_THRESHOLD_END),void 0!==e.RIP_THRESHOLD_RAMP_ATTEMPTS\u0026\u0026(t.RIP_THRESHOLD_RAMP_ATTEMPTS=e.RIP_THRESHOLD_RAMP_ATTEMPTS),void 0!==e.RIP_CONGESTION_REGION_COST_FACTOR\u0026\u0026(t.RIP_CONGESTION_REGION_COST_FACTOR=e.RIP_CONGESTION_REGION_COST_FACTOR),void 0!==e.TRACE_DENSITY_COST_FACTOR\u0026\u0026(t.TRACE_DENSITY_COST_FACTOR=Math.max(0,e.TRACE_DENSITY_COST_FACTOR)),void 0!==e.USE_LAZY_ROUTE_HEURISTIC\u0026\u0026(t.USE_LAZY_ROUTE_HEURISTIC=e.USE_LAZY_ROUTE_HEURISTIC),void 0!==e.USE_SPARSE_CANDIDATE_STORAGE\u0026\u0026(t.USE_SPARSE_CANDIDATE_STORAGE=e.USE_SPARSE_CANDIDATE_STORAGE),void 0!==e.MAX_ITERATIONS\u0026\u0026(t.MAX_ITERATIONS=e.MAX_ITERATIONS),void 0!==e.VERBOSE\u0026\u0026(t.VERBOSE=e.VERBOSE),void 0!==e.STATIC_REACHABILITY_PRECHECK\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK=e.STATIC_REACHABILITY_PRECHECK),void 0!==e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS=e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),void 0!==e.ACCEPT_BEST_SOLUTION_ON_TIMEOUT\u0026\u0026(t.ACCEPT_BEST_SOLUTION_ON_TIMEOUT=e.ACCEPT_BEST_SOLUTION_ON_TIMEOUT),void 0!==e.GREEDY_FINAL_ROUTE_ITERS\u0026\u0026(t.GREEDY_FINAL_ROUTE_ITERS=e.GREEDY_FINAL_ROUTE_ITERS),void 0!==e.PARTIAL_RIP_ENABLED\u0026\u0026(t.PARTIAL_RIP_ENABLED=e.PARTIAL_RIP_ENABLED),void 0!==e.PARTIAL_RIP_MIN_ROUTE_COUNT\u0026\u0026(t.PARTIAL_RIP_MIN_ROUTE_COUNT=e.PARTIAL_RIP_MIN_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_MAX_ROUTE_COUNT\u0026\u0026(t.PARTIAL_RIP_MAX_ROUTE_COUNT=e.PARTIAL_RIP_MAX_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_MAX_DISTANCE\u0026\u0026(t.PARTIAL_RIP_MAX_DISTANCE=e.PARTIAL_RIP_MAX_DISTANCE),void 0!==e.PARTIAL_RIP_QUALITY_MAX_DISTANCE\u0026\u0026(t.PARTIAL_RIP_QUALITY_MAX_DISTANCE=e.PARTIAL_RIP_QUALITY_MAX_DISTANCE),void 0!==e.PARTIAL_RIP_MAX_ATTEMPTS\u0026\u0026(t.PARTIAL_RIP_MAX_ATTEMPTS=e.PARTIAL_RIP_MAX_ATTEMPTS),void 0!==e.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS\u0026\u0026(t.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS=e.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS),void 0!==e.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT\u0026\u0026(t.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT=e.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO\u0026\u0026(t.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO=e.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO),void 0!==e.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO\u0026\u0026(t.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO=e.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO),void 0!==e.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO\u0026\u0026(t.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO=e.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO),void 0!==e.OUTSIDE_IN_ROUTING\u0026\u0026(t.OUTSIDE_IN_ROUTING=e.OUTSIDE_IN_ROUTING),void 0!==e.OUTSIDE_IN_MAX_DISTANCE\u0026\u0026(t.OUTSIDE_IN_MAX_DISTANCE=e.OUTSIDE_IN_MAX_DISTANCE))},tB=t=\u003e({minViaPadDiameter:t.minViaPadDiameter,DISTANCE_TO_COST:t.DISTANCE_TO_COST,RIP_THRESHOLD_START:t.RIP_THRESHOLD_START,RIP_THRESHOLD_END:t.RIP_THRESHOLD_END,RIP_THRESHOLD_RAMP_ATTEMPTS:t.RIP_THRESHOLD_RAMP_ATTEMPTS,RIP_CONGESTION_REGION_COST_FACTOR:t.RIP_CONGESTION_REGION_COST_FACTOR,TRACE_DENSITY_COST_FACTOR:t.TRACE_DENSITY_COST_FACTOR,USE_LAZY_ROUTE_HEURISTIC:t.USE_LAZY_ROUTE_HEURISTIC,USE_SPARSE_CANDIDATE_STORAGE:t.USE_SPARSE_CANDIDATE_STORAGE,MAX_ITERATIONS:t.MAX_ITERATIONS,VERBOSE:t.VERBOSE,STATIC_REACHABILITY_PRECHECK:t.STATIC_REACHABILITY_PRECHECK,STATIC_REACHABILITY_PRECHECK_MAX_HOPS:t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:t.ACCEPT_BEST_SOLUTION_ON_TIMEOUT,GREEDY_FINAL_ROUTE_ITERS:t.GREEDY_FINAL_ROUTE_ITERS,PARTIAL_RIP_ENABLED:t.PARTIAL_RIP_ENABLED,PARTIAL_RIP_MIN_ROUTE_COUNT:t.PARTIAL_RIP_MIN_ROUTE_COUNT,PARTIAL_RIP_MAX_ROUTE_COUNT:t.PARTIAL_RIP_MAX_ROUTE_COUNT,PARTIAL_RIP_MAX_DISTANCE:t.PARTIAL_RIP_MAX_DISTANCE,PARTIAL_RIP_QUALITY_MAX_DISTANCE:t.PARTIAL_RIP_QUALITY_MAX_DISTANCE,PARTIAL_RIP_MAX_ATTEMPTS:t.PARTIAL_RIP_MAX_ATTEMPTS,PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS:t.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:t.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT,PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO:t.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO,PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO:t.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO,PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO:t.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO,OUTSIDE_IN_ROUTING:t.OUTSIDE_IN_ROUTING,OUTSIDE_IN_MAX_DISTANCE:t.OUTSIDE_IN_MAX_DISTANCE}),eB=(t,e)=\u003et.f-e.f,nB=class extends kt{constructor(t,e,n){super(),this.topology=t,this.problem=e,QF(this,n);let o=1;const i=new Int32Array(t.portCount).fill(-1),r=new Int32Array(t.portCount).fill(-1);for(let e=0;e\u003ct.portCount;e++){const n=t.incidentPortRegion[e]??[];n.length\u003eo\u0026\u0026(o=n.length),i[e]=n[0]??-1,r[e]=n[1]??-1}this.candidateHopSlotStride=o,this.candidateFirstRegionByPortId=i,this.candidateSecondRegionByPortId=r;const s=t.portCount*o;this.candidateHopCapacity=s,this.state={portAssignment:new Int32Array(t.portCount).fill(-1),regionSegments:Array.from({length:t.regionCount},()=\u003e[]),regionIntersectionCaches:Array.from({length:t.regionCount},()=\u003eqF()),currentRouteId:void 0,currentRouteNetId:void 0,unroutedRoutes:oF(e.routeCount),candidateQueue:new Zz([],eB),candidateBestCostByHopId:this.USE_SPARSE_CANDIDATE_STORAGE?new Map:new Float64Array(s),candidateBestCostGenerationByHopId:this.USE_SPARSE_CANDIDATE_STORAGE?new Map:new Uint32Array(s),candidateBestCostGeneration:1,goalPortId:-1,ripCount:0,regionCongestionCost:new Float64Array(t.regionCount).fill(0)},this.routeAttemptCountByRouteId=new Uint32Array(e.routeCount),this.routeSuccessCountByRouteId=new Uint32Array(e.routeCount);const a=Uz({topology:t,problem:e,state:this.state,routeSuccessCountByRouteId:this.routeSuccessCountByRouteId,appendSegmentToRegionCache:(t,e,n)=\u003ethis.appendSegmentToRegionCache(t,e,n)});a\u0026\u0026(this.stats={...this.stats,...a})}topology;problem;state;candidateHopSlotStride;candidateHopCapacity;candidateFirstRegionByPortId;candidateSecondRegionByPortId;candidateOverflowBestCost;_problemSetup;routeAttemptCountByRouteId;routeSuccessCountByRouteId;bestSolvedStateSnapshot;bestSolvedStateSummary;hasLoggedNeverSuccessfullyRoutedRoutes=!1;staticallyUnroutableRoutes=[];segmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};ADD_SEGMENT_DISTANCE_TO_G=!1;DISTANCE_TO_COST=.05;minViaPadDiameter=Yz;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;RIP_CONGESTION_REGION_COST_FACTOR=.1;TRACE_DENSITY_COST_FACTOR=0;USE_LAZY_ROUTE_HEURISTIC=!1;USE_SPARSE_CANDIDATE_STORAGE=!1;MAX_ITERATIONS=1e6;VERBOSE=!1;STATIC_REACHABILITY_PRECHECK=!0;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;ACCEPT_BEST_SOLUTION_ON_TIMEOUT=!0;GREEDY_FINAL_ROUTE_ITERS=4;PARTIAL_RIP_ENABLED=!1;PARTIAL_RIP_MIN_ROUTE_COUNT=0;PARTIAL_RIP_MAX_ROUTE_COUNT=Number.POSITIVE_INFINITY;PARTIAL_RIP_MAX_DISTANCE=12;PARTIAL_RIP_QUALITY_MAX_DISTANCE;PARTIAL_RIP_MAX_ATTEMPTS=Number.POSITIVE_INFINITY;PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS=0;PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT=Number.POSITIVE_INFINITY;PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO=0;PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO=.2;PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO=.1;OUTSIDE_IN_ROUTING=!1;OUTSIDE_IN_MAX_DISTANCE=24;get problemSetup(){return this._problemSetup||(this._problemSetup=this.computeProblemSetup()),this._problemSetup}computeProblemSetup(){const{topology:t,problem:e}=this,n=this.USE_LAZY_ROUTE_HEURISTIC?void 0:new Float64Array(t.portCount*e.routeCount),o=t.portX,i=t.portY,r=Array.from({length:t.portCount},()=\u003enew Set),s=new Int32Array(t.portCount).fill(-1),a=(t,e)=\u003e{r[t].add(e);const n=s[t];-1===n?s[t]=e:n!==e\u0026\u0026(s[t]=-2)};for(let r=0;r\u003ce.routeCount;r++){const s=e.routeNet[r];if(a(e.routeStartPort[r],s),a(e.routeEndPort[r],s),n){const s=e.routeEndPort[r],a=o[s],c=i[s];for(let s=0;s\u003ct.portCount;s++){const t=o[s]-a,l=i[s]-c;n[s*e.routeCount+r]=Math.sqrt(t*t+l*l)*this.DISTANCE_TO_COST}}}return{portHCostToEndOfRoute:n,portEndpointNetIds:r,portEndpointReservationNetId:s}}_setup(){if(this.problemSetup,this.STATIC_REACHABILITY_PRECHECK){const t=nF({topology:this.topology,problem:this.problem,problemSetup:this.problemSetup,portAssignment:this.state.portAssignment,routeIds:this.state.unroutedRoutes,maxPrecheckHops:Math.max(0,this.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),getStartingNextRegionId:(t,e)=\u003ethis.getStartingNextRegionId(t,e),getRouteSummary:t=\u003ethis.getRouteSummary(t)});this.staticallyUnroutableRoutes=t,t.length\u003e0\u0026\u0026(this.failed=!0,this.error=(t=\u003e{const e=t.slice(0,5).map(t=\u003e{const e=t.pointIds.length\u003e=2?`${t.pointIds[0]}-\u003e${t.pointIds[1]}`:`${t.startPortId}-\u003e${t.endPortId}`;return`${t.connectionId} (${e})`}).join(\", \"),n=t.length-5;return[\"Static reachability precheck failed:\",`${t.length} route(s) have no legal path under the current reservation and start-region rules`,n\u003e0?`${e}, +${n} more`:e].join(\" \")})(t),this.stats={...this.stats,staticallyUnroutableRouteCount:t.length})}}_step(){const{problem:t,topology:e,state:n}=this;if(void 0===n.currentRouteId){if(0===n.unroutedRoutes.length)return void this.onAllRoutesRouted();n.currentRouteId=n.unroutedRoutes.shift(),n.currentRouteNetId=t.routeNet[n.currentRouteId],this.routeAttemptCountByRouteId[n.currentRouteId]+=1,this.resetCandidateBestCosts();const e=this.getRouteStartPortId(n.currentRouteId);n.candidateQueue.clear();const o=this.getStartingNextRegionId(n.currentRouteId,e);if(void 0===o)return this.failed=!0,void(this.error=`Start port ${e} has no incident regions`);this.setCandidateBestCost(this.getHopId(e,o),0),n.candidateQueue.queue({nextRegionId:o,portId:e,f:0,g:0,h:0}),n.goalPortId=this.getRouteEndPortId(n.currentRouteId)}const o=n.candidateQueue.dequeue();if(!o)return void this.onOutOfCandidates();const i=this.getHopId(o.portId,o.nextRegionId);if(o.g\u003ethis.getCandidateBestCost(i))return;if(this.isRegionReservedForDifferentNet(o.nextRegionId))return;const r=e.regionIncidentPorts[o.nextRegionId];for(const i of r){const r=n.portAssignment[i];if(this.isPortReservedForDifferentNet(i))continue;if(i===n.goalPortId){if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;return void this.onPathFound(o)}if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;if(i===o.portId)continue;if(0===t.portSectionMask[i])continue;const s=e.incidentPortRegion[i][0]===o.nextRegionId?e.incidentPortRegion[i][1]:e.incidentPortRegion[i][0];if(void 0===s||this.isRegionReservedForDifferentNet(s))continue;const a=this.getHopId(i,s);if(!0===n.candidateQueue.isClosedHop?.(i,s))continue;const c=this.getCandidateBestCost(a);if(o.g\u003e=c)continue;const l=this.computeG(o,i,c);if(!Number.isFinite(l)||l\u003e=c)continue;const d=this.computeH(i),h={prevRegionId:o.nextRegionId,nextRegionId:s,portId:i,g:l,h:d,f:l+d,prevCandidate:o};if(i===n.goalPortId)return void this.onPathFound(h);this.setCandidateBestCost(a,l),n.candidateQueue.queue(h)}}resetCandidateBestCosts(){const{state:t}=this;if(this.candidateOverflowBestCost?.clear(),4294967295===t.candidateBestCostGeneration)return t.candidateBestCostByHopId instanceof Map\u0026\u0026t.candidateBestCostByHopId.clear(),t.candidateBestCostGenerationByHopId instanceof Map?t.candidateBestCostGenerationByHopId.clear():t.candidateBestCostGenerationByHopId.fill(0),void(t.candidateBestCostGeneration=1);t.candidateBestCostGeneration+=1}getCandidateBestCost(t){if(t\u003c0)return this.candidateOverflowBestCost?.get(t)??Number.POSITIVE_INFINITY;const{state:e}=this,n=e.candidateBestCostGenerationByHopId;return(n instanceof Map?n.get(t):n[t])===e.candidateBestCostGeneration?e.candidateBestCostByHopId instanceof Map?e.candidateBestCostByHopId.get(t):e.candidateBestCostByHopId[t]:Number.POSITIVE_INFINITY}setCandidateBestCost(t,e){if(t\u003c0)return this.candidateOverflowBestCost||(this.candidateOverflowBestCost=new Map),void this.candidateOverflowBestCost.set(t,e);const{state:n}=this;n.candidateBestCostGenerationByHopId instanceof Map?n.candidateBestCostGenerationByHopId.set(t,n.candidateBestCostGeneration):n.candidateBestCostGenerationByHopId[t]=n.candidateBestCostGeneration,n.candidateBestCostByHopId instanceof Map?n.candidateBestCostByHopId.set(t,e):n.candidateBestCostByHopId[t]=e}getHopId(t,e){const n=t*this.candidateHopSlotStride;if(this.candidateFirstRegionByPortId[t]===e)return n;if(this.candidateSecondRegionByPortId[t]===e)return n+1;const o=this.topology.incidentPortRegion[t];for(let t=2;t\u003c(o?.length??0);t++)if(o[t]===e)return n+t;return-(t*this.topology.regionCount+e)-1}getStartingNextRegionId(t,e){const n=this.topology.incidentPortRegion[e]??[],o=this.problem.routeNet[t];return n.find(t=\u003e-1===this.problem.regionNetId[t])??n.find(t=\u003ethis.problem.regionNetId[t]===o)??n[0]}getRouteStartPortId(t){return this.problem.routeStartPort[t]}getRouteEndPortId(t){return this.problem.routeEndPort[t]}isPortReservedForDifferentNet(t){const e=this.problemSetup.portEndpointReservationNetId[t]??-1;return-2===e||-1!==e\u0026\u0026e!==this.state.currentRouteNetId}isRegionReservedForDifferentNet(t){const e=this.problem.regionNetId[t];return-1!==e\u0026\u0026e!==this.state.currentRouteNetId}isKnownSingleLayerRegion(t){const e=this.topology.regionAvailableZMask?.[t]??0;return Xz(e)}computeRegionCostForRegion(t,e,n,o,i){return((t,e,n,o,i,r,s=0,a=.3,c=0)=\u003eVz(t*e,n,o,i,r,s,a,c))(this.topology.regionWidth[t],this.topology.regionHeight[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0,this.minViaPadDiameter,this.TRACE_DENSITY_COST_FACTOR)}populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.segmentGeometryScratch,r=this.candidateFirstRegionByPortId[e]===t||this.candidateSecondRegionByPortId[e]!==t?o.portAngleForRegion1[e]:o.portAngleForRegion2?.[e]??o.portAngleForRegion1[e],s=this.candidateFirstRegionByPortId[n]===t||this.candidateSecondRegionByPortId[n]!==t?o.portAngleForRegion1[n]:o.portAngleForRegion2?.[n]??o.portAngleForRegion1[n],a=o.portZ[e],c=o.portZ[n];return i.lesserAngle=r\u003cs?r:s,i.greaterAngle=r\u003cs?s:r,i.layerMask=1\u003c\u003ca|1\u003c\u003cc,i.entryExitLayerChanges=a!==c?1:0,i}appendSegmentToRegionCache(t,e,n){const{state:o}=this,i=o.regionIntersectionCaches[t],r=this.populateSegmentGeometryScratch(t,e,n),[s,a,c]=Hz(i,o.currentRouteNetId,r.lesserAngle,r.greaterAngle,r.layerMask,r.entryExitLayerChanges),l=i.netIds.length+1,d=new Int32Array(l);d.set(i.netIds),d[l-1]=o.currentRouteNetId;const h=new Int32Array(l);h.set(i.lesserAngles),h[l-1]=r.lesserAngle;const u=new Int32Array(l);u.set(i.greaterAngles),u[l-1]=r.greaterAngle;const p=new Int32Array(l);p.set(i.layerMasks),p[l-1]=r.layerMask;const m=i.existingSameLayerIntersections+s,g=i.existingCrossingLayerIntersections+a,f=i.existingEntryExitLayerChanges+c,y=h.length;o.regionIntersectionCaches[t]={netIds:d,lesserAngles:h,greaterAngles:u,layerMasks:p,existingSameLayerIntersections:m,existingCrossingLayerIntersections:g,existingEntryExitLayerChanges:f,existingSegmentCount:y,existingRegionCost:this.computeRegionCostForRegion(t,m,g,f,y)}}getSolvedPathSegments(t){const{state:e}=this,n=[];let o=t;for(;o;)n.unshift(o),o=o.prevCandidate;const i=[];for(let t=1;t\u003cn.length;t++)i.push({regionId:n[t-1].nextRegionId,fromPortId:n[t-1].portId,toPortId:n[t].portId});const r=n[n.length-1];return r\u0026\u0026r.portId!==e.goalPortId\u0026\u0026i.push({regionId:r.nextRegionId,fromPortId:r.portId,toPortId:e.goalPortId}),i}resetRoutingStateForRerip(){const{topology:t,problem:e,state:n}=this;n.portAssignment.fill(-1),n.regionSegments=Array.from({length:t.regionCount},()=\u003e[]),n.regionIntersectionCaches=Array.from({length:t.regionCount},()=\u003eqF()),n.currentRouteNetId=void 0,n.currentRouteId=void 0,n.unroutedRoutes=qz(oF(e.routeCount),n.ripCount),n.candidateQueue.clear(),this.resetCandidateBestCosts(),n.goalPortId=-1}getMaxRegionCost(){const{topology:t,state:e}=this;let n=0;for(let o=0;o\u003ct.regionCount;o++){const t=e.regionIntersectionCaches[o]?.existingRegionCost??0;n=Math.max(n,t)}return n}getRouteMetadata(t){return this.problem.routeMetadata?.[t]}getRouteConnectionId(t){const e=this.getRouteMetadata(t)?.connectionId;return\"string\"==typeof e?e:`route-${t}`}getRouteSummary(t){return(({problem:t,routeId:e,getRouteMetadata:n,getRouteConnectionId:o})=\u003e{const i=n?.(e)??Jz(t,e);return{routeId:e,connectionId:o?.(e)??Qz(t,e),startPortId:t.routeStartPort[e],endPortId:t.routeEndPort[e],startRegionId:\"string\"==typeof i?.startRegionId?i.startRegionId:void 0,endRegionId:\"string\"==typeof i?.endRegionId?i.endRegionId:void 0,pointIds:Kz(i)}})({problem:this.problem,routeId:t,getRouteMetadata:t=\u003ethis.getRouteMetadata(t),getRouteConnectionId:t=\u003ethis.getRouteConnectionId(t)})}getAdditionalRegionLabel(t){}getNeverSuccessfullyRoutedRoutes(){const t=[];for(let e=0;e\u003cthis.problem.routeCount;e++){const n=this.routeAttemptCountByRouteId[e];0===n||this.routeSuccessCountByRouteId[e]\u003e0||t.push({...this.getRouteSummary(e),attempts:n})}return t}getStaticallyUnroutableRoutes(){return this.staticallyUnroutableRoutes}logNeverSuccessfullyRoutedRoutes(){if(!this.VERBOSE||this.hasLoggedNeverSuccessfullyRoutedRoutes)return;const t=this.getNeverSuccessfullyRoutedRoutes();if(this.hasLoggedNeverSuccessfullyRoutedRoutes=!0,0!==t.length){console.log([\"[TinyHyperGraphSolver:never-routed-summary]\",`count=${t.length}`].join(\" \"));for(const e of t){const t=e.pointIds.length\u003e=2?`${e.pointIds[0]}-\u003e${e.pointIds[1]}`:\"unknown\";console.log([\"[TinyHyperGraphSolver:never-routed]\",`routeId=${e.routeId}`,`connectionId=${e.connectionId}`,`attempts=${e.attempts}`,`pointPath=${t}`,`startRegionId=${e.startRegionId??\"unknown\"}`,`endRegionId=${e.endRegionId??\"unknown\"}`].join(\" \"))}}}logRipEvent(t,e,n={}){this.VERBOSE\u0026\u0026console.log([\"[TinyHyperGraphSolver:rip]\",`ripCount=${this.state.ripCount}`,`maxRegionCostBeforeRip=${e.toFixed(3)}`,`reason=${t}`,...Object.entries(n).map(([t,e])=\u003e`${t}=${\"number\"==typeof e?Number.isInteger(e)?String(e):e.toFixed(3):e}`)].join(\" \"))}compareRegionCostSummaries(t,e){return t.maxRegionCost!==e.maxRegionCost?t.maxRegionCost-e.maxRegionCost:t.totalRegionCost-e.totalRegionCost}captureBestSolvedState(t){this.bestSolvedStateSummary\u0026\u0026this.compareRegionCostSummaries(t,this.bestSolvedStateSummary)\u003e=0||this.replaceBestSolvedState(t)}replaceBestSolvedState(t){this.bestSolvedStateSummary=t,this.bestSolvedStateSnapshot=KF({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches,regionCongestionCost:this.state.regionCongestionCost,ripCount:this.state.ripCount})}restoreBestSolvedState(){if(!this.bestSolvedStateSnapshot)return;const t=KF(this.bestSolvedStateSnapshot);this.state.portAssignment=t.portAssignment,this.state.regionSegments=t.regionSegments,this.state.regionIntersectionCaches=t.regionIntersectionCaches,this.state.regionCongestionCost=t.regionCongestionCost,this.state.ripCount=t.ripCount,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1}getRemainingRouteIdsForGreedyFinalRoute(){const t=new Set(this.state.unroutedRoutes);return void 0!==this.state.currentRouteId\u0026\u0026t.add(this.state.currentRouteId),[...t]}applySnapshotToGreedyFinalRouteSolver(t,e,n){const o=KF(e);t.state.portAssignment=o.portAssignment,t.state.regionSegments=o.regionSegments,t.state.regionIntersectionCaches=o.regionIntersectionCaches,t.state.regionCongestionCost=o.regionCongestionCost,t.state.ripCount=0,t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.state.unroutedRoutes=[...n],t.state.candidateQueue.clear(),t.resetCandidateBestCosts(),t.state.goalPortId=-1}summarizeSolvedState(t){let e=0,n=0;for(const o of t.state.regionIntersectionCaches){const t=o.existingRegionCost;e=Math.max(e,t),n+=t}return{maxRegionCost:e,totalRegionCost:n}}tryGreedyFinalRouteAcceptance(){const t=Math.max(0,Math.floor(this.GREEDY_FINAL_ROUTE_ITERS));if(0===t)return!1;const e=this.getRemainingRouteIdsForGreedyFinalRoute();if(0===e.length)return!1;const n=KF({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches,regionCongestionCost:this.state.regionCongestionCost,ripCount:this.state.ripCount});for(let o=0;o\u003ct;o++){const t=0===o?e:qz(e,this.state.ripCount+o),i=new oB(this.topology,this.problem,{...tB(this),ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!1,GREEDY_FINAL_ROUTE_ITERS:0,MAX_ITERATIONS:ZF,RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!1});if(this.applySnapshotToGreedyFinalRouteSolver(i,n,t),i.solve(),i.solved\u0026\u0026!i.failed)return this.bestSolvedStateSnapshot=KF({portAssignment:i.state.portAssignment,regionSegments:i.state.regionSegments,regionIntersectionCaches:i.state.regionIntersectionCaches,regionCongestionCost:i.state.regionCongestionCost,ripCount:i.state.ripCount}),this.bestSolvedStateSummary=this.summarizeSolvedState(i),this.restoreBestSolvedState(),this.stats={...this.stats,acceptedGreedyFinalRouteOnTimeout:!0,greedyFinalRouteIter:o,greedyFinalRouteRemainingRouteCount:e.length,greedyFinalRouteMaxIterations:ZF,neverSuccessfullyRoutedRouteCount:0,maxRegionCost:this.bestSolvedStateSummary.maxRegionCost,totalRegionCost:this.bestSolvedStateSummary.totalRegionCost,bestMaxRegionCost:this.bestSolvedStateSummary.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary.totalRegionCost},this.solved=!0,this.failed=!1,this.error=null,!0}return this.stats={...this.stats,greedyFinalRouteAttemptCount:t,greedyFinalRouteRemainingRouteCount:e.length,greedyFinalRouteMaxIterations:ZF},!1}onAllRoutesRouted(){const{topology:t,state:e}=this,n=this.RIP_THRESHOLD_RAMP_ATTEMPTS\u003c=0?1:Math.min(1,e.ripCount/this.RIP_THRESHOLD_RAMP_ATTEMPTS),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(t.regionCount);let s=0,a=0;for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;r[n]=t,s=Math.max(s,t),a+=t,t\u003eo\u0026\u0026i.push(n)}if(this.captureBestSolvedState({maxRegionCost:s,totalRegionCost:a}),this.stats={...this.stats,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:s,totalRegionCost:a,bestMaxRegionCost:this.bestSolvedStateSummary?.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary?.totalRegionCost,ripCount:e.ripCount},0===i.length||e.ripCount\u003e=this.RIP_THRESHOLD_RAMP_ATTEMPTS)this.solved=!0;else{for(let n=0;n\u003ct.regionCount;n++)e.regionCongestionCost[n]+=r[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCostBeforeRip:s,reripRegionCount:i.length},this.logRipEvent(\"hot_regions\",s,{hotRegionCount:i.length,currentRipThreshold:o})}}onOutOfCandidates(){const{topology:t,state:e}=this,n=e.currentRouteId,o=this.getMaxRegionCost();for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;e.regionCongestionCost[n]+=t*this.RIP_CONGESTION_REGION_COST_FACTOR}e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCost:o,maxRegionCostBeforeRip:o,reripReason:\"out_of_candidates\"},this.logRipEvent(\"out_of_candidates\",o,{...void 0===n?{}:{routeId:n,connectionId:this.getRouteConnectionId(n)}})}onPathFound(t){const{state:e}=this,n=e.currentRouteId;if(void 0===n)return;this.routeSuccessCountByRouteId[n]+=1;const o=this.getSolvedPathSegments(t);for(const{regionId:t,fromPortId:i,toPortId:r}of o)e.regionSegments[t].push([n,i,r]),e.portAssignment[i]=e.currentRouteNetId,e.portAssignment[r]=e.currentRouteNetId,this.appendSegmentToRegionCache(t,i,r);e.candidateQueue.clear(),e.currentRouteNetId=void 0,e.currentRouteId=void 0}computeG(t,e,n=Number.POSITIVE_INFINITY,o){const{state:i,topology:r}=this,s=t.nextRegionId,a=i.regionIntersectionCaches[s];let c=0;if(this.ADD_SEGMENT_DISTANCE_TO_G){let n=o;if(void 0===n){const o=r.portX[t.portId]-r.portX[e],i=r.portY[t.portId]-r.portY[e];n=Math.sqrt(o*o+i*i)}c=n*this.DISTANCE_TO_COST}if(t.g+i.regionCongestionCost[s]+(this.problem.portPenalty?.[e]??0)+c\u003en+1e-9)return Number.POSITIVE_INFINITY;const l=t.portId,d=this.candidateFirstRegionByPortId[l]===s||this.candidateSecondRegionByPortId[l]!==s?r.portAngleForRegion1[l]:r.portAngleForRegion2?.[l]??r.portAngleForRegion1[l],h=this.candidateFirstRegionByPortId[e]===s||this.candidateSecondRegionByPortId[e]!==s?r.portAngleForRegion1[e]:r.portAngleForRegion2?.[e]??r.portAngleForRegion1[e],u=d\u003ch?d:h,p=d\u003ch?h:d,m=r.portZ[l],g=r.portZ[e],f=1\u003c\u003cm|1\u003c\u003cg,y=m!==g?1:0,[_,b,x]=Hz(a,i.currentRouteNetId,u,p,f,y);if(_\u003e0\u0026\u0026this.isKnownSingleLayerRegion(s))return Number.POSITIVE_INFINITY;const v=this.computeRegionCostForRegion(s,a.existingSameLayerIntersections+_,a.existingCrossingLayerIntersections+b,a.existingEntryExitLayerChanges+x,a.existingSegmentCount+1)-a.existingRegionCost;return t.g+v+i.regionCongestionCost[s]+(this.problem.portPenalty?.[e]??0)+c}tryFinalAcceptance(){const t=this.getNeverSuccessfullyRoutedRoutes();if(this.stats={...this.stats,neverSuccessfullyRoutedRouteCount:t.length},this.ACCEPT_BEST_SOLUTION_ON_TIMEOUT\u0026\u0026this.bestSolvedStateSnapshot\u0026\u0026this.bestSolvedStateSummary)return this.restoreBestSolvedState(),this.stats={...this.stats,acceptedBestSolutionOnTimeout:!0,maxRegionCost:this.bestSolvedStateSummary.maxRegionCost,totalRegionCost:this.bestSolvedStateSummary.totalRegionCost,bestMaxRegionCost:this.bestSolvedStateSummary.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary.totalRegionCost},this.solved=!0,this.failed=!1,void(this.error=null);this.ACCEPT_BEST_SOLUTION_ON_TIMEOUT\u0026\u0026this.tryGreedyFinalRouteAcceptance()||this.logNeverSuccessfullyRoutedRoutes()}computeH(t){const e=this.problemSetup.portHCostToEndOfRoute;if(e)return e[t*this.problem.routeCount+this.state.currentRouteId];const n=this.getRouteEndPortId(this.state.currentRouteId),o=this.topology.portX[t]-this.topology.portX[n],i=this.topology.portY[t]-this.topology.portY[n];return Math.sqrt(o*o+i*i)*this.DISTANCE_TO_COST}visualize(){return UF(this)}getOutput(){return $z(this)}},oB=class extends nB{computeG(t,e){return t.g}},iB=class{constructor(t,e){this.regionCount=t,this.compactHopIndex=e,e\u0026\u0026(this.hopStateGeneration=new Uint32Array(e.hopCapacity),this.hopIndexOrClosed=new Int32Array(e.hopCapacity))}regionCount;compactHopIndex;items=[];indexByHopId=new Map;closedHopIds=new Set;hopStateGeneration;hopIndexOrClosed;currentHopStateGeneration=1;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0,this.indexByHopId.clear(),this.closedHopIds.clear(),this.hopStateGeneration\u0026\u0026(4294967295===this.currentHopStateGeneration?(this.hopStateGeneration.fill(0),this.currentHopStateGeneration=1):this.currentHopStateGeneration+=1)}isClosedHop(t,e){return this.isHopClosed(this.getHopIdFromValues(t,e))}queue(t){const e=this.getHopId(t);if(this.isHopClosed(e))return;const n=this.getQueuedHopIndex(e);if(void 0!==n){const e=this.items[n];if(t.g\u003e=e.g)return;return this.items[n]=t,void(t.f\u003c=e.f?this.siftUp(n):this.siftDown(n))}const o=this.items.length;this.items.push(t),this.siftUp(o)}dequeue(){const t=this.items[0];if(!t)return;const e=this.getHopId(t);this.closeHop(e);const n=this.items.pop();return this.items.length\u003e0\u0026\u0026(this.items[0]=n,this.siftDown(0)),t}getHopId(t){return this.getHopIdFromValues(t.portId,t.nextRegionId)}getHopIdFromValues(t,e){const n=this.compactHopIndex;if(!n)return t*this.regionCount+e;const o=t*n.hopSlotStride;if(n.firstRegionByPortId[t]===e)return o;if(n.secondRegionByPortId[t]===e)return o+1;const i=n.incidentPortRegion[t];for(let t=2;t\u003c(i?.length??0);t++)if(i[t]===e)return o+t;return-(t*this.regionCount+e)-1}getQueuedHopIndex(t){if(t\u003e=0\u0026\u0026this.hopStateGeneration?.[t]===this.currentHopStateGeneration){const e=this.hopIndexOrClosed[t];return e\u003e=0?e:void 0}return this.indexByHopId.get(t)}isHopClosed(t){return t\u003e=0\u0026\u0026this.hopStateGeneration?.[t]===this.currentHopStateGeneration?-1===this.hopIndexOrClosed[t]:this.closedHopIds.has(t)}setQueuedHopIndex(t,e){if(t\u003e=0\u0026\u0026this.hopStateGeneration)return this.hopStateGeneration[t]=this.currentHopStateGeneration,void(this.hopIndexOrClosed[t]=e);this.indexByHopId.set(t,e)}closeHop(t){if(t\u003e=0\u0026\u0026this.hopStateGeneration)return this.hopStateGeneration[t]=this.currentHopStateGeneration,void(this.hopIndexOrClosed[t]=-1);this.indexByHopId.delete(t),this.closedHopIds.add(t)}siftUp(t){const e=this.items[t];let n=t;for(;n\u003e0;){const t=n-1\u003e\u003e1,o=this.items[t];if(o.f\u003c=e.f)break;this.items[n]=o,this.setQueuedHopIndex(this.getHopId(o),n),n=t}this.items[n]=e,this.setQueuedHopIndex(this.getHopId(e),n)}siftDown(t){const e=this.items[t];let n=t;for(;;){const t=2*n+1;if(t\u003e=this.items.length)break;const o=t+1,i=o\u003cthis.items.length\u0026\u0026this.items[o].f\u003cthis.items[t].f?o:t,r=this.items[i];if(e.f\u003c=r.f)break;this.items[n]=r,this.setQueuedHopIndex(this.getHopId(r),n),n=i}this.items[n]=e,this.setQueuedHopIndex(this.getHopId(e),n)}},rB=class extends nB{constructor(t,e,n){super(t,e,n),this.ADD_SEGMENT_DISTANCE_TO_G=!0}_setup(){super._setup(),this.state.candidateQueue=new iB(this.topology.regionCount,{hopCapacity:this.candidateHopCapacity,hopSlotStride:this.candidateHopSlotStride,firstRegionByPortId:this.candidateFirstRegionByPortId,secondRegionByPortId:this.candidateSecondRegionByPortId,incidentPortRegion:this.topology.incidentPortRegion})}onPathFound(t){const e=this.state.goalPortId;if(t.portId===e)return void super.onPathFound(t);const n=this.computeG(t,e);if(!Number.isFinite(n))return;const o=this.getHopId(e,t.nextRegionId);n\u003e=this.getCandidateBestCost(o)||(this.setCandidateBestCost(o,n),this.state.candidateQueue.queue({prevRegionId:t.nextRegionId,nextRegionId:t.nextRegionId,portId:e,g:n,h:0,f:n,prevCandidate:t}))}},sB=new Set,aB=class extends rB{partialRipRoutePlans=new Map;outsideInRouteSearch;oneSidedFallbackRouteId;partialRipWindowDistance;partialRipCount=0;partiallyRippedRouteCount=0;partiallyRippedSegmentCount=0;retainedPartialRipSegmentCount=0;outsideInRouteCount=0;outsideInCompletedRouteCount=0;outsideInFallbackRouteCount=0;outsideInForwardExpansionCount=0;outsideInReverseExpansionCount=0;outsideInDistancePruneCount=0;completedRoundSummaries=[];firstCompletedRoundSummary;partialRipQualityBaselineSummary;bestSolvedRoundSummary;partialRipTargetReached=!1;useComplexityAwareSelection=!1;constructor(t,e,n){super(t,e,n),void 0===n?.PARTIAL_RIP_ENABLED\u0026\u0026(this.PARTIAL_RIP_ENABLED=!0),void 0===n?.OUTSIDE_IN_ROUTING\u0026\u0026(this.OUTSIDE_IN_ROUTING=!0),this.PARTIAL_RIP_ENABLED\u0026\u0026void 0===n?.PARTIAL_RIP_MAX_ATTEMPTS\u0026\u0026(this.PARTIAL_RIP_MAX_ATTEMPTS=10),(e.routeCount\u003cMath.max(0,this.PARTIAL_RIP_MIN_ROUTE_COUNT)||e.routeCount\u003eMath.max(0,this.PARTIAL_RIP_MAX_ROUTE_COUNT))\u0026\u0026(this.PARTIAL_RIP_ENABLED=!1,this.OUTSIDE_IN_ROUTING=!1),this.useComplexityAwareSelection=e.routeCount\u003e=Math.max(0,this.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT)}getRouteStartPortId(t){return this.PARTIAL_RIP_ENABLED?this.partialRipRoutePlans.get(t)?.activeStartPortId??super.getRouteStartPortId(t):super.getRouteStartPortId(t)}getRouteEndPortId(t){return this.PARTIAL_RIP_ENABLED?this.partialRipRoutePlans.get(t)?.activeEndPortId??super.getRouteEndPortId(t):super.getRouteEndPortId(t)}getStartingNextRegionId(t,e){if(!this.PARTIAL_RIP_ENABLED)return super.getStartingNextRegionId(t,e);const n=this.partialRipRoutePlans.get(t);return n\u0026\u0026n.activeStartPortId===e?n.forcedStartRegionId:super.getStartingNextRegionId(t,e)}getEndingNextRegionId(t,e){const n=this.partialRipRoutePlans.get(t);return n\u0026\u0026n.activeEndPortId===e?n.forcedEndRegionId:super.getStartingNextRegionId(t,e)}computeH(t){if(!this.PARTIAL_RIP_ENABLED)return super.computeH(t);const e=this.state.currentRouteId;if(void 0===e||!this.partialRipRoutePlans.has(e))return super.computeH(t);const n=this.getRouteEndPortId(e),o=this.topology.portX[t]-this.topology.portX[n],i=this.topology.portY[t]-this.topology.portY[n];return Math.sqrt(o*o+i*i)*this.DISTANCE_TO_COST}onPathFound(t){if(!this.PARTIAL_RIP_ENABLED\u0026\u0026!this.OUTSIDE_IN_ROUTING)return void super.onPathFound(t);const e=this.state.currentRouteId,n=void 0!==e\u0026\u0026this.outsideInRouteSearch?.routeId===e;super.onPathFound(t),void 0!==e\u0026\u0026void 0===this.state.currentRouteId\u0026\u0026(this.partialRipRoutePlans.delete(e),n\u0026\u0026(this.outsideInCompletedRouteCount+=1),this.oneSidedFallbackRouteId===e\u0026\u0026(this.oneSidedFallbackRouteId=void 0)),this.outsideInRouteSearch=void 0,this.publishOutsideInStats()}resetRoutingStateForRerip(){this.PARTIAL_RIP_ENABLED||this.OUTSIDE_IN_ROUTING?(this.partialRipRoutePlans.clear(),this.outsideInRouteSearch=void 0,this.oneSidedFallbackRouteId=void 0,super.resetRoutingStateForRerip()):super.resetRoutingStateForRerip()}clearPartialRipPlans(t){for(const e of t)this.partialRipRoutePlans.delete(e)}getRouteIdsPreferredForPreservation(){return sB}getCommittedRouteSegments(t){const e=[];for(let n=0;n\u003cthis.state.regionSegments.length;n++)for(const[o,i,r]of this.state.regionSegments[n]??[])o===t\u0026\u0026e.push({segmentIndex:e.length,regionId:n,fromPortId:i,toPortId:r});if(0===e.length)return;const n=new Map;for(const t of e)for(const e of[t.fromPortId,t.toPortId]){const o=n.get(e)??[];o.push(t.segmentIndex),n.set(e,o)}const o=this.problem.routeEndPort[t],i=[],r=new Set,s=new Set([this.problem.routeStartPort[t]]),a=t=\u003e{if(t===o)return!0;for(const o of n.get(t)??[]){if(r.has(o))continue;const n=e[o],c=n.fromPortId===t?n.toPortId:n.fromPortId;if(!s.has(c)){if(r.add(o),s.add(c),i.push({regionId:n.regionId,fromPortId:t,toPortId:c}),a(c))return!0;i.pop(),s.delete(c),r.delete(o)}}return!1};return a(this.problem.routeStartPort[t])\u0026\u0026r.size===e.length?i:void 0}getSegmentDistance(t){const e=this.topology.portX[t.fromPortId]-this.topology.portX[t.toPortId],n=this.topology.portY[t.fromPortId]-this.topology.portY[t.toPortId];return Math.sqrt(e*e+n*n)}getPartialRipWindow(t,e,n){let o,i=Number.NEGATIVE_INFINITY;for(let r=0;r\u003ct.length;r++){const s=t[r];if(!e.has(s.regionId))continue;const a=n[s.regionId]??0;a\u003ei\u0026\u0026(i=a,o=r)}if(void 0===o)return;const r=Math.max(0,this.partialRipWindowDistance??this.PARTIAL_RIP_MAX_DISTANCE);let s=o,a=o,c=this.getSegmentDistance(t[o])/2,l=c;for(;s\u003e0;){const e=this.getSegmentDistance(t[s-1]);if(c+e\u003er)break;s-=1,c+=e}for(;a+1\u003ct.length;){const e=this.getSegmentDistance(t[a+1]);if(l+e\u003er)break;a+=1,l+=e}return{startIndex:s,endIndex:a}}appendRetainedSegment(t,e,n){t[n.regionId].push([e,n.fromPortId,n.toPortId])}preparePartialRip(t,e){if(!this.PARTIAL_RIP_ENABLED||0===t.length)return!1;const n=new Set(t);if(void 0===this.partialRipWindowDistance){let n=0;for(const o of t)n=Math.max(n,e[o]??0);const o=Math.max(0,this.PARTIAL_RIP_MAX_DISTANCE),i=Math.max(o,this.PARTIAL_RIP_QUALITY_MAX_DISTANCE??2*o);this.partialRipWindowDistance=n\u003c=1.5*this.RIP_THRESHOLD_END?i:o}const o=new Set;for(const e of t)for(const[t]of this.state.regionSegments[e]??[])o.add(t);if(0===o.size)return!1;const i=this.getRouteIdsPreferredForPreservation(),r=[...o].some(t=\u003e!i.has(t)),s=Array.from({length:this.topology.regionCount},()=\u003e[]),a=new Map;let c=0,l=0;for(let t=0;t\u003cthis.problem.routeCount;t++){const d=this.getCommittedRouteSegments(t);if(!d)return!1;if(!o.has(t)||r\u0026\u0026i.has(t)){for(const e of d)this.appendRetainedSegment(s,t,e),l+=1;continue}const h=this.getPartialRipWindow(d,n,e);if(!h)return!1;for(let e=0;e\u003cd.length;e++){const n=d[e];e\u003e=h.startIndex\u0026\u0026e\u003c=h.endIndex?c+=1:(this.appendRetainedSegment(s,t,n),l+=1)}const u=d[h.startIndex],p=d[h.endIndex];a.set(t,{routeId:t,activeStartPortId:u.fromPortId,activeEndPortId:p.toPortId,forcedStartRegionId:u.regionId,forcedEndRegionId:p.regionId,rippedSegmentCount:h.endIndex-h.startIndex+1,retainedSegmentCount:d.length-(h.endIndex-h.startIndex+1)})}return 0!==a.size\u0026\u00260!==c\u0026\u0026(this.partialRipRoutePlans=a,this.rebuildRetainedRoutingState(s,[...a.keys()]),this.partialRipCount+=1,this.partiallyRippedRouteCount+=a.size,this.partiallyRippedSegmentCount+=c,this.retainedPartialRipSegmentCount+=l,this.publishPartialRipStats(),!0)}rebuildRetainedRoutingState(t,e){this.state.portAssignment.fill(-1),this.state.regionSegments=Array.from({length:this.topology.regionCount},()=\u003e[]),this.state.regionIntersectionCaches=Array.from({length:this.topology.regionCount},()=\u003eqF()),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=e,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.outsideInRouteSearch=void 0,this.oneSidedFallbackRouteId=void 0;for(let e=0;e\u003ct.length;e++)for(const[n,o,i]of t[e]??[]){const t=this.problem.routeNet[n];this.state.currentRouteNetId=t;for(const e of[o,i]){const n=this.state.portAssignment[e];if(-1!==n\u0026\u0026n!==t)throw new Error(`OutsideInPartialRipTinyHyperGraphSolver: retained port ${e} belongs to multiple nets`);this.state.portAssignment[e]=t}this.state.regionSegments[e].push([n,o,i]),this.appendSegmentToRegionCache(e,o,i)}this.state.currentRouteNetId=void 0}publishPartialRipStats(){this.stats={...this.stats,partialRipCount:this.partialRipCount,partiallyRippedRouteCount:this.partiallyRippedRouteCount,partiallyRippedSegmentCount:this.partiallyRippedSegmentCount,retainedPartialRipSegmentCount:this.retainedPartialRipSegmentCount,partialRipMaxDistance:this.partialRipWindowDistance??this.PARTIAL_RIP_MAX_DISTANCE,partialRipBaseMaxDistance:this.PARTIAL_RIP_MAX_DISTANCE,partialRipQualityMaxDistance:this.PARTIAL_RIP_QUALITY_MAX_DISTANCE??2*this.PARTIAL_RIP_MAX_DISTANCE,partialRipMaxAttempts:this.PARTIAL_RIP_MAX_ATTEMPTS}}publishOutsideInStats(){this.stats={...this.stats,outsideInRouteCount:this.outsideInRouteCount,outsideInCompletedRouteCount:this.outsideInCompletedRouteCount,outsideInFallbackRouteCount:this.outsideInFallbackRouteCount,outsideInForwardExpansionCount:this.outsideInForwardExpansionCount,outsideInReverseExpansionCount:this.outsideInReverseExpansionCount,outsideInDistancePruneCount:this.outsideInDistancePruneCount,outsideInMaxDistance:this.OUTSIDE_IN_MAX_DISTANCE}}createOutsideInFrontier(t,e,n){const o=new Zz([],(t,e)=\u003et.f===e.f?t.g-e.g:t.f-e.f),i=this.topology.portX[t]-this.topology.portX[n],r=this.topology.portY[t]-this.topology.portY[n],s=Math.sqrt(i*i+r*r)*this.DISTANCE_TO_COST,a={portId:t,nextRegionId:e,f:s,g:0,h:s,travelDistance:0};return o.queue(a),{queue:o,bestCostByHopId:new Map([[this.getHopId(t,e),0]]),settledByPortId:new Map,settledByRegionId:new Map,targetPortId:n}}startOutsideInRouteSearch(t){const e=this.getRouteStartPortId(t),n=this.getRouteEndPortId(t),o=this.getStartingNextRegionId(t,e),i=this.getEndingNextRegionId(t,n);return void 0!==o\u0026\u0026void 0!==i\u0026\u0026(this.state.goalPortId=n,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.outsideInRouteSearch={routeId:t,forward:this.createOutsideInFrontier(e,o,n),reverse:this.createOutsideInFrontier(n,i,e),expandForwardNext:!0,distanceLimitHit:!1,bestJoinedCost:Number.POSITIVE_INFINITY},this.outsideInRouteCount+=1,this.publishOutsideInStats(),!0)}dequeueFreshCandidate(t){for(;t.queue.length\u003e0;){const e=t.queue.dequeue(),n=this.getHopId(e.portId,e.nextRegionId);if(e.g\u003c=(t.bestCostByHopId.get(n)??1/0))return e}}recordSettledCandidate(t,e){const n=t.settledByPortId.get(e.portId);(!n||e.g\u003cn.g)\u0026\u0026t.settledByPortId.set(e.portId,e);const o=t.settledByRegionId.get(e.nextRegionId)??[];o.push(e),o.sort((t,e)=\u003et.g-e.g),o.length\u003e16\u0026\u0026(o.length=16),t.settledByRegionId.set(e.nextRegionId,o)}getCandidatePath(t){const e=[];let n=t;for(;n;)e.push(n),n=n.prevCandidate;return e.reverse(),e}buildJoinedCandidate(t,e){const n=this.getCandidatePath(t),o=this.getCandidatePath(e),i=n.map(({portId:t})=\u003et),r=n.slice(0,-1).map(({nextRegionId:t})=\u003et);if(t.portId!==e.portId){if(t.nextRegionId!==e.nextRegionId)return;const n=this.topology.portX[t.portId]-this.topology.portX[e.portId],o=this.topology.portY[t.portId]-this.topology.portY[e.portId],s=Math.sqrt(n*n+o*o);if(t.travelDistance+e.travelDistance+s\u003e2*this.OUTSIDE_IN_MAX_DISTANCE)return;const a=this.computeG(t,e.portId);if(!Number.isFinite(a))return;r.push(t.nextRegionId),i.push(e.portId)}for(let t=o.length-2;t\u003e=0;t--){const e=o[t];r.push(e.nextRegionId),i.push(e.portId)}if(new Set(i).size!==i.length||r.length+1!==i.length)return;let s={portId:i[0],nextRegionId:r[0],f:0,g:0,h:0};for(let t=1;t\u003ci.length;t++)s={portId:i[t],prevRegionId:r[t-1],nextRegionId:r[t]??r[t-1],prevCandidate:s,f:0,g:0,h:0};const a=t.portId===e.portId?0:this.computeG(t,e.portId)-t.g;return{candidate:s,cost:t.g+e.g+a}}considerOutsideInJoins(t,e){const n=this.outsideInRouteSearch,o=e?n.reverse:n.forward,i=t=\u003e{!t||t.cost\u003e=n.bestJoinedCost||(n.bestJoinedCandidate=t.candidate,n.bestJoinedCost=t.cost,n.remainingPostMeetingExpansions=24)},r=o.settledByPortId.get(t.portId);r\u0026\u0026i(e?this.buildJoinedCandidate(t,r):this.buildJoinedCandidate(r,t));for(const n of o.settledByRegionId.get(t.nextRegionId)??[])i(e?this.buildJoinedCandidate(t,n):this.buildJoinedCandidate(n,t))}commitBestOutsideInJoin(){const t=this.outsideInRouteSearch?.bestJoinedCandidate;return!!t\u0026\u0026(this.onPathFound(t),!0)}expandOutsideInFrontier(t){const e=this.outsideInRouteSearch,n=t?e.forward:e.reverse,o=this.dequeueFreshCandidate(n);if(!o)return!1;if(t?this.outsideInForwardExpansionCount+=1:this.outsideInReverseExpansionCount+=1,this.isRegionReservedForDifferentNet(o.nextRegionId))return!0;this.recordSettledCandidate(n,o),this.considerOutsideInJoins(o,t);for(const t of this.topology.regionIncidentPorts[o.nextRegionId]??[]){if(t===o.portId)continue;if(this.isPortReservedForDifferentNet(t))continue;const i=this.state.portAssignment[t];if(-1!==i\u0026\u0026i!==this.state.currentRouteNetId)continue;if(t!==n.targetPortId\u0026\u00260===this.problem.portSectionMask[t])continue;const r=this.topology.portX[o.portId]-this.topology.portX[t],s=this.topology.portY[o.portId]-this.topology.portY[t],a=Math.sqrt(r*r+s*s),c=o.travelDistance+a;if(c\u003ethis.OUTSIDE_IN_MAX_DISTANCE){e.distanceLimitHit=!0,this.outsideInDistancePruneCount+=1;continue}const l=this.topology.incidentPortRegion[t]?.[0]===o.nextRegionId?this.topology.incidentPortRegion[t]?.[1]:this.topology.incidentPortRegion[t]?.[0];if(void 0===l||this.isRegionReservedForDifferentNet(l))continue;const d=this.getHopId(t,l),h=n.bestCostByHopId.get(d)??1/0;if(o.g\u003e=h)continue;const u=this.computeG(o,t,h,a);if(!Number.isFinite(u)||u\u003e=h)continue;n.bestCostByHopId.set(d,u);const p=this.topology.portX[t]-this.topology.portX[n.targetPortId],m=this.topology.portY[t]-this.topology.portY[n.targetPortId],g=Math.sqrt(p*p+m*m)*this.DISTANCE_TO_COST;n.queue.queue({portId:t,prevRegionId:o.nextRegionId,nextRegionId:l,prevCandidate:o,f:u+g,g:u,h:g,travelDistance:c})}return!0}fallBackToOneSidedRouteSearch(){const t=this.state.currentRouteId;void 0!==t\u0026\u0026(this.outsideInRouteSearch=void 0,this.outsideInFallbackRouteCount+=1,this.oneSidedFallbackRouteId=t,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.goalPortId=-1,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.unroutedRoutes.unshift(t),this.publishOutsideInStats())}_step(){if(!this.OUTSIDE_IN_ROUTING)return void super._step();const t=this.state.currentRouteId??this.state.unroutedRoutes[0];if(void 0!==t\u0026\u0026!this.partialRipRoutePlans.has(t))return void super._step();if(void 0!==this.oneSidedFallbackRouteId)return void super._step();if(void 0===this.state.currentRouteId){if(0===this.state.unroutedRoutes.length)return void this.onAllRoutesRouted();const t=this.state.unroutedRoutes.shift();if(this.state.currentRouteId=t,this.state.currentRouteNetId=this.problem.routeNet[t],this.routeAttemptCountByRouteId[t]+=1,!this.startOutsideInRouteSearch(t))return this.failed=!0,void(this.error=`Route ${t} has an endpoint without an incident region`)}const e=this.outsideInRouteSearch;if(!e)return;let n=this.expandOutsideInFrontier(e.expandForwardNext);if(void 0!==this.state.currentRouteId\u0026\u0026(n||(n=this.expandOutsideInFrontier(!e.expandForwardNext),void 0!==this.state.currentRouteId)))if(e.expandForwardNext=!e.expandForwardNext,e.bestJoinedCandidate\u0026\u0026(e.remainingPostMeetingExpansions=(e.remainingPostMeetingExpansions??1)-1,(e.remainingPostMeetingExpansions??0)\u003c=0))this.commitBestOutsideInJoin();else{if(!n\u0026\u00260===e.forward.queue.length\u0026\u00260===e.reverse.queue.length){if(this.commitBestOutsideInJoin())return;this.outsideInRouteSearch=void 0,e.distanceLimitHit?this.fallBackToOneSidedRouteSearch():this.onOutOfCandidates()}this.publishOutsideInStats()}}shouldReplaceBestSolvedState(t){const e=this.bestSolvedRoundSummary;if(!e)return!0;if(!this.useComplexityAwareSelection)return this.compareRegionCostSummaries(t,e)\u003c0;const n=this.partialRipQualityBaselineSummary;if(!n)return this.compareRegionCostSummaries(t,e)\u003c0;const o=this.firstCompletedRoundSummary??n,i=o.maxRegionCost*(1+Math.max(0,this.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO)),r=o.totalRegionCost*(1+Math.max(0,this.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO)),s=t.maxRegionCost\u003c=i\u0026\u0026t.totalRegionCost\u003c=r;return s!==(e.maxRegionCost\u003c=i\u0026\u0026e.totalRegionCost\u003c=r)?s:s\u0026\u0026t.segmentCount!==e.segmentCount?t.segmentCount\u003ce.segmentCount:this.compareRegionCostSummaries(t,e)\u003c0}onAllRoutesRouted(){if(!this.PARTIAL_RIP_ENABLED)return void super.onAllRoutesRouted();const{state:t,topology:e}=this,n=Math.min(this.RIP_THRESHOLD_RAMP_ATTEMPTS,this.PARTIAL_RIP_MAX_ATTEMPTS),o=Math.max(0,this.RIP_THRESHOLD_RAMP_ATTEMPTS),i=o\u003c=0?1:Math.min(1,t.ripCount/o),r=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*i,s=new Float64Array(e.regionCount),a=[];let c=0,l=0,d=0,h=0,u=0;for(let n=0;n\u003ce.regionCount;n++){const e=t.regionIntersectionCaches[n]?.existingRegionCost??0;s[n]=e,c=Math.max(c,e),l+=e;const o=t.regionSegments[n]?.length??0;d+=o,h=Math.max(h,o),u+=o*o,e\u003er\u0026\u0026a.push(n)}const p={maxRegionCost:c,totalRegionCost:l},m={...p,ripCount:t.ripCount,segmentCount:d,maxRegionSegmentCount:h,squaredRegionSegmentCount:u};this.completedRoundSummaries.push(m),this.firstCompletedRoundSummary??=m,void 0===this.partialRipQualityBaselineSummary\u0026\u0026t.ripCount\u003e=Math.max(0,this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS)\u0026\u0026(this.partialRipQualityBaselineSummary=m);this.shouldReplaceBestSolvedState(m)\u0026\u0026(this.replaceBestSolvedState(p),this.bestSolvedRoundSummary=m);const g=this.firstCompletedRoundSummary,f=this.partialRipQualityBaselineSummary??g,y=Math.max(0,this.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO),_=Math.max(0,this.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO),b=f.maxRegionCost*(1-y),x=f.totalRegionCost*(1+_),v=this.useComplexityAwareSelection\u0026\u0026t.ripCount\u003ef.ripCount\u0026\u0026y\u003e0\u0026\u0026c\u003c=b\u0026\u0026l\u003c=x\u0026\u0026d\u003c=f.segmentCount;if(v\u0026\u0026(this.partialRipTargetReached=!0),this.stats={...this.stats,currentRipThreshold:r,hotRegionCount:a.length,maxRegionCost:c,totalRegionCost:l,bestMaxRegionCost:this.bestSolvedStateSummary?.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary?.totalRegionCost,ripCount:t.ripCount,completedRoundSummaries:this.completedRoundSummaries.map(t=\u003e({...t})),firstMaxRegionCost:g.maxRegionCost,firstTotalRegionCost:g.totalRegionCost,firstSegmentCount:g.segmentCount,firstMaxRegionSegmentCount:g.maxRegionSegmentCount,firstSquaredRegionSegmentCount:g.squaredRegionSegmentCount,partialRipQualityBaselineRipCount:f.ripCount,partialRipQualityBaselineMaxRegionCost:f.maxRegionCost,partialRipQualityBaselineTotalRegionCost:f.totalRegionCost,partialRipQualityBaselineSegmentCount:f.segmentCount,partialRipQualityBaselineMaxRegionSegmentCount:f.maxRegionSegmentCount,partialRipQualityBaselineSquaredRegionSegmentCount:f.squaredRegionSegmentCount,bestSolvedSegmentCount:this.bestSolvedRoundSummary?.segmentCount,bestSolvedMaxRegionSegmentCount:this.bestSolvedRoundSummary?.maxRegionSegmentCount,bestSolvedSquaredRegionSegmentCount:this.bestSolvedRoundSummary?.squaredRegionSegmentCount,partialRipTargetMaxRegionCost:b,partialRipMaxTargetTotalRegionCost:x,partialRipComplexityAwareSelection:this.useComplexityAwareSelection,partialRipComplexitySelectionMinRouteCount:this.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT,partialRipMaxRegionCostGrowthRatio:this.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO,partialRipTargetReached:this.partialRipTargetReached},this.publishPartialRipStats(),0===a.length||v||t.ripCount\u003e=n)return this.restoreBestSolvedState(),void(this.solved=!0);for(let n=0;n\u003ce.regionCount;n++)t.regionCongestionCost[n]+=s[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;const S=t.ripCount\u003cMath.max(0,this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS);t.ripCount+=1;const I=!S\u0026\u0026this.preparePartialRip(a,s);I||this.resetRoutingStateForRerip();const C=S?\"warmup_full\":I?\"partial\":\"full_fallback\";this.stats={...this.stats,ripCount:t.ripCount,maxRegionCostBeforeRip:c,reripRegionCount:a.length,reripMode:C,partialRipWarmupFullRipAttempts:this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS},this.logRipEvent(\"hot_regions\",c,{hotRegionCount:a.length,currentRipThreshold:r,reripMode:C,partialRouteCount:I?this.partialRipRoutePlans.size:0})}},cB=t=\u003e{const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;return Number.isFinite(e)?e:void 0},lB=t=\u003e{const e=new Set;for(const n of t.connections??[])e.add(n.startRegionId),e.add(n.endRegionId);const n=new Set(t.regions.filter(t=\u003e(t=\u003e{if(!0!==t.d?._containsObstacle)return!1;const e=cB(t);return void 0===e||-1===e})(t)\u0026\u0026!e.has(t.regionId)).map(t=\u003et.regionId));if(0===n.size)return t;const o=t.ports.filter(t=\u003e!n.has(t.region1Id)\u0026\u0026!n.has(t.region2Id)),i=(t.connections??[]).find(t=\u003en.has(t.startRegionId)||n.has(t.endRegionId));if(i)throw new Error(`Connection \"${i.connectionId}\" references full-obstacle region`);return{...t,regions:t.regions.filter(t=\u003e!n.has(t.regionId)),ports:o}},dB=t=\u003e{const e=t.d?.bounds;if(e)return e;const n=t.d?.center,o=t.d?.width,i=t.d?.height;return n\u0026\u0026\"number\"==typeof n.x\u0026\u0026\"number\"==typeof n.y\u0026\u0026\"number\"==typeof o\u0026\u0026\"number\"==typeof i?{minX:n.x-o/2,maxX:n.x+o/2,minY:n.y-i/2,maxY:n.y+i/2}:{minX:0,maxX:0,minY:0,maxY:0}},hB=t=\u003eNumber(t.d?.x??0),uB=t=\u003eNumber(t.d?.y??0),pB=(t,e)=\u003e{if(!e)return 0;const n=dB(e),o=hB(t),i=uB(t),r=n.minX\u003c=o\u0026\u0026o\u003c=n.maxX,s=n.minY\u003c=i\u0026\u0026i\u003c=n.maxY;if(s\u0026\u0026o\u003e=n.maxX){const t=Math.max(n.maxY-n.minY,1e-9),e=(i-n.minY)/t;return Math.round(9e3*e)}if(r\u0026\u0026i\u003e=n.maxY){const t=Math.max(n.maxX-n.minX,1e-9),e=(n.maxX-o)/t;return 9e3+Math.round(9e3*e)}if(s\u0026\u0026o\u003c=n.minX){const t=Math.max(n.maxY-n.minY,1e-9),e=(n.maxY-i)/t;return 18e3+Math.round(9e3*e)}if(r\u0026\u0026i\u003c=n.minY){const t=Math.max(n.maxX-n.minX,1e-9),e=(o-n.minX)/t;return 27e3+Math.round(9e3*e)}const a=Math.abs(o-n.minX),c=Math.abs(o-n.maxX),l=Math.abs(i-n.minY),d=Math.abs(i-n.maxY),h=Math.min(a,c,l,d),u=Math.max(n.maxX-n.minX,1e-9),p=Math.max(n.maxY-n.minY,1e-9);if(h===c){const t=(i-n.minY)/p;return Math.round(9e3*t)}if(h===d){const t=(n.maxX-o)/u;return 9e3+Math.round(9e3*t)}if(h===a){const t=(n.maxY-i)/p;return 18e3+Math.round(9e3*t)}const m=(o-n.minX)/u;return 27e3+Math.round(9e3*m)},mB=(t,e)=\u003e{if(!t)return;return[...t.pointIds].sort((t,n)=\u003e{const o=e.get(t),i=e.get(n),r=Number(o?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY),s=Number(i?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY);if(r!==s)return r-s;const a=Number(o?.d?.z??0),c=Number(i?.d?.z??0);return a!==c?a-c:t.localeCompare(n)})[0]},gB=t=\u003e{const e=lB(t),n=new Map,o=new Map,i=new Map,r=new Map((e.solvedRoutes??[]).map(t=\u003e[t.connection.connectionId,t]));e.regions.forEach((t,e)=\u003e{n.set(t.regionId,e)}),e.ports.forEach((t,e)=\u003e{o.set(t.portId,e),i.set(t.portId,t)});const s=e.regions.length,a=e.ports.length,c=e.regions.map(t=\u003et.pointIds.map(t=\u003eo.get(t)).filter(t=\u003evoid 0!==t)),l=Array.from({length:a},()=\u003e[]),d=new Float64Array(s),h=new Float64Array(s),u=new Float64Array(s),p=new Float64Array(s),m=new Int32Array(s),g=new Int32Array(s).fill(-1),f=new Int8Array(s);e.regions.forEach((t,e)=\u003e{const n=(t=\u003e{const e=dB(t),n=\"number\"==typeof t.d?.width?t.d.width:e.maxX-e.minX,o=\"number\"==typeof t.d?.height?t.d.height:e.maxY-e.minY;return{centerX:\"number\"==typeof t.d?.center?.x?t.d.center.x:(e.minX+e.maxX)/2,centerY:\"number\"==typeof t.d?.center?.y?t.d.center.y:(e.minY+e.maxY)/2,width:n,height:o}})(t);d[e]=n.width,h[e]=n.height,u[e]=n.centerX,p[e]=n.centerY,m[e]=(t=\u003e{const e=t.d?.availableZ;if(!Array.isArray(e))return 0;let n=0;for(const t of e)!Number.isInteger(t)||t\u003c0||t\u003e=31||(n|=1\u003c\u003ct);return n})(t);const o=cB(t);void 0!==o\u0026\u0026(g[e]=o,f[e]=1)});const y=new Int32Array(a),_=new Int32Array(a),b=new Float64Array(a),x=new Float64Array(a),v=new Int32Array(a);e.ports.forEach((t,o)=\u003e{const i=n.get(t.region1Id),r=n.get(t.region2Id);if(void 0===i||void 0===r)throw new Error(`Port \"${t.portId}\" references missing regions \"${t.region1Id}\" or \"${t.region2Id}\"`);l[o]=[i,r],b[o]=hB(t),x[o]=uB(t),v[o]=(t=\u003e{const e=Number(t.d?.z??0);return Number.isFinite(e)?e:0})(t),y[o]=pB(t,e.regions[i]),_[o]=pB(t,e.regions[r])});const S=e.regions.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedRegionId\",{value:t.regionId,enumerable:!1,configurable:!0,writable:!0}),n})(t,(t=\u003eRz(Ez(m[t]))??Rz((c[t]??[]).map(t=\u003ev[t]))??\"z0\")(e))),I=e.ports.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedPortId\",{value:t.portId,enumerable:!1,configurable:!0,writable:!0}),n})(t,Rz([v[e]])??\"z0\")),C=e.connections??[],P=new Map;let M=0;const N=t=\u003e{const e=t.mutuallyConnectedNetworkId??t.connectionId;let n=P.get(e);return void 0===n\u0026\u0026(n=M++,P.set(e,n)),n},w=Array.from({length:s},()=\u003enew Set),T=(t,e)=\u003e{const o=n.get(t);if(void 0===o)throw new Error(`Connection references missing region \"${t}\"`);w[o].add(e)};C.forEach(t=\u003e{const e=N(t);T(t.startRegionId,e),T(t.endRegionId,e)}),w.forEach((t,e)=\u003e{1!==f[e]\u0026\u00261===t.size\u0026\u0026(g[e]=[...t][0])});const R=C.map(t=\u003e{const n=r.get(t.connectionId),o=((t,e)=\u003et.ports.filter(t=\u003et.region1Id===e.startRegionId\u0026\u0026t.region2Id===e.endRegionId||t.region2Id===e.startRegionId\u0026\u0026t.region1Id===e.endRegionId).map(t=\u003et.portId))(e,t);return{connection:t,solvedRoute:n,sharedPortIds:o}}).filter(({solvedRoute:t,sharedPortIds:e})=\u003e0===e.length||(t?.path.length??0)\u003e1),E=R.length,A=new Map(R.map(({connection:t},e)=\u003e[t.connectionId,e])),O=new Int8Array(a).fill(1),k=new Int32Array(E),L=new Int32Array(E),D=new Int32Array(E);R.forEach(({connection:t,solvedRoute:n},r)=\u003e{const s=mB(e.regions.find(e=\u003ee.regionId===t.startRegionId),i),a=mB(e.regions.find(e=\u003ee.regionId===t.endRegionId),i),c=n?.path[0]?.portId??s,l=n?.path[n.path.length-1]?.portId??a,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)throw new Error(`Connection \"${t.connectionId}\" could not be mapped to route endpoints`);k[r]=d,L[r]=h,D[r]=N(t)});const z={portCount:a,regionCount:s,regionIncidentPorts:c,incidentPortRegion:l,regionWidth:d,regionHeight:h,regionCenterX:u,regionCenterY:p,regionAvailableZMask:m,regionMetadata:S,portAngleForRegion1:y,portAngleForRegion2:_,portX:b,portY:x,portZ:v,portMetadata:I},F=e.regions.flatMap((t,e)=\u003e(t.assignments??[]).map(n=\u003e{const i=A.get(n.connectionId);if(void 0===i)throw new Error(`Region \"${t.regionId}\" assignment references unknown routable connection \"${n.connectionId}\"`);const r=o.get(n.regionPort1Id),s=o.get(n.regionPort2Id);if(void 0===r||void 0===s)throw new Error(`Region \"${t.regionId}\" assignment references missing port \"${void 0===r?n.regionPort1Id:n.regionPort2Id}\"`);if(!c[e]?.includes(r)||!c[e]?.includes(s))throw new Error(`Region \"${t.regionId}\" assignment ports must both belong to the region`);return{routeId:i,regionId:e,fromPortId:r,toPortId:s}})),B=Float64Array.from(e.ports,t=\u003e{const e=Number(t.d?.tinyHypergraphPortPenalty??0);return Number.isFinite(e)\u0026\u0026e\u003e0?e:0}),j=B.some(t=\u003et\u003e0),$={routeCount:E,portSectionMask:O,routeMetadata:R.map(({connection:t})=\u003et),routeStartPort:k,routeEndPort:L,routeNet:D,regionNetId:g,...F.length\u003e0\u0026\u0026{initialAssignments:F},...j\u0026\u0026{portPenalty:B}},Y=[],X=[];for(const{solvedRoute:t}of R){if(!t){Y.push([]),X.push([]);continue}const e=[],i=[];for(let r=1;r\u003ct.path.length;r++){const s=t.path[r-1],a=t.path[r],c=s?.portId,l=a?.portId,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)continue;const u=\"string\"==typeof s?.nextRegionId?s.nextRegionId:\"string\"==typeof a?.lastRegionId?a.lastRegionId:void 0;e.push([d,h]),i.push(void 0!==u?n.get(u):void 0)}Y.push(e),X.push(i)}return{topology:z,problem:$,solution:{solvedRoutePathSegments:Y,solvedRoutePathRegionIds:X}}},fB=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,yB=t=\u003eArray.isArray(t)?t.map(t=\u003eyB(t)):fB(t)?Object.fromEntries(Object.entries(t).map(([t,e])=\u003e[t,yB(e)])):t,_B=t=\u003efB(t)?{...t}:void 0===t?{}:{value:t},bB=(t,e=0)=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)?t:e,xB=t=\u003e({x:bB(t.d?.x),y:bB(t.d?.y)}),vB=t=\u003e[t.region1Id,t.region2Id].sort().join(\"\\0\"),SB=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y),IB=t=\u003e{const e=Math.hypot(t.x,t.y);if(!(e\u003c=1e-9))return{x:t.x/e,y:t.y/e}},CB=t=\u003e{const e=t?.d?.center;if(fB(e))return{x:bB(e.x),y:bB(e.y)};const n=(t=\u003e{const e=t?.d?.bounds;if(fB(e)\u0026\u0026\"number\"==typeof e.minX\u0026\u0026\"number\"==typeof e.maxX\u0026\u0026\"number\"==typeof e.minY\u0026\u0026\"number\"==typeof e.maxY)return{minX:e.minX,maxX:e.maxX,minY:e.minY,maxY:e.maxY};const n=t?.d?.center,o=bB(t?.d?.width),i=bB(t?.d?.height);if(fB(n)){const t=bB(n.x),e=bB(n.y);return{minX:t-o/2,maxX:t+o/2,minY:e-i/2,maxY:e+i/2}}return{minX:0,maxX:0,minY:0,maxY:0}})(t);return{x:(n.minX+n.maxX)/2,y:(n.minY+n.maxY)/2}},PB=(t,e)=\u003e{const n=vB(t),o=xB(t);let i,r=Number.POSITIVE_INFINITY;for(const s of e){if(s.portId===t.portId)continue;if(vB(s)!==n)continue;const e=SB(o,xB(s));e\u003c=1e-9||e\u003e=r||(i=s,r=e)}return i},MB=(t,e,n)=\u003e{const o=xB(t);if(e){const t=xB(e),n=IB({x:o.x-t.x,y:o.y-t.y});if(n)return n}return((t,e)=\u003e{const n=CB(e.get(t.region1Id)),o=CB(e.get(t.region2Id));return IB({x:-(o.y-n.y),y:o.x-n.x})??{x:1,y:0}})(t,n)},NB=(t,e,n)=\u003e{const o=`${t}::dup${e}`;if(!n.has(o))return n.add(o),o;for(let t=2;;t++){const e=`${o}-${t}`;if(!n.has(e))return n.add(e),e}},wB=(t,e,n)=\u003e{const o=t.indexOf(e);-1!==o?t.splice(o+1,0,...n):t.push(...n)},TB=(t,e)=\u003e{const n=t.portMetadata?.[e];if(fB(n)){if(\"string\"==typeof n.serializedPortId)return n.serializedPortId;if(\"string\"==typeof n.portId)return n.portId}return`port-${e}`},RB=(t,e)=\u003e({routeCount:1,portSectionMask:new Int8Array(t.portSectionMask),routeMetadata:void 0===t.routeMetadata?void 0:[t.routeMetadata[e]],routeStartPort:Int32Array.from([t.routeStartPort[e]]),routeEndPort:Int32Array.from([t.routeEndPort[e]]),routeNet:Int32Array.from([t.routeNet[e]]),regionNetId:new Int32Array(t.regionNetId),portPenalty:void 0===t.portPenalty?void 0:new Float64Array(t.portPenalty)}),EB=t=\u003e{const e=new Set;for(const n of t.state.regionSegments)for(const[,t,o]of n)e.add(t),e.add(o);return 0===e.size\u0026\u00261===t.problem.routeCount\u0026\u0026(e.add(t.problem.routeStartPort[0]),e.add(t.problem.routeEndPort[0])),e},AB=class extends kt{constructor(t,e={}){super(),this.serializedHyperGraph=t,this.options=e}serializedHyperGraph;options;revisedSerializedHyperGraph;report={portUseCounts:{},duplicatedPorts:[]};getDuplicatePortProximity(){return this.options.duplicatePortProximity??.05}getIndividualRouteSolveOptions(){return{RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!1,...this.options.routeSolveOptions}}getPortUseCounts(){const{topology:t,problem:e}=gB(this.serializedHyperGraph);!1===this.options.useSerializedPortPenalties\u0026\u0026(e.portPenalty=void 0);const n=new Map;for(let o=0;o\u003ce.routeCount;o++){const i=RB(e,o),r=new nB(t,i,this.getIndividualRouteSolveOptions());if(r.solve(),!r.solved||r.failed)throw new Error(`Route ${o} could not be solved independently: ${r.error??\"unknown error\"}`);for(const e of EB(r)){const o=TB(t,e);n.set(o,(n.get(o)??0)+1)}}return n}duplicateCongestedPorts(t){const e=this.getDuplicatePortProximity();if(!(e\u003e0))throw new Error(\"duplicatePortProximity must be greater than zero\");const{solvedRoutes:n,...o}=this.serializedHyperGraph,i=this.serializedHyperGraph.regions.map(t=\u003e({...t,pointIds:[...t.pointIds],d:yB(t.d)})),r=this.serializedHyperGraph.ports.map(t=\u003e({...t,d:yB(t.d)})),s=new Map(i.map(t=\u003e[t.regionId,t])),a=new Map(r.map(t=\u003e[t.portId,t])),c=new Set(r.map(t=\u003et.portId)),l=[];for(const[n,o]of[...t.entries()].sort(([t],[e])=\u003et.localeCompare(e))){if(o\u003c=1)continue;const t=a.get(n);if(!t)continue;const i=o-1,d=PB(t,this.serializedHyperGraph.ports),h=MB(t,d,s),u=xB(t),p=[];for(let s=1;s\u003c=i;s++){const a=NB(n,s,c),l=e*s/(i+1),d=_B(yB(t.d));d.x=u.x+h.x*l,d.y=u.y+h.y*l,d.duplicatedFromPortId=n,d.duplicateIndex=s,d.duplicatePortUseCount=o,d.duplicatePortProximity=e,d.repairReason=\"congested-port\",r.push({...t,portId:a,d:d}),p.push(a)}for(const e of[t.region1Id,t.region2Id]){const t=s.get(e);t\u0026\u0026wB(t.pointIds,n,p)}l.push({sourcePortId:n,duplicatePortIds:p,useCount:o})}return this.report={portUseCounts:Object.fromEntries([...t.entries()].sort()),duplicatedPorts:l},{...o,regions:i,ports:r,connections:void 0===this.serializedHyperGraph.connections?void 0:yB(this.serializedHyperGraph.connections)}}_setup(){try{const t=this.getPortUseCounts();this.revisedSerializedHyperGraph=this.duplicateCongestedPorts(t),this.stats={...this.stats,duplicateSourcePortCount:this.report.duplicatedPorts.length,duplicatedPortCount:this.report.duplicatedPorts.reduce((t,e)=\u003et+e.duplicatePortIds.length,0)},this.solved=!0}catch(t){this.failed=!0,this.error=t instanceof Error?t.message:String(t)}}_step(){this.failed||(this.solved=!0)}getOutput(){if(!this.revisedSerializedHyperGraph||this.failed)throw new Error(\"DuplicateCongestedPortSolver does not have a repaired topology output\");return this.revisedSerializedHyperGraph}},OB=(t,e)=\u003e{const n=t.owners.size-e.owners.size;if(0!==n)return n;const o=t.distance-e.distance;return 0!==o?o:t.queueOrder-e.queueOrder},kB=class{heap=[];push(t){this.heap.push(t);let e=this.heap.length-1;for(;e\u003e0;){const t=Math.floor((e-1)/2);if(OB(this.heap[t],this.heap[e])\u003c=0)break;[this.heap[t],this.heap[e]]=[this.heap[e],this.heap[t]],e=t}}pop(){const t=this.heap[0],e=this.heap.pop();if(!t||!e)return null;if(0===this.heap.length)return t;this.heap[0]=e;let n=0;for(;;){const t=2*n+1,e=t+1;let o=n;if(t\u003cthis.heap.length\u0026\u0026OB(this.heap[t],this.heap[o])\u003c0\u0026\u0026(o=t),e\u003cthis.heap.length\u0026\u0026OB(this.heap[e],this.heap[o])\u003c0\u0026\u0026(o=e),o===n)break;[this.heap[n],this.heap[o]]=[this.heap[o],this.heap[n]],n=o}return t}},LB=(t,e)=\u003e!(t.distance\u003ee.distance)\u0026\u0026((t,e)=\u003e{if(t.size\u003ee.size)return!1;for(const n of t)if(!e.has(n))return!1;return!0})(t.owners,e.owners),DB=(t,e)=\u003e{const n=[],o=[];let i=t;for(;null!==i;)n.push(i.state),null!==i.incomingHop\u0026\u0026o.push(i.incomingHop),i=i.parent;return n.reverse(),o.reverse(),{found:!0,states:n,hops:o,owners:new Set(t.owners),distance:t.distance,expandedLabelCount:e}},zB=t=\u003e{for(;;){const e=t.pop();if(null===e)return null;if(e.active)return e}},FB=(t,e)=\u003e{QF(t,e),e\u0026\u0026(void 0!==e.MAX_RIPS\u0026\u0026(t.MAX_RIPS=e.MAX_RIPS),void 0!==e.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT\u0026\u0026(t.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=e.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT),void 0!==e.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST\u0026\u0026(t.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=e.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST))},BB=t=\u003et.map(t=\u003et.map(([t,e,n])=\u003e[t,e,n])),jB=t=\u003e({netIds:new Int32Array(t.netIds),lesserAngles:new Int32Array(t.lesserAngles),greaterAngles:new Int32Array(t.greaterAngles),layerMasks:new Int32Array(t.layerMasks),existingCrossingLayerIntersections:t.existingCrossingLayerIntersections,existingSameLayerIntersections:t.existingSameLayerIntersections,existingEntryExitLayerChanges:t.existingEntryExitLayerChanges,existingRegionCost:t.existingRegionCost,existingSegmentCount:t.existingSegmentCount}),$B=t=\u003e({portAssignment:new Int32Array(t.portAssignment),regionSegments:BB(t.regionSegments),regionIntersectionCaches:t.regionIntersectionCaches.map(jB)}),YB=(t,e)=\u003e{const n=$B(e);t.state.portAssignment=n.portAssignment,t.state.regionSegments=n.regionSegments,t.state.regionIntersectionCaches=n.regionIntersectionCaches},XB=t=\u003e{let e=0,n=0;for(let o=0;o\u003ct.length;o++){const i=t[o]?.existingRegionCost??0;e=Math.max(e,i),n+=i}return{maxRegionCost:e,totalRegionCost:n}},VB=(t,e)=\u003et.maxRegionCost!==e.maxRegionCost?t.maxRegionCost-e.maxRegionCost:t.totalRegionCost-e.totalRegionCost,WB=(t,e,n)=\u003e{const o=t.incidentPortRegion[e]??[],i=t.incidentPortRegion[n]??[],r=o.find(t=\u003ei.includes(t));if(void 0===r)throw new Error(`Ports ${e} and ${n} do not share a region`);return r},HB=(t,e,n,o)=\u003e{const i=n.solvedRoutePathSegments[o]??[],r=n.solvedRoutePathRegionIds?.[o]??[],s=e.routeStartPort[o],a=e.routeEndPort[o];if(0===i.length){if(s===a)return{orderedPortIds:[s],orderedRegionIds:[]};throw new Error(`Route ${o} does not have an existing solved path`)}const c=new Map;i.forEach(([t,e],n)=\u003e{const o={segmentIndex:n,fromPortId:t,toPortId:e,regionId:r[n]},i=c.get(t)??[];i.push(o),c.set(t,i);const s=c.get(e)??[];s.push(o),c.set(e,s)});const l=[s],d=[],h=new Set;let u,p=s;for(;p!==a;){const e=(c.get(p)??[]).filter(({segmentIndex:t,fromPortId:e,toPortId:n})=\u003e{if(h.has(t))return!1;return(e===p?n:e)!==u});if(1!==e.length)throw new Error(`Route ${o} is not a single ordered path from ${s} to ${a}`);const n=e[0],i=n.fromPortId===p?n.toPortId:n.fromPortId;h.add(n.segmentIndex),d.push(n.regionId??WB(t,n.fromPortId,n.toPortId)),l.push(i),u=p,p=i}if(h.size!==i.length)throw new Error(`Route ${o} contains disconnected solved segments`);return{orderedPortIds:l,orderedRegionIds:d}},GB=(t,e,n,o)=\u003e{const i=new nB(t,e,o);return((t,e)=\u003e{t.state.portAssignment.fill(-1),t.state.regionSegments=Array.from({length:t.topology.regionCount},()=\u003e[]),t.state.regionIntersectionCaches=Array.from({length:t.topology.regionCount},()=\u003eqF()),t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.state.unroutedRoutes=[],t.state.candidateQueue.clear(),t.resetCandidateBestCosts(),t.state.goalPortId=-1,t.state.ripCount=0,t.state.regionCongestionCost.fill(0);for(let n=0;n\u003ce.length;n++)for(const[o,i,r]of e[n]??[])t.state.currentRouteNetId=t.problem.routeNet[o],t.state.regionSegments[n].push([o,i,r]),t.state.portAssignment[i]=t.state.currentRouteNetId,t.state.portAssignment[r]=t.state.currentRouteNetId,t.appendSegmentToRegionCache(n,i,r);t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.solved=!0,t.failed=!1,t.error=null})(i,n),i},UB=(t,e,n)=\u003e{const o=new Int32Array(e.routeStartPort),i=new Int32Array(e.routeEndPort),r=Array.from({length:e.routeCount},(t,e)=\u003e({routeId:e,fixedSegments:[]})),s=[];for(let a=0;a\u003ce.routeCount;a++){const c=r[a],{orderedPortIds:l,orderedRegionIds:d}=HB(t,e,n,a),h=[];let u;for(let t=0;t\u003cl.length;t++){const n=l[t],o=1===e.portSectionMask[n];o\u0026\u0026void 0===u?u=t:o||void 0===u||(h.push({startIndex:u,endIndex:t-1}),u=void 0)}if(void 0!==u\u0026\u0026h.push({startIndex:u,endIndex:l.length-1}),0===h.length){for(let t=1;t\u003cl.length;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});continue}if(h.length\u003e1)throw new Error(`Route ${a} enters the section multiple times; only one contiguous section span is currently supported`);const p=h[0],m=Math.max(0,p.startIndex-1),g=Math.min(l.length-1,p.endIndex+1);if(g\u003c=m)throw new Error(`Route ${a} does not have a valid section span`);for(let t=1;t\u003c=m;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});for(let t=g+1;t\u003cl.length;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});c.activeStartPortId=l[m],c.activeEndPortId=l[g],c.forcedStartRegionId=d[m],o[a]=c.activeStartPortId,i[a]=c.activeEndPortId,s.push(a)}return{sectionProblem:{routeCount:e.routeCount,portSectionMask:new Int8Array(e.portSectionMask),routeMetadata:e.routeMetadata,routeStartPort:o,routeEndPort:i,routeNet:new Int32Array(e.routeNet),regionNetId:new Int32Array(e.regionNetId),portPenalty:void 0===e.portPenalty?void 0:new Float64Array(e.portPenalty)},routePlans:r,activeRouteIds:s}},ZB=(t,e,n)=\u003eUB(t,e,n).activeRouteIds,qB=class extends nB{constructor(t,e,n,o,i,r,s,a){super(t,e,a),this.routePlans=n,this.activeRouteIds=o,this.mutableRegionIds=i,this.immutableRegionSummary=r,this.baselineSummary=s,FB(this,a),this.state.unroutedRoutes=[...o],this.applyFixedSegments(),this.fixedSnapshot=$B({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches})}routePlans;activeRouteIds;mutableRegionIds;immutableRegionSummary;baselineSummary;bestSnapshot;fixedSnapshot;bestSummary;baselineBeatRipCount;previousBestMaxRegionCost=Number.POSITIVE_INFINITY;ripsSinceBestMaxRegionCostImprovement=0;MAX_RIPS=Number.POSITIVE_INFINITY;MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=Number.POSITIVE_INFINITY;EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=Number.POSITIVE_INFINITY;applyFixedSegments(){for(const t of this.routePlans)for(const{regionId:e,fromPortId:n,toPortId:o}of t.fixedSegments)this.state.currentRouteNetId=this.problem.routeNet[t.routeId],this.state.regionSegments[e].push([t.routeId,n,o]),this.state.portAssignment[n]=this.state.currentRouteNetId,this.state.portAssignment[o]=this.state.currentRouteNetId,this.appendSegmentToRegionCache(e,n,o);this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0}captureBestState(t){this.bestSummary\u0026\u0026VB(t,this.bestSummary)\u003e=0||(this.bestSummary=t,this.bestSnapshot=$B({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches}))}restoreBestState(){this.bestSnapshot\u0026\u0026(YB(this,this.bestSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1)}getStartingNextRegionId(t,e){const n=this.routePlans[t]?.forcedStartRegionId;return void 0!==n?n:super.getStartingNextRegionId(t,e)}resetRoutingStateForRerip(){if(!this.fixedSnapshot)return super.resetRoutingStateForRerip(),this.state.unroutedRoutes=qz([...this.activeRouteIds],this.state.ripCount),void this.applyFixedSegments();YB(this,this.fixedSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=qz([...this.activeRouteIds],this.state.ripCount),this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1}onAllRoutesRouted(){const{state:t}=this,e=Math.min(this.MAX_RIPS,this.RIP_THRESHOLD_RAMP_ATTEMPTS),n=e\u003c=0?1:Math.min(1,t.ripCount/e),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(this.mutableRegionIds.length);let s=0,a=0;for(let e=0;e\u003cthis.mutableRegionIds.length;e++){const n=this.mutableRegionIds[e],c=t.regionIntersectionCaches[n]?.existingRegionCost??0;r[e]=c,s=Math.max(s,c),a+=c,c\u003eo\u0026\u0026i.push(n)}const c=Math.max(this.immutableRegionSummary.maxRegionCost,s),l=this.immutableRegionSummary.totalRegionCost+a;this.captureBestState({maxRegionCost:c,totalRegionCost:l});const d=this.bestSummary??{maxRegionCost:c,totalRegionCost:l};if(d.maxRegionCost\u003cthis.previousBestMaxRegionCost-Number.EPSILON?(this.previousBestMaxRegionCost=d.maxRegionCost,this.ripsSinceBestMaxRegionCostImprovement=0):this.ripsSinceBestMaxRegionCostImprovement+=1,void 0===this.baselineBeatRipCount\u0026\u0026d.maxRegionCost\u003cthis.baselineSummary.maxRegionCost-Number.EPSILON\u0026\u0026(this.baselineBeatRipCount=t.ripCount),this.stats={...this.stats,activeRouteCount:this.activeRouteIds.length,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:c,totalRegionCost:l,bestMaxRegionCost:d.maxRegionCost,bestTotalRegionCost:d.totalRegionCost,ripCount:t.ripCount},0===i.length||t.ripCount\u003e=e||this.ripsSinceBestMaxRegionCostImprovement\u003e=this.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT||void 0!==this.baselineBeatRipCount\u0026\u0026t.ripCount-this.baselineBeatRipCount\u003e=this.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST)return this.restoreBestState(),void(this.solved=!0);for(let e=0;e\u003cthis.mutableRegionIds.length;e++){const n=this.mutableRegionIds[e];t.regionCongestionCost[n]+=r[e]*this.RIP_CONGESTION_REGION_COST_FACTOR}t.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:t.ripCount,reripRegionCount:i.length}}onOutOfCandidates(){const{state:t}=this;for(const e of this.mutableRegionIds){const n=t.regionIntersectionCaches[e]?.existingRegionCost??0;t.regionCongestionCost[e]+=n*this.RIP_CONGESTION_REGION_COST_FACTOR}t.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:t.ripCount,reripReason:\"out_of_candidates\"}}tryFinalAcceptance(){if(this.bestSnapshot)return this.restoreBestState(),void(this.solved=!0);this.fixedSnapshot\u0026\u0026YB(this,this.fixedSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[...this.activeRouteIds],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.stats={...this.stats,acceptedFixedSectionStateOnTimeout:!0},this.solved=!0}visualize(){return UF(this,{highlightSectionMask:!0,showInitialRouteHints:!1,showOnlySectionPortsOnIdle:!0})}},JB=class extends kt{constructor(t,e,n,o){super(),this.topology=t,this.problem=e,this.initialSolution=n,FB(this,o),this.baselineSolver=((t,e,n,o)=\u003e{const i=Array.from({length:t.regionCount},()=\u003e[]);for(let o=0;o\u003ce.routeCount;o++){const{orderedPortIds:r,orderedRegionIds:s}=HB(t,e,n,o);for(let t=1;t\u003cr.length;t++){const e=r[t-1],n=r[t];i[s[t-1]].push([o,e,n])}}return GB(t,e,i,o)})(t,e,n,tB(this)),this.baselineSummary=XB(this.baselineSolver.state.regionIntersectionCaches),this.sectionRegionIds=((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ce.portSectionMask.length;o++)if(1===e.portSectionMask[o])for(const e of t.incidentPortRegion[o]??[])n.add(e);return[...n]})(t,e),this.sectionBaselineSummary=((t,e)=\u003e{let n=0,o=0;for(const i of e){const e=t[i]?.existingRegionCost??0;n=Math.max(n,e),o+=e}return{maxRegionCost:n,totalRegionCost:o}})(this.baselineSolver.state.regionIntersectionCaches,this.sectionRegionIds),this.outsideSectionBaselineSummary=((t,e)=\u003e{const n=new Set(e);let o=0,i=0;for(let e=0;e\u003ct.length;e++){if(n.has(e))continue;const r=t[e]?.existingRegionCost??0;o=Math.max(o,r),i+=r}return{maxRegionCost:o,totalRegionCost:i}})(this.baselineSolver.state.regionIntersectionCaches,this.sectionRegionIds),this.applySectionRipPolicy()}topology;problem;initialSolution;baselineSolver;baselineSummary;sectionBaselineSummary;outsideSectionBaselineSummary;sectionRegionIds;optimizedSolver;sectionSolver;activeRouteIds=[];DISTANCE_TO_COST=.05;minViaPadDiameter=Yz;VERBOSE=!1;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;MAX_RIPS=Number.POSITIVE_INFINITY;MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=10;EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=10;RIP_CONGESTION_REGION_COST_FACTOR=.1;MAX_ITERATIONS=1e6;STATIC_REACHABILITY_PRECHECK=!1;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;ACCEPT_BEST_SOLUTION_ON_TIMEOUT=!0;GREEDY_FINAL_ROUTE_ITERS=4;applySectionRipPolicy(){this.RIP_THRESHOLD_START=.05,this.RIP_THRESHOLD_END=Math.max(this.RIP_THRESHOLD_START,this.sectionBaselineSummary.maxRegionCost),this.MAX_RIPS=Math.min(this.MAX_RIPS,20)}_setup(){this.applySectionRipPolicy();const{sectionProblem:t,routePlans:e,activeRouteIds:n}=UB(this.topology,this.problem,this.initialSolution);if(this.activeRouteIds=n,0===n.length)return this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,activeRouteCount:0,initialMaxRegionCost:this.baselineSummary.maxRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,optimized:!1},void(this.solved=!0);var o;this.sectionSolver=new qB(this.topology,t,e,n,this.sectionRegionIds,this.outsideSectionBaselineSummary,this.baselineSummary,{...tB(o=this),MAX_RIPS:o.MAX_RIPS,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:o.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:o.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST}),this.activeSubSolver=this.sectionSolver,this.stats={...this.stats,sectionBaselineMaxRegionCost:this.sectionBaselineSummary.maxRegionCost,sectionBaselineTotalRegionCost:this.sectionBaselineSummary.totalRegionCost,effectiveRipThresholdStart:this.RIP_THRESHOLD_START,effectiveRipThresholdEnd:this.RIP_THRESHOLD_END,effectiveMaxRips:this.MAX_RIPS}}_step(){if(!this.sectionSolver)return void(this.solved=!0);if(this.sectionSolver.step(),this.stats={...this.stats,...this.sectionSolver.stats,activeRouteCount:this.activeRouteIds.length},this.sectionSolver.failed)return this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,finalTotalRegionCost:this.baselineSummary.totalRegionCost,optimized:!1,sectionSearchFailedFallbackToBaseline:!0,sectionSearchError:this.sectionSolver.error},void(this.solved=!0);if(!this.sectionSolver.solved)return;const t=GB(this.topology,this.problem,BB(this.sectionSolver.state.regionSegments),tB(this)),e=XB(t.state.regionIntersectionCaches),n=VB(e,this.baselineSummary)\u003c0;this.optimizedSolver=n?t:this.baselineSolver;const o=n?e:this.baselineSummary;this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,candidateMaxRegionCost:e.maxRegionCost,candidateTotalRegionCost:e.totalRegionCost,finalMaxRegionCost:o.maxRegionCost,finalTotalRegionCost:o.totalRegionCost,optimized:n},this.solved=!0}tryFinalAcceptance(){this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,finalTotalRegionCost:this.baselineSummary.totalRegionCost,optimized:!1,sectionSolverTimeoutFallbackToBaseline:!0},this.solved=!0,this.failed=!1,this.error=null}getSolvedSolver(){if(!this.solved||this.failed||!this.optimizedSolver)throw new Error(\"TinyHyperGraphSectionSolver does not have a solved output yet\");return this.optimizedSolver}visualize(){return this.optimizedSolver?UF(this.optimizedSolver,{highlightSectionMask:!0}):this.sectionSolver?this.sectionSolver.visualize():UF(this.baselineSolver,{highlightSectionMask:!0,showInitialRouteHints:!1,showOnlySectionPortsOnIdle:!0})}getOutput(){return this.getSolvedSolver().getOutput()}},KB=[\"self-touch\",\"onehop-all\",\"onehop-touch\",\"twohop-all\",\"twohop-touch\"],QB={\"self-all\":0,\"self-touch\":0,\"onehop-all\":1,\"onehop-touch\":1,\"twohop-all\":2,\"twohop-touch\":2,\"threehop-all\":3,\"threehop-touch\":3,\"fourhop-all\":4,\"fourhop-touch\":4},tj=(t,e)=\u003e{const n=new Set(e);for(const o of e)for(const e of t.regionIncidentPorts[o]??[])for(const o of t.incidentPortRegion[e]??[])n.add(o);return[...n]},ej=(t,e,n)=\u003e{let o=[...new Set(e)];for(let e=0;e\u003cn;e+=1)o=tj(t,o);return o},nj=(t,e,n)=\u003ee.flatMap(e=\u003en.map(n=\u003e((t,e,n)=\u003e({label:`hot-${e}-${n}`,family:n,regionIds:ej(t,[e],QB[n]),portSelectionRule:n.endsWith(\"-all\")?\"all-incident-regions-selected\":\"touches-selected-region\"}))(t,e,n))),oj={RIP_THRESHOLD_RAMP_ATTEMPTS:5},ij={DISTANCE_TO_COST:.05,RIP_THRESHOLD_RAMP_ATTEMPTS:16,RIP_CONGESTION_REGION_COST_FACTOR:.1,MAX_ITERATIONS:5e4,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:6,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:Number.POSITIVE_INFINITY},rj=t=\u003et.state.regionIntersectionCaches.reduce((t,e)=\u003eMath.max(t,e.existingRegionCost),0),sj=(t,e)=\u003e{const n=gB(t),o=new JB(n.topology,n.problem,n.solution,e);return rj(o.baselineSolver)},aj=(t,e,n)=\u003e{const o=new Set(e);return Int8Array.from({length:t.portCount},(e,i)=\u003e{const r=t.incidentPortRegion[i]??[];return\"touches-selected-region\"===n?r.some(t=\u003eo.has(t))?1:0:r.length\u003e0\u0026\u0026r.every(t=\u003eo.has(t))?1:0})},cj=(t,e)=\u003e({routeCount:t.routeCount,portSectionMask:e,routeMetadata:t.routeMetadata,routeStartPort:new Int32Array(t.routeStartPort),routeEndPort:new Int32Array(t.routeEndPort),routeNet:new Int32Array(t.routeNet),regionNetId:new Int32Array(t.regionNetId),portPenalty:void 0===t.portPenalty?void 0:new Float64Array(t.portPenalty)}),lj=(t,e,n,o,i,r)=\u003e{const s=performance.now(),a=performance.now(),c=new JB(e,n,o,r),l=rj(c.baselineSolver),d=performance.now()-a;let h,u,p=l,m=new Int8Array(e.portCount),g=0,f=0,y=0,_=0,b=0,x=0,v=0;const S=new Set,I=i?.maxHotRegions??r.MAX_HOT_REGIONS??2;for(const s of((t,e,n,o)=\u003e{const i=t.state.regionIntersectionCaches.map((t,e)=\u003e({regionId:e,regionCost:t.existingRegionCost})).filter(({regionCost:t})=\u003et\u003e0).sort((t,e)=\u003ee.regionCost-t.regionCost).slice(0,n).map(({regionId:t})=\u003et);return nj(e,i,o)})(t,e,I,i?.candidateFamilies??[...KB])){const t=cj(n,aj(e,s.regionIds,s.portSelectionRule));g+=1;const i=t.portSectionMask.join(\",\");if(S.has(i))y+=1;else{S.add(i);try{const n=performance.now(),i=ZB(e,t,o);if(_+=performance.now()-n,0===i.length)continue;f+=1;const a=performance.now(),c=new JB(e,t,o,r);b+=performance.now()-a;const l=performance.now();if(c.solve(),x+=performance.now()-l,c.failed||!c.solved)continue;if(Number(c.stats.finalMaxRegionCost??rj(c.getSolvedSolver()))\u003cp-1e-9){const e=performance.now(),n=sj(c.getOutput(),r);v+=performance.now()-e,n\u003cp-1e-9\u0026\u0026(p=n,m=new Int8Array(t.portSectionMask),h=s.label,u=s.family)}}catch{}}}return{portSectionMask:m,baselineMaxRegionCost:l,finalMaxRegionCost:p,generatedCandidateCount:g,candidateCount:f,duplicateCandidateCount:y,totalMs:performance.now()-s,baselineEvaluationMs:d,candidateEligibilityMs:_,candidateInitMs:b,candidateSolveMs:x,candidateReplayScoreMs:v,winningCandidateLabel:h,winningCandidateFamily:u}},dj=class extends Dt{initialVisualizationSolver;selectedSectionMask;selectedSectionCandidateLabel;selectedSectionCandidateFamily;constructor(t){super(t),this.MAX_ITERATIONS=2e5}loadHyperGraph(t){return gB(t)}getSolveGraphOptions(){return{...oj,...void 0===this.inputProblem.minViaPadDiameter?{}:{minViaPadDiameter:this.inputProblem.minViaPadDiameter},...this.inputProblem.solveGraphOptions}}getSectionSolverOptions(){return{...ij,...void 0===this.inputProblem.minViaPadDiameter?{}:{minViaPadDiameter:this.inputProblem.minViaPadDiameter},...this.inputProblem.sectionSolverOptions}}pipelineDef=[{solverName:\"solveGraph\",solverClass:nB,getConstructorParams:t=\u003e{const{topology:e,problem:n}=t.loadHyperGraph(t.inputProblem.serializedHyperGraph);return[e,n,t.getSolveGraphOptions()]}},{solverName:\"optimizeSection\",solverClass:JB,getConstructorParams:t=\u003et.getSectionStageParams()}];getSectionStageParams(){const t=this.getStageOutput(\"solveGraph\");if(!t)throw new Error(\"solveGraph did not produce a solved serialized hypergraph\");const e=this.getSolver(\"solveGraph\");if(!e)throw new Error(\"solveGraph solver is unavailable\");const n=this.getSectionSolverOptions(),{topology:o,problem:i,solution:r}=this.loadHyperGraph(t),s=this.inputProblem.createSectionMask?this.inputProblem.createSectionMask({serializedHyperGraph:this.inputProblem.serializedHyperGraph,solvedSerializedHyperGraph:t,solvedSolver:e,topology:o,problem:i,solution:r}):(()=\u003e{const t=lj(e,o,i,r,this.inputProblem.sectionSearchConfig,n);return this.selectedSectionCandidateLabel=t.winningCandidateLabel,this.selectedSectionCandidateFamily=t.winningCandidateFamily,this.stats={...this.stats,sectionSearchGeneratedCandidateCount:t.generatedCandidateCount,sectionSearchCandidateCount:t.candidateCount,sectionSearchDuplicateCandidateCount:t.duplicateCandidateCount,sectionSearchBaselineMaxRegionCost:t.baselineMaxRegionCost,sectionSearchFinalMaxRegionCost:t.finalMaxRegionCost,sectionSearchDelta:t.baselineMaxRegionCost-t.finalMaxRegionCost,selectedSectionCandidateLabel:t.winningCandidateLabel??null,selectedSectionCandidateFamily:t.winningCandidateFamily??null,sectionSearchMs:t.totalMs,sectionSearchBaselineEvaluationMs:t.baselineEvaluationMs,sectionSearchCandidateEligibilityMs:t.candidateEligibilityMs,sectionSearchCandidateInitMs:t.candidateInitMs,sectionSearchCandidateSolveMs:t.candidateSolveMs,sectionSearchCandidateReplayScoreMs:t.candidateReplayScoreMs},t.portSectionMask})();return this.selectedSectionMask=new Int8Array(s),i.portSectionMask=new Int8Array(s),this.stats={...this.stats,sectionMaskPortCount:[...s].filter(t=\u003e1===t).length},[o,i,r,n]}getInitialVisualizationSolver(){if(!this.initialVisualizationSolver){const{topology:t,problem:e}=this.loadHyperGraph(this.inputProblem.serializedHyperGraph);this.initialVisualizationSolver=new nB(t,e,this.getSolveGraphOptions())}return this.initialVisualizationSolver}initialVisualize(){return this.getInitialVisualizationSolver().visualize()}visualize(){return 0===this.iterations?this.initialVisualize()??super.visualize():super.visualize()}getOutput(){return this.getStageOutput(\"optimizeSection\")??this.getStageOutput(\"solveGraph\")??null}tryFinalAcceptance(){this.getStageOutput(\"solveGraph\")\u0026\u0026(this.stats={...this.stats,acceptedSolveGraphOutputOnSectionPipelineTimeout:!0},this.activeSubSolver=void 0,this.solved=!0,this.failed=!1,this.error=null)}};var hj=class extends aB{failedOwnerPairCounts=new Map;selectiveReripStats={selectiveRipCount:0,selectivelyRippedRouteCount:0,globalReripCount:0,alternateBlockerSearchCount:0,alternateOwnerCount:0,failedOwnerPairCount:0,maxFailedOwnerPairCount:0,failedOwnerPairs:[],lastDirectOwnerRouteIds:[],lastRepeatedOwnerRouteIds:[],lastAlternateOwnerRouteIds:[],lastRippedRouteIds:[],lastRelaxedSearchExpandedLabelCount:0,lastAlternateSearchExpandedLabelCount:0};selectiveReripCongestionUpdateCount=0;constructor(t,e,n){super(t,e,n)}getSelectiveReripStats(){return{...this.selectiveReripStats,failedOwnerPairs:this.selectiveReripStats.failedOwnerPairs.map(t=\u003e({...t})),lastDirectOwnerRouteIds:[...this.selectiveReripStats.lastDirectOwnerRouteIds],lastRepeatedOwnerRouteIds:[...this.selectiveReripStats.lastRepeatedOwnerRouteIds],lastAlternateOwnerRouteIds:[...this.selectiveReripStats.lastAlternateOwnerRouteIds],lastRippedRouteIds:[...this.selectiveReripStats.lastRippedRouteIds]}}onOutOfCandidates(){const t=this.state.currentRouteId;if(void 0===t)throw new Error(\"SelectiveReripTinyHyperGraphSolver: candidate search exhausted without a current route\");const e=this.findRelaxedBlockerPathPreferringPreservedRoutes();if(!e.found||0===e.owners.size)return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=e.found?\"no_blocker_path\":e.reason,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=[],this.selectiveReripStats.lastRepeatedOwnerRouteIds=[],this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=0,super.onOutOfCandidates(),void this.publishSelectiveReripStats();const n=[...e.owners],o=[];for(const e of n){this.incrementFailedOwnerPair(t,e)\u003e=2\u0026\u0026o.push(e)}if(n.some(e=\u003ethis.hasFailedOwnerPath(e,t)))return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=\"failed_owner_cycle\",this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=0,this.failedOwnerPairCounts.clear(),super.onOutOfCandidates(),void this.publishSelectiveReripStats();let i;if(o.length\u003e0\u0026\u0026(this.selectiveReripStats.alternateBlockerSearchCount+=1,i=this.findRelaxedBlockerPathPreferringPreservedRoutes(new Set(o)),!i.found))return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=i.reason,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=i.expandedLabelCount,super.onOutOfCandidates(),void this.publishSelectiveReripStats();const r=i?.found?[...i.owners]:void 0,s=function(t){const e=new Set(t.alternateOwnerRouteIds??t.directOwnerRouteIds);if(e.delete(t.failedRouteId),0===e.size)throw new Error(`SelectiveReripTinyHyperGraphSolver: route ${t.failedRouteId} has blocker resources but no distinct committed owner can be reripped`);return e}({failedRouteId:t,directOwnerRouteIds:n,alternateOwnerRouteIds:r});this.clearPartialRipPlans(s);const a=(r??[]).filter(t=\u003e!e.owners.has(t));this.selectiveReripCongestionUpdateCount\u003c1\u0026\u0026(this.addCongestionCostForSelectiveRerip(),this.selectiveReripCongestionUpdateCount+=1),this.rebuildCommittedState(s),this.state.ripCount+=1,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=function(t){const e=t.pendingRouteIds.filter(e=\u003ee!==t.failedRouteId\u0026\u0026!t.rippedRouteIds.has(e)),n=[...t.rippedRouteIds].filter(e=\u003ee!==t.failedRouteId);return[t.failedRouteId,...e,...n]}({failedRouteId:t,pendingRouteIds:this.state.unroutedRoutes,rippedRouteIds:s}),this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.selectiveReripStats.selectiveRipCount+=1,this.selectiveReripStats.selectivelyRippedRouteCount+=s.size,this.selectiveReripStats.alternateOwnerCount+=a.length,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=a,this.selectiveReripStats.lastRippedRouteIds=[...s],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=i?.expandedLabelCount??0,this.publishSelectiveReripStats()}addCongestionCostForSelectiveRerip(){for(let t=0;t\u003cthis.topology.regionCount;t++){const e=this.state.regionIntersectionCaches[t]?.existingRegionCost??0;this.state.regionCongestionCost[t]+=e*this.RIP_CONGESTION_REGION_COST_FACTOR}}findRelaxedBlockerPath(t=new Set){const e=this.state.currentRouteId,n=this.state.currentRouteNetId;if(void 0===e||void 0===n)throw new Error(\"SelectiveReripTinyHyperGraphSolver: blocker search requires a current route and net\");const o=this.getRouteStartPortId(e),i=this.getRouteEndPortId(e),r=this.getStartingNextRegionId(e,o);if(void 0===r)throw new Error(`SelectiveReripTinyHyperGraphSolver: route ${this.describeRoute(e)} has no starting region for blocker search`);const s=this.getPortOwners();return(t=\u003e{const e=t.maxExpandedLabels??Number.POSITIVE_INFINITY;if(e!==Number.POSITIVE_INFINITY\u0026\u0026(!Number.isInteger(e)||e\u003c0))throw new Error(\"maxExpandedLabels must be a non-negative integer\");const n=new Map,o=new kB;let i=0,r=0;const s={state:t.start,stateKey:t.getStateKey(t.start),owners:new Set,distance:0,parent:null,incomingHop:null,queueOrder:i++,active:!0};for(n.set(s.stateKey,[s]),o.push(s);;){const s=zB(o);if(null===s)return{found:!1,reason:\"no_path\",expandedLabelCount:r};if(t.isGoal(s.state))return DB(s,r);if(r\u003e=e)return{found:!1,reason:\"expansion_limit\",expandedLabelCount:r};r++;for(const e of t.getHops(s.state)){if(!Number.isFinite(e.distance)||e.distance\u003c0)throw new Error(\"Distinct-owner blocker hops require finite distances \u003e= 0\");const r=new Set(s.owners);for(const t of e.owners??[])r.add(t);const a=s.distance+e.distance;if(!Number.isFinite(a))throw new Error(\"Distinct-owner blocker path distance overflowed\");const c={state:e.state,stateKey:t.getStateKey(e.state),owners:r,distance:a,parent:s,incomingHop:e,queueOrder:i++,active:!0},l=n.get(c.stateKey)??[];if(l.some(t=\u003eLB(t,c)))continue;const d=[];for(const t of l)LB(c,t)?t.active=!1:d.push(t);d.push(c),n.set(c.stateKey,d),o.push(c)}}})({start:{portId:o,nextRegionId:r},getStateKey:({portId:t,nextRegionId:e})=\u003ethis.getHopId(t,e),isGoal:({portId:t})=\u003et===i,getHops:e=\u003ethis.getRelaxedSearchHops({state:e,goalPortId:i,routeNetId:n,portOwners:s,forbiddenOwnerRouteIds:t}),maxExpandedLabels:this.getRelaxedSearchExpansionLimit()})}findRelaxedBlockerPathPreferringPreservedRoutes(t=new Set){const e=this.getRouteIdsPreferredForPreservation();if(0===e.size)return this.findRelaxedBlockerPath(t);const n=new Set(t);for(const t of e)n.add(t);const o=this.findRelaxedBlockerPath(n);return o.found\u0026\u0026o.owners.size\u003e0?o:this.findRelaxedBlockerPath(t)}getRelaxedSearchExpansionLimit(){let t=0;for(const e of this.topology.incidentPortRegion)t+=e.length;const e=Math.max(4,Math.ceil(Math.log2(this.problem.routeCount+1)));return Math.max(4096,t*e*4)}getRelaxedSearchHops(t){const{state:e,goalPortId:n,routeNetId:o}=t;if(this.isRegionReservedForDifferentNet(e.nextRegionId))return[];const i=[];for(const r of this.topology.regionIncidentPorts[e.nextRegionId]??[]){if(r===e.portId)continue;if(this.isPortReservedForDifferentNet(r))continue;if(r!==n\u0026\u00260===this.problem.portSectionMask[r])continue;const s=this.getHopBlockerResources({regionId:e.nextRegionId,fromPortId:e.portId,toPortId:r,routeNetId:o,portOwners:t.portOwners}),a=[...new Set(s.flatMap(t=\u003et.owners))];if(a.some(e=\u003et.forbiddenOwnerRouteIds.has(e)))continue;let c=e.nextRegionId;if(r!==n){const[t,n]=this.topology.incidentPortRegion[r]??[];if(c=t===e.nextRegionId?n:t,void 0===c||this.isRegionReservedForDifferentNet(c))continue}i.push({state:{portId:r,nextRegionId:c},distance:Math.hypot(this.topology.portX[e.portId]-this.topology.portX[r],this.topology.portY[e.portId]-this.topology.portY[r]),owners:a,data:{resources:s}})}return i}getHopBlockerResources(t){const e=[],n=this.state.portAssignment[t.toPortId];if(-1!==n\u0026\u0026n!==t.routeNetId){const o=[...t.portOwners.get(t.toPortId)??new Set].filter(e=\u003ethis.problem.routeNet[e]!==t.routeNetId);if(0===o.length)throw new Error(`SelectiveReripTinyHyperGraphSolver: port ${t.toPortId} is assigned to foreign net ${n} without a committed route owner`);e.push({kind:\"port\",portId:t.toPortId,owners:o})}const o=this.getHardBlockedCrossingOwners(t.regionId,t.fromPortId,t.toPortId);return o.length\u003e0\u0026\u0026e.push({kind:\"same_layer_intersection\",regionId:t.regionId,fromPortId:t.fromPortId,toPortId:t.toPortId,owners:o}),e}getPortOwners(){const t=new Map;for(const e of this.state.regionSegments)for(const[n,o,i]of e)for(const e of[o,i]){const o=t.get(e)??new Set;o.add(n),t.set(e,o)}return t}getHardBlockedCrossingOwners(t,e,n){if(!this.isKnownSingleLayerRegion(t))return[];const o=this.state.currentRouteNetId;if(void 0===o)throw new Error(\"SelectiveReripTinyHyperGraphSolver: crossing ownership requires a current route net\");const i=new Set;for(const[r,s,a]of this.state.regionSegments[t]??[])this.problem.routeNet[r]!==o\u0026\u0026this.segmentsCrossOnSameLayer(t,e,n,s,a)\u0026\u0026i.add(r);return[...i]}segmentsCrossOnSameLayer(t,e,n,o,i){const r={...this.populateSegmentGeometryScratch(t,e,n)},s={...this.populateSegmentGeometryScratch(t,o,i)};if(0===(r.layerMask\u0026s.layerMask))return!1;if(r.lesserAngle===s.lesserAngle||r.lesserAngle===s.greaterAngle||r.greaterAngle===s.lesserAngle||r.greaterAngle===s.greaterAngle)return!1;return(r.lesserAngle\u003cs.lesserAngle\u0026\u0026s.lesserAngle\u003cr.greaterAngle)!==(r.lesserAngle\u003cs.greaterAngle\u0026\u0026s.greaterAngle\u003cr.greaterAngle)}rebuildCommittedState(t){this.state.regionSegments=this.state.regionSegments.map(e=\u003ee.filter(([e])=\u003e!t.has(e))),this.state.portAssignment.fill(-1),this.state.regionIntersectionCaches=Array.from({length:this.topology.regionCount},()=\u003eqF());for(let t=0;t\u003cthis.state.regionSegments.length;t++)for(const[e,n,o]of this.state.regionSegments[t]){const i=this.problem.routeNet[e];this.state.currentRouteNetId=i;for(const t of[n,o]){const e=this.state.portAssignment[t];if(-1!==e\u0026\u0026e!==i)throw new Error(`SelectiveReripTinyHyperGraphSolver: rebuilding committed routes found cross-net ownership at port ${t} between net ${e} and net ${i}`);this.state.portAssignment[t]=i}this.appendSegmentToRegionCache(t,n,o)}this.state.currentRouteNetId=void 0}incrementFailedOwnerPair(t,e){const n=this.failedOwnerPairCounts.get(t)??new Map,o=(n.get(e)??0)+1;return n.set(e,o),this.failedOwnerPairCounts.set(t,n),o}hasFailedOwnerPath(t,e){const n=[t],o=new Set;for(;n.length\u003e0;){const t=n.pop();if(t===e)return!0;o.has(t)||(o.add(t),n.push(...this.failedOwnerPairCounts.get(t)?.keys()??[]))}return!1}publishSelectiveReripStats(){const t=[];for(const[e,n]of this.failedOwnerPairCounts)for(const[o,i]of n)t.push({failedRouteId:e,ownerRouteId:o,count:i});t.sort((t,e)=\u003et.failedRouteId-e.failedRouteId||t.ownerRouteId-e.ownerRouteId),this.selectiveReripStats.failedOwnerPairs=t,this.selectiveReripStats.failedOwnerPairCount=t.length,this.selectiveReripStats.maxFailedOwnerPairCount=Math.max(0,...t.map(({count:t})=\u003et)),this.stats={...this.stats,...this.getSelectiveReripStats()}}describeRoute(t){const e=this.problem.routeMetadata?.[t]?.connectionId;return void 0===e?String(t):`${t} (${String(e)})`}};new Int32Array(0);var uj=class extends hj{initialAssignmentRouteIds;getRouteIdsPreferredForPreservation(){return this.initialAssignmentRouteIds||(this.initialAssignmentRouteIds=new Set((this.problem.initialAssignments??[]).map(t=\u003et.routeId))),this.initialAssignmentRouteIds}resetRoutingStateForRerip(){super.resetRoutingStateForRerip(),this.problem.initialAssignments?.length\u0026\u0026Uz({topology:this.topology,problem:this.problem,state:this.state,routeSuccessCountByRouteId:this.routeSuccessCountByRouteId,appendSegmentToRegionCache:(t,e,n)=\u003ethis.appendSegmentToRegionCache(t,e,n)})}},pj=t=\u003e{if(\"object\"!=typeof t||null===t)return!1;const e=t,n=e.preloadedTraceSection;return\"string\"==typeof e.connectionId\u0026\u0026\"string\"==typeof n?.traceId\u0026\u0026\"number\"==typeof n.startRoutePosition\u0026\u0026\"number\"==typeof n.endRoutePosition\u0026\u0026\"number\"==typeof n.startPoint?.x\u0026\u0026\"number\"==typeof n.startPoint.y\u0026\u0026\"number\"==typeof n.startPoint.z\u0026\u0026\"number\"==typeof n.endPoint?.x\u0026\u0026\"number\"==typeof n.endPoint.y\u0026\u0026\"number\"==typeof n.endPoint.z},mj=(t,e)=\u003e`__tscircuit_preloaded_trace__:${JSON.stringify([t,e])}`,gj=t=\u003e[t.region1Id,t.region2Id],fj=(t,e)=\u003e{const n=new Set(gj(e));return gj(t).filter(t=\u003en.has(t))},yj=(t,e,n)=\u003e{const o=t[e],i=t[e+1],r=fj(o.port,i.port);if(0===r.length)return;if(1===r.length)return r[0];const s=t[e+2];if(s){const t=new Set(fj(i.port,s.port)),e=r.find(e=\u003et.has(e));if(e)return e}return n\u0026\u0026r.includes(n)?n:[...r].sort()[0]},_j=(t,e)=\u003egj(t).find(t=\u003et!==e)??e,bj=t=\u003e{const e=new Set((t.connections??[]).filter(pj).map(t=\u003et.connectionId)),n=t.ports.filter(t=\u003e(t.d?._preloadedTracePortAssignments?.length??0)\u003e0).length,o=t.regions.reduce((t,n)=\u003et+(n.assignments??[]).filter(t=\u003ee.has(t.connectionId)).length,0);return{preloadedTraceCount:e.size,preloadedPortCount:n,preloadedAssignmentCount:o}},xj=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},vj=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},Sj=1e-6,Ij={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,PARTIAL_RIP_MIN_ROUTE_COUNT:100,PARTIAL_RIP_MAX_ROUTE_COUNT:350,PARTIAL_RIP_MAX_ATTEMPTS:7,PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS:1,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:100,PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO:.02,PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO:.05,PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO:.1},Cj={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:6,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:Number.POSITIVE_INFINITY},Pj=t=\u003eMath.max(t,.01),Mj=t=\u003eNumber.isFinite(t)?{minViaPadDiameter:t}:{},Nj=(t,e)=\u003e{const n=Pj(t);return{...Ij,...Mj(e),USE_SPARSE_CANDIDATE_STORAGE:!1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.ceil(10*n),MAX_ITERATIONS:Math.ceil(2e6*n)}},wj=(t,e)=\u003e{const n=Pj(t);return{...Cj,...Mj(e),USE_SPARSE_CANDIDATE_STORAGE:!1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.ceil(16*n),MAX_ITERATIONS:Math.ceil(1e6*n)}},Tj=t=\u003e(t.solveGraphOptions?.MAX_ITERATIONS??1e6)+(t.sectionSolverOptions?.MAX_ITERATIONS??1e6)+1e6,Rj=t=\u003et.mutuallyConnectedNetworkId,Ej=(t,e)=\u003et.simpleRouteConnection?.pointsToConnect[e],Aj=t=\u003e{const e=Ej(t.routeMetadata,t.endpointIndex);if(!e)return t.fallbackZ;const n=xo(e).map(e=\u003eko(e,t.layerCount));return t.regionAvailableZ.find(t=\u003en.includes(t))??t.fallbackZ},Oj=(t,e)=\u003e{const n=t.d,o=n.bounds;return{capacityMeshNodeId:t.d.capacityMeshNodeId,center:{x:t.d.center.x,y:t.d.center.y},width:t.d.width,height:t.d.height,availableZ:[...t.d.availableZ],...o?{bounds:{minX:o.minX,maxX:o.maxX,minY:o.minY,maxY:o.maxY}}:{},_containsObstacle:t.d._containsObstacle,_containsTarget:t.d._containsTarget,_offBoardConnectionId:t.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:void 0===t.d._offBoardConnectedCapacityMeshNodeIds?void 0:[...t.d._offBoardConnectedCapacityMeshNodeIds],_qfpRegionType:n._qfpRegionType,_isNarrowQfpPadGap:n._isNarrowQfpPadGap,...void 0!==e?{netId:e}:{}}},kj=t=\u003e{const e=t.d;return{portId:t.d.portId,x:t.d.x,y:t.d.y,z:t.d.z,prevPortPointId:e.prevPortPointId,nextPortPointId:e.nextPortPointId,distToCentermostPortOnZ:t.d.distToCentermostPortOnZ,tinyHypergraphPortPenalty:t.d.tinyHypergraphPortPenalty,cramped:t.d.cramped,_preloadedFixedNetIds:t.d._preloadedFixedNetIds,_preloadedTracePortAssignments:t.d._preloadedTracePortAssignments}},Lj=t=\u003e{const e=function(){const t=new Map;return e=\u003e{const n=e.mutuallyConnectedNetworkId;let o=t.get(n);return void 0===o\u0026\u0026(o=t.size,t.set(n,o)),o}}(),n=function(t){const e=new Map,n=new Set,o=new Map;for(const i of t.params.connections){const r=i.mutuallyConnectedNetworkId,s=t.getNetIndex({connectionId:i.connectionId,mutuallyConnectedNetworkId:r});for(const t of[i.connectionId,r])o.set(t,s);for(const o of i.simpleRouteConnection.pointsToConnect)for(const i of t.params.graph.regions){if(!gf({point:o,region:i,layerCount:t.params.layerCount}))continue;if(void 0===o.pcb_port_id\u0026\u0026!0!==i.d._containsTarget){n.add(i.regionId);continue}let r=e.get(i.regionId);r||(r=new Set,e.set(i.regionId,r)),r.add(s)}}for(const n of t.params.graph.regions)for(const t of n.d._connectedTo??[]){const i=o.get(t);if(void 0===i)continue;let r=e.get(n.regionId);r||(r=new Set,e.set(n.regionId,r)),r.add(i)}const i=new Map;for(const t of n)i.set(t,-1);for(const[t,n]of e)1===n.size\u0026\u0026i.set(t,[...n][0]);return i}({params:t,getNetIndex:e}),o=t.graph.regions.map(t=\u003e({regionId:t.regionId,pointIds:t.ports.map(t=\u003et.d.portId),d:Oj(t,n.get(t.regionId))})),i=t.graph.ports.map(t=\u003e({portId:t.d.portId,region1Id:t.region1.regionId,region2Id:t.region2.regionId,d:kj(t)})),r=t.connections.map(t=\u003e({connectionId:t.connectionId,mutuallyConnectedNetworkId:t.mutuallyConnectedNetworkId,startRegionId:t.startRegion.regionId,endRegionId:t.endRegion.regionId,simpleRouteConnection:t.simpleRouteConnection})),s=[];for(const n of t.connections){const r={connectionId:n.connectionId,mutuallyConnectedNetworkId:n.mutuallyConnectedNetworkId,simpleRouteConnection:n.simpleRouteConnection},a=e(r),c=Ej(r,0),l=Ej(r,1),d=n.startRegion.d.availableZ[0]??0,h=n.endRegion.d.availableZ[0]??0,u=Aj({routeMetadata:r,endpointIndex:0,fallbackZ:d,regionAvailableZ:n.startRegion.d.availableZ,layerCount:t.layerCount}),p=Aj({routeMetadata:r,endpointIndex:1,fallbackZ:h,regionAvailableZ:n.endRegion.d.availableZ,layerCount:t.layerCount}),m=`tiny-terminal:start-region:${n.connectionId}`,g=`tiny-terminal:end-region:${n.connectionId}`,f=`tiny-terminal:start-port:${n.connectionId}`,y=`tiny-terminal:end-port:${n.connectionId}`;o.push({regionId:m,pointIds:[f],d:{capacityMeshNodeId:m,center:{x:c?.x??n.startRegion.d.center.x,y:c?.y??n.startRegion.d.center.y},width:Sj,height:Sj,availableZ:[u],_containsTarget:!0,_tinyTerminal:!0,_tinyTerminalNetId:n.mutuallyConnectedNetworkId,netId:a}}),o.push({regionId:g,pointIds:[y],d:{capacityMeshNodeId:g,center:{x:l?.x??n.endRegion.d.center.x,y:l?.y??n.endRegion.d.center.y},width:Sj,height:Sj,availableZ:[p],_containsTarget:!0,_tinyTerminal:!0,_tinyTerminalNetId:n.mutuallyConnectedNetworkId,netId:a}}),i.push({portId:f,region1Id:n.startRegion.regionId,region2Id:m,d:{portId:f,x:c?.x??n.startRegion.d.center.x,y:c?.y??n.startRegion.d.center.y,z:u,distToCentermostPortOnZ:0,_tinyTerminal:!0,...t.preserveTerminalPcbPortIds\u0026\u0026c?.pcb_port_id?{pcb_port_id:c.pcb_port_id}:{}}}),i.push({portId:y,region1Id:n.endRegion.regionId,region2Id:g,d:{portId:y,x:l?.x??n.endRegion.d.center.x,y:l?.y??n.endRegion.d.center.y,z:p,distToCentermostPortOnZ:0,_tinyTerminal:!0,...t.preserveTerminalPcbPortIds\u0026\u0026l?.pcb_port_id?{pcb_port_id:l.pcb_port_id}:{}}});const _=o.find(t=\u003et.regionId===n.startRegion.regionId),b=o.find(t=\u003et.regionId===n.endRegion.regionId);_?.pointIds.push(f),b?.pointIds.push(y),s.push({connection:{connectionId:n.connectionId},path:[{portId:f},{portId:y}]})}const a={regions:o,ports:i,connections:r,solvedRoutes:s};return(t=\u003e{const e=new Map,n=new Map,o=new Set((t.connections??[]).flatMap(t=\u003e[t.startRegionId,t.endRegionId])),i=new Set(t.regions.filter(t=\u003e{const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;return!0===t.d?._containsObstacle\u0026\u0026(void 0===e||-1===e)\u0026\u0026!o.has(t.regionId)}).map(t=\u003et.regionId));let r=0;for(const o of t.ports){const t=o.d,s=t?._preloadedTracePortAssignments??[];if(s.length\u003e0\u0026\u0026r++,!i.has(o.region1Id)\u0026\u0026!i.has(o.region2Id))for(const t of s){const i=n.get(t.traceId);if(void 0!==i\u0026\u0026i!==t.fixedNetId)throw new Error(`Preloaded trace \"${t.traceId}\" maps to multiple canonical nets`);n.set(t.traceId,t.fixedNetId);const r=e.get(t.traceId)??[];r.push({port:o,assignment:t}),e.set(t.traceId,r)}}const s=new Map(t.regions.map(t=\u003e[t.regionId,t])),a=t.connections??=[],c=t.solvedRoutes??=[];let l=0,d=0;for(const[t,o]of e){o.sort((t,e)=\u003et.assignment.routePosition-e.assignment.routePosition||t.assignment.z-e.assignment.z||t.port.portId.localeCompare(e.port.portId));const e=o.filter(({port:t},e)=\u003e0===e||t.portId!==o[e-1].port.portId);if(e.length\u003c2)continue;const i=[];let r;for(let t=0;t\u003ce.length-1;t++){const n=e[t],o=e[t+1];if(n.assignment.z===o.assignment.z\u0026\u0026Math.abs(n.assignment.routePosition-o.assignment.routePosition)\u003c=1e-6){r=void 0;continue}const s=yj(e,t,r);s?(i.push({regionId:s,from:n,to:o}),r=s):r=void 0}const h=[];for(const t of i){const e=h.at(-1);e\u0026\u0026e.at(-1).to.port.portId===t.from.port.portId?e.push(t):h.push([t])}for(const[e,o]of h.entries()){const i=mj(t,e);for(const e of o){const n=s.get(e.regionId);if(!n)throw new Error(`Preloaded trace \"${t}\" references missing region \"${e.regionId}\"`);n.assignments=[...n.assignments??[],{regionPort1Id:e.from.port.portId,regionPort2Id:e.to.port.portId,connectionId:i}],d++}const r=o[0],l=o.at(-1),h=r.from.port,u=l.to.port,p={connectionId:i,mutuallyConnectedNetworkId:n.get(t)??t,startRegionId:_j(h,r.regionId),endRegionId:_j(u,l.regionId),preloadedTraceSection:{traceId:t,startRoutePosition:r.from.assignment.routePosition,endRoutePosition:l.to.assignment.routePosition,startPoint:{x:r.from.assignment.tracePoint.x,y:r.from.assignment.tracePoint.y,z:r.from.assignment.z},endPoint:{x:l.to.assignment.tracePoint.x,y:l.to.assignment.tracePoint.y,z:l.to.assignment.z}}};a.push(p),c.push({requiredRip:!1,connection:p,path:[h,u].map(t=\u003e({portId:t.portId,g:0,h:0,f:0,hops:0,ripRequired:!1}))})}h.length\u003e0\u0026\u0026l++}})(a),a},Dj=t=\u003e{const e=new Map;for(let n=0;n\u003ct.problem.routeNet.length;n++){const o=t.problem.routeMetadata?.[n],i=o?.mutuallyConnectedNetworkId;if(\"string\"!=typeof i||0===i.length)throw new Error(`Tiny hypergraph route ${n} is missing a net ID`);e.set(i,t.problem.routeNet[n])}for(let n=0;n\u003ct.problem.regionNetId.length;n++){const o=t.topology.regionMetadata?.[n]?._tinyTerminalNetId;if(\"string\"!=typeof o)continue;const i=e.get(o);void 0!==i\u0026\u0026(t.problem.regionNetId[n]=i)}},zj=t=\u003e{const e=new Map;t.topology.regionMetadata?.forEach((t,n)=\u003e{\"string\"==typeof t.serializedRegionId\u0026\u0026e.set(t.serializedRegionId,n)});const n=new Set;for(const e of t.problem.routeMetadata??[])pj(e)||(\"string\"==typeof e.startRegionId\u0026\u0026n.add(e.startRegionId),\"string\"==typeof e.endRegionId\u0026\u0026n.add(e.endRegionId));for(const o of t.problem.routeMetadata??[])if(pj(o))for(const i of[o.startRegionId,o.endRegionId]){if(\"string\"!=typeof i||n.has(i))continue;const o=e.get(i);if(void 0===o)continue;const r=t.topology.regionMetadata?.[o];\"number\"==typeof r?.netId||\"number\"==typeof r?.NetId||(t.problem.regionNetId[o]=-1)}},Fj=t=\u003e{if(t.problem.metadataPortPenaltiesApplied)return 0;let e=0,n=void 0!==t.problem.portPenalty;for(let o=0;o\u003ct.topology.portCount;o++){const i=Number(t.topology.portMetadata?.[o]?.tinyHypergraphPortPenalty),r=Number.isFinite(i)\u0026\u0026i\u003e0?i:0;r\u003e0\u0026\u0026e++,t.problem.portPenalty?.[o]!==r\u0026\u0026(n=!1)}if(n)return t.problem.metadataPortPenaltiesApplied=!0,e;e=0;const o=t.problem.portPenalty?new Float64Array(t.problem.portPenalty):new Float64Array(t.topology.portCount);for(let n=0;n\u003ct.topology.portCount;n++){const i=Number(t.topology.portMetadata?.[n]?.tinyHypergraphPortPenalty);!Number.isFinite(i)||i\u003c=0||(o[n]+=i,e++)}return e\u003e0\u0026\u0026(t.problem.portPenalty=o),t.problem.metadataPortPenaltiesApplied=!0,e},Bj=class extends dj{configuredSolvers=new WeakSet;duplicatePortPenaltyCount=0;metadataPortPenaltyCount=0;crampedPortPenaltyCount=0;preloadedPortCount=0;preloadedFixedSegmentCount=0;crampedPortTraversalPenalty;useSelectiveReripRouting;constructor(t,e){super(t),this.useSelectiveReripRouting=e,this.crampedPortTraversalPenalty=150;const n=bj(t.serializedHyperGraph);if(this.preloadedPortCount=n.preloadedPortCount,this.preloadedFixedSegmentCount=n.preloadedAssignmentCount,e){const t=this.pipelineDef.find(t=\u003e\"solveGraph\"===t.solverName);if(!t)throw new Error(\"Tiny hypergraph pipeline is missing the solveGraph stage\");t.solverClass=uj}this.MAX_ITERATIONS=Tj(t)}loadHyperGraph(t){const e=super.loadHyperGraph(t);((t,e)=\u003e{const n=new Map;for(const t of e.connections??[])pj(t)\u0026\u0026n.set(t.connectionId,t.preloadedTraceSection);for(const e of t.problem.routeMetadata??[]){const t=n.get(e.connectionId);t\u0026\u0026(e.preloadedTraceSection=t)}})(e,this.inputProblem.serializedHyperGraph);const n=Fj(e),{duplicatePortPenaltyCount:o,crampedPortPenaltyCount:i}=((t,e)=\u003e{let n=0,o=0;const i=t.problem.portPenalty?new Float64Array(t.problem.portPenalty):new Float64Array(t.topology.portCount);for(let r=0;r\u003ct.topology.portCount;r++){const s=t.topology.portMetadata?.[r];\"string\"==typeof s?.duplicatedFromPortId\u0026\u0026(i[r]+=150,n++),s?.cramped\u0026\u0026e\u003e0\u0026\u0026(i[r]+=e,o++)}return(n\u003e0||o\u003e0)\u0026\u0026(t.problem.portPenalty=i),{duplicatePortPenaltyCount:n,crampedPortPenaltyCount:o}})(e,this.crampedPortTraversalPenalty);return Dj(e),zj(e),this.metadataPortPenaltyCount=Math.max(this.metadataPortPenaltyCount,n),this.duplicatePortPenaltyCount=Math.max(this.duplicatePortPenaltyCount,o),this.crampedPortPenaltyCount=Math.max(this.crampedPortPenaltyCount,i),e}_step(){super._step(),this.configureSolver(this.activeSubSolver)}getInitialVisualizationSolver(){if(this.useSelectiveReripRouting\u0026\u0026!this.initialVisualizationSolver){const{topology:t,problem:e}=this.loadHyperGraph(this.inputProblem.serializedHyperGraph);this.initialVisualizationSolver=new uj(t,e,this.getSolveGraphOptions())}const t=super.getInitialVisualizationSolver();return this.configureSolver(t),t}getSolvedTinySolver(){const t=this.getSolver(\"optimizeSection\");if(t?.solved\u0026\u0026!t.failed)return t.getSolvedSolver();const e=this.getSolver(\"solveGraph\");if(e?.solved\u0026\u0026!e.failed)return e;throw new Error(\"TinyHyperGraph section pipeline does not have a solved graph\")}configureSolver(t){if(t\u0026\u0026!this.configuredSolvers.has(t)){if(t instanceof JB||t instanceof nB){const e=t;Fj(e),Dj(e),zj(e)}this.configuredSolvers.add(t)}}},jj=class extends si{constructor(t){super(),this.params=t;const e=(t=\u003et.map(t=\u003e{const e=t.simpleRouteConnection;if(!e)throw new Error(`TinyHypergraphPortPointPathingSolver requires a SimpleRouteConnection for \"${t.connectionId}\"`);const n=t.mutuallyConnectedNetworkId;if(!n)throw new Error(`TinyHypergraphPortPointPathingSolver requires a net ID for \"${t.connectionId}\"`);return{...t,mutuallyConnectedNetworkId:n,simpleRouteConnection:e}}))(t.connections),n=t.flags.USE_SELECTIVE_RERIP_ROUTING?function(t,e){const n=new Map;for(const o of t){const t=e(o);n.set(t,(n.get(t)??0)+1)}return t.map((t,e)=\u003e({connection:t,index:e})).sort((t,o)=\u003e(n.get(e(o.connection))??0)-(n.get(e(t.connection))??0)||t.index-o.index).map(({connection:t})=\u003et)}(e,Rj):e;this.rootConnectionNameByConnectionId=new Map(n.map(t=\u003e[t.connectionId,t.simpleRouteConnection.__rootConnectionNames?.[0]]));const o=Lj({...t,connections:n});this.originalPreloadedSegmentKeysByConnectionId=(t=\u003e{const e=new Map;for(const n of t.connections??[])pj(n)\u0026\u0026e.set(n.connectionId,new Set);for(const n of t.regions)for(const t of n.assignments??[]){const o=e.get(t.connectionId);if(!o)continue;const[i,r]=[t.regionPort1Id,t.regionPort2Id].sort();o.add(JSON.stringify([n.regionId,i,r]))}return e})(o);const i=bj(o),r=i.preloadedPortCount\u003e0,s=r\u0026\u0026!0===t.flags.USE_PARTIAL_RIP_ROUTING_WITH_PRELOADED_TRACES,a=s?Math.max(o.connections?.length??0,i.preloadedAssignmentCount):void 0;let c=o;if(n.length\u003c=180){const e=new AB(o,{duplicatePortProximity:.05,useSerializedPortPenalties:!1,routeSolveOptions:{...Mj(t.minViaPadDiameter),USE_SPARSE_CANDIDATE_STORAGE:!1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,MAX_ITERATIONS:Math.ceil(2e6*Pj(t.effort)),RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!0}});if(e.solve(),e.failed)this.duplicateCongestedPortError=e.error??\"unknown error\";else{this.duplicateCongestedPortReport=e.report,c=e.getOutput();for(const t of c.ports){const e=vj(t.d);\"string\"==typeof e.duplicatedFromPortId\u0026\u0026(delete e._preloadedFixedNetIds,delete e._preloadedTracePortAssignments)}}}else this.duplicateCongestedPortError=`Skipped for ${n.length} connections`;this.duplicatedPortCount=this.duplicateCongestedPortReport?.duplicatedPorts.reduce((t,e)=\u003et+e.duplicatePortIds.length,0)??0;const l=((t,e,n,o=!0,i)=\u003e{const r=t.connections?.length??0,s=i??r,a=Ij.PARTIAL_RIP_MIN_ROUTE_COUNT??0,c=Ij.PARTIAL_RIP_MAX_ROUTE_COUNT??Number.POSITIVE_INFINITY,l=o\u0026\u0026s\u003e=a\u0026\u0026s\u003c=c;return{serializedHyperGraph:t,createSectionMask:({topology:t})=\u003enew Int8Array(t.portCount),solveGraphOptions:{...Nj(e,n),...l?{PARTIAL_RIP_MIN_ROUTE_COUNT:0,PARTIAL_RIP_MAX_ROUTE_COUNT:Number.POSITIVE_INFINITY,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:0}:{PARTIAL_RIP_ENABLED:!1,OUTSIDE_IN_ROUTING:!1}},sectionSolverOptions:wj(e,n)}})({...c,solvedRoutes:o.solvedRoutes},t.effort,t.minViaPadDiameter,!r||s,a);this.tinyPipelineSolver=new Bj(l,!0===t.flags.USE_SELECTIVE_RERIP_ROUTING),this.primaryTinyPipelineSolver=this.tinyPipelineSolver,n.length\u003e=30\u0026\u0026n.length\u003c=99\u0026\u0026(this.alternativeTinyPipelineInput={...l,solveGraphOptions:{...l.solveGraphOptions,TRACE_DENSITY_COST_FACTOR:1}}),this.MAX_ITERATIONS=Tj(l)*(this.alternativeTinyPipelineInput?2:1),this.originalRegionById=new Map(t.graph.regions.map(t=\u003e[t.regionId,t])),this.originalRegionIds=new Set(this.originalRegionById.keys()),this.inputNodeWithPortPoints=((t,e)=\u003e{const n=new Map(e.regions.map(t=\u003e[t.regionId,t])),o=new Map(e.ports.map(t=\u003e[t.portId,t]));return t.graph.regions.map(t=\u003e{const e=n.get(t.regionId),i=(e?.pointIds??t.ports.map(t=\u003et.d.portId)).map(t=\u003eo.get(t)).filter(t=\u003et\u0026\u0026!vj(t.d)._tinyTerminal).map(t=\u003e{const e=t,o=vj(e.d),i=n.get(e.region1Id),r=n.get(e.region2Id),s=Boolean(xj(i?.d)._offBoardConnectionId??xj(r?.d)._offBoardConnectionId);return{portPointId:e.portId,x:Number(o.x??0),y:Number(o.y??0),z:Number(o.z??0),prevPortPointId:\"string\"==typeof o.prevPortPointId?o.prevPortPointId:void 0,nextPortPointId:\"string\"==typeof o.nextPortPointId?o.nextPortPointId:void 0,connectionNodeIds:[e.region1Id,e.region2Id],distToCentermostPortOnZ:Number(o.distToCentermostPortOnZ??0),cramped:Boolean(o.cramped),connectsToOffBoardNode:s}});return{capacityMeshNodeId:t.d.capacityMeshNodeId,center:t.d.center,width:t.d.width,height:t.d.height,portPoints:i,availableZ:t.d.availableZ,_containsObstacle:t.d._containsObstacle,_containsTarget:t.d._containsTarget,_offBoardConnectionId:t.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t.d._offBoardConnectedCapacityMeshNodeIds,_qfpRegionType:t.d._qfpRegionType,_isNarrowQfpPadGap:t.d._isNarrowQfpPadGap}})})(t,c)}params;tinyPipelineSolver;primaryTinyPipelineSolver;alternativeTinyPipelineSolver;alternativeTinyPipelineInput;candidatePortfolioPhase=\"primary\";primaryCandidateSummary;alternativeCandidateSummary;alternativeCandidateEvaluated=!1;selectedCandidate=\"primary\";duplicateCongestedPortReport;duplicateCongestedPortError;duplicatedPortCount=0;inputNodeWithPortPoints;originalRegionById;originalRegionIds;rootConnectionNameByConnectionId;originalPreloadedSegmentKeysByConnectionId;getSolverName(){return\"TinyHypergraphPortPointPathingSolver\"}getChangedPreloadedRouteIds(t){const e=new Map,n=new Map;for(let o=0;o\u003ct.problem.routeCount;o++){const i=this.getRouteMetadata(t,o);pj(i)\u0026\u0026(e.set(i.connectionId,o),n.set(o,new Set))}for(let e=0;e\u003ct.state.regionSegments.length;e++){const o=t.topology.regionMetadata?.[e]?.serializedRegionId;for(const[i,r,s]of t.state.regionSegments[e]??[]){const e=n.get(i);if(!e)continue;const a=t.topology.portMetadata?.[r]?.serializedPortId,c=t.topology.portMetadata?.[s]?.serializedPortId;if(\"string\"!=typeof o||\"string\"!=typeof a||\"string\"!=typeof c)throw new Error(`Tiny hypergraph preloaded route ${i} has a segment without serialized topology IDs`);const[l,d]=[a,c].sort();e.add(JSON.stringify([o,l,d]))}}const o=new Set;for(const[t,i]of this.originalPreloadedSegmentKeysByConnectionId){const r=e.get(t);if(void 0===r)throw new Error(`Tiny hypergraph lost preloaded trace section \"${t}\"`);const s=n.get(r);if(i.size\u003e0\u0026\u00260===s.size)throw new Error(`Tiny hypergraph lost preloaded trace section \"${t}\"`);(i.size!==s.size||[...i].some(t=\u003e!s.has(t)))\u0026\u0026o.add(r)}return o}summarizePipelineCandidate(t){const e=t.getSolvedTinySolver();let n=0,o=0,i=0,r=0,s=0,a=0;const c=e.topology.regionMetadata??[];for(let t=0;t\u003ce.state.regionSegments.length;t++){const l=e.state.regionSegments[t];s+=l.length;for(const[,t,n]of l)e.topology.portZ[t]!==e.topology.portZ[n]\u0026\u0026(a+=1);const d=c[t]?.capacityMeshNodeId;if(!d||!this.originalRegionIds.has(d))continue;const h=this.originalRegionById.get(d);if(!h||0===l.length)continue;const u=l.map(([t,n,o])=\u003e[this.createAssignedPortPoint(e,t,n),this.createAssignedPortPoint(e,t,o)]),p={capacityMeshNodeId:h.d.capacityMeshNodeId,center:h.d.center,width:h.d.width,height:h.d.height,portPoints:u.flat(),portPointsInPairs:u,availableZ:h.d.availableZ},m=Ms(p),g=Ys(h.d,m.numSameLayerCrossings,m.numEntryExitLayerChanges,m.numTransitionPairCrossings);n+=g,o+=g*g,i=Math.max(i,g),r+=p.portPoints.length**2}return{nodePfSum:n,nodePfSquaredSum:o,nodePfMax:i,squaredNodePortPointCount:r,segmentCount:s,layerChangeCount:a,changedPreloadedTraceSectionCount:this.getChangedPreloadedRouteIds(e).size}}shouldEvaluateAlternative(t){const e=this.primaryTinyPipelineSolver.getSolvedTinySolver().problem.routeCount;return void 0!==this.alternativeTinyPipelineInput\u0026\u0026((t,e)=\u003et.nodePfSum\u003e4\u0026\u0026t.nodePfMax\u003e1\u0026\u0026t.squaredNodePortPointCount/Math.max(1,e)\u003e=125)(t,e)}shouldSelectAlternative(t,e){return((t,e,n)=\u003e{if(e.changedPreloadedTraceSectionCount\u003et.changedPreloadedTraceSectionCount)return!1;const o=n\u003e40?.92:.95,i=e.nodePfSum\u003c=.9*t.nodePfSum\u0026\u0026e.nodePfSquaredSum\u003c=.85*t.nodePfSquaredSum\u0026\u0026e.nodePfMax\u003c=.85*t.nodePfMax\u0026\u0026e.squaredNodePortPointCount\u003c.98*t.squaredNodePortPointCount\u0026\u0026e.segmentCount\u003c=.97*t.segmentCount;return e.nodePfSum\u003c=1.03*t.nodePfSum\u0026\u0026e.nodePfSquaredSum\u003c=1.06*t.nodePfSquaredSum\u0026\u0026(e.squaredNodePortPointCount\u003ct.squaredNodePortPointCount*o||i)})(t,e,this.primaryTinyPipelineSolver.getSolvedTinySolver().problem.routeCount)}finishCandidatePortfolio(){this.candidatePortfolioPhase=\"complete\",this.solved=this.tinyPipelineSolver.solved,this.failed=this.tinyPipelineSolver.failed,this.error=this.tinyPipelineSolver.error??null}getSolveGraphBenchmarkMetrics(){const t=this.tinyPipelineSolver.getSolver(\"solveGraph\");if(!t)return;const e=t.state.regionSegments.map(t=\u003et.length),n=\"alternative\"===this.selectedCandidate?this.alternativeCandidateSummary:this.primaryCandidateSummary,o=t.stats,i=this.tinyPipelineSolver.getStageStats().solveGraph;return{routeCount:t.problem.routeCount,traceDensityCandidateEvaluated:this.alternativeCandidateEvaluated,traceDensityCandidateSelected:\"alternative\"===this.selectedCandidate,downstreamNodePfSum:n?.nodePfSum,downstreamNodePfSquaredSum:n?.nodePfSquaredSum,downstreamNodePfMax:n?.nodePfMax,downstreamSquaredNodePortPointCount:n?.squaredNodePortPointCount,changedPreloadedTraceSectionCount:n?.changedPreloadedTraceSectionCount,iterations:t.iterations,timeMs:i?.timeSpent,ripCount:o.ripCount,partialRipCount:o.partialRipCount,partiallyRippedRouteCount:o.partiallyRippedRouteCount,partiallyRippedSegmentCount:o.partiallyRippedSegmentCount,retainedPartialRipSegmentCount:o.retainedPartialRipSegmentCount,firstMaxRegionCost:o.firstMaxRegionCost,bestMaxRegionCost:o.bestMaxRegionCost,firstTotalRegionCost:o.firstTotalRegionCost,bestTotalRegionCost:o.bestTotalRegionCost,firstSegmentCount:o.firstSegmentCount,bestSolvedSegmentCount:o.bestSolvedSegmentCount,bestSolvedMaxRegionSegmentCount:o.bestSolvedMaxRegionSegmentCount,bestSolvedSquaredRegionSegmentCount:o.bestSolvedSquaredRegionSegmentCount,finalMaxRegionSegmentCount:Math.max(0,...e),finalSquaredRegionSegmentCount:e.reduce((t,e)=\u003et+e*e,0),finalSegmentCount:n?.segmentCount,finalLayerChangeCount:n?.layerChangeCount,warmupFullRipAttempts:o.partialRipWarmupFullRipAttempts,complexityAwareSelection:o.partialRipComplexityAwareSelection,targetReached:o.partialRipTargetReached,outsideInCompletedRouteCount:o.outsideInCompletedRouteCount,outsideInFallbackRouteCount:o.outsideInFallbackRouteCount,outsideInForwardExpansionCount:o.outsideInForwardExpansionCount,outsideInReverseExpansionCount:o.outsideInReverseExpansionCount}}_step(){this.tinyPipelineSolver.step(),\"primary\"===this.candidatePortfolioPhase\u0026\u0026this.primaryTinyPipelineSolver.failed?(this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio()):\"primary\"===this.candidatePortfolioPhase\u0026\u0026this.primaryTinyPipelineSolver.solved?(this.primaryCandidateSummary=this.summarizePipelineCandidate(this.primaryTinyPipelineSolver),this.shouldEvaluateAlternative(this.primaryCandidateSummary)?(this.alternativeCandidateEvaluated=!0,this.alternativeTinyPipelineSolver=new Bj(this.alternativeTinyPipelineInput,!0===this.params.flags.USE_SELECTIVE_RERIP_ROUTING),this.tinyPipelineSolver=this.alternativeTinyPipelineSolver,this.candidatePortfolioPhase=\"alternative\"):(this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio())):\"alternative\"===this.candidatePortfolioPhase\u0026\u0026(this.tinyPipelineSolver.solved||this.tinyPipelineSolver.failed)\u0026\u0026(this.tinyPipelineSolver.solved\u0026\u0026!this.tinyPipelineSolver.failed\u0026\u0026(this.alternativeCandidateSummary=this.summarizePipelineCandidate(this.tinyPipelineSolver)),this.alternativeCandidateSummary\u0026\u0026this.primaryCandidateSummary\u0026\u0026this.shouldSelectAlternative(this.primaryCandidateSummary,this.alternativeCandidateSummary)?(this.selectedCandidate=\"alternative\",this.primaryTinyPipelineSolver=void 0,this.alternativeTinyPipelineSolver=void 0):(this.tinyPipelineSolver=this.primaryTinyPipelineSolver,this.alternativeTinyPipelineSolver=void 0),this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio());const t=this.tinyPipelineSolver.getSolver(\"optimizeSection\"),e=this.getCurrentTinySolver();this.solved=\"complete\"===this.candidatePortfolioPhase\u0026\u0026this.tinyPipelineSolver.solved,this.failed=\"complete\"===this.candidatePortfolioPhase\u0026\u0026this.tinyPipelineSolver.failed,this.error=this.failed?this.tinyPipelineSolver.error??null:null,this.progress=\"complete\"===this.candidatePortfolioPhase?1:\"alternative\"===this.candidatePortfolioPhase?.5+.5*this.tinyPipelineSolver.progress:this.alternativeTinyPipelineInput?.5*this.tinyPipelineSolver.progress:this.tinyPipelineSolver.progress,this.stats={duplicateCongestedPortSourceCount:this.duplicateCongestedPortReport?.duplicatedPorts.length??0,duplicateCongestedPortCount:this.duplicateCongestedPortReport?.duplicatedPorts.reduce((t,e)=\u003et+e.duplicatePortIds.length,0)??0,duplicateCongestedPortFallbackToOriginal:Boolean(this.duplicateCongestedPortError),duplicateCongestedPortPenalty:this.duplicatedPortCount\u003e0?150:0,duplicateCongestedPortPenaltyCount:this.tinyPipelineSolver.duplicatePortPenaltyCount,metadataPortPenaltyCount:this.tinyPipelineSolver.metadataPortPenaltyCount,crampedPortPenalty:this.tinyPipelineSolver.crampedPortTraversalPenalty,crampedPortPenaltyCount:this.tinyPipelineSolver.crampedPortPenaltyCount,preloadedPortCount:this.tinyPipelineSolver.preloadedPortCount,preloadedFixedSegmentCount:this.tinyPipelineSolver.preloadedFixedSegmentCount,duplicateCongestedPortError:this.duplicateCongestedPortError,candidatePortfolioPhase:this.candidatePortfolioPhase,candidatePortfolioSelectedCandidate:this.selectedCandidate,candidatePortfolioPrimarySummary:this.primaryCandidateSummary,candidatePortfolioAlternativeSummary:this.alternativeCandidateSummary,...this.tinyPipelineSolver.stats??{},...e?.stats??{},...t?.stats??{},currentStage:this.tinyPipelineSolver.getCurrentStageName(),stageStats:this.tinyPipelineSolver.getStageStats()},this.activeSubSolver=this.tinyPipelineSolver.activeSubSolver??null}preview(){return this.visualize()}getCurrentTinySolver(){const t=this.tinyPipelineSolver.getSolver(\"optimizeSection\");if(t?.solved\u0026\u0026!t.failed)return t.getSolvedSolver();const e=this.tinyPipelineSolver.getSolver(\"solveGraph\");return e||void 0}getSolvedTinySolver(){return this.tinyPipelineSolver.getSolvedTinySolver()}getRouteMetadata(t,e){return t.problem.routeMetadata?.[e]}createAssignedPortPoint(t,e,n){const o=this.getRouteMetadata(t,e),i=o?(t=\u003et.simpleRouteConnection?.name??t.connectionId)(o):`route-${e}`,r=o?this.rootConnectionNameByConnectionId.get(o.connectionId)??o.mutuallyConnectedNetworkId:void 0,s=t.topology.portMetadata?.[n];return{portPointId:String(s?.serializedPortId??s?.portId??`tiny-port-${n}`),x:t.topology.portX[n],y:t.topology.portY[n],z:t.topology.portZ[n],connectionName:i,rootConnectionName:r,...this.params.preserveTerminalPcbPortIds\u0026\u0026\"string\"==typeof s?.pcb_port_id?{pcb_port_id:s.pcb_port_id}:{},prevPortPointId:\"string\"==typeof s?.prevPortPointId?s.prevPortPointId:void 0,nextPortPointId:\"string\"==typeof s?.nextPortPointId?s.nextPortPointId:void 0}}getOutput(){const t=this.getSolvedTinySolver(),e=[],n=t.state.regionSegments,o=t.topology.regionMetadata??[],i=this.getChangedPreloadedRouteIds(t);for(let r=0;r\u003cn.length;r++){const s=o[r]?.capacityMeshNodeId;if(!s||!this.originalRegionIds.has(s))continue;const a=this.originalRegionById.get(s);if(!a)continue;const c=n[r].filter(([e])=\u003e{const n=this.getRouteMetadata(t,e);return!pj(n)||i.has(e)}).map(([e,n,o])=\u003e{const i=this.createAssignedPortPoint(t,e,n),r=this.createAssignedPortPoint(t,e,o);return i.portPointId\u0026\u0026r.portPointId\u0026\u0026(i.nextPortPointId=r.portPointId,r.prevPortPointId=i.portPointId),[i,r]}),l=c.flat();0!==l.length\u0026\u0026e.push({capacityMeshNodeId:a.d.capacityMeshNodeId,center:a.d.center,width:a.d.width,height:a.d.height,portPoints:l,portPointsInPairs:c,availableZ:a.d.availableZ})}const r=[...i].map(e=\u003e{const n=this.getRouteMetadata(t,e);if(!pj(n))throw new Error(`Changed preloaded hypergraph route ${e} is missing section metadata`);const o=n.preloadedTraceSection;return{connectionName:n.connectionId,traceId:o.traceId,startRoutePosition:o.startRoutePosition,endRoutePosition:o.endRoutePosition,connection:{name:n.connectionId,__rootConnectionNames:[n.mutuallyConnectedNetworkId],pointsToConnect:[{x:o.startPoint.x,y:o.startPoint.y,layer:vo(o.startPoint.z,this.params.layerCount)},{x:o.endPoint.x,y:o.endPoint.y,layer:vo(o.endPoint.z,this.params.layerCount)}]}}});return this.stats.changedPreloadedTraceSectionCount=r.length,{nodesWithPortPoints:e,inputNodeWithPortPoints:this.inputNodeWithPortPoints,changedPreloadedTraceSections:r}}computeNodePf(t){const e=this.getOutput().nodesWithPortPoints.find(e=\u003ee.capacityMeshNodeId===t.capacityMeshNodeId),n=this.originalRegionById.get(t.capacityMeshNodeId);if(!e||!n)return null;const o=Ms(e);return Ys(n.d,o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.numTransitionPairCrossings)}tryFinalAcceptance(){}getConstructorParams(){return[this.params]}visualize(){return this.tinyPipelineSolver.visualize()}},$j=(t,e)=\u003e{if(!t||\"none\"===t)return t;try{const n=gt(t);return`rgba(${n.red},${n.green},${n.blue},${e})`}catch{return To(t,1-e)}},Yj=({srj:t,opacity:e=.25,visualizationOptions:n={}})=\u003e{const o=Ho({...t,obstacles:[]},n);return{...o,points:[],lines:o.lines?.map(t=\u003e({...t,strokeColor:$j(t.strokeColor,e)})),rects:o.rects?.map(t=\u003e({...t,fill:$j(t.fill,e),stroke:$j(t.stroke,e)})),circles:o.circles?.map(t=\u003e({...t,fill:$j(t.fill,e),stroke:$j(t.stroke,e)}))}};function Xj(t,e){return t.x\u003e=e.center.x-e.width/2\u0026\u0026t.x\u003c=e.center.x+e.width/2\u0026\u0026t.y\u003e=e.center.y-e.height/2\u0026\u0026t.y\u003c=e.center.y+e.height/2}var Vj=\"escape-via:\",Wj=1e-4,Hj=t=\u003et.obstacleId??[t.layers.join(\".\"),t.center.x.toFixed(4),t.center.y.toFixed(4),t.width.toFixed(4),t.height.toFixed(4)].join(\":\"),Gj=(t,e,n=1e-4)=\u003exe(t,e)\u003c=n,Uj=class extends si{constructor(t,e={}){super(),this.ogSrj=t,this.viaDiameter=e.viaDiameter??Yo(t).padDiameter,this.viaRadius=this.viaDiameter/2,this.minTraceWidth=e.minTraceWidth??t.minTraceWidth,this.obstacleMargin=e.obstacleMargin??t.defaultObstacleMargin??.15,this.requiredViaToPadClearance=Math.max(this.obstacleMargin,t.minViaEdgeToPadEdgeClearance??0),this.escapeOffset=this.viaRadius+Math.max(this.minTraceWidth/2,this.requiredViaToPadClearance),this.requiredTraceClearance=this.minTraceWidth/2+this.obstacleMargin/2,this.requiredViaToViaClearance=this.viaDiameter+this.obstacleMargin,this.outputSrj=t,this.escapeViaMetadataByPointId=new Map,this.createdEscapeVias=[]}ogSrj;getSolverName(){return\"EscapeViaLocationSolver\"}viaDiameter;viaRadius;minTraceWidth;obstacleMargin;escapeOffset;requiredTraceClearance;requiredViaToPadClearance;requiredViaToViaClearance;outputSrj;escapeViaMetadataByPointId;createdEscapeVias;nextEscapeViaIndex=0;getConnectionNetIds(t){return new Set([t.name,...t.__rootConnectionNames??[],t.__netConnectionName].filter(t=\u003eBoolean(t)))}obstacleMatchesConnectionNet(t,e){return t.connectedTo.some(t=\u003ee.has(t))}getObstacleZs(t){return t.__zLayers\u0026\u0026t.__zLayers.length\u003e0?t.__zLayers:t.layers.map(t=\u003eko(t,this.ogSrj.layerCount))}getViaSpanLayers(t,e){const n=ko(t,this.ogSrj.layerCount),o=ko(e,this.ogSrj.layerCount),i=Math.min(n,o),r=Math.max(n,o),s=Array.from({length:r-i+1},(t,e)=\u003ei+e);return{__zLayers:s,layers:s.map(t=\u003evo(t,this.ogSrj.layerCount))}}createEscapeViaObstacle(t){const{escapeVia:e,connectionNetIds:n}=t,{layers:o,__zLayers:i}=this.getViaSpanLayers(e.sourceLayer,e.targetLayer);return{obstacleId:`escape-via-obstacle:${e.pointId}`,type:\"rect\",layers:o,__zLayers:i,center:{x:e.x,y:e.y},width:this.viaDiameter,height:this.viaDiameter,connectedTo:Array.from(n)}}selectSourceObstacle(t){const{point:e,sourceLayer:n,connectionNetIds:o}=t;return this.ogSrj.obstacles.filter(t=\u003e!t.isCopperPour\u0026\u0026t.layers.includes(n)\u0026\u0026Xj(e,t)).sort((t,n)=\u003e{const i=t.connectedTo.includes(e.pointId??\"\")||t.connectedTo.includes(e.pcb_port_id??\"\")||this.obstacleMatchesConnectionNet(t,o);return i!==(n.connectedTo.includes(e.pointId??\"\")||n.connectedTo.includes(e.pcb_port_id??\"\")||this.obstacleMatchesConnectionNet(n,o))?i?-1:1:t.width*t.height-n.width*n.height})[0]}getCandidatePositions(t,e){if(!e)return this.dedupeCandidatePositions([{x:t.x+this.escapeOffset,y:t.y},{x:t.x-this.escapeOffset,y:t.y},{x:t.x,y:t.y+this.escapeOffset},{x:t.x,y:t.y-this.escapeOffset},{x:t.x+this.escapeOffset,y:t.y+this.escapeOffset},{x:t.x+this.escapeOffset,y:t.y-this.escapeOffset},{x:t.x-this.escapeOffset,y:t.y+this.escapeOffset},{x:t.x-this.escapeOffset,y:t.y-this.escapeOffset}]);const n=e.center.x-e.width/2,o=e.center.x+e.width/2,i=e.center.y-e.height/2,r=e.center.y+e.height/2,s=n-this.escapeOffset,a=o+this.escapeOffset,c=i-this.escapeOffset,l=r+this.escapeOffset,d=this.getEdgeSamples(i,r,t.y),h=this.getEdgeSamples(n,o,t.x),u=[];for(const t of d)u.push({x:s,y:t},{x:a,y:t});for(const t of h)u.push({x:t,y:c},{x:t,y:l});return this.dedupeCandidatePositions(u)}dedupeCandidatePositions(t){const e=[];for(const n of t)e.some(t=\u003eGj(t,n))||e.push(n);return e}pushEdgeSample(t,e,n,o){const i=Math.max(n,Math.min(o,e));t.some(t=\u003eMath.abs(t-i)\u003c=Wj)||t.push(i)}getEdgeSamples(t,e,n){const o=[],i=e-t;if(this.pushEdgeSample(o,n,t,e),i\u003c=Wj)return o;this.pushEdgeSample(o,t,t,e),this.pushEdgeSample(o,e,t,e),this.pushEdgeSample(o,(t+e)/2,t,e);const r=Math.max(t,Math.min(e,n)),s=Math.max(this.requiredViaToViaClearance,Wj),a=Math.ceil(i/s);for(let n=1;n\u003c=a;n++){const i=n*s;this.pushEdgeSample(o,r+i,t,e),this.pushEdgeSample(o,r-i,t,e)}return o}isInsideBoard(t){return!!(t.x\u003e=this.ogSrj.bounds.minX+this.viaRadius\u0026\u0026t.x\u003c=this.ogSrj.bounds.maxX-this.viaRadius\u0026\u0026t.y\u003e=this.ogSrj.bounds.minY+this.viaRadius\u0026\u0026t.y\u003c=this.ogSrj.bounds.maxY-this.viaRadius)\u0026\u0026(!(this.ogSrj.outline\u0026\u0026this.ogSrj.outline.length\u003e=3)||za(t,this.ogSrj.outline))}hasClearEscapePath(t){const{sourcePoint:e,candidate:n,sourceLayer:o,sourceObstacle:i}=t;if(this.ogSrj.outline\u0026\u0026this.ogSrj.outline.length\u003e=3){if(Fa({start:e,end:n,polygon:this.ogSrj.outline,margin:this.requiredTraceClearance}))return!1}for(const t of this.ogSrj.obstacles){if(t===i)continue;if(!t.layers.includes(o))continue;if(Xj(n,t))return!1;const r=Cl(t);if(Math.min(...r.map(t=\u003eRa(e,n,t.start,t.end)))+Wj\u003cthis.requiredTraceClearance)return!1}return!0}getBoardBoundarySegments(){if(this.ogSrj.outline\u0026\u0026this.ogSrj.outline.length\u003e=3)return this.ogSrj.outline.map((t,e)=\u003e({start:t,end:this.ogSrj.outline[(e+1)%this.ogSrj.outline.length]}));const{minX:t,maxX:e,minY:n,maxY:o}=this.ogSrj.bounds;return[{start:{x:t,y:n},end:{x:e,y:n}},{start:{x:e,y:n},end:{x:e,y:o}},{start:{x:e,y:o},end:{x:t,y:o}},{start:{x:t,y:o},end:{x:t,y:n}}]}getRayProbeDistance(){const{minX:t,maxX:e,minY:n,maxY:o}=this.ogSrj.bounds;return 2*Math.hypot(e-t,o-n)+this.viaDiameter}getRayIntersectionDistance(t){const{rayStart:e,rayEnd:n,segmentStart:o,segmentEnd:i}=t;if(!fe(e,n,o,i))return null;const r=ve(e,n,o,i);if(!r)return null;const s=xe(e,r);return s\u003c=Wj?null:s}getProjectedFreeSpace(t){const{sourcePoint:e,candidate:n}=t,o=n.x-e.x,i=n.y-e.y;return Math.abs(o)\u003c=Wj||Math.abs(i)\u003c=Wj?this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:o,y:i},travelDistance:xe(e,n)}):Math.min(this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:0,y:Math.sign(i)},travelDistance:Math.abs(i)}),this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:Math.sign(o),y:Math.sign(i)},travelDistance:xe(e,n)}),this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:Math.sign(o),y:0},travelDistance:Math.abs(o)}))}getProjectedFreeSpaceAlongDirection(t){const{sourcePoint:e,sourceLayer:n,sourceObstacle:o,direction:i,travelDistance:r}=t,s=Math.hypot(i.x,i.y);if(s\u003c=Wj||r\u003c=Wj)return 0;const a=this.getRayProbeDistance(),c=i.x/s,l=i.y/s,d={x:e.x+c*a,y:e.y+l*a};let h=Number.POSITIVE_INFINITY;for(const t of this.ogSrj.obstacles)if(t!==o\u0026\u0026t.layers.includes(n))for(const n of Cl(t)){const t=this.getRayIntersectionDistance({rayStart:e,rayEnd:d,segmentStart:n.start,segmentEnd:n.end});null!==t\u0026\u0026(h=Math.min(h,t))}for(const t of this.getBoardBoundarySegments()){const n=this.getRayIntersectionDistance({rayStart:e,rayEnd:d,segmentStart:t.start,segmentEnd:t.end});null!==n\u0026\u0026(h=Math.min(h,n))}return Number.isFinite(h)?Math.max(0,h-r):0}getMinBlockingClearance(t){const{candidate:e,connectionNetIds:n,sourceZ:o,targetZ:i}=t,r=Math.min(o,i),s=Math.max(o,i);let a=Number.POSITIVE_INFINITY;for(const t of this.ogSrj.obstacles){const n=this.getObstacleZs(t);if(!n.some(t=\u003et\u003e=r\u0026\u0026t\u003c=s))continue;if(t.isCopperPour\u0026\u0026!n.includes(o))continue;const i=Be(e,t)-this.viaRadius;if(a=Math.min(a,i),a+Wj\u003cthis.requiredViaToPadClearance)return a}return a}getMinPlacedEscapeViaClearance(t){let e=Number.POSITIVE_INFINITY;for(const n of this.createdEscapeVias){const o=xe(t,n)-this.viaDiameter;if(e=Math.min(e,o),e+Wj\u003cthis.obstacleMargin)return e}return e}selectPointOwner(t){const{point:e,groupConnections:n,matchingCopperPours:o}=t,i=ua(e),r=n.map(t=\u003e({connection:t,pointIndex:t.pointsToConnect.findIndex(t=\u003eua(t)===i)})).filter(t=\u003e-1!==t.pointIndex);return 0===r.length?null:(r.sort((t,e)=\u003e{const n=o.some(e=\u003ethis.obstacleMatchesConnectionNet(e,this.getConnectionNetIds(t.connection)));return n!==o.some(t=\u003ethis.obstacleMatchesConnectionNet(t,this.getConnectionNetIds(e.connection)))?n?-1:1:t.pointIndex-e.pointIndex}),r[0])}findBestEscapeViaCandidate(t){const{connection:e,point:n,pointIndex:o,matchingCopperPours:i,connectionNetIds:r,sourceObstacle:s}=t;if(!_o(n))return null;const a=n.layer,c=ko(a,this.ogSrj.layerCount),l=s??this.selectSourceObstacle({point:n,sourceLayer:a,connectionNetIds:r}),d=this.getCandidatePositions(n,l);let h=null;for(const t of i){const i=t.layers[0];if(!i||i===a)continue;const s=ko(i,this.ogSrj.layerCount),u=Hj(t);for(const p of d){if(!this.isInsideBoard(p))continue;if(!Xj(p,t))continue;if(!this.hasClearEscapePath({sourcePoint:n,candidate:p,sourceLayer:a,sourceObstacle:l}))continue;const d=this.getMinBlockingClearance({candidate:p,connectionNetIds:r,sourceZ:c,targetZ:s});if(d+Wj\u003cthis.requiredViaToPadClearance)continue;const m=this.getMinPlacedEscapeViaClearance(p);if(m+Wj\u003cthis.obstacleMargin)continue;const g=this.getProjectedFreeSpace({sourcePoint:n,candidate:p,sourceLayer:a,sourceObstacle:l}),f=Math.min(g,3),y=100*d-xe(n,p)-.5*Math.abs(s-c)+2*f+(Number.isFinite(m)?10*Math.min(m,this.requiredViaToViaClearance):0);(!h||y\u003eh.score)\u0026\u0026(h={pointId:`${Vj}${e.name}:${n.pointId??`p${o}`}:${i}:${this.nextEscapeViaIndex++}`,x:p.x,y:p.y,connectionName:e.name,rootConnectionName:e.__rootConnectionNames?.[0]??e.name,sourcePointIndex:o,sourcePointId:n.pointId,sourceLayer:a,targetLayer:i,targetPourKey:u,score:y})}}return h}buildPointPlacementPlans(t){const{mergedConnection:e,groupConnections:n,matchingCopperPours:o,connectionNetIds:i}=t,r=[];for(const t of e.pointsToConnect){const e=this.selectPointOwner({point:t,groupConnections:n,matchingCopperPours:o});if(!e)continue;const s=_o(t)?this.selectSourceObstacle({point:t,sourceLayer:t.layer,connectionNetIds:i}):void 0,a=_o(t)?this.getCandidatePositions(t,s).length:0;r.push({point:t,pointOwner:e,sourceObstacle:s,candidateCount:a})}return r.sort((t,e)=\u003e{if(t.candidateCount!==e.candidateCount)return t.candidateCount-e.candidateCount;const n=(t.sourceObstacle?.width??0)*(t.sourceObstacle?.height??0),o=(e.sourceObstacle?.width??0)*(e.sourceObstacle?.height??0);return n!==o?n-o:t.pointOwner.pointIndex-e.pointOwner.pointIndex})}_step(){const t=this.ogSrj.obstacles.filter(t=\u003et.isCopperPour),e=this.ogSrj.connections,n=e.map(t=\u003estructuredClone(t)),o=new Map(n.map(t=\u003e[t.name,t])),i=structuredClone(this.ogSrj.obstacles),r=pa([...e]);for(const n of r){const r=new Set(n.__rootConnectionNames??[n.name]),s=e.filter(t=\u003e(t.__rootConnectionNames??[t.name]).some(t=\u003er.has(t)));if(0===s.length)continue;const a=new Set;for(const t of s)for(const e of this.getConnectionNetIds(t))a.add(e);const c=t.filter(t=\u003ethis.obstacleMatchesConnectionNet(t,a));if(0===c.length)continue;const l=new Map,d=new Map,h=this.buildPointPlacementPlans({mergedConnection:n,groupConnections:s,matchingCopperPours:c,connectionNetIds:a});for(const{point:t,pointOwner:e,sourceObstacle:n}of h){const r=this.findBestEscapeViaCandidate({connection:e.connection,point:t,pointIndex:e.pointIndex,matchingCopperPours:c,connectionNetIds:a,sourceObstacle:n});if(!r)continue;const s=o.get(e.connection.name);if(!s)continue;if(s.pointsToConnect.some(t=\u003e_o(t)\u0026\u0026t.layer===r.sourceLayer\u0026\u0026Gj(t,r)))continue;s.pointsToConnect.push({x:r.x,y:r.y,layer:r.sourceLayer,pointId:r.pointId,terminalVia:{toLayer:r.targetLayer,viaDiameter:this.viaDiameter}}),this.escapeViaMetadataByPointId.set(r.pointId,r),this.createdEscapeVias.push(r),i.push(this.createEscapeViaObstacle({escapeVia:r,connectionNetIds:this.getConnectionNetIds(e.connection)}));const h=l.get(r.targetPourKey);h?h.push(r.pointId):l.set(r.targetPourKey,[r.pointId]),d.has(r.targetPourKey)||d.set(r.targetPourKey,e.connection.name)}for(const[t,e]of l.entries()){if(e.length\u003c=1)continue;const n=d.get(t);if(!n)continue;const i=o.get(n);i\u0026\u0026(i.externallyConnectedPointIds=[...i.externallyConnectedPointIds??[],e])}}this.outputSrj={...structuredClone(this.ogSrj),connections:n,obstacles:i},this.solved=!0}getOutputSimpleRouteJson(){return structuredClone(this.outputSrj)}getEscapeViaMetadataByPointId(){return new Map(this.escapeViaMetadataByPointId)}visualize(){return{title:\"Escape Via Location Solver\",points:this.outputSrj.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({x:e.x,y:e.y,color:!0===e.pointId?.startsWith(Vj)?\"#0f766e\":\"#dc2626\",label:!0===e.pointId?.startsWith(Vj)?`${t.name}\\nescape via`:t.name}))),lines:this.createdEscapeVias.map(t=\u003e{const e=this.outputSrj.connections.find(e=\u003ee.name===t.connectionName)?.pointsToConnect[t.sourcePointIndex]??null;return{points:e?[{x:e.x,y:e.y},{x:t.x,y:t.y}]:[{x:t.x,y:t.y}],strokeColor:\"#0f766e\"}}),circles:this.createdEscapeVias.map(t=\u003e({center:{x:t.x,y:t.y},radius:this.viaRadius,strokeColor:\"#0f766e\",label:`${t.connectionName}\\n${t.targetLayer}`})),rects:this.outputSrj.obstacles.filter(t=\u003e!t.isCopperPour).map(t=\u003e({...t,fill:\"rgba(220,38,38,0.12)\"}))}}},Zj=t=\u003e({...t}),qj=t=\u003e({...t,route:t.route?.map(Zj),vias:t.vias?.map(t=\u003e({...t}))}),Jj=t=\u003et.map(qj),Kj=\"#0000FF\",Qj=.15,t$=1e-6,e$=.1,n$=[\"top\",\"bottom\",\"left\",\"right\"],o$=t=\u003et.x*t.x+t.y*t.y,i$=(t,e)=\u003e({x:t.x-e.x,y:t.y-e.y}),r$=(t,e,n)=\u003e{const o=i$(n,e),i=o$(o);if(i\u003c=t$)return Math.sqrt(o$(i$(t,e)));const r=(a=i$(t,e),c=o,s=(a.x*c.x+a.y*c.y)/i,Math.max(0,Math.min(1,s)));var s,a,c;const l={x:e.x+o.x*r,y:e.y+o.y*r};return Math.sqrt(o$(i$(t,l)))},s$=t=\u003e1===t?.z?\"bottom\":\"top\",a$=(t,e,n)=\u003e(t.z??0)===(e.z??0)\u0026\u0026((e.z??0)===(n.z??0)\u0026\u0026(t.x===e.x\u0026\u0026e.x===n.x||t.y===e.y\u0026\u0026e.y===n.y)),c$=(t,e,n)=\u003e{const o=n?.get(t);if(o)return o;const i=t.route??[],r=t.traceThickness??Qj;let s=Number.POSITIVE_INFINITY,a=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY,l=Number.NEGATIVE_INFINITY,d=!1;const h=(t,e,n)=\u003e{s=Math.min(s,t-n),a=Math.min(a,e-n),c=Math.max(c,t+n),l=Math.max(l,e+n),d=!0},u={segments:[],segmentsByLayer:{top:[],bottom:[]},vias:(t.vias??[]).map(n=\u003e{const o=(n.diameter??t.viaDiameter??.3)/2;return h(n.x,n.y,o),{center:{x:n.x,y:n.y},radius:o,routeIndex:e}}),bounds:{minX:0,minY:0,maxX:0,maxY:0}};for(let t=0;t\u003ci.length-1;){const n=i[t];let o=t+1,s=i[o];const a=r/2;for(n\u0026\u0026h(n.x,n.y,a),s\u0026\u0026h(s.x,s.y,a);o\u003ci.length-1;){const t=i[o],e=i[o+1];if(!n||!t||!e)break;if(s$(n)!==s$(t))break;if(s$(t)!==s$(e))break;if(!a$(n,t,e))break;o+=1,s=e,h(e.x,e.y,a)}if(!n||!s){t+=1;continue}const c=s$(n),l={start:n,end:s,routeIndex:e,pointIndex:t,endPointIndex:o,thickness:r,halfThickness:a,layer:c,minX:Math.min(n.x,s.x)-a,maxX:Math.max(n.x,s.x)+a,minY:Math.min(n.y,s.y)-a,maxY:Math.max(n.y,s.y)+a};u.segments.push(l),u.segmentsByLayer[c].push(l),t=o}if(!d)for(const t of i)h(t.x,t.y,r/2);return u.bounds=d?{minX:s,minY:a,maxX:c,maxY:l}:{minX:0,minY:0,maxX:0,maxY:0},n?.set(t,u),u},l$=(t,e,n)=\u003ee.x\u003c=Math.max(t.x,n.x)+t$\u0026\u0026e.x\u003e=Math.min(t.x,n.x)-t$\u0026\u0026e.y\u003c=Math.max(t.y,n.y)+t$\u0026\u0026e.y\u003e=Math.min(t.y,n.y)-t$,d$=(t,e,n)=\u003e(e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y),h$=(t,e,n,o)=\u003e((t,e,n,o)=\u003e{const i=d$(t,e,n),r=d$(t,e,o),s=d$(n,o,t),a=d$(n,o,e);return!!(Math.abs(i)\u003c=t$\u0026\u0026l$(t,n,e))||!!(Math.abs(r)\u003c=t$\u0026\u0026l$(t,o,e))||!!(Math.abs(s)\u003c=t$\u0026\u0026l$(n,t,o))||!!(Math.abs(a)\u003c=t$\u0026\u0026l$(n,e,o))||i\u003e0!=r\u003e0\u0026\u0026s\u003e0!=a\u003e0})(t,e,n,o)?0:Math.min(r$(t,n,o),r$(e,n,o),r$(n,t,e),r$(o,t,e)),u$=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=t$\u0026\u0026Math.abs(t.y-e.y)\u003c=t$,p$=(t,e)=\u003eu$(t.start,e.start)||u$(t.start,e.end)||u$(t.end,e.start)||u$(t.end,e.end),m$=t=\u003e{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))},g$=(t,e)=\u003e{const n=m$(t),o=m$(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))},f$=(t,e,n)=\u003et.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY,y$=(t,e,n)=\u003e{const o=n+t.halfThickness+e.halfThickness-t$;return t.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY\u0026\u0026o\u003e0},_$=(t,e,n,o)=\u003e{const i=o+n.halfThickness+e-t$,r=t.x-i,s=t.x+i,a=t.y-i,c=t.y+i;return r\u003c=n.maxX\u0026\u0026s\u003e=n.minX\u0026\u0026a\u003c=n.maxY\u0026\u0026c\u003e=n.minY},b$=(t,e)=\u003e{const n=new WeakMap,o=t.map((t,e)=\u003ec$(t,e,n)),i=[],r=new Set,s=t=\u003e{r.has(t.label)||(r.add(t.label),i.push(t))};for(let n=0;n\u003co.length;n+=1){const i=o[n];if(i)for(let r=n+1;r\u003co.length;r+=1){const a=o[r];if(a\u0026\u0026(!g$(t[n],t[r])\u0026\u0026f$(i.bounds,a.bounds,e))){for(const t of[\"top\",\"bottom\"]){const o=i.segmentsByLayer[t],c=a.segmentsByLayer[t];for(const i of o)for(const o of c){if(p$(i,o))continue;if(!y$(i,o,e))continue;const a=e+(i.thickness+o.thickness)/2-t$;if(h$(i.start,i.end,o.start,o.end)\u003e=a)continue;s({center:{x:(Math.max(i.minX-e,o.minX-e)+Math.min(i.maxX+e,o.maxX+e))/2,y:(Math.max(i.minY-e,o.minY-e)+Math.min(i.maxY+e,o.maxY+e))/2},label:`trace-violation:${n}:s${i.pointIndex}:${r}:s${o.pointIndex}:${t}`})}}for(const t of i.segments)for(const[o,i]of a.vias.entries()){if(!_$(i.center,i.radius,t,e))continue;const a=e+t.halfThickness+i.radius-t$;r$(i.center,t.start,t.end)\u003e=a||s({center:i.center,label:`trace-violation:${n}:s${t.pointIndex}:${r}:v${o}`})}for(const t of a.segments)for(const[o,a]of i.vias.entries()){if(!_$(a.center,a.radius,t,e))continue;const i=e+t.halfThickness+a.radius-t$;r$(a.center,t.start,t.end)\u003e=i||s({center:a.center,label:`trace-violation:${n}:v${o}:${r}:s${t.pointIndex}`})}}}}return(t=\u003e{const e=[];for(const n of t){const t=e.find(t=\u003e{return e=t.center,o=n.center,Math.hypot(e.x-o.x,e.y-o.y)\u003c=.28;var e,o});t?(t.center={x:(t.center.x*t.count+n.center.x)/(t.count+1),y:(t.center.y*t.count+n.center.y)/(t.count+1)},t.labels.push(n.label),t.count+=1):e.push({center:n.center,labels:[n.label],count:1})}return e.map((t,e)=\u003e({center:t.center,radius:Math.min(.3,.2+.035*Math.sqrt(t.count-1)),stroke:\"#f59e0b\",fill:\"rgba(245, 158, 11, 0.46)\",label:1===t.count?t.labels[0]:`trace-violations:${e}:count-${t.count}`}))})(i)},x$=({routeIndexes:t,layers:e,routePointIndexes:n})=\u003e`${t[0]}:${e[0]}:${n[0].join(\",\")}:${t[1]}:${e[1]}:${n[1].join(\",\")}`,v$=(t,e,n,o,i,r,s)=\u003e{const a=((t,e,n,o,i,r)=\u003et\u003cn?`${t}:${e}:${i.join(\",\")}:${n}:${o}:${r.join(\",\")}`:`${n}:${o}:${r.join(\",\")}:${t}:${e}:${i.join(\",\")}`)(e,n,o,i,r,s),c=t.get(a);if(c){const[t,n]=e\u003co?[r,s]:[s,r];for(const e of t)c.routePointIndexes[0].includes(e)||c.routePointIndexes[0].push(e);for(const t of n)c.routePointIndexes[1].includes(t)||c.routePointIndexes[1].push(t);return c.routePointIndexes[0].sort((t,e)=\u003et-e),void c.routePointIndexes[1].sort((t,e)=\u003et-e)}e\u003co?t.set(a,{routeIndexes:[e,o],layers:[n,i],routePointIndexes:[[...new Set(r)].sort((t,e)=\u003et-e),[...new Set(s)].sort((t,e)=\u003et-e)]}):t.set(a,{routeIndexes:[o,e],layers:[i,n],routePointIndexes:[[...new Set(s)].sort((t,e)=\u003et-e),[...new Set(r)].sort((t,e)=\u003et-e)]})},S$=t=\u003e{const e=[];for(let n=t.pointIndex;n\u003c=t.endPointIndex;n+=1)e.push(n);return e},I$=(t,e)=\u003e!e||t.some(t=\u003ee.has(t)),C$=(t,e)=\u003e{const n=t.route??[],o=[];for(let t=0;t\u003cn.length;t+=1){const i=n[t];i\u0026\u0026(Math.abs(i.x-e.center.x)\u003c=t$\u0026\u0026Math.abs(i.y-e.center.y)\u003c=t$\u0026\u0026o.push(t))}return o},P$=(t,e,n)=\u003et.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY,M$=(t,e,n)=\u003e{const o=n+t.halfThickness+e.halfThickness-t$;return t.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY\u0026\u0026o\u003e0},N$=(t,e,n,o)=\u003e{const i=o+n.halfThickness+e-t$,r=t.x-i,s=t.x+i,a=t.y-i,c=t.y+i;return r\u003c=n.maxX\u0026\u0026s\u003e=n.minX\u0026\u0026a\u003c=n.maxY\u0026\u0026c\u003e=n.minY},w$=(t,e,n)=\u003e{const o=n+t.radius+e.radius-t$;return Math.abs(t.center.x-e.center.x)\u003c=o\u0026\u0026Math.abs(t.center.y-e.center.y)\u003c=o},T$=(t,e,n,o,i)=\u003e{const r=t.map((t,e)=\u003ec$(t,e,o)),s=new Map;if(0===e.size)return[];const a=Array.from(e),c=new Map,l=t=\u003e{const e=c.get(t);if(e)return e;const o=r[t];if(!o)return[];const i=[];for(let e=0;e\u003cr.length;e+=1){if(e===t)continue;const s=r[e];s\u0026\u0026(P$(o.bounds,s.bounds,n)\u0026\u0026i.push(e))}return c.set(t,i),i};for(const t of a){const o=r[t];if(!o)continue;const a=l(t),c=i?.get(t);for(const l of o.segments){const o=S$(l);if(I$(o,c))for(const c of a){if(t\u003ec\u0026\u0026e.has(c))continue;const a=r[c];if(!a)continue;const d=i?.get(c),h=a.segmentsByLayer[l.layer];for(const t of h){const e=S$(t);if(!I$(e,d))continue;if(p$(l,t))continue;if(!M$(l,t,n))continue;const i=n+(l.thickness+t.thickness)/2-t$;h$(l.start,l.end,t.start,t.end)\u003ci\u0026\u0026v$(s,l.routeIndex,l.layer,t.routeIndex,t.layer,o,e)}}}}for(const o of a){const a=r[o];if(!a)continue;const c=l(o),d=i?.get(o);for(const l of a.vias){const a=C$(t[l.routeIndex],l);if(I$(a,d))for(const t of c){if(o\u003et\u0026\u0026e.has(t))continue;const c=r[t];if(!c)continue;const d=i?.get(t);for(const t of c.segments){const e=S$(t);if(!I$(e,d))continue;if(!N$(l.center,l.radius,t,n))continue;const o=n+t.thickness/2+l.radius-t$;r$(l.center,t.start,t.end)\u003co\u0026\u0026v$(s,t.routeIndex,t.layer,l.routeIndex,\"via\",e,a)}}}}for(const e of a){const o=r[e];if(!o)continue;const a=l(e),c=i?.get(e);for(const e of o.segments){const o=S$(e);if(I$(o,c))for(const c of a){const a=r[c];if(!a)continue;const l=i?.get(c);for(const i of a.vias){const r=C$(t[i.routeIndex],i);if(!I$(r,l))continue;if(!N$(i.center,i.radius,e,n))continue;const a=n+e.thickness/2+i.radius-t$;r$(i.center,e.start,e.end)\u003ca\u0026\u0026v$(s,e.routeIndex,e.layer,i.routeIndex,\"via\",o,r)}}}}for(const o of a){const a=r[o];if(!a)continue;const c=l(o),d=i?.get(o);for(const l of a.vias){const a=C$(t[l.routeIndex],l);if(I$(a,d))for(const d of c){if(o\u003ed\u0026\u0026e.has(d))continue;const c=r[d];if(!c)continue;const h=i?.get(d);for(const e of c.vias){const o=C$(t[e.routeIndex],e);if(!I$(o,h))continue;if(!w$(l,e,n))continue;const i=n+l.radius+e.radius-t$;Math.hypot(l.center.x-e.center.x,l.center.y-e.center.y)\u003ci\u0026\u0026v$(s,l.routeIndex,\"via\",e.routeIndex,\"via\",a,o)}}}}return Array.from(s.values())},R$=(t,e)=\u003et.x\u003e=e.minX-t$\u0026\u0026t.x\u003c=e.maxX+t$\u0026\u0026t.y\u003e=e.minY-t$\u0026\u0026t.y\u003c=e.maxY+t$,E$=(t,e,n)=\u003e{switch(e){case\"left\":return{minX:t.minX,maxX:t.minX+n,minY:t.minY,maxY:t.maxY};case\"right\":return{minX:t.maxX-n,maxX:t.maxX,minY:t.minY,maxY:t.maxY};case\"top\":return{minX:t.minX,maxX:t.maxX,minY:t.maxY-n,maxY:t.maxY};case\"bottom\":return{minX:t.minX,maxX:t.maxX,minY:t.minY,maxY:t.minY+n}}},A$=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;let r=0,s=1;const a=(t,e)=\u003e{if(Math.abs(t)\u003c=t$)return e\u003e=-1e-6;const n=e/t;return t\u003c0?!(n\u003es)\u0026\u0026(n\u003er\u0026\u0026(r=n),!0):!(n\u003cr)\u0026\u0026(n\u003cs\u0026\u0026(s=n),!0)};if(!(a(-o,t.x-n.minX)\u0026\u0026a(o,n.maxX-t.x)\u0026\u0026a(-i,t.y-n.minY)\u0026\u0026a(i,n.maxY-t.y)))return 0;const c=Math.hypot(o,i);return Math.max(0,s-r)*c},O$=(t,e)=\u003en$.filter(n=\u003e{switch(n){case\"left\":return Math.abs(t.x-e.minX)\u003c=t$;case\"right\":return Math.abs(t.x-e.maxX)\u003c=t$;case\"top\":return Math.abs(t.y-e.maxY)\u003c=t$;case\"bottom\":return Math.abs(t.y-e.minY)\u003c=t$}return!1}),k$=(t,e)=\u003e{const n=[];return t.x\u003ce.minX-t$\u0026\u0026n.push(\"left\"),t.x\u003ee.maxX+t$\u0026\u0026n.push(\"right\"),t.y\u003ee.maxY+t$\u0026\u0026n.push(\"top\"),t.y\u003ce.minY-t$\u0026\u0026n.push(\"bottom\"),n},L$=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;switch(n){case\"left\":case\"right\":return Math.abs(o)\u003c=t$\u0026\u0026Math.abs(i)\u003et$;case\"top\":case\"bottom\":return Math.abs(i)\u003c=t$\u0026\u0026Math.abs(o)\u003et$}},D$=(t,e,n)=\u003e{const o=[],i=Math.max(n,t$),r=Math.min(.1,i/4);for(let n=0;n\u003ct.length;n+=1){const s=t[n],a=s?.route??[];for(let t=0;t\u003ca.length-1;t+=1){const c=a[t],l=a[t+1];if(!c||!l)continue;const d=k$(c,e),h=k$(l,e),u=O$(c,e),p=O$(l,e),m=n$.filter(t=\u003e{if(s.connectedPadSides?.includes(t))return!1;return!(A$(c,l,E$(e,t,i))\u003c=r)\u0026\u0026!!L$(c,l,t)}),g=!R$(c,e)||!R$(l,e),f=Array.from(new Set([...m,...d,...h]));(g||0!==f.length)\u0026\u0026o.push({routeIndex:n,connectionName:s.connectionName??s.rootConnectionName??`route-${n}`,segmentIndex:t,touchedSides:f,startSides:u,endSides:p,start:c,end:l})}}return o},z$=t=\u003et?.center\u0026\u0026t.width\u0026\u0026t.height?{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,width:t.width,height:t.height,center:t.center}:null,F$=t=\u003e\"bottom\"===t?Kj:\"#FF0000\",B$=t=\u003e{const e=t.route??[],n=[];if(e.length\u003c2)return n;let o=s$(e[0]),i=[e[0]];for(let r=1;r\u003ce.length;r+=1){const s=e[r],a=s$(s);a===o?i.push(s):(i.length\u003e=2\u0026\u0026n.push({points:i,strokeColor:F$(o),strokeWidth:t.traceThickness??Qj,label:t.connectionName??\"route\"}),o=a,i=[e[r-1],s])}return i.length\u003e=2\u0026\u0026n.push({points:i,strokeColor:F$(o),strokeWidth:t.traceThickness??Qj,label:t.connectionName??\"route\"}),n},j$=(t,e)=\u003e({title:`HighDensityRepair02 Initial State (margin=${e})`,routes:t}),$=t=\u003e{const e=[];for(const n of t){const t=e[e.length-1];t\u0026\u0026t.z===n.z\u0026\u0026u$(t,n)||e.push(n)}return e},Y$=(t,e,n)=\u003e{const o=Math.max(0,t.minX-e.maxX,e.minX-t.maxX),i=Math.max(0,t.minY-e.maxY,e.minY-t.maxY);return Math.hypot(o,i)\u003c=n+t$},X$=(t,e)=\u003e{let n=Number.POSITIVE_INFINITY;for(const o of t.segments)for(const t of e.segments){if(o.layer!==t.layer)continue;const e=h$(o.start,o.end,t.start,t.end)-(o.thickness+t.thickness)/2;n=Math.min(n,e)}return n},V$=({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,maximumAllowedClearance:o})=\u003e{const i=new WeakMap,r=new WeakMap,s=[],a=Array.from(n).sort((t,e)=\u003et-e),c=t.map((t,e)=\u003ec$(t,e,i)),l=e.map((t,e)=\u003ec$(t,e,r)),d=new Set;for(const t of a)for(let n=0;n\u003ce.length;n+=1){if(n===t)continue;const e=Math.min(t,n),i=Math.max(t,n),r=`${e}:${i}`;if(d.has(r))continue;d.add(r);const a=l[e],h=l[i];if(!a||!h||!Y$(a.bounds,h.bounds,o))continue;const u=X$(a,h);if(!Number.isFinite(u)||u\u003eo+t$||!c[e]||!c[i])continue;const p=X$(c[e],c[i]);!Number.isFinite(p)||u\u003e=p-t$||s.push({routeIndexes:[e,i],previousClearance:p,nextClearance:u})}return s},W$=.001,H$=(t,e)=\u003et.map(t=\u003e{const n=t.route??[];return 0===n.length?t:{...t,route:n.map((t,o)=\u003e0===o||o===n.length-1?((t,e)=\u003e{const n={...t};return Math.abs(n.x-e.minX)\u003c=W$?n.x=e.minX:Math.abs(n.x-e.maxX)\u003c=W$\u0026\u0026(n.x=e.maxX),Math.abs(n.y-e.minY)\u003c=W$?n.y=e.minY:Math.abs(n.y-e.maxY)\u003c=W$\u0026\u0026(n.y=e.maxY),n})(t,e):t)}}),G$=(t,e)=\u003eArray.from(e).flatMap(e=\u003eB$(t[e]).map(t=\u003e({...t,strokeColor:\"#000000\",strokeWidth:t.strokeWidth,label:`candidate:${t.label}`}))),U$=(t,e,n,o,i)=\u003e{const r=\"rgba(0, 0, 0, 0)\";switch(e){case\"left\":return{center:{x:t.minX+n/2,y:t.center.y},width:n,height:t.height,stroke:r,fill:o,label:i};case\"right\":return{center:{x:t.maxX-n/2,y:t.center.y},width:n,height:t.height,stroke:r,fill:o,label:i};case\"top\":return{center:{x:t.center.x,y:t.maxY-n/2},width:t.width,height:n,stroke:r,fill:o,label:i};case\"bottom\":return{center:{x:t.center.x,y:t.minY+n/2},width:t.width,height:n,stroke:r,fill:o,label:i}}},Z$=({routes:t,candidateRoutes:e,candidateRouteIndexes:n,originalRoutes:o,boundary:i,side:r,margin:s,rejected:a,rejectionReason:c})=\u003e{const l=Array.from(n).map(t=\u003ee[t].connectionName??`route-${t}`);return{title:a?`${r} move rejected (${c})`:`${r} move accepted`,routes:a?t:e,originalRoutes:o,activeSide:r,candidateRouteNames:l,overlayLines:a?G$(e,n):[],overlayRects:[U$(i,r,s,a?\"rgba(220, 38, 38, 0.14)\":\"rgba(16, 185, 129, 0.14)\",a?`rejected:${r}`:`accepted:${r}`)]}},q$=(t,e,n,o)=\u003e{const i=(t?.adjacentObstacles??[]).some(t=\u003e((t,e,n,o)=\u003e{const i=(t=\u003et.center\u0026\u0026t.width\u0026\u0026t.height?{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}:null)(t);if(!i)return!1;switch(n){case\"left\":return i.maxX\u003e=e.minX-t$\u0026\u0026i.minX\u003c=e.minX+o+t$;case\"right\":return i.minX\u003c=e.maxX+t$\u0026\u0026i.maxX\u003e=e.maxX-o-t$;case\"top\":return i.minY\u003c=e.maxY+t$\u0026\u0026i.maxY\u003e=e.maxY-o-t$;case\"bottom\":return i.maxY\u003e=e.minY-t$\u0026\u0026i.minY\u003c=e.minY+o+t$}})(t,e,n,o));return{hasObstacle:i,moveAmount:i?o:o/2}},J$=({start:t,end:e,side:n,boundary:o,amount:i,targetAxisValue:r})=\u003e{const s=(({side:t,boundary:e,amount:n,targetAxisValue:o})=\u003e{const i=o??(()=\u003e{switch(t){case\"left\":return e.minX+n;case\"right\":return e.maxX-n;case\"top\":return e.maxY-n;case\"bottom\":return e.minY+n}})();switch(t){case\"left\":case\"right\":return Math.min(Math.max(i,e.minX),e.maxX);case\"top\":case\"bottom\":return Math.min(Math.max(i,e.minY),e.maxY)}})({side:n,boundary:o,amount:i,targetAxisValue:r});switch(n){case\"left\":case\"right\":return $([t,{x:s,y:t.y,z:t.z},{x:s,y:e.y,z:e.z},e]);case\"top\":case\"bottom\":return $([t,{x:t.x,y:s,z:t.z},{x:e.x,y:s,z:e.z},e])}},K$=(t,e,n,o,i,r,s,a=!1)=\u003e{const c=t.route??[];if(c.length\u003c2||0===e.length)return qj(t);const l=a?i:Math.max(i,r),d=((t,e)=\u003e{switch(t){case\"left\":return{x:e,y:0};case\"right\":return{x:-e,y:0};case\"top\":return{x:0,y:-e};case\"bottom\":return{x:0,y:e}}})(o,l);if(a||(t.vias?.length??0)\u003e0||c.length\u003e2){const n=qj(t),o=n.route??[];for(const t of e){const e=o[t];e\u0026\u0026(o[t]={...e,x:e.x+d.x,y:e.y+d.y})}for(const o of n.vias??[]){e.some(e=\u003e{const n=t.route?.[e];return!!n\u0026\u0026u$(n,o)})\u0026\u0026(o.x+=d.x,o.y+=d.y)}return n}const h=qj(t);if(2===c.length\u0026\u00262===e.length\u0026\u00260===e[0]\u0026\u00261===e[1]){const e=c[0],i=c[1];return qj({...t,route:J$({start:e,end:i,side:o,boundary:n,amount:l,targetAxisValue:s})})}return h},Q$=(t,e,n)=\u003e{switch(n){case\"left\":return t.x-e.minX;case\"right\":return e.maxX-t.x;case\"top\":return e.maxY-t.y;case\"bottom\":return t.y-e.minY}},tY=(t,e,n)=\u003e{const o=(t=\u003e{const e=t.route??[];if(0===e.length)return[];const n=[];for(let t=0;t\u003ce.length;t+=1){const o=e[t];if(!o)continue;0===t||t===e.length-1||n.push(o);const i=e[t+1];i\u0026\u0026n.push({x:(o.x+i.x)/2,y:(o.y+i.y)/2})}return n})(t);return 0===o.length?Number.POSITIVE_INFINITY:o.reduce((t,o)=\u003eMath.min(t,Q$(o,e,n)),Number.POSITIVE_INFINITY)},eY=(t,e,n=[])=\u003e{const o=t.route??[],i=[],r=new Set,s=0===e.length||e.includes(\"via\");if(2===o.length)return[0,1];const a=t=\u003e{if(t\u003c=0||t\u003e=o.length-1)return;if(r.has(t))return;const n=o[t];n\u0026\u0026(s||e.includes(s$(n)))\u0026\u0026(r.add(t),i.push(t))};if(n.length\u003e0)for(const t of n)a(t);else for(let t=1;t\u003co.length-1;t+=1)a(t);for(let t=0;t\u003ci.length;t+=1){const e=i[t],n=o[e];if(n)for(let t=1;t\u003co.length-1;t+=1){if(r.has(t))continue;const e=o[t];e\u0026\u0026(e.z!==n.z\u0026\u0026u$(e,n)\u0026\u0026(r.add(t),i.push(t)))}}return i.sort((t,e)=\u003et-e),i},nY=(t,e)=\u003eMath.max(0,...(t.route??[]).map(t=\u003eMath.max(e.minX-t.x,t.x-e.maxX,e.minY-t.y,t.y-e.maxY,0))),oY=(t,e,n,o)=\u003eQ$(t,e,n)\u003c=o+t$,iY=(t,e,n,o)=\u003e{const i=t.route??[],r=[],s=new Set;let a=1,c=i.length-2;for(;a\u003ci.length-1\u0026\u0026u$(i[a],i[0]);)a+=1;for(;c\u003e0\u0026\u0026u$(i[c],i[i.length-1]);)c-=1;for(let t=a;t\u003c=c;t+=1)oY(i[t],e,n,o)\u0026\u0026(s.add(t),r.push(t));for(let t=0;t\u003cr.length;t+=1){const e=i[r[t]];if(e)for(let t=a;t\u003c=c;t+=1){if(s.has(t))continue;const n=i[t];n\u0026\u0026(n.z!==e.z\u0026\u0026u$(n,e)\u0026\u0026(s.add(t),r.push(t)))}}return 0===r.length\u0026\u00262===i.length\u0026\u0026i.some(t=\u003eoY(t,e,n,o))?[0,1]:(r.sort((t,e)=\u003et-e),r)},rY=(t,e,n)=\u003e{const o=t.route??[],i=0===n?o[0]:o[o.length-1];return i?n$.filter(t=\u003eQ$(i,e,t)\u003c=t$):[]},sY=(t,e,n)=\u003e{const o=t.route??[],i=e.route??[];if(0===o.length||0===i.length)return!0;for(const e of[0,-1]){const o=rY(t,n,e);if(0===o.length)continue;const r=0===e?i[0]:i[i.length-1];if(!r)return!1;for(const t of o)if(Q$(r,n,t)\u003et$)return!1}return!0},aY=(t,e)=\u003eMath.hypot(e.x-t.x,e.y-t.y),cY=(t,e,n,o)=\u003e{const i=t.route??[];if(0===i.length)return\"none\";let r=!1;for(let t=0;t\u003ci.length;t+=1){const s=i[t];if(s\u0026\u0026oY(s,e,n,o)){if(0!==t\u0026\u0026t!==i.length-1)return\"interior\";r=!0}}for(let t=0;t\u003ci.length-1;t+=1){const r=i[t],s=i[t+1];if(r\u0026\u0026s\u0026\u0026(oY(r,e,n,o)\u0026\u0026oY(s,e,n,o)\u0026\u0026!(aY(r,s)\u003c=t$)))return\"interior\"}return r?\"endpoint\":\"none\"},lY=({currentRoutes:t,routeIndex:e,side:n,moveSide:o=n,boundary:i,margin:r,moveAmount:s,geometryCache:a})=\u003e{const c=t[e],l=2===(c.route?.length??0),d=iY(c,i,n,r);if(0===d.length)return null;const h=new Set,u=new Map,p=new Set,m=t.slice();let g=!1,f=\"overlap\";const y=new Set([e]),_=new Map([[e,new Set]]),b=new Map([[e,new Set]]),x=[e];let v=0,S=null,I=null,C=null,P=null;const M=t=\u003enew Set(t.map(t=\u003ex$(t))),N=()=\u003eS||(S=T$(t,h,r,a,u),S),w=()=\u003eC||(C=T$(t,h,0,a,u),C),T=()=\u003eP||(P=T$(m,h,0,a,u),P);for(;v\u003cx.length\u0026\u0026!g;){const c=x[v];if(v+=1,y.delete(c),h.has(c))continue;const l=m[c],d=Array.from(_.get(c)??[]),w=Array.from(b.get(c)??[]);_.delete(c),b.delete(c);const T=c===e?iY(l,i,n,r):eY(l,d,w);if(0===T.length){if(c===e)return null;g=!0,f=\"eventual-overlap\";break}const R=l.route??[],E=c===e?void 0:\"left\"===o||\"right\"===o?(R[T[0]]?.x??0)+(\"left\"===o?s:-s):(R[T[0]]?.y??0)+(\"top\"===o?-s:s);m[c]=K$(l,T,i,o,s,r,E,c!==e),h.add(c),u.set(c,new Set(T)),S=null,I=null,C=null,P=null,2===(l.route?.length??0)\u0026\u0026p.add(c);const A=nY(t[c],i);if(nY(m[c],i)\u003eA+1e-6){g=!0,f=\"boundary\";break}if(!sY(t[c],m[c],i)){g=!0,f=\"endpoint-boundary\";break}const O=T$(m,new Set([c]),r,a,new Map([[c,new Set(T)]]));for(const t of O){if(M(N()).has(x$(t)))continue;const[e,n]=t.routeIndexes,o=h.has(e),i=h.has(n);if(o\u0026\u0026i)continue;const r=o?n:e,s=o?t.layers[1]:t.layers[0],a=o?t.routePointIndexes[1]:t.routePointIndexes[0];if(h.has(r)||y.has(r)){if(y.has(r)){const t=_.get(r)??new Set;t.add(s),_.set(r,t);const e=b.get(r)??new Set;for(const t of a)e.add(t);b.set(r,e)}}else y.add(r),x.push(r),_.set(r,new Set([s])),b.set(r,new Set(a))}}if(!g\u0026\u0026h.size\u003e1){const t=M(N()),e=M(I||(I=T$(m,h,r,a,u),I));for(const n of e)if(!t.has(n)){g=!0,f=\"eventual-overlap\";break}}if(!g\u0026\u0026h.size\u003e1){const t=M(w()),e=M(T());for(const n of e)if(!t.has(n)){g=!0,f=\"eventual-overlap\";break}}if(!g){const e=new Set(T$(t,h,0,a).map(t=\u003ex$(t))),n=T$(m,h,0,a);for(const t of n){const n=x$(t);if(!e.has(n)){g=!0,f=\"eventual-overlap\";break}}}if(!g){const e=(({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,boundary:o,activeSide:i})=\u003e{const r=n$.filter(t=\u003et!==i),s=[];for(const i of n){const n=t[i],a=e[i];if(n\u0026\u0026a)for(const t of r){const e=tY(n,o,t),r=tY(a,o,t);e\u003et$\u0026\u0026r\u003c=t$\u0026\u0026s.push({routeIndex:i,side:t,previousClearance:e,nextClearance:r})}}return s})({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,boundary:i,activeSide:n});e.length\u003e0\u0026\u0026(g=!0,f=\"boundary-touch\")}if(!g){const e=(({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,geometryCache:o,currentConflicts:i,candidateConflicts:r})=\u003e{const s=i??T$(t,n,0,o),a=r??T$(e,n,0,o),c=new Set(s.map(t=\u003ex$(t)));return a.filter(t=\u003e{const o=x$(t);if(c.has(o))return!1;const[i,r]=t.routeIndexes,[s,a]=t.layers,l=n.has(i),d=n.has(r);if(l\u0026\u0026d)return!1;const h=l?a:s,u=e[l?r:i];return!!u\u0026\u00260===eY(u,[h]).length})})({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,geometryCache:a,currentConflicts:w(),candidateConflicts:T()});e.length\u003e0\u0026\u0026(g=!0,f=\"fixed-trace-touch\")}if(!g){V$({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,maximumAllowedClearance:Math.min(r/2,e$)}).length\u003e0\u0026\u0026(g=!0,f=\"trace-clearance\")}return!g\u0026\u0026((t,e,n,o,i,r)=\u003eArray.from(n).some(n=\u003e{const s=t[n],a=e[n];return n$.filter(t=\u003et!==i).some(t=\u003e{const e=cY(s,o,t,r),n=cY(a,o,t,r);return\"none\"===e\u0026\u0026\"none\"!==n})}))(t,m,h,i,n,r)\u0026\u0026(g=!0,f=\"side-regression\"),{isTwoPointRoute:l,movableIndexes:d,candidateRouteIndexes:h,movedTwoPointRouteIndexes:p,candidateRoutes:m,rejected:g,rejectionReason:f}},dY=(t,e,n,o,i)=\u003e{const r=t.route??[];if(0===e.length)return null;if(\"top\"===o||\"bottom\"===o){const t=e.reduce((t,e)=\u003et+(r[e]?.x??n.center.x),0)/e.length;return t\u003cn.center.x-i/2?\"right\":t\u003en.center.x+i/2?\"left\":null}const s=e.reduce((t,e)=\u003et+(r[e]?.y??n.center.y),0)/e.length;return s\u003en.center.y+i/2?\"bottom\":s\u003cn.center.y-i/2?\"top\":null},hY=({side:t,sample:e,boundary:n,margin:o,repairedRoutes:i,frames:r,captureProgressFrames:s,lockedTwoPointRoutes:a,geometryCache:c,allowTwoPointWithoutObstacle:l=!1})=\u003e{const{hasObstacle:d,moveAmount:h}=q$(e,n,t,o);s\u0026\u0026r.push(((t,e,n,o,i,r)=\u003e({title:`${n} boundary analysis: move=${i.toFixed(3)} (${r?\"obstacle-side\":\"clear-side\"})`,routes:t,activeSide:n,overlayRects:[U$(e,n,o,\"rgba(245, 158, 11, 0.16)\",`strip:${n}`)]}))(Jj(i),n,t,o,h,d));const u=new Set;let p=0;for(let e=0;e\u003ci.length;e+=1){if(u.has(e))continue;if(a.has(e))continue;const m=i[e];if(m.connectedPadSides?.includes(t))continue;if(2===(m.route?.length??0)\u0026\u0026!d\u0026\u0026!l)continue;let g=lY({currentRoutes:i,routeIndex:e,side:t,boundary:n,margin:o,moveAmount:h,geometryCache:c});if(g){if(g.rejected){const r=dY(m,g.movableIndexes,n,t,o);if(r){const s=lY({currentRoutes:i,routeIndex:e,side:t,moveSide:r,boundary:n,margin:o,moveAmount:h,geometryCache:c});s\u0026\u0026!s.rejected\u0026\u0026(g=s)}}if(s\u0026\u0026r.push(Z$({routes:Jj(i),candidateRoutes:g.candidateRoutes,candidateRouteIndexes:g.candidateRouteIndexes,originalRoutes:g.rejected?void 0:Array.from(g.candidateRouteIndexes).map(t=\u003eqj(i[t])),boundary:n,side:t,margin:o,rejected:g.rejected,rejectionReason:g.rejectionReason})),!g.rejected){i.splice(0,i.length,...g.candidateRoutes);for(const t of g.movedTwoPointRouteIndexes)a.add(t);p+=1}u.add(e)}}return{movesAccepted:p}},uY=(t,e,n,o)=\u003eoY(t,e,n,o),pY=(t,e,n,o)=\u003e{switch(n){case\"left\":return{...t,x:Math.min(e.minX+o,e.maxX)};case\"right\":return{...t,x:Math.max(e.maxX-o,e.minX)};case\"top\":return{...t,y:Math.max(e.maxY-o,e.minY)};case\"bottom\":return{...t,y:Math.min(e.minY+o,e.maxY)}}},mY=t=\u003e`${t.routeIndexes[0]}:${t.layers[0]}:${t.routeIndexes[1]}:${t.layers[1]}`,gY=t=\u003e{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))},fY=(t,e)=\u003e{const n=gY(t),o=gY(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))},yY=(t,e,n)=\u003et?D$([t],e,n).length:0,_Y=(t,e,n,o)=\u003e{const i=new Set(T$(t,new Set([n]),o).map(x$));return T$(e,new Set([n]),o).some(t=\u003e!i.has(x$(t)))},bY=(t,e,n)=\u003eD$(t,e,n).length,xY=t=\u003e{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))},vY=(t,e)=\u003eT$(t,new Set(t.map((t,e)=\u003ee)),e$,e).filter(e=\u003e!(\"via\"===e.layers[0]\u0026\u0026\"via\"===e.layers[1]||((t,e)=\u003e{const n=xY(t),o=xY(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))})(t[e.routeIndexes[0]],t[e.routeIndexes[1]]))).length,SY=t=\u003e{const e=n$;return[...e.slice(t%e.length),...e.slice(0,t%e.length)]},IY=(t,e,n=!1)=\u003e{const o=z$(t?.nodeWithPortPoints),i=o?((t,e)=\u003et.map(t=\u003e{const n=t.route??[];let o=!1;const i=n.map(t=\u003e{let n=t.x,i=t.y;return n\u003ce.minX?n=e.minX:n\u003ee.maxX\u0026\u0026(n=e.maxX),i\u003ce.minY?i=e.minY:i\u003ee.maxY\u0026\u0026(i=e.maxY),n===t.x\u0026\u0026i===t.y?t:(o=!0,{...t,x:n,y:i})});return o?{...t,route:i}:t}))(H$(Jj(t?.nodeHdRoutes??[]),o),o):Jj(t?.nodeHdRoutes??[]),r=Math.max(e??.4,.05),s=Jj(i);if(!o)return{boundary:null,baseRoutes:i,repairedRoutes:s,margin:r,frames:[{title:\"HighDensityRepair02 Missing Boundary\",routes:s}]};const a=n?[j$(Jj(s),r)]:[],c=new WeakMap;let l=bY(s,o,r);for(let e=0;e\u003c1;e+=1){const i=new Set;let d=0;for(const l of SY(e)){const{movesAccepted:h}=hY({side:l,sample:t,boundary:o,frames:a,margin:r,repairedRoutes:s,captureProgressFrames:n,lockedTwoPointRoutes:i,geometryCache:c,allowTwoPointWithoutObstacle:e\u003e=1});d+=h}const h=bY(s,o,r);if(0===d)break;if(0===h)break;if(h\u003e=l)break;l=h}const d=Jj(s),h=vY(s,c);(({routes:t,boundary:e,margin:n,geometryCache:o})=\u003e{const i=D$(t,e,n);if(0===i.length)return{movesAccepted:0};const r=new Map;for(const t of i){const e=r.get(t.routeIndex)??new Set;for(const n of t.touchedSides)e.add(n);r.set(t.routeIndex,e)}const s=[8e-6,.01,n/4,n/2,n+8e-6];let a=0;const c=(i,r,s)=\u003e{const a=r.route??[];if(a.length\u003c2)return!1;const c={...r,route:$(a)};if((c.route?.length??0)\u003c2)return!1;const l=t.slice();if(l[i]=c,yY(l[i],e,n)\u003e=s)return!1;const d=e=\u003efY(t[e.routeIndexes[0]],t[e.routeIndexes[1]]),h=new Set(T$(t,new Set([i]),0,o).filter(t=\u003e!d(t)).map(mY));return!T$(l,new Set([i]),0,o).filter(t=\u003e!d(t)).some(t=\u003e!h.has(mY(t)))\u0026\u0026!(V$({currentRoutes:t,candidateRoutes:l,candidateRouteIndexes:new Set([i]),maximumAllowedClearance:Math.min(n/2,e$)}).filter(e=\u003e!fY(t[e.routeIndexes[0]],t[e.routeIndexes[1]])).length\u003e0||(t[i]=c,0))},l=(n,o,i,r)=\u003e{if(0===o.length)return!1;for(const a of s){const s=t[n],l=qj(s),d=l.route??[];let h=!1;for(const t of o){const n=d[t];n\u0026\u0026(d[t]=pY(n,e,i,a),h=!0)}if(!h)return!1;if(c(n,l,r))return!0}return!1},d=(t,n)=\u003e{const o=[];return\"top\"===n||\"bottom\"===n?(Math.abs(t.x-e.minX)\u003c=t$\u0026\u0026o.push(\"left\"),Math.abs(t.x-e.maxX)\u003c=t$\u0026\u0026o.push(\"right\")):(Math.abs(t.y-e.minY)\u003c=t$\u0026\u0026o.push(\"bottom\"),Math.abs(t.y-e.maxY)\u003c=t$\u0026\u0026o.push(\"top\")),o},h=(o,i,r)=\u003e{const a=t[o],l=a.route??[];if(2!==l.length)return!1;const[h,u]=l;if(!uY(h,e,i,n))return!1;if(!uY(u,e,i,n))return!1;const p=d(h,i),m=d(u,i);for(const t of s){let n=pY(h,e,i,t),s=pY(u,e,i,t);for(const o of p)n=pY(n,e,o,t);for(const n of m)s=pY(s,e,n,t);const l={...a,route:[h,n,s,u]};if(c(o,l,r))return!0}return!1};for(const[o,i]of r)if(t[o])for(const r of i){let i=!0;for(;i;){i=!1;const s=t[o].route??[];if(2===s.length){const i=yY(t[o],e,n);i\u003e0\u0026\u0026h(o,r,i)\u0026\u0026(a+=1);break}if(s.length\u003c3)break;const c=yY(t[o],e,n);if(0===c)break;const d=[];for(let t=1;t\u003cs.length-1;t+=1){const o=s[t];o\u0026\u0026uY(o,e,r,n)\u0026\u0026d.push(t)}if(0===d.length)break;if(l(o,d,r,c)){a+=1,i=!0;continue}let u=!1,p=c,m=0;for(;m\u003cd.length;){let i=m;for(;i+1\u003cd.length\u0026\u0026d[i+1]===d[i]+1;)i+=1;l(o,d.slice(m,i+1),r,p)\u0026\u0026(a+=1,u=!0,p=yY(t[o],e,n)),m=i+1}if(!u){const i=t[o].route??[];let s=c;for(let c=1;c\u003ci.length-1;c+=1){const d=i[c];d\u0026\u0026uY(d,e,r,n)\u0026\u0026l(o,[c],r,s)\u0026\u0026(a+=1,u=!0,s=yY(t[o],e,n))}}u\u0026\u0026(i=!0)}}for(const[o,i]of r){const r=t[o];if(!r)continue;const s=r.route??[];if(s.length\u003c=2)continue;const c=yY(t[o],e,n);if(0!==c)for(const l of i){if(!s.every(t=\u003euY(t,e,l,n)))continue;const i=s[0]?.z;if(!s.every(t=\u003et.z===i))continue;const d={...r,route:[s[0],s[s.length-1]]},u=t[o];t[o]=d,h(o,l,c)?a+=1:t[o]=u;break}}})({routes:d,boundary:o,margin:r,geometryCache:c});return vY(d,c)\u003c=h\u0026\u0026s.splice(0,s.length,...d),(({routes:t,boundary:e,clearanceMargin:n})=\u003e{for(let o=0;o\u003ct.length;o+=1){const i=t[o];if((i.route??[]).length\u003c=2)continue;const r=n,s=Math.max(e.width/2-t$,0),a=Math.max(e.height/2-t$,0),c=Math.min(r,s),l=Math.min(r,a),d=i.connectedPadSides??[],h=e.minX+(d.includes(\"left\")?0:c),u=e.maxX-(d.includes(\"right\")?0:c),p=e.minY+(d.includes(\"bottom\")?0:l),m=e.maxY-(d.includes(\"top\")?0:l),g=qj(i),f=g.route??[];let y=!1;for(let t=1;t\u003cf.length-1;t+=1){const e=f[t];if(!e)continue;const n=Math.min(Math.max(e.x,h),u),o=Math.min(Math.max(e.y,p),m);(Math.abs(n-e.x)\u003et$||Math.abs(o-e.y)\u003et$)\u0026\u0026(e.x=n,e.y=o,y=!0)}if(!y)continue;if(g.route=$(f),(g.route?.length??0)\u003c2)continue;const _=Jj(t);_[o]=g;const b=_Y(t,_,o,0),x=_Y(t,_,o,n),v=V$({currentRoutes:t,candidateRoutes:_,candidateRouteIndexes:new Set([o]),maximumAllowedClearance:n}).length\u003e0;b||x||v||(t[o]=g)}})({routes:s,boundary:o,clearanceMargin:r}),a.push(((t,e,n)=\u003e({title:`HighDensityRepair02 Final State (margin=${n})`,routes:t,originalRoutes:e}))(Jj(s),Jj(i),r)),{boundary:o,baseRoutes:i,repairedRoutes:s,frames:a,margin:r}},CY=class extends kt{constructor(t={}){super(),this.params=t,this.showBoundryViolationMarkers=t.showBoundryViolationMarkers??!1}params;frames=[];currentFrameIndex=0;showBoundryViolationMarkers;repairedRoutes=[];_setup(){this.buildFrames();const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();this.stats={boundryViolationCount:t,traceViolationCount:e,margin:this.params.margin??.4,frames:this.frames.length,currentFrame:this.currentFrameIndex}}_step(){if(this.frames.length\u003c=1){const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();return this.showBoundryViolationMarkers=!0,this.stats={...this.stats,boundryViolationCount:t,traceViolationCount:e},void(this.solved=!0)}this.currentFrameIndex\u003cthis.frames.length-1\u0026\u0026(this.currentFrameIndex+=1);const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();this.stats={boundryViolationCount:t,traceViolationCount:e,margin:this.params.margin??.4,frames:this.frames.length,currentFrame:this.currentFrameIndex,title:this.frames[this.currentFrameIndex]?.title},this.currentFrameIndex\u003e=this.frames.length-1\u0026\u0026(this.showBoundryViolationMarkers=!0,this.solved=!0)}getConstructorParams(){return[this.params]}getOutput(){const t=this.getCurrentTraceViolationCount();return{margin:this.params.margin??.4,repairedRoutes:this.repairedRoutes,frameCount:this.frames.length,traceViolationCount:t}}setShowBoundryViolationMarkers(t){this.showBoundryViolationMarkers=t}buildFrames(){const t=IY(this.params.sample,this.params.margin,this.params.captureProgressFrames??!1);this.frames=t.frames,this.repairedRoutes=t.repairedRoutes}getCurrentFrame(){const t=this.params.sample;return this.frames[this.currentFrameIndex]??{title:\"HighDensityRepair02\",routes:Jj(t?.nodeHdRoutes??[])}}getBoundryViolationsForFrame(t){const e=z$(this.params.sample?.nodeWithPortPoints);return e?D$(t.routes,e,this.params.margin??.4):[]}getCurrentBoundryViolationCount(){return this.getBoundryViolationsForFrame(this.getCurrentFrame()).length}getRouteNetNames(t){if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))}areRoutesSameNet(t,e){const n=this.getRouteNetNames(t),o=this.getRouteNetNames(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))}getCurrentTraceViolationCount(){const t=this.getCurrentFrame().routes,e=new Set(t.map((t,e)=\u003ee));return T$(t,e,e$).filter(e=\u003e!(\"via\"===e.layers[0]\u0026\u0026\"via\"===e.layers[1]||this.areRoutesSameNet(t[e.routeIndexes[0]],t[e.routeIndexes[1]]))).length}visualize(){const t=this.params.sample,e=t?.nodeWithPortPoints,n=t?.adjacentObstacles??[],o=this.getCurrentFrame(),i=z$(e),r=i\u0026\u0026e?.capacityMeshNodeId?[{center:i.center,width:i.width,height:i.height,stroke:\"#1d4ed8\",fill:\"rgba(29, 78, 216, 0.08)\",label:e.capacityMeshNodeId}]:i?[{center:i.center,width:i.width,height:i.height,stroke:\"#1d4ed8\",fill:\"rgba(29, 78, 216, 0.08)\",label:\"capacity-node\"}]:[],s=n.filter(t=\u003et.center\u0026\u0026t.width\u0026\u0026t.height).map((t,e)=\u003e({center:t.center,width:t.width,height:t.height,stroke:\"oval\"===t.type?\"#a855f7\":\"#dc2626\",fill:\"oval\"===t.type?\"rgba(168, 85, 247, 0.12)\":\"rgba(220, 38, 38, 0.08)\",label:t.type?`obstacle:${t.type}:${e}`:`obstacle:${e}`})),a=this.showBoundryViolationMarkers\u0026\u0026i?this.getBoundryViolationsForFrame(o).map(t=\u003e{const e=t.end.x-t.start.x,n=t.end.y-t.start.y,o=Math.max(Math.hypot(e,n),.2),i=Math.abs(e)\u003e=Math.abs(n);return{center:{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2},width:i?o:.18,height:i?.18:o,stroke:\"#b45309\",fill:\"rgba(250, 204, 21, 0.45)\",label:`boundry-violation:${t.routeIndex}:${t.segmentIndex}`}}):[];const c=this.showBoundryViolationMarkers?b$(o.routes,e$):[],l=[...(e?.portPoints??[]).map(t=\u003e({x:t.x,y:t.y,color:\"#0f766e\",label:t.connectionName??t.portPointId??\"port-point\"})),...o.routes.flatMap(t=\u003et.route??[]).map(t=\u003e({x:t.x,y:t.y,color:\"bottom\"===s$(t)?Kj:\"#0ea5e9\",label:\"\"})),...o.overlayPoints??[]],d=[...(o.originalRoutes??[]).flatMap(t=\u003eB$(t).map(t=\u003e({...t,strokeColor:\"#111111\",strokeWidth:Math.max(.6*t.strokeWidth,.05),label:`original:${t.label}`}))),...o.routes.filter(t=\u003e(t.route?.length??0)\u003e=2).flatMap(t=\u003eB$(t)),...o.overlayLines??[]],h=o.routes.flatMap(t=\u003e(t.vias??[]).map(e=\u003e({center:{x:e.x,y:e.y},radius:(e.diameter??t.viaDiameter??.3)/2,stroke:\"#7c3aed\",fill:\"rgba(124, 58, 237, 0.2)\",label:t.connectionName?`via:${t.connectionName}`:\"via\"})));return h.push(...c),{coordinateSystem:\"cartesian\",title:o.title,rects:[...r,...s,...o.overlayRects??[],...a],points:l,lines:d,circles:h,arrows:o.overlayArrows}}},PY=(t,e,n,o)=\u003e{const i=.001,r=new Set;for(const s of[e.route[0],e.route.at(-1)]){if(!s)continue;n.some(t=\u003et.__zLayers.includes(s.z)\u0026\u0026fo(t,e,o)\u0026\u0026Math.abs(s.x-t.center.x)\u003c=t.width/2+i\u0026\u0026Math.abs(s.y-t.center.y)\u003c=t.height/2+i)\u0026\u0026(Math.abs(s.x-(t.center.x-t.width/2))\u003c=i\u0026\u0026r.add(\"left\"),Math.abs(s.x-(t.center.x+t.width/2))\u003c=i\u0026\u0026r.add(\"right\"),Math.abs(s.y-(t.center.y-t.height/2))\u003c=i\u0026\u0026r.add(\"bottom\"),Math.abs(s.y-(t.center.y+t.height/2))\u003c=i\u0026\u0026r.add(\"top\"))}return[...r]},MY=(t,e=0)=\u003e({minX:t.center.x-t.width/2-e,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2-e,maxY:t.center.y+t.height/2+e}),NY=(t,e,n=0)=\u003e{const o=MY(e,n);return t.x\u003e=o.minX\u0026\u0026t.x\u003c=o.maxX\u0026\u0026t.y\u003e=o.minY\u0026\u0026t.y\u003c=o.maxY},wY=(t,e,n)=\u003et.route.length\u003e0\u0026\u0026e.some(e=\u003e(t=\u003e(t.__zLayers?.length??t.layers?.length??0)\u003e1)(e)\u0026\u0026fo(e,t,n)\u0026\u0026t.route.every(t=\u003e((t,e)=\u003e{const n=e.width/2,o=e.height/2;return Math.abs(t.x-e.center.x)\u003c=n\u0026\u0026Math.abs(t.y-e.center.y)\u003c=o})(t,e))),TY=(t,e,n)=\u003e{if(t.regionId){const n=e.findIndex(e=\u003ee.capacityMeshNodeId===t.regionId);if(-1!==n)return n}const o=[...t.route.map(({x:t,y:e})=\u003e({x:t,y:e})),...t.vias.map(({x:t,y:e})=\u003e({x:t,y:e}))];for(let t=0;t\u003ce.length;t++){const i=e[t];if(o.every(t=\u003eNY(t,i,n)))return t}return-1},RY=(t,e)=\u003e({connectionName:t.connectionName??e.connectionName,rootConnectionName:t.rootConnectionName??e.rootConnectionName,...e.startPcbPortId?{startPcbPortId:e.startPcbPortId}:{},...e.endPcbPortId?{endPcbPortId:e.endPcbPortId}:{},regionId:t.capacityMeshNodeId??e.regionId,traceThickness:t.traceThickness??e.traceThickness,viaDiameter:t.viaDiameter??e.viaDiameter,route:t.route?.map(t=\u003e({x:t.x,y:t.y,z:t.z??0}))??e.route,vias:t.vias?.map(t=\u003e({x:t.x,y:t.y}))??e.vias,jumpers:e.jumpers}),EY=(t,e,n,o,i)=\u003e{const r=MY(t,n);return e.search(r).filter(t=\u003e{return e=r,n=(t=\u003e({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}))(t),e.minX\u003c=n.maxX\u0026\u0026e.maxX\u003e=n.minX\u0026\u0026e.minY\u003c=n.maxY\u0026\u0026e.maxY\u003e=n.minY;var e,n}).filter(t=\u003e!i||!o.some(e=\u003efo(t,e,i))).map(t=\u003e({type:t.type,center:t.center,width:t.width,height:t.height}))},AY=class extends si{repairMargin;sampleEntries;originalHdRoutes;originalNodeWithPortPoints;originalObstacles;obstacleSHI;colorMap;connMap;repairedRoutesByIndex=new Map;activeSampleIndex=0;activeSubSolver=null;latestVisualization={};constructor(t){super(),this.repairMargin=t.repairMargin??.2,this.originalHdRoutes=t.hdRoutes,this.originalNodeWithPortPoints=t.nodeWithPortPoints,this.originalObstacles=t.obstacles,this.obstacleSHI=new Na(\"flatbush\",this.originalObstacles),this.colorMap=t.colorMap??{},this.connMap=t.connMap;const e=new Map;for(let n=0;n\u003ct.hdRoutes.length;n++){if(wY(t.hdRoutes[n],t.obstacles,t.connMap))continue;const o=TY(t.hdRoutes[n],t.nodeWithPortPoints,this.repairMargin);if(-1===o)continue;const i=e.get(o)??[];i.push(n),e.set(o,i)}const n=Kr(t.obstacles,Math.max(2,...t.nodeWithPortPoints.flatMap(t=\u003et.availableZ?.map(t=\u003et+1)??[]))),o=Array.from(e.entries()).map(([e,o])=\u003e{const i=t.nodeWithPortPoints[e];return{node:i,routeIndexes:o,sample:{nodeWithPortPoints:{capacityMeshNodeId:i.capacityMeshNodeId,center:i.center,width:i.width,height:i.height,portPoints:i.portPoints.map(t=\u003e({x:t.x,y:t.y,z:t.z,connectionName:t.connectionName,portPointId:t.portPointId,prevPortPointId:t.prevPortPointId,nextPortPointId:t.nextPortPointId}))},nodeHdRoutes:o.map(e=\u003e{return{...(o=t.hdRoutes[e],{capacityMeshNodeId:o.regionId,connectionName:o.connectionName,rootConnectionName:o.rootConnectionName,route:o.route.map(t=\u003e({x:t.x,y:t.y,z:t.z})),traceThickness:o.traceThickness,vias:o.vias.map(t=\u003e({x:t.x,y:t.y,diameter:o.viaDiameter})),viaDiameter:o.viaDiameter}),...t.connMap?{connectedPadSides:PY(i,t.hdRoutes[e],n,t.connMap)}:{}};var o}),adjacentObstacles:EY(i,this.obstacleSHI,this.repairMargin,o.map(e=\u003et.hdRoutes[e]),t.connMap)}}});this.sampleEntries=void 0!==t.maxSampleEntries\u0026\u0026o.length\u003et.maxSampleEntries?[]:o,this.MAX_ITERATIONS=Math.max(1e3*this.sampleEntries.length,1e5),this.stats={sampleCount:this.sampleEntries.length,skippedSampleCount:o.length\u003ethis.sampleEntries.length?o.length:0,repairedNodeCount:0,repairedRouteCount:0}}getSolverName(){return\"Pipeline4HighDensityRepairSolver\"}getConstructorParams(){return[{nodeWithPortPoints:this.sampleEntries.map(t=\u003et.node),hdRoutes:this.originalHdRoutes,obstacles:this.originalObstacles,repairMargin:this.repairMargin,colorMap:this.colorMap,connMap:this.connMap}]}_step(){const t=this.sampleEntries[this.activeSampleIndex];if(t){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.latestVisualization=this.activeSubSolver.visualize(),this.activeSubSolver.failed)return this.failed=!0,this.error=this.activeSubSolver.error??`High density repair failed for node ${t.node.capacityMeshNodeId}`,void(this.activeSubSolver=null);if(!this.activeSubSolver.solved)return;const e=this.activeSubSolver.getOutput().repairedRoutes;for(let n=0;n\u003ct.routeIndexes.length;n++){const o=t.routeIndexes[n],i=this.originalHdRoutes[o],r=e[n];this.repairedRoutesByIndex.set(o,r?RY(r,i):i)}return this.activeSubSolver=null,this.activeSampleIndex+=1,this.stats={sampleCount:this.sampleEntries.length,repairedNodeCount:this.activeSampleIndex,repairedRouteCount:this.repairedRoutesByIndex.size},void(this.activeSampleIndex\u003e=this.sampleEntries.length\u0026\u0026(this.solved=!0))}this.activeSubSolver=new CY({sample:t.sample,margin:this.repairMargin}),this.latestVisualization=this.activeSubSolver.visualize()}else this.solved=!0}getOutput(){return this.originalHdRoutes.map((t,e)=\u003ethis.repairedRoutesByIndex.get(e)??t)}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();if(!this.solved)return this.latestVisualization;const t=[],e=[];for(const n of this.getOutput()){const o=this.colorMap[n.connectionName]??\"#0ea5e9\";for(let e=0;e\u003cn.route.length-1;e++){const i=n.route[e],r=n.route[e+1];i.z===r.z\u0026\u0026t.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:0===i.z?o:To(o,.5),strokeWidth:n.traceThickness,layer:`z${i.z}`,strokeDash:0!==i.z?[.1,.3]:void 0})}for(const t of n.vias)e.push({center:{x:t.x,y:t.y},radius:n.viaDiameter/2,stroke:o,fill:\"rgba(14,165,233,0.12)\"})}return{title:\"Pipeline4 High Density Repair\",lines:t,circles:e}}},OY=1e-6,kY=({startGap:t,endGap:e,segmentGap:n,requiredGap:o})=\u003e{const i=t\u003co\u0026\u0026e\u003e=o-OY\u0026\u0026n\u003e=t-OY,r=e\u003co\u0026\u0026t\u003e=o-OY\u0026\u0026n\u003e=e-OY,s=t\u003co\u0026\u0026e\u003co\u0026\u0026n\u003e=Math.min(t,e)-OY;return i||r||s},LY=class{minClearance;rootsByConnection=new Map;sameNetCache=new Map;segments=[];vias=[];segmentIndexesByLayer;viaIndex;constructor({hdRoutes:t,minClearance:e=.1}){this.minClearance=e;for(const e of t)this.addRoute(e);this.buildSpatialIndexes()}addRoute(t){const e=this.rootsByConnection.get(t.connectionName)??new Set;e.add(t.rootConnectionName??t.connectionName),this.rootsByConnection.set(t.connectionName,e),this.sameNetCache.clear();for(let e=0;e\u003ct.route.length-1;e+=1){const n=t.route[e],o=t.route[e+1];if(n.z!==o.z)continue;if(n.insideJumperPad\u0026\u0026o.insideJumperPad)continue;const i={connectionName:t.connectionName,start:n,end:o,traceThickness:t.traceThickness};this.segments.push(i),this.insertSegmentIntoSpatialIndex(i)}for(const e of t.vias){const n={connectionName:t.connectionName,x:e.x,y:e.y,diameter:t.viaDiameter};this.vias.push(n),this.insertViaIntoSpatialIndex(n)}}insertSegmentIntoSpatialIndex(t){if(!this.segmentIndexesByLayer)return;let e=this.segmentIndexesByLayer.get(t.start.z);e||(e=new Pa,this.segmentIndexesByLayer.set(t.start.z,e));const n=t.traceThickness/2;e.insert(t,Math.min(t.start.x,t.end.x)-n,Math.min(t.start.y,t.end.y)-n,Math.max(t.start.x,t.end.x)+n,Math.max(t.start.y,t.end.y)+n)}insertViaIntoSpatialIndex(t){if(!this.viaIndex)return;const e=t.diameter/2;this.viaIndex.insert(t,t.x-e,t.y-e,t.x+e,t.y+e)}buildSpatialIndexes(){this.segmentIndexesByLayer=new Map;const t=new Map;for(const e of this.segments){const n=t.get(e.start.z);n?n.push(e):t.set(e.start.z,[e])}for(const[e,n]of t){const t=new Pa;t.bulkLoad(n.map(t=\u003e{const e=t.traceThickness/2;return{item:t,minX:Math.min(t.start.x,t.end.x)-e,minY:Math.min(t.start.y,t.end.y)-e,maxX:Math.max(t.start.x,t.end.x)+e,maxY:Math.max(t.start.y,t.end.y)+e}})),this.segmentIndexesByLayer.set(e,t)}this.viaIndex=new Pa,this.viaIndex.bulkLoad(this.vias.map(t=\u003e{const e=t.diameter/2;return{item:t,minX:t.x-e,minY:t.y-e,maxX:t.x+e,maxY:t.y+e}}))}areSameNet(t,e){if(t===e)return!0;const n=this.sameNetCache.get(t)?.get(e);if(void 0!==n)return n;const o=this.rootsByConnection.get(t),i=this.rootsByConnection.get(e);let r=!1;if(o\u0026\u0026i)for(const t of o)if(i.has(t)){r=!0;break}let s=this.sameNetCache.get(t);return s||(s=new Map,this.sameNetCache.set(t,s)),s.set(e,r),r}isSegmentClear({connectionName:t,start:e,end:n,traceThickness:o}){const i=o/2,r=this.minClearance+i,s=Math.min(e.x,n.x)-r,a=Math.min(e.y,n.y)-r,c=Math.max(e.x,n.x)+r,l=Math.max(e.y,n.y)+r,d=this.segmentIndexesByLayer?.get(e.z)?.search(s,a,c,l)??[];for(const o of d){if(this.areSameNet(t,o.connectionName))continue;const r=this.minClearance+i+o.traceThickness/2,s=Ra(e,n,o.start,o.end);if(s\u003cr\u0026\u0026!kY({startGap:be(e,o.start,o.end),endGap:be(n,o.start,o.end),segmentGap:s,requiredGap:r}))return!1}const h=this.viaIndex?.search(s,a,c,l)??[];for(const o of h){if(this.areSameNet(t,o.connectionName))continue;const r=this.minClearance+i+o.diameter/2,s=be(o,e,n);if(s\u003cr\u0026\u0026!kY({startGap:Math.hypot(e.x-o.x,e.y-o.y),endGap:Math.hypot(n.x-o.x,n.y-o.y),segmentGap:s,requiredGap:r}))return!1}return!0}},DY=1e-9,zY=1.25,FY=(t,e)=\u003et\u003ce?-1:t\u003ee?1:0,BY=(t,e)=\u003eFY(t.z,e.z)||FY(t.x,e.x)||FY(t.y,e.y),jY=t=\u003e`${t.z.toFixed(6)}:${t.x.toFixed(6)}:${t.y.toFixed(6)}`,$Y=t=\u003e{const e=t.route.map(jY).join(\"|\"),n=[...t.route].reverse().map(jY).join(\"|\");return e\u003c=n?e:n},YY=(t,e)=\u003e{const n=t.connectionName.localeCompare(e.connectionName);if(0!==n)return n;const o=(t.rootConnectionName??\"\").localeCompare(e.rootConnectionName??\"\");if(0!==o)return o;const i=$Y(t).localeCompare($Y(e));return 0!==i?i:FY(t.traceThickness,e.traceThickness)||FY(t.viaDiameter,e.viaDiameter)||FY(t.route.length,e.route.length)||FY(t.vias.length,e.vias.length)||FY(t.jumpers?.length??0,e.jumpers?.length??0)},XY=1e5,VY=.001,WY=1.000000001,HY=class extends si{getSolverName(){return\"SingleHighDensityRouteStitchSolver3\"}mergedHdRoute;remainingHdRoutes;start;end;colorMap;allowedLayerTransitionPointKeys;isStitchSegmentClear;stitchClearanceMode;isPlanarStitchClear(t,e){return this.isStitchSegmentClear({connectionName:this.mergedHdRoute.connectionName,start:t,end:e,traceThickness:this.mergedHdRoute.traceThickness})}constructor(t){super();const e=[...t.hdRoutes].sort(YY);if(this.remainingHdRoutes=e,this.colorMap=t.colorMap??{},this.allowedLayerTransitionPointKeys=t.allowedLayerTransitionPointKeys,this.isStitchSegmentClear=t.isStitchSegmentClear,this.stitchClearanceMode=t.stitchClearanceMode,0===e.length){this.start=t.start,this.end=t.end;const n=t.defaultTraceThickness??.15,o=[{x:t.start.x,y:t.start.y,z:t.start.z}],i=[];if(t.start.z!==t.end.z){if(t.allowedLayerTransitionPointKeys\u0026\u0026!t.allowedLayerTransitionPointKeys.has(af(t.start)))return this.failed=!0,void(this.error=`Layer transition at ${af(t.start)} is not allowed`);o.push({x:t.start.x,y:t.start.y,z:t.end.z}),i.push({x:t.start.x,y:t.start.y})}const r=o[o.length-1],s={x:t.end.x,y:t.end.y,z:t.end.z},a={connectionName:t.connectionName,start:r,end:s,traceThickness:n};return xe(r,s)\u003eVY\u0026\u0026!this.isStitchSegmentClear(a)\u0026\u0026\"require_clear\"===this.stitchClearanceMode?(this.failed=!0,void(this.error=`Terminal stitch for \"${t.connectionName}\" violates copper clearance`)):(o.push(s),this.mergedHdRoute={connectionName:t.connectionName,...t.preserveTerminalPcbPortIds\u0026\u0026t.start.pcb_port_id?{startPcbPortId:t.start.pcb_port_id}:{},...t.preserveTerminalPcbPortIds\u0026\u0026t.end.pcb_port_id?{endPcbPortId:t.end.pcb_port_id}:{},rootConnectionName:e[0]?.rootConnectionName,route:o,vias:i,jumpers:[],viaDiameter:t.defaultViaDiameter??.3,traceThickness:n},void(this.solved=!0))}const n=new Set((t.preserveTerminalPcbPortIds?[t.start.pcb_port_id,t.end.pcb_port_id]:[]).filter(t=\u003evoid 0!==t));if(t.preserveTerminalPcbPortIds\u0026\u0026t.start.pcb_port_id\u0026\u0026t.start.pcb_port_id===t.end.pcb_port_id)throw new Error(`SingleHighDensityRouteStitchSolver3 received duplicate PCB terminal \"${t.start.pcb_port_id}\" for \"${t.connectionName}\"`);const o=e.flatMap(t=\u003e[t.startPcbPortId,t.endPcbPortId]).filter(t=\u003evoid 0!==t);if(n.size\u003e0)for(const e of o)if(!n.has(e))throw new Error(`SingleHighDensityRouteStitchSolver3 found unknown PCB terminal \"${e}\" on \"${t.connectionName}\"`);let i=1/0,r=e[0],s=\"start-to-end\";for(const n of e){const e=n.route[0],o=n.route[n.route.length-1],a=xe(t.start,e),c=xe(t.start,o),l=xe(t.end,e),d=xe(t.end,o),h=Math.min(a,c,l,d);(h\u003ci-DY||Math.abs(h-i)\u003c=DY\u0026\u0026YY(n,r)\u003c0)\u0026\u0026(i=h,r=n,s=Math.min(l,d)\u003cMath.min(a,c)-DY||Math.abs(Math.min(l,d)-Math.min(a,c))\u003c=DY\u0026\u0026BY(t.end,t.start)\u003c0?\"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 a=r.route[0],c=r.route[r.route.length-1],l=xe(this.start,a),d=xe(this.start,c),h=l\u003cd-DY||Math.abs(l-d)\u003c=DY\u0026\u0026BY(a,c)\u003c=0?a:c,u=h===a?r.startPcbPortId:r.endPcbPortId;if(u\u0026\u0026this.start.pcb_port_id\u0026\u0026u!==this.start.pcb_port_id)throw new Error(`SingleHighDensityRouteStitchSolver3 terminal identity disagrees with route orientation for \"${t.connectionName}\"`);this.mergedHdRoute={connectionName:t.connectionName,...t.preserveTerminalPcbPortIds\u0026\u0026this.start.pcb_port_id?{startPcbPortId:this.start.pcb_port_id}:{},...t.preserveTerminalPcbPortIds\u0026\u0026this.end.pcb_port_id?{endPcbPortId:this.end.pcb_port_id}:{},rootConnectionName:r.rootConnectionName,route:[{x:this.start.x,y:this.start.y,z:h.z}],vias:[],jumpers:[],viaDiameter:r.viaDiameter,traceThickness:r.traceThickness}}getDisjointedRoute(){for(const t of this.remainingHdRoutes){if([t.route[0],t.route[t.route.length-1]].some(e=\u003e!this.remainingHdRoutes.some(n=\u003e{if(n===t)return!1;return[n.route[0],n.route[n.route.length-1]].some(t=\u003et.z===e.z\u0026\u0026xe(e,t)\u003c.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],e={...this.end,z:t.z},n=xe(t,e);if(n\u003eVY\u0026\u0026n\u003c=zY){if(!this.isPlanarStitchClear(t,e)\u0026\u0026\"require_clear\"===this.stitchClearanceMode)return this.failed=!0,void(this.error=`Terminal stitch for \"${this.mergedHdRoute.connectionName}\" violates copper clearance`);this.mergedHdRoute.route.push({x:this.end.x,y:this.end.y,z:t.z})}return void(this.solved=!0)}const t=this.mergedHdRoute.route[this.mergedHdRoute.route.length-1];let e=-1,n=\"first\",o=1/0,i=!1;for(let r=0;r\u003cthis.remainingHdRoutes.length;r++){const s=this.remainingHdRoutes[r],a=s.route[0],c=s.route[s.route.length-1],l=xe(t,a),d=xe(t,c);let h=1/0;if(t.z===a.z){if(l\u003cVY)h=l;else if(l\u003c=1){const e=this.isPlanarStitchClear(t,a);if(e||\"prefer_clear\"===this.stitchClearanceMode){h=XY+(e?0:WY)+l}else i=!0}}else l\u003cVY\u0026\u0026(!this.allowedLayerTransitionPointKeys||this.allowedLayerTransitionPointKeys.has(af(a)))\u0026\u0026(h=1e3+l);h\u003co\u0026\u0026(o=h,e=r,n=\"first\");let u=1/0;if(t.z===c.z){if(d\u003cVY)u=d;else if(d\u003c=1){const e=this.isPlanarStitchClear(t,c);if(e||\"prefer_clear\"===this.stitchClearanceMode){u=XY+(e?0:WY)+d}else i=!0}}else d\u003cVY\u0026\u0026(!this.allowedLayerTransitionPointKeys||this.allowedLayerTransitionPointKeys.has(af(c)))\u0026\u0026(u=1e3+d);u\u003co\u0026\u0026(o=u,e=r,n=\"last\")}if(-1===e)return i?(this.failed=!0,void(this.error=`Route stitch for \"${this.mergedHdRoute.connectionName}\" violates copper clearance`)):void(this.remainingHdRoutes=[]);const r=this.remainingHdRoutes[e];let s;this.remainingHdRoutes.splice(e,1),s=\"first\"===n?r.route:(t=\u003e{const e=[...t].reverse().map(t=\u003e{const{toNextSegmentType:e,...n}=t;return n});for(let n=0;n\u003ct.length-1;n++){const o=t[n]?.toNextSegmentType;if(!o)continue;const i=t.length-n-2;e[i]={...e[i],toNextSegmentType:o}}return e})(r.route),s.length\u003e0\u0026\u0026xe(t,s[0])\u003cVY\u0026\u0026t.z===s[0].z?(s[0].toNextSegmentType\u0026\u0026(t.toNextSegmentType=s[0].toNextSegmentType),this.mergedHdRoute.route.push(...s.slice(1))):this.mergedHdRoute.route.push(...s),this.mergedHdRoute.vias.push(...r.vias),r.jumpers\u0026\u0026this.mergedHdRoute.jumpers.push(...r.jumpers)}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:\"Single High Density Route Stitch Solver 3\"};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\u0026\u0026this.mergedHdRoute.route.length\u003e1){t.lines?.push({points:this.mergedHdRoute.route.map(t=\u003e({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\u0026\u0026this.mergedHdRoute.jumpers.length\u003e0){const e=_a(this.mergedHdRoute.jumpers,{color:\"green\",label:this.mergedHdRoute.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const e of this.remainingHdRoutes){t.lines?.push({points:e.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:\"orange\"});for(const n of e.route)t.points?.push({x:n.x,y:n.y,color:\"orange\"});for(const n of e.vias)t.circles?.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:\"orange\"});if(e.jumpers\u0026\u0026e.jumpers.length\u003e0){const n=_a(e.jumpers,{color:\"orange\",label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}return t}},GY=class{constructor(t=!1){this.preferSameLayerTerminalEndpoints=t}preferSameLayerTerminalEndpoints;endpointClusters=new Map;getEndpointKey(t,e){const n=this.endpointClusters.get(t)??[];let o,i=1/0;for(const t of n){if(t.point.z!==e.z)continue;const n=xe(t.point,e);n\u003c=.1\u0026\u0026(n\u003ci-DY||Math.abs(n-i)\u003c=DY\u0026\u0026(!o||BY(t.point,o.point)\u003c0))\u0026\u0026(o=t,i=n)}if(o)return o.key;const r=`${t}:endpoint_${n.length}`;return n.push({key:r,point:{x:e.x,y:e.y,z:e.z}}),this.endpointClusters.set(t,n),r}getClusters(t){return this.endpointClusters.get(t)??[]}getClosestEndpointKey(t,e,n){const o=e.flatMap(t=\u003e[t.route[0],t.route[t.route.length-1]]),i=o.filter(t=\u003et.z===n.z),r=this.preferSameLayerTerminalEndpoints\u0026\u0026i.length\u003e0?i:o;let s=null,a=null,c=1/0;for(const e of r){const o=xe(n,e),i=this.getEndpointKey(t,e);(o\u003cc-DY||Math.abs(o-c)\u003c=DY\u0026\u0026(null===s||i.localeCompare(s)\u003c0||i===s\u0026\u0026null!==a\u0026\u0026BY(e,a)\u003c0))\u0026\u0026(c=o,s=i,a=e)}return s}},UY=(t,e,n)=\u003e{const o=t.get(e)??[];o.some(t=\u003et.nextHash===n.nextHash\u0026\u0026t.routeIndex===n.routeIndex)||(o.push(n),t.set(e,o))},ZY=t=\u003e{const e=[...t.possibleEndpoints].sort(BY),n=e.reduce((e,n)=\u003e{const o=xe(n,t.globalStart),i=xe(e,t.globalStart);return o\u003ci-DY||Math.abs(o-i)\u003c=DY\u0026\u0026BY(n,e)\u003c0?n:e}),o=e.filter(t=\u003et!==n),i=(o.length\u003e0?o:t.possibleEndpoints).reduce((e,n)=\u003e{const o=xe(n,t.globalEnd),i=xe(e,t.globalEnd);return o\u003ci-DY||Math.abs(o-i)\u003c=DY\u0026\u0026BY(n,e)\u003c0?n:e});return{start:n,end:i}},qY=t=\u003e{const e=[...t.terminals].sort(BY);let n=e[0],o=xe(t.islandEndpoint,n);for(const i of e.slice(1)){const e=xe(t.islandEndpoint,i);(e\u003co-DY||Math.abs(e-o)\u003c=DY\u0026\u0026BY(i,n)\u003c0)\u0026\u0026(n=i,o=e)}return o\u003c=zY?n:t.islandEndpoint},JY=t=\u003e{if(t.hdRoutes.length\u003c=2)return t.hdRoutes;const e=[...t.hdRoutes].sort(YY),n=t.endpointIndex.getClosestEndpointKey(t.connectionName,e,t.start),o=t.endpointIndex.getClosestEndpointKey(t.connectionName,e,t.end);if(!n||!o||n===o)return e;const i=new Map;for(let n=0;n\u003ce.length;n++){const o=e[n],r=t.endpointIndex.getEndpointKey(t.connectionName,o.route[0]),s=t.endpointIndex.getEndpointKey(t.connectionName,o.route[o.route.length-1]);UY(i,r,{nextHash:s,routeIndex:n}),UY(i,s,{nextHash:r,routeIndex:n})}const r=[...t.endpointIndex.getClusters(t.connectionName)].sort((t,e)=\u003eBY(t.point,e.point));for(let t=0;t\u003cr.length;t++){const e=r[t];for(let n=t+1;n\u003cr.length;n++){const t=r[n];e.point.z===t.point.z\u0026\u0026(xe(e.point,t.point)\u003e1||(UY(i,e.key,{nextHash:t.key,routeIndex:null}),UY(i,t.key,{nextHash:e.key,routeIndex:null})))}}for(const[t,n]of i.entries())i.set(t,[...n].sort((t,n)=\u003e{if(null===t.routeIndex\u0026\u0026null!==n.routeIndex)return 1;if(null!==t.routeIndex\u0026\u0026null===n.routeIndex)return-1;if(null!==t.routeIndex\u0026\u0026null!==n.routeIndex){const o=YY(e[t.routeIndex],e[n.routeIndex]);if(0!==o)return o}return t.nextHash.localeCompare(n.nextHash)}));const s=[n],a=new Set([n]),c=new Map;for(;s.length\u003e0;){const t=s.shift();if(t===o)break;for(const e of i.get(t)??[])a.has(e.nextHash)||(a.add(e.nextHash),c.set(e.nextHash,{prevHash:t,routeIndex:e.routeIndex}),s.push(e.nextHash))}if(!a.has(o))return e;const l=[];let d=o;for(;d!==n;){const t=c.get(d);if(!t)return e;null!==t.routeIndex\u0026\u0026l.push(t.routeIndex),d=t.prevHash}if(0===l.length)return t.hdRoutes;const h=l.reverse().map(t=\u003ee[t]);return h.length\u003e0\u0026\u0026!t.canStitchBetweenTerminals({connectionName:t.connectionName,hdRoutes:h,start:t.start,end:t.end})?e:h},KY=class extends si{getSolverName(){return\"MultipleHighDensityRouteStitchSolver3\"}unsolvedRoutes;activeSolver=null;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;allowedLayerTransitionPointKeys;preserveTerminalPcbPortIds;endpointIndex;clearanceValidator;canStitchBetweenTerminals(t){const e=new HY({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter,allowedLayerTransitionPointKeys:this.allowedLayerTransitionPointKeys,preserveTerminalPcbPortIds:this.preserveTerminalPcbPortIds,isStitchSegmentClear:t=\u003ethis.clearanceValidator.isSegmentClear(t),stitchClearanceMode:\"require_clear\"});for(;!e.solved\u0026\u0026!e.failed\u0026\u0026e.iterations\u003ce.MAX_ITERATIONS;)e.step();if(e.failed)return!1;const n=e.mergedHdRoute.route[0],o=e.mergedHdRoute.route[e.mergedHdRoute.route.length-1],i=xe(n,t.start)+xe(o,t.end),r=xe(n,t.end)+xe(o,t.start);return Math.min(i,r)\u003c=zY}getSharedRootPathRoutes(t){const e=t.rootConnectionName;if(!e)return null;const n=new Set(t.hdRoutes),o=t.allHdRoutes.filter(t=\u003e(t.rootConnectionName??t.connectionName)===e);if(o.every(t=\u003en.has(t)))return null;const i=JY({connectionName:t.connectionName,hdRoutes:o,start:t.start,end:t.end,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=\u003ethis.canStitchBetweenTerminals(t)});return!i.some(t=\u003e!n.has(t))||i.length\u003e=o.length?null:i}constructor(t){super(),this.endpointIndex=new GY(t.preferSameLayerTerminalEndpoints),this.colorMap=t.colorMap??{},this.allowedLayerTransitionPointKeys=t.allowedLayerTransitionPointKeys,this.preserveTerminalPcbPortIds=t.preserveTerminalPcbPortIds??!1;const e=[...t.hdRoutes].sort(YY);this.clearanceValidator=new LY({hdRoutes:e});const n=e[0];this.defaultTraceThickness=n?.traceThickness??.15,this.defaultViaDiameter=n?.viaDiameter??t.defaultViaDiameter??.3;const o=new fa({}),i=[],r=new Map;for(let t=0;t\u003ce.length;t++){const n=e[t],o=n.route[0],r=n.route[n.route.length-1];i.push([`route_island_${t}`,this.endpointIndex.getEndpointKey(n.connectionName,o),this.endpointIndex.getEndpointKey(n.connectionName,r)])}o.addConnections(i);for(const t of i)for(const e of t.slice(1))r.set(e,(r.get(e)??0)+1);this.unsolvedRoutes=[];const s=Array.from(new Set(Object.values(o.idToNetMap)));for(const n of s){const i=o.getIdsConnectedToNet(n),s=e.filter((t,e)=\u003ei.includes(`route_island_${e}`));if(0===s.length)continue;const a=t.connections.find(t=\u003et.name===s[0].connectionName),c=s.flatMap(t=\u003e[t.route[0],t.route[t.route.length-1]]),l=new Map,d=[];for(const t of c){const e=this.endpointIndex.getEndpointKey(s[0].connectionName,t);l.has(e)||l.set(e,t),1===r.get(e)\u0026\u0026d.push(t)}const h=d.length\u003e0?d:[...l.values()];if(0===h.length)continue;let u,p;if(h.length\u003e=2){const e={...a.pointsToConnect[0],z:ko(bo(a.pointsToConnect[0]),t.layerCount)},n={...a.pointsToConnect[1],z:ko(bo(a.pointsToConnect[1]),t.layerCount)};({start:u,end:p}=ZY({possibleEndpoints:h,globalStart:e,globalEnd:n})),xe(u,a.pointsToConnect[1])\u003cxe(p,a.pointsToConnect[0])\u0026\u0026([u,p]=[p,u]),u=qY({islandEndpoint:u,terminals:[e,n]}),p=qY({islandEndpoint:p,terminals:[e,n]})}else u={...a.pointsToConnect[0],z:ko(bo(a.pointsToConnect[0]),t.layerCount)},p={...a.pointsToConnect[1],z:ko(bo(a.pointsToConnect[1]),t.layerCount)};const m=JY({connectionName:s[0].connectionName,hdRoutes:s,start:u,end:p,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=\u003ethis.canStitchBetweenTerminals(t)});this.unsolvedRoutes.push({connectionName:s[0].connectionName,hdRoutes:m,start:u,end:p})}const a=new Map;for(const t of this.unsolvedRoutes){const e=a.get(t.connectionName);e?e.push(t):a.set(t.connectionName,[t])}this.unsolvedRoutes=Array.from(a.entries()).flatMap(([n,o])=\u003e{const i=t.connections.find(t=\u003et.name===n),r=o.some(t=\u003et.hdRoutes.some(t=\u003et.route.length\u003c2)),s=o.length\u003e1\u0026\u0026(t=\u003e{for(let e=0;e\u003ct.length;e++)for(let n=e+1;n\u003ct.length;n++){const o=[t[e].start,t[e].end],i=[t[n].start,t[n].end];for(const t of o)for(const e of i)if(t.z===e.z\u0026\u0026xe(t,e)\u003c=1)return!0}return!1})(o);if(!i)return o;const a={...i.pointsToConnect[0],z:ko(bo(i.pointsToConnect[0]),t.layerCount)},c={...i.pointsToConnect[1],z:ko(bo(i.pointsToConnect[1]),t.layerCount)},l=o.flatMap(t=\u003et.hdRoutes),d=o.length\u003e1?this.getSharedRootPathRoutes({connectionName:n,rootConnectionName:i.__rootConnectionNames?.[0]??l[0]?.rootConnectionName,hdRoutes:l,allHdRoutes:e,start:a,end:c}):null;return r||s||d?[{connectionName:n,hdRoutes:d??JY({connectionName:n,hdRoutes:l,start:a,end:c,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=\u003ethis.canStitchBetweenTerminals(t)}),start:a,end:c}]:o}),this.MAX_ITERATIONS=1e5}_step(){if(this.activeSolver)return this.activeSolver.step(),void(this.activeSolver.solved?(this.activeSolver instanceof HY\u0026\u0026(this.clearanceValidator.addRoute(this.activeSolver.mergedHdRoute),this.mergedHdRoutes.push(this.activeSolver.mergedHdRoute)),this.activeSolver=null):this.activeSolver.failed\u0026\u0026(this.failed=!0,this.error=this.activeSolver.error));const t=this.unsolvedRoutes.pop();t?this.activeSolver=new HY({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter,allowedLayerTransitionPointKeys:this.allowedLayerTransitionPointKeys,preserveTerminalPcbPortIds:this.preserveTerminalPcbPortIds,isStitchSegmentClear:t=\u003ethis.clearanceValidator.isSegmentClear(t),stitchClearanceMode:\"prefer_clear\"}):this.solved=!0}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:\"Multiple High Density Route Stitch Solver 3\"};if(this.activeSolver){const e=this.activeSolver.visualize();e.points?.length\u0026\u0026t.points?.push(...e.points),e.lines?.length\u0026\u0026t.lines?.push(...e.lines),e.circles?.length\u0026\u0026t.circles?.push(...e.circles),e.rects?.length\u0026\u0026(t.rects||(t.rects=[]),t.rects.push(...e.rects))}for(const[e,n]of this.mergedHdRoutes.entries()){const o=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e\u003cn.route.length-1;e++){const i=n.route[e],r=n.route[e+1],s=0!==i.z?To(o,.5):o;t.lines?.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:s,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?To(o,.5):o;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:o});if(n.jumpers\u0026\u0026n.jumpers.length\u003e0){const e=_a(n.jumpers,{color:o,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}return t}},QY=t=\u003e(t%360+360)%360,tX=(t,e)=\u003e{const{ccwRotationDegrees:n,...o}=t,i=(t=\u003e{const e=QY(t),n=[0,90,180,270];for(const t of n)if(Math.min(Math.abs(e-t),360-Math.abs(e-t))\u003c=.01)return t;return null})(e);return 90===i||270===i?{...o,width:t.height,height:t.width}:o},eX=t=\u003e\"layers\"in t?t.layers:[t.layer],nX=(t,e)=\u003e!(eX(t).length\u003e0\u0026\u0026!eX(t).some(t=\u003ee.layers.includes(t)))\u0026\u0026Me(t,Ve(e)),oX=(t,e)=\u003e{const{minX:n,maxX:o,minY:i,maxY:r}=Ve(e);return{x:Math.max(n,Math.min(o,t.x)),y:Math.max(i,Math.min(r,t.y))}},iX=(t,e)=\u003et.obstacleId??`${t.componentId??\"obstacle\"}_${e}`;function rX(t,e=2){const{center:n,width:o,height:i,rotation:r}=t,s=[],a=Math.max(1,Math.ceil(e)),c=r*Math.PI/180,l=Math.cos(c),d=Math.sin(c);if(o\u003e=i){const t=o/a;for(let e=0;e\u003ca;e++){const o=(e-a/2+.5)*t,r=o*l,c=o*d,h=Math.abs(t*l)+Math.abs(i*d),u=Math.abs(t*d)+Math.abs(i*l);s.push({center:{x:n.x+r,y:n.y+c},width:h,height:u})}}else{const t=i/a;for(let e=0;e\u003ca;e++){const i=(e-a/2+.5)*t,r=-i*d,c=i*l,h=Math.abs(o*l)+Math.abs(t*d),u=Math.abs(o*d)+Math.abs(t*l);s.push({center:{x:n.x+r,y:n.y+c},width:h,height:u})}}return s}var sX=t=\u003e{if(\"oval\"===t.type)return sX({...t,type:\"rect\"});const e=t.ccwRotationDegrees;if(\"number\"!=typeof e||!Number.isFinite(e))return[t];if((t=\u003e{const e=QY(t);return[0,90,180,270].some(t=\u003eMath.min(Math.abs(e-t),360-Math.abs(e-t))\u003c=.01)})(e))return[tX(t,e)];const{ccwRotationDegrees:n,...o}=t,i={center:t.center,width:t.width,height:t.height,rotation:e},r=(t=\u003e{const e=Math.max(t.width,t.height),n=Math.min(t.width,t.height);return t.obstacleId?.startsWith(\"trace_obstacle_\")?Math.max(2,Math.ceil(e/.75)):n\u003c=0?2:e/n\u003c2||n\u003e=.9?null:Math.max(2,Math.ceil(e/.75))})(t),s=t.connectedTo.length\u003e0\u0026\u0026!t.obstacleId?.startsWith(\"trace_obstacle_\")?(t=\u003e{const e=t.rotation*Math.PI/180,n=Math.cos(e),o=Math.sin(e),i=[-1,1].flatMap(e=\u003e[-1,1].map(i=\u003e{const r=e*(t.width/2),s=i*(t.height/2);return{x:t.center.x+r*n-s*o,y:t.center.y+r*o+s*n}})),r=[i[0],i[2],i[3],i[1]],s=Math.min(...r.map(t=\u003et.x)),a=Math.max(...r.map(t=\u003et.x)),c=Math.min(...r.map(t=\u003et.y)),l=Math.max(...r.map(t=\u003et.y)),d=a-s\u003c=l-c?\"x\":\"y\",h=\"x\"===d?s:c,u=\"x\"===d?a:l,p=Math.max(1,Math.ceil((u-h)/.4)),m=(u-h)/p,g=(t,e,n)=\u003e{const o=[],i=t=\u003et[d];for(let r=0;r\u003ct.length;r++){const s=t[r],a=t[(r+1)%t.length],c=i(s),l=i(a),d=n?c\u003e=e:c\u003c=e,h=n?l\u003e=e:l\u003c=e;if(d\u0026\u0026o.push(s),d===h)continue;const u=(e-c)/(l-c);o.push({x:s.x+(a.x-s.x)*u,y:s.y+(a.y-s.y)*u})}return o},f=[];for(let t=0;t\u003cp;t++){const e=h+t*m,n=t===p-1?u:e+m,o=g(g(r,e,!0),n,!1);if(0===o.length)continue;const i=Math.min(...o.map(t=\u003et.x)),s=Math.max(...o.map(t=\u003et.x)),a=Math.min(...o.map(t=\u003et.y)),c=Math.max(...o.map(t=\u003et.y));f.push({center:{x:(i+s)/2,y:(a+c)/2},width:s-i,height:c-a})}return f})(i):null===r?((t,e)=\u003e{const{center:n,width:o,height:i,rotation:r}=t,s=Math.max(1,Math.ceil(o/e)),a=Math.max(1,Math.ceil(i/e)),c=o/s,l=i/a,d=r*Math.PI/180,h=Math.cos(d),u=Math.sin(d),p=[];for(let t=0;t\u003cs;t++){const e=(t-s/2+.5)*c;for(let t=0;t\u003ca;t++){const o=(t-a/2+.5)*l;p.push({center:{x:n.x+e*h-o*u,y:n.y+e*u+o*h},width:Math.abs(c*h)+Math.abs(l*u),height:Math.abs(c*u)+Math.abs(l*h)})}}return p})(i,(t=\u003et.obstacleId?.startsWith(\"trace_obstacle_\")?.75:.4)(t)):t.obstacleId?.startsWith(\"trace_obstacle_\")?rX(i,r):((t,e)=\u003e{const{center:n,width:o,height:i,rotation:r}=t,s=Math.max(o,i),a=Math.min(o,i),c=Math.max(1,Math.ceil(e)),l=s/c,d=r*Math.PI/180,h=Math.cos(d),u=Math.sin(d),p=Math.max(l,.75*a),m=[];for(let t=0;t\u003cc;t++){const e=(t-c/2+.5)*l,r=o\u003e=i?e*h:-e*u,s=o\u003e=i?e*u:e*h;m.push({center:{x:n.x+r,y:n.y+s},width:p,height:p})}return m})(i,r),a=t.connectedTo.length\u003e0?s.reduce((e,n,o)=\u003e{const i=s[e],r=(i.center.x-t.center.x)**2+(i.center.y-t.center.y)**2;return(n.center.x-t.center.x)**2+(n.center.y-t.center.y)**2\u003cr?o:e},0):-1;return s.map((t,e)=\u003e({...o,obstacleId:e===a?o.obstacleId:o.obstacleId?`${o.obstacleId}_approx_${e}`:void 0,connectedTo:o.connectedTo,center:t.center,width:t.width,height:t.height}))},aX=t=\u003e{const e=new Map,n=new Map,o=new Map;for(const[i,r]of t.obstacles.entries()){const t=sX(r),s=iX(r,i);n.set(s,t),o.set(s,r);for(const n of t){const t=[n.center.x.toFixed(6),n.center.y.toFixed(6),n.width.toFixed(6),n.height.toFixed(6),n.layers.join(\",\")].join(\":\"),o=e.get(t);o?o.connectedTo=[...new Set([...o.connectedTo,...n.connectedTo])]:e.set(t,n)}}const i=t.connections.map(t=\u003e({...t,pointsToConnect:t.pointsToConnect.map(t=\u003e{const e=(t=\u003e[t.pointId,t.pcb_port_id].filter(t=\u003eBoolean(t)))(t);if(0===e.length)return t;for(const[i,r]of o){if(!e.some(t=\u003er.connectedTo.includes(t)))continue;if(!nX(t,r))continue;const o=n.get(i)??[];if(0===o.length)continue;if(o.some(e=\u003enX(t,e)))return t;let s=o[0],a=Number.POSITIVE_INFINITY;for(const e of o){const n=xe(oX(t,e),t);n\u003ca\u0026\u0026(a=n,s=e)}return{...t,...oX(t,s)}}return t})}));return{...t,connections:i,obstacles:[...e.values()]}},cX=.001,lX=t=\u003e\"wire\"===t.route_type,dX=t=\u003e\"via\"===t.route_type,hX=t=\u003e\"through_obstacle\"===t.route_type,uX=(t,e,n)=\u003e{const o=ko(t,n),i=ko(e,n),r=Math.min(o,i),s=Math.max(o,i);return Array.from({length:s-r+1},(t,e)=\u003evo(r+e,n))},pX=({obstacleId:t,start:e,end:n,width:o,layer:i,connectedTo:r})=\u003e{const s=n.x-e.x,a=n.y-e.y,c=Math.hypot(s,a);return c\u003c=cX?null:{obstacleId:t,type:\"rect\",layers:[i],center:{x:(e.x+n.x)/2,y:(e.y+n.y)/2},width:c,height:Math.max(o,cX),ccwRotationDegrees:180*Math.atan2(a,s)/Math.PI,connectedTo:r}};function mX(t){if(!t)return t;const e=(t=\u003e{if(!t)return[];const e=[],n=Yo(t);for(const[o,i]of(t.traces??[]).entries()){const r=i.connectsTo??[];for(let s=0;s\u003ci.route.length;s++){const a=i.route[s];if(dX(a)){const c=a.via_diameter??n.padDiameter;e.push({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${s}_via`,type:\"rect\",layers:uX(a.from_layer,a.to_layer,t.layerCount),center:{x:a.x,y:a.y},width:Math.max(c,cX),height:Math.max(c,cX),connectedTo:r});continue}if(hX(a)){const n=pX({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${s}_through`,start:a.start,end:a.end,width:a.width,layer:a.from_layer,connectedTo:r});n\u0026\u0026(n.layers=uX(a.from_layer,a.to_layer,t.layerCount),e.push(n))}}for(let t=0;t\u003ci.route.length-1;t++){const n=i.route[t],s=i.route[t+1];if(!lX(n)||!lX(s)||n.layer!==s.layer)continue;const a=pX({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${t}_wire`,start:n,end:s,width:n.width,layer:n.layer,connectedTo:r});a\u0026\u0026e.push(a)}}return e})(t);return 0===e.length?t:{...t,obstacles:[...t.obstacles??[],...e]}}function gX(t,e){const n=function(t,e){const n=Lo(t.__zLayers??t.zLayers??[],e);if(n.length\u003e0)return n;const o=Do(t.layers,e);if(o.length\u003e0)return o;throw new Error(`Obstacle \"${t.obstacleId??\"unknown\"}\" has no layers on this ${e}-layer board`)}(t,e);return{...t,layers:n.map(t=\u003evo(t,e)),zLayers:n,__zLayers:n}}function fX(t){return{...t,obstacles:t.obstacles.map(e=\u003egX(e,t.layerCount)),jumpers:t.jumpers?.map(e=\u003e({...e,pads:e.pads.map(e=\u003egX(e,t.layerCount))}))}}var yX=t=\u003e{const e=t.obstacles.filter(e=\u003e!((t,e)=\u003e!(t=\u003e(t.connectedTo?.length??0)\u003e0||(t.offBoardConnectsTo?.length??0)\u003e0||!0===t.netIsAssignable)(t)\u0026\u0026(e.outline\u0026\u0026e.outline.length\u003e=3?!Te(t,e.outline):!Xe({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.bounds)))(e,t)),n=e.length!==t.obstacles.length,o=n\u0026\u0026t.outline\u0026\u0026t.outline.length\u003e=3?(t=\u003e{if(t.width\u0026\u0026t.height\u0026\u0026t.center){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,width:t.width,height:t.height,center:{x:t.center.x,y:t.center.y}}}if(!t.outline||0===t.outline.length)throw new Error(\"Unable to compute board bounds. pcb_board must include width/height/center or a non-empty outline.\");let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t.outline)e=Math.min(e,r.x),n=Math.min(n,r.y),o=Math.max(o,r.x),i=Math.max(i,r.y);const r=o-e,s=i-n;return{minX:e,minY:n,maxX:o,maxY:i,width:r,height:s,center:{x:e+r/2,y:n+s/2}}})({type:\"pcb_board\",pcb_board_id:\"__autorouting_board_outline__\",center:{x:0,y:0},thickness:1,num_layers:t.layerCount,material:\"fr4\",outline:t.outline}):t.bounds;return n?{...t,obstacles:e,bounds:o}:t},_X=class extends si{constructor(t,e={}){super(),this.inputSrj=t,this.visualizationOptions=e,this.MAX_ITERATIONS=1}inputSrj;visualizationOptions;outputSrj;_step(){const t=fX(this.inputSrj),e=mX(t)??t,n=aX(yX(e));this.outputSrj=fX(n),this.solved=!0}getOutputSimpleRouteJson(){if(!this.outputSrj)throw new Error(\"PreprocessSimpleRouteJsonSolver has not solved yet\");return this.outputSrj}getConstructorParams(){return[this.inputSrj,this.visualizationOptions]}visualize(){return this.outputSrj?pi(Ho({...this.outputSrj,traces:[]},this.visualizationOptions),Yj({srj:this.outputSrj,visualizationOptions:this.visualizationOptions})):{lines:[],points:[],rects:[],circles:[]}}};function bX(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var xX=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;nodeSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[bX(\"preprocessSimpleRouteJsonSolver\",_X,t=\u003e[t.originalSrj],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),bX(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),bX(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),bX(\"nodeSolver\",Kn,t=\u003e[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=\u003e{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),bX(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver?.outputNodes??[]}}),bX(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),bX(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),bX(\"necessaryCrampedPortPointSolver\",sf,t=\u003e[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),bX(\"portPointPathingSolver\",jj,t=\u003e{const e=t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),bX(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),bX(\"highDensityRouteSolver\",zs,t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=(e.length\u003e0?e:n).map(e=\u003ews(e)?{...e,availableZ:Array.from({length:t.srj.layerCount},(t,e)=\u003ee)}:e);return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0}]}),bX(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,totalStepsPerNode:Math.max(20,Math.round(60*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),bX(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2}]),bX(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),bX(\"traceSimplificationSolver\",vc,t=\u003e[{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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,iterations:2}]),bX(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),bX(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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\u0026\u0026(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\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.nodeSolver?.visualize(),o=this.nodeDimensionSubdivisionSolver?.visualize(),i=this.nodeTargetMerger?.visualize(),r=this.singleLayerNodeMerger?.visualize(),s=this.strawSolver?.visualize(),a=this.edgeSolver?.visualize(),c=this.deadEndSolver?.visualize(),l=this.availableSegmentPointSolver?.visualize(),d=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),u=this.uniformPortDistributionSolver?.visualize(),p=this.highDensityRouteSolver?.visualize(),m=this.highDensityForceImproveSolver?.visualize(),g=this.highDensityRepairSolver?.visualize(),f=this.highDensityStitchSolver?.visualize(),y=this.traceSimplificationSolver?.visualize(),_=this.necessaryCrampedPortPointSolver?.visualize(),b=(this.highDensityRouteSolver?.visualize(),this.originalSrj),x=b.outline,v=[];if(v.push({points:[{x:b.bounds?.minX??-50,y:b.bounds?.minY??-50},{x:b.bounds?.maxX??50,y:b.bounds?.minY??-50},{x:b.bounds?.maxX??50,y:b.bounds?.maxY??50},{x:b.bounds?.minX??-50,y:b.bounds?.maxY??50},{x:b.bounds?.minX??-50,y:b.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),x\u0026\u0026x.length\u003e=2){const t=x.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const S=Oo(b),I={points:[...b.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,b.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(b.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,b.layerCount),label:S(t)}))],lines:v},C=Yj({srj:b}),P=[pi(I,C),t,e,n,o,i,r,s,a,c,l,_,d,h,u,p?pi(I,p):null,m,g,f,y,this.solved?pi({lines:v},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...P)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){return this.globalDrcForceImproveSolver?.getOutput()??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 o=n.__netConnectionName??this.originalSrj.connections.find(t=\u003et.name===n.name)?.__netConnectionName,i=e.filter(t=\u003et.connectionName===n.name);for(let e=0;e\u003ci.length;e++){const r=i[e],s={type:\"pcb_trace\",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.srj.obstacles,connMap:this.connMap})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},vX=t=\u003e{const e=[];let n=t;for(;n;)e.push(n),n=n.activeSubSolver;for(let t=e.length-1;t\u003e=0;t--){const n=e[t]?.pendingEffects?.filter(Boolean)??[];if(n.length\u003e0)return n}return[]},SX=t=\u003e/\\/solve\\/?$/.test(t)?t.replace(/\\/+$/,\"\"):`${t.replace(/\\/+$/,\"\")}/solve`,IX=(t,e,n)=\u003e{const o=(t=\u003e{const e=new Map;for(const n of t.portPoints)n.rootConnectionName\u0026\u0026!e.has(n.connectionName)\u0026\u0026e.set(n.connectionName,n.rootConnectionName);return e})(t);return e.map(t=\u003e({connectionName:t.connectionName,rootConnectionName:t.rootConnectionName??o.get(t.connectionName)??void 0,traceThickness:t.traceThickness??n.traceWidth,viaDiameter:t.viaDiameter??n.viaDiameter,route:(t.route??[]).map(t=\u003e({x:t.x,y:t.y,z:t.z,...t.insideJumperPad?{insideJumperPad:!0}:{}})),vias:(t.vias??[]).map(t=\u003e({x:t.x,y:t.y})),...t.jumpers?{jumpers:t.jumpers}:{}}))},CX=(t,e)=\u003e{if(0===t.length)return null;const n=Math.min(Math.max(e,0),1),o=(t.length-1)*n,i=Math.floor(o),r=Math.ceil(o),s=t[i],a=t[r];return i===r?s:s+(a-s)*(o-i)},PX=t=\u003enew Set(t.portPoints.map(t=\u003et.connectionName)).size,MX=t=\u003e!(PX(t)\u003c3)\u0026\u00261!==(t.availableZ?.length??0),NX=t=\u003et?.MULTI_HEAD_POLYLINE_SOLVER?\"MultiHeadPolyLineIntraNodeSolver3\":t?.CLOSED_FORM_SINGLE_TRANSITION?\"SingleTransitionIntraNodeSolver\":t?.CLOSED_FORM_TWO_TRACE_SAME_LAYER?\"TwoCrossingRoutesHighDensitySolver\":t?.CLOSED_FORM_TWO_TRACE_TRANSITION_CROSSING?\"SingleTransitionCrossingRouteSolver\":t?.HIGH_DENSITY_A01?\"HighDensitySolverA01\":t?.HIGH_DENSITY_A03?\"HighDensitySolverA03\":\"SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost\",wX=t=\u003e{if(t instanceof rr){const e=NX(t.hyperParameters);return t.cacheHit?`${e} [cached]`:e}if(t instanceof er)return NX(t.hyperParameters);if(t\u0026\u0026\"object\"==typeof t\u0026\u0026\"getSolverName\"in t\u0026\u0026\"function\"==typeof t.getSolverName)return t.getSolverName();const e=t?.constructor;return\"string\"==typeof e?.name?e.name:\"unknown\"},TX=t=\u003et.winningSolver?wX(t.winningSolver):wX(t),RX=class extends si{getSolverName(){return\"Pipeline5HdCacheHighDensitySolver\"}unsolvedNodePortPoints;colorMap;connMap;viaDiameter;traceWidth;obstacleMargin;obstacles;layerCount;hdCacheBaseUrl;fetchImpl;nodePfById;routes=[];nodeSolveMetadataById=new Map;launchedRemoteSolves=!1;solvedRoutesByNodeIndex=new Map;failedNodeResults=[];remoteResponseMeasurements=[];constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,obstacles:s,layerCount:a,nodePfById:c,hdCacheBaseUrl:l,fetchImpl:d}){super(),this.unsolvedNodePortPoints=t,this.colorMap=e??{},this.connMap=n,this.viaDiameter=o??.3,this.traceWidth=i??.15,this.obstacleMargin=r??.15,this.obstacles=s??[],this.layerCount=a??2,this.hdCacheBaseUrl=l??\"https://hd-cache.tscircuit.com\",this.fetchImpl=(d??globalThis.fetch).bind(globalThis),this.nodePfById=c instanceof Map?new Map(c):new Map(Object.entries(c??{})),this.pendingEffects=[],this.stats={localDirectNodeCount:0,localSolvedNodeCount:0,localFallbackNodeCount:0,remoteFallbackNodeCount:0,remoteRequestsStarted:0,remoteRequestsCompleted:0,remoteResponseSampleCount:0,remoteKOrderSampleCount:0,slowestRemoteResponseMs:null,slowestRemoteResponseNodeId:null,p50RemoteResponseMs:null,p50RemoteKOrder:null,p95RemoteKOrder:null,remoteSources:{}}}computeProgress(){return 0===this.unsolvedNodePortPoints.length?1:this.nodeSolveMetadataById.size/this.unsolvedNodePortPoints.length}solveNodeLocally(t,e,n={}){const o=new Ss({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,obstacles:this.obstacles,layerCount:this.layerCount});if(o.solve(),o.failed){const e=o.error??`Local intra-node solver failed for ${t.capacityMeshNodeId}`,i=PX(t);return this.failedNodeResults.push({node:t,error:n.remoteFailure\u0026\u0026\"local-fallback\"===n.resolution?`Remote solve failed (${n.remoteFailure}); local fallback failed (${e})`:e}),void this.recordNodeSolveMetadata(t,{status:\"failed\",resolution:\"failed\",solverType:TX(o),supervisorType:o.getSolverName(),iterations:o.iterations,pairCount:i,routeCount:0,remoteAttempt:\"local-fallback\"===n.resolution?{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:\"error\",durationMs:n.remoteDurationMs,error:n.remoteFailure??e}:{attempted:!1},error:e})}this.solvedRoutesByNodeIndex.set(e,o.solvedRoutes);const i=PX(t);this.recordNodeSolveMetadata(t,{status:\"solved\",resolution:n.resolution??\"local\",solverType:TX(o),supervisorType:o.getSolverName(),iterations:o.iterations,pairCount:i,routeCount:o.solvedRoutes.length,remoteAttempt:\"local-fallback\"===n.resolution?{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:\"error\",durationMs:n.remoteDurationMs,error:n.remoteFailure}:{attempted:!1}}),\"local-fallback\"===n.resolution?(this.stats.localFallbackNodeCount+=1,this.stats.remoteFallbackNodeCount+=1):this.stats.localDirectNodeCount+=1,this.stats.localSolvedNodeCount+=1}async solveNodeViaHdCache(t,e){const n=SX(this.hdCacheBaseUrl),o={\"content-type\":\"application/json\"},i={nodeWithPortPoints:t},r=JSON.stringify(i),s=Date.now();let a,c,l,d=null,h=null;try{const i=await this.fetchImpl(n,{method:\"POST\",headers:o,body:r});if(a=i.status,c=i.ok,l=await i.text(),d=Date.now()-s,h=l?JSON.parse(l):null,!i.ok)throw new Error(h?.message??l??`hd-cache request failed with status ${i.status}`);if(!h?.ok||null===h.routes)throw new Error(h?.message??`hd-cache returned no routes for ${t.capacityMeshNodeId}`);const u=IX(t,h.routes,{traceWidth:this.traceWidth,viaDiameter:this.viaDiameter});this.solvedRoutesByNodeIndex.set(e,u),this.recordNodeSolveMetadata(t,{status:\"solved\",resolution:\"remote\",solverType:`hd-cache.tscircuit.com [${h.source}]`,iterations:null,pairCount:PX(t),routeCount:u.length,remoteAttempt:{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:h.source,durationMs:d}}),this.recordRemoteSource(h.source)}catch(u){d??=Date.now()-s;const p=(t=\u003et instanceof Error?t.message:String(t))(u);this.recordFailedHdCacheRequest({nodeId:t.capacityMeshNodeId,pairCount:PX(t),failedAt:(new Date).toISOString(),durationMs:d,error:p,url:n,request:{method:\"POST\",headers:o,body:r,bodyJson:i},response:void 0!==a||void 0!==c||void 0!==l||null!==h?{status:a,ok:c,text:l,body:h}:void 0}),this.recordRemoteSource(\"error\"),this.solveNodeLocally(t,e,{resolution:\"local-fallback\",remoteFailure:p,remoteDurationMs:d})}finally{this.recordRemoteResponseMetrics(t.capacityMeshNodeId,d??Date.now()-s,(u=h?.kOrder,\"number\"==typeof u\u0026\u0026Number.isFinite(u)?h.kOrder:null)),this.stats.remoteRequestsCompleted+=1}var u}launchRemoteSolves(){const t=[];this.unsolvedNodePortPoints.forEach((e,n)=\u003e{if(!MX(e))return void this.solveNodeLocally(e,n);const o={name:`hd-cache:${e.capacityMeshNodeId}`,promise:Promise.resolve()};o.promise=this.solveNodeViaHdCache(e,n).finally(()=\u003e{this.pendingEffects=this.pendingEffects?.filter(t=\u003et!==o)}),t.push(o)}),this.pendingEffects=t,this.stats.remoteRequestsStarted=t.length}recordRemoteSource(t){this.stats.remoteSources[t]=(this.stats.remoteSources[t]??0)+1}recordRemoteResponseMetrics(t,e,n){this.remoteResponseMeasurements.push({nodeId:t,durationMs:e,kOrder:n}),this.stats.remoteResponseSampleCount=this.remoteResponseMeasurements.length,this.stats.remoteKOrderSampleCount=this.remoteResponseMeasurements.filter(t=\u003enull!==t.kOrder).length;let o=null;for(const t of this.remoteResponseMeasurements)(!o||t.durationMs\u003eo.durationMs)\u0026\u0026(o=t);this.stats.slowestRemoteResponseMs=o?.durationMs??null,this.stats.slowestRemoteResponseNodeId=o?.nodeId??null;const i=this.remoteResponseMeasurements.map(t=\u003et.durationMs).sort((t,e)=\u003et-e);this.stats.p50RemoteResponseMs=CX(i,.5);const r=this.remoteResponseMeasurements.map(t=\u003et.kOrder).filter(t=\u003enull!==t).sort((t,e)=\u003et-e);this.stats.p50RemoteKOrder=CX(r,.5),this.stats.p95RemoteKOrder=CX(r,.95)}recordFailedHdCacheRequest(t){const e=(()=\u003e{if(\"undefined\"==typeof window)return null;const t=window;return Array.isArray(t.__FAILED_HD_CACHE_REQUESTS)||(t.__FAILED_HD_CACHE_REQUESTS=[]),t.__FAILED_HD_CACHE_REQUESTS})();e\u0026\u0026e.push(t)}recordNodeSolveMetadata(t,e){this.nodeSolveMetadataById.set(t.capacityMeshNodeId,{...e,node:t,nodePf:this.nodePfById.get(t.capacityMeshNodeId)??null})}ensureFailedNodeMetadata(){for(const t of this.failedNodeResults)this.nodeSolveMetadataById.has(t.node.capacityMeshNodeId)||this.recordNodeSolveMetadata(t.node,{status:\"failed\",resolution:\"failed\",solverType:\"unknown\",iterations:null,pairCount:PX(t.node),routeCount:0,remoteAttempt:{attempted:MX(t.node),source:\"error\",error:t.error},error:t.error})}getVisibleRoutes(){if(this.solved)return this.routes;const t=[];for(let e=0;e\u003cthis.unsolvedNodePortPoints.length;e++)t.push(...this.solvedRoutesByNodeIndex.get(e)??[]);return t}createNodeMarkerLabel(t,e){return[\"hd_node_marker\",`node: ${t}`,`status: ${e.status}`,`resolution: ${e.resolution}`,`solver: ${e.solverType}`,...e.supervisorType?[`supervisor: ${e.supervisorType}`]:[],...null!==e.iterations?[`iterations: ${e.iterations}`]:[],`pairCount: ${e.pairCount}`,`routes: ${e.routeCount}`,`nodePf: ${e.nodePf??\"n/a\"}`,\"remoteAttempted: \"+(e.remoteAttempt.attempted?\"yes\":\"no\"),...e.remoteAttempt.source?[`remoteSource: ${e.remoteAttempt.source}`]:[],...void 0!==e.remoteAttempt.durationMs?[`remoteDurationMs: ${e.remoteAttempt.durationMs}`]:[],...e.remoteAttempt.error?[`remoteError: ${e.remoteAttempt.error}`]:[],`portPoints: ${e.node.portPoints.length}`,...e.error?[`error: ${e.error}`]:[]].join(\"\\n\")}_step(){if(!this.launchedRemoteSolves)return this.launchedRemoteSolves=!0,void this.launchRemoteSolves();if(!((this.pendingEffects?.length??0)\u003e0)){if(this.failedNodeResults.length\u003e0){this.ensureFailedNodeMetadata();const t=this.failedNodeResults[0];return this.failed=!0,void(this.error=`Failed to solve ${this.failedNodeResults.length} nodes via hd-cache. First failure: ${t?.node.capacityMeshNodeId} (${t?.error})`)}this.routes=[];for(let t=0;t\u003cthis.unsolvedNodePortPoints.length;t++)this.routes.push(...this.solvedRoutesByNodeIndex.get(t)??[]);this.solved=!0}}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.getVisibleRoutes()){const n=mi(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const o of n)t.lines.push({points:o.points,label:o.connectionName,strokeColor:0===o.z?o.color:To(o.color,.75),layer:`z${o.z}`,strokeWidth:e.traceThickness,strokeDash:0!==o.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,n]of this.nodeSolveMetadataById){const o=n.node.center.x-n.node.width/2,i=n.node.center.x+n.node.width/2,r=n.node.center.y-n.node.height/2,s=n.node.center.y+n.node.height/2,a=this.createNodeMarkerLabel(e,n),c=\"solved\"===n.status?\"blue\":\"red\",l=\"solved\"===n.status?.03:.08;if(t.lines.push({points:[{x:o,y:r},{x:i,y:r}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a},{points:[{x:i,y:r},{x:i,y:s}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a},{points:[{x:i,y:s},{x:o,y:s}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a},{points:[{x:o,y:s},{x:o,y:r}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a}),\"solved\"===n.status)t.points.push({x:n.node.center.x,y:n.node.center.y,color:c,layer:\"hd_node_markers\",label:a});else{t.lines.push({points:[{x:0,y:0},{x:n.node.center.x,y:n.node.center.y}],layer:\"hd_failed_node_guides\",strokeColor:c,strokeDash:\"8, 6\",strokeWidth:.05,label:a});const e=Math.max(n.node.width,1.2),o=Math.max(n.node.height,1.2),i=e/2,r=o/2;t.rects.push({center:n.node.center,layer:\"hd_node_markers\",width:e,height:o,fill:\"rgba(255, 0, 0, 0.3)\",stroke:c,label:a}),t.circles.push({center:n.node.center,radius:Math.max(.6*Math.max(e,o),1.1),layer:\"hd_node_markers\",fill:\"rgba(255, 0, 0, 0.08)\",stroke:c,label:a}),t.lines.push({points:[{x:n.node.center.x-i,y:n.node.center.y-r},{x:n.node.center.x+i,y:n.node.center.y+r}],layer:\"hd_node_markers\",strokeColor:c,strokeWidth:.16,label:a},{points:[{x:n.node.center.x-i,y:n.node.center.y+r},{x:n.node.center.x+i,y:n.node.center.y-r}],layer:\"hd_node_markers\",strokeColor:c,strokeWidth:.16,label:a})}}return t}},EX=class extends xX{hdCacheBaseUrl;hdCacheFetch;constructor(t,e={}){super(t,{...e,maxNodeDimension:e.maxNodeDimension??7,maxNodeRatio:e.maxNodeRatio??4}),this.hdCacheBaseUrl=e.hdCacheBaseUrl??\"https://hd-cache.tscircuit.com\",this.hdCacheFetch=e.hdCacheFetch,this.replaceHighDensityPipelineStep()}replaceHighDensityPipelineStep(){const t=this.pipelineDef.findIndex(t=\u003e\"highDensityRouteSolver\"===t.solverName);if(-1===t)throw new Error(\"Pipeline4 highDensityRouteSolver step is missing\");this.pipelineDef[t]={...this.pipelineDef[t],solverClass:RX,getConstructorParams:t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length\u003e0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,hdCacheBaseUrl:t.hdCacheBaseUrl,fetchImpl:t.hdCacheFetch}]}}}async stepAsync(){if(this.solved||this.failed)return;this.step();const t=vX(this);0!==t.length\u0026\u0026(await Promise.race(t.map(t=\u003et.promise.then(()=\u003et.name,()=\u003et.name))),this.solved||this.failed||this.step())}async solveAsync(){const t=Date.now();for(;!this.solved\u0026\u0026!this.failed;)await this.stepAsync();this.timeToSolve=Date.now()-t}solve(){throw new Error(\"AutoroutingPipelineSolver5_HdCache requires async execution. Use solveAsync() or stepAsync().\")}},AX=1e-9,OX=Math.PI/2,kX=(t,e)=\u003et.x*e.y-t.y*e.x,LX=(t,e)=\u003et.x*e.x+t.y*e.y,DX=t=\u003e{let e=t%OX;return e\u003c0\u0026\u0026(e+=OX),OX-e\u003c1e-8?0:e},zX=t=\u003e{const e=Math.cos(t),n=Math.sin(t);return{u:{x:e,y:n},v:{x:-n,y:e}}},FX=t=\u003e{let e=0;for(let n=0;n\u003ct.length;n++){const o=t[n],i=t[(n+1)%t.length];e+=o.x*i.y-i.x*o.y}return e/2},BX=t=\u003eMath.abs(FX(t)),jX=t=\u003e{const e=FX(t);if(Math.abs(e)\u003cAX){const e=t.reduce((t,e)=\u003e({x:t.x+e.x,y:t.y+e.y}),{x:0,y:0});return{x:e.x/Math.max(1,t.length),y:e.y/Math.max(1,t.length)}}let n=0,o=0;for(let e=0;e\u003ct.length;e++){const i=t[e],r=t[(e+1)%t.length],s=i.x*r.y-r.x*i.y;n+=(i.x+r.x)*s,o+=(i.y+r.y)*s}const i=1/(6*e);return{x:n*i,y:o*i}},$X=t=\u003eFX(t)\u003e=0?[...t]:[...t].reverse(),YX=(t,e)=\u003e{const n=new Set;n.add(0);for(let t=0;t\u003c90;t++)n.add(t/90*OX);for(let e=0;e\u003ct.length;e++){const o=t[e],i=t[(e+1)%t.length],r=Math.atan2(i.y-o.y,i.x-o.x);n.add(DX(r)),n.add(DX(r+OX))}const o=n=\u003e{const o=((t,e=jX(t),n=0)=\u003e{const o=$X(t),{u:i,v:r}=zX(n),s=o.map((t,n)=\u003e{const s=o[(n+1)%o.length],a=s.x-t.x,c=s.y-t.y,l={x:a,y:c};return{hxCoeff:Math.abs(kX(l,i)),hyCoeff:Math.abs(kX(l,r)),limit:a*(e.y-t.y)-c*(e.x-t.x)}});if(s.some(t=\u003et.limit\u003c-1e-7))throw new Error(\"Projected rect center is outside polygon\");let a=Number.POSITIVE_INFINITY;for(const t of s)t.hxCoeff\u003eAX\u0026\u0026(a=Math.min(a,t.limit/t.hxCoeff));if(!Number.isFinite(a)||a\u003c=AX)return{center:e,width:1e-6,height:1e-6,ccwRotationRadians:n,ccwRotationDegrees:180*n/Math.PI};const c=t=\u003e{let e=Number.POSITIVE_INFINITY;for(const n of s){const o=n.limit-n.hxCoeff*t;if(o\u003c-1e-8)return 0;n.hyCoeff\u003eAX\u0026\u0026(e=Math.min(e,o/n.hyCoeff))}return Number.isFinite(e)?Math.max(0,e):0},l=t=\u003et*c(t);let d=0,h=a;for(let t=0;t\u003c80;t++){const t=d+(h-d)/3,e=h-(h-d)/3;l(t)\u003cl(e)?d=t:h=e}const u=(d+h)/2,p=c(u);return{center:e,width:Math.max(1e-6,2*u),height:Math.max(1e-6,2*p),ccwRotationRadians:n,ccwRotationDegrees:180*n/Math.PI}})(t,e,n);return{rect:o,area:o.width*o.height}};let i=o(0),r=0;for(const t of n){const e=o(t);e.area\u003ei.area+1e-8\u0026\u0026(i=e,r=t)}const s=OX/90;let a=r-s,c=r+s;for(let t=0;t\u003c60;t++){const t=a+(c-a)/3,e=c-(c-a)/3;o(t).area\u003co(e).area?a=t:c=e}const l=o(DX((a+c)/2));return l.area\u003ei.area+1e-8?l.rect:i.rect},XX=(t,e,n,o)=\u003e{const i=o.x-n.x,r=o.y-n.y,s=e.x*r-e.y*i;if(Math.abs(s)\u003cAX)return;const a=n.x-t.x,c=n.y-t.y,l=(a*r-c*i)/s,d=(a*e.y-c*e.x)/s;return l\u003c-1e-8||d\u003c-1e-8||d\u003e1+1e-8?void 0:{x:t.x+e.x*l,y:t.y+e.y*l,rayT:l}},VX=(t,e)=\u003e{const n=[],o=[];for(let i=0;i\u003c4;i++){const{x:r,y:s}=t[i],a=e[i].x,c=e[i].y;n.push([r,s,1,0,0,0,-a*r,-a*s]),o.push(a),n.push([0,0,0,r,s,1,-c*r,-c*s]),o.push(c)}const i=((t,e)=\u003e{const n=e.length,o=t.map((t,n)=\u003e[...t,e[n]]);for(let t=0;t\u003cn;t++){let e=t;for(let i=t+1;i\u003cn;i++)Math.abs(o[i][t])\u003eMath.abs(o[e][t])\u0026\u0026(e=i);if(Math.abs(o[e][t])\u003cAX)throw new Error(\"Could not solve homography\");[o[t],o[e]]=[o[e],o[t]];const i=o[t][t];for(let e=t;e\u003c=n;e++)o[t][e]=o[t][e]/i;for(let e=0;e\u003cn;e++){if(e===t)continue;const i=o[e][t];for(let r=t;r\u003c=n;r++)o[e][r]=o[e][r]-i*o[t][r]}}return o.map(t=\u003et[n])})(n,o);return[i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7],1]},WX=(t,e)=\u003e{const n=Math.cos(e),o=Math.sin(e);return[n,-o,t.x-n*t.x+o*t.y,o,n,t.y-o*t.x-n*t.y,0,0,1]},HX=(t,e)=\u003e{const n=t[6]*e.x+t[7]*e.y+t[8];return Math.abs(n)\u003cAX?{x:e.x,y:e.y}:{x:(t[0]*e.x+t[1]*e.y+t[2])/n,y:(t[3]*e.x+t[4]*e.y+t[5])/n}},GX=(t,e,n)=\u003e{const{u:o,v:i}=zX(n);return{x:e.x+t.x*o.x+t.y*i.x,y:e.y+t.x*o.y+t.y*i.y}},UX=(t,e)=\u003eGX({x:t.x-e.center.x,y:t.y-e.center.y},e.center,e.ccwRotationRadians),ZX=(t,e)=\u003e{const n=((t,e,n)=\u003e{const{u:o,v:i}=zX(n),r={x:t.x-e.x,y:t.y-e.y};return{x:LX(r,o),y:LX(r,i)}})(t,e.center,e.ccwRotationRadians);if(Math.abs(n.x)\u003cAX\u0026\u0026Math.abs(n.y)\u003cAX)return{...e.center};const o=e.width/2,i=e.height/2,r=Math.abs(n.x)\u003eAX?o/Math.abs(n.x):1/0,s=Math.abs(n.y)\u003eAX?i/Math.abs(n.y):1/0,a=Math.min(r,s);return{x:e.center.x+n.x*a,y:e.center.y+n.y*a}},qX=(t,e=0,n=0)=\u003e{const o=((t,e)=\u003e{const n=$X(e);for(let e=0;e\u003cn.length;e++){const o=n[e],i=n[(e+1)%n.length];if((i.x-o.x)*(t.y-o.y)-(i.y-o.y)*(t.x-o.x)\u003c-1e-7)return!1}return!0})(jX(t),t)?[...t]:(t=\u003e{const e=[...t].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e.x-t.x)\u003c1e-9\u0026\u0026Math.abs(e.y-t.y)\u003c1e-9)===e).sort((t,e)=\u003et.x-e.x||t.y-e.y);if(e.length\u003c=3)return e;const n=(t,e,n)=\u003e(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),o=[];for(const t of e){for(;o.length\u003e=2\u0026\u0026n(o[o.length-2],o[o.length-1],t)\u003c=1e-9;)o.pop();o.push(t)}const i=[];for(let t=e.length-1;t\u003e=0;t--){const o=e[t];for(;i.length\u003e=2\u0026\u0026n(i[i.length-2],i[i.length-1],o)\u003c=1e-9;)i.pop();i.push(o)}return o.pop(),i.pop(),[...o,...i]})(t),i=jX(o),r=YX(o,i),s=BX(o),a=r.width*r.height,c=(l=e,Math.max(0,l));var l;const d=a+Math.max(0,s-a)*c,h=a\u003eAX\u0026\u0026d\u003ea?Math.sqrt(d/a):1,u=Math.max(0,n),p=Math.max(r.width*h,u),m=Math.max(r.height*h,u),g=DX(r.ccwRotationRadians),f=180*g/Math.PI,y=(t=\u003e{const e=t.width/2,n=t.height/2;return[{x:t.center.x-e,y:t.center.y-n},{x:t.center.x+e,y:t.center.y-n},{x:t.center.x+e,y:t.center.y+n},{x:t.center.x-e,y:t.center.y+n}]})({center:i,width:p,height:m}),_=(t=\u003e{const e=t.width/2,n=t.height/2;return[GX({x:-e,y:-n},t.center,t.ccwRotationRadians),GX({x:e,y:-n},t.center,t.ccwRotationRadians),GX({x:e,y:n},t.center,t.ccwRotationRadians),GX({x:-e,y:n},t.center,t.ccwRotationRadians)]})({center:i,width:p,height:m,ccwRotationRadians:g}),b=_.map(t=\u003e{const e={x:t.x-i.x,y:t.y-i.y},n=((t,e,n)=\u003e{let o;for(let i=0;i\u003cn.length;i++){const r=XX(t,e,n[i],n[(i+1)%n.length]);r\u0026\u0026(!o||r.rayT\u003co.rayT)\u0026\u0026(o=r)}return o})(i,e,o);return n?{x:n.x,y:n.y}:t});let x=BX(b)\u003eAX?b:_;let v,S;try{v=VX(y,x),S=(t=\u003e{const[e,n,o,i,r,s,a,c,l]=t,d=r*l-s*c,h=-(i*l-s*a),u=i*c-r*a,p=-(n*l-o*c),m=e*l-o*a,g=-(e*c-n*a),f=n*s-o*r,y=-(e*s-o*i),_=e*r-n*i,b=e*d+n*h+o*u;if(Math.abs(b)\u003cAX)throw new Error(\"Cannot invert singular 3x3 matrix\");const x=1/b;return[d*x,p*x,f*x,h*x,m*x,y*x,u*x,g*x,_*x]})(v)}catch{x=_,v=WX(i,g),S=WX(i,-g)}return{center:i,width:p,height:m,innerWidth:r.width,innerHeight:r.height,ccwRotationDegrees:f,ccwRotationRadians:g,polygonArea:s,equivalentAreaExpansionFactor:c,targetQuad:x,rectToPolygonMatrix:v,polygonToRectMatrix:S}},JX=class extends si{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1}params;getSolverName(){return\"AttachProjectedRectsSolver\"}outputNodes=[];projectionAdjustmentByNodeId=new Map;_step(){this.projectionAdjustmentByNodeId.clear(),this.outputNodes=this.params.nodesWithPortPoints.map(t=\u003e{const e=this.params.equivalentAreaExpansionFactor??0,n=this.params.minProjectedRectDimension??0,o=(({traceWidth:t,viaDiameter:e,obstacleMargin:n,minProjectedRectDimension:o})=\u003eMath.max(o,e??0,(t??0)+2*(n??0)))({traceWidth:this.params.traceWidth,viaDiameter:this.params.viaDiameter,obstacleMargin:this.params.obstacleMargin,minProjectedRectDimension:n});let i=qX(t.polygon,e,n);if(Math.min(i.width,i.height)\u003eo+(this.params.traceWidth??0))return{...t,center:i.center,width:i.width,height:i.height,projectedRect:i};const r=qX(t.polygon,1,n);return(({node:t,projectedRect:e,conservativeProjectedRect:n,requiredRoutingCorridorWidth:o,traceWidth:i})=\u003e{if(o\u003c=0)return!1;const r=Math.min(e.width,e.height),s=Math.min(n.width,n.height),a=Math.max(e.width,e.height),c=Math.max(n.width,n.height),l=o+(i??0),d=Math.floor(r/o),h=Math.floor(s/o);return new Set(t.portPoints.map(t=\u003et.connectionName)).size\u003e1\u0026\u0026d\u003c=h\u0026\u0026r\u003c=l\u0026\u0026a-c\u003e=o\u0026\u0026e.equivalentAreaExpansionFactor\u003e1})({node:t,projectedRect:i,conservativeProjectedRect:r,requiredRoutingCorridorWidth:o,traceWidth:this.params.traceWidth})\u0026\u0026(i=r,this.projectionAdjustmentByNodeId.set(t.capacityMeshNodeId,\"corridor-expansion-factor-1\")),{...t,center:i.center,width:i.width,height:i.height,projectedRect:i}}),this.solved=!0}getOutput(){return this.outputNodes}getConstructorParams(){return[this.params]}visualize(){const t=this.outputNodes.length\u003e0?this.outputNodes:this.params.nodesWithPortPoints;return{polygons:t.map(t=\u003e({points:t.polygon,fill:\"rgba(40, 140, 220, 0.06)\",stroke:\"rgba(20, 70, 160, 0.95)\",strokeWidth:.04,label:`${t.capacityMeshNodeId} polygon`})),lines:t.map(t=\u003e({points:[...t.polygon,t.polygon[0]],strokeColor:\"rgba(20, 70, 160, 0.95)\",strokeWidth:.04,label:`${t.capacityMeshNodeId} polygon outline`})),rects:t.flatMap(t=\u003et.projectedRect?[{center:t.projectedRect.center,width:t.projectedRect.width,height:t.projectedRect.height,ccwRotationDegrees:t.projectedRect.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.16)\",stroke:\"rgba(255, 140, 0, 0.8)\",label:`${t.capacityMeshNodeId} projectedRect`}]:[]),points:t.flatMap(t=\u003et.portPoints.map(t=\u003e({x:t.x,y:t.y,color:\"rgba(30, 30, 30, 0.85)\",label:t.connectionName})))}}},KX=class extends si{constructor(t){super(),this.params=t;const{nodeWithPortPoints:e}=t;if(!e.projectedRect)throw new Error(\"Poly node is missing projectedRect\");this.projectedPorts=e.portPoints.map(t=\u003e{const n=ZX(t,e.projectedRect);return{original:t,projected:{...t,x:n.x,y:n.y}}}),this.projectedNode={capacityMeshNodeId:e.capacityMeshNodeId,center:e.projectedRect.center,width:e.projectedRect.width,height:e.projectedRect.height,availableZ:e.availableZ,portPoints:this.projectedPorts.map(({projected:t})=\u003et)},this.highDensitySolver=new Ss({nodeWithPortPoints:this.projectedNode,colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort}),this.activeSubSolver=this.highDensitySolver,this.MAX_ITERATIONS=this.highDensitySolver.MAX_ITERATIONS+1e3}params;getSolverName(){return\"PolySingleIntraNodeSolver\"}highDensitySolver;projectedNode;solvedRoutes=[];projectedPorts;_step(){this.highDensitySolver.step(),this.progress=this.highDensitySolver.progress,this.stats=this.highDensitySolver.stats,this.highDensitySolver.solved?(this.solvedRoutes=this.highDensitySolver.solvedRoutes,this.solved=!0,this.activeSubSolver=null):this.highDensitySolver.failed\u0026\u0026(this.error=this.highDensitySolver.error,this.failed=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.params]}visualize(){const t=this.params.nodeWithPortPoints,e=t.projectedRect,n={polygons:[{points:t.polygon,fill:\"rgba(60, 160, 220, 0.10)\",stroke:\"rgba(40, 90, 150, 0.7)\",label:`${t.capacityMeshNodeId} polygon`},...e?[{points:e.targetQuad,fill:\"rgba(255, 165, 0, 0.08)\",stroke:\"rgba(255, 120, 0, 0.65)\",label:`${t.capacityMeshNodeId} distortion target`}]:[]],rects:e?[{center:e.center,width:e.width,height:e.height,ccwRotationDegrees:e.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.14)\",stroke:\"rgba(255, 120, 0, 0.8)\",label:`${t.capacityMeshNodeId} projectedRect`}]:[],points:[...t.portPoints.map(t=\u003e({x:t.x,y:t.y,color:\"rgba(0, 80, 160, 0.85)\",label:`${t.connectionName} original`})),...this.projectedPorts.map(({projected:t})=\u003e({x:t.x,y:t.y,color:\"rgba(255, 120, 0, 0.85)\",label:`${t.connectionName} projected`}))]};return pi(n,this.highDensitySolver.visualize())}},QX=class extends si{getSolverName(){return\"PolyHighDensitySolver\"}unsolvedNodePortPoints;nodePortPoints;routes=[];routesByNodeId=new Map;failedSolvers=[];activeSubSolver=null;colorMap;connMap;viaDiameter;traceWidth;obstacleMargin;effort;nodePfById;constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a}){super(),this.nodePortPoints=[...t],this.unsolvedNodePortPoints=[...t],this.colorMap=e??{},this.connMap=n,this.viaDiameter=o??.3,this.traceWidth=i??.15,this.obstacleMargin=r??.15,this.effort=s??1,this.MAX_ITERATIONS=1e7*this.effort,this.nodePfById=a instanceof Map?new Map(a):new Map(Object.entries(a??{}))}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){const t=this.activeSubSolver.params.nodeWithPortPoints.capacityMeshNodeId,e=this.activeSubSolver.solvedRoutes;this.routesByNodeId.set(t,[...this.routesByNodeId.get(t)??[],...e]),this.routes.push(...this.activeSubSolver.solvedRoutes),this.activeSubSolver=null}else this.activeSubSolver.failed\u0026\u0026(this.failedSolvers.push(this.activeSubSolver),this.activeSubSolver=null);return}if(0===this.unsolvedNodePortPoints.length)return this.failedSolvers.length\u003e0?(this.failed=!0,void(this.error=`Failed to solve ${this.failedSolvers.length} poly nodes, ${this.failedSolvers.slice(0,5).map(t=\u003et.params.nodeWithPortPoints.capacityMeshNodeId).join(\", \")}. err0: ${this.failedSolvers[0]?.error}`)):void(this.solved=!0);const t=this.unsolvedNodePortPoints.pop();this.activeSubSolver=new KX({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort})}computeProgress(){const t=this.routes.length+this.failedSolvers.length+this.unsolvedNodePortPoints.length+(this.activeSubSolver?1:0);return 0===t?1:(this.routes.length+this.failedSolvers.length+(this.activeSubSolver?.progress??0))/t}getConstructorParams(){return[{nodePortPoints:this.nodePortPoints,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById}]}visualize(){const t={polygons:this.nodePortPoints.map(t=\u003e({points:t.polygon,fill:\"rgba(180, 180, 180, 0.05)\",stroke:\"rgba(120, 120, 120, 0.25)\",label:`${t.capacityMeshNodeId} polygon`})),rects:this.nodePortPoints.flatMap(t=\u003et.projectedRect?[{center:t.projectedRect.center,width:t.projectedRect.width,height:t.projectedRect.height,ccwRotationDegrees:t.projectedRect.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.08)\",stroke:\"rgba(255, 120, 0, 0.65)\",label:`${t.capacityMeshNodeId} projectedRect`}]:[]),lines:[],circles:[],points:this.nodePortPoints.flatMap(t=\u003et.portPoints.map(t=\u003e({x:t.x,y:t.y,color:\"rgba(80, 80, 80, 0.5)\",label:`${t.connectionName} original`})))};for(const[e,n]of this.routesByNodeId){const o=this.nodePortPoints.find(t=\u003et.capacityMeshNodeId===e),i=o?.projectedRect;if(i)for(const e of n){const n=this.colorMap[e.connectionName]??\"#0000ff\",o={...e,route:e.route.map(t=\u003e({...t,...UX(t,i)})),vias:e.vias.map(t=\u003eUX(t,i))},r=mi(o.route,e.connectionName,n);for(const n of r)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:To(n.color,.5),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?[.1,.3]:void 0});for(const i of o.vias)t.circles.push({center:i,layer:\"z0,1\",radius:e.viaDiameter/2,fill:n,label:`${e.connectionName} via`})}}const e=this.activeSubSolver?.visualize();return e\u0026\u0026t.polygons.push(...this.unsolvedNodePortPoints.map(t=\u003e({points:t.polygon,fill:\"rgba(180, 180, 180, 0.08)\",stroke:\"rgba(120, 120, 120, 0.4)\",label:t.capacityMeshNodeId}))),e?pi(t,e):t}},tV=t=\u003e{const{o:e,a:n,b:o}=t;return(n.x-e.x)*(o.y-e.y)-(n.y-e.y)*(o.x-e.x)},eV=(t,e)=\u003e{const n=[...new Set(t)].map(t=\u003e{const n=e[t];return n?{i:t,x:n.x,y:n.y}:null}).filter(t=\u003enull!==t);if(n.sort((t,e)=\u003et.x-e.x||t.y-e.y),n.length\u003c=2)return n.map(t=\u003et.i);const o=[],i=[];for(const t of n){for(;o.length\u003e=2;){const e=o[o.length-2],n=o[o.length-1];if(!e||!n||tV({o:e,a:n,b:t})\u003e1e-10)break;o.pop()}o.push(t)}for(let t=n.length-1;t\u003e=0;t--){const e=n[t];if(e){for(;i.length\u003e=2;){const t=i[i.length-2],n=i[i.length-1];if(!t||!n||tV({o:t,a:n,b:e})\u003e1e-10)break;i.pop()}i.push(e)}}return o.pop(),i.pop(),o.concat(i).map(t=\u003et.i)},nV=t=\u003e{const e=Math.max(0,Math.min(30,Math.floor(t)));return 0===e?0:(1\u003c\u003ce)-1},oV=(t,e=31)=\u003e{const n=[],o=Math.max(0,Math.min(31,Math.floor(e)));for(let e=0;e\u003co;e++)t\u00261\u003c\u003ce\u0026\u0026n.push(e);return n},iV=t=\u003e{let e=0;for(const n of t)Number.isInteger(n)\u0026\u0026n\u003e=0\u0026\u0026n\u003c31\u0026\u0026(e|=1\u003c\u003cn);return e},rV=(t,e)=\u003e{const n=t.trim().toLowerCase();if(\"top\"===n)return 0;if(\"bottom\"===n)return Math.max(0,e-1);const o=n.match(/^inner(\\d+)$/);if(o?.[1]){const t=Number(o[1]);return t\u003e=0\u0026\u0026t\u003ce?t:void 0}const i=n.match(/^layer(\\d+)$/);if(i?.[1]){const t=Number(i[1])-1;return t\u003e=0\u0026\u0026t\u003ce?t:void 0}const r=n.match(/^z(\\d+)$/);if(r?.[1]){const t=Number(r[1]);return t\u003e=0\u0026\u0026t\u003ce?t:void 0}},sV=(t,e)=\u003e{const n=nV(e),o=t.zLayers;if(Array.isArray(o)\u0026\u0026o.length\u003e0)return iV(o)\u0026n;const i=t.layers;if(Array.isArray(i)\u0026\u0026i.length\u003e0){let t=0;for(const n of i){const o=rV(n,e);void 0!==o\u0026\u0026(t|=1\u003c\u003co)}return t\u0026n}return n},aV=.1,cV=.15,lV=aV+cV,dV=3*lV/4,hV=5,uV=1e-9,pV=t=\u003eMath.round(1e6*t)/1e6,mV=t=\u003e`${pV(t.x)},${pV(t.y)}`,gV=(t,e)=\u003e{const n=mV(t),o=mV(e);return n\u003co?`${n}|${o}`:`${o}|${n}`},fV=t=\u003e{let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t)e=Math.min(e,r.x),n=Math.max(n,r.x),o=Math.min(o,r.y),i=Math.max(i,r.y);return{minX:e,maxX:n,minY:o,maxY:i}},yV=(t,e)=\u003e{const n=t.x\u003ce.minX?e.minX-t.x:t.x\u003ee.maxX?t.x-e.maxX:0,o=t.y\u003ce.minY?e.minY-t.y:t.y\u003ee.maxY?t.y-e.maxY:0;return n*n+o*o},_V=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c1e-18)return!1;const s=((t.x-e.x)*o+(t.y-e.y)*i)/r;if(s\u003c-1e-9||s\u003e1+1e-9)return!1;const a=e.x+s*o,c=e.y+s*i;return(t.x-a)**2+(t.y-c)**2\u003c1e-12},bV=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003cuV)return(t.x-e.x)**2+(t.y-e.y)**2;const s=Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r)),a=e.x+s*o,c=e.y+s*i;return(t.x-a)**2+(t.y-c)**2},xV=(t,e)=\u003e({x:(t.x+e.x)/2,y:(t.y+e.y)/2}),vV=(t,e,n,o=.001)=\u003e{const i=o*o;return((t,e)=\u003e{let n=Number.POSITIVE_INFINITY;for(let o=0;o\u003ce.length;o++){const i=e[o],r=e[(o+1)%e.length];n=Math.min(n,bV(t,i,r))}return n})(xV(t,e),n)\u003c=i},SV=(t,e)=\u003e{let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];if(_V(t,r,s))return!0;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y+1e-12)+r.x\u0026\u0026(n=!n)}return n},IV=(t,e,n,o)=\u003e{const i=e.x-t.x,r=e.y-t.y,s=o.x-n.x,a=o.y-n.y,c=i*a-r*s;if(Math.abs(c)\u003cuV){for(const i of[t,e])if(_V(i,n,o))return i;for(const i of[n,o])if(_V(i,t,e))return i;return}const l=((n.x-t.x)*a-(n.y-t.y)*s)/c,d=((n.x-t.x)*r-(n.y-t.y)*i)/c;if(!(l\u003c-1e-9||l\u003e1.000000001||d\u003c-1e-9||d\u003e1.000000001))return{x:t.x+l*i,y:t.y+l*r}},CV=(t,e)=\u003e{for(const n of t)if(SV(n,e))return n;for(const n of e)if(SV(n,t))return n;for(let n=0;n\u003ct.length;n++){const o=t[n],i=t[(n+1)%t.length];for(let t=0;t\u003ce.length;t++){const n=e[t],r=e[(t+1)%e.length],s=IV(o,i,n,r);if(s)return s}}},PV=(t,e=1e-6)=\u003e[{x:t.x-e,y:t.y-e},{x:t.x+e,y:t.y-e},{x:t.x,y:t.y+e}],MV=(t,e,n,o,i)=\u003e{const r=e.x-t.x,s=e.y-t.y,a=Math.hypot(r,s);if(a\u003cuV)return[];const c=Number.isFinite(n)\u0026\u0026n\u003euV?n:lV,l=Number.isFinite(o)?Math.max(0,o):dV,d=Math.min(l,a/2),h=a-2*d;if(h\u003c=.75*c)return[{x:(t.x+e.x)/2,y:(t.y+e.y)/2,distToCentermostPortOnZ:0,cramped:!0}];const u=Math.max(1,Math.floor(h/c)+1),p=Number.isFinite(i)\u0026\u0026i\u003e0?Math.floor(i):hV,m=u\u003ep?p+Math.floor(u/4):u;if(m\u003c=1)return[{x:(t.x+e.x)/2,y:(t.y+e.y)/2,distToCentermostPortOnZ:0,cramped:!1}];const g=a/2,f=Array.from({length:m},(e,n)=\u003e{const o=d+h*n/(m-1),i=o/a;return{x:t.x+r*i,y:t.y+s*i,distanceFromStart:o}}),y=f.reduce((t,e)=\u003eMath.abs(e.distanceFromStart-g)\u003cMath.abs(t-g)?e.distanceFromStart:t,f[0].distanceFromStart);return f.map(({x:t,y:e,distanceFromStart:n})=\u003e({x:t,y:e,distToCentermostPortOnZ:Math.abs(n-y),cramped:!1}))},NV=(t,e)=\u003e{if(!(Math.hypot(e.x-t.x,e.y-t.y)\u003cuV))return{...xV(t,e),distToCentermostPortOnZ:0,cramped:!1}},wV=(t,e)=\u003e{if(\"object\"!=typeof t||null===t)return;const n=t[e];return\"string\"==typeof n?n:void 0},TV=t=\u003e{const e=new Set,n=t=\u003e{\"string\"==typeof t\u0026\u0026t.length\u003e0\u0026\u0026e.add(t)},o=t=\u003e{n(t.pointId),n(t.pcb_port_id)};n(t.connectionId),n(t.mutuallyConnectedNetworkId),o(t.start),o(t.end);const i=t.simpleRouteConnection;n(wV(i,\"name\")),n(wV(i,\"source_trace_id\")),n(wV(i,\"rootConnectionName\"));const r=\"object\"==typeof i\u0026\u0026null!==i?i.pointsToConnect:void 0;if(Array.isArray(r))for(const t of r)o(t);return e},RV=t=\u003e{const{regions:e,availableZ:n,layerCount:o,connections:i=[],obstacleRegions:r=[],regionIdPrefix:s=\"free\",portIdPrefix:a=\"shared-port\",traceWidth:c=aV,obstacleMargin:l=cV,portSpacing:d=c+l,portMarginFromSegmentEndpoint:h=3*d/4,maxDensePortsBeforeDecimation:u=hV}=t,p=Array.from({length:o},(t,e)=\u003ee),m=new Map,g=new Map,f=t=\u003et.mutuallyConnectedNetworkId??t.connectionId;for(const t of i){const e=f(t);let n=m.get(e);void 0===n\u0026\u0026(n=m.size,m.set(e,n));for(const e of TV(t))g.has(e)||g.set(e,n)}const y=e.map((t,e)=\u003e{const o=fV(t);return{regionId:`${s}-${e}`,pointIds:[],d:{polygon:t,availableZ:n?.[e]??p,center:{x:(o.minX+o.maxX)/2,y:(o.minY+o.maxY)/2},width:o.maxX-o.minX,height:o.maxY-o.minY}}}),_=y.map((t,e)=\u003e({regionId:t.regionId,serializedRegionIndex:e,polygon:t.d.polygon,availableZ:t.d.availableZ,bounds:fV(t.d.polygon),isObstacle:!1,netId:void 0})),b=r.flatMap((t,e)=\u003e{if(t.polygon.length\u003c3)return[];const n=(t=\u003e{if(Number.isInteger(t.netId)\u0026\u0026t.netId\u003e=0)return t.netId;if(\"string\"==typeof t.mutuallyConnectedNetworkId)return m.get(t.mutuallyConnectedNetworkId);for(const e of t.connectedTo??[]){const t=g.get(e);if(void 0!==t)return t}})(t);if(void 0===n)return[];const o=t.polygon,i=fV(o),r=t.availableZ??p,s=t.regionId??`obstacle-${e}`,a=y.length;y.push({regionId:s,pointIds:[],d:{...t.d??{},polygon:o,availableZ:r,center:{x:(i.minX+i.maxX)/2,y:(i.minY+i.maxY)/2},width:i.maxX-i.minX,height:i.maxY-i.minY,_containsObstacle:!0,_containsTarget:!0,netId:n}});const c={regionId:s,serializedRegionIndex:a,polygon:o,availableZ:r,bounds:i,isObstacle:!0,netId:n};return _.push(c),[c]}),x=[],v=new Map;for(let t=0;t\u003ce.length;t++){const n=e[t];for(let e=0;e\u003cn.length;e++){const o=n[e],i=n[(e+1)%n.length],r=gV(o,i),s=v.get(r)??[];s.push({regionIndex:t,a:o,b:i}),v.set(r,s)}}let S=0;const I=t=\u003e{const{region1Id:e,region2Id:n,pointIndex:o,portPoint:i,z:r,portIdSuffix:s}=t,c=`${a}-${String(S).padStart(5,\"0\")}::p${o}::z${r}${s??\"\"}`;return x.push({portId:c,region1Id:e,region2Id:n,d:{portId:c,x:i.x,y:i.y,z:r,distToCentermostPortOnZ:i.distToCentermostPortOnZ,...i.cramped?{cramped:!0}:{}}}),S+=1,c};for(const t of v.values()){if(2!==t.length)continue;const[e,o]=t,i=n?.[e.regionIndex]??p,r=n?.[o.regionIndex]??p,a=i.filter(t=\u003er.includes(t));if(0===a.length)continue;const c=MV(e.a,e.b,d,h,u);if(0!==c.length)for(let t=0;t\u003cc.length;t++){const n=c[t];for(const i of a){if(b.some(t=\u003et.availableZ.includes(i)\u0026\u0026vV(e.a,e.b,t.polygon)))continue;const r=I({region1Id:`${s}-${e.regionIndex}`,region2Id:`${s}-${o.regionIndex}`,pointIndex:t,portPoint:n,z:i});y[e.regionIndex].pointIds.push(r),y[o.regionIndex].pointIds.push(r)}}}for(const t of b)for(const e of v.values())for(const o of e){if(!vV(o.a,o.b,t.polygon))continue;const e=(n?.[o.regionIndex]??p).filter(e=\u003et.availableZ.includes(e));if(0===e.length)continue;const i=NV(o.a,o.b);if(i)for(const n of e){const e=I({region1Id:`${s}-${o.regionIndex}`,region2Id:t.regionId,pointIndex:0,portPoint:i,z:n,portIdSuffix:\"::obstacle\"});y[o.regionIndex].pointIds.push(e),y[t.serializedRegionIndex].pointIds.push(e)}}for(let t=0;t\u003cb.length;t++){const e=b[t];for(let n=t+1;n\u003cb.length;n++){const t=b[n];if(e.netId!==t.netId)continue;const o=e.availableZ.filter(e=\u003et.availableZ.includes(e));if(0===o.length)continue;const i=CV(e.polygon,t.polygon);if(i)for(const n of o){const o=I({region1Id:e.regionId,region2Id:t.regionId,pointIndex:0,portPoint:{x:i.x,y:i.y,distToCentermostPortOnZ:0},z:n,portIdSuffix:\"::obstacle-contact\"});y[e.serializedRegionIndex].pointIds.push(o),y[t.serializedRegionIndex].pointIds.push(o)}}}const C=(t,e)=\u003e{const n=((t,e)=\u003e{if(Number.isInteger(t.z)\u0026\u0026t.z\u003e=0\u0026\u0026t.z\u003ce)return[t.z];if(Array.isArray(t.zLayers)\u0026\u0026t.zLayers.length\u003e0)return t.zLayers.filter(t=\u003eNumber.isInteger(t)\u0026\u0026t\u003e=0\u0026\u0026t\u003ce);if(\"string\"==typeof t.layer){const n=rV(t.layer,e);return void 0===n?[]:[n]}return Array.isArray(t.layers)\u0026\u0026t.layers.length\u003e0?t.layers.map(t=\u003erV(t,e)).filter(t=\u003evoid 0!==t):[0]})(t,o);let i;const r=_.filter(t=\u003et.isObstacle\u0026\u0026(void 0===e||t.netId===e));for(const e of r){const o=n.find(t=\u003ee.availableZ.includes(t))??e.availableZ[0];if(void 0!==o\u0026\u0026SV(t,e.polygon))return{regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o}}for(const e of _.filter(t=\u003e!t.isObstacle)){const o=n.find(t=\u003ee.availableZ.includes(t))??e.availableZ[0];if(void 0===o)continue;if(SV(t,e.polygon))return{regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o};const r=yV(t,e.bounds);(!i||r\u003ci.distanceSq)\u0026\u0026(i={regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o,distanceSq:r})}return i},P=[];for(const t of i){const e=m.get(f(t)),n=C(t.start,e),o=C(t.end,e);if(!n||!o)throw new Error(`Could not map connection \"${t.connectionId}\" endpoint into a generated region`);const i=`terminal-start-${t.connectionId}`,r=`terminal-end-${t.connectionId}`,s=`terminal-start-port-${t.connectionId}`,a=`terminal-end-port-${t.connectionId}`;y.push({regionId:i,pointIds:[s],d:{polygon:PV(t.start),availableZ:[n.z],center:{x:t.start.x,y:t.start.y},width:1e-6,height:1e-6,_containsTarget:!0}}),y.push({regionId:r,pointIds:[a],d:{polygon:PV(t.end),availableZ:[o.z],center:{x:t.end.x,y:t.end.y},width:1e-6,height:1e-6,_containsTarget:!0}}),x.push({portId:s,region1Id:n.regionId,region2Id:i,d:{portId:s,x:t.start.x,y:t.start.y,z:n.z,distToCentermostPortOnZ:0}}),x.push({portId:a,region1Id:o.regionId,region2Id:r,d:{portId:a,x:t.end.x,y:t.end.y,z:o.z,distToCentermostPortOnZ:0}}),y[n.serializedRegionIndex].pointIds.push(s),y[o.serializedRegionIndex].pointIds.push(a),P.push({connectionId:t.connectionId,mutuallyConnectedNetworkId:t.mutuallyConnectedNetworkId,startRegionId:i,endRegionId:r,simpleRouteConnection:t.simpleRouteConnection})}return{regions:y,ports:x,connections:P}},EV=t=\u003e{const{polygon:e,clearance:n,verticesOnly:o=!1}=t,i=e.points,r=i.length;if(r\u003c3)return[];const s=new xO(i.map(t=\u003emO(t.x,t.y))).orientation()===fE.CCW,a=[];for(let t=0;t\u003cr;t++){const e=i[t],o=i[(t+1)%r],c=gO(o.x-e.x,o.y-e.y);if(0===c.length){a.push(_O(mO(e.x,e.y),gO(1,0)));continue}const l=c.normalize(),d=s?gO(l.y,-l.x):gO(-l.y,l.x),h=mO(e.x+n*d.x,e.y+n*d.y);a.push(_O(h,d))}const c=[];for(let t=0;t\u003cr;t++){const e=a[(t-1+r)%r],n=a[t],o=e.intersect(n);if(o.length\u003e0){const t=o[0];c.push({x:t.x,y:t.y})}else c.push({x:n.pt.x,y:n.pt.y})}if(o)return c;const l=[];for(let t=0;t\u003cr;t++){const e=c[t],n=c[(t+1)%r],o=fO(mO(e.x,e.y),mO(n.x,n.y)).length,i=Math.max(2,Math.ceil(o/20));for(let t=0;t\u003ci;t++){const o=t/i;l.push({x:e.x+o*(n.x-e.x),y:e.y+o*(n.y-e.y)})}}return l},AV=t=\u003e{const{localX:e,localY:n,rect:o}=t,i=Math.cos(o.ccwRotation),r=Math.sin(o.ccwRotation);return{x:o.center.x+e*i-n*r,y:o.center.y+e*r+n*i}},OV=t=\u003enew xO(t.map(t=\u003emO(t.x,t.y))),kV=t=\u003e{const e=[];for(const n of t.faces){const t=[];for(const e of n.vertices)t.push({x:e.x,y:e.y});t.length\u003e=3\u0026\u0026e.push(t)}return e},LV=(t,e,n)=\u003e{const o=e.length;e.push(...t);const i=t.length;for(let t=0;t\u003ci;t++)n.push([o+t,o+(t+1)%i])},DV=t=\u003e{const{bounds:e,vias:n,clearance:o,rects:i,polygons:r=[],viaSegments:s=8,preserveObstacleBoundaries:a=!1}=t,c=[],l=[],d=[],{minX:h,maxX:u,minY:p,maxY:m}=e,g=10,f=[];for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:h+e*(u-h),y:p})}for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:u,y:p+e*(m-p)})}for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:u-e*(u-h),y:m})}for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:h,y:m-e*(m-p)})}d.push(l.length),LV(f,c,l);const y=[];for(const t of n){const e=t.diameter/2+o,n=[];for(let o=0;o\u003cs;o++){const i=2*Math.PI*o/s;n.push({x:t.center.x+e*Math.cos(i),y:t.center.y+e*Math.sin(i)})}y.push(n)}for(const t of i){const e=t.width/2+o,n=t.height/2+o,i=[AV({localX:-e,localY:-n,rect:t}),AV({localX:e,localY:-n,rect:t}),AV({localX:e,localY:n,rect:t}),AV({localX:-e,localY:n,rect:t})];y.push(i)}for(const t of r){if(t.points.length\u003c3)continue;const e=EV({polygon:t,clearance:o,verticesOnly:!0});y.push(e)}const _=a?y:(t=\u003e{if(t.length\u003c=1)return t;try{let e=t.map(OV);for(let t=0;t\u003c2;t++){const t=[],n=new Set;for(let o=0;o\u003ce.length;o++){if(n.has(o))continue;let i=e[o];for(let t=o+1;t\u003ce.length;t++){if(n.has(t))continue;const o=i.box,r=e[t].box;if(!(o.xmin\u003er.xmax+1e-6||o.xmax\u003cr.xmin-1e-6||o.ymin\u003er.ymax+1e-6||o.ymax\u003cr.ymin-1e-6))try{const o=WA.unify(i,e[t]);o.faces.size\u003e0\u0026\u0026(i=o,n.add(t))}catch{}}t.push(i),n.add(o)}e=t}const n=[];for(const t of e){const e=kV(t);n.push(...e)}return n.length\u003e0?n:t}catch{return t}})(y);for(const t of _)d.push(l.length),LV(t,c,l);const b=((t,e,n)=\u003e{const o=new Array(e.length);for(let t=0;t\u003ce.length;t++)for(let e=n.length-1;e\u003e=0;e--)if(t\u003e=n[e]){o[t]=e;break}const i=new Map,r=t.slice();for(let t=0;t\u003ce.length;t++)for(let n=t+1;n\u003ce.length;n++){if(o[t]===o[n])continue;const[s,a]=e[t],[c,l]=e[n],d=r[s],h=r[a],u=r[c],p=r[l],m=h.x-d.x,g=h.y-d.y,f=p.x-u.x,y=p.y-u.y,_=m*y-g*f;if(Math.abs(_)\u003c1e-10)continue;const b=((u.x-d.x)*y-(u.y-d.y)*f)/_,x=((u.x-d.x)*g-(u.y-d.y)*m)/_;if(b\u003e1e-6\u0026\u0026b\u003c.999999\u0026\u0026x\u003e1e-6\u0026\u0026x\u003c.999999){const e=d.x+b*m,o=d.y+b*g,s=r.length;r.push({x:e,y:o}),i.has(t)||i.set(t,[]),i.get(t).push({t:b,idx:s}),i.has(n)||i.set(n,[]),i.get(n).push({t:x,idx:s})}}if(0===i.size)return{pts:t,constraintEdges:e,hadCrossings:!1};const s=[];for(let t=0;t\u003ce.length;t++){const n=i.get(t);if(!n||0===n.length){s.push(e[t]);continue}n.sort((t,e)=\u003et.t-e.t);const[o,r]=e[t];let a=o;for(const t of n)s.push([a,t.idx]),a=t.idx;s.push([a,r])}return{pts:r,constraintEdges:s,hadCrossings:!0}})(c,l,d);return{pts:b.pts.map((t,e)=\u003e({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)})),constraintEdges:b.constraintEdges,hadCrossings:b.hadCrossings}},zV=t=\u003e{const{p:e,a:n,b:o}=t,i=o.x-n.x,r=o.y-n.y,s=i*i+r*r;if(s\u003c1e-10)return Math.hypot(e.x-n.x,e.y-n.y);let a=((e.x-n.x)*i+(e.y-n.y)*r)/s;return a=Math.max(0,Math.min(1,a)),Math.hypot(e.x-n.x-a*i,e.y-n.y-a*r)},FV=(t,e)=\u003e{if(t.length\u003c=3)return 0;const n=eV(t,e),o=new Set(n),i=n.map(t=\u003ee[t]).filter(t=\u003eBoolean(t));let r=0;for(const n of t){if(o.has(n))continue;const t=e[n];if(!t)continue;let s=Number.POSITIVE_INFINITY;for(let e=0;e\u003ci.length;e++){const n=i[e],o=i[(e+1)%i.length];n\u0026\u0026o\u0026\u0026(s=Math.min(s,zV({p:t,a:n,b:o})))}r=Math.max(r,s)}return r},BV=(t,e)=\u003et\u003ce?1e5*t+e:1e5*e+t,jV=(t,e)=\u003e{const n=t.map((e,n)=\u003e[e,t[(n+1)%t.length]]),o=e.map((t,n)=\u003e[t,e[(n+1)%e.length]]),i=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,r]of o)void 0!==r\u0026\u0026t===r\u0026\u0026e===n\u0026\u0026i.add(BV(t,e));if(0===i.size)return null;const r=[];for(const[t,e]of n)void 0!==e\u0026\u0026(i.has(BV(t,e))||r.push([t,e]));for(const[t,e]of o)void 0!==e\u0026\u0026(i.has(BV(t,e))||r.push([t,e]));if(0===r.length)return null;const s=new Map;for(const[t,e]of r)s.set(t,e);const a=r[0]?.[0];if(void 0===a)return null;const c=[a];let l=s.get(a),d=0;for(;void 0!==l\u0026\u0026l!==a\u0026\u0026d++\u003cr.length+5;)c.push(l),l=s.get(l);return l!==a||c.length!==r.length?null:c},$V=(t,e)=\u003et\u003ce?1e5*t+e:1e5*e+t,YV=(t,e)=\u003et\u003ce?1e5*t+e:1e5*e+t,XV=c(T(),1),VV=t=\u003e{const{a:e,b:n,c:o}=t,i=2*(e.x*(n.y-o.y)+n.x*(o.y-e.y)+o.x*(e.y-n.y));if(Math.abs(i)\u003c1e-10)return{x:0,y:0,r2:1e18};const r=e.x*e.x+e.y*e.y,s=n.x*n.x+n.y*n.y,a=o.x*o.x+o.y*o.y,c=(r*(n.y-o.y)+s*(o.y-e.y)+a*(e.y-n.y))/i,l=(r*(o.x-n.x)+s*(e.x-o.x)+a*(n.x-e.x))/i;return{x:c,y:l,r2:(e.x-c)**2+(e.y-l)**2}},WV=(t,e,n)=\u003e[t.a,t.b,t.c].includes(e)\u0026\u0026[t.a,t.b,t.c].includes(n),HV=t=\u003e{const{px:e,py:n,polygonPoints:o,clearance:i}=t;if(o.length\u003c3)return!1;const r=o.map(t=\u003emO(t.x,t.y)),s=[];for(let t=0;t\u003cr.length;t++){const e=r[t],n=r[(t+1)%r.length];s.push(fO(e,n))}const a=new xO;a.addFace(s);const c=mO(e,n);if(a.contains(c))return!0;const[l]=a.distanceTo(c);return l\u003ci-.1},GV=t=\u003e{const{point:e,via:n,clearance:o}=t,i=e.x-n.center.x,r=e.y-n.center.y,s=n.diameter/2+o;return i*i+r*r\u003c=s*s+1e-9},UV=t=\u003e{const{point:e,rect:n,clearance:o}=t,i=Math.cos(-n.ccwRotation),r=Math.sin(-n.ccwRotation),s=e.x-n.center.x,a=e.y-n.center.y,c=s*i-a*r,l=s*r+a*i;return Math.abs(c)\u003c=n.width/2+o+1e-9\u0026\u0026Math.abs(l)\u003c=n.height/2+o+1e-9},ZV=t=\u003eHV({px:t.point.x,py:t.point.y,polygonPoints:t.polygon.points,clearance:t.clearance}),qV=(t,e)=\u003et.x\u003e=e.minX-1e-9\u0026\u0026t.x\u003c=e.maxX+1e-9\u0026\u0026t.y\u003e=e.minY-1e-9\u0026\u0026t.y\u003c=e.maxY+1e-9,JV=t=\u003e{const{point:e,vias:n,rects:o,polygons:i,clearance:r,layerCount:s}=t;let a=0;for(const t of n)GV({point:e,via:t,clearance:r})\u0026\u0026(a|=sV(t,s));for(const t of o)UV({point:e,rect:t,clearance:r})\u0026\u0026(a|=sV(t,s));for(const t of i)ZV({point:e,polygon:t,clearance:r})\u0026\u0026(a|=sV(t,s));return a},KV=t=\u003e{const{triangles:e,pts:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a,layerCount:c}=t,l=nV(c),d=[],h=[];for(const[t,u,p]of e){const e=n[t],m=n[u],g=n[p];if(!e||!m||!g)continue;const f={x:(e.x+m.x+g.x)/3,y:(e.y+m.y+g.y)/3};if(!qV(f,o))continue;const y=l\u0026~JV({point:f,vias:i,rects:s,polygons:a,clearance:r,layerCount:c});0!==y\u0026\u0026(d.push([t,u,p]),h.push(oV(y,c)))}return{triangles:d,triangleAvailableZ:h}},QV=t=\u003e{const{triangles:e,pts:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a}=t;return e.filter(([t,e,c])=\u003e{const l=n[t],d=n[e],h=n[c];if(!l||!d||!h)return!1;if(!(t=\u003e{const{px:e,py:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a}=t,{minX:c,maxX:l,minY:d,maxY:h}=o,u=1e-6*Math.max(l-c,h-d,1);if(e\u003cc-u||e\u003el+u||n\u003cd-u||n\u003eh+u)return!1;for(const t of i){const o=t.diameter/2+r,i=Math.max(0,o-u);if((e-t.center.x)**2+(n-t.center.y)**2\u003ci*i)return!1}for(const t of s){const o=t.width/2+r,i=t.height/2+r,s=Math.max(0,o-u),a=Math.max(0,i-u),c=e-t.center.x,l=n-t.center.y,d=Math.cos(t.ccwRotation),h=Math.sin(t.ccwRotation),p=c*d+l*h,m=-c*h+l*d;if(Math.abs(p)\u003cs\u0026\u0026Math.abs(m)\u003ca)return!1}for(const t of a)if(HV({px:e,py:n,polygonPoints:t.points,clearance:r}))return!1;return!0})({px:(l.x+d.x+h.x)/3,py:(l.y+d.y+h.y)/3,bounds:o,vias:i,clearance:r,rects:s,polygons:a}))return!1;if(a.length\u003e0){const t=[l,d,h,{x:(l.x+d.x)/2,y:(l.y+d.y)/2},{x:(d.x+h.x)/2,y:(d.y+h.y)/2},{x:(h.x+l.x)/2,y:(h.y+l.y)/2}];for(const e of t)for(const t of a)if(HV({px:e.x,py:e.y,polygonPoints:t.points,clearance:r}))return!1}return!0})},tW=t=\u003evoid 0!==t,eW=t=\u003e{const{bounds:e,clearance:n,concavityTolerance:o}=t,i=t.vias??[],r=t.rects??[],s=t.polygons??[];let a,c,l;if(!1!==t.useConstrainedDelaunay){const o=DV({bounds:e,vias:i,clearance:n,rects:r,polygons:s,viaSegments:t.viaSegments,preserveObstacleBoundaries:void 0!==t.layerCount});a=o.pts;const d=((t,e,n={})=\u003e{const o=t.map(t=\u003e[t.x,t.y]);return(0,XV.default)(o,e,{exterior:!!n.includeConstraintInteriors})})(a,o.constraintEdges,{includeConstraintInteriors:void 0!==t.layerCount});if(void 0!==t.layerCount){const o=KV({triangles:d,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s,layerCount:t.layerCount});c=o.triangles,l=o.triangleAvailableZ}else{c=i.length\u003e0||r.length\u003e0||s.length\u003e0?QV({triangles:d,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s}):d}}else{a=(t=\u003e{const{bounds:e,vias:n,clearance:o,rects:i,polygons:r=[],viaSegments:s=24}=t,a=[],{minX:c,maxX:l,minY:d,maxY:h}=e;a.push({x:c,y:d},{x:l,y:d},{x:l,y:h},{x:c,y:h});for(let t=1;t\u003c10;t++){const e=t/10;a.push({x:c+e*(l-c),y:d}),a.push({x:l,y:d+e*(h-d)}),a.push({x:l-e*(l-c),y:h}),a.push({x:c,y:h-e*(h-d)})}for(const t of n){const e=t.diameter/2+o;for(let n=0;n\u003cs;n++){const o=2*Math.PI*n/s;a.push({x:t.center.x+e*Math.cos(o),y:t.center.y+e*Math.sin(o)})}}for(const t of i){const e=t.width/2+o,n=t.height/2+o,i=Math.max(2,Math.ceil(Math.max(2*e,2*n)/20));for(let o=0;o\u003ci;o++){const r=o/i;a.push(AV({localX:2*r*e-e,localY:-n,rect:t})),a.push(AV({localX:e,localY:2*r*n-n,rect:t})),a.push(AV({localX:e-2*r*e,localY:n,rect:t})),a.push(AV({localX:-e,localY:n-2*r*n,rect:t}))}}for(const t of r){if(t.points.length\u003c3)continue;const e=EV({polygon:t,clearance:o});a.push(...e)}return a.map((t,e)=\u003e({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))})({bounds:e,vias:i,clearance:n,rects:r,polygons:s,viaSegments:t.viaSegments});const o=(t=\u003e{const e=t.map((t,e)=\u003e({...t,i:e}));if(e.length\u003c3)return[];let n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),o=Math.min(o,t.y),i=Math.max(i,t.x),r=Math.max(r,t.y);const s=Math.max(i-n,r-o)||1,a=(n+i)/2,c=(o+r)/2,l={x:a-30*s,y:c-s,i:-1},d={x:a,y:c+30*s,i:-2},h={x:a+30*s,y:c-s,i:-3};let u=[{a:l,b:d,c:h,cc:VV({a:l,b:d,c:h})}];for(const t of e){const e=u.filter(e=\u003e{const n=t.x-e.cc.x,o=t.y-e.cc.y;return n*n+o*o\u003ce.cc.r2+1e-6}),n=new Set(e),o=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[i,r]of n){let n=!1;for(const o of e)if(o!==t\u0026\u0026WV(o,i,r)){n=!0;break}n||o.push([i,r])}}u=u.filter(t=\u003e!n.has(t));for(const[e,n]of o)u.push({a:e,b:n,c:t,cc:VV({a:e,b:n,c:t})})}return u.filter(t=\u003et.a.i\u003e=0\u0026\u0026t.b.i\u003e=0\u0026\u0026t.c.i\u003e=0).map(t=\u003e[t.a.i,t.b.i,t.c.i])})(a);if(void 0!==t.layerCount){const d=KV({triangles:o,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s,layerCount:t.layerCount});c=d.triangles,l=d.triangleAvailableZ}else c=QV({triangles:o,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s})}const{cells:d,depths:h,availableZ:u}=!1!==t.usePolyanyaMerge?(t=\u003e{const{triangles:e,pts:n,cellAvailableZ:o,layerMergeMode:i=\"same\"}=t;if(!e.length)return{cells:[],depths:[]};const r=e.length,s=e.map(([t,e,o])=\u003e{const i=n[t],r=n[e],s=n[o];return i\u0026\u0026r\u0026\u0026s\u0026\u0026tV({o:i,a:r,b:s})\u003c0?[t,o,e]:[t,e,o]}),a=o?.map(iV),c=new Array(r).fill(null);for(let t=0;t\u003cr;t++)c[t]=new Map;function l(){for(let t=0;t\u003cc.length;t++)c[t]\u0026\u0026c[t].clear();const t=new Map;for(let e=0;e\u003cs.length;e++){const n=s[e];if(n)for(let o=0;o\u003cn.length;o++){const i=n[o],r=n[(o+1)%n.length],s=YV(i,r),a=t.get(s);a?(c[e].set(o,{neighbor:a.cellIdx,neighborEdge:a.edgePos}),c[a.cellIdx].set(a.edgePos,{neighbor:e,neighborEdge:o})):t.set(s,{cellIdx:e,edgePos:o})}}}function d(t){let e=0;for(let o=0;o\u003ct.length;o++){const i=n[t[o]],r=n[t[(o+1)%t.length]];e+=i.x*r.y-r.x*i.y}return Math.abs(e)/2}function h(t,e){const n=s[t],o=c[t],i=n.length;let r=-1;for(const[t,n]of o)if(n.neighbor===e){r=t;break}if(-1===r)return null;let a=r;for(;;){const t=(a-1+i)%i;if(t===r)break;const n=o.get(t);if(!n||n.neighbor!==e)break;a=t}let l=r;for(;;){const t=(l+1)%i;if(t===a)break;const n=o.get(t);if(!n||n.neighbor!==e)break;l=t}return{firstK:a,lastK:l,sharedCount:(l-a+i)%i+1}}function u(t,e){const o=s[t],r=s[e],c=h(t,e);if(!c)return!1;const{firstK:l,lastK:d,sharedCount:u}=c,p=o.length,m=r.length,g=o[l],f=o[(d+1)%p];let y=-1;for(let t=0;t\u003cm;t++)if(r[t]===g){y=t;break}if(-1===y)return!1;const _=(y-u+m)%m;if(r[_]!==f)return!1;const b=n[o[(l-1+p)%p]],x=n[g],v=n[r[(y+1)%m]];if(tV({o:b,a:x,b:v})\u003c-1e-8)return!1;const S=n[r[(_-1+m)%m]],I=n[f],C=n[o[(d+2)%p]];if(tV({o:S,a:I,b:C})\u003c-1e-8)return!1;if(a){if(0===(a[t]\u0026a[e]))return!1;if(\"same\"===i\u0026\u0026a[t]!==a[e])return!1}return!0}function p(t,e){const n=s[t],o=s[e],i=h(t,e),{firstK:r,lastK:c,sharedCount:l}=i,d=n.length,u=o.length,p=n[r],m=n[(c+1)%d];let g=-1;for(let t=0;t\u003cu;t++)if(o[t]===p){g=t;break}const f=[];f.push(p);const y=u-l-1;for(let t=1;t\u003c=y;t++)f.push(o[(g+t)%u]);f.push(m);const _=d-l-1;for(let t=2;t\u003c=_+1;t++)f.push(n[(c+t)%d]);s[t]=f,s[e]=null,a\u0026\u0026(a[t]=a[t]\u0026a[e],a[e]=0)}l();let m=!0;for(;m;){m=!1,l();for(let t=0;t\u003cs.length;t++){if(!s[t])continue;const e=c[t],n=new Set;for(const[,t]of e)s[t.neighbor]\u0026\u0026n.add(t.neighbor);if(1===n.size){const e=n.values().next().value;u(t,e)\u0026\u0026(p(t,e),m=!0)}}}l();const g=new Array(s.length).fill(0);for(let t=0;t\u003cs.length;t++)s[t]\u0026\u0026(g[t]=d(s[t]));const f=[];function y(t){f.push(t);let e=f.length-1;for(;e\u003e0;){const t=e-1\u003e\u003e1;if(f[t].area\u003e=f[e].area)break;const n=f[t];f[t]=f[e],f[e]=n,e=t}}function _(){if(0===f.length)return;const t=f[0],e=f.pop();if(f.length\u003e0){f[0]=e;let t=0;for(;;){let e=t;const n=2*t+1,o=2*t+2;if(n\u003cf.length\u0026\u0026f[n].area\u003ef[e].area\u0026\u0026(e=n),o\u003cf.length\u0026\u0026f[o].area\u003ef[e].area\u0026\u0026(e=o),e===t)break;const i=f[t];f[t]=f[e],f[e]=i,t=e}}return t}const b=new Set;for(let t=0;t\u003cs.length;t++){if(!s[t])continue;const e=c[t],n=new Set;for(const[,t]of e)s[t.neighbor]\u0026\u0026n.add(t.neighbor);for(const e of n){const n=t\u003ce?1e5*t+e:1e5*e+t;b.has(n)||(b.add(n),u(t,e)\u0026\u0026y({area:g[t]+g[e],xIdx:t,yIdx:e}))}}for(;f.length\u003e0;){const t=_(),{xIdx:e,yIdx:n}=t;if(!s[e]||!s[n])continue;const o=g[e]+g[n];if(Math.abs(o-t.area)\u003e1e-10){u(e,n)\u0026\u0026y({area:o,xIdx:e,yIdx:n});continue}if(!u(e,n))continue;p(e,n),g[e]=d(s[e]),l();const i=c[e],r=new Set;for(const[,t]of i)s[t.neighbor]\u0026\u0026r.add(t.neighbor);for(const t of r)u(e,t)\u0026\u0026y({area:g[e]+g[t],xIdx:e,yIdx:t})}const x=s.filter(t=\u003enull!==t),v=a?s.flatMap((t,e)=\u003enull===t?[]:[oV(a[e])]):void 0,S=x.map(()=\u003e0);return{cells:x,depths:S,...v?{availableZ:v}:{}}})({triangles:c,pts:a,cellAvailableZ:l,layerMergeMode:t.layerMergeMode}):(t=\u003e{const{triangles:e,pts:n,concavityTolerance:o,cellAvailableZ:i,layerMergeMode:r=\"same\"}=t;if(!e.length)return{cells:[],depths:[]};const s=e.map(([t,e,o])=\u003e{const i=n[t],r=n[e],s=n[o];return i\u0026\u0026r\u0026\u0026s\u0026\u0026tV({o:i,a:r,b:s})\u003c0?[t,o,e]:[t,e,o]}),a=i?.map(iV),c=(t,e)=\u003e{if(!a)return;const n=a[t]\u0026a[e];return 0===n||\"same\"===r\u0026\u0026a[t]!==a[e]?0:n};let l=!0,d=0;for(;l\u0026\u0026d++\u003c800;){l=!1;const t=new Map,e=s.map(()=\u003enew Set);for(let n=0;n\u003cs.length;n++){const o=s[n];if(o)for(let i=0;i\u003co.length;i++){const r=o[i],s=o[(i+1)%o.length];if(void 0===r||void 0===s)continue;const a=$V(r,s);if(t.has(a)){const o=t.get(a);void 0!==o\u0026\u0026(e[n]?.add(o),e[o]?.add(n))}else t.set(a,n)}}let i=-1,r=-1,d=null,h=Number.POSITIVE_INFINITY;for(let t=0;t\u003cs.length;t++){const a=e[t];if(a)for(const e of a){if(e\u003c=t)continue;const a=jV(s[t]??[],s[e]??[]);if(!a)continue;if(0===c(t,e))continue;const l=FV(a,n);l\u003c=o+1e-6\u0026\u0026l\u003ch\u0026\u0026(h=l,i=t,r=e,d=a)}}if(i\u003c0||r\u003c0||!d)break;s[i]=d,a\u0026\u0026(a[i]=c(i,r),a.splice(r,1)),s.splice(r,1),l=!0}const h=s.map(t=\u003eFV(t,n));return{cells:s,depths:h,...a?{availableZ:a.map(t=\u003eoV(t))}:{}}})({triangles:c,pts:a,concavityTolerance:o,cellAvailableZ:l,layerMergeMode:t.layerMergeMode}),p=a.map(t=\u003e((t,e)=\u003e({x:Math.min(e.maxX,Math.max(e.minX,t.x)),y:Math.min(e.maxY,Math.max(e.minY,t.y))}))(t,e)),m=d.map(t=\u003et.map(t=\u003ep[t]).filter(tW)),g=d.map(t=\u003eeV(t,p).map(t=\u003ep[t]).filter(tW));return{pts:p,validTris:c,regions:m,hulls:g,depths:h,...u?{availableZ:u}:{}}},nW=t=\u003e{const e=[...new Set(t.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0))].sort((t,e)=\u003et-e);if(0!==e.length)return`z${e.join(\",\")}`},oW=t=\u003e{const e=[];for(let n=0;n\u003c31;n++)t\u00261\u003c\u003cn\u0026\u0026e.push(n);return e},iW=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,rW=t=\u003eiW(t)?{...t}:void 0===t?{}:{value:t},sW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];if(iW(n)){if(\"string\"==typeof n.serializedRegionId)return n.serializedRegionId;if(\"string\"==typeof n.regionId)return n.regionId;if(\"string\"==typeof n.capacityMeshNodeId)return n.capacityMeshNodeId}return`region-${e}`},aW=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];if(iW(n)){if(\"string\"==typeof n.serializedPortId)return n.serializedPortId;if(\"string\"==typeof n.portId)return(o=n.portId).includes(\"::\")?o.slice(0,o.indexOf(\"::\")):o}var o;return`port-${e}`},cW=(t,e)=\u003e{const n=rW(t.topology.regionMetadata?.[e]);if(iW(n.center)||(n.center={x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),\"number\"!=typeof n.width\u0026\u0026(n.width=t.topology.regionWidth[e]),\"number\"!=typeof n.height\u0026\u0026(n.height=t.topology.regionHeight[e]),!Array.isArray(n.availableZ)){const o=t.topology.regionAvailableZMask?.[e]??0;0!==o\u0026\u0026(n.availableZ=oW(o))}return n.layer=nW(Array.isArray(n.availableZ)?n.availableZ:[])??nW((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))??\"z0\",n},lW=(t,e)=\u003e{const n=rW(t.topology.portMetadata?.[e]);return\"number\"!=typeof n.x\u0026\u0026(n.x=t.topology.portX[e]),\"number\"!=typeof n.y\u0026\u0026(n.y=t.topology.portY[e]),\"number\"!=typeof n.z\u0026\u0026(n.z=t.topology.portZ[e]),n.layer=nW([t.topology.portZ[e]])??\"z0\",n},dW=(t,e,n)=\u003e{const o=(t.topology.incidentPortRegion[e]??[]).find(t=\u003et!==n);if(void 0===o)throw new Error(`Port ${e} is not incident to a region outside route region ${n}`);return o},hW=(t,e,n)=\u003e{const{orderedPortIds:o,orderedRegionIds:i}=((t,e,n)=\u003e{if(0===n.length)throw new Error(`Route ${e} has no solved segments`);const o=t.problem.routeStartPort[e],i=t.problem.routeEndPort[e],r=new Map;n.forEach((t,e)=\u003e{const n={...t,segmentIndex:e},o=r.get(t.fromPortId)??[];o.push(n),r.set(t.fromPortId,o);const i=r.get(t.toPortId)??[];i.push(n),r.set(t.toPortId,i)});const s=[o],a=[],c=new Set;let l,d=o;for(;d!==i;){const t=(r.get(d)??[]).filter(t=\u003e!c.has(t.segmentIndex)\u0026\u0026(t.fromPortId===d?t.toPortId:t.fromPortId)!==l);if(1!==t.length)throw new Error(`Route ${e} is not a single ordered path from ${o} to ${i}`);const n=t[0],h=n.fromPortId===d?n.toPortId:n.fromPortId;c.add(n.segmentIndex),a.push(n.regionId),s.push(h),l=d,d=h}if(c.size!==n.length)throw new Error(`Route ${e} contains disconnected solved segments`);return{orderedPortIds:s,orderedRegionIds:a}})(t,e,n),r=i[0],s=i[i.length-1];if(void 0===r||void 0===s)throw new Error(`Route ${e} could not determine endpoint regions`);const a=sW(t,dW(t,o[0],r)),c=sW(t,dW(t,o[o.length-1],s)),l=((t,e,n,o)=\u003e{const i=t.problem.routeMetadata?.[e];return{connectionId:(iW(i)\u0026\u0026\"string\"==typeof i.connectionId?i.connectionId:void 0)??`route-${e}`,startRegionId:(iW(i)\u0026\u0026\"string\"==typeof i.startRegionId?i.startRegionId:void 0)??n,endRegionId:(iW(i)\u0026\u0026\"string\"==typeof i.endRegionId?i.endRegionId:void 0)??o,mutuallyConnectedNetworkId:(iW(i)\u0026\u0026\"string\"==typeof i.mutuallyConnectedNetworkId?i.mutuallyConnectedNetworkId:void 0)??`net-${t.problem.routeNet[e]}`}})(t,e,a,c),d=o.map((e,n)=\u003e{const r={portId:aW(t,e),g:n,h:0,f:n,hops:n,ripRequired:!1,nextRegionId:n\u003ci.length?sW(t,i[n]):l.endRegionId};return n\u003e0\u0026\u0026(r.lastPortId=aW(t,o[n-1]),r.lastRegionId=sW(t,i[n-1])),r});return{connection:l,solvedRoute:{connection:l,path:d,requiredRip:!1}}},uW=t=\u003e{if(!t.solved||t.failed)throw new Error(\"convertToSerializedHyperGraph requires a solved, non-failed solver\");const{topology:e}=t,n=(t=\u003e{const e=Array.from({length:t.problem.routeCount},()=\u003e[]);return t.state.regionSegments.forEach((t,n)=\u003e{for(const[o,i,r]of t)e[o].push({regionId:n,fromPortId:i,toPortId:r})}),e})(t),o=Array.from({length:e.regionCount},(n,o)=\u003e({regionId:sW(t,o),pointIds:e.regionIncidentPorts[o].map(e=\u003eaW(t,e)),d:cW(t,o)})),i=Array.from({length:e.portCount},(n,o)=\u003e{const[i,r]=e.incidentPortRegion[o]??[];if(void 0===i||void 0===r)throw new Error(`Port ${o} is missing incident regions`);return{portId:aW(t,o),region1Id:sW(t,i),region2Id:sW(t,r),d:lW(t,o)}}),r=n.map((e,n)=\u003ehW(t,n,e));return{regions:o,ports:i,connections:r.map(({connection:t})=\u003et),solvedRoutes:r.map(({solvedRoute:t})=\u003et)}},pW=t=\u003et\u003e0\u0026\u0026!(t\u0026t-1),mW=(t,e,n,o,i,r=0)=\u003e.2025*(2*e+1*n+1*o)*(1+i/5)/t+(pW(r)?10*e:0),gW=(t,e,n,o,i,r)=\u003e{const{netIds:s,lesserAngles:a,greaterAngles:c,layerMasks:l}=t;let d=0,h=0;for(let t=0;t\u003cs.length;t++){if(e===s[t])continue;(n\u003ca[t]\u0026\u0026a[t]\u003co)!==(n\u003cc[t]\u0026\u0026c[t]\u003co)\u0026\u0026(0!==(i\u0026l[t])?d++:h++)}return[d,h,r]},fW=class{constructor(t,e){this.items=t,this.compare=e}items;compare;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0}queue(t){this.items.push(t),this.siftUp(this.items.length-1)}dequeue(){const t=this.items[0];if(void 0===t)return;const e=this.items.pop();return this.items.length\u003e0\u0026\u0026(this.items[0]=e,this.siftDown(0)),t}siftUp(t){let e=t;for(;e\u003e0;){const t=e-1\u003e\u003e1,n=this.items[t],o=this.items[e];if(this.compare(n,o)\u003c=0)return;this.items[t]=o,this.items[e]=n,e=t}}siftDown(t){let e=t;const n=this.items.length;for(;;){const t=2*e+1;if(t\u003e=n)return;const o=t+1;let i=t;o\u003cn\u0026\u0026this.compare(this.items[o],this.items[t])\u003c0\u0026\u0026(i=o);const r=this.items[e],s=this.items[i];if(this.compare(r,s)\u003c=0)return;this.items[e]=s,this.items[i]=r,e=i}}},yW=(t,e)=\u003e{const n=[...t],o=(t=\u003e{let e=t\u003e\u003e\u003e0;return()=\u003e{e+=1831565813;let t=e;return t=Math.imul(t^t\u003e\u003e\u003e15,1|t),t^=t+Math.imul(t^t\u003e\u003e\u003e7,61|t),((t^t\u003e\u003e\u003e14)\u003e\u003e\u003e0)/4294967296}})(e);for(let t=n.length-1;t\u003e0;t--){const e=Math.floor(o()*(t+1));[n[t],n[e]]=[n[e],n[t]]}return n},_W=(t,e)=\u003et.routeMetadata?.[e],bW=t=\u003et?.simpleRouteConnection?.pointsToConnect?.map(({pointId:t})=\u003e\"string\"==typeof t?t:null).filter(t=\u003enull!==t)??[],xW=(t,e)=\u003e{const n=_W(t,e)?.connectionId;return\"string\"==typeof n?n:`route-${e}`},vW=(t,e,n)=\u003e{const o=t.portEndpointNetIds[n];if(!o)return!1;for(const t of o)if(t!==e)return!0;return!1},SW=(t,e,n)=\u003e{const o=t.regionNetId[n];return-1!==o\u0026\u0026o!==e},IW=t=\u003e[...new Set(t.routeIds)].filter(e=\u003e!((t,e)=\u003e{const{topology:n,problem:o,problemSetup:i,portAssignment:r,maxPrecheckHops:s}=t,a=o.routeNet[e],c=o.routeStartPort[e],l=o.routeEndPort[e];if(c===l)return!0;const d=t.getStartingNextRegionId(e,c);if(void 0===d)return!1;const h=[{portId:c,nextRegionId:d}],u=new Set([c*n.regionCount+d]);for(let t=0;t\u003ch.length;t++){const e=h[t];if(!SW(o,a,e.nextRegionId))for(const t of n.regionIncidentPorts[e.nextRegionId]??[]){const c=r[t];if(vW(i,a,t))continue;if(t===l){if(-1!==c\u0026\u0026c!==a)continue;return!0}if(t===e.portId)continue;if(-1!==c\u0026\u0026c!==a)continue;if(0===o.portSectionMask[t])continue;const d=n.incidentPortRegion[t]??[],p=d[0]===e.nextRegionId?d[1]:d[0];if(void 0===p||SW(o,a,p))continue;const m=t*n.regionCount+p;if(!u.has(m)){if(u.size\u003e=s)return!0;u.add(m),h.push({portId:t,nextRegionId:p})}}}return!1})(t,e)).map(e=\u003et.getRouteSummary(e)),CW=t=\u003e{const e=new Array(t);for(let n=0;n\u003ct;n++)e[n]=n;return e},PW=.05,MW={r:255,g:64,b:64,a:.72},NW=\"rgba(220, 38, 38, 0.98)\",wW=\"rgba(220, 38, 38, 0.12)\",TW=\"10 6\",RW=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),EW=t=\u003eMath.min(1,Math.max(0,t)),AW=(t,e,n)=\u003eMath.round(t+(e-t)*n),OW=({r:t,g:e,b:n,a:o})=\u003e`rgba(${t}, ${e}, ${n}, ${o})`,kW=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},LW=t=\u003e\"number\"==typeof t.centerRouteId,DW=(t,e)=\u003eLW(t)?e===t.centerRouteId?1:.5:1,zW=(t,e)=\u003e{const n=t.match(/^(rgba|hsla)\\((.*),\\s*([0-9]*\\.?[0-9]+)\\)$/);if(!n)return t;const[,o,i,r]=n,s=EW(Number(r)*e);return`${o}(${i}, ${Number(s.toFixed(3))})`},FW=(t,e,n=.8)=\u003e((t,e,n=.8)=\u003e{const o=`${t.problem.routeNet[e]}:${kW(t,e)}`;let i=0;for(let t=0;t\u003co.length;t++)i=17777*o.charCodeAt(t)+((i\u003c\u003c5)-i);return`hsla(${Math.abs(i)%360}, 70%, 50%, ${n})`})(t,e,n*DW(t,e)),BW=(t,e)=\u003e`net: ${t.problem.routeNet[e]}`,jW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=n?.polygon;if(Array.isArray(o)\u0026\u0026o.length\u003e=3){const t=o.map(t=\u003et.x),e=o.map(t=\u003et.y);return{minX:Math.min(...t),maxX:Math.max(...t),minY:Math.min(...e),maxY:Math.max(...e)}}const i=n?.bounds;if(i\u0026\u0026\"number\"==typeof i.minX\u0026\u0026\"number\"==typeof i.maxX\u0026\u0026\"number\"==typeof i.minY\u0026\u0026\"number\"==typeof i.maxY)return i;const r=t.topology.regionWidth[e],s=t.topology.regionHeight[e],a=t.topology.regionCenterX[e],c=t.topology.regionCenterY[e];return{minX:a-r/2,maxX:a+r/2,minY:c-s/2,maxY:c+s/2}},$W=(t,e)=\u003e({x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),YW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=Array.isArray(n?.availableZ)?n.availableZ.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0):[];if(o.length\u003e0)return nW(o)??\"z0\";const i=oW(t.topology.regionAvailableZMask?.[e]??0);if(i.length\u003e0)return nW(i)??\"z0\";const r=[...new Set((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))].sort((t,e)=\u003et-e);return nW(r)??\"z0\"},XW=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e],o=n?.existingRegionCost??0,i=t.state.regionCongestionCost[e]??0,r=t.problem.regionNetId[e];return RW(`region: region-${e}`,`net: ${-1===r?\"free\":`${r}`}`,t.getAdditionalRegionLabel(e),`cost: ${o.toFixed(3)}`,`congestion: ${i.toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},VW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];return n?.isConnectionRegion?{r:255,g:100,b:255,a:.6}:n?.isThroughJumper?{r:100,g:200,b:100,a:.5}:n?.isPad?{r:255,g:200,b:100,a:.5}:\"bottom\"===n?.layer?{r:52,g:152,b:219,a:.08}:{r:200,g:200,b:255,a:.1}},WW=(t,e)=\u003e{const n=VW(t,e),o=EW(t.state.regionIntersectionCaches[e]?.existingRegionCost??0),i=Math.pow(o,.8);return OW((s=MW,a=i,{r:AW((r=n).r,s.r,a),g:AW(r.g,s.g,a),b:AW(r.b,s.b,a),a:Number((r.a+(s.a-r.a)*a).toFixed(3))}));var r,s,a},HW=(t,e)=\u003e({x:t.topology.portX[e],y:t.topology.portY[e]}),GW=HW,UW=HW,ZW=(t,e)=\u003enW([t.topology.portZ[e]])??\"z0\",qW=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},JW=(t,e,n)=\u003e{if(void 0!==n)return`net: ${t.problem.routeNet[n]}`;const o=t.state.portAssignment[e];if(o\u003e=0)return`net: ${o}`;const i=new Set;for(let n=0;n\u003ct.problem.routeCount;n++)t.problem.routeStartPort[n]!==e\u0026\u0026t.problem.routeEndPort[n]!==e||i.add(t.problem.routeNet[n]);return 0!==i.size?`net: ${Array.from(i).sort((t,e)=\u003et-e).join(\", \")}`:void 0},KW=(t,e)=\u003e`z: ${t.topology.portZ[e]}`,QW=(t,e,n)=\u003eRW(qW(t,e),((t,e)=\u003e{const n=t.topology.incidentPortRegion[e]?.[0],o=t.topology.incidentPortRegion[e]?.[1];return`connects: region-${n??\"?\"} \u003c-\u003e region-${o??\"?\"}`})(t,e),JW(t,e,n)),tH=(t,e,n,o)=\u003e{const i=t.topology.portZ[n],r=t.topology.portZ[o];return i\u003e0\u0026\u0026r\u003e0?{strokeColor:zW(\"rgba(52, 152, 219, 0.95)\",DW(t,e)),strokeDash:\"3 2\"}:i!==r?{strokeColor:zW(\"rgba(22, 160, 133, 0.95)\",DW(t,e)),strokeDash:\"2 4 2\"}:{strokeColor:FW(t,e)}},eH=(t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++)if(t.problem.routeStartPort[n]===e||t.problem.routeEndPort[n]===e)return!0;return!1},nH=(t,e,n)=\u003e{const o=((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ce.length;o++)if(1===e[o])for(const e of t.topology.incidentPortRegion[o]??[])n.add(e);return n})(t,n),i=\"rgba(245, 158, 11, 0.95)\",r=\"rgba(245, 158, 11, 0.08)\";for(const n of o){const o=t.topology.regionMetadata?.[n],s=o?.polygon,a=jW(t,n),c=$W(t,n),l=a.maxX-a.minX,d=a.maxY-a.minY,h=YW(t,n),u=RW(\"section region\",XW(t,n));Array.isArray(s)\u0026\u0026s.length\u003e=3?e.polygons.push({points:s,fill:r,stroke:i,strokeWidth:2,layer:h,label:u}):e.rects.push({center:c,width:Math.max(l-PW,.05),height:Math.max(d-PW,.05),fill:r,stroke:i,layer:h,label:u})}for(let o=0;o\u003cn.length;o++)1===n[o]\u0026\u0026e.circles.push({center:UW(t,o),radius:.07,fill:\"rgba(251, 191, 36, 0.18)\",stroke:i,layer:ZW(t,o),label:RW(QW(t,o),KW(t,o),\"section port\")})},oH=(t,e={})=\u003e{const n={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:\"Tiny HyperGraph\",coordinateSystem:\"cartesian\"},o=((t,e)=\u003e{if(!e?.highlightSectionMask)return;const n=e.sectionPortMask??t.problem.portSectionMask;if(n.length!==t.topology.portCount)return;let o=0,i=0;for(let t=0;t\u003cn.length;t++)1===n[t]?o+=1:i+=1;return 0!==o\u0026\u00260!==i?n:void 0})(t,e);for(let e=0;e\u003ct.topology.regionCount;e++){const o=t.topology.regionMetadata?.[e],i=o?.polygon,r=jW(t,e),s=$W(t,e),a=r.maxX-r.minX,c=r.maxY-r.minY,l=YW(t,e),d=OW(VW(t,e));Array.isArray(i)\u0026\u0026i.length\u003e=3?n.polygons.push({points:i,fill:d,layer:l}):n.rects.push({center:s,width:Math.max(a-PW,.05),height:Math.max(c-PW,.05),fill:WW(t,e),layer:l,label:XW(t,e)})}if(((t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a=FW(t,n),c=kW(t,n),l=BW(t,n);e.points.push({x:r.x,y:r.y,color:a,layer:ZW(t,o),label:RW(`route: ${c}`,l,\"endpoint: start\",qW(t,o),KW(t,o))}),e.points.push({x:s.x,y:s.y,color:a,layer:ZW(t,i),label:RW(`route: ${c}`,l,\"endpoint: end\",qW(t,i),KW(t,i))})}})(t,n),0===t.iterations){for(const t of n.polygons)t.stroke=\"rgba(128, 128, 128, 0.5)\";for(const t of n.rects)t.stroke=\"rgba(128, 128, 128, 0.5)\"}if(0===t.iterations){for(let i=0;i\u003ct.topology.portCount;i++){const r=1===o?.[i];e.showOnlySectionPortsOnIdle\u0026\u0026!r||n.circles.push({center:UW(t,i),radius:.05,fill:t.topology.portZ[i]\u003e0?\"rgba(52, 152, 219, 0.55)\":\"rgba(128, 128, 128, 0.5)\",layer:ZW(t,i),label:RW(QW(t,i),KW(t,i))})}!1!==e.showInitialRouteHints\u0026\u0026((t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a={x:(r.x+s.x)/2,y:(r.y+s.y)/2};e.lines.push({points:[r,s],strokeColor:FW(t,n),strokeDash:\"3 3\",label:kW(t,n)}),e.points.push({x:a.x,y:a.y,color:FW(t,n,1),label:kW(t,n)})}})(t,n)}else((t,e)=\u003e{for(let n=0;n\u003ct.state.regionSegments.length;n++){const o=t.state.regionSegments[n]??[];for(const[i,r,s]of o)e.lines.push({points:[GW(t,r),GW(t,s)],label:RW(`route: ${kW(t,i)}`,`region: region-${n}`),...tH(t,i,r,s)})}})(t,n),((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ct.state.regionSegments.length;o++){const i=t.state.regionSegments[o]??[];for(const[o,r,s]of i)for(const i of[r,s]){const r=`${o}:${i}`;if(n.has(r))continue;n.add(r);const s=GW(t,i);e.points.push({x:s.x,y:s.y,color:FW(t,o,1),layer:ZW(t,i),label:RW(`route: ${kW(t,o)}`,qW(t,i),JW(t,i,o),KW(t,i))})}}})(t,n),(t=\u003eLW(t)\u0026\u0026!0===t.showUnassignedPortsInVisualization)(t)\u0026\u0026((t,e)=\u003e{for(let n=0;n\u003ct.topology.portCount;n++)t.state.portAssignment[n]\u003e=0||eH(t,n)||e.circles.push({center:UW(t,n),radius:.04,fill:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.2)\":\"rgba(128, 128, 128, 0.2)\",stroke:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.6)\":\"rgba(128, 128, 128, 0.6)\",layer:ZW(t,n),label:RW(QW(t,n),KW(t,n),\"state: unassigned\")})})(t,n),LW(t)||(((t,e)=\u003e{const n=t.state.currentRouteId;if(void 0===n||t.solved)return;const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a=FW(t,n),c=kW(t,n);e.lines.push({points:[r,s],strokeColor:a,strokeDash:\"10 5\",label:c})})(t,n),((t,e)=\u003e{if(t.solved)return;const n=t.state.currentRouteId,o=t.state.candidateQueue.toArray().sort((t,e)=\u003et.f-e.f).slice(0,10);for(let i=0;i\u003co.length;i++){const r=o[i],s=GW(t,r.portId),a=0===i;e.points.push({x:s.x,y:s.y,color:a?\"green\":\"rgba(128, 128, 128, 0.25)\",layer:ZW(t,r.portId),label:RW(QW(t,r.portId,n),KW(t,r.portId),`g: ${r.g.toFixed(2)}`,`h: ${r.h.toFixed(2)}`,`f: ${r.f.toFixed(2)}`)})}const i=o[0];if(!i)return;const r=[];let s=i;for(;s;)r.unshift(GW(t,s.portId)),s=s.prevCandidate;r.length\u003e1\u0026\u0026e.lines.push({points:r,strokeColor:void 0!==n?FW(t,n):\"rgba(0, 160, 120, 0.9)\"})})(t,n));o\u0026\u0026nH(t,n,o),((t,e)=\u003e{if(t.failed)for(const n of t.getNeverSuccessfullyRoutedRoutes()){const{routeId:o,connectionId:i,attempts:r,startPortId:s,endPortId:a}=n,c=BW(t,o),l=UW(t,s),d=UW(t,a),h=RW(`never routed: ${i}`,`attempts: ${r}`,c,n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0);e.lines.push({points:[{x:0,y:0},{x:l.x,y:l.y}],strokeColor:NW,strokeDash:TW,layer:ZW(t,s),label:RW(h,\"origin guide\",\"endpoint: start\")}),e.circles.push({center:l,radius:1,fill:wW,stroke:NW,layer:ZW(t,s),label:RW(h,\"endpoint: start\",qW(t,s),KW(t,s))}),e.lines.push({points:[{x:0,y:0},{x:d.x,y:d.y}],strokeColor:NW,strokeDash:TW,layer:ZW(t,a),label:RW(h,\"origin guide\",\"endpoint: end\")}),e.circles.push({center:d,radius:1,fill:wW,stroke:NW,layer:ZW(t,a),label:RW(h,\"endpoint: end\",qW(t,a),KW(t,a))})}})(t,n);const i=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1),r=o?o.reduce((t,e)=\u003et+Number(1===e),0):0;return n.title=[\"Tiny HyperGraph\",`iter=${t.iterations}`,`pending=${i}`,o?`sectionPorts=${r}`:void 0,t.failed?\"failed\":t.solved?\"solved\":\"running\"].filter(Boolean).join(\" | \"),n},iH=()=\u003e({netIds:new Int32Array(0),lesserAngles:new Int32Array(0),greaterAngles:new Int32Array(0),layerMasks:new Int32Array(0),existingCrossingLayerIntersections:0,existingSameLayerIntersections:0,existingEntryExitLayerChanges:0,existingRegionCost:0,existingSegmentCount:0}),rH=(t,e)=\u003et.f-e.f,sH=class extends kt{constructor(t,e,n){super(),this.topology=t,this.problem=e,((t,e)=\u003e{e\u0026\u0026(void 0!==e.DISTANCE_TO_COST\u0026\u0026(t.DISTANCE_TO_COST=e.DISTANCE_TO_COST),void 0!==e.RIP_THRESHOLD_START\u0026\u0026(t.RIP_THRESHOLD_START=e.RIP_THRESHOLD_START),void 0!==e.RIP_THRESHOLD_END\u0026\u0026(t.RIP_THRESHOLD_END=e.RIP_THRESHOLD_END),void 0!==e.RIP_THRESHOLD_RAMP_ATTEMPTS\u0026\u0026(t.RIP_THRESHOLD_RAMP_ATTEMPTS=e.RIP_THRESHOLD_RAMP_ATTEMPTS),void 0!==e.RIP_CONGESTION_REGION_COST_FACTOR\u0026\u0026(t.RIP_CONGESTION_REGION_COST_FACTOR=e.RIP_CONGESTION_REGION_COST_FACTOR),void 0!==e.MAX_ITERATIONS\u0026\u0026(t.MAX_ITERATIONS=e.MAX_ITERATIONS),void 0!==e.VERBOSE\u0026\u0026(t.VERBOSE=e.VERBOSE),void 0!==e.STATIC_REACHABILITY_PRECHECK\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK=e.STATIC_REACHABILITY_PRECHECK),void 0!==e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS=e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS))})(this,n),this.state={portAssignment:new Int32Array(t.portCount).fill(-1),regionSegments:Array.from({length:t.regionCount},()=\u003e[]),regionIntersectionCaches:Array.from({length:t.regionCount},()=\u003eiH()),currentRouteId:void 0,currentRouteNetId:void 0,unroutedRoutes:CW(e.routeCount),candidateQueue:new fW([],rH),candidateBestCostByHopId:new Float64Array(t.portCount*t.regionCount),candidateBestCostGenerationByHopId:new Uint32Array(t.portCount*t.regionCount),candidateBestCostGeneration:1,goalPortId:-1,ripCount:0,regionCongestionCost:new Float64Array(t.regionCount).fill(0)},this.routeAttemptCountByRouteId=new Uint32Array(e.routeCount),this.routeSuccessCountByRouteId=new Uint32Array(e.routeCount)}topology;problem;state;_problemSetup;routeAttemptCountByRouteId;routeSuccessCountByRouteId;hasLoggedNeverSuccessfullyRoutedRoutes=!1;segmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};DISTANCE_TO_COST=.05;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;RIP_CONGESTION_REGION_COST_FACTOR=.1;MAX_ITERATIONS=1e6;VERBOSE=!1;STATIC_REACHABILITY_PRECHECK=!0;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;get problemSetup(){return this._problemSetup||(this._problemSetup=this.computeProblemSetup()),this._problemSetup}computeProblemSetup(){const{topology:t,problem:e}=this,n=t.portX,o=t.portY,i=new Float64Array(t.portCount*e.routeCount),r=Array.from({length:t.portCount},()=\u003enew Set);for(let s=0;s\u003ce.routeCount;s++){r[e.routeStartPort[s]].add(e.routeNet[s]),r[e.routeEndPort[s]].add(e.routeNet[s]);const a=e.routeEndPort[s],c=n[a],l=o[a];for(let r=0;r\u003ct.portCount;r++){const t=n[r]-c,a=o[r]-l;i[r*e.routeCount+s]=Math.hypot(t,a)*this.DISTANCE_TO_COST}}return{portHCostToEndOfRoute:i,portEndpointNetIds:r}}_setup(){if(this.problemSetup,this.STATIC_REACHABILITY_PRECHECK){const t=IW({topology:this.topology,problem:this.problem,problemSetup:this.problemSetup,portAssignment:this.state.portAssignment,routeIds:this.state.unroutedRoutes,maxPrecheckHops:Math.max(0,this.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),getStartingNextRegionId:(t,e)=\u003ethis.getStartingNextRegionId(t,e),getRouteSummary:t=\u003ethis.getRouteSummary(t)});t.length\u003e0\u0026\u0026(this.failed=!0,this.error=(t=\u003e{const e=t.slice(0,5).map(t=\u003e{const e=t.pointIds.length\u003e=2?`${t.pointIds[0]}-\u003e${t.pointIds[1]}`:`${t.startPortId}-\u003e${t.endPortId}`;return`${t.connectionId} (${e})`}).join(\", \"),n=t.length-5;return[\"Static reachability precheck failed:\",`${t.length} route(s) have no legal path under the current reservation and start-region rules`,n\u003e0?`${e}, +${n} more`:e].join(\" \")})(t),this.stats={...this.stats,staticallyUnroutableRouteCount:t.length})}}_step(){const{problem:t,topology:e,state:n}=this;if(void 0===n.currentRouteId){if(0===n.unroutedRoutes.length)return void this.onAllRoutesRouted();n.currentRouteId=n.unroutedRoutes.shift(),n.currentRouteNetId=t.routeNet[n.currentRouteId],this.routeAttemptCountByRouteId[n.currentRouteId]+=1,this.resetCandidateBestCosts();const e=t.routeStartPort[n.currentRouteId];n.candidateQueue.clear();const o=this.getStartingNextRegionId(n.currentRouteId,e);if(void 0===o)return this.failed=!0,void(this.error=`Start port ${e} has no incident regions`);this.setCandidateBestCost(this.getHopId(e,o),0),n.candidateQueue.queue({nextRegionId:o,portId:e,f:0,g:0,h:0}),n.goalPortId=t.routeEndPort[n.currentRouteId]}const o=n.candidateQueue.dequeue();if(!o)return void this.onOutOfCandidates();const i=this.getHopId(o.portId,o.nextRegionId);if(o.g\u003ethis.getCandidateBestCost(i))return;if(this.isRegionReservedForDifferentNet(o.nextRegionId))return;const r=e.regionIncidentPorts[o.nextRegionId];for(const i of r){const r=n.portAssignment[i];if(this.isPortReservedForDifferentNet(i))continue;if(i===n.goalPortId){if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;return void this.onPathFound(o)}if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;if(i===o.portId)continue;if(0===t.portSectionMask[i])continue;const s=this.computeG(o,i);if(!Number.isFinite(s))continue;const a=this.computeH(i),c=e.incidentPortRegion[i][0]===o.nextRegionId?e.incidentPortRegion[i][1]:e.incidentPortRegion[i][0];if(void 0===c||this.isRegionReservedForDifferentNet(c))continue;const l={prevRegionId:o.nextRegionId,nextRegionId:c,portId:i,g:s,h:a,f:s+a,prevCandidate:o};if(i===n.goalPortId)return void this.onPathFound(l);const d=this.getHopId(i,c);s\u003e=this.getCandidateBestCost(d)||(this.setCandidateBestCost(d,s),n.candidateQueue.queue(l))}}resetCandidateBestCosts(){const{state:t}=this;if(4294967295===t.candidateBestCostGeneration)return t.candidateBestCostGenerationByHopId.fill(0),void(t.candidateBestCostGeneration=1);t.candidateBestCostGeneration+=1}getCandidateBestCost(t){const{state:e}=this;return e.candidateBestCostGenerationByHopId[t]===e.candidateBestCostGeneration?e.candidateBestCostByHopId[t]:Number.POSITIVE_INFINITY}setCandidateBestCost(t,e){const{state:n}=this;n.candidateBestCostGenerationByHopId[t]=n.candidateBestCostGeneration,n.candidateBestCostByHopId[t]=e}getHopId(t,e){return t*this.topology.regionCount+e}getStartingNextRegionId(t,e){const n=this.topology.incidentPortRegion[e]??[],o=this.problem.routeNet[t];return n.find(t=\u003e-1===this.problem.regionNetId[t])??n.find(t=\u003ethis.problem.regionNetId[t]===o)??n[0]}isPortReservedForDifferentNet(t){const e=this.problemSetup.portEndpointNetIds[t];if(!e)return!1;for(const t of e)if(t!==this.state.currentRouteNetId)return!0;return!1}isRegionReservedForDifferentNet(t){const e=this.problem.regionNetId[t];return-1!==e\u0026\u0026e!==this.state.currentRouteNetId}isKnownSingleLayerRegion(t){const e=this.topology.regionAvailableZMask?.[t]??0;return pW(e)}computeRegionCostForRegion(t,e,n,o,i){return((t,e,n,o,i,r,s=0)=\u003emW(t*e,n,o,i,r,s))(this.topology.regionWidth[t],this.topology.regionHeight[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0)}populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.segmentGeometryScratch,r=o.incidentPortRegion[e],s=o.incidentPortRegion[n],a=r[0]===t||r[1]!==t?o.portAngleForRegion1[e]:o.portAngleForRegion2?.[e]??o.portAngleForRegion1[e],c=s[0]===t||s[1]!==t?o.portAngleForRegion1[n]:o.portAngleForRegion2?.[n]??o.portAngleForRegion1[n],l=o.portZ[e],d=o.portZ[n];return i.lesserAngle=a\u003cc?a:c,i.greaterAngle=a\u003cc?c:a,i.layerMask=1\u003c\u003cl|1\u003c\u003cd,i.entryExitLayerChanges=l!==d?1:0,i}appendSegmentToRegionCache(t,e,n){const{topology:o,state:i}=this,r=i.regionIntersectionCaches[t],s=this.populateSegmentGeometryScratch(t,e,n),[a,c,l]=gW(r,i.currentRouteNetId,s.lesserAngle,s.greaterAngle,s.layerMask,s.entryExitLayerChanges),d=r.netIds.length+1,h=new Int32Array(d);h.set(r.netIds),h[d-1]=i.currentRouteNetId;const u=new Int32Array(d);u.set(r.lesserAngles),u[d-1]=s.lesserAngle;const p=new Int32Array(d);p.set(r.greaterAngles),p[d-1]=s.greaterAngle;const m=new Int32Array(d);m.set(r.layerMasks),m[d-1]=s.layerMask;const g=r.existingSameLayerIntersections+a,f=r.existingCrossingLayerIntersections+c,y=r.existingEntryExitLayerChanges+l,_=u.length;i.regionIntersectionCaches[t]={netIds:h,lesserAngles:u,greaterAngles:p,layerMasks:m,existingSameLayerIntersections:g,existingCrossingLayerIntersections:f,existingEntryExitLayerChanges:y,existingSegmentCount:_,existingRegionCost:this.computeRegionCostForRegion(t,g,f,y,_)}}getSolvedPathSegments(t){const{state:e}=this,n=[];let o=t;for(;o;)n.unshift(o),o=o.prevCandidate;const i=[];for(let t=1;t\u003cn.length;t++)i.push({regionId:n[t-1].nextRegionId,fromPortId:n[t-1].portId,toPortId:n[t].portId});const r=n[n.length-1];return r\u0026\u0026r.portId!==e.goalPortId\u0026\u0026i.push({regionId:r.nextRegionId,fromPortId:r.portId,toPortId:e.goalPortId}),i}resetRoutingStateForRerip(){const{topology:t,problem:e,state:n}=this;n.portAssignment.fill(-1),n.regionSegments=Array.from({length:t.regionCount},()=\u003e[]),n.regionIntersectionCaches=Array.from({length:t.regionCount},()=\u003eiH()),n.currentRouteNetId=void 0,n.currentRouteId=void 0,n.unroutedRoutes=yW(CW(e.routeCount),n.ripCount),n.candidateQueue.clear(),this.resetCandidateBestCosts(),n.goalPortId=-1}getMaxRegionCost(){const{topology:t,state:e}=this;let n=0;for(let o=0;o\u003ct.regionCount;o++){const t=e.regionIntersectionCaches[o]?.existingRegionCost??0;n=Math.max(n,t)}return n}getRouteMetadata(t){return this.problem.routeMetadata?.[t]}getRouteConnectionId(t){const e=this.getRouteMetadata(t)?.connectionId;return\"string\"==typeof e?e:`route-${t}`}getRouteSummary(t){return(({problem:t,routeId:e,getRouteMetadata:n,getRouteConnectionId:o})=\u003e{const i=n?.(e)??_W(t,e);return{routeId:e,connectionId:o?.(e)??xW(t,e),startPortId:t.routeStartPort[e],endPortId:t.routeEndPort[e],startRegionId:\"string\"==typeof i?.startRegionId?i.startRegionId:void 0,endRegionId:\"string\"==typeof i?.endRegionId?i.endRegionId:void 0,pointIds:bW(i)}})({problem:this.problem,routeId:t,getRouteMetadata:t=\u003ethis.getRouteMetadata(t),getRouteConnectionId:t=\u003ethis.getRouteConnectionId(t)})}getAdditionalRegionLabel(t){}getNeverSuccessfullyRoutedRoutes(){const t=[];for(let e=0;e\u003cthis.problem.routeCount;e++){const n=this.routeAttemptCountByRouteId[e];0===n||this.routeSuccessCountByRouteId[e]\u003e0||t.push({...this.getRouteSummary(e),attempts:n})}return t}logNeverSuccessfullyRoutedRoutes(){if(!this.VERBOSE||this.hasLoggedNeverSuccessfullyRoutedRoutes)return;const t=this.getNeverSuccessfullyRoutedRoutes();if(this.hasLoggedNeverSuccessfullyRoutedRoutes=!0,0!==t.length){console.log([\"[TinyHyperGraphSolver:never-routed-summary]\",`count=${t.length}`].join(\" \"));for(const e of t){const t=e.pointIds.length\u003e=2?`${e.pointIds[0]}-\u003e${e.pointIds[1]}`:\"unknown\";console.log([\"[TinyHyperGraphSolver:never-routed]\",`routeId=${e.routeId}`,`connectionId=${e.connectionId}`,`attempts=${e.attempts}`,`pointPath=${t}`,`startRegionId=${e.startRegionId??\"unknown\"}`,`endRegionId=${e.endRegionId??\"unknown\"}`].join(\" \"))}}}logRipEvent(t,e,n={}){this.VERBOSE\u0026\u0026console.log([\"[TinyHyperGraphSolver:rip]\",`ripCount=${this.state.ripCount}`,`maxRegionCostBeforeRip=${e.toFixed(3)}`,`reason=${t}`,...Object.entries(n).map(([t,e])=\u003e`${t}=${\"number\"==typeof e?Number.isInteger(e)?String(e):e.toFixed(3):e}`)].join(\" \"))}onAllRoutesRouted(){const{topology:t,state:e}=this,n=this.RIP_THRESHOLD_RAMP_ATTEMPTS\u003c=0?1:Math.min(1,e.ripCount/this.RIP_THRESHOLD_RAMP_ATTEMPTS),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(t.regionCount);let s=0;for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;r[n]=t,s=Math.max(s,t),t\u003eo\u0026\u0026i.push(n)}if(this.stats={...this.stats,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:s,ripCount:e.ripCount},0===i.length||e.ripCount\u003e=this.RIP_THRESHOLD_RAMP_ATTEMPTS)this.solved=!0;else{for(let n=0;n\u003ct.regionCount;n++)e.regionCongestionCost[n]+=r[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCostBeforeRip:s,reripRegionCount:i.length},this.logRipEvent(\"hot_regions\",s,{hotRegionCount:i.length,currentRipThreshold:o})}}onOutOfCandidates(){const{topology:t,state:e}=this,n=e.currentRouteId,o=this.getMaxRegionCost();for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;e.regionCongestionCost[n]+=t*this.RIP_CONGESTION_REGION_COST_FACTOR}e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCost:o,maxRegionCostBeforeRip:o,reripReason:\"out_of_candidates\"},this.logRipEvent(\"out_of_candidates\",o,{...void 0===n?{}:{routeId:n,connectionId:this.getRouteConnectionId(n)}})}onPathFound(t){const{state:e}=this,n=e.currentRouteId;if(void 0===n)return;this.routeSuccessCountByRouteId[n]+=1;const o=this.getSolvedPathSegments(t);for(const{regionId:t,fromPortId:i,toPortId:r}of o)e.regionSegments[t].push([n,i,r]),e.portAssignment[i]=e.currentRouteNetId,e.portAssignment[r]=e.currentRouteNetId,this.appendSegmentToRegionCache(t,i,r);e.candidateQueue.clear(),e.currentRouteNetId=void 0,e.currentRouteId=void 0}computeG(t,e){const{topology:n,state:o}=this,i=t.nextRegionId,r=o.regionIntersectionCaches[i],s=this.populateSegmentGeometryScratch(i,t.portId,e),[a,c,l]=gW(r,o.currentRouteNetId,s.lesserAngle,s.greaterAngle,s.layerMask,s.entryExitLayerChanges);if(a\u003e0\u0026\u0026this.isKnownSingleLayerRegion(i))return Number.POSITIVE_INFINITY;const d=this.computeRegionCostForRegion(i,r.existingSameLayerIntersections+a,r.existingCrossingLayerIntersections+c,r.existingEntryExitLayerChanges+l,r.existingSegmentCount+1)-r.existingRegionCost;return t.g+d+o.regionCongestionCost[i]}tryFinalAcceptance(){const t=this.getNeverSuccessfullyRoutedRoutes();this.stats={...this.stats,neverSuccessfullyRoutedRouteCount:t.length},this.logNeverSuccessfullyRoutedRoutes()}computeH(t){return this.problemSetup.portHCostToEndOfRoute[t*this.problem.routeCount+this.state.currentRouteId]}visualize(){return oH(this)}getOutput(){return uW(this)}},aH=t=\u003e{const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;return Number.isFinite(e)?e:void 0},cH=t=\u003e{const e=new Set;for(const n of t.connections??[])e.add(n.startRegionId),e.add(n.endRegionId);const n=new Set(t.regions.filter(t=\u003e(t=\u003e{if(!0!==t.d?._containsObstacle)return!1;if(!0!==t.d?._containsTarget)return!0;const e=aH(t);return void 0===e||-1===e})(t)\u0026\u0026!e.has(t.regionId)).map(t=\u003et.regionId));if(0===n.size)return t;const o=t.ports.filter(t=\u003e!n.has(t.region1Id)\u0026\u0026!n.has(t.region2Id)),i=(t.connections??[]).find(t=\u003en.has(t.startRegionId)||n.has(t.endRegionId));if(i)throw new Error(`Connection \"${i.connectionId}\" references full-obstacle region`);return{...t,regions:t.regions.filter(t=\u003e!n.has(t.regionId)),ports:o}},lH=t=\u003e{const e=t.d?.bounds;if(e)return e;const n=t.d?.center,o=t.d?.width,i=t.d?.height;return n\u0026\u0026\"number\"==typeof n.x\u0026\u0026\"number\"==typeof n.y\u0026\u0026\"number\"==typeof o\u0026\u0026\"number\"==typeof i?{minX:n.x-o/2,maxX:n.x+o/2,minY:n.y-i/2,maxY:n.y+i/2}:{minX:0,maxX:0,minY:0,maxY:0}},dH=t=\u003e{const e=Number(t.d?.z??0);return Number.isFinite(e)?e:0},hH=t=\u003e.005*dH(t),uH=t=\u003eNumber(t.d?.x??0)+hH(t),pH=t=\u003eNumber(t.d?.y??0)+hH(t),mH=(t,e)=\u003e{if(!e)return 0;const n=lH(e),o=uH(t),i=pH(t),r=n.minX\u003c=o\u0026\u0026o\u003c=n.maxX,s=n.minY\u003c=i\u0026\u0026i\u003c=n.maxY;if(s\u0026\u0026o\u003e=n.maxX){const t=Math.max(n.maxY-n.minY,1e-9),e=(i-n.minY)/t;return Math.round(9e3*e)}if(r\u0026\u0026i\u003e=n.maxY){const t=Math.max(n.maxX-n.minX,1e-9),e=(n.maxX-o)/t;return 9e3+Math.round(9e3*e)}if(s\u0026\u0026o\u003c=n.minX){const t=Math.max(n.maxY-n.minY,1e-9),e=(n.maxY-i)/t;return 18e3+Math.round(9e3*e)}if(r\u0026\u0026i\u003c=n.minY){const t=Math.max(n.maxX-n.minX,1e-9),e=(o-n.minX)/t;return 27e3+Math.round(9e3*e)}const a=Math.abs(o-n.minX),c=Math.abs(o-n.maxX),l=Math.abs(i-n.minY),d=Math.abs(i-n.maxY),h=Math.min(a,c,l,d),u=Math.max(n.maxX-n.minX,1e-9),p=Math.max(n.maxY-n.minY,1e-9);if(h===c){const t=(i-n.minY)/p;return Math.round(9e3*t)}if(h===d){const t=(n.maxX-o)/u;return 9e3+Math.round(9e3*t)}if(h===a){const t=(n.maxY-i)/p;return 18e3+Math.round(9e3*t)}const m=(o-n.minX)/u;return 27e3+Math.round(9e3*m)},gH=(t,e)=\u003e{if(!t)return;return[...t.pointIds].sort((t,n)=\u003e{const o=e.get(t),i=e.get(n),r=Number(o?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY),s=Number(i?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY);if(r!==s)return r-s;const a=Number(o?.d?.z??0),c=Number(i?.d?.z??0);return a!==c?a-c:t.localeCompare(n)})[0]},fH=t=\u003e{const e=cH(t),n=new Map,o=new Map,i=new Map,r=new Map((e.solvedRoutes??[]).map(t=\u003e[t.connection.connectionId,t]));e.regions.forEach((t,e)=\u003e{n.set(t.regionId,e)}),e.ports.forEach((t,e)=\u003e{o.set(t.portId,e),i.set(t.portId,t)});const s=e.regions.length,a=e.ports.length,c=e.regions.map(t=\u003et.pointIds.map(t=\u003eo.get(t)).filter(t=\u003evoid 0!==t)),l=Array.from({length:a},()=\u003e[]),d=new Float64Array(s),h=new Float64Array(s),u=new Float64Array(s),p=new Float64Array(s),m=new Int32Array(s),g=new Int32Array(s).fill(-1),f=new Int8Array(s);e.regions.forEach((t,e)=\u003e{const n=(t=\u003e{const e=lH(t),n=\"number\"==typeof t.d?.width?t.d.width:e.maxX-e.minX,o=\"number\"==typeof t.d?.height?t.d.height:e.maxY-e.minY;return{centerX:\"number\"==typeof t.d?.center?.x?t.d.center.x:(e.minX+e.maxX)/2,centerY:\"number\"==typeof t.d?.center?.y?t.d.center.y:(e.minY+e.maxY)/2,width:n,height:o}})(t);d[e]=n.width,h[e]=n.height,u[e]=n.centerX,p[e]=n.centerY,m[e]=(t=\u003e{const e=t.d?.availableZ;if(!Array.isArray(e))return 0;let n=0;for(const t of e)!Number.isInteger(t)||t\u003c0||t\u003e=31||(n|=1\u003c\u003ct);return n})(t);const o=aH(t);void 0!==o\u0026\u0026(g[e]=o,f[e]=1)});const y=new Int32Array(a),_=new Int32Array(a),b=new Float64Array(a),x=new Float64Array(a),v=new Int32Array(a);e.ports.forEach((t,o)=\u003e{const i=n.get(t.region1Id),r=n.get(t.region2Id);if(void 0===i||void 0===r)throw new Error(`Port \"${t.portId}\" references missing regions \"${t.region1Id}\" or \"${t.region2Id}\"`);l[o]=[i,r],b[o]=uH(t),x[o]=pH(t),v[o]=dH(t),y[o]=mH(t,e.regions[i]),_[o]=mH(t,e.regions[r])});const S=e.regions.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedRegionId\",{value:t.regionId,enumerable:!1,configurable:!0,writable:!0}),n})(t,(t=\u003enW(oW(m[t]))??nW((c[t]??[]).map(t=\u003ev[t]))??\"z0\")(e))),I=e.ports.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedPortId\",{value:t.portId,enumerable:!1,configurable:!0,writable:!0}),n})(t,nW([v[e]])??\"z0\")),C=e.connections??[],P=new Map;let M=0;const N=t=\u003e{const e=t.mutuallyConnectedNetworkId??t.connectionId;let n=P.get(e);return void 0===n\u0026\u0026(n=M++,P.set(e,n)),n},w=Array.from({length:s},()=\u003enew Set),T=(t,e)=\u003e{const o=n.get(t);if(void 0===o)throw new Error(`Connection references missing region \"${t}\"`);w[o].add(e)};C.forEach(t=\u003e{const e=N(t);T(t.startRegionId,e),T(t.endRegionId,e)}),w.forEach((t,e)=\u003e{1!==f[e]\u0026\u00261===t.size\u0026\u0026(g[e]=[...t][0])});const R=C.map(t=\u003e{const n=r.get(t.connectionId),o=((t,e)=\u003et.ports.filter(t=\u003et.region1Id===e.startRegionId\u0026\u0026t.region2Id===e.endRegionId||t.region2Id===e.startRegionId\u0026\u0026t.region1Id===e.endRegionId).map(t=\u003et.portId))(e,t);return{connection:t,solvedRoute:n,sharedPortIds:o}}).filter(({solvedRoute:t,sharedPortIds:e})=\u003e0===e.length||(t?.path.length??0)\u003e1),E=R.length,A=new Int8Array(a).fill(1),O=new Int32Array(E),k=new Int32Array(E),L=new Int32Array(E);R.forEach(({connection:t,solvedRoute:n},r)=\u003e{const s=gH(e.regions.find(e=\u003ee.regionId===t.startRegionId),i),a=gH(e.regions.find(e=\u003ee.regionId===t.endRegionId),i),c=n?.path[0]?.portId??s,l=n?.path[n.path.length-1]?.portId??a,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)throw new Error(`Connection \"${t.connectionId}\" could not be mapped to route endpoints`);O[r]=d,k[r]=h,L[r]=N(t)});const D={portCount:a,regionCount:s,regionIncidentPorts:c,incidentPortRegion:l,regionWidth:d,regionHeight:h,regionCenterX:u,regionCenterY:p,regionAvailableZMask:m,regionMetadata:S,portAngleForRegion1:y,portAngleForRegion2:_,portX:b,portY:x,portZ:v,portMetadata:I},z={routeCount:E,portSectionMask:A,routeMetadata:R.map(({connection:t})=\u003et),routeStartPort:O,routeEndPort:k,routeNet:L,regionNetId:g},F=[],B=[];for(const{solvedRoute:t}of R){if(!t){F.push([]),B.push([]);continue}const e=[],i=[];for(let r=1;r\u003ct.path.length;r++){const s=t.path[r-1],a=t.path[r],c=s?.portId,l=a?.portId,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)continue;const u=\"string\"==typeof s?.nextRegionId?s.nextRegionId:\"string\"==typeof a?.lastRegionId?a.lastRegionId:void 0;e.push([d,h]),i.push(void 0!==u?n.get(u):void 0)}F.push(e),B.push(i)}return{topology:D,problem:z,solution:{solvedRoutePathSegments:F,solvedRoutePathRegionIds:B}}},yH=(Number.POSITIVE_INFINITY,1e-9),_H=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,bH=(t,e=0)=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)?t:e,xH=t=\u003e{const e=(t=\u003e{const e=Math.min(t.minX,t.maxX),n=Math.max(t.minX,t.maxX),o=Math.min(t.minY,t.maxY),i=Math.max(t.minY,t.maxY);return{minX:e,maxX:n\u003ee?n:e+yH,minY:o,maxY:i\u003eo?i:o+yH}})(t);return[{x:e.maxX,y:e.minY},{x:e.maxX,y:e.maxY},{x:e.minX,y:e.maxY},{x:e.minX,y:e.minY}]},vH=(t,e)=\u003e{const n=t.filter(t=\u003eNumber.isFinite(t.x)\u0026\u0026Number.isFinite(t.y)),o=n.length\u003e=3?n:xH(e),i=(t=\u003e{let e=0;for(let n=0;n\u003ct.length;n++){const o=t[n],i=t[(n+1)%t.length];e+=o.x*i.y-o.y*i.x}return e})(o);if(Math.abs(i)\u003c=Number.EPSILON)return xH(e);return(t=\u003e{if(t.length\u003c3)throw new Error(\"Convex polygon requires at least three points\");return t})(i\u003c0?[...o].reverse():[...o])},SH=t=\u003e{const e=(t=\u003e{const e=t.d,n=e?.bounds;if(n\u0026\u0026\"number\"==typeof n.minX\u0026\u0026\"number\"==typeof n.maxX\u0026\u0026\"number\"==typeof n.minY\u0026\u0026\"number\"==typeof n.maxY)return{minX:n.minX,maxX:n.maxX,minY:n.minY,maxY:n.maxY};const o=e?.center,i=bH(e?.width,0),r=bH(e?.height,0);return o\u0026\u0026\"number\"==typeof o.x\u0026\u0026\"number\"==typeof o.y?{minX:o.x-i/2,maxX:o.x+i/2,minY:o.y-r/2,maxY:o.y+r/2}:{minX:0,maxX:yH,minY:0,maxY:yH}})(t);return vH((t=\u003e{const e=t.d,n=e?.polygon??e?.points??e?.vertices;if(!Array.isArray(n))return;const o=n.map(t=\u003e{if(!_H(t))return;const e=t.x,n=t.y;return\"number\"==typeof e\u0026\u0026\"number\"==typeof n?{x:e,y:n}:void 0}).filter(t=\u003evoid 0!==t);if(o.length\u003e1){const t=o[0],e=o[o.length-1];t.x===e.x\u0026\u0026t.y===e.y\u0026\u0026o.pop()}return o.length\u003e=3?o:void 0})(t)??xH(e),e)},IH=t=\u003e{let e=0,n=0,o=0,i=0,r=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,a=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY;for(let l=0;l\u003ct.length;l++){const d=t[l],h=t[(l+1)%t.length],u=d.x*h.y-h.x*d.y;e+=u,n+=(d.x+h.x)*u,o+=(d.y+h.y)*u,i+=Math.hypot(h.x-d.x,h.y-d.y),r=Math.min(r,d.x),s=Math.max(s,d.x),a=Math.min(a,d.y),c=Math.max(c,d.y)}const l=Math.abs(e)/2,d=Math.abs(e)\u003eNumber.EPSILON?3*e:Number.NaN,h=t.reduce((e,n)=\u003e({x:e.x+n.x/t.length,y:e.y+n.y/t.length}),{x:0,y:0});return{area:l,perimeter:i,centerX:Number.isFinite(d)?n/d:h.x,centerY:Number.isFinite(d)?o/d:h.y,bounds:{minX:r,maxX:s,minY:a,maxY:c}}},CH=(t,e,n,o)=\u003e{if(n\u003c=0)return{boundaryPosition:0,edgeIndex:0,edgeT:0};let i=Number.POSITIVE_INFINITY,r=0,s=0,a=0,c=0;for(let n=0;n\u003ce.length;n++){const o=e[n],l=e[(n+1)%e.length],d=l.x-o.x,h=l.y-o.y,u=d*d+h*h,p=Math.sqrt(u),m=u\u003c=Number.EPSILON?0:((t.x-o.x)*d+(t.y-o.y)*h)/u,g=Math.min(1,Math.max(0,m)),f=o.x+d*g,y=o.y+h*g,_=t.x-f,b=t.y-y,x=_*_+b*b;x\u003ci\u0026\u0026(i=x,r=n,s=g,a=c+p*g),c+=p}return{boundaryPosition:Math.round(a/n*o)%o,edgeIndex:r,edgeT:s}},PH=(t,e)=\u003e{const n=t.regionMetadata?.[e];return _H(n)\u0026\u0026\"string\"==typeof n.serializedRegionId?n.serializedRegionId:`region-${e}`},MH=(t,e)=\u003e{const n=t.portMetadata?.[e];return _H(n)\u0026\u0026\"string\"==typeof n.serializedPortId?n.serializedPortId:`port-${e}`},NH=(t,e,n,o)=\u003e{const i={..._H(t)?{...t}:void 0===t?{}:{value:t},polygon:n,sourceBounds:o};return Object.defineProperty(i,\"serializedRegionId\",{value:e,enumerable:!1,configurable:!0,writable:!0}),i},wH=(t,e)=\u003e{const n=new Map,o=new Map,i=new Map,r=new Map;for(let e=0;e\u003ct.regionCount;e++)n.set(PH(t,e),e);for(let e=0;e\u003ct.portCount;e++)o.set(MH(t,e),e);for(let t=0;t\u003ce.routeCount;t++){const n=e.routeMetadata?.[t];if(!_H(n))continue;\"string\"==typeof n.connectionId\u0026\u0026i.set(n.connectionId,t);const o=\"string\"==typeof n.mutuallyConnectedNetworkId?n.mutuallyConnectedNetworkId:\"string\"==typeof n.connectionId?n.connectionId:void 0;void 0!==o\u0026\u0026r.set(o,e.routeNet[t])}return{serializedRegionIdToRegionId:n,serializedPortIdToPortId:o,connectionIdToRouteId:i,netIdToNetIndex:r}},TH=(t,e,n)=\u003e{const o=t.incidentPortRegion[e];return o[0]===n||o[1]!==n?t.portBoundaryPositionForRegion1[e]:t.portBoundaryPositionForRegion2[e]},RH=class extends sH{constructor(t,e,n){super(t,e,n),this.topology=t,this.problem=e}topology;problem;polySegmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.polySegmentGeometryScratch,r=TH(o,e,t),s=TH(o,n,t),a=o.portZ[e],c=o.portZ[n];return i.lesserAngle=r\u003cs?r:s,i.greaterAngle=r\u003cs?s:r,i.layerMask=1\u003c\u003ca|1\u003c\u003cc,i.entryExitLayerChanges=a!==c?1:0,i}computeRegionCostForRegion(t,e,n,o,i){return mW(this.topology.regionArea[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0)}visualize(){return $H(this)}},EH=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),AH=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},OH=(t,e,n=.85)=\u003e{const o=`${t.problem.routeNet[e]}:${AH(t,e)}`;let i=0;for(let t=0;t\u003co.length;t++)i=17777*o.charCodeAt(t)+((i\u003c\u003c5)-i);return`hsla(${Math.abs(i)%360}, 70%, 45%, ${n})`},kH=(t,e)=\u003e{const n=t.regionVertexStart[e],o=t.regionVertexCount[e],i=[];for(let e=0;e\u003co;e++){const o=n+e;i.push({x:t.regionVertexX[o],y:t.regionVertexY[o]})}return i},LH=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e]?.existingRegionCost??0,o=Math.min(1,Math.max(0,Math.pow(n,.8))),i=Math.round(245-105*o);return`rgba(245, ${Math.round(248-168*o)}, ${i}, ${.18+.48*o})`},DH=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e],o=PH(t.topology,e),i=t.problem.regionNetId[e];return EH(`region: ${o}`,`net: ${-1===i?\"free\":i}`,`area: ${t.topology.regionArea[e].toFixed(3)}`,`cost: ${(n?.existingRegionCost??0).toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},zH=(t,e)=\u003enW(oW(t.topology.regionAvailableZMask?.[e]??0))??nW((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))??\"z0\",FH=(t,e)=\u003e({x:t.topology.portX[e],y:t.topology.portY[e]}),BH=(t,e)=\u003enW([t.topology.portZ[e]])??\"z0\",jH=(t,e)=\u003e{const[n,o]=t.topology.incidentPortRegion[e]??[];return EH(`port: ${MH(t.topology,e)}`,`connects: ${n??\"?\"} \u003c-\u003e ${o??\"?\"}`,`z: ${t.topology.portZ[e]}`)},$H=t=\u003e{const e={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:\"Poly HyperGraph\",coordinateSystem:\"cartesian\"};for(let n=0;n\u003ct.topology.regionCount;n++)e.polygons.push({points:kH(t.topology,n),fill:LH(t,n),stroke:\"rgba(80, 80, 120, 0.55)\",layer:zH(t,n),label:DH(t,n)});for(let n=0;n\u003ct.topology.portCount;n++)e.circles.push({center:FH(t,n),radius:.05,fill:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.55)\":\"rgba(80, 80, 80, 0.45)\",layer:BH(t,n),label:jH(t,n)});((t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=AH(t,n),s=OH(t,n);e.points.push({...FH(t,o),color:s,layer:BH(t,o),label:EH(`route: ${r}`,\"endpoint: start\",jH(t,o))}),e.points.push({...FH(t,i),color:s,layer:BH(t,i),label:EH(`route: ${r}`,\"endpoint: end\",jH(t,i))})}})(t,e),((t,e)=\u003e{for(let n=0;n\u003ct.state.regionSegments.length;n++)for(const[o,i,r]of t.state.regionSegments[n]??[])e.lines.push({points:[FH(t,i),FH(t,r)],strokeColor:OH(t,o),layer:nW([t.topology.portZ[i],t.topology.portZ[r]])??\"z0\",label:EH(`route: ${AH(t,o)}`,`region: ${PH(t.topology,n)}`)})})(t,e),((t,e)=\u003e{if(t.solved)return;const n=t.state.candidateQueue.toArray().sort((t,e)=\u003et.f-e.f).slice(0,10);for(let o=0;o\u003cn.length;o++){const i=n[o];e.points.push({...FH(t,i.portId),color:0===o?\"green\":\"rgba(128, 128, 128, 0.4)\",layer:BH(t,i.portId),label:EH(jH(t,i.portId),`g: ${i.g.toFixed(2)}`,`h: ${i.h.toFixed(2)}`,`f: ${i.f.toFixed(2)}`)})}const o=n[0];if(!o)return;const i=[];let r=o;for(;r;)i.unshift(FH(t,r.portId)),r=r.prevCandidate;if(i.length\u003c=1)return;const s=t.state.currentRouteId;e.lines.push({points:i,strokeColor:void 0!==s?OH(t,s,.95):\"rgba(0, 160, 120, 0.95)\",strokeDash:\"4 3\",layer:BH(t,o.portId),label:EH(void 0!==s?`route: ${AH(t,s)}`:void 0,\"active candidate path\",`candidate port: ${MH(t.topology,o.portId)}`)})})(t,e);const n=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1);return e.title=[\"Poly HyperGraph\",`iter=${t.iterations}`,`pending=${n}`,t.failed?\"failed\":t.solved?\"solved\":\"running\"].join(\" | \"),e},YH=(new Int32Array(0),t=\u003e(t.ccwRotationDegrees??0)*Math.PI/180),XH=(t,e=8)=\u003e{const n=t.width/2,o=t.height/2,i=YH(t),r=Math.cos(i),s=Math.sin(i);return Array.from({length:e},(i,a)=\u003e{const c=2*Math.PI*a/e,l=n*Math.cos(c),d=o*Math.sin(c);return{x:t.center.x+l*r-d*s,y:t.center.y+l*s+d*r}})},VH=t=\u003e(t.obstacles??[]).filter(t=\u003e\"oval\"===t.type).map(t=\u003e({points:XH(t),layers:t.layers,zLayers:t.__zLayers,isCopperPour:t.isCopperPour})),WH=(t,e)=\u003e(t.obstacles??[]).flatMap((n,o)=\u003e{if(!Array.isArray(n.connectedTo)||0===n.connectedTo.length)return[];const i=oV(sV(n,t.layerCount),t.layerCount);if(0===i.length)return[];let r;const s=n.type;if(\"rect\"===s)r=((t,e=0)=\u003e{const n=t.width/2+e,o=t.height/2+e,i=YH(t),r=Math.cos(i),s=Math.sin(i);return[{localX:-n,localY:-o},{localX:n,localY:-o},{localX:n,localY:o},{localX:-n,localY:o}].map(({localX:e,localY:n})=\u003e({x:t.center.x+e*r-n*s,y:t.center.y+e*s+n*r}))})(n,e);else{if(\"oval\"!==s)return[];r=EV({polygon:{points:XH(n),layers:n.layers,zLayers:n.__zLayers,isCopperPour:n.isCopperPour},clearance:e,verticesOnly:!0})}return[{regionId:`connected-obstacle-${o}`,polygon:r,availableZ:i,connectedTo:n.connectedTo,d:{obstacleIndex:o,obstacleType:s,connectedTo:n.connectedTo}}]}),HH=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},GH=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},UH=(t,e)=\u003e{const n=HH(t).serializedRegionId;return\"string\"==typeof n?n:`region-${e}`},ZH=(t,e)=\u003e{const n=GH(t);return\"string\"==typeof n.serializedPortId?n.serializedPortId:\"string\"==typeof n.portId?n.portId:`poly-port-${e}`},qH=t=\u003e{const e=GH(t);return{prevPortPointId:\"string\"==typeof e.prevPortPointId?e.prevPortPointId:void 0,nextPortPointId:\"string\"==typeof e.nextPortPointId?e.nextPortPointId:void 0}},JH=t=\u003e{const e=HH(t).polygon;if(Array.isArray(e)\u0026\u0026!(e.length\u003c3))return e.every(t=\u003e\"object\"==typeof t\u0026\u0026null!==t\u0026\u0026\"number\"==typeof t.x\u0026\u0026\"number\"==typeof t.y)?e:void 0},KH=class extends si{constructor(t){super(),this.params=t,this.effort=t.effort??1,this.clearance=t.srj.defaultObstacleMargin??t.srj.minTraceWidth;const e=e=\u003e{return eW({bounds:t.srj.bounds,rects:(n=t.srj,(n.obstacles??[]).filter(t=\u003e\"rect\"===t.type).map(t=\u003e({center:t.center,width:t.width,height:t.height,ccwRotation:YH(t),layers:t.layers,zLayers:t.__zLayers,isCopperPour:t.isCopperPour}))),polygons:VH(t.srj),clearance:this.clearance,concavityTolerance:t.concavityTolerance??0,layerCount:t.srj.layerCount,layerMergeMode:t.layerMergeMode??\"same\",useConstrainedDelaunay:e,usePolyanyaMerge:t.usePolyanyaMerge??!1,viaSegments:t.viaSegments??8});var n},n=t.useConstrainedDelaunay??!0;try{this.convexRegions=e(n)}catch(t){if(!n)throw t;this.usedUnconstrainedDelaunayFallback=!0,this.convexRegions=e(!1)}var o;this.serializedGraph=RV({regions:this.convexRegions.regions,availableZ:this.convexRegions.availableZ,layerCount:t.srj.layerCount,connections:(o=t.srj,o.connections.flatMap(t=\u003e{const e=t.pointsToConnect??[];if(e.length\u003c2)return[];const n=e[0];return e.slice(1).map((e,o)=\u003e{const i=((t,e,n,o)=\u003e{const i=2===t.pointsToConnect.length?t.name:`${t.name}::${o}`;return{...t,name:i,__rootConnectionNames:t.__rootConnectionNames??[t.name],pointsToConnect:[e,n]}})(t,n,e,o);return{connectionId:i.name,mutuallyConnectedNetworkId:i.__rootConnectionNames?.[0]??i.name,start:n,end:e,simpleRouteConnection:i}})})),obstacleRegions:WH(t.srj,this.clearance),portSpacing:t.portSpacing??lV,portMarginFromSegmentEndpoint:t.portMarginFromSegmentEndpoint??dV}),this.loaded=((t,e={})=\u003e{const n=e.boundaryCoordinateScale??36e3,o=fH(t),{topology:i,problem:r,solution:s}=o,a=new Map(t.regions.map(t=\u003e[t.regionId,t])),c=[];for(let t=0;t\u003ci.regionCount;t++){const e=PH(i,t),n=a.get(e),o=n?SH(n):xH({minX:i.regionCenterX[t]-i.regionWidth[t]/2,maxX:i.regionCenterX[t]+i.regionWidth[t]/2,minY:i.regionCenterY[t]-i.regionHeight[t]/2,maxY:i.regionCenterY[t]+i.regionHeight[t]/2});c.push(o)}const l=c.reduce((t,e)=\u003et+e.length,0),d=new Int32Array(i.regionCount),h=new Int32Array(i.regionCount),u=new Float64Array(l),p=new Float64Array(l),m=new Float64Array(i.regionCount),g=new Float64Array(i.regionCount),f=new Float64Array(i.regionCount),y=new Float64Array(i.regionCount),_=new Float64Array(i.regionCount),b=new Float64Array(i.regionCount),x=new Float64Array(i.regionCount),v=new Float64Array(i.regionCount),S=new Float64Array(i.regionCount),I=new Float64Array(i.regionCount),C=new Array(i.regionCount);let P=0;for(let t=0;t\u003ci.regionCount;t++){const e=c[t],n=IH(e),o=Math.sqrt(Math.max(n.area,yH));d[t]=P,h[t]=e.length,m[t]=n.area,g[t]=n.perimeter,f[t]=n.centerX,y[t]=n.centerY,_[t]=n.bounds.minX,b[t]=n.bounds.maxX,x[t]=n.bounds.minY,v[t]=n.bounds.maxY,S[t]=o,I[t]=o,C[t]=NH(i.regionMetadata?.[t],PH(i,t),e,n.bounds);for(const t of e)u[P]=t.x,p[P]=t.y,P+=1}const M=new Int32Array(i.portCount),N=new Int32Array(i.portCount),w=new Int32Array(i.portCount),T=new Int32Array(i.portCount),R=new Float64Array(i.portCount),E=new Float64Array(i.portCount);for(let t=0;t\u003ci.portCount;t++){const e={x:i.portX[t],y:i.portY[t]},[o,r]=i.incidentPortRegion[t]??[];if(void 0!==o){const i=CH(e,c[o],g[o],n);M[t]=i.boundaryPosition,w[t]=i.edgeIndex,R[t]=i.edgeT}if(void 0!==r){const o=CH(e,c[r],g[r],n);N[t]=o.boundaryPosition,T[t]=o.edgeIndex,E[t]=o.edgeT}}for(let t=0;t\u003ci.regionCount;t++)C[t].layer=nW(oW(i.regionAvailableZMask?.[t]??0))??nW((i.regionIncidentPorts[t]??[]).map(t=\u003ei.portZ[t]))??\"z0\";const A={...i,regionWidth:S,regionHeight:I,regionCenterX:f,regionCenterY:y,regionMetadata:C,portAngleForRegion1:M,portAngleForRegion2:N,regionVertexStart:d,regionVertexCount:h,regionVertexX:u,regionVertexY:p,regionArea:m,regionPerimeter:g,regionBoundsMinX:_,regionBoundsMaxX:b,regionBoundsMinY:x,regionBoundsMaxY:v,portBoundaryPositionForRegion1:M,portBoundaryPositionForRegion2:N,portEdgeIndexForRegion1:w,portEdgeIndexForRegion2:T,portEdgeTForRegion1:R,portEdgeTForRegion2:E};return{topology:A,problem:r,solution:s,mapping:wH(A,r)}})(this.serializedGraph),this.reservedRegionCount=((t,e)=\u003e{const n=t.problem.regionNetId;if(!n)return 0;const o=new Map;for(const t of e.regions){const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;Number.isInteger(e)\u0026\u0026e\u003e=0\u0026\u0026o.set(t.regionId,e)}let i=0;for(let e=0;e\u003ct.topology.regionCount;e++){const r=t.topology.regionMetadata?.[e],s=\"object\"==typeof r\u0026\u0026null!==r?r.serializedRegionId:void 0;if(\"string\"!=typeof s)continue;const a=o.get(s);void 0!==a\u0026\u0026(n[e]=a,i+=1)}return i})(this.loaded,this.serializedGraph);const i={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.max(1,Math.ceil(10*this.effort)),MAX_ITERATIONS:Math.max(1e5,Math.ceil(1e7*this.effort))};this.polySolver=new RH(this.loaded.topology,this.loaded.problem,i),this.activeSubSolver=this.polySolver,this.MAX_ITERATIONS=i.MAX_ITERATIONS+1e3,this.inputNodeWithPortPoints=this.createInputNodesWithPortPoints()}params;getSolverName(){return\"PolyHypergraphPortPointPathingSolver\"}convexRegions;serializedGraph;loaded;polySolver;inputNodeWithPortPoints=[];nodesWithPortPoints=[];reservedRegionCount=0;clearance;effort;usedUnconstrainedDelaunayFallback=!1;createInputNodesWithPortPoints(){const{topology:t}=this.loaded,e=[];for(let n=0;n\u003ct.regionCount;n++){const o=HH(t.regionMetadata?.[n]??{}),i=UH(o,n);if(i.startsWith(\"terminal-\"))continue;const r=(t.regionIncidentPorts[n]??[]).map(e=\u003e{const n=t.incidentPortRegion[e]??[],o=t.portMetadata?.[e];return{portPointId:ZH(o,e),x:t.portX[e],y:t.portY[e],z:t.portZ[e],...qH(o),connectionNodeIds:n.map(e=\u003eUH(t.regionMetadata?.[e],e)),distToCentermostPortOnZ:t.portMetadata?.[e]?.distToCentermostPortOnZ??0,connectsToOffBoardNode:!1}});e.push({capacityMeshNodeId:i,center:{x:t.regionCenterX[n],y:t.regionCenterY[n]},width:t.regionWidth[n],height:t.regionHeight[n],portPoints:r,availableZ:o.availableZ??Array.from({length:this.params.srj.layerCount},(t,e)=\u003ee),_containsObstacle:Boolean(o._containsObstacle),_containsTarget:Boolean(o._containsTarget)})}return e}createAssignedPortPoint(t,e){const n=this.polySolver.problem.routeMetadata?.[t],o=n?(t=\u003et.simpleRouteConnection?.name??t.connectionId)(n):`route-${t}`,i=n?(t=\u003et.simpleRouteConnection?.rootConnectionName??t.mutuallyConnectedNetworkId)(n):void 0,r=this.polySolver.topology.portMetadata?.[e];return{portPointId:ZH(r,e),x:this.polySolver.topology.portX[e],y:this.polySolver.topology.portY[e],z:this.polySolver.topology.portZ[e],connectionName:o,rootConnectionName:i,...qH(r)}}buildOutputNodes(){const{topology:t,state:e}=this.polySolver,n=[];for(let o=0;o\u003ce.regionSegments.length;o++){const i=HH(t.regionMetadata?.[o]??{}),r=UH(i,o);if(r.startsWith(\"terminal-\"))continue;const s=JH(i);if(!s)continue;const a=(e.regionSegments[o]??[]).flatMap(([t,e,n])=\u003e{const o=this.createAssignedPortPoint(t,e),i=this.createAssignedPortPoint(t,n);return o.portPointId\u0026\u0026i.portPointId\u0026\u0026(o.nextPortPointId=i.portPointId,i.prevPortPointId=o.portPointId),[o,i]});0!==a.length\u0026\u0026n.push({capacityMeshNodeId:r,center:{x:t.regionCenterX[o],y:t.regionCenterY[o]},width:t.regionWidth[o],height:t.regionHeight[o],polygon:s,portPoints:a,availableZ:i.availableZ})}this.nodesWithPortPoints=n}_step(){this.polySolver.step(),this.progress=this.polySolver.progress,this.stats={...this.polySolver.stats??{},reservedRegionCount:this.reservedRegionCount,usedUnconstrainedDelaunayFallback:this.usedUnconstrainedDelaunayFallback,regionCount:this.loaded.topology.regionCount,portCount:this.loaded.topology.portCount,routeCount:this.loaded.problem.routeCount},this.polySolver.solved?(this.buildOutputNodes(),this.solved=!0,this.activeSubSolver=null):this.polySolver.failed\u0026\u0026(this.error=this.polySolver.error,this.failed=!0,this.activeSubSolver=null)}getOutput(){return{nodesWithPortPoints:this.nodesWithPortPoints,inputNodeWithPortPoints:this.inputNodeWithPortPoints}}computeNodePf(t){const e=this.nodesWithPortPoints.find(e=\u003ee.capacityMeshNodeId===t.capacityMeshNodeId);if(!e)return null;const n=Ms(e);return Ys({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,layer:\"top\",availableZ:e.availableZ??[]},n.numSameLayerCrossings,n.numEntryExitLayerChanges,n.numTransitionPairCrossings)}getConstructorParams(){return[this.params]}preview(){return this.visualize()}visualize(){return this.polySolver.visualize()}},QH=class extends si{constructor(t){super(),this.inputSrj=t,this.MAX_ITERATIONS=1}inputSrj;outputSrj;_step(){this.outputSrj=mX(this.inputSrj)??this.inputSrj,this.solved=!0}getOutputSimpleRouteJson(){if(!this.outputSrj)throw new Error(\"PreprocessSimpleRouteJsonSolver has not solved yet\");return this.outputSrj}getConstructorParams(){return[this.inputSrj]}visualize(){return this.outputSrj?pi(Ho({...this.outputSrj,traces:[]}),Yj({srj:this.outputSrj})):{lines:[],points:[],rects:[],circles:[]}}},tG=(t,e)=\u003e(t.x-e.x)**2+(t.y-e.y)**2,eG=(t,e,n)=\u003e{if(!n)return;const o=t.filter(({projected:t})=\u003et.connectionName===e\u0026\u0026(void 0===n.z||t.z===n.z));return 0!==o.length?o.reduce((t,e)=\u003etG(e.projected,n)\u003ctG(t.projected,n)?e:t).original:void 0},nG=(t,e)=\u003e{const n=e.projectedRect;if(!n)throw new Error(\"Poly node is missing projectedRect\");const o=n.rectToPolygonMatrix,i=(t=\u003e{if(!t.projectedRect)throw new Error(\"Poly node is missing projectedRect\");return t.portPoints.map(e=\u003e{const n=ZX(e,t.projectedRect);return{original:e,projected:{...e,x:n.x,y:n.y}}})})(e),r=t.route.map(t=\u003e({...t,...HX(o,t)})),s=t.vias.map(t=\u003eHX(o,t)),a=eG(i,t.connectionName,t.route[0]),c=eG(i,t.connectionName,t.route[t.route.length-1]);return a\u0026\u0026r[0]\u0026\u0026(r[0]={...r[0],x:a.x,y:a.y,z:a.z}),c\u0026\u0026r[r.length-1]\u0026\u0026(r[r.length-1]={...r[r.length-1],x:c.x,y:c.y,z:c.z}),{...t,route:r,vias:s,jumpers:t.jumpers?.map(t=\u003e({...t,start:HX(o,t.start),end:HX(o,t.end)}))}},oG=class extends si{getSolverName(){return\"ProjectHighDensityToPolygonSolver\"}routes=[];routesByNodeId=new Map;colorMap;nodePortPoints;rawRoutesByNodeId;constructor({nodePortPoints:t,routesByNodeId:e,colorMap:n}){super(),this.MAX_ITERATIONS=1,this.nodePortPoints=t,this.rawRoutesByNodeId=e instanceof Map?new Map(e):new Map(Object.entries(e)),this.colorMap=n??{}}_step(){this.routes=[],this.routesByNodeId=new Map;for(const t of this.nodePortPoints){const e=(this.rawRoutesByNodeId.get(t.capacityMeshNodeId)??[]).map(e=\u003enG(e,t));e.length\u003e0\u0026\u0026(this.routesByNodeId.set(t.capacityMeshNodeId,e),this.routes.push(...e))}this.solved=!0}getOutput(){return this.routes}getConstructorParams(){return[{nodePortPoints:this.nodePortPoints,routesByNodeId:this.rawRoutesByNodeId,colorMap:this.colorMap}]}visualize(){const t={polygons:this.nodePortPoints.flatMap(t=\u003e[{points:t.polygon,fill:\"rgba(40, 140, 220, 0.06)\",stroke:\"rgba(20, 70, 160, 0.65)\",label:`${t.capacityMeshNodeId} polygon`},...t.projectedRect?[{points:t.projectedRect.targetQuad,fill:\"rgba(255, 165, 0, 0.05)\",stroke:\"rgba(255, 120, 0, 0.45)\",label:`${t.capacityMeshNodeId} projection target`}]:[]]),lines:[],circles:[]};for(const e of this.routes){const n=this.colorMap[e.connectionName]??\"#0000ff\",o=mi(e.route,e.connectionName,n);for(const n of o)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:To(n.color,.5),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?[.1,.3]:void 0});for(const o of e.vias)t.circles.push({center:o,layer:\"z0,1\",radius:e.viaDiameter/2,fill:n,label:`${e.connectionName} via`})}return t}};function iG(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var rG=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),this.equivalentAreaExpansionFactor=n.equivalentAreaExpansionFactor??2,this.minProjectedRectDimension=n.minProjectedRectDimension??3*this.minTraceWidth,void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;polyGraphSolver;attachProjectedRectsSolver;highDensityRouteSolver;projectHighDensityToPolgonSolver;highDensityStitchSolver;traceSimplificationSolver;traceWidthSolver;globalDrcForceImproveSolver;colorMap;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;equivalentAreaExpansionFactor;minProjectedRectDimension;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;highDensityNodePortPoints;projectedHighDensityNodePortPoints;cacheProvider=null;pipelineDef=[iG(\"preprocessSimpleRouteJsonSolver\",QH,t=\u003e[t.originalSrj],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),iG(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),iG(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),iG(\"polyGraphSolver\",KH,t=\u003e[{srj:t.srjWithPointPairs,effort:t.effort,concavityTolerance:t.opts.polyConcavityTolerance,portSpacing:t.opts.polyPortSpacing,portMarginFromSegmentEndpoint:t.opts.polyPortMarginFromSegmentEndpoint}],{onSolved:t=\u003e{t.highDensityNodePortPoints=t.polyGraphSolver?.getOutput().nodesWithPortPoints??[]}}),iG(\"attachProjectedRectsSolver\",JX,t=\u003e[{nodesWithPortPoints:t.highDensityNodePortPoints??[],equivalentAreaExpansionFactor:t.equivalentAreaExpansionFactor,minProjectedRectDimension:t.minProjectedRectDimension,traceWidth:t.minTraceWidth,viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.projectedHighDensityNodePortPoints=t.attachProjectedRectsSolver?.getOutput()??[]}}),iG(\"highDensityRouteSolver\",QX,t=\u003e[{nodePortPoints:t.projectedHighDensityNodePortPoints??[],nodePfById:new Map((t.polyGraphSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.polyGraphSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,effort:t.effort}]),iG(\"projectHighDensityToPolgonSolver\",oG,t=\u003e[{nodePortPoints:t.projectedHighDensityNodePortPoints??[],routesByNodeId:t.highDensityRouteSolver.routesByNodeId,colorMap:t.colorMap}]),iG(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.projectHighDensityToPolgonSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),iG(\"traceSimplificationSolver\",vc,t=\u003e[{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}]),iG(\"traceWidthSolver\",Ic,t=\u003e[{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}]),iG(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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\u0026\u0026(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\"}getProblemVisualization({includeRoutes:t=!0}={}){const e=this.originalSrj,n=[{points:[{x:e.bounds?.minX??-50,y:e.bounds?.minY??-50},{x:e.bounds?.maxX??50,y:e.bounds?.minY??-50},{x:e.bounds?.maxX??50,y:e.bounds?.maxY??50},{x:e.bounds?.minX??-50,y:e.bounds?.maxY??50},{x:e.bounds?.minX??-50,y:e.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}];if(e.outline\u0026\u0026e.outline.length\u003e=2){const t=e.outline.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),n.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const o=Oo(e),i={points:[...e.connections.flatMap(t=\u003et.pointsToConnect.map(n=\u003e({...n,layer:Fo(n,e.layerCount),label:`${t.name} ${n.pcb_port_id??\"\"}`})))],rects:[...(e.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,e.layerCount),label:o(t)}))],lines:n};if(!t)return i;const r=Yj({srj:e});return pi(i,r)}visualize(){if(!this.solved\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.getProblemVisualization(),e=this.getProblemVisualization({includeRoutes:!1}),n=this.polyGraphSolver?.visualize(),o=this.attachProjectedRectsSolver?.visualize(),i=this.highDensityRouteSolver?.visualize(),r=this.projectHighDensityToPolgonSolver?.visualize(),s=this.highDensityStitchSolver?.visualize(),a=this.traceSimplificationSolver?.visualize();return pi(...[t,this.escapeViaLocationSolver?.visualize(),this.netToPointPairsSolver?.visualize(),n,o,i?pi(e,i):null,r?pi(e,r):null,s,a,this.solved?pi({lines:e.lines},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean))}preview(){if(this.projectHighDensityToPolgonSolver){const t=[];for(let e=this.projectHighDensityToPolgonSolver.routes.length-1;e\u003e=0;e--){const n=this.projectHighDensityToPolgonSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.polyGraphSolver?this.polyGraphSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){return this.globalDrcForceImproveSolver?.getOutput()??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 o=n.__netConnectionName??this.originalSrj.connections.find(t=\u003et.name===n.name)?.__netConnectionName,i=e.filter(t=\u003et.connectionName===n.name);for(let e=0;e\u003ci.length;e++){const r=i[e],s={type:\"pcb_trace\",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},sG=t=\u003et.rootConnectionName??t.connectionName,aG=(t,e)=\u003et.flatMap((t,n)=\u003esG(t)===e?[n]:[]),cG=(t,e,n,o)=\u003e{const i=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=t.x-e.x,s=t.y-e.y,a=o**2+i**2,c=0===a?0:Math.max(0,Math.min(1,(r*o+s*i)/a));return Math.hypot(t.x-(e.x+c*o),t.y-(e.y+c*i))},r={x:e.x-t.x,y:e.y-t.y},s={x:o.x-n.x,y:o.y-n.y},a={x:n.x-t.x,y:n.y-t.y},c=(t,e)=\u003et.x*e.y-t.y*e.x,l=c(r,s),d=Math.hypot(r.x,r.y),h=1e-12*(d*Math.hypot(s.x,s.y)+1);if(Math.abs(l)\u003eh){const t=c(a,s)/l,e=c(a,r)/l;if(t\u003e=-1e-12\u0026\u0026t\u003c=1+1e-12\u0026\u0026e\u003e=-1e-12\u0026\u0026e\u003c=1+1e-12)return 0}else if(d\u003e1e-12\u0026\u0026Math.abs(c(a,r))\u003c=h){const i=Math.abs(r.x)\u003e=Math.abs(r.y),s=Math.min(i?t.x:t.y,i?e.x:e.y),a=Math.max(i?t.x:t.y,i?e.x:e.y),c=Math.min(i?n.x:n.y,i?o.x:o.y),l=Math.max(i?n.x:n.y,i?o.x:o.y);if(Math.max(s,c)\u003c=Math.min(a,l)+1e-12)return 0}return Math.min(i(t,n,o),i(e,n,o),i(n,t,e),i(o,t,e))},lG=(t,e)=\u003eMath.hypot(e.x-t.x,e.y-t.y),dG=t=\u003e{let e=0;for(let n=0;n\u003ct.route.length-1;n++)e+=lG(t.route[n],t.route[n+1]);return e},hG=(t,e)=\u003ee.reduce((e,n)=\u003ee+dG(t[n]),0),uG=(t,e)=\u003e{const n=t.__zLayers,o=t.zLayers,i=void 0!==n?n:o;if(void 0!==i){if(!Array.isArray(i)||0===i.length||i.some(t=\u003e!Number.isInteger(t)||t\u003c0||t\u003e=e))throw new Error(\"Obstacle has invalid z-layer indexes\");return i}if(0===t.layers.length)throw new Error(\"Obstacle has no declared layers\");return t.layers.map(t=\u003e{if(\"top\"===t)return 0;if(\"bottom\"===t)return e-1;const n=/^inner(\\d+)$/.exec(t),o=n?Number(n[1]):-1;if(o\u003c=0||o\u003e=e-1)throw new Error(`Obstacle has invalid layer name \"${t}\"`);return o})},pG=t=\u003e{const e=(t,e,n,o)=\u003e{const i=n.center.x-n.width/2-o,r=n.center.x+n.width/2+o,s=n.center.y-n.height/2-o,a=n.center.y+n.height/2+o;if(t.x\u003e=i\u0026\u0026t.x\u003c=r\u0026\u0026t.y\u003e=s\u0026\u0026t.y\u003c=a||e.x\u003e=i\u0026\u0026e.x\u003c=r\u0026\u0026e.y\u003e=s\u0026\u0026e.y\u003c=a)return!0;const c=[{x:i,y:s},{x:r,y:s},{x:r,y:a},{x:i,y:a}];return c.some((n,o)=\u003e0===cG(t,e,n,c[(o+1)%c.length]))};if(t.bounds\u0026\u0026t.meanderPoints.some(e=\u003ee.x\u003ct.bounds.minX||e.x\u003et.bounds.maxX||e.y\u003ct.bounds.minY||e.y\u003et.bounds.maxY))return!1;const n=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},o=sG(t.route),i=t.route.traceThickness/2+t.obstacleMargin;for(let r=0;r\u003ct.meanderPoints.length-1;r++){const s=t.meanderPoints[r],a=t.meanderPoints[r+1];for(const n of t.obstacles){if(!uG(n,t.layerCount).includes(s.z))continue;const c=0===r||r===t.meanderPoints.length-2;if((!n.connectedTo.includes(o)||!c)\u0026\u0026e(s,a,n,i))return!1}for(const e of t.routedRoutes){const i=sG(e)===o;for(const o of e.vias){if(o.zLayers\u0026\u0026!o.zLayers.includes(s.z))continue;const r=Math.hypot(o.x-s.x,o.y-s.y)\u003c=1e-8||Math.hypot(o.x-a.x,o.y-a.y)\u003c=1e-8,c=t.route.traceThickness/2+e.viaDiameter/2+t.obstacleMargin;if((!i||!r)\u0026\u0026n(o,s,a)\u003cc)return!1}if(!i)for(let n=0;n\u003ce.route.length-1;n++){const o=e.route[n],i=e.route[n+1];if(s.z!==o.z||s.z!==i.z)continue;const r=t.route.traceThickness/2+e.traceThickness/2+t.obstacleMargin;if(cG(s,a,o,i)\u003cr)return!1}}}return!0},mG=t=\u003e{const e=[];for(const n of t.routeIndexes){const o=t.routes[n],i=t.minMeanderGap??Math.max(.3,2*o.traceThickness),r=o.traceThickness+i,s=Math.max(t.minimumToothPitch??0,2*r),a=t.minMeanderHeight??r;for(let i=0;i\u003co.route.length-1;i++){const r=o.route[i],c=o.route[i+1],l=lG(r,c);if(l\u003c=0||r.z!==c.z)continue;const d=Math.min(Math.max(0,Math.floor(l/s)-1),t.maxToothCount);for(let o=1;o\u003c=d;o++){const r=l/(o+1),c=[r,Math.sqrt(s*r),s].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e-t)\u003c1e-9)===e),d=o%2==0?[\"balanced\",\"negative\",\"positive\"]:[\"negative\",\"positive\"];for(const r of c)for(const s of d)e.push({routeIndex:n,segmentIndex:i,segmentLength:l,toothCount:o,maximumDepth:t.maximumDepth,minimumHeight:a,toothPitch:r,placement:s,heightProfile:o\u003e1?\"tapered\":\"uniform\"})}}}const n={balanced:0,negative:1,positive:2};return e.sort((t,e)=\u003et.toothCount-e.toothCount||n[t.placement]-n[e.placement]||e.toothPitch-t.toothPitch||e.segmentLength-t.segmentLength)},gG=t=\u003e{if(null===t.centerlineDistanceCost)return 0;const e=t.predictedToothDepths.flatMap((t,e)=\u003et\u003e0?[e]:[]);if(0===e.length)return 0;const n=e.map(e=\u003et.predictedToothDepths[e]),o=Math.max(...n),i=n.reduce((t,e)=\u003et+e,0)/n.length,r=Math.sqrt(n.reduce((t,e)=\u003et+(e-i)**2,0)/n.length),s=e[0],a=(e.at(-1)-s+1)*t.toothPitch,c=o/(t.toothPitch/2),l=t.addedLength/a,d=c/(1+c)*40,h=l/(1+l)*30,u=t.predictedToothDepths.map((e,n)=\u003eMath.sin(Math.PI*(n+1)/(t.predictedToothDepths.length+1))),p=Math.max(...u),m=Math.sqrt(t.predictedToothDepths.reduce((t,e,n)=\u003et+(e-o*u[n]/p)**2,0)/t.predictedToothDepths.length),g=100-d-h-Math.min(10,(\"tapered\"===t.heightProfile?m:r)/i*10)-2*(n.length-1)-7*Math.min(1,t.addedLength/t.segmentLength)-100*t.centerlineDistanceCost,f=t.centerlineDistanceCost\u003e0?g:Math.max(0,g);return Math.round(1e6*f)/1e6},fG=t=\u003e{if(t.toothDepths.length!==t.toothCount)throw new Error(`LengthMatchingSolver: expected ${t.toothCount} tooth depths, received ${t.toothDepths.length}`);if(t.toothDepths.some(t=\u003e!Number.isFinite(t)||t\u003c0))throw new Error(\"LengthMatchingSolver: every meander tooth depth must be a non-negative finite number\");const e=t.route.route[t.segmentIndex],n=t.route.route[t.segmentIndex+1],o=lG(e,n),i=(n.x-e.x)/o,r=(n.y-e.y)/o,s=(o-(t.toothCount-.5)*t.toothPitch)/2,a=[{...e}];for(let n=0;n\u003ct.toothCount;n++){const o=t.toothDepths[n];if(0===o)continue;const c=\"balanced\"===t.placement?n%2==0?-1:1:\"negative\"===t.placement?-1:1,l={x:-r*c,y:i*c},d=s+n*t.toothPitch,h=d+t.toothPitch/2,u={...e,x:e.x+i*d,y:e.y+r*d};a.push(u,{...u,x:u.x+l.x*o,y:u.y+l.y*o},{...e,x:e.x+i*h+l.x*o,y:e.y+r*h+l.y*o},{...e,x:e.x+i*h,y:e.y+r*h})}return a.push({...n}),(t=\u003e{if(t.length\u003c3)return t;const e=[{...t[0]}];for(let n=1;n\u003ct.length-1;n++){const o=t[n-1],i=t[n],r=t[n+1],s=Math.hypot(i.x-o.x,i.y-o.y),a=Math.hypot(r.x-i.x,r.y-i.y);if(0===s||0===a)throw new Error(\"LengthMatchingSolver: meander contains a zero-length segment\");const c={x:(i.x-o.x)/s,y:(i.y-o.y)/s},l={x:(r.x-i.x)/a,y:(r.y-i.y)/a};if(Math.abs(c.x*l.y-c.y*l.x)\u003c1e-9){e.push({...i});continue}const d=Math.min(s,a)/2,h={...i,x:i.x-c.x*d,y:i.y-c.y*d},u={...i,x:i.x+l.x*d,y:i.y+l.y*d},p=e.at(-1);h.x===p.x\u0026\u0026h.y===p.y||e.push(h);for(let t=1;t\u003c6;t++){const n=t/6,o=1-n;e.push({...i,x:o**2*h.x+2*o*n*i.x+n**2*u.x,y:o**2*h.y+2*o*n*i.y+n**2*u.y})}e.push(u)}return e.push({...t[t.length-1]}),e})(a)},yG=t=\u003e[...t.route.route.slice(0,t.segmentIndex),...fG(t),...t.route.route.slice(t.segmentIndex+2)],_G=t=\u003e{const e=dG(t.route),n=(()=\u003e{const e=[];for(let n=0;n\u003ct.candidate.toothCount;n++){const o=Array(t.candidate.toothCount).fill(0);o[n]=t.candidate.maximumDepth;const i=fG({...t.candidate,route:t.route,toothDepths:o});if(t.isGeometryValid(i)){e.push(t.candidate.maximumDepth);continue}let r=0,s=t.candidate.maximumDepth;for(let e=0;e\u003c32;e++){const e=(r+s)/2,o=Array(t.candidate.toothCount).fill(0);o[n]=e;const i=fG({...t.candidate,route:t.route,toothDepths:o});t.isGeometryValid(i)?r=e:s=e}e.push(r)}return e})(),o=(t=\u003e{if(\"tapered\"!==t.heightProfile)return Array(t.toothCount).fill(1);const e=Array.from({length:t.toothCount},(e,n)=\u003eMath.sin(Math.PI*(n+1)/(t.toothCount+1))),n=Math.max(...e);return e.map(t=\u003et/n)})(t.candidate),i=t.candidate.maximumDepth,r=n.map((t,e)=\u003eMath.min(t,i*o[e])),s=[.25,.75],a=r.map(t=\u003et*s[0]),c=r.map(t=\u003et*s[1]),l=yG({...t.candidate,route:t.route,toothDepths:a}),d=yG({...t.candidate,route:t.route,toothDepths:c}),h=[dG({...t.route,route:l})-e,dG({...t.route,route:d})-e],u=yG({...t.candidate,route:t.route,toothDepths:r}),p=dG({...t.route,route:u})-e,m=(h[1]-h[0])/(s[1]-s[0]),g=h[0]-m*s[0],f=m\u003e0\u0026\u0026Number.isFinite(m)?(t.targetAddedLength-g)/m:0,y=Math.min(t.targetAddedLength,p),_=t.targetAddedLength\u003e0\u0026\u0026y\u003e0?(e=\u003e{let n=0,o=t.candidate.maximumDepth;for(let i=0;i\u003c32;i++){const i=(n+o)/2,r=e.maximumToothDepths.map((t,n)=\u003eMath.min(t,i*e.toothHeightWeights[n])),s=yG({...t.candidate,route:t.route,toothDepths:r}),a=dG({...t.route,route:s})-e.originalLength,c=fG({...t.candidate,route:t.route,toothDepths:r});t.isGeometryValid(c)?a\u003ce.targetAddedLength?n=i:o=i:o=i}const i=(n+o)/2;return{depthLevel:i,toothDepths:e.maximumToothDepths.map((t,n)=\u003eMath.min(t,i*e.toothHeightWeights[n]))}})({maximumToothDepths:n,toothHeightWeights:o,originalLength:e,targetAddedLength:y}):{depthLevel:f*i,toothDepths:r.map(t=\u003eMath.max(0,t*f))},b=_.depthLevel/i,x=_.toothDepths,v=yG({...t.candidate,route:t.route,toothDepths:x}),S=dG({...t.route,route:v})-e,I=Math.abs(y-S),C=fG({...t.candidate,route:t.route,toothDepths:x});let P=0;if(t.getCenterlineDistanceCost\u0026\u0026(P=t.getCenterlineDistanceCost(C)),null!==P\u0026\u0026(!Number.isFinite(P)||P\u003c0))throw new Error(\"LengthMatchingSolver: meander centerline distance cost must be a non-negative finite number\");const M=Number.isFinite(b)\u0026\u0026b\u003e0\u0026\u0026b\u003c=1,N=x.every(e=\u003e0===e||e\u003e=t.candidate.minimumHeight),w=t.isGeometryValid(C);let T,R=null;null===P?R=\"no-paired-same-layer-geometry\":M?I\u003et.lengthTolerance?R=\"target-error\":w?N||(R=\"below-minimum-height\"):R=\"invalid-geometry\":R=\"invalid-scale\",T=R?{valid:!1,invalidReason:R}:{valid:!0,invalidReason:null};const E={...t.candidate,connectionName:t.connectionName,maximumToothDepths:n,sampleScaleFactors:s,sampleAddedLengths:h,slope:m,intercept:g,predictedScaleFactor:b,predictedToothDepths:x,predictedRoute:v,addedLength:S,maximumAddedLength:p,resultingError:I,testedSegment:[{...t.route.route[t.candidate.segmentIndex]},{...t.route.route[t.candidate.segmentIndex+1]}],meanderPoints:C,centerlineDistanceCost:P,qualityScore:0,...T};return{...E,qualityScore:gG(E)}},bG=t=\u003e{const e=(t=\u003e{if(\"tapered\"!==t.heightProfile)return Array(t.toothCount).fill(1);const e=Array.from({length:t.toothCount},(e,n)=\u003eMath.sin(Math.PI*(n+1)/(t.toothCount+1))),n=Math.max(...e);return e.map(t=\u003et/n)})(t.candidate),n=Math.max(...e.map(e=\u003et.candidate.minimumHeight/e)),o=t.candidate.maximumDepth/2**30,i=e.map(t=\u003et*(n+o));if(i.some(e=\u003ee\u003et.candidate.maximumDepth))return null;const r=fG({...t.candidate,route:t.route,toothDepths:i});if(!t.isGeometryValid(r))return null;const s=yG({...t.candidate,route:t.route,toothDepths:i}),a=dG({...t.route,route:s})-dG(t.route),c=_G({...t,targetAddedLength:a});return c.valid?c:null},xG=t=\u003e{const e=(t,e)=\u003e{const n=t[e.routeIndex];if(!n)throw new Error(`LengthMatchingSolver: dual meander references missing route ${e.routeIndex}`);const o=[...t];return o[e.routeIndex]={...n,route:e.predictedRoute},o},n=(()=\u003e{if(t.targetAddedLength+t.config.lengthTolerance\u003ct.plan.minimumAddedLength||t.targetAddedLength-t.config.lengthTolerance\u003et.plan.maximumAddedLength)return null;const e=t.plan.attemptOptions.map(t=\u003eMath.min(...t.map(t=\u003et.attempt.addedLength)));let n=Math.max(0,t.targetAddedLength-t.plan.minimumAddedLength),o=e.map((t,e)=\u003ee);for(;n\u003e1e-9\u0026\u0026o.length\u003e0;){const i=n/o.length;let r=0;const s=[];for(const n of o){const o=Math.max(...t.plan.attemptOptions[n].map(t=\u003et.attempt.maximumAddedLength))-e[n],a=Math.min(o,i);e[n]+=a,r+=a,o-a\u003e1e-9\u0026\u0026s.push(n)}if(r\u003c=1e-9)break;n-=r,o=s}return n\u003c=t.config.lengthTolerance?e:null})();if(!n)return null;const o=t.plan.attemptOptions.map((t,e)=\u003e({attemptOptions:t,targetAddedLength:n[e]})).sort((t,e)=\u003ee.attemptOptions[0].candidate.routeIndex-t.attemptOptions[0].candidate.routeIndex||e.attemptOptions[0].candidate.segmentIndex-t.attemptOptions[0].candidate.segmentIndex);let i=[...t.routes];const r=[];for(const n of o){const o=n.attemptOptions[0]?.candidate;if(!o)throw new Error(\"LengthMatchingSolver: empty dual-meander segment options\");const s=i[o.routeIndex];if(!s)throw new Error(`LengthMatchingSolver: missing planned dual-meander route ${o.routeIndex}`);let a=null;for(const e of n.attemptOptions){if(e.attempt.addedLength-t.config.lengthTolerance\u003en.targetAddedLength||e.attempt.maximumAddedLength+t.config.lengthTolerance\u003cn.targetAddedLength)continue;const o=_G({candidate:e.candidate,route:s,connectionName:t.connectionName,targetAddedLength:n.targetAddedLength,lengthTolerance:t.config.lengthTolerance,isGeometryValid:e=\u003epG({route:s,meanderPoints:e,routedRoutes:t.excludedConnectionName?i.filter(e=\u003esG(e)!==t.excludedConnectionName):i,...t.config})});o.valid\u0026\u0026(!a||o.qualityScore\u003ea.qualityScore)\u0026\u0026(a=o)}if(!a)return null;i=e(i,a),r.push(a)}const s=r.reduce((t,e)=\u003et+e.addedLength,0);if(Math.abs(s-t.targetAddedLength)\u003et.config.lengthTolerance)return null;const a=r[0];if(!a)throw new Error(\"LengthMatchingSolver: fitted an empty dual-meander plan\");return{attempts:[a,...r.slice(1)],routes:i,addedLength:s}},vG=t=\u003e{if(0===t.length)throw new Error(\"LengthMatchingSolver: cannot score an empty meander plan\");return t.reduce((t,e)=\u003et+e.qualityScore,0)/t.length-3*(t.length-1)},SG=t=\u003e{const e=t=\u003e[t.candidate.toothCount,t.candidate.placement,t.candidate.heightProfile].join(\":\"),n=new Map;for(const o of t){const t=e(o),i=`${o.candidate.routeIndex}:${o.candidate.segmentIndex}`,r=n.get(t);if(!r){n.set(t,new Map([[i,[o]]]));continue}const s=r.get(i);s?s.push(o):r.set(i,[o])}const o=[];for(const t of n.values()){const e=[...t.values()].map(t=\u003e({attempts:t,maximumAddedLength:Math.max(...t.map(t=\u003et.attempt.maximumAddedLength)),minimumAddedLength:Math.min(...t.map(t=\u003et.attempt.addedLength)),rankingAttempt:t.reduce((t,e)=\u003ee.attempt.qualityScore\u003et.attempt.qualityScore?e:t)})).sort((t,e)=\u003ee.maximumAddedLength-t.maximumAddedLength);for(const t of e)o.push({attempts:[t.rankingAttempt],attemptOptions:[t.attempts],minimumAddedLength:t.minimumAddedLength,maximumAddedLength:t.maximumAddedLength,rankingQualityScore:t.rankingAttempt.attempt.qualityScore});for(let t=2;t\u003c=e.length;t++){const n=e.slice(0,t),i=n.map(t=\u003et.rankingAttempt);o.push({attempts:i,attemptOptions:n.map(t=\u003et.attempts),minimumAddedLength:n.reduce((t,e)=\u003et+e.minimumAddedLength,0),maximumAddedLength:n.reduce((t,e)=\u003et+e.maximumAddedLength,0),rankingQualityScore:vG(i.map(t=\u003et.attempt))})}}return o},IG=class extends Error{connectionName;reason;constructor(t){super(t.message),this.name=\"LengthMatchingNoSolutionError\",this.connectionName=t.connectionName,this.reason=t.reason}},CG=t=\u003e[t.routeIndex,t.segmentIndex,t.toothCount,t.placement,t.toothPitch,t.heightProfile,t.maximumDepth,t.minimumHeight].join(\":\"),PG=t=\u003e{const e=new Map,n=[...t.attempts].sort((t,e)=\u003et.addedLength-e.addedLength);let o=t.targetAddedLength;for(let t=0;t\u003cn.length;t++){const i=n[t],r=Math.min(i.addedLength,o/(n.length-t));e.set(CG(i),{routeIndex:i.routeIndex,segmentIndex:i.segmentIndex,targetAddedLength:r}),o-=r}return e},MG=(t,e)=\u003e`z${uG(t,e).join(\",\")}`,NG=t=\u003e`z${t}`,wG=t=\u003e{if(!t.showAttempt)return;if(!t.attempt)return void(t=\u003e{const e=t.activePair?.candidates[t.activePair.candidateIndex];if(!e)return;const n=t.routes[e.routeIndex];if(!n)return;const o=n.route[e.segmentIndex],i=n.route[e.segmentIndex+1];o\u0026\u0026i\u0026\u0026t.graphics.lines.push({points:[o,i],strokeColor:\"rgba(234, 179, 8, 0.6)\",strokeWidth:2*n.traceThickness,strokeDash:[.1,.1],layer:NG(o.z)})})(t);const e=t.routes[t.attempt.routeIndex],[n,o]=t.attempt.testedSegment,i=t.theme.getConnectionColor(t.attempt.connectionName);t.graphics.lines.push({points:[n,o],strokeColor:t.theme.getTestedSegmentColor(i),strokeWidth:e.traceThickness,strokeDash:[.15,.15],layer:NG(n.z)}),t.attempt.valid?t.graphics.lines.push({points:t.attempt.meanderPoints.map(({x:t,y:e})=\u003e({x:t,y:e})),strokeColor:\"rgba(234, 179, 8, 0.6)\",strokeWidth:2*e.traceThickness,strokeDash:[.1,.1],layer:NG(n.z)}):t.graphics.lines.push({points:t.attempt.meanderPoints.map(({x:t,y:e})=\u003e({x:t,y:e})),strokeColor:t.theme.getRejectedCandidateColor(i),strokeWidth:e.traceThickness,strokeDash:[.1,.1],layer:NG(n.z)}),t.graphics.points.push({x:n.x,y:n.y,color:i,layer:NG(n.z)},{x:o.x,y:o.y,color:i,layer:NG(o.z)})},TG=t=\u003e{const e={lines:[],points:[],rects:[],circles:[]},n=(t=\u003e{for(const e of Object.values(t))Tt(0,e);return{getConnectionColor:(e,n)=\u003et[e]??(n?t[n]:void 0)??(t=\u003et?`hsl(${300*t.split(\"\").reduce((t,e)=\u003et+e.charCodeAt(0),0)/t.length%360}, 100%, 50%)`:\"rgba(0, 0, 0, 0.5)\")(e),getInnerLayerConnectionColor:t=\u003eTt(.5,t),getTestedSegmentColor:t=\u003eTt(.55,t),getRejectedCandidateColor:t=\u003eTt(.45,t),boardBounds:{fill:\"rgba(30,41,59,0.03)\",stroke:\"rgba(30,41,59,0.55)\"},obstacle:{fill:\"rgba(255,0,0,0.25)\",stroke:\"rgba(255,0,0,0.5)\"},via:{fill:\"blue\",stroke:\"none\"}}})(t.colorMap);return(t=\u003e{for(const e of t.routes){const n=sG(e),o=t.theme.getConnectionColor(n,e.connectionName);for(let n=0;n\u003ce.route.length-1;n++){const i=e.route[n],r=e.route[n+1];i.z===r.z\u0026\u0026t.graphics.lines.push({points:[i,r],strokeColor:0===i.z?o:t.theme.getInnerLayerConnectionColor(o),strokeWidth:e.traceThickness,...0===i.z?{}:{strokeDash:[.2,.2]},layer:NG(i.z)})}const i=[...new Set(e.route.map(t=\u003et.z))];for(const n of e.vias)t.graphics.circles.push({center:n,radius:e.viaDiameter/2,fill:t.theme.via.fill,stroke:t.theme.via.stroke,layer:`z${(n.zLayers??i).join(\",\")}`})}})({routes:t.routes,theme:n,graphics:e}),(t=\u003e{if(t.bounds){const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds;t.graphics.rects.push({center:{x:(e+n)/2,y:(o+i)/2},width:n-e,height:i-o,fill:t.theme.boardBounds.fill,stroke:t.theme.boardBounds.stroke,layer:`z${Array.from({length:t.layerCount},(t,e)=\u003ee).join(\",\")}`})}for(const e of t.obstacles)t.graphics.rects.push({center:e.center,width:e.width,height:e.height,ccwRotationDegrees:e.ccwRotationDegrees,fill:t.theme.obstacle.fill,stroke:t.theme.obstacle.stroke,layer:MG(e,t.layerCount)})})({obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,theme:n,graphics:e}),wG({routes:t.routes,attempt:t.currentAttempt,activePair:t.activePair,showAttempt:!t.solved,theme:n,graphics:e}),{...e}},RG=class extends kt{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1e5,this.matchedHdRoutes=t.hdRoutes.map(t=\u003e({...t,route:t.route.map(t=\u003e({...t}))})),this.pairs=t.differentialPairs??[]}params;matchedHdRoutes;pairs;nextPairIndex=0;activePair=null;currentAttempt=null;config=null;candidatesTried=0;getSolverName(){return\"LengthMatchingSolver\"}startNextPair(){const t=this.pairs[this.nextPairIndex++];if(!t)return void(this.solved=!0);((t,e)=\u003e{if(t.connectionNames[0]===t.connectionNames[1])throw new Error(\"LengthMatchingSolver: a differential pair must reference two distinct connections\");if(!Number.isFinite(t.lengthTolerance)||t.lengthTolerance\u003c0)throw new Error(\"LengthMatchingSolver: differential pair lengthTolerance must be a non-negative finite number\");for(const e of[t.minimumCenterlineDistance,t.maximumCenterlineDistance])if(void 0!==e\u0026\u0026(!Number.isFinite(e)||e\u003c=0))throw new Error(\"LengthMatchingSolver: differential pair centerline distances must be positive finite numbers\");if(void 0!==t.minimumCenterlineDistance\u0026\u0026void 0!==t.maximumCenterlineDistance\u0026\u0026t.minimumCenterlineDistance\u003et.maximumCenterlineDistance)throw new Error(\"LengthMatchingSolver: differential pair minimumCenterlineDistance cannot exceed maximumCenterlineDistance\");const n=new Map(e.map(t=\u003e[t.name,t]));for(const e of t.connectionNames){const t=n.get(e);if(!t)throw new Error(`LengthMatchingSolver: differential pair references unknown connection \"${e}\"`);if(2!==t.pointsToConnect.length)throw new Error(`LengthMatchingSolver: differential pair connection \"${e}\" must have exactly two points before MST splitting`)}})(t,this.params.originalConnections);const e=aG(this.matchedHdRoutes,t.connectionNames[0]),n=aG(this.matchedHdRoutes,t.connectionNames[1]);if(0===e.length\u0026\u00260===n.length)return;if(0===e.length||0===n.length)throw new Error(`LengthMatchingSolver: differential pair ${t.connectionNames.join(\"/\")} has routed geometry for only one connection`);const o=hG(this.matchedHdRoutes,e),i=hG(this.matchedHdRoutes,n),r=Math.abs(o-i);if(r\u003c=t.lengthTolerance)return;const s=o\u003ci,a=t.connectionNames[s?0:1],c=t.connectionNames[s?1:0],l=mG({routes:this.matchedHdRoutes,routeIndexes:s?e:n,maximumDepth:this.getConfig().maximumMeanderDepth,minimumToothPitch:this.getConfig().minimumToothPitch,minMeanderGap:this.getConfig().minMeanderGap,minMeanderHeight:this.getConfig().minMeanderHeight,maxToothCount:this.getConfig().maxToothCount});if(0===l.length)throw new IG({message:`LengthMatchingSolver: no same-layer straight segment can tune connection \"${a}\"`,connectionName:a,reason:\"no-meander-candidate\"});this.activePair={pair:t,longerConnectionName:c,longerRouteIndexes:s?n:e,shorterConnectionName:a,targetAddedLength:r,remainingAddedLength:r,candidates:l,candidateIndex:0,lastMatchedSegmentIndexByRoute:new Map,partialAttempts:[],fullAttempts:[],plannedAttemptTargets:null,hasMinimumHeightBlockedAttempt:!1}}acceptAttempt(t,e){const n=this.matchedHdRoutes[e.routeIndex];this.matchedHdRoutes[e.routeIndex]={...n,route:e.predictedRoute},t.remainingAddedLength-=e.addedLength,t.lastMatchedSegmentIndexByRoute.set(e.routeIndex,e.segmentIndex),t.candidateIndex=0,t.partialAttempts=[],t.fullAttempts=[],t.plannedAttemptTargets?.delete(CG(e)),0===t.plannedAttemptTargets?.size\u0026\u0026(t.plannedAttemptTargets=null),t.remainingAddedLength\u003c=t.pair.lengthTolerance\u0026\u0026(this.activePair=null)}tryCandidate(t){let e;for(;!e;){const n=t.candidates[t.candidateIndex++];if(!n)break;const o=t.lastMatchedSegmentIndexByRoute.get(n.routeIndex);(void 0===o||n.segmentIndex\u003co)\u0026\u0026(!t.plannedAttemptTargets||t.plannedAttemptTargets.has(CG(n))\u0026\u0026![...t.plannedAttemptTargets.values()].some(t=\u003et.routeIndex===n.routeIndex\u0026\u0026t.segmentIndex\u003en.segmentIndex))\u0026\u0026(e=n)}if(!e){const e=t.fullAttempts.reduce((t,e)=\u003e!t||e.qualityScore\u003et.qualityScore?e:t,null),n=(t=\u003e{const e=t=\u003e[t.toothCount,t.placement,t.heightProfile].join(\":\"),n=new Map;for(const o of t.attempts){const t=`${o.routeIndex}:${o.segmentIndex}`,i=e(o),r=n.get(i);if(!r){n.set(i,new Map([[t,[o]]]));continue}const s=r.get(t);s?s.push(o):r.set(t,[o])}let o=null;for(const e of n.values()){const n=[...e.values()].map(t=\u003e({attempts:t,maximumCapacityAttempt:t.reduce((t,e)=\u003ee.addedLength\u003et.addedLength?e:t)})).sort((t,e)=\u003ee.maximumCapacityAttempt.addedLength-t.maximumCapacityAttempt.addedLength);let i=0;for(let e=0;e\u003cn.length;e++){if(i+=n[e].maximumCapacityAttempt.addedLength,i+t.lengthTolerance\u003ct.targetAddedLength)continue;const r=n.slice(0,e+1),s=r.map(t=\u003et.maximumCapacityAttempt),a=PG({attempts:s,targetAddedLength:t.targetAddedLength}),c=r.map(e=\u003e{const n=a.get(CG(e.maximumCapacityAttempt));if(!n)throw new Error(`LengthMatchingSolver: missing capacity target for ${CG(e.maximumCapacityAttempt)}`);const o=e.attempts.filter(e=\u003ee.addedLength+t.lengthTolerance\u003e=n.targetAddedLength);if(0===o.length)throw new Error(`LengthMatchingSolver: no pitch can supply planned target for route ${e.maximumCapacityAttempt.routeIndex} segment ${e.maximumCapacityAttempt.segmentIndex}`);return o.reduce((t,e)=\u003ee.qualityScore\u003et.qualityScore||e.qualityScore===t.qualityScore\u0026\u0026e.toothPitch\u003et.toothPitch?e:t)}),l=vG(c);if(!o){o={attempts:c};break}const d=vG(o.attempts);(c.length\u003co.attempts.length||c.length===o.attempts.length\u0026\u0026l\u003ed)\u0026\u0026(o={attempts:c});break}}return o})({attempts:t.partialAttempts,targetAddedLength:t.remainingAddedLength,lengthTolerance:t.pair.lengthTolerance});if(e\u0026\u0026(!n||e.qualityScore\u003e=vG(n.attempts)))return void this.acceptAttempt(t,e);if(!n){if(!(t.hasMinimumHeightBlockedAttempt\u0026\u0026null===t.plannedAttemptTargets\u0026\u00260===t.lastMatchedSegmentIndexByRoute.size))throw new IG({message:`LengthMatchingSolver: linear regression exhausted all segment/tooth combinations for \"${t.shorterConnectionName}\"; required ${t.targetAddedLength.toFixed(4)}mm`,connectionName:t.shorterConnectionName,reason:\"meander-search-exhausted\"});return this.tryDualMeanderPlan(t)}return t.plannedAttemptTargets=PG({attempts:n.attempts,targetAddedLength:t.remainingAddedLength}),t.candidateIndex=0,t.partialAttempts=[],void(t.fullAttempts=[])}const n=this.matchedHdRoutes[e.routeIndex],o=this.getConfig(),i=t.plannedAttemptTargets?.get(CG(e));if(null!==t.plannedAttemptTargets\u0026\u0026void 0===i)throw new Error(`LengthMatchingSolver: missing planned target for ${CG(e)}`);this.currentAttempt=_G({candidate:e,route:n,connectionName:t.shorterConnectionName,targetAddedLength:void 0===i?t.remainingAddedLength:i.targetAddedLength,lengthTolerance:t.pair.lengthTolerance,isGeometryValid:t=\u003epG({route:n,meanderPoints:t,routedRoutes:this.matchedHdRoutes,obstacles:o.obstacles,bounds:o.bounds,layerCount:o.layerCount,obstacleMargin:o.obstacleMargin}),getCenterlineDistanceCost:void 0===t.pair.minimumCenterlineDistance\u0026\u0026void 0===t.pair.maximumCenterlineDistance?void 0:e=\u003e(t=\u003e{let e=0,n=0;for(let o=0;o\u003ct.meanderPoints.length-1;o++){const i=t.meanderPoints[o],r=t.meanderPoints[o+1],s=Math.hypot(r.x-i.x,r.y-i.y);if(0!==s){for(let e=0;e\u003c4;e++){const o=(e+.5)/4,a={x:i.x+(r.x-i.x)*o,y:i.y+(r.y-i.y)*o},c=[];for(const e of t.pairedRoutes)for(let t=0;t\u003ce.route.length-1;t++){const n=e.route[t],o=e.route[t+1];i.z===n.z\u0026\u0026i.z===o.z\u0026\u0026c.push(cG(a,a,n,o))}if(0===c.length)return null;const l=Math.min(...c);n+=s*Math.max(0,(t.minimumCenterlineDistance??Number.NEGATIVE_INFINITY)-l,l-(t.maximumCenterlineDistance??Number.POSITIVE_INFINITY))/4}e+=s}}if(0===e)throw new Error(\"LengthMatchingSolver: cannot measure a zero-length meander centerline\");return n/e})({meanderPoints:e,pairedRoutes:t.longerRouteIndexes.map(t=\u003ethis.matchedHdRoutes[t]),minimumCenterlineDistance:t.pair.minimumCenterlineDistance,maximumCenterlineDistance:t.pair.maximumCenterlineDistance})}),this.candidatesTried++,\"below-minimum-height\"===this.currentAttempt.invalidReason\u0026\u0026(t.hasMinimumHeightBlockedAttempt=!0),this.stats={pair:`${t.pair.connectionNames[0]}/${t.pair.connectionNames[1]}`,candidatesTried:this.candidatesTried,segmentIndex:e.segmentIndex,toothCount:e.toothCount,toothPitch:e.toothPitch,placement:e.placement,predictedScaleFactor:this.currentAttempt.predictedScaleFactor,predictedToothDepths:this.currentAttempt.predictedToothDepths,resultingError:this.currentAttempt.resultingError,qualityScore:this.currentAttempt.qualityScore,accepted:this.currentAttempt.valid},this.currentAttempt.valid\u0026\u0026(null===t.plannedAttemptTargets?t.remainingAddedLength-this.currentAttempt.addedLength\u003c=t.pair.lengthTolerance?t.fullAttempts.push(this.currentAttempt):t.partialAttempts.push(this.currentAttempt):this.acceptAttempt(t,this.currentAttempt))}tryDualMeanderPlan(t){if(t.remainingAddedLength!==t.targetAddedLength)throw new Error(`LengthMatchingSolver: cannot start a dual-meander plan after partially tuning \"${t.shorterConnectionName}\"`);const e=this.getConfig(),n=mG({routes:this.matchedHdRoutes,routeIndexes:t.longerRouteIndexes,maximumDepth:e.maximumMeanderDepth,minimumToothPitch:e.minimumToothPitch,minMeanderGap:e.minMeanderGap,minMeanderHeight:e.minMeanderHeight,maxToothCount:e.maxToothCount}),o=(t=\u003e{const e=(t,e)=\u003et.rankingQualityScore!==e.rankingQualityScore?t.rankingQualityScore\u003ee.rankingQualityScore:t.leftIndex!==e.leftIndex?t.leftIndex\u003ce.leftIndex:t.rightIndex\u003ce.rightIndex,n=(t,n)=\u003e{t.push(n);let o=t.length-1;for(;o\u003e0;){const i=Math.floor((o-1)/2),r=t[i];if(e(r,n))break;t[o]=r,o=i}t[o]=n},o=t=\u003e{const n=t[0],o=t.pop();if(!n||!o||0===t.length)return n;let i=0;for(;;){const n=2*i+1,r=n+1;if(n\u003e=t.length)break;const s=r\u003ct.length\u0026\u0026e(t[r],t[n])?r:n,a=t[s];if(e(o,a))break;t[i]=a,i=s}return t[i]=o,n},i=function*(t){const e=[...t.leftOptions].sort((e,n)=\u003et.getLeftQualityScore(n)-t.getLeftQualityScore(e)),i=[...t.rightOptions].sort((e,n)=\u003et.getRightQualityScore(n)-t.getRightQualityScore(e)),r=[];for(let o=0;o\u003ce.length;o++){const s=i[0];if(!s)break;n(r,{leftIndex:o,rightIndex:0,rankingQualityScore:(t.getLeftQualityScore(e[o])+t.getRightQualityScore(s))/2})}for(;r.length\u003e0;){const s=o(r);yield[e[s.leftIndex],i[s.rightIndex]];const a=s.rightIndex+1,c=i[a];c\u0026\u0026n(r,{leftIndex:s.leftIndex,rightIndex:a,rankingQualityScore:(t.getLeftQualityScore(e[s.leftIndex])+t.getRightQualityScore(c))/2})}},r=(t,e)=\u003e{const n=t[e.routeIndex];if(!n)throw new Error(`LengthMatchingSolver: dual meander references missing route ${e.routeIndex}`);const o=[...t];return o[e.routeIndex]={...n,route:e.predictedRoute},o},s=t=\u003e{const e=t.routes[t.attempt.routeIndex];if(!e)throw new Error(`LengthMatchingSolver: cannot validate missing dual-meander route ${t.attempt.routeIndex}`);return pG({route:e,meanderPoints:t.attempt.meanderPoints,routedRoutes:t.routes,...t.config})},a=t=\u003e{const e=t.routes.filter(e=\u003esG(e)!==t.counterpartConnectionName),n=[];for(const o of t.candidates){const i=t.routes[o.routeIndex];if(!i)throw new Error(`LengthMatchingSolver: dual-meander candidate references missing route ${o.routeIndex}`);const r=bG({candidate:o,route:i,connectionName:t.connectionName,lengthTolerance:t.config.lengthTolerance,isGeometryValid:n=\u003epG({route:i,meanderPoints:n,routedRoutes:e,...t.config})});r\u0026\u0026n.push({candidate:o,attempt:r})}return n},c={obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,obstacleMargin:t.obstacleMargin},l=a({candidates:t.shorterCandidates,routes:t.routes,connectionName:t.shorterConnectionName,counterpartConnectionName:t.longerConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(0===l.length)return null;const d=a({candidates:t.longerCandidates,routes:t.routes,connectionName:t.longerConnectionName,counterpartConnectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}}),h=i({leftOptions:d,rightOptions:l,getLeftQualityScore:t=\u003et.attempt.qualityScore,getRightQualityScore:t=\u003et.attempt.qualityScore});for(const[e,n]of h){const o=Math.max(e.attempt.addedLength,n.attempt.addedLength-t.originalLengthDifference),i=o+t.originalLengthDifference;if(o-t.lengthTolerance\u003ee.attempt.maximumAddedLength||i-t.lengthTolerance\u003en.attempt.maximumAddedLength)continue;const a=t.routes[e.candidate.routeIndex];if(!a)throw new Error(`LengthMatchingSolver: missing longer route ${e.candidate.routeIndex}`);const l=t.routes[n.candidate.routeIndex];if(!l)throw new Error(`LengthMatchingSolver: missing shorter route ${n.candidate.routeIndex}`);const d=t.routes.filter(e=\u003esG(e)!==t.shorterConnectionName),h=_G({candidate:e.candidate,route:a,connectionName:t.longerConnectionName,targetAddedLength:o,lengthTolerance:t.lengthTolerance,isGeometryValid:t=\u003epG({route:a,meanderPoints:t,routedRoutes:d,...c})});if(!h.valid||Math.abs(h.addedLength-o)\u003et.lengthTolerance)continue;const u=r(t.routes,h),p=h.addedLength+t.originalLengthDifference,m=_G({candidate:n.candidate,route:l,connectionName:t.shorterConnectionName,targetAddedLength:p,lengthTolerance:t.lengthTolerance,isGeometryValid:t=\u003epG({route:l,meanderPoints:t,routedRoutes:u,...c})});if(!m.valid)continue;const g=r(u,m),f=aG(g,t.longerConnectionName),y=aG(g,t.shorterConnectionName);if(!(Math.abs(hG(g,y)-hG(g,f))\u003et.lengthTolerance)\u0026\u0026s({attempt:h,routes:g,config:c})\u0026\u0026s({attempt:m,routes:g,config:c}))return{longerAttempts:[h],shorterAttempts:[m]}}const u=i({leftOptions:SG(d),rightOptions:SG(l),getLeftQualityScore:t=\u003et.rankingQualityScore,getRightQualityScore:t=\u003et.rankingQualityScore});for(const[e,n]of u){if(1===e.attempts.length\u0026\u00261===n.attempts.length)continue;const o=Math.max(e.minimumAddedLength,n.minimumAddedLength-t.originalLengthDifference),i=o+t.originalLengthDifference;if(o-t.lengthTolerance\u003ee.maximumAddedLength||i-t.lengthTolerance\u003en.maximumAddedLength)continue;const r=xG({plan:e,targetAddedLength:o,routes:t.routes,connectionName:t.longerConnectionName,excludedConnectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(!r)continue;const a=xG({plan:n,targetAddedLength:r.addedLength+t.originalLengthDifference,routes:r.routes,connectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(!a)continue;const l=aG(a.routes,t.longerConnectionName),d=aG(a.routes,t.shorterConnectionName),h=Math.abs(hG(a.routes,d)-hG(a.routes,l)),u=[...r.attempts,...a.attempts];if(!(h\u003et.lengthTolerance||u.some(t=\u003e!s({attempt:t,routes:a.routes,config:c}))))return{longerAttempts:r.attempts,shorterAttempts:a.attempts}}return null})({routes:this.matchedHdRoutes,longerConnectionName:t.longerConnectionName,shorterConnectionName:t.shorterConnectionName,originalLengthDifference:t.targetAddedLength,lengthTolerance:t.pair.lengthTolerance,longerCandidates:n,shorterCandidates:t.candidates,obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,obstacleMargin:e.obstacleMargin});if(!o)throw new IG({message:`LengthMatchingSolver: linear regression exhausted all segment/tooth combinations for \"${t.shorterConnectionName}\"; required ${t.targetAddedLength.toFixed(4)}mm`,connectionName:t.shorterConnectionName,reason:\"meander-search-exhausted\"});const i=[...this.matchedHdRoutes];for(const t of[...o.longerAttempts,...o.shorterAttempts]){const e=this.matchedHdRoutes[t.routeIndex];if(!e)throw new Error(`LengthMatchingSolver: cannot commit dual meander to missing route ${t.routeIndex}`);i[t.routeIndex]={...e,route:t.predictedRoute}}this.matchedHdRoutes=i,this.currentAttempt=o.shorterAttempts[0];const r=o.longerAttempts.reduce((t,e)=\u003et+e.addedLength,0),s=o.shorterAttempts.reduce((t,e)=\u003et+e.addedLength,0);this.stats={pair:`${t.pair.connectionNames[0]}/${t.pair.connectionNames[1]}`,mode:\"dual-meander\",longerAddedLength:r,shorterAddedLength:s,resultingError:Math.abs(s-r-t.targetAddedLength)},this.activePair=null}getConfig(){return this.config||(this.config=(t=\u003e{const e=t.maximumMeanderDepth??5,n=t.maxToothCount??12;if(!Number.isFinite(e)||e\u003c=0)throw new Error(\"LengthMatchingSolver: maximumMeanderDepth must be a positive finite number\");if(void 0!==t.minimumToothPitch\u0026\u0026(!Number.isFinite(t.minimumToothPitch)||t.minimumToothPitch\u003c=0))throw new Error(\"LengthMatchingSolver: minimumToothPitch must be a positive finite number\");if(void 0!==t.minMeanderGap\u0026\u0026(!Number.isFinite(t.minMeanderGap)||t.minMeanderGap\u003c=0))throw new Error(\"LengthMatchingSolver: minMeanderGap must be a positive finite number\");if(void 0!==t.minMeanderHeight\u0026\u0026(!Number.isFinite(t.minMeanderHeight)||t.minMeanderHeight\u003c=0))throw new Error(\"LengthMatchingSolver: minMeanderHeight must be a positive finite number\");if(void 0!==t.minMeanderHeight\u0026\u0026t.minMeanderHeight\u003ee)throw new Error(\"LengthMatchingSolver: minMeanderHeight cannot exceed maximumMeanderDepth\");if(!Number.isFinite(n)||!Number.isInteger(n)||n\u003c=0)throw new Error(\"LengthMatchingSolver: maxToothCount must be a positive finite integer\");return{maximumMeanderDepth:e,minimumToothPitch:t.minimumToothPitch,minMeanderGap:t.minMeanderGap,minMeanderHeight:t.minMeanderHeight,maxToothCount:n,obstacles:t.obstacles??[],bounds:t.bounds,obstacleMargin:t.obstacleMargin??.15,layerCount:t.layerCount??2,colorMap:t.colorMap??{}}})(this.params)),this.config}_step(){this.getConfig(),this.activePair?this.tryCandidate(this.activePair):this.startNextPair()}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved)throw new Error(\"LengthMatchingSolver: getOutput() called before the solver completed\");return{matchedHdRoutes:this.matchedHdRoutes}}getBestEffortOutput(){const t=structuredClone(this.matchedHdRoutes),e=this.activePair?.fullAttempts??[];let n=null;for(const t of e)(!n||t.qualityScore\u003en.qualityScore)\u0026\u0026(n=t);if(!n)for(const t of this.activePair?.partialAttempts??[])(!n||t.addedLength\u003en.addedLength||t.addedLength===n.addedLength\u0026\u0026t.qualityScore\u003en.qualityScore)\u0026\u0026(n=t);if(n){const e=t[n.routeIndex];e\u0026\u0026(t[n.routeIndex]={...e,route:structuredClone(n.predictedRoute)})}return{matchedHdRoutes:t}}computeProgress(){if(this.solved)return 1;if(0===this.pairs.length)return this.config?1:0;const t=Math.max(0,this.nextPairIndex-1),e=this.activePair?this.activePair.candidateIndex/this.activePair.candidates.length:0;return Math.min(.99,(t+e)/this.pairs.length)}visualize(){const t=this.getConfig();return TG({routes:this.matchedHdRoutes,obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,colorMap:t.colorMap,activePair:this.activePair,currentAttempt:this.currentAttempt,solved:this.solved})}},EG=(t,e)=\u003e{if(\"top\"===t)return 0;if(\"bottom\"===t)return e-1;const n=/^inner(\\d+)$/.exec(t);if(!n)return-1;const o=Number(n[1]);return o\u003e0\u0026\u0026o\u003ce-1?o:-1},AG=(t,e)=\u003e0===t?\"top\":t===e-1?\"bottom\":`inner${t}`,OG=(t,e,n)=\u003e{const o=EG(t,n),i=EG(e,n);if(o\u003c0||i\u003c0)return[];const r=Math.min(o,i),s=Math.max(o,i);return Array.from({length:s-r+1},(t,e)=\u003eAG(r+e,n))},kG=1e-8,LG=(t,e)=\u003e{if(0===t.route.length)throw new Error(`trace \"${t.connection_name}\" has an empty route`);if(t.route.some(t=\u003e\"wire\"!==t.route_type\u0026\u0026\"via\"!==t.route_type))throw new Error(`trace \"${t.connection_name}\" contains unsupported jumper or through-obstacle geometry`);const n=t.route.findIndex(t=\u003e\"wire\"===t.route_type),o=t.route[n],i=t.route.findLast(t=\u003e\"wire\"===t.route_type);if(\"wire\"!==o?.route_type||!i)throw new Error(`trace \"${t.connection_name}\" must contain a wire point`);const r=[],s=[],a=[],c=[];let l=null,d=o.width;if(n\u003e0){let e=o.layer;for(let o=n-1;o\u003e=0;o--){const n=t.route[o];if(\"via\"!==n?.route_type)throw new Error(`trace \"${t.connection_name}\" has unsupported geometry before its first wire`);if(e===n.to_layer)e=n.from_layer;else{if(e!==n.from_layer)throw new Error(`trace \"${t.connection_name}\" has discontinuous leading vias`);e=n.to_layer}}const i=t.route[0];if(\"via\"!==i.route_type)throw new Error(`trace \"${t.connection_name}\" has an invalid leading entry`);l={x:i.x,y:i.y,layer:e,width:o.width},r.push(l)}for(const n of t.route){if(\"wire\"===n.route_type){if(!Number.isFinite(n.x)||!Number.isFinite(n.y)||!Number.isFinite(n.width)||n.width\u003c=0||EG(n.layer,e)\u003c0)throw new Error(`trace \"${t.connection_name}\" has an invalid wire point`);d=Math.max(d,n.width);const o={x:n.x,y:n.y,layer:n.layer,width:n.width};if(l){if(l.layer!==o.layer)throw new Error(`trace \"${t.connection_name}\" changes layers without a via`);Math.hypot(l.x-o.x,l.y-o.y)\u003ekG\u0026\u0026s.push({start:l,end:o,layer:o.layer,width:Math.max(l.width,o.width),connectionName:t.connection_name,terminal:null})}r.push(o),l=o;continue}if(\"via\"!==n.route_type)throw new Error(`trace \"${t.connection_name}\" contains unsupported route geometry`);if(!l)throw new Error(`trace \"${t.connection_name}\" has a leading via`);const o=EG(n.from_layer,e),i=EG(n.to_layer,e),h=n.via_diameter??l.width;if(!Number.isFinite(n.x)||!Number.isFinite(n.y)||o\u003c0||i\u003c0||o===i||void 0!==n.via_diameter\u0026\u0026(!Number.isFinite(n.via_diameter)||n.via_diameter\u003c=0)||void 0!==n.via_hole_diameter\u0026\u0026(!Number.isFinite(n.via_hole_diameter)||n.via_hole_diameter\u003c=0||n.via_hole_diameter\u003e=h))throw new Error(`trace \"${t.connection_name}\" has an invalid via`);const u=l.layer===n.from_layer?n.from_layer:l.layer===n.to_layer?n.to_layer:null;if(!u)throw new Error(`trace \"${t.connection_name}\" has a discontinuous via transition`);Math.hypot(l.x-n.x,l.y-n.y)\u003ekG\u0026\u0026s.push({start:l,end:n,layer:l.layer,width:l.width,connectionName:t.connection_name,terminal:null});const p=u===n.from_layer?n.to_layer:n.from_layer;c.push({...n,from_layer:u,to_layer:p}),a.push({x:n.x,y:n.y,layers:OG(u,p,e),diameter:h,connectionName:t.connection_name,terminal:1===r.length?\"start\":null}),l={x:n.x,y:n.y,layer:p,width:l.width},r.push(l)}if(r.length\u003c2||0===s.length)throw new Error(`trace \"${t.connection_name}\" does not contain a routable path`);s[0].terminal=1===s.length?\"both\":\"start\",s[s.length-1].terminal=1===s.length?\"both\":\"end\";const h=a.at(-1);return h\u0026\u0026Math.hypot(h.x-i.x,h.y-i.y)\u003c=kG\u0026\u0026(h.terminal=\"end\"),{source:t,points:r,segments:s,vias:a,transitions:c,width:d,viaDiameter:t.__postProcessingViaDiameter??d,...o.start_pcb_port_id?{startPortId:o.start_pcb_port_id}:{},...i.end_pcb_port_id?{endPortId:i.end_pcb_port_id}:{}}},DG=(t,e)=\u003e{const n=[],o=[],i=t.route.find(t=\u003e\"wire\"===t.route_type),r=\"wire\"===i?.route_type?i.width:null,s={\"0603\":.95,1206:1.8,\"1206x4_pair\":1.8};let a=null;for(let i=0;i\u003ct.route.length;i++){const c=t.route[i];if(\"wire\"===c.route_type){if(!Number.isFinite(c.x)||!Number.isFinite(c.y)||!Number.isFinite(c.width)||c.width\u003c=0||EG(c.layer,e)\u003c0)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has an invalid wire`);if(a\u0026\u0026a.layer!==c.layer)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" changes layer without a transition`);a\u0026\u0026n.push({start:a,end:c,layer:c.layer,width:Math.max(a.width,c.width),connectionName:t.connection_name,terminal:null}),a=c;continue}if(\"via\"===c.route_type){const s=OG(c.from_layer,c.to_layer,e),l=a,d=c.via_diameter??l?.width??r;if(!Number.isFinite(c.x)||!Number.isFinite(c.y)||s.length\u003c2||null===d||!Number.isFinite(d)||d\u003c=0||void 0!==c.via_hole_diameter\u0026\u0026(!Number.isFinite(c.via_hole_diameter)||c.via_hole_diameter\u003c=0||null!==d\u0026\u0026c.via_hole_diameter\u003e=d))throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has an invalid via`);l\u0026\u0026Math.hypot(l.x-c.x,l.y-c.y)\u003e1e-8\u0026\u0026n.push({start:l,end:c,layer:l.layer,width:l.width,connectionName:t.connection_name,terminal:null}),o.push({x:c.x,y:c.y,layers:s,diameter:d,connectionName:t.connection_name,terminal:0===i?\"start\":i===t.route.length-1?\"end\":null});const h=t.route.slice(i+1).find(t=\u003e\"wire\"===t.route_type),u=l?.layer===c.from_layer?c.to_layer:l?.layer===c.to_layer?c.from_layer:\"wire\"!==h?.route_type||h.layer!==c.from_layer\u0026\u0026h.layer!==c.to_layer?null:h.layer;if(!u)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has a discontinuous via`);a={x:c.x,y:c.y,layer:u,width:l?.width??r??d};continue}if(\"jumper\"===c.route_type){const o=s[c.footprint];if(!Number.isFinite(c.start.x)||!Number.isFinite(c.start.y)||!Number.isFinite(c.end.x)||!Number.isFinite(c.end.y)||EG(c.layer,e)\u003c0)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has an invalid jumper`);if(a\u0026\u0026(a.layer!==c.layer||Math.hypot(a.x-c.start.x,a.y-c.start.y)\u003e1e-8))throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has a discontinuous jumper`);n.push({start:c.start,end:c.end,layer:c.layer,width:o,connectionName:t.connection_name,terminal:null}),a={...c.end,layer:c.layer,width:o};continue}const l=OG(c.from_layer,c.to_layer,e);if(!Number.isFinite(c.start.x)||!Number.isFinite(c.start.y)||!Number.isFinite(c.end.x)||!Number.isFinite(c.end.y)||!Number.isFinite(c.width)||c.width\u003c=0||l.length\u003c2)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has invalid through-obstacle copper`);if(a\u0026\u0026(a.layer!==c.from_layer\u0026\u0026a.layer!==c.to_layer||Math.hypot(a.x-c.start.x,a.y-c.start.y)\u003e1e-8))throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has discontinuous through-obstacle copper`);for(const e of l)n.push({start:c.start,end:c.end,layer:e,width:c.width,connectionName:t.connection_name,terminal:null});const d=a,h=d?.layer===c.to_layer?c.from_layer:c.to_layer;a={...c.end,layer:h,width:c.width}}return{segments:n,vias:o}},zG=(t,e)=\u003e{const n=DG(t,e);return[...n.segments.map((n,o)=\u003e({connectionName:`${t.connection_name}#immutable-segment-${o}`,rootConnectionName:t.connection_name,traceThickness:n.width,viaDiameter:n.width,route:[{x:n.start.x,y:n.start.y,z:EG(n.layer,e),traceThickness:n.width},{x:n.end.x,y:n.end.y,z:EG(n.layer,e),traceThickness:n.width}],vias:[]})),...n.vias.map((n,o)=\u003e({connectionName:`${t.connection_name}#immutable-via-${o}`,rootConnectionName:t.connection_name,traceThickness:n.diameter,viaDiameter:n.diameter,route:[],vias:[{x:n.x,y:n.y,zLayers:n.layers.map(t=\u003eEG(t,e))}]}))]},FG=t=\u003et.segments.reduce((t,e)=\u003et+Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),0),BG=t=\u003e{const{simpleRouteJson:e}=t.params,n=(t=\u003e{const e=new Set(t.reroutedPairs.map(t=\u003et.connectionNames.join(\"\\0\")));return t.declaredPairs.filter(n=\u003e{const o=n.connectionNames.map(e=\u003et.traces.filter(t=\u003et.connection_name===e));if(o.some(t=\u003e1!==t.length))return!1;if(e.has(n.connectionNames.join(\"\\0\")))return!0;const i=o.map(t=\u003et[0]);if(i.some(t=\u003et.route.length\u003c2||\"wire\"!==t.route[0]?.route_type||!t.route.every(t=\u003e\"wire\"===t.route_type||\"via\"===t.route_type)))return!1;const r=i.map(e=\u003eFG(LG(e,t.layerCount)));return Math.abs(r[0]-r[1])\u003en.lengthTolerance+1e-7}).map(t=\u003estructuredClone(t))})({traces:t.result.traces,declaredPairs:e.differentialPairs,reroutedPairs:t.result.reroutedPairs,layerCount:e.layerCount}),o=new Set(n.flatMap(t=\u003et.connectionNames)),i=[],r=[],s=[],a=new Set;for(let n=0;n\u003ct.result.traces.length;n++){const c=t.result.traces[n];if(!o.has(c.connection_name))continue;const l=c.route.every(t=\u003e\"wire\"===t.route_type||\"via\"===t.route_type),d=\"wire\"===c.route[0]?.route_type;if(!l||!d)throw new Error(`PostProcessingSolver: rerouted connection \"${c.connection_name}\" cannot be bound to LengthMatchingSolver`);const h=LG(c,e.layerCount),u=c.route[0];if(\"wire\"!==u.route_type)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" lost its first wire during binding`);const p=[{x:u.x,y:u.y,z:EG(u.layer,e.layerCount),traceThickness:u.width}],m=[],g=[];let f=u.layer,y=u.width;for(const t of c.route.slice(1)){if(\"wire\"===t.route_type){if(t.layer!==f)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" changes layers without a via while binding`);p.push({x:t.x,y:t.y,z:EG(t.layer,e.layerCount),traceThickness:t.width}),y=t.width;continue}if(\"via\"!==t.route_type)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" contains unsupported bound geometry`);const n=f===t.from_layer?t.to_layer:f===t.to_layer?t.from_layer:null;if(!n)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" has a discontinuous bound via`);const o=p.at(-1);Math.hypot(o.x-t.x,o.y-t.y)\u003e1e-8\u0026\u0026p.push({x:t.x,y:t.y,z:EG(f,e.layerCount),traceThickness:y}),p.push({x:t.x,y:t.y,z:EG(n,e.layerCount),traceThickness:y}),m.push({x:t.x,y:t.y,zLayers:OG(t.from_layer,t.to_layer,e.layerCount).map(t=\u003eEG(t,e.layerCount))}),g.push({...t}),f=n}if(p.length\u003c2)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" has no bound copper segments`);const _=Math.max(...p.map(t=\u003et.traceThickness??h.width)),b=h.viaDiameter,x=i.length;i.push({connectionName:c.connection_name,traceThickness:_,viaDiameter:b,route:p,vias:m});const v=p[0],S=p.at(-1);r.push({name:c.connection_name,pointsToConnect:[{x:v.x,y:v.y,layer:u.layer,...h.startPortId?{pcb_port_id:h.startPortId}:{}},{x:S.x,y:S.y,layer:h.points.at(-1).layer,...h.endPortId?{pcb_port_id:h.endPortId}:{}}]}),s.push({traceIndex:n,matchedRouteIndex:x,viaTemplates:g,startEndpoint:{...v},endEndpoint:{...S},...h.startPortId?{startPortId:h.startPortId}:{},...h.endPortId?{endPortId:h.endPortId}:{}}),a.add(c.connection_name)}for(const t of o)if(!a.has(t))throw new Error(`PostProcessingSolver: missing LengthMatchingSolver binding for rerouted connection \"${t}\"`);for(const n of t.result.traces)o.has(n.connection_name)||i.push(...zG(n,e.layerCount));const c=e.minTraceToPadEdgeClearance??Math.max(0,...i.filter(t=\u003et.route.length\u003e=2).map(t=\u003et.traceThickness));return{solverParams:{hdRoutes:i,originalConnections:r,differentialPairs:n,obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,obstacleMargin:c},traceBindings:s,baseTraces:structuredClone(t.result.traces)}},jG=t=\u003e{const e=new Map;for(const n of t.differentialPairs)for(const o of n.connectionNames){const n=t.hdRoutes.map((t,e)=\u003e({route:t,hdRouteIndex:e})).filter(({route:t})=\u003et.connectionName===o);1===n.length\u0026\u0026e.set(n[0].hdRouteIndex,o)}const n=t.hdRoutes.map((e,n)=\u003e{const o=[],i=new Map;for(let t=0;t\u003c(e.jumpers?.length??0);t++){const n=e.jumpers[t],o=e.route.map((t,e)=\u003e({point:t,index:e})).filter(({point:t})=\u003eMath.hypot(t.x-n.start.x,t.y-n.start.y)\u003c=1e-8).map(({index:t})=\u003et),r=e.route.map((t,e)=\u003e({point:t,index:e})).filter(({point:t})=\u003eMath.hypot(t.x-n.end.x,t.y-n.end.y)\u003c=1e-8).map(({index:t})=\u003et),s=[...o.flatMap(t=\u003er.filter(e=\u003ee\u003et).map(e=\u003e({startIndex:t,endIndex:e}))),...r.flatMap(t=\u003eo.filter(e=\u003ee\u003et).map(e=\u003e({startIndex:t,endIndex:e})))];if(1!==s.length)throw new Error(`PostProcessingSolver: immutable HD route \"${e.connectionName}\" has an ambiguous jumper traversal`);const a=s[0];if(i.has(a.startIndex)||[...i.values()].some(({endIndex:t})=\u003ea.startIndex\u003ct||a.endIndex\u003c=t))throw new Error(`PostProcessingSolver: immutable HD route \"${e.connectionName}\" has overlapping or unordered jumpers`);i.set(a.startIndex,{endIndex:a.endIndex,jumperIndex:t})}if(e.route.length\u003e0){const n=e.route[0];o.push({route_type:\"wire\",x:n.x,y:n.y,width:n.traceThickness??e.traceThickness,layer:AG(n.z,t.layerCount)});for(let n=0;n\u003ce.route.length-1;n++){const r=e.route[n],s=i.get(n);if(s){const i=e.route[s.endIndex],a=e.jumpers[s.jumperIndex];if(r.z!==i.z)throw new Error(`PostProcessingSolver: immutable HD route \"${e.connectionName}\" changes layers through a jumper`);o.push({route_type:\"jumper\",start:{x:r.x,y:r.y},end:{x:i.x,y:i.y},footprint:a.footprint,layer:AG(r.z,t.layerCount)}),o.push({route_type:\"wire\",x:i.x,y:i.y,width:i.traceThickness??e.traceThickness,layer:AG(i.z,t.layerCount)}),n=s.endIndex-1;continue}const a=e.route[n+1],c=AG(r.z,t.layerCount),l=AG(a.z,t.layerCount);r.z!==a.z\u0026\u0026(\"through_obstacle\"===r.toNextSegmentType?o.push({route_type:\"through_obstacle\",start:{x:r.x,y:r.y},end:{x:a.x,y:a.y},from_layer:c,to_layer:l,width:r.traceThickness??e.traceThickness}):o.push({route_type:\"via\",x:a.x,y:a.y,from_layer:c,to_layer:l,via_diameter:e.viaDiameter})),o.push({route_type:\"wire\",x:a.x,y:a.y,width:a.traceThickness??e.traceThickness,layer:l})}const r=o.filter(t=\u003e\"wire\"===t.route_type),s=e.startPcbPortId??e.route[0]?.pcb_port_id,a=e.endPcbPortId??e.route.at(-1)?.pcb_port_id;s\u0026\u0026r[0]\u0026\u0026(r[0].start_pcb_port_id=s),a\u0026\u0026r.at(-1)\u0026\u0026(r.at(-1).end_pcb_port_id=a)}return{type:\"pcb_trace\",pcb_trace_id:`post_processing_hd_route_${n}`,connection_name:e.connectionName,__postProcessingViaDiameter:e.viaDiameter,route:o}}),o=structuredClone(t.obstacles);for(let n=0;n\u003ct.hdRoutes.length;n++){const i=t.hdRoutes[n],r=new Set([i.connectionName,i.rootConnectionName,i.startPcbPortId,i.endPcbPortId,i.route[0]?.pcb_port_id,i.route.at(-1)?.pcb_port_id,e.get(n)].filter(t=\u003evoid 0!==t));for(const t of o)t.connectedTo.some(t=\u003er.has(t))\u0026\u0026(t.connectedTo=[...new Set([...t.connectedTo,...r])])}return{params:{simpleRouteJson:{traces:n,differentialPairs:structuredClone(t.differentialPairs),obstacles:o,bounds:structuredClone(t.bounds),layerCount:t.layerCount,minTraceToPadEdgeClearance:t.minTraceToPadEdgeClearance},...t.routingGrid?{routingGrid:structuredClone(t.routingGrid)}:{}},routeBindings:[...e.entries()].map(([t,e])=\u003e({hdRouteIndex:t,traceIndex:t,internalConnectionName:e})),sourceHdRoutes:structuredClone(t.hdRoutes)}};function $G(t){const e=structuredClone(t.model.sourceHdRoutes);for(const n of t.model.routeBindings){const o=t.binding.traceBindings.find(t=\u003et.traceIndex===n.traceIndex);if(!o)continue;const i=t.result.matchedHdRoutes[o.matchedRouteIndex],r=e[n.hdRouteIndex];if(!i||!r)throw new Error(`PostProcessingSolver: missing matched or source HD route for \"${n.internalConnectionName}\"`);if(i.connectionName!==n.internalConnectionName)throw new Error(`PostProcessingSolver: matched HD binding changed \"${n.internalConnectionName}\" to \"${i.connectionName}\"`);const s=i.route.map(t=\u003e({...t})),a=(e,o)=\u003e{if(e\u0026\u0026o\u0026\u0026(o.pcb_port_id\u0026\u0026(e.pcb_port_id=o.pcb_port_id),o.insideJumperPad\u0026\u0026t.rejectInsideJumperPad))throw new Error(`PostProcessingSolver: cannot restore jumper-pad metadata on rerouted connection \"${n.internalConnectionName}\"`)};a(s[0],r.route[0]),a(s.at(-1),r.route.at(-1)),e[n.hdRouteIndex]={...r,route:s,vias:structuredClone(i.vias)}}return{hdRoutes:e,postProcessingErrors:[]}}var YG=class extends Error{connectionNames;reason;constructor(t){super(`PostProcessingSolver: differential pair ${t.connectionNames.join(\"/\")} ${t.message}`),this.name=\"DifferentialPairRoutingError\",this.connectionNames=[t.connectionNames[0],t.connectionNames[1]],this.reason=t.reason}},XG=class extends Error{connectionNames;reason;constructor(t){super(t.message),this.name=\"PostProcessingConstraintError\",this.connectionNames=[...t.connectionNames],this.reason=t.reason}},VG=class extends Error{reason=\"grid-capacity-exhausted\";constructor(t){super(t),this.name=\"PostProcessingGridCapacityError\"}},WG=t=\u003e{const e=75e3*t.simpleRouteJson.differentialPairs.length;if(!Number.isSafeInteger(e))throw new Error(\"PostProcessingSolver: derived rerouting iteration bound exceeds the safe integer range\");const n=Math.min(e,8e4);return Math.max(1,n)},HG=t=\u003estructuredClone(t),GG=(t,e,n)=\u003e{const o=t=\u003e{const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}},i=o(t.start),r=o(t.end),s=e.width/2+n,a=e.height/2+n;if(Math.abs(i.x)\u003c=s\u0026\u0026Math.abs(i.y)\u003c=a||Math.abs(r.x)\u003c=s\u0026\u0026Math.abs(r.y)\u003c=a)return!0;const c=[{x:-s,y:-a},{x:s,y:-a},{x:s,y:a},{x:-s,y:a}];return c.some((t,e)=\u003ecG(i,r,t,c[(e+1)%c.length])\u003c=1e-7)},UG=t=\u003e{const e=[],n=[];for(const o of t.immutableTraces){const i=DG(o,t.layerCount);e.push(...i.segments),n.push(...i.vias)}const o=Array.from({length:t.layerCount},()=\u003e[]);for(const n of e){const e=EG(n.layer,t.layerCount);o[e].push(n)}const i=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y)\u003c=1e-8,r=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-e.x-o*s,t.y-e.y-i*s)},s=(t,e,n)=\u003e{const o=-(e.ccwRotationDegrees??0)*Math.PI/180,i=t.x-e.center.x,r=t.y-e.center.y,s=i*Math.cos(o)-r*Math.sin(o),a=i*Math.sin(o)+r*Math.cos(o);return Math.abs(s)\u003c=e.width/2+n\u0026\u0026Math.abs(a)\u003c=e.height/2+n},a=(e,n)=\u003e{const o=EG(n,t.layerCount);return uG(e,t.layerCount).includes(o)},c=(e,n,o)=\u003e{const i=((e,n,o)=\u003e{const i=Math.hypot(n.x,n.y);if(i\u003c=1e-10)throw new Error(\"PostProcessingSolver: cannot orient terminal fanout on a zero-length spine\");const r=-n.y/i*t.side*t.centerlineSpacing/2,s=n.x/i*t.side*t.centerlineSpacing/2,a=\"start\"===o?[t.firstStartTerminal,t.secondStartTerminal]:[t.firstEndTerminal,t.secondEndTerminal],c=[t.firstWidth,t.secondWidth],l=[t.firstConnectionName,t.secondConnectionName];return a.map((t,n)=\u003e{const i=0===n?1:-1,a={x:e.x+r*i,y:e.y+s*i};return{start:\"start\"===o?t:a,end:\"start\"===o?a:t,layer:e.layer,width:c[n],connectionName:l[n],terminal:o}})})(e,n,o),r=i.map(t=\u003e\"start\"===o?t.end:t.start);return i.every(l)\u0026\u0026r.every((n,o)=\u003et.obstacles.every(r=\u003e!a(r,e.layer)||!s(n,r,1.5*i[o].width+(t.terminalMiterMargin??0))))\u0026\u0026cG(i[0].start,i[0].end,i[1].start,i[1].end)\u003e=i[0].width/2+i[1].width/2-1e-7},l=e=\u003e{const i=e.width/2,c=i+(t.minTraceToPadEdgeClearance??e.width),l=EG(e.layer,t.layerCount),d=Math.min(e.start.x,e.end.x),h=Math.max(e.start.x,e.end.x),u=Math.min(e.start.y,e.end.y),p=Math.max(e.start.y,e.end.y);for(const n of[e.start,e.end])if(n.x-i\u003ct.bounds.minX||n.x+i\u003et.bounds.maxX||n.y-i\u003ct.bounds.minY||n.y+i\u003et.bounds.maxY)return!1;for(const n of t.obstacles){if(!a(n,e.layer))continue;const o=Math.hypot(n.width/2+c,n.height/2+c);if(h\u003cn.center.x-o||d\u003en.center.x+o||p\u003cn.center.y-o||u\u003en.center.y+o)continue;const[i,r]=e.connectionName===t.firstConnectionName?[t.firstStartTerminal,t.firstEndTerminal]:[t.secondStartTerminal,t.secondEndTerminal],l=s(i,n,0)\u0026\u0026(s(e.start,n,c)||s(e.end,n,c))\u0026\u0026Math.hypot(e.end.x-i.x,e.end.y-i.y)\u003e=Math.hypot(e.start.x-i.x,e.start.y-i.y),m=s(r,n,0)\u0026\u0026(s(e.start,n,c)||s(e.end,n,c))\u0026\u0026Math.hypot(e.end.x-r.x,e.end.y-r.y)\u003c=Math.hypot(e.start.x-r.x,e.start.y-r.y);if(!(n.connectedTo.includes(e.connectionName)\u0026\u0026(l||m))\u0026\u0026GG(e,n,c))return!1}for(const t of o[l]){const n=e.width/2+t.width/2+Math.max(e.width,t.width);if(!(h+n\u003cMath.min(t.start.x,t.end.x)||d-n\u003eMath.max(t.start.x,t.end.x)||p+n\u003cMath.min(t.start.y,t.end.y)||u-n\u003eMath.max(t.start.y,t.end.y))\u0026\u0026cG(e.start,e.end,t.start,t.end)\u003cn)return!1}for(const t of n)if(t.layers.includes(e.layer)\u0026\u0026r(t,e.start,e.end)\u003ce.width/2+t.diameter/2+e.width)return!1;return!0},d=o=\u003e{const i=o.diameter/2;if(o.x-i\u003ct.bounds.minX||o.x+i\u003et.bounds.maxX||o.y-i\u003ct.bounds.minY||o.y+i\u003et.bounds.maxY)return!1;for(const e of t.obstacles){if(!o.layers.some(t=\u003ea(e,t)))continue;if(!(null!==o.terminal\u0026\u0026e.connectedTo.includes(o.connectionName)\u0026\u0026s(o,e,0))\u0026\u0026s(o,e,i+o.diameter))return!1}for(const t of e){if(!o.layers.includes(t.layer))continue;const e=i+t.width/2+Math.max(o.diameter,t.width);if(r(o,t.start,t.end)\u003ce)return!1}for(const t of n){if(!t.layers.some(t=\u003eo.layers.includes(t)))continue;const e=i+t.diameter/2+Math.max(o.diameter,t.diameter);if(Math.hypot(o.x-t.x,o.y-t.y)\u003ce)return!1}return!0};return{isEdgeValid:(e,n)=\u003e{if(e.layer!==n.layer||!((e,n)=\u003e{const o=Math.hypot(n.x-e.x,n.y-e.y);if(0===o)return[];const r=-(n.y-e.y)/o*t.side*t.centerlineSpacing/2,s=(n.x-e.x)/o*t.side*t.centerlineSpacing/2,a=i(e,t.start),c=i(n,t.end),l=t.terminalFanout?a\u0026\u0026c?\"both\":a?\"start\":c?\"end\":null:null,d=a\u0026\u0026t.terminalFanout?t.firstStartTerminal:{x:e.x+r,y:e.y+s},h=c\u0026\u0026t.terminalFanout?t.firstEndTerminal:{x:n.x+r,y:n.y+s},u=a\u0026\u0026t.terminalFanout?t.secondStartTerminal:{x:e.x-r,y:e.y-s},p=c\u0026\u0026t.terminalFanout?t.secondEndTerminal:{x:n.x-r,y:n.y-s};return[{start:d,end:h,layer:e.layer,width:t.firstWidth,connectionName:t.firstConnectionName,terminal:l},{start:u,end:p,layer:e.layer,width:t.secondWidth,connectionName:t.secondConnectionName,terminal:l}]})(e,n).every(l))return!1;if(t.terminalFanout||void 0===t.terminalMiterMargin)return!0;const o={x:n.x-e.x,y:n.y-e.y};return!(i(e,t.start)\u0026\u0026!c(e,o,\"start\"))\u0026\u0026!(i(n,t.end)\u0026\u0026!c(n,o,\"end\"))},isTerminalFanoutValid:c,isViaValid:(e,n,o)=\u003e{const r=Math.hypot(o.x,o.y);if(r\u003c=1e-10)throw new Error(\"PostProcessingSolver: cannot orient a coupled via on a zero-length spine\");const s=OG(e.layer,n,t.layerCount),a=-o.y/r*t.side*t.centerlineSpacing/2,c=o.x/r*t.side*t.centerlineSpacing/2,l=i(e,t.start)?\"start\":i(e,t.end)?\"end\":null;return[{x:e.x+a,y:e.y+c,layers:s,diameter:t.firstViaDiameter,connectionName:t.firstConnectionName,terminal:l},{x:e.x-a,y:e.y-c,layers:s,diameter:t.secondViaDiameter,connectionName:t.secondConnectionName,terminal:l}].every(d)}}},ZG=(t,e,n)=\u003e{const o=1e-7,i=(t,e)=\u003e{const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}},r=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},s=(t,e,n)=\u003e{const o=EG(e,n);return uG(t,n).includes(o)},a=(t,e,n)=\u003e{const a=t.width/2;if(t.start.x-a\u003ce.bounds.minX-o||t.start.x+a\u003ee.bounds.maxX+o||t.start.y-a\u003ce.bounds.minY-o||t.start.y+a\u003ee.bounds.maxY+o||t.end.x-a\u003ce.bounds.minX-o||t.end.x+a\u003ee.bounds.maxX+o||t.end.y-a\u003ce.bounds.minY-o||t.end.y+a\u003ee.bounds.maxY+o)return!1;for(const n of e.obstacles){if(!s(n,t.layer,e.layerCount))continue;const r=\"both\"===t.terminal?[t.start,t.end]:\"start\"===t.terminal?[t.start]:\"end\"===t.terminal?[t.end]:[];if(!(n.connectedTo.includes(t.connectionName)\u0026\u0026r.some(t=\u003e{const e=i(t,n);return Math.abs(e.x)\u003c=n.width/2+o\u0026\u0026Math.abs(e.y)\u003c=n.height/2+o}))\u0026\u0026GG(t,n,a+(e.minTraceToPadEdgeClearance??t.width)))return!1}for(const e of n.segments){if(e.layer!==t.layer)continue;const n=t.width/2+e.width/2+Math.max(t.width,e.width);if(cG(t.start,t.end,e.start,e.end)\u003cn-o)return!1}for(const e of n.vias){if(!e.layers.includes(t.layer))continue;const n=t.width/2+e.diameter/2+t.width;if(r(e,t.start,t.end)\u003cn-o)return!1}return!0},c=(t,e,n)=\u003e{const a=t.diameter/2;if(t.x-a\u003ce.bounds.minX-o||t.x+a\u003ee.bounds.maxX+o||t.y-a\u003ce.bounds.minY-o||t.y+a\u003ee.bounds.maxY+o)return!1;for(const n of e.obstacles){if(!t.layers.some(t=\u003es(n,t,e.layerCount)))continue;const r=i(t,n);if(!(null!==t.terminal\u0026\u0026n.connectedTo.includes(t.connectionName)\u0026\u0026Math.abs(r.x)\u003c=n.width/2+o\u0026\u0026Math.abs(r.y)\u003c=n.height/2+o)\u0026\u0026Math.abs(r.x)\u003c=n.width/2+a+t.diameter\u0026\u0026Math.abs(r.y)\u003c=n.height/2+a+t.diameter)return!1}for(const e of n.segments){if(!t.layers.includes(e.layer))continue;const n=a+e.width/2+Math.max(t.diameter,e.width);if(r(t,e.start,e.end)\u003cn-o)return!1}for(const e of n.vias){if(!e.layers.some(e=\u003et.layers.includes(e)))continue;const n=a+e.diameter/2+Math.max(t.diameter,e.diameter);if(Math.hypot(t.x-e.x,t.y-e.y)\u003cn-o)return!1}return!0},l=t=\u003e{for(let e=0;e\u003ct.segments.length;e++){const n=t.segments[e];for(let i=e+2;i\u003ct.segments.length;i++){const r=t.segments[i];if(n.layer!==r.layer)continue;if(!(t.segments.slice(e+1,i).reduce((t,e)=\u003et+Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),0)\u003c=n.width+r.width+o)\u0026\u0026cG(n.start,n.end,r.start,r.end)\u003cn.width/2+r.width/2-o)return!0}}for(const e of t.vias)for(const n of t.segments){if(!e.layers.includes(n.layer))continue;if(!(Math.hypot(e.x-n.start.x,e.y-n.start.y)\u003c=o||Math.hypot(e.x-n.end.x,e.y-n.end.y)\u003c=o)\u0026\u0026r(e,n.start,n.end)\u003ce.diameter/2+n.width/2-o)return!0}return!1},d=((t,e)=\u003e{const n=[],o=[];for(const i of t){const t=DG(i,e);n.push(...t.segments),o.push(...t.vias)}return{segments:n,vias:o}})(n.immutableTraces,n.layerCount);if(!((t,e)=\u003e{for(const n of t.segments)for(const t of e.segments){if(n.layer!==t.layer)continue;const e=n.width/2+t.width/2;if(cG(n.start,n.end,t.start,t.end)\u003ce-o)return!1}for(const[n,i]of[[t.vias,e.segments],[e.vias,t.segments]])for(const t of n)for(const e of i)if(t.layers.includes(e.layer)\u0026\u0026r(t,e.start,e.end)\u003ct.diameter/2+e.width/2-o)return!1;for(const n of t.vias)for(const t of e.vias)if(n.layers.some(e=\u003et.layers.includes(e))\u0026\u0026Math.hypot(n.x-t.x,n.y-t.y)\u003cn.diameter/2+t.diameter/2-o)return!1;return!0})(t,e)||l(t)||l(e))return!1;for(const o of[t,e])if(o.segments.some(t=\u003e!a(t,n,d))||o.vias.some(t=\u003e!c(t,n,d)))return!1;return!0},qG=[{x:1,y:0},{x:1,y:1},{x:0,y:1},{x:-1,y:1},{x:-1,y:0},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1}],JG=class{constructor(t){this.input=t;const{bounds:e,grid:n}=t,o={minX:e.minX+n.outerPerimeterWidth,maxX:e.maxX-n.outerPerimeterWidth,minY:e.minY+n.outerPerimeterWidth,maxY:e.maxY-n.outerPerimeterWidth},i=this.createAxis(e.minX,e.maxX,n.outerGridStep,[o.minX,o.maxX]),r=this.createAxis(e.minY,e.maxY,n.outerGridStep,[o.minY,o.maxY]),s=this.createAxis(o.minX,o.maxX,n.innerGridStep,[],t.start.x),a=this.createAxis(o.minY,o.maxY,n.innerGridStep,[],t.start.y),c=this.createGrid(i,r,t=\u003et.x\u003c=o.minX||t.x\u003e=o.maxX||t.y\u003c=o.minY||t.y\u003e=o.maxY),l=this.createGrid(s,a,()=\u003e!0);this.connectLocalNeighbors(c),this.connectLocalNeighbors(l);for(const t of[\"left\",\"right\",\"bottom\",\"top\"])this.connectBoundaries(t,c,l,o);const d=this.nodes.map((t,e)=\u003ee);this.connectEndpoint(t.start,d),this.connectEndpoint(t.end,d)}input;nodes=[];nodeIdByPoint=new Map;endpointNodeIdByPoint=new Map;getPlanarNeighbors(t){const e=this.endpointNodeIdByPoint.get(this.exactKeyFor(t))??this.nodeIdByPoint.get(this.keyFor(t));if(void 0===e)throw new Error(`PostProcessingSolver: coupled path point (${t.x}, ${t.y}) is not on the composite grid`);return[...this.nodes[e].neighborIds].map(e=\u003e({...this.nodes[e].point,layer:t.layer}))}getNodeCount(){return this.nodes.length}getSearchStateCountUpperBound(t){const e=this.nodes.reduce((t,e)=\u003et+e.neighborIds.size,0)*t+1;if(!Number.isSafeInteger(e))throw new Error(\"PostProcessingSolver: composite-grid search-state bound exceeds the safe integer range\");return e}createAxis(t,e,n,o,i=t){const r=[t,e,...o].map(t=\u003e({value:t,fixed:!0}));for(let o=Math.ceil((t-i)/n);i+o*n\u003ce-1e-8;o++)r.push({value:i+o*n,fixed:!1});r.sort((t,e)=\u003et.value-e.value||Number(e.fixed)-Number(t.fixed));const s=[];for(const t of r){const e=s.at(-1);!e||Math.abs(t.value-e.value)\u003e1e-8?s.push(t):t.fixed\u0026\u0026!e.fixed\u0026\u0026(s[s.length-1]=t)}return s.map(t=\u003et.value)}createGrid(t,e,n){return e.map(e=\u003et.map(t=\u003e{const o={x:t,y:e};return n(o)?this.addNode(o):null}))}connectLocalNeighbors(t){for(let e=0;e\u003ct.length;e++)for(let n=0;n\u003c(t[e]?.length??0);n++){const o=t[e][n];if(null!==o)for(const i of qG){const r=t[e+i.y]?.[n+i.x];null!=r\u0026\u0026this.connect(o,r)}}}connectBoundaries(t,e,n,o){const i=\"left\"===t?o.minX:\"right\"===t?o.maxX:\"bottom\"===t?o.minY:o.maxY,r=\"left\"===t||\"right\"===t,s=t=\u003eMath.abs((r?t.x:t.y)-i)\u003c=1e-8,a=t=\u003e{const e=new Set;for(const n of t)for(const t of n)null!==t\u0026\u0026s(this.nodes[t].point)\u0026\u0026e.add(t);return[...e].sort((t,e)=\u003e{const n=this.nodes[t].point,o=this.nodes[e].point;return(r?n.y-o.y:n.x-o.x)||t-e})},c=a(e),l=a(n);if(0===c.length||0===l.length)throw new Error(`PostProcessingSolver: composite grid has no ${t} boundary bridge candidates`);for(const t of c)this.connect(t,this.findNearestAlongBoundary(t,l,r));for(const t of l)this.connect(t,this.findNearestAlongBoundary(t,c,r))}findNearestAlongBoundary(t,e,n){const o=this.nodes[t].point;let i=e[0],r=Number.POSITIVE_INFINITY;for(const t of e){const e=this.nodes[t].point,s=Math.abs(n?o.y-e.y:o.x-e.x);(s\u003cr-1e-8||Math.abs(s-r)\u003c=1e-8\u0026\u0026t\u003ci)\u0026\u0026(r=s,i=t)}return i}connectEndpoint(t,e){const n=this.nodeIdByPoint.get(this.keyFor(t)),o=void 0===n?null:this.nodes[n].point,i=o?.x===t.x\u0026\u0026o.y===t.y?n:this.nodes.push({point:{x:t.x,y:t.y},neighborIds:new Set})-1;this.endpointNodeIdByPoint.set(this.exactKeyFor(t),i);const r=(t,n)=\u003e{const o=this.nodes[t].point,i=e.filter(e=\u003ee!==t).map(t=\u003e({nodeId:t,distance:Math.hypot(this.nodes[t].point.x-o.x,this.nodes[t].point.y-o.y)})).filter(({distance:t})=\u003et\u003e1e-10).sort((t,e)=\u003et.distance-e.distance||t.nodeId-e.nodeId).slice(0,n);if(0===i.length)throw new Error(\"PostProcessingSolver: composite grid has no endpoint connection candidates\");for(const{nodeId:e}of i)this.connect(t,e)};r(i,8);for(const e of qG){const n={x:t.x+e.x*this.input.grid.innerGridStep,y:t.y+e.y*this.input.grid.innerGridStep};if(n.x\u003cthis.input.bounds.minX||n.x\u003ethis.input.bounds.maxX||n.y\u003cthis.input.bounds.minY||n.y\u003ethis.input.bounds.maxY)continue;const o=this.addNode(n);this.connect(i,o),r(o,4)}}addNode(t){const e=this.keyFor(t),n=this.nodeIdByPoint.get(e);if(void 0!==n)return n;const o=this.nodes.length;return this.nodes.push({point:{x:t.x,y:t.y},neighborIds:new Set}),this.nodeIdByPoint.set(e,o),o}connect(t,e){if(t===e)return;const n=this.nodes[t],o=this.nodes[e];n.neighborIds.add(e),o.neighborIds.add(t)}keyFor(t){const e=Object.is(t.x,-0)?0:t.x,n=Object.is(t.y,-0)?0:t.y;return`${e.toFixed(12)}:${n.toFixed(12)}`}exactKeyFor(t){return`${Object.is(t.x,-0)?0:t.x}:${Object.is(t.y,-0)?0:t.y}`}},KG=class{constructor(t){if(this.input=t,this.startLayer=EG(t.start.layer,t.layerCount),this.endLayer=EG(t.end.layer,t.layerCount),this.grid=new JG(t),this.maxSearchStates=this.grid.getSearchStateCountUpperBound(t.layerCount),this.exploredStateLimit=Math.min(this.maxSearchStates,2e4),this.startLayer\u003c0||this.endLayer\u003c0)return this.queue=[],void(this.status=\"exhausted\");const e={point:t.start,direction:null,cost:0,estimate:this.estimate(t.start),parent:null,sequence:0};this.queue=[e],this.bestCosts.set(this.keyFor(t.start,null),0)}input;queue;bestCosts=new Map;startLayer;endLayer;grid;maxSearchStates;exploredStateLimit;current=null;result=null;status=\"searching\";explored=0;nextSequence=1;isComplete(){return\"searching\"!==this.status}getPath(){return this.result}getPreviewPath(){return this.current?this.createPath(this.current):[this.input.start]}getExploredCount(){return this.explored}getProgress(){return\"searching\"!==this.status?1:Math.min(.99,this.explored/this.exploredStateLimit)}getGridNodeCount(){return this.grid.getNodeCount()}step(){if(\"searching\"!==this.status)return;const t=this.popQueue();if(!t)return void(this.status=\"exhausted\");const e=this.bestCosts.get(this.keyFor(t.point,t.direction));if(void 0===e)throw new Error(\"PostProcessingSolver: coupled path queue contains an untracked state\");if(t.cost\u003ee+1e-10)0===this.queue.length\u0026\u0026(this.status=\"exhausted\");else{if(this.current=t,this.explored++,this.explored\u003ethis.maxSearchStates)throw new Error(`PostProcessingSolver: coupled path search exceeded its ${this.maxSearchStates}-state graph invariant limit`);if(this.isEnd(t.point)){const e=this.createPath(t);return e[e.length-1]=this.input.end,this.result=this.simplifyPath(e),void(this.status=\"found\")}this.explored\u003e=this.exploredStateLimit?this.status=\"exhausted\":(this.enqueuePlanarNeighbors(t),this.enqueueViaNeighbors(t),0===this.queue.length\u0026\u0026(this.status=\"exhausted\"))}}isEnd(t){return t.layer===this.input.end.layer\u0026\u0026t.x===this.input.end.x\u0026\u0026t.y===this.input.end.y}estimate(t){return Math.hypot(t.x-this.input.end.x,t.y-this.input.end.y)+3*Math.abs(EG(t.layer,this.input.layerCount)-this.endLayer)}keyFor(t,e){return`${Object.is(t.x,-0)?0:t.x}:${Object.is(t.y,-0)?0:t.y}:${t.layer}:${e?.key??\"start\"}`}createDirection(t,e){const n=e.x-t.x,o=e.y-t.y,i=Math.hypot(n,o);if(i\u003c=1e-10)throw new Error(\"PostProcessingSolver: composite grid produced a zero-length planar edge\");const r=n/i,s=o/i;return{x:r,y:s,key:`${r.toFixed(6)}:${s.toFixed(6)}`}}createPath(t){const e=[];let n=t;for(;n;)e.push(n.point),n=n.parent;return e.reverse()}simplifyPath(t){return t.filter((e,n)=\u003e{if(0===n||n===t.length-1)return!0;const o=t[n-1],i=t[n+1],r={x:e.x-o.x,y:e.y-o.y},s={x:i.x-e.x,y:i.y-e.y},a=r.x*s.y-r.y*s.x,c=Math.hypot(r.x,r.y)*Math.hypot(s.x,s.y);return Math.abs(a)\u003e1e-10*c||e.layer!==o.layer||e.layer!==i.layer})}hasHigherQueuePriority(t,e){return t.estimate!==e.estimate?t.estimate\u003ce.estimate:t.cost!==e.cost?t.cost\u003ce.cost:t.point.x!==e.point.x?t.point.x\u003ce.point.x:t.point.y!==e.point.y?t.point.y\u003ce.point.y:t.point.layer!==e.point.layer?t.point.layer\u003ce.point.layer:t.sequence\u003ce.sequence}pushQueue(t){this.queue.push(t);let e=this.queue.length-1;for(;e\u003e0;){const n=Math.floor((e-1)/2),o=this.queue[n];if(!this.hasHigherQueuePriority(t,o))break;this.queue[e]=o,e=n}this.queue[e]=t}popQueue(){const t=this.queue[0],e=this.queue.pop();if(!t||!e||0===this.queue.length)return t;let n=0;for(;;){const t=2*n+1;if(t\u003e=this.queue.length)break;const o=t+1;let i=t;o\u003cthis.queue.length\u0026\u0026this.hasHigherQueuePriority(this.queue[o],this.queue[t])\u0026\u0026(i=o);const r=this.queue[i];if(!this.hasHigherQueuePriority(r,e))break;this.queue[n]=r,n=i}return this.queue[n]=e,t}enqueuePlanarNeighbors(t){for(const e of this.grid.getPlanarNeighbors(t.point)){if(!this.input.isEdgeValid(t.point,e))continue;const n=this.createDirection(t.point,e),o=null===t.direction||t.direction.key===n.key?0:.18,i=t.cost+Math.hypot(e.x-t.point.x,e.y-t.point.y)+o,r=this.keyFor(e,n);(this.bestCosts.get(r)??Number.POSITIVE_INFINITY)\u003c=i||(this.bestCosts.set(r,i),this.pushQueue({point:e,direction:n,cost:i,estimate:i+this.estimate(e),parent:t,sequence:this.nextSequence++}))}}enqueueViaNeighbors(t){if(!t.direction)return;const e=EG(t.point.layer,this.input.layerCount);for(const n of[e-1,e+1]){if(n\u003c0||n\u003e=this.input.layerCount)continue;const e=AG(n,this.input.layerCount);if(!this.input.isViaValid(t.point,e,t.direction))continue;const o={...t.point,layer:e},i=t.cost+4,r=this.keyFor(o,t.direction);(this.bestCosts.get(r)??Number.POSITIVE_INFINITY)\u003c=i||(this.bestCosts.set(r,i),this.pushQueue({point:o,direction:t.direction,cost:i,estimate:i+this.estimate(o),parent:t,sequence:this.nextSequence++}))}}},QG=t=\u003e{const e=Math.min(t.bounds.maxX-t.bounds.minX,t.bounds.maxY-t.bounds.minY),n=t.config?.innerGridStep??t.defaultInnerGridStep,o=t.config?.outerGridStep??4*n,i=t.config?.outerPerimeterWidth??Math.min(o,e/4);if(!Number.isFinite(n)||n\u003c1e-4)throw new Error(\"PostProcessingSolver: routingGrid.innerGridStep must be finite and at least 0.0001\");if(!Number.isFinite(o)||o\u003c=n)throw new Error(\"PostProcessingSolver: routingGrid.outerGridStep must be finite and greater than innerGridStep\");if(!Number.isFinite(i)||i\u003c=0||2*i\u003e=e)throw new Error(\"PostProcessingSolver: routingGrid.outerPerimeterWidth must be finite, positive, and less than half the smaller board extent\");const r=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY;if((Math.ceil(r/o)+4)*(Math.ceil(s/o)+4)+(Math.ceil((r-2*i)/n)+2)*(Math.ceil((s-2*i)/n)+2)+18\u003e25e4)throw new VG(\"PostProcessingSolver: valid input exceeds the 250000-node optimization grid capacity\");return{innerGridStep:n,outerGridStep:o,outerPerimeterWidth:i}},tU=t=\u003e{const e=-t.pathDirection.y,n=t.pathDirection.x,o=Math.tan(t.maximumTurnDegrees*Math.PI/180),i=Math.max(0,...t.lanes.map(({point:i,polarity:r})=\u003e{const s=i.x-t.anchor.x,a=i.y-t.anchor.y,c=s*t.escapeDirection.x+a*t.escapeDirection.y,l=s*e+a*n,d=r*t.side*t.centerlineSpacing/2;return c+Math.abs(l-d)/o})),r=t.maxUncoupledLength??i;if(i\u003er+1e-8)return null;const s=Math.max(.05,Math.min(.25,t.searchStep/2)),a=Math.max(1,Math.ceil((r-i)/s)+1);for(let o=0;o\u003ca;o++){const a=Math.min(r,i+o*s),c={x:t.anchor.x+t.escapeDirection.x*a,y:t.anchor.y+t.escapeDirection.y*a,layer:t.anchor.layer};if(t.lanes.every(({point:o,polarity:i})=\u003e{const r=i*t.side*t.centerlineSpacing/2,s=c.x+e*r,a=c.y+n*r;return void 0===t.maxUncoupledLength||Math.hypot(s-o.x,a-o.y)\u003c=t.maxUncoupledLength+1e-8})\u0026\u0026t.isValid(c))return c}return null},eU=[.75,.5,1,.25,1.25],nU=100,oU=class{constructor(t){this.input=t,this.pairName=t.pair.connectionNames.join(\"/\"),this.prepared=this.prepare()}input;pairName;prepared;candidates=[];result=null;search=null;nextAttempt=0;exploredNodeCount=0;isComplete(){return null!==this.result}getResult(){if(!this.result)throw new Error(`PostProcessingSolver: differential pair ${this.pairName} is not complete`);return this.result}getPreviewPath(){return this.search?.getPreviewPath()??null}getProgress(){if(this.result)return 1;const t=this.prepared.attempts.length,e=this.search?.getProgress()??0;return Math.min(.99,(this.nextAttempt+e)/t)}getStats(){return{phase:this.search?\"searching\":\"candidate-selection\",pair:this.pairName,attemptIndex:this.nextAttempt,attemptCount:this.prepared.attempts.length,exploredNodeCount:this.exploredNodeCount+(this.search?.getExploredCount()??0),gridNodeCount:this.search?.getGridNodeCount()??0,acceptedCandidateCount:this.candidates.length}}step(){if(this.result)return;const t=this.prepared;if(!this.search){const e=t.attempts[this.nextAttempt];return e?void(this.search=new KG(e.input)):void this.complete()}if(this.search.step(),!this.search.isComplete())return;const e=this.search.getPath();this.exploredNodeCount+=this.search.getExploredCount();const n=t.attempts[this.nextAttempt];if(!n)throw new Error(`PostProcessingSolver: differential pair ${this.pairName} lost its active attempt`);if(this.search=null,this.nextAttempt++,!e)return;const o=(t=\u003e{const e=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y)\u003c=1e-8;if(t.path.length\u003c2)throw new Error(\"PostProcessingSolver: coupled path has fewer than two stations\");const n=(n,o)=\u003e{for(let i=n+o;i\u003e=0\u0026\u0026i\u003ct.path.length;i+=o){const o=t.path[i];if(!e(o,t.path[n]))return o}return null},o=e=\u003e{const o=t.path[e],i=n(e,-1),r=n(e,1),s=(t,e)=\u003e{const n=e.x-t.x,o=e.y-t.y,i=Math.hypot(n,o);if(i\u003c=1e-10)throw new Error(\"PostProcessingSolver: cannot offset a zero-length spine\");return{x:-o/i,y:n/i}},a=t.side*t.centerlineSpacing/2;if(!i||!r){const t=s(i??o,r??o);return{x:t.x*a,y:t.y*a}}if(t.terminalFanout\u0026\u00261===e)return s(i,o);if(t.terminalFanout\u0026\u0026e===t.path.length-2)return s(o,r);if(t.terminalFanout\u0026\u0026t.path[e+1]?.layer!==o.layer)return s(i,o);const c=s(i,o),l=s(o,r),d={x:c.x+l.x,y:c.y+l.y},h=Math.hypot(d.x,d.y);if(h\u003c=1e-10)return null;const u=d.x/h,p=d.y/h,m=a/(u*c.x+p*c.y);return{x:u*m,y:p*m}},i=t.first.points[0],r=t.first.points.at(-1),s=t.reverseSecond?t.second.points.at(-1):t.second.points[0],a=t.reverseSecond?t.second.points[0]:t.second.points.at(-1),c=[[{route_type:\"wire\",x:i.x,y:i.y,width:i.width,layer:i.layer}],[{route_type:\"wire\",x:s.x,y:s.y,width:s.width,layer:s.layer}]],l=[t.first.transitions[0],t.second.transitions[0]];let d=0;const h=t.terminalFanout?1:0,u=t.path.length-2,p=t.path[u],m=t.path[u-1],g=t.terminalFanout\u0026\u0026p?.layer===r.layer\u0026\u0026m?.layer===p.layer,f=t.terminalFanout?g?u-1:t.path.length-1:t.path.length;for(let n=h;n\u003cf;n++){const i=t.path[n],r=o(n);if(!r)return null;for(const o of[0,1]){const s=0===o?1:-1,a={x:i.x+r.x*s,y:i.y+r.y*s},d=c[o],h=t.path[n-1];if(h\u0026\u0026h.layer!==i.layer){if(!e(h,i))throw new Error(\"PostProcessingSolver: a coupled layer transition moved in the plane\");const n=[...d].reverse().find(t=\u003e\"wire\"===t.route_type);if(!n)throw new Error(\"PostProcessingSolver: generated via has no preceding wire\");const r=l[o];d.push({route_type:\"via\",x:n.x,y:n.y,from_layer:h.layer,to_layer:i.layer,via_diameter:r?.via_diameter??(0===o?t.first.viaDiameter:t.second.viaDiameter),...void 0!==r?.via_hole_diameter?{via_hole_diameter:r.via_hole_diameter}:{}}),d.push({route_type:\"wire\",x:n.x,y:n.y,width:0===o?t.first.width:t.second.width,layer:i.layer})}else{const n=d.at(-1);\"wire\"===n?.route_type\u0026\u0026e(n,a)\u0026\u0026n.layer===i.layer||d.push({route_type:\"wire\",...a,width:0===o?t.first.width:t.second.width,layer:i.layer})}}t.path[n-1]?.layer!==i.layer\u0026\u0026n\u003e0\u0026\u0026d++}const y=(e,n)=\u003e{const o=e.at(-1);if(!o||\"wire\"!==o.route_type)throw new Error(\"PostProcessingSolver: terminal fanout has no preceding wire\");const i=e.at(-2);let r=!1;if(\"wire\"===i?.route_type\u0026\u0026i.layer===o.layer\u0026\u0026o.layer===n.layer){const t={x:o.x-i.x,y:o.y-i.y},e={x:n.x-o.x,y:n.y-o.y},s=Math.hypot(t.x,t.y),a=Math.hypot(e.x,e.y);if(s\u003e1e-8\u0026\u0026a\u003e1e-8\u0026\u0026Math.abs(t.x*e.x+t.y*e.y)\u003c=1e-8){const e={x:o.x-t.x/s*a,y:o.y-t.y/s*a};(e.x-i.x)*(t.x/s)+(e.y-i.y)*(t.y/s)\u003e1e-8\u0026\u0026(o.x=e.x,o.y=e.y,r=!0)}}t.terminalFanout\u0026\u0026!r\u0026\u0026o.x!==n.x\u0026\u0026o.y!==n.y\u0026\u0026e.push({route_type:\"wire\",x:n.x,y:o.y,width:n.width,layer:n.layer}),e.push({route_type:\"wire\",x:n.x,y:n.y,width:n.width,layer:n.layer})};y(c[0],r),y(c[1],a),t.reverseSecond\u0026\u0026(c[1]=c[1].reverse().map(t=\u003e\"via\"===t.route_type?{...t,from_layer:t.to_layer,to_layer:t.from_layer}:t));const _=(t,e)=\u003e{const n=t.filter(t=\u003e\"wire\"===t.route_type);for(const t of n)delete t.start_pcb_port_id,delete t.end_pcb_port_id;e.startPortId\u0026\u0026(n[0].start_pcb_port_id=e.startPortId),e.endPortId\u0026\u0026(n.at(-1).end_pcb_port_id=e.endPortId)};_(c[0],t.first),_(c[1],t.second);const b={...t.first.source,route:c[0]},x={...t.second.source,route:c[1]};return{first:b,second:x,firstParsed:LG(b,t.layerCount),secondParsed:LG(x,t.layerCount),edgeGap:t.edgeGap,centerlineDistance:t.centerlineSpacing,bendCount:Math.max(0,t.path.length-d-2),viaPairCount:d}})({first:t.first,second:t.second,reverseSecond:t.reverseSecond,path:e,centerlineSpacing:n.edgeGap+t.first.width/2+t.second.width/2,edgeGap:n.edgeGap,side:n.side,layerCount:this.input.layerCount,terminalFanout:t.terminalFanout});o\u0026\u0026ZG(o.firstParsed,o.secondParsed,t.context)\u0026\u0026this.candidates.push(o)}prepare(){const t=this.input.traces.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:t})=\u003et.connection_name===this.input.pair.connectionNames[0]),e=this.input.traces.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:t})=\u003et.connection_name===this.input.pair.connectionNames[1]);if(1!==t.length||1!==e.length)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"trace-resolution-failure\",message:\"must resolve each connection_name to exactly one non-branching trace\"});if(t[0].index===e[0].index)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"trace-resolution-failure\",message:\"resolved both members to one trace\"});let n,o;try{n=LG(t[0].trace,this.input.layerCount),o=LG(e[0].trace,this.input.layerCount)}catch(t){throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"invalid-routed-geometry\",message:`has unsupported or invalid routed geometry: ${t instanceof Error?t.message:String(t)}`})}const i=n.points[0],r=n.points.at(-1),s=Math.hypot(i.x-o.points[0].x,i.y-o.points[0].y)+Math.hypot(r.x-o.points.at(-1).x,r.y-o.points.at(-1).y),a=Math.hypot(i.x-o.points.at(-1).x,i.y-o.points.at(-1).y)+Math.hypot(r.x-o.points[0].x,r.y-o.points[0].y)+1e-8\u003cs,c=a?o.points.at(-1):o.points[0],l=a?o.points[0]:o.points.at(-1);if(i.layer!==c.layer||r.layer!==l.layer)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"terminal-layer-mismatch\",message:\"does not have common paired layers at both terminal stations\"});const d={x:(i.x+c.x)/2,y:(i.y+c.y)/2,layer:i.layer},h={x:(r.x+l.x)/2,y:(r.y+l.y)/2,layer:r.layer},u=Math.hypot(h.x-d.x,h.y-d.y);if(u\u003c1e-6)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"coincident-terminal-midpoints\",message:\"has coincident terminal-pair midpoints\"});const p={x:-(h.y-d.y)/u,y:(h.x-d.x)/u},m=i.x-c.x,g=i.y-c.y,f=m*p.x+g*p.y\u003e=0?1:-1,y=(t,e)=\u003e{const n=t.x-e.x,o=t.y-e.y,i=Math.hypot(n,o);return i\u003e1e-8\u0026\u0026Math.abs(n*p.x+o*p.y)/i\u003c.5},_=y(i,c)\u0026\u0026y(r,l),b={x:p.y,y:-p.x},x=[i,c].some(t=\u003e(t.x-d.x)*b.x+(t.y-d.y)*b.y\u003e1e-8),v={immutableTraces:this.input.traces.filter((n,o)=\u003eo!==t[0].index\u0026\u0026o!==e[0].index),obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,minTraceToPadEdgeClearance:this.input.minTraceToPadEdgeClearance},S=(t=\u003e{const{minimumCenterlineDistance:e,maximumCenterlineDistance:n}=t;if(void 0===e\u0026\u0026void 0===n)return t.legacyCenterlineDistances;const o=[...void 0!==e\u0026\u0026void 0!==n?[(e+n)/2,e,n,e-.25,n+.25]:void 0!==e?[e,e+.25,e+.5,e-.25,e+1]:[n,n-.25,n-.5,n+.25,n-1],...t.legacyCenterlineDistances];return o.filter((e,n)=\u003ee\u003et.minimumPhysicalDistance\u0026\u0026o.findIndex(t=\u003eMath.abs(t-e)\u003c1e-8)===n)})({minimumCenterlineDistance:this.input.pair.minimumCenterlineDistance,maximumCenterlineDistance:this.input.pair.maximumCenterlineDistance,minimumPhysicalDistance:n.width/2+o.width/2,legacyCenterlineDistances:eU.map(t=\u003et+n.width/2+o.width/2)}).flatMap(t=\u003e{const e=t-n.width/2-o.width/2;return[f,1===f?-1:1].flatMap(s=\u003e{const a=QG({config:this.input.routingGrid,bounds:this.input.bounds,defaultInnerGridStep:Math.max(.25,Math.min(.5,t/2))}),u=(e,a)=\u003eUG({...v,start:e,end:a,firstConnectionName:n.source.connection_name,secondConnectionName:o.source.connection_name,firstStartTerminal:i,firstEndTerminal:r,secondStartTerminal:c,secondEndTerminal:l,firstWidth:n.width,secondWidth:o.width,firstViaDiameter:n.transitions[0]?.via_diameter??n.viaDiameter,secondViaDiameter:o.transitions[0]?.via_diameter??o.viaDiameter,centerlineSpacing:t,side:s,terminalFanout:_,terminalMiterMargin:void 0===this.input.pair.maxUncoupledLength?void 0:t/2});let m=void 0===this.input.pair.maxUncoupledLength?((t,e)=\u003e{if(!x||_)return d;const n=[{terminal:i,offset:e*t/2},{terminal:c,offset:-e*t/2}],o=Math.tan(55*Math.PI/180),r=Math.max(...n.map(({terminal:t,offset:e})=\u003e{const n=(t.x-d.x)*b.x+(t.y-d.y)*b.y,i=(t.x-d.x)*p.x+(t.y-d.y)*p.y;return n+Math.abs(i-e)/o}));return{x:d.x+b.x*r,y:d.y+b.y*r,layer:d.layer}})(t,s):d,g=h;if(!_\u0026\u0026void 0!==this.input.pair.maxUncoupledLength){const e=u(d,h),n=tU({anchor:d,escapeDirection:b,pathDirection:b,centerlineSpacing:t,side:s,lanes:[{point:i,polarity:1},{point:c,polarity:-1}],maxUncoupledLength:this.input.pair.maxUncoupledLength,maximumTurnDegrees:55,searchStep:a.innerGridStep,isValid:t=\u003ee.isTerminalFanoutValid(t,b,\"start\")}),o=tU({anchor:h,escapeDirection:{x:-b.x,y:-b.y},pathDirection:b,centerlineSpacing:t,side:s,lanes:[{point:r,polarity:1},{point:l,polarity:-1}],maxUncoupledLength:this.input.pair.maxUncoupledLength,maximumTurnDegrees:45,searchStep:a.innerGridStep,isValid:t=\u003ee.isTerminalFanoutValid(t,b,\"end\")});if(!n||!o)return[];m=n,g=o;if((g.x-m.x)*b.x+(g.y-m.y)*b.y\u003c=a.innerGridStep)return[]}const f=u(m,g);return[{edgeGap:e,side:s,input:{start:m,end:g,bounds:this.input.bounds,layerCount:this.input.layerCount,grid:a,...f}}]})});return{first:n,second:o,reverseSecond:a,terminalFanout:_,context:v,attempts:S}}complete(){if(0===this.candidates.length)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"no-valid-candidate\",message:\"could not be improved without violating bounds, copper clearance, or coupled-via constraints\"});this.candidates.sort((t,e)=\u003ethis.score(t)-this.score(e)||t.edgeGap-e.edgeGap),this.result={status:\"accepted\",candidate:this.candidates[0]}}score(t){return(void 0!==this.input.pair.minimumCenterlineDistance||void 0!==this.input.pair.maximumCenterlineDistance?Math.max(0,(this.input.pair.minimumCenterlineDistance??Number.NEGATIVE_INFINITY)-t.centerlineDistance)*nU+Math.max(0,t.centerlineDistance-(this.input.pair.maximumCenterlineDistance??Number.POSITIVE_INFINITY))*nU:t.edgeGap\u003c.5?(.5-t.edgeGap)*nU:t.edgeGap\u003e1?(t.edgeGap-1)*nU:0)+FG(t.firstParsed)+FG(t.secondParsed)+.15*t.bendCount+8*t.viaPairCount}},iU=t=\u003e{const e={lines:[],points:[],rects:[],circles:[]};e.rects.push({center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,fill:\"rgba(30, 70, 120, 0.04)\",stroke:\"rgba(30, 70, 120, 0.55)\",layer:`z${Array.from({length:t.layerCount},(t,e)=\u003ee).join(\",\")}`});for(const n of t.obstacles){const o=uG(n,t.layerCount);e.rects.push({center:n.center,width:n.width,height:n.height,ccwRotationDegrees:n.ccwRotationDegrees,fill:\"rgba(220, 60, 60, 0.16)\",stroke:\"rgba(190, 40, 40, 0.75)\",layer:`z${o.join(\",\")}`})}for(let n=0;n\u003c(t.previewPath?.length??0)-1;n++){const o=t.previewPath[n],i=t.previewPath[n+1];if(o.layer!==i.layer)continue;const r=EG(o.layer,t.layerCount);e.lines.push({points:[o,i],strokeColor:\"#16a34a\",strokeWidth:.08,strokeDash:[.18,.12],layer:`z${r}`})}for(const n of t.traces){if(t.activeConnectionNames?.includes(n.connection_name))continue;const o=\"#2563eb\";let i=null;for(const r of n.route)if(\"wire\"===r.route_type){if(i\u0026\u0026i.layer===r.layer){const n=EG(r.layer,t.layerCount);e.lines.push({points:[i,r],strokeColor:o,strokeWidth:Math.max(i.width,r.width),...0===n?{}:{strokeDash:[.2,.16]},layer:`z${n}`})}i=r}else if(\"via\"===r.route_type){const n=OG(r.from_layer,r.to_layer,t.layerCount).map(e=\u003eEG(e,t.layerCount));if(e.circles.push({center:r,radius:(r.via_diameter??i?.width??.2)/2,fill:\"rgba(37, 99, 235, 0.45)\",stroke:o,layer:`z${n.join(\",\")}`}),i){const t=i.width;i={x:r.x,y:r.y,layer:r.to_layer,width:t}}}}return e},rU=class extends kt{constructor(t){super(),this.params=t,this.outputTraces=HG(t.simpleRouteJson.traces),this.MAX_ITERATIONS=WG(t)}params;outputTraces;reroutedPairs=[];failures=[];nextPairIndex=0;activeConnectionNames=null;activeSession=null;getSolverName(){return\"DifferentialPairReroutingSolver\"}_step(){const t=this.params.simpleRouteJson.differentialPairs[this.nextPairIndex];if(!t)return void this.finish();this.activeConnectionNames=t.connectionNames;try{if(!this.activeSession)return this.activeSession=new oU({pair:t,traces:this.outputTraces,obstacles:this.params.simpleRouteJson.obstacles,bounds:this.params.simpleRouteJson.bounds,layerCount:this.params.simpleRouteJson.layerCount,minTraceToPadEdgeClearance:this.params.simpleRouteJson.minTraceToPadEdgeClearance,routingGrid:this.params.routingGrid}),void(this.stats=this.activeSession.getStats());this.activeSession.step()}catch(e){if(!(e instanceof YG))throw e;return void this.skipFailedPair(t,e)}if(this.stats=this.activeSession.getStats(),!this.activeSession.isComplete())return;const e=this.activeSession.getResult();this.activeSession=null;for(const t of[e.candidate.first,e.candidate.second]){const e=this.outputTraces.findIndex(e=\u003ee.connection_name===t.connection_name);if(e\u003c0)throw new Error(`DifferentialPairReroutingSolver: accepted replacement for unknown connection \"${t.connection_name}\"`);this.outputTraces[e]=t}this.reroutedPairs.push(t),this.nextPairIndex++,this.nextPairIndex!==this.params.simpleRouteJson.differentialPairs.length?this.stats={phase:\"accepted\",pair:t.connectionNames.join(\"/\"),pairIndex:this.nextPairIndex-1,pairCount:this.params.simpleRouteJson.differentialPairs.length}:this.finish()}finish(){this.activeConnectionNames=null,this.solved=!0,this.stats={phase:\"complete\",acceptedPairCount:this.reroutedPairs.length,skippedPairCount:this.failures.length}}skipFailedPair(t,e){this.failures.push({connectionNames:[...t.connectionNames],reason:e.reason,message:e.message}),this.activeSession=null,this.nextPairIndex++,this.nextPairIndex!==this.params.simpleRouteJson.differentialPairs.length?this.stats={phase:\"skipped\",pair:t.connectionNames.join(\"/\"),pairIndex:this.nextPairIndex-1,pairCount:this.params.simpleRouteJson.differentialPairs.length,skippedPairCount:this.failures.length}:this.finish()}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved)throw new Error(\"DifferentialPairReroutingSolver: getOutput() called before completion\");return this.getBestEffortOutput()}getBestEffortOutput(){return{traces:HG(this.outputTraces),reroutedPairs:this.reroutedPairs.map(t=\u003e({...t,connectionNames:[...t.connectionNames]})),failures:this.failures.map(t=\u003e({...t,connectionNames:[...t.connectionNames]}))}}computeProgress(){return this.solved?1:0===this.params.simpleRouteJson.differentialPairs.length?0:(this.nextPairIndex+(this.activeSession?.getProgress()??0))/this.params.simpleRouteJson.differentialPairs.length}visualize(){return iU({traces:this.outputTraces,obstacles:this.params.simpleRouteJson.obstacles,bounds:this.params.simpleRouteJson.bounds,layerCount:this.params.simpleRouteJson.layerCount,activeConnectionNames:this.activeConnectionNames,previewPath:this.activeSession?.getPreviewPath()??null})}},sU=1e-8,aU=class extends kt{constructor(t){super(),this.input=t,this.traces=HG(t.traces),this.MAX_ITERATIONS=Math.max(1,t.reroutedPairs.length+1)}input;traces;nextPairIndex=0;getSolverName(){return\"FortyFiveDegreeSimplificationSolver\"}_step(){const t=this.input.reroutedPairs[this.nextPairIndex];if(!t)return this.solved=!0,void(this.stats={phase:\"complete\",simplifiedPairCount:this.nextPairIndex});this.traces=(t=\u003e{const e=t.pair.connectionNames.join(\"/\"),n=t.pair.connectionNames.map(e=\u003et.traces.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:t})=\u003et.connection_name===e));if(1!==n[0].length||1!==n[1].length)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} must resolve to exactly two traces`);const o=n[0][0].index,i=n[1][0].index;if(o===i)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} resolved both members to one trace`);const r=structuredClone(t.traces),s={immutableTraces:r.filter((t,e)=\u003ee!==o\u0026\u0026e!==i),obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,minTraceToPadEdgeClearance:t.minTraceToPadEdgeClearance},a=n=\u003e{const r=LG(n[o],t.layerCount),s=LG(n[i],t.layerCount);let a=0;for(const[t,n]of[[r.segments,s.segments],[s.segments,r.segments]])for(const o of t){if(null!==o.terminal)continue;const t=n.filter(t=\u003et.layer===o.layer);if(0===t.length)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} lost common-layer interior copper`);a=Math.max(a,Math.min(...t.map(t=\u003ecG(o.start,o.end,t.start,t.end))))}return a},c=e=\u003e{const n=LG(e[o],t.layerCount),r=LG(e[i],t.layerCount);let s=Number.POSITIVE_INFINITY;for(const[t,e]of[[n.segments,r.segments],[r.segments,n.segments]])for(const n of t)if(null===n.terminal)for(const t of e)t.layer===n.layer\u0026\u0026(s=Math.min(s,cG(n.start,n.end,t.start,t.end)-n.width/2-t.width/2));return Number.isFinite(s)?s:null},l=e=\u003e{const n=LG(e[o],t.layerCount),r=LG(e[i],t.layerCount);return ZG(n,r,s)};if(!l(r))throw new Error(`FortyFiveDegreeSimplificationSolver: rerouted pair ${e} has invalid complete copper before simplification`);if(void 0!==t.pair.maxUncoupledLength\u0026\u0026void 0!==t.pair.minimumCenterlineDistance\u0026\u0026void 0!==t.pair.maximumCenterlineDistance\u0026\u0026Math.abs(t.pair.minimumCenterlineDistance-t.pair.maximumCenterlineDistance)\u003c=sU)return r;const d=LG(r[o],t.layerCount),h=LG(r[i],t.layerCount),u=Math.abs(FG(d)-FG(h)),p=c(r),m=t.pair.maximumCenterlineDistance??1+d.width/2+h.width/2,g=Math.min(a(r),m),f=t=\u003e{if(!l(t))return!1;if(a(t)\u003eg+sU)return!1;const e=c(t);return null===p||null===e||e\u003e=p-sU},y=(t,e)=\u003e{const n=Math.abs(e.x-t.x),o=Math.abs(e.y-t.y),i=e.x\u003e=t.x?1:-1,r=e.y\u003e=t.y?1:-1,s=[],a={x:e.x-i*o,y:t.y};(a.x-t.x)*i\u003e=-1e-8\u0026\u0026(a.x-e.x)*i\u003c=sU\u0026\u0026s.push([t,a,e]);const c={x:t.x,y:e.y-r*n};(c.y-t.y)*r\u003e=-1e-8\u0026\u0026(c.y-e.y)*r\u003c=sU\u0026\u0026s.push([t,c,e]);const l={x:t.x+i*Math.min(n,o),y:t.y+r*Math.min(n,o)};return s.push([t,l,e]),s.map((t,e)=\u003e{const n=t.filter((e,n)=\u003e0===n||Math.hypot(e.x-t[n-1].x,e.y-t[n-1].y)\u003esU),o=n.slice(0,-1).map((t,e)=\u003e{const o=n[e+1],i=Math.abs(o.x-t.x),r=Math.abs(o.y-t.y);return{length:Math.hypot(i,r),straight:i\u003c=sU||r\u003c=sU?Math.hypot(i,r):0}});return{points:n,usableStraightLength:Math.max(0,...o.map(t=\u003et.straight)),bendCount:Math.max(0,n.length-2),priority:e}}).filter((t,e,n)=\u003en.findIndex(e=\u003eJSON.stringify(e.points)===JSON.stringify(t.points))===e).sort((t,e)=\u003ee.usableStraightLength-t.usableStraightLength||t.bendCount-e.bendCount||t.priority-e.priority)},_=t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n];if(\"wire\"===o?.route_type)for(let i=t.route.length-1;i\u003e=n+1;i--){if(0===n||i===t.route.length-1)continue;const r=t.route[i];\"wire\"===r?.route_type\u0026\u0026r.layer===o.layer\u0026\u0026(t.route.slice(n+1,i).some(t=\u003e\"wire\"!==t.route_type||t.layer!==o.layer)||e.push({startIndex:n,endIndex:i,skippedPointCount:i-n-1}))}}return e.sort((t,e)=\u003ee.skippedPointCount-t.skippedPointCount||t.startIndex-e.startIndex||e.endIndex-t.endIndex)},b=(t,e,n)=\u003e{const o=t.route[e.startIndex],i=t.route[e.endIndex],r=Math.max(o.width,i.width),s=n.points.slice(1,-1).map(t=\u003e({route_type:\"wire\",...t,width:r,layer:o.layer}));return{...t,route:[...t.route.slice(0,e.startIndex+1),...s,...t.route.slice(e.endIndex)]}};for(const t of[o,i]){let e=!0;for(;e;){e=!1;const n=r[t];for(const s of _(n)){const a=n.route[s.startIndex],c=n.route[s.endIndex],l=n.route.slice(s.startIndex,s.endIndex+1),d=l.slice(0,-1).every((t,e)=\u003e{const n=l[e+1],o=Math.abs(n.x-t.x),i=Math.abs(n.y-t.y);return o\u003c=sU||i\u003c=sU||Math.abs(o-i)\u003c=sU});for(const h of y(a,c)){if(h.points.length\u003e=l.length\u0026\u0026d)continue;const a=b(n,s,h),c=[...r];if(c[t]=a,JSON.stringify(a.route)===JSON.stringify(n.route))continue;if(f(c)){r[t]=a,e=!0;break}const u=t===o?i:o,p=r[u],m=_(p).find(t=\u003et.startIndex===s.startIndex\u0026\u0026t.endIndex===s.endIndex);if(!m)continue;const g=p.route[m.startIndex],x=p.route[m.endIndex];for(const n of y(g,x)){const o=b(p,m,n),i=[...c];if(i[u]=o,f(i)){r[t]=a,r[u]=o,e=!0;break}}if(e)break}if(e)break}}}if(!f(r))throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} produced invalid complete copper`);const x=LG(r[o],t.layerCount),v=LG(r[i],t.layerCount),S=Math.abs(FG(x)-FG(v));return Math.abs(S-u)\u003et.pair.lengthTolerance+sU?structuredClone(t.traces):r})({traces:this.traces,pair:t,obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,minTraceToPadEdgeClearance:this.input.minTraceToPadEdgeClearance}),this.nextPairIndex++,this.stats={phase:\"simplifying\",pair:t.connectionNames.join(\"/\"),pairIndex:this.nextPairIndex-1,pairCount:this.input.reroutedPairs.length}}getConstructorParams(){return[this.input]}getOutput(){if(!this.solved)throw new Error(\"FortyFiveDegreeSimplificationSolver: getOutput() called before completion\");return this.getBestEffortOutput()}getBestEffortOutput(){return{traces:HG(this.traces),reroutedPairs:this.input.reroutedPairs.map(t=\u003e({...t,connectionNames:[...t.connectionNames]}))}}computeProgress(){return this.solved?1:0===this.input.reroutedPairs.length?0:this.nextPairIndex/this.input.reroutedPairs.length}visualize(){return iU({traces:this.traces,obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,activeConnectionNames:this.input.reroutedPairs[this.nextPairIndex]?.connectionNames??null,previewPath:null})}},cU=class extends kt{constructor(t){super(),this.input=t}input;output=null;visualizationTraces=null;getSolverName(){return\"HdRouteReconstructionSolver\"}_step(){this.visualizationTraces=(t=\u003e{const{simpleRouteJson:e}=t.params;if(t.result.matchedHdRoutes.length!==t.binding.solverParams.hdRoutes.length)throw new Error(\"PostProcessingSolver: LengthMatchingSolver changed the search route count\");const n=structuredClone(t.binding.baseTraces);for(const o of t.binding.traceBindings){const i=t.result.matchedHdRoutes[o.matchedRouteIndex];if(!i)throw new Error(`PostProcessingSolver: missing matched route at index ${o.matchedRouteIndex}`);const r=n[o.traceIndex];if(!r)throw new Error(`PostProcessingSolver: missing simplified trace binding at index ${o.traceIndex}`);if(r.connection_name!==i.connectionName)throw new Error(`PostProcessingSolver: route binding changed connection \"${r.connection_name}\" to \"${i.connectionName}\"`);if(i.route.length\u003c2)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" has incomplete geometry`);const s=i.route[0],a=i.route.at(-1);if(Math.hypot(s.x-o.startEndpoint.x,s.y-o.startEndpoint.y)\u003e1e-8||s.z!==o.startEndpoint.z||Math.hypot(a.x-o.endEndpoint.x,a.y-o.endEndpoint.y)\u003e1e-8||a.z!==o.endEndpoint.z)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" moved a preserved endpoint`);const c=[];let l=0;const d=t=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:t.traceThickness??i.traceThickness,layer:AG(t.z,e.layerCount)});c.push(d(i.route[0]));for(let t=1;t\u003ci.route.length;t++){const n=i.route[t-1],r=i.route[t];if(n.z===r.z){c.push(d(r));continue}if(Math.hypot(n.x-r.x,n.y-r.y)\u003e1e-8)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" moves while changing layers`);const s=o.viaTemplates[l++];if(!s)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" added an unbound via`);if(Math.hypot(s.x-r.x,s.y-r.y)\u003e1e-8)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" moved a preserved via`);const a=AG(n.z,e.layerCount),h=AG(r.z,e.layerCount),u=new Set([s.from_layer,s.to_layer]);if(!u.has(a)||!u.has(h))throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" changed a preserved via span`);c.push({...s}),c.push(d(r))}if(l!==o.viaTemplates.length)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" removed a preserved via`);const h=c.filter(t=\u003e\"wire\"===t.route_type);for(const t of h)delete t.start_pcb_port_id,delete t.end_pcb_port_id;o.startPortId\u0026\u0026(h[0].start_pcb_port_id=o.startPortId),o.endPortId\u0026\u0026(h.at(-1).end_pcb_port_id=o.endPortId),n[o.traceIndex]={...r,route:c}}for(const o of t.binding.solverParams.differentialPairs){const t=o.connectionNames.join(\"/\"),i=o.connectionNames.map(t=\u003en.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:e})=\u003ee.connection_name===t));if(1!==i[0].length||1!==i[1].length)throw new Error(`PostProcessingSolver: reconstructed pair ${t} does not resolve to complete copper`);const r=i[0][0],s=i[1][0],a=LG(r.trace,e.layerCount),c=LG(s.trace,e.layerCount),l=Math.abs(FG(a)-FG(c));if(l\u003eo.lengthTolerance+1e-7)throw new XG({message:`PostProcessingSolver: reconstructed pair ${t} exceeds length tolerance ${o.lengthTolerance} with error ${l}`,connectionNames:[...o.connectionNames],reason:\"length-tolerance-unsatisfied\"});if(!ZG(a,c,{immutableTraces:n.filter((t,e)=\u003ee!==r.index\u0026\u0026e!==s.index),obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,minTraceToPadEdgeClearance:e.minTraceToPadEdgeClearance}))throw new XG({message:`PostProcessingSolver: length matching produced invalid complete copper for pair ${t}`,connectionNames:[...o.connectionNames],reason:\"invalid-final-copper\"})}return n})(this.input),this.output=$G({...this.input,rejectInsideJumperPad:!0}),this.stats={phase:\"complete\",routeCount:this.output.hdRoutes.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){if(!this.output||!this.solved)throw new Error(\"HdRouteReconstructionSolver: getOutput() called before completion\");return structuredClone(this.output)}visualize(){const t=this.visualizationTraces??this.input.simplified.traces,{obstacles:e,bounds:n,layerCount:o}=this.input.params.simpleRouteJson;return iU({traces:t,obstacles:e,bounds:n,layerCount:o,activeConnectionNames:null,previewPath:null})}};var lU=class extends Dt{differentialPairReroutingSolver;fortyFiveDegreeSimplificationSolver;lengthMatchingSolver;hdRouteReconstructionSolver;lengthMatchingBinding=null;model;fallbackOutput=null;postProcessingErrors=[];pipelineDef=[Lt(\"differentialPairReroutingSolver\",rU,t=\u003e[t.model.params]),Lt(\"fortyFiveDegreeSimplificationSolver\",aU,t=\u003e{const e=t.getStageOutput(\"differentialPairReroutingSolver\");if(!e)throw new Error(\"PostProcessingSolver: rerouting stage completed without output\");const{obstacles:n,bounds:o,layerCount:i,minTraceToPadEdgeClearance:r}=t.model.params.simpleRouteJson;return[{...e,obstacles:n,bounds:o,layerCount:i,minTraceToPadEdgeClearance:r}]}),Lt(\"lengthMatchingSolver\",RG,t=\u003e{const e=t.getStageOutput(\"fortyFiveDegreeSimplificationSolver\");if(!e)throw new Error(\"PostProcessingSolver: 45-degree simplification stage completed without output\");return t.lengthMatchingBinding=BG({result:e,params:t.model.params}),[t.lengthMatchingBinding.solverParams]}),Lt(\"hdRouteReconstructionSolver\",cU,t=\u003e{const e=t.getStageOutput(\"fortyFiveDegreeSimplificationSolver\"),n=t.getStageOutput(\"lengthMatchingSolver\");if(!e||!n||!t.lengthMatchingBinding)throw new Error(\"PostProcessingSolver: reconstruction stage is missing a required binding or output\");return[{binding:t.lengthMatchingBinding,result:n,simplified:e,params:t.model.params,model:t.model}]},{onSolved:t=\u003e{const e=t.getStageOutput(\"differentialPairReroutingSolver\");if(!e)throw new Error(\"PostProcessingSolver: cannot summarize missing rerouting output\");t.stats={phase:\"complete\",acceptedPairCount:e.reroutedPairs.length},e.failures.length\u003e0\u0026\u0026(t.stats.skippedPairCount=e.failures.length,t.stats.postProcessingErrorCount=e.failures.length)}})];constructor(t){super(structuredClone(t));let e=null;try{!function(t){if(!t||\"object\"!=typeof t)throw new Error(\"PostProcessingSolver: params must be an object\");if(!Array.isArray(t.hdRoutes))throw new Error(\"PostProcessingSolver: hdRoutes must be an array\");if(!Array.isArray(t.differentialPairs))throw new Error(\"PostProcessingSolver: differentialPairs must be an array\");if(!Array.isArray(t.obstacles))throw new Error(\"PostProcessingSolver: obstacles must be an array\");if(void 0!==t.minTraceToPadEdgeClearance\u0026\u0026(!Number.isFinite(t.minTraceToPadEdgeClearance)||t.minTraceToPadEdgeClearance\u003c0))throw new Error(\"PostProcessingSolver: minTraceToPadEdgeClearance must be finite and nonnegative\");if(!Number.isInteger(t.layerCount)||t.layerCount\u003c1)throw new Error(\"PostProcessingSolver: layerCount must be a positive integer\");for(const e of t.obstacles){if(!e||\"object\"!=typeof e||\"rect\"!==e.type||!e.center||!Number.isFinite(e.center.x)||!Number.isFinite(e.center.y)||!Number.isFinite(e.width)||e.width\u003c=0||!Number.isFinite(e.height)||e.height\u003c=0||!Array.isArray(e.layers)||e.layers.some(t=\u003e\"string\"!=typeof t)||!Array.isArray(e.connectedTo)||e.connectedTo.some(t=\u003e\"string\"!=typeof t||0===t.length)||void 0!==e.ccwRotationDegrees\u0026\u0026!Number.isFinite(e.ccwRotationDegrees))throw new Error(\"PostProcessingSolver: obstacle declaration is invalid\");uG(e,t.layerCount)}const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds??{};if(![e,n,o,i].every(Number.isFinite)||e\u003e=n||o\u003e=i)throw new Error(\"PostProcessingSolver: bounds must have finite positive extents\");const r=new Set(t.differentialPairs.flatMap(t=\u003et.connectionNames));for(const e of t.hdRoutes){if(!e||\"object\"!=typeof e||\"string\"!=typeof e.connectionName||0===e.connectionName.length||void 0!==e.rootConnectionName\u0026\u0026(\"string\"!=typeof e.rootConnectionName||0===e.rootConnectionName.length)||!Number.isFinite(e.traceThickness)||e.traceThickness\u003c=0||!Number.isFinite(e.viaDiameter)||e.viaDiameter\u003c0||0===e.viaDiameter\u0026\u0026r.has(e.connectionName)||!Array.isArray(e.route)||!Array.isArray(e.vias)||void 0!==e.jumpers\u0026\u0026!Array.isArray(e.jumpers))throw new Error(\"PostProcessingSolver: HD route declaration is invalid\");if(void 0!==e.startPcbPortId\u0026\u0026(\"string\"!=typeof e.startPcbPortId||0===e.startPcbPortId.length)||void 0!==e.endPcbPortId\u0026\u0026(\"string\"!=typeof e.endPcbPortId||0===e.endPcbPortId.length))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has invalid terminal metadata`);for(const n of e.route)if(!n||\"object\"!=typeof n||!Number.isFinite(n.x)||!Number.isFinite(n.y)||!Number.isInteger(n.z)||n.z\u003c0||n.z\u003e=t.layerCount||void 0!==n.traceThickness\u0026\u0026(!Number.isFinite(n.traceThickness)||n.traceThickness\u003c=0))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has an invalid route point`);for(const n of e.vias)if(!n||\"object\"!=typeof n||!Number.isFinite(n.x)||!Number.isFinite(n.y)||void 0!==n.zLayers\u0026\u0026(!Array.isArray(n.zLayers)||n.zLayers.some(e=\u003e!Number.isInteger(e)||e\u003c0||e\u003e=t.layerCount)))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has an invalid via`);if(e.vias.length\u003e0\u0026\u0026e.viaDiameter\u003c=0)throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has a non-positive via diameter`);for(const t of e.jumpers??[])if(!(t\u0026\u0026\"object\"==typeof t\u0026\u0026\"jumper\"===t.route_type\u0026\u0026Number.isFinite(t.start?.x)\u0026\u0026Number.isFinite(t.start?.y)\u0026\u0026Number.isFinite(t.end?.x)\u0026\u0026Number.isFinite(t.end?.y)\u0026\u0026[\"0603\",\"1206\",\"1206x4_pair\"].includes(t.footprint)))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has an invalid jumper`)}const s=new Set;for(const e of t.differentialPairs){if(!e||\"object\"!=typeof e||!Array.isArray(e.connectionNames)||2!==e.connectionNames.length||e.connectionNames[0]===e.connectionNames[1]||!e.connectionNames.every(t=\u003e\"string\"==typeof t\u0026\u0026t.length\u003e0)||!Number.isFinite(e.lengthTolerance)||e.lengthTolerance\u003c0)throw new Error(\"PostProcessingSolver: differential pair declaration is invalid\");for(const t of[e.minimumCenterlineDistance,e.maximumCenterlineDistance])if(void 0!==t\u0026\u0026(!Number.isFinite(t)||t\u003c=0))throw new Error(\"PostProcessingSolver: differential pair centerline distances must be positive finite numbers\");if(void 0!==e.maxUncoupledLength\u0026\u0026(!Number.isFinite(e.maxUncoupledLength)||e.maxUncoupledLength\u003c0))throw new Error(\"PostProcessingSolver: differential pair maxUncoupledLength must be a non-negative finite number\");if(void 0!==e.minimumCenterlineDistance\u0026\u0026void 0!==e.maximumCenterlineDistance\u0026\u0026e.minimumCenterlineDistance\u003ee.maximumCenterlineDistance)throw new Error(\"PostProcessingSolver: differential pair minimumCenterlineDistance cannot exceed maximumCenterlineDistance\");for(const t of e.connectionNames){if(s.has(t))throw new Error(`PostProcessingSolver: connection \"${t}\" belongs to multiple differential pairs`);s.add(t)}}for(const e of[.25,.5])QG({config:t.routingGrid,bounds:t.bounds,defaultInnerGridStep:e})}(t)}catch(t){if(!(t instanceof VG))throw t;e=t}if(this.model=jG(t),e)return void this.finishWithBestEffortOutput({stage:\"differentialPairReroutingSolver\",message:e.message,reason:e.reason});const n=WG(this.model.params)+Math.max(1,t.differentialPairs.length+1)+1e5+10;if(!Number.isSafeInteger(n))throw new Error(\"PostProcessingSolver: derived pipeline iteration bound exceeds the safe integer range\");this.MAX_ITERATIONS=n}getSolverName(){return\"PostProcessingSolver\"}getConstructorParams(){return[structuredClone(this.inputProblem)]}_step(){const t=this.getCurrentStageName();try{super._step()}catch(e){const n=this.classifyOptimizationFailure(e,t);if(!n)throw e;return void this.finishWithBestEffortOutput(n)}if(!this.failed)return;const e=this.classifyIterationFailure(this.error,t);if(!e)throw new Error(this.error??\"PostProcessingSolver failed without an error message\");this.finishWithBestEffortOutput(e)}tryFinalAcceptance(){const t=this.getCurrentStageName();\"differentialPairReroutingSolver\"!==t\u0026\u0026\"lengthMatchingSolver\"!==t||this.finishWithBestEffortOutput({stage:t,message:\"PostProcessingSolver reached its iteration limit\",reason:\"iteration-limit-exhausted\"})}classifyOptimizationFailure(t,e){return\"lengthMatchingSolver\"===e\u0026\u0026t instanceof IG?{stage:e,message:t.message,connectionName:t.connectionName,reason:t.reason}:\"hdRouteReconstructionSolver\"===e\u0026\u0026t instanceof XG||\"differentialPairReroutingSolver\"===e\u0026\u0026t instanceof YG\u0026\u0026\"no-valid-candidate\"===t.reason?{stage:e,message:t.message,connectionNames:[...t.connectionNames],reason:t.reason}:null}classifyIterationFailure(t,e){return\"differentialPairReroutingSolver\"!==e\u0026\u0026\"lengthMatchingSolver\"!==e?null:t\u0026\u0026t.endsWith(\"ran out of iterations\")?{stage:e,message:t,reason:\"iteration-limit-exhausted\"}:null}createBestEffortOutput(t){let e=this.lengthMatchingBinding;if(!e){const t=this.getStageOutput(\"fortyFiveDegreeSimplificationSolver\")??this.fortyFiveDegreeSimplificationSolver?.getBestEffortOutput(),n=this.getStageOutput(\"differentialPairReroutingSolver\")??this.differentialPairReroutingSolver?.getBestEffortOutput(),o=t??n;o\u0026\u0026(e=BG({result:o,params:this.model.params}))}if(!e)return{output:{hdRoutes:structuredClone(this.inputProblem.hdRoutes),postProcessingErrors:[]},source:\"input-hd-routes\"};let n=this.getStageOutput(\"lengthMatchingSolver\");return n||(n=this.lengthMatchingSolver?.getBestEffortOutput()),n\u0026\u0026\"invalid-final-copper\"!==t.reason||(n={matchedHdRoutes:e.solverParams.hdRoutes}),{output:$G({binding:e,result:n,model:this.model}),source:\"best-effort-hd-routes\"}}finishWithBestEffortOutput(t){const e=this.createBestEffortOutput(t),n={type:\"post_processing_error\",...t,returnedRouteSource:e.source};this.postProcessingErrors.push(n),this.fallbackOutput=e.output,this.activeSubSolver=null,this.error=null,this.failed=!1,this.solved=!0,this.progress=1,this.stats={phase:\"complete\",postProcessingErrorCount:this.postProcessingErrors.length}}getOutput(){if(!this.solved)throw new Error(\"PostProcessingSolver: getOutput() called before the solver completed\");const t=this.fallbackOutput??this.getStageOutput(\"hdRouteReconstructionSolver\");if(!t)throw new Error(\"PostProcessingSolver: completed pipeline is missing reconstruction output\");const e=this.getStageOutput(\"differentialPairReroutingSolver\")??this.differentialPairReroutingSolver?.getBestEffortOutput(),n=e?.failures??[];let o=\"input-hd-routes\";(e?.reroutedPairs.length??0)\u003e0\u0026\u0026(o=\"best-effort-hd-routes\");const i=[...n.map(t=\u003e({type:\"post_processing_error\",stage:\"differentialPairReroutingSolver\",message:t.message,connectionNames:[...t.connectionNames],reason:t.reason,returnedRouteSource:o})),...this.postProcessingErrors],r=structuredClone(t);return r.postProcessingErrors=structuredClone(i),r}initialVisualize(){if(this.fallbackOutput)return{lines:this.fallbackOutput.hdRoutes.map(t=\u003e({points:t.route.map(({x:t,y:e})=\u003e({x:t,y:e})),strokeWidth:t.traceThickness}))};const{traces:t,obstacles:e,bounds:n,layerCount:o}=this.model.params.simpleRouteJson;return iU({traces:structuredClone(t),obstacles:e,bounds:n,layerCount:o,activeConnectionNames:null,previewPath:null})}finalVisualize(){if(this.fallbackOutput)return this.initialVisualize();const t=jG({...this.inputProblem,hdRoutes:this.getOutput().hdRoutes}),{traces:e,obstacles:n,bounds:o,layerCount:i}=t.params.simpleRouteJson;return iU({traces:e,obstacles:n,bounds:o,layerCount:i,activeConnectionNames:null,previewPath:null})}},dU=class t{static generators=new Map;static register(e){t.generators.set(e.componentKind,e)}static create(e){const n=e.detectedComponent.componentKind,o=t.generators.get(n);if(!o)throw new Error(`No topology generator registered for component kind \"${n}\"`);return new o(e)}},hU=t=\u003e[t.obstacle.obstacleId??t.obstacle.componentId??\"obstacle\",t.start.x.toFixed(4),t.start.y.toFixed(4),t.end.x.toFixed(4),t.end.y.toFixed(4),t.expansionDirection.x,t.expansionDirection.y].join(\":\"),uU=t=\u003e{let e=0;for(const n of t)e=31*e+n.charCodeAt(0)\u003e\u003e\u003e0;return e},pU=(t,e)=\u003e`hsla(${uU(hU(t))%360},72%,36%,${e})`,mU=t=\u003e{const e=t.expansionDirection;return e.x\u003c0?\"left\":e.x\u003e0?\"right\":e.y\u003c0?\"bottom\":\"top\"},gU=t=\u003e({x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2}),fU=t=\u003e{const e=/^bga-gapfill-(\\d+)-/.exec(t.capacityMeshNodeId);return e?Number.parseInt(e[1],10):null},yU=(t,e)=\u003e{const n=gU(t),o=gU(e),i=n.y-o.y;if(Math.abs(i)\u003e1e-6)return i;const r=n.x-o.x;return Math.abs(r)\u003e1e-6?r:hU(t).localeCompare(hU(e))},_U=t=\u003e{const e=[...t].sort(yU),n=[];let o=e.shift();for(;o\u0026\u0026(n.push(o),0!==e.length);){const t=gU(o);let n=0,i=Number.POSITIVE_INFINITY;for(let o=0;o\u003ce.length;o++){const r=e[o],s=gU(r),a=(s.x-t.x)**2+(s.y-t.y)**2;a\u003ci-1e-9?(i=a,n=o):Math.abs(a-i)\u003c=1e-9\u0026\u0026yU(r,e[n])\u003c0\u0026\u0026(n=o)}o=e.splice(n,1)[0]}return n},bU=(t,e)=\u003e{const n=hU(t),o=e.findIndex(t=\u003ehU(t)===n);return o\u003e=0?`E${o+1}`:`E${uU(n).toString(36).slice(0,4)}`},xU=t=\u003et.flatMap(t=\u003e{const e=Ve(t);return[{obstacle:t,start:{x:e.minX,y:e.minY},end:{x:e.minX,y:e.maxY},expansionDirection:{x:-1,y:0}},{obstacle:t,start:{x:e.maxX,y:e.minY},end:{x:e.maxX,y:e.maxY},expansionDirection:{x:1,y:0}},{obstacle:t,start:{x:e.minX,y:e.minY},end:{x:e.maxX,y:e.minY},expansionDirection:{x:0,y:-1}},{obstacle:t,start:{x:e.minX,y:e.maxY},end:{x:e.maxX,y:e.maxY},expansionDirection:{x:0,y:1}}]}),vU=.001,SU=.001,IU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;meshIndex;allEdges=[];queueEdges=[];disconnectedEdges=[];currentEdge=null;lastSearchBounds=null;lastCandidateMeshNodes=[];lastMatchedMeshNode=null;_setup(){const t=Math.max(this.inputProblem.meshNodes.length,1);this.meshIndex=new Bt(t);for(const t of this.inputProblem.meshNodes){const e=Ve(t);this.meshIndex.add(e.minX,e.minY,e.maxX,e.maxY)}this.meshIndex.finish();const e=xU(this.inputProblem.unmarkedComponentObstacles);this.queueEdges=e,this.allEdges=_U(e),this.currentEdge=null,this.lastSearchBounds=null,this.lastCandidateMeshNodes=[],this.lastMatchedMeshNode=null}_step(){const t=this.queueEdges.shift();if(!t)return this.currentEdge=null,this.lastSearchBounds=null,this.lastCandidateMeshNodes=[],this.lastMatchedMeshNode=null,void(this.solved=!0);this.currentEdge=t,this.lastMatchedMeshNode=null;const e=Math.abs(t.start.x-t.end.x)\u003c=vU,n=e?{minX:t.start.x-SU,maxX:t.start.x+SU,minY:Math.min(t.start.y,t.end.y),maxY:Math.max(t.start.y,t.end.y)}:{minX:Math.min(t.start.x,t.end.x),maxX:Math.max(t.start.x,t.end.x),minY:t.start.y-SU,maxY:t.start.y+SU};this.lastSearchBounds=n;const o=this.meshIndex.search(n.minX,n.minY,n.maxX,n.maxY);this.lastCandidateMeshNodes=o.map(t=\u003ethis.inputProblem.meshNodes[t]);let i=!1;for(const n of o){const o=this.inputProblem.meshNodes[n],r=Ve(o);if(e){if(!(Math.min(r.maxY,Math.max(t.start.y,t.end.y))-Math.max(r.minY,Math.min(t.start.y,t.end.y))\u003evU))continue;if(-1===t.expansionDirection.x\u0026\u0026Math.abs(r.maxX-t.start.x)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}if(1===t.expansionDirection.x\u0026\u0026Math.abs(r.minX-t.start.x)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}continue}if(Math.min(r.maxX,Math.max(t.start.x,t.end.x))-Math.max(r.minX,Math.min(t.start.x,t.end.x))\u003evU){if(-1===t.expansionDirection.y\u0026\u0026Math.abs(r.maxY-t.start.y)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}if(1===t.expansionDirection.y\u0026\u0026Math.abs(r.minY-t.start.y)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}}}i||this.disconnectedEdges.push(t)}getOutput(){return this.disconnectedEdges}visualize(){const t=this.disconnectedEdges,e=this.allEdges.length\u003e0?this.allEdges:[...t,...this.currentEdge?[this.currentEdge]:[]],n=this.currentEdge?pU(this.currentEdge,.88):\"rgba(40,40,40,0.4)\",o=this.inputProblem.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(120,120,120,0.18)\":\"rgba(120,120,120,0.08)\",stroke:t._containsObstacle?\"rgba(120,120,120,0.42)\":\"rgba(120,120,120,0.24)\"})),i=this.lastSearchBounds\u0026\u0026this.currentEdge?[{center:(r=this.lastSearchBounds,{x:(r.minX+r.maxX)/2,y:(r.minY+r.maxY)/2}),width:this.lastSearchBounds.maxX-this.lastSearchBounds.minX,height:this.lastSearchBounds.maxY-this.lastSearchBounds.minY,fill:pU(this.currentEdge,.1),stroke:pU(this.currentEdge,.36),label:[bU(this.currentEdge,e),\"search band\"].join(\" \")}]:[];var r;const s=this.lastCandidateMeshNodes.map(t=\u003e({...Dc(t,{rectMargin:.018}),fill:t===this.lastMatchedMeshNode?\"rgba(0,180,90,0.24)\":this.currentEdge?pU(this.currentEdge,.16):\"rgba(80,120,160,0.16)\",stroke:t===this.lastMatchedMeshNode?\"rgba(0,150,80,0.88)\":n,label:[t===this.lastMatchedMeshNode?\"matched\":\"candidate\",t.capacityMeshNodeId,`z:${t.availableZ.join(\",\")}`].join(\"\\n\")})),a=this.inputProblem.unmarkedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(160,160,160,0.10)\",stroke:\"rgba(160,160,160,0.40)\",label:t.obstacleId??t.componentId??\"obstacle\"})),c=t.map(t=\u003e({points:[t.start,t.end],strokeColor:pU(t,.14),strokeWidth:.01,strokeDash:\"5 4\",label:[bU(t,e),mU(t),\"disconnected\"].join(\" \")})),l=[],d=[];if(this.currentEdge){const t=gU(this.currentEdge);l.push({points:[this.currentEdge.start,this.currentEdge.end],strokeColor:pU(this.currentEdge,1),strokeWidth:.06,label:[bU(this.currentEdge,e),mU(this.currentEdge),\"checking\"].join(\" \")},{points:[t,{x:t.x+.16*this.currentEdge.expansionDirection.x,y:t.y+.16*this.currentEdge.expansionDirection.y}],strokeColor:pU(this.currentEdge,.82),strokeWidth:.02,strokeDash:\"3 3\"}),d.push({...t,color:pU(this.currentEdge,1),label:bU(this.currentEdge,e)})}return{rects:[...o,...i,...s,...a],lines:[...c,...l],points:d}}},CU=.001,PU=.001,MU=1e-6,NU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;meshIndex;meshBounds;expandedNodes=[];_setup(){const t=Math.max(this.inputProblem.meshNodes.length,1);this.meshIndex=new Bt(t);let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const t of this.inputProblem.meshNodes){const r=Ve(t);this.meshIndex.add(r.minX,r.minY,r.maxX,r.maxY),e=Math.min(e,r.minX),n=Math.max(n,r.maxX),o=Math.min(o,r.minY),i=Math.max(i,r.maxY)}this.meshIndex.finish(),this.meshBounds=this.inputProblem.meshNodes.length?{minX:e,maxX:n,minY:o,maxY:i}:{minX:0,maxX:0,minY:0,maxY:0}}getObstacleAvailableZ(t){return t.__zLayers??t.layers.map(t=\u003eko(t,this.inputProblem.layerCount))}getSharedOverlapArea(t,e){if(!t.availableZ.some(t=\u003ee.availableZ.includes(t)))return 0;const n=Ve(t),o=Ve(e),i=Math.min(n.maxX,o.maxX)-Math.max(n.minX,o.minX),r=Math.min(n.maxY,o.maxY)-Math.max(n.minY,o.minY);return i\u003c=MU||r\u003c=MU?0:i*r}getNodeObstacleOverlapArea(t,e){const n=this.getObstacleAvailableZ(e);if(!t.availableZ.some(t=\u003en.includes(t)))return 0;const o=Ve(t),i=Ve(e),r=Math.min(o.maxX,i.maxX)-Math.max(o.minX,i.minX),s=Math.min(o.maxY,i.maxY)-Math.max(o.minY,i.minY);return r\u003c=MU||s\u003c=MU?0:r*s}getClosestMeshNode(t,e){const n=Math.abs(t.start.x-t.end.x)\u003c=CU,o=this.getObstacleAvailableZ(t.obstacle),i=n?t.expansionDirection.x\u003c0?{minX:this.meshBounds.minX,maxX:t.start.x,minY:Math.min(t.start.y,t.end.y)-PU,maxY:Math.max(t.start.y,t.end.y)+PU}:{minX:t.start.x,maxX:this.meshBounds.maxX,minY:Math.min(t.start.y,t.end.y)-PU,maxY:Math.max(t.start.y,t.end.y)+PU}:t.expansionDirection.y\u003c0?{minX:Math.min(t.start.x,t.end.x)-PU,maxX:Math.max(t.start.x,t.end.x)+PU,minY:this.meshBounds.minY,maxY:t.start.y}:{minX:Math.min(t.start.x,t.end.x)-PU,maxX:Math.max(t.start.x,t.end.x)+PU,minY:t.start.y,maxY:this.meshBounds.maxY},r=this.meshIndex.search(i.minX,i.minY,i.maxX,i.maxY);let s=null,a=Number.POSITIVE_INFINITY;const c=[...r.map(t=\u003ethis.inputProblem.meshNodes[t]),...e];for(const e of c){if(e._containsObstacle)continue;if(!e.availableZ.some(t=\u003eo.includes(t)))continue;const i=Ve(e);if((n?Math.min(Math.max(t.start.y,t.end.y),i.maxY)-Math.max(Math.min(t.start.y,t.end.y),i.minY):Math.min(Math.max(t.start.x,t.end.x),i.maxX)-Math.max(Math.min(t.start.x,t.end.x),i.minX))\u003c=CU)continue;const r=n?t.expansionDirection.x\u003c0?t.start.x-i.maxX:i.minX-t.start.x:t.expansionDirection.y\u003c0?t.start.y-i.maxY:i.minY-t.start.y;r\u003cCU||(r\u003e=a||(a=r,s=e))}return s}createExpandedNode(t,e,n){const o=Ve(e),i=this.getObstacleAvailableZ(t.obstacle);if(Math.abs(t.start.x-t.end.x)\u003c=CU){const r=Math.max(Math.min(t.start.y,t.end.y),o.minY),s=Math.min(Math.max(t.start.y,t.end.y),o.maxY),a=t.expansionDirection.x\u003c0?o.maxX:t.start.x,c=t.expansionDirection.x\u003c0?t.start.x:o.minX;return c-a\u003c=CU||s-r\u003c=CU?null:{capacityMeshNodeId:`bga-gapfill-${n}-${t.obstacle.obstacleId??\"no-obstacle\"}-${e.capacityMeshNodeId}`,center:{x:(a+c)/2,y:(r+s)/2},width:c-a,height:s-r,layer:`z${i.join(\",\")}`,availableZ:i}}const r=Math.max(Math.min(t.start.x,t.end.x),o.minX),s=Math.min(Math.max(t.start.x,t.end.x),o.maxX),a=t.expansionDirection.y\u003c0?o.maxY:t.start.y,c=t.expansionDirection.y\u003c0?t.start.y:o.minY;return s-r\u003c=CU||c-a\u003c=CU?null:{capacityMeshNodeId:`bga-gapfill-${n}-${t.obstacle.obstacleId??\"no-obstacle\"}-${e.capacityMeshNodeId}`,center:{x:(r+s)/2,y:(a+c)/2},width:s-r,height:c-a,layer:`z${i.join(\",\")}`,availableZ:i}}overlapsExistingGeometry(t,e){for(const e of this.inputProblem.meshNodes)if(this.getSharedOverlapArea(t,e)\u003e0)return!0;for(const n of e)if(this.getSharedOverlapArea(t,n)\u003e0)return!0;for(const e of this.inputProblem.edgesWithObstacle)if(this.getNodeObstacleOverlapArea(t,e.obstacle)\u003e0)return!0;return!1}_step(){const t=[];for(const[e,n]of this.inputProblem.edgesWithObstacle.entries()){const o=this.getClosestMeshNode(n,t);if(!o)continue;const i=this.createExpandedNode(n,o,e);i\u0026\u0026(this.overlapsExistingGeometry(i,t)||t.push(i))}this.expandedNodes=t,this.solved=!0}getOutput(){return this.expandedNodes}visualize(){const t=this.inputProblem.edgesWithObstacle,e=_U(t);return{rects:[...this.inputProblem.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.16)\":\"rgba(0,120,255,0.08)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.35)\":\"rgba(0,120,255,0.28)\"})),...this.expandedNodes.map(n=\u003e{const o=fU(n),i=null===o?null:t[o]??null;return{...Dc(n,{rectMargin:.012,zOffset:.01}),fill:i?pU(i,.24):\"rgba(0,160,100,0.24)\",stroke:i?pU(i,.72):\"rgba(0,160,100,0.68)\",label:[i?bU(i,e):\"E?\",\"expanded\",n.capacityMeshNodeId,`z:${n.availableZ.join(\",\")}`].join(\"\\n\")}})],lines:[...this.inputProblem.edgesWithObstacle.map(t=\u003e({points:[t.start,t.end],strokeColor:pU(t,.9),strokeWidth:.034,label:[bU(t,e),mU(t)].join(\" \")})),...this.inputProblem.edgesWithObstacle.map(t=\u003e{const e=gU(t);return{points:[e,{x:e.x+.16*t.expansionDirection.x,y:e.y+.16*t.expansionDirection.y}],strokeColor:pU(t,.7),strokeWidth:.016,strokeDash:\"3 3\"}})],points:this.inputProblem.edgesWithObstacle.map(t=\u003e({...gU(t),color:pU(t,.95),label:bU(t,e)}))}}},wU=.001,TU=class extends Dt{constructor(t){super(t),this.inputProblem=t}inputProblem;detectEdgesNotConnectedToMesh;expandUnconnectedEdgesToMesh;pipelineDef=[Lt(\"detectEdgesNotConnectedToMesh\",IU,t=\u003e[t.inputProblem]),Lt(\"expandUnconnectedEdgesToMesh\",NU,t=\u003e[{meshNodes:t.inputProblem.meshNodes,edgesWithObstacle:t.detectEdgesNotConnectedToMesh.getOutput(),layerCount:t.inputProblem.layerCount}])];getOutput(){return[...this.inputProblem.meshNodes,...this.expandUnconnectedEdgesToMesh.getOutput()]}getExpandedNodes(){return this.expandUnconnectedEdgesToMesh.getOutput()}getObstacleLayer(t){return`z${(t.obstacle.__zLayers??t.obstacle.layers.map(t=\u003eko(t,this.inputProblem.layerCount))).join(\",\")}`}getObstacleRects(){return this.inputProblem.unmarkedComponentObstacles.map(t=\u003e{const e=t.__zLayers??t.layers.map(t=\u003eko(t,this.inputProblem.layerCount));return{center:t.center,width:t.width,height:t.height,fill:\"rgba(150,150,150,0.08)\",stroke:\"rgba(90,90,90,0.42)\",label:t.obstacleId??t.componentId??\"bga obstacle\",layer:`z${e.join(\",\")}`}})}getBaseMeshRects(){return this.inputProblem.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.025,zOffset:.01}),fill:t._containsObstacle?\"rgba(210,60,60,0.14)\":\"rgba(80,120,160,0.08)\",stroke:t._containsObstacle?\"rgba(190,40,40,0.42)\":\"rgba(80,120,160,0.28)\",label:`mesh ${t.capacityMeshNodeId}\\nz:${t.availableZ.join(\",\")}`}))}initialVisualize(){const t=xU(this.inputProblem.unmarkedComponentObstacles),e=_U(t),n=[...t.map(t=\u003e({points:[t.start,t.end],strokeColor:pU(t,.72),strokeWidth:.018,strokeDash:\"0.05 0.035\",layer:this.getObstacleLayer(t),label:[bU(t,e),mU(t)].join(\" \")})),...t.map(t=\u003e{const e=gU(t);return{points:[e,{x:e.x+.18*t.expansionDirection.x,y:e.y+.18*t.expansionDirection.y}],strokeColor:pU(t,.64),strokeWidth:.012,strokeDash:\"0.035 0.025\",layer:this.getObstacleLayer(t)}})];return{title:\"BGA GapFill: candidate obstacle edges\",rects:[...this.getBaseMeshRects(),...this.getObstacleRects()],lines:n}}finalVisualize(){const t=this.getStageOutput(\"detectEdgesNotConnectedToMesh\")??[],e=this.getStageOutput(\"expandUnconnectedEdgesToMesh\")??[],n=_U(xU(this.inputProblem.unmarkedComponentObstacles)),o=new Map;for(const t of e){const e=fU(t);null!==e\u0026\u0026o.set(e,t)}const i=e.map(e=\u003e{const o=fU(e),i=null===o?null:t[o]??null,r=i?(({expandedNode:t,edge:e,meshNodes:n})=\u003e{const o=Ve(t),i=Math.abs(e.start.x-e.end.x)\u003c=wU;return n.filter(n=\u003e{if(n._containsObstacle)return!1;if(!t.availableZ.some(t=\u003en.availableZ.includes(t)))return!1;const r=Ve(n);return i?!(Math.min(o.maxY,r.maxY)-Math.max(o.minY,r.minY)\u003c=wU)\u0026\u0026(e.expansionDirection.x\u003c0?Math.abs(r.maxX-o.minX)\u003c=wU:Math.abs(r.minX-o.maxX)\u003c=wU):!(Math.min(o.maxX,r.maxX)-Math.max(o.minX,r.minX)\u003c=wU)\u0026\u0026(e.expansionDirection.y\u003c0?Math.abs(r.maxY-o.minY)\u003c=wU:Math.abs(r.minY-o.maxY)\u003c=wU)}).map(t=\u003et.capacityMeshNodeId)})({expandedNode:e,edge:i,meshNodes:this.inputProblem.meshNodes}):[],s=i?bU(i,n):\"E?\",a=null===i?\"rgba(0,160,100,0.72)\":pU(i,.72);return{...Dc(e,{rectMargin:.012,zOffset:.01}),fill:null===i?\"rgba(0,160,100,0.24)\":pU(i,.16),stroke:a,label:[`${s} gap fill`,r.length\u003e0?`to ${r.join(\",\")}`:\"target mesh not adjacent\",`z:${e.availableZ.join(\",\")}`].join(\"\\n\")}}),r=t.map((t,e)=\u003e{const i=o.get(e);return{points:[t.start,t.end],strokeColor:i?pU(t,.68):\"rgba(80,80,80,0.14)\",strokeWidth:i?.026:.008,...i?{}:{strokeDash:\"5 4\"},layer:this.getObstacleLayer(t),label:[[bU(t,n),mU(t)].join(\" \"),i?\"filled\":\"no fill created\"].join(\"\\n\")}}),s=t.flatMap((t,e)=\u003e{const n=gU(t),i=o.get(e);return i?[{points:[n,i.center],strokeColor:pU(t,.42),strokeWidth:.012,strokeDash:\"0.035 0.025\",layer:this.getObstacleLayer(t)}]:[]}),a=t.flatMap((t,e)=\u003eo.has(e)?[{...gU(t),color:pU(t,.82),label:bU(t,n),layer:this.getObstacleLayer(t)}]:[]);return{title:\"BGA GapFill: disconnected edges and created mesh\",rects:[...this.getBaseMeshRects(),...this.getObstacleRects(),...i],lines:[...r,...s],points:a}}};function RU(t,e){const n=[];for(let o=0;o\u003ct.length;o++){const i=t[o];n.push(i);const r=t[o+1];if(void 0===r)continue;const s=Math.round((r-i)/e);if(!(s\u003c=1))for(let t=1;t\u003cs;t++){const e=t/s;n.push(Number((i+(r-i)*e).toFixed(6)))}}return n}var EU=.001;function AU(t){const e=[];for(let n=1;n\u003ct.length;n++){const o=t[n]-t[n-1];o\u003eEU\u0026\u0026e.push(o)}if(0===e.length)return null;const n=Math.min(...e),o=e.filter(t=\u003et\u003c=1.5*n).sort((t,e)=\u003et-e),i=Math.floor(o.length/2);return o.length%2==0?(o[i-1]+o[i])/2:o[i]}function OU(t){return[...new Set(t)].sort((t,e)=\u003et-e)}function kU(t){return Number(t.toFixed(6))}var LU=class t{static fromObstacles(e){if(0===e.length)return null;const n=OU(e.map(t=\u003et.center.x)),o=OU(e.map(t=\u003et.center.y)),i=AU(n),r=AU(o);return null===i||null===r?null:new t({obstacles:e,xCoordinates:RU(n,i),yCoordinates:RU(o,r),pitchX:i,pitchY:r})}xCoordinates;yCoordinates;pitchX;pitchY;originX;originY;rowCount;colCount;padWidth;padHeight;slots=new Map;constructor(t){this.xCoordinates=t.xCoordinates,this.yCoordinates=t.yCoordinates,this.pitchX=t.pitchX,this.pitchY=t.pitchY,this.originX=this.xCoordinates[0],this.originY=this.yCoordinates[0],this.colCount=this.xCoordinates.length,this.rowCount=this.yCoordinates.length,this.padWidth=t.obstacles[0].width,this.padHeight=t.obstacles[0].height;for(const e of t.obstacles){const t=this.getSlotForObstacle(e);t\u0026\u0026this.slots.set(this.getSlotKey(t.row,t.col),{...t,obstacle:e})}}getSlotKey(t,e){return`${t}:${e}`}getAxisIndex(t,e){let n=-1,o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ct.length;i++){const r=Math.abs(t[i]-e);r\u003co\u0026\u0026(o=r,n=i)}return o\u003c=EU?n:null}getAxisCoordinate(t,e){return t[e]}hasPadAt(t,e){return this.slots.has(this.getSlotKey(t,e))}getSlotForObstacle(t){const e=this.getAxisIndex(this.yCoordinates,t.center.y),n=this.getAxisIndex(this.xCoordinates,t.center.x);return null===e||null===n||e\u003c0||e\u003e=this.rowCount||n\u003c0||n\u003e=this.colCount?null:{row:e,col:n}}getSlotCenter(t,e){return{x:this.getAxisCoordinate(this.xCoordinates,e),y:this.getAxisCoordinate(this.yCoordinates,t)}}getHorizontalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t,e+1),i=Math.abs(o.x-n.x);return{orientation:\"horizontal\",row:t,col:e,center:{x:kU((n.x+o.x)/2),y:n.y},width:i-this.padWidth,height:this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)\u0026\u0026this.hasPadAt(t,e+1)}}getVerticalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t+1,e),i=Math.abs(o.y-n.y);return{orientation:\"vertical\",row:t,col:e,center:{x:n.x,y:kU((n.y+o.y)/2)},width:this.padWidth,height:i-this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)\u0026\u0026this.hasPadAt(t+1,e)}}getDiagonalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t+1,e+1),i=Math.abs(o.x-n.x),r=Math.abs(o.y-n.y);return{orientation:\"diagonal\",row:t,col:e,center:{x:kU((n.x+o.x)/2),y:kU((n.y+o.y)/2)},width:i-this.padWidth,height:r-this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)\u0026\u0026this.hasPadAt(t+1,e+1)}}getDiagonalGaps(){const t=[];for(let e=0;e\u003cthis.rowCount-1;e++)for(let n=0;n\u003cthis.colCount-1;n++)t.push(this.getDiagonalGap(e,n));return t.filter(t=\u003et.width\u003eEU\u0026\u0026t.height\u003eEU)}getAxisGaps(){const t=[];for(let e=0;e\u003cthis.rowCount;e++)for(let n=0;n\u003cthis.colCount-1;n++)t.push(this.getHorizontalGap(e,n));for(let e=0;e\u003cthis.rowCount-1;e++)for(let n=0;n\u003cthis.colCount;n++)t.push(this.getVerticalGap(e,n));return t.filter(t=\u003et.width\u003eEU\u0026\u0026t.height\u003eEU)}getMissingSlots(){const t=[];for(let e=0;e\u003cthis.rowCount;e++)for(let n=0;n\u003cthis.colCount;n++)this.hasPadAt(e,n)||t.push({row:e,col:n,center:this.getSlotCenter(e,n),width:this.padWidth,height:this.padHeight});return t}};function DU(t){if([t.point.pointId,t.point.pcb_port_id].filter(t=\u003e\"string\"==typeof t).some(e=\u003et.obstacle.connectedTo.includes(e)))return!0;if(0===t.obstacle.connectedTo.length)return!1;if(Be(t.point,t.obstacle)\u003e.001)return!1;const e=xo(t.point).map(e=\u003eko(e,t.layerCount)),n=t.obstacle.layers.map(e=\u003eko(e,t.layerCount));return e.some(t=\u003en.includes(t))}function zU(t){return t.obstacleId??[t.componentId??\"no-component\",t.center.x,t.center.y,t.width,t.height,t.layers.join(\",\")].join(\":\")}function FU({componentId:t,orientationKey:e,row:n,col:o,center:i,width:r,height:s}){return[\"cmn\",e,t,n,o,i.x,i.y,r,s].join(\"_\")}function BU(t){const{componentId:e,bgaGap:n,freeLayers:o,multiLayerThreshold:i}=t,r=n.width\u003ei\u0026\u0026n.height\u003ei;let s=\"d\";\"horizontal\"===n.orientation\u0026\u0026(s=\"h\"),\"vertical\"===n.orientation\u0026\u0026(s=\"v\");const a=FU({componentId:e,orientationKey:s,row:n.row,col:n.col,center:n.center,width:n.width,height:n.height});return\"diagonal\"===n.orientation\u0026\u0026r||!n.isBetweenTwoPads\u0026\u0026r?[{center:n.center,width:n.width,height:n.height,availableZ:[...o],capacityMeshNodeId:`${a}_all`,layer:\"\"}]:o.map(t=\u003e({center:n.center,width:n.width,height:n.height,availableZ:[t],capacityMeshNodeId:`${a}_${t}`,layer:\"\"}))}function jU(t){const{componentId:e,obstacle:n,freeLayers:o,layerCount:i}=t,r=n.layers.map(t=\u003eko(t,i)),s=o.filter(t=\u003e!r.includes(t)),a=zU(n);return s.map(t=\u003e({capacityMeshNodeId:`free-${e}-${a}-${t}`,center:n.center,width:n.width,height:n.height,layer:`z${t}`,availableZ:[t]}))}function $U(t,e,n){const o=e.layers.map(t=\u003eko(t,n.layerCount)),i=zU(e),r=function(t){for(const e of t.srj.connections)for(const n of e.pointsToConnect)if(DU({point:n,obstacle:t.obstacle,layerCount:t.srj.layerCount}))return e.__rootConnectionNames?.[0]??e.name}({obstacle:e,srj:n});return{capacityMeshNodeId:`obstacle-${t}-${i}-${o.join(\",\")}-${e.center.x}-${e.center.y}`,_containsObstacle:!0,...r?{_containsTarget:!0,_targetConnectionName:r}:{},center:e.center,width:e.width,height:e.height,layer:`z${o.join(\",\")}`,availableZ:o}}var YU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;componentObstacles=[];meshNodes=[];getConstructorParams(){return[this.inputProblem]}_step(){const{srj:t,componentBounds:e,componentId:n,markedComponentObstacles:o,unmarkedComponentObstacles:i}=this.inputProblem,r=t.obstacles.filter(t=\u003e!0===t.isCopperPour).filter(t=\u003eXe(Ve(t),e)).flatMap(e=\u003ee.layers.map(e=\u003eko(e,t.layerCount))),s=Array.from({length:t.layerCount},(t,e)=\u003ee).filter(t=\u003e!r.includes(t));if(this.componentObstacles=o,0===o.length||0===s.length)return void(this.solved=!0);const a=LU.fromObstacles(o);if(!a)return void(this.solved=!0);const c=a.getAxisGaps(),l=a.getDiagonalGaps(),d=a.getMissingSlots(),h=1.2*(this.inputProblem.viaDiameter??Yo(t).padDiameter);this.meshNodes=[...c.flatMap(t=\u003eBU({componentId:n,bgaGap:t,freeLayers:s,multiLayerThreshold:h})),...l.flatMap(t=\u003eBU({componentId:n,bgaGap:t,freeLayers:s,multiLayerThreshold:h})),...d.flatMap(t=\u003efunction(t){const{componentId:e,missingBgaSlot:n,freeLayers:o,multiLayerThreshold:i}=t,r=FU({componentId:e,orientationKey:\"missing\",row:n.row,col:n.col,center:n.center,width:n.width,height:n.height});return n.width\u003ei\u0026\u0026n.height\u003ei?[{center:n.center,width:n.width,height:n.height,availableZ:[...o],capacityMeshNodeId:`${r}_all`,layer:\"\"}]:o.map(t=\u003e({center:n.center,width:n.width,height:n.height,availableZ:[t],capacityMeshNodeId:`${r}_${t}`,layer:\"\"}))}({componentId:n,missingBgaSlot:t,freeLayers:s,multiLayerThreshold:h})),...o.flatMap(e=\u003e[...jU({componentId:n,obstacle:e,freeLayers:s,layerCount:t.layerCount}),$U(n,e,t)]),...i.flatMap(e=\u003e[$U(n,e,t)])],this.meshNodes=function(t){const e=new Map;return t.map(t=\u003e{const n=e.get(t.capacityMeshNodeId)??0;return e.set(t.capacityMeshNodeId,n+1),0===n?t:{...t,capacityMeshNodeId:`${t.capacityMeshNodeId}__dup${n}`}})}(this.meshNodes),this.solved=!0}getOutput(){return this.meshNodes}visualize(){return{rects:[{center:{x:(this.inputProblem.componentBounds.minX+this.inputProblem.componentBounds.maxX)/2,y:(this.inputProblem.componentBounds.minY+this.inputProblem.componentBounds.maxY)/2},width:this.inputProblem.componentBounds.maxX-this.inputProblem.componentBounds.minX,height:this.inputProblem.componentBounds.maxY-this.inputProblem.componentBounds.minY,fill:\"rgba(0,0,0,0)\",stroke:\"rgba(30,30,30,0.65)\",label:`component ${this.inputProblem.componentId}`},...this.inputProblem.markedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,0,0,0.18)\",stroke:\"rgba(255,0,0,0.52)\",label:`pad ${t.obstacleId??\"obstacle\"}`})),...this.inputProblem.unmarkedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.14)\",stroke:\"rgba(255,140,0,0.42)\",label:`foreign ${t.obstacleId??\"obstacle\"}`})),...this.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.14)\":t.capacityMeshNodeId.includes(\"missing\")?\"rgba(0,200,120,0.18)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.36)\":t.capacityMeshNodeId.includes(\"missing\")?\"rgba(0,200,120,0.52)\":\"rgba(0,120,255,0.38)\"}))]}}};function XU(t){return t.capacityMeshNodeId.startsWith(\"bga-gapfill-\")}function VU(t){return JSON.stringify({availableZ:[...t.availableZ].sort((t,e)=\u003et-e),_containsTarget:t._containsTarget??!1,_targetConnectionName:t._targetConnectionName??null,_depth:t._depth??null,_strawNode:t._strawNode??!1,_strawParentCapacityMeshNodeId:t._strawParentCapacityMeshNodeId??null,_qfpRegionType:t._qfpRegionType??null,_isNarrowQfpPadGap:t._isNarrowQfpPadGap??!1,_soicRegionType:t._soicRegionType??null,_offBoardConnectionId:t._offBoardConnectionId??null,_offboardNetName:t._offboardNetName??null,_isVirtualOffboard:t._isVirtualOffboard??!1,_containsObstacle:t._containsObstacle??!1})}function WU(t,e){const n=Ve(t);for(const o of e){if(!t.availableZ.some(t=\u003eo.availableZ.includes(t)))continue;const e=Ve(o);if(Xe(n,e))return!0}return!1}function HU(t){const e=t[0];if(!e)throw new Error(\"createMergedNode requires at least one source node\");let n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const e of t){const t=Ve(e);n=Math.min(n,t.minX),o=Math.max(o,t.maxX),i=Math.min(i,t.minY),r=Math.max(r,t.maxY)}return{...e,capacityMeshNodeId:`merge:${t.map(t=\u003et.capacityMeshNodeId).join(\":\")}`,center:{x:(n+o)/2,y:(i+r)/2},width:o-n,height:r-i}}function GU(t,e,n){return{center:t.center,width:t.width,height:t.height,fill:e,stroke:e,label:n}}var UU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;obstacleNodes=[];passthroughNodes=[];mergedNodes=[];pendingGroups=[];totalGroupCount=0;processedGroupCount=0;debugFilteredNodes=[];debugMergeEvents=[];currentGroupKey=null;currentRootNodeId=null;lastMergedNodeId=null;_setup(){this.obstacleNodes=this.inputProblem.meshNodes.filter(t=\u003e!0===t._containsObstacle),this.passthroughNodes=[],this.mergedNodes=[],this.pendingGroups=[],this.totalGroupCount=0,this.processedGroupCount=0,this.debugFilteredNodes=[],this.debugMergeEvents=[],this.currentGroupKey=null,this.currentRootNodeId=null,this.lastMergedNodeId=null;const t=new Map;for(const e of this.inputProblem.meshNodes){if(!0===e._containsObstacle){this.passthroughNodes.push(e),this.debugFilteredNodes.push({type:\"preserved-obstacle\",node:e,reason:\"contains-obstacle\"});continue}if(XU(e)){this.passthroughNodes.push(e);continue}if(e.availableZ.length!==this.inputProblem.layerCount){this.passthroughNodes.push(e);continue}let n=!1;for(let t=0;t\u003cthis.inputProblem.layerCount;t+=1)if(!e.availableZ.includes(t)){n=!0;break}if(n){this.passthroughNodes.push(e);continue}if(WU(e,this.obstacleNodes)){this.passthroughNodes.push(e),this.debugFilteredNodes.push({type:\"preserved-overlap\",node:e,reason:\"overlaps-obstacle\"});continue}const o=VU(e),i=t.get(o);i?i.push(e):t.set(o,[e])}for(const[e,n]of t.entries())n.length\u003c=1?this.passthroughNodes.push(...n):this.pendingGroups.push({groupKey:e,nodes:n});this.pendingGroups.sort((t,e)=\u003ee.nodes.length-t.nodes.length),this.totalGroupCount=this.pendingGroups.length,this.updateStats(\"setup\")}_step(){const t=this.pendingGroups.shift();if(!t)return this.currentGroupKey=null,this.currentRootNodeId=null,this.solved=!0,void this.updateStats(\"done\");const e=t.nodes[0];this.currentGroupKey=t.groupKey,this.currentRootNodeId=e?e.capacityMeshNodeId:null;const n=function(t){if(!t.nodes[0])return{outputNodes:[],mergeEvents:[]};let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.POSITIVE_INFINITY;for(const r of t.nodes){e=Math.min(e,r.width),n=Math.min(n,r.height);const t=Ve(r);o=Math.min(o,t.minX),i=Math.min(i,t.minY)}const r=new Map,s=[];for(const a of t.nodes){const t=Ve(a),c=Math.round((t.minX-o)/e),l=Math.round((t.minY-i)/n),d=Math.max(1,Math.round(a.width/e)),h=Math.max(1,Math.round(a.height/n));for(let t=0;t\u003ch;t+=1)for(let e=0;e\u003cd;e+=1)r.set(`${c+e},${l+t}`,a);s.push({col:c,row:l})}s.sort((t,e)=\u003et.row-e.row||t.col-e.col);const a=new Set,c=[],l=[];for(const o of s){const i=`${o.col},${o.row}`;if(a.has(i))continue;let s=0;for(;;){const t=`${o.col+s},${o.row}`;if(!r.has(t))break;if(a.has(t))break;s+=1}let d=s,h=1,u=1,p=1;for(let t=1;;t+=1){const i=o.row+t-1;let s=0;for(;s\u003cd;){const t=`${o.col+s},${i}`;if(!r.has(t))break;if(a.has(t))break;s+=1}if(0===s)break;d=Math.min(d,s);for(let o=d;o\u003e=1;o-=1){const i=o*e,r=t*n,s=Math.min(i,r);if((s\u003c=1e-6?Number.POSITIVE_INFINITY:Math.max(i,r)/s)\u003e4)continue;const a=o*t;a\u003ep\u0026\u0026(p=a,h=o,u=t);break}}const m=new Map;for(let t=0;t\u003cu;t+=1)for(let e=0;e\u003ch;e+=1){const n=`${o.col+e},${o.row+t}`,i=r.get(n);i\u0026\u0026(a.add(n),m.set(i.capacityMeshNodeId,i))}const g=[...m.values()];if(g.length\u003c=1){const t=g[0];t\u0026\u0026c.push(t);continue}const f=HU(g);c.push(f),l.push({type:\"merge\",groupKey:t.groupKey,sourceNodes:g,mergedNode:f})}return{outputNodes:c,mergeEvents:l}}(t);this.mergedNodes.push(...n.outputNodes),this.processedGroupCount+=1,this.debugMergeEvents.push(...n.mergeEvents);const o=n.mergeEvents[n.mergeEvents.length-1];o\u0026\u0026(this.lastMergedNodeId=o.mergedNode.capacityMeshNodeId),this.updateStats(n.mergeEvents.length\u003e0?\"merged-group\":\"passthrough-group\")}computeProgress(){return 0===this.totalGroupCount?1:this.processedGroupCount/this.totalGroupCount}updateStats(t){const e=new Set(this.debugMergeEvents.map(t=\u003et.groupKey)),n={lastAction:t,totalGroupCount:this.totalGroupCount,processedGroupCount:this.processedGroupCount,pendingGroupCount:this.pendingGroups.length,mergedNodeCount:this.mergedNodes.length,passthroughNodeCount:this.passthroughNodes.length,gapFillNodeCount:this.passthroughNodes.filter(XU).length,preservedObstacleNodeCount:this.debugFilteredNodes.filter(t=\u003e\"preserved-obstacle\"===t.type).length,preservedOverlapNodeCount:this.debugFilteredNodes.filter(t=\u003e\"preserved-overlap\"===t.type).length,mergeCount:this.debugMergeEvents.length,mergedGroupCount:e.size,currentGroupKey:this.currentGroupKey,currentRootNodeId:this.currentRootNodeId,lastMergedNodeId:this.lastMergedNodeId};this.stats=n}getConstructorParams(){return[this.inputProblem]}getOutput(){return[...this.mergedNodes,...this.passthroughNodes]}visualize(){const t=this.getOutput(),e=this.currentRootNodeId?t.find(t=\u003et.capacityMeshNodeId===this.currentRootNodeId)??null:null,n=this.lastMergedNodeId?t.find(t=\u003et.capacityMeshNodeId===this.lastMergedNodeId)??null:null;return{rects:[...this.debugFilteredNodes.map(t=\u003eGU(t.node,\"preserved-obstacle\"===t.type?\"rgba(255,64,64,0.35)\":\"rgba(255,160,64,0.35)\",t.reason)),...this.passthroughNodes.map(t=\u003eGU(t,t._containsObstacle?\"rgba(255,0,0,0.35)\":XU(t)?\"rgba(0,120,255,0.18)\":\"rgba(160,160,160,0.12)\")),...this.mergedNodes.map(t=\u003eGU(t,\"rgba(120,120,120,0.14)\")),...e?[GU(e,\"rgba(255,215,0,0.35)\",\"active-group\")]:[],...n?[GU(n,\"rgba(0,200,120,0.28)\",\"merged\")]:[]]}}},ZU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;obstacleQueue=[];obstacleQueueIndex=0;meshNodes=[];_setup(){this.obstacleQueue=this.inputProblem.obstacles,this.obstacleQueueIndex=0,this.meshNodes=[...this.inputProblem.meshNodes]}_step(){if(this.obstacleQueueIndex\u003e=this.obstacleQueue.length)return void(this.solved=!0);const t=this.obstacleQueue[this.obstacleQueueIndex],e=t.layers.map(t=\u003eko(t,this.inputProblem.layerCount)),n=[];for(const o of this.meshNodes){if(o._containsObstacle){n.push(o);continue}if(!e.some(t=\u003eo.availableZ.includes(t))){n.push(o);continue}if(!Xe(Ve(o),Ve(t))){n.push(o);continue}if(1===o.availableZ.length)continue;const i=o.availableZ.filter(t=\u003e!e.includes(t));for(const t of i){const e={...o,capacityMeshNodeId:`${o.capacityMeshNodeId}:z${t}`,availableZ:[t],layer:`z${t}`};n.push(e)}}this.meshNodes=n,this.obstacleQueueIndex+=1,this.stats={obstaclesProcessed:this.obstacleQueueIndex,obstacleCount:this.obstacleQueue.length,meshNodeCount:this.meshNodes.length}}computeProgress(){return 0===this.obstacleQueue.length?1:this.obstacleQueueIndex/this.obstacleQueue.length}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.meshNodes}visualize(){const t=this.obstacleQueueIndex\u003cthis.obstacleQueue.length?this.obstacleQueue[this.obstacleQueueIndex]??null:null,e=this.obstacleQueue.slice(0,this.obstacleQueueIndex),n=t?this.obstacleQueue.slice(this.obstacleQueueIndex+1):[];return{rects:[...e.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(160,160,160,0.10)\",stroke:\"rgba(160,160,160,0.35)\",label:`processed ${t.obstacleId??\"obstacle\"}`})),...t?[{center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.22)\",stroke:\"rgba(255,140,0,0.75)\",label:`active ${t.obstacleId??\"obstacle\"}`}]:[],...n.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,0,0,0.05)\",stroke:\"rgba(255,0,0,0.22)\",label:`pending ${t.obstacleId??\"obstacle\"}`})),...this.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.18)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.45)\":\"rgba(0,120,255,0.45)\"}))]}}};dU.register(class extends Dt{constructor(t){super(t),this.inputProblem=t}inputProblem;static componentKind=\"bga\";initialTopologySolver;removeMeshNodeOverlappingWithUnmarkedObstacle;gapfillDueToNodeRemoval;mergeMeshNodes;markedComponentObstacles=[];unmarkedComponentObstacles=[];pipelineDef=[Lt(\"initialTopologySolver\",YU,t=\u003e[{srj:t.inputProblem.inputSrj,componentBounds:t.inputProblem.detectedComponent.bounds,componentId:t.inputProblem.detectedComponent.componentId,markedComponentObstacles:t.markedComponentObstacles,unmarkedComponentObstacles:t.unmarkedComponentObstacles,viaDiameter:t.inputProblem.viaDiameter}]),Lt(\"removeMeshNodeOverlappingWithUnmarkedObstacle\",ZU,t=\u003e[{meshNodes:t.initialTopologySolver.getOutput(),obstacles:t.unmarkedComponentObstacles,layerCount:t.inputProblem.inputSrj.layerCount}]),Lt(\"gapfillDueToNodeRemoval\",TU,t=\u003e[{meshNodes:t.removeMeshNodeOverlappingWithUnmarkedObstacle.getOutput(),unmarkedComponentObstacles:t.unmarkedComponentObstacles,layerCount:t.inputProblem.inputSrj.layerCount}]),Lt(\"mergeMeshNodes\",UU,t=\u003e[{meshNodes:t.gapfillDueToNodeRemoval.getOutput(),layerCount:t.inputProblem.inputSrj.layerCount}])];_setup(){const t=this.inputProblem.detectedComponent.bounds,e=this.inputProblem.detectedComponent.componentId,n=[],o=[];for(const i of this.inputProblem.inputSrj.obstacles){const r=Ve(i);Xe(t,r)\u0026\u0026(i.componentId!==e?o.push(i):n.push(i))}this.markedComponentObstacles=n,this.unmarkedComponentObstacles=o}getConstructorParams(){return[this.inputProblem]}getOutput(){return{routingRegions:this.mergeMeshNodes?.getOutput()??this.gapfillDueToNodeRemoval?.getOutput()??this.removeMeshNodeOverlappingWithUnmarkedObstacle?.getOutput()??[]}}initialVisualize(){return{rects:[{center:{x:(this.inputProblem.detectedComponent.bounds.minX+this.inputProblem.detectedComponent.bounds.maxX)/2,y:(this.inputProblem.detectedComponent.bounds.minY+this.inputProblem.detectedComponent.bounds.maxY)/2},width:this.inputProblem.detectedComponent.bounds.maxX-this.inputProblem.detectedComponent.bounds.minX,height:this.inputProblem.detectedComponent.bounds.maxY-this.inputProblem.detectedComponent.bounds.minY,fill:\"rgba(0,0,0,0)\",stroke:\"rgba(30,30,30,0.65)\",label:`bga ${this.inputProblem.detectedComponent.componentId}`},...this.markedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,0,0,0.18)\",stroke:\"rgba(255,0,0,0.52)\",label:`pad ${t.obstacleId??\"obstacle\"}`})),...this.unmarkedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.14)\",stroke:\"rgba(255,140,0,0.42)\",label:`foreign ${t.obstacleId??\"obstacle\"}`}))]}}finalVisualize(){return{rects:this.getOutput().routingRegions.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.16)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.36)\":\"rgba(0,120,255,0.42)\"}))}}});var qU=1e-6;function JU(t,e){return t.__zLayers\u0026\u0026t.__zLayers.length\u003e0?Lo(t.__zLayers,e):Do(t.layers,e)}function KU(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(let t=1;t\u003ce.length;t++){const o=e[t]-e[t-1];o\u003eqU\u0026\u0026n.push(o)}const o=n.length\u003e0?Math.max(qU,Math.min(...n)/4):.001,i=[];for(const t of e){const e=i[i.length-1];(void 0===e||Math.abs(t-e)\u003eo)\u0026\u0026i.push(t)}return i}function QU(t){return Array.from({length:Math.max(0,t)},(t,e)=\u003ee)}var tZ=1e-6;function eZ(t){return t.maxX-t.minX\u003etZ\u0026\u0026t.maxY-t.minY\u003etZ}function nZ(t){return function(t){const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return e\u003c=0?0:n/e}(t)\u003e=1.5}function oZ(t,e){const n=[{side:\"top\",distance:Math.abs(t.center.y-e.minY)},{side:\"right\",distance:Math.abs(e.maxX-t.center.x)},{side:\"bottom\",distance:Math.abs(e.maxY-t.center.y)},{side:\"left\",distance:Math.abs(t.center.x-e.minX)}];return n.sort((t,e)=\u003et.distance-e.distance),n[0].side}function iZ(t,e){return t.map((t,n)=\u003e({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e)}))}function rZ(t,e){return t.map((t,n)=\u003e({key:`thermal-pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e)}))}function sZ(t,e){return!!eZ(t)\u0026\u0026Math.min(t.maxX-t.minX,t.maxY-t.minY)\u003c=e}function aZ({side:t,sideObstacles:e,bounds:n,innerBounds:o,narrowThreshold:i}){const r=[];for(let s=0;s\u003ce.length-1;s++){const a=Ee(e[s]),c=Ee(e[s+1]);let l;l=\"top\"===t?{minX:a.maxX,maxX:c.minX,minY:n.minY,maxY:o.minY}:\"right\"===t?{minX:o.maxX,maxX:n.maxX,minY:a.maxY,maxY:c.minY}:\"bottom\"===t?{minX:a.maxX,maxX:c.minX,minY:o.maxY,maxY:n.maxY}:{minX:n.minX,maxX:o.minX,minY:a.maxY,maxY:c.minY},r.push({key:`${t}-gap-${s}`,bounds:l,regionType:\"pad-gap\",isNarrowPadGap:sZ(l,i)})}return r}function cZ({side:t,sideObstacles:e,thermalPadBounds:n,narrowThreshold:o}){const i=[];for(let r=0;r\u003ce.length;r++){const s=Ee(e[r]),a=e[r-1]?Ee(e[r-1]):null,c=e[r+1]?Ee(e[r+1]):null;let l;l=\"top\"===t?{minX:a?(a.maxX+s.minX)/2:s.minX,maxX:c?(s.maxX+c.minX)/2:s.maxX,minY:s.maxY,maxY:n.minY}:\"right\"===t?{minX:n.maxX,maxX:s.minX,minY:a?(a.maxY+s.minY)/2:s.minY,maxY:c?(s.maxY+c.minY)/2:s.maxY}:\"bottom\"===t?{minX:a?(a.maxX+s.minX)/2:s.minX,maxX:c?(s.maxX+c.minX)/2:s.maxX,minY:n.maxY,maxY:s.minY}:{minX:s.maxX,maxX:n.minX,minY:a?(a.maxY+s.minY)/2:s.minY,maxY:c?(s.maxY+c.minY)/2:s.maxY},i.push({key:`inner-${t}-pad-${r}`,bounds:l,regionType:\"pad-gap\",isNarrowPadGap:sZ(l,o)})}return i}function lZ({bounds:t,innerBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:\"corner-nw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-top\",regionType:\"corner\",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:\"corner-ne-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-top\",regionType:\"corner\",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:\"corner-se-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-se-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:\"corner-se-bottom\",regionType:\"corner\",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-bottom\",regionType:\"corner\",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}function dZ({innerBounds:t,thermalPadBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:\"inner-corner-nw-core\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-nw-top\",regionType:\"corner\",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-nw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:\"inner-corner-ne-core\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-ne-top\",regionType:\"corner\",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-ne-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:\"inner-corner-se-core\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-se-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:\"inner-corner-se-bottom\",regionType:\"corner\",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-sw-core\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-sw-bottom\",regionType:\"corner\",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-sw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind=\"qfp_thermalpad\";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=\u003et.componentId===o),s=r.length\u003e0?r:e,{padRingObstacles:a,thermalPadObstacles:c}=function(t){return{padRingObstacles:t.filter(nZ),thermalPadObstacles:t.filter(t=\u003e!nZ(t))}}(s),l=function(t,e){const n={top:[],right:[],bottom:[],left:[]};for(const o of t)n[oZ(o,e)].push(o);return n.top.sort((t,e)=\u003et.center.x-e.center.x),n.bottom.sort((t,e)=\u003et.center.x-e.center.x),n.left.sort((t,e)=\u003et.center.y-e.center.y),n.right.sort((t,e)=\u003et.center.y-e.center.y),n}(a,n),d=function({bounds:t,sideGroups:e}){return{minX:e.left.length\u003e0?Math.max(...e.left.map(t=\u003eEe(t).maxX)):t.minX,maxX:e.right.length\u003e0?Math.min(...e.right.map(t=\u003eEe(t).minX)):t.maxX,minY:e.top.length\u003e0?Math.max(...e.top.map(t=\u003eEe(t).maxY)):t.minY,maxY:e.bottom.length\u003e0?Math.min(...e.bottom.map(t=\u003eEe(t).minY)):t.maxY}}({bounds:n,sideGroups:l}),h=function(t){return 0===t.length?null:t.reduce((t,e)=\u003e{const n=Ee(e);return{minX:Math.min(t.minX,n.minX),maxX:Math.max(t.maxX,n.maxX),minY:Math.min(t.minY,n.minY),maxY:Math.max(t.maxY,n.maxY)}},Ee(t[0]))}(c);if(!h)return this.failed=!0,void(this.error=\"QfpThermalPadTopologyGeneratorSolver requires a thermal pad\");const u=o,p=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,m=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,g=p+2*m,f=this.inputProblem.inputSrj.minTraceWidth+2*m,y=[...iZ(a,t),...rZ(c,t),...aZ({side:\"top\",sideObstacles:l.top,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:\"right\",sideObstacles:l.right,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:\"bottom\",sideObstacles:l.bottom,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:\"left\",sideObstacles:l.left,bounds:n,innerBounds:d,narrowThreshold:f}),...cZ({side:\"top\",sideObstacles:l.top,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:\"right\",sideObstacles:l.right,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:\"bottom\",sideObstacles:l.bottom,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:\"left\",sideObstacles:l.left,thermalPadBounds:h,narrowThreshold:f}),...dZ({innerBounds:d,thermalPadBounds:h,sideGroups:l}),...lZ({bounds:n,innerBounds:d,sideGroups:l})].flatMap(t=\u003efunction({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,isNarrowPadGap:r=!1,obstacleZ:s=[]}){if(!eZ(e))return[];const a=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),c=Math.min(a.width,a.height)\u003eo,l=c?[{availableZ:n.filter(t=\u003e!s.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=\u003es.includes(t)),containsObstacle:!0}].filter(t=\u003et.availableZ.length\u003e0):n.map(t=\u003e({availableZ:[t],containsObstacle:s.includes(t)}));return l.map(e=\u003e({capacityMeshNodeId:1===l.length?t:c?`${t}:${e.containsObstacle?\"obstacle\":\"free\"}`:`${t}:z${e.availableZ[0]}`,center:a.center,width:a.width,height:a.height,layer:`z${e.availableZ.join(\",\")}`,availableZ:e.availableZ,_qfpRegionType:i,_isNarrowQfpPadGap:r,_containsObstacle:e.containsObstacle}))}({nodeId:`qfp_thermalpad:${u}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:g,regionType:t.regionType,isNarrowPadGap:t.isNarrowPadGap,obstacleZ:t.obstacleZ}));this.output={routingRegions:y},this.stats={componentId:o,layerCount:t,viaDiameter:p,obstacleMargin:m,multiLayerThreshold:g,narrowPadGapThreshold:f,thermalPadCount:c.length,perimeterPadCount:a.length,innerCornerRectCount:y.filter(t=\u003et.capacityMeshNodeId.includes(\":inner-corner-\")).length,narrowPadGapNodeCount:y.filter(t=\u003et._isNarrowQfpPadGap).length,topPadCount:l.top.length,rightPadCount:l.right.length,bottomPadCount:l.bottom.length,leftPadCount:l.left.length,multiLayerNodeCount:y.filter(t=\u003et.availableZ.length\u003e1).length,totalMeshNodeCount:y.length},this.solved=!0}getOutput(){if(!this.output)throw new Error(\"QfpThermalPadTopologyGeneratorSolver has not solved yet\");return this.output}});var hZ=1e-6;function uZ(t){return t.maxX-t.minX\u003ehZ\u0026\u0026t.maxY-t.minY\u003ehZ}function pZ(t,e){const n=[{side:\"top\",distance:Math.abs(t.center.y-e.minY)},{side:\"right\",distance:Math.abs(e.maxX-t.center.x)},{side:\"bottom\",distance:Math.abs(e.maxY-t.center.y)},{side:\"left\",distance:Math.abs(t.center.x-e.minX)}];return n.sort((t,e)=\u003et.distance-e.distance),n[0].side}function mZ(t,e){return t.map((t,n)=\u003e({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e),connectedTo:[...t.connectedTo]}))}function gZ(t,e){return!!uZ(t)\u0026\u0026Math.min(t.maxX-t.minX,t.maxY-t.minY)\u003c=e}function fZ({side:t,sideObstacles:e,bounds:n,centralBounds:o,narrowThreshold:i}){const r=[];for(let s=0;s\u003ce.length-1;s++){const a=Ee(e[s]),c=Ee(e[s+1]);let l;l=\"top\"===t?{minX:a.maxX,maxX:c.minX,minY:n.minY,maxY:o.minY}:\"right\"===t?{minX:o.maxX,maxX:n.maxX,minY:a.maxY,maxY:c.minY}:\"bottom\"===t?{minX:a.maxX,maxX:c.minX,minY:o.maxY,maxY:n.maxY}:{minX:n.minX,maxX:o.minX,minY:a.maxY,maxY:c.minY},r.push({key:`${t}-gap-${s}`,bounds:l,regionType:\"pad-gap\",isNarrowPadGap:gZ(l,i)})}return r}function yZ({bounds:t,centralBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:\"corner-nw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-top\",regionType:\"corner\",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:\"corner-ne-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-top\",regionType:\"corner\",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:\"corner-se-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-se-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:\"corner-se-bottom\",regionType:\"corner\",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-bottom\",regionType:\"corner\",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind=\"qfp\";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=\u003et.componentId===o),s=r.length\u003e0?r:e,a=function(t,e){const n={top:[],right:[],bottom:[],left:[]};for(const o of t)n[pZ(o,e)].push(o);return n.top.sort((t,e)=\u003et.center.x-e.center.x),n.bottom.sort((t,e)=\u003et.center.x-e.center.x),n.left.sort((t,e)=\u003et.center.y-e.center.y),n.right.sort((t,e)=\u003et.center.y-e.center.y),n}(s,n),c=function({bounds:t,sideGroups:e}){return{minX:e.left.length\u003e0?Math.max(...e.left.map(t=\u003eEe(t).maxX)):t.minX,maxX:e.right.length\u003e0?Math.min(...e.right.map(t=\u003eEe(t).minX)):t.maxX,minY:e.top.length\u003e0?Math.max(...e.top.map(t=\u003eEe(t).maxY)):t.minY,maxY:e.bottom.length\u003e0?Math.min(...e.bottom.map(t=\u003eEe(t).minY)):t.maxY}}({bounds:n,sideGroups:a}),l=o,d=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,h=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,u=d+2*h,p=this.inputProblem.inputSrj.minTraceWidth+2*h,m=[{key:\"center\",bounds:c,regionType:\"center\"},...mZ(s,t),...fZ({side:\"top\",sideObstacles:a.top,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:\"right\",sideObstacles:a.right,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:\"bottom\",sideObstacles:a.bottom,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:\"left\",sideObstacles:a.left,bounds:n,centralBounds:c,narrowThreshold:p}),...yZ({bounds:n,centralBounds:c,sideGroups:a})].flatMap(t=\u003efunction({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,isNarrowPadGap:r=!1,obstacleZ:s=[],connectedTo:a}){if(!uZ(e))return[];const c=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),l=Math.min(c.width,c.height)\u003eo,d=l?[{availableZ:n.filter(t=\u003e!s.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=\u003es.includes(t)),containsObstacle:!0}].filter(t=\u003et.availableZ.length\u003e0):n.map(t=\u003e({availableZ:[t],containsObstacle:s.includes(t)}));return d.map(e=\u003e({capacityMeshNodeId:1===d.length?t:l?`${t}:${e.containsObstacle?\"obstacle\":\"free\"}`:`${t}:z${e.availableZ[0]}`,center:c.center,width:c.width,height:c.height,layer:`z${e.availableZ.join(\",\")}`,availableZ:e.availableZ,_qfpRegionType:i,_isNarrowQfpPadGap:r,_containsObstacle:e.containsObstacle,_connectedTo:e.containsObstacle?a:void 0}))}({nodeId:`qfp:${l}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:u,regionType:t.regionType,isNarrowPadGap:t.isNarrowPadGap,obstacleZ:t.obstacleZ,connectedTo:t.connectedTo}));this.output={routingRegions:m},this.stats={componentId:o,layerCount:t,viaDiameter:d,obstacleMargin:h,multiLayerThreshold:u,narrowPadGapThreshold:p,narrowPadGapNodeCount:m.filter(t=\u003et._isNarrowQfpPadGap).length,topPadCount:a.top.length,rightPadCount:a.right.length,bottomPadCount:a.bottom.length,leftPadCount:a.left.length,multiLayerNodeCount:m.filter(t=\u003et.availableZ.length\u003e1).length,totalMeshNodeCount:m.length},this.solved=!0}getOutput(){if(!this.output)throw new Error(\"QfpTopologyGeneratorSolver has not solved yet\");return this.output}});var _Z=1e-6;function bZ({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,obstacleZ:r=[],connectedTo:s}){if(!function(t){return t.maxX-t.minX\u003e_Z\u0026\u0026t.maxY-t.minY\u003e_Z}(e))return[];const a=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),c=Math.min(a.width,a.height)\u003eo,l=c?[{availableZ:n.filter(t=\u003e!r.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=\u003er.includes(t)),containsObstacle:!0}].filter(t=\u003et.availableZ.length\u003e0):n.map(t=\u003e({availableZ:[t],containsObstacle:r.includes(t)}));return l.map(e=\u003e({capacityMeshNodeId:1===l.length?t:c?`${t}:${e.containsObstacle?\"obstacle\":\"free\"}`:`${t}:z${e.availableZ[0]}`,center:a.center,width:a.width,height:a.height,layer:`z${e.availableZ.join(\",\")}`,availableZ:e.availableZ,_soicRegionType:i,_containsObstacle:e.containsObstacle,_connectedTo:e.containsObstacle?s:void 0}))}function xZ(t,e){let n=0,o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ce.length;i++){const r=Math.abs(t-e[i]);r\u003co\u0026\u0026(n=i,o=r)}return n}function vZ(t,e){return t.map((t,n)=\u003e({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e),connectedTo:[...t.connectedTo]}))}function SZ(t,e){if(t.componentId!==e.componentId)return!1;const{bounds:n}=e;return t.center.x\u003e=n.minX\u0026\u0026t.center.x\u003c=n.maxX\u0026\u0026t.center.y\u003e=n.minY\u0026\u0026t.center.y\u003c=n.maxY}function IZ({detectedComponent:t,inputSrj:e}){const n=e.obstacles.filter(e=\u003eSZ(e,t)),o=Array.from({length:e.layerCount},(t,e)=\u003ee),i=o.map(t=\u003evo(t,e.layerCount)),r=Array.from(new Set(n.flatMap(t=\u003et.connectedTo))),{bounds:s}=t;return{obstacleId:`${t.componentId}_component_bounds`,componentId:t.componentId,type:\"rect\",layers:i,__zLayers:o,center:{x:(s.minX+s.maxX)/2,y:(s.minY+s.maxY)/2},width:s.maxX-s.minX,height:s.maxY-s.minY,connectedTo:r}}function CZ(t){if(0===t.length)return{minX:0,maxX:0,minY:0,maxY:0};let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t){const t=Ee(r);e=Math.min(e,t.minX),n=Math.max(n,t.maxX),o=Math.min(o,t.minY),i=Math.max(i,t.maxY)}return{minX:e,maxX:n,minY:o,maxY:i}}function PZ(t){const e=t.componentDetectionOutput??[],n=function({detectedComponents:t,inputSrj:e}){return t.map(t=\u003e{const n=e.obstacles.filter(e=\u003eSZ(e,t));return{componentId:t.componentId,componentKind:t.componentKind,memberObstacleIds:n.map((e,n)=\u003ee.obstacleId??`${t.componentId}:member:${n}`),memberObstacles:n,replacementObstacle:IZ({detectedComponent:t,inputSrj:e})}})}({detectedComponents:e,inputSrj:t.inputSrj}),o=t.globalNoConnectionSrj??(e.length\u003e0?function({detectedComponents:t,inputSrj:e}){return{...structuredClone(e),obstacles:[...e.obstacles.filter(e=\u003e!t.some(t=\u003eSZ(e,t))),...t.map(t=\u003eIZ({detectedComponent:t,inputSrj:e}))]}}({detectedComponents:e,inputSrj:t.inputSrj}):t.inputSrj)??t.brokenSrj?.componentsAsObstaclesSrj,i=t.components??n??t.brokenSrj?.components??[];if(!o)throw new Error(\"MultiGraphTopologyPlannerSolver requires globalNoConnectionSrj or detected components\");return{globalNoConnectionSrj:o,components:i}}function MZ({rects:t,components:e}){return t\u0026\u00260!==e.length?t.filter(t=\u003e!function(t){return\"string\"==typeof t.label\u0026\u0026t.label.startsWith(\"node \")}(t)||!e.some(e=\u003efunction({rect:t,obstacle:e}){if(!t.center||void 0===t.width||void 0===t.height)return!1;const n=1e-9,o=Ve({center:t.center,width:t.width,height:t.height}),i=Ve({center:e.center,width:e.width,height:e.height});return NZ({bounds:o,outerBounds:i,epsilon:n})}({rect:t,obstacle:e.replacementObstacle}))):t}function NZ({bounds:t,outerBounds:e,epsilon:n}){return t.minX\u003e=e.minX-n\u0026\u0026t.maxX\u003c=e.maxX+n\u0026\u0026t.minY\u003e=e.minY-n\u0026\u0026t.maxY\u003c=e.maxY+n}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind=\"soic\";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=\u003et.componentId===o),s=r.length\u003e0?r:e,a=function(t){const e=KU(t.map(t=\u003et.center.y)).length;return 2===KU(t.map(t=\u003et.center.x)).length\u0026\u00262!==e?\"vertical-columns\":\"horizontal-rows\"}(s),c=function({obstacles:t,orientation:e}){const n={left:[],right:[],top:[],bottom:[]};if(\"vertical-columns\"===e){const e=KU(t.map(t=\u003et.center.x));for(const o of t)n[0===xZ(o.center.x,e)?\"left\":\"right\"].push(o);return n.left.sort((t,e)=\u003et.center.y-e.center.y),n.right.sort((t,e)=\u003et.center.y-e.center.y),n}const o=KU(t.map(t=\u003et.center.y));for(const e of t)n[0===xZ(e.center.y,o)?\"top\":\"bottom\"].push(e);return n.top.sort((t,e)=\u003et.center.x-e.center.x),n.bottom.sort((t,e)=\u003et.center.x-e.center.x),n}({obstacles:s,orientation:a}),l=function({bounds:t,orientation:e,sideGroups:n}){return\"vertical-columns\"===e?{minX:Math.max(...n.left.map(t=\u003eEe(t).maxX)),maxX:Math.min(...n.right.map(t=\u003eEe(t).minX)),minY:t.minY,maxY:t.maxY}:{minX:t.minX,maxX:t.maxX,minY:Math.max(...n.top.map(t=\u003eEe(t).maxY)),maxY:Math.min(...n.bottom.map(t=\u003eEe(t).minY))}}({bounds:n,orientation:a,sideGroups:c}),d=o,h=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,u=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,p=2*(h+u),m=\"vertical-columns\"===a?[\"left\",\"right\"]:[\"top\",\"bottom\"],g=[{key:\"center\",bounds:l,regionType:\"center\"},...vZ(s,t),...m.flatMap(t=\u003efunction({side:t,sideObstacles:e,bounds:n,centralBounds:o}){const i=[];for(let r=0;r\u003ce.length-1;r++){const s=Ee(e[r]),a=Ee(e[r+1]);let c;c=\"left\"===t?{minX:n.minX,maxX:o.minX,minY:s.maxY,maxY:a.minY}:\"right\"===t?{minX:o.maxX,maxX:n.maxX,minY:s.maxY,maxY:a.minY}:\"top\"===t?{minX:s.maxX,maxX:a.minX,minY:n.minY,maxY:o.minY}:{minX:s.maxX,maxX:a.minX,minY:o.maxY,maxY:n.maxY},i.push({key:`${t}-gap-${r}`,bounds:c,regionType:\"pad-gap\"})}return i}({side:t,sideObstacles:c[t],bounds:n,centralBounds:l}))],f=g.flatMap(t=\u003ebZ({nodeId:`soic:${d}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:p,regionType:t.regionType,obstacleZ:t.obstacleZ,connectedTo:t.connectedTo}));this.output={routingRegions:f},this.stats={componentId:o,layerCount:t,orientation:a,viaDiameter:h,obstacleMargin:u,multiLayerThreshold:p,firstSidePadCount:c[m[0]].length,secondSidePadCount:c[m[1]].length,multiLayerNodeCount:f.filter(t=\u003et.availableZ.length\u003e1).length,totalMeshNodeCount:f.length},this.solved=!0}getOutput(){if(!this.output)throw new Error(\"SoicTopologyGeneratorSolver has not solved yet\");return this.output}});var wZ=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;activeSubSolver=null;currentIndex=0;componentMeshNodes=[];getConstructorParams(){return[this.inputProblem]}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.failed)return this.error=this.activeSubSolver.error,this.failed=!0,void(this.activeSubSolver=null);if(!this.activeSubSolver.solved)return;return this.componentMeshNodes.push(this.activeSubSolver.getOutput().routingRegions),this.currentIndex+=1,void(this.activeSubSolver=null)}if(this.currentIndex\u003e=this.inputProblem.componentSrjs.length)return void(this.solved=!0);const t=this.inputProblem.componentKinds[this.currentIndex],e=this.inputProblem.componentSrjs[this.currentIndex],n={inputSrj:e,detectedComponent:{componentId:this.inputProblem.componentIds[this.currentIndex],componentKind:t,bounds:{__type:\"rect\",...e.bounds}},viaDiameter:this.inputProblem.viaDiameter,obstacleMargin:this.inputProblem.obstacleMargin};this.activeSubSolver=dU.create(n)}getOutput(){return{componentMeshNodes:this.componentMeshNodes}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.inputProblem.componentSrjs[this.currentIndex]??null,e=this.componentMeshNodes.flatMap(t=\u003et);return{rects:[...t?[{center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,fill:\"rgba(0,0,0,0)\",stroke:\"rgba(255,140,0,0.72)\",label:`active component ${this.inputProblem.componentIds[this.currentIndex]??this.currentIndex}`},...t.obstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.10)\",stroke:\"rgba(255,140,0,0.30)\",label:t.obstacleId??t.componentId??\"obstacle\"}))]:[],...e.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.14)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.34)\":\"rgba(0,120,255,0.38)\"}))]}}},TZ=.001;function RZ(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(const t of e){const e=n[n.length-1];(void 0===e||Math.abs(t-e)\u003eTZ)\u0026\u0026n.push(t)}return n}function EZ(t){const e=Math.min(...t),n=Math.max(...t);return!(e\u003c=0)\u0026\u0026n/e\u003c=1.01}function AZ(t){if(!function(t){return EZ(t.map(t=\u003et.width))\u0026\u0026EZ(t.map(t=\u003et.height))}(t))return!1;if(!function(t){return t.every(t=\u003e{const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return!(e\u003c=0)\u0026\u0026n/e\u003c=1.5})}(t))return!1;const e=RZ(t.map(t=\u003et.center.y)),n=RZ(t.map(t=\u003et.center.x)),o=e.length,i=n.length;if(o\u003c3||i\u003c3)return!1;const r=o*i;return!((r\u003e0?t.length/r:0)\u003c.5)\u0026\u0026!!function(t,e,n){if(e.length\u003c3)return!1;if(n.length\u003c3)return!1;const o=new Set(e.slice(1,-1)),i=new Set(n.slice(1,-1));let r=0;for(const e of t)o.has(e.center.y)\u0026\u0026i.has(e.center.x)\u0026\u0026(r+=1);return r\u003e=1}(t,e,n)}function OZ(t){return[Math.round(t.width/TZ),Math.round(t.height/TZ),t.layers.join(\",\")].join(\":\")}function kZ(t){if(t.length\u003c3)return!1;const e=[...t].sort((t,e)=\u003et-e),n=e[1]-e[0];return!(n\u003c=TZ)\u0026\u0026e.every((t,o)=\u003e0===o||Math.abs(t-e[o-1]-n)\u003c=TZ)}function LZ(t){const e=function(t){const e=new Map;for(const n of t){const t=Math.round(n.center.y/TZ),o=Math.round(n.center.x/TZ),i=e.get(t)??{y:n.center.y,obstaclesByX:new Map};i.obstaclesByX.set(o,n),e.set(t,i)}return[...e.values()]}(t);let n=[];for(const t of e){const o=[...t.obstaclesByX.keys()];if(!kZ([...t.obstaclesByX.values()].map(t=\u003et.center.x)))continue;const i=e.filter(t=\u003eo.every(e=\u003et.obstaclesByX.has(e)));if(!kZ(i.map(t=\u003et.y)))continue;const r=i.flatMap(t=\u003eo.map(e=\u003et.obstaclesByX.get(e)));r.length\u003en.length\u0026\u0026(n=r)}return n}function DZ(t){if(AZ(t))return t;const e=Map.groupBy(t,OZ);let n=[];for(const t of e.values()){const e=LZ(t);e.length\u003en.length\u0026\u0026(n=e)}return n.length\u003e0?n:null}function zZ(t){const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return e\u003e0\u0026\u0026n/e\u003e=1.5}function FZ({perimeterPadObstacles:t,thermalPadObstacles:e}){if(0===e.length)return!0;if(e.length\u003e4)return!1;const n=CZ(t),o=n.maxX-n.minX,i=n.maxY-n.minY,r=n.minX+.2*o,s=n.maxX-.2*o,a=n.minY+.2*i,c=n.maxY-.2*i,l=Math.min(...t.map(t=\u003eMath.min(t.width,t.height)));return e.every(t=\u003e{const e=Math.min(t.width,t.height);return t.center.x\u003e=r\u0026\u0026t.center.x\u003c=s\u0026\u0026t.center.y\u003e=a\u0026\u0026t.center.y\u003c=c\u0026\u0026e\u003el})}function BZ(t){if(t.length\u003c12)return!1;if(t.length\u003e32)return!1;const{counts:e,maxNearestSideRatio:n}=function(t){const e=CZ(t),n=e.maxX-e.minX,o=e.maxY-e.minY,i={top:0,right:0,bottom:0,left:0};if(n\u003c=0||o\u003c=0)return{counts:i,maxNearestSideRatio:1};let r=0;for(const s of t){const t=s.width\u003es.height,a=[{side:\"top\",distance:Math.abs(s.center.y-e.minY),axisSpan:o,orientationMatches:!t},{side:\"right\",distance:Math.abs(e.maxX-s.center.x),axisSpan:n,orientationMatches:t},{side:\"bottom\",distance:Math.abs(e.maxY-s.center.y),axisSpan:o,orientationMatches:!t},{side:\"left\",distance:Math.abs(s.center.x-e.minX),axisSpan:n,orientationMatches:t}].filter(t=\u003et.orientationMatches).sort((t,e)=\u003et.distance-e.distance)[0];i[a.side]+=1,r=Math.max(r,a.distance/a.axisSpan)}return{counts:i,maxNearestSideRatio:r}}(t);return e.top\u003e=3\u0026\u0026e.right\u003e=3\u0026\u0026e.bottom\u003e=3\u0026\u0026e.left\u003e=3\u0026\u0026n\u003c=.25}function jZ(t){const e=function(t){return t.filter(zZ)}(t);return{perimeterPadObstacles:e,thermalPadObstacles:t.filter(t=\u003e!zZ(t))}}function $Z(t){const e=Math.min(...t),n=Math.max(...t);return!(e\u003c=0)\u0026\u0026n/e\u003c=1.01}function YZ(t,e){let n=0,o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ce.length;i++){const r=Math.abs(t-e[i]);r\u003co\u0026\u0026(n=i,o=r)}return n}function XZ({memberObstacles:t,inputSrj:e}){if(!function(t){return $Z(t.map(t=\u003et.width))\u0026\u0026$Z(t.map(t=\u003et.height))}(t))return!1;const n=RZ(t.map(t=\u003et.center.y)),o=RZ(t.map(t=\u003et.center.x));if(!(2===n.length\u0026\u0026o.length\u003e=4||2===o.length\u0026\u0026n.length\u003e=4))return!1;const i=function({memberObstacles:t,rowAxisValues:e,columnAxisValues:n}){if(2===e.length\u0026\u0026n.length\u003e=4){const n=[[],[]];for(const o of t)n[YZ(o.center.y,e)].push(o);return Math.min(...n[1].map(t=\u003et.center.y-t.height/2))-Math.max(...n[0].map(t=\u003et.center.y+t.height/2))}if(2===n.length\u0026\u0026e.length\u003e=4){const e=[[],[]];for(const o of t)e[YZ(o.center.x,n)].push(o);return Math.min(...e[1].map(t=\u003et.center.x-t.width/2))-Math.max(...e[0].map(t=\u003et.center.x+t.width/2))}return null}({memberObstacles:t,rowAxisValues:n,columnAxisValues:o});if(null===i)return!1;return i\u003e2*(Yo(e).padDiameter+(e.defaultObstacleMargin??.15))}var VZ=[class t{constructor(t){this.params=t}params;static componentKind=\"qfp_thermalpad\";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){const{perimeterPadObstacles:e,thermalPadObstacles:n}=jZ(t);return 0!==n.length\u0026\u0026!!BZ(e)\u0026\u0026FZ({perimeterPadObstacles:e,thermalPadObstacles:n})}(t)}},class t{constructor(t){this.params=t}params;static componentKind=\"qfp\";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){const{perimeterPadObstacles:e,thermalPadObstacles:n}=jZ(t);return!(n.length\u003e0)\u0026\u0026!!FZ({perimeterPadObstacles:e,thermalPadObstacles:n})\u0026\u0026BZ(e)}(t)}},class t{constructor(t){this.params=t}params;static componentKind=\"soic\";componentKind=t.componentKind;static isMatch(t){return XZ(t)}},class t{constructor(t){this.params=t}params;static componentKind=\"bga\";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){return null!==DZ(t)}(t)}}];function WZ(t){return function(t){for(const e of VZ)if(e.isMatch(t))return new e(t);return null}(t)?.componentKind??null}var HZ=class extends kt{inputSrj;initialized=!1;groupedComponentObstacles={};groupedComponentKinds={};unprocessedComponentIds=[];detectedComponents=[];currentComponentId=null;currentMemberObstacles=[];output=null;constructor({inputSrj:t}){super(),this.inputSrj=t}getConstructorParams(){return[{inputSrj:this.inputSrj}]}_step(){this.initialized?this.output?this.solved=!0:null!==this.currentComponentId||this.unprocessedComponentIds.length\u003e0?this.processNextComponent():(this.finalizeOutput(),this.solved=!0):this.initializeDetectionState()}getOutput(){if(!this.output)throw new Error(\"ComponentDetectionSolver has not solved yet\");return this.output}visualize(){const t=[];t.push(...this.inputSrj.obstacles.filter(t=\u003e!t.componentId).map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(120, 120, 120, 0.10)\",stroke:\"rgba(120, 120, 120, 0.40)\",label:t.obstacleId,layer:t.layers.join(\",\"),step:0})));const e=new Set(this.detectedComponents.map(t=\u003et.componentId));for(const n of this.inputSrj.obstacles){if(!n.componentId)continue;if(e.has(n.componentId))continue;const o=n.componentId===this.currentComponentId,i=Ro(n.componentId),r=this.groupedComponentKinds[n.componentId];t.push({center:n.center,width:n.width,height:n.height,fill:To(i,o?.55:.82),stroke:To(i,o?.1:.45),label:r?`${n.componentId} ${r.toUpperCase()}`:n.componentId,layer:n.layers.join(\",\"),step:o?1:0})}for(const e of this.detectedComponents){const n=Ro(e.componentId);t.push({center:{x:(e.bounds.minX+e.bounds.maxX)/2,y:(e.bounds.minY+e.bounds.maxY)/2},width:e.bounds.maxX-e.bounds.minX,height:e.bounds.maxY-e.bounds.minY,fill:To(n,.88),stroke:To(n,.1),label:`${e.componentId} ${e.componentKind.toUpperCase()} region`,step:2})}return{title:this.getVisualizationTitle(),rects:t,lines:[],points:[],circles:[]}}preview(){return this.visualize()}initializeDetectionState(){this.initialized=!0,this.groupedComponentKinds={},this.groupedComponentObstacles=this.groupObstaclesByComponentId({obstacles:this.inputSrj.obstacles}),this.unprocessedComponentIds=Object.keys(this.groupedComponentObstacles).sort(),this.detectedComponents=[],this.currentComponentId=null,this.currentMemberObstacles=[],this.output=null}processNextComponent(){if(!this.currentComponentId){const t=this.unprocessedComponentIds.shift();return t?(this.currentComponentId=t,void(this.currentMemberObstacles=this.groupedComponentObstacles[t]??[])):(this.currentComponentId=null,void(this.currentMemberObstacles=[]))}if(0===this.currentMemberObstacles.length)return this.currentComponentId=null,void(this.currentMemberObstacles=[]);this.detectedComponents.push(this.createDetectedComponent({componentId:this.currentComponentId,componentKind:this.groupedComponentKinds[this.currentComponentId],memberObstacles:this.currentMemberObstacles})),this.currentComponentId=null,this.currentMemberObstacles=[]}finalizeOutput(){this.output=this.detectedComponents.map(t=\u003e({...t,bounds:{...t.bounds}})),this.stats={initialized:this.initialized,totalComponentCount:Object.keys(this.groupedComponentObstacles).length,detectedComponentCount:this.detectedComponents.length,detectedBgaComponentCount:this.detectedComponents.filter(t=\u003e\"bga\"===t.componentKind).length,detectedQfpComponentCount:this.detectedComponents.filter(t=\u003e\"qfp\"===t.componentKind).length,detectedQfpComponentIds:this.detectedComponents.filter(t=\u003e\"qfp\"===t.componentKind).map(t=\u003et.componentId),detectedQfpThermalPadComponentCount:this.detectedComponents.filter(t=\u003e\"qfp_thermalpad\"===t.componentKind).length,detectedQfpThermalPadComponentIds:this.detectedComponents.filter(t=\u003e\"qfp_thermalpad\"===t.componentKind).map(t=\u003et.componentId),detectedSoicComponentCount:this.detectedComponents.filter(t=\u003e\"soic\"===t.componentKind).length,detectedSoicComponentIds:this.detectedComponents.filter(t=\u003e\"soic\"===t.componentKind).map(t=\u003et.componentId),remainingComponentCount:this.unprocessedComponentIds.length,hasActiveComponent:null!==this.currentComponentId}}groupObstaclesByComponentId({obstacles:t}){const e={},n={};for(const n of t)n.componentId\u0026\u0026(e[n.componentId]??=[],e[n.componentId].push(n));const o=Object.entries(e).flatMap(([t,e])=\u003e{const o=this.inputSrj.bounds;if(e.some(t=\u003e!NZ({bounds:Ee(t),outerBounds:o,epsilon:0})))return[];const i=WZ({memberObstacles:e,inputSrj:this.inputSrj});if(!i)return[];n[t]=i;return[[t,\"bga\"===i?DZ(e):e]]});return this.groupedComponentKinds=n,Object.fromEntries(o)}createDetectedComponent({componentId:t,componentKind:e,memberObstacles:n}){return{componentId:t,componentKind:e,bounds:{__type:\"rect\",...CZ(n)}}}getVisualizationTitle(){const t=Object.keys(this.groupedComponentObstacles).length||new Set(this.inputSrj.obstacles.map(t=\u003et.componentId).filter(t=\u003eBoolean(t))).size,e=this.detectedComponents.length;return this.initialized?this.output||this.solved?`Component Detection: done ${e}/${t}`:null!==this.currentComponentId||this.unprocessedComponentIds.length\u003e0?`Component Detection: ${e}/${t} processed`:`Component Detection: finalizing ${e}/${t}`:\"Component Detection: setup\"}},GZ=t=\u003et.componentId\u0026\u0026t.obstacleId?`${t.componentId}\\n${t.obstacleId}`:t.componentId??t.obstacleId??\"obstacle\",UZ=class extends Dt{rectBoundsComponentDetection;pipelineDef=[Lt(\"rectBoundsComponentDetection\",HZ,t=\u003e[{inputSrj:t.inputProblem.inputSrj}])];getConstructorParams(){return[this.inputProblem]}getOutput(){const t=this.getStageOutput(\"rectBoundsComponentDetection\");if(!t)throw new Error(\"ComponentDetectionSolver has not solved yet\");return t}initialVisualize(){const{bounds:t}=this.inputProblem.inputSrj;return{title:\"Component Detection: board and grouped component pads\",rects:[{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,fill:\"rgba(0, 0, 0, 0)\",stroke:\"rgba(40, 40, 40, 0.7)\",label:\"Board bounds\",step:0},...this.inputProblem.inputSrj.obstacles.map(t=\u003e{const e=t.componentId?Ro(t.componentId):null;return{center:t.center,width:t.width,height:t.height,fill:e?To(e,.72):\"rgba(120, 120, 120, 0.10)\",stroke:e?To(e,.28):\"rgba(120, 120, 120, 0.40)\",label:GZ(t),layer:t.layers.join(\",\"),step:t.componentId?1:0}})],lines:[],points:[],circles:[]}}},ZZ=1e-9;function qZ(t){return Ve({center:t.center,width:t.width,height:t.height})}function JZ(t,e){const n={minX:Math.max(t.minX,e.minX),maxX:Math.min(t.maxX,e.maxX),minY:Math.max(t.minY,e.minY),maxY:Math.min(t.maxY,e.maxY)};return KZ(n)?n:null}function KZ(t){const e=t.maxX-t.minX,n=t.maxY-t.minY,o=Number.isFinite(e)\u0026\u0026e\u003eZZ,i=Number.isFinite(n)\u0026\u0026n\u003eZZ;return o\u0026\u0026i}function QZ(t){!function(t){if(!Number.isInteger(t.layerCount))throw new Error(\"TopologyMergingSolver: layerCount must be an integer\");if(t.layerCount\u003c=0)throw new Error(\"TopologyMergingSolver: layerCount must be positive\");if(0===t.nodeGroups.length)throw new Error(\"TopologyMergingSolver: at least one node group is required\");const e=new Set;let n=0;for(const o of t.nodeGroups){if(e.has(o.groupId))throw new Error(`TopologyMergingSolver: duplicate topology group id \"${o.groupId}\"`);if(e.add(o.groupId),n+=o.nodes.length,0===o.nodes.length)throw new Error(`TopologyMergingSolver: topology group \"${o.groupId}\" is empty`);const i=new Set;for(const e of o.nodes){if(i.has(e.capacityMeshNodeId))throw new Error(`TopologyMergingSolver: duplicate node id \"${e.capacityMeshNodeId}\" in group \"${o.groupId}\"`);i.add(e.capacityMeshNodeId),tq({node:e,groupId:o.groupId,layerCount:t.layerCount})}}if(0===n)throw new Error(\"TopologyMergingSolver: topology node groups are empty\")}(t);const e=[],n=new Map;for(let o=0;o\u003ct.nodeGroups.length;o++){const i=t.nodeGroups[o];for(const t of i.nodes){const r={sourceKey:`${i.groupId}:${t.capacityMeshNodeId}`,groupIndex:o,node:t,bounds:qZ(t)};e.push(r),n.set(r.sourceKey,r)}}return{preparedNodes:e,preparedNodeBySourceKey:n}}function tq({node:t,groupId:e,layerCount:n}){if(!KZ(qZ(t)))throw new Error(`TopologyMergingSolver: node \"${t.capacityMeshNodeId}\" in group \"${e}\" has invalid bounds`);if(0===t.availableZ.length)throw new Error(`TopologyMergingSolver: node \"${t.capacityMeshNodeId}\" in group \"${e}\" has no available layers`);const o=[...new Set(t.availableZ)].sort((t,e)=\u003et-e),i=o.some(t=\u003e!Number.isInteger(t)||t\u003c0||t\u003e=n),r=o.length===t.availableZ.length\u0026\u0026o.every((e,n)=\u003ee===t.availableZ[n]);if(i||!r)throw new Error(`TopologyMergingSolver: node \"${t.capacityMeshNodeId}\" in group \"${e}\" has invalid or unsorted availableZ`)}var eq=1e-5,nq=4e-5;function oq({regions:t,preparedNodeBySourceKey:e,nodeGroups:n,provenance:o,preserveSourceIds:i=!0}){i\u0026\u0026(o.groupIndexesByNodeId.clear(),o.sourceKeysByNodeId.clear());const r=[...t].sort((t,e)=\u003et.bounds.minX-e.bounds.minX||t.bounds.minY-e.bounds.minY||t.bounds.maxX-e.bounds.maxX||t.bounds.maxY-e.bounds.maxY||t.availableZ[0]-e.availableZ[0]),s=new Set;return r.map((t,r)=\u003e{const a=t.sourceKeys.map(t=\u003e{const n=e.get(t);if(!n)throw new Error(`TopologyMergingSolver: missing source node for \"${t}\"`);return n}),c=a.map(({node:t})=\u003et),l=function({sourceNodes:t,isComponentTopologyNode:e}){if(1===t.length)return{_isComponentTopologyNode:!!e||t[0]._isComponentTopologyNode};const n=t.map(t=\u003et.capacityMeshNodeId),o=iq(t.map(t=\u003et._targetConnectionName),\"target connection\",n),i=iq(t.map(t=\u003et._offBoardConnectionId),\"off-board connection\",n),r=iq(t.map(t=\u003et._offboardNetName),\"off-board net\",n),s=Array.from(new Set(t.flatMap(t=\u003et._offBoardConnectedCapacityMeshNodeIds??[]))),a=Array.from(new Set(t.flatMap(t=\u003et._connectedTo??[])));return{_containsObstacle:t.some(t=\u003et._containsObstacle)||void 0,_completelyInsideObstacle:t.some(t=\u003et._completelyInsideObstacle)||void 0,_containsTarget:t.some(t=\u003et._containsTarget)||void 0,_targetConnectionName:o,_isVirtualOffboard:t.some(t=\u003et._isVirtualOffboard)||void 0,_offboardNetName:r,_offBoardConnectionId:i,_offBoardConnectedCapacityMeshNodeIds:s.length\u003e0?s:void 0,_qfpRegionType:rq(t.map(t=\u003et._qfpRegionType)),_isNarrowQfpPadGap:t.some(t=\u003et._isNarrowQfpPadGap)||void 0,_soicRegionType:rq(t.map(t=\u003et._soicRegionType)),_isComponentTopologyNode:e||void 0,_connectedTo:a.length\u003e0?a:void 0}}({sourceNodes:c,isComponentTopologyNode:a.some(({groupIndex:t})=\u003en[t].isComponent)}),d=i\u0026\u00261===a.length?a[0].node:null,h=Boolean(d\u0026\u0026function({region:t,sourceNode:e,usedNodeIds:n}){const o=qZ(e),i=Math.abs(t.bounds.minX-o.minX)\u003c=eq\u0026\u0026Math.abs(t.bounds.maxX-o.maxX)\u003c=eq\u0026\u0026Math.abs(t.bounds.minY-o.minY)\u003c=eq\u0026\u0026Math.abs(t.bounds.maxY-o.maxY)\u003c=eq,r=t.availableZ.length===e.availableZ.length\u0026\u0026t.availableZ.every((t,n)=\u003et===e.availableZ[n]);return i\u0026\u0026r\u0026\u0026!n.has(e.capacityMeshNodeId)}({region:t,sourceNode:d,usedNodeIds:s}));let u=h?d.capacityMeshNodeId:`topology_merge_${r}`;for(;s.has(u);)u=`${u}_next`;return s.add(u),i\u0026\u0026(o.groupIndexesByNodeId.set(u,[...new Set(a.map(({groupIndex:t})=\u003et))]),o.sourceKeysByNodeId.set(u,[...t.sourceKeys])),{...d??c[0],...l,capacityMeshNodeId:u,center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,layer:`z${t.availableZ.join(\",\")}`,availableZ:[...t.availableZ],_adjacentNodeIds:void 0,_parent:void 0,_strawNode:void 0,_strawParentCapacityMeshNodeId:void 0}})}function iq(t,e,n){const o=Array.from(new Set(t.filter(t=\u003evoid 0!==t)));if(o.length\u003e1)throw new Error(`TopologyMergingSolver: conflicting ${e} values for overlapping source nodes ${n.join(\", \")}`);return o[0]}function rq(t){const e=Array.from(new Set(t.filter(t=\u003evoid 0!==t)));return 1===e.length?e[0]:void 0}function sq({node:t,sourceKey:e,preparedNodeBySourceKey:n}){const o=n.get(e);if(!o)throw new Error(`TopologyMergingSolver: missing source node for output \"${t.capacityMeshNodeId}\"`);const i=qZ(t),r=i.minX\u003e=o.bounds.minX-nq\u0026\u0026i.maxX\u003c=o.bounds.maxX+nq\u0026\u0026i.minY\u003e=o.bounds.minY-nq\u0026\u0026i.maxY\u003c=o.bounds.maxY+nq,s=t.availableZ.every(t=\u003eo.node.availableZ.includes(t));if(!r||!s)throw new Error(`TopologyMergingSolver: output node \"${t.capacityMeshNodeId}\" escapes its source geometry or layers`)}function aq({groupIndexesA:t,groupIndexesB:e,sourceKeysA:n,sourceKeysB:o,sharedLayers:i,preparedNodeBySourceKey:r}){if(1!==t.length||1!==e.length||t[0]!==e[0]||1!==n.length||1!==o.length||n[0]===o[0])return!1;const s=r.get(n[0]),a=r.get(o[0]);if(!s||!a||0===i.length)return!1;return i.some(t=\u003es.node.availableZ.includes(t)\u0026\u0026a.node.availableZ.includes(t))\u0026\u0026null!==JZ(s.bounds,a.bounds)}function cq(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(const t of e){const e=n[n.length-1];(void 0===e||Math.abs(t-e)\u003eeq)\u0026\u0026n.push(t)}return n}function lq(t,e){return e.x\u003e=t.minX-eq\u0026\u0026e.x\u003c=t.maxX+eq\u0026\u0026e.y\u003e=t.minY-eq\u0026\u0026e.y\u003c=t.maxY+eq}function dq({coveringNodes:t,nodeGroups:e,layerCount:n}){const o=new Map;for(let i=0;i\u003cn;i++){const n=t.filter(({node:t})=\u003et.availableZ.includes(i)).sort((t,e)=\u003et.sourceKey.localeCompare(e.sourceKey));if(0===n.length)continue;const r=new Set(n.map(({groupIndex:t})=\u003et)),s=n.filter(({node:t})=\u003et._containsObstacle\u0026\u0026t._containsTarget),a=s.filter(({groupIndex:t})=\u003e!e[t].isComponent),c=new Set(s.map(({groupIndex:t})=\u003et)),l=s.length\u003e0?a.length\u003e0||1===c.size?\"target-passthrough\":\"target-merged\":1===r.size?\"passthrough\":\"merged\",d=gq({topologyMode:l,nodesOnLayer:n,targetObstacleNodes:s,globalTargetObstacleNodes:a});for(const t of d){const e=JSON.stringify({mode:l,sourceKeys:t}),n=o.get(e);n?n.availableZ.push(i):o.set(e,{availableZ:[i],sourceKeys:t,topologyMode:l,topologySignature:e})}}return[...o.values()]}function hq(t){return JSON.stringify({availableZ:t.availableZ,topologySignature:t.topologySignature})}function uq(t){return JSON.stringify({mergeKey:hq(t),minY:t.bounds.minY.toPrecision(15),maxY:t.bounds.maxY.toPrecision(15)})}function pq(t){return JSON.stringify({mergeKey:hq(t),minX:t.bounds.minX.toPrecision(15),maxX:t.bounds.maxX.toPrecision(15)})}function mq(t,e){const n=new Map;for(const o of t){const t=\"horizontal\"===e?uq(o):pq(o),i=n.get(t)??[];i.push(o),n.set(t,i)}return[...n.values()].flatMap(t=\u003efunction(t,e){const n=[...t].sort((t,n)=\u003e\"horizontal\"===e?t.bounds.minX-n.bounds.minX:t.bounds.minY-n.bounds.minY),o=[];for(const t of n){const n=o[o.length-1],i=void 0!==n\u0026\u0026(\"horizontal\"===e?Math.abs(n.bounds.maxX-t.bounds.minX)\u003c=eq:Math.abs(n.bounds.maxY-t.bounds.minY)\u003c=eq);n\u0026\u0026i?\"horizontal\"===e?n.bounds.maxX=t.bounds.maxX:n.bounds.maxY=t.bounds.maxY:o.push({...t,bounds:{...t.bounds},availableZ:[...t.availableZ],sourceKeys:[...t.sourceKeys]})}return o}(t,e))}function gq({topologyMode:t,nodesOnLayer:e,targetObstacleNodes:n,globalTargetObstacleNodes:o}){if(\"target-passthrough\"===t){return(o.length\u003e0?o:n).map(({sourceKey:t})=\u003e[t])}return\"target-merged\"===t?[n.map(({sourceKey:t})=\u003et).sort()]:\"passthrough\"===t?e.map(({sourceKey:t})=\u003e[t]):[e.map(({sourceKey:t})=\u003et).sort()]}var fq=class extends kt{constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e5;const{preparedNodes:e,preparedNodeBySourceKey:n}=QZ(t);this.preparedNodes=e,this.preparedNodeBySourceKey=n,this.xCoordinates=cq(this.preparedNodes.flatMap(({bounds:t})=\u003e[t.minX,t.maxX])),this.stats={inputNodeCount:this.preparedNodes.length,xSlabCount:Math.max(0,this.xCoordinates.length-1),processedXSlabCount:0,atomicRegionCount:0,outputNodeCount:0}}inputProblem;preparedNodes;preparedNodeBySourceKey;outputProvenance={groupIndexesByNodeId:new Map,sourceKeysByNodeId:new Map};xCoordinates;atomicRegions=[];outputNodes=[];currentXIndex=0;getConstructorParams(){return[this.inputProblem]}_step(){if(1===this.inputProblem.nodeGroups.length)return void this.completePassthroughTopology();if(this.currentXIndex\u003cthis.xCoordinates.length-1)return this.processCurrentXSlab(),this.currentXIndex+=1,this.stats.processedXSlabCount=this.currentXIndex,void(this.stats.atomicRegionCount=this.atomicRegions.length);const t=function(t){let e=t;for(;;){const t=mq(e,\"horizontal\"),n=mq(t,\"vertical\");if(n.length===e.length)return n;e=n}}(function({regions:t,preparedNodeBySourceKey:e}){const n=new Map;for(const e of t)for(const t of e.sourceKeys){const o=n.get(t)??new Set;o.add(e.topologyMode),n.set(t,o)}const o=new Set([...n.entries()].filter(([,t])=\u003e1===t.size\u0026\u0026t.has(\"target-passthrough\")).map(([t])=\u003et));return 0===o.size?t:[...t.filter(t=\u003e\"target-passthrough\"!==t.topologyMode||!o.has(t.sourceKeys[0])),...[...o].map(t=\u003e{const n=e.get(t);if(!n)throw new Error(`TopologyMergingSolver: missing authoritative target source \"${t}\"`);return{bounds:{...n.bounds},availableZ:[...n.node.availableZ],sourceKeys:[t],topologyMode:\"target-passthrough\",topologySignature:JSON.stringify({mode:\"target-passthrough\",sourceKeys:[t]})}})]}({regions:this.atomicRegions,preparedNodeBySourceKey:this.preparedNodeBySourceKey}));this.outputNodes=oq({regions:t,preparedNodeBySourceKey:this.preparedNodeBySourceKey,nodeGroups:this.inputProblem.nodeGroups,provenance:this.outputProvenance}),function({nodes:t,preparedNodeBySourceKey:e,provenance:n}){const o=new Set;for(const i of t){if(o.has(i.capacityMeshNodeId))throw new Error(`TopologyMergingSolver: duplicate output node id \"${i.capacityMeshNodeId}\"`);if(o.add(i.capacityMeshNodeId),!KZ(qZ(i)))throw new Error(`TopologyMergingSolver: output node \"${i.capacityMeshNodeId}\" has invalid bounds`);if(0===i.availableZ.length)throw new Error(`TopologyMergingSolver: output node \"${i.capacityMeshNodeId}\" has no available layers`);const t=n.sourceKeysByNodeId.get(i.capacityMeshNodeId);if(!t)throw new Error(`TopologyMergingSolver: missing output provenance for node \"${i.capacityMeshNodeId}\"`);1===t.length\u0026\u0026sq({node:i,sourceKey:t[0],preparedNodeBySourceKey:e})}for(let o=0;o\u003ct.length;o++){const i=t[o];for(let r=o+1;r\u003ct.length;r++){const o=t[r],s=i.availableZ.filter(t=\u003eo.availableZ.includes(t));if(0===s.length)continue;const a=JZ(qZ(i),qZ(o));if(!a)continue;const c=a.maxX-a.minX,l=a.maxY-a.minY;if(c\u003c=nq||l\u003c=nq)continue;const d=n.groupIndexesByNodeId.get(i.capacityMeshNodeId),h=n.groupIndexesByNodeId.get(o.capacityMeshNodeId);if(!d||!h)throw new Error(`TopologyMergingSolver: missing output provenance for overlapping nodes \"${i.capacityMeshNodeId}\" and \"${o.capacityMeshNodeId}\"`);const u=n.sourceKeysByNodeId.get(i.capacityMeshNodeId),p=n.sourceKeysByNodeId.get(o.capacityMeshNodeId);if(!u||!p)throw new Error(`TopologyMergingSolver: missing source provenance for overlapping nodes \"${i.capacityMeshNodeId}\" and \"${o.capacityMeshNodeId}\"`);if(!aq({groupIndexesA:d,groupIndexesB:h,sourceKeysA:u,sourceKeysB:p,sharedLayers:s,preparedNodeBySourceKey:e}))throw new Error(`TopologyMergingSolver: output nodes \"${i.capacityMeshNodeId}\" and \"${o.capacityMeshNodeId}\" have an unresolved inter-group overlap on a shared layer`)}}}({nodes:this.outputNodes,preparedNodeBySourceKey:this.preparedNodeBySourceKey,provenance:this.outputProvenance}),this.stats.outputNodeCount=this.outputNodes.length,this.stats.compactedRegionCount=t.length,this.solved=!0}getOutput(){if(!this.solved)throw new Error(\"TopologyMergingSolver: getOutput() called before the solver completed\");return this.outputNodes}computeProgress(){const t=Math.max(1,this.xCoordinates.length-1);return this.solved?1:Math.min(.99,this.currentXIndex/t)}visualize(){const t=this.solved?this.outputNodes:oq({regions:this.atomicRegions,preparedNodeBySourceKey:this.preparedNodeBySourceKey,nodeGroups:this.inputProblem.nodeGroups,provenance:this.outputProvenance,preserveSourceIds:!1});return{title:`Topology Merging: ${t.length} refined regions`,coordinateSystem:\"cartesian\",rects:t.map(t=\u003e({...Dc(t,{rectMargin:.01,zOffset:.02}),label:`${t.capacityMeshNodeId}\\navailableZ: ${t.availableZ.join(\",\")}\\ncomponent: ${t._isComponentTopologyNode?\"yes\":\"no\"}`})),lines:[],points:[],circles:[],texts:[]}}completePassthroughTopology(){const t=this.inputProblem.nodeGroups[0];this.outputNodes=t.nodes;for(const e of this.outputNodes)this.outputProvenance.groupIndexesByNodeId.set(e.capacityMeshNodeId,[0]),this.outputProvenance.sourceKeysByNodeId.set(e.capacityMeshNodeId,[`${t.groupId}:${e.capacityMeshNodeId}`]);this.stats.processedXSlabCount=this.stats.xSlabCount,this.stats.atomicRegionCount=0,this.stats.compactedRegionCount=0,this.stats.outputNodeCount=this.outputNodes.length,this.stats.passthroughNodeCount=this.outputNodes.length,this.solved=!0}processCurrentXSlab(){const t=this.xCoordinates[this.currentXIndex],e=this.xCoordinates[this.currentXIndex+1];if(e-t\u003c=eq)return;const n=(t+e)/2,o=this.preparedNodes.filter(({bounds:t})=\u003en\u003e=t.minX-eq\u0026\u0026n\u003c=t.maxX+eq),i=cq(o.flatMap(({bounds:t})=\u003e[t.minY,t.maxY]));for(let r=0;r\u003ci.length-1;r++){const s=i[r],a=i[r+1];if(a-s\u003c=eq)continue;const c={x:n,y:(s+a)/2},l=o.filter(({bounds:t})=\u003elq(t,c));if(0===l.length)continue;const d=dq({coveringNodes:l,nodeGroups:this.inputProblem.nodeGroups,layerCount:this.inputProblem.layerCount});for(const n of d)this.atomicRegions.push({bounds:{minX:t,maxX:e,minY:s,maxY:a},availableZ:n.availableZ,sourceKeys:n.sourceKeys,topologyMode:n.topologyMode,topologySignature:n.topologySignature})}}};function yq({meshNodes:t,components:e}){return 0===e.length?t:t.map(t=\u003e{const n=e.some(e=\u003efunction({node:t,component:e}){const{replacementObstacle:n}=e,o=Math.abs(t.center.x-n.center.x)\u003c=ZZ\u0026\u0026Math.abs(t.center.y-n.center.y)\u003c=ZZ\u0026\u0026Math.abs(t.width-n.width)\u003c=ZZ\u0026\u0026Math.abs(t.height-n.height)\u003c=ZZ;if(\"qfp\"!==e.componentKind\u0026\u0026\"qfp_thermalpad\"!==e.componentKind\u0026\u0026\"soic\"!==e.componentKind)return o;const i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=n.center.y-n.height/2,a=n.center.y+n.height/2,c=t.center.x\u003e=i-ZZ\u0026\u0026t.center.x\u003c=r+ZZ\u0026\u0026t.center.y\u003e=s-ZZ\u0026\u0026t.center.y\u003c=a+ZZ,l=t.width*t.height,d=n.width*n.height,h=c\u0026\u0026l\u003e=.2*d;return o||h}({node:t,component:e}));return n?{...t,_containsObstacle:void 0,_completelyInsideObstacle:void 0,_containsTarget:void 0,_targetConnectionName:void 0,_connectedTo:void 0}:t})}var _q=class extends Dt{globalTopologySolver;componentTopologyBatchSolver;normalizedInput;pipelineDef=[Lt(\"globalTopologySolver\",Kn,t=\u003e[t.getGlobalTopologySolverInput()]),Lt(\"componentTopologyBatchSolver\",wZ,t=\u003e[{componentSrjs:t.getComponentNoConnectionSrjs(),componentIds:t.normalizedInput.components.map(t=\u003et.componentId),componentKinds:t.normalizedInput.components.map(t=\u003et.componentKind),viaDiameter:t.inputProblem.viaDiameter,obstacleMargin:t.inputProblem.obstacleMargin}])];constructor(t){super(t),this.normalizedInput=PZ(t)}getConstructorParams(){return[this.inputProblem]}getOutput(){const t=yq({meshNodes:this.getStageOutput(\"globalTopologySolver\")?.meshNodes??[],components:this.normalizedInput.components}),e=this.getStageOutput(\"componentTopologyBatchSolver\")?.componentMeshNodes??[],n=this.getComponentNoConnectionSrjs();return{globalNoConnectionSrj:this.normalizedInput.globalNoConnectionSrj,componentNoConnectionSrjs:n,globalMeshNodes:t,componentMeshNodes:e}}finalVisualize(){const t=this.getOutput();return{title:\"Topology Planning: generated topology groups\",rects:[...t.componentNoConnectionSrjs.flatMap((t,e)=\u003e{const n=this.normalizedInput.components[e]??null;return t.obstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(120, 120, 120, 0.06)\",stroke:\"rgba(120, 120, 120, 0.35)\",label:t.obstacleId??n?.componentId??\"component-pad\",layer:t.layers.join(\",\")}))}),...[...t.globalMeshNodes,...t.componentMeshNodes.flat()].map(t=\u003e{const e=this.normalizedInput.components.find(e=\u003et.capacityMeshNodeId.includes(e.componentId));return{...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?To(\"red\",.82):\"rgba(0, 120, 255, 0.12)\",stroke:t._containsObstacle?To(\"red\",.3):\"rgba(0, 120, 255, 0.55)\",label:e?`${e.componentKind.toUpperCase()} ${t.capacityMeshNodeId}`:t.capacityMeshNodeId}})],lines:[],points:[],circles:[],texts:[]}}visualize(){return this.filterGlobalRectDiffNodesFromVisualization({visualization:super.visualize()})}preview(){return this.filterGlobalRectDiffNodesFromVisualization({visualization:super.preview()})}getComponentNoConnectionSrjs(){return this.normalizedInput.components.map(t=\u003efunction({inputSrj:t,component:e}){const n=CZ(e.memberObstacles),o=Math.max(t.minViaPadDiameter??t.min_via_pad_diameter??t.minViaDiameter??.3,t.defaultObstacleMargin??.15,2*t.minTraceWidth),i=new Set(e.memberObstacles.flatMap(t=\u003et.connectedTo)),r=t.connections.flatMap(t=\u003et.pointsToConnect.filter(t=\u003e{const e=[t.pointId,t.pcb_port_id].filter(t=\u003e\"string\"==typeof t).some(t=\u003ei.has(t)),r=t.x\u003e=n.minX-o\u0026\u0026t.x\u003c=n.maxX+o\u0026\u0026t.y\u003e=n.minY-o\u0026\u0026t.y\u003c=n.maxY+o;return e\u0026\u0026r})).reduce((t,e)=\u003e({minX:Math.min(t.minX,e.x),maxX:Math.max(t.maxX,e.x),minY:Math.min(t.minY,e.y),maxY:Math.max(t.maxY,e.y)}),n),s=t.obstacles.filter(t=\u003eXe(Ee(t),r)).map(t=\u003e({...t}));return{...structuredClone(t),bounds:r,obstacles:s}}({inputSrj:this.inputProblem.inputSrj,component:t}))}getGlobalTopologySolverInput(){return{simpleRouteJson:this.normalizedInput.globalNoConnectionSrj,maxGapFillPasses:4}}filterGlobalRectDiffNodesFromVisualization({visualization:t}){return{...t,rects:MZ({rects:t.rects,components:this.normalizedInput.components})}}},bq=(t,e)=\u003e{if(t)return Object.entries(e).sort(([t],[e])=\u003ee.length-t.length).find(([e])=\u003et.includes(e))?.[1]},xq=(t,e)=\u003e({...t,points:t.points?.map(t=\u003e({...t,color:bq(t.label,e)??t.color})),lines:t.lines?.map(t=\u003e({...t,strokeColor:bq(t.label,e)??t.strokeColor})),circles:t.circles?.map(t=\u003e{const n=bq(t.label,e);return n?{...t,fill:n,stroke:n}:t})}),vq=class extends si{constructor(t){super(),this.topologyPlanningSolver=t,this.solved=t.solved,this.failed=t.failed,this.error=t.error,this.stats=t.stats}topologyPlanningSolver;getOutput(){return this.topologyPlanningSolver.getOutput().componentMeshNodes.flat()}visualize(){return this.topologyPlanningSolver.finalVisualize()??this.topologyPlanningSolver.visualize()}preview(){return this.visualize()}},Sq=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\u0026\u0026!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026this.tryFinalAcceptance(),!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),\"computeProgress\"in this\u0026\u0026(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error(\"getConstructorParams not implemented\")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved\u0026\u0026!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:[]}}},Iq=t=\u003et.filter(t=\u003eBoolean(t)),Cq=(t,e,n)=\u003e{const o=`${Math.round(100*t.x)},${Math.round(100*t.y)}`,i=e.map(t=\u003e((t,e)=\u003e\"top\"===t?0:\"bottom\"===t?e-1:Number.parseInt(t.slice(5),10))(t,n)).sort().join(\"-\");return`${o}:${i}`},Pq=class{parent=new Map;constructor(t,e=t.traces??[],n={}){for(const e of t.connections)this.unionAll(Iq([e.name,e.source_trace_id,e.rootConnectionName,e.netConnectionName,...e.mergedConnectionNames??[],...e.pointsToConnect.flatMap(e=\u003e[e.pointId,e.pcb_port_id,...n.includePhysicalPositionAliases?[Cq(e,e.layers??[e.layer],t.layerCount)]:[]])]));for(const n of[...e,...t.fixedTraces??[]])this.unionAll(Iq([n.pcb_trace_id,n.connection_name,n.source_trace_id,n.rootConnectionName,...n.mergedConnectionNames??[],...n.connectsTo??[]]));for(const e of t.obstacles)this.unionAll(n.includePhysicalPositionAliases?Iq([e.obstacleId,...e.connectedTo,...e.offBoardConnectsTo??[],Cq(e.center,e.layers,t.layerCount)]):e.connectedTo)}canonicalize(t){return[...new Set(t.map(t=\u003ethis.find(t)))]}unionAll(t){const e=t[0];if(e){this.add(e);for(let n=1;n\u003ct.length;n++)this.union(e,t[n])}}add(t){this.parent.has(t)||this.parent.set(t,t)}find(t){this.add(t);const e=this.parent.get(t);if(e===t)return t;const n=this.find(e);return this.parent.set(t,n),n}union(t,e){const n=this.find(t),o=this.find(e);n!==o\u0026\u0026this.parent.set(o,n)}},Mq=1e-6,Nq=(t,e)=\u003eMath.hypot(e.x-t.x,e.y-t.y),wq=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c=1e-12)return Nq(t,e);const s=Rq(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return Math.hypot(t.x-(e.x+o*s),t.y-(e.y+i*s))},Tq=(t,e,n=1e-6)=\u003eMath.abs(t.x-e.x)\u003c=n\u0026\u0026Math.abs(t.y-e.y)\u003c=n,Rq=(t,e,n)=\u003eMath.max(e,Math.min(n,t)),Eq=(t,e,n)=\u003e(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),Aq=(t,e,n)=\u003eMath.abs(Eq(e,n,t))\u003c=1e-9\u0026\u0026t.x\u003e=Math.min(e.x,n.x)-1e-9\u0026\u0026t.x\u003c=Math.max(e.x,n.x)+1e-9\u0026\u0026t.y\u003e=Math.min(e.y,n.y)-1e-9\u0026\u0026t.y\u003c=Math.max(e.y,n.y)+1e-9,Oq=(t,e,n,o)=\u003e((t,e,n,o)=\u003e{const i=Eq(t,e,n),r=Eq(t,e,o),s=Eq(n,o,t),a=Eq(n,o,e);return i*r\u003c0\u0026\u0026s*a\u003c0||Math.abs(i)\u003c=1e-9\u0026\u0026Aq(n,t,e)||Math.abs(r)\u003c=1e-9\u0026\u0026Aq(o,t,e)||Math.abs(s)\u003c=1e-9\u0026\u0026Aq(t,n,o)||Math.abs(a)\u003c=1e-9\u0026\u0026Aq(e,n,o)})(t,e,n,o)?0:Math.min(wq(t,n,o),wq(e,n,o),wq(n,t,e),wq(o,t,e)),kq=(t,e)=\u003e{let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];if(Aq(t,s,r))return!0;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n},Lq=(t,e,n)=\u003e{if(kq(t,n)||kq(e,n))return 0;let o=Number.POSITIVE_INFINITY;for(let i=0;i\u003cn.length;i++){const r=n[i],s=n[(i+1)%n.length];o=Math.min(o,Oq(t,e,r,s))}return o};function Dq(t,e,n){let o=0,i=1;const r=e.x-t.x,s=e.y-t.y,a=[[-r,t.x-n.minX],[r,n.maxX-t.x],[-s,t.y-n.minY],[s,n.maxY-t.y]];for(const[t,e]of a){if(Math.abs(t)\u003c1e-12){if(e\u003c0)return!1;continue}const n=e/t;if(t\u003c0?o=Math.max(o,n):i=Math.min(i,n),o\u003ei)return!1}return!0}function zq({start:t,end:e,width:n,base:o}){const i=Nq(t,e),r=(t=\u003eRq(1.25*t,.25,.75))(n),s=Math.max(1,Math.ceil(i/r)),a=n/2,c=[];for(let i=0;i\u003cs;i++){const r=i/s,l=(i+1)/s,d=t.x+(e.x-t.x)*r,h=t.y+(e.y-t.y)*r,u=t.x+(e.x-t.x)*l,p=t.y+(e.y-t.y)*l;c.push({...o,minX:Math.min(d,u)-a,minY:Math.min(h,p)-a,maxX:Math.max(d,u)+a,maxY:Math.max(h,p)+a,exactShape:{type:\"segment\",start:{x:d,y:h},end:{x:u,y:p},width:n}})}return c}var Fq=(t,e,n)=\u003e{const o=Math.cos(n),i=Math.sin(n),r=t.x-e.x,s=t.y-e.y;return{x:e.x+r*o-s*i,y:e.y+r*i+s*o}};var Bq=class{nodeIndices=[];priorities=[];get size(){return this.nodeIndices.length}push(t,e){let n=this.nodeIndices.length;for(this.nodeIndices.push(t),this.priorities.push(e);n\u003e0;){const t=n-1\u003e\u003e1;if(this.priorities[t]\u003c=e)break;this.swap(n,t),n=t}}pop(){const t=this.nodeIndices[0],e=this.nodeIndices.pop(),n=this.priorities.pop();if(0===this.nodeIndices.length)return t;this.nodeIndices[0]=e,this.priorities[0]=n;let o=0;for(;;){const t=2*o+1,e=t+1;if(t\u003e=this.nodeIndices.length)break;let n=t;if(e\u003cthis.nodeIndices.length\u0026\u0026this.priorities[e]\u003cthis.priorities[t]\u0026\u0026(n=e),this.priorities[o]\u003c=this.priorities[n])break;this.swap(o,n),o=n}return t}swap(t,e){[this.nodeIndices[t],this.nodeIndices[e]]=[this.nodeIndices[e],this.nodeIndices[t]],[this.priorities[t],this.priorities[e]]=[this.priorities[e],this.priorities[t]]}},jq=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]],$q=[\"#d53535\",\"#3478c8\",\"#8e44ad\",\"#15956f\"],Yq=class extends Sq{problem;searchBounds;rows;columns;origin;nodes=[];open=new Bq;bestCost=new Map;closed=new Set;baseStateCount;stateSpaceUpperBound;endLayerIndices;targetCell;segmentWidthCache=new Map;closedStateCount=0;output=null;constructor(t){super(),this.problem=t;const e=Math.max(t.traceWidth,t.viaDiameter)/2+t.obstacleIndex.clearance,n=Rq(Math.min(t.start.x,t.end.x)-t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),o=Rq(Math.max(t.start.x,t.end.x)+t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),i=Rq(Math.min(t.start.y,t.end.y)-t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),r=Rq(Math.max(t.start.y,t.end.y)+t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),s=Math.floor((n-t.gridOffset.x)/t.gridSize)*t.gridSize+t.gridOffset.x,a=Math.floor((i-t.gridOffset.y)/t.gridSize)*t.gridSize+t.gridOffset.y;this.origin={x:s,y:a},this.columns=Math.max(2,Math.floor((o-s)/t.gridSize)+1),this.rows=Math.max(2,Math.floor((r-a)/t.gridSize)+1),this.searchBounds={minX:s,minY:a,maxX:s+(this.columns-1)*t.gridSize,maxY:a+(this.rows-1)*t.gridSize};const c=this.rows*this.columns*t.layers.length*(t.maxViaCount+1);this.baseStateCount=c,this.stateSpaceUpperBound=c*(this.rows*this.columns+1),this.targetCell=this.pointToCell(t.end),this.endLayerIndices=new Set(t.endLayers.map(e=\u003et.layers.indexOf(e)).filter(t=\u003et\u003e=0));const l=this.pointToCell(t.start);for(const e of t.startLayers){const n=t.layers.indexOf(e);if(n\u003c0||this.endpointCollides(t.start,n))continue;const o={...l,...t.start,layerIndex:n,viaCount:0,viaPoints:[],g:0,f:this.heuristic(t.start),parentIndex:-1},i=this.nodes.length;this.nodes.push(o),this.open.push(i,o.f),this.bestCost.set(this.toStateIndex(o),0)}0!==this.open.size\u0026\u00260!==this.endLayerIndices.size||(this.failed=!0,this.error=\"No collision-free multilayer route endpoint\"),this.MAX_ITERATIONS=Math.min(15e3,Math.max(2e3,2*c)),this.stats=this.createStats()}getSolverName(){return`LayerAwareGridRouteSolver(${this.problem.gridSize.toFixed(3)}mm)`}_step(){if(0===this.open.size)return this.failed=!0,void(this.error=\"No collision-free multilayer grid route found\");const t=this.open.pop(),e=this.nodes[t],n=this.toStateIndex(e);if(!this.closed.has(n)){if(this.closed.add(n),this.closedStateCount++,e.row===this.targetCell.row\u0026\u0026e.column===this.targetCell.column\u0026\u0026this.endLayerIndices.has(e.layerIndex)\u0026\u0026e.viaCount\u003e=this.problem.minViaCount\u0026\u0026!this.segmentCollides(e,this.problem.end))return this.output=this.reconstructRoute(t),this.solved=!0,void(this.stats=this.createStats());this.expandPlanarMoves(t,e),this.expandViaMoves(t,e),this.stats=this.createStats()}}expandPlanarMoves(t,e){for(const[n,o]of jq){const i=e.row+n,r=e.column+o;if(i\u003c0||i\u003e=this.rows||r\u003c0||r\u003e=this.columns)continue;const s=this.cellToPoint(i,r),a=this.getSafeSegmentWidth(e,s);if(a\u003c=0)continue;const c=this.problem.gridSize*(0!==n\u0026\u00260!==o?Math.SQRT2:1)*Math.max(1,(this.problem.traceWidth/a)**this.problem.neckPenaltyExponent);this.enqueueNode({row:i,column:r,...s,layerIndex:e.layerIndex,viaCount:e.viaCount,viaPoints:e.viaPoints,g:e.g+c,parentIndex:t})}}expandViaMoves(t,e){if(e.viaCount\u003e=this.problem.maxViaCount)return;const n=.5*this.problem.gridSize;if(Nq(e,this.problem.start)\u003cn-1e-9||Nq(e,this.problem.end)\u003cn-1e-9)return;const o=e.parentIndex\u003e=0?this.nodes[e.parentIndex]:void 0;if(!o||o.layerIndex===e.layerIndex||!Tq(o,e))for(let n=0;n\u003cthis.problem.layers.length;n++)n!==e.layerIndex\u0026\u0026(this.problem.obstacleIndex.collidesVia({point:e,layers:this.problem.layers,padDiameter:this.problem.viaDiameter,holeDiameter:this.problem.viaHoleDiameter,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreTraceIndices:this.problem.softTraceIndices,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance,blockSameNetObstacles:!0,sameNetObstacleClearance:0,otherNewViaPoints:e.viaPoints,fixedVias:this.problem.fixedVias})||this.enqueueNode({row:e.row,column:e.column,x:e.x,y:e.y,layerIndex:n,viaCount:e.viaCount+1,viaPoints:[...e.viaPoints,{x:e.x,y:e.y}],g:e.g+this.problem.viaCost,parentIndex:t}))}enqueueNode(t){const e=this.toStateIndex(t);if(this.closed.has(e)||t.g\u003e=(this.bestCost.get(e)??Number.POSITIVE_INFINITY))return;this.bestCost.set(e,t.g);const n=t.g+this.heuristic(t),o=this.nodes.length;this.nodes.push({...t,f:n}),this.open.push(o,n)}endpointCollides(t,e){return this.getSafeSegmentWidth({...t,layerIndex:e,viaCount:0},t)\u003c=0}segmentCollides(t,e){return this.getSafeSegmentWidth(t,e)\u003c=0}getSafeSegmentWidth(t,e){const n=this.problem.layers[t.layerIndex],o=1===this.problem.startLayers.length\u0026\u00260===t.viaCount\u0026\u0026n===this.problem.originalStartLayer\u0026\u0026Nq(this.problem.start,t)\u003c=this.problem.maxStartNeckLength+1e-9\u0026\u0026Nq(this.problem.start,e)\u003c=this.problem.maxStartNeckLength+1e-9,i=1===this.problem.endLayers.length\u0026\u0026n===this.problem.originalEndLayer\u0026\u0026Nq(this.problem.end,t)\u003c=this.problem.maxEndNeckLength+1e-9\u0026\u0026Nq(this.problem.end,e)\u003c=this.problem.maxEndNeckLength+1e-9,r=Math.max(o?this.problem.startNeckWidth:0,i?this.problem.endNeckWidth:0),s=[t.x,t.y,e.x,e.y,t.layerIndex,t.viaCount,r].join(\":\"),a=this.segmentWidthCache.get(s);if(void 0!==a)return a;const c=o=\u003e!this.problem.obstacleIndex.collides({start:t,end:e,layer:n,width:o,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreTraceIndices:this.problem.softTraceIndices,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance});let l=0;if(o||i){const t=.025;let e=Math.ceil((r-1e-9)/t),n=Math.floor((this.problem.traceWidth+1e-9)/t);for(;e\u003c=n;){const o=Math.floor((e+n)/2),i=Number((o*t).toFixed(6));c(i)?(l=i,e=o+1):n=o-1}l\u003cr-1e-9\u0026\u0026c(r)\u0026\u0026(l=r)}else l=c(this.problem.traceWidth)?this.problem.traceWidth:0;return this.segmentWidthCache.set(s,l),l}reconstructRoute(t){const e=[];let n=t;for(;n\u003e=0;){const t=this.nodes[n];e.push(t),n=t.parentIndex}e.reverse();const o=e[e.length-1];Tq(o,this.problem.end)||e.push({...o,...this.problem.end,row:this.targetCell.row,column:this.targetCell.column,parentIndex:-1});const i=[];let r=[e[0]];for(let t=1;t\u003ce.length;t++){const n=e[t-1],o=e[t];o.layerIndex!==n.layerIndex?(i.push(r),r=[o]):r.push(o)}i.push(r);const s=[];for(let t=0;t\u003ci.length;t++){const e=this.simplifySection(i[t]),n=e.slice(0,-1).map((t,n)=\u003ethis.getSafeSegmentWidth(t,e[n+1])),o=e.map((t,o)=\u003e({route_type:\"wire\",x:t.x,y:t.y,layer:this.problem.layers[t.layerIndex],width:0===n.length?Math.min(this.problem.startNeckWidth,this.problem.endNeckWidth):0===o?n[0]:o===e.length-1?n[n.length-1]:Math.min(n[o-1],n[o])}));s.push(...o);const r=i[t+1];if(r){const t=this.problem.layers[e.at(-1).layerIndex],n=this.problem.layers[r[0].layerIndex],o=e.at(-1);s.push({route_type:\"via\",x:o.x,y:o.y,from_layer:t,to_layer:n,via_diameter:this.problem.viaDiameter,via_hole_diameter:this.problem.viaHoleDiameter})}}return{route:s,traceWidth:this.problem.traceWidth,startNeckWidth:this.problem.startNeckWidth,endNeckWidth:this.problem.endNeckWidth,gridSize:this.problem.gridSize,gridOffset:this.problem.gridOffset,viaCount:i.length-1}}simplifySection(t){return t.length\u003c=2?t:this.problem.neckPenaltyExponent\u003e1?this.simplifyStrictSection(t):this.simplifyWidthPreservingSection(t)}simplifyStrictSection(t){const e=t.slice(0,-1).map((e,n)=\u003ethis.getSafeSegmentWidth(e,t[n+1])),n=[0];for(let o=0;o\u003ce.length;o++)n.push(n[o]+this.getWidthPenalizedCost(t[o],t[o+1],e[o]));const o=[t[0]];let i=0;for(;i\u003ct.length-1;){let r=t.length-1;for(;r\u003ei+1\u0026\u0026!this.shortcutPreservesRouteQuality(t,e,n,i,r);)r--;o.push(t[r]),i=r}return this.removeRedundantCollinearPoints(o)}shortcutPreservesRouteQuality(t,e,n,o,i){const r=this.getSafeSegmentWidth(t[o],t[i]);if(r\u003c=0)return!1;let s=Number.POSITIVE_INFINITY;for(let t=o;t\u003ci;t++)s=Math.min(s,e[t]);const a=n[i]-n[o];return r\u003e=s-1e-9\u0026\u0026this.getWidthPenalizedCost(t[o],t[i],r)\u003c=a+1e-9}getWidthPenalizedCost(t,e,n){return Nq(t,e)*Math.max(1,(this.problem.traceWidth/n)**this.problem.neckPenaltyExponent)}simplifyWidthPreservingSection(t){const e=t.slice(0,-1).map((e,n)=\u003ethis.getSafeSegmentWidth(e,t[n+1])),n=[0];for(let o=0;o\u003ce.length;o++)n.push(n[o]+Nq(t[o],t[o+1])*Math.max(1,(this.problem.traceWidth/e[o])**this.problem.neckPenaltyExponent));const o=new Float64Array(t.length).fill(Number.POSITIVE_INFINITY),i=new Float64Array(t.length).fill(Number.POSITIVE_INFINITY),r=new Int32Array(t.length).fill(-1);o[0]=0,i[0]=0;for(let s=1;s\u003ct.length;s++){let a=Number.POSITIVE_INFINITY;for(let c=s-1;c\u003e=0;c--){if(a=Math.min(a,e[c]),!Number.isFinite(o[c]))continue;const l=this.getSafeSegmentWidth(t[c],t[s]);if(l\u003ca-1e-9)continue;const d=Nq(t[c],t[s]);if(d*Math.max(1,(this.problem.traceWidth/l)**this.problem.neckPenaltyExponent)\u003en[s]-n[c]+1e-9)continue;const h=o[c]+d*Math.max(0,this.problem.traceWidth-l),u=i[c]+d;(h\u003co[s]-1e-9||Math.abs(h-o[s])\u003c=1e-9\u0026\u0026u\u003ci[s]-1e-9)\u0026\u0026(o[s]=h,i[s]=u,r[s]=c)}}const s=[];let a=t.length-1;for(;a\u003e=0\u0026\u0026(s.push(t[a]),0!==a);)if(a=r[a],a\u003c0)return t;return s.reverse(),this.removeRedundantCollinearPoints(s)}removeRedundantCollinearPoints(t){return t.filter((t,e,n)=\u003e{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x),s=Math.abs(this.getSafeSegmentWidth(o,t)-this.getSafeSegmentWidth(t,i))\u003c1e-9;return Math.abs(r)\u003e1e-8||!s})}pointToCell(t){return{column:Rq(Math.round((t.x-this.origin.x)/this.problem.gridSize),0,this.columns-1),row:Rq(Math.round((t.y-this.origin.y)/this.problem.gridSize),0,this.rows-1)}}cellToPoint(t,e){return{x:this.origin.x+e*this.problem.gridSize,y:this.origin.y+t*this.problem.gridSize}}toStateIndex(t){const e=((t.viaCount*this.problem.layers.length+t.layerIndex)*this.rows+t.row)*this.columns+t.column;if(1!==t.viaCount||0===t.viaPoints.length||Nq(t,t.viaPoints[0])\u003e=this.problem.viaHoleDiameter+this.problem.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance-1e-9)return e;const n=this.pointToCell(t.viaPoints[0]);return e+(1+n.row*this.columns+n.column)*this.baseStateCount}heuristic(t){return Nq(t,this.problem.end)}createStats(){return{phase:\"layer-aware-grid-search\",gridSize:this.problem.gridSize,traceWidth:this.problem.traceWidth,startNeckWidth:this.problem.startNeckWidth,endNeckWidth:this.problem.endNeckWidth,maxViaCount:this.problem.maxViaCount,minViaCount:this.problem.minViaCount,openStates:this.open.size,closedStates:this.closedStateCount,trackedStates:this.bestCost.size,stateSpaceUpperBound:this.stateSpaceUpperBound}}computeProgress(){return Math.min(.99,this.iterations/this.MAX_ITERATIONS)}getOutput(){return this.output}getConstructorParams(){const{obstacleIndex:t,...e}=this.problem;return[e]}visualize(){const t=this.nodes.filter(t=\u003ethis.closed.has(this.toStateIndex(t))).slice(-2e3).map(t=\u003e({x:t.x,y:t.y,color:`${$q[t.layerIndex%$q.length]}55`})),e=[],n=[],o=this.output?.route??[];for(let t=0;t\u003co.length-1;t++){const i=o[t],r=o[t+1];if(\"wire\"===i?.route_type\u0026\u0026\"wire\"===r?.route_type\u0026\u0026i.layer===r.layer){const t=this.problem.layers.indexOf(i.layer);e.push({points:[i,r],strokeColor:$q[t%$q.length]??\"#333\",strokeWidth:i.width})}\"via\"===i?.route_type\u0026\u0026n.push({center:i,radius:(i.via_diameter??this.problem.viaDiameter)/2,fill:\"#d4a017\"})}return{coordinateSystem:\"cartesian\",title:this.getSolverName(),rects:[{center:{x:(this.searchBounds.minX+this.searchBounds.maxX)/2,y:(this.searchBounds.minY+this.searchBounds.maxY)/2},width:this.searchBounds.maxX-this.searchBounds.minX,height:this.searchBounds.maxY-this.searchBounds.minY,stroke:\"#777\"}],points:[...t,{...this.problem.start,color:\"green\",label:\"reroute start\"},{...this.problem.end,color:\"purple\",label:\"reroute target\"}],lines:e,circles:n,texts:[]}}},Xq=[{direction:1,strength:.7},{direction:-1,strength:.7},{direction:1,strength:1},{direction:-1,strength:1}],Vq=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c=1e-12)return{...e};const s=Rq(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return{x:e.x+o*s,y:e.y+i*s}},Wq=class extends Sq{problem;phase=\"prepare-candidate\";variantCursor=0;relaxationIteration=0;candidatePoints=[];sampledPoints;output=null;constructor(t){super(),this.problem=t,this.sampledPoints=this.sampleRoute(),this.MAX_ITERATIONS=100,this.stats=this.createStats()}getSolverName(){return\"ElasticTracePushSolver\"}_step(){switch(this.phase){case\"prepare-candidate\":if(this.variantCursor\u003e=Xq.length)return this.failed=!0,void(this.error=\"No collision-free elastic displacement found\");this.candidatePoints=this.sampledPoints.map(t=\u003e({...t})),this.relaxationIteration=0,this.phase=\"relax-candidate\";break;case\"relax-candidate\":this.relaxCandidate(),this.relaxationIteration++,this.relaxationIteration\u003e=10\u0026\u0026(this.phase=\"validate-candidate\");break;case\"validate-candidate\":{const t=this.simplifyCandidate(this.candidatePoints);this.pathCollides(t)?(this.variantCursor++,this.phase=\"prepare-candidate\"):(this.output={points:t,traceWidth:this.problem.traceWidth},this.phase=\"complete\");break}case\"complete\":this.solved=!0}this.stats=this.createStats()}sampleRoute(){const t=[],e=Rq(2*this.problem.traceWidth,.2,.45),n=this.problem.trace.route;for(let o=this.problem.range.startIndex;o\u003cthis.problem.range.endIndex;o++){const i=n[o],r=n[o+1];if(\"wire\"!==i?.route_type||\"wire\"!==r?.route_type||i.layer!==r.layer)continue;0===t.length\u0026\u0026t.push({x:i.x,y:i.y});const s=Nq(i,r),a=Math.max(1,Math.ceil(s/e));for(let e=1;e\u003c=a;e++){const n=e/a;t.push({x:i.x+(r.x-i.x)*n,y:i.y+(r.y-i.y)*n})}}return t}relaxCandidate(){const t=Xq[this.variantCursor],e=this.candidatePoints.map(t=\u003e({...t})),n=new Uint8Array(this.candidatePoints.length);for(let o=1;o\u003cthis.candidatePoints.length-1;o++){const i=this.candidatePoints[o],r=this.findNearestCorridorSegment(i);if(!r)continue;const s=Nq(r.segment.start,r.segment.end);if(s\u003c=1e-9)continue;const a=r.segment.width/2+this.problem.traceWidth/2+this.problem.obstacleIndex.clearance+.025;if(r.distance\u003ea+.35)continue;const c={x:(r.segment.start.y-r.segment.end.y)/s*t.direction,y:(r.segment.end.x-r.segment.start.x)/s*t.direction},l=a-((i.x-r.closest.x)*c.x+(i.y-r.closest.y)*c.y);if(l\u003c=0)continue;const d=Math.min(.35,l*t.strength);e[o]={x:i.x+c.x*d,y:i.y+c.y*d},n[o]=1}for(let t=1;t\u003ce.length-1;t++){if(!n[t])continue;const o=e[t-1],i=e[t],r=e[t+1];e[t]={x:.85*i.x+(o.x+r.x)/2*.15,y:.85*i.y+(o.y+r.y)/2*.15}}this.candidatePoints=e}findNearestCorridorSegment(t){let e;for(const n of this.problem.corridor){if(n.layer!==this.problem.layer)continue;const o=Vq(t,n.start,n.end),i=Nq(t,o);(!e||i\u003ce.distance)\u0026\u0026(e={segment:n,closest:o,distance:i})}return e}simplifyCandidate(t){if(t.length\u003c=2)return t;const e=[t[0]];let n=0;for(;n\u003ct.length-1;){let o=t.length-1;for(;o\u003en+1\u0026\u0026this.segmentCollides(t[n],t[o]);)o--;e.push(t[o]),n=o}return e.filter((t,e,n)=\u003e0===e||!Tq(t,n[e-1]))}pathCollides(t){if(t.length\u003c2)return!0;for(let e=0;e\u003ct.length-1;e++)if(this.segmentCollides(t[e],t[e+1]))return!0;return!1}segmentCollides(t,e){return this.problem.obstacleIndex.collides({start:t,end:e,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:-1})}createStats(){const t=Xq[this.variantCursor];return{phase:this.phase,direction:t?.direction,strength:t?.strength,variantCursor:this.variantCursor,relaxationIteration:this.relaxationIteration,sampledPointCount:this.sampledPoints.length}}computeProgress(){return Math.min(.99,(this.variantCursor+this.relaxationIteration/12)/Xq.length)}getOutput(){return this.output}getConstructorParams(){return[this.problem]}visualize(){return{coordinateSystem:\"cartesian\",title:`Elastic trace push: ${this.phase}`,lines:[...this.problem.corridor.map(t=\u003e({points:[t.start,t.end],strokeColor:\"rgba(255, 128, 0, 0.6)\",strokeWidth:t.width})),...this.candidatePoints.length\u003e1?[{points:this.candidatePoints,strokeColor:\"#1769d2\",strokeWidth:this.problem.traceWidth}]:[]],points:[],rects:[],circles:[],texts:[]}}},Hq=(t,e)=\u003e{const n=Math.abs(e.x-t.x),o=Math.abs(e.y-t.y);return n\u003c=Mq||o\u003c=Mq||Math.abs(n-o)\u003c=Mq},Gq=t=\u003e{let e=0;for(let n=0;n\u003ct.length-1;n++)Hq(t[n],t[n+1])||e++;return e},Uq=t=\u003e{let e=0;for(let n=0;n\u003ct.length-1;n++)e+=Nq(t[n],t[n+1]);return e},Zq=t=\u003et.filter((e,n)=\u003e0===n||!Tq(e,t[n-1])),qq=(t,e)=\u003e{const n=e.x-t.x,o=e.y-t.y,i=Math.abs(n),r=Math.abs(o),s=Math.sign(n),a=Math.sign(o),c=[];Hq(t,e)\u0026\u0026c.push([t,e]),c.push([t,{x:e.x,y:t.y},e],[t,{x:t.x,y:e.y},e]),i\u003e=r?c.push([t,{x:e.x-s*r,y:t.y},e],[t,{x:t.x+s*r,y:e.y},e]):c.push([t,{x:t.x,y:e.y-a*i},e],[t,{x:e.x,y:t.y+a*i},e]);const l=new Map;for(const t of c){const e=Zq(t);if(e.length\u003c2||e.some((t,n)=\u003en\u003ce.length-1\u0026\u0026!Hq(t,e[n+1])))continue;const n=e.map(t=\u003e`${t.x.toFixed(6)},${t.y.toFixed(6)}`).join(\";\");l.set(n,e)}return[...l.values()].sort((t,e)=\u003eUq(t)-Uq(e)||t.length-e.length)},Jq=class{nodeIndices=[];priorities=[];get size(){return this.nodeIndices.length}push(t,e){let n=this.nodeIndices.length;for(this.nodeIndices.push(t),this.priorities.push(e);n\u003e0;){const t=n-1\u003e\u003e1;if(this.priorities[t]\u003c=e)break;this.swap(n,t),n=t}}pop(){const t=this.nodeIndices[0],e=this.nodeIndices.pop(),n=this.priorities.pop();if(0===this.nodeIndices.length)return t;this.nodeIndices[0]=e,this.priorities[0]=n;let o=0;for(;;){const t=2*o+1,e=t+1;if(t\u003e=this.nodeIndices.length)break;let n=t;if(e\u003cthis.nodeIndices.length\u0026\u0026this.priorities[e]\u003cthis.priorities[t]\u0026\u0026(n=e),this.priorities[o]\u003c=this.priorities[n])break;this.swap(o,n),o=n}return t}swap(t,e){[this.nodeIndices[t],this.nodeIndices[e]]=[this.nodeIndices[e],this.nodeIndices[t]],[this.priorities[t],this.priorities[e]]=[this.priorities[e],this.priorities[t]]}},Kq=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]],Qq=class extends Sq{problem;searchBounds;rows;columns;origin;nodes=[];open=new Jq;bestCost;closed;closedCellCount=0;targetCell;output=null;constructor(t){super(),this.problem=t;const e=t.traceWidth/2+t.obstacleIndex.clearance,n=Rq(Math.min(t.start.x,t.end.x)-t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),o=Rq(Math.max(t.start.x,t.end.x)+t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),i=Rq(Math.min(t.start.y,t.end.y)-t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),r=Rq(Math.max(t.start.y,t.end.y)+t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),s=Math.floor((n-t.gridOffset.x)/t.gridSize)*t.gridSize+t.gridOffset.x,a=Math.floor((i-t.gridOffset.y)/t.gridSize)*t.gridSize+t.gridOffset.y;if(this.origin={x:s,y:a},this.columns=Math.max(2,Math.floor((o-s)/t.gridSize)+1),this.rows=Math.max(2,Math.floor((r-a)/t.gridSize)+1),this.searchBounds={minX:s,minY:a,maxX:s+(this.columns-1)*t.gridSize,maxY:a+(this.rows-1)*t.gridSize},this.bestCost=new Float64Array(this.rows*this.columns).fill(Number.POSITIVE_INFINITY),this.closed=new Uint8Array(this.rows*this.columns),this.endpointCollides(t.start)||this.endpointCollides(t.end))return this.failed=!0,this.error=\"Grid-route endpoint violates obstacle clearance\",this.targetCell={row:0,column:0},this.MAX_ITERATIONS=1,void(this.stats=this.createStats());const c=this.pointToCell(t.start);this.targetCell=this.pointToCell(t.end);const l={...c,x:t.start.x,y:t.start.y,g:0,f:this.heuristic(t.start),parentIndex:-1};this.nodes.push(l),this.open.push(0,l.f),this.bestCost[this.toFlatIndex(c.row,c.column)]=0,this.MAX_ITERATIONS=Math.min(5e3,Math.max(1e3,this.rows*this.columns*2)),this.stats=this.createStats()}endpointCollides(t){return this.problem.obstacleIndex.collides({start:t,end:t,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance})}getSolverName(){return`ObstacleAwareGridRouteSolver(${this.problem.gridSize.toFixed(3)}mm)`}_step(){if(0===this.open.size)return this.failed=!0,void(this.error=\"No collision-free grid route found\");const t=this.open.pop(),e=this.nodes[t],n=this.toFlatIndex(e.row,e.column);if(!this.closed[n]){if(this.closed[n]=1,this.closedCellCount++,e.row===this.targetCell.row\u0026\u0026e.column===this.targetCell.column\u0026\u0026null!==this.getAllowedConnector(e,this.problem.end))return this.output={points:this.reconstructPath(t),traceWidth:this.problem.traceWidth,gridSize:this.problem.gridSize,gridOffset:this.problem.gridOffset},this.solved=!0,void(this.stats=this.createStats());for(const[n,o]of Kq){const i=e.row+n,r=e.column+o;if(i\u003c0||i\u003e=this.rows||r\u003c0||r\u003e=this.columns)continue;const s=this.toFlatIndex(i,r);if(this.closed[s])continue;const a=this.cellToPoint(i,r),c=this.getAllowedConnector(e,a);if(null===c)continue;const l=-1===e.parentIndex\u0026\u0026this.problem.requireOctilinear?Uq(c):this.problem.gridSize*(0!==n\u0026\u00260!==o?Math.SQRT2:1),d=e.g+l;if(d\u003e=this.bestCost[s])continue;this.bestCost[s]=d;const h=d+this.heuristic(a),u=this.nodes.length;this.nodes.push({row:i,column:r,...a,g:d,f:h,parentIndex:t}),this.open.push(u,h)}this.stats=this.createStats()}}segmentCollides(t,e){return this.problem.obstacleIndex.collides({start:t,end:e,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance})}getAllowedConnector(t,e){return this.problem.requireOctilinear\u0026\u0026(\"parentIndex\"in t\u0026\u0026-1===t.parentIndex||Tq(e,this.problem.end))?qq(t,e).find(t=\u003et.slice(0,-1).every((e,n)=\u003e!this.segmentCollides(e,t[n+1])))??null:this.segmentCollides(t,e)?null:[t,e]}pointToCell(t){return{column:Rq(Math.round((t.x-this.origin.x)/this.problem.gridSize),0,this.columns-1),row:Rq(Math.round((t.y-this.origin.y)/this.problem.gridSize),0,this.rows-1)}}cellToPoint(t,e){return{x:this.origin.x+e*this.problem.gridSize,y:this.origin.y+t*this.problem.gridSize}}toFlatIndex(t,e){return t*this.columns+e}heuristic(t){return Math.hypot(this.problem.end.x-t.x,this.problem.end.y-t.y)}reconstructPath(t){const e=[];let n=t;for(;n\u003e=0;){const t=this.nodes[n];e.push({x:t.x,y:t.y}),n=t.parentIndex}if(e.reverse(),Tq(e[0],this.problem.start)||e.unshift({...this.problem.start}),Tq(e[e.length-1],this.problem.end)||e.push({...this.problem.end}),this.problem.requireOctilinear){const t=[e[0]];for(let n=0;n\u003ce.length-1;n++){const o=e[n],i=e[n+1],r=0===n||n===e.length-2?this.getAllowedConnector(0===n?{...o,parentIndex:-1}:o,i):[o,i];if(!r)return e;t.push(...r.slice(1))}return t.filter((t,e,n)=\u003e{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x);return Math.abs(r)\u003e1e-8||!Hq(o,i)})}const o=[e[0]];let i=0;for(;i\u003ce.length-1;){let t=e.length-1;for(;t\u003ei+1\u0026\u0026this.segmentCollides(e[i],e[t]);)t--;o.push(e[t]),i=t}return o.filter((t,e,n)=\u003e{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x);return Math.abs(r)\u003e1e-8})}createStats(){return{phase:\"obstacle-aware-grid-search\",gridSize:this.problem.gridSize,traceWidth:this.problem.traceWidth,gridOffset:this.problem.gridOffset,openCells:this.open.size,closedCells:this.closedCellCount,gridCells:this.rows*this.columns}}computeProgress(){return Math.min(.99,this.iterations/this.MAX_ITERATIONS)}getOutput(){return this.output}getConstructorParams(){const{obstacleIndex:t,...e}=this.problem;return[e]}visualize(){const t=this.nodes.filter(t=\u003ethis.closed[this.toFlatIndex(t.row,t.column)]).slice(-2e3).map(t=\u003e({x:t.x,y:t.y,color:\"rgba(0,90,255,0.22)\"})),e=this.output?.points??[];return{coordinateSystem:\"cartesian\",title:this.getSolverName(),rects:[{center:{x:(this.searchBounds.minX+this.searchBounds.maxX)/2,y:(this.searchBounds.minY+this.searchBounds.maxY)/2},width:this.searchBounds.maxX-this.searchBounds.minX,height:this.searchBounds.maxY-this.searchBounds.minY,stroke:\"#777\"}],points:[...t,{...this.problem.start,color:\"green\",label:\"reroute start\"},{...this.problem.end,color:\"purple\",label:\"reroute target\"}],lines:e.length\u003e1?[{points:e,strokeColor:\"#00a050\",strokeWidth:this.problem.traceWidth}]:[],circles:[],texts:[]}}},tJ=class{items;clearance;boardEdgeClearance;boardLayers;minViaHoleEdgeToViaHoleEdgeClearance;defaultViaHoleDiameter;bounds;maxIndexedViaHoleDiameter;index;connectionNameSets;copperObjectIds;connectionNameResolver;connectedPads;dynamicTraceIndex;constructor(t,e,n,o=[],i=new Pq(t,e)){var r;this.bounds=t.bounds,this.boardLayers=(r=t.layerCount,[\"top\",...Array.from({length:Math.max(0,r-2)},(t,e)=\u003e`inner${e+1}`),...r\u003e1?[\"bottom\"]:[]]),this.dynamicTraceIndex=n,this.clearance=Math.max(t.defaultObstacleMargin??0,t.minTraceToPadEdgeClearance??0,.1),this.boardEdgeClearance=t.minBoardEdgeClearance??this.clearance,this.minViaHoleEdgeToViaHoleEdgeClearance=Math.max(t.minViaHoleEdgeToViaHoleEdgeClearance??0,.1),this.defaultViaHoleDiameter=t.min_via_hole_diameter??t.minViaHoleDiameter??.3,this.items=[...t.obstacles.flatMap((t,e)=\u003efunction(t,e=.6){const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.max(1,Math.ceil(t.width/e)),i=Math.max(1,Math.ceil(t.height/e)),r=t.width/o,s=t.height/i,a=[];for(let e=0;e\u003ci;e++)for(let i=0;i\u003co;i++){const o={x:t.center.x-t.width/2+(i+.5)*r,y:t.center.y-t.height/2+(e+.5)*s},c=r/2,l=s/2,d=[{x:o.x-c,y:o.y-l},{x:o.x+c,y:o.y-l},{x:o.x+c,y:o.y+l},{x:o.x-c,y:o.y+l}].map(e=\u003eFq(e,t.center,n));a.push({minX:Math.min(...d.map(t=\u003et.x)),minY:Math.min(...d.map(t=\u003et.y)),maxX:Math.max(...d.map(t=\u003et.x)),maxY:Math.max(...d.map(t=\u003et.y)),layers:t.layers,kind:\"obstacle\",obstacleKind:t.connectedTo[0]?.startsWith(\"pcb_via_\")?\"via\":t.connectedTo[0]?.startsWith(\"pcb_smtpad_\")||t.connectedTo[0]?.startsWith(\"pcb_plated_hole_\")?\"pad\":\"other\",connectionNames:t.connectedTo,exactShape:{type:\"polygon\",points:d}})}return a}(t).map(t=\u003e({...t,copperObjectId:`obstacle:${e}`}))),...this.createTraceItems(t.fixedTraces??[],!0),...this.createTraceItems(e),...o],this.maxIndexedViaHoleDiameter=this.items.reduce((t,e)=\u003e\"via\"===e.kind?Math.max(t,e.viaHoleDiameter??this.defaultViaHoleDiameter):t,this.defaultViaHoleDiameter),this.connectionNameResolver=i,this.connectionNameSets=this.items.map(t=\u003enew Set(i.canonicalize(t.connectionNames))),this.copperObjectIds=this.items.map((t,e)=\u003et.copperObjectId??`indexed-item:${e}`),this.connectedPads=t.obstacles.flatMap(t=\u003et.connectedTo.some(t=\u003et.startsWith(\"pcb_smtpad_\")||t.startsWith(\"pcb_plated_hole_\"))?[{obstacle:t,canonicalConnectionNames:new Set(i.canonicalize(t.connectedTo))}]:[]),this.index=this.items.length\u003e0?new Bt(this.items.length):null;for(const t of this.items)this.index.add(t.minX,t.minY,t.maxX,t.maxY);this.index?.finish()}createTraceItems(t,e=!1){const n=[];for(let o=0;o\u003ct.length;o++){const i=t[o],r=e?void 0:o,s=`${e?\"fixed-trace\":\"trace\"}:${o}`,a=!e\u0026\u0026o===this.dynamicTraceIndex,c=[i.connection_name,i.source_trace_id,i.rootConnectionName,...i.mergedConnectionNames??[],...i.connectsTo??[]].filter(t=\u003eBoolean(t));for(let t=0;t\u003ci.route.length;t++){const e=i.route[t];if(\"via\"===e.route_type){const o=e.via_diameter??.6;n.push({minX:e.x-o/2,minY:e.y-o/2,maxX:e.x+o/2,maxY:e.y+o/2,layers:this.boardLayers,kind:\"via\",connectionNames:c,copperObjectId:s,traceIndex:r,routeStartIndex:t,routeEndIndex:t,viaHoleDiameter:e.via_hole_diameter??this.defaultViaHoleDiameter,exactShape:{type:\"circle\",center:{x:e.x,y:e.y},radius:o/2}});continue}if(a)continue;const o=i.route[t+1];\"wire\"===e.route_type\u0026\u0026\"wire\"===o?.route_type\u0026\u0026e.layer===o.layer\u0026\u0026n.push(...zq({start:e,end:o,width:e.width,base:{layers:[e.layer],kind:\"trace\",connectionNames:c,copperObjectId:s,traceIndex:r,routeStartIndex:t,routeEndIndex:t+1}}))}}return n}collides(t){if(this.isOutsideBounds(t))return!0;const{radius:e,candidates:n,canonicalConnectionNames:o}=this.getCollisionCandidates(t);for(const i of n)if(this.itemCollides(i,t,e,o))return!0;return!1}findCollisions(t){const{radius:e,candidates:n,canonicalConnectionNames:o}=this.getCollisionCandidates(t),i=[];for(const r of n)this.itemCollides(r,t,e,o)\u0026\u0026i.push(this.items[r]);return i}getSameNetCopperContactIds(t){const e=t.width/2,n=this.index?.search(Math.min(t.start.x,t.end.x)-e,Math.min(t.start.y,t.end.y)-e,Math.max(t.start.x,t.end.x)+e,Math.max(t.start.y,t.end.y)+e)??[],o=new Set(this.connectionNameResolver.canonicalize(t.connectionNames)),i=new Set;for(const r of n){const n=this.items[r];n.layers.includes(t.layer)\u0026\u0026(n.traceIndex===t.ignoreTraceIndex||t.ignoreTraceIndices?.includes(n.traceIndex??-1)||[...this.connectionNameSets[r]].some(t=\u003eo.has(t))\u0026\u0026this.itemCopperTouches(n,t,e)\u0026\u0026i.add(this.copperObjectIds[r]))}return i}getConnectedPadWidthLimit(t){if(Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y)\u003c=1e-5)return null;const e=this.getConnectedPadWidthLimitAtPoint(t,t.start),n=this.getConnectedPadWidthLimitAtPoint(t,t.end);return null===e?n:null===n?e:Math.min(e,n)}getConnectedPadWidthLimitAtPoint(t,e){const n=this.getConnectedPadsAtPoint(t,e);return 0===n.length?null:Math.max(...n.map(({obstacle:e})=\u003ethis.getPadWidthNormalToQuery(e,t)))}getConnectedPadEndpointWidthLimitAtPoint(t,e){const n=this.getConnectedPadsAtPoint(t,e);return 0===n.length?null:Math.max(...n.map(({obstacle:t})=\u003e{const n=this.getObstacleLocalPoint(e,t);return Math.max(0,2*Math.min(t.width/2-Math.abs(n.x),t.height/2-Math.abs(n.y)))}))}getConnectedPadBoundaryPoint(t,e){const n=\"start\"===e?t.start:t.end,o=\"start\"===e?t.end:t.start,i=this.getConnectedPadsAtPoint(t,n).sort((e,n)=\u003ethis.getPadWidthNormalToQuery(n.obstacle,t)-this.getPadWidthNormalToQuery(e.obstacle,t))[0];return!i||this.pointIsInsideObstacle(o,i.obstacle)?null:this.getObstacleBoundaryPoint(n,o,i.obstacle)}getConnectedPadsAtPoint(t,e){const n=new Set(this.connectionNameResolver.canonicalize(t.connectionNames));return this.connectedPads.filter(({obstacle:o,canonicalConnectionNames:i})=\u003eo.layers.includes(t.layer)\u0026\u0026[...i].some(t=\u003en.has(t))\u0026\u0026this.pointIsInsideObstacle(e,o))}pointIsInsideObstacle(t,e){const{x:n,y:o}=this.getObstacleLocalPoint(t,e);return Math.abs(n)\u003c=e.width/2+1e-9\u0026\u0026Math.abs(o)\u003c=e.height/2+1e-9}getObstacleLocalPoint(t,e){const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=Math.cos(n),i=Math.sin(n),r=t.x-e.center.x,s=t.y-e.center.y;return{x:r*o-s*i,y:r*i+s*o}}getPadWidthNormalToQuery(t,e){const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.hypot(n,o);if(i\u003c=1e-9)return Math.min(t.width,t.height);const r=-o/i,s=n/i,a=-(t.ccwRotationDegrees??0)*Math.PI/180,c=Math.cos(a),l=Math.sin(a),d=r*c-s*l,h=r*l+s*c;return Math.abs(d)*t.width+Math.abs(h)*t.height}getObstacleBoundaryPoint(t,e,n){const o=-(n.ccwRotationDegrees??0)*Math.PI/180,i=Math.cos(o),r=Math.sin(o),s=t=\u003e{const e=t.x-n.center.x,o=t.y-n.center.y;return{x:e*i-o*r,y:e*r+o*i}},a=s(t),c=s(e),l={x:c.x-a.x,y:c.y-a.y},d=[];if(Math.abs(l.x)\u003e1e-12){const t=l.x\u003e0?n.width/2:-n.width/2;d.push((t-a.x)/l.x)}if(Math.abs(l.y)\u003e1e-12){const t=l.y\u003e0?n.height/2:-n.height/2;d.push((t-a.y)/l.y)}const h=Math.min(...d.filter(t=\u003et\u003e=0\u0026\u0026t\u003c=1));return Number.isFinite(h)?{x:t.x+(e.x-t.x)*h,y:t.y+(e.y-t.y)*h}:null}getConnectedLayersAtPoint(t,e){const n=new Set(this.connectionNameResolver.canonicalize(e)),o=new Set,i=this.index?.search(t.x,t.y,t.x,t.y)??[];for(const e of i){const i=this.items[e];if(\"obstacle\"!==i.kind)continue;if(![...this.connectionNameSets[e]].some(t=\u003en.has(t)))continue;if(\"polygon\"===i.exactShape?.type?Lq(t,t,i.exactShape.points)\u003c=1e-9:\"circle\"===i.exactShape?.type?Math.hypot(i.exactShape.center.x-t.x,i.exactShape.center.y-t.y)\u003c=i.exactShape.radius+1e-9:t.x\u003e=i.minX-1e-9\u0026\u0026t.x\u003c=i.maxX+1e-9\u0026\u0026t.y\u003e=i.minY-1e-9\u0026\u0026t.y\u003c=i.maxY+1e-9)for(const t of i.layers)o.add(t)}return[...o]}collidesVia(t){return this.getViaViolationSignatures(t).size\u003e0}getViaViolationSignatures(t){const e=new Set;for(const n of t.layers){const o={start:t.point,end:t.point,layer:n,width:t.padDiameter,connectionNames:t.connectionNames,ignoreTraceIndex:t.ignoreTraceIndex,ignoreTraceIndices:t.ignoreTraceIndices,ignoreRouteRange:t.ignoreRouteRange,obstacleClearance:t.obstacleClearance,blockSameNetObstacles:t.blockSameNetObstacles,sameNetObstacleClearance:t.sameNetObstacleClearance};this.isOutsideBounds(o)\u0026\u0026e.add(`board-edge:${n}`);const{radius:i,candidates:r,canonicalConnectionNames:s}=this.getCollisionCandidates(o);for(const t of r)this.itemCollides(t,o,i,s)\u0026\u0026e.add(`copper:${n}:${this.getViolationObjectId(t)}`)}const n=t.holeDiameter+this.minViaHoleEdgeToViaHoleEdgeClearance;for(const o of t.otherNewViaPoints??[])Math.hypot(o.x-t.point.x,o.y-t.point.y)\u003cn-1e-9\u0026\u0026e.add(`new-via-drill:${o.x},${o.y}:${t.holeDiameter}`);const o=t.fixedVias??[];for(let n=0;n\u003co.length;n++){const i=o[n],r=t.holeDiameter/2+i.holeDiameter/2+this.minViaHoleEdgeToViaHoleEdgeClearance;Math.hypot(i.point.x-t.point.x,i.point.y-t.point.y)\u003cr-1e-9\u0026\u0026e.add(`fixed-via-drill:${n}:${i.point.x},${i.point.y}:${i.holeDiameter}`)}const i=t.holeDiameter/2+this.maxIndexedViaHoleDiameter/2+this.minViaHoleEdgeToViaHoleEdgeClearance,r=this.index?.search(t.point.x-i,t.point.y-i,t.point.x+i,t.point.y+i)??[],s=new Set;for(const n of r){const o=this.items[n];if(\"via\"!==o.kind||\"circle\"!==o.exactShape?.type)continue;if(o.traceIndex===t.ignoreTraceIndex\u0026\u0026t.ignoreRouteRange\u0026\u0026(o.routeEndIndex??-1)\u003e=t.ignoreRouteRange.start\u0026\u0026(o.routeStartIndex??Number.POSITIVE_INFINITY)\u003c=t.ignoreRouteRange.end)continue;if(t.ignoreTraceIndices?.includes(o.traceIndex??-1))continue;const i=`${this.copperObjectIds[n]??\"unknown\"}:${o.routeStartIndex??-1}`;if(s.has(i))continue;s.add(i);const r=o.viaHoleDiameter??this.defaultViaHoleDiameter,a=t.holeDiameter/2+r/2+this.minViaHoleEdgeToViaHoleEdgeClearance;Math.hypot(o.exactShape.center.x-t.point.x,o.exactShape.center.y-t.point.y)\u003ca-1e-9\u0026\u0026e.add(`indexed-via-drill:${this.getViolationObjectId(n)}`)}return e}getViolationObjectId(t){const e=this.items[t],n=this.copperObjectIds[t],o=`${e.routeStartIndex??\"\"}-${e.routeEndIndex??\"\"}`;if(\"obstacle\"===e.kind)return n;if(\"segment\"===e.exactShape?.type){const{start:t,end:i,width:r}=e.exactShape;return`${n}:${e.kind}:${o}:${t.x},${t.y}:${i.x},${i.y}:${r}`}if(\"circle\"===e.exactShape?.type){const{center:t,radius:i}=e.exactShape;return`${n}:${e.kind}:${o}:${t.x},${t.y}:${i}`}return\"polygon\"===e.exactShape?.type?`${n}:${e.kind}:${o}:${e.exactShape.points.map(t=\u003e`${t.x},${t.y}`).join(\";\")}`:`${n}:${e.kind}:${o}:${e.minX},${e.minY},${e.maxX},${e.maxY}`}getCollisionCandidates(t){const e=Math.max(this.clearance,t.obstacleClearance??this.clearance,t.sameNetObstacleClearance??0),n=t.width/2+e,o={minX:Math.min(t.start.x,t.end.x)-n,minY:Math.min(t.start.y,t.end.y)-n,maxX:Math.max(t.start.x,t.end.x)+n,maxY:Math.max(t.start.y,t.end.y)+n};return{radius:n,candidates:this.index?.search(o.minX,o.minY,o.maxX,o.maxY)??[],canonicalConnectionNames:this.connectionNameResolver.canonicalize(t.connectionNames)}}itemCollides(t,e,n,o){const i=this.items[t];if(!i.layers.includes(e.layer))return!1;const r=this.connectionNameSets[t],s=o.some(t=\u003er.has(t));if(s\u0026\u0026(!e.blockSameNetObstacles||\"obstacle\"!==i.kind||\"via\"===i.obstacleKind))return!1;if(\"trace\"===i.kind\u0026\u0026e.ignoreTraceIndices?.includes(i.traceIndex??-1))return!1;if(\"trace\"===i.kind\u0026\u0026i.traceIndex===e.ignoreTraceIndex\u0026\u0026e.ignoreRouteRange\u0026\u0026(i.routeEndIndex??-1)\u003e=e.ignoreRouteRange.start\u0026\u0026(i.routeStartIndex??Number.POSITIVE_INFINITY)\u003c=e.ignoreRouteRange.end)return!1;const a=\"obstacle\"===i.kind\u0026\u0026\"pad\"===i.obstacleKind?s\u0026\u0026e.blockSameNetObstacles?e.sameNetObstacleClearance??e.obstacleClearance??this.clearance:e.obstacleClearance??this.clearance:this.clearance,c=e.width/2+a;return\"segment\"===i.exactShape?.type?Oq(e.start,e.end,i.exactShape.start,i.exactShape.end)\u003c=c+i.exactShape.width/2+1e-9:\"polygon\"===i.exactShape?.type?Lq(e.start,e.end,i.exactShape.points)\u003c=c+1e-9:\"circle\"===i.exactShape?.type?wq(i.exactShape.center,e.start,e.end)\u003c=c+i.exactShape.radius+1e-9:Dq(e.start,e.end,{minX:i.minX-c,minY:i.minY-c,maxX:i.maxX+c,maxY:i.maxY+c})}itemCopperTouches(t,e,n){return\"segment\"===t.exactShape?.type?Oq(e.start,e.end,t.exactShape.start,t.exactShape.end)\u003c=n+t.exactShape.width/2+1e-9:\"polygon\"===t.exactShape?.type?Lq(e.start,e.end,t.exactShape.points)\u003c=n+1e-9:\"circle\"===t.exactShape?.type?wq(t.exactShape.center,e.start,e.end)\u003c=n+t.exactShape.radius+1e-9:Dq(e.start,e.end,{minX:t.minX-n,minY:t.minY-n,maxX:t.maxX+n,maxY:t.maxY+n})}isOutsideBounds(t){const e=t.width/2+this.boardEdgeClearance;return Math.min(t.start.x,t.end.x)-e\u003cthis.bounds.minX||Math.max(t.start.x,t.end.x)+e\u003ethis.bounds.maxX||Math.min(t.start.y,t.end.y)-e\u003cthis.bounds.minY||Math.max(t.start.y,t.end.y)+e\u003ethis.bounds.maxY}},eJ=[{x:0,y:0},{x:.5,y:0},{x:0,y:.5},{x:.5,y:.5}],nJ=t=\u003e\"wire\"===t?.route_type,oJ=class extends Sq{inputProblem;traces;corridor;phase=\"scan-corridor\";corridorCursor=0;blockerCursor=0;offsetCursor=0;resolutionCursor=0;attemptedGridCount=0;blockerIndex;connectionNameResolver;connectionByTraceId=new Map;mutableTraceIndices;blockersByTrace=new Map;blockers=[];currentBlocker=null;currentRange=null;currentTraceWidth=0;gridResolutions=[];currentObstacleIndex=null;output=null;constructor(t,e=new Pq(t.simpleRouteJson,t.traces)){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.corridor=structuredClone(t.corridor),this.mutableTraceIndices=t.mutableTraceIndices?new Set(t.mutableTraceIndices):null,this.connectionNameResolver=e,this.blockerIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,t.powerTraceIndex,[],this.connectionNameResolver),this.activeSubSolver=null,this.MAX_ITERATIONS=25e3,this.stats=this.createStats()}getSolverName(){return\"LocalTraceInflationSolver\"}_step(){if(this.activeSubSolver)return this.stepActiveSubSolver(),void(this.stats=this.createStats());switch(this.phase){case\"scan-corridor\":this.scanNextCorridorSegment();break;case\"select-blocker\":this.selectNextBlocker();break;case\"try-elastic-push\":break;case\"try-grid-candidate\":this.startNextGridCandidate();break;case\"complete\":this.output?this.solved=!0:(this.failed=!0,this.error=\"No locally reroutable trace blocks the power corridor\")}this.stats=this.createStats()}scanNextCorridorSegment(){const t=this.corridor[this.corridorCursor];if(!t)return this.blockers=[...this.blockersByTrace.values()].sort((t,e)=\u003et.traceIndex-e.traceIndex),void(this.phase=\"select-blocker\");const e=this.traces[this.inputProblem.powerTraceIndex],n=this.blockerIndex.findCollisions({start:t.start,end:t.end,layer:t.layer,width:t.width,connectionNames:e?this.getTraceConnectionNames(e):[]});for(const t of n)this.recordBlockingTrace(t);this.corridorCursor++}recordBlockingTrace(t){if(\"trace\"!==t.kind||void 0===t.traceIndex||void 0===t.routeStartIndex||void 0===t.routeEndIndex||t.traceIndex===this.inputProblem.powerTraceIndex||null!==this.mutableTraceIndices\u0026\u0026!this.mutableTraceIndices.has(t.traceIndex))return;const e=this.traces[t.traceIndex];if(!e)return;const n=this.findConnectionForTrace(e);if((n?this.resolveNominalTraceWidth(n):this.getTraceNominalWidth(e))\u003e=(this.inputProblem.pushOnlyNominalWidthsBelow??this.inputProblem.nominalPowerWidth)-Mq)return;const o=this.blockersByTrace.get(t.traceIndex);if(o)return o.firstRouteIndex=Math.min(o.firstRouteIndex,t.routeStartIndex),void(o.lastRouteIndex=Math.max(o.lastRouteIndex,t.routeEndIndex));this.blockersByTrace.set(t.traceIndex,{traceIndex:t.traceIndex,firstRouteIndex:t.routeStartIndex,lastRouteIndex:t.routeEndIndex})}selectNextBlocker(){if(this.currentBlocker=this.blockers[this.blockerCursor]??null,!this.currentBlocker)return void(this.phase=\"complete\");const t=this.findStableAnchorRange(this.currentBlocker);if(!t)return void this.blockerCursor++;const e=this.traces[this.currentBlocker.traceIndex];this.currentRange=t,this.currentTraceWidth=this.getRangeWidth(e,t),this.gridResolutions=this.getGridResolutions(this.currentTraceWidth),this.resolutionCursor=0,this.offsetCursor=0,this.currentObstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,this.currentBlocker.traceIndex,this.createInflatedCorridorItems(),this.connectionNameResolver),this.activeSubSolver=new Wq({trace:e,range:t,layer:e.route[t.startIndex].layer,traceWidth:this.currentTraceWidth,corridor:this.corridor,obstacleIndex:this.currentObstacleIndex,connectionNames:this.getTraceConnectionNames(e)}),this.phase=\"try-elastic-push\"}findStableAnchorRange(t){const e=this.traces[t.traceIndex];if(!e)return null;let n=t.firstRouteIndex,o=t.lastRouteIndex;for(;n\u003e0;){const t=e.route[n];if(nJ(t)\u0026\u0026this.pointClearsCorridor(t))break;n--}for(;o\u003ce.route.length-1;){const t=e.route[o];if(nJ(t)\u0026\u0026this.pointClearsCorridor(t))break;o++}const i=e.route[n],r=e.route[o];if(!nJ(i)||!nJ(r)||i.layer!==r.layer||!this.pointClearsCorridor(i)||!this.pointClearsCorridor(r)||n\u003e=o)return null;const s={startIndex:n,endIndex:o},a=this.getRangeLength(e,s);return!Number.isFinite(a)||a\u003e(this.inputProblem.maxRerouteLength??10)+Mq?null:s}pointClearsCorridor(t){return this.corridor.every(e=\u003e{if(e.layer!==t.layer)return!0;const n=e.width/2+t.width/2+this.blockerIndex.clearance;return wq(t,e.start,e.end)\u003e=n-Mq})}startNextGridCandidate(){if(!this.currentBlocker||!this.currentRange)return void(this.phase=\"select-blocker\");if(this.resolutionCursor\u003e=this.gridResolutions.length)return this.blockerCursor++,void(this.phase=\"select-blocker\");if(this.offsetCursor\u003e=eJ.length)return this.resolutionCursor++,void(this.offsetCursor=0);const t=this.traces[this.currentBlocker.traceIndex],e=t.route[this.currentRange.startIndex],n=t.route[this.currentRange.endIndex];if(!nJ(e)||!nJ(n))return this.blockerCursor++,void(this.phase=\"select-blocker\");const o=this.gridResolutions[this.resolutionCursor],i=eJ[this.offsetCursor],r=this.currentObstacleIndex;if(!r)return this.blockerCursor++,void(this.phase=\"select-blocker\");this.attemptedGridCount++,this.activeSubSolver=new Qq({start:e,end:n,layer:e.layer,traceWidth:this.currentTraceWidth,gridSize:o,gridOffset:{x:i.x*o,y:i.y*o},connectionNames:this.getTraceConnectionNames(t),obstacleIndex:r,ignoreTraceIndex:this.currentBlocker.traceIndex,ignoreRouteRange:{start:this.currentRange.startIndex,end:this.currentRange.endIndex},bounds:this.inputProblem.simpleRouteJson.bounds,searchPadding:Rq(2.5*this.inputProblem.nominalPowerWidth,1.5,4)})}stepActiveSubSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e)return this.applyRoute(e,t instanceof Wq?\"elastic\":\"grid\"),this.activeSubSolver=null,void(this.phase=\"complete\")}this.failedSubSolvers??=[],this.failedSubSolvers.push(t),this.activeSubSolver=null,t instanceof Wq?this.phase=\"try-grid-candidate\":this.offsetCursor++}}applyRoute(t,e){const n=this.currentBlocker,o=this.currentRange,i=this.traces[n.traceIndex],r=i.route[o.startIndex],s=i.route[o.endIndex],a=t.points.map(t=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:this.currentTraceWidth,layer:r.layer}));a[0].width=Math.max(a[0].width,r.width),a[a.length-1].width=Math.max(a[a.length-1].width,s.width),i.route.splice(o.startIndex,o.endIndex-o.startIndex+1,...a),this.output={traces:this.traces,pushedTraceIndex:n.traceIndex,replacedRange:o,strategy:e}}createInflatedCorridorItems(){return this.corridor.flatMap(t=\u003ezq({start:t.start,end:t.end,width:t.width,base:{layers:[t.layer],kind:\"obstacle\",connectionNames:[]}}))}getGridResolutions(t){return[Rq(1.5*t,.1,.3),Rq(.75*t,.08,.18)].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e-t)\u003cMq)===e)}getRangeWidth(t,e){let n=this.inputProblem.simpleRouteJson.minTraceWidth;for(let o=e.startIndex;o\u003c=e.endIndex;o++){const e=t.route[o];nJ(e)\u0026\u0026(n=Math.max(n,e.width))}return n}getRangeLength(t,e){let n=0;for(let o=e.startIndex;o\u003ce.endIndex;o++){const e=t.route[o],i=t.route[o+1];if(!nJ(e)||!nJ(i)||e.layer!==i.layer)return Number.POSITIVE_INFINITY;n+=Nq(e,i)}return n}resolveNominalTraceWidth(t){return Math.max(t.nominalTraceWidth??t.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.inputProblem.simpleRouteJson.minTraceWidth,this.inputProblem.simpleRouteJson.minTraceWidth)}getTraceNominalWidth(t){return t.route.reduce((t,e)=\u003e\"wire\"===e.route_type?Math.max(t,e.width):t,this.inputProblem.simpleRouteJson.minTraceWidth)}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=this.getTraceConnectionNames(t),o=this.inputProblem.simpleRouteJson.connections.find(t=\u003e[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t)).some(t=\u003en.includes(t)))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getTraceConnectionNames(t){return[t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))}createStats(){return{phase:this.phase,corridorSegment:this.corridorCursor,corridorSegmentCount:this.corridor.length,blockingTraceCount:this.blockersByTrace.size,blockerCursor:this.blockerCursor,pushedTraceIndex:this.currentBlocker?.traceIndex,anchorRange:this.currentRange,traceWidth:this.currentTraceWidth,gridSize:this.gridResolutions[this.resolutionCursor],gridOffsetVariant:this.offsetCursor,attemptedGridCount:this.attemptedGridCount}}computeProgress(){return\"scan-corridor\"===this.phase?0===this.corridor.length?.25:this.corridorCursor/this.corridor.length*.25:0===this.blockers.length?.5:Math.min(.99,.25+this.blockerCursor/this.blockers.length)}getOutput(){return this.output}getConstructorParams(){return[this.inputProblem]}visualize(){const t=[];for(let e=0;e\u003cthis.traces.length;e++){const n=this.traces[e];for(let o=0;o\u003cn.route.length-1;o++){const i=n.route[o],r=n.route[o+1];nJ(i)\u0026\u0026nJ(r)\u0026\u0026i.layer===r.layer\u0026\u0026t.push({points:[i,r],strokeColor:e===this.currentBlocker?.traceIndex?\"#1769d2\":\"#777\",strokeWidth:Math.max(i.width,r.width)})}}for(const e of this.corridor)t.push({points:[e.start,e.end],strokeColor:\"rgba(255, 128, 0, 0.55)\",strokeWidth:e.width});return{coordinateSystem:\"cartesian\",title:this.getSolverName(),lines:t,points:[],rects:[],circles:[],texts:[]}}},iJ=1e-6,rJ=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y),sJ=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r\u003c=1e-12?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},aJ=(t,e,n)=\u003e(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),cJ=(t,e,n,o)=\u003e((t,e,n,o)=\u003e{const i=aJ(n,o,t),r=aJ(n,o,e),s=aJ(t,e,n),a=aJ(t,e,o);return(i\u003e0\u0026\u0026r\u003c0||i\u003c0\u0026\u0026r\u003e0)\u0026\u0026(s\u003e0\u0026\u0026a\u003c0||s\u003c0\u0026\u0026a\u003e0)})(t,e,n,o)?0:Math.min(sJ(t,n,o),sJ(e,n,o),sJ(n,t,e),sJ(o,t,e)),lJ=t=\u003e{const e=(t.ccwRotationDegrees??0)*Math.PI/180,n=Math.cos(e),o=Math.sin(e);return[{x:-t.width/2,y:-t.height/2},{x:t.width/2,y:-t.height/2},{x:t.width/2,y:t.height/2},{x:-t.width/2,y:t.height/2}].map(e=\u003e({x:t.center.x+e.x*n-e.y*o,y:t.center.y+e.x*o+e.y*n}))},dJ=t=\u003e{if(!(\"oval\"===t.type||\"circle\"===t.shape))return!1;if(Math.abs(t.width-t.height)\u003eiJ)throw new Error(`Physical connectivity does not yet support non-circular oval obstacle ${t.obstacleId??\"\u003cunknown\u003e\"}`);return!0},hJ=(t,e)=\u003e{for(let n=0;n\u003ce.length;n++)if(sJ(t,e[n],e[(n+1)%e.length])\u003c=iJ)return!0;let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n},uJ=(t,e)=\u003e{if(dJ(e))return Math.max(0,rJ(t,e.center)-e.width/2);const n=lJ(e);return hJ(t,n)?0:Math.min(...n.map((e,o)=\u003esJ(t,e,n[(o+1)%n.length])))},pJ=(t,e)=\u003e{if(dJ(t))return dJ(e)?Math.max(0,rJ(t.center,e.center)-t.width/2-e.width/2):Math.max(0,uJ(t.center,e)-t.width/2);if(dJ(e))return pJ(e,t);const n=lJ(t),o=lJ(e);if(hJ(n[0],o)||hJ(o[0],n))return 0;let i=Number.POSITIVE_INFINITY;for(let t=0;t\u003cn.length;t++)for(let e=0;e\u003co.length;e++)i=Math.min(i,cJ(n[t],n[(t+1)%n.length],o[e],o[(e+1)%o.length]));return i},mJ=(t,e)=\u003e({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),gJ=t=\u003e({minX:t.x,minY:t.y,maxX:t.x,maxY:t.y}),fJ=t=\u003e{if(dJ(t))return mJ(gJ(t.center),t.width/2);const e=lJ(t);return{minX:Math.min(...e.map(t=\u003et.x)),minY:Math.min(...e.map(t=\u003et.y)),maxX:Math.max(...e.map(t=\u003et.x)),maxY:Math.max(...e.map(t=\u003et.y))}},yJ=(t,e)=\u003e{if(!((t,e)=\u003et.layers.some(t=\u003ee.layers.includes(t)))(t,e)||!((t,e)=\u003et.maxX+iJ\u003e=e.minX\u0026\u0026e.maxX+iJ\u003e=t.minX\u0026\u0026t.maxY+iJ\u003e=e.minY\u0026\u0026e.maxY+iJ\u003e=t.minY)(t.bounds,e.bounds))return!1;if(\"bridge-pad\"===t.kind){const n={kind:\"obstacle\",obstacle:t.obstacle,layers:t.layers,bounds:t.bounds};return\"bridge-pad\"===e.kind?yJ(n,{kind:\"obstacle\",obstacle:e.obstacle,layers:e.layers,bounds:e.bounds}):yJ(n,e)}return\"bridge-pad\"===e.kind?yJ(e,t):\"endpoint\"===t.kind?\"endpoint\"===e.kind?rJ(t.point,e.point)\u003c=iJ:\"obstacle\"===e.kind?uJ(t.point,e.obstacle)\u003c=iJ:\"segment\"===e.kind?sJ(t.point,e.start,e.end)\u003c=e.width/2+iJ:rJ(t.point,e.center)\u003c=e.diameter/2+iJ:\"endpoint\"===e.kind?yJ(e,t):\"obstacle\"===t.kind?\"obstacle\"===e.kind?pJ(t.obstacle,e.obstacle)\u003c=iJ:\"segment\"===e.kind?((t,e,n)=\u003e{if(dJ(n))return Math.max(0,sJ(n.center,t,e)-n.width/2);const o=lJ(n);return hJ(t,o)||hJ(e,o)?0:Math.min(...o.map((n,i)=\u003ecJ(t,e,n,o[(i+1)%o.length])))})(e.start,e.end,t.obstacle)\u003c=e.width/2+iJ:uJ(e.center,t.obstacle)\u003c=e.diameter/2+iJ:\"obstacle\"===e.kind?yJ(e,t):\"segment\"===t.kind?\"segment\"===e.kind?cJ(t.start,t.end,e.start,e.end)\u003c=(t.width+e.width)/2+iJ:sJ(e.center,t.start,t.end)\u003c=t.width/2+e.diameter/2+iJ:\"segment\"===e.kind?yJ(e,t):rJ(t.center,e.center)\u003c=(t.diameter+e.diameter)/2+iJ},_J=class{parent;constructor(t){this.parent=Array.from({length:t},(t,e)=\u003ee)}find(t){const e=this.parent[t];if(e===t)return t;const n=this.find(e);return this.parent[t]=n,n}union(t,e){const n=this.find(t),o=this.find(e);n!==o\u0026\u0026(this.parent[o]=n)}},bJ=(t,e)=\u003e{const n=e.indexOf(t.from_layer),o=e.indexOf(t.to_layer);return n\u003c0||o\u003c0?[...new Set([t.from_layer,t.to_layer])]:e.slice(Math.min(n,o),Math.max(n,o)+1)},xJ=t=\u003e[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=\u003eBoolean(t)),vJ=t=\u003e[t.name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],t.netConnectionName,...t.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])].filter(t=\u003eBoolean(t)),SJ=t=\u003e[t.obstacleId,...t.connectedTo,...t.offBoardConnectsTo??[]].filter(t=\u003eBoolean(t)),IJ=(t,e,n,o)=\u003e({kind:\"bridge-contact\",center:{x:t.x,y:t.y},diameter:e,layers:n,bridgeId:o,bounds:mJ(gJ(t),e/2)}),CJ=.01,PJ={\"0603\":{horizontalWidth:.8,horizontalHeight:.95,centerSpacings:[1.65,1.8]},1206:{horizontalWidth:.6,horizontalHeight:1.6,centerSpacings:[3.2]},\"1206x4_pair\":{horizontalWidth:.8,horizontalHeight:.5,centerSpacings:[2.7]}},MJ=(t,e,n)=\u003e{if(!t.layer)throw new Error(`Jumper ${n} is missing its layer`);const o=PJ[t.footprint];if(!o)throw new Error(`Unsupported jumper footprint ${String(t.footprint)} on ${n}`);const i=Math.abs(t.end.x-t.start.x),r=Math.abs(t.end.y-t.start.y),s=t=\u003eo.centerSpacings.some(e=\u003eMath.abs(t-e)\u003cCJ),a=r\u003cCJ\u0026\u0026s(i),c=i\u003cCJ\u0026\u0026s(r);if(!a\u0026\u0026!c)throw new Error(`Jumper ${n} does not match ${t.footprint} pad spacing`);const l={type:\"rect\",center:{...e},width:a?o.horizontalWidth:o.horizontalHeight,height:a?o.horizontalHeight:o.horizontalWidth,layers:[t.layer],connectedTo:[]};return{kind:\"bridge-pad\",obstacle:l,layers:l.layers,bridgeId:n,bounds:fJ(l)}},NJ=(t,e,n)=\u003e{if(t.layer!==n.layer||e.layer!==n.layer)return!1;const o=(t,e)=\u003eMath.abs(t.x-e.x)\u003cCJ\u0026\u0026Math.abs(t.y-e.y)\u003cCJ,i=o(t,n.start)\u0026\u0026o(e,n.end),r=o(t,n.end)\u0026\u0026o(e,n.start);return i||r},wJ=(t,e,n,o)=\u003e{const i=[],r=t.route.flatMap((t,e)=\u003e\"jumper\"===t.route_type?[{routePoint:t,routePointIndex:e}]:[]),s=new Map;for(const e of r){const n=[];for(let o=1;o\u003ct.route.length;o++){const i=t.route[o-1],r=t.route[o];\"wire\"===i?.route_type\u0026\u0026\"wire\"===r?.route_type\u0026\u0026NJ(i,r,e.routePoint)\u0026\u0026n.push(o)}if(1!==n.length)throw new Error(`Jumper ${t.pcb_trace_id}:${e.routePointIndex} matched ${n.length} placeholder wire segments`);const o=n[0];if(s.has(o))throw new Error(`Multiple jumpers matched placeholder segment ${o} on ${t.pcb_trace_id}`);s.set(o,e)}let a;for(let r=0;r\u003ct.route.length;r++){const c=t.route[r];if(\"wire\"===c.route_type){if(a\u0026\u0026a.layer===c.layer\u0026\u0026rJ(a,c)\u003eiJ){const t=a;if(s.get(r));else{const e=t.width/2;i.push({kind:\"segment\",start:{x:t.x,y:t.y},end:{x:c.x,y:c.y},width:t.width,layers:[t.layer],bounds:mJ({minX:Math.min(t.x,c.x),minY:Math.min(t.y,c.y),maxX:Math.max(t.x,c.x),maxY:Math.max(t.y,c.y)},e)})}}a=c;continue}if(a=void 0,\"via\"===c.route_type){const o=t.route[r-1],s=t.route[r+1];for(const e of[o,s])if(\"wire\"===e?.route_type\u0026\u0026rJ(e,c)\u003eiJ)throw new Error(`Via ${t.pcb_trace_id}:${r} is adjacent to a non-colocated wire endpoint`);const a=c.via_diameter??n;i.push({kind:\"via\",center:{x:c.x,y:c.y},diameter:a,layers:bJ(c,e),bounds:mJ(gJ(c),a/2)});continue}const l=`${t.pcb_trace_id}:${r}:${c.route_type}`;if(\"jumper\"===c.route_type){i.push(MJ(c,c.start,l),MJ(c,c.end,l));continue}if(\"through_obstacle\"===c.route_type){if(!o.find(t=\u003et.layers.includes(c.from_layer)\u0026\u0026t.layers.includes(c.to_layer)\u0026\u0026uJ(c.start,t)\u003c=iJ\u0026\u0026uJ(c.end,t)\u003c=iJ))throw new Error(`Through-obstacle marker ${l} has no same-net multilayer obstacle witness`);i.push(IJ(c.start,0,[c.from_layer],l),IJ(c.end,0,[c.to_layer],l));continue}throw new Error(`Unsupported route primitive: ${String(c.route_type)}`)}return i},TJ=(t,e,n)=\u003e{const o=t.pointsToConnect[n];return o.pointId??o.pcb_port_id??`${t.name}[${e}:${n}]`},RJ=t=\u003e{const e={},n={},o=[];for(let i=0;i\u003ct.connections.length;i++){const r=t.connections[i];for(let t=0;t\u003cr.pointsToConnect.length;t++){const s=`${i}:${t}`;e[s]=TJ(r,i,t),n[s]=s,o.push([s])}}return{endpointCount:Object.keys(e).length,endpointLabels:e,componentByEndpointKey:n,endpointComponents:o}},EJ=t=\u003e{if(null===t||\"object\"!=typeof t)return JSON.stringify(t)??String(t);if(Array.isArray(t))return`[${t.map(t=\u003eEJ(t)).join(\",\")}]`;const e=t;return`{${Object.keys(e).sort().map(t=\u003e`${JSON.stringify(t)}:${EJ(e[t])}`).join(\",\")}}`},AJ=(t,e)=\u003e{const n=new Pq(t,e,{includePhysicalPositionAliases:!0}),o=(i=t.layerCount)\u003c=1?[\"top\"]:2===i?[\"top\",\"bottom\"]:[\"top\",...Array.from({length:i-2},(t,e)=\u003e`inner${e+1}`),\"bottom\"];var i;const r=(t=\u003e{const e=t.min_via_hole_diameter??t.minViaHoleDiameter??0;return Math.max(e,t.min_via_pad_diameter??t.minViaPadDiameter??t.minViaDiameter??.6)})(t),s=new Map,a=new Map,c={},l=(t,e)=\u003e{const n=s.get(t)??[];n.push(e),s.set(t,n)};for(let e=0;e\u003ct.connections.length;e++){const o=t.connections[e],i=n.canonicalize(vJ(o));if(1!==i.length)throw new Error(`Connection ${o.name} resolved to ${i.length} canonical nets`);for(let t=0;t\u003co.pointsToConnect.length;t++){const n=o.pointsToConnect[t],r=`${e}:${t}`,s=TJ(o,e,t);c[r]=s;const a={kind:\"endpoint\",endpointKey:r,endpointLabel:s,point:{x:n.x,y:n.y},layers:n.layers??[n.layer],bounds:gJ(n)};for(const t of i)l(t,a)}}for(const e of t.obstacles){const t={kind:\"obstacle\",obstacle:e,layers:e.layers,bounds:fJ(e)};for(const o of n.canonicalize(SJ(e))){const n=a.get(o)??[];n.push(e),a.set(o,n),s.has(o)\u0026\u0026l(o,t)}}for(const i of[...e,...t.fixedTraces??[]]){const t=n.canonicalize(xJ(i));if(1!==t.length)throw new Error(`Trace ${i.pcb_trace_id} resolved to ${t.length} canonical nets`);const e=a.get(t[0])??[],c=wJ(i,o,r,e);for(const e of t)if(s.has(e))for(const t of c)l(e,t)}const d={},h=[];for(const t of s.values()){const e=new _J(t.length),n=new Map;for(let o=0;o\u003ct.length;o++){const i=t[o];if(\"bridge-contact\"!==i.kind\u0026\u0026\"bridge-pad\"!==i.kind)continue;const r=n.get(i.bridgeId);void 0===r?n.set(i.bridgeId,o):e.union(r,o)}const o=t.length\u003e0?new Bt(t.length):null;if(o){for(const e of t)o.add(e.bounds.minX,e.bounds.minY,e.bounds.maxX,e.bounds.maxY);o.finish()}for(let n=0;n\u003ct.length;n++){const i=t[n],r=o?.search(i.bounds.minX-iJ,i.bounds.minY-iJ,i.bounds.maxX+iJ,i.bounds.maxY+iJ)??[];for(const o of r)o\u003c=n||yJ(i,t[o])\u0026\u0026e.union(n,o)}const i=new Map;for(let n=0;n\u003ct.length;n++){const o=t[n];if(\"endpoint\"!==o.kind)continue;const r=e.find(n),s=i.get(r)??[];s.push(o.endpointKey),i.set(r,s)}for(const t of i.values()){t.sort();const e=t[0];h.push(t);for(const n of t){if(void 0!==d[n])throw new Error(`Endpoint ${n} was assigned to multiple canonical nets`);d[n]=e}}}return h.sort(([t=\"\"],[e=\"\"])=\u003et.localeCompare(e)),{endpointCount:Object.keys(c).length,endpointLabels:c,componentByEndpointKey:d,endpointComponents:h}},OJ=class{baseline;inputProblem;baselineCaptureError;baselineTraceSignature;constructor(t,e){this.inputProblem=t,this.baselineTraceSignature=EJ(e);try{this.baseline=AJ(t,e),this.baselineCaptureError=null}catch(e){this.baseline=RJ(t),this.baselineCaptureError=e instanceof Error?e.message:String(e)}}validate(t){if(this.baselineCaptureError){const e=EJ(t)===this.baselineTraceSignature;return{safe:e,candidate:this.baseline,regressions:[],validationError:e?`Connectivity validation is limited to exact trace preservation: ${this.baselineCaptureError}`:`Connectivity validation failed closed: ${this.baselineCaptureError}`}}let e;try{e=AJ(this.inputProblem,t)}catch(t){return{safe:!1,candidate:RJ(this.inputProblem),regressions:[],validationError:`Connectivity validation failed closed: ${t instanceof Error?t.message:String(t)}`}}const n=[];for(const t of this.baseline.endpointComponents){if(t.length\u003c2)continue;const o=new Map;for(const n of t){const t=e.componentByEndpointKey[n]??`missing:${n}`,i=o.get(t)??[];i.push(n),o.set(t,i)}o.size\u003c=1||n.push({baselineEndpointKeys:[...t],baselineEndpointLabels:t.map(t=\u003ethis.baseline.endpointLabels[t]),candidateComponents:[...o.values()]})}return{safe:0===n.length,candidate:e,regressions:n}}},kJ=[{x:0,y:0},{x:.5,y:.5}],LJ=[.15,.2,.25,.3,.4,.5],DJ=t=\u003e\"wire\"===t?.route_type,zJ=t=\u003e\"via\"===t?.route_type,FJ=Array.from({length:24},(t,e)=\u003e{const n=e*Math.PI/12;return{x:Math.cos(n),y:Math.sin(n)}}),BJ=t=\u003e[...new Set(t.map(t=\u003eNumber(t.toFixed(6))))].sort((t,e)=\u003ee-t),jJ=class extends Sq{inputProblem;traces;obstacleIndex;phase=\"repair-vias\";traceCursor=0;routeCursor=0;candidateCursor=0;clearanceTierCursor=0;attemptedCandidateCount=0;attemptedClearanceShoveCount=0;attemptedViaGridCount=0;committedClearanceShoveCount=0;viaPairCountRemoved=0;viaCountRemoved=0;simplifiedPathCount=0;normalizedSegmentCount=0;achievedExtraClearanceCount=0;relocatedViaCount=0;unresolvedViaCount=0;attemptedPushedViaRepairCount=0;committedPushedViaRepairCount=0;padClearanceRerouteCount=0;unresolvedPadClearanceCount=0;initialPadClearanceViolationCount=0;remainingPadClearanceViolationCount=0;initialPadClearanceViolationCountByClearance={};remainingPadClearanceViolationCountByClearance={};budgetLimited=!1;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;connectionNameResolver;connectionByTraceId=new Map;connectivityInvariant;initialConnectivitySafeTraces;mutableTraceIndices;mutableTraceIndexSet;viaRepairTraceIndices;traceIndices;maxRerouteLength;clearancePaddingTiers;desiredPadClearance;initialTraceLengths=new Map;candidates=[];candidateShoveCount=0;rollbackTraces=null;baseCandidateValidated=!1;activeShovePadding=0;viaGridAttempt=null;candidateSetMayUseGridFallback=!1;pendingPushedViaRepair=null;alternatePushedViaRepairs=[];pushedViaRepairRollbackTraces=null;connectivityFinalized=!1;finalizedMutatedTraceIndices=[];resumePhase=\"scan-via-pairs\";constructor(t){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.initialConnectivitySafeTraces=structuredClone(t.traces),this.connectivityInvariant=new OJ(this.inputProblem.simpleRouteJson,this.initialConnectivitySafeTraces),this.connectionNameResolver=new Pq(t.simpleRouteJson,this.traces),this.maxRerouteLength=t.maxRerouteLength??10,this.desiredPadClearance=t.desiredPadClearance,this.clearancePaddingTiers=BJ([...t.clearancePaddingTiers??[.1,.05,0],0]).filter(t=\u003et\u003e=0);const e=this.traces.map((t,e)=\u003ee),n=(t,e,n)=\u003e{const o=[...new Set(t??n)];for(const t of o)if(!Number.isInteger(t)||t\u003c0||t\u003e=this.traces.length)throw new RangeError(`Invalid cleanup ${e} index: ${t}`);return o},o=n(t.traceIndices,\"trace\",e);this.viaRepairTraceIndices=n(t.viaRepairTraceIndices,\"via repair trace\",o),this.mutableTraceIndices=n(t.mutableTraceIndices,\"mutable trace\",o),this.mutableTraceIndexSet=new Set(this.mutableTraceIndices),this.traceIndices=o.filter(t=\u003ethis.resolveNominalTraceWidth(this.traces[t])\u003e=.499999);for(const t of this.traceIndices)this.initialTraceLengths.set(t,this.measureTraceLength(this.traces[t]));this.obstacleIndex=this.createObstacleIndex(),this.initialPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCount=this.initialPadClearanceViolationCount,this.initialPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.remainingPadClearanceViolationCountByClearance={...this.initialPadClearanceViolationCountByClearance},this.activeSubSolver=null,this.MAX_ITERATIONS=1e6,this.stats=this.createStats()}getSolverName(){return\"PowerTraceCleanupSolver\"}_step(){if(this.activeSubSolver)return this.stepActiveShoveSolver(),void(this.stats=this.createStats());switch(this.phase){case\"repair-vias\":this.repairNextVia();break;case\"scan-via-pairs\":this.scanNextViaPair();break;case\"scan-pad-clearance\":this.scanNextPadClearance();break;case\"scan-simplification\":this.scanNextSimplification();break;case\"evaluate-candidate\":this.evaluateCurrentCandidate();break;case\"shove-clearance\":break;case\"route-via-pair\":this.startNextViaGridCandidate();break;case\"complete\":this.ensureConnectivitySafeOutput(),this.solved=!0}this.stats=this.createStats()}repairNextVia(){const t=this.viaRepairTraceIndices[this.traceCursor],e=void 0===t?void 0:this.traces[t];if(!e)return this.traceCursor=0,this.routeCursor=0,this.phase=\"scan-via-pairs\",void this.rebuildObstacleIndex();const n=e.route.findIndex((t,e)=\u003ee\u003e=this.routeCursor\u0026\u0026zJ(t));if(-1===n)return this.traceCursor++,void(this.routeCursor=0);this.routeCursor=n+1;const o=e.route[n],i=e.route[n-1],r=e.route[n+1];if(!zJ(o)||!DJ(i)||!DJ(r))return;const s=this.getTraceConnectionNames(e),a=this.getBaseObstacleClearance();if(!this.obstacleIndex.collidesVia({point:o,layers:this.obstacleIndex.boardLayers,padDiameter:o.via_diameter??.6,holeDiameter:o.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,connectionNames:s,ignoreTraceIndex:t,ignoreRouteRange:{start:n,end:n},obstacleClearance:a,blockSameNetObstacles:!0,sameNetObstacleClearance:0}))return;const c=this.findViaRepair(e,n,a);if(!c){const t=this.findPushableViaRepairs(e,n,a),o=t.shift();return o?(this.alternatePushedViaRepairs=t,void this.startPushedViaRepair(o)):void this.unresolvedViaCount++}e.route.splice(c.startIndex,c.endIndex-c.startIndex+1,...c.route),this.relocatedViaCount++,this.routeCursor=c.startIndex+c.route.length,this.rebuildObstacleIndex()}findViaRepair(t,e,n){const o=this.createViaRepairContext(t,e);if(!o)return null;const i=o.candidates.map(t=\u003e({point:t,movedLength:Nq(o.leftAnchor,t)+Nq(t,o.rightAnchor)})).filter(({movedLength:t})=\u003et\u003c=o.originalLength+Math.min(6,this.maxRerouteLength)+Mq);i.sort((t,e)=\u003et.movedLength-e.movedLength||Nq(t.point,o.via)-Nq(e.point,o.via));for(const t of i)if(this.isViaRepairPointSafe(o,t.point,n))return this.createViaRepairReplacement(o,t.point);return null}findPushableViaRepairs(t,e,n){const o=this.viaRepairTraceIndices[this.traceCursor];if(void 0===o)return[];const i=this.createViaRepairContext(t,e);if(!i)return[];const r=i.candidates.flatMap(t=\u003e{const e=Nq(i.leftAnchor,t)+Nq(t,i.rightAnchor);if(e\u003ei.originalLength+Math.min(6,this.maxRerouteLength)+Mq)return[];const r=new Set,s=this.getViaRepairCollisionQueries(i,t,n);for(const t of s)for(const e of this.obstacleIndex.findCollisions(t)){if(\"trace\"!==e.kind||void 0===e.traceIndex||e.traceIndex===o||!this.mutableTraceIndexSet.has(e.traceIndex))return[];r.add(e.traceIndex)}if(0===r.size||r.size\u003e2)return[];const a=[...r];return this.isViaRepairPointSafe(i,t,n,a)?[{point:t,movedLength:e,blockerCount:r.size,blockerKey:[...r].sort((t,e)=\u003et-e).join(\",\")}]:[]});r.sort((t,e)=\u003et.blockerCount-e.blockerCount||t.movedLength-e.movedLength||Nq(t.point,i.via)-Nq(e.point,i.via));return[...new Map([...r].reverse().map(t=\u003e[t.blockerKey,t])).values(),...r].filter((t,e,n)=\u003en.findIndex(e=\u003ee.point.x===t.point.x\u0026\u0026e.point.y===t.point.y)===e).slice(0,12).map(t=\u003e({traceIndex:o,viaIndex:e,point:t.point,padClearance:n,corridor:[{start:i.leftAnchor,end:t.point,layer:i.leftWire.layer,width:i.leftWire.width},{start:t.point,end:i.rightAnchor,layer:i.rightWire.layer,width:i.rightWire.width},...this.obstacleIndex.boardLayers.map(e=\u003e({start:t.point,end:t.point,layer:e,width:i.viaDiameter}))]}))}createViaRepairContext(t,e){const n=t.route[e],o=t.route[e-1],i=t.route[e+1];if(!zJ(n)||!DJ(o)||!DJ(i))return null;const r=e-1==0||!DJ(t.route[e-2]),s=e+1===t.route.length-1||!DJ(t.route[e+2]),a=r?o:t.route[e-2],c=s?i:t.route[e+2],l=Nq(a,n)+Nq(n,c),d=this.getTraceConnectionNames(t),h=n.via_diameter??.6,u=n.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,p=Math.max(.3,u+this.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance+.05),m=[p,p+.15,p+.3,p+.5,p+.75,p+1,p+1.5,p+2].flatMap(t=\u003eFJ.map(e=\u003e({x:.025*Math.round((n.x+e.x*t)/.025),y:.025*Math.round((n.y+e.y*t)/.025)}))),g=[...m,...m.flatMap(t=\u003e[{x:t.x,y:Math.floor(10*n.y)/10},{x:t.x,y:Math.ceil(10*n.y)/10},{x:Math.floor(10*n.x)/10,y:t.y},{x:Math.ceil(10*n.x)/10,y:t.y}])].filter((t,e,n)=\u003en.findIndex(e=\u003ee.x===t.x\u0026\u0026e.y===t.y)===e);return{trace:t,viaIndex:e,via:n,leftWire:o,rightWire:i,leftIsEndpoint:r,rightIsEndpoint:s,leftAnchor:a,rightAnchor:c,originalLength:l,connectionNames:d,viaDiameter:h,holeDiameter:u,ignoreRouteRange:{start:Math.max(0,e-2),end:Math.min(t.route.length-1,e+2)},candidates:g}}getViaRepairCollisionQueries(t,e,n,o){const i=this.viaRepairTraceIndices[this.traceCursor],r={connectionNames:t.connectionNames,ignoreTraceIndex:i,ignoreTraceIndices:o,ignoreRouteRange:t.ignoreRouteRange,obstacleClearance:n};return[...this.obstacleIndex.boardLayers.map(n=\u003e({...r,start:e,end:e,layer:n,width:t.viaDiameter,blockSameNetObstacles:!0,sameNetObstacleClearance:0})),{...r,start:t.leftAnchor,end:e,layer:t.leftWire.layer,width:t.leftWire.width},{...r,start:e,end:t.rightAnchor,layer:t.rightWire.layer,width:t.rightWire.width}]}isViaRepairPointSafe(t,e,n,o){const i=this.viaRepairTraceIndices[this.traceCursor];return!this.obstacleIndex.collidesVia({point:e,layers:this.obstacleIndex.boardLayers,padDiameter:t.viaDiameter,holeDiameter:t.holeDiameter,connectionNames:t.connectionNames,ignoreTraceIndex:i,ignoreTraceIndices:o,ignoreRouteRange:{start:t.viaIndex,end:t.viaIndex},obstacleClearance:n,blockSameNetObstacles:!0,sameNetObstacleClearance:0})\u0026\u0026!this.getViaRepairCollisionQueries(t,e,n,o).slice(this.obstacleIndex.boardLayers.length).some(t=\u003ethis.obstacleIndex.collides(t))}createViaRepairReplacement(t,e){const n={...t.leftWire,...e},o={...t.via,...e},i={...t.rightWire,...e};return{startIndex:t.viaIndex-1,endIndex:t.viaIndex+1,route:[...t.leftIsEndpoint?[t.leftWire]:[],n,o,i,...t.rightIsEndpoint?[t.rightWire]:[]]}}startPushedViaRepair(t){this.pendingPushedViaRepair=t,this.pushedViaRepairRollbackTraces=structuredClone(this.traces),this.attemptedPushedViaRepairCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem.simpleRouteJson,traces:this.traces,powerTraceIndex:t.traceIndex,nominalPowerWidth:Math.max(...t.corridor.map(t=\u003et.width)),pushOnlyNominalWidthsBelow:Number.POSITIVE_INFINITY,mutableTraceIndices:this.mutableTraceIndices,corridor:t.corridor,maxRerouteLength:this.maxRerouteLength},this.connectionNameResolver)}finishPushedViaRepairSolver(t){const e=this.pendingPushedViaRepair;if(this.activeSubSolver=null,!e)return;if(t.solved){const n=t.getOutput();if(n){this.traces=n.traces,this.rebuildObstacleIndex();const t=this.traces[e.traceIndex],o=t?this.createViaRepairContext(t,e.viaIndex):null;if(o\u0026\u0026this.isViaRepairPointSafe(o,e.point,e.padClearance)){const n=this.createViaRepairReplacement(o,e.point);return t.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...n.route),this.relocatedViaCount++,this.committedPushedViaRepairCount++,this.routeCursor=n.startIndex+n.route.length,this.pendingPushedViaRepair=null,this.alternatePushedViaRepairs=[],this.pushedViaRepairRollbackTraces=null,void this.rebuildObstacleIndex()}}}this.pushedViaRepairRollbackTraces\u0026\u0026(this.traces=this.pushedViaRepairRollbackTraces),this.pendingPushedViaRepair=null,this.pushedViaRepairRollbackTraces=null;const n=this.alternatePushedViaRepairs.shift();if(n)return this.rebuildObstacleIndex(),void this.startPushedViaRepair(n);this.alternatePushedViaRepairs=[],this.unresolvedViaCount++,this.rebuildObstacleIndex()}scanNextViaPair(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.traceCursor=0,this.routeCursor=0,void(this.phase=\"scan-pad-clearance\");const e=this.traces[t],n=e.route.findIndex((t,e)=\u003ee\u003e=this.routeCursor\u0026\u0026\"via\"===t.route_type);if(-1===n)return void this.advanceTrace();const o=e.route.slice(n+1).findIndex(t=\u003e\"via\"===t.route_type);if(-1===o)return void this.advanceTrace();const i=n-1,r=n+1+o+1,s=e.route[i],a=e.route[r];if(this.routeCursor=n+1,!DJ(s)||!DJ(a)||s.layer!==a.layer||Nq(s,a)\u003ethis.maxRerouteLength+Mq)return;const c=this.createCandidates({kind:\"via-pair\",traceIndex:t,startIndex:i,endIndex:r}),l=c[0]?.width??Math.max(s.width,a.width),d=c[0]?.padClearance??this.getCandidatePadClearance(\"via-pair\",t,i,r),h=n=\u003e{const o=e.route[n];return!!DJ(o)\u0026\u0026this.obstacleIndex.findCollisions({start:o,end:o,layer:o.layer,width:l,connectionNames:this.getTraceConnectionNames(e),ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,i-1),end:Math.min(e.route.length-1,r+1)},obstacleClearance:d}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind)},u=e.route[i-1],p=e.route[r+1],m=c.length\u003e0\u0026\u0026h(i)\u0026\u0026DJ(u)\u0026\u0026u.layer===s.layer?i-1:i,g=c.length\u003e0\u0026\u0026h(r)\u0026\u0026DJ(p)\u0026\u0026p.layer===a.layer?r+1:r,f=[{startIndex:i,endIndex:r},{startIndex:m,endIndex:r},{startIndex:i,endIndex:g},{startIndex:m,endIndex:g}].filter((t,e,n)=\u003en.findIndex(e=\u003ee.startIndex===t.startIndex\u0026\u0026e.endIndex===t.endIndex)===e).flatMap(e=\u003ee.startIndex===i\u0026\u0026e.endIndex===r?c:this.createCandidates({kind:\"via-pair\",traceIndex:t,startIndex:e.startIndex,endIndex:e.endIndex}));0!==f.length\u0026\u0026this.beginCandidates(f,\"scan-via-pairs\",!0)}scanNextPadClearance(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.traceCursor=0,this.routeCursor=0,void(this.phase=\"scan-simplification\");const e=this.traces[t];if(this.resolveNominalTraceWidth(e)\u003c.499999)return void this.advanceTrace();const n=this.routeCursor,o=e.route[n],i=e.route[n+1];if(!DJ(o)||!DJ(i)||o.layer!==i.layer)return void(n\u003e=e.route.length-1?this.advanceTrace():this.routeCursor++);if(this.routeCursor++,!this.segmentHasPadClearanceViolation(t,n))return;const r=this.getPadClearanceIntervals(e,n).flatMap(e=\u003ethis.getImprovedPadClearanceTiers(t,e.startIndex,e.endIndex).flatMap(n=\u003ethis.createCandidates({kind:\"pad-clearance\",traceIndex:t,startIndex:e.startIndex,endIndex:e.endIndex,padClearance:n}).slice(0,8)));0!==r.length?this.beginCandidates(r.slice(0,72),\"scan-pad-clearance\",!0):this.unresolvedPadClearanceCount++}segmentHasPadClearanceViolation(t,e){const n=this.traces[t],o=n.route[e],i=n.route[e+1];return!(!DJ(o)||!DJ(i)||o.layer!==i.layer)\u0026\u0026this.obstacleIndex.findCollisions({start:o,end:i,layer:o.layer,width:Math.max(o.width,i.width),connectionNames:this.getTraceConnectionNames(n),ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,e-1),end:Math.min(n.route.length-1,e+2)},obstacleClearance:this.getPadClearanceForTrace(n)}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind)}getPadClearanceIntervals(t,e){const n=t.route[e];if(!DJ(n))return[];const o=[e];let i=0;for(let r=e-1;r\u003e=0;r--){const e=t.route[r],s=t.route[r+1];if(!DJ(e)||!DJ(s)||e.layer!==n.layer||s.layer!==n.layer)break;if(i+=Nq(e,s),i\u003ethis.maxRerouteLength/2+Mq)break;o.push(r)}const r=[e+1];i=0;for(let o=e+1;o\u003ct.route.length-1;o++){const e=t.route[o],s=t.route[o+1];if(!DJ(e)||!DJ(s)||e.layer!==n.layer||s.layer!==n.layer)break;if(i+=Nq(e,s),i\u003ethis.maxRerouteLength/2+Mq)break;r.push(o+1)}return o.flatMap(e=\u003er.map(n=\u003e({startIndex:e,endIndex:n,length:this.measureRouteRange(t,e,n).length}))).filter(t=\u003et.length\u003c=this.maxRerouteLength+Mq\u0026\u0026t.startIndex\u003ct.endIndex).sort((t,e)=\u003ee.length-t.length).slice(0,8)}scanNextSimplification(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),void(this.phase=\"complete\");const e=this.traces[t],n=this.routeCursor,o=e.route[n];if(!DJ(o)||n\u003e=e.route.length-1)return void(n\u003e=e.route.length-1?this.advanceTrace():this.routeCursor++);let i=0;const r=[];for(let t=n+1;t\u003ce.route.length;t++){const s=e.route[t-1],a=e.route[t];if(!DJ(s)||!DJ(a)||s.layer!==o.layer||a.layer!==o.layer)break;if(i+=Nq(s,a),i\u003ethis.maxRerouteLength+Mq)break;const c=this.measureRouteRange(e,n,t);(c.nonOctilinearSegmentCount\u003e0||c.pointCount\u003e3)\u0026\u0026r.push(t)}const s=r.slice(-6).reverse().flatMap(e=\u003ethis.createCandidates({kind:\"simplification\",traceIndex:t,startIndex:n,endIndex:e}));0!==s.length?this.beginCandidates(s,\"scan-simplification\"):this.routeCursor++}createCandidates({kind:t,traceIndex:e,startIndex:n,endIndex:o,padClearance:i}){const r=this.traces[e],s=r.route[n],a=r.route[o];if(!DJ(s)||!DJ(a)||s.layer!==a.layer)return[];const c=this.resolveNominalTraceWidth(r),l=this.measureRouteRange(r,n,o),d=i??this.getCandidatePadClearance(t,e,n,o),h=[],u=qq(s,a);if(\"pad-clearance\"===t\u0026\u00260===Gq([s,a])){const t=Nq(s,a);if(t\u003eMq){const e={x:-(a.y-s.y)/t,y:(a.x-s.x)/t};for(const t of[.25,.5,.75,1,1.5,2])for(const n of[-1,1])u.push([s,{x:s.x+e.x*t*n,y:s.y+e.y*t*n},{x:a.x+e.x*t*n,y:a.y+e.y*t*n},a])}}const p=new Map(u.map(t=\u003e[t.map(t=\u003e`${t.x.toFixed(6)},${t.y.toFixed(6)}`).join(\";\"),t]));for(const i of p.values()){const u=Uq(i);if(u\u003ethis.maxRerouteLength+Mq||\"pad-clearance\"===t\u0026\u0026u\u003e1.35*l.length+.5||\"simplification\"===t\u0026\u0026(u\u003e1.1*l.length+Mq||this.measureTraceLength(r)-l.length+u\u003e1.01*(this.initialTraceLengths.get(e)??this.measureTraceLength(r))+Mq))continue;const p=u\u003c=Mq?c:c-l.deficitArea/u;if(p\u003ec+Mq)continue;const m=.05*Math.ceil(Math.max(this.inputProblem.simpleRouteJson.minTraceWidth,p)/.05-Mq),g=BJ([c,Math.min(c,m),Math.min(c,Math.max(this.inputProblem.simpleRouteJson.minTraceWidth,p))].map(t=\u003eMath.max(t,s.width)));for(const r of g){const u=this.measureCandidate(i,r,c,a.width,s.width);u.deficitArea\u003el.deficitArea+Mq||u.conservativeDeficitArea\u003el.conservativeDeficitArea+Mq||!this.preservesCoverage(u,l)||(\"simplification\"!==t||0!==l.nonOctilinearSegmentCount||u.pointCount\u003cl.pointCount\u0026\u0026u.length\u003cl.length-Mq)\u0026\u0026h.push({kind:t,traceIndex:e,startIndex:n,endIndex:o,layer:s.layer,points:i,width:r,padClearance:d,originalQuality:l})}}return h.slice(0,18)}beginCandidates(t,e,n=!1){this.candidates=t,this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.rollbackTraces=null,this.baseCandidateValidated=!1,this.resumePhase=e,this.candidateSetMayUseGridFallback=n,this.phase=\"evaluate-candidate\"}evaluateCurrentCandidate(){const t=this.candidates[this.candidateCursor];if(!t)return void this.finishCandidateSet(!1);if(!this.baseCandidateValidated){if(!this.candidateCollides(t,0))return this.candidateShoveCount\u003e0?void this.applyCandidate(t,0):(this.baseCandidateValidated=!0,void(this.clearanceTierCursor=0));return this.getPushableTraceIndices(t,0)\u0026\u0026this.candidateShoveCount\u003c2\u0026\u0026this.attemptedClearanceShoveCount\u003c48?void this.startClearanceShove(t,0):void this.advanceCandidate()}const e=this.clearancePaddingTiers[this.clearanceTierCursor];if(void 0===e||e\u003c=Mq)return void this.applyCandidate(t,0);if(this.attemptedCandidateCount++,!this.candidateCollides(t,e))return void this.applyCandidate(t,e);this.getPushableTraceIndices(t,e)\u0026\u0026this.candidateShoveCount\u003c2\u0026\u0026this.attemptedClearanceShoveCount\u003c48?this.startClearanceShove(t,e):(this.rollbackCandidateShoves(),this.clearanceTierCursor++,this.candidateShoveCount=0)}advanceCandidate(){this.rollbackCandidateShoves(),this.candidateCursor++,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1}candidateCollides(t,e){const n=this.traces[t.traceIndex],o=this.getTraceConnectionNames(n);for(let i=0;i\u003ct.points.length-1;i++){const r=this.getCandidateSegmentWidth(t,i);if(this.obstacleIndex.collides({start:t.points[i],end:t.points[i+1],layer:t.layer,width:r+2*e,connectionNames:o,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(n.route.length-1,t.endIndex+1)},obstacleClearance:t.padClearance}))return!0}return!1}getPushableTraceIndices(t,e){const n=this.traces[t.traceIndex],o=this.getTraceConnectionNames(n),i=new Set;for(let r=0;r\u003ct.points.length-1;r++){const s=this.getCandidateSegmentWidth(t,r),a={start:t.points[r],end:t.points[r+1],layer:t.layer,width:s+2*e,connectionNames:o,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(n.route.length-1,t.endIndex+1)},obstacleClearance:t.padClearance};if(!this.obstacleIndex.collides(a))continue;const c=this.obstacleIndex.findCollisions(a);if(0===c.length)return null;for(const e of c){if(\"trace\"!==e.kind||void 0===e.traceIndex||e.traceIndex===t.traceIndex||!this.mutableTraceIndexSet.has(e.traceIndex))return null;const n=this.traces[e.traceIndex];if(!n||this.resolveNominalTraceWidth(n)\u003e=t.width-Mq)return null;i.add(e.traceIndex)}}return i.size\u003e0\u0026\u0026i.size\u003c=2?[...i]:null}startClearanceShove(t,e){this.rollbackTraces??=structuredClone(this.traces),this.activeShovePadding=e;const n=t.width+2*e,o=t.points.slice(0,-1).map((n,o)=\u003e({start:n,end:t.points[o+1],layer:t.layer,width:this.getCandidateSegmentWidth(t,o)+2*e}));this.attemptedClearanceShoveCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem.simpleRouteJson,traces:this.traces,powerTraceIndex:t.traceIndex,nominalPowerWidth:n,pushOnlyNominalWidthsBelow:t.width,mutableTraceIndices:this.mutableTraceIndices,corridor:o,maxRerouteLength:this.maxRerouteLength},this.connectionNameResolver),this.phase=\"shove-clearance\"}getCandidateSegmentWidth(t,e){const n=this.traces[t.traceIndex],o=n.route[t.startIndex],i=n.route[t.endIndex],r=0===e\u0026\u0026DJ(o)?o.width:t.width,s=e===t.points.length-2\u0026\u0026DJ(i)?i.width:t.width;return Math.max(r,s)}stepActiveShoveSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed)if(this.pendingPushedViaRepair\u0026\u0026t instanceof oJ)this.finishPushedViaRepairSolver(t);else if(t instanceof Qq)this.finishViaGridSolver(t);else{if(this.activeSubSolver=null,this.phase=\"evaluate-candidate\",t.solved){const e=t.getOutput();if(e)return this.traces=e.traces,this.candidateShoveCount++,void this.rebuildObstacleIndex()}this.failedSubSolvers??=[],this.failedSubSolvers.push(t),this.rollbackCandidateShoves(),this.activeShovePadding\u003c=Mq?this.advanceCandidate():this.clearanceTierCursor++,this.candidateShoveCount=0}}rollbackCandidateShoves(){this.rollbackTraces\u0026\u0026(this.traces=this.rollbackTraces,this.rollbackTraces=null,this.rebuildObstacleIndex())}applyCandidate(t,e){const n=this.traces[t.traceIndex],o=n.route[t.startIndex],i=n.route[t.endIndex],r=t.points.map((e,n)=\u003e({...0===n?o:n===t.points.length-1?i:{route_type:\"wire\",layer:t.layer,width:t.width},x:e.x,y:e.y,layer:t.layer,width:0===n?o.width:n===t.points.length-1?i.width:t.width})),s=n.route.slice(t.startIndex,t.endIndex+1),a=t.originalQuality.nonOctilinearSegmentCount;if(n.route.splice(t.startIndex,t.endIndex-t.startIndex+1,...r),\"via-pair\"===t.kind){const e=s.filter(t=\u003e\"via\"===t.route_type).length;this.viaPairCountRemoved++,this.viaCountRemoved+=e,this.routeCursor=Math.max(0,t.startIndex-1)}else\"pad-clearance\"===t.kind?(this.padClearanceRerouteCount++,this.routeCursor=t.startIndex+Math.max(1,r.length-1)):(this.simplifiedPathCount++,this.normalizedSegmentCount+=a,this.routeCursor=t.startIndex+Math.max(1,r.length-1));this.committedClearanceShoveCount+=this.candidateShoveCount,e\u003eMq\u0026\u0026this.achievedExtraClearanceCount++,this.rollbackTraces=null,this.candidateShoveCount=0,this.rebuildObstacleIndex(),this.finishCandidateSet(!0)}finishCandidateSet(t){const e=this.candidates[0],n=BJ(this.candidates.filter(t=\u003et.kind===e?.kind).map(t=\u003et.width)),o=BJ(this.candidates.filter(t=\u003et.kind===e?.kind\u0026\u0026t.traceIndex===e.traceIndex\u0026\u0026t.startIndex===e.startIndex\u0026\u0026t.endIndex===e.endIndex).map(t=\u003et.padClearance));if(this.rollbackCandidateShoves(),this.candidates=[],this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1,!t\u0026\u0026this.candidateSetMayUseGridFallback\u0026\u0026e)return this.candidateSetMayUseGridFallback=!1,void this.beginViaGridAttempt(e,n,o);this.candidateSetMayUseGridFallback=!1,t||this.routeCursor++,this.phase=this.resumePhase}beginViaGridAttempt(t,e,n=[t.padClearance]){this.viaGridAttempt={kind:t.kind,traceIndex:t.traceIndex,startIndex:t.startIndex,endIndex:t.endIndex,layer:t.layer,padClearances:n,padClearanceCursor:0,originalQuality:t.originalQuality,widths:e,widthCursor:0,gridSizes:[],gridSizeCursor:0,offsetCursor:0},this.phase=\"route-via-pair\"}startNextViaGridCandidate(){const t=this.viaGridAttempt;if(!t)return void(this.phase=this.resumePhase);if(t.padClearanceCursor\u003e=t.padClearances.length)return\"pad-clearance\"===t.kind\u0026\u0026this.unresolvedPadClearanceCount++,this.viaGridAttempt=null,this.routeCursor++,void(this.phase=this.resumePhase);if(t.widthCursor\u003e=t.widths.length)return t.padClearanceCursor++,t.widthCursor=0,t.gridSizes=[],t.gridSizeCursor=0,void(t.offsetCursor=0);const e=t.widths[t.widthCursor],n=t.padClearances[t.padClearanceCursor];if(0===t.gridSizes.length\u0026\u0026(t.gridSizes=BJ([Rq(e/2,.2,.4),Rq(e/3,.15,.25)])),t.gridSizeCursor\u003e=t.gridSizes.length)return t.widthCursor++,t.gridSizes=[],t.gridSizeCursor=0,void(t.offsetCursor=0);if(t.offsetCursor\u003e=kJ.length)return t.gridSizeCursor++,void(t.offsetCursor=0);const o=this.traces[t.traceIndex],i=o.route[t.startIndex],r=o.route[t.endIndex];if(!DJ(i)||!DJ(r))return this.viaGridAttempt=null,this.routeCursor++,void(this.phase=this.resumePhase);const s=t.gridSizes[t.gridSizeCursor],a=kJ[t.offsetCursor];this.attemptedViaGridCount++,this.activeSubSolver=new Qq({start:i,end:r,layer:t.layer,traceWidth:e,gridSize:s,gridOffset:{x:a.x*s,y:a.y*s},connectionNames:this.getTraceConnectionNames(o),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(o.route.length-1,t.endIndex+1)},bounds:this.inputProblem.simpleRouteJson.bounds,obstacleClearance:n,searchPadding:Math.min(4,Math.max(2,Nq(i,r)/2,3*e)),requireOctilinear:!0})}finishViaGridSolver(t){const e=this.viaGridAttempt;if(this.activeSubSolver=null,t.solved\u0026\u0026e){const n=t.getOutput(),o=this.traces[e.traceIndex];if(n\u0026\u0026o){const t=this.resolveNominalTraceWidth(o),i=this.measureCandidate(n.points,n.traceWidth,t,o.route[e.endIndex].width,o.route[e.startIndex].width);if(0===i.nonOctilinearSegmentCount\u0026\u0026i.length\u003c=this.maxRerouteLength+Mq\u0026\u0026i.deficitArea\u003c=e.originalQuality.deficitArea+Mq\u0026\u0026i.conservativeDeficitArea\u003c=e.originalQuality.conservativeDeficitArea+Mq\u0026\u0026this.preservesCoverage(i,e.originalQuality)){const t={kind:e.kind,traceIndex:e.traceIndex,startIndex:e.startIndex,endIndex:e.endIndex,layer:e.layer,points:n.points,width:n.traceWidth,padClearance:e.padClearances[e.padClearanceCursor],originalQuality:e.originalQuality};return this.viaGridAttempt=null,void this.beginCandidates([t],this.resumePhase,!1)}}}t.failed\u0026\u0026(this.failedSubSolvers??=[],this.failedSubSolvers.push(t)),e\u0026\u0026e.offsetCursor++,this.phase=\"route-via-pair\"}measureRouteRange(t,e,n){const o=this.resolveNominalTraceWidth(t);let i=0,r=0,s=0,a=0,c=0,l=0,d=0;for(let h=e;h\u003c=n;h++){if(DJ(t.route[h])\u0026\u0026d++,h\u003e=n)continue;const e=t.route[h],u=t.route[h+1];if(!DJ(e)||!DJ(u)||e.layer!==u.layer)continue;const p=Nq(e,u);i+=p,r+=p*Math.max(0,o-e.width),e.width\u003e=o-Mq\u0026\u0026(a+=p),s+=p*Math.max(0,o-Math.min(e.width,u.width)),Math.min(e.width,u.width)\u003e=o-Mq\u0026\u0026(c+=p),l+=Gq([e,u])}return{length:i,deficitArea:r,conservativeDeficitArea:s,nominalLength:a,conservativeNominalLength:c,nonOctilinearSegmentCount:l,pointCount:d}}measureTraceLength(t){let e=0;for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];DJ(o)\u0026\u0026DJ(i)\u0026\u0026o.layer===i.layer\u0026\u0026(e+=Nq(o,i))}return e}measureCandidate(t,e,n,o=e,i=e){const r=Uq(t);let s=0,a=0,c=0,l=0;for(let r=0;r\u003ct.length-1;r++){const d=Nq(t[r],t[r+1]),h=0===r?i:e,u=r===t.length-2?o:e,p=Math.min(h,u);s+=d*Math.max(0,n-h),a+=d*Math.max(0,n-p),h\u003e=n-Mq\u0026\u0026(c+=d),p\u003e=n-Mq\u0026\u0026(l+=d)}return{length:r,deficitArea:s,conservativeDeficitArea:a,nominalLength:c,conservativeNominalLength:l,nonOctilinearSegmentCount:Gq(t),pointCount:t.length}}preservesCoverage(t,e){const n=e.length\u003c=Mq?1:e.nominalLength/e.length,o=t.length\u003c=Mq?1:t.nominalLength/t.length,i=e.length\u003c=Mq?1:e.conservativeNominalLength/e.length,r=t.length\u003c=Mq?1:t.conservativeNominalLength/t.length;return!(o+Mq\u003cn||r+Mq\u003ci)\u0026\u0026!(t.length\u003ee.length+Mq\u0026\u0026o\u003c.999999)}advanceTrace(){this.traceCursor++,this.routeCursor=0,this.rebuildObstacleIndex()}createObstacleIndex(){return new tJ(this.inputProblem.simpleRouteJson,this.traces,\"repair-vias\"===this.phase?void 0:this.traceIndices?.[this.traceCursor],[],this.connectionNameResolver)}rebuildObstacleIndex(){this.obstacleIndex=this.createObstacleIndex()}resolveNominalTraceWidth(t){const e=this.findConnectionForTrace(t);return Math.max(e?.nominalTraceWidth??e?.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.inputProblem.simpleRouteJson.minTraceWidth,this.inputProblem.simpleRouteJson.minTraceWidth)}getPadClearanceForTrace(t){const e=this.getBaseObstacleClearance();return this.resolveNominalTraceWidth(t)\u003e=.499999?Math.max(e,this.desiredPadClearance??this.resolveNominalTraceWidth(t)/2):e}getBaseObstacleClearance(){return Math.max(this.inputProblem.simpleRouteJson.defaultObstacleMargin??0,this.inputProblem.simpleRouteJson.minTraceToPadEdgeClearance??0,.1)}getCandidatePadClearance(t,e,n,o){const i=this.traces[e],r=this.getBaseObstacleClearance(),s=this.getPadClearanceForTrace(i);if(\"pad-clearance\"===t)return s;const a=\"via-pair\"===t?Math.min(s,Math.max(r,.15)):s;return this.findExistingPadClearance(e,n,o,r,a)}getImprovedPadClearanceTiers(t,e,n){const o=this.traces[t],i=this.getBaseObstacleClearance(),r=this.getPadClearanceForTrace(o),s=this.findExistingPadClearance(t,e,n,i,r),a=Math.max(.025,Math.min(.05,r/10)),c=[r];for(let t=r-a;t\u003es+a/2;t-=a)c.push(t);return BJ(c).filter(t=\u003et\u003es+Mq)}findExistingPadClearance(t,e,n,o,i){if(this.routeRangeHasPadClearanceViolation(t,e,n,o))return o;if(!this.routeRangeHasPadClearanceViolation(t,e,n,i))return i;let r=o,s=i;for(let o=0;o\u003c7;o++){const o=(r+s)/2;this.routeRangeHasPadClearanceViolation(t,e,n,o)?s=o:r=o}return Math.max(o,Number((r-.001).toFixed(6)))}routeRangeHasPadClearanceViolation(t,e,n,o){const i=this.traces[t],r=this.getTraceConnectionNames(i);for(let s=e;s\u003cn;s++){const a=i.route[s],c=i.route[s+1];if(!DJ(a)||!DJ(c)||a.layer!==c.layer)continue;if(this.obstacleIndex.findCollisions({start:a,end:c,layer:a.layer,width:Math.max(a.width,c.width),connectionNames:r,ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,e-1),end:Math.min(i.route.length-1,n+1)},obstacleClearance:o}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind))return!0}return!1}countPadClearanceViolations(t){let e=0;for(const n of this.traceIndices){const o=this.traces[n];if(!o)continue;const i=this.getTraceConnectionNames(o);for(let r=0;r\u003co.route.length-1;r++){const s=o.route[r],a=o.route[r+1];if(!DJ(s)||!DJ(a)||s.layer!==a.layer)continue;this.obstacleIndex.findCollisions({start:s,end:a,layer:s.layer,width:Math.max(s.width,a.width),connectionNames:i,ignoreTraceIndex:n,ignoreRouteRange:{start:Math.max(0,r-1),end:Math.min(o.route.length-1,r+2)},obstacleClearance:t??this.getPadClearanceForTrace(o)}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind)\u0026\u0026e++}}return e}countPadClearanceViolationsByTier(){return Object.fromEntries(LJ.map(t=\u003e[t.toFixed(2),this.countPadClearanceViolations(t)]))}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=new Set(this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t))),o=this.inputProblem.simpleRouteJson.connections.find(t=\u003ethis.connectionNameResolver.canonicalize(this.getConnectionNames(t)).some(t=\u003en.has(t)))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getConnectionNames(t){return[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))}getTraceConnectionNames(t){return[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=\u003eBoolean(t))}ensureConnectivitySafeOutput(){if(!this.connectivityFinalized){this.connectivityFinalized=!0,this.connectivityValidationCount++;try{const t=this.connectivityInvariant.validate(this.traces);if(this.connectivityValidationError??=t.validationError??null,t.safe)return void(this.finalizedMutatedTraceIndices=this.getMutatedTraceIndices());this.connectivityRegressionEndpointIds=[...new Set(t.regressions.flatMap(t=\u003et.baselineEndpointLabels))]}catch(t){this.connectivityValidationError=t instanceof Error?t.message:String(t)}this.connectivityRollbackCount++,this.connectivityRollbackMutationStats={committedClearanceShoveCount:this.committedClearanceShoveCount,viaPairCountRemoved:this.viaPairCountRemoved,viaCountRemoved:this.viaCountRemoved,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,achievedExtraClearanceCount:this.achievedExtraClearanceCount,relocatedViaCount:this.relocatedViaCount,committedPushedViaRepairCount:this.committedPushedViaRepairCount,padClearanceRerouteCount:this.padClearanceRerouteCount},this.committedClearanceShoveCount=0,this.viaPairCountRemoved=0,this.viaCountRemoved=0,this.simplifiedPathCount=0,this.normalizedSegmentCount=0,this.achievedExtraClearanceCount=0,this.relocatedViaCount=0,this.committedPushedViaRepairCount=0,this.padClearanceRerouteCount=0,this.traces=structuredClone(this.initialConnectivitySafeTraces),this.obstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,void 0,[],this.connectionNameResolver),this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.finalizedMutatedTraceIndices=this.getMutatedTraceIndices()}}getMutatedTraceIndices(){const t=Math.max(this.initialConnectivitySafeTraces.length,this.traces.length);return Array.from({length:t},(t,e)=\u003ee).filter(t=\u003eJSON.stringify(this.initialConnectivitySafeTraces[t])!==JSON.stringify(this.traces[t]))}createStats(){const t=this.candidates[this.candidateCursor],e=\"repair-vias\"===this.phase?this.viaRepairTraceIndices:this.traceIndices;return{phase:this.phase,budgetLimited:this.budgetLimited,completionReason:\"complete\"===this.phase||this.solved?this.connectivityRollbackCount\u003e0?\"connectivity_rollback\":this.budgetLimited?\"iteration_budget\":this.connectivityValidationError?\"connectivity_validation_unavailable\":\"completed\":null,resultStatus:this.connectivityRollbackCount\u003e0||this.budgetLimited||null!==this.connectivityValidationError?\"best_effort\":\"complete\",traceCursor:this.traceCursor,traceCount:e.length,traceIndex:e[this.traceCursor],routeCursor:this.routeCursor,candidateCursor:this.candidateCursor,candidateCount:this.candidates.length,candidateKind:t?.kind,candidateWidth:t?.width,candidatePointCount:t?.points.length,clearancePadding:this.clearancePaddingTiers[this.clearanceTierCursor],candidateShoveCount:this.candidateShoveCount,attemptedCandidateCount:this.attemptedCandidateCount,attemptedClearanceShoveCount:this.attemptedClearanceShoveCount,attemptedViaGridCount:this.attemptedViaGridCount,committedClearanceShoveCount:this.committedClearanceShoveCount,viaPairCountRemoved:this.viaPairCountRemoved,viaCountRemoved:this.viaCountRemoved,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,achievedExtraClearanceCount:this.achievedExtraClearanceCount,relocatedViaCount:this.relocatedViaCount,unresolvedViaCount:this.unresolvedViaCount,attemptedPushedViaRepairCount:this.attemptedPushedViaRepairCount,committedPushedViaRepairCount:this.committedPushedViaRepairCount,padClearanceRerouteCount:this.padClearanceRerouteCount,unresolvedPadClearanceCount:this.unresolvedPadClearanceCount,initialPadClearanceViolationCount:this.initialPadClearanceViolationCount,remainingPadClearanceViolationCount:this.remainingPadClearanceViolationCount,initialPadClearanceViolationCountByClearance:{...this.initialPadClearanceViolationCountByClearance},remainingPadClearanceViolationCountByClearance:{...this.remainingPadClearanceViolationCountByClearance},connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},mutatedTraceIndices:[...this.finalizedMutatedTraceIndices],spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){if(this.solved||\"complete\"===this.phase)return 1;const t=\"repair-vias\"===this.phase?this.viaRepairTraceIndices:this.traceIndices;if(0===t.length)return 1;const e=\"scan-via-pairs\"===this.resumePhase?0:.5;return Math.min(.99,e+this.traceCursor/t.length*.5)}getConstructorParams(){return[this.inputProblem]}tryFinalAcceptance(){const t=this.pushedViaRepairRollbackTraces??this.rollbackTraces;t\u0026\u0026(this.traces=t),this.activeSubSolver=null,this.rollbackTraces=null,this.pushedViaRepairRollbackTraces=null,this.pendingPushedViaRepair=null,this.alternatePushedViaRepairs=[],this.viaGridAttempt=null,this.candidates=[],this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1,this.candidateSetMayUseGridFallback=!1,this.ensureConnectivitySafeOutput(),this.obstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,void 0,[],this.connectionNameResolver),this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.budgetLimited=!0,this.phase=\"complete\",this.solved=!0,this.progress=1,this.stats=this.createStats()}getOutput(){return structuredClone(this.solved?this.traces:this.initialConnectivitySafeTraces)}visualize(){const t=[],e=[],n=this.candidates[this.candidateCursor];for(let n=0;n\u003cthis.traces.length;n++){const o=this.traces[n];for(const t of o.route)\"via\"===t.route_type\u0026\u0026e.push({center:t,radius:(t.via_diameter??.6)/2,fill:\"#d4a017\",stroke:\"#7a5700\"});for(let e=0;e\u003co.route.length-1;e++){const n=o.route[e],i=o.route[e+1];DJ(n)\u0026\u0026DJ(i)\u0026\u0026n.layer===i.layer\u0026\u0026t.push({points:[n,i],strokeColor:\"bottom\"===n.layer?\"#376fc4\":\"#777\",strokeWidth:n.width})}}if(n)for(let e=0;e\u003cn.points.length-1;e++)t.push({points:[n.points[e],n.points[e+1]],strokeColor:\"#ff7400\",strokeWidth:n.width+2*(this.clearancePaddingTiers[this.clearanceTierCursor]??0)});return{coordinateSystem:\"cartesian\",title:`Power trace cleanup: ${this.phase}`,lines:t,points:[],circles:e,rects:[],texts:[]}}},$J=t=\u003e\"wire\"===t?.route_type,YJ=class extends Sq{inputProblem;traces;obstacleIndex;traceCursor=0;routeCursor=0;repairedSegmentCount=0;repairedPadNeckSegmentCount=0;unresolvedSegmentCount=0;totalWidthReduction=0;budgetLimited=!1;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;connectionNameResolver;nominalWidthByTraceId=new Map;connectivityInvariant;initialConnectivitySafeTraces;minimumTraceWidth;traceIndices;connectivityFinalized=!1;constructor(t){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.initialConnectivitySafeTraces=structuredClone(t.traces),this.connectivityInvariant=new OJ(this.inputProblem.simpleRouteJson,this.initialConnectivitySafeTraces),this.connectionNameResolver=new Pq(t.simpleRouteJson,this.traces),this.minimumTraceWidth=t.simpleRouteJson.minTraceWidth;const e=t.traceIndices?[...new Set(t.traceIndices)]:this.traces.map((t,e)=\u003ee);for(const t of e)if(!Number.isInteger(t)||t\u003c0||t\u003e=this.traces.length)throw new RangeError(`Invalid clearance-repair trace index: ${t}`);this.traceIndices=e,this.obstacleIndex=this.createConservativeObstacleIndex();const n=this.traceIndices.reduce((t,e)=\u003et+Math.max(0,this.traces[e].route.length-1),0);this.MAX_ITERATIONS=Math.max(10,8*n+2*this.traceIndices.length),this.stats=this.createStats()}getSolverName(){return\"PowerTraceClearanceRepairSolver\"}_step(){const t=this.traceIndices[this.traceCursor],e=void 0===t?void 0:this.traces[t];if(!e)return this.ensureConnectivitySafeOutput(),this.solved=!0,void(this.stats=this.createStats());if(this.routeCursor\u003e=e.route.length-1)return this.traceCursor++,this.routeCursor=0,void(this.stats=this.createStats());const n=this.routeCursor++,o=e.route[n],i=e.route[n+1];if(!$J(o)||!$J(i)||o.layer!==i.layer)return void(this.stats=this.createStats());const r=Math.max(o.width,i.width),s={start:o,end:i,layer:o.layer,width:r,connectionNames:this.getTraceConnectionNames(e),ignoreTraceIndex:t,ignoreRouteRange:{start:n,end:n+1}};if(this.repairConnectedPadNeck(e,n,s))return void(this.stats=this.createStats());if(!this.segmentHasForeignTraceCollision(n,r))return void(this.stats=this.createStats());if(this.segmentHasForeignTraceCollision(n,this.minimumTraceWidth))return this.unresolvedSegmentCount++,void(this.stats=this.createStats());let a=this.minimumTraceWidth,c=r;for(let t=0;t\u003c10;t++){const t=(a+c)/2;this.segmentHasForeignTraceCollision(n,t)?c=t:a=t}const l=r\u003e=.5?.025:.0125,d=Math.max(this.minimumTraceWidth,Math.floor((a+Mq)/l)*l),h=this.segmentHasForeignTraceCollision(n,d)?a:d,u=o.width,p=i.width;o.width=Math.min(o.width,h),i.width=Math.min(i.width,h);const m=u-o.width+(p-i.width);if(m\u003c=Mq)return this.unresolvedSegmentCount++,void(this.stats=this.createStats());this.repairedSegmentCount++,this.totalWidthReduction+=m,this.obstacleIndex=this.createConservativeObstacleIndex(),this.routeCursor=Math.max(0,n-1),this.stats=this.createStats()}repairConnectedPadNeck(t,e,n){const o=t.route[e],i=t.route[e+1];if(!$J(o)||!$J(i))return!1;let r=this.obstacleIndex.getConnectedPadWidthLimitAtPoint(n,o),s=this.obstacleIndex.getConnectedPadWidthLimitAtPoint(n,i);0===e\u0026\u0026(r=this.getSmallerLimit(r,this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(n,o))),e+1===t.route.length-1\u0026\u0026(s=this.getSmallerLimit(s,this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(n,i)));const a=r,c=s;if((null===a||o.width\u003c=a+Mq)\u0026\u0026(null===c||i.width\u003c=c+Mq))return!1;const l=o.width,d=i.width;if(null!==a\u0026\u0026(o.width=Math.min(o.width,a)),null!==c\u0026\u0026(i.width=Math.min(i.width,c)),null!==a\u0026\u0026null===c)this.insertPadBoundaryTransition(t,e,n,\"start\",o.width,d);else if(null===a\u0026\u0026null!==c)this.insertPadBoundaryTransition(t,e,n,\"end\",i.width,l);else if(null!==a\u0026\u0026null!==c){const r=this.obstacleIndex.getConnectedPadBoundaryPoint(n,\"start\"),s=this.obstacleIndex.getConnectedPadBoundaryPoint(n,\"end\");r\u0026\u0026s\u0026\u0026(this.insertPadBoundaryTransition(t,e,n,\"start\",o.width,d),this.insertPadBoundaryTransition(t,e+2,n,\"end\",i.width,l))}return this.totalWidthReduction+=l-o.width+(d-i.width),this.repairedPadNeckSegmentCount++,this.obstacleIndex=this.createConservativeObstacleIndex(),this.routeCursor=Math.max(0,e-1),!0}getSmallerLimit(t,e){return null===t?e:null===e?t:Math.min(t,e)}insertPadBoundaryTransition(t,e,n,o,i,r){const s=this.obstacleIndex.getConnectedPadBoundaryPoint(n,o);if(!s)return;const a=\"start\"===o?n.start:n.end,c=\"start\"===o?n.end:n.start,l=Math.hypot(c.x-a.x,c.y-a.y);if(l\u003c=1e-9)return;const d=Math.min(1e-6,l/4),h=(c.x-a.x)/l,u=(c.y-a.y)/l,p={route_type:\"wire\",x:s.x-h*d,y:s.y-u*d,width:i,layer:n.layer},m={...p,x:s.x+h*d,y:s.y+u*d,width:r},g=\"start\"===o?t.route[e+1]:t.route[e],f=\"start\"===o?t.route[e+2]:t.route[e-1];if($J(g)\u0026\u0026\"via\"===f?.route_type){const e=this.resolveNominalTraceWidth(t);this.obstacleIndex.collides({...n,start:g,end:m,width:e})||(g.width=Math.max(g.width,e),m.width=g.width)}t.route.splice(e+1,0,...\"start\"===o?[p,m]:[m,p])}resolveNominalTraceWidth(t){const e=this.nominalWidthByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e;const n=new Set(this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t))),o=this.inputProblem.simpleRouteJson.connections.find(t=\u003ethis.connectionNameResolver.canonicalize([t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))).some(t=\u003en.has(t))),i=Math.max(o?.nominalTraceWidth??o?.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.minimumTraceWidth,this.minimumTraceWidth);return this.nominalWidthByTraceId.set(t.pcb_trace_id,i),i}segmentHasForeignTraceCollision(t,e){const n=this.traceIndices[this.traceCursor],o=void 0===n?void 0:this.traces[n],i=o?.route[t],r=o?.route[t+1];return!!(o\u0026\u0026$J(i)\u0026\u0026$J(r)\u0026\u0026i.layer===r.layer)\u0026\u0026this.obstacleIndex.findCollisions({start:i,end:r,layer:i.layer,width:e,connectionNames:this.getTraceConnectionNames(o),ignoreTraceIndex:n,ignoreRouteRange:{start:t,end:t+1}}).some(t=\u003e\"trace\"===t.kind\u0026\u0026void 0!==t.traceIndex\u0026\u0026t.traceIndex!==n)}createConservativeObstacleIndex(){const t=structuredClone(this.traces);for(const e of t)for(let t=0;t\u003ce.route.length-1;t++){const n=e.route[t],o=e.route[t+1];$J(n)\u0026\u0026$J(o)\u0026\u0026n.layer===o.layer\u0026\u0026(n.width=Math.max(n.width,o.width))}return new tJ(this.inputProblem.simpleRouteJson,t,void 0,[],this.connectionNameResolver)}getTraceConnectionNames(t){return[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=\u003eBoolean(t))}ensureConnectivitySafeOutput(){if(!this.connectivityFinalized){this.connectivityFinalized=!0,this.connectivityValidationCount++;try{const t=this.connectivityInvariant.validate(this.traces);if(this.connectivityValidationError??=t.validationError??null,t.safe)return;this.connectivityRegressionEndpointIds=[...new Set(t.regressions.flatMap(t=\u003et.baselineEndpointLabels))]}catch(t){this.connectivityValidationError=t instanceof Error?t.message:String(t)}this.connectivityRollbackCount++,this.connectivityRollbackMutationStats={repairedSegmentCount:this.repairedSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,totalWidthReduction:this.totalWidthReduction},this.repairedSegmentCount=0,this.repairedPadNeckSegmentCount=0,this.totalWidthReduction=0,this.traces=structuredClone(this.initialConnectivitySafeTraces),this.obstacleIndex=this.createConservativeObstacleIndex()}}createStats(){return{phase:this.solved?\"complete\":\"repair-trace-clearance\",budgetLimited:this.budgetLimited,completionReason:this.solved?this.connectivityRollbackCount\u003e0?\"connectivity_rollback\":this.budgetLimited?\"iteration_budget\":this.connectivityValidationError?\"connectivity_validation_unavailable\":\"completed\":null,resultStatus:this.connectivityRollbackCount\u003e0||this.budgetLimited||null!==this.connectivityValidationError?\"best_effort\":\"complete\",traceCursor:this.traceCursor,traceCount:this.traceIndices.length,traceIndex:this.traceIndices[this.traceCursor],routeCursor:this.routeCursor,repairedSegmentCount:this.repairedSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,unresolvedSegmentCount:this.unresolvedSegmentCount,totalWidthReduction:this.totalWidthReduction,connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){return this.solved||0===this.traceIndices.length?1:Math.min(.99,this.traceCursor/this.traceIndices.length)}tryFinalAcceptance(){this.ensureConnectivitySafeOutput(),this.budgetLimited=!0,this.solved=!0,this.progress=1,this.stats=this.createStats()}getConstructorParams(){return[this.inputProblem]}getOutput(){return structuredClone(this.solved?this.traces:this.initialConnectivitySafeTraces)}visualize(){const t=[];for(let e=0;e\u003cthis.traces.length;e++){const n=this.traces[e];for(let o=0;o\u003cn.route.length-1;o++){const i=n.route[o],r=n.route[o+1];$J(i)\u0026\u0026$J(r)\u0026\u0026i.layer===r.layer\u0026\u0026t.push({points:[i,r],strokeColor:e===this.traceIndices[this.traceCursor]\u0026\u0026o===this.routeCursor?\"#ff7400\":\"bottom\"===i.layer?\"#376fc4\":\"#777\",strokeWidth:Math.max(i.width,r.width)})}}return{coordinateSystem:\"cartesian\",title:\"Power trace direction-independent clearance repair\",lines:t,points:[],circles:[],rects:[],texts:[]}}},XJ=[{x:0,y:0},{x:.5,y:0},{x:0,y:.5},{x:.5,y:.5}],VJ=[{offset:{x:0,y:0},strictNecking:!0},{offset:{x:.5,y:.5},strictNecking:!0},{offset:{x:0,y:0},strictNecking:!1},{offset:{x:.5,y:.5},strictNecking:!1}],WJ=t=\u003e[...new Set(t.map(t=\u003eNumber(t.toFixed(6))))].sort((t,e)=\u003ee-t),HJ=t=\u003e\"wire\"===t?.route_type,GJ=class extends Sq{inputProblem;options;traces;obstacleIndex;connectionNameResolver;connectionByTraceId=new Map;connectivityInvariant;lastConnectivitySafeTraces;traceOrder;selectedOwnedTraceIndices;selectedCleanupTraceIndices;selectedViaRepairTraceIndices;mutableBlockerTraceIndices;immutableTraceIndices;initialImmutableTraceSignatures=new Map;traceOrderCursor=-1;maxPassCount=4;previousWidthDeficit=0;passIndex=0;completedPassCount=0;lastNormalizedWidthDeficitGain=0;normalizedWidthDeficitGainByPass=[];plateauReached=!1;phase=\"scan-trace\";traceIndex=-1;routeSegmentIndex=0;nominalTraceWidth=0;currentIntervals=[];intervalCursor=0;candidateWidths=[];widthCursor=0;gridResolutions=[];resolutionCursor=0;offsetCursor=0;keptTraceCount=0;recreatedTraceCount=0;expandedSegmentCount=0;intermediateExpandedSegmentCount=0;pathWidthUpgradeCount=0;inPlaceWidthProbeCount=0;reroutedSegmentCount=0;unresolvedSegmentCount=0;attemptedGridCount=0;attemptedLayerGridCount=0;attemptedInflationCount=0;pushedTraceCount=0;elasticPushedTraceCount=0;layerReroutedTraceCount=0;insertedViaCount=0;neckedLayerSegmentCount=0;removedViaPairCount=0;removedViaCount=0;simplifiedPathCount=0;normalizedSegmentCount=0;cleanupClearanceShoveCount=0;relocatedViaCount=0;unresolvedViaCount=0;initialImmutableViaViolationCount=0;remainingImmutableViaViolationCount=0;initialImmutableViaViolationPairCount=0;remainingImmutableViaViolationPairCount=0;immutableTraceMutationIds=[];lastSafeImmutableViaViolationSignatures=new Set;immutableViaViolationRollbackCount=0;attemptedImmutableViaViolationCount=null;attemptedImmutableViaViolationPairCount=null;immutableViaViolationRegressionIds=[];padClearanceRerouteCount=0;unresolvedPadClearanceCount=0;repairedTraceClearanceSegmentCount=0;repairedPadNeckSegmentCount=0;unresolvedTraceClearanceSegmentCount=0;sameNetContactRejectionCount=0;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRollbackPhases=[];immutableSafetyRollbackCount=0;immutableSafetyRollbackPhases=[];connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;immutableSafetyRollbackMutationStats=null;discardedExpansionMutationStats=null;initialPadClearanceViolationCount=0;remainingPadClearanceViolationCount=0;initialPadClearanceViolationCountByClearance={};remainingPadClearanceViolationCountByClearance={};budgetLimitedExpansion=!1;finalAcceptanceUsed=!1;cleanupCompleted=!1;clearanceRepairCompleted=!1;cleanupBestEffortAccepted=!1;clearanceRepairBestEffortAccepted=!1;cleanupIterationBudget=0;clearanceRepairIterationBudget=0;expansionPushedTraceIndices=new Set;cleanupMutatedTraceIndices=[];failedSubSolverCount=0;inflationAttemptsBySegment=new Map;layerAttemptCountByTrace=new Map;layerRerouteCountByTrace=new Map;activeInflationKey=null;activeInflationWidth=null;layerAttempt=null;pendingLayerOutput=null;pendingLayerPushCount=0;constructor(t,e={}){super(),this.inputProblem=structuredClone(t),this.options=structuredClone(e),this.traces=structuredClone(t.traces??[]),this.connectionNameResolver=new Pq(this.inputProblem,this.traces),this.lastConnectivitySafeTraces=structuredClone(this.traces),this.connectivityInvariant=new OJ(this.inputProblem,this.lastConnectivitySafeTraces);const n=e.onlyConnectionNames?new Set(this.connectionNameResolver.canonicalize([...e.onlyConnectionNames])):null,o=this.traces.flatMap((t,e)=\u003e{if(!n)return[e];return this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t)).some(t=\u003en.has(t))?[e]:[]}),i=new Map(o.map(t=\u003e[t,this.getInitialTracePriority(this.traces[t])]));this.traceOrder=o.sort((t,e)=\u003ei.get(e)-i.get(t)||t-e),this.selectedOwnedTraceIndices=this.traceOrder.filter(t=\u003ethis.findConnectionForTrace(this.traces[t])),this.selectedCleanupTraceIndices=[...this.selectedOwnedTraceIndices],this.selectedViaRepairTraceIndices=[...this.selectedOwnedTraceIndices],this.mutableBlockerTraceIndices=this.traces.flatMap((t,e)=\u003ethis.findConnectionForTrace(t)?[e]:[]);const r=new Set(this.mutableBlockerTraceIndices);this.immutableTraceIndices=this.traces.flatMap((t,e)=\u003er.has(e)?[]:(this.initialImmutableTraceSignatures.set(e,JSON.stringify(t)),[e])),this.previousWidthDeficit=this.calculateWidthDeficit().deficit,this.obstacleIndex=new tJ(this.inputProblem,this.traces,this.traceIndex\u003e=0?this.traceIndex:void 0,[],this.connectionNameResolver),this.lastSafeImmutableViaViolationSignatures=this.getImmutableViaViolationSignatures(this.traces),this.initialImmutableViaViolationCount=this.countViolatingImmutableVias(this.lastSafeImmutableViaViolationSignatures),this.remainingImmutableViaViolationCount=this.initialImmutableViaViolationCount,this.initialImmutableViaViolationPairCount=this.lastSafeImmutableViaViolationSignatures.size,this.remainingImmutableViaViolationPairCount=this.initialImmutableViaViolationPairCount,this.activeSubSolver=null,this.MAX_ITERATIONS=8e6,this.stats=this.createStats()}getSolverName(){return\"PowerTraceExpanderSolver\"}_step(){if(this.shouldStartBudgetFinalization())return this.startBudgetFinalization(),void(this.stats=this.createStats());if(this.activeSubSolver)return this.stepActiveGridSolver(),void(this.stats=this.createStats());switch(this.phase){case\"scan-trace\":this.scanNextTrace();break;case\"evaluate-segment\":this.evaluateNextSegment();break;case\"try-trace-inflation\":case\"cleanup\":case\"repair-trace-clearance\":break;case\"try-layer-candidate\":this.startNextLayerCandidate();break;case\"try-grid-candidate\":this.startNextGridCandidate();break;case\"complete\":this.acceptConnectivityCheckpoint(this.traces,\"final\"),this.solved=!0}this.stats=this.createStats()}scanNextTrace(){if(this.traceOrderCursor++,this.routeSegmentIndex=0,this.traceOrderCursor\u003e=this.traceOrder.length)return void this.finishOrStartNextPass();this.traceIndex=this.traceOrder[this.traceOrderCursor];const t=this.traces[this.traceIndex];this.findConnectionForTrace(t)?(this.nominalTraceWidth=this.resolveNominalTraceWidth(t),this.traceMeetsNominalWidth(t,this.nominalTraceWidth)?this.keptTraceCount++:(this.rebuildObstacleIndex(),t.route=function(t,e){if(t.length\u003c2)return t.map(t=\u003e({...t}));const n=[];for(let o=0;o\u003ct.length-1;o++){const i=t[o],r=t[o+1];if(n.push({...i}),\"wire\"!==i.route_type||\"wire\"!==r.route_type||i.layer!==r.layer||i.width\u003e=e-Mq)continue;const s=Nq(i,r),a=Math.max(1,Math.ceil(s/e));for(let t=1;t\u003ca;t++){const e=t/a;n.push({route_type:\"wire\",x:i.x+(r.x-i.x)*e,y:i.y+(r.y-i.y)*e,width:i.width,layer:i.layer})}}return n.push({...t[t.length-1]}),n}(t.route,this.nominalTraceWidth),this.recreatedTraceCount++,this.phase=\"evaluate-segment\")):this.keptTraceCount++}finishOrStartNextPass(){const{deficit:t,nominalArea:e}=this.calculateWidthDeficit(),n=this.previousWidthDeficit-t;if(this.lastNormalizedWidthDeficitGain=e\u003c=Mq?0:n/e,this.normalizedWidthDeficitGainByPass.push(this.lastNormalizedWidthDeficitGain),this.plateauReached=this.lastNormalizedWidthDeficitGain\u003c.001,this.completedPassCount=this.passIndex+1,this.passIndex+1\u003cthis.maxPassCount\u0026\u0026this.lastNormalizedWidthDeficitGain\u003e=.001)return this.previousWidthDeficit=t,this.passIndex++,this.traceOrderCursor=-1,this.traceIndex=-1,this.routeSegmentIndex=0,this.inflationAttemptsBySegment.clear(),void(this.phase=\"scan-trace\");this.startCleanup()}startCleanup(){this.acceptConnectivityCheckpoint(this.traces,\"expansion\"),this.traceIndex=this.traces.length,this.phase=\"cleanup\";const t=new jJ({simpleRouteJson:this.inputProblem,traces:this.traces,traceIndices:this.selectedCleanupTraceIndices,viaRepairTraceIndices:this.selectedViaRepairTraceIndices,mutableTraceIndices:this.mutableBlockerTraceIndices,maxRerouteLength:10,desiredPadClearance:this.options.powerTraceToPadClearance}),e=this.getRemainingParentIterationsAfterCurrentStep(),n=0===e?0:Math.max(1,Math.floor(.75*e));t.MAX_ITERATIONS=Math.min(t.MAX_ITERATIONS,n),this.cleanupIterationBudget=t.MAX_ITERATIONS,this.activeSubSolver=t}shouldStartBudgetFinalization(){return!this.budgetLimitedExpansion\u0026\u0026(\"cleanup\"!==this.phase\u0026\u0026\"repair-trace-clearance\"!==this.phase\u0026\u0026\"complete\"!==this.phase\u0026\u0026this.iterations\u003e=this.getExpansionIterationBudget())}getFinalizationIterationReserve(){return Math.min(Math.max(0,this.MAX_ITERATIONS-1),Math.max(1,Math.floor(.125*this.MAX_ITERATIONS)))}getExpansionIterationBudget(){return Math.max(1,this.MAX_ITERATIONS-this.getFinalizationIterationReserve())}startBudgetFinalization(){this.budgetLimitedExpansion=!0,this.activeSubSolver=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.activeInflationKey=null,this.activeInflationWidth=null,this.layerAttempt=null,this.discardInFlightExpansion(),this.startCleanup()}discardInFlightExpansion(){this.discardedExpansionMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}rollbackConnectivityRegressedExpansion(){this.connectivityRollbackMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}rollbackImmutableUnsafeExpansion(){this.immutableSafetyRollbackMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}captureAndResetExpansionMutationStats(){const t={recreatedTraceCount:this.recreatedTraceCount,expandedSegmentCount:this.expandedSegmentCount,intermediateExpandedSegmentCount:this.intermediateExpandedSegmentCount,pathWidthUpgradeCount:this.pathWidthUpgradeCount,reroutedSegmentCount:this.reroutedSegmentCount,pushedTraceCount:this.pushedTraceCount,elasticPushedTraceCount:this.elasticPushedTraceCount,layerReroutedTraceCount:this.layerReroutedTraceCount,insertedViaCount:this.insertedViaCount,neckedLayerSegmentCount:this.neckedLayerSegmentCount};return this.recreatedTraceCount=0,this.expandedSegmentCount=0,this.intermediateExpandedSegmentCount=0,this.pathWidthUpgradeCount=0,this.reroutedSegmentCount=0,this.pushedTraceCount=0,this.elasticPushedTraceCount=0,this.layerReroutedTraceCount=0,this.insertedViaCount=0,this.neckedLayerSegmentCount=0,this.expansionPushedTraceIndices.clear(),t}restoreLastConnectivitySafeTraces(){this.traces=structuredClone(this.lastConnectivitySafeTraces),this.rebuildObstacleIndex()}getRemainingParentIterationsAfterCurrentStep(){return Math.max(0,this.MAX_ITERATIONS-this.iterations-1)}calculateWidthDeficit(){let t=0,e=0;for(const n of this.traceOrder){const o=this.traces[n];if(!this.findConnectionForTrace(o))continue;const i=this.resolveNominalTraceWidth(o);for(let n=0;n\u003co.route.length-1;n++){const r=o.route[n],s=o.route[n+1];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)continue;const a=Nq(r,s),c=r.width;e+=a*i,t+=a*Math.max(0,i-c)}}return{deficit:t,nominalArea:e}}getInitialTracePriority(t){const e=this.resolveNominalTraceWidth(t);let n=0;for(let o=0;o\u003ct.route.length-1;o++){const i=t.route[o],r=t.route[o+1];HJ(i)\u0026\u0026HJ(r)\u0026\u0026i.layer===r.layer\u0026\u0026(n+=Nq(i,r)*Math.max(0,e-Math.min(i.width,r.width)))}return e*n}evaluateNextSegment(){const t=this.traces[this.traceIndex];if(!t)return void(this.phase=\"scan-trace\");const e=this.findNextUnderWidthSegment(t,this.routeSegmentIndex,this.nominalTraceWidth);if(-1===e)return void(this.phase=\"scan-trace\");this.routeSegmentIndex=e;const n=t.route[e],o=t.route[e+1];if(!HJ(n)||!HJ(o))return void this.routeSegmentIndex++;const i=this.getTraceConnectionNames(t),r=Math.min(n.width,o.width),s=this.findMaximumSafeInPlaceWidth(t,e,i);if(s\u003er+Mq){if(n.width=Math.max(n.width,s),o.width=Math.max(o.width,s),s\u003e=this.nominalTraceWidth-Mq)return this.expandedSegmentCount++,void this.routeSegmentIndex++;this.intermediateExpandedSegmentCount++}this.startTraceInflation(t,e)||this.prepareLayerRouteAttempt(t,e)||this.prepareRegularGridCandidates(t,e)}prepareRegularGridCandidates(t,e){if(this.currentIntervals=this.getExponentialIntervalCandidates(t,e,this.nominalTraceWidth),this.intervalCursor=0,this.candidateWidths=this.getCandidateWidths(this.nominalTraceWidth),this.widthCursor=0,this.gridResolutions=[],this.resolutionCursor=0,this.offsetCursor=0,0===this.currentIntervals.length)return this.unresolvedSegmentCount++,void this.routeSegmentIndex++;this.phase=\"try-grid-candidate\"}prepareLayerRouteAttempt(t,e){if(this.nominalTraceWidth\u003c.499999)return!1;const n=!1!==this.options.allowNewVias\u0026\u0026this.inputProblem.layerCount\u003e=2,o=n?2:this.maxPassCount,i=this.layerAttemptCountByTrace.get(this.traceIndex)??0,r=this.layerRerouteCountByTrace.get(this.traceIndex)??0;if(r\u003e=o||i\u003e=o||i\u003ethis.passIndex||i\u003e0\u0026\u00260===r)return!1;const s=t.route[e],a=t.route[e+1];if(!HJ(s)||!HJ(a)||Math.min(s.width,a.width)\u003e=.5*this.nominalTraceWidth-Mq)return!1;const c=this.getExponentialIntervalCandidates(t,e,this.nominalTraceWidth).filter(e=\u003ethis.intervalSupportsLayerRouting(t,e)).sort((e,n)=\u003en.endIndex-e.endIndex||e.startIndex-n.startIndex||this.getRouteIntervalLength(t,n.startIndex,n.endIndex)-this.getRouteIntervalLength(t,e.startIndex,e.endIndex))[0];if(!c)return!1;const l=this.getRouteQuality(t.route.slice(c.startIndex,c.endIndex+1));if(l.deficitArea\u003cthis.nominalTraceWidth)return!1;if(i\u003e0\u0026\u0026l.deficitArea/Math.max(l.length,Mq)\u003c.25)return!1;const d=t.route[c.startIndex],h=t.route[c.endIndex],u=this.getTraceConnectionNames(t),p=n?this.getEndpointLayers(d,u):[d.layer],m=n?this.getEndpointLayers(h,u):[h.layer],g=Math.min(this.nominalTraceWidth,Math.max(d.width,this.findMaximumSafeInPlaceWidth(t,c.startIndex,u))),f=Math.min(this.nominalTraceWidth,Math.max(h.width,this.findMaximumSafeInPlaceWidth(t,c.endIndex-1,u))),y=this.getSoftTraceIndices(this.nominalTraceWidth);return this.layerAttemptCountByTrace.set(this.traceIndex,i+1),this.layerAttempt={interval:c,minViaCount:n?1:0,maxViaCount:n?2:0,candidateWidths:[this.nominalTraceWidth],widthCursor:0,gridResolutions:[Rq(this.nominalTraceWidth/4,.2,.3)],resolutionCursor:0,offsetCursor:0,startLayers:p,endLayers:m,startNeckWidth:g,endNeckWidth:f,softTraceIndices:y},this.phase=\"try-layer-candidate\",!0}intervalSupportsLayerRouting(t,e){if(e.startIndex\u003e=e.endIndex)return!1;for(let n=e.startIndex;n\u003c=e.endIndex;n++){const e=t.route[n];if(!HJ(e))return!1}const n=t.route[e.startIndex],o=t.route[e.endIndex];return n.layer===o.layer}getEndpointLayers(t,e){return[...new Set([t.layer,...this.obstacleIndex.getConnectedLayersAtPoint({x:t.x,y:t.y},e)])].filter(t=\u003ethis.obstacleIndex.boardLayers.includes(t))}getSoftTraceIndices(t){const e=[];for(let n=0;n\u003cthis.traces.length;n++){if(n===this.traceIndex)continue;const o=this.traces[n],i=this.findConnectionForTrace(o);if(!i)continue;Math.max(i.nominalTraceWidth??i.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth,this.inputProblem.minTraceWidth)\u003ct-Mq\u0026\u0026e.push(n)}return e}startNextLayerCandidate(){const t=this.layerAttempt,e=this.traces[this.traceIndex];if(!t||!e)return this.layerAttempt=null,void(this.phase=\"evaluate-segment\");if(t.widthCursor\u003e=t.candidateWidths.length){const t=this.routeSegmentIndex;return this.layerAttempt=null,void this.prepareRegularGridCandidates(e,t)}const n=t.candidateWidths[t.widthCursor];if(0===t.gridResolutions.length\u0026\u0026(t.gridResolutions=this.getGridResolutions(n)),t.resolutionCursor\u003e=t.gridResolutions.length)return t.widthCursor++,t.gridResolutions=[],t.resolutionCursor=0,void(t.offsetCursor=0);if(t.offsetCursor\u003e=VJ.length)return t.resolutionCursor++,void(t.offsetCursor=0);const o=e.route[t.interval.startIndex],i=e.route[t.interval.endIndex];if(!HJ(o)||!HJ(i))return this.layerAttempt=null,void this.prepareRegularGridCandidates(e,this.routeSegmentIndex);const r=t.gridResolutions[t.resolutionCursor],s=VJ[t.offsetCursor],a=s.offset,c=Math.min(t.startNeckWidth,t.endNeckWidth),l=this.inputProblem.min_via_hole_diameter??this.inputProblem.minViaHoleDiameter??.3,d=Math.max(l,this.inputProblem.min_via_pad_diameter??this.inputProblem.minViaPadDiameter??this.inputProblem.minViaDiameter??.6),h=Math.max(this.inputProblem.minTraceWidth,Math.min(s.strictNecking?t.startNeckWidth:c,n)),u=Math.max(this.inputProblem.minTraceWidth,Math.min(s.strictNecking?t.endNeckWidth:c,n)),p=Rq(3*this.nominalTraceWidth,1.5,3);t.maxViaCount\u003e0?this.attemptedLayerGridCount++:this.attemptedGridCount++,this.activeSubSolver=new Yq({start:o,end:i,originalStartLayer:o.layer,originalEndLayer:i.layer,startLayers:t.startLayers,endLayers:t.endLayers,layers:this.obstacleIndex.boardLayers,traceWidth:n,startNeckWidth:h,endNeckWidth:u,maxStartNeckLength:p,maxEndNeckLength:p,neckPenaltyExponent:s.strictNecking?2:1,viaDiameter:d,viaHoleDiameter:l,minViaCount:t.minViaCount,maxViaCount:t.maxViaCount,viaCost:Math.max(1,2*this.nominalTraceWidth),gridSize:r,gridOffset:{x:a.x*r,y:a.y*r},connectionNames:this.getTraceConnectionNames(e),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,t.interval.startIndex-1),end:Math.min(e.route.length-1,t.interval.endIndex+1)},softTraceIndices:t.softTraceIndices,fixedVias:this.getFixedViasOutsideInterval(e,t.interval),bounds:this.inputProblem.bounds,obstacleClearance:this.getDesiredPadClearance(n),searchPadding:Math.min(5,Math.max(2.5,Nq(o,i)/2,4*n))})}startNextGridCandidate(){const t=this.traces[this.traceIndex];if(!t)return void(this.phase=\"scan-trace\");if(this.widthCursor\u003e=this.candidateWidths.length)return this.unresolvedSegmentCount++,this.routeSegmentIndex++,void(this.phase=\"evaluate-segment\");if(this.intervalCursor\u003e=this.currentIntervals.length)return this.widthCursor++,this.intervalCursor=0,this.gridResolutions=[],this.resolutionCursor=0,void(this.offsetCursor=0);const e=this.candidateWidths[this.widthCursor],n=t.route[this.routeSegmentIndex],o=t.route[this.routeSegmentIndex+1];if(HJ(n)\u0026\u0026HJ(o)\u0026\u0026e\u003c=Math.min(n.width,o.width)+Mq)return void(this.widthCursor=this.candidateWidths.length);if(0===this.gridResolutions.length\u0026\u0026(this.gridResolutions=this.getGridResolutions(e)),this.resolutionCursor\u003e=this.gridResolutions.length)return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);if(this.offsetCursor\u003e=XJ.length)return this.resolutionCursor++,void(this.offsetCursor=0);const i=this.currentIntervals[this.intervalCursor],r=t.route[i.startIndex],s=t.route[i.endIndex];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);if(this.endpointCollides(t,i,r,e)||this.endpointCollides(t,i,s,e))return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);const a=this.gridResolutions[this.resolutionCursor],c=XJ[this.offsetCursor],l={x:c.x*a,y:c.y*a};this.attemptedGridCount++,this.activeSubSolver=new Qq({start:r,end:s,layer:r.layer,traceWidth:e,gridSize:a,gridOffset:l,connectionNames:this.getTraceConnectionNames(t),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,i.startIndex-1),end:Math.min(t.route.length-1,i.endIndex+1)},bounds:this.inputProblem.bounds,obstacleClearance:this.getDesiredPadClearance(e),searchPadding:Math.min(5,Math.max(1.5,Nq(r,s)/2,3*e))})}endpointCollides(t,e,n,o){return this.obstacleIndex.collides({start:n,end:n,layer:n.layer,width:o,connectionNames:this.getTraceConnectionNames(t),ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,e.startIndex-1),end:Math.min(t.route.length-1,e.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(o)})}stepActiveGridSolver(){if(this.activeSubSolver instanceof YJ)return void this.stepActiveTraceClearanceRepairSolver();if(this.activeSubSolver instanceof jJ)return void this.stepActiveCleanupSolver();if(this.activeSubSolver instanceof oJ)return void this.stepActiveInflationSolver();if(this.activeSubSolver instanceof Yq)return void this.stepActiveLayerSolver();const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e){const t=this.gridRouteReplacementCollides(e)||this.gridRouteBoundaryCollides(e);if(!t\u0026\u0026this.gridRoutePreservesSameNetContacts(e))return this.applyGridRoute(this.maximizeGridRouteWidth(e)),void(this.activeSubSolver=null);t||this.sameNetContactRejectionCount++}}this.retainFailedSubSolver(t),this.activeSubSolver=null,this.offsetCursor++}}stepActiveCleanupSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved)return this.adoptCleanupOutput(t),this.activeSubSolver=null,void this.startTraceClearanceRepair();this.retainFailedSubSolver(t),this.activeSubSolver=null,this.startTraceClearanceRepair()}}adoptCleanupOutput(t){const e=this.acceptConnectivityCheckpoint(t.getOutput(),\"cleanup\");this.cleanupCompleted=!t.budgetLimited;const n=t.stats;this.connectivityValidationError??=n.connectivityValidationError??null,this.connectivityValidationCount+=Number(n.connectivityValidationCount??0);const o=Number(n.connectivityRollbackCount??0);o\u003e0\u0026\u0026(this.connectivityRollbackCount+=o,this.connectivityRollbackPhases.includes(\"cleanup\")||this.connectivityRollbackPhases.push(\"cleanup\"),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...n.connectivityRegressionEndpointIds??[]])]);const i=e\u0026\u00260===o;this.cleanupBestEffortAccepted=t.budgetLimited\u0026\u0026i,this.cleanupMutatedTraceIndices=i?[...n.mutatedTraceIndices??[]]:[],this.removedViaPairCount=i?Number(n.viaPairCountRemoved??0):0,this.removedViaCount=i?Number(n.viaCountRemoved??0):0,this.simplifiedPathCount=i?Number(n.simplifiedPathCount??0):0,this.normalizedSegmentCount=i?Number(n.normalizedSegmentCount??0):0,this.cleanupClearanceShoveCount=i?Number(n.committedClearanceShoveCount??0):0,this.relocatedViaCount=i?Number(n.relocatedViaCount??0):0,this.unresolvedViaCount=Number(n.unresolvedViaCount??0),this.padClearanceRerouteCount=i?Number(n.padClearanceRerouteCount??0):0,this.unresolvedPadClearanceCount=Number(n.unresolvedPadClearanceCount??0),this.initialPadClearanceViolationCount=Number(n.initialPadClearanceViolationCount??0),this.remainingPadClearanceViolationCount=Number(n.remainingPadClearanceViolationCount??0),this.initialPadClearanceViolationCountByClearance={...n.initialPadClearanceViolationCountByClearance??{}},this.remainingPadClearanceViolationCountByClearance={...n.remainingPadClearanceViolationCountByClearance??{}},this.rebuildObstacleIndex()}startTraceClearanceRepair(){this.phase=\"repair-trace-clearance\";const t=[...new Set([...this.getOwnedTraceIndices(),...this.expansionPushedTraceIndices,...this.cleanupMutatedTraceIndices])],e=new YJ({simpleRouteJson:this.inputProblem,traces:this.traces,traceIndices:t});e.MAX_ITERATIONS=Math.min(e.MAX_ITERATIONS,this.getRemainingParentIterationsAfterCurrentStep()),this.clearanceRepairIterationBudget=e.MAX_ITERATIONS,this.activeSubSolver=e}stepActiveTraceClearanceRepairSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved)return this.adoptClearanceRepairOutput(t),this.activeSubSolver=null,void(this.phase=\"complete\");this.retainFailedSubSolver(t),this.activeSubSolver=null,this.phase=\"complete\"}}adoptClearanceRepairOutput(t){const e=this.acceptConnectivityCheckpoint(t.getOutput(),\"clearance-repair\");this.clearanceRepairCompleted=!t.budgetLimited;const n=t.stats;this.connectivityValidationError??=n.connectivityValidationError??null,this.connectivityValidationCount+=Number(n.connectivityValidationCount??0);const o=Number(n.connectivityRollbackCount??0);o\u003e0\u0026\u0026(this.connectivityRollbackCount+=o,this.connectivityRollbackPhases.includes(\"clearance-repair\")||this.connectivityRollbackPhases.push(\"clearance-repair\"),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...n.connectivityRegressionEndpointIds??[]])]);const i=e\u0026\u00260===o;this.clearanceRepairBestEffortAccepted=t.budgetLimited\u0026\u0026i,this.repairedTraceClearanceSegmentCount=i?Number(n.repairedSegmentCount??0):0,this.repairedPadNeckSegmentCount=i?Number(n.repairedPadNeckSegmentCount??0):0,this.unresolvedTraceClearanceSegmentCount=Number(n.unresolvedSegmentCount??0),this.rebuildObstacleIndex()}stepActiveLayerSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e){const t=!this.layerRouteReplacementCollides(e,!0)\u0026\u0026this.layerRouteImprovesInterval(e),n=t\u0026\u0026this.layerRoutePreservesSameNetContacts(e);if(n){if(this.activeSubSolver=null,this.pendingLayerOutput=e,this.pendingLayerPushCount=0,!this.layerRouteReplacementCollides(e,!1))return void this.applyLayerRoute(e);if(this.startPendingLayerInflation())return;this.pendingLayerOutput=null}t\u0026\u0026!n\u0026\u0026this.sameNetContactRejectionCount++}}this.retainFailedSubSolver(t),this.activeSubSolver=null,this.layerAttempt\u0026\u0026this.layerAttempt.offsetCursor++,this.phase=\"try-layer-candidate\"}}layerRouteReplacementCollides(t,e){const n=this.traces[this.traceIndex],o=this.layerAttempt;if(!n||!o)return!0;const i=this.getTraceConnectionNames(n),r=e?o.softTraceIndices:void 0,s={start:Math.max(0,o.interval.startIndex-1),end:Math.min(n.route.length-1,o.interval.endIndex+1)},a=this.getFixedViasOutsideInterval(n,o.interval);for(let e=0;e\u003ct.route.length;e++){const n=t.route[e];if(\"via\"===n?.route_type){if(this.obstacleIndex.collidesVia({point:n,layers:this.obstacleIndex.boardLayers,padDiameter:n.via_diameter??.6,holeDiameter:n.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,connectionNames:i,ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:r,otherNewViaPoints:t.route.slice(0,e).filter(t=\u003e\"via\"===t.route_type).map(t=\u003e({x:t.x,y:t.y})),fixedVias:a,ignoreRouteRange:s,obstacleClearance:this.getDesiredPadClearance(t.traceWidth),blockSameNetObstacles:!0,sameNetObstacleClearance:0}))return!0;continue}const o=t.route[e+1];if(\"wire\"===n?.route_type\u0026\u0026\"wire\"===o?.route_type\u0026\u0026n.layer===o.layer\u0026\u0026this.obstacleIndex.collides({start:n,end:o,layer:n.layer,width:Math.max(n.width,o.width),connectionNames:i,ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:r,ignoreRouteRange:s,obstacleClearance:this.getDesiredPadClearance(t.traceWidth)}))return!0}return this.layerRouteBoundaryCollides(t,e)}getFixedViasOutsideInterval(t,e){return t.route.flatMap((t,n)=\u003e\"via\"!==t.route_type||n\u003e=e.startIndex\u0026\u0026n\u003c=e.endIndex?[]:[{point:{x:t.x,y:t.y},padDiameter:t.via_diameter??.6,holeDiameter:t.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter}])}layerRouteBoundaryCollides(t,e){const n=this.traces[this.traceIndex],o=this.layerAttempt,i=t.route.find(t=\u003e\"wire\"===t.route_type);let r;for(let e=t.route.length-1;e\u003e=0;e--){const n=t.route[e];if(\"wire\"===n?.route_type){r=n;break}}if(!i||!r)return!0;const s=[{outside:n.route[o.interval.startIndex-1],inside:i},{outside:n.route[o.interval.endIndex+1],inside:r}];for(const i of s)if(HJ(i.outside)\u0026\u0026i.outside.layer===i.inside.layer\u0026\u0026this.obstacleIndex.collides({start:i.outside,end:i.inside,layer:i.inside.layer,width:Math.max(i.outside.width,i.inside.width),connectionNames:this.getTraceConnectionNames(n),ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:e?o.softTraceIndices:void 0,ignoreRouteRange:{start:Math.max(0,o.interval.startIndex-1),end:Math.min(n.route.length-1,o.interval.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(t.traceWidth)}))return!0;return!1}layerRouteImprovesInterval(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=this.getRouteQuality(e.route.slice(n.startIndex,n.endIndex+1)),i=this.getRouteQuality(t.route);return i.length\u003c=o.length+10+Mq\u0026\u0026i.deficitArea\u003c=o.deficitArea-Math.max(.05,.1*o.deficitArea)}getRouteQuality(t){let e=0,n=0;for(let o=0;o\u003ct.length-1;o++){const i=t[o],r=t[o+1];if(!HJ(i)||!HJ(r)||i.layer!==r.layer)continue;const s=Nq(i,r),a=Math.min(i.width,r.width);e+=s,n+=s*Math.max(0,this.nominalTraceWidth-a)}return{length:e,deficitArea:n}}getLayerInflationCorridor(t){const e=[];for(let n=0;n\u003ct.route.length;n++){const o=t.route[n];if(\"via\"===o?.route_type){for(const t of this.obstacleIndex.boardLayers)e.push({start:o,end:o,layer:t,width:o.via_diameter??.6});continue}const i=t.route[n+1];\"wire\"===o?.route_type\u0026\u0026\"wire\"===i?.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({start:o,end:i,layer:o.layer,width:Math.max(o.width,i.width)})}return e}startPendingLayerInflation(){const t=this.pendingLayerOutput;if(!t||this.pendingLayerPushCount\u003e=2)return!1;const e=this.getLayerInflationCorridor(t);return 0!==e.length\u0026\u0026(this.pendingLayerPushCount++,this.attemptedInflationCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem,traces:this.traces,powerTraceIndex:this.traceIndex,nominalPowerWidth:t.traceWidth,mutableTraceIndices:this.mutableBlockerTraceIndices,corridor:e,maxRerouteLength:10},this.connectionNameResolver),this.phase=\"try-trace-inflation\",!0)}applyLayerRoute(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=this.createLayerRouteReplacement(t);e.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...o),t.viaCount\u003e0\u0026\u0026this.layerReroutedTraceCount++,this.layerRerouteCountByTrace.set(this.traceIndex,(this.layerRerouteCountByTrace.get(this.traceIndex)??0)+1),this.reroutedSegmentCount++,this.insertedViaCount+=t.viaCount,t.viaCount\u003e0\u0026\u0026(this.neckedLayerSegmentCount+=o.filter(t=\u003e\"wire\"===t.route_type\u0026\u0026t.width\u003cthis.nominalTraceWidth-Mq).length),this.routeSegmentIndex=n.startIndex,this.currentIntervals=[],this.layerAttempt=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.phase=\"evaluate-segment\"}createLayerRouteReplacement(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=e.route[n.startIndex],i=e.route[n.endIndex],r=structuredClone(t.route),s=r.findIndex(t=\u003e\"wire\"===t.route_type);let a=-1;for(let t=r.length-1;t\u003e=0;t--)if(\"wire\"===r[t]?.route_type){a=t;break}return s\u003e=0\u0026\u0026(r[s]={...o,...r[s]}),a\u003e=0\u0026\u0026(r[a]={...i,...r[a]}),r}layerRoutePreservesSameNetContacts(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval;return this.routeReplacementPreservesSameNetContacts(e,n,this.createLayerRouteReplacement(t))}startTraceInflation(t,e){const n=t.route[e],o=t.route[e+1];if(!HJ(n)||!HJ(o))return!1;const i=Math.min(n.width,o.width),r=this.findBestPushableInflationWidth(t,e,i);if(!r)return!1;const s=this.getLocalInflationCorridor(t,e,r);if(0===s.length)return!1;const a=[this.traceIndex,n.x,n.y,o.x,o.y].join(\":\"),c=this.inflationAttemptsBySegment.get(a)??0;return!(c\u003e=2)\u0026\u0026(this.inflationAttemptsBySegment.set(a,c+1),this.activeInflationKey=a,this.activeInflationWidth=r,this.attemptedInflationCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem,traces:this.traces,powerTraceIndex:this.traceIndex,nominalPowerWidth:r,mutableTraceIndices:this.mutableBlockerTraceIndices,corridor:s,maxRerouteLength:10},this.connectionNameResolver),this.phase=\"try-trace-inflation\",!0)}hasOnlyPushableTraceBlockers(t,e,n){const o=Math.max(0,e-1),i=Math.min(t.route.length-2,e+1),r=new Set;for(let e=o;e\u003c=i;e++){const s=t.route[e],a=t.route[e+1];if(!HJ(s)||!HJ(a)||s.layer!==a.layer)continue;const c={start:s,end:a,layer:s.layer,width:n,connectionNames:this.getTraceConnectionNames(t),ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:o,end:i+1},obstacleClearance:this.getDesiredPadClearance(n)},l=this.obstacleIndex.findCollisions(c);if(0===l.length\u0026\u0026this.obstacleIndex.collides(c))return!1;for(const t of l){if(\"trace\"!==t.kind||void 0===t.traceIndex)return!1;const e=this.traces[t.traceIndex];if(!e)return!1;const o=this.findConnectionForTrace(e);if(!o||(o.nominalTraceWidth??o.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth)\u003e=n-Mq)return!1;r.add(t.traceIndex)}}return r.size\u003e0\u0026\u0026r.size\u003c=2}findBestPushableInflationWidth(t,e,n){const o=this.nominalTraceWidth\u003e=.5?.05:.0125;for(let i=this.nominalTraceWidth;i\u003en+Mq;i-=o){const n=Number(i.toFixed(6));if(this.hasOnlyPushableTraceBlockers(t,e,n))return n}return null}stepActiveInflationSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput(),n=e\u0026\u0026this.sameNetContactsArePreserved(this.traces[e.pushedTraceIndex].route,e.traces[e.pushedTraceIndex].route,this.getTraceConnectionNames(this.traces[e.pushedTraceIndex]),e.pushedTraceIndex);if(e\u0026\u0026n){if(this.traces=e.traces,this.pushedTraceCount++,this.expansionPushedTraceIndices.add(e.pushedTraceIndex),\"elastic\"===e.strategy\u0026\u0026this.elasticPushedTraceCount++,this.activeSubSolver=null,this.activeInflationKey=null,this.activeInflationWidth=null,this.rebuildObstacleIndex(),this.pendingLayerOutput){if(!this.layerRouteReplacementCollides(this.pendingLayerOutput,!1)\u0026\u0026this.layerRoutePreservesSameNetContacts(this.pendingLayerOutput))return void this.applyLayerRoute(this.pendingLayerOutput);if(this.startPendingLayerInflation())return;return this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.layerAttempt\u0026\u0026this.layerAttempt.offsetCursor++,void(this.phase=\"try-layer-candidate\")}return void(this.phase=\"evaluate-segment\")}e\u0026\u0026!n\u0026\u0026this.sameNetContactRejectionCount++}if(this.retainFailedSubSolver(t),this.activeInflationKey\u0026\u0026this.inflationAttemptsBySegment.set(this.activeInflationKey,2),this.activeInflationKey=null,this.activeInflationWidth=null,this.activeSubSolver=null,this.pendingLayerOutput)return this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.layerAttempt\u0026\u0026this.layerAttempt.offsetCursor++,void(this.phase=\"try-layer-candidate\");this.phase=\"evaluate-segment\"}}getLocalInflationCorridor(t,e,n){const o=t.route[e],i=t.route[e+1];if(!HJ(o)||!HJ(i)||o.layer!==i.layer)return[];const r=Rq(4*n,2,4),s=r/2;let a=e,c=0;for(;a\u003e0;){const e=t.route[a-1],n=t.route[a];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(c+o\u003es+Mq)break;c+=o,a--}let l=e+1,d=0;for(;l\u003ct.route.length-1;){const e=t.route[l],n=t.route[l+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(d+o\u003es+Mq)break;d+=o,l++}let h=r-c-d;for(;h\u003eMq\u0026\u0026a\u003e0;){const e=t.route[a-1],n=t.route[a];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(o\u003eh+Mq)break;h-=o,a--}for(;h\u003eMq\u0026\u0026l\u003ct.route.length-1;){const e=t.route[l],n=t.route[l+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(o\u003eh+Mq)break;h-=o,l++}const u=[];for(let e=a;e\u003cl;e++){const o=t.route[e],i=t.route[e+1];HJ(o)\u0026\u0026HJ(i)\u0026\u0026o.layer===i.layer\u0026\u0026u.push({start:o,end:i,layer:o.layer,width:n})}return u}applyGridRoute(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=this.createGridRouteReplacement(t);e.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...o),this.reroutedSegmentCount++,this.routeSegmentIndex=n.startIndex+o.length-1,this.currentIntervals=[],this.phase=\"evaluate-segment\"}createGridRouteReplacement(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=e.route[n.startIndex],i=e.route[n.endIndex],r=t.points.map(e=\u003e({route_type:\"wire\",x:e.x,y:e.y,width:t.traceWidth,layer:o.layer}));return r[0].width=Math.max(o.width,t.traceWidth),r[r.length-1].width=Math.max(i.width,t.traceWidth),r}gridRoutePreservesSameNetContacts(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor];return this.routeReplacementPreservesSameNetContacts(e,n,this.createGridRouteReplacement(t))}routeReplacementPreservesSameNetContacts(t,e,n){const o=this.getTraceConnectionNames(t),i=this.getSameNetContactIds(t.route.slice(e.startIndex,e.endIndex+1),o,this.traceIndex),r=new Set([...this.getSameNetContactIds(t.route.slice(0,e.startIndex+1),o,this.traceIndex),...this.getSameNetContactIds(t.route.slice(e.endIndex),o,this.traceIndex)]),s=new Set([...i].filter(t=\u003e!r.has(t)));if(0===s.size)return!0;const a=this.getSameNetContactIds(n,o,this.traceIndex);return[...s].every(t=\u003ea.has(t))}sameNetContactsArePreserved(t,e,n,o){const i=this.getSameNetContactIds(t,n,o);if(0===i.size)return!0;const r=this.getSameNetContactIds(e,n,o);return[...i].every(t=\u003er.has(t))}getSameNetContactIds(t,e,n){const o=new Set;for(let i=0;i\u003ct.length;i++){const r=t[i];if(\"via\"===r?.route_type){for(const t of this.getViaLayers(r))for(const i of this.obstacleIndex.getSameNetCopperContactIds({start:r,end:r,layer:t,width:r.via_diameter??.6,connectionNames:e,ignoreTraceIndex:n}))o.add(i);continue}const s=t[i+1];if(\"wire\"===r?.route_type\u0026\u0026\"wire\"===s?.route_type\u0026\u0026r.layer===s.layer)for(const t of this.obstacleIndex.getSameNetCopperContactIds({start:r,end:s,layer:r.layer,width:Math.min(r.width,s.width),connectionNames:e,ignoreTraceIndex:n}))o.add(t)}return o}getViaLayers(t){const e=this.obstacleIndex.boardLayers.indexOf(t.from_layer),n=this.obstacleIndex.boardLayers.indexOf(t.to_layer);return e\u003c0||n\u003c0?this.obstacleIndex.boardLayers:this.obstacleIndex.boardLayers.slice(Math.min(e,n),Math.max(e,n)+1)}gridRouteReplacementCollides(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=e.route[n.startIndex],i=e.route[n.endIndex],r=this.getTraceConnectionNames(e);for(let s=0;s\u003ct.points.length-1;s++){const a=Math.max(t.traceWidth,0===s?o.width:0,s===t.points.length-2?i.width:0);if(this.obstacleIndex.collides({start:t.points[s],end:t.points[s+1],layer:o.layer,width:a,connectionNames:r,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,n.startIndex-1),end:Math.min(e.route.length-1,n.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(a)}))return!0}return!1}gridRouteBoundaryCollides(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=this.getTraceConnectionNames(e),i=[{startIndex:n.startIndex-1,endIndex:n.startIndex},{startIndex:n.endIndex,endIndex:n.endIndex+1}];for(const n of i){const i=e.route[n.startIndex],r=e.route[n.endIndex];if(HJ(i)\u0026\u0026HJ(r)\u0026\u0026i.layer===r.layer\u0026\u0026this.obstacleIndex.collides({start:i,end:r,layer:i.layer,width:Math.max(i.width,r.width,t.traceWidth),connectionNames:o,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:n.startIndex,end:n.endIndex},obstacleClearance:this.getDesiredPadClearance(Math.max(i.width,r.width,t.traceWidth))}))return!0}return!1}canExpandSegmentAndEndpoints(t,e,n,o=this.nominalTraceWidth){const i=Math.max(0,e-1),r=Math.min(t.route.length-2,e+1);for(let s=i;s\u003c=r;s++){const a=t.route[s],c=t.route[s+1];if(!HJ(a)||!HJ(c)||a.layer!==c.layer)continue;const l=s\u003c=e+1\u0026\u0026s+1\u003e=e,d=Math.max(a.width,c.width,l?o:0);if(this.obstacleIndex.collides({start:a,end:c,layer:a.layer,width:d,connectionNames:n,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:i,end:r+1},obstacleClearance:this.getDesiredPadClearance(d)}))return!1}return!0}findMaximumSafeInPlaceWidth(t,e,n){const o=t.route[e],i=t.route[e+1];if(!HJ(o)||!HJ(i))return 0;const r=Math.min(o.width,i.width);if(this.probeInPlaceWidth(t,e,n,this.nominalTraceWidth))return this.nominalTraceWidth;let s=r,a=this.nominalTraceWidth;for(let o=0;o\u003c7;o++){const o=(s+a)/2;if(o\u003c=s+Mq)break;this.probeInPlaceWidth(t,e,n,o)?s=o:a=o}const c=this.nominalTraceWidth\u003e=.5?.025:.0125,l=Math.max(r,Math.floor((s+Mq)/c)*c);return l\u003er+Mq\u0026\u0026this.probeInPlaceWidth(t,e,n,l)?l:r}probeInPlaceWidth(t,e,n,o){return this.inPlaceWidthProbeCount++,this.canExpandSegmentAndEndpoints(t,e,n,o)}maximizeGridRouteWidth(t){if(t.traceWidth\u003e=this.nominalTraceWidth-Mq)return t;let e=t.traceWidth,n=this.nominalTraceWidth;for(let o=0;o\u003c7;o++){const o=(e+n)/2,i={...t,traceWidth:o};this.gridRouteReplacementCollides(i)||this.gridRouteBoundaryCollides(i)?n=o:e=o}const o=this.nominalTraceWidth\u003e=.5?.025:.0125,i=Math.max(t.traceWidth,Math.floor((e+Mq)/o)*o);if(i\u003et.traceWidth+Mq){const e={...t,traceWidth:i};if(!this.gridRouteReplacementCollides(e)\u0026\u0026!this.gridRouteBoundaryCollides(e))return this.pathWidthUpgradeCount++,e}return t}getExponentialIntervalCandidates(t,e,n){const o=this.getExponentialIndices(t,e,-1,n,5),i=this.getExponentialIndices(t,e,1,n,10).filter(t=\u003et\u003ee),r=[];for(const e of o)for(const n of i){const o=this.getRouteIntervalLength(t,e,n);o\u003e10.000001||r.push({startIndex:e,endIndex:n,routeLength:o})}return r.sort((t,e)=\u003et.routeLength-e.routeLength).filter((t,e,n)=\u003en.findIndex(e=\u003ee.startIndex===t.startIndex\u0026\u0026e.endIndex===t.endIndex)===e).slice(0,10).map(({startIndex:t,endIndex:e})=\u003e({startIndex:t,endIndex:e}))}getExponentialIndices(t,e,n,o,i){const r=[e];let s=0,a=Math.max(o,.3),c=e,l=e;for(;;){const e=c+n;if(e\u003c0||e\u003e=t.route.length)break;const o=t.route[c],d=t.route[e];if(!HJ(o)||!HJ(d)||o.layer!==d.layer)break;const h=Nq(o,d);if(s+h\u003ei+Mq)break;s+=h,c=e,l=e,s+Mq\u003e=a\u0026\u0026(r.push(e),a*=2)}return r.includes(l)||r.push(l),r}getRouteIntervalLength(t,e,n){let o=0;for(let i=e;i\u003cn;i++){const e=t.route[i],n=t.route[i+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)return Number.POSITIVE_INFINITY;o+=Nq(e,n)}return o}getCandidateWidths(t){const e=this.inputProblem.minTraceWidth;return WJ([t,.875*t,.75*t,.625*t,.5*t,.375*t,.25*t,e]).filter(t=\u003et\u003e=e-Mq)}getGridResolutions(t){return WJ([Math.max(.1,Math.min(.5,t/2)),Math.max(.1,Math.min(.25,t/3))])}resolveNominalTraceWidth(t){const e=this.findConnectionForTrace(t);return Math.max(e?.nominalTraceWidth??e?.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth,this.inputProblem.minTraceWidth)}getDesiredPadClearance(t=this.nominalTraceWidth){const e=Math.max(this.inputProblem.defaultObstacleMargin??0,this.inputProblem.minTraceToPadEdgeClearance??0,.1);return t\u003c.499999||\"cleanup\"!==this.phase?e:Math.max(e,this.options.powerTraceToPadClearance??t/2)}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=this.getTraceConnectionNames(t),o=this.inputProblem.connections.find(t=\u003ethis.connectionMatchesTrace(t,n))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getOwnedTraceIndices(){return[...this.selectedOwnedTraceIndices]}connectionMatchesTrace(t,e){return[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t)).some(t=\u003ee.includes(t))}getTraceConnectionNames(t){return[t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))}traceMeetsNominalWidth(t,e){return t.route.every(t=\u003e\"wire\"!==t.route_type||t.width\u003e=e-Mq)}findNextUnderWidthSegment(t,e,n){for(let o=e;o\u003ct.route.length-1;o++){const e=t.route[o],i=t.route[o+1];if(HJ(e)\u0026\u0026HJ(i)\u0026\u0026e.layer===i.layer\u0026\u0026(e.width\u003cn-Mq||i.width\u003cn-Mq))return o}return-1}getMutatedImmutableTraceIds(t){return this.immutableTraceIndices.flatMap(e=\u003e{const n=t[e];return JSON.stringify(n)===this.initialImmutableTraceSignatures.get(e)?[]:[n?.pcb_trace_id??this.traces[e]?.pcb_trace_id??String(e)]})}getImmutableViaViolationSignatures(t){const e=new Set;if(0===this.immutableTraceIndices.length)return e;const n=new Pq(this.inputProblem,t),o=new tJ(this.inputProblem,t,void 0,[],n);for(const n of this.immutableTraceIndices){const i=t[n];if(!i)continue;const r=[i.pcb_trace_id,i.connection_name,i.source_trace_id,i.rootConnectionName,...i.mergedConnectionNames??[],...i.connectsTo??[]].filter(t=\u003eBoolean(t));for(let t=0;t\u003ci.route.length;t++){const s=i.route[t];if(\"via\"!==s?.route_type)continue;const a=`${i.pcb_trace_id}:${t}`,c=o.getViaViolationSignatures({point:s,layers:o.boardLayers,padDiameter:s.via_diameter??this.inputProblem.min_via_pad_diameter??this.inputProblem.minViaPadDiameter??this.inputProblem.minViaDiameter??.6,holeDiameter:s.via_hole_diameter??o.defaultViaHoleDiameter,connectionNames:r,ignoreTraceIndex:n,ignoreRouteRange:{start:t,end:t},blockSameNetObstacles:!0,sameNetObstacleClearance:0});for(const t of c)e.add(`${a}|${t}`)}}return e}countViolatingImmutableVias(t){return new Set([...t].map(t=\u003et.split(\"|\")[0])).size}acceptConnectivityCheckpoint(t,e){this.connectivityValidationCount++;let n=!1,o=!1;try{const e=this.connectivityInvariant.validate(t),i=this.getMutatedImmutableTraceIds(t),r=this.getImmutableViaViolationSignatures(t),s=[...r].filter(t=\u003e!this.lastSafeImmutableViaViolationSignatures.has(t)),a=s.length\u003e0;if(n=!e.safe,o=i.length\u003e0||a,this.connectivityValidationError??=e.validationError??null,!n\u0026\u0026!o)return this.traces=structuredClone(t),this.lastConnectivitySafeTraces=structuredClone(t),this.remainingImmutableViaViolationCount=this.countViolatingImmutableVias(r),this.remainingImmutableViaViolationPairCount=r.size,this.lastSafeImmutableViaViolationSignatures=r,this.connectivityInvariant=new OJ(this.inputProblem,this.lastConnectivitySafeTraces),!0;this.immutableTraceMutationIds=[...new Set([...this.immutableTraceMutationIds,...i])],a\u0026\u0026(this.immutableViaViolationRollbackCount++,this.attemptedImmutableViaViolationCount=this.countViolatingImmutableVias(r),this.attemptedImmutableViaViolationPairCount=r.size,this.immutableViaViolationRegressionIds=[...new Set([...this.immutableViaViolationRegressionIds,...s])]),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...e.regressions.flatMap(t=\u003et.baselineEndpointLabels)])]}catch(t){n=!0,this.connectivityValidationError=t instanceof Error?t.message:String(t)}return n\u0026\u0026(this.connectivityRollbackCount++,this.connectivityRollbackPhases.includes(e)||this.connectivityRollbackPhases.push(e)),o\u0026\u0026(this.immutableSafetyRollbackCount++,this.immutableSafetyRollbackPhases.includes(e)||this.immutableSafetyRollbackPhases.push(e)),\"expansion\"===e?n?this.rollbackConnectivityRegressedExpansion():this.rollbackImmutableUnsafeExpansion():this.restoreLastConnectivitySafeTraces(),this.remainingImmutableViaViolationCount=this.countViolatingImmutableVias(this.lastSafeImmutableViaViolationSignatures),this.remainingImmutableViaViolationPairCount=this.lastSafeImmutableViaViolationSignatures.size,!1}rebuildObstacleIndex(){this.obstacleIndex=new tJ(this.inputProblem,this.traces,this.traceIndex,[],this.connectionNameResolver)}retainFailedSubSolver(t){this.failedSubSolverCount++,this.failedSubSolvers??=[],this.failedSubSolvers.length\u003c16?this.failedSubSolvers.push(t):this.failedSubSolvers[15]=t}tryFinalAcceptance(){this.finalAcceptanceUsed=!0;let t=!1;this.activeSubSolver instanceof jJ?(this.activeSubSolver.tryFinalAcceptance(),this.adoptCleanupOutput(this.activeSubSolver),t=!0):this.activeSubSolver instanceof YJ\u0026\u0026(this.activeSubSolver.tryFinalAcceptance(),this.adoptClearanceRepairOutput(this.activeSubSolver),t=!0),t||\"cleanup\"===this.phase||\"repair-trace-clearance\"===this.phase||\"complete\"===this.phase||this.discardInFlightExpansion(),this.activeSubSolver=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.activeInflationKey=null,this.activeInflationWidth=null,this.layerAttempt=null,this.acceptConnectivityCheckpoint(this.traces,\"final\"),this.traceIndex=this.traces.length,this.phase=\"complete\",this.rebuildObstacleIndex(),this.progress=1,this.solved=!0,this.stats=this.createStats()}createStats(){return{phase:this.phase,pass:this.passIndex+1,completedPassCount:this.completedPassCount,lastNormalizedWidthDeficitGain:this.lastNormalizedWidthDeficitGain,normalizedWidthDeficitGainByPass:[...this.normalizedWidthDeficitGainByPass],plateauReached:this.plateauReached,traceIndex:this.traceIndex,traceCount:this.traces.length,selectedTraceCount:this.traceOrder.length,routeSegmentIndex:this.routeSegmentIndex,nominalTraceWidth:this.nominalTraceWidth,intervalCursor:this.intervalCursor,intervalCount:this.currentIntervals.length,candidateWidth:this.candidateWidths[this.widthCursor],gridSize:this.gridResolutions[this.resolutionCursor],gridOffsetVariant:this.offsetCursor,keptTraceCount:this.keptTraceCount,recreatedTraceCount:this.recreatedTraceCount,expandedSegmentCount:this.expandedSegmentCount,intermediateExpandedSegmentCount:this.intermediateExpandedSegmentCount,pathWidthUpgradeCount:this.pathWidthUpgradeCount,inPlaceWidthProbeCount:this.inPlaceWidthProbeCount,reroutedSegmentCount:this.reroutedSegmentCount,unresolvedSegmentCount:this.unresolvedSegmentCount,attemptedGridCount:this.attemptedGridCount,attemptedLayerGridCount:this.attemptedLayerGridCount,attemptedInflationCount:this.attemptedInflationCount,activeInflationWidth:this.activeInflationWidth,pushedTraceCount:this.pushedTraceCount,elasticPushedTraceCount:this.elasticPushedTraceCount,layerReroutedTraceCount:this.layerReroutedTraceCount,insertedViaCount:this.insertedViaCount,neckedLayerSegmentCount:this.neckedLayerSegmentCount,removedViaPairCount:this.removedViaPairCount,removedViaCount:this.removedViaCount,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,cleanupClearanceShoveCount:this.cleanupClearanceShoveCount,relocatedViaCount:this.relocatedViaCount,unresolvedViaCount:this.unresolvedViaCount,initialImmutableViaViolationCount:this.initialImmutableViaViolationCount,remainingImmutableViaViolationCount:this.remainingImmutableViaViolationCount,initialImmutableViaViolationPairCount:this.initialImmutableViaViolationPairCount,remainingImmutableViaViolationPairCount:this.remainingImmutableViaViolationPairCount,skippedImmutableViaRepairCount:this.remainingImmutableViaViolationCount,immutableViaViolationRollbackCount:this.immutableViaViolationRollbackCount,attemptedImmutableViaViolationCount:this.attemptedImmutableViaViolationCount,attemptedImmutableViaViolationPairCount:this.attemptedImmutableViaViolationPairCount,immutableViaViolationRegressionIds:[...this.immutableViaViolationRegressionIds],immutableTraceMutationIds:[...this.immutableTraceMutationIds],padClearanceRerouteCount:this.padClearanceRerouteCount,unresolvedPadClearanceCount:this.unresolvedPadClearanceCount,repairedTraceClearanceSegmentCount:this.repairedTraceClearanceSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,unresolvedTraceClearanceSegmentCount:this.unresolvedTraceClearanceSegmentCount,sameNetContactRejectionCount:this.sameNetContactRejectionCount,connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRollbackPhases:[...this.connectivityRollbackPhases],immutableSafetyRollbackCount:this.immutableSafetyRollbackCount,immutableSafetyRollbackPhases:[...this.immutableSafetyRollbackPhases],connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},immutableSafetyRollbackMutationStats:null===this.immutableSafetyRollbackMutationStats?null:{...this.immutableSafetyRollbackMutationStats},expansionPushedTraceIndices:[...this.expansionPushedTraceIndices],cleanupMutatedTraceIndices:[...this.cleanupMutatedTraceIndices],discardedExpansionMutationStats:null===this.discardedExpansionMutationStats?null:{...this.discardedExpansionMutationStats},initialPadClearanceViolationCount:this.initialPadClearanceViolationCount,remainingPadClearanceViolationCount:this.remainingPadClearanceViolationCount,initialPadClearanceViolationCountByClearance:{...this.initialPadClearanceViolationCountByClearance},remainingPadClearanceViolationCountByClearance:{...this.remainingPadClearanceViolationCountByClearance},budgetLimitedExpansion:this.budgetLimitedExpansion,finalAcceptanceUsed:this.finalAcceptanceUsed,cleanupCompleted:this.cleanupCompleted,clearanceRepairCompleted:this.clearanceRepairCompleted,cleanupBestEffortAccepted:this.cleanupBestEffortAccepted,clearanceRepairBestEffortAccepted:this.clearanceRepairBestEffortAccepted,cleanupStatus:this.connectivityRollbackPhases.includes(\"cleanup\")?\"connectivity_rollback\":this.immutableSafetyRollbackPhases.includes(\"cleanup\")?\"immutable_safety_rollback\":this.cleanupBestEffortAccepted?\"budget_limited\":this.cleanupCompleted?\"completed\":\"cleanup\"===this.phase?\"in_progress\":\"not_started\",clearanceRepairStatus:this.connectivityRollbackPhases.includes(\"clearance-repair\")?\"connectivity_rollback\":this.immutableSafetyRollbackPhases.includes(\"clearance-repair\")?\"immutable_safety_rollback\":this.clearanceRepairBestEffortAccepted?\"budget_limited\":this.clearanceRepairCompleted?\"completed\":\"repair-trace-clearance\"===this.phase?\"in_progress\":\"not_started\",cleanupIterationBudget:this.cleanupIterationBudget,clearanceRepairIterationBudget:this.clearanceRepairIterationBudget,completionReason:\"complete\"===this.phase||this.solved?this.connectivityRollbackCount\u003e0?\"connectivity_rollback\":this.immutableSafetyRollbackCount\u003e0?\"immutable_safety_rollback\":this.connectivityValidationError?\"connectivity_validation_unavailable\":this.finalAcceptanceUsed?\"total_iteration_budget\":this.budgetLimitedExpansion?\"expansion_budget\":this.cleanupBestEffortAccepted?\"cleanup_budget\":this.clearanceRepairBestEffortAccepted?\"clearance_repair_budget\":this.remainingImmutableViaViolationCount\u003e0?\"immutable_via_violations_preserved\":\"completed\":null,resultStatus:this.finalAcceptanceUsed||this.budgetLimitedExpansion||this.cleanupBestEffortAccepted||this.clearanceRepairBestEffortAccepted||this.connectivityRollbackCount\u003e0||this.immutableSafetyRollbackCount\u003e0||null!==this.connectivityValidationError||this.remainingImmutableViaViolationCount\u003e0?\"best_effort\":\"complete\",failedSubSolverCount:this.failedSubSolverCount,retainedFailedSubSolverCount:this.failedSubSolvers?.length??0,expansionIterationBudget:this.getExpansionIterationBudget(),finalizationIterationReserve:this.getFinalizationIterationReserve(),spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){return this.solved||\"complete\"===this.phase?1:this.budgetLimitedExpansion?.99:0===this.traceOrder.length?1:Math.min(.99,(this.passIndex+Math.max(0,this.traceOrderCursor)/this.traceOrder.length)/this.maxPassCount)}getConstructorParams(){return[this.inputProblem,this.options]}getOutput(){return structuredClone(this.lastConnectivitySafeTraces)}visualize(){const t=[],e=[];for(let n=0;n\u003cthis.traces.length;n++){const o=this.traces[n],i=this.resolveNominalTraceWidth(o);for(const t of o.route)\"via\"===t.route_type\u0026\u0026e.push({center:t,radius:(t.via_diameter??.6)/2,fill:\"#d4a017\",stroke:\"#7a5700\"});for(let e=0;e\u003co.route.length-1;e++){const r=o.route[e],s=o.route[e+1];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)continue;const a=n===this.traceIndex\u0026\u0026e===this.routeSegmentIndex,c=r.width\u003e=i-Mq\u0026\u0026s.width\u003e=i-Mq,l=\"bottom\"===r.layer;t.push({points:[r,s],strokeColor:a?\"#ff8c00\":c?l?\"#2468c7\":\"#169c45\":l?\"#8b4bb8\":\"#cc3344\",strokeWidth:Math.max(r.width,s.width)})}}return{coordinateSystem:\"cartesian\",title:`Power trace expander: ${this.phase}`,lines:t,points:[],circles:e,rects:this.obstacleIndex.items.filter(t=\u003e\"obstacle\"===t.kind).slice(0,2e3).map(t=\u003e({center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,fill:\"rgba(80,80,80,0.12)\",stroke:\"rgba(80,80,80,0.35)\"})),texts:[]}}},UJ=class extends si{constructor(t,e={}){if(super(),this.inputSrj=t,this.options=e,this.powerTraceExpanderSolver=new GJ(t,e),0===e.onlyConnectionNames?.length)return this.MAX_ITERATIONS=1,this.progress=1,this.solved=!0,void(this.stats={selectedTraceCount:0,bypassed:!0});this.MAX_ITERATIONS=this.powerTraceExpanderSolver.MAX_ITERATIONS+1}inputSrj;options;powerTraceExpanderSolver;_step(){const t=this.powerTraceExpanderSolver;if(t.step(),this.progress=t.progress,this.stats=t.stats,t.failed)return this.error=t.error,void(this.failed=!0);t.solved\u0026\u0026(this.solved=!0)}getConstructorParams(){return[this.inputSrj,this.options]}getOutput(){if(!this.solved)throw new Error(\"Cannot get power trace expansion output before solving\");return this.powerTraceExpanderSolver.getOutput()}visualize(){return Ho({...this.inputSrj,traces:this.getOutput()},{traceColorMode:\"layer\"})}},ZJ=({connections:t,originalConnections:e,layerCount:n,obstacles:o,defaultViaHoleDiameter:i,connMap:r})=\u003e{const s=new Map;for(const t of e)s.has(t.name)||s.set(t.name,t.__netConnectionName);const a=t.map(t=\u003e{if(2!==t.pointsToConnect.length)throw new Error(`Expected Pipeline7 output connection \"${t.name}\" to have two points, got ${t.pointsToConnect.length}`);const[e,n]=t.pointsToConnect;return{connection:t,connectsTo:[e?.pointId,n?.pointId].filter(t=\u003eBoolean(t)),outputConnectionName:t.__netConnectionName??s.get(t.name)??t.__rootConnectionNames?.[0]??t.name}}),c=o.filter(t=\u003e(t.__zLayers?.length??t.layers?.length??0)\u003e1),l=new Map,d=t=\u003e{let e=l.get(t.connectionName);e||(e=new Map,l.set(t.connectionName,e));const n=e.get(t.rootConnectionName);if(n)return n;const o=c.filter(e=\u003efo(e,t,r));return e.set(t.rootConnectionName,o),o};return t=\u003e{const e=[],o=new Map;for(const e of t){const t=o.get(e.connectionName);t?t.push(e):o.set(e.connectionName,[e])}for(const{connection:t,connectsTo:s,outputConnectionName:c}of a){const a=o.get(t.name)??[];for(let o=0;o\u003ca.length;o+=1){const l=a[o];e.push({type:\"pcb_trace\",pcb_trace_id:`${t.name}_${o}`,connection_name:c,connectsTo:s,route:Mo(l,n,{connectionPoints:t.pointsToConnect,defaultViaHoleDiameter:i,connectedMultilayerObstacles:d(l),connMap:r})})}}return e}},qJ=({connections:t,originalConnections:e,hdRoutes:n,layerCount:o,obstacles:i,defaultViaHoleDiameter:r,connMap:s})=\u003eZJ({connections:t,originalConnections:e,layerCount:o,obstacles:i,defaultViaHoleDiameter:r,connMap:s})(n),JJ=t=\u003e{const e=Math.max(t.minTraceWidth+.1,2*t.minTraceWidth);return t.connections.flatMap(n=\u003e(n.nominalTraceWidth??t.nominalTraceWidth??t.minTraceWidth)+1e-6\u003e=e?[n.name]:[])},KJ=(t,e,n=new Map(t.map(t=\u003e[t.connectionName,t])))=\u003e{const o=new Map(e.map(t=\u003e[t.name,t]));return t.map(t=\u003e{if(0===t.route.length)throw new Error(`Cannot lock PCB terminals for empty route \"${t.connectionName}\"`);const e=o.get(t.connectionName);if(!e)throw new Error(`Cannot lock PCB terminals: connection \"${t.connectionName}\" was not found`);if(2!==e.pointsToConnect.length)throw new Error(`Cannot lock PCB terminals for \"${t.connectionName}\": expected 2 connection points, found ${e.pointsToConnect.length}`);const i=n.get(t.connectionName)??t,r=new Map;for(const n of e.pointsToConnect)if(n.pcb_port_id){if(r.has(n.pcb_port_id))throw new Error(`Cannot lock duplicate PCB terminal \"${n.pcb_port_id}\" for \"${t.connectionName}\"`);r.set(n.pcb_port_id,n)}if(0===r.size)return t;const s=[i.startPcbPortId,i.endPcbPortId].filter(t=\u003evoid 0!==t);if(0===s.length)return t;if(new Set(s).size!==s.length||s.some(t=\u003e!r.has(t)))throw new Error(`Cannot lock PCB terminals for \"${t.connectionName}\": route endpoint IDs do not match connection terminal IDs`);const a=i.startPcbPortId?r.get(i.startPcbPortId):void 0,c=i.endPcbPortId?r.get(i.endPcbPortId):void 0,l=t.route.map((e,n)=\u003e{if(0===n\u0026\u0026a)return{...e,x:a.x,y:a.y,pcb_port_id:a.pcb_port_id};if(n===t.route.length-1\u0026\u0026c)return{...e,x:c.x,y:c.y,pcb_port_id:c.pcb_port_id};const o={...e};return delete o.pcb_port_id,o});return{...t,route:l}})},QJ=({originalSrj:t,newlyRoutedTraces:e,currentPreloadedTraces:n,expandedConnectionNames:o,resolveConnectedTraceAliases:i=!1})=\u003e{const r=n??t.traces??[],s=i?tK({originalSrj:t,newlyRoutedTraces:e,preloadedTraces:r,expandedConnectionNames:o}):new Set(r.filter(t=\u003eo.includes(t.connection_name))),a=r.filter(t=\u003e!s.has(t)),c=new Set([...e.map(t=\u003et.pcb_trace_id),...a.map(t=\u003et.pcb_trace_id)]),l=r.filter(t=\u003es.has(t)).map(t=\u003e{const e=t.pcb_trace_id;let n=e,o=2;for(;c.has(n);)n=`${e}_power_expansion_${o++}`;return c.add(n),{...t,pcb_trace_id:n,__replaces_pcb_trace_id:t.__replaces_pcb_trace_id??t.pcb_trace_id}});return{...t,traces:[...e,...l],fixedTraces:a}},tK=({originalSrj:t,newlyRoutedTraces:e,preloadedTraces:n,expandedConnectionNames:o})=\u003e{const i=new Set(n.map(t=\u003et.pcb_trace_id)),r=new Set([...i,...e.map(t=\u003et.pcb_trace_id)]),s=e.map((t,e)=\u003e{if(!i.has(t.pcb_trace_id))return t;const n=`__pipeline7_new_trace_${e}_${t.pcb_trace_id}`;let o=n,s=2;for(;r.has(o);)o=`${n}_${s++}`;return r.add(o),{...t,pcb_trace_id:o}}),a=new Pq({...t,traces:[...s,...n]}),c=new Set(a.canonicalize([...o]));return new Set(n.filter(t=\u003ea.canonicalize([t.connection_name]).some(t=\u003ec.has(t))))};function eK(t){return new Set((t??[]).filter(t=\u003et._isComponentTopologyNode).map(t=\u003et.capacityMeshNodeId))}function nK(t,e){return t.nodeIds.some(t=\u003ee.has(t))}function oK({sharedEdgeSegments:t,componentCapacityMeshNodeIds:e}){return t.filter(t=\u003e!nK(t,e))}function iK(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var rK=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e;const n=fX(t);this.originalSrj=n,this.opts={...e};const o=this.opts;if(this.effort=o.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=o.maxNodeDimension??16,this.maxNodeRatio=o.maxNodeRatio??6,this.minNodeArea=o.minNodeArea??.1**2,this.visualizationTraceColorMode=o.visualizationTraceColorMode??\"layer\",this.setSimpleRouteJson(n),void 0===o.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,n=Math.max(t,e),i=o.targetMinCapacity??.5;o.capacityDepth=$s(n,i)}this.cacheProvider=void 0===o.cacheProvider?oo():null===o.cacheProvider?null:o.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;getSolverName(){return\"AutoroutingPipelineSolver7_MultiGraph\"}preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;componentTopologyGeneratorSolver;topologyPlanningSolver;topologyMergingSolver;globalTopologyGeneratorSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;exactGeometryDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;lengthMatchingPostProcessingSolver;powerTraceExpansionSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;componentDetectionSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;visualizationTraceColorMode;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;sharedEdgeSegmentsWithNecessaryCrampedPortPoints;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[iK(\"preprocessSimpleRouteJsonSolver\",_X,t=\u003e[t.originalSrj,{traceColorMode:t.visualizationTraceColorMode}],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),iK(\"componentDetectionSolver\",UZ,t=\u003e[{inputSrj:t.srj}]),iK(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),iK(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),iK(\"topologyPlanningSolver\",_q,t=\u003e[{inputSrj:t.srjWithPointPairs,componentDetectionOutput:t.componentDetectionSolver.getOutput(),viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.topologyPlanningSolver.getOutput();t.globalTopologyGeneratorSolver=t.topologyPlanningSolver.globalTopologySolver,t.componentTopologyGeneratorSolver=new vq(t.topologyPlanningSolver)}}),iK(\"topologyMergingSolver\",fq,t=\u003e{const e=t.topologyPlanningSolver.getOutput();return[{layerCount:t.srj.layerCount,nodeGroups:[{groupId:\"global\",nodes:e.globalMeshNodes,isComponent:!1},...e.componentMeshNodes.map((t,e)=\u003e({groupId:`component-${e}`,nodes:t,isComponent:!0}))]}]},{onSolved:t=\u003e{t.capacityNodes=t.topologyMergingSolver.getOutput()}}),iK(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver.outputNodes}}),iK(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),iK(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),iK(\"necessaryCrampedPortPointSolver\",sf,t=\u003e{const e=eK(t.capacityNodes);return[{capacityMeshNodes:t.capacityNodes.filter(t=\u003e!e.has(t.capacityMeshNodeId)),sharedEdgeSegments:oK({sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),componentCapacityMeshNodeIds:e}),simpleRouteJson:t.srjWithPointPairs}]},{onSolved:t=\u003e{const e=eK(t.capacityNodes);t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints=function({originalSharedEdgeSegments:t,filteredSharedEdgeSegments:e,componentCapacityMeshNodeIds:n}){const o=new Map(e.map(t=\u003e[t.edgeId,t]));return t.map(t=\u003enK(t,n)?t:o.get(t.edgeId)??t)}({originalSharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),filteredSharedEdgeSegments:t.necessaryCrampedPortPointSolver.getOutput(),componentCapacityMeshNodeIds:e})}}),iK(\"portPointPathingSolver\",jj,t=\u003e{const e=t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints??t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,preserveTerminalPcbPortIds:!0,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0,USE_SELECTIVE_RERIP_ROUTING:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),iK(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),iK(\"highDensityRouteSolver\",zs,t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length\u003e0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!0,growShrinkFallbackToInvalidGeometryOnFailure:!0,captureSearchDebug:!1}]}),iK(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),iK(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2,maxSampleEntries:80}]),iK(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,preserveTerminalPcbPortIds:!0}]),iK(\"traceSimplificationSolver\",vc,t=\u003e[{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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,enableCrossingViaReduction:!0,iterations:2}]),iK(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),iK(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:KJ(t.traceWidthSolver.getHdRoutesWithWidths(),t.netToPointPairsSolver?.newConnections??[],new Map((t.highDensityStitchSolver?.mergedHdRoutes??[]).map(t=\u003e[t.connectionName,t]))),connMap:t.connMap,effort:t.effort,maxIterations:16,enableLargeBoardBroadFallback:!1,enablePostSolveClearanceRelaxation:!1}]),iK(\"exactGeometryDrcForceImproveSolver\",wz,t=\u003e{const e=t.globalDrcForceImproveSolver.getOutput(),n=(t=\u003e{const e={...t.srjWithPointPairs,obstacles:t.originalSrj.obstacles,minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter??t.srjWithPointPairs.minViaDiameter},n=Math.max(Yo(t.originalSrj).padDiameter,e.minTraceWidth)+Math.max(.1,.1),o=new s_(e,{connMap:t.connMap,includeTraceViaOwnerMetadata:!0,traceClearance:.1,viaClearance:.1,spatialCellSize:n}),i=ZJ(t),r=t.originalSrj.traces??[];return({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline7 autorouting DRC evaluation requires HD routes\");const s=i(n),a=r.length?[...r,...s]:s;return o.evaluate(a)}})({connections:t.netToPointPairsSolver?.newConnections??[],originalConnections:t.originalSrj.connections,layerCount:t.srj.layerCount,obstacles:t.srj.obstacles,defaultViaHoleDiameter:t.viaHoleDiameter,connMap:t.connMap,srjWithPointPairs:t.srjWithPointPairs,originalSrj:t.originalSrj});return[{srj:t.srjWithPointPairs,hdRoutes:e,connMap:t.connMap,effort:t.effort,viaHoleDiameter:t.viaHoleDiameter,drcEvaluator:n,viaInPadDrcEvaluator:n,maxIterations:32,enableLargeBoardBroadFallback:!1,enableBroadFallback:!1,enableTargetedErrorSweep:!0,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:t.originalSrj.allowViaInPad??!1,viaInPadMaxIterations:32,broadMaxIterations:12,broadPassMultiplier:3}]}),iK(\"lengthMatchingPostProcessingSolver\",lU,t=\u003e{const e=t.netToPointPairsSolver;if(!e)throw new Error(\"Pipeline7: length-matching post-processing requires NetToPointPairsSolver output\");const n=e.newConnections,o=new Map;for(const e of t.srj.differentialPairs??[])for(const t of e.connectionNames){const e=n.filter(e=\u003ee.name===t||e.__rootConnectionNames?.includes(t)||e.__netConnectionName===t);if(1!==e.length)throw new Error(`Pipeline7: differential pair connection \"${t}\" must resolve to exactly one final point-pair connection, got ${e.length}`);o.set(t,e[0].name)}const i=t.exactGeometryDrcForceImproveSolver.getOutput(),r=(t.srj.differentialPairs??[]).map(t=\u003e{const e=t.connectionNames.map(t=\u003e{const e=o.get(t);if(!e)throw new Error(`Pipeline7: differential pair connection \"${t}\" is missing from final routed output`);return e});if(e[0]===e[1])throw new Error(`Pipeline7: differential pair ${t.connectionNames.join(\"/\")} resolves both members to \"${e[0]}\"`);if(void 0===t.traceGap)return{connectionNames:e,lengthTolerance:t.lengthTolerance,maxUncoupledLength:t.maxUncoupledLength};const n=e.map(t=\u003e{const e=i.filter(e=\u003ee.connectionName===t);if(1!==e.length)throw new Error(`Pipeline7: differential pair connection \"${t}\" must resolve to exactly one final HD route, got ${e.length}`);return e[0]}),r=t.traceGap+n.reduce((t,e)=\u003et+e.traceThickness/2,0);return{connectionNames:e,lengthTolerance:t.lengthTolerance,maxUncoupledLength:t.maxUncoupledLength,minimumCenterlineDistance:r,maximumCenterlineDistance:r}});return[{hdRoutes:i,differentialPairs:r,obstacles:t.srj.obstacles,bounds:t.srj.bounds,layerCount:t.srj.layerCount}]}),iK(\"powerTraceExpansionSolver\",UJ,t=\u003e{const e=t.opts.powerTraceExpansion??{},n=e.onlyConnectionNames??JJ(t.originalSrj);return[QJ({originalSrj:t.originalSrj,newlyRoutedTraces:t.getPrePowerTraceOutputSimplifiedPcbTraces(),expandedConnectionNames:n}),{allowNewVias:!1,...e,onlyConnectionNames:n}]})];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;computeProgress(){const t=this.activeSubSolver?.progress??0;return(this.currentPipelineStepIndex+t)/this.pipelineDef.length}_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\u0026\u0026(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),\"lengthMatchingPostProcessingSolver\"!==t.solverName\u0026\u0026\"powerTraceExpansionSolver\"!==t.solverName||(this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,this.iterations+this.activeSubSolver.MAX_ITERATIONS+1)),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\u0026\u0026this.activeSubSolver)return this.visualizeStage(this.activeSubSolver);const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.componentDetectionSolver?.visualize(),o=this.componentTopologyGeneratorSolver?.visualize(),i=this.globalTopologyGeneratorSolver?.visualize(),r=this.topologyMergingSolver?.visualize(),s=this.nodeDimensionSubdivisionSolver?.visualize(),a=this.nodeTargetMerger?.visualize(),c=this.singleLayerNodeMerger?.visualize(),l=this.strawSolver?.visualize(),d=this.edgeSolver?.visualize(),h=this.deadEndSolver?.visualize(),u=this.availableSegmentPointSolver?.visualize(),p=this.portPointPathingSolver?.visualize(),m=this.multiSectionPortPointOptimizer?.visualize(),g=this.uniformPortDistributionSolver?.visualize(),f=this.highDensityRouteSolver?.visualize(),y=this.highDensityForceImproveSolver?.visualize(),_=this.highDensityRepairSolver?.visualize(),b=this.highDensityStitchSolver?.visualize(),x=this.traceSimplificationSolver?.visualize(),v=this.lengthMatchingPostProcessingSolver?.visualize(),S=this.traceWidthSolver?.visualize(),I=this.necessaryCrampedPortPointSolver?.visualize(),C=(this.highDensityRouteSolver?.visualize(),this.originalSrj),P=C.outline,M=[];if(M.push({points:[{x:C.bounds?.minX??-50,y:C.bounds?.minY??-50},{x:C.bounds?.maxX??50,y:C.bounds?.minY??-50},{x:C.bounds?.maxX??50,y:C.bounds?.maxY??50},{x:C.bounds?.minX??-50,y:C.bounds?.maxY??50},{x:C.bounds?.minX??-50,y:C.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),P\u0026\u0026P.length\u003e=2){const t=P.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),M.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const N=Oo(C),w={points:[...C.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,C.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(C.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,C.layerCount),label:N(t)}))],lines:M},T={traceColorMode:this.visualizationTraceColorMode},R=Yj({srj:C,visualizationOptions:T}),E=pi(w,R),A=this.preprocessSimpleRouteJsonSolver?.visualize(),O=this.globalDrcForceImproveSolver?.visualize(),k=this.exactGeometryDrcForceImproveSolver?.visualize(),L=[E,A,n,o,t,e,i,r,s,a,c,l,d,h,u,I,p,m,g,f?pi(w,f):null,y,_,b,x,S,O,k,v,this.solved?pi({lines:M},Yj({srj:this.originalSrj,visualizationOptions:T}),this.visualizeFinalOutput()):null].filter(Boolean),D=pi(...L);return\"net\"===this.visualizationTraceColorMode?xq(D,this.colorMap):D}visualizeStage(t){const e=t.visualize();return\"net\"===this.visualizationTraceColorMode?xq(e,this.colorMap):e}visualizeFinalOutput(){const t=this.visualizationTraceColorMode,e=this.getOutputSimpleRouteJson();return Ho(e,{traceColorMode:t})}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.componentTopologyGeneratorSolver?this.componentTopologyGeneratorSolver.visualize():this.componentDetectionSolver?this.componentDetectionSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){if(this.lengthMatchingPostProcessingSolver){const{hdRoutes:t}=this.lengthMatchingPostProcessingSolver.getOutput();return t}return this.exactGeometryDrcForceImproveSolver?.getOutput()??this.globalDrcForceImproveSolver?.getOutput()??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\");return this.powerTraceExpansionSolver?this.powerTraceExpansionSolver.getOutput():this.getPrePowerTraceOutputSimplifiedPcbTraces()}getPrePowerTraceOutputSimplifiedPcbTraces(){return qJ({connections:this.netToPointPairsSolver?.newConnections??[],originalConnections:this.originalSrj.connections,hdRoutes:this._getOutputHdRoutes(),layerCount:this.srj.layerCount,obstacles:this.srj.obstacles,defaultViaHoleDiameter:this.viaHoleDiameter,connMap:this.connMap})}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},sK=t=\u003e[...new Set(t)].sort((t,e)=\u003et-e),aK=class extends si{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1}params;outputNodes=[];outputSharedEdgeSegments=[];nodeIdByOriginalAndZ=new Map;getSolverName(){return\"SplitNodesIntoSingleLayerNodeSolver\"}_step(){this.outputNodes=this.params.capacityMeshNodes.flatMap(t=\u003esK(t.availableZ).map(e=\u003e{const n=((t,e)=\u003e`${t}__z${e}`)(t.capacityMeshNodeId,e);return this.nodeIdByOriginalAndZ.set(`${t.capacityMeshNodeId}:${e}`,n),{...t,capacityMeshNodeId:n,layer:`z${e}`,availableZ:[e],_parent:t}})),this.outputSharedEdgeSegments=this.params.sharedEdgeSegments.flatMap(t=\u003ethis.splitSharedEdgeSegment(t)),this.stats={inputNodeCount:this.params.capacityMeshNodes.length,outputNodeCount:this.outputNodes.length,inputPortPointCount:this.params.sharedEdgeSegments.reduce((t,e)=\u003et+e.portPoints.length,0),outputPortPointCount:this.outputSharedEdgeSegments.reduce((t,e)=\u003et+e.portPoints.length,0)},this.solved=!0}getSplitNodeId(t,e){return this.nodeIdByOriginalAndZ.get(`${t}:${e}`)}splitPortPoint(t){return sK(t.availableZ).flatMap(e=\u003e{const n=t.nodeIds.map(t=\u003ethis.getSplitNodeId(t,e));return n[0]\u0026\u0026n[1]?[{...t,segmentPortPointId:`${t.segmentPortPointId}__z${e}`,availableZ:[e],nodeIds:[n[0],n[1]]}]:[]})}splitSharedEdgeSegment(t){const e=new Map;for(const n of t.portPoints.flatMap(t=\u003ethis.splitPortPoint(t))){const t=n.availableZ[0];if(void 0===t)continue;const o=e.get(t)??[];o.push(n),e.set(t,o)}return[...e.entries()].map(([e,n])=\u003e({...t,edgeId:`${t.edgeId}__z${e}`,nodeIds:n[0].nodeIds,availableZ:[e],portPoints:n}))}getOutput(){return{capacityMeshNodes:this.outputNodes,sharedEdgeSegments:this.outputSharedEdgeSegments}}getConstructorParams(){return[this.params]}visualize(){return{rects:this.outputNodes.map(t=\u003e({...Dc(t),label:`${t.capacityMeshNodeId}\\n${t.layer}`})),points:this.outputSharedEdgeSegments.flatMap(t=\u003et.portPoints.map(t=\u003e({x:t.x,y:t.y,label:`${t.segmentPortPointId}\\nz${t.availableZ.join(\",\")}`})))}}};function cK(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var lK=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;nodeSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityForceImproveRoutes;highDensityRepairSolver;highDensityRepairRoutes;highDensityStitchSolver;globalDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;splitNodesIntoSingleLayerNodeSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[cK(\"preprocessSimpleRouteJsonSolver\",_X,t=\u003e[t.originalSrj],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),cK(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),cK(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),cK(\"nodeSolver\",Kn,t=\u003e[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=\u003e{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),cK(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver?.outputNodes??[]}}),cK(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),cK(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),cK(\"necessaryCrampedPortPointSolver\",sf,t=\u003e[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),cK(\"splitNodesIntoSingleLayerNodeSolver\",aK,t=\u003e[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput()}],{onSolved:t=\u003e{t.capacityNodes=t.splitNodesIntoSingleLayerNodeSolver.getOutput().capacityMeshNodes}}),cK(\"portPointPathingSolver\",jj,t=\u003e{const e=t.splitNodesIntoSingleLayerNodeSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:e.capacityMeshNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.sharedEdgeSegments.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections,assignableViaObstacles:t.originalSrj.obstacles});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),cK(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),cK(\"highDensityRouteSolver\",zs,t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length\u003e0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]}),cK(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.getHighDensityNodePortPointsWithAssignableViasFirst(),hdRoutes:t.getMovableHighDensityRoutes(t.highDensityRouteSolver.routes),colorMap:t.colorMap,totalStepsPerNode:Math.max(20,Math.round(60*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}],{onSolved:t=\u003e{t.highDensityForceImproveRoutes=t.mergeMovableHighDensityRoutesBack(t.highDensityRouteSolver.routes,t.highDensityForceImproveSolver.getOutput())}}),cK(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.getHighDensityNodePortPointsWithAssignableViasFirst(),hdRoutes:t.getMovableHighDensityRoutes(t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes),obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2}],{onSolved:t=\u003e{const e=t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes;t.highDensityRepairRoutes=t.mergeMovableHighDensityRoutesBack(e,t.highDensityRepairSolver.getOutput())}}),cK(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairRoutes??t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,allowedLayerTransitionPointKeys:uf(t.originalSrj.obstacles)}]),cK(\"traceSimplificationSolver\",vc,t=\u003e[{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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,iterations:2}]),cK(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),cK(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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\u0026\u0026(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\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.nodeSolver?.visualize(),o=this.nodeDimensionSubdivisionSolver?.visualize(),i=this.nodeTargetMerger?.visualize(),r=this.singleLayerNodeMerger?.visualize(),s=this.strawSolver?.visualize(),a=this.edgeSolver?.visualize(),c=this.deadEndSolver?.visualize(),l=this.availableSegmentPointSolver?.visualize(),d=this.splitNodesIntoSingleLayerNodeSolver?.visualize(),h=this.portPointPathingSolver?.visualize(),u=this.multiSectionPortPointOptimizer?.visualize(),p=this.uniformPortDistributionSolver?.visualize(),m=this.highDensityRouteSolver?.visualize(),g=this.highDensityForceImproveSolver?.visualize(),f=this.highDensityRepairSolver?.visualize(),y=this.highDensityStitchSolver?.visualize(),_=this.traceSimplificationSolver?.visualize(),b=this.necessaryCrampedPortPointSolver?.visualize(),x=(this.highDensityRouteSolver?.visualize(),this.originalSrj),v=x.outline,S=[];if(S.push({points:[{x:x.bounds?.minX??-50,y:x.bounds?.minY??-50},{x:x.bounds?.maxX??50,y:x.bounds?.minY??-50},{x:x.bounds?.maxX??50,y:x.bounds?.maxY??50},{x:x.bounds?.minX??-50,y:x.bounds?.maxY??50},{x:x.bounds?.minX??-50,y:x.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),v\u0026\u0026v.length\u003e=2){const t=v.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),S.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const I=Oo(x),C={points:[...x.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,x.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(x.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,x.layerCount),label:I(t)}))],lines:S},P=Yj({srj:x}),M=[pi(C,P),t,e,n,o,i,r,s,a,c,l,b,d,h,u,p,m?pi(C,m):null,g,f,y,_,this.solved?pi({lines:S},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...M)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){const t=this.globalDrcForceImproveSolver?.getOutput();return t\u0026\u0026this.routesOnlyUsePreplacedVias(t)?t:this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityRepairRoutes??this.highDensityForceImproveRoutes??this.highDensityStitchSolver.mergedHdRoutes}routesOnlyUsePreplacedVias(t){const e=uf(this.originalSrj.obstacles);return 0===e.size||t.every(t=\u003et.vias.every(t=\u003ee.has(af(t))))}getHighDensityNodePortPointsWithAssignableViasFirst(){return[...this.highDensityNodePortPoints??[]].sort((t,e)=\u003e{const n=t.capacityMeshNodeId.startsWith(\"assignable-via:\");return n===e.capacityMeshNodeId.startsWith(\"assignable-via:\")?0:n?-1:1})}getPreplacedAssignableViaObstacles(){return this.originalSrj.obstacles.filter(t=\u003e!0===t.netIsAssignable\u0026\u0026(t.layers?.length??0)\u003e1)}isFixedPreplacedViaRoute(t){const e=this.getPreplacedAssignableViaObstacles();return 0!==e.length\u0026\u00260!==t.vias.length\u0026\u0026e.some(e=\u003e[...t.route,...t.vias].every(t=\u003eBe(t,e)\u003c=0))}getMovableHighDensityRouteIndexes(t){return t.map((t,e)=\u003ethis.isFixedPreplacedViaRoute(t)?-1:e).filter(t=\u003e-1!==t)}getMovableHighDensityRoutes(t){return this.getMovableHighDensityRouteIndexes(t).map(e=\u003et[e])}mergeMovableHighDensityRoutesBack(t,e){const n=this.getMovableHighDensityRouteIndexes(t),o=[...t];for(let t=0;t\u003cn.length;t++)o[n[t]]=e[t];return o}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 o=n.__netConnectionName??this.originalSrj.connections.find(t=\u003et.name===n.name)?.__netConnectionName,i=e.filter(t=\u003et.connectionName===n.name);for(let e=0;e\u003ci.length;e++){const r=i[e],s={type:\"pcb_trace\",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.srj.obstacles,connMap:this.connMap})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},dK=(t,e)=\u003e{const n=t.filter(t=\u003e(t.rootConnectionName??t.connectionName)===e);if(0!==n.length)return n.reduce((t,e)=\u003et+e.route.slice(1).reduce((t,n,o)=\u003e{const i=e.route[o];return t+Math.hypot(n.x-i.x,n.y-i.y)},0),0)},hK=(t,e)=\u003e{const n=new Set(t.flatMap(t=\u003evoid 0===t.maxLengthSkew?[]:t.connectionNames));return e.flatMap(t=\u003e{if(!n.has(t.name))return[];const e=t.pointsToConnect[0],o=t.pointsToConnect.at(-1);if(!e||!o||e===o)throw new Error(`Length matching: bus connection \"${t.name}\" needs at least two points`);return[{...t,pointsToConnect:[e,o]}]})},uK=class extends si{constructor(t){super(),this.params=t,this.differentialPairSolver=new lU({hdRoutes:t.hdRoutes,differentialPairs:t.differentialPairs,obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,minTraceToPadEdgeClearance:t.obstacleMargin}),this.MAX_ITERATIONS=this.differentialPairSolver.MAX_ITERATIONS+1e5+10}params;differentialPairSolver;busLengthMatchingSolver;outputHdRoutes;getSolverName(){return\"LengthMatchingPostProcessingSolver\"}_step(){if(!this.differentialPairSolver.solved)return this.differentialPairSolver.step(),void(this.differentialPairSolver.failed\u0026\u0026(this.failed=!0,this.error=this.differentialPairSolver.error));if(!this.busLengthMatchingSolver){const n=this.differentialPairSolver.getOutput().hdRoutes,o=(t=this.params.buses,e=n,t.flatMap(t=\u003e{const n=t.maxLengthSkew;if(void 0===n||t.connectionNames.length\u003c2)return[];const o=t.connectionNames.map(n=\u003e{const o=dK(e,n);if(void 0===o)throw new Error(`Length matching: bus \"${t.busId}\" has no routed geometry for connection \"${n}\"`);return{connectionName:n,length:o}}),i=o.reduce((t,e)=\u003ee.length\u003et.length?e:t);return o.flatMap(t=\u003et.connectionName===i.connectionName?[]:[{connectionNames:[t.connectionName,i.connectionName],lengthTolerance:n}])}));return 0===o.length?(this.outputHdRoutes=n,void(this.solved=!0)):void(this.busLengthMatchingSolver=new RG({hdRoutes:n,originalConnections:hK(this.params.buses,this.params.connections),differentialPairs:o,obstacles:this.params.obstacles,bounds:this.params.bounds,layerCount:this.params.layerCount,obstacleMargin:this.params.obstacleMargin}))}var t,e;if(this.busLengthMatchingSolver.step(),this.busLengthMatchingSolver.failed)return this.failed=!0,void(this.error=this.busLengthMatchingSolver.error);this.busLengthMatchingSolver.solved\u0026\u0026(this.outputHdRoutes=this.busLengthMatchingSolver.getOutput().matchedHdRoutes,((t,e)=\u003e{for(const n of t){if(void 0===n.maxLengthSkew||n.connectionNames.length\u003c2)continue;const t=n.connectionNames.map(t=\u003e{const o=dK(e,t);if(void 0===o)throw new Error(`Length matching: bus \"${n.busId}\" lost routed geometry for connection \"${t}\"`);return o}),o=Math.max(...t)-Math.min(...t);if(o\u003en.maxLengthSkew+1e-6)throw new Error(`Length matching: bus \"${n.busId}\" routed length skew ${o.toFixed(4)}mm exceeds ${n.maxLengthSkew.toFixed(4)}mm`)}})(this.params.buses,this.outputHdRoutes),this.solved=!0)}getOutput(){if(!this.solved||!this.outputHdRoutes)throw new Error(\"LengthMatchingPostProcessingSolver output requested before completion\");return{hdRoutes:this.outputHdRoutes}}visualize(){return this.busLengthMatchingSolver?.visualize()??this.differentialPairSolver.visualize()}},pK=1e-9,mK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=pK\u0026\u0026Math.abs(t.y-e.y)\u003c=pK\u0026\u0026t.z===e.z,gK=(t,e)=\u003e{if(0===t.length)return void t.push(...e.route);const n=t.at(-1);if(e.route[0]\u0026\u0026mK(n,e.route[0]))t.push(...e.route.slice(1));else{if(!e.route.at(-1)||!mK(n,e.route.at(-1)))throw new Error(`Pipeline9 could not reconnect mutated preloaded segment \"${e.connectionName}\"`);t.push(...e.route.slice(0,-1).reverse())}},fK=(t,e)=\u003e{const n=t.preloadedRoutePositionStart??t.preloadedRouteIndex,o=e.preloadedRoutePositionStart??e.preloadedRouteIndex,i=t.preloadedRoutePositionEnd??n,r=e.preloadedRoutePositionEnd??o;return n-o||i-r||t.preloadedRouteIndex-e.preloadedRouteIndex||t.connectionName.localeCompare(e.connectionName)},yK=t=\u003e{const e=t.route.flatMap(t=\u003e\"wire\"===t.route_type||\"through_obstacle\"===t.route_type?[t.width]:[]);return e.length\u003e0?Math.max(...e):void 0},_K=({trace:t,updatedTraceRoutes:e,layerCount:n,defaultViaHoleDiameter:o,obstacles:i,connMap:r})=\u003e{if(0===e.length)throw new Error(`Pipeline9 lost every fixed route for mutated trace \"${t.pcb_trace_id}\"`);const s=[];let a,c=0,l=0;for(const t of[...e].sort(fK))gK(s,t),c=Math.max(c,t.traceThickness),l=Math.max(l,t.viaDiameter),a??=t.rootConnectionName;const d={connectionName:t.connection_name,rootConnectionName:a,traceThickness:yK(t)??c,viaDiameter:l,route:s,vias:s.slice(0,-1).flatMap((t,e)=\u003e{const n=s[e+1];return t.z!==n.z\u0026\u0026Math.abs(t.x-n.x)\u003c=pK\u0026\u0026Math.abs(t.y-n.y)\u003c=pK?[{x:n.x,y:n.y}]:[]})};return Mo(d,n,{defaultViaHoleDiameter:o,obstacles:i,connMap:r})},bK=(t,e)=\u003et.filter(t=\u003e{if(!0===t.isThroughObstacle)return!1;const n=t.preloadedRoutePositionStart,o=t.preloadedRoutePositionEnd;if(void 0===n||void 0===o)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" is missing route-position metadata`);const i=Math.min(n,o),r=Math.max(n,o);return i\u003e=e.routePositionStart-pK\u0026\u0026r\u003c=e.routePositionEnd+pK}),xK=({trace:t,originalTraceRoutes:e,updatedTraceRoutes:n,layerCount:o,defaultViaHoleDiameter:i,obstacles:r,connMap:s})=\u003e{if(0===n.length)throw new Error(`Pipeline9 lost every fixed route for mutated trace \"${t.pcb_trace_id}\"`);const a=(t=\u003e{const e=[];let n=0;for(let o=0;o\u003ct.route.length;o++)\"through_obstacle\"===t.route[o]?.route_type\u0026\u0026(n\u003co\u0026\u0026e.push({routePositionStart:n,routePositionEnd:o-1}),n=o+1);return n\u003ct.route.length\u0026\u0026e.push({routePositionStart:n,routePositionEnd:t.route.length-1}),e})(t),c=n.filter(t=\u003e!0!==t.isThroughObstacle);for(const t of c){if(1!==a.filter(e=\u003ebK([t],e).includes(t)).length)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" crosses an immutable through-obstacle primitive`)}const l=[];let d=0;for(const c of a){l.push(...t.route.slice(d,c.routePositionStart));const a=bK(e,c),h=bK(n,c);if(a.length\u003e0\u0026\u00260===h.length)throw new Error(`Pipeline9 lost every fixed route for an ordinary section of mutated trace \"${t.pcb_trace_id}\"`);l.push(...h.length\u003e0?_K({trace:t,updatedTraceRoutes:h,layerCount:o,defaultViaHoleDiameter:i,obstacles:r,connMap:s}):t.route.slice(c.routePositionStart,c.routePositionEnd+1)),d=c.routePositionEnd+1}return l.push(...t.route.slice(d)),l},vK=(t,e)=\u003e{const n=new Set(e.map(t=\u003et.pcb_trace_id));return t.map(t=\u003e{if(!n.has(t.pcb_trace_id))return n.add(t.pcb_trace_id),t;const e=`${t.pcb_trace_id}_routed`;let o=e,i=2;for(;n.has(o);)o=`${e}_${i}`,i+=1;return n.add(o),{...t,pcb_trace_id:o}})},SK=(t,e,n)=\u003e{const o=t=\u003e`${t.x}:${t.y}`,i=new Map;for(const t of e){const e=o(t.center),n=i.get(e)??[];n.push(t),i.set(e,n)}const r=new Map;for(const e of t)for(const t of e.pointsToConnect){if(!t.pcb_port_id)continue;const e=r.get(t.pcb_port_id)??new Set,s=\"layers\"in t?t.layers:[t.layer];for(const t of s)e.add(ko(t,n));for(const r of i.get(o(t))??[])if(!(r.layers.length\u003c=1)\u0026\u0026r.connectedTo.includes(t.pcb_port_id))for(const t of r.layers)e.add(ko(t,n));r.set(t.pcb_port_id,e)}return r},IK=(t,e)=\u003enew Map(t.flatMap(t=\u003e{const n=e.getNetConnectedToId(t.connectionName)??(t.rootConnectionName?e.getNetConnectedToId(t.rootConnectionName)??(e.netMap[t.rootConnectionName]?t.rootConnectionName:void 0):void 0);return n?[[t.connectionName,n]]:[]})),CK=1e-9,PK=1e-6,MK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=PK\u0026\u0026Math.abs(t.y-e.y)\u003c=PK\u0026\u0026t.z===e.z,NK=t=\u003enew Map(t.map((t,e)=\u003e[t.pcb_trace_id,e])),wK=(t,e)=\u003e{const n=t[0],o=t.at(-1);if(!n||!o)throw new Error(\"Pipeline9 cannot split an empty preloaded route\");if(n.z!==o.z)throw new Error(\"Pipeline9 cannot partially split a preloaded layer transition\");return{...n,x:n.x+(o.x-n.x)*e,y:n.y+(o.y-n.y)*e}},TK=({traces:t,fixedHdRoutes:e,sections:n})=\u003e{const o=(({traces:t,sections:e})=\u003e{const n=NK(t),o=new Map;for(const t of e){const e=n.get(t.traceId);if(void 0===e)throw new Error(`Pipeline9 hypergraph changed missing preloaded trace \"${t.traceId}\"`);const i=o.get(e)??[];i.push({start:Math.min(t.startRoutePosition,t.endRoutePosition),end:Math.max(t.startRoutePosition,t.endRoutePosition)}),o.set(e,i)}for(const t of o.values())t.sort((t,e)=\u003et.start-e.start||t.end-e.end);return o})({traces:t,sections:n});return e.flatMap(t=\u003e{const e=o.get(t.preloadedTraceIndex);if(!e?.length)return[t];const n=t.preloadedRoutePositionStart,i=t.preloadedRoutePositionEnd;if(void 0===n||void 0===i)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" is missing route-position metadata`);if(Math.abs(i-n)\u003c=CK)return e.some(t=\u003et.start-CK\u003c=n\u0026\u0026n\u003c=t.end+CK)?[]:[t];let r=[{start:n,end:i}];for(const t of e)r=r.flatMap(e=\u003e{if(t.end\u003c=e.start+CK||t.start\u003e=e.end-CK)return[e];const n=[];return t.start\u003ee.start+CK\u0026\u0026n.push({start:e.start,end:Math.min(t.start,e.end)}),t.end\u003ce.end-CK\u0026\u0026n.push({start:Math.max(t.end,e.start),end:e.end}),n});return r.map((e,o)=\u003e{const r=(e.start-n)/(i-n),s=(e.end-n)/(i-n);return{...t,connectionName:`${t.connectionName}_hypergraph_fixed_${o}`,preloadedRoutePositionStart:e.start,preloadedRoutePositionEnd:e.end,route:[wK(t.route,r),wK(t.route,s)],vias:[]}})})},RK=({traces:t,sections:e,stitchedHdRoutes:n,layerCount:o})=\u003e{const i=NK(t);return e.map((t,r)=\u003e{const s=i.get(t.traceId);if(void 0===s)throw new Error(`Pipeline9 cannot materialize missing preloaded trace \"${t.traceId}\"`);const[a,c]=((t,e)=\u003e{const n=t.connection.pointsToConnect.map(t=\u003e({x:t.x,y:t.y,z:ko(bo(t),e)}));if(!n[0]||!n[1])throw new Error(`Pipeline9 changed section \"${t.connectionName}\" is missing an endpoint`);return[n[0],n[1]]})(t,o),l=n.flatMap(e=\u003e{if(e.connectionName!==t.connectionName)return[];const n=(({route:t,sectionStart:e,sectionEnd:n})=\u003e{const o=t.route[0],i=t.route.at(-1);if(!o||!i)return null;const r=o.z===e.z\u0026\u0026i.z===n.z,s=o.z===n.z\u0026\u0026i.z===e.z,a=r?xe(o,e)+xe(i,n):Number.POSITIVE_INFINITY,c=s?xe(o,n)+xe(i,e):Number.POSITIVE_INFINITY;return Number.isFinite(a)||Number.isFinite(c)?a\u003c=c?{score:a,reverse:!1}:{score:c,reverse:!0}:null})({route:e,sectionStart:a,sectionEnd:c});return n?[{route:e,...n}]:[]});l.sort((t,e)=\u003et.score-e.score);const d=l[0],h=l[1];if(!d||h\u0026\u0026Math.abs(h.score-d.score)\u003c=PK)throw new Error(`Pipeline9 expected one nearest stitched route for changed preloaded section \"${t.connectionName}\", got ${l.length}`);const u=(({route:t,reverse:e,sectionStart:n,sectionEnd:o})=\u003e{const i=e?(t=\u003e{const e=[...t].reverse().map(t=\u003e{const{toNextSegmentType:e,...n}=t;return n});for(let n=0;n\u003ct.length-1;n++){const o=t[n]?.toNextSegmentType;o\u0026\u0026(e[t.length-n-2]={...e[t.length-n-2],toNextSegmentType:o})}return e})(t.route):[...t.route];if(!i[0]||!i.at(-1))throw new Error(`Pipeline9 cannot materialize empty route \"${t.connectionName}\"`);return MK(i[0],n)||i.unshift(n),MK(i.at(-1),o)||i.push(o),{...t,route:i}})({route:d.route,reverse:d.reverse,sectionStart:a,sectionEnd:c});return{...u,preloadedTraceIndex:s,preloadedRouteIndex:Number.MAX_SAFE_INTEGER-e.length+r,preloadedRoutePositionStart:t.startRoutePosition,preloadedRoutePositionEnd:t.endRoutePosition,isThroughObstacle:!1}})},EK=1e-6,AK=t=\u003et.map(t=\u003e{const e=[];for(const n of t.route){const o=e.at(-1);if(!o||o.z===n.z||\"through_obstacle\"===o.toNextSegmentType){e.push(n);continue}const i=Math.abs(o.x-n.x)\u003c=EK\u0026\u0026Math.abs(o.y-n.y)\u003c=EK,r=t.vias.some(t=\u003eMath.abs(t.x-o.x)\u003c=EK\u0026\u0026Math.abs(t.y-o.y)\u003c=EK),s=t.vias.some(t=\u003eMath.abs(t.x-n.x)\u003c=EK\u0026\u0026Math.abs(t.y-n.y)\u003c=EK);if(i)e.push(n);else{if(!r\u0026\u0026!s)throw new Error(`Pipeline9 route \"${t.connectionName}\" changes layers from z=${o.z} to z=${n.z} without an explicit via`);if(r===s)throw new Error(`Pipeline9 route \"${t.connectionName}\" has an ambiguous layer transition between (${o.x}, ${o.y}) and (${n.x}, ${n.y})`);r?e.push({x:o.x,y:o.y,z:n.z}):e.push({x:n.x,y:n.y,z:o.z}),e.push(n)}}return{...t,route:e}}),OK=1e-9,kK=t=\u003e({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}),LK=(t,e)=\u003et.x\u003e=e.minX-OK\u0026\u0026t.x\u003c=e.maxX+OK\u0026\u0026t.y\u003e=e.minY-OK\u0026\u0026t.y\u003c=e.maxY+OK,DK=(t,e,n)=\u003en\u003c=OK?t:n\u003e=.999999999?e:{x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n,z:t.z},zK=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;if(Math.abs(o)\u003c=OK\u0026\u0026Math.abs(i)\u003c=OK)return LK(t,n)\u0026\u0026LK(e,n)?{start:t,end:e}:null;let r=0,s=1;const a=[[-o,t.x-n.minX],[o,n.maxX-t.x],[-i,t.y-n.minY],[i,n.maxY-t.y]];for(const[t,e]of a){if(Math.abs(t)\u003c=OK){if(e\u003c0)return null;continue}const n=e/t;if(t\u003c0?r=Math.max(r,n):s=Math.min(s,n),r\u003es+OK)return null}return{start:DK(t,e,r),end:DK(t,e,s)}},FK=t=\u003e{const e=t.sourceRoutes[0],n=`pipeline9_fallback:${e.connectionName}`,o=`${n}:start`,i=`${n}:end`;return[{...t.start.point,portPointId:o,nextPortPointId:i,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName},{...t.end.point,portPointId:i,prevPortPointId:o,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName}]},BK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=OK\u0026\u0026Math.abs(t.y-e.y)\u003c=OK\u0026\u0026t.z===e.z,jK=(t,e)=\u003et.sourceRoute.preloadedTraceIndex===e.sourceRoute.preloadedTraceIndex\u0026\u0026BK(t.sourceRoute.route.at(-1),e.sourceRoute.route[0]),$K=(t,e,n=new Set)=\u003e{const o=new Map,i=[],r=new Set(t.portPoints.map(t=\u003et.z)),s=e.map(e=\u003e((t,e)=\u003e{const n=kK(e);let o,i;for(let e=0;e\u003ct.route.length-1;e++){const r=zK(t.route[e],t.route[e+1],n);r\u0026\u0026(o??={segmentIndex:e,point:r.start},i={segmentIndex:e,point:r.end})}return o\u0026\u0026i?Math.abs(o.point.x-i.point.x)\u003c=OK\u0026\u0026Math.abs(o.point.y-i.point.y)\u003c=OK\u0026\u0026o.point.z===i.point.z?null:{sourceRoute:t,start:o,end:i}:null})(e,t)).filter(t=\u003enull!==t),a=s.filter(t=\u003e!0!==t.sourceRoute.isThroughObstacle\u0026\u0026(((t,e)=\u003e0===e.size||[t.start.point,...t.sourceRoute.route.slice(t.start.segmentIndex+1,t.end.segmentIndex+1),t.end.point].some(t=\u003ee.has(t.z)))(t,r)||n.has(t.sourceRoute.connectionName))).sort((t,e)=\u003et.sourceRoute.preloadedTraceIndex-e.sourceRoute.preloadedTraceIndex||t.sourceRoute.preloadedRouteIndex-e.sourceRoute.preloadedRouteIndex),c=new Set(a.map(t=\u003et.sourceRoute)),l=s.map(t=\u003et.sourceRoute).filter(t=\u003e!c.has(t)),d=[];for(let t=0;t\u003ca.length;t++){const e=a[t],n=a[t-1],o=d.at(-1);n\u0026\u0026o\u0026\u0026jK(n,e)?(o.sourceRoutes.push(e.sourceRoute),o.end=e.end):d.push({sourceRoutes:[e.sourceRoute],start:e.start,end:e.end})}for(const t of d){const e=t.sourceRoutes[0].connectionName;if(o.has(e))throw new Error(`Pipeline9 regional fallback found duplicate fixed route section identity \"${e}\"`);o.set(e,t),i.push(FK(t))}return{nodeWithPortPoints:{...t,portPoints:[...t.portPoints,...i.flatMap(t=\u003et)],portPointsInPairs:[...t.portPointsInPairs??[],...i]},fixedRouteSectionsByConnectionName:o,fixedObstacleRoutes:l}},YK=t=\u003e{const e=[];for(let n=0;n\u003ct.length-1;n++){const o=t[n],i=t[n+1];o.z!==i.z\u0026\u0026Math.abs(o.x-i.x)\u003c=OK\u0026\u0026Math.abs(o.y-i.y)\u003c=OK\u0026\u0026e.push({x:i.x,y:i.y})}return e},XK=(t,e)=\u003eVK({section:t,replacement:e,sourceMutationMasks:new Map,replacementIsMutated:!1}).route,VK=({section:t,replacement:e,sourceMutationMasks:n,replacementIsMutated:o})=\u003e{const i=t.sourceRoutes[0],r=t.sourceRoutes.at(-1),s=((t,e)=\u003e{const n=t.route,o=n[0],i=n.at(-1);if(!o||!i)throw new Error(`Pipeline9 regional fallback produced an empty replacement for \"${e.sourceRoutes[0].connectionName}\"`);const r=Math.hypot(o.x-e.start.point.x,o.y-e.start.point.y)+Math.hypot(i.x-e.end.point.x,i.y-e.end.point.y);return Math.hypot(i.x-e.start.point.x,i.y-e.start.point.y)+Math.hypot(o.x-e.end.point.x,o.y-e.end.point.y)\u003cr?[...n].reverse():n})(e,t),a=[],c=[],l=(t,e)=\u003e{const o=n.get(t.connectionName);if(o\u0026\u0026o.length!==t.route.length-1)throw new Error(`Pipeline9 fixed route mutation mask for \"${t.connectionName}\" has ${o.length} segments, expected ${t.route.length-1}`);return o?.[e]??!1},d=(t,e)=\u003e{const n=a.at(-1);if(n){if(!BK(n,t)){if(n.z!==t.z\u0026\u0026(Math.abs(n.x-t.x)\u003eOK||Math.abs(n.y-t.y)\u003eOK)){const o={...t,z:n.z};BK(n,o)||(a.push(o),c.push(e))}BK(a.at(-1),t)||(a.push(t),c.push(e))}}else a.push(t)};d(i.route[0],!1);for(let e=1;e\u003c=t.start.segmentIndex;e++)d(i.route[e],l(i,e-1));d(t.start.point,l(i,t.start.segmentIndex));const h=c.length;for(const t of s.slice(1,-1))d(t,o);d(t.end.point,o);const u=c.length\u003eh;for(let e=t.end.segmentIndex+1;e\u003cr.route.length;e++)d(r.route[e],l(r,e-1));if(c.length!==a.length-1)throw new Error(`Pipeline9 produced an invalid mutation mask while splicing \"${i.connectionName}\"`);return{route:{...i,preloadedRoutePositionStart:i.preloadedRoutePositionStart,preloadedRoutePositionEnd:r.preloadedRoutePositionEnd,traceThickness:Math.max(...t.sourceRoutes.map(t=\u003et.traceThickness)),viaDiameter:Math.max(...t.sourceRoutes.map(t=\u003et.viaDiameter)),route:a,vias:YK(a)},mutatedSegments:c,replacementProducedSegment:u}},WK=1e-6,HK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=WK\u0026\u0026Math.abs(t.y-e.y)\u003c=WK\u0026\u0026t.z===e.z,GK=(t,e)=\u003e{for(const n of e)t.at(-1)\u0026\u0026HK(t.at(-1),n)||t.push(n)},UK=t=\u003et.slice(0,-1).flatMap((e,n)=\u003e{const o=t[n+1];return e.z!==o.z\u0026\u0026Math.abs(e.x-o.x)\u003c=WK\u0026\u0026Math.abs(e.y-o.y)\u003c=WK?[{x:o.x,y:o.y}]:[]}),ZK=t=\u003e{const e=t.preloadedRoutePositionStart,n=t.preloadedRoutePositionEnd;if(void 0===e||void 0===n)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" is missing route-position metadata`);return{start:Math.min(e,n),end:Math.max(e,n)}},qK=(t,e)=\u003e{const n=ZK(t),o=ZK(e);return t.preloadedTraceIndex-e.preloadedTraceIndex||n.start-o.start||n.end-o.end||t.preloadedRouteIndex-e.preloadedRouteIndex||t.connectionName.localeCompare(e.connectionName)},JK=(t,e)=\u003e{const n=t.route.at(-1),o=e.route[0];return Boolean(n\u0026\u0026o\u0026\u0026t.preloadedTraceIndex===e.preloadedTraceIndex\u0026\u0026HK(n,o))},KK=(t,e)=\u003e{const n=t.preloadedRoutePositionStart??t.preloadedRouteIndex;return n+((t.preloadedRoutePositionEnd??t.preloadedRouteIndex)-n)*e/(t.route.length-1)},QK=(t,e)=\u003et.route[e].z!==t.route[e+1].z,tQ=({updatedFixedRoutes:t,regionalMutationMasks:e})=\u003e{const n=[],o=(({updatedFixedRoutes:t,regionalMutationMasks:e})=\u003e{const n=new Map;for(const o of t){if(0===o.route.length)throw new Error(`Pipeline9 cannot normalize empty fixed route \"${o.connectionName}\"`);const t=o.route.length-1;if(n.has(o.connectionName))throw new Error(`Pipeline9 cannot normalize duplicate fixed route \"${o.connectionName}\"`);const i=e.get(o.connectionName);if(i\u0026\u0026i.length!==t)throw new Error(`Pipeline9 fixed route mutation mask for \"${o.connectionName}\" has ${i.length} segments, expected ${t}`);const r=!0!==o.isThroughObstacle\u0026\u00260===(o.jumpers?.length??0);n.set(o.connectionName,Array.from({length:t},(t,e)=\u003er\u0026\u0026(i?.[e]??!1)))}let o=[];const i=()=\u003e{for(;o[0]\u0026\u0026QK(o[0].route,o[0].segmentIndex);){const t=o.shift();n.get(t.route.connectionName)[t.segmentIndex]=!1}for(;o.at(-1)\u0026\u0026QK(o.at(-1).route,o.at(-1).segmentIndex);){const t=o.pop();n.get(t.route.connectionName)[t.segmentIndex]=!1}o=[]};let r;for(const e of[...t].sort(qK)){r\u0026\u0026!JK(r,e)\u0026\u0026i();const t=n.get(e.connectionName);if(0!==t.length){for(let n=0;n\u003ct.length;n++)t[n]?o.push({route:e,segmentIndex:n}):i();r=e}else i(),r=e}return i(),n})({updatedFixedRoutes:t,regionalMutationMasks:e});for(const e of t){const t=e.route.length-1,i=o.get(e.connectionName);if(0===t){n.push({route:e,mutated:!1});continue}const r=[];for(let e=0;e\u003ct;e++){const t=i[e],n=r.at(-1);n?.mutated===t?n.end=e+1:r.push({start:e,end:e+1,mutated:t})}for(const[t,o]of r.entries()){const i=e.route.slice(o.start,o.end+1),s={...e,connectionName:1===r.length?e.connectionName:`${e.connectionName}_mutation_fragment_${t}`,preloadedRouteIndex:e.preloadedRouteIndex+t/(r.length+1),preloadedRoutePositionStart:KK(e,o.start),preloadedRoutePositionEnd:KK(e,o.end),route:i,vias:UK(i)};n.push({route:s,mutated:o.mutated})}}return n},eQ=({updatedFixedRoutes:t,regionalMutationMasks:e})=\u003e{const n=tQ({updatedFixedRoutes:t,regionalMutationMasks:e}),o=n.map(({route:t})=\u003et),i=(t=\u003e{const e=[];let n;for(const o of[...t].sort((t,e)=\u003eqK(t.route,e.route))){const t=o.route;if(!o.mutated){n=void 0;continue}const i=t.route[0],r=t.route.at(-1);if(!i||!r||t.route.length\u003c2)throw new Error(`Pipeline9 cannot simplify empty fixed route \"${t.connectionName}\"`);const s=n?.sourceRoutes.at(-1);n\u0026\u0026s\u0026\u0026JK(s,t)?(n.sourceRoutes.push(t),n.end={segmentIndex:t.route.length-2,point:r}):(n={sourceRoutes:[t],start:{segmentIndex:0,point:i},end:{segmentIndex:t.route.length-2,point:r}},e.push(n))}return e})(n),r=i.map((t,e)=\u003e{const n=((t,e)=\u003e{const n=t.sourceRoutes[0],o=t.sourceRoutes.at(-1);if(!n||!o)throw new Error(\"Pipeline9 cannot simplify an empty mutation section\");const i=[t.start.point];for(const[e,n]of t.sourceRoutes.entries()){const o=0===e,r=e===t.sourceRoutes.length-1,s=o?t.start.segmentIndex+1:0,a=r?t.end.segmentIndex+1:n.route.length;GK(i,n.route.slice(s,a))}if(GK(i,[t.end.point]),i.length\u003c2)throw new Error(`Pipeline9 mutation section for \"${n.connectionName}\" has no routable span`);return{connectionName:`pipeline9_mutated_preload_${n.preloadedTraceIndex}_${e}`,rootConnectionName:n.rootConnectionName,traceThickness:Math.max(...t.sourceRoutes.map(t=\u003et.traceThickness)),viaDiameter:Math.max(...t.sourceRoutes.map(t=\u003et.viaDiameter)),route:i,vias:UK(i)}})(t,e);return{connectionName:n.connectionName,section:t,hdRoute:n}}),s=new Set(r.flatMap(({section:t})=\u003et.sourceRoutes.map(t=\u003et.connectionName)));return{sections:r,immutableHdRoutes:o.filter(t=\u003e!s.has(t.connectionName)),normalizedFixedRoutes:o}},nQ=1e-9,oQ=(t,e,n,o,i)=\u003e{const r=i.getNetConnectedToId(t.connection_name)??t.connection_name,s=[],a=(n,i,a=o,c=[],l,d,h=!1)=\u003e{n.length\u003c2||s.push({connectionName:`${t.connection_name}_fixed_${e}_${s.length}`,rootConnectionName:r,preloadedTraceIndex:e,preloadedRouteIndex:s.length,preloadedRoutePositionStart:l,preloadedRoutePositionEnd:d,isThroughObstacle:h,traceThickness:Math.max(nQ,i),viaDiameter:Math.max(nQ,a),route:n,vias:c})};for(let e=0;e\u003ct.route.length;e++){const i=t.route[e];if(\"via\"===i.route_type){a([{x:i.x,y:i.y,z:ko(i.from_layer,n)},{x:i.x,y:i.y,z:ko(i.to_layer,n)}],nQ,i.via_diameter??o,[{x:i.x,y:i.y}],e,e);continue}if(\"through_obstacle\"===i.route_type){const t=ko(i.from_layer,n),r=ko(i.to_layer,n);for(let n=Math.min(t,r);n\u003c=Math.max(t,r);n++)a([{...i.start,z:n},{...i.end,z:n}],i.width,o,[],e,e+1,!0);continue}const r=t.route[e+1];\"wire\"===i.route_type\u0026\u0026\"wire\"===r?.route_type\u0026\u0026i.layer===r.layer\u0026\u0026a([{x:i.x,y:i.y,z:ko(i.layer,n)},{x:r.x,y:r.y,z:ko(r.layer,n)}],Math.max(i.width,r.width),o,[],e,e+1)}return s};function iQ(t,e){return{x:t.a*e.x+t.b*e.y+t.c,y:t.d*e.x+t.e*e.y+t.f}}var rQ={highResolutionCellSize:.1,highResolutionCellThickness:8,lowResolutionCellSize:.4,traceMargin:.15,traceThickness:.1,viaDiameter:.3,viaMinDistFromBorder:.15},sQ={...rQ},aQ=(t,e,n)=\u003e{const[o,i]=t;if(o===i)return;const r=((t,e)=\u003e{const n=t.portPointId??`${t.connectionName}:${t.x}:${t.y}:${t.z}`,o=e.portPointId??`${e.connectionName}:${e.x}:${e.y}:${e.z}`;return n\u003co?`${n}|${o}`:`${o}|${n}`})(o,i);e.has(r)||(e.add(r),n.push(t))},cQ=(t,e,n)=\u003e{for(let o=0;o\u003ct.length-1;o++)aQ([t[o],t[o+1]],e,n)},lQ=t=\u003e{const e=[],n=new Set,o=(t=\u003e{const e=new Map;for(const n of t)n.portPointId\u0026\u0026e.set(n.portPointId,n);return e})(t);for(const i of t){if(i.prevPortPointId){const t=o.get(i.prevPortPointId);t\u0026\u0026t.connectionName===i.connectionName\u0026\u0026aQ([t,i],n,e)}if(i.nextPortPointId){const t=o.get(i.nextPortPointId);t\u0026\u0026t.connectionName===i.connectionName\u0026\u0026aQ([i,t],n,e)}}if(0===e.length)return cQ(t,n,e),e;const i=(t=\u003e{const e=new Set;for(const[n,o]of t)n.portPointId\u0026\u0026e.add(n.portPointId),o.portPointId\u0026\u0026e.add(o.portPointId);return e})(e),r=t.filter(t=\u003e!t.portPointId||!i.has(t.portPointId));return cQ(r,n,e),e};function dQ(t,e,n){return Math.max(e,Math.min(n,t))}var hQ=[\"left\",\"top\",\"right\",\"bottom\",\"middle\"],uQ=class{f=new Float64Array(1024);seq=new Uint32Array(1024);id=new Int32Array(1024);n=0;push(t,e,n){this.ensureCapacity(this.n+1);let o=this.n++;for(this.f[o]=t,this.seq[o]=e,this.id[o]=n;o\u003e0;){const t=o-1\u003e\u003e1;if(this.less(t,o))break;this.swap(o,t),o=t}}pop(){const t=this.id[0];return this.n--,this.n\u003e0\u0026\u0026(this.f[0]=this.f[this.n],this.seq[0]=this.seq[this.n],this.id[0]=this.id[this.n],this.siftDown(0)),t}get size(){return this.n}clear(){this.n=0}ensureCapacity(t){if(t\u003c=this.f.length)return;let e=this.f.length;for(;e\u003ct;)e*=2;const n=new Float64Array(e);n.set(this.f),this.f=n;const o=new Uint32Array(e);o.set(this.seq),this.seq=o;const i=new Int32Array(e);i.set(this.id),this.id=i}siftDown(t){for(;;){const e=2*t+1,n=e+1;if(e\u003e=this.n)return;let o=e;if(n\u003cthis.n\u0026\u0026!this.less(e,n)\u0026\u0026(o=n),this.less(t,o))return;this.swap(t,o),t=o}}less(t,e){const n=this.f[t],o=this.f[e];return n!==o?n\u003co:this.seq[t]\u003cthis.seq[e]}swap(t,e){const n=this.f[t];this.f[t]=this.f[e],this.f[e]=n;const o=this.seq[t];this.seq[t]=this.seq[e],this.seq[e]=o;const i=this.id[t];this.id[t]=this.id[e],this.id[e]=i}},pQ=class{z=new Int32Array(1024);cellId=new Int32Array(1024);g=new Float64Array(1024);parent=new Int32Array(1024);ripHead=new Int32Array(1024).fill(-1);ripCount=new Int32Array(1024);length=0;clear(){this.length=0}push(t,e,n,o,i,r){this.ensureCapacity(this.length+1);const s=this.length++;return this.z[s]=t,this.cellId[s]=e,this.g[s]=n,this.parent[s]=o,this.ripHead[s]=i,this.ripCount[s]=r,s}ensureCapacity(t){if(t\u003c=this.z.length)return;let e=this.z.length;for(;e\u003ct;)e*=2;const n=new Int32Array(e);n.set(this.z),this.z=n;const o=new Int32Array(e);o.set(this.cellId),this.cellId=o;const i=new Float64Array(e);i.set(this.g),this.g=i;const r=new Int32Array(e);r.set(this.parent),this.parent=r;const s=new Int32Array(e);s.fill(-1),s.set(this.ripHead.subarray(0,this.length)),this.ripHead=s;const a=new Int32Array(e);a.set(this.ripCount.subarray(0,this.length)),this.ripCount=a}},mQ=class{connId=new Int32Array(1024);prev=new Int32Array(1024).fill(-1);length=0;clear(){this.length=0}append(t,e){this.ensureCapacity(this.length+1);const n=this.length++;return this.connId[n]=e,this.prev[n]=t,n}contains(t,e){for(let n=t;n\u003e=0;n=this.prev[n])if(this.connId[n]===e)return!0;return!1}collect(t,e){e.length=0;for(let n=t;n\u003e=0;n=this.prev[n])e.push(this.connId[n])}ensureCapacity(t){if(t\u003c=this.connId.length)return;let e=this.connId.length;for(;e\u003ct;)e*=2;const n=new Int32Array(e);n.set(this.connId),this.connId=n;const o=new Int32Array(e);o.fill(-1),o.set(this.prev.subarray(0,this.length)),this.prev=o}};function gQ(t,e){return e??t.replace(/_mst\\d+$/,\"\")}function fQ(t,e){const n=t.x-e.center.x,o=t.y-e.center.y,i=Math.cos(-e.rotationRadians),r=Math.sin(-e.rotationRadians);return{x:n*i-o*r,y:n*r+o*i}}function yQ(t){return{minX:-t.width/2,minY:-t.height/2,maxX:t.width/2,maxY:t.height/2}}function _Q(t,e,n){return Math.max(e,Math.min(n,t))}function bQ(t,e){for(let n=0;n\u003ct.length;n++)if(t[n]===e)return;t.push(e)}function xQ(t,e){for(let n=0;n\u003ct.length;n++)if(t[n].cellId===e.cellId)return;t.push(e)}function vQ(t,e,n,o,i,r,s){const a=t-_Q(t,o,r),c=e-_Q(e,i,s);return a*a+c*c\u003c=n*n}function SQ(t){const e=t.segmentEnd.x-t.segmentStart.x,n=t.segmentEnd.y-t.segmentStart.y,o=e**2+n**2;if(0===o)return(t.point.x-t.segmentStart.x)**2+(t.point.y-t.segmentStart.y)**2;const i=_Q(((t.point.x-t.segmentStart.x)*e+(t.point.y-t.segmentStart.y)*n)/o,0,1),r=t.segmentStart.x+i*e,s=t.segmentStart.y+i*n;return(t.point.x-r)**2+(t.point.y-s)**2}function IQ(t){const e=_Q(t.point.x,t.rect.minX,t.rect.maxX),n=_Q(t.point.y,t.rect.minY,t.rect.maxY),o=t.point.x-e,i=t.point.y-n;return o*o+i*i}function CQ(t){return(t.second.x-t.first.x)*(t.third.y-t.first.y)-(t.second.y-t.first.y)*(t.third.x-t.first.x)}function PQ(t){return!(Math.abs(CQ({first:t.segmentStart,second:t.segmentEnd,third:t.point}))\u003e1e-9)\u0026\u0026(t.point.x\u003e=Math.min(t.segmentStart.x,t.segmentEnd.x)\u0026\u0026t.point.x\u003c=Math.max(t.segmentStart.x,t.segmentEnd.x)\u0026\u0026t.point.y\u003e=Math.min(t.segmentStart.y,t.segmentEnd.y)\u0026\u0026t.point.y\u003c=Math.max(t.segmentStart.y,t.segmentEnd.y))}function MQ(t){const e=CQ({first:t.firstStart,second:t.firstEnd,third:t.secondStart}),n=CQ({first:t.firstStart,second:t.firstEnd,third:t.secondEnd}),o=CQ({first:t.secondStart,second:t.secondEnd,third:t.firstStart}),i=CQ({first:t.secondStart,second:t.secondEnd,third:t.firstEnd});return e*n\u003c0\u0026\u0026o*i\u003c0||(PQ({point:t.secondStart,segmentStart:t.firstStart,segmentEnd:t.firstEnd})||PQ({point:t.secondEnd,segmentStart:t.firstStart,segmentEnd:t.firstEnd})||PQ({point:t.firstStart,segmentStart:t.secondStart,segmentEnd:t.secondEnd})||PQ({point:t.firstEnd,segmentStart:t.secondStart,segmentEnd:t.secondEnd}))}function NQ(t){return MQ(t)?0:Math.min(SQ({point:t.firstStart,segmentStart:t.secondStart,segmentEnd:t.secondEnd}),SQ({point:t.firstEnd,segmentStart:t.secondStart,segmentEnd:t.secondEnd}),SQ({point:t.secondStart,segmentStart:t.firstStart,segmentEnd:t.firstEnd}),SQ({point:t.secondEnd,segmentStart:t.firstStart,segmentEnd:t.firstEnd}))}function wQ(t){if(function(t){if(0===IQ({point:t.segmentStart,rect:t.rect})||0===IQ({point:t.segmentEnd,rect:t.rect}))return!0;const e=[{x:t.rect.minX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.maxY},{x:t.rect.minX,y:t.rect.maxY}];for(let n=0;n\u003ce.length;n++){const o=(n+1)%e.length;if(MQ({firstStart:t.segmentStart,firstEnd:t.segmentEnd,secondStart:e[n],secondEnd:e[o]}))return!0}return!1}(t))return!0;const e=t.radius**2;if(IQ({point:t.segmentStart,rect:t.rect})\u003c=e||IQ({point:t.segmentEnd,rect:t.rect})\u003c=e)return!0;return[{x:t.rect.minX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.maxY},{x:t.rect.minX,y:t.rect.maxY}].some(n=\u003eSQ({point:n,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd})\u003c=e)}var TQ=class extends kt{getSolverName(){return\"HighDensitySolverB01\"}nodeWithPortPoints;obstacles;highResolutionCellSize;highResolutionCellThickness;lowResolutionCellSize;viaDiameter;MAX_RIPS;maxCellCount;traceThickness;traceMargin;obstacleClearanceMargin;viaMinDistFromBorder;showPenaltyMap;showUsedCellMap;effort;stepMultiplier;hyperParameters;initialPenaltyFn;boundsMinX;boundsMaxX;boundsMinY;boundsMaxY;gridToBoundsTransform;availableZ;zToLayer;layerToZ;layers;fineRows;fineCols;lowScale;bandRows;bandCols;regions;planeSize;cellCenterX;cellCenterY;cellMinX;cellMinY;cellMaxX;cellMaxY;cellWidth;cellHeight;cellRegion;cellRow;cellCol;viaAllowed;neighborOffset;neighborIds;neighborCosts;usedCellsFlat;sharedCellsFlat;portOwnerFlat;penalty2d;ripStateBuckets;visitedStamp;bestGStamp;bestGValue;visitedFlatStamp;sharedCrossRootPortFlat;stamp=0;connNameToId;connIdToName;connIdToRootNet;overlapFriendlyRootNets;usedIndicesByConn;unsolvedSegs;solvedRoutes;activeConnSeg=null;activeConnId=-1;nodePool;heap;ripChain;seqCounter=0;_viaOccs=[];_cellOccs=[];_rippedIds=[];ripCount;totalRipEvents=0;searchIterations=0;consecutiveSkips=0;penaltyCap;baseSearchBudgetIters;_moveCost=0;_moveRippedHead=-1;_moveRipCount=0;traceKeepoutRadius;viaKeepoutRadius;obstacleTraceRootIdsFlat;obstacleViaRootIdsByCell;obstacleRootNameToId;obstacleRootNames;obstacleTracePrimitives;obstacleViaPrimitives;obstacleRectPrimitives;obstacleTraceBlockedCellCount=0;obstacleViaBlockedCellCount=0;get unsolvedConnections(){return this.unsolvedSegs}get solvedConnectionsMap(){const t=new Map;for(let e=0;e\u003cthis.solvedRoutes.length;e++){const n=this.getSolvedRoutesForConn(e);n.length\u003e0\u0026\u0026t.set(e,n)}return t}get activeConnection(){if(!this.activeConnSeg)return null;const t=this.activeConnSeg.startCellId,e=this.activeConnSeg.endCellId;return{connectionName:this.connIdToName[this.activeConnSeg.connId]??\"\",start:{cellId:t,region:hQ[this.cellRegion[t]],row:this.cellRow[t],col:this.cellCol[t],x:this.cellCenterX[t],y:this.cellCenterY[t],z:this.activeConnSeg.startZ},end:{cellId:e,region:hQ[this.cellRegion[e]],row:this.cellRow[e],col:this.cellCol[e],x:this.cellCenterX[e],y:this.cellCenterY[e],z:this.activeConnSeg.endZ}}}get openSet(){return{length:this.heap?.size??0}}get gridStats(){return{cells:this.planeSize||0,layers:this.layers||0,states:(this.planeSize||0)*(this.layers||0),ripStateBuckets:this.ripStateBuckets||0,neighborEdges:this.neighborIds?.length??0,regionCounts:this.regions?Object.fromEntries(this.regions.map(t=\u003e[t.name,t.rows*t.cols])):{},obstacleTraceBlockedCells:this.obstacleTraceBlockedCellCount,obstacleViaBlockedCells:this.obstacleViaBlockedCellCount,obstacleRootCount:this.obstacleRootNames?.length??0,obstacleRectCount:this.obstacleRectPrimitives?.length??0}}constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.obstacles=t.obstacles,this.highResolutionCellSize=t.highResolutionCellSize??.1,this.highResolutionCellThickness=Math.max(1,Math.floor(t.highResolutionCellThickness??8)),this.lowResolutionCellSize=t.lowResolutionCellSize??.4,this.viaDiameter=t.viaDiameter,this.maxCellCount=t.maxCellCount,this.traceThickness=t.traceThickness??.1,this.traceMargin=t.traceMargin??.15,this.obstacleClearanceMargin=t.obstacleClearanceMargin??0,this.viaMinDistFromBorder=t.viaMinDistFromBorder??.15,this.showPenaltyMap=t.showPenaltyMap??!1,this.showUsedCellMap=t.showUsedCellMap??!1,this.effort=t.effort??1,this.stepMultiplier=Math.max(1,Math.floor(t.stepMultiplier??1)),this.hyperParameters={shuffleSeed:0,ripCost:8,ripTracePenalty:.5,ripViaPenalty:.75,viaBaseCost:.1,greedyMultiplier:1.5,sameRootObstacleCostMultiplier:1,...t.hyperParameters},this.MAX_ITERATIONS=1e8,this.MAX_RIPS=200,this.initialPenaltyFn=t.initialPenaltyFn}getConstructorParams(){return[{nodeWithPortPoints:this.nodeWithPortPoints,obstacles:this.obstacles,highResolutionCellSize:this.highResolutionCellSize,highResolutionCellThickness:this.highResolutionCellThickness,lowResolutionCellSize:this.lowResolutionCellSize,viaDiameter:this.viaDiameter,maxCellCount:this.maxCellCount,stepMultiplier:this.stepMultiplier,traceThickness:this.traceThickness,traceMargin:this.traceMargin,obstacleClearanceMargin:this.obstacleClearanceMargin,viaMinDistFromBorder:this.viaMinDistFromBorder,showPenaltyMap:this.showPenaltyMap,showUsedCellMap:this.showUsedCellMap,effort:this.effort,hyperParameters:this.hyperParameters,initialPenaltyFn:this.initialPenaltyFn}]}_setup(){const{nodeWithPortPoints:t}=this,{width:e,height:n,center:o}=t;if(e\u003e15||n\u003e15)return this.error=`HighDensitySolverB01 only supports routing windows up to 15x15mm; received ${e}x${n}mm`,void(this.failed=!0);const i=this.lowResolutionCellSize/this.highResolutionCellSize,r=Math.round(i);if(!Number.isFinite(i)||i\u003c=0||Math.abs(i-r)\u003e1e-9)return this.error=\"lowResolutionCellSize must be a positive integer multiple of highResolutionCellSize\",void(this.failed=!0);this.lowScale=Math.max(1,r),this.availableZ=t.availableZ??[...new Set(t.portPoints.map(t=\u003et.z))].sort((t,e)=\u003et-e),this.layers=this.availableZ.length,this.zToLayer=new Map,this.layerToZ=new Map;for(let t=0;t\u003cthis.availableZ.length;t++){const e=this.availableZ[t];this.zToLayer.set(e,t),this.layerToZ.set(t,e)}this.boundsMinX=o.x-e/2,this.boundsMaxX=o.x+e/2,this.boundsMinY=o.y-n/2,this.boundsMaxY=o.y+n/2,this.traceKeepoutRadius=this.traceMargin+this.traceThickness/2,this.viaKeepoutRadius=this.viaDiameter/2+this.traceKeepoutRadius,this.buildFiveRegionGrid(e,n),this.gridToBoundsTransform=this.computeGridToBoundsTransform();const s=this.layers*this.planeSize;if(void 0!==this.maxCellCount\u0026\u0026s\u003ethis.maxCellCount)return this.error=`Cell count ${s} exceeds maxCellCount ${this.maxCellCount}`,void(this.failed=!0);this.connNameToId=new Map,this.connIdToName=[],this.connIdToRootNet=[],this.overlapFriendlyRootNets=new Set,this.unsolvedSegs=this.buildConnectionSegs(),this.penalty2d=new Float64Array(this.planeSize);const a=e\u003e0?1/e:0,c=n\u003e0?1/n:0;for(let t=0;t\u003cthis.planeSize;t++){let e=0;this.initialPenaltyFn\u0026\u0026(e+=this.initialPenaltyFn({x:this.cellCenterX[t],y:this.cellCenterY[t],px:(this.cellCenterX[t]-this.boundsMinX)*a,py:(this.cellCenterY[t]-this.boundsMinY)*c,cellId:t,region:hQ[this.cellRegion[t]],row:this.cellRow[t],col:this.cellCol[t]})),this.penalty2d[t]=e}this.usedCellsFlat=new Int32Array(s).fill(-1),this.sharedCellsFlat=Array.from({length:s},()=\u003e{}),this.portOwnerFlat=new Int32Array(s).fill(-1),this.sharedCrossRootPortFlat=new Uint8Array(s),this.obstacleTraceRootIdsFlat=Array.from({length:s},()=\u003e{}),this.obstacleViaRootIdsByCell=Array.from({length:this.planeSize},()=\u003e{}),this.obstacleRootNameToId=new Map,this.obstacleRootNames=[],this.obstacleTracePrimitives=[],this.obstacleViaPrimitives=[],this.obstacleRectPrimitives=[];const l=this.rasterizeObstacles();if(l)return this.error=l,void(this.failed=!0);this.ripStateBuckets=1;const d=s;this.visitedStamp=new Uint32Array(d),this.bestGStamp=new Uint32Array(d),this.bestGValue=new Float64Array(d),this.visitedFlatStamp=new Uint32Array(s),this.stamp=0;const h=new Map;for(const t of this.nodeWithPortPoints.portPoints){const e=this.connNameToId.get(t.connectionName);if(void 0===e)continue;const n=this.pointToCell(t),o=n.z*this.planeSize+n.cellId,i=this.connIdToRootNet[e],r=h.get(o);void 0===r?h.set(o,i):r!==i\u0026\u0026(this.sharedCrossRootPortFlat[o]=1);const s=this.portOwnerFlat[o];this.portOwnerFlat[o]=-1===s||s===e?e:-2}this.solvedRoutes=[],this.usedIndicesByConn=[],this.ripCount=[],this.consecutiveSkips=0,this.penaltyCap=.5*this.hyperParameters.ripCost,this.shuffleConnections();const u=function(t){const e=t.planeSize*t.layers,n=t.connectionCount,o=Math.sqrt(n),i=Math.max(1,t.maxIterations),r=dQ(Math.round(e*(8+1.2*o)),15e4,12e6),s=dQ(Math.round(r*t.effort),15e4,12e6),a=dQ(Math.round(.2*i),15e4,2e6);return{maxIterationsIters:Math.max(1,Math.min(i,Math.max(a,s))),baseSearchBudgetIters:dQ(Math.round(e*(10+.8*o)*t.effort),5e4,4e6)}}({planeSize:this.planeSize,layers:this.layers,connectionCount:this.unsolvedSegs.length,effort:this.effort,maxIterations:this.MAX_ITERATIONS});this.baseSearchBudgetIters=u.baseSearchBudgetIters,this.MAX_ITERATIONS=u.maxIterationsIters,this.activeConnSeg=null,this.activeConnId=-1,this.nodePool=new pQ,this.heap=new uQ,this.ripChain=new mQ,this.seqCounter=0}_step(){for(let t=0;t\u003cthis.stepMultiplier;t++){if(this.solved||this.failed)return;this.stepOnce()}}rasterizeObstacles(){for(let t=0;t\u003cthis.obstacles.length;t++){const e=this.obstacles[t];if(\"rect\"===e.type){const n=this.rasterizeRectObstacle(e,t);if(n)return n;continue}if(e.traceThickness\u003c=0||e.viaDiameter\u003c=0||e.route.length\u003c2)return`Obstacle ${t} must have positive trace/via sizes and at least two route points`;const n=gQ(e.connectionName,e.rootConnectionName),o=this.internObstacleRootName(n);for(let n=1;n\u003ce.route.length;n++){const i=e.route[n-1],r=e.route[n];if(!(Number.isFinite(i.x)\u0026\u0026Number.isFinite(i.y)\u0026\u0026Number.isFinite(i.z)\u0026\u0026Number.isFinite(r.x)\u0026\u0026Number.isFinite(r.y)\u0026\u0026Number.isFinite(r.z)))return`Obstacle ${t} contains non-finite route coordinates`;if(i.z===r.z){const n=this.zToLayer.get(i.z);if(void 0===n)return`Obstacle ${t} uses unavailable layer z=${i.z}`;this.rasterizeObstacleTraceSegment({segmentStart:i,segmentEnd:r,layer:n,obstacleRootId:o,obstacleTraceThickness:e.traceThickness})}else if(!e.vias.some(t=\u003et.x===r.x\u0026\u0026t.y===r.y)){const n=this.rasterizeObstacleVia({center:r,obstacleRootId:o,obstacleViaDiameter:e.viaDiameter,zStart:i.z,zEnd:r.z,obstacleIndex:t});if(n)return n}}for(const n of e.vias){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))return`Obstacle ${t} contains non-finite via coordinates`;const i=this.rasterizeObstacleVia({center:n,obstacleRootId:o,obstacleViaDiameter:e.viaDiameter,zStart:n.zStart,zEnd:n.zEnd,obstacleIndex:t});if(i)return i}}return this.obstacleTraceBlockedCellCount=this.obstacleTraceRootIdsFlat.reduce((t,e)=\u003et+(e?1:0),0),this.obstacleViaBlockedCellCount=this.obstacleViaRootIdsByCell.reduce((t,e)=\u003et+(e?1:0),0),null}rasterizeRectObstacle(t,e){if(!Number.isFinite(t.center.x)||!Number.isFinite(t.center.y)||!Number.isFinite(t.width)||!Number.isFinite(t.height)||t.width\u003c=0||t.height\u003c=0)return`Rect obstacle ${e} must have finite geometry and positive dimensions`;const n=[];for(const o of t.zLayers){const t=this.zToLayer.get(o);if(void 0===t)return`Rect obstacle ${e} uses unavailable layer z=${o}`;bQ(n,t)}if(0===n.length)return`Rect obstacle ${e} must apply to at least one layer`;const o=this.internObstacleRootName(gQ(t.connectionName,t.rootConnectionName)),i={rootId:o,center:t.center,width:t.width,height:t.height,rotationRadians:(t.ccwRotationDegrees??0)*Math.PI/180,layers:n};this.obstacleRectPrimitives.push(i);const r=this.transformBoundsPointToGrid(t.center),s=Math.hypot(t.width/2,t.height/2),a=this.getConservativeGridRadius(s+this.traceThickness/2+this.traceMargin);this.forEachCellNearCircle(r.x,r.y,a,t=\u003e{for(const e of n)this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:e*this.planeSize+t,obstacleRootId:o})});const c=this.getConservativeGridRadius(s+this.viaDiameter/2+this.traceMargin);return this.forEachCellNearCircle(r.x,r.y,c,t=\u003e{this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:t,obstacleRootId:o})}),null}internObstacleRootName(t){const e=this.obstacleRootNameToId.get(t);if(void 0!==e)return e;const n=this.obstacleRootNames.length;return this.obstacleRootNames.push(t),this.obstacleRootNameToId.set(t,n),n}rasterizeObstacleTraceSegment(t){this.obstacleTracePrimitives.push({rootId:t.obstacleRootId,layer:t.layer,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd,traceRadius:t.obstacleTraceThickness/2});const e=this.transformBoundsPointToGrid(t.segmentStart),n=this.transformBoundsPointToGrid(t.segmentEnd),o=this.getConservativeGridRadius(t.obstacleTraceThickness/2+this.traceMargin),i=this.getConservativeGridRadius(t.obstacleTraceThickness/2+this.viaDiameter/2+this.traceMargin);this.forEachCellNearSegment({segmentStart:e,segmentEnd:n,radius:o},e=\u003e{this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:t.layer*this.planeSize+e,obstacleRootId:t.obstacleRootId})}),this.forEachCellNearSegment({segmentStart:e,segmentEnd:n,radius:i},e=\u003e{this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:e,obstacleRootId:t.obstacleRootId})})}rasterizeObstacleVia(t){if(void 0===t.zStart!=(void 0===t.zEnd))return`Obstacle ${t.obstacleIndex} via must provide both zStart and zEnd`;let e=Array.from({length:this.layers},(t,e)=\u003ee);if(void 0!==t.zStart\u0026\u0026void 0!==t.zEnd){if(!Number.isFinite(t.zStart)||!Number.isFinite(t.zEnd))return`Obstacle ${t.obstacleIndex} contains a non-finite via layer span`;const n=Math.min(t.zStart,t.zEnd),o=Math.max(t.zStart,t.zEnd);e=this.availableZ.flatMap((t,e)=\u003et\u003e=n\u0026\u0026t\u003c=o?[e]:[])}if(0===e.length)return null;this.obstacleViaPrimitives.push({rootId:t.obstacleRootId,center:t.center,viaRadius:t.obstacleViaDiameter/2,layers:e});const n=this.transformBoundsPointToGrid(t.center),o=this.getConservativeGridRadius(t.obstacleViaDiameter/2+this.traceThickness/2+this.traceMargin),i=this.getConservativeGridRadius(t.obstacleViaDiameter/2+this.viaDiameter/2+this.traceMargin);return this.forEachCellNearCircle(n.x,n.y,Math.max(o,i),r=\u003e{const s=this.getCellRect(r);if(vQ(n.x,n.y,o,s.minX,s.minY,s.maxX,s.maxY))for(const n of e)this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:n*this.planeSize+r,obstacleRootId:t.obstacleRootId});vQ(n.x,n.y,i,s.minX,s.minY,s.maxX,s.maxY)\u0026\u0026this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:r,obstacleRootId:t.obstacleRootId})}),null}forEachCellNearSegment(t,e){const n={x:(t.segmentStart.x+t.segmentEnd.x)/2,y:(t.segmentStart.y+t.segmentEnd.y)/2},o=Math.hypot(t.segmentEnd.x-t.segmentStart.x,t.segmentEnd.y-t.segmentStart.y)/2+t.radius;this.forEachCellNearCircle(n.x,n.y,o,n=\u003e{wQ({segmentStart:t.segmentStart,segmentEnd:t.segmentEnd,radius:t.radius,rect:this.getCellRect(n)})\u0026\u0026e(n)})}getCellRect(t){return{minX:this.cellMinX[t],minY:this.cellMinY[t],maxX:this.cellMaxX[t],maxY:this.cellMaxY[t]}}transformBoundsPointToGrid(t){const e=this.gridToBoundsTransform;return{x:(t.x-e.c)/e.a,y:(t.y-e.f)/e.e}}getConservativeGridRadius(t){return t/Math.min(Math.abs(this.gridToBoundsTransform.a),Math.abs(this.gridToBoundsTransform.e))}addObstacleRootId(t){let e=t.rootIdsByCell[t.cellIndex];e||(e=[],t.rootIdsByCell[t.cellIndex]=e),bQ(e,t.obstacleRootId)}isBlockedByObstacleRoots(t,e){if(!t)return!1;const n=this.connIdToRootNet[e];for(const e of t)if(this.obstacleRootNames[e]!==n)return!0;return!1}hasSameRootObstacle(t,e){if(!t)return!1;const n=this.connIdToRootNet[e];return t.some(t=\u003ethis.obstacleRootNames[t]===n)}isLateralMoveBlockedByObstacleGeometry(t){const e=this.connIdToRootNet[t.activeConn],n=this.activeConnSeg,o=n\u0026\u0026t.layer===n.startZ\u0026\u0026t.fromCellId===n.startCellId?n.startPoint:iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.fromCellId],y:this.cellCenterY[t.fromCellId]}),i=n\u0026\u0026t.layer===n.endZ\u0026\u0026t.toCellId===n.endCellId?n.endPoint:iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.toCellId],y:this.cellCenterY[t.toCellId]});for(const n of this.obstacleTracePrimitives){if(n.layer!==t.layer||this.obstacleRootNames[n.rootId]===e)continue;const r=n.traceRadius+this.traceThickness/2+this.obstacleClearanceMargin;if(NQ({firstStart:o,firstEnd:i,secondStart:n.segmentStart,secondEnd:n.segmentEnd})\u003cr*r)return!0}for(const n of this.obstacleViaPrimitives){if(!n.layers.includes(t.layer)||this.obstacleRootNames[n.rootId]===e)continue;const r=n.viaRadius+this.traceThickness/2+this.obstacleClearanceMargin;if(SQ({point:n.center,segmentStart:o,segmentEnd:i})\u003cr*r)return!0}for(const n of this.obstacleRectPrimitives)if(n.layers.includes(t.layer)\u0026\u0026this.obstacleRootNames[n.rootId]!==e\u0026\u0026wQ({segmentStart:fQ(o,n),segmentEnd:fQ(i,n),radius:this.traceThickness/2+this.obstacleClearanceMargin,rect:yQ(n)}))return!0;return!1}isViaMoveBlockedByObstacleGeometry(t){const e=this.connIdToRootNet[t.activeConn],n=iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.cellId],y:this.cellCenterY[t.cellId]});for(const t of this.obstacleTracePrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=t.traceRadius+this.viaDiameter/2+this.obstacleClearanceMargin;if(SQ({point:n,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd})\u003co*o)return!0}for(const t of this.obstacleViaPrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=t.viaRadius+this.viaDiameter/2+this.obstacleClearanceMargin;if((n.x-t.center.x)**2+(n.y-t.center.y)**2\u003co*o)return!0}for(const t of this.obstacleRectPrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=fQ(n,t),i=this.viaDiameter/2+this.obstacleClearanceMargin;if(IQ({point:o,rect:yQ(t)})\u003ci*i)return!0}return!1}buildFiveRegionGrid(t,e){this.fineCols=Math.max(1,Math.ceil(t/this.highResolutionCellSize)),this.fineRows=Math.max(1,Math.ceil(e/this.highResolutionCellSize)),this.bandCols=Math.min(this.highResolutionCellThickness,Math.floor(this.fineCols/2)),this.bandRows=Math.min(this.highResolutionCellThickness,Math.floor(this.fineRows/2));const n=Math.max(0,this.fineCols-2*this.bandCols),o=Math.max(0,this.fineRows-2*this.bandRows),i=n,r=n;this.regions=[{id:0,name:\"left\",fineOriginRow:0,fineOriginCol:0,fineRows:this.fineRows,fineCols:this.bandCols,cellScale:1,rows:this.fineRows,cols:this.bandCols,offset:0},{id:1,name:\"top\",fineOriginRow:0,fineOriginCol:this.bandCols,fineRows:this.bandRows,fineCols:i,cellScale:1,rows:this.bandRows,cols:i,offset:0},{id:2,name:\"right\",fineOriginRow:0,fineOriginCol:this.fineCols-this.bandCols,fineRows:this.fineRows,fineCols:this.bandCols,cellScale:1,rows:this.fineRows,cols:this.bandCols,offset:0},{id:3,name:\"bottom\",fineOriginRow:this.fineRows-this.bandRows,fineOriginCol:this.bandCols,fineRows:this.bandRows,fineCols:r,cellScale:1,rows:this.bandRows,cols:r,offset:0},{id:4,name:\"middle\",fineOriginRow:this.bandRows,fineOriginCol:this.bandCols,fineRows:o,fineCols:n,cellScale:this.lowScale,rows:o\u003e0?Math.ceil(o/this.lowScale):0,cols:n\u003e0?Math.ceil(n/this.lowScale):0,offset:0}];let s=0;for(let t=0;t\u003cthis.regions.length;t++)this.regions[t].offset=s,s+=this.regions[t].rows*this.regions[t].cols;this.planeSize=s,this.cellCenterX=new Float64Array(this.planeSize),this.cellCenterY=new Float64Array(this.planeSize),this.cellMinX=new Float64Array(this.planeSize),this.cellMinY=new Float64Array(this.planeSize),this.cellMaxX=new Float64Array(this.planeSize),this.cellMaxY=new Float64Array(this.planeSize),this.cellWidth=new Float64Array(this.planeSize),this.cellHeight=new Float64Array(this.planeSize),this.cellRegion=new Uint8Array(this.planeSize),this.cellRow=new Int32Array(this.planeSize),this.cellCol=new Int32Array(this.planeSize),this.viaAllowed=new Uint8Array(this.planeSize);for(let t=0;t\u003cthis.regions.length;t++){const e=this.regions[t];for(let t=0;t\u003ce.rows;t++){const n=e.fineOriginRow+t*e.cellScale,o=Math.min(e.fineOriginRow+e.fineRows,n+e.cellScale),i=this.boundsMinY+n*this.highResolutionCellSize,r=Math.min(this.boundsMaxY,this.boundsMinY+o*this.highResolutionCellSize);for(let n=0;n\u003ce.cols;n++){const o=e.fineOriginCol+n*e.cellScale,s=Math.min(e.fineOriginCol+e.fineCols,o+e.cellScale),a=this.boundsMinX+o*this.highResolutionCellSize,c=Math.min(this.boundsMaxX,this.boundsMinX+s*this.highResolutionCellSize),l=this.cellIdFor(e.id,t,n);this.cellCenterX[l]=(a+c)/2,this.cellCenterY[l]=(i+r)/2,this.cellMinX[l]=a,this.cellMinY[l]=i,this.cellMaxX[l]=c,this.cellMaxY[l]=r,this.cellWidth[l]=c-a,this.cellHeight[l]=r-i,this.cellRegion[l]=e.id,this.cellRow[l]=t,this.cellCol[l]=n;const d=Math.min(this.cellCenterX[l]-this.boundsMinX,this.boundsMaxX-this.cellCenterX[l],this.cellCenterY[l]-this.boundsMinY,this.boundsMaxY-this.cellCenterY[l]);this.viaAllowed[l]=d\u003e=this.viaMinDistFromBorder?1:0}}}const a=Array.from({length:this.planeSize},()=\u003e[]),c=(t,e)=\u003e{if(t===e||t\u003c0||e\u003c0)return;const n=this.cellCenterX[t]-this.cellCenterX[e],o=this.cellCenterY[t]-this.cellCenterY[e],i=Math.hypot(n,o);xQ(a[t],{cellId:e,cost:i}),xQ(a[e],{cellId:t,cost:i})};for(let t=0;t\u003cthis.regions.length;t++){const e=this.regions[t];for(let t=0;t\u003ce.rows;t++)for(let n=0;n\u003ce.cols;n++){const o=this.cellIdFor(e.id,t,n);t+1\u003ce.rows\u0026\u0026c(o,this.cellIdFor(e.id,t+1,n)),n+1\u003ce.cols\u0026\u0026c(o,this.cellIdFor(e.id,t,n+1))}}const l=this.regions[0],d=this.regions[1],h=this.regions[2],u=this.regions[3],p=this.regions[4],m=l.rows\u003e0\u0026\u0026l.cols\u003e0,g=d.rows\u003e0\u0026\u0026d.cols\u003e0,f=h.rows\u003e0\u0026\u0026h.cols\u003e0,y=u.rows\u003e0\u0026\u0026u.cols\u003e0,_=p.rows\u003e0\u0026\u0026p.cols\u003e0;if(m\u0026\u0026g)for(let t=0;t\u003cthis.bandRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(1,t,0));if(g\u0026\u0026f)for(let t=0;t\u003cthis.bandRows;t++)c(this.cellIdFor(1,t,d.cols-1),this.cellIdFor(2,t,0));if(m\u0026\u0026y)for(let t=this.fineRows-this.bandRows;t\u003cthis.fineRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(3,t-(this.fineRows-this.bandRows),0));if(y\u0026\u0026f)for(let t=this.fineRows-this.bandRows;t\u003cthis.fineRows;t++)c(this.cellIdFor(3,t-(this.fineRows-this.bandRows),u.cols-1),this.cellIdFor(2,t,0));if(m\u0026\u0026_)for(let t=this.bandRows;t\u003cthis.fineRows-this.bandRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(4,Math.floor((t-this.bandRows)/this.lowScale),0));if(f\u0026\u0026_)for(let t=this.bandRows;t\u003cthis.fineRows-this.bandRows;t++)c(this.cellIdFor(4,Math.floor((t-this.bandRows)/this.lowScale),p.cols-1),this.cellIdFor(2,t,0));if(g\u0026\u0026_)for(let t=this.bandCols;t\u003cthis.fineCols-this.bandCols;t++)c(this.cellIdFor(1,d.rows-1,t-this.bandCols),this.cellIdFor(4,0,Math.floor((t-this.bandCols)/this.lowScale)));if(y\u0026\u0026_)for(let t=this.bandCols;t\u003cthis.fineCols-this.bandCols;t++)c(this.cellIdFor(4,p.rows-1,Math.floor((t-this.bandCols)/this.lowScale)),this.cellIdFor(3,0,t-this.bandCols));if(!_\u0026\u0026!g\u0026\u0026!y\u0026\u0026m\u0026\u0026f)for(let t=0;t\u003cMath.min(l.rows,h.rows);t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(2,t,0));if(!_\u0026\u0026!m\u0026\u0026!f\u0026\u0026g\u0026\u0026y)for(let t=0;t\u003cMath.min(d.cols,u.cols);t++)c(this.cellIdFor(1,d.rows-1,t),this.cellIdFor(3,0,t));const b=this.flattenNeighborLists(a);this.neighborOffset=b.offset,this.neighborIds=b.ids,this.neighborCosts=b.costs}cellIdFor(t,e,n){const o=this.regions[t];return o.offset+e*o.cols+n}stepOnce(){if(!this.activeConnSeg){if(0===this.unsolvedSegs.length)return void(this.solved=!0);const t=this.unsolvedSegs.shift();this.activeConnSeg=t,this.activeConnId=t.connId,this.nodePool.clear(),this.ripChain.clear(),this.heap.clear(),this.seqCounter=0,this.searchIterations=0,this.nextStamp();const e=this.computeH(t.startZ,t.startCellId,t.endZ,t.endCellId)*this.hyperParameters.greedyMultiplier,n=this.nodePool.push(t.startZ,t.startCellId,0,-1,-1,0),o=t.startZ*this.planeSize+t.startCellId,i=this.getSearchStateIdx(o,0);return this.bestGStamp[i]=this.stamp,this.bestGValue[i]=0,void this.heap.push(e,this.seqCounter++,n)}this.searchIterations++;const t=this.ripCount[this.activeConnId]??0,e=Math.round(this.baseSearchBudgetIters*(1+.25*Math.min(t,10)));if(this.searchIterations\u003ee){const t=this.penalty2d;for(let e=0;e\u003ct.length;e++)t[e]=.9*t[e];return this.unsolvedSegs.push(this.activeConnSeg),this.activeConnSeg=null,this.activeConnId=-1,this.heap.clear(),this.nodePool.clear(),this.consecutiveSkips++,void(this.consecutiveSkips\u003e=Math.max(3,3*this.unsolvedSegs.length)\u0026\u0026(this.error=`Convergence failure: ${this.unsolvedSegs.length} connections stuck`,this.failed=!0))}if(0===this.heap.size)return this.error=`No path found for ${this.connIdToName[this.activeConnId]}`,void(this.failed=!0);const n=this.heap.pop(),o=this.nodePool.z[n],i=this.nodePool.cellId[n],r=this.nodePool.g[n],s=this.nodePool.ripHead[n],a=this.nodePool.ripCount[n],c=o*this.planeSize+i,l=this.getSearchStateIdx(c,a);if(this.visitedStamp[l]===this.stamp)return;this.visitedStamp[l]=this.stamp,this.visitedFlatStamp[c]=this.stamp;const d=this.activeConnSeg;if(o===d.endZ\u0026\u0026i===d.endCellId)return this.finalizeRoute(n),this.activeConnSeg=null,void(this.activeConnId=-1);const h=this.visitedStamp,u=this.stamp,p=this.activeConnId,m=d.endZ,g=d.endCellId,f=this.neighborOffset[i],y=this.neighborOffset[i+1];for(let t=f;t\u003cy;t++){const e=this.neighborIds[t],c=o*this.planeSize+e;if(this.computeMoveCostAndRips(p,o,i,e,!1,s,a,this.neighborCosts[t]),this._moveCost\u003c0)continue;const l=this.getSearchStateIdx(c,this._moveRipCount);if(h[l]===u)continue;const d=r+this._moveCost;if(this.bestGStamp[l]===u\u0026\u0026d\u003e=this.bestGValue[l])continue;this.bestGStamp[l]=u,this.bestGValue[l]=d;const f=d+this.computeH(o,e,m,g)*this.hyperParameters.greedyMultiplier,y=this.nodePool.push(o,e,d,n,this._moveRippedHead,this._moveRipCount);this.heap.push(f,this.seqCounter++,y)}if(this.viaAllowed[i])for(let t=0;t\u003cthis.layers;t++){if(t===o)continue;const e=t*this.planeSize+i;if(this.computeMoveCostAndRips(p,t,i,i,!0,s,a,0),this._moveCost\u003c0)continue;const c=this.getSearchStateIdx(e,this._moveRipCount);if(h[c]===u)continue;const l=r+this._moveCost;if(this.bestGStamp[c]===u\u0026\u0026l\u003e=this.bestGValue[c])continue;this.bestGStamp[c]=u,this.bestGValue[c]=l;const d=l+this.computeH(t,i,m,g)*this.hyperParameters.greedyMultiplier,f=this.nodePool.push(t,i,l,n,this._moveRippedHead,this._moveRipCount);this.heap.push(d,this.seqCounter++,f)}}computeMoveCostAndRips(t,e,n,o,i,r,s,a){let c=0,l=r,d=s;const h=e*this.planeSize+o,u=i?this.obstacleViaRootIdsByCell[o]:[...this.obstacleTraceRootIdsFlat[e*this.planeSize+n]??[],...this.obstacleTraceRootIdsFlat[h]??[]];if(this.isBlockedByObstacleRoots(u,t)\u0026\u0026(i?this.isViaMoveBlockedByObstacleGeometry({activeConn:t,cellId:o}):this.isLateralMoveBlockedByObstacleGeometry({activeConn:t,layer:e,fromCellId:n,toCellId:o})))return this._moveCost=-1,this._moveRippedHead=l,void(this._moveRipCount=d);const p=this.hasSameRootObstacle(u,t);if(i){c+=this.hyperParameters.viaBaseCost,c+=Math.min(this.penalty2d[o],this.penaltyCap);const n=this.portOwnerFlat[h],i=this.allowSharedUse(t,n),r=this.activeConnSeg,s=!!r\u0026\u0026e===r.endZ\u0026\u0026o===r.endCellId;if(n\u003e=0\u0026\u0026n!==t\u0026\u0026!i\u0026\u0026!s)return this._moveCost=-1,void(this._moveRippedHead=l);this.fillViaOccupants(o,t);const a=this._viaOccs;for(let t=0;t\u003ca.length;t++){const e=a[t];this.ripChain.contains(l,e)||(c+=this.hyperParameters.ripCost,l=this.ripChain.append(l,e),d++),c+=this.hyperParameters.ripViaPenalty}}else{c+=a,c+=Math.min(this.penalty2d[o],this.penaltyCap);const n=this.portOwnerFlat[h],i=this.allowSharedUse(t,n),r=this.activeConnSeg,s=!!r\u0026\u0026e===r.endZ\u0026\u0026o===r.endCellId;if(n\u003e=0\u0026\u0026n!==t\u0026\u0026!i\u0026\u0026!s)return this._moveCost=-1,void(this._moveRippedHead=l);this.fillTraceOccupants(h,t,this._cellOccs);for(let t=0;t\u003cthis._cellOccs.length;t++){const e=this._cellOccs[t];this.ripChain.contains(l,e)||(c+=this.hyperParameters.ripCost,l=this.ripChain.append(l,e),d++),c+=this.hyperParameters.ripTracePenalty}}p\u0026\u0026(c*=this.hyperParameters.sameRootObstacleCostMultiplier),this._moveCost=c,this._moveRippedHead=l,this._moveRipCount=d}fillViaOccupants(t,e){const n=this._viaOccs;n.length=0;const o=this.cellCenterX[t],i=this.cellCenterY[t];this.forEachCellNearCircle(o,i,this.viaKeepoutRadius,t=\u003e{if(vQ(o,i,this.viaKeepoutRadius,this.cellMinX[t],this.cellMinY[t],this.cellMaxX[t],this.cellMaxY[t]))for(let o=0;o\u003cthis.layers;o++)this.pushFlatOccupants(o*this.planeSize+t,e,n)})}fillTraceOccupants(t,e,n){n.length=0,this.pushFlatOccupants(t,e,n)}pushFlatOccupants(t,e,n){const o=this.usedCellsFlat[t];-1===o||o===e||this.allowSharedUse(e,o)||bQ(n,o);const i=this.sharedCellsFlat[t];if(i)for(let t=0;t\u003ci.length;t++){const o=i[t];o!==e\u0026\u0026(this.allowSharedUse(e,o)||bQ(n,o))}}addSharedOccupant(t,e){if(this.usedCellsFlat[t]===e)return;let n=this.sharedCellsFlat[t];n||(n=[],this.sharedCellsFlat[t]=n),bQ(n,e)}replaceOccupants(t,e){this.usedCellsFlat[t]=e,this.sharedCellsFlat[t]=void 0}removeOccupant(t,e){const n=this.sharedCellsFlat[t];if(this.usedCellsFlat[t]===e)return void(n\u0026\u0026n.length\u003e0?(this.usedCellsFlat[t]=n.pop(),0===n.length\u0026\u0026(this.sharedCellsFlat[t]=void 0)):this.usedCellsFlat[t]=-1);if(!n)return;const o=n.indexOf(e);-1!==o\u0026\u0026(n.splice(o,1),0===n.length\u0026\u0026(this.sharedCellsFlat[t]=void 0))}allowSharedUse(t,e){if(e\u003c0)return!1;return this.connIdToRootNet[e]===this.connIdToRootNet[t]}shouldSkipFixedPortHalo(t,e){const n=this.portOwnerFlat[t];return n!==e\u0026\u0026(-2===n||!(n\u003c0)\u0026\u0026!this.allowSharedUse(e,n))}nextStamp(){this.stamp=this.stamp+1\u003e\u003e\u003e0,0===this.stamp\u0026\u0026(this.visitedStamp.fill(0),this.bestGStamp.fill(0),this.visitedFlatStamp.fill(0),this.stamp=1)}getSearchStateIdx(t,e){return t}computeH(t,e,n,o){const i=Math.hypot(this.cellCenterX[e]-this.cellCenterX[o],this.cellCenterY[e]-this.cellCenterY[o]);return t===n?i:i+this.hyperParameters.viaBaseCost}internConn(t,e){const n=this.connNameToId.get(t);if(void 0!==n)return n;const o=this.connIdToName.length;return this.connIdToName.push(t),this.connIdToRootNet.push(gQ(t,e)),this.connNameToId.set(t,o),o}buildConnectionSegs(){const t=new Map;for(const e of this.nodeWithPortPoints.portPoints){const n=e.connectionName;t.has(n)||t.set(n,{points:[],rootConnectionName:e.rootConnectionName}),t.get(n).points.push(e)}const e=[],n=new Map;for(const[o,i]of t){const t=i.points,r=lQ(t);if(0===r.length)continue;const s=this.internConn(o,i.rootConnectionName);for(const[t,i]of r){const r=this.pointToCell(t),a=this.pointToCell(i),c=`${r.z}:${r.cellId}`,l=`${a.z}:${a.cellId}`,d=c\u003cl?`${c}|${l}`:`${l}|${c}`,h=this.connIdToRootNet[s],u=`${h}|${d}`,p=n.get(u);if(p){if(this.overlapFriendlyRootNets.add(h),!p.connectionAliases.some(t=\u003et.connectionName===o)){const e=p.startZ===r.z\u0026\u0026p.startCellId===r.cellId\u0026\u0026p.endZ===a.z\u0026\u0026p.endCellId===a.cellId,n=p.startZ===a.z\u0026\u0026p.startCellId===a.cellId\u0026\u0026p.endZ===r.z\u0026\u0026p.endCellId===r.cellId;if(!e\u0026\u0026!n)throw new Error(`Connection alias ${o} does not match canonical segment ${u}`);p.connectionAliases.push({connectionName:o,rootConnectionName:h,startPoint:t,endPoint:i,reversedFromCanonical:!e\u0026\u0026n})}continue}const m={connId:s,startZ:r.z,startCellId:r.cellId,startPoint:t,endZ:a.z,endCellId:a.cellId,endPoint:i,connectionAliases:[{connectionName:o,rootConnectionName:h,startPoint:t,endPoint:i,reversedFromCanonical:!1}]};n.set(u,m),e.push(m)}}return e}pointToCell(t){const e=_Q(Math.floor((t.x-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),n=_Q(Math.floor((t.y-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1);let o=4;e\u003cthis.bandCols?o=0:e\u003e=this.fineCols-this.bandCols?o=2:n\u003cthis.bandRows?o=1:n\u003e=this.fineRows-this.bandRows\u0026\u0026(o=3);const i=this.regions[o],r=n-i.fineOriginRow,s=e-i.fineOriginCol,a=_Q(Math.floor(r/i.cellScale),0,Math.max(0,i.rows-1)),c=_Q(Math.floor(s/i.cellScale),0,Math.max(0,i.cols-1));return{z:this.zToLayer.get(t.z)??0,cellId:this.cellIdFor(o,a,c)}}shuffleConnections(){const t=this.unsolvedSegs;let e=this.hyperParameters.shuffleSeed\u003e\u003e\u003e0;const n=()=\u003e(e=Math.imul(e,1664525)+1013904223\u003e\u003e\u003e0,e/4294967295);for(let e=t.length-1;e\u003e0;e--){const o=Math.floor(n()*(e+1)),i=t[e];t[e]=t[o],t[o]=i}}finalizeRoute(t){this.consecutiveSkips=Math.max(0,this.consecutiveSkips-1);const e=[];let n=t;for(;n\u003e=0;){const t=this.nodePool.z[n],o=this.nodePool.cellId[n];e.push(t*this.planeSize+o),n=this.nodePool.parent[n]}for(e.reverse();e.length\u003e1\u0026\u0026this.sharedCrossRootPortFlat[e[0]];)e.shift();for(;e.length\u003e1\u0026\u0026this.sharedCrossRootPortFlat[e[e.length-1]];)e.pop();const o=this.extractViaCellIds(e),i=this.activeConnId;this.ripChain.collect(this.nodePool.ripHead[t],this._rippedIds);for(let t=0;t\u003cthis._rippedIds.length;t++)if(this.ripTrace(this._rippedIds[t]),this.failed)return;const r=[];for(let t=0;t\u003ce.length;t++){const n=e[t],o=Math.floor(n/this.planeSize),s=n-o*this.planeSize;this.markTraceFootprint(i,o,s,r)}const s=[];for(let t=0;t\u003co.length;t++)this.markViaFootprint(i,o[t],r,s);for(;this.usedIndicesByConn.length\u003c=i;)this.usedIndicesByConn.push(void 0);const a=this.usedIndicesByConn[i]??[];for(a.push(...r),this.usedIndicesByConn[i]=a;this.solvedRoutes.length\u003c=i;)this.solvedRoutes.push(void 0);const c=this.solvedRoutes[i]??[];c.push({connId:i,states:Int32Array.from(e),viaCellIds:Int32Array.from(o),startPoint:this.activeConnSeg.startPoint,endPoint:this.activeConnSeg.endPoint,connectionAliases:this.activeConnSeg.connectionAliases}),this.solvedRoutes[i]=c;for(let t=0;t\u003cs.length;t++)if(this.ripTrace(s[t]),this.failed)return;if(this._rippedIds.length\u003e0||s.length\u003e0){const t=this.penalty2d,e=this.penaltyCap;if(this.totalRipEvents\u003e50)for(let e=0;e\u003ct.length;e++)t[e]=.99*t[e];else for(let n=0;n\u003ct.length;n++)t[n]\u003ee\u0026\u0026(t[n]=.5*t[n])}}extractViaCellIds(t){const e=[];for(let n=1;n\u003ct.length;n++){const o=t[n-1],i=t[n],r=Math.floor(o/this.planeSize),s=Math.floor(i/this.planeSize);r!==s\u0026\u0026e.push(i-s*this.planeSize)}return e}markTraceFootprint(t,e,n,o){const i=this.cellCenterX[n],r=this.cellCenterY[n];this.forEachCellNearCircle(i,r,this.traceKeepoutRadius,s=\u003e{if(!vQ(i,r,this.traceKeepoutRadius,this.cellMinX[s],this.cellMinY[s],this.cellMaxX[s],this.cellMaxY[s]))return;const a=e*this.planeSize+s;if(s!==n\u0026\u0026this.shouldSkipFixedPortHalo(a,t))return;const c=this.usedCellsFlat[a],l=this.allowSharedUse(t,c);(-1===c||c===t||l)\u0026\u0026(-1!==c\u0026\u0026c!==t?this.addSharedOccupant(a,t):this.usedCellsFlat[a]=t,o.push(a))})}markViaFootprint(t,e,n,o){const i=this.cellCenterX[e],r=this.cellCenterY[e];this.forEachCellNearCircle(i,r,this.viaKeepoutRadius,s=\u003e{if(vQ(i,r,this.viaKeepoutRadius,this.cellMinX[s],this.cellMinY[s],this.cellMaxX[s],this.cellMaxY[s]))for(let i=0;i\u003cthis.layers;i++){const r=i*this.planeSize+s;if(s!==e\u0026\u0026this.shouldSkipFixedPortHalo(r,t))continue;if(this.fillTraceOccupants(r,t,this._cellOccs),this._cellOccs.length\u003e0){for(let t=0;t\u003cthis._cellOccs.length;t++)bQ(o,this._cellOccs[t]);this.replaceOccupants(r,t),n.push(r);continue}const a=this.usedCellsFlat[r];-1!==a\u0026\u0026a!==t?this.addSharedOccupant(r,t):this.usedCellsFlat[r]=t,n.push(r)}})}forEachCellNearCircle(t,e,n,o){const i=_Q(Math.floor((t-n-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),r=_Q(Math.floor((t+n-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),s=_Q(Math.floor((e-n-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1),a=_Q(Math.floor((e+n-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1);for(let t=0;t\u003cthis.regions.length;t++){const e=this.regions[t];if(0===e.rows||0===e.cols)continue;const n=Math.max(s,e.fineOriginRow),c=Math.min(a,e.fineOriginRow+e.fineRows-1),l=Math.max(i,e.fineOriginCol),d=Math.min(r,e.fineOriginCol+e.fineCols-1);if(n\u003ec)continue;if(l\u003ed)continue;const h=Math.floor((n-e.fineOriginRow)/e.cellScale),u=Math.floor((c-e.fineOriginRow)/e.cellScale),p=Math.floor((l-e.fineOriginCol)/e.cellScale),m=Math.floor((d-e.fineOriginCol)/e.cellScale);for(let t=h;t\u003c=u;t++)for(let n=p;n\u003c=m;n++)o(this.cellIdFor(e.id,t,n))}}ripTrace(t){for(;this.ripCount.length\u003c=t;)this.ripCount.push(0);if(this.ripCount[t]++,this.totalRipEvents++,this.totalRipEvents\u003e=this.MAX_RIPS)return this.error=`Convergence failure: exceeded MAX_RIPS ${this.MAX_RIPS}`,void(this.failed=!0);const e=this.getSolvedRoutesForConn(t);if(e.length\u003e0)for(const t of e){for(let e=0;e\u003ct.states.length;e++){const n=t.states[e]%this.planeSize;this.penalty2d[n]=this.penalty2d[n]+this.hyperParameters.ripTracePenalty}for(let e=0;e\u003ct.viaCellIds.length;e++){const n=t.viaCellIds[e];this.penalty2d[n]=this.penalty2d[n]+this.hyperParameters.ripViaPenalty}}const n=this.usedIndicesByConn[t];if(n){for(let e=0;e\u003cn.length;e++)this.removeOccupant(n[e],t);this.usedIndicesByConn[t]=void 0}if(e.length\u003e0){this.solvedRoutes[t]=void 0;for(const n of e){const e=n.states[0],o=n.states[n.states.length-1],i=Math.floor(e/this.planeSize),r=Math.floor(o/this.planeSize);this.unsolvedSegs.push({connId:t,startZ:i,startCellId:e-i*this.planeSize,startPoint:n.startPoint,endZ:r,endCellId:o-r*this.planeSize,endPoint:n.endPoint,connectionAliases:n.connectionAliases})}}}flattenNeighborLists(t){const e=new Int32Array(t.length+1);let n=0;for(let o=0;o\u003ct.length;o++)e[o]=n,n+=t[o].length;e[t.length]=n;const o=new Int32Array(n),i=new Float32Array(n);let r=0;for(let e=0;e\u003ct.length;e++){const n=t[e];for(let t=0;t\u003cn.length;t++){const e=n[t];o[r]=e.cellId,i[r]=e.cost,r++}}return{offset:e,ids:o,costs:i}}visualize(){const t=[\"red\",\"blue\",\"orange\",\"green\"],e=this.gridToBoundsTransform,n=[],o=[],i=[],r=[];r.push({center:{x:this.nodeWithPortPoints.center.x,y:this.nodeWithPortPoints.center.y},width:this.nodeWithPortPoints.width,height:this.nodeWithPortPoints.height,stroke:\"gray\"});const s=({route:e,connectionName:n,strokeWidth:i,strokeDash:r,labelPrefix:s})=\u003e{if(e.length\u003c2)return;let a=0;for(let c=1;c\u003ce.length;c+=1){const l=e[c-1];e[c].z!==l.z\u0026\u0026(c-a\u003e=2\u0026\u0026o.push({points:e.slice(a,c).map(t=\u003e({x:t.x,y:t.y})),strokeColor:t[l.z]??\"rgba(128,128,128,0.75)\",strokeWidth:i,strokeDash:r,label:`${s} ${n} z=${l.z}`}),a=c)}if(e.length-a\u003c2)return;const c=e[a].z;o.push({points:e.slice(a).map(t=\u003e({x:t.x,y:t.y})),strokeColor:t[c]??\"rgba(128,128,128,0.75)\",strokeWidth:i,strokeDash:r,label:`${s} ${n} z=${c}`})};for(const t of this.obstacles)if(\"rect\"!==t.type){s({route:t.route,connectionName:t.connectionName,strokeWidth:t.traceThickness,strokeDash:[.12,.08],labelPrefix:\"fixed obstacle\"});for(const e of t.vias)i.push({center:{x:e.x,y:e.y},radius:t.viaDiameter/2,fill:\"rgba(128,0,128,0.25)\",stroke:\"purple\",label:`fixed obstacle ${t.connectionName} via`})}else r.push({center:t.center,width:t.width,height:t.height,fill:\"rgba(128,0,128,0.12)\",stroke:\"purple\",label:`fixed obstacle ${t.connectionName}`});if(this.showPenaltyMap\u0026\u0026this.penalty2d){let t=0;for(let e=0;e\u003cthis.penalty2d.length;e++)this.penalty2d[e]\u003et\u0026\u0026(t=this.penalty2d[e]);if(t\u003e0)for(let n=0;n\u003cthis.planeSize;n++){const o=this.penalty2d[n];if(o\u003c=0)continue;const i=iQ(e,{x:this.cellCenterX[n],y:this.cellCenterY[n]}),s=Math.min(.6,o/t*.6);r.push({center:i,width:this.cellWidth[n]*e.a,height:this.cellHeight[n]*e.e,fill:`rgba(255,165,0,${s.toFixed(3)})`})}}if(this.showUsedCellMap\u0026\u0026this.usedCellsFlat)for(let t=0;t\u003cthis.layers;t++){const n=t*this.planeSize;for(let t=0;t\u003cthis.planeSize;t++){if(-1===this.usedCellsFlat[n+t])continue;const o=iQ(e,{x:this.cellCenterX[t],y:this.cellCenterY[t]});r.push({center:o,width:this.cellWidth[t]*e.a,height:this.cellHeight[t]*e.e,fill:\"rgba(0,0,255,0.5)\"})}}for(const e of this.nodeWithPortPoints.portPoints)n.push({x:e.x,y:e.y,color:t[e.z]??\"gray\",label:e.connectionName});const a=this.getOutput();for(const t of a)s({route:t.route,connectionName:t.connectionName,strokeWidth:this.traceThickness,labelPrefix:\"B01 route\"});for(const t of a)for(const e of t.vias)i.push({center:{x:e.x,y:e.y},radius:this.viaDiameter/2,fill:\"rgba(0,0,0,0.3)\",stroke:\"black\",label:`B01 route ${t.connectionName} via`});if(this.activeConnSeg\u0026\u0026this.visitedFlatStamp){const t=this.stamp;for(let o=0;o\u003cthis.layers;o++){const i=o*this.planeSize;for(let o=0;o\u003cthis.planeSize;o++){if(this.visitedFlatStamp[i+o]!==t)continue;const r=iQ(e,{x:this.cellCenterX[o],y:this.cellCenterY[o]});n.push({x:r.x,y:r.y,color:\"rgba(0,0,255,0.2)\"})}}}return{points:n,lines:o,circles:i,rects:r,coordinateSystem:\"cartesian\",title:`HighDensityB01 [${this.getSolvedRouteCount()} solved, ${this.unsolvedSegs?.length??0} remaining]`}}getOutput(){const t=this.gridToBoundsTransform,e=[];for(let n=0;n\u003cthis.solvedRoutes.length;n++){const o=this.getSolvedRoutesForConn(n);if(0!==o.length)for(const n of o){const o=Array.from(n.states,e=\u003e{const n=Math.floor(e/this.planeSize),o=e-n*this.planeSize,i=iQ(t,{x:this.cellCenterX[o],y:this.cellCenterY[o]});return{x:i.x,y:i.y,z:this.layerToZ.get(n)??n}}),i=Array.from(n.viaCellIds,e=\u003eiQ(t,{x:this.cellCenterX[e],y:this.cellCenterY[e]}));for(const t of n.connectionAliases){const n=(t.reversedFromCanonical?[...o].reverse():o).map(t=\u003e({...t}));n.length\u003e0\u0026\u0026(n[0]={...t.startPoint},n.length\u003e1\u0026\u0026(n[n.length-1]={...t.endPoint})),e.push({connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,regionId:this.nodeWithPortPoints.capacityMeshNodeId,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,route:n,vias:i.map(t=\u003e({...t}))})}}}return e}getSolvedRoutesForConn(t){const e=this.solvedRoutes[t];return e?Array.isArray(e)?e:[e]:[]}getSolvedRouteCount(){let t=0;for(let e=0;e\u003cthis.solvedRoutes.length;e++)t+=this.getSolvedRoutesForConn(e).length;return t}computeGridToBoundsTransform(){let t=1/0,e=-1/0,n=1/0,o=-1/0;for(let i=0;i\u003cthis.planeSize;i++){const r=this.cellCenterX[i],s=this.cellCenterY[i];r\u003ct\u0026\u0026(t=r),r\u003ee\u0026\u0026(e=r),s\u003cn\u0026\u0026(n=s),s\u003eo\u0026\u0026(o=s)}const i=e-t,r=o-n,s=this.boundsMaxX-this.boundsMinX,a=this.boundsMaxY-this.boundsMinY,c=i\u003e0?s/i:1,l=r\u003e0?a/r:1;return{a:c,b:0,c:i\u003e0?this.boundsMinX-c*t:(this.boundsMinX+this.boundsMaxX)/2-t,d:0,e:l,f:r\u003e0?this.boundsMinY-l*n:(this.boundsMinY+this.boundsMaxY)/2-n}}},RQ=new WeakMap,EQ=t=\u003e{const e=RQ.get(t);if(e)return e;const n=[],o=[];for(let e=1;e\u003ct.route.length;e++){const i=t.route[e-1],r=t.route[e],s=Math.hypot(r.x-i.x,r.y-i.y),a=Math.max(i.traceThickness??t.traceThickness,r.traceThickness??t.traceThickness);if(i.z!==r.z\u0026\u0026\"through_obstacle\"===i.toNextSegmentType){const e=Math.min(i.z,r.z),c=Math.max(i.z,r.z);if(s\u003c=1e-9){const n=t.vias.some(t=\u003eMath.hypot(t.x-r.x,t.y-r.y)\u003c=1e-9);o.push({center:{x:r.x,y:r.y},minZ:e,maxZ:c,diameter:n?t.viaDiameter:a});continue}for(let t=e;t\u003c=c;t++)n.push({start:{...i,z:t},end:{...r,z:t},z:t,width:a});continue}s\u003e1e-9\u0026\u0026n.push({start:i,end:i.z===r.z?r:{...r,z:i.z},z:i.z,width:a}),i.z!==r.z\u0026\u0026o.push({center:{x:r.x,y:r.y},minZ:Math.min(i.z,r.z),maxZ:Math.max(i.z,r.z),diameter:t.viaDiameter})}const i={wireSegments:n,viaSpans:o};return RQ.set(t,i),i},AQ=(t,e,n)=\u003e{const o=t.end.x-t.start.x,i=t.end.y-t.start.y,r=Math.hypot(o,i),s={x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2};return Math.abs(o)\u003c=1e-9||Math.abs(i)\u003c=1e-9?[{center:s,width:Math.abs(o)\u003eMath.abs(i)?r:t.width,height:Math.abs(o)\u003eMath.abs(i)?t.width:r}]:rX({center:s,width:r,height:t.width,rotation:180*Math.atan2(i,o)/Math.PI},Math.max(n,Math.ceil(r/e)))},OQ=({fixedObstacleRoutes:t,layerCount:e})=\u003et.flatMap((t,n)=\u003e{const o=[t.connectionName,t.rootConnectionName].filter(t=\u003e\"string\"==typeof t),i=EQ(t);return[...i.wireSegments.flatMap((t,i)=\u003eAQ(t,.75,2).map((r,s)=\u003e({obstacleId:`pipeline9_fixed_obstacle_${n}_wire_${i}_${s}`,type:\"rect\",layers:[vo(t.z,e)],center:r.center,width:r.width,height:r.height,connectedTo:o}))),...i.viaSpans.map((t,i)=\u003e({obstacleId:`pipeline9_fixed_obstacle_${n}_via_${i}`,type:\"rect\",layers:Array.from({length:t.maxZ-t.minZ+1},(n,o)=\u003evo(t.minZ+o,e)),center:t.center,width:t.diameter,height:t.diameter,connectedTo:o}))]}),kQ=(t,e,n)=\u003e{const o=[t.connectionName,t.rootConnectionName].filter(t=\u003e\"string\"==typeof t),i=[e.connectionName,e.rootConnectionName].filter(t=\u003e\"string\"==typeof t);return o.some(t=\u003ei.some(e=\u003et===e||n.areIdsConnected(t,e)))},LQ=(t,e)=\u003et.minX\u003c=e.maxX\u0026\u0026t.maxX\u003e=e.minX\u0026\u0026t.minY\u003c=e.maxY\u0026\u0026t.maxY\u003e=e.minY,DQ=({left:t,right:e,clearance:n,leftBounds:o})=\u003e{const i=EQ(t),r=EQ(e),s=o?i.wireSegments.filter(t=\u003e((t,e)=\u003e{const n={minX:Math.min(t.start.x,t.end.x)-t.width/2,maxX:Math.max(t.start.x,t.end.x)+t.width/2,minY:Math.min(t.start.y,t.end.y)-t.width/2,maxY:Math.max(t.start.y,t.end.y)+t.width/2};return LQ(n,e)})(t,o)):i.wireSegments,a=o?i.viaSpans.filter(t=\u003e((t,e)=\u003e{const n={minX:t.center.x-t.diameter/2,maxX:t.center.x+t.diameter/2,minY:t.center.y-t.diameter/2,maxY:t.center.y+t.diameter/2};return LQ(n,e)})(t,o)):i.viaSpans;for(const t of s){for(const e of r.wireSegments){if(t.z!==e.z)continue;const o=t.width/2+e.width/2+n;if(Ra(t.start,t.end,e.start,e.end)\u003co)return!0}for(const e of r.viaSpans){if(t.z\u003ce.minZ||t.z\u003ee.maxZ)continue;const o=t.width/2+e.diameter/2+n;if(Ra(t.start,t.end,e.center,e.center)\u003co)return!0}}for(const t of a){for(const e of r.wireSegments){if(e.z\u003ct.minZ||e.z\u003et.maxZ)continue;const o=t.diameter/2+e.width/2+n;if(Ra(t.center,t.center,e.start,e.end)\u003co)return!0}for(const e of r.viaSpans){if(t.minZ\u003ee.maxZ||e.minZ\u003et.maxZ)continue;const o=t.diameter/2+e.diameter/2+n;if(Math.hypot(t.center.x-e.center.x,t.center.y-e.center.y)\u003co)return!0}}return!1},zQ=({routes:t,movablePreloadedConnectionNames:e,boardObstacles:n,connMap:o,layerCount:i,viaToPadClearance:r})=\u003et.some(t=\u003e{if(!e.has(t.connectionName))return!1;return EQ(t).viaSpans.some(e=\u003en.some(n=\u003e{if(fo(n,t,o))return!1;const s=((t,e)=\u003e{const n=t.__zLayers??t.zLayers;return n||t.layers.map(t=\u003eko(t,e))})(n,i);return!!s.some(t=\u003et\u003e=e.minZ\u0026\u0026t\u003c=e.maxZ)\u0026\u0026((t,e)=\u003e{const n=-1*(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y,r=o*Math.cos(n)-i*Math.sin(n),s=o*Math.sin(n)+i*Math.cos(n),a=Math.max(Math.abs(r)-e.width/2,0),c=Math.max(Math.abs(s)-e.height/2,0);return Math.hypot(a,c)})(e.center,n)\u003ce.diameter/2+r}))}),FQ=class extends si{params;highDensitySolver;forceImproveSolver;repairSolver;phase=\"route\";constructor(t){super(),this.params=t,this.stats={preloadedViaCandidateRejectionCount:0,forceImproveCandidateRejectionCount:0,repairCandidateRejectionCount:0},this.highDensitySolver=new zs({nodePortPoints:[t.nodeWithPortPoints],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:t.nodePfById,obstacles:t.obstacles,layerCount:t.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!1,growShrinkFallbackToInvalidGeometryOnFailure:!1,growShrinkSolutionValidator:t.boardObstacles\u0026\u0026t.movablePreloadedConnectionNames\u0026\u0026void 0!==t.viaToPadClearance?t=\u003ethis.validateCandidateRoutes(t):void 0}),this.activeSubSolver=this.highDensitySolver,this.MAX_ITERATIONS=1e8*t.effort}getSolverName(){return\"Pipeline9RegionalFallbackSolver\"}validateCandidateRoutes(t){const{boardObstacles:e,movablePreloadedConnectionNames:n,viaToPadClearance:o}=this.params;if(!e||!n||void 0===o)return!0;const i=zQ({routes:t,movablePreloadedConnectionNames:n,boardObstacles:e,connMap:this.params.connMap,layerCount:this.params.layerCount,viaToPadClearance:o});return i\u0026\u0026(this.stats.preloadedViaCandidateRejectionCount=Number(this.stats.preloadedViaCandidateRejectionCount??0)+1),!i}_step(){if(\"route\"===this.phase){if(this.highDensitySolver.step(),this.highDensitySolver.failed)return this.error=this.highDensitySolver.error,void(this.failed=!0);if(!this.highDensitySolver.solved)return;const t=AK(this.highDensitySolver.routes);return this.validateCandidateRoutes(t)?(this.forceImproveSolver=new Yy({nodeWithPortPoints:[this.params.nodeWithPortPoints],hdRoutes:t,colorMap:this.params.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*this.params.effort)),nodeAssignmentMargin:this.params.obstacleMargin}),this.activeSubSolver=this.forceImproveSolver,void(this.phase=\"improve\")):(this.error=\"Pipeline9 regional route output failed its candidate validator\",void(this.failed=!0))}if(\"improve\"===this.phase){if(this.forceImproveSolver.step(),this.forceImproveSolver.failed)return this.error=this.forceImproveSolver.error,void(this.failed=!0);if(!this.forceImproveSolver.solved)return;const t=this.forceImproveSolver.getOutput();return this.validateCandidateRoutes(t)?(this.repairSolver=new AY({nodeWithPortPoints:[this.params.nodeWithPortPoints],hdRoutes:t,obstacles:this.params.obstacles,colorMap:this.params.colorMap,repairMargin:this.params.obstacleMargin,maxSampleEntries:80,connMap:this.params.connMap}),this.activeSubSolver=this.repairSolver,void(this.phase=\"repair\")):(this.stats.forceImproveCandidateRejectionCount=Number(this.stats.forceImproveCandidateRejectionCount??0)+1,this.error=\"Pipeline9 regional force-improve output failed its candidate validator\",void(this.failed=!0))}if(\"repair\"===this.phase){if(this.repairSolver.step(),this.repairSolver.failed)return this.error=this.repairSolver.error,void(this.failed=!0);if(!this.repairSolver.solved)return;const t=this.repairSolver.getOutput();return this.validateCandidateRoutes(t)?(this.activeSubSolver=null,this.phase=\"done\",void(this.solved=!0)):(this.stats.repairCandidateRejectionCount=Number(this.stats.repairCandidateRejectionCount??0)+1,this.error=\"Pipeline9 regional repair output failed its candidate validator\",void(this.failed=!0))}}getOutput(){return this.repairSolver?.getOutput()??this.forceImproveSolver?.getOutput()??this.highDensitySolver.routes}visualize(){return this.repairSolver?.visualize()??this.forceImproveSolver?.visualize()??this.highDensitySolver.visualize()}},BQ=(t,e)=\u003e({minX:t.center.x-t.width/2-e,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2-e,maxY:t.center.y+t.height/2+e}),jQ=(t,e,n)=\u003e{const o=Math.max(n.minX-t.x,0,t.x-n.maxX),i=Math.max(n.minY-t.y,0,t.y-n.maxY);return o*o+i*i\u003c=e*e},$Q=(t,e,n,o)=\u003eMath.min(t.x,e.x)-n\u003c=o.maxX\u0026\u0026Math.max(t.x,e.x)+n\u003e=o.minX\u0026\u0026Math.min(t.y,e.y)-n\u003c=o.maxY\u0026\u0026Math.max(t.y,e.y)+n\u003e=o.minY,YQ=(t,e)=\u003e{const n=t=\u003e({...t,rootConnectionName:e.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName});return{...t,portPoints:t.portPoints.map(n),portPointsInPairs:t.portPointsInPairs?.map(([t,e])=\u003e[n(t),n(e)])}},XQ=({nodeWithPortPoints:t,connMap:e,colorMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a,obstacles:c,layerCount:l})=\u003enew zs({nodePortPoints:[YQ(t,e)],colorMap:n,connMap:e,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a,obstacles:c,layerCount:l,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!1,growShrinkFallbackToInvalidGeometryOnFailure:!1,captureSearchDebug:!1}),VQ=class extends si{fixedHdRoutes;connMap;colorMap;obstacles;layerCount;viaDiameter;traceWidth;obstacleMargin;viaToPadClearance;effort;nodePfById;preserveTerminalPcbPortIds;includeBoardObstacles;enableRegionalFallback;maxB01Rips;routes=[];failedSolvers=[];unsolvedNodePortPoints;fixedRouteReplacements=new Map;removedFixedRouteConnectionNames=new Set;preloadedTraceMutationMasks=new Map;activeRegularSolver=null;activeB01Solver=null;activeFallbackSolver=null;activeFallbackFixedRouteSections=new Map;activeFallbackFixedObstacleRoutes=[];activeFallbackPromotedFixedRouteConnectionNames=new Set;activeFallbackReason=null;activeNode=null;constructor(t){super(),this.fixedHdRoutes=t.fixedHdRoutes,this.connMap=t.connMap,this.colorMap=t.colorMap??{},this.obstacles=t.obstacles,this.layerCount=t.layerCount,this.viaDiameter=t.viaDiameter,this.traceWidth=t.traceWidth,this.obstacleMargin=t.obstacleMargin,this.viaToPadClearance=t.viaToPadClearance,this.effort=t.effort,this.nodePfById=t.nodePfById instanceof Map?new Map(t.nodePfById):new Map(Object.entries(t.nodePfById??{})),this.preserveTerminalPcbPortIds=t.preserveTerminalPcbPortIds??!1,this.includeBoardObstacles=t.includeBoardObstacles??!1,this.enableRegionalFallback=t.enableRegionalFallback??!0,this.maxB01Rips=t.maxB01Rips,this.unsolvedNodePortPoints=[...t.nodePortPoints],this.MAX_ITERATIONS=1e8*this.effort,this.stats={nodeCount:t.nodePortPoints.length,solvedNodeCount:0,fixedObstacleCount:t.fixedHdRoutes.length,fixedObstacleUses:0,boardObstacleUses:0,fallbackNodeCount:0,regularNodeCount:0,b01NodeCount:0,reroutedFixedRouteCount:0,reroutedFixedRouteSectionCount:0,promotedFallbackAttemptCount:0,promotedFixedRouteCount:0,regionalPreloadedViaCandidateRejectionCount:0,regionalForceImproveCandidateRejectionCount:0,regionalRepairCandidateRejectionCount:0}}getSolverName(){return\"Pipeline9HighDensitySolver\"}getUpdatedFixedHdRoutes(){return this.fixedHdRoutes.flatMap(t=\u003ethis.removedFixedRouteConnectionNames.has(t.connectionName)?[]:[this.fixedRouteReplacements.get(t.connectionName)??t])}finishActiveNode(t){const e=this.activeNode?((t,e)=\u003et.map(t=\u003e({...t,rootConnectionName:e.portPoints.find(e=\u003ee.connectionName===t.connectionName)?.rootConnectionName??t.rootConnectionName})))(t,this.activeNode):t;this.routes.push(...this.preserveTerminalPcbPortIds\u0026\u0026this.activeNode?((t,e)=\u003e{const n=e.portPoints.filter(t=\u003evoid 0!==t.pcb_port_id);return t.map(t=\u003e{const e=t.route[0],o=t.route.at(-1),i=n.find(n=\u003evoid 0!==e\u0026\u0026n.connectionName===t.connectionName\u0026\u0026n.x===e.x\u0026\u0026n.y===e.y\u0026\u0026n.z===e.z),r=n.find(e=\u003evoid 0!==o\u0026\u0026e.connectionName===t.connectionName\u0026\u0026e.x===o.x\u0026\u0026e.y===o.y\u0026\u0026e.z===o.z);return{...t,startPcbPortId:i?.pcb_port_id,endPcbPortId:r?.pcb_port_id}})})(e,this.activeNode):e),this.stats.solvedNodeCount=Number(this.stats.solvedNodeCount??0)+1,this.activeB01Solver=null,this.activeRegularSolver=null,this.activeFallbackSolver=null,this.activeFallbackFixedRouteSections.clear(),this.activeFallbackFixedObstacleRoutes=[],this.activeFallbackPromotedFixedRouteConnectionNames.clear(),this.activeFallbackReason=null,this.activeNode=null}startRegularSolver(t){this.activeNode=t,this.activeRegularSolver=XQ({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById,obstacles:this.obstacles,layerCount:this.layerCount}),this.stats.regularNodeCount=Number(this.stats.regularNodeCount??0)+1}startRegionalFallback(t=new Set){if(!this.activeNode)throw new Error(\"Pipeline9 cannot start a regional fallback without an active node\");const e={...YQ(this.activeNode,this.connMap),availableZ:Array.from({length:this.layerCount},(t,e)=\u003ee)},n=$K(e,this.getUpdatedFixedHdRoutes(),t),o=new Set([...n.fixedRouteSectionsByConnectionName.values()].flatMap(t=\u003et.sourceRoutes.map(t=\u003et.connectionName)));for(const e of t)if(!o.has(e))throw new Error(`Pipeline9 could not promote fixed route \"${e}\" into the active regional fallback`);const i=[...t].filter(t=\u003e!this.activeFallbackPromotedFixedRouteConnectionNames.has(t)).length;this.activeFallbackFixedRouteSections=n.fixedRouteSectionsByConnectionName,this.activeFallbackFixedObstacleRoutes=n.fixedObstacleRoutes,this.activeFallbackPromotedFixedRouteConnectionNames=new Set(t);const r=OQ({fixedObstacleRoutes:this.activeFallbackFixedObstacleRoutes,layerCount:this.layerCount});this.activeFallbackSolver=new FQ({nodeWithPortPoints:n.nodeWithPortPoints,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById,obstacles:[...this.obstacles,...r],boardObstacles:this.obstacles,movablePreloadedConnectionNames:o,viaToPadClearance:this.viaToPadClearance,layerCount:this.layerCount}),0===t.size?this.stats.fallbackNodeCount=Number(this.stats.fallbackNodeCount??0)+1:(this.stats.promotedFallbackAttemptCount=Number(this.stats.promotedFallbackAttemptCount??0)+1,this.stats.promotedFixedRouteCount=Number(this.stats.promotedFixedRouteCount??0)+i)}finishRegionalFallback(){if(!this.activeFallbackSolver)return;if(!this.activeNode)throw new Error(\"Pipeline9 cannot finish a regional fallback without an active node\");this.recordRegionalCandidateRejections();const t=[],e=new Map;for(const n of this.activeFallbackSolver.getOutput()){if(!this.activeFallbackFixedRouteSections.has(n.connectionName)){t.push(n);continue}const o=e.get(n.connectionName)??[];o.push(n),e.set(n.connectionName,o)}const n=[],o=[];for(const[t,i]of this.activeFallbackFixedRouteSections){const r=e.get(t)??[];if(0===r.length){o.push(i);continue}if(r.length\u003e1)return this.error=`Pipeline9 regional fallback expected one replacement for fixed route \"${t}\", got ${r.length}`,void(this.failed=!0);const s=VK({section:i,replacement:r[0],sourceMutationMasks:this.preloadedTraceMutationMasks,replacementIsMutated:!0});n.push({connectionName:t,section:i,replacement:s.route,mutatedSegments:s.mutatedSegments,replacementProducedSegment:s.replacementProducedSegment})}const i=[...t,...n.map(({replacement:t})=\u003et)],r=[...this.activeFallbackFixedObstacleRoutes,...o.flatMap(t=\u003et.sourceRoutes)],s=BQ(this.activeNode,this.obstacleMargin+Math.max(this.traceWidth,this.viaDiameter)/2),a=new Map;for(const t of i)for(const e of r)kQ(t,e,this.connMap)||DQ({left:t,right:e,clearance:this.obstacleMargin,leftBounds:s})\u0026\u0026a.set(e.connectionName,e);if(a.size\u003e0){const t=[...a.keys()],e=[...a].flatMap(([t,e])=\u003e!0===e.isThroughObstacle?[]:[t]),n=new Set(this.activeFallbackPromotedFixedRouteConnectionNames);for(const t of e)n.add(t);if(n.size===this.activeFallbackPromotedFixedRouteConnectionNames.size){const e=[...a].flatMap(([t,e])=\u003e!0===e.isThroughObstacle?[t]:[]);return this.error=e.length\u003e0?`Pipeline9 regional fallback conflicts with immutable through-obstacle route(s): ${e.join(\", \")}`:`Pipeline9 promoted regional fallback could not resolve immutable fixed route conflict(s): ${t.join(\", \")}`,void(this.failed=!0)}return void this.startRegionalFallback(n)}const c=new Map;for(const{section:t,replacementProducedSegment:e}of n)if(e)for(const e of t.sourceRoutes){const t=e.preloadedRoutePositionStart,n=e.preloadedRoutePositionEnd;if(void 0===t!=(void 0===n))throw new Error(`Pipeline9 fixed route \"${e.connectionName}\" has incomplete route-position metadata`);const o=Math.min(t??e.preloadedRouteIndex,n??e.preloadedRouteIndex),i=Math.max(t??e.preloadedRouteIndex,n??e.preloadedRouteIndex),r=c.get(e.preloadedTraceIndex);c.set(e.preloadedTraceIndex,{start:Math.min(r?.start??o,o),end:Math.max(r?.end??i,i)})}for(const{connectionName:t,section:e,replacement:o,mutatedSegments:i}of n){this.fixedRouteReplacements.set(t,o),this.preloadedTraceMutationMasks.set(t,i);for(const t of e.sourceRoutes.slice(1))this.removedFixedRouteConnectionNames.add(t.connectionName),this.preloadedTraceMutationMasks.delete(t.connectionName)}const l=$K({...YQ(this.activeNode,this.connMap),portPoints:[],portPointsInPairs:[],availableZ:Array.from({length:this.layerCount},(t,e)=\u003ee)},this.getUpdatedFixedHdRoutes()),d=new Set;for(const t of l.fixedRouteSectionsByConnectionName.values()){const e=t.sourceRoutes[0];if(!e)continue;const n=c.get(e.preloadedTraceIndex);if(n)for(const[o,i]of t.sourceRoutes.entries()){const r=i.preloadedRoutePositionStart??i.preloadedRouteIndex,s=i.preloadedRoutePositionEnd??i.preloadedRouteIndex,a={start:Math.min(r,s),end:Math.max(r,s)},c=a.start===a.end,l=n.start===n.end;if(!(c||l?a.start\u003c=n.end\u0026\u0026n.start\u003c=a.end:a.start\u003cn.end\u0026\u0026n.start\u003ca.end))continue;d.add(e.preloadedTraceIndex);const h=[...this.preloadedTraceMutationMasks.get(i.connectionName)??Array(i.route.length-1).fill(!1)];if(h.length!==i.route.length-1)throw new Error(`Pipeline9 fixed route mutation mask for \"${i.connectionName}\" has ${h.length} segments, expected ${i.route.length-1}`);const u=0===o?t.start.segmentIndex:0,p=o===t.sourceRoutes.length-1?t.end.segmentIndex:i.route.length-2;for(let t=u;t\u003c=p;t++)h[t]=!0;this.preloadedTraceMutationMasks.set(i.connectionName,h)}}for(const t of c.keys())if(!d.has(t))throw new Error(`Pipeline9 could not capture accepted mutation provenance for trace ${t}`);const h=n.reduce((t,{section:e})=\u003et+e.sourceRoutes.length,0);this.stats.reroutedFixedRouteCount=Number(this.stats.reroutedFixedRouteCount??0)+h,this.stats.reroutedFixedRouteSectionCount=Number(this.stats.reroutedFixedRouteSectionCount??0)+n.length,this.finishActiveNode(t)}recordRegionalCandidateRejections(){if(!this.activeFallbackSolver)return;const t=this.activeFallbackSolver.stats;this.stats.regionalPreloadedViaCandidateRejectionCount=Number(this.stats.regionalPreloadedViaCandidateRejectionCount??0)+Number(t.preloadedViaCandidateRejectionCount??0),this.stats.regionalForceImproveCandidateRejectionCount=Number(this.stats.regionalForceImproveCandidateRejectionCount??0)+Number(t.forceImproveCandidateRejectionCount??0),this.stats.regionalRepairCandidateRejectionCount=Number(this.stats.regionalRepairCandidateRejectionCount??0)+Number(t.repairCandidateRejectionCount??0)}finishRegularSolverFailure(t){if(this.activeFallbackReason=`regular high-density routing failed: ${t}`,this.activeRegularSolver=null,!this.enableRegionalFallback)return this.error=`Pipeline9 ${this.activeFallbackReason}`,this.failed=!0,void(this.activeNode=null);this.startRegionalFallback()}_step(){if(this.activeFallbackSolver){if(this.activeFallbackSolver.step(),this.activeFallbackSolver.failed)return this.recordRegionalCandidateRejections(),this.error=[`Pipeline9 primary high-density routing failed: ${this.activeFallbackReason??\"unknown error\"}`,`regional fallback failed: ${this.activeFallbackSolver.error??\"unknown error\"}`].join(\"; \"),this.failed=!0,this.activeFallbackSolver=null,this.activeFallbackFixedRouteSections.clear(),this.activeFallbackFixedObstacleRoutes=[],this.activeFallbackPromotedFixedRouteConnectionNames.clear(),void(this.activeNode=null);if(!this.activeFallbackSolver.solved)return;return void this.finishRegionalFallback()}if(this.activeRegularSolver){if(this.activeRegularSolver.step(),this.activeRegularSolver.failed)return void this.finishRegularSolverFailure(this.activeRegularSolver.error??\"unknown error\");if(!this.activeRegularSolver.solved)return;return void this.finishActiveNode(this.activeRegularSolver.routes)}if(this.activeB01Solver){if(this.activeB01Solver.step(),this.activeB01Solver.failed)return this.failedSolvers.push(this.activeB01Solver),this.activeFallbackReason=`B01 failed: ${this.activeB01Solver.error??\"unknown error\"}`,this.activeB01Solver=null,this.enableRegionalFallback?void this.startRegionalFallback():(this.error=`Pipeline9 ${this.activeFallbackReason}`,this.failed=!0,void(this.activeNode=null));if(!this.activeB01Solver.solved)return;return void this.finishActiveNode(this.activeB01Solver.getOutput())}const t=this.unsolvedNodePortPoints.pop();if(!t)return void(this.solved=!0);const e=BQ(t,this.obstacleMargin),n=Math.max(this.traceWidth,this.viaDiameter)/2,o=this.getUpdatedFixedHdRoutes().filter(o=\u003e((t,e,n,o)=\u003e{const i=new Set(e.availableZ??e.portPoints.map(t=\u003et.z));for(let e=1;e\u003ct.route.length;e++){const r=t.route[e-1],s=t.route[e];if(r.z===s.z){if(i.has(r.z)\u0026\u0026$Q(r,s,t.traceThickness/2+o,n))return!0;continue}const a=Math.min(r.z,s.z),c=Math.max(r.z,s.z);if([...i].some(t=\u003et\u003e=a\u0026\u0026t\u003c=c)\u0026\u0026jQ(s,t.viaDiameter/2+o,n))return!0}return!1})(o,t,e,n)).flatMap(e=\u003e((t,e)=\u003e{const n=new Set(e.availableZ??e.portPoints.map(t=\u003et.z));if(0===n.size)throw new Error(`Pipeline9 B01 node \"${e.capacityMeshNodeId}\" has no available layers`);const o={type:\"route\",connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,traceThickness:t.traceThickness,viaDiameter:t.viaDiameter},i=[];for(let e=1;e\u003ct.route.length;e++){const r=t.route[e-1],s=t.route[e];if(r.z===s.z){if(!n.has(r.z))continue;i.push({...o,route:[r,s],vias:[]});continue}const a=Math.min(r.z,s.z),c=Math.max(r.z,s.z);[...n].some(t=\u003et\u003e=a\u0026\u0026t\u003c=c)\u0026\u0026i.push({...o,route:[r,s],vias:[{x:s.x,y:s.y,zStart:r.z,zEnd:s.z}]})}return i})(e,t));if(this.stats.fixedObstacleUses=Number(this.stats.fixedObstacleUses??0)+o.length,0===o.length)return void this.startRegularSolver(t);const i=(this.includeBoardObstacles?this.obstacles:[]).filter(t=\u003e((t,e)=\u003e{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.abs(Math.cos(n)),i=Math.abs(Math.sin(n)),r=t.width/2*o+t.height/2*i,s=t.width/2*i+t.height/2*o;return t.center.x-r\u003c=e.maxX\u0026\u0026t.center.x+r\u003e=e.minX\u0026\u0026t.center.y-s\u003c=e.maxY\u0026\u0026t.center.y+s\u003e=e.minY})(t,e)).map(e=\u003e(({obstacle:t,node:e,connMap:n,layerCount:o})=\u003e{const i=new Set(e.availableZ??e.portPoints.map(t=\u003et.z)),r=(t.zLayers??t.layers.map(t=\u003eko(t,o))).filter(t=\u003ei.has(t));if(0===r.length)return;const s=t.connectedTo[0]??t.obstacleId??`pipeline9_obstacle_${t.center.x}_${t.center.y}`;return{type:\"rect\",connectionName:s,rootConnectionName:n.getNetConnectedToId(s)??s,center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,zLayers:r}})({obstacle:e,node:t,connMap:this.connMap,layerCount:this.layerCount})).filter(t=\u003evoid 0!==t);if(this.stats.boardObstacleUses=Number(this.stats.boardObstacleUses??0)+i.length,this.activeNode=t,t.width\u003e15||t.height\u003e15)return this.activeFallbackReason=`B01 node \"${t.capacityMeshNodeId}\" exceeds the 15x15mm routing limit (${t.width}x${t.height}mm)`,void this.startRegionalFallback();const r=YQ(t,this.connMap);this.stats.b01NodeCount=Number(this.stats.b01NodeCount??0)+1,this.activeB01Solver=new TQ({...sQ,nodeWithPortPoints:r,obstacles:[...o,...i],viaDiameter:this.viaDiameter,viaMinDistFromBorder:this.viaDiameter/2,traceThickness:this.traceWidth,traceMargin:this.obstacleMargin,obstacleClearanceMargin:.15,effort:this.effort}),void 0!==this.maxB01Rips\u0026\u0026(this.activeB01Solver.MAX_RIPS=this.maxB01Rips)}visualize(){return this.activeFallbackSolver?.visualize()??this.activeRegularSolver?.visualize()??this.activeB01Solver?.visualize()??{lines:this.routes.flatMap(t=\u003et.route.slice(0,-1).map((e,n)=\u003e({points:[e,t.route[n+1]],strokeWidth:t.traceThickness,layer:`z${e.z}`,label:t.connectionName}))),points:[],rects:[],circles:[]}}},WQ=(t,e)=\u003e{const n=e*Math.PI/180;return{x:t.x*Math.cos(n)-t.y*Math.sin(n),y:t.x*Math.sin(n)+t.y*Math.cos(n)}},HQ=({x:t,y:e,width:n,height:o,ccwRotation:i})=\u003e{const r=n/2,s=o/2;return[{x:-r,y:-s},{x:r,y:-s},{x:r,y:s},{x:-r,y:s}].map(n=\u003e{const o=WQ(n,i);return{x:t+o.x,y:e+o.y}})},GQ=t=\u003e{const e=\"rotated_pill\"===t.shape?t.ccw_rotation:0,n=Math.max(Math.max(t.width,t.height)/2-t.radius,0),o=t.width\u003e=t.height?{x:n,y:0}:{x:0,y:n},i=WQ(o,e);return{start:{x:t.x-i.x,y:t.y-i.y},end:{x:t.x+i.x,y:t.y+i.y},radius:t.radius}},UQ=t=\u003e{if(\"pcb_smtpad\"===t.type){if(\"polygon\"===t.shape)return t.points;if(\"rotated_rect\"===t.shape)return HQ({x:t.x,y:t.y,width:t.width,height:t.height,ccwRotation:t.ccw_rotation})}if(\"pcb_plated_hole\"===t.type\u0026\u0026\"rect_pad_width\"in t\u0026\u0026\"rect_pad_height\"in t)return HQ({x:t.x,y:t.y,width:t.rect_pad_width,height:t.rect_pad_height,ccwRotation:\"rect_ccw_rotation\"in t\u0026\u0026\"number\"==typeof t.rect_ccw_rotation?t.rect_ccw_rotation:0});throw new Error(`Expected polygonal pad geometry, got ${t.type} with shape \"${t.shape}\"`)},ZQ=t=\u003et.map((e,n)=\u003e[e,t[(n+1)%t.length]]),qQ=(t,e,n,o)=\u003e{const i=ve(t,e,n,o);if(i)return{distance:0,pointOnA:i,pointOnB:i,center:i};const r=[{pointOnA:t,pointOnB:ze(t,n,o)},{pointOnA:e,pointOnB:ze(e,n,o)},{pointOnA:ze(n,t,e),pointOnB:n},{pointOnA:ze(o,t,e),pointOnB:o}];let s=r[0],a=Ye(s.pointOnA,s.pointOnB);for(const t of r.slice(1)){const e=Ye(t.pointOnA,t.pointOnB);e\u003ca\u0026\u0026(s=t,a=e)}return{distance:Oe(t,e,n,o),pointOnA:s.pointOnA,pointOnB:s.pointOnB,center:{x:(s.pointOnA.x+s.pointOnB.x)/2,y:(s.pointOnA.y+s.pointOnB.y)/2}}};function JQ(t,e){return Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2)}var KQ=1e-9,QQ=1e-9;function t0(t,e){const n=(t.y-e.start.y)*(e.end.x-e.start.x)-(t.x-e.start.x)*(e.end.y-e.start.y);if(Math.abs(n)\u003eKQ)return!1;const o=(t.x-e.start.x)*(e.end.x-e.start.x)+(t.y-e.start.y)*(e.end.y-e.start.y);if(o\u003c-1e-9)return!1;return o\u003c=(e.end.x-e.start.x)**2+(e.end.y-e.start.y)**2+KQ}function e0(t,e){let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];if(t0(t,{start:r,end:s}))return!0;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n}function n0(t,e){if(\"pcb_smtpad\"===e.type){if(\"circle\"===e.shape)return JQ(t,e)\u003c=e.radius+QQ;if(\"rect\"===e.shape){const n=e.width/2,o=e.height/2;return Math.abs(t.x-e.x)\u003c=n+QQ\u0026\u0026Math.abs(t.y-e.y)\u003c=o+QQ}if(\"rotated_rect\"===e.shape)return e0(t,UQ(e));if(\"pill\"===e.shape||\"rotated_pill\"===e.shape){if(\"rotated_pill\"===e.shape){const n=GQ(e);return be(t,n.start,n.end)\u003c=n.radius+QQ}const n=e.width/2,o=e.height/2,i=e.radius;if(Math.abs(t.x-e.x)\u003c=n-i+QQ\u0026\u0026Math.abs(t.y-e.y)\u003c=o+QQ)return!0;const r=Math.max(Math.abs(t.x-e.x)-(n-i),0),s=Math.max(Math.abs(t.y-e.y)-(o-i),0),a=i+QQ;return r*r+s*s\u003c=a*a}if(\"polygon\"===e.shape)return e0(t,e.points)}if(\"pcb_plated_hole\"===e.type){if(\"circle\"===e.shape)return JQ(t,e)\u003c=e.outer_diameter/2+QQ;if(\"rect_pad_width\"in e\u0026\u0026\"rect_pad_height\"in e)return e0(t,UQ(e));if(\"oval\"===e.shape||\"pill\"===e.shape)return Math.abs(t.x-e.x)\u003c=e.outer_width/2+QQ\u0026\u0026Math.abs(t.y-e.y)\u003c=e.outer_height/2+QQ}return!1}function o0(t,e,n,o){return Math.sqrt((n-t)**2+(o-e)**2)}var i0=.1,r0=.1,s0=.2,a0=.1,c0=.005,l0=t=\u003et.find(t=\u003e\"pcb_board\"===t.type),d0=(t,e)=\u003et?.[e],h0=t=\u003eEM([t]),u0=t=\u003e{const e=h0(t);return Math.min(e.maxX-e.minX,e.maxY-e.minY)/2},p0=t=\u003e{const e=(t=\u003e{const e=h0(t);return $e({x:e.minX,y:e.minY},{x:e.maxX,y:e.maxY})})(t);return{kind:\"circle\",x:e.x,y:e.y,radius:u0(t)}},m0=t=\u003evM(t).pcb_trace.list().flatMap(t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];\"wire\"===o.route_type\u0026\u0026(\"wire\"===i.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({type:\"pcb_trace_segment\",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:\"width\"in o?o.width:\"width\"in i?i.width:a0,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),g0=t=\u003e{const e=t._pcbTrace.route.flatMap(t=\u003e\"through_pad\"===t.route_type?[t.start,t.end]:[{x:t.x,y:t.y}]),n=e[0],o=e[e.length-1];return n\u0026\u0026o?$e(n,o):$e({x:t.x1,y:t.y1},{x:t.x2,y:t.y2})},f0=({tracePoint:t,obstaclePoint:e,traceRadius:n,obstacleRadius:o})=\u003e{const i=e.x-t.x,r=e.y-t.y,s=Math.hypot(i,r);if(0===s)return $e(t,e);const a=i/s,c=r/s;return $e({x:t.x+a*n,y:t.y+c*n},{x:e.x-a*o,y:e.y-c*o})},y0=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=t.thickness/2;if(\"pcb_via\"===e.type||(\"pcb_via\"===(r=e).type||\"circle\"===r.shape)){const t=\"pcb_via\"===e.type?{x:e.x,y:e.y,radius:e.outer_diameter/2}:p0(e),r=ze(t,n,o);return{gap:De(n,o,t)-i,center:f0({tracePoint:r,obstaclePoint:t,traceRadius:i,obstacleRadius:t.radius})}}var r;if((t=\u003e\"pcb_smtpad\"===t.type\u0026\u0026(\"pill\"===t.shape||\"rotated_pill\"===t.shape))(e)){const n=((t,e)=\u003e{const n=GQ(e),o=qQ({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},n.start,n.end);return{distance:o.distance,center:o.center,radius:n.radius,tracePoint:o.pointOnA,obstaclePoint:o.pointOnB}})(t,e);return{gap:n.distance-i-n.radius,center:f0({tracePoint:n.tracePoint,obstaclePoint:n.obstaclePoint,traceRadius:i,obstacleRadius:n.radius})}}const s=((t,e,n)=\u003e{if(n.length\u003c3)return{distance:Number.POSITIVE_INFINITY,center:t,tracePoint:t,obstaclePoint:t};const o=ZQ(n).map(([n,o])=\u003eve(t,e,n,o)).filter(t=\u003enull!==t);if(o.length\u003e0){const n=e.x-t.x,i=e.y-t.y,r=n*n+i*i;return o.sort((e,o)=\u003e((e.x-t.x)*n+(e.y-t.y)*i)/r-((o.x-t.x)*n+(o.y-t.y)*i)/r),{distance:0,center:o[0],tracePoint:o[0],obstaclePoint:o[0]}}if(Ne(t,n)||Ne(e,n)){const n={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return{distance:0,center:n,tracePoint:n,obstaclePoint:n}}let i=qQ(t,e,n[0],n[1]);for(const[o,r]of ZQ(n).slice(1)){const n=qQ(t,e,o,r);n.distance\u003ci.distance\u0026\u0026(i=n)}return{distance:i.distance,center:i.center,tracePoint:i.pointOnA,obstaclePoint:i.pointOnB}})(n,o,(t=\u003e{if(\"pcb_smtpad\"===t.type\u0026\u0026(\"polygon\"===t.shape||\"rotated_rect\"===t.shape))return{kind:\"polygon\",points:UQ(t)};if(\"pcb_plated_hole\"===t.type\u0026\u0026\"rect_pad_width\"in t\u0026\u0026\"rect_pad_height\"in t)return{kind:\"polygon\",points:UQ(t)};const e=h0(t);return{kind:\"polygon\",points:[{x:e.minX,y:e.minY},{x:e.maxX,y:e.minY},{x:e.maxX,y:e.maxY},{x:e.minX,y:e.maxY}]}})(e).points);return{gap:s.distance-i,center:f0({tracePoint:s.tracePoint,obstaclePoint:s.obstaclePoint,traceRadius:i,obstacleRadius:0})}},_0=t=\u003et\u003c=0,b0=class{buckets;objectsById;getBounds;getId;CELL_SIZE=.4;constructor({objects:t,getBounds:e,getId:n,CELL_SIZE:o}){this.buckets=new Map,this.objectsById=new Map,this.getBounds=e,this.getId=n??(()=\u003ethis._getNextId()),this.CELL_SIZE=o??this.CELL_SIZE;for(const e of t)this.addObject(e)}_idCounter=0;_getNextId(){return\"\"+this._idCounter++}addObject(t){const e=this.getBounds(t),n=this.getId(t),o={...t,spatialIndexId:n};this.objectsById.set(n,o);const i=Math.floor(e.minX/this.CELL_SIZE),r=Math.floor(e.minY/this.CELL_SIZE),s=Math.floor(e.maxX/this.CELL_SIZE),a=Math.floor(e.maxY/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const n=`${t}x${e}`,i=this.buckets.get(n);i?i.push(o):this.buckets.set(n,[o])}}removeObject(t){const e=this.objectsById.get(t);if(!e)return!1;this.objectsById.delete(t);const n=this.getBounds(e),o=Math.floor(n.minX/this.CELL_SIZE),i=Math.floor(n.minY/this.CELL_SIZE),r=Math.floor(n.maxX/this.CELL_SIZE),s=Math.floor(n.maxY/this.CELL_SIZE);for(let e=o;e\u003c=r;e++)for(let n=i;n\u003c=s;n++){const o=`${e}x${n}`,i=this.buckets.get(o);if(i){const e=i.findIndex(e=\u003ee.spatialIndexId===t);-1!==e\u0026\u0026(i.splice(e,1),0===i.length\u0026\u0026this.buckets.delete(o))}}return!0}getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getObjectsInBounds(t,e=0){const n=[],o=new Set,i=Math.floor((t.minX-e)/this.CELL_SIZE),r=Math.floor((t.minY-e)/this.CELL_SIZE),s=Math.floor((t.maxX+e)/this.CELL_SIZE),a=Math.floor((t.maxY+e)/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const i=`${t}x${e}`,r=this.buckets.get(i)||[];for(const t of r){const e=t.spatialIndexId;o.has(e)||(o.add(e),n.push(t))}}return n}};function x0(t){return\"pcb_trace_segment\"===t.type||\"pcb_smtpad\"===t.type?[t.layer]:\"pcb_plated_hole\"===t.type?Array.isArray(t.layers)?t.layers:[...WS]:\"pcb_hole\"===t.type?[...WS]:\"pcb_via\"===t.type?Array.isArray(t.layers)?t.layers:[...WS]:\"pcb_keepout\"===t.type\u0026\u0026Array.isArray(t.layers)?t.layers:[]}var v0=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=e.minX,r=e.minY,s=e.maxX,a=e.maxY;if(n.x===o.x\u0026\u0026n.y===o.y){const t=Math.max(i,Math.min(s,n.x)),e=Math.max(r,Math.min(a,n.y));return t===n.x\u0026\u0026e===n.y?{x:n.x,y:n.y}:{x:t,y:e}}const c=o.x-n.x,l=o.y-n.y,d=0!==c?(i-n.x)/c:Number.NEGATIVE_INFINITY,h=0!==c?(s-n.x)/c:Number.POSITIVE_INFINITY,u=0!==l?(r-n.y)/l:Number.NEGATIVE_INFINITY,p=0!==l?(a-n.y)/l:Number.POSITIVE_INFINITY,m=Math.max(Math.min(d,h),Math.min(u,p)),g=Math.min(Math.max(d,h),Math.max(u,p));if(m\u003c=g\u0026\u0026g\u003e=0\u0026\u0026m\u003c=1){const t=Math.max(0,Math.min(1,m));return{x:n.x+t*c,y:n.y+t*l}}const f={x:Math.max(i,Math.min(s,n.x)),y:Math.max(r,Math.min(a,n.y))},y={x:Math.max(i,Math.min(s,o.x)),y:Math.max(r,Math.min(a,o.y))},_=(f.x-n.x)**2+(f.y-n.y)**2,b=(y.x-o.x)**2+(y.y-o.y)**2,x=[{start:{x:i,y:r},end:{x:s,y:r}},{start:{x:s,y:r},end:{x:s,y:a}},{start:{x:s,y:a},end:{x:i,y:a}},{start:{x:i,y:a},end:{x:i,y:r}}];let v=Math.min(_,b),S=_\u003c=b?f:y;const I=(t,e,n)=\u003eMath.max(e,Math.min(n,t));for(const t of x){const e={x:o.x-n.x,y:o.y-n.y},i={x:t.end.x-t.start.x,y:t.end.y-t.start.y},r={x:n.x-t.start.x,y:n.y-t.start.y},s=e.x*e.x+e.y*e.y,a=e.x*i.x+e.y*i.y,c=e.x*r.x+e.y*r.y,l=i.x*i.x+i.y*i.y,d=i.x*r.x+i.y*r.y,h=s*l-a*a;if(Math.abs(h)\u003c1e-10)continue;let u=(a*d-l*c)/h,p=(s*d-a*c)/h;u=I(u,0,1),p=I(p,0,1);const m={x:n.x+u*e.x,y:n.y+u*e.y},g={x:t.start.x+p*i.x,y:t.start.y+p*i.y},f=m.x-g.x,y=m.y-g.y,_=f*f+y*y;_\u003cv\u0026\u0026(v=_,S={x:(m.x+g.x)/2,y:(m.y+g.y)/2})}return S},S0=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i={x:e.x1,y:e.y1},r={x:e.x2,y:e.y2},s={x:o.x-n.x,y:o.y-n.y},a={x:r.x-i.x,y:r.y-i.y},c=s.x*s.x+s.y*s.y,l=a.x*a.x+a.y*a.y;if(0===c||0===l){if(0===c\u0026\u00260===l)return{x:(n.x+i.x)/2,y:(n.y+i.y)/2};if(0===c){const t=C0(((n.x-i.x)*a.x+(n.y-i.y)*a.y)/l,0,1),e={x:i.x+t*a.x,y:i.y+t*a.y};return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}}const t=C0(((i.x-n.x)*s.x+(i.y-n.y)*s.y)/c,0,1),e={x:n.x+t*s.x,y:n.y+t*s.y};return{x:(e.x+i.x)/2,y:(e.y+i.y)/2}}const d=n.x-i.x,h=n.y-i.y,u=s.x*s.x+s.y*s.y,p=s.x*a.x+s.y*a.y,m=s.x*d+s.y*h,g=a.x*a.x+a.y*a.y,f=a.x*d+a.y*h,y=u*g-p*p;if(y\u003c1e-10)return I0(n,o,i,r,s,a,c,l);let _=(p*f-g*m)/y,b=(u*f-p*m)/y;_=C0(_,0,1),b=C0(b,0,1),b=(_*p+f)/g,b=C0(b,0,1),_=(b*p-m)/u,_=C0(_,0,1);const x=n.x+_*s.x,v=n.y+_*s.y,S=i.x+b*a.x,I=i.y+b*a.y,C=x-S,P=v-I;Math.sqrt(C*C+P*P);return{x:(x+S)/2,y:(v+I)/2}},I0=(t,e,n,o,i,r,s,a)=\u003e{let c=((n.x-t.x)*i.x+(n.y-t.y)*i.y)/s;c=C0(c,0,1);const l={x:t.x+c*i.x,y:t.y+c*i.y};let d=((o.x-t.x)*i.x+(o.y-t.y)*i.y)/s;d=C0(d,0,1);const h={x:t.x+d*i.x,y:t.y+d*i.y};let u=((t.x-n.x)*r.x+(t.y-n.y)*r.y)/a;u=C0(u,0,1);const p={x:n.x+u*r.x,y:n.y+u*r.y};let m=((e.x-n.x)*r.x+(e.y-n.y)*r.y)/a;m=C0(m,0,1);const g={x:n.x+m*r.x,y:n.y+m*r.y},f=[{pointA:l,pointB:n,distance:Math.sqrt((l.x-n.x)**2+(l.y-n.y)**2)},{pointA:h,pointB:o,distance:Math.sqrt((h.x-o.x)**2+(h.y-o.y)**2)},{pointA:t,pointB:p,distance:Math.sqrt((t.x-p.x)**2+(t.y-p.y)**2)},{pointA:e,pointB:g,distance:Math.sqrt((e.x-g.x)**2+(e.y-g.y)**2)}].reduce((t,e)=\u003ee.distance\u003ct.distance?e:t);return{x:(f.pointA.x+f.pointB.x)/2,y:(f.pointA.y+f.pointB.y)/2}},C0=(t,e,n)=\u003eMath.max(e,Math.min(n,t)),P0=t=\u003e{if(\"pcb_trace_segment\"===t.type)return{minX:Math.min(t.x1,t.x2),minY:Math.min(t.y1,t.y2),maxX:Math.max(t.x1,t.x2),maxY:Math.max(t.y1,t.y2)};if(\"pcb_smtpad\"===t.type||\"pcb_plated_hole\"===t.type){if(\"pcb_smtpad\"===t.type\u0026\u0026(\"rotated_rect\"===t.shape||\"polygon\"===t.shape)||\"pcb_plated_hole\"===t.type\u0026\u0026\"rect_pad_width\"in t\u0026\u0026\"rect_pad_height\"in t){const e=UQ(t);return{minX:Math.min(...e.map(t=\u003et.x)),minY:Math.min(...e.map(t=\u003et.y)),maxX:Math.max(...e.map(t=\u003et.x)),maxY:Math.max(...e.map(t=\u003et.y))}}if(\"pcb_smtpad\"===t.type\u0026\u0026\"rotated_pill\"===t.shape){const e=GQ(t);return{minX:Math.min(e.start.x,e.end.x)-e.radius,minY:Math.min(e.start.y,e.end.y)-e.radius,maxX:Math.max(e.start.x,e.end.x)+e.radius,maxY:Math.max(e.start.y,e.end.y)+e.radius}}}return EM([t])};function M0(t){return\"wire\"!==t.route_type?[]:[t.start_pcb_port_id,t.end_pcb_port_id].filter(t=\u003eBoolean(t))}function N0(t){const e=new Set;for(const n of t.route)for(const t of M0(n))e.add(t);return Array.from(e)}function w0(t){const e=new Set;for(const n of t)for(const t of N0(n))e.add(t);return Array.from(e)}var T0=t=\u003e{if(\"pcb_via\"===t.type)return t.outer_diameter/2;if(\"pcb_plated_hole\"===t.type\u0026\u0026\"circle\"===t.shape)return t.outer_diameter/2;if(\"pcb_hole\"===t.type\u0026\u0026\"circle\"===t.hole_shape)return t.hole_diameter/2;if(\"pcb_smtpad\"===t.type\u0026\u0026\"circle\"===t.shape)return t.radius;throw new Error(`Could not determine radius of element: ${JSON.stringify(t)}`)},R0=t=\u003e\"pcb_port\"===t.type?t.pcb_port_id:\"pcb_smtpad\"===t.type?t.pcb_smtpad_id:t.pcb_plated_hole_id;function E0(t,{connMap:e,minClearance:n}={}){const o=[];(t=\u003e{const e=t.filter(t=\u003e\"pcb_port\"===t.type),n=t.filter(t=\u003e\"pcb_smtpad\"===t.type),o=t.filter(t=\u003e\"pcb_trace\"===t.type);function i(t,o={}){const i=o.traceWidth||0,r=e.find(e=\u003eo0(e.x,e.y,t.x,t.y)\u003c.01);if(r)return r.pcb_port_id;if(o.isFirstOrLastPoint){const e=n.find(e=\u003e\"rect\"===e.shape?Math.abs(t.x-e.x)\u003ce.width/2+i/2\u0026\u0026Math.abs(t.y-e.y)\u003ce.height/2+i/2:\"circle\"===e.shape?o0(t.x,t.y,e.x,e.y)\u003ce.radius:\"pill\"===e.shape||\"rotated_pill\"===e.shape?n0(t,e):void 0);if(e)return e.pcb_port_id??null}return null}for(const t of o)for(let e=0;e\u003ct.route.length;e++){const n=t.route[e],o=0===e||e===t.route.length-1;if(\"wire\"===n.route_type){if(!n.start_pcb_port_id\u0026\u00260===e){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.start_pcb_port_id=t)}if(!n.end_pcb_port_id\u0026\u0026e===t.route.length-1){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.end_pcb_port_id=t)}}}})(t),e??=ei(t);const i=l0(t);n??=d0(i,\"min_trace_to_pad_edge_clearance\")??.1;const r=vM(t).pcb_trace.list().flatMap(t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];\"wire\"===o.route_type\u0026\u0026(\"wire\"===i.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({type:\"pcb_trace_segment\",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:\"width\"in o?o.width:\"width\"in i?i.width:a0,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),s=vM(t).pcb_smtpad.list(),a=vM(t).pcb_plated_hole.list(),c=vM(t).pcb_port.list(),l=vM(t).pcb_hole.list(),d=vM(t).pcb_via.list(),h=vM(t).pcb_keepout.list(),u=[...c,...s,...a],p=new Map;for(const t of h){const e=new Set(t.excluded_pcb_component_ids??[]);0!==e.size\u0026\u0026p.set(t.pcb_keepout_id,u.filter(t=\u003et.pcb_component_id\u0026\u0026e.has(t.pcb_component_id)).map(R0))}const m=[...r,...s,...a,...l,...d,...h],g=new b0({objects:m,getBounds:P0}),f=e=\u003eNM(t,e),y=(t,e,n)=\u003e_0(n)?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,_=new Set;for(const t of r){const i=n,r=P0(t),s=g.getObjectsInBounds(r,i+t.thickness/2);if(t.x1!==t.x2||t.y1!==t.y2)for(const r of s){if(!x0(r).includes(t.layer))continue;if(\"pcb_keepout\"===r.type\u0026\u0026(p.get(r.pcb_keepout_id)??[]).some(n=\u003ee.areIdsConnected(t.pcb_trace_id,n)))continue;if(\"pcb_trace_segment\"===r.type){const i=r;if(t.layer!==i.layer)continue;if(e.areIdsConnected(t.pcb_trace_id,i.pcb_trace_id))continue;const s=Oe({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:i.x1,y:i.y1},{x:i.x2,y:i.y2})-t.thickness/2-i.thickness/2;if(s\u003en-c0)continue;const a=`overlap_${t.pcb_trace_id}_${i.pcb_trace_id}`,c=`overlap_${i.pcb_trace_id}_${t.pcb_trace_id}`;if(_.has(a))continue;if(_.has(c))continue;_.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),f(i.pcb_trace_id),s),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[],center:S0(t,i),pcb_port_ids:w0([t._pcbTrace,i._pcbTrace])});continue}const s=AM(r);if(e.areIdsConnected(t.pcb_trace_id,\"pcb_trace_id\"in r?r.pcb_trace_id:s))continue;if(\"pcb_smtpad\"===r.type||\"pcb_plated_hole\"===r.type||\"pcb_via\"===r.type){const{gap:e,center:n}=y0(t,r);if(!_0(e))continue;const i=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(i))continue;_.add(i),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),`${r.type} \"${f(s)}\"`,e),pcb_trace_id:t.pcb_trace_id,center:n,source_trace_id:\"\",pcb_trace_error_id:i,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...w0([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)});continue}if(\"pcb_hole\"===r.type){const e=T0(r),i=De({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:r.x,y:r.y,radius:e})-t.thickness/2;if(i\u003en-c0)continue;const a=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(a))continue;_.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),`${r.type} \"${f(AM(r))}\"`,i),pcb_trace_id:t.pcb_trace_id,center:v0(t,P0(r)),source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...w0([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}const a=ke({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},P0(r))-t.thickness/2;if(a+c0\u003ci){const e=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(e))continue;_.add(e),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),`${r.type} \"${f(AM(r))}\"`,a),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:e,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),center:v0(t,P0(r)),pcb_port_ids:[...w0([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}}}return o}function A0(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function O0(t,e){return A0(t,e)\u003c=c0}function k0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];const i=l0(t);n??=d0(i,\"min_via_hole_edge_to_via_hole_edge_clearance\")??i0,e??=ei(t);const r=[],s=new Set;for(let i=0;i\u003co.length;i++)for(let a=i+1;a\u003co.length;a++){const c=o[i],l=o[a];if(O0(c,l))continue;if(!e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=A0(c,l)-c.hole_diameter/2-l.hole_diameter/2;if(d+c0\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");s.has(h)||(s.add(h),r.push({type:\"pcb_via_clearance_error\",pcb_error_id:`same_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return r}function L0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];const i=l0(t);n??=d0(i,\"min_via_hole_edge_to_via_hole_edge_clearance\")??i0,e??=ei(t);const r=[],s=new Set;for(let i=0;i\u003co.length;i++)for(let a=i+1;a\u003co.length;a++){const c=o[i],l=o[a];if(O0(c,l))continue;if(e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=A0(c,l)-c.hole_diameter/2-l.hole_diameter/2;if(d+c0\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");s.has(h)||(s.add(h),r.push({type:\"pcb_via_clearance_error\",pcb_error_id:`different_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} from different nets are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return r}function D0(t){return\"through_pad\"===t.route_type?{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2}:{x:t.x,y:t.y}}function z0(t,e,n,o){return\"wire\"===t.route_type\u0026\u0026e.some(e=\u003e{if(!e.pcb_port_id||e.pcb_port_id===n)return!1;const i=o.get(e.pcb_port_id);return i?.some(e=\u003en0({x:t.x,y:t.y},e))??!1})}function F0({firstPoint:t,lastPoint:e,port:n,expectedPorts:o,padMap:i}){let r;const s=\"wire\"===t.route_type?t:void 0,a=\"wire\"===e.route_type?e:void 0,c=M0(t).includes(n.pcb_port_id),l=M0(e).includes(n.pcb_port_id);c\u0026\u0026s?r=s:l\u0026\u0026a||z0(t,o,n.pcb_port_id,i)\u0026\u0026a?r=a:z0(e,o,n.pcb_port_id,i)\u0026\u0026s?r=s:s\u0026\u0026a?r=A0(s,n)\u003c=A0(a,n)?s:a:s?r=s:a\u0026\u0026(r=a);const d=D0(t),h=D0(e);return r?{x:r.x,y:r.y}:{x:(d.x+h.x)/2,y:(d.y+h.y)/2}}function B0(t){const e=[],n=t.filter(t=\u003e\"pcb_port\"===t.type),o=t.filter(t=\u003e\"pcb_trace\"===t.type),i=t.filter(t=\u003e\"source_trace\"===t.type),r=t.filter(t=\u003e\"pcb_smtpad\"===t.type),s=t.filter(t=\u003e\"pcb_plated_hole\"===t.type),a=new Map,c=new ni(t),l=new Set;for(const t of r)t.pcb_port_id\u0026\u0026a.set(t.pcb_port_id,[...a.get(t.pcb_port_id)??[],t]);for(const t of s)t.pcb_port_id\u0026\u0026a.set(t.pcb_port_id,[...a.get(t.pcb_port_id)??[],t]);for(const r of o){if(0===r.route.length)continue;const s=r.route[0],d=r.route[r.route.length-1],h=i.find(t=\u003et.source_trace_id===r.source_trace_id),u=h?n.filter(t=\u003eh.connected_source_port_ids?.includes(t.source_port_id)):[];for(let n=1;n\u003cr.route.length-1;n++){const o=r.route[n-1],i=r.route[n],s=r.route[n+1];if(\"via\"===i.route_type){const a=\"wire\"===o.route_type,c=\"wire\"===s.route_type;if(a\u0026\u0026c){const a=Math.abs(o.x-i.x)\u003c.01\u0026\u0026Math.abs(o.y-i.y)\u003c.01,c=Math.abs(s.x-i.x)\u003c.01\u0026\u0026Math.abs(s.y-i.y)\u003c.01;if(!a||!c){const o=PM(t,r.pcb_trace_id);e.push({type:\"pcb_trace_error\",message:`Via in trace [${o}] is misaligned at position {x: ${i.x}, y: ${i.y}}.`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`misaligned_via_${r.pcb_trace_id}_${n}`,pcb_component_ids:[],pcb_port_ids:[]})}}}}const p=PM(t,r.pcb_trace_id);if(h\u0026\u0026u.length\u003e0){if(l.has(h.source_trace_id))continue;l.add(h.source_trace_id)}for(const n of u){if(!n.pcb_port_id)continue;const l=a.get(n.pcb_port_id);if(!l?.length)continue;let m=!1;const g=[...c.getAllTracesConnectedToTrace(r.pcb_trace_id),...o.filter(t=\u003et.source_trace_id===h?.source_trace_id)];for(const t of g){if(t.pcb_trace_id===r.pcb_trace_id)continue;if(!t.source_trace_id)continue;const e=i.find(e=\u003ee.source_trace_id===t.source_trace_id);if(!h||t.source_trace_id!==h.source_trace_id\u0026\u0026!e?.connected_source_port_ids.includes(n.source_port_id))continue;const o=t.route[0],s=t.route.at(-1);if(N0(t).includes(n.pcb_port_id)||\"wire\"===o?.route_type\u0026\u0026l.some(t=\u003en0(o,t))||\"wire\"===s?.route_type\u0026\u0026l.some(t=\u003en0(s,t))){m=!0;break}}if(m)continue;const f=\"wire\"===s.route_type\u0026\u0026l.some(t=\u003en0({x:s.x,y:s.y},t)),y=\"wire\"===d.route_type\u0026\u0026l.some(t=\u003en0({x:d.x,y:d.y},t));if(!f\u0026\u0026!y){const o=MM(t,n.pcb_port_id).replace(\"pcb_port\",\"\"),i=l[0].type.replace(/pcb_/,\"\"),c=F0({firstPoint:s,lastPoint:d,port:n,expectedPorts:u,padMap:a});e.push({type:\"pcb_trace_error\",message:`Trace [${p}] is missing a connection to ${i}${o}`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`missing_connection_${r.pcb_trace_id}_${n.pcb_port_id}`,center:c,pcb_component_ids:[],pcb_port_ids:[n.pcb_port_id]})}}if(0===u.length){let t=!1,n=!1;const o=\"wire\"===s.route_type\u0026\u0026\"wire\"===d.route_type\u0026\u0026Math.abs(s.x-d.x)\u003c.01\u0026\u0026Math.abs(s.y-d.y)\u003c.01;for(const e of a.values())\"wire\"===s.route_type\u0026\u0026e.some(t=\u003en0({x:s.x,y:s.y},t))\u0026\u0026(t=!0),\"wire\"===d.route_type\u0026\u0026e.some(t=\u003en0({x:d.x,y:d.y},t))\u0026\u0026(n=!0);t||\"wire\"!==s.route_type||e.push({type:\"pcb_trace_error\",message:`Trace [${p}] has disconnected endpoint at (${s.x.toFixed(2)}, ${s.y.toFixed(2)})`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`disconnected_endpoint_${r.pcb_trace_id}_start`,center:{x:s.x,y:s.y},pcb_component_ids:[],pcb_port_ids:[]}),n||\"wire\"!==d.route_type||o\u0026\u0026!t||e.push({type:\"pcb_trace_error\",message:`Trace [${p}] has disconnected endpoint at (${d.x.toFixed(2)}, ${d.y.toFixed(2)})`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`disconnected_endpoint_${r.pcb_trace_id}_end`,center:{x:d.x,y:d.y},pcb_component_ids:[],pcb_port_ids:[]})}}return e}function j0(t,e={}){const n=[],o=l0(t);if(!o)return n;const i=e.margin??d0(o,\"min_board_edge_clearance\")??s0,r=function(t){if(t.outline\u0026\u0026t.outline.length\u003e0)return t.outline.map(t=\u003e({x:t.x,y:t.y}));if(t.center\u0026\u0026\"number\"==typeof t.width\u0026\u0026\"number\"==typeof t.height){const e=t.center.x,n=t.center.y,o=t.width/2,i=t.height/2;return[{x:e-o,y:n-i},{x:e+o,y:n-i},{x:e+o,y:n+i},{x:e-o,y:n+i}]}return null}(o);if(!r)return n;const s=vM(t).pcb_trace.list();for(const t of s)if(!(t.route.length\u003c2))for(let e=0;e\u003ct.route.length-1;e++){const o=t.route[e],s=t.route[e+1];if(\"wire\"!==o.route_type||\"wire\"!==s.route_type)continue;const a=\"width\"in o?o.width:\"width\"in s?s.width:.1,c={x:o.x,y:o.y},l={x:s.x,y:s.y};let d=Number.POSITIVE_INFINITY;for(let t=0;t\u003cr.length;t++){const e=Oe(c,l,r[t],r[(t+1)%r.length]);e\u003cd\u0026\u0026(d=e)}const h=a/2+i;if(d\u003ch){const o={type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",pcb_trace_error_id:`trace_too_close_to_board_${t.pcb_trace_id}_segment_${e}`,message:`Trace too close to board edge (${d.toFixed(3)}mm \u003c ${h.toFixed(3)}mm required, margin: ${i}mm)`,pcb_trace_id:t.pcb_trace_id,source_trace_id:t.source_trace_id||\"\",center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2},pcb_component_ids:[],pcb_port_ids:[]};n.push(o)}}return n}function $0(t,{connMap:e,minClearance:n}={}){const o=(t=\u003e[...vM(t).pcb_smtpad.list(),...vM(t).pcb_plated_hole.list()])(t),i=m0(t);if(0===o.length||0===i.length)return[];const r=l0(t);n??=d0(r,\"min_trace_to_pad_edge_clearance\")??r0,e??=ei(t);const s=new b0({objects:o,getBounds:h0,getId:t=\u003eAM(t)}),a=new Map,c=new Set;for(const o of i){const i=s.getObjectsInBounds(P0(o),n+o.thickness/2);for(const r of i){const i=AM(r);if(!x0(r).includes(o.layer))continue;if(e.areIdsConnected(o.pcb_trace_id,i))continue;const s=`${i}_${o.pcb_trace_id}`,{gap:l}=y0(o,r);if(_0(l)){a.delete(s),c.add(s);continue}if(c.has(s))continue;if(l+c0\u003e=n)continue;const d={type:\"pcb_pad_trace_clearance_error\",pcb_pad_trace_clearance_error_id:`pad_trace_clearance_${s}`,error_type:\"pcb_pad_trace_clearance_error\",message:`Pad ${NM(t,i)} and trace ${NM(t,o.pcb_trace_id)} are too close (clearance: ${I_(l)}, minimum: ${I_(n)})`,pcb_pad_id:i,pcb_trace_id:o.pcb_trace_id,minimum_clearance:n,actual_clearance:l,center:g0(o)},h=a.get(s);(!h||l\u003ch.gap)\u0026\u0026a.set(s,{error:d,gap:l})}}return Array.from(a.values()).map(({error:t})=\u003et)}function Y0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type),i=m0(t);if(0===o.length||0===i.length)return[];const r=l0(t);n??=d0(r,\"min_trace_to_pad_edge_clearance\")??r0,e??=ei(t);const s=new Map,a=new Set;for(const r of o)for(const o of i){if(!x0(r).includes(o.layer))continue;if(e.areIdsConnected(o.pcb_trace_id,r.pcb_via_id))continue;const i=`${r.pcb_via_id}_${o.pcb_trace_id}`,{gap:c}=y0(o,r);if(_0(c)){s.delete(i),a.add(i);continue}if(a.has(i))continue;if(c+c0\u003e=n)continue;const l={type:\"pcb_via_trace_clearance_error\",pcb_via_trace_clearance_error_id:`via_trace_clearance_${i}`,error_type:\"pcb_via_trace_clearance_error\",message:`Via ${NM(t,r.pcb_via_id)} and trace ${NM(t,o.pcb_trace_id)} are too close (clearance: ${I_(c)}, minimum: ${I_(n)})`,pcb_via_id:r.pcb_via_id,pcb_trace_id:o.pcb_trace_id,minimum_clearance:n,actual_clearance:c,center:g0(o)},d=s.get(i);(!d||c\u003cd.gap)\u0026\u0026s.set(i,{error:l,gap:c})}return Array.from(s.values()).map(({error:t})=\u003et)}var X0=(t,e={})=\u003e{const n=(t=\u003e{const e=ei(t),n=t.filter(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_trace_id).map(t=\u003e[t.pcb_via_id,t.pcb_trace_id]);return e.addConnections(n),e})(t),o=Math.max(e.viaClearance??.1,.1),i=E0(t,{connMap:n,minClearance:e.traceClearance}),r=!1!==e.includeTypedTraceClearance,s=r?Y0(t,{connMap:n,minClearance:e.traceClearance}):[],a=r?$0(t,{connMap:n,minClearance:e.traceClearance}):[],c=[...k0(t,{connMap:n,minClearance:o}),...L0(t,{connMap:n,minClearance:o})],l=[...i,...j0(t),...!1===e.includeTraceContinuity?[]:B0(t),...s,...a,...c],d=t.filter(t=\u003e\"pcb_via\"===t.type),h=new Map(d.map(t=\u003e[t.pcb_via_id,t])),u=l.map(t=\u003e{if(\"pcb_via_trace_clearance_error\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id){const e=h.get(t.pcb_via_id);if(e)return{...t,center:{x:e.x,y:e.y}}}if(\"center\"in t\u0026\u0026t.center)return t;if(\"pcb_center\"in t\u0026\u0026t.pcb_center)return{...t,center:t.pcb_center};if(\"pcb_via_ids\"in t\u0026\u0026Array.isArray(t.pcb_via_ids)){const[e,n]=t.pcb_via_ids,o=h.get(e),i=h.get(n);if(o\u0026\u0026i)return{...t,center:{x:(o.x+i.x)/2,y:(o.y+i.y)/2}}}if(\"pcb_error_id\"in t\u0026\u0026\"string\"==typeof t.pcb_error_id\u0026\u0026(t.pcb_error_id.startsWith(\"same_net_vias_close_\")||t.pcb_error_id.startsWith(\"different_net_vias_close_\"))){const e=t.pcb_error_id.replace(\"same_net_vias_close_\",\"\").replace(\"different_net_vias_close_\",\"\").split(\"_\").filter(Boolean);if(2===e.length){const n=h.get(e[0]),o=h.get(e[1]);if(n\u0026\u0026o)return{...t,center:{x:(n.x+o.x)/2,y:(n.y+o.y)/2}}}}return t}),p=u.filter(t=\u003eBoolean(t.center));return{errors:l,errorsWithCenters:u,locationAwareErrors:p}},V0={traceClearance:.1,viaClearance:.1};var W0=t=\u003et.circuitJsonMetadata??{},H0=({connections:t,obstacles:e})=\u003enew Set([...t.flatMap(t=\u003et.pointsToConnect.flatMap(t=\u003et.pcb_port_id?[t.pcb_port_id]:[])),...e.flatMap(t=\u003e{const e=W0(t).pcb_port_id;return e?[e]:[]})]),G0=t=\u003et.__netConnectionName??t.__rootConnectionNames?.[0]??t.name,U0=t=\u003eArray.from(new Set([t.name,t.__netConnectionName,...t.__rootConnectionNames??[],...t.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])])).filter(t=\u003eBoolean(t)),Z0=(t,e)=\u003e{const n=new Map,o=new Set,i=new Map;for(const r of t){const t=G0(r);for(const e of U0(r)){const i=n.get(e);i\u0026\u0026i!==t?(n.delete(e),o.add(e)):o.has(e)||n.set(e,t)}const s=e.getNetConnectedToId(r.name);if(!s)continue;const a=s,c=i.get(a)??new Set;c.add(t),i.set(a,c)}return{connMap:e,circuitJsonSourceTraceIdBySrjDeclaredConnectionReference:n,circuitJsonSourceTraceIdsByConnectivityNetId:i}},q0=(t,e)=\u003e{const n=t.circuitJsonSourceTraceIdBySrjDeclaredConnectionReference.get(e);if(n)return n;const o=t.connMap.getNetConnectedToId(e);if(!o)return;const i=t.circuitJsonSourceTraceIdsByConnectivityNetId.get(o);return 1===i?.size?i.values().next().value:void 0};function J0(t,e,n=t){const o=[],i=n===t?t.connections:[...t.connections,...n.connections],r=n===t?t.obstacles:n.obstacles,s=Z0(i,ii(n===t?t:{...n,connections:i})),a=H0({connections:i,obstacles:r});if(i.forEach(t=\u003e{const n=t.pointsToConnect.map(t=\u003et.pcb_port_id).filter(t=\u003eBoolean(t)),i=new Set(n),a=t=\u003e(t=\u003eArray.from(new Set(t.flatMap(t=\u003et.connectedTo))))(t).filter(t=\u003e!i.has(t)),c=t.pointsToConnect.map(t=\u003et.pointId).filter(t=\u003eBoolean(t)),l=q0(s,t.name)??G0(t),d=[],h=e.find(e=\u003e(e.connection_name??e.connectionName)===t.name);if(h){const t=t=\u003e\"route_type\"in t\u0026\u0026\"jumper\"===t.route_type?t.start:\"x\"in t\u0026\u0026\"y\"in t?{x:t.x,y:t.y}:{x:0,y:0},e=[t(h.route[0]),t(h.route[h.route.length-1])];for(const t of e)for(const e of r)Be(t,e)\u003c=0\u0026\u0026d.push(e)}const u=o.find(t=\u003e\"source_trace\"===t.type\u0026\u0026t.source_trace_id===l);if(u){const t=u;t.connected_source_port_ids=[...new Set([...t.connected_source_port_ids,...n])],t.connected_source_net_ids=[...new Set([...t.connected_source_net_ids??[],...c,...a(d)])]}else o.push({type:\"source_trace\",source_trace_id:l,connected_source_port_ids:n,connected_source_net_ids:a(d).concat(c)})}),e[0]\u0026\u0026\"type\"in e[0]){const t=new Map(i.map(t=\u003e[t.name,t]));for(const n of e){const e=[...new Set((n.connectsTo??[]).filter(t=\u003ea.has(t)))],i=new Set(e),r=[...new Set((n.connectsTo??[]).filter(t=\u003e!i.has(t)))];if(0===e.length\u0026\u00260===r.length)continue;const c=t.get(n.connection_name),l=q0(s,n.connection_name)??n.connectsTo?.map(t=\u003eq0(s,t)).find(t=\u003evoid 0!==t)??(c?G0(c):n.connection_name),d=o.find(t=\u003e\"source_trace\"===t.type\u0026\u0026t.source_trace_id===l);\"source_trace\"!==d?.type?o.push({type:\"source_trace\",source_trace_id:l,connected_source_port_ids:e,connected_source_net_ids:r}):(d.connected_source_port_ids=[...new Set([...d.connected_source_port_ids,...e])],d.connected_source_net_ids=[...new Set([...d.connected_source_net_ids??[],...r])])}}return o}function K0(t,e,n){let o,i=Number.POSITIVE_INFINITY;for(const r of e){const e=n.get(r);if(!e)continue;const s=Math.hypot(e.x-t.x,e.y-t.y);s\u003ci\u0026\u0026(i=s,o=r)}return o??e[0]}var Q0=new Set([\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\",\"inner7\",\"inner8\"]),t1=t=\u003eQ0.has(t);function e1(t){const e=[],n=new Set,o=new Set,i=function(t){const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{x:t.x,y:t.y});return e}(t),r=H0(t);for(const s of t.obstacles){const t=s.connectedTo,a=W0(s);if(a.pcb_via_id)continue;const c=a.pcb_smtpad_id,l=a.pcb_plated_hole_id,d=[...new Set([...a.pcb_port_id?[a.pcb_port_id]:[],...t.filter(t=\u003er.has(t))])],h=K0(s.center,d,i);if(!c\u0026\u0026!l\u0026\u0026!h)continue;const u=s.layers.filter(t1);if(0===u.length)continue;const p=s.width,m=s.height,g=s.center.x,f=s.center.y,y=s.ccwRotationDegrees;if(Boolean(l)||u.length\u003e1){const t=l??`pcb_plated_hole_${g.toFixed(3)}_${f.toFixed(3)}`;if(o.has(t))continue;if(o.add(t),\"number\"==typeof y\u0026\u0026Number.isFinite(y)){const n=Math.max(.5*Math.min(p,m),.1);e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"rotated_pill_hole_with_rect_pad\",hole_shape:\"rotated_pill\",pad_shape:\"rect\",hole_width:n,hole_height:n,hole_ccw_rotation:y,rect_pad_width:p,rect_pad_height:m,rect_ccw_rotation:y,hole_offset_x:0,hole_offset_y:0,x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}if(Math.abs(p-m)\u003c.001){e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circle\",outer_diameter:Math.max(p,m),hole_diameter:Math.max(.5*Math.min(p,m),.1),x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circular_hole_with_rect_pad\",hole_shape:\"circle\",hole_diameter:Math.max(.5*Math.min(p,m),.1),rect_pad_width:p,rect_pad_height:m,hole_offset_x:0,hole_offset_y:0,x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}const _=c??`pcb_smtpad_${g.toFixed(3)}_${f.toFixed(3)}`;n.has(_)||(n.add(_),\"number\"==typeof y\u0026\u0026Number.isFinite(y)?e.push({type:\"pcb_smtpad\",pcb_smtpad_id:_,layer:u[0],shape:\"rotated_rect\",x:g,y:f,width:p,height:m,ccw_rotation:y,...h?{pcb_port_id:h}:{}}):e.push({type:\"pcb_smtpad\",pcb_smtpad_id:_,layer:u[0],shape:\"rect\",width:p,height:m,x:g,y:f,...h?{pcb_port_id:h}:{}}))}return e}function n1(t,e,n={}){const{minTraceWidth:o=.1,minViaDiameter:i,minViaHoleDiameter:r,originalSrj:s,includeOriginalConnections:a=!1}=n,c=Yo(t),l=i??c.padDiameter,d=t.min_via_hole_diameter??t.minViaHoleDiameter,h=r??d??(void 0!==i?.5*l:c.holeDiameter),u=[];u.push(...J0(t,e,a\u0026\u0026s?s:t)),u.push(...function(t){const e=new Map;return t.connections.forEach(t=\u003e{t.pointsToConnect.forEach(t=\u003e{t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{type:\"pcb_port\",pcb_port_id:t.pcb_port_id,source_port_id:t.pcb_port_id,x:t.x,y:t.y,layers:xo(t)})})}),Array.from(e.values())}(a\u0026\u0026s?s:t)),u.push(...e1(s??t)),u.push(...function(t,e,n=.3,o=.5*n){const i=[],r=new Set;return t.length\u003e0\u0026\u0026(\"type\"in t[0]\u0026\u0026\"pcb_trace\"===t[0].type?t.forEach(t=\u003e{t.route.forEach(s=\u003e{if(\"via\"===s.route_type){if(!t1(s.from_layer)||!t1(s.to_layer))return;const a=s.via_diameter??n,c=s.via_hole_diameter??o,l=`${s.x},${s.y},${s.from_layer},${s.to_layer}`;r.has(l)||(i.push({type:\"pcb_via\",pcb_via_id:`via_${i.length}`,pcb_trace_id:t.pcb_trace_id,x:s.x,y:s.y,outer_diameter:a,hole_diameter:c,layers:Wy(s,e)}),r.add(l))}})}):t.forEach((t,s)=\u003e{const a=`trace_${s}`,c=t.viaDiameter??n,l=o;for(let n=1;n\u003ct.route.length;n++){const o=t.route[n-1],s=t.route[n];if(o.z!==s.z\u0026\u0026Math.abs(o.x-s.x)\u003c.01\u0026\u0026Math.abs(o.y-s.y)\u003c.01){const t=vo(o.z,e),n=vo(s.z,e),d=`${s.x},${s.y},${t},${n}`;r.has(d)||(i.push({type:\"pcb_via\",pcb_via_id:`via_${i.length}`,pcb_trace_id:a,x:s.x,y:s.y,outer_diameter:c,hole_diameter:l,layers:Wy({from_layer:t,to_layer:n},e)}),r.add(d))}}})),i}(e,t.layerCount,l,h));const p=Z0(t.connections,ii(t));return e.length\u003e0\u0026\u0026(\"type\"in e[0]\u0026\u0026\"pcb_trace\"===e[0].type?e.forEach(t=\u003e{const e=q0(p,t.connection_name)??t.connectsTo?.map(t=\u003eq0(p,t)).find(t=\u003eBoolean(t))??t.connection_name;u.push(function(t,e){return{type:\"pcb_trace\",pcb_trace_id:t.pcb_trace_id,source_trace_id:e,route:t.route.map(t=\u003e{if(\"wire\"===t.route_type){if(!t1(t.layer))return null;const e=\"start_pcb_port_id\"in t\u0026\u0026\"string\"==typeof t.start_pcb_port_id?t.start_pcb_port_id:void 0,n=\"end_pcb_port_id\"in t\u0026\u0026\"string\"==typeof t.end_pcb_port_id?t.end_pcb_port_id:void 0;return{route_type:\"wire\",x:t.x,y:t.y,width:t.width,layer:t.layer,...e?{start_pcb_port_id:e}:{},...n?{end_pcb_port_id:n}:{}}}return\"via\"===t.route_type\u0026\u0026t1(t.from_layer)\u0026\u0026t1(t.to_layer)?{route_type:\"via\",x:t.x,y:t.y,from_layer:t.from_layer,to_layer:t.to_layer}:null}).filter(t=\u003enull!==t)}}(t,e))}):e.forEach((e,n)=\u003e{const i=function(t,e,n,o,i=.1){const r=[];if(!t.jumpers||0===t.jumpers.length)return[{type:\"pcb_trace\",pcb_trace_id:e,source_trace_id:n,route:t.route.map((e,n)=\u003e{const r=0===n,s=n===t.route.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:e.traceThickness??i,layer:vo(e.z,o),...r\u0026\u0026e.pcb_port_id?{start_pcb_port_id:e.pcb_port_id}:{},...s\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})}];const s=[];for(const e of t.jumpers){let n=-1,o=-1;for(let i=0;i\u003ct.route.length;i++){const r=t.route[i];Math.abs(r.x-e.start.x)\u003c.01\u0026\u0026Math.abs(r.y-e.start.y)\u003c.01\u0026\u0026(n=i),Math.abs(r.x-e.end.x)\u003c.01\u0026\u0026Math.abs(r.y-e.end.y)\u003c.01\u0026\u0026(o=i)}-1!==n\u0026\u0026-1!==o\u0026\u0026(n\u003eo\u0026\u0026([n,o]=[o,n]),s.push({startIdx:n,endIdx:o}))}s.sort((t,e)=\u003et.startIdx-e.startIdx);let a=0,c=0;for(const{startIdx:l,endIdx:d}of s){if(l\u003e=a){const s=t.route.slice(a,l+1);s.length\u003e0\u0026\u0026(r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((t,e)=\u003e{const n=0===e\u0026\u00260===a;return{route_type:\"wire\",x:t.x,y:t.y,width:t.traceThickness??i,layer:vo(t.z,o),...n\u0026\u0026t.pcb_port_id?{start_pcb_port_id:t.pcb_port_id}:{}}})}),c++)}a=d}if(a\u003ct.route.length){const s=t.route.slice(a);if(s.length\u003e0){const t=!0;r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((e,n)=\u003e{const r=t\u0026\u0026n===s.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:e.traceThickness??i,layer:vo(e.z,o),...r\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})})}}return r}(e,`trace_${n}`,q0(p,e.connectionName)??e.connectionName,t.layerCount,o);u.push(...i)})),u}var o1=(t,e)=\u003e{const n=new Set(e.flatMap(t=\u003et.__replaces_pcb_trace_id?[t.__replaces_pcb_trace_id]:[]));return[...t.filter(t=\u003e!n.has(t.pcb_trace_id)),...e]},i1=({inputSrj:t,srjWithPointPairs:e,routedTraces:n,drcOptions:o})=\u003e{const i=t.traces??[],r=n1(e,o1(i,n),{minTraceWidth:t.minTraceWidth,minViaDiameter:t.minViaDiameter,originalSrj:t,includeOriginalConnections:!0});return{circuitJson:r,...X0(r,{...V0,...o})}},r1=(t,e)=\u003e{const n=t({hdRoutes:e,traces:[]});return Array.isArray(n)?n:n.errorsWithCenters??n.errors},s1=t=\u003e{const e=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,n=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],o=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids:[]].filter(t=\u003e\"string\"==typeof t),i=e?`overlap_${e}_`:void 0,r=i\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0;if(n.length\u003e0){const t=e\u0026\u0026!n.includes(e)?[e,...n]:[...n];return t.length\u003c2\u0026\u0026r\u0026\u0026!o.includes(r)\u0026\u0026t.push(r),t}return[e,r].filter(t=\u003e\"string\"==typeof t\u0026\u0026!o.includes(t))},a1=t=\u003es1(t).filter((t,e,n)=\u003en.indexOf(t)===e),c1=t=\u003et.reduce((t,e)=\u003e{if(\"number\"==typeof e.actual_clearance\u0026\u0026\"number\"==typeof e.minimum_clearance)return t+Math.max(0,e.minimum_clearance-e.actual_clearance);const n=(\"string\"==typeof e.message?e.message:\"\").match(/gap: (-?\\d+(?:\\.\\d+)?)mm/);return n?t+Math.max(0,.1-Number.parseFloat(n[1])):t+1},0),l1=(t,e)=\u003et.length\u003ce.length||t.length===e.length\u0026\u0026c1(t)\u003cc1(e)-1e-9,d1=({routes:t,newConnections:e,syntheticConnectionNames:n})=\u003e{const o=new Set([...e.map(t=\u003et.name),...n]),i=new Map,r=new Map;for(let e=0;e\u003ct.length;e++){const n=t[e];if(!o.has(n.connectionName))continue;const s=i.get(n.connectionName)??0;i.set(n.connectionName,s+1),r.set(`${n.connectionName}_${s}`,e)}return r},h1=[.03,.1,.25],u1=t=\u003e{let e=0;for(const n of t){if(\"number\"!=typeof n.actual_clearance||!Number.isFinite(n.actual_clearance)||\"number\"!=typeof n.minimum_clearance||!Number.isFinite(n.minimum_clearance))return;if(e+=Math.max(0,n.minimum_clearance-n.actual_clearance),!Number.isFinite(e))return}return e},p1=({errors:t,errorsWithCenters:e,routeIndexByTraceId:n,padPositionById:o})=\u003e{const i=[];let r=0;for(const s of t){const t=\"pcb_via_trace_clearance_error\"===s.type,a=\"pcb_pad_trace_clearance_error\"===s.type;if(!t\u0026\u0026!a||\"string\"!=typeof s.pcb_trace_id||!n.has(s.pcb_trace_id)||\"number\"!=typeof s.actual_clearance||!Number.isFinite(s.actual_clearance)||\"number\"!=typeof s.minimum_clearance||!Number.isFinite(s.minimum_clearance))return;const c=a1(s);if(t\u0026\u0026c.length\u003c2||c.some(t=\u003e!n.has(t)))return;const l=e.find(t=\u003et.type===s.type\u0026\u0026t.pcb_trace_id===s.pcb_trace_id\u0026\u0026t.pcb_pad_id===s.pcb_pad_id\u0026\u0026t.pcb_via_id===s.pcb_via_id),d=a?\"string\"==typeof s.pcb_pad_id?o.get(s.pcb_pad_id):void 0:l?.center??s.center;if(!d||\"object\"!=typeof d)return;if(!(\"x\"in d\u0026\u0026\"y\"in d\u0026\u0026\"number\"==typeof d.x\u0026\u0026Number.isFinite(d.x)\u0026\u0026\"number\"==typeof d.y\u0026\u0026Number.isFinite(d.y)))return;const h={...s,pcb_trace_id:s.pcb_trace_id,actual_clearance:s.actual_clearance,minimum_clearance:s.minimum_clearance,center:{x:d.x,y:d.y}};if(t){if(\"string\"!=typeof s.pcb_via_id)return;i.push({...h,type:\"pcb_via_trace_clearance_error\",pcb_via_id:s.pcb_via_id,pcb_pad_id:void 0})}else{if(\"string\"!=typeof s.pcb_pad_id)return;i.push({...h,type:\"pcb_pad_trace_clearance_error\",pcb_pad_id:s.pcb_pad_id,pcb_via_id:void 0})}if(r+=Math.max(0,s.minimum_clearance-s.actual_clearance),!Number.isFinite(r))return}return{errors:i,deficit:r}},m1=(t,e)=\u003e{const n=[];for(let o=0;o\u003ct.route.length;o+=1){const i=t.route[o];if(\"via\"!==i.route_type){n.push(structuredClone(i));continue}const r=n[n.length-1],s=t.route[o+1],a=\"wire\"===r?.route_type?r.width:\"wire\"===s?.route_type?s.width:e,c=\"wire\"===s?.route_type?s.width:a;\"wire\"===r?.route_type\u0026\u0026r.x===i.x\u0026\u0026r.y===i.y\u0026\u0026r.layer===i.from_layer||n.push({route_type:\"wire\",x:i.x,y:i.y,layer:i.from_layer,width:a}),n.push(structuredClone(i)),\"wire\"===s?.route_type\u0026\u0026s.x===i.x\u0026\u0026s.y===i.y\u0026\u0026s.layer===i.to_layer||n.push({route_type:\"wire\",x:i.x,y:i.y,layer:i.to_layer,width:c})}return{...structuredClone(t),route:n}};function g1(t){const{srj:e,routes:n,routeIndex:o,start:i,end:r,bounds:s,traceThickness:a}=t;if(void 0!==t.maxNodes\u0026\u0026(!Number.isSafeInteger(t.maxNodes)||t.maxNodes\u003c1))throw new Error(\"repair04: maxNodes must be a positive safe integer\");if(t.stats\u0026\u0026(t.stats.nodesPopped=0,t.stats.completionReason=\"no-path\"),!1===t.allowLayerChanges\u0026\u0026i.z!==r.z)return null;const c=n[o],l=new Map,d=t=\u003e{const e=l.get(t);if(void 0===e||e===t)return t;const n=d(e);return l.set(t,n),n},h=t=\u003e{const e=t.filter(t=\u003eBoolean(t));if(!e.length)return;const n=d(e[0]);for(const t of e)l.set(d(t),n)};for(const t of e.connections){const e=t;h([e.name,e.rootConnectionName,e.netConnectionName,e.__netConnectionName,...e.mergedConnectionNames??[],...e.__rootConnectionNames??[],...e.pointsToConnect.flatMap(t=\u003e[t.pcb_port_id,t.pointId])])}for(const t of e.obstacles)h(t.connectedTo);for(const t of n)h([t.connectionName,t.rootConnectionName]);const u=d(c.connectionName),p=t=\u003e\"top\"===t?0:\"bottom\"===t?e.layerCount-1:Number(t.slice(5)),m=[s.minX,s.maxX,s.minY,s.maxY,i.x,i.y,r.x,r.y,a,c.viaDiameter,t.traceClearance,t.viaClearance,e.defaultObstacleMargin??0,e.minTraceToPadEdgeClearance??0,e.minViaEdgeToPadEdgeClearance??0].every(t=\u003eNumber.isFinite(t)\u0026\u0026Math.abs(t)\u003c=1e4),g=[],f=(t,e,n,o,i=!1)=\u003e{const r=o?Math.hypot(o.width,o.height)/2:n,s=o?Math.cos(o.rotation):1,a=o?Math.sin(o.rotation):0,c={minX:Math.min(t.x,e.x)-r,maxX:Math.max(t.x,e.x)+r,minY:Math.min(t.y,e.y)-r,maxY:Math.max(t.y,e.y)+r},l=o\u0026\u0026m?((t,e,n,o,i,r)=\u003e{if(t.x!==e.x||t.y!==e.y||!Number.isFinite(n.rotation)||n.width\u003c=0||n.height\u003c=0||![t.x,t.y,n.width,n.height,r.minX,r.maxX,r.minY,r.maxY].every(t=\u003eNumber.isFinite(t)\u0026\u0026Math.abs(t)\u003c=1e4))return r;const s=o*o+i*i;if(!Number.isFinite(s)||Math.abs(s-1)\u003e1e-12)return r;const a=n.width/2,c=n.height/2,l=(Math.abs(o)*a+Math.abs(i)*c)/s+1e-8,d=(Math.abs(i)*a+Math.abs(o)*c)/s+1e-8,h={minX:t.x-l,maxX:t.x+l,minY:t.y-d,maxY:t.y+d};return h.minX\u003cr.minX||h.maxX\u003er.maxX||h.minY\u003cr.minY||h.maxY\u003er.maxY?r:h})(t,e,o,s,a,c):c;g.push({a:t,b:e,radius:n,rect:o,viaOnly:i,rectCos:s,rectSin:a,rectBounds:o?{minX:-o.width/2,maxX:o.width/2,minY:-o.height/2,maxY:o.height/2}:void 0,visitedQuery:0,...l,minZ:Math.min(t.z,e.z),maxZ:Math.max(t.z,e.z)})};for(const t of e.obstacles){const e=t.connectedTo.some(t=\u003ed(t)===u),n=t.__zLayers??t.zLayers??t.layers.map(p);for(const o of n)f({...t.center,z:o},{...t.center,z:o},0,{width:t.width,height:t.height,rotation:(t.ccwRotationDegrees??0)*Math.PI/180},e)}for(const t of n)if(d(t.connectionName)!==u)for(let e=1;e\u003ct.route.length;e++){const n=t.route[e-1],o=t.route[e];\"through_obstacle\"!==n.toNextSegmentType\u0026\u0026f(n,o,n.z!==o.z?t.viaDiameter/2:Math.max(n.traceThickness??t.traceThickness,o.traceThickness??t.traceThickness)/2)}for(const t of e.traces??[]){if(d(t.connection_name)===u)continue;const n=m1(t,e.minTraceWidth);for(let t=1;t\u003cn.route.length;t++){const e=n.route[t-1],o=n.route[t];\"wire\"===e.route_type\u0026\u0026\"wire\"===o.route_type\u0026\u0026e.layer===o.layer\u0026\u0026f({x:e.x,y:e.y,z:p(e.layer)},{x:o.x,y:o.y,z:p(o.layer)},Math.max(e.width,o.width)/2),\"via\"===o.route_type\u0026\u0026f({x:o.x,y:o.y,z:p(o.from_layer)},{x:o.x,y:o.y,z:p(o.to_layer)},(o.via_diameter??c.viaDiameter)/2)}}const y=new Map,_=Math.max(c.viaDiameter,a)/2+Math.max(t.traceClearance,t.viaClearance,e.defaultObstacleMargin??0,e.minTraceToPadEdgeClearance??0,e.minViaEdgeToPadEdgeClearance??0)+1e-5;for(const t of g)for(let e=Math.floor(Math.max(t.minX,s.minX-_));e\u003c=Math.floor(Math.min(t.maxX,s.maxX+_));e++){let n=y.get(e);for(let o=Math.floor(Math.max(t.minY,s.minY-_));o\u003c=Math.floor(Math.min(t.maxY,s.maxY+_));o++){n||(n=new Map,y.set(e,n));const i=n.get(o);i?i.push(t):n.set(o,[t])}}let b=0;const x={x:0,y:0},v={x:0,y:0},S=(n,o)=\u003e{const i=n.z!==o.z,r=i?c.viaDiameter/2:a/2,s=Math.max(i?t.viaClearance:t.traceClearance,e.defaultObstacleMargin??0,i?e.minViaEdgeToPadEdgeClearance??0:e.minTraceToPadEdgeClearance??0),l=r+s+1e-5,d=++b,h=Math.min(n.x,o.x),u=Math.max(n.x,o.x),p=Math.min(n.y,o.y),m=Math.max(n.y,o.y),g=Math.min(n.z,o.z),f=Math.max(n.z,o.z);for(let e=Math.floor(h-l);e\u003c=Math.floor(u+l);e++){const a=y.get(e);if(a)for(let e=Math.floor(p-l);e\u003c=Math.floor(m+l);e++){const c=a.get(e);if(c)for(const e of c){if(e.viaOnly\u0026\u0026!i)continue;if(e.visitedQuery===d)continue;if(e.visitedQuery=d,e.maxZ\u003cg||e.minZ\u003ef)continue;const a=r+(e.rect?s:i\u0026\u0026e.minZ!==e.maxZ?t.viaClearance:t.traceClearance)+1e-5;if(u+a\u003ce.minX||h-a\u003ee.maxX||m+a\u003ce.minY||p-a\u003ee.maxY)continue;let c;if(e.rect?(x.x=(n.x-e.a.x)*e.rectCos+(n.y-e.a.y)*e.rectSin,x.y=-(n.x-e.a.x)*e.rectSin+(n.y-e.a.y)*e.rectCos,v.x=(o.x-e.a.x)*e.rectCos+(o.y-e.a.y)*e.rectSin,v.y=-(o.x-e.a.x)*e.rectSin+(o.y-e.a.y)*e.rectCos,c=ke(x,v,e.rectBounds)):c=Oe(n,o,e.a,e.b)-e.radius,c\u003ca)return!1}}}return!0};if(!S(i,i)||!S(r,r))return null;const I=t.gridSize??.1;if(!Number.isFinite(I)||I\u003c=0)throw new Error(\"repair04: clearance grid size must be positive and finite\");const C=Math.floor((s.maxX-s.minX)/I),P=Math.floor((s.maxY-s.minY)/I),M=t=\u003e({x:s.minX+(t%C+.5)*I,y:s.minY+(Math.floor(t/C)%P+.5)*I,z:Math.floor(t/(C*P)),traceThickness:a}),N=(t,e,n)=\u003e(n*P+e)*C+t,w=t=\u003eMath.hypot(t.x-r.x,t.y-r.y)+(t.z===r.z?0:1),T=[],R=t=\u003e{T.push(t);let e=T.length-1;for(;e\u003e0;){const n=Math.floor((e-1)/2);if(T[n].priority\u003c=t.priority)break;T[e]=T[n],e=n}T[e]=t},E=()=\u003e{const t=T[0],e=T.pop();if(T.length){let t=0;for(;2*t+1\u003cT.length;){let n=2*t+1;if(n+1\u003cT.length\u0026\u0026T[n+1].priority\u003cT[n].priority\u0026\u0026n++,T[n].priority\u003e=e.priority)break;T[t]=T[n],t=n}T[t]=e}return t},A=new Map,O=new Map,k=(z=i,N(Math.max(0,Math.min(C-1,Math.floor((z.x-s.minX)/I))),Math.max(0,Math.min(P-1,Math.floor((z.y-s.minY)/I))),z.z)),L=k%C,D=Math.floor(k/C)%P;var z;for(let t=-2;t\u003c=2;t++)for(let e=-2;e\u003c=2;e++){const n=L+t,o=D+e;if(n\u003c0||n\u003e=C||o\u003c0||o\u003e=P)continue;const r=N(n,o,i.z),s=M(r);if(!S(i,s))continue;const a=Math.hypot(s.x-i.x,s.y-i.y);A.set(r,a),O.set(r,-1),R({id:r,cost:a,priority:a+w(s)})}const F=C*P*e.layerCount,B=C\u003e0\u0026\u0026P\u003e0\u0026\u0026Number.isSafeInteger(e.layerCount)\u0026\u0026Number.isSafeInteger(F)\u0026\u0026F\u003e0\u0026\u0026Number.isSafeInteger(F*F-1)\u0026\u0026Number.isInteger(i.z)\u0026\u0026i.z\u003e=0\u0026\u0026i.z\u003ce.layerCount,j=new Map;let $=0;for(;T.length\u0026\u0026$\u003c(t.maxNodes??3e4);){const n=E();if($++,t.stats\u0026\u0026(t.stats.nodesPopped=$),n.cost!==A.get(n.id))continue;const o=M(n.id);if(o.z===r.z\u0026\u0026Math.hypot(o.x-r.x,o.y-r.y)\u003c3*I\u0026\u0026S(o,r)){const e=[r];for(let t=n.id;-1!==t;t=O.get(t))e.push(M(t));e.push(i);const o=e.reverse(),s=[i];for(let t=1;t\u003co.length;){let e=t;if(o[t].z===s.at(-1).z)for(let n=t+1;n\u003co.length\u0026\u0026o[n].z===o[t].z;n++)S(s.at(-1),o[n])\u0026\u0026(e=n);s.push(o[e]),t=e+1}return t.stats\u0026\u0026(t.stats.completionReason=\"found\"),s}const s=n.id%C,a=Math.floor(n.id/C)%P,c=[];for(let t=-1;t\u003c=1;t++)for(let e=-1;e\u003c=1;e++)0===t\u0026\u00260===e||s+t\u003c0||s+t\u003e=C||a+e\u003c0||a+e\u003e=P||c.push(N(s+t,a+e,o.z));if(!1!==t.allowLayerChanges)for(let t=0;t\u003ce.layerCount;t++)t!==o.z\u0026\u0026c.push(N(s,a,t));for(const t of c){const e=M(t),i=n.cost+(o.z===e.z?Math.hypot(o.x-e.x,o.y-e.y):1);if(i\u003e=(A.get(t)??1/0))continue;const r=Math.min(n.id,t),s=Math.max(n.id,t),a=B?r*F+s:`${r},${s}`;let c=j.get(a);void 0===c\u0026\u0026(c=S(o,e),j.set(a,c)),c\u0026\u0026(A.set(t,i),O.set(t,n.id),R({id:t,cost:i,priority:i+w(e)}))}}return t.stats\u0026\u0026(t.stats.completionReason=T.length?\"node-limit\":\"no-path\"),null}var f1=(t,e)=\u003e{if(!Number.isInteger(e)||e\u003c1)throw new Error(`Invalid board layer count: ${e}`);const n=Array.from({length:e},(t,n)=\u003e((t,e)=\u003e0===t?\"top\":t===e-1?\"bottom\":`inner${t}`)(n,e)),o=n.findIndex(e=\u003ee===t.from_layer),i=n.findIndex(e=\u003ee===t.to_layer);if(o\u003c0||i\u003c0)throw new Error(`Via span ${t.from_layer} -\u003e ${t.to_layer} is outside the board`);return n.slice(Math.min(o,i),Math.max(o,i)+1)},y1=.005,_1=1e-6,b1=(t,e)=\u003e({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),x1=t=\u003eb1({minX:Math.min(t.start.x,t.end.x),minY:Math.min(t.start.y,t.end.y),maxX:Math.max(t.start.x,t.end.x),maxY:Math.max(t.start.y,t.end.y)},t.width/2),v1=t=\u003e{const e=t.diameter/2;return{minX:t.x-e,minY:t.y-e,maxX:t.x+e,maxY:t.y+e}},S1=t=\u003e({minX:t.x-t.width/2,minY:t.y-t.height/2,maxX:t.x+t.width/2,maxY:t.y+t.height/2}),I1=(t,e)=\u003e`${t}:${e}`,C1=class{constructor(t){this.cellSize=t}cellSize;cells=new Map;insert(t,e){const n=Math.floor(e.minX/this.cellSize),o=Math.floor(e.maxX/this.cellSize),i=Math.floor(e.minY/this.cellSize),r=Math.floor(e.maxY/this.cellSize);for(let e=n;e\u003c=o;e+=1)for(let n=i;n\u003c=r;n+=1){const o=I1(e,n),i=this.cells.get(o);i?i.push(t):this.cells.set(o,[t])}}insertWithCellKeys(t,e){for(const n of e){const e=this.cells.get(n);e?e.push(t):this.cells.set(n,[t])}}getCellKeys(t){const e=Math.floor(t.minX/this.cellSize),n=Math.floor(t.maxX/this.cellSize),o=Math.floor(t.minY/this.cellSize),i=Math.floor(t.maxY/this.cellSize),r=[];for(let t=e;t\u003c=n;t+=1)for(let e=o;e\u003c=i;e+=1)r.push(I1(t,e));return r}queryWithCellKeys(t){const e=new Set;for(const n of t){const t=this.cells.get(n);if(t)for(const n of t)e.add(n)}return[...e]}queryWithCellKeysUsingOrder(t,e){const n=[];for(const o of t){const t=this.cells.get(o);if(t)for(const o of t)o.lastDynamicQueryOrder!==e\u0026\u0026(o.lastDynamicQueryOrder=e,n.push(o))}return n}query(t){const e=Math.floor(t.minX/this.cellSize),n=Math.floor(t.maxX/this.cellSize),o=Math.floor(t.minY/this.cellSize),i=Math.floor(t.maxY/this.cellSize),r=new Set;for(let t=e;t\u003c=n;t+=1)for(let e=o;e\u003c=i;e+=1){const n=this.cells.get(I1(t,e));if(n)for(const t of n)r.add(t)}return[...r]}},P1=(t,e)=\u003e{const n=ve(t.start,t.end,e.start,e.end);if(n)return n;const o=[{left:t.start,right:ze(t.start,e.start,e.end)},{left:t.end,right:ze(t.end,e.start,e.end)},{left:ze(e.start,t.start,t.end),right:e.start},{left:ze(e.end,t.start,t.end),right:e.end}];let i={left:t.start,right:e.start},r=Number.POSITIVE_INFINITY;for(const t of o){const e=Math.hypot(t.left.x-t.right.x,t.left.y-t.right.y);e\u003cr\u0026\u0026(i=t,r=e)}return{x:(i.left.x+i.right.x)/2,y:(i.left.y+i.right.y)/2}},M1=(t,e)=\u003e{const n=ze(e,t.start,t.end);return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}},N1=(t,e)=\u003e{const n=ze({x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},t.start,t.end),o=Math.max(e.minX,Math.min(e.maxX,n.x)),i=Math.max(e.minY,Math.min(e.maxY,n.y));return{x:(n.x+o)/2,y:(n.y+i)/2}},w1=t=\u003e{const e=new Set;for(const n of t.route)\"wire\"===n.route_type\u0026\u0026(n.start_pcb_port_id\u0026\u0026e.add(n.start_pcb_port_id),n.end_pcb_port_id\u0026\u0026e.add(n.end_pcb_port_id));return[...e]},T1=(t,e,n)=\u003en\u003c0?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,R1=class{constructor(t,e={}){if(this.srj=t,this.cacheImmutableTraceGeometry=e.cacheImmutableTraceGeometry??!1,this.useConservativeRectObstaclePrecheck=e.useConservativeRectObstaclePrecheck??!1,this.useTransientDynamicQueryMarkers=e.useTransientDynamicQueryMarkers??!1,this.traceClearance=e.traceClearance??.1,this.viaClearance=Math.max(e.viaClearance??.1,.1),this.viaToPadClearance=e.viaToPadClearance??this.srj.minViaEdgeToPadEdgeClearance??.1,this.connMap=e.connMap,this.includeTraceViaOwnerMetadata=e.includeTraceViaOwnerMetadata??!1,this.cellSize=e.spatialCellSize??this.getDefaultSpatialCellSize(),!Number.isFinite(this.traceClearance)||this.traceClearance\u003c0)throw new Error(\"traceClearance must be a non-negative finite number\");if(!Number.isFinite(this.viaClearance))throw new Error(\"viaClearance must be a finite number\");if(!Number.isFinite(this.viaToPadClearance)||this.viaToPadClearance\u003c0)throw new Error(\"viaToPadClearance must be a non-negative finite number\");if(!Number.isFinite(this.cellSize)||this.cellSize\u003c=0)throw new Error(\"spatialCellSize must be a positive finite number\");if(e.cacheStaticObstacleNetMembership\u0026\u0026this.connMap)throw new Error(\"cacheStaticObstacleNetMembership cannot be combined with connMap\");if(this.cacheImmutableTraceGeometry\u0026\u0026this.connMap)throw new Error(\"cacheImmutableTraceGeometry cannot be combined with connMap\");if(this.useTransientDynamicQueryMarkers\u0026\u0026!this.cacheImmutableTraceGeometry)throw new Error(\"useTransientDynamicQueryMarkers requires cacheImmutableTraceGeometry\");this.compileConnectionAliases(),this.obstacles=this.compileStaticObstacles(),e.cacheStaticObstacleNetMembership\u0026\u0026(this.staticObstacleNets=new Map(this.obstacles.map(t=\u003e[t,new Set(t.connectedTo.map(t=\u003ethis.resolveNetId(t)))]))),this.indexStaticObstacles()}srj;cacheImmutableTraceGeometry;useConservativeRectObstaclePrecheck;useTransientDynamicQueryMarkers;immutableTraceGeometry=new WeakMap;immutableDynamicCellKeys=new WeakMap;immutableDynamicQueryCellKeys=new WeakMap;immutableStaticCandidates=new WeakMap;immutableStaticClearance=new WeakMap;traceClearance;viaClearance;viaToPadClearance;cellSize;connMap;includeTraceViaOwnerMetadata;canonicalNetByAlias=new Map;connMapNetByCanonicalNet=new Map;obstacles;staticObstacleNets;obstacleIndexesByLayer=new Map;lastRunStats={traceCount:0,segmentCount:0,viaCount:0,obstacleCount:0,broadPhaseCandidateCount:0,exactCheckCount:0};getDefaultSpatialCellSize(){const t=Math.max(0,this.srj.bounds.maxX-this.srj.bounds.minX),e=Math.max(0,this.srj.bounds.maxY-this.srj.bounds.minY);return Math.max(.25,Math.max(t,e)/64,(this.srj.minViaDiameter??.3)+Math.max(this.traceClearance,this.viaToPadClearance))}compileConnectionAliases(){const t=new Map;for(const e of this.srj.connections){const n=e.netConnectionName??e.rootConnectionName??e.name,o=[e.name,e.rootConnectionName,e.netConnectionName,...e.mergedConnectionNames??[],...e.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])];for(const e of o){if(!e)continue;this.canonicalNetByAlias.set(e,n);const o=this.connMap?.getNetConnectedToId(e);if(!o)continue;let i=t.get(n);i||(i=new Set,t.set(n,i)),i.add(o)}this.canonicalNetByAlias.set(n,n)}for(const[e,n]of t)1===n.size\u0026\u0026this.connMapNetByCanonicalNet.set(e,n.values().next().value)}resolveNetId(t){const e=this.connMap?.getNetConnectedToId(t);if(e)return e;const n=this.canonicalNetByAlias.get(t);return n?this.connMapNetByCanonicalNet.get(n)??n:t}areConnected(t,e){return t===e||(!!this.connMap?.areIdsConnected(t,e)||this.resolveNetId(t)===this.resolveNetId(e))}compileStaticObstacles(){const t=[],e=new Set,n=new Set;for(const o of this.srj.obstacles){if(0===o.layers.length)continue;const i=o.connectedTo.find(t=\u003et.startsWith(\"pcb_smtpad_\")),r=o.connectedTo.find(t=\u003et.startsWith(\"pcb_plated_hole_\")),s=o.connectedTo.find(t=\u003et.startsWith(\"pcb_port_\"));if(!i\u0026\u0026!r\u0026\u0026!s)continue;const a=o.layers.length\u003e1,c=a?\"pcb_plated_hole\":\"pcb_smtpad\",l=a?r??`pcb_plated_hole_${o.center.x.toFixed(3)}_${o.center.y.toFixed(3)}`:i??`pcb_smtpad_${o.center.x.toFixed(3)}_${o.center.y.toFixed(3)}`,d=a?n:e;if(d.has(l))continue;d.add(l);const h=a\u0026\u0026Math.abs(o.width-o.height)\u003c.001;t.push({kind:\"obstacle\",obstacleType:c,obstacleId:l,connectedTo:o.connectedTo,x:o.center.x,y:o.center.y,width:o.width,height:o.height,...h?{radius:Math.max(o.width,o.height)/2}:{},layers:o.layers,...s?{pcbPortId:s}:{}})}return t}indexStaticObstacles(){for(const t of this.obstacles){const e=b1(S1(t),Math.max(this.traceClearance,this.viaToPadClearance));for(const n of t.layers){let o=this.obstacleIndexesByLayer.get(n);o||(o=new C1(this.cellSize),this.obstacleIndexesByLayer.set(n,o)),o.insert(t,e)}}}getImmutableTraceGeometry(t){const e=this.immutableTraceGeometry.get(t);if(e)return e;const n=this.resolveNetId(t.connection_name),o=w1(t),i=[];for(let e=0;e\u003ct.route.length-1;e++){const r=t.route[e],s=t.route[e+1];\"wire\"===r?.route_type\u0026\u0026\"wire\"===s?.route_type\u0026\u0026r.layer===s.layer\u0026\u0026(Math.abs(r.x-s.x)\u003c=_1\u0026\u0026Math.abs(r.y-s.y)\u003c=_1||i.push({geometryKey:{},kind:\"trace_segment\",traceId:t.pcb_trace_id,netId:n,start:{x:r.x,y:r.y},end:{x:s.x,y:s.y},width:E1(r,s),layer:r.layer,pcbPortIds:o}))}const r=[];for(const e of t.route)\"via\"===e.route_type\u0026\u0026r.push({locationKey:`${e.x},${e.y},${e.from_layer},${e.to_layer}`,point:e,geometryKey:{}});const s={segments:i,vias:r,traceId:t.pcb_trace_id,netId:n};return this.immutableTraceGeometry.set(t,s),s}collectImmutableDynamicGeometry(t){const e=[],n=[],o=new Set;for(const i of t){const t=this.getImmutableTraceGeometry(i);for(const n of t.segments)e.push({geometryKey:n.geometryKey,kind:\"trace_segment\",traceId:n.traceId,netId:n.netId,start:n.start,end:n.end,width:n.width,layer:n.layer,pcbPortIds:n.pcbPortIds,order:e.length});for(const e of t.vias){if(o.has(e.locationKey))continue;o.add(e.locationKey);const i=e.point,r=e.prepared??={geometryKey:e.geometryKey,kind:\"via\",traceId:t.traceId,netId:t.netId,x:i.x,y:i.y,diameter:i.via_diameter??this.srj.minViaDiameter??.3,layers:f1(i,this.srj.layerCount)};n.push({geometryKey:r.geometryKey,kind:\"via\",traceId:r.traceId,netId:r.netId,x:r.x,y:r.y,diameter:r.diameter,layers:r.layers,order:n.length,viaId:`via_${n.length}`})}}return{segments:e,vias:n}}collectDynamicGeometry(t){if(this.cacheImmutableTraceGeometry)return this.collectImmutableDynamicGeometry(t);const e=[],n=[],o=new Set;for(const i of t){const t=this.resolveNetId(i.connection_name),r=w1(i);for(let n=0;n\u003ci.route.length-1;n+=1){const o=i.route[n],s=i.route[n+1];\"wire\"===o?.route_type\u0026\u0026\"wire\"===s?.route_type\u0026\u0026o.layer===s.layer\u0026\u0026(Math.abs(o.x-s.x)\u003c=_1\u0026\u0026Math.abs(o.y-s.y)\u003c=_1||e.push({kind:\"trace_segment\",order:e.length,traceId:i.pcb_trace_id,netId:t,start:{x:o.x,y:o.y},end:{x:s.x,y:s.y},width:E1(o,s),layer:o.layer,pcbPortIds:r}))}for(const e of i.route){if(\"via\"!==e.route_type)continue;const r=`${e.x},${e.y},${e.from_layer},${e.to_layer}`;o.has(r)||(o.add(r),n.push({kind:\"via\",order:n.length,viaId:`via_${n.length}`,traceId:i.pcb_trace_id,netId:t,x:e.x,y:e.y,diameter:e.via_diameter??this.srj.minViaDiameter??.3,layers:f1(e,this.srj.layerCount)}))}}return{segments:e,vias:n}}getImmutableDynamicCellKeys(t,e){const n=t.geometryKey;if(!n)throw new Error(\"Immutable spatial cache requires private entity identities\");let o=this.immutableDynamicCellKeys.get(n);if(!o){const i=\"trace_segment\"===t.kind?x1(t):v1(t);o=e.getCellKeys(b1(i,this.traceClearance)),this.immutableDynamicCellKeys.set(n,o)}return o}getImmutableDynamicQueryCellKeys(t,e,n){const o=t.geometryKey;if(!o)throw new Error(\"Immutable spatial cache requires private entity identities\");let i=this.immutableDynamicQueryCellKeys.get(o);return i||(i=e.getCellKeys(n),this.immutableDynamicQueryCellKeys.set(o,i)),i}getStaticObstacleCandidates(t,e){const n=t.geometryKey;if(!n)throw new Error(\"Immutable spatial cache requires private entity identities\");let o=this.immutableStaticCandidates.get(n);o||(o=new Map,this.immutableStaticCandidates.set(n,o));let i=o.get(e);if(!i){const n=\"trace_segment\"===t.kind?x1(t):v1(t);i=this.obstacleIndexesByLayer.get(e)?.query(n)??[],o.set(e,i)}return i}buildImmutableDynamicIndexes(t,e){const n=new Map,o=(t,e)=\u003e{let o=n.get(t);o||(o=new C1(this.cellSize),n.set(t,o)),o.insertWithCellKeys(e,this.getImmutableDynamicCellKeys(e,o))};for(const e of t)o(e.layer,e);for(const t of e)for(const e of t.layers)o(e,t);return n}buildDynamicIndexes(t,e){if(this.cacheImmutableTraceGeometry)return this.buildImmutableDynamicIndexes(t,e);const n=new Map,o=(t,e,o)=\u003e{let i=n.get(t);i||(i=new C1(this.cellSize),n.set(t,i)),i.insert(e,b1(o,this.traceClearance))};for(const e of t)o(e.layer,e,x1(e));for(const t of e)for(const e of t.layers)o(e,t,v1(t));return n}obstacleSharesNet(t,e){return this.staticObstacleNets?this.staticObstacleNets.get(e).has(this.resolveNetId(t)):e.connectedTo.some(e=\u003ethis.areConnected(t,e))}checkTracePair(t,e){if(this.areConnected(t.netId,e.netId))return;this.lastRunStats.exactCheckCount+=1;const n=Oe(t.start,t.end,e.start,e.end)-t.width/2-e.width/2;if(n\u003ethis.traceClearance-y1)return;const o=`overlap_${t.traceId}_${e.traceId}`;return{type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:T1(t.traceId,`PCB trace ${e.traceId}`,n),pcb_trace_id:t.traceId,source_trace_id:\"\",pcb_trace_error_id:o,minimum_clearance:this.traceClearance,actual_clearance:n,pcb_component_ids:[],pcb_port_ids:[...new Set([...t.pcbPortIds,...e.pcbPortIds])],center:this.cacheImmutableTraceGeometry?{...P1(t,e)}:P1(t,e)}}checkTraceVia(t,e){if(this.areConnected(t.netId,e.netId))return;this.lastRunStats.exactCheckCount+=1;const n=De(t.start,t.end,{x:e.x,y:e.y,radius:e.diameter/2})-t.width/2;if(n\u003ethis.traceClearance-y1)return;const o=`overlap_${t.traceId}_${e.viaId}`;return{type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:T1(t.traceId,`pcb_via \"${e.viaId}\"`,n),pcb_trace_id:t.traceId,...this.includeTraceViaOwnerMetadata?{pcb_trace_ids:[t.traceId,e.traceId],pcb_via_id:e.viaId,pcb_via_ids:[e.viaId]}:{},source_trace_id:\"\",pcb_trace_error_id:o,minimum_clearance:this.traceClearance,actual_clearance:n,pcb_component_ids:[],pcb_port_ids:this.cacheImmutableTraceGeometry?[...t.pcbPortIds]:t.pcbPortIds,center:M1(t,e)}}checkTraceObstacle(t,e){if(this.obstacleSharesNet(t.netId,e))return;this.lastRunStats.exactCheckCount+=1;const n=S1(e);if(this.useConservativeRectObstaclePrecheck\u0026\u0026void 0===e.radius\u0026\u0026((t,e,n)=\u003e{const o=t.width/2+n-y1;return Math.max(e.minX-Math.max(t.start.x,t.end.x),Math.min(t.start.x,t.end.x)-e.maxX,e.minY-Math.max(t.start.y,t.end.y),Math.min(t.start.y,t.end.y)-e.maxY)\u003eo+1e-9\u0026\u0026e.minX\u003c=e.maxX\u0026\u0026e.minY\u003c=e.maxY\u0026\u0026Number.isFinite(o)\u0026\u0026Math.abs(t.start.x)\u003c=1e4\u0026\u0026Math.abs(t.start.y)\u003c=1e4\u0026\u0026Math.abs(t.end.x)\u003c=1e4\u0026\u0026Math.abs(t.end.y)\u003c=1e4\u0026\u0026Math.abs(e.minX)\u003c=1e4\u0026\u0026Math.abs(e.minY)\u003c=1e4\u0026\u0026Math.abs(e.maxX)\u003c=1e4\u0026\u0026Math.abs(e.maxY)\u003c=1e4})(t,n,this.traceClearance))return;const o=(void 0===e.radius?ke(t.start,t.end,n):De(t.start,t.end,{x:e.x,y:e.y,radius:e.radius}))-t.width/2;if(o+y1\u003e=this.traceClearance)return;const i=`overlap_${t.traceId}_${e.obstacleId}`;return{type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:T1(t.traceId,`${e.obstacleType} \"${e.obstacleId}\"`,o),pcb_trace_id:t.traceId,source_trace_id:\"\",pcb_trace_error_id:i,minimum_clearance:this.traceClearance,actual_clearance:o,pcb_component_ids:[],pcb_port_ids:[...new Set([...t.pcbPortIds,...e.pcbPortId?[e.pcbPortId]:[]])],center:void 0===e.radius?N1(t,n):M1(t,e)}}appendTraceObstacleErrors(t,e){const n=this.cacheImmutableTraceGeometry?t.geometryKey:void 0,o=n?this.immutableStaticClearance.get(n):void 0;if(o)return this.lastRunStats.broadPhaseCandidateCount+=o.broadPhaseCandidateCount,void(this.lastRunStats.exactCheckCount+=o.exactCheckCount);const i=this.cacheImmutableTraceGeometry?this.getStaticObstacleCandidates(t,t.layer):this.obstacleIndexesByLayer.get(t.layer)?.query(x1(t))??[],r=e.length,s=this.lastRunStats.exactCheckCount;for(const n of i){this.lastRunStats.broadPhaseCandidateCount+=1;const o=this.checkTraceObstacle(t,n);o\u0026\u0026e.push(o)}n\u0026\u0026e.length===r\u0026\u0026this.immutableStaticClearance.set(n,{broadPhaseCandidateCount:i.length,exactCheckCount:this.lastRunStats.exactCheckCount-s})}checkViaObstacle(t,e){if(this.obstacleSharesNet(t.netId,e))return;this.lastRunStats.exactCheckCount+=1;const n=S1(e),o=(void 0===e.radius?Math.hypot(Math.max(n.minX-t.x,0,t.x-n.maxX),Math.max(n.minY-t.y,0,t.y-n.maxY)):Math.hypot(t.x-e.x,t.y-e.y)-e.radius)-t.diameter/2;if(o+y1\u003e=this.viaToPadClearance)return;const i=`via_pad_clearance_${t.viaId}_${e.obstacleId}`,r={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return{type:\"pcb_pad_pad_clearance_error\",error_type:\"pcb_pad_pad_clearance_error\",pcb_pad_pad_clearance_error_id:i,message:`pcb_via \"${t.viaId}\" and ${e.obstacleType} \"${e.obstacleId}\" are too close (gap: ${o.toFixed(3)}mm)`,pcb_trace_id:t.traceId,pcb_pad_ids:[t.viaId,e.obstacleId],pcb_via_ids:[t.viaId],minimum_clearance:this.viaToPadClearance,actual_clearance:o,center:r}}checkViaPairs(t){if(t.length\u003c2)return[];const e=[],n=new C1(this.cellSize);for(const e of t)n.insert(e,b1(v1(e),this.viaClearance));for(const o of t)for(const t of n.query(v1(o))){if(this.lastRunStats.broadPhaseCandidateCount+=1,t.order\u003c=o.order)continue;this.lastRunStats.exactCheckCount+=1;const n=Math.hypot(o.x-t.x,o.y-t.y);if(n\u003c=_1)continue;const i=n-o.diameter/2-t.diameter/2;if(i+y1\u003e=this.viaClearance)continue;const r=this.areConnected(o.netId,t.netId),s=[o.viaId,t.viaId].sort().join(\"_\"),a={x:(o.x+t.x)/2,y:(o.y+t.y)/2};e.push({type:\"pcb_via_clearance_error\",error_type:\"pcb_via_clearance_error\",pcb_error_id:`${r?\"same_net\":\"different_net\"}_vias_close_${s}`,message:`Vias ${o.viaId} and ${t.viaId}${r?\"\":\" from different nets\"} are too close together (gap: ${i.toFixed(3)}mm)`,pcb_via_ids:[o.viaId,t.viaId],...this.includeTraceViaOwnerMetadata?{pcb_trace_ids:[o.traceId,t.traceId]}:{},pcb_via_pair_net_relation:r?\"same_net\":\"different_net\",minimum_clearance:this.viaClearance,actual_clearance:i,pcb_center:a,center:a})}return e}evaluate(t){return this.evaluateInternal(t,!0)}evaluateLegacy(t){return this.evaluateInternal(t,!1)}evaluateInternal(t,e){const{segments:n,vias:o}=this.collectDynamicGeometry(t),i=this.buildDynamicIndexes(n,o),r=[],s=[];this.lastRunStats={traceCount:t.length,segmentCount:n.length,viaCount:o.length,obstacleCount:this.obstacles.length,broadPhaseCandidateCount:0,exactCheckCount:0};for(const t of n){const e=x1(t),n=i.get(t.layer),o=n?this.cacheImmutableTraceGeometry?this.useTransientDynamicQueryMarkers?n.queryWithCellKeysUsingOrder(this.getImmutableDynamicQueryCellKeys(t,n,e),t.order):n.queryWithCellKeys(this.getImmutableDynamicQueryCellKeys(t,n,e)):n.query(e):[];for(const e of o){if(this.lastRunStats.broadPhaseCandidateCount+=1,\"trace_segment\"===e.kind\u0026\u0026e.order\u003c=t.order)continue;const n=\"trace_segment\"===e.kind?this.checkTracePair(t,e):this.checkTraceVia(t,e);n\u0026\u0026r.push(n)}this.appendTraceObstacleErrors(t,r)}const a=this.checkViaPairs(o);if(e)for(const t of o){const e=new Set;for(const n of t.layers){const o=this.cacheImmutableTraceGeometry?this.getStaticObstacleCandidates(t,n):this.obstacleIndexesByLayer.get(n)?.query(v1(t))??[];for(const n of o){if(e.has(n))continue;e.add(n),this.lastRunStats.broadPhaseCandidateCount+=1;const o=this.checkViaObstacle(t,n);o\u0026\u0026s.push(o)}}}const c=new Map;for(const t of r){const e=String(t.pcb_trace_error_id),n=c.get(e),o=Number(t.actual_clearance);if(!n){c.set(e,{...t,first_contact_center:t.center,first_contact_message:t.message,first_actual_clearance:o,worst_contact_center:t.center,worst_contact_message:t.message,worst_actual_clearance:o});continue}const i=Number(n.worst_actual_clearance);(o\u003ci||!Number.isFinite(i))\u0026\u0026(n.worst_contact_center=t.center,n.worst_contact_message=t.message,n.worst_actual_clearance=o)}const l=[...c.values()].map(t=\u003e({...t,center:\"object\"==typeof t.worst_contact_center?t.worst_contact_center:t.center,message:\"string\"==typeof t.worst_contact_message?t.worst_contact_message:t.message,actual_clearance:\"number\"==typeof t.worst_actual_clearance?t.worst_actual_clearance:t.actual_clearance}));l.push(...s),l.push(...a);const d=l.filter(t=\u003et.center);return{errors:l,errorsWithCenters:d,locationAwareErrors:d}}},E1=(t,e)=\u003et.width??e.width??.1,A1={Hz:{baseUnit:\"Hz\",variants:{MHz:1e6,kHz:1e3,Hz:1}},g:{baseUnit:\"g\",variants:{kg:1e3,g:1}},\"Ω\":{baseUnit:\"Ω\",variants:{\"mΩ\":.001,\"Ω\":1,\"kΩ\":1e3,\"KΩ\":1e3,kohm:1e3,\"MΩ\":1e6,\"GΩ\":1e9,\"TΩ\":1e12}},V:{baseUnit:\"V\",variants:{mV:.001,V:1,kV:1e3,KV:1e3,MV:1e6,GV:1e9,TV:1e12}},A:{baseUnit:\"A\",variants:{\"µA\":1e-6,mA:.001,ma:.001,A:1,kA:1e3,MA:1e6}},F:{baseUnit:\"F\",variants:{pF:1e-12,nF:1e-9,\"µF\":1e-6,uF:1e-6,mF:.001,F:1}},ml:{baseUnit:\"ml\",variants:{ml:1,mL:1,l:1e3,L:1e3}},deg:{baseUnit:\"deg\",variants:{rad:180/Math.PI}},ms:{baseUnit:\"ms\",variants:{fs:1e-12,ps:1e-9,ns:1e-6,us:.001,\"µs\":.001,ms:1,s:1e3}},mm:{baseUnit:\"mm\",variants:{nm:1e-6,\"µm\":.001,um:.001,mm:1,cm:10,dm:100,m:1e3,km:1e6,in:25.4,ft:304.8,IN:25.4,FT:304.8,yd:914.4,mi:1609344,mil:.0254}}},O1=new Set;for(const[t,e]of Object.entries(A1)){O1.add(t);for(const t of Object.keys(e.variants))O1.add(t)}var k1={tera:1e12,T:1e12,giga:1e9,G:1e9,mega:1e6,M:1e6,kilo:1e3,k:1e3,deci:.1,d:.1,centi:.01,c:.01,milli:.001,m:.001,micro:1e-6,u:1e-6,\"µ\":1e-6,nano:1e-9,n:1e-9,pico:1e-12,p:1e-12};function L1(t){if(null==t)return{parsedUnit:null,unitOfValue:null,value:null};if(\"string\"==typeof t\u0026\u0026t.match(/^-?[\\d\\.]+$/))return{value:Number.parseFloat(t),parsedUnit:null,unitOfValue:null};if(\"number\"==typeof t)return{value:t,parsedUnit:null,unitOfValue:null};if(\"object\"==typeof t\u0026\u0026\"x\"in t\u0026\u0026\"y\"in t){const{parsedUnit:e,unitOfValue:n}=L1(t.x),o=L1(t.x),i=L1(t.y);return null===o.value||null===i.value?{parsedUnit:null,unitOfValue:null,value:null}:{parsedUnit:e,unitOfValue:n,value:{x:o.value,y:i.value}}}const e=t.toString().split(\"\").reverse().join(\"\"),n=e.match(/[^\\d\\s]+/)?.[0];if(!n)throw new Error(`Could not determine unit: \"${t}\"`);const o=n.split(\"\").reverse().join(\"\"),i=t.slice(0,-o.length);if(o in k1\u0026\u0026!O1.has(o)){const t=k1[o];return{parsedUnit:null,unitOfValue:null,value:Number.parseFloat(i)*t}}const{baseUnit:r,conversionFactor:s}=function(t){for(const[e,n]of Object.entries(A1))if(t in n.variants)return{baseUnit:n.baseUnit,conversionFactor:n.variants[t]};return{baseUnit:t,conversionFactor:1}}(o);return{parsedUnit:o,unitOfValue:r,value:s*Number.parseFloat(i)}}var D1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),z1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value).transform(t=\u003eNumber.parseFloat(t.toPrecision(12))),F1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),B1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),j1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),$1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),Y1=j1,X1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),V1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),W1=V1,H1=k_.string().datetime(),G1=k_.string().or(k_.number()).transform(t=\u003e\"number\"==typeof t?t:t.endsWith(\"deg\")?Number.parseFloat(t.split(\"deg\")[0]):t.endsWith(\"rad\")?180*Number.parseFloat(t.split(\"rad\")[0])/Math.PI:Number.parseFloat(t)),U1=k_.number().or(k_.string().endsWith(\"mAh\")).transform(t=\u003e{if(\"string\"==typeof t){const e=t.replace(\"mAh\",\"\"),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error(\"Invalid capacity\");return n}return t}).describe(\"Battery capacity in mAh\"),Z1=k_.object({x:Y1,y:Y1}),q1=k_.object({x:Y1,y:Y1,z:Y1}),J1=k_.object({width:k_.number(),height:k_.number()}),K1=t=\u003ek_.string().optional().default(()=\u003e`${t}_${(t=\u003e{const e=\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";return Array.from({length:t},()=\u003ee[Math.floor(62*Math.random())]).join(\"\")})(10)}`),Q1=k_.enum([\"top_left\",\"top_center\",\"top_right\",\"center_left\",\"center\",\"center_right\",\"bottom_left\",\"bottom_center\",\"bottom_right\"]),t2=(k_.enum([\"top_silkscreen\",\"bottom_silkscreen\",\"top_copper\",\"bottom_copper\",\"top_soldermask\",\"bottom_soldermask\",\"top_fabrication_note\",\"bottom_fabrication_note\",\"top_user_note\",\"bottom_user_note\",\"top_courtyard\",\"bottom_courtyard\",\"inner1_copper\",\"inner2_copper\",\"inner3_copper\",\"inner4_copper\",\"inner5_copper\",\"inner6_copper\",\"edge_cuts\",\"drill\"]),k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()})),e2=Z1.extend({rotation:G1.optional()}),n2=k_.object({size:Z1.optional(),thickness:Y1.optional()}),o2=k_.object({font:n2.optional()}),i2=k_.object({value:k_.string(),at:e2.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:o2.optional()}),r2=k_.object({Reference:i2.optional(),Value:i2.optional(),Datasheet:i2.optional(),Description:i2.optional()}),s2=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),a2=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:e2.optional(),size:Z1.optional(),drill:Y1.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),c2=k_.object({path:k_.string(),offset:q1.optional(),scale:q1.optional(),rotate:q1.optional()}),l2=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:r2.optional(),attributes:s2.optional(),pads:k_.array(a2).optional(),embeddedFonts:k_.boolean().optional(),model:c2.optional()}),d2=k_.object({hide:k_.boolean().optional()}),h2=k_.object({offset:Y1.optional(),hide:k_.boolean().optional()}),u2=k_.object({font:n2.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),p2=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:e2.optional(),effects:u2.optional()}),m2=k_.object({Reference:p2.optional(),Value:p2.optional(),Footprint:p2.optional(),Datasheet:p2.optional(),Description:p2.optional(),ki_keywords:p2.optional(),ki_fp_filters:p2.optional()}),g2=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:d2.optional(),pinNames:h2.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:m2.optional(),embeddedFonts:k_.boolean().optional()}),f2=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),y2=k_.enum([\"jlcpcb\",\"macrofab\",\"pcbway\",\"digikey\",\"mouser\",\"lcsc\"]),_2=k_.object({type:k_.literal(\"source_component\"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(y2,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),b2=_2.extend({ftype:k_.literal(\"simple_capacitor\"),capacitance:z1,max_voltage_rating:B1.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:Y1.optional()}),x2=_2.extend({ftype:k_.literal(\"simple_resistor\"),resistance:D1,display_resistance:k_.string().optional()}),v2=_2.extend({ftype:k_.literal(\"simple_diode\")}),S2=_2.extend({ftype:k_.literal(\"simple_fiducial\")}),I2=v2.extend({ftype:k_.literal(\"simple_led\"),color:k_.string().optional(),wavelength:k_.string().optional()}),C2=_2.extend({ftype:k_.literal(\"simple_ground\")}),P2=_2.extend({ftype:k_.literal(\"simple_chip\")}),M2=_2.extend({ftype:k_.literal(\"simple_power_source\"),voltage:B1}),N2=_2.extend({ftype:k_.literal(\"simple_current_source\"),current:X1,frequency:$1.optional(),peak_to_peak_current:X1.optional(),wave_shape:k_.enum([\"sine\",\"square\",\"triangle\",\"sawtooth\",\"dc\"]).optional().default(\"dc\"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),w2=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),T2=_2.extend({ftype:k_.literal(\"simple_fuse\"),current_rating_amps:k_.number().describe(\"Nominal current in amps the fuse is rated for\"),voltage_rating_volts:k_.number().describe(\"Voltage rating in volts, e.g. ±5V would be 5\")}),R2=_2.extend({ftype:k_.literal(\"simple_battery\"),capacity:U1}),E2=_2.extend({ftype:k_.literal(\"simple_inductor\"),inductance:F1,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),A2=_2.extend({ftype:k_.literal(\"simple_push_button\")}),O2=_2.extend({ftype:k_.literal(\"simple_potentiometer\"),max_resistance:D1,display_max_resistance:k_.string().optional()}),k2=_2.extend({ftype:k_.literal(\"simple_crystal\"),frequency:k_.number().describe(\"Frequency in Hz\"),load_capacitance:k_.number().optional().describe(\"Load capacitance in pF\"),pin_variant:k_.enum([\"two_pin\",\"four_pin\"]).optional()}),L2=_2.extend({ftype:k_.literal(\"simple_pin_header\"),pin_count:k_.number(),gender:k_.enum([\"male\",\"female\"]).optional().default(\"male\")}),D2=_2.extend({ftype:k_.literal(\"simple_connector\"),standard:k_.enum([\"usb_c\",\"m2\"]).optional()}),z2=_2.extend({ftype:k_.literal(\"simple_pinout\")}),F2=_2.extend({ftype:k_.literal(\"simple_resonator\"),load_capacitance:z1,equivalent_series_resistance:D1.optional(),frequency:$1}),B2=_2.extend({ftype:k_.literal(\"simple_transistor\"),transistor_type:k_.enum([\"npn\",\"pnp\"])}),j2=_2.extend({ftype:k_.literal(\"simple_test_point\"),footprint_variant:k_.enum([\"pad\",\"through_hole\"]).optional(),pad_shape:k_.enum([\"rect\",\"circle\"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),$2=_2.extend({ftype:k_.literal(\"simple_mosfet\"),channel_type:k_.enum([\"n\",\"p\"]),mosfet_mode:k_.enum([\"enhancement\",\"depletion\"])}),Y2=_2.extend({ftype:k_.literal(\"simple_op_amp\")}),X2=_2.extend({ftype:k_.literal(\"simple_switch\")}),V2=k_.object({type:k_.literal(\"source_project_metadata\"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),created_at:H1.optional()}),W2=f2.extend({type:k_.literal(\"source_missing_property_error\"),source_missing_property_error_id:K1(\"source_missing_property_error\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_missing_property_error\").default(\"source_missing_property_error\")}).describe(\"The source code is missing a property\"),H2=f2.extend({type:k_.literal(\"source_failed_to_create_component_error\"),source_failed_to_create_component_error_id:K1(\"source_failed_to_create_component_error\"),error_type:k_.literal(\"source_failed_to_create_component_error\").default(\"source_failed_to_create_component_error\"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe(\"Error emitted when a component fails to be constructed\"),G2=f2.extend({type:k_.literal(\"source_invalid_component_property_error\"),source_invalid_component_property_error_id:K1(\"source_invalid_component_property_error\"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_invalid_component_property_error\").default(\"source_invalid_component_property_error\")}).describe(\"The source component property is invalid\"),U2=f2.extend({type:k_.literal(\"source_trace_not_connected_error\"),source_trace_not_connected_error_id:K1(\"source_trace_not_connected_error\"),error_type:k_.literal(\"source_trace_not_connected_error\").default(\"source_trace_not_connected_error\"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe(\"Occurs when a source trace selector does not match any ports\"),Z2=k_.object({type:k_.literal(\"source_property_ignored_warning\"),source_property_ignored_warning_id:K1(\"source_property_ignored_warning\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_property_ignored_warning\").default(\"source_property_ignored_warning\"),message:k_.string()}).describe(\"The source property was ignored\"),q2=k_.object({type:k_.literal(\"source_pin_missing_trace_warning\"),source_pin_missing_trace_warning_id:K1(\"source_pin_missing_trace_warning\"),warning_type:k_.literal(\"source_pin_missing_trace_warning\").default(\"source_pin_missing_trace_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component pin is missing a trace connection\"),J2=k_.object({type:k_.literal(\"source_missing_manufacturer_part_number_warning\"),source_missing_manufacturer_part_number_warning_id:K1(\"source_missing_manufacturer_part_number_warning\"),warning_type:k_.literal(\"source_missing_manufacturer_part_number_warning\").default(\"source_missing_manufacturer_part_number_warning\"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a standard connector is missing manufacturer part number\"),K2=_2.extend({ftype:k_.literal(\"simple_voltage_probe\")}),Q2=_2.extend({ftype:k_.literal(\"interconnect\")}),t5=f2.extend({type:k_.literal(\"source_i2c_misconfigured_error\"),source_i2c_misconfigured_error_id:K1(\"source_i2c_misconfigured_error\"),error_type:k_.literal(\"source_i2c_misconfigured_error\").default(\"source_i2c_misconfigured_error\"),source_port_ids:k_.array(k_.string())}).describe(\"Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net\"),e5=_2.extend({ftype:k_.literal(\"simple_voltage_source\"),voltage:B1,frequency:$1.optional(),peak_to_peak_voltage:B1.optional(),wave_shape:k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]).optional(),phase:G1.optional(),duty_cycle:k_.number().optional().describe(\"Duty cycle as a fraction (0 to 1)\")}),n5=k_.union([x2,b2,v2,S2,I2,C2,P2,M2,N2,R2,E2,A2,O2,k2,L2,D2,z2,F2,X2,B2,j2,$2,Y2,T2,K2,Q2,e5,V2,W2,G2,H2,U2,Z2,q2,J2,t5]),o5=k_.object({type:k_.literal(\"source_port\"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(w2),i5=k_.object({type:k_.literal(\"source_component_internal_connection\"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),r5=k_.object({type:k_.literal(\"source_trace\"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),s5=k_.object({type:k_.literal(\"source_group\"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),a5=k_.object({type:k_.literal(\"source_net\"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),c5=k_.object({type:k_.literal(\"source_board\"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe(\"Defines a board in the source domain\"),l5=f2.extend({type:k_.literal(\"source_ambiguous_port_reference\"),source_ambiguous_port_reference_id:K1(\"source_ambiguous_port_reference\"),error_type:k_.literal(\"source_ambiguous_port_reference\").default(\"source_ambiguous_port_reference\"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous\"),d5=k_.object({type:k_.literal(\"source_pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane in the source domain\"),h5=k_.enum([\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\"]),u5=h5.or(k_.object({name:h5})).transform(t=\u003e\"string\"==typeof t?t:t.name),p5=k_.enum([\"top\",\"bottom\"]),m5=k_.object({type:k_.literal(\"source_manually_placed_via\"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe(\"Defines a via that is manually placed in the source domain\"),g5=k_.object({type:k_.literal(\"source_no_power_pin_defined_warning\"),source_no_power_pin_defined_warning_id:K1(\"source_no_power_pin_defined_warning\"),warning_type:k_.literal(\"source_no_power_pin_defined_warning\").default(\"source_no_power_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports with requires_power=true\"),f5=k_.object({type:k_.literal(\"source_no_ground_pin_defined_warning\"),source_no_ground_pin_defined_warning_id:K1(\"source_no_ground_pin_defined_warning\"),warning_type:k_.literal(\"source_no_ground_pin_defined_warning\").default(\"source_no_ground_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports marked as ground pins\"),y5=k_.object({type:k_.literal(\"source_component_pins_underspecified_warning\"),source_component_pins_underspecified_warning_id:K1(\"source_component_pins_underspecified_warning\"),warning_type:k_.literal(\"source_component_pins_underspecified_warning\").default(\"source_component_pins_underspecified_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when all ports on a source component are underspecified\"),_5=f2.extend({type:k_.literal(\"source_pin_must_be_connected_error\"),source_pin_must_be_connected_error_id:K1(\"source_pin_must_be_connected_error\"),error_type:k_.literal(\"source_pin_must_be_connected_error\").default(\"source_pin_must_be_connected_error\"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pin with mustBeConnected attribute is not connected to any trace\"),b5=f2.extend({type:k_.literal(\"unknown_error_finding_part\"),unknown_error_finding_part_id:K1(\"unknown_error_finding_part\"),error_type:k_.literal(\"unknown_error_finding_part\").default(\"unknown_error_finding_part\"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when an unexpected error occurs while finding a part\"),x5=k_.object({type:k_.literal(\"schematic_box\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:Y1,height:Y1,is_dashed:k_.boolean().default(!1),x:Y1,y:Y1,subcircuit_id:k_.string().optional()}).describe(\"Draws a box on the schematic\"),v5=k_.object({type:k_.literal(\"schematic_path\"),schematic_path_id:K1(\"schematic_path\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),stroke_width:Y1.nullable().optional(),stroke_color:k_.string().optional(),points:k_.array(Z1),subcircuit_id:k_.string().optional()}),S5=k_.record(k_.object({left_margin:j1.optional(),right_margin:j1.optional(),top_margin:j1.optional(),bottom_margin:j1.optional()})),I5=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),C5=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional()}),P5=k_.union([I5,C5]),M5=k_.object({type:k_.literal(\"schematic_component\"),size:J1,center:Z1,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_symbol_id:k_.string().optional(),pin_spacing:j1.optional(),pin_styles:S5.optional(),box_width:j1.optional(),symbol_name:k_.string().optional(),port_arrangement:P5.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),N5=k_.object({kicad_symbol:g2.optional()}).catchall(k_.unknown()),w5=k_.object({type:k_.literal(\"schematic_symbol\"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:N5.optional()}).describe(\"Defines a named schematic symbol that can be referenced by components.\"),T5=k_.object({type:k_.literal(\"schematic_line\"),schematic_line_id:K1(\"schematic_line\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:Y1,y1:Y1,x2:Y1,y2:Y1,stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled line on the schematic\"),R5=k_.object({type:k_.literal(\"schematic_rect\"),schematic_rect_id:K1(\"schematic_rect\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,width:Y1,height:Y1,rotation:G1.default(0),stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled rectangle on the schematic\"),E5=k_.object({type:k_.literal(\"schematic_circle\"),schematic_circle_id:K1(\"schematic_circle\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,radius:Y1,stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled circle on the schematic\"),A5=k_.object({type:k_.literal(\"schematic_arc\"),schematic_arc_id:K1(\"schematic_arc\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,radius:Y1,start_angle_degrees:G1,end_angle_degrees:G1,direction:k_.enum([\"clockwise\",\"counterclockwise\"]).default(\"counterclockwise\"),stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled arc on the schematic\"),O5=k_.object({type:k_.literal(\"schematic_trace\"),schematic_trace_id:k_.string(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),k5=k_.enum([\"center\",\"left\",\"right\",\"top\",\"bottom\"]),L5=k_.object({type:k_.literal(\"schematic_text\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:Y1,y:Y1}),rotation:k_.number().default(0),anchor:k_.union([k5.describe(\"legacy\"),Q1]).default(\"center\"),color:k_.string().default(\"#000000\"),subcircuit_id:k_.string().optional()}),D5=k_.object({type:k_.literal(\"schematic_port\"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_component_id:k_.string().optional(),center:Z1,facing_direction:k_.enum([\"up\",\"down\",\"left\",\"right\"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe(\"Defines a port on a schematic component\"),z5=k_.object({type:k_.literal(\"schematic_net_label\"),schematic_net_label_id:K1(\"schematic_net_label\"),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:Z1,anchor_position:Z1.optional(),anchor_side:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),F5=f2.extend({type:k_.literal(\"schematic_error\"),schematic_error_id:k_.string(),error_type:k_.literal(\"schematic_port_not_found\").default(\"schematic_port_not_found\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic error on the schematic\"),B5=f2.extend({type:k_.literal(\"schematic_layout_error\"),schematic_layout_error_id:K1(\"schematic_layout_error\"),error_type:k_.literal(\"schematic_layout_error\").default(\"schematic_layout_error\"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when schematic layout fails for a group\"),j5=k_.object({type:k_.literal(\"schematic_debug_object\"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),$5=j5.extend({shape:k_.literal(\"rect\"),center:Z1,size:J1}),Y5=j5.extend({shape:k_.literal(\"line\"),start:Z1,end:Z1}),X5=j5.extend({shape:k_.literal(\"point\"),center:Z1}),V5=k_.discriminatedUnion(\"shape\",[$5,Y5,X5]),W5=k_.object({type:k_.literal(\"schematic_voltage_probe\"),schematic_voltage_probe_id:k_.string(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:Z1,schematic_trace_id:k_.string(),voltage:B1.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:Q1.optional()}).describe(\"Defines a voltage probe measurement point on a schematic trace\"),H5=k_.object({type:k_.literal(\"schematic_manual_edit_conflict_warning\"),schematic_manual_edit_conflict_warning_id:K1(\"schematic_manual_edit_conflict_warning\"),warning_type:k_.literal(\"schematic_manual_edit_conflict_warning\").default(\"schematic_manual_edit_conflict_warning\"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit schX/schY coordinates\"),G5=k_.object({type:k_.literal(\"schematic_group\"),schematic_group_id:K1(\"schematic_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:j1,height:j1,center:Z1,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe(\"Defines a group of components on the schematic\"),U5=k_.object({type:k_.literal(\"schematic_table\"),schematic_table_id:K1(\"schematic_table\"),anchor_position:Z1,column_widths:k_.array(Y1),row_heights:k_.array(Y1),cell_padding:Y1.optional(),border_width:Y1.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:Q1.optional()}).describe(\"Defines a table on the schematic\"),Z5=k_.object({type:k_.literal(\"schematic_table_cell\"),schematic_table_cell_id:K1(\"schematic_table_cell\"),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:Z1,width:Y1,height:Y1,horizontal_align:k_.enum([\"left\",\"center\",\"right\"]).optional(),vertical_align:k_.enum([\"top\",\"middle\",\"bottom\"]).optional(),font_size:Y1.optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a cell within a schematic_table\"),q5=k_.object({type:k_.literal(\"schematic_sheet\"),schematic_sheet_id:K1(\"schematic_sheet\"),name:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic sheet or page that components can be placed on\"),J5=k_.object({x:Y1,y:Y1,bulge:k_.number().optional()}),K5=k_.object({vertices:k_.array(J5)}),Q5=k_.object({outer_ring:K5,inner_rings:k_.array(K5).default([])}),t3=k_.object({x:Y1,y:Y1,via:k_.boolean().optional(),via_to_layer:u5.optional()}),e3=(k_.array(t3),k_.object({x:Y1,y:Y1,via:k_.boolean().optional(),to_layer:u5.optional(),trace_width:Y1.optional()})),n3=k_.object({min_trace_width:j1.optional(),min_board_edge_clearance:j1.optional(),min_via_hole_edge_to_via_hole_edge_clearance:j1.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:j1.optional(),min_trace_to_pad_edge_clearance:j1.optional(),min_pad_edge_to_pad_edge_clearance:j1.optional(),min_same_net_trace_edge_to_trace_edge_clearance:j1.optional(),min_different_net_trace_edge_to_trace_edge_clearance:j1.optional(),min_via_hole_diameter:j1.optional(),min_via_pad_diameter:j1.optional()}),o3=k_.object({type:k_.literal(\"pcb_component\"),pcb_component_id:K1(\"pcb_component\"),source_component_id:k_.string(),center:Z1,layer:u5,rotation:G1,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this part, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this part, usually corresponding with how the user specified it\"),width:j1,height:j1,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"relative_to_another_component\",\"none\"]).optional(),anchor_position:Z1.optional(),anchor_alignment:Q1.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:Z1.optional(),insertion_direction:k_.enum([\"from_above\",\"from_left\",\"from_right\",\"from_front\",\"from_back\"]).optional(),metadata:k_.object({kicad_footprint:l2.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe(\"Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath\")}).describe(\"Defines a component on the PCB\"),i3=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),hole_diameter:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),r3=(i3.describe(\"Defines a circular hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),s3=(r3.describe(\"Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"square\"]),hole_diameter:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),a3=(s3.describe(\"Defines a circular or square hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"oval\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),c3=(a3.describe(\"Defines an oval hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),l3=(c3.describe(\"Defines a pill-shaped hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,ccw_rotation:G1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),d3=(l3.describe(\"Defines a rotated pill-shaped hole on the PCB\"),s3.or(a3).or(c3).or(l3).or(i3).or(r3)),h3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),u3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.enum([\"oval\",\"pill\"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,ccw_rotation:G1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),p3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circular_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),pad_shape:k_.literal(\"rect\"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:G1.optional()}),m3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),g3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"rotated_pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:G1,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:G1,hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),f3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"hole_with_polygon_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"oval\",\"pill\",\"rotated_pill\"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:Y1,y:Y1})).min(3),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),ccw_rotation:G1.optional()}),y3=k_.union([h3,u3,p3,m3,g3,f3]),_3=k_.object({type:k_.literal(\"pcb_port\"),pcb_port_id:K1(\"pcb_port\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:Y1,y:Y1,layers:k_.array(u5),is_board_pinout:k_.boolean().optional()}).describe(\"Defines a port on the PCB\"),b3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"circle\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,radius:k_.number(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),x3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rect\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),v3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_rect\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:G1,layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),S3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"pill\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),I3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_pill\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:G1,layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),C3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"polygon\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(Z1),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),P3=k_.discriminatedUnion(\"shape\",[b3,x3,v3,I3,S3,C3]).describe(\"Defines an SMT pad on the PCB\"),M3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"circle\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,radius:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),N3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rect\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),w3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"pill\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),T3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rotated_rect\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),ccw_rotation:Y1,layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),R3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"oval\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),E3=k_.union([M3,N3,w3,T3,R3]).describe(\"Defines solderpaste on the PCB\"),A3=k_.object({type:k_.literal(\"pcb_text\"),pcb_text_id:K1(\"pcb_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:Z1,layer:u5,width:j1,height:j1,lines:k_.number(),align:k_.enum([\"bottom-left\"])}).describe(\"Defines text on the PCB\"),O3=k_.object({route_type:k_.literal(\"wire\"),x:Y1,y:Y1,width:Y1,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:u5}),k3=k_.object({route_type:k_.literal(\"via\"),x:Y1,y:Y1,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:Y1.optional(),outer_diameter:Y1.optional(),from_layer:u5,to_layer:u5}),L3=k_.union([O3,k3]),D3=k_.object({type:k_.literal(\"pcb_trace\"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:K1(\"pcb_trace\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum([\"constant\",\"interpolated\"]).default(\"constant\").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(L3)}).describe(\"Defines a trace on the PCB\"),z3=k_.object({type:k_.literal(\"pcb_trace_warning\"),pcb_trace_warning_id:K1(\"pcb_trace_warning\"),warning_type:k_.literal(\"pcb_trace_warning\").default(\"pcb_trace_warning\"),message:k_.string(),center:Z1.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace warning on the PCB\"),F3=f2.extend({type:k_.literal(\"pcb_trace_error\"),pcb_trace_error_id:K1(\"pcb_trace_error\"),error_type:k_.literal(\"pcb_trace_error\").default(\"pcb_trace_error\"),center:Z1.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB\"),B3=f2.extend({type:k_.literal(\"pcb_trace_missing_error\"),pcb_trace_missing_error_id:K1(\"pcb_trace_missing_error\"),error_type:k_.literal(\"pcb_trace_missing_error\").default(\"pcb_trace_missing_error\"),center:Z1.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a source trace has no corresponding PCB trace\"),j3=f2.extend({type:k_.literal(\"pcb_port_not_matched_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_port_not_matched_error\").default(\"pcb_port_not_matched_error\"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB where a port is not matched\"),$3=f2.extend({type:k_.literal(\"pcb_port_not_connected_error\"),pcb_port_not_connected_error_id:K1(\"pcb_port_not_connected_error\"),error_type:k_.literal(\"pcb_port_not_connected_error\").default(\"pcb_port_not_connected_error\"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a pcb port is not connected to any trace\"),Y3=k_.object({type:k_.literal(\"pcb_net\"),pcb_net_id:K1(\"pcb_net\"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe(\"Defines a net on the PCB\"),X3=k_.object({type:k_.literal(\"pcb_via\"),pcb_via_id:K1(\"pcb_via\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:Y1,y:Y1,outer_diameter:Y1.default(\"0.6mm\"),hole_diameter:Y1.default(\"0.25mm\"),from_layer:u5.optional(),to_layer:u5.optional(),layers:k_.array(u5),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe(\"Defines a via on the PCB\"),V3=k_.object({type:k_.literal(\"pcb_board\"),pcb_board_id:K1(\"pcb_board\"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:j1.optional(),height:j1.optional(),center:Z1,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this board, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this board, usually corresponding with how the user specified it\"),thickness:j1.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(Z1).optional(),shape:k_.enum([\"rect\",\"polygon\"]).optional(),material:k_.enum([\"fr4\",\"fr1\"]).default(\"fr4\"),anchor_position:Z1.optional(),anchor_alignment:Q1.optional(),position_mode:k_.enum([\"relative_to_panel_anchor\",\"none\"]).optional()}).merge(n3).describe(\"Defines the board outline of the PCB\"),W3=k_.object({type:k_.literal(\"pcb_panel\"),pcb_panel_id:K1(\"pcb_panel\"),width:j1,height:j1,center:Z1,thickness:j1.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe(\"Defines a PCB panel that can contain multiple boards\"),H3=f2.extend({type:k_.literal(\"pcb_placement_error\"),pcb_placement_error_id:K1(\"pcb_placement_error\"),error_type:k_.literal(\"pcb_placement_error\").default(\"pcb_placement_error\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a placement error on the PCB\"),G3=f2.extend({type:k_.literal(\"pcb_panelization_placement_error\"),pcb_panelization_placement_error_id:K1(\"pcb_panelization_placement_error\"),error_type:k_.literal(\"pcb_panelization_placement_error\").default(\"pcb_panelization_placement_error\"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a panelization placement error on the PCB\"),U3=k_.object({type:k_.literal(\"pcb_trace_hint\"),pcb_trace_hint_id:K1(\"pcb_trace_hint\"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(e3),subcircuit_id:k_.string().optional()}).describe(\"A hint that can be used during generation of a PCB trace\"),Z3=k_.object({type:k_.literal(\"pcb_silkscreen_line\"),pcb_silkscreen_line_id:K1(\"pcb_silkscreen_line\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:Y1.default(\"0.1mm\"),x1:Y1,y1:Y1,x2:Y1,y2:Y1,layer:p5}).describe(\"Defines a silkscreen line on the PCB\"),q3=k_.object({type:k_.literal(\"pcb_silkscreen_path\"),pcb_silkscreen_path_id:K1(\"pcb_silkscreen_path\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,route:k_.array(Z1),stroke_width:j1}).describe(\"Defines a silkscreen path on the PCB\"),J3=k_.object({type:k_.literal(\"pcb_silkscreen_text\"),pcb_silkscreen_text_id:K1(\"pcb_silkscreen_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:j1,top:j1,bottom:j1,right:j1}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:u5,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:Q1.default(\"center\")}).describe(\"Defines silkscreen text on the PCB\"),K3=k_.object({type:k_.literal(\"pcb_copper_text\"),pcb_copper_text_id:K1(\"pcb_copper_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:j1,top:j1,bottom:j1,right:j1}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:u5,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:Q1.default(\"center\")}).describe(\"Defines copper text on the PCB\"),Q3=k_.object({type:k_.literal(\"pcb_silkscreen_rect\"),pcb_silkscreen_rect_id:K1(\"pcb_silkscreen_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:u5,stroke_width:j1.default(\"1mm\"),corner_radius:j1.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen rect on the PCB\"),t4=k_.object({type:k_.literal(\"pcb_silkscreen_circle\"),pcb_silkscreen_circle_id:K1(\"pcb_silkscreen_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:j1,layer:p5,stroke_width:j1.default(\"1mm\"),is_filled:k_.boolean().optional()}).describe(\"Defines a silkscreen circle on the PCB\"),e4=k_.object({type:k_.literal(\"pcb_silkscreen_oval\"),pcb_silkscreen_oval_id:K1(\"pcb_silkscreen_oval\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius_x:Y1,radius_y:Y1,layer:p5,ccw_rotation:G1.optional()}).describe(\"Defines a silkscreen oval on the PCB\"),n4=k_.object({type:k_.literal(\"pcb_silkscreen_pill\"),pcb_silkscreen_pill_id:K1(\"pcb_silkscreen_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:u5,ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen pill on the PCB\"),o4=k_.object({type:k_.literal(\"pcb_fabrication_note_text\"),pcb_fabrication_note_text_id:K1(\"pcb_fabrication_note_text\"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"1mm\"),pcb_component_id:k_.string(),text:k_.string(),layer:p5,anchor_position:Z1.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),color:k_.string().optional()}).describe(\"Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators\"),i4=k_.object({type:k_.literal(\"pcb_fabrication_note_path\"),pcb_fabrication_note_path_id:K1(\"pcb_fabrication_note_path\"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:u5,route:k_.array(Z1),stroke_width:j1,color:k_.string().optional()}).describe(\"Defines a fabrication path on the PCB for fabricators or assemblers\"),r4=k_.object({type:k_.literal(\"pcb_fabrication_note_rect\"),pcb_fabrication_note_rect_id:K1(\"pcb_fabrication_note_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5,stroke_width:j1.default(\"0.1mm\"),corner_radius:j1.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a fabrication note rectangle on the PCB\"),s4=k_.object({type:k_.literal(\"pcb_fabrication_note_dimension\"),pcb_fabrication_note_dimension_id:K1(\"pcb_fabrication_note_dimension\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,from:Z1,to:Z1,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:j1.optional(),offset_distance:j1.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:j1.default(\"1mm\"),color:k_.string().optional(),arrow_size:j1.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB fabrication notes\"),a4=k_.object({type:k_.literal(\"pcb_note_text\"),pcb_note_text_id:K1(\"pcb_note_text\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"1mm\"),text:k_.string().optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),layer:p5.default(\"top\"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a documentation note in text on the PCB\"),c4=k_.object({type:k_.literal(\"pcb_note_rect\"),pcb_note_rect_id:K1(\"pcb_note_rect\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5.default(\"top\"),stroke_width:j1.default(\"0.1mm\"),corner_radius:j1.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a rectangular documentation note on the PCB\"),l4=k_.object({type:k_.literal(\"pcb_note_path\"),pcb_note_path_id:K1(\"pcb_note_path\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(Z1),layer:p5.default(\"top\"),stroke_width:j1.default(\"0.1mm\"),color:k_.string().optional()}).describe(\"Defines a polyline documentation note on the PCB\"),d4=k_.object({type:k_.literal(\"pcb_note_line\"),pcb_note_line_id:K1(\"pcb_note_line\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:Y1,y1:Y1,x2:Y1,y2:Y1,layer:p5.default(\"top\"),stroke_width:Y1.default(\"0.1mm\"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe(\"Defines a straight documentation note line on the PCB\"),h4=k_.object({type:k_.literal(\"pcb_note_dimension\"),pcb_note_dimension_id:K1(\"pcb_note_dimension\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:Z1,to:Z1,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:j1.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:j1.default(\"1mm\"),layer:p5.default(\"top\"),color:k_.string().optional(),arrow_size:j1.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB documentation notes\"),u4=f2.extend({type:k_.literal(\"pcb_footprint_overlap_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_footprint_overlap_error\").default(\"pcb_footprint_overlap_error\"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when a pcb footprint overlaps with another element\"),p4=f2.extend({type:k_.literal(\"pcb_courtyard_overlap_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_courtyard_overlap_error\").default(\"pcb_courtyard_overlap_error\"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe(\"Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another\"),m4=k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"rect\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:Y1,height:Y1,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:Y1,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),g4=k_.object({type:k_.literal(\"pcb_cutout\"),pcb_cutout_id:K1(\"pcb_cutout\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),f4=g4.extend({shape:k_.literal(\"rect\"),center:Z1,width:j1,height:j1,rotation:G1.optional(),corner_radius:j1.optional()}),y4=g4.extend({shape:k_.literal(\"circle\"),center:Z1,radius:j1}),_4=g4.extend({shape:k_.literal(\"polygon\"),points:k_.array(Z1)}),b4=g4.extend({shape:k_.literal(\"path\"),route:k_.array(Z1),slot_width:j1,slot_length:j1.optional(),space_between_slots:j1.optional(),slot_corner_radius:j1.optional()}),x4=k_.discriminatedUnion(\"shape\",[f4,y4,_4,b4]).describe(\"Defines a cutout on the PCB, removing board material.\"),v4=f2.extend({type:k_.literal(\"pcb_missing_footprint_error\"),pcb_missing_footprint_error_id:K1(\"pcb_missing_footprint_error\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"pcb_missing_footprint_error\").default(\"pcb_missing_footprint_error\"),source_component_id:k_.string()}).describe(\"Defines a missing footprint error on the PCB\"),S4=f2.extend({type:k_.literal(\"external_footprint_load_error\"),external_footprint_load_error_id:K1(\"external_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal(\"external_footprint_load_error\").default(\"external_footprint_load_error\")}).describe(\"Defines an error when an external footprint fails to load\"),I4=f2.extend({type:k_.literal(\"circuit_json_footprint_load_error\"),circuit_json_footprint_load_error_id:K1(\"circuit_json_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"circuit_json_footprint_load_error\").default(\"circuit_json_footprint_load_error\"),circuit_json:k_.array(k_.any()).optional()}).describe(\"Defines an error when a circuit JSON footprint fails to load\"),C4=k_.object({type:k_.literal(\"pcb_group\"),pcb_group_id:K1(\"pcb_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:j1.optional(),height:j1.optional(),center:Z1,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this group, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this group, usually corresponding with how the user specified it\"),outline:k_.array(Z1).optional(),anchor_position:Z1.optional(),anchor_alignment:Q1.default(\"center\"),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"none\"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum([\"packed\",\"none\"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:j1}).optional(),autorouter_used_string:k_.string().optional()}).describe(\"Defines a group of components on the PCB\"),P4=f2.extend({type:k_.literal(\"pcb_autorouting_error\"),pcb_error_id:K1(\"pcb_autorouting_error\"),error_type:k_.literal(\"pcb_autorouting_error\").default(\"pcb_autorouting_error\"),subcircuit_id:k_.string().optional()}).describe(\"The autorouting has failed to route a portion of the board\"),M4=k_.object({type:k_.literal(\"pcb_manual_edit_conflict_warning\"),pcb_manual_edit_conflict_warning_id:K1(\"pcb_manual_edit_conflict_warning\"),warning_type:k_.literal(\"pcb_manual_edit_conflict_warning\").default(\"pcb_manual_edit_conflict_warning\"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates\"),N4=k_.enum([\"x-\",\"x+\",\"y+\",\"y-\"]),w4=k_.object({type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\"),pcb_connector_not_in_accessible_orientation_warning_id:K1(\"pcb_connector_not_in_accessible_orientation_warning\"),warning_type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\").default(\"pcb_connector_not_in_accessible_orientation_warning\"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:N4,recommended_facing_direction:N4,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction\"),T4=k_.object({type:k_.literal(\"supplier_footprint_mismatch_warning\"),supplier_footprint_mismatch_warning_id:K1(\"supplier_footprint_mismatch_warning\"),warning_type:k_.literal(\"supplier_footprint_mismatch_warning\").default(\"supplier_footprint_mismatch_warning\"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:y2.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe(\"Warning emitted when a supplier part footprint does not match the expected footprint\"),R4=k_.object({type:k_.literal(\"pcb_breakout_point\"),pcb_breakout_point_id:K1(\"pcb_breakout_point\"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:Y1,y:Y1}).describe(\"Defines a routing target within a pcb_group for a source_trace or source_net\"),E4=k_.object({type:k_.literal(\"pcb_ground_plane\"),pcb_ground_plane_id:K1(\"pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane on the PCB\"),A4=k_.object({type:k_.literal(\"pcb_ground_plane_region\"),pcb_ground_plane_region_id:K1(\"pcb_ground_plane_region\"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:u5,points:k_.array(Z1)}).describe(\"Defines a polygon region of a ground plane\"),O4=k_.object({type:k_.literal(\"pcb_thermal_spoke\"),pcb_thermal_spoke_id:K1(\"pcb_thermal_spoke\"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:Y1,spoke_inner_diameter:Y1,spoke_outer_diameter:Y1,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Pattern for connecting a ground plane to a plated hole\"),k4=k_.object({type:k_.literal(\"pcb_copper_pour\"),pcb_copper_pour_id:K1(\"pcb_copper_pour\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:u5,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),L4=k4.extend({shape:k_.literal(\"rect\"),center:Z1,width:j1,height:j1,rotation:G1.optional()}),D4=k4.extend({shape:k_.literal(\"brep\"),brep_shape:Q5}),z4=k4.extend({shape:k_.literal(\"polygon\"),points:k_.array(Z1)}),F4=k_.discriminatedUnion(\"shape\",[L4,D4,z4]).describe(\"Defines a copper pour on the PCB.\"),B4=f2.extend({type:k_.literal(\"pcb_component_outside_board_error\"),pcb_component_outside_board_error_id:K1(\"pcb_component_outside_board_error\"),error_type:k_.literal(\"pcb_component_outside_board_error\").default(\"pcb_component_outside_board_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Z1,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a PCB component is placed outside the board boundaries\"),j4=f2.extend({type:k_.literal(\"pcb_component_not_on_board_edge_error\"),pcb_component_not_on_board_edge_error_id:K1(\"pcb_component_not_on_board_edge_error\"),error_type:k_.literal(\"pcb_component_not_on_board_edge_error\").default(\"pcb_component_not_on_board_edge_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Z1,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component that must be placed on the board edge is centered away from the edge\"),$4=f2.extend({type:k_.literal(\"pcb_component_invalid_layer_error\"),pcb_component_invalid_layer_error_id:K1(\"pcb_component_invalid_layer_error\"),error_type:k_.literal(\"pcb_component_invalid_layer_error\").default(\"pcb_component_invalid_layer_error\"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:u5,subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)\"),Y4=f2.extend({type:k_.literal(\"pcb_via_clearance_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_via_clearance_error\").default(\"pcb_via_clearance_error\"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when vias are closer than the allowed clearance\"),X4=f2.extend({type:k_.literal(\"pcb_via_trace_clearance_error\"),pcb_via_trace_clearance_error_id:K1(\"pcb_via_trace_clearance_error\"),error_type:k_.literal(\"pcb_via_trace_clearance_error\").default(\"pcb_via_trace_clearance_error\"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a via and trace are closer than the allowed clearance\"),V4=f2.extend({type:k_.literal(\"pcb_pad_pad_clearance_error\"),pcb_pad_pad_clearance_error_id:K1(\"pcb_pad_pad_clearance_error\"),error_type:k_.literal(\"pcb_pad_pad_clearance_error\").default(\"pcb_pad_pad_clearance_error\"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when pads are closer than the allowed clearance\"),W4=f2.extend({type:k_.literal(\"pcb_pad_trace_clearance_error\"),pcb_pad_trace_clearance_error_id:K1(\"pcb_pad_trace_clearance_error\"),error_type:k_.literal(\"pcb_pad_trace_clearance_error\").default(\"pcb_pad_trace_clearance_error\"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pad and trace are closer than allowed clearance\"),H4=k_.object({type:k_.literal(\"pcb_courtyard_rect\"),pcb_courtyard_rect_id:K1(\"pcb_courtyard_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5,ccw_rotation:G1.optional(),color:k_.string().optional()}).describe(\"Defines a courtyard rectangle on the PCB\"),G4=k_.object({type:k_.literal(\"pcb_courtyard_outline\"),pcb_courtyard_outline_id:K1(\"pcb_courtyard_outline\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,outline:k_.array(Z1).min(2)}).describe(\"Defines a courtyard outline on the PCB\"),U4=k_.object({type:k_.literal(\"pcb_courtyard_polygon\"),pcb_courtyard_polygon_id:K1(\"pcb_courtyard_polygon\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,points:k_.array(Z1).min(3),color:k_.string().optional()}).describe(\"Defines a courtyard polygon on the PCB\"),Z4=k_.object({type:k_.literal(\"pcb_courtyard_circle\"),pcb_courtyard_circle_id:K1(\"pcb_courtyard_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:j1,layer:p5,color:k_.string().optional()}).describe(\"Defines a courtyard circle on the PCB\"),q4=k_.object({type:k_.literal(\"cad_component\"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:q1,rotation:q1.optional(),size:q1.optional(),layer:u5.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:t2.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum([\"x+\",\"x-\",\"y+\",\"y-\",\"z+\",\"z-\"]).optional().describe('The direction in the model\\'s coordinate space that is considered \"up\" or \"coming out of the board surface\"'),model_origin_position:q1.optional(),model_origin_alignment:k_.enum([\"unknown\",\"center\",\"center_of_component_on_board_surface\",\"bottom_center_of_component\"]).optional(),model_object_fit:k_.enum([\"contain_within_bounds\",\"fill_bounds\"]).optional().default(\"contain_within_bounds\"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),anchor_alignment:k_.enum([\"center\",\"center_of_component_on_board_surface\"]).optional().default(\"center\")}).describe(\"Defines a component on the PCB\"),J4=k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]),K4=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),Q4=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:K1(\"simulation_voltage_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:B1}).describe(\"Defines a DC voltage source for simulation\"),t6=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:K1(\"simulation_voltage_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:B1.optional(),frequency:$1.optional(),peak_to_peak_voltage:B1.optional(),wave_shape:J4.optional(),phase:G1.optional(),duty_cycle:K4.optional()}).describe(\"Defines an AC voltage source for simulation\"),e6=k_.union([Q4,t6]).describe(\"Defines a voltage source for simulation\"),n6=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),o6=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:K1(\"simulation_current_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:X1}).describe(\"Defines a DC current source for simulation\"),i6=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:K1(\"simulation_current_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:X1.optional(),frequency:$1.optional(),peak_to_peak_current:X1.optional(),wave_shape:J4.optional(),phase:G1.optional(),duty_cycle:n6.optional()}).describe(\"Defines an AC current source for simulation\"),r6=k_.union([o6,i6]).describe(\"Defines a current source for simulation\"),s6=k_.union([k_.literal(\"spice_dc_sweep\"),k_.literal(\"spice_dc_operating_point\"),k_.literal(\"spice_transient_analysis\"),k_.literal(\"spice_ac_analysis\")]),a6=k_.object({type:k_.literal(\"simulation_experiment\"),simulation_experiment_id:K1(\"simulation_experiment\"),name:k_.string(),experiment_type:s6,time_per_step:V1.optional(),start_time_ms:W1.optional(),end_time_ms:W1.optional()}).describe(\"Defines a simulation experiment configuration\"),c6=k_.object({type:k_.literal(\"simulation_transient_voltage_graph\"),simulation_transient_voltage_graph_id:K1(\"simulation_transient_voltage_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:V1,start_time_ms:W1,end_time_ms:W1,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores voltage measurements over time for a simulation\"),l6=k_.object({type:k_.literal(\"simulation_switch\"),simulation_switch_id:K1(\"simulation_switch\"),source_component_id:k_.string().optional(),closes_at:W1.optional(),opens_at:W1.optional(),starts_closed:k_.boolean().optional(),switching_frequency:$1.optional()}).describe(\"Defines a switch for simulation timing control\"),d6=k_.object({type:k_.literal(\"simulation_voltage_probe\"),simulation_voltage_probe_id:K1(\"simulation_voltage_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.\").superRefine((t,e)=\u003e{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n\u0026\u0026o?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a differential probe.\"}):n?t.signal_input_source_port_id\u0026\u0026t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id.\"}):o\u0026\u0026(t.signal_input_source_net_id\u0026\u0026t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id.\"}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id.\"})}),h6=f2.extend({type:k_.literal(\"simulation_unknown_experiment_error\"),simulation_unknown_experiment_error_id:K1(\"simulation_unknown_experiment_error\"),error_type:k_.literal(\"simulation_unknown_experiment_error\").default(\"simulation_unknown_experiment_error\"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"An unknown error occurred during the simulation experiment.\"),u6=k_.object({type:k_.literal(\"simulation_op_amp\"),simulation_op_amp_id:K1(\"simulation_op_amp\"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe(\"Defines a simple ideal operational amplifier for simulation\"),p6=(k_.union([r5,o5,i5,n5,a5,s5,P2,b2,v2,I2,x2,M2,R2,E2,L2,z2,F2,X2,B2,j2,$2,Y2,O2,A2,d5,m5,c5,V2,G2,U2,q2,J2,g5,f5,y5,_5,b5,t5,l5,o3,d3,v4,S4,I4,M4,w4,T4,y3,m4,_3,Y3,A3,D3,z3,X3,P3,E3,V3,W3,C4,U3,Z3,q3,J3,n4,K3,Q3,t4,e4,F3,B3,H3,G3,j3,$3,Y4,X4,V4,W4,i4,o4,r4,s4,a4,c4,l4,d4,h4,P4,u4,p4,R4,x4,E4,A4,O4,F4,B4,j4,$4,H4,G4,U4,Z4,x5,L5,T5,R5,E5,A5,M5,w5,D5,O5,v5,F5,B5,z5,V5,W5,H5,G5,q5,U5,Z5,q4,e6,r6,a6,c6,l6,d6,h6,u6]),[0,1,-1,2,-2,3,-3,4]),m6=(p6.flatMap(t=\u003ep6.map(e=\u003e[t,e])).sort(([t,e],[n,o])=\u003eMath.abs(t)+Math.abs(e)-Math.abs(n)-Math.abs(o)).length,[.2,.4,.8,1.2].flatMap(t=\u003e[.2,.3,.45,.6].flatMap(e=\u003e[-1,1].map(n=\u003e({halfSpan:t,offset:e,directionSign:n})))).flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,...t}))));[1,-1].flatMap(t=\u003e[1,-1].flatMap(e=\u003e[!1,!0].flatMap(n=\u003e[0,1].map(o=\u003e({routeSide:o,normalDirectionSign:t,tangentDirectionSign:e,reverseEndpointOffsets:n}))))),[0,1].map(t=\u003e({kind:\"displacementChain\",routeSide:t})),[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,halfSpan:.4,offset:1.2,directionSign:t}))),[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"span\",routeSide:e,spanExpansion:3,offset:1.8,directionSign:t}))),[{dx:-2.4,dy:-.4},{dx:-2.4,dy:.4},{dx:2.4,dy:-.4},{dx:2.4,dy:.4},{dx:-.4,dy:-2.4},{dx:-.4,dy:2.4},{dx:.4,dy:-2.4},{dx:.4,dy:2.4}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:2,...t}))),[{dx:-.17,dy:0},{dx:.17,dy:0},{dx:0,dy:-.17},{dx:0,dy:.17}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:0,...t})));var g6=1e-8,f6=(t,e,n=0)=\u003et.x\u003e=e.minX+n-g6\u0026\u0026t.x\u003c=e.maxX-n+g6\u0026\u0026t.y\u003e=e.minY+n-g6\u0026\u0026t.y\u003c=e.maxY-n+g6,y6=(t,e,n)=\u003e{let o=0,i=1;for(const[r,s,a,c]of[[t.x,e.x-t.x,n.minX,n.maxX],[t.y,e.y-t.y,n.minY,n.maxY]]){if(void 0===r||void 0===s||void 0===a||void 0===c)throw new Error(\"Invalid segment clipping axis\");if(Math.abs(s)\u003c=g6){if(r\u003ca-g6||r\u003ec+g6)return;continue}const t=(a-r)/s,e=(c-r)/s;if(o=Math.max(o,Math.min(t,e)),i=Math.min(i,Math.max(t,e)),i\u003co-g6)return}return[Math.max(0,o),Math.min(1,i)]},_6=(t,e,n)=\u003e{if(n\u003c=g6)return structuredClone(t);if(n\u003e=.99999999)return structuredClone(e);const o={...structuredClone(t),x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n};return delete o.pcb_port_id,o},b6=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=g6\u0026\u0026Math.abs(t.y-e.y)\u003c=g6\u0026\u0026t.z===e.z,x6=t=\u003eArray.isArray(t)?`[${t.map(x6).join(\",\")}]`:null!==t\u0026\u0026\"object\"==typeof t?`{${Object.keys(t).filter(e=\u003evoid 0!==t[e]).sort().map(e=\u003e`${JSON.stringify(e)}:${x6(t[e])}`).join(\",\")}}`:JSON.stringify(t)??\"undefined\",v6=(t,e,n)=\u003e{if(1===t.route.length)return structuredClone(t.route);const o=e=\u003e{const n=Math.min(Math.floor(e),t.route.length-2);return _6(t.route[n],t.route[n+1],e-n)},i=[o(e)];for(let o=Math.floor(e)+1;o\u003cn-g6;o+=1)i.push(structuredClone(t.route[o]));return n\u003ee+g6\u0026\u0026i.push(o(n)),i},S6=(t,e,n)=\u003e{const o=v6(t,e,n),i=Object.fromEntries(Object.entries(t).filter(([t])=\u003e\"route\"!==t\u0026\u0026\"vias\"!==t)),r=t.vias.filter(t=\u003eo.some(e=\u003eMath.hypot(e.x-t.x,e.y-t.y)\u003c=g6));return x6({metadata:i,points:o,vias:r})},I6=(t,e)=\u003e{const n=t.__zLayers;if(n)return new Set(n);if(t.zLayers)return new Set(t.zLayers);const o=new Set;for(const n of t.layers){const t=\"top\"===n?0:\"bottom\"===n?e-1:/^inner\\d+$/.test(n)?Number(n.slice(5)):-1;if(t\u003c0||t\u003e=e)throw new Error(`repair04 obstacle has an unknown layer: ${n}`);o.add(t)}return o},C6=({srj:t,routes:e,traceClearance:n=.1,viaClearance:o=.1})=\u003e{let i;const r=new Map,s=[];let a=!1;return c=\u003e{const l=i??=((t,e)=\u003e{const n=new Map,o=t=\u003e{const e=n.get(t);if(void 0===e)return n.set(t,t),t;if(e===t)return t;const i=o(e);return n.set(t,i),i},i=t=\u003e{const e=t.filter(t=\u003e\"string\"==typeof t\u0026\u0026t.length\u003e0);if(0===e.length)return;const i=o(e[0]);for(const t of e)n.set(o(t),i)};for(const e of t.connections){const t=e;i([t.name,t.rootConnectionName,t.netConnectionName,t.__netConnectionName,...t.mergedConnectionNames??[],...t.__rootConnectionNames??[],...t.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])])}for(const e of t.obstacles)i(e.connectedTo);for(const t of e)i([t.connectionName,t.rootConnectionName]);for(const t of n.keys())n.set(t,o(t));return n})(t,e),d=new Map,h=a?s:function*(e){for(let i=0;i\u003ct.obstacles.length;i++){if(r.has(i)){const t=r.get(i);t\u0026\u0026(yield t);continue}const a=t.obstacles[i],c=a.connectedTo.some(t=\u003e/^(pcb_smtpad_|pcb_plated_hole_|pcb_port_)/.test(t)),l=Math.abs((a.ccwRotationDegrees??0)%180)\u003e1e-8,d=\"rect\"===a.type\u0026\u0026a.layers.length\u003e1\u0026\u0026Math.abs(a.width-a.height)\u003c.001;if(c\u0026\u0026!l\u0026\u0026!d){r.set(i,null);continue}if(![a.center.x,a.center.y,a.width,a.height,a.ccwRotationDegrees??0].every(Number.isFinite)||a.width\u003c0||a.height\u003c0)throw new Error(\"repair04 fixed obstacle geometry must be finite and nonnegative\");const h=I6(a,t.layerCount),u=new Set(a.connectedTo.map(t=\u003ee.get(t)??t)),p={minX:-a.width/2,maxX:a.width/2,minY:-a.height/2,maxY:a.height/2},m=(a.ccwRotationDegrees??0)*Math.PI/180,g=Math.cos(m),f=Math.sin(m),y=Math.hypot(a.width,a.height)/2,_=t=\u003e{const e=t.x-a.center.x,n=t.y-a.center.y;return{x:e*g+n*f,y:-e*f+n*g}},b=(t,e,n)=\u003eMath.max(t.x,e.x)+n\u003ca.center.x-y||Math.min(t.x,e.x)-n\u003ea.center.x+y||Math.max(t.y,e.y)+n\u003ca.center.y-y||Math.min(t.y,e.y)-n\u003ea.center.y+y,x=!0===a.obstacleId?.startsWith(\"repair04_board_edge_\"),v=x?0:Math.max(n,t.defaultObstacleMargin??0,t.minTraceToPadEdgeClearance??0),S=x?0:Math.max(o,t.defaultObstacleMargin??0,t.minViaEdgeToPadEdgeClearance??0),I={obstacleIndex:i,obstacle:a,zLayers:h,obstacleNets:u,obstacleBounds:p,toLocal:_,separated:b,wireGap:v,viaGap:S};r.set(i,I),s.push(I),yield I}a=!0}(l);for(const{obstacleIndex:t,obstacle:e,zLayers:n,obstacleNets:o,obstacleBounds:i,toLocal:r,separated:s,wireGap:a,viaGap:u}of h)for(let h=0;h\u003cc.length;h+=1){const p=c[h];if(!(p.route.length\u003c2)\u0026\u0026![p.connectionName,p.rootConnectionName].some(t=\u003evoid 0!==t\u0026\u0026o.has(l.get(t)??t)))for(let o=1;o\u003cp.route.length;o+=1){const c=p.route[o-1],l=p.route[o];if(\"through_obstacle\"===c.toNextSegmentType)continue;if(c.z!==l.z){if(!Array.from(n).some(t=\u003et\u003e=Math.min(c.z,l.z)\u0026\u0026t\u003c=Math.max(c.z,l.z)))continue;if(Math.abs(c.x-l.x)\u003e1e-8||Math.abs(c.y-l.y)\u003e1e-8)throw new Error(\"repair04 found a non-colocated via transition: \"+JSON.stringify({route:p,from:c,to:l}));if(s(c,c,p.viaDiameter/2+u+1e-8))continue;const e=r(c),o=ke(e,e,i),a=p.viaDiameter/2+u-o;if(a\u003c=1e-8)continue;const m=`fixed-obstacle:${h}:${t}:via`;(d.get(m)?.severity??-1/0)\u003ca\u0026\u0026d.set(m,{key:m,center:{x:c.x,y:c.y},routeIndex:h,obstacleIndex:t,kind:\"via\",severity:a});continue}if(!n.has(c.z))continue;const m=Math.max(c.traceThickness??p.traceThickness,l.traceThickness??p.traceThickness)/2;if(s(c,l,m+a+1e-8))continue;const g=m+a-ke(r(c),r(l),i);if(g\u003c=1e-8)continue;const f=`fixed-obstacle:${h}:${t}:wire`;(d.get(f)?.severity??-1/0)\u003cg\u0026\u0026d.set(f,{key:f,center:ze(e.center,c,l),routeIndex:h,obstacleIndex:t,kind:\"wire\",severity:g})}}return Array.from(d.values())}},P6=t=\u003eC6(t)(t.routes),M6=(t,e)=\u003e{const n=[];for(let o=1;o\u003ct.route.length;o++){const i=t.route[o-1],r=t.route[o];if(i.z===r.z||\"through_obstacle\"===i.toNextSegmentType)continue;if(i.x!==r.x||i.y!==r.y||![i.x,i.y,i.z,r.z,t.viaDiameter].every(Number.isFinite)||!Number.isInteger(i.z)||!Number.isInteger(r.z)||Math.min(i.z,r.z)\u003c0||Math.max(i.z,r.z)\u003e=e||t.viaDiameter\u003c=0)throw new Error(\"repair04 new-via guard requires valid colocated vias\");const s=o-1,a=[i.z,r.z];let c=Math.min(i.z,r.z),l=Math.max(i.z,r.z);for(;o+1\u003ct.route.length\u0026\u0026\"through_obstacle\"!==t.route[o].toNextSegmentType;){const n=t.route[o+1];if(n.x!==r.x||n.y!==r.y)break;if(!Number.isInteger(n.z)||n.z\u003c0||n.z\u003e=e)throw new Error(\"repair04 new-via guard found an invalid layer span\");n.z!==a.at(-1)\u0026\u0026a.push(n.z),c=Math.min(c,n.z),l=Math.max(l,n.z),o++}n.push({pointIndices:Array.from({length:o-s+1},(t,e)=\u003es+e),layerSequence:a,x:r.x,y:r.y,minZ:c,maxZ:l,diameter:t.viaDiameter,identity:JSON.stringify([r.x,r.y,c,l,t.viaDiameter])})}return n},N6=({srj:t,viaClearance:e=.1})=\u003e{const n=new Map,o=new Map,i=[e,t.defaultObstacleMargin??0,t.minViaEdgeToPadEdgeClearance??0],r=Math.max(...i),s=e=\u003e{const i=o.get(e.identity);if(i)return i;const s=[];for(let o=0;o\u003ct.obstacles.length;o++){const i=t.obstacles[o];let a=n.get(o);if(!a){const e=i.__zLayers??i.zLayers??i.layers.map(e=\u003e\"top\"===e?0:\"bottom\"===e?t.layerCount-1:/^inner\\d+$/.test(e)?Number(e.slice(5)):-1);if(e.some(e=\u003e!Number.isInteger(e)||e\u003c0||e\u003e=t.layerCount))throw new Error(\"repair04 new-via guard found an unknown obstacle layer\");a={zs:e},n.set(o,a)}if(!a.zs.some(t=\u003et\u003e=e.minZ\u0026\u0026t\u003c=e.maxZ))continue;if(!a.geometry){if(![i.center.x,i.center.y,i.width,i.height,i.ccwRotationDegrees??0].every(Number.isFinite)||i.width\u003c0||i.height\u003c0)throw new Error(\"repair04 new-via guard found invalid obstacle geometry\");const t=(i.ccwRotationDegrees??0)*Math.PI/180;a.geometry={x:i.center.x,y:i.center.y,cosine:Math.cos(t),sine:Math.sin(t),extent:Math.hypot(i.width,i.height)/2,bounds:{minX:-i.width/2,maxX:i.width/2,minY:-i.height/2,maxY:i.height/2}}}const c=a.geometry,l=c.extent+e.diameter/2+r+1e-8;if(Math.abs(e.x-c.x)\u003el||Math.abs(e.y-c.y)\u003el)continue;const d=e.x-c.x,h=e.y-c.y,u={x:d*c.cosine+h*c.sine,y:-d*c.sine+h*c.cosine},p=ke(u,u,c.bounds),m=e.diameter/2+r-p;m\u003c=1e-8||s.push({obstacleIndex:o,severity:m})}return o.set(e.identity,s),s};return({previousRoutes:e,routes:n,includeExistingVias:o=[]})=\u003e{if(e.length!==n.length)throw new Error(\"repair04 new-via guard requires matching route ordering\");if(i.some(t=\u003e!Number.isFinite(t)||t\u003c0))throw new Error(\"repair04 new-via guard requires nonnegative finite margins\");const r=[];for(let i=0;i\u003cn.length;i++){const a=n[i],c=e[i],l=new Set(a.connectionName===c.connectionName\u0026\u0026a.rootConnectionName===c.rootConnectionName?M6(c,t.layerCount).map(t=\u003et.identity):[]),d=M6(a,t.layerCount);for(let t=0;t\u003cd.length;t++){const e=d[t];if(!l.has(e.identity)||o.some(e=\u003ee.routeIndex===i\u0026\u0026e.viaIndex===t))for(const n of s(e))r.push({key:`new-via-pad:${i}:${n.obstacleIndex}:${t}`,routeIndex:i,obstacleIndex:n.obstacleIndex,center:{x:e.x,y:e.y},kind:\"via\",severity:n.severity})}}return r}},w6=t=\u003eN6(t)(t);function T6(t,e){return t.x\u003ee.minX+4e-8\u0026\u0026t.x\u003ce.maxX-4e-8\u0026\u0026t.y\u003ee.minY+4e-8\u0026\u0026t.y\u003ce.maxY-4e-8}function R6(t){const e=[];for(let n=1;n\u003ct.route.length;n++){const o=t.route[n-1],i=t.route[n];if(o.z!==i.z\u0026\u0026\"through_obstacle\"!==o.toNextSegmentType){if(o.x!==i.x||o.y!==i.y)throw new Error(\"repair04: a layer transition must have coincident endpoints\");e.some(t=\u003et.x===i.x\u0026\u0026t.y===i.y)||e.push({x:i.x,y:i.y})}}return{...t,vias:e}}function E6(t){const e=[];for(let n=1;n\u003ct.route.length;n++){const o=t.route[n-1],i=t.route[n];o.z!==i.z\u0026\u0026\"through_obstacle\"!==o.toNextSegmentType\u0026\u0026e.push([o.x,o.y,o.z,i.z])}return JSON.stringify([t.viaDiameter,e])}var A6=class extends kt{input;mutableBounds;engine;fixedTraces;routes;score=null;candidates=null;bestAdjustment=null;lockedPoints;evaluated=0;accepted=0;maxCandidates;candidateAttempts=0;pathSearchNodes=0;pathSearchCalls=0;viaBlockerPathSearchCalls=0;coupledPathSearchCalls=0;threeRoutePathSearchCalls=0;threeRoutePathSearchNodes=0;candidateScores=new Map;routeCache=new WeakMap;fixedObstacleNetContext;fixedObstacleEvaluator;viaPadEvaluator;viaGeometryCache=new WeakMap;constructor(t){if(super(),!Number.isFinite(t.boundaryMargin)||t.boundaryMargin\u003c=0)throw new Error(\"repair04: boundaryMargin must be positive and finite\");const e=t.bounds;if(![e.minX,e.maxX,e.minY,e.maxY].every(Number.isFinite)||e.maxX-e.minX\u003c10-1e-8||e.maxY-e.minY\u003c10-1e-8)throw new Error(\"repair04: bounds must be finite and at least 10 × 10 mm\");if(this.input=structuredClone(t),this.viaPadEvaluator=(({srj:t,viaClearance:e})=\u003eN6({srj:{layerCount:t.layerCount,obstacles:structuredClone(t.obstacles),defaultObstacleMargin:t.defaultObstacleMargin,minViaEdgeToPadEdgeClearance:t.minViaEdgeToPadEdgeClearance},viaClearance:e}))({srj:this.input.srj,viaClearance:this.input.viaClearance}),this.routes=structuredClone(t.routes),this.fixedObstacleNetContext=this.input.routes.map(t=\u003e({...t,route:[]})),this.fixedObstacleEvaluator=(t=\u003eC6({...t,srj:structuredClone(t.srj),routes:t.routes.map(t=\u003e({...t,route:[]}))}))({srj:this.input.srj,routes:this.fixedObstacleNetContext,traceClearance:this.input.traceClearance,viaClearance:this.input.viaClearance}),this.fixedTraces=(t.srj.traces??[]).map(e=\u003em1(e,t.srj.minTraceWidth)),this.mutableBounds={minX:e.minX+t.boundaryMargin,minY:e.minY+t.boundaryMargin,maxX:e.maxX-t.boundaryMargin,maxY:e.maxY-t.boundaryMargin},this.mutableBounds.minX\u003e=this.mutableBounds.maxX||this.mutableBounds.minY\u003e=this.mutableBounds.maxY)throw new Error(\"repair04: boundary collar leaves no mutable area\");if(t.lockedPointIndices.length!==t.routes.length)throw new Error(\"repair04: every route requires a lock mask\");this.lockedPoints=this.routes.map((e,n)=\u003e{if(t.lockedPointIndices[n].length!==e.route.length)throw new Error(\"repair04: lock mask length must match its route\");for(let t=1;t\u003ce.route.length;t++){const n=y6(e.route[t-1],e.route[t],this.mutableBounds);if(n?.some(t=\u003et\u003e1e-8\u0026\u0026t\u003c1-1e-8))throw new Error(\"repair04: boundary crossings require fixed cut points; use extractRepairRegion\")}return e.route.filter((o,i)=\u003et.lockedPointIndices[n][i]||0===i||i===e.route.length-1||o.pcb_port_id||o.insideJumperPad||o.toNextSegmentType||!T6(o,this.mutableBounds))});for(const e of t.movableVias??[]){const n=this.routes[e.routeIndex],o=n\u0026\u0026M6(n,t.srj.layerCount)[e.viaIndex];if(!o||o.pointIndices.some(t=\u003ethis.isLocked(e.routeIndex,n.route[t])))throw new Error(\"repair04: movable via must identify an unlocked existing via\")}for(const e of[\"maxCandidateAttempts\",\"maxPathSearchNodes\"]){const n=t[e];if(void 0!==n\u0026\u0026(!Number.isSafeInteger(n)||n\u003c1))throw new Error(`repair04: ${e} must be a positive safe integer`)}if(this.maxCandidates=t.maxCandidates??8e3,!Number.isInteger(this.maxCandidates)||this.maxCandidates\u003c1)throw new Error(\"repair04: maxCandidates must be a positive integer\");this.MAX_ITERATIONS=2*this.maxCandidates+4,this.engine=new R1(this.input.srj,{cacheStaticObstacleNetMembership:!0,cacheImmutableTraceGeometry:!0,useTransientDynamicQueryMarkers:!0,useConservativeRectObstaclePrecheck:!0,traceClearance:t.traceClearance??.1,viaClearance:t.viaClearance??.1,includeTraceViaOwnerMetadata:!0})}getWorkLimitReason(){return void 0!==this.input.maxCandidateAttempts\u0026\u0026this.candidateAttempts\u003e=this.input.maxCandidateAttempts?\"candidate-attempt-limit\":void 0!==this.input.maxPathSearchNodes\u0026\u0026this.pathSearchNodes\u003e=this.input.maxPathSearchNodes?\"path-search-node-limit\":null}updateWorkStats(t){void 0===this.input.maxCandidateAttempts\u0026\u0026void 0===this.input.maxPathSearchNodes||(this.stats={...this.stats,candidateAttempts:this.candidateAttempts,pathSearchNodes:this.pathSearchNodes,pathSearchCalls:this.pathSearchCalls,...void 0===t?{}:{completionReason:t}})}finishSearch(t){this.bestAdjustment\u0026\u0026(this.routes=this.bestAdjustment.routes,this.candidateScores.clear(),this.score=this.bestAdjustment.score,this.accepted++,this.bestAdjustment=null,this.stats={...this.stats,finalErrorCount:this.score.count,accepted:this.accepted}),this.updateWorkStats(t),this.solved=!0}getRouteCache(t,e){let n=this.routeCache.get(e);n||(n=new Map,this.routeCache.set(e,n));let o=n.get(t);return o||(o={},n.set(t,o)),o}getViaGeometry(t){let e=this.viaGeometryCache.get(t);return e||(e=M6(t,this.input.srj.layerCount),this.viaGeometryCache.set(t,e)),e}getViaPadViolations(t,e){return 0===t.length?this.viaPadEvaluator({previousRoutes:[],routes:[]}):t.flatMap((t,n)=\u003e{const o=this.getRouteCache(n,t),i=e?\"scoredViaViolations\":\"newViaViolations\";if(!o[i]){const r=e?!0!==this.input.allowLayerChanges||this.input.movableVias?.length?(this.input.movableVias??[]).filter(t=\u003et.routeIndex===n).map(t=\u003e({routeIndex:0,viaIndex:t.viaIndex})):this.getViaGeometry(t).flatMap((e,o)=\u003ee.pointIndices.every(e=\u003e!this.isLocked(n,t.route[e]))?[{routeIndex:0,viaIndex:o}]:[]):[];o[i]=this.viaPadEvaluator({previousRoutes:[e?t:this.input.routes[n]],routes:[t],includeExistingVias:r}).map(t=\u003e({...t,routeIndex:n,key:t.key.replace(\"new-via-pad:0:\",`new-via-pad:${n}:`)}))}return o[i]})}getFixedViolations(t){if(0===t.length)return this.fixedObstacleEvaluator(t);const e=t.flatMap((t,e)=\u003evoid 0===this.getRouteCache(e,t).fixedViolations?[e]:[]);if(e.length){const n=this.fixedObstacleNetContext.slice();for(const o of e)n[o]=t[o];const o=this.fixedObstacleEvaluator(n);for(const n of e)this.getRouteCache(n,t[n]).fixedViolations=[];for(const e of o)this.getRouteCache(e.routeIndex,t[e.routeIndex]).fixedViolations.push(e)}return t.flatMap((t,e)=\u003ethis.getRouteCache(e,t).fixedViolations).sort((t,e)=\u003et.obstacleIndex-e.obstacleIndex||t.routeIndex-e.routeIndex)}evaluate(t){const{errors:e}=this.engine.evaluate([...this.fixedTraces,...t.map((t,e)=\u003e{const n=this.getRouteCache(e,t);return n.trace||(n.trace=function(t,e){const n=t=\u003e0===t?\"top\":t===e-1?\"bottom\":`inner${t}`;return t.map((t,e)=\u003e{const o=[];for(let e=0;e\u003ct.route.length;e++){const i=t.route[e],r=t.route[e-1];r\u0026\u0026\"through_obstacle\"!==r.toNextSegmentType\u0026\u0026r.z!==i.z\u0026\u0026r.x===i.x\u0026\u0026r.y===i.y\u0026\u0026o.push({route_type:\"via\",x:i.x,y:i.y,from_layer:n(r.z),to_layer:n(i.z),via_diameter:t.viaDiameter});const s=i.traceThickness??t.traceThickness;o.push({route_type:\"wire\",x:i.x,y:i.y,layer:n(i.z),width:s,...0===e\u0026\u0026i.pcb_port_id?{start_pcb_port_id:i.pcb_port_id}:{},...e===t.route.length-1\u0026\u0026i.pcb_port_id?{end_pcb_port_id:i.pcb_port_id}:{}})}return{type:\"pcb_trace\",pcb_trace_id:`repair04_${e}`,connection_name:t.rootConnectionName??t.connectionName,route:o}})}([t],this.input.srj.layerCount)[0],n.trace.pcb_trace_id=`repair04_${e}`),n.trace})]),n=new Map;for(const o of this.getFixedViolations(t))n.set(o.key,o.severity),e.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:`repair04 fixed obstacle clearance: ${o.key}`,center:o.center,minimum_clearance:o.severity,actual_clearance:0,pcb_trace_id:`repair04_${o.routeIndex}`,pcb_trace_error_id:o.key});for(const n of this.getViaPadViolations(t,!0))e.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:`repair04 selected existing via pad clearance: ${n.key}`,center:n.center,minimum_clearance:n.severity,actual_clearance:0,pcb_trace_id:`repair04_${n.routeIndex}`,pcb_trace_error_id:n.key});let o=0;for(const t of e){const e=/gap: (-?[\\d.]+)/.exec(t.message),n=\"number\"==typeof t.actual_clearance?t.actual_clearance:e?Number(e[1]):null,i=\"number\"==typeof t.minimum_clearance?t.minimum_clearance:.1;o+=null!==n?Math.max(0,i-n):1}return{count:e.length,severity:o,errors:e,fixedViolations:n}}isLocked(t,e){return!T6(e,this.mutableBounds)||this.lockedPoints[t].some(t=\u003et.x===e.x\u0026\u0026t.y===e.y)}*generateTaperedSegmentCandidates(t){const e=new Set;for(const{ri:n,pi:o}of t){if(!this.score.errors.some(t=\u003et.pcb_trace_id===`repair04_${n}`))continue;const t=this.routes[n];for(const[i,r]of[[o-2,o+1],[o-2,o],[o-1,o+1],[o-1,o]]){if(e.size\u003e=8)return;if(i\u003c=0||r\u003e=t.route.length-1)continue;const o=`${n}:${i}:${r}`;if(e.has(o))continue;const s=t.route.slice(i,r+1),a=s[0].z;if(!T6(t.route[i-1],this.mutableBounds)||!T6(t.route[r+1],this.mutableBounds)||t.route[i-1].z!==a||t.route[r+1].z!==a||s.some(e=\u003ee.z!==a||this.isLocked(n,e)||Boolean(e.portPointId)||t.vias.some(t=\u003et.x===e.x\u0026\u0026t.y===e.y)))continue;if(!(new Set(s.map(e=\u003ee.traceThickness??t.traceThickness)).size\u003c2)){e.add(o);for(const e of[.1,.05])for(let o=0;o\u003c8;o++){const a=e*Math.cos(o*Math.PI/4),c=e*Math.sin(o*Math.PI/4),l=s.map(t=\u003e({...t,x:t.x+a,y:t.y+c}));l.some(t=\u003e!T6(t,this.mutableBounds))||(yield{routeIndex:n,route:{...t,route:[...t.route.slice(0,i),...l,...t.route.slice(r+1)]}})}}}}}*generateCrossingPairCandidates(){if(this.coupledPathSearchCalls\u003e=4||this.getWorkLimitReason())return;const t=new Set,e=this.score.errors.filter(t=\u003e\"pcb_trace_error\"===t.type\u0026\u0026\"number\"==typeof t.actual_clearance\u0026\u0026t.actual_clearance\u003c0\u0026\u0026void 0!==t.center);for(const n of e){const e=n.center,o=[];for(let t=0;t\u003cthis.routes.length;t++){const n=this.routes[t];if(!n.jumpers?.length)for(let i=1;i\u003cn.route.length;i++){const r=n.route[i-1],s=n.route[i],a=s.x-r.x,c=s.y-r.y,l=a*a+c*c;if(r.z!==s.z||l\u003c1e-12)continue;const d=((e.x-r.x)*a+(e.y-r.y)*c)/l;d\u003c0||d\u003e1||Math.hypot(e.x-r.x-d*a,e.y-r.y-d*c)\u003c1e-6\u0026\u0026o.push({ri:t,pi:i,a:r,b:s})}}for(let e=0;e\u003co.length;e++)for(let i=e+1;i\u003co.length;i++){let r=o[e],s=o[i];if(r.ri===s.ri||r.a.z!==s.a.z)continue;const a=n.pcb_trace_error_id;if(a!==`overlap_repair04_${r.ri}_repair04_${s.ri}`\u0026\u0026a!==`overlap_repair04_${s.ri}_repair04_${r.ri}`)continue;0===this.routes[r.ri].vias.length\u0026\u0026([r,s]=[s,r]);const c=this.routes[r.ri],l=this.routes[s.ri];if(0===c.vias.length||0!==l.vias.length)continue;const d=`${r.ri}:${s.ri}`;if(t.has(d))continue;t.add(d);let h=s.pi-1,u=s.pi;for(;h\u003e0\u0026\u0026!this.isLocked(s.ri,l.route[h]);)h--;for(;u\u003cl.route.length-1\u0026\u0026!this.isLocked(s.ri,l.route[u]);)u++;if(u-h\u003e64||u-h\u003c2||!T6(l.route[h],this.mutableBounds)||!T6(l.route[u],this.mutableBounds))continue;const p=l.route[h].traceThickness??l.traceThickness;if(l.route.slice(h,u+1).some(t=\u003et.z!==s.a.z||t.toNextSegmentType||t.insideJumperPad||(t.traceThickness??l.traceThickness)!==p))continue;const m=this.getViaGeometry(c),g=m.map((t,e)=\u003e({via:t,viaIndex:e,distance:Math.min(...t.pointIndices.map(t=\u003eMath.abs(t-r.pi)))})).sort((t,e)=\u003et.distance-e.distance)[0];if(!g||g.via.pointIndices.some(t=\u003ethis.isLocked(r.ri,c.route[t]))||this.input.movableVias?.length\u0026\u0026!this.input.movableVias.some(t=\u003et.routeIndex===r.ri\u0026\u0026t.viaIndex===g.viaIndex))continue;const f=Math.max(...g.via.pointIndices);let y=r.pi-1;for(;y\u003e0\u0026\u0026!this.isLocked(r.ri,c.route[y]);)y--;if(y\u003e=Math.min(...g.via.pointIndices))continue;const _=s.b.x-s.a.x,b=s.b.y-s.a.y,x=Math.abs(b)\u003e=Math.abs(_)?{x:1,y:0}:{x:0,y:1},v=2*(this.input.traceClearance??.1)+p;for(const t of[-1,1])for(const e of[2,1]){if(this.coupledPathSearchCalls\u003e=4||this.getWorkLimitReason())return;const n=f+e;if(n\u003e=c.route.length)continue;if(c.route.slice(y+1,n).some(t=\u003ethis.isLocked(r.ri,t)))continue;if(!T6(c.route[y],this.mutableBounds)||!T6(c.route[n],this.mutableBounds))continue;const o=c.route[y].traceThickness??c.traceThickness;if(c.route.slice(y,n+1).some(t=\u003et.toNextSegmentType||t.insideJumperPad||(t.traceThickness??c.traceThickness)!==o))continue;const i={...l,route:l.route.map((e,n)=\u003en\u003eh\u0026\u0026n\u003cu?{...e,x:e.x+t*x.x*v,y:e.y+t*x.y*v}:e)};if(i.route.some((t,e)=\u003ee\u003eh\u0026\u0026e\u003cu\u0026\u0026!T6(t,this.mutableBounds)))continue;const a=this.routes.slice();a[s.ri]=i;const d={nodesPopped:0,completionReason:\"no-path\"},p=Math.min(3e4,void 0===this.input.maxPathSearchNodes?3e4:this.input.maxPathSearchNodes-this.pathSearchNodes);if(p\u003c1)return;const g=g1({srj:this.input.srj,routes:a,routeIndex:r.ri,start:c.route[y],end:c.route[n],bounds:this.mutableBounds,traceThickness:o,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,gridSize:o\u003c=.1?o/2:.1,allowLayerChanges:!0,maxNodes:p,stats:d});if(this.coupledPathSearchCalls++,this.pathSearchCalls++,this.pathSearchNodes+=d.nodesPopped,this.updateWorkStats(),!g)continue;const _=R6({...c,route:[...c.route.slice(0,y),...g,...c.route.slice(n+1)]}),b=this.getViaGeometry(_);b.length!==m.length||b.some((t,e)=\u003et.diameter!==m[e].diameter||JSON.stringify(t.layerSequence)!==JSON.stringify(m[e].layerSequence))||(yield{routeIndex:r.ri,route:_,additionalRoutes:[{routeIndex:s.ri,route:i}]})}}}}*generateClearanceCandidates(t,e){const n=new Set;for(const{ri:o,pi:i}of t){if(n.size\u003e=12)break;const t=this.routes[o],r=n=\u003e{const i=t.route[n];return this.isLocked(o,i)||!e\u0026\u0026(n\u003e0\u0026\u0026t.route[n-1].z!==i.z||n+1\u003ct.route.length\u0026\u0026t.route[n+1].z!==i.z)};let s=i-1,a=i;for(;s\u003e0\u0026\u0026!r(s);)s--;for(;a\u003ct.route.length-1\u0026\u0026!r(a);)a++;const c=`${o}:${s}:${a}`;if(n.has(c))continue;n.add(c);const l=t.route[s],d=t.route[a];if(l.x===d.x\u0026\u0026l.y===d.y)continue;const h=t=\u003et.x\u003e=this.mutableBounds.minX-g6\u0026\u0026t.x\u003c=this.mutableBounds.maxX+g6\u0026\u0026t.y\u003e=this.mutableBounds.minY-g6\u0026\u0026t.y\u003c=this.mutableBounds.maxY+g6;if(!h(l)||!h(d))continue;const u=new Set(t.route.slice(s,a+1).map(e=\u003ee.traceThickness??t.traceThickness));if(1!==u.size)continue;const p=[...u][0];if(\"path-search-node-limit\"===this.getWorkLimitReason())return;const m={nodesPopped:0,completionReason:\"no-path\"},g=g1({maxNodes:void 0===this.input.maxPathSearchNodes?void 0:Math.min(3e4,this.input.maxPathSearchNodes-this.pathSearchNodes),stats:m,allowLayerChanges:e,srj:this.input.srj,routes:this.routes,routeIndex:o,start:l,end:d,bounds:this.mutableBounds,traceThickness:p,gridSize:p\u003c=.1?p/2:.1,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1});this.pathSearchCalls++,this.pathSearchNodes+=m.nodesPopped,this.updateWorkStats(),g\u0026\u0026(yield{routeIndex:o,route:R6({...t,route:[...t.route.slice(0,s),...g,...t.route.slice(a+1)]})})}}preservesViaPermissions(t,e){const n=this.input.routes[t],o=this.getViaGeometry(n),i=this.getViaGeometry(e);return e.connectionName===n.connectionName\u0026\u0026e.rootConnectionName===n.rootConnectionName\u0026\u0026e.viaDiameter===n.viaDiameter\u0026\u0026o.length===i.length\u0026\u0026o.every((e,n)=\u003e{const o=i[n];if(JSON.stringify(e.layerSequence)!==JSON.stringify(o.layerSequence)||e.diameter!==o.diameter)return!1;const r=this.input.movableVias?.some(e=\u003ee.routeIndex===t\u0026\u0026e.viaIndex===n);return!0===r||e.x===o.x\u0026\u0026e.y===o.y})}getIndexedViaIds(t,e,n){const o=new Set;if(1!==this.getViaGeometry(e).filter(t=\u003et.x===n.x\u0026\u0026t.y===n.y\u0026\u0026t.identity===n.identity).length)return o;const i=t=\u003e0===t?\"top\":t===this.input.srj.layerCount-1?\"bottom\":`inner${t}`,r=new Set;for(let t=1;t\u003cn.layerSequence.length;t++)r.add(`${n.x},${n.y},${i(n.layerSequence[t-1])},${i(n.layerSequence[t])}`);const s=this.routes.map((n,o)=\u003e{const i=this.getRouteCache(o,o===t?e:n).trace;if(!i)throw new Error(\"repair04: indexed via mapping requires an evaluated route\");return i}),a=new Set;for(const e of[...this.fixedTraces,...s])for(const n of e.route){if(\"via\"!==n.route_type)continue;const i=`${n.x},${n.y},${n.from_layer},${n.to_layer}`;if(a.has(i))continue;const c=`via_${a.size}`;a.add(i),e===s[t]\u0026\u0026r.has(i)\u0026\u0026o.add(c)}return o.size===r.size?o:new Set}*generateViaBlockerCandidates(t,e,n={}){if(this.viaBlockerPathSearchCalls\u003e=4||this.getWorkLimitReason())return;const o=e.evaluatedScore;if(!o||!this.score||e.additionalRoutes?.length||e.routeIndex!==t.routeIndex)return;if(!this.input.movableVias?.some(e=\u003ee.routeIndex===t.routeIndex\u0026\u0026e.viaIndex===t.viaIndex)||!this.preservesViaPermissions(t.routeIndex,e.route))return;if([...o.fixedViolations].some(([t,e])=\u003e!this.score.fixedViolations.has(t)||e\u003ethis.score.fixedViolations.get(t)+g6))return;const i=this.routes[t.routeIndex],r=this.getViaGeometry(i)[t.viaIndex],s=this.getViaGeometry(e.route)[t.viaIndex],a=n.oldIds??=this.getIndexedViaIds(t.routeIndex,i,r);if(!a.size)return;const c=`repair04_${t.routeIndex}`,l=(t,e)=\u003e{const n=t.pcb_via_id,o=t.pcb_trace_id;if(\"pcb_trace_error\"===t.type\u0026\u0026\"string\"==typeof n\u0026\u0026e.has(n)\u0026\u0026\"string\"==typeof o\u0026\u0026o!==c\u0026\u0026t.pcb_trace_error_id===`overlap_${o}_${n}`\u0026\u0026Array.isArray(t.pcb_trace_ids)\u0026\u00262===t.pcb_trace_ids.length\u0026\u0026t.pcb_trace_ids.includes(c)\u0026\u0026t.pcb_trace_ids.includes(o))return o},d=(t,e)=\u003e{const n=new Set;for(const o of t){const t=l(o,e);void 0!==t\u0026\u0026n.add(t)}return n},h=n.oldContacts??=d(this.score.errors,a);if(!h.size)return;if(n.oldNeighborFixed??=this.getFixedViolations(this.routes).some(t=\u003e\"wire\"===t.kind\u0026\u0026h.has(`repair04_${t.routeIndex}`)))return;const u=this.getIndexedViaIds(t.routeIndex,e.route,s);if(a.size!==u.size)return;for(const t of o.errors){if([t.pcb_via_id,...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids:[],...Array.isArray(t.pcb_pad_ids)?t.pcb_pad_ids:[]].some(t=\u003e\"string\"==typeof t\u0026\u0026u.has(t))\u0026\u0026void 0===l(t,u))return}const p=d(o.errors,u);if(1!==p.size||[...p].some(t=\u003eh.has(t)))return;const m=[...p][0];if(!/^repair04_(0|[1-9][0-9]*)$/.test(m))return;const g=Number(m.slice(9)),f=this.routes[g];if(!f||g===t.routeIndex||f.jumpers?.length||f.connectionName===i.connectionName||f.rootConnectionName\u0026\u0026f.rootConnectionName===i.rootConnectionName||f.route.some(t=\u003eBoolean(t.toNextSegmentType||t.insideJumperPad)))return;let y=-1,_=1/0;for(let t=1;t\u003cf.route.length;t++){const e=f.route[t-1],n=f.route[t];if(e.z!==n.z||e.z\u003cs.minZ||e.z\u003es.maxZ)continue;const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,a=r?Math.max(0,Math.min(1,((s.x-e.x)*o+(s.y-e.y)*i)/r)):0,c=Math.hypot(s.x-e.x-a*o,s.y-e.y-a*i);c\u003c_\u0026\u0026(_=c,y=t)}if(y\u003c1)return;const b=t=\u003e{const e=f.route[t];return this.isLocked(g,e)||t\u003e0\u0026\u0026f.route[t-1].z!==e.z||t+1\u003cf.route.length\u0026\u0026f.route[t+1].z!==e.z};let x=y-1,v=y;for(;x\u003e0\u0026\u0026!b(x);)x--;for(;v\u003cf.route.length-1\u0026\u0026!b(v);)v++;const S=f.route[x],I=f.route[v],C=t=\u003et.x\u003e=this.mutableBounds.minX-g6\u0026\u0026t.x\u003c=this.mutableBounds.maxX+g6\u0026\u0026t.y\u003e=this.mutableBounds.minY-g6\u0026\u0026t.y\u003c=this.mutableBounds.maxY+g6;if(S.z!==I.z||!C(S)||!C(I))return;const P=S.traceThickness??f.traceThickness;if(f.route.slice(x,v+1).some(t=\u003e(t.traceThickness??f.traceThickness)!==P))return;const M=Math.min(3e4,void 0===this.input.maxPathSearchNodes?3e4:this.input.maxPathSearchNodes-this.pathSearchNodes);if(M\u003c1)return;const N=this.routes.slice();N[t.routeIndex]=e.route;const w={nodesPopped:0,completionReason:\"no-path\"},T=g1({srj:this.input.srj,routes:N,routeIndex:g,start:I,end:S,bounds:this.mutableBounds,traceThickness:P,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,gridSize:Math.max(.025,P/4),allowLayerChanges:!1,maxNodes:M,stats:w});if(this.viaBlockerPathSearchCalls++,this.pathSearchCalls++,this.pathSearchNodes+=w.nodesPopped,this.updateWorkStats(),!T)return;T.reverse();const R={...f,route:[...f.route.slice(0,x),...T,...f.route.slice(v+1)]};E6(R)===E6(f)\u0026\u0026(yield{routeIndex:e.routeIndex,route:e.route,additionalRoutes:[{routeIndex:g,route:R}]})}*generateExistingViaCandidates(){for(const t of this.input.movableVias??[]){const e=this.routes[t.routeIndex],n=this.getViaGeometry(e)[t.viaIndex];if(n.pointIndices.some(n=\u003ethis.isLocked(t.routeIndex,e.route[n])))continue;const o={};for(const i of[.025,.05,.1,.2,.35,.5,.8,1.2])for(let r=0;r\u003c16;r++){const s=n.x+i*Math.cos(r*Math.PI/8),a=n.y+i*Math.sin(r*Math.PI/8);if(!T6({x:s,y:a,z:n.minZ},this.mutableBounds))continue;const c=e.route.map((t,e)=\u003en.pointIndices.includes(e)?{...t,x:s,y:a}:t),l={routeIndex:t.routeIndex,route:R6({...e,route:c})};yield l,yield*this.generateViaBlockerCandidates(t,l,o)}}}*generateCandidates(){yield*this.generateExistingViaCandidates();for(const t of!0===this.input.allowLayerChanges?!1===this.input.traceOnlyFirst?[!0]:[!1,!0]:[!1]){if(\"path-search-node-limit\"===this.getWorkLimitReason())return;const e=!0===this.input.allowLayerChanges?Math.min(512,Math.floor(this.maxCandidates/4)):Number.MAX_SAFE_INTEGER;if(!t\u0026\u00260===e)continue;let n=0;for(const o of this.generateCandidatesForMode(t)){if(!t){if([o,...o.additionalRoutes??[]].some(({routeIndex:t,route:e})=\u003ethis.input.movableVias?.length?!this.preservesViaPermissions(t,e):E6(e)!==E6(this.routes[t])))continue;if(n++\u003e=e)break}yield o}}}*generateCandidatesForMode(t){const e=this.score.errors.flatMap(t=\u003e{const e=t.center??t.pcb_center;return e?[e]:[]}),n=[];for(let t=0;t\u003cthis.routes.length;t++){const o=this.routes[t];if(!o.jumpers?.length\u0026\u0026!o.route.some(t=\u003et.toNextSegmentType||t.insideJumperPad))for(let i=1;i\u003co.route.length;i++){const r=o.route[i-1],s=o.route[i];if(r.toNextSegmentType||r.insideJumperPad||s.insideJumperPad)continue;let a=1/0,c=.5;const l=s.x-r.x,d=s.y-r.y,h=l*l+d*d;for(const t of e){const e=h?Math.max(0,Math.min(1,((t.x-r.x)*l+(t.y-r.y)*d)/h)):0,n=Math.hypot(t.x-r.x-e*l,t.y-r.y-e*d);n\u003ca\u0026\u0026(a=n,c=e)}a\u003c1.5\u0026\u0026n.push({ri:t,pi:i,distance:a,t:c})}}if(n.sort((t,e)=\u003et.distance-e.distance||t.ri-e.ri||t.pi-e.pi),this.threeRoutePathSearchCalls\u003c18\u0026\u0026!this.getWorkLimitReason()){const t=function*(t){const{routes:e}=t,n=t.violations.filter(t=\u003e\"wire\"===t.kind).sort((t,e)=\u003ee.severity-t.severity||t.routeIndex-e.routeIndex||t.obstacleIndex-e.obstacleIndex);if(!n.length||t.maxSearchCalls\u003c=0||t.remainingNodes()\u003c=0)return;const o=[];let i=0;const r=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r?Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r)):0;return Math.hypot(t.x-e.x-s*o,t.y-e.y-s*i)},s=(t,e)=\u003e{const n=t.route[e],o=t.route[e-1],i=t.route[e+1];return void 0!==o\u0026\u0026o.z!==n.z||void 0!==i\u0026\u0026i.z!==n.z},a=e=\u003e{const n=t.bounds;return e.x\u003e=n.minX-1e-8\u0026\u0026e.x\u003c=n.maxX+1e-8\u0026\u0026e.y\u003e=n.minY-1e-8\u0026\u0026e.y\u003c=n.maxY+1e-8};for(let n=0;n\u003ce.length;n++){const i=e[n];if(i.jumpers?.length||i.route.some(t=\u003eBoolean(t.toNextSegmentType||t.insideJumperPad)))continue;const r=e=\u003et.isLocked(n,e)||s(i,e);for(let t=0;t\u003ci.route.length-1;){let e=t+1;if(i.route[t].z!==i.route[e].z){t=e;continue}for(;e\u003ci.route.length-1\u0026\u0026!r(e)\u0026\u0026i.route[e+1].z===i.route[t].z;)e++;const c=i.route[t].traceThickness??i.traceThickness;e\u003et\u0026\u0026a(i.route[t])\u0026\u0026a(i.route[e])\u0026\u0026i.route.slice(t,e+1).every(t=\u003e(t.traceThickness??i.traceThickness)===c)\u0026\u0026o.push({ri:n,a:t,b:e,z:i.route[t].z,width:c,distance:1/0,viaEnds:Number(s(i,t))+Number(s(i,e))}),t=e}}const c=new Set;for(const s of n){for(const t of o){t.distance=1/0;const n=e[t.ri];for(let e=t.a+1;e\u003c=t.b;e++)t.distance=Math.min(t.distance,r(s.center,n.route[e-1],n.route[e]))}const n=o.filter(t=\u003et.ri===s.routeIndex).sort((t,e)=\u003et.distance-e.distance||t.a-e.a)[0];if(!n||n.distance\u003e.5)continue;const a=e[n.ri],l=o.filter(t=\u003et.ri!==n.ri\u0026\u0026t.z===n.z\u0026\u0026t.distance\u003c1.5\u0026\u0026e[t.ri].connectionName!==a.connectionName\u0026\u0026(!a.rootConnectionName||e[t.ri].rootConnectionName!==a.rootConnectionName)).sort((t,e)=\u003et.distance-e.distance||t.ri-e.ri||t.a-e.a),d=l[0],h=l.find(t=\u003et.ri!==d?.ri);if(!d||!h)continue;const u=[n,d,h],p=u.map(t=\u003e`${t.ri}:${t.a}:${t.b}`).join(\"|\");if(c.has(p))continue;c.add(p);const m=d.viaEnds\u003e=h.viaEnds?1:2,g=3-m,f=[[m,0,g],[0,1,2],[0,2,1],[1,2,0],[2,1,0],[g,0,m]],y=new Set;for(const n of f){if(y.has(n.join()))continue;y.add(n.join());const o=e.map(t=\u003e({...t}));for(const t of u){const n=e[t.ri];o[t.ri]={...n,route:n.route.slice(0,t.a+1)},o.push({...n,route:n.route.slice(t.b)})}let r=!0;for(const s of n){if(i\u003e=t.maxSearchCalls||t.remainingNodes()\u003c=0)return;const n=u[s],a=e[n.ri],c={nodesPopped:0,completionReason:\"no-path\"},l=g1({srj:t.srj,routes:o,routeIndex:n.ri,start:a.route[n.b],end:a.route[n.a],bounds:t.bounds,traceThickness:n.width,traceClearance:t.traceClearance,viaClearance:t.viaClearance,gridSize:Math.max(.025,n.width/4),allowLayerChanges:!1,maxNodes:Math.min(3e4,t.remainingNodes()),stats:c});if(i++,t.onSearch(c),!l){r=!1;break}l.reverse(),o[n.ri]={...a,route:[...a.route.slice(0,n.a),...l,...a.route.slice(n.b+1)]},o[e.length+s].route=[]}r\u0026\u0026(yield u.map(t=\u003e({routeIndex:t.ri,route:o[t.ri]})))}}}({srj:this.input.srj,routes:this.routes,bounds:this.mutableBounds,violations:this.getFixedViolations(this.routes),isLocked:(t,e)=\u003ethis.isLocked(t,this.routes[t].route[e]),traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,maxSearchCalls:18-this.threeRoutePathSearchCalls,remainingNodes:()=\u003eMath.min(5e5-this.threeRoutePathSearchNodes,void 0===this.input.maxPathSearchNodes?Number.MAX_SAFE_INTEGER:this.input.maxPathSearchNodes-this.pathSearchNodes),onSearch:t=\u003e{this.threeRoutePathSearchCalls++,this.threeRoutePathSearchNodes+=t.nodesPopped,this.pathSearchCalls++,this.pathSearchNodes+=t.nodesPopped,this.updateWorkStats()}});for(const[e,...n]of t)e\u0026\u0026(yield{...e,additionalRoutes:n})}if(t\u0026\u0026(yield*this.generateCrossingPairCandidates()),yield*this.generateTaperedSegmentCandidates(n),yield*this.generateClearanceCandidates(n,t),\"path-search-node-limit\"===this.getWorkLimitReason())return;const o=new Set;for(const{ri:e,pi:i}of n.slice(0,80)){const n=this.routes[e];for(const r of[2,4,8,16]){const s=Math.max(0,i-r),a=Math.min(n.route.length-1,i+r),c=`${e}:${s}:${a}`;if(o.has(c))continue;o.add(c);const l=n.route[s],d=n.route[a];if(l.z!==d.z||!T6(l,this.mutableBounds)||!T6(d,this.mutableBounds))continue;if(n.route.slice(s+1,a).some(t=\u003ethis.isLocked(e,t)))continue;const h=new Set(n.route.slice(s,a+1).map(t=\u003et.traceThickness??n.traceThickness));if(1!==h.size)continue;const u=[...h][0],p=d.x-l.x,m=d.y-l.y,g=Math.hypot(p,m);if(!(g\u003c.1)){yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),...n.route.slice(a)]})};for(const t of[.15,-.15,.35,-.35,.7,-.7,1.5,-1.5])for(const o of[.2,0]){const i={x:l.x+p*o-m/g*t,y:l.y+m*o+p/g*t,z:l.z,traceThickness:u},r={x:l.x+p*(1-o)-m/g*t,y:l.y+m*(1-o)+p/g*t,z:l.z,traceThickness:u};T6(i,this.mutableBounds)\u0026\u0026T6(r,this.mutableBounds)\u0026\u0026(yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),i,r,...n.route.slice(a)]})})}if(t\u0026\u0026g\u003e2*n.viaDiameter+.3)for(let t=0;t\u003cthis.input.srj.layerCount;t++){if(t===l.z)continue;const o={x:l.x+.2*p,y:l.y+.2*m,z:l.z,traceThickness:u},i={x:l.x+.8*p,y:l.y+.8*m,z:l.z,traceThickness:u};yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),o,{...o,z:t},{...i,z:t},i,...n.route.slice(a)]})}}}}}const i=new Set;for(const{ri:e,pi:o,t:r}of n){const n=this.routes[e],s=n.route[o-1],a=n.route[o];for(const t of[o-1,o]){const o=n.route[t],r=`${e}:${o.x}:${o.y}`;if(i.has(r))continue;i.add(r);const s=n.route.map((t,e)=\u003et.x===o.x\u0026\u0026t.y===o.y?e:-1).filter(t=\u003et\u003e=0);if(!s.some(t=\u003ethis.isLocked(e,n.route[t])))for(const t of[.025,.05,.1,.2,.35,.5,.8,1.2])for(let o=0;o\u003c16;o++){const i=t*Math.cos(o*Math.PI/8),r=t*Math.sin(o*Math.PI/8),a=n.route.map((t,e)=\u003es.includes(e)?{...t,x:t.x+i,y:t.y+r}:t);s.some(t=\u003e!T6(a[t],this.mutableBounds))||(yield{routeIndex:e,route:R6({...n,route:a})})}}const c=t=\u003et.x\u003e=this.mutableBounds.minX-1e-8\u0026\u0026t.x\u003c=this.mutableBounds.maxX+1e-8\u0026\u0026t.y\u003e=this.mutableBounds.minY-1e-8\u0026\u0026t.y\u003c=this.mutableBounds.maxY+1e-8;if(s.z!==a.z||!c(s)||!c(a))continue;const l=a.x-s.x,d=a.y-s.y,h=Math.hypot(l,d);if(h\u003c.02)continue;const u=Math.max(s.traceThickness??n.traceThickness,a.traceThickness??n.traceThickness),p=l/h,m=d/h;for(const i of[.4,.8,1.5,3]){const a=Math.max(0,r*h-i),c=Math.min(h,r*h+i);for(const t of[.12,-.12,.25,-.25,.5,-.5,1,-1]){const i={x:s.x+p*a-m*t,y:s.y+m*a+p*t,z:s.z,traceThickness:u},r={x:s.x+p*c-m*t,y:s.y+m*c+p*t,z:s.z,traceThickness:u};T6(i,this.mutableBounds)\u0026\u0026T6(r,this.mutableBounds)\u0026\u0026(yield{routeIndex:e,route:{...n,route:[...n.route.slice(0,o),i,r,...n.route.slice(o)]}})}if(!t||c-a\u003cn.viaDiameter+.15)continue;const l={x:s.x+p*a,y:s.y+m*a,z:s.z,traceThickness:u},d={x:s.x+p*c,y:s.y+m*c,z:s.z,traceThickness:u};if(T6(l,this.mutableBounds)\u0026\u0026T6(d,this.mutableBounds))for(let t=0;t\u003cthis.input.srj.layerCount;t++){if(t===s.z)continue;const i=[l,{...l,z:t},{...d,z:t},d];yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,o),...i,...n.route.slice(o)]})}}}}}_step(){this.score||(this.score=this.evaluate(this.routes),this.stats={initialErrorCount:this.score.count,finalErrorCount:this.score.count,candidates:0,accepted:0},this.candidates=this.generateCandidates(),this.updateWorkStats());const t=this.getWorkLimitReason();if(0===this.score.count||this.evaluated\u003e=this.maxCandidates||t)return void this.finishSearch(0===this.score.count?\"clean\":this.evaluated\u003e=this.maxCandidates?\"candidate-limit\":t);const e=this.candidates.next();if(e.done){const t=this.getWorkLimitReason();return t?void this.finishSearch(t):void(this.bestAdjustment?(this.routes=this.bestAdjustment.routes,this.candidateScores.clear(),this.score=this.bestAdjustment.score,this.bestAdjustment=null,this.accepted++,this.candidates=this.generateCandidates()):(this.updateWorkStats(\"search-exhausted\"),this.solved=!0))}this.candidateAttempts++,this.updateWorkStats();const n=[e.value,...e.value.additionalRoutes??[]];if((!0!==this.input.allowLayerChanges||this.input.movableVias?.length)\u0026\u0026n.some(({routeIndex:t,route:e})=\u003e!this.preservesViaPermissions(t,e)))return;const o=this.routes.slice();for(const{routeIndex:t,route:e}of n)o[t]=e;const i=new Map;for(const t of this.getFixedViolations(o))i.set(t.key,t.severity);const r=[...i].every(([t,e])=\u003ethis.score.fixedViolations.has(t)\u0026\u0026e\u003c=this.score.fixedViolations.get(t)+g6),s=0===this.getViaPadViolations(o,!1).length;let a;if(s\u0026\u0026r){const t=JSON.stringify([e.value.routeIndex,e.value.route,...e.value.additionalRoutes??[]]);a=this.candidateScores.get(t),a||(a=this.evaluate(o),this.candidateScores.size\u003e=128\u0026\u0026this.candidateScores.delete(this.candidateScores.keys().next().value),this.candidateScores.set(t,a))}e.value.evaluatedScore=a,this.evaluated++,a\u0026\u0026s\u0026\u0026r\u0026\u0026a.count\u003cthis.score.count?(this.routes=o,this.candidateScores.clear(),this.score=a,this.accepted++,this.bestAdjustment=null,this.candidates=this.generateCandidates()):a\u0026\u0026r\u0026\u0026s\u0026\u0026a.count===this.score.count\u0026\u0026a.severity\u003c(this.bestAdjustment?.score.severity??this.score.severity)-1e-6\u0026\u0026(this.bestAdjustment={routes:o,score:a}),this.stats={...this.stats,finalErrorCount:this.score.count,candidates:this.evaluated,accepted:this.accepted},this.progress=this.evaluated/this.maxCandidates}getConstructorParams(){return[structuredClone(this.input)]}getOutput(){if(!this.solved||this.failed)throw new Error(\"repair04: getOutput requires a completed solve\");return structuredClone(this.routes)}visualize(){const t=this.input.bounds,e=this.mutableBounds;return{title:\"repair04 — fixed boundary, local copper repair\",rects:[{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,stroke:\"#64748b\",fill:\"rgba(148,163,184,0.15)\"},{center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,stroke:\"#0891b2\",fill:\"transparent\"},...this.input.srj.obstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,fill:\"rgba(239,68,68,0.22)\",stroke:\"#b91c1c\",layer:`z${t.layers.map(t=\u003e\"top\"===t?0:\"bottom\"===t?this.input.srj.layerCount-1:Number(t.slice(5))).join(\",\")}`}))],lines:this.routes.flatMap(t=\u003et.route.slice(1).flatMap((e,n)=\u003ee.z===t.route[n].z?[{points:[t.route[n],e],strokeColor:0===e.z?\"#dc2626\":\"rgba(37,99,235,0.65)\",strokeWidth:e.traceThickness??t.traceThickness,...0===e.z?{}:{strokeDash:[.2,.12]},layer:`z${e.z}`}]:[])),circles:this.routes.flatMap(t=\u003et.vias.map(e=\u003e{const n=t.route.filter(t=\u003et.x===e.x\u0026\u0026t.y===e.y).map(t=\u003et.z),o=Math.min(...n),i=Math.max(...n);return{center:e,radius:t.viaDiameter/2,fill:\"rgba(37,99,235,0.65)\",stroke:\"#1e40af\",layer:`z${Array.from({length:i-o+1},(t,e)=\u003eo+e).join(\",\")}`}})),points:this.lockedPoints.flat().map(t=\u003e({...t,color:\"#0f172a\",layer:`z${t.z}`}))}}},O6=(t,e,n)=\u003e{if(n\u003c=g6)return structuredClone(t);if(n\u003e=.99999999)return structuredClone(e);const o={...structuredClone(t),x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n};return delete o.start_pcb_port_id,delete o.end_pcb_port_id,o},k6=(t,e)=\u003e{const n=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,s=e.start.x-t.start.x,a=e.start.y-t.start.y,c=n*r-o*i,l=(t,e)=\u003e({x:t.start.x+(t.end.x-t.start.x)*e,y:t.start.y+(t.end.y-t.start.y)*e}),d=(t,e)=\u003e{const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=n*n+o*o,r=i\u003e10000000000000001e-32?Math.max(0,Math.min(1,((t.x-e.start.x)*n+(t.y-e.start.y)*o)/i)):0;return l(e,r)};if(Math.abs(c)\u003eg6){const e=(s*r-a*i)/c,d=(s*o-a*n)/c;if(e\u003e=0\u0026\u0026e\u003c=1\u0026\u0026d\u003e=0\u0026\u0026d\u003c=1){const n=l(t,e);return[n,n]}}else{const i=n*n+o*o;if(i\u003e10000000000000001e-32){const r=(s*n+a*o)/i,c=((e.end.x-t.start.x)*n+(e.end.y-t.start.y)*o)/i,h=Math.max(0,Math.min(r,c)),u=Math.min(1,Math.max(r,c));if(h\u003c=u){const n=l(t,(h+u)/2);return[n,d(n,e)]}}}const h=[[t.start,d(t.start,e)],[t.end,d(t.end,e)],[d(e.start,t),e.start],[d(e.end,t),e.end]];return h.sort((t,e)=\u003eMath.hypot(t[0].x-t[1].x,t[0].y-t[1].y)-Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y)),h[0]},L6=(t,e)=\u003e{const n=\"top\"===t?0:\"bottom\"===t?e-1:/^inner\\d+$/.test(t)?Number(t.slice(5)):-1;if(!Number.isInteger(n)||n\u003c0||n\u003e=e)throw new Error(`repair04 preload has an unknown layer: ${t}`);return n},D6=(t,e,n)=\u003e{const o=((t,e)=\u003e{const n=new Map,o=t=\u003e{const e=n.get(t);if(void 0===e||e===t)return t;const i=o(e);return n.set(t,i),i},i=t=\u003e{const e=t.filter(t=\u003e\"string\"==typeof t\u0026\u0026t.length\u003e0);if(0===e.length)return;const i=o(e[0]);for(const t of e)n.set(o(t),i)};for(const e of t.connections){const t=e;i([t.name,t.rootConnectionName,t.netConnectionName,t.__netConnectionName,...t.mergedConnectionNames??[],...t.__rootConnectionNames??[]])}for(const t of e)i([t.connectionName,t.rootConnectionName]);for(const e of t.traces??[])i([e.connection_name,...e.connectsTo??[]]);return o})(t,e),i=e.map((t,e)=\u003ee),r=t=\u003e{const e=i[t];if(e===t)return t;const n=r(e);return i[t]=n,n},s=new Map;for(let t=0;t\u003ce.length;t+=1){const n=e[t];for(const e of[n.route[0],n.route.at(-1)]){if(!e?.pcb_port_id)continue;const a=JSON.stringify([o(n.connectionName),e.pcb_port_id,e.x,e.y,e.z]),c=s.get(a);void 0===c?s.set(a,t):i[r(t)]=r(c)}}const a=(t,e)=\u003e!(!t.startsWith(\"route:\")||!e.startsWith(\"route:\"))\u0026\u0026r(Number(t.slice(6)))===r(Number(e.slice(6))),c=[],l=[],d=[],h=e.map(()=\u003e({segmentTimes:new Map,viaPositions:[]})),u=t=\u003e{if(f6(t,n)){d.push(t);for(let e=t.minZ;e\u003c=t.maxZ;e+=1)c.push({x:t.x,y:t.y,z:e,radius:t.radius,net:t.net,source:t.source,...void 0!==t.routeIndex?{viaOwner:t.routeIndex}:{}})}};for(let t=0;t\u003ce.length;t+=1){const i=e[t],r=o(i.connectionName),s=`route:${t}`;for(let e=0;e\u003ci.route.length;e+=1){const o=i.route[e];if((0===e||e===i.route.length-1||o.pcb_port_id)\u0026\u0026f6(o,n)\u0026\u0026c.push({x:o.x,y:o.y,z:o.z,radius:(o.traceThickness??i.traceThickness)/2,net:r,source:s}),0===e)continue;const a=i.route[e-1];\"through_obstacle\"!==a.toNextSegmentType\u0026\u0026(a.z===o.z?l.push({start:a,end:o,z:o.z,radius:Math.max(a.traceThickness??i.traceThickness,o.traceThickness??i.traceThickness)/2,net:r,source:s,routeIndex:t,segmentIndex:e-1}):u({x:o.x,y:o.y,minZ:Math.min(a.z,o.z),maxZ:Math.max(a.z,o.z),radius:i.viaDiameter/2,net:r,source:s,routeIndex:t}))}}for(let e=0;e\u003c(t.traces??[]).length;e+=1){const i=m1(t.traces[e],t.minTraceWidth),r=o(i.connection_name),s=`fixed:${e}`;for(let e=0;e\u003ci.route.length;e+=1){const o=i.route[e],a=i.route[e-1];if(\"wire\"===o.route_type){const d=L6(o.layer,t.layerCount);(0===e||e===i.route.length-1||o.start_pcb_port_id||o.end_pcb_port_id)\u0026\u0026f6(o,n)\u0026\u0026c.push({x:o.x,y:o.y,z:d,radius:o.width/2,net:r,source:s}),\"wire\"===a?.route_type\u0026\u0026a.layer===o.layer\u0026\u0026l.push({start:a,end:o,z:d,radius:Math.max(a.width,o.width)/2,net:r,source:s})}else if(\"via\"===o.route_type){const e=L6(o.from_layer,t.layerCount),n=L6(o.to_layer,t.layerCount);u({x:o.x,y:o.y,minZ:Math.min(e,n),maxZ:Math.max(e,n),radius:(o.via_diameter??t.minViaDiameter??.3)/2,net:r,source:s})}}}const p=new Map;for(const t of c){const e=JSON.stringify([t.net,t.z]),n=p.get(e)??[];n.push(t),p.set(e,n)}const m=(t,e)=\u003e{if(void 0===t)return;const n=h[t].viaPositions;n.some(t=\u003eMath.hypot(t.x-e.x,t.y-e.y)\u003c=g6)||n.push({x:e.x,y:e.y})};for(const t of l){if(!y6(t.start,t.end,n))continue;const e=t.end.x-t.start.x,o=t.end.y-t.start.y,i=e*e+o*o;if(!(i\u003c=10000000000000001e-32))for(const r of p.get(JSON.stringify([t.net,t.z]))??[]){if(r.source===t.source||a(r.source,t.source))continue;const s=Math.max(0,Math.min(1,((r.x-t.start.x)*e+(r.y-t.start.y)*o)/i)),c={x:t.start.x+e*s,y:t.start.y+o*s};if(f6(c,n)\u0026\u0026!(Math.hypot(c.x-r.x,c.y-r.y)\u003et.radius+r.radius+g6)){if(void 0!==t.routeIndex\u0026\u0026void 0!==t.segmentIndex){const e=h[t.routeIndex].segmentTimes.get(t.segmentIndex)??[];e.some(t=\u003eMath.abs(t-s)\u003c=g6)||e.push(s),h[t.routeIndex].segmentTimes.set(t.segmentIndex,e)}m(r.viaOwner,r)}}}for(const t of d)for(let e=t.minZ;e\u003c=t.maxZ;e+=1)for(const n of p.get(JSON.stringify([t.net,e]))??[])n.source===t.source||a(n.source,t.source)||Math.hypot(t.x-n.x,t.y-n.y)\u003et.radius+n.radius+g6||(m(t.routeIndex,t),m(n.viaOwner,n));return((t,e,n,o)=\u003e{const i=new Map,r=new Set,s=[],a=(t,e)=\u003e{if(void 0===t.routeIndex||void 0===t.segmentIndex)return;const o=t.end.x-t.start.x,i=t.end.y-t.start.y,r=o*o+i*i;if(r\u003c=10000000000000001e-32)return;const s=Math.max(0,Math.min(1,((e.x-t.start.x)*o+(e.y-t.start.y)*i)/r)),a=n[t.routeIndex].segmentTimes.get(t.segmentIndex)??[];a.some(t=\u003eMath.abs(t-s)\u003c=g6)||a.push(s),n[t.routeIndex].segmentTimes.set(t.segmentIndex,a)};for(const n of t){const t=y6(n.start,n.end,e);if(!t||t[1]-t[0]\u003c=g6)continue;const c=t=\u003e({x:n.start.x+(n.end.x-n.start.x)*t,y:n.start.y+(n.end.y-n.start.y)*t}),l={...n,start:c(t[0]),end:c(t[1])},d=s.length;s.push({original:n,clipped:l});const h=Math.floor((Math.min(l.start.x,l.end.x)-l.radius)/2),u=Math.floor((Math.max(l.start.x,l.end.x)+l.radius)/2),p=Math.floor((Math.min(l.start.y,l.end.y)-l.radius)/2),m=Math.floor((Math.max(l.start.y,l.end.y)+l.radius)/2);for(let t=h;t\u003c=u;t+=1)for(let e=p;e\u003c=m;e+=1){const c=JSON.stringify([l.net,l.z,t,e]),h=i.get(c)??[];for(const t of h){const e=s[t];if(e.original.source===n.source||o(e.original.source,n.source)||void 0===e.original.routeIndex\u0026\u0026void 0===n.routeIndex)continue;const i=`${t}:${d}`;if(r.has(i))continue;r.add(i);const[c,h]=k6(l,e.clipped);Math.hypot(c.x-h.x,c.y-h.y)\u003el.radius+e.clipped.radius+g6||(a(n,c),a(e.original,h))}h.push(d),i.set(c,h)}}})(l,n,h,a),h},z6=(t,e)=\u003e({minX:t.minX-e,maxX:t.maxX+e,minY:t.minY-e,maxY:t.maxY+e}),F6=(t,e,n,o)=\u003e{const i=[];let r;const s=t.route,a=t=\u003e0===t||t===s.length-1||void 0!==s[t]?.pcb_port_id,c=()=\u003e{void 0!==r\u0026\u0026r.points.length\u003e0\u0026\u0026(r.locks[0]=!0,r.locks[r.points.length-1]=!0,i.push(r)),r=void 0};if(1===s.length\u0026\u0026s[0]\u0026\u0026f6(s[0],e))return[{points:structuredClone(s),locks:[!0],start:{segmentIndex:0,t:0},end:{segmentIndex:0,t:0}}];for(let i=0;i\u003cs.length-1;i+=1){const l=s[i],d=s[i+1];if(!l||!d)throw new Error(\"repair04 found a missing route point\");if(![l.x,l.y,l.z,d.x,d.y,d.z].every(Number.isFinite))throw new Error(\"repair04 route coordinates must be finite\");if(l.z!==d.z\u0026\u0026!b6({x:l.x,y:l.y},{x:d.x,y:d.y})\u0026\u0026\"through_obstacle\"!==l.toNextSegmentType)throw new Error(\"repair04 requires colocated points at a via transition\");const h=y6(l,d,e);if(!h){c();continue}const[u,p]=h;if(p-u\u003c=g6\u0026\u0026!b6(l,d)){c();continue}const m=y6(l,d,n),g=[u,p],f=o.segmentTimes.get(i)??[];for(const t of f)t\u003e=u-g6\u0026\u0026t\u003c=p+g6\u0026\u0026g.push(Math.max(u,Math.min(p,t)));if(m\u0026\u0026l.z===d.z)for(const t of m)t\u003eu+g6\u0026\u0026t\u003cp-g6\u0026\u0026g.push(t);g.sort((t,e)=\u003et-e);const y=g.filter((t,e)=\u003e0===e||Math.abs(t-g[e-1])\u003eg6),_=_6(l,d,u);r\u0026\u0026!b6(r.points[r.points.length-1],_)\u0026\u0026c(),r||(r={points:[],locks:[],start:{segmentIndex:i,t:u},end:{segmentIndex:i,t:p}});for(const e of y){const s=_6(l,d,e),c=e\u003c=g6?i:e\u003e=.99999999?i+1:void 0,h=!f6(s,n,4e-8)||f.some(t=\u003eMath.abs(t-e)\u003c=g6)||o.viaPositions.some(t=\u003eMath.hypot(t.x-s.x,t.y-s.y)\u003c=g6)||void 0!==c\u0026\u0026a(c)||\"through_obstacle\"===l.toNextSegmentType||\"through_obstacle\"===s.toNextSegmentType||!0===l.insideJumperPad||!0===d.insideJumperPad||(t.jumpers??[]).some(t=\u003eb6(s,{...t.start,z:s.z})||b6(s,{...t.end,z:s.z})),u=r.points[r.points.length-1];u\u0026\u0026b6(u,s)?r.locks[r.locks.length-1]=r.locks[r.locks.length-1]||h:(r.points.push(s),r.locks.push(h))}r.end={segmentIndex:i,t:p},p\u003c.99999999\u0026\u0026c()}c();for(const t of i)for(let e=1;e\u003ct.points.length;e+=1){const n=t.points[e-1],o=t.points[e];if(n.z!==o.z\u0026\u0026(t.locks[e-1]||t.locks[e])){let n=e-1,i=e;for(;n\u003e0\u0026\u0026b6({x:t.points[n-1].x,y:t.points[n-1].y},{x:o.x,y:o.y});)n-=1;for(;i+1\u003ct.points.length\u0026\u0026b6({x:t.points[i+1].x,y:t.points[i+1].y},{x:o.x,y:o.y});)i+=1;for(let e=n;e\u003c=i;e+=1)t.locks[e]=!0}}return i},B6=(t,e)=\u003e{const n=t.bounds,o=t.outline\u0026\u0026t.outline.length\u003e=3?t.outline:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}],i=[];for(let n=0;n\u003co.length;n+=1){const r=o[n],s=o[(n+1)%o.length],a=y6(r,s,e);if(!a)continue;const c=s.x-r.x,l=s.y-r.y,d=Math.hypot(c,l);if(d\u003c=g6)continue;const h=(a[0]+a[1])/2;i.push({obstacleId:`repair04_board_edge_${n}`,type:\"rect\",center:{x:r.x+c*h,y:r.y+l*h},width:d*(a[1]-a[0]),height:Math.max(2*(t.minBoardEdgeClearance??0),g6),ccwRotationDegrees:180*Math.atan2(l,c)/Math.PI,layers:Array.from({length:t.layerCount},(e,n)=\u003e0===n?\"top\":n===t.layerCount-1?\"bottom\":`inner${n}`),zLayers:Array.from({length:t.layerCount},(t,e)=\u003ee),connectedTo:[]})}return i},j6=({srj:t,routes:e,bounds:n,boundaryMargin:o=.5,clearanceHalo:i})=\u003e{if((t=\u003e{if(!Object.values(t).every(Number.isFinite))throw new Error(\"repair04 bounds must contain finite coordinates\");if(t.maxX-t.minX\u003c9.99999999||t.maxY-t.minY\u003c9.99999999)throw new Error(\"repair04 requires bounds at least 10 mm by 10 mm\")})(n),!Number.isFinite(o)||o\u003c0||void 0!==i\u0026\u0026(!Number.isFinite(i)||i\u003c0))throw new Error(\"repair04 collar and halo must be finite and nonnegative\");const r=Math.max(t.defaultObstacleMargin??.2,t.minTraceToPadEdgeClearance??0,t.minViaEdgeToPadEdgeClearance??0);let s=Math.max(t.minTraceWidth,t.minViaDiameter??0);for(const t of e){s=Math.max(s,t.traceThickness,t.viaDiameter);for(const e of t.route)s=Math.max(s,e.traceThickness??0)}for(const e of t.traces??[])for(const n of e.route)\"wire\"===n.route_type\u0026\u0026(s=Math.max(s,n.width)),\"via\"===n.route_type\u0026\u0026(s=Math.max(s,n.via_diameter??t.minViaDiameter??.3));if(!Number.isFinite(s)||s\u003c=0)throw new Error(\"repair04 requires finite positive copper widths\");const a=Math.max(o,s+r);if(2*a\u003e=Math.min(n.maxX-n.minX,n.maxY-n.minY))throw new Error(\"repair04 bounds are too small for their required copper safety collar\");const c=z6(n,Math.max(i??a,r+s)),l=z6(n,-a),d=D6(t,e,c),h=((t,e,n)=\u003e{const o=[];for(const i of t){const t=m1(i,n),r=[];let s=[];const a=()=\u003e{s.length\u003e0\u0026\u0026r.push(s),s=[]},c=t=\u003e{x6(s[s.length-1])!==x6(t)\u0026\u0026s.push(structuredClone(t))};for(let n=0;n\u003ct.route.length;n+=1){const o=t.route[n],i=t.route[n-1];if(\"wire\"===o.route_type\u0026\u0026\"wire\"===i?.route_type\u0026\u0026o.layer===i.layer){const t=y6(i,o,e);if(!t){a();continue}const n=O6(i,o,t[0]),r=O6(i,o,t[1]),l=s[s.length-1];\"wire\"===l?.route_type\u0026\u0026(l.layer!==n.layer||Math.hypot(l.x-n.x,l.y-n.y)\u003eg6)\u0026\u0026a(),c(n),c(r),t[1]\u003c.99999999\u0026\u0026a()}else if(\"via\"===o.route_type){if(!f6(o,e)){a();continue}if(\"wire\"!==i?.route_type)throw new Error(\"repair04 normalized preload via has no incoming wire\");c(i),c(o);const r=t.route[n+1];if(\"wire\"!==r?.route_type)throw new Error(\"repair04 normalized preload via has no outgoing wire\");c(r)}else if(\"wire\"===o.route_type)f6(o,e)\u0026\u0026c(o);else if(\"start\"in o\u0026\u0026\"end\"in o){const t=y6(o.start,o.end,e);if(!t){a();continue}const n=t=\u003e({x:o.start.x+(o.end.x-o.start.x)*t,y:o.start.y+(o.end.y-o.start.y)*t});c({...structuredClone(o),start:n(t[0]),end:n(t[1])}),t[1]\u003c.99999999\u0026\u0026a()}}a();for(let t=0;t\u003cr.length;t+=1)o.push({...structuredClone(i),pcb_trace_id:1===r.length?i.pcb_trace_id:`${i.pcb_trace_id}__repair04_fixed_${t}`,route:r[t]})}return o})(t.traces??[],c,t.minTraceWidth),u=[],p=[],m=[];for(let t=0;t\u003ce.length;t+=1){const n=e[t];for(const e of F6(n,c,l,d[t])){const o={...structuredClone(Object.fromEntries(Object.entries(n).filter(([t])=\u003e\"route\"!==t\u0026\u0026\"vias\"!==t\u0026\u0026\"jumpers\"!==t))),connectionName:n.connectionName,traceThickness:n.traceThickness,viaDiameter:n.viaDiameter,route:e.points,vias:n.vias.filter(t=\u003ee.points.some(e=\u003eMath.abs(e.x-t.x)\u003c=g6\u0026\u0026Math.abs(e.y-t.y)\u003c=g6)).map(t=\u003estructuredClone(t)),...void 0!==n.jumpers?{jumpers:n.jumpers.filter(t=\u003evoid 0!==y6(t.start,t.end,c)).map(t=\u003estructuredClone(t))}:{}};u.push(o),p.push(e.locks),m.push({sourceRouteIndex:t,start:e.start,end:e.end,sourceGeometryKey:S6(n,e.start.segmentIndex+e.start.t,e.end.segmentIndex+e.end.t),originalFragment:structuredClone(o)})}}const g=new Set([...u.flatMap(t=\u003e[t.connectionName,...t.rootConnectionName?[t.rootConnectionName]:[]]),...h.map(t=\u003et.connection_name)]),f=t.connections.filter(t=\u003eg.has(t.name)||t.pointsToConnect.some(t=\u003ef6(t,c))).map(t=\u003e({...structuredClone(Object.fromEntries(Object.entries(t).filter(([t])=\u003e\"pointsToConnect\"!==t))),name:t.name,pointsToConnect:t.pointsToConnect.filter(t=\u003ef6(t,c)).map(t=\u003estructuredClone(t))}));for(let e=0;e\u003cu.length;e+=1){const n=u[e];let o=f.find(t=\u003et.name===n.connectionName);o||(o={name:n.connectionName,...n.rootConnectionName?{rootConnectionName:n.rootConnectionName}:{},pointsToConnect:[]},f.push(o));for(const[i,r]of[[\"start\",n.route[0]],[\"end\",n.route[n.route.length-1]]]){if(!r)continue;const n=0===r.z?\"top\":r.z===t.layerCount-1?\"bottom\":`inner${r.z}`;o.pointsToConnect.some(t=\u003eMath.abs(t.x-r.x)\u003c=g6\u0026\u0026Math.abs(t.y-r.y)\u003c=g6\u0026\u0026(\"layer\"in t?t.layer===n:t.layers.includes(n)))||o.pointsToConnect.push({x:r.x,y:r.y,layer:n,pointId:`repair04_${e}_${i}`,...r.pcb_port_id?{pcb_port_id:r.pcb_port_id}:{}})}}const y={...Object.fromEntries(Object.entries(t).filter(([t,e])=\u003e\"sourceCircuitJson\"!==t\u0026\u0026\"sourceKicadPcb\"!==t\u0026\u0026(\"number\"==typeof e||\"boolean\"==typeof e||\"string\"==typeof e))),layerCount:t.layerCount,minTraceWidth:t.minTraceWidth,bounds:structuredClone(c),obstacles:[...t.obstacles.filter(t=\u003e((t,e)=\u003e{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=(Math.abs(t.width*Math.cos(n))+Math.abs(t.height*Math.sin(n)))/2,i=(Math.abs(t.width*Math.sin(n))+Math.abs(t.height*Math.cos(n)))/2;return t.center.x+o\u003e=e.minX\u0026\u0026t.center.x-o\u003c=e.maxX\u0026\u0026t.center.y+i\u003e=e.minY\u0026\u0026t.center.y-i\u003c=e.maxY})(t,c)).map(t=\u003estructuredClone(t)),...B6(t,c)],connections:f,...void 0!==t.traces?{traces:h}:{},...void 0!==t.allowJumpers?{allowJumpers:t.allowJumpers}:{},...t.availableJumperTypes?{availableJumperTypes:structuredClone(t.availableJumperTypes)}:{}};return{srj:y,routes:u,bounds:structuredClone(n),contextBounds:c,mutableBounds:l,boundaryMargin:a,lockedPointIndices:p,routeMappings:m}},$6=t=\u003ex6(Object.fromEntries(Object.entries(t).filter(([t])=\u003e\"route\"!==t\u0026\u0026\"vias\"!==t))),Y6=(t,e)=\u003e{const n=[];for(let o=1;o\u003ct.route.length;o+=1){const i=t.route[o-1],r=t.route[o],s=y6(i,r,e),a=s?[...s[0]\u003eg6?[[0,s[0]]]:[],...s[1]\u003c.99999999?[[s[1],1]]:[]]:[[0,1]];s\u0026\u0026!f6(_6(i,r,.5),e,4e-8)\u0026\u00260===a.length\u0026\u0026a.push([0,1]);for(const[t,e]of a)n.push(x6([_6(i,r,t),_6(i,r,e)]))}return n},X6=(t,e,n,o,i,r)=\u003e{if($6(t)!==$6(e))throw new Error(\"repair04 merge rejected changed net, width, jumper, or route metadata\");if(n.length!==t.route.length)throw new Error(\"repair04 merge received an invalid lock mask\");if(0===e.route.length)throw new Error(\"repair04 merge rejected an empty replacement route\");if(x6(t.route[0])!==x6(e.route[0])||x6(t.route[t.route.length-1])!==x6(e.route[e.route.length-1]))throw new Error(\"repair04 merge rejected a moved fragment endpoint\");let s=0;for(let o=0;o\u003ct.route.length;o+=1){if(!n[o])continue;const i=x6(t.route[o]);for(;s\u003ce.route.length\u0026\u0026x6(e.route[s])!==i;)s+=1;if(s===e.route.length)throw new Error(\"repair04 merge rejected a moved or removed locked point\");s+=1}if(x6(Y6(t,o))!==x6(Y6(e,o)))throw new Error(\"repair04 merge rejected modified geometry in the fixed boundary collar\");for(let n=1;n\u003ct.route.length;n+=1){const o=t.route[n-1],i=t.route[n];if(!(\"through_obstacle\"===o.toNextSegmentType||!0===o.insideJumperPad||!0===i.insideJumperPad||(t.jumpers??[]).some(t=\u003eb6(o,{...t.start,z:o.z})\u0026\u0026b6(i,{...t.end,z:i.z})||b6(o,{...t.end,z:o.z})\u0026\u0026b6(i,{...t.start,z:i.z}))))continue;const r=x6([o,i]);if(!e.route.some((t,n)=\u003en+1\u003ce.route.length\u0026\u0026x6([t,e.route[n+1]])===r))throw new Error(\"repair04 merge rejected a changed atomic jumper or through-obstacle span\")}for(const n of e.route){if(![n.x,n.y,n.z].every(Number.isFinite)||!Number.isInteger(n.z)||n.z\u003c0||n.z\u003e=r||!f6(n,i))throw new Error(\"repair04 merge rejected invalid or out-of-region geometry\");if((void 0!==n.pcb_port_id||!0===n.insideJumperPad||void 0!==n.toNextSegmentCircuitJsonMetadata)\u0026\u0026!t.route.some(t=\u003ex6(t)===x6(n)))throw new Error(\"repair04 merge rejected invented or moved terminal/circuit metadata\");if(void 0!==n.traceThickness\u0026\u0026(!Number.isFinite(n.traceThickness)||n.traceThickness\u003c=0||n.traceThickness\u003eMath.max(t.traceThickness,...t.route.map(t=\u003et.traceThickness??0))+g6))throw new Error(\"repair04 merge rejected increased per-point copper width\")}for(let n=1;n\u003ce.route.length;n+=1){const o=e.route[n-1],i=e.route[n];if(\"through_obstacle\"===o.toNextSegmentType\u0026\u0026!t.route.some((e,n)=\u003en+1\u003ct.route.length\u0026\u0026x6([e,t.route[n+1]])===x6([o,i])))throw new Error(\"repair04 merge rejected an invented through-obstacle span\");if(o.z!==i.z\u0026\u0026\"through_obstacle\"!==o.toNextSegmentType\u0026\u0026(Math.abs(o.x-i.x)\u003eg6||Math.abs(o.y-i.y)\u003eg6||!e.vias.some(t=\u003eMath.abs(t.x-o.x)\u003c=g6\u0026\u0026Math.abs(t.y-o.y)\u003c=g6)))throw new Error(\"repair04 merge rejected a disconnected or missing via\")}for(const n of e.vias){if(!(Number.isFinite(n.x)\u0026\u0026Number.isFinite(n.y)\u0026\u0026f6(n,i)\u0026\u0026e.route.some(t=\u003eMath.abs(t.x-n.x)\u003c=g6\u0026\u0026Math.abs(t.y-n.y)\u003c=g6)))throw new Error(\"repair04 merge rejected an invalid via position\");if(!f6(n,o,4e-8)\u0026\u0026!t.vias.some(t=\u003ex6(t)===x6(n)))throw new Error(\"repair04 merge rejected a new via in the boundary collar\")}for(const n of t.vias)if(!f6(n,o,4e-8)\u0026\u0026!e.vias.some(t=\u003ex6(t)===x6(n)))throw new Error(\"repair04 merge rejected a changed via in the boundary collar\")},V6=(t,e)=\u003e{for(const n of e){const e=t[t.length-1];e\u0026\u0026b6(e,n)\u0026\u0026x6(e)===x6(n)||t.push(structuredClone(n))}},W6=(t,e,n)=\u003e{const o=new Set(e.route.map(x6)),i=new Set(n.flatMap(t=\u003et.originalFragment.route.map(x6)).filter(t=\u003e!o.has(t))),r=[];for(const e of t)for(r.push(e);r.length\u003e=3;){const t=r[r.length-3],e=r[r.length-2],n=r[r.length-1];if(!i.has(x6(e)))break;if(t.z!==e.z||e.z!==n.z\u0026\u0026\"through_obstacle\"!==t.toNextSegmentType)break;if(t.toNextSegmentType!==e.toNextSegmentType||t.insideJumperPad!==e.insideJumperPad||t.traceThickness!==e.traceThickness||x6(t.toNextSegmentCircuitJsonMetadata)!==x6(e.toNextSegmentCircuitJsonMetadata))break;const o=n.x-t.x,s=n.y-t.y,a=o*o+s*s;if(a\u003c=10000000000000001e-32)break;const c=(e.x-t.x)*s-(e.y-t.y)*o,l=((e.x-t.x)*o+(e.y-t.y)*s)/a;if(Math.abs(c)\u003eg6*Math.sqrt(a)||l\u003c0||l\u003e1)break;r.splice(r.length-2,1)}return r},H6=t=\u003e{if(!Number.isInteger(t.segmentIndex)||t.segmentIndex\u003c0||!Number.isFinite(t.t)||t.t\u003c0||t.t\u003e1)throw new Error(\"repair04 merge received invalid fragment provenance\");return t.segmentIndex+t.t},G6=({routes:t,region:e,repairedRoutes:n})=\u003e{if(n.length!==e.routeMappings.length||e.lockedPointIndices.length!==n.length)throw new Error(\"repair04 merge requires exactly one replacement for every extracted fragment\");const o=new Map;for(let i=0;i\u003cn.length;i+=1){const r=e.routeMappings[i],s=n[i];if(!t[r.sourceRouteIndex])throw new Error(\"repair04 merge source route no longer exists\");if(X6(r.originalFragment,s,e.lockedPointIndices[i],e.mutableBounds,e.contextBounds,e.srj.layerCount),x6(r.originalFragment)===x6(s))continue;const a=o.get(r.sourceRouteIndex)??[];a.push({mapping:r,repaired:s}),o.set(r.sourceRouteIndex,a)}return t.map((t,e)=\u003e{const n=o.get(e);if(!n)return t;n.sort((t,e)=\u003eH6(t.mapping.start)-H6(e.mapping.start));const i=[];let r=0;for(const{mapping:e,repaired:o}of n){const n=H6(e.start),s=H6(e.end);if(n\u003cr-g6||s\u003cn||s\u003et.route.length-1+g6)throw new Error(\"repair04 merge received overlapping or stale fragment provenance\");if(S6(t,n,s)!==e.sourceGeometryKey)throw new Error(\"repair04 merge rejected stale source geometry\");V6(i,v6(t,r,n)),V6(i,o.route),r=s}V6(i,v6(t,r,t.route.length-1));const s=new Set(n.flatMap(({mapping:t})=\u003et.originalFragment.vias.map(t=\u003e`${t.x},${t.y}`))),a=t.vias.filter(t=\u003e!s.has(`${t.x},${t.y}`)).map(t=\u003estructuredClone(t));for(const{repaired:t}of n)for(const e of t.vias)a.some(t=\u003eMath.abs(t.x-e.x)\u003c=g6\u0026\u0026Math.abs(t.y-e.y)\u003c=g6)||a.push(structuredClone(e));return{...t,route:W6(i,t,n.map(({mapping:t})=\u003et)),vias:a}})},U6=12e4,Z6=[10,16],q6=[3,4,5,6,8],J6=(t,e)=\u003e{const n=\"string\"==typeof t.pcb_pad_id?t.pcb_pad_id:\"string\"==typeof t.pcb_trace_error_id?t.pcb_trace_error_id.match(/(pcb_(?:smtpad|plated_hole|hole|keepout)_\\d+)$/)?.[1]:void 0;if(n){const t=e.obstacles.find(t=\u003et.obstacleId===n||t.connectedTo[0]===n);if(t)return t.center}return(t=\u003e{const e=t.center;return e\u0026\u0026\"object\"==typeof e\u0026\u0026\"x\"in e\u0026\u0026\"y\"in e\u0026\u0026\"number\"==typeof e.x\u0026\u0026\"number\"==typeof e.y?{x:e.x,y:e.y}:void 0})(t)},K6=({error:t,routeIndexByTraceId:e})=\u003e{const n=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,o=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]],i=n?`overlap_${n}_`:void 0,r=i\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0,s=void 0!==r\u0026\u0026o.includes(r);return[n,...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids:[],s?void 0:r].filter(t=\u003e\"string\"==typeof t\u0026\u0026e.has(t)).filter((t,e,n)=\u003en.indexOf(t)===e)},Q6=t=\u003et.filter(t=\u003e\"pcb_via_clearance_error\"===t.type||Array.isArray(t.pcb_via_ids)).length,t9=(t,e)=\u003e{const n=new Map;for(const e of t)n.set(e.connectionName,(n.get(e.connectionName)??0)+1);return t.map((t,o)=\u003e{const i=n.get(t.connectionName)\u003e1?`${t.connectionName}_regional_${o}`:t.connectionName;return i!==t.connectionName\u0026\u0026e.addConnections([[i,t.connectionName,t.rootConnectionName??t.connectionName]]),{...t,connectionName:i,preloadedTraceId:`pipeline9_joint_candidate_${o}`,preloadedTraceIndex:o,preloadedRouteIndex:0,isThroughObstacle:!1}})},e9=(t,e)=\u003et.minX\u003c=e.maxX\u0026\u0026t.maxX\u003e=e.minX\u0026\u0026t.minY\u003c=e.maxY\u0026\u0026t.maxY\u003e=e.minY,n9=t=\u003e({minX:t.center.x-t.diameter/2,maxX:t.center.x+t.diameter/2,minY:t.center.y-t.diameter/2,maxY:t.center.y+t.diameter/2}),o9=t=\u003e({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}),i9=(t,e)=\u003e{const n=EQ(t);return n.wireSegments.some(t=\u003ee9((t=\u003e({minX:Math.min(t.start.x,t.end.x)-t.width/2,maxX:Math.max(t.start.x,t.end.x)+t.width/2,minY:Math.min(t.start.y,t.end.y)-t.width/2,maxY:Math.max(t.start.y,t.end.y)+t.width/2}))(t),e))||n.viaSpans.some(t=\u003ee9(n9(t),e))},r9=({routes:t,fixedObstacleRoutes:e,routeIndex:n,center:o,regionSize:i,srj:r,connMap:s,colorMap:a,viaDiameter:c,traceWidth:l,obstacleMargin:d,effort:h})=\u003e{const u=t9(t,s),p=u[n];if(!p)return;const m={capacityMeshNodeId:`pipeline9_joint_drc_${n}_${i}`,center:o,width:i,height:i,availableZ:Array.from({length:r.layerCount},(t,e)=\u003ee),portPoints:[],portPointsInPairs:[]},g=$K(m,[p]),f=g.fixedRouteSectionsByConnectionName.get(p.connectionName);if(!f)return;const y=u.filter((t,e)=\u003ee!==n),_=new VQ({nodePortPoints:[g.nodeWithPortPoints],fixedHdRoutes:[...y,...e].map(t=\u003e({...t,rootConnectionName:s.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName})),connMap:s,colorMap:a,obstacles:r.obstacles,layerCount:r.layerCount,viaDiameter:c,traceWidth:l,obstacleMargin:d,effort:h,preserveTerminalPcbPortIds:!0,includeBoardObstacles:!0,enableRegionalFallback:!1,maxB01Rips:120});if(_.solve(),!_.solved||_.failed)return;const b=_.routes.find(t=\u003et.connectionName===p.connectionName);return b?{routes:t.map((t,e)=\u003ee===n?{...XK(f,b),connectionName:t.connectionName}:t),usedFallback:Number(_.stats.fallbackNodeCount??0)\u003e0}:void 0},s9=({routes:t,fixedRouteCopperSpatialIndex:e,center:n,regionSize:o,srj:i,connMap:r,colorMap:s,viaDiameter:a,traceWidth:c,obstacleMargin:l,effort:d})=\u003e{const h=t9(t,r),u={capacityMeshNodeId:\"pipeline9_joint_drc_regular_fallback\",center:n,width:o,height:o,availableZ:Array.from({length:i.layerCount},(t,e)=\u003ee),portPoints:[],portPointsInPairs:[]},p=$K(u,h);if(0===p.fixedRouteSectionsByConnectionName.size)return;if(!(t=\u003e{const e=kK(t);return t.portPoints.every(t=\u003e\"on-boundary\"===rs({point:t,bounds:e}))})(p.nodeWithPortPoints))return;const m=[...p.fixedRouteSectionsByConnectionName.values()].flatMap(t=\u003et.sourceRoutes).reduce((t,e)=\u003e{const n=EQ(e);return Math.max(t,e.viaDiameter/2,...n.wireSegments.map(t=\u003et.width/2),...n.viaSpans.map(t=\u003et.diameter/2))},Math.max(c/2,a/2)),g={minX:n.x-o/2-l-m,maxX:n.x+o/2+l+m,minY:n.y-o/2-l-m,maxY:n.y+o/2+l+m},f=e.getRoutesOverlappingBounds(g),y=OQ({fixedObstacleRoutes:f,layerCount:i.layerCount}),_=new FQ({nodeWithPortPoints:p.nodeWithPortPoints,colorMap:s,connMap:r,viaDiameter:a,traceWidth:c,obstacleMargin:l,effort:d,obstacles:[...i.obstacles,...y],layerCount:i.layerCount});if(_.solve(),!_.solved||_.failed)return;const b=_.getOutput(),x=new Map(b.map(t=\u003e[t.connectionName,t])),v=new Map,S=new Set;for(const[t,e]of p.fixedRouteSectionsByConnectionName){const n=x.get(t);if(!n)return;v.set(e.sourceRoutes[0].preloadedTraceIndex,XK(e,n));for(const t of e.sourceRoutes.slice(1))S.add(t.preloadedTraceIndex)}const I=h.flatMap((e,n)=\u003eS.has(n)?[]:[{...v.get(n)??e,connectionName:t[n].connectionName}]);return(({candidateRoutes:t,fixedObstacleRoutes:e,obstacleMargin:n,connMap:o,candidateBounds:i})=\u003e{for(const r of t)for(const t of e)if(!kQ(r,t,o)\u0026\u0026DQ({left:r,right:t,clearance:n,leftBounds:i}))return!0;return!1})({candidateRoutes:I,fixedObstacleRoutes:f,obstacleMargin:l,connMap:r,candidateBounds:g})?void 0:I},a9=({srj:t,routes:e,fixedObstacleRoutes:n,newConnections:o,syntheticConnectionNames:i,drcEvaluator:r,initialErrors:s,allowTracePairRepair:a=!1,preloadRepairTraceIds:c,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m})=\u003e{let g=e,f=s??r1(r,g),y=0,_=0,b=0,x=0,v=!1;const S=(t=\u003e{if(!Number.isInteger(t)||t\u003c0)throw new Error(\"Pipeline9 regional repair route count must be nonnegative\");const e=Math.floor(7e3/Math.max(1,t));return Math.max(16,Math.min(192,e))})(e.length),I=f.filter(t=\u003e(({error:t,preloadRepairTraceIds:e})=\u003e!!s1(t).some(t=\u003ee.has(t))||(t.__collapsed_trace_participants??[]).flatMap(t=\u003enew Set(t.evaluationTraceIds).size\u003e1?[t.solverTraceId]:[]).some(t=\u003ee.collidingFixedTraceIds?.has(t)))({error:t,preloadRepairTraceIds:c})).length,C=d1({routes:g,newConnections:o,syntheticConnectionNames:i}),P=a\u0026\u0026f.some(t=\u003e((t,e)=\u003e!(\"pcb_trace_error\"!==t.type||\"string\"==typeof t.pcb_via_id||Array.isArray(t.pcb_via_ids)\u0026\u0026t.pcb_via_ids.length\u003e0)\u0026\u00262===K6({error:t,routeIndexByTraceId:e}).length)(t,C));if(0===I\u0026\u0026!P)return{routes:g,attemptedCandidateCount:y,acceptedCandidateCount:_,fallbackCandidateCount:b,candidateSearchCount:x,candidateSearchBudget:S,candidateSearchBudgetExhausted:v,safeTraceLayerRepairSkippedForBudget:!1,remainingDrcIssueCount:f.length,preloadEligibleDrcIssueCount:I,preloadRepairAttempted:!1};const M=(t=\u003e{const e=new Map,n=(t,n)=\u003e{const o=Math.floor(n.minX/4),i=Math.floor(n.maxX/4),r=Math.floor(n.minY/4),s=Math.floor(n.maxY/4);for(let n=o;n\u003c=i;n++)for(let o=r;o\u003c=s;o++){const i=`${n}:${o}`,r=e.get(i)??new Set;r.add(t),e.set(i,r)}};for(let e=0;e\u003ct.length;e++){const o=EQ(t[e]);for(const t of o.wireSegments)for(const o of AQ(t,4,1))n(e,o9(o));for(const t of o.viaSpans)n(e,n9(t))}return{getRoutesOverlappingBounds:n=\u003e{const o=new Set,i=Math.floor(n.minX/4),r=Math.floor(n.maxX/4),s=Math.floor(n.minY/4),a=Math.floor(n.maxY/4);for(let t=i;t\u003c=r;t++)for(let n=s;n\u003c=a;n++)for(const i of e.get(`${t}:${n}`)??[])o.add(i);return[...o].sort((t,e)=\u003et-e).map(e=\u003et[e]).filter(t=\u003ei9(t,n))}}})(n);for(let e=0;e\u003c2\u0026\u0026!v;e++){let e=!1;const s=d1({routes:g,newConnections:o,syntheticConnectionNames:i}),a=f.filter(t=\u003e(\"pcb_trace_error\"===t.type||\"pcb_pad_trace_clearance_error\"===t.type||\"pcb_via_trace_clearance_error\"===t.type||\"pcb_via_clearance_error\"===t.type)\u0026\u0026\"string\"==typeof t.pcb_trace_id);for(const o of a){if(v)break;const i=J6(o,t),a=K6({error:o,routeIndexByTraceId:s});if(!i)continue;let c=g,I=f;for(const e of a.slice(0,2)){if(v)break;const o=s.get(e);if(void 0!==o){for(const e of q6){if(x\u003e=S){v=!0;break}x++;const s=r9({routes:g,fixedObstacleRoutes:n,routeIndex:o,center:i,regionSize:e,srj:t,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m});if(!s)continue;y++,s.usedFallback\u0026\u0026b++;const a=r1(r,s.routes);if(l1(a,I)\u0026\u0026(c=s.routes,I=a),0===I.length)break}if(0===I.length)break}}if(c!==g||v||(x\u003e=S?v=!0:x++),c===g\u0026\u0026!v){const e=s9({routes:g,fixedRouteCopperSpatialIndex:M,center:i,regionSize:3,srj:t,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m});if(e){y++,b++;const t=r1(r,e);l1(t,I)\u0026\u0026(c=e,I=t)}}if(c!==g\u0026\u0026(g=c,f=I,_++,e=!0),v)break}if(!e||0===f.length)break}if(_\u003e0\u0026\u0026f.length\u003e0){const e=iD({...t,traces:void 0},g,m,1,l);if(e!==g){const t=r1(r,e);Q6(t)\u003c=Q6(f)\u0026\u0026l1(t,f)\u0026\u0026(g=e,f=t)}}const N=f.some(t=\u003e\"pcb_trace_error\"===t.type||\"pcb_pad_trace_clearance_error\"===t.type),w=N\u0026\u0026v;if(N\u0026\u0026!v){const e=new Nz({srj:{...t,traces:void 0},hdRoutes:g,connMap:l,effort:m,drcEvaluator:r,maxIterations:8,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1});if(e.solve(),e.failed)throw new Error(`Pipeline9 post-regional safe trace-layer repair failed: ${e.error??\"unknown error\"}`);const n=e.getOutput(),o=r1(r,n);l1(o,f)\u0026\u0026(g=n,f=o)}return{routes:g,attemptedCandidateCount:y,acceptedCandidateCount:_,fallbackCandidateCount:b,candidateSearchCount:x,candidateSearchBudget:S,candidateSearchBudgetExhausted:v,safeTraceLayerRepairSkippedForBudget:w,remainingDrcIssueCount:f.length,preloadEligibleDrcIssueCount:I,preloadRepairAttempted:I\u003e0}},c9=[.9,.72],l9=Array.from({length:16},(t,e)=\u003ee*Math.PI/8),d9=t=\u003e\"pcb_pad_trace_clearance_error\"===t.type||\"pcb_trace_error\"===t.type\u0026\u0026!(Array.isArray(t.pcb_trace_ids)\u0026\u0026t.pcb_trace_ids.length\u003e=2),h9=t=\u003e{if(\"string\"==typeof t.pcb_pad_id)return t.pcb_pad_id;if(\"string\"==typeof t.pcb_trace_error_id){const e=t.pcb_trace_error_id.match(/(pcb_(?:smtpad|plated_hole|hole|keepout)_\\d+)$/)?.[1];if(e)return e}const e=\"string\"==typeof t.message?t.message:\"\";return e.match(/(?:pcb_smtpad|pcb_plated_hole|pcb_hole|pcb_keepout)\\[#?([^\\]\"]+)\\]/)?.[1]},u9=(t,e)=\u003e{if(!e)return;const n=e.startsWith(\"pcb_\")?e:`pcb_${e}`;return t.obstacles.find(t=\u003et.obstacleId===n||t.connectedTo[0]===n)},p9=({srj:t,pcbPortId:e,z:n,portPositionMap:o})=\u003e{const i=vo(n,t.layerCount),r=o.get(e),s=t.obstacles.filter(t=\u003et.layers.includes(i)\u0026\u0026t.connectedTo.includes(e));return r?s.reduce((t,e)=\u003et?Math.hypot(e.center.x-r.x,e.center.y-r.y)\u003cMath.hypot(t.center.x-r.x,t.center.y-r.y)?e:t:e,void 0):s[0]},m9=({terminalObstacle:t,conflictingObstacle:e,traceRadius:n})=\u003e{const o=Math.max(0,t.width/2-n),i=Math.max(0,t.height/2-n),r=(t.ccwRotationDegrees??0)*Math.PI/180;return c9.flatMap(e=\u003el9.map(n=\u003e{const s={x:Math.cos(n)*o*e,y:Math.sin(n)*i*e},a=(l=r,{x:(c=s).x*Math.cos(l)-c.y*Math.sin(l),y:c.x*Math.sin(l)+c.y*Math.cos(l)});var c,l;return{x:t.center.x+a.x,y:t.center.y+a.y}})).sort((t,n)=\u003eMath.hypot(n.x-e.center.x,n.y-e.center.y)-Math.hypot(t.x-e.center.x,t.y-e.center.y)).slice(0,16)},g9=({routes:t,routeIndex:e,endpointIndex:n,point:o,bounds:i,collapseAdjacent:r})=\u003e{const s=(t=\u003et.map(t=\u003e({...t,route:t.route.map(t=\u003e({...t})),vias:t.vias.map(t=\u003e({...t}))})))(t),a=s[e];if(!a||a.route.length\u003c2)return;const c=0===n?0:a.route.length-1,l=0===n?1:c-1,d=a.route[c],h=a.route[l];if(!d||!h||d.z!==h.z)return;const u=a.traceThickness/2;if(!(o.x-u\u003ci.minX||o.x+u\u003ei.maxX||o.y-u\u003ci.minY||o.y+u\u003ei.maxY)){if(a.route[c]={...d,...o},r){const t=0===n?l+1:l-1,e=a.route[t],i=a.vias.some(t=\u003et.x===h.x\u0026\u0026t.y===h.y);if(!e||e.z!==d.z||void 0!==h.pcb_port_id||i)return;a.route[l]={...h,...o}}return s}},f9=({srj:t,originalSrj:e,routes:n,newConnections:o,syntheticConnectionNames:i,drcEvaluator:r})=\u003e{let s=n,a=r1(r,s),c=0,l=0;const d=(t=\u003e{const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,t);return e})(e);for(let n=0;n\u003c2;n++){let n=!1;const h=d1({routes:s,newConnections:o,syntheticConnectionNames:i});for(const o of a.filter(d9)){if(c\u003e=256)break;if(\"string\"!=typeof o.pcb_trace_id)continue;const i=h.get(o.pcb_trace_id),u=u9(t,h9(o));if(void 0===i||!u)continue;const p=s[i];let m=s,g=a;t:for(const n of[0,-1]){const o=0===n?p.route[0]:p.route.at(-1);if(!o||\"string\"!=typeof o.pcb_port_id)continue;const a=p9({srj:e,pcbPortId:o.pcb_port_id,z:o.z,portPositionMap:d});if(!a||a===u)continue;const l=Math.hypot(u.width,u.height)/2+Math.hypot(a.width,a.height)/2+.5;if(!(Math.hypot(o.x-u.center.x,o.y-u.center.y)\u003el))for(const e of m9({terminalObstacle:a,conflictingObstacle:u,traceRadius:p.traceThickness/2}))for(const o of[!1,!0]){if(c\u003e=256)break t;const a=g9({routes:s,routeIndex:i,endpointIndex:n,point:e,bounds:t.bounds,collapseAdjacent:o});if(!a)continue;c++;const l=r1(r,a);l1(l,g)\u0026\u0026(m=a,g=l)}}m!==s\u0026\u0026(s=m,a=g,l++,n=!0)}if(!n||0===a.length)break}return{routes:s,attemptedCandidateCount:c,acceptedCandidateCount:l,remainingErrors:a}},y9=[\"pcb_trace_error_id\",\"pcb_error_id\",\"pcb_via_trace_clearance_error_id\",\"pcb_pad_trace_clearance_error_id\"],_9=(t,e)=\u003e{let n=t;const o=[...e].sort(([t],[e])=\u003ee.length-t.length);for(const[t,e]of o)n=n.replaceAll(t,e);return n},b9=(t,e)=\u003e{const n=String(t.type??t.error_type??\"unknown\");if(\"pcb_via_clearance_error\"===n)return((t,e)=\u003e{const n=[...\"string\"==typeof t.pcb_trace_id?[t.pcb_trace_id]:[],...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[]].map(t=\u003e_9(t,e)).filter((t,e,n)=\u003en.indexOf(t)===e).sort(),o=t.center\u0026\u0026\"object\"==typeof t.center?t.center:t.pcb_center\u0026\u0026\"object\"==typeof t.pcb_center?t.pcb_center:void 0,i=\"number\"==typeof o?.x\u0026\u0026\"number\"==typeof o.y?{x:o.x,y:o.y}:void 0,r=\"string\"==typeof t.pcb_via_pair_net_relation?t.pcb_via_pair_net_relation:void 0;if(0!==n.length\u0026\u0026i\u0026\u0026r)return`pcb_via_clearance_error:${JSON.stringify({traceIds:n,center:i,netRelation:r})}`})(t,e);for(const o of y9){const i=t[o];if(\"string\"==typeof i)return`${n}:${_9(i,e)}`}const o=Object.fromEntries(Object.entries(t).filter(([t,e])=\u003e(t.endsWith(\"_id\")||t.endsWith(\"_ids\"))\u0026\u0026(\"string\"==typeof e||Array.isArray(e))).sort(([t],[e])=\u003et.localeCompare(e)).map(([t,n])=\u003e[t,\"string\"==typeof n?_9(n,e):n]));return`${n}:${JSON.stringify(o)}`},x9=({errors:t,baselineErrors:e,originalTraceIdByPreparedTraceId:n=new Map})=\u003e{const o=new Set(e.filter(t=\u003e!(t=\u003e\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(\"missing_connection_\"))(t)).map(t=\u003eb9(t,new Map)));return o.delete(void 0),t.filter(t=\u003e{const e=b9(t,n);return void 0===e||!o.has(e)})},v9=1.5,S9=({errorsWithCenters:t,traces:e,layerCount:n,defaultViaDiameter:o,connMap:i})=\u003e{const r=(t=\u003et.flatMap(t=\u003e{if(\"pcb_trace_error\"!==t.type||!Array.isArray(t.pcb_port_ids)||t.pcb_port_ids.length\u003c4)return[];const e=t.center;return e\u0026\u0026\"object\"==typeof e\u0026\u0026\"x\"in e\u0026\u0026\"y\"in e\u0026\u0026\"number\"==typeof e.x\u0026\u0026\"number\"==typeof e.y?[{x:e.x,y:e.y}]:[]}))(t),s=new Set;for(let t=0;t\u003ce.length;t++){const a=e[t],c=oQ(a,t,n,o,i);r.some(t=\u003ec.some(e=\u003e{const n=e.route.map(t=\u003et.x),o=e.route.map(t=\u003et.y);return Math.min(...n)\u003c=t.x+v9\u0026\u0026Math.max(...n)\u003e=t.x-v9\u0026\u0026Math.min(...o)\u003c=t.y+v9\u0026\u0026Math.max(...o)\u003e=t.y-v9}))\u0026\u0026s.add(a.pcb_trace_id)}return s},I9=({routes:t,otherHdRoutes:e,obstacles:n,colorMap:o,layerCount:i,connMap:r})=\u003e{const s=IK([...t,...e],r),a=new tc({inputHdRoutes:t,otherHdRoutes:e,netByConnectionName:s,obstacles:n,colorMap:o,layerCount:i,connMap:r});if(a.solve(),a.failed)throw new Error(`Pipeline9 could not merge movable preloaded vias: ${a.error??\"unknown error\"}`);return a.getMergedViaHdRoutes()??t},C9=({errors:t,circuitJson:e,newTraceIds:n})=\u003e{const o=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.map(t=\u003e{const e=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,i=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],r=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]].filter((t,e,n)=\u003en.indexOf(t)===e);if(e\u0026\u0026\"string\"==typeof t.pcb_trace_error_id){const s=`overlap_${e}_`,a=t.pcb_trace_error_id.startsWith(s)?t.pcb_trace_error_id.slice(s.length):void 0,c=void 0!==a\u0026\u0026(r.includes(a)||o.has(a)\u0026\u0026!i.includes(a)),l=i.find(t=\u003et!==e\u0026\u0026n.has(t))??(a\u0026\u0026!c?a:void 0);if(!n.has(e)\u0026\u00260===r.length\u0026\u0026l\u0026\u0026n.has(l)){const n=[l,e,...i].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,pcb_trace_id:l,pcb_trace_ids:n,pcb_trace_error_id:`overlap_${l}_${e}`}}}const s=r.flatMap(t=\u003e{const e=o.get(t);return e?[e]:[]}).filter((t,e,n)=\u003en.indexOf(t)===e),a=s.length\u003e0?s:i.filter(t=\u003et!==e),c=a.find(t=\u003en.has(t));if(c\u0026\u0026(!e||!n.has(e))){const n=[c,...e?[e]:[],...i,...a].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,pcb_trace_id:c,pcb_trace_ids:n,pcb_via_id:r[0],pcb_via_ids:r}}if(r.length\u003e0){const n=[...e?[e]:[],...i,...a].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,pcb_trace_ids:n,pcb_via_id:r[0],pcb_via_ids:r}}return t})},P9=1e-9,M9=t=\u003e{const e=new Set,n=[];for(const o of t)for(const t of o.route){if(\"via\"!==t.route_type)continue;const i=`${t.x},${t.y},${t.from_layer},${t.to_layer}`;e.has(i)||(e.add(i),n.push({type:\"pcb_via\",pcb_via_id:`via_${n.length}`,pcb_trace_id:o.pcb_trace_id}))}return n},N9=({errors:t,circuitJson:e,evaluatedTraceIds:n})=\u003e{const o=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.map(t=\u003e{const e=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]],i=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,r=i?`overlap_${i}_`:void 0,s=r\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(r)?t.pcb_trace_error_id.slice(r.length):void 0,a=\"string\"==typeof t.pcb_trace_error_id?t.pcb_trace_error_id.match(/_(via_\\d+)$/)?.[1]:void 0,c=0!==e.length||!a||!o.has(a)||s\u0026\u0026n.has(s)?void 0:a,l=[...e,...c?[c]:[]].filter((t,e,n)=\u003en.indexOf(t)===e),d=[...\"string\"==typeof t.pcb_trace_id?[t.pcb_trace_id]:[],...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],...l.flatMap(t=\u003e{const e=o.get(t);return e?[e]:[]})].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,...l.length\u003e0?{pcb_via_id:l[0],pcb_via_ids:l}:{},...l.length\u003e0\u0026\u0026d.length\u003e0?{pcb_trace_ids:d}:{}}})},w9=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=P9\u0026\u0026Math.abs(t.y-e.y)\u003c=P9\u0026\u0026t.z===e.z,T9=({trace:t,sectionGroup:e,syntheticConnectionName:n,connMap:o})=\u003e{const i=e.routes;if(0===i.length)throw new Error(`Pipeline9 cannot exactly repair empty preloaded section for trace \"${t.pcb_trace_id}\"`);const r=[];for(const e of i){if(0===r.length){r.push(...e.route);continue}const n=r.at(-1);if(e.route[0]\u0026\u0026w9(n,e.route[0]))r.push(...e.route.slice(1));else{if(!e.route.at(-1)||!w9(n,e.route.at(-1)))throw new Error(`Pipeline9 cannot reconnect preloaded trace \"${t.pcb_trace_id}\" for exact repair`);r.push(...e.route.slice(0,-1).reverse())}}const s=0===e.routePositionStart,a=e.routePositionEnd===t.route.length-1,c=s?t.connectsTo?.[0]:null,l=a?t.connectsTo?.at(-1):null;return c\u0026\u0026r[0]\u0026\u0026(r[0]={...r[0],pcb_port_id:c}),l\u0026\u0026r.at(-1)\u0026\u0026(r[r.length-1]={...r.at(-1),pcb_port_id:l}),{connectionName:n,rootConnectionName:o.getNetConnectedToId(t.connection_name)??t.connection_name,traceThickness:Math.max(...i.map(t=\u003et.traceThickness)),viaDiameter:Math.max(...i.map(t=\u003et.viaDiameter)),route:r,vias:r.slice(0,-1).flatMap((t,e)=\u003e{const n=r[e+1];return t.z!==n.z\u0026\u0026(o=t,i=n,Math.abs(o.x-i.x)\u003c=P9\u0026\u0026Math.abs(o.y-i.y)\u003c=P9)?[{x:n.x,y:n.y}]:[];var o,i})}},R9=({trace:t,traceIndex:e,layerCount:n,defaultViaDiameter:o,connMap:i})=\u003e{const r=t.route.flatMap((t,e)=\u003e\"through_obstacle\"===t.route_type?[e]:[]),s=new Map,a=oQ(t,e,n,o,i);for(const e of a){const n=e.preloadedRoutePositionStart,o=e.preloadedRoutePositionEnd;if(void 0===n||void 0===o)throw new Error(`Pipeline9 preloaded trace section is missing route positions for \"${t.pcb_trace_id}\"`);if(\"through_obstacle\"===t.route[n]?.route_type)continue;const i=r.filter(t=\u003et\u003cn).length,a=s.get(i)??{routePositionStart:n,routePositionEnd:o,routes:[]};a.routePositionStart=Math.min(a.routePositionStart,n),a.routePositionEnd=Math.max(a.routePositionEnd,o),a.routes.push(e),s.set(i,a)}return[...s.values()]},E9=(t,e)=\u003et.map(t=\u003e{const n=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],o=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,i=o?`overlap_${o}_`:void 0,r=i\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0,s=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]],a=void 0!==r\u0026\u0026s.includes(r),c=[o,...n,a?void 0:r].filter(t=\u003e\"string\"==typeof t),l=new Map;for(const t of c){const n=e.get(t)??t,o=l.get(n)??new Set;o.add(t),l.set(n,o)}const d=[...l].flatMap(([t,e])=\u003ee.size\u003e1?[{solverTraceId:t,evaluationTraceIds:[...e]}]:[]),h=o?e.get(o)??o:void 0,u=n.map(t=\u003ee.get(t)??t),p=r?a?r:e.get(r)??r:void 0;return h!==o||u.some((t,e)=\u003et!==n[e])||p!==r?{...t,...o?{pcb_trace_id:h}:{},...Array.isArray(t.pcb_trace_ids)?{pcb_trace_ids:u}:{},...h\u0026\u0026p?{pcb_trace_error_id:`overlap_${h}_${p}`}:{},...d.length\u003e0?{__collapsed_trace_participants:d}:{}}:t}),A9=(t,e)=\u003e{const n=t.hdRoute.route[0],o=t.hdRoute.route.at(-1);return{name:t.syntheticConnectionName,rootConnectionName:t.hdRoute.rootConnectionName,__netConnectionName:t.originalTrace.connection_name,nominalTraceWidth:t.hdRoute.traceThickness,pointsToConnect:[{x:n.x,y:n.y,layer:vo(n.z,e),pointId:`${t.syntheticConnectionName}:start`},{x:o.x,y:o.y,layer:vo(o.z,e),pointId:`${t.syntheticConnectionName}:end`}]}},O9=({originalTrace:t,repairedSections:e})=\u003e{const n=[];let o=0;for(const i of[...e].sort((t,e)=\u003et.routePositionStart-e.routePositionStart)){if(i.routePositionStart\u003co)throw new Error(`Pipeline9 found overlapping repaired sections for preloaded trace \"${t.pcb_trace_id}\"`);n.push(...t.route.slice(o,i.routePositionStart),...i.route),o=i.routePositionEnd+1}return n.push(...t.route.slice(o)),{...t,__replaces_pcb_trace_id:t.pcb_trace_id,route:n}},k9=class extends si{params;inputNewHdRoutes;inputUpdatedPreloadedTraces;movablePreloadedSections;fixedPreloadedObstacleRoutes;syntheticConnectionNames;exactRepairSolver;drcEvaluator;cachedReferenceDrcEvaluator;clearancePrecisionDrcEvaluator;clearancePrecisionIndexedDrcEvaluator;clearanceMarginDrcEvaluator;referenceDrcValidationCount=0;referenceDrcFalseNegativeCount=0;indexedDrcEvaluationCount=0;indexedDrcCacheHitCount=0;indexedDrcEvaluationTimeMs=0;indexedDrcCandidateCache=new Map;combinedOutput;cacheIndexedDrcResult(t,e){if(this.indexedDrcCandidateCache.size\u003e=64){const t=this.indexedDrcCandidateCache.keys().next().value;void 0!==t\u0026\u0026this.indexedDrcCandidateCache.delete(t)}this.indexedDrcCandidateCache.set(t,e)}constructor(t){super(),this.params=t,this.inputNewHdRoutes=t.newHdRoutes,this.inputUpdatedPreloadedTraces=t.updatedPreloadedTraces;const e=t.updatedPreloadedTraces.filter(e=\u003et.mutatedPreloadedTraceIds.has(e.pcb_trace_id)),n=ZJ({connections:t.newConnections,originalConnections:t.originalSrj.connections,layerCount:t.layerCount,obstacles:t.obstacles,defaultViaHoleDiameter:t.defaultViaHoleDiameter,connMap:t.connMap}),o=n(t.newHdRoutes),i=new Set(o.map(t=\u003et.pcb_trace_id)),r=(({originalPreloadedTraces:t,mutatedPreloadedTraces:e,newTraces:n})=\u003e{const o=new Set(n.map(t=\u003et.pcb_trace_id)),i=new Map(e.map(t=\u003e[t.pcb_trace_id,t])),r=new Set([...t.map(t=\u003et.pcb_trace_id),...o]),s=new Map;return{routedTraces:[...t.filter(t=\u003eo.has(t.pcb_trace_id)).map(t=\u003e{const e=i.get(t.pcb_trace_id)??t,n=`${t.pcb_trace_id}_preloaded`;let o=n,a=2;for(;r.has(o);)o=`${n}_${a}`,a+=1;return r.add(o),s.set(o,t.pcb_trace_id),{...e,pcb_trace_id:o,__replaces_pcb_trace_id:t.pcb_trace_id}}),...e.filter(t=\u003e!o.has(t.pcb_trace_id)),...n],originalPreloadedTraceIdByPreparedTraceId:s}})({originalPreloadedTraces:t.originalSrj.traces??[],mutatedPreloadedTraces:e,newTraces:o}),s=t.originalSrj.minTraceToPadEdgeClearance??V0.traceClearance??.1,a=V0.viaClearance??.1,c=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:[],drcOptions:{traceClearance:s}}),l=new Set((t.originalSrj.traces??[]).map(t=\u003et.pcb_trace_id)),d=N9({errors:c.errors,circuitJson:c.circuitJson,evaluatedTraceIds:l}),h=N9({errors:c.errorsWithCenters,circuitJson:c.circuitJson,evaluatedTraceIds:l}),u=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:r.routedTraces,drcOptions:{traceClearance:s}}),p=new Set(o1(t.originalSrj.traces??[],r.routedTraces).map(t=\u003et.pcb_trace_id)),m=N9({errors:u.errors,circuitJson:u.circuitJson,evaluatedTraceIds:p}),g=N9({errors:u.errorsWithCenters,circuitJson:u.circuitJson,evaluatedTraceIds:p}),f={...u,errors:x9({errors:m,baselineErrors:d,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId}),errorsWithCenters:x9({errors:g,baselineErrors:h,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId})},y=(({errors:t,circuitJson:e})=\u003e{const n=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[])),o=new Set;for(const e of t){const t=\"string\"==typeof e.pcb_trace_id?e.pcb_trace_id:void 0,i=[...\"string\"==typeof e.pcb_via_id?[e.pcb_via_id]:[],...Array.isArray(e.pcb_via_ids)?e.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]];if(\"string\"==typeof e.pcb_trace_id\u0026\u0026o.add(e.pcb_trace_id),Array.isArray(e.pcb_trace_ids))for(const t of e.pcb_trace_ids)\"string\"==typeof t\u0026\u0026o.add(t);if(\"string\"==typeof e.pcb_via_id){const t=n.get(e.pcb_via_id);t\u0026\u0026o.add(t)}if(Array.isArray(e.pcb_via_ids))for(const t of e.pcb_via_ids){if(\"string\"!=typeof t)continue;const e=n.get(t);e\u0026\u0026o.add(e)}const r=t?`overlap_${t}_`:void 0;if(r\u0026\u0026\"string\"==typeof e.pcb_trace_error_id\u0026\u0026e.pcb_trace_error_id.startsWith(r)){const t=e.pcb_trace_error_id.slice(r.length);i.includes(t)||o.add(t)}}return o})({errors:f.errors,circuitJson:f.circuitJson}),_=new Map(t.updatedPreloadedTraces.map(t=\u003e[t.pcb_trace_id,t])),b=new Set;for(const t of y){const e=r.originalPreloadedTraceIdByPreparedTraceId.get(t);e\u0026\u0026_.has(e)?b.add(e):!i.has(t)\u0026\u0026_.has(t)\u0026\u0026b.add(t)}for(const e of S9({errorsWithCenters:f.errorsWithCenters,traces:t.updatedPreloadedTraces,layerCount:t.layerCount,defaultViaDiameter:t.defaultViaDiameter,connMap:t.connMap}))b.add(e);this.movablePreloadedSections=[];for(const e of b){const n=_.get(e);if(!n)throw new Error(`Pipeline9 cannot find preloaded trace \"${e}\" selected for exact repair`);const o=t.updatedPreloadedTraces.findIndex(t=\u003et.pcb_trace_id===e),i=R9({trace:n,traceIndex:o,layerCount:t.layerCount,defaultViaDiameter:t.defaultViaDiameter,connMap:t.connMap});for(const[e,o]of i.entries()){const i=`pipeline9_preloaded_drc_${this.movablePreloadedSections.length}`;this.movablePreloadedSections.push({originalTrace:n,originalRoutePositionStart:o.routePositionStart,originalRoutePositionEnd:o.routePositionEnd,syntheticConnectionName:i,evaluationTraceId:`${n.pcb_trace_id}__pipeline9_section_${e}`,hdRoute:T9({trace:n,sectionGroup:o,syntheticConnectionName:i,connMap:t.connMap})})}}this.syntheticConnectionNames=new Set(this.movablePreloadedSections.map(t=\u003et.syntheticConnectionName));const x=new Set(this.movablePreloadedSections.map(t=\u003et.originalTrace.pcb_trace_id));this.fixedPreloadedObstacleRoutes=t.updatedPreloadedTraces.flatMap((e,n)=\u003e{const o=oQ(e,n,t.layerCount,t.defaultViaDiameter,t.connMap);return x.has(e.pcb_trace_id)?o.filter(t=\u003e{const n=t.preloadedRoutePositionStart;return void 0!==n\u0026\u0026\"through_obstacle\"===e.route[n]?.route_type}):o});const v=new Map;for(const[t,e]of this.movablePreloadedSections.entries()){const n=e.originalTrace.pcb_trace_id,o=v.get(n)??[];o.push(t),v.set(n,o)}for(const e of(({errors:t,circuitJson:e,originalTraceIdByPreparedTraceId:n})=\u003e{const o=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.flatMap(t=\u003e{if(\"pcb_via_clearance_error\"!==t.type||!Array.isArray(t.pcb_via_ids)||\"number\"!=typeof t.actual_clearance||t.actual_clearance\u003e=0)return[];const e=t.pcb_via_ids.flatMap(t=\u003e{if(\"string\"!=typeof t)return[];const e=o.get(t);return e?[n.get(e)??e]:[]}).filter((t,e,n)=\u003en.indexOf(t)===e);return e.length\u003e0?[e]:[]})})({errors:f.errors,circuitJson:f.circuitJson,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId})){const n=e.flatMap(t=\u003ev.get(t)??[]).filter((t,e,n)=\u003en.indexOf(t)===e);if(0===n.length)continue;const o=new Set(n),i=I9({routes:n.map(t=\u003ethis.movablePreloadedSections[t].hdRoute),otherHdRoutes:[...t.newHdRoutes,...this.fixedPreloadedObstacleRoutes,...this.movablePreloadedSections.flatMap((t,e)=\u003eo.has(e)?[]:[t.hdRoute])],obstacles:t.obstacles,colorMap:t.colorMap,layerCount:t.layerCount,connMap:t.connMap});for(let t=0;t\u003cn.length;t++)this.movablePreloadedSections[n[t]].hdRoute=i[t]}if(this.stats={initialJointDrcIssueCount:f.errors.length,baselineJointDrcIssueCount:c.errors.length,initialJointDrcIssueCountByType:f.errors.reduce((t,e)=\u003e{const n=String(e.type??e.error_type??\"unknown\");return t[n]=(t[n]??0)+1,t},{}),movablePreloadedTraceCount:x.size,movablePreloadedSectionCount:this.movablePreloadedSections.length,exactRepairConfiguredMaxIterations:32,exactRepairConfiguredViaInPadMaxIterations:32,exactRepairConfiguredBroadMaxIterations:12},0===f.errors.length)return void(this.solved=!0);const S=new Set(this.movablePreloadedSections.map(t=\u003et.originalTrace.pcb_trace_id)),I=e.filter(t=\u003e!S.has(t.pcb_trace_id)),C=new Map(this.movablePreloadedSections.map(e=\u003e[e.syntheticConnectionName,A9(e,t.layerCount)])),{traces:P,...M}=t.srjWithPointPairs,N={...M,connections:[...t.srjWithPointPairs.connections,...C.values()]},w=new s_({...N,obstacles:t.originalSrj.obstacles,minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter??t.defaultViaDiameter},{connMap:t.connMap,traceClearance:s,viaClearance:a,includeTraceViaOwnerMetadata:!0,spatialCellSize:Math.max(t.defaultViaDiameter,t.originalSrj.minTraceWidth)+Math.max(s,a)}),T=w.evaluate(t.originalSrj.traces??[]),R=M9(t.originalSrj.traces??[]),E={...T,errors:N9({errors:T.errors,circuitJson:R,evaluatedTraceIds:l}),errorsWithCenters:N9({errors:T.errorsWithCenters,circuitJson:R,evaluatedTraceIds:l})};let A;const O=e=\u003e{const o=e.filter(t=\u003e!this.syntheticConnectionNames.has(t.connectionName)),i=n(o),r=vK(i,t.originalSrj.traces??[]),s=new Set,a=new Map,c=this.movablePreloadedSections.map(n=\u003e{const o=e.find(t=\u003et.connectionName===n.syntheticConnectionName);if(!o)throw new Error(`Pipeline9 joint DRC repair lost preloaded section \"${n.syntheticConnectionName}\"`);const i=n.originalTrace.pcb_trace_id;a.set(n.evaluationTraceId,i);const r=!s.has(i);return s.add(i),{...n.originalTrace,pcb_trace_id:n.evaluationTraceId,...r?{__replaces_pcb_trace_id:i}:{__replaces_pcb_trace_id:void 0},route:Mo(o,t.layerCount,{defaultViaHoleDiameter:t.defaultViaHoleDiameter,obstacles:t.obstacles,connMap:t.connMap})}}),l=new Map;for(let t=0;t\u003ci.length;t++)l.set(r[t].pcb_trace_id,i[t].pcb_trace_id);for(const t of this.movablePreloadedSections)l.set(t.evaluationTraceId,`${t.syntheticConnectionName}_0`);const d=new Set(l.values()),h=[...I,...c,...r];return{evaluatedTraces:o1(t.originalSrj.traces??[],h),movableTraceIds:d,originalTraceIdByEvaluationTraceId:a,routedTraces:h,solverTraceIdByEvaluationTraceId:l}},k=({errors:t,errorsWithCenters:e,circuitJson:n,movableTraceIds:o,solverTraceIdByEvaluationTraceId:i})=\u003e{const r=n.map(t=\u003e{if(!(\"pcb_trace_id\"in t)||\"string\"!=typeof t.pcb_trace_id)return t;const e=i.get(t.pcb_trace_id);return e?{...t,pcb_trace_id:e}:t});return{errors:C9({errors:E9(t,i),circuitJson:r,newTraceIds:o}),errorsWithCenters:C9({errors:E9(e,i),circuitJson:r,newTraceIds:o})}},L=({routes:e,hdRoutes:n},o=!0)=\u003e{const i=e??n;if(!i)throw new Error(\"Pipeline9 reference DRC repair requires HD routes\");const r=O(i),a=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:r.routedTraces,drcOptions:{traceClearance:s,includeTraceContinuity:o}}),c=new Set(r.evaluatedTraces.map(t=\u003et.pcb_trace_id)),l=N9({errors:a.errors,circuitJson:a.circuitJson,evaluatedTraceIds:c}),u=N9({errors:a.errorsWithCenters,circuitJson:a.circuitJson,evaluatedTraceIds:c}),p=x9({errors:l,baselineErrors:d,originalTraceIdByPreparedTraceId:r.originalTraceIdByEvaluationTraceId}),m=x9({errors:u,baselineErrors:h,originalTraceIdByPreparedTraceId:r.originalTraceIdByEvaluationTraceId});return k({errors:p,errorsWithCenters:m,circuitJson:a.circuitJson,movableTraceIds:r.movableTraceIds,solverTraceIdByEvaluationTraceId:r.solverTraceIdByEvaluationTraceId})},D=({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline9 cached reference DRC requires HD routes\");const o=JSON.stringify(n);if(A?.candidateKey===o)return A.result;this.referenceDrcValidationCount+=1;const i=L({traces:[],routes:n,hdRoutes:n});return A={candidateKey:o,result:i},i};this.cachedReferenceDrcEvaluator=D,this.clearancePrecisionDrcEvaluator=({routes:t,hdRoutes:e})=\u003eL({traces:[],routes:t,hdRoutes:e},!1);const z=e=\u003e{const n=O(e);return n1(t.srjWithPointPairs,n.routedTraces,{minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter,originalSrj:t.originalSrj,includeOriginalConnections:!0})};let F;this.clearanceMarginDrcEvaluator=(t,e,n)=\u003e(F?.routes!==n\u0026\u0026(F={routes:n,circuitJson:z(n)}),(({circuitJson:t,originalCircuitJson:e,targets:n})=\u003e{const o=new Map(t.filter(t=\u003e\"pcb_trace\"===t.type).map(t=\u003e[t.pcb_trace_id,t])),i=new Map(e.filter(t=\u003e\"pcb_trace\"===t.type).map(t=\u003e[t.pcb_trace_id,t])),r=t.filter(t=\u003e\"pcb_via\"===t.type),s=new Map;for(const e of t)\"pcb_via\"===e.type?s.set(e.pcb_via_id,e):\"pcb_smtpad\"===e.type?s.set(e.pcb_smtpad_id,e):\"pcb_plated_hole\"===e.type\u0026\u0026s.set(e.pcb_plated_hole_id,e);const a=[];for(const t of n){const n=\"pcb_via_trace_clearance_error\"===t.type,c=n?t.pcb_via_id:t.pcb_pad_id;if(!n\u0026\u0026\"pcb_pad_trace_clearance_error\"!==t.type||\"string\"!=typeof t.pcb_trace_id||\"string\"!=typeof c||\"number\"!=typeof t.minimum_clearance||!Number.isFinite(t.minimum_clearance)||t.minimum_clearance\u003c=0)throw new Error(\"Pipeline9 clearance margin requires a valid target pair\");const l=i.get(t.pcb_trace_id),d=e.find(t=\u003en?\"pcb_via\"===t.type\u0026\u0026t.pcb_via_id===c:\"pcb_smtpad\"===t.type\u0026\u0026t.pcb_smtpad_id===c||\"pcb_plated_hole\"===t.type\u0026\u0026t.pcb_plated_hole_id===c);if(!l||!d)throw new Error(`Pipeline9 clearance margin has no original target ${c}/${t.pcb_trace_id}`);const h=o.get(t.pcb_trace_id);let u=s.get(c);if(n){if(\"pcb_via\"!==d.type||\"string\"!=typeof d.pcb_trace_id)throw new Error(\"Pipeline9 clearance margin requires the original via owner\");const t=i.get(d.pcb_trace_id);if(!t)throw new Error(\"Pipeline9 clearance margin lost the original via owner\");const e=t.route.filter(t=\u003e\"via\"===t.route_type),n=e.map((t,e)=\u003e({segment:t,index:e})).filter(({segment:t})=\u003et.x===d.x\u0026\u0026t.y===d.y\u0026\u0026d.layers.includes(t.from_layer)\u0026\u0026d.layers.includes(t.to_layer)\u0026\u0026(t.from_layer===d.layers[0]\u0026\u0026t.to_layer===d.layers.at(-1)||t.to_layer===d.layers[0]\u0026\u0026t.from_layer===d.layers.at(-1))).filter(({segment:t},e,n)=\u003en.findIndex(e=\u003ee.segment.from_layer===t.from_layer\u0026\u0026e.segment.to_layer===t.to_layer)===e);if(0===n.length)throw new Error(\"Pipeline9 clearance margin lost the original via transition\");if(1!==n.length)return{status:\"unsupported-identity\"};const s=n[0].index,a=o.get(d.pcb_trace_id),c=a?.route.filter(t=\u003e\"via\"===t.route_type);if(!c||c.length!==e.length||c.some((t,n)=\u003et.from_layer!==e[n].from_layer||t.to_layer!==e[n].to_layer))return{status:\"unsupported-identity\"};const l=c[s];u=r.filter(t=\u003et.x===l.x\u0026\u0026t.y===l.y\u0026\u0026t.layers.join()===d.layers.join()).reduce((t,e)=\u003e!t||e.outer_diameter\u003et.outer_diameter?e:t,void 0)}if(!(h\u0026\u0026u\u0026\u0026\"x\"in u\u0026\u0026\"y\"in u))return{status:\"unsupported-identity\"};const p={minClearance:t.minimum_clearance+1},m=n?Y0([h,u],p):$0([h,u],p),g=t.minimum_clearance+.01;for(const e of m){const n=e.actual_clearance;if(\"number\"!=typeof n||!Number.isFinite(n))throw new Error(\"Pipeline9 clearance margin requires a finite measurement\");n\u003e=g||a.push({...t,...\"pcb_via\"===u.type?{pcb_via_id:u.pcb_via_id,pcb_via_ids:[u.pcb_via_id]}:{},actual_clearance:n,minimum_clearance:g,center:{x:u.x,y:u.y}})}}return{status:\"measured\",errors:a}})({circuitJson:z(t),originalCircuitJson:F.circuitJson,targets:e})),this.clearancePrecisionIndexedDrcEvaluator=({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline9 clearance ranking requires HD routes\");const o=O(n);return w.evaluate(o.evaluatedTraces)};const B=({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline9 joint DRC repair requires HD routes\");const o=JSON.stringify(n),i=this.indexedDrcCandidateCache.get(o);if(void 0!==i)return this.indexedDrcCacheHitCount+=1,i;const r=performance.now();this.indexedDrcEvaluationCount+=1;const s=O(n),a=w.evaluate(s.evaluatedTraces),c=M9(s.evaluatedTraces),l=new Set(s.evaluatedTraces.map(t=\u003et.pcb_trace_id)),d=N9({errors:a.errors,circuitJson:c,evaluatedTraceIds:l}),h=N9({errors:a.errorsWithCenters,circuitJson:c,evaluatedTraceIds:l}),u=x9({errors:d,baselineErrors:E.errors,originalTraceIdByPreparedTraceId:s.originalTraceIdByEvaluationTraceId}),p=x9({errors:h,baselineErrors:E.errorsWithCenters,originalTraceIdByPreparedTraceId:s.originalTraceIdByEvaluationTraceId});if(0===u.length){const t=this.referenceDrcValidationCount,e=D({traces:[],routes:n,hdRoutes:n}),i=Array.isArray(e)?e:e.errors;return this.referenceDrcValidationCount\u003et\u0026\u0026i.length\u003e0\u0026\u0026(this.referenceDrcFalseNegativeCount+=1),this.indexedDrcEvaluationTimeMs+=performance.now()-r,this.cacheIndexedDrcResult(o,e),e}const m=k({errors:u,errorsWithCenters:p,circuitJson:c,movableTraceIds:s.movableTraceIds,solverTraceIdByEvaluationTraceId:s.solverTraceIdByEvaluationTraceId});return this.indexedDrcEvaluationTimeMs+=performance.now()-r,this.cacheIndexedDrcResult(o,m),m};this.drcEvaluator=B,this.exactRepairSolver=new wz({srj:N,hdRoutes:[...t.newHdRoutes,...this.movablePreloadedSections.map(t=\u003et.hdRoute)],connMap:t.connMap,effort:t.effort,viaHoleDiameter:t.defaultViaHoleDiameter,drcEvaluator:B,viaInPadDrcEvaluator:B,maxIterations:32,enableBroadFallback:!1,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!0,enableTraceViaOwnerTargeting:!0,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:t.originalSrj.allowViaInPad??!1,viaInPadMaxIterations:32,broadMaxIterations:12,broadPassMultiplier:3}),this.activeSubSolver=this.exactRepairSolver,this.MAX_ITERATIONS=this.exactRepairSolver.MAX_ITERATIONS+1}getSolverName(){return\"Pipeline9JointDrcRepairSolver\"}_step(){if(!this.exactRepairSolver)return void(this.solved=!0);if(this.exactRepairSolver.step(),this.progress=this.exactRepairSolver.progress,this.exactRepairSolver.failed)return this.failed=!0,void(this.error=this.exactRepairSolver.error);if(!this.exactRepairSolver.solved)return;let t=this.exactRepairSolver.getOutput();const e=this.exactRepairSolver.stats.finalDrcIssueCount,n=\"number\"==typeof e\u0026\u0026Number.isFinite(e)\u0026\u0026e\u003e=0?e:void 0;let o,i=0,r=0,s=0,a=!1;const c=this.cachedReferenceDrcEvaluator({traces:[],routes:t,hdRoutes:t}),l=Array.isArray(c)?c:c.errors;if(o=l.length,l.length\u003e0){const e=(({srj:t,routes:e,newConnections:n,syntheticConnectionNames:o,connMap:i,indexedDrcEvaluator:r,candidateDrcEvaluator:s,marginDrcEvaluator:a,drcEvaluator:c,initialErrors:l,initialErrorsWithCenters:d=l})=\u003e{const h={routes:e,attemptedCandidateCount:0,candidateValidationCount:0,referenceValidationCount:0,repaired:!1};if((t.traces?.length??0)\u003e0||o.size\u003e0)return h;if(0===l.length)return h;const u=d1({routes:e,newConnections:n,syntheticConnectionNames:o}),p=new Map;for(const e of t.obstacles)for(const t of[e.obstacleId,e.circuitJsonMetadata?.pcb_smtpad_id,e.circuitJsonMetadata?.pcb_plated_hole_id,e.connectedTo[0]])\"string\"==typeof t\u0026\u0026p.set(t,e.center);const m=p1({errors:l,errorsWithCenters:d,routeIndexByTraceId:u,padPositionById:p});if(!m)return h;let g=m;const f=m.errors,y=m.errors.map(t=\u003e({...t,minimum_clearance:t.minimum_clearance+.01})),_=u1(y);if(void 0===_)return h;let b={errors:y,deficit:_},x=e,v=0,S=0,I=0;for(let n=0;n\u003c8;n++){const n=new Map;for(const t of[...b.errors,...g.errors]){const e=JSON.stringify([t.type,t.pcb_trace_id,t.pcb_pad_id,t.pcb_via_id]);n.set(e,t)}const o=[...n.values()];let l;for(const e of h1){const n=kk(x);if(!$D(t,n,o,u,e,i,!0,!0,!0,!1))continue;const s=aD(n);v++;const a=r({traces:[],routes:s,hdRoutes:s}),c=u1(Array.isArray(a)?a:a.errors);void 0!==c\u0026\u0026(!l||c\u003cl.deficit)\u0026\u0026(l={routes:s,deficit:c})}if(!l)break;S++;const d=s({traces:[],routes:l.routes,hdRoutes:l.routes}),h=Array.isArray(d)?d:d.errors,m=p1({errors:h,errorsWithCenters:Array.isArray(d)?d:d.errorsWithCenters??d.errors,routeIndexByTraceId:u,padPositionById:p});if(!m)break;const y=a(l.routes,f,e);if(\"unsupported-identity\"===y.status)break;const _=y.errors,C=p1({errors:_,errorsWithCenters:_,routeIndexByTraceId:u,padPositionById:p});if(!C)break;if(0===h.length\u0026\u00260===_.length){I++;const t=c({traces:[],routes:l.routes,hdRoutes:l.routes});if(0===(Array.isArray(t)?t:t.errors).length)return{routes:l.routes,attemptedCandidateCount:v,candidateValidationCount:S,referenceValidationCount:I,repaired:!0};break}if(m.deficit+C.deficit\u003e=g.deficit+b.deficit-1e-9)break;x=l.routes,g=m,b=C}return{routes:e,attemptedCandidateCount:v,candidateValidationCount:S,referenceValidationCount:I,repaired:!1}})({srj:this.params.srj,routes:t,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,connMap:this.params.connMap,indexedDrcEvaluator:this.clearancePrecisionIndexedDrcEvaluator,candidateDrcEvaluator:this.clearancePrecisionDrcEvaluator,marginDrcEvaluator:this.clearanceMarginDrcEvaluator,drcEvaluator:this.cachedReferenceDrcEvaluator,initialErrors:l,initialErrorsWithCenters:Array.isArray(c)?c:c.errorsWithCenters??c.errors});i=e.attemptedCandidateCount,r=e.candidateValidationCount,s=e.referenceValidationCount,a=e.repaired,e.repaired\u0026\u0026(t=e.routes,o=0)}if(0===o)return this.combinedOutput=t,this.stats={...this.stats,...this.exactRepairSolver.stats,postExactIndexedDrcIssueCount:n,postExactReferenceValidationAttempted:!0,postExactReferenceDrcIssueCount:0,postExactReferenceAccepted:!0,clearancePrecisionCandidateCount:i,clearancePrecisionCandidateValidationCount:r,clearancePrecisionReferenceValidationCount:s,clearancePrecisionRepaired:a,boundedRegionalRepairAttemptedRegionCount:0,boundedRegionalRepairAcceptedRegionCount:0,boundedRegionalRepairCandidateAttemptCount:0,boundedRegionalRepairPathSearchNodeCount:0,boundedRegionalRepairReferenceValidationCount:0,boundedRegionalRepairRepaired:!1,boundedRegionalRepairTimeMs:0,regionalB01RepairCandidateCount:0,regionalB01RepairAcceptedCount:0,regionalB01RepairFallbackCandidateCount:0,regionalB01RepairCandidateSearchCount:0,regionalB01RepairCandidateSearchBudget:0,regionalB01RepairCandidateSearchBudgetExhausted:!1,regionalB01RepairSafeTraceLayerSkippedForBudget:!1,regionalB01RepairRemainingDrcIssueCount:0,regionalB01RepairPreloadEligibleDrcIssueCount:0,regionalB01RepairAttempted:!1,regionalB01RepairTraceIdCount:0,terminalEscapeCandidateCount:0,terminalEscapeAcceptedCount:0,referenceDrcValidationCount:this.referenceDrcValidationCount,referenceDrcFalseNegativeCount:this.referenceDrcFalseNegativeCount,indexedDrcEvaluationCount:this.indexedDrcEvaluationCount,indexedDrcCacheHitCount:this.indexedDrcCacheHitCount,indexedDrcEvaluationTimeMs:this.indexedDrcEvaluationTimeMs,indexedDrcCandidateCacheSize:this.indexedDrcCandidateCache.size,indexedDrcCandidateCacheCapacity:64},void(this.solved=!0);const d=f9({srj:this.params.srj,originalSrj:this.params.originalSrj,routes:t,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.drcEvaluator}),h=(({routes:t,newConnections:e,syntheticConnectionNames:n,fixedPreloadedObstacleRoutes:o,updatedPreloadedTraces:i})=\u003e{const r=new Set,s=Object.assign(new Set,{collidingFixedTraceIds:r}),a=d1({routes:t,newConnections:e,syntheticConnectionNames:n}),c=new Set;for(const[e,o]of a)n.has(t[o].connectionName)?s.add(e):c.add(e);for(const t of o){const e=i[t.preloadedTraceIndex];if(!e)throw new Error(`Pipeline9 fixed preload route has invalid trace index ${t.preloadedTraceIndex}`);c.has(e.pcb_trace_id)?r.add(e.pcb_trace_id):s.add(e.pcb_trace_id)}return s})({routes:d.routes,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,fixedPreloadedObstacleRoutes:this.fixedPreloadedObstacleRoutes,updatedPreloadedTraces:this.params.updatedPreloadedTraces}),u=a9({srj:this.params.srj,routes:d.routes,fixedObstacleRoutes:this.fixedPreloadedObstacleRoutes,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.drcEvaluator,initialErrors:d.remainingErrors,allowTracePairRepair:!0,preloadRepairTraceIds:h,connMap:this.params.connMap,colorMap:this.params.colorMap,viaDiameter:this.params.defaultViaDiameter,traceWidth:this.params.srj.minTraceWidth,obstacleMargin:this.params.srj.defaultObstacleMargin??this.params.srj.minTraceToPadEdgeClearance??.15,effort:this.params.effort}),p=performance.now(),m=(({originalSrj:t,routes:e,syntheticConnectionNames:n,drcEvaluator:o})=\u003e{const i={routes:e,attemptedRegionCount:0,acceptedRegionCount:0,candidateAttemptCount:0,pathSearchNodeCount:0,referenceValidationCount:0,initialDrcIssueCount:void 0,finalDrcIssueCount:void 0,repaired:!1};if(t.traces?.length||n.size\u003e0)return i;const r=Math.max(t.defaultObstacleMargin??.2,t.minTraceToPadEdgeClearance??0,t.minViaEdgeToPadEdgeClearance??0);let s=Math.max(t.minTraceWidth,t.minViaDiameter??0);for(const t of e){s=Math.max(s,t.traceThickness,t.viaDiameter);for(const e of t.route)s=Math.max(s,e.traceThickness??0)}const a=Math.max(.5,s+r),c=Z6.filter(t=\u003e!Number.isFinite(a)||2*a\u003ct);if(0===c.length)return i;let l=e,d=o({traces:[],routes:e,hdRoutes:e});i.referenceValidationCount++;let h=Array.isArray(d)?d:d.errors;if(i.initialDrcIssueCount=h.length,i.finalDrcIssueCount=h.length,0===h.length)return i;const u={...fX(t),traces:void 0},p=[];let m=new Map(P6({srj:u,routes:l}).map(t=\u003e[t.key,t.severity]));for(;i.attemptedRegionCount\u003c4;){const t=(Array.isArray(d)?d:d.errorsWithCenters??d.errors).map(t=\u003et.center??t.pcb_center).filter(t=\u003enull!==t\u0026\u0026\"object\"==typeof t\u0026\u0026\"x\"in t\u0026\u0026\"y\"in t\u0026\u0026\"number\"==typeof t.x\u0026\u0026\"number\"==typeof t.y\u0026\u0026Number.isFinite(t.x)\u0026\u0026Number.isFinite(t.y));let e;for(const n of c){const o=t.find(({x:t,y:e})=\u003e!p.some(({bounds:o,size:i})=\u003en===i\u0026\u0026t\u003e=o.minX\u0026\u0026t\u003c=o.maxX\u0026\u0026e\u003e=o.minY\u0026\u0026e\u003c=o.maxY));if(o){e={center:o,size:n};break}}if(!e)break;const{center:n,size:r}=e,s=j6({srj:u,routes:l,bounds:{minX:n.x-r/2,maxX:n.x+r/2,minY:n.y-r/2,maxY:n.y+r/2}});if(p.push({bounds:s.mutableBounds,size:r}),i.attemptedRegionCount++,0===s.routes.length)continue;const a=new A6({srj:s.srj,routes:s.routes,bounds:s.bounds,boundaryMargin:s.boundaryMargin,lockedPointIndices:s.lockedPointIndices,maxCandidates:256,maxCandidateAttempts:256,maxPathSearchNodes:U6,allowLayerChanges:!0,traceOnlyFirst:!1});if(a.solve(),a.failed)throw new Error(`Pipeline9 bounded regional repair failed: ${a.error}`);const{candidateAttempts:g,pathSearchNodes:f}=a.stats;if(!Number.isSafeInteger(g)||g\u003c0||g\u003e256||!Number.isSafeInteger(f)||f\u003c0||f\u003eU6)throw new Error(\"Pipeline9 bounded regional repair exceeded its work budget\");i.candidateAttemptCount+=g,i.pathSearchNodeCount+=f;const y=G6({routes:l,region:s,repairedRoutes:a.getOutput()});if(y.every((t,e)=\u003et===l[e]))continue;const _=P6({srj:u,routes:y});if(!_.every(({key:t,severity:e})=\u003em.has(t)\u0026\u0026e\u003c=m.get(t)+1e-8)||w6({srj:u,previousRoutes:l,routes:y}).length\u003e0)continue;const b=o({traces:[],routes:y,hdRoutes:y});i.referenceValidationCount++;const x=Array.isArray(b)?b:b.errors;if(!(x.length\u003e=h.length)\u0026\u0026(l=y,h=x,d=b,m=new Map(_.map(t=\u003e[t.key,t.severity])),i.acceptedRegionCount++,i.finalDrcIssueCount=h.length,0===h.length))return i.routes=l,i.repaired=!0,i}return i})({originalSrj:this.params.originalSrj,routes:u.routes,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.cachedReferenceDrcEvaluator});this.combinedOutput=m.routes,this.stats={...this.stats,...this.exactRepairSolver.stats,postExactIndexedDrcIssueCount:n,postExactReferenceValidationAttempted:!0,postExactReferenceDrcIssueCount:o,postExactReferenceAccepted:!1,clearancePrecisionCandidateCount:i,clearancePrecisionCandidateValidationCount:r,clearancePrecisionReferenceValidationCount:s,clearancePrecisionRepaired:a,boundedRegionalRepairAttemptedRegionCount:m.attemptedRegionCount,boundedRegionalRepairAcceptedRegionCount:m.acceptedRegionCount,boundedRegionalRepairCandidateAttemptCount:m.candidateAttemptCount,boundedRegionalRepairPathSearchNodeCount:m.pathSearchNodeCount,boundedRegionalRepairReferenceValidationCount:m.referenceValidationCount,boundedRegionalRepairRepaired:m.repaired,boundedRegionalRepairTimeMs:performance.now()-p,regionalB01RepairCandidateCount:u.attemptedCandidateCount,regionalB01RepairAcceptedCount:u.acceptedCandidateCount,regionalB01RepairFallbackCandidateCount:u.fallbackCandidateCount,regionalB01RepairCandidateSearchCount:u.candidateSearchCount,regionalB01RepairCandidateSearchBudget:u.candidateSearchBudget,regionalB01RepairCandidateSearchBudgetExhausted:u.candidateSearchBudgetExhausted,regionalB01RepairSafeTraceLayerSkippedForBudget:u.safeTraceLayerRepairSkippedForBudget,regionalB01RepairRemainingDrcIssueCount:u.remainingDrcIssueCount,regionalB01RepairPreloadEligibleDrcIssueCount:u.preloadEligibleDrcIssueCount,regionalB01RepairAttempted:u.preloadRepairAttempted,regionalB01RepairTraceIdCount:h.size+(h.collidingFixedTraceIds?.size??0),terminalEscapeCandidateCount:d.attemptedCandidateCount,terminalEscapeAcceptedCount:d.acceptedCandidateCount,referenceDrcValidationCount:this.referenceDrcValidationCount,referenceDrcFalseNegativeCount:this.referenceDrcFalseNegativeCount,indexedDrcEvaluationCount:this.indexedDrcEvaluationCount,indexedDrcCacheHitCount:this.indexedDrcCacheHitCount,indexedDrcEvaluationTimeMs:this.indexedDrcEvaluationTimeMs,indexedDrcCandidateCacheSize:this.indexedDrcCandidateCache.size,indexedDrcCandidateCacheCapacity:64},this.solved=!0}getCombinedOutput(){return this.combinedOutput??this.exactRepairSolver?.getOutput()??this.inputNewHdRoutes}getOutput(){return this.getCombinedOutput().filter(t=\u003e!this.syntheticConnectionNames.has(t.connectionName))}getUpdatedPreloadedTraces(){const t=new Map(this.getCombinedOutput().map(t=\u003e[t.connectionName,t])),e=new Map;for(const n of this.movablePreloadedSections){const o=t.get(n.syntheticConnectionName);if(!o)throw new Error(`Pipeline9 joint DRC repair output is missing \"${n.syntheticConnectionName}\"`);const i=n.originalTrace.pcb_trace_id,r=e.get(i)??[];r.push({routePositionStart:n.originalRoutePositionStart,routePositionEnd:n.originalRoutePositionEnd,route:Mo(o,this.params.layerCount,{defaultViaHoleDiameter:this.params.defaultViaHoleDiameter,obstacles:this.params.obstacles,connMap:this.params.connMap})}),e.set(i,r)}const n=new Map([...e].map(([t,e])=\u003e{const n=this.inputUpdatedPreloadedTraces.find(e=\u003ee.pcb_trace_id===t);if(!n)throw new Error(`Pipeline9 cannot find preloaded trace \"${t}\" while rebuilding repaired sections`);return[t,O9({originalTrace:n,repairedSections:e})]}));return this.inputUpdatedPreloadedTraces.map(t=\u003en.get(t.pcb_trace_id)??t)}getMutatedPreloadedTraces(){const t=new Set([...this.params.mutatedPreloadedTraceIds,...this.movablePreloadedSections.map(t=\u003et.originalTrace.pcb_trace_id)]);return this.getUpdatedPreloadedTraces().filter(e=\u003et.has(e.pcb_trace_id))}visualize(){return this.exactRepairSolver?.visualize()??{}}},L9=1e-6,D9=(t,e,n)=\u003e{const o=ko(t,n),i=ko(e,n);return Array.from({length:Math.abs(i-o)+1},(t,e)=\u003eMath.min(o,i)+e)},z9=t=\u003e\"wire\"===t.route_type,F9=(t,e,n)=\u003et.portPoints.filter(t=\u003et.availableZ.includes(n)\u0026\u0026!(t._preloadedTracePortAssignments??[]).some(t=\u003et.z===n\u0026\u0026t.fixedNetId!==e.fixedNetId)).map(t=\u003e({portPoint:t,distance:be(t,e.start,e.end)})).sort((t,e)=\u003et.distance-e.distance||t.portPoint.distToCentermostPortOnZ-e.portPoint.distToCentermostPortOnZ||t.portPoint.segmentPortPointId.localeCompare(e.portPoint.segmentPortPointId))[0]?.portPoint,B9=(t,e,n)=\u003e{t._preloadedFixedNetIds=[...new Set([...t._preloadedFixedNetIds??[],e.fixedNetId])].sort();const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.start.x)*o+(t.y-e.start.y)*i)/r)),a={traceId:e.traceId,fixedNetId:e.fixedNetId,routePosition:e.routePositionStart+s*(e.routePositionEnd-e.routePositionStart),tracePoint:{x:e.start.x+s*o,y:e.start.y+s*i},z:n},c=t._preloadedTracePortAssignments??[];c.some(t=\u003et.traceId===a.traceId\u0026\u0026t.fixedNetId===a.fixedNetId\u0026\u0026t.z===a.z\u0026\u0026Math.abs(t.routePosition-a.routePosition)\u003c=L9)||(t._preloadedTracePortAssignments=[...c,a].sort((t,e)=\u003et.traceId.localeCompare(e.traceId)||t.routePosition-e.routePosition||t.z-e.z))},j9=class extends si{constructor(t,e){super(),this.sharedEdgeSegments=t,this.srj=e,this.MAX_ITERATIONS=1,this.primitives=(t=\u003e{const e=[],n=ii(t);for(const o of t.traces??[]){if(!o.connection_name)throw new Error(`Preloaded trace \"${o.pcb_trace_id}\" is missing a connection name`);const i=n.getNetConnectedToId(o.connection_name)??o.connection_name;for(const[n,r]of o.route.entries())if(\"via\"===r.route_type)e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n,zLayers:D9(r.from_layer,r.to_layer,t.layerCount),start:r,end:r});else if(\"through_obstacle\"===r.route_type)e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n+1,zLayers:D9(r.from_layer,r.to_layer,t.layerCount),start:r.start,end:r.end});else if(\"jumper\"===r.route_type){const s=ko(r.layer,t.layerCount);for(const[t,a]of[r.start,r.end].entries())e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n+t,routePositionEnd:n+t,zLayers:[s],start:a,end:a})}for(let n=0;n\u003co.route.length-1;n++){const r=o.route[n],s=o.route[n+1];z9(r)\u0026\u0026z9(s)\u0026\u0026r.layer===s.layer\u0026\u0026e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n+1,zLayers:[ko(r.layer,t.layerCount)],start:r,end:s})}}return e})(e)}sharedEdgeSegments;srj;primitives;getSolverName(){return\"PreloadedTraceGraphSolver\"}_step(){for(const t of this.primitives)for(const e of this.sharedEdgeSegments)if(!(Ra(t.start,t.end,e.start,e.end)\u003eL9))for(const n of t.zLayers){if(!e.availableZ.includes(n))continue;const o=F9(e,t,n);o\u0026\u0026B9(o,t,n)}const t=this.sharedEdgeSegments.flatMap(t=\u003et.portPoints),e=t.filter(t=\u003e(t._preloadedFixedNetIds?.length??0)\u003e0);this.stats={preloadedTraceCount:this.srj.traces?.length??0,preloadedTraceShapeCount:this.primitives.length,inputBoundaryCount:this.sharedEdgeSegments.length,outputBoundaryCount:this.sharedEdgeSegments.length,inputPortCount:t.length,outputPortCount:t.length,preloadedPortCount:e.length,tracePortAssignmentCount:e.reduce((t,e)=\u003et+(e._preloadedTracePortAssignments?.length??0),0),topologyChanged:!1},this.solved=!0}getOutput(){if(!this.solved)throw new Error(\"PreloadedTraceGraphSolver has not solved yet\");return this.sharedEdgeSegments}},$9=class extends _X{_step(){const{traces:t,...e}=this.inputSrj,n=fX(e),o=fX(aX(yX(n)));this.outputSrj=void 0===t?o:{...o,traces:t},this.solved=!0}};function Y9(t){return new Set((t??[]).filter(t=\u003et._isComponentTopologyNode).map(t=\u003et.capacityMeshNodeId))}function X9(t,e){return t.nodeIds.some(t=\u003ee.has(t))}function V9({sharedEdgeSegments:t,componentCapacityMeshNodeIds:e}){return t.filter(t=\u003e!X9(t,e))}function W9(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var H9=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e;const n=fX(t);this.originalSrj=n,this.opts={...e};const o=this.opts;if(this.effort=o.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=o.maxNodeDimension??15,this.maxNodeRatio=o.maxNodeRatio??6,this.minNodeArea=o.minNodeArea??.1**2,this.visualizationTraceColorMode=o.visualizationTraceColorMode??\"layer\",this.setSimpleRouteJson(n),void 0===o.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,n=Math.max(t,e),i=o.targetMinCapacity??.5;o.capacityDepth=$s(n,i)}this.cacheProvider=void 0===o.cacheProvider?oo():null===o.cacheProvider?null:o.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;getSolverName(){return\"AutoroutingPipelineSolver9_PreloadedTraceGraph\"}preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;componentTopologyGeneratorSolver;topologyPlanningSolver;topologyMergingSolver;globalTopologyGeneratorSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;pipeline9JointDrcRepairSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;mutatedPreloadedTraceSimplificationSolver;lengthMatchingPostProcessingSolver;powerTraceExpansionSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;preloadedTraceGraphSolver;componentDetectionSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;visualizationTraceColorMode;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;sharedEdgeSegmentsWithNecessaryCrampedPortPoints;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[W9(\"preprocessSimpleRouteJsonSolver\",$9,t=\u003e[t.originalSrj,{traceColorMode:t.visualizationTraceColorMode}],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),W9(\"componentDetectionSolver\",UZ,t=\u003e[{inputSrj:t.srj}]),W9(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),W9(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),W9(\"topologyPlanningSolver\",_q,t=\u003e[{inputSrj:t.srjWithPointPairs,componentDetectionOutput:t.componentDetectionSolver.getOutput(),viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.topologyPlanningSolver.getOutput();t.globalTopologyGeneratorSolver=t.topologyPlanningSolver.globalTopologySolver,t.componentTopologyGeneratorSolver=new vq(t.topologyPlanningSolver)}}),W9(\"topologyMergingSolver\",fq,t=\u003e{const e=t.topologyPlanningSolver.getOutput();return[{layerCount:t.srj.layerCount,nodeGroups:[{groupId:\"global\",nodes:e.globalMeshNodes,isComponent:!1},...e.componentMeshNodes.map((t,e)=\u003e({groupId:`component-${e}`,nodes:t,isComponent:!0}))]}]},{onSolved:t=\u003e{t.capacityNodes=t.topologyMergingSolver.getOutput()}}),W9(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver.outputNodes}}),W9(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),W9(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),W9(\"necessaryCrampedPortPointSolver\",sf,t=\u003e{const e=Y9(t.capacityNodes);return[{capacityMeshNodes:t.capacityNodes.filter(t=\u003e!e.has(t.capacityMeshNodeId)),sharedEdgeSegments:V9({sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),componentCapacityMeshNodeIds:e}),simpleRouteJson:t.srjWithPointPairs}]},{onSolved:t=\u003e{const e=Y9(t.capacityNodes);t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints=function({originalSharedEdgeSegments:t,filteredSharedEdgeSegments:e,componentCapacityMeshNodeIds:n}){const o=new Map(e.map(t=\u003e[t.edgeId,t]));return t.map(t=\u003eX9(t,n)?t:o.get(t.edgeId)??t)}({originalSharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),filteredSharedEdgeSegments:t.necessaryCrampedPortPointSolver.getOutput(),componentCapacityMeshNodeIds:e})}}),W9(\"preloadedTraceGraphSolver\",j9,t=\u003e[t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints,t.srjWithPointPairs]),W9(\"portPointPathingSolver\",jj,t=\u003e{const e=t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints??t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,preserveTerminalPcbPortIds:!0,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0,USE_SELECTIVE_RERIP_ROUTING:!0,USE_PARTIAL_RIP_ROUTING_WITH_PRELOADED_TRACES:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),W9(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),W9(\"highDensityRouteSolver\",VQ,t=\u003e{const e=t.portPointPathingSolver;if(!e)throw new Error(\"Pipeline9 invariant violated: high-density routing requires the completed port-point pathing solver\");const n=e.getOutput(),o=t.uniformPortDistributionSolver?.getOutput()??[],i=n.nodesWithPortPoints,r=o.length\u003e0?o:i;t.highDensityNodePortPoints=structuredClone(r);const s=(t.originalSrj.traces??[]).flatMap((e,n)=\u003eoQ(e,n,t.originalSrj.layerCount,t.viaDiameter,t.connMap));return[{nodePortPoints:r,fixedHdRoutes:TK({traces:t.originalSrj.traces??[],fixedHdRoutes:s,sections:t.getChangedPreloadedTraceSections()}),connMap:t.connMap,colorMap:t.colorMap,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,viaToPadClearance:t.srj.minViaEdgeToPadEdgeClearance,effort:t.effort,includeBoardObstacles:!0,nodePfById:new Map(n.inputNodeWithPortPoints.map(t=\u003e[t.capacityMeshNodeId,e.computeNodePf(t)])),preserveTerminalPcbPortIds:!0}]}),W9(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:AK(t.highDensityRouteSolver.routes),colorMap:t.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),W9(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2,maxSampleEntries:80,connMap:t.connMap}]),W9(\"highDensityStitchSolver\",KY,t=\u003e[{connections:[...t.srjWithPointPairs.connections,...t.getChangedPreloadedTraceSections().map(t=\u003et.connection)],hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,preserveTerminalPcbPortIds:!0,preferSameLayerTerminalEndpoints:!0}]),W9(\"traceSimplificationSolver\",vc,t=\u003e{const e=t.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces.flatMap((e,n)=\u003eoQ(e,n,t.originalSrj.layerCount,t.viaDiameter,t.connMap).map(t=\u003e({...t,rootConnectionName:e.connection_name}))),n=new Set(t.getChangedPreloadedTraceSections().map(t=\u003et.connectionName)),o=t.highDensityStitchSolver.mergedHdRoutes.filter(t=\u003e!n.has(t.connectionName)),i=IK([...o,...e],t.connMap);return[{hdRoutes:o,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,otherHdRoutes:e,netByConnectionName:i,enableCrossingViaReduction:!0,terminalLayerIndicesByPcbPortId:SK(t.srj.connections,t.srj.obstacles,t.srj.layerCount),iterations:2}]}),W9(\"mutatedPreloadedTraceSimplificationSolver\",vc,t=\u003e{const e=t.getPreparedMutatedPreloadedTraceSections(),n=e.sections.map(t=\u003et.hdRoute),o=[...e.immutableHdRoutes,...t.traceSimplificationSolver.simplifiedHdRoutes];return[{hdRoutes:n,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,otherHdRoutes:o,netByConnectionName:IK([...n,...o],t.connMap),enableCrossingViaReduction:!0,preserveRouteEndpoints:!0,iterations:2}]}),W9(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srjWithPointPairs.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),W9(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.getSrjWithMaterializedPreloadedTraces(),hdRoutes:KJ(t.traceWidthSolver.getHdRoutesWithWidths(),t.netToPointPairsSolver?.newConnections??[],new Map((t.highDensityStitchSolver?.mergedHdRoutes??[]).map(t=\u003e[t.connectionName,t]))),connMap:t.connMap,effort:t.effort,maxIterations:16,enableLargeBoardBroadFallback:!1,enablePostSolveClearanceRelaxation:!1}]),W9(\"pipeline9JointDrcRepairSolver\",k9,t=\u003e{const e=t.getPreloadedTraceUpdatesAfterHighDensity(),n=t.getSrjWithMaterializedPreloadedTraces();return[{srj:n,srjWithPointPairs:n,originalSrj:t.originalSrj,newConnections:t.netToPointPairsSolver?.newConnections??[],newHdRoutes:t.globalDrcForceImproveSolver.getOutput(),updatedPreloadedTraces:e.updatedPreloadedTraces,mutatedPreloadedTraceIds:new Set(e.mutatedPreloadedTraces.map(t=\u003et.pcb_trace_id)),connMap:t.connMap,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,defaultViaHoleDiameter:t.viaHoleDiameter,effort:t.effort,colorMap:t.colorMap}]}),W9(\"lengthMatchingPostProcessingSolver\",uK,t=\u003e{const e=t.netToPointPairsSolver;if(!e)throw new Error(\"Pipeline9: length-matching post-processing requires NetToPointPairsSolver output\");const n=e.newConnections,o=new Map;for(const e of t.srj.differentialPairs??[])for(const t of e.connectionNames){const e=n.filter(e=\u003ee.name===t||e.__rootConnectionNames?.includes(t)||e.__netConnectionName===t);if(1!==e.length)throw new Error(`Pipeline9: differential pair connection \"${t}\" must resolve to exactly one final point-pair connection, got ${e.length}`);o.set(t,e[0].name)}const i=t.pipeline9JointDrcRepairSolver.getOutput(),r=(t.srj.differentialPairs??[]).map(t=\u003e{const e=t.connectionNames.map(t=\u003e{const e=o.get(t);if(!e)throw new Error(`Pipeline9: differential pair connection \"${t}\" is missing from final routed output`);return e});if(e[0]===e[1])throw new Error(`Pipeline9: differential pair ${t.connectionNames.join(\"/\")} resolves both members to \"${e[0]}\"`);if(void 0===t.traceGap)return{connectionNames:e,lengthTolerance:t.lengthTolerance};const n=e.map(t=\u003e{const e=i.filter(e=\u003ee.connectionName===t);if(1!==e.length)throw new Error(`Pipeline9: differential pair connection \"${t}\" must resolve to exactly one final HD route, got ${e.length}`);return e[0]}),r=t.traceGap+n.reduce((t,e)=\u003et+e.traceThickness/2,0);return{connectionNames:e,lengthTolerance:t.lengthTolerance,minimumCenterlineDistance:r,maximumCenterlineDistance:r}});return[{hdRoutes:i,differentialPairs:r,buses:t.srj.buses??[],connections:t.srj.connections,obstacles:t.srj.obstacles,bounds:t.srj.bounds,layerCount:t.srj.layerCount,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15}]}),W9(\"powerTraceExpansionSolver\",UJ,t=\u003e{const e=t.opts.powerTraceExpansion??{},n=e.onlyConnectionNames??JJ(t.originalSrj);return[QJ({originalSrj:t.originalSrj,newlyRoutedTraces:t.getNewTracesBeforePowerExpansion(),currentPreloadedTraces:t.getUpdatedPreloadedTraces(),expandedConnectionNames:n,resolveConnectedTraceAliases:!0}),{allowNewVias:!1,...e,onlyConnectionNames:n}]})];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;computeProgress(){const t=this.activeSubSolver?.progress??0;return(this.currentPipelineStepIndex+t)/this.pipelineDef.length}_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\u0026\u0026(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),\"lengthMatchingPostProcessingSolver\"!==t.solverName\u0026\u0026\"powerTraceExpansionSolver\"!==t.solverName||(this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,this.iterations+this.activeSubSolver.MAX_ITERATIONS+1)),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\u0026\u0026this.activeSubSolver)return this.visualizeStage(this.activeSubSolver);const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.componentDetectionSolver?.visualize(),o=this.componentTopologyGeneratorSolver?.visualize(),i=this.globalTopologyGeneratorSolver?.visualize(),r=this.topologyMergingSolver?.visualize(),s=this.nodeDimensionSubdivisionSolver?.visualize(),a=this.nodeTargetMerger?.visualize(),c=this.singleLayerNodeMerger?.visualize(),l=this.strawSolver?.visualize(),d=this.edgeSolver?.visualize(),h=this.deadEndSolver?.visualize(),u=this.availableSegmentPointSolver?.visualize(),p=this.portPointPathingSolver?.visualize(),m=this.multiSectionPortPointOptimizer?.visualize(),g=this.uniformPortDistributionSolver?.visualize(),f=this.highDensityRouteSolver?.visualize(),y=this.highDensityForceImproveSolver?.visualize(),_=this.highDensityRepairSolver?.visualize(),b=this.highDensityStitchSolver?.visualize(),x=this.traceSimplificationSolver?.visualize(),v=this.mutatedPreloadedTraceSimplificationSolver?.visualize(),S=this.lengthMatchingPostProcessingSolver?.visualize(),I=this.powerTraceExpansionSolver?.visualize(),C=this.traceWidthSolver?.visualize(),P=this.necessaryCrampedPortPointSolver?.visualize(),M=(this.highDensityRouteSolver?.visualize(),this.originalSrj),N=M.outline,w=[];if(w.push({points:[{x:M.bounds?.minX??-50,y:M.bounds?.minY??-50},{x:M.bounds?.maxX??50,y:M.bounds?.minY??-50},{x:M.bounds?.maxX??50,y:M.bounds?.maxY??50},{x:M.bounds?.minX??-50,y:M.bounds?.maxY??50},{x:M.bounds?.minX??-50,y:M.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),N\u0026\u0026N.length\u003e=2){const t=N.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),w.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const T=Oo(M),R={points:[...M.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,M.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(M.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,M.layerCount),label:T(t)}))],lines:w},E={traceColorMode:this.visualizationTraceColorMode},A=Yj({srj:M,visualizationOptions:E}),O=pi(R,A),k=this.preprocessSimpleRouteJsonSolver?.visualize(),L=this.globalDrcForceImproveSolver?.visualize(),D=this.pipeline9JointDrcRepairSolver?.visualize(),z=[O,k,n,o,t,e,i,r,s,a,c,l,d,h,u,P,p,m,g,f?pi(R,f):null,y,_,b,x,v,C,L,D,S,I,this.solved?pi({lines:w},Yj({srj:this.originalSrj,visualizationOptions:E}),this.visualizeFinalOutput()):null].filter(Boolean),F=pi(...z);return\"net\"===this.visualizationTraceColorMode?xq(F,this.colorMap):F}visualizeStage(t){const e=t.visualize();return\"net\"===this.visualizationTraceColorMode?xq(e,this.colorMap):e}visualizeFinalOutput(){const t=this.visualizationTraceColorMode,e=this.getOutputSimpleRouteJson();return Ho(e,{traceColorMode:t})}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.componentTopologyGeneratorSolver?this.componentTopologyGeneratorSolver.visualize():this.componentDetectionSolver?this.componentDetectionSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){if(((this.originalSrj.differentialPairs?.length??0)\u003e0||(this.originalSrj.buses??[]).some(t=\u003evoid 0!==t.maxLengthSkew))\u0026\u0026this.lengthMatchingPostProcessingSolver){const{hdRoutes:t}=this.lengthMatchingPostProcessingSolver.getOutput();return t}return this.pipeline9JointDrcRepairSolver?.getOutput()??this.globalDrcForceImproveSolver?.getOutput()??this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOriginalFixedHdRoutes(){return(this.originalSrj.traces??[]).flatMap((t,e)=\u003eoQ(t,e,this.originalSrj.layerCount,this.viaDiameter,this.connMap))}getChangedPreloadedTraceSections(){return this.portPointPathingSolver?.getOutput().changedPreloadedTraceSections??[]}getPreloadedFixedRouteStateAfterHighDensity(){const t=this.getOriginalFixedHdRoutes(),e=this.getChangedPreloadedTraceSections(),n=TK({traces:this.originalSrj.traces??[],fixedHdRoutes:t,sections:e}),o=0===e.length?[]:RK({traces:this.originalSrj.traces??[],sections:e,stitchedHdRoutes:this.highDensityStitchSolver?.mergedHdRoutes??[],layerCount:this.originalSrj.layerCount}),i=new Set(e.map(t=\u003et.traceId)),r=t.filter(t=\u003ei.has(this.originalSrj.traces?.[t.preloadedTraceIndex]?.pcb_trace_id??\"\")).map(t=\u003et.connectionName);return{originalFixedRoutes:t,updatedFixedRoutes:[...this.highDensityRouteSolver?.getUpdatedFixedHdRoutes()??n,...o],replacedConnectionNames:new Set([...this.highDensityRouteSolver?.fixedRouteReplacements.keys()??[],...r]),mutationMasks:new Map([...this.highDensityRouteSolver?.preloadedTraceMutationMasks??[],...o.map(t=\u003e[t.connectionName,Array(t.route.length-1).fill(!0)])])}}getPreparedMutatedPreloadedTraceSections(){const t=this.getPreloadedFixedRouteStateAfterHighDensity();return eQ({updatedFixedRoutes:t.updatedFixedRoutes,regionalMutationMasks:t.mutationMasks})}getPreloadedTraceUpdatesAfterHighDensity(){const t=this.getPreloadedFixedRouteStateAfterHighDensity(),e=this.getPreparedMutatedPreloadedTraceSections(),n=!0===this.mutatedPreloadedTraceSimplificationSolver?.solved?(({updatedFixedRoutes:t,sections:e,simplifiedHdRoutes:n})=\u003e{const o=new Set(e.map(t=\u003et.connectionName)),i=new Map(n.map(t=\u003e[t.connectionName,t]));if(i.size!==e.length||n.some(t=\u003e!o.has(t.connectionName)))throw new Error(`Pipeline9 trace simplification changed the mutation-section set (expected ${e.length}, got ${n.length})`);const r=new Map,s=new Set;for(const t of e){const e=i.get(t.connectionName);if(!e)throw new Error(`Pipeline9 trace simplification lost mutation section \"${t.connectionName}\"`);const n=e.route[0],o=e.route.at(-1);if(!(n\u0026\u0026o\u0026\u0026HK(n,t.section.start.point)\u0026\u0026HK(o,t.section.end.point)))throw new Error(`Pipeline9 trace simplification changed mutation-section boundary \"${t.connectionName}\"`);const a=XK(t.section,e),c=t.section.sourceRoutes[0];s.add(c.connectionName);for(const e of t.section.sourceRoutes){if(r.has(e.connectionName))throw new Error(`Pipeline9 attempted to simplify fixed route \"${e.connectionName}\" more than once`);r.set(e.connectionName,a)}}return t.flatMap(t=\u003e{const e=r.get(t.connectionName);return e?s.has(t.connectionName)?[e]:[]:[t]})})({updatedFixedRoutes:e.normalizedFixedRoutes,sections:e.sections,simplifiedHdRoutes:this.mutatedPreloadedTraceSimplificationSolver.simplifiedHdRoutes}):t.updatedFixedRoutes;return(({originalTraces:t,originalFixedRoutes:e,updatedFixedRoutes:n,replacedConnectionNames:o,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a})=\u003e{const c=new Map,l=new Map;for(const t of e){const e=c.get(t.preloadedTraceIndex)??[];e.push(t),c.set(t.preloadedTraceIndex,e)}for(const t of n){const e=l.get(t.preloadedTraceIndex)??[];e.push(t),l.set(t.preloadedTraceIndex,e)}const d=[];return{updatedPreloadedTraces:t.map((t,e)=\u003e{const n=(c.get(e)??[]).sort(fK);if(!n.some(t=\u003eo.has(t.connectionName)))return t;const h=(l.get(e)??[]).sort(fK),u=t.route.some(t=\u003e\"through_obstacle\"===t.route_type),p={...t,__replaces_pcb_trace_id:t.pcb_trace_id,route:u?xK({trace:t,originalTraceRoutes:n,updatedTraceRoutes:h,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a}):_K({trace:t,updatedTraceRoutes:h,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a})};return d.push(p),p}),mutatedPreloadedTraces:d}})({originalTraces:this.originalSrj.traces??[],originalFixedRoutes:t.originalFixedRoutes,updatedFixedRoutes:n,replacedConnectionNames:t.replacedConnectionNames,layerCount:this.originalSrj.layerCount,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.originalSrj.obstacles,connMap:this.connMap})}getSrjWithMaterializedPreloadedTraces(){return{...this.srjWithPointPairs,traces:this.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces}}getUpdatedPreloadedTraces(){return this.pipeline9JointDrcRepairSolver?.getUpdatedPreloadedTraces()??this.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces}getMutatedPreloadedTraces(){return this.pipeline9JointDrcRepairSolver?.getMutatedPreloadedTraces()??this.getPreloadedTraceUpdatesAfterHighDensity().mutatedPreloadedTraces}getNewTracesBeforePowerExpansion(){if(!this.highDensityRouteSolver)throw new Error(\"Cannot get new traces before high-density routing\");const t=qJ({connections:this.netToPointPairsSolver?.newConnections??[],originalConnections:this.originalSrj.connections,hdRoutes:this._getOutputHdRoutes(),layerCount:this.srj.layerCount,obstacles:this.srj.obstacles,defaultViaHoleDiameter:this.viaHoleDiameter,connMap:this.connMap});return vK(t,this.originalSrj.traces??[])}getPowerTraceExpansionFixedTraces(){if(!this.powerTraceExpansionSolver)throw new Error(\"Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver\");return this.powerTraceExpansionSolver.inputSrj.fixedTraces}getOutputSimplifiedPcbTraces(){if(!this.solved)throw new Error(\"Cannot get output before solving is complete\");if(!this.powerTraceExpansionSolver)throw new Error(\"Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver\");return[...this.getPowerTraceExpansionFixedTraces().filter(t=\u003evoid 0!==t.__replaces_pcb_trace_id),...this.powerTraceExpansionSolver.getOutput()]}getOutputSimpleRouteJson(){if(!this.solved)throw new Error(\"Cannot get output before solving is complete\");if(!this.powerTraceExpansionSolver)throw new Error(\"Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver\");const t=[...this.getPowerTraceExpansionFixedTraces(),...this.powerTraceExpansionSolver.getOutput()];return{...this.originalSrj,traces:t}}},G9=String(\"0.0.886\"),U9=({nodeWithPortPoints:t,obstacleMargin:e,traceWidth:n,viaDiameter:o})=\u003e{const i=ro(t),r=e+Math.max(n,o)/2+1e-6;return{minX:t.center.x+8*(i.minX-t.center.x)-r,maxX:t.center.x+8*(i.maxX-t.center.x)+r,minY:t.center.y+8*(i.minY-t.center.y)-r,maxY:t.center.y+8*(i.maxY-t.center.y)+r}},Z9=(t,e)=\u003e{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.abs(Math.cos(n)),i=Math.abs(Math.sin(n)),r=t.width/2,s=t.height/2,a=Math.max(r,r*o+s*i),c=Math.max(s,r*i+s*o);return t.center.x-a\u003c=e.maxX\u0026\u0026t.center.x+a\u003e=e.minX\u0026\u0026t.center.y-c\u003c=e.maxY\u0026\u0026t.center.y+c\u003e=e.minY},q9=(t,e)=\u003e{for(const n of[e.connectionName,e.rootConnectionName,e.portPointId,e.pcb_port_id,e.prevPortPointId,e.nextPortPointId])void 0!==n\u0026\u0026t.add(n)},J9=(t,e)=\u003eObject.fromEntries(Object.entries(t.netMap).flatMap(([t,n])=\u003e{const o=n.filter(t=\u003ee.has(t));return o.length\u003e0||e.has(t)?[[t,o]]:[]})),K9=({obstacle:t,connectedTo:e,preserveRotation:n})=\u003e({type:\"rect\",layers:t.layers,...void 0===t.zLayers?{}:{zLayers:t.zLayers},...void 0===t.__zLayers?{}:{__zLayers:t.__zLayers},center:t.center,width:t.width,height:t.height,...n\u0026\u0026void 0!==t.ccwRotationDegrees?{ccwRotationDegrees:t.ccwRotationDegrees}:{},connectedTo:e,...void 0===t.circuitJsonMetadata?{}:{circuitJsonMetadata:t.circuitJsonMetadata}});function Q9({nodeWithPortPoints:t,connMap:e,obstacles:n,obstacleMargin:o,traceWidth:i,viaDiameter:r}){const s=U9({nodeWithPortPoints:t,obstacleMargin:o,traceWidth:i,viaDiameter:r}),a=new Set;for(const e of t.portPoints)q9(a,e);for(const e of t.portPointsInPairs??[])q9(a,e[0]),q9(a,e[1]);const c=n.flatMap(n=\u003e{if(!Z9(n,s))return[];const o=(({obstacle:t,nodeWithPortPoints:e,connMap:n})=\u003e{const o=new Set(e.portPoints.flatMap(t=\u003e{const e=n.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName;return[t.connectionName,e]})),i=new Set(t.connectedTo.filter(t=\u003eo.has(t))),r=new Map;for(const t of o){const e=n.getNetConnectedToId(t)??t,o=r.get(e)??[];o.push(t),r.set(e,o)}for(const e of r.values()){if([...i].some(t=\u003ee.some(e=\u003ee===t||n.areIdsConnected(e,t))))continue;const o=t.connectedTo.find(t=\u003ee.some(e=\u003ee===t||n.areIdsConnected(e,t)));void 0!==o\u0026\u0026i.add(o)}return[...i]})({obstacle:n,nodeWithPortPoints:t,connMap:e});for(const t of o)a.add(t);return[K9({obstacle:n,connectedTo:o,preserveRotation:!0})]});return{connectivityNetMap:J9(e,a),obstacles:c}}var t8=(...t)=\u003e{const e=new Map;for(const n of t)for(const[t,o]of Object.entries(n)){const n=e.get(t)??new Set;for(const t of o)n.add(t);e.set(t,n)}return Object.fromEntries([...e].map(([t,e])=\u003e[t,[...e]]))};function e8({nodeWithPortPoints:t,connMap:e,colorMap:n,obstacles:o,obstacleMargin:i,traceWidth:r,viaDiameter:s}){const a=U9({nodeWithPortPoints:t,obstacleMargin:i,traceWidth:r,viaDiameter:s}),c=(t=\u003e[...new Set(t.portPoints.map(t=\u003et.connectionName))])(t),l=o.flatMap(t=\u003e{if(!Z9(t,a))return[];const n=c.filter(n=\u003et.connectedTo.some(t=\u003et===n||e.areIdsConnected(n,t)));return 0===n.length?[]:[K9({obstacle:t,connectedTo:n,preserveRotation:!1})]}),d=new Set;for(const e of t.portPoints)q9(d,e);for(const e of t.portPointsInPairs??[])q9(d,e[0]),q9(d,e[1]);for(const t of l)for(const e of[t.circuitJsonMetadata?.pcb_smtpad_id,t.circuitJsonMetadata?.pcb_plated_hole_id,t.circuitJsonMetadata?.pcb_port_id,t.circuitJsonMetadata?.pcb_via_id,...t.connectedTo??[]])void 0!==e\u0026\u0026d.add(e);return{connectivityNetMap:J9(e,d),colorMap:Object.fromEntries(Object.entries(n??{}).filter(([t])=\u003ed.has(t))),obstacles:l}}var n8=\"https://hd-cache2.tscircuit.com\",o8=31e4,i8=1835008,r8=16777216,s8=class extends Error{constructor(t,e){super(e),this.reason=t,this.name=\"HdCache2RequestError\"}reason},a8=t=\u003et instanceof Error?t.message:String(t),c8=new Set([\"pcb_smtpad_id\",\"pcb_plated_hole_id\",\"pcb_port_id\",\"pcb_via_id\",\"source_component_name\",\"source_port_name\"]),l8=t=\u003e!(!t||\"object\"!=typeof t||Array.isArray(t))\u0026\u0026Object.entries(t).every(([t,e])=\u003ec8.has(t)\u0026\u0026\"string\"==typeof e),d8=(t,e)=\u003eMath.abs(t-e)\u003c=1e-9*Math.max(1,Math.abs(t),Math.abs(e)),h8=1e-6,u8=(t,e)=\u003e{const n=\"ordinary\"===e?h8:.001,o=new Set;for(let i=0;i\u003ct.route.length-1;i++){const r=t.route[i],s=t.route[i+1],a=r.z!==s.z;if(\"through_obstacle\"===r.toNextSegmentType){if(!a)return!1;continue}if(void 0!==r.toNextSegmentCircuitJsonMetadata)return!1;if(!a)continue;const c=[],l=[];for(const[e,o]of t.vias.entries())Math.hypot(o.x-r.x,o.y-r.y)\u003c=n\u0026\u0026c.push(e),Math.hypot(o.x-s.x,o.y-s.y)\u003c=n\u0026\u0026l.push(e);if(Math.hypot(r.x-s.x,r.y-s.y)\u003c=h8){if(0===c.length)return!1;for(const t of c)o.add(t)}else{if(\"regional-fallback\"===e)return!1;if(0===c.length==(0===l.length))return!1;for(const t of[...c,...l])o.add(t)}}const i=t.route.at(-1);return void 0===i.toNextSegmentType\u0026\u0026void 0===i.toNextSegmentCircuitJsonMetadata\u0026\u0026t.vias.every((t,e)=\u003eo.has(e))},p8=(t,e,n)=\u003e{if(!Array.isArray(t))return!1;const o=new Map;for(const t of e.nodeWithPortPoints.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}const i=new Set(e.nodeWithPortPoints.availableZ??e.nodeWithPortPoints.portPoints.map(t=\u003et.z)),r=U9({nodeWithPortPoints:e.nodeWithPortPoints,obstacleMargin:e.obstacleMargin,traceWidth:e.traceWidth,viaDiameter:e.viaDiameter}),s=(t,e)=\u003e(o.get(e)??[]).some(e=\u003e\"number\"==typeof t.x\u0026\u0026d8(t.x,e.x)\u0026\u0026\"number\"==typeof t.y\u0026\u0026d8(t.y,e.y)\u0026\u0026t.z===e.z);for(const a of t){if(!a||\"object\"!=typeof a)return!1;const t=a;if(\"string\"!=typeof t.connectionName||0===t.connectionName.length||!o.has(t.connectionName)||\"number\"!=typeof t.traceThickness||!Number.isFinite(t.traceThickness)||t.traceThickness\u003c=0||\"number\"!=typeof t.viaDiameter||!Number.isFinite(t.viaDiameter)||t.viaDiameter\u003c=0||!d8(t.viaDiameter,e.viaDiameter)||!Array.isArray(t.route)||t.route.length\u003c2||!Array.isArray(t.vias))return!1;for(const e of[t.rootConnectionName,t.startPcbPortId,t.endPcbPortId,t.regionId])if(void 0!==e\u0026\u0026\"string\"!=typeof e)return!1;for(const o of t.route){if(!o||\"object\"!=typeof o)return!1;const t=o;if(\"number\"!=typeof t.x||!Number.isFinite(t.x)||\"number\"!=typeof t.y||!Number.isFinite(t.y)||t.x\u003cr.minX||t.x\u003er.maxX||t.y\u003cr.minY||t.y\u003er.maxY||\"number\"!=typeof t.z||!Number.isInteger(t.z)||t.z\u003c0||t.z\u003e=e.layerCount||\"ordinary\"===n\u0026\u0026!i.has(t.z))return!1;if(void 0!==t.traceThickness\u0026\u0026(\"number\"!=typeof t.traceThickness||!Number.isFinite(t.traceThickness)||t.traceThickness\u003c=0))return!1;if(void 0!==t.pcb_port_id\u0026\u0026\"string\"!=typeof t.pcb_port_id)return!1;if(void 0!==t.insideJumperPad\u0026\u0026\"boolean\"!=typeof t.insideJumperPad)return!1;if(void 0!==t.toNextSegmentType\u0026\u0026\"through_obstacle\"!==t.toNextSegmentType)return!1;if(void 0!==t.toNextSegmentCircuitJsonMetadata\u0026\u0026!l8(t.toNextSegmentCircuitJsonMetadata))return!1}const c=t.route;if(!(\"ordinary\"!==n||s(c[0],t.connectionName)\u0026\u0026s(c.at(-1),t.connectionName)))return!1;for(const e of t.vias){if(!e||\"object\"!=typeof e)return!1;const t=e;if(\"number\"!=typeof t.x||!Number.isFinite(t.x)||\"number\"!=typeof t.y||!Number.isFinite(t.y)||t.x\u003cr.minX||t.x\u003er.maxX||t.y\u003cr.minY||t.y\u003er.maxY)return!1}if(!u8(t,n))return!1;if(void 0!==t.jumpers){if(!Array.isArray(t.jumpers))return!1;for(const e of t.jumpers){if(!e||\"object\"!=typeof e)return!1;const t=e,n=t.start,o=t.end;if(\"jumper\"!==t.route_type||\"0603\"!==t.footprint\u0026\u0026\"1206\"!==t.footprint\u0026\u0026\"1206x4_pair\"!==t.footprint||!n||\"number\"!=typeof n.x||!Number.isFinite(n.x)||\"number\"!=typeof n.y||!Number.isFinite(n.y)||!o||\"number\"!=typeof o.x||!Number.isFinite(o.x)||\"number\"!=typeof o.y||!Number.isFinite(o.y)||n.x\u003cr.minX||n.x\u003er.maxX||n.y\u003cr.minY||n.y\u003er.maxY||o.x\u003cr.minX||o.x\u003er.maxX||o.y\u003cr.minY||o.y\u003er.maxY)return!1}}}const a=t;return\"ordinary\"===n?((t,e)=\u003e{const n=e.portPointsInPairs??[];if(n.length\u003e0){for(const[e,o]of n)if(!xs(t,e.connectionName,_s(e)).has(_s(o)))return!1;return!0}const o=new Map;for(const t of e.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}for(const[e,n]of o)for(const[o,i]of Dr(n))if(!xs(t,e,_s(o)).has(_s(i)))return!1;return!0})(a,e.nodeWithPortPoints):((t,e)=\u003e{const n=(t,e)=\u003e{if(t.z!==e.z)return!1;const n=t.x-e.x,o=t.y-e.y;return Math.hypot(n,o)\u003c=.001},o=new Map;for(const i of t){const t=i.route.some((t,e)=\u003e{const n=i.route[e+1];return!(void 0===n||d8(t.x,n.x)\u0026\u0026d8(t.y,n.y)\u0026\u0026t.z===n.z)}),r=i.route[0],s=i.route.at(-1);if(!t||!r||!s)return!1;const a=e.portPoints.filter(t=\u003et.connectionName===i.connectionName);if(!a.some(t=\u003en(r,t))||!a.some(t=\u003en(s,t)))return!1;const c=o.get(i.connectionName)??[];c.push({start:r,end:s}),o.set(i.connectionName,c)}const i=(t,e,i)=\u003e{if(n(e,i))return!0;const r=o.get(t)??[],s=[],a=new Set;for(const[t,o]of r.entries())(n(e,o.start)||n(e,o.end))\u0026\u0026(s.push(t),a.add(t));for(;s.length\u003e0;){const t=r[s.pop()];if(n(i,t.start)||n(i,t.end))return!0;for(const[e,o]of r.entries())a.has(e)||(n(t.start,o.start)||n(t.start,o.end)||n(t.end,o.start)||n(t.end,o.end))\u0026\u0026(a.add(e),s.push(e))}return!1},r=e.portPointsInPairs??[];if(r.length\u003e0)return r.every(([t,e])=\u003ei(t.connectionName,t,e));const s=new Map;for(const t of e.portPoints){const e=s.get(t.connectionName)??[];e.push(t),s.set(t.connectionName,e)}return[...s].every(([,t])=\u003eDr(t).every(([t,e])=\u003ei(t.connectionName,t,e)))})(a,e.nodeWithPortPoints)},m8=class{constructor(t,e=n8,n={}){this.autorouterVersion=t,this.serverUrl=e;const{cacheVersion:o}=n;if(void 0!==o\u0026\u00260===o.trim().length)throw new Error(\"hd-cache2 cacheVersion must not be empty\");this.cacheVersion=o}autorouterVersion;serverUrl;cacheVersion;stats={batchRequestsStarted:0,batchRequestsCompleted:0,batchItemsStarted:0,batchBodyBytesStarted:0,batchMaxBodyBytes:0,batchCacheMisses:0,singleRequestsStarted:0,batchInvalidLines:0,batchUnknownRequestIds:0,batchDuplicateRequestIds:0};solveMany(t){const e=t.map((t,e)=\u003ethis.createPendingSolve(String(e),t)),n=e.filter(t=\u003enull!==t.serializedItem),{batches:o,singletonSolves:i}=this.prepareBatches(n);for(const t of o)this.fetchBatch(t);for(const t of i)this.launchSingleSolve(t);return e.map(t=\u003et.promise)}createPendingSolve(t,e){let n;const o={requestId:t,input:e,serializedItem:null,promise:new Promise(t=\u003e{n=t}),resolve:n,settled:!1,singleSolveStarted:!1};try{o.serializedItem=JSON.stringify({requestId:t,input:e})}catch(t){this.settleWithFallback(o,\"request_serialization_error\",a8(t))}return o}settle(t,e){t.settled||(t.settled=!0,t.resolve(e))}settleWithFallback(t,e,n){this.settle(t,{kind:\"local-fallback\",reason:e,error:n})}parseSuccessfulResponse(t,e){if(!t||\"object\"!=typeof t||Array.isArray(t))throw new s8(\"invalid_response\",\"hd-cache2 returned a non-object response\");const n=t;if(!0!==n.ok)throw new s8(\"remote_error\",\"string\"==typeof n.message?n.message:\"hd-cache2 returned an unsuccessful response\");if(n.autorouterVersion!==this.autorouterVersion)throw new s8(\"version_mismatch\",`hd-cache2 returned autorouter version ${String(n.autorouterVersion)}, expected ${this.autorouterVersion}`);if(n.cacheVersion!==this.cacheVersion)throw new s8(\"cache_version_mismatch\",`hd-cache2 returned cache version ${String(n.cacheVersion)}, expected ${String(this.cacheVersion)}`);if(\"cache\"!==n.source\u0026\u0026\"solver\"!==n.source)throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid cache source\");if(\"ordinary\"!==n.solutionStage\u0026\u0026\"regional-fallback\"!==n.solutionStage)throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid solution stage\");if(\"regional-fallback\"===n.solutionStage\u0026\u0026(!e.enableRegionalFallback||\"string\"!=typeof n.ordinaryFailure||0===n.ordinaryFailure.length))throw new s8(\"invalid_response\",\"hd-cache2 returned invalid regional fallback metadata\");if(\"ordinary\"===n.solutionStage\u0026\u0026Object.prototype.hasOwnProperty.call(n,\"ordinaryFailure\"))throw new s8(\"invalid_response\",\"hd-cache2 returned regional metadata on an ordinary result\");if(\"ordinary\"===n.solutionStage\u0026\u0026\"failed\"===n.status\u0026\u0026e.enableRegionalFallback)throw new s8(\"invalid_response\",\"hd-cache2 returned an intermediate ordinary failure\");if(\"solved\"===n.status\u0026\u0026p8(n.routes,e,n.solutionStage))return n;if(\"failed\"===n.status\u0026\u0026\"string\"==typeof n.error\u0026\u0026n.error.length\u003e0)return n;throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid solve result\")}parseBatchCacheMiss(t){if(!1!==t.ok||\"CACHE_MISS\"!==t.code)return null;if(t.autorouterVersion!==this.autorouterVersion)throw new s8(\"version_mismatch\",`hd-cache2 returned autorouter version ${String(t.autorouterVersion)}, expected ${this.autorouterVersion}`);if(t.cacheVersion!==this.cacheVersion)throw new s8(\"cache_version_mismatch\",`hd-cache2 returned cache version ${String(t.cacheVersion)}, expected ${String(this.cacheVersion)}`);if(\"string\"!=typeof t.message)throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid cache miss response\");return t}async fetchSingle(t){const e=new AbortController;let n=!1;const o=setTimeout(()=\u003e{n=!0,e.abort(new Error(\"hd-cache2 transport timed out after 310000ms\"))},o8);o.unref?.();try{const n={autorouterVersion:this.autorouterVersion,...void 0===this.cacheVersion?{}:{cacheVersion:this.cacheVersion},input:t.input};let o;try{o=JSON.stringify(n)}catch(t){throw new s8(\"request_serialization_error\",a8(t))}const r=await fetch((i=this.serverUrl,/\\/solve\\/?$/.test(i)?i.replace(/\\/+$/,\"\"):`${i.replace(/\\/+$/,\"\")}/solve`),{method:\"POST\",headers:{accept:\"application/json\",\"content-type\":\"application/json\"},body:o,signal:e.signal}),s=await r.text();let a=null;try{a=s?JSON.parse(s):null}catch{if(!r.ok)throw new s8(\"http_error\",`hd-cache2 request failed with status ${r.status}`);throw new s8(\"invalid_json\",`hd-cache2 returned invalid JSON with status ${r.status}`)}if(!r.ok){const t=a\u0026\u0026\"object\"==typeof a\u0026\u0026\"message\"in a\u0026\u0026\"string\"==typeof a.message?a.message:`hd-cache2 request failed with status ${r.status}`;throw new s8(\"http_error\",t)}this.settle(t,{kind:\"remote\",response:this.parseSuccessfulResponse(a,t.input)})}catch(e){const o=e instanceof s8?e.reason:n?\"transport_timeout\":\"transport_error\";this.settleWithFallback(t,o,a8(e))}finally{clearTimeout(o)}var i}launchSingleSolve(t){t.singleSolveStarted||t.settled||(t.singleSolveStarted=!0,this.stats.singleRequestsStarted+=1,this.fetchSingle(t))}handleBatchResponseLine(t,e,n){if(0===t.trim().length)return;if(t.length\u003er8)throw new s8(\"response_too_large\",\"hd-cache2 returned an oversized batch result line\");let o;try{o=JSON.parse(t)}catch{return void(this.stats.batchInvalidLines+=1)}if(!o||\"object\"!=typeof o||Array.isArray(o))return void(this.stats.batchInvalidLines+=1);const i=o,r=i.requestId;if(\"string\"!=typeof r)return void(this.stats.batchInvalidLines+=1);const s=e.get(r);if(s)if(n.has(r))this.stats.batchDuplicateRequestIds+=1;else{n.add(r);try{if(this.parseBatchCacheMiss(i))return this.stats.batchCacheMisses+=1,void this.launchSingleSolve(s);this.settle(s,{kind:\"remote\",response:this.parseSuccessfulResponse(i,s.input)})}catch(t){this.stats.batchInvalidLines+=1,this.settleWithFallback(s,t instanceof s8?t.reason:\"invalid_response\",a8(t))}}else this.stats.batchUnknownRequestIds+=1}async readBatchResponse(t,e){if(!t.body)throw new s8(\"invalid_response\",\"hd-cache2 returned an empty batch response body\");const n=new Map(e.items.map(t=\u003e[t.requestId,t])),o=new Set,i=new TextDecoder,r=t.body.getReader();let s=\"\";for(;o.size\u003ce.items.length;){const{done:t,value:e}=await r.read();if(s+=i.decode(e,{stream:!t}),s.length\u003er8\u0026\u0026!s.includes(\"\\n\"))throw new s8(\"response_too_large\",\"hd-cache2 returned an oversized unterminated batch result line\");let a=s.indexOf(\"\\n\");for(;a\u003e=0;){const t=s.slice(0,a);s=s.slice(a+1),this.handleBatchResponseLine(t,n,o),a=s.indexOf(\"\\n\")}if(t){s.trim().length\u003e0\u0026\u0026this.handleBatchResponseLine(s,n,o);break}}if(o.size!==e.items.length)for(const t of e.items)o.has(t.requestId)||this.settleWithFallback(t,\"missing_response\",`hd-cache2 batch ended without result ${t.requestId}`);else await r.cancel().catch(()=\u003e{})}async fetchBatch(t){const e=new AbortController;let n=!1;const o=setTimeout(()=\u003e{n=!0,e.abort(new Error(\"hd-cache2 batch transport timed out after 310000ms\"))},o8);o.unref?.(),this.stats.batchRequestsStarted+=1,this.stats.batchItemsStarted+=t.items.length,this.stats.batchBodyBytesStarted+=t.bodyBytes,this.stats.batchMaxBodyBytes=Math.max(this.stats.batchMaxBodyBytes,t.bodyBytes);try{const n=await fetch((t=\u003e{const e=t.replace(/\\/+$/,\"\");return/\\/solve-batch$/.test(e)?e:/\\/solve$/.test(e)?e.replace(/\\/solve$/,\"/solve-batch\"):`${e}/solve-batch`})(this.serverUrl),{method:\"POST\",headers:{accept:\"application/x-ndjson\",\"content-type\":\"application/json\"},body:t.body,signal:e.signal});if(!n.ok){const t=await n.text().catch(()=\u003e\"\");let e=`hd-cache2 batch request failed with status ${n.status}`;try{const n=t?JSON.parse(t):null;n\u0026\u0026\"object\"==typeof n\u0026\u0026\"message\"in n\u0026\u0026\"string\"==typeof n.message\u0026\u0026(e=n.message)}catch{}throw new s8(\"http_error\",e)}await this.readBatchResponse(n,t)}catch(e){const o=e instanceof s8?e.reason:n?\"transport_timeout\":\"transport_error\";for(const n of t.items)n.singleSolveStarted||this.settleWithFallback(n,o,a8(e))}finally{clearTimeout(o),this.stats.batchRequestsCompleted+=1}}prepareBatches(t){const e=new TextEncoder,n=void 0===this.cacheVersion?\"\":`,\"cacheVersion\":${JSON.stringify(this.cacheVersion)}`,o=`{\"autorouterVersion\":${JSON.stringify(this.autorouterVersion)}${n},\"items\":[`,i=e.encode(o+\"]}\").byteLength,r=[],s=[];let a=[],c=i;const l=()=\u003e{0!==a.length\u0026\u0026(r.push({body:`${o}${a.map(t=\u003et.serializedItem).join(\",\")}]}`,bodyBytes:c,items:a}),a=[],c=i)};for(const n of t){const t=e.encode(n.serializedItem).byteLength,o=0===a.length?0:1;i+t\u003ei8?(l(),s.push(n)):((a.length\u003e=100||c+o+t\u003ei8)\u0026\u0026l(),a.push(n),c+=(1===a.length?0:1)+t)}return l(),{batches:r,singletonSolves:s}}},g8=\"ordinary_then_regional_without_fixed_copper_v1\",f8=class extends VQ{autorouterVersion;hdCache2ServerUrl;hdCache2CacheVersion;requestTimeoutMs;hdCache2Client;launchedRemoteSolves=!1;waitingForRemoteNode=null;remoteRequestByNode=new Map;remoteResultByNode=new Map;logicallyTimedOutNodes=new Set;constructor({autorouterVersion:t,hdCache2ServerUrl:e,hdCache2CacheVersion:n,requestTimeoutMs:o,...i}){if(super(i),1!==i.effort)throw new Error(`Pipeline9 networked high-density routing requires effort=1, received ${i.effort}`);if(this.requestTimeoutMs=o??3e4,!Number.isFinite(this.requestTimeoutMs)||this.requestTimeoutMs\u003c=0)throw new Error(`Pipeline9 network request timeout must be a positive number, received ${this.requestTimeoutMs}`);this.autorouterVersion=t,this.hdCache2ServerUrl=e??n8,this.hdCache2CacheVersion=n,this.hdCache2Client=new m8(this.autorouterVersion,this.hdCache2ServerUrl,{cacheVersion:n}),this.pendingEffects=[],this.stats={...this.stats,remoteRequestsStarted:0,remoteRequestsCompleted:0,remoteBatchRequestsStarted:0,remoteBatchRequestsCompleted:0,remoteBatchItemsStarted:0,remoteBatchBodyBytesStarted:0,remoteBatchMaxBodyBytes:0,remoteBatchCacheMisses:0,remoteSingleRequestsStarted:0,remoteBatchInvalidLines:0,remoteBatchUnknownRequestIds:0,remoteBatchDuplicateRequestIds:0,remoteCacheHits:0,remoteSolverResults:0,remoteSolvedResults:0,remoteFailedResults:0,remoteOrdinaryResults:0,remoteRegionalFallbackResults:0,remoteRegionalFallbackResultsApplied:0,remoteRegionalFallbackResultsDeferredToLocal:0,remoteTransportFallbacks:0,remoteLogicalTimeoutFallbacks:0,remoteFallbackReasonCounts:{}}}getSolverName(){return\"Pipeline9NetworkedHighDensitySolver\"}async waitForAllRemoteRequests(){const t=[...this.remoteRequestByNode.values()];0!==t.length?(await Promise.all(t.map(({promise:t})=\u003et)),this.syncClientStats()):this.syncClientStats()}createNodeInput(t){const e=this.enableRegionalFallback?Q9({nodeWithPortPoints:t,connMap:this.connMap,obstacles:this.obstacles,obstacleMargin:this.obstacleMargin,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter}):{connectivityNetMap:{},obstacles:[]},n=e8({nodeWithPortPoints:t,connMap:this.connMap,colorMap:this.colorMap,obstacles:this.enableRegionalFallback?e.obstacles:this.obstacles,obstacleMargin:this.obstacleMargin,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter});return{solvePolicy:g8,enableRegionalFallback:this.enableRegionalFallback,nodeWithPortPoints:t,connectivityNetMap:t8(n.connectivityNetMap,e.connectivityNetMap),colorMap:n.colorMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:1,obstacles:n.obstacles,regionalObstacles:e.obstacles,layerCount:this.layerCount,nodePf:this.nodePfById.get(t.capacityMeshNodeId)??null}}syncClientStats(){const t=this.hdCache2Client.stats;this.stats.remoteBatchRequestsStarted=t.batchRequestsStarted,this.stats.remoteBatchRequestsCompleted=t.batchRequestsCompleted,this.stats.remoteBatchItemsStarted=t.batchItemsStarted,this.stats.remoteBatchBodyBytesStarted=t.batchBodyBytesStarted,this.stats.remoteBatchMaxBodyBytes=t.batchMaxBodyBytes,this.stats.remoteBatchCacheMisses=t.batchCacheMisses,this.stats.remoteSingleRequestsStarted=t.singleRequestsStarted,this.stats.remoteBatchInvalidLines=t.batchInvalidLines,this.stats.remoteBatchUnknownRequestIds=t.batchUnknownRequestIds,this.stats.remoteBatchDuplicateRequestIds=t.batchDuplicateRequestIds}recordFallbackReason(t){const e=this.stats.remoteFallbackReasonCounts;e[t]=(e[t]??0)+1}trackRemoteSolve(t,e){const n=performance.now()+this.requestTimeoutMs;this.stats.remoteRequestsStarted+=1;const o=e.then(e=\u003e{const n=this.logicallyTimedOutNodes.has(t);n||this.remoteResultByNode.set(t,e),\"remote\"===e.kind?(\"cache\"===e.response.source\u0026\u0026(this.stats.remoteCacheHits+=1),\"solver\"===e.response.source\u0026\u0026(this.stats.remoteSolverResults+=1),\"solved\"===e.response.status?this.stats.remoteSolvedResults+=1:this.stats.remoteFailedResults+=1):n||(this.stats.remoteTransportFallbacks+=1,this.recordFallbackReason(e.reason)),this.stats.remoteRequestsCompleted+=1,this.syncClientStats()});this.remoteRequestByNode.set(t,{promise:o,deadlineAt:n})}launchRemoteSolves(){const t=[],e=[...this.unsolvedNodePortPoints].reverse();for(const n of e)try{t.push({node:n,input:this.createNodeInput(n)})}catch(t){this.trackRemoteSolve(n,Promise.resolve({kind:\"local-fallback\",reason:\"request_serialization_error\",error:t instanceof Error?t.message:String(t)}))}const n=this.hdCache2Client.solveMany(t.map(({input:t})=\u003et));for(const[e,o]of n.entries())this.trackRemoteSolve(t[e].node,o);this.syncClientStats()}async waitForCurrentRemoteNode(t,e){const n=e.deadlineAt-performance.now();if(n\u003c=0)return void this.recordLogicalTimeout(t);let o;const i=await Promise.race([e.promise.then(()=\u003e\"request-settled\"),new Promise(t=\u003e{o=setTimeout(()=\u003et(\"logical-timeout\"),n)})]);void 0!==o\u0026\u0026clearTimeout(o),\"logical-timeout\"===i\u0026\u0026this.recordLogicalTimeout(t)}recordLogicalTimeout(t){this.logicallyTimedOutNodes.add(t),this.stats.remoteLogicalTimeoutFallbacks+=1,this.stats.remoteTransportFallbacks+=1,this.recordFallbackReason(\"logical_timeout\")}startRegularSolver(t){const e=this.remoteResultByNode.get(t);if(!e){const e=this.remoteRequestByNode.get(t);if(e){this.waitingForRemoteNode=t;const n=this.waitForCurrentRemoteNode(t,e);n.then(()=\u003e{this.waitingForRemoteNode===t\u0026\u0026(this.pendingEffects=[])});const o={name:`hd-cache2:${t.capacityMeshNodeId}`,promise:n};return void(this.pendingEffects=[o])}return void super.startRegularSolver(t)}this.applyRemoteResultToRegularNode(t,e)}applyRemoteResultToRegularNode(t,e){if(\"local-fallback\"!==e.kind){if(this.stats.regularNodeCount=Number(this.stats.regularNodeCount??0)+1,this.activeNode=t,\"regional-fallback\"===e.response.solutionStage){if(this.stats.remoteRegionalFallbackResults+=1,!this.canUseNoFixedCopperRegionalResult(t))return this.stats.remoteRegionalFallbackResultsDeferredToLocal+=1,void this.finishRegularSolverFailure(e.response.ordinaryFailure);this.stats.remoteRegionalFallbackResultsApplied+=1,this.stats.fallbackNodeCount=Number(this.stats.fallbackNodeCount??0)+1}else this.stats.remoteOrdinaryResults+=1;if(\"failed\"===e.response.status)return this.error=e.response.error,this.failed=!0,void(this.activeNode=null);this.finishActiveNode(e.response.routes)}else super.startRegularSolver(t)}canUseNoFixedCopperRegionalResult(t){const e={...YQ(t,this.connMap),availableZ:Array.from({length:this.layerCount},(t,e)=\u003ee)},n=$K(e,this.getUpdatedFixedHdRoutes());return 0===n.fixedRouteSectionsByConnectionName.size\u0026\u00260===n.fixedObstacleRoutes.length}_step(){if(this.syncClientStats(),this.launchedRemoteSolves||(this.launchedRemoteSolves=!0,this.launchRemoteSolves()),this.waitingForRemoteNode){const t=this.waitingForRemoteNode;if(this.logicallyTimedOutNodes.has(t))return this.waitingForRemoteNode=null,this.pendingEffects=[],void super.startRegularSolver(t);const e=this.remoteResultByNode.get(t);if(!e)return;return this.waitingForRemoteNode=null,this.pendingEffects=[],void this.applyRemoteResultToRegularNode(t,e)}super._step()}},y8=class extends H9{hdCache2ServerUrl;hdCache2CacheVersion;getSolverName(){return\"AutoroutingPipelineSolver9_Networked\"}constructor(t,e={}){if(super(t,e),1!==this.effort)throw new Error(`AutoroutingPipelineSolver9_Networked is only available at effort=1, received ${this.effort}`);this.hdCache2ServerUrl=e.hdCache2ServerUrl??n8,this.hdCache2CacheVersion=e.hdCache2CacheVersion,this.replaceHighDensityPipelineStep()}replaceHighDensityPipelineStep(){const t=this.pipelineDef.findIndex(t=\u003e\"highDensityRouteSolver\"===t.solverName),e=this.pipelineDef[t];if(!e)throw new Error(\"Pipeline9 highDensityRouteSolver step is missing\");const n=e.getConstructorParams;this.pipelineDef[t]={...e,solverClass:f8,getConstructorParams:t=\u003e{const[e]=n(t);return[{...e,autorouterVersion:G9,hdCache2ServerUrl:t.hdCache2ServerUrl,hdCache2CacheVersion:t.hdCache2CacheVersion}]}}}async stepAsync(){if(this.solved||this.failed)return;this.step();const t=vX(this);0!==t.length\u0026\u0026(await Promise.race(t.map(t=\u003et.promise.then(()=\u003et.name,()=\u003et.name))),this.solved||this.failed||this.step())}async solveAsync(){const t=Date.now();for(;!this.solved\u0026\u0026!this.failed;)await this.stepAsync();this.timeToSolve=Date.now()-t}async solveUntilPhaseAsync(t){for(;this.getCurrentPhase()!==t\u0026\u0026!this.solved\u0026\u0026!this.failed;)await this.stepAsync()}solve(){throw new Error(\"AutoroutingPipelineSolver9_Networked requires async execution. Use solveAsync() or stepAsync().\")}solveUntilPhase(t){throw new Error(\"AutoroutingPipelineSolver9_Networked requires solveUntilPhaseAsync().\")}};function _8(t){if(t.solvePolicy!==g8)throw new Error(`Unsupported Pipeline9 networked solve policy ${String(t.solvePolicy)}`);if(1!==t.effort)throw new Error(`Pipeline9 networked high-density solving requires effort=1, received ${t.effort}`);const e=new ti(t.connectivityNetMap),n=(({input:t,connMap:e})=\u003e{const n=XQ({nodeWithPortPoints:t.nodeWithPortPoints,colorMap:t.colorMap,connMap:e,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:{[t.nodeWithPortPoints.capacityMeshNodeId]:t.nodePf},obstacles:t.obstacles,layerCount:t.layerCount});return n.solve(),n.solved?{status:\"solved\",routes:n.routes}:{status:\"failed\",error:n.error||\"Pipeline9 ordinary high-density solver failed\"}})({input:t,connMap:e});if(\"solved\"===n.status)return{status:\"solved\",solutionStage:\"ordinary\",routes:n.routes};const o=n.error;if(!t.enableRegionalFallback)return{status:\"failed\",solutionStage:\"ordinary\",error:`Pipeline9 regular high-density routing failed: ${o}`};const i=YQ(t.nodeWithPortPoints,e),r=$K({...i,availableZ:Array.from({length:t.layerCount},(t,e)=\u003ee)},[]),s=new FQ({nodeWithPortPoints:r.nodeWithPortPoints,colorMap:t.colorMap,connMap:e,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:{[t.nodeWithPortPoints.capacityMeshNodeId]:t.nodePf},obstacles:t.regionalObstacles,layerCount:t.layerCount});if(s.solve(),s.solved)return{status:\"solved\",solutionStage:\"regional-fallback\",ordinaryFailure:o,routes:s.getOutput()};return{status:\"failed\",solutionStage:\"regional-fallback\",ordinaryFailure:o,error:[`Pipeline9 primary high-density routing failed: regular high-density routing failed: ${o}`,`regional fallback failed: ${s.error||\"Pipeline9 regional fallback solver failed\"}`].join(\"; \")}}var b8=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\u0026\u0026!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026this.tryFinalAcceptance(),!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),\"computeProgress\"in this\u0026\u0026(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error(\"getConstructorParams not implemented\")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved\u0026\u0026!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 x8(t){const e=`${t.connectionName}:source-${t.sourcePointIndex}`;return{boundaryExitPointId:`fanout-exit:${e}`,planeExitPointId:`fanout-plane:${e}`,traceId:`fanout:${e}`,viaObstacleId:`fanout-via:${e}`,planeEndpointPointId:`fanout-plane-endpoint-point:${e}`,planeEndpointTraceId:`fanout-plane-endpoint:${e}`,planeEndpointViaObstacleId:`fanout-plane-endpoint-via:${e}`}}function v8(t,e,n=!1){const o=n?t.planeEndpointVia:t.via;if(!o)return null;const i=o.spanLayers.map(n=\u003e{const o=e.indexOf(n);if(o\u003c0)throw new Error(`FanoutSolver: via for \"${t.connectionName}\" uses unknown layer \"${n}\"`);return o}),r=x8(t);return{obstacleId:n?r.planeEndpointViaObstacleId:r.viaObstacleId,type:\"rect\",center:o.center,width:o.diameter,height:o.diameter,layers:o.spanLayers,zLayers:i,__zLayers:i,connectedTo:[t.connectionName,t.trace.pcb_trace_id]}}function S8(t){const{inputSrj:e,plans:n,layerNames:o}=t,i=e.connections.map(t=\u003e({...t,pointsToConnect:t.pointsToConnect.map(t=\u003e({...t}))})),r=[],s=new Set;for(const t of n){const e=i[t.connectionIndex];if(!e)throw new Error(`FanoutSolver: output connection index ${t.connectionIndex} is missing`);const n=x8(t);e.pointsToConnect[t.sourcePointIndex]={x:t.exitPoint.x,y:t.exitPoint.y,layer:t.targetLayer,pointId:\"plane\"===t.termination.type?n.planeExitPointId:n.boundaryExitPointId},\"plane\"===t.termination.type\u0026\u0026s.add(t.connectionName);const a=v8(t,o);a\u0026\u0026r.push(a);const c=v8(t,o,!0);c\u0026\u0026r.push(c)}const a=n.flatMap(t=\u003e[t.trace,...t.planeEndpointTrace?[t.planeEndpointTrace]:[]]),c=a.flatMap(t=\u003et.route.filter(t=\u003e\"x\"in t\u0026\u0026\"y\"in t)),l=Math.max(e.defaultObstacleMargin??0,e.minTraceWidth),d=0===c.length?{...e.bounds}:{minX:Math.min(e.bounds.minX,...c.map(t=\u003et.x-l)),maxX:Math.max(e.bounds.maxX,...c.map(t=\u003et.x+l)),minY:Math.min(e.bounds.minY,...c.map(t=\u003et.y-l)),maxY:Math.max(e.bounds.maxY,...c.map(t=\u003et.y+l))};return{...e,fanoutPlaneConnectivity:n.flatMap(t=\u003e\"plane\"===t.termination.type?[{connectionName:t.connectionName,layer:t.termination.layer}]:[]),bounds:d,connections:i.filter(t=\u003e!s.has(t.name)),buses:e.buses?.map(t=\u003e({...t,connectionNames:t.connectionNames.filter(t=\u003e!s.has(t))})).filter(t=\u003et.connectionNames.length\u003e0),obstacles:[...e.obstacles.map(t=\u003e({...t,center:{...t.center},layers:[...t.layers],connectedTo:[...t.connectedTo]})),...r],traces:[...(e.traces??[]).map(t=\u003e({...t,route:t.route.map(t=\u003e({...t}))})),...a]}}var I8=1e-9;function C8(t){return\"circle\"===t.shape}function P8(t,e){const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}}function M8(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function N8(t,e,n){const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r\u003cI8?0:((t.x-e.x)*o+(t.y-e.y)*i)/r,a=Math.max(0,Math.min(1,s));return Math.hypot(t.x-(e.x+a*o),t.y-(e.y+a*i))}function w8(t,e,n){return(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x)}function T8(t,e,n,o){return function(t,e,n,o){const i=w8(n,o,t),r=w8(n,o,e),s=w8(t,e,n),a=w8(t,e,o);return(i\u003e0\u0026\u0026r\u003c0||i\u003c0\u0026\u0026r\u003e0)\u0026\u0026(s\u003e0\u0026\u0026a\u003c0||s\u003c0\u0026\u0026a\u003e0)}(t,e,n,o)?0:Math.min(N8(t,n,o),N8(e,n,o),N8(n,t,e),N8(o,t,e))}function R8(t,e,n=1e-9){if(C8(e))return M8(t,e.center)\u003c=e.width/2+n;const o=P8(t,e);return Math.abs(o.x)\u003c=e.width/2+n\u0026\u0026Math.abs(o.y)\u003c=e.height/2+n}function E8(t,e){if(C8(e))return Math.max(0,M8(t,e.center)-e.width/2);const n=P8(t,e),o=Math.max(Math.abs(n.x)-e.width/2,0),i=Math.max(Math.abs(n.y)-e.height/2,0);return Math.hypot(o,i)}function A8(t,e){if(C8(e))return Math.max(0,N8(e.center,t.start,t.end)-e.width/2);const n=P8(t.start,e),o=P8(t.end,e);if(Math.abs(n.x)\u003c=e.width/2+I8\u0026\u0026Math.abs(n.y)\u003c=e.height/2+I8)return 0;if(Math.abs(o.x)\u003c=e.width/2+I8\u0026\u0026Math.abs(o.y)\u003c=e.height/2+I8)return 0;const i=-e.width/2,r=e.width/2,s=-e.height/2,a=e.height/2,c=[{x:i,y:s},{x:r,y:s},{x:r,y:a},{x:i,y:a}];let l=Number.POSITIVE_INFINITY;for(let t=0;t\u003cc.length;t++)l=Math.min(l,T8(n,o,c[t],c[(t+1)%c.length]));return l}function O8(t,e,n){if(t.layer!==e.layer)return!0;const o=(t.width+e.width)/2+n;return T8(t.start,t.end,e.start,e.end)\u003e=o-I8}function k8(t){if(!Number.isInteger(t)||t\u003c1)throw new Error(`FanoutSolver: layerCount must be a positive integer, received ${t}`);return 1===t?[\"top\"]:2===t?[\"top\",\"bottom\"]:[\"top\",...Array.from({length:t-2},(t,e)=\u003e`inner${e+1}`),\"bottom\"]}function L8(t,e,n){const o=n.indexOf(t),i=n.indexOf(e);if(o\u003c0||i\u003c0)throw new Error(`FanoutSolver: cannot build via span from \"${t}\" to \"${e}\"`);const r=Math.min(o,i),s=Math.max(o,i);return n.slice(r,s+1)}var D8=new WeakMap;function z8(t){return t.netConnectionName??t.rootConnectionName??t.name}function F8(t,e,n){if(!e)return!1;const o=t.get(e)??new Set,i=o.size;return o.add(n),t.set(e,o),o.size!==i}function B8(t,e){const n=new Set;for(const o of e)for(const e of t.get(o)??[])n.add(e);return n}function j8(t){const e=D8.get(t);if(e)return e;const n=function(t){const e=new Map,n=new Map;for(const o of t.connections){const t=z8(o);e.set(o.name,t),F8(n,o.name,t),F8(n,o.rootConnectionName,t),F8(n,o.netConnectionName,t);for(const e of o.pointsToConnect)F8(n,e.pointId,t),F8(n,e.pcb_port_id,t)}for(const o of t.traces??[]){const t=o.connection_name?e.get(o.connection_name):void 0;if(t){F8(n,o.pcb_trace_id,t);for(const e of o.connectsTo??[])F8(n,e,t)}}for(let e=0;e\u003c2;e++){let e=!1;for(const o of t.obstacles){const t=B8(n,o.connectedTo);if(1!==t.size)continue;const i=[...t][0];for(const t of o.connectedTo)e=F8(n,t,i)||e}if(!e)break}const o=new Map,i=t=\u003e{const e=o.get(t)??t;if(o.set(t,e),e===t)return t;const n=i(e);return o.set(t,n),n},r=(t,e)=\u003e{const n=i(t),r=i(e);n!==r\u0026\u0026o.set(r,n)};for(const t of n.values()){const[e,...n]=[...t];if(e)for(const t of n)r(e,t)}for(const e of[...t.obstacles.map(t=\u003et.connectedTo),...(t.traces??[]).map(t=\u003et.connectsTo??[])]){const[t,...o]=[...B8(n,e)];if(t)for(const e of o)r(t,e)}for(const[t,n]of e)e.set(t,i(n));for(const[t,e]of n)n.set(t,new Set([...e].map(t=\u003ei(t))));return{connectionNetKeys:e,tokenNetKeys:n}}(t);return D8.set(t,n),n}function $8(t,e,n){const o=j8(t),i=o.connectionNetKeys.get(e),r=o.connectionNetKeys.get(n);return void 0!==i\u0026\u0026i===r}function Y8(t,e,n){const o=j8(t),i=o.connectionNetKeys.get(n);return!!i\u0026\u0026e.connectedTo.some(t=\u003eo.tokenNetKeys.get(t)?.has(i))}var X8=1e-6;function V8(t){return\"layer\"in t?[t.layer]:t.layers}function W8(t,e){return t.some(t=\u003ee.includes(t))}function H8(t,e){const n=[];let o;for(const i of t.route)\"via\"!==i.route_type?\"wire\"===i.route_type\u0026\u0026(o\u0026\u0026o.layer===i.layer\u0026\u0026M8(o,i)\u003eX8\u0026\u0026n.push({type:\"segment\",segment:{start:{x:o.x,y:o.y},end:{x:i.x,y:i.y},width:i.width,layer:i.layer}}),o=i):(n.push({type:\"via\",center:{x:i.x,y:i.y},diameter:i.via_diameter??0,layers:L8(i.from_layer,i.to_layer,e)}),o=void 0);return n}function G8(t,e){return\"plane\"===t.type\u0026\u0026\"plane\"===e.type?t.layer===e.layer:\"plane\"===t.type\u0026\u0026\"via\"===e.type?e.layers.includes(t.layer):\"via\"===t.type\u0026\u0026\"plane\"===e.type?G8(e,t):\"plane\"===t.type\u0026\u0026\"segment\"===e.type?t.layer===e.segment.layer:\"segment\"===t.type\u0026\u0026\"plane\"===e.type?G8(e,t):\"endpoint\"===t.type\u0026\u0026\"endpoint\"===e.type?W8(t.layers,e.layers)\u0026\u0026M8(t.point,e.point)\u003c=X8:\"endpoint\"===t.type\u0026\u0026\"obstacle\"===e.type?W8(t.layers,e.obstacle.layers)\u0026\u0026R8(t.point,e.obstacle,X8):\"obstacle\"===t.type\u0026\u0026\"endpoint\"===e.type?G8(e,t):\"endpoint\"===t.type\u0026\u0026\"segment\"===e.type?t.layers.includes(e.segment.layer)\u0026\u0026N8(t.point,e.segment.start,e.segment.end)\u003c=e.segment.width/2+X8:\"segment\"===t.type\u0026\u0026\"endpoint\"===e.type?G8(e,t):\"endpoint\"===t.type\u0026\u0026\"via\"===e.type?W8(t.layers,e.layers)\u0026\u0026M8(t.point,e.center)\u003c=e.diameter/2+X8:\"via\"===t.type\u0026\u0026\"endpoint\"===e.type?G8(e,t):\"obstacle\"===t.type\u0026\u0026\"segment\"===e.type?t.obstacle.layers.includes(e.segment.layer)\u0026\u0026A8(e.segment,t.obstacle)\u003c=e.segment.width/2+X8:\"segment\"===t.type\u0026\u0026\"obstacle\"===e.type?G8(e,t):\"obstacle\"===t.type\u0026\u0026\"via\"===e.type?W8(t.obstacle.layers,e.layers)\u0026\u0026E8(e.center,t.obstacle)\u003c=e.diameter/2+X8:\"via\"===t.type\u0026\u0026\"obstacle\"===e.type?G8(e,t):\"segment\"===t.type\u0026\u0026\"segment\"===e.type?t.segment.layer===e.segment.layer\u0026\u0026T8(t.segment.start,t.segment.end,e.segment.start,e.segment.end)\u003c=(t.segment.width+e.segment.width)/2+X8:\"segment\"===t.type\u0026\u0026\"via\"===e.type?e.layers.includes(t.segment.layer)\u0026\u0026N8(e.center,t.segment.start,t.segment.end)\u003c=e.diameter/2+t.segment.width/2+X8:\"via\"===t.type\u0026\u0026\"segment\"===e.type?G8(e,t):\"via\"===t.type\u0026\u0026\"via\"===e.type\u0026\u0026(W8(t.layers,e.layers)\u0026\u0026M8(t.center,e.center)\u003c=(t.diameter+e.diameter)/2+X8)}var U8=class{parent;constructor(t){this.parent=Array.from({length:t},(t,e)=\u003ee)}find(t){const e=this.parent[t];if(e===t)return t;const n=this.find(e);return this.parent[t]=n,n}union(t,e){const n=this.find(t),o=this.find(e);n!==o\u0026\u0026(this.parent[o]=n)}};function Z8(t,e,n){return Boolean(e.connection_name\u0026\u0026$8(t,e.connection_name,n.name))}function q8(t){const{inputSrj:e,routedSrj:n}=t,o=n.fanoutPlaneConnectivity,i=k8(n.layerCount),r=new Map;for(const t of e.connections){const e=z8(t),n=r.get(e)??[];n.push(t),r.set(e,n)}const s=[];let a=0,c=0;for(const t of r.values()){const r=t[0],l=t.flatMap(t=\u003et.pointsToConnect.map((e,n)=\u003e({type:\"endpoint\",connectionName:t.name,endpointIndex:n,point:e,layers:V8(e)}))),d=e.obstacles.filter(t=\u003eY8(e,t,r.name)).map(t=\u003e({type:\"obstacle\",obstacle:t})),h=(n.traces??[]).filter(t=\u003eZ8(e,t,r)).flatMap(t=\u003eH8(t,i)),u=[...new Set((o??[]).flatMap(t=\u003e$8(e,t.connectionName,r.name)?[t.layer]:[]))].map(t=\u003e({type:\"plane\",layer:t})),p=[...l,...d,...h,...u],m=new U8(p.length);for(let t=0;t\u003cp.length;t++)for(let e=t+1;e\u003cp.length;e++)G8(p[t],p[e])\u0026\u0026m.union(t,e);const g=new Map;for(let t=0;t\u003cl.length;t++){const e=l[t],n=g.get(e.connectionName)??[];n[e.endpointIndex]=t,g.set(e.connectionName,n)}for(const e of t){const t=g.get(e.name)??[],n=t[0],o=void 0===n?void 0:m.find(n),i=t.flatMap((t,e)=\u003evoid 0===o||m.find(t)!==o?[e]:[]);c+=t.length-i.length,0===i.length?a++:s.push({code:\"original-endpoints-disconnected\",connectionName:e.name,disconnectedEndpointIndices:i,message:`Connection ${e.name} has no physical copper path from endpoint 0 to original endpoint${1===i.length?\"\":\"s\"} ${i.join(\", \")}`})}}const l=e.connections.reduce((t,e)=\u003et+e.pointsToConnect.length,0);return{valid:0===s.length,checkedConnectionCount:e.connections.length,connectedConnectionCount:a,checkedEndpointCount:l,connectedEndpointCount:c,issues:s}}var J8=1e-6;function K8(t){const{inputSrj:e,segment:n,bodyObstacle:o,connectionName:i}=t;if(o.connectedTo.length\u003e0||!o.componentId)return!1;const r=e.obstacles.filter(t=\u003et.componentId===o.componentId\u0026\u0026t.layers.includes(n.layer)\u0026\u0026Y8(e,t,i));for(const t of r)for(const[e,i]of[[n.start,n.end],[n.end,n.start]]){if(!R8(e,t,J8))continue;const n={x:e.x-o.center.x,y:e.y-o.center.y},r={x:i.x-e.x,y:i.y-e.y};if(n.x*r.x+n.y*r.y\u003eJ8)return!0}return!1}function Q8(t,e){return M8(t,e)\u003c=J8}function t7(t,e){t.push(e)}function e7(t){const{srj:e,trace:n,connectionName:o,layerNames:i,issues:r}=t,s=[],a=[];let c,l;for(const t of n.route){if(\"via\"===t.route_type){const s=L8(t.from_layer,t.to_layer,i);a.push({center:{x:t.x,y:t.y},diameter:t.via_diameter??e.minViaPadDiameter??e.minTraceWidth,spanLayers:s}),c\u0026\u0026Q8(c,t)\u0026\u0026c.layer===t.from_layer||t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} reaches a via without a matching ${t.from_layer} wire endpoint`}),l=t;continue}\"wire\"===t.route_type?l?(Q8(t,l)\u0026\u0026t.layer===l.to_layer||t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} does not continue from its via on ${l.to_layer}`}),c=t,l=void 0):(c\u0026\u0026(c.layer!==t.layer?t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} changes from ${c.layer} to ${t.layer} without a via`}):Q8(c,t)||s.push({start:{x:c.x,y:c.y},end:{x:t.x,y:t.y},width:t.width,layer:t.layer})),c=t):(t7(r,{code:\"unsupported-route-point\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} contains unsupported ${t.route_type} geometry`}),c=void 0,l=void 0)}return l\u0026\u0026t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} ends at a via without a wire on ${l.to_layer}`}),{trace:n,connectionName:o,segments:s,vias:a}}function n7(t){const{inputSrj:e,routedSrj:n,clearance:o}=t,i=[],r=k8(n.layerCount),s=[],a=[e,n].flatMap(t=\u003et.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({connectionName:t.name,point:e}))));for(const t of n.traces??[]){const o=t.connection_name;o\u0026\u0026e.connections.some(t=\u003et.name===o)?s.push(e7({srj:n,trace:t,connectionName:o,layerNames:r,issues:i})):t7(i,{code:\"unknown-trace-connection\",traceId:t.pcb_trace_id,...o?{connectionName:o}:{},message:`Trace ${t.pcb_trace_id} does not identify an input connection`})}for(const t of s){for(const n of t.segments)for(const r of e.obstacles){if(!r.layers.includes(n.layer)||Y8(e,r,t.connectionName))continue;if(K8({inputSrj:e,segment:n,bodyObstacle:r,connectionName:t.connectionName}))continue;const s=A8(n,r),a=n.width/2+o;s\u003ca-J8\u0026\u0026t7(i,{code:\"trace-obstacle-clearance\",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,layer:n.layer,obstacleId:r.obstacleId,message:`Trace ${t.trace.pcb_trace_id} on ${n.layer} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId}; ${a.toFixed(4)}mm is required`})}for(const n of t.vias){const r=a.find(({point:t})=\u003eM8(n.center,t)\u003c=J8);r\u0026\u0026t7(i,{code:\"via-at-endpoint\",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,otherConnectionName:r.connectionName,message:`Via in ${t.trace.pcb_trace_id} is placed directly at an original or routed connection endpoint`});for(const r of e.obstacles){if(!r.layers.some(t=\u003en.spanLayers.includes(t))||Y8(e,r,t.connectionName))continue;const s=E8(n.center,r),a=n.diameter/2+o;s\u003ca-J8\u0026\u0026t7(i,{code:\"via-obstacle-clearance\",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,obstacleId:r.obstacleId,message:`Via in ${t.trace.pcb_trace_id} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId} on its layer span; ${a.toFixed(4)}mm is required`})}}}for(let t=0;t\u003cs.length;t++){const n=s[t];for(let r=t+1;r\u003cs.length;r++){const t=s[r];if(!$8(e,n.connectionName,t.connectionName)){for(const e of n.segments){for(const r of t.segments)O8(e,r,o)||t7(i,{code:\"different-net-trace-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:e.layer,message:`Different-net traces ${n.trace.pcb_trace_id} and ${t.trace.pcb_trace_id} intersect or violate clearance on ${e.layer}`});for(const r of t.vias)!r.spanLayers.includes(e.layer)||N8(r.center,e.start,e.end)\u003e=r.diameter/2+e.width/2+o-J8||t7(i,{code:\"different-net-trace-via-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:e.layer,message:`Trace ${n.trace.pcb_trace_id} violates via clearance to ${t.trace.pcb_trace_id} on ${e.layer}`})}for(const e of n.vias){for(const r of t.segments)!e.spanLayers.includes(r.layer)||N8(e.center,r.start,r.end)\u003e=e.diameter/2+r.width/2+o-J8||t7(i,{code:\"different-net-trace-via-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:r.layer,message:`Via in ${n.trace.pcb_trace_id} violates trace clearance to ${t.trace.pcb_trace_id} on ${r.layer}`});for(const r of t.vias)!e.spanLayers.some(t=\u003er.spanLayers.includes(t))||M8(e.center,r.center)\u003e=(e.diameter+r.diameter)/2+o-J8||t7(i,{code:\"different-net-via-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,message:`Different-net vias in ${n.trace.pcb_trace_id} and ${t.trace.pcb_trace_id} violate clearance on an overlapping layer span`})}}}}return{valid:0===i.length,checkedTraceCount:n.traces?.length??0,checkedSegmentCount:s.reduce((t,e)=\u003et+e.segments.length,0),checkedViaCount:s.reduce((t,e)=\u003et+e.vias.length,0),issues:i}}var o7=1e-9;function i7(t,e){if(\"layer\"in t)return t.layer;if(e\u0026\u0026t.layers.includes(e))return e;const n=t.layers[0];if(!n)throw new Error(\"Endpoint completion received a layerless point\");return n}function r7(t){const e=[];for(const n of t)e.at(-1)\u0026\u0026M8(e.at(-1),n)\u003co7||e.push(n);return e}function s7(t,e){const n=r7(t);if(n.length\u003c3)return n;const o=[n[0]];for(let t=1;t\u003cn.length-1;t++){const i=n[t-1],r=n[t],s=n[t+1],a=M8(i,r),c=M8(r,s),l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c};if(Math.abs(l.x*d.x+l.y*d.y)\u003e1e-6){o.push(r);continue}const h=Math.min(e,a/2,c/2);o.push({x:r.x-l.x*h,y:r.y-l.y*h}),o.push({x:r.x+d.x*h,y:r.y+d.y*h})}return o.push(n.at(-1)),r7(o)}function a7(t){const{inputSrj:e,plan:n}=t,o=i7(n.targetPoint),i=function(t){const{inputSrj:e,connectionName:n,target:o,targetLayer:i}=t;return e.obstacles.find(t=\u003et.layers.includes(i)\u0026\u0026Y8(e,t,n)\u0026\u0026R8(o,t,1e-6))}({inputSrj:e,connectionName:n.connectionName,target:n.targetPoint,targetLayer:o}),r=e.obstacles.find(t=\u003et.componentId===i?.componentId\u0026\u00260===t.connectedTo.length),s=r?{x:n.targetPoint.x-r.center.x,y:n.targetPoint.y-r.center.y}:{x:n.targetPoint.x-n.sourcePoint.x,y:n.targetPoint.y-n.sourcePoint.y},a=Math.hypot(s.x,s.y),c=a\u003eo7?{x:s.x/a,y:s.y/a}:{x:1,y:0};return{outward:c,perpendicular:{x:-c.y,y:c.x}}}function c7(t){const{plan:e,branchStart:n,viaPoint:o,assignedLayerPath:i,terminalApproach:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,candidateIndex:l,chamfer:d}=t,h=i7(e.targetPoint),u=s7(i,d),p=s7([o,...r?[r]:[],e.targetPoint],d),m=u.map(t=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:s,layer:n.layer}));n.layer!==h\u0026\u0026(m.push({route_type:\"via\",x:o.x,y:o.y,from_layer:n.layer,to_layer:h,via_diameter:a,via_hole_diameter:c}),m.push({route_type:\"wire\",x:o.x,y:o.y,width:s,layer:h}));for(const t of p.slice(1))m.push({route_type:\"wire\",x:t.x,y:t.y,width:s,layer:h});return{type:\"pcb_trace\",pcb_trace_id:(g={connectionName:e.connectionName,sourcePointIndex:e.sourcePointIndex,candidateIndex:l},`fanout-completion:${g.connectionName}:source-${g.sourcePointIndex}:${g.candidateIndex}`),connection_name:e.connectionName,route:m};var g}function l7(t,e){return!t.issues.some(t=\u003et.connectionName===e)}function d7(t){const{trace:e,endpointSrjs:n}=t,o=n.flatMap(t=\u003et.connections.flatMap(t=\u003et.pointsToConnect));return e.route.some(t=\u003e\"via\"===t.route_type\u0026\u0026o.some(e=\u003eM8(t,e)\u003c=1e-6))}function h7(t){const{inputSrj:e,fanoutSrj:n,plan:o,acceptedTraces:i,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,clearance:c}=t,{outward:l,perpendicular:d}=a7({inputSrj:e,plan:o}),h=[...o.via?[{x:o.via.center.x,y:o.via.center.y,layer:o.targetLayer}]:[],{x:o.sourcePoint.x,y:o.sourcePoint.y,layer:o.sourceLayer}];let u=[],p=Number.POSITIVE_INFINITY,m=0;const g=e.connections.length\u003e32?600:Number.POSITIVE_INFINITY,f=\"plane\"===o.termination.type?g7({trace:o.trace,endpoint:o.exitPoint,layer:o.sourceLayer,distances:[.2,.3,.4]}):[],y=[...\"plane\"===o.termination.type\u0026\u0026o.via?[{...o.via.center}]:[],...f,...[.4,.8,1.2,1.6].flatMap(t=\u003e[0,.4,-.4,.8,-.8,1.2,-1.2,1.6,-1.6].map(e=\u003e({x:o.sourcePoint.x+l.x*t+d.x*e,y:o.sourcePoint.y+l.y*t+d.y*e})))];for(const t of y){const y=[...\"plane\"===o.termination.type?[{...t,layer:o.targetLayer}]:[],...h,...f.flatMap(e=\u003eM8(e,t)\u003c=1e-6?[{...e,layer:o.sourceLayer}]:[])];for(const h of y){const f=M8(h,t)\u003c=1e-6?[[h]]:[[h,t],[h,{x:t.x,y:h.y},t],[h,{x:h.x,y:t.y},t],...[.4,-.4].map(e=\u003e[h,{x:h.x+e,y:h.y},{x:h.x+e,y:t.y},t])];for(const y of f){const f=[void 0,...[.4,.8].map(t=\u003e({x:o.targetPoint.x+l.x*t,y:o.targetPoint.y+l.y*t})),...[.4,-.4].map(t=\u003e({x:o.targetPoint.x+.4*l.x+d.x*t,y:o.targetPoint.y+.4*l.y+d.y*t}))];for(const l of f){if(m\u003e=g)return{blockingConnectionNames:u};const d=c7({plan:o,branchStart:h,viaPoint:t,assignedLayerPath:y,terminalApproach:l,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,candidateIndex:m++,chamfer:0});if(d7({trace:d,endpointSrjs:[e,n]}))continue;const f={...n,traces:[...n.traces??[],...i,d]},_=n7({inputSrj:e,routedSrj:f,clearance:c});if(!_.valid){_.issues.length\u003cp\u0026\u0026(p=_.issues.length,u=[...new Set(_.issues.flatMap(t=\u003e[t.connectionName,t.otherConnectionName].flatMap(t=\u003et\u0026\u0026t!==o.connectionName?[t]:[])))]);continue}if(l7(q8({inputSrj:e,routedSrj:f}),o.connectionName))return{trace:d,blockingConnectionNames:[]}}}}}return{blockingConnectionNames:u}}function u7(t){const{inputSrj:e,fanoutSrj:n,plans:o,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a}=t,c=[],l=[],d=new Set;for(const t of o){const o=h7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:c,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});if(o.trace)c.push(o.trace);else{l.push(t.connectionName);for(const t of o.blockingConnectionNames)d.add(t)}}const h={...n,traces:[...n.traces??[],...c]};return{traces:c,failedConnectionNames:l,blockingConnectionNames:[...d],connectivity:q8({inputSrj:e,routedSrj:h}),drc:n7({inputSrj:e,routedSrj:h,clearance:a})}}function p7(t){let e,n=0;for(const o of t.route)\"wire\"===o.route_type?(e?.layer===o.layer\u0026\u0026(n+=M8(e,o)),e=o):e=void 0;return n}function m7(t){const e=k8(t.layerCount),n=[];for(const o of t.traces??[]){let i;for(const r of o.route)if(\"via\"!==r.route_type)if(\"wire\"===r.route_type){if(i?.layer===r.layer){const t=M8(i,r);t\u003eo7\u0026\u0026n.push({obstacleId:`endpoint-completion-keepout:${o.pcb_trace_id}:segment:${n.length}`,type:\"rect\",center:{x:(i.x+r.x)/2,y:(i.y+r.y)/2},width:t,height:Math.max(i.width,r.width),ccwRotationDegrees:180*Math.atan2(r.y-i.y,r.x-i.x)/Math.PI,layers:[r.layer],connectedTo:[o.connection_name]})}i=r}else i=void 0;else n.push({obstacleId:`endpoint-completion-keepout:${o.pcb_trace_id}:via:${n.length}`,type:\"rect\",center:{x:r.x,y:r.y},width:r.via_diameter??t.minViaPadDiameter??.3,height:r.via_diameter??t.minViaPadDiameter??.3,layers:L8(r.from_layer,r.to_layer,e),connectedTo:[o.connection_name]}),i=void 0}return n}function g7(t){const{trace:e,endpoint:n,layer:o,distances:i}=t,r=e.route.findLastIndex(t=\u003e\"wire\"===t.route_type\u0026\u0026t.layer===o\u0026\u0026M8(t,n)\u003c=1e-6);return r\u003c0?[]:i.flatMap(t=\u003e{let i=t,s=n;for(let t=r-1;t\u003e=0;t--){const n=e.route[t];if(\"wire\"!==n?.route_type||n.layer!==o)break;const r=M8(s,n);if(!(r\u003c=o7)){if(i\u003cr-1e-6)return[{x:s.x+(n.x-s.x)*i/r,y:s.y+(n.y-s.y)*i/r}];i-=r,s=n}}return[]})}function f7(t){const{inputSrj:e,fanoutSrj:n,plan:o,acceptedTraces:i,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,clearance:c}=t,l={x:o.exitPoint.x,y:o.exitPoint.y,layer:o.targetLayer},d=o.targetPoint,h=i7(d);let u=0;const p=t=\u003e{const l=c7({plan:o,branchStart:t.start,viaPoint:t.viaPoint,assignedLayerPath:[t.start,t.viaPoint],terminalApproach:t.terminalApproach,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,candidateIndex:1e4+u++,chamfer:Math.max(r,.1)});if(d7({trace:l,endpointSrjs:[e,n]}))return;const d={...n,traces:[...n.traces??[],...i,l]};return n7({inputSrj:e,routedSrj:d,clearance:c}).valid\u0026\u0026l7(q8({inputSrj:e,routedSrj:d}),o.connectionName)?l:void 0};if(l.layer!==h){const t=g7({trace:o.trace,endpoint:o.exitPoint,layer:o.targetLayer,distances:[.4,.8,1.2,1.6]});for(const e of t){const t={...e,layer:o.targetLayer};for(const n of[void 0,{x:d.x,y:e.y},{x:e.x,y:d.y}]){const o=p({start:t,viaPoint:e,terminalApproach:n});if(o)return o}}}const m=[[d],[{x:d.x,y:l.y},d],[{x:l.x,y:d.y},d]];for(const t of m){const e=t[0],n=M8(l,e),o=l.layer===h?[0]:[.4,.8,1.2,1.6];for(const i of o){if(l.layer!==h\u0026\u0026(n\u003c=i+.2||i\u003c=1e-6))continue;const o=p({start:l,viaPoint:l.layer===h?{x:l.x,y:l.y}:{x:l.x+(e.x-l.x)*i/n,y:l.y+(e.y-l.y)*i/n},terminalApproach:t.length\u003e1?e:void 0});if(o)return o}}}function y7(t){const{inputSrj:e,fanoutSrj:n,plans:o,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a,effort:c=1,routeDownstreamConnections:l}=t,d=[],h=n7({inputSrj:e,routedSrj:n,clearance:a}),u=q8({inputSrj:e,routedSrj:n}),p=o.filter(t=\u003ei7(t.sourcePoint)!==i7(t.targetPoint)\u0026\u0026M8(t.sourcePoint,t.targetPoint)\u003c=.25\u0026\u0026!l7(u,t.connectionName));let m={traces:[],failedConnectionNames:p.map(t=\u003et.connectionName),blockingConnectionNames:[],connectivity:u,drc:h},g=0;if(h.valid){let t=[];const o=new Map(p.map((t,e)=\u003e[t.connectionName,e])),c=e.connections.length\u003e32?1:3;for(let l=0;l\u003cc;l++){const c=new Map(t.map((t,e)=\u003e[t,e])),l=u7({inputSrj:e,fanoutSrj:n,plans:p.toSorted((t,e)=\u003e(c.get(t.connectionName)??Number.MAX_SAFE_INTEGER)-(c.get(e.connectionName)??Number.MAX_SAFE_INTEGER)||(o.get(t.connectionName)??0)-(o.get(e.connectionName)??0)),traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});if(g++,l.drc.valid\u0026\u0026(l.connectivity.connectedConnectionCount\u003em.connectivity.connectedConnectionCount||l.connectivity.connectedConnectionCount===m.connectivity.connectedConnectionCount\u0026\u0026l.traces.length\u003cm.traces.length)\u0026\u0026(m=l),t=[...new Set([...l.failedConnectionNames,...l.blockingConnectionNames,...t])],0===l.failedConnectionNames.length)break}}else d.push(\"Fanout prefix failed emitted-copper DRC; skipped completion\");const f=new Set(p.map(t=\u003et.connectionName)),y=o.filter(t=\u003e!f.has(t.connectionName)\u0026\u0026!l7(u,t.connectionName)),_=[];if(h.valid)for(const t of y){const o=f7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:[...m.traces,..._],traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});o\u0026\u0026_.push(o)}const b={...n,traces:[...n.traces??[],...m.traces,..._]},x=new Set(q8({inputSrj:e,routedSrj:b}).issues.map(t=\u003et.connectionName)),v=n.connections.filter(t=\u003e!f.has(t.name)\u0026\u0026x.has(t.name));let S=[];if(h.valid\u0026\u0026v.length\u003e0\u0026\u0026v.length\u003c=12\u0026\u0026l){const t=new Set(v.map(t=\u003et.name)),o={...n,connections:v,buses:n.buses?.map(e=\u003e({...e,connectionNames:e.connectionNames.filter(e=\u003et.has(e))})).filter(t=\u003et.connectionNames.length\u003e0),obstacles:[...n.obstacles,...m7(n)],traces:[]};try{const i=l(o,{effort:c});S=function(t){const{inputSrj:e,fanoutSrj:n,localTraces:o,candidates:i,clearance:r}=t,s=[...n.traces??[],...o],a={...n,traces:s},c=q8({inputSrj:e,routedSrj:a}),l=i.filter(t=\u003et.route.length\u003e1\u0026\u0026t.route.every(t=\u003e\"wire\"===t.route_type||\"via\"===t.route_type)\u0026\u0026!d7({trace:t,endpointSrjs:[e,n]})).filter(t=\u003e{const o=q8({inputSrj:e,routedSrj:{...n,traces:[...s,t]}});return o.connectedConnectionCount\u003ec.connectedConnectionCount\u0026\u0026l7(o,t.connection_name)}),d={...n,traces:[...s,...l]};if(n7({inputSrj:e,routedSrj:d,clearance:r}).valid)return l;const h=[];for(const t of l.toSorted((t,e)=\u003ep7(t)-p7(e))){const o={...n,traces:[...s,...h,t]};if(!n7({inputSrj:e,routedSrj:o,clearance:r}).valid)continue;const i=q8({inputSrj:e,routedSrj:{...n,traces:[...s,...h]}}),a=q8({inputSrj:e,routedSrj:o});a.connectedConnectionCount\u003ei.connectedConnectionCount\u0026\u0026l7(a,t.connection_name)\u0026\u0026h.push(t)}return h}({inputSrj:e,fanoutSrj:n,localTraces:[...m.traces,..._],candidates:i.filter(e=\u003et.has(e.connection_name)),clearance:a})}catch(t){d.push(`Downstream router failed: ${t instanceof Error?t.message:String(t)}`)}}else!h.valid\u0026\u0026v.length\u003e0?d.push(\"Skipped downstream router because the endpoint-completion baseline failed emitted-copper DRC\"):v.length\u003e12?d.push(`Skipped downstream router for ${v.length} unresolved connections (bounded at 12)`):v.length\u003e0\u0026\u0026!l\u0026\u0026d.push(`Skipped downstream router for ${v.length} unresolved connections because no routeDownstreamConnections callback was provided`);const I=[...m.traces,..._,...S];for(const t of y){if(l7(q8({inputSrj:e,routedSrj:{...n,traces:[...n.traces??[],...I]}}),t.connectionName))continue;const o=f7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:I,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});o\u0026\u0026I.push(o)}const C=function(t){const{fanoutSrj:e,completionTraces:n}=t,o=new Map(n.flatMap(t=\u003e{const e=t.route.find(t=\u003e\"wire\"===t.route_type);return e?[[t.connection_name,{x:e.x,y:e.y,layer:e.layer}]]:[]})),i=(e.traces??[]).map(t=\u003e{if(!t.pcb_trace_id.startsWith(\"fanout:\"))return t;const e=o.get(t.connection_name);if(!e)return t;let n;for(let o=0;o\u003ct.route.length;o++){const i=t.route[o];if(\"wire\"===i?.route_type){if(void 0!==n){const o=t.route[n];if(\"wire\"===o?.route_type\u0026\u0026o.layer===e.layer\u0026\u0026i.layer===e.layer\u0026\u0026N8(e,o,i)\u003c=1e-6){const r=t.route.slice(0,n+1);return M8(o,e)\u003e1e-6\u0026\u0026r.push({route_type:\"wire\",x:e.x,y:e.y,width:i.width,layer:e.layer}),{...t,route:r}}}n=o}else n=void 0}return t});return{...e,traces:i}}({fanoutSrj:{...n,traces:[...n.traces??[],...I]},completionTraces:I}),P=q8({inputSrj:e,routedSrj:C}),M=n7({inputSrj:e,routedSrj:C,clearance:a});return M.valid?{simpleRouteJson:C,traces:I,report:{attemptedLocalConnectionCount:p.length,attemptedDownstreamConnectionCount:y.length,completionTraceCount:I.length,searchPassCount:g,errors:d,connectivity:P,drc:M}}:(d.push(\"Final endpoint-completion output failed emitted-copper DRC\"),{simpleRouteJson:n,traces:[],report:{attemptedLocalConnectionCount:p.length,attemptedDownstreamConnectionCount:y.length,completionTraceCount:0,searchPassCount:g,errors:d,connectivity:q8({inputSrj:e,routedSrj:n}),drc:h}})}var _7=new Set([\"left\",\"right\",\"top\",\"bottom\",\"top-left\",\"top-right\",\"bottom-left\",\"bottom-right\"]),b7={top_left:{direction:\"up\",preferredExit:\"top-left\"},top_middle:{direction:\"up\",preferredExit:\"top\"},top_right:{direction:\"up\",preferredExit:\"top-right\"},right_top:{direction:\"right\",preferredExit:\"top-right\"},right_middle:{direction:\"right\",preferredExit:\"right\"},right_bottom:{direction:\"right\",preferredExit:\"bottom-right\"},bottom_right:{direction:\"down\",preferredExit:\"bottom-right\"},bottom_middle:{direction:\"down\",preferredExit:\"bottom\"},bottom_left:{direction:\"down\",preferredExit:\"bottom-left\"},left_bottom:{direction:\"left\",preferredExit:\"bottom-left\"},left_middle:{direction:\"left\",preferredExit:\"left\"},left_top:{direction:\"left\",preferredExit:\"top-left\"},top:{direction:\"up\",preferredExit:\"top\"},right:{direction:\"right\",preferredExit:\"right\"},bottom:{direction:\"down\",preferredExit:\"bottom\"},left:{direction:\"left\",preferredExit:\"left\"}};function x7(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(const t of e)(0===n.length||Math.abs(n[n.length-1]-t)\u003e1e-6)\u0026\u0026n.push(t);return n}function v7(t){let e=Number.POSITIVE_INFINITY;for(let n=1;n\u003ct.length;n++){const o=t[n]-t[n-1];o\u003e1e-6\u0026\u0026(e=Math.min(e,o))}return e}function S7(t,e){const n=\"x\"===e?\"y\":\"x\";let o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ct.length;i++){const r=t[i];for(let s=i+1;s\u003ct.length;s++){const i=t[s];if(Math.abs(r.center[n]-i.center[n])\u003e1e-6)continue;const a=Math.abs(r.center[e]-i.center[e]);a\u003e1e-6\u0026\u0026(o=Math.min(o,a))}}return o}function I7(t){return{minX:Math.min(...t.map(t=\u003et.center.x-t.width/2)),maxX:Math.max(...t.map(t=\u003et.center.x+t.width/2)),minY:Math.min(...t.map(t=\u003et.center.y-t.height/2)),maxY:Math.max(...t.map(t=\u003et.center.y+t.height/2))}}function C7(t,e){const n=e.componentBounds?.[t.componentId];if(!n){const e=2.25*t.pitchX,n=2.25*t.pitchY;return{minX:t.bounds.minX-e,maxX:t.bounds.maxX+e,minY:t.bounds.minY-n,maxY:t.bounds.maxY+n}}if([n.minX,n.maxX,n.minY,n.maxY].some(t=\u003e!Number.isFinite(t))||n.minX\u003e=n.maxX||n.minY\u003e=n.maxY)throw new Error(`FanoutSolver: componentBounds for \"${t.componentId}\" must contain finite, increasing bounds`);if(n.minX\u003et.bounds.minX+1e-6||n.maxX\u003ct.bounds.maxX-1e-6||n.minY\u003et.bounds.minY+1e-6||n.maxY\u003ct.bounds.maxY-1e-6)throw new Error(`FanoutSolver: componentBounds for \"${t.componentId}\" must contain every component pad`);return{...n}}function P7(t,e){if([t.minX,t.maxX,t.minY,t.maxY].some(t=\u003e!Number.isFinite(t))||t.minX\u003e=t.maxX||t.minY\u003e=t.maxY)throw new Error(\"FanoutSolver: sharedBoundary must contain finite, increasing bounds\");for(const n of e)if(t.minX\u003en.bounds.minX+1e-6||t.maxX\u003cn.bounds.maxX-1e-6||t.minY\u003en.bounds.minY+1e-6||t.maxY\u003cn.bounds.maxY-1e-6)throw new Error(`FanoutSolver: sharedBoundary must contain every pad of component \"${n.componentId}\"`);return{...t}}function M7(t){return\"layer\"in t?[t.layer]:t.layers}function N7(t){const{point:e,connection:n,componentGrids:o}=t,i=M7(e),r=[];for(const t of o){const o=t.obstacles.filter(t=\u003et.layers.some(t=\u003ei.includes(t))).filter(t=\u003eR8(e,t,1e-5)).sort((t,o)=\u003e{const i=t.connectedTo.includes(n.name)||t.connectedTo.includes(e.pointId??\"\")||t.connectedTo.includes(e.pcb_port_id??\"\");return i!==(o.connectedTo.includes(n.name)||o.connectedTo.includes(e.pointId??\"\")||o.connectedTo.includes(e.pcb_port_id??\"\"))?i?-1:1:t.width*t.height-o.width*o.height});o[0]\u0026\u0026r.push({grid:t,obstacle:o[0]})}return r}function w7(t){for(const e of t.pointsToConnect)if(\"layers\"in e\u0026\u0026e.busId)return e.busId;const e=/^BUS[_:-]([^_:-]+)(?:[_:-]\\d+)?$/i.exec(t.name);return e?.[1]??null}function T7(t,e){if(void 0!==e){if(!_7.has(e))throw new Error(`FanoutSolver: bus \"${t}\" has invalid preferredExit \"${e}\"`);return e}}function R7(t){if(void 0===t)return;if(0===t.length)throw new Error(\"FanoutSolver: availableCornersAndSides must contain at least one boundary region\");const e=[],n=new Set;for(const o of t){const t=b7[o];if(!t)throw new Error(`FanoutSolver: invalid availableCornersAndSides value \"${o}\"`);const i=`${t.direction}:${t.preferredExit}`;n.has(i)||(n.add(i),e.push(t))}return e}function E7(t,e){if(void 0===e||\"boundary\"===e.type)return{type:\"boundary\"};if(\"plane\"!==e.type||\"string\"!=typeof e.layer||0===e.layer.length)throw new Error(`FanoutSolver: bus \"${t}\" has an invalid termination target`);return{type:\"plane\",layer:e.layer}}function A7(t,e,n,o){const i=e.pointsToConnect.filter((t,e)=\u003ee!==n).sort((e,n)=\u003eM8(t,n)-M8(t,e))[0];if(!i\u0026\u0026\"plane\"===o.type)return t;if(!i)throw new Error(`FanoutSolver: connection \"${e.name}\" has no target beyond its BGA pad`);return i}function O7(t,e){let n=0,o=0;for(const t of e){const e=t.exitTargetPoint??t.targetPoint;n+=e.x-t.sourcePoint.x,o+=e.y-t.sourcePoint.y}if(Math.abs(n)\u003c1e-9\u0026\u0026Math.abs(o)\u003c1e-9)throw new Error(`FanoutSolver: cannot infer an escape direction for bus \"${t}\"`);return Math.abs(n)\u003e=Math.abs(o)?n\u003e=0?\"right\":\"left\":o\u003e=0?\"up\":\"down\"}function k7(t){return{x:t.reduce((t,e)=\u003et+e.sourcePoint.x,0)/t.length,y:t.reduce((t,e)=\u003et+e.sourcePoint.y,0)/t.length}}function L7(t,e,n){switch(e){case\"left\":return t.x-n.minX;case\"right\":return n.maxX-t.x;case\"up\":return n.maxY-t.y;case\"down\":return t.y-n.minY}}function D7(t,e){return\"up\"===t.direction||\"down\"===t.direction?t.preferredExit.endsWith(\"left\")?e.minX:t.preferredExit.endsWith(\"right\")?e.maxX:(e.minX+e.maxX)/2:t.preferredExit.startsWith(\"top\")?e.maxY:t.preferredExit.startsWith(\"bottom\")?e.minY:(e.minY+e.maxY)/2}function z7(t,e){return\"up\"===e||\"down\"===e?t.x:t.y}function F7(t){const{busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s}=t,a=s.filter(t=\u003e!(void 0!==n\u0026\u0026t.direction!==n||void 0!==o\u0026\u0026t.preferredExit!==o));if(0===a.length)throw new Error(`FanoutSolver: bus \"${e}\" cannot use its requested exit with availableCornersAndSides`);const c=n?void 0:function(t,e){try{return O7(t,e)}catch{return}}(e,i),l=c?a.filter(t=\u003et.direction===c):[],d=l.length\u003e0?l:a,h=k7(i);return[...d].toSorted((t,e)=\u003eL7(h,t.direction,r)-L7(h,e.direction,r)||Math.abs(z7(h,t.direction)-D7(t,r))-Math.abs(z7(h,e.direction)-D7(e,r))||t.preferredExit.localeCompare(e.preferredExit))[0]}function B7(t){const{busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s}=t;if(s)return F7({busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s});if(!o)return{direction:n??O7(e,i)};const a=function(t){switch(t){case\"left\":return[\"left\"];case\"right\":return[\"right\"];case\"top\":return[\"up\"];case\"bottom\":return[\"down\"];case\"top-left\":return[\"up\",\"left\"];case\"top-right\":return[\"up\",\"right\"];case\"bottom-left\":return[\"down\",\"left\"];case\"bottom-right\":return[\"down\",\"right\"]}}(o);if(n){if(!a.includes(n))throw new Error(`FanoutSolver: bus \"${e}\" direction \"${n}\" is incompatible with preferredExit \"${o}\"`);return{direction:n,preferredExit:o}}if(1===a.length)return{direction:a[0],preferredExit:o};let c;try{c=O7(e,i)}catch{c=void 0}if(c\u0026\u0026a.includes(c))return{direction:c,preferredExit:o};const l=k7(i);return{direction:a.toSorted((t,e)=\u003eL7(l,t,r)-L7(l,e,r)||t.localeCompare(e))[0],preferredExit:o}}function j7(t,e){const n=function(t){const e=new Map;for(const n of t){if(!n.componentId||n.isCopperPour)continue;const t=e.get(n.componentId)??[];t.push(n),e.set(n.componentId,t)}const n=[];for(const[t,o]of e){const e=x7(o.map(t=\u003et.center.x)),i=x7(o.map(t=\u003et.center.y)),r=S7(o,\"x\"),s=S7(o,\"y\"),a=v7(e),c=v7(i),l=Math.min(...[r,s,a,c].filter(Number.isFinite)),d=Math.max(...o.flatMap(t=\u003e[t.width,t.height])),h=Number.isFinite(l)?l:d,u=Number.isFinite(r)?r:Number.isFinite(a)?a:h,p=Number.isFinite(s)?s:Number.isFinite(c)?c:h;n.push({componentId:t,obstacles:o,xCoordinates:e,yCoordinates:i,pitchX:u,pitchY:p,bounds:I7(o)})}return n}(t.obstacles);if(0===n.length\u0026\u0026t.connections.length\u003e0)throw new Error(\"FanoutSolver: no componentId-tagged pad footprint was found\");const o=new Map(t.connections.map((t,e)=\u003e[t.name,e])),i=function(t,e){const n=e.buses??t.buses,o=new Map,i=new Set,r=new Set(t.connections.map(t=\u003et.name));for(const t of n??[]){if(o.has(t.busId))throw new Error(`FanoutSolver: duplicate bus id \"${t.busId}\"`);for(const e of t.connectionNames){if(!r.has(e))throw new Error(`FanoutSolver: bus \"${t.busId}\" references unknown connection \"${e}\"`);if(i.has(e))throw new Error(`FanoutSolver: connection \"${e}\" belongs to more than one bus`);i.add(e)}const n=E7(t.busId,t.termination),s=T7(t.busId,e.busExitPreferences?.[t.busId]??t.preferredExit??e.defaultPreferredExit);if(\"plane\"===n.type\u0026\u0026void 0!==s)throw new Error(`FanoutSolver: plane-terminated bus \"${t.busId}\" cannot also specify preferredExit`);o.set(t.busId,{...t,sourceComponentId:t.sourceComponentId??e.sourceComponentId,direction:e.busDirections?.[t.busId]??t.direction??e.defaultDirection,preferredExit:s,termination:n})}for(const n of t.connections){if(i.has(n.name))continue;const t=w7(n);if(t){const i=o.get(t);o.set(t,{busId:t,connectionNames:[...i?.connectionNames??[],n.name],direction:e.busDirections?.[t]??i?.direction??e.defaultDirection,sourceComponentId:i?.sourceComponentId??e.sourceComponentId,preferredExit:T7(t,e.busExitPreferences?.[t]??i?.preferredExit??e.defaultPreferredExit),termination:i?.termination??{type:\"boundary\"}})}else{const t=`connection:${n.name}`;o.set(t,{busId:t,connectionNames:[n.name],sourceComponentId:e.sourceComponentId,direction:e.busDirections?.[t]??e.defaultDirection,preferredExit:T7(t,e.busExitPreferences?.[t]??e.defaultPreferredExit),termination:{type:\"boundary\"}})}}return[...o.values()]}(t,e).map(e=\u003e{for(const[t,n]of Object.entries(e.connectionExitTargets??{})){if(!e.connectionNames.includes(t))throw new Error(`FanoutSolver: connectionExitTargets contains connection \"${t}\" outside bus \"${e.busId}\"`);if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error(`FanoutSolver: connectionExitTargets for connection \"${t}\" must contain finite x and y coordinates`)}const i=e.connectionNames.map(e=\u003e{const n=o.get(e);if(void 0===n)throw new Error(`FanoutSolver: connection \"${e}\" is missing from the input`);return t.connections[n]}),r=function(t){const{busSpec:e,connections:n,componentGrids:o}=t,i=new Map;for(const t of n){const e=new Set;for(const n of t.pointsToConnect)for(const i of N7({point:n,connection:t,componentGrids:o}))e.add(i.grid.componentId);for(const t of e)i.set(t,(i.get(t)??0)+1)}const r=[...o].sort((t,e)=\u003e{const n=(i.get(e.componentId)??0)-(i.get(t.componentId)??0);return 0!==n?n:e.obstacles.length-t.obstacles.length})[0],s=e.sourceComponentId?o.find(t=\u003et.componentId===e.sourceComponentId):void 0;if(e.sourceComponentId\u0026\u0026!s)throw new Error(`FanoutSolver: source component \"${e.sourceComponentId}\" for bus \"${e.busId}\" was not found`);const a=s??r,c=a?i.get(a.componentId)??0:0;if(!a||c!==n.length)throw new Error(e.sourceComponentId?`FanoutSolver: source component \"${e.sourceComponentId}\" is not an endpoint on every connection in bus \"${e.busId}\"`:`FanoutSolver: bus \"${e.busId}\" does not have one component endpoint on every connection`);return a}({busSpec:e,connections:i,componentGrids:n}),s=i.map(t=\u003efunction(t){const{connection:e,connectionIndex:n,sourceGrid:o,componentGrids:i,termination:r,exitTargetPoint:s}=t;for(let t=0;t\u003ce.pointsToConnect.length;t++){const a=e.pointsToConnect[t],c=N7({point:a,connection:e,componentGrids:i}).find(t=\u003et.grid.componentId===o.componentId);if(!c)continue;const l=M7(a).find(t=\u003ec.obstacle.layers.includes(t));if(!l)throw new Error(`FanoutSolver: connection \"${e.name}\" has no source layer shared with its BGA pad`);const d=A7(a,e,t,r);return{connection:e,connectionIndex:n,sourcePoint:a,sourcePointIndex:t,sourceLayer:l,sourceObstacle:c.obstacle,targetPoint:d,exitTargetPoint:s??d}}throw new Error(`FanoutSolver: connection \"${e.name}\" does not touch component \"${o.componentId}\"`)}({connection:t,connectionIndex:o.get(t.name),sourceGrid:r,componentGrids:n,termination:e.termination??{type:\"boundary\"},exitTargetPoint:e.connectionExitTargets?.[t.name]}));return{busSpec:e,sourceGrid:r,preparedConnections:s}}),r=function(t,e){if(e.sharedBoundary)return P7(e.sharedBoundary,t);const n=t.map(t=\u003eC7(t,e)),o=2.25*Math.max(...t.flatMap(t=\u003e[t.pitchX,t.pitchY]));return P7({minX:Math.min(...n.map(t=\u003et.minX))-o,maxX:Math.max(...n.map(t=\u003et.maxX))+o,minY:Math.min(...n.map(t=\u003et.minY))-o,maxY:Math.max(...n.map(t=\u003et.maxY))+o},t)}([...new Map(i.map(({sourceGrid:t})=\u003e[t.componentId,t])).values()],e),s=R7(e.availableCornersAndSides),a=[];for(const{busSpec:t,sourceGrid:n,preparedConnections:o}of i){const i=B7({busId:t.busId,explicitDirection:t.direction??e.busDirections?.[t.busId],preferredExit:t.preferredExit,connections:o,sharedBoundary:r,availableRegions:\"plane\"===t.termination?.type?void 0:s});a.push({busId:t.busId,direction:i.direction,preferredExit:i.preferredExit,termination:t.termination??{type:\"boundary\"},connections:o,componentId:n.componentId,componentObstacles:n.obstacles,componentBounds:C7(n,e),sharedBoundary:r,xCoordinates:[...n.xCoordinates],yCoordinates:[...n.yCoordinates],pitchX:n.pitchX,pitchY:n.pitchY})}return a}function $7(t){return\"left\"===t||\"right\"===t}function Y7(t){return\"right\"===t||\"up\"===t?1:-1}function X7(t,e){return $7(e)?t.x:t.y}function V7(t,e){return $7(e)?t.y:t.x}function W7(t,e,n){return $7(n)?{x:t,y:e}:{x:e,y:t}}function H7(t){switch(t.direction){case\"right\":return t.sharedBoundary.maxX;case\"left\":return t.sharedBoundary.minX;case\"up\":return t.sharedBoundary.maxY;case\"down\":return t.sharedBoundary.minY}}function G7(t){return $7(t.direction)?t.pitchX:t.pitchY}function U7(t){const e=$7(t.direction)?t.xCoordinates:t.yCoordinates,n=t.connections.reduce((e,n)=\u003ee+X7(n.sourcePoint,t.direction),0)/t.connections.length,o=Y7(t.direction)\u003e0?Math.max(...e):Math.min(...e);return Math.abs(n-o)\u003c1e-6}function Z7(t,e){const n=[...t.connections].sort((e,n)=\u003eV7(e.sourcePoint,t.direction)-V7(n.sourcePoint,t.direction)).findIndex(t=\u003et.connectionIndex===e.connectionIndex);if(n\u003c0)throw new Error(`FanoutSolver: connection \"${e.connection.name}\" is missing from bus \"${t.busId}\"`);return n}function q7(t,e){return t.x\u003e=e.minX-1e-6\u0026\u0026t.x\u003c=e.maxX+1e-6\u0026\u0026t.y\u003e=e.minY-1e-6\u0026\u0026t.y\u003c=e.maxY+1e-6}function J7(t,e,n,o,i){const r=e-t,s=Math.floor((r-o)/(n+o)+1e-9);if(s\u003c1)return[];const a=t+(r-(s*n+(s-1)*o))/2+n/2;return Array.from({length:s},(t,e)=\u003e({value:a+e*(n+o),kind:i}))}function K7(t){const e=V7(t.connection.exitTargetPoint??t.connection.targetPoint,t.bus.direction),n=$7(t.bus.direction)?t.bus.sharedBoundary.minY:t.bus.sharedBoundary.minX,o=$7(t.bus.direction)?t.bus.sharedBoundary.maxY:t.bus.sharedBoundary.maxX;return Math.max(n+t.traceWidth/2,Math.min(o-t.traceWidth/2,e))}function Q7(t){const{bus:e,connection:n,targetUsesVia:o,interstitialEscape:i,compactBusTracks:r,traceWidth:s,viaDiameter:a,clearance:c}=t,l=($7(e.direction)?e.yCoordinates:e.xCoordinates).toSorted((t,e)=\u003et-e),d=V7(n.sourcePoint,e.direction);if(r){const t=Z7(e,n);return(l[0]+l.at(-1))/2+(t-(e.connections.length-1)/2)*(s+c)}if(!o||!i)return d;const h=function(t){const e=($7(t.direction)?t.xCoordinates:t.yCoordinates).toSorted((t,e)=\u003et-e),n=t.connections.reduce((e,n)=\u003ee+X7(n.sourcePoint,t.direction),0)/t.connections.length,o=Y7(t.direction)\u003e0?e.at(-1):e[0];return Math.abs(o-n)/G7(t)}(e),u=s+c,p=Math.ceil(e.connections.length/2),m=(p-1)*u,g=a/2+s/2+c+.001,f=Math.round(h)+1,y=f*g+(f-1)*m,_=Z7(e,n),b=l[0],x=l.at(-1),v=_\u003cp?b-y-(p-_-1)*u:x+y+(_-p)*u,S=$7(e.direction)?e.sharedBoundary.minY:e.sharedBoundary.minX,I=$7(e.direction)?e.sharedBoundary.maxY:e.sharedBoundary.maxX;return Math.max(S+s/2,Math.min(I-s/2,v))}function ttt(t){const e=Y7(t.direction),n=[...t.connections].sort((n,o)=\u003e{const i=e*(X7(o.sourcePoint,t.direction)-X7(n.sourcePoint,t.direction));return Math.abs(i)\u003e1e-6?i:V7(n.sourcePoint,t.direction)-V7(o.sourcePoint,t.direction)}),o=[...t.connections].sort((n,o)=\u003eV7(n.sourcePoint,t.direction)-V7(o.sourcePoint,t.direction)||e*(X7(o.sourcePoint,t.direction)-X7(n.sourcePoint,t.direction))),i=[n,[...n].reverse(),o,[...o].reverse()];for(let t=1;t\u003cMath.min(n.length,8);t++)i.push([...n.slice(t),...n.slice(0,t)]);return i}function ett(t,e,n,o,i){M8(e,n)\u003c1e-9||t.push({start:e,end:n,width:o,layer:i})}function ntt(t){const{preparedConnection:e,bus:n,targetLayer:o,track:i,exitAxis:r,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,viaHandedness:d,interstitialEscape:h,spreadLaneIndex:u,clearance:p,terminateAtVia:m}=t,g={x:e.sourcePoint.x,y:e.sourcePoint.y},f=Y7(n.direction),y=G7(n),_=function(t){return $7(t.direction)?t.pitchY:t.pitchX}(n),b=o!==e.sourceLayer,x=$7(n.direction)?e.sourceObstacle.width:e.sourceObstacle.height,v=b\u0026\u0026!U7(n)?x\u003e=y?x/2+c/2+p+.001:.5*y:b?Math.max(.5*y,x/2+(b?c:a)/2+p+.001):x/2+a/2+p+.001,S=X7(g,n.direction)+f*v,I=V7(g,n.direction)+d*_*.5,C=W7(S,I,n.direction),P=c/2+a/2+p+.001+u*(a+p),M=h\u0026\u0026y\u003e=P+c/2+p,N=M?W7(S+f*P,I,n.direction):C,w=W7(M?X7(N,n.direction):S+f*Math.abs(i-I),i,n.direction),T=m?C:W7(r,i,n.direction),R=[],E=[];let A;if(E.push({route_type:\"wire\",x:g.x,y:g.y,width:a,layer:e.sourceLayer,start_pcb_port_id:e.sourcePoint.pcb_port_id}),ett(R,g,C,a,e.sourceLayer),E.push({route_type:\"wire\",x:C.x,y:C.y,width:a,layer:e.sourceLayer}),o!==e.sourceLayer){const t=L8(e.sourceLayer,o,s);A={center:C,diameter:c,holeDiameter:l,fromLayer:e.sourceLayer,toLayer:o,spanLayers:t},E.push({route_type:\"via\",x:C.x,y:C.y,from_layer:e.sourceLayer,to_layer:o,via_diameter:c,via_hole_diameter:l}),E.push({route_type:\"wire\",x:C.x,y:C.y,width:a,layer:o})}const O=m?[C]:M?function(t,e){if(t.length\u003c3)return t;const n=[t[0]];for(let o=1;o\u003ct.length-1;o++){const i=t[o-1],r=t[o],s=t[o+1],a=M8(i,r),c=M8(r,s);if(a\u003c1e-9||c\u003c1e-9)continue;const l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c},h=l.x*d.x+l.y*d.y;if(Math.abs(h)\u003e1e-6){n.push(r);continue}const u=Math.min(e,a/2,c/2);n.push({x:r.x-l.x*u,y:r.y-l.y*u}),n.push({x:r.x+d.x*u,y:r.y+d.y*u})}return n.push(t.at(-1)),n}([C,N,w,T],Math.max(a+p,2*a)):[C,w,T];for(let t=1;t\u003cO.length;t++){const e=O[t-1],n=O[t];ett(R,e,n,a,o),E.push({route_type:\"wire\",x:n.x,y:n.y,width:a,layer:o})}const k=x8({connectionName:e.connection.name,sourcePointIndex:e.sourcePointIndex});return{busId:n.busId,connectionName:e.connection.name,connectionIndex:e.connectionIndex,sourcePointIndex:e.sourcePointIndex,sourcePoint:e.sourcePoint,sourceObstacle:e.sourceObstacle,sourceLayer:e.sourceLayer,targetPoint:e.targetPoint,targetLayer:o,termination:n.termination,direction:n.direction,exitPoint:T,trace:{type:\"pcb_trace\",pcb_trace_id:k.traceId,connection_name:e.connection.name,connectsTo:[...e.sourcePoint.pointId?[e.sourcePoint.pointId]:[],...e.sourcePoint.pcb_port_id?[e.sourcePoint.pcb_port_id]:[],k.boundaryExitPointId],route:E},segments:R,via:A,length:R.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}function ott(t){const{preparedConnection:e,bus:n,viaDiameter:o,clearance:i}=t,{sourcePoint:r,targetPoint:s}=e,a=.5*Math.max(n.pitchX,n.pitchY);if(M8(r,s)\u003c=1e-6||M8(r,s)\u003ea)return[];const c=(()=\u003e{switch(n.direction){case\"left\":return{x:-1,y:0};case\"right\":return{x:1,y:0};case\"up\":return{x:0,y:1};case\"down\":return{x:0,y:-1}}})(),l=Math.SQRT1_2,d=[c,...[{x:l,y:l},{x:l,y:-l},{x:-l,y:l},{x:-l,y:-l},{x:1,y:0},{x:-1,y:0},{x:0,y:1},{x:0,y:-1}].toSorted((t,e)=\u003ee.x*c.x+e.y*c.y-(t.x*c.x+t.y*c.y))],h=Math.max(o,o/2+i),u=[h,Math.max(h,.5*Math.min(n.pitchX,n.pitchY)),Math.max(h,.625*Math.min(n.pitchX,n.pitchY)),Math.max(h,.75*Math.min(n.pitchX,n.pitchY))],p=[];for(const t of[r,s])for(const e of u)for(const n of d){const o={x:t.x+n.x*e,y:t.y+n.y*e};M8(o,r)\u003c=1e-6||M8(o,s)\u003c=1e-6||p.some(t=\u003eM8(t,o)\u003c=1e-6)||p.push(o)}return p}function itt(t){const{plan:e,preparedConnection:n,planeLayer:o,viaPoint:i,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c}=t,l={x:n.targetPoint.x,y:n.targetPoint.y},d=function(t){const e=\"layer\"in t?t.layer:t.layers[0];if(!e)throw new Error(\"FanoutSolver: plane endpoint has no copper layer\");return e}(n.targetPoint),h=L8(o,d,r);if(!h.includes(o))throw new Error(`FanoutSolver: via for \"${n.connection.name}\" does not cross plane ${o}`);const u=[{start:i,end:l,width:s,layer:d}],p={center:i,diameter:a,holeDiameter:c,fromLayer:o,toLayer:d,spanLayers:h},m=x8({connectionName:n.connection.name,sourcePointIndex:n.sourcePointIndex}),g={type:\"pcb_trace\",pcb_trace_id:m.planeEndpointTraceId,connection_name:n.connection.name,connectsTo:[...n.targetPoint.pointId?[n.targetPoint.pointId]:[],...n.targetPoint.pcb_port_id?[n.targetPoint.pcb_port_id]:[],m.planeEndpointPointId],route:[{route_type:\"wire\",...i,width:s,layer:o},{route_type:\"via\",...i,from_layer:o,to_layer:d,via_diameter:a,via_hole_diameter:c},{route_type:\"wire\",...i,width:s,layer:d},{route_type:\"wire\",...l,width:s,layer:d}]};return{...e,planeEndpointTrace:g,planeEndpointSegments:u,planeEndpointVia:p,length:e.length+u.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}function rtt(t){const{segment:e,plan:n,segmentIndex:o,srj:i,allowSameNetMerges:r,obstacles:s,clearance:a}=t;for(const t of s)if(t.layers.includes(e.layer)\u0026\u0026!t.connectedTo.includes(n.connectionName)\u0026\u0026!(r\u0026\u0026Y8(i,t,n.connectionName)||K8({inputSrj:i,segment:e,bodyObstacle:t,connectionName:n.connectionName})||0===o\u0026\u0026t===n.sourceObstacle\u0026\u0026e.layer===n.sourceLayer||!(A8(e,t)\u003ce.width/2+a-1e-9)))return!1;return!0}function stt(t){return[...t.segments,...t.planeEndpointSegments??[]]}function att(t){return[t.via,t.planeEndpointVia].filter(t=\u003eBoolean(t))}function ctt(t){const{plan:e,srj:n,sharedBoundary:o,clearance:i,allowSameNetMerges:r}=t,s=function(t,e){return{minX:Math.min(t.minX,e.minX),maxX:Math.max(t.maxX,e.maxX),minY:Math.min(t.minY,e.minY),maxY:Math.max(t.maxY,e.maxY)}}(n.bounds,o);if(!q7(e.exitPoint,s)||stt(e).some(t=\u003e!q7(t.start,s)||!q7(t.end,s)))return!1;const a=stt(e);for(let t=0;t\u003ca.length;t++)if(!rtt({segment:a[t],plan:e,segmentIndex:t\u003ce.segments.length?t:-1,srj:n,allowSameNetMerges:r,obstacles:n.obstacles,clearance:i}))return!1;for(const t of att(e))for(const o of n.obstacles)if(o.layers.some(e=\u003et.spanLayers.includes(e))\u0026\u0026(!r||!Y8(n,o,e.connectionName))\u0026\u0026E8(t.center,o)\u003ct.diameter/2+i-1e-9)return!1;return!0}function ltt(t){const{plan:e,otherPlans:n,staticClearanceCache:o,blockingBusCounts:i,cacheKey:r,srj:s,sharedBoundary:a,clearance:c,allowSameNetMerges:l}=t;let d=o?.get(r);return void 0===d\u0026\u0026(d=ctt({plan:e,srj:s,sharedBoundary:a,clearance:c,allowSameNetMerges:l}),o?.set(r,d)),d\u0026\u0026function(t){const{plan:e,otherPlans:n,srj:o,allowSameNetMerges:i,clearance:r,blockingBusCounts:s}=t;for(const t of n){if(i\u0026\u0026$8(o,e.connectionName,t.connectionName))continue;if(e.sourcePoint.pcb_port_id\u0026\u0026e.sourcePoint.pcb_port_id===t.sourcePoint.pcb_port_id||e.sourcePoint.pointId\u0026\u0026e.sourcePoint.pointId===t.sourcePoint.pointId)continue;const n=()=\u003e{t.busId!==e.busId\u0026\u0026s?.set(t.busId,(s.get(t.busId)??0)+1)},a=stt(e),c=stt(t),l=att(e),d=att(t);for(const t of a){for(const e of c)if(!O8(t,e,r))return n(),!1;for(const e of d)if(e.spanLayers.includes(t.layer)\u0026\u0026N8(e.center,t.start,t.end)\u003ce.diameter/2+t.width/2+r-1e-9)return n(),!1}for(const t of l){for(const e of c)if(t.spanLayers.includes(e.layer)\u0026\u0026N8(t.center,e.start,e.end)\u003ct.diameter/2+e.width/2+r-1e-9)return n(),!1;for(const e of d)if(t.spanLayers.some(t=\u003ee.spanLayers.includes(t))\u0026\u0026M8(t.center,e.center)\u003c(t.diameter+e.diameter)/2+r-1e-9)return n(),!1}}return!0}({plan:e,otherPlans:n,srj:s,allowSameNetMerges:l,clearance:c,blockingBusCounts:i})}function dtt(t,e=1){const{srj:n,bus:o,targetLayer:i,acceptedPlans:r,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,clearance:d,compactBusTracks:h,staticClearanceCache:u,blockingBusCounts:p,allowSameNetMerges:m=!1}=t;if(!Number.isInteger(e)||e\u003c1)throw new Error(`FanoutSolver: maxAlternatives must be a positive integer, received ${e}`);if(\"plane\"===o.termination.type){const e=function(t){const{srj:e,bus:n,targetLayer:o,acceptedPlans:i,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,clearance:l,staticClearanceCache:d,blockingBusCounts:h,allowSameNetMerges:u=!1}=t,p=n.connections[0]?.sourceObstacle;if(!p||\"plane\"!==n.termination.type)return null;const m=n.connections[0].sourceLayer;if(o===m)return null;const g=[n.direction,...[\"left\",\"right\",\"up\",\"down\"].filter(t=\u003et!==n.direction)];for(const t of g){const m=t===n.direction?n:{...n,direction:t},g=$7(t)?p.width:p.height,f=G7(m)/2-g/2\u003e=a/2+l-1e-9,y=f?[0]:[1,-1];for(const p of y)for(const g of ttt(m)){const y=[];let _=!0;for(const b of g){const g=V7(b.sourcePoint,t),x=ntt({preparedConnection:b,bus:m,targetLayer:o,track:g,exitAxis:H7(m),layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,viaHandedness:p,interstitialEscape:!f,spreadLaneIndex:0,clearance:l,terminateAtVia:!0}),v=[...ott({preparedConnection:b,bus:m,viaDiameter:a,clearance:l}).map(t=\u003eitt({plan:x,preparedConnection:b,planeLayer:o,viaPoint:t,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c})),x].find((r,s)=\u003eltt({plan:r,otherPlans:[...i,...y],staticClearanceCache:d,blockingBusCounts:h,cacheKey:`plane:${n.busId}:${o}:${t}:${b.connectionIndex}:${p}:${s}`,srj:e,sharedBoundary:n.sharedBoundary,clearance:l,allowSameNetMerges:u}));if(!v){_=!1;break}y.push(v)}if(_)return y}}return null}(t);return e?[e]:[]}const g=H7(o),f=o.connections[0]?.sourceObstacle;if(!f)return[[]];const y=$7(o.direction)?f.width:f.height,_=o.connections[0].sourceLayer,b=i!==_,x=U7(o),v=G7(o)/2-y/2\u003e=c/2+d-1e-9,S=b\u0026\u0026!x\u0026\u0026!v,I=b?v||x?[0]:[1,-1]:[0],C=[],P=new Set,M=(t,f,y,_)=\u003e{if(C.length\u003e=e)return;if(y\u003e=t.length)return void(t=\u003e{const e=t.map(t=\u003e`${t.connectionIndex}:${t.targetLayer}:${t.exitPoint.x}:${t.exitPoint.y}:${t.segments.map(t=\u003e`${t.start.x},${t.start.y},${t.end.x},${t.end.y},${t.layer}`).join(\";\")}`).join(\"|\");P.has(e)||(P.add(e),C.push(t))})(_);const x=t[y],v=Z7(o,x),I=[K7({bus:o,connection:x,traceWidth:a}),Q7({bus:o,connection:x,targetUsesVia:b,interstitialEscape:S,compactBusTracks:h,traceWidth:a,viaDiameter:c,clearance:d})].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e-t)\u003c1e-9)===e).flatMap(t=\u003efunction(t){const{bus:e,connection:n,preferredTrack:o,traceWidth:i,clearance:r}=t,s=($7(e.direction)?e.yCoordinates:e.xCoordinates).toSorted((t,e)=\u003et-e),a=Math.max(...e.componentObstacles.map(t=\u003e$7(e.direction)?t.height/2:t.width/2)),c=$7(e.direction)?e.sharedBoundary.minY:e.sharedBoundary.minX,l=$7(e.direction)?e.sharedBoundary.maxY:e.sharedBoundary.maxX,d=l-c,h=l,u=[{value:o,kind:\"preferred\"},...J7(c,s[0]-a,i,r,\"margin\")];for(let t=0;t\u003cs.length;t++)u.push({value:s[t],kind:\"corridor\"}),t\u003cs.length-1\u0026\u0026u.push(...J7(s[t]+a,s[t+1]-a,i,r,\"gap\"));u.push(...J7(s.at(-1)+a,h,i,r,\"margin\"));const p=V7(n.sourcePoint,e.direction),m=(s[0]+s.at(-1))/2;return u.filter(t=\u003eMath.abs(t.value-p)\u003c=d+1e-9).filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e.value-t.value)\u003c1e-9)===e).sort((t,e)=\u003eMath.abs(t.value-o)-Math.abs(e.value-o)-.001*(Math.abs(t.value-m)-Math.abs(e.value-m)))}({bus:o,connection:x,preferredTrack:t,traceWidth:a,clearance:d})).filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e.value-t.value)\u003c1e-9)===e);for(let h=0;h\u003cI.length;h++){const b=I[h],P=ntt({preparedConnection:x,bus:o,targetLayer:i,track:b.value,exitAxis:g,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,viaHandedness:f,interstitialEscape:S,spreadLaneIndex:Math.min(v,o.connections.length-v-1),clearance:d,terminateAtVia:!1});if(ltt({plan:P,otherPlans:[...r,..._],staticClearanceCache:u,blockingBusCounts:p,cacheKey:`boundary:${o.busId}:${i}:${x.connectionIndex}:${f}:${h}`,srj:n,sharedBoundary:o.sharedBoundary,clearance:d,allowSameNetMerges:m})){if(M(t,f,y+1,[..._,P]),C.length\u003e=e)return;if(1===e)return}}};for(const t of I)for(const n of ttt(o))if(M(n,t,0,[]),C.length\u003e=e)return C;return C}function htt(t){return dtt(t,1)[0]??null}var utt=1e-9,ptt=\"1\"===globalThis.process?.env?.FANOUT_FLOW_DEBUG;function mtt(t){const e=t.connection;return t.sourceObstacle.connectedTo.find(t=\u003et.startsWith(\"connectivity_net\"))??e.netConnectionName??t.connection.name.replace(/::fanout:\\d+$/,\"\")}function gtt(t,e){return t===e.connection.sourceObstacle||t.connectedTo.includes(e.connection.connection.name)||t.connectedTo.includes(e.netKey)}function ftt(t,e){const n=e.x-t.x,o=e.y-t.y,i=Math.abs(n),r=Math.abs(o);return i\u003cutt||r\u003cutt||Math.abs(i-r)\u003cutt?[t,e]:i\u003er?[t,{x:t.x+Math.sign(n)*r,y:e.y},e]:[t,{x:e.x,y:t.y+Math.sign(o)*i},e]}function ytt(t){if(t.length\u003c2)return t;const e=[t[0]];for(const n of t.slice(1)){const t=e.at(-1),o=Math.abs(n.x-t.x),i=Math.abs(n.y-t.y);o\u003cutt||i\u003cutt||Math.abs(o-i)\u003cutt?e.push(n):e.push(...ftt(n,t).reverse().slice(1))}return _tt(e)}function _tt(t){if(t.length\u003c3)return t;const e=[t[0]];for(let n=1;n\u003ct.length-1;n++){const o=e.at(-1),i=t[n],r=t[n+1];Math.sign(i.x-o.x)===Math.sign(r.x-i.x)\u0026\u0026Math.sign(i.y-o.y)===Math.sign(r.y-i.y)||e.push(i)}return e.push(t.at(-1)),e}function btt(t,e){if(t.length\u003c3)return t;const n=[t[0]];for(let o=1;o\u003ct.length-1;o++){const i=t[o-1],r=t[o],s=t[o+1],a=M8(i,r),c=M8(r,s);if(a\u003cutt||c\u003cutt)continue;const l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c};if(Math.abs(l.x*d.x+l.y*d.y)\u003e1e-6){n.push(r);continue}const h=Math.min(e,a/2,c/2);n.push({x:r.x-l.x*h,y:r.y-l.y*h}),n.push({x:r.x+d.x*h,y:r.y+d.y*h})}return n.push(t.at(-1)),_tt(n)}function xtt(t,e){const n=[];for(let o=1;o\u003ct.length;o++)M8(t[o-1],t[o])\u003cutt||n.push({start:t[o-1],end:t[o],width:e,layer:\"top\"});return n}var vtt=class{edges;levels;nextEdges;constructor(t){this.edges=Array.from({length:t},()=\u003e[]),this.levels=new Int32Array(t),this.nextEdges=new Int32Array(t)}addEdge(t,e,n,o={}){const i={to:e,reverseIndex:this.edges[e].length,capacity:n,initialCapacity:n,...o},r={to:t,reverseIndex:this.edges[t].length,capacity:0,initialCapacity:0};this.edges[t].push(i),this.edges[e].push(r)}buildLevels(t,e){this.levels.fill(-1);const n=new Int32Array(this.edges.length);let o=0,i=0;for(n[i++]=t,this.levels[t]=0;o\u003ci;){const t=n[o++];for(const e of this.edges[t])e.capacity\u003c=0||this.levels[e.to]\u003e=0||(this.levels[e.to]=this.levels[t]+1,n[i++]=e.to)}return this.levels[e]\u003e=0}sendFlow(t,e){if(t===e)return 1;for(let n=this.nextEdges[t];n\u003cthis.edges[t].length;n++,this.nextEdges[t]=n){const o=this.edges[t][n];if(o.capacity\u003c=0||this.levels[o.to]!==this.levels[t]+1)continue;const i=this.sendFlow(o.to,e);if(0!==i)return o.capacity-=i,this.edges[o.to][o.reverseIndex].capacity+=i,i}return 0}maximumFlow(t,e,n){let o=0;for(;o\u003cn\u0026\u0026this.buildLevels(t,e);)for(this.nextEdges.fill(0);o\u003cn;){const n=this.sendFlow(t,e);if(0===n)break;o+=n}return o}};function Stt(t){const{direction:e,availableDirections:n,items:o,grid:i,obstacles:r,traceWidth:s,clearance:a,occupiedNodes:c,acceptedSegments:l,connectorSelectionOffset:d=0}=t;if(0===o.length)return{routes:[],usedNodes:[],unmatchedItems:[]};const{boundary:h,step:u,columnCount:p,rowCount:m,nodeCount:g}=i,f=t=\u003ei.points[t],y=s/2+a,_=s+a,b=new Uint8Array(g);for(let t=0;t\u003cg;t++)!c[t]\u0026\u0026i.obstacleFreeNodes[t]\u0026\u0026(b[t]=1);const x=(t,e)=\u003e{const n=xtt(t,s);return n.every(t=\u003er.every(n=\u003egtt(n,e)||A8(t,n)\u003e=y-utt))\u0026\u0026n.every(t=\u003el.every(e=\u003eT8(t.start,t.end,e.start,e.end)\u003e=_-utt))},v=new Map;for(const t of o){const e=`${t.source.x.toFixed(6)}:${t.source.y.toFixed(6)}:${t.netKey}`,n=v.get(e)??[];n.push(t),v.set(e,n)}const S=Array.from({length:3721},(t,e)=\u003e{const n=e%61-30,o=Math.floor(e/61)-30;return{x:n,y:o,distanceSquared:n*n+o*o}}).sort((t,e)=\u003et.distanceSquared-e.distanceSquared),I=[];for(const t of v.values()){const e=t[0],n=Math.hypot(e.connection.sourceObstacle.width/2,e.connection.sourceObstacle.height/2)+a+2*u,o=Math.round((e.source.x-h.minX)/u),i=Math.round((e.source.y-h.minY)/u),r=[],s=new Set;for(const t of S){const a=o+t.x,c=i+t.y;if(a\u003c0||a\u003e=p||c\u003c0||c\u003e=m)continue;const l=c*p+a;if(!b[l]||s.has(l))continue;if(M8(e.source,f(l))\u003en)continue;const d=ftt(e.source,f(l));if(x(d,e)\u0026\u0026(s.add(l),r.push({node:l,connectorPoints:d}),r.length\u003e=12))break}if(0===r.length)return null;I.push({item:e,equivalentItems:t,candidates:r})}const C=[];for(const t of[...I].sort((t,e)=\u003et.candidates.length-e.candidates.length)){const e=0===t.candidates.length?0:d%t.candidates.length,n=[...t.candidates.slice(e),...t.candidates.slice(0,e)].find(e=\u003e{const n=xtt(e.connectorPoints,s);return C.every(e=\u003ee.netKey===t.item.netKey||n.every(t=\u003ee.segments.every(e=\u003eT8(t.start,t.end,e.start,e.end)\u003e=_-utt)))});if(!n)return null;t.candidates=[n],C.push({netKey:t.item.netKey,segments:xtt(n.connectorPoints,s)})}const P=new Set(I.map(t=\u003et.candidates[0].node));for(const t of C)for(const e of t.segments){const t=Math.max(0,Math.floor((Math.min(e.start.x,e.end.x)-_-h.minX)/u)),n=Math.min(p-1,Math.ceil((Math.max(e.start.x,e.end.x)+_-h.minX)/u)),o=Math.max(0,Math.floor((Math.min(e.start.y,e.end.y)-_-h.minY)/u)),i=Math.min(m-1,Math.ceil((Math.max(e.start.y,e.end.y)+_-h.minY)/u));for(let r=o;r\u003c=i;r++)for(let o=t;o\u003c=n;o++){const t=r*p+o;if(!b[t]||P.has(t))continue;const n=f(t);T8(e.start,e.end,n,n)\u003c_-utt\u0026\u0026(b[t]=0)}}const M=1+I.length,N=M+g,w=N+g,T=new vtt(w+1);for(let t=0;t\u003cI.length;t++){const e=1+t;T.addEdge(0,e,1);for(const n of I[t].candidates)T.addEdge(e,M+n.node,1,{gridNode:n.node})}for(let t=0;t\u003cg;t++){if(!b[t])continue;T.addEdge(M+t,N+t,1);const o=t%p,r=Math.floor(t/p);for(const e of i.neighbors[t])b[e]\u0026\u0026T.addEdge(N+t,M+e,1,{gridNode:e});(\"any\"===e\u0026\u0026((!n||n.has(\"left\"))\u0026\u00260===o||(!n||n.has(\"right\"))\u0026\u0026o===p-1||(!n||n.has(\"down\"))\u0026\u00260===r||(!n||n.has(\"up\"))\u0026\u0026r===m-1)||\"left\"===e\u0026\u00260===o||\"right\"===e\u0026\u0026o===p-1||\"down\"===e\u0026\u00260===r||\"up\"===e\u0026\u0026r===m-1)\u0026\u0026T.addEdge(N+t,w,1,{isSink:!0})}const R=T.maximumFlow(0,w,I.length),E=t=\u003e{const e=1+t;return T.edges[0].some(t=\u003et.to===e\u0026\u00261===t.initialCapacity\u0026\u00260===t.capacity)};if(R!==I.length\u0026\u0026ptt){const t=I.flatMap((t,e)=\u003eE(e)?[]:[t.item.connection.connection.name]);console.error(\"single-layer flow group failed\",{direction:e,achievedFlow:R,requiredFlow:I.length,unmatchedConnections:t})}const A=[],O=[],k=[];for(let t=0;t\u003cI.length;t++){const e=I[t];if(!E(t)){k.push(...e.equivalentItems);continue}const n=1+t,o=T.edges[n].find(t=\u003e1===t.initialCapacity\u0026\u00260===t.capacity\u0026\u0026void 0!==t.gridNode);if(void 0===o?.gridNode)return null;const i=e.candidates.find(t=\u003et.node===o.gridNode);if(!i)return null;const r=[f(i.node)];let a=i.node;const c=[a];for(let t=0;t\u003c=g;t++){const t=N+a,e=T.edges[t].find(t=\u003e1===t.initialCapacity\u0026\u00260===t.capacity\u0026\u0026(void 0!==t.gridNode||t.isSink));if(!e)return null;if(e.isSink)break;if(void 0===e.gridNode)return null;a=e.gridNode,c.push(a),r.push(f(a))}O.push(...c);const l=ytt(btt(_tt([...i.connectorPoints,...r.slice(1)]),u/2)),d=xtt(l,s);for(const t of e.equivalentItems)A.push({item:t,points:l,segments:d})}return{routes:A,usedNodes:O,unmatchedItems:k}}function Itt(t,e){const n=ftt(t,e),o=ftt(e,t).reverse();return n.length===o.length\u0026\u0026n.every((t,e)=\u003eM8(t,o[e])\u003cutt)?[n]:[n,o]}function Ctt(t,e){return Math.abs(t.x-e.minX)\u003cutt?\"left\":Math.abs(t.x-e.maxX)\u003cutt?\"right\":Math.abs(t.y-e.minY)\u003cutt?\"down\":Math.abs(t.y-e.maxY)\u003cutt?\"up\":null}function Ptt(t){const{items:e,grid:n,obstacles:o,traceWidth:i,clearance:r,availableBoundaryRegions:s}=t,a=s?new Set(s.map(t=\u003et.direction)):void 0,c=new Set(e.filter(t=\u003et.connection.sourceObstacle.width\u003e2\u0026\u0026t.connection.sourceObstacle.height\u003e2));let l=null;for(let t=0;t\u003c4;t++){const t=e.filter(t=\u003e!c.has(t));let s=null;for(let e=0;e\u003c4;e++){const c=Stt({direction:\"any\",availableDirections:a,items:t,grid:n,obstacles:o,traceWidth:i,clearance:r,occupiedNodes:new Uint8Array(n.nodeCount),acceptedSegments:[],connectorSelectionOffset:e});if(c\u0026\u0026((!s||c.routes.length\u003es.routes.length)\u0026\u0026(s=c),c.routes.length===t.length))break}if(!s)return null;if(s.routes.length===t.length){l=s;break}const d=new Map;for(const e of t)d.set(e.netKey,(d.get(e.netKey)??0)+1);let h=!1;for(const t of s.unmatchedItems)(d.get(t.netKey)??0)\u003c2||(c.add(t),h=!0);if(!h)return null}if(!l)return null;const d=[...l.routes],h=i/2+r,u=i+r;for(const t of c){const e=d.filter(e=\u003ee.item.netKey===t.netKey).flatMap(t=\u003et.points.map((e,n)=\u003e({route:t,point:e,pointIndex:n}))).sort((e,n)=\u003eNumber(n.route.item.bus.componentId===t.bus.componentId)-Number(e.route.item.bus.componentId===t.bus.componentId)||M8(t.source,e.point)-M8(t.source,n.point));let n=null;for(const r of e){for(const e of Itt(t.source,r.point)){const s=xtt(e,i),a=s.every(e=\u003eo.every(n=\u003egtt(n,t)||A8(e,n)\u003e=h-utt)),c=s.every(e=\u003ed.every(n=\u003en.item.netKey===t.netKey||n.segments.every(t=\u003eT8(e.start,e.end,t.start,t.end)\u003e=u-utt)));if(!a||!c)continue;const l=ytt(_tt([...e,...r.route.points.slice(r.pointIndex+1)]));n={item:t,points:l,segments:xtt(l,i)};break}if(n)break}if(!n)return null;d.push(n)}const p=d.map(t=\u003efunction(t,e){const{item:n,points:o,segments:i}=t,r=o.map((t,o)=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:e,layer:\"top\",...0===o\u0026\u0026n.connection.sourcePoint.pcb_port_id?{start_pcb_port_id:n.connection.sourcePoint.pcb_port_id}:{}})),s=x8({connectionName:n.connection.connection.name,sourcePointIndex:n.connection.sourcePointIndex});return{busId:n.bus.busId,connectionName:n.connection.connection.name,connectionIndex:n.connection.connectionIndex,sourcePointIndex:n.connection.sourcePointIndex,sourcePoint:n.connection.sourcePoint,sourceObstacle:n.connection.sourceObstacle,sourceLayer:n.connection.sourceLayer,targetPoint:n.connection.targetPoint,targetLayer:\"top\",termination:n.bus.termination,direction:n.bus.direction,exitPoint:o.at(-1),trace:{type:\"pcb_trace\",pcb_trace_id:s.traceId,connection_name:n.connection.connection.name,connectsTo:[...n.connection.sourcePoint.pointId?[n.connection.sourcePoint.pointId]:[],...n.connection.sourcePoint.pcb_port_id?[n.connection.sourcePoint.pcb_port_id]:[],s.boundaryExitPointId],route:r},segments:i,length:i.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}(t,i));if(!function(t){const{plans:e,items:n,obstacles:o,traceWidth:i,clearance:r}=t,s=new Map(n.map(t=\u003e[t.connection.connection.name,t.netKey])),a=new Map,c=new Map;for(const t of e){const e=s.get(t.connectionName),n=a.get(e)??[],o=c.get(e)??new Set;for(const e of t.segments){const t=[e.start,e.end].map(t=\u003e`${t.x.toFixed(6)}:${t.y.toFixed(6)}`).sort().join(\":\");o.has(t)||(o.add(t),n.push(e))}a.set(e,n),c.set(e,o)}const l=i/2+r;for(const[t,e]of a)for(const n of e)for(const e of o)if(!(e.connectedTo.includes(t)||A8(n,e)\u003e=l-utt))return ptt\u0026\u0026console.error(\"single-layer route violates obstacle clearance\",{netKey:t,segment:n,obstacleId:e.obstacleId,distance:A8(n,e),requiredObstacleDistance:l}),!1;const d=i+r,h=[...a];for(let t=0;t\u003ch.length;t++)for(let e=t+1;e\u003ch.length;e++)for(const n of h[t][1])for(const o of h[e][1])if(T8(n.start,n.end,o.start,o.end)\u003cd-utt)return ptt\u0026\u0026console.error(\"single-layer routes violate copper clearance\",{firstNetKey:h[t][0],secondNetKey:h[e][0],first:n,second:o,distance:T8(n.start,n.end,o.start,o.end),requiredRouteDistance:d}),!1;return!0}({plans:p,items:e,obstacles:o,traceWidth:i,clearance:r}))return ptt\u0026\u0026console.error(\"single-layer adaptive exits failed exact clearance\"),null;for(const t of p){const o=Ctt(t.exitPoint,n.boundary);if(!o||a\u0026\u0026!a.has(o))return null;const i=e.find(e=\u003ee.connection.connection.name===t.connectionName);i.bus.direction=o;const r=s?.filter(t=\u003et.direction===o),c=\"up\"===o||\"down\"===o?t.exitPoint.x:t.exitPoint.y;i.bus.preferredExit=r?.toSorted((t,e)=\u003eMath.abs(c-D7(t,n.boundary))-Math.abs(c-D7(e,n.boundary)))[0]?.preferredExit??(\"up\"===o?\"top\":\"down\"===o?\"bottom\":o),t.direction=o}const m=new Map(p.map(t=\u003e[t.connectionName,t]));return e.map(t=\u003em.get(t.connection.connection.name))}function Mtt(t){const{srj:e,buses:n,traceWidth:o,clearance:i,availableBoundaryRegions:r}=t;if(n.some(t=\u003e1!==t.connections.length))return null;const s=n.flatMap(t=\u003et.connections.map(e=\u003e({bus:t,connection:e,source:{x:e.sourcePoint.x,y:e.sourcePoint.y},netKey:mtt(e)}))),a=e.obstacles.filter(t=\u003et.layers.includes(\"top\")),c=n[0]?.sharedBoundary;if(!c)return[];const l=function(t){const{boundary:e,obstacles:n,traceWidth:o,clearance:i}=t,r=o+i,s=Math.round((e.maxX-e.minX)/r)+1,a=Math.round((e.maxY-e.minY)/r)+1,c=s*a,l=Array.from({length:c},(t,n)=\u003e({x:e.minX+n%s*r,y:e.minY+Math.floor(n/s)*r})),d=o/2+i,h=new Map;for(let t=0;t\u003cn.length;t++){const e=n[t],o=Math.floor((e.center.x-e.width/2-d)/1),i=Math.floor((e.center.x+e.width/2+d)/1),r=Math.floor((e.center.y-e.height/2-d)/1),s=Math.floor((e.center.y+e.height/2+d)/1);for(let e=o;e\u003c=i;e++)for(let n=r;n\u003c=s;n++){const o=`${e}:${n}`,i=h.get(o)??[];i.push(t),h.set(o,i)}}const u=(t,e=t)=\u003e{const o=Math.floor(Math.min(t.x,e.x)/1),i=Math.floor(Math.max(t.x,e.x)/1),r=Math.floor(Math.min(t.y,e.y)/1),s=Math.floor(Math.max(t.y,e.y)/1),a=new Set;for(let t=o;t\u003c=i;t++)for(let e=r;e\u003c=s;e++)for(const n of h.get(`${t}:${e}`)??[])a.add(n);return[...a].map(t=\u003en[t])},p=new Uint8Array(c);for(let t=0;t\u003cc;t++){const e=l[t];u(e).every(t=\u003eE8(e,t)\u003e=d-utt)\u0026\u0026(p[t]=1)}const m=Array.from({length:c},()=\u003e[]);for(let t=0;t\u003cc;t++){if(!p[t])continue;const e=t%s,n=Math.floor(t/s);for(const[i,r]of[[1,0],[0,1]]){const c=e+i,h=n+r;if(c\u003e=s||h\u003e=a)continue;const g=h*s+c;if(!p[g])continue;const f={start:l[t],end:l[g],width:o,layer:\"top\"};u(f.start,f.end).some(t=\u003eA8(f,t)\u003cd-utt)||(m[t].push(g),m[g].push(t))}}return{boundary:e,step:r,columnCount:s,rowCount:a,nodeCount:c,points:l,obstacleFreeNodes:p,neighbors:m}}({boundary:c,obstacles:a,traceWidth:o,clearance:i});ptt\u0026\u0026console.error(\"single-layer adaptive-exit grid ready\",{nodeCount:l.nodeCount});const d=Ptt({items:s,grid:l,obstacles:a,traceWidth:o,clearance:i,availableBoundaryRegions:r});return d||null}function Ntt(t){return\"left\"===t||\"right\"===t}function wtt(t){return\"right\"===t||\"up\"===t?1:-1}function Ttt(t,e){return Ntt(e)?t.x:t.y}function Rtt(t,e){return Ntt(e)?t.y:t.x}function Ett(t,e,n){return Ntt(n)?{x:t,y:e}:{x:e,y:t}}function Att(t){switch(t.direction){case\"right\":return t.sharedBoundary.maxX;case\"left\":return t.sharedBoundary.minX;case\"up\":return t.sharedBoundary.maxY;case\"down\":return t.sharedBoundary.minY}}function Ott(t){if(t.length\u003c3)return t;const e=[t[0]];for(let n=1;n\u003ct.length-1;n++){const o=e.at(-1),i=t[n],r=t[n+1],s={x:Math.sign(i.x-o.x),y:Math.sign(i.y-o.y)},a={x:Math.sign(r.x-i.x),y:Math.sign(r.y-i.y)};s.x===a.x\u0026\u0026s.y===a.y||e.push(i)}return e.push(t.at(-1)),e}function ktt(t,e){const n=[];for(let o=1;o\u003ct.length;o++)M8(t[o-1],t[o])\u003c1e-9||n.push({start:t[o-1],end:t[o],width:e,layer:\"top\"});return n}function Ltt(t){const{item:e,srj:n,acceptedSegments:o,traceWidth:i,clearance:r}=t,s=e.cornerChannelPrefixes;if(!s)return null;const a=e.direction,c=wtt(a),l=Att(e.bus),d=i+r,h=i/2+r,u=Ntt(a)?e.bus.sharedBoundary.minY:e.bus.sharedBoundary.minX,p=Ntt(a)?e.bus.sharedBoundary.maxY:e.bus.sharedBoundary.maxX,m=u+i/2,g=p-i/2,f=Rtt(e.connection.exitTargetPoint??e.connection.targetPoint,a),y=d/2,_=new Set([Math.max(m,Math.min(g,f))]);for(let t=Math.ceil(m/y)*y;t\u003c=g+1e-9;t+=y)_.add(Number(t.toFixed(9)));const b=[..._].toSorted((t,e)=\u003eMath.abs(t-f)-Math.abs(e-f));for(const t of s){const s=t.at(-1),u=Rtt(s,a);for(const p of b){const m=Math.abs(p-u),g=Ett(Ttt(s,a)+c*d,u,a),f=Ett(Ttt(g,a)+c*m,p,a);if(c*(l-Ttt(f,a))\u003c-1e-9)continue;const y=Ett(l,p,a),_=[...t,g,...m\u003e1e-9?[f]:[]];M8(_.at(-1),y)\u003e1e-9\u0026\u0026_.push(y);const b=Ott(_),x=ktt(b,i);if(!x.every(t=\u003en.obstacles.every(n=\u003en===e.connection.sourceObstacle||!n.layers.includes(\"top\")||A8(t,n)\u003e=h-1e-9)))continue;if(x.every(t=\u003eo.every(e=\u003eT8(t.start,t.end,e.start,e.end)\u003e=i+r-1e-9)))return{item:e,points:b,track:p}}}return null}function Dtt(t){const{route:e,direction:n,exitAxis:o,signedShift:i,maximumShift:r,obstacles:s,requiredObstacleDistance:a}=t;if(r\u003c=1e-9||Math.abs(i)\u003c=1e-9)return 0;const c=Math.sign(i),l=t=\u003e{if(t\u003c=1e-9)return!0;const i={start:Ett(o-wtt(n)*t,e.track,n),end:Ett(o,e.track+c*t,n),width:0,layer:\"top\"};return s.every(t=\u003et===e.item.connection.sourceObstacle||!t.layers.includes(\"top\")||A8(i,t)\u003e=a-1e-9)};if(l(r))return r;let d=0,h=r;for(let t=0;t\u003c32;t++){const t=(d+h)/2;l(t)?d=t:h=t}return d}function ztt(t){const{requestedTracks:e,currentTracks:n,candidateTracks:o,maximumShifts:i}=t,r=e.length+1,s=o.length+1,a=Array.from({length:r},()=\u003enew Float64Array(s).fill(Number.POSITIVE_INFINITY)),c=Array.from({length:r},()=\u003enew Uint8Array(s));a[0].fill(0);for(let t=1;t\u003cr;t++)for(let r=1;r\u003cs;r++){const s=a[t][r-1],l=Math.abs(e[t-1]-o[r-1]),d=Math.abs(n[t-1]-o[r-1])\u003ei[t-1]+1e-9?Number.POSITIVE_INFINITY:a[t-1][r-1]+l;d\u003cs?(a[t][r]=d,c[t][r]=1):a[t][r]=s}if(!Number.isFinite(a.at(-1).at(-1)))return null;const l=[];let d=e.length,h=o.length;for(;d\u003e0\u0026\u0026h\u003e0;)c[d][h]\u0026\u0026(l.push(o[h-1]),d--),h--;return d\u003e0?null:l.reverse()}function Ftt(t){const{direction:e,activeRoutes:n,obstacles:o,boundaryMinimum:i,boundaryMaximum:r,traceWidth:s,clearance:a,requestedTracks:c,maximumShifts:l}=t,d=s+a,h=s/2+a;let u=null,p=Number.POSITIVE_INFINITY;for(const t of Array.from({length:Math.round(d/s)},(t,e)=\u003ee*s)){const a=[];for(let n=Math.ceil((i-t)/d)*d+t;n\u003c=r+1e-9;n+=d){const t=Math.round(n/s)*s;o.every(n=\u003e{const o=Rtt(n.center,e),i=Ntt(e)?n.height:n.width;return Math.abs(t-o)\u003e=i/2+h-1e-9})\u0026\u0026a.push(t)}const m=ztt({requestedTracks:c,currentTracks:n.map(t=\u003et.track),candidateTracks:a,maximumShifts:l});if(!m)continue;const g=m.reduce((t,e,n)=\u003et+Math.abs(e-c[n]),0);g\u003cp\u0026\u0026(p=g,u=m)}return u}function Btt(t,e){switch(e){case\"up\":return\"top-left\"===t?\"minimum\":\"top-right\"===t?\"maximum\":null;case\"down\":return\"bottom-left\"===t?\"minimum\":\"bottom-right\"===t?\"maximum\":null;case\"left\":return\"bottom-left\"===t?\"minimum\":\"top-left\"===t?\"maximum\":null;case\"right\":return\"bottom-right\"===t?\"minimum\":\"top-right\"===t?\"maximum\":null}}function jtt(t){const{items:e,direction:n,boundaryMinimum:o,boundaryMaximum:i,traceWidth:r,clearance:s,borderDistribution:a,currentTrackByConnectionName:c}=t,l=t=\u003ec.get(t.connection.connection.name)??Rtt(t.source,n),d=[...e].toSorted((t,e)=\u003el(t)-l(e)||t.connection.connection.name.localeCompare(e.connection.connection.name)),h=r+s,u=o+r/2,p=i-r/2;if(p-u\u003ch*Math.max(d.length-1,0)-1e-9)return null;const m=d.map(l);let g=[...m],f=h;const y=new Set;if(\"even\"===a\u0026\u0026d.length\u003e1){const t=m[0],e=m.at(-1),n=Math.max(h,(e-t)/(d.length-1)),o=t=\u003e{const e=[...m],n=Math.floor(d.length/2),o=d.length%2==0?n-1:n;if(o!==n){const i=e[n]-e[o];if(i\u003ct){const r=(t-i)/2;e[o]=e[o]-r,e[n]=e[n]+r}}for(let n=o-1;n\u003e=0;n--)e[n]=Math.min(e[n],e[n+1]-t);for(let o=n+1;o\u003ce.length;o++)e[o]=Math.max(e[o],e[o-1]+t);return e},i=t=\u003et[0]\u003e=u-1e-9\u0026\u0026t.at(-1)\u003c=p+1e-9;if(g=o(n),i(g))f=n;else{let t=h,e=n;if(g=o(t),!i(g))return null;for(let n=0;n\u003c32;n++){const n=(t+e)/2,r=o(n);i(r)?(t=n,g=r):e=n}f=t}for(const t of d)y.add(t.connection.connection.name)}const _=[],b=[];for(let t=0;t\u003cd.length;t++){const e=d[t],o=e.bus.preferredExit;if(!o?.includes(\"-\"))continue;const i=Btt(o,n);if(!i)return null;y.add(e.connection.connection.name),\"minimum\"===i?_.push(t):b.push(t)}if(_.some((t,e)=\u003et!==e)||b.some((t,e)=\u003et!==d.length-b.length+e))return null;const x=2*h;if(_.length\u003e0){g[0]=u+x;for(let t=1;t\u003c_.length;t++){const e=Math.max(f,m[t]-m[t-1]);g[t]=g[t-1]+e}}if(b.length\u003e0){const t=d.length-1;g[t]=p-x;for(let e=t-1;e\u003e=d.length-b.length;e--){const t=Math.max(f,m[e+1]-m[e]);g[e]=g[e+1]-t}}return{byConnectionName:new Map(d.map((t,e)=\u003e[t.connection.connection.name,g[e]])),enforcedConnectionNames:y}}function $tt(t){const{item:e,points:n,segments:o}=t,i=n.map((t,n)=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:o[0]?.width??.1,layer:\"top\",...0===n\u0026\u0026e.connection.sourcePoint.pcb_port_id?{start_pcb_port_id:e.connection.sourcePoint.pcb_port_id}:{}})),r=x8({connectionName:e.connection.connection.name,sourcePointIndex:e.connection.sourcePointIndex});return{busId:e.bus.busId,connectionName:e.connection.connection.name,connectionIndex:e.connection.connectionIndex,sourcePointIndex:e.connection.sourcePointIndex,sourcePoint:e.connection.sourcePoint,sourceObstacle:e.connection.sourceObstacle,sourceLayer:e.connection.sourceLayer,targetPoint:e.connection.targetPoint,targetLayer:\"top\",termination:e.bus.termination,direction:e.direction,exitPoint:n.at(-1),trace:{type:\"pcb_trace\",pcb_trace_id:r.traceId,connection_name:e.connection.connection.name,connectsTo:[...e.connection.sourcePoint.pointId?[e.connection.sourcePoint.pointId]:[],...e.connection.sourcePoint.pcb_port_id?[e.connection.sourcePoint.pcb_port_id]:[],r.boundaryExitPointId],route:i},segments:o,length:o.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}function Ytt(t){const{srj:e,buses:n,traceWidth:o,clearance:i,borderDistribution:r}=t,s=o/2+i,a=new Map,c=new Map,l=n.flatMap(t=\u003et.connections.map(n=\u003e{const r={x:n.sourcePoint.x,y:n.sourcePoint.y},s=function(t){const{srj:e,bus:n,connection:o,traceWidth:i,clearance:r}=t,s=n.direction,a=wtt(s),c={x:o.sourcePoint.x,y:o.sourcePoint.y},l=Ttt(c,s),d=Rtt(c,s),h=i/2+r,u=(()=\u003e{switch(s){case\"right\":return n.componentBounds.maxX+h;case\"left\":return n.componentBounds.minX-h;case\"up\":return n.componentBounds.maxY+h;case\"down\":return n.componentBounds.minY-h}})(),p=t=\u003eMath.min(...e.obstacles.filter(t=\u003et!==o.sourceObstacle\u0026\u0026t.layers.includes(\"top\")).map(e=\u003eA8(t,e))),m={start:c,end:Ett(u,d,s),width:i,layer:\"top\"};if(p(m)\u003e=h-1e-9)return null;const g=Ntt(s)?{minimum:n.componentBounds.minY,maximum:n.componentBounds.maxY}:{minimum:n.componentBounds.minX,maximum:n.componentBounds.maxX},f=a*(u-l),y=Rtt(o.exitTargetPoint??o.targetPoint,s),_=i+r,b=Att(n),x=[-1,1].map(t=\u003e{const e=t*((t\u003c0?g.minimum-h:g.maximum+h)-d),o=Math.max(f,e),r=Ett(l+a*o,d+t*o,s);if(a*(b-Ttt(r,s))\u003c_-1e-9)return null;const u=[c,r];if(!u.every(t=\u003et.x\u003e=n.sharedBoundary.minX-1e-9\u0026\u0026t.x\u003c=n.sharedBoundary.maxX+1e-9\u0026\u0026t.y\u003e=n.sharedBoundary.minY-1e-9\u0026\u0026t.y\u003c=n.sharedBoundary.maxY+1e-9))return null;const m=Math.min(...ktt(u,i).map(p));return m\u003ch-1e-9?null:{points:u,obstacleDistance:m,targetDistance:Math.abs(Rtt(r,s)-y)}}).filter(t=\u003enull!==t).toSorted((t,e)=\u003ee.obstacleDistance-t.obstacleDistance||t.targetDistance-e.targetDistance);return x.length\u003e0?x.map(t=\u003et.points):null}({srj:e,bus:t,connection:n,traceWidth:o,clearance:i});return{bus:t,connection:n,direction:t.direction,source:r,...s?{cornerChannelPrefixes:s}:{}}}));for(const t of[\"left\",\"right\",\"up\",\"down\"]){const n=wtt(t),d=l.filter(e=\u003ee.direction===t\u0026\u0026!e.cornerChannelPrefixes);if(0===d.length)continue;const h=Ntt(t)?d[0].bus.sharedBoundary.minY:d[0].bus.sharedBoundary.minX,u=Ntt(t)?d[0].bus.sharedBoundary.maxY:d[0].bus.sharedBoundary.maxX,p=Att(d[0].bus),m=new Map,g=new Map,f=new Map;for(const e of d){const n=Ttt(e.source,t),o=n.toFixed(6);f.set(o,n);const i=m.get(o)??[];i.push(e),m.set(o,i)}for(const[n,o]of m){const i=f.get(n),r=new Set(o.map(t=\u003et.bus.componentId));g.set(n,e.obstacles.filter(e=\u003ee.layers.includes(\"top\")\u0026\u0026!!e.componentId\u0026\u0026r.has(e.componentId)\u0026\u0026Math.abs(Ttt(e.center,t)-i)\u003c1e-6))}const y=[...f.values()].toSorted((t,e)=\u003en*(t-e)),_=new Map;for(let e=0;e\u003cy.length;e++){const r=y[e],a=r.toFixed(6);for(const e of m.get(a)??[]){const o=Ntt(t)?e.connection.sourceObstacle.width:e.connection.sourceObstacle.height,i=Math.max(e.connection.sourceObstacle.width,e.connection.sourceObstacle.height)\u003c1.5?o/2+s:0,a=Ett(r+n*i,Rtt(e.source,t),t);_.set(e.connection.connection.name,{item:e,points:M8(e.source,a)\u003e1e-9?[e.source,a]:[e.source],track:Rtt(e.source,t)})}const c=y[e+1]??p;if(0===_.size||n*(c-r)\u003c=1e-9)continue;const l=[..._.values()].toSorted((t,e)=\u003et.track-e.track||t.item.connection.connection.name.localeCompare(e.item.connection.connection.name)),d=y.slice(e+1,e+3).flatMap(t=\u003eg.get(t.toFixed(6))??[]),f=l.map(e=\u003eMath.abs(c-Ttt(e.points.at(-1),t))),b=Ftt({direction:t,activeRoutes:l,obstacles:d,boundaryMinimum:h,boundaryMaximum:u,traceWidth:o,clearance:i,requestedTracks:l.map(t=\u003et.track),maximumShifts:f});if(!b)return null;for(let e=0;e\u003cl.length;e++){const o=l[e],i=b[e],r=Math.abs(i-o.track),s=Ett(Ttt(o.points.at(-1),t)+n*r,i,t);M8(o.points.at(-1),s)\u003e1e-9\u0026\u0026o.points.push(s);const a=Ett(c,i,t);M8(o.points.at(-1),a)\u003e1e-9\u0026\u0026o.points.push(a),o.track=i}}const b=jtt({items:d,direction:t,boundaryMinimum:h,boundaryMaximum:u,traceWidth:o,clearance:i,borderDistribution:r,currentTrackByConnectionName:new Map([..._.values()].map(t=\u003e[t.item.connection.connection.name,t.track]))});if(!b)return null;const x=[..._.values()].toSorted((t,e)=\u003et.track-e.track||t.item.connection.connection.name.localeCompare(e.item.connection.connection.name)),v=new Map,S=o+i;let I=S;for(const t of x){const e=t.item.connection.connection.name;if(!b.enforcedConnectionNames.has(e))continue;b.byConnectionName.get(e)-t.track\u003e=-1e-9||(v.set(e,I),I+=2*S)}let C=S;for(let t=x.length-1;t\u003e=0;t--){const e=x[t],n=e.item.connection.connection.name;if(!b.enforcedConnectionNames.has(n))continue;b.byConnectionName.get(n)-e.track\u003c=1e-9||(v.set(n,C),C+=2*S)}for(const o of x){const i=o.item.connection.connection.name,r=b.byConnectionName.get(i)??o.track,a=v.get(i)??0,c=o.points.at(-2),l=c?n*(p-Ttt(c,t)):0,d=r-o.track,h=Math.min(Math.abs(d),Math.max(0,l-a)),u=Dtt({route:o,direction:t,exitAxis:p,signedShift:d,maximumShift:h,obstacles:e.obstacles,requiredObstacleDistance:s}),m=Math.sign(d)*u;b.byConnectionName.set(i,o.track+m)}for(const t of b.enforcedConnectionNames)c.set(t,b.byConnectionName.get(t));for(const e of x){const o=e.item.connection.connection.name,i=b.byConnectionName.get(o)??e.track,r=Math.abs(i-e.track),s=v.get(o)??0,a=p-n*(r\u003e1e-9?s+r:0),c=e.points.at(-1);if(Math.abs(Ttt(c,t)-p)\u003e1e-6)return null;const l=e.points.at(-2);if(l\u0026\u0026(Math.abs(Rtt(l,t)-e.track)\u003e1e-6||n*(a-Ttt(l,t))\u003c-1e-6))return null;const d=Ett(a,e.track,t);l\u0026\u0026M8(l,d)\u003c1e-9?e.points.pop():e.points[e.points.length-1]=d}for(const e of x){const o=e.item.connection.connection.name,i=b.byConnectionName.get(o)??e.track,r=Math.abs(i-e.track),s=v.get(o)??0;r\u003e1e-9\u0026\u0026s\u003e1e-9\u0026\u0026e.points.push(Ett(Ttt(e.points.at(-1),t)+n*s,e.track,t)),r\u003e1e-9\u0026\u0026(e.points.push(Ett(Ttt(e.points.at(-1),t)+n*r,i,t)),e.track=i);const c=Ett(p,e.track,t);if(M8(e.points.at(-1),c)\u003e1e-9){if(n*(p-Ttt(e.points.at(-1),t))\u003c-1e-6)return null;e.points.push(c)}a.set(o,e)}}const d=[...a.values()].flatMap(t=\u003ektt(Ott(t.points),o));for(const t of l){if(!t.cornerChannelPrefixes)continue;const n=Ltt({item:t,srj:e,acceptedSegments:d,traceWidth:o,clearance:i});if(!n)return null;a.set(t.connection.connection.name,n),d.push(...ktt(Ott(n.points),o))}if(a.size!==l.length)return null;const h=(o+i)/2+1e-6;for(const[t,e]of c){const n=a.get(t);if(!n||Math.abs(n.track-e)\u003eh)return null}const u=l.map(t=\u003e{const e=Ott(a.get(t.connection.connection.name).points);return{item:t,points:e,segments:ktt(e,o)}});return function(t){const{paths:e,obstacles:n,traceWidth:o,clearance:i}=t,r=o/2+i,s=o+i;for(const t of e){if(Math.abs(Ttt(t.points.at(-1),t.item.direction)-Att(t.item.bus))\u003e1e-6)return!1;for(const e of t.segments)for(const o of n)if(o!==t.item.connection.sourceObstacle\u0026\u0026o.layers.includes(\"top\")\u0026\u0026A8(e,o)\u003cr-1e-9)return!1}for(let t=0;t\u003ce.length;t++)for(let n=t+1;n\u003ce.length;n++)for(const o of e[t].segments)for(const t of e[n].segments)if(T8(o.start,o.end,t.start,t.end)\u003cs-1e-9)return!1;return!0}({paths:u,obstacles:e.obstacles,traceWidth:o,clearance:i})?u.map($tt):null}var Xtt=1e-6;function Vtt(t,e){return M8(t,e)\u003c=Xtt}function Wtt(t){return\"layer\"in t?[t.layer]:t.layers}function Htt(t){return[...t.segments,...t.planeEndpointSegments??[]]}function Gtt(t){return[t.via,t.planeEndpointVia].filter(t=\u003eBoolean(t))}function Utt(t,e){return Vtt(t,e)\u0026\u0026Wtt(t).join(\"\\0\")===Wtt(e).join(\"\\0\")\u0026\u0026t.pointId===e.pointId\u0026\u0026t.pcb_port_id===e.pcb_port_id}function Ztt(t,e){const n=t.x\u003e=e.minX-Xtt\u0026\u0026t.x\u003c=e.maxX+Xtt\u0026\u0026t.y\u003e=e.minY-Xtt\u0026\u0026t.y\u003c=e.maxY+Xtt,o=Math.abs(t.x-e.minX)\u003c=Xtt||Math.abs(t.x-e.maxX)\u003c=Xtt||Math.abs(t.y-e.minY)\u003c=Xtt||Math.abs(t.y-e.maxY)\u003c=Xtt;return n\u0026\u0026o}function qtt(t,e){return t.x\u003e=e.minX-Xtt\u0026\u0026t.x\u003c=e.maxX+Xtt\u0026\u0026t.y\u003e=e.minY-Xtt\u0026\u0026t.y\u003c=e.maxY+Xtt}function Jtt(t,e,n,o,i){t.push({code:e,message:n,...o?{connectionName:o.connectionName,busId:o.busId}:{},...i?{otherConnectionName:i}:{}})}function Ktt(t){const{trace:e,plan:n,issues:o}=t,i=[];let r,s;for(const t of e.route)\"via\"!==t.route_type?\"wire\"===t.route_type?s?(Vtt(t,s)\u0026\u0026t.layer===s.to_layer||Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} does not continue from its via on ${s.to_layer}`,n),r=t,s=void 0):(r\u0026\u0026(r.layer!==t.layer?Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} changes from ${r.layer} to ${t.layer} without a via`,n):Vtt(r,t)||i.push({start:{x:r.x,y:r.y},end:{x:t.x,y:t.y},width:t.width,layer:t.layer})),r=t):Jtt(o,\"unsupported-route-point\",`Trace ${e.pcb_trace_id} contains unsupported ${t.route_type} geometry`,n):(r\u0026\u0026Vtt(r,t)\u0026\u0026r.layer===t.from_layer||Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} reaches a via without a matching ${t.from_layer} wire endpoint`,n),s=t);return s\u0026\u0026Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} ends at a via without a wire on ${s.to_layer}`,n),i}function Qtt(t){const{plan:e,preparedBus:n,inputSrj:o,outputSrj:i,sharedBoundary:r,issues:s}=t,a=o.connections[e.connectionIndex];if(!a||a.name!==e.connectionName)return void Jtt(s,\"connection-mismatch\",`Plan index ${e.connectionIndex} does not identify connection ${e.connectionName}`,e);const c=n?.connections.find(t=\u003et.connectionIndex===e.connectionIndex);if(c\u0026\u0026c.sourcePointIndex===e.sourcePointIndex\u0026\u0026Utt(c.sourcePoint,e.sourcePoint)\u0026\u0026c.sourceObstacle.obstacleId===e.sourceObstacle.obstacleId||Jtt(s,\"source-mismatch\",`Plan ${e.connectionName} does not start at its prepared component endpoint`,e),n?.termination.type!==e.termination.type\u0026\u0026Jtt(s,\"termination-mismatch\",`Plan ${e.connectionName} does not use its bus termination`,e),0===e.segments.length||e.length\u003c=Xtt)Jtt(s,\"not-broken-out\",`Plan ${e.connectionName} has no non-zero escape geometry`,e);else{const t={minX:Math.min(o.bounds.minX,r.minX),maxX:Math.max(o.bounds.maxX,r.maxX),minY:Math.min(o.bounds.minY,r.minY),maxY:Math.max(o.bounds.maxY,r.maxY)};e.segments.some(e=\u003e!qtt(e.start,t)||!qtt(e.end,t))\u0026\u0026Jtt(s,\"outside-routing-bounds\",`Plan ${e.connectionName} leaves the routable SRJ/shared-boundary area`,e),Vtt(e.segments[0].start,e.sourcePoint)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} does not start at its source pad`,e),Vtt(e.segments.at(-1).end,e.exitPoint)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} does not end at its declared exit`,e);for(let t=1;t\u003ce.segments.length;t++){const n=e.segments[t-1],o=e.segments[t];Vtt(n.end,o.start)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} has a gap between route segments`,e),n.layer===o.layer||e.via\u0026\u0026Vtt(n.end,e.via.center)\u0026\u0026e.via.spanLayers.includes(n.layer)\u0026\u0026e.via.spanLayers.includes(o.layer)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} changes layers without a connecting via`,e)}}const l=Ktt({trace:e.trace,plan:e,issues:s});if((l.length!==e.segments.length||l.some((t,n)=\u003e{const o=e.segments[n];return!o||t.layer!==o.layer||Math.abs(t.width-o.width)\u003eXtt||!Vtt(t.start,o.start)||!Vtt(t.end,o.end)}))\u0026\u0026Jtt(s,\"trace-plan-mismatch\",`Trace ${e.trace.pcb_trace_id} does not encode its declared route segments`,e),e.planeEndpointTrace||e.planeEndpointSegments||e.planeEndpointVia)if(e.planeEndpointTrace\u0026\u0026e.planeEndpointSegments\u0026\u0026e.planeEndpointVia){const t=Ktt({trace:e.planeEndpointTrace,plan:e,issues:s});(t.length!==e.planeEndpointSegments.length||t.some((t,n)=\u003e{const o=e.planeEndpointSegments?.[n];return!o||t.layer!==o.layer||Math.abs(t.width-o.width)\u003eXtt||!Vtt(t.start,o.start)||!Vtt(t.end,o.end)})||M8(e.planeEndpointVia.center,e.targetPoint)\u003c=Xtt)\u0026\u0026Jtt(s,\"trace-plan-mismatch\",`Trace ${e.planeEndpointTrace.pcb_trace_id} does not encode a valid offset plane-to-endpoint dogbone`,e)}else Jtt(s,\"trace-plan-mismatch\",`Plane endpoint geometry for ${e.connectionName} is incomplete`,e);const d=e.trace.route.find(t=\u003e\"x\"in t\u0026\u0026\"y\"in t),h=[...e.trace.route].reverse().find(t=\u003e\"x\"in t\u0026\u0026\"y\"in t);d\u0026\u0026h\u0026\u0026Vtt(d,e.sourcePoint)\u0026\u0026Vtt(h,e.exitPoint)||Jtt(s,\"disconnected-trace\",`Trace ${e.trace.pcb_trace_id} does not span its source and exit`,e);const u=i.connections.find(t=\u003et.name===e.connectionName);if(\"boundary\"===e.termination.type)if(u){const t=u.pointsToConnect[e.sourcePointIndex];t\u0026\u0026Vtt(t,e.exitPoint)\u0026\u0026\"layer\"in t\u0026\u0026t.layer===e.targetLayer||Jtt(s,\"output-exit-mismatch\",`Output connection ${e.connectionName} is not attached to its fanout exit`,e);for(let t=0;t\u003ca.pointsToConnect.length;t++){if(t===e.sourcePointIndex)continue;const n=a.pointsToConnect[t],o=u.pointsToConnect[t];n\u0026\u0026o\u0026\u0026Utt(n,o)||Jtt(s,\"downstream-endpoint-lost\",`Output connection ${e.connectionName} did not retain downstream endpoint ${t}`,e)}}else Jtt(s,\"output-connection-missing\",`Boundary connection ${e.connectionName} was removed from the output`,e);else u\u0026\u0026Jtt(s,\"plane-connection-retained\",`Plane-terminated connection ${e.connectionName} remains in the output`,e)}function tet(t,e){const n=Htt(t),o=Htt(e),i=Gtt(t),r=Gtt(e);for(const t of n){for(const e of o)if(t.layer===e.layer\u0026\u0026T8(t.start,t.end,e.start,e.end)\u003c=(t.width+e.width)/2+Xtt)return!0;for(const e of r)if(e.spanLayers.includes(t.layer)\u0026\u0026N8(e.center,t.start,t.end)\u003c=e.diameter/2+t.width/2+Xtt)return!0}for(const t of i){for(const e of o)if(t.spanLayers.includes(e.layer)\u0026\u0026N8(t.center,e.start,e.end)\u003c=t.diameter/2+e.width/2+Xtt)return!0;for(const e of r)if(t.spanLayers.some(t=\u003ee.spanLayers.includes(t))\u0026\u0026M8(t.center,e.center)\u003c=(t.diameter+e.diameter)/2+Xtt)return!0}return!1}function eet(t){const{inputSrj:e,outputSrj:n,plans:o,preparedBuses:i,sharedBoundary:r,clearance:s}=t,a=[],c=new Map,l=new Map(i.map(t=\u003e[t.busId,t]));for(const t of o){const e=c.get(t.connectionName)??[];e.push(t),c.set(t.connectionName,e)}for(const t of e.connections){const e=c.get(t.name)??[];0===e.length?Jtt(a,\"missing-plan\",`Connection ${t.name} has no fanout plan`):e.length\u003e1\u0026\u0026Jtt(a,\"duplicate-plan\",`Connection ${t.name} has ${e.length} fanout plans`,e[0])}for(const t of o)e.connections.some(e=\u003ee.name===t.connectionName)?Qtt({plan:t,preparedBus:l.get(t.busId),inputSrj:e,outputSrj:n,sharedBoundary:r,issues:a}):Jtt(a,\"unknown-plan\",`Plan ${t.connectionName} is not an input connection`,t);const d=function(t){const{plans:e,inputSrj:n,sharedBoundary:o,issues:i}=t,r=new Set,s=new Map;for(const t of e)s.set(t,[]);for(let t=0;t\u003ce.length;t++){const i=e[t];(\"plane\"===i.termination.type?Boolean(i.via):i.segments.some(t=\u003eZtt(t.start,o)||Ztt(t.end,o)))\u0026\u0026r.add(i);for(let o=t+1;o\u003ce.length;o++){const t=e[o];$8(n,i.connectionName,t.connectionName)\u0026\u0026tet(i,t)\u0026\u0026(s.get(i).push(t),s.get(t).push(i))}}const a=[...r];for(;a.length\u003e0;){const t=a.shift();for(const e of s.get(t)??[])r.has(e)||(r.add(e),a.push(e))}for(const t of e)r.has(t)||Jtt(i,\"not-broken-out\",\"boundary\"===t.termination.type?`Connection ${t.connectionName} has no continuous same-net copper path to the shared boundary`:`Plane connection ${t.connectionName} has no terminating via`,t);return r}({plans:o,inputSrj:e,sharedBoundary:r,issues:a});return function(t){const{plans:e,inputSrj:n,clearance:o,issues:i}=t;for(const t of e){const e=Htt(t);for(let r=0;r\u003ce.length;r++){const s=e[r];for(const e of n.obstacles){if(!e.layers.includes(s.layer))continue;if(Y8(n,e,t.connectionName))continue;if(0===r\u0026\u0026e.obstacleId===t.sourceObstacle.obstacleId\u0026\u0026s.layer===t.sourceLayer)continue;if(K8({inputSrj:n,segment:s,bodyObstacle:e,connectionName:t.connectionName}))continue;const a=A8(s,e),c=s.width/2+o;a\u003cc-1e-9\u0026\u0026Jtt(i,\"obstacle-clearance\",`Trace ${t.connectionName} on ${s.layer} is ${a.toFixed(4)}mm from different-net obstacle ${e.obstacleId}; ${c.toFixed(4)}mm is required`,t)}}for(const e of Gtt(t))for(const r of n.obstacles){if(!r.layers.some(t=\u003ee.spanLayers.includes(t))||Y8(n,r,t.connectionName))continue;const s=E8(e.center,r),a=e.diameter/2+o;s\u003ca-1e-9\u0026\u0026Jtt(i,\"via-obstacle-clearance\",`Via ${t.connectionName} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId} on its layer span; ${a.toFixed(4)}mm is required`,t)}}for(let t=0;t\u003ce.length;t++){const r=e[t];for(let s=t+1;s\u003ce.length;s++){const t=e[s];if($8(n,r.connectionName,t.connectionName))continue;const a=Htt(r),c=Htt(t),l=Gtt(r),d=Gtt(t);for(const e of a){for(const n of c)O8(e,n,o)||Jtt(i,\"different-net-trace-clearance\",`Different-net traces ${r.connectionName} and ${t.connectionName} intersect or violate clearance on ${e.layer}`,r,t.connectionName);for(const n of d)n.spanLayers.includes(e.layer)\u0026\u0026N8(n.center,e.start,e.end)\u003cn.diameter/2+e.width/2+o-1e-9\u0026\u0026Jtt(i,\"different-net-trace-via-clearance\",`Trace ${r.connectionName} violates via clearance to ${t.connectionName} on ${e.layer}`,r,t.connectionName)}for(const e of l){for(const n of c)e.spanLayers.includes(n.layer)\u0026\u0026N8(e.center,n.start,n.end)\u003ce.diameter/2+n.width/2+o-1e-9\u0026\u0026Jtt(i,\"different-net-trace-via-clearance\",`Via ${r.connectionName} violates trace clearance to ${t.connectionName} on ${n.layer}`,r,t.connectionName);for(const n of d)e.spanLayers.some(t=\u003en.spanLayers.includes(t))\u0026\u0026M8(e.center,n.center)\u003c(e.diameter+n.diameter)/2+o-1e-9\u0026\u0026Jtt(i,\"different-net-via-clearance\",`Vias ${r.connectionName} and ${t.connectionName} violate clearance on an overlapping layer span`,r,t.connectionName)}}}}({plans:o,inputSrj:e,clearance:s,issues:a}),{valid:0===a.length,checkedConnectionCount:e.connections.length,brokenOutConnectionCount:new Set([...d].map(t=\u003et.connectionName)).size,issues:a}}var net=[\"#ef4444\",\"#2563eb\",\"#16a34a\",\"#9333ea\",\"#f59e0b\",\"#0891b2\",\"#db2777\",\"#65a30d\",\"#4f46e5\",\"#ea580c\"];function oet(t){if(!Number.isInteger(t)||t\u003c0)throw new Error(`FanoutSolver: copper layer index must be a non-negative integer, received ${t}`);return net[t%net.length]}var iet=new Set([\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\",\"inner7\",\"inner8\"]),ret={\"0603\":{padLength:.8,padWidth:.95},1206:{padLength:.6,padWidth:1.6},\"1206x4_pair\":{padLength:.8,padWidth:.5}},set=(t,e)=\u003e{const n=t.indexOf(e);if(n\u003c0)throw new Error(`FanoutSolver: cannot visualize unknown copper layer \"${e}\"`);return n},aet=(t,e)=\u003e`z${[...new Set(e.map(e=\u003eset(t,e)))].sort((t,e)=\u003et-e).join(\",\")}`,cet=t=\u003e{const e=\"layers\"in t?t.layers:void 0;return e\u0026\u0026e.length\u003e0?e:[t.layer]},det=(t,e)=\u003et.__zLayers\u0026\u0026t.__zLayers.length\u003e0?[...new Set(t.__zLayers)].filter(t=\u003eNumber.isInteger(t)\u0026\u0026t\u003e=0\u0026\u0026t\u003ce.length).sort((t,e)=\u003et-e):[...new Set(t.layers.map(t=\u003eset(e,t)))].sort((t,e)=\u003et-e),het=(t,e,n)=\u003e{const o=set(t,e),i=set(t,n);return t.slice(Math.min(o,i),Math.max(o,i)+1)},uet=(...t)=\u003et.find(t=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)),pet=t=\u003e{const e=uet(t.min_via_hole_diameter,t.minViaHoleDiameter),n=uet(t.min_via_pad_diameter,t.minViaPadDiameter,t.minViaDiameter);return Math.max(n??t.minViaDiameter??.3,e??0)},met=(t,e)=\u003e{let n={blue:[0,0,255],orange:[255,165,0],purple:[128,0,128],red:[255,0,0]}[t],o=1;const i=/^rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)$/.exec(t);i\u0026\u0026(n=[Number(i[1]),Number(i[2]),Number(i[3])],o=void 0===i[4]?1:Number(i[4]));const r=/^hsl\\(\\s*([\\d.-]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%\\s*\\)$/.exec(t);if(r\u0026\u0026(n=((t,e,n)=\u003e{const o=(1-Math.abs(2*n-1))*e,i=(t%360+360)%360/60,r=o*(1-Math.abs(i%2-1)),[s,a,c]=i\u003c1?[o,r,0]:i\u003c2?[r,o,0]:i\u003c3?[0,o,r]:i\u003c4?[0,r,o]:i\u003c5?[r,0,o]:[o,0,r],l=n-o/2;return[s,a,c].map(t=\u003eMath.round(255*(t+l)))})(Number(r[1]),Number(r[2])/100,Number(r[3])/100)),!n)return t;const s=+Math.max(0,100*o-100*e).toFixed(2)/100;if(s\u003e=1){const t=n.map(t=\u003eMath.round(t).toString(16).padStart(2,\"0\")).join(\"\");return t[0]===t[1]\u0026\u0026t[2]===t[3]\u0026\u0026t[4]===t[5]?`#${t[0]}${t[2]}${t[4]}`:`#${t}`}return`rgba(${n.join(\",\")},${s})`},get=t=\u003e{const e=new Map,n=(t,n)=\u003e{if(!t)return;const o=e.get(t)??[];o.includes(n)||o.push(n),e.set(t,o)};for(const e of t.connections){const t=e.__rootConnectionNames??[e.name];for(const o of t){n(e.name,o),n(o,o),n(e.__netConnectionName,o);for(const t of e.pointsToConnect)n(t.pointId,o),n(t.pcb_port_id,o)}}return t=\u003e{const n=(t=\u003e{const e=new Set;return t.filter(t=\u003e!e.has(t)\u0026\u0026(e.add(t),!0))})([...t.connectedTo.flatMap(t=\u003ee.get(t)??[]),...(t.offBoardConnectsTo??[]).flatMap(t=\u003ee.get(t)??[])]).join(\", \");return t.layers.map(t=\u003en?`${t}\\n${n}`:t).join(\"\\n\")}};function fet(t){const e=k8(t.layerCount),n=(t.traces??[]).some(t=\u003et.route.some((e,n)=\u003e{const o=t.route[n+1];return\"wire\"===e.route_type\u0026\u0026\"wire\"===o?.route_type\u0026\u0026o.layer===e.layer\u0026\u0026!iet.has(e.layer)})),o=new Set(t.connections.map(({name:t})=\u003et)),i=n?[...new Set((t.traces??[]).map(({connection_name:t})=\u003et).filter(t=\u003et\u0026\u0026!o.has(t)))].map(t=\u003e({name:t,pointsToConnect:[]})):[],r=[...t.connections,...i],s=(a=r,Object.fromEntries(a.map((t,e)=\u003e[t.name,`hsl(${340*e/a.length}, 100%, 50%)`])));var a;const c=get({...t,connections:r}),l=[],d=[],h=[],u=[];for(const t of r)for(const n of t.pointsToConnect){const o=cet(n),i=t.__rootConnectionNames??[t.name];u.push({x:n.x,y:n.y,color:s[t.name],layer:aet(e,o),label:[t.name,i.join(\", \"),o.join(\",\")].join(\"\\n\")})}for(const o of t.traces??[]){const i=o.route.filter(t=\u003e\"jumper\"===t.route_type),r=(t,e)=\u003ei.some(n=\u003e{const o=.01;return Math.abs(t.x-n.start.x)\u003co\u0026\u0026Math.abs(t.y-n.start.y)\u003co\u0026\u0026Math.abs(e.x-n.end.x)\u003co\u0026\u0026Math.abs(e.y-n.end.y)\u003co||Math.abs(t.x-n.end.x)\u003co\u0026\u0026Math.abs(t.y-n.end.y)\u003co\u0026\u0026Math.abs(e.x-n.start.x)\u003co\u0026\u0026Math.abs(e.y-n.start.y)\u003co});for(const i of o.route)if(\"via\"===i.route_type){const r=het(e,i.from_layer,i.to_layer);d.push({center:{x:i.x,y:i.y},radius:(i.via_diameter??pet(t))/2,fill:n?s[o.connection_name]:\"blue\",stroke:\"none\",layer:aet(e,r)})}else\"through_obstacle\"===i.route_type\u0026\u0026l.push({points:[i.start,i.end],strokeColor:met(s[o.connection_name]??\"purple\",.35),strokeWidth:i.width,strokeDash:[.1,.1],layer:aet(e,[i.from_layer,i.to_layer]),label:`${o.connection_name} through_obstacle`});for(let t=0;t\u003co.route.length-1;t++){const i=o.route[t],a=o.route[t+1];if(\"jumper\"===i.route_type){const t=s[o.connection_name]??\"rgba(255, 165, 0, 0.8)\",n=ret[\"1206x4_pair\"===i.footprint?\"1206x4_pair\":\"0603\"],r=Math.abs(i.end.x-i.start.x)\u003eMath.abs(i.end.y-i.start.y),a=r?n.padLength:n.padWidth,c=r?n.padWidth:n.padLength,d=aet(e,[i.layer]);for(const e of[i.start,i.end])h.push({center:e,width:a,height:c,fill:met(t,.5),stroke:\"rgba(0, 0, 0, 0.5)\",layer:d});l.push({points:[i.start,i.end],strokeColor:\"rgba(100, 100, 100, 0.8)\",strokeWidth:.3*n.padWidth,layer:d})}else if(\"wire\"===i.route_type\u0026\u0026\"wire\"===a.route_type\u0026\u0026a.layer===i.layer\u0026\u0026!r(i,a)){const t=set(e,i.layer);l.push({points:[{x:i.x,y:i.y},{x:a.x,y:a.y}],layer:`z${t}`,strokeWidth:i.width,strokeColor:oet(t),...n?{label:o.connection_name}:{}})}}}for(const n of t.obstacles){if(n.isCopperPour)continue;const t=det(n,e);if(0===t.length)throw new Error(`FanoutSolver: cannot visualize obstacle \"${n.obstacleId??\"unknown\"}\" without a valid layer`);const o=1===t.length?e[t[0]]:void 0,i=met(\"bottom\"===o?\"blue\":\"red\",.5**t.length),r=n.shape,s={center:n.center,fill:i,layer:`z${t.join(\",\")}`,label:c(n)};\"circle\"===r?d.push({...s,radius:Math.min(n.width,n.height)/2}):h.push({...s,width:n.width,height:n.height,ccwRotationDegrees:n.ccwRotationDegrees})}for(const n of t.jumpers??[])for(const t of n.pads)h.push({center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.3)\",stroke:\"rgba(255, 165, 0, 0.8)\",layer:aet(e,t.layers)});return{rects:h,circles:d,lines:l,points:u}}function yet(t,e){if(!Number.isFinite(e)||e\u003c=0)throw new Error(`FanoutSolver: ${t} must be a positive number, received ${e}`);return e}function _et(t,e,n){const o=new Map(e.map(t=\u003e[t.busId,t.connections.length])),i=new Map;for(const[e,r]of Object.entries(t))i.set(r,(i.get(r)??0)+(n?o.get(e)??1:1));return[...i.values()].reduce((t,e)=\u003et+e*e,0)}function bet(t){return t.balanceLayerLoadByConnectionCount?.25:.01}function xet(t){return t.reduce((t,e)=\u003et+Number(Boolean(e.via))+Number(Boolean(e.planeEndpointVia)),0)}function vet(t){const e=t.connections.reduce((e,n)=\u003ee+(\"left\"===t.direction||\"right\"===t.direction?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length;switch(t.direction){case\"right\":return t.sharedBoundary.maxX-e;case\"left\":return e-t.sharedBoundary.minX;case\"up\":return t.sharedBoundary.maxY-e;case\"down\":return e-t.sharedBoundary.minY}}function Iet(t){const e=\"left\"===t.direction||\"right\"===t.direction;return t.connections.some(t=\u003e{const n=t.exitTargetPoint??t.targetPoint,o=e?t.sourcePoint.y:t.sourcePoint.x,i=e?n.y:n.x;return Math.abs(o-i)\u003e1e-6})}function Cet(t){const e=\"left\"===t.direction||\"right\"===t.direction,n=e?t.xCoordinates:t.yCoordinates,o=t.connections.reduce((t,n)=\u003et+(e?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length,i=\"right\"===t.direction||\"up\"===t.direction?Math.max(...n):Math.min(...n);return Math.abs(o-i)\u003c1e-6}function Pet(t){const e=\"left\"===t.direction||\"right\"===t.direction,n=e?t.xCoordinates:t.yCoordinates,o=t.connections.reduce((t,n)=\u003et+(e?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length,i=\"right\"===t.direction||\"up\"===t.direction?Math.max(...n):Math.min(...n),r=e?t.pitchX:t.pitchY;return Math.round(Math.abs(o-i)/r)}function Met(t){const{buses:e,escapeLayers:n,escapeLayersByBusId:o}=t,i={},r=new Map;let s=0;for(const t of e){const e=r.get(t.componentId)??new Set;e.add(t.direction),r.set(t.componentId,e)}for(const t of e){const e=t.connections[0]?.sourceLayer;if(!e)throw new Error(`FanoutSolver: bus \"${t.busId}\" has no connections`);if(\"plane\"===t.termination.type){i[t.busId]=t.termination.layer;continue}const a=o[t.busId]??n,c=a.filter(t=\u003et!==e);if(a.includes(e)\u0026\u0026(Iet(t)||Cet(t)))i[t.busId]=e;else if(c.length\u003e0){const e=r.get(t.componentId);if(e.has(\"left\")\u0026\u0026e.has(\"right\")||e.has(\"up\")\u0026\u0026e.has(\"down\")){const e=Pet(t);i[t.busId]=c[Math.max(e-1,0)%c.length]}else i[t.busId]=c[s%c.length],s++}else i[t.busId]=e}return i}function Net(t){const{bus:e,srj:n,config:o,staticClearanceCache:i}=t,r=o.escapeLayers.filter(t=\u003enull!==htt({srj:n,bus:e,targetLayer:t,acceptedPlans:[],layerNames:o.layerNames,traceWidth:o.traceWidth,viaDiameter:o.viaDiameter,viaHoleDiameter:o.viaHoleDiameter,clearance:o.clearance,compactBusTracks:o.compactBusTracks,allowSameNetMerges:o.allowSameNetMerges,staticClearanceCache:i}));return r.length\u003e0?r:o.escapeLayers}var wet=class extends b8{constructor(t,e={}){super(),this.inputSrj=t,this.options=e,this.config=function(t,e){const n=yet(\"traceWidth\",e.traceWidth??t.nominalTraceWidth??t.minTraceWidth),o=yet(\"viaDiameter\",e.viaDiameter??t.minViaPadDiameter??t.min_via_pad_diameter??t.minViaDiameter??Math.max(2*n,.3)),i=yet(\"viaHoleDiameter\",e.viaHoleDiameter??t.minViaHoleDiameter??t.min_via_hole_diameter??.5*o);if(i\u003e=o)throw new Error(`FanoutSolver: viaHoleDiameter ${i} must be smaller than viaDiameter ${o}`);const r=yet(\"clearance\",e.clearance??t.minViaEdgeToPadEdgeClearance??t.minTraceToPadEdgeClearance??t.defaultObstacleMargin??t.minTraceWidth),s=k8(t.layerCount),a=e.escapeLayers??s;for(const e of a)if(!s.includes(e))throw new Error(`FanoutSolver: escape layer \"${e}\" is not available in a ${t.layerCount}-layer SimpleRouteJson`);if(new Set(a).size!==a.length)throw new Error(\"FanoutSolver: escapeLayers contains duplicates\");const c=e.borderDistribution??\"preserve\";if(\"preserve\"!==c\u0026\u0026\"even\"!==c)throw new Error(`FanoutSolver: borderDistribution must be \"preserve\" or \"even\", received \"${c}\"`);return{traceWidth:n,viaDiameter:o,viaHoleDiameter:i,clearance:r,compactBusTracks:e.compactBusTracks??!1,allowSameNetMerges:e.allowSameNetMerges??!1,singleLayerPushAndShove:e.singleLayerPushAndShove??!1,singleLayerAdaptiveExits:e.singleLayerAdaptiveExits??!1,borderDistribution:c,layerNames:s,escapeLayers:a,maxLayerCombinations:void 0===e.maxLayerCombinations?256:yet(\"maxLayerCombinations\",e.maxLayerCombinations),balanceLayerLoadByConnectionCount:e.balanceLayerLoadByConnectionCount??!1}}(t,e),this.preparedBuses=j7(t,e);for(const t of this.preparedBuses){if(\"plane\"!==t.termination.type)continue;const e=t.termination.layer;if(!this.config.layerNames.includes(e))throw new Error(`FanoutSolver: plane-terminated bus \"${t.busId}\" targets unavailable layer \"${e}\"`);if(t.connections.some(t=\u003et.sourceLayer===e))throw new Error(`FanoutSolver: plane-terminated bus \"${t.busId}\" must target a layer below its source pad`)}const n=this.preparedBuses.filter(t=\u003e\"boundary\"===t.termination.type).map(t=\u003et.busId),o=Object.fromEntries(this.preparedBuses.flatMap(t=\u003e\"plane\"===t.termination.type?[[t.busId,t.termination.layer]]:[])),i=Object.fromEntries(this.preparedBuses.flatMap(e=\u003e\"plane\"===e.termination.type?[]:[[e.busId,Net({bus:e,srj:t,config:this.config,staticClearanceCache:this.routeStaticClearanceCache})]]));this.escapeLayersByBusId=i;const r=function(t){const{busIds:e,layers:n,layersByBusId:o,maxAssignments:i}=t;if(0===n.length)throw new Error(\"FanoutSolver: no escape layers are available\");if(!Number.isInteger(i)||i\u003c1)throw new Error(`FanoutSolver: maxLayerCombinations must be positive, received ${i}`);const r=e.map(t=\u003eo?.[t]??n),s=r.findIndex(t=\u003e0===t.length);if(s\u003e=0)throw new Error(`FanoutSolver: no escape layers are available for bus \"${e[s]}\"`);const a=r.reduce((t,e)=\u003et*e.length,1),c=Math.min(i,Number.isFinite(a)?a:i),l=[],d=new Set;function h(t){const n={};for(let o=0;o\u003ce.length;o++)n[e[o]]=r[o][t[o]];const o=JSON.stringify(n);d.has(o)||(d.add(o),l.push(n))}if(a\u003c=i){for(let t=0;t\u003cc;t++){const n=[];let o=t;for(let t=0;t\u003ce.length;t++){const e=r[t].length,i=o%e;o=Math.floor(o/e),n.push((i+t)%e)}h(n)}return l}function u(t){let e=0|t;return e=Math.imul(e^e\u003e\u003e\u003e16,569420461),e=Math.imul(e^e\u003e\u003e\u003e15,1935289751),(e^e\u003e\u003e\u003e15)\u003e\u003e\u003e0}const p=e.map((t,e)=\u003ee%r[e].length);h(p);const m=Math.max(...r.map(t=\u003et.length));for(let t=1;t\u003cm\u0026\u0026l.length\u003cc;t++)h(p.map((e,n)=\u003e(e+t)%r[n].length));for(let t=0;t\u003ce.length\u0026\u0026l.length\u003cc;t++)for(let e=1;e\u003cr[t].length\u0026\u0026l.length\u003cc;e++){const n=[...p];n[t]=(p[t]+e)%r[t].length,h(n)}for(let t=1;l.length\u003cc\u0026\u0026t\u003c20*c;t++)h(e.map((e,n)=\u003eu(2654435761*t+2246822507*n)%r[n].length));return l}({busIds:n,layers:this.config.escapeLayers,layersByBusId:i,maxAssignments:this.config.maxLayerCombinations}).map(t=\u003e({...t,...o}));this.layerAssignments=function(t){const{preferredAssignment:e,generatedAssignments:n,maxAssignments:o}=t,i=JSON.stringify(e);return[e,...n.filter(t=\u003eJSON.stringify(t)!==i)].slice(0,o)}({preferredAssignment:Met({buses:this.preparedBuses,escapeLayers:this.config.escapeLayers,escapeLayersByBusId:i}),generatedAssignments:r,maxAssignments:this.config.maxLayerCombinations}),this.MAX_ITERATIONS=this.config.maxLayerCombinations+2}inputSrj;options;preparedBuses;attempts=[];layerAssignments;config;escapeLayersByBusId;evaluatedAssignmentKeys=new Set;queuedAssignmentKeys=new Set;assignmentRepairDepthByKey=new Map;pendingRepairAssignments=[];routeStaticClearanceCache=new Map;routingPrefixCache=new Map;groupedBeamEvaluated=!1;nextAssignmentIndex=0;nextGeneratedAssignmentIndex=0;bestAttempt=null;endpointCompletion=null;getSolverName(){return\"FanoutSolver\"}completeBestAttemptEndpoints(){this.options.completeOriginalEndpoints\u0026\u0026!this.endpointCompletion\u0026\u0026this.bestAttempt\u0026\u0026(this.endpointCompletion=y7({inputSrj:this.inputSrj,fanoutSrj:this.bestAttempt.outputSrj,plans:this.bestAttempt.plans,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,effort:this.options.endpointCompletionEffort,routeDownstreamConnections:this.options.routeDownstreamConnections}))}getValidationBoundary(){if(this.options.sharedBoundary)return this.options.sharedBoundary;const t=this.preparedBuses[0]?.sharedBoundary;return t?this.preparedBuses.slice(1).reduce((t,e)=\u003e({minX:Math.min(t.minX,e.sharedBoundary.minX),maxX:Math.max(t.maxX,e.sharedBoundary.maxX),minY:Math.min(t.minY,e.sharedBoundary.minY),maxY:Math.max(t.maxY,e.sharedBoundary.maxY)}),{...t}):this.inputSrj.bounds}validateCompletePlans(t,e){return eet({inputSrj:this.inputSrj,outputSrj:e,plans:t,preparedBuses:this.preparedBuses,sharedBoundary:this.getValidationBoundary(),clearance:this.config.clearance})}evaluateAssignmentWithStrategy(t,e,n){let o=[],i=[],r=new Map;const s=1===this.config.escapeLayers.length;if(s\u0026\u0026this.config.singleLayerPushAndShove){const t={srj:this.inputSrj,buses:this.preparedBuses,traceWidth:this.config.traceWidth,clearance:this.config.clearance,borderDistribution:this.config.borderDistribution},e=Ytt(t)??(this.config.singleLayerAdaptiveExits?Mtt({...t,availableBoundaryRegions:R7(this.options.availableCornersAndSides)}):null);e?o.push(...e):i.push(...this.preparedBuses.map(t=\u003et.busId))}const a=[...this.preparedBuses].sort((t,o)=\u003eNumber(\"plane\"===o.termination.type)-Number(\"plane\"===t.termination.type)||(\"group-by-layer\"===n?(e[t.busId]??\"\").localeCompare(e[o.busId]??\"\"):0)||o.componentObstacles.length-t.componentObstacles.length||(s?vet(o)-vet(t):o.connections.length-t.connections.length||(\"deep-first\"===n?vet(o)-vet(t):vet(t)-vet(o))));let c,l=`${n}|`;for(const n of s\u0026\u0026this.config.singleLayerPushAndShove?[]:a){const s=e[n.busId];if(!s)throw new Error(`FanoutSolver: assignment ${t} has no layer for bus \"${n.busId}\"`);l+=`${n.busId.length}:${n.busId};${s.length}:${s};`;const a=this.routingPrefixCache.get(l);if(a){o=[...a.plans],i=[...a.failedBusIds],r=new Map(a.blockingBusCounts);continue}const c=new Map,d=htt({srj:this.inputSrj,bus:n,targetLayer:s,acceptedPlans:o,layerNames:this.config.layerNames,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,compactBusTracks:this.config.compactBusTracks,allowSameNetMerges:this.config.allowSameNetMerges,staticClearanceCache:this.routeStaticClearanceCache,blockingBusCounts:c});if(d)o.push(...d);else{i.push(n.busId);for(const[t,e]of c)r.set(t,(r.get(t)??0)+e)}this.routingPrefixCache.set(l,{plans:[...o],failedBusIds:[...i],blockingBusCounts:new Map(r)})}let d=S8({inputSrj:this.inputSrj,plans:o,layerNames:this.config.layerNames});const h=o.length===this.inputSrj.connections.length?this.validateCompletePlans(o,d):null;h\u0026\u0026!h.valid\u0026\u0026(c=h.issues,o=[],i=this.preparedBuses.map(t=\u003et.busId),r.clear(),d=S8({inputSrj:this.inputSrj,plans:o,layerNames:this.config.layerNames}));const u=this.preparedBuses.length-i.length,p=o.reduce((t,e)=\u003et+e.length,0),m=1e6*(this.inputSrj.connections.length-o.length)+1e5*i.length+p+.1*xet(o)+_et(e,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config);return{summary:{assignmentIndex:t,busLayerAssignments:e,routedBusCount:u,routedConnectionCount:o.length,failedBusIds:i,score:m,...c?{validationIssues:c}:{}},plans:o,blockingBusIds:[...r.entries()].toSorted(([,t],[,e])=\u003ee-t).map(([t])=\u003et),outputSrj:d}}evaluateAssignment(t,e){let n=this.evaluateAssignmentWithStrategy(t,e,\"default\");if(n.summary.routedConnectionCount===this.inputSrj.connections.length)return n;for(const o of[\"group-by-layer\",\"deep-first\"]){const i=this.evaluateAssignmentWithStrategy(t,e,o);if(i.summary.score\u003cn.summary.score\u0026\u0026(n=i),n.summary.routedConnectionCount===this.inputSrj.connections.length)return n}return n}evaluateGroupedBeam(t,e=!1){if(this.config.escapeLayers.length\u003c2)return null;if(this.preparedBuses.length\u003e56)return null;const n=this.inputSrj.connections.length;if(n\u003e64)return null;if(1!==new Set(this.preparedBuses.map(t=\u003et.componentId)).size)return null;const o=[...this.preparedBuses].sort((t,n)=\u003e{const o=\"plane\"===t.termination.type?1:this.escapeLayersByBusId[t.busId]?.length??this.config.escapeLayers.length,i=\"plane\"===n.termination.type?1:this.escapeLayersByBusId[n.busId]?.length??this.config.escapeLayers.length;return Number(\"plane\"===n.termination.type)-Number(\"plane\"===t.termination.type)||(e?t.direction.localeCompare(n.direction):0)||o-i||n.componentObstacles.length-t.componentObstacles.length||n.connections.length-t.connections.length||Pet(n)-Pet(t)||t.busId.localeCompare(n.busId)}),i=n\u003c=24,r=this.preparedBuses.some(t=\u003et.connections.length\u003e1),s=i?48:n\u003c=32?24:12,a=i\u0026\u0026!r?4:1;let c=[{assignment:{},plans:[]}];const l=t=\u003et.plans.reduce((t,e)=\u003et+e.length,0)+.1*xet(t.plans)+1e4*this.preparedBuses.reduce((e,n)=\u003e{if(\"boundary\"!==n.termination.type||!Iet(n))return e;const o=n.connections[0]?.sourceLayer;return t.assignment[n.busId]===o?e:e+n.connections.length},0)+_et(t.assignment,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config);for(const t of o){const e=[];for(const n of c){const o=\"plane\"===t.termination.type?[t.termination.layer]:this.escapeLayersByBusId[t.busId]??this.config.escapeLayers,i=new Map;for(const[t,e]of Object.entries(n.assignment)){const n=this.preparedBuses.find(e=\u003ee.busId===t);i.set(e,(i.get(e)??0)+(this.config.balanceLayerLoadByConnectionCount?n?.connections.length??1:1))}const r=t.connections[0]?.sourceLayer,s=Iet(t),c=o.toSorted((t,e)=\u003e(i.get(t)??0)-(i.get(e)??0)||(s?Number(e===r)-Number(t===r):Number(t===r)-Number(e===r))||t.localeCompare(e));for(const o of c){const i=dtt({srj:this.inputSrj,bus:t,targetLayer:o,acceptedPlans:n.plans,layerNames:this.config.layerNames,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,compactBusTracks:this.config.compactBusTracks,allowSameNetMerges:this.config.allowSameNetMerges,staticClearanceCache:this.routeStaticClearanceCache},a);for(const r of i)e.push({assignment:{...n.assignment,[t.busId]:o},plans:[...n.plans,...r]})}}if(0===e.length)return null;e.sort((t,e)=\u003e{const n=l(t)-l(e);return Math.abs(n)\u003e1e-9?n:JSON.stringify(t.assignment).localeCompare(JSON.stringify(e.assignment))});const n=new Map;c=[];for(const t of e){const e=JSON.stringify(t.assignment),o=n.get(e)??0;if(!(o\u003e=2)\u0026\u0026(n.set(e,o+1),c.push(t),c.length\u003e=s))break}}const d=c[0];if(!d)return null;const h=S8({inputSrj:this.inputSrj,plans:d.plans,layerNames:this.config.layerNames});if(d.plans.length===this.inputSrj.connections.length\u0026\u0026!this.validateCompletePlans(d.plans,h).valid)return null;const u=d.plans.length===this.inputSrj.connections.length?d.plans.reduce((t,e)=\u003et+e.length,0)+.1*xet(d.plans)+_et(d.assignment,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config):Number.POSITIVE_INFINITY;if(!Number.isFinite(u))return null;return{summary:{assignmentIndex:t,busLayerAssignments:d.assignment,routedBusCount:this.preparedBuses.length,routedConnectionCount:d.plans.length,failedBusIds:[],score:u},plans:d.plans,blockingBusIds:[],outputSrj:h}}prioritizeFailedBusRepairs(t,e,n){const o=JSON.stringify(t),i=this.assignmentRepairDepthByKey.get(o)??0;if(i\u003e=2)return;const r=[],s=new Set,a=t=\u003e{const e=JSON.stringify(t);s.has(e)||this.evaluatedAssignmentKeys.has(e)||this.queuedAssignmentKeys.has(e)||(s.add(e),this.queuedAssignmentKeys.add(e),this.assignmentRepairDepthByKey.set(e,i+1),r.push(t))},c=[];for(let t=0;t\u003cMath.max(e.length,n.length);t++){const o=e[t],i=n[t];o\u0026\u0026!c.includes(o)\u0026\u0026c.push(o),i\u0026\u0026!c.includes(i)\u0026\u0026c.push(i)}for(const o of e){const e=t[o],i=this.escapeLayersByBusId[o];if(e\u0026\u0026i){for(const s of n.slice(0,4)){const n=t[s],c=this.escapeLayersByBusId[s];if(n\u0026\u0026c\u0026\u0026i.includes(n)\u0026\u0026c.includes(e)\u0026\u0026(a({...t,[o]:n,[s]:e}),r.length\u003e=8))break}if(r.length\u003e=8)break}}for(const e of c){const n=t[e],o=this.escapeLayersByBusId[e];if(!n||!o)continue;const i=o.indexOf(n);for(let s=1;s\u003co.length;s++){const c=o[(Math.max(i,0)+s)%o.length];if(c!==n\u0026\u0026(a({...t,[e]:c}),r.length\u003e=8))break}if(r.length\u003e=8)break}this.pendingRepairAssignments.push(...r)}hasCompleteBestAttempt(){return this.bestAttempt?.summary.routedConnectionCount===this.inputSrj.connections.length}shouldEvaluateGroupedBeam(){if(this.groupedBeamEvaluated||0===this.nextAssignmentIndex)return!1;return this.hasCompleteBestAttempt()||0===this.pendingRepairAssignments.length||this.nextAssignmentIndex\u003e=this.config.maxLayerCombinations}_step(){if(this.shouldEvaluateGroupedBeam()){this.groupedBeamEvaluated=!0;let t=this.evaluateGroupedBeam(-1);if(t||(t=this.evaluateGroupedBeam(-1,!0)),t){this.attempts.push(t.summary),(!this.bestAttempt||t.summary.score\u003cthis.bestAttempt.summary.score)\u0026\u0026(this.bestAttempt=t);const e=this.bestAttempt.summary;return this.stats={assignment:e.assignmentIndex\u003c0?0:e.assignmentIndex+1,assignmentCount:this.config.maxLayerCombinations,routedBuses:`${e.routedBusCount}/${this.preparedBuses.length}`,routedConnections:`${e.routedConnectionCount}/${this.inputSrj.connections.length}`,failedBuses:\"none\",bestScore:e.score},this.completeBestAttemptEndpoints(),void(this.solved=!0)}if(this.hasCompleteBestAttempt())return this.completeBestAttemptEndpoints(),void(this.solved=!0)}let t;for(;!t\u0026\u0026this.nextAssignmentIndex\u003cthis.config.maxLayerCombinations;){const e=this.nextAssignmentIndex%3==0;let n,o=!1;if(!this.groupedBeamEvaluated\u0026\u0026this.nextAssignmentIndex\u003e0?(n=this.pendingRepairAssignments.pop(),o=void 0!==n):e?n=this.layerAssignments[this.nextGeneratedAssignmentIndex++]:(n=this.pendingRepairAssignments.pop(),o=void 0!==n),n||!this.groupedBeamEvaluated\u0026\u00260!==this.nextAssignmentIndex||(n=e?this.pendingRepairAssignments.pop():this.layerAssignments[this.nextGeneratedAssignmentIndex++],o=e\u0026\u0026void 0!==n),!n)break;const i=JSON.stringify(n);o\u0026\u0026this.queuedAssignmentKeys.delete(i),this.evaluatedAssignmentKeys.has(i)||(t=n)}if(!t\u0026\u0026!this.groupedBeamEvaluated)return;if(!t)return void(this.hasCompleteBestAttempt()?(this.completeBestAttemptEndpoints(),this.solved=!0):(this.failed=!0,this.error=this.bestAttempt?`FanoutSolver: best layer assignment routed ${this.bestAttempt.summary.routedConnectionCount}/${this.inputSrj.connections.length} connections`:\"FanoutSolver: no layer assignment could be evaluated\"));const e=this.evaluateAssignment(this.nextAssignmentIndex,t);this.nextAssignmentIndex++,this.evaluatedAssignmentKeys.add(JSON.stringify(t)),(!this.bestAttempt||e.summary.routedConnectionCount\u003e=this.bestAttempt.summary.routedConnectionCount)\u0026\u0026this.prioritizeFailedBusRepairs(t,e.summary.failedBusIds,e.blockingBusIds),this.attempts.push(e.summary),(!this.bestAttempt||e.summary.score\u003cthis.bestAttempt.summary.score)\u0026\u0026(this.bestAttempt=e),this.stats={assignment:e.summary.assignmentIndex+1,assignmentCount:this.config.maxLayerCombinations,routedBuses:`${e.summary.routedBusCount}/${this.preparedBuses.length}`,routedConnections:`${e.summary.routedConnectionCount}/${this.inputSrj.connections.length}`,failedBuses:e.summary.failedBusIds.join(\", \")||\"none\",bestScore:this.bestAttempt.summary.score},this.groupedBeamEvaluated\u0026\u0026e.summary.routedConnectionCount===this.inputSrj.connections.length\u0026\u0026(this.completeBestAttemptEndpoints(),this.solved=!0)}computeProgress(){return this.solved||this.failed?1:this.nextAssignmentIndex/this.config.maxLayerCombinations}getConstructorParams(){return[this.inputSrj,this.options]}getOutput(){if(!this.solved||!this.bestAttempt)throw new Error(\"FanoutSolver: getOutput() called before a complete fanout was solved\");const t=this.validateCompletePlans(this.bestAttempt.plans,this.bestAttempt.outputSrj);if(!t.valid)throw new Error(`FanoutSolver: completed output failed validation: ${t.issues[0]?.message??\"unknown validation error\"}`);const e=this.endpointCompletion?.simpleRouteJson??this.bestAttempt.outputSrj,n=new Map((e.traces??[]).map(t=\u003e[t.pcb_trace_id,t]));return{simpleRouteJson:this.endpointCompletion?.simpleRouteJson??this.bestAttempt.outputSrj,fanoutTraces:this.bestAttempt.plans.flatMap(t=\u003e[n.get(t.trace.pcb_trace_id)??t.trace,...t.planeEndpointTrace?[n.get(t.planeEndpointTrace.pcb_trace_id)??t.planeEndpointTrace]:[]]),completionTraces:this.endpointCompletion?.traces??[],...this.endpointCompletion?{endpointCompletion:this.endpointCompletion.report}:{},planeTerminations:this.bestAttempt.plans.flatMap(t=\u003e\"plane\"===t.termination.type\u0026\u0026t.via?[{busId:t.busId,connectionName:t.connectionName,layer:t.termination.layer,via:t.via}]:[]),busLayerAssignments:this.bestAttempt.summary.busLayerAssignments,busDirections:Object.fromEntries(this.preparedBuses.map(t=\u003e[t.busId,t.direction])),attempts:[...this.attempts],validation:t}}getOutputSimpleRouteJson(){return this.getOutput().simpleRouteJson}visualize(){return fet(this.endpointCompletion?.simpleRouteJson??this.bestAttempt?.outputSrj??this.inputSrj)}};function Tet(t){const{minX:e,maxX:n}=t.bounds,o=(e+n)/2;if(!Number.isFinite(o))throw new Error(`Detected component ${t.componentId} has bad bounds`);return o}function Ret(t){const{minY:e,maxY:n}=t.bounds,o=(e+n)/2;if(!Number.isFinite(o))throw new Error(`Detected component ${t.componentId} has bad bounds`);return o}function Eet(t,e){const n=(function(t,e){const[n,o]=Tet(t)\u003cTet(e)?[t,e]:[e,t];return o.bounds.minX-n.bounds.maxX}(t,e)-2)/2;return Math.min(4.5,n)}function Aet(t,e){const n=e.filter(t=\u003e\"bga\"===t.componentKind).map(e=\u003efunction(t,e){const n=t.obstacles.filter(t=\u003et.componentId===e.componentId);if(0===n.length)throw new Error(`Detected component ${e.componentId} has no physical obstacles`);return{...e,bounds:{__type:\"rect\",minX:Math.min(...n.map(t=\u003et.center.x-t.width/2)),maxX:Math.max(...n.map(t=\u003et.center.x+t.width/2)),minY:Math.min(...n.map(t=\u003et.center.y-t.height/2)),maxY:Math.max(...n.map(t=\u003et.center.y+t.height/2))}}}(t,e)).toSorted((t,e)=\u003eTet(t)-Tet(e));if(2!==n.length)throw new Error(`Pipeline 10 requires exactly two detected BGAs; found ${n.map(t=\u003et.componentId).join(\", \")||\"none\"}`);const[o,i]=n;if(o.componentId===i.componentId)throw new Error(\"Pipeline 10 requires two distinct BGA component IDs\");if(Eet(o,i)\u003c2)throw new Error(\"Pipeline 10 cannot provide 2mm fanout margins while retaining a 2mm routing corridor\");return{first:o,second:i}}function Oet(t,e){const{minX:n,maxX:o,minY:i,maxY:r}=t.bounds;return{minX:n-e,maxX:o+e,minY:i-e,maxY:r+e}}function ket(t){const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds;return{minX:e,maxX:n,minY:o,maxY:i}}function Let({inputSrj:t,source:e,target:n}){const o=Eet(e,n),i=Oet(e,o),r=Tet(n)\u003eTet(e)?\"right\":\"left\",s=\"right\"===r?\"left\":\"right\";return t.connections.map((t,n)=\u003e{const a=t.pointsToConnect.filter(t=\u003et.x\u003e=e.bounds.minX\u0026\u0026t.x\u003c=e.bounds.maxX\u0026\u0026t.y\u003e=e.bounds.minY\u0026\u0026t.y\u003c=e.bounds.maxY);if(1!==a.length)throw new Error(`Connection ${t.name} must touch ${e.componentId} exactly once before fanout`);const c=a[0],l=\"right\"===r?i.maxX-c.x:c.x-i.minX,d=[{direction:\"up\",distance:i.maxY-c.y},{direction:\"down\",distance:c.y-i.minY},{direction:s,distance:\"right\"===s?i.maxX-c.x:c.x-i.minX}].toSorted((t,e)=\u003et.distance-e.distance)[0].direction,h=l\u003c=o+1.2?r:d;let u=\"up\"===h?\"top\":\"down\"===h?\"bottom\":h;return\"up\"===h?u=c.x\u003cTet(e)?\"top-left\":\"top-right\":\"down\"===h?u=c.x\u003cTet(e)?\"bottom-left\":\"bottom-right\":c.y\u003eRet(e)+1e-6?u=\"right\"===h?\"top-right\":\"top-left\":c.y\u003cRet(e)-1e-6\u0026\u0026(u=\"right\"===h?\"bottom-right\":\"bottom-left\"),{busId:`pipeline10_fanout:${e.componentId}:${n}`,connectionNames:[t.name],sourceComponentId:e.componentId,direction:h,preferredExit:u,termination:{type:\"boundary\"}}})}function Det({inputSrj:t,source:e,target:n}){const o=Eet(e,n);return{buses:Let({inputSrj:t,source:e,target:n}),sourceComponentId:e.componentId,availableCornersAndSides:[\"top_left\",\"top_middle\",\"top_right\",\"right_top\",\"right_middle\",\"right_bottom\",\"bottom_right\",\"bottom_middle\",\"bottom_left\",\"left_bottom\",\"left_middle\",\"left_top\"],componentBounds:{[e.componentId]:ket(e)},sharedBoundary:Oet(e,o),maxLayerCombinations:256,balanceLayerLoadByConnectionCount:!0,compactBusTracks:!0,borderDistribution:\"even\"}}var zet=class extends kt{constructor(t){super(),this.inputProblem=t,this.fanoutSolver=new wet(t.inputSrj,t.options),this.activeSubSolver=this.fanoutSolver,this.MAX_ITERATIONS=this.fanoutSolver.MAX_ITERATIONS+1}inputProblem;fanoutSolver;_step(){if(this.fanoutSolver.step(),this.progress=this.fanoutSolver.progress,this.stats={...this.fanoutSolver.stats},this.fanoutSolver.failed)return this.error=this.fanoutSolver.error??\"Fanout solver failed\",this.failed=!0,void(this.activeSubSolver=null);this.fanoutSolver.solved\u0026\u0026(this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.fanoutSolver.getOutput()}getOutputSimpleRouteJson(){return this.fanoutSolver.getOutputSimpleRouteJson()}visualize(){return this.fanoutSolver.visualize()}preview(){return this.fanoutSolver.preview()}},Fet=class extends kt{constructor(t){super(),this.inputProblem=t,this.autoroutingPipelineSolver=new H9(t.inputSrj,t.options),this.activeSubSolver=this.autoroutingPipelineSolver,this.MAX_ITERATIONS=this.autoroutingPipelineSolver.MAX_ITERATIONS+1}inputProblem;autoroutingPipelineSolver;_step(){if(this.autoroutingPipelineSolver.step(),this.progress=this.autoroutingPipelineSolver.progress,this.stats={...this.autoroutingPipelineSolver.stats},this.autoroutingPipelineSolver.failed)return this.error=this.autoroutingPipelineSolver.error??\"Autorouting pipeline failed\",this.failed=!0,void(this.activeSubSolver=null);this.autoroutingPipelineSolver.solved\u0026\u0026(this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.autoroutingPipelineSolver.getOutputSimpleRouteJson()}visualize(){return this.autoroutingPipelineSolver.visualize()}preview(){return this.autoroutingPipelineSolver.preview()}},Bet=class extends Dt{componentDetectionSolver;firstBgaFanoutSolver;secondBgaFanoutSolver;autoroutingPipelineSolver;get currentPipelineStepIndex(){return this.currentPipelineStageIndex}get startTimeOfPhase(){return this.startTimeOfStage}get timeSpentOnPhase(){return this.timeSpentOnStage}pipelineDef=[Lt(\"componentDetectionSolver\",UZ,t=\u003e[{inputSrj:t.inputProblem.inputSrj}]),Lt(\"firstBgaFanoutSolver\",zet,t=\u003e{const e=Aet(t.inputProblem.inputSrj,t.componentDetectionSolver.getOutput());return[{inputSrj:t.inputProblem.inputSrj,options:Det({inputSrj:t.inputProblem.inputSrj,source:e.first,target:e.second})}]}),Lt(\"secondBgaFanoutSolver\",zet,t=\u003e{const e=Aet(t.inputProblem.inputSrj,t.componentDetectionSolver.getOutput()),n=t.firstBgaFanoutSolver.getOutputSimpleRouteJson();return[{inputSrj:n,options:Det({inputSrj:n,source:e.second,target:e.first})}]}),Lt(\"autoroutingPipelineSolver\",Fet,t=\u003e[{inputSrj:t.secondBgaFanoutSolver.getOutputSimpleRouteJson(),options:t.inputProblem.options}])];constructor(t,e={}){super({inputSrj:t,options:e}),this.MAX_ITERATIONS=1e8*(e.effort??1)+1024}getSolverName(){return\"AutoroutingPipelineSolver10_BgaFanout\"}getConstructorParams(){return[this.inputProblem.inputSrj,this.inputProblem.options]}getOutput(){if(!this.autoroutingPipelineSolver?.solved)throw new Error(\"Pipeline 10 has not solved yet\");return this.autoroutingPipelineSolver.getOutput()}getOutputSimpleRouteJson(){return this.getOutput()}getOutputSimplifiedPcbTraces(){return this.getOutput().traces??[]}get srjWithPointPairs(){return this.autoroutingPipelineSolver?.autoroutingPipelineSolver.srjWithPointPairs}initialVisualize(){return Ho(this.inputProblem.inputSrj)}finalVisualize(){return Ho(this.getOutput())}},jet=class extends kt{constructor(t){super(),this.inputProblem=t,this.simplifiedRouteByTraceId=new Map(t.simplifiedHdRoutes.map(t=\u003e[t.connectionName,t])),this.MAX_ITERATIONS=t.preparedInput.preparedTraces.length+1}inputProblem;simplifiedRouteByTraceId;outputTraces=[];nextTraceIndex=0;getSolverName(){return\"ApplyTraceSimplificationSolver\"}_step(){const t=this.inputProblem.preparedInput.preparedTraces,e=t[this.nextTraceIndex];e?(this.outputTraces.push(this.applyTrace(e)),this.nextTraceIndex++,this.progress=this.nextTraceIndex/Math.max(1,t.length)):this.finishApplication()}applyTrace(t){if(!t.mutableHdRoute)return structuredClone(t.originalTrace);const e=this.simplifiedRouteByTraceId.get(t.originalTrace.pcb_trace_id);if(!e||void 0===t.uniformTraceWidth)throw new Error(`Simplification removed trace \"${t.originalTrace.pcb_trace_id}\"`);const n=Mo(e,this.inputProblem.preparedInput.srj.layerCount,{defaultViaHoleDiameter:t.viaHoleDiameter,obstacles:this.inputProblem.preparedInput.srj.obstacles,connMap:this.inputProblem.preparedInput.connMap}),o=n.filter(t=\u003e\"jumper\"===t.route_type),i=((t,e)=\u003et.map(t=\u003e\"wire\"===t.route_type||\"through_obstacle\"===t.route_type?{...t,width:e}:t))([...structuredClone(t.leadingTerminalVias),...n.filter(t=\u003e\"jumper\"!==t.route_type),...structuredClone(t.trailingTerminalVias),...o],t.uniformTraceWidth);return((t,e)=\u003e{const n=t.filter(t=\u003e\"wire\"===t.route_type);e.startPcbPortId\u0026\u0026n[0]\u0026\u0026(n[0].start_pcb_port_id=e.startPcbPortId),e.endPcbPortId\u0026\u0026n.at(-1)\u0026\u0026(n.at(-1).end_pcb_port_id=e.endPcbPortId)})(i,e),{...structuredClone(t.originalTrace),route:i}}finishApplication(){const t=this.inputProblem.preparedInput.preparedTraces;this.stats={inputTraceCount:t.length,outputTraceCount:this.outputTraces.length,inputRoutePointCount:t.reduce((t,e)=\u003et+e.originalTrace.route.length,0),outputRoutePointCount:this.outputTraces.reduce((t,e)=\u003et+e.route.length,0)},this.progress=1,this.solved=!0}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error(\"Cannot get applied traces before conversion completes\");return{...structuredClone(this.inputProblem.preparedInput.originalSrj),traces:structuredClone(this.outputTraces)}}},$et=(t,e)=\u003e{const n=t.at(-1);if(n\u0026\u0026(o=n,i=e,Math.abs(o.x-i.x)\u003c=1e-9\u0026\u0026Math.abs(o.y-i.y)\u003c=1e-9\u0026\u0026o.z===i.z))return void 0!==e.traceThickness\u0026\u0026(n.traceThickness=e.traceThickness),void(void 0!==e.pcb_port_id\u0026\u0026(n.pcb_port_id=e.pcb_port_id));var o,i;t.push(e)},Yet=(t,e,n)=\u003e{for(let o=e+1;o\u003ct.length;o++){const e=t[o];if(\"wire\"===e.route_type)return ko(e.layer,n);if(\"through_obstacle\"===e.route_type)return ko(e.from_layer,n)}},Xet=({fromZ:t,toZ:e,previousZ:n,nextZ:o})=\u003en===t?[t,e]:n===e?[e,t]:o===e?[t,e]:o===t?[e,t]:[t,e],Vet=(t,e)=\u003e{for(const e of t)if(\"via\"===e.route_type\u0026\u0026void 0!==e.via_diameter)return e.via_diameter;return e},Wet=(t,e)=\u003e{const n=\"start\"===e?t:[...t].reverse();for(const t of n){if(\"wire\"!==t.route_type)continue;const n=\"start\"===e?t.start_pcb_port_id:t.end_pcb_port_id;if(n)return n}},Het=t=\u003e({route_type:\"jumper\",start:{...t.start},end:{...t.end},footprint:t.footprint}),Get=(t,e)=\u003e{for(const e of t.route)if(\"via\"===e.route_type\u0026\u0026void 0!==e.via_hole_diameter)return e.via_hole_diameter;return e},Uet=class extends kt{preparedInput;seenTraceIds=new Set;nextTraceIndex=0;constructor(t){super();const e=structuredClone(t.inputSrj),n=fX(e),o=ii(n);this.preparedInput={originalSrj:e,srj:n,connMap:o,colorMap:wo(n,o),immutableHdRoutes:[],mutableHdRoutes:[],netByConnectionName:new Map,options:{...t.options},preparedTraces:[]},this.MAX_ITERATIONS=(n.traces?.length??0)+1}getSolverName(){return\"PrepareTraceSimplificationSolver\"}_step(){const t=this.preparedInput.srj.traces??[],e=t[this.nextTraceIndex];if(!e)return this.stats={inputTraceCount:t.length,mutableTraceCount:this.preparedInput.mutableHdRoutes.length,immutableTraceCount:t.length-this.preparedInput.mutableHdRoutes.length},this.progress=1,void(this.solved=!0);this.prepareTrace(e,this.nextTraceIndex),this.nextTraceIndex++,this.progress=this.nextTraceIndex/Math.max(1,t.length)}prepareTrace(t,e){if(this.seenTraceIds.has(t.pcb_trace_id))throw new Error(`Duplicate pcb_trace_id \"${t.pcb_trace_id}\"`);this.seenTraceIds.add(t.pcb_trace_id);const n=Yo(this.preparedInput.srj),o=(t=\u003e{const e=t.route.flatMap(t=\u003e\"wire\"===t.route_type||\"through_obstacle\"===t.route_type?[t.width]:[]),n=e[0];if(void 0!==n\u0026\u0026!e.some(t=\u003eMath.abs(t-n)\u003e1e-9))return n})(t),{traceToSimplify:i,leadingTerminalVias:r,trailingTerminalVias:s}=(t=\u003e{let e=0;for(;\"via\"===t.route[e]?.route_type;)e++;let n=t.route.length;for(;\"jumper\"===t.route[n-1]?.route_type;)n--;let o=n;for(;o\u003ee\u0026\u0026\"via\"===t.route[o-1]?.route_type;)o--;return{traceToSimplify:{...t,route:[...t.route.slice(e,o),...t.route.slice(n)]},leadingTerminalVias:t.route.slice(0,e),trailingTerminalVias:t.route.slice(o,n)}})(t),a=this.preparedInput.connMap.getNetConnectedToId(t.connection_name)??t.connection_name,c=void 0===o?void 0:((t,e)=\u003e{const n=[],o=[],i=[],r=((t,e)=\u003e{for(const e of t)if(\"wire\"===e.route_type||\"through_obstacle\"===e.route_type)return e.width;return e})(t.route,e.defaultTraceThickness);for(let s=0;s\u003ct.route.length;s++){const a=t.route[s];if(\"jumper\"===a.route_type){i.push(Het(a));continue}if(\"wire\"===a.route_type){$et(n,{x:a.x,y:a.y,z:ko(a.layer,e.layerCount),traceThickness:a.width,pcb_port_id:a.start_pcb_port_id??a.end_pcb_port_id});continue}const c=ko(a.from_layer,e.layerCount),l=ko(a.to_layer,e.layerCount),[d,h]=Xet({fromZ:c,toZ:l,previousZ:n.at(-1)?.z,nextZ:Yet(t.route,s,e.layerCount)});if(\"via\"===a.route_type){$et(n,{x:a.x,y:a.y,z:d,traceThickness:r}),$et(n,{x:a.x,y:a.y,z:h,traceThickness:r}),o.push({x:a.x,y:a.y});continue}const u=d===c,p=u?a.start:a.end,m=u?a.end:a.start;$et(n,{...p,z:d,traceThickness:a.width,toNextSegmentType:\"through_obstacle\",...a.circuitJsonMetadata?{toNextSegmentCircuitJsonMetadata:a.circuitJsonMetadata}:{}}),$et(n,{...m,z:h,traceThickness:a.width})}return{connectionName:t.pcb_trace_id,rootConnectionName:e.rootConnectionName,startPcbPortId:Wet(t.route,\"start\"),endPcbPortId:Wet(t.route,\"end\"),traceThickness:r,viaDiameter:Vet(t.route,e.defaultViaDiameter),route:n,vias:o,...i.length\u003e0?{jumpers:i}:{}}})(i,{layerCount:this.preparedInput.srj.layerCount,defaultTraceThickness:o,defaultViaDiameter:n.padDiameter,rootConnectionName:a}),l=c\u0026\u0026c.route.length\u003e=2?c:void 0;if(this.preparedInput.preparedTraces.push({originalTrace:t,mutableHdRoute:l,leadingTerminalVias:r,trailingTerminalVias:s,uniformTraceWidth:o,viaHoleDiameter:Get(t,n.holeDiameter)}),!l)return void this.preparedInput.immutableHdRoutes.push(...oQ(t,e,this.preparedInput.srj.layerCount,n.padDiameter,this.preparedInput.connMap));this.preparedInput.mutableHdRoutes.push(l),this.preparedInput.netByConnectionName.set(l.connectionName,a),this.preparedInput.colorMap[l.connectionName]=this.preparedInput.colorMap[a]??this.preparedInput.colorMap[t.connection_name]??\"#2563eb\";const d={...t,route:[...r,...s]};this.preparedInput.immutableHdRoutes.push(...oQ(d,e,this.preparedInput.srj.layerCount,n.padDiameter,this.preparedInput.connMap))}getOutput(){if(!this.solved)throw new Error(\"Cannot get prepared traces before preparation completes\");return this.preparedInput}},Zet=class extends kt{constructor(t){super(),this.inputProblem=t;const e=t.preparedInput,n=Yo(e.srj);this.traceSimplificationSolver=new vc({hdRoutes:e.mutableHdRoutes,otherHdRoutes:e.immutableHdRoutes,obstacles:e.srj.obstacles,connMap:e.connMap,colorMap:e.colorMap,outline:e.srj.outline,defaultViaDiameter:n.padDiameter,layerCount:e.srj.layerCount,minTraceToPadEdgeClearance:e.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:e.srj.minBoardEdgeClearance,netByConnectionName:e.netByConnectionName,enableCrossingViaReduction:e.options.enableCrossingViaReduction??!0,preserveRouteEndpoints:!0,useTraceWidthAwareClearance:!0,enableVertexShortcuts:e.options.enableVertexShortcuts??!0}),this.traceSimplificationSolver.MAX_SIMPLIFICATION_PIPELINE_LOOPS=e.options.iterations??2,this.activeSubSolver=this.traceSimplificationSolver,this.MAX_ITERATIONS=this.traceSimplificationSolver.MAX_ITERATIONS+1}inputProblem;traceSimplificationSolver;getSolverName(){return\"TraceSimplificationStageSolver\"}_step(){if(this.traceSimplificationSolver.step(),this.progress=this.traceSimplificationSolver.progress,this.stats={...this.traceSimplificationSolver.stats},this.traceSimplificationSolver.failed)return this.error=this.traceSimplificationSolver.error??\"Trace simplification failed\",this.failed=!0,void(this.activeSubSolver=null);this.traceSimplificationSolver.solved\u0026\u0026(this.progress=1,this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error(\"Cannot get simplified routes before cleanup completes\");return structuredClone(this.traceSimplificationSolver.simplifiedHdRoutes)}visualize(){return this.traceSimplificationSolver.visualize()}preview(){return this.traceSimplificationSolver.preview()}},qet=class extends kt{constructor(t){super(),this.inputProblem=t;const e=t.preparedInput;this.drcEngine=new s_(e.srj,{connMap:e.connMap,traceClearance:e.srj.minTraceToPadEdgeClearance??.1,viaClearance:.1}),this.MAX_ITERATIONS=3}inputProblem;drcEngine;phase=\"baseline\";baselineErrorCounts={};outputErrorCounts={};getSolverName(){return\"ValidateTraceSimplificationSolver\"}_step(){return\"baseline\"===this.phase?(this.baselineErrorCounts=this.evaluateErrorCounts(this.inputProblem.preparedInput.originalSrj),this.phase=\"output\",void(this.progress=1/3)):\"output\"===this.phase?(this.outputErrorCounts=this.evaluateErrorCounts(this.inputProblem.outputSrj),this.phase=\"compare\",void(this.progress=2/3)):(this.assertNoNewDrcErrors(),this.stats={baselineErrorCounts:this.baselineErrorCounts,outputErrorCounts:this.outputErrorCounts},this.progress=1,void(this.solved=!0))}evaluateErrorCounts(t){return(t=\u003e{const e={};for(const n of t.errors)e[n.type]=(e[n.type]??0)+1;return e})(this.drcEngine.evaluate(t.traces??[]))}assertNoNewDrcErrors(){const t=[...new Set([...Object.keys(this.baselineErrorCounts),...Object.keys(this.outputErrorCounts)])].filter(t=\u003e(this.outputErrorCounts[t]??0)\u003e(this.baselineErrorCounts[t]??0));if(0===t.length)return;const e=t.map(t=\u003e`${t}: ${this.baselineErrorCounts[t]??0} -\u003e ${this.outputErrorCounts[t]??0}`).join(\", \");throw new Error(`Pipeline 11 simplification introduced DRC errors (${e})`)}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error(\"Cannot get Pipeline 11 output before DRC validation\");return structuredClone(this.inputProblem.outputSrj)}},Jet=class extends Dt{prepareTraceSimplificationSolver;traceSimplificationStageSolver;applyTraceSimplificationSolver;validateTraceSimplificationSolver;pipelineDef=[Lt(\"prepareTraceSimplificationSolver\",Uet,t=\u003e[{inputSrj:t.inputProblem.inputSrj,options:t.inputProblem.options}]),Lt(\"traceSimplificationStageSolver\",Zet,t=\u003e[{preparedInput:t.prepareTraceSimplificationSolver.getOutput()}]),Lt(\"applyTraceSimplificationSolver\",jet,t=\u003e[{preparedInput:t.prepareTraceSimplificationSolver.getOutput(),simplifiedHdRoutes:t.traceSimplificationStageSolver.getOutput()}]),Lt(\"validateTraceSimplificationSolver\",qet,t=\u003e[{preparedInput:t.prepareTraceSimplificationSolver.getOutput(),outputSrj:t.applyTraceSimplificationSolver.getOutput()}])];constructor(t,e={}){if(void 0!==e.iterations\u0026\u0026(!Number.isInteger(e.iterations)||e.iterations\u003c1))throw new Error(\"Simplification iterations must be a positive integer\");super({inputSrj:t,options:{...e}}),this.MAX_ITERATIONS=1e8}getSolverName(){return\"AutoroutingPipelineSolver11_Simplification\"}getConstructorParams(){return[this.inputProblem.inputSrj,this.inputProblem.options]}getOutput(){if(!this.validateTraceSimplificationSolver?.solved)throw new Error(\"Pipeline 11 simplification has not solved yet\");return this.validateTraceSimplificationSolver.getOutput()}getOutputSimpleRouteJson(){return this.getOutput()}getOutputSimplifiedPcbTraces(){return structuredClone(this.getOutput().traces??[])}initialVisualize(){return Ho(this.inputProblem.inputSrj)}finalVisualize(){return Ho(this.getOutput())}},Ket=class extends kc{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e}srj;opts;MAX_SIZE_FOR_SINGLE_LAYER_NODES=2;isObstacleAssignable(t){return Boolean(t?.netIsAssignable)}getOverlappingAssignableObstacles(t){return this.getXYZOverlappingObstacles(t).filter(t=\u003ethis.isObstacleAssignable(t))}shouldNodeBeXYSubdivided(t){return!(t._depth\u003e=this.MAX_DEPTH)\u0026\u0026(!!t._containsTarget||(!(!t._containsObstacle||t._completelyInsideObstacle)||1===t.availableZ.length\u0026\u0026(t.width\u003ethis.MAX_SIZE_FOR_SINGLE_LAYER_NODES||t.height\u003ethis.MAX_SIZE_FOR_SINGLE_LAYER_NODES)))}shouldFilterNodeForObstacle(t){if(!t._containsObstacle)return!1;return!(this.getOverlappingAssignableObstacles(t).length\u003e0)\u0026\u0026(1!==t.availableZ.length||this.shouldFilterSingleLayerNodeForObstacle(t))}insertAssignableObstaclesAsNodes(){const t=this.srj.obstacles.filter(t=\u003ethis.isObstacleAssignable(t)),e=new Map;for(const n of t){const t=[];for(const e of this.finishedNodes){this.getXYZOverlappingObstacles(e).some(t=\u003et===n)\u0026\u0026t.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=\u003e!n.has(t));for(const n of t){const t=e.get(n)||[],o=n.layers\u0026\u0026n.layers.length\u003e0?Array.from(new Set(n.layers.map(t=\u003eko(t,this.srj.layerCount)))).sort((t,e)=\u003et-e):Array.from({length:this.srj.layerCount},(t,e)=\u003ethis.srj.layerCount-e-1);let i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=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,o=e.center.y-e.height/2,c=e.center.y+e.height/2;i=Math.min(i,t),r=Math.max(r,n),s=Math.min(s,o),a=Math.max(a,c)}const c=r-i,l=a-s,d=(i+r)/2,h=(s+a)/2;let u=!1;for(const t of this.srj.connections){for(const e of t.pointsToConnect)if(e.x\u003e=i\u0026\u0026e.x\u003c=r\u0026\u0026e.y\u003e=s\u0026\u0026e.y\u003c=a){u=!0;break}if(u)break}const p={capacityMeshNodeId:`assignable_via_${n.center.x}_${n.center.y}`,center:{x:d,y:h},width:c,height:l,layer:1===o.length?`z${o[0]}`:`z${o.join(\",\")}`,availableZ:o,_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=[],o=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),i=t.availableZ.length\u003e1\u0026\u0026!e;if(e)o.push(t);else{if(i){const e=this.getZSubdivisionChildNodes(t);for(const t of e)!t._containsTarget\u0026\u0026this.shouldFilterNodeForObstacle(t)||(this.shouldNodeBeXYSubdivided(t)?o.push(t):(t._containsObstacle=!1,n.push(t)));continue}this.shouldFilterNodeForObstacle(t)\u0026\u0026!t._containsTarget||n.push(t)}}this.unfinishedNodes.push(...o),this.finishedNodes.push(...n)}},Qet=.005,tnt=class extends si{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\u003e1?(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)=\u003et[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])=\u003et.capacityMeshNodeId),this.nextBatchNodeIds=[],this.batchHadModifications=!1}computeAdjacentNodeIdsForFirstBatch(t){const e=Math.max(...t.map(t=\u003eMath.max(...t.availableZ))),n=[];for(let o=0;o\u003c=e;o++)n.push(new hi(t.filter(t=\u003et.availableZ[0]===o)));for(const e of t){const t=[],o=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of o)n._containsTarget\u0026\u0026n._targetConnectionName!==e._targetConnectionName||e._containsTarget\u0026\u0026(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId\u0026\u0026li(e,n)\u0026\u0026t.push(n);e._adjacentNodeIds=t.map(t=\u003et.capacityMeshNodeId)}}getAdjacentSameLayerUnprocessedNodes(t){const e=[],n=Array.from(new Set((t._adjacentNodeIds??[]).map(t=\u003ethis.nodeMap.get(t)))).filter(e=\u003ee\u0026\u0026e.capacityMeshNodeId!==t.capacityMeshNodeId);n.sort((t,e)=\u003et.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=\u003ethis.nodeMap.get(t))),this.hasComputedAdjacentNodeIds=!0);let t=this.currentBatchNodeIds.pop();for(;t\u0026\u0026this.absorbedNodeIds.has(t);)t=this.currentBatchNodeIds.pop();if(!t)return this.batchHadModifications?(this.currentBatchNodeIds=this.nextBatchNodeIds.sort((t,e)=\u003e{const n=this.nodeMap.get(t),o=this.nodeMap.get(e);return n.width*n.height-o.width*o.height}),this.nextBatchNodeIds=[],void(this.batchHadModifications=!1)):(this.solved=!0,void this.newNodes.push(...this.nextBatchNodeIds.map(t=\u003ethis.nodeMap.get(t))));const e=this.nodeMap.get(t);let n=!1;const o=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===o.length)return void this.nextBatchNodeIds.push(t);const i=t=\u003e{for(const e of t)this.absorbedNodeIds.add(e.capacityMeshNodeId);e._adjacentNodeIds=Array.from(new Set([...e._adjacentNodeIds??[],...t.flatMap(t=\u003et._adjacentNodeIds??[])].filter(t=\u003et!==e.capacityMeshNodeId\u0026\u0026!this.absorbedNodeIds.has(t))))},r=o.filter(t=\u003et.center.x\u003ce.center.x\u0026\u0026Math.abs(t.center.y-e.center.y)\u003ce.height/2);if(r.length\u003e0){const{width:t,height:o}=r[0],s=r.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(r.reduce((t,e)=\u003et+e.height,0)-e.height)\u003cQet\u0026\u0026s\u0026\u0026(e.width+=t,e.center.x=e.center.x-t/2,i(r),n=!0)}const s=o.filter(t=\u003et.center.x\u003ee.center.x\u0026\u0026Math.abs(t.center.y-e.center.y)\u003ce.height/2);if(s.length\u003e0\u0026\u0026!n){const{width:t,height:o}=s[0],r=s.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(s.reduce((t,e)=\u003et+e.height,0)-e.height)\u003cQet\u0026\u0026r\u0026\u0026(e.width+=t,e.center.x=e.center.x+t/2,i(s),n=!0)}const a=o.filter(t=\u003et.center.y\u003ee.center.y\u0026\u0026Math.abs(t.center.x-e.center.x)\u003ce.width/2);if(a.length\u003e0\u0026\u0026!n){const{width:t,height:o}=a[0],r=a.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(a.reduce((t,e)=\u003et+e.width,0)-e.width)\u003cQet\u0026\u0026r\u0026\u0026(e.height+=o,e.center.y=e.center.y+o/2,i(a),n=!0)}const c=o.filter(t=\u003et.center.y\u003ce.center.y\u0026\u0026Math.abs(t.center.x-e.center.x)\u003ce.width/2);if(c.length\u003e0\u0026\u0026!n){const{width:t,height:o}=c[0],r=c.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(c.reduce((t,e)=\u003et+e.width,0)-e.width)\u003cQet\u0026\u0026r\u0026\u0026(e.height+=o,e.center.y=e.center.y-o/2,i(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(Dc(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e\u0026\u0026(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const o of this.currentBatchNodeIds){const i=this.nodeMap.get(o);if(!this.absorbedNodeIds.has(o)\u0026\u0026i){const r=Dc(i,{rectMargin:.01});o===e?r.stroke=\"rgba(0, 255, 0, 0.8)\":n?.some(t=\u003et.capacityMeshNodeId===o)?r.stroke=\"rgba(128, 0, 128, 0.8)\":r.stroke=\"rgba(255, 165, 0, 0.8)\",r.layer=`z${i.availableZ.join(\",\")}`,r.label=`${r.label}\\n(unprocessed)`,t.rects.push(r)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)\u0026\u0026n){const e=Dc(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}},ent=class extends si{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,o=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;const s=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,l=t.center.y-t.height/2,d=t.center.y+t.height/2;n=Math.min(n,e),o=Math.max(o,c),i=Math.min(i,l),r=Math.max(r,d);for(const e of t.availableZ)s.add(e);t._containsTarget\u0026\u0026(a=!0)}const c=o-n,l=r-i,d=(n+o)/2,h=(i+r)/2,u=Array.from(s).sort((t,e)=\u003et-e),p={capacityMeshNodeId:`merged_via_${t.center.x}_${t.center.y}`,center:{x:d,y:h},width:c,height:l,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=Dc(e);e._assignedViaObstacle\u0026\u0026(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=Dc(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}},nnt=class extends si{constructor(t){const{simpleRouteJson:e,nodes:n,edges:o,colorMap:i,MAX_ITERATIONS:r=1e6,hyperParameters:s={}}=t;super(),this.inputParams=t,this.hyperParameters=s,this.MAX_ITERATIONS=r,this.simpleRouteJson=e,this.nodes=n,this.edges=o,this.colorMap=i??{},this.nodeMap=new Map(this.nodes.map(t=\u003e[t.capacityMeshNodeId,t])),this.nodeEdgeMap=ai(this.edges);const a=this.nodes.filter(t=\u003et._containsTarget);this.unprocessedConnectionPairs=Xi(this.simpleRouteJson.connections.map(t=\u003e{const[e,n]=t.pointsToConnect;return{start:a.find(t=\u003exe(t.center,e)\u003ct.width/2),end:a.find(t=\u003exe(t.center,n)\u003ct.width/2),connection:t}}),this.hyperParameters.SHUFFLE_SEED??0),this.viaNodes=this.nodes.filter(t=\u003et.availableZ.length\u003e1)}inputParams;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=\u003e!t._completelyInsideObstacle\u0026\u0026!t._containsObstacle).filter(t=\u003e!this.usedNodeMap.has(t.capacityMeshNodeId));if(e.length\u003e0){const n=e.reduce((e,n)=\u003e{const o=this._dist(e,t.start);return this._dist(n,t.start)\u003co?n:e});this.closestViaForConnectionStartMap.set(t,n);const o=e.reduce((e,n)=\u003e{const o=this._dist(e,t.end);return this._dist(n,t.end)\u003co?n:e});this.closestViaForConnectionEndMap.set(t,o)}}}_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\u0026\u0026!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\u0026\u0026(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\u0026\u00260===this.visitedNodes.size){const t=this._dist(e,n),o={prevCandidate:null,node:e,g:0,h:t,f:this.GREEDY_MULTIPLIER*t};this.queuedCandidateNodes.push(o)}let o;for(this.queuedCandidateNodes.sort((t,e)=\u003et.f-e.f);this.queuedCandidateNodes.length\u0026\u0026!o;){const t=this.queuedCandidateNodes.shift();this.visitedNodes.has(t.node.capacityMeshNodeId)||(o=t)}if(!o)return this.failed=!0,void(this.error=\"No viable candidates left\");if(this.visitedNodes.add(o.node.capacityMeshNodeId),o.node.capacityMeshNodeId===n.capacityMeshNodeId){const e=[];let n=o;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 i=this.getNeighbors(o.node);for(const t of i){const e=t.capacityMeshNodeId;if(this.visitedNodes.has(e))continue;const i=this.computeG(o,t,n),r=this.computeH(o,t,n),s=i+this.GREEDY_MULTIPLIER*r,a=this.queuedCandidateNodes.findIndex(t=\u003et.node.capacityMeshNodeId===e);if(a\u003e=0){if(this.queuedCandidateNodes[a].g\u003c=i)continue;this.queuedCandidateNodes.splice(a,1)}this.queuedCandidateNodes.push({prevCandidate:o,node:t,g:i,h:r,f:s})}}getNeighbors(t){const e=new Set,n=this.nodeEdgeMap.get(t.capacityMeshNodeId)??[];for(const o of n){const[n,i]=o.nodeIds,r=n===t.capacityMeshNodeId?i:n,s=this.nodeMap.get(r);s\u0026\u0026e.add(s)}const o=this.activeSubpath?.layer;return Array.from(e).filter(t=\u003e!(t.capacityMeshNodeId!==this.activeSubpath?.end.capacityMeshNodeId)||!t._containsObstacle\u0026\u0026(!t._containsTarget\u0026\u0026(!this.usedNodeMap.has(t.capacityMeshNodeId)\u0026\u0026!(void 0!==o\u0026\u0026!t.availableZ.includes(o)))))}clearCandidateNodes(){this.queuedCandidateNodes=[],this.visitedNodes=new Set}computeG(t,e,n){const o=this._dist(t.node,e);return t.g+o}computeH(t,e,n){return this._dist(e,n)}createSolvedRoute(t,e){const n=[];for(let e=0;e\u003ct.length;e++){const o=t[e];o.path?0===e?n.push(...o.path):n.push(...o.path.slice(1)):(0===e\u0026\u0026n.push(o.start),e===t.length-1\u0026\u0026n.push(o.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,$i(e.reduce((t,e)=\u003et+16807*e%2147483647,0))()\u003cn))return[{start:t.start,end:t.end,solved:!1,layer:t.start.availableZ[0]??0}];const o=this.getClosestVia(t.start),i=this.getFarVia(o,t.end),r=t.start.availableZ[0]??0,s=t.end.availableZ[0]??0,a=[];return a.push({start:t.start,end:o,solved:!1,layer:r}),r===s?(a.push({start:o,end:i,solved:!1,layer:0===r?1:0}),a.push({start:i,end:t.end,solved:!1,layer:s})):a.push({start:o,end:t.end,solved:!1,layer:s}),a}getClosestVia(t){if(0===this.viaNodes.length)return t;const e=new Set;for(const[t,n]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair\u0026\u0026e.add(n.capacityMeshNodeId);for(const[t,n]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair\u0026\u0026e.add(n.capacityMeshNodeId);const n=this.viaNodes.filter(t=\u003e!t._completelyInsideObstacle\u0026\u0026!t._containsObstacle).filter(t=\u003e!this.usedNodeMap.has(t.capacityMeshNodeId)).filter(t=\u003e!e.has(t.capacityMeshNodeId));if(0===n.length){const e=this.viaNodes.filter(t=\u003e!t._completelyInsideObstacle\u0026\u0026!t._containsObstacle).filter(t=\u003e!this.usedNodeMap.has(t.capacityMeshNodeId));return 0===e.length?t:(e.sort((e,n)=\u003ethis._dist(e,t)-this._dist(n,t)),e[0])}n.sort((e,n)=\u003ethis._dist(e,t)-this._dist(n,t));const o=this.hyperParameters.MAX_CLOSEST_VIA_SKIP??0;if(o\u003e0\u0026\u0026n.length\u003e1){const t=$i((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length),e=Math.floor(t()*(o+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,o=new Set;for(const[t,e]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair\u0026\u0026o.add(e.capacityMeshNodeId);for(const[t,e]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair\u0026\u0026o.add(e.capacityMeshNodeId);const i=this.viaNodes.filter(e=\u003e!this.usedNodeMap.has(e.capacityMeshNodeId)\u0026\u0026e.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026!e._completelyInsideObstacle\u0026\u0026!e._containsObstacle\u0026\u0026!o.has(e.capacityMeshNodeId)\u0026\u0026this._dist(e,t)\u003e=n);if(0===i.length){const o=this.viaNodes.filter(e=\u003ee.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026!e._completelyInsideObstacle\u0026\u0026!e._containsObstacle\u0026\u0026!this.usedNodeMap.has(e.capacityMeshNodeId)\u0026\u0026this._dist(e,t)\u003e=n).sort((t,n)=\u003ethis._dist(t,e)-this._dist(n,e));if(o.length\u003e0)return o[0];return this.viaNodes.filter(e=\u003ee.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026!e._completelyInsideObstacle\u0026\u0026!e._containsObstacle\u0026\u0026!this.usedNodeMap.has(e.capacityMeshNodeId)).sort((t,n)=\u003ethis._dist(t,e)-this._dist(n,e))[0]??t}i.sort((t,n)=\u003ethis._dist(t,e)-this._dist(n,e));const r=this.hyperParameters.MAX_FURTHEST_VIA_SKIP??0;if(r\u003e0\u0026\u0026i.length\u003e1){const t=$i((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length+1e3),e=Math.floor(t()*(r+1));return i[Math.min(e,i.length-1)]}return i[0]}getCapacityPaths(){const t=[];for(const e of this.solvedRoutes){const n=e.path;n\u0026\u0026n.length\u003e0\u0026\u0026t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,nodeIds:n.map(t=\u003et.capacityMeshNodeId)})}return t}visualize(){const t={lines:[],points:[],rects:[],circles:[]},e=t=\u003e!!t\u0026\u0026\"number\"==typeof t.x\u0026\u0026\"number\"==typeof t.y\u0026\u0026!Number.isNaN(t.x)\u0026\u0026!Number.isNaN(t.y)\u0026\u0026Number.isFinite(t.x)\u0026\u0026Number.isFinite(t.y),n=t=\u003e\"number\"==typeof t\u0026\u0026!Number.isNaN(t)\u0026\u0026Number.isFinite(t);for(const o of this.nodes){const i=this.queuedCandidateNodes.some(t=\u003et.node.capacityMeshNodeId===o.capacityMeshNodeId),r=this.queuedCandidateNodes.find(t=\u003et.node.capacityMeshNodeId===o.capacityMeshNodeId);if(e(o.center)\u0026\u0026n(o.width)\u0026\u0026n(o.height)){const e=Dc(o,{rectMargin:.025,zOffset:.01});t.rects.push({...e,fill:i?\"rgba(255, 128, 255, 0.5)\":o._containsTarget?\"rgba(0, 150, 255, 0.15)\":o._containsObstacle?\"rgba(255, 0, 0, 0.1)\":\"rgba(200, 200, 200, 0.05)\",label:[`ID: ${o.capacityMeshNodeId}`,`Size: ${o.width.toFixed(2)}x${o.height.toFixed(2)}`,`Z: ${o.availableZ.join(\", \")}`,r?`g: ${r.g.toFixed(2)}`:\"\",r?`h: ${r.h.toFixed(2)}`:\"\",r?`f: ${r.f.toFixed(2)}`:\"\",o._containsTarget?\"TARGET\":\"\",o._containsObstacle?\"OBSTACLE\":\"\"].filter(t=\u003et).join(\"\\n\")})}}for(const n of this.edges){const[o,i]=n.nodeIds,r=this.nodeMap.get(o),s=this.nodeMap.get(i);r?.center\u0026\u0026s?.center\u0026\u0026e(r.center)\u0026\u0026e(s.center)\u0026\u0026t.lines.push({points:[r.center,s.center],strokeColor:\"rgba(150, 150, 150, 0.2)\"})}for(let n=0;n\u003cthis.solvedRoutes.length;n++){const o=this.solvedRoutes[n],i=o.path,r=\"blue\";for(let o=0;o\u003ci.length-1;o++){const s=i[o],a=i[o+1];if(s?.center\u0026\u0026a?.center\u0026\u0026e(s.center)\u0026\u0026e(a.center)){const e=s.availableZ.includes(1)\u0026\u0026a.availableZ.includes(1),o=n%5*.02;t.lines.push({points:[{x:s.center.x+o,y:s.center.y+o},{x:a.center.x+o,y:a.center.y+o}],strokeColor:r,strokeDash:e?\"5 5\":void 0})}}if(i.length\u003e0){const n=i[0],r=i[i.length-1];n?.center\u0026\u0026e(n.center)\u0026\u0026t.points.push({x:n.center.x,y:n.center.y,label:`START: ${o.connection.name}`}),r?.center\u0026\u0026e(r.center)\u0026\u0026t.points.push({x:r.center.x,y:r.center.y,label:`END: ${o.connection.name}`})}}if(this.solvedSubpaths)for(let n=0;n\u003cthis.solvedSubpaths.length;n++){const o=this.solvedSubpaths[n];if(o.path\u0026\u0026o.path.length\u003e1)for(let n=0;n\u003co.path.length-1;n++){const i=o.path[n],r=o.path[n+1];i?.center\u0026\u0026r?.center\u0026\u0026e(i.center)\u0026\u0026e(r.center)\u0026\u0026t.lines.push({points:[i.center,r.center],strokeColor:\"green\",strokeDash:1===o.layer?\"3 3\":void 0})}}if(this.activeSubpath){const n=this.activeSubpath.start?.center,o=this.activeSubpath.end?.center;n\u0026\u0026o\u0026\u0026e(n)\u0026\u0026e(o)\u0026\u0026(t.lines.push({points:[n,o],strokeColor:\"orange\",strokeDash:\"5 5\"}),t.points.push({x:n.x,y:n.y,label:\"ACTIVE START\"}),t.points.push({x:o.x,y:o.y,label:\"ACTIVE END\"}))}const o=this.queuedCandidateNodes.slice(0,10).sort((t,e)=\u003et.f-e.f);for(let n=0;n\u003co.length;n++){const i=.6*(1-n/10),r=[];let s=o[n];for(;s;)r.push(s.node),s=s.prevCandidate;if(r.reverse(),r.length\u003e1){const n=r.map(t=\u003et.center).filter(t=\u003ee(t));n.length\u003e1\u0026\u0026t.lines.push({points:n,strokeColor:To(\"purple\",1-i),strokeDash:1===this.activeSubpath?.layer?\"4 2\":void 0})}}if(this.activeConnectionPair){const n=this.activeConnectionPair.start?.center,o=this.activeConnectionPair.end?.center;n\u0026\u0026o\u0026\u0026e(n)\u0026\u0026e(o)\u0026\u0026t.lines.push({points:[n,o],strokeColor:\"cyan\",strokeDash:\"20 5\"})}if(this.ogUnprocessedSubpaths\u0026\u00263===this.ogUnprocessedSubpaths.length){const[,o]=this.ogUnprocessedSubpaths;if(o.start?.center\u0026\u0026e(o.start.center)){const e=Math.max(o.start.width||0,o.start.height||0);n(e)\u0026\u0026e\u003e0\u0026\u0026(t.circles.push({center:o.start.center,radius:e,stroke:\"blue\"}),t.points.push({x:o.start.center.x,y:o.start.center.y,label:\"DIRECTIVE VIA 1\"}))}if(o.end?.center\u0026\u0026e(o.end.center)){const e=Math.max(o.end.width||0,o.end.height||0);n(e)\u0026\u0026e\u003e0\u0026\u0026(t.circles.push({center:o.end.center,radius:e,stroke:\"purple\"}),t.points.push({x:o.end.center.x,y:o.end.center.y,label:\"DIRECTIVE VIA 2\"}))}}if(this.queuedCandidateNodes.length\u003e0)for(const n of this.queuedCandidateNodes){const o=n.node;o?.center\u0026\u0026e(o.center)\u0026\u0026t.circles.push({center:o.center,radius:.05,fill:\"rgba(255, 255, 0, 0.6)\",stroke:\"yellow\"})}if(this.visitedNodes.size\u003e0)for(const n of this.visitedNodes){const o=this.nodeMap.get(n);o?.center\u0026\u0026e(o.center)\u0026\u0026t.circles.push({center:o.center,radius:.08,fill:\"rgba(128, 128, 128, 0.5)\",stroke:\"gray\"})}return t}},ont=class extends ys{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,o=e\u003e0?n/e:0;return t.iterations/t.MAX_ITERATIONS+(1-o)}computeH(t){const e=t.unprocessedConnectionPairs.length+t.solvedRoutes.length+(t.activeConnectionPair?1:0),n=t.solvedRoutes.length;return e\u003e0?1-n/e:0}generateSolver(t){return new nnt({...this.constructorParams,hyperParameters:{...this.constructorParams.hyperParameters,...t}})}};function int(t){const e=new Map;for(const n of t)e.set(n.capacityMeshNodeId,n);return e}function rnt(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}var snt=class extends si{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=int(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\u0026\u0026e.offBoardConnectsTo.length\u003e0\u0026\u0026this.assignableNodes.push(t)}}initializePendingEdges(){const t=new Map;for(const e of this.assignableNodes){const n=e._assignedViaObstacle;if(n?.offBoardConnectsTo)for(const o of n.offBoardConnectsTo)t.has(o)||t.set(o,[]),t.get(o).push(e)}this.pendingEdges=[];for(const[e,n]of t)if(n.length\u003e1)for(let t=0;t\u003cn.length;t++)for(let o=t+1;o\u003cn.length;o++)this.pendingEdges.push({node1:n[t],node2:n[o],netName:e})}_step(){switch(this.animationState){case\"showing_nodes\":if(this.assignableNodes.length\u003e0){const t=this.assignableNodes.shift();this.shownNodes.push(t)}else this.animationState=\"showing_edges\";break;case\"showing_edges\":if(this.pendingEdges.length\u003e0){const{node1:t,node2:e,netName:n}=this.pendingEdges.shift(),o=this.createOffboardEdge(t,e,n);this.enhancedEdges.push(o),this.createdEdges.push(o)}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=[],o=new Set(this.shownNodes.map(t=\u003et.capacityMeshNodeId));for(const e of this.capacityEdges){if(e.isOffboardEdge)continue;if(o.has(e.nodeIds[0])||o.has(e.nodeIds[1])){const n=this.nodeMap.get(e.nodeIds[0]),o=this.nodeMap.get(e.nodeIds[1]);n\u0026\u0026o\u0026\u0026t.push({points:[n.center,o.center],strokeColor:\"rgba(0, 200, 0, 0.5)\",strokeWidth:.05})}}for(let t=0;t\u003cthis.shownNodes.length;t++){const o=this.shownNodes[t],i=o._assignedViaObstacle,r=t===this.shownNodes.length-1\u0026\u0026\"showing_nodes\"===this.animationState;n.push({center:o.center,width:o.width,height:o.height,fill:r?\"rgba(255, 165, 0, 0.5)\":\"rgba(173, 216, 230, 0.5)\",stroke:r?\"orange\":\"blue\",strokeWidth:r?.15:.1}),e.push({x:o.center.x,y:o.center.y,color:r?\"orange\":\"blue\",label:`${r?\"NEW: \":\"\"}${o.capacityMeshNodeId}\\n${i?.offBoardConnectsTo?.join(\", \")||\"\"}`})}for(let n=0;n\u003cthis.createdEdges.length;n++){const o=this.createdEdges[n],i=n===this.createdEdges.length-1\u0026\u0026\"showing_edges\"===this.animationState,r=this.nodeMap.get(o.nodeIds[0]),s=this.nodeMap.get(o.nodeIds[1]);if(r\u0026\u0026s){t.push({points:[r.center,s.center],strokeColor:i?\"red\":\"orange\",strokeWidth:i?.2:.1,strokeDasharray:\"0.3,0.15\"});const n=rnt(r.center,s.center);e.push({x:n.x,y:n.y,color:i?\"red\":\"orange\",label:`${i?\"NEW: \":\"\"}⚡ ${o.offboardNetName}`})}}let i=\"Offboard Capacity Node Solver\";switch(this.animationState){case\"showing_nodes\":i+=` - Showing nodes (${this.shownNodes.length}/${this.shownNodes.length+this.assignableNodes.length})`;break;case\"showing_edges\":i+=` - Creating edges (${this.createdEdges.length}/${this.createdEdges.length+this.pendingEdges.length})`;break;case\"done\":i+=` - Done (${this.shownNodes.length} nodes, ${this.createdEdges.length} edges)`}return{lines:t,points:e,rects:n,title:i}}getVirtualOffboardNodes(){return[]}getOffboardEdges(){return this.enhancedEdges.filter(t=\u003et.isOffboardEdge)}},ant=class extends si{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:o}){super(),this.inputPaths=[...t],this.capacityEdges=e,this.originalConnections=o,this.nodeMap=int(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=\u003et.isFragmentedPath)?this.animationState=\"showing_fragment\":this.fragmentedPaths.push(...this.currentFragments);break;case\"showing_fragment\":if(this.currentFragmentIndex\u003cthis.currentFragments.length){const t=this.currentFragments[this.currentFragmentIndex];this.fragmentedPaths.push(t),this.currentFragmentIndex++}else this.currentPath\u0026\u0026(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=\u003ee.name===t.connectionName);if(n)for(let t=0;t\u003ce.length;t++){const o=e[t];if(!o.isFragmentedPath)continue;const i=n.pointsToConnect.filter(t=\u003e{for(const e of o.nodeIds){const n=this.nodeMap.get(e);if(n\u0026\u0026Xj(t,n))return!0}return!1}),r=0===t,s=r?o.nodeIds[o.nodeIds.length-1]:o.nodeIds[0],a=this.nodeMap.get(s);if(i.length\u003e0\u0026\u0026a){const t=i[0],e={x:a.center.x,y:a.center.y,layer:bo(t)},s=r?[...i,e]:[e,...i];this.fragmentedConnections.push({name:o.connectionName,pointsToConnect:s,__netConnectionName:n.__netConnectionName,__rootConnectionNames:n.__rootConnectionNames})}}}splitPath(t){const{nodeIds:e}=t;if(e.length\u003c2)return[t];const n=[];for(let t=0;t\u003ce.length-1;t++){const o=this.capacityEdges.find(n=\u003en.nodeIds[0]===e[t]\u0026\u0026n.nodeIds[1]===e[t+1]||n.nodeIds[0]===e[t+1]\u0026\u0026n.nodeIds[1]===e[t]);o\u0026\u0026o.isOffboardEdge\u0026\u0026n.push(t)}if(0===n.length)return[t];const o=[];let i=0,r=0;for(const s of n){const n=e.slice(i,s+1);if(n.length\u003e=1){const e=this.nextFragmentId++;o.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${r++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}i=s+1}if(i\u003ce.length){const n=e.slice(i);if(n.length\u003e=1){const e=this.nextFragmentId++;o.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${r++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}}return o.length\u003e0?o:[t]}getFragmentedPaths(){return this.fragmentedPaths}getFragmentedConnections(){return this.fragmentedConnections}getFragmentedOriginalConnectionNames(){return this.fragmentedOriginalConnectionNames}visualize(){const t=[],e=[],n=[];if(\"showing_original_path\"===this.animationState\u0026\u0026this.currentPath\u0026\u0026this.drawPath({path:this.currentPath,color:\"gray\",lines:t,points:e,rects:n,labelPrefix:\"Original: \"}),this.fragmentedPaths.forEach((o,i)=\u003e{if(o.isFragmentedPath){const r=i%2==0?\"blue\":\"red\";this.drawPath({path:o,color:r,lines:t,points:e,rects:n,labelPrefix:`Frag ${i}: `})}else this.drawPath({path:o,color:\"green\",lines:t,points:e,rects:n,labelPrefix:\"\"})}),\"showing_fragment\"===this.animationState\u0026\u0026this.currentFragmentIndex\u003e0){const o=this.fragmentedPaths.length-1;if(o\u003e=0){const i=this.fragmentedPaths[o];i.isFragmentedPath\u0026\u0026this.drawPath({path:i,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]),o=this.nodeMap.get(e.nodeIds[1]);n\u0026\u0026o\u0026\u0026t.push({points:[n.center,o.center],strokeColor:\"orange\",strokeWidth:.15,strokeDasharray:\"0.3,0.15\"})}let o=\"Offboard Path Fragment Solver\";return\"showing_original_path\"===this.animationState?o+=\" - Analyzing path...\":\"showing_fragment\"===this.animationState?o+=` - Fragment ${this.currentFragmentIndex}/${this.currentFragments.length}`:o+=` - Done (${this.fragmentedPaths.filter(t=\u003et.isFragmentedPath).length} fragments)`,{lines:t,points:e,rects:n,title:o}}drawPath(t){const{path:e,color:n,lines:o,points:i,rects:r,labelPrefix:s}=t,a=[];for(let t=0;t\u003ce.nodeIds.length;t++){const o=e.nodeIds[t],c=this.nodeMap.get(o);c\u0026\u0026(a.push(c.center),r.push({center:c.center,width:.8*c.width,height:.8*c.height,stroke:n,strokeWidth:.05,fill:`${n}33`}),0!==t\u0026\u0026t!==e.nodeIds.length-1||i.push({x:c.center.x,y:c.center.y,color:n,label:`${s}${e.connectionName}\\n${o}`}))}a.length\u003e1\u0026\u0026o.push({points:a,strokeColor:n,strokeWidth:.1})}};function cnt(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var lnt=class extends si{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,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),r=n.targetMinCapacity??.5;n.capacityDepth=$s(i,r)}this.connMap=ii(t),this.colorMap=wo(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;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=[cnt(\"netToPointPairsSolver\",ma,t=\u003e[t.srj,t.colorMap,ri(t.srj)],{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,this.connMap),t.connMap=ii(t.srjWithPointPairs)}}),cnt(\"nodeSolver\",Ket,t=\u003e[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=\u003e{t.capacityNodes=t.nodeSolver?.finishedNodes}}),cnt(\"mergeAssignableViaNodes\",ent,t=\u003e[t.nodeSolver?.finishedNodes],{onSolved:t=\u003e{t.capacityNodes=t.mergeAssignableViaNodes?.newNodes}}),cnt(\"singleLayerNodeMerger\",tnt,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),cnt(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),cnt(\"offboardCapacityNodeSolver\",snt,t=\u003e[{capacityNodes:t.capacityNodes,capacityEdges:t.capacityEdges||[]}],{onSolved:t=\u003e{t.capacityEdges=t.offboardCapacityNodeSolver?.enhancedEdges||t.capacityEdges}}),cnt(\"deadEndSolver\",Qc,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges}],{onSolved:t=\u003e{const e=t.deadEndSolver?.removedNodeIds;t.capacityNodes=t.capacityNodes.filter(t=\u003e!e.has(t.capacityMeshNodeId)),t.capacityEdges=t.capacityEdges.filter(t=\u003et.nodeIds.every(t=\u003e!e.has(t)))}}),cnt(\"initialPathingHyperSolver\",ont,t=\u003e[{simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,hyperParameters:{MAX_CAPACITY_FACTOR:1}}],{onSolved:t=\u003e{const e=t.initialPathingHyperSolver?.winningSolver;e\u0026\u0026(t.initialPathingSolver=e)}}),cnt(\"offboardPathFragmentSolver\",ant,t=\u003e[{capacityPaths:t.initialPathingSolver?.getCapacityPaths()||[],capacityEdges:t.capacityEdges||[],capacityNodes:t.capacityNodes||[],connections:t.srjWithPointPairs?.connections||[]}],{onSolved:t=\u003e{const e=t.offboardPathFragmentSolver;if(!e)return;const n=e.getFragmentedPaths();for(const e of n)if(e.isFragmentedPath\u0026\u0026e.mstPairConnectionName){const n=t.colorMap[e.mstPairConnectionName];n\u0026\u0026!t.colorMap[e.connectionName]\u0026\u0026(t.colorMap[e.connectionName]=n)}const o=e.getFragmentedOriginalConnectionNames(),i=e.getFragmentedConnections();o.size\u003e0\u0026\u0026t.srjWithPointPairs\u0026\u0026(t.srjWithPointPairs={...t.srjWithPointPairs,connections:[...t.srjWithPointPairs.connections.filter(t=\u003e!o.has(t.name)),...i]},t.connMap=ii(t.srjWithPointPairs))}}),cnt(\"edgeToPortSegmentSolver\",Nc,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.offboardPathFragmentSolver?.getFragmentedPaths()||t.initialPathingSolver?.getCapacityPaths()||[],colorMap:t.colorMap}]),cnt(\"segmentToPointSolver\",Lc,t=\u003e{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments\u0026\u0026t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=\u003e{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),cnt(\"unravelMultiSectionSolver\",gl,t=\u003e[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),cnt(\"highDensityRouteSolver\",zs,t=\u003e[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap}]),cnt(\"highDensityStitchSolver\",Ca,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),cnt(\"uselessViaRemovalSolver1\",Xa,t=\u003e[{unsimplifiedHdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount,connMap:t.connMap}]),cnt(\"multiSimplifiedPathSolver1\",Za,t=\u003e[{unsimplifiedHdRoutes:t.uselessViaRemovalSolver1?.getOptimizedHdRoutes()||t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline}]),cnt(\"uselessViaRemovalSolver2\",Xa,t=\u003e[{unsimplifiedHdRoutes:t.multiSimplifiedPathSolver1.simplifiedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount,connMap:t.connMap}]),cnt(\"multiSimplifiedPathSolver2\",Za,t=\u003e[{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\u0026\u0026(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\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),o=this.mergeAssignableViaNodes?.visualize(),i=this.singleLayerNodeMerger?.visualize(),r=this.strawSolver?.visualize(),s=this.edgeSolver?.visualize(),a=(this.offboardCapacityNodeSolver?.visualize(),this.deadEndSolver?.visualize()),c=this.initialPathingSolver?.visualize(),l=this.offboardPathFragmentSolver?.visualize(),d=this.pathingOptimizer?.visualize(),h=this.edgeToPortSegmentSolver?.visualize(),u=this.segmentToPointSolver?.visualize(),p=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),m=this.highDensityRouteSolver?.visualize(),g=this.highDensityStitchSolver?.visualize(),f=this.uselessViaRemovalSolver1?.visualize(),y=this.uselessViaRemovalSolver2?.visualize(),_=this.multiSimplifiedPathSolver1?.visualize(),b=this.multiSimplifiedPathSolver2?.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\u0026\u0026x.length\u003e=2){const t=x.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const S=Oo(this.srj),I={points:[...this.srj.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,this.srj.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(this.srj.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,this.srj.layerCount),label:S(t)}))],lines:v},C=[I,t,e,n,o,i,r,s,a,c,l,d,h,u,p,m?pi(I,m):null,g,f,_,y,b,this.solved?pi({lines:v},Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...C)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}if(this.pathingOptimizer){const t=[];for(const e of this.pathingOptimizer.connectionsWithNodes)e.path\u0026\u0026t.push({points:e.path.map(t=\u003e({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 o of n){const n=o.__netConnectionName,i=o.__rootConnectionNames?.[0],r=e.filter(t=\u003et.connectionName===o.name);for(let e=0;e\u003cr.length;e++){const s=r[e],a={type:\"pcb_trace\",pcb_trace_id:`${o.name}_${e}`,connection_name:n??i??o.name,route:Mo(s,this.srj.layerCount)};t.push(a)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},dnt=1e-9,hnt=t=\u003e(t=\u003e\"wire\"===t.route_type)(t)||(t=\u003e\"via\"===t.route_type)(t)?t:(t=\u003e\"through_obstacle\"===t.route_type)(t)\u0026\u0026Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y)\u003c=dnt?{route_type:t.route_type,x:t.start.x,y:t.start.y,from_layer:t.from_layer,to_layer:t.to_layer,width:t.width}:null,unt=(t,e)=\u003et.layer??e.layer??t.to_layer??e.from_layer??t.from_layer??e.to_layer??\"top\",pnt=(t,e,n)=\u003et.width??e.width??n,mnt=(t,e,n,o,i)=\u003e({x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n,layer:o,width:i}),gnt=(t,e)=\u003e({...t,x:Math.abs(t.x-e.minX)\u003c1e-6?e.minX:Math.abs(t.x-e.maxX)\u003c1e-6?e.maxX:t.x,y:Math.abs(t.y-e.minY)\u003c1e-6?e.minY:Math.abs(t.y-e.maxY)\u003c1e-6?e.maxY:t.y}),fnt=({x:t,y:e,layer:n})=\u003e({x:t,y:e,layer:n}),ynt=({x:t,y:e,layer:n,width:o})=\u003e({route_type:\"wire\",x:t,y:e,layer:n,width:o}),_nt=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;let r=0,s=1;const a=(t,e)=\u003e{if(Math.abs(t)\u003cdnt)return e\u003e=0;const n=e/t;if(t\u003c0){if(n\u003es)return!1;n\u003er\u0026\u0026(r=n)}else{if(n\u003cr)return!1;n\u003cs\u0026\u0026(s=n)}return!0};return a(-o,t.x-n.minX)\u0026\u0026a(o,n.maxX-t.x)\u0026\u0026a(-i,t.y-n.minY)\u0026\u0026a(i,n.maxY-t.y)?{startT:r,endT:s}:null},bnt=(t,e)=\u003et.x\u003e=e.minX-1e-6\u0026\u0026t.x\u003c=e.maxX+1e-6\u0026\u0026t.y\u003e=e.minY-1e-6\u0026\u0026t.y\u003c=e.maxY+1e-6\u0026\u0026(Math.abs(t.x-e.minX)\u003c=1e-6||Math.abs(t.x-e.maxX)\u003c=1e-6||Math.abs(t.y-e.minY)\u003c=1e-6||Math.abs(t.y-e.maxY)\u003c=1e-6),xnt=(t,e,n,o,i)=\u003e{var r,s;(r=o,s=i,Math.hypot(r.x-s.x,r.y-s.y)\u003c=dnt)||t.push({type:\"pcb_trace\",pcb_trace_id:`${e.pcb_trace_id}_keep_${n}`,connection_name:e.connection_name,route:[ynt(o),ynt(i)]})},vnt=({obstacleId:t,start:e,end:n,layer:o,width:i})=\u003e{const r=n.x-e.x,s=n.y-e.y,a=Math.hypot(r,s);return a\u003ei+dnt?null:{obstacleId:t,type:\"rect\",layers:[o],center:{x:(e.x+n.x)/2,y:(e.y+n.y)/2},width:a,height:i,ccwRotationDegrees:180*Math.atan2(s,r)/Math.PI,connectedTo:[]}},Snt=({connection:t,point:e,endpointIndex:n})=\u003e({obstacleId:`${t.name}_route_endpoint_${n}`,type:\"rect\",layers:[e.layer],center:{x:e.x,y:e.y},width:e.width,height:e.width,connectedTo:[t.name,t.__rootConnectionNames?.[0]??t.name]}),Int=({trace:t,ripIndex:e,start:n,end:o,region:i,allowInteriorStart:r,allowInteriorEnd:s})=\u003e{if(!r\u0026\u0026!bnt(n,i)||!s\u0026\u0026!bnt(o,i))return null;const a=(({trace:t,ripIndex:e,start:n,end:o})=\u003e({name:`${t.connection_name}_reroute_${t.pcb_trace_id}_${e}`,__rootConnectionNames:[t.connection_name],pointsToConnect:[fnt(n),fnt(o)]}))({trace:t,ripIndex:e,start:n,end:o});return{connection:a,endpointObstacles:[Snt({connection:a,point:n,endpointIndex:0}),Snt({connection:a,point:o,endpointIndex:1})]}},Cnt=(t,e,n)=\u003e{const o=[],i=[],r=[],s=[];let a=null,c=!1,l=0,d=!1;for(let h=0;h\u003ct.route.length-1;h++){const u=hnt(t.route[h]),p=hnt(t.route[h+1]);if(!u||!p)return null;const m=unt(u,p),g=pnt(u,p,n),f=_nt(u,p,e),y=mnt(u,p,0,m,g),_=mnt(u,p,1,m,g),b=0===h;if(!f){xnt(o,t,l++,y,_);continue}if(d=!0,f.startT\u003ednt){const e=mnt(u,p,f.startT,m,g),n=vnt({obstacleId:`${t.pcb_trace_id}_keep_${l}_bounds`,start:y,end:e,layer:m,width:g});n\u0026\u0026s.push(n),xnt(o,t,l++,y,e)}const x=mnt(u,p,f.endT,m,g),v=gnt(mnt(u,p,f.startT,m,g),e),S=gnt(mnt(u,p,f.endT,m,g),e);if(a||(a=v,c=b\u0026\u0026f.startT\u003c=dnt),f.endT\u003c.999999999){const n=Int({trace:t,ripIndex:i.length,start:a,end:S,region:e,allowInteriorStart:c});n\u0026\u0026(i.push(n.connection),r.push(...n.endpointObstacles)),a=null,c=!1;const d=vnt({obstacleId:`${t.pcb_trace_id}_keep_${l}_bounds`,start:x,end:_,layer:m,width:g});d\u0026\u0026s.push(d),xnt(o,t,l++,x,_)}}if(a){const n=t.route.slice().reverse().map(hnt).find(t=\u003eBoolean(t));if(n){const o=Int({trace:t,ripIndex:i.length,start:a,end:{x:n.x,y:n.y,layer:n.layer??n.from_layer??a.layer,width:a.width},region:e,allowInteriorStart:c,allowInteriorEnd:!0});o\u0026\u0026(i.push(o.connection),r.push(...o.endpointObstacles))}}return{keptTraces:o,rerouteConnections:i,rerouteEndpointObstacles:r,clippedTraceSegmentObstacles:s,hadIntersection:d}},Pnt=(t,e)=\u003e{const n=structuredClone(t),o=[],i=[],r=[],s=[];for(const n of t.traces??[]){const a=Cnt(n,e,t.minTraceWidth);a?a.hadIntersection?(o.push(...a.keptTraces),i.push(...a.rerouteConnections),r.push(...a.rerouteEndpointObstacles),s.push(...a.clippedTraceSegmentObstacles)):o.push(structuredClone(n)):o.push(structuredClone(n))}const a=((t,e)=\u003e{const n={minX:t.minX,maxX:t.maxX,minY:t.minY,maxY:t.maxY};for(const t of e){const e=Ee(t);n.minX=Math.min(n.minX,e.minX),n.maxX=Math.max(n.maxX,e.maxX),n.minY=Math.min(n.minY,e.minY),n.maxY=Math.max(n.maxY,e.maxY)}return n})(e,[...r,...s]);return{...n,bounds:a,obstacles:[...n.obstacles,...r],traces:o,connections:i}},Mnt=(t,e)=\u003e{const n=new Map(e.connections.map(t=\u003e[t.name,t.__rootConnectionNames?.[0]??t.name])),o=(e.traces??[]).map(t=\u003e{const e=n.get(t.connection_name);return e?{...structuredClone(t),connection_name:e}:structuredClone(t)});return{...structuredClone(t),traces:o,jumpers:e.jumpers?structuredClone(e.jumpers):structuredClone(t.jumpers)}},Nnt=(t,e,n=[])=\u003e[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join(\"\\n\"),wnt=1.8,Tnt=.95,Rnt=.8,Ent=.95,Ant=class extends si{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;regionId;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.regionId=t.regionId,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=xe(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\u0026\u0026this.existingJumpers.push(...t.jumpers);const n=Math.ceil(5*(this.numRoutes+1));let o=this.boundsSize.width/this.cellStep,i=this.boundsSize.height/this.cellStep;for(;o*i\u003en**2\u0026\u0026!(this.cellStep\u003et.minDistBetweenEnteringPoints);)this.cellStep*=2,o=this.boundsSize.width/this.cellStep,i=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR;const r=Math.abs(this.A.x-this.bounds.minX)\u003c.001\u0026\u0026Math.abs(this.B.x-this.bounds.minX)\u003c.001||Math.abs(this.A.x-this.bounds.maxX)\u003c.001\u0026\u0026Math.abs(this.B.x-this.bounds.maxX)\u003c.001||Math.abs(this.A.y-this.bounds.minY)\u003c.001\u0026\u0026Math.abs(this.B.y-this.bounds.minY)\u003c.001||Math.abs(this.A.y-this.bounds.maxY)\u003c.001\u0026\u0026Math.abs(this.B.y-this.bounds.maxY)\u003c.001;this.futureConnections\u0026\u00260===this.futureConnections.length\u0026\u00260===this.obstacleRoutes.length\u0026\u0026!r\u0026\u0026this.handleSimpleCases();const s={x:t.A.x,y:t.A.y};this.initialNodeGridOffset={x:s.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:s.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 Wi([{...t.A,...s,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,regionId:this.regionId,route:[{x:t.x,y:t.y,z:0},{x:e.x,y:e.y,z:0}],traceThickness:this.traceThickness,jumpers:[]}}get jumperPenaltyDistance(){return wnt+this.straightLineDistance*this.JUMPER_PENALTY_FACTOR}isNodeTooCloseToObstacle(t,e){e??=this.obstacleMargin;for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){const o=Ont(n);for(const n of o)if(be(t,n.A,n.B)\u003cthis.traceThickness+e)return!0}for(const o of n.jumpers||[])if(this.isNodeTooCloseToJumper(t,o,e))return!0}return!1}isNodeTooCloseToJumper(t,e,n){const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=Math.abs(o)\u003eMath.abs(i),s=(r?Rnt:Ent)/2+n,a=(r?Ent:Rnt)/2+n;return Math.abs(t.x-e.start.x)\u003cs\u0026\u0026Math.abs(t.y-e.start.y)\u003ca||Math.abs(t.x-e.end.x)\u003cs\u0026\u0026Math.abs(t.y-e.end.y)\u003ca}isNodeTooCloseToEdge(t){const e=t.gComponents?.distFromStart??0\u003cthis.obstacleMargin/2?-this.obstacleMargin/2:this.obstacleMargin/2,n=t.x\u003cthis.bounds.minX+e||t.x\u003ethis.bounds.maxX-e||t.y\u003cthis.bounds.minY+e||t.y\u003ethis.bounds.maxY-e;return(!n||!(xe(t,this.B)\u003c2*e||xe(t,this.A)\u003c2*e))\u0026\u0026n}doesPathToParentIntersectObstacle(t){const e=t.parent;if(!e)return!1;for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){for(const o of Ont(n))if(fe(t,e,o.A,o.B))return!0;for(const o of n.jumpers||[])if(this.doesSegmentIntersectJumperPads(t,e,o))return!0}}return!1}doesSegmentIntersectJumperPads(t,e,n){const o=this.obstacleMargin,i=n.end.x-n.start.x,r=n.end.y-n.start.y,s=Math.abs(i)\u003eMath.abs(r),a=(s?Rnt:Ent)/2+o,c=(s?Ent:Rnt)/2+o;return!!this.doesSegmentIntersectRect(t,e,n.start,a,c)||!!this.doesSegmentIntersectRect(t,e,n.end,a,c)}doesSegmentIntersectRect(t,e,n,o,i){const r=n.x-o,s=n.x+o,a=n.y-i,c=n.y+i;if(t.x\u003e=r\u0026\u0026t.x\u003c=s\u0026\u0026t.y\u003e=a\u0026\u0026t.y\u003c=c)return!0;if(e.x\u003e=r\u0026\u0026e.x\u003c=s\u0026\u0026e.y\u003e=a\u0026\u0026e.y\u003c=c)return!0;const l=[{A:{x:r,y:a},B:{x:s,y:a}},{A:{x:s,y:a},B:{x:s,y:c}},{A:{x:s,y:c},B:{x:r,y:c}},{A:{x:r,y:c},B:{x:r,y:a}}];for(const n of l)if(fe(t,e,n.A,n.B))return!0;return!1}findObstaclesBetween(t,e){const n=[];for(const o of this.obstacleRoutes){const i=this.connMap?.areIdsConnected?.(this.connectionName,o.connectionName);if(!i)for(const i of Ont(o))fe(t,e,i.A,i.B)\u0026\u0026n.push({A:i.A,B:i.B})}return n}computeHComponents(t){const e=xe(t,this.roundedGoalPosition),n=this.getObstacleProximityPenalty(t),o=this.getEdgeProximityPenalty(t),i=this.getFutureConnectionStartEndPenalty(t),r=this.getFutureConnectionLinePenalty(t),s=t.parent,a=s?.hComponents,c=s?xe(t,s):0,l=(t,n)=\u003e{if(void 0===n||c\u003c1e-9||e\u003c1e-9)return t;const o=(t-n)/c;return(t+Math.max(0,t+o*e))/2},d=l(n,a?.obstacleProximityRate),h=l(o,a?.edgeProximityRate),u=l(i,a?.futureConnectionStartEndProximityRate),p=l(r,a?.futureConnectionLineRate),m=d*e,g=h*e,f=u*e,y=p*e;return{distanceToGoal:e,obstacleProximity:m,edgeProximity:g,futureConnectionStartEndProximityPenalty:f,futureConnectionLine:y,total:e+m+g+f+y,obstacleProximityRate:n,edgeProximityRate:o,futureConnectionStartEndProximityRate:i,futureConnectionLineRate:r}}computeH(t){return this.computeHComponents(t).total}computeGComponents(t){const e=t.parent,n=e?xe(t,e):0,o=e?.gComponents??{distFromStart:0,weightedMmNearObstacle:0,weightedMmNearEdge:0,weightedMmNearFutureConnectionStartEnd:0,weightedMmNearFutureConnectionLine:0,jumperPenalty:0,jumperPadFutureConnectionPenalty:0,total:0},i=o.distFromStart+n,r=o.weightedMmNearObstacle+this.getObstacleProximityPenalty(t)*n,s=o.weightedMmNearEdge+this.getEdgeProximityPenalty(t)*n,a=o.weightedMmNearFutureConnectionStartEnd+this.getFutureConnectionStartEndPenalty(t)*n,c=o.weightedMmNearFutureConnectionLine+this.getFutureConnectionLinePenalty(t)*n;let l=o.jumperPenalty,d=o.jumperPadFutureConnectionPenalty;t.isJumperExit\u0026\u0026(l+=this.jumperPenaltyDistance,d+=this.getJumperPadFutureConnectionPenalty(t));return{distFromStart:i,weightedMmNearObstacle:r,weightedMmNearEdge:s,weightedMmNearFutureConnectionStartEnd:a,weightedMmNearFutureConnectionLine:c,jumperPenalty:l,jumperPadFutureConnectionPenalty:d,total:i+r+s+a+c+l+d}}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 o of this.futureConnections)for(const i of o.points){const o=xe(t,i);o\u003ce\u0026\u0026(e=o,n=i)}return n}getFutureConnectionStartEndPenalty(t){let e=0;const n=this.getClosestFutureConnectionPoint(t);if(n){const o=xe(t,n);if(o\u003ethis.FUTURE_CONNECTION_START_END_PROXIMITY)return 0;const i=o/this.FUTURE_CONNECTION_START_END_PROXIMITY;e=this.FUTURE_CONNECTION_START_END_PENALTY*(1-i)**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\u003c2)continue;const o=be(t,n.points[0],n.points[n.points.length-1]);e=Math.min(e,o)}if(e*=n,e\u003cthis.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 o=1/0;for(const t of this.futureConnections)for(const i of t.points){const t=xe(e,i),r=xe(n,i),s=Math.min(t,r);o=Math.min(o,s)}if(o\u003cthis.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY){const t=o/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 o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){for(const o of Ont(n))e=Math.min(e,be(t,o.A,o.B));for(const o of n.jumpers||[])e=Math.min(e,this.distanceToJumperPads(t,o))}}return e}distanceToJumperPads(t,e){const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.abs(n)\u003eMath.abs(o),r=(i?Rnt:Ent)/2,s=(i?Ent:Rnt)/2;return Math.min(this.pointToRectDistance(t,e.start,r,s),this.pointToRectDistance(t,e.end,r,s))}pointToRectDistance(t,e,n,o){const i=Math.max(Math.abs(t.x-e.x)-n,0),r=Math.max(Math.abs(t.y-e.y)-o,0);return Math.hypot(i,r)}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)),o=this.OBSTACLE_PROX_SIGMA;return this.OBSTACLE_PROX_PENALTY_FACTOR*Math.exp(-n/o)}getEdgeProximityPenalty(t){const e=this.getClearanceToEdge(t),n=this.EDGE_PROX_SIGMA;if(e\u003e2*this.EDGE_PROX_SIGMA)return 0;const o=xe(t,this.B),i=Math.min(1,o/(2*this.EDGE_PROX_SIGMA));return this.EDGE_PROX_PENALTY_FACTOR*Math.exp(-e/n)*i}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)\u003cthis.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 o of n){const n=2*wnt,i=t.x+o.dx*n,r=t.y+o.dy*n,s=this.findObstaclesBetween(t,{x:i,y:r});if(s.length\u003e0)for(const n of s){const i=this.calculateJumperExit(t,n,o);i\u0026\u0026!this.exploredNodes.has(this.getNodeKey(i))\u0026\u0026(this.isNodeTooCloseToObstacle(i)||this.isNodeTooCloseToEdge(i)||!this.isJumperPlacementValid(t,i)||(i.gComponents=this.computeGComponents(i),i.hComponents=this.computeHComponents(i),i.g=i.gComponents.total,i.h=i.hComponents.total,i.f=this.computeF(i.g,i.h),e.push(i)))}}return e}calculateJumperExit(t,e,n){const o=wnt,i=Math.sqrt(n.dx*n.dx+n.dy*n.dy),r=n.dx/i,s=n.dy/i,a=t.x+r*o,c=t.y+s*o;return a\u003cthis.bounds.minX||a\u003ethis.bounds.maxX||c\u003cthis.bounds.minY||c\u003ethis.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,o=e.y-t.y,i=Math.abs(n)\u003eMath.abs(o),r=(i?Rnt:Ent)/2,s=(i?Ent:Rnt)/2,a=this.obstacleMargin,c=[t,e];for(const t of c){const e=[t,{x:t.x-r,y:t.y-s},{x:t.x+r,y:t.y-s},{x:t.x-r,y:t.y+s},{x:t.x+r,y:t.y+s},{x:t.x-r,y:t.y},{x:t.x+r,y:t.y},{x:t.x,y:t.y-s},{x:t.x,y:t.y+s}];for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(o)continue;const i=Ont(n);for(const n of i){for(const t of e)if(be(t,n.A,n.B)\u003cthis.traceThickness+a)return!0;if(this.doesSegmentIntersectRect(n.A,n.B,t,r+a,s+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 o=this.getJumpersInPath(t);for(const t of o)if(this.doJumpersOverlap(n,t))return!1;return!0}doJumpersOverlap(t,e){const n=this.obstacleMargin,o=Math.min(t.start.x,t.end.x)-Tnt/2-n,i=Math.max(t.start.x,t.end.x)+Tnt/2+n,r=Math.min(t.start.y,t.end.y)-Tnt/2-n,s=Math.max(t.start.y,t.end.y)+Tnt/2+n,a=Math.min(e.start.x,e.end.x)-Tnt/2-n,c=Math.max(e.start.x,e.end.x)+Tnt/2+n,l=Math.min(e.start.y,e.end.y)-Tnt/2-n,d=Math.max(e.start.y,e.end.y)+Tnt/2+n;return!(i\u003ca||o\u003ec||s\u003cl||r\u003ed)}getJumpersInPath(t){const e=[];let n=t;for(;n\u0026\u0026n.parent;)n.isJumperExit\u0026\u0026n.jumperEntry\u0026\u0026e.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:o,maxY:i,minY:r}=this.bounds;for(let s=-1;s\u003c=1;s++)for(let a=-1;a\u003c=1;a++){if(0===s\u0026\u00260===a)continue;if(!this.ALLOW_DIAGONAL\u0026\u00260!==s\u0026\u00260!==a)continue;const c=t.x+s*this.cellStep,l=t.y+a*this.cellStep,d=knt(c,o,n),h=knt(l,r,i),u={...t,parent:t,x:d,y:h,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 s=this.getJumperNeighbors(t);return e.push(...s),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\u003ce.length;t++){const o=e[t];o.isJumperExit\u0026\u0026o.jumperEntry\u0026\u0026n.push({route_type:\"jumper\",start:o.jumperEntry,end:{x:o.x,y:o.y},footprint:\"0603\"})}this.solvedPath={connectionName:this.connectionName,rootConnectionName:this.rootConnectionName,regionId:this.regionId,traceThickness:this.traceThickness,route:e.map(t=\u003e({x:t.x,y:t.y,z:0})).concat([{x:this.B.x,y:this.B.y,z:0}]),jumpers:n}}computeProgress(t,e){if(void 0===e)return Number.NaN;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\u0026\u0026e\u0026\u0026this.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=xe(t,this.roundedGoalPosition);this.progress=this.computeProgress(t,n),n\u003c=this.cellStep*Math.SQRT2\u0026\u0026!this.doesPathToParentIntersectObstacle({...t,parent:t,x:this.B.x,y:this.B.y})\u0026\u0026(this.solved=!0,this.setSolvedPath(t));const o=this.getNeighbors(t);for(const t of o)this.candidates.enqueue(t)}drawJumperPads(t,e,n,o,i,r){const s=e.end.x-e.start.x,a=e.end.y-e.start.y,c=Rnt,l=Ent,d=Math.abs(s)\u003eMath.abs(a),h=d?c:l,u=d?l:c;t.rects.push({center:{x:e.start.x,y:e.start.y},width:h,height:u,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:o??\"jumper\",step:i,label:r}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:h,height:u,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:o??\"jumper\",step:i,label:r}),t.lines.push({points:[e.start,e.end],strokeColor:\"rgba(100, 100, 100, 0.8)\",strokeWidth:.3*l,layer:o??\"jumper-body\",step:i,label:r})}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:Nnt(this.connectionName,this.rootConnectionName,[\"Input A\",`z: ${this.A.z}`]),color:\"orange\"}),t.points.push({x:this.B.x,y:this.B.y,label:Nnt(this.connectionName,this.rootConnectionName,[\"Input B\",`z: ${this.B.z}`]),color:\"orange\"}),t.lines.push({points:[this.A,this.B],strokeColor:\"rgba(255, 0, 0, 0.5)\",label:Nnt(this.connectionName,this.rootConnectionName,[\"Direct Input Connection\"])});for(let e=0;e\u003cthis.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let o=0;o\u003cn.route.length-1;o++)t.lines.push({points:[n.route[o],n.route[o+1]],strokeColor:\"rgba(255, 0, 0, 0.75)\",strokeWidth:n.traceThickness,label:Nnt(n.connectionName,n.rootConnectionName,[\"Obstacle Route\"]),layer:`obstacle${e.toString()}`});for(const o of n.jumpers||[])this.drawJumperPads(t,o,\"rgba(255, 0, 0, 0.5)\",`obstacle-jumper-${e}`,void 0,Nnt(n.connectionName,n.rootConnectionName,[\"Obstacle Jumper\"]))}for(let e=0;e\u003cthis.futureConnections.length;e++){const n=this.futureConnections[e];if(n.points.length\u003c2)continue;const o=n.points[0],i=n.points[n.points.length-1];t.lines.push({points:[o,i],strokeColor:\"rgba(0, 100, 255, 0.6)\",strokeWidth:this.traceThickness,label:Nnt(n.connectionName,n.rootConnectionName,[\"Future\"]),layer:`future-connection-${e}`})}for(let e=0;e\u003cthis.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[o,i]=n.split(\",\").map(Number),r=n.endsWith(\"_j\"),s=this.debug_exploredNodeValues.get(n),a=s?.gComponents,c=s?.hComponents,l=c?.distanceToGoal??0,d=[r?\"Explored (jumper)\":\"Explored\"];d.push(`g.distFromStart: ${a?.distFromStart.toFixed(2)??\"?\"}`),d.push(`g.nearObstacle: ${a?.weightedMmNearObstacle.toFixed(2)??\"?\"}`),d.push(`g.nearEdge: ${a?.weightedMmNearEdge.toFixed(2)??\"?\"}`),d.push(`g.nearFutStrtEnd: ${a?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??\"?\"}`),d.push(`g.nearFutLine: ${a?.weightedMmNearFutureConnectionLine.toFixed(2)??\"?\"}`),d.push(`g.jumper: ${a?.jumperPenalty.toFixed(2)??\"?\"}`),d.push(`g.jumperPadFutPenalty: ${a?.jumperPadFutureConnectionPenalty.toFixed(2)??\"?\"}`),d.push(`h.goalDist: ${l.toFixed(2)}`),d.push(`h.obstacleProx: ${c?.obstacleProximity.toFixed(2)??\"?\"} (${l\u003e0?((c?.obstacleProximity??0)/l).toFixed(3):0}/mm)`),d.push(`h.edgeProx: ${c?.edgeProximity.toFixed(2)??\"?\"} (${l\u003e0?((c?.edgeProximity??0)/l).toFixed(3):0}/mm)`),d.push(`h.futureConnPt: ${c?.futureConnectionStartEndProximityPenalty.toFixed(2)??\"?\"} (${l\u003e0?((c?.futureConnectionStartEndProximityPenalty??0)/l).toFixed(3):0}/mm)`),d.push(`h.futureConnLine: ${c?.futureConnectionLine.toFixed(2)??\"?\"} (${l\u003e0?((c?.futureConnectionLine??0)/l).toFixed(3):0}/mm)`),d.push(`g: ${s?.g.toFixed(2)??\"?\"}`),d.push(`h: ${s?.h.toFixed(2)??\"?\"}`),d.push(`f: ${s?.f.toFixed(2)??\"?\"}`);const h=d.join(\"\\n\");t.rects.push({center:{x:o+this.initialNodeGridOffset.x,y:i+this.initialNodeGridOffset.y},fill:r?`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:h})}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\u003ce.length;n++){const o=e[n],i=o.isJumperExit??!1,r=o.gComponents,s=o.hComponents,a=s?.distanceToGoal??0,c=[`Candidate #${n+1}${i?\" (jumper)\":\"\"}`];c.push(`g.distFromStart: ${r?.distFromStart.toFixed(2)??\"?\"}`),c.push(`g.nearObstacle: ${r?.weightedMmNearObstacle.toFixed(2)??\"?\"}`),c.push(`g.nearEdge: ${r?.weightedMmNearEdge.toFixed(2)??\"?\"}`),c.push(`g.nearFutureConnPt: ${r?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??\"?\"}`),c.push(`g.nearFutureConnLine: ${r?.weightedMmNearFutureConnectionLine.toFixed(2)??\"?\"}`),c.push(`g.jumper: ${r?.jumperPenalty.toFixed(2)??\"?\"}`),c.push(`g.jumperPadFutureConn: ${r?.jumperPadFutureConnectionPenalty.toFixed(2)??\"?\"}`),c.push(`g: ${o.g.toFixed(2)}`),c.push(`h.goalDist: ${a.toFixed(2)}`),c.push(`h.obstacleProx: ${s?.obstacleProximity.toFixed(2)??\"?\"} (${a\u003e0?((s?.obstacleProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.edgeProx: ${s?.edgeProximity.toFixed(2)??\"?\"} (${a\u003e0?((s?.edgeProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnPt: ${s?.futureConnectionStartEndProximityPenalty.toFixed(2)??\"?\"} (${a\u003e0?((s?.futureConnectionStartEndProximityPenalty??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnLine: ${s?.futureConnectionLine.toFixed(2)??\"?\"} (${a\u003e0?((s?.futureConnectionLine??0)/a).toFixed(3):0}/mm)`),c.push(`h: ${o.h.toFixed(2)}`),c.push(`f: ${o.f.toFixed(2)}`);const l=c.join(\"\\n\");t.points.push({x:o.x,y:o.y,color:\"gray\",label:l})}if(this.solvedPath){t.lines.push({points:this.solvedPath.route,strokeColor:\"green\",label:Nnt(this.solvedPath.connectionName,this.solvedPath.rootConnectionName,[\"Solved Route\"]),strokeWidth:this.traceThickness});for(const e of this.solvedPath.jumpers)this.drawJumperPads(t,e,\"rgba(0, 200, 0, 0.8)\",\"solved-jumper\",void 0,Nnt(this.solvedPath.connectionName,this.solvedPath.rootConnectionName,[\"Solved Jumper\"]))}const{minX:n,minY:o,maxX:i,maxY:r}=this.bounds;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:r},{x:n,y:r},{x:n,y:o}],strokeColor:\"rgba(255, 0, 0, 0.25)\",strokeDash:\"4 4\",layer:\"border\"}),t}};function Ont(t){const e=[];for(let n=0;n\u003ct.route.length-1;n++)if(t.route[n].z===t.route[n+1].z){const o=t.route[n],i=t.route[n+1],r=t.jumpers?.some(t=\u003e{const e=Math.abs(t.start.x-o.x)\u003c.001\u0026\u0026Math.abs(t.start.y-o.y)\u003c.001\u0026\u0026Math.abs(t.end.x-i.x)\u003c.001\u0026\u0026Math.abs(t.end.y-i.y)\u003c.001,n=Math.abs(t.start.x-i.x)\u003c.001\u0026\u0026Math.abs(t.start.y-i.y)\u003c.001\u0026\u0026Math.abs(t.end.x-o.x)\u003c.001\u0026\u0026Math.abs(t.end.y-o.y)\u003c.001;return e||n});r||e.push({z:o.z,A:o,B:i})}return e}function knt(t,e,n){return Math.max(e,Math.min(t,n))}var Lnt=.8,Dnt=.95,znt=(t,e,n=[])=\u003e[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join(\"\\n\"),Fnt=class extends si{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 o=new Map;for(const t of e.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}this.unsolvedConnections=[];for(const[t,e]of o){const n=Dr(e);for(const[e,o]of n)this.unsolvedConnections.push({connectionName:t,rootConnectionName:e.rootConnectionName??o.rootConnectionName,points:[{x:e.x,y:e.y,z:0},{x:o.x,y:o.y,z:0}]});if(0===n.length\u0026\u00261===e.length){const[n]=e;this.unsolvedConnections.push({connectionName:t,rootConnectionName:n?.rootConnectionName,points:n?[{x:n.x,y:n.y,z:0}]:[]})}}this.hyperParameters.SHUFFLE_SEED\u0026\u0026(this.unsolvedConnections=Xi(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=\u003e({...e,points:Xi(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Vi(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\u0026\u0026(this.failedSubSolvers.push(this.activeSubSolver),this.lastActiveSubSolver=this.activeSubSolver,this.activeSubSolver=null,this.error=this.failedSubSolvers.map(t=\u003et.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,o=Math.abs(e.x-n.x)\u003c1e-6,i=Math.abs(e.y-n.y)\u003c1e-6;if(o\u0026\u0026i)return}const{connectionName:e,rootConnectionName:n,points:o}=t;this.activeSubSolver=new Ant({connectionName:e,rootConnectionName:n,regionId:this.nodeWithPortPoints.capacityMeshNodeId,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:ro(this.nodeWithPortPoints),A:{x:o[0].x,y:o[0].y,z:0},B:{x:o[o.length-1].x,y:o[o.length-1].y,z:0},obstacleRoutes:this.solvedRoutes.filter(t=\u003e(!n||t.rootConnectionName!==n)\u0026\u0026!this.connMap?.areIdsConnected(t.connectionName,e)),futureConnections:this.unsolvedConnections,hyperParameters:this.hyperParameters,connMap:this.connMap,traceThickness:this.traceWidth})}drawJumperPads(t,e,n,o,i){const r=e.end.x-e.start.x,s=e.end.y-e.start.y,a=Lnt,c=Dnt,l=Math.abs(r)\u003eMath.abs(s),d=l?a:c,h=l?c:a;t.rects.push({center:{x:e.start.x,y:e.start.y},width:d,height:h,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:\"jumper\",label:i}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:d,height:h,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:\"jumper\",label:i}),t.lines.push({points:[e.start,e.end],strokeColor:\"rgba(100, 100, 100, 0.8)\",strokeWidth:.3*c,layer:\"jumper-body\",label:i})}visualize(){if(this.activeSubSolver\u0026\u0026!this.solved)return this.activeSubSolver.visualize();if(this.failed\u0026\u0026this.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:znt(e.connectionName,e.rootConnectionName,[\"layer: 0 (single-layer)\"]),color:this.colorMap[e.connectionName]??\"blue\"});for(let e=0;e\u003cthis.solvedRoutes.length;e++){const n=this.solvedRoutes[e];if(n.route.length\u003e0){const o=this.colorMap[n.connectionName]??\"blue\";for(let e=0;e\u003cn.route.length-1;e++){const i=n.route[e],r=n.route[e+1];t.lines.push({points:[i,r],strokeColor:To(o,.2),layer:\"route-layer-0\",strokeWidth:n.traceThickness,label:znt(n.connectionName,n.rootConnectionName,[\"layer: 0\"])})}for(const i of n.jumpers)this.drawJumperPads(t,i,To(o,.5),e,znt(n.connectionName,n.rootConnectionName,[\"jumper\"]))}}const e=ro(this.nodeWithPortPoints),{minX:n,minY:o,maxX:i,maxY:r}=e;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:r},{x:n,y:r},{x:n,y:o}],strokeColor:\"rgba(255, 0, 0, 0.25)\",strokeDash:\"4 4\",layer:\"border\"}),t}},Bnt=Ss;export{G9 as AUTOROUTER_VERSION,lnt as AssignableAutoroutingPipeline1Solver,Wl as AssignableAutoroutingPipeline2,ef as AssignableAutoroutingPipeline3,JX as AttachProjectedRectsSolver,yl as AutoroutingPipeline1_OriginalUnravel,rK as AutoroutingPipelineSolver,Bet as AutoroutingPipelineSolver10_BgaFanout,Jet as AutoroutingPipelineSolver11_Simplification,Pc as AutoroutingPipelineSolver2_PortPointPathing,Nf as AutoroutingPipelineSolver3_HgPortPointPathing,xX as AutoroutingPipelineSolver4,xX as AutoroutingPipelineSolver4_TinyHypergraph,EX as AutoroutingPipelineSolver5,EX as AutoroutingPipelineSolver5_HdCache,rG as AutoroutingPipelineSolver6,rG as AutoroutingPipelineSolver6_PolyHypergraph,rK as AutoroutingPipelineSolver7_MultiGraph,lK as AutoroutingPipelineSolver8,y8 as AutoroutingPipelineSolver9_Networked,H9 as AutoroutingPipelineSolver9_PreloadedTraceGraph,Mc as CapacityMeshSolver,Pd as CurvyIntraNodeSolver,n8 as DEFAULT_HD_CACHE2_SERVER_URL,wz as GlobalDrcBranchPortfolioSolver,Nz as GlobalDrcForceImproveSolver,Ls as GrowShrinkHighDensityIntraNodeSolver,Qg as HighDensitySolver,Bnt as HyperSingleIntraNodeSolver,Qn as InMemoryCache,Fnt as IntraNodeSolverWithJumpers,eo as LocalStorageCache,g8 as PIPELINE9_NETWORKED_SOLVE_POLICY,QX as PolyHighDensitySolver,KX as PolyIntraNodeSolver,KX as PolySingleIntraNodeSolver,Ss as PortfolioSingleIntraNodeSolver,oG as ProjectHighDensityToPolygonSolver,Ant as SingleHighDensityRouteWithJumpersSolver,$s as calculateOptimalCapacityDepth,Ho as convertSrjToGraphicsObject,oo as getGlobalInMemoryCache,no as getGlobalLocalStorageCache,Pnt as getRerouteSimpleRouteJson,js as getTunedTotalCapacity1,Mnt as reconnectReroutedSimpleRouteJsonRegion,io as setupGlobalCaches,_8 as solvePipeline9NetworkedHighDensityNode};\n/*! Bundled license information:\n\nis-buffer/index.js:\n (*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh \u003chttps://feross.org\u003e\n * @license MIT\n *)\n\ndeep-rename-keys/index.js:\n (*!\n * deep-rename-keys \u003chttps://github.com/jonschlinkert/deep-rename-keys\u003e\n *\n * Copyright (c) 2015 Jon Schlinkert, contributors.\n * Licensed under the MIT license.\n *)\n\n@tscircuit/curvy-trace-solver/dist/index.js:\n@tscircuit/find-convex-regions/dist/index.js:\n (*! Bundled license information:\n \n is-buffer/index.js:\n (*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh \u003chttps://feross.org\u003e\n * @license MIT\n *)\n \n deep-rename-keys/index.js:\n (*!\n * deep-rename-keys \u003chttps://github.com/jonschlinkert/deep-rename-keys\u003e\n *\n * Copyright (c) 2015 Jon Schlinkert, contributors.\n * Licensed under the MIT license.\n *)\n *)\n\n@tscircuit/hypergraph/dist/index.js:\n (*! Bundled license information:\n \n @tscircuit/find-convex-regions/dist/index.js:\n (*! Bundled license information:\n \n is-buffer/index.js:\n (*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh \u003chttps://feross.org\u003e\n * @license MIT\n *)\n \n deep-rename-keys/index.js:\n (*!\n * deep-rename-keys \u003chttps://github.com/jonschlinkert/deep-rename-keys\u003e\n *\n * Copyright (c) 2015 Jon Schlinkert, contributors.\n * Licensed under the MIT license.\n *)\n *)\n *)\n*///# sourceMappingURL=index.js.map","content_mimetype":"text/javascript","created_at":"2026-09-08T16:51:04.318Z"}; window.SSR_PACKAGE_RELEASES = [{"package_release_id":"dadcc3e3-2713-4e98-887f-4b6137bd5354","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.21","github_commit_sha":null,"is_locked":false,"is_latest":true,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-09-08T16:51:00.213Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-c972a675127a917f4275e6ed2e8d118e","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=dadcc3e3-2713-4e98-887f-4b6137bd5354\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=dadcc3e3-2713-4e98-887f-4b6137bd5354\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=dadcc3e3-2713-4e98-887f-4b6137bd5354\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"87ce88af-6ebc-4d18-8566-4157e21ea81e","user_code_job_started_at":"2026-09-08T16:52:33.622Z","user_code_job_completed_at":"2026-09-08T16:59:59.297Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=d6b4ee33048d45c49f3c2aa07288211b524699d6de79c1297a7ac825a214cef2","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"1bd43346-33f3-4cde-bfc0-0d0f5ef7be46","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.20","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-09-08T15:16:56.192Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-d11498066a18b91f14cfef35200ce692","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1bd43346-33f3-4cde-bfc0-0d0f5ef7be46\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1bd43346-33f3-4cde-bfc0-0d0f5ef7be46\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1bd43346-33f3-4cde-bfc0-0d0f5ef7be46\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"25ade5eb-73d1-47ce-9823-5f98374536ec","user_code_job_started_at":"2026-09-08T15:18:02.030Z","user_code_job_completed_at":"2026-09-08T15:25:40.398Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=89a479e0fa012d7b67eda0b76d5ebc3715268e252699e7ddd07a3464689ff513","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8c74453a-83e2-4172-bcda-666d01f22b9f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.19","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-09-08T15:06:14.644Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-d91e0490b469149ed15fbb1a51ebd6c4","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"1eb0a04c-ecf7-497e-af22-0e9b9527afed","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.18","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-09-08T14:59:07.818Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-d29c5c93da4790e226795ec61a311545","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"310748ea-1f54-4e0b-bcb0-e26de0418bbe","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.17","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-20T09:08:27.021Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-3ab68ad76231274fced8daa9b4d216d1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"31871f8c-83e2-47f0-968e-30522688d9b6","user_code_job_started_at":"2026-09-07T20:49:28.128Z","user_code_job_completed_at":"2026-09-07T21:05:41.129Z","user_code_job_error":{"message":"Your code failed to build (exit code 1), see build logs for the error details","error_code":"user_code_build_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=295f4c032a00680940217b249f3b3f4fc21ade71a404fb9d8dd81770696f8397","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"de03c299-1b05-400b-9a9e-29d42c16b2bc","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.16","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-17T16:56:08.078Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-d8dbda73d7ae6158f52f028821fc56ee","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"3bf37cdc-0107-4eac-9892-f247c5e18661","user_code_job_started_at":"2026-08-17T16:58:40.245Z","user_code_job_completed_at":"2026-08-17T17:28:41.191Z","user_code_job_error":{"message":"Build timed out after 30 minutes","error_code":"user_code_job_timeout"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=76d319070ca1fa7f302a7515628d2639daeeecb6a5981c696f85e46107e3b9b9","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"0e701bc3-f617-464c-b79c-8117d2c86339","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.15","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-12T16:15:42.323Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-1d696f35b011352aeb71a3a73b619442","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0e701bc3-f617-464c-b79c-8117d2c86339\u0026file_path=dist%2Fleft%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0e701bc3-f617-464c-b79c-8117d2c86339\u0026file_path=dist%2Fleft%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0e701bc3-f617-464c-b79c-8117d2c86339\u0026file_path=dist%2Fleft%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"b70c43ef-2eed-47b4-b330-04f89859db6a","user_code_job_started_at":"2026-08-12T19:18:18.738Z","user_code_job_completed_at":"2026-08-12T19:28:03.200Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=12aa44a3f0616a1a15b3a1b0b9f58c05bbb5a610306d691dd1254f2acd6c484b","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"051bc4bf-1895-4c06-848e-06f0dca2393d","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.14","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-12T15:57:48.194Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-0c5e9892ec1ff3b912eed0a8c52f86d6","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"27e8a9f6-e7eb-447a-8734-0d94020b0275","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.13","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-12T15:50:05.533Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-9c0370a7e35c6d29e28e2ecfd1a35f0d","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"09680cad-cb3a-43bc-b3d9-3977d56d794c","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.12","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-12T15:44:02.661Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-5db3a4d5fec54b23a1879189c3ae3cbb","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"9800209a-d5a4-4a4b-940a-d0269c8f63b6","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.11","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-11T15:04:42.562Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-566054e353ef8fe7b66172bc2fae98b0","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9800209a-d5a4-4a4b-940a-d0269c8f63b6\u0026file_path=dist%2Fleft%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9800209a-d5a4-4a4b-940a-d0269c8f63b6\u0026file_path=dist%2Fleft%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9800209a-d5a4-4a4b-940a-d0269c8f63b6\u0026file_path=dist%2Fleft%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"30a6cf6d-8331-40a2-88c1-c288ec518721","user_code_job_started_at":"2026-08-12T06:03:29.394Z","user_code_job_completed_at":"2026-08-12T06:05:35.547Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=9786155159a44073aca7f275639c5bba8096798efe9ea7bbec0ac5bff5dbbff4","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"dfee26ad-0833-46ab-80ba-c79f11c42204","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.10","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-11T15:00:53.088Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-3323412296cadec0032dc46d61871214","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"ab72b3d5-3b6f-492c-97d2-683e46ee727f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.9","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-10T12:08:14.180Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-c3f01b7ce05c51934f420bc6f5a6bef2","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ab72b3d5-3b6f-492c-97d2-683e46ee727f\u0026file_path=dist%2Fleft%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ab72b3d5-3b6f-492c-97d2-683e46ee727f\u0026file_path=dist%2Fleft%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ab72b3d5-3b6f-492c-97d2-683e46ee727f\u0026file_path=dist%2Fleft%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"a09c97ff-fc3a-43f6-adb6-fdecc09ac5a4","user_code_job_started_at":"2026-08-10T12:14:11.619Z","user_code_job_completed_at":"2026-08-10T12:22:41.299Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=bd272eacf6b19c9d8bca9ff7025a50289e8cc5dcce91b374d4398239f9b8fdc6","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"aab741d2-66d6-4141-a56f-dec9a93f0745","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.8","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T12:05:54.107Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":null,"circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8d099371-81f4-4556-9b50-06c5ff43530c","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.7","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T12:01:26.302Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-90b8b592fc532bc050dfa0051f22721d","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"b5644906-1850-4f7e-bc7f-384131bc85d5","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.6","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T11:57:22.892Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-645c7d3e9b78aedbd409f63ea760ff03","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"bf68f755-3410-47ae-a8f7-bf1842ede84f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.5","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-10T10:36:56.206Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-fae103c87d843cdbb7d5853edd5e00a1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"62b3be01-12c5-415f-af59-2eb8cd87f0a2","user_code_job_started_at":"2026-08-10T10:39:53.625Z","user_code_job_completed_at":"2026-08-10T10:46:01.744Z","user_code_job_error":{"message":"Your code failed to build (exit code 1), see build logs for the error details","error_code":"user_code_build_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=5b7af5faf2794cb43b7c2ef0edf4af78aee1d8f2cbf54dc1148ababea99e1991","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"12026e15-765c-488a-9886-a89e93409099","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.4","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T10:32:18.439Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-640370fe7412c50c2a81985dc4c85ea1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"49831c5f-ff27-4706-b8d9-7a0fe1662179","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.3","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T10:28:40.595Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-abd2412878570b9cbce9d060b8e64f90","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"2bbe2022-8ce9-4466-bce4-9d3460eb7620","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T10:24:34.733Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-0c6ef3495ed62c8311da6c2a4a5ce1f1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"511d059e-9f7c-4d44-b609-44cd623b4972","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-09T20:30:50.584Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-932b3b7914f4275cc095769b0f588268","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"af3b8d2e-6b0e-4354-9c73-14b62b65bd8d","user_code_job_started_at":"2026-08-10T09:05:50.472Z","user_code_job_completed_at":"2026-08-10T09:11:56.569Z","user_code_job_error":{"message":"Your code failed to build (exit code 1), see build logs for the error details","error_code":"user_code_build_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=858f0f5564ef737003bbfa6e781aeca055df3ed980065067ac7a494d91462263","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"0c2b43a3-54ff-41cc-9c2a-3c072a4bfce4","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-09T20:27:15.716Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-09c3251b45a913a702805e1ecccbb7b5","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"6243441b-092b-4166-b003-a232a9cb59ff","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.3","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-06T14:45:44.407Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-f8665c2de359b48d96d3d32c1ca7d0f8","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"3fcb8ef5-0e39-440c-a18f-1c682ef1e73d","user_code_job_started_at":"2026-08-06T14:45:50.004Z","user_code_job_completed_at":"2026-08-06T14:49:33.535Z","user_code_job_error":{"message":"There was an error running the job on our infrastructure, this is probably not your code, see build logs","error_code":"user_code_job_infrastructure_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=cbd18a5931f35b3cf6d4679c66ba2eeffba4e991283dff69751626b4d0c8bd62","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8c27b90d-b11f-403c-8691-41f218374a8f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-06T13:40:38.469Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-e220e519e921d21de687f0af4239252c","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"ea20fb0d-e807-43f9-ba83-8978b2a9cd04","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-06T13:38:39.968Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-234591a7f9c087d813fd8d5ecbda0d46","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ea20fb0d-e807-43f9-ba83-8978b2a9cd04\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ea20fb0d-e807-43f9-ba83-8978b2a9cd04\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ea20fb0d-e807-43f9-ba83-8978b2a9cd04\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"5155b2ea-d7ed-41fc-80c6-d6311b4b55b4","user_code_job_started_at":"2026-08-06T13:38:48.763Z","user_code_job_completed_at":"2026-08-06T13:40:21.516Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=2d9c8a936d46c3ed4f25c54515d1eb4ff16872ade7b430062b7a024bd40f6dee","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-06T13:15:02.283Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-1def03398d147a237eb937a952295e79","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"97b18410-03ef-4231-98d7-89ecd9b787a4","user_code_job_started_at":"2026-08-06T13:15:08.904Z","user_code_job_completed_at":"2026-08-06T13:16:24.373Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=279a064e6ac1ab57ef793fb8ad3a32d71e6b5262e3dd6104e362a8d55c2f7b68","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null}]; window.SSR_PACKAGE_BUILDS = []; window.SSR_RELATED_PACKAGES = [{"package_id":"307fe261-5d71-417c-bc01-7835cd4f4abe","creator_account_id":"96f144ef-7dfe-4068-aac0-8753c8ab5f62","latest_package_release_id":"3c938c18-451d-4aea-8ecc-b5e5f561e6c6","last_built_release_id":"3c938c18-451d-4aea-8ecc-b5e5f561e6c6","latest_package_release_fs_sha":"md5-d17042528d94ca0759bc1345f41464bb","latest_pcb_preview_image_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.2","license":"unset","owner_org_id":"f46c84e5-2ffb-44f6-a4fa-47ad19769e7a","org_owner_tscircuit_handle":"test-1","owner_github_username":"test-1","github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"imrishabh18/boost-converter","unscoped_name":"boost-converter","star_count":0,"created_at":"2026-05-18T12:43:26.451Z","updated_at":"2026-05-19T18:52:38.681Z","ai_description":"This code defines a PCB schematic and 3D model layout focusing on a power conversion circuit with components like USB-C connector, MT3608 step-up regulator, inductor, diode, input/output capacitors, and resistors arranged on a double-layer PCB.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"same_author","thumbnail_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2Fpcb.svg"},{"package_id":"1bb71080-c9d9-4806-8dad-9546e8b9913b","creator_account_id":"03854e77-22c2-44a0-9cfc-2d4ed6741105","latest_package_release_id":"92d10956-aa95-4eba-8e98-42e66c16f463","last_built_release_id":"92d10956-aa95-4eba-8e98-42e66c16f463","latest_package_release_fs_sha":"md5-73c7349eef4667e7cbc7beecb7e35036","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.5","license":"unset","owner_org_id":"7978967e-b956-4ac2-b813-667a08f6310a","org_owner_tscircuit_handle":"abse","owner_github_username":null,"github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"abse/boostxl-uln2003","unscoped_name":"boostxl-uln2003","star_count":0,"created_at":"2026-08-12T10:10:06.978Z","updated_at":"2026-08-12T22:29:23.783Z","ai_description":"This code defines a React component that models a through-hole or surface-mount LED with specified pin labels, footprint, silkscreen, and 3D CAD model for PCB layout.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"similar_ai_description","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2Fpcb.svg"},{"package_id":"7065b9a6-03de-43a1-ba42-2a0ead33b548","creator_account_id":"1f745cb8-1b99-4215-905f-f8e3dc29bc28","latest_package_release_id":"5746ef1e-d91a-4043-9db3-2cc17f89d777","last_built_release_id":"5746ef1e-d91a-4043-9db3-2cc17f89d777","latest_package_release_fs_sha":"md5-27fc15676f25d1e3a229466d1de0fe7a","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.1","license":"unset","owner_org_id":"60917f07-d371-4c51-854f-e2bd7dab9e5a","org_owner_tscircuit_handle":"hrithik18k","owner_github_username":null,"github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"hrithik18k/smart-switch-pcb","unscoped_name":"smart-switch-pcb","star_count":0,"created_at":"2026-09-09T11:12:10.428Z","updated_at":"2026-09-09T11:56:59.112Z","ai_description":"The AO3400A component models a SOT-23 N-channel MOSFET with labeled pins for Gate, Source, and Drain, including 3D CAD models and schematic symbols for electronic circuit design.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"random","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fpcb.svg"}]; window.SSR_PACKAGE_ROUTE = {"author":"imrishabh18","packageName":"corne-keyboard","packageNameWithScope":"imrishabh18/corne-keyboard","version":null,"isLegacyRoute":false,"kind":"file","filePath":"debug-autorouter.mjs"};
)}function Mb(t){let e=`${Sb}T${Cb(t)}`;const n=[];return n.push(t.local?"Z?":"Z"),t.offset&&n.push("([+-]\\d{2}:?\\d{2})"),e=`${e}(${n.join("|")})`,new RegExp(`^${e}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
),{});a(k_,{BRAND:()=\u003emx,DIRTY:()=\u003eJ_,EMPTY_PATH:()=\u003eW_,INVALID:()=\u003eq_,NEVER:()=\u003ecv,OK:()=\u003eK_,ParseStatus:()=\u003eZ_,Schema:()=\u003eab,ZodAny:()=\u003eBb,ZodArray:()=\u003eXb,ZodBigInt:()=\u003eOb,ZodBoolean:()=\u003ekb,ZodBranded:()=\u003egx,ZodCatch:()=\u003eux,ZodDate:()=\u003eLb,ZodDefault:()=\u003ehx,ZodDiscriminatedUnion:()=\u003eUb,ZodEffects:()=\u003ecx,ZodEnum:()=\u003erx,ZodError:()=\u003eB_,ZodFirstPartyTypeKind:()=\u003exx,ZodFunction:()=\u003eex,ZodIntersection:()=\u003eqb,ZodIssueCode:()=\u003ez_,ZodLazy:()=\u003enx,ZodLiteral:()=\u003eox,ZodMap:()=\u003eQb,ZodNaN:()=\u003epx,ZodNativeEnum:()=\u003esx,ZodNever:()=\u003e$b,ZodNull:()=\u003eFb,ZodNullable:()=\u003edx,ZodNumber:()=\u003eAb,ZodObject:()=\u003eWb,ZodOptional:()=\u003elx,ZodParsedType:()=\u003eL_,ZodPipeline:()=\u003efx,ZodPromise:()=\u003eax,ZodReadonly:()=\u003eyx,ZodRecord:()=\u003eKb,ZodSchema:()=\u003eab,ZodSet:()=\u003etx,ZodString:()=\u003eRb,ZodSymbol:()=\u003eDb,ZodTransformer:()=\u003ecx,ZodTuple:()=\u003eJb,ZodType:()=\u003eab,ZodUndefined:()=\u003ezb,ZodUnion:()=\u003eHb,ZodUnknown:()=\u003ejb,ZodVoid:()=\u003eYb,addIssueToContext:()=\u003eH_,any:()=\u003eOx,array:()=\u003ezx,bigint:()=\u003eNx,boolean:()=\u003ewx,coerce:()=\u003eav,custom:()=\u003ebx,date:()=\u003eTx,datetimeRegex:()=\u003eMb,defaultErrorMap:()=\u003ej_,discriminatedUnion:()=\u003e$x,effect:()=\u003eQx,enum:()=\u003eqx,function:()=\u003eGx,getErrorMap:()=\u003eX_,getParsedType:()=\u003eD_,instanceof:()=\u003eIx,intersection:()=\u003eYx,isAborted:()=\u003eQ_,isAsync:()=\u003enb,isDirty:()=\u003etb,isValid:()=\u003eeb,late:()=\u003eSx,lazy:()=\u003eUx,literal:()=\u003eZx,makeIssue:()=\u003eV_,map:()=\u003eWx,nan:()=\u003eMx,nativeEnum:()=\u003eJx,never:()=\u003eLx,null:()=\u003eAx,nullable:()=\u003eev,number:()=\u003ePx,object:()=\u003eFx,objectUtil:()=\u003eA_,oboolean:()=\u003esv,onumber:()=\u003erv,optional:()=\u003etv,ostring:()=\u003eiv,pipeline:()=\u003eov,preprocess:()=\u003env,promise:()=\u003eKx,quotelessJson:()=\u003eF_,record:()=\u003eVx,set:()=\u003eHx,setErrorMap:()=\u003eY_,strictObject:()=\u003eBx,string:()=\u003eCx,symbol:()=\u003eRx,transformer:()=\u003eQx,tuple:()=\u003eXx,undefined:()=\u003eEx,union:()=\u003ejx,unknown:()=\u003ekx,util:()=\u003eR_,void:()=\u003eDx}),(E_=R_||(R_={})).assertEqual=t=\u003e{},E_.assertIs=function(t){},E_.assertNever=function(t){throw new Error},E_.arrayToEnum=t=\u003e{const e={};for(const n of t)e[n]=n;return e},E_.getValidEnumValues=t=\u003e{const e=E_.objectKeys(t).filter(e=\u003e\"number\"!=typeof t[t[e]]),n={};for(const o of e)n[o]=t[o];return E_.objectValues(n)},E_.objectValues=t=\u003eE_.objectKeys(t).map(function(e){return t[e]}),E_.objectKeys=\"function\"==typeof Object.keys?t=\u003eObject.keys(t):t=\u003e{const e=[];for(const n in t)Object.prototype.hasOwnProperty.call(t,n)\u0026\u0026e.push(n);return e},E_.find=(t,e)=\u003e{for(const n of t)if(e(n))return n},E_.isInteger=\"function\"==typeof Number.isInteger?t=\u003eNumber.isInteger(t):t=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)\u0026\u0026Math.floor(t)===t,E_.joinValues=function(t,e=\" | \"){return t.map(t=\u003e\"string\"==typeof t?`'${t}'`:t).join(e)},E_.jsonStringifyReplacer=(t,e)=\u003e\"bigint\"==typeof e?e.toString():e,(A_||(A_={})).mergeShapes=(t,e)=\u003e({...t,...e});var L_=R_.arrayToEnum([\"string\",\"nan\",\"number\",\"integer\",\"float\",\"boolean\",\"date\",\"bigint\",\"symbol\",\"function\",\"undefined\",\"null\",\"array\",\"object\",\"unknown\",\"promise\",\"void\",\"never\",\"map\",\"set\"]),D_=t=\u003e{switch(typeof t){case\"undefined\":return L_.undefined;case\"string\":return L_.string;case\"number\":return Number.isNaN(t)?L_.nan:L_.number;case\"boolean\":return L_.boolean;case\"function\":return L_.function;case\"bigint\":return L_.bigint;case\"symbol\":return L_.symbol;case\"object\":return Array.isArray(t)?L_.array:null===t?L_.null:t.then\u0026\u0026\"function\"==typeof t.then\u0026\u0026t.catch\u0026\u0026\"function\"==typeof t.catch?L_.promise:\"undefined\"!=typeof Map\u0026\u0026t instanceof Map?L_.map:\"undefined\"!=typeof Set\u0026\u0026t instanceof Set?L_.set:\"undefined\"!=typeof Date\u0026\u0026t instanceof Date?L_.date:L_.object;default:return L_.unknown}},z_=R_.arrayToEnum([\"invalid_type\",\"invalid_literal\",\"custom\",\"invalid_union\",\"invalid_union_discriminator\",\"invalid_enum_value\",\"unrecognized_keys\",\"invalid_arguments\",\"invalid_return_type\",\"invalid_date\",\"invalid_string\",\"too_small\",\"too_big\",\"invalid_intersection_types\",\"not_multiple_of\",\"not_finite\"]),F_=t=\u003eJSON.stringify(t,null,2).replace(/\"([^\"]+)\":/g,\"$1:\"),B_=class t extends Error{get errors(){return this.issues}constructor(t){super(),this.issues=[],this.addIssue=t=\u003e{this.issues=[...this.issues,t]},this.addIssues=(t=[])=\u003e{this.issues=[...this.issues,...t]};const e=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,e):this.__proto__=e,this.name=\"ZodError\",this.issues=t}format(t){const e=t||function(t){return t.message},n={_errors:[]},o=t=\u003e{for(const i of t.issues)if(\"invalid_union\"===i.code)i.unionErrors.map(o);else if(\"invalid_return_type\"===i.code)o(i.returnTypeError);else if(\"invalid_arguments\"===i.code)o(i.argumentsError);else if(0===i.path.length)n._errors.push(e(i));else{let t=n,o=0;for(;o\u003ci.path.length;){const n=i.path[o];o===i.path.length-1?(t[n]=t[n]||{_errors:[]},t[n]._errors.push(e(i))):t[n]=t[n]||{_errors:[]},t=t[n],o++}}};return o(this),n}static assert(e){if(!(e instanceof t))throw new Error(`Not a ZodError: ${e}`)}toString(){return this.message}get message(){return JSON.stringify(this.issues,R_.jsonStringifyReplacer,2)}get isEmpty(){return 0===this.issues.length}flatten(t=t=\u003et.message){const e={},n=[];for(const o of this.issues)if(o.path.length\u003e0){const n=o.path[0];e[n]=e[n]||[],e[n].push(t(o))}else n.push(t(o));return{formErrors:n,fieldErrors:e}}get formErrors(){return this.flatten()}};B_.create=t=\u003enew B_(t);var j_=(t,e)=\u003e{let n;switch(t.code){case z_.invalid_type:n=t.received===L_.undefined?\"Required\":`Expected ${t.expected}, received ${t.received}`;break;case z_.invalid_literal:n=`Invalid literal value, expected ${JSON.stringify(t.expected,R_.jsonStringifyReplacer)}`;break;case z_.unrecognized_keys:n=`Unrecognized key(s) in object: ${R_.joinValues(t.keys,\", \")}`;break;case z_.invalid_union:n=\"Invalid input\";break;case z_.invalid_union_discriminator:n=`Invalid discriminator value. Expected ${R_.joinValues(t.options)}`;break;case z_.invalid_enum_value:n=`Invalid enum value. Expected ${R_.joinValues(t.options)}, received '${t.received}'`;break;case z_.invalid_arguments:n=\"Invalid function arguments\";break;case z_.invalid_return_type:n=\"Invalid function return type\";break;case z_.invalid_date:n=\"Invalid date\";break;case z_.invalid_string:\"object\"==typeof t.validation?\"includes\"in t.validation?(n=`Invalid input: must include \"${t.validation.includes}\"`,\"number\"==typeof t.validation.position\u0026\u0026(n=`${n} at one or more positions greater than or equal to ${t.validation.position}`)):\"startsWith\"in t.validation?n=`Invalid input: must start with \"${t.validation.startsWith}\"`:\"endsWith\"in t.validation?n=`Invalid input: must end with \"${t.validation.endsWith}\"`:R_.assertNever(t.validation):n=\"regex\"!==t.validation?`Invalid ${t.validation}`:\"Invalid\";break;case z_.too_small:n=\"array\"===t.type?`Array must contain ${t.exact?\"exactly\":t.inclusive?\"at least\":\"more than\"} ${t.minimum} element(s)`:\"string\"===t.type?`String must contain ${t.exact?\"exactly\":t.inclusive?\"at least\":\"over\"} ${t.minimum} character(s)`:\"number\"===t.type||\"bigint\"===t.type?`Number must be ${t.exact?\"exactly equal to \":t.inclusive?\"greater than or equal to \":\"greater than \"}${t.minimum}`:\"date\"===t.type?`Date must be ${t.exact?\"exactly equal to \":t.inclusive?\"greater than or equal to \":\"greater than \"}${new Date(Number(t.minimum))}`:\"Invalid input\";break;case z_.too_big:n=\"array\"===t.type?`Array must contain ${t.exact?\"exactly\":t.inclusive?\"at most\":\"less than\"} ${t.maximum} element(s)`:\"string\"===t.type?`String must contain ${t.exact?\"exactly\":t.inclusive?\"at most\":\"under\"} ${t.maximum} character(s)`:\"number\"===t.type?`Number must be ${t.exact?\"exactly\":t.inclusive?\"less than or equal to\":\"less than\"} ${t.maximum}`:\"bigint\"===t.type?`BigInt must be ${t.exact?\"exactly\":t.inclusive?\"less than or equal to\":\"less than\"} ${t.maximum}`:\"date\"===t.type?`Date must be ${t.exact?\"exactly\":t.inclusive?\"smaller than or equal to\":\"smaller than\"} ${new Date(Number(t.maximum))}`:\"Invalid input\";break;case z_.custom:n=\"Invalid input\";break;case z_.invalid_intersection_types:n=\"Intersection results could not be merged\";break;case z_.not_multiple_of:n=`Number must be a multiple of ${t.multipleOf}`;break;case z_.not_finite:n=\"Number must be finite\";break;default:n=e.defaultError,R_.assertNever(t)}return{message:n}},$_=j_;function Y_(t){$_=t}function X_(){return $_}var V_=t=\u003e{const{data:e,path:n,errorMaps:o,issueData:i}=t,r=[...n,...i.path||[]],s={...i,path:r};if(void 0!==i.message)return{...i,path:r,message:i.message};let a=\"\";const c=o.filter(t=\u003e!!t).slice().reverse();for(const t of c)a=t(s,{data:e,defaultError:a}).message;return{...i,path:r,message:a}},W_=[];function H_(t,e){const n=X_(),o=V_({issueData:e,data:t.data,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,n,n===j_?void 0:j_].filter(t=\u003e!!t)});t.common.issues.push(o)}var G_,U_,Z_=class t{constructor(){this.value=\"valid\"}dirty(){\"valid\"===this.value\u0026\u0026(this.value=\"dirty\")}abort(){\"aborted\"!==this.value\u0026\u0026(this.value=\"aborted\")}static mergeArray(t,e){const n=[];for(const o of e){if(\"aborted\"===o.status)return q_;\"dirty\"===o.status\u0026\u0026t.dirty(),n.push(o.value)}return{status:t.value,value:n}}static async mergeObjectAsync(e,n){const o=[];for(const t of n){const e=await t.key,n=await t.value;o.push({key:e,value:n})}return t.mergeObjectSync(e,o)}static mergeObjectSync(t,e){const n={};for(const o of e){const{key:e,value:i}=o;if(\"aborted\"===e.status)return q_;if(\"aborted\"===i.status)return q_;\"dirty\"===e.status\u0026\u0026t.dirty(),\"dirty\"===i.status\u0026\u0026t.dirty(),\"__proto__\"===e.value||void 0===i.value\u0026\u0026!o.alwaysSet||(n[e.value]=i.value)}return{status:t.value,value:n}}},q_=Object.freeze({status:\"aborted\"}),J_=t=\u003e({status:\"dirty\",value:t}),K_=t=\u003e({status:\"valid\",value:t}),Q_=t=\u003e\"aborted\"===t.status,tb=t=\u003e\"dirty\"===t.status,eb=t=\u003e\"valid\"===t.status,nb=t=\u003e\"undefined\"!=typeof Promise\u0026\u0026t instanceof Promise;(U_=G_||(G_={})).errToObj=t=\u003e\"string\"==typeof t?{message:t}:t||{},U_.toString=t=\u003e\"string\"==typeof t?t:t?.message;var ob=class{constructor(t,e,n,o){this._cachedPath=[],this.parent=t,this.data=e,this._path=n,this._key=o}get path(){return this._cachedPath.length||(Array.isArray(this._key)?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}},ib=(t,e)=\u003e{if(eb(e))return{success:!0,data:e.value};if(!t.common.issues.length)throw new Error(\"Validation failed but no issues detected.\");return{success:!1,get error(){if(this._error)return this._error;const e=new B_(t.common.issues);return this._error=e,this._error}}};function rb(t){if(!t)return{};const{errorMap:e,invalid_type_error:n,required_error:o,description:i}=t;if(e\u0026\u0026(n||o))throw new Error('Can\\'t use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.');if(e)return{errorMap:e,description:i};return{errorMap:(e,i)=\u003e{const{message:r}=t;return\"invalid_enum_value\"===e.code?{message:r??i.defaultError}:void 0===i.data?{message:r??o??i.defaultError}:\"invalid_type\"!==e.code?{message:i.defaultError}:{message:r??n??i.defaultError}},description:i}}var sb,ab=class{get description(){return this._def.description}_getType(t){return D_(t.data)}_getOrReturnCtx(t,e){return e||{common:t.parent.common,data:t.data,parsedType:D_(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}_processInputParams(t){return{status:new Z_,ctx:{common:t.parent.common,data:t.data,parsedType:D_(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}}_parseSync(t){const e=this._parse(t);if(nb(e))throw new Error(\"Synchronous parse encountered promise.\");return e}_parseAsync(t){const e=this._parse(t);return Promise.resolve(e)}parse(t,e){const n=this.safeParse(t,e);if(n.success)return n.data;throw n.error}safeParse(t,e){const n={common:{issues:[],async:e?.async??!1,contextualErrorMap:e?.errorMap},path:e?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)},o=this._parseSync({data:t,path:n.path,parent:n});return ib(n,o)}\"~validate\"(t){const e={common:{issues:[],async:!!this[\"~standard\"].async},path:[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)};if(!this[\"~standard\"].async)try{const n=this._parseSync({data:t,path:[],parent:e});return eb(n)?{value:n.value}:{issues:e.common.issues}}catch(t){t?.message?.toLowerCase()?.includes(\"encountered\")\u0026\u0026(this[\"~standard\"].async=!0),e.common={issues:[],async:!0}}return this._parseAsync({data:t,path:[],parent:e}).then(t=\u003eeb(t)?{value:t.value}:{issues:e.common.issues})}async parseAsync(t,e){const n=await this.safeParseAsync(t,e);if(n.success)return n.data;throw n.error}async safeParseAsync(t,e){const n={common:{issues:[],contextualErrorMap:e?.errorMap,async:!0},path:e?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:D_(t)},o=this._parse({data:t,path:n.path,parent:n}),i=await(nb(o)?o:Promise.resolve(o));return ib(n,i)}refine(t,e){const n=t=\u003e\"string\"==typeof e||void 0===e?{message:e}:\"function\"==typeof e?e(t):e;return this._refinement((e,o)=\u003e{const i=t(e),r=()=\u003eo.addIssue({code:z_.custom,...n(e)});return\"undefined\"!=typeof Promise\u0026\u0026i instanceof Promise?i.then(t=\u003e!!t||(r(),!1)):!!i||(r(),!1)})}refinement(t,e){return this._refinement((n,o)=\u003e!!t(n)||(o.addIssue(\"function\"==typeof e?e(n,o):e),!1))}_refinement(t){return new cx({schema:this,typeName:xx.ZodEffects,effect:{type:\"refinement\",refinement:t}})}superRefine(t){return this._refinement(t)}constructor(t){this.spa=this.safeParseAsync,this._def=t,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this),this[\"~standard\"]={version:1,vendor:\"zod\",validate:t=\u003ethis[\"~validate\"](t)}}optional(){return lx.create(this,this._def)}nullable(){return dx.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return Xb.create(this)}promise(){return ax.create(this,this._def)}or(t){return Hb.create([this,t],this._def)}and(t){return qb.create(this,t,this._def)}transform(t){return new cx({...rb(this._def),schema:this,typeName:xx.ZodEffects,effect:{type:\"transform\",transform:t}})}default(t){const e=\"function\"==typeof t?t:()=\u003et;return new hx({...rb(this._def),innerType:this,defaultValue:e,typeName:xx.ZodDefault})}brand(){return new gx({typeName:xx.ZodBranded,type:this,...rb(this._def)})}catch(t){const e=\"function\"==typeof t?t:()=\u003et;return new ux({...rb(this._def),innerType:this,catchValue:e,typeName:xx.ZodCatch})}describe(t){return new(0,this.constructor)({...this._def,description:t})}pipe(t){return fx.create(this,t)}readonly(){return yx.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}},cb=/^c[^\\s-]{8,}$/i,lb=/^[0-9a-z]+$/,db=/^[0-9A-HJKMNP-TV-Z]{26}$/i,hb=/^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i,ub=/^[a-z0-9_-]{21}$/i,pb=/^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$/,mb=/^[-+]?P(?!$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??$/,gb=/^(?!\\.)(?!.*\\.\\.)([A-Z0-9_'+\\-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i,fb=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,yb=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/(3[0-2]|[12]?[0-9])$/,_b=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,bb=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,xb=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,vb=/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,Sb=\"((\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\\\d|30)|(02)-(0[1-9]|1\\\\d|2[0-8])))\",Ib=new RegExp(`^${Sb}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
);function Cb(t){let e=\"[0-5]\\\\d\";t.precision?e=`${e}\\\\.\\\\d{${t.precision}}`:null==t.precision\u0026\u0026(e=`${e}(\\\\.\\\\d+)?`);return`([01]\\\\d|2[0-3]):[0-5]\\\\d(:${e})${t.precision?\"+\":\"?\"}`}function Pb(t){return new RegExp(`^${Cb(t)}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
)}function Mb(t){let e=`${Sb}T${Cb(t)}`;const n=[];return n.push(t.local?\"Z?\":\"Z\"),t.offset\u0026\u0026n.push(\"([+-]\\\\d{2}:?\\\\d{2})\"),e=`${e}(${n.join(\"|\")})`,new RegExp(`^${e}
debug-autorouter.mjs - imrishabh18/corne-keyboard - tscircuit
)}function Nb(t,e){return!(\"v4\"!==e\u0026\u0026e||!fb.test(t))||!(\"v6\"!==e\u0026\u0026e||!_b.test(t))}function wb(t,e){if(!pb.test(t))return!1;try{const[n]=t.split(\".\");if(!n)return!1;const o=n.replace(/-/g,\"+\").replace(/_/g,\"/\").padEnd(n.length+(4-n.length%4)%4,\"=\"),i=JSON.parse(atob(o));return\"object\"==typeof i\u0026\u0026null!==i\u0026\u0026((!(\"typ\"in i)||\"JWT\"===i?.typ)\u0026\u0026(!!i.alg\u0026\u0026(!e||i.alg===e)))}catch{return!1}}function Tb(t,e){return!(\"v4\"!==e\u0026\u0026e||!yb.test(t))||!(\"v6\"!==e\u0026\u0026e||!bb.test(t))}var Rb=class t extends ab{_parse(t){this._def.coerce\u0026\u0026(t.data=String(t.data));if(this._getType(t)!==L_.string){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.string,received:e.parsedType}),q_}const e=new Z_;let n;for(const o of this._def.checks)if(\"min\"===o.kind)t.data.length\u003co.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_small,minimum:o.value,type:\"string\",inclusive:!0,exact:!1,message:o.message}),e.dirty());else if(\"max\"===o.kind)t.data.length\u003eo.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_big,maximum:o.value,type:\"string\",inclusive:!0,exact:!1,message:o.message}),e.dirty());else if(\"length\"===o.kind){const i=t.data.length\u003eo.value,r=t.data.length\u003co.value;(i||r)\u0026\u0026(n=this._getOrReturnCtx(t,n),i?H_(n,{code:z_.too_big,maximum:o.value,type:\"string\",inclusive:!0,exact:!0,message:o.message}):r\u0026\u0026H_(n,{code:z_.too_small,minimum:o.value,type:\"string\",inclusive:!0,exact:!0,message:o.message}),e.dirty())}else if(\"email\"===o.kind)gb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"email\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"emoji\"===o.kind)sb||(sb=new RegExp(\"^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+$\",\"u\")),sb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"emoji\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"uuid\"===o.kind)hb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"uuid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"nanoid\"===o.kind)ub.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"nanoid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"cuid\"===o.kind)cb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"cuid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"cuid2\"===o.kind)lb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"cuid2\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"ulid\"===o.kind)db.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"ulid\",code:z_.invalid_string,message:o.message}),e.dirty());else if(\"url\"===o.kind)try{new URL(t.data)}catch{n=this._getOrReturnCtx(t,n),H_(n,{validation:\"url\",code:z_.invalid_string,message:o.message}),e.dirty()}else if(\"regex\"===o.kind){o.regex.lastIndex=0;o.regex.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"regex\",code:z_.invalid_string,message:o.message}),e.dirty())}else if(\"trim\"===o.kind)t.data=t.data.trim();else if(\"includes\"===o.kind)t.data.includes(o.value,o.position)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{includes:o.value,position:o.position},message:o.message}),e.dirty());else if(\"toLowerCase\"===o.kind)t.data=t.data.toLowerCase();else if(\"toUpperCase\"===o.kind)t.data=t.data.toUpperCase();else if(\"startsWith\"===o.kind)t.data.startsWith(o.value)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{startsWith:o.value},message:o.message}),e.dirty());else if(\"endsWith\"===o.kind)t.data.endsWith(o.value)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{endsWith:o.value},message:o.message}),e.dirty());else if(\"datetime\"===o.kind){Mb(o).test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:\"datetime\",message:o.message}),e.dirty())}else if(\"date\"===o.kind){Ib.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:\"date\",message:o.message}),e.dirty())}else if(\"time\"===o.kind){Pb(o).test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:\"time\",message:o.message}),e.dirty())}else\"duration\"===o.kind?mb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"duration\",code:z_.invalid_string,message:o.message}),e.dirty()):\"ip\"===o.kind?Nb(t.data,o.version)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"ip\",code:z_.invalid_string,message:o.message}),e.dirty()):\"jwt\"===o.kind?wb(t.data,o.alg)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"jwt\",code:z_.invalid_string,message:o.message}),e.dirty()):\"cidr\"===o.kind?Tb(t.data,o.version)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"cidr\",code:z_.invalid_string,message:o.message}),e.dirty()):\"base64\"===o.kind?xb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"base64\",code:z_.invalid_string,message:o.message}),e.dirty()):\"base64url\"===o.kind?vb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:\"base64url\",code:z_.invalid_string,message:o.message}),e.dirty()):R_.assertNever(o);return{status:e.value,value:t.data}}_regex(t,e,n){return this.refinement(e=\u003et.test(e),{validation:e,code:z_.invalid_string,...G_.errToObj(n)})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}email(t){return this._addCheck({kind:\"email\",...G_.errToObj(t)})}url(t){return this._addCheck({kind:\"url\",...G_.errToObj(t)})}emoji(t){return this._addCheck({kind:\"emoji\",...G_.errToObj(t)})}uuid(t){return this._addCheck({kind:\"uuid\",...G_.errToObj(t)})}nanoid(t){return this._addCheck({kind:\"nanoid\",...G_.errToObj(t)})}cuid(t){return this._addCheck({kind:\"cuid\",...G_.errToObj(t)})}cuid2(t){return this._addCheck({kind:\"cuid2\",...G_.errToObj(t)})}ulid(t){return this._addCheck({kind:\"ulid\",...G_.errToObj(t)})}base64(t){return this._addCheck({kind:\"base64\",...G_.errToObj(t)})}base64url(t){return this._addCheck({kind:\"base64url\",...G_.errToObj(t)})}jwt(t){return this._addCheck({kind:\"jwt\",...G_.errToObj(t)})}ip(t){return this._addCheck({kind:\"ip\",...G_.errToObj(t)})}cidr(t){return this._addCheck({kind:\"cidr\",...G_.errToObj(t)})}datetime(t){return\"string\"==typeof t?this._addCheck({kind:\"datetime\",precision:null,offset:!1,local:!1,message:t}):this._addCheck({kind:\"datetime\",precision:void 0===t?.precision?null:t?.precision,offset:t?.offset??!1,local:t?.local??!1,...G_.errToObj(t?.message)})}date(t){return this._addCheck({kind:\"date\",message:t})}time(t){return\"string\"==typeof t?this._addCheck({kind:\"time\",precision:null,message:t}):this._addCheck({kind:\"time\",precision:void 0===t?.precision?null:t?.precision,...G_.errToObj(t?.message)})}duration(t){return this._addCheck({kind:\"duration\",...G_.errToObj(t)})}regex(t,e){return this._addCheck({kind:\"regex\",regex:t,...G_.errToObj(e)})}includes(t,e){return this._addCheck({kind:\"includes\",value:t,position:e?.position,...G_.errToObj(e?.message)})}startsWith(t,e){return this._addCheck({kind:\"startsWith\",value:t,...G_.errToObj(e)})}endsWith(t,e){return this._addCheck({kind:\"endsWith\",value:t,...G_.errToObj(e)})}min(t,e){return this._addCheck({kind:\"min\",value:t,...G_.errToObj(e)})}max(t,e){return this._addCheck({kind:\"max\",value:t,...G_.errToObj(e)})}length(t,e){return this._addCheck({kind:\"length\",value:t,...G_.errToObj(e)})}nonempty(t){return this.min(1,G_.errToObj(t))}trim(){return new t({...this._def,checks:[...this._def.checks,{kind:\"trim\"}]})}toLowerCase(){return new t({...this._def,checks:[...this._def.checks,{kind:\"toLowerCase\"}]})}toUpperCase(){return new t({...this._def,checks:[...this._def.checks,{kind:\"toUpperCase\"}]})}get isDatetime(){return!!this._def.checks.find(t=\u003e\"datetime\"===t.kind)}get isDate(){return!!this._def.checks.find(t=\u003e\"date\"===t.kind)}get isTime(){return!!this._def.checks.find(t=\u003e\"time\"===t.kind)}get isDuration(){return!!this._def.checks.find(t=\u003e\"duration\"===t.kind)}get isEmail(){return!!this._def.checks.find(t=\u003e\"email\"===t.kind)}get isURL(){return!!this._def.checks.find(t=\u003e\"url\"===t.kind)}get isEmoji(){return!!this._def.checks.find(t=\u003e\"emoji\"===t.kind)}get isUUID(){return!!this._def.checks.find(t=\u003e\"uuid\"===t.kind)}get isNANOID(){return!!this._def.checks.find(t=\u003e\"nanoid\"===t.kind)}get isCUID(){return!!this._def.checks.find(t=\u003e\"cuid\"===t.kind)}get isCUID2(){return!!this._def.checks.find(t=\u003e\"cuid2\"===t.kind)}get isULID(){return!!this._def.checks.find(t=\u003e\"ulid\"===t.kind)}get isIP(){return!!this._def.checks.find(t=\u003e\"ip\"===t.kind)}get isCIDR(){return!!this._def.checks.find(t=\u003e\"cidr\"===t.kind)}get isBase64(){return!!this._def.checks.find(t=\u003e\"base64\"===t.kind)}get isBase64url(){return!!this._def.checks.find(t=\u003e\"base64url\"===t.kind)}get minLength(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return t}get maxLength(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return t}};function Eb(t,e){const n=(t.toString().split(\".\")[1]||\"\").length,o=(e.toString().split(\".\")[1]||\"\").length,i=n\u003eo?n:o;return Number.parseInt(t.toFixed(i).replace(\".\",\"\"))%Number.parseInt(e.toFixed(i).replace(\".\",\"\"))/10**i}Rb.create=t=\u003enew Rb({checks:[],typeName:xx.ZodString,coerce:t?.coerce??!1,...rb(t)});var Ab=class t extends ab{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(t){this._def.coerce\u0026\u0026(t.data=Number(t.data));if(this._getType(t)!==L_.number){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.number,received:e.parsedType}),q_}let e;const n=new Z_;for(const o of this._def.checks)if(\"int\"===o.kind)R_.isInteger(t.data)||(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.invalid_type,expected:\"integer\",received:\"float\",message:o.message}),n.dirty());else if(\"min\"===o.kind){(o.inclusive?t.data\u003co.value:t.data\u003c=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_small,minimum:o.value,type:\"number\",inclusive:o.inclusive,exact:!1,message:o.message}),n.dirty())}else if(\"max\"===o.kind){(o.inclusive?t.data\u003eo.value:t.data\u003e=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_big,maximum:o.value,type:\"number\",inclusive:o.inclusive,exact:!1,message:o.message}),n.dirty())}else\"multipleOf\"===o.kind?0!==Eb(t.data,o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_multiple_of,multipleOf:o.value,message:o.message}),n.dirty()):\"finite\"===o.kind?Number.isFinite(t.data)||(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_finite,message:o.message}),n.dirty()):R_.assertNever(o);return{status:n.value,value:t.data}}gte(t,e){return this.setLimit(\"min\",t,!0,G_.toString(e))}gt(t,e){return this.setLimit(\"min\",t,!1,G_.toString(e))}lte(t,e){return this.setLimit(\"max\",t,!0,G_.toString(e))}lt(t,e){return this.setLimit(\"max\",t,!1,G_.toString(e))}setLimit(e,n,o,i){return new t({...this._def,checks:[...this._def.checks,{kind:e,value:n,inclusive:o,message:G_.toString(i)}]})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}int(t){return this._addCheck({kind:\"int\",message:G_.toString(t)})}positive(t){return this._addCheck({kind:\"min\",value:0,inclusive:!1,message:G_.toString(t)})}negative(t){return this._addCheck({kind:\"max\",value:0,inclusive:!1,message:G_.toString(t)})}nonpositive(t){return this._addCheck({kind:\"max\",value:0,inclusive:!0,message:G_.toString(t)})}nonnegative(t){return this._addCheck({kind:\"min\",value:0,inclusive:!0,message:G_.toString(t)})}multipleOf(t,e){return this._addCheck({kind:\"multipleOf\",value:t,message:G_.toString(e)})}finite(t){return this._addCheck({kind:\"finite\",message:G_.toString(t)})}safe(t){return this._addCheck({kind:\"min\",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:G_.toString(t)})._addCheck({kind:\"max\",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:G_.toString(t)})}get minValue(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return t}get maxValue(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return t}get isInt(){return!!this._def.checks.find(t=\u003e\"int\"===t.kind||\"multipleOf\"===t.kind\u0026\u0026R_.isInteger(t.value))}get isFinite(){let t=null,e=null;for(const n of this._def.checks){if(\"finite\"===n.kind||\"int\"===n.kind||\"multipleOf\"===n.kind)return!0;\"min\"===n.kind?(null===e||n.value\u003ee)\u0026\u0026(e=n.value):\"max\"===n.kind\u0026\u0026(null===t||n.value\u003ct)\u0026\u0026(t=n.value)}return Number.isFinite(e)\u0026\u0026Number.isFinite(t)}};Ab.create=t=\u003enew Ab({checks:[],typeName:xx.ZodNumber,coerce:t?.coerce||!1,...rb(t)});var Ob=class t extends ab{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(t){if(this._def.coerce)try{t.data=BigInt(t.data)}catch{return this._getInvalidInput(t)}if(this._getType(t)!==L_.bigint)return this._getInvalidInput(t);let e;const n=new Z_;for(const o of this._def.checks)if(\"min\"===o.kind){(o.inclusive?t.data\u003co.value:t.data\u003c=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_small,type:\"bigint\",minimum:o.value,inclusive:o.inclusive,message:o.message}),n.dirty())}else if(\"max\"===o.kind){(o.inclusive?t.data\u003eo.value:t.data\u003e=o.value)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_big,type:\"bigint\",maximum:o.value,inclusive:o.inclusive,message:o.message}),n.dirty())}else\"multipleOf\"===o.kind?t.data%o.value!==BigInt(0)\u0026\u0026(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_multiple_of,multipleOf:o.value,message:o.message}),n.dirty()):R_.assertNever(o);return{status:n.value,value:t.data}}_getInvalidInput(t){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.bigint,received:e.parsedType}),q_}gte(t,e){return this.setLimit(\"min\",t,!0,G_.toString(e))}gt(t,e){return this.setLimit(\"min\",t,!1,G_.toString(e))}lte(t,e){return this.setLimit(\"max\",t,!0,G_.toString(e))}lt(t,e){return this.setLimit(\"max\",t,!1,G_.toString(e))}setLimit(e,n,o,i){return new t({...this._def,checks:[...this._def.checks,{kind:e,value:n,inclusive:o,message:G_.toString(i)}]})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}positive(t){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!1,message:G_.toString(t)})}negative(t){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!1,message:G_.toString(t)})}nonpositive(t){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!0,message:G_.toString(t)})}nonnegative(t){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!0,message:G_.toString(t)})}multipleOf(t,e){return this._addCheck({kind:\"multipleOf\",value:t,message:G_.toString(e)})}get minValue(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return t}get maxValue(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return t}};Ob.create=t=\u003enew Ob({checks:[],typeName:xx.ZodBigInt,coerce:t?.coerce??!1,...rb(t)});var kb=class extends ab{_parse(t){this._def.coerce\u0026\u0026(t.data=Boolean(t.data));if(this._getType(t)!==L_.boolean){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.boolean,received:e.parsedType}),q_}return K_(t.data)}};kb.create=t=\u003enew kb({typeName:xx.ZodBoolean,coerce:t?.coerce||!1,...rb(t)});var Lb=class t extends ab{_parse(t){this._def.coerce\u0026\u0026(t.data=new Date(t.data));if(this._getType(t)!==L_.date){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.date,received:e.parsedType}),q_}if(Number.isNaN(t.data.getTime())){return H_(this._getOrReturnCtx(t),{code:z_.invalid_date}),q_}const e=new Z_;let n;for(const o of this._def.checks)\"min\"===o.kind?t.data.getTime()\u003co.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_small,message:o.message,inclusive:!0,exact:!1,minimum:o.value,type:\"date\"}),e.dirty()):\"max\"===o.kind?t.data.getTime()\u003eo.value\u0026\u0026(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_big,message:o.message,inclusive:!0,exact:!1,maximum:o.value,type:\"date\"}),e.dirty()):R_.assertNever(o);return{status:e.value,value:new Date(t.data.getTime())}}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}min(t,e){return this._addCheck({kind:\"min\",value:t.getTime(),message:G_.toString(e)})}max(t,e){return this._addCheck({kind:\"max\",value:t.getTime(),message:G_.toString(e)})}get minDate(){let t=null;for(const e of this._def.checks)\"min\"===e.kind\u0026\u0026(null===t||e.value\u003et)\u0026\u0026(t=e.value);return null!=t?new Date(t):null}get maxDate(){let t=null;for(const e of this._def.checks)\"max\"===e.kind\u0026\u0026(null===t||e.value\u003ct)\u0026\u0026(t=e.value);return null!=t?new Date(t):null}};Lb.create=t=\u003enew Lb({checks:[],coerce:t?.coerce||!1,typeName:xx.ZodDate,...rb(t)});var Db=class extends ab{_parse(t){if(this._getType(t)!==L_.symbol){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.symbol,received:e.parsedType}),q_}return K_(t.data)}};Db.create=t=\u003enew Db({typeName:xx.ZodSymbol,...rb(t)});var zb=class extends ab{_parse(t){if(this._getType(t)!==L_.undefined){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.undefined,received:e.parsedType}),q_}return K_(t.data)}};zb.create=t=\u003enew zb({typeName:xx.ZodUndefined,...rb(t)});var Fb=class extends ab{_parse(t){if(this._getType(t)!==L_.null){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.null,received:e.parsedType}),q_}return K_(t.data)}};Fb.create=t=\u003enew Fb({typeName:xx.ZodNull,...rb(t)});var Bb=class extends ab{constructor(){super(...arguments),this._any=!0}_parse(t){return K_(t.data)}};Bb.create=t=\u003enew Bb({typeName:xx.ZodAny,...rb(t)});var jb=class extends ab{constructor(){super(...arguments),this._unknown=!0}_parse(t){return K_(t.data)}};jb.create=t=\u003enew jb({typeName:xx.ZodUnknown,...rb(t)});var $b=class extends ab{_parse(t){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.never,received:e.parsedType}),q_}};$b.create=t=\u003enew $b({typeName:xx.ZodNever,...rb(t)});var Yb=class extends ab{_parse(t){if(this._getType(t)!==L_.undefined){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.void,received:e.parsedType}),q_}return K_(t.data)}};Yb.create=t=\u003enew Yb({typeName:xx.ZodVoid,...rb(t)});var Xb=class t extends ab{_parse(t){const{ctx:e,status:n}=this._processInputParams(t),o=this._def;if(e.parsedType!==L_.array)return H_(e,{code:z_.invalid_type,expected:L_.array,received:e.parsedType}),q_;if(null!==o.exactLength){const t=e.data.length\u003eo.exactLength.value,i=e.data.length\u003co.exactLength.value;(t||i)\u0026\u0026(H_(e,{code:t?z_.too_big:z_.too_small,minimum:i?o.exactLength.value:void 0,maximum:t?o.exactLength.value:void 0,type:\"array\",inclusive:!0,exact:!0,message:o.exactLength.message}),n.dirty())}if(null!==o.minLength\u0026\u0026e.data.length\u003co.minLength.value\u0026\u0026(H_(e,{code:z_.too_small,minimum:o.minLength.value,type:\"array\",inclusive:!0,exact:!1,message:o.minLength.message}),n.dirty()),null!==o.maxLength\u0026\u0026e.data.length\u003eo.maxLength.value\u0026\u0026(H_(e,{code:z_.too_big,maximum:o.maxLength.value,type:\"array\",inclusive:!0,exact:!1,message:o.maxLength.message}),n.dirty()),e.common.async)return Promise.all([...e.data].map((t,n)=\u003eo.type._parseAsync(new ob(e,t,e.path,n)))).then(t=\u003eZ_.mergeArray(n,t));const i=[...e.data].map((t,n)=\u003eo.type._parseSync(new ob(e,t,e.path,n)));return Z_.mergeArray(n,i)}get element(){return this._def.type}min(e,n){return new t({...this._def,minLength:{value:e,message:G_.toString(n)}})}max(e,n){return new t({...this._def,maxLength:{value:e,message:G_.toString(n)}})}length(e,n){return new t({...this._def,exactLength:{value:e,message:G_.toString(n)}})}nonempty(t){return this.min(1,t)}};function Vb(t){if(t instanceof Wb){const e={};for(const n in t.shape){const o=t.shape[n];e[n]=lx.create(Vb(o))}return new Wb({...t._def,shape:()=\u003ee})}return t instanceof Xb?new Xb({...t._def,type:Vb(t.element)}):t instanceof lx?lx.create(Vb(t.unwrap())):t instanceof dx?dx.create(Vb(t.unwrap())):t instanceof Jb?Jb.create(t.items.map(t=\u003eVb(t))):t}Xb.create=(t,e)=\u003enew Xb({type:t,minLength:null,maxLength:null,exactLength:null,typeName:xx.ZodArray,...rb(e)});var Wb=class t extends ab{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(null!==this._cached)return this._cached;const t=this._def.shape(),e=R_.objectKeys(t);return this._cached={shape:t,keys:e},this._cached}_parse(t){if(this._getType(t)!==L_.object){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.object,received:e.parsedType}),q_}const{status:e,ctx:n}=this._processInputParams(t),{shape:o,keys:i}=this._getCached(),r=[];if(!(this._def.catchall instanceof $b\u0026\u0026\"strip\"===this._def.unknownKeys))for(const t in n.data)i.includes(t)||r.push(t);const s=[];for(const t of i){const e=o[t],i=n.data[t];s.push({key:{status:\"valid\",value:t},value:e._parse(new ob(n,i,n.path,t)),alwaysSet:t in n.data})}if(this._def.catchall instanceof $b){const t=this._def.unknownKeys;if(\"passthrough\"===t)for(const t of r)s.push({key:{status:\"valid\",value:t},value:{status:\"valid\",value:n.data[t]}});else if(\"strict\"===t)r.length\u003e0\u0026\u0026(H_(n,{code:z_.unrecognized_keys,keys:r}),e.dirty());else if(\"strip\"!==t)throw new Error(\"Internal ZodObject error: invalid unknownKeys value.\")}else{const t=this._def.catchall;for(const e of r){const o=n.data[e];s.push({key:{status:\"valid\",value:e},value:t._parse(new ob(n,o,n.path,e)),alwaysSet:e in n.data})}}return n.common.async?Promise.resolve().then(async()=\u003e{const t=[];for(const e of s){const n=await e.key,o=await e.value;t.push({key:n,value:o,alwaysSet:e.alwaysSet})}return t}).then(t=\u003eZ_.mergeObjectSync(e,t)):Z_.mergeObjectSync(e,s)}get shape(){return this._def.shape()}strict(e){return G_.errToObj,new t({...this._def,unknownKeys:\"strict\",...void 0!==e?{errorMap:(t,n)=\u003e{const o=this._def.errorMap?.(t,n).message??n.defaultError;return\"unrecognized_keys\"===t.code?{message:G_.errToObj(e).message??o}:{message:o}}}:{}})}strip(){return new t({...this._def,unknownKeys:\"strip\"})}passthrough(){return new t({...this._def,unknownKeys:\"passthrough\"})}extend(e){return new t({...this._def,shape:()=\u003e({...this._def.shape(),...e})})}merge(e){return new t({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=\u003e({...this._def.shape(),...e._def.shape()}),typeName:xx.ZodObject})}setKey(t,e){return this.augment({[t]:e})}catchall(e){return new t({...this._def,catchall:e})}pick(e){const n={};for(const t of R_.objectKeys(e))e[t]\u0026\u0026this.shape[t]\u0026\u0026(n[t]=this.shape[t]);return new t({...this._def,shape:()=\u003en})}omit(e){const n={};for(const t of R_.objectKeys(this.shape))e[t]||(n[t]=this.shape[t]);return new t({...this._def,shape:()=\u003en})}deepPartial(){return Vb(this)}partial(e){const n={};for(const t of R_.objectKeys(this.shape)){const o=this.shape[t];e\u0026\u0026!e[t]?n[t]=o:n[t]=o.optional()}return new t({...this._def,shape:()=\u003en})}required(e){const n={};for(const t of R_.objectKeys(this.shape))if(e\u0026\u0026!e[t])n[t]=this.shape[t];else{let e=this.shape[t];for(;e instanceof lx;)e=e._def.innerType;n[t]=e}return new t({...this._def,shape:()=\u003en})}keyof(){return ix(R_.objectKeys(this.shape))}};Wb.create=(t,e)=\u003enew Wb({shape:()=\u003et,unknownKeys:\"strip\",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)}),Wb.strictCreate=(t,e)=\u003enew Wb({shape:()=\u003et,unknownKeys:\"strict\",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)}),Wb.lazycreate=(t,e)=\u003enew Wb({shape:t,unknownKeys:\"strip\",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)});var Hb=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n=this._def.options;if(e.common.async)return Promise.all(n.map(async t=\u003e{const n={...e,common:{...e.common,issues:[]},parent:null};return{result:await t._parseAsync({data:e.data,path:e.path,parent:n}),ctx:n}})).then(function(t){for(const e of t)if(\"valid\"===e.result.status)return e.result;for(const n of t)if(\"dirty\"===n.result.status)return e.common.issues.push(...n.ctx.common.issues),n.result;const n=t.map(t=\u003enew B_(t.ctx.common.issues));return H_(e,{code:z_.invalid_union,unionErrors:n}),q_});{let t;const o=[];for(const i of n){const n={...e,common:{...e.common,issues:[]},parent:null},r=i._parseSync({data:e.data,path:e.path,parent:n});if(\"valid\"===r.status)return r;\"dirty\"!==r.status||t||(t={result:r,ctx:n}),n.common.issues.length\u0026\u0026o.push(n.common.issues)}if(t)return e.common.issues.push(...t.ctx.common.issues),t.result;const i=o.map(t=\u003enew B_(t));return H_(e,{code:z_.invalid_union,unionErrors:i}),q_}}get options(){return this._def.options}};Hb.create=(t,e)=\u003enew Hb({options:t,typeName:xx.ZodUnion,...rb(e)});var Gb=t=\u003et instanceof nx?Gb(t.schema):t instanceof cx?Gb(t.innerType()):t instanceof ox?[t.value]:t instanceof rx?t.options:t instanceof sx?R_.objectValues(t.enum):t instanceof hx?Gb(t._def.innerType):t instanceof zb?[void 0]:t instanceof Fb?[null]:t instanceof lx?[void 0,...Gb(t.unwrap())]:t instanceof dx?[null,...Gb(t.unwrap())]:t instanceof gx||t instanceof yx?Gb(t.unwrap()):t instanceof ux?Gb(t._def.innerType):[],Ub=class t extends ab{_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.object)return H_(e,{code:z_.invalid_type,expected:L_.object,received:e.parsedType}),q_;const n=this.discriminator,o=e.data[n],i=this.optionsMap.get(o);return i?e.common.async?i._parseAsync({data:e.data,path:e.path,parent:e}):i._parseSync({data:e.data,path:e.path,parent:e}):(H_(e,{code:z_.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[n]}),q_)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,n,o){const i=new Map;for(const t of n){const n=Gb(t.shape[e]);if(!n.length)throw new Error(`A discriminator value for key \\`${e}\\` could not be extracted from all schema options`);for(const o of n){if(i.has(o))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(o)}`);i.set(o,t)}}return new t({typeName:xx.ZodDiscriminatedUnion,discriminator:e,options:n,optionsMap:i,...rb(o)})}};function Zb(t,e){const n=D_(t),o=D_(e);if(t===e)return{valid:!0,data:t};if(n===L_.object\u0026\u0026o===L_.object){const n=R_.objectKeys(e),o=R_.objectKeys(t).filter(t=\u003e-1!==n.indexOf(t)),i={...t,...e};for(const n of o){const o=Zb(t[n],e[n]);if(!o.valid)return{valid:!1};i[n]=o.data}return{valid:!0,data:i}}if(n===L_.array\u0026\u0026o===L_.array){if(t.length!==e.length)return{valid:!1};const n=[];for(let o=0;o\u003ct.length;o++){const i=Zb(t[o],e[o]);if(!i.valid)return{valid:!1};n.push(i.data)}return{valid:!0,data:n}}return n===L_.date\u0026\u0026o===L_.date\u0026\u0026+t===+e?{valid:!0,data:t}:{valid:!1}}var qb=class extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t),o=(t,o)=\u003e{if(Q_(t)||Q_(o))return q_;const i=Zb(t.value,o.value);return i.valid?((tb(t)||tb(o))\u0026\u0026e.dirty(),{status:e.value,value:i.data}):(H_(n,{code:z_.invalid_intersection_types}),q_)};return n.common.async?Promise.all([this._def.left._parseAsync({data:n.data,path:n.path,parent:n}),this._def.right._parseAsync({data:n.data,path:n.path,parent:n})]).then(([t,e])=\u003eo(t,e)):o(this._def.left._parseSync({data:n.data,path:n.path,parent:n}),this._def.right._parseSync({data:n.data,path:n.path,parent:n}))}};qb.create=(t,e,n)=\u003enew qb({left:t,right:e,typeName:xx.ZodIntersection,...rb(n)});var Jb=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.array)return H_(n,{code:z_.invalid_type,expected:L_.array,received:n.parsedType}),q_;if(n.data.length\u003cthis._def.items.length)return H_(n,{code:z_.too_small,minimum:this._def.items.length,inclusive:!0,exact:!1,type:\"array\"}),q_;!this._def.rest\u0026\u0026n.data.length\u003ethis._def.items.length\u0026\u0026(H_(n,{code:z_.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:\"array\"}),e.dirty());const o=[...n.data].map((t,e)=\u003e{const o=this._def.items[e]||this._def.rest;return o?o._parse(new ob(n,t,n.path,e)):null}).filter(t=\u003e!!t);return n.common.async?Promise.all(o).then(t=\u003eZ_.mergeArray(e,t)):Z_.mergeArray(e,o)}get items(){return this._def.items}rest(e){return new t({...this._def,rest:e})}};Jb.create=(t,e)=\u003e{if(!Array.isArray(t))throw new Error(\"You must pass an array of schemas to z.tuple([ ... ])\");return new Jb({items:t,typeName:xx.ZodTuple,rest:null,...rb(e)})};var Kb=class t extends ab{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.object)return H_(n,{code:z_.invalid_type,expected:L_.object,received:n.parsedType}),q_;const o=[],i=this._def.keyType,r=this._def.valueType;for(const t in n.data)o.push({key:i._parse(new ob(n,t,n.path,t)),value:r._parse(new ob(n,n.data[t],n.path,t)),alwaysSet:t in n.data});return n.common.async?Z_.mergeObjectAsync(e,o):Z_.mergeObjectSync(e,o)}get element(){return this._def.valueType}static create(e,n,o){return new t(n instanceof ab?{keyType:e,valueType:n,typeName:xx.ZodRecord,...rb(o)}:{keyType:Rb.create(),valueType:e,typeName:xx.ZodRecord,...rb(n)})}},Qb=class extends ab{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.map)return H_(n,{code:z_.invalid_type,expected:L_.map,received:n.parsedType}),q_;const o=this._def.keyType,i=this._def.valueType,r=[...n.data.entries()].map(([t,e],r)=\u003e({key:o._parse(new ob(n,t,n.path,[r,\"key\"])),value:i._parse(new ob(n,e,n.path,[r,\"value\"]))}));if(n.common.async){const t=new Map;return Promise.resolve().then(async()=\u003e{for(const n of r){const o=await n.key,i=await n.value;if(\"aborted\"===o.status||\"aborted\"===i.status)return q_;\"dirty\"!==o.status\u0026\u0026\"dirty\"!==i.status||e.dirty(),t.set(o.value,i.value)}return{status:e.value,value:t}})}{const t=new Map;for(const n of r){const o=n.key,i=n.value;if(\"aborted\"===o.status||\"aborted\"===i.status)return q_;\"dirty\"!==o.status\u0026\u0026\"dirty\"!==i.status||e.dirty(),t.set(o.value,i.value)}return{status:e.value,value:t}}}};Qb.create=(t,e,n)=\u003enew Qb({valueType:e,keyType:t,typeName:xx.ZodMap,...rb(n)});var tx=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.set)return H_(n,{code:z_.invalid_type,expected:L_.set,received:n.parsedType}),q_;const o=this._def;null!==o.minSize\u0026\u0026n.data.size\u003co.minSize.value\u0026\u0026(H_(n,{code:z_.too_small,minimum:o.minSize.value,type:\"set\",inclusive:!0,exact:!1,message:o.minSize.message}),e.dirty()),null!==o.maxSize\u0026\u0026n.data.size\u003eo.maxSize.value\u0026\u0026(H_(n,{code:z_.too_big,maximum:o.maxSize.value,type:\"set\",inclusive:!0,exact:!1,message:o.maxSize.message}),e.dirty());const i=this._def.valueType;function r(t){const n=new Set;for(const o of t){if(\"aborted\"===o.status)return q_;\"dirty\"===o.status\u0026\u0026e.dirty(),n.add(o.value)}return{status:e.value,value:n}}const s=[...n.data.values()].map((t,e)=\u003ei._parse(new ob(n,t,n.path,e)));return n.common.async?Promise.all(s).then(t=\u003er(t)):r(s)}min(e,n){return new t({...this._def,minSize:{value:e,message:G_.toString(n)}})}max(e,n){return new t({...this._def,maxSize:{value:e,message:G_.toString(n)}})}size(t,e){return this.min(t,e).max(t,e)}nonempty(t){return this.min(1,t)}};tx.create=(t,e)=\u003enew tx({valueType:t,minSize:null,maxSize:null,typeName:xx.ZodSet,...rb(e)});var ex=class t extends ab{constructor(){super(...arguments),this.validate=this.implement}_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.function)return H_(e,{code:z_.invalid_type,expected:L_.function,received:e.parsedType}),q_;function n(t,n){return V_({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,X_(),j_].filter(t=\u003e!!t),issueData:{code:z_.invalid_arguments,argumentsError:n}})}function o(t,n){return V_({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,X_(),j_].filter(t=\u003e!!t),issueData:{code:z_.invalid_return_type,returnTypeError:n}})}const i={errorMap:e.common.contextualErrorMap},r=e.data;if(this._def.returns instanceof ax){const t=this;return K_(async function(...e){const s=new B_([]),a=await t._def.args.parseAsync(e,i).catch(t=\u003e{throw s.addIssue(n(e,t)),s}),c=await Reflect.apply(r,this,a);return await t._def.returns._def.type.parseAsync(c,i).catch(t=\u003e{throw s.addIssue(o(c,t)),s})})}{const t=this;return K_(function(...e){const s=t._def.args.safeParse(e,i);if(!s.success)throw new B_([n(e,s.error)]);const a=Reflect.apply(r,this,s.data),c=t._def.returns.safeParse(a,i);if(!c.success)throw new B_([o(a,c.error)]);return c.data})}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new t({...this._def,args:Jb.create(e).rest(jb.create())})}returns(e){return new t({...this._def,returns:e})}implement(t){return this.parse(t)}strictImplement(t){return this.parse(t)}static create(e,n,o){return new t({args:e||Jb.create([]).rest(jb.create()),returns:n||jb.create(),typeName:xx.ZodFunction,...rb(o)})}},nx=class extends ab{get schema(){return this._def.getter()}_parse(t){const{ctx:e}=this._processInputParams(t);return this._def.getter()._parse({data:e.data,path:e.path,parent:e})}};nx.create=(t,e)=\u003enew nx({getter:t,typeName:xx.ZodLazy,...rb(e)});var ox=class extends ab{_parse(t){if(t.data!==this._def.value){const e=this._getOrReturnCtx(t);return H_(e,{received:e.data,code:z_.invalid_literal,expected:this._def.value}),q_}return{status:\"valid\",value:t.data}}get value(){return this._def.value}};function ix(t,e){return new rx({values:t,typeName:xx.ZodEnum,...rb(e)})}ox.create=(t,e)=\u003enew ox({value:t,typeName:xx.ZodLiteral,...rb(e)});var rx=class t extends ab{_parse(t){if(\"string\"!=typeof t.data){const e=this._getOrReturnCtx(t),n=this._def.values;return H_(e,{expected:R_.joinValues(n),received:e.parsedType,code:z_.invalid_type}),q_}if(this._cache||(this._cache=new Set(this._def.values)),!this._cache.has(t.data)){const e=this._getOrReturnCtx(t),n=this._def.values;return H_(e,{received:e.data,code:z_.invalid_enum_value,options:n}),q_}return K_(t.data)}get options(){return this._def.values}get enum(){const t={};for(const e of this._def.values)t[e]=e;return t}get Values(){const t={};for(const e of this._def.values)t[e]=e;return t}get Enum(){const t={};for(const e of this._def.values)t[e]=e;return t}extract(e,n=this._def){return t.create(e,{...this._def,...n})}exclude(e,n=this._def){return t.create(this.options.filter(t=\u003e!e.includes(t)),{...this._def,...n})}};rx.create=ix;var sx=class extends ab{_parse(t){const e=R_.getValidEnumValues(this._def.values),n=this._getOrReturnCtx(t);if(n.parsedType!==L_.string\u0026\u0026n.parsedType!==L_.number){const t=R_.objectValues(e);return H_(n,{expected:R_.joinValues(t),received:n.parsedType,code:z_.invalid_type}),q_}if(this._cache||(this._cache=new Set(R_.getValidEnumValues(this._def.values))),!this._cache.has(t.data)){const t=R_.objectValues(e);return H_(n,{received:n.data,code:z_.invalid_enum_value,options:t}),q_}return K_(t.data)}get enum(){return this._def.values}};sx.create=(t,e)=\u003enew sx({values:t,typeName:xx.ZodNativeEnum,...rb(e)});var ax=class extends ab{unwrap(){return this._def.type}_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.promise\u0026\u0026!1===e.common.async)return H_(e,{code:z_.invalid_type,expected:L_.promise,received:e.parsedType}),q_;const n=e.parsedType===L_.promise?e.data:Promise.resolve(e.data);return K_(n.then(t=\u003ethis._def.type.parseAsync(t,{path:e.path,errorMap:e.common.contextualErrorMap})))}};ax.create=(t,e)=\u003enew ax({type:t,typeName:xx.ZodPromise,...rb(e)});var cx=class extends ab{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===xx.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(t){const{status:e,ctx:n}=this._processInputParams(t),o=this._def.effect||null,i={addIssue:t=\u003e{H_(n,t),t.fatal?e.abort():e.dirty()},get path(){return n.path}};if(i.addIssue=i.addIssue.bind(i),\"preprocess\"===o.type){const t=o.transform(n.data,i);if(n.common.async)return Promise.resolve(t).then(async t=\u003e{if(\"aborted\"===e.value)return q_;const o=await this._def.schema._parseAsync({data:t,path:n.path,parent:n});return\"aborted\"===o.status?q_:\"dirty\"===o.status||\"dirty\"===e.value?J_(o.value):o});{if(\"aborted\"===e.value)return q_;const o=this._def.schema._parseSync({data:t,path:n.path,parent:n});return\"aborted\"===o.status?q_:\"dirty\"===o.status||\"dirty\"===e.value?J_(o.value):o}}if(\"refinement\"===o.type){const t=t=\u003e{const e=o.refinement(t,i);if(n.common.async)return Promise.resolve(e);if(e instanceof Promise)throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");return t};if(!1===n.common.async){const o=this._def.schema._parseSync({data:n.data,path:n.path,parent:n});return\"aborted\"===o.status?q_:(\"dirty\"===o.status\u0026\u0026e.dirty(),t(o.value),{status:e.value,value:o.value})}return this._def.schema._parseAsync({data:n.data,path:n.path,parent:n}).then(n=\u003e\"aborted\"===n.status?q_:(\"dirty\"===n.status\u0026\u0026e.dirty(),t(n.value).then(()=\u003e({status:e.value,value:n.value}))))}if(\"transform\"===o.type){if(!1===n.common.async){const t=this._def.schema._parseSync({data:n.data,path:n.path,parent:n});if(!eb(t))return q_;const r=o.transform(t.value,i);if(r instanceof Promise)throw new Error(\"Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.\");return{status:e.value,value:r}}return this._def.schema._parseAsync({data:n.data,path:n.path,parent:n}).then(t=\u003eeb(t)?Promise.resolve(o.transform(t.value,i)).then(t=\u003e({status:e.value,value:t})):q_)}R_.assertNever(o)}};cx.create=(t,e,n)=\u003enew cx({schema:t,typeName:xx.ZodEffects,effect:e,...rb(n)}),cx.createWithPreprocess=(t,e,n)=\u003enew cx({schema:e,effect:{type:\"preprocess\",transform:t},typeName:xx.ZodEffects,...rb(n)});var lx=class extends ab{_parse(t){return this._getType(t)===L_.undefined?K_(void 0):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}};lx.create=(t,e)=\u003enew lx({innerType:t,typeName:xx.ZodOptional,...rb(e)});var dx=class extends ab{_parse(t){return this._getType(t)===L_.null?K_(null):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}};dx.create=(t,e)=\u003enew dx({innerType:t,typeName:xx.ZodNullable,...rb(e)});var hx=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t);let n=e.data;return e.parsedType===L_.undefined\u0026\u0026(n=this._def.defaultValue()),this._def.innerType._parse({data:n,path:e.path,parent:e})}removeDefault(){return this._def.innerType}};hx.create=(t,e)=\u003enew hx({innerType:t,typeName:xx.ZodDefault,defaultValue:\"function\"==typeof e.default?e.default:()=\u003ee.default,...rb(e)});var ux=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n={...e,common:{...e.common,issues:[]}},o=this._def.innerType._parse({data:n.data,path:n.path,parent:{...n}});return nb(o)?o.then(t=\u003e({status:\"valid\",value:\"valid\"===t.status?t.value:this._def.catchValue({get error(){return new B_(n.common.issues)},input:n.data})})):{status:\"valid\",value:\"valid\"===o.status?o.value:this._def.catchValue({get error(){return new B_(n.common.issues)},input:n.data})}}removeCatch(){return this._def.innerType}};ux.create=(t,e)=\u003enew ux({innerType:t,typeName:xx.ZodCatch,catchValue:\"function\"==typeof e.catch?e.catch:()=\u003ee.catch,...rb(e)});var px=class extends ab{_parse(t){if(this._getType(t)!==L_.nan){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.nan,received:e.parsedType}),q_}return{status:\"valid\",value:t.data}}};px.create=t=\u003enew px({typeName:xx.ZodNaN,...rb(t)});var mx=Symbol(\"zod_brand\"),gx=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n=e.data;return this._def.type._parse({data:n,path:e.path,parent:e})}unwrap(){return this._def.type}},fx=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.common.async){return(async()=\u003e{const t=await this._def.in._parseAsync({data:n.data,path:n.path,parent:n});return\"aborted\"===t.status?q_:\"dirty\"===t.status?(e.dirty(),J_(t.value)):this._def.out._parseAsync({data:t.value,path:n.path,parent:n})})()}{const t=this._def.in._parseSync({data:n.data,path:n.path,parent:n});return\"aborted\"===t.status?q_:\"dirty\"===t.status?(e.dirty(),{status:\"dirty\",value:t.value}):this._def.out._parseSync({data:t.value,path:n.path,parent:n})}}static create(e,n){return new t({in:e,out:n,typeName:xx.ZodPipeline})}},yx=class extends ab{_parse(t){const e=this._def.innerType._parse(t),n=t=\u003e(eb(t)\u0026\u0026(t.value=Object.freeze(t.value)),t);return nb(e)?e.then(t=\u003en(t)):n(e)}unwrap(){return this._def.innerType}};function _x(t,e){const n=\"function\"==typeof t?t(e):\"string\"==typeof t?{message:t}:t;return\"string\"==typeof n?{message:n}:n}function bx(t,e={},n){return t?Bb.create().superRefine((o,i)=\u003e{const r=t(o);if(r instanceof Promise)return r.then(t=\u003e{if(!t){const t=_x(e,o),r=t.fatal??n??!0;i.addIssue({code:\"custom\",...t,fatal:r})}});if(!r){const t=_x(e,o),r=t.fatal??n??!0;i.addIssue({code:\"custom\",...t,fatal:r})}}):Bb.create()}yx.create=(t,e)=\u003enew yx({innerType:t,typeName:xx.ZodReadonly,...rb(e)});var xx,vx,Sx={object:Wb.lazycreate};(vx=xx||(xx={})).ZodString=\"ZodString\",vx.ZodNumber=\"ZodNumber\",vx.ZodNaN=\"ZodNaN\",vx.ZodBigInt=\"ZodBigInt\",vx.ZodBoolean=\"ZodBoolean\",vx.ZodDate=\"ZodDate\",vx.ZodSymbol=\"ZodSymbol\",vx.ZodUndefined=\"ZodUndefined\",vx.ZodNull=\"ZodNull\",vx.ZodAny=\"ZodAny\",vx.ZodUnknown=\"ZodUnknown\",vx.ZodNever=\"ZodNever\",vx.ZodVoid=\"ZodVoid\",vx.ZodArray=\"ZodArray\",vx.ZodObject=\"ZodObject\",vx.ZodUnion=\"ZodUnion\",vx.ZodDiscriminatedUnion=\"ZodDiscriminatedUnion\",vx.ZodIntersection=\"ZodIntersection\",vx.ZodTuple=\"ZodTuple\",vx.ZodRecord=\"ZodRecord\",vx.ZodMap=\"ZodMap\",vx.ZodSet=\"ZodSet\",vx.ZodFunction=\"ZodFunction\",vx.ZodLazy=\"ZodLazy\",vx.ZodLiteral=\"ZodLiteral\",vx.ZodEnum=\"ZodEnum\",vx.ZodEffects=\"ZodEffects\",vx.ZodNativeEnum=\"ZodNativeEnum\",vx.ZodOptional=\"ZodOptional\",vx.ZodNullable=\"ZodNullable\",vx.ZodDefault=\"ZodDefault\",vx.ZodCatch=\"ZodCatch\",vx.ZodPromise=\"ZodPromise\",vx.ZodBranded=\"ZodBranded\",vx.ZodPipeline=\"ZodPipeline\",vx.ZodReadonly=\"ZodReadonly\";var Ix=(t,e={message:`Input not instance of ${t.name}`})=\u003ebx(e=\u003ee instanceof t,e),Cx=Rb.create,Px=Ab.create,Mx=px.create,Nx=Ob.create,wx=kb.create,Tx=Lb.create,Rx=Db.create,Ex=zb.create,Ax=Fb.create,Ox=Bb.create,kx=jb.create,Lx=$b.create,Dx=Yb.create,zx=Xb.create,Fx=Wb.create,Bx=Wb.strictCreate,jx=Hb.create,$x=Ub.create,Yx=qb.create,Xx=Jb.create,Vx=Kb.create,Wx=Qb.create,Hx=tx.create,Gx=ex.create,Ux=nx.create,Zx=ox.create,qx=rx.create,Jx=sx.create,Kx=ax.create,Qx=cx.create,tv=lx.create,ev=dx.create,nv=cx.createWithPreprocess,ov=fx.create,iv=()=\u003eCx().optional(),rv=()=\u003ePx().optional(),sv=()=\u003ewx().optional(),av={string:t=\u003eRb.create({...t,coerce:!0}),number:t=\u003eAb.create({...t,coerce:!0}),boolean:t=\u003ekb.create({...t,coerce:!0}),bigint:t=\u003eOb.create({...t,coerce:!0}),date:t=\u003eLb.create({...t,coerce:!0})},cv=q_,lv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"Ω\").value),dv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"F\").value).transform(t=\u003eNumber.parseFloat(t.toPrecision(12))),hv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"H\").value),uv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"V\").value),pv=k_.string().or(k_.number()).transform(t=\u003eT_(t).value),mv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"Hz\").value),gv=pv,fv=k_.string().or(k_.number()).transform(t=\u003eT_(t,\"A\").value),yv=k_.string().or(k_.number()).transform(t=\u003eT_(t).value),_v=yv,bv=yv,xv=k_.string().datetime(),vv=k_.string().or(k_.number()).transform(t=\u003e\"number\"==typeof t?t:t.endsWith(\"deg\")?Number.parseFloat(t.split(\"deg\")[0]):t.endsWith(\"rad\")?180*Number.parseFloat(t.split(\"rad\")[0])/Math.PI:Number.parseFloat(t)),Sv=k_.number().or(k_.string().endsWith(\"mAh\")).transform(t=\u003e{if(\"string\"==typeof t){const e=t.replace(\"mAh\",\"\"),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error(\"Invalid capacity\");return n}return t}).describe(\"Battery capacity in mAh\"),Iv=k_.object({x:gv,y:gv}),Cv=Iv,Pv=k_.object({x:gv,y:gv,z:gv}),Mv=Pv,Nv=k_.object({width:k_.number(),height:k_.number()}),wv=t=\u003ek_.string().optional().default(()=\u003e`${t}_${(t=\u003e{const e=\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";return Array.from({length:t},()=\u003ee[Math.floor(62*Math.random())]).join(\"\")})(10)}`),Tv=k_.enum([\"top_left\",\"top_center\",\"top_right\",\"center_left\",\"center\",\"center_right\",\"bottom_left\",\"bottom_center\",\"bottom_right\"]),Rv=k_.enum([\"top_silkscreen\",\"bottom_silkscreen\",\"top_copper\",\"bottom_copper\",\"top_soldermask\",\"bottom_soldermask\",\"top_fabrication_note\",\"bottom_fabrication_note\",\"top_user_note\",\"bottom_user_note\",\"top_courtyard\",\"bottom_courtyard\",\"inner1_copper\",\"inner2_copper\",\"inner3_copper\",\"inner4_copper\",\"inner5_copper\",\"inner6_copper\",\"inner7_copper\",\"inner8_copper\",\"edge_cuts\",\"drill\"]),Ev=k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()}),Av=Iv.extend({rotation:vv.optional()}),Ov=k_.object({size:Iv.optional(),thickness:gv.optional()}),kv=k_.object({font:Ov.optional()}),Lv=k_.object({value:k_.string(),at:Av.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:kv.optional()}),Dv=k_.object({Reference:Lv.optional(),Value:Lv.optional(),Datasheet:Lv.optional(),Description:Lv.optional()}),zv=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),Fv=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:Av.optional(),size:Iv.optional(),drill:gv.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),Bv=k_.object({path:k_.string(),offset:Pv.optional(),scale:Pv.optional(),rotate:Pv.optional()}),jv=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:Dv.optional(),attributes:zv.optional(),pads:k_.array(Fv).optional(),embeddedFonts:k_.boolean().optional(),model:Bv.optional()}),$v=k_.object({hide:k_.boolean().optional()}),Yv=k_.object({offset:gv.optional(),hide:k_.boolean().optional()}),Xv=k_.object({font:Ov.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),Vv=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:Av.optional(),effects:Xv.optional()}),Wv=k_.object({Reference:Vv.optional(),Value:Vv.optional(),Footprint:Vv.optional(),Datasheet:Vv.optional(),Description:Vv.optional(),ki_keywords:Vv.optional(),ki_fp_filters:Vv.optional()}),Hv=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:$v.optional(),pinNames:Yv.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:Wv.optional(),embeddedFonts:k_.boolean().optional()}),Gv=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),Uv=k_.enum([\"jlcpcb\",\"macrofab\",\"pcbway\",\"digikey\",\"mouser\",\"lcsc\"]),Zv=k_.object({type:k_.literal(\"source_component\"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(Uv,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),qv=Zv.extend({ftype:k_.literal(\"simple_capacitor\"),capacitance:dv,max_voltage_rating:uv.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:gv.optional()}),Jv=Zv.extend({ftype:k_.literal(\"simple_resistor\"),resistance:lv,display_resistance:k_.string().optional()}),Kv=Zv.extend({ftype:k_.literal(\"simple_diode\")}),Qv=Zv.extend({ftype:k_.literal(\"simple_fiducial\")}),tS=Kv.extend({ftype:k_.literal(\"simple_led\"),color:k_.string().optional(),wavelength:k_.string().optional()}),eS=Zv.extend({ftype:k_.literal(\"simple_ground\")}),nS=Zv.extend({ftype:k_.literal(\"simple_chip\")}),oS=Zv.extend({ftype:k_.literal(\"simple_power_source\"),voltage:uv}),iS=Zv.extend({ftype:k_.literal(\"simple_current_source\"),current:fv,frequency:mv.optional(),peak_to_peak_current:fv.optional(),wave_shape:k_.enum([\"sine\",\"square\",\"triangle\",\"sawtooth\",\"dc\"]).optional().default(\"dc\"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),rS=Zv.extend({ftype:k_.literal(\"simple_fuse\"),current_rating_amps:k_.number().describe(\"Nominal current in amps the fuse is rated for\"),voltage_rating_volts:k_.number().describe(\"Voltage rating in volts, e.g. ±5V would be 5\")}),sS=Zv.extend({ftype:k_.literal(\"simple_ammeter\")}),aS=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),cS=Zv.extend({ftype:k_.literal(\"simple_battery\"),capacity:Sv}),lS=Zv.extend({ftype:k_.literal(\"simple_inductor\"),inductance:hv,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),dS=Zv.extend({ftype:k_.literal(\"simple_push_button\")}),hS=Zv.extend({ftype:k_.literal(\"simple_potentiometer\"),max_resistance:lv,display_max_resistance:k_.string().optional()}),uS=Zv.extend({ftype:k_.literal(\"simple_crystal\"),frequency:k_.number().describe(\"Frequency in Hz\"),load_capacitance:k_.number().optional().describe(\"Load capacitance in pF\"),pin_variant:k_.enum([\"two_pin\",\"four_pin\"]).optional()}),pS=Zv.extend({ftype:k_.literal(\"simple_pin_header\"),pin_count:k_.number(),gender:k_.enum([\"male\",\"female\"]).optional().default(\"male\")}),mS=Zv.extend({ftype:k_.literal(\"simple_connector\"),standard:k_.enum([\"usb_c\",\"m2\"]).optional()}),gS=Zv.extend({ftype:k_.literal(\"simple_pinout\")}),fS=Zv.extend({ftype:k_.literal(\"simple_resonator\"),load_capacitance:dv,equivalent_series_resistance:lv.optional(),frequency:mv}),yS=Zv.extend({ftype:k_.literal(\"simple_transistor\"),transistor_type:k_.enum([\"npn\",\"pnp\"])}),_S=Zv.extend({ftype:k_.literal(\"simple_test_point\"),footprint_variant:k_.enum([\"pad\",\"through_hole\"]).optional(),pad_shape:k_.enum([\"rect\",\"circle\"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),bS=Zv.extend({ftype:k_.literal(\"simple_mosfet\"),channel_type:k_.enum([\"n\",\"p\"]),mosfet_mode:k_.enum([\"enhancement\",\"depletion\"])}),xS=Zv.extend({ftype:k_.literal(\"simple_op_amp\")}),vS=Zv.extend({ftype:k_.literal(\"simple_switch\")}),SS=k_.object({type:k_.literal(\"source_project_metadata\"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),source_filesystem_md5_hash:k_.string().optional(),created_at:xv.optional()}),IS=Gv.extend({type:k_.literal(\"source_missing_property_error\"),source_missing_property_error_id:wv(\"source_missing_property_error\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_missing_property_error\").default(\"source_missing_property_error\")}).describe(\"The source code is missing a property\"),CS=Gv.extend({type:k_.literal(\"source_failed_to_create_component_error\"),source_failed_to_create_component_error_id:wv(\"source_failed_to_create_component_error\"),error_type:k_.literal(\"source_failed_to_create_component_error\").default(\"source_failed_to_create_component_error\"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe(\"Error emitted when a component fails to be constructed\"),PS=Gv.extend({type:k_.literal(\"source_invalid_component_property_error\"),source_invalid_component_property_error_id:wv(\"source_invalid_component_property_error\"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_invalid_component_property_error\").default(\"source_invalid_component_property_error\")}).describe(\"The source component property is invalid\"),MS=Gv.extend({type:k_.literal(\"source_trace_not_connected_error\"),source_trace_not_connected_error_id:wv(\"source_trace_not_connected_error\"),error_type:k_.literal(\"source_trace_not_connected_error\").default(\"source_trace_not_connected_error\"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe(\"Occurs when a source trace selector does not match any ports\"),NS=k_.object({type:k_.literal(\"source_property_ignored_warning\"),source_property_ignored_warning_id:wv(\"source_property_ignored_warning\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_property_ignored_warning\").default(\"source_property_ignored_warning\"),message:k_.string()}).describe(\"The source property was ignored\"),wS=k_.object({type:k_.literal(\"source_pin_missing_trace_warning\"),source_pin_missing_trace_warning_id:wv(\"source_pin_missing_trace_warning\"),warning_type:k_.literal(\"source_pin_missing_trace_warning\").default(\"source_pin_missing_trace_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component pin is missing a trace connection\"),TS=k_.object({type:k_.literal(\"source_missing_manufacturer_part_number_warning\"),source_missing_manufacturer_part_number_warning_id:wv(\"source_missing_manufacturer_part_number_warning\"),warning_type:k_.literal(\"source_missing_manufacturer_part_number_warning\").default(\"source_missing_manufacturer_part_number_warning\"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a standard connector is missing manufacturer part number\"),RS=k_.object({type:k_.literal(\"source_refdes_convention_warning\"),source_refdes_convention_warning_id:wv(\"source_refdes_convention_warning\"),warning_type:k_.literal(\"source_refdes_convention_warning\").default(\"source_refdes_convention_warning\"),message:k_.string(),source_component_id:k_.string(),refdes:k_.string(),source_component_ftype:k_.string(),expected_prefixes:k_.array(k_.string()),actual_prefix:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component reference designator does not match the component type convention\"),ES=Zv.extend({ftype:k_.literal(\"simple_voltage_probe\")}),AS=Zv.extend({ftype:k_.literal(\"interconnect\")}),OS=Gv.extend({type:k_.literal(\"source_i2c_misconfigured_error\"),source_i2c_misconfigured_error_id:wv(\"source_i2c_misconfigured_error\"),error_type:k_.literal(\"source_i2c_misconfigured_error\").default(\"source_i2c_misconfigured_error\"),source_port_ids:k_.array(k_.string())}).describe(\"Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net\"),kS=Gv.extend({type:k_.literal(\"source_component_misconfigured_error\"),source_component_misconfigured_error_id:wv(\"source_component_misconfigured_error\"),error_type:k_.literal(\"source_component_misconfigured_error\").default(\"source_component_misconfigured_error\"),source_component_ids:k_.array(k_.string()),source_port_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when one or more source components have an invalid or conflicting configuration\"),LS=Zv.extend({ftype:k_.literal(\"simple_voltage_source\"),voltage:uv,frequency:mv.optional(),peak_to_peak_voltage:uv.optional(),wave_shape:k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]).optional(),phase:vv.optional(),duty_cycle:k_.number().optional().describe(\"Duty cycle as a fraction (0 to 1)\"),pulse_delay:bv.optional(),rise_time:bv.optional(),fall_time:bv.optional(),pulse_width:bv.optional(),period:bv.optional()}),DS=k_.union([Jv,qv,Kv,Qv,tS,eS,nS,oS,iS,sS,cS,lS,dS,hS,uS,pS,mS,gS,fS,vS,yS,_S,bS,xS,rS,ES,AS,LS,SS,IS,PS,CS,MS,NS,wS,TS,RS,OS,kS]),zS=k_.object({type:k_.literal(\"source_port\"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(aS),FS=k_.object({type:k_.literal(\"source_component_internal_connection\"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),BS=k_.object({type:k_.literal(\"source_trace\"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),name:k_.string().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),jS=k_.object({type:k_.literal(\"source_group\"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),$S=k_.object({type:k_.literal(\"source_net\"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),YS=k_.object({type:k_.literal(\"source_board\"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe(\"Defines a board in the source domain\"),XS=Gv.extend({type:k_.literal(\"source_ambiguous_port_reference\"),source_ambiguous_port_reference_id:wv(\"source_ambiguous_port_reference\"),error_type:k_.literal(\"source_ambiguous_port_reference\").default(\"source_ambiguous_port_reference\"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous\"),VS=k_.object({type:k_.literal(\"source_pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane in the source domain\"),WS=[\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\",\"inner7\",\"inner8\"],HS=k_.enum(WS),GS=HS.or(k_.object({name:HS})).transform(t=\u003e\"string\"==typeof t?t:t.name),US=k_.enum([\"top\",\"bottom\"]),ZS=k_.object({type:k_.literal(\"source_manually_placed_via\"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe(\"Defines a via that is manually placed in the source domain\"),qS=k_.object({type:k_.literal(\"source_unnamed_trace_warning\"),source_unnamed_trace_warning_id:wv(\"source_unnamed_trace_warning\"),warning_type:k_.literal(\"source_unnamed_trace_warning\").default(\"source_unnamed_trace_warning\"),message:k_.string(),source_trace_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source trace is missing a name\"),JS=k_.object({type:k_.literal(\"source_no_power_pin_defined_warning\"),source_no_power_pin_defined_warning_id:wv(\"source_no_power_pin_defined_warning\"),warning_type:k_.literal(\"source_no_power_pin_defined_warning\").default(\"source_no_power_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports with requires_power=true\"),KS=k_.object({type:k_.literal(\"source_no_ground_pin_defined_warning\"),source_no_ground_pin_defined_warning_id:wv(\"source_no_ground_pin_defined_warning\"),warning_type:k_.literal(\"source_no_ground_pin_defined_warning\").default(\"source_no_ground_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports marked as ground pins\"),QS=k_.object({type:k_.literal(\"source_component_pins_underspecified_warning\"),source_component_pins_underspecified_warning_id:wv(\"source_component_pins_underspecified_warning\"),warning_type:k_.literal(\"source_component_pins_underspecified_warning\").default(\"source_component_pins_underspecified_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when all ports on a source component are underspecified\"),tI=Gv.extend({type:k_.literal(\"source_pin_must_be_connected_error\"),source_pin_must_be_connected_error_id:wv(\"source_pin_must_be_connected_error\"),error_type:k_.literal(\"source_pin_must_be_connected_error\").default(\"source_pin_must_be_connected_error\"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pin with mustBeConnected attribute is not connected to any trace\"),eI=Gv.extend({type:k_.literal(\"unknown_error_finding_part\"),unknown_error_finding_part_id:wv(\"unknown_error_finding_part\"),error_type:k_.literal(\"unknown_error_finding_part\").default(\"unknown_error_finding_part\"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when an unexpected error occurs while finding a part\"),nI=k_.object({type:k_.literal(\"source_part_not_found_warning\"),source_part_not_found_warning_id:wv(\"source_part_not_found_warning\"),warning_type:k_.literal(\"source_part_not_found_warning\").default(\"source_part_not_found_warning\"),message:k_.string(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:Uv.optional(),manufacturer_part_number:k_.string().optional(),supplier_part_number:k_.string().optional(),part_name:k_.string().optional()}).describe(\"Warning emitted when a requested part can not be found\"),oI=k_.object({type:k_.literal(\"schematic_box\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:gv,height:gv,is_dashed:k_.boolean().default(!1),x:gv,y:gv,subcircuit_id:k_.string().optional()}).describe(\"Draws a box on the schematic\"),iI=k_.object({type:k_.literal(\"schematic_path\"),schematic_path_id:wv(\"schematic_path\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),is_dashed:k_.boolean().default(!1),stroke_width:gv.nullable().optional(),stroke_color:k_.string().optional(),dash_length:gv.optional(),dash_gap:gv.optional(),points:k_.array(Iv),subcircuit_id:k_.string().optional()}),rI=k_.record(k_.object({left_margin:pv.optional(),right_margin:pv.optional(),top_margin:pv.optional(),bottom_margin:pv.optional()})),sI=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),aI=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional()}),cI=k_.union([sI,aI]),lI=k_.object({type:k_.literal(\"schematic_component\"),size:Nv,center:Iv,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_sheet_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),pin_spacing:pv.optional(),pin_styles:rI.optional(),box_width:pv.optional(),symbol_name:k_.string().optional(),port_arrangement:cI.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),dI=k_.object({kicad_symbol:Hv.optional()}).catchall(k_.unknown()),hI=k_.object({type:k_.literal(\"schematic_symbol\"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:dI.optional()}).describe(\"Defines a named schematic symbol that can be referenced by components.\"),uI=k_.object({type:k_.literal(\"schematic_line\"),schematic_line_id:wv(\"schematic_line\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:gv,y1:gv,x2:gv,y2:gv,stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),dash_length:gv.optional(),dash_gap:gv.optional(),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled line on the schematic\"),pI=k_.object({type:k_.literal(\"schematic_rect\"),schematic_rect_id:wv(\"schematic_rect\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,width:gv,height:gv,rotation:vv.default(0),stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled rectangle on the schematic\"),mI=k_.object({type:k_.literal(\"schematic_circle\"),schematic_circle_id:wv(\"schematic_circle\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,radius:gv,stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled circle on the schematic\"),gI=k_.object({type:k_.literal(\"schematic_arc\"),schematic_arc_id:wv(\"schematic_arc\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,radius:gv,start_angle_degrees:vv,end_angle_degrees:vv,direction:k_.enum([\"clockwise\",\"counterclockwise\"]).default(\"counterclockwise\"),stroke_width:gv.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled arc on the schematic\"),fI=k_.object({type:k_.literal(\"schematic_trace\"),schematic_trace_id:k_.string(),schematic_sheet_id:k_.string().optional(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),yI=k_.enum([\"center\",\"left\",\"right\",\"top\",\"bottom\"]),_I=k_.object({type:k_.literal(\"schematic_text\"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:gv,y:gv}),rotation:k_.number().default(0),anchor:k_.union([yI.describe(\"legacy\"),Tv]).default(\"center\"),color:k_.string().default(\"#000000\"),subcircuit_id:k_.string().optional()}),bI=k_.object({type:k_.literal(\"schematic_port\"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),center:Iv,facing_direction:k_.enum([\"up\",\"down\",\"left\",\"right\"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe(\"Defines a port on a schematic component\"),xI=k_.object({type:k_.literal(\"schematic_net_label\"),schematic_net_label_id:wv(\"schematic_net_label\"),schematic_sheet_id:k_.string().optional(),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:Iv,anchor_position:Iv.optional(),anchor_side:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),vI=Gv.extend({type:k_.literal(\"schematic_error\"),schematic_error_id:k_.string(),error_type:k_.literal(\"schematic_port_not_found\").default(\"schematic_port_not_found\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic error on the schematic\"),SI=Gv.extend({type:k_.literal(\"schematic_layout_error\"),schematic_layout_error_id:wv(\"schematic_layout_error\"),error_type:k_.literal(\"schematic_layout_error\").default(\"schematic_layout_error\"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when schematic layout fails for a group\"),II=k_.object({type:k_.literal(\"schematic_debug_object\"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),CI=II.extend({shape:k_.literal(\"rect\"),center:Iv,size:Nv}),PI=II.extend({shape:k_.literal(\"line\"),start:Iv,end:Iv}),MI=II.extend({shape:k_.literal(\"point\"),center:Iv}),NI=k_.discriminatedUnion(\"shape\",[CI,PI,MI]),wI=k_.object({type:k_.literal(\"schematic_voltage_probe\"),schematic_voltage_probe_id:k_.string(),schematic_sheet_id:k_.string().optional(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:Iv,schematic_trace_id:k_.string(),voltage:uv.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:Tv.optional()}).describe(\"Defines a voltage probe measurement point on a schematic trace\"),TI=k_.object({type:k_.literal(\"schematic_manual_edit_conflict_warning\"),schematic_manual_edit_conflict_warning_id:wv(\"schematic_manual_edit_conflict_warning\"),warning_type:k_.literal(\"schematic_manual_edit_conflict_warning\").default(\"schematic_manual_edit_conflict_warning\"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit schX/schY coordinates\"),RI=k_.object({type:k_.literal(\"schematic_group\"),schematic_group_id:wv(\"schematic_group\"),schematic_sheet_id:k_.string().optional(),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:pv,height:pv,center:Iv,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe(\"Defines a group of components on the schematic\"),EI=k_.object({type:k_.literal(\"schematic_table\"),schematic_table_id:wv(\"schematic_table\"),schematic_sheet_id:k_.string().optional(),anchor_position:Iv,column_widths:k_.array(gv),row_heights:k_.array(gv),cell_padding:gv.optional(),border_width:gv.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:Tv.optional()}).describe(\"Defines a table on the schematic\"),AI=k_.object({type:k_.literal(\"schematic_table_cell\"),schematic_table_cell_id:wv(\"schematic_table_cell\"),schematic_sheet_id:k_.string().optional(),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:Iv,width:gv,height:gv,horizontal_align:k_.enum([\"left\",\"center\",\"right\"]).optional(),vertical_align:k_.enum([\"top\",\"middle\",\"bottom\"]).optional(),font_size:gv.optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a cell within a schematic_table\"),OI=k_.object({type:k_.literal(\"schematic_sheet\"),schematic_sheet_id:wv(\"schematic_sheet\"),name:k_.string().optional(),sheet_index:k_.number().optional(),subcircuit_id:k_.string().optional(),outline_color:k_.string().optional()}).describe(\"Defines a schematic sheet or page that components can be placed on\"),kI=k_.object({x:gv,y:gv,bulge:k_.number().optional()}),LI=k_.object({vertices:k_.array(kI)}),DI=k_.object({outer_ring:LI,inner_rings:k_.array(LI).default([])}),zI=k_.object({x:gv,y:gv,via:k_.boolean().optional(),via_to_layer:GS.optional()}),FI=k_.array(zI),BI=k_.object({x:gv,y:gv,via:k_.boolean().optional(),to_layer:GS.optional(),trace_width:gv.optional()}),jI=k_.object({min_trace_width:pv.optional(),min_board_edge_clearance:pv.optional(),min_via_hole_edge_to_via_hole_edge_clearance:pv.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:pv.optional(),min_trace_to_pad_edge_clearance:pv.optional(),min_pad_edge_to_pad_edge_clearance:pv.optional(),min_same_net_trace_edge_to_trace_edge_clearance:pv.optional(),min_different_net_trace_edge_to_trace_edge_clearance:pv.optional(),min_via_edge_to_pad_edge_clearance:pv.optional(),min_via_hole_diameter:pv.optional(),min_via_pad_diameter:pv.optional()}),$I=k_.object({type:k_.literal(\"pcb_component\"),pcb_component_id:wv(\"pcb_component\"),source_component_id:k_.string(),center:Iv,layer:GS,rotation:vv,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this part, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this part, usually corresponding with how the user specified it\"),width:pv,height:pv,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"relative_to_another_component\",\"none\"]).optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:Iv.optional(),insertion_direction:k_.enum([\"from_above\",\"from_left\",\"from_right\",\"from_front\",\"from_back\"]).optional(),metadata:k_.object({kicad_footprint:jv.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe(\"Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath\")}).describe(\"Defines a component on the PCB\"),YI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),hole_diameter:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),XI=YI.describe(\"Defines a circular hole on the PCB\"),VI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),WI=VI.describe(\"Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.\"),HI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"square\"]),hole_diameter:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),GI=HI.describe(\"Defines a circular or square hole on the PCB\"),UI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"oval\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),ZI=UI.describe(\"Defines an oval hole on the PCB\"),qI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),JI=qI.describe(\"Defines a pill-shaped hole on the PCB\"),KI=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:wv(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,ccw_rotation:vv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),QI=KI.describe(\"Defines a rotated pill-shaped hole on the PCB\"),tC=HI.or(UI).or(qI).or(KI).or(YI).or(VI),eC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),nC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.enum([\"oval\",\"pill\"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,ccw_rotation:vv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),oC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circular_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),pad_shape:k_.literal(\"rect\"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:vv.optional()}),iC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),rC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"rotated_pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:vv,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:vv,hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),sC=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"hole_with_polygon_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"oval\",\"pill\",\"rotated_pill\"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:gv,y:gv})).min(3),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),ccw_rotation:vv.optional()}),aC=k_.union([eC,nC,oC,iC,rC,sC]),cC=k_.object({type:k_.literal(\"pcb_port\"),pcb_port_id:wv(\"pcb_port\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:gv,y:gv,layers:k_.array(GS),is_board_pinout:k_.boolean().optional()}).describe(\"Defines a port on the PCB\"),lC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"circle\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,radius:k_.number(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),dC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rect\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),hC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_rect\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:vv,layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),uC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"pill\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),pC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_pill\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:vv,layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),mC=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"polygon\"),pcb_smtpad_id:wv(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(Iv),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),gC=k_.discriminatedUnion(\"shape\",[lC,dC,hC,pC,uC,mC]).describe(\"Defines an SMT pad on the PCB\"),fC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"circle\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,radius:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),yC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rect\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),_C=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"pill\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),bC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rotated_rect\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),ccw_rotation:gv,layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),xC=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"oval\"),pcb_solder_paste_id:wv(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),vC=k_.union([fC,yC,_C,bC,xC]).describe(\"Defines solderpaste on the PCB\"),SC=k_.object({type:k_.literal(\"pcb_text\"),pcb_text_id:wv(\"pcb_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:Iv,layer:GS,width:pv,height:pv,lines:k_.number(),align:k_.enum([\"bottom-left\"])}).describe(\"Defines text on the PCB\"),IC=k_.object({route_type:k_.literal(\"wire\"),x:gv,y:gv,width:gv,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:GS}),CC=k_.object({route_type:k_.literal(\"via\"),x:gv,y:gv,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:gv.optional(),outer_diameter:gv.optional(),from_layer:GS,to_layer:GS}),PC=k_.object({route_type:k_.literal(\"through_pad\"),start:Iv,end:Iv,width:gv,start_layer:GS,end_layer:GS,pcb_smtpad_id:k_.string().optional(),pcb_plated_hole_id:k_.string().optional()}),MC=k_.union([IC,CC,PC]),NC=k_.object({type:k_.literal(\"pcb_trace\"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:wv(\"pcb_trace\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum([\"constant\",\"interpolated\"]).default(\"constant\").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(MC)}).describe(\"Defines a trace on the PCB\"),wC=k_.object({type:k_.literal(\"pcb_trace_warning\"),pcb_trace_warning_id:wv(\"pcb_trace_warning\"),warning_type:k_.literal(\"pcb_trace_warning\").default(\"pcb_trace_warning\"),message:k_.string(),center:Iv.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace warning on the PCB\"),TC=k_.object({type:k_.literal(\"pcb_trace_too_long_warning\"),pcb_trace_too_long_warning_id:wv(\"pcb_trace_too_long_warning\"),warning_type:k_.literal(\"pcb_trace_too_long_warning\").default(\"pcb_trace_too_long_warning\"),message:k_.string(),pcb_trace_id:k_.string(),source_net_id:k_.string().optional(),source_trace_id:k_.string().optional(),actual_trace_length:gv,maximum_trace_length:gv,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a PCB trace is longer than its maximum allowed length\"),RC=Gv.extend({type:k_.literal(\"pcb_trace_error\"),pcb_trace_error_id:wv(\"pcb_trace_error\"),error_type:k_.literal(\"pcb_trace_error\").default(\"pcb_trace_error\"),center:Iv.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB\"),EC=Gv.extend({type:k_.literal(\"pcb_trace_missing_error\"),pcb_trace_missing_error_id:wv(\"pcb_trace_missing_error\"),error_type:k_.literal(\"pcb_trace_missing_error\").default(\"pcb_trace_missing_error\"),center:Iv.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a source trace has no corresponding PCB trace\"),AC=Gv.extend({type:k_.literal(\"pcb_port_not_matched_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_port_not_matched_error\").default(\"pcb_port_not_matched_error\"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB where a port is not matched\"),OC=Gv.extend({type:k_.literal(\"pcb_port_not_connected_error\"),pcb_port_not_connected_error_id:wv(\"pcb_port_not_connected_error\"),error_type:k_.literal(\"pcb_port_not_connected_error\").default(\"pcb_port_not_connected_error\"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a pcb port is not connected to any trace\"),kC=k_.object({type:k_.literal(\"pcb_net\"),pcb_net_id:wv(\"pcb_net\"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe(\"Defines a net on the PCB\"),LC=k_.object({type:k_.literal(\"pcb_via\"),pcb_via_id:wv(\"pcb_via\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:gv,y:gv,outer_diameter:gv.default(\"0.6mm\"),hole_diameter:gv.default(\"0.25mm\"),from_layer:GS.optional(),to_layer:GS.optional(),layers:k_.array(GS),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe(\"Defines a via on the PCB\"),DC=k_.object({type:k_.literal(\"pcb_board\"),pcb_board_id:wv(\"pcb_board\"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:pv.optional(),height:pv.optional(),center:Iv,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this board, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this board, usually corresponding with how the user specified it\"),thickness:pv.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(Iv).optional(),shape:k_.enum([\"rect\",\"polygon\"]).optional(),material:k_.enum([\"fr4\",\"fr1\"]).default(\"fr4\"),solder_mask_color:k_.string().optional(),silkscreen_color:k_.string().optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.optional(),position_mode:k_.enum([\"relative_to_panel_anchor\",\"none\"]).optional()}).merge(jI).describe(\"Defines the board outline of the PCB\"),zC=k_.object({type:k_.literal(\"pcb_panel\"),pcb_panel_id:wv(\"pcb_panel\"),width:pv,height:pv,center:Iv,thickness:pv.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe(\"Defines a PCB panel that can contain multiple boards\"),FC=Gv.extend({type:k_.literal(\"pcb_placement_error\"),pcb_placement_error_id:wv(\"pcb_placement_error\"),error_type:k_.literal(\"pcb_placement_error\").default(\"pcb_placement_error\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a placement error on the PCB\"),BC=Gv.extend({type:k_.literal(\"pcb_panelization_placement_error\"),pcb_panelization_placement_error_id:wv(\"pcb_panelization_placement_error\"),error_type:k_.literal(\"pcb_panelization_placement_error\").default(\"pcb_panelization_placement_error\"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a panelization placement error on the PCB\"),jC=k_.object({type:k_.literal(\"pcb_trace_hint\"),pcb_trace_hint_id:wv(\"pcb_trace_hint\"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(BI),subcircuit_id:k_.string().optional()}).describe(\"A hint that can be used during generation of a PCB trace\"),$C=k_.object({type:k_.literal(\"pcb_silkscreen_line\"),pcb_silkscreen_line_id:wv(\"pcb_silkscreen_line\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:gv.default(\"0.1mm\"),x1:gv,y1:gv,x2:gv,y2:gv,layer:US}).describe(\"Defines a silkscreen line on the PCB\"),YC=k_.object({type:k_.literal(\"pcb_silkscreen_path\"),pcb_silkscreen_path_id:wv(\"pcb_silkscreen_path\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,route:k_.array(Iv),stroke_width:pv}).describe(\"Defines a silkscreen path on the PCB\"),XC=k_.object({type:k_.literal(\"pcb_silkscreen_text\"),pcb_silkscreen_text_id:wv(\"pcb_silkscreen_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:pv,top:pv,bottom:pv,right:pv}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:GS,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:Tv.default(\"center\")}).describe(\"Defines silkscreen text on the PCB\"),VC=k_.object({type:k_.literal(\"pcb_copper_text\"),pcb_copper_text_id:wv(\"pcb_copper_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:pv,top:pv,bottom:pv,right:pv}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:GS,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:Tv.default(\"center\")}).describe(\"Defines copper text on the PCB\"),WC=k_.object({type:k_.literal(\"pcb_silkscreen_rect\"),pcb_silkscreen_rect_id:wv(\"pcb_silkscreen_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:GS,stroke_width:pv.default(\"1mm\"),corner_radius:pv.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen rect on the PCB\"),HC=k_.object({type:k_.literal(\"pcb_silkscreen_circle\"),pcb_silkscreen_circle_id:wv(\"pcb_silkscreen_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:pv,layer:US,stroke_width:pv.default(\"1mm\"),is_filled:k_.boolean().optional()}).describe(\"Defines a silkscreen circle on the PCB\"),GC=k_.object({type:k_.literal(\"pcb_silkscreen_oval\"),pcb_silkscreen_oval_id:wv(\"pcb_silkscreen_oval\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius_x:gv,radius_y:gv,layer:US,ccw_rotation:vv.optional()}).describe(\"Defines a silkscreen oval on the PCB\"),UC=k_.object({type:k_.literal(\"pcb_silkscreen_graphic\"),pcb_silkscreen_graphic_id:wv(\"pcb_silkscreen_graphic\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,image_asset:Ev.optional()}).extend({shape:k_.literal(\"brep\"),brep_shape:DI}).describe(\"Defines a BRep silkscreen graphic on the PCB\"),ZC=k_.discriminatedUnion(\"shape\",[UC]).describe(\"Defines a silkscreen graphic on the PCB\"),qC=k_.object({type:k_.literal(\"pcb_silkscreen_pill\"),pcb_silkscreen_pill_id:wv(\"pcb_silkscreen_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:GS,ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen pill on the PCB\"),JC=k_.object({type:k_.literal(\"pcb_fabrication_note_text\"),pcb_fabrication_note_text_id:wv(\"pcb_fabrication_note_text\"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"1mm\"),pcb_component_id:k_.string(),text:k_.string(),ccw_rotation:k_.number().optional(),layer:US,anchor_position:Iv.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),color:k_.string().optional()}).describe(\"Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators\"),KC=k_.object({type:k_.literal(\"pcb_fabrication_note_path\"),pcb_fabrication_note_path_id:wv(\"pcb_fabrication_note_path\"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:GS,route:k_.array(Iv),stroke_width:pv,color:k_.string().optional()}).describe(\"Defines a fabrication path on the PCB for fabricators or assemblers\"),QC=k_.object({type:k_.literal(\"pcb_fabrication_note_rect\"),pcb_fabrication_note_rect_id:wv(\"pcb_fabrication_note_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US,stroke_width:pv.default(\"0.1mm\"),corner_radius:pv.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a fabrication note rectangle on the PCB\"),tP=k_.object({type:k_.literal(\"pcb_fabrication_note_dimension\"),pcb_fabrication_note_dimension_id:wv(\"pcb_fabrication_note_dimension\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,from:Iv,to:Iv,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:pv.optional(),offset_distance:pv.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:pv.default(\"1mm\"),color:k_.string().optional(),arrow_size:pv.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB fabrication notes\"),eP=k_.object({type:k_.literal(\"pcb_note_text\"),pcb_note_text_id:wv(\"pcb_note_text\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:gv.default(\"1mm\"),text:k_.string().optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),layer:US.default(\"top\"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a documentation note in text on the PCB\"),nP=k_.object({type:k_.literal(\"pcb_note_rect\"),pcb_note_rect_id:wv(\"pcb_note_rect\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US.default(\"top\"),stroke_width:pv.default(\"0.1mm\"),corner_radius:pv.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a rectangular documentation note on the PCB\"),oP=k_.object({type:k_.literal(\"pcb_note_path\"),pcb_note_path_id:wv(\"pcb_note_path\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(Iv),layer:US.default(\"top\"),stroke_width:pv.default(\"0.1mm\"),color:k_.string().optional()}).describe(\"Defines a polyline documentation note on the PCB\"),iP=k_.object({type:k_.literal(\"pcb_note_line\"),pcb_note_line_id:wv(\"pcb_note_line\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:gv,y1:gv,x2:gv,y2:gv,layer:US.default(\"top\"),stroke_width:gv.default(\"0.1mm\"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe(\"Defines a straight documentation note line on the PCB\"),rP=k_.object({type:k_.literal(\"pcb_note_dimension\"),pcb_note_dimension_id:wv(\"pcb_note_dimension\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:Iv,to:Iv,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:pv.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:pv.default(\"1mm\"),layer:US.default(\"top\"),color:k_.string().optional(),arrow_size:pv.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB documentation notes\"),sP=Gv.extend({type:k_.literal(\"pcb_footprint_overlap_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_footprint_overlap_error\").default(\"pcb_footprint_overlap_error\"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when a pcb footprint overlaps with another element\"),aP=Gv.extend({type:k_.literal(\"pcb_courtyard_overlap_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_courtyard_overlap_error\").default(\"pcb_courtyard_overlap_error\"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe(\"Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another\"),cP=k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"rect\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:gv,height:gv,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:gv,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),lP=k_.object({type:k_.literal(\"pcb_cutout\"),pcb_cutout_id:wv(\"pcb_cutout\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),dP=lP.extend({shape:k_.literal(\"rect\"),center:Iv,width:pv,height:pv,rotation:vv.optional(),corner_radius:pv.optional()}),hP=lP.extend({shape:k_.literal(\"circle\"),center:Iv,radius:pv}),uP=lP.extend({shape:k_.literal(\"polygon\"),points:k_.array(Iv)}),pP=lP.extend({shape:k_.literal(\"path\"),route:k_.array(Iv),slot_width:pv,slot_length:pv.optional(),space_between_slots:pv.optional(),slot_corner_radius:pv.optional()}),mP=k_.discriminatedUnion(\"shape\",[dP,hP,uP,pP]).describe(\"Defines a cutout on the PCB, removing board material.\"),gP=Gv.extend({type:k_.literal(\"pcb_missing_footprint_error\"),pcb_missing_footprint_error_id:wv(\"pcb_missing_footprint_error\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"pcb_missing_footprint_error\").default(\"pcb_missing_footprint_error\"),source_component_id:k_.string()}).describe(\"Defines a missing footprint error on the PCB\"),fP=Gv.extend({type:k_.literal(\"external_footprint_load_error\"),external_footprint_load_error_id:wv(\"external_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal(\"external_footprint_load_error\").default(\"external_footprint_load_error\")}).describe(\"Defines an error when an external footprint fails to load\"),yP=Gv.extend({type:k_.literal(\"circuit_json_footprint_load_error\"),circuit_json_footprint_load_error_id:wv(\"circuit_json_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"circuit_json_footprint_load_error\").default(\"circuit_json_footprint_load_error\"),circuit_json:k_.array(k_.any()).optional()}).describe(\"Defines an error when a circuit JSON footprint fails to load\"),_P=k_.object({type:k_.literal(\"pcb_group\"),pcb_group_id:wv(\"pcb_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:pv.optional(),height:pv.optional(),center:Iv,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this group, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this group, usually corresponding with how the user specified it\"),outline:k_.array(Iv).optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.default(\"center\"),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"none\"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum([\"packed\",\"none\"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:pv}).optional(),autorouter_used_string:k_.string().optional()}).describe(\"Defines a group of components on the PCB\"),bP=Gv.extend({type:k_.literal(\"pcb_autorouting_error\"),pcb_error_id:wv(\"pcb_autorouting_error\"),error_type:k_.literal(\"pcb_autorouting_error\").default(\"pcb_autorouting_error\"),subcircuit_id:k_.string().optional()}).describe(\"The autorouting has failed to route a portion of the board\"),xP=k_.object({type:k_.literal(\"pcb_manual_edit_conflict_warning\"),pcb_manual_edit_conflict_warning_id:wv(\"pcb_manual_edit_conflict_warning\"),warning_type:k_.literal(\"pcb_manual_edit_conflict_warning\").default(\"pcb_manual_edit_conflict_warning\"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates\"),vP=k_.enum([\"x-\",\"x+\",\"y+\",\"y-\"]),SP=k_.object({type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\"),pcb_connector_not_in_accessible_orientation_warning_id:wv(\"pcb_connector_not_in_accessible_orientation_warning\"),warning_type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\").default(\"pcb_connector_not_in_accessible_orientation_warning\"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:vP,recommended_facing_direction:vP,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction\"),IP=k_.object({type:k_.literal(\"supplier_footprint_mismatch_warning\"),supplier_footprint_mismatch_warning_id:wv(\"supplier_footprint_mismatch_warning\"),warning_type:k_.literal(\"supplier_footprint_mismatch_warning\").default(\"supplier_footprint_mismatch_warning\"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:Uv.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe(\"Warning emitted when a supplier part footprint does not match the expected footprint\"),CP=k_.object({type:k_.literal(\"pcb_breakout_point\"),pcb_breakout_point_id:wv(\"pcb_breakout_point\"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:gv,y:gv}).describe(\"Defines a routing target within a pcb_group for a source_trace or source_net\"),PP=k_.object({type:k_.literal(\"pcb_ground_plane\"),pcb_ground_plane_id:wv(\"pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane on the PCB\"),MP=k_.object({type:k_.literal(\"pcb_ground_plane_region\"),pcb_ground_plane_region_id:wv(\"pcb_ground_plane_region\"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:GS,points:k_.array(Iv)}).describe(\"Defines a polygon region of a ground plane\"),NP=k_.object({type:k_.literal(\"pcb_thermal_spoke\"),pcb_thermal_spoke_id:wv(\"pcb_thermal_spoke\"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:gv,spoke_inner_diameter:gv,spoke_outer_diameter:gv,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Pattern for connecting a ground plane to a plated hole\"),wP=k_.object({type:k_.literal(\"pcb_copper_pour\"),pcb_copper_pour_id:wv(\"pcb_copper_pour\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:GS,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),TP=wP.extend({shape:k_.literal(\"rect\"),center:Iv,width:pv,height:pv,rotation:vv.optional()}),RP=wP.extend({shape:k_.literal(\"brep\"),brep_shape:DI}),EP=wP.extend({shape:k_.literal(\"polygon\"),points:k_.array(Iv)}),AP=k_.discriminatedUnion(\"shape\",[TP,RP,EP]).describe(\"Defines a copper pour on the PCB.\"),OP=Gv.extend({type:k_.literal(\"pcb_component_outside_board_error\"),pcb_component_outside_board_error_id:wv(\"pcb_component_outside_board_error\"),error_type:k_.literal(\"pcb_component_outside_board_error\").default(\"pcb_component_outside_board_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Iv,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a PCB component is placed outside the board boundaries\"),kP=Gv.extend({type:k_.literal(\"pcb_component_not_on_board_edge_error\"),pcb_component_not_on_board_edge_error_id:wv(\"pcb_component_not_on_board_edge_error\"),error_type:k_.literal(\"pcb_component_not_on_board_edge_error\").default(\"pcb_component_not_on_board_edge_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Iv,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component that must be placed on the board edge is centered away from the edge\"),LP=Gv.extend({type:k_.literal(\"pcb_component_invalid_layer_error\"),pcb_component_invalid_layer_error_id:wv(\"pcb_component_invalid_layer_error\"),error_type:k_.literal(\"pcb_component_invalid_layer_error\").default(\"pcb_component_invalid_layer_error\"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:GS,subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)\"),DP=Gv.extend({type:k_.literal(\"pcb_via_clearance_error\"),pcb_error_id:wv(\"pcb_error\"),error_type:k_.literal(\"pcb_via_clearance_error\").default(\"pcb_via_clearance_error\"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when vias are closer than the allowed clearance\"),zP=Gv.extend({type:k_.literal(\"pcb_via_trace_clearance_error\"),pcb_via_trace_clearance_error_id:wv(\"pcb_via_trace_clearance_error\"),error_type:k_.literal(\"pcb_via_trace_clearance_error\").default(\"pcb_via_trace_clearance_error\"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a via and trace are closer than the allowed clearance\"),FP=Gv.extend({type:k_.literal(\"pcb_pad_pad_clearance_error\"),pcb_pad_pad_clearance_error_id:wv(\"pcb_pad_pad_clearance_error\"),error_type:k_.literal(\"pcb_pad_pad_clearance_error\").default(\"pcb_pad_pad_clearance_error\"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when pads are closer than the allowed clearance\"),BP=Gv.extend({type:k_.literal(\"pcb_pad_trace_clearance_error\"),pcb_pad_trace_clearance_error_id:wv(\"pcb_pad_trace_clearance_error\"),error_type:k_.literal(\"pcb_pad_trace_clearance_error\").default(\"pcb_pad_trace_clearance_error\"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pad and trace are closer than allowed clearance\"),jP=k_.object({type:k_.literal(\"pcb_courtyard_rect\"),pcb_courtyard_rect_id:wv(\"pcb_courtyard_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US,ccw_rotation:vv.optional(),color:k_.string().optional()}).describe(\"Defines a courtyard rectangle on the PCB\"),$P=k_.object({type:k_.literal(\"pcb_courtyard_outline\"),pcb_courtyard_outline_id:wv(\"pcb_courtyard_outline\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,outline:k_.array(Iv).min(2)}).describe(\"Defines a courtyard outline on the PCB\"),YP=k_.object({type:k_.literal(\"pcb_courtyard_polygon\"),pcb_courtyard_polygon_id:wv(\"pcb_courtyard_polygon\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,points:k_.array(Iv).min(3),color:k_.string().optional()}).describe(\"Defines a courtyard polygon on the PCB\"),XP=k_.object({type:k_.literal(\"pcb_courtyard_circle\"),pcb_courtyard_circle_id:wv(\"pcb_courtyard_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:pv,layer:US,color:k_.string().optional()}).describe(\"Defines a courtyard circle on the PCB\"),VP=k_.object({type:k_.literal(\"pcb_courtyard_pill\"),pcb_courtyard_pill_id:wv(\"pcb_courtyard_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,radius:pv,layer:US,color:k_.string().optional()}).describe(\"Defines a courtyard pill on the PCB\"),WP=[\"obj\",\"stl\",\"3mf\",\"gltf\",\"glb\",\"step\",\"wrl\"],HP=[\"x+\",\"x-\",\"y+\",\"y-\",\"z+\",\"z-\"],GP={obj:\"z+\",stl:\"z+\",\"3mf\":\"z+\",gltf:\"y+\",glb:\"y+\",step:\"z+\",wrl:\"y+\"},UP=k_.object({type:k_.literal(\"cad_component\"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:Pv,rotation:Pv.optional(),size:Pv.optional(),layer:GS.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:Ev.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum(HP).optional().describe('The direction in the model\\'s coordinate space that is considered \"up\" or \"coming out of the board surface\"'),model_origin_position:Pv.optional(),model_origin_alignment:k_.enum([\"unknown\",\"center\",\"center_of_component_on_board_surface\",\"bottom_center_of_component\"]).optional(),model_object_fit:k_.enum([\"contain_within_bounds\",\"fill_bounds\"]).optional().default(\"contain_within_bounds\"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),show_as_bounding_box:k_.boolean().optional(),anchor_alignment:k_.enum([\"center\",\"center_of_component_on_board_surface\"]).optional().default(\"center\")}).describe(\"Defines a component on the PCB\"),ZP=k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]),qP=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),JP=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:wv(\"simulation_voltage_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:uv}).describe(\"Defines a DC voltage source for simulation\"),KP=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:wv(\"simulation_voltage_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:uv.optional(),frequency:mv.optional(),peak_to_peak_voltage:uv.optional(),wave_shape:ZP.optional(),phase:vv.optional(),duty_cycle:qP.optional(),pulse_delay:bv.optional(),rise_time:bv.optional(),fall_time:bv.optional(),pulse_width:bv.optional(),period:bv.optional()}).describe(\"Defines an AC voltage source for simulation\"),QP=k_.union([JP,KP]).describe(\"Defines a voltage source for simulation\"),tM=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),eM=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:wv(\"simulation_current_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:fv}).describe(\"Defines a DC current source for simulation\"),nM=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:wv(\"simulation_current_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:fv.optional(),frequency:mv.optional(),peak_to_peak_current:fv.optional(),wave_shape:ZP.optional(),phase:vv.optional(),duty_cycle:tM.optional()}).describe(\"Defines an AC current source for simulation\"),oM=k_.union([eM,nM]).describe(\"Defines a current source for simulation\"),iM=k_.union([k_.literal(\"spice_dc_sweep\"),k_.literal(\"spice_dc_operating_point\"),k_.literal(\"spice_transient_analysis\"),k_.literal(\"spice_ac_analysis\")]),rM=k_.object({method:k_.enum([\"trap\",\"gear\"]).optional(),reltol:k_.union([k_.number(),k_.string()]).optional(),abstol:k_.union([k_.number(),k_.string()]).optional(),vntol:k_.union([k_.number(),k_.string()]).optional()}).describe(\"SPICE solver options for a simulation experiment\"),sM=k_.object({type:k_.literal(\"simulation_experiment\"),simulation_experiment_id:wv(\"simulation_experiment\"),name:k_.string(),experiment_type:iM,time_per_step:yv.optional(),start_time_ms:bv.optional(),end_time_ms:bv.optional(),spice_options:rM.optional()}).describe(\"Defines a simulation experiment configuration\"),aM=k_.object({type:k_.literal(\"simulation_transient_voltage_graph\"),simulation_transient_voltage_graph_id:wv(\"simulation_transient_voltage_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:yv,start_time_ms:bv,end_time_ms:bv,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores voltage measurements over time for a simulation\"),cM=k_.object({type:k_.literal(\"simulation_transient_current_graph\"),simulation_transient_current_graph_id:wv(\"simulation_transient_current_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),current_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:yv,start_time_ms:bv,end_time_ms:bv,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores current measurements over time for a simulation\"),lM=k_.object({type:k_.literal(\"simulation_switch\"),simulation_switch_id:wv(\"simulation_switch\"),source_component_id:k_.string().optional(),closes_at:bv.optional(),opens_at:bv.optional(),starts_closed:k_.boolean().optional(),switching_frequency:mv.optional()}).describe(\"Defines a switch for simulation timing control\"),dM=k_.object({type:k_.literal(\"simulation_voltage_probe\"),simulation_voltage_probe_id:wv(\"simulation_voltage_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.\").superRefine((t,e)=\u003e{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n\u0026\u0026o?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a differential probe.\"}):n?t.signal_input_source_port_id\u0026\u0026t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id.\"}):o\u0026\u0026(t.signal_input_source_net_id\u0026\u0026t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id.\"}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id.\"})}),hM=k_.object({type:k_.literal(\"simulation_current_probe\"),simulation_current_probe_id:wv(\"simulation_current_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a current probe for simulation. It measures current flowing from the positive endpoint to the negative endpoint.\").superRefine((t,e)=\u003e{const n=!!t.positive_source_port_id,o=!!t.negative_source_port_id,i=!!t.positive_source_net_id,r=!!t.negative_source_net_id,s=n||o,a=i||r;s\u0026\u0026a?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a current probe.\"}):s?n\u0026\u0026o||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Current probe using source ports requires both positive_source_port_id and negative_source_port_id.\"}):a?i\u0026\u0026r||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Current probe using source nets requires both positive_source_net_id and negative_source_net_id.\"}):e.addIssue({code:k_.ZodIssueCode.custom,message:\"A current probe must have either positive/negative source port ids or positive/negative source net ids.\"})}),uM=Gv.extend({type:k_.literal(\"simulation_unknown_experiment_error\"),simulation_unknown_experiment_error_id:wv(\"simulation_unknown_experiment_error\"),error_type:k_.literal(\"simulation_unknown_experiment_error\").default(\"simulation_unknown_experiment_error\"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"An unknown error occurred during the simulation experiment.\"),pM=k_.object({type:k_.literal(\"simulation_op_amp\"),simulation_op_amp_id:wv(\"simulation_op_amp\"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe(\"Defines a simple ideal operational amplifier for simulation\"),mM=k_.object({type:k_.literal(\"simulation_spice_subcircuit\"),simulation_spice_subcircuit_id:wv(\"simulation_spice_subcircuit\"),source_component_id:k_.string(),spice_pin_to_source_port_map:k_.record(k_.string(),k_.string()),subcircuit_source:k_.string()}).describe(\"Defines a custom SPICE subcircuit model for simulation\"),gM=t=\u003evoid 0!==t,fM=k_.object({type:k_.literal(\"simulation_oscilloscope_trace\"),simulation_oscilloscope_trace_id:wv(\"simulation_oscilloscope_trace\"),simulation_transient_voltage_graph_id:k_.string().optional(),simulation_transient_current_graph_id:k_.string().optional(),simulation_voltage_probe_id:k_.string().optional(),simulation_current_probe_id:k_.string().optional(),display_name:k_.string().optional(),color:k_.string().optional(),display_center_value:k_.number().optional(),display_center_offset_divs:k_.number().optional(),volts_per_div:k_.number().positive().optional(),amps_per_div:k_.number().positive().optional()}).describe(\"Defines how a simulation measurement is rendered as an oscilloscope-style trace.\").superRefine((t,e)=\u003e{const n=[t.simulation_transient_voltage_graph_id,t.simulation_voltage_probe_id].filter(gM).length,o=[t.simulation_transient_current_graph_id,t.simulation_current_probe_id].filter(gM).length;n+o!==1\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"An oscilloscope trace must reference exactly one voltage graph, current graph, voltage probe, or current probe.\"}),n\u003e0\u0026\u0026void 0!==t.amps_per_div\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"Voltage oscilloscope traces must use volts_per_div, not amps_per_div.\"}),o\u003e0\u0026\u0026void 0!==t.volts_per_div\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"Current oscilloscope traces must use amps_per_div, not volts_per_div.\"})}),yM=k_.union([BS,zS,FS,DS,$S,jS,nS,qv,Kv,tS,Jv,oS,cS,lS,pS,gS,fS,vS,yS,_S,bS,xS,hS,dS,VS,ZS,YS,SS,PS,MS,wS,qS,TS,RS,JS,KS,QS,tI,eI,nI,OS,kS,XS,$I,tC,gP,fP,yP,xP,SP,IP,aC,cP,cC,kC,SC,NC,wC,TC,LC,gC,vC,DC,zC,_P,jC,$C,YC,XC,qC,VC,WC,HC,GC,ZC,RC,EC,FC,BC,AC,OC,DP,zP,FP,BP,KC,JC,QC,tP,eP,nP,oP,iP,rP,bP,sP,aP,CP,mP,PP,MP,NP,AP,OP,kP,LP,jP,$P,YP,XP,VP,oI,_I,uI,pI,mI,gI,lI,hI,bI,fI,iI,vI,SI,xI,NI,wI,TI,RI,OI,EI,AI,UP,QP,oM,sM,aM,cM,lM,dM,hM,fM,uM,pM,mM]),_M=yM;function bM(t,e,n){if(!e||!n)return;let o=t.get(e);o||(o=new Set,t.set(e,o)),o.add(n);let i=t.get(n);i||(i=new Set,t.set(n,i)),i.add(e)}var xM=(t,e={})=\u003e{const n=t;let o=n._internal_store;if(!o){o={counts:{},editCount:0},n._internal_store=o;for(const t of n){const e=t.type,n=t[`${e}_id`];if(!n)continue;const i=Number.parseInt(n.split(\"_\").pop());Number.isNaN(i)||(o.counts[e]=Math.max(o.counts[e]??0,i))}}const i=new Proxy({},{get:(t,r)=\u003e{if(\"toArray\"===r)return()=\u003e(n.editCount=o.editCount,n);if(\"editCount\"===r)return o.editCount;if(\"subtree\"===r)return t=\u003exM(function(t,e){if(!e.subcircuit_id\u0026\u0026!e.source_group_id)return[...t];let n=e;if(e.subcircuit_id){const o=new Set([e.subcircuit_id]),i=new Map,r=new Map;for(const e of t)if(\"source_group\"===e.type){const t=e.source_group_id,n=e.subcircuit_id;n\u0026\u0026r.set(t,n);const o=e.parent_source_group_id;o\u0026\u0026(i.has(o)||i.set(o,[]),i.get(o).push(t))}let s;for(const[t,n]of r)if(n===e.subcircuit_id){s=t;break}if(s){const t=e=\u003e{const n=i.get(e)||[];for(const e of n){const n=r.get(e);n\u0026\u0026o.add(n),t(e)}};t(s),n={...e,subcircuit_ids:Array.from(o)}}}const o=new Map;for(const e of t){const t=e[`${e.type}_id`];\"string\"==typeof t\u0026\u0026o.set(t,e)}const i=new Map;for(const e of t){const t=Object.entries(e);for(const[n,r]of t)if(\"parent_source_group_id\"!==n)if(n.endsWith(\"_id\")\u0026\u0026\"string\"==typeof r)bM(i,e,o.get(r));else if(n.endsWith(\"_ids\")\u0026\u0026Array.isArray(r))for(const t of r)\"string\"==typeof t\u0026\u0026bM(i,e,o.get(t))}const r=[],s=new Set;for(const e of t){let t=!1;(n.subcircuit_id\u0026\u0026\"subcircuit_id\"in e\u0026\u0026e.subcircuit_id===n.subcircuit_id||n.subcircuit_ids\u0026\u0026\"subcircuit_id\"in e\u0026\u0026e.subcircuit_id\u0026\u0026n.subcircuit_ids.includes(e.subcircuit_id)||n.source_group_id\u0026\u0026\"source_group_id\"in e\u0026\u0026e.source_group_id===n.source_group_id||n.source_group_id\u0026\u0026\"member_source_group_ids\"in e\u0026\u0026Array.isArray(e.member_source_group_ids)\u0026\u0026e.member_source_group_ids.includes(n.source_group_id))\u0026\u0026(t=!0),t\u0026\u0026(r.push(e),s.add(e))}for(;r.length\u003e0;){const t=r.shift(),e=i.get(t);if(e)for(const t of e)s.has(t)||(s.add(t),r.push(t))}return t.filter(t=\u003es.has(t))}(n,t),e);if(\"insert\"===r)return t=\u003e{const i=t.type;if(!i)throw new Error(\"insert requires an element with a type\");o.counts[i]??=-1,o.counts[i]++;const r=o.counts[i],s={...t,type:i,[`${i}_id`]:`${i}_${r}`};if(e.validateInserts){(S_[i]??_M).parse(s)}return n.push(s),o.editCount++,s};if(\"insertAll\"===r)return t=\u003et.map(t=\u003ei.insert(t));const s=r;return{get:t=\u003en.find(e=\u003ee.type===s\u0026\u0026e[`${s}_id`]===t),getUsing:t=\u003e{const e=Object.keys(t);if(1!==e.length)throw new Error(\"getUsing requires exactly one key, e.g. { pcb_component_id }\");const o=e[0],i=o.replace(\"_id\",\"\"),r=n.find(e=\u003ee.type===i\u0026\u0026e[o]===t[o]);return r?n.find(t=\u003et.type===s\u0026\u0026t[`${s}_id`]===r[`${s}_id`]):null},getWhere:t=\u003e{const e=Object.keys(t);return n.find(n=\u003en.type===s\u0026\u0026e.every(e=\u003en[e]===t[e]))},list:t=\u003e{const e=t?Object.keys(t):[];return n.filter(n=\u003en.type===s\u0026\u0026e.every(e=\u003en[e]===t[e]))},insert:t=\u003e{o.counts[s]??=-1,o.counts[s]++;const i=o.counts[s],r={type:s,[`${s}_id`]:`${s}_${i}`,...t};if(e.validateInserts){(S_[s]??_M).parse(r)}return n.push(r),o.editCount++,r},delete:t=\u003e{const e=n.find(e=\u003ee[`${s}_id`]===t);e\u0026\u0026(n.splice(n.indexOf(e),1),o.editCount++)},update:(t,e)=\u003e{const i=n.find(e=\u003ee.type===s\u0026\u0026e[`${s}_id`]===t);return i?(Object.assign(i,e),o.editCount++,i):null},select:t=\u003e{if(\"source_component\"===s)return n.find(e=\u003e\"source_component\"===e.type\u0026\u0026e.name===t.replace(/\\./g,\"\"));if(\"pcb_port\"===s||\"source_port\"===s||\"schematic_port\"===s){const[e,o]=t.replace(/\\./g,\"\").split(/[\\s\\\u003e]+/),i=n.find(t=\u003e\"source_component\"===t.type\u0026\u0026t.name===e);if(!i)return null;const r=n.find(t=\u003e\"source_port\"===t.type\u0026\u0026t.source_component_id===i.source_component_id\u0026\u0026(t.name===o||(t.port_hints??[]).includes(o)));if(!r)return null;if(\"source_port\"===s)return r;if(\"pcb_port\"===s)return n.find(t=\u003e\"pcb_port\"===t.type\u0026\u0026t.source_port_id===r.source_port_id);if(\"schematic_port\"===s)return n.find(t=\u003e\"schematic_port\"===t.type\u0026\u0026t.source_port_id===r.source_port_id)}}}}});return i};xM.unparsed=xM;var vM=xM;function SM(t){const e=t.type;return`${e}:${t[`${e}_id`]}`}var IM=(t,e={})=\u003e{let n=t._internal_store_indexed;if(!n){n={counts:{},editCount:0,indexes:{}};for(const e of t){const t=e.type,o=e[`${t}_id`];if(!o)continue;const i=Number.parseInt(o.split(\"_\").pop()||\"\");Number.isNaN(i)||(n.counts[t]=Math.max(n.counts[t]??0,i))}const o=e.indexConfig||{},i=n.indexes;if(o.byId\u0026\u0026(i.byId=new Map),o.byType\u0026\u0026(i.byType=new Map),o.byRelation\u0026\u0026(i.byRelation=new Map),o.bySubcircuit\u0026\u0026(i.bySubcircuit=new Map),o.byCustomField\u0026\u0026o.byCustomField.length\u003e0){i.byCustomField=new Map;for(const t of o.byCustomField)i.byCustomField.set(t,new Map)}for(const e of t){if(o.byId){const t=SM(e);i.byId.set(t,e)}if(o.byType){const t=i.byType.get(e.type)||[];t.push(e),i.byType.set(e.type,t)}if(o.byRelation){const t=Object.entries(e);for(const[n,o]of t)if(n.endsWith(\"_id\")\u0026\u0026n!==`${e.type}_id`\u0026\u0026\"string\"==typeof o){const t=i.byRelation.get(n)||new Map,r=t.get(o)||[];r.push(e),t.set(o,r),i.byRelation.set(n,t)}}if(o.bySubcircuit\u0026\u0026\"subcircuit_id\"in e){const t=e.subcircuit_id;if(t\u0026\u0026\"string\"==typeof t){const n=i.bySubcircuit.get(t)||[];n.push(e),i.bySubcircuit.set(t,n)}}if(o.byCustomField\u0026\u0026i.byCustomField)for(const t of o.byCustomField)if(t in e){const n=e[t];if(void 0!==n\u0026\u0026(\"string\"==typeof n||\"number\"==typeof n)){const o=String(n),r=i.byCustomField.get(t),s=r.get(o)||[];s.push(e),r.set(o,s)}}}t._internal_store_indexed=n}return new Proxy({},{get:(o,i)=\u003e{if(\"toArray\"===i)return()=\u003e(t.editCount=n.editCount,t);if(\"editCount\"===i)return n.editCount;const r=i;return{get:o=\u003e{const i=e.indexConfig||{};if(i.byId\u0026\u0026n.indexes.byId)return n.indexes.byId.get(`${r}:${o}`)||null;if(i.byType\u0026\u0026n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=\u003et[`${r}_id`]===o)||null}return t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===o)||null},getUsing:o=\u003e{const i=e.indexConfig||{},s=Object.keys(o);if(1!==s.length)throw new Error(\"getUsing requires exactly one key, e.g. { pcb_component_id }\");const a=s[0],c=a.replace(\"_id\",\"\");if(i.byRelation\u0026\u0026n.indexes.byRelation){const e=n.indexes.byRelation.get(a);if(e){const s=(e.get(o[a])||[]).find(t=\u003et.type===c);if(!s)return null;const l=s[`${r}_id`];if(i.byId\u0026\u0026n.indexes.byId)return n.indexes.byId.get(`${r}:${l}`)||null;if(i.byType\u0026\u0026n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=\u003et[`${r}_id`]===l)||null}return t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===l)||null}}const l=t.find(t=\u003et.type===c\u0026\u0026t[a]===o[a]);return l\u0026\u0026t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===l[`${r}_id`])||null},getWhere:o=\u003e{const i=e.indexConfig||{},s=Object.keys(o);if(1===s.length\u0026\u0026i.byCustomField\u0026\u0026n.indexes.byCustomField){const t=s[0],e=n.indexes.byCustomField.get(t);if(e){const n=String(o[t]);return(e.get(n)||[]).find(t=\u003et.type===r)||null}}if(\"subcircuit_id\"in o\u0026\u0026i.bySubcircuit\u0026\u0026n.indexes.bySubcircuit){const t=o.subcircuit_id;return(n.indexes.bySubcircuit.get(t)||[]).find(t=\u003et.type===r\u0026\u0026s.every(e=\u003et[e]===o[e]))||null}if(i.byType\u0026\u0026n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=\u003es.every(e=\u003et[e]===o[e]))||null}return t.find(t=\u003et.type===r\u0026\u0026s.every(e=\u003et[e]===o[e]))||null},list:o=\u003e{const i=e.indexConfig||{},s=o?Object.keys(o):[];if(0===s.length\u0026\u0026i.byType\u0026\u0026n.indexes.byType)return n.indexes.byType.get(r)||[];if(1===s.length\u0026\u0026\"subcircuit_id\"===s[0]\u0026\u0026i.bySubcircuit\u0026\u0026n.indexes.bySubcircuit){const t=o.subcircuit_id;return(n.indexes.bySubcircuit.get(t)||[]).filter(t=\u003et.type===r)}let a;return a=i.byType\u0026\u0026n.indexes.byType?n.indexes.byType.get(r)||[]:t.filter(t=\u003et.type===r),s.length\u003e0?a.filter(t=\u003es.every(e=\u003et[e]===o[e])):a},insert:o=\u003e{n.counts[r]??=-1,n.counts[r]++;const i=n.counts[r],s={type:r,[`${r}_id`]:`${r}_${i}`,...o};if(e.validateInserts){(S_[r]??_M).parse(s)}t.push(s),n.editCount++;const a=e.indexConfig||{};if(a.byId\u0026\u0026n.indexes.byId){const t=SM(s);n.indexes.byId.set(t,s)}if(a.byType\u0026\u0026n.indexes.byType){const t=n.indexes.byType.get(r)||[];t.push(s),n.indexes.byType.set(r,t)}if(a.byRelation\u0026\u0026n.indexes.byRelation){const t=Object.entries(s);for(const[e,o]of t)if(e.endsWith(\"_id\")\u0026\u0026e!==`${s.type}_id`\u0026\u0026\"string\"==typeof o){const t=n.indexes.byRelation.get(e)||new Map,i=t.get(o)||[];i.push(s),t.set(o,i),n.indexes.byRelation.set(e,t)}}if(a.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in s){const t=s.subcircuit_id;if(t\u0026\u0026\"string\"==typeof t){const e=n.indexes.bySubcircuit.get(t)||[];e.push(s),n.indexes.bySubcircuit.set(t,e)}}if(a.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of a.byCustomField)if(t in s){const e=s[t];if(void 0!==e\u0026\u0026(\"string\"==typeof e||\"number\"==typeof e)){const o=String(e),i=n.indexes.byCustomField.get(t),r=i.get(o)||[];r.push(s),i.set(o,r)}}return s},delete:o=\u003e{const i=e.indexConfig||{};let s;if(i.byId\u0026\u0026n.indexes.byId)s=n.indexes.byId.get(`${r}:${o}`);else if(i.byType\u0026\u0026n.indexes.byType){const t=n.indexes.byType.get(r)||[];s=t.find(t=\u003et[`${r}_id`]===o)}else s=t.find(t=\u003et[`${r}_id`]===o);if(!s)return;const a=t.indexOf(s);if(a\u003e=0\u0026\u0026(t.splice(a,1),n.editCount++),i.byId\u0026\u0026n.indexes.byId){const t=SM(s);n.indexes.byId.delete(t)}if(i.byType\u0026\u0026n.indexes.byType){const t=(n.indexes.byType.get(r)||[]).filter(t=\u003et[`${r}_id`]!==o);n.indexes.byType.set(r,t)}if(i.byRelation\u0026\u0026n.indexes.byRelation)for(const[t,e]of n.indexes.byRelation.entries())for(const[t,n]of e.entries()){const o=n.filter(t=\u003et!==s);0===o.length?e.delete(t):e.set(t,o)}if(i.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in s){const t=s.subcircuit_id;if(t){const e=(n.indexes.bySubcircuit.get(t)||[]).filter(t=\u003et!==s);0===e.length?n.indexes.bySubcircuit.delete(t):n.indexes.bySubcircuit.set(t,e)}}if(i.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of n.indexes.byCustomField.values())for(const[e,n]of t.entries()){const o=n.filter(t=\u003et!==s);0===o.length?t.delete(e):t.set(e,o)}},update:(o,i)=\u003e{const s=e.indexConfig||{};let a;if(s.byId\u0026\u0026n.indexes.byId)a=n.indexes.byId.get(`${r}:${o}`);else if(s.byType\u0026\u0026n.indexes.byType){const t=n.indexes.byType.get(r)||[];a=t.find(t=\u003et[`${r}_id`]===o)}else a=t.find(t=\u003et.type===r\u0026\u0026t[`${r}_id`]===o);if(!a)return null;if(s.byRelation\u0026\u0026n.indexes.byRelation){const t=Object.entries(a);for(const[e,o]of t)if(e.endsWith(\"_id\")\u0026\u0026e!==`${a.type}_id`\u0026\u0026\"string\"==typeof o\u0026\u0026e in i\u0026\u0026i[e]!==o){const t=n.indexes.byRelation.get(e);if(t){const e=(t.get(o)||[]).filter(t=\u003et!==a);0===e.length?t.delete(o):t.set(o,e)}}}if(s.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in a\u0026\u0026\"subcircuit_id\"in i){const t=a.subcircuit_id;if(t!==i.subcircuit_id){const e=(n.indexes.bySubcircuit.get(t)||[]).filter(t=\u003et!==a);0===e.length?n.indexes.bySubcircuit.delete(t):n.indexes.bySubcircuit.set(t,e)}}if(s.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of s.byCustomField)if(t in a\u0026\u0026t in i\u0026\u0026a[t]!==i[t]){const e=n.indexes.byCustomField.get(t);if(e){const n=String(a[t]),o=(e.get(n)||[]).filter(t=\u003et!==a);0===o.length?e.delete(n):e.set(n,o)}}if(Object.assign(a,i),n.editCount++,s.byRelation\u0026\u0026n.indexes.byRelation){const t=Object.entries(a);for(const[e,o]of t)if(e.endsWith(\"_id\")\u0026\u0026e!==`${a.type}_id`\u0026\u0026\"string\"==typeof o\u0026\u0026e in i){const t=n.indexes.byRelation.get(e)||new Map,i=t.get(o)||[];i.includes(a)||(i.push(a),t.set(o,i),n.indexes.byRelation.set(e,t))}}if(s.bySubcircuit\u0026\u0026n.indexes.bySubcircuit\u0026\u0026\"subcircuit_id\"in a\u0026\u0026\"subcircuit_id\"in i){const t=a.subcircuit_id;if(t\u0026\u0026\"string\"==typeof t){const e=n.indexes.bySubcircuit.get(t)||[];e.includes(a)||(e.push(a),n.indexes.bySubcircuit.set(t,e))}}if(s.byCustomField\u0026\u0026n.indexes.byCustomField)for(const t of s.byCustomField)if(t in a\u0026\u0026t in i){const e=a[t];if(void 0!==e\u0026\u0026(\"string\"==typeof e||\"number\"==typeof e)){const o=String(e),i=n.indexes.byCustomField.get(t),r=i.get(o)||[];r.includes(a)||(r.push(a),i.set(o,r))}}return a},select:e=\u003e{if(\"source_component\"===r)return t.find(t=\u003e\"source_component\"===t.type\u0026\u0026t.name===e.replace(/\\./g,\"\"))||null;if(\"pcb_port\"===r||\"source_port\"===r||\"schematic_port\"===r){const[n,o]=e.replace(/\\./g,\"\").split(/[\\s\\\u003e]+/),i=t.find(t=\u003e\"source_component\"===t.type\u0026\u0026t.name===n);if(!i)return null;const s=t.find(t=\u003e\"source_port\"===t.type\u0026\u0026t.source_component_id===i.source_component_id\u0026\u0026(t.name===o||(t.port_hints??[]).includes(o)));if(!s)return null;if(\"source_port\"===r)return s;if(\"pcb_port\"===r)return t.find(t=\u003e\"pcb_port\"===t.type\u0026\u0026t.source_port_id===s.source_port_id)||null;if(\"schematic_port\"===r)return t.find(t=\u003e\"schematic_port\"===t.type\u0026\u0026t.source_port_id===s.source_port_id)||null}return null}}}})};IM.unparsed=IM;var CM=t=\u003et[`${t.type}_id`];function PM(t,e){const n=xM(t).pcb_trace.get(e);if(!n)return`trace[${e}]`;const o=n.route.flatMap(t=\u003e[t.start_pcb_port_id,t.end_pcb_port_id]).filter(Boolean);if(0===o.length)return`trace[${e}]`;return`trace[${o.map(e=\u003e{const n=function(e){const n=xM(t).pcb_port.get(e);if(!n)return null;const o=n.pcb_component_id?xM(t).pcb_component.get(n.pcb_component_id):void 0;if(!o)return null;const i=xM(t).source_component.get(o.source_component_id);if(!i)return null;const r=xM(t).source_port.get(n.source_port_id),s=r?.port_hints?r.port_hints[1]:\"\";return{componentName:i.name,portHint:s}}(e);return n?`.${n.componentName} \u003e port.${n.portHint}`:`port[${e}]`}).join(\", \")}]`}var MM=(t,e)=\u003e{const n=xM(t).pcb_port.get(e);if(!n)return`pcb_port[#${e}]`;const o=n.pcb_component_id?xM(t).pcb_component.get(n.pcb_component_id):void 0;if(!o)return`pcb_port[#${e}]`;const i=xM(t).source_component.get(o.source_component_id);if(!i)return`pcb_port[#${e}]`;const r=xM(t).source_port.get(n.source_port_id);if(!r)return`pcb_port[#${e}]`;let s;return s=r?.port_hints\u0026\u0026r.port_hints.length\u003e0||r.port_hints\u0026\u0026r.port_hints.length\u003e0?r.port_hints[0]:e,`pcb_port[.${i.name} \u003e .${s}]`};var NM=(t,e)=\u003e{if(\"string\"==typeof e){const n=((t,e)=\u003et.find(t=\u003eCM(t)===e)??null)(t,e);return NM(t,n)}switch(e.type){case\"pcb_port\":return MM(t,e.pcb_port_id);case\"pcb_smtpad\":return function(t,e){const n=xM(t).pcb_smtpad.get(e);return n\u0026\u0026n.pcb_port_id?MM(t,n.pcb_port_id):`smtpad[${e}]`}(t,e.pcb_smtpad_id);case\"pcb_trace\":return PM(t,e.pcb_trace_id);case\"source_component\":return`source_component[${e.name}]`;default:return`${e.type}[#${CM(e)}]`}},wM=(t,e)=\u003e({minX:Math.min(t.minX,e.minX),minY:Math.min(t.minY,e.minY),maxX:Math.max(t.maxX,e.maxX),maxY:Math.max(t.maxY,e.maxY)}),TM=(t,e,n)=\u003e{const o=n/2;return{minX:t-o,minY:e-o,maxX:t+o,maxY:e+o}},RM=(t,e,n,o,i)=\u003e{const r=n/2,s=o/2,a=i*Math.PI/180,c=Math.cos(a),l=Math.sin(a),d=[{x:-r,y:-s},{x:r,y:-s},{x:r,y:s},{x:-r,y:s}].map(n=\u003e({x:t+n.x*c-n.y*l,y:e+n.x*l+n.y*c}));return{minX:Math.min(...d.map(t=\u003et.x)),minY:Math.min(...d.map(t=\u003et.y)),maxX:Math.max(...d.map(t=\u003et.x)),maxY:Math.max(...d.map(t=\u003et.y))}},EM=t=\u003e{let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t){if(!r.type.startsWith(\"pcb_\"))continue;if(\"pcb_smtpad\"===r.type\u0026\u0026\"polygon\"===r.shape\u0026\u0026Array.isArray(r.points)){for(const t of r.points)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);continue}if(\"pcb_hole\"===r.type\u0026\u0026\"circle\"===r.hole_shape){const t=TM(r.x,r.y,r.hole_diameter);e=Math.min(e,t.minX),n=Math.min(n,t.minY),o=Math.max(o,t.maxX),i=Math.max(i,t.maxY);continue}if(\"pcb_plated_hole\"===r.type){let t;if(\"outer_diameter\"in r\u0026\u0026\"number\"==typeof r.outer_diameter?t=TM(r.x,r.y,r.outer_diameter):\"hole_diameter\"in r\u0026\u0026\"number\"==typeof r.hole_diameter\u0026\u0026(t=TM(r.x,r.y,r.hole_diameter)),\"rect_pad_width\"in r\u0026\u0026\"number\"==typeof r.rect_pad_width\u0026\u0026\"rect_pad_height\"in r\u0026\u0026\"number\"==typeof r.rect_pad_height){const e=RM(r.x,r.y,r.rect_pad_width,r.rect_pad_height,\"rect_ccw_rotation\"in r?r.rect_ccw_rotation??0:0);t=t?wM(t,e):e}if(\"hole_diameter\"in r\u0026\u0026\"number\"==typeof r.hole_diameter){const e=TM(r.x+(\"hole_offset_x\"in r?r.hole_offset_x??0:0),r.y+(\"hole_offset_y\"in r?r.hole_offset_y??0:0),r.hole_diameter);t=t?wM(t,e):e}if(t){e=Math.min(e,t.minX),n=Math.min(n,t.minY),o=Math.max(o,t.maxX),i=Math.max(i,t.maxY);continue}}let t,s,a,c;if(\"x\"in r\u0026\u0026\"y\"in r\u0026\u0026(t=Number(r.x),s=Number(r.y)),\"outer_diameter\"in r\u0026\u0026(a=Number(r.outer_diameter),c=Number(r.outer_diameter)),\"width\"in r\u0026\u0026(a=Number(r.width)),\"height\"in r\u0026\u0026(c=Number(r.height)),\"center\"in r\u0026\u0026(t=r.center.x,s=r.center.y),void 0!==t\u0026\u0026void 0!==s)e=Math.min(e,t),n=Math.min(n,s),o=Math.max(o,t),i=Math.max(i,s),void 0!==a\u0026\u0026void 0!==c\u0026\u0026(e=Math.min(e,t-a/2),n=Math.min(n,s-c/2),o=Math.max(o,t+a/2),i=Math.max(i,s+c/2)),\"radius\"in r\u0026\u0026(e=Math.min(e,t-r.radius),n=Math.min(n,s-r.radius),o=Math.max(o,t+r.radius),i=Math.max(i,s+r.radius));else if(\"pcb_trace\"===r.type)for(const t of r.route)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);else if(\"pcb_courtyard_outline\"===r.type)for(const t of r.outline)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);else if(\"pcb_courtyard_polygon\"===r.type)for(const t of r.points)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y)}return{minX:e,minY:n,maxX:o,maxY:i}},AM=t=\u003et[`${t.type}_id`],OM={Hz:{baseUnit:\"Hz\",variants:{MHz:1e6,kHz:1e3,Hz:1}},g:{baseUnit:\"g\",variants:{kg:1e3,g:1}},\"Ω\":{baseUnit:\"Ω\",variants:{\"mΩ\":.001,\"Ω\":1,\"kΩ\":1e3,\"KΩ\":1e3,kohm:1e3,\"MΩ\":1e6,\"GΩ\":1e9,\"TΩ\":1e12}},V:{baseUnit:\"V\",variants:{mV:.001,V:1,kV:1e3,KV:1e3,MV:1e6,GV:1e9,TV:1e12}},A:{baseUnit:\"A\",variants:{\"µA\":1e-6,mA:.001,ma:.001,A:1,kA:1e3,MA:1e6}},F:{baseUnit:\"F\",variants:{pF:1e-12,nF:1e-9,\"µF\":1e-6,uF:1e-6,mF:.001,F:1}},ml:{baseUnit:\"ml\",variants:{ml:1,mL:1,l:1e3,L:1e3}},deg:{baseUnit:\"deg\",variants:{rad:180/Math.PI}},ms:{baseUnit:\"ms\",variants:{fs:1e-12,ps:1e-9,ns:1e-6,us:.001,\"µs\":.001,ms:1,s:1e3}},mm:{baseUnit:\"mm\",variants:{nm:1e-6,\"µm\":.001,um:.001,mm:1,cm:10,dm:100,m:1e3,km:1e6,in:25.4,ft:304.8,IN:25.4,FT:304.8,yd:914.4,mi:1609344,mil:.0254}}},kM=new Set;for(const[t,e]of Object.entries(OM)){kM.add(t);for(const t of Object.keys(e.variants))kM.add(t)}var LM={tera:1e12,T:1e12,giga:1e9,G:1e9,mega:1e6,M:1e6,kilo:1e3,k:1e3,deci:.1,d:.1,centi:.01,c:.01,milli:.001,m:.001,micro:1e-6,u:1e-6,\"µ\":1e-6,nano:1e-9,n:1e-9,pico:1e-12,p:1e-12};function DM(t){if(null==t)return{parsedUnit:null,unitOfValue:null,value:null};if(\"string\"==typeof t\u0026\u0026t.match(/^-?[\\d\\.]+$/))return{value:Number.parseFloat(t),parsedUnit:null,unitOfValue:null};if(\"number\"==typeof t)return{value:t,parsedUnit:null,unitOfValue:null};if(\"object\"==typeof t\u0026\u0026\"x\"in t\u0026\u0026\"y\"in t){const{parsedUnit:e,unitOfValue:n}=DM(t.x),o=DM(t.x),i=DM(t.y);return null===o.value||null===i.value?{parsedUnit:null,unitOfValue:null,value:null}:{parsedUnit:e,unitOfValue:n,value:{x:o.value,y:i.value}}}const e=t.toString().split(\"\").reverse().join(\"\"),n=e.match(/[^\\d\\s]+/)?.[0];if(!n)throw new Error(`Could not determine unit: \"${t}\"`);const o=n.split(\"\").reverse().join(\"\"),i=t.slice(0,-o.length);if(o in LM\u0026\u0026!kM.has(o)){const t=LM[o];return{parsedUnit:null,unitOfValue:null,value:Number.parseFloat(i)*t}}const{baseUnit:r,conversionFactor:s}=function(t){for(const[e,n]of Object.entries(OM))if(t in n.variants)return{baseUnit:n.baseUnit,conversionFactor:n.variants[t]};return{baseUnit:t,conversionFactor:1}}(o);return{parsedUnit:o,unitOfValue:r,value:s*Number.parseFloat(i)}}var zM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),FM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value).transform(t=\u003eNumber.parseFloat(t.toPrecision(12))),BM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),jM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),$M=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),YM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),XM=$M,VM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),WM=k_.string().or(k_.number()).transform(t=\u003eDM(t).value),HM=WM,GM=k_.string().datetime(),UM=k_.string().or(k_.number()).transform(t=\u003e\"number\"==typeof t?t:t.endsWith(\"deg\")?Number.parseFloat(t.split(\"deg\")[0]):t.endsWith(\"rad\")?180*Number.parseFloat(t.split(\"rad\")[0])/Math.PI:Number.parseFloat(t)),ZM=k_.number().or(k_.string().endsWith(\"mAh\")).transform(t=\u003e{if(\"string\"==typeof t){const e=t.replace(\"mAh\",\"\"),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error(\"Invalid capacity\");return n}return t}).describe(\"Battery capacity in mAh\"),qM=k_.object({x:XM,y:XM}),JM=k_.object({x:XM,y:XM,z:XM}),KM=k_.object({width:k_.number(),height:k_.number()}),QM=t=\u003ek_.string().optional().default(()=\u003e`${t}_${(t=\u003e{const e=\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";return Array.from({length:t},()=\u003ee[Math.floor(62*Math.random())]).join(\"\")})(10)}`),tN=k_.enum([\"top_left\",\"top_center\",\"top_right\",\"center_left\",\"center\",\"center_right\",\"bottom_left\",\"bottom_center\",\"bottom_right\"]),eN=(k_.enum([\"top_silkscreen\",\"bottom_silkscreen\",\"top_copper\",\"bottom_copper\",\"top_soldermask\",\"bottom_soldermask\",\"top_fabrication_note\",\"bottom_fabrication_note\",\"top_user_note\",\"bottom_user_note\",\"top_courtyard\",\"bottom_courtyard\",\"inner1_copper\",\"inner2_copper\",\"inner3_copper\",\"inner4_copper\",\"inner5_copper\",\"inner6_copper\",\"edge_cuts\",\"drill\"]),k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()})),nN=qM.extend({rotation:UM.optional()}),oN=k_.object({size:qM.optional(),thickness:XM.optional()}),iN=k_.object({font:oN.optional()}),rN=k_.object({value:k_.string(),at:nN.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:iN.optional()}),sN=k_.object({Reference:rN.optional(),Value:rN.optional(),Datasheet:rN.optional(),Description:rN.optional()}),aN=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),cN=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:nN.optional(),size:qM.optional(),drill:XM.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),lN=k_.object({path:k_.string(),offset:JM.optional(),scale:JM.optional(),rotate:JM.optional()}),dN=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:sN.optional(),attributes:aN.optional(),pads:k_.array(cN).optional(),embeddedFonts:k_.boolean().optional(),model:lN.optional()}),hN=k_.object({hide:k_.boolean().optional()}),uN=k_.object({offset:XM.optional(),hide:k_.boolean().optional()}),pN=k_.object({font:oN.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),mN=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:nN.optional(),effects:pN.optional()}),gN=k_.object({Reference:mN.optional(),Value:mN.optional(),Footprint:mN.optional(),Datasheet:mN.optional(),Description:mN.optional(),ki_keywords:mN.optional(),ki_fp_filters:mN.optional()}),fN=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:hN.optional(),pinNames:uN.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:gN.optional(),embeddedFonts:k_.boolean().optional()}),yN=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),_N=k_.enum([\"jlcpcb\",\"macrofab\",\"pcbway\",\"digikey\",\"mouser\",\"lcsc\"]),bN=k_.object({type:k_.literal(\"source_component\"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(_N,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),xN=bN.extend({ftype:k_.literal(\"simple_capacitor\"),capacitance:FM,max_voltage_rating:jM.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:XM.optional()}),vN=bN.extend({ftype:k_.literal(\"simple_resistor\"),resistance:zM,display_resistance:k_.string().optional()}),SN=bN.extend({ftype:k_.literal(\"simple_diode\")}),IN=bN.extend({ftype:k_.literal(\"simple_fiducial\")}),CN=SN.extend({ftype:k_.literal(\"simple_led\"),color:k_.string().optional(),wavelength:k_.string().optional()}),PN=bN.extend({ftype:k_.literal(\"simple_ground\")}),MN=bN.extend({ftype:k_.literal(\"simple_chip\")}),NN=bN.extend({ftype:k_.literal(\"simple_power_source\"),voltage:jM}),wN=bN.extend({ftype:k_.literal(\"simple_current_source\"),current:VM,frequency:YM.optional(),peak_to_peak_current:VM.optional(),wave_shape:k_.enum([\"sine\",\"square\",\"triangle\",\"sawtooth\",\"dc\"]).optional().default(\"dc\"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),TN=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),RN=bN.extend({ftype:k_.literal(\"simple_fuse\"),current_rating_amps:k_.number().describe(\"Nominal current in amps the fuse is rated for\"),voltage_rating_volts:k_.number().describe(\"Voltage rating in volts, e.g. ±5V would be 5\")}),EN=bN.extend({ftype:k_.literal(\"simple_battery\"),capacity:ZM}),AN=bN.extend({ftype:k_.literal(\"simple_inductor\"),inductance:BM,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),ON=bN.extend({ftype:k_.literal(\"simple_push_button\")}),kN=bN.extend({ftype:k_.literal(\"simple_potentiometer\"),max_resistance:zM,display_max_resistance:k_.string().optional()}),LN=bN.extend({ftype:k_.literal(\"simple_crystal\"),frequency:k_.number().describe(\"Frequency in Hz\"),load_capacitance:k_.number().optional().describe(\"Load capacitance in pF\"),pin_variant:k_.enum([\"two_pin\",\"four_pin\"]).optional()}),DN=bN.extend({ftype:k_.literal(\"simple_pin_header\"),pin_count:k_.number(),gender:k_.enum([\"male\",\"female\"]).optional().default(\"male\")}),zN=bN.extend({ftype:k_.literal(\"simple_connector\"),standard:k_.enum([\"usb_c\",\"m2\"]).optional()}),FN=bN.extend({ftype:k_.literal(\"simple_pinout\")}),BN=bN.extend({ftype:k_.literal(\"simple_resonator\"),load_capacitance:FM,equivalent_series_resistance:zM.optional(),frequency:YM}),jN=bN.extend({ftype:k_.literal(\"simple_transistor\"),transistor_type:k_.enum([\"npn\",\"pnp\"])}),$N=bN.extend({ftype:k_.literal(\"simple_test_point\"),footprint_variant:k_.enum([\"pad\",\"through_hole\"]).optional(),pad_shape:k_.enum([\"rect\",\"circle\"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),YN=bN.extend({ftype:k_.literal(\"simple_mosfet\"),channel_type:k_.enum([\"n\",\"p\"]),mosfet_mode:k_.enum([\"enhancement\",\"depletion\"])}),XN=bN.extend({ftype:k_.literal(\"simple_op_amp\")}),VN=bN.extend({ftype:k_.literal(\"simple_switch\")}),WN=k_.object({type:k_.literal(\"source_project_metadata\"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),created_at:GM.optional()}),HN=yN.extend({type:k_.literal(\"source_missing_property_error\"),source_missing_property_error_id:QM(\"source_missing_property_error\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_missing_property_error\").default(\"source_missing_property_error\")}).describe(\"The source code is missing a property\"),GN=yN.extend({type:k_.literal(\"source_failed_to_create_component_error\"),source_failed_to_create_component_error_id:QM(\"source_failed_to_create_component_error\"),error_type:k_.literal(\"source_failed_to_create_component_error\").default(\"source_failed_to_create_component_error\"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe(\"Error emitted when a component fails to be constructed\"),UN=yN.extend({type:k_.literal(\"source_invalid_component_property_error\"),source_invalid_component_property_error_id:QM(\"source_invalid_component_property_error\"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_invalid_component_property_error\").default(\"source_invalid_component_property_error\")}).describe(\"The source component property is invalid\"),ZN=yN.extend({type:k_.literal(\"source_trace_not_connected_error\"),source_trace_not_connected_error_id:QM(\"source_trace_not_connected_error\"),error_type:k_.literal(\"source_trace_not_connected_error\").default(\"source_trace_not_connected_error\"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe(\"Occurs when a source trace selector does not match any ports\"),qN=k_.object({type:k_.literal(\"source_property_ignored_warning\"),source_property_ignored_warning_id:QM(\"source_property_ignored_warning\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_property_ignored_warning\").default(\"source_property_ignored_warning\"),message:k_.string()}).describe(\"The source property was ignored\"),JN=k_.object({type:k_.literal(\"source_pin_missing_trace_warning\"),source_pin_missing_trace_warning_id:QM(\"source_pin_missing_trace_warning\"),warning_type:k_.literal(\"source_pin_missing_trace_warning\").default(\"source_pin_missing_trace_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component pin is missing a trace connection\"),KN=k_.object({type:k_.literal(\"source_missing_manufacturer_part_number_warning\"),source_missing_manufacturer_part_number_warning_id:QM(\"source_missing_manufacturer_part_number_warning\"),warning_type:k_.literal(\"source_missing_manufacturer_part_number_warning\").default(\"source_missing_manufacturer_part_number_warning\"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a standard connector is missing manufacturer part number\"),QN=bN.extend({ftype:k_.literal(\"simple_voltage_probe\")}),tw=bN.extend({ftype:k_.literal(\"interconnect\")}),ew=yN.extend({type:k_.literal(\"source_i2c_misconfigured_error\"),source_i2c_misconfigured_error_id:QM(\"source_i2c_misconfigured_error\"),error_type:k_.literal(\"source_i2c_misconfigured_error\").default(\"source_i2c_misconfigured_error\"),source_port_ids:k_.array(k_.string())}).describe(\"Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net\"),nw=bN.extend({ftype:k_.literal(\"simple_voltage_source\"),voltage:jM,frequency:YM.optional(),peak_to_peak_voltage:jM.optional(),wave_shape:k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]).optional(),phase:UM.optional(),duty_cycle:k_.number().optional().describe(\"Duty cycle as a fraction (0 to 1)\")}),ow=k_.union([vN,xN,SN,IN,CN,PN,MN,NN,wN,EN,AN,ON,kN,LN,DN,zN,FN,BN,VN,jN,$N,YN,XN,RN,QN,tw,nw,WN,HN,UN,GN,ZN,qN,JN,KN,ew]),iw=k_.object({type:k_.literal(\"source_port\"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(TN),rw=k_.object({type:k_.literal(\"source_component_internal_connection\"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),sw=k_.object({type:k_.literal(\"source_trace\"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),aw=k_.object({type:k_.literal(\"source_group\"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),cw=k_.object({type:k_.literal(\"source_net\"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),lw=k_.object({type:k_.literal(\"source_board\"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe(\"Defines a board in the source domain\"),dw=yN.extend({type:k_.literal(\"source_ambiguous_port_reference\"),source_ambiguous_port_reference_id:QM(\"source_ambiguous_port_reference\"),error_type:k_.literal(\"source_ambiguous_port_reference\").default(\"source_ambiguous_port_reference\"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous\"),hw=k_.object({type:k_.literal(\"source_pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane in the source domain\"),uw=[\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\"],pw=k_.enum(uw),mw=pw.or(k_.object({name:pw})).transform(t=\u003e\"string\"==typeof t?t:t.name),gw=k_.enum([\"top\",\"bottom\"]),fw=k_.object({type:k_.literal(\"source_manually_placed_via\"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe(\"Defines a via that is manually placed in the source domain\"),yw=k_.object({type:k_.literal(\"source_no_power_pin_defined_warning\"),source_no_power_pin_defined_warning_id:QM(\"source_no_power_pin_defined_warning\"),warning_type:k_.literal(\"source_no_power_pin_defined_warning\").default(\"source_no_power_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports with requires_power=true\"),_w=k_.object({type:k_.literal(\"source_no_ground_pin_defined_warning\"),source_no_ground_pin_defined_warning_id:QM(\"source_no_ground_pin_defined_warning\"),warning_type:k_.literal(\"source_no_ground_pin_defined_warning\").default(\"source_no_ground_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports marked as ground pins\"),bw=k_.object({type:k_.literal(\"source_component_pins_underspecified_warning\"),source_component_pins_underspecified_warning_id:QM(\"source_component_pins_underspecified_warning\"),warning_type:k_.literal(\"source_component_pins_underspecified_warning\").default(\"source_component_pins_underspecified_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when all ports on a source component are underspecified\"),xw=yN.extend({type:k_.literal(\"source_pin_must_be_connected_error\"),source_pin_must_be_connected_error_id:QM(\"source_pin_must_be_connected_error\"),error_type:k_.literal(\"source_pin_must_be_connected_error\").default(\"source_pin_must_be_connected_error\"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pin with mustBeConnected attribute is not connected to any trace\"),vw=yN.extend({type:k_.literal(\"unknown_error_finding_part\"),unknown_error_finding_part_id:QM(\"unknown_error_finding_part\"),error_type:k_.literal(\"unknown_error_finding_part\").default(\"unknown_error_finding_part\"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when an unexpected error occurs while finding a part\"),Sw=k_.object({type:k_.literal(\"schematic_box\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:XM,height:XM,is_dashed:k_.boolean().default(!1),x:XM,y:XM,subcircuit_id:k_.string().optional()}).describe(\"Draws a box on the schematic\"),Iw=k_.object({type:k_.literal(\"schematic_path\"),schematic_path_id:QM(\"schematic_path\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),stroke_width:XM.nullable().optional(),stroke_color:k_.string().optional(),points:k_.array(qM),subcircuit_id:k_.string().optional()}),Cw=k_.record(k_.object({left_margin:$M.optional(),right_margin:$M.optional(),top_margin:$M.optional(),bottom_margin:$M.optional()})),Pw=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),Mw=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional()}),Nw=k_.union([Pw,Mw]),ww=k_.object({type:k_.literal(\"schematic_component\"),size:KM,center:qM,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_symbol_id:k_.string().optional(),pin_spacing:$M.optional(),pin_styles:Cw.optional(),box_width:$M.optional(),symbol_name:k_.string().optional(),port_arrangement:Nw.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),Tw=k_.object({kicad_symbol:fN.optional()}).catchall(k_.unknown()),Rw=k_.object({type:k_.literal(\"schematic_symbol\"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:Tw.optional()}).describe(\"Defines a named schematic symbol that can be referenced by components.\"),Ew=k_.object({type:k_.literal(\"schematic_line\"),schematic_line_id:QM(\"schematic_line\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:XM,y1:XM,x2:XM,y2:XM,stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled line on the schematic\"),Aw=k_.object({type:k_.literal(\"schematic_rect\"),schematic_rect_id:QM(\"schematic_rect\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,width:XM,height:XM,rotation:UM.default(0),stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled rectangle on the schematic\"),Ow=k_.object({type:k_.literal(\"schematic_circle\"),schematic_circle_id:QM(\"schematic_circle\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,radius:XM,stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled circle on the schematic\"),kw=k_.object({type:k_.literal(\"schematic_arc\"),schematic_arc_id:QM(\"schematic_arc\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,radius:XM,start_angle_degrees:UM,end_angle_degrees:UM,direction:k_.enum([\"clockwise\",\"counterclockwise\"]).default(\"counterclockwise\"),stroke_width:XM.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled arc on the schematic\"),Lw=k_.object({type:k_.literal(\"schematic_trace\"),schematic_trace_id:k_.string(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),Dw=k_.enum([\"center\",\"left\",\"right\",\"top\",\"bottom\"]),zw=k_.object({type:k_.literal(\"schematic_text\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:XM,y:XM}),rotation:k_.number().default(0),anchor:k_.union([Dw.describe(\"legacy\"),tN]).default(\"center\"),color:k_.string().default(\"#000000\"),subcircuit_id:k_.string().optional()}),Fw=k_.object({type:k_.literal(\"schematic_port\"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_component_id:k_.string().optional(),center:qM,facing_direction:k_.enum([\"up\",\"down\",\"left\",\"right\"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe(\"Defines a port on a schematic component\"),Bw=k_.object({type:k_.literal(\"schematic_net_label\"),schematic_net_label_id:QM(\"schematic_net_label\"),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:qM,anchor_position:qM.optional(),anchor_side:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),jw=yN.extend({type:k_.literal(\"schematic_error\"),schematic_error_id:k_.string(),error_type:k_.literal(\"schematic_port_not_found\").default(\"schematic_port_not_found\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic error on the schematic\"),$w=yN.extend({type:k_.literal(\"schematic_layout_error\"),schematic_layout_error_id:QM(\"schematic_layout_error\"),error_type:k_.literal(\"schematic_layout_error\").default(\"schematic_layout_error\"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when schematic layout fails for a group\"),Yw=k_.object({type:k_.literal(\"schematic_debug_object\"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),Xw=Yw.extend({shape:k_.literal(\"rect\"),center:qM,size:KM}),Vw=Yw.extend({shape:k_.literal(\"line\"),start:qM,end:qM}),Ww=Yw.extend({shape:k_.literal(\"point\"),center:qM}),Hw=k_.discriminatedUnion(\"shape\",[Xw,Vw,Ww]),Gw=k_.object({type:k_.literal(\"schematic_voltage_probe\"),schematic_voltage_probe_id:k_.string(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:qM,schematic_trace_id:k_.string(),voltage:jM.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:tN.optional()}).describe(\"Defines a voltage probe measurement point on a schematic trace\"),Uw=k_.object({type:k_.literal(\"schematic_manual_edit_conflict_warning\"),schematic_manual_edit_conflict_warning_id:QM(\"schematic_manual_edit_conflict_warning\"),warning_type:k_.literal(\"schematic_manual_edit_conflict_warning\").default(\"schematic_manual_edit_conflict_warning\"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit schX/schY coordinates\"),Zw=k_.object({type:k_.literal(\"schematic_group\"),schematic_group_id:QM(\"schematic_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:$M,height:$M,center:qM,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe(\"Defines a group of components on the schematic\"),qw=k_.object({type:k_.literal(\"schematic_table\"),schematic_table_id:QM(\"schematic_table\"),anchor_position:qM,column_widths:k_.array(XM),row_heights:k_.array(XM),cell_padding:XM.optional(),border_width:XM.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:tN.optional()}).describe(\"Defines a table on the schematic\"),Jw=k_.object({type:k_.literal(\"schematic_table_cell\"),schematic_table_cell_id:QM(\"schematic_table_cell\"),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:qM,width:XM,height:XM,horizontal_align:k_.enum([\"left\",\"center\",\"right\"]).optional(),vertical_align:k_.enum([\"top\",\"middle\",\"bottom\"]).optional(),font_size:XM.optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a cell within a schematic_table\"),Kw=k_.object({type:k_.literal(\"schematic_sheet\"),schematic_sheet_id:QM(\"schematic_sheet\"),name:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic sheet or page that components can be placed on\"),Qw=k_.object({x:XM,y:XM,bulge:k_.number().optional()}),tT=k_.object({vertices:k_.array(Qw)}),eT=k_.object({outer_ring:tT,inner_rings:k_.array(tT).default([])}),nT=k_.object({x:XM,y:XM,via:k_.boolean().optional(),via_to_layer:mw.optional()}),oT=(k_.array(nT),k_.object({x:XM,y:XM,via:k_.boolean().optional(),to_layer:mw.optional(),trace_width:XM.optional()})),iT=k_.object({min_trace_width:$M.optional(),min_board_edge_clearance:$M.optional(),min_via_hole_edge_to_via_hole_edge_clearance:$M.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:$M.optional(),min_trace_to_pad_edge_clearance:$M.optional(),min_pad_edge_to_pad_edge_clearance:$M.optional(),min_same_net_trace_edge_to_trace_edge_clearance:$M.optional(),min_different_net_trace_edge_to_trace_edge_clearance:$M.optional(),min_via_hole_diameter:$M.optional(),min_via_pad_diameter:$M.optional()}),rT=k_.object({type:k_.literal(\"pcb_component\"),pcb_component_id:QM(\"pcb_component\"),source_component_id:k_.string(),center:qM,layer:mw,rotation:UM,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this part, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this part, usually corresponding with how the user specified it\"),width:$M,height:$M,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"relative_to_another_component\",\"none\"]).optional(),anchor_position:qM.optional(),anchor_alignment:tN.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:qM.optional(),insertion_direction:k_.enum([\"from_above\",\"from_left\",\"from_right\",\"from_front\",\"from_back\"]).optional(),metadata:k_.object({kicad_footprint:dN.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe(\"Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath\")}).describe(\"Defines a component on the PCB\"),sT=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),hole_diameter:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),aT=(sT.describe(\"Defines a circular hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),cT=(aT.describe(\"Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"square\"]),hole_diameter:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),lT=(cT.describe(\"Defines a circular or square hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"oval\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),dT=(lT.describe(\"Defines an oval hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),hT=(dT.describe(\"Defines a pill-shaped hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:QM(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,ccw_rotation:UM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),uT=(hT.describe(\"Defines a rotated pill-shaped hole on the PCB\"),cT.or(lT).or(dT).or(hT).or(sT).or(aT)),pT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),mT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.enum([\"oval\",\"pill\"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,ccw_rotation:UM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),gT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circular_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),pad_shape:k_.literal(\"rect\"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:UM.optional()}),fT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),yT=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"rotated_pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:UM,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:UM,hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),_T=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"hole_with_polygon_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"oval\",\"pill\",\"rotated_pill\"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:XM,y:XM})).min(3),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),ccw_rotation:UM.optional()}),bT=k_.union([pT,mT,gT,fT,yT,_T]),xT=k_.object({type:k_.literal(\"pcb_port\"),pcb_port_id:QM(\"pcb_port\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:XM,y:XM,layers:k_.array(mw),is_board_pinout:k_.boolean().optional()}).describe(\"Defines a port on the PCB\"),vT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"circle\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,radius:k_.number(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),ST=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rect\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),IT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_rect\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:UM,layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),CT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"pill\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),PT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_pill\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:UM,layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),MT=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"polygon\"),pcb_smtpad_id:QM(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(qM),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),NT=k_.discriminatedUnion(\"shape\",[vT,ST,IT,PT,CT,MT]).describe(\"Defines an SMT pad on the PCB\"),wT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"circle\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,radius:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),TT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rect\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),RT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"pill\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),ET=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rotated_rect\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),ccw_rotation:XM,layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),AT=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"oval\"),pcb_solder_paste_id:QM(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),OT=k_.union([wT,TT,RT,ET,AT]).describe(\"Defines solderpaste on the PCB\"),kT=k_.object({type:k_.literal(\"pcb_text\"),pcb_text_id:QM(\"pcb_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:qM,layer:mw,width:$M,height:$M,lines:k_.number(),align:k_.enum([\"bottom-left\"])}).describe(\"Defines text on the PCB\"),LT=k_.object({route_type:k_.literal(\"wire\"),x:XM,y:XM,width:XM,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:mw}),DT=k_.object({route_type:k_.literal(\"via\"),x:XM,y:XM,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:XM.optional(),outer_diameter:XM.optional(),from_layer:mw,to_layer:mw}),zT=k_.union([LT,DT]),FT=k_.object({type:k_.literal(\"pcb_trace\"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:QM(\"pcb_trace\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum([\"constant\",\"interpolated\"]).default(\"constant\").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(zT)}).describe(\"Defines a trace on the PCB\"),BT=k_.object({type:k_.literal(\"pcb_trace_warning\"),pcb_trace_warning_id:QM(\"pcb_trace_warning\"),warning_type:k_.literal(\"pcb_trace_warning\").default(\"pcb_trace_warning\"),message:k_.string(),center:qM.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace warning on the PCB\"),jT=yN.extend({type:k_.literal(\"pcb_trace_error\"),pcb_trace_error_id:QM(\"pcb_trace_error\"),error_type:k_.literal(\"pcb_trace_error\").default(\"pcb_trace_error\"),center:qM.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB\"),$T=yN.extend({type:k_.literal(\"pcb_trace_missing_error\"),pcb_trace_missing_error_id:QM(\"pcb_trace_missing_error\"),error_type:k_.literal(\"pcb_trace_missing_error\").default(\"pcb_trace_missing_error\"),center:qM.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a source trace has no corresponding PCB trace\"),YT=yN.extend({type:k_.literal(\"pcb_port_not_matched_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_port_not_matched_error\").default(\"pcb_port_not_matched_error\"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB where a port is not matched\"),XT=yN.extend({type:k_.literal(\"pcb_port_not_connected_error\"),pcb_port_not_connected_error_id:QM(\"pcb_port_not_connected_error\"),error_type:k_.literal(\"pcb_port_not_connected_error\").default(\"pcb_port_not_connected_error\"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a pcb port is not connected to any trace\"),VT=k_.object({type:k_.literal(\"pcb_net\"),pcb_net_id:QM(\"pcb_net\"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe(\"Defines a net on the PCB\"),WT=k_.object({type:k_.literal(\"pcb_via\"),pcb_via_id:QM(\"pcb_via\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:XM,y:XM,outer_diameter:XM.default(\"0.6mm\"),hole_diameter:XM.default(\"0.25mm\"),from_layer:mw.optional(),to_layer:mw.optional(),layers:k_.array(mw),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe(\"Defines a via on the PCB\"),HT=k_.object({type:k_.literal(\"pcb_board\"),pcb_board_id:QM(\"pcb_board\"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:$M.optional(),height:$M.optional(),center:qM,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this board, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this board, usually corresponding with how the user specified it\"),thickness:$M.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(qM).optional(),shape:k_.enum([\"rect\",\"polygon\"]).optional(),material:k_.enum([\"fr4\",\"fr1\"]).default(\"fr4\"),anchor_position:qM.optional(),anchor_alignment:tN.optional(),position_mode:k_.enum([\"relative_to_panel_anchor\",\"none\"]).optional()}).merge(iT).describe(\"Defines the board outline of the PCB\"),GT=k_.object({type:k_.literal(\"pcb_panel\"),pcb_panel_id:QM(\"pcb_panel\"),width:$M,height:$M,center:qM,thickness:$M.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe(\"Defines a PCB panel that can contain multiple boards\"),UT=yN.extend({type:k_.literal(\"pcb_placement_error\"),pcb_placement_error_id:QM(\"pcb_placement_error\"),error_type:k_.literal(\"pcb_placement_error\").default(\"pcb_placement_error\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a placement error on the PCB\"),ZT=yN.extend({type:k_.literal(\"pcb_panelization_placement_error\"),pcb_panelization_placement_error_id:QM(\"pcb_panelization_placement_error\"),error_type:k_.literal(\"pcb_panelization_placement_error\").default(\"pcb_panelization_placement_error\"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a panelization placement error on the PCB\"),qT=k_.object({type:k_.literal(\"pcb_trace_hint\"),pcb_trace_hint_id:QM(\"pcb_trace_hint\"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(oT),subcircuit_id:k_.string().optional()}).describe(\"A hint that can be used during generation of a PCB trace\"),JT=k_.object({type:k_.literal(\"pcb_silkscreen_line\"),pcb_silkscreen_line_id:QM(\"pcb_silkscreen_line\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:XM.default(\"0.1mm\"),x1:XM,y1:XM,x2:XM,y2:XM,layer:gw}).describe(\"Defines a silkscreen line on the PCB\"),KT=k_.object({type:k_.literal(\"pcb_silkscreen_path\"),pcb_silkscreen_path_id:QM(\"pcb_silkscreen_path\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,route:k_.array(qM),stroke_width:$M}).describe(\"Defines a silkscreen path on the PCB\"),QT=k_.object({type:k_.literal(\"pcb_silkscreen_text\"),pcb_silkscreen_text_id:QM(\"pcb_silkscreen_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:$M,top:$M,bottom:$M,right:$M}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:mw,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:tN.default(\"center\")}).describe(\"Defines silkscreen text on the PCB\"),tR=k_.object({type:k_.literal(\"pcb_copper_text\"),pcb_copper_text_id:QM(\"pcb_copper_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:$M,top:$M,bottom:$M,right:$M}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:mw,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:tN.default(\"center\")}).describe(\"Defines copper text on the PCB\"),eR=k_.object({type:k_.literal(\"pcb_silkscreen_rect\"),pcb_silkscreen_rect_id:QM(\"pcb_silkscreen_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:mw,stroke_width:$M.default(\"1mm\"),corner_radius:$M.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen rect on the PCB\"),nR=k_.object({type:k_.literal(\"pcb_silkscreen_circle\"),pcb_silkscreen_circle_id:QM(\"pcb_silkscreen_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:$M,layer:gw,stroke_width:$M.default(\"1mm\"),is_filled:k_.boolean().optional()}).describe(\"Defines a silkscreen circle on the PCB\"),oR=k_.object({type:k_.literal(\"pcb_silkscreen_oval\"),pcb_silkscreen_oval_id:QM(\"pcb_silkscreen_oval\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius_x:XM,radius_y:XM,layer:gw,ccw_rotation:UM.optional()}).describe(\"Defines a silkscreen oval on the PCB\"),iR=k_.object({type:k_.literal(\"pcb_silkscreen_pill\"),pcb_silkscreen_pill_id:QM(\"pcb_silkscreen_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:mw,ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen pill on the PCB\"),rR=k_.object({type:k_.literal(\"pcb_fabrication_note_text\"),pcb_fabrication_note_text_id:QM(\"pcb_fabrication_note_text\"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"1mm\"),pcb_component_id:k_.string(),text:k_.string(),layer:gw,anchor_position:qM.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),color:k_.string().optional()}).describe(\"Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators\"),sR=k_.object({type:k_.literal(\"pcb_fabrication_note_path\"),pcb_fabrication_note_path_id:QM(\"pcb_fabrication_note_path\"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:mw,route:k_.array(qM),stroke_width:$M,color:k_.string().optional()}).describe(\"Defines a fabrication path on the PCB for fabricators or assemblers\"),aR=k_.object({type:k_.literal(\"pcb_fabrication_note_rect\"),pcb_fabrication_note_rect_id:QM(\"pcb_fabrication_note_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw,stroke_width:$M.default(\"0.1mm\"),corner_radius:$M.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a fabrication note rectangle on the PCB\"),cR=k_.object({type:k_.literal(\"pcb_fabrication_note_dimension\"),pcb_fabrication_note_dimension_id:QM(\"pcb_fabrication_note_dimension\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,from:qM,to:qM,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:$M.optional(),offset_distance:$M.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:$M.default(\"1mm\"),color:k_.string().optional(),arrow_size:$M.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB fabrication notes\"),lR=k_.object({type:k_.literal(\"pcb_note_text\"),pcb_note_text_id:QM(\"pcb_note_text\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:XM.default(\"1mm\"),text:k_.string().optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),layer:gw.default(\"top\"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a documentation note in text on the PCB\"),dR=k_.object({type:k_.literal(\"pcb_note_rect\"),pcb_note_rect_id:QM(\"pcb_note_rect\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw.default(\"top\"),stroke_width:$M.default(\"0.1mm\"),corner_radius:$M.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a rectangular documentation note on the PCB\"),hR=k_.object({type:k_.literal(\"pcb_note_path\"),pcb_note_path_id:QM(\"pcb_note_path\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(qM),layer:gw.default(\"top\"),stroke_width:$M.default(\"0.1mm\"),color:k_.string().optional()}).describe(\"Defines a polyline documentation note on the PCB\"),uR=k_.object({type:k_.literal(\"pcb_note_line\"),pcb_note_line_id:QM(\"pcb_note_line\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:XM,y1:XM,x2:XM,y2:XM,layer:gw.default(\"top\"),stroke_width:XM.default(\"0.1mm\"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe(\"Defines a straight documentation note line on the PCB\"),pR=k_.object({type:k_.literal(\"pcb_note_dimension\"),pcb_note_dimension_id:QM(\"pcb_note_dimension\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:qM,to:qM,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:$M.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:$M.default(\"1mm\"),layer:gw.default(\"top\"),color:k_.string().optional(),arrow_size:$M.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB documentation notes\"),mR=yN.extend({type:k_.literal(\"pcb_footprint_overlap_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_footprint_overlap_error\").default(\"pcb_footprint_overlap_error\"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when a pcb footprint overlaps with another element\"),gR=yN.extend({type:k_.literal(\"pcb_courtyard_overlap_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_courtyard_overlap_error\").default(\"pcb_courtyard_overlap_error\"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe(\"Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another\"),fR=k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"rect\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:XM,height:XM,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:XM,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),yR=k_.object({type:k_.literal(\"pcb_cutout\"),pcb_cutout_id:QM(\"pcb_cutout\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),_R=yR.extend({shape:k_.literal(\"rect\"),center:qM,width:$M,height:$M,rotation:UM.optional(),corner_radius:$M.optional()}),bR=yR.extend({shape:k_.literal(\"circle\"),center:qM,radius:$M}),xR=yR.extend({shape:k_.literal(\"polygon\"),points:k_.array(qM)}),vR=yR.extend({shape:k_.literal(\"path\"),route:k_.array(qM),slot_width:$M,slot_length:$M.optional(),space_between_slots:$M.optional(),slot_corner_radius:$M.optional()}),SR=k_.discriminatedUnion(\"shape\",[_R,bR,xR,vR]).describe(\"Defines a cutout on the PCB, removing board material.\"),IR=yN.extend({type:k_.literal(\"pcb_missing_footprint_error\"),pcb_missing_footprint_error_id:QM(\"pcb_missing_footprint_error\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"pcb_missing_footprint_error\").default(\"pcb_missing_footprint_error\"),source_component_id:k_.string()}).describe(\"Defines a missing footprint error on the PCB\"),CR=yN.extend({type:k_.literal(\"external_footprint_load_error\"),external_footprint_load_error_id:QM(\"external_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal(\"external_footprint_load_error\").default(\"external_footprint_load_error\")}).describe(\"Defines an error when an external footprint fails to load\"),PR=yN.extend({type:k_.literal(\"circuit_json_footprint_load_error\"),circuit_json_footprint_load_error_id:QM(\"circuit_json_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"circuit_json_footprint_load_error\").default(\"circuit_json_footprint_load_error\"),circuit_json:k_.array(k_.any()).optional()}).describe(\"Defines an error when a circuit JSON footprint fails to load\"),MR=k_.object({type:k_.literal(\"pcb_group\"),pcb_group_id:QM(\"pcb_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:$M.optional(),height:$M.optional(),center:qM,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this group, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this group, usually corresponding with how the user specified it\"),outline:k_.array(qM).optional(),anchor_position:qM.optional(),anchor_alignment:tN.default(\"center\"),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"none\"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum([\"packed\",\"none\"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:$M}).optional(),autorouter_used_string:k_.string().optional()}).describe(\"Defines a group of components on the PCB\"),NR=yN.extend({type:k_.literal(\"pcb_autorouting_error\"),pcb_error_id:QM(\"pcb_autorouting_error\"),error_type:k_.literal(\"pcb_autorouting_error\").default(\"pcb_autorouting_error\"),subcircuit_id:k_.string().optional()}).describe(\"The autorouting has failed to route a portion of the board\"),wR=k_.object({type:k_.literal(\"pcb_manual_edit_conflict_warning\"),pcb_manual_edit_conflict_warning_id:QM(\"pcb_manual_edit_conflict_warning\"),warning_type:k_.literal(\"pcb_manual_edit_conflict_warning\").default(\"pcb_manual_edit_conflict_warning\"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates\"),TR=k_.enum([\"x-\",\"x+\",\"y+\",\"y-\"]),RR=k_.object({type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\"),pcb_connector_not_in_accessible_orientation_warning_id:QM(\"pcb_connector_not_in_accessible_orientation_warning\"),warning_type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\").default(\"pcb_connector_not_in_accessible_orientation_warning\"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:TR,recommended_facing_direction:TR,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction\"),ER=k_.object({type:k_.literal(\"supplier_footprint_mismatch_warning\"),supplier_footprint_mismatch_warning_id:QM(\"supplier_footprint_mismatch_warning\"),warning_type:k_.literal(\"supplier_footprint_mismatch_warning\").default(\"supplier_footprint_mismatch_warning\"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:_N.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe(\"Warning emitted when a supplier part footprint does not match the expected footprint\"),AR=k_.object({type:k_.literal(\"pcb_breakout_point\"),pcb_breakout_point_id:QM(\"pcb_breakout_point\"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:XM,y:XM}).describe(\"Defines a routing target within a pcb_group for a source_trace or source_net\"),OR=k_.object({type:k_.literal(\"pcb_ground_plane\"),pcb_ground_plane_id:QM(\"pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane on the PCB\"),kR=k_.object({type:k_.literal(\"pcb_ground_plane_region\"),pcb_ground_plane_region_id:QM(\"pcb_ground_plane_region\"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:mw,points:k_.array(qM)}).describe(\"Defines a polygon region of a ground plane\"),LR=k_.object({type:k_.literal(\"pcb_thermal_spoke\"),pcb_thermal_spoke_id:QM(\"pcb_thermal_spoke\"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:XM,spoke_inner_diameter:XM,spoke_outer_diameter:XM,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Pattern for connecting a ground plane to a plated hole\"),DR=k_.object({type:k_.literal(\"pcb_copper_pour\"),pcb_copper_pour_id:QM(\"pcb_copper_pour\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:mw,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),zR=DR.extend({shape:k_.literal(\"rect\"),center:qM,width:$M,height:$M,rotation:UM.optional()}),FR=DR.extend({shape:k_.literal(\"brep\"),brep_shape:eT}),BR=DR.extend({shape:k_.literal(\"polygon\"),points:k_.array(qM)}),jR=k_.discriminatedUnion(\"shape\",[zR,FR,BR]).describe(\"Defines a copper pour on the PCB.\"),$R=yN.extend({type:k_.literal(\"pcb_component_outside_board_error\"),pcb_component_outside_board_error_id:QM(\"pcb_component_outside_board_error\"),error_type:k_.literal(\"pcb_component_outside_board_error\").default(\"pcb_component_outside_board_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:qM,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a PCB component is placed outside the board boundaries\"),YR=yN.extend({type:k_.literal(\"pcb_component_not_on_board_edge_error\"),pcb_component_not_on_board_edge_error_id:QM(\"pcb_component_not_on_board_edge_error\"),error_type:k_.literal(\"pcb_component_not_on_board_edge_error\").default(\"pcb_component_not_on_board_edge_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:qM,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component that must be placed on the board edge is centered away from the edge\"),XR=yN.extend({type:k_.literal(\"pcb_component_invalid_layer_error\"),pcb_component_invalid_layer_error_id:QM(\"pcb_component_invalid_layer_error\"),error_type:k_.literal(\"pcb_component_invalid_layer_error\").default(\"pcb_component_invalid_layer_error\"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:mw,subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)\"),VR=yN.extend({type:k_.literal(\"pcb_via_clearance_error\"),pcb_error_id:QM(\"pcb_error\"),error_type:k_.literal(\"pcb_via_clearance_error\").default(\"pcb_via_clearance_error\"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when vias are closer than the allowed clearance\"),WR=yN.extend({type:k_.literal(\"pcb_via_trace_clearance_error\"),pcb_via_trace_clearance_error_id:QM(\"pcb_via_trace_clearance_error\"),error_type:k_.literal(\"pcb_via_trace_clearance_error\").default(\"pcb_via_trace_clearance_error\"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a via and trace are closer than the allowed clearance\"),HR=yN.extend({type:k_.literal(\"pcb_pad_pad_clearance_error\"),pcb_pad_pad_clearance_error_id:QM(\"pcb_pad_pad_clearance_error\"),error_type:k_.literal(\"pcb_pad_pad_clearance_error\").default(\"pcb_pad_pad_clearance_error\"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when pads are closer than the allowed clearance\"),GR=yN.extend({type:k_.literal(\"pcb_pad_trace_clearance_error\"),pcb_pad_trace_clearance_error_id:QM(\"pcb_pad_trace_clearance_error\"),error_type:k_.literal(\"pcb_pad_trace_clearance_error\").default(\"pcb_pad_trace_clearance_error\"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pad and trace are closer than allowed clearance\"),UR=k_.object({type:k_.literal(\"pcb_courtyard_rect\"),pcb_courtyard_rect_id:QM(\"pcb_courtyard_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw,ccw_rotation:UM.optional(),color:k_.string().optional()}).describe(\"Defines a courtyard rectangle on the PCB\"),ZR=k_.object({type:k_.literal(\"pcb_courtyard_outline\"),pcb_courtyard_outline_id:QM(\"pcb_courtyard_outline\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,outline:k_.array(qM).min(2)}).describe(\"Defines a courtyard outline on the PCB\"),qR=k_.object({type:k_.literal(\"pcb_courtyard_polygon\"),pcb_courtyard_polygon_id:QM(\"pcb_courtyard_polygon\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,points:k_.array(qM).min(3),color:k_.string().optional()}).describe(\"Defines a courtyard polygon on the PCB\"),JR=k_.object({type:k_.literal(\"pcb_courtyard_circle\"),pcb_courtyard_circle_id:QM(\"pcb_courtyard_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:$M,layer:gw,color:k_.string().optional()}).describe(\"Defines a courtyard circle on the PCB\"),KR=k_.object({type:k_.literal(\"cad_component\"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:JM,rotation:JM.optional(),size:JM.optional(),layer:mw.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:eN.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum([\"x+\",\"x-\",\"y+\",\"y-\",\"z+\",\"z-\"]).optional().describe('The direction in the model\\'s coordinate space that is considered \"up\" or \"coming out of the board surface\"'),model_origin_position:JM.optional(),model_origin_alignment:k_.enum([\"unknown\",\"center\",\"center_of_component_on_board_surface\",\"bottom_center_of_component\"]).optional(),model_object_fit:k_.enum([\"contain_within_bounds\",\"fill_bounds\"]).optional().default(\"contain_within_bounds\"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),anchor_alignment:k_.enum([\"center\",\"center_of_component_on_board_surface\"]).optional().default(\"center\")}).describe(\"Defines a component on the PCB\"),QR=k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]),tE=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),eE=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:QM(\"simulation_voltage_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:jM}).describe(\"Defines a DC voltage source for simulation\"),nE=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:QM(\"simulation_voltage_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:jM.optional(),frequency:YM.optional(),peak_to_peak_voltage:jM.optional(),wave_shape:QR.optional(),phase:UM.optional(),duty_cycle:tE.optional()}).describe(\"Defines an AC voltage source for simulation\"),oE=k_.union([eE,nE]).describe(\"Defines a voltage source for simulation\"),iE=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),rE=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:QM(\"simulation_current_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:VM}).describe(\"Defines a DC current source for simulation\"),sE=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:QM(\"simulation_current_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:VM.optional(),frequency:YM.optional(),peak_to_peak_current:VM.optional(),wave_shape:QR.optional(),phase:UM.optional(),duty_cycle:iE.optional()}).describe(\"Defines an AC current source for simulation\"),aE=k_.union([rE,sE]).describe(\"Defines a current source for simulation\"),cE=k_.union([k_.literal(\"spice_dc_sweep\"),k_.literal(\"spice_dc_operating_point\"),k_.literal(\"spice_transient_analysis\"),k_.literal(\"spice_ac_analysis\")]),lE=k_.object({type:k_.literal(\"simulation_experiment\"),simulation_experiment_id:QM(\"simulation_experiment\"),name:k_.string(),experiment_type:cE,time_per_step:WM.optional(),start_time_ms:HM.optional(),end_time_ms:HM.optional()}).describe(\"Defines a simulation experiment configuration\"),dE=k_.object({type:k_.literal(\"simulation_transient_voltage_graph\"),simulation_transient_voltage_graph_id:QM(\"simulation_transient_voltage_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:WM,start_time_ms:HM,end_time_ms:HM,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores voltage measurements over time for a simulation\"),hE=k_.object({type:k_.literal(\"simulation_switch\"),simulation_switch_id:QM(\"simulation_switch\"),source_component_id:k_.string().optional(),closes_at:HM.optional(),opens_at:HM.optional(),starts_closed:k_.boolean().optional(),switching_frequency:YM.optional()}).describe(\"Defines a switch for simulation timing control\"),uE=k_.object({type:k_.literal(\"simulation_voltage_probe\"),simulation_voltage_probe_id:QM(\"simulation_voltage_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.\").superRefine((t,e)=\u003e{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n\u0026\u0026o?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a differential probe.\"}):n?t.signal_input_source_port_id\u0026\u0026t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id.\"}):o\u0026\u0026(t.signal_input_source_net_id\u0026\u0026t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id.\"}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id.\"})}),pE=yN.extend({type:k_.literal(\"simulation_unknown_experiment_error\"),simulation_unknown_experiment_error_id:QM(\"simulation_unknown_experiment_error\"),error_type:k_.literal(\"simulation_unknown_experiment_error\").default(\"simulation_unknown_experiment_error\"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"An unknown error occurred during the simulation experiment.\"),mE=k_.object({type:k_.literal(\"simulation_op_amp\"),simulation_op_amp_id:QM(\"simulation_op_amp\"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe(\"Defines a simple ideal operational amplifier for simulation\"),gE=(k_.union([sw,iw,rw,ow,cw,aw,MN,xN,SN,CN,vN,NN,EN,AN,DN,FN,BN,VN,jN,$N,YN,XN,kN,ON,hw,fw,lw,WN,UN,ZN,JN,KN,yw,_w,bw,xw,vw,ew,dw,rT,uT,IR,CR,PR,wR,RR,ER,bT,fR,xT,VT,kT,FT,BT,WT,NT,OT,HT,GT,MR,qT,JT,KT,QT,iR,tR,eR,nR,oR,jT,$T,UT,ZT,YT,XT,VR,WR,HR,GR,sR,rR,aR,cR,lR,dR,hR,uR,pR,NR,mR,gR,AR,SR,OR,kR,LR,jR,$R,YR,XR,UR,ZR,qR,JR,Sw,zw,Ew,Aw,Ow,kw,ww,Rw,Fw,Lw,Iw,jw,$w,Bw,Hw,Gw,Uw,Zw,Kw,qw,Jw,KR,oE,aE,lE,dE,hE,uE,pE,mE]),!0),fE={CCW:-1,CW:1,NOT_ORIENTABLE:0},yE=2*Math.PI,_E=Object.freeze({__proto__:null,BOUNDARY:2,CCW:gE,CONTAINS:3,CW:!1,END_VERTEX:2,INSIDE:1,INTERLACE:4,NOT_VERTEX:0,ORIENTATION:fE,OUTSIDE:0,OVERLAP_OPPOSITE:2,OVERLAP_SAME:1,PIx2:yE,START_VERTEX:1}),bE=1e-6;function xE(t){bE=t}function vE(){return bE}function SE(t){return t\u003cbE\u0026\u0026t\u003e-bE}function IE(t,e){return t-e\u003cbE\u0026\u0026t-e\u003e-bE}function CE(t,e){return t-e\u003ebE}function PE(t,e){return t-e\u003c-bE}var ME={Utils:Object.freeze({__proto__:null,DECIMALS:3,EQ:IE,EQ_0:SE,GE:function(t,e){return t-e\u003e-bE},GT:CE,LE:function(t,e){return t-e\u003cbE},LT:PE,getTolerance:vE,setTolerance:xE}),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 _E)ME[t]=_E[t];Object.defineProperty(ME,\"DP_TOL\",{get:function(){return vE()},set:function(t){xE(t)}});var NE=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\")}};ME.Errors=NE;var wE=class{constructor(t,e){this.first=t,this.last=e||this.first}[Symbol.iterator](){let t;return{next:()=\u003e(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=[],o=t||this.first,i=e||this.last,r=o;if(void 0===r)return n;do{n.push(r),r=r.next}while(r!==i.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\u0026\u0026(n.prev=t),t.prev=e,t.next=n,this.last===e\u0026\u0026(this.last=t)}return this.last.next=void 0,this.first.prev=void 0,this}remove(t){return t===this.first\u0026\u0026t===this.last?(this.first=void 0,this.last=void 0):(t.prev\u0026\u0026(t.prev.next=t.next),t.next\u0026\u0026(t.next.prev=t.prev),t===this.first\u0026\u0026(this.first=t.next),t===this.last\u0026\u0026(this.last=t.prev)),this}isEmpty(){return void 0===this.first}static testInfiniteLoop(t){let e=t,n=t;do{if(e!=t\u0026\u0026e===n)throw NE.INFINITE_LOOP;e=e.next,n=n.next.next}while(e!=t)}},TE={stroke:\"black\"},RE=class{constructor(t=TE){for(const e in t)this[e]=t[e];this.stroke=t.stroke??TE.stroke}toAttributesString(){return Object.keys(this).reduce((t,e)=\u003et+(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 EE(t){return new RE(t).toAttributesString()}function AE(t,e){let n=[],[o,i,r]=t.standard,[s,a,c]=e.standard,l=o*a-i*s,d=r*a-i*c,h=o*c-r*s;if(!ME.Utils.EQ_0(l)){let t,e;0===i?(t=r/o,e=h/l):0===a?(t=c/s,e=h/l):0===o?(t=d/l,e=r/i):0===s?(t=d/l,e=c/a):(t=d/l,e=h/l),n.push(new ME.Point(t,e))}return n}function OE(t,e){let n=[],o=e.pc.projectionOn(t),i=e.pc.distanceTo(o)[0];if(ME.Utils.EQ(i,e.r))n.push(o);else if(ME.Utils.LT(i,e.r)){let r,s,a=Math.sqrt(e.r*e.r-i*i);r=t.norm.rotate90CCW().multiply(a),s=o.translate(r),n.push(s),r=t.norm.rotate90CW().multiply(a),s=o.translate(r),n.push(s)}return n}function kE(t,e){let n=[];for(let o of e.toSegments()){let e=DE(o,t);for(let t of e)eA(t,n)||n.push(t)}return n}function LE(t,e){let n=[];if(0===kE(t,e.box).length)return n;let o=OE(t,new ME.Circle(e.pc,e.r));for(let t of o)t.on(e)\u0026\u0026n.push(t);return n}function DE(t,e){let n=[];return t.ps.on(e)\u0026\u0026n.push(t.ps),t.pe.on(e)\u0026\u0026!t.isZeroLength()\u0026\u0026n.push(t.pe),n.length\u003e0||t.isZeroLength()||t.ps.leftTo(e)\u0026\u0026t.pe.leftTo(e)||!t.ps.leftTo(e)\u0026\u0026!t.pe.leftTo(e)?n:AE(new ME.Line(t.ps,t.pe),e)}function zE(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)\u0026\u0026n.push(t.ps),n;if(e.isZeroLength())return e.ps.on(t)\u0026\u0026n.push(e.ps),n;let o=new ME.Line(t.ps,t.pe),i=new ME.Line(e.ps,e.pe);if(o.incidentTo(i))t.ps.on(e)\u0026\u0026n.push(t.ps),t.pe.on(e)\u0026\u0026n.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 if(o.parallelTo(i)){const o=new ME.Vector(t.ps,t.pe),i=new ME.Vector(e.ps,e.pe),r=new ME.Vector(t.ps,e.ps),s=o.cross(i);if(!ME.Utils.EQ_0(s)){const a=r.cross(i)/s,c=r.cross(o)/s;ME.Utils.GE(a,0)\u0026\u0026ME.Utils.LE(a,1)\u0026\u0026ME.Utils.GE(c,0)\u0026\u0026ME.Utils.LE(c,1)\u0026\u0026n.push(FE(t.ps.translate(o.multiply(a)),t,e))}}else{let r=AE(o,i);r.length\u003e0\u0026\u0026BE(r[0],t)\u0026\u0026BE(r[0],e)\u0026\u0026n.push(FE(r[0],t,e))}return n}function FE(t,e,n){for(const o of[e.ps,e.pe,n.ps,n.pe])if(t.equalTo(o))return o;return t}function BE(t,e){const n=e.box;return ME.Utils.LE(t.x,n.xmax)\u0026\u0026ME.Utils.GE(t.x,n.xmin)\u0026\u0026ME.Utils.LE(t.y,n.ymax)\u0026\u0026ME.Utils.GE(t.y,n.ymin)}function jE(t,e){let n=[];if(t.isZeroLength()){let[o,i]=t.ps.distanceTo(e.pc);return ME.Utils.EQ(o,e.r)\u0026\u0026n.push(t.ps),n}let o=OE(new ME.Line(t.ps,t.pe),e);for(let e of o)e.on(t)\u0026\u0026n.push(e);return n}function $E(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)\u0026\u0026n.push(t.ps),n;let o=OE(new ME.Line(t.ps,t.pe),new ME.Circle(e.pc,e.r));for(let i of o)i.on(t)\u0026\u0026i.on(e)\u0026\u0026n.push(i);return n}function YE(t,e){let n=[],o=new ME.Vector(t.pc,e.pc),i=t.r,r=e.r;if(ME.Utils.EQ_0(i)||ME.Utils.EQ_0(r))return n;if(ME.Utils.EQ_0(o.x)\u0026\u0026ME.Utils.EQ_0(o.y)\u0026\u0026ME.Utils.EQ(i,r))return n.push(t.pc.translate(-i,0)),n;let s,a=t.pc.distanceTo(e.pc)[0];if(ME.Utils.GT(a,i+r))return n;if(ME.Utils.LT(a,Math.abs(i-r)))return n;if(o.x/=a,o.y/=a,ME.Utils.EQ(a,i+r)||ME.Utils.EQ(a,Math.abs(i-r)))return s=t.pc.translate(i*o.x,i*o.y),n.push(s),n;let c=i*i/(2*a)-r*r/(2*a)+a/2,l=t.pc.translate(c*o.x,c*o.y),d=Math.sqrt(i*i-c*c);return s=l.translate(o.rotate90CCW().multiply(d)),n.push(s),s=l.translate(o.rotate90CW().multiply(d)),n.push(s),n}function XE(t,e){let n=[];if(t.pc.equalTo(e.pc)\u0026\u0026ME.Utils.EQ(t.r,e.r)){let o;return o=t.start,o.on(e)\u0026\u0026n.push(o),o=t.end,o.on(e)\u0026\u0026n.push(o),o=e.start,o.on(t)\u0026\u0026n.push(o),o=e.end,o.on(t)\u0026\u0026n.push(o),n}let o=new ME.Circle(t.pc,t.r),i=new ME.Circle(e.pc,e.r),r=o.intersect(i);for(let o of r)o.on(t)\u0026\u0026o.on(e)\u0026\u0026n.push(o);return n}function VE(t,e){let n=[];if(e.pc.equalTo(t.pc)\u0026\u0026ME.Utils.EQ(e.r,t.r))return n.push(t.start),n.push(t.end),n;let o=YE(e,new ME.Circle(t.pc,t.r));for(let e of o)e.on(t)\u0026\u0026n.push(e);return n}function WE(t,e){return t.isSegment?zE(t.shape,e):$E(e,t.shape)}function HE(t,e){return t.isSegment?$E(t.shape,e):XE(t.shape,e)}function GE(t,e){return t.isSegment?DE(t.shape,e):LE(e,t.shape)}function UE(t,e){return t.isSegment?jE(t.shape,e):VE(t.shape,e)}function ZE(t,e){let n=[];for(let o of e.edges)for(let e of WE(o,t))n.push(e);return n}function qE(t,e){let n=[];for(let o of e.edges)for(let e of HE(o,t))n.push(e);return n}function JE(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of GE(o,t))eA(e,n)||n.push(e);return t.sortPoints(n)}function KE(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of UE(o,t))n.push(e);return n}function QE(t,e){return t.isSegment?WE(e,t.shape):t.isArc?HE(e,t.shape):t.isLine?GE(e,t.shape):t.isRay?(n=e,o=t.shape,n.isSegment?oA(o,n.shape):iA(o,n.shape)):[];var n,o}function tA(t,e){let n=[];if(e.isEmpty()||t.shape.box.not_intersect(e.box))return n;let o=e.edges.search(t.shape.box);for(let e of o)n=[...n,...QE(t,e)];return n}function eA(t,e){return e.some(e=\u003ee.equalTo(t))}function nA(t){return new ME.Line(t.start,t.norm)}function oA(t,e){return DE(e,nA(t)).filter(e=\u003et.contains(e))}function iA(t,e){return LE(nA(t),e).filter(e=\u003et.contains(e))}function rA(t,e){return OE(nA(t),e).filter(e=\u003et.contains(e))}function sA(t,e){return AE(nA(t),e).filter(e=\u003et.contains(e))}function aA(t,e){return JE(nA(t),e).filter(e=\u003et.contains(e))}function cA(t,e){if(t.intersect\u0026\u0026t.intersect instanceof Function)return t.intersect(e);throw NE.UNSUPPORTED_SHAPE_TYPE}function lA(t,e){let n=[];for(let o of e)n=[...n,...cA(t,o.shape)];return n}var dA=class t extends wE{constructor(...t){if(super(),this.isInfinite=!1,1===t.length\u0026\u0026t[0]instanceof Array\u0026\u0026t[0].length\u003e0){const e=t[0],n=e.length,o=t=\u003et instanceof ME.Segment||t instanceof ME.Arc||t instanceof ME.Ray,i=t=\u003et instanceof ME.Segment||t instanceof ME.Arc;if(!(1===n\u0026\u0026(t=\u003et instanceof ME.Segment||t instanceof ME.Arc||t instanceof ME.Ray||t instanceof ME.Line)(e[0])||n\u003e1\u0026\u0026o(e[0])\u0026\u0026o(e[n-1])\u0026\u0026e.slice(1,n-1).every(i)))throw ME.Errors.ILLEGAL_PARAMETERS;this.isInfinite=e.some(t=\u003et instanceof ME.Ray||t instanceof ME.Line);for(let t of e){let e=new ME.Edge(t);this.append(e)}this.setArcLength()}}get edges(){return[...this]}get box(){return this.edges.reduce((t,e)=\u003et.merge(e.box),new ME.Box)}get vertices(){let t=this.edges.map(t=\u003et.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\u003ethis.length||t\u003c0)return null;if(this.isInfinite)return null;let e=null;for(let n of this)if(t\u003e=n.arc_length\u0026\u0026(n===this.last||t\u003cn.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 o=new ME.Edge(n[0]),i=e.prev;return this.insert(o,i),e.shape=n[1],o}getChain(t,e){let n=[];for(let o=t;o!==e.next;o=o.next)n.push(o);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 ME.Point){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Line){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Circle){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Segment){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Arc){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Box){const[e,n]=ME.Distance.shape2multiline(new ME.Polygon(t),this);return[e,n.reverse()]}if(t instanceof ME.Multiline)return ME.Distance.multiline2multiline(this,t);throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}intersect(t){return t instanceof ME.Multiline?function(t,e){let n=[];for(let o of t)for(let t of e)n=[...n,...cA(o.shape,t.shape)];return n}(this,t):lA(t,this)}contains(t){if(t instanceof ME.Point)return this.edges.some(e=\u003ee.shape.contains(t));throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}translate(e){return new t(this.edges.map(t=\u003et.shape.translate(e)))}rotate(e=0,n=new ME.Point){return new t(this.edges.map(t=\u003et.shape.rotate(e,n)))}transform(e=new ME.Matrix){return new t(this.edges.map(t=\u003et.shape.transform(e)))}toShapes(){return this.edges.map(t=\u003et.shape.clone())}toJSON(){return this.edges.map(t=\u003et.toJSON())}svgPoints(){return this.vertices.map(t=\u003e`${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\u003cpath ${EE({fill:\"none\",...t})} d=\"`;e+=`\\nM${this.first.start.x},${this.first.start.y}`;for(let t of this)e+=t.svg();return e+='\" \u003e\\n\u003c/path\u003e',e}};ME.Multiline=dA;function hA(t,e,n){let o=n.length,i=t.shape.split(e);if(0===i.length)return;let r=0;r=null===i[0]?0:null===i[1]?t.shape.length:i[0].length;let s,a=0;IE(r,0)\u0026\u0026(a|=1),IE(r,t.shape.length)\u0026\u0026(a|=2),s=r===1/0?i[0].coord(e):2\u0026a\u0026\u0026t.next\u0026\u00260===t.next.arc_length?0:t.arc_length+r,n.push({id:o,pt:e,arc_length:s,edge_before:t,edge_after:void 0,face:t.face,is_vertex:a})}function uA(t){t.int_points1_sorted=pA(t.int_points1),t.int_points2_sorted=pA(t.int_points2)}function pA(t){let e=new Map,n=0;for(let o of t)e.has(o.face)||(e.set(o.face,n),n++);for(let n of t)n.faceId=e.get(n.face);return t.slice().sort(mA)}function mA(t,e){return t.faceId\u003ce.faceId?-1:t.faceId\u003ee.faceId?1:t.arc_length\u003ce.arc_length?-1:t.arc_length\u003ee.arc_length?1:0}function gA(t){if(t.int_points1.length\u003c2)return;let e,n,o,i,r=!1;for(let s=0;s\u003ct.int_points1_sorted.length;s++)if(-1!==t.int_points1_sorted[s].id){e=t.int_points1_sorted[s],n=t.int_points2[e.id];for(let a=s+1;a\u003ct.int_points1_sorted.length\u0026\u0026(o=t.int_points1_sorted[a],IE(o.arc_length,e.arc_length));a++)-1!==o.id\u0026\u0026(i=t.int_points2[o.id],-1!==i.id\u0026\u0026o.edge_before===e.edge_before\u0026\u0026o.edge_after===e.edge_after\u0026\u0026i.edge_before===n.edge_before\u0026\u0026i.edge_after===n.edge_after\u0026\u0026(o.id=-1,i.id=-1,r=!0))}n=t.int_points2_sorted[0],e=t.int_points1[n.id];for(let o=1;o\u003ct.int_points2_sorted.length;o++){let i=t.int_points2_sorted[o];if(-1===i.id)continue;if(-1===n.id||!IE(i.arc_length,n.arc_length)){n=i,e=t.int_points1[n.id];continue}let s=t.int_points1[i.id];s.edge_before===e.edge_before\u0026\u0026s.edge_after===e.edge_after\u0026\u0026i.edge_before===n.edge_before\u0026\u0026i.edge_after===n.edge_after\u0026\u0026(s.id=-1,i.id=-1,r=!0)}r\u0026\u0026(t.int_points1=t.int_points1.filter(t=\u003et.id\u003e=0),t.int_points2=t.int_points2.filter(t=\u003et.id\u003e=0),t.int_points1.forEach((t,e)=\u003et.id=e),t.int_points2.forEach((t,e)=\u003et.id=e))}function fA(t){for(let e of t)e.edge_before\u0026\u0026(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\u0026\u0026(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\u0026\u0026(e.edge_before.bvEnd=2),e.edge_after\u0026\u0026(e.edge_after.bvStart=2)}function yA(t,e){for(let n of t)n.edge_before\u0026\u0026n.edge_before.setInclusion(e),n.edge_after\u0026\u0026n.edge_after.setInclusion(e)}function _A(t,e,n){let o,i,r=1;if(1===t.length)return 1;o=t[e];for(let s=e+1;s\u003ct.length\u0026\u0026o.face===n\u0026\u0026(i=t[s],i.pt.equalTo(o.pt)\u0026\u0026i.edge_before===o.edge_before\u0026\u0026i.edge_after===o.edge_after);s++)r++;return r}function bA(t,e){if(e){for(let n of e){let e=n.edge_before;if(n.is_vertex=0,e.shape.start\u0026\u0026e.shape.start.equalTo(n.pt)\u0026\u0026(n.is_vertex|=1),e.shape.end\u0026\u0026e.shape.end.equalTo(n.pt)\u0026\u0026(n.is_vertex|=2),1\u0026n.is_vertex){n.edge_before=e.prev,e.prev\u0026\u0026(n.is_vertex=2);continue}if(2\u0026n.is_vertex)continue;let o=t.addVertex(n.pt,e);n.edge_before=o}for(let n of e)n.edge_before?n.edge_after=n.edge_before.next:t instanceof dA\u0026\u00261\u0026n.is_vertex\u0026\u0026(n.edge_after=t.first)}}function xA(t,e,n){const o=t.edge_before,i=e.edge_after,r=n.length;o.next=n[0],n[0].prev=o,n[r-1].next=i,i.prev=n[r-1]}ME.multiline=(...t)=\u003enew ME.Multiline(...t);var{INSIDE:vA,OUTSIDE:SA,BOUNDARY:IA,OVERLAP_SAME:CA,OVERLAP_OPPOSITE:PA}=_E,{NOT_VERTEX:MA,START_VERTEX:NA,END_VERTEX:wA}=_E;function TA(t,e){let n=e.clone().reverse(),[o,i]=LA(t,n,3,!0);return o}function RA(t,e){let[n,o]=LA(t,e,2,!0);return n}function EA(t,e){let[n,o]=LA(t,e,2,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=\u003et.shape)];let r=[];for(let t of o.faces)r=[...r,...[...t.edges].map(t=\u003et.shape)];return[i,r]}function AA(t,e){let[n,o]=LA(t,e,3,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=\u003et.shape)];return i}function OA(t,e){let n=t.clone(),o=e.clone(),i=DA(n,o);return uA(i),bA(n,i.int_points1_sorted),bA(o,i.int_points2_sorted),gA(i),uA(i),[i.int_points1_sorted.map(t=\u003et.pt),i.int_points2_sorted.map(t=\u003et.pt)]}function kA(t,e,n,o){let i=zA(t,n.int_points1),r=zA(e,n.int_points2);for(FA(i,e),FA(r,t),fA(n.int_points1),fA(n.int_points2),yA(n.int_points1,e),yA(n.int_points2,t);BA(t,e,n.int_points1,n.int_points1_sorted,n.int_points2,n););!function(t){let e,n,o,i=t.int_points1.length;for(let r=0;r\u003ci;r++){let s=t.int_points1_sorted[r];s.face!==e\u0026\u0026(n=r,e=s.face);let a,c=r,l=_A(t.int_points1_sorted,r,e);a=c+l\u003ci\u0026\u0026t.int_points1_sorted[c+l].face===e?c+l:n;let d=_A(t.int_points1_sorted,a,e);o=null;for(let n=a;n\u003ca+d;n++){let i=t.int_points1_sorted[n];if(i.face===e\u0026\u0026t.int_points2[i.id].face===t.int_points2[s.id].face){o=i;break}}if(null===o)continue;let h=s.edge_after,u=o.edge_before;if(2!==h.bv||2!==u.bv)continue;if(h!==u)continue;let p=t.int_points2[s.id],m=t.int_points2[o.id],g=p.edge_after,f=m.edge_before;2===g.bv\u0026\u00262===f.bv\u0026\u0026g===f||(p=t.int_points2[o.id],m=t.int_points2[s.id],g=p.edge_after,f=m.edge_before),2===g.bv\u0026\u00262===f.bv\u0026\u0026g===f\u0026\u0026h.setOverlap(g)}}(n),jA(t,o,n.int_points1_sorted,!0),jA(e,o,n.int_points2_sorted,!1),XA(t,i,o,!0),XA(e,r,o,!1)}function LA(t,e,n,o){let i=t.clone(),r=e.clone(),s=DA(i,r);return uA(s),bA(i,s.int_points1_sorted),bA(r,s.int_points2_sorted),gA(s),uA(s),kA(i,r,s,n),o\u0026\u0026function(t,e,n){!function(t,e,n,o){for(let n of e.faces){for(let e of n)t.edges.add(e);void 0===o.find(t=\u003et.face===n)\u0026\u0026t.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\u003cn.int_points1.length;t++){let e=n.int_points1[t],o=n.int_points2[t];if(void 0!==e.edge_before\u0026\u0026void 0===e.edge_after\u0026\u0026void 0===o.edge_before\u0026\u0026void 0!==o.edge_after\u0026\u0026(e.edge_before.next=o.edge_after,o.edge_after.prev=e.edge_before,e.edge_after=o.edge_after,o.edge_before=e.edge_before),void 0!==o.edge_before\u0026\u0026void 0===o.edge_after\u0026\u0026void 0===e.edge_before\u0026\u0026void 0!==e.edge_after\u0026\u0026(o.edge_before.next=e.edge_after,e.edge_after.prev=o.edge_before,o.edge_after=e.edge_after,e.edge_before=o.edge_before),void 0!==e.edge_before\u0026\u0026void 0===e.edge_after)for(let t of n.int_points1_sorted)t!==e\u0026\u0026void 0===t.edge_before\u0026\u0026void 0!==t.edge_after\u0026\u0026t.pt.equalTo(e.pt)\u0026\u0026(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!==o.edge_before\u0026\u0026void 0===o.edge_after)for(let t of n.int_points2_sorted)t!==o\u0026\u0026void 0===t.edge_before\u0026\u0026void 0!==t.edge_after\u0026\u0026t.pt.equalTo(o.pt)\u0026\u0026(o.edge_before.next=t.edge_after,t.edge_after.prev=o.edge_before,o.edge_after=t.edge_after,t.edge_before=o.edge_before)}}(0,0,n),$A(t,n.int_points1),$A(e,n.int_points2),YA(t,n.int_points1,n.int_points2),YA(t,n.int_points2,n.int_points1),VA(t),VA(e)}(i,r,s),[i,r]}function DA(t,e){let n={int_points1:[],int_points2:[]};for(let o of t.edges){let t=e.edges.search(o.box);for(let e of t){let t=o.shape.intersect(e.shape);for(let i of t)hA(o,i,n.int_points1),hA(e,i,n.int_points2)}}return n}function zA(t,e){let n=[];for(let o of t.faces)e.find(t=\u003et.face===o)||n.push(o);return n}function FA(t,e){for(let n of t)n.first.bv=n.first.bvStart=n.first.bvEnd=void 0,n.first.setInclusion(e)}function BA(t,e,n,o,i,r){let s,a,c,l=o.length,d=!1;for(let h=0;h\u003cl;h++){let u=o[h];u.face!==s\u0026\u0026(a=h,s=u.face);let p,m=h,g=_A(o,h,s);p=m+g\u003cl\u0026\u0026o[m+g].face===s?m+g:a;let f=_A(o,p,s);c=null;for(let t=p;t\u003cp+f;t++){let e=o[t];if(e.face===s\u0026\u0026i[e.id].face===i[u.id].face){c=e;break}}if(null===c)continue;let y=u.edge_after,_=c.edge_before;if(y.bv!==IA||_.bv==IA)if(y.bv==IA||_.bv!==IA){if(y.bv===IA\u0026\u0026_.bv===IA\u0026\u0026y!=_||y.bv===vA\u0026\u0026_.bv===SA||y.bv===SA\u0026\u0026_.bv===vA){let t=y.next;for(;t!=_;)t.bvStart=void 0,t.bvEnd=void 0,t.bv=void 0,t.setInclusion(e),t=t.next}if(y.bv===IA\u0026\u0026_.bv===IA\u0026\u0026y!=_){let t,e=y.next;for(;e!=_;){if(e.bv!=IA)if(void 0===t)t=e.bv;else if(e.bv!=t)throw NE.UNRESOLVED_BOUNDARY_CONFLICT;e=e.next}null!=t\u0026\u0026(y.bv=t,_.bv=t);continue}if(y.bv===vA\u0026\u0026_.bv===SA||y.bv===SA\u0026\u0026_.bv===vA){let o=y;for(;o!=_;){if(o.bvStart===y.bv\u0026\u0026o.bvEnd===_.bv){let[s,a]=o.shape.distanceTo(e);if(s\u003c10*ME.DP_TOL){hA(o,a.ps,n);let s=n[n.length-1];if(s.is_vertex\u0026NA)s.edge_after=o,s.edge_before=o.prev,o.bvStart=IA,o.bv=void 0,o.setInclusion(e);else if(s.is_vertex\u0026wA)s.edge_after=o.next,o.bvEnd=IA,o.bv=void 0,o.setInclusion(e);else{let t=e.addVertex(s.pt,o);s.edge_before=t,s.edge_after=t.next,t.setInclusion(e),t.next.bvStart=IA,t.next.bvEnd=void 0,t.next.bv=void 0,t.next.setInclusion(e)}let c=e.findEdgeByPoint(a.pe);hA(c,a.pe,i);let l=i[i.length-1];if(l.is_vertex\u0026NA)l.edge_after=c,l.edge_before=c.prev;else if(l.is_vertex\u0026wA)l.edge_after=c.next;else{let n=i.find(t=\u003et.edge_after===c),o=e.addVertex(l.pt,c);l.edge_before=o,l.edge_after=o.next,n\u0026\u0026(n.edge_after=o),o.bvStart=void 0,o.bvEnd=IA,o.bv=void 0,o.setInclusion(t),o.next.bvStart=IA,o.next.bvEnd=void 0,o.next.bv=void 0,o.next.setInclusion(t)}uA(r),d=!0;break}}o=o.next}if(d)break;throw NE.UNRESOLVED_BOUNDARY_CONFLICT}}else _.bv=y.bv;else y.bv=_.bv}return d}function jA(t,e,n,o){if(!n)return;let i,r,s,a;for(let c=0;c\u003cn.length;c++){if(s=n[c],s.face!==i\u0026\u0026(r=c,i=s.face),i.isEmpty())continue;let l,d=c,h=_A(n,c,i);l=d+h\u003cn.length\u0026\u0026n[d+h].face===s.face?d+h:r,a=n[l];let u=l,p=_A(n,u,i),m=s.edge_after,g=a.edge_before;if(m.bv===vA\u0026\u0026g.bv===vA\u0026\u00261===e||m.bv===SA\u0026\u0026g.bv===SA\u0026\u00262===e||(m.bv===SA||g.bv===SA)\u0026\u00263===e\u0026\u0026!o||(m.bv===vA||g.bv===vA)\u0026\u00263===e\u0026\u0026o||m.bv===IA\u0026\u0026g.bv===IA\u0026\u0026m.overlap\u0026CA\u0026\u0026o||m.bv===IA\u0026\u0026g.bv===IA\u0026\u0026m.overlap\u0026PA){t.removeChain(i,m,g);for(let t=d;t\u003cd+h;t++)n[t].edge_after=void 0;for(let t=u;t\u003cu+p;t++)n[t].edge_before=void 0}c+=h-1}}function $A(t,e){for(let n of e)t.faces.delete(n.face),n.face=void 0,n.edge_before\u0026\u0026(n.edge_before.face=void 0),n.edge_after\u0026\u0026(n.edge_after.face=void 0)}function YA(t,e,n){for(let o of e){if(void 0===o.edge_before||void 0===o.edge_after)continue;if(o.face)continue;if(o.edge_after.face||o.edge_before.face)continue;let i=o.edge_after,r=o.edge_before;try{wE.testInfiniteLoop(i)}catch(t){throw NE.CANNOT_COMPLETE_BOOLEAN_OPERATION}let s=t.addFace(i,r);for(let t of e)t.edge_before\u0026\u0026t.edge_after\u0026\u0026t.edge_before.face===s\u0026\u0026t.edge_after.face===s\u0026\u0026(t.face=s);for(let t of n)t.edge_before\u0026\u0026t.edge_after\u0026\u0026t.edge_before.face===s\u0026\u0026t.edge_after.face===s\u0026\u0026(t.face=s)}}function XA(t,e,n,o){for(let i of e){let e=i.first.bv;(1===n\u0026\u0026e===vA||3===n\u0026\u0026e===vA\u0026\u0026o||3===n\u0026\u0026e===SA\u0026\u0026!o||2===n\u0026\u0026e===SA)\u0026\u0026t.deleteFace(i)}}function VA(t){const e=[];for(const n of t.edges)n.face\u0026\u0026t.faces.has(n.face)||e.push(n);for(const n of e)t.edges.delete(n)}var WA=Object.freeze({__proto__:null,BOOLEAN_INTERSECT:2,BOOLEAN_SUBTRACT:3,BOOLEAN_UNION:1,calculateIntersections:OA,innerClip:EA,intersect:RA,outerClip:AA,removeNotRelevantChains:jA,removeOldFaces:$A,restoreFaces:YA,subtract:TA,unify:function(t,e){let[n,o]=LA(t,e,1,!0);return n}}),HA=RegExp(\"T.F..FFF.|T.F...F..\"),GA=RegExp(\"T........|.T.......|...T.....|....T....\"),UA=RegExp(\"FT.......|F..T.....|F...T....\"),ZA=RegExp(\"T.F..F...\"),qA=RegExp(\"T.F..F...|.TF..F...|..FT.F...|..F.TF...\"),JA=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=\u003et instanceof Array\u0026\u0026t.length\u003e0?\"T\":t instanceof Array\u0026\u00260===t.length?\"F\":\"*\").join(\"\")}equal(){return HA.test(this.toString())}intersect(){return GA.test(this.toString())}touch(){return UA.test(this.toString())}inside(){return ZA.test(this.toString())}covered(){return qA.test(this.toString())}};function KA(t,e){let n,o=new ME.Ray(e),i=new ME.Line(o.pt,o.norm);const r=new ME.Box(o.box.xmin-ME.DP_TOL,o.box.ymin-ME.DP_TOL,o.box.xmax+ME.DP_TOL,o.box.ymax+ME.DP_TOL);if(t.box.not_intersect(r))return ME.OUTSIDE;let s=t.edges.search(r);if(0===s.length)return ME.OUTSIDE;for(let t of s)if(t.shape.contains(e))return ME.BOUNDARY;let a=[...t.faces],c=[];for(let t of s)for(let n of o.intersect(t.shape)){if(n.equalTo(e))return ME.BOUNDARY;c.push({pt:n,edge:t,face_index:a.indexOf(t.face)})}c.sort((t,e)=\u003ePE(t.pt.x,e.pt.x)?-1:CE(t.pt.x,e.pt.x)?1:t.face_index\u003ce.face_index?-1:t.face_index\u003ee.face_index?1:t.edge.arc_length\u003ce.edge.arc_length?-1:t.edge.arc_length\u003ee.edge.arc_length?1:0);let l=0;for(let t=0;t\u003cc.length;t++){let e=c[t];if(e.pt.equalTo(e.edge.shape.start)){if(t\u003e0\u0026\u0026e.pt.equalTo(c[t-1].pt)\u0026\u0026e.face_index===c[t-1].face_index\u0026\u0026e.edge.prev===c[t-1].edge)continue;let n=e.edge.prev;for(;SE(n.length);)n=n.prev;let o=n.shape.tangentInEnd(),r=e.pt.translate(o),s=e.edge.shape.tangentInStart(),a=e.pt.translate(s),d=r.leftTo(i),h=a.leftTo(i);(d\u0026\u0026!h||!d\u0026\u0026h)\u0026\u0026l++}else if(e.pt.equalTo(e.edge.shape.end)){if(t\u003e0\u0026\u0026e.pt.equalTo(c[t-1].pt)\u0026\u0026e.face_index===c[t-1].face_index\u0026\u0026e.edge.next===c[t-1].edge)continue;let n=e.edge.next;for(;SE(n.length);)n=n.next;let o=n.shape.tangentInStart(),r=e.pt.translate(o),s=e.edge.shape.tangentInEnd(),a=e.pt.translate(s),d=r.leftTo(i),h=a.leftTo(i);(d\u0026\u0026!h||!d\u0026\u0026h)\u0026\u0026l++}else if(e.edge.shape instanceof ME.Segment)l++;else{let t=e.edge.shape.box;IE(e.pt.y,t.ymin)||IE(e.pt.y,t.ymax)||l++}}return n=l%2==1?1:0,n}function QA(t,e){return oO(t,e).intersect()}function tO(t,e){return oO(t,e).inside()}function eO(t,e){return oO(t,e).covered()}function nO(t,e){return eO(e,t)}function oO(t,e){return t instanceof ME.Line\u0026\u0026e instanceof ME.Line?function(t,e){let n=new JA,o=AE(t,e);0===o.length?t.contains(e.pt)\u0026\u0026e.contains(t.pt)?(n.I2I=[t],n.I2E=[],n.E2I=[]):(n.I2I=[],n.I2E=[t],n.E2I=[e]):(n.I2I=o,n.I2E=t.split(o),n.E2I=e.split(o));return n}(t,e):t instanceof ME.Line\u0026\u0026e instanceof ME.Circle?function(t,e){let n=new JA,o=OE(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new dA([t]),r=t.sortPoints(o);i.split(r);let s=i.toShapes();n.I2I=[s[1]],n.I2B=r,n.I2E=[s[0],s[2]],n.E2I=new ME.Polygon([e.toArc()]).cutWithLine(t)}return n}(t,e):t instanceof ME.Line\u0026\u0026e instanceof ME.Box?function(t,e){let n=new JA,o=kE(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new dA([t]),r=t.sortPoints(o);i.split(r);let s=i.toShapes();e.toSegments().some(t=\u003et.contains(o[0])\u0026\u0026t.contains(o[1]))?(n.I2I=[],n.I2B=[s[1]],n.I2E=[s[0],s[2]],n.E2I=[e]):(n.I2I=[s[1]],n.I2B=r,n.I2E=[s[0],s[2]],n.E2I=new ME.Polygon(e.toSegments()).cutWithLine(t))}return n}(t,e):t instanceof ME.Line\u0026\u0026e instanceof ME.Polygon?function(t,e){let n=new JA,o=JE(t,e),i=new dA([t]),r=o.length\u003e0?o.slice():t.sortPoints(o);return i.split(r),[...i].forEach(t=\u003et.setInclusion(e)),n.I2I=[...i].filter(t=\u003et.bv===ME.INSIDE).map(t=\u003et.shape),n.I2B=[...i].slice(1).map(t=\u003et.bv===ME.BOUNDARY?t.shape:t.shape.start),n.I2E=[...i].filter(t=\u003et.bv===ME.OUTSIDE).map(t=\u003et.shape),n.E2I=e.cutWithLine(t),n}(t,e):(t instanceof ME.Segment||t instanceof ME.Arc)\u0026\u0026e instanceof ME.Polygon?iO(t,e):(t instanceof ME.Segment||t instanceof ME.Arc)\u0026\u0026(e instanceof ME.Circle||e instanceof ME.Box)?iO(t,new ME.Polygon(e)):t instanceof ME.Polygon\u0026\u0026e instanceof ME.Polygon?rO(t,e):(t instanceof ME.Circle||t instanceof ME.Box)\u0026\u0026(e instanceof ME.Circle||e instanceof ME.Box)?rO(new ME.Polygon(t),new ME.Polygon(e)):(t instanceof ME.Circle||t instanceof ME.Box)\u0026\u0026e instanceof ME.Polygon?rO(new ME.Polygon(t),e):t instanceof ME.Polygon\u0026\u0026(e instanceof ME.Circle||e instanceof ME.Box)?rO(t,new ME.Polygon(e)):void 0}function iO(t,e){let n=new JA,o=function(t,e){return t instanceof ME.Line?JE(t,e):t instanceof ME.Segment?ZE(t,e):t instanceof ME.Arc?qE(t,e):[]}(t,e),i=o.length\u003e0?o.slice():t.sortPoints(o),r=new dA([t]);r.split(i),[...r].forEach(t=\u003et.setInclusion(e)),n.I2I=[...r].filter(t=\u003et.bv===ME.INSIDE).map(t=\u003et.shape),n.I2B=[...r].slice(1).map(t=\u003et.bv===ME.BOUNDARY?t.shape:t.shape.start),n.I2E=[...r].filter(t=\u003et.bv===ME.OUTSIDE).map(t=\u003et.shape),n.B2I=[],n.B2B=[],n.B2E=[];for(let o of[t.start,t.end])switch(KA(e,o)){case ME.INSIDE:n.B2I.push(o);break;case ME.BOUNDARY:n.B2B.push(o);break;case ME.OUTSIDE:n.B2E.push(o)}return n}function rO(t,e){let n=new JA,[o,i]=OA(t,e),r=RA(t,e),s=TA(t,e),a=TA(e,t),[c,l]=EA(t,e),d=AA(t,e),h=AA(e,t);return n.I2I=r.isEmpty()?[]:[r],n.I2B=l,n.I2E=s.isEmpty()?[]:[s],n.B2I=c,n.B2B=o,n.B2E=d,n.E2I=a.isEmpty()?[]:[a],n.E2B=h,n}var sO=Object.freeze({__proto__:null,contain:function(t,e){return tO(e,t)},cover:nO,covered:eO,disjoint:function(t,e){return!QA(t,e)},equal:function(t,e){return oO(t,e).equal()},inside:tO,intersect:QA,relate:oO,touch:function(t,e){return oO(t,e).touch()}}),aO=class t{constructor(t=1,e=0,n=0,o=1,i=0,r=0){this.a=t,this.b=e,this.c=n,this.d=o,this.tx=i,this.ty=r}fromMatrix3x3(e){const[n,o,i]=e[0],[r,s,a]=e[1];return new t(n,r,o,s,i,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,o;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 NE.ILLEGAL_PARAMETERS;n=e[0],o=e[1]}else n=e[0].x,o=e[0].y;return this.multiply(new t(1,0,0,1,n,o))}rotate(e,n=0,o=0){let i=Math.cos(e),r=Math.sin(e);return this.translate(n,o).multiply(new t(i,r,-r,i,0,0)).translate(-n,-o)}scale(e,n){return this.multiply(new t(e,0,0,n,0,0))}equalTo(t){return!!ME.Utils.EQ(this.tx,t.tx)\u0026\u0026(!!ME.Utils.EQ(this.ty,t.ty)\u0026\u0026(!!ME.Utils.EQ(this.a,t.a)\u0026\u0026(!!ME.Utils.EQ(this.b,t.b)\u0026\u0026(!!ME.Utils.EQ(this.c,t.c)\u0026\u0026!!ME.Utils.EQ(this.d,t.d)))))}};ME.Matrix=aO;ME.matrix=(...t)=\u003enew ME.Matrix(...t);var cO=class{constructor(t,e){this.low=t,this.high=e}get max(){return this.clone()}less_than(t){return this.low\u003ct.low||this.low===t.low\u0026\u0026this.high\u003ct.high}equal_to(t){return this.low===t.low\u0026\u0026this.high===t.high}intersect(t){return!this.not_intersect(t)}not_intersect(t){return this.high\u003ct.low||t.high\u003cthis.low}merge(t){const e=void 0===this.low?t.low:this.low\u003ct.low?this.low:t.low,n=void 0===this.high?t.high:this.high\u003et.high?this.high:t.high,o=this.clone();return o.low=e,o.high=n,o}output(){return[this.low,this.high]}comparable_less_than(t,e){return t\u003ce}},lO=class t extends cO{clone(){return new t(this.low,this.high)}},dO=class{constructor(t,e,n=null,o=null,i=null,r=0){if(this.left=n,this.right=o,this.parent=i,this.color=r,this.item={key:void 0,values:[]},void 0!==e\u0026\u0026this.item.values.push(e),void 0!==t)if(Array.isArray(t)){const[e,n]=t;if(!Number.isNaN(e)\u0026\u0026!Number.isNaN(n)){let t=e,o=n;t\u003eo\u0026\u0026([t,o]=[o,t]),this.item.key=new lO(t,o)}}else this.item.key=t;this.max=this.item.key?this.item.key.max:void 0}isNil(){return void 0===this.item.key\u0026\u00260===this.item.values.length\u0026\u0026null===this.left\u0026\u0026null===this.right\u0026\u00260===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\u0026\u0026n\u0026\u0026e.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\u0026\u0026this.right.max\u0026\u0026(this.max=this.max?this.max.merge(this.right.max):this.right.max),this.left\u0026\u0026this.left.max\u0026\u0026(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(),o=t.requireKey();return n.comparable_less_than(e,o.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(),o=t.requireKey();return n.comparable_less_than(o.high,e)}},hO=class t{constructor(){this.root=null,this.nil_node=new dO}get size(){let t=0;return this.tree_walk(this.root,e=\u003et+=e.item.values.length),t}get keys(){const t=[];return this.tree_walk(this.root,e=\u003et.push(e.item.key.output())),t}get values(){const t=[];return this.tree_walk(this.root,e=\u003e{for(const n of e.item.values)t.push(n)}),t}get items(){const t=[];return this.tree_walk(this.root,e=\u003e{const n=e.item.key.output();for(const o of e.item.values)t.push({key:n,value:o})}),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 dO(t));if(n)return n.item.values.push(e),n;const o=new dO(t,e,this.nil_node,this.nil_node,null,1);return this.tree_insert(o),this.recalc_max(o),o}exist(t,e=t){const n=this.tree_search(this.root,new dO(t));return!!n\u0026\u0026(arguments.length\u003c2||e===t||n.item.values.some(t=\u003et\u0026\u0026t.equal_to?t.equal_to(e):t===e))}remove(t,e=t){const n=this.tree_search(this.root,new dO(t));if(!n)return;if(arguments.length\u003c2)return this.tree_delete(n),n;const o=n.item.values.findIndex(t=\u003et\u0026\u0026t.equal_to?t.equal_to(e):t===e);return o\u003e=0?(n.item.values.splice(o,1),0===n.item.values.length\u0026\u0026this.tree_delete(n),n):void 0}search(t,e=(t,e)=\u003et===e?e.output():t){const n=new dO(t),o=[];this.tree_search_interval(this.root,n,o);const i=[];for(const t of o)for(const n of t.item.values)i.push(e(n,t.item.key));return i}intersect_any(t){const e=new dO(t);return this.tree_find_any_interval(this.root,e)}forEach(t){this.tree_walk(this.root,e=\u003e{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=\u003e{for(const o of t.item.values)n.insert(t.item.key,e(o,t.item.key))}),n}*iterate(t,e=(t,e)=\u003et===e?e.output():t){let n=null;for(t?n=this.tree_search_nearest_forward(this.root,new dO(t)):this.root\u0026\u0026(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\u0026\u00261===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\u0026\u0026(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\u0026\u0026(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\u0026\u0026(t.copy_data(e),t.update_max(),this.recalc_max(t)),0===e.color\u0026\u0026this.delete_fixup(n)}delete_fixup(t){let e,n=t;for(;n!==this.root\u0026\u0026null!=n.parent\u0026\u00260===n.color;)n===n.parent.left?(e=n.parent.right,1===e.color\u0026\u0026(e.color=0,n.parent.color=1,this.rotate_left(n.parent),e=n.parent.right),0===e.left.color\u0026\u00260===e.right.color?(e.color=1,n=n.parent):(0===e.right.color\u0026\u0026(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\u0026\u0026(e.color=0,n.parent.color=1,this.rotate_right(n.parent),e=n.parent.left),0===e.left.color\u0026\u00260===e.right.color?(e.color=1,n=n.parent):(0===e.left.color\u0026\u0026(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\u0026\u0026t!==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,o=t;for(;o\u0026\u0026o!==this.nil_node;)o.less_than(e)?o.intersect(e)?(n=o,o=o.left):o=o.right:(n\u0026\u0026!o.less_than(n)||(n=o),o=o.left);return n||null}tree_search_interval(t,e,n){null!=t\u0026\u0026t!==this.nil_node\u0026\u0026(t.left===this.nil_node||t.not_intersect_left_subtree(e)||this.tree_search_interval(t.left,e,n),t.intersect(e)\u0026\u0026n.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\u0026\u0026t!==this.nil_node\u0026\u0026(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\u0026\u0026e.left!==this.nil_node;)e=e.left;return e}local_maximum(t){let e=t;for(;null!=e.right\u0026\u0026e.right!==this.nil_node;)e=e.right;return e}tree_successor(t){let e,n,o;if(t.right!==this.nil_node)e=this.local_minimum(t.right);else{for(n=t,o=t.parent;null!=o\u0026\u0026o.right===n;)n=o,o=o.parent;e=o}return e}rotate_left(t){const e=t.right;t.right=e.left,e.left!==this.nil_node\u0026\u0026(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\u0026\u0026t!==this.nil_node\u0026\u0026t.update_max(),null!=e\u0026\u0026e!==this.nil_node\u0026\u0026e.update_max()}rotate_right(t){const e=t.left;t.left=e.right,e.right!==this.nil_node\u0026\u0026(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\u0026\u0026t!==this.nil_node\u0026\u0026t.update_max(),null!=e\u0026\u0026e!==this.nil_node\u0026\u0026e.update_max()}tree_walk(t,e){null!=t\u0026\u0026t!==this.nil_node\u0026\u0026(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\u0026\u0026(0===e.left.color\u0026\u00260===e.right.color||(t=!1))}),t}testBlackHeightProperty(t){let e=0,n=0,o=0;if(0===t.color\u0026\u0026e++,n=t.left!==this.nil_node?this.testBlackHeightProperty(t.left):1,o=t.right!==this.nil_node?this.testBlackHeightProperty(t.right):1,n!==o)throw new Error(\"Red-black height property violated\");return e+=n,e}},uO=class extends Set{constructor(t){super(t),this.index=new hO,this.forEach(t=\u003ethis.index.insert(t))}add(t){let e=this.size;const{key:n,value:o}=t,i=n||t.box,r=o||t;return super.add(r),this.size\u003ee\u0026\u0026this.index.insert(i,r),this}delete(t){const{key:e,value:n}=t,o=e||t.box,i=n||t;let r=super.delete(i);return r\u0026\u0026this.index.remove(o,i),r}clear(){super.clear(),this.index=new hO}search(t){return this.index.search(t)}hit(t){let e=new ME.Box(t.x-1,t.y-1,t.x+1,t.y+1);return this.index.search(e).filter(e=\u003et.on(e))}svg(){return[...this].reduce((t,e)=\u003et+e.svg(),\"\")}};ME.PlanarSet=uO;var pO=class{get name(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform((new aO).translate(...t))}rotate(t,e=new ME.Point){return this.transform((new aO).rotate(t,e.x,e.y))}scale(t,e){return this.transform((new aO).scale(t,e))}transform(...t){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}};ME.Point=class t extends pO{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length\u0026\u0026t[0]instanceof Array\u0026\u00262===t[0].length){let e=t[0];if(\"number\"==typeof e[0]\u0026\u0026\"number\"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"point\"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(2===t.length\u0026\u0026\"number\"==typeof t[0]\u0026\u0026\"number\"==typeof t[1])return this.x=t[0],void(this.y=t[1]);throw NE.ILLEGAL_PARAMETERS}}get box(){return new ME.Box(this.x,this.y,this.x,this.y)}clone(){return new ME.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return ME.Utils.EQ(this.x,t.x)\u0026\u0026ME.Utils.EQ(this.y,t.y)}lessThan(t){return!!ME.Utils.LT(this.y,t.y)||!(!ME.Utils.EQ(this.y,t.y)||!ME.Utils.LT(this.x,t.x))}transform(t){return new ME.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let e=new ME.Vector(this,t.pt);if(ME.Utils.EQ_0(e.cross(t.norm)))return t.pt.clone();let n=e.dot(t.norm),o=t.norm.multiply(n);return this.translate(o)}leftTo(t){let e=new ME.Vector(t.pt,this);return ME.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 ME.Segment(this,e)]}return e instanceof ME.Line?ME.Distance.point2line(this,e):e instanceof ME.Circle?ME.Distance.point2circle(this,e):e instanceof ME.Segment?ME.Distance.point2segment(this,e):e instanceof ME.Arc?ME.Distance.point2arc(this,e):e instanceof ME.Box?ME.Distance.point2polygon(this,new ME.Polygon(e)):e instanceof ME.Polygon?ME.Distance.point2polygon(this,e):e instanceof ME.PlanarSet?ME.Distance.shape2planarSet(this,e):e instanceof ME.Multiline?ME.Distance.shape2multiline(this,e):void 0}on(t){if(t instanceof ME.Point)return this.equalTo(t);if(t.contains\u0026\u0026t.contains instanceof Function)return t.contains(this);throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}get name(){return\"point\"}svg(t={}){const e=t.r??3;return`\\n\u003ccircle cx=\"${this.x}\" cy=\"${this.y}\" r=\"${e}\"\\n ${EE({fill:\"red\",...t})} /\u003e`}};var mO=(...t)=\u003enew ME.Point(...t);ME.point=mO;ME.Vector=class extends pO{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length\u0026\u0026t[0]instanceof Array\u0026\u00262===t[0].length){let e=t[0];if(\"number\"==typeof e[0]\u0026\u0026\"number\"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"vector\"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"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\u0026\u0026\"number\"==typeof n)return this.x=e,void(this.y=n);if(e instanceof ME.Point\u0026\u0026n instanceof ME.Point)return this.x=n.x-e.x,void(this.y=n.y-e.y)}throw NE.ILLEGAL_PARAMETERS}}clone(){return new ME.Vector(this.x,this.y)}get slope(){let t=Math.atan2(this.y,this.x);return t\u003c0\u0026\u0026(t=2*Math.PI+t),t}get length(){return Math.sqrt(this.dot(this))}isZeroLength(){return ME.Utils.EQ_0(this.length)}equalTo(t){return ME.Utils.EQ(this.x,t.x)\u0026\u0026ME.Utils.EQ(this.y,t.y)}multiply(t){return new ME.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 NE.ZERO_DIVISION;return new ME.Vector(this.x/this.length,this.y/this.length)}rotate(t,e=new ME.Point){if(0===e.x\u0026\u00260===e.y)return this.transform((new aO).rotate(t));throw NE.OPERATION_IS_NOT_SUPPORTED}transform(t){return new ME.Vector(t.transform([this.x,this.y]))}rotate90CCW(){return new ME.Vector(-this.y,this.x)}rotate90CW(){return new ME.Vector(this.y,-this.x)}invert(){return new ME.Vector(-this.x,-this.y)}add(t){return new ME.Vector(this.x+t.x,this.y+t.y)}subtract(t){return new ME.Vector(this.x-t.x,this.y-t.y)}angleTo(t){let e=this.normalize(),n=t.normalize(),o=Math.atan2(e.cross(n),e.dot(n));return o\u003c0\u0026\u0026(o+=2*Math.PI),o}projectionOn(t){let e=t.normalize(),n=this.dot(e);return e.multiply(n)}get name(){return\"vector\"}};var gO=(...t)=\u003enew ME.Vector(...t);ME.vector=gO;ME.Segment=class t extends pO{constructor(...t){if(super(),this.ps=new ME.Point,this.pe=new ME.Point,0!==t.length){if(1===t.length\u0026\u0026t[0]instanceof Array\u0026\u00264===t[0].length){let e=t[0];return this.ps=new ME.Point(e[0],e[1]),void(this.pe=new ME.Point(e[2],e[3]))}if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"segment\"===t[0].name){let{ps:e,pe:n}=t[0];return this.ps=new ME.Point(e.x,e.y),void(this.pe=new ME.Point(n.x,n.y))}if(!(1===t.length\u0026\u0026t[0]instanceof ME.Point)){if(2===t.length\u0026\u0026t[0]instanceof ME.Point\u0026\u0026t[1]instanceof ME.Point)return this.ps=t[0].clone(),void(this.pe=t[1].clone());if(4===t.length)return this.ps=new ME.Point(t[0],t[1]),void(this.pe=new ME.Point(t[2],t[3]));throw NE.ILLEGAL_PARAMETERS}this.ps=t[0].clone()}}clone(){return new ME.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 ME.Vector(this.start,this.end).slope}get box(){return new ME.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)\u0026\u0026this.pe.equalTo(t.pe)}contains(t){return ME.Utils.EQ_0(this.distanceToPoint(t))}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?DE(this,t):t instanceof ME.Ray?oA(t,this):t instanceof ME.Segment?zE(this,t):t instanceof ME.Circle?jE(this,t):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=zE(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?$E(this,t):t instanceof ME.Polygon?ZE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2segment(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.segment2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.segment2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2segment(this,t);return[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.segment2arc(this,t);return[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline)return ME.Distance.shape2multiline(this,t)}tangentInStart(){return new ME.Vector(this.start,this.end).normalize()}tangentInEnd(){return new ME.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 ME.Segment(this.start,t),new ME.Segment(t,this.end)]}middle(){return new ME.Point((this.start.x+this.end.x)/2,(this.start.y+this.end.y)/2)}pointAtLength(t){if(t\u003ethis.length||t\u003c0)return null;if(0==t)return this.start;if(t==this.length)return this.end;let e=t/this.length;return new ME.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]=ME.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 ME.Matrix){return new t(this.ps.transform(e),this.pe.transform(e))}isZeroLength(){return this.ps.equalTo(this.pe)}sortPoints(t){return new ME.Line(this.start,this.end).sortPoints(t)}get name(){return\"segment\"}svg(t={}){return`\\n\u003cline x1=\"${this.start.x}\" y1=\"${this.start.y}\" x2=\"${this.end.x}\" y2=\"${this.end.y}\" ${EE(t)} /\u003e`}};var fO=(...t)=\u003enew ME.Segment(...t);ME.segment=fO;var{vector:yO}=ME;ME.Line=class t extends pO{constructor(...e){if(super(),this.pt=new ME.Point,this.norm=new ME.Vector(0,1),0!==e.length){if(1===e.length\u0026\u0026e[0]instanceof Object\u0026\u0026\"line\"===e[0].name){let{pt:t,norm:n}=e[0];return this.pt=new ME.Point(t),void(this.norm=new ME.Vector(n))}if(2===e.length){let n=e[0],o=e[1];if(n instanceof ME.Point\u0026\u0026o instanceof ME.Point)return this.pt=n,this.norm=t.points2norm(n,o),void(this.norm.dot(yO(this.pt.x,this.pt.y))\u003e=0\u0026\u0026this.norm.invert());if(n instanceof ME.Point\u0026\u0026o instanceof ME.Vector){if(ME.Utils.EQ_0(o.x)\u0026\u0026ME.Utils.EQ_0(o.y))throw NE.ILLEGAL_PARAMETERS;return this.pt=n.clone(),this.norm=o.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(yO(this.pt.x,this.pt.y))\u003e=0\u0026\u0026this.norm.invert())}if(n instanceof ME.Vector\u0026\u0026o instanceof ME.Point){if(ME.Utils.EQ_0(n.x)\u0026\u0026ME.Utils.EQ_0(n.y))throw NE.ILLEGAL_PARAMETERS;return this.pt=o.clone(),this.norm=n.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(yO(this.pt.x,this.pt.y))\u003e=0\u0026\u0026this.norm.invert())}}throw NE.ILLEGAL_PARAMETERS}}clone(){return new ME.Line(this.pt,this.norm)}get start(){}get end(){}get length(){return Number.POSITIVE_INFINITY}get box(){return new ME.Box(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)}get middle(){}get slope(){return new ME.Vector(this.norm.y,-this.norm.x).slope}get standard(){return[this.norm.x,this.norm.y,this.norm.dot(yO(this.pt.x,this.pt.y))]}parallelTo(t){return ME.Utils.EQ_0(this.norm.cross(t.norm))}incidentTo(t){return this.parallelTo(t)\u0026\u0026this.pt.on(t)}contains(t){if(this.pt.equalTo(t))return!0;let e=new ME.Vector(this.pt,t);return ME.Utils.EQ_0(this.norm.dot(e))}coord(t){return yO(t.x,t.y).cross(this.norm)}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?AE(this,t):t instanceof ME.Ray?sA(t,this):t instanceof ME.Circle?OE(this,t):t instanceof ME.Box?kE(this,t):t instanceof ME.Segment?DE(t,this):t instanceof ME.Arc?LE(this,t):t instanceof ME.Polygon?JE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.circle2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2line(t,this);return[e,n.reverse()]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2line(t,this);return[e,n.reverse()]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}}split(t){if(t instanceof ME.Point)return[new ME.Ray(t,this.norm),new ME.Ray(t,this.norm)];{let e=new ME.Multiline([this]),n=this.sortPoints(t);return e.split(n),e.toShapes()}}rotate(t,e=new ME.Point){return new ME.Line(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new ME.Line(this.pt.transform(t),this.norm.clone())}sortPoints(t){return t.slice().sort((t,e)=\u003ethis.coord(t)\u003cthis.coord(e)?-1:this.coord(t)\u003ethis.coord(e)?1:0)}get name(){return\"line\"}svg(t,e={}){let n=kE(this,t);if(0===n.length)return\"\";let o=n[0],i=2===n.length?n[1]:n.find(t=\u003e!t.equalTo(o));return void 0===i\u0026\u0026(i=o),new ME.Segment(o,i).svg(e)}static points2norm(t,e){if(t.equalTo(e))throw NE.ILLEGAL_PARAMETERS;return new ME.Vector(t,e).normalize().rotate90CCW()}};var _O=(...t)=\u003enew ME.Line(...t);ME.line=_O;ME.Circle=class extends pO{constructor(...t){if(super(),this.pc=new ME.Point,this.r=1,1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"circle\"===t[0].name){let{pc:e,r:n}=t[0];this.pc=new ME.Point(e),this.r=n}else{let[e,n]=[...t];e\u0026\u0026e instanceof ME.Point\u0026\u0026(this.pc=e.clone()),void 0!==n\u0026\u0026(this.r=n)}}clone(){return new ME.Circle(this.pc.clone(),this.r)}get center(){return this.pc}get box(){return new ME.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 ME.Point?ME.Utils.LE(t.distanceTo(this.center)[0],this.r):t instanceof ME.Segment?ME.Utils.LE(t.start.distanceTo(this.center)[0],this.r)\u0026\u0026ME.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof ME.Arc?0===this.intersect(t).length\u0026\u0026ME.Utils.LE(t.start.distanceTo(this.center)[0],this.r)\u0026\u0026ME.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof ME.Circle?0===this.intersect(t).length\u0026\u0026ME.Utils.LE(t.r,this.r)\u0026\u0026ME.Utils.LE(t.center.distanceTo(this.center)[0],this.r):void 0}toArc(t=!0){return new ME.Arc(this.center,this.r,Math.PI,-Math.PI,t)}scale(t,e){if(t!==e)throw NE.OPERATION_IS_NOT_SUPPORTED;if(0!==this.pc.x||0!==this.pc.y)throw NE.OPERATION_IS_NOT_SUPPORTED;return new ME.Circle(this.pc,this.r*t)}transform(t=new ME.Matrix){return new ME.Circle(this.pc.transform(t),this.r)}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?OE(t,this):t instanceof ME.Ray?rA(t,this):t instanceof ME.Segment?jE(t,this):t instanceof ME.Circle?YE(t,this):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=jE(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?VE(t,this):t instanceof ME.Polygon?KE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.circle2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.circle2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline){let[e,n]=ME.Distance.shape2multiline(this,t);return[e,n]}}get name(){return\"circle\"}svg(t={}){return`\\n\u003ccircle cx=\"${this.pc.x}\" cy=\"${this.pc.y}\" r=\"${this.r}\"\\n ${EE({fill:\"none\",...t})} /\u003e`}};ME.circle=(...t)=\u003enew ME.Circle(...t);ME.Arc=class extends pO{constructor(...t){if(super(),this.pc=new ME.Point,this.r=1,this.startAngle=0,this.endAngle=2*Math.PI,this.counterClockwise=!0,0!==t.length)if(1===t.length\u0026\u0026t[0]instanceof Object\u0026\u0026\"arc\"===t[0].name){let{pc:e,r:n,startAngle:o,endAngle:i,counterClockwise:r}=t[0];this.pc=new ME.Point(e.x,e.y),this.r=n,this.startAngle=o,this.endAngle=i,this.counterClockwise=r}else{let[e,n,o,i,r]=[...t];e\u0026\u0026e instanceof ME.Point\u0026\u0026(this.pc=e.clone()),void 0!==n\u0026\u0026(this.r=n),void 0!==o\u0026\u0026(this.startAngle=o),void 0!==i\u0026\u0026(this.endAngle=i),void 0!==r\u0026\u0026(this.counterClockwise=r)}}clone(){return new ME.Arc(this.pc.clone(),this.r,this.startAngle,this.endAngle,this.counterClockwise)}get sweep(){let t=this.startAngle,e=this.endAngle;if(ME.Utils.EQ(Math.abs(t-e),ME.PIx2))return ME.PIx2;Math.abs(t)\u003eME.PIx2\u0026\u0026(t-=Math.trunc(t/ME.PIx2)*ME.PIx2),t\u003c0\u0026\u0026(t+=ME.PIx2),Math.abs(e)\u003eME.PIx2\u0026\u0026(e-=Math.trunc(e/ME.PIx2)*ME.PIx2),e\u003c0\u0026\u0026(e+=ME.PIx2);let n=this.counterClockwise?e-t:t-e;return n\u003c0\u0026\u0026(n+=ME.PIx2),n}get start(){return new ME.Point(this.pc.x+this.r,this.pc.y).rotate(this.startAngle,this.pc)}get end(){return new ME.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)=\u003et.merge(e.start.box),new ME.Box);return t=t.merge(this.end.box),t}contains(t){if(!ME.Utils.EQ(this.pc.distanceTo(t)[0],this.r))return!1;if(t.equalTo(this.start))return!0;let e=new ME.Vector(this.pc,t).slope,n=new ME.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise);return ME.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 ME.Vector(this.pc,t).slope;return[new ME.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise),new ME.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 ME.Arc(this.pc,this.r,this.startAngle,t,this.counterClockwise).end}pointAtLength(t){if(t\u003ethis.length||t\u003c0)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 ME.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 ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?LE(t,this):t instanceof ME.Ray?iA(t,this):t instanceof ME.Circle?VE(this,t):t instanceof ME.Segment?$E(t,this):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=$E(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?XE(this,t):t instanceof ME.Polygon?qE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.arc2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.arc2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2arc(this,t);return[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline)return ME.Distance.shape2multiline(this,t)}breakToFunctional(){let t=[],e=[0,Math.PI/2,Math.PI,3*Math.PI/2],n=this.startAngle,o=this.endAngle;ME.Utils.EQ(Math.abs(n-o),ME.PIx2)\u0026\u0026(o=n),Math.abs(n)\u003eME.PIx2\u0026\u0026(n-=Math.trunc(n/ME.PIx2)*ME.PIx2),n\u003c0\u0026\u0026(n+=ME.PIx2),Math.abs(o)\u003eME.PIx2\u0026\u0026(o-=Math.trunc(o/ME.PIx2)*ME.PIx2),o\u003c0\u0026\u0026(o+=ME.PIx2);let i,r,s,a=n;this.counterClockwise?(r=Math.ceil(n/(Math.PI/2))%4,s=1):(r=Math.floor(n/(Math.PI/2))%4,s=-1);for(let o=0,c=r;o\u003c4;o++,c=(c+s+4)%4){if(i=e[c],i===a)continue;let o=this.counterClockwise?i-n:n-i;if(o\u003c0\u0026\u0026(o+=ME.PIx2),o\u003ethis.sweep)break;t.push(new ME.Arc(this.pc,this.r,a,i,this.counterClockwise)),a=i}return 0===t.length?(t.push(this),t):(i=o,a!==i\u0026\u0026t.push(new ME.Arc(this.pc,this.r,a,i,this.counterClockwise)),t)}tangentInStart(){let t=new ME.Vector(this.pc,this.start),e=this.counterClockwise?Math.PI/2:-Math.PI/2;return t.rotate(e).normalize()}tangentInEnd(){let t=new ME.Vector(this.pc,this.end),e=this.counterClockwise?-Math.PI/2:Math.PI/2;return t.rotate(e).normalize()}reverse(){return new ME.Arc(this.pc,this.r,this.endAngle,this.startAngle,!this.counterClockwise)}transform(t=new ME.Matrix){let e=this.start.transform(t),n=this.end.transform(t),o=this.pc.transform(t),i=this.counterClockwise;return t.a*t.d\u003c0\u0026\u0026(i=!i),ME.Arc.arcSE(o,e,n,i)}static arcSE(t,e,n,o){let{vector:i}=ME,r=i(t,e).slope,s=i(t,n).slope;ME.Utils.EQ(r,s)\u0026\u0026(s+=2*Math.PI,o=!0);let a=i(t,e).length;return new ME.Arc(t,a,r,s,o)}definiteIntegral(t=0){return this.breakToFunctional().reduce((e,n)=\u003ee+n.circularSegmentDefiniteIntegral(t),0)}circularSegmentDefiniteIntegral(t){let e=new ME.Segment(this.start,this.end).definiteIntegral(t),n=ME.Utils.EQ(this.sweep,ME.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}=ME;return t.slice().sort((t,n)=\u003e{let o=e(this.pc,t).slope,i=e(this.pc,n).slope;return o\u003ci?-1:o\u003ei?1:0})}get name(){return\"arc\"}svg(t={}){let e=this.sweep\u003c=Math.PI?\"0\":\"1\",n=this.counterClockwise?\"1\":\"0\";if(ME.Utils.EQ(this.sweep,2*Math.PI)){return new ME.Circle(this.pc,this.r).svg(t)}return`\\n\u003cpath d=\"M${this.start.x},${this.start.y}\\n A${this.r},${this.r} 0 ${e},${n} ${this.end.x},${this.end.y}\"\\n ${EE({fill:\"none\",...t})} /\u003e`}};ME.arc=(...t)=\u003enew ME.Arc(...t);ME.Box=class t extends pO{constructor(t=void 0,e=void 0,n=void 0,o=void 0){super(),this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}clone(){return new t(this.xmin,this.ymin,this.xmax,this.ymax)}get low(){return new ME.Point(this.xmin,this.ymin)}get high(){return new ME.Point(this.xmax,this.ymax)}get max(){return this.clone()}get center(){return new ME.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\u003ct.xmin||this.xmin\u003et.xmax||this.ymax\u003ct.ymin||this.ymin\u003et.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)\u0026\u0026this.high.equalTo(t.high)}output(){return this.clone()}comparable_less_than(t,e){return t.lessThan(e)}set(t,e,n,o){this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}extend(e){return e\u003c=0?this.clone():new t(this.xmin-e,this.ymin-e,this.xmax+e,this.ymax+e)}toPoints(){return[new ME.Point(this.xmin,this.ymin),new ME.Point(this.xmax,this.ymin),new ME.Point(this.xmax,this.ymax),new ME.Point(this.xmin,this.ymax)]}toSegments(){let t=this.toPoints();return[new ME.Segment(t[0],t[1]),new ME.Segment(t[1],t[2]),new ME.Segment(t[2],t[3]),new ME.Segment(t[3],t[0])]}rotate(t,e=new ME.Point){throw NE.OPERATION_IS_NOT_SUPPORTED}transform(e=new ME.Matrix){return this.toPoints().map(t=\u003et.transform(e)).reduce((t,e)=\u003et.merge(e.box),new t)}contains(t){return t instanceof ME.Point?t.x\u003e=this.xmin\u0026\u0026t.x\u003c=this.xmax\u0026\u0026t.y\u003e=this.ymin\u0026\u0026t.y\u003c=this.ymax:t instanceof ME.Segment?t.vertices.every(t=\u003ethis.contains(t)):t instanceof ME.Box?t.toSegments().every(t=\u003ethis.contains(t)):t instanceof ME.Circle?this.contains(t.box):t instanceof ME.Arc?t.vertices.every(t=\u003ethis.contains(t))\u0026\u0026this.toSegments().every(e=\u003e0===$E(e,t).length):!(t instanceof ME.Line||t instanceof ME.Ray)\u0026\u0026(t instanceof ME.Multiline?t.toShapes().every(t=\u003ethis.contains(t)):t instanceof ME.Polygon?this.contains(t.box):void 0)}distanceTo(t){const e=this.toSegments().map(e=\u003ee.distanceTo(t));let n=[Number.MAX_SAFE_INTEGER,null];return e.forEach(t=\u003e{t[0]\u003cn[0]\u0026\u0026(n=t)}),n}get name(){return\"box\"}svg(t={}){const e=this.xmax-this.xmin,n=this.ymax-this.ymin;return`\\n\u003crect x=\"${this.xmin}\" y=\"${this.ymin}\" width=\"${e}\" height=\"${n}\"\\n ${EE({fill:\"none\",...t})} /\u003e`}};ME.box=(...t)=\u003enew ME.Box(...t);ME.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 ME.Segment}get isArc(){return this.shape instanceof ME.Arc}get isLine(){return this.shape instanceof ME.Line}get isRay(){return this.shape instanceof ME.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 ME.Line||this.shape instanceof ME.Ray)return this.bv=ME.OUTSIDE,this.bv;if(void 0===this.bvStart\u0026\u0026(this.bvStart=KA(t,this.start)),void 0===this.bvEnd\u0026\u0026(this.bvEnd=KA(t,this.end)),this.bvStart===ME.OUTSIDE||this.bvEnd==ME.OUTSIDE)this.bv=ME.OUTSIDE;else if(this.bvStart===ME.INSIDE||this.bvEnd==ME.INSIDE)this.bv=ME.INSIDE;else{let e=KA(t,this.middle());this.bv=e}return this.bv}setOverlap(t){let e,n=this.shape,o=t.shape;n instanceof ME.Segment\u0026\u0026o instanceof ME.Segment?n.start.equalTo(o.start)\u0026\u0026n.end.equalTo(o.end)?e=ME.OVERLAP_SAME:n.start.equalTo(o.end)\u0026\u0026n.end.equalTo(o.start)\u0026\u0026(e=ME.OVERLAP_OPPOSITE):(n instanceof ME.Arc\u0026\u0026o instanceof ME.Arc||n instanceof ME.Segment\u0026\u0026o instanceof ME.Arc||n instanceof ME.Arc\u0026\u0026o instanceof ME.Segment)\u0026\u0026(n.start.equalTo(o.start)\u0026\u0026n.end.equalTo(o.end)\u0026\u0026n.middle().equalTo(o.middle())?e=ME.OVERLAP_SAME:n.start.equalTo(o.end)\u0026\u0026n.end.equalTo(o.start)\u0026\u0026n.middle().equalTo(o.middle())\u0026\u0026(e=ME.OVERLAP_OPPOSITE)),void 0===this.overlap\u0026\u0026(this.overlap=e),void 0===t.overlap\u0026\u0026(t.overlap=e)}svg(){if(this.shape instanceof ME.Segment)return` L${this.shape.end.x},${this.shape.end.y}`;if(this.shape instanceof ME.Arc){let t,e=this.shape,n=e.counterClockwise?\"1\":\"0\";if(ME.Utils.EQ(e.sweep,2*Math.PI)){let o=e.counterClockwise?1:-1,i=new ME.Arc(e.pc,e.r,e.startAngle,e.startAngle+o*Math.PI,e.counterClockwise),r=new ME.Arc(e.pc,e.r,e.startAngle+o*Math.PI,e.endAngle,e.counterClockwise);return t=\"0\",` A${i.r},${i.r} 0 ${t},${n} ${i.end.x},${i.end.y}\\n A${r.r},${r.r} 0 ${t},${n} ${r.end.x},${r.end.y}`}return t=e.sweep\u003c=Math.PI?\"0\":\"1\",` A${e.r},${e.r} 0 ${t},${n} ${e.end.x},${e.end.y}`}}toJSON(){return this.shape.toJSON()}};var bO=class extends wE{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:()=\u003e{let e=t||this.first,n=!this.first||!!t\u0026\u0026t===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}};ME.Face=class t extends bO{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 o=n[0];if(0===o.length)return;if(o.every(t=\u003et instanceof ME.Point)){let n=t.points2segments(o);this.shapes2face(e.edges,n)}else if(o.every(t=\u003et instanceof Array\u0026\u00262===t.length)){let n=o.map(t=\u003enew ME.Point(t[0],t[1])),i=t.points2segments(n);this.shapes2face(e.edges,i)}else if(o.every(t=\u003et instanceof ME.Segment||t instanceof ME.Arc))this.shapes2face(e.edges,o);else if(o.every(t=\u003e\"segment\"===t.name||\"arc\"===t.name)){let t=[];for(let e of o){let n;n=\"segment\"===e.name?new ME.Segment(e):new ME.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 ME.Circle)this.shapes2face(e.edges,[n[0].toArc(gE)]);else if(n[0]instanceof ME.Box){let t=n[0];this.shapes2face(e.edges,[new ME.Segment(new ME.Point(t.xmin,t.ymin),new ME.Point(t.xmax,t.ymin)),new ME.Segment(new ME.Point(t.xmax,t.ymin),new ME.Point(t.xmax,t.ymax)),new ME.Segment(new ME.Point(t.xmax,t.ymax),new ME.Point(t.xmin,t.ymax)),new ME.Segment(new ME.Point(t.xmin,t.ymax),new ME.Point(t.xmin,t.ymin))])}2===n.length\u0026\u0026n[0]instanceof ME.Edge\u0026\u0026n[1]instanceof ME.Edge\u0026\u0026(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=\u003et.shape.start.clone())}get shapes(){return this.edges.map(t=\u003et.shape.clone())}get box(){if(void 0===this._box){let t=new ME.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\u003ethis.perimeter||t\u003c0)return null;let e=null;for(let n of this)if(t\u003e=n.arc_length\u0026\u0026(n===this.last||t\u003cn.next.arc_length)){e=n.pointAtLength(t-n.arc_length);break}return e}static points2segments(t){let e=[];for(let n=0;n\u003ct.length;n++)t[n].equalTo(t[(n+1)%t.length])||e.push(new ME.Segment(t[n],t[(n+1)%t.length]));return e}shapes2face(t,e){for(let n of e){let e=new ME.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\u0026\u0026(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();ME.Utils.EQ_0(t)?this._orientation=fE.NOT_ORIENTABLE:ME.Utils.LT(t,0)?this._orientation=fE.CCW:this._orientation=fE.CW}return this._orientation}isSimple(e){return 0===t.getSelfIntersections(this,e,!0).length}static getSelfIntersections(t,e,n=!1){let o=[];for(let i of t){let r=e.search(i.box);for(let e of r){if(i===e)continue;if(e.face!==t)continue;if(i.shape instanceof ME.Segment\u0026\u0026e.shape instanceof ME.Segment\u0026\u0026(i.next===e||i.prev===e))continue;let r=i.shape.intersect(e.shape);for(let t of r)if((!t.equalTo(i.start)||!t.equalTo(e.end)||e!==i.prev)\u0026\u0026(!t.equalTo(i.end)||!t.equalTo(e.start)||e!==i.next)\u0026\u0026(o.push(t),n))break;if(o.length\u003e0\u0026\u0026n)break}if(o.length\u003e0\u0026\u0026n)break}return o}findEdgeByPoint(t){let e;for(let n of this)if(!t.equalTo(n.shape.start)\u0026\u0026(t.equalTo(n.shape.end)||n.shape.contains(t))){e=n;break}return e}toPolygon(){return new ME.Polygon(this.shapes)}toJSON(){return this.edges.map(t=\u003et.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}};ME.Ray=class t extends pO{constructor(...t){if(super(),this.pt=new ME.Point,this.norm=new ME.Vector(0,1),0!==t.length\u0026\u0026(t.length\u003e=1\u0026\u0026t[0]instanceof ME.Point\u0026\u0026(this.pt=t[0].clone()),1!==t.length)){if(!(2===t.length\u0026\u0026t[1]instanceof ME.Vector))throw NE.ILLEGAL_PARAMETERS;this.norm=t[1].clone()}}clone(){return new t(this.pt,this.norm)}get slope(){return new ME.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new ME.Box(t\u003eMath.PI/2\u0026\u0026t\u003c3*Math.PI/2?Number.NEGATIVE_INFINITY:this.pt.x,t\u003e=0\u0026\u0026t\u003c=Math.PI?this.pt.y:Number.NEGATIVE_INFINITY,t\u003e=Math.PI/2\u0026\u0026t\u003c=3*Math.PI/2?this.pt.x:Number.POSITIVE_INFINITY,t\u003e=Math.PI\u0026\u0026t\u003c=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 ME.Vector(this.pt,t);return ME.Utils.EQ_0(this.norm.dot(e))\u0026\u0026ME.Utils.GE(e.cross(this.norm),0)}coord(t){return gO(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new ME.Segment(this.pt,t),new ME.Ray(t,this.norm)]:[]}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Segment?oA(this,t):t instanceof ME.Arc?iA(this,t):t instanceof ME.Line?sA(this,t):t instanceof ME.Ray?(n=t,AE(nA(e=this),nA(n)).filter(t=\u003ee.contains(t)).filter(t=\u003en.contains(t))):t instanceof ME.Circle?rA(this,t):t instanceof ME.Box?(i=t,kE(nA(o=this),i).filter(t=\u003eo.contains(t))):t instanceof ME.Polygon?aA(this,t):t instanceof ME.Multiline?lA(this,t):void 0;var e,n,o,i}rotate(t,e=new ME.Point){return new ME.Ray(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new ME.Ray(this.pt.transform(t),this.norm.clone())}get name(){return\"ray\"}svg(t,e={}){let n=kE(new ME.Line(this.pt,this.norm),t);return n=n.filter(t=\u003ethis.contains(t)),0===n.length||2===n.length?\"\":new ME.Segment(this.pt,n[0]).svg(e)}};ME.ray=(...t)=\u003enew ME.Ray(...t);var xO=class t{constructor(){this.faces=new ME.PlanarSet,this.edges=new ME.PlanarSet;let t=[...arguments];if(1===t.length\u0026\u0026(t[0]instanceof Array\u0026\u0026t[0].length\u003e0||t[0]instanceof ME.Circle||t[0]instanceof ME.Box)){let e=t[0];if(t[0]instanceof Array\u0026\u0026t[0].every(t=\u003et instanceof Array))if(e.every(t=\u003et instanceof Array\u0026\u00262===t.length\u0026\u0026\"number\"==typeof t[0]\u0026\u0026\"number\"==typeof t[1]))this.faces.add(new ME.Face(this,e));else for(let t of e)if(t instanceof Array\u0026\u0026t[0]instanceof Array\u0026\u0026t[0].every(t=\u003et instanceof Array\u0026\u00262===t.length\u0026\u0026\"number\"==typeof t[0]\u0026\u0026\"number\"==typeof t[1]))for(let e of t)this.faces.add(new ME.Face(this,e));else this.faces.add(new ME.Face(this,t));else this.faces.add(new ME.Face(this,e))}}get box(){return[...this.faces].reduce((t,e)=\u003et.merge(e.box),new ME.Box)}get vertices(){return[...this.faces].flatMap(t=\u003et.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=\u003e[...t.faces].forEach(t=\u003en.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)=\u003et+e.signedArea(),0);return Math.abs(t)}addFace(...t){let e=new ME.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 o=e;o!==n.next;o=o.next)if(t.remove(o),this.edges.delete(o),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 o=new ME.Edge(n[0]),i=e.prev;return e.face.insert(o,i),this.edges.delete(e),this.edges.add(o),e.shape=n[1],this.edges.add(e),o}removeEndVertex(t){const e=t.next;e!==t\u0026\u0026(t.face.merge_with_next_edge(t),this.edges.delete(e))}cut(t){const e=this.splitToIslands().flatMap(e=\u003ee._cutSingleIsland(t)).filter(t=\u003et.isValid()\u0026\u0026!1===t.isEmpty());return this.createFromArray(e)}_cutSingleIsland(t){let e=this.clone();const n=t.clone();let o,i,r={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let t of n.edges)for(let n of e.edges){let e=QE(t,n);for(let o of e)hA(t,o,r.int_points1),hA(n,o,r.int_points2)}if(0===r.int_points1.length)return e;r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2),bA(n,r.int_points1_sorted),bA(e,r.int_points2_sorted),gA(r),r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2),fA(r.int_points1),yA(r.int_points1,e);for(let t of r.int_points1_sorted)t.edge_before\u0026\u0026t.edge_after\u0026\u0026t.edge_before.bv===t.edge_after.bv\u0026\u0026(r.int_points2[t.id]=-1,t.id=-1);if(r.int_points1=r.int_points1.filter(t=\u003et.id\u003e=0),r.int_points2=r.int_points2.filter(t=\u003et.id\u003e=0),r.int_points1.forEach((t,e)=\u003e{t.id=e}),r.int_points2.forEach((t,e)=\u003e{t.id=e}),0===r.int_points1.length)return e;r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2);for(let t=1;t\u003cr.int_points1_sorted.length;t++)if(i=r.int_points1_sorted[t],o=r.int_points1_sorted[t-1],i.edge_before\u0026\u00261===i.edge_before.bv){let t=o.edge_after,s=i.edge_before,a=n.getChain(t,s);xA(r.int_points2[o.id],r.int_points2[i.id],a),a.forEach(t=\u003ee.edges.add(t)),a=a.reverse().map(t=\u003enew ME.Edge(t.shape.reverse()));for(let t=0;t\u003ca.length-1;t++)a[t].next=a[t+1],a[t+1].prev=a[t];xA(r.int_points2[i.id],r.int_points2[o.id],a),a.forEach(t=\u003ee.edges.add(t))}return e.recreateFaces(),e}cutWithLine(t){let e=new dA([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)=\u003ee.area()-t.area());let e=[...t[0].faces][0].orientation(),n=t.filter(t=\u003e[...t.faces][0].orientation()===e);for(let o of t){let t=[...o.faces][0];if(t.orientation()!==e)for(let e of n)if(t.shapes.every(t=\u003ee.contains(t))){e.addFace(t.shapes);break}}return n}rearrange(){if(this.faces.size\u003c=1)return this.clone();const e=this.splitToIslands(),n=new t;return e.forEach(t=\u003e{t.faces.forEach(t=\u003en.addFace(t.shapes))}),n}orientation(){return this.isEmpty()?fE.NOT_ORIENTABLE:[...this.faces][0].orientation()}isOuter(t){return t.orientation()===this.orientation()}isMultiPolygon(){let t=0;return this.faces.forEach(e=\u003e{this.isOuter(e)\u0026\u0026t++}),t\u003e1}reverse(){for(let t of this.faces)t.reverse();return this}contains(t){if(t instanceof ME.Point){let e=KA(this,t);return 1===e||2===e}return nO(this,t)}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle||t instanceof ME.Line||t instanceof ME.Segment||t instanceof ME.Arc){let[e,n]=ME.Distance.shape2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Box)return this.distanceTo(new ME.Polygon(t));if(t instanceof ME.Polygon){let e,n,o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of this.edges){let r=o[0];[e,n]=ME.Distance.shape2planarSet(i.shape,t.edges,r),ME.Utils.LT(e,r)\u0026\u0026(o=[e,n])}return o}}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?JE(t,this):t instanceof ME.Ray?aA(t,this):t instanceof ME.Circle?KE(t,this):t instanceof ME.Segment?ZE(t,this):t instanceof ME.Arc?qE(t,this):t instanceof ME.Polygon?function(t,e){let n=[];if(t.isEmpty()||e.isEmpty())return n;if(t.box.not_intersect(e.box))return n;for(let o of t.edges)n=[...n,...tA(o,e)];return n}(t,this):t instanceof ME.Multiline?function(t,e){let n=[];if(e.isEmpty()||0===t.size)return n;for(let o of t)n=[...n,...tA(o,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=\u003et.translate(e)));return n}rotate(e=0,n=new ME.Point){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=\u003et.rotate(e,n)));return o}scale(e,n){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=\u003et.scale(e,n)));return o}transform(e=new ME.Matrix){let n=new t;for(let t of this.faces)n.addFace(t.shapes.map(t=\u003et.transform(e)));return n}toJSON(){return[...this.faces].map(t=\u003et.toJSON())}toArray(){return[...this.faces].map(t=\u003et.toPolygon())}dpath(){return[...this.faces].reduce((t,e)=\u003et+e.svg(),\"\")}svg(t={}){let e=`\\n\u003cpath ${EE({fillRule:\"evenodd\",fill:\"lightcyan\",...t})} d=\"`;for(let t of this.faces)e+=`\\n${t.svg()}`;return e+='\" \u003e\\n\u003c/path\u003e',e}};ME.Polygon=xO;ME.polygon=(...t)=\u003enew ME.Polygon(...t);var{Circle:vO,Line:SO,Point:IO,Vector:CO,Utils:PO}=ME;ME.Inversion=class t{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,e){const n=new CO(t.pc,e),o=t.r*t.r,i=n.dot(n);return PO.EQ_0(i)?new IO(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY):t.pc.translate(n.multiply(o/i))}static inverseCircle(t,e){const n=t.pc.distanceTo(e.pc)[0];if(PO.EQ(n,e.r)){let n=t.r*t.r/(2*e.r),o=new CO(t.pc,e.pc);o=o.normalize();let i=t.pc.translate(o.multiply(n));return new SO(i,o)}{let n=new CO(t.pc,e.pc),o=t.r*t.r/(n.dot(n)-e.r*e.r),i=t.pc.translate(n.multiply(o)),r=Math.abs(o)*e.r;return new vO(i,r)}}static inverseLine(t,e){const[n,o]=t.pc.distanceTo(e);if(PO.EQ_0(n))return e.clone();{let e=t.r*t.r/(2*n),i=new CO(t.pc,o.end);return i=i.multiply(e/n),new vO(t.pc.translate(i),e)}}inverse(e){return e instanceof IO?t.inversePoint(this.circle,e):e instanceof vO?t.inverseCircle(this.circle,e):e instanceof SO?t.inverseLine(this.circle,e):void 0}};ME.inversion=t=\u003enew ME.Inversion(t);ME.Distance=class t{static point2point(t,e){return t.distanceTo(e)}static point2line(t,e){let n=t.projectionOn(e);return[new ME.Vector(t,n).length,new ME.Segment(t,n)]}static point2circle(t,e){let[n,o]=t.distanceTo(e.center);if(ME.Utils.EQ_0(n))return[e.r,new ME.Segment(t,e.toArc().start)];{let o=Math.abs(n-e.r),i=new ME.Vector(e.pc,t).normalize().multiply(e.r),r=e.pc.translate(i);return[o,new ME.Segment(t,r)]}}static point2segment(e,n){if(n.start.equalTo(n.end))return t.point2point(e,n.start);let o,i,r=new ME.Vector(n.start,n.end),s=new ME.Vector(n.start,e),a=new ME.Vector(n.end,e),c=r.dot(s),l=-r.dot(a);if(ME.Utils.GE(c,0)\u0026\u0026ME.Utils.GE(l,0)){let t=n.tangentInStart();return o=Math.abs(t.cross(s)),i=n.start.translate(t.multiply(t.dot(s))),[o,new ME.Segment(e,i)]}return c\u003c0?e.distanceTo(n.start):e.distanceTo(n.end)}static point2arc(e,n){let o,i,r=new ME.Circle(n.pc,n.r),s=[];return[o,i]=t.point2circle(e,r),i.end.on(n)\u0026\u0026s.push(t.point2circle(e,r)),s.push(t.point2point(e,n.start)),s.push(t.point2point(e,n.end)),t.sort(s),s[0]}static point2edge(e,n){return n.shape instanceof ME.Segment?t.point2segment(e,n.shape):t.point2arc(e,n.shape)}static segment2line(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=[];return i.push(t.point2line(e.start,n)),i.push(t.point2line(e.end,n)),t.sort(i),i[0]}static segment2segment(e,n){let o=zE(e,n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i,r,s=[];return[i,r]=t.point2segment(n.start,e),s.push([i,r.reverse()]),[i,r]=t.point2segment(n.end,e),s.push([i,r.reverse()]),s.push(t.point2segment(e.start,n)),s.push(t.point2segment(e.end,n)),t.sort(s),s[0]}static segment2circle(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Line(e.ps,e.pe),[r,s]=t.point2line(n.center,i);if(ME.Utils.GE(r,n.r)\u0026\u0026s.end.on(e))return t.point2circle(s.end,n);{let[o,i]=t.point2circle(e.start,n),[r,s]=t.point2circle(e.end,n);return ME.Utils.LT(o,r)?[o,i]:[r,s]}}static segment2arc(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Line(e.ps,e.pe),r=new ME.Circle(n.pc,n.r),[s,a]=t.point2line(r.center,i);if(ME.Utils.GE(s,r.r)\u0026\u0026a.end.on(e)){let[e,o]=t.point2circle(a.end,r);if(o.end.on(n))return[e,o]}let c,l,d=[];return d.push(t.point2arc(e.start,n)),d.push(t.point2arc(e.end,n)),[c,l]=t.point2segment(n.start,e),d.push([c,l.reverse()]),[c,l]=t.point2segment(n.end,e),d.push([c,l.reverse()]),t.sort(d),d[0]}static circle2circle(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];if(e.center.equalTo(n.center)){let o=e.toArc(),i=n.toArc();return t.point2point(o.start,i.start)}{let o=new ME.Line(e.center,n.center),i=o.intersect(e),r=o.intersect(n),s=[];return s.push(t.point2point(i[0],r[0])),s.push(t.point2point(i[0],r[1])),s.push(t.point2point(i[1],r[0])),s.push(t.point2point(i[1],r[1])),t.sort(s),s[0]}}static circle2line(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let[i,r]=t.point2line(e.center,n),[s,a]=t.point2circle(r.end,e);return a=a.reverse(),[s,a]}static arc2line(e,n){let o=n.intersect(e);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),[r,s]=t.point2line(i.center,n);if(!ME.Utils.GE(r,i.r)){let o=[];return o.push(t.point2line(e.start,n)),o.push(t.point2line(e.end,n)),t.sort(o),o[0]}{let[n,o]=t.point2circle(s.end,i);if(o.end.on(e))return[n,o]}}static arc2circle(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),[r,s]=t.circle2circle(i,n);if(s.start.on(e))return[r,s];{let o=[];return o.push(t.point2circle(e.start,n)),o.push(t.point2circle(e.end,n)),t.sort(o),o[0]}}static arc2arc(e,n){let o=e.intersect(n);if(o.length\u003e0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),r=new ME.Circle(n.center,n.r),[s,a]=t.circle2circle(i,r);if(a.start.on(e)\u0026\u0026a.end.on(n))return[s,a];{let o,i,r=[];return[o,i]=t.point2arc(e.start,n),i.end.on(n)\u0026\u0026r.push([o,i]),[o,i]=t.point2arc(e.end,n),i.end.on(n)\u0026\u0026r.push([o,i]),[o,i]=t.point2arc(n.start,e),i.end.on(e)\u0026\u0026r.push([o,i.reverse()]),[o,i]=t.point2arc(n.end,e),i.end.on(e)\u0026\u0026r.push([o,i.reverse()]),[o,i]=t.point2point(e.start,n.start),r.push([o,i]),[o,i]=t.point2point(e.start,n.end),r.push([o,i]),[o,i]=t.point2point(e.end,n.start),r.push([o,i]),[o,i]=t.point2point(e.end,n.end),r.push([o,i]),t.sort(r),r[0]}}static point2polygon(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of n.edges){let[n,r]=t.point2edge(e,i);ME.Utils.LT(n,o[0])\u0026\u0026(o=[n,r])}return o}static shape2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new ME.Segment];for(let o of e.edges){let[e,i]=t.distanceTo(o.shape);ME.Utils.LT(e,n[0])\u0026\u0026(n=[e,i])}return n}static polygon2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new ME.Segment];for(let o of t.edges)for(let t of e.edges){let[e,i]=o.shape.distanceTo(t.shape);ME.Utils.LT(e,n[0])\u0026\u0026(n=[e,i])}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)),o=Math.max(Math.max(t.ymin-e.ymax,0),Math.max(e.ymin-t.ymax,0)),i=n*n+o*o,r=t.merge(e),s=r.xmax-r.xmin,a=r.ymax-r.ymin;return[i,s*s+a*a]}static minmax_tree_process_level(e,n,o,i){let r,s;for(let a of n){[r,s]=t.box2box_minmax(e.box,a.item.key);for(let t of a.item.values)t instanceof ME.Edge?i.insert([r,s],t.shape):i.insert([r,s],t);ME.Utils.LT(s,o)\u0026\u0026(o=s)}if(0===n.length)return o;let a=[...n.map(t=\u003et.left.isNil()?void 0:t.left).filter(t=\u003evoid 0!==t),...n.map(t=\u003et.right.isNil()?void 0:t.right).filter(t=\u003evoid 0!==t)].filter(n=\u003e{let[i,r]=t.box2box_minmax(e.box,n.max);return ME.Utils.LE(i,o)});return o=t.minmax_tree_process_level(e,a,o,i)}static minmax_tree(e,n,o){let i=new hO,r=[n.index.root],s=o\u003cNumber.POSITIVE_INFINITY?o*o:Number.POSITIVE_INFINITY;return s=t.minmax_tree_process_level(e,r,s,i),i}static minmax_tree_calc_distance(e,n,o){let i,r;if(null!=n\u0026\u0026!n.isNil()){if([i,r]=t.minmax_tree_calc_distance(e,n.left,o),r)return[i,r];if(ME.Utils.LT(i[0],Math.sqrt(n.item.key.low)))return[i,!0];let[s,a]=t.distanceToArray(e,n.item.values);return ME.Utils.LT(s,i[0])\u0026\u0026(i=[s,a]),[i,r]=t.minmax_tree_calc_distance(e,n.right,i),[i,r]}return[o,!1]}static shape2planarSet(e,n,o=Number.POSITIVE_INFINITY){let i=[o,new ME.Segment],r=!1;if(n instanceof ME.PlanarSet){let s=t.minmax_tree(e,n,o);[i,r]=t.minmax_tree_calc_distance(e,s.root,i)}return i}static sort(t){t.sort((t,e)=\u003eME.Utils.LT(t[0],e[0])?-1:ME.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 ME.Segment];for(let o of e){let[e,i]=t.distanceTo(o);ME.Utils.LT(e,n[0])\u0026\u0026(n=[e,i])}return n}static shape2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of n){let[n,r]=t.distance(e,i.shape);ME.Utils.LT(n,o[0])\u0026\u0026(o=[n,r])}return o}static multiline2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of e)for(let e of n){let[n,r]=t.distance(i.shape,e.shape);ME.Utils.LT(n,o[0])\u0026\u0026(o=[n,r])}return o}};var{Multiline:MO,Point:NO,Segment:wO,Polygon:TO}=ME;function RO(t){return new NO(t.split(\" \").map(Number))}function EO(t){return t.split(\", \").map(RO)}function AO(t){const e=EO(t);let n=[];for(let t=0;t\u003ce.length-1;t++)n.push(new wO(e[t],e[t+1]));return new MO(n)}function OO(t){const e=t.replace(/\\(\\(/,\"\").replace(/\\)\\)$/,\"\").split(\"), (\"),n=new TO;let o;return e.forEach((t,e)=\u003e{let i=t.split(\", \").map(t=\u003enew NO(t.split(\" \").map(Number)));const r=n.addFace(i);0===e?o=r.orientation():r.orientation()===o\u0026\u0026r.reverse()}),n}function kO(t){if(t.startsWith(\"POLYGON\")){return OO(t.replace(/^POLYGON /,\"\"))}return function(t){const e=t.split(/\\)\\), \\(\\(/).map(t=\u003e\"((\"+t+\"))\").map(OO),n=new TO;return e.reduce((t,e)=\u003e[...t,...e?.faces],[]).forEach(t=\u003en.addFace([...t?.shapes])),n}(t.replace(/^MULTIPOLYGON \\(\\(\\((.*)\\)\\)\\)$/,\"$1\"))}function LO(t){return t.split(\"\\n\")?.every(t=\u003et.includes(\"POINT\"))}function DO(t){return t.split(\"\\n\")?.every(t=\u003et.includes(\"LINESTRING\"))}function zO(t,e,n,o){return Math.sqrt((n-t)**2+(o-e)**2)}ME.isWktString=function(t){return t.startsWith(\"POINT\")||LO(t)||t.startsWith(\"LINESTRING\")||DO(t)||t.startsWith(\"MULTILINESTRING\")||t.startsWith(\"POLYGON\")||t.startsWith(\"MULTIPOINT\")||t.startsWith(\"MULTIPOLYGON\")||t.startsWith(\"GEOMETRYCOLLECTION\")},ME.parseWKT=function t(e){if(e.startsWith(\"POINT\")){return RO(e.replace(/^POINT \\(/,\"\").replace(/\\)$/,\"\"))}if(e.startsWith(\"MULTIPOINT\")){return EO(e.replace(/^MULTIPOINT \\(/,\"\").replace(/\\)$/,\"\"))}if(e.startsWith(\"LINESTRING\")){return AO(e.replace(/^LINESTRING \\(/,\"\").replace(/\\)$/,\"\"))}if(e.startsWith(\"MULTILINESTRING\")){return function(t){return t.replace(/\\(\\(/,\"\").replace(/\\)\\)$/,\"\").split(\"), (\").map(AO)}(e.replace(/^MULTILINESTRING /,\"\"))}if(e.startsWith(\"POLYGON\")||e.startsWith(\"MULTIPOLYGON\"))return kO(e);if(e.startsWith(\"GEOMETRYCOLLECTION\")){const n=/(?\u003ctype\u003ePOINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \\((?:[^\\(\\)]|\\([^\\)]*\\))*\\)/g,o=e.match(n);o[0].startsWith(\"GEOMETRYCOLLECTION\")\u0026\u0026(o[0]=o[0].replace(\"GEOMETRYCOLLECTION (\",\"\"));return o.map(t).map(t=\u003et instanceof Array?t:[t]).reduce((t,e)=\u003e[...t,...e],[])}return LO(e)?function(t){return t.split(\"\\n\").map(t=\u003et.match(/\\(([^)]+)\\)/)[1]).map(RO)}(e):DO(e)?function(t){return t.split(\"\\n\").map(t=\u003et.match(/\\(([^)]+)\\)/)[1]).map(AO).reduce((t,e)=\u003e[...t,...e],[])}(e):[]},ME.BooleanOperations=WA,ME.Relations=sO;var FO=class{buckets;objectsById;getBounds;getId;CELL_SIZE=.4;constructor({objects:t,getBounds:e,getId:n,CELL_SIZE:o}){this.buckets=new Map,this.objectsById=new Map,this.getBounds=e,this.getId=n??(()=\u003ethis._getNextId()),this.CELL_SIZE=o??this.CELL_SIZE;for(const e of t)this.addObject(e)}_idCounter=0;_getNextId(){return\"\"+this._idCounter++}addObject(t){const e=this.getBounds(t),n=this.getId(t),o={...t,spatialIndexId:n};this.objectsById.set(n,o);const i=Math.floor(e.minX/this.CELL_SIZE),r=Math.floor(e.minY/this.CELL_SIZE),s=Math.floor(e.maxX/this.CELL_SIZE),a=Math.floor(e.maxY/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const n=`${t}x${e}`,i=this.buckets.get(n);i?i.push(o):this.buckets.set(n,[o])}}removeObject(t){const e=this.objectsById.get(t);if(!e)return!1;this.objectsById.delete(t);const n=this.getBounds(e),o=Math.floor(n.minX/this.CELL_SIZE),i=Math.floor(n.minY/this.CELL_SIZE),r=Math.floor(n.maxX/this.CELL_SIZE),s=Math.floor(n.maxY/this.CELL_SIZE);for(let e=o;e\u003c=r;e++)for(let n=i;n\u003c=s;n++){const o=`${e}x${n}`,i=this.buckets.get(o);if(i){const e=i.findIndex(e=\u003ee.spatialIndexId===t);-1!==e\u0026\u0026(i.splice(e,1),0===i.length\u0026\u0026this.buckets.delete(o))}}return!0}getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getObjectsInBounds(t,e=0){const n=[],o=new Set,i=Math.floor((t.minX-e)/this.CELL_SIZE),r=Math.floor((t.minY-e)/this.CELL_SIZE),s=Math.floor((t.maxX+e)/this.CELL_SIZE),a=Math.floor((t.maxY+e)/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const i=`${t}x${e}`,r=this.buckets.get(i)||[];for(const t of r){const e=t.spatialIndexId;o.has(e)||(o.add(e),n.push(t))}}return n}},BO=.1,jO=.1,$O=BO,YO=BO,XO=.005;function VO(t){return\"pcb_trace_segment\"===t.type||\"pcb_smtpad\"===t.type?[t.layer]:\"pcb_plated_hole\"===t.type?Array.isArray(t.layers)?t.layers:[...uw]:\"pcb_hole\"===t.type?[...uw]:\"pcb_via\"===t.type?Array.isArray(t.layers)?t.layers:[...uw]:\"pcb_keepout\"===t.type\u0026\u0026Array.isArray(t.layers)?t.layers:[]}var WO=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=e.minX,r=e.minY,s=e.maxX,a=e.maxY;if(n.x===o.x\u0026\u0026n.y===o.y){const t=Math.max(i,Math.min(s,n.x)),e=Math.max(r,Math.min(a,n.y));return t===n.x\u0026\u0026e===n.y?{x:n.x,y:n.y}:{x:t,y:e}}const c=o.x-n.x,l=o.y-n.y,d=0!==c?(i-n.x)/c:Number.NEGATIVE_INFINITY,h=0!==c?(s-n.x)/c:Number.POSITIVE_INFINITY,u=0!==l?(r-n.y)/l:Number.NEGATIVE_INFINITY,p=0!==l?(a-n.y)/l:Number.POSITIVE_INFINITY,m=Math.max(Math.min(d,h),Math.min(u,p)),g=Math.min(Math.max(d,h),Math.max(u,p));if(m\u003c=g\u0026\u0026g\u003e=0\u0026\u0026m\u003c=1){const t=Math.max(0,Math.min(1,m));return{x:n.x+t*c,y:n.y+t*l}}const f={x:Math.max(i,Math.min(s,n.x)),y:Math.max(r,Math.min(a,n.y))},y={x:Math.max(i,Math.min(s,o.x)),y:Math.max(r,Math.min(a,o.y))},_=(f.x-n.x)**2+(f.y-n.y)**2,b=(y.x-o.x)**2+(y.y-o.y)**2,x=[{start:{x:i,y:r},end:{x:s,y:r}},{start:{x:s,y:r},end:{x:s,y:a}},{start:{x:s,y:a},end:{x:i,y:a}},{start:{x:i,y:a},end:{x:i,y:r}}];let v=Math.min(_,b),S=_\u003c=b?f:y;const I=(t,e,n)=\u003eMath.max(e,Math.min(n,t));for(const t of x){const e={x:o.x-n.x,y:o.y-n.y},i={x:t.end.x-t.start.x,y:t.end.y-t.start.y},r={x:n.x-t.start.x,y:n.y-t.start.y},s=e.x*e.x+e.y*e.y,a=e.x*i.x+e.y*i.y,c=e.x*r.x+e.y*r.y,l=i.x*i.x+i.y*i.y,d=i.x*r.x+i.y*r.y,h=s*l-a*a;if(Math.abs(h)\u003c1e-10)continue;let u=(a*d-l*c)/h,p=(s*d-a*c)/h;u=I(u,0,1),p=I(p,0,1);const m={x:n.x+u*e.x,y:n.y+u*e.y},g={x:t.start.x+p*i.x,y:t.start.y+p*i.y},f=m.x-g.x,y=m.y-g.y,_=f*f+y*y;_\u003cv\u0026\u0026(v=_,S={x:(m.x+g.x)/2,y:(m.y+g.y)/2})}return S},HO=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i={x:e.x1,y:e.y1},r={x:e.x2,y:e.y2},s={x:o.x-n.x,y:o.y-n.y},a={x:r.x-i.x,y:r.y-i.y},c=s.x*s.x+s.y*s.y,l=a.x*a.x+a.y*a.y;if(0===c||0===l){if(0===c\u0026\u00260===l)return{x:(n.x+i.x)/2,y:(n.y+i.y)/2};if(0===c){const t=UO(((n.x-i.x)*a.x+(n.y-i.y)*a.y)/l,0,1),e={x:i.x+t*a.x,y:i.y+t*a.y};return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}}const t=UO(((i.x-n.x)*s.x+(i.y-n.y)*s.y)/c,0,1),e={x:n.x+t*s.x,y:n.y+t*s.y};return{x:(e.x+i.x)/2,y:(e.y+i.y)/2}}const d=n.x-i.x,h=n.y-i.y,u=s.x*s.x+s.y*s.y,p=s.x*a.x+s.y*a.y,m=s.x*d+s.y*h,g=a.x*a.x+a.y*a.y,f=a.x*d+a.y*h,y=u*g-p*p;if(y\u003c1e-10)return GO(n,o,i,r,s,a,c,l);let _=(p*f-g*m)/y,b=(u*f-p*m)/y;_=UO(_,0,1),b=UO(b,0,1),b=(_*p+f)/g,b=UO(b,0,1),_=(b*p-m)/u,_=UO(_,0,1);const x=n.x+_*s.x,v=n.y+_*s.y,S=i.x+b*a.x,I=i.y+b*a.y,C=x-S,P=v-I;Math.sqrt(C*C+P*P);return{x:(x+S)/2,y:(v+I)/2}},GO=(t,e,n,o,i,r,s,a)=\u003e{let c=((n.x-t.x)*i.x+(n.y-t.y)*i.y)/s;c=UO(c,0,1);const l={x:t.x+c*i.x,y:t.y+c*i.y};let d=((o.x-t.x)*i.x+(o.y-t.y)*i.y)/s;d=UO(d,0,1);const h={x:t.x+d*i.x,y:t.y+d*i.y};let u=((t.x-n.x)*r.x+(t.y-n.y)*r.y)/a;u=UO(u,0,1);const p={x:n.x+u*r.x,y:n.y+u*r.y};let m=((e.x-n.x)*r.x+(e.y-n.y)*r.y)/a;m=UO(m,0,1);const g={x:n.x+m*r.x,y:n.y+m*r.y},f=[{pointA:l,pointB:n,distance:Math.sqrt((l.x-n.x)**2+(l.y-n.y)**2)},{pointA:h,pointB:o,distance:Math.sqrt((h.x-o.x)**2+(h.y-o.y)**2)},{pointA:t,pointB:p,distance:Math.sqrt((t.x-p.x)**2+(t.y-p.y)**2)},{pointA:e,pointB:g,distance:Math.sqrt((e.x-g.x)**2+(e.y-g.y)**2)}].reduce((t,e)=\u003ee.distance\u003ct.distance?e:t);return{x:(f.pointA.x+f.pointB.x)/2,y:(f.pointA.y+f.pointB.y)/2}},UO=(t,e,n)=\u003eMath.max(e,Math.min(n,t)),ZO=t=\u003e\"pcb_trace_segment\"===t.type?{minX:Math.min(t.x1,t.x2),minY:Math.min(t.y1,t.y2),maxX:Math.max(t.x1,t.x2),maxY:Math.max(t.y1,t.y2)}:EM([t]);function qO(t){const e=new Set;for(const n of t.route)\"wire\"===n.route_type\u0026\u0026(n.start_pcb_port_id\u0026\u0026e.add(n.start_pcb_port_id),n.end_pcb_port_id\u0026\u0026e.add(n.end_pcb_port_id));return Array.from(e)}function JO(t){const e=new Set;for(const n of t)for(const t of qO(n))e.add(t);return Array.from(e)}var KO=t=\u003e{if(\"pcb_via\"===t.type)return t.outer_diameter/2;if(\"pcb_plated_hole\"===t.type\u0026\u0026\"circle\"===t.shape)return t.outer_diameter/2;if(\"pcb_hole\"===t.type\u0026\u0026\"circle\"===t.hole_shape)return t.hole_diameter/2;if(\"pcb_smtpad\"===t.type\u0026\u0026\"circle\"===t.shape)return t.radius;throw new Error(`Could not determine radius of element: ${JSON.stringify(t)}`)};function QO(t,{connMap:e,minClearance:n=.1}={}){const o=[];(t=\u003e{const e=t.filter(t=\u003e\"pcb_port\"===t.type),n=t.filter(t=\u003e\"pcb_smtpad\"===t.type),o=t.filter(t=\u003e\"pcb_trace\"===t.type);function i(t,o={}){const i=o.traceWidth||0,r=e.find(e=\u003ezO(e.x,e.y,t.x,t.y)\u003c.01);if(r)return r.pcb_port_id;if(o.isFirstOrLastPoint){const e=n.find(e=\u003e\"rect\"===e.shape?Math.abs(t.x-e.x)\u003ce.width/2+i/2\u0026\u0026Math.abs(t.y-e.y)\u003ce.height/2+i/2:\"circle\"===e.shape?zO(t.x,t.y,e.x,e.y)\u003ce.radius:void 0);if(e)return e.pcb_port_id??null}return null}for(const t of o)for(let e=0;e\u003ct.route.length;e++){const n=t.route[e],o=0===e||e===t.route.length-1;if(\"wire\"===n.route_type){if(!n.start_pcb_port_id\u0026\u00260===e){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.start_pcb_port_id=t)}if(!n.end_pcb_port_id\u0026\u0026e===t.route.length-1){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.end_pcb_port_id=t)}}}})(t),e??=v_(t);const i=vM(t).pcb_trace.list().flatMap(t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];\"wire\"===o.route_type\u0026\u0026(\"wire\"===i.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({type:\"pcb_trace_segment\",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:\"width\"in o?o.width:\"width\"in i?i.width:jO,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),r=vM(t).pcb_smtpad.list(),s=vM(t).pcb_plated_hole.list(),a=vM(t).pcb_hole.list(),c=vM(t).pcb_via.list(),l=vM(t).pcb_keepout.list(),d=[...i,...r,...s,...a,...c,...l],h=new FO({objects:d,getBounds:ZO}),u=e=\u003eNM(t,e),p=(t,e,n)=\u003en\u003c0?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,m=new Set;for(const t of i){const i=n,r=ZO(t),s=h.getObjectsInBounds(r,i+t.thickness/2);if(t.x1!==t.x2||t.y1!==t.y2)for(const r of s){if(!VO(r).includes(t.layer))continue;if(\"pcb_trace_segment\"===r.type){const i=r;if(t.layer!==i.layer)continue;if(e.areIdsConnected(t.pcb_trace_id,i.pcb_trace_id))continue;const s=Oe({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:i.x1,y:i.y1},{x:i.x2,y:i.y2})-t.thickness/2-i.thickness/2;if(s\u003en-XO)continue;const a=`overlap_${t.pcb_trace_id}_${i.pcb_trace_id}`,c=`overlap_${i.pcb_trace_id}_${t.pcb_trace_id}`;if(m.has(a))continue;if(m.has(c))continue;m.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:p(u(t.pcb_trace_id),u(i.pcb_trace_id),s),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[],center:HO(t,i),pcb_port_ids:JO([t._pcbTrace,i._pcbTrace])});continue}const s=AM(r);if(e.areIdsConnected(t.pcb_trace_id,\"pcb_trace_id\"in r?r.pcb_trace_id:s))continue;if(\"pcb_via\"===r.type||\"pcb_plated_hole\"===r.type\u0026\u0026\"circle\"===r.shape||\"pcb_hole\"===r.type||\"pcb_smtpad\"===r.type\u0026\u0026\"circle\"===r.shape){const e=KO(r),i=De({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:r.x,y:r.y,radius:e})-t.thickness/2;if(i\u003en-XO)continue;const a=`overlap_${t.pcb_trace_id}_${s}`;if(m.has(a))continue;m.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:p(u(t.pcb_trace_id),`${r.type} \"${u(AM(r))}\"`,i),pcb_trace_id:t.pcb_trace_id,center:WO(t,ZO(r)),source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...JO([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}const a=ke({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},ZO(r))-t.thickness/2;if(a+XO\u003ci){const e=`overlap_${t.pcb_trace_id}_${s}`;if(m.has(e))continue;m.add(e),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:p(u(t.pcb_trace_id),`${r.type} \"${u(AM(r))}\"`,a),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:e,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),center:WO(t,ZO(r)),pcb_port_ids:[...JO([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}}}return o}function tk(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function ek(t,e){return tk(t,e)\u003c=XO}function nk(t,{connMap:e,minClearance:n=$O}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];e??=v_(t);const i=[],r=new Set;for(let s=0;s\u003co.length;s++)for(let a=s+1;a\u003co.length;a++){const c=o[s],l=o[a];if(ek(c,l))continue;if(!e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=tk(c,l)-c.outer_diameter/2-l.outer_diameter/2;if(d+XO\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");r.has(h)||(r.add(h),i.push({type:\"pcb_via_clearance_error\",pcb_error_id:`same_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return i}function ok(t,{connMap:e,minClearance:n=YO}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];e??=v_(t);const i=[],r=new Set;for(let s=0;s\u003co.length;s++)for(let a=s+1;a\u003co.length;a++){const c=o[s],l=o[a];if(ek(c,l))continue;if(e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=tk(c,l)-c.outer_diameter/2-l.outer_diameter/2;if(d+XO\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");r.has(h)||(r.add(h),i.push({type:\"pcb_via_clearance_error\",pcb_error_id:`different_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} from different nets are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return i}var ik=t=\u003e({minSpacing:t,minClearance:t}),rk={traceClearance:.1,viaClearance:.1},sk=t=\u003e(t=\u003e\"layer\"in t)(t)?[t.layer]:t.layers;function ak(t,e,n){let o,i=Number.POSITIVE_INFINITY;for(const r of e){const e=n.get(r);if(!e)continue;const s=Math.hypot(e.x-t.x,e.y-t.y);s\u003ci\u0026\u0026(i=s,o=r)}return o??e[0]}function ck(t){const e=[],n=new Set,o=new Set,i=function(t){const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{x:t.x,y:t.y});return e}(t);for(const r of t.obstacles){const t=r.connectedTo,s=t.find(t=\u003et.startsWith(\"pcb_smtpad_\")),a=t.find(t=\u003et.startsWith(\"pcb_plated_hole_\")),c=t.filter(t=\u003et.startsWith(\"pcb_port_\")),l=ak(r.center,c,i);if(!s\u0026\u0026!a\u0026\u0026!l)continue;const d=r.layers;if(0===d.length)continue;const h=r.width,u=r.height,p=r.center.x,m=r.center.y,g=r.ccwRotationDegrees,f=\"number\"==typeof g\u0026\u0026Number.isFinite(g);if(d.length\u003e1){const t=a??`pcb_plated_hole_${p.toFixed(3)}_${m.toFixed(3)}`;if(o.has(t))continue;if(o.add(t),f){const n=Math.max(.5*Math.min(h,u),.1);e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"rotated_pill_hole_with_rect_pad\",hole_shape:\"rotated_pill\",pad_shape:\"rect\",hole_width:n,hole_height:n,hole_ccw_rotation:g,rect_pad_width:h,rect_pad_height:u,rect_ccw_rotation:g,hole_offset_x:0,hole_offset_y:0,x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}if(Math.abs(h-u)\u003c.001){e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circle\",outer_diameter:Math.max(h,u),hole_diameter:Math.max(.5*Math.min(h,u),.1),x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circular_hole_with_rect_pad\",hole_shape:\"circle\",hole_diameter:Math.max(.5*Math.min(h,u),.1),rect_pad_width:h,rect_pad_height:u,hole_offset_x:0,hole_offset_y:0,x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}const y=s??`pcb_smtpad_${p.toFixed(3)}_${m.toFixed(3)}`;n.has(y)||(n.add(y),f?e.push({type:\"pcb_smtpad\",pcb_smtpad_id:y,layer:d[0],shape:\"rotated_rect\",x:p,y:m,width:h,height:u,ccw_rotation:g,...l?{pcb_port_id:l}:{}}):e.push({type:\"pcb_smtpad\",pcb_smtpad_id:y,layer:d[0],shape:\"rect\",width:h,height:u,x:p,y:m,...l?{pcb_port_id:l}:{}}))}return e}function lk(t,e,n=.1,o=t.minViaDiameter??.3){const i=[];i.push(...function(t,e){const n=[];return t.connections.forEach(o=\u003e{const i=o.pointsToConnect.filter(t=\u003et.pcb_port_id).map(t=\u003et.pcb_port_id).filter(Boolean),r=o.netConnectionName||o.rootConnectionName||o.name,s=[],a=e.find(t=\u003e(t.connection_name??t.connectionName)===o.name);if(a){const e=t=\u003e\"route_type\"in t\u0026\u0026\"jumper\"===t.route_type?t.start:\"x\"in t\u0026\u0026\"y\"in t?{x:t.x,y:t.y}:{x:0,y:0},n=[e(a.route[0]),e(a.route[a.route.length-1])];for(const e of n)for(const n of t.obstacles)Be(e,n)\u003c=0\u0026\u0026s.push(n)}const c=n.find(t=\u003e\"source_trace\"===t.type\u0026\u0026t.source_trace_id===r);if(c){const t=c;t.connected_source_port_ids=[...new Set([...t.connected_source_port_ids,...i])]}else n.push({type:\"source_trace\",source_trace_id:r,connected_source_port_ids:i.concat(s.flatMap(t=\u003e[`obstacle_${t.center.x.toFixed(3)}_${t.center.y.toFixed(3)}_${t.layers.join(\".\")}`,...t.connectedTo])),connected_source_net_ids:[]})}),n}(t,e)),i.push(...function(t){const e=new Map;return t.connections.forEach(t=\u003e{t.pointsToConnect.forEach(t=\u003e{t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{type:\"pcb_port\",pcb_port_id:t.pcb_port_id,source_port_id:t.pcb_port_id,x:t.x,y:t.y,layers:sk(t)})})}),Array.from(e.values())}(t)),i.push(...ck(t)),i.push(...function(t,e,n=.3){const o=[],i=new Set;return t.length\u003e0\u0026\u0026(\"type\"in t[0]\u0026\u0026\"pcb_trace\"===t[0].type?t.forEach(t=\u003e{t.route.forEach(r=\u003e{if(\"via\"===r.route_type){const s=r.via_diameter??n,a=`${r.x},${r.y},${r.from_layer},${r.to_layer}`;i.has(a)||(o.push({type:\"pcb_via\",pcb_via_id:`via_${o.length}`,pcb_trace_id:t.pcb_trace_id,x:r.x,y:r.y,outer_diameter:s,hole_diameter:.5*s,layers:Wy(r,e)}),i.add(a))}})}):t.forEach((t,r)=\u003e{const s=`trace_${r}`,a=t.viaDiameter??n;for(let n=1;n\u003ct.route.length;n++){const r=t.route[n-1],c=t.route[n];if(r.z!==c.z\u0026\u0026Math.abs(r.x-c.x)\u003c.01\u0026\u0026Math.abs(r.y-c.y)\u003c.01){const t=Vy(r.z,e),n=Vy(c.z,e),l=`${c.x},${c.y},${t},${n}`;i.has(l)||(o.push({type:\"pcb_via\",pcb_via_id:`via_${o.length}`,pcb_trace_id:s,x:c.x,y:c.y,outer_diameter:a,hole_diameter:.5*a,layers:Wy({from_layer:t,to_layer:n},e)}),i.add(l))}}})),o}(e,t.layerCount,o));const r=new Map;return t.connections.forEach(t=\u003e{r.set(t.name,t.netConnectionName||t.rootConnectionName||t.name)}),e.length\u003e0\u0026\u0026(\"type\"in e[0]\u0026\u0026\"pcb_trace\"===e[0].type?e.forEach(t=\u003e{const e=t.connection_name;i.push(function(t,e){return{type:\"pcb_trace\",pcb_trace_id:t.pcb_trace_id,source_trace_id:e,route:t.route.map(t=\u003e\"wire\"===t.route_type?{route_type:\"wire\",x:t.x,y:t.y,width:t.width,layer:t.layer,start_pcb_port_id:t.start_pcb_port_id,end_pcb_port_id:t.end_pcb_port_id}:\"via\"===t.route_type?{route_type:\"via\",x:t.x,y:t.y,from_layer:t.from_layer,to_layer:t.to_layer}:null).filter(t=\u003enull!==t)}}(t,r.get(e)||e))}):e.forEach((e,o)=\u003e{const s=e.connectionName,a=function(t,e,n,o=.1,i){const r=[];if(!t.jumpers||0===t.jumpers.length)return[{type:\"pcb_trace\",pcb_trace_id:e,source_trace_id:n,route:t.route.map((e,n)=\u003e{const r=0===n,s=n===t.route.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:o,layer:Vy(e.z,i),...r\u0026\u0026e.pcb_port_id?{start_pcb_port_id:e.pcb_port_id}:{},...s\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})}];const s=[];for(const e of t.jumpers){let n=-1,o=-1;for(let i=0;i\u003ct.route.length;i++){const r=t.route[i];Math.abs(r.x-e.start.x)\u003c.01\u0026\u0026Math.abs(r.y-e.start.y)\u003c.01\u0026\u0026(n=i),Math.abs(r.x-e.end.x)\u003c.01\u0026\u0026Math.abs(r.y-e.end.y)\u003c.01\u0026\u0026(o=i)}-1!==n\u0026\u0026-1!==o\u0026\u0026(n\u003eo\u0026\u0026([n,o]=[o,n]),s.push({startIdx:n,endIdx:o}))}s.sort((t,e)=\u003et.startIdx-e.startIdx);let a=0,c=0;for(const{startIdx:l,endIdx:d}of s){if(l\u003e=a){const s=t.route.slice(a,l+1);s.length\u003e0\u0026\u0026(r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((t,e)=\u003e{const n=0===e\u0026\u00260===a;return{route_type:\"wire\",x:t.x,y:t.y,width:o,layer:Vy(t.z,i),...n\u0026\u0026t.pcb_port_id?{start_pcb_port_id:t.pcb_port_id}:{}}})}),c++)}a=d}if(a\u003ct.route.length){const s=t.route.slice(a);if(s.length\u003e0){const t=!0;r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((e,n)=\u003e{const r=t\u0026\u0026n===s.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:o,layer:Vy(e.z,i),...r\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})})}}return r}(e,`trace_${o}`,r.get(s)||s,n,t.layerCount);i.push(...a)})),i}var dk=t=\u003et.rootConnectionName??t.connectionName,hk=(t,e)=\u003e{if(t\u0026\u0026e)return t.getNetConnectedToId(e)},uk=(t,e,n)=\u003e{if(!e)return!1;if(t===e)return!0;if(n?.areIdsConnected(t,e))return!0;const o=hk(n,t),i=hk(n,e);return!(!o||o!==e\u0026\u0026o!==i)||!(!i||i!==t\u0026\u0026i!==o)},pk=(t,e,n)=\u003ee.connectedTo?.some(e=\u003euk(t,e,n))??!1,mk=(t,e,n)=\u003eMath.max(e,Math.min(t,n)),gk=(t,e)=\u003e{t.x=mk(t.x,e.minX,e.maxX),t.y=mk(t.y,e.minY,e.maxY)},fk=(t,e)=\u003e({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),yk=(t,e)=\u003e({minCellX:Math.floor(t.minX/e),maxCellX:Math.floor(t.maxX/e),minCellY:Math.floor(t.minY/e),maxCellY:Math.floor(t.maxY/e)}),_k=(t,e)=\u003e`${t}:${e}`,bk=(t,e,n)=\u003e{const o=new Map;for(let i=0;i\u003ct.length;i+=1){const r=t[i];if(!r)continue;const s=yk(e(r),n);for(let t=s.minCellX;t\u003c=s.maxCellX;t+=1)for(let e=s.minCellY;e\u003c=s.maxCellY;e+=1){const n=_k(t,e),r=o.get(n);r?r.push(i):o.set(n,[i])}}return o},xk=(t,e,n)=\u003e{const o=new Set,i=yk(e,n);for(let e=i.minCellX;e\u003c=i.maxCellX;e+=1)for(let n=i.minCellY;n\u003c=i.maxCellY;n+=1){const i=t.get(_k(e,n));if(i)for(const t of i)o.add(t)}return[...o].sort((t,e)=\u003et-e)},vk=1e-6,Sk=(t,e,n)=\u003e{if(0===t.length)return[];const o=n?.traceThickness??.1,i=t[0],r=t.at(-1),s=t=\u003e{if(t.pcb_port_id)return t.pcb_port_id;const o=Vy(t.z,e);return n?.connectionPoints?.find(e=\u003e{return e.pcb_port_id\u0026\u0026(n=e,i=t,Math.abs(n.x-i.x)\u003c=vk\u0026\u0026Math.abs(n.y-i.y)\u003c=vk)\u0026\u0026sk(e).includes(o);var n,i})?.pcb_port_id},a=s(i),c=s(r),l=[{route_type:\"wire\",x:i.x,y:i.y,width:o,layer:Vy(i.z,e),...a?{start_pcb_port_id:a}:{},...1===t.length\u0026\u0026c?{end_pcb_port_id:c}:{}}];for(let i=1;i\u003ct.length;i+=1){const r=t[i-1],s=t[i];r\u0026\u0026s\u0026\u0026(r.z!==s.z\u0026\u0026r.x===s.x\u0026\u0026r.y===s.y\u0026\u0026l.push({route_type:\"via\",x:s.x,y:s.y,from_layer:Vy(r.z,e),to_layer:Vy(s.z,e),...n?.viaDiameter?{via_diameter:n.viaDiameter}:{}}),l.push({route_type:\"wire\",x:s.x,y:s.y,width:o,layer:Vy(s.z,e),...i===t.length-1\u0026\u0026c?{end_pcb_port_id:c}:{}}))}return l},Ik=(t,e)=\u003e({x:Ae(t.x,e.minX,e.maxX),y:Ae(t.y,e.minY,e.maxY)}),Ck=(t,e)=\u003e{const n=t.x-e.center.x,o=t.y-e.center.y;return e.circular?Math.max(0,Math.hypot(n,o)-e.halfWidth):je(R(e.worldToLocal,t),{minX:-e.halfWidth,maxX:e.halfWidth,minY:-e.halfHeight,maxY:e.halfHeight})},Pk=(t,e)=\u003e({kind:\"line\",start:t,end:e,bounds:We([t,e])}),Mk=(t,e)=\u003e({kind:\"circle\",center:t,radius:e,bounds:Ve({center:t,width:2*e,height:2*e})}),Nk=t=\u003e{const e=t.clearance+h_;if(t.circular)return[Mk(t.center,t.halfWidth+e)];const n=(e,n)=\u003eR(t.localToWorld,{x:e,y:n}),{halfWidth:o,halfHeight:i}=t;return[Pk(n(-o,-i-e),n(o,-i-e)),Pk(n(o+e,-i),n(o+e,i)),Pk(n(o,i+e),n(-o,i+e)),Pk(n(-o-e,i),n(-o-e,-i)),Mk(n(-o,-i),e),Mk(n(o,-i),e),Mk(n(o,i),e),Mk(n(-o,i),e)]},wk=(t,e)=\u003e{if(\"circle\"===e.kind){const n=t.x-e.center.x,o=t.y-e.center.y,i=Math.hypot(n,o);return 0===i?[{x:e.center.x+e.radius,y:e.center.y},{x:e.center.x-e.radius,y:e.center.y},{x:e.center.x,y:e.center.y+e.radius},{x:e.center.x,y:e.center.y-e.radius}]:[{x:e.center.x+n*e.radius/i,y:e.center.y+o*e.radius/i}]}return[e.start,e.end,ze(t,e.start,e.end)]},Tk=(t,e)=\u003e{const n=t.end.x-t.start.x,o=t.end.y-t.start.y,i=t.start.x-e.center.x,r=t.start.y-e.center.y,s=n*n+o*o;if(0===s)return[];const a=2*(i*n+r*o),c=a*a-4*s*(i*i+r*r-e.radius*e.radius);if(c\u003c0)return[];const l=Math.sqrt(c);return[(-a-l)/(2*s),(-a+l)/(2*s)].filter(t=\u003et\u003e=0\u0026\u0026t\u003c=1).map(e=\u003e({x:t.start.x+n*e,y:t.start.y+o*e}))},Rk=(t,e)=\u003e{if(\"line\"===t.kind\u0026\u0026\"circle\"===e.kind)return Tk(t,e);if(\"circle\"===t.kind\u0026\u0026\"line\"===e.kind)return Tk(e,t);if(\"line\"===t.kind\u0026\u0026\"line\"===e.kind){const n=ve(t.start,t.end,e.start,e.end);return n?[n]:[]}if(\"circle\"!==t.kind||\"circle\"!==e.kind)return[];const n=e.center.x-t.center.x,o=e.center.y-t.center.y,i=Math.hypot(n,o);if(0===i||i\u003et.radius+e.radius||i\u003cMath.abs(t.radius-e.radius))return[];const r=(t.radius**2-e.radius**2+i**2)/(2*i),s=Math.sqrt(Math.max(0,t.radius**2-r**2)),a=t.center.x+n*r/i,c=t.center.y+o*r/i;return[{x:a-o*s/i,y:c+n*s/i},{x:a+o*s/i,y:c-n*s/i}]},Ek=(t,e,n,o,i)=\u003e{const r=new Set(function(t,e,n=1){if(0===n)throw new Error(\"step cannot be 0\");let o,i;void 0===e?(o=0,i=t):(o=t,i=e);const r=[];if(n\u003e0)for(let t=o;t\u003ci;t+=n)r.push(t);else for(let t=o;t\u003ei;t+=n)r.push(t);return r}(Math.min(...o),Math.max(...o)+1).map(e=\u003eVy(e,t.layerCount)));return t.obstacles.filter(t=\u003e!t.isCopperPour\u0026\u0026t.layers.some(t=\u003er.has(t))).map(o=\u003e{const r=\"number\"==typeof o.ccwRotationDegrees\u0026\u0026Number.isFinite(o.ccwRotationDegrees),s=!r\u0026\u0026o.layers.length\u003e1\u0026\u0026Math.abs(o.width-o.height)\u003c.001,a=D(k(o.center.x,o.center.y),j(r?o.ccwRotationDegrees:0)),c=s?Math.max(o.width,o.height)/2:o.width/2,l=s?c:o.height/2,d=pk(dk(e),o,i)||pk(e.connectionName,o,i),h=n+(d?0:y_(t)),u=We(E(a,[{x:-c,y:-l},{x:c,y:-l},{x:c,y:l},{x:-c,y:l}])),p=h+h_;return{center:o.center,halfWidth:c,halfHeight:l,localToWorld:a,worldToLocal:A(a),circular:s,clearance:h,bounds:{minX:u.minX-p,maxX:u.maxX+p,minY:u.minY-p,maxY:u.maxY+p}}})},Ak=(t,e,n,o)=\u003e{const i=Math.min(...t.zLayers),r=Math.max(...t.zLayers),s=e.filter(e=\u003ee.z\u003e=i\u0026\u0026e.z\u003c=r\u0026\u0026!uk(t.rootConnectionName,e.rootConnectionName,o)).map(e=\u003e({segment:e,required:t.radius+e.radius+n})).filter(({segment:e,required:n})=\u003ebe(t,e.start,e.end)\u003c=n+p_),a=s.flatMap(({segment:t,required:e})=\u003e{const{start:n,end:o}=t,i=Math.sqrt(Ye(n,o));if(i\u003c=h_)return[];const r=e+h_,s=(o.y-n.y)/i*r,a=(n.x-o.x)/i*r;return[Pk({x:n.x+s,y:n.y+a},{x:o.x+s,y:o.y+a}),Pk({x:n.x-s,y:n.y-a},{x:o.x-s,y:o.y-a}),Mk(n,r),Mk(o,r)]}).filter(e=\u003eje(t,e.bounds)\u003c=p_),c=[],l=e=\u003e{Ye(e,t)\u003ep_**2||c.some(t=\u003eYe(t,e)\u003c1e-12)||s.some(({segment:t,required:n})=\u003ebe(e,t.start,t.end)\u003cn)||c.push(e)};l(t);for(let e=0;e\u003ca.length;e+=1){const n=a[e];for(const e of wk(t,n))l(e);for(let t=e+1;t\u003ca.length;t+=1){const e=a[t];if(Xe(n.bounds,e.bounds))for(const t of Rk(n,e))l(t)}}return c.sort((e,n)=\u003eYe(e,t)-Ye(n,t))},Ok=t=\u003e({...t,route:t.route.map(t=\u003e({...t})),vias:t.vias.map(t=\u003e({...t}))}),kk=t=\u003et.map(Ok),Lk=(t,e)=\u003e{const n=new Set(e);return t.map((t,e)=\u003en.has(e)?Ok(t):t)},Dk=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=u_\u0026\u0026Math.abs(t.y-e.y)\u003c=u_,zk=[\"pcb_smtpad\",\"pcb_plated_hole\",\"pcb_hole\",\"pcb_keepout\"],Fk=t=\u003e\"string\"==typeof t.type?t.type:\"string\"==typeof t.error_type?t.error_type:void 0,Bk=t=\u003e{if(\"pcb_pad_trace_clearance_error\"===Fk(t))return!0;const e=\"string\"==typeof t.message?t.message.toLowerCase():\"\";return(e.includes(\"pcb_trace\")||e.includes(\"pcb trace\"))\u0026\u0026zk.some(t=\u003ee.includes(t))},jk=t=\u003e{const e=\"string\"==typeof t.message?t.message:\"\",n=e.match(/gap: (-?\\d+(?:\\.\\d+)?)mm/),o=e.match(/required: (-?\\d+(?:\\.\\d+)?)mm/);if(n\u0026\u0026o){const t=Number.parseFloat(n[1]),e=Number.parseFloat(o[1]);if(Number.isFinite(t)\u0026\u0026Number.isFinite(e))return Math.max(0,e-t)}if(n){const t=Number.parseFloat(n[1]),e=rk.traceClearance??.1;if(Number.isFinite(t))return Math.max(0,e-t)}return 1},$k={projectEngineError:t=\u003e({...t,center:\"object\"==typeof t.first_contact_center?t.first_contact_center:t.center,message:\"string\"==typeof t.first_contact_message?t.first_contact_message:t.message,actual_clearance:\"number\"==typeof t.first_actual_clearance?t.first_actual_clearance:t.actual_clearance}),getErrorSeverity:jk},Yk={projectEngineError:t=\u003et,getErrorSeverity:t=\u003e{const e=Number(t.minimum_clearance),n=Number(t.worst_actual_clearance);return Number.isFinite(e)\u0026\u0026Number.isFinite(n)?Math.max(0,e-n):jk(t)}},Xk=(t,e=jk)=\u003et.reduce((t,n)=\u003et+e(n),0),Vk=(t,e,n,o,i,r=$k)=\u003e{const s=i\u0026\u0026!n?t:((t,e)=\u003ee?{...t,connections:t.connections.map(t=\u003e{const n=hk(e,t.name)??hk(e,t.rootConnectionName)??t.netConnectionName;return n?{...t,netConnectionName:n}:t}),obstacles:t.obstacles.map(t=\u003e{const n=new Set(t.connectedTo);for(const o of t.connectedTo){const t=hk(e,o);t\u0026\u0026n.add(t)}return{...t,connectedTo:[...n]}})}:t)(t,o),{traces:a,traceRouteIndexById:c}=((t,e)=\u003e{const n=[],o=new Map,i=new Map;for(let t=0;t\u003ce.length;t+=1){const n=e[t];if(!n)continue;const o=i.get(n.connectionName);o?o.push({route:n,routeIndex:t}):i.set(n.connectionName,[{route:n,routeIndex:t}])}for(const e of t.connections){const r=i.get(e.name)??[];for(let i=0;i\u003cr.length;i+=1){const s=r[i];if(!s)continue;const a=`${e.name}_${i}`;n.push({type:\"pcb_trace\",pcb_trace_id:a,connection_name:e.netConnectionName??e.rootConnectionName??e.name,route:Sk(s.route.route,t.layerCount,{traceThickness:s.route.traceThickness??e.nominalTraceWidth??t.nominalTraceWidth??t.minTraceWidth,viaDiameter:s.route.viaDiameter??t.minViaDiameter,connectionPoints:e.pointsToConnect})}),o.set(a,s.routeIndex)}}return{traces:n,traceRouteIndexById:o}})(s,e),l=n?.({srj:s,routes:e,traces:a});if(l){const t=Array.isArray(l)?l:l.errors,e=Array.isArray(l)?l:l.errorsWithCenters??l.errors;return{errors:e,count:t.length,issueScore:Xk(e,r.getErrorSeverity),legacyIssueScore:Xk(e.filter(t=\u003e!uD(t)),r.getErrorSeverity),traceRouteIndexById:c}}const d=i?.evaluate(a)??((t,e={})=\u003e{const n=Math.max(e.viaClearance??.1,.1),o=[...QO(t,ik(e.traceClearance)),...nk(t,ik(n)),...ok(t,ik(n))],i=t.filter(t=\u003e\"pcb_via\"===t.type),r=new Map(i.map(t=\u003e[t.pcb_via_id,t])),s=o.map(t=\u003e{if(\"center\"in t\u0026\u0026t.center)return t;if(\"pcb_center\"in t\u0026\u0026t.pcb_center)return{...t,center:t.pcb_center};if(\"pcb_via_ids\"in t\u0026\u0026Array.isArray(t.pcb_via_ids)){const[e,n]=t.pcb_via_ids;if(\"string\"!=typeof e||\"string\"!=typeof n)return t;const o=r.get(e),i=r.get(n);if(o\u0026\u0026i)return{...t,center:{x:(o.x+i.x)/2,y:(o.y+i.y)/2}}}if(\"pcb_error_id\"in t\u0026\u0026\"string\"==typeof t.pcb_error_id\u0026\u0026(t.pcb_error_id.startsWith(\"same_net_vias_close_\")||t.pcb_error_id.startsWith(\"different_net_vias_close_\"))){const e=t.pcb_error_id.replace(\"same_net_vias_close_\",\"\").replace(\"different_net_vias_close_\",\"\").split(\"_\").filter(Boolean);if(2===e.length){const n=e[0],o=e[1];if(!n||!o)return t;const i=r.get(n),s=r.get(o);if(i\u0026\u0026s)return{...t,center:{x:(i.x+s.x)/2,y:(i.y+s.y)/2}}}}return t}),a=s.filter(t=\u003eBoolean(t.center));return{errors:o,errorsWithCenters:s,locationAwareErrors:a}})(lk(s,a,s.minTraceWidth,s.minViaDiameter),{...rk,traceClearance:s.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:s.minTraceToPadEdgeClearance??rk.viaClearance}),h=d.errors,u=(d.errorsWithCenters.length\u003e0?d.errorsWithCenters:d.errors).map(t=\u003er.projectEngineError(t));return{errors:u,count:h.length,issueScore:Xk(u,r.getErrorSeverity),legacyIssueScore:Xk(u.filter(t=\u003e!uD(t)),r.getErrorSeverity),traceRouteIndexById:c}},Wk=(t,e,n,o,i)=\u003eVk(t,e,n,o,i,$k),Hk=(t,e,n,o,i)=\u003eVk(t,e,n,o,i,Yk),Gk=(t,e=.3)=\u003e{const n=[];for(let o=0;o\u003ct.length;o+=1){const i=t[o];if(!i)continue;const r=new Set;for(let t=0;t\u003ci.route.length-1;t+=1){const s=i.route[t],a=i.route[t+1];if(!s||!a)continue;if(s.z===a.z||!Dk(s,a))continue;const c=[t,t+1];for(let e=t-1;e\u003e=0;e-=1){const t=i.route[e];if(!t||!Dk(t,s))break;c.push(e)}for(let e=t+2;e\u003ci.route.length;e+=1){const t=i.route[e];if(!t||!Dk(t,s))break;c.push(e)}const l=[...new Set(c)];if(l.some(t=\u003er.has(t)))continue;for(const t of l)r.add(t);const d=l.filter(t=\u003e0===t||t===i.route.length-1),h=d.some(t=\u003eBoolean(i.route[t]?.pcb_port_id));n.push({routeIndex:o,rootConnectionName:dk(i),pointIndexes:l,zLayers:[...new Set(l.map(t=\u003ei.route[t].z))],x:s.x,y:s.y,radius:(i.viaDiameter??e)/2,movable:0===d.length,canCanonicalize:0===d.length||!h})}}return n},Uk=(t,e)=\u003e{const n=[];for(let o=0;o\u003ct.route.length-1;o+=1){const i=t.route[o],r=t.route[o+1];i\u0026\u0026r\u0026\u0026(i.z!==r.z||Dk(i,r)||n.push({routeIndex:e,rootConnectionName:dk(t),startIndex:o,endIndex:o+1,start:i,end:r,z:i.z,radius:(t.traceThickness??.1)/2}))}return n},Zk=t=\u003et.flatMap((t,e)=\u003eUk(t,e)),qk=t=\u003e({minX:t.x,minY:t.y,maxX:t.x,maxY:t.y}),Jk=t=\u003e({minX:Math.min(t.start.x,t.end.x),minY:Math.min(t.start.y,t.end.y),maxX:Math.max(t.start.x,t.end.x),maxY:Math.max(t.start.y,t.end.y)}),Kk=t=\u003e({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}),Qk=(t,e)=\u003e{if(t.zLayers\u0026\u0026t.zLayers.length\u003e0)return t.zLayers;const n=Array.from({length:e},(t,e)=\u003ee).filter(n=\u003et.layers.includes(Vy(n,e)));return n.length\u003e0?n:Array.from({length:e},(t,e)=\u003ee)},tL=(t,e,n)=\u003e{const o=e.reduce((t,e)=\u003eMath.max(t,e.radius),(t.minViaDiameter??.3)/2),i=n.reduce((t,e)=\u003eMath.max(t,e.radius),t.minTraceWidth/2),r=(rk.traceClearance??.1)+g_;return Math.max(2*o+.2+g_,o+i+r,2*i+r,i+f_(t)+g_,o+y_(t)+g_)},eL=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c=h_)return{x:e.x,y:e.y,t:0};const s=mk(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return{x:e.x+o*s,y:e.y+i*s,t:s}},nL=(t,e)=\u003eeL(t,e.start,e.end),oL=(t,e)=\u003e{const n=e.width/2,o=e.height/2,i=Math.max(Math.abs(t.x-e.center.x)-n,0),r=Math.max(Math.abs(t.y-e.center.y)-o,0);return Math.hypot(i,r)},iL=(t,e)=\u003et.x\u003e=e.center.x-e.width/2-u_\u0026\u0026t.x\u003c=e.center.x+e.width/2+u_\u0026\u0026t.y\u003e=e.center.y-e.height/2-u_\u0026\u0026t.y\u003c=e.center.y+e.height/2+u_,rL=(t,e,n,o)=\u003et.obstacles.find(i=\u003epk(dk(e),i,o)\u0026\u0026Qk(i,t.layerCount).includes(n.z)\u0026\u0026iL(n,i)),sL=(t,e,n=.6,o)=\u003e{let i;for(const r of t.obstacles){if(o\u0026\u0026!o(r))continue;const t=oL(e,r);t\u003en||(!i||t\u003ci.distance)\u0026\u0026(i={obstacle:r,distance:t})}return i?.obstacle},aL=(t,e,n)=\u003e{const o=e.width/2,i=e.height/2,r=mk(t.x,e.center.x-o,e.center.x+o),s=mk(t.y,e.center.y-i,e.center.y+i);let a=t.x-r,c=t.y-s,l=Math.hypot(a,c);if(l\u003c=h_){o-Math.abs(t.x-e.center.x)\u003ci-Math.abs(t.y-e.center.y)?(a=t.x\u003e=e.center.x?1:-1,c=0,l=0):(a=0,c=t.y\u003e=e.center.y?1:-1,l=0)}const d=n-l;if(d\u003c=0)return;const h=Math.hypot(a,c);return{direction:{x:h\u003eh_?a/h:1,y:h\u003eh_?c/h:0},penetration:d}},cL=(t,e,n,o)=\u003e{const i=e.message;if(\"string\"!=typeof i||!i.includes(\"pcb_\"))return n;const r=Array.isArray(e.pcb_pad_ids)?e.pcb_pad_ids.filter(t=\u003e\"string\"==typeof t):[],s=t.obstacles.find(t=\u003er.some(e=\u003et.connectedTo.includes(e))\u0026\u0026(o?.(t)??!0));return s?s.center:sL(t,n,.6,o)?.center??n},lL=(t,e)=\u003e{const n=t.route[e];if(!n)return[];const o=[e];for(let i=e-1;i\u003e=0;i-=1){const e=t.route[i];if(!e||!Dk(e,n))break;o.push(i)}for(let i=e+1;i\u003ct.route.length;i+=1){const e=t.route[i];if(!e||!Dk(e,n))break;o.push(i)}return[...new Set(o)]},dL=(t,e)=\u003e{if(e\u003c=0||e\u003e=t.route.length-1)return;const n=lL(t,e);return n.includes(0)||n.includes(t.route.length-1)?void 0:n},hL=(t,e)=\u003et.x\u003e=e.minX-u_\u0026\u0026t.x\u003c=e.maxX+u_\u0026\u0026t.y\u003e=e.minY-u_\u0026\u0026t.y\u003c=e.maxY+u_,uL=(t,e)=\u003eMath.min(t.x-e.minX,e.maxX-t.x,t.y-e.minY,e.maxY-t.y),pL=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=t.x-e.x,s=o*(t.y-e.y)-i*r;if(Math.abs(s)\u003eu_)return!1;const a=Math.min(e.x,n.x)-u_,c=Math.max(e.x,n.x)+u_,l=Math.min(e.y,n.y)-u_,d=Math.max(e.y,n.y)+u_;return t.x\u003e=a\u0026\u0026t.x\u003c=c\u0026\u0026t.y\u003e=l\u0026\u0026t.y\u003c=d},mL=(t,e)=\u003e{if(e.length\u003c3)return!0;for(let n=0;n\u003ce.length;n+=1){const o=e[n],i=e[(n+1)%e.length];if(o\u0026\u0026i\u0026\u0026pL(t,o,i))return!0}let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o,o+=1){const r=e[o],s=e[i];if(!r||!s)continue;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n},gL=(t,e)=\u003e{const n=Math.hypot(t,e);if(!(n\u003c=h_))return{x:t/n,y:e/n}},fL=(t,e)=\u003et.outline\u0026\u0026t.outline.length\u003e=3?((t,e)=\u003e{const n=mL(t,e);let o;for(let n=0;n\u003ce.length;n+=1){const i=e[n],r=e[(n+1)%e.length];if(!i||!r)continue;const s=eL(t,i,r),a=Math.hypot(t.x-s.x,t.y-s.y);(!o||a\u003co.distance)\u0026\u0026(o={projection:s,start:i,end:r,distance:a})}if(!o)return;const i=gL(n?t.x-o.projection.x:o.projection.x-t.x,n?t.y-o.projection.y:o.projection.y-t.y);if(i)return i;const r=o.end.x-o.start.x,s=o.end.y-o.start.y,a=Math.hypot(r,s);if(a\u003c=h_)return;const c=(t=\u003e{let e=0;for(let n=0;n\u003ct.length;n+=1){const o=t[n],i=t[(n+1)%t.length];o\u0026\u0026i\u0026\u0026(e+=o.x*i.y-i.x*o.y)}return e/2})(e)\u003e=0;return{x:c?-s/a:s/a,y:c?r/a:-r/a}})(e,t.outline):((t,e)=\u003e{const n=t.x-e.minX,o=e.maxX-t.x,i=t.y-e.minY,r=e.maxY-t.y,s=Math.min(n,o,i,r);let a=0,c=0;return n\u003c=s+u_\u0026\u0026(a+=1),o\u003c=s+u_\u0026\u0026(a-=1),i\u003c=s+u_\u0026\u0026(c+=1),r\u003c=s+u_\u0026\u0026(c-=1),gL(a,c)})(e,t.bounds),yL=(t,e)=\u003et.outline\u0026\u0026t.outline.length\u003e=3?mL(e,t.outline):hL(e,t.bounds),_L=(t,e)=\u003e{if(t.outline\u0026\u0026t.outline.length\u003e=3){const n=((t,e)=\u003e{let n=Number.POSITIVE_INFINITY;for(let o=0;o\u003ce.length;o+=1){const i=e[o],r=e[(o+1)%e.length];i\u0026\u0026r\u0026\u0026(n=Math.min(n,be(t,i,r)))}return n})(e,t.outline);return mL(e,t.outline)?n:-n}return uL(e,t.bounds)},bL=(t,e,n)=\u003e{if(Math.abs(e.x-n.x)\u003c=u_\u0026\u0026Math.abs(e.y-n.y)\u003c=u_)return Math.min(_L(t,e),_L(t,n));if(t.outline\u0026\u0026t.outline.length\u003e=3){if(!mL(e,t.outline)||!mL(n,t.outline))return Math.min(_L(t,e),_L(t,n));let o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ct.outline.length;i+=1){const r=t.outline[i],s=t.outline[(i+1)%t.outline.length];r\u0026\u0026s\u0026\u0026(o=Math.min(o,Oe(e,n,r,s)))}return o}return hL(e,t.bounds)\u0026\u0026hL(n,t.bounds)?Math.min(uL(e,t.bounds),uL(n,t.bounds)):Math.min(_L(t,e),_L(t,n))},xL=(t,e)=\u003ee+Math.max(.16,t.defaultObstacleMargin??0,rk.traceClearance??.1),vL=(t,e,n)=\u003ee\u003ct-u_\u0026\u0026Math.min(t,e)\u003c=n+u_,SL=(t,e,n,o,i)=\u003e{const r=t*n.x+e*n.y,s=-Math.max(0,o-i);if(r\u003e=s-u_)return{x:t,y:e};const a=s-r;return{x:t+n.x*a,y:e+n.y*a}},IL=(t,e,n,o,i)=\u003e{const r=fL(t,e);return r?SL(n,o,r,_L(t,e),xL(t,i)):{x:n,y:o}},CL=(t,e,n,o)=\u003e{const i=[...new Set(n)].sort((t,e)=\u003et-e);if(0===i.length)return Number.POSITIVE_INFINITY;const r=new Set(i),s=t=\u003eo?.get(t)??e.route[t];let a=Number.POSITIVE_INFINITY;for(const e of i){const n=s(e);n\u0026\u0026(a=Math.min(a,_L(t,n)))}for(let n=0;n\u003ce.route.length-1;n+=1){if(!r.has(n)\u0026\u0026!r.has(n+1))continue;const e=s(n),o=s(n+1);e\u0026\u0026o\u0026\u0026(a=Math.min(a,bL(t,e,o)))}return a},PL=(t,e,n,o,i,r)=\u003e{const s=[...new Set(n)].sort((t,e)=\u003et-e);if(0===s.length)return;const a=((t,e,n,o,i,r)=\u003e{const s=[...new Set(n)].sort((t,e)=\u003et-e);let a={x:o,y:i};const c=xL(t,r);for(let n=0;n\u003cMath.max(1,s.length);n+=1){let n=!1;for(const o of s){const i=e.route[o];if(!i)continue;const r=fL(t,i);if(!r)continue;const s=SL(a.x,a.y,r,_L(t,i),c);(Math.abs(s.x-a.x)\u003eh_||Math.abs(s.y-a.y)\u003eh_)\u0026\u0026(a=s,n=!0)}if(!n)break}return a})(t,e,s,o,i,r);if(Math.abs(a.x)\u003c=h_\u0026\u0026Math.abs(a.y)\u003c=h_)return;const c=new Map;for(const t of s){const n=e.route[t];if(!n)continue;const o={x:n.x+a.x,y:n.y+a.y};c.set(t,o)}const l=CL(t,e,s),d=CL(t,e,s,c);if(d\u003cr-u_)return;const h=xL(t,r);return vL(l,d,h)?void 0:a},ML=(t,e,n,o,i,r,s)=\u003e{const a=t[e];if(!a)return!1;const c=dL(a,n);if(!c)return!1;const l=PL(r,a,c,o,i,s);if(!l)return!1;let d=!1;for(const t of c){const e=a.route[t];e\u0026\u0026(e.x+=l.x,e.y+=l.y,gk(e,r.bounds),d=!0)}return d},NL=(t,e,n,o,i,r)=\u003edL(e,n)??((t,e,n,o,i,r)=\u003e{const s=e.route[n];if(!s||s.pcb_port_id||0!==n\u0026\u0026n!==e.route.length-1)return;const a=rL(t,e,s,r);if(!a)return;const c={...s,x:s.x+o,y:s.y+i};return yL(t,c)\u0026\u0026iL(c,a)?lL(e,n):void 0})(t,e,n,o,i,r),wL=(t,e,n,o,i,r)=\u003e{const s=PL(i,t,e,n,o,r);if(!s)return!1;let a=!1;for(const n of e){const e=t.route[n];e\u0026\u0026(e.x+=s.x,e.y+=s.y,gk(e,i.bounds),a=!0)}return a},TL=(t,e,n,o,i,r)=\u003e{const s=e.route[n];if(!s)return!1;if(s.pcb_port_id)return!1;const a=rL(t,e,s,r);return!!a\u0026\u0026iL({...s,x:s.x+o,y:s.y+i},a)},RL=(t,e,n,o)=\u003e{const i=e.route[n];if(i\u0026\u0026!i.pcb_port_id)return rL(t,e,i,o)},EL=(t,e,n,o,i,r,s)=\u003e{const a=t[e];if(!a||0===a.route.length)return!1;const c=((t,e,n,o,i)=\u003e{let r=Number.NEGATIVE_INFINITY,s=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY,c=Number.POSITIVE_INFINITY;for(const n of[0,e.route.length-1]){const o=e.route[n],l=RL(t,e,n,i);if(!o||!l)return;r=Math.max(r,l.center.x-l.width/2-o.x),s=Math.min(s,l.center.x+l.width/2-o.x),a=Math.max(a,l.center.y-l.height/2-o.y),c=Math.min(c,l.center.y+l.height/2-o.y)}if(!(r\u003es||a\u003ec))return{x:mk(n,r,s),y:mk(o,a,c)}})(i,a,n,o,s);if(!c)return!1;const l=a.route.map((t,e)=\u003ee),d=PL(i,a,l,c.x,c.y,r);if(!d)return!1;const h=a.route.length-1;if(!TL(i,a,0,d.x,d.y,s)||!TL(i,a,h,d.x,d.y,s))return!1;let u=!1;for(const t of a.route)t.x+=d.x,t.y+=d.y,gk(t,i.bounds),u=!0;return u},AL=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y,r=n.x-e.x,s=n.y-e.y;return Math.abs(o*s-i*r)\u003c=u_},OL=(t,e)=\u003e{if(t.z!==e.z)return!1;const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=t.x-e.start.x,r=t.y-e.start.y;return Math.abs(n*r-o*i)\u003c=u_},kL=(t,e)=\u003e{const n=((t,e)=\u003e{const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.max(u_,.12*(t.traceThickness??.1)),r=Math.abs(o)\u003c=i,s=Math.abs(n)\u003c=i;let a=e.startIndex,c=e.endIndex;if(r||s){const n=r?(e.start.y+e.end.y)/2:(e.start.x+e.end.x)/2;for(;a\u003e0;){const o=t.route[a-1];if(!o||o.z!==e.z||Math.abs((r?o.y:o.x)-n)\u003ei)break;a-=1}for(;c\u003ct.route.length-1;){const o=t.route[c+1];if(!o||o.z!==e.z||Math.abs((r?o.y:o.x)-n)\u003ei)break;c+=1}return Array.from({length:c-a+1},(t,e)=\u003ea+e)}for(;a\u003e0;){const n=t.route[a-1],o=t.route[a],i=t.route[a+1];if(!(n\u0026\u0026o\u0026\u0026i\u0026\u0026n.z===e.z\u0026\u0026OL(n,e)\u0026\u0026AL(n,o,i)))break;a-=1}for(;c\u003ct.route.length-1;){const n=t.route[c-1],o=t.route[c],i=t.route[c+1];if(!(n\u0026\u0026o\u0026\u0026i\u0026\u0026i.z===e.z\u0026\u0026OL(i,e)\u0026\u0026AL(n,o,i)))break;c+=1}return Array.from({length:c-a+1},(t,e)=\u003ea+e)})(t,e);if(n.length\u003c=2)return;const o=[];for(const e of n){const n=dL(t,e);if(!n)return;o.push(...n)}return[...new Set(o)]},LL=(t,e)=\u003ee\u003e0\u0026\u0026e\u003ct.route.length-1\u0026\u0026!((t,e)=\u003e{const n=t.route[e];if(!n)return!1;const o=t.route[e-1],i=t.route[e+1];return o\u0026\u0026o.z!==n.z\u0026\u0026Dk(o,n)||i\u0026\u0026i.z!==n.z\u0026\u0026Dk(i,n)})(t,e),DL=(t,e,n)=\u003e{const o=t.route[e.startIndex],i=t.route[e.endIndex];return!(!o||!i)\u0026\u0026(o.z===e.z\u0026\u0026i.z===e.z\u0026\u0026(!!((t,e)=\u003eJk(t).maxX\u003e=e.minX-u_\u0026\u0026Jk(t).minX\u003c=e.maxX+u_\u0026\u0026Jk(t).maxY\u003e=e.minY-u_\u0026\u0026Jk(t).minY\u003c=e.maxY+u_)(e,n)\u0026\u0026(LL(t,e.startIndex)||LL(t,e.endIndex))))},zL=(t,e,n,o,i,r,s)=\u003e{const a=t[e.routeIndex];if(!a)return!1;const c=((t,e,n,o)=\u003e{const i=fk(Kk(n),o);let r=e.startIndex,s=e.startIndex;for(;r\u003e0;){const n={...e,startIndex:r-1,endIndex:r,start:t.route[r-1],end:t.route[r]};if(!t.route[r-1]||!DL(t,n,i))break;r-=1}for(;s\u003ct.route.length-2;){const n={...e,startIndex:s+1,endIndex:s+2,start:t.route[s+1],end:t.route[s+2]};if(!t.route[s+2]||!DL(t,n,i))break;s+=1}const a=[];for(let e=r;e\u003c=s+1;e+=1)LL(t,e)\u0026\u0026a.push(e);return[...new Set(a)]})(a,e,n,o);return!(c.length\u003c=2)\u0026\u0026wL(a,c,i,r,s,e.radius)},FL=(t,e)=\u003e{const n=nL(e,t),o=n.x-e.x,i=n.y-e.y,r=Math.hypot(o,i),s=t.end.x-t.start.x,a=t.end.y-t.start.y,c=Math.hypot(s,a),l=t.routeIndex%2==0?1:-1;return{projection:n,direction:r\u003eh_?{x:o/r,y:i/r}:c\u003eh_?{x:-a/c*l,y:s/c*l}:{x:1,y:0}}},BL=(t,e,n,o,i)=\u003e{const r=t[e.routeIndex];if(!r)return!1;const s=IL(i,e,n,o,e.radius);if(Math.abs(s.x)\u003c=h_\u0026\u0026Math.abs(s.y)\u003c=h_)return!1;const a={x:e.x+s.x,y:e.y+s.y},c=_L(i,e),l=_L(i,a);if(l\u003ce.radius-u_)return!1;const d=xL(i,e.radius);if(vL(c,l,d))return!1;e.x+=s.x,e.y+=s.y,gk(e,i.bounds);for(const t of e.pointIndexes){const n=r.route[t];n\u0026\u0026(n.x=e.x,n.y=e.y)}return!0},jL=(t,e)=\u003e{const n=Gk(t),o=n.find(t=\u003et.routeIndex===e.routeIndex\u0026\u0026t.pointIndexes.some(t=\u003ee.pointIndexes.includes(t)));return o?n.filter(t=\u003et.rootConnectionName===o.rootConnectionName\u0026\u0026Math.hypot(t.x-o.x,t.y-o.y)\u003c=u_):[]},$L=(t,e,n,o,i)=\u003ee.movable\u0026\u0026jL(t,e).length\u003c=1\u0026\u0026BL(t,e,n,o,i),YL=(t,e,n,o,i=1)=\u003e{const{projection:r,direction:s}=FL(e,n),a=p_*i,c=1-r.t,l=r.t,d=ML(t,e.routeIndex,e.startIndex,s.x*a*c,s.y*a*c,o,e.radius),h=ML(t,e.routeIndex,e.endIndex,s.x*a*l,s.y*a*l,o,e.radius);return!(!d\u0026\u0026!h)||((t,e,n,o,i)=\u003e{const r=t[e.routeIndex];if(!r)return!1;const{projection:s,direction:a}=FL(e,n),c=IL(o,s,a.x*p_*i,a.y*p_*i,e.radius);if(Math.abs(c.x)\u003c=h_\u0026\u0026Math.abs(c.y)\u003c=h_)return!1;const l={...r.route[e.startIndex],x:s.x+c.x,y:s.y+c.y};if(gk(l,o.bounds),be(l,e.start,e.end)\u003c=u_)return!1;const d=r.route[e.startIndex],h=r.route[e.endIndex];if(!d||!h)return!1;const u=bL(o,d,h),p=Math.min(_L(o,l),bL(o,d,l),bL(o,l,h));if(p\u003ce.radius-u_)return!1;const m=xL(o,e.radius);return!vL(u,p,m)\u0026\u0026(r.route.splice(e.endIndex,0,l),!0)})(t,e,n,o,i)},XL=(t,e,n,o,i,r=1)=\u003e{const s=e.radius+f_(o)+g_,a=nD(e,n,s);if(!a)return!1;const c=Math.min(.3*Math.abs(r),a.penetration+g_),l=a.direction.x*c,d=a.direction.y*c,h=t[e.routeIndex];if(!h)return!1;const u=!(t=\u003e{for(let e=0;e\u003ct.route.length-1;e+=1){const n=t.route[e],o=t.route[e+1];if(n\u0026\u0026o\u0026\u0026n.z!==o.z\u0026\u0026Dk(n,o))return!0}return!1})(h);if(u\u0026\u0026EL(t,e.routeIndex,l,d,o,e.radius,i))return!0;const p=zL(t,e,n,s,l,d,o)||((t,e,n,o,i)=\u003e{const r=t[e.routeIndex];if(!r)return!1;const s=kL(r,e);return!!s\u0026\u0026wL(r,s,n,o,i,e.radius)})(t,e,l,d,o)||((t,e,n,o,i,r)=\u003e{const s=t[e.routeIndex];if(!s)return!1;const a=NL(i,s,e.startIndex,n,o,r),c=NL(i,s,e.endIndex,n,o,r);if(!a||!c)return!1;const l=[...new Set([...a,...c])],d=PL(i,s,l,n,o,e.radius);if(!d)return!1;let h=!1;for(const t of l){const e=s.route[t];e\u0026\u0026(e.x+=d.x,e.y+=d.y,gk(e,i.bounds),h=!0)}return h})(t,e,l,d,o,i);if(p)return!0;if(!u\u0026\u0026EL(t,e.routeIndex,l,d,o,e.radius,i))return!0;const m=n.width/2,g=n.height/2,f=(Math.abs(a.direction.y)\u003e=Math.abs(a.direction.x)?[{...h.route[e.startIndex],x:n.center.x-m-s,y:n.center.y+a.direction.y*(g+s)},{...h.route[e.startIndex],x:n.center.x+m+s,y:n.center.y+a.direction.y*(g+s)}]:[{...h.route[e.startIndex],x:n.center.x+a.direction.x*(m+s),y:n.center.y-g-s},{...h.route[e.startIndex],x:n.center.x+a.direction.x*(m+s),y:n.center.y+g+s}]).map(t=\u003e{const{t:n}=nL(t,e),i={x:e.start.x+(e.end.x-e.start.x)*n,y:e.start.y+(e.end.y-e.start.y)*n},r=IL(o,i,t.x-i.x,t.y-i.y,e.radius);return t.x=i.x+r.x,t.y=i.y+r.y,gk(t,o.bounds),{point:t,t:n,moved:Math.abs(r.x)\u003eh_||Math.abs(r.y)\u003eh_,awayFromObstacleMotion:r.x*a.direction.x+r.y*a.direction.y}}).sort((t,e)=\u003et.t-e.t);if(!f.some(({moved:t})=\u003et))return!1;if(!f.some(({awayFromObstacleMotion:t})=\u003et\u003eu_))return!1;const y=f.map(({point:t})=\u003et);if(y.every(t=\u003ebe(t,e.start,e.end)\u003c=u_))return!1;if(y.some(t=\u003e!yL(o,t)))return!1;const _=h.route[e.startIndex],b=h.route[e.endIndex],x=y[0],v=y[1];if(!(_\u0026\u0026b\u0026\u0026x\u0026\u0026v))return!1;const S=bL(o,_,b),I=Math.min(_L(o,x),_L(o,v),bL(o,_,x),bL(o,x,v),bL(o,v,b));if(I\u003ce.radius-u_)return!1;const C=xL(o,e.radius);return!vL(S,I,C)\u0026\u0026(h.route.splice(e.endIndex,0,...y),!0)},VL=(t,e,n)=\u003e{let o;for(const i of t){if(void 0!==n\u0026\u0026i.routeIndex!==n)continue;const t=nL(e,i),r=Math.hypot(t.x-e.x,t.y-e.y);(!o||r\u003co.distance)\u0026\u0026(o={segment:i,distance:r})}return o?.segment},WL=(t,e,n)=\u003e{let o;for(const i of t){if(void 0!==n\u0026\u0026i.routeIndex!==n)continue;const t=Math.hypot(i.x-e.x,i.y-e.y);(!o||t\u003co.distance)\u0026\u0026(o={via:i,distance:t})}return o?.via},HL=(t,e)=\u003e{const n=t.map(t=\u003e({via:t,distance:Math.hypot(t.x-e.x,t.y-e.y)})).sort((t,e)=\u003et.distance-e.distance).slice(0,2).map(({via:t})=\u003et);return 2===n.length?n:void 0},GL=(t,e,n,o)=\u003e{const i=e.x-n.x,r=e.y-n.y,s=Math.hypot(i,r);return $L(t,e,(s\u003eh_?i/s:1)*p_,(s\u003eh_?r/s:0)*p_,o)},UL=(t,e)=\u003e{const n=nL(t.start,e),o=nL(t.end,e),i=nL(e.start,t),r=nL(e.end,t);return[{leftT:0,rightT:n.t,leftPoint:t.start,rightPoint:n},{leftT:1,rightT:o.t,leftPoint:t.end,rightPoint:o},{leftT:i.t,rightT:0,leftPoint:i,rightPoint:e.start},{leftT:r.t,rightT:1,leftPoint:r,rightPoint:e.end}].sort((t,e)=\u003eMath.hypot(t.leftPoint.x-t.rightPoint.x,t.leftPoint.y-t.rightPoint.y)-Math.hypot(e.leftPoint.x-e.rightPoint.x,e.leftPoint.y-e.rightPoint.y))},ZL=(t,e,n,o,i,r)=\u003e{const s=mk(r,0,1),a=1-s,c=s,l=ML(t,e.routeIndex,e.startIndex,n*a,o*a,i,e.radius),d=ML(t,e.routeIndex,e.endIndex,n*c,o*c,i,e.radius);return l||d},qL=(t,e,n,o,i,r=.035,s=!1)=\u003e{if(!s\u0026\u0026uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const a=e.radius+n.radius+.2+g_,c=e.x-n.x,l=e.y-n.y,d=Math.hypot(c,l),h=a-d;if(h\u003c=0)return!1;const u=1.618*(97*e.routeIndex+13*n.routeIndex),p=d\u003eh_?c/d:Math.cos(u),m=d\u003eh_?l/d:Math.sin(u),g=Number(e.movable)+Number(n.movable);if(0===g)return!1;const f=Math.min(r,h/g),y=$L(t,e,p*f,m*f,o),_=$L(t,n,-p*f,-m*f,o);return y||_},JL=(t,e,n,o,i)=\u003e{if(!uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const[r,s]=e.canCanonicalize?n.canCanonicalize\u0026\u0026e.routeIndex\u003c=n.routeIndex?[e,n]:[n,e]:[e,n];return((t,e,n,o)=\u003e{if(!n.canCanonicalize)return!1;const i=e.x-n.x,r=e.y-n.y;if(!n.movable\u0026\u0026Math.hypot(i,r)\u003en.radius+u_)return!1;const s=t[n.routeIndex];if(!s)return!1;const a={x:n.x,y:n.y},c=n.pointIndexes.map(t=\u003e{const e=s.route[t];return e?{pointIndex:t,x:e.x,y:e.y}:void 0});if(BL(t,n,i,r,o)\u0026\u0026Dk(n,e))return!0;n.x=a.x,n.y=a.y;for(const t of c){if(!t)continue;const e=s.route[t.pointIndex];e\u0026\u0026(e.x=t.x,e.y=t.y)}return!1})(t,r,s,o)},KL=(t,e,n,o,i,r=.035,s=2,a=!1)=\u003e{if(uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const c=nL(e,n),l=e.x-c.x,d=e.y-c.y,h=Math.hypot(l,d),u=e.radius+n.radius+(rk.traceClearance??.1)+g_-h;if(u\u003c=0)return!1;const p=n.end.x-n.start.x,m=n.end.y-n.start.y,g=Math.hypot(p,m),f=e.routeIndex%2==0?1:-1,y=h\u003eh_?l/h:g\u003eh_?-m/g*f:1,_=h\u003eh_?d/h:g\u003eh_?p/g*f:0,b=Math.min(r,u/s),x=a?((t,e,n,o,i)=\u003e{const r=jL(t,e);if(0===r.length||r.some(e=\u003e!e.movable||void 0===t[e.routeIndex]))return!1;const s=r.reduce((t,e)=\u003ee.radius\u003et.radius?e:t);if(!BL(t,s,n,o,i))return!1;for(const e of r){if(e===s)continue;e.x=s.x,e.y=s.y;const n=t[e.routeIndex];for(const t of e.pointIndexes){const e=n.route[t];e\u0026\u0026(e.x=s.x,e.y=s.y)}}return!0})(t,e,y*b,_*b,o):$L(t,e,y*b,_*b,o),v=ZL(t,n,-y*b,-_*b,o,c.t);return x||v},QL=(t,e,n,o,i)=\u003e{if(e.z!==n.z||uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const[r]=UL(e,n);if(!r)return!1;const s=r.leftPoint.x-r.rightPoint.x,a=r.leftPoint.y-r.rightPoint.y,c=Math.hypot(s,a),l=e.radius+n.radius+(rk.traceClearance??.1)+g_-c;if(l\u003c=0)return!1;const d=e.end.x-e.start.x,h=e.end.y-e.start.y,u=Math.hypot(d,h),p=(e.routeIndex+n.routeIndex)%2==0?1:-1,m=c\u003eh_?s/c:u\u003eh_?-h/u*p:1,g=c\u003eh_?a/c:u\u003eh_?d/u*p:0,f=Math.min(m_,l/2),y=ZL(t,e,m*f,g*f,o,r.leftT),_=ZL(t,n,-m*f,-g*f,o,r.rightT);return y||_},tD=(t,e,n)=\u003eQk(t,n).includes(e.z),eD=(t,e,n,o,i)=\u003e{const r=e[n];if(!r)return;const s=Uk(r,n);if(0===s.length)return;const a=dk(r),c=VL(s,o);if(!c)return;const l=sL(t,o,.6,e=\u003e!pk(a,e,i)\u0026\u0026tD(e,c,t.layerCount));if(l)return{obstacle:l,segment:c};const d=sL(t,o,.6,e=\u003e!pk(a,e,i)\u0026\u0026s.some(n=\u003etD(e,n,t.layerCount)));if(!d)return;const h=VL(s.filter(e=\u003etD(d,e,t.layerCount)),o);return h?{obstacle:d,segment:h}:void 0},nD=(t,e,n)=\u003e{const o=e.width/2,i=e.height/2,r=[{x:e.center.x-o,y:e.center.y-i},{x:e.center.x+o,y:e.center.y-i},{x:e.center.x+o,y:e.center.y+i},{x:e.center.x-o,y:e.center.y+i}],s=[e.center,...r].map(e=\u003enL(e,t)),a=[{point:t.start,t:0},{point:t.end,t:1},{point:{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2},t:.5},...s.map(t=\u003e({point:{x:t.x,y:t.y},t:t.t}))];let c;const l=Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y);for(const o of a){const i=aL(o.point,e,n);if(!i)continue;const r=l\u003eh_?Math.abs(((t.end.x-t.start.x)*i.direction.y-(t.end.y-t.start.y)*i.direction.x)/l):0;(!c||i.penetration\u003ec.penetration+h_||Math.abs(i.penetration-c.penetration)\u003c=h_\u0026\u0026r\u003ec.normality)\u0026\u0026(c={...i,normality:r,t:o.t})}return c},oD=(t,e,n,o=!1)=\u003e{let i=!1;const r=Gk(e),s=Zk(e),a=tL(t,r,s),c=Math.max(1,2*a),l=bk(r,qk,c),d=bk(s,Jk,c);for(let s=0;s\u003cr.length;s+=1){const d=r[s];if(!d)continue;const h=xk(l,fk(qk(d),a),c);for(const a of h){if(a\u003c=s)continue;const c=r[a];c\u0026\u0026(i=qL(e,d,c,t,n,m_,o)||i)}}for(let o=0;o\u003cr.length;o+=1){const l=r[o];if(!l)continue;const h=xk(d,fk(qk(l),a),c);for(const o of h){const r=s[o];r\u0026\u0026(i=KL(e,l,r,t,n)||i)}}for(let o=0;o\u003cs.length;o+=1){const r=s[o];if(!r)continue;const l=xk(d,fk(Jk(r),a),c);for(const a of l){if(a\u003c=o)continue;const c=s[a];c\u0026\u0026(i=QL(e,r,c,t,n)||i)}}return((t,e,n,o,i,r,s,a)=\u003e{let c=!1;const l=t.minTraceWidth/2+f_(t)+g_,d=(t.minViaDiameter??.3)/2+y_(t)+g_;for(const h of t.obstacles){if(h.isCopperPour)continue;const u=Kk(h),p=xk(i,fk(u,d),s);for(const o of p){const i=n[o];if(!i)continue;if(pk(i.rootConnectionName,h,a))continue;const r=aL(i,h,d);if(!r)continue;const s=Math.min(m_,r.penetration);c=$L(e,i,r.direction.x*s,r.direction.y*s,t)||c}const m=xk(r,fk(u,l),s);for(const n of m){const i=o[n];if(!i)continue;if(pk(i.rootConnectionName,h,a)||!tD(h,i,t.layerCount))continue;const r=nD(i,h,l);if(!r)continue;const s=Math.min(m_,r.penetration);c=ZL(e,i,r.direction.x*s,r.direction.y*s,t,r.t)||c}}return c})(t,e,r,s,l,d,c,n)||i},iD=(t,e,n,o=1,i,r=!1,s=!0)=\u003e{const a=kk(e),c=Math.max(2,Math.round(12*Math.max(1,n)*o));let l=!1;for(let e=0;e\u003cc;e+=1){if(!oD(t,a,i,r))break;l=!0}return l\u0026\u0026s\u0026\u0026((t,e,n)=\u003e{let o=!1;const i=Gk(e),r=Zk(e),s=tL(t,i,r),a=Math.max(1,2*s),c=bk(r,Jk,a);for(const l of i){const i=xk(c,fk(qk(l),s),a);for(const s of i){const i=r[s];i\u0026\u0026(o=KL(e,l,i,t,n,m_,1.75)||o)}}})(t,a,i),l?aD(a):e},rD=t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n+=1){const o=t.route[n],i=t.route[n+1];if(!o||!i)continue;if(\"through_obstacle\"===o.toNextSegmentType)continue;if(o.z===i.z||!Dk(o,i))continue;const r={x:o.x,y:o.y},s=e.at(-1);s\u0026\u0026Dk(s,r)||e.push(r)}return e},sD=t=\u003e({...t,vias:rD(t)}),aD=t=\u003et.map(sD),cD=(t,e)=\u003e{const n=new Set(e);return t.map((t,e)=\u003en.has(e)?sD(t):t)},lD=t=\u003e{const e=t.pcb_trace_id;if(\"string\"!=typeof e)return;const n=e.match(/^trace_(\\d+)/);return n?Number.parseInt(n[1],10):void 0},dD=t=\u003e{const e=t.center??t.pcb_center;if(!e||\"object\"!=typeof e)return;const n=e;return\"number\"==typeof n.x\u0026\u0026\"number\"==typeof n.y?{x:n.x,y:n.y}:void 0},hD=(t,e=!0)=\u003et.errors.filter(t=\u003e(t=\u003e\"pcb_via_clearance_error\"===Fk(t)||Array.isArray(t.pcb_via_ids))(t)\u0026\u0026(e||!uD(t))).length,uD=t=\u003e\"pcb_pad_pad_clearance_error\"===Fk(t)\u0026\u0026Array.isArray(t.pcb_via_ids)\u0026\u00261===t.pcb_via_ids.length,pD=t=\u003e{const e=Object.entries(t).filter(([t,e])=\u003e\"source_trace_id\"!==t\u0026\u0026(t.endsWith(\"_id\")||t.endsWith(\"_ids\"))\u0026\u0026void 0!==e\u0026\u0026\"\"!==e).sort(([t],[e])=\u003et.localeCompare(e)),n=\"string\"==typeof t.message?t.message.replace(/-?\\d+\\.\\d+/g,\"#\"):\"\";return JSON.stringify([Fk(t),e,n])},mD=t=\u003eMath.max(t.errors.filter(t=\u003e!uD(t)).length,t.count-t.errors.filter(uD).length),gD=t=\u003e{const e=mD(t);return e\u003e0?e:t.count},fD=t=\u003e{if(0===mD(t))return t.issueScore;const e=t.errors.filter(t=\u003e!uD(t));return t.errors.some(uD)?Xk(e):t.legacyIssueScore??Xk(e)},yD=(t,e)=\u003e{const n=mD(t),o=mD(e);return n!==o?n\u003co:!(n\u003e0)\u0026\u0026t.count\u003ce.count},_D=t=\u003e{const e=t.filter(t=\u003e!uD(t));return e.length\u003e0?e:t},bD=(t,e)=\u003e{const n=t.pcb_trace_id;return\"string\"==typeof n?e.get(n)??lD(t):lD(t)},xD=(t,e,n,o,i)=\u003e{const r=n.pcb_port_id;if(!r)return!1;const s=(i??e.viaDiameter)/2;return t.obstacles.some(i=\u003e{const a=Qk(i,t.layerCount);return!(1!==a.length||a[0]!==n.z||!i.connectedTo.includes(r)||n.x-s\u003ci.center.x-i.width/2-h_||n.x+s\u003ei.center.x+i.width/2+h_||n.y-s\u003ci.center.y-i.height/2-h_||n.y+s\u003ei.center.y+i.height/2+h_)\u0026\u0026(pk(dk(e),i,o)||pk(e.connectionName,i,o))})},vD=[0,1,-1,2,-2,3,-3,4],SD=vD.flatMap(t=\u003evD.map(e=\u003e[t,e])).sort(([t,e],[n,o])=\u003eMath.abs(t)+Math.abs(e)-Math.abs(n)-Math.abs(o)),ID=SD.length,CD=(t,e,n)=\u003et.x-e\u003e=n.minX-h_\u0026\u0026t.x+e\u003c=n.maxX+h_\u0026\u0026t.y-e\u003e=n.minY-h_\u0026\u0026t.y+e\u003c=n.maxY+h_,PD=(t,e)=\u003e{const n=t.at(-1);n\u0026\u0026Dk(n,e)\u0026\u0026n.z===e.z\u0026\u0026n.pcb_port_id===e.pcb_port_id||t.push(e)},MD=(t,e,n,o,i,r,s,a=0,c=!1)=\u003e{const l=Fk(n);if(\"pcb_pad_trace_clearance_error\"!==l\u0026\u0026\"pcb_trace_error\"!==l)return!1;if(i\u003c0||i\u003e=t.layerCount)return!1;const d=e[o];if(!d||d.route.length\u003c2)return!1;const h=d.route.map(t=\u003e({...t})),u=h[0],p=h.at(-1);if(!u||!p)return!1;const m=dD(n);if(!m)return!1;const g=Bk(n),f=g?eD(t,e,o,m,s):void 0,y=g?f?.segment:VL(Uk(d,o),m);if(!y||y.z===i)return!1;let _=y.startIndex,b=y.endIndex;const x=\"full\"===r?h.length:r;for(let t=0;t\u003cx;t+=1){let t=!1;const e=h[_-1];e?.z===y.z\u0026\u0026(_-=1,t=!0);const n=h[b+1];if(n?.z===y.z\u0026\u0026(b+=1,t=!0),!t)break}const v=0===_\u0026\u0026u.pcb_port_id,S=b===h.length-1\u0026\u0026p.pcb_port_id,I=d.viaDiameter/2,C=SD[a%ID];let P=!1;const M=e=\u003e{const n=\"start\"===e?u:p,o=((t,e,n,o)=\u003e{const i=n.pcb_port_id;if(i)return t.obstacles.find(r=\u003e{const s=Qk(r,t.layerCount);return!(1!==s.length||s[0]!==n.z||!r.connectedTo.includes(i)||!iL(n,r))\u0026\u0026(pk(dk(e),r,o)||pk(e.connectionName,r,o))})})(t,d,n,s),r=((t,e)=\u003e{const n=\"start\"===e?t[0]:t.at(-1);if(!n)return;const o=\"start\"===e?Array.from({length:t.length-1},(t,e)=\u003ee+1):Array.from({length:t.length-1},(e,n)=\u003et.length-n-2);for(const e of o){const o=t[e];if(!o)continue;const i=o.x-n.x,r=o.y-n.y,s=Math.hypot(i,r);if(!(s\u003c=h_))return{x:i/s,y:r/s}}})(h,e);if(!o||!r)return;const a=((t,e,n,o)=\u003e{let i=0,r=Math.hypot(e.width,e.height)+2*o;const s=o+h_,a=e=\u003e({x:t.x+n.x*e,y:t.y+n.y*e});if(!(oL(a(r),e)\u003cs)){for(;r-i\u003eh_;){const t=(i+r)/2;oL(a(t),e)\u003e=s?r=t:i=t}return a(r)}})(n,o,((t,e)=\u003e{const n=e*Math.PI/4,o=Math.cos(n),i=Math.sin(n);return{x:t.x*o-t.y*i,y:t.x*i+t.y*o}})(r,\"start\"===e?C[0]:C[1]),I);if(!a||!CD(a,I,t.bounds)||oL(a,o)+h_\u003cI)return;if(!c)return a;const l=((t,e,n,o,i,r)=\u003e{const s=o+(t.minBoardEdgeClearance??0),a={minX:t.bounds.minX+s,maxX:t.bounds.maxX-s,minY:t.bounds.minY+s,maxY:t.bounds.maxY-s};if(a.minX\u003ea.maxX||a.minY\u003ea.maxY)return;const c=Ek(t,e,o,i,r),l=t=\u003eMe(t,a)\u0026\u0026c.every(e=\u003eCk(t,e)\u003e=e.clearance),d=Ik(n,a);if(l(d))return Me(n,a)?n:d;const h=c.filter(t=\u003eCk(d,t)\u003ct.clearance),u=new Set(h);for(let t=0;t\u003ch.length;t+=1)for(const e of c)!u.has(e)\u0026\u0026Xe(h[t].bounds,e.bounds)\u0026\u0026(u.add(e),h.push(e));const p=h.flatMap(Nk),m={x:a.minX,y:a.minY},g={x:a.maxX,y:a.minY},f={x:a.maxX,y:a.maxY},y={x:a.minX,y:a.maxY};let _;p.push(Pk(m,g),Pk(g,f),Pk(f,y),Pk(y,m));let b=Number.POSITIVE_INFINITY;const x=t=\u003e{const e=Ye(t,n);e\u003cb\u0026\u0026l(t)\u0026\u0026(_=t,b=e)};for(const t of p)for(const e of wk(n,t))x(e);for(let t=0;t\u003cp.length;t+=1){const e=p[t];if(!(Ye(n,Ik(n,e.bounds))\u003eb))for(let o=t+1;o\u003cp.length;o+=1){const t=p[o];if(Xe(e.bounds,t.bounds)\u0026\u0026!(Ye(n,Ik(n,t.bounds))\u003eb))for(const n of Rk(e,t))x(n)}}return _})(t,d,a,I,[y.z,i],s);return P||=void 0!==l\u0026\u0026l!==a,l},N=v?M(\"start\"):void 0,w=S?M(\"end\"):void 0;if(v\u0026\u0026!N||S\u0026\u0026!w||c\u0026\u0026!P)return!1;const T=[];for(let t=0;t\u003c_;t+=1)PD(T,h[t]);const R=h[_],E=_\u003e0\u0026\u0026Dk(h[_-1],R),A=h[b],O=b\u003ch.length-1\u0026\u0026Dk(h[b+1],A);v?(PD(T,u),PD(T,{...u,...N,pcb_port_id:void 0}),PD(T,{...u,...N,z:i,pcb_port_id:void 0})):(E||PD(T,{...R,pcb_port_id:void 0}),PD(T,{...R,z:i,pcb_port_id:void 0}));const k=S?b-1:b;for(let t=_+1;t\u003c=k;t+=1)PD(T,{...h[t],z:i,pcb_port_id:void 0});S?(PD(T,{...p,...w,z:i,pcb_port_id:void 0}),PD(T,{...p,...w,pcb_port_id:void 0}),PD(T,p)):O||PD(T,{...A,pcb_port_id:void 0});for(let t=b+1;t\u003ch.length;t+=1)PD(T,h[t]);for(let t=1;t\u003cT.length-1;t+=1)T[t].pcb_port_id=void 0;const L=t.minBoardEdgeClearance??.2,D=Uk(d,o),z=Gk([d]);for(let e=1;e\u003cT.length;e+=1){const n=T[e-1],o=T[e];if(n.z===o.z\u0026\u0026!D.some(t=\u003epL(n,t.start,t.end)\u0026\u0026pL(o,t.start,t.end))\u0026\u0026bL(t,n,o)\u003cd.traceThickness/2+L)return!1;if(n.z!==o.z\u0026\u0026\"through_obstacle\"!==n.toNextSegmentType\u0026\u0026!z.some(t=\u003eDk(t,o)\u0026\u0026t.radius\u003e=I)\u0026\u0026_L(t,o)\u003cI+L)return!1}return d.route=T,!0},ND=(t,e,n,o,i,r,s)=\u003e{const a=Fk(n);if(\"pcb_pad_trace_clearance_error\"!==a\u0026\u0026\"pcb_trace_error\"!==a)return!1;if(i\u003c0||i\u003e=t.layerCount)return!1;const c=bD(n,o);if(void 0===c)return!1;const l=e[c];if(!l||l.route.length\u003c2)return!1;const d=l.route[0],h=l.route.at(-1);if(!d||!h||d.z!==h.z||i===d.z)return!1;if(l.route.some(t=\u003et.z!==d.z))return!1;if(!d.pcb_port_id||!h.pcb_port_id)return!1;if(!xD(t,l,d,r,s)||!xD(t,l,h,r,s))return!1;const u=l.route.map(t=\u003e({...t}));return l.route=[u[0],{...u[0],z:i,pcb_port_id:void 0},...u.slice(1,-1).map(t=\u003e({...t,z:i})),{...u.at(-1),z:i,pcb_port_id:void 0},u.at(-1)],!0},wD=(t,e,n,o,i,r,s)=\u003e{if(\"pcb_pad_trace_clearance_error\"!==Fk(n))return!1;const a=bD(n,o);if(void 0===a)return!1;const c=e[a];if(!c||c.route.length\u003c4)return!1;const l=c.route.map(t=\u003e({...t}));if(\"start\"===i){const e=l[0];if(!xD(t,c,e,r,s))return!1;let n=-1;for(let t=1;t\u003cl.length;t+=1)if(l[t].z!==e.z){n=t;break}if(n\u003c=0)return!1;const o=n-1;if(!Dk(l[o],l[n]))return!1;let i=n;for(;i+1\u003cl.length\u0026\u0026Dk(l[n],l[i+1]);)i+=1;const a=l[i].z,d=l.slice(o,i+1).map(t=\u003et.z);return c.route=[e,...d.slice(1).map(t=\u003e({...e,z:t,pcb_port_id:void 0})),...l.slice(1,o+1).map(t=\u003e({...t,z:a})),...l.slice(i+1)],!0}const d=l.at(-1);if(!xD(t,c,d,r,s))return!1;let h=-1;for(let t=l.length-2;t\u003e=0;t-=1)if(l[t].z!==d.z){h=t;break}if(h\u003c0||h\u003e=l.length-1)return!1;const u=h+1;if(!Dk(l[h],l[u]))return!1;let p=h;for(;p-1\u003e=0\u0026\u0026Dk(l[h],l[p-1]);)p-=1;const m=l[p].z,g=l.slice(p,u+1).map(t=\u003et.z);return c.route=[...l.slice(0,p+1),...l.slice(u+1,-1).map(t=\u003e({...t,z:m})),{...d,z:m,pcb_port_id:void 0},...g.slice(1,-1).map(t=\u003e({...d,z:t,pcb_port_id:void 0})),d],!0},TD=(t,e)=\u003e{const n=t.pcb_trace_id;if(\"string\"!=typeof n)return;if(Array.isArray(t.pcb_via_ids)\u0026\u0026t.pcb_via_ids.length\u003e0)return;const o=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],i=t.pcb_trace_error_id,r=`overlap_${n}_`,s=\"string\"==typeof i\u0026\u0026i.startsWith(r)?i.slice(r.length):void 0,a=[n,...o,...s?[s]:[]],c=[...new Set(a.map(t=\u003ee.get(t)).filter(t=\u003evoid 0!==t))];return c.length\u003e=2?[c[0],c[1]]:void 0},RD=(t,e,n,o,i)=\u003e{if(\"pcb_trace_error\"!==Fk(n))return;const r=TD(n,o);if(!r)return;const s=n.worst_contact_center??n.center;if(!s||\"object\"!=typeof s)return;const a=s;if(\"number\"!=typeof a.x||\"number\"!=typeof a.y)return;const c={x:a.x,y:a.y},l=Zk(e),d=VL(l,c,r[0]),h=VL(l,c,r[1]);if(!d||!h||d.z!==h.z)return;const[u]=UL(d,h);if(!u)return;const p=u.leftPoint.x-u.rightPoint.x,m=u.leftPoint.y-u.rightPoint.y,g=Math.hypot(p,m),f=Number(n.minimum_clearance),y=Number.isFinite(f)?f:rk.traceClearance??.1,_=d.radius+h.radius+y-g;if(_\u003c=h_)return;const b=0===i?d:h,x=0===i?u.leftT:u.rightT,v=(1-x)**2+x**2;if(v\u003c=h_)return;const S=_/v,I=0===i?u.leftPoint:u.rightPoint,C=0===i?u.rightPoint:u.leftPoint,P=0===i?1:-1,M=b.end.x-b.start.x,N=b.end.y-b.start.y,w=Math.hypot(M,N),T=(b.routeIndex+(0===i?h.routeIndex:d.routeIndex))%2==0?1:-1,R=g\u003eh_?(I.x-C.x)/g:w\u003eh_?-N/w*T*P:P,E=g\u003eh_?(I.y-C.y)/g:w\u003eh_?M/w*T*P:0;return ZL(e,b,R*S,E*S,t,x)?{movedRouteIndex:b.routeIndex}:void 0},ED=t=\u003e{const{srj:e,via:n,segment:o,segments:i,initialTarget:r,requiredTraceDistance:s,requiredObstacleDistance:a,connMap:c}=t,l=Math.min(...n.zLayers),d=Math.max(...n.zLayers),h=e.obstacles.filter(t=\u003e!t.isCopperPour\u0026\u0026!pk(n.rootConnectionName,t,c)\u0026\u0026Qk(t,e.layerCount).some(t=\u003et\u003e=l\u0026\u0026t\u003c=d)),u=h.filter(t=\u003eBoolean(aL(r,t,a))),p=[r,...Ak(n,i,s-n.radius-o.radius,c),...u.flatMap(t=\u003e(t=\u003e{const{point:e,obstacle:n,requiredDistance:o}=t,i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=n.center.y-n.height/2,a=n.center.y+n.height/2,c=Math.max(i-e.x,e.x-r,0),l=Math.max(s-e.y,e.y-a,0),d=[];if(c\u003co){const t=Math.sqrt(o*o-c*c);d.push({x:e.x,y:s-t-h_},{x:e.x,y:a+t+h_})}if(l\u003co){const t=Math.sqrt(o*o-l*l);d.push({x:i-t-h_,y:e.y},{x:r+t+h_,y:e.y})}return d})({point:r,obstacle:t,requiredDistance:a}))];return p.filter(t=\u003e{if(!CD(t,n.radius,e.bounds))return!1;const r=nL(t,o);return!(Math.hypot(t.x-r.x,t.y-r.y)\u003cs-h_)\u0026\u0026(!i.some(e=\u003ee.z\u003e=l\u0026\u0026e.z\u003c=d\u0026\u0026!uk(n.rootConnectionName,e.rootConnectionName,c)\u0026\u0026be(t,e.start,e.end)\u003cs+e.radius-o.radius-h_)\u0026\u0026h.every(e=\u003eoL(t,e)\u003e=a-h_))}).sort((t,e)=\u003eMath.hypot(t.x-n.x,t.y-n.y)-Math.hypot(e.x-n.x,e.y-n.y))[0]},AD=(t,e,n,o,i,r)=\u003e{if(\"pcb_trace_error\"!==Fk(n))return!1;const s=\"string\"==typeof n.pcb_trace_error_id?n.pcb_trace_error_id.toLowerCase():\"\",a=\"string\"==typeof n.message?n.message.toLowerCase():\"\";if(!(\"string\"==typeof n.pcb_via_id||Array.isArray(n.pcb_via_ids)||s.includes(\"_via_\")||a.includes(\"via\")))return!1;if(bD(n,o)!==i)return!1;if(TD(n,o))return!1;const c=n.worst_contact_center??n.center;if(!c||\"object\"!=typeof c)return!1;const l=c;if(\"number\"!=typeof l.x||\"number\"!=typeof l.y)return!1;const d={x:l.x,y:l.y},h=Zk(e),u=VL(h,d,i),p=Array.isArray(n.pcb_trace_ids)?n.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t\u0026\u0026t!==n.pcb_trace_id):[],m=p.map(t=\u003eo.get(t)).filter(t=\u003evoid 0!==t),g=Gk(e),f=WL(p.length\u003e0?g.filter(t=\u003em.includes(t.routeIndex)):g,d);if(!u||!f||!f.movable||uk(f.rootConnectionName,u.rootConnectionName,r))return!1;const y=nL(f,u),_=f.x-y.x,b=f.y-y.y,x=Math.hypot(_,b),v=Number(n.minimum_clearance),S=Number.isFinite(v)?v:rk.traceClearance??.1,I=f.radius+u.radius+S-x;if(I\u003c=h_)return!1;const C=u.end.x-u.start.x,P=u.end.y-u.start.y,M=Math.hypot(C,P),N=f.routeIndex%2==0?1:-1,w=x\u003eh_?_/x:M\u003eh_?-P/M*N:1,T=x\u003eh_?b/x:M\u003eh_?C/M*N:0,R=f.radius+u.radius+S,E=f.radius+y_(t)+g_,A={x:f.x+w*(I+g_),y:f.y+T*(I+g_)},O=ED({srj:t,via:f,segment:u,segments:h,initialTarget:A,requiredTraceDistance:R,requiredObstacleDistance:E,connMap:r});return!!O\u0026\u0026$L(e,f,O.x-f.x,O.y-f.y,t)},OD=(t,e,n)=\u003e{if(\"pcb_trace_error\"!==Fk(e))return;const o=dD(e),i=t[n];if(!o||!i)return;const r=VL(Uk(i,n),o);return r?{center:o,route:i,segment:r}:void 0},kD=(t,e,n,o)=\u003e{const i=OD(t,e,n);if(!i)return;const{route:r,segment:s}=i,a=Math.max(0,s.startIndex-o),c=Math.min(r.route.length-1,s.endIndex+o),l=r.route.slice(a,c+1),d=l[0],h=l.at(-1);return d\u0026\u0026h\u0026\u0026!l.some(t=\u003et.z!==d.z)\u0026\u0026d.z===h.z?{route:r,spanStartIndex:a,spanEndIndex:c,start:d,end:h}:void 0},LD=(t,e,n,o,i,r,s=0,a,c)=\u003e{if(r\u003c0||r\u003e=t.layerCount)return!1;const l=TD(n,o);if(!l)return!1;const d=l[i],h=OD(e,n,d);if(!h||h.segment.z===r)return!1;const{route:u,segment:p}=h;let m=p.startIndex,g=p.endIndex;for(let t=0;t\u003cs;t+=1){const t=u.route[m-1];t?.z===p.z\u0026\u0026(m-=1);const e=u.route[g+1];e?.z===p.z\u0026\u0026(g+=1)}if(0===m\u0026\u0026u.route[0]?.pcb_port_id\u0026\u0026!xD(t,u,u.route[0],a,c)||g===u.route.length-1\u0026\u0026u.route.at(-1)?.pcb_port_id\u0026\u0026!xD(t,u,u.route.at(-1),a,c))return!1;const f=u.route[m],y=u.route[g];if(!f||!y||f.z!==y.z)return!1;const _=u.route.slice(m,g+1).map(t=\u003e({...t,z:r,pcb_port_id:void 0}));return u.route.splice(m,g-m+1,{...f},..._,{...y}),!0},DD=(t,e,n,o,i,r)=\u003e{if(o\u003c=0||i\u003c=0)return!1;const s=OD(t,e,n);if(!s)return!1;const{center:a,route:c,segment:l}=s,d=l.end.x-l.start.x,h=l.end.y-l.start.y,u=Math.hypot(d,h);if(u\u003c=h_)return!1;const p=nL(a,l),m=mk(p.t-o/u,.02,.98),g=mk(p.t+o/u,.02,.98);if(m\u003e=g)return!1;const f=t=\u003e({x:l.start.x+d*t,y:l.start.y+h*t,z:l.z}),y=f(m),_=f(g),b=-h/u*r,x=d/u*r,v=c.route[l.startIndex],S=c.route[l.endIndex];return c.route.splice(l.startIndex,2,{...v},y,{...y,x:y.x+b*i,y:y.y+x*i},{..._,x:_.x+b*i,y:_.y+x*i},_,{...S}),!0},zD=(t,e,n,o,i,r,s,a=!1)=\u003e{if(!Number.isInteger(i)||i\u003c0||i\u003e=t.layerCount)return!1;const c=dD(n),l=e[o],d=l?.route[0],h=l?.route.at(-1);if(!l||!c||!d||!h||d.z!==h.z||d.z===i||l.jumpers?.length||l.route.some(t=\u003et.z!==d.z||\"through_obstacle\"===t.toNextSegmentType))return!1;const u=h.x-d.x,p=h.y-d.y,m=Math.hypot(u,p);if(m\u003c=h_||m\u003e8)return!1;const g=u/m,f=p/m,y=f*r,_=-g*r,b=t=\u003e(t.x-c.x)*g+(t.y-c.y)*f,x=(t,e,n)=\u003e({x:c.x+g*t+y*e,y:c.y+f*t+_*e,z:n}),v=(l.viaDiameter??t.minViaDiameter??.3)+(t.minTraceToPadEdgeClearance??rk.traceClearance??.1),S=(a?1.25:-.75)*v,I=(a?-.75:1.25)*v,C=b(d)+.5*v*s,P=b(h)+v*s,M=x(C,S,d.z),N=x(P,I,d.z),w=x(C,2*v,i),T=x(P,2*v,i),R=[{...d},M,{...M,z:i},w,T,{...N,z:i},N,{...h}],E=t.minBoardEdgeClearance??0,A=(l.viaDiameter??t.minViaDiameter??.3)/2,O=l.traceThickness/2;if([M,N].some(e=\u003e_L(t,e)+u_\u003cA+E))return!1;for(let e=0;e\u003cR.length-1;e+=1){const n=R[e],o=R[e+1];if(n.z===o.z\u0026\u0026bL(t,n,o)+u_\u003cO+E)return!1}return l.route.splice(0,l.route.length,...R),!0},FD=(t,e,n,o,i,r,s)=\u003e{if(!Number.isInteger(i)||i\u003c1||r\u003c=0)return!1;const a=kD(e,n,o,i);if(!a)return!1;const{route:c,spanStartIndex:l,spanEndIndex:d,start:h,end:u}=a,p=u.x-h.x,m=u.y-h.y,g=Math.hypot(p,m);if(g\u003c=h_)return!1;const f=-m/g*s*r,y=p/g*s*r,_={...h,x:h.x+f,y:h.y+y,pcb_port_id:void 0},b={...u,x:u.x+f,y:u.y+y,pcb_port_id:void 0};return!(!hL(_,t.bounds)||!hL(b,t.bounds))\u0026\u0026(c.route.splice(l,d-l+1,{...h},_,b,{...u}),!0)},BD=(t,e,n,o,i,r)=\u003e{if(!Number.isInteger(i)||i\u003c0)return!1;const s=kD(e,n,o,i);if(!s)return!1;const{route:a,spanStartIndex:c,spanEndIndex:l,start:d,end:h}=s;return!(Math.hypot(r.x-d.x,r.y-d.y)\u003c=h_||Math.hypot(r.x-h.x,r.y-h.y)\u003c=h_||!hL(r,t.bounds))\u0026\u0026(a.route.splice(c,l-c+1,{...d},{x:r.x,y:r.y,z:d.z},{...h}),!0)},jD=(t,e,n,o,i,r)=\u003e{if(r){const e=mD(t),n=mD(r);if(e!==n)return e\u003cn}const s=gD(t),a=fD(t);return s\u003cn||s===n\u0026\u0026a\u003co||s===n\u0026\u0026e\u003ci},$D=(t,e,n,o,i,r,s=!0,a=!1,c=!0,l=!1)=\u003e{let d=!1;const h=Gk(e),u=Zk(e);for(const p of n){const n=dD(p);if(!n)continue;let m=n;const g=p.pcb_via_ids,f=\"pcb_via_clearance_error\"===Fk(p),y=uD(p),_=Array.isArray(g)\u0026\u0026g.length\u003e0,b=!f\u0026\u0026!y\u0026\u0026_\u0026\u0026(\"string\"==typeof p.pcb_trace_id||Array.isArray(p.pcb_trace_ids)),x=l\u0026\u0026b;if(_\u0026\u0026!b){m=cL(t,p,n);const c=bD(p,o),l=g.length\u003e1?HL(h,n):void 0;if(l){const n=a\u0026\u0026\"pcb_via_clearance_error\"===Fk(p)\u0026\u0026\"same_net\"===p.pcb_via_pair_net_relation,o=s\u0026\u0026\"pcb_via_clearance_error\"===Fk(p);d=(n?JL(e,l[0],l[1],t,r):qL(e,l[0],l[1],t,r,.16*Math.abs(i),o))||d}else{const o=WL(h,n,c);o\u0026\u0026(d=GL(e,o,m,t)||d)}continue}const v=p.pcb_trace_id,S=bD(p,o);if(x\u0026\u0026void 0===S)continue;const I=Array.isArray(p.pcb_trace_ids)?p.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[];if(x\u0026\u0026\"string\"==typeof v\u0026\u0026void 0!==S\u0026\u0026I.includes(v)\u0026\u0026I.some(t=\u003et!==v\u0026\u0026!o.has(t))){const o=WL(h,n,S);if(o){d=GL(e,o,n,t)||d;continue}}const C=s\u0026\u0026!b?TD(p,o):void 0;if(C){const o=VL(u,n,C[0]),i=VL(u,n,C[1]);if(o\u0026\u0026i\u0026\u0026QL(e,o,i,t,r)){d=!0;continue}}const P=Bk(p),M=P\u0026\u0026void 0!==S?eD(t,e,S,n,r):void 0,N=P?M?.segment:VL(u,n,S);if(N){const o=P?M?.obstacle:sL(t,n);if(P\u0026\u0026!o)continue;m=P?o?.center??n:cL(t,p,n);const s=x?void 0:WL(h,n),a=\"pcb_via_trace_clearance_error\"===Fk(p),l=\"string\"==typeof p.pcb_trace_error_id?p.pcb_trace_error_id.toLowerCase():\"\",u=\"string\"==typeof p.message?p.message.toLowerCase():\"\",g=a||\"string\"==typeof p.pcb_via_id||Array.isArray(p.pcb_via_ids)||l.includes(\"_via_\")||u.includes(\"via\"),f=Array.isArray(p.pcb_port_ids)\u0026\u0026p.pcb_port_ids.length\u003e0;if(s\u0026\u0026!uk(s.rootConnectionName,N.rootConnectionName,r)\u0026\u0026(a||Math.hypot(s.x-n.x,s.y-n.y)\u003c.45)){if(KL(e,s,N,t,r,.3*Math.abs(i),1,c)\u0026\u0026(d=!0,g\u0026\u0026!f))continue}d=(void 0!==o\u0026\u0026(P||!pk(N.rootConnectionName,o,r)\u0026\u0026tD(o,N,t.layerCount))?XL(e,N,o,t,r,i):YL(e,N,m,t,i))||d}const w=x?void 0:WL(h,n);w\u0026\u0026Math.hypot(w.x-n.x,w.y-n.y)\u003c.35\u0026\u0026(d=GL(e,w,m,t)||d)}return d},YD=1e-6,XD=.006,VD=[1,.5,.25,.1,.05,.025],WD=(t,e)=\u003e(e.traceThickness??t.minTraceWidth)/2,HD=t=\u003et.minTraceToPadEdgeClearance??.1,GD=(t,e)=\u003ee.viaDiameter??t.minViaDiameter??.3,UD=(t,e)=\u003exe(t,e)\u003cYD,ZD=t=\u003e{const e=[],n=t=\u003e{e.some(e=\u003eUD(e,t))||e.push({x:t.x,y:t.y})};for(const e of t.vias)n(e);for(let e=0;e\u003ct.route.length-1;e+=1){const o=t.route[e],i=t.route[e+1];o\u0026\u0026i\u0026\u0026o.z!==i.z\u0026\u0026(UD(o,i)\u0026\u0026n(o))}return e},qD=t=\u003exe({x:0,y:0},t)\u003cYD?{x:0,y:0}:Fe({x:0,y:0},t),JD=(t,e)=\u003e{if(t.zLayers\u0026\u0026t.zLayers.length\u003e0)return t.zLayers;const n=Array.from({length:e},(t,e)=\u003ee).filter(n=\u003et.layers.includes(Vy(n,e)));return n.length\u003e0?n:Array.from({length:e},(t,e)=\u003ee)},KD=(t,e,n)=\u003euk(dk(t),dk(e),n)||uk(dk(t),e.connectionName,n)||uk(t.connectionName,dk(e),n)||uk(t.connectionName,e.connectionName,n),QD=(t,e,n)=\u003epk(dk(t),e,n)||pk(t.connectionName,e,n),tz=(t,e,n,o)=\u003e!n.pcb_port_id\u0026\u0026t.obstacles.some(i=\u003eQD(e,i,o)\u0026\u0026JD(i,t.layerCount).includes(n.z)\u0026\u0026((t,e)=\u003et.x\u003e=e.center.x-e.width/2-YD\u0026\u0026t.x\u003c=e.center.x+e.width/2+YD\u0026\u0026t.y\u003e=e.center.y-e.height/2-YD\u0026\u0026t.y\u003c=e.center.y+e.height/2+YD)(n,i)),ez=(t,e,n,o,i)=\u003e{if(!((t,e)=\u003et.zLayers.includes(e))(i,n.z))return Number.POSITIVE_INFINITY;const r=WD(t,e);return\"pad\"===i.kind?Le(n,o,i.obstacle)-(HD(t)+r+XD):be(i.center,n,o)-(HD(t)+r+i.diameter/2+XD)},nz=(t,e,n)=\u003e{const o=\"pad\"===n.kind?n.obstacle.center:n.center,i=ze(o,t,e);let r=qD({x:i.x-o.x,y:i.y-o.y});if(Math.abs(r.x)\u003cYD\u0026\u0026Math.abs(r.y)\u003cYD){const n=e.x-t.x,i=e.y-t.y,s=$e(t,e),a=qD({x:-i,y:n}),c={x:-a.x,y:-a.y};r=xe({x:s.x+a.x,y:s.y+a.y},o)\u003e=xe({x:s.x+c.x,y:s.y+c.y},o)?a:c}return r},oz=(t,e,n,o)=\u003e{if(n\u003c=0||n\u003e=e.route.length-1){const i=e.route[n];return!i||!tz(t,e,i,o)}const i=e.route[n];if(!i||i.insideJumperPad)return!0;const r=e.route[n-1],s=e.route[n+1];return!(!r||r.z===i.z)||(!(!s||s.z===i.z)||e.vias.some(t=\u003eUD(t,i)))},iz=(t,e,n)=\u003e{let o=0;for(let i=0;i\u003ce.route.length-1;i+=1){const r=e.route[i],s=e.route[i+1];if(r\u0026\u0026s\u0026\u0026r.z===s.z\u0026\u0026!UD(r,s))for(const i of n){const n=ez(t,e,r,s,i);if(!(n\u003e=0)\u0026\u0026(o+=n*n,\"pad\"===i.kind)){if(Le(r,s,i.obstacle)\u003cYD){o+=.01/(be(i.obstacle.center,r,s)+.01)}}}}return o},rz=(t,e,n,o)=\u003e{let i=0;for(let r=0;r\u003ce.route.length-1;r+=1){const s=e.route[r],a=e.route[r+1];if(s\u0026\u0026a\u0026\u0026s.z===a.z\u0026\u0026!UD(s,a))for(const r of n)if(!KD(e,r,o)){for(let n=0;n\u003cr.route.length-1;n+=1){const o=r.route[n],c=r.route[n+1];if(!o||!c||o.z!==s.z||c.z!==s.z||UD(o,c))continue;const l=Oe(s,a,o,c)-WD(t,e)-WD(t,r),d=HD(t)+XD-l;d\u003e0\u0026\u0026(i+=d*d)}for(const n of ZD(r)){const o=be(n,s,a)-WD(t,e)-GD(t,r)/2,c=HD(t)+XD-o;c\u003e0\u0026\u0026(i+=c*c)}}}return i},sz=(t,e,n,o,i)=\u003e{const r=e.route.map(()=\u003e({x:0,y:0}));for(let s=0;s\u003ce.route.length-1;s+=1){const a=e.route[s],c=e.route[s+1];if(a\u0026\u0026c\u0026\u0026a.z===c.z\u0026\u0026!UD(a,c)){for(const o of n){const n=ez(t,e,a,c,o);if(n\u003e=0)continue;const l=nz(a,c,o);if(Math.abs(l.x)\u003cYD\u0026\u0026Math.abs(l.y)\u003cYD)continue;const d=!oz(t,e,s,i),h=!oz(t,e,s+1,i);if(!d\u0026\u0026!h)continue;const u=-n,p=d\u0026\u0026h?.5:d?1:0,m=d\u0026\u0026h?.5:h?1:0;r[s].x+=l.x*u*p,r[s].y+=l.y*u*p,r[s+1].x+=l.x*u*m,r[s+1].y+=l.y*u*m}for(const n of o)if(!KD(e,n,i))for(let o=0;o\u003cn.route.length-1;o+=1){const l=n.route[o],d=n.route[o+1];if(!l||!d||l.z!==a.z||d.z!==a.z||UD(l,d))continue;const h=Oe(a,c,l,d)-WD(t,e)-WD(t,n),u=t.minTraceToPadEdgeClearance+XD-h;if(u\u003c=0)continue;const p=$e(a,c),m=ze(p,l,d);let g=qD({x:p.x-m.x,y:p.y-m.y});if(Math.abs(g.x)\u003cYD\u0026\u0026Math.abs(g.y)\u003cYD){const t=c.x-a.x,e=c.y-a.y;g=qD({x:-e,y:t})}const f=!oz(t,e,s,i),y=!oz(t,e,s+1,i);if(!f\u0026\u0026!y)continue;const _=f\u0026\u0026y?.5:f?1:0,b=f\u0026\u0026y?.5:y?1:0;r[s].x+=g.x*u*_,r[s].y+=g.y*u*_,r[s+1].x+=g.x*u*b,r[s+1].y+=g.y*u*b}}}return r},az=(t,e,n,o,i)=\u003e({...e,route:e.route.map((r,s)=\u003e{if(oz(t,e,s,i))return{...r};const a=((t,e)=\u003e{const n=xe({x:0,y:0},t);if(n\u003c=e||n\u003cYD)return t;const o=e/n;return{x:t.x*o,y:t.y*o}})(n[s]??{x:0,y:0},.5);return{...r,x:r.x+a.x*o,y:r.y+a.y*o}}),vias:e.vias.map(t=\u003e({...t})),jumpers:e.jumpers?[...e.jumpers]:void 0}),cz=(t,e)=\u003ee.route.every(e=\u003ee.x\u003e=t.bounds.minX-YD\u0026\u0026e.x\u003c=t.bounds.maxX+YD\u0026\u0026e.y\u003e=t.bounds.minY-YD\u0026\u0026e.y\u003c=t.bounds.maxY+YD),lz=(t,e,n,o,i)=\u003e{const r=((t,e,n,o)=\u003e{const i=[];for(const e of t.obstacles)e.isCopperPour||QD(n,e,o)||i.push({kind:\"pad\",obstacle:e,zLayers:JD(e,t.layerCount)});const r=Array.from({length:t.layerCount},(t,e)=\u003ee);for(const s of e)if(s!==n\u0026\u0026!KD(n,s,o))for(const e of ZD(s))i.push({kind:\"via\",center:{x:e.x,y:e.y},diameter:GD(t,s),zLayers:r,connectionName:s.connectionName,rootConnectionName:s.rootConnectionName});return i})(t,e,n,i),s=e.filter((t,e)=\u003ee!==o\u0026\u0026t!==n);let a=n,c=iz(t,a,r)+rz(t,a,s,i);for(let e=0;e\u003c160\u0026\u0026!(c\u003c=YD);e+=1){const e=sz(t,a,r,s,i);if(e.every(t=\u003exe(t,{x:0,y:0})\u003c1e-9))break;let n=null,o=c;for(const l of VD){const d=az(t,a,e,l,i),h=iz(t,d,r)+rz(t,d,s,i);if(h\u003cc-1e-6\u0026\u0026cz(t,d)){n=d,o=h;break}}if(!n)break;a=n,c=o}return a},dz=1e-6,hz=[1,.5,.25,.1,.05,.025],uz=(t,e)=\u003et.some(t=\u003ee.includes(t)),pz=(t,e,n,o)=\u003e(pk(t.rootConnectionName,n,o)||pk(e.connectionName,n,o))\u0026\u0026oL(t,n)\u003c=dz,mz=(t,e,n,o)=\u003e{const i=[],r=e[n.routeIndex];if(!r)return i;for(const e of t.obstacles){if(e.isCopperPour||pz(n,r,e,o))continue;const s=Qk(e,t.layerCount);uz(n.zLayers,s)\u0026\u0026i.push({obstacle:e})}return i},gz=(t,e,n)=\u003eoL(e,n.obstacle)-(e.radius+t.minViaEdgeToPadEdgeClearance+.006),fz=(t,e,n,o)=\u003eGk(e,t.minViaDiameter).filter(t=\u003et.routeIndex===n).reduce((n,i)=\u003en+((t,e,n,o)=\u003e{let i=0;for(const r of mz(t,e,n,o)){const e=gz(t,n,r);!(e\u003e=0)\u0026\u0026(i+=e*e,oL(n,r.obstacle)\u003cdz)\u0026\u0026(i+=.01/(xe(n,r.obstacle.center)+.01))}return i})(t,e,i,o),0),yz=(t,e,n,o)=\u003e{const i=e[n];if(!i)return[];const r=i.route.map(()=\u003e({x:0,y:0})),s=Gk(e,t.minViaDiameter).filter(t=\u003et.routeIndex===n);for(const n of s)if(n.movable)for(const i of mz(t,e,n,o)){const e=n.radius+t.minViaEdgeToPadEdgeClearance+.006,o=aL(n,i.obstacle,e);if(o)for(const t of n.pointIndexes)r[t].x+=o.direction.x*o.penetration,r[t].y+=o.direction.y*o.penetration}return r},_z=(t,e,n,o)=\u003e{const i=new Set(Gk([e],t.minViaDiameter).flatMap(t=\u003et.movable?t.pointIndexes:[]));return{...e,route:e.route.map((t,e)=\u003e{if(!i.has(e))return{...t};const r=((t,e)=\u003e{const n=xe({x:0,y:0},t);if(n\u003c=e||n\u003cdz)return t;const o=e/n;return{x:t.x*o,y:t.y*o}})(n[e]??{x:0,y:0},.5);return{...t,x:t.x+r.x*o,y:t.y+r.y*o}}),vias:e.vias.map(t=\u003e({...t})),jumpers:e.jumpers?[...e.jumpers]:void 0}},bz=(t,e)=\u003ee.route.every(e=\u003ee.x\u003e=t.bounds.minX-dz\u0026\u0026e.x\u003c=t.bounds.maxX+dz\u0026\u0026e.y\u003e=t.bounds.minY-dz\u0026\u0026e.y\u003c=t.bounds.maxY+dz),xz=(t,e,n,o,i)=\u003e{let r=n,s=fz(t,e,o,i);for(let n=0;n\u003c160\u0026\u0026!(s\u003c=dz);n+=1){const n=yz(t,e,o,i);if(n.every(t=\u003exe(t,{x:0,y:0})\u003c1e-9))break;let a=null,c=s;for(const l of hz){const d=_z(t,r,n,l),h=[...e];h[o]=d;const u=fz(t,h,o,i);if(u\u003cs-1e-6\u0026\u0026bz(t,d)){a=d,c=u;break}}if(!a)break;e[o]=a,r=a,s=c}return r},vz=[.2,.4,.8,1.2].flatMap(t=\u003e[.2,.3,.45,.6].flatMap(e=\u003e[-1,1].map(n=\u003e({halfSpan:t,offset:e,directionSign:n})))),Sz=vz.flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,...t}))),Iz=[1,-1].flatMap(t=\u003e[1,-1].flatMap(e=\u003e[!1,!0].flatMap(n=\u003e[0,1].map(o=\u003e({routeSide:o,normalDirectionSign:t,tangentDirectionSign:e,reverseEndpointOffsets:n}))))),Cz=[0,1].map(t=\u003e({kind:\"displacementChain\",routeSide:t})),Pz=[...Cz,...[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,halfSpan:.4,offset:1.2,directionSign:t}))),...[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"span\",routeSide:e,spanExpansion:3,offset:1.8,directionSign:t}))),...[{dx:-2.4,dy:-.4},{dx:-2.4,dy:.4},{dx:2.4,dy:-.4},{dx:2.4,dy:.4},{dx:-.4,dy:-2.4},{dx:-.4,dy:2.4},{dx:.4,dy:-2.4},{dx:.4,dy:2.4}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:2,...t}))),...[{dx:-.17,dy:0},{dx:.17,dy:0},{dx:0,dy:-.17},{dx:0,dy:.17}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:0,...t}))),...Sz],Mz=[0,1,2],Nz=class extends kt{srj;inputHdRoutes;guardedInputHdRoutes;connMap;effort;drcEvaluator;referenceDrcEvaluator;autoroutingDrcEngine;viaHoleDiameter;configuredMaxIterations;enableBroadFallback;enableLargeBoardBroadFallback;enableTargetedErrorSweep;enablePostSolveClearanceRelaxation;enableSafeTraceLayerMoves;enableViaInPadLayerMoves;enableTraceViaOwnerTargeting;outputHdRoutes;initialDrcIssueCount;initialRepairDrcIssueCount;initialLowCountErrorsHaveMovableTraces=!1;broadForceAccepted=!1;targetedForceAccepted=!1;candidateAttempts=0;viaInPadCandidateAttempts=0;viaInPadCandidatesAccepted=0;padTopologyErrorCursor=0;safeTraceLayerCursorByErrorId=new Map;traceLayerCorridorCursorByErrorId=new Map;tracePairDetourCursorByErrorId=new Map;errorCursor=0;stalledIterations=0;bestDrcIssueCountSeen;bestDrcIssueScoreSeen;lastDrcCountImprovementCheckIteration=0;drcCountPlateauChecks=0;largeBoardBroadFallbackMisses=0;outputSnapshot;legacyCleanCheckpoint;viaPadRepairRolledBack=!1;referenceInputDrcIssueCount;referenceCandidateDrcIssueCount;referenceCandidateRolledBack=!1;referenceInputSnapshot;inputSnapshot;constructor(t){if(super(),this.srj=t.srj,this.inputHdRoutes=t.hdRoutes,this.guardedInputHdRoutes=aD(kk(t.hdRoutes)),this.connMap=t.connMap,this.effort=t.effort??1,this.drcEvaluator=t.drcEvaluator,this.referenceDrcEvaluator=t.referenceDrcEvaluator,this.autoroutingDrcEngine=t.autoroutingDrcEngine??(t.drcEvaluator?void 0:new s_(t.srj,{connMap:t.connMap,traceClearance:t.srj.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:t.srj.minTraceToPadEdgeClearance??rk.viaClearance,includeTraceViaOwnerMetadata:t.enableTraceViaOwnerTargeting??!1})),void 0!==t.viaHoleDiameter\u0026\u0026(!Number.isFinite(t.viaHoleDiameter)||t.viaHoleDiameter\u003c=0))throw new Error(\"viaHoleDiameter must be a positive finite number\");this.viaHoleDiameter=t.viaHoleDiameter,this.configuredMaxIterations=t.maxIterations,this.enableBroadFallback=t.enableBroadFallback??!0,this.enableLargeBoardBroadFallback=t.enableLargeBoardBroadFallback??!0,this.enableTargetedErrorSweep=t.enableTargetedErrorSweep??!1,this.enablePostSolveClearanceRelaxation=t.enablePostSolveClearanceRelaxation??!0,this.enableSafeTraceLayerMoves=t.enableSafeTraceLayerMoves??!1,this.enableViaInPadLayerMoves=t.enableViaInPadLayerMoves??!1,this.enableTraceViaOwnerTargeting=t.enableTraceViaOwnerTargeting??!1,this.outputHdRoutes=t.hdRoutes,this.referenceDrcEvaluator\u0026\u0026(this.referenceInputSnapshot=this.getReferenceDrcSnapshot(this.inputHdRoutes)),this.MAX_ITERATIONS=this.configuredMaxIterations??__(this.effort)}getConstructorParams(){return[{srj:this.srj,hdRoutes:this.inputHdRoutes,connMap:this.connMap,effort:this.effort,drcEvaluator:this.drcEvaluator,referenceDrcEvaluator:this.referenceDrcEvaluator,autoroutingDrcEngine:this.autoroutingDrcEngine,viaHoleDiameter:this.viaHoleDiameter,maxIterations:this.configuredMaxIterations,enableBroadFallback:this.enableBroadFallback,enableLargeBoardBroadFallback:this.enableLargeBoardBroadFallback,enableTargetedErrorSweep:this.enableTargetedErrorSweep,enablePostSolveClearanceRelaxation:this.enablePostSolveClearanceRelaxation,enableSafeTraceLayerMoves:this.enableSafeTraceLayerMoves,enableViaInPadLayerMoves:this.enableViaInPadLayerMoves,enableTraceViaOwnerTargeting:this.enableTraceViaOwnerTargeting}]}updateStats(t){this.stats={initialDrcIssueCount:this.initialDrcIssueCount??t.count,finalDrcIssueCount:t.count,globalDrcForceImproveMaxIterations:this.MAX_ITERATIONS,globalDrcForceImproveBroadForceAccepted:this.broadForceAccepted,globalDrcForceImproveTargetedForceAccepted:this.targetedForceAccepted,globalDrcForceImproveCandidateAttempts:this.candidateAttempts,globalDrcForceImproveViaInPadCandidateAttempts:this.viaInPadCandidateAttempts,globalDrcForceImproveViaInPadCandidatesAccepted:this.viaInPadCandidatesAccepted,globalDrcForceImproveStalledIterations:this.stalledIterations,globalDrcForceImproveBestDrcIssueCountSeen:this.bestDrcIssueCountSeen??t.count,globalDrcForceImproveBestDrcIssueScoreSeen:this.bestDrcIssueScoreSeen??t.issueScore,globalDrcForceImproveDrcCountPlateauChecks:this.drcCountPlateauChecks,globalDrcForceImproveLargeBoardBroadFallbackMisses:this.largeBoardBroadFallbackMisses,globalDrcForceImproveViaPadRepairRolledBack:this.viaPadRepairRolledBack,globalDrcForceImproveReferenceInputDrcIssueCount:this.referenceInputDrcIssueCount,globalDrcForceImproveReferenceCandidateDrcIssueCount:this.referenceCandidateDrcIssueCount,globalDrcForceImproveReferenceCandidateRolledBack:this.referenceCandidateRolledBack}}finishAtLegacyCleanCheckpoint(){const t=this.legacyCleanCheckpoint;return!!t\u0026\u0026(this.outputHdRoutes=t.routes,this.outputSnapshot=t.snapshot,this.viaPadRepairRolledBack=!0,this.updateStats(t.snapshot),this.solved=!0,!0)}increaseMaxIterationsForDrcIssueCount(t){void 0===this.configuredMaxIterations?this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,((t,e)=\u003eMath.max(__(e),Math.ceil(t*d_*Math.max(1,e))))(t,this.effort),((t,e)=\u003et\u003e120\u0026\u0026e\u003e0?192:48)(this.inputHdRoutes.length,t)):this.MAX_ITERATIONS=this.configuredMaxIterations}getSnapshot(t){return(this.initialLowCountErrorsHaveMovableTraces?Hk:Wk)(this.srj,t,this.drcEvaluator,this.connMap,this.autoroutingDrcEngine)}getReferenceDrcSnapshot(t){const e={traces:[],srj:this.srj,routes:t,hdRoutes:t},n=this.referenceDrcEvaluator?.getCachedResult?.(e);if(n){const t=Array.isArray(n)?n:n.errors;return{errors:t,count:t.length}}return Wk(this.srj,t,this.referenceDrcEvaluator,this.connMap,this.autoroutingDrcEngine)}getViaIssueCount(t){return hD(t)}getRepairIssueCount(t){return gD(t)}getRepairIssueScore(t){return fD(t)}acceptSolvedRoutes(t,e){const n=this.enablePostSolveClearanceRelaxation?((t,e,n)=\u003e{if(void 0===t.minTraceToPadEdgeClearance||t.minTraceToPadEdgeClearance\u003c=0)return e;let o=!1;const i=kk(e);for(let e=0;e\u003c4;e+=1)for(let e=0;e\u003ci.length;e+=1){const r=i[e];if(!r)continue;const s=lz(t,i,r,e,n);s!==r\u0026\u0026(i[e]=s,o=!0)}return o?i:e})(this.srj,t,this.connMap):t,o=this.enablePostSolveClearanceRelaxation?((t,e,n)=\u003e{if(void 0===t.minViaEdgeToPadEdgeClearance||t.minViaEdgeToPadEdgeClearance\u003c=0)return e;let o=!1;const i=kk(e);for(let e=0;e\u003c4;e+=1)for(let e=0;e\u003ci.length;e+=1){const r=i[e];if(!r)continue;const s=xz(t,i,r,e,n);s!==r\u0026\u0026(i[e]=s,o=!0)}return o?aD(i):e})(this.srj,n,this.connMap):t,i=o===t?e:this.getSnapshot(o),r=i.count\u003ce.count||i.count===e.count\u0026\u0026i.issueScore\u003c=e.issueScore;let s=r?o:t,a=r?i:e;const c=this.inputSnapshot??this.getSnapshot(this.guardedInputHdRoutes);if(this.referenceDrcEvaluator){const t=this.referenceInputSnapshot,e=this.getReferenceDrcSnapshot(s);this.referenceInputDrcIssueCount=t.count,this.referenceCandidateDrcIssueCount=e.count,e.count\u003et.count\u0026\u0026(s=this.guardedInputHdRoutes,a=c,this.referenceCandidateRolledBack=!0)}this.outputHdRoutes=s,this.outputSnapshot=a,this.stalledIterations=0,this.updateStats(a),this.solved=!0}updateDrcCountPlateauState(t){const e=this.getRepairIssueCount(t),n=this.getRepairIssueScore(t);this.bestDrcIssueCountSeen??=e,this.bestDrcIssueScoreSeen??=n;const o=this.initialRepairDrcIssueCount??e,i=this.inputHdRoutes.length\u003e120\u0026\u0026o\u003e0;if((o\u003e=20||i)\u0026\u0026this.iterations\u003c192)return(e\u003cthis.bestDrcIssueCountSeen||e===this.bestDrcIssueCountSeen\u0026\u0026n\u003cthis.bestDrcIssueScoreSeen)\u0026\u0026(this.bestDrcIssueCountSeen=e,this.bestDrcIssueScoreSeen=n),void(i\u0026\u0026this.largeBoardBroadFallbackMisses\u003e=2\u0026\u0026(this.solved=!0));const r=(t=\u003et\u003e=20?8:t\u003c=2?1:2)(o);if(!(this.iterations-this.lastDrcCountImprovementCheckIteration\u003cr)){if(this.lastDrcCountImprovementCheckIteration=this.iterations,e\u003cthis.bestDrcIssueCountSeen||e===this.bestDrcIssueCountSeen\u0026\u0026n\u003cthis.bestDrcIssueScoreSeen)return this.bestDrcIssueCountSeen=e,this.bestDrcIssueScoreSeen=n,void(this.drcCountPlateauChecks=0);this.drcCountPlateauChecks+=1,this.drcCountPlateauChecks\u003e=2\u0026\u0026(this.solved=!0)}}_step(){let t=this.outputHdRoutes,e=this.outputSnapshot??this.getSnapshot(t);const n=mD(e);if(this.legacyCleanCheckpoint\u0026\u0026n\u003e0)return void this.finishAtLegacyCleanCheckpoint();if(!this.legacyCleanCheckpoint\u0026\u00260===n\u0026\u0026e.errors.some(uD)\u0026\u0026(this.legacyCleanCheckpoint={routes:aD(kk(t)),snapshot:e}),void 0===this.initialDrcIssueCount){this.inputSnapshot=e,this.initialDrcIssueCount=e.count,this.initialRepairDrcIssueCount=this.getRepairIssueCount(e);const n=_D(e.errors);this.initialLowCountErrorsHaveMovableTraces=this.initialRepairDrcIssueCount\u003e0\u0026\u0026this.initialRepairDrcIssueCount\u003c=3\u0026\u0026n.every(t=\u003evoid 0!==bD(t,e.traceRouteIndexById)),this.initialLowCountErrorsHaveMovableTraces\u0026\u0026(e=this.getSnapshot(t)),this.bestDrcIssueCountSeen=this.getRepairIssueCount(e),this.bestDrcIssueScoreSeen=this.getRepairIssueScore(e),this.increaseMaxIterationsForDrcIssueCount(this.getRepairIssueCount(e))}if(0===e.count)return void this.acceptSolvedRoutes(t,e);let o=this.getRepairIssueCount(e),i=this.getRepairIssueScore(e),r=this.getViaIssueCount(e);const s=e.errors.filter(t=\u003eBoolean(dD(t)));if(0===s.length)return void this.acceptSolvedRoutes(t,e);const a=(c=this.effort,Math.max(1,Math.round(3*Math.max(1,c))));var c;let l=0,d=0,h=!1,u=!1,p=!1;const m=_D(s),g=this.enableTargetedErrorSweep?m.find(t=\u003e\"pcb_via_clearance_error\"===t.type\u0026\u0026\"same_net\"===t.pcb_via_pair_net_relation):void 0,f=this.enableTargetedErrorSweep\u0026\u0026(this.iterations-1)%8==0,y=g??(f?m.find(t=\u003e\"pcb_via_clearance_error\"===t.type):void 0),_=y?[y,...m.filter(t=\u003et!==y)]:m,b=Math.min(_.length,Math.max(1,Math.ceil(this.effort))),x=y?0:this.errorCursor%_.length,v=this.enableTargetedErrorSweep?((t,e)=\u003e{const n=Math.max(2,Math.round(12*Math.max(1,e)));return t.filter(t=\u003e\"pcb_trace_error\"===Fk(t)).slice(0,n)})(s,this.effort):[],S=o\u003c=1||this.initialLowCountErrorsHaveMovableTraces,I=!this.initialLowCountErrorsHaveMovableTraces\u0026\u0026o\u003c=8\u0026\u0026this.srj.layerCount\u003e1,C=y?[]:s.filter(t=\u003e\"pcb_pad_trace_clearance_error\"===t.type||(this.enableSafeTraceLayerMoves||S||I)\u0026\u0026\"pcb_trace_error\"===t.type),P=C.map((t,e)=\u003eC[(this.padTopologyErrorCursor+e)%C.length]);for(const n of this.enableSafeTraceLayerMoves||this.enableViaInPadLayerMoves?P:[]){const s=!this.enableSafeTraceLayerMoves||d\u003e=a,c=!this.enableViaInPadLayerMoves||l\u003e=a;if(u||s\u0026\u0026c)break;let p;this.padTopologyErrorCursor=(C.indexOf(n)+1)%C.length;const m=\"string\"==typeof n.pcb_trace_error_id?n.pcb_trace_error_id:\"string\"==typeof n.pcb_trace_id?n.pcb_trace_id:void 0,g=bD(n,e.traceRouteIndexById),f=TD(n,e.traceRouteIndexById);if(this.enableTraceViaOwnerTargeting\u0026\u0026void 0!==g\u0026\u0026Array.isArray(n.pcb_via_ids)\u0026\u00261===n.pcb_via_ids.length\u0026\u0026l\u003ca){const o=kk(t);if(AD(this.srj,o,n,e.traceRouteIndexById,g,this.connMap)){const t=aD(o),n=this.getSnapshot(t),i=this.getViaIssueCount(n);l+=1,this.candidateAttempts+=1,i\u003c=r\u0026\u0026yD(n,e)\u0026\u0026(p={routes:t,snapshot:n,viaIssueCount:i,usesViaInPad:!1})}}if(this.enableSafeTraceLayerMoves\u0026\u0026void 0!==g){const o=f??[g],i=o.length*this.srj.layerCount*Mz.length,s=o.length*this.srj.layerCount*ID,c=i+s,l=Bk(n),h=l?0:i,u=l?s:0;let y=m?this.safeTraceLayerCursorByErrorId.get(m)??0:0,_=0;for(;d\u003ca\u0026\u0026_\u003cc;){const i=y;y=(y+1)%c,_+=1;const a=i\u003e=h\u0026\u0026i\u003ch+s,l=i-(a?h:u),m=l%o.length,g=Math.floor(l/o.length),f=g%this.srj.layerCount,b=a?\"full\":Mz[Math.floor(g/this.srj.layerCount)%Mz.length],x=a?Math.floor(g/this.srj.layerCount):0,v=o[m];let S=!1;for(const o of[!1,!0]){const i=Lk(t,[v]);if(!MD(this.srj,i,n,v,f,b,this.connMap,x,o))continue;const s=cD(i,[v]);S=!0,this.candidateAttempts+=1;const a=this.getSnapshot(s),c=this.getViaIssueCount(a),l=p?.snapshot??e;c\u003c=(p?.viaIssueCount??r)\u0026\u0026(yD(a,l)||void 0!==p\u0026\u0026gD(a)===gD(l)\u0026\u0026a.count\u003cl.count)\u0026\u0026(p={routes:s,snapshot:a,viaIssueCount:c,usesViaInPad:!1})}S\u0026\u0026(d+=1)}m\u0026\u0026this.safeTraceLayerCursorByErrorId.set(m,y)}if(this.enableSafeTraceLayerMoves\u0026\u0026I\u0026\u0026m\u0026\u0026f){let o=this.traceLayerCorridorCursorByErrorId.get(m)??0,i=0;for(;l\u003ca\u0026\u0026i\u003cIz.length;){const s=Iz[o%Iz.length];o+=1,i+=1;const a=f[s.routeSide],c=t[a]?.route[0]?.z;if(void 0===c)continue;const d=(c+1)%this.srj.layerCount,h=Lk(t,[a]);if(!zD(this.srj,h,n,a,d,s.normalDirectionSign,s.tangentDirectionSign,s.reverseEndpointOffsets))continue;const u=cD(h,[a]);l+=1,this.candidateAttempts+=1;const m=this.getSnapshot(u),g=this.getViaIssueCount(m),y=p?.snapshot??e;g\u003c=(p?.viaIssueCount??r)\u0026\u0026yD(m,y)\u0026\u0026(p={routes:u,snapshot:m,viaIssueCount:g,usesViaInPad:!1})}this.traceLayerCorridorCursorByErrorId.set(m,o)}if(this.enableSafeTraceLayerMoves\u0026\u0026m\u0026\u0026(this.initialLowCountErrorsHaveMovableTraces\u0026\u0026(f||void 0!==g)||!this.initialLowCountErrorsHaveMovableTraces\u0026\u0026f)){const s=this.initialLowCountErrorsHaveMovableTraces?Pz:S?[...Cz,...Sz]:Cz,c=f??[g];let d=this.tracePairDetourCursorByErrorId.get(m)??0,u=0;for(;l\u003ca\u0026\u0026u\u003cs.length;){const m=s[d%s.length];d+=1,u+=1;const g=c[m.routeSide];if(void 0===g)continue;const f=this.initialLowCountErrorsHaveMovableTraces\u0026\u0026n.worst_contact_center?{...n,center:n.worst_contact_center,message:n.worst_contact_message??n.message,actual_clearance:n.worst_actual_clearance??n.actual_clearance}:n;if(\"displacementChain\"===m.kind){const n=kk(t),s=RD(this.srj,n,f,e.traceRouteIndexById,m.routeSide);if(!s)continue;h=!0,l+=1,this.candidateAttempts+=1;let c=aD(n),d=this.getSnapshot(c),u=this.getViaIssueCount(d),g=this.getRepairIssueCount(d);if(g\u003e0\u0026\u0026l\u003ca){const t=kk(c);let e=!1;for(const n of d.errors)e=AD(this.srj,t,n,d.traceRouteIndexById,s.movedRouteIndex,this.connMap)||e;if(e){l+=1,this.candidateAttempts+=1;const e=aD(t),n=this.getSnapshot(e),o=this.getViaIssueCount(n);jD(n,o,g,this.getRepairIssueScore(d),u,d)\u0026\u0026(c=e,d=n,u=o,g=this.getRepairIssueCount(d))}}const y=p?this.getRepairIssueCount(p.snapshot):o,_=p?this.getRepairIssueScore(p.snapshot):i,b=p?.viaIssueCount??r;if(u\u003c=b\u0026\u0026jD(d,u,y,_,b,p?.snapshot??e)\u0026\u0026(p={routes:c,snapshot:d,viaIssueCount:u,usesViaInPad:!1}),0===g)break;continue}const y=Lk(t,[g]);if(!(\"segment\"===m.kind?DD(y,f,g,m.halfSpan,m.offset,m.directionSign):\"span\"===m.kind?FD(this.srj,y,f,g,m.spanExpansion,m.offset,m.directionSign):BD(this.srj,y,f,g,m.spanExpansion,{x:f.center.x+m.dx,y:f.center.y+m.dy})))continue;const _=cD(y,[g]);h=!0,l+=1,this.candidateAttempts+=1;const b=this.getSnapshot(_),x=this.getViaIssueCount(b),v=p?this.getRepairIssueCount(p.snapshot):o,S=p?this.getRepairIssueScore(p.snapshot):i,I=p?.viaIssueCount??r;(this.initialLowCountErrorsHaveMovableTraces?jD(b,x,v,S,I,p?.snapshot??e):x\u003c=I\u0026\u0026yD(b,p?.snapshot??e))\u0026\u0026(p={routes:_,snapshot:b,viaIssueCount:x,usesViaInPad:!1})}this.tracePairDetourCursorByErrorId.set(m,d)}for(const s of this.enableViaInPadLayerMoves?[\"start\",\"end\"]:[]){if(l\u003e=a)break;if(void 0===g)break;const c=Lk(t,[g]);if(!wD(this.srj,c,n,e.traceRouteIndexById,s,this.connMap,this.viaHoleDiameter))continue;const d=cD(c,[g]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const h=this.getSnapshot(d),u=this.getViaIssueCount(h),m=p?this.getRepairIssueCount(p.snapshot):o,f=p?this.getRepairIssueScore(p.snapshot):i;jD(h,u,m,f,p?.viaIssueCount??r,p?.snapshot??e)\u0026\u0026(p={routes:d,snapshot:h,viaIssueCount:u,usesViaInPad:!0})}const y=this.enableViaInPadLayerMoves?this.srj.layerCount:0;for(let s=0;s\u003cy\u0026\u0026!(l\u003e=a)\u0026\u0026void 0!==g;s+=1){const a=Lk(t,[g]);if(!ND(this.srj,a,n,e.traceRouteIndexById,s,this.connMap,this.viaHoleDiameter))continue;const c=cD(a,[g]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const d=this.getSnapshot(c),h=this.getViaIssueCount(d),u=p?this.getRepairIssueCount(p.snapshot):o,m=p?this.getRepairIssueScore(p.snapshot):i;jD(d,h,u,m,p?.viaIssueCount??r,p?.snapshot??e)\u0026\u0026(p={routes:c,snapshot:d,viaIssueCount:h,usesViaInPad:!0})}if(this.enableViaInPadLayerMoves\u0026\u0026S\u0026\u0026f){const s=this.iterations%2==0?[0,1]:[1,0],c=this.iterations%3;for(const d of s)for(let s=0;s\u003cthis.srj.layerCount\u0026\u0026!(l\u003e=a);s+=1){const a=f[d],h=Lk(t,[a]);if(!LD(this.srj,h,n,e.traceRouteIndexById,d,s,c,this.connMap,this.viaHoleDiameter))continue;const u=cD(h,[a]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const m=this.getSnapshot(u),g=this.getViaIssueCount(m),y=p?this.getRepairIssueCount(p.snapshot):o,_=p?this.getRepairIssueScore(p.snapshot):i;jD(m,g,y,_,p?.viaIssueCount??r,p?.snapshot??e)\u0026\u0026(p={routes:u,snapshot:m,viaIssueCount:g,usesViaInPad:!0})}}p\u0026\u0026(t=p.routes,e=p.snapshot,o=this.getRepairIssueCount(e),i=this.getRepairIssueScore(e),r=p.viaIssueCount,this.targetedForceAccepted=!0,p.usesViaInPad\u0026\u0026(this.viaInPadCandidatesAccepted+=1),u=!0)}if(!u\u0026\u0026v.length\u003e=2){const n=kk(t);let s=!1;for(const t of v)s=$D(this.srj,n,[t],e.traceRouteIndexById,1,this.connMap,!0,this.enableTargetedErrorSweep,!1,this.enableTraceViaOwnerTargeting)||s;if(s){const s=aD(n);l+=1,this.candidateAttempts+=1;const a=this.getSnapshot(s),c=this.getViaIssueCount(a);if(jD(a,c,o,i,r,e)\u0026\u0026(t=s,e=a,o=this.getRepairIssueCount(a),i=this.getRepairIssueScore(a),r=c,this.targetedForceAccepted=!0,u=!0,0===a.count))return void this.acceptSolvedRoutes(t,e)}}for(let n=0;n\u003cb\u0026\u0026l\u003ca\u0026\u0026!u;n+=1){const s=(x+n)%_.length,c=_[s];if(!c)continue;this.errorCursor=(s+1)%_.length;const d=1===o;for(const n of b_(this.effort)){if(l\u003e=a)break;const s=kk(t);if(!$D(this.srj,s,[c],e.traceRouteIndexById,n,this.connMap,!0,this.enableTargetedErrorSweep,d,this.enableTraceViaOwnerTargeting))continue;const h=aD(s);l+=1,this.candidateAttempts+=1;const p=this.getSnapshot(h),m=this.getViaIssueCount(p);if(jD(p,m,o,i,r,e)){if(t=h,e=p,o=this.getRepairIssueCount(p),i=this.getRepairIssueScore(p),r=m,this.targetedForceAccepted=!0,u=!0,0===p.count)return void this.acceptSolvedRoutes(t,e);break}}if(u)break}const M=t.length\u003c=120,N=(w=s.length,Math.max(16,Math.min(64,2*w)));var w;const T=this.enableLargeBoardBroadFallback\u0026\u0026this.MAX_ITERATIONS\u003e=192\u0026\u0026!M\u0026\u0026this.stalledIterations\u003e0\u0026\u0026this.stalledIterations%N===0;if(this.enableBroadFallback\u0026\u0026!u\u0026\u0026(M||this.effort\u003e=2\u0026\u0026this.stalledIterations\u003e=2||T)){p=T;for(const n of[1,2]){const s=iD(this.srj,t,this.effort,n,this.connMap,void 0===this.drcEvaluator,!1);if(s===t)continue;const a=this.getSnapshot(s),c=this.getViaIssueCount(a);if(jD(a,c,o,i,r,e)\u0026\u0026(t=s,e=a,o=this.getRepairIssueCount(a),i=this.getRepairIssueScore(a),r=c,this.broadForceAccepted=!0,u=!0,0===a.count))return void this.acceptSolvedRoutes(t,e)}}u?this.largeBoardBroadFallbackMisses=0:p\u0026\u0026(this.largeBoardBroadFallbackMisses+=1),this.outputHdRoutes=t,this.outputSnapshot=e,this.stalledIterations=u?0:this.stalledIterations+1,h||this.updateDrcCountPlateauState(e),this.updateStats(e),(this.solved||0===o)\u0026\u0026this.acceptSolvedRoutes(t,e)}tryFinalAcceptance(){const t=this.outputSnapshot??this.getSnapshot(this.outputHdRoutes);this.legacyCleanCheckpoint\u0026\u0026mD(t)\u003e0\u0026\u0026this.finishAtLegacyCleanCheckpoint()||this.acceptSolvedRoutes(this.outputHdRoutes,t)}getOutput(){return this.outputHdRoutes}visualize(){return super.visualize()}preview(){return this.visualize()}},wz=class extends kt{params;inputHdRoutes;guardedInputHdRoutes;broadMaxIterations;broadPassMultiplier;autoroutingDrcEngine;legacyDrcEvaluator;outputHdRoutes;phase=\"start\";inputSnapshot;baselineSolver;baselineSnapshot;broadInputSnapshot;broadSnapshot;broadSolver;safeTraceLayerInputRoutes;safeTraceLayerInputSnapshot;safeTraceLayerSolver;safeTraceLayerPhaseAccepted=!1;mixedSafeTraceLayerSolver;mixedSafeTraceLayerPhaseAccepted=!1;legacySafeTraceLayerRoutes;legacySafeTraceLayerSnapshot;legacySafeTraceLayerSelectedSolver;viaInPadSolver;portfolioSelectedSolver;selectedSolver;referenceInputDrcIssueCount;referenceCandidateDrcIssueCount;referenceCandidateRolledBack=!1;mixedReferenceInputDrcIssueCount;mixedReferenceCandidateDrcIssueCount;referenceInputSnapshot;constructor(t){if(super(),!Number.isFinite(t.broadPassMultiplier))throw new Error(\"broadPassMultiplier must be a finite number\");if(t.broadPassMultiplier\u003c=0)throw new Error(\"broadPassMultiplier must be greater than zero\");if(!Number.isInteger(t.broadMaxIterations))throw new Error(\"broadMaxIterations must be an integer\");if(t.broadMaxIterations\u003c=0)throw new Error(\"broadMaxIterations must be greater than zero\");if(void 0!==t.viaInPadMaxIterations\u0026\u0026!Number.isInteger(t.viaInPadMaxIterations))throw new Error(\"viaInPadMaxIterations must be an integer\");if(void 0!==t.viaInPadMaxIterations\u0026\u0026t.viaInPadMaxIterations\u003c=0)throw new Error(\"viaInPadMaxIterations must be greater than zero\");this.autoroutingDrcEngine=t.autoroutingDrcEngine??(t.drcEvaluator?void 0:new s_(t.srj,{connMap:t.connMap,traceClearance:t.srj.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:t.srj.minTraceToPadEdgeClearance??rk.viaClearance,includeTraceViaOwnerMetadata:t.enableTraceViaOwnerTargeting??!1})),this.legacyDrcEvaluator=e=\u003e{const n=t.drcEvaluator?.evaluateLegacy??t.drcEvaluator,o=n?n(e):this.autoroutingDrcEngine.evaluateLegacy(e.traces),i=Array.isArray(o)?o:o.errors,r=Array.isArray(o)?o:o.errorsWithCenters??o.errors;return{errors:i.filter(t=\u003e!uD(t)),errorsWithCenters:r.filter(t=\u003e!uD(t))}},this.params={...t,autoroutingDrcEngine:this.autoroutingDrcEngine},this.inputHdRoutes=t.hdRoutes,this.guardedInputHdRoutes=aD(kk(t.hdRoutes)),this.broadMaxIterations=t.broadMaxIterations,this.broadPassMultiplier=t.broadPassMultiplier,this.outputHdRoutes=t.hdRoutes,this.params.referenceDrcEvaluator\u0026\u0026(this.referenceInputSnapshot=this.getReferenceDrcSnapshot(this.inputHdRoutes))}getConstructorParams(){return[{...this.params,hdRoutes:this.inputHdRoutes}]}stepBranch(t,e){if(this.activeSubSolver=t,t.step(),t.failed)throw new Error(`${e} DRC repair branch failed: ${t.error}`)}getReferenceDrcSnapshot(t){const e={traces:[],srj:this.params.srj,routes:t,hdRoutes:t},n=this.params.referenceDrcEvaluator?.getCachedResult?.(e);if(n){const t=Array.isArray(n)?n:n.errors;return{errors:t,count:t.length}}return Wk(this.params.srj,t,this.params.referenceDrcEvaluator,this.params.connMap,this.autoroutingDrcEngine)}finishWithOutput(t,e,n){let o=t,i=e;if(this.params.referenceDrcEvaluator){const t=this.referenceInputSnapshot,e=this.getReferenceDrcSnapshot(o);this.referenceInputDrcIssueCount=t.count,this.referenceCandidateDrcIssueCount=e.count,(e.count\u003et.count||e.count===t.count\u0026\u0026((t,e)=\u003e{const n=new Set(e.map(pD));return t.some(t=\u003e!n.has(pD(t)))})(e.errors,t.errors))\u0026\u0026(o=this.guardedInputHdRoutes,i=this.inputSnapshot,this.referenceCandidateRolledBack=!0)}this.outputHdRoutes=o,this.selectedSolver=n,this.activeSubSolver=null,this.phase=\"done\",this.progress=1,this.stats={...this.portfolioSelectedSolver?.stats??{},...n?.stats??{},finalDrcIssueCount:i.count,drcBranchPortfolioInitialDrcIssueCount:this.inputSnapshot?.count??e.count,drcBranchPortfolioBaselineDrcIssueCount:this.baselineSnapshot?.count??e.count,drcBranchPortfolioBroadInitialDrcIssueCount:this.broadInputSnapshot?.count,drcBranchPortfolioBroadFinalDrcIssueCount:this.broadSnapshot?.count,drcBranchPortfolioBroadMaxIterations:this.broadMaxIterations,drcBranchPortfolioBroadBranchAttempted:Boolean(this.broadSolver),drcBranchPortfolioBroadBranchAccepted:void 0!==this.portfolioSelectedSolver\u0026\u0026this.portfolioSelectedSolver===this.broadSolver,drcBranchPortfolioSafeTraceLayerPhaseAttempted:Boolean(this.safeTraceLayerSolver),drcBranchPortfolioSafeTraceLayerPhaseAccepted:this.safeTraceLayerPhaseAccepted,drcBranchPortfolioMixedSafeTraceLayerPhaseAttempted:Boolean(this.mixedSafeTraceLayerSolver),drcBranchPortfolioMixedSafeTraceLayerPhaseAccepted:this.mixedSafeTraceLayerPhaseAccepted,drcBranchPortfolioViaInPadPhaseAttempted:Boolean(this.viaInPadSolver),drcBranchPortfolioViaInPadMaxIterations:this.params.viaInPadMaxIterations,drcBranchPortfolioFinalNonViaPadDrcIssueCount:mD(i),drcBranchPortfolioReferenceInputDrcIssueCount:this.referenceInputDrcIssueCount,drcBranchPortfolioReferenceCandidateDrcIssueCount:this.referenceCandidateDrcIssueCount,drcBranchPortfolioReferenceCandidateRolledBack:this.referenceCandidateRolledBack,drcBranchPortfolioMixedReferenceInputDrcIssueCount:this.mixedReferenceInputDrcIssueCount,drcBranchPortfolioMixedReferenceCandidateDrcIssueCount:this.mixedReferenceCandidateDrcIssueCount},this.solved=!0}startBaselineBranch(){this.baselineSolver=new Nz({...this.params,hdRoutes:this.inputHdRoutes,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.baselineSolver,this.phase=\"baseline\"}startSafeTraceLayerPhase(t,e,n){this.portfolioSelectedSolver=n,this.params.enableSafeTraceLayerMoves?(this.safeTraceLayerInputRoutes=t,this.safeTraceLayerInputSnapshot=e,this.safeTraceLayerSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.safeTraceLayerSolver,this.phase=\"safeTraceLayer\"):this.startViaInPadPhase(t,e,n)}startViaInPadPhase(t,e,n){this.portfolioSelectedSolver=n;const o=this.params.enableViaInPadLayerMoves\u0026\u0026void 0!==this.params.viaInPadDrcEvaluator;e.errors.some(uD)||o?(this.viaInPadSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.params.viaInPadDrcEvaluator??this.params.drcEvaluator,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:this.params.enableViaInPadLayerMoves}),this.activeSubSolver=this.viaInPadSolver,this.phase=\"viaInPad\"):this.finishWithOutput(t,e,n)}startMixedSafeTraceLayerPhase(t,e,n){this.legacySafeTraceLayerRoutes=t,this.legacySafeTraceLayerSnapshot=e,this.legacySafeTraceLayerSelectedSolver=n,this.mixedSafeTraceLayerSolver=new Nz({...this.params,hdRoutes:this.safeTraceLayerInputRoutes,drcEvaluator:this.params.drcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.mixedSafeTraceLayerSolver,this.phase=\"mixedSafeTraceLayer\"}startBroadBranch(){const t=iD(this.params.srj,this.inputHdRoutes,this.params.effort??1,this.broadPassMultiplier,this.params.connMap);this.broadInputSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),yD(this.broadInputSnapshot,this.baselineSnapshot)?(this.broadSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.broadMaxIterations,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.broadSolver,this.phase=\"broad\"):this.startSafeTraceLayerPhase(this.baselineSolver.getOutput(),this.baselineSnapshot,this.baselineSolver)}_step(){if(\"start\"===this.phase)return this.inputSnapshot=Wk(this.params.srj,this.inputHdRoutes,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),0===mD(this.inputSnapshot)?void this.startViaInPadPhase(this.inputHdRoutes,this.inputSnapshot):void this.startBaselineBranch();if(\"baseline\"===this.phase){if(this.stepBranch(this.baselineSolver,\"baseline\"),!this.baselineSolver.solved)return;const t=this.baselineSolver.getOutput();return this.baselineSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),0===mD(this.baselineSnapshot)?void this.startViaInPadPhase(t,this.baselineSnapshot,this.baselineSolver):void(this.params.enableSafeTraceLayerMoves\u0026\u0026this.baselineSnapshot.count\u003c=3?this.startSafeTraceLayerPhase(t,this.baselineSnapshot,this.baselineSolver):this.startBroadBranch())}if(\"broad\"===this.phase){if(this.stepBranch(this.broadSolver,\"broad\"),!this.broadSolver.solved)return;const t=this.broadSolver.getOutput();return this.broadSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),yD(this.broadSnapshot,this.baselineSnapshot)?void this.startSafeTraceLayerPhase(t,this.broadSnapshot,this.broadSolver):void this.startSafeTraceLayerPhase(this.baselineSolver.getOutput(),this.baselineSnapshot,this.baselineSolver)}if(\"safeTraceLayer\"===this.phase){if(this.stepBranch(this.safeTraceLayerSolver,\"safe trace-layer\"),!this.safeTraceLayerSolver.solved)return;const t=this.safeTraceLayerSolver.getOutput(),e=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),n=hD(this.safeTraceLayerInputSnapshot,!1),o=hD(e,!1);this.safeTraceLayerPhaseAccepted=o\u003c=n\u0026\u0026jD(e,o,this.safeTraceLayerInputSnapshot.count,this.safeTraceLayerInputSnapshot.issueScore,n,this.safeTraceLayerInputSnapshot);const i=this.safeTraceLayerPhaseAccepted?t:this.safeTraceLayerInputRoutes,r=this.safeTraceLayerPhaseAccepted?e:this.safeTraceLayerInputSnapshot,s=this.safeTraceLayerPhaseAccepted?this.safeTraceLayerSolver:this.portfolioSelectedSolver;return r.count\u003e0\u0026\u0026!this.broadInputSnapshot?void this.startBroadBranch():mD(r)\u003e0\u0026\u0026this.safeTraceLayerInputSnapshot.errors.some(uD)?void this.startMixedSafeTraceLayerPhase(i,r,s):void this.startViaInPadPhase(i,r,s)}if(\"mixedSafeTraceLayer\"===this.phase){if(this.stepBranch(this.mixedSafeTraceLayerSolver,\"mixed safe trace-layer\"),!this.mixedSafeTraceLayerSolver.solved)return;const t=this.mixedSafeTraceLayerSolver.getOutput(),e=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),n=mD(e)\u003c=mD(this.legacySafeTraceLayerSnapshot);let o=!0;if(this.params.referenceDrcEvaluator){const e=this.getReferenceDrcSnapshot(this.legacySafeTraceLayerRoutes),n=this.getReferenceDrcSnapshot(t);this.mixedReferenceInputDrcIssueCount=e.count,this.mixedReferenceCandidateDrcIssueCount=n.count,o=n.count\u003c=e.count}return this.mixedSafeTraceLayerPhaseAccepted=n\u0026\u0026o,void this.startViaInPadPhase(this.mixedSafeTraceLayerPhaseAccepted?t:this.legacySafeTraceLayerRoutes,this.mixedSafeTraceLayerPhaseAccepted?e:this.legacySafeTraceLayerSnapshot,this.mixedSafeTraceLayerPhaseAccepted?this.mixedSafeTraceLayerSolver:this.legacySafeTraceLayerSelectedSolver)}if(\"viaInPad\"===this.phase){if(this.stepBranch(this.viaInPadSolver,\"via-in-pad\"),!this.viaInPadSolver.solved)return;const t=this.viaInPadSolver.getOutput(),e=Wk(this.params.srj,t,this.params.viaInPadDrcEvaluator??this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine);this.finishWithOutput(t,e,this.viaInPadSolver)}}getOutput(){return this.outputHdRoutes}visualize(){const t=this.activeSubSolver??this.selectedSolver;return t?.visualize()??super.visualize()}preview(){const t=this.activeSubSolver??this.selectedSolver;return t?.preview()??this.visualize()}},Tz=class extends si{constructor(t,e,n=Number.POSITIVE_INFINITY,o=.010000000000000002){super(),this.nodes=t,this.maxNodeDimension=e,this.maxNodeRatio=n,this.minNodeArea=o,this.outputNodes=[]}nodes;maxNodeDimension;maxNodeRatio;minNodeArea;outputNodes;getSolverName(){return\"NodeDimensionSubdivisionSolver\"}getSubdivisionGrid(t){const e=Number.isFinite(this.maxNodeDimension)\u0026\u0026this.maxNodeDimension\u003e0,n=Number.isFinite(this.maxNodeRatio)\u0026\u0026this.maxNodeRatio\u003e0;let o=e?Math.max(1,Math.ceil(t.width/this.maxNodeDimension)):1,i=e?Math.max(1,Math.ceil(t.height/this.maxNodeDimension)):1;if(n\u0026\u0026t.width\u003e0\u0026\u0026t.height\u003e0)for(;;){const e=t.width/o,n=t.height/i;if((e\u003e=n?e/n:n/e)\u003c=this.maxNodeRatio)break;e\u003e=n?o++:i++}return{cols:o,rows:i}}shouldRemoveNode(t){const e=Number.isFinite(this.minNodeArea)\u0026\u0026this.minNodeArea\u003e0;if(!Number.isFinite(t.width)||!Number.isFinite(t.height))return!0;if(!e||t.width*t.height\u003e=this.minNodeArea)return!1;if(Math.min(t.width,t.height)\u003c.002)return!0;if(t._containsTarget)return!1;let n=0;for(const e of this.nodes)if(e.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026t.availableZ.some(t=\u003ee.availableZ.includes(t))\u0026\u0026li(t,e)){if(e._containsTarget)return!1;if(n++,n\u003e=2)return!1}return!0}subdivideNode(t){if(this.shouldRemoveNode(t))return[];const{cols:e,rows:n}=this.getSubdivisionGrid(t);if(1===e\u0026\u00261===n)return[t];const o=t.width/e,i=t.height/n,r=t.center.x-t.width/2,s=t.center.y-t.height/2,a=[];for(let c=0;c\u003cn;c++)for(let n=0;n\u003ce;n++)a.push({...t,capacityMeshNodeId:`${t.capacityMeshNodeId}__sub_${c}_${n}`,center:{x:r+o*(n+.5),y:s+i*(c+.5)},width:o,height:i,availableZ:[...t.availableZ]});return a}_step(){const t=this.nodes.length;let e=0,n=0,o=0;for(const t of this.nodes){const i=!Number.isFinite(t.width)||!Number.isFinite(t.height),r=this.subdivideNode(t);0!==r.length?(r.length\u003e1\u0026\u0026e++,this.outputNodes.push(...r)):i?o++:n++}this.stats={inputNodeCount:t,outputNodeCount:this.outputNodes.length,subdividedNodeCount:e,removedSmallNodeCount:n,removedInvalidNodeCount:o,maxNodeDimension:this.maxNodeDimension,maxNodeRatio:this.maxNodeRatio,minNodeArea:this.minNodeArea},this.solved=!0}visualize(){return{rects:this.outputNodes.map(t=\u003e({center:t.center,width:t.width,height:t.height,label:`${t.capacityMeshNodeId}\\n${t.width.toFixed(2)}x${t.height.toFixed(2)}`,layer:`z${t.availableZ.join(\",\")}`,fill:\"rgba(0, 200, 255, 0.08)\",stroke:\"rgba(0, 120, 180, 0.5)\"}))}}},Rz=t=\u003e{const e=[...new Set(t.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0))].sort((t,e)=\u003et-e);if(0!==e.length)return`z${e.join(\",\")}`},Ez=t=\u003e{const e=[];for(let n=0;n\u003c31;n++)t\u00261\u003c\u003cn\u0026\u0026e.push(n);return e},Az=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,Oz=t=\u003eAz(t)?{...t}:void 0===t?{}:{value:t},kz=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];if(Az(n)){if(\"string\"==typeof n.serializedRegionId)return n.serializedRegionId;if(\"string\"==typeof n.regionId)return n.regionId;if(\"string\"==typeof n.capacityMeshNodeId)return n.capacityMeshNodeId}return`region-${e}`},Lz=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];if(Az(n)){if(\"string\"==typeof n.serializedPortId)return n.serializedPortId;if(\"string\"==typeof n.portId)return(o=n.portId).includes(\"::\")?o.slice(0,o.indexOf(\"::\")):o}var o;return`port-${e}`},Dz=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return Az(n)\u0026\u0026\"string\"==typeof n.connectionId?n.connectionId:`route-${e}`},zz=(t,e)=\u003e{const n=Oz(t.topology.regionMetadata?.[e]);if(Az(n.center)||(n.center={x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),\"number\"!=typeof n.width\u0026\u0026(n.width=t.topology.regionWidth[e]),\"number\"!=typeof n.height\u0026\u0026(n.height=t.topology.regionHeight[e]),!Array.isArray(n.availableZ)){const o=t.topology.regionAvailableZMask?.[e]??0;0!==o\u0026\u0026(n.availableZ=Ez(o))}return n.layer=Rz(Array.isArray(n.availableZ)?n.availableZ:[])??Rz((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))??\"z0\",n},Fz=(t,e)=\u003e{const n=Oz(t.topology.portMetadata?.[e]);return\"number\"!=typeof n.x\u0026\u0026(n.x=t.topology.portX[e]),\"number\"!=typeof n.y\u0026\u0026(n.y=t.topology.portY[e]),\"number\"!=typeof n.z\u0026\u0026(n.z=t.topology.portZ[e]),n.layer=Rz([t.topology.portZ[e]])??\"z0\",n},Bz=(t,e,n)=\u003e{const o=(t.topology.incidentPortRegion[e]??[]).find(t=\u003et!==n);if(void 0===o)throw new Error(`Port ${e} is not incident to a region outside route region ${n}`);return o},jz=(t,e,n)=\u003e{const{orderedPortIds:o,orderedRegionIds:i}=((t,e,n)=\u003e{if(0===n.length)throw new Error(`Route ${e} has no solved segments`);const o=t.problem.routeStartPort[e],i=t.problem.routeEndPort[e],r=new Map;n.forEach((t,e)=\u003e{const n={...t,segmentIndex:e},o=r.get(t.fromPortId)??[];o.push(n),r.set(t.fromPortId,o);const i=r.get(t.toPortId)??[];i.push(n),r.set(t.toPortId,i)});const s=[o],a=[],c=(t,e,n)=\u003e{if(t===i)return!0;for(const o of r.get(t)??[]){if(e.has(o.segmentIndex))continue;const i=o.fromPortId===t?o.toPortId:o.fromPortId;if(!n.has(i)){if(e.add(o.segmentIndex),n.add(i),a.push(o.regionId),s.push(i),c(i,e,n))return!0;s.pop(),a.pop(),n.delete(i),e.delete(o.segmentIndex)}}return!1};if(!c(o,new Set,new Set([o])))throw new Error(`Route ${e} is not a single ordered path from ${o} to ${i}`);return{orderedPortIds:s,orderedRegionIds:a}})(t,e,n),r=i[0],s=i[i.length-1];if(void 0===r||void 0===s)throw new Error(`Route ${e} could not determine endpoint regions`);const a=kz(t,Bz(t,o[0],r)),c=kz(t,Bz(t,o[o.length-1],s)),l=((t,e,n,o)=\u003e{const i=t.problem.routeMetadata?.[e];return{connectionId:Dz(t,e),startRegionId:(Az(i)\u0026\u0026\"string\"==typeof i.startRegionId?i.startRegionId:void 0)??n,endRegionId:(Az(i)\u0026\u0026\"string\"==typeof i.endRegionId?i.endRegionId:void 0)??o,mutuallyConnectedNetworkId:(Az(i)\u0026\u0026\"string\"==typeof i.mutuallyConnectedNetworkId?i.mutuallyConnectedNetworkId:void 0)??`net-${t.problem.routeNet[e]}`}})(t,e,a,c),d=o.map((e,n)=\u003e{const r={portId:Lz(t,e),g:n,h:0,f:n,hops:n,ripRequired:!1,nextRegionId:n\u003ci.length?kz(t,i[n]):l.endRegionId};return n\u003e0\u0026\u0026(r.lastPortId=Lz(t,o[n-1]),r.lastRegionId=kz(t,i[n-1])),r});return{connection:l,solvedRoute:{connection:l,path:d,requiredRip:!1}}},$z=t=\u003e{if(!t.solved||t.failed)throw new Error(\"convertToSerializedHyperGraph requires a solved, non-failed solver\");const{topology:e}=t,n=(t=\u003e{const e=Array.from({length:t.problem.routeCount},()=\u003e[]);return t.state.regionSegments.forEach((t,n)=\u003e{for(const[o,i,r]of t)e[o].push({regionId:n,fromPortId:i,toPortId:r})}),e})(t),o=Array.from({length:e.regionCount},(n,o)=\u003e{const i=t.state.regionSegments[o].map(([e,n,o])=\u003e({regionPort1Id:Lz(t,n),regionPort2Id:Lz(t,o),connectionId:Dz(t,e)}));return{regionId:kz(t,o),pointIds:e.regionIncidentPorts[o].map(e=\u003eLz(t,e)),d:zz(t,o),...i.length\u003e0\u0026\u0026{assignments:i}}}),i=Array.from({length:e.portCount},(n,o)=\u003e{const[i,r]=e.incidentPortRegion[o]??[];if(void 0===i||void 0===r)throw new Error(`Port ${o} is missing incident regions`);return{portId:Lz(t,o),region1Id:kz(t,i),region2Id:kz(t,r),d:Fz(t,o)}}),r=n.map((e,n)=\u003ejz(t,n,e));return{regions:o,ports:i,connections:r.map(({connection:t})=\u003et),solvedRoutes:r.map(({solvedRoute:t})=\u003et)}},Yz=.3,Xz=t=\u003et\u003e0\u0026\u0026!(t\u0026t-1),Vz=(t,e,n,o,i,r=0,s=.3,a=0)=\u003e(2*e+1*n+1*o)*(s+.15)**2*(1+i/5)/t+(Xz(r)?10*e:0)+a*(i/Wz(r))**2*.1**2/t,Wz=t=\u003e{if(0===t)return 2;let e=t\u003e\u003e\u003e0,n=0;for(;0!==e;)n+=1\u0026e,e\u003e\u003e\u003e=1;return n},Hz=(t,e,n,o,i,r)=\u003e{const{netIds:s,lesserAngles:a,greaterAngles:c,layerMasks:l}=t;let d=0,h=0;for(let t=0;t\u003cs.length;t++){if(e===s[t])continue;(n\u003ca[t]\u0026\u0026a[t]\u003co)!==(n\u003cc[t]\u0026\u0026c[t]\u003co)\u0026\u0026(0!==(i\u0026l[t])?d++:h++)}return[d,h,r]},Gz=(t,e,n)=\u003e{const o=t.routeStartPort[e],i=t.routeEndPort[e],r=new Map;for(const{fromPortId:t,toPortId:e}of n){const n=r.get(t)??new Set;n.add(e),r.set(t,n);const o=r.get(e)??new Set;o.add(t),r.set(e,o)}const s=new Set,a=[o];for(;a.length\u003e0;){const t=a.pop();if(!s.has(t)){s.add(t);for(const e of r.get(t)??[])a.push(e)}}if(!s.has(i))throw new Error(`Initial assignments for route ${e} do not connect ${o} to ${i}`);if(n.some(({fromPortId:t,toPortId:e})=\u003e!s.has(t)||!s.has(e)))throw new Error(`Initial assignments for route ${e} contain disconnected segments`)},Uz=({topology:t,problem:e,state:n,routeSuccessCountByRouteId:o,appendSegmentToRegionCache:i})=\u003e{const r=e.initialAssignments??[];if(0===r.length)return;const s=new Map;for(const n of r){const{routeId:o,regionId:i,fromPortId:r,toPortId:a}=n;if(!Number.isInteger(o)||o\u003c0||o\u003e=e.routeCount)throw new Error(`Initial assignment references invalid route ${o}`);if(!Number.isInteger(i)||i\u003c0||i\u003e=t.regionCount)throw new Error(`Initial assignment references invalid region ${i}`);for(const e of[r,a]){if(!Number.isInteger(e)||e\u003c0||e\u003e=t.portCount)throw new Error(`Initial assignment references invalid port ${e}`);if(!t.incidentPortRegion[e]?.includes(i))throw new Error(`Initial assignment port ${e} is not incident to region ${i}`)}const c=s.get(o)??[];c.push(n),s.set(o,c)}for(const[t,n]of s)Gz(e,t,n);const a=new Set(s.keys());for(const{routeId:t,regionId:o,fromPortId:s,toPortId:a}of r){const r=e.routeNet[t];for(const t of[s,a]){const e=n.portAssignment[t];if(-1!==e\u0026\u0026e!==r)throw new Error(`Initial assignment port ${t} is assigned to multiple nets`);n.portAssignment[t]=r}n.currentRouteNetId=r,n.regionSegments[o].push([t,s,a]),i(o,s,a)}n.currentRouteNetId=void 0,n.unroutedRoutes=n.unroutedRoutes.filter(t=\u003e!a.has(t));for(const t of a)o[t]=1;return{initialAssignmentCount:r.length,initiallyRoutedRouteCount:a.size}},Zz=class{constructor(t,e){this.items=t,this.compare=e}items;compare;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0}queue(t){this.items.push(t),this.siftUp(this.items.length-1)}dequeue(){const t=this.items[0];if(void 0===t)return;const e=this.items.pop();return this.items.length\u003e0\u0026\u0026(this.items[0]=e,this.siftDown(0)),t}siftUp(t){let e=t;for(;e\u003e0;){const t=e-1\u003e\u003e1,n=this.items[t],o=this.items[e];if(this.compare(n,o)\u003c=0)return;this.items[t]=o,this.items[e]=n,e=t}}siftDown(t){let e=t;const n=this.items.length;for(;;){const t=2*e+1;if(t\u003e=n)return;const o=t+1;let i=t;o\u003cn\u0026\u0026this.compare(this.items[o],this.items[t])\u003c0\u0026\u0026(i=o);const r=this.items[e],s=this.items[i];if(this.compare(r,s)\u003c=0)return;this.items[e]=s,this.items[i]=r,e=i}}},qz=(t,e)=\u003e{const n=[...t],o=(t=\u003e{let e=t\u003e\u003e\u003e0;return()=\u003e{e+=1831565813;let t=e;return t=Math.imul(t^t\u003e\u003e\u003e15,1|t),t^=t+Math.imul(t^t\u003e\u003e\u003e7,61|t),((t^t\u003e\u003e\u003e14)\u003e\u003e\u003e0)/4294967296}})(e);for(let t=n.length-1;t\u003e0;t--){const e=Math.floor(o()*(t+1));[n[t],n[e]]=[n[e],n[t]]}return n},Jz=(t,e)=\u003et.routeMetadata?.[e],Kz=t=\u003et?.simpleRouteConnection?.pointsToConnect?.map(({pointId:t})=\u003e\"string\"==typeof t?t:null).filter(t=\u003enull!==t)??[],Qz=(t,e)=\u003e{const n=Jz(t,e)?.connectionId;return\"string\"==typeof n?n:`route-${e}`},tF=(t,e,n)=\u003e{const o=t.portEndpointNetIds[n];if(!o)return!1;for(const t of o)if(t!==e)return!0;return!1},eF=(t,e,n)=\u003e{const o=t.regionNetId[n];return-1!==o\u0026\u0026o!==e},nF=t=\u003e[...new Set(t.routeIds)].filter(e=\u003e!((t,e)=\u003e{const{topology:n,problem:o,problemSetup:i,portAssignment:r,maxPrecheckHops:s}=t,a=o.routeNet[e],c=o.routeStartPort[e],l=o.routeEndPort[e];if(c===l)return!0;const d=t.getStartingNextRegionId(e,c);if(void 0===d)return!1;const h=[{portId:c,nextRegionId:d}],u=new Set([c*n.regionCount+d]);for(let t=0;t\u003ch.length;t++){const e=h[t];if(!eF(o,a,e.nextRegionId))for(const t of n.regionIncidentPorts[e.nextRegionId]??[]){const c=r[t];if(tF(i,a,t))continue;if(t===l){if(-1!==c\u0026\u0026c!==a)continue;return!0}if(t===e.portId)continue;if(-1!==c\u0026\u0026c!==a)continue;if(0===o.portSectionMask[t])continue;const d=n.incidentPortRegion[t]??[],p=d[0]===e.nextRegionId?d[1]:d[0];if(void 0===p||eF(o,a,p))continue;const m=t*n.regionCount+p;if(!u.has(m)){if(u.size\u003e=s)return!0;u.add(m),h.push({portId:t,nextRegionId:p})}}}return!1})(t,e)).map(e=\u003et.getRouteSummary(e)),oF=t=\u003e{const e=new Array(t);for(let n=0;n\u003ct;n++)e[n]=n;return e},iF=\"rgba(220, 38, 38, 0.98)\",rF=\"rgba(220, 38, 38, 0.18)\",sF=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),aF=(t,e)=\u003e{const n=.005*t.topology.portZ[e];return{x:t.topology.portX[e]+n,y:t.topology.portY[e]+n}},cF=(t,e)=\u003eRz([t.topology.portZ[e]])??\"z0\",lF=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},dF=(t,e)=\u003e`z: ${t.topology.portZ[e]}`,hF=(t,e)=\u003e((t,e,n)=\u003e{const o=t.topology.portZ[e],i=t.topology.portZ[n];return o===i?`z: ${o}`:`z: ${o} -\u003e ${i}`})(t,t.problem.routeStartPort[e],t.problem.routeEndPort[e]),uF=(t,e)=\u003e`net: ${t.problem.routeNet[e]}`,pF=.05,mF={r:255,g:64,b:64,a:.72},gF=\"rgba(220, 38, 38, 0.98)\",fF=\"rgba(220, 38, 38, 0.12)\",yF=\"10 6\",_F=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),bF=t=\u003eMath.min(1,Math.max(0,t)),xF=(t,e,n)=\u003eMath.round(t+(e-t)*n),vF=({r:t,g:e,b:n,a:o})=\u003e`rgba(${t}, ${e}, ${n}, ${o})`,SF=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},IF=t=\u003e\"number\"==typeof t.centerRouteId,CF=(t,e)=\u003eIF(t)?e===t.centerRouteId?1:.5:1,PF=(t,e)=\u003e{const n=t.match(/^(rgba|hsla)\\((.*),\\s*([0-9]*\\.?[0-9]+)\\)$/);if(!n)return t;const[,o,i,r]=n,s=bF(Number(r)*e);return`${o}(${i}, ${Number(s.toFixed(3))})`},MF=(t,e,n=.8)=\u003e((t,e,n=.8)=\u003e{const o=`${t.problem.routeNet[e]}:${SF(t,e)}`;let i=0;for(let t=0;t\u003co.length;t++)i=17777*o.charCodeAt(t)+((i\u003c\u003c5)-i);return`hsla(${Math.abs(i)%360}, 70%, 50%, ${n})`})(t,e,n*CF(t,e)),NF=(t,e)=\u003e`net: ${t.problem.routeNet[e]}`,wF=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=n?.polygon;if(Array.isArray(o)\u0026\u0026o.length\u003e=3){const t=o.map(t=\u003et.x),e=o.map(t=\u003et.y);return{minX:Math.min(...t),maxX:Math.max(...t),minY:Math.min(...e),maxY:Math.max(...e)}}const i=n?.bounds;if(i\u0026\u0026\"number\"==typeof i.minX\u0026\u0026\"number\"==typeof i.maxX\u0026\u0026\"number\"==typeof i.minY\u0026\u0026\"number\"==typeof i.maxY)return i;const r=t.topology.regionWidth[e],s=t.topology.regionHeight[e],a=t.topology.regionCenterX[e],c=t.topology.regionCenterY[e];return{minX:a-r/2,maxX:a+r/2,minY:c-s/2,maxY:c+s/2}},TF=(t,e)=\u003e({x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),RF=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=Array.isArray(n?.availableZ)?n.availableZ.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0):[];if(o.length\u003e0)return Rz(o)??\"z0\";const i=Ez(t.topology.regionAvailableZMask?.[e]??0);if(i.length\u003e0)return Rz(i)??\"z0\";const r=[...new Set((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))].sort((t,e)=\u003et-e);return Rz(r)??\"z0\"},EF=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e],o=n?.existingRegionCost??0,i=t.state.regionCongestionCost[e]??0,r=t.problem.regionNetId[e];return _F(`region: region-${e}`,`net: ${-1===r?\"free\":`${r}`}`,t.getAdditionalRegionLabel(e),`cost: ${o.toFixed(3)}`,`congestion: ${i.toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},AF=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];return n?.isConnectionRegion?{r:255,g:100,b:255,a:.6}:n?.isThroughJumper?{r:100,g:200,b:100,a:.5}:n?.isPad?{r:255,g:200,b:100,a:.5}:\"bottom\"===n?.layer?{r:52,g:152,b:219,a:.08}:{r:200,g:200,b:255,a:.1}},OF=(t,e)=\u003e{const n=AF(t,e),o=bF(t.state.regionIntersectionCaches[e]?.existingRegionCost??0);return vF((r=mF,s=o**.8,{r:xF((i=n).r,r.r,s),g:xF(i.g,r.g,s),b:xF(i.b,r.b,s),a:Number((i.a+(r.a-i.a)*s).toFixed(3))}));var i,r,s},kF=(t,e)=\u003e{const n=((t,e)=\u003e({x:t.topology.portX[e],y:t.topology.portY[e]}))(t,e),o=.005*t.topology.portZ[e];return{x:n.x+o,y:n.y+o}},LF=kF,DF=(t,e)=\u003eRz([t.topology.portZ[e]])??\"z0\",zF=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},FF=(t,e,n)=\u003e{if(void 0!==n)return`net: ${t.problem.routeNet[n]}`;const o=t.state.portAssignment[e];if(o\u003e=0)return`net: ${o}`;const i=new Set;for(let n=0;n\u003ct.problem.routeCount;n++)t.problem.routeStartPort[n]!==e\u0026\u0026t.problem.routeEndPort[n]!==e||i.add(t.problem.routeNet[n]);return 0!==i.size?`net: ${Array.from(i).sort((t,e)=\u003et-e).join(\", \")}`:void 0},BF=(t,e)=\u003e`z: ${t.topology.portZ[e]}`,jF=(t,e,n)=\u003e{const o=t.topology.portZ[e],i=t.topology.portZ[n];return o===i?`z: ${o}`:`z: ${o} -\u003e ${i}`},$F=(t,e)=\u003ejF(t,t.problem.routeStartPort[e],t.problem.routeEndPort[e]),YF=(t,e,n)=\u003e_F(zF(t,e),((t,e)=\u003e{const n=t.topology.incidentPortRegion[e]?.[0],o=t.topology.incidentPortRegion[e]?.[1];return`connects: region-${n??\"?\"} \u003c-\u003e region-${o??\"?\"}`})(t,e),FF(t,e,n)),XF=(t,e,n,o)=\u003e{const i=t.topology.portZ[n];return i!==t.topology.portZ[o]?{strokeColor:PF(\"rgba(22, 160, 133, 0.95)\",CF(t,e)),strokeDash:\"2 4 2\"}:i\u003e0?{strokeColor:PF(\"rgba(52, 152, 219, 0.95)\",CF(t,e)),strokeDash:\"3 2\"}:{strokeColor:MF(t,e)}},VF=(t,e)=\u003e{for(let n=0;n\u003ct.state.regionSegments.length;n++){const o=t.state.regionSegments[n]??[];for(const[i,r,s]of o)e.lines.push({points:[kF(t,r),kF(t,s)],label:_F(`route: ${SF(t,i)}`,`region: region-${n}`,jF(t,r,s)),layer:DF(t,r),...XF(t,i,r,s)})}},WF=(t,e)=\u003e{const n=new Set;for(let o=0;o\u003ct.state.regionSegments.length;o++){const i=t.state.regionSegments[o]??[];for(const[o,r,s]of i)for(const i of[r,s]){const r=`${o}:${i}`;if(n.has(r))continue;n.add(r);const s=kF(t,i);e.points.push({x:s.x,y:s.y,color:MF(t,o,1),layer:DF(t,i),label:_F(`route: ${SF(t,o)}`,zF(t,i),FF(t,i,o),BF(t,i))})}}},HF=(t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++)if(t.problem.routeStartPort[n]===e||t.problem.routeEndPort[n]===e)return!0;return!1},GF=(t,e,n)=\u003e{const o=((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ce.length;o++)if(1===e[o])for(const e of t.topology.incidentPortRegion[o]??[])n.add(e);return n})(t,n),i=\"rgba(245, 158, 11, 0.95)\",r=\"rgba(245, 158, 11, 0.08)\";for(const n of o){const o=t.topology.regionMetadata?.[n],s=o?.polygon,a=wF(t,n),c=TF(t,n),l=a.maxX-a.minX,d=a.maxY-a.minY,h=RF(t,n),u=_F(\"section region\",EF(t,n));Array.isArray(s)\u0026\u0026s.length\u003e=3?e.polygons.push({points:s,fill:r,stroke:i,strokeWidth:2,layer:h,label:u}):e.rects.push({center:c,width:Math.max(l-pF,.05),height:Math.max(d-pF,.05),fill:r,stroke:i,layer:h,label:u})}for(let o=0;o\u003cn.length;o++)1===n[o]\u0026\u0026e.circles.push({center:LF(t,o),radius:.07,fill:\"rgba(251, 191, 36, 0.18)\",stroke:i,layer:DF(t,o),label:_F(YF(t,o),BF(t,o),\"section port\")})},UF=(t,e={})=\u003e{const n={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:\"Tiny HyperGraph\",coordinateSystem:\"cartesian\"},o=((t,e)=\u003e{if(!e?.highlightSectionMask)return;const n=e.sectionPortMask??t.problem.portSectionMask;if(n.length!==t.topology.portCount)return;let o=0,i=0;for(let t=0;t\u003cn.length;t++)1===n[t]?o+=1:i+=1;return 0!==o\u0026\u00260!==i?n:void 0})(t,e),i=(t=\u003e{const e=t.getStaticallyUnroutableRoutes();if(0!==e.length)return new Set(e.map(t=\u003et.routeId))})(t);for(let e=0;e\u003ct.topology.regionCount;e++){const o=t.topology.regionMetadata?.[e],i=o?.polygon,r=wF(t,e),s=TF(t,e),a=r.maxX-r.minX,c=r.maxY-r.minY,l=RF(t,e),d=vF(AF(t,e));Array.isArray(i)\u0026\u0026i.length\u003e=3?n.polygons.push({points:i,fill:d,layer:l}):n.rects.push({center:s,width:Math.max(a-pF,.05),height:Math.max(c-pF,.05),fill:OF(t,e),layer:l,label:EF(t,e)})}if(((t,e,n)=\u003e{for(let o=0;o\u003ct.problem.routeCount;o++){if(n\u0026\u0026!n.has(o))continue;const i=t.problem.routeStartPort[o],r=t.problem.routeEndPort[o],s=kF(t,i),a=kF(t,r),c=MF(t,o),l=SF(t,o),d=NF(t,o);e.points.push({x:s.x,y:s.y,color:c,layer:DF(t,i),label:_F(`route: ${l}`,d,\"endpoint: start\",zF(t,i),BF(t,i))}),e.points.push({x:a.x,y:a.y,color:c,layer:DF(t,r),label:_F(`route: ${l}`,d,\"endpoint: end\",zF(t,r),BF(t,r))})}})(t,n,i),0===t.iterations){for(const t of n.polygons)t.stroke=\"rgba(128, 128, 128, 0.5)\";for(const t of n.rects)t.stroke=\"rgba(128, 128, 128, 0.5)\"}if(0===t.iterations){for(let i=0;i\u003ct.topology.portCount;i++){const r=1===o?.[i];e.showOnlySectionPortsOnIdle\u0026\u0026!r||n.circles.push({center:LF(t,i),radius:.05,fill:t.topology.portZ[i]\u003e0?\"rgba(52, 152, 219, 0.55)\":\"rgba(128, 128, 128, 0.5)\",layer:DF(t,i),label:_F(YF(t,i),BF(t,i))})}if(i)((t,e)=\u003e{for(const n of t.getStaticallyUnroutableRoutes()){const{routeId:o,connectionId:i,startPortId:r,endPortId:s}=n,a=aF(t,r),c=aF(t,s),l=sF(`static reachability failed: ${i}`,uF(t,o),n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0,n.pointIds.length\u003e=2?`points: ${n.pointIds.join(\" -\u003e \")}`:void 0,hF(t,o));e.lines.push({points:[a,c],strokeColor:iF,strokeDash:\"8 4\",label:l}),e.circles.push({center:a,radius:.12,fill:rF,stroke:iF,layer:cF(t,r),label:sF(l,\"endpoint: start\",lF(t,r),dF(t,r))}),e.circles.push({center:c,radius:.12,fill:rF,stroke:iF,layer:cF(t,s),label:sF(l,\"endpoint: end\",lF(t,s),dF(t,s))})}})(t,n);else{const o=new Set;for(const e of t.state.regionSegments)for(const[t]of e)o.add(t);if(o.size\u003e0\u0026\u0026(VF(t,n),WF(t,n)),!1!==e.showInitialRouteHints){const e=new Set(t.state.unroutedRoutes);void 0!==t.state.currentRouteId\u0026\u0026e.add(t.state.currentRouteId),((t,e,n)=\u003e{for(let o=0;o\u003ct.problem.routeCount;o++){if(n\u0026\u0026!n.has(o))continue;const i=t.problem.routeStartPort[o],r=t.problem.routeEndPort[o],s=kF(t,i),a=kF(t,r),c={x:(s.x+a.x)/2,y:(s.y+a.y)/2};e.lines.push({points:[s,a],strokeColor:MF(t,o),strokeDash:\"3 3\",layer:DF(t,i),label:_F(SF(t,o),$F(t,o))}),e.points.push({x:c.x,y:c.y,color:MF(t,o,1),layer:DF(t,i),label:_F(SF(t,o),$F(t,o))})}})(t,n,e)}}}else VF(t,n),WF(t,n),(t=\u003eIF(t)\u0026\u0026!0===t.showUnassignedPortsInVisualization)(t)\u0026\u0026((t,e)=\u003e{for(let n=0;n\u003ct.topology.portCount;n++)t.state.portAssignment[n]\u003e=0||HF(t,n)||e.circles.push({center:LF(t,n),radius:.04,fill:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.2)\":\"rgba(128, 128, 128, 0.2)\",stroke:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.6)\":\"rgba(128, 128, 128, 0.6)\",layer:DF(t,n),label:_F(YF(t,n),BF(t,n),\"state: unassigned\")})})(t,n),IF(t)||(((t,e)=\u003e{const n=t.state.currentRouteId;if(void 0===n||t.solved)return;const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=kF(t,o),s=kF(t,i),a=MF(t,n),c=SF(t,n);e.lines.push({points:[r,s],strokeColor:a,strokeDash:\"10 5\",label:_F(c,$F(t,n))})})(t,n),((t,e)=\u003e{if(t.solved)return;const n=t.state.currentRouteId,o=t.state.candidateQueue.toArray().sort((t,e)=\u003et.f-e.f).slice(0,10);for(let i=0;i\u003co.length;i++){const r=o[i],s=kF(t,r.portId),a=0===i;e.points.push({x:s.x,y:s.y,color:a?\"green\":\"rgba(128, 128, 128, 0.25)\",layer:DF(t,r.portId),label:_F(YF(t,r.portId,n),BF(t,r.portId),`g: ${r.g.toFixed(2)}`,`h: ${r.h.toFixed(2)}`,`f: ${r.f.toFixed(2)}`)})}const i=o[0];if(!i)return;const r=[];let s=i;for(;s;)r.unshift(kF(t,s.portId)),s=s.prevCandidate;r.length\u003e1\u0026\u0026e.lines.push({points:r,strokeColor:void 0!==n?MF(t,n):\"rgba(0, 160, 120, 0.9)\"})})(t,n));o\u0026\u0026GF(t,n,o),((t,e)=\u003e{if(t.failed)for(const n of t.getNeverSuccessfullyRoutedRoutes()){const{routeId:o,connectionId:i,attempts:r,startPortId:s,endPortId:a}=n,c=NF(t,o),l=LF(t,s),d=LF(t,a),h=_F(`never routed: ${i}`,`attempts: ${r}`,c,n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0);e.lines.push({points:[{x:0,y:0},{x:l.x,y:l.y}],strokeColor:gF,strokeDash:yF,layer:DF(t,s),label:_F(h,\"origin guide\",\"endpoint: start\")}),e.circles.push({center:l,radius:1,fill:fF,stroke:gF,layer:DF(t,s),label:_F(h,\"endpoint: start\",zF(t,s),BF(t,s))}),e.lines.push({points:[{x:0,y:0},{x:d.x,y:d.y}],strokeColor:gF,strokeDash:yF,layer:DF(t,a),label:_F(h,\"origin guide\",\"endpoint: end\")}),e.circles.push({center:d,radius:1,fill:fF,stroke:gF,layer:DF(t,a),label:_F(h,\"endpoint: end\",zF(t,a),BF(t,a))})}})(t,n);const r=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1),s=o?o.reduce((t,e)=\u003et+Number(1===e),0):0;return n.title=[\"Tiny HyperGraph\",`iter=${t.iterations}`,`pending=${r}`,o?`sectionPorts=${s}`:void 0,i?`staticReachabilityFailed=${i.size}`:void 0,t.failed?\"failed\":t.solved?\"solved\":\"running\"].filter(Boolean).join(\" | \"),n},ZF=5e4,qF=()=\u003e({netIds:new Int32Array(0),lesserAngles:new Int32Array(0),greaterAngles:new Int32Array(0),layerMasks:new Int32Array(0),existingCrossingLayerIntersections:0,existingSameLayerIntersections:0,existingEntryExitLayerChanges:0,existingRegionCost:0,existingSegmentCount:0}),JF=t=\u003e({netIds:new Int32Array(t.netIds),lesserAngles:new Int32Array(t.lesserAngles),greaterAngles:new Int32Array(t.greaterAngles),layerMasks:new Int32Array(t.layerMasks),existingCrossingLayerIntersections:t.existingCrossingLayerIntersections,existingSameLayerIntersections:t.existingSameLayerIntersections,existingEntryExitLayerChanges:t.existingEntryExitLayerChanges,existingRegionCost:t.existingRegionCost,existingSegmentCount:t.existingSegmentCount}),KF=t=\u003e{return{portAssignment:new Int32Array(t.portAssignment),regionSegments:(e=t.regionSegments,e.map(t=\u003et.map(([t,e,n])=\u003e[t,e,n]))),regionIntersectionCaches:t.regionIntersectionCaches.map(JF),regionCongestionCost:new Float64Array(t.regionCongestionCost),ripCount:t.ripCount};var e},QF=(t,e)=\u003e{e\u0026\u0026(void 0!==e.minViaPadDiameter\u0026\u0026(t.minViaPadDiameter=e.minViaPadDiameter),void 0!==e.DISTANCE_TO_COST\u0026\u0026(t.DISTANCE_TO_COST=e.DISTANCE_TO_COST),void 0!==e.RIP_THRESHOLD_START\u0026\u0026(t.RIP_THRESHOLD_START=e.RIP_THRESHOLD_START),void 0!==e.RIP_THRESHOLD_END\u0026\u0026(t.RIP_THRESHOLD_END=e.RIP_THRESHOLD_END),void 0!==e.RIP_THRESHOLD_RAMP_ATTEMPTS\u0026\u0026(t.RIP_THRESHOLD_RAMP_ATTEMPTS=e.RIP_THRESHOLD_RAMP_ATTEMPTS),void 0!==e.RIP_CONGESTION_REGION_COST_FACTOR\u0026\u0026(t.RIP_CONGESTION_REGION_COST_FACTOR=e.RIP_CONGESTION_REGION_COST_FACTOR),void 0!==e.TRACE_DENSITY_COST_FACTOR\u0026\u0026(t.TRACE_DENSITY_COST_FACTOR=Math.max(0,e.TRACE_DENSITY_COST_FACTOR)),void 0!==e.USE_LAZY_ROUTE_HEURISTIC\u0026\u0026(t.USE_LAZY_ROUTE_HEURISTIC=e.USE_LAZY_ROUTE_HEURISTIC),void 0!==e.USE_SPARSE_CANDIDATE_STORAGE\u0026\u0026(t.USE_SPARSE_CANDIDATE_STORAGE=e.USE_SPARSE_CANDIDATE_STORAGE),void 0!==e.MAX_ITERATIONS\u0026\u0026(t.MAX_ITERATIONS=e.MAX_ITERATIONS),void 0!==e.VERBOSE\u0026\u0026(t.VERBOSE=e.VERBOSE),void 0!==e.STATIC_REACHABILITY_PRECHECK\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK=e.STATIC_REACHABILITY_PRECHECK),void 0!==e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS=e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),void 0!==e.ACCEPT_BEST_SOLUTION_ON_TIMEOUT\u0026\u0026(t.ACCEPT_BEST_SOLUTION_ON_TIMEOUT=e.ACCEPT_BEST_SOLUTION_ON_TIMEOUT),void 0!==e.GREEDY_FINAL_ROUTE_ITERS\u0026\u0026(t.GREEDY_FINAL_ROUTE_ITERS=e.GREEDY_FINAL_ROUTE_ITERS),void 0!==e.PARTIAL_RIP_ENABLED\u0026\u0026(t.PARTIAL_RIP_ENABLED=e.PARTIAL_RIP_ENABLED),void 0!==e.PARTIAL_RIP_MIN_ROUTE_COUNT\u0026\u0026(t.PARTIAL_RIP_MIN_ROUTE_COUNT=e.PARTIAL_RIP_MIN_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_MAX_ROUTE_COUNT\u0026\u0026(t.PARTIAL_RIP_MAX_ROUTE_COUNT=e.PARTIAL_RIP_MAX_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_MAX_DISTANCE\u0026\u0026(t.PARTIAL_RIP_MAX_DISTANCE=e.PARTIAL_RIP_MAX_DISTANCE),void 0!==e.PARTIAL_RIP_QUALITY_MAX_DISTANCE\u0026\u0026(t.PARTIAL_RIP_QUALITY_MAX_DISTANCE=e.PARTIAL_RIP_QUALITY_MAX_DISTANCE),void 0!==e.PARTIAL_RIP_MAX_ATTEMPTS\u0026\u0026(t.PARTIAL_RIP_MAX_ATTEMPTS=e.PARTIAL_RIP_MAX_ATTEMPTS),void 0!==e.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS\u0026\u0026(t.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS=e.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS),void 0!==e.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT\u0026\u0026(t.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT=e.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO\u0026\u0026(t.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO=e.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO),void 0!==e.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO\u0026\u0026(t.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO=e.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO),void 0!==e.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO\u0026\u0026(t.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO=e.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO),void 0!==e.OUTSIDE_IN_ROUTING\u0026\u0026(t.OUTSIDE_IN_ROUTING=e.OUTSIDE_IN_ROUTING),void 0!==e.OUTSIDE_IN_MAX_DISTANCE\u0026\u0026(t.OUTSIDE_IN_MAX_DISTANCE=e.OUTSIDE_IN_MAX_DISTANCE))},tB=t=\u003e({minViaPadDiameter:t.minViaPadDiameter,DISTANCE_TO_COST:t.DISTANCE_TO_COST,RIP_THRESHOLD_START:t.RIP_THRESHOLD_START,RIP_THRESHOLD_END:t.RIP_THRESHOLD_END,RIP_THRESHOLD_RAMP_ATTEMPTS:t.RIP_THRESHOLD_RAMP_ATTEMPTS,RIP_CONGESTION_REGION_COST_FACTOR:t.RIP_CONGESTION_REGION_COST_FACTOR,TRACE_DENSITY_COST_FACTOR:t.TRACE_DENSITY_COST_FACTOR,USE_LAZY_ROUTE_HEURISTIC:t.USE_LAZY_ROUTE_HEURISTIC,USE_SPARSE_CANDIDATE_STORAGE:t.USE_SPARSE_CANDIDATE_STORAGE,MAX_ITERATIONS:t.MAX_ITERATIONS,VERBOSE:t.VERBOSE,STATIC_REACHABILITY_PRECHECK:t.STATIC_REACHABILITY_PRECHECK,STATIC_REACHABILITY_PRECHECK_MAX_HOPS:t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:t.ACCEPT_BEST_SOLUTION_ON_TIMEOUT,GREEDY_FINAL_ROUTE_ITERS:t.GREEDY_FINAL_ROUTE_ITERS,PARTIAL_RIP_ENABLED:t.PARTIAL_RIP_ENABLED,PARTIAL_RIP_MIN_ROUTE_COUNT:t.PARTIAL_RIP_MIN_ROUTE_COUNT,PARTIAL_RIP_MAX_ROUTE_COUNT:t.PARTIAL_RIP_MAX_ROUTE_COUNT,PARTIAL_RIP_MAX_DISTANCE:t.PARTIAL_RIP_MAX_DISTANCE,PARTIAL_RIP_QUALITY_MAX_DISTANCE:t.PARTIAL_RIP_QUALITY_MAX_DISTANCE,PARTIAL_RIP_MAX_ATTEMPTS:t.PARTIAL_RIP_MAX_ATTEMPTS,PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS:t.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:t.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT,PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO:t.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO,PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO:t.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO,PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO:t.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO,OUTSIDE_IN_ROUTING:t.OUTSIDE_IN_ROUTING,OUTSIDE_IN_MAX_DISTANCE:t.OUTSIDE_IN_MAX_DISTANCE}),eB=(t,e)=\u003et.f-e.f,nB=class extends kt{constructor(t,e,n){super(),this.topology=t,this.problem=e,QF(this,n);let o=1;const i=new Int32Array(t.portCount).fill(-1),r=new Int32Array(t.portCount).fill(-1);for(let e=0;e\u003ct.portCount;e++){const n=t.incidentPortRegion[e]??[];n.length\u003eo\u0026\u0026(o=n.length),i[e]=n[0]??-1,r[e]=n[1]??-1}this.candidateHopSlotStride=o,this.candidateFirstRegionByPortId=i,this.candidateSecondRegionByPortId=r;const s=t.portCount*o;this.candidateHopCapacity=s,this.state={portAssignment:new Int32Array(t.portCount).fill(-1),regionSegments:Array.from({length:t.regionCount},()=\u003e[]),regionIntersectionCaches:Array.from({length:t.regionCount},()=\u003eqF()),currentRouteId:void 0,currentRouteNetId:void 0,unroutedRoutes:oF(e.routeCount),candidateQueue:new Zz([],eB),candidateBestCostByHopId:this.USE_SPARSE_CANDIDATE_STORAGE?new Map:new Float64Array(s),candidateBestCostGenerationByHopId:this.USE_SPARSE_CANDIDATE_STORAGE?new Map:new Uint32Array(s),candidateBestCostGeneration:1,goalPortId:-1,ripCount:0,regionCongestionCost:new Float64Array(t.regionCount).fill(0)},this.routeAttemptCountByRouteId=new Uint32Array(e.routeCount),this.routeSuccessCountByRouteId=new Uint32Array(e.routeCount);const a=Uz({topology:t,problem:e,state:this.state,routeSuccessCountByRouteId:this.routeSuccessCountByRouteId,appendSegmentToRegionCache:(t,e,n)=\u003ethis.appendSegmentToRegionCache(t,e,n)});a\u0026\u0026(this.stats={...this.stats,...a})}topology;problem;state;candidateHopSlotStride;candidateHopCapacity;candidateFirstRegionByPortId;candidateSecondRegionByPortId;candidateOverflowBestCost;_problemSetup;routeAttemptCountByRouteId;routeSuccessCountByRouteId;bestSolvedStateSnapshot;bestSolvedStateSummary;hasLoggedNeverSuccessfullyRoutedRoutes=!1;staticallyUnroutableRoutes=[];segmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};ADD_SEGMENT_DISTANCE_TO_G=!1;DISTANCE_TO_COST=.05;minViaPadDiameter=Yz;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;RIP_CONGESTION_REGION_COST_FACTOR=.1;TRACE_DENSITY_COST_FACTOR=0;USE_LAZY_ROUTE_HEURISTIC=!1;USE_SPARSE_CANDIDATE_STORAGE=!1;MAX_ITERATIONS=1e6;VERBOSE=!1;STATIC_REACHABILITY_PRECHECK=!0;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;ACCEPT_BEST_SOLUTION_ON_TIMEOUT=!0;GREEDY_FINAL_ROUTE_ITERS=4;PARTIAL_RIP_ENABLED=!1;PARTIAL_RIP_MIN_ROUTE_COUNT=0;PARTIAL_RIP_MAX_ROUTE_COUNT=Number.POSITIVE_INFINITY;PARTIAL_RIP_MAX_DISTANCE=12;PARTIAL_RIP_QUALITY_MAX_DISTANCE;PARTIAL_RIP_MAX_ATTEMPTS=Number.POSITIVE_INFINITY;PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS=0;PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT=Number.POSITIVE_INFINITY;PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO=0;PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO=.2;PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO=.1;OUTSIDE_IN_ROUTING=!1;OUTSIDE_IN_MAX_DISTANCE=24;get problemSetup(){return this._problemSetup||(this._problemSetup=this.computeProblemSetup()),this._problemSetup}computeProblemSetup(){const{topology:t,problem:e}=this,n=this.USE_LAZY_ROUTE_HEURISTIC?void 0:new Float64Array(t.portCount*e.routeCount),o=t.portX,i=t.portY,r=Array.from({length:t.portCount},()=\u003enew Set),s=new Int32Array(t.portCount).fill(-1),a=(t,e)=\u003e{r[t].add(e);const n=s[t];-1===n?s[t]=e:n!==e\u0026\u0026(s[t]=-2)};for(let r=0;r\u003ce.routeCount;r++){const s=e.routeNet[r];if(a(e.routeStartPort[r],s),a(e.routeEndPort[r],s),n){const s=e.routeEndPort[r],a=o[s],c=i[s];for(let s=0;s\u003ct.portCount;s++){const t=o[s]-a,l=i[s]-c;n[s*e.routeCount+r]=Math.sqrt(t*t+l*l)*this.DISTANCE_TO_COST}}}return{portHCostToEndOfRoute:n,portEndpointNetIds:r,portEndpointReservationNetId:s}}_setup(){if(this.problemSetup,this.STATIC_REACHABILITY_PRECHECK){const t=nF({topology:this.topology,problem:this.problem,problemSetup:this.problemSetup,portAssignment:this.state.portAssignment,routeIds:this.state.unroutedRoutes,maxPrecheckHops:Math.max(0,this.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),getStartingNextRegionId:(t,e)=\u003ethis.getStartingNextRegionId(t,e),getRouteSummary:t=\u003ethis.getRouteSummary(t)});this.staticallyUnroutableRoutes=t,t.length\u003e0\u0026\u0026(this.failed=!0,this.error=(t=\u003e{const e=t.slice(0,5).map(t=\u003e{const e=t.pointIds.length\u003e=2?`${t.pointIds[0]}-\u003e${t.pointIds[1]}`:`${t.startPortId}-\u003e${t.endPortId}`;return`${t.connectionId} (${e})`}).join(\", \"),n=t.length-5;return[\"Static reachability precheck failed:\",`${t.length} route(s) have no legal path under the current reservation and start-region rules`,n\u003e0?`${e}, +${n} more`:e].join(\" \")})(t),this.stats={...this.stats,staticallyUnroutableRouteCount:t.length})}}_step(){const{problem:t,topology:e,state:n}=this;if(void 0===n.currentRouteId){if(0===n.unroutedRoutes.length)return void this.onAllRoutesRouted();n.currentRouteId=n.unroutedRoutes.shift(),n.currentRouteNetId=t.routeNet[n.currentRouteId],this.routeAttemptCountByRouteId[n.currentRouteId]+=1,this.resetCandidateBestCosts();const e=this.getRouteStartPortId(n.currentRouteId);n.candidateQueue.clear();const o=this.getStartingNextRegionId(n.currentRouteId,e);if(void 0===o)return this.failed=!0,void(this.error=`Start port ${e} has no incident regions`);this.setCandidateBestCost(this.getHopId(e,o),0),n.candidateQueue.queue({nextRegionId:o,portId:e,f:0,g:0,h:0}),n.goalPortId=this.getRouteEndPortId(n.currentRouteId)}const o=n.candidateQueue.dequeue();if(!o)return void this.onOutOfCandidates();const i=this.getHopId(o.portId,o.nextRegionId);if(o.g\u003ethis.getCandidateBestCost(i))return;if(this.isRegionReservedForDifferentNet(o.nextRegionId))return;const r=e.regionIncidentPorts[o.nextRegionId];for(const i of r){const r=n.portAssignment[i];if(this.isPortReservedForDifferentNet(i))continue;if(i===n.goalPortId){if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;return void this.onPathFound(o)}if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;if(i===o.portId)continue;if(0===t.portSectionMask[i])continue;const s=e.incidentPortRegion[i][0]===o.nextRegionId?e.incidentPortRegion[i][1]:e.incidentPortRegion[i][0];if(void 0===s||this.isRegionReservedForDifferentNet(s))continue;const a=this.getHopId(i,s);if(!0===n.candidateQueue.isClosedHop?.(i,s))continue;const c=this.getCandidateBestCost(a);if(o.g\u003e=c)continue;const l=this.computeG(o,i,c);if(!Number.isFinite(l)||l\u003e=c)continue;const d=this.computeH(i),h={prevRegionId:o.nextRegionId,nextRegionId:s,portId:i,g:l,h:d,f:l+d,prevCandidate:o};if(i===n.goalPortId)return void this.onPathFound(h);this.setCandidateBestCost(a,l),n.candidateQueue.queue(h)}}resetCandidateBestCosts(){const{state:t}=this;if(this.candidateOverflowBestCost?.clear(),4294967295===t.candidateBestCostGeneration)return t.candidateBestCostByHopId instanceof Map\u0026\u0026t.candidateBestCostByHopId.clear(),t.candidateBestCostGenerationByHopId instanceof Map?t.candidateBestCostGenerationByHopId.clear():t.candidateBestCostGenerationByHopId.fill(0),void(t.candidateBestCostGeneration=1);t.candidateBestCostGeneration+=1}getCandidateBestCost(t){if(t\u003c0)return this.candidateOverflowBestCost?.get(t)??Number.POSITIVE_INFINITY;const{state:e}=this,n=e.candidateBestCostGenerationByHopId;return(n instanceof Map?n.get(t):n[t])===e.candidateBestCostGeneration?e.candidateBestCostByHopId instanceof Map?e.candidateBestCostByHopId.get(t):e.candidateBestCostByHopId[t]:Number.POSITIVE_INFINITY}setCandidateBestCost(t,e){if(t\u003c0)return this.candidateOverflowBestCost||(this.candidateOverflowBestCost=new Map),void this.candidateOverflowBestCost.set(t,e);const{state:n}=this;n.candidateBestCostGenerationByHopId instanceof Map?n.candidateBestCostGenerationByHopId.set(t,n.candidateBestCostGeneration):n.candidateBestCostGenerationByHopId[t]=n.candidateBestCostGeneration,n.candidateBestCostByHopId instanceof Map?n.candidateBestCostByHopId.set(t,e):n.candidateBestCostByHopId[t]=e}getHopId(t,e){const n=t*this.candidateHopSlotStride;if(this.candidateFirstRegionByPortId[t]===e)return n;if(this.candidateSecondRegionByPortId[t]===e)return n+1;const o=this.topology.incidentPortRegion[t];for(let t=2;t\u003c(o?.length??0);t++)if(o[t]===e)return n+t;return-(t*this.topology.regionCount+e)-1}getStartingNextRegionId(t,e){const n=this.topology.incidentPortRegion[e]??[],o=this.problem.routeNet[t];return n.find(t=\u003e-1===this.problem.regionNetId[t])??n.find(t=\u003ethis.problem.regionNetId[t]===o)??n[0]}getRouteStartPortId(t){return this.problem.routeStartPort[t]}getRouteEndPortId(t){return this.problem.routeEndPort[t]}isPortReservedForDifferentNet(t){const e=this.problemSetup.portEndpointReservationNetId[t]??-1;return-2===e||-1!==e\u0026\u0026e!==this.state.currentRouteNetId}isRegionReservedForDifferentNet(t){const e=this.problem.regionNetId[t];return-1!==e\u0026\u0026e!==this.state.currentRouteNetId}isKnownSingleLayerRegion(t){const e=this.topology.regionAvailableZMask?.[t]??0;return Xz(e)}computeRegionCostForRegion(t,e,n,o,i){return((t,e,n,o,i,r,s=0,a=.3,c=0)=\u003eVz(t*e,n,o,i,r,s,a,c))(this.topology.regionWidth[t],this.topology.regionHeight[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0,this.minViaPadDiameter,this.TRACE_DENSITY_COST_FACTOR)}populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.segmentGeometryScratch,r=this.candidateFirstRegionByPortId[e]===t||this.candidateSecondRegionByPortId[e]!==t?o.portAngleForRegion1[e]:o.portAngleForRegion2?.[e]??o.portAngleForRegion1[e],s=this.candidateFirstRegionByPortId[n]===t||this.candidateSecondRegionByPortId[n]!==t?o.portAngleForRegion1[n]:o.portAngleForRegion2?.[n]??o.portAngleForRegion1[n],a=o.portZ[e],c=o.portZ[n];return i.lesserAngle=r\u003cs?r:s,i.greaterAngle=r\u003cs?s:r,i.layerMask=1\u003c\u003ca|1\u003c\u003cc,i.entryExitLayerChanges=a!==c?1:0,i}appendSegmentToRegionCache(t,e,n){const{state:o}=this,i=o.regionIntersectionCaches[t],r=this.populateSegmentGeometryScratch(t,e,n),[s,a,c]=Hz(i,o.currentRouteNetId,r.lesserAngle,r.greaterAngle,r.layerMask,r.entryExitLayerChanges),l=i.netIds.length+1,d=new Int32Array(l);d.set(i.netIds),d[l-1]=o.currentRouteNetId;const h=new Int32Array(l);h.set(i.lesserAngles),h[l-1]=r.lesserAngle;const u=new Int32Array(l);u.set(i.greaterAngles),u[l-1]=r.greaterAngle;const p=new Int32Array(l);p.set(i.layerMasks),p[l-1]=r.layerMask;const m=i.existingSameLayerIntersections+s,g=i.existingCrossingLayerIntersections+a,f=i.existingEntryExitLayerChanges+c,y=h.length;o.regionIntersectionCaches[t]={netIds:d,lesserAngles:h,greaterAngles:u,layerMasks:p,existingSameLayerIntersections:m,existingCrossingLayerIntersections:g,existingEntryExitLayerChanges:f,existingSegmentCount:y,existingRegionCost:this.computeRegionCostForRegion(t,m,g,f,y)}}getSolvedPathSegments(t){const{state:e}=this,n=[];let o=t;for(;o;)n.unshift(o),o=o.prevCandidate;const i=[];for(let t=1;t\u003cn.length;t++)i.push({regionId:n[t-1].nextRegionId,fromPortId:n[t-1].portId,toPortId:n[t].portId});const r=n[n.length-1];return r\u0026\u0026r.portId!==e.goalPortId\u0026\u0026i.push({regionId:r.nextRegionId,fromPortId:r.portId,toPortId:e.goalPortId}),i}resetRoutingStateForRerip(){const{topology:t,problem:e,state:n}=this;n.portAssignment.fill(-1),n.regionSegments=Array.from({length:t.regionCount},()=\u003e[]),n.regionIntersectionCaches=Array.from({length:t.regionCount},()=\u003eqF()),n.currentRouteNetId=void 0,n.currentRouteId=void 0,n.unroutedRoutes=qz(oF(e.routeCount),n.ripCount),n.candidateQueue.clear(),this.resetCandidateBestCosts(),n.goalPortId=-1}getMaxRegionCost(){const{topology:t,state:e}=this;let n=0;for(let o=0;o\u003ct.regionCount;o++){const t=e.regionIntersectionCaches[o]?.existingRegionCost??0;n=Math.max(n,t)}return n}getRouteMetadata(t){return this.problem.routeMetadata?.[t]}getRouteConnectionId(t){const e=this.getRouteMetadata(t)?.connectionId;return\"string\"==typeof e?e:`route-${t}`}getRouteSummary(t){return(({problem:t,routeId:e,getRouteMetadata:n,getRouteConnectionId:o})=\u003e{const i=n?.(e)??Jz(t,e);return{routeId:e,connectionId:o?.(e)??Qz(t,e),startPortId:t.routeStartPort[e],endPortId:t.routeEndPort[e],startRegionId:\"string\"==typeof i?.startRegionId?i.startRegionId:void 0,endRegionId:\"string\"==typeof i?.endRegionId?i.endRegionId:void 0,pointIds:Kz(i)}})({problem:this.problem,routeId:t,getRouteMetadata:t=\u003ethis.getRouteMetadata(t),getRouteConnectionId:t=\u003ethis.getRouteConnectionId(t)})}getAdditionalRegionLabel(t){}getNeverSuccessfullyRoutedRoutes(){const t=[];for(let e=0;e\u003cthis.problem.routeCount;e++){const n=this.routeAttemptCountByRouteId[e];0===n||this.routeSuccessCountByRouteId[e]\u003e0||t.push({...this.getRouteSummary(e),attempts:n})}return t}getStaticallyUnroutableRoutes(){return this.staticallyUnroutableRoutes}logNeverSuccessfullyRoutedRoutes(){if(!this.VERBOSE||this.hasLoggedNeverSuccessfullyRoutedRoutes)return;const t=this.getNeverSuccessfullyRoutedRoutes();if(this.hasLoggedNeverSuccessfullyRoutedRoutes=!0,0!==t.length){console.log([\"[TinyHyperGraphSolver:never-routed-summary]\",`count=${t.length}`].join(\" \"));for(const e of t){const t=e.pointIds.length\u003e=2?`${e.pointIds[0]}-\u003e${e.pointIds[1]}`:\"unknown\";console.log([\"[TinyHyperGraphSolver:never-routed]\",`routeId=${e.routeId}`,`connectionId=${e.connectionId}`,`attempts=${e.attempts}`,`pointPath=${t}`,`startRegionId=${e.startRegionId??\"unknown\"}`,`endRegionId=${e.endRegionId??\"unknown\"}`].join(\" \"))}}}logRipEvent(t,e,n={}){this.VERBOSE\u0026\u0026console.log([\"[TinyHyperGraphSolver:rip]\",`ripCount=${this.state.ripCount}`,`maxRegionCostBeforeRip=${e.toFixed(3)}`,`reason=${t}`,...Object.entries(n).map(([t,e])=\u003e`${t}=${\"number\"==typeof e?Number.isInteger(e)?String(e):e.toFixed(3):e}`)].join(\" \"))}compareRegionCostSummaries(t,e){return t.maxRegionCost!==e.maxRegionCost?t.maxRegionCost-e.maxRegionCost:t.totalRegionCost-e.totalRegionCost}captureBestSolvedState(t){this.bestSolvedStateSummary\u0026\u0026this.compareRegionCostSummaries(t,this.bestSolvedStateSummary)\u003e=0||this.replaceBestSolvedState(t)}replaceBestSolvedState(t){this.bestSolvedStateSummary=t,this.bestSolvedStateSnapshot=KF({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches,regionCongestionCost:this.state.regionCongestionCost,ripCount:this.state.ripCount})}restoreBestSolvedState(){if(!this.bestSolvedStateSnapshot)return;const t=KF(this.bestSolvedStateSnapshot);this.state.portAssignment=t.portAssignment,this.state.regionSegments=t.regionSegments,this.state.regionIntersectionCaches=t.regionIntersectionCaches,this.state.regionCongestionCost=t.regionCongestionCost,this.state.ripCount=t.ripCount,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1}getRemainingRouteIdsForGreedyFinalRoute(){const t=new Set(this.state.unroutedRoutes);return void 0!==this.state.currentRouteId\u0026\u0026t.add(this.state.currentRouteId),[...t]}applySnapshotToGreedyFinalRouteSolver(t,e,n){const o=KF(e);t.state.portAssignment=o.portAssignment,t.state.regionSegments=o.regionSegments,t.state.regionIntersectionCaches=o.regionIntersectionCaches,t.state.regionCongestionCost=o.regionCongestionCost,t.state.ripCount=0,t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.state.unroutedRoutes=[...n],t.state.candidateQueue.clear(),t.resetCandidateBestCosts(),t.state.goalPortId=-1}summarizeSolvedState(t){let e=0,n=0;for(const o of t.state.regionIntersectionCaches){const t=o.existingRegionCost;e=Math.max(e,t),n+=t}return{maxRegionCost:e,totalRegionCost:n}}tryGreedyFinalRouteAcceptance(){const t=Math.max(0,Math.floor(this.GREEDY_FINAL_ROUTE_ITERS));if(0===t)return!1;const e=this.getRemainingRouteIdsForGreedyFinalRoute();if(0===e.length)return!1;const n=KF({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches,regionCongestionCost:this.state.regionCongestionCost,ripCount:this.state.ripCount});for(let o=0;o\u003ct;o++){const t=0===o?e:qz(e,this.state.ripCount+o),i=new oB(this.topology,this.problem,{...tB(this),ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!1,GREEDY_FINAL_ROUTE_ITERS:0,MAX_ITERATIONS:ZF,RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!1});if(this.applySnapshotToGreedyFinalRouteSolver(i,n,t),i.solve(),i.solved\u0026\u0026!i.failed)return this.bestSolvedStateSnapshot=KF({portAssignment:i.state.portAssignment,regionSegments:i.state.regionSegments,regionIntersectionCaches:i.state.regionIntersectionCaches,regionCongestionCost:i.state.regionCongestionCost,ripCount:i.state.ripCount}),this.bestSolvedStateSummary=this.summarizeSolvedState(i),this.restoreBestSolvedState(),this.stats={...this.stats,acceptedGreedyFinalRouteOnTimeout:!0,greedyFinalRouteIter:o,greedyFinalRouteRemainingRouteCount:e.length,greedyFinalRouteMaxIterations:ZF,neverSuccessfullyRoutedRouteCount:0,maxRegionCost:this.bestSolvedStateSummary.maxRegionCost,totalRegionCost:this.bestSolvedStateSummary.totalRegionCost,bestMaxRegionCost:this.bestSolvedStateSummary.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary.totalRegionCost},this.solved=!0,this.failed=!1,this.error=null,!0}return this.stats={...this.stats,greedyFinalRouteAttemptCount:t,greedyFinalRouteRemainingRouteCount:e.length,greedyFinalRouteMaxIterations:ZF},!1}onAllRoutesRouted(){const{topology:t,state:e}=this,n=this.RIP_THRESHOLD_RAMP_ATTEMPTS\u003c=0?1:Math.min(1,e.ripCount/this.RIP_THRESHOLD_RAMP_ATTEMPTS),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(t.regionCount);let s=0,a=0;for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;r[n]=t,s=Math.max(s,t),a+=t,t\u003eo\u0026\u0026i.push(n)}if(this.captureBestSolvedState({maxRegionCost:s,totalRegionCost:a}),this.stats={...this.stats,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:s,totalRegionCost:a,bestMaxRegionCost:this.bestSolvedStateSummary?.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary?.totalRegionCost,ripCount:e.ripCount},0===i.length||e.ripCount\u003e=this.RIP_THRESHOLD_RAMP_ATTEMPTS)this.solved=!0;else{for(let n=0;n\u003ct.regionCount;n++)e.regionCongestionCost[n]+=r[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCostBeforeRip:s,reripRegionCount:i.length},this.logRipEvent(\"hot_regions\",s,{hotRegionCount:i.length,currentRipThreshold:o})}}onOutOfCandidates(){const{topology:t,state:e}=this,n=e.currentRouteId,o=this.getMaxRegionCost();for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;e.regionCongestionCost[n]+=t*this.RIP_CONGESTION_REGION_COST_FACTOR}e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCost:o,maxRegionCostBeforeRip:o,reripReason:\"out_of_candidates\"},this.logRipEvent(\"out_of_candidates\",o,{...void 0===n?{}:{routeId:n,connectionId:this.getRouteConnectionId(n)}})}onPathFound(t){const{state:e}=this,n=e.currentRouteId;if(void 0===n)return;this.routeSuccessCountByRouteId[n]+=1;const o=this.getSolvedPathSegments(t);for(const{regionId:t,fromPortId:i,toPortId:r}of o)e.regionSegments[t].push([n,i,r]),e.portAssignment[i]=e.currentRouteNetId,e.portAssignment[r]=e.currentRouteNetId,this.appendSegmentToRegionCache(t,i,r);e.candidateQueue.clear(),e.currentRouteNetId=void 0,e.currentRouteId=void 0}computeG(t,e,n=Number.POSITIVE_INFINITY,o){const{state:i,topology:r}=this,s=t.nextRegionId,a=i.regionIntersectionCaches[s];let c=0;if(this.ADD_SEGMENT_DISTANCE_TO_G){let n=o;if(void 0===n){const o=r.portX[t.portId]-r.portX[e],i=r.portY[t.portId]-r.portY[e];n=Math.sqrt(o*o+i*i)}c=n*this.DISTANCE_TO_COST}if(t.g+i.regionCongestionCost[s]+(this.problem.portPenalty?.[e]??0)+c\u003en+1e-9)return Number.POSITIVE_INFINITY;const l=t.portId,d=this.candidateFirstRegionByPortId[l]===s||this.candidateSecondRegionByPortId[l]!==s?r.portAngleForRegion1[l]:r.portAngleForRegion2?.[l]??r.portAngleForRegion1[l],h=this.candidateFirstRegionByPortId[e]===s||this.candidateSecondRegionByPortId[e]!==s?r.portAngleForRegion1[e]:r.portAngleForRegion2?.[e]??r.portAngleForRegion1[e],u=d\u003ch?d:h,p=d\u003ch?h:d,m=r.portZ[l],g=r.portZ[e],f=1\u003c\u003cm|1\u003c\u003cg,y=m!==g?1:0,[_,b,x]=Hz(a,i.currentRouteNetId,u,p,f,y);if(_\u003e0\u0026\u0026this.isKnownSingleLayerRegion(s))return Number.POSITIVE_INFINITY;const v=this.computeRegionCostForRegion(s,a.existingSameLayerIntersections+_,a.existingCrossingLayerIntersections+b,a.existingEntryExitLayerChanges+x,a.existingSegmentCount+1)-a.existingRegionCost;return t.g+v+i.regionCongestionCost[s]+(this.problem.portPenalty?.[e]??0)+c}tryFinalAcceptance(){const t=this.getNeverSuccessfullyRoutedRoutes();if(this.stats={...this.stats,neverSuccessfullyRoutedRouteCount:t.length},this.ACCEPT_BEST_SOLUTION_ON_TIMEOUT\u0026\u0026this.bestSolvedStateSnapshot\u0026\u0026this.bestSolvedStateSummary)return this.restoreBestSolvedState(),this.stats={...this.stats,acceptedBestSolutionOnTimeout:!0,maxRegionCost:this.bestSolvedStateSummary.maxRegionCost,totalRegionCost:this.bestSolvedStateSummary.totalRegionCost,bestMaxRegionCost:this.bestSolvedStateSummary.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary.totalRegionCost},this.solved=!0,this.failed=!1,void(this.error=null);this.ACCEPT_BEST_SOLUTION_ON_TIMEOUT\u0026\u0026this.tryGreedyFinalRouteAcceptance()||this.logNeverSuccessfullyRoutedRoutes()}computeH(t){const e=this.problemSetup.portHCostToEndOfRoute;if(e)return e[t*this.problem.routeCount+this.state.currentRouteId];const n=this.getRouteEndPortId(this.state.currentRouteId),o=this.topology.portX[t]-this.topology.portX[n],i=this.topology.portY[t]-this.topology.portY[n];return Math.sqrt(o*o+i*i)*this.DISTANCE_TO_COST}visualize(){return UF(this)}getOutput(){return $z(this)}},oB=class extends nB{computeG(t,e){return t.g}},iB=class{constructor(t,e){this.regionCount=t,this.compactHopIndex=e,e\u0026\u0026(this.hopStateGeneration=new Uint32Array(e.hopCapacity),this.hopIndexOrClosed=new Int32Array(e.hopCapacity))}regionCount;compactHopIndex;items=[];indexByHopId=new Map;closedHopIds=new Set;hopStateGeneration;hopIndexOrClosed;currentHopStateGeneration=1;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0,this.indexByHopId.clear(),this.closedHopIds.clear(),this.hopStateGeneration\u0026\u0026(4294967295===this.currentHopStateGeneration?(this.hopStateGeneration.fill(0),this.currentHopStateGeneration=1):this.currentHopStateGeneration+=1)}isClosedHop(t,e){return this.isHopClosed(this.getHopIdFromValues(t,e))}queue(t){const e=this.getHopId(t);if(this.isHopClosed(e))return;const n=this.getQueuedHopIndex(e);if(void 0!==n){const e=this.items[n];if(t.g\u003e=e.g)return;return this.items[n]=t,void(t.f\u003c=e.f?this.siftUp(n):this.siftDown(n))}const o=this.items.length;this.items.push(t),this.siftUp(o)}dequeue(){const t=this.items[0];if(!t)return;const e=this.getHopId(t);this.closeHop(e);const n=this.items.pop();return this.items.length\u003e0\u0026\u0026(this.items[0]=n,this.siftDown(0)),t}getHopId(t){return this.getHopIdFromValues(t.portId,t.nextRegionId)}getHopIdFromValues(t,e){const n=this.compactHopIndex;if(!n)return t*this.regionCount+e;const o=t*n.hopSlotStride;if(n.firstRegionByPortId[t]===e)return o;if(n.secondRegionByPortId[t]===e)return o+1;const i=n.incidentPortRegion[t];for(let t=2;t\u003c(i?.length??0);t++)if(i[t]===e)return o+t;return-(t*this.regionCount+e)-1}getQueuedHopIndex(t){if(t\u003e=0\u0026\u0026this.hopStateGeneration?.[t]===this.currentHopStateGeneration){const e=this.hopIndexOrClosed[t];return e\u003e=0?e:void 0}return this.indexByHopId.get(t)}isHopClosed(t){return t\u003e=0\u0026\u0026this.hopStateGeneration?.[t]===this.currentHopStateGeneration?-1===this.hopIndexOrClosed[t]:this.closedHopIds.has(t)}setQueuedHopIndex(t,e){if(t\u003e=0\u0026\u0026this.hopStateGeneration)return this.hopStateGeneration[t]=this.currentHopStateGeneration,void(this.hopIndexOrClosed[t]=e);this.indexByHopId.set(t,e)}closeHop(t){if(t\u003e=0\u0026\u0026this.hopStateGeneration)return this.hopStateGeneration[t]=this.currentHopStateGeneration,void(this.hopIndexOrClosed[t]=-1);this.indexByHopId.delete(t),this.closedHopIds.add(t)}siftUp(t){const e=this.items[t];let n=t;for(;n\u003e0;){const t=n-1\u003e\u003e1,o=this.items[t];if(o.f\u003c=e.f)break;this.items[n]=o,this.setQueuedHopIndex(this.getHopId(o),n),n=t}this.items[n]=e,this.setQueuedHopIndex(this.getHopId(e),n)}siftDown(t){const e=this.items[t];let n=t;for(;;){const t=2*n+1;if(t\u003e=this.items.length)break;const o=t+1,i=o\u003cthis.items.length\u0026\u0026this.items[o].f\u003cthis.items[t].f?o:t,r=this.items[i];if(e.f\u003c=r.f)break;this.items[n]=r,this.setQueuedHopIndex(this.getHopId(r),n),n=i}this.items[n]=e,this.setQueuedHopIndex(this.getHopId(e),n)}},rB=class extends nB{constructor(t,e,n){super(t,e,n),this.ADD_SEGMENT_DISTANCE_TO_G=!0}_setup(){super._setup(),this.state.candidateQueue=new iB(this.topology.regionCount,{hopCapacity:this.candidateHopCapacity,hopSlotStride:this.candidateHopSlotStride,firstRegionByPortId:this.candidateFirstRegionByPortId,secondRegionByPortId:this.candidateSecondRegionByPortId,incidentPortRegion:this.topology.incidentPortRegion})}onPathFound(t){const e=this.state.goalPortId;if(t.portId===e)return void super.onPathFound(t);const n=this.computeG(t,e);if(!Number.isFinite(n))return;const o=this.getHopId(e,t.nextRegionId);n\u003e=this.getCandidateBestCost(o)||(this.setCandidateBestCost(o,n),this.state.candidateQueue.queue({prevRegionId:t.nextRegionId,nextRegionId:t.nextRegionId,portId:e,g:n,h:0,f:n,prevCandidate:t}))}},sB=new Set,aB=class extends rB{partialRipRoutePlans=new Map;outsideInRouteSearch;oneSidedFallbackRouteId;partialRipWindowDistance;partialRipCount=0;partiallyRippedRouteCount=0;partiallyRippedSegmentCount=0;retainedPartialRipSegmentCount=0;outsideInRouteCount=0;outsideInCompletedRouteCount=0;outsideInFallbackRouteCount=0;outsideInForwardExpansionCount=0;outsideInReverseExpansionCount=0;outsideInDistancePruneCount=0;completedRoundSummaries=[];firstCompletedRoundSummary;partialRipQualityBaselineSummary;bestSolvedRoundSummary;partialRipTargetReached=!1;useComplexityAwareSelection=!1;constructor(t,e,n){super(t,e,n),void 0===n?.PARTIAL_RIP_ENABLED\u0026\u0026(this.PARTIAL_RIP_ENABLED=!0),void 0===n?.OUTSIDE_IN_ROUTING\u0026\u0026(this.OUTSIDE_IN_ROUTING=!0),this.PARTIAL_RIP_ENABLED\u0026\u0026void 0===n?.PARTIAL_RIP_MAX_ATTEMPTS\u0026\u0026(this.PARTIAL_RIP_MAX_ATTEMPTS=10),(e.routeCount\u003cMath.max(0,this.PARTIAL_RIP_MIN_ROUTE_COUNT)||e.routeCount\u003eMath.max(0,this.PARTIAL_RIP_MAX_ROUTE_COUNT))\u0026\u0026(this.PARTIAL_RIP_ENABLED=!1,this.OUTSIDE_IN_ROUTING=!1),this.useComplexityAwareSelection=e.routeCount\u003e=Math.max(0,this.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT)}getRouteStartPortId(t){return this.PARTIAL_RIP_ENABLED?this.partialRipRoutePlans.get(t)?.activeStartPortId??super.getRouteStartPortId(t):super.getRouteStartPortId(t)}getRouteEndPortId(t){return this.PARTIAL_RIP_ENABLED?this.partialRipRoutePlans.get(t)?.activeEndPortId??super.getRouteEndPortId(t):super.getRouteEndPortId(t)}getStartingNextRegionId(t,e){if(!this.PARTIAL_RIP_ENABLED)return super.getStartingNextRegionId(t,e);const n=this.partialRipRoutePlans.get(t);return n\u0026\u0026n.activeStartPortId===e?n.forcedStartRegionId:super.getStartingNextRegionId(t,e)}getEndingNextRegionId(t,e){const n=this.partialRipRoutePlans.get(t);return n\u0026\u0026n.activeEndPortId===e?n.forcedEndRegionId:super.getStartingNextRegionId(t,e)}computeH(t){if(!this.PARTIAL_RIP_ENABLED)return super.computeH(t);const e=this.state.currentRouteId;if(void 0===e||!this.partialRipRoutePlans.has(e))return super.computeH(t);const n=this.getRouteEndPortId(e),o=this.topology.portX[t]-this.topology.portX[n],i=this.topology.portY[t]-this.topology.portY[n];return Math.sqrt(o*o+i*i)*this.DISTANCE_TO_COST}onPathFound(t){if(!this.PARTIAL_RIP_ENABLED\u0026\u0026!this.OUTSIDE_IN_ROUTING)return void super.onPathFound(t);const e=this.state.currentRouteId,n=void 0!==e\u0026\u0026this.outsideInRouteSearch?.routeId===e;super.onPathFound(t),void 0!==e\u0026\u0026void 0===this.state.currentRouteId\u0026\u0026(this.partialRipRoutePlans.delete(e),n\u0026\u0026(this.outsideInCompletedRouteCount+=1),this.oneSidedFallbackRouteId===e\u0026\u0026(this.oneSidedFallbackRouteId=void 0)),this.outsideInRouteSearch=void 0,this.publishOutsideInStats()}resetRoutingStateForRerip(){this.PARTIAL_RIP_ENABLED||this.OUTSIDE_IN_ROUTING?(this.partialRipRoutePlans.clear(),this.outsideInRouteSearch=void 0,this.oneSidedFallbackRouteId=void 0,super.resetRoutingStateForRerip()):super.resetRoutingStateForRerip()}clearPartialRipPlans(t){for(const e of t)this.partialRipRoutePlans.delete(e)}getRouteIdsPreferredForPreservation(){return sB}getCommittedRouteSegments(t){const e=[];for(let n=0;n\u003cthis.state.regionSegments.length;n++)for(const[o,i,r]of this.state.regionSegments[n]??[])o===t\u0026\u0026e.push({segmentIndex:e.length,regionId:n,fromPortId:i,toPortId:r});if(0===e.length)return;const n=new Map;for(const t of e)for(const e of[t.fromPortId,t.toPortId]){const o=n.get(e)??[];o.push(t.segmentIndex),n.set(e,o)}const o=this.problem.routeEndPort[t],i=[],r=new Set,s=new Set([this.problem.routeStartPort[t]]),a=t=\u003e{if(t===o)return!0;for(const o of n.get(t)??[]){if(r.has(o))continue;const n=e[o],c=n.fromPortId===t?n.toPortId:n.fromPortId;if(!s.has(c)){if(r.add(o),s.add(c),i.push({regionId:n.regionId,fromPortId:t,toPortId:c}),a(c))return!0;i.pop(),s.delete(c),r.delete(o)}}return!1};return a(this.problem.routeStartPort[t])\u0026\u0026r.size===e.length?i:void 0}getSegmentDistance(t){const e=this.topology.portX[t.fromPortId]-this.topology.portX[t.toPortId],n=this.topology.portY[t.fromPortId]-this.topology.portY[t.toPortId];return Math.sqrt(e*e+n*n)}getPartialRipWindow(t,e,n){let o,i=Number.NEGATIVE_INFINITY;for(let r=0;r\u003ct.length;r++){const s=t[r];if(!e.has(s.regionId))continue;const a=n[s.regionId]??0;a\u003ei\u0026\u0026(i=a,o=r)}if(void 0===o)return;const r=Math.max(0,this.partialRipWindowDistance??this.PARTIAL_RIP_MAX_DISTANCE);let s=o,a=o,c=this.getSegmentDistance(t[o])/2,l=c;for(;s\u003e0;){const e=this.getSegmentDistance(t[s-1]);if(c+e\u003er)break;s-=1,c+=e}for(;a+1\u003ct.length;){const e=this.getSegmentDistance(t[a+1]);if(l+e\u003er)break;a+=1,l+=e}return{startIndex:s,endIndex:a}}appendRetainedSegment(t,e,n){t[n.regionId].push([e,n.fromPortId,n.toPortId])}preparePartialRip(t,e){if(!this.PARTIAL_RIP_ENABLED||0===t.length)return!1;const n=new Set(t);if(void 0===this.partialRipWindowDistance){let n=0;for(const o of t)n=Math.max(n,e[o]??0);const o=Math.max(0,this.PARTIAL_RIP_MAX_DISTANCE),i=Math.max(o,this.PARTIAL_RIP_QUALITY_MAX_DISTANCE??2*o);this.partialRipWindowDistance=n\u003c=1.5*this.RIP_THRESHOLD_END?i:o}const o=new Set;for(const e of t)for(const[t]of this.state.regionSegments[e]??[])o.add(t);if(0===o.size)return!1;const i=this.getRouteIdsPreferredForPreservation(),r=[...o].some(t=\u003e!i.has(t)),s=Array.from({length:this.topology.regionCount},()=\u003e[]),a=new Map;let c=0,l=0;for(let t=0;t\u003cthis.problem.routeCount;t++){const d=this.getCommittedRouteSegments(t);if(!d)return!1;if(!o.has(t)||r\u0026\u0026i.has(t)){for(const e of d)this.appendRetainedSegment(s,t,e),l+=1;continue}const h=this.getPartialRipWindow(d,n,e);if(!h)return!1;for(let e=0;e\u003cd.length;e++){const n=d[e];e\u003e=h.startIndex\u0026\u0026e\u003c=h.endIndex?c+=1:(this.appendRetainedSegment(s,t,n),l+=1)}const u=d[h.startIndex],p=d[h.endIndex];a.set(t,{routeId:t,activeStartPortId:u.fromPortId,activeEndPortId:p.toPortId,forcedStartRegionId:u.regionId,forcedEndRegionId:p.regionId,rippedSegmentCount:h.endIndex-h.startIndex+1,retainedSegmentCount:d.length-(h.endIndex-h.startIndex+1)})}return 0!==a.size\u0026\u00260!==c\u0026\u0026(this.partialRipRoutePlans=a,this.rebuildRetainedRoutingState(s,[...a.keys()]),this.partialRipCount+=1,this.partiallyRippedRouteCount+=a.size,this.partiallyRippedSegmentCount+=c,this.retainedPartialRipSegmentCount+=l,this.publishPartialRipStats(),!0)}rebuildRetainedRoutingState(t,e){this.state.portAssignment.fill(-1),this.state.regionSegments=Array.from({length:this.topology.regionCount},()=\u003e[]),this.state.regionIntersectionCaches=Array.from({length:this.topology.regionCount},()=\u003eqF()),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=e,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.outsideInRouteSearch=void 0,this.oneSidedFallbackRouteId=void 0;for(let e=0;e\u003ct.length;e++)for(const[n,o,i]of t[e]??[]){const t=this.problem.routeNet[n];this.state.currentRouteNetId=t;for(const e of[o,i]){const n=this.state.portAssignment[e];if(-1!==n\u0026\u0026n!==t)throw new Error(`OutsideInPartialRipTinyHyperGraphSolver: retained port ${e} belongs to multiple nets`);this.state.portAssignment[e]=t}this.state.regionSegments[e].push([n,o,i]),this.appendSegmentToRegionCache(e,o,i)}this.state.currentRouteNetId=void 0}publishPartialRipStats(){this.stats={...this.stats,partialRipCount:this.partialRipCount,partiallyRippedRouteCount:this.partiallyRippedRouteCount,partiallyRippedSegmentCount:this.partiallyRippedSegmentCount,retainedPartialRipSegmentCount:this.retainedPartialRipSegmentCount,partialRipMaxDistance:this.partialRipWindowDistance??this.PARTIAL_RIP_MAX_DISTANCE,partialRipBaseMaxDistance:this.PARTIAL_RIP_MAX_DISTANCE,partialRipQualityMaxDistance:this.PARTIAL_RIP_QUALITY_MAX_DISTANCE??2*this.PARTIAL_RIP_MAX_DISTANCE,partialRipMaxAttempts:this.PARTIAL_RIP_MAX_ATTEMPTS}}publishOutsideInStats(){this.stats={...this.stats,outsideInRouteCount:this.outsideInRouteCount,outsideInCompletedRouteCount:this.outsideInCompletedRouteCount,outsideInFallbackRouteCount:this.outsideInFallbackRouteCount,outsideInForwardExpansionCount:this.outsideInForwardExpansionCount,outsideInReverseExpansionCount:this.outsideInReverseExpansionCount,outsideInDistancePruneCount:this.outsideInDistancePruneCount,outsideInMaxDistance:this.OUTSIDE_IN_MAX_DISTANCE}}createOutsideInFrontier(t,e,n){const o=new Zz([],(t,e)=\u003et.f===e.f?t.g-e.g:t.f-e.f),i=this.topology.portX[t]-this.topology.portX[n],r=this.topology.portY[t]-this.topology.portY[n],s=Math.sqrt(i*i+r*r)*this.DISTANCE_TO_COST,a={portId:t,nextRegionId:e,f:s,g:0,h:s,travelDistance:0};return o.queue(a),{queue:o,bestCostByHopId:new Map([[this.getHopId(t,e),0]]),settledByPortId:new Map,settledByRegionId:new Map,targetPortId:n}}startOutsideInRouteSearch(t){const e=this.getRouteStartPortId(t),n=this.getRouteEndPortId(t),o=this.getStartingNextRegionId(t,e),i=this.getEndingNextRegionId(t,n);return void 0!==o\u0026\u0026void 0!==i\u0026\u0026(this.state.goalPortId=n,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.outsideInRouteSearch={routeId:t,forward:this.createOutsideInFrontier(e,o,n),reverse:this.createOutsideInFrontier(n,i,e),expandForwardNext:!0,distanceLimitHit:!1,bestJoinedCost:Number.POSITIVE_INFINITY},this.outsideInRouteCount+=1,this.publishOutsideInStats(),!0)}dequeueFreshCandidate(t){for(;t.queue.length\u003e0;){const e=t.queue.dequeue(),n=this.getHopId(e.portId,e.nextRegionId);if(e.g\u003c=(t.bestCostByHopId.get(n)??1/0))return e}}recordSettledCandidate(t,e){const n=t.settledByPortId.get(e.portId);(!n||e.g\u003cn.g)\u0026\u0026t.settledByPortId.set(e.portId,e);const o=t.settledByRegionId.get(e.nextRegionId)??[];o.push(e),o.sort((t,e)=\u003et.g-e.g),o.length\u003e16\u0026\u0026(o.length=16),t.settledByRegionId.set(e.nextRegionId,o)}getCandidatePath(t){const e=[];let n=t;for(;n;)e.push(n),n=n.prevCandidate;return e.reverse(),e}buildJoinedCandidate(t,e){const n=this.getCandidatePath(t),o=this.getCandidatePath(e),i=n.map(({portId:t})=\u003et),r=n.slice(0,-1).map(({nextRegionId:t})=\u003et);if(t.portId!==e.portId){if(t.nextRegionId!==e.nextRegionId)return;const n=this.topology.portX[t.portId]-this.topology.portX[e.portId],o=this.topology.portY[t.portId]-this.topology.portY[e.portId],s=Math.sqrt(n*n+o*o);if(t.travelDistance+e.travelDistance+s\u003e2*this.OUTSIDE_IN_MAX_DISTANCE)return;const a=this.computeG(t,e.portId);if(!Number.isFinite(a))return;r.push(t.nextRegionId),i.push(e.portId)}for(let t=o.length-2;t\u003e=0;t--){const e=o[t];r.push(e.nextRegionId),i.push(e.portId)}if(new Set(i).size!==i.length||r.length+1!==i.length)return;let s={portId:i[0],nextRegionId:r[0],f:0,g:0,h:0};for(let t=1;t\u003ci.length;t++)s={portId:i[t],prevRegionId:r[t-1],nextRegionId:r[t]??r[t-1],prevCandidate:s,f:0,g:0,h:0};const a=t.portId===e.portId?0:this.computeG(t,e.portId)-t.g;return{candidate:s,cost:t.g+e.g+a}}considerOutsideInJoins(t,e){const n=this.outsideInRouteSearch,o=e?n.reverse:n.forward,i=t=\u003e{!t||t.cost\u003e=n.bestJoinedCost||(n.bestJoinedCandidate=t.candidate,n.bestJoinedCost=t.cost,n.remainingPostMeetingExpansions=24)},r=o.settledByPortId.get(t.portId);r\u0026\u0026i(e?this.buildJoinedCandidate(t,r):this.buildJoinedCandidate(r,t));for(const n of o.settledByRegionId.get(t.nextRegionId)??[])i(e?this.buildJoinedCandidate(t,n):this.buildJoinedCandidate(n,t))}commitBestOutsideInJoin(){const t=this.outsideInRouteSearch?.bestJoinedCandidate;return!!t\u0026\u0026(this.onPathFound(t),!0)}expandOutsideInFrontier(t){const e=this.outsideInRouteSearch,n=t?e.forward:e.reverse,o=this.dequeueFreshCandidate(n);if(!o)return!1;if(t?this.outsideInForwardExpansionCount+=1:this.outsideInReverseExpansionCount+=1,this.isRegionReservedForDifferentNet(o.nextRegionId))return!0;this.recordSettledCandidate(n,o),this.considerOutsideInJoins(o,t);for(const t of this.topology.regionIncidentPorts[o.nextRegionId]??[]){if(t===o.portId)continue;if(this.isPortReservedForDifferentNet(t))continue;const i=this.state.portAssignment[t];if(-1!==i\u0026\u0026i!==this.state.currentRouteNetId)continue;if(t!==n.targetPortId\u0026\u00260===this.problem.portSectionMask[t])continue;const r=this.topology.portX[o.portId]-this.topology.portX[t],s=this.topology.portY[o.portId]-this.topology.portY[t],a=Math.sqrt(r*r+s*s),c=o.travelDistance+a;if(c\u003ethis.OUTSIDE_IN_MAX_DISTANCE){e.distanceLimitHit=!0,this.outsideInDistancePruneCount+=1;continue}const l=this.topology.incidentPortRegion[t]?.[0]===o.nextRegionId?this.topology.incidentPortRegion[t]?.[1]:this.topology.incidentPortRegion[t]?.[0];if(void 0===l||this.isRegionReservedForDifferentNet(l))continue;const d=this.getHopId(t,l),h=n.bestCostByHopId.get(d)??1/0;if(o.g\u003e=h)continue;const u=this.computeG(o,t,h,a);if(!Number.isFinite(u)||u\u003e=h)continue;n.bestCostByHopId.set(d,u);const p=this.topology.portX[t]-this.topology.portX[n.targetPortId],m=this.topology.portY[t]-this.topology.portY[n.targetPortId],g=Math.sqrt(p*p+m*m)*this.DISTANCE_TO_COST;n.queue.queue({portId:t,prevRegionId:o.nextRegionId,nextRegionId:l,prevCandidate:o,f:u+g,g:u,h:g,travelDistance:c})}return!0}fallBackToOneSidedRouteSearch(){const t=this.state.currentRouteId;void 0!==t\u0026\u0026(this.outsideInRouteSearch=void 0,this.outsideInFallbackRouteCount+=1,this.oneSidedFallbackRouteId=t,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.goalPortId=-1,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.unroutedRoutes.unshift(t),this.publishOutsideInStats())}_step(){if(!this.OUTSIDE_IN_ROUTING)return void super._step();const t=this.state.currentRouteId??this.state.unroutedRoutes[0];if(void 0!==t\u0026\u0026!this.partialRipRoutePlans.has(t))return void super._step();if(void 0!==this.oneSidedFallbackRouteId)return void super._step();if(void 0===this.state.currentRouteId){if(0===this.state.unroutedRoutes.length)return void this.onAllRoutesRouted();const t=this.state.unroutedRoutes.shift();if(this.state.currentRouteId=t,this.state.currentRouteNetId=this.problem.routeNet[t],this.routeAttemptCountByRouteId[t]+=1,!this.startOutsideInRouteSearch(t))return this.failed=!0,void(this.error=`Route ${t} has an endpoint without an incident region`)}const e=this.outsideInRouteSearch;if(!e)return;let n=this.expandOutsideInFrontier(e.expandForwardNext);if(void 0!==this.state.currentRouteId\u0026\u0026(n||(n=this.expandOutsideInFrontier(!e.expandForwardNext),void 0!==this.state.currentRouteId)))if(e.expandForwardNext=!e.expandForwardNext,e.bestJoinedCandidate\u0026\u0026(e.remainingPostMeetingExpansions=(e.remainingPostMeetingExpansions??1)-1,(e.remainingPostMeetingExpansions??0)\u003c=0))this.commitBestOutsideInJoin();else{if(!n\u0026\u00260===e.forward.queue.length\u0026\u00260===e.reverse.queue.length){if(this.commitBestOutsideInJoin())return;this.outsideInRouteSearch=void 0,e.distanceLimitHit?this.fallBackToOneSidedRouteSearch():this.onOutOfCandidates()}this.publishOutsideInStats()}}shouldReplaceBestSolvedState(t){const e=this.bestSolvedRoundSummary;if(!e)return!0;if(!this.useComplexityAwareSelection)return this.compareRegionCostSummaries(t,e)\u003c0;const n=this.partialRipQualityBaselineSummary;if(!n)return this.compareRegionCostSummaries(t,e)\u003c0;const o=this.firstCompletedRoundSummary??n,i=o.maxRegionCost*(1+Math.max(0,this.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO)),r=o.totalRegionCost*(1+Math.max(0,this.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO)),s=t.maxRegionCost\u003c=i\u0026\u0026t.totalRegionCost\u003c=r;return s!==(e.maxRegionCost\u003c=i\u0026\u0026e.totalRegionCost\u003c=r)?s:s\u0026\u0026t.segmentCount!==e.segmentCount?t.segmentCount\u003ce.segmentCount:this.compareRegionCostSummaries(t,e)\u003c0}onAllRoutesRouted(){if(!this.PARTIAL_RIP_ENABLED)return void super.onAllRoutesRouted();const{state:t,topology:e}=this,n=Math.min(this.RIP_THRESHOLD_RAMP_ATTEMPTS,this.PARTIAL_RIP_MAX_ATTEMPTS),o=Math.max(0,this.RIP_THRESHOLD_RAMP_ATTEMPTS),i=o\u003c=0?1:Math.min(1,t.ripCount/o),r=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*i,s=new Float64Array(e.regionCount),a=[];let c=0,l=0,d=0,h=0,u=0;for(let n=0;n\u003ce.regionCount;n++){const e=t.regionIntersectionCaches[n]?.existingRegionCost??0;s[n]=e,c=Math.max(c,e),l+=e;const o=t.regionSegments[n]?.length??0;d+=o,h=Math.max(h,o),u+=o*o,e\u003er\u0026\u0026a.push(n)}const p={maxRegionCost:c,totalRegionCost:l},m={...p,ripCount:t.ripCount,segmentCount:d,maxRegionSegmentCount:h,squaredRegionSegmentCount:u};this.completedRoundSummaries.push(m),this.firstCompletedRoundSummary??=m,void 0===this.partialRipQualityBaselineSummary\u0026\u0026t.ripCount\u003e=Math.max(0,this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS)\u0026\u0026(this.partialRipQualityBaselineSummary=m);this.shouldReplaceBestSolvedState(m)\u0026\u0026(this.replaceBestSolvedState(p),this.bestSolvedRoundSummary=m);const g=this.firstCompletedRoundSummary,f=this.partialRipQualityBaselineSummary??g,y=Math.max(0,this.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO),_=Math.max(0,this.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO),b=f.maxRegionCost*(1-y),x=f.totalRegionCost*(1+_),v=this.useComplexityAwareSelection\u0026\u0026t.ripCount\u003ef.ripCount\u0026\u0026y\u003e0\u0026\u0026c\u003c=b\u0026\u0026l\u003c=x\u0026\u0026d\u003c=f.segmentCount;if(v\u0026\u0026(this.partialRipTargetReached=!0),this.stats={...this.stats,currentRipThreshold:r,hotRegionCount:a.length,maxRegionCost:c,totalRegionCost:l,bestMaxRegionCost:this.bestSolvedStateSummary?.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary?.totalRegionCost,ripCount:t.ripCount,completedRoundSummaries:this.completedRoundSummaries.map(t=\u003e({...t})),firstMaxRegionCost:g.maxRegionCost,firstTotalRegionCost:g.totalRegionCost,firstSegmentCount:g.segmentCount,firstMaxRegionSegmentCount:g.maxRegionSegmentCount,firstSquaredRegionSegmentCount:g.squaredRegionSegmentCount,partialRipQualityBaselineRipCount:f.ripCount,partialRipQualityBaselineMaxRegionCost:f.maxRegionCost,partialRipQualityBaselineTotalRegionCost:f.totalRegionCost,partialRipQualityBaselineSegmentCount:f.segmentCount,partialRipQualityBaselineMaxRegionSegmentCount:f.maxRegionSegmentCount,partialRipQualityBaselineSquaredRegionSegmentCount:f.squaredRegionSegmentCount,bestSolvedSegmentCount:this.bestSolvedRoundSummary?.segmentCount,bestSolvedMaxRegionSegmentCount:this.bestSolvedRoundSummary?.maxRegionSegmentCount,bestSolvedSquaredRegionSegmentCount:this.bestSolvedRoundSummary?.squaredRegionSegmentCount,partialRipTargetMaxRegionCost:b,partialRipMaxTargetTotalRegionCost:x,partialRipComplexityAwareSelection:this.useComplexityAwareSelection,partialRipComplexitySelectionMinRouteCount:this.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT,partialRipMaxRegionCostGrowthRatio:this.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO,partialRipTargetReached:this.partialRipTargetReached},this.publishPartialRipStats(),0===a.length||v||t.ripCount\u003e=n)return this.restoreBestSolvedState(),void(this.solved=!0);for(let n=0;n\u003ce.regionCount;n++)t.regionCongestionCost[n]+=s[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;const S=t.ripCount\u003cMath.max(0,this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS);t.ripCount+=1;const I=!S\u0026\u0026this.preparePartialRip(a,s);I||this.resetRoutingStateForRerip();const C=S?\"warmup_full\":I?\"partial\":\"full_fallback\";this.stats={...this.stats,ripCount:t.ripCount,maxRegionCostBeforeRip:c,reripRegionCount:a.length,reripMode:C,partialRipWarmupFullRipAttempts:this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS},this.logRipEvent(\"hot_regions\",c,{hotRegionCount:a.length,currentRipThreshold:r,reripMode:C,partialRouteCount:I?this.partialRipRoutePlans.size:0})}},cB=t=\u003e{const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;return Number.isFinite(e)?e:void 0},lB=t=\u003e{const e=new Set;for(const n of t.connections??[])e.add(n.startRegionId),e.add(n.endRegionId);const n=new Set(t.regions.filter(t=\u003e(t=\u003e{if(!0!==t.d?._containsObstacle)return!1;const e=cB(t);return void 0===e||-1===e})(t)\u0026\u0026!e.has(t.regionId)).map(t=\u003et.regionId));if(0===n.size)return t;const o=t.ports.filter(t=\u003e!n.has(t.region1Id)\u0026\u0026!n.has(t.region2Id)),i=(t.connections??[]).find(t=\u003en.has(t.startRegionId)||n.has(t.endRegionId));if(i)throw new Error(`Connection \"${i.connectionId}\" references full-obstacle region`);return{...t,regions:t.regions.filter(t=\u003e!n.has(t.regionId)),ports:o}},dB=t=\u003e{const e=t.d?.bounds;if(e)return e;const n=t.d?.center,o=t.d?.width,i=t.d?.height;return n\u0026\u0026\"number\"==typeof n.x\u0026\u0026\"number\"==typeof n.y\u0026\u0026\"number\"==typeof o\u0026\u0026\"number\"==typeof i?{minX:n.x-o/2,maxX:n.x+o/2,minY:n.y-i/2,maxY:n.y+i/2}:{minX:0,maxX:0,minY:0,maxY:0}},hB=t=\u003eNumber(t.d?.x??0),uB=t=\u003eNumber(t.d?.y??0),pB=(t,e)=\u003e{if(!e)return 0;const n=dB(e),o=hB(t),i=uB(t),r=n.minX\u003c=o\u0026\u0026o\u003c=n.maxX,s=n.minY\u003c=i\u0026\u0026i\u003c=n.maxY;if(s\u0026\u0026o\u003e=n.maxX){const t=Math.max(n.maxY-n.minY,1e-9),e=(i-n.minY)/t;return Math.round(9e3*e)}if(r\u0026\u0026i\u003e=n.maxY){const t=Math.max(n.maxX-n.minX,1e-9),e=(n.maxX-o)/t;return 9e3+Math.round(9e3*e)}if(s\u0026\u0026o\u003c=n.minX){const t=Math.max(n.maxY-n.minY,1e-9),e=(n.maxY-i)/t;return 18e3+Math.round(9e3*e)}if(r\u0026\u0026i\u003c=n.minY){const t=Math.max(n.maxX-n.minX,1e-9),e=(o-n.minX)/t;return 27e3+Math.round(9e3*e)}const a=Math.abs(o-n.minX),c=Math.abs(o-n.maxX),l=Math.abs(i-n.minY),d=Math.abs(i-n.maxY),h=Math.min(a,c,l,d),u=Math.max(n.maxX-n.minX,1e-9),p=Math.max(n.maxY-n.minY,1e-9);if(h===c){const t=(i-n.minY)/p;return Math.round(9e3*t)}if(h===d){const t=(n.maxX-o)/u;return 9e3+Math.round(9e3*t)}if(h===a){const t=(n.maxY-i)/p;return 18e3+Math.round(9e3*t)}const m=(o-n.minX)/u;return 27e3+Math.round(9e3*m)},mB=(t,e)=\u003e{if(!t)return;return[...t.pointIds].sort((t,n)=\u003e{const o=e.get(t),i=e.get(n),r=Number(o?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY),s=Number(i?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY);if(r!==s)return r-s;const a=Number(o?.d?.z??0),c=Number(i?.d?.z??0);return a!==c?a-c:t.localeCompare(n)})[0]},gB=t=\u003e{const e=lB(t),n=new Map,o=new Map,i=new Map,r=new Map((e.solvedRoutes??[]).map(t=\u003e[t.connection.connectionId,t]));e.regions.forEach((t,e)=\u003e{n.set(t.regionId,e)}),e.ports.forEach((t,e)=\u003e{o.set(t.portId,e),i.set(t.portId,t)});const s=e.regions.length,a=e.ports.length,c=e.regions.map(t=\u003et.pointIds.map(t=\u003eo.get(t)).filter(t=\u003evoid 0!==t)),l=Array.from({length:a},()=\u003e[]),d=new Float64Array(s),h=new Float64Array(s),u=new Float64Array(s),p=new Float64Array(s),m=new Int32Array(s),g=new Int32Array(s).fill(-1),f=new Int8Array(s);e.regions.forEach((t,e)=\u003e{const n=(t=\u003e{const e=dB(t),n=\"number\"==typeof t.d?.width?t.d.width:e.maxX-e.minX,o=\"number\"==typeof t.d?.height?t.d.height:e.maxY-e.minY;return{centerX:\"number\"==typeof t.d?.center?.x?t.d.center.x:(e.minX+e.maxX)/2,centerY:\"number\"==typeof t.d?.center?.y?t.d.center.y:(e.minY+e.maxY)/2,width:n,height:o}})(t);d[e]=n.width,h[e]=n.height,u[e]=n.centerX,p[e]=n.centerY,m[e]=(t=\u003e{const e=t.d?.availableZ;if(!Array.isArray(e))return 0;let n=0;for(const t of e)!Number.isInteger(t)||t\u003c0||t\u003e=31||(n|=1\u003c\u003ct);return n})(t);const o=cB(t);void 0!==o\u0026\u0026(g[e]=o,f[e]=1)});const y=new Int32Array(a),_=new Int32Array(a),b=new Float64Array(a),x=new Float64Array(a),v=new Int32Array(a);e.ports.forEach((t,o)=\u003e{const i=n.get(t.region1Id),r=n.get(t.region2Id);if(void 0===i||void 0===r)throw new Error(`Port \"${t.portId}\" references missing regions \"${t.region1Id}\" or \"${t.region2Id}\"`);l[o]=[i,r],b[o]=hB(t),x[o]=uB(t),v[o]=(t=\u003e{const e=Number(t.d?.z??0);return Number.isFinite(e)?e:0})(t),y[o]=pB(t,e.regions[i]),_[o]=pB(t,e.regions[r])});const S=e.regions.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedRegionId\",{value:t.regionId,enumerable:!1,configurable:!0,writable:!0}),n})(t,(t=\u003eRz(Ez(m[t]))??Rz((c[t]??[]).map(t=\u003ev[t]))??\"z0\")(e))),I=e.ports.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedPortId\",{value:t.portId,enumerable:!1,configurable:!0,writable:!0}),n})(t,Rz([v[e]])??\"z0\")),C=e.connections??[],P=new Map;let M=0;const N=t=\u003e{const e=t.mutuallyConnectedNetworkId??t.connectionId;let n=P.get(e);return void 0===n\u0026\u0026(n=M++,P.set(e,n)),n},w=Array.from({length:s},()=\u003enew Set),T=(t,e)=\u003e{const o=n.get(t);if(void 0===o)throw new Error(`Connection references missing region \"${t}\"`);w[o].add(e)};C.forEach(t=\u003e{const e=N(t);T(t.startRegionId,e),T(t.endRegionId,e)}),w.forEach((t,e)=\u003e{1!==f[e]\u0026\u00261===t.size\u0026\u0026(g[e]=[...t][0])});const R=C.map(t=\u003e{const n=r.get(t.connectionId),o=((t,e)=\u003et.ports.filter(t=\u003et.region1Id===e.startRegionId\u0026\u0026t.region2Id===e.endRegionId||t.region2Id===e.startRegionId\u0026\u0026t.region1Id===e.endRegionId).map(t=\u003et.portId))(e,t);return{connection:t,solvedRoute:n,sharedPortIds:o}}).filter(({solvedRoute:t,sharedPortIds:e})=\u003e0===e.length||(t?.path.length??0)\u003e1),E=R.length,A=new Map(R.map(({connection:t},e)=\u003e[t.connectionId,e])),O=new Int8Array(a).fill(1),k=new Int32Array(E),L=new Int32Array(E),D=new Int32Array(E);R.forEach(({connection:t,solvedRoute:n},r)=\u003e{const s=mB(e.regions.find(e=\u003ee.regionId===t.startRegionId),i),a=mB(e.regions.find(e=\u003ee.regionId===t.endRegionId),i),c=n?.path[0]?.portId??s,l=n?.path[n.path.length-1]?.portId??a,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)throw new Error(`Connection \"${t.connectionId}\" could not be mapped to route endpoints`);k[r]=d,L[r]=h,D[r]=N(t)});const z={portCount:a,regionCount:s,regionIncidentPorts:c,incidentPortRegion:l,regionWidth:d,regionHeight:h,regionCenterX:u,regionCenterY:p,regionAvailableZMask:m,regionMetadata:S,portAngleForRegion1:y,portAngleForRegion2:_,portX:b,portY:x,portZ:v,portMetadata:I},F=e.regions.flatMap((t,e)=\u003e(t.assignments??[]).map(n=\u003e{const i=A.get(n.connectionId);if(void 0===i)throw new Error(`Region \"${t.regionId}\" assignment references unknown routable connection \"${n.connectionId}\"`);const r=o.get(n.regionPort1Id),s=o.get(n.regionPort2Id);if(void 0===r||void 0===s)throw new Error(`Region \"${t.regionId}\" assignment references missing port \"${void 0===r?n.regionPort1Id:n.regionPort2Id}\"`);if(!c[e]?.includes(r)||!c[e]?.includes(s))throw new Error(`Region \"${t.regionId}\" assignment ports must both belong to the region`);return{routeId:i,regionId:e,fromPortId:r,toPortId:s}})),B=Float64Array.from(e.ports,t=\u003e{const e=Number(t.d?.tinyHypergraphPortPenalty??0);return Number.isFinite(e)\u0026\u0026e\u003e0?e:0}),j=B.some(t=\u003et\u003e0),$={routeCount:E,portSectionMask:O,routeMetadata:R.map(({connection:t})=\u003et),routeStartPort:k,routeEndPort:L,routeNet:D,regionNetId:g,...F.length\u003e0\u0026\u0026{initialAssignments:F},...j\u0026\u0026{portPenalty:B}},Y=[],X=[];for(const{solvedRoute:t}of R){if(!t){Y.push([]),X.push([]);continue}const e=[],i=[];for(let r=1;r\u003ct.path.length;r++){const s=t.path[r-1],a=t.path[r],c=s?.portId,l=a?.portId,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)continue;const u=\"string\"==typeof s?.nextRegionId?s.nextRegionId:\"string\"==typeof a?.lastRegionId?a.lastRegionId:void 0;e.push([d,h]),i.push(void 0!==u?n.get(u):void 0)}Y.push(e),X.push(i)}return{topology:z,problem:$,solution:{solvedRoutePathSegments:Y,solvedRoutePathRegionIds:X}}},fB=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,yB=t=\u003eArray.isArray(t)?t.map(t=\u003eyB(t)):fB(t)?Object.fromEntries(Object.entries(t).map(([t,e])=\u003e[t,yB(e)])):t,_B=t=\u003efB(t)?{...t}:void 0===t?{}:{value:t},bB=(t,e=0)=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)?t:e,xB=t=\u003e({x:bB(t.d?.x),y:bB(t.d?.y)}),vB=t=\u003e[t.region1Id,t.region2Id].sort().join(\"\\0\"),SB=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y),IB=t=\u003e{const e=Math.hypot(t.x,t.y);if(!(e\u003c=1e-9))return{x:t.x/e,y:t.y/e}},CB=t=\u003e{const e=t?.d?.center;if(fB(e))return{x:bB(e.x),y:bB(e.y)};const n=(t=\u003e{const e=t?.d?.bounds;if(fB(e)\u0026\u0026\"number\"==typeof e.minX\u0026\u0026\"number\"==typeof e.maxX\u0026\u0026\"number\"==typeof e.minY\u0026\u0026\"number\"==typeof e.maxY)return{minX:e.minX,maxX:e.maxX,minY:e.minY,maxY:e.maxY};const n=t?.d?.center,o=bB(t?.d?.width),i=bB(t?.d?.height);if(fB(n)){const t=bB(n.x),e=bB(n.y);return{minX:t-o/2,maxX:t+o/2,minY:e-i/2,maxY:e+i/2}}return{minX:0,maxX:0,minY:0,maxY:0}})(t);return{x:(n.minX+n.maxX)/2,y:(n.minY+n.maxY)/2}},PB=(t,e)=\u003e{const n=vB(t),o=xB(t);let i,r=Number.POSITIVE_INFINITY;for(const s of e){if(s.portId===t.portId)continue;if(vB(s)!==n)continue;const e=SB(o,xB(s));e\u003c=1e-9||e\u003e=r||(i=s,r=e)}return i},MB=(t,e,n)=\u003e{const o=xB(t);if(e){const t=xB(e),n=IB({x:o.x-t.x,y:o.y-t.y});if(n)return n}return((t,e)=\u003e{const n=CB(e.get(t.region1Id)),o=CB(e.get(t.region2Id));return IB({x:-(o.y-n.y),y:o.x-n.x})??{x:1,y:0}})(t,n)},NB=(t,e,n)=\u003e{const o=`${t}::dup${e}`;if(!n.has(o))return n.add(o),o;for(let t=2;;t++){const e=`${o}-${t}`;if(!n.has(e))return n.add(e),e}},wB=(t,e,n)=\u003e{const o=t.indexOf(e);-1!==o?t.splice(o+1,0,...n):t.push(...n)},TB=(t,e)=\u003e{const n=t.portMetadata?.[e];if(fB(n)){if(\"string\"==typeof n.serializedPortId)return n.serializedPortId;if(\"string\"==typeof n.portId)return n.portId}return`port-${e}`},RB=(t,e)=\u003e({routeCount:1,portSectionMask:new Int8Array(t.portSectionMask),routeMetadata:void 0===t.routeMetadata?void 0:[t.routeMetadata[e]],routeStartPort:Int32Array.from([t.routeStartPort[e]]),routeEndPort:Int32Array.from([t.routeEndPort[e]]),routeNet:Int32Array.from([t.routeNet[e]]),regionNetId:new Int32Array(t.regionNetId),portPenalty:void 0===t.portPenalty?void 0:new Float64Array(t.portPenalty)}),EB=t=\u003e{const e=new Set;for(const n of t.state.regionSegments)for(const[,t,o]of n)e.add(t),e.add(o);return 0===e.size\u0026\u00261===t.problem.routeCount\u0026\u0026(e.add(t.problem.routeStartPort[0]),e.add(t.problem.routeEndPort[0])),e},AB=class extends kt{constructor(t,e={}){super(),this.serializedHyperGraph=t,this.options=e}serializedHyperGraph;options;revisedSerializedHyperGraph;report={portUseCounts:{},duplicatedPorts:[]};getDuplicatePortProximity(){return this.options.duplicatePortProximity??.05}getIndividualRouteSolveOptions(){return{RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!1,...this.options.routeSolveOptions}}getPortUseCounts(){const{topology:t,problem:e}=gB(this.serializedHyperGraph);!1===this.options.useSerializedPortPenalties\u0026\u0026(e.portPenalty=void 0);const n=new Map;for(let o=0;o\u003ce.routeCount;o++){const i=RB(e,o),r=new nB(t,i,this.getIndividualRouteSolveOptions());if(r.solve(),!r.solved||r.failed)throw new Error(`Route ${o} could not be solved independently: ${r.error??\"unknown error\"}`);for(const e of EB(r)){const o=TB(t,e);n.set(o,(n.get(o)??0)+1)}}return n}duplicateCongestedPorts(t){const e=this.getDuplicatePortProximity();if(!(e\u003e0))throw new Error(\"duplicatePortProximity must be greater than zero\");const{solvedRoutes:n,...o}=this.serializedHyperGraph,i=this.serializedHyperGraph.regions.map(t=\u003e({...t,pointIds:[...t.pointIds],d:yB(t.d)})),r=this.serializedHyperGraph.ports.map(t=\u003e({...t,d:yB(t.d)})),s=new Map(i.map(t=\u003e[t.regionId,t])),a=new Map(r.map(t=\u003e[t.portId,t])),c=new Set(r.map(t=\u003et.portId)),l=[];for(const[n,o]of[...t.entries()].sort(([t],[e])=\u003et.localeCompare(e))){if(o\u003c=1)continue;const t=a.get(n);if(!t)continue;const i=o-1,d=PB(t,this.serializedHyperGraph.ports),h=MB(t,d,s),u=xB(t),p=[];for(let s=1;s\u003c=i;s++){const a=NB(n,s,c),l=e*s/(i+1),d=_B(yB(t.d));d.x=u.x+h.x*l,d.y=u.y+h.y*l,d.duplicatedFromPortId=n,d.duplicateIndex=s,d.duplicatePortUseCount=o,d.duplicatePortProximity=e,d.repairReason=\"congested-port\",r.push({...t,portId:a,d:d}),p.push(a)}for(const e of[t.region1Id,t.region2Id]){const t=s.get(e);t\u0026\u0026wB(t.pointIds,n,p)}l.push({sourcePortId:n,duplicatePortIds:p,useCount:o})}return this.report={portUseCounts:Object.fromEntries([...t.entries()].sort()),duplicatedPorts:l},{...o,regions:i,ports:r,connections:void 0===this.serializedHyperGraph.connections?void 0:yB(this.serializedHyperGraph.connections)}}_setup(){try{const t=this.getPortUseCounts();this.revisedSerializedHyperGraph=this.duplicateCongestedPorts(t),this.stats={...this.stats,duplicateSourcePortCount:this.report.duplicatedPorts.length,duplicatedPortCount:this.report.duplicatedPorts.reduce((t,e)=\u003et+e.duplicatePortIds.length,0)},this.solved=!0}catch(t){this.failed=!0,this.error=t instanceof Error?t.message:String(t)}}_step(){this.failed||(this.solved=!0)}getOutput(){if(!this.revisedSerializedHyperGraph||this.failed)throw new Error(\"DuplicateCongestedPortSolver does not have a repaired topology output\");return this.revisedSerializedHyperGraph}},OB=(t,e)=\u003e{const n=t.owners.size-e.owners.size;if(0!==n)return n;const o=t.distance-e.distance;return 0!==o?o:t.queueOrder-e.queueOrder},kB=class{heap=[];push(t){this.heap.push(t);let e=this.heap.length-1;for(;e\u003e0;){const t=Math.floor((e-1)/2);if(OB(this.heap[t],this.heap[e])\u003c=0)break;[this.heap[t],this.heap[e]]=[this.heap[e],this.heap[t]],e=t}}pop(){const t=this.heap[0],e=this.heap.pop();if(!t||!e)return null;if(0===this.heap.length)return t;this.heap[0]=e;let n=0;for(;;){const t=2*n+1,e=t+1;let o=n;if(t\u003cthis.heap.length\u0026\u0026OB(this.heap[t],this.heap[o])\u003c0\u0026\u0026(o=t),e\u003cthis.heap.length\u0026\u0026OB(this.heap[e],this.heap[o])\u003c0\u0026\u0026(o=e),o===n)break;[this.heap[n],this.heap[o]]=[this.heap[o],this.heap[n]],n=o}return t}},LB=(t,e)=\u003e!(t.distance\u003ee.distance)\u0026\u0026((t,e)=\u003e{if(t.size\u003ee.size)return!1;for(const n of t)if(!e.has(n))return!1;return!0})(t.owners,e.owners),DB=(t,e)=\u003e{const n=[],o=[];let i=t;for(;null!==i;)n.push(i.state),null!==i.incomingHop\u0026\u0026o.push(i.incomingHop),i=i.parent;return n.reverse(),o.reverse(),{found:!0,states:n,hops:o,owners:new Set(t.owners),distance:t.distance,expandedLabelCount:e}},zB=t=\u003e{for(;;){const e=t.pop();if(null===e)return null;if(e.active)return e}},FB=(t,e)=\u003e{QF(t,e),e\u0026\u0026(void 0!==e.MAX_RIPS\u0026\u0026(t.MAX_RIPS=e.MAX_RIPS),void 0!==e.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT\u0026\u0026(t.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=e.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT),void 0!==e.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST\u0026\u0026(t.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=e.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST))},BB=t=\u003et.map(t=\u003et.map(([t,e,n])=\u003e[t,e,n])),jB=t=\u003e({netIds:new Int32Array(t.netIds),lesserAngles:new Int32Array(t.lesserAngles),greaterAngles:new Int32Array(t.greaterAngles),layerMasks:new Int32Array(t.layerMasks),existingCrossingLayerIntersections:t.existingCrossingLayerIntersections,existingSameLayerIntersections:t.existingSameLayerIntersections,existingEntryExitLayerChanges:t.existingEntryExitLayerChanges,existingRegionCost:t.existingRegionCost,existingSegmentCount:t.existingSegmentCount}),$B=t=\u003e({portAssignment:new Int32Array(t.portAssignment),regionSegments:BB(t.regionSegments),regionIntersectionCaches:t.regionIntersectionCaches.map(jB)}),YB=(t,e)=\u003e{const n=$B(e);t.state.portAssignment=n.portAssignment,t.state.regionSegments=n.regionSegments,t.state.regionIntersectionCaches=n.regionIntersectionCaches},XB=t=\u003e{let e=0,n=0;for(let o=0;o\u003ct.length;o++){const i=t[o]?.existingRegionCost??0;e=Math.max(e,i),n+=i}return{maxRegionCost:e,totalRegionCost:n}},VB=(t,e)=\u003et.maxRegionCost!==e.maxRegionCost?t.maxRegionCost-e.maxRegionCost:t.totalRegionCost-e.totalRegionCost,WB=(t,e,n)=\u003e{const o=t.incidentPortRegion[e]??[],i=t.incidentPortRegion[n]??[],r=o.find(t=\u003ei.includes(t));if(void 0===r)throw new Error(`Ports ${e} and ${n} do not share a region`);return r},HB=(t,e,n,o)=\u003e{const i=n.solvedRoutePathSegments[o]??[],r=n.solvedRoutePathRegionIds?.[o]??[],s=e.routeStartPort[o],a=e.routeEndPort[o];if(0===i.length){if(s===a)return{orderedPortIds:[s],orderedRegionIds:[]};throw new Error(`Route ${o} does not have an existing solved path`)}const c=new Map;i.forEach(([t,e],n)=\u003e{const o={segmentIndex:n,fromPortId:t,toPortId:e,regionId:r[n]},i=c.get(t)??[];i.push(o),c.set(t,i);const s=c.get(e)??[];s.push(o),c.set(e,s)});const l=[s],d=[],h=new Set;let u,p=s;for(;p!==a;){const e=(c.get(p)??[]).filter(({segmentIndex:t,fromPortId:e,toPortId:n})=\u003e{if(h.has(t))return!1;return(e===p?n:e)!==u});if(1!==e.length)throw new Error(`Route ${o} is not a single ordered path from ${s} to ${a}`);const n=e[0],i=n.fromPortId===p?n.toPortId:n.fromPortId;h.add(n.segmentIndex),d.push(n.regionId??WB(t,n.fromPortId,n.toPortId)),l.push(i),u=p,p=i}if(h.size!==i.length)throw new Error(`Route ${o} contains disconnected solved segments`);return{orderedPortIds:l,orderedRegionIds:d}},GB=(t,e,n,o)=\u003e{const i=new nB(t,e,o);return((t,e)=\u003e{t.state.portAssignment.fill(-1),t.state.regionSegments=Array.from({length:t.topology.regionCount},()=\u003e[]),t.state.regionIntersectionCaches=Array.from({length:t.topology.regionCount},()=\u003eqF()),t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.state.unroutedRoutes=[],t.state.candidateQueue.clear(),t.resetCandidateBestCosts(),t.state.goalPortId=-1,t.state.ripCount=0,t.state.regionCongestionCost.fill(0);for(let n=0;n\u003ce.length;n++)for(const[o,i,r]of e[n]??[])t.state.currentRouteNetId=t.problem.routeNet[o],t.state.regionSegments[n].push([o,i,r]),t.state.portAssignment[i]=t.state.currentRouteNetId,t.state.portAssignment[r]=t.state.currentRouteNetId,t.appendSegmentToRegionCache(n,i,r);t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.solved=!0,t.failed=!1,t.error=null})(i,n),i},UB=(t,e,n)=\u003e{const o=new Int32Array(e.routeStartPort),i=new Int32Array(e.routeEndPort),r=Array.from({length:e.routeCount},(t,e)=\u003e({routeId:e,fixedSegments:[]})),s=[];for(let a=0;a\u003ce.routeCount;a++){const c=r[a],{orderedPortIds:l,orderedRegionIds:d}=HB(t,e,n,a),h=[];let u;for(let t=0;t\u003cl.length;t++){const n=l[t],o=1===e.portSectionMask[n];o\u0026\u0026void 0===u?u=t:o||void 0===u||(h.push({startIndex:u,endIndex:t-1}),u=void 0)}if(void 0!==u\u0026\u0026h.push({startIndex:u,endIndex:l.length-1}),0===h.length){for(let t=1;t\u003cl.length;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});continue}if(h.length\u003e1)throw new Error(`Route ${a} enters the section multiple times; only one contiguous section span is currently supported`);const p=h[0],m=Math.max(0,p.startIndex-1),g=Math.min(l.length-1,p.endIndex+1);if(g\u003c=m)throw new Error(`Route ${a} does not have a valid section span`);for(let t=1;t\u003c=m;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});for(let t=g+1;t\u003cl.length;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});c.activeStartPortId=l[m],c.activeEndPortId=l[g],c.forcedStartRegionId=d[m],o[a]=c.activeStartPortId,i[a]=c.activeEndPortId,s.push(a)}return{sectionProblem:{routeCount:e.routeCount,portSectionMask:new Int8Array(e.portSectionMask),routeMetadata:e.routeMetadata,routeStartPort:o,routeEndPort:i,routeNet:new Int32Array(e.routeNet),regionNetId:new Int32Array(e.regionNetId),portPenalty:void 0===e.portPenalty?void 0:new Float64Array(e.portPenalty)},routePlans:r,activeRouteIds:s}},ZB=(t,e,n)=\u003eUB(t,e,n).activeRouteIds,qB=class extends nB{constructor(t,e,n,o,i,r,s,a){super(t,e,a),this.routePlans=n,this.activeRouteIds=o,this.mutableRegionIds=i,this.immutableRegionSummary=r,this.baselineSummary=s,FB(this,a),this.state.unroutedRoutes=[...o],this.applyFixedSegments(),this.fixedSnapshot=$B({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches})}routePlans;activeRouteIds;mutableRegionIds;immutableRegionSummary;baselineSummary;bestSnapshot;fixedSnapshot;bestSummary;baselineBeatRipCount;previousBestMaxRegionCost=Number.POSITIVE_INFINITY;ripsSinceBestMaxRegionCostImprovement=0;MAX_RIPS=Number.POSITIVE_INFINITY;MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=Number.POSITIVE_INFINITY;EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=Number.POSITIVE_INFINITY;applyFixedSegments(){for(const t of this.routePlans)for(const{regionId:e,fromPortId:n,toPortId:o}of t.fixedSegments)this.state.currentRouteNetId=this.problem.routeNet[t.routeId],this.state.regionSegments[e].push([t.routeId,n,o]),this.state.portAssignment[n]=this.state.currentRouteNetId,this.state.portAssignment[o]=this.state.currentRouteNetId,this.appendSegmentToRegionCache(e,n,o);this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0}captureBestState(t){this.bestSummary\u0026\u0026VB(t,this.bestSummary)\u003e=0||(this.bestSummary=t,this.bestSnapshot=$B({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches}))}restoreBestState(){this.bestSnapshot\u0026\u0026(YB(this,this.bestSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1)}getStartingNextRegionId(t,e){const n=this.routePlans[t]?.forcedStartRegionId;return void 0!==n?n:super.getStartingNextRegionId(t,e)}resetRoutingStateForRerip(){if(!this.fixedSnapshot)return super.resetRoutingStateForRerip(),this.state.unroutedRoutes=qz([...this.activeRouteIds],this.state.ripCount),void this.applyFixedSegments();YB(this,this.fixedSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=qz([...this.activeRouteIds],this.state.ripCount),this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1}onAllRoutesRouted(){const{state:t}=this,e=Math.min(this.MAX_RIPS,this.RIP_THRESHOLD_RAMP_ATTEMPTS),n=e\u003c=0?1:Math.min(1,t.ripCount/e),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(this.mutableRegionIds.length);let s=0,a=0;for(let e=0;e\u003cthis.mutableRegionIds.length;e++){const n=this.mutableRegionIds[e],c=t.regionIntersectionCaches[n]?.existingRegionCost??0;r[e]=c,s=Math.max(s,c),a+=c,c\u003eo\u0026\u0026i.push(n)}const c=Math.max(this.immutableRegionSummary.maxRegionCost,s),l=this.immutableRegionSummary.totalRegionCost+a;this.captureBestState({maxRegionCost:c,totalRegionCost:l});const d=this.bestSummary??{maxRegionCost:c,totalRegionCost:l};if(d.maxRegionCost\u003cthis.previousBestMaxRegionCost-Number.EPSILON?(this.previousBestMaxRegionCost=d.maxRegionCost,this.ripsSinceBestMaxRegionCostImprovement=0):this.ripsSinceBestMaxRegionCostImprovement+=1,void 0===this.baselineBeatRipCount\u0026\u0026d.maxRegionCost\u003cthis.baselineSummary.maxRegionCost-Number.EPSILON\u0026\u0026(this.baselineBeatRipCount=t.ripCount),this.stats={...this.stats,activeRouteCount:this.activeRouteIds.length,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:c,totalRegionCost:l,bestMaxRegionCost:d.maxRegionCost,bestTotalRegionCost:d.totalRegionCost,ripCount:t.ripCount},0===i.length||t.ripCount\u003e=e||this.ripsSinceBestMaxRegionCostImprovement\u003e=this.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT||void 0!==this.baselineBeatRipCount\u0026\u0026t.ripCount-this.baselineBeatRipCount\u003e=this.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST)return this.restoreBestState(),void(this.solved=!0);for(let e=0;e\u003cthis.mutableRegionIds.length;e++){const n=this.mutableRegionIds[e];t.regionCongestionCost[n]+=r[e]*this.RIP_CONGESTION_REGION_COST_FACTOR}t.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:t.ripCount,reripRegionCount:i.length}}onOutOfCandidates(){const{state:t}=this;for(const e of this.mutableRegionIds){const n=t.regionIntersectionCaches[e]?.existingRegionCost??0;t.regionCongestionCost[e]+=n*this.RIP_CONGESTION_REGION_COST_FACTOR}t.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:t.ripCount,reripReason:\"out_of_candidates\"}}tryFinalAcceptance(){if(this.bestSnapshot)return this.restoreBestState(),void(this.solved=!0);this.fixedSnapshot\u0026\u0026YB(this,this.fixedSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[...this.activeRouteIds],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.stats={...this.stats,acceptedFixedSectionStateOnTimeout:!0},this.solved=!0}visualize(){return UF(this,{highlightSectionMask:!0,showInitialRouteHints:!1,showOnlySectionPortsOnIdle:!0})}},JB=class extends kt{constructor(t,e,n,o){super(),this.topology=t,this.problem=e,this.initialSolution=n,FB(this,o),this.baselineSolver=((t,e,n,o)=\u003e{const i=Array.from({length:t.regionCount},()=\u003e[]);for(let o=0;o\u003ce.routeCount;o++){const{orderedPortIds:r,orderedRegionIds:s}=HB(t,e,n,o);for(let t=1;t\u003cr.length;t++){const e=r[t-1],n=r[t];i[s[t-1]].push([o,e,n])}}return GB(t,e,i,o)})(t,e,n,tB(this)),this.baselineSummary=XB(this.baselineSolver.state.regionIntersectionCaches),this.sectionRegionIds=((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ce.portSectionMask.length;o++)if(1===e.portSectionMask[o])for(const e of t.incidentPortRegion[o]??[])n.add(e);return[...n]})(t,e),this.sectionBaselineSummary=((t,e)=\u003e{let n=0,o=0;for(const i of e){const e=t[i]?.existingRegionCost??0;n=Math.max(n,e),o+=e}return{maxRegionCost:n,totalRegionCost:o}})(this.baselineSolver.state.regionIntersectionCaches,this.sectionRegionIds),this.outsideSectionBaselineSummary=((t,e)=\u003e{const n=new Set(e);let o=0,i=0;for(let e=0;e\u003ct.length;e++){if(n.has(e))continue;const r=t[e]?.existingRegionCost??0;o=Math.max(o,r),i+=r}return{maxRegionCost:o,totalRegionCost:i}})(this.baselineSolver.state.regionIntersectionCaches,this.sectionRegionIds),this.applySectionRipPolicy()}topology;problem;initialSolution;baselineSolver;baselineSummary;sectionBaselineSummary;outsideSectionBaselineSummary;sectionRegionIds;optimizedSolver;sectionSolver;activeRouteIds=[];DISTANCE_TO_COST=.05;minViaPadDiameter=Yz;VERBOSE=!1;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;MAX_RIPS=Number.POSITIVE_INFINITY;MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=10;EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=10;RIP_CONGESTION_REGION_COST_FACTOR=.1;MAX_ITERATIONS=1e6;STATIC_REACHABILITY_PRECHECK=!1;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;ACCEPT_BEST_SOLUTION_ON_TIMEOUT=!0;GREEDY_FINAL_ROUTE_ITERS=4;applySectionRipPolicy(){this.RIP_THRESHOLD_START=.05,this.RIP_THRESHOLD_END=Math.max(this.RIP_THRESHOLD_START,this.sectionBaselineSummary.maxRegionCost),this.MAX_RIPS=Math.min(this.MAX_RIPS,20)}_setup(){this.applySectionRipPolicy();const{sectionProblem:t,routePlans:e,activeRouteIds:n}=UB(this.topology,this.problem,this.initialSolution);if(this.activeRouteIds=n,0===n.length)return this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,activeRouteCount:0,initialMaxRegionCost:this.baselineSummary.maxRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,optimized:!1},void(this.solved=!0);var o;this.sectionSolver=new qB(this.topology,t,e,n,this.sectionRegionIds,this.outsideSectionBaselineSummary,this.baselineSummary,{...tB(o=this),MAX_RIPS:o.MAX_RIPS,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:o.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:o.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST}),this.activeSubSolver=this.sectionSolver,this.stats={...this.stats,sectionBaselineMaxRegionCost:this.sectionBaselineSummary.maxRegionCost,sectionBaselineTotalRegionCost:this.sectionBaselineSummary.totalRegionCost,effectiveRipThresholdStart:this.RIP_THRESHOLD_START,effectiveRipThresholdEnd:this.RIP_THRESHOLD_END,effectiveMaxRips:this.MAX_RIPS}}_step(){if(!this.sectionSolver)return void(this.solved=!0);if(this.sectionSolver.step(),this.stats={...this.stats,...this.sectionSolver.stats,activeRouteCount:this.activeRouteIds.length},this.sectionSolver.failed)return this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,finalTotalRegionCost:this.baselineSummary.totalRegionCost,optimized:!1,sectionSearchFailedFallbackToBaseline:!0,sectionSearchError:this.sectionSolver.error},void(this.solved=!0);if(!this.sectionSolver.solved)return;const t=GB(this.topology,this.problem,BB(this.sectionSolver.state.regionSegments),tB(this)),e=XB(t.state.regionIntersectionCaches),n=VB(e,this.baselineSummary)\u003c0;this.optimizedSolver=n?t:this.baselineSolver;const o=n?e:this.baselineSummary;this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,candidateMaxRegionCost:e.maxRegionCost,candidateTotalRegionCost:e.totalRegionCost,finalMaxRegionCost:o.maxRegionCost,finalTotalRegionCost:o.totalRegionCost,optimized:n},this.solved=!0}tryFinalAcceptance(){this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,finalTotalRegionCost:this.baselineSummary.totalRegionCost,optimized:!1,sectionSolverTimeoutFallbackToBaseline:!0},this.solved=!0,this.failed=!1,this.error=null}getSolvedSolver(){if(!this.solved||this.failed||!this.optimizedSolver)throw new Error(\"TinyHyperGraphSectionSolver does not have a solved output yet\");return this.optimizedSolver}visualize(){return this.optimizedSolver?UF(this.optimizedSolver,{highlightSectionMask:!0}):this.sectionSolver?this.sectionSolver.visualize():UF(this.baselineSolver,{highlightSectionMask:!0,showInitialRouteHints:!1,showOnlySectionPortsOnIdle:!0})}getOutput(){return this.getSolvedSolver().getOutput()}},KB=[\"self-touch\",\"onehop-all\",\"onehop-touch\",\"twohop-all\",\"twohop-touch\"],QB={\"self-all\":0,\"self-touch\":0,\"onehop-all\":1,\"onehop-touch\":1,\"twohop-all\":2,\"twohop-touch\":2,\"threehop-all\":3,\"threehop-touch\":3,\"fourhop-all\":4,\"fourhop-touch\":4},tj=(t,e)=\u003e{const n=new Set(e);for(const o of e)for(const e of t.regionIncidentPorts[o]??[])for(const o of t.incidentPortRegion[e]??[])n.add(o);return[...n]},ej=(t,e,n)=\u003e{let o=[...new Set(e)];for(let e=0;e\u003cn;e+=1)o=tj(t,o);return o},nj=(t,e,n)=\u003ee.flatMap(e=\u003en.map(n=\u003e((t,e,n)=\u003e({label:`hot-${e}-${n}`,family:n,regionIds:ej(t,[e],QB[n]),portSelectionRule:n.endsWith(\"-all\")?\"all-incident-regions-selected\":\"touches-selected-region\"}))(t,e,n))),oj={RIP_THRESHOLD_RAMP_ATTEMPTS:5},ij={DISTANCE_TO_COST:.05,RIP_THRESHOLD_RAMP_ATTEMPTS:16,RIP_CONGESTION_REGION_COST_FACTOR:.1,MAX_ITERATIONS:5e4,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:6,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:Number.POSITIVE_INFINITY},rj=t=\u003et.state.regionIntersectionCaches.reduce((t,e)=\u003eMath.max(t,e.existingRegionCost),0),sj=(t,e)=\u003e{const n=gB(t),o=new JB(n.topology,n.problem,n.solution,e);return rj(o.baselineSolver)},aj=(t,e,n)=\u003e{const o=new Set(e);return Int8Array.from({length:t.portCount},(e,i)=\u003e{const r=t.incidentPortRegion[i]??[];return\"touches-selected-region\"===n?r.some(t=\u003eo.has(t))?1:0:r.length\u003e0\u0026\u0026r.every(t=\u003eo.has(t))?1:0})},cj=(t,e)=\u003e({routeCount:t.routeCount,portSectionMask:e,routeMetadata:t.routeMetadata,routeStartPort:new Int32Array(t.routeStartPort),routeEndPort:new Int32Array(t.routeEndPort),routeNet:new Int32Array(t.routeNet),regionNetId:new Int32Array(t.regionNetId),portPenalty:void 0===t.portPenalty?void 0:new Float64Array(t.portPenalty)}),lj=(t,e,n,o,i,r)=\u003e{const s=performance.now(),a=performance.now(),c=new JB(e,n,o,r),l=rj(c.baselineSolver),d=performance.now()-a;let h,u,p=l,m=new Int8Array(e.portCount),g=0,f=0,y=0,_=0,b=0,x=0,v=0;const S=new Set,I=i?.maxHotRegions??r.MAX_HOT_REGIONS??2;for(const s of((t,e,n,o)=\u003e{const i=t.state.regionIntersectionCaches.map((t,e)=\u003e({regionId:e,regionCost:t.existingRegionCost})).filter(({regionCost:t})=\u003et\u003e0).sort((t,e)=\u003ee.regionCost-t.regionCost).slice(0,n).map(({regionId:t})=\u003et);return nj(e,i,o)})(t,e,I,i?.candidateFamilies??[...KB])){const t=cj(n,aj(e,s.regionIds,s.portSelectionRule));g+=1;const i=t.portSectionMask.join(\",\");if(S.has(i))y+=1;else{S.add(i);try{const n=performance.now(),i=ZB(e,t,o);if(_+=performance.now()-n,0===i.length)continue;f+=1;const a=performance.now(),c=new JB(e,t,o,r);b+=performance.now()-a;const l=performance.now();if(c.solve(),x+=performance.now()-l,c.failed||!c.solved)continue;if(Number(c.stats.finalMaxRegionCost??rj(c.getSolvedSolver()))\u003cp-1e-9){const e=performance.now(),n=sj(c.getOutput(),r);v+=performance.now()-e,n\u003cp-1e-9\u0026\u0026(p=n,m=new Int8Array(t.portSectionMask),h=s.label,u=s.family)}}catch{}}}return{portSectionMask:m,baselineMaxRegionCost:l,finalMaxRegionCost:p,generatedCandidateCount:g,candidateCount:f,duplicateCandidateCount:y,totalMs:performance.now()-s,baselineEvaluationMs:d,candidateEligibilityMs:_,candidateInitMs:b,candidateSolveMs:x,candidateReplayScoreMs:v,winningCandidateLabel:h,winningCandidateFamily:u}},dj=class extends Dt{initialVisualizationSolver;selectedSectionMask;selectedSectionCandidateLabel;selectedSectionCandidateFamily;constructor(t){super(t),this.MAX_ITERATIONS=2e5}loadHyperGraph(t){return gB(t)}getSolveGraphOptions(){return{...oj,...void 0===this.inputProblem.minViaPadDiameter?{}:{minViaPadDiameter:this.inputProblem.minViaPadDiameter},...this.inputProblem.solveGraphOptions}}getSectionSolverOptions(){return{...ij,...void 0===this.inputProblem.minViaPadDiameter?{}:{minViaPadDiameter:this.inputProblem.minViaPadDiameter},...this.inputProblem.sectionSolverOptions}}pipelineDef=[{solverName:\"solveGraph\",solverClass:nB,getConstructorParams:t=\u003e{const{topology:e,problem:n}=t.loadHyperGraph(t.inputProblem.serializedHyperGraph);return[e,n,t.getSolveGraphOptions()]}},{solverName:\"optimizeSection\",solverClass:JB,getConstructorParams:t=\u003et.getSectionStageParams()}];getSectionStageParams(){const t=this.getStageOutput(\"solveGraph\");if(!t)throw new Error(\"solveGraph did not produce a solved serialized hypergraph\");const e=this.getSolver(\"solveGraph\");if(!e)throw new Error(\"solveGraph solver is unavailable\");const n=this.getSectionSolverOptions(),{topology:o,problem:i,solution:r}=this.loadHyperGraph(t),s=this.inputProblem.createSectionMask?this.inputProblem.createSectionMask({serializedHyperGraph:this.inputProblem.serializedHyperGraph,solvedSerializedHyperGraph:t,solvedSolver:e,topology:o,problem:i,solution:r}):(()=\u003e{const t=lj(e,o,i,r,this.inputProblem.sectionSearchConfig,n);return this.selectedSectionCandidateLabel=t.winningCandidateLabel,this.selectedSectionCandidateFamily=t.winningCandidateFamily,this.stats={...this.stats,sectionSearchGeneratedCandidateCount:t.generatedCandidateCount,sectionSearchCandidateCount:t.candidateCount,sectionSearchDuplicateCandidateCount:t.duplicateCandidateCount,sectionSearchBaselineMaxRegionCost:t.baselineMaxRegionCost,sectionSearchFinalMaxRegionCost:t.finalMaxRegionCost,sectionSearchDelta:t.baselineMaxRegionCost-t.finalMaxRegionCost,selectedSectionCandidateLabel:t.winningCandidateLabel??null,selectedSectionCandidateFamily:t.winningCandidateFamily??null,sectionSearchMs:t.totalMs,sectionSearchBaselineEvaluationMs:t.baselineEvaluationMs,sectionSearchCandidateEligibilityMs:t.candidateEligibilityMs,sectionSearchCandidateInitMs:t.candidateInitMs,sectionSearchCandidateSolveMs:t.candidateSolveMs,sectionSearchCandidateReplayScoreMs:t.candidateReplayScoreMs},t.portSectionMask})();return this.selectedSectionMask=new Int8Array(s),i.portSectionMask=new Int8Array(s),this.stats={...this.stats,sectionMaskPortCount:[...s].filter(t=\u003e1===t).length},[o,i,r,n]}getInitialVisualizationSolver(){if(!this.initialVisualizationSolver){const{topology:t,problem:e}=this.loadHyperGraph(this.inputProblem.serializedHyperGraph);this.initialVisualizationSolver=new nB(t,e,this.getSolveGraphOptions())}return this.initialVisualizationSolver}initialVisualize(){return this.getInitialVisualizationSolver().visualize()}visualize(){return 0===this.iterations?this.initialVisualize()??super.visualize():super.visualize()}getOutput(){return this.getStageOutput(\"optimizeSection\")??this.getStageOutput(\"solveGraph\")??null}tryFinalAcceptance(){this.getStageOutput(\"solveGraph\")\u0026\u0026(this.stats={...this.stats,acceptedSolveGraphOutputOnSectionPipelineTimeout:!0},this.activeSubSolver=void 0,this.solved=!0,this.failed=!1,this.error=null)}};var hj=class extends aB{failedOwnerPairCounts=new Map;selectiveReripStats={selectiveRipCount:0,selectivelyRippedRouteCount:0,globalReripCount:0,alternateBlockerSearchCount:0,alternateOwnerCount:0,failedOwnerPairCount:0,maxFailedOwnerPairCount:0,failedOwnerPairs:[],lastDirectOwnerRouteIds:[],lastRepeatedOwnerRouteIds:[],lastAlternateOwnerRouteIds:[],lastRippedRouteIds:[],lastRelaxedSearchExpandedLabelCount:0,lastAlternateSearchExpandedLabelCount:0};selectiveReripCongestionUpdateCount=0;constructor(t,e,n){super(t,e,n)}getSelectiveReripStats(){return{...this.selectiveReripStats,failedOwnerPairs:this.selectiveReripStats.failedOwnerPairs.map(t=\u003e({...t})),lastDirectOwnerRouteIds:[...this.selectiveReripStats.lastDirectOwnerRouteIds],lastRepeatedOwnerRouteIds:[...this.selectiveReripStats.lastRepeatedOwnerRouteIds],lastAlternateOwnerRouteIds:[...this.selectiveReripStats.lastAlternateOwnerRouteIds],lastRippedRouteIds:[...this.selectiveReripStats.lastRippedRouteIds]}}onOutOfCandidates(){const t=this.state.currentRouteId;if(void 0===t)throw new Error(\"SelectiveReripTinyHyperGraphSolver: candidate search exhausted without a current route\");const e=this.findRelaxedBlockerPathPreferringPreservedRoutes();if(!e.found||0===e.owners.size)return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=e.found?\"no_blocker_path\":e.reason,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=[],this.selectiveReripStats.lastRepeatedOwnerRouteIds=[],this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=0,super.onOutOfCandidates(),void this.publishSelectiveReripStats();const n=[...e.owners],o=[];for(const e of n){this.incrementFailedOwnerPair(t,e)\u003e=2\u0026\u0026o.push(e)}if(n.some(e=\u003ethis.hasFailedOwnerPath(e,t)))return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=\"failed_owner_cycle\",this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=0,this.failedOwnerPairCounts.clear(),super.onOutOfCandidates(),void this.publishSelectiveReripStats();let i;if(o.length\u003e0\u0026\u0026(this.selectiveReripStats.alternateBlockerSearchCount+=1,i=this.findRelaxedBlockerPathPreferringPreservedRoutes(new Set(o)),!i.found))return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=i.reason,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=i.expandedLabelCount,super.onOutOfCandidates(),void this.publishSelectiveReripStats();const r=i?.found?[...i.owners]:void 0,s=function(t){const e=new Set(t.alternateOwnerRouteIds??t.directOwnerRouteIds);if(e.delete(t.failedRouteId),0===e.size)throw new Error(`SelectiveReripTinyHyperGraphSolver: route ${t.failedRouteId} has blocker resources but no distinct committed owner can be reripped`);return e}({failedRouteId:t,directOwnerRouteIds:n,alternateOwnerRouteIds:r});this.clearPartialRipPlans(s);const a=(r??[]).filter(t=\u003e!e.owners.has(t));this.selectiveReripCongestionUpdateCount\u003c1\u0026\u0026(this.addCongestionCostForSelectiveRerip(),this.selectiveReripCongestionUpdateCount+=1),this.rebuildCommittedState(s),this.state.ripCount+=1,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=function(t){const e=t.pendingRouteIds.filter(e=\u003ee!==t.failedRouteId\u0026\u0026!t.rippedRouteIds.has(e)),n=[...t.rippedRouteIds].filter(e=\u003ee!==t.failedRouteId);return[t.failedRouteId,...e,...n]}({failedRouteId:t,pendingRouteIds:this.state.unroutedRoutes,rippedRouteIds:s}),this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.selectiveReripStats.selectiveRipCount+=1,this.selectiveReripStats.selectivelyRippedRouteCount+=s.size,this.selectiveReripStats.alternateOwnerCount+=a.length,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=a,this.selectiveReripStats.lastRippedRouteIds=[...s],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=i?.expandedLabelCount??0,this.publishSelectiveReripStats()}addCongestionCostForSelectiveRerip(){for(let t=0;t\u003cthis.topology.regionCount;t++){const e=this.state.regionIntersectionCaches[t]?.existingRegionCost??0;this.state.regionCongestionCost[t]+=e*this.RIP_CONGESTION_REGION_COST_FACTOR}}findRelaxedBlockerPath(t=new Set){const e=this.state.currentRouteId,n=this.state.currentRouteNetId;if(void 0===e||void 0===n)throw new Error(\"SelectiveReripTinyHyperGraphSolver: blocker search requires a current route and net\");const o=this.getRouteStartPortId(e),i=this.getRouteEndPortId(e),r=this.getStartingNextRegionId(e,o);if(void 0===r)throw new Error(`SelectiveReripTinyHyperGraphSolver: route ${this.describeRoute(e)} has no starting region for blocker search`);const s=this.getPortOwners();return(t=\u003e{const e=t.maxExpandedLabels??Number.POSITIVE_INFINITY;if(e!==Number.POSITIVE_INFINITY\u0026\u0026(!Number.isInteger(e)||e\u003c0))throw new Error(\"maxExpandedLabels must be a non-negative integer\");const n=new Map,o=new kB;let i=0,r=0;const s={state:t.start,stateKey:t.getStateKey(t.start),owners:new Set,distance:0,parent:null,incomingHop:null,queueOrder:i++,active:!0};for(n.set(s.stateKey,[s]),o.push(s);;){const s=zB(o);if(null===s)return{found:!1,reason:\"no_path\",expandedLabelCount:r};if(t.isGoal(s.state))return DB(s,r);if(r\u003e=e)return{found:!1,reason:\"expansion_limit\",expandedLabelCount:r};r++;for(const e of t.getHops(s.state)){if(!Number.isFinite(e.distance)||e.distance\u003c0)throw new Error(\"Distinct-owner blocker hops require finite distances \u003e= 0\");const r=new Set(s.owners);for(const t of e.owners??[])r.add(t);const a=s.distance+e.distance;if(!Number.isFinite(a))throw new Error(\"Distinct-owner blocker path distance overflowed\");const c={state:e.state,stateKey:t.getStateKey(e.state),owners:r,distance:a,parent:s,incomingHop:e,queueOrder:i++,active:!0},l=n.get(c.stateKey)??[];if(l.some(t=\u003eLB(t,c)))continue;const d=[];for(const t of l)LB(c,t)?t.active=!1:d.push(t);d.push(c),n.set(c.stateKey,d),o.push(c)}}})({start:{portId:o,nextRegionId:r},getStateKey:({portId:t,nextRegionId:e})=\u003ethis.getHopId(t,e),isGoal:({portId:t})=\u003et===i,getHops:e=\u003ethis.getRelaxedSearchHops({state:e,goalPortId:i,routeNetId:n,portOwners:s,forbiddenOwnerRouteIds:t}),maxExpandedLabels:this.getRelaxedSearchExpansionLimit()})}findRelaxedBlockerPathPreferringPreservedRoutes(t=new Set){const e=this.getRouteIdsPreferredForPreservation();if(0===e.size)return this.findRelaxedBlockerPath(t);const n=new Set(t);for(const t of e)n.add(t);const o=this.findRelaxedBlockerPath(n);return o.found\u0026\u0026o.owners.size\u003e0?o:this.findRelaxedBlockerPath(t)}getRelaxedSearchExpansionLimit(){let t=0;for(const e of this.topology.incidentPortRegion)t+=e.length;const e=Math.max(4,Math.ceil(Math.log2(this.problem.routeCount+1)));return Math.max(4096,t*e*4)}getRelaxedSearchHops(t){const{state:e,goalPortId:n,routeNetId:o}=t;if(this.isRegionReservedForDifferentNet(e.nextRegionId))return[];const i=[];for(const r of this.topology.regionIncidentPorts[e.nextRegionId]??[]){if(r===e.portId)continue;if(this.isPortReservedForDifferentNet(r))continue;if(r!==n\u0026\u00260===this.problem.portSectionMask[r])continue;const s=this.getHopBlockerResources({regionId:e.nextRegionId,fromPortId:e.portId,toPortId:r,routeNetId:o,portOwners:t.portOwners}),a=[...new Set(s.flatMap(t=\u003et.owners))];if(a.some(e=\u003et.forbiddenOwnerRouteIds.has(e)))continue;let c=e.nextRegionId;if(r!==n){const[t,n]=this.topology.incidentPortRegion[r]??[];if(c=t===e.nextRegionId?n:t,void 0===c||this.isRegionReservedForDifferentNet(c))continue}i.push({state:{portId:r,nextRegionId:c},distance:Math.hypot(this.topology.portX[e.portId]-this.topology.portX[r],this.topology.portY[e.portId]-this.topology.portY[r]),owners:a,data:{resources:s}})}return i}getHopBlockerResources(t){const e=[],n=this.state.portAssignment[t.toPortId];if(-1!==n\u0026\u0026n!==t.routeNetId){const o=[...t.portOwners.get(t.toPortId)??new Set].filter(e=\u003ethis.problem.routeNet[e]!==t.routeNetId);if(0===o.length)throw new Error(`SelectiveReripTinyHyperGraphSolver: port ${t.toPortId} is assigned to foreign net ${n} without a committed route owner`);e.push({kind:\"port\",portId:t.toPortId,owners:o})}const o=this.getHardBlockedCrossingOwners(t.regionId,t.fromPortId,t.toPortId);return o.length\u003e0\u0026\u0026e.push({kind:\"same_layer_intersection\",regionId:t.regionId,fromPortId:t.fromPortId,toPortId:t.toPortId,owners:o}),e}getPortOwners(){const t=new Map;for(const e of this.state.regionSegments)for(const[n,o,i]of e)for(const e of[o,i]){const o=t.get(e)??new Set;o.add(n),t.set(e,o)}return t}getHardBlockedCrossingOwners(t,e,n){if(!this.isKnownSingleLayerRegion(t))return[];const o=this.state.currentRouteNetId;if(void 0===o)throw new Error(\"SelectiveReripTinyHyperGraphSolver: crossing ownership requires a current route net\");const i=new Set;for(const[r,s,a]of this.state.regionSegments[t]??[])this.problem.routeNet[r]!==o\u0026\u0026this.segmentsCrossOnSameLayer(t,e,n,s,a)\u0026\u0026i.add(r);return[...i]}segmentsCrossOnSameLayer(t,e,n,o,i){const r={...this.populateSegmentGeometryScratch(t,e,n)},s={...this.populateSegmentGeometryScratch(t,o,i)};if(0===(r.layerMask\u0026s.layerMask))return!1;if(r.lesserAngle===s.lesserAngle||r.lesserAngle===s.greaterAngle||r.greaterAngle===s.lesserAngle||r.greaterAngle===s.greaterAngle)return!1;return(r.lesserAngle\u003cs.lesserAngle\u0026\u0026s.lesserAngle\u003cr.greaterAngle)!==(r.lesserAngle\u003cs.greaterAngle\u0026\u0026s.greaterAngle\u003cr.greaterAngle)}rebuildCommittedState(t){this.state.regionSegments=this.state.regionSegments.map(e=\u003ee.filter(([e])=\u003e!t.has(e))),this.state.portAssignment.fill(-1),this.state.regionIntersectionCaches=Array.from({length:this.topology.regionCount},()=\u003eqF());for(let t=0;t\u003cthis.state.regionSegments.length;t++)for(const[e,n,o]of this.state.regionSegments[t]){const i=this.problem.routeNet[e];this.state.currentRouteNetId=i;for(const t of[n,o]){const e=this.state.portAssignment[t];if(-1!==e\u0026\u0026e!==i)throw new Error(`SelectiveReripTinyHyperGraphSolver: rebuilding committed routes found cross-net ownership at port ${t} between net ${e} and net ${i}`);this.state.portAssignment[t]=i}this.appendSegmentToRegionCache(t,n,o)}this.state.currentRouteNetId=void 0}incrementFailedOwnerPair(t,e){const n=this.failedOwnerPairCounts.get(t)??new Map,o=(n.get(e)??0)+1;return n.set(e,o),this.failedOwnerPairCounts.set(t,n),o}hasFailedOwnerPath(t,e){const n=[t],o=new Set;for(;n.length\u003e0;){const t=n.pop();if(t===e)return!0;o.has(t)||(o.add(t),n.push(...this.failedOwnerPairCounts.get(t)?.keys()??[]))}return!1}publishSelectiveReripStats(){const t=[];for(const[e,n]of this.failedOwnerPairCounts)for(const[o,i]of n)t.push({failedRouteId:e,ownerRouteId:o,count:i});t.sort((t,e)=\u003et.failedRouteId-e.failedRouteId||t.ownerRouteId-e.ownerRouteId),this.selectiveReripStats.failedOwnerPairs=t,this.selectiveReripStats.failedOwnerPairCount=t.length,this.selectiveReripStats.maxFailedOwnerPairCount=Math.max(0,...t.map(({count:t})=\u003et)),this.stats={...this.stats,...this.getSelectiveReripStats()}}describeRoute(t){const e=this.problem.routeMetadata?.[t]?.connectionId;return void 0===e?String(t):`${t} (${String(e)})`}};new Int32Array(0);var uj=class extends hj{initialAssignmentRouteIds;getRouteIdsPreferredForPreservation(){return this.initialAssignmentRouteIds||(this.initialAssignmentRouteIds=new Set((this.problem.initialAssignments??[]).map(t=\u003et.routeId))),this.initialAssignmentRouteIds}resetRoutingStateForRerip(){super.resetRoutingStateForRerip(),this.problem.initialAssignments?.length\u0026\u0026Uz({topology:this.topology,problem:this.problem,state:this.state,routeSuccessCountByRouteId:this.routeSuccessCountByRouteId,appendSegmentToRegionCache:(t,e,n)=\u003ethis.appendSegmentToRegionCache(t,e,n)})}},pj=t=\u003e{if(\"object\"!=typeof t||null===t)return!1;const e=t,n=e.preloadedTraceSection;return\"string\"==typeof e.connectionId\u0026\u0026\"string\"==typeof n?.traceId\u0026\u0026\"number\"==typeof n.startRoutePosition\u0026\u0026\"number\"==typeof n.endRoutePosition\u0026\u0026\"number\"==typeof n.startPoint?.x\u0026\u0026\"number\"==typeof n.startPoint.y\u0026\u0026\"number\"==typeof n.startPoint.z\u0026\u0026\"number\"==typeof n.endPoint?.x\u0026\u0026\"number\"==typeof n.endPoint.y\u0026\u0026\"number\"==typeof n.endPoint.z},mj=(t,e)=\u003e`__tscircuit_preloaded_trace__:${JSON.stringify([t,e])}`,gj=t=\u003e[t.region1Id,t.region2Id],fj=(t,e)=\u003e{const n=new Set(gj(e));return gj(t).filter(t=\u003en.has(t))},yj=(t,e,n)=\u003e{const o=t[e],i=t[e+1],r=fj(o.port,i.port);if(0===r.length)return;if(1===r.length)return r[0];const s=t[e+2];if(s){const t=new Set(fj(i.port,s.port)),e=r.find(e=\u003et.has(e));if(e)return e}return n\u0026\u0026r.includes(n)?n:[...r].sort()[0]},_j=(t,e)=\u003egj(t).find(t=\u003et!==e)??e,bj=t=\u003e{const e=new Set((t.connections??[]).filter(pj).map(t=\u003et.connectionId)),n=t.ports.filter(t=\u003e(t.d?._preloadedTracePortAssignments?.length??0)\u003e0).length,o=t.regions.reduce((t,n)=\u003et+(n.assignments??[]).filter(t=\u003ee.has(t.connectionId)).length,0);return{preloadedTraceCount:e.size,preloadedPortCount:n,preloadedAssignmentCount:o}},xj=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},vj=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},Sj=1e-6,Ij={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,PARTIAL_RIP_MIN_ROUTE_COUNT:100,PARTIAL_RIP_MAX_ROUTE_COUNT:350,PARTIAL_RIP_MAX_ATTEMPTS:7,PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS:1,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:100,PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO:.02,PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO:.05,PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO:.1},Cj={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:6,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:Number.POSITIVE_INFINITY},Pj=t=\u003eMath.max(t,.01),Mj=t=\u003eNumber.isFinite(t)?{minViaPadDiameter:t}:{},Nj=(t,e)=\u003e{const n=Pj(t);return{...Ij,...Mj(e),USE_SPARSE_CANDIDATE_STORAGE:!1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.ceil(10*n),MAX_ITERATIONS:Math.ceil(2e6*n)}},wj=(t,e)=\u003e{const n=Pj(t);return{...Cj,...Mj(e),USE_SPARSE_CANDIDATE_STORAGE:!1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.ceil(16*n),MAX_ITERATIONS:Math.ceil(1e6*n)}},Tj=t=\u003e(t.solveGraphOptions?.MAX_ITERATIONS??1e6)+(t.sectionSolverOptions?.MAX_ITERATIONS??1e6)+1e6,Rj=t=\u003et.mutuallyConnectedNetworkId,Ej=(t,e)=\u003et.simpleRouteConnection?.pointsToConnect[e],Aj=t=\u003e{const e=Ej(t.routeMetadata,t.endpointIndex);if(!e)return t.fallbackZ;const n=xo(e).map(e=\u003eko(e,t.layerCount));return t.regionAvailableZ.find(t=\u003en.includes(t))??t.fallbackZ},Oj=(t,e)=\u003e{const n=t.d,o=n.bounds;return{capacityMeshNodeId:t.d.capacityMeshNodeId,center:{x:t.d.center.x,y:t.d.center.y},width:t.d.width,height:t.d.height,availableZ:[...t.d.availableZ],...o?{bounds:{minX:o.minX,maxX:o.maxX,minY:o.minY,maxY:o.maxY}}:{},_containsObstacle:t.d._containsObstacle,_containsTarget:t.d._containsTarget,_offBoardConnectionId:t.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:void 0===t.d._offBoardConnectedCapacityMeshNodeIds?void 0:[...t.d._offBoardConnectedCapacityMeshNodeIds],_qfpRegionType:n._qfpRegionType,_isNarrowQfpPadGap:n._isNarrowQfpPadGap,...void 0!==e?{netId:e}:{}}},kj=t=\u003e{const e=t.d;return{portId:t.d.portId,x:t.d.x,y:t.d.y,z:t.d.z,prevPortPointId:e.prevPortPointId,nextPortPointId:e.nextPortPointId,distToCentermostPortOnZ:t.d.distToCentermostPortOnZ,tinyHypergraphPortPenalty:t.d.tinyHypergraphPortPenalty,cramped:t.d.cramped,_preloadedFixedNetIds:t.d._preloadedFixedNetIds,_preloadedTracePortAssignments:t.d._preloadedTracePortAssignments}},Lj=t=\u003e{const e=function(){const t=new Map;return e=\u003e{const n=e.mutuallyConnectedNetworkId;let o=t.get(n);return void 0===o\u0026\u0026(o=t.size,t.set(n,o)),o}}(),n=function(t){const e=new Map,n=new Set,o=new Map;for(const i of t.params.connections){const r=i.mutuallyConnectedNetworkId,s=t.getNetIndex({connectionId:i.connectionId,mutuallyConnectedNetworkId:r});for(const t of[i.connectionId,r])o.set(t,s);for(const o of i.simpleRouteConnection.pointsToConnect)for(const i of t.params.graph.regions){if(!gf({point:o,region:i,layerCount:t.params.layerCount}))continue;if(void 0===o.pcb_port_id\u0026\u0026!0!==i.d._containsTarget){n.add(i.regionId);continue}let r=e.get(i.regionId);r||(r=new Set,e.set(i.regionId,r)),r.add(s)}}for(const n of t.params.graph.regions)for(const t of n.d._connectedTo??[]){const i=o.get(t);if(void 0===i)continue;let r=e.get(n.regionId);r||(r=new Set,e.set(n.regionId,r)),r.add(i)}const i=new Map;for(const t of n)i.set(t,-1);for(const[t,n]of e)1===n.size\u0026\u0026i.set(t,[...n][0]);return i}({params:t,getNetIndex:e}),o=t.graph.regions.map(t=\u003e({regionId:t.regionId,pointIds:t.ports.map(t=\u003et.d.portId),d:Oj(t,n.get(t.regionId))})),i=t.graph.ports.map(t=\u003e({portId:t.d.portId,region1Id:t.region1.regionId,region2Id:t.region2.regionId,d:kj(t)})),r=t.connections.map(t=\u003e({connectionId:t.connectionId,mutuallyConnectedNetworkId:t.mutuallyConnectedNetworkId,startRegionId:t.startRegion.regionId,endRegionId:t.endRegion.regionId,simpleRouteConnection:t.simpleRouteConnection})),s=[];for(const n of t.connections){const r={connectionId:n.connectionId,mutuallyConnectedNetworkId:n.mutuallyConnectedNetworkId,simpleRouteConnection:n.simpleRouteConnection},a=e(r),c=Ej(r,0),l=Ej(r,1),d=n.startRegion.d.availableZ[0]??0,h=n.endRegion.d.availableZ[0]??0,u=Aj({routeMetadata:r,endpointIndex:0,fallbackZ:d,regionAvailableZ:n.startRegion.d.availableZ,layerCount:t.layerCount}),p=Aj({routeMetadata:r,endpointIndex:1,fallbackZ:h,regionAvailableZ:n.endRegion.d.availableZ,layerCount:t.layerCount}),m=`tiny-terminal:start-region:${n.connectionId}`,g=`tiny-terminal:end-region:${n.connectionId}`,f=`tiny-terminal:start-port:${n.connectionId}`,y=`tiny-terminal:end-port:${n.connectionId}`;o.push({regionId:m,pointIds:[f],d:{capacityMeshNodeId:m,center:{x:c?.x??n.startRegion.d.center.x,y:c?.y??n.startRegion.d.center.y},width:Sj,height:Sj,availableZ:[u],_containsTarget:!0,_tinyTerminal:!0,_tinyTerminalNetId:n.mutuallyConnectedNetworkId,netId:a}}),o.push({regionId:g,pointIds:[y],d:{capacityMeshNodeId:g,center:{x:l?.x??n.endRegion.d.center.x,y:l?.y??n.endRegion.d.center.y},width:Sj,height:Sj,availableZ:[p],_containsTarget:!0,_tinyTerminal:!0,_tinyTerminalNetId:n.mutuallyConnectedNetworkId,netId:a}}),i.push({portId:f,region1Id:n.startRegion.regionId,region2Id:m,d:{portId:f,x:c?.x??n.startRegion.d.center.x,y:c?.y??n.startRegion.d.center.y,z:u,distToCentermostPortOnZ:0,_tinyTerminal:!0,...t.preserveTerminalPcbPortIds\u0026\u0026c?.pcb_port_id?{pcb_port_id:c.pcb_port_id}:{}}}),i.push({portId:y,region1Id:n.endRegion.regionId,region2Id:g,d:{portId:y,x:l?.x??n.endRegion.d.center.x,y:l?.y??n.endRegion.d.center.y,z:p,distToCentermostPortOnZ:0,_tinyTerminal:!0,...t.preserveTerminalPcbPortIds\u0026\u0026l?.pcb_port_id?{pcb_port_id:l.pcb_port_id}:{}}});const _=o.find(t=\u003et.regionId===n.startRegion.regionId),b=o.find(t=\u003et.regionId===n.endRegion.regionId);_?.pointIds.push(f),b?.pointIds.push(y),s.push({connection:{connectionId:n.connectionId},path:[{portId:f},{portId:y}]})}const a={regions:o,ports:i,connections:r,solvedRoutes:s};return(t=\u003e{const e=new Map,n=new Map,o=new Set((t.connections??[]).flatMap(t=\u003e[t.startRegionId,t.endRegionId])),i=new Set(t.regions.filter(t=\u003e{const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;return!0===t.d?._containsObstacle\u0026\u0026(void 0===e||-1===e)\u0026\u0026!o.has(t.regionId)}).map(t=\u003et.regionId));let r=0;for(const o of t.ports){const t=o.d,s=t?._preloadedTracePortAssignments??[];if(s.length\u003e0\u0026\u0026r++,!i.has(o.region1Id)\u0026\u0026!i.has(o.region2Id))for(const t of s){const i=n.get(t.traceId);if(void 0!==i\u0026\u0026i!==t.fixedNetId)throw new Error(`Preloaded trace \"${t.traceId}\" maps to multiple canonical nets`);n.set(t.traceId,t.fixedNetId);const r=e.get(t.traceId)??[];r.push({port:o,assignment:t}),e.set(t.traceId,r)}}const s=new Map(t.regions.map(t=\u003e[t.regionId,t])),a=t.connections??=[],c=t.solvedRoutes??=[];let l=0,d=0;for(const[t,o]of e){o.sort((t,e)=\u003et.assignment.routePosition-e.assignment.routePosition||t.assignment.z-e.assignment.z||t.port.portId.localeCompare(e.port.portId));const e=o.filter(({port:t},e)=\u003e0===e||t.portId!==o[e-1].port.portId);if(e.length\u003c2)continue;const i=[];let r;for(let t=0;t\u003ce.length-1;t++){const n=e[t],o=e[t+1];if(n.assignment.z===o.assignment.z\u0026\u0026Math.abs(n.assignment.routePosition-o.assignment.routePosition)\u003c=1e-6){r=void 0;continue}const s=yj(e,t,r);s?(i.push({regionId:s,from:n,to:o}),r=s):r=void 0}const h=[];for(const t of i){const e=h.at(-1);e\u0026\u0026e.at(-1).to.port.portId===t.from.port.portId?e.push(t):h.push([t])}for(const[e,o]of h.entries()){const i=mj(t,e);for(const e of o){const n=s.get(e.regionId);if(!n)throw new Error(`Preloaded trace \"${t}\" references missing region \"${e.regionId}\"`);n.assignments=[...n.assignments??[],{regionPort1Id:e.from.port.portId,regionPort2Id:e.to.port.portId,connectionId:i}],d++}const r=o[0],l=o.at(-1),h=r.from.port,u=l.to.port,p={connectionId:i,mutuallyConnectedNetworkId:n.get(t)??t,startRegionId:_j(h,r.regionId),endRegionId:_j(u,l.regionId),preloadedTraceSection:{traceId:t,startRoutePosition:r.from.assignment.routePosition,endRoutePosition:l.to.assignment.routePosition,startPoint:{x:r.from.assignment.tracePoint.x,y:r.from.assignment.tracePoint.y,z:r.from.assignment.z},endPoint:{x:l.to.assignment.tracePoint.x,y:l.to.assignment.tracePoint.y,z:l.to.assignment.z}}};a.push(p),c.push({requiredRip:!1,connection:p,path:[h,u].map(t=\u003e({portId:t.portId,g:0,h:0,f:0,hops:0,ripRequired:!1}))})}h.length\u003e0\u0026\u0026l++}})(a),a},Dj=t=\u003e{const e=new Map;for(let n=0;n\u003ct.problem.routeNet.length;n++){const o=t.problem.routeMetadata?.[n],i=o?.mutuallyConnectedNetworkId;if(\"string\"!=typeof i||0===i.length)throw new Error(`Tiny hypergraph route ${n} is missing a net ID`);e.set(i,t.problem.routeNet[n])}for(let n=0;n\u003ct.problem.regionNetId.length;n++){const o=t.topology.regionMetadata?.[n]?._tinyTerminalNetId;if(\"string\"!=typeof o)continue;const i=e.get(o);void 0!==i\u0026\u0026(t.problem.regionNetId[n]=i)}},zj=t=\u003e{const e=new Map;t.topology.regionMetadata?.forEach((t,n)=\u003e{\"string\"==typeof t.serializedRegionId\u0026\u0026e.set(t.serializedRegionId,n)});const n=new Set;for(const e of t.problem.routeMetadata??[])pj(e)||(\"string\"==typeof e.startRegionId\u0026\u0026n.add(e.startRegionId),\"string\"==typeof e.endRegionId\u0026\u0026n.add(e.endRegionId));for(const o of t.problem.routeMetadata??[])if(pj(o))for(const i of[o.startRegionId,o.endRegionId]){if(\"string\"!=typeof i||n.has(i))continue;const o=e.get(i);if(void 0===o)continue;const r=t.topology.regionMetadata?.[o];\"number\"==typeof r?.netId||\"number\"==typeof r?.NetId||(t.problem.regionNetId[o]=-1)}},Fj=t=\u003e{if(t.problem.metadataPortPenaltiesApplied)return 0;let e=0,n=void 0!==t.problem.portPenalty;for(let o=0;o\u003ct.topology.portCount;o++){const i=Number(t.topology.portMetadata?.[o]?.tinyHypergraphPortPenalty),r=Number.isFinite(i)\u0026\u0026i\u003e0?i:0;r\u003e0\u0026\u0026e++,t.problem.portPenalty?.[o]!==r\u0026\u0026(n=!1)}if(n)return t.problem.metadataPortPenaltiesApplied=!0,e;e=0;const o=t.problem.portPenalty?new Float64Array(t.problem.portPenalty):new Float64Array(t.topology.portCount);for(let n=0;n\u003ct.topology.portCount;n++){const i=Number(t.topology.portMetadata?.[n]?.tinyHypergraphPortPenalty);!Number.isFinite(i)||i\u003c=0||(o[n]+=i,e++)}return e\u003e0\u0026\u0026(t.problem.portPenalty=o),t.problem.metadataPortPenaltiesApplied=!0,e},Bj=class extends dj{configuredSolvers=new WeakSet;duplicatePortPenaltyCount=0;metadataPortPenaltyCount=0;crampedPortPenaltyCount=0;preloadedPortCount=0;preloadedFixedSegmentCount=0;crampedPortTraversalPenalty;useSelectiveReripRouting;constructor(t,e){super(t),this.useSelectiveReripRouting=e,this.crampedPortTraversalPenalty=150;const n=bj(t.serializedHyperGraph);if(this.preloadedPortCount=n.preloadedPortCount,this.preloadedFixedSegmentCount=n.preloadedAssignmentCount,e){const t=this.pipelineDef.find(t=\u003e\"solveGraph\"===t.solverName);if(!t)throw new Error(\"Tiny hypergraph pipeline is missing the solveGraph stage\");t.solverClass=uj}this.MAX_ITERATIONS=Tj(t)}loadHyperGraph(t){const e=super.loadHyperGraph(t);((t,e)=\u003e{const n=new Map;for(const t of e.connections??[])pj(t)\u0026\u0026n.set(t.connectionId,t.preloadedTraceSection);for(const e of t.problem.routeMetadata??[]){const t=n.get(e.connectionId);t\u0026\u0026(e.preloadedTraceSection=t)}})(e,this.inputProblem.serializedHyperGraph);const n=Fj(e),{duplicatePortPenaltyCount:o,crampedPortPenaltyCount:i}=((t,e)=\u003e{let n=0,o=0;const i=t.problem.portPenalty?new Float64Array(t.problem.portPenalty):new Float64Array(t.topology.portCount);for(let r=0;r\u003ct.topology.portCount;r++){const s=t.topology.portMetadata?.[r];\"string\"==typeof s?.duplicatedFromPortId\u0026\u0026(i[r]+=150,n++),s?.cramped\u0026\u0026e\u003e0\u0026\u0026(i[r]+=e,o++)}return(n\u003e0||o\u003e0)\u0026\u0026(t.problem.portPenalty=i),{duplicatePortPenaltyCount:n,crampedPortPenaltyCount:o}})(e,this.crampedPortTraversalPenalty);return Dj(e),zj(e),this.metadataPortPenaltyCount=Math.max(this.metadataPortPenaltyCount,n),this.duplicatePortPenaltyCount=Math.max(this.duplicatePortPenaltyCount,o),this.crampedPortPenaltyCount=Math.max(this.crampedPortPenaltyCount,i),e}_step(){super._step(),this.configureSolver(this.activeSubSolver)}getInitialVisualizationSolver(){if(this.useSelectiveReripRouting\u0026\u0026!this.initialVisualizationSolver){const{topology:t,problem:e}=this.loadHyperGraph(this.inputProblem.serializedHyperGraph);this.initialVisualizationSolver=new uj(t,e,this.getSolveGraphOptions())}const t=super.getInitialVisualizationSolver();return this.configureSolver(t),t}getSolvedTinySolver(){const t=this.getSolver(\"optimizeSection\");if(t?.solved\u0026\u0026!t.failed)return t.getSolvedSolver();const e=this.getSolver(\"solveGraph\");if(e?.solved\u0026\u0026!e.failed)return e;throw new Error(\"TinyHyperGraph section pipeline does not have a solved graph\")}configureSolver(t){if(t\u0026\u0026!this.configuredSolvers.has(t)){if(t instanceof JB||t instanceof nB){const e=t;Fj(e),Dj(e),zj(e)}this.configuredSolvers.add(t)}}},jj=class extends si{constructor(t){super(),this.params=t;const e=(t=\u003et.map(t=\u003e{const e=t.simpleRouteConnection;if(!e)throw new Error(`TinyHypergraphPortPointPathingSolver requires a SimpleRouteConnection for \"${t.connectionId}\"`);const n=t.mutuallyConnectedNetworkId;if(!n)throw new Error(`TinyHypergraphPortPointPathingSolver requires a net ID for \"${t.connectionId}\"`);return{...t,mutuallyConnectedNetworkId:n,simpleRouteConnection:e}}))(t.connections),n=t.flags.USE_SELECTIVE_RERIP_ROUTING?function(t,e){const n=new Map;for(const o of t){const t=e(o);n.set(t,(n.get(t)??0)+1)}return t.map((t,e)=\u003e({connection:t,index:e})).sort((t,o)=\u003e(n.get(e(o.connection))??0)-(n.get(e(t.connection))??0)||t.index-o.index).map(({connection:t})=\u003et)}(e,Rj):e;this.rootConnectionNameByConnectionId=new Map(n.map(t=\u003e[t.connectionId,t.simpleRouteConnection.__rootConnectionNames?.[0]]));const o=Lj({...t,connections:n});this.originalPreloadedSegmentKeysByConnectionId=(t=\u003e{const e=new Map;for(const n of t.connections??[])pj(n)\u0026\u0026e.set(n.connectionId,new Set);for(const n of t.regions)for(const t of n.assignments??[]){const o=e.get(t.connectionId);if(!o)continue;const[i,r]=[t.regionPort1Id,t.regionPort2Id].sort();o.add(JSON.stringify([n.regionId,i,r]))}return e})(o);const i=bj(o),r=i.preloadedPortCount\u003e0,s=r\u0026\u0026!0===t.flags.USE_PARTIAL_RIP_ROUTING_WITH_PRELOADED_TRACES,a=s?Math.max(o.connections?.length??0,i.preloadedAssignmentCount):void 0;let c=o;if(n.length\u003c=180){const e=new AB(o,{duplicatePortProximity:.05,useSerializedPortPenalties:!1,routeSolveOptions:{...Mj(t.minViaPadDiameter),USE_SPARSE_CANDIDATE_STORAGE:!1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,MAX_ITERATIONS:Math.ceil(2e6*Pj(t.effort)),RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!0}});if(e.solve(),e.failed)this.duplicateCongestedPortError=e.error??\"unknown error\";else{this.duplicateCongestedPortReport=e.report,c=e.getOutput();for(const t of c.ports){const e=vj(t.d);\"string\"==typeof e.duplicatedFromPortId\u0026\u0026(delete e._preloadedFixedNetIds,delete e._preloadedTracePortAssignments)}}}else this.duplicateCongestedPortError=`Skipped for ${n.length} connections`;this.duplicatedPortCount=this.duplicateCongestedPortReport?.duplicatedPorts.reduce((t,e)=\u003et+e.duplicatePortIds.length,0)??0;const l=((t,e,n,o=!0,i)=\u003e{const r=t.connections?.length??0,s=i??r,a=Ij.PARTIAL_RIP_MIN_ROUTE_COUNT??0,c=Ij.PARTIAL_RIP_MAX_ROUTE_COUNT??Number.POSITIVE_INFINITY,l=o\u0026\u0026s\u003e=a\u0026\u0026s\u003c=c;return{serializedHyperGraph:t,createSectionMask:({topology:t})=\u003enew Int8Array(t.portCount),solveGraphOptions:{...Nj(e,n),...l?{PARTIAL_RIP_MIN_ROUTE_COUNT:0,PARTIAL_RIP_MAX_ROUTE_COUNT:Number.POSITIVE_INFINITY,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:0}:{PARTIAL_RIP_ENABLED:!1,OUTSIDE_IN_ROUTING:!1}},sectionSolverOptions:wj(e,n)}})({...c,solvedRoutes:o.solvedRoutes},t.effort,t.minViaPadDiameter,!r||s,a);this.tinyPipelineSolver=new Bj(l,!0===t.flags.USE_SELECTIVE_RERIP_ROUTING),this.primaryTinyPipelineSolver=this.tinyPipelineSolver,n.length\u003e=30\u0026\u0026n.length\u003c=99\u0026\u0026(this.alternativeTinyPipelineInput={...l,solveGraphOptions:{...l.solveGraphOptions,TRACE_DENSITY_COST_FACTOR:1}}),this.MAX_ITERATIONS=Tj(l)*(this.alternativeTinyPipelineInput?2:1),this.originalRegionById=new Map(t.graph.regions.map(t=\u003e[t.regionId,t])),this.originalRegionIds=new Set(this.originalRegionById.keys()),this.inputNodeWithPortPoints=((t,e)=\u003e{const n=new Map(e.regions.map(t=\u003e[t.regionId,t])),o=new Map(e.ports.map(t=\u003e[t.portId,t]));return t.graph.regions.map(t=\u003e{const e=n.get(t.regionId),i=(e?.pointIds??t.ports.map(t=\u003et.d.portId)).map(t=\u003eo.get(t)).filter(t=\u003et\u0026\u0026!vj(t.d)._tinyTerminal).map(t=\u003e{const e=t,o=vj(e.d),i=n.get(e.region1Id),r=n.get(e.region2Id),s=Boolean(xj(i?.d)._offBoardConnectionId??xj(r?.d)._offBoardConnectionId);return{portPointId:e.portId,x:Number(o.x??0),y:Number(o.y??0),z:Number(o.z??0),prevPortPointId:\"string\"==typeof o.prevPortPointId?o.prevPortPointId:void 0,nextPortPointId:\"string\"==typeof o.nextPortPointId?o.nextPortPointId:void 0,connectionNodeIds:[e.region1Id,e.region2Id],distToCentermostPortOnZ:Number(o.distToCentermostPortOnZ??0),cramped:Boolean(o.cramped),connectsToOffBoardNode:s}});return{capacityMeshNodeId:t.d.capacityMeshNodeId,center:t.d.center,width:t.d.width,height:t.d.height,portPoints:i,availableZ:t.d.availableZ,_containsObstacle:t.d._containsObstacle,_containsTarget:t.d._containsTarget,_offBoardConnectionId:t.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t.d._offBoardConnectedCapacityMeshNodeIds,_qfpRegionType:t.d._qfpRegionType,_isNarrowQfpPadGap:t.d._isNarrowQfpPadGap}})})(t,c)}params;tinyPipelineSolver;primaryTinyPipelineSolver;alternativeTinyPipelineSolver;alternativeTinyPipelineInput;candidatePortfolioPhase=\"primary\";primaryCandidateSummary;alternativeCandidateSummary;alternativeCandidateEvaluated=!1;selectedCandidate=\"primary\";duplicateCongestedPortReport;duplicateCongestedPortError;duplicatedPortCount=0;inputNodeWithPortPoints;originalRegionById;originalRegionIds;rootConnectionNameByConnectionId;originalPreloadedSegmentKeysByConnectionId;getSolverName(){return\"TinyHypergraphPortPointPathingSolver\"}getChangedPreloadedRouteIds(t){const e=new Map,n=new Map;for(let o=0;o\u003ct.problem.routeCount;o++){const i=this.getRouteMetadata(t,o);pj(i)\u0026\u0026(e.set(i.connectionId,o),n.set(o,new Set))}for(let e=0;e\u003ct.state.regionSegments.length;e++){const o=t.topology.regionMetadata?.[e]?.serializedRegionId;for(const[i,r,s]of t.state.regionSegments[e]??[]){const e=n.get(i);if(!e)continue;const a=t.topology.portMetadata?.[r]?.serializedPortId,c=t.topology.portMetadata?.[s]?.serializedPortId;if(\"string\"!=typeof o||\"string\"!=typeof a||\"string\"!=typeof c)throw new Error(`Tiny hypergraph preloaded route ${i} has a segment without serialized topology IDs`);const[l,d]=[a,c].sort();e.add(JSON.stringify([o,l,d]))}}const o=new Set;for(const[t,i]of this.originalPreloadedSegmentKeysByConnectionId){const r=e.get(t);if(void 0===r)throw new Error(`Tiny hypergraph lost preloaded trace section \"${t}\"`);const s=n.get(r);if(i.size\u003e0\u0026\u00260===s.size)throw new Error(`Tiny hypergraph lost preloaded trace section \"${t}\"`);(i.size!==s.size||[...i].some(t=\u003e!s.has(t)))\u0026\u0026o.add(r)}return o}summarizePipelineCandidate(t){const e=t.getSolvedTinySolver();let n=0,o=0,i=0,r=0,s=0,a=0;const c=e.topology.regionMetadata??[];for(let t=0;t\u003ce.state.regionSegments.length;t++){const l=e.state.regionSegments[t];s+=l.length;for(const[,t,n]of l)e.topology.portZ[t]!==e.topology.portZ[n]\u0026\u0026(a+=1);const d=c[t]?.capacityMeshNodeId;if(!d||!this.originalRegionIds.has(d))continue;const h=this.originalRegionById.get(d);if(!h||0===l.length)continue;const u=l.map(([t,n,o])=\u003e[this.createAssignedPortPoint(e,t,n),this.createAssignedPortPoint(e,t,o)]),p={capacityMeshNodeId:h.d.capacityMeshNodeId,center:h.d.center,width:h.d.width,height:h.d.height,portPoints:u.flat(),portPointsInPairs:u,availableZ:h.d.availableZ},m=Ms(p),g=Ys(h.d,m.numSameLayerCrossings,m.numEntryExitLayerChanges,m.numTransitionPairCrossings);n+=g,o+=g*g,i=Math.max(i,g),r+=p.portPoints.length**2}return{nodePfSum:n,nodePfSquaredSum:o,nodePfMax:i,squaredNodePortPointCount:r,segmentCount:s,layerChangeCount:a,changedPreloadedTraceSectionCount:this.getChangedPreloadedRouteIds(e).size}}shouldEvaluateAlternative(t){const e=this.primaryTinyPipelineSolver.getSolvedTinySolver().problem.routeCount;return void 0!==this.alternativeTinyPipelineInput\u0026\u0026((t,e)=\u003et.nodePfSum\u003e4\u0026\u0026t.nodePfMax\u003e1\u0026\u0026t.squaredNodePortPointCount/Math.max(1,e)\u003e=125)(t,e)}shouldSelectAlternative(t,e){return((t,e,n)=\u003e{if(e.changedPreloadedTraceSectionCount\u003et.changedPreloadedTraceSectionCount)return!1;const o=n\u003e40?.92:.95,i=e.nodePfSum\u003c=.9*t.nodePfSum\u0026\u0026e.nodePfSquaredSum\u003c=.85*t.nodePfSquaredSum\u0026\u0026e.nodePfMax\u003c=.85*t.nodePfMax\u0026\u0026e.squaredNodePortPointCount\u003c.98*t.squaredNodePortPointCount\u0026\u0026e.segmentCount\u003c=.97*t.segmentCount;return e.nodePfSum\u003c=1.03*t.nodePfSum\u0026\u0026e.nodePfSquaredSum\u003c=1.06*t.nodePfSquaredSum\u0026\u0026(e.squaredNodePortPointCount\u003ct.squaredNodePortPointCount*o||i)})(t,e,this.primaryTinyPipelineSolver.getSolvedTinySolver().problem.routeCount)}finishCandidatePortfolio(){this.candidatePortfolioPhase=\"complete\",this.solved=this.tinyPipelineSolver.solved,this.failed=this.tinyPipelineSolver.failed,this.error=this.tinyPipelineSolver.error??null}getSolveGraphBenchmarkMetrics(){const t=this.tinyPipelineSolver.getSolver(\"solveGraph\");if(!t)return;const e=t.state.regionSegments.map(t=\u003et.length),n=\"alternative\"===this.selectedCandidate?this.alternativeCandidateSummary:this.primaryCandidateSummary,o=t.stats,i=this.tinyPipelineSolver.getStageStats().solveGraph;return{routeCount:t.problem.routeCount,traceDensityCandidateEvaluated:this.alternativeCandidateEvaluated,traceDensityCandidateSelected:\"alternative\"===this.selectedCandidate,downstreamNodePfSum:n?.nodePfSum,downstreamNodePfSquaredSum:n?.nodePfSquaredSum,downstreamNodePfMax:n?.nodePfMax,downstreamSquaredNodePortPointCount:n?.squaredNodePortPointCount,changedPreloadedTraceSectionCount:n?.changedPreloadedTraceSectionCount,iterations:t.iterations,timeMs:i?.timeSpent,ripCount:o.ripCount,partialRipCount:o.partialRipCount,partiallyRippedRouteCount:o.partiallyRippedRouteCount,partiallyRippedSegmentCount:o.partiallyRippedSegmentCount,retainedPartialRipSegmentCount:o.retainedPartialRipSegmentCount,firstMaxRegionCost:o.firstMaxRegionCost,bestMaxRegionCost:o.bestMaxRegionCost,firstTotalRegionCost:o.firstTotalRegionCost,bestTotalRegionCost:o.bestTotalRegionCost,firstSegmentCount:o.firstSegmentCount,bestSolvedSegmentCount:o.bestSolvedSegmentCount,bestSolvedMaxRegionSegmentCount:o.bestSolvedMaxRegionSegmentCount,bestSolvedSquaredRegionSegmentCount:o.bestSolvedSquaredRegionSegmentCount,finalMaxRegionSegmentCount:Math.max(0,...e),finalSquaredRegionSegmentCount:e.reduce((t,e)=\u003et+e*e,0),finalSegmentCount:n?.segmentCount,finalLayerChangeCount:n?.layerChangeCount,warmupFullRipAttempts:o.partialRipWarmupFullRipAttempts,complexityAwareSelection:o.partialRipComplexityAwareSelection,targetReached:o.partialRipTargetReached,outsideInCompletedRouteCount:o.outsideInCompletedRouteCount,outsideInFallbackRouteCount:o.outsideInFallbackRouteCount,outsideInForwardExpansionCount:o.outsideInForwardExpansionCount,outsideInReverseExpansionCount:o.outsideInReverseExpansionCount}}_step(){this.tinyPipelineSolver.step(),\"primary\"===this.candidatePortfolioPhase\u0026\u0026this.primaryTinyPipelineSolver.failed?(this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio()):\"primary\"===this.candidatePortfolioPhase\u0026\u0026this.primaryTinyPipelineSolver.solved?(this.primaryCandidateSummary=this.summarizePipelineCandidate(this.primaryTinyPipelineSolver),this.shouldEvaluateAlternative(this.primaryCandidateSummary)?(this.alternativeCandidateEvaluated=!0,this.alternativeTinyPipelineSolver=new Bj(this.alternativeTinyPipelineInput,!0===this.params.flags.USE_SELECTIVE_RERIP_ROUTING),this.tinyPipelineSolver=this.alternativeTinyPipelineSolver,this.candidatePortfolioPhase=\"alternative\"):(this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio())):\"alternative\"===this.candidatePortfolioPhase\u0026\u0026(this.tinyPipelineSolver.solved||this.tinyPipelineSolver.failed)\u0026\u0026(this.tinyPipelineSolver.solved\u0026\u0026!this.tinyPipelineSolver.failed\u0026\u0026(this.alternativeCandidateSummary=this.summarizePipelineCandidate(this.tinyPipelineSolver)),this.alternativeCandidateSummary\u0026\u0026this.primaryCandidateSummary\u0026\u0026this.shouldSelectAlternative(this.primaryCandidateSummary,this.alternativeCandidateSummary)?(this.selectedCandidate=\"alternative\",this.primaryTinyPipelineSolver=void 0,this.alternativeTinyPipelineSolver=void 0):(this.tinyPipelineSolver=this.primaryTinyPipelineSolver,this.alternativeTinyPipelineSolver=void 0),this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio());const t=this.tinyPipelineSolver.getSolver(\"optimizeSection\"),e=this.getCurrentTinySolver();this.solved=\"complete\"===this.candidatePortfolioPhase\u0026\u0026this.tinyPipelineSolver.solved,this.failed=\"complete\"===this.candidatePortfolioPhase\u0026\u0026this.tinyPipelineSolver.failed,this.error=this.failed?this.tinyPipelineSolver.error??null:null,this.progress=\"complete\"===this.candidatePortfolioPhase?1:\"alternative\"===this.candidatePortfolioPhase?.5+.5*this.tinyPipelineSolver.progress:this.alternativeTinyPipelineInput?.5*this.tinyPipelineSolver.progress:this.tinyPipelineSolver.progress,this.stats={duplicateCongestedPortSourceCount:this.duplicateCongestedPortReport?.duplicatedPorts.length??0,duplicateCongestedPortCount:this.duplicateCongestedPortReport?.duplicatedPorts.reduce((t,e)=\u003et+e.duplicatePortIds.length,0)??0,duplicateCongestedPortFallbackToOriginal:Boolean(this.duplicateCongestedPortError),duplicateCongestedPortPenalty:this.duplicatedPortCount\u003e0?150:0,duplicateCongestedPortPenaltyCount:this.tinyPipelineSolver.duplicatePortPenaltyCount,metadataPortPenaltyCount:this.tinyPipelineSolver.metadataPortPenaltyCount,crampedPortPenalty:this.tinyPipelineSolver.crampedPortTraversalPenalty,crampedPortPenaltyCount:this.tinyPipelineSolver.crampedPortPenaltyCount,preloadedPortCount:this.tinyPipelineSolver.preloadedPortCount,preloadedFixedSegmentCount:this.tinyPipelineSolver.preloadedFixedSegmentCount,duplicateCongestedPortError:this.duplicateCongestedPortError,candidatePortfolioPhase:this.candidatePortfolioPhase,candidatePortfolioSelectedCandidate:this.selectedCandidate,candidatePortfolioPrimarySummary:this.primaryCandidateSummary,candidatePortfolioAlternativeSummary:this.alternativeCandidateSummary,...this.tinyPipelineSolver.stats??{},...e?.stats??{},...t?.stats??{},currentStage:this.tinyPipelineSolver.getCurrentStageName(),stageStats:this.tinyPipelineSolver.getStageStats()},this.activeSubSolver=this.tinyPipelineSolver.activeSubSolver??null}preview(){return this.visualize()}getCurrentTinySolver(){const t=this.tinyPipelineSolver.getSolver(\"optimizeSection\");if(t?.solved\u0026\u0026!t.failed)return t.getSolvedSolver();const e=this.tinyPipelineSolver.getSolver(\"solveGraph\");return e||void 0}getSolvedTinySolver(){return this.tinyPipelineSolver.getSolvedTinySolver()}getRouteMetadata(t,e){return t.problem.routeMetadata?.[e]}createAssignedPortPoint(t,e,n){const o=this.getRouteMetadata(t,e),i=o?(t=\u003et.simpleRouteConnection?.name??t.connectionId)(o):`route-${e}`,r=o?this.rootConnectionNameByConnectionId.get(o.connectionId)??o.mutuallyConnectedNetworkId:void 0,s=t.topology.portMetadata?.[n];return{portPointId:String(s?.serializedPortId??s?.portId??`tiny-port-${n}`),x:t.topology.portX[n],y:t.topology.portY[n],z:t.topology.portZ[n],connectionName:i,rootConnectionName:r,...this.params.preserveTerminalPcbPortIds\u0026\u0026\"string\"==typeof s?.pcb_port_id?{pcb_port_id:s.pcb_port_id}:{},prevPortPointId:\"string\"==typeof s?.prevPortPointId?s.prevPortPointId:void 0,nextPortPointId:\"string\"==typeof s?.nextPortPointId?s.nextPortPointId:void 0}}getOutput(){const t=this.getSolvedTinySolver(),e=[],n=t.state.regionSegments,o=t.topology.regionMetadata??[],i=this.getChangedPreloadedRouteIds(t);for(let r=0;r\u003cn.length;r++){const s=o[r]?.capacityMeshNodeId;if(!s||!this.originalRegionIds.has(s))continue;const a=this.originalRegionById.get(s);if(!a)continue;const c=n[r].filter(([e])=\u003e{const n=this.getRouteMetadata(t,e);return!pj(n)||i.has(e)}).map(([e,n,o])=\u003e{const i=this.createAssignedPortPoint(t,e,n),r=this.createAssignedPortPoint(t,e,o);return i.portPointId\u0026\u0026r.portPointId\u0026\u0026(i.nextPortPointId=r.portPointId,r.prevPortPointId=i.portPointId),[i,r]}),l=c.flat();0!==l.length\u0026\u0026e.push({capacityMeshNodeId:a.d.capacityMeshNodeId,center:a.d.center,width:a.d.width,height:a.d.height,portPoints:l,portPointsInPairs:c,availableZ:a.d.availableZ})}const r=[...i].map(e=\u003e{const n=this.getRouteMetadata(t,e);if(!pj(n))throw new Error(`Changed preloaded hypergraph route ${e} is missing section metadata`);const o=n.preloadedTraceSection;return{connectionName:n.connectionId,traceId:o.traceId,startRoutePosition:o.startRoutePosition,endRoutePosition:o.endRoutePosition,connection:{name:n.connectionId,__rootConnectionNames:[n.mutuallyConnectedNetworkId],pointsToConnect:[{x:o.startPoint.x,y:o.startPoint.y,layer:vo(o.startPoint.z,this.params.layerCount)},{x:o.endPoint.x,y:o.endPoint.y,layer:vo(o.endPoint.z,this.params.layerCount)}]}}});return this.stats.changedPreloadedTraceSectionCount=r.length,{nodesWithPortPoints:e,inputNodeWithPortPoints:this.inputNodeWithPortPoints,changedPreloadedTraceSections:r}}computeNodePf(t){const e=this.getOutput().nodesWithPortPoints.find(e=\u003ee.capacityMeshNodeId===t.capacityMeshNodeId),n=this.originalRegionById.get(t.capacityMeshNodeId);if(!e||!n)return null;const o=Ms(e);return Ys(n.d,o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.numTransitionPairCrossings)}tryFinalAcceptance(){}getConstructorParams(){return[this.params]}visualize(){return this.tinyPipelineSolver.visualize()}},$j=(t,e)=\u003e{if(!t||\"none\"===t)return t;try{const n=gt(t);return`rgba(${n.red},${n.green},${n.blue},${e})`}catch{return To(t,1-e)}},Yj=({srj:t,opacity:e=.25,visualizationOptions:n={}})=\u003e{const o=Ho({...t,obstacles:[]},n);return{...o,points:[],lines:o.lines?.map(t=\u003e({...t,strokeColor:$j(t.strokeColor,e)})),rects:o.rects?.map(t=\u003e({...t,fill:$j(t.fill,e),stroke:$j(t.stroke,e)})),circles:o.circles?.map(t=\u003e({...t,fill:$j(t.fill,e),stroke:$j(t.stroke,e)}))}};function Xj(t,e){return t.x\u003e=e.center.x-e.width/2\u0026\u0026t.x\u003c=e.center.x+e.width/2\u0026\u0026t.y\u003e=e.center.y-e.height/2\u0026\u0026t.y\u003c=e.center.y+e.height/2}var Vj=\"escape-via:\",Wj=1e-4,Hj=t=\u003et.obstacleId??[t.layers.join(\".\"),t.center.x.toFixed(4),t.center.y.toFixed(4),t.width.toFixed(4),t.height.toFixed(4)].join(\":\"),Gj=(t,e,n=1e-4)=\u003exe(t,e)\u003c=n,Uj=class extends si{constructor(t,e={}){super(),this.ogSrj=t,this.viaDiameter=e.viaDiameter??Yo(t).padDiameter,this.viaRadius=this.viaDiameter/2,this.minTraceWidth=e.minTraceWidth??t.minTraceWidth,this.obstacleMargin=e.obstacleMargin??t.defaultObstacleMargin??.15,this.requiredViaToPadClearance=Math.max(this.obstacleMargin,t.minViaEdgeToPadEdgeClearance??0),this.escapeOffset=this.viaRadius+Math.max(this.minTraceWidth/2,this.requiredViaToPadClearance),this.requiredTraceClearance=this.minTraceWidth/2+this.obstacleMargin/2,this.requiredViaToViaClearance=this.viaDiameter+this.obstacleMargin,this.outputSrj=t,this.escapeViaMetadataByPointId=new Map,this.createdEscapeVias=[]}ogSrj;getSolverName(){return\"EscapeViaLocationSolver\"}viaDiameter;viaRadius;minTraceWidth;obstacleMargin;escapeOffset;requiredTraceClearance;requiredViaToPadClearance;requiredViaToViaClearance;outputSrj;escapeViaMetadataByPointId;createdEscapeVias;nextEscapeViaIndex=0;getConnectionNetIds(t){return new Set([t.name,...t.__rootConnectionNames??[],t.__netConnectionName].filter(t=\u003eBoolean(t)))}obstacleMatchesConnectionNet(t,e){return t.connectedTo.some(t=\u003ee.has(t))}getObstacleZs(t){return t.__zLayers\u0026\u0026t.__zLayers.length\u003e0?t.__zLayers:t.layers.map(t=\u003eko(t,this.ogSrj.layerCount))}getViaSpanLayers(t,e){const n=ko(t,this.ogSrj.layerCount),o=ko(e,this.ogSrj.layerCount),i=Math.min(n,o),r=Math.max(n,o),s=Array.from({length:r-i+1},(t,e)=\u003ei+e);return{__zLayers:s,layers:s.map(t=\u003evo(t,this.ogSrj.layerCount))}}createEscapeViaObstacle(t){const{escapeVia:e,connectionNetIds:n}=t,{layers:o,__zLayers:i}=this.getViaSpanLayers(e.sourceLayer,e.targetLayer);return{obstacleId:`escape-via-obstacle:${e.pointId}`,type:\"rect\",layers:o,__zLayers:i,center:{x:e.x,y:e.y},width:this.viaDiameter,height:this.viaDiameter,connectedTo:Array.from(n)}}selectSourceObstacle(t){const{point:e,sourceLayer:n,connectionNetIds:o}=t;return this.ogSrj.obstacles.filter(t=\u003e!t.isCopperPour\u0026\u0026t.layers.includes(n)\u0026\u0026Xj(e,t)).sort((t,n)=\u003e{const i=t.connectedTo.includes(e.pointId??\"\")||t.connectedTo.includes(e.pcb_port_id??\"\")||this.obstacleMatchesConnectionNet(t,o);return i!==(n.connectedTo.includes(e.pointId??\"\")||n.connectedTo.includes(e.pcb_port_id??\"\")||this.obstacleMatchesConnectionNet(n,o))?i?-1:1:t.width*t.height-n.width*n.height})[0]}getCandidatePositions(t,e){if(!e)return this.dedupeCandidatePositions([{x:t.x+this.escapeOffset,y:t.y},{x:t.x-this.escapeOffset,y:t.y},{x:t.x,y:t.y+this.escapeOffset},{x:t.x,y:t.y-this.escapeOffset},{x:t.x+this.escapeOffset,y:t.y+this.escapeOffset},{x:t.x+this.escapeOffset,y:t.y-this.escapeOffset},{x:t.x-this.escapeOffset,y:t.y+this.escapeOffset},{x:t.x-this.escapeOffset,y:t.y-this.escapeOffset}]);const n=e.center.x-e.width/2,o=e.center.x+e.width/2,i=e.center.y-e.height/2,r=e.center.y+e.height/2,s=n-this.escapeOffset,a=o+this.escapeOffset,c=i-this.escapeOffset,l=r+this.escapeOffset,d=this.getEdgeSamples(i,r,t.y),h=this.getEdgeSamples(n,o,t.x),u=[];for(const t of d)u.push({x:s,y:t},{x:a,y:t});for(const t of h)u.push({x:t,y:c},{x:t,y:l});return this.dedupeCandidatePositions(u)}dedupeCandidatePositions(t){const e=[];for(const n of t)e.some(t=\u003eGj(t,n))||e.push(n);return e}pushEdgeSample(t,e,n,o){const i=Math.max(n,Math.min(o,e));t.some(t=\u003eMath.abs(t-i)\u003c=Wj)||t.push(i)}getEdgeSamples(t,e,n){const o=[],i=e-t;if(this.pushEdgeSample(o,n,t,e),i\u003c=Wj)return o;this.pushEdgeSample(o,t,t,e),this.pushEdgeSample(o,e,t,e),this.pushEdgeSample(o,(t+e)/2,t,e);const r=Math.max(t,Math.min(e,n)),s=Math.max(this.requiredViaToViaClearance,Wj),a=Math.ceil(i/s);for(let n=1;n\u003c=a;n++){const i=n*s;this.pushEdgeSample(o,r+i,t,e),this.pushEdgeSample(o,r-i,t,e)}return o}isInsideBoard(t){return!!(t.x\u003e=this.ogSrj.bounds.minX+this.viaRadius\u0026\u0026t.x\u003c=this.ogSrj.bounds.maxX-this.viaRadius\u0026\u0026t.y\u003e=this.ogSrj.bounds.minY+this.viaRadius\u0026\u0026t.y\u003c=this.ogSrj.bounds.maxY-this.viaRadius)\u0026\u0026(!(this.ogSrj.outline\u0026\u0026this.ogSrj.outline.length\u003e=3)||za(t,this.ogSrj.outline))}hasClearEscapePath(t){const{sourcePoint:e,candidate:n,sourceLayer:o,sourceObstacle:i}=t;if(this.ogSrj.outline\u0026\u0026this.ogSrj.outline.length\u003e=3){if(Fa({start:e,end:n,polygon:this.ogSrj.outline,margin:this.requiredTraceClearance}))return!1}for(const t of this.ogSrj.obstacles){if(t===i)continue;if(!t.layers.includes(o))continue;if(Xj(n,t))return!1;const r=Cl(t);if(Math.min(...r.map(t=\u003eRa(e,n,t.start,t.end)))+Wj\u003cthis.requiredTraceClearance)return!1}return!0}getBoardBoundarySegments(){if(this.ogSrj.outline\u0026\u0026this.ogSrj.outline.length\u003e=3)return this.ogSrj.outline.map((t,e)=\u003e({start:t,end:this.ogSrj.outline[(e+1)%this.ogSrj.outline.length]}));const{minX:t,maxX:e,minY:n,maxY:o}=this.ogSrj.bounds;return[{start:{x:t,y:n},end:{x:e,y:n}},{start:{x:e,y:n},end:{x:e,y:o}},{start:{x:e,y:o},end:{x:t,y:o}},{start:{x:t,y:o},end:{x:t,y:n}}]}getRayProbeDistance(){const{minX:t,maxX:e,minY:n,maxY:o}=this.ogSrj.bounds;return 2*Math.hypot(e-t,o-n)+this.viaDiameter}getRayIntersectionDistance(t){const{rayStart:e,rayEnd:n,segmentStart:o,segmentEnd:i}=t;if(!fe(e,n,o,i))return null;const r=ve(e,n,o,i);if(!r)return null;const s=xe(e,r);return s\u003c=Wj?null:s}getProjectedFreeSpace(t){const{sourcePoint:e,candidate:n}=t,o=n.x-e.x,i=n.y-e.y;return Math.abs(o)\u003c=Wj||Math.abs(i)\u003c=Wj?this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:o,y:i},travelDistance:xe(e,n)}):Math.min(this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:0,y:Math.sign(i)},travelDistance:Math.abs(i)}),this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:Math.sign(o),y:Math.sign(i)},travelDistance:xe(e,n)}),this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:Math.sign(o),y:0},travelDistance:Math.abs(o)}))}getProjectedFreeSpaceAlongDirection(t){const{sourcePoint:e,sourceLayer:n,sourceObstacle:o,direction:i,travelDistance:r}=t,s=Math.hypot(i.x,i.y);if(s\u003c=Wj||r\u003c=Wj)return 0;const a=this.getRayProbeDistance(),c=i.x/s,l=i.y/s,d={x:e.x+c*a,y:e.y+l*a};let h=Number.POSITIVE_INFINITY;for(const t of this.ogSrj.obstacles)if(t!==o\u0026\u0026t.layers.includes(n))for(const n of Cl(t)){const t=this.getRayIntersectionDistance({rayStart:e,rayEnd:d,segmentStart:n.start,segmentEnd:n.end});null!==t\u0026\u0026(h=Math.min(h,t))}for(const t of this.getBoardBoundarySegments()){const n=this.getRayIntersectionDistance({rayStart:e,rayEnd:d,segmentStart:t.start,segmentEnd:t.end});null!==n\u0026\u0026(h=Math.min(h,n))}return Number.isFinite(h)?Math.max(0,h-r):0}getMinBlockingClearance(t){const{candidate:e,connectionNetIds:n,sourceZ:o,targetZ:i}=t,r=Math.min(o,i),s=Math.max(o,i);let a=Number.POSITIVE_INFINITY;for(const t of this.ogSrj.obstacles){const n=this.getObstacleZs(t);if(!n.some(t=\u003et\u003e=r\u0026\u0026t\u003c=s))continue;if(t.isCopperPour\u0026\u0026!n.includes(o))continue;const i=Be(e,t)-this.viaRadius;if(a=Math.min(a,i),a+Wj\u003cthis.requiredViaToPadClearance)return a}return a}getMinPlacedEscapeViaClearance(t){let e=Number.POSITIVE_INFINITY;for(const n of this.createdEscapeVias){const o=xe(t,n)-this.viaDiameter;if(e=Math.min(e,o),e+Wj\u003cthis.obstacleMargin)return e}return e}selectPointOwner(t){const{point:e,groupConnections:n,matchingCopperPours:o}=t,i=ua(e),r=n.map(t=\u003e({connection:t,pointIndex:t.pointsToConnect.findIndex(t=\u003eua(t)===i)})).filter(t=\u003e-1!==t.pointIndex);return 0===r.length?null:(r.sort((t,e)=\u003e{const n=o.some(e=\u003ethis.obstacleMatchesConnectionNet(e,this.getConnectionNetIds(t.connection)));return n!==o.some(t=\u003ethis.obstacleMatchesConnectionNet(t,this.getConnectionNetIds(e.connection)))?n?-1:1:t.pointIndex-e.pointIndex}),r[0])}findBestEscapeViaCandidate(t){const{connection:e,point:n,pointIndex:o,matchingCopperPours:i,connectionNetIds:r,sourceObstacle:s}=t;if(!_o(n))return null;const a=n.layer,c=ko(a,this.ogSrj.layerCount),l=s??this.selectSourceObstacle({point:n,sourceLayer:a,connectionNetIds:r}),d=this.getCandidatePositions(n,l);let h=null;for(const t of i){const i=t.layers[0];if(!i||i===a)continue;const s=ko(i,this.ogSrj.layerCount),u=Hj(t);for(const p of d){if(!this.isInsideBoard(p))continue;if(!Xj(p,t))continue;if(!this.hasClearEscapePath({sourcePoint:n,candidate:p,sourceLayer:a,sourceObstacle:l}))continue;const d=this.getMinBlockingClearance({candidate:p,connectionNetIds:r,sourceZ:c,targetZ:s});if(d+Wj\u003cthis.requiredViaToPadClearance)continue;const m=this.getMinPlacedEscapeViaClearance(p);if(m+Wj\u003cthis.obstacleMargin)continue;const g=this.getProjectedFreeSpace({sourcePoint:n,candidate:p,sourceLayer:a,sourceObstacle:l}),f=Math.min(g,3),y=100*d-xe(n,p)-.5*Math.abs(s-c)+2*f+(Number.isFinite(m)?10*Math.min(m,this.requiredViaToViaClearance):0);(!h||y\u003eh.score)\u0026\u0026(h={pointId:`${Vj}${e.name}:${n.pointId??`p${o}`}:${i}:${this.nextEscapeViaIndex++}`,x:p.x,y:p.y,connectionName:e.name,rootConnectionName:e.__rootConnectionNames?.[0]??e.name,sourcePointIndex:o,sourcePointId:n.pointId,sourceLayer:a,targetLayer:i,targetPourKey:u,score:y})}}return h}buildPointPlacementPlans(t){const{mergedConnection:e,groupConnections:n,matchingCopperPours:o,connectionNetIds:i}=t,r=[];for(const t of e.pointsToConnect){const e=this.selectPointOwner({point:t,groupConnections:n,matchingCopperPours:o});if(!e)continue;const s=_o(t)?this.selectSourceObstacle({point:t,sourceLayer:t.layer,connectionNetIds:i}):void 0,a=_o(t)?this.getCandidatePositions(t,s).length:0;r.push({point:t,pointOwner:e,sourceObstacle:s,candidateCount:a})}return r.sort((t,e)=\u003e{if(t.candidateCount!==e.candidateCount)return t.candidateCount-e.candidateCount;const n=(t.sourceObstacle?.width??0)*(t.sourceObstacle?.height??0),o=(e.sourceObstacle?.width??0)*(e.sourceObstacle?.height??0);return n!==o?n-o:t.pointOwner.pointIndex-e.pointOwner.pointIndex})}_step(){const t=this.ogSrj.obstacles.filter(t=\u003et.isCopperPour),e=this.ogSrj.connections,n=e.map(t=\u003estructuredClone(t)),o=new Map(n.map(t=\u003e[t.name,t])),i=structuredClone(this.ogSrj.obstacles),r=pa([...e]);for(const n of r){const r=new Set(n.__rootConnectionNames??[n.name]),s=e.filter(t=\u003e(t.__rootConnectionNames??[t.name]).some(t=\u003er.has(t)));if(0===s.length)continue;const a=new Set;for(const t of s)for(const e of this.getConnectionNetIds(t))a.add(e);const c=t.filter(t=\u003ethis.obstacleMatchesConnectionNet(t,a));if(0===c.length)continue;const l=new Map,d=new Map,h=this.buildPointPlacementPlans({mergedConnection:n,groupConnections:s,matchingCopperPours:c,connectionNetIds:a});for(const{point:t,pointOwner:e,sourceObstacle:n}of h){const r=this.findBestEscapeViaCandidate({connection:e.connection,point:t,pointIndex:e.pointIndex,matchingCopperPours:c,connectionNetIds:a,sourceObstacle:n});if(!r)continue;const s=o.get(e.connection.name);if(!s)continue;if(s.pointsToConnect.some(t=\u003e_o(t)\u0026\u0026t.layer===r.sourceLayer\u0026\u0026Gj(t,r)))continue;s.pointsToConnect.push({x:r.x,y:r.y,layer:r.sourceLayer,pointId:r.pointId,terminalVia:{toLayer:r.targetLayer,viaDiameter:this.viaDiameter}}),this.escapeViaMetadataByPointId.set(r.pointId,r),this.createdEscapeVias.push(r),i.push(this.createEscapeViaObstacle({escapeVia:r,connectionNetIds:this.getConnectionNetIds(e.connection)}));const h=l.get(r.targetPourKey);h?h.push(r.pointId):l.set(r.targetPourKey,[r.pointId]),d.has(r.targetPourKey)||d.set(r.targetPourKey,e.connection.name)}for(const[t,e]of l.entries()){if(e.length\u003c=1)continue;const n=d.get(t);if(!n)continue;const i=o.get(n);i\u0026\u0026(i.externallyConnectedPointIds=[...i.externallyConnectedPointIds??[],e])}}this.outputSrj={...structuredClone(this.ogSrj),connections:n,obstacles:i},this.solved=!0}getOutputSimpleRouteJson(){return structuredClone(this.outputSrj)}getEscapeViaMetadataByPointId(){return new Map(this.escapeViaMetadataByPointId)}visualize(){return{title:\"Escape Via Location Solver\",points:this.outputSrj.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({x:e.x,y:e.y,color:!0===e.pointId?.startsWith(Vj)?\"#0f766e\":\"#dc2626\",label:!0===e.pointId?.startsWith(Vj)?`${t.name}\\nescape via`:t.name}))),lines:this.createdEscapeVias.map(t=\u003e{const e=this.outputSrj.connections.find(e=\u003ee.name===t.connectionName)?.pointsToConnect[t.sourcePointIndex]??null;return{points:e?[{x:e.x,y:e.y},{x:t.x,y:t.y}]:[{x:t.x,y:t.y}],strokeColor:\"#0f766e\"}}),circles:this.createdEscapeVias.map(t=\u003e({center:{x:t.x,y:t.y},radius:this.viaRadius,strokeColor:\"#0f766e\",label:`${t.connectionName}\\n${t.targetLayer}`})),rects:this.outputSrj.obstacles.filter(t=\u003e!t.isCopperPour).map(t=\u003e({...t,fill:\"rgba(220,38,38,0.12)\"}))}}},Zj=t=\u003e({...t}),qj=t=\u003e({...t,route:t.route?.map(Zj),vias:t.vias?.map(t=\u003e({...t}))}),Jj=t=\u003et.map(qj),Kj=\"#0000FF\",Qj=.15,t$=1e-6,e$=.1,n$=[\"top\",\"bottom\",\"left\",\"right\"],o$=t=\u003et.x*t.x+t.y*t.y,i$=(t,e)=\u003e({x:t.x-e.x,y:t.y-e.y}),r$=(t,e,n)=\u003e{const o=i$(n,e),i=o$(o);if(i\u003c=t$)return Math.sqrt(o$(i$(t,e)));const r=(a=i$(t,e),c=o,s=(a.x*c.x+a.y*c.y)/i,Math.max(0,Math.min(1,s)));var s,a,c;const l={x:e.x+o.x*r,y:e.y+o.y*r};return Math.sqrt(o$(i$(t,l)))},s$=t=\u003e1===t?.z?\"bottom\":\"top\",a$=(t,e,n)=\u003e(t.z??0)===(e.z??0)\u0026\u0026((e.z??0)===(n.z??0)\u0026\u0026(t.x===e.x\u0026\u0026e.x===n.x||t.y===e.y\u0026\u0026e.y===n.y)),c$=(t,e,n)=\u003e{const o=n?.get(t);if(o)return o;const i=t.route??[],r=t.traceThickness??Qj;let s=Number.POSITIVE_INFINITY,a=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY,l=Number.NEGATIVE_INFINITY,d=!1;const h=(t,e,n)=\u003e{s=Math.min(s,t-n),a=Math.min(a,e-n),c=Math.max(c,t+n),l=Math.max(l,e+n),d=!0},u={segments:[],segmentsByLayer:{top:[],bottom:[]},vias:(t.vias??[]).map(n=\u003e{const o=(n.diameter??t.viaDiameter??.3)/2;return h(n.x,n.y,o),{center:{x:n.x,y:n.y},radius:o,routeIndex:e}}),bounds:{minX:0,minY:0,maxX:0,maxY:0}};for(let t=0;t\u003ci.length-1;){const n=i[t];let o=t+1,s=i[o];const a=r/2;for(n\u0026\u0026h(n.x,n.y,a),s\u0026\u0026h(s.x,s.y,a);o\u003ci.length-1;){const t=i[o],e=i[o+1];if(!n||!t||!e)break;if(s$(n)!==s$(t))break;if(s$(t)!==s$(e))break;if(!a$(n,t,e))break;o+=1,s=e,h(e.x,e.y,a)}if(!n||!s){t+=1;continue}const c=s$(n),l={start:n,end:s,routeIndex:e,pointIndex:t,endPointIndex:o,thickness:r,halfThickness:a,layer:c,minX:Math.min(n.x,s.x)-a,maxX:Math.max(n.x,s.x)+a,minY:Math.min(n.y,s.y)-a,maxY:Math.max(n.y,s.y)+a};u.segments.push(l),u.segmentsByLayer[c].push(l),t=o}if(!d)for(const t of i)h(t.x,t.y,r/2);return u.bounds=d?{minX:s,minY:a,maxX:c,maxY:l}:{minX:0,minY:0,maxX:0,maxY:0},n?.set(t,u),u},l$=(t,e,n)=\u003ee.x\u003c=Math.max(t.x,n.x)+t$\u0026\u0026e.x\u003e=Math.min(t.x,n.x)-t$\u0026\u0026e.y\u003c=Math.max(t.y,n.y)+t$\u0026\u0026e.y\u003e=Math.min(t.y,n.y)-t$,d$=(t,e,n)=\u003e(e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y),h$=(t,e,n,o)=\u003e((t,e,n,o)=\u003e{const i=d$(t,e,n),r=d$(t,e,o),s=d$(n,o,t),a=d$(n,o,e);return!!(Math.abs(i)\u003c=t$\u0026\u0026l$(t,n,e))||!!(Math.abs(r)\u003c=t$\u0026\u0026l$(t,o,e))||!!(Math.abs(s)\u003c=t$\u0026\u0026l$(n,t,o))||!!(Math.abs(a)\u003c=t$\u0026\u0026l$(n,e,o))||i\u003e0!=r\u003e0\u0026\u0026s\u003e0!=a\u003e0})(t,e,n,o)?0:Math.min(r$(t,n,o),r$(e,n,o),r$(n,t,e),r$(o,t,e)),u$=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=t$\u0026\u0026Math.abs(t.y-e.y)\u003c=t$,p$=(t,e)=\u003eu$(t.start,e.start)||u$(t.start,e.end)||u$(t.end,e.start)||u$(t.end,e.end),m$=t=\u003e{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))},g$=(t,e)=\u003e{const n=m$(t),o=m$(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))},f$=(t,e,n)=\u003et.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY,y$=(t,e,n)=\u003e{const o=n+t.halfThickness+e.halfThickness-t$;return t.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY\u0026\u0026o\u003e0},_$=(t,e,n,o)=\u003e{const i=o+n.halfThickness+e-t$,r=t.x-i,s=t.x+i,a=t.y-i,c=t.y+i;return r\u003c=n.maxX\u0026\u0026s\u003e=n.minX\u0026\u0026a\u003c=n.maxY\u0026\u0026c\u003e=n.minY},b$=(t,e)=\u003e{const n=new WeakMap,o=t.map((t,e)=\u003ec$(t,e,n)),i=[],r=new Set,s=t=\u003e{r.has(t.label)||(r.add(t.label),i.push(t))};for(let n=0;n\u003co.length;n+=1){const i=o[n];if(i)for(let r=n+1;r\u003co.length;r+=1){const a=o[r];if(a\u0026\u0026(!g$(t[n],t[r])\u0026\u0026f$(i.bounds,a.bounds,e))){for(const t of[\"top\",\"bottom\"]){const o=i.segmentsByLayer[t],c=a.segmentsByLayer[t];for(const i of o)for(const o of c){if(p$(i,o))continue;if(!y$(i,o,e))continue;const a=e+(i.thickness+o.thickness)/2-t$;if(h$(i.start,i.end,o.start,o.end)\u003e=a)continue;s({center:{x:(Math.max(i.minX-e,o.minX-e)+Math.min(i.maxX+e,o.maxX+e))/2,y:(Math.max(i.minY-e,o.minY-e)+Math.min(i.maxY+e,o.maxY+e))/2},label:`trace-violation:${n}:s${i.pointIndex}:${r}:s${o.pointIndex}:${t}`})}}for(const t of i.segments)for(const[o,i]of a.vias.entries()){if(!_$(i.center,i.radius,t,e))continue;const a=e+t.halfThickness+i.radius-t$;r$(i.center,t.start,t.end)\u003e=a||s({center:i.center,label:`trace-violation:${n}:s${t.pointIndex}:${r}:v${o}`})}for(const t of a.segments)for(const[o,a]of i.vias.entries()){if(!_$(a.center,a.radius,t,e))continue;const i=e+t.halfThickness+a.radius-t$;r$(a.center,t.start,t.end)\u003e=i||s({center:a.center,label:`trace-violation:${n}:v${o}:${r}:s${t.pointIndex}`})}}}}return(t=\u003e{const e=[];for(const n of t){const t=e.find(t=\u003e{return e=t.center,o=n.center,Math.hypot(e.x-o.x,e.y-o.y)\u003c=.28;var e,o});t?(t.center={x:(t.center.x*t.count+n.center.x)/(t.count+1),y:(t.center.y*t.count+n.center.y)/(t.count+1)},t.labels.push(n.label),t.count+=1):e.push({center:n.center,labels:[n.label],count:1})}return e.map((t,e)=\u003e({center:t.center,radius:Math.min(.3,.2+.035*Math.sqrt(t.count-1)),stroke:\"#f59e0b\",fill:\"rgba(245, 158, 11, 0.46)\",label:1===t.count?t.labels[0]:`trace-violations:${e}:count-${t.count}`}))})(i)},x$=({routeIndexes:t,layers:e,routePointIndexes:n})=\u003e`${t[0]}:${e[0]}:${n[0].join(\",\")}:${t[1]}:${e[1]}:${n[1].join(\",\")}`,v$=(t,e,n,o,i,r,s)=\u003e{const a=((t,e,n,o,i,r)=\u003et\u003cn?`${t}:${e}:${i.join(\",\")}:${n}:${o}:${r.join(\",\")}`:`${n}:${o}:${r.join(\",\")}:${t}:${e}:${i.join(\",\")}`)(e,n,o,i,r,s),c=t.get(a);if(c){const[t,n]=e\u003co?[r,s]:[s,r];for(const e of t)c.routePointIndexes[0].includes(e)||c.routePointIndexes[0].push(e);for(const t of n)c.routePointIndexes[1].includes(t)||c.routePointIndexes[1].push(t);return c.routePointIndexes[0].sort((t,e)=\u003et-e),void c.routePointIndexes[1].sort((t,e)=\u003et-e)}e\u003co?t.set(a,{routeIndexes:[e,o],layers:[n,i],routePointIndexes:[[...new Set(r)].sort((t,e)=\u003et-e),[...new Set(s)].sort((t,e)=\u003et-e)]}):t.set(a,{routeIndexes:[o,e],layers:[i,n],routePointIndexes:[[...new Set(s)].sort((t,e)=\u003et-e),[...new Set(r)].sort((t,e)=\u003et-e)]})},S$=t=\u003e{const e=[];for(let n=t.pointIndex;n\u003c=t.endPointIndex;n+=1)e.push(n);return e},I$=(t,e)=\u003e!e||t.some(t=\u003ee.has(t)),C$=(t,e)=\u003e{const n=t.route??[],o=[];for(let t=0;t\u003cn.length;t+=1){const i=n[t];i\u0026\u0026(Math.abs(i.x-e.center.x)\u003c=t$\u0026\u0026Math.abs(i.y-e.center.y)\u003c=t$\u0026\u0026o.push(t))}return o},P$=(t,e,n)=\u003et.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY,M$=(t,e,n)=\u003e{const o=n+t.halfThickness+e.halfThickness-t$;return t.minX-n\u003c=e.maxX\u0026\u0026t.maxX+n\u003e=e.minX\u0026\u0026t.minY-n\u003c=e.maxY\u0026\u0026t.maxY+n\u003e=e.minY\u0026\u0026o\u003e0},N$=(t,e,n,o)=\u003e{const i=o+n.halfThickness+e-t$,r=t.x-i,s=t.x+i,a=t.y-i,c=t.y+i;return r\u003c=n.maxX\u0026\u0026s\u003e=n.minX\u0026\u0026a\u003c=n.maxY\u0026\u0026c\u003e=n.minY},w$=(t,e,n)=\u003e{const o=n+t.radius+e.radius-t$;return Math.abs(t.center.x-e.center.x)\u003c=o\u0026\u0026Math.abs(t.center.y-e.center.y)\u003c=o},T$=(t,e,n,o,i)=\u003e{const r=t.map((t,e)=\u003ec$(t,e,o)),s=new Map;if(0===e.size)return[];const a=Array.from(e),c=new Map,l=t=\u003e{const e=c.get(t);if(e)return e;const o=r[t];if(!o)return[];const i=[];for(let e=0;e\u003cr.length;e+=1){if(e===t)continue;const s=r[e];s\u0026\u0026(P$(o.bounds,s.bounds,n)\u0026\u0026i.push(e))}return c.set(t,i),i};for(const t of a){const o=r[t];if(!o)continue;const a=l(t),c=i?.get(t);for(const l of o.segments){const o=S$(l);if(I$(o,c))for(const c of a){if(t\u003ec\u0026\u0026e.has(c))continue;const a=r[c];if(!a)continue;const d=i?.get(c),h=a.segmentsByLayer[l.layer];for(const t of h){const e=S$(t);if(!I$(e,d))continue;if(p$(l,t))continue;if(!M$(l,t,n))continue;const i=n+(l.thickness+t.thickness)/2-t$;h$(l.start,l.end,t.start,t.end)\u003ci\u0026\u0026v$(s,l.routeIndex,l.layer,t.routeIndex,t.layer,o,e)}}}}for(const o of a){const a=r[o];if(!a)continue;const c=l(o),d=i?.get(o);for(const l of a.vias){const a=C$(t[l.routeIndex],l);if(I$(a,d))for(const t of c){if(o\u003et\u0026\u0026e.has(t))continue;const c=r[t];if(!c)continue;const d=i?.get(t);for(const t of c.segments){const e=S$(t);if(!I$(e,d))continue;if(!N$(l.center,l.radius,t,n))continue;const o=n+t.thickness/2+l.radius-t$;r$(l.center,t.start,t.end)\u003co\u0026\u0026v$(s,t.routeIndex,t.layer,l.routeIndex,\"via\",e,a)}}}}for(const e of a){const o=r[e];if(!o)continue;const a=l(e),c=i?.get(e);for(const e of o.segments){const o=S$(e);if(I$(o,c))for(const c of a){const a=r[c];if(!a)continue;const l=i?.get(c);for(const i of a.vias){const r=C$(t[i.routeIndex],i);if(!I$(r,l))continue;if(!N$(i.center,i.radius,e,n))continue;const a=n+e.thickness/2+i.radius-t$;r$(i.center,e.start,e.end)\u003ca\u0026\u0026v$(s,e.routeIndex,e.layer,i.routeIndex,\"via\",o,r)}}}}for(const o of a){const a=r[o];if(!a)continue;const c=l(o),d=i?.get(o);for(const l of a.vias){const a=C$(t[l.routeIndex],l);if(I$(a,d))for(const d of c){if(o\u003ed\u0026\u0026e.has(d))continue;const c=r[d];if(!c)continue;const h=i?.get(d);for(const e of c.vias){const o=C$(t[e.routeIndex],e);if(!I$(o,h))continue;if(!w$(l,e,n))continue;const i=n+l.radius+e.radius-t$;Math.hypot(l.center.x-e.center.x,l.center.y-e.center.y)\u003ci\u0026\u0026v$(s,l.routeIndex,\"via\",e.routeIndex,\"via\",a,o)}}}}return Array.from(s.values())},R$=(t,e)=\u003et.x\u003e=e.minX-t$\u0026\u0026t.x\u003c=e.maxX+t$\u0026\u0026t.y\u003e=e.minY-t$\u0026\u0026t.y\u003c=e.maxY+t$,E$=(t,e,n)=\u003e{switch(e){case\"left\":return{minX:t.minX,maxX:t.minX+n,minY:t.minY,maxY:t.maxY};case\"right\":return{minX:t.maxX-n,maxX:t.maxX,minY:t.minY,maxY:t.maxY};case\"top\":return{minX:t.minX,maxX:t.maxX,minY:t.maxY-n,maxY:t.maxY};case\"bottom\":return{minX:t.minX,maxX:t.maxX,minY:t.minY,maxY:t.minY+n}}},A$=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;let r=0,s=1;const a=(t,e)=\u003e{if(Math.abs(t)\u003c=t$)return e\u003e=-1e-6;const n=e/t;return t\u003c0?!(n\u003es)\u0026\u0026(n\u003er\u0026\u0026(r=n),!0):!(n\u003cr)\u0026\u0026(n\u003cs\u0026\u0026(s=n),!0)};if(!(a(-o,t.x-n.minX)\u0026\u0026a(o,n.maxX-t.x)\u0026\u0026a(-i,t.y-n.minY)\u0026\u0026a(i,n.maxY-t.y)))return 0;const c=Math.hypot(o,i);return Math.max(0,s-r)*c},O$=(t,e)=\u003en$.filter(n=\u003e{switch(n){case\"left\":return Math.abs(t.x-e.minX)\u003c=t$;case\"right\":return Math.abs(t.x-e.maxX)\u003c=t$;case\"top\":return Math.abs(t.y-e.maxY)\u003c=t$;case\"bottom\":return Math.abs(t.y-e.minY)\u003c=t$}return!1}),k$=(t,e)=\u003e{const n=[];return t.x\u003ce.minX-t$\u0026\u0026n.push(\"left\"),t.x\u003ee.maxX+t$\u0026\u0026n.push(\"right\"),t.y\u003ee.maxY+t$\u0026\u0026n.push(\"top\"),t.y\u003ce.minY-t$\u0026\u0026n.push(\"bottom\"),n},L$=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;switch(n){case\"left\":case\"right\":return Math.abs(o)\u003c=t$\u0026\u0026Math.abs(i)\u003et$;case\"top\":case\"bottom\":return Math.abs(i)\u003c=t$\u0026\u0026Math.abs(o)\u003et$}},D$=(t,e,n)=\u003e{const o=[],i=Math.max(n,t$),r=Math.min(.1,i/4);for(let n=0;n\u003ct.length;n+=1){const s=t[n],a=s?.route??[];for(let t=0;t\u003ca.length-1;t+=1){const c=a[t],l=a[t+1];if(!c||!l)continue;const d=k$(c,e),h=k$(l,e),u=O$(c,e),p=O$(l,e),m=n$.filter(t=\u003e{if(s.connectedPadSides?.includes(t))return!1;return!(A$(c,l,E$(e,t,i))\u003c=r)\u0026\u0026!!L$(c,l,t)}),g=!R$(c,e)||!R$(l,e),f=Array.from(new Set([...m,...d,...h]));(g||0!==f.length)\u0026\u0026o.push({routeIndex:n,connectionName:s.connectionName??s.rootConnectionName??`route-${n}`,segmentIndex:t,touchedSides:f,startSides:u,endSides:p,start:c,end:l})}}return o},z$=t=\u003et?.center\u0026\u0026t.width\u0026\u0026t.height?{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,width:t.width,height:t.height,center:t.center}:null,F$=t=\u003e\"bottom\"===t?Kj:\"#FF0000\",B$=t=\u003e{const e=t.route??[],n=[];if(e.length\u003c2)return n;let o=s$(e[0]),i=[e[0]];for(let r=1;r\u003ce.length;r+=1){const s=e[r],a=s$(s);a===o?i.push(s):(i.length\u003e=2\u0026\u0026n.push({points:i,strokeColor:F$(o),strokeWidth:t.traceThickness??Qj,label:t.connectionName??\"route\"}),o=a,i=[e[r-1],s])}return i.length\u003e=2\u0026\u0026n.push({points:i,strokeColor:F$(o),strokeWidth:t.traceThickness??Qj,label:t.connectionName??\"route\"}),n},j$=(t,e)=\u003e({title:`HighDensityRepair02 Initial State (margin=${e})`,routes:t}),$=t=\u003e{const e=[];for(const n of t){const t=e[e.length-1];t\u0026\u0026t.z===n.z\u0026\u0026u$(t,n)||e.push(n)}return e},Y$=(t,e,n)=\u003e{const o=Math.max(0,t.minX-e.maxX,e.minX-t.maxX),i=Math.max(0,t.minY-e.maxY,e.minY-t.maxY);return Math.hypot(o,i)\u003c=n+t$},X$=(t,e)=\u003e{let n=Number.POSITIVE_INFINITY;for(const o of t.segments)for(const t of e.segments){if(o.layer!==t.layer)continue;const e=h$(o.start,o.end,t.start,t.end)-(o.thickness+t.thickness)/2;n=Math.min(n,e)}return n},V$=({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,maximumAllowedClearance:o})=\u003e{const i=new WeakMap,r=new WeakMap,s=[],a=Array.from(n).sort((t,e)=\u003et-e),c=t.map((t,e)=\u003ec$(t,e,i)),l=e.map((t,e)=\u003ec$(t,e,r)),d=new Set;for(const t of a)for(let n=0;n\u003ce.length;n+=1){if(n===t)continue;const e=Math.min(t,n),i=Math.max(t,n),r=`${e}:${i}`;if(d.has(r))continue;d.add(r);const a=l[e],h=l[i];if(!a||!h||!Y$(a.bounds,h.bounds,o))continue;const u=X$(a,h);if(!Number.isFinite(u)||u\u003eo+t$||!c[e]||!c[i])continue;const p=X$(c[e],c[i]);!Number.isFinite(p)||u\u003e=p-t$||s.push({routeIndexes:[e,i],previousClearance:p,nextClearance:u})}return s},W$=.001,H$=(t,e)=\u003et.map(t=\u003e{const n=t.route??[];return 0===n.length?t:{...t,route:n.map((t,o)=\u003e0===o||o===n.length-1?((t,e)=\u003e{const n={...t};return Math.abs(n.x-e.minX)\u003c=W$?n.x=e.minX:Math.abs(n.x-e.maxX)\u003c=W$\u0026\u0026(n.x=e.maxX),Math.abs(n.y-e.minY)\u003c=W$?n.y=e.minY:Math.abs(n.y-e.maxY)\u003c=W$\u0026\u0026(n.y=e.maxY),n})(t,e):t)}}),G$=(t,e)=\u003eArray.from(e).flatMap(e=\u003eB$(t[e]).map(t=\u003e({...t,strokeColor:\"#000000\",strokeWidth:t.strokeWidth,label:`candidate:${t.label}`}))),U$=(t,e,n,o,i)=\u003e{const r=\"rgba(0, 0, 0, 0)\";switch(e){case\"left\":return{center:{x:t.minX+n/2,y:t.center.y},width:n,height:t.height,stroke:r,fill:o,label:i};case\"right\":return{center:{x:t.maxX-n/2,y:t.center.y},width:n,height:t.height,stroke:r,fill:o,label:i};case\"top\":return{center:{x:t.center.x,y:t.maxY-n/2},width:t.width,height:n,stroke:r,fill:o,label:i};case\"bottom\":return{center:{x:t.center.x,y:t.minY+n/2},width:t.width,height:n,stroke:r,fill:o,label:i}}},Z$=({routes:t,candidateRoutes:e,candidateRouteIndexes:n,originalRoutes:o,boundary:i,side:r,margin:s,rejected:a,rejectionReason:c})=\u003e{const l=Array.from(n).map(t=\u003ee[t].connectionName??`route-${t}`);return{title:a?`${r} move rejected (${c})`:`${r} move accepted`,routes:a?t:e,originalRoutes:o,activeSide:r,candidateRouteNames:l,overlayLines:a?G$(e,n):[],overlayRects:[U$(i,r,s,a?\"rgba(220, 38, 38, 0.14)\":\"rgba(16, 185, 129, 0.14)\",a?`rejected:${r}`:`accepted:${r}`)]}},q$=(t,e,n,o)=\u003e{const i=(t?.adjacentObstacles??[]).some(t=\u003e((t,e,n,o)=\u003e{const i=(t=\u003et.center\u0026\u0026t.width\u0026\u0026t.height?{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}:null)(t);if(!i)return!1;switch(n){case\"left\":return i.maxX\u003e=e.minX-t$\u0026\u0026i.minX\u003c=e.minX+o+t$;case\"right\":return i.minX\u003c=e.maxX+t$\u0026\u0026i.maxX\u003e=e.maxX-o-t$;case\"top\":return i.minY\u003c=e.maxY+t$\u0026\u0026i.maxY\u003e=e.maxY-o-t$;case\"bottom\":return i.maxY\u003e=e.minY-t$\u0026\u0026i.minY\u003c=e.minY+o+t$}})(t,e,n,o));return{hasObstacle:i,moveAmount:i?o:o/2}},J$=({start:t,end:e,side:n,boundary:o,amount:i,targetAxisValue:r})=\u003e{const s=(({side:t,boundary:e,amount:n,targetAxisValue:o})=\u003e{const i=o??(()=\u003e{switch(t){case\"left\":return e.minX+n;case\"right\":return e.maxX-n;case\"top\":return e.maxY-n;case\"bottom\":return e.minY+n}})();switch(t){case\"left\":case\"right\":return Math.min(Math.max(i,e.minX),e.maxX);case\"top\":case\"bottom\":return Math.min(Math.max(i,e.minY),e.maxY)}})({side:n,boundary:o,amount:i,targetAxisValue:r});switch(n){case\"left\":case\"right\":return $([t,{x:s,y:t.y,z:t.z},{x:s,y:e.y,z:e.z},e]);case\"top\":case\"bottom\":return $([t,{x:t.x,y:s,z:t.z},{x:e.x,y:s,z:e.z},e])}},K$=(t,e,n,o,i,r,s,a=!1)=\u003e{const c=t.route??[];if(c.length\u003c2||0===e.length)return qj(t);const l=a?i:Math.max(i,r),d=((t,e)=\u003e{switch(t){case\"left\":return{x:e,y:0};case\"right\":return{x:-e,y:0};case\"top\":return{x:0,y:-e};case\"bottom\":return{x:0,y:e}}})(o,l);if(a||(t.vias?.length??0)\u003e0||c.length\u003e2){const n=qj(t),o=n.route??[];for(const t of e){const e=o[t];e\u0026\u0026(o[t]={...e,x:e.x+d.x,y:e.y+d.y})}for(const o of n.vias??[]){e.some(e=\u003e{const n=t.route?.[e];return!!n\u0026\u0026u$(n,o)})\u0026\u0026(o.x+=d.x,o.y+=d.y)}return n}const h=qj(t);if(2===c.length\u0026\u00262===e.length\u0026\u00260===e[0]\u0026\u00261===e[1]){const e=c[0],i=c[1];return qj({...t,route:J$({start:e,end:i,side:o,boundary:n,amount:l,targetAxisValue:s})})}return h},Q$=(t,e,n)=\u003e{switch(n){case\"left\":return t.x-e.minX;case\"right\":return e.maxX-t.x;case\"top\":return e.maxY-t.y;case\"bottom\":return t.y-e.minY}},tY=(t,e,n)=\u003e{const o=(t=\u003e{const e=t.route??[];if(0===e.length)return[];const n=[];for(let t=0;t\u003ce.length;t+=1){const o=e[t];if(!o)continue;0===t||t===e.length-1||n.push(o);const i=e[t+1];i\u0026\u0026n.push({x:(o.x+i.x)/2,y:(o.y+i.y)/2})}return n})(t);return 0===o.length?Number.POSITIVE_INFINITY:o.reduce((t,o)=\u003eMath.min(t,Q$(o,e,n)),Number.POSITIVE_INFINITY)},eY=(t,e,n=[])=\u003e{const o=t.route??[],i=[],r=new Set,s=0===e.length||e.includes(\"via\");if(2===o.length)return[0,1];const a=t=\u003e{if(t\u003c=0||t\u003e=o.length-1)return;if(r.has(t))return;const n=o[t];n\u0026\u0026(s||e.includes(s$(n)))\u0026\u0026(r.add(t),i.push(t))};if(n.length\u003e0)for(const t of n)a(t);else for(let t=1;t\u003co.length-1;t+=1)a(t);for(let t=0;t\u003ci.length;t+=1){const e=i[t],n=o[e];if(n)for(let t=1;t\u003co.length-1;t+=1){if(r.has(t))continue;const e=o[t];e\u0026\u0026(e.z!==n.z\u0026\u0026u$(e,n)\u0026\u0026(r.add(t),i.push(t)))}}return i.sort((t,e)=\u003et-e),i},nY=(t,e)=\u003eMath.max(0,...(t.route??[]).map(t=\u003eMath.max(e.minX-t.x,t.x-e.maxX,e.minY-t.y,t.y-e.maxY,0))),oY=(t,e,n,o)=\u003eQ$(t,e,n)\u003c=o+t$,iY=(t,e,n,o)=\u003e{const i=t.route??[],r=[],s=new Set;let a=1,c=i.length-2;for(;a\u003ci.length-1\u0026\u0026u$(i[a],i[0]);)a+=1;for(;c\u003e0\u0026\u0026u$(i[c],i[i.length-1]);)c-=1;for(let t=a;t\u003c=c;t+=1)oY(i[t],e,n,o)\u0026\u0026(s.add(t),r.push(t));for(let t=0;t\u003cr.length;t+=1){const e=i[r[t]];if(e)for(let t=a;t\u003c=c;t+=1){if(s.has(t))continue;const n=i[t];n\u0026\u0026(n.z!==e.z\u0026\u0026u$(n,e)\u0026\u0026(s.add(t),r.push(t)))}}return 0===r.length\u0026\u00262===i.length\u0026\u0026i.some(t=\u003eoY(t,e,n,o))?[0,1]:(r.sort((t,e)=\u003et-e),r)},rY=(t,e,n)=\u003e{const o=t.route??[],i=0===n?o[0]:o[o.length-1];return i?n$.filter(t=\u003eQ$(i,e,t)\u003c=t$):[]},sY=(t,e,n)=\u003e{const o=t.route??[],i=e.route??[];if(0===o.length||0===i.length)return!0;for(const e of[0,-1]){const o=rY(t,n,e);if(0===o.length)continue;const r=0===e?i[0]:i[i.length-1];if(!r)return!1;for(const t of o)if(Q$(r,n,t)\u003et$)return!1}return!0},aY=(t,e)=\u003eMath.hypot(e.x-t.x,e.y-t.y),cY=(t,e,n,o)=\u003e{const i=t.route??[];if(0===i.length)return\"none\";let r=!1;for(let t=0;t\u003ci.length;t+=1){const s=i[t];if(s\u0026\u0026oY(s,e,n,o)){if(0!==t\u0026\u0026t!==i.length-1)return\"interior\";r=!0}}for(let t=0;t\u003ci.length-1;t+=1){const r=i[t],s=i[t+1];if(r\u0026\u0026s\u0026\u0026(oY(r,e,n,o)\u0026\u0026oY(s,e,n,o)\u0026\u0026!(aY(r,s)\u003c=t$)))return\"interior\"}return r?\"endpoint\":\"none\"},lY=({currentRoutes:t,routeIndex:e,side:n,moveSide:o=n,boundary:i,margin:r,moveAmount:s,geometryCache:a})=\u003e{const c=t[e],l=2===(c.route?.length??0),d=iY(c,i,n,r);if(0===d.length)return null;const h=new Set,u=new Map,p=new Set,m=t.slice();let g=!1,f=\"overlap\";const y=new Set([e]),_=new Map([[e,new Set]]),b=new Map([[e,new Set]]),x=[e];let v=0,S=null,I=null,C=null,P=null;const M=t=\u003enew Set(t.map(t=\u003ex$(t))),N=()=\u003eS||(S=T$(t,h,r,a,u),S),w=()=\u003eC||(C=T$(t,h,0,a,u),C),T=()=\u003eP||(P=T$(m,h,0,a,u),P);for(;v\u003cx.length\u0026\u0026!g;){const c=x[v];if(v+=1,y.delete(c),h.has(c))continue;const l=m[c],d=Array.from(_.get(c)??[]),w=Array.from(b.get(c)??[]);_.delete(c),b.delete(c);const T=c===e?iY(l,i,n,r):eY(l,d,w);if(0===T.length){if(c===e)return null;g=!0,f=\"eventual-overlap\";break}const R=l.route??[],E=c===e?void 0:\"left\"===o||\"right\"===o?(R[T[0]]?.x??0)+(\"left\"===o?s:-s):(R[T[0]]?.y??0)+(\"top\"===o?-s:s);m[c]=K$(l,T,i,o,s,r,E,c!==e),h.add(c),u.set(c,new Set(T)),S=null,I=null,C=null,P=null,2===(l.route?.length??0)\u0026\u0026p.add(c);const A=nY(t[c],i);if(nY(m[c],i)\u003eA+1e-6){g=!0,f=\"boundary\";break}if(!sY(t[c],m[c],i)){g=!0,f=\"endpoint-boundary\";break}const O=T$(m,new Set([c]),r,a,new Map([[c,new Set(T)]]));for(const t of O){if(M(N()).has(x$(t)))continue;const[e,n]=t.routeIndexes,o=h.has(e),i=h.has(n);if(o\u0026\u0026i)continue;const r=o?n:e,s=o?t.layers[1]:t.layers[0],a=o?t.routePointIndexes[1]:t.routePointIndexes[0];if(h.has(r)||y.has(r)){if(y.has(r)){const t=_.get(r)??new Set;t.add(s),_.set(r,t);const e=b.get(r)??new Set;for(const t of a)e.add(t);b.set(r,e)}}else y.add(r),x.push(r),_.set(r,new Set([s])),b.set(r,new Set(a))}}if(!g\u0026\u0026h.size\u003e1){const t=M(N()),e=M(I||(I=T$(m,h,r,a,u),I));for(const n of e)if(!t.has(n)){g=!0,f=\"eventual-overlap\";break}}if(!g\u0026\u0026h.size\u003e1){const t=M(w()),e=M(T());for(const n of e)if(!t.has(n)){g=!0,f=\"eventual-overlap\";break}}if(!g){const e=new Set(T$(t,h,0,a).map(t=\u003ex$(t))),n=T$(m,h,0,a);for(const t of n){const n=x$(t);if(!e.has(n)){g=!0,f=\"eventual-overlap\";break}}}if(!g){const e=(({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,boundary:o,activeSide:i})=\u003e{const r=n$.filter(t=\u003et!==i),s=[];for(const i of n){const n=t[i],a=e[i];if(n\u0026\u0026a)for(const t of r){const e=tY(n,o,t),r=tY(a,o,t);e\u003et$\u0026\u0026r\u003c=t$\u0026\u0026s.push({routeIndex:i,side:t,previousClearance:e,nextClearance:r})}}return s})({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,boundary:i,activeSide:n});e.length\u003e0\u0026\u0026(g=!0,f=\"boundary-touch\")}if(!g){const e=(({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,geometryCache:o,currentConflicts:i,candidateConflicts:r})=\u003e{const s=i??T$(t,n,0,o),a=r??T$(e,n,0,o),c=new Set(s.map(t=\u003ex$(t)));return a.filter(t=\u003e{const o=x$(t);if(c.has(o))return!1;const[i,r]=t.routeIndexes,[s,a]=t.layers,l=n.has(i),d=n.has(r);if(l\u0026\u0026d)return!1;const h=l?a:s,u=e[l?r:i];return!!u\u0026\u00260===eY(u,[h]).length})})({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,geometryCache:a,currentConflicts:w(),candidateConflicts:T()});e.length\u003e0\u0026\u0026(g=!0,f=\"fixed-trace-touch\")}if(!g){V$({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,maximumAllowedClearance:Math.min(r/2,e$)}).length\u003e0\u0026\u0026(g=!0,f=\"trace-clearance\")}return!g\u0026\u0026((t,e,n,o,i,r)=\u003eArray.from(n).some(n=\u003e{const s=t[n],a=e[n];return n$.filter(t=\u003et!==i).some(t=\u003e{const e=cY(s,o,t,r),n=cY(a,o,t,r);return\"none\"===e\u0026\u0026\"none\"!==n})}))(t,m,h,i,n,r)\u0026\u0026(g=!0,f=\"side-regression\"),{isTwoPointRoute:l,movableIndexes:d,candidateRouteIndexes:h,movedTwoPointRouteIndexes:p,candidateRoutes:m,rejected:g,rejectionReason:f}},dY=(t,e,n,o,i)=\u003e{const r=t.route??[];if(0===e.length)return null;if(\"top\"===o||\"bottom\"===o){const t=e.reduce((t,e)=\u003et+(r[e]?.x??n.center.x),0)/e.length;return t\u003cn.center.x-i/2?\"right\":t\u003en.center.x+i/2?\"left\":null}const s=e.reduce((t,e)=\u003et+(r[e]?.y??n.center.y),0)/e.length;return s\u003en.center.y+i/2?\"bottom\":s\u003cn.center.y-i/2?\"top\":null},hY=({side:t,sample:e,boundary:n,margin:o,repairedRoutes:i,frames:r,captureProgressFrames:s,lockedTwoPointRoutes:a,geometryCache:c,allowTwoPointWithoutObstacle:l=!1})=\u003e{const{hasObstacle:d,moveAmount:h}=q$(e,n,t,o);s\u0026\u0026r.push(((t,e,n,o,i,r)=\u003e({title:`${n} boundary analysis: move=${i.toFixed(3)} (${r?\"obstacle-side\":\"clear-side\"})`,routes:t,activeSide:n,overlayRects:[U$(e,n,o,\"rgba(245, 158, 11, 0.16)\",`strip:${n}`)]}))(Jj(i),n,t,o,h,d));const u=new Set;let p=0;for(let e=0;e\u003ci.length;e+=1){if(u.has(e))continue;if(a.has(e))continue;const m=i[e];if(m.connectedPadSides?.includes(t))continue;if(2===(m.route?.length??0)\u0026\u0026!d\u0026\u0026!l)continue;let g=lY({currentRoutes:i,routeIndex:e,side:t,boundary:n,margin:o,moveAmount:h,geometryCache:c});if(g){if(g.rejected){const r=dY(m,g.movableIndexes,n,t,o);if(r){const s=lY({currentRoutes:i,routeIndex:e,side:t,moveSide:r,boundary:n,margin:o,moveAmount:h,geometryCache:c});s\u0026\u0026!s.rejected\u0026\u0026(g=s)}}if(s\u0026\u0026r.push(Z$({routes:Jj(i),candidateRoutes:g.candidateRoutes,candidateRouteIndexes:g.candidateRouteIndexes,originalRoutes:g.rejected?void 0:Array.from(g.candidateRouteIndexes).map(t=\u003eqj(i[t])),boundary:n,side:t,margin:o,rejected:g.rejected,rejectionReason:g.rejectionReason})),!g.rejected){i.splice(0,i.length,...g.candidateRoutes);for(const t of g.movedTwoPointRouteIndexes)a.add(t);p+=1}u.add(e)}}return{movesAccepted:p}},uY=(t,e,n,o)=\u003eoY(t,e,n,o),pY=(t,e,n,o)=\u003e{switch(n){case\"left\":return{...t,x:Math.min(e.minX+o,e.maxX)};case\"right\":return{...t,x:Math.max(e.maxX-o,e.minX)};case\"top\":return{...t,y:Math.max(e.maxY-o,e.minY)};case\"bottom\":return{...t,y:Math.min(e.minY+o,e.maxY)}}},mY=t=\u003e`${t.routeIndexes[0]}:${t.layers[0]}:${t.routeIndexes[1]}:${t.layers[1]}`,gY=t=\u003e{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))},fY=(t,e)=\u003e{const n=gY(t),o=gY(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))},yY=(t,e,n)=\u003et?D$([t],e,n).length:0,_Y=(t,e,n,o)=\u003e{const i=new Set(T$(t,new Set([n]),o).map(x$));return T$(e,new Set([n]),o).some(t=\u003e!i.has(x$(t)))},bY=(t,e,n)=\u003eD$(t,e,n).length,xY=t=\u003e{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))},vY=(t,e)=\u003eT$(t,new Set(t.map((t,e)=\u003ee)),e$,e).filter(e=\u003e!(\"via\"===e.layers[0]\u0026\u0026\"via\"===e.layers[1]||((t,e)=\u003e{const n=xY(t),o=xY(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))})(t[e.routeIndexes[0]],t[e.routeIndexes[1]]))).length,SY=t=\u003e{const e=n$;return[...e.slice(t%e.length),...e.slice(0,t%e.length)]},IY=(t,e,n=!1)=\u003e{const o=z$(t?.nodeWithPortPoints),i=o?((t,e)=\u003et.map(t=\u003e{const n=t.route??[];let o=!1;const i=n.map(t=\u003e{let n=t.x,i=t.y;return n\u003ce.minX?n=e.minX:n\u003ee.maxX\u0026\u0026(n=e.maxX),i\u003ce.minY?i=e.minY:i\u003ee.maxY\u0026\u0026(i=e.maxY),n===t.x\u0026\u0026i===t.y?t:(o=!0,{...t,x:n,y:i})});return o?{...t,route:i}:t}))(H$(Jj(t?.nodeHdRoutes??[]),o),o):Jj(t?.nodeHdRoutes??[]),r=Math.max(e??.4,.05),s=Jj(i);if(!o)return{boundary:null,baseRoutes:i,repairedRoutes:s,margin:r,frames:[{title:\"HighDensityRepair02 Missing Boundary\",routes:s}]};const a=n?[j$(Jj(s),r)]:[],c=new WeakMap;let l=bY(s,o,r);for(let e=0;e\u003c1;e+=1){const i=new Set;let d=0;for(const l of SY(e)){const{movesAccepted:h}=hY({side:l,sample:t,boundary:o,frames:a,margin:r,repairedRoutes:s,captureProgressFrames:n,lockedTwoPointRoutes:i,geometryCache:c,allowTwoPointWithoutObstacle:e\u003e=1});d+=h}const h=bY(s,o,r);if(0===d)break;if(0===h)break;if(h\u003e=l)break;l=h}const d=Jj(s),h=vY(s,c);(({routes:t,boundary:e,margin:n,geometryCache:o})=\u003e{const i=D$(t,e,n);if(0===i.length)return{movesAccepted:0};const r=new Map;for(const t of i){const e=r.get(t.routeIndex)??new Set;for(const n of t.touchedSides)e.add(n);r.set(t.routeIndex,e)}const s=[8e-6,.01,n/4,n/2,n+8e-6];let a=0;const c=(i,r,s)=\u003e{const a=r.route??[];if(a.length\u003c2)return!1;const c={...r,route:$(a)};if((c.route?.length??0)\u003c2)return!1;const l=t.slice();if(l[i]=c,yY(l[i],e,n)\u003e=s)return!1;const d=e=\u003efY(t[e.routeIndexes[0]],t[e.routeIndexes[1]]),h=new Set(T$(t,new Set([i]),0,o).filter(t=\u003e!d(t)).map(mY));return!T$(l,new Set([i]),0,o).filter(t=\u003e!d(t)).some(t=\u003e!h.has(mY(t)))\u0026\u0026!(V$({currentRoutes:t,candidateRoutes:l,candidateRouteIndexes:new Set([i]),maximumAllowedClearance:Math.min(n/2,e$)}).filter(e=\u003e!fY(t[e.routeIndexes[0]],t[e.routeIndexes[1]])).length\u003e0||(t[i]=c,0))},l=(n,o,i,r)=\u003e{if(0===o.length)return!1;for(const a of s){const s=t[n],l=qj(s),d=l.route??[];let h=!1;for(const t of o){const n=d[t];n\u0026\u0026(d[t]=pY(n,e,i,a),h=!0)}if(!h)return!1;if(c(n,l,r))return!0}return!1},d=(t,n)=\u003e{const o=[];return\"top\"===n||\"bottom\"===n?(Math.abs(t.x-e.minX)\u003c=t$\u0026\u0026o.push(\"left\"),Math.abs(t.x-e.maxX)\u003c=t$\u0026\u0026o.push(\"right\")):(Math.abs(t.y-e.minY)\u003c=t$\u0026\u0026o.push(\"bottom\"),Math.abs(t.y-e.maxY)\u003c=t$\u0026\u0026o.push(\"top\")),o},h=(o,i,r)=\u003e{const a=t[o],l=a.route??[];if(2!==l.length)return!1;const[h,u]=l;if(!uY(h,e,i,n))return!1;if(!uY(u,e,i,n))return!1;const p=d(h,i),m=d(u,i);for(const t of s){let n=pY(h,e,i,t),s=pY(u,e,i,t);for(const o of p)n=pY(n,e,o,t);for(const n of m)s=pY(s,e,n,t);const l={...a,route:[h,n,s,u]};if(c(o,l,r))return!0}return!1};for(const[o,i]of r)if(t[o])for(const r of i){let i=!0;for(;i;){i=!1;const s=t[o].route??[];if(2===s.length){const i=yY(t[o],e,n);i\u003e0\u0026\u0026h(o,r,i)\u0026\u0026(a+=1);break}if(s.length\u003c3)break;const c=yY(t[o],e,n);if(0===c)break;const d=[];for(let t=1;t\u003cs.length-1;t+=1){const o=s[t];o\u0026\u0026uY(o,e,r,n)\u0026\u0026d.push(t)}if(0===d.length)break;if(l(o,d,r,c)){a+=1,i=!0;continue}let u=!1,p=c,m=0;for(;m\u003cd.length;){let i=m;for(;i+1\u003cd.length\u0026\u0026d[i+1]===d[i]+1;)i+=1;l(o,d.slice(m,i+1),r,p)\u0026\u0026(a+=1,u=!0,p=yY(t[o],e,n)),m=i+1}if(!u){const i=t[o].route??[];let s=c;for(let c=1;c\u003ci.length-1;c+=1){const d=i[c];d\u0026\u0026uY(d,e,r,n)\u0026\u0026l(o,[c],r,s)\u0026\u0026(a+=1,u=!0,s=yY(t[o],e,n))}}u\u0026\u0026(i=!0)}}for(const[o,i]of r){const r=t[o];if(!r)continue;const s=r.route??[];if(s.length\u003c=2)continue;const c=yY(t[o],e,n);if(0!==c)for(const l of i){if(!s.every(t=\u003euY(t,e,l,n)))continue;const i=s[0]?.z;if(!s.every(t=\u003et.z===i))continue;const d={...r,route:[s[0],s[s.length-1]]},u=t[o];t[o]=d,h(o,l,c)?a+=1:t[o]=u;break}}})({routes:d,boundary:o,margin:r,geometryCache:c});return vY(d,c)\u003c=h\u0026\u0026s.splice(0,s.length,...d),(({routes:t,boundary:e,clearanceMargin:n})=\u003e{for(let o=0;o\u003ct.length;o+=1){const i=t[o];if((i.route??[]).length\u003c=2)continue;const r=n,s=Math.max(e.width/2-t$,0),a=Math.max(e.height/2-t$,0),c=Math.min(r,s),l=Math.min(r,a),d=i.connectedPadSides??[],h=e.minX+(d.includes(\"left\")?0:c),u=e.maxX-(d.includes(\"right\")?0:c),p=e.minY+(d.includes(\"bottom\")?0:l),m=e.maxY-(d.includes(\"top\")?0:l),g=qj(i),f=g.route??[];let y=!1;for(let t=1;t\u003cf.length-1;t+=1){const e=f[t];if(!e)continue;const n=Math.min(Math.max(e.x,h),u),o=Math.min(Math.max(e.y,p),m);(Math.abs(n-e.x)\u003et$||Math.abs(o-e.y)\u003et$)\u0026\u0026(e.x=n,e.y=o,y=!0)}if(!y)continue;if(g.route=$(f),(g.route?.length??0)\u003c2)continue;const _=Jj(t);_[o]=g;const b=_Y(t,_,o,0),x=_Y(t,_,o,n),v=V$({currentRoutes:t,candidateRoutes:_,candidateRouteIndexes:new Set([o]),maximumAllowedClearance:n}).length\u003e0;b||x||v||(t[o]=g)}})({routes:s,boundary:o,clearanceMargin:r}),a.push(((t,e,n)=\u003e({title:`HighDensityRepair02 Final State (margin=${n})`,routes:t,originalRoutes:e}))(Jj(s),Jj(i),r)),{boundary:o,baseRoutes:i,repairedRoutes:s,frames:a,margin:r}},CY=class extends kt{constructor(t={}){super(),this.params=t,this.showBoundryViolationMarkers=t.showBoundryViolationMarkers??!1}params;frames=[];currentFrameIndex=0;showBoundryViolationMarkers;repairedRoutes=[];_setup(){this.buildFrames();const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();this.stats={boundryViolationCount:t,traceViolationCount:e,margin:this.params.margin??.4,frames:this.frames.length,currentFrame:this.currentFrameIndex}}_step(){if(this.frames.length\u003c=1){const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();return this.showBoundryViolationMarkers=!0,this.stats={...this.stats,boundryViolationCount:t,traceViolationCount:e},void(this.solved=!0)}this.currentFrameIndex\u003cthis.frames.length-1\u0026\u0026(this.currentFrameIndex+=1);const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();this.stats={boundryViolationCount:t,traceViolationCount:e,margin:this.params.margin??.4,frames:this.frames.length,currentFrame:this.currentFrameIndex,title:this.frames[this.currentFrameIndex]?.title},this.currentFrameIndex\u003e=this.frames.length-1\u0026\u0026(this.showBoundryViolationMarkers=!0,this.solved=!0)}getConstructorParams(){return[this.params]}getOutput(){const t=this.getCurrentTraceViolationCount();return{margin:this.params.margin??.4,repairedRoutes:this.repairedRoutes,frameCount:this.frames.length,traceViolationCount:t}}setShowBoundryViolationMarkers(t){this.showBoundryViolationMarkers=t}buildFrames(){const t=IY(this.params.sample,this.params.margin,this.params.captureProgressFrames??!1);this.frames=t.frames,this.repairedRoutes=t.repairedRoutes}getCurrentFrame(){const t=this.params.sample;return this.frames[this.currentFrameIndex]??{title:\"HighDensityRepair02\",routes:Jj(t?.nodeHdRoutes??[])}}getBoundryViolationsForFrame(t){const e=z$(this.params.sample?.nodeWithPortPoints);return e?D$(t.routes,e,this.params.margin??.4):[]}getCurrentBoundryViolationCount(){return this.getBoundryViolationsForFrame(this.getCurrentFrame()).length}getRouteNetNames(t){if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=\u003eBoolean(t));return Array.from(new Set(e))}areRoutesSameNet(t,e){const n=this.getRouteNetNames(t),o=this.getRouteNetNames(e);return 0!==n.length\u0026\u00260!==o.length\u0026\u0026n.some(t=\u003eo.includes(t))}getCurrentTraceViolationCount(){const t=this.getCurrentFrame().routes,e=new Set(t.map((t,e)=\u003ee));return T$(t,e,e$).filter(e=\u003e!(\"via\"===e.layers[0]\u0026\u0026\"via\"===e.layers[1]||this.areRoutesSameNet(t[e.routeIndexes[0]],t[e.routeIndexes[1]]))).length}visualize(){const t=this.params.sample,e=t?.nodeWithPortPoints,n=t?.adjacentObstacles??[],o=this.getCurrentFrame(),i=z$(e),r=i\u0026\u0026e?.capacityMeshNodeId?[{center:i.center,width:i.width,height:i.height,stroke:\"#1d4ed8\",fill:\"rgba(29, 78, 216, 0.08)\",label:e.capacityMeshNodeId}]:i?[{center:i.center,width:i.width,height:i.height,stroke:\"#1d4ed8\",fill:\"rgba(29, 78, 216, 0.08)\",label:\"capacity-node\"}]:[],s=n.filter(t=\u003et.center\u0026\u0026t.width\u0026\u0026t.height).map((t,e)=\u003e({center:t.center,width:t.width,height:t.height,stroke:\"oval\"===t.type?\"#a855f7\":\"#dc2626\",fill:\"oval\"===t.type?\"rgba(168, 85, 247, 0.12)\":\"rgba(220, 38, 38, 0.08)\",label:t.type?`obstacle:${t.type}:${e}`:`obstacle:${e}`})),a=this.showBoundryViolationMarkers\u0026\u0026i?this.getBoundryViolationsForFrame(o).map(t=\u003e{const e=t.end.x-t.start.x,n=t.end.y-t.start.y,o=Math.max(Math.hypot(e,n),.2),i=Math.abs(e)\u003e=Math.abs(n);return{center:{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2},width:i?o:.18,height:i?.18:o,stroke:\"#b45309\",fill:\"rgba(250, 204, 21, 0.45)\",label:`boundry-violation:${t.routeIndex}:${t.segmentIndex}`}}):[];const c=this.showBoundryViolationMarkers?b$(o.routes,e$):[],l=[...(e?.portPoints??[]).map(t=\u003e({x:t.x,y:t.y,color:\"#0f766e\",label:t.connectionName??t.portPointId??\"port-point\"})),...o.routes.flatMap(t=\u003et.route??[]).map(t=\u003e({x:t.x,y:t.y,color:\"bottom\"===s$(t)?Kj:\"#0ea5e9\",label:\"\"})),...o.overlayPoints??[]],d=[...(o.originalRoutes??[]).flatMap(t=\u003eB$(t).map(t=\u003e({...t,strokeColor:\"#111111\",strokeWidth:Math.max(.6*t.strokeWidth,.05),label:`original:${t.label}`}))),...o.routes.filter(t=\u003e(t.route?.length??0)\u003e=2).flatMap(t=\u003eB$(t)),...o.overlayLines??[]],h=o.routes.flatMap(t=\u003e(t.vias??[]).map(e=\u003e({center:{x:e.x,y:e.y},radius:(e.diameter??t.viaDiameter??.3)/2,stroke:\"#7c3aed\",fill:\"rgba(124, 58, 237, 0.2)\",label:t.connectionName?`via:${t.connectionName}`:\"via\"})));return h.push(...c),{coordinateSystem:\"cartesian\",title:o.title,rects:[...r,...s,...o.overlayRects??[],...a],points:l,lines:d,circles:h,arrows:o.overlayArrows}}},PY=(t,e,n,o)=\u003e{const i=.001,r=new Set;for(const s of[e.route[0],e.route.at(-1)]){if(!s)continue;n.some(t=\u003et.__zLayers.includes(s.z)\u0026\u0026fo(t,e,o)\u0026\u0026Math.abs(s.x-t.center.x)\u003c=t.width/2+i\u0026\u0026Math.abs(s.y-t.center.y)\u003c=t.height/2+i)\u0026\u0026(Math.abs(s.x-(t.center.x-t.width/2))\u003c=i\u0026\u0026r.add(\"left\"),Math.abs(s.x-(t.center.x+t.width/2))\u003c=i\u0026\u0026r.add(\"right\"),Math.abs(s.y-(t.center.y-t.height/2))\u003c=i\u0026\u0026r.add(\"bottom\"),Math.abs(s.y-(t.center.y+t.height/2))\u003c=i\u0026\u0026r.add(\"top\"))}return[...r]},MY=(t,e=0)=\u003e({minX:t.center.x-t.width/2-e,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2-e,maxY:t.center.y+t.height/2+e}),NY=(t,e,n=0)=\u003e{const o=MY(e,n);return t.x\u003e=o.minX\u0026\u0026t.x\u003c=o.maxX\u0026\u0026t.y\u003e=o.minY\u0026\u0026t.y\u003c=o.maxY},wY=(t,e,n)=\u003et.route.length\u003e0\u0026\u0026e.some(e=\u003e(t=\u003e(t.__zLayers?.length??t.layers?.length??0)\u003e1)(e)\u0026\u0026fo(e,t,n)\u0026\u0026t.route.every(t=\u003e((t,e)=\u003e{const n=e.width/2,o=e.height/2;return Math.abs(t.x-e.center.x)\u003c=n\u0026\u0026Math.abs(t.y-e.center.y)\u003c=o})(t,e))),TY=(t,e,n)=\u003e{if(t.regionId){const n=e.findIndex(e=\u003ee.capacityMeshNodeId===t.regionId);if(-1!==n)return n}const o=[...t.route.map(({x:t,y:e})=\u003e({x:t,y:e})),...t.vias.map(({x:t,y:e})=\u003e({x:t,y:e}))];for(let t=0;t\u003ce.length;t++){const i=e[t];if(o.every(t=\u003eNY(t,i,n)))return t}return-1},RY=(t,e)=\u003e({connectionName:t.connectionName??e.connectionName,rootConnectionName:t.rootConnectionName??e.rootConnectionName,...e.startPcbPortId?{startPcbPortId:e.startPcbPortId}:{},...e.endPcbPortId?{endPcbPortId:e.endPcbPortId}:{},regionId:t.capacityMeshNodeId??e.regionId,traceThickness:t.traceThickness??e.traceThickness,viaDiameter:t.viaDiameter??e.viaDiameter,route:t.route?.map(t=\u003e({x:t.x,y:t.y,z:t.z??0}))??e.route,vias:t.vias?.map(t=\u003e({x:t.x,y:t.y}))??e.vias,jumpers:e.jumpers}),EY=(t,e,n,o,i)=\u003e{const r=MY(t,n);return e.search(r).filter(t=\u003e{return e=r,n=(t=\u003e({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}))(t),e.minX\u003c=n.maxX\u0026\u0026e.maxX\u003e=n.minX\u0026\u0026e.minY\u003c=n.maxY\u0026\u0026e.maxY\u003e=n.minY;var e,n}).filter(t=\u003e!i||!o.some(e=\u003efo(t,e,i))).map(t=\u003e({type:t.type,center:t.center,width:t.width,height:t.height}))},AY=class extends si{repairMargin;sampleEntries;originalHdRoutes;originalNodeWithPortPoints;originalObstacles;obstacleSHI;colorMap;connMap;repairedRoutesByIndex=new Map;activeSampleIndex=0;activeSubSolver=null;latestVisualization={};constructor(t){super(),this.repairMargin=t.repairMargin??.2,this.originalHdRoutes=t.hdRoutes,this.originalNodeWithPortPoints=t.nodeWithPortPoints,this.originalObstacles=t.obstacles,this.obstacleSHI=new Na(\"flatbush\",this.originalObstacles),this.colorMap=t.colorMap??{},this.connMap=t.connMap;const e=new Map;for(let n=0;n\u003ct.hdRoutes.length;n++){if(wY(t.hdRoutes[n],t.obstacles,t.connMap))continue;const o=TY(t.hdRoutes[n],t.nodeWithPortPoints,this.repairMargin);if(-1===o)continue;const i=e.get(o)??[];i.push(n),e.set(o,i)}const n=Kr(t.obstacles,Math.max(2,...t.nodeWithPortPoints.flatMap(t=\u003et.availableZ?.map(t=\u003et+1)??[]))),o=Array.from(e.entries()).map(([e,o])=\u003e{const i=t.nodeWithPortPoints[e];return{node:i,routeIndexes:o,sample:{nodeWithPortPoints:{capacityMeshNodeId:i.capacityMeshNodeId,center:i.center,width:i.width,height:i.height,portPoints:i.portPoints.map(t=\u003e({x:t.x,y:t.y,z:t.z,connectionName:t.connectionName,portPointId:t.portPointId,prevPortPointId:t.prevPortPointId,nextPortPointId:t.nextPortPointId}))},nodeHdRoutes:o.map(e=\u003e{return{...(o=t.hdRoutes[e],{capacityMeshNodeId:o.regionId,connectionName:o.connectionName,rootConnectionName:o.rootConnectionName,route:o.route.map(t=\u003e({x:t.x,y:t.y,z:t.z})),traceThickness:o.traceThickness,vias:o.vias.map(t=\u003e({x:t.x,y:t.y,diameter:o.viaDiameter})),viaDiameter:o.viaDiameter}),...t.connMap?{connectedPadSides:PY(i,t.hdRoutes[e],n,t.connMap)}:{}};var o}),adjacentObstacles:EY(i,this.obstacleSHI,this.repairMargin,o.map(e=\u003et.hdRoutes[e]),t.connMap)}}});this.sampleEntries=void 0!==t.maxSampleEntries\u0026\u0026o.length\u003et.maxSampleEntries?[]:o,this.MAX_ITERATIONS=Math.max(1e3*this.sampleEntries.length,1e5),this.stats={sampleCount:this.sampleEntries.length,skippedSampleCount:o.length\u003ethis.sampleEntries.length?o.length:0,repairedNodeCount:0,repairedRouteCount:0}}getSolverName(){return\"Pipeline4HighDensityRepairSolver\"}getConstructorParams(){return[{nodeWithPortPoints:this.sampleEntries.map(t=\u003et.node),hdRoutes:this.originalHdRoutes,obstacles:this.originalObstacles,repairMargin:this.repairMargin,colorMap:this.colorMap,connMap:this.connMap}]}_step(){const t=this.sampleEntries[this.activeSampleIndex];if(t){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.latestVisualization=this.activeSubSolver.visualize(),this.activeSubSolver.failed)return this.failed=!0,this.error=this.activeSubSolver.error??`High density repair failed for node ${t.node.capacityMeshNodeId}`,void(this.activeSubSolver=null);if(!this.activeSubSolver.solved)return;const e=this.activeSubSolver.getOutput().repairedRoutes;for(let n=0;n\u003ct.routeIndexes.length;n++){const o=t.routeIndexes[n],i=this.originalHdRoutes[o],r=e[n];this.repairedRoutesByIndex.set(o,r?RY(r,i):i)}return this.activeSubSolver=null,this.activeSampleIndex+=1,this.stats={sampleCount:this.sampleEntries.length,repairedNodeCount:this.activeSampleIndex,repairedRouteCount:this.repairedRoutesByIndex.size},void(this.activeSampleIndex\u003e=this.sampleEntries.length\u0026\u0026(this.solved=!0))}this.activeSubSolver=new CY({sample:t.sample,margin:this.repairMargin}),this.latestVisualization=this.activeSubSolver.visualize()}else this.solved=!0}getOutput(){return this.originalHdRoutes.map((t,e)=\u003ethis.repairedRoutesByIndex.get(e)??t)}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();if(!this.solved)return this.latestVisualization;const t=[],e=[];for(const n of this.getOutput()){const o=this.colorMap[n.connectionName]??\"#0ea5e9\";for(let e=0;e\u003cn.route.length-1;e++){const i=n.route[e],r=n.route[e+1];i.z===r.z\u0026\u0026t.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:0===i.z?o:To(o,.5),strokeWidth:n.traceThickness,layer:`z${i.z}`,strokeDash:0!==i.z?[.1,.3]:void 0})}for(const t of n.vias)e.push({center:{x:t.x,y:t.y},radius:n.viaDiameter/2,stroke:o,fill:\"rgba(14,165,233,0.12)\"})}return{title:\"Pipeline4 High Density Repair\",lines:t,circles:e}}},OY=1e-6,kY=({startGap:t,endGap:e,segmentGap:n,requiredGap:o})=\u003e{const i=t\u003co\u0026\u0026e\u003e=o-OY\u0026\u0026n\u003e=t-OY,r=e\u003co\u0026\u0026t\u003e=o-OY\u0026\u0026n\u003e=e-OY,s=t\u003co\u0026\u0026e\u003co\u0026\u0026n\u003e=Math.min(t,e)-OY;return i||r||s},LY=class{minClearance;rootsByConnection=new Map;sameNetCache=new Map;segments=[];vias=[];segmentIndexesByLayer;viaIndex;constructor({hdRoutes:t,minClearance:e=.1}){this.minClearance=e;for(const e of t)this.addRoute(e);this.buildSpatialIndexes()}addRoute(t){const e=this.rootsByConnection.get(t.connectionName)??new Set;e.add(t.rootConnectionName??t.connectionName),this.rootsByConnection.set(t.connectionName,e),this.sameNetCache.clear();for(let e=0;e\u003ct.route.length-1;e+=1){const n=t.route[e],o=t.route[e+1];if(n.z!==o.z)continue;if(n.insideJumperPad\u0026\u0026o.insideJumperPad)continue;const i={connectionName:t.connectionName,start:n,end:o,traceThickness:t.traceThickness};this.segments.push(i),this.insertSegmentIntoSpatialIndex(i)}for(const e of t.vias){const n={connectionName:t.connectionName,x:e.x,y:e.y,diameter:t.viaDiameter};this.vias.push(n),this.insertViaIntoSpatialIndex(n)}}insertSegmentIntoSpatialIndex(t){if(!this.segmentIndexesByLayer)return;let e=this.segmentIndexesByLayer.get(t.start.z);e||(e=new Pa,this.segmentIndexesByLayer.set(t.start.z,e));const n=t.traceThickness/2;e.insert(t,Math.min(t.start.x,t.end.x)-n,Math.min(t.start.y,t.end.y)-n,Math.max(t.start.x,t.end.x)+n,Math.max(t.start.y,t.end.y)+n)}insertViaIntoSpatialIndex(t){if(!this.viaIndex)return;const e=t.diameter/2;this.viaIndex.insert(t,t.x-e,t.y-e,t.x+e,t.y+e)}buildSpatialIndexes(){this.segmentIndexesByLayer=new Map;const t=new Map;for(const e of this.segments){const n=t.get(e.start.z);n?n.push(e):t.set(e.start.z,[e])}for(const[e,n]of t){const t=new Pa;t.bulkLoad(n.map(t=\u003e{const e=t.traceThickness/2;return{item:t,minX:Math.min(t.start.x,t.end.x)-e,minY:Math.min(t.start.y,t.end.y)-e,maxX:Math.max(t.start.x,t.end.x)+e,maxY:Math.max(t.start.y,t.end.y)+e}})),this.segmentIndexesByLayer.set(e,t)}this.viaIndex=new Pa,this.viaIndex.bulkLoad(this.vias.map(t=\u003e{const e=t.diameter/2;return{item:t,minX:t.x-e,minY:t.y-e,maxX:t.x+e,maxY:t.y+e}}))}areSameNet(t,e){if(t===e)return!0;const n=this.sameNetCache.get(t)?.get(e);if(void 0!==n)return n;const o=this.rootsByConnection.get(t),i=this.rootsByConnection.get(e);let r=!1;if(o\u0026\u0026i)for(const t of o)if(i.has(t)){r=!0;break}let s=this.sameNetCache.get(t);return s||(s=new Map,this.sameNetCache.set(t,s)),s.set(e,r),r}isSegmentClear({connectionName:t,start:e,end:n,traceThickness:o}){const i=o/2,r=this.minClearance+i,s=Math.min(e.x,n.x)-r,a=Math.min(e.y,n.y)-r,c=Math.max(e.x,n.x)+r,l=Math.max(e.y,n.y)+r,d=this.segmentIndexesByLayer?.get(e.z)?.search(s,a,c,l)??[];for(const o of d){if(this.areSameNet(t,o.connectionName))continue;const r=this.minClearance+i+o.traceThickness/2,s=Ra(e,n,o.start,o.end);if(s\u003cr\u0026\u0026!kY({startGap:be(e,o.start,o.end),endGap:be(n,o.start,o.end),segmentGap:s,requiredGap:r}))return!1}const h=this.viaIndex?.search(s,a,c,l)??[];for(const o of h){if(this.areSameNet(t,o.connectionName))continue;const r=this.minClearance+i+o.diameter/2,s=be(o,e,n);if(s\u003cr\u0026\u0026!kY({startGap:Math.hypot(e.x-o.x,e.y-o.y),endGap:Math.hypot(n.x-o.x,n.y-o.y),segmentGap:s,requiredGap:r}))return!1}return!0}},DY=1e-9,zY=1.25,FY=(t,e)=\u003et\u003ce?-1:t\u003ee?1:0,BY=(t,e)=\u003eFY(t.z,e.z)||FY(t.x,e.x)||FY(t.y,e.y),jY=t=\u003e`${t.z.toFixed(6)}:${t.x.toFixed(6)}:${t.y.toFixed(6)}`,$Y=t=\u003e{const e=t.route.map(jY).join(\"|\"),n=[...t.route].reverse().map(jY).join(\"|\");return e\u003c=n?e:n},YY=(t,e)=\u003e{const n=t.connectionName.localeCompare(e.connectionName);if(0!==n)return n;const o=(t.rootConnectionName??\"\").localeCompare(e.rootConnectionName??\"\");if(0!==o)return o;const i=$Y(t).localeCompare($Y(e));return 0!==i?i:FY(t.traceThickness,e.traceThickness)||FY(t.viaDiameter,e.viaDiameter)||FY(t.route.length,e.route.length)||FY(t.vias.length,e.vias.length)||FY(t.jumpers?.length??0,e.jumpers?.length??0)},XY=1e5,VY=.001,WY=1.000000001,HY=class extends si{getSolverName(){return\"SingleHighDensityRouteStitchSolver3\"}mergedHdRoute;remainingHdRoutes;start;end;colorMap;allowedLayerTransitionPointKeys;isStitchSegmentClear;stitchClearanceMode;isPlanarStitchClear(t,e){return this.isStitchSegmentClear({connectionName:this.mergedHdRoute.connectionName,start:t,end:e,traceThickness:this.mergedHdRoute.traceThickness})}constructor(t){super();const e=[...t.hdRoutes].sort(YY);if(this.remainingHdRoutes=e,this.colorMap=t.colorMap??{},this.allowedLayerTransitionPointKeys=t.allowedLayerTransitionPointKeys,this.isStitchSegmentClear=t.isStitchSegmentClear,this.stitchClearanceMode=t.stitchClearanceMode,0===e.length){this.start=t.start,this.end=t.end;const n=t.defaultTraceThickness??.15,o=[{x:t.start.x,y:t.start.y,z:t.start.z}],i=[];if(t.start.z!==t.end.z){if(t.allowedLayerTransitionPointKeys\u0026\u0026!t.allowedLayerTransitionPointKeys.has(af(t.start)))return this.failed=!0,void(this.error=`Layer transition at ${af(t.start)} is not allowed`);o.push({x:t.start.x,y:t.start.y,z:t.end.z}),i.push({x:t.start.x,y:t.start.y})}const r=o[o.length-1],s={x:t.end.x,y:t.end.y,z:t.end.z},a={connectionName:t.connectionName,start:r,end:s,traceThickness:n};return xe(r,s)\u003eVY\u0026\u0026!this.isStitchSegmentClear(a)\u0026\u0026\"require_clear\"===this.stitchClearanceMode?(this.failed=!0,void(this.error=`Terminal stitch for \"${t.connectionName}\" violates copper clearance`)):(o.push(s),this.mergedHdRoute={connectionName:t.connectionName,...t.preserveTerminalPcbPortIds\u0026\u0026t.start.pcb_port_id?{startPcbPortId:t.start.pcb_port_id}:{},...t.preserveTerminalPcbPortIds\u0026\u0026t.end.pcb_port_id?{endPcbPortId:t.end.pcb_port_id}:{},rootConnectionName:e[0]?.rootConnectionName,route:o,vias:i,jumpers:[],viaDiameter:t.defaultViaDiameter??.3,traceThickness:n},void(this.solved=!0))}const n=new Set((t.preserveTerminalPcbPortIds?[t.start.pcb_port_id,t.end.pcb_port_id]:[]).filter(t=\u003evoid 0!==t));if(t.preserveTerminalPcbPortIds\u0026\u0026t.start.pcb_port_id\u0026\u0026t.start.pcb_port_id===t.end.pcb_port_id)throw new Error(`SingleHighDensityRouteStitchSolver3 received duplicate PCB terminal \"${t.start.pcb_port_id}\" for \"${t.connectionName}\"`);const o=e.flatMap(t=\u003e[t.startPcbPortId,t.endPcbPortId]).filter(t=\u003evoid 0!==t);if(n.size\u003e0)for(const e of o)if(!n.has(e))throw new Error(`SingleHighDensityRouteStitchSolver3 found unknown PCB terminal \"${e}\" on \"${t.connectionName}\"`);let i=1/0,r=e[0],s=\"start-to-end\";for(const n of e){const e=n.route[0],o=n.route[n.route.length-1],a=xe(t.start,e),c=xe(t.start,o),l=xe(t.end,e),d=xe(t.end,o),h=Math.min(a,c,l,d);(h\u003ci-DY||Math.abs(h-i)\u003c=DY\u0026\u0026YY(n,r)\u003c0)\u0026\u0026(i=h,r=n,s=Math.min(l,d)\u003cMath.min(a,c)-DY||Math.abs(Math.min(l,d)-Math.min(a,c))\u003c=DY\u0026\u0026BY(t.end,t.start)\u003c0?\"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 a=r.route[0],c=r.route[r.route.length-1],l=xe(this.start,a),d=xe(this.start,c),h=l\u003cd-DY||Math.abs(l-d)\u003c=DY\u0026\u0026BY(a,c)\u003c=0?a:c,u=h===a?r.startPcbPortId:r.endPcbPortId;if(u\u0026\u0026this.start.pcb_port_id\u0026\u0026u!==this.start.pcb_port_id)throw new Error(`SingleHighDensityRouteStitchSolver3 terminal identity disagrees with route orientation for \"${t.connectionName}\"`);this.mergedHdRoute={connectionName:t.connectionName,...t.preserveTerminalPcbPortIds\u0026\u0026this.start.pcb_port_id?{startPcbPortId:this.start.pcb_port_id}:{},...t.preserveTerminalPcbPortIds\u0026\u0026this.end.pcb_port_id?{endPcbPortId:this.end.pcb_port_id}:{},rootConnectionName:r.rootConnectionName,route:[{x:this.start.x,y:this.start.y,z:h.z}],vias:[],jumpers:[],viaDiameter:r.viaDiameter,traceThickness:r.traceThickness}}getDisjointedRoute(){for(const t of this.remainingHdRoutes){if([t.route[0],t.route[t.route.length-1]].some(e=\u003e!this.remainingHdRoutes.some(n=\u003e{if(n===t)return!1;return[n.route[0],n.route[n.route.length-1]].some(t=\u003et.z===e.z\u0026\u0026xe(e,t)\u003c.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],e={...this.end,z:t.z},n=xe(t,e);if(n\u003eVY\u0026\u0026n\u003c=zY){if(!this.isPlanarStitchClear(t,e)\u0026\u0026\"require_clear\"===this.stitchClearanceMode)return this.failed=!0,void(this.error=`Terminal stitch for \"${this.mergedHdRoute.connectionName}\" violates copper clearance`);this.mergedHdRoute.route.push({x:this.end.x,y:this.end.y,z:t.z})}return void(this.solved=!0)}const t=this.mergedHdRoute.route[this.mergedHdRoute.route.length-1];let e=-1,n=\"first\",o=1/0,i=!1;for(let r=0;r\u003cthis.remainingHdRoutes.length;r++){const s=this.remainingHdRoutes[r],a=s.route[0],c=s.route[s.route.length-1],l=xe(t,a),d=xe(t,c);let h=1/0;if(t.z===a.z){if(l\u003cVY)h=l;else if(l\u003c=1){const e=this.isPlanarStitchClear(t,a);if(e||\"prefer_clear\"===this.stitchClearanceMode){h=XY+(e?0:WY)+l}else i=!0}}else l\u003cVY\u0026\u0026(!this.allowedLayerTransitionPointKeys||this.allowedLayerTransitionPointKeys.has(af(a)))\u0026\u0026(h=1e3+l);h\u003co\u0026\u0026(o=h,e=r,n=\"first\");let u=1/0;if(t.z===c.z){if(d\u003cVY)u=d;else if(d\u003c=1){const e=this.isPlanarStitchClear(t,c);if(e||\"prefer_clear\"===this.stitchClearanceMode){u=XY+(e?0:WY)+d}else i=!0}}else d\u003cVY\u0026\u0026(!this.allowedLayerTransitionPointKeys||this.allowedLayerTransitionPointKeys.has(af(c)))\u0026\u0026(u=1e3+d);u\u003co\u0026\u0026(o=u,e=r,n=\"last\")}if(-1===e)return i?(this.failed=!0,void(this.error=`Route stitch for \"${this.mergedHdRoute.connectionName}\" violates copper clearance`)):void(this.remainingHdRoutes=[]);const r=this.remainingHdRoutes[e];let s;this.remainingHdRoutes.splice(e,1),s=\"first\"===n?r.route:(t=\u003e{const e=[...t].reverse().map(t=\u003e{const{toNextSegmentType:e,...n}=t;return n});for(let n=0;n\u003ct.length-1;n++){const o=t[n]?.toNextSegmentType;if(!o)continue;const i=t.length-n-2;e[i]={...e[i],toNextSegmentType:o}}return e})(r.route),s.length\u003e0\u0026\u0026xe(t,s[0])\u003cVY\u0026\u0026t.z===s[0].z?(s[0].toNextSegmentType\u0026\u0026(t.toNextSegmentType=s[0].toNextSegmentType),this.mergedHdRoute.route.push(...s.slice(1))):this.mergedHdRoute.route.push(...s),this.mergedHdRoute.vias.push(...r.vias),r.jumpers\u0026\u0026this.mergedHdRoute.jumpers.push(...r.jumpers)}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:\"Single High Density Route Stitch Solver 3\"};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\u0026\u0026this.mergedHdRoute.route.length\u003e1){t.lines?.push({points:this.mergedHdRoute.route.map(t=\u003e({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\u0026\u0026this.mergedHdRoute.jumpers.length\u003e0){const e=_a(this.mergedHdRoute.jumpers,{color:\"green\",label:this.mergedHdRoute.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const e of this.remainingHdRoutes){t.lines?.push({points:e.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:\"orange\"});for(const n of e.route)t.points?.push({x:n.x,y:n.y,color:\"orange\"});for(const n of e.vias)t.circles?.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:\"orange\"});if(e.jumpers\u0026\u0026e.jumpers.length\u003e0){const n=_a(e.jumpers,{color:\"orange\",label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}return t}},GY=class{constructor(t=!1){this.preferSameLayerTerminalEndpoints=t}preferSameLayerTerminalEndpoints;endpointClusters=new Map;getEndpointKey(t,e){const n=this.endpointClusters.get(t)??[];let o,i=1/0;for(const t of n){if(t.point.z!==e.z)continue;const n=xe(t.point,e);n\u003c=.1\u0026\u0026(n\u003ci-DY||Math.abs(n-i)\u003c=DY\u0026\u0026(!o||BY(t.point,o.point)\u003c0))\u0026\u0026(o=t,i=n)}if(o)return o.key;const r=`${t}:endpoint_${n.length}`;return n.push({key:r,point:{x:e.x,y:e.y,z:e.z}}),this.endpointClusters.set(t,n),r}getClusters(t){return this.endpointClusters.get(t)??[]}getClosestEndpointKey(t,e,n){const o=e.flatMap(t=\u003e[t.route[0],t.route[t.route.length-1]]),i=o.filter(t=\u003et.z===n.z),r=this.preferSameLayerTerminalEndpoints\u0026\u0026i.length\u003e0?i:o;let s=null,a=null,c=1/0;for(const e of r){const o=xe(n,e),i=this.getEndpointKey(t,e);(o\u003cc-DY||Math.abs(o-c)\u003c=DY\u0026\u0026(null===s||i.localeCompare(s)\u003c0||i===s\u0026\u0026null!==a\u0026\u0026BY(e,a)\u003c0))\u0026\u0026(c=o,s=i,a=e)}return s}},UY=(t,e,n)=\u003e{const o=t.get(e)??[];o.some(t=\u003et.nextHash===n.nextHash\u0026\u0026t.routeIndex===n.routeIndex)||(o.push(n),t.set(e,o))},ZY=t=\u003e{const e=[...t.possibleEndpoints].sort(BY),n=e.reduce((e,n)=\u003e{const o=xe(n,t.globalStart),i=xe(e,t.globalStart);return o\u003ci-DY||Math.abs(o-i)\u003c=DY\u0026\u0026BY(n,e)\u003c0?n:e}),o=e.filter(t=\u003et!==n),i=(o.length\u003e0?o:t.possibleEndpoints).reduce((e,n)=\u003e{const o=xe(n,t.globalEnd),i=xe(e,t.globalEnd);return o\u003ci-DY||Math.abs(o-i)\u003c=DY\u0026\u0026BY(n,e)\u003c0?n:e});return{start:n,end:i}},qY=t=\u003e{const e=[...t.terminals].sort(BY);let n=e[0],o=xe(t.islandEndpoint,n);for(const i of e.slice(1)){const e=xe(t.islandEndpoint,i);(e\u003co-DY||Math.abs(e-o)\u003c=DY\u0026\u0026BY(i,n)\u003c0)\u0026\u0026(n=i,o=e)}return o\u003c=zY?n:t.islandEndpoint},JY=t=\u003e{if(t.hdRoutes.length\u003c=2)return t.hdRoutes;const e=[...t.hdRoutes].sort(YY),n=t.endpointIndex.getClosestEndpointKey(t.connectionName,e,t.start),o=t.endpointIndex.getClosestEndpointKey(t.connectionName,e,t.end);if(!n||!o||n===o)return e;const i=new Map;for(let n=0;n\u003ce.length;n++){const o=e[n],r=t.endpointIndex.getEndpointKey(t.connectionName,o.route[0]),s=t.endpointIndex.getEndpointKey(t.connectionName,o.route[o.route.length-1]);UY(i,r,{nextHash:s,routeIndex:n}),UY(i,s,{nextHash:r,routeIndex:n})}const r=[...t.endpointIndex.getClusters(t.connectionName)].sort((t,e)=\u003eBY(t.point,e.point));for(let t=0;t\u003cr.length;t++){const e=r[t];for(let n=t+1;n\u003cr.length;n++){const t=r[n];e.point.z===t.point.z\u0026\u0026(xe(e.point,t.point)\u003e1||(UY(i,e.key,{nextHash:t.key,routeIndex:null}),UY(i,t.key,{nextHash:e.key,routeIndex:null})))}}for(const[t,n]of i.entries())i.set(t,[...n].sort((t,n)=\u003e{if(null===t.routeIndex\u0026\u0026null!==n.routeIndex)return 1;if(null!==t.routeIndex\u0026\u0026null===n.routeIndex)return-1;if(null!==t.routeIndex\u0026\u0026null!==n.routeIndex){const o=YY(e[t.routeIndex],e[n.routeIndex]);if(0!==o)return o}return t.nextHash.localeCompare(n.nextHash)}));const s=[n],a=new Set([n]),c=new Map;for(;s.length\u003e0;){const t=s.shift();if(t===o)break;for(const e of i.get(t)??[])a.has(e.nextHash)||(a.add(e.nextHash),c.set(e.nextHash,{prevHash:t,routeIndex:e.routeIndex}),s.push(e.nextHash))}if(!a.has(o))return e;const l=[];let d=o;for(;d!==n;){const t=c.get(d);if(!t)return e;null!==t.routeIndex\u0026\u0026l.push(t.routeIndex),d=t.prevHash}if(0===l.length)return t.hdRoutes;const h=l.reverse().map(t=\u003ee[t]);return h.length\u003e0\u0026\u0026!t.canStitchBetweenTerminals({connectionName:t.connectionName,hdRoutes:h,start:t.start,end:t.end})?e:h},KY=class extends si{getSolverName(){return\"MultipleHighDensityRouteStitchSolver3\"}unsolvedRoutes;activeSolver=null;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;allowedLayerTransitionPointKeys;preserveTerminalPcbPortIds;endpointIndex;clearanceValidator;canStitchBetweenTerminals(t){const e=new HY({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter,allowedLayerTransitionPointKeys:this.allowedLayerTransitionPointKeys,preserveTerminalPcbPortIds:this.preserveTerminalPcbPortIds,isStitchSegmentClear:t=\u003ethis.clearanceValidator.isSegmentClear(t),stitchClearanceMode:\"require_clear\"});for(;!e.solved\u0026\u0026!e.failed\u0026\u0026e.iterations\u003ce.MAX_ITERATIONS;)e.step();if(e.failed)return!1;const n=e.mergedHdRoute.route[0],o=e.mergedHdRoute.route[e.mergedHdRoute.route.length-1],i=xe(n,t.start)+xe(o,t.end),r=xe(n,t.end)+xe(o,t.start);return Math.min(i,r)\u003c=zY}getSharedRootPathRoutes(t){const e=t.rootConnectionName;if(!e)return null;const n=new Set(t.hdRoutes),o=t.allHdRoutes.filter(t=\u003e(t.rootConnectionName??t.connectionName)===e);if(o.every(t=\u003en.has(t)))return null;const i=JY({connectionName:t.connectionName,hdRoutes:o,start:t.start,end:t.end,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=\u003ethis.canStitchBetweenTerminals(t)});return!i.some(t=\u003e!n.has(t))||i.length\u003e=o.length?null:i}constructor(t){super(),this.endpointIndex=new GY(t.preferSameLayerTerminalEndpoints),this.colorMap=t.colorMap??{},this.allowedLayerTransitionPointKeys=t.allowedLayerTransitionPointKeys,this.preserveTerminalPcbPortIds=t.preserveTerminalPcbPortIds??!1;const e=[...t.hdRoutes].sort(YY);this.clearanceValidator=new LY({hdRoutes:e});const n=e[0];this.defaultTraceThickness=n?.traceThickness??.15,this.defaultViaDiameter=n?.viaDiameter??t.defaultViaDiameter??.3;const o=new fa({}),i=[],r=new Map;for(let t=0;t\u003ce.length;t++){const n=e[t],o=n.route[0],r=n.route[n.route.length-1];i.push([`route_island_${t}`,this.endpointIndex.getEndpointKey(n.connectionName,o),this.endpointIndex.getEndpointKey(n.connectionName,r)])}o.addConnections(i);for(const t of i)for(const e of t.slice(1))r.set(e,(r.get(e)??0)+1);this.unsolvedRoutes=[];const s=Array.from(new Set(Object.values(o.idToNetMap)));for(const n of s){const i=o.getIdsConnectedToNet(n),s=e.filter((t,e)=\u003ei.includes(`route_island_${e}`));if(0===s.length)continue;const a=t.connections.find(t=\u003et.name===s[0].connectionName),c=s.flatMap(t=\u003e[t.route[0],t.route[t.route.length-1]]),l=new Map,d=[];for(const t of c){const e=this.endpointIndex.getEndpointKey(s[0].connectionName,t);l.has(e)||l.set(e,t),1===r.get(e)\u0026\u0026d.push(t)}const h=d.length\u003e0?d:[...l.values()];if(0===h.length)continue;let u,p;if(h.length\u003e=2){const e={...a.pointsToConnect[0],z:ko(bo(a.pointsToConnect[0]),t.layerCount)},n={...a.pointsToConnect[1],z:ko(bo(a.pointsToConnect[1]),t.layerCount)};({start:u,end:p}=ZY({possibleEndpoints:h,globalStart:e,globalEnd:n})),xe(u,a.pointsToConnect[1])\u003cxe(p,a.pointsToConnect[0])\u0026\u0026([u,p]=[p,u]),u=qY({islandEndpoint:u,terminals:[e,n]}),p=qY({islandEndpoint:p,terminals:[e,n]})}else u={...a.pointsToConnect[0],z:ko(bo(a.pointsToConnect[0]),t.layerCount)},p={...a.pointsToConnect[1],z:ko(bo(a.pointsToConnect[1]),t.layerCount)};const m=JY({connectionName:s[0].connectionName,hdRoutes:s,start:u,end:p,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=\u003ethis.canStitchBetweenTerminals(t)});this.unsolvedRoutes.push({connectionName:s[0].connectionName,hdRoutes:m,start:u,end:p})}const a=new Map;for(const t of this.unsolvedRoutes){const e=a.get(t.connectionName);e?e.push(t):a.set(t.connectionName,[t])}this.unsolvedRoutes=Array.from(a.entries()).flatMap(([n,o])=\u003e{const i=t.connections.find(t=\u003et.name===n),r=o.some(t=\u003et.hdRoutes.some(t=\u003et.route.length\u003c2)),s=o.length\u003e1\u0026\u0026(t=\u003e{for(let e=0;e\u003ct.length;e++)for(let n=e+1;n\u003ct.length;n++){const o=[t[e].start,t[e].end],i=[t[n].start,t[n].end];for(const t of o)for(const e of i)if(t.z===e.z\u0026\u0026xe(t,e)\u003c=1)return!0}return!1})(o);if(!i)return o;const a={...i.pointsToConnect[0],z:ko(bo(i.pointsToConnect[0]),t.layerCount)},c={...i.pointsToConnect[1],z:ko(bo(i.pointsToConnect[1]),t.layerCount)},l=o.flatMap(t=\u003et.hdRoutes),d=o.length\u003e1?this.getSharedRootPathRoutes({connectionName:n,rootConnectionName:i.__rootConnectionNames?.[0]??l[0]?.rootConnectionName,hdRoutes:l,allHdRoutes:e,start:a,end:c}):null;return r||s||d?[{connectionName:n,hdRoutes:d??JY({connectionName:n,hdRoutes:l,start:a,end:c,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=\u003ethis.canStitchBetweenTerminals(t)}),start:a,end:c}]:o}),this.MAX_ITERATIONS=1e5}_step(){if(this.activeSolver)return this.activeSolver.step(),void(this.activeSolver.solved?(this.activeSolver instanceof HY\u0026\u0026(this.clearanceValidator.addRoute(this.activeSolver.mergedHdRoute),this.mergedHdRoutes.push(this.activeSolver.mergedHdRoute)),this.activeSolver=null):this.activeSolver.failed\u0026\u0026(this.failed=!0,this.error=this.activeSolver.error));const t=this.unsolvedRoutes.pop();t?this.activeSolver=new HY({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter,allowedLayerTransitionPointKeys:this.allowedLayerTransitionPointKeys,preserveTerminalPcbPortIds:this.preserveTerminalPcbPortIds,isStitchSegmentClear:t=\u003ethis.clearanceValidator.isSegmentClear(t),stitchClearanceMode:\"prefer_clear\"}):this.solved=!0}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:\"Multiple High Density Route Stitch Solver 3\"};if(this.activeSolver){const e=this.activeSolver.visualize();e.points?.length\u0026\u0026t.points?.push(...e.points),e.lines?.length\u0026\u0026t.lines?.push(...e.lines),e.circles?.length\u0026\u0026t.circles?.push(...e.circles),e.rects?.length\u0026\u0026(t.rects||(t.rects=[]),t.rects.push(...e.rects))}for(const[e,n]of this.mergedHdRoutes.entries()){const o=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e\u003cn.route.length-1;e++){const i=n.route[e],r=n.route[e+1],s=0!==i.z?To(o,.5):o;t.lines?.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:s,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?To(o,.5):o;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:o});if(n.jumpers\u0026\u0026n.jumpers.length\u003e0){const e=_a(n.jumpers,{color:o,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}return t}},QY=t=\u003e(t%360+360)%360,tX=(t,e)=\u003e{const{ccwRotationDegrees:n,...o}=t,i=(t=\u003e{const e=QY(t),n=[0,90,180,270];for(const t of n)if(Math.min(Math.abs(e-t),360-Math.abs(e-t))\u003c=.01)return t;return null})(e);return 90===i||270===i?{...o,width:t.height,height:t.width}:o},eX=t=\u003e\"layers\"in t?t.layers:[t.layer],nX=(t,e)=\u003e!(eX(t).length\u003e0\u0026\u0026!eX(t).some(t=\u003ee.layers.includes(t)))\u0026\u0026Me(t,Ve(e)),oX=(t,e)=\u003e{const{minX:n,maxX:o,minY:i,maxY:r}=Ve(e);return{x:Math.max(n,Math.min(o,t.x)),y:Math.max(i,Math.min(r,t.y))}},iX=(t,e)=\u003et.obstacleId??`${t.componentId??\"obstacle\"}_${e}`;function rX(t,e=2){const{center:n,width:o,height:i,rotation:r}=t,s=[],a=Math.max(1,Math.ceil(e)),c=r*Math.PI/180,l=Math.cos(c),d=Math.sin(c);if(o\u003e=i){const t=o/a;for(let e=0;e\u003ca;e++){const o=(e-a/2+.5)*t,r=o*l,c=o*d,h=Math.abs(t*l)+Math.abs(i*d),u=Math.abs(t*d)+Math.abs(i*l);s.push({center:{x:n.x+r,y:n.y+c},width:h,height:u})}}else{const t=i/a;for(let e=0;e\u003ca;e++){const i=(e-a/2+.5)*t,r=-i*d,c=i*l,h=Math.abs(o*l)+Math.abs(t*d),u=Math.abs(o*d)+Math.abs(t*l);s.push({center:{x:n.x+r,y:n.y+c},width:h,height:u})}}return s}var sX=t=\u003e{if(\"oval\"===t.type)return sX({...t,type:\"rect\"});const e=t.ccwRotationDegrees;if(\"number\"!=typeof e||!Number.isFinite(e))return[t];if((t=\u003e{const e=QY(t);return[0,90,180,270].some(t=\u003eMath.min(Math.abs(e-t),360-Math.abs(e-t))\u003c=.01)})(e))return[tX(t,e)];const{ccwRotationDegrees:n,...o}=t,i={center:t.center,width:t.width,height:t.height,rotation:e},r=(t=\u003e{const e=Math.max(t.width,t.height),n=Math.min(t.width,t.height);return t.obstacleId?.startsWith(\"trace_obstacle_\")?Math.max(2,Math.ceil(e/.75)):n\u003c=0?2:e/n\u003c2||n\u003e=.9?null:Math.max(2,Math.ceil(e/.75))})(t),s=t.connectedTo.length\u003e0\u0026\u0026!t.obstacleId?.startsWith(\"trace_obstacle_\")?(t=\u003e{const e=t.rotation*Math.PI/180,n=Math.cos(e),o=Math.sin(e),i=[-1,1].flatMap(e=\u003e[-1,1].map(i=\u003e{const r=e*(t.width/2),s=i*(t.height/2);return{x:t.center.x+r*n-s*o,y:t.center.y+r*o+s*n}})),r=[i[0],i[2],i[3],i[1]],s=Math.min(...r.map(t=\u003et.x)),a=Math.max(...r.map(t=\u003et.x)),c=Math.min(...r.map(t=\u003et.y)),l=Math.max(...r.map(t=\u003et.y)),d=a-s\u003c=l-c?\"x\":\"y\",h=\"x\"===d?s:c,u=\"x\"===d?a:l,p=Math.max(1,Math.ceil((u-h)/.4)),m=(u-h)/p,g=(t,e,n)=\u003e{const o=[],i=t=\u003et[d];for(let r=0;r\u003ct.length;r++){const s=t[r],a=t[(r+1)%t.length],c=i(s),l=i(a),d=n?c\u003e=e:c\u003c=e,h=n?l\u003e=e:l\u003c=e;if(d\u0026\u0026o.push(s),d===h)continue;const u=(e-c)/(l-c);o.push({x:s.x+(a.x-s.x)*u,y:s.y+(a.y-s.y)*u})}return o},f=[];for(let t=0;t\u003cp;t++){const e=h+t*m,n=t===p-1?u:e+m,o=g(g(r,e,!0),n,!1);if(0===o.length)continue;const i=Math.min(...o.map(t=\u003et.x)),s=Math.max(...o.map(t=\u003et.x)),a=Math.min(...o.map(t=\u003et.y)),c=Math.max(...o.map(t=\u003et.y));f.push({center:{x:(i+s)/2,y:(a+c)/2},width:s-i,height:c-a})}return f})(i):null===r?((t,e)=\u003e{const{center:n,width:o,height:i,rotation:r}=t,s=Math.max(1,Math.ceil(o/e)),a=Math.max(1,Math.ceil(i/e)),c=o/s,l=i/a,d=r*Math.PI/180,h=Math.cos(d),u=Math.sin(d),p=[];for(let t=0;t\u003cs;t++){const e=(t-s/2+.5)*c;for(let t=0;t\u003ca;t++){const o=(t-a/2+.5)*l;p.push({center:{x:n.x+e*h-o*u,y:n.y+e*u+o*h},width:Math.abs(c*h)+Math.abs(l*u),height:Math.abs(c*u)+Math.abs(l*h)})}}return p})(i,(t=\u003et.obstacleId?.startsWith(\"trace_obstacle_\")?.75:.4)(t)):t.obstacleId?.startsWith(\"trace_obstacle_\")?rX(i,r):((t,e)=\u003e{const{center:n,width:o,height:i,rotation:r}=t,s=Math.max(o,i),a=Math.min(o,i),c=Math.max(1,Math.ceil(e)),l=s/c,d=r*Math.PI/180,h=Math.cos(d),u=Math.sin(d),p=Math.max(l,.75*a),m=[];for(let t=0;t\u003cc;t++){const e=(t-c/2+.5)*l,r=o\u003e=i?e*h:-e*u,s=o\u003e=i?e*u:e*h;m.push({center:{x:n.x+r,y:n.y+s},width:p,height:p})}return m})(i,r),a=t.connectedTo.length\u003e0?s.reduce((e,n,o)=\u003e{const i=s[e],r=(i.center.x-t.center.x)**2+(i.center.y-t.center.y)**2;return(n.center.x-t.center.x)**2+(n.center.y-t.center.y)**2\u003cr?o:e},0):-1;return s.map((t,e)=\u003e({...o,obstacleId:e===a?o.obstacleId:o.obstacleId?`${o.obstacleId}_approx_${e}`:void 0,connectedTo:o.connectedTo,center:t.center,width:t.width,height:t.height}))},aX=t=\u003e{const e=new Map,n=new Map,o=new Map;for(const[i,r]of t.obstacles.entries()){const t=sX(r),s=iX(r,i);n.set(s,t),o.set(s,r);for(const n of t){const t=[n.center.x.toFixed(6),n.center.y.toFixed(6),n.width.toFixed(6),n.height.toFixed(6),n.layers.join(\",\")].join(\":\"),o=e.get(t);o?o.connectedTo=[...new Set([...o.connectedTo,...n.connectedTo])]:e.set(t,n)}}const i=t.connections.map(t=\u003e({...t,pointsToConnect:t.pointsToConnect.map(t=\u003e{const e=(t=\u003e[t.pointId,t.pcb_port_id].filter(t=\u003eBoolean(t)))(t);if(0===e.length)return t;for(const[i,r]of o){if(!e.some(t=\u003er.connectedTo.includes(t)))continue;if(!nX(t,r))continue;const o=n.get(i)??[];if(0===o.length)continue;if(o.some(e=\u003enX(t,e)))return t;let s=o[0],a=Number.POSITIVE_INFINITY;for(const e of o){const n=xe(oX(t,e),t);n\u003ca\u0026\u0026(a=n,s=e)}return{...t,...oX(t,s)}}return t})}));return{...t,connections:i,obstacles:[...e.values()]}},cX=.001,lX=t=\u003e\"wire\"===t.route_type,dX=t=\u003e\"via\"===t.route_type,hX=t=\u003e\"through_obstacle\"===t.route_type,uX=(t,e,n)=\u003e{const o=ko(t,n),i=ko(e,n),r=Math.min(o,i),s=Math.max(o,i);return Array.from({length:s-r+1},(t,e)=\u003evo(r+e,n))},pX=({obstacleId:t,start:e,end:n,width:o,layer:i,connectedTo:r})=\u003e{const s=n.x-e.x,a=n.y-e.y,c=Math.hypot(s,a);return c\u003c=cX?null:{obstacleId:t,type:\"rect\",layers:[i],center:{x:(e.x+n.x)/2,y:(e.y+n.y)/2},width:c,height:Math.max(o,cX),ccwRotationDegrees:180*Math.atan2(a,s)/Math.PI,connectedTo:r}};function mX(t){if(!t)return t;const e=(t=\u003e{if(!t)return[];const e=[],n=Yo(t);for(const[o,i]of(t.traces??[]).entries()){const r=i.connectsTo??[];for(let s=0;s\u003ci.route.length;s++){const a=i.route[s];if(dX(a)){const c=a.via_diameter??n.padDiameter;e.push({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${s}_via`,type:\"rect\",layers:uX(a.from_layer,a.to_layer,t.layerCount),center:{x:a.x,y:a.y},width:Math.max(c,cX),height:Math.max(c,cX),connectedTo:r});continue}if(hX(a)){const n=pX({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${s}_through`,start:a.start,end:a.end,width:a.width,layer:a.from_layer,connectedTo:r});n\u0026\u0026(n.layers=uX(a.from_layer,a.to_layer,t.layerCount),e.push(n))}}for(let t=0;t\u003ci.route.length-1;t++){const n=i.route[t],s=i.route[t+1];if(!lX(n)||!lX(s)||n.layer!==s.layer)continue;const a=pX({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${t}_wire`,start:n,end:s,width:n.width,layer:n.layer,connectedTo:r});a\u0026\u0026e.push(a)}}return e})(t);return 0===e.length?t:{...t,obstacles:[...t.obstacles??[],...e]}}function gX(t,e){const n=function(t,e){const n=Lo(t.__zLayers??t.zLayers??[],e);if(n.length\u003e0)return n;const o=Do(t.layers,e);if(o.length\u003e0)return o;throw new Error(`Obstacle \"${t.obstacleId??\"unknown\"}\" has no layers on this ${e}-layer board`)}(t,e);return{...t,layers:n.map(t=\u003evo(t,e)),zLayers:n,__zLayers:n}}function fX(t){return{...t,obstacles:t.obstacles.map(e=\u003egX(e,t.layerCount)),jumpers:t.jumpers?.map(e=\u003e({...e,pads:e.pads.map(e=\u003egX(e,t.layerCount))}))}}var yX=t=\u003e{const e=t.obstacles.filter(e=\u003e!((t,e)=\u003e!(t=\u003e(t.connectedTo?.length??0)\u003e0||(t.offBoardConnectsTo?.length??0)\u003e0||!0===t.netIsAssignable)(t)\u0026\u0026(e.outline\u0026\u0026e.outline.length\u003e=3?!Te(t,e.outline):!Xe({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.bounds)))(e,t)),n=e.length!==t.obstacles.length,o=n\u0026\u0026t.outline\u0026\u0026t.outline.length\u003e=3?(t=\u003e{if(t.width\u0026\u0026t.height\u0026\u0026t.center){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,width:t.width,height:t.height,center:{x:t.center.x,y:t.center.y}}}if(!t.outline||0===t.outline.length)throw new Error(\"Unable to compute board bounds. pcb_board must include width/height/center or a non-empty outline.\");let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t.outline)e=Math.min(e,r.x),n=Math.min(n,r.y),o=Math.max(o,r.x),i=Math.max(i,r.y);const r=o-e,s=i-n;return{minX:e,minY:n,maxX:o,maxY:i,width:r,height:s,center:{x:e+r/2,y:n+s/2}}})({type:\"pcb_board\",pcb_board_id:\"__autorouting_board_outline__\",center:{x:0,y:0},thickness:1,num_layers:t.layerCount,material:\"fr4\",outline:t.outline}):t.bounds;return n?{...t,obstacles:e,bounds:o}:t},_X=class extends si{constructor(t,e={}){super(),this.inputSrj=t,this.visualizationOptions=e,this.MAX_ITERATIONS=1}inputSrj;visualizationOptions;outputSrj;_step(){const t=fX(this.inputSrj),e=mX(t)??t,n=aX(yX(e));this.outputSrj=fX(n),this.solved=!0}getOutputSimpleRouteJson(){if(!this.outputSrj)throw new Error(\"PreprocessSimpleRouteJsonSolver has not solved yet\");return this.outputSrj}getConstructorParams(){return[this.inputSrj,this.visualizationOptions]}visualize(){return this.outputSrj?pi(Ho({...this.outputSrj,traces:[]},this.visualizationOptions),Yj({srj:this.outputSrj,visualizationOptions:this.visualizationOptions})):{lines:[],points:[],rects:[],circles:[]}}};function bX(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var xX=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;nodeSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[bX(\"preprocessSimpleRouteJsonSolver\",_X,t=\u003e[t.originalSrj],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),bX(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),bX(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),bX(\"nodeSolver\",Kn,t=\u003e[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=\u003e{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),bX(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver?.outputNodes??[]}}),bX(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),bX(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),bX(\"necessaryCrampedPortPointSolver\",sf,t=\u003e[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),bX(\"portPointPathingSolver\",jj,t=\u003e{const e=t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),bX(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),bX(\"highDensityRouteSolver\",zs,t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=(e.length\u003e0?e:n).map(e=\u003ews(e)?{...e,availableZ:Array.from({length:t.srj.layerCount},(t,e)=\u003ee)}:e);return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0}]}),bX(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,totalStepsPerNode:Math.max(20,Math.round(60*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),bX(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2}]),bX(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),bX(\"traceSimplificationSolver\",vc,t=\u003e[{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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,iterations:2}]),bX(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),bX(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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\u0026\u0026(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\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.nodeSolver?.visualize(),o=this.nodeDimensionSubdivisionSolver?.visualize(),i=this.nodeTargetMerger?.visualize(),r=this.singleLayerNodeMerger?.visualize(),s=this.strawSolver?.visualize(),a=this.edgeSolver?.visualize(),c=this.deadEndSolver?.visualize(),l=this.availableSegmentPointSolver?.visualize(),d=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),u=this.uniformPortDistributionSolver?.visualize(),p=this.highDensityRouteSolver?.visualize(),m=this.highDensityForceImproveSolver?.visualize(),g=this.highDensityRepairSolver?.visualize(),f=this.highDensityStitchSolver?.visualize(),y=this.traceSimplificationSolver?.visualize(),_=this.necessaryCrampedPortPointSolver?.visualize(),b=(this.highDensityRouteSolver?.visualize(),this.originalSrj),x=b.outline,v=[];if(v.push({points:[{x:b.bounds?.minX??-50,y:b.bounds?.minY??-50},{x:b.bounds?.maxX??50,y:b.bounds?.minY??-50},{x:b.bounds?.maxX??50,y:b.bounds?.maxY??50},{x:b.bounds?.minX??-50,y:b.bounds?.maxY??50},{x:b.bounds?.minX??-50,y:b.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),x\u0026\u0026x.length\u003e=2){const t=x.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const S=Oo(b),I={points:[...b.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,b.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(b.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,b.layerCount),label:S(t)}))],lines:v},C=Yj({srj:b}),P=[pi(I,C),t,e,n,o,i,r,s,a,c,l,_,d,h,u,p?pi(I,p):null,m,g,f,y,this.solved?pi({lines:v},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...P)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){return this.globalDrcForceImproveSolver?.getOutput()??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 o=n.__netConnectionName??this.originalSrj.connections.find(t=\u003et.name===n.name)?.__netConnectionName,i=e.filter(t=\u003et.connectionName===n.name);for(let e=0;e\u003ci.length;e++){const r=i[e],s={type:\"pcb_trace\",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.srj.obstacles,connMap:this.connMap})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},vX=t=\u003e{const e=[];let n=t;for(;n;)e.push(n),n=n.activeSubSolver;for(let t=e.length-1;t\u003e=0;t--){const n=e[t]?.pendingEffects?.filter(Boolean)??[];if(n.length\u003e0)return n}return[]},SX=t=\u003e/\\/solve\\/?$/.test(t)?t.replace(/\\/+$/,\"\"):`${t.replace(/\\/+$/,\"\")}/solve`,IX=(t,e,n)=\u003e{const o=(t=\u003e{const e=new Map;for(const n of t.portPoints)n.rootConnectionName\u0026\u0026!e.has(n.connectionName)\u0026\u0026e.set(n.connectionName,n.rootConnectionName);return e})(t);return e.map(t=\u003e({connectionName:t.connectionName,rootConnectionName:t.rootConnectionName??o.get(t.connectionName)??void 0,traceThickness:t.traceThickness??n.traceWidth,viaDiameter:t.viaDiameter??n.viaDiameter,route:(t.route??[]).map(t=\u003e({x:t.x,y:t.y,z:t.z,...t.insideJumperPad?{insideJumperPad:!0}:{}})),vias:(t.vias??[]).map(t=\u003e({x:t.x,y:t.y})),...t.jumpers?{jumpers:t.jumpers}:{}}))},CX=(t,e)=\u003e{if(0===t.length)return null;const n=Math.min(Math.max(e,0),1),o=(t.length-1)*n,i=Math.floor(o),r=Math.ceil(o),s=t[i],a=t[r];return i===r?s:s+(a-s)*(o-i)},PX=t=\u003enew Set(t.portPoints.map(t=\u003et.connectionName)).size,MX=t=\u003e!(PX(t)\u003c3)\u0026\u00261!==(t.availableZ?.length??0),NX=t=\u003et?.MULTI_HEAD_POLYLINE_SOLVER?\"MultiHeadPolyLineIntraNodeSolver3\":t?.CLOSED_FORM_SINGLE_TRANSITION?\"SingleTransitionIntraNodeSolver\":t?.CLOSED_FORM_TWO_TRACE_SAME_LAYER?\"TwoCrossingRoutesHighDensitySolver\":t?.CLOSED_FORM_TWO_TRACE_TRANSITION_CROSSING?\"SingleTransitionCrossingRouteSolver\":t?.HIGH_DENSITY_A01?\"HighDensitySolverA01\":t?.HIGH_DENSITY_A03?\"HighDensitySolverA03\":\"SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost\",wX=t=\u003e{if(t instanceof rr){const e=NX(t.hyperParameters);return t.cacheHit?`${e} [cached]`:e}if(t instanceof er)return NX(t.hyperParameters);if(t\u0026\u0026\"object\"==typeof t\u0026\u0026\"getSolverName\"in t\u0026\u0026\"function\"==typeof t.getSolverName)return t.getSolverName();const e=t?.constructor;return\"string\"==typeof e?.name?e.name:\"unknown\"},TX=t=\u003et.winningSolver?wX(t.winningSolver):wX(t),RX=class extends si{getSolverName(){return\"Pipeline5HdCacheHighDensitySolver\"}unsolvedNodePortPoints;colorMap;connMap;viaDiameter;traceWidth;obstacleMargin;obstacles;layerCount;hdCacheBaseUrl;fetchImpl;nodePfById;routes=[];nodeSolveMetadataById=new Map;launchedRemoteSolves=!1;solvedRoutesByNodeIndex=new Map;failedNodeResults=[];remoteResponseMeasurements=[];constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,obstacles:s,layerCount:a,nodePfById:c,hdCacheBaseUrl:l,fetchImpl:d}){super(),this.unsolvedNodePortPoints=t,this.colorMap=e??{},this.connMap=n,this.viaDiameter=o??.3,this.traceWidth=i??.15,this.obstacleMargin=r??.15,this.obstacles=s??[],this.layerCount=a??2,this.hdCacheBaseUrl=l??\"https://hd-cache.tscircuit.com\",this.fetchImpl=(d??globalThis.fetch).bind(globalThis),this.nodePfById=c instanceof Map?new Map(c):new Map(Object.entries(c??{})),this.pendingEffects=[],this.stats={localDirectNodeCount:0,localSolvedNodeCount:0,localFallbackNodeCount:0,remoteFallbackNodeCount:0,remoteRequestsStarted:0,remoteRequestsCompleted:0,remoteResponseSampleCount:0,remoteKOrderSampleCount:0,slowestRemoteResponseMs:null,slowestRemoteResponseNodeId:null,p50RemoteResponseMs:null,p50RemoteKOrder:null,p95RemoteKOrder:null,remoteSources:{}}}computeProgress(){return 0===this.unsolvedNodePortPoints.length?1:this.nodeSolveMetadataById.size/this.unsolvedNodePortPoints.length}solveNodeLocally(t,e,n={}){const o=new Ss({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,obstacles:this.obstacles,layerCount:this.layerCount});if(o.solve(),o.failed){const e=o.error??`Local intra-node solver failed for ${t.capacityMeshNodeId}`,i=PX(t);return this.failedNodeResults.push({node:t,error:n.remoteFailure\u0026\u0026\"local-fallback\"===n.resolution?`Remote solve failed (${n.remoteFailure}); local fallback failed (${e})`:e}),void this.recordNodeSolveMetadata(t,{status:\"failed\",resolution:\"failed\",solverType:TX(o),supervisorType:o.getSolverName(),iterations:o.iterations,pairCount:i,routeCount:0,remoteAttempt:\"local-fallback\"===n.resolution?{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:\"error\",durationMs:n.remoteDurationMs,error:n.remoteFailure??e}:{attempted:!1},error:e})}this.solvedRoutesByNodeIndex.set(e,o.solvedRoutes);const i=PX(t);this.recordNodeSolveMetadata(t,{status:\"solved\",resolution:n.resolution??\"local\",solverType:TX(o),supervisorType:o.getSolverName(),iterations:o.iterations,pairCount:i,routeCount:o.solvedRoutes.length,remoteAttempt:\"local-fallback\"===n.resolution?{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:\"error\",durationMs:n.remoteDurationMs,error:n.remoteFailure}:{attempted:!1}}),\"local-fallback\"===n.resolution?(this.stats.localFallbackNodeCount+=1,this.stats.remoteFallbackNodeCount+=1):this.stats.localDirectNodeCount+=1,this.stats.localSolvedNodeCount+=1}async solveNodeViaHdCache(t,e){const n=SX(this.hdCacheBaseUrl),o={\"content-type\":\"application/json\"},i={nodeWithPortPoints:t},r=JSON.stringify(i),s=Date.now();let a,c,l,d=null,h=null;try{const i=await this.fetchImpl(n,{method:\"POST\",headers:o,body:r});if(a=i.status,c=i.ok,l=await i.text(),d=Date.now()-s,h=l?JSON.parse(l):null,!i.ok)throw new Error(h?.message??l??`hd-cache request failed with status ${i.status}`);if(!h?.ok||null===h.routes)throw new Error(h?.message??`hd-cache returned no routes for ${t.capacityMeshNodeId}`);const u=IX(t,h.routes,{traceWidth:this.traceWidth,viaDiameter:this.viaDiameter});this.solvedRoutesByNodeIndex.set(e,u),this.recordNodeSolveMetadata(t,{status:\"solved\",resolution:\"remote\",solverType:`hd-cache.tscircuit.com [${h.source}]`,iterations:null,pairCount:PX(t),routeCount:u.length,remoteAttempt:{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:h.source,durationMs:d}}),this.recordRemoteSource(h.source)}catch(u){d??=Date.now()-s;const p=(t=\u003et instanceof Error?t.message:String(t))(u);this.recordFailedHdCacheRequest({nodeId:t.capacityMeshNodeId,pairCount:PX(t),failedAt:(new Date).toISOString(),durationMs:d,error:p,url:n,request:{method:\"POST\",headers:o,body:r,bodyJson:i},response:void 0!==a||void 0!==c||void 0!==l||null!==h?{status:a,ok:c,text:l,body:h}:void 0}),this.recordRemoteSource(\"error\"),this.solveNodeLocally(t,e,{resolution:\"local-fallback\",remoteFailure:p,remoteDurationMs:d})}finally{this.recordRemoteResponseMetrics(t.capacityMeshNodeId,d??Date.now()-s,(u=h?.kOrder,\"number\"==typeof u\u0026\u0026Number.isFinite(u)?h.kOrder:null)),this.stats.remoteRequestsCompleted+=1}var u}launchRemoteSolves(){const t=[];this.unsolvedNodePortPoints.forEach((e,n)=\u003e{if(!MX(e))return void this.solveNodeLocally(e,n);const o={name:`hd-cache:${e.capacityMeshNodeId}`,promise:Promise.resolve()};o.promise=this.solveNodeViaHdCache(e,n).finally(()=\u003e{this.pendingEffects=this.pendingEffects?.filter(t=\u003et!==o)}),t.push(o)}),this.pendingEffects=t,this.stats.remoteRequestsStarted=t.length}recordRemoteSource(t){this.stats.remoteSources[t]=(this.stats.remoteSources[t]??0)+1}recordRemoteResponseMetrics(t,e,n){this.remoteResponseMeasurements.push({nodeId:t,durationMs:e,kOrder:n}),this.stats.remoteResponseSampleCount=this.remoteResponseMeasurements.length,this.stats.remoteKOrderSampleCount=this.remoteResponseMeasurements.filter(t=\u003enull!==t.kOrder).length;let o=null;for(const t of this.remoteResponseMeasurements)(!o||t.durationMs\u003eo.durationMs)\u0026\u0026(o=t);this.stats.slowestRemoteResponseMs=o?.durationMs??null,this.stats.slowestRemoteResponseNodeId=o?.nodeId??null;const i=this.remoteResponseMeasurements.map(t=\u003et.durationMs).sort((t,e)=\u003et-e);this.stats.p50RemoteResponseMs=CX(i,.5);const r=this.remoteResponseMeasurements.map(t=\u003et.kOrder).filter(t=\u003enull!==t).sort((t,e)=\u003et-e);this.stats.p50RemoteKOrder=CX(r,.5),this.stats.p95RemoteKOrder=CX(r,.95)}recordFailedHdCacheRequest(t){const e=(()=\u003e{if(\"undefined\"==typeof window)return null;const t=window;return Array.isArray(t.__FAILED_HD_CACHE_REQUESTS)||(t.__FAILED_HD_CACHE_REQUESTS=[]),t.__FAILED_HD_CACHE_REQUESTS})();e\u0026\u0026e.push(t)}recordNodeSolveMetadata(t,e){this.nodeSolveMetadataById.set(t.capacityMeshNodeId,{...e,node:t,nodePf:this.nodePfById.get(t.capacityMeshNodeId)??null})}ensureFailedNodeMetadata(){for(const t of this.failedNodeResults)this.nodeSolveMetadataById.has(t.node.capacityMeshNodeId)||this.recordNodeSolveMetadata(t.node,{status:\"failed\",resolution:\"failed\",solverType:\"unknown\",iterations:null,pairCount:PX(t.node),routeCount:0,remoteAttempt:{attempted:MX(t.node),source:\"error\",error:t.error},error:t.error})}getVisibleRoutes(){if(this.solved)return this.routes;const t=[];for(let e=0;e\u003cthis.unsolvedNodePortPoints.length;e++)t.push(...this.solvedRoutesByNodeIndex.get(e)??[]);return t}createNodeMarkerLabel(t,e){return[\"hd_node_marker\",`node: ${t}`,`status: ${e.status}`,`resolution: ${e.resolution}`,`solver: ${e.solverType}`,...e.supervisorType?[`supervisor: ${e.supervisorType}`]:[],...null!==e.iterations?[`iterations: ${e.iterations}`]:[],`pairCount: ${e.pairCount}`,`routes: ${e.routeCount}`,`nodePf: ${e.nodePf??\"n/a\"}`,\"remoteAttempted: \"+(e.remoteAttempt.attempted?\"yes\":\"no\"),...e.remoteAttempt.source?[`remoteSource: ${e.remoteAttempt.source}`]:[],...void 0!==e.remoteAttempt.durationMs?[`remoteDurationMs: ${e.remoteAttempt.durationMs}`]:[],...e.remoteAttempt.error?[`remoteError: ${e.remoteAttempt.error}`]:[],`portPoints: ${e.node.portPoints.length}`,...e.error?[`error: ${e.error}`]:[]].join(\"\\n\")}_step(){if(!this.launchedRemoteSolves)return this.launchedRemoteSolves=!0,void this.launchRemoteSolves();if(!((this.pendingEffects?.length??0)\u003e0)){if(this.failedNodeResults.length\u003e0){this.ensureFailedNodeMetadata();const t=this.failedNodeResults[0];return this.failed=!0,void(this.error=`Failed to solve ${this.failedNodeResults.length} nodes via hd-cache. First failure: ${t?.node.capacityMeshNodeId} (${t?.error})`)}this.routes=[];for(let t=0;t\u003cthis.unsolvedNodePortPoints.length;t++)this.routes.push(...this.solvedRoutesByNodeIndex.get(t)??[]);this.solved=!0}}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.getVisibleRoutes()){const n=mi(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const o of n)t.lines.push({points:o.points,label:o.connectionName,strokeColor:0===o.z?o.color:To(o.color,.75),layer:`z${o.z}`,strokeWidth:e.traceThickness,strokeDash:0!==o.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,n]of this.nodeSolveMetadataById){const o=n.node.center.x-n.node.width/2,i=n.node.center.x+n.node.width/2,r=n.node.center.y-n.node.height/2,s=n.node.center.y+n.node.height/2,a=this.createNodeMarkerLabel(e,n),c=\"solved\"===n.status?\"blue\":\"red\",l=\"solved\"===n.status?.03:.08;if(t.lines.push({points:[{x:o,y:r},{x:i,y:r}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a},{points:[{x:i,y:r},{x:i,y:s}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a},{points:[{x:i,y:s},{x:o,y:s}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a},{points:[{x:o,y:s},{x:o,y:r}],layer:\"hd_node_boundaries\",strokeColor:c,strokeDash:\"6, 4\",strokeWidth:l,label:a}),\"solved\"===n.status)t.points.push({x:n.node.center.x,y:n.node.center.y,color:c,layer:\"hd_node_markers\",label:a});else{t.lines.push({points:[{x:0,y:0},{x:n.node.center.x,y:n.node.center.y}],layer:\"hd_failed_node_guides\",strokeColor:c,strokeDash:\"8, 6\",strokeWidth:.05,label:a});const e=Math.max(n.node.width,1.2),o=Math.max(n.node.height,1.2),i=e/2,r=o/2;t.rects.push({center:n.node.center,layer:\"hd_node_markers\",width:e,height:o,fill:\"rgba(255, 0, 0, 0.3)\",stroke:c,label:a}),t.circles.push({center:n.node.center,radius:Math.max(.6*Math.max(e,o),1.1),layer:\"hd_node_markers\",fill:\"rgba(255, 0, 0, 0.08)\",stroke:c,label:a}),t.lines.push({points:[{x:n.node.center.x-i,y:n.node.center.y-r},{x:n.node.center.x+i,y:n.node.center.y+r}],layer:\"hd_node_markers\",strokeColor:c,strokeWidth:.16,label:a},{points:[{x:n.node.center.x-i,y:n.node.center.y+r},{x:n.node.center.x+i,y:n.node.center.y-r}],layer:\"hd_node_markers\",strokeColor:c,strokeWidth:.16,label:a})}}return t}},EX=class extends xX{hdCacheBaseUrl;hdCacheFetch;constructor(t,e={}){super(t,{...e,maxNodeDimension:e.maxNodeDimension??7,maxNodeRatio:e.maxNodeRatio??4}),this.hdCacheBaseUrl=e.hdCacheBaseUrl??\"https://hd-cache.tscircuit.com\",this.hdCacheFetch=e.hdCacheFetch,this.replaceHighDensityPipelineStep()}replaceHighDensityPipelineStep(){const t=this.pipelineDef.findIndex(t=\u003e\"highDensityRouteSolver\"===t.solverName);if(-1===t)throw new Error(\"Pipeline4 highDensityRouteSolver step is missing\");this.pipelineDef[t]={...this.pipelineDef[t],solverClass:RX,getConstructorParams:t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length\u003e0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,hdCacheBaseUrl:t.hdCacheBaseUrl,fetchImpl:t.hdCacheFetch}]}}}async stepAsync(){if(this.solved||this.failed)return;this.step();const t=vX(this);0!==t.length\u0026\u0026(await Promise.race(t.map(t=\u003et.promise.then(()=\u003et.name,()=\u003et.name))),this.solved||this.failed||this.step())}async solveAsync(){const t=Date.now();for(;!this.solved\u0026\u0026!this.failed;)await this.stepAsync();this.timeToSolve=Date.now()-t}solve(){throw new Error(\"AutoroutingPipelineSolver5_HdCache requires async execution. Use solveAsync() or stepAsync().\")}},AX=1e-9,OX=Math.PI/2,kX=(t,e)=\u003et.x*e.y-t.y*e.x,LX=(t,e)=\u003et.x*e.x+t.y*e.y,DX=t=\u003e{let e=t%OX;return e\u003c0\u0026\u0026(e+=OX),OX-e\u003c1e-8?0:e},zX=t=\u003e{const e=Math.cos(t),n=Math.sin(t);return{u:{x:e,y:n},v:{x:-n,y:e}}},FX=t=\u003e{let e=0;for(let n=0;n\u003ct.length;n++){const o=t[n],i=t[(n+1)%t.length];e+=o.x*i.y-i.x*o.y}return e/2},BX=t=\u003eMath.abs(FX(t)),jX=t=\u003e{const e=FX(t);if(Math.abs(e)\u003cAX){const e=t.reduce((t,e)=\u003e({x:t.x+e.x,y:t.y+e.y}),{x:0,y:0});return{x:e.x/Math.max(1,t.length),y:e.y/Math.max(1,t.length)}}let n=0,o=0;for(let e=0;e\u003ct.length;e++){const i=t[e],r=t[(e+1)%t.length],s=i.x*r.y-r.x*i.y;n+=(i.x+r.x)*s,o+=(i.y+r.y)*s}const i=1/(6*e);return{x:n*i,y:o*i}},$X=t=\u003eFX(t)\u003e=0?[...t]:[...t].reverse(),YX=(t,e)=\u003e{const n=new Set;n.add(0);for(let t=0;t\u003c90;t++)n.add(t/90*OX);for(let e=0;e\u003ct.length;e++){const o=t[e],i=t[(e+1)%t.length],r=Math.atan2(i.y-o.y,i.x-o.x);n.add(DX(r)),n.add(DX(r+OX))}const o=n=\u003e{const o=((t,e=jX(t),n=0)=\u003e{const o=$X(t),{u:i,v:r}=zX(n),s=o.map((t,n)=\u003e{const s=o[(n+1)%o.length],a=s.x-t.x,c=s.y-t.y,l={x:a,y:c};return{hxCoeff:Math.abs(kX(l,i)),hyCoeff:Math.abs(kX(l,r)),limit:a*(e.y-t.y)-c*(e.x-t.x)}});if(s.some(t=\u003et.limit\u003c-1e-7))throw new Error(\"Projected rect center is outside polygon\");let a=Number.POSITIVE_INFINITY;for(const t of s)t.hxCoeff\u003eAX\u0026\u0026(a=Math.min(a,t.limit/t.hxCoeff));if(!Number.isFinite(a)||a\u003c=AX)return{center:e,width:1e-6,height:1e-6,ccwRotationRadians:n,ccwRotationDegrees:180*n/Math.PI};const c=t=\u003e{let e=Number.POSITIVE_INFINITY;for(const n of s){const o=n.limit-n.hxCoeff*t;if(o\u003c-1e-8)return 0;n.hyCoeff\u003eAX\u0026\u0026(e=Math.min(e,o/n.hyCoeff))}return Number.isFinite(e)?Math.max(0,e):0},l=t=\u003et*c(t);let d=0,h=a;for(let t=0;t\u003c80;t++){const t=d+(h-d)/3,e=h-(h-d)/3;l(t)\u003cl(e)?d=t:h=e}const u=(d+h)/2,p=c(u);return{center:e,width:Math.max(1e-6,2*u),height:Math.max(1e-6,2*p),ccwRotationRadians:n,ccwRotationDegrees:180*n/Math.PI}})(t,e,n);return{rect:o,area:o.width*o.height}};let i=o(0),r=0;for(const t of n){const e=o(t);e.area\u003ei.area+1e-8\u0026\u0026(i=e,r=t)}const s=OX/90;let a=r-s,c=r+s;for(let t=0;t\u003c60;t++){const t=a+(c-a)/3,e=c-(c-a)/3;o(t).area\u003co(e).area?a=t:c=e}const l=o(DX((a+c)/2));return l.area\u003ei.area+1e-8?l.rect:i.rect},XX=(t,e,n,o)=\u003e{const i=o.x-n.x,r=o.y-n.y,s=e.x*r-e.y*i;if(Math.abs(s)\u003cAX)return;const a=n.x-t.x,c=n.y-t.y,l=(a*r-c*i)/s,d=(a*e.y-c*e.x)/s;return l\u003c-1e-8||d\u003c-1e-8||d\u003e1+1e-8?void 0:{x:t.x+e.x*l,y:t.y+e.y*l,rayT:l}},VX=(t,e)=\u003e{const n=[],o=[];for(let i=0;i\u003c4;i++){const{x:r,y:s}=t[i],a=e[i].x,c=e[i].y;n.push([r,s,1,0,0,0,-a*r,-a*s]),o.push(a),n.push([0,0,0,r,s,1,-c*r,-c*s]),o.push(c)}const i=((t,e)=\u003e{const n=e.length,o=t.map((t,n)=\u003e[...t,e[n]]);for(let t=0;t\u003cn;t++){let e=t;for(let i=t+1;i\u003cn;i++)Math.abs(o[i][t])\u003eMath.abs(o[e][t])\u0026\u0026(e=i);if(Math.abs(o[e][t])\u003cAX)throw new Error(\"Could not solve homography\");[o[t],o[e]]=[o[e],o[t]];const i=o[t][t];for(let e=t;e\u003c=n;e++)o[t][e]=o[t][e]/i;for(let e=0;e\u003cn;e++){if(e===t)continue;const i=o[e][t];for(let r=t;r\u003c=n;r++)o[e][r]=o[e][r]-i*o[t][r]}}return o.map(t=\u003et[n])})(n,o);return[i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7],1]},WX=(t,e)=\u003e{const n=Math.cos(e),o=Math.sin(e);return[n,-o,t.x-n*t.x+o*t.y,o,n,t.y-o*t.x-n*t.y,0,0,1]},HX=(t,e)=\u003e{const n=t[6]*e.x+t[7]*e.y+t[8];return Math.abs(n)\u003cAX?{x:e.x,y:e.y}:{x:(t[0]*e.x+t[1]*e.y+t[2])/n,y:(t[3]*e.x+t[4]*e.y+t[5])/n}},GX=(t,e,n)=\u003e{const{u:o,v:i}=zX(n);return{x:e.x+t.x*o.x+t.y*i.x,y:e.y+t.x*o.y+t.y*i.y}},UX=(t,e)=\u003eGX({x:t.x-e.center.x,y:t.y-e.center.y},e.center,e.ccwRotationRadians),ZX=(t,e)=\u003e{const n=((t,e,n)=\u003e{const{u:o,v:i}=zX(n),r={x:t.x-e.x,y:t.y-e.y};return{x:LX(r,o),y:LX(r,i)}})(t,e.center,e.ccwRotationRadians);if(Math.abs(n.x)\u003cAX\u0026\u0026Math.abs(n.y)\u003cAX)return{...e.center};const o=e.width/2,i=e.height/2,r=Math.abs(n.x)\u003eAX?o/Math.abs(n.x):1/0,s=Math.abs(n.y)\u003eAX?i/Math.abs(n.y):1/0,a=Math.min(r,s);return{x:e.center.x+n.x*a,y:e.center.y+n.y*a}},qX=(t,e=0,n=0)=\u003e{const o=((t,e)=\u003e{const n=$X(e);for(let e=0;e\u003cn.length;e++){const o=n[e],i=n[(e+1)%n.length];if((i.x-o.x)*(t.y-o.y)-(i.y-o.y)*(t.x-o.x)\u003c-1e-7)return!1}return!0})(jX(t),t)?[...t]:(t=\u003e{const e=[...t].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e.x-t.x)\u003c1e-9\u0026\u0026Math.abs(e.y-t.y)\u003c1e-9)===e).sort((t,e)=\u003et.x-e.x||t.y-e.y);if(e.length\u003c=3)return e;const n=(t,e,n)=\u003e(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),o=[];for(const t of e){for(;o.length\u003e=2\u0026\u0026n(o[o.length-2],o[o.length-1],t)\u003c=1e-9;)o.pop();o.push(t)}const i=[];for(let t=e.length-1;t\u003e=0;t--){const o=e[t];for(;i.length\u003e=2\u0026\u0026n(i[i.length-2],i[i.length-1],o)\u003c=1e-9;)i.pop();i.push(o)}return o.pop(),i.pop(),[...o,...i]})(t),i=jX(o),r=YX(o,i),s=BX(o),a=r.width*r.height,c=(l=e,Math.max(0,l));var l;const d=a+Math.max(0,s-a)*c,h=a\u003eAX\u0026\u0026d\u003ea?Math.sqrt(d/a):1,u=Math.max(0,n),p=Math.max(r.width*h,u),m=Math.max(r.height*h,u),g=DX(r.ccwRotationRadians),f=180*g/Math.PI,y=(t=\u003e{const e=t.width/2,n=t.height/2;return[{x:t.center.x-e,y:t.center.y-n},{x:t.center.x+e,y:t.center.y-n},{x:t.center.x+e,y:t.center.y+n},{x:t.center.x-e,y:t.center.y+n}]})({center:i,width:p,height:m}),_=(t=\u003e{const e=t.width/2,n=t.height/2;return[GX({x:-e,y:-n},t.center,t.ccwRotationRadians),GX({x:e,y:-n},t.center,t.ccwRotationRadians),GX({x:e,y:n},t.center,t.ccwRotationRadians),GX({x:-e,y:n},t.center,t.ccwRotationRadians)]})({center:i,width:p,height:m,ccwRotationRadians:g}),b=_.map(t=\u003e{const e={x:t.x-i.x,y:t.y-i.y},n=((t,e,n)=\u003e{let o;for(let i=0;i\u003cn.length;i++){const r=XX(t,e,n[i],n[(i+1)%n.length]);r\u0026\u0026(!o||r.rayT\u003co.rayT)\u0026\u0026(o=r)}return o})(i,e,o);return n?{x:n.x,y:n.y}:t});let x=BX(b)\u003eAX?b:_;let v,S;try{v=VX(y,x),S=(t=\u003e{const[e,n,o,i,r,s,a,c,l]=t,d=r*l-s*c,h=-(i*l-s*a),u=i*c-r*a,p=-(n*l-o*c),m=e*l-o*a,g=-(e*c-n*a),f=n*s-o*r,y=-(e*s-o*i),_=e*r-n*i,b=e*d+n*h+o*u;if(Math.abs(b)\u003cAX)throw new Error(\"Cannot invert singular 3x3 matrix\");const x=1/b;return[d*x,p*x,f*x,h*x,m*x,y*x,u*x,g*x,_*x]})(v)}catch{x=_,v=WX(i,g),S=WX(i,-g)}return{center:i,width:p,height:m,innerWidth:r.width,innerHeight:r.height,ccwRotationDegrees:f,ccwRotationRadians:g,polygonArea:s,equivalentAreaExpansionFactor:c,targetQuad:x,rectToPolygonMatrix:v,polygonToRectMatrix:S}},JX=class extends si{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1}params;getSolverName(){return\"AttachProjectedRectsSolver\"}outputNodes=[];projectionAdjustmentByNodeId=new Map;_step(){this.projectionAdjustmentByNodeId.clear(),this.outputNodes=this.params.nodesWithPortPoints.map(t=\u003e{const e=this.params.equivalentAreaExpansionFactor??0,n=this.params.minProjectedRectDimension??0,o=(({traceWidth:t,viaDiameter:e,obstacleMargin:n,minProjectedRectDimension:o})=\u003eMath.max(o,e??0,(t??0)+2*(n??0)))({traceWidth:this.params.traceWidth,viaDiameter:this.params.viaDiameter,obstacleMargin:this.params.obstacleMargin,minProjectedRectDimension:n});let i=qX(t.polygon,e,n);if(Math.min(i.width,i.height)\u003eo+(this.params.traceWidth??0))return{...t,center:i.center,width:i.width,height:i.height,projectedRect:i};const r=qX(t.polygon,1,n);return(({node:t,projectedRect:e,conservativeProjectedRect:n,requiredRoutingCorridorWidth:o,traceWidth:i})=\u003e{if(o\u003c=0)return!1;const r=Math.min(e.width,e.height),s=Math.min(n.width,n.height),a=Math.max(e.width,e.height),c=Math.max(n.width,n.height),l=o+(i??0),d=Math.floor(r/o),h=Math.floor(s/o);return new Set(t.portPoints.map(t=\u003et.connectionName)).size\u003e1\u0026\u0026d\u003c=h\u0026\u0026r\u003c=l\u0026\u0026a-c\u003e=o\u0026\u0026e.equivalentAreaExpansionFactor\u003e1})({node:t,projectedRect:i,conservativeProjectedRect:r,requiredRoutingCorridorWidth:o,traceWidth:this.params.traceWidth})\u0026\u0026(i=r,this.projectionAdjustmentByNodeId.set(t.capacityMeshNodeId,\"corridor-expansion-factor-1\")),{...t,center:i.center,width:i.width,height:i.height,projectedRect:i}}),this.solved=!0}getOutput(){return this.outputNodes}getConstructorParams(){return[this.params]}visualize(){const t=this.outputNodes.length\u003e0?this.outputNodes:this.params.nodesWithPortPoints;return{polygons:t.map(t=\u003e({points:t.polygon,fill:\"rgba(40, 140, 220, 0.06)\",stroke:\"rgba(20, 70, 160, 0.95)\",strokeWidth:.04,label:`${t.capacityMeshNodeId} polygon`})),lines:t.map(t=\u003e({points:[...t.polygon,t.polygon[0]],strokeColor:\"rgba(20, 70, 160, 0.95)\",strokeWidth:.04,label:`${t.capacityMeshNodeId} polygon outline`})),rects:t.flatMap(t=\u003et.projectedRect?[{center:t.projectedRect.center,width:t.projectedRect.width,height:t.projectedRect.height,ccwRotationDegrees:t.projectedRect.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.16)\",stroke:\"rgba(255, 140, 0, 0.8)\",label:`${t.capacityMeshNodeId} projectedRect`}]:[]),points:t.flatMap(t=\u003et.portPoints.map(t=\u003e({x:t.x,y:t.y,color:\"rgba(30, 30, 30, 0.85)\",label:t.connectionName})))}}},KX=class extends si{constructor(t){super(),this.params=t;const{nodeWithPortPoints:e}=t;if(!e.projectedRect)throw new Error(\"Poly node is missing projectedRect\");this.projectedPorts=e.portPoints.map(t=\u003e{const n=ZX(t,e.projectedRect);return{original:t,projected:{...t,x:n.x,y:n.y}}}),this.projectedNode={capacityMeshNodeId:e.capacityMeshNodeId,center:e.projectedRect.center,width:e.projectedRect.width,height:e.projectedRect.height,availableZ:e.availableZ,portPoints:this.projectedPorts.map(({projected:t})=\u003et)},this.highDensitySolver=new Ss({nodeWithPortPoints:this.projectedNode,colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort}),this.activeSubSolver=this.highDensitySolver,this.MAX_ITERATIONS=this.highDensitySolver.MAX_ITERATIONS+1e3}params;getSolverName(){return\"PolySingleIntraNodeSolver\"}highDensitySolver;projectedNode;solvedRoutes=[];projectedPorts;_step(){this.highDensitySolver.step(),this.progress=this.highDensitySolver.progress,this.stats=this.highDensitySolver.stats,this.highDensitySolver.solved?(this.solvedRoutes=this.highDensitySolver.solvedRoutes,this.solved=!0,this.activeSubSolver=null):this.highDensitySolver.failed\u0026\u0026(this.error=this.highDensitySolver.error,this.failed=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.params]}visualize(){const t=this.params.nodeWithPortPoints,e=t.projectedRect,n={polygons:[{points:t.polygon,fill:\"rgba(60, 160, 220, 0.10)\",stroke:\"rgba(40, 90, 150, 0.7)\",label:`${t.capacityMeshNodeId} polygon`},...e?[{points:e.targetQuad,fill:\"rgba(255, 165, 0, 0.08)\",stroke:\"rgba(255, 120, 0, 0.65)\",label:`${t.capacityMeshNodeId} distortion target`}]:[]],rects:e?[{center:e.center,width:e.width,height:e.height,ccwRotationDegrees:e.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.14)\",stroke:\"rgba(255, 120, 0, 0.8)\",label:`${t.capacityMeshNodeId} projectedRect`}]:[],points:[...t.portPoints.map(t=\u003e({x:t.x,y:t.y,color:\"rgba(0, 80, 160, 0.85)\",label:`${t.connectionName} original`})),...this.projectedPorts.map(({projected:t})=\u003e({x:t.x,y:t.y,color:\"rgba(255, 120, 0, 0.85)\",label:`${t.connectionName} projected`}))]};return pi(n,this.highDensitySolver.visualize())}},QX=class extends si{getSolverName(){return\"PolyHighDensitySolver\"}unsolvedNodePortPoints;nodePortPoints;routes=[];routesByNodeId=new Map;failedSolvers=[];activeSubSolver=null;colorMap;connMap;viaDiameter;traceWidth;obstacleMargin;effort;nodePfById;constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a}){super(),this.nodePortPoints=[...t],this.unsolvedNodePortPoints=[...t],this.colorMap=e??{},this.connMap=n,this.viaDiameter=o??.3,this.traceWidth=i??.15,this.obstacleMargin=r??.15,this.effort=s??1,this.MAX_ITERATIONS=1e7*this.effort,this.nodePfById=a instanceof Map?new Map(a):new Map(Object.entries(a??{}))}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){const t=this.activeSubSolver.params.nodeWithPortPoints.capacityMeshNodeId,e=this.activeSubSolver.solvedRoutes;this.routesByNodeId.set(t,[...this.routesByNodeId.get(t)??[],...e]),this.routes.push(...this.activeSubSolver.solvedRoutes),this.activeSubSolver=null}else this.activeSubSolver.failed\u0026\u0026(this.failedSolvers.push(this.activeSubSolver),this.activeSubSolver=null);return}if(0===this.unsolvedNodePortPoints.length)return this.failedSolvers.length\u003e0?(this.failed=!0,void(this.error=`Failed to solve ${this.failedSolvers.length} poly nodes, ${this.failedSolvers.slice(0,5).map(t=\u003et.params.nodeWithPortPoints.capacityMeshNodeId).join(\", \")}. err0: ${this.failedSolvers[0]?.error}`)):void(this.solved=!0);const t=this.unsolvedNodePortPoints.pop();this.activeSubSolver=new KX({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort})}computeProgress(){const t=this.routes.length+this.failedSolvers.length+this.unsolvedNodePortPoints.length+(this.activeSubSolver?1:0);return 0===t?1:(this.routes.length+this.failedSolvers.length+(this.activeSubSolver?.progress??0))/t}getConstructorParams(){return[{nodePortPoints:this.nodePortPoints,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById}]}visualize(){const t={polygons:this.nodePortPoints.map(t=\u003e({points:t.polygon,fill:\"rgba(180, 180, 180, 0.05)\",stroke:\"rgba(120, 120, 120, 0.25)\",label:`${t.capacityMeshNodeId} polygon`})),rects:this.nodePortPoints.flatMap(t=\u003et.projectedRect?[{center:t.projectedRect.center,width:t.projectedRect.width,height:t.projectedRect.height,ccwRotationDegrees:t.projectedRect.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.08)\",stroke:\"rgba(255, 120, 0, 0.65)\",label:`${t.capacityMeshNodeId} projectedRect`}]:[]),lines:[],circles:[],points:this.nodePortPoints.flatMap(t=\u003et.portPoints.map(t=\u003e({x:t.x,y:t.y,color:\"rgba(80, 80, 80, 0.5)\",label:`${t.connectionName} original`})))};for(const[e,n]of this.routesByNodeId){const o=this.nodePortPoints.find(t=\u003et.capacityMeshNodeId===e),i=o?.projectedRect;if(i)for(const e of n){const n=this.colorMap[e.connectionName]??\"#0000ff\",o={...e,route:e.route.map(t=\u003e({...t,...UX(t,i)})),vias:e.vias.map(t=\u003eUX(t,i))},r=mi(o.route,e.connectionName,n);for(const n of r)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:To(n.color,.5),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?[.1,.3]:void 0});for(const i of o.vias)t.circles.push({center:i,layer:\"z0,1\",radius:e.viaDiameter/2,fill:n,label:`${e.connectionName} via`})}}const e=this.activeSubSolver?.visualize();return e\u0026\u0026t.polygons.push(...this.unsolvedNodePortPoints.map(t=\u003e({points:t.polygon,fill:\"rgba(180, 180, 180, 0.08)\",stroke:\"rgba(120, 120, 120, 0.4)\",label:t.capacityMeshNodeId}))),e?pi(t,e):t}},tV=t=\u003e{const{o:e,a:n,b:o}=t;return(n.x-e.x)*(o.y-e.y)-(n.y-e.y)*(o.x-e.x)},eV=(t,e)=\u003e{const n=[...new Set(t)].map(t=\u003e{const n=e[t];return n?{i:t,x:n.x,y:n.y}:null}).filter(t=\u003enull!==t);if(n.sort((t,e)=\u003et.x-e.x||t.y-e.y),n.length\u003c=2)return n.map(t=\u003et.i);const o=[],i=[];for(const t of n){for(;o.length\u003e=2;){const e=o[o.length-2],n=o[o.length-1];if(!e||!n||tV({o:e,a:n,b:t})\u003e1e-10)break;o.pop()}o.push(t)}for(let t=n.length-1;t\u003e=0;t--){const e=n[t];if(e){for(;i.length\u003e=2;){const t=i[i.length-2],n=i[i.length-1];if(!t||!n||tV({o:t,a:n,b:e})\u003e1e-10)break;i.pop()}i.push(e)}}return o.pop(),i.pop(),o.concat(i).map(t=\u003et.i)},nV=t=\u003e{const e=Math.max(0,Math.min(30,Math.floor(t)));return 0===e?0:(1\u003c\u003ce)-1},oV=(t,e=31)=\u003e{const n=[],o=Math.max(0,Math.min(31,Math.floor(e)));for(let e=0;e\u003co;e++)t\u00261\u003c\u003ce\u0026\u0026n.push(e);return n},iV=t=\u003e{let e=0;for(const n of t)Number.isInteger(n)\u0026\u0026n\u003e=0\u0026\u0026n\u003c31\u0026\u0026(e|=1\u003c\u003cn);return e},rV=(t,e)=\u003e{const n=t.trim().toLowerCase();if(\"top\"===n)return 0;if(\"bottom\"===n)return Math.max(0,e-1);const o=n.match(/^inner(\\d+)$/);if(o?.[1]){const t=Number(o[1]);return t\u003e=0\u0026\u0026t\u003ce?t:void 0}const i=n.match(/^layer(\\d+)$/);if(i?.[1]){const t=Number(i[1])-1;return t\u003e=0\u0026\u0026t\u003ce?t:void 0}const r=n.match(/^z(\\d+)$/);if(r?.[1]){const t=Number(r[1]);return t\u003e=0\u0026\u0026t\u003ce?t:void 0}},sV=(t,e)=\u003e{const n=nV(e),o=t.zLayers;if(Array.isArray(o)\u0026\u0026o.length\u003e0)return iV(o)\u0026n;const i=t.layers;if(Array.isArray(i)\u0026\u0026i.length\u003e0){let t=0;for(const n of i){const o=rV(n,e);void 0!==o\u0026\u0026(t|=1\u003c\u003co)}return t\u0026n}return n},aV=.1,cV=.15,lV=aV+cV,dV=3*lV/4,hV=5,uV=1e-9,pV=t=\u003eMath.round(1e6*t)/1e6,mV=t=\u003e`${pV(t.x)},${pV(t.y)}`,gV=(t,e)=\u003e{const n=mV(t),o=mV(e);return n\u003co?`${n}|${o}`:`${o}|${n}`},fV=t=\u003e{let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t)e=Math.min(e,r.x),n=Math.max(n,r.x),o=Math.min(o,r.y),i=Math.max(i,r.y);return{minX:e,maxX:n,minY:o,maxY:i}},yV=(t,e)=\u003e{const n=t.x\u003ce.minX?e.minX-t.x:t.x\u003ee.maxX?t.x-e.maxX:0,o=t.y\u003ce.minY?e.minY-t.y:t.y\u003ee.maxY?t.y-e.maxY:0;return n*n+o*o},_V=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c1e-18)return!1;const s=((t.x-e.x)*o+(t.y-e.y)*i)/r;if(s\u003c-1e-9||s\u003e1+1e-9)return!1;const a=e.x+s*o,c=e.y+s*i;return(t.x-a)**2+(t.y-c)**2\u003c1e-12},bV=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003cuV)return(t.x-e.x)**2+(t.y-e.y)**2;const s=Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r)),a=e.x+s*o,c=e.y+s*i;return(t.x-a)**2+(t.y-c)**2},xV=(t,e)=\u003e({x:(t.x+e.x)/2,y:(t.y+e.y)/2}),vV=(t,e,n,o=.001)=\u003e{const i=o*o;return((t,e)=\u003e{let n=Number.POSITIVE_INFINITY;for(let o=0;o\u003ce.length;o++){const i=e[o],r=e[(o+1)%e.length];n=Math.min(n,bV(t,i,r))}return n})(xV(t,e),n)\u003c=i},SV=(t,e)=\u003e{let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];if(_V(t,r,s))return!0;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y+1e-12)+r.x\u0026\u0026(n=!n)}return n},IV=(t,e,n,o)=\u003e{const i=e.x-t.x,r=e.y-t.y,s=o.x-n.x,a=o.y-n.y,c=i*a-r*s;if(Math.abs(c)\u003cuV){for(const i of[t,e])if(_V(i,n,o))return i;for(const i of[n,o])if(_V(i,t,e))return i;return}const l=((n.x-t.x)*a-(n.y-t.y)*s)/c,d=((n.x-t.x)*r-(n.y-t.y)*i)/c;if(!(l\u003c-1e-9||l\u003e1.000000001||d\u003c-1e-9||d\u003e1.000000001))return{x:t.x+l*i,y:t.y+l*r}},CV=(t,e)=\u003e{for(const n of t)if(SV(n,e))return n;for(const n of e)if(SV(n,t))return n;for(let n=0;n\u003ct.length;n++){const o=t[n],i=t[(n+1)%t.length];for(let t=0;t\u003ce.length;t++){const n=e[t],r=e[(t+1)%e.length],s=IV(o,i,n,r);if(s)return s}}},PV=(t,e=1e-6)=\u003e[{x:t.x-e,y:t.y-e},{x:t.x+e,y:t.y-e},{x:t.x,y:t.y+e}],MV=(t,e,n,o,i)=\u003e{const r=e.x-t.x,s=e.y-t.y,a=Math.hypot(r,s);if(a\u003cuV)return[];const c=Number.isFinite(n)\u0026\u0026n\u003euV?n:lV,l=Number.isFinite(o)?Math.max(0,o):dV,d=Math.min(l,a/2),h=a-2*d;if(h\u003c=.75*c)return[{x:(t.x+e.x)/2,y:(t.y+e.y)/2,distToCentermostPortOnZ:0,cramped:!0}];const u=Math.max(1,Math.floor(h/c)+1),p=Number.isFinite(i)\u0026\u0026i\u003e0?Math.floor(i):hV,m=u\u003ep?p+Math.floor(u/4):u;if(m\u003c=1)return[{x:(t.x+e.x)/2,y:(t.y+e.y)/2,distToCentermostPortOnZ:0,cramped:!1}];const g=a/2,f=Array.from({length:m},(e,n)=\u003e{const o=d+h*n/(m-1),i=o/a;return{x:t.x+r*i,y:t.y+s*i,distanceFromStart:o}}),y=f.reduce((t,e)=\u003eMath.abs(e.distanceFromStart-g)\u003cMath.abs(t-g)?e.distanceFromStart:t,f[0].distanceFromStart);return f.map(({x:t,y:e,distanceFromStart:n})=\u003e({x:t,y:e,distToCentermostPortOnZ:Math.abs(n-y),cramped:!1}))},NV=(t,e)=\u003e{if(!(Math.hypot(e.x-t.x,e.y-t.y)\u003cuV))return{...xV(t,e),distToCentermostPortOnZ:0,cramped:!1}},wV=(t,e)=\u003e{if(\"object\"!=typeof t||null===t)return;const n=t[e];return\"string\"==typeof n?n:void 0},TV=t=\u003e{const e=new Set,n=t=\u003e{\"string\"==typeof t\u0026\u0026t.length\u003e0\u0026\u0026e.add(t)},o=t=\u003e{n(t.pointId),n(t.pcb_port_id)};n(t.connectionId),n(t.mutuallyConnectedNetworkId),o(t.start),o(t.end);const i=t.simpleRouteConnection;n(wV(i,\"name\")),n(wV(i,\"source_trace_id\")),n(wV(i,\"rootConnectionName\"));const r=\"object\"==typeof i\u0026\u0026null!==i?i.pointsToConnect:void 0;if(Array.isArray(r))for(const t of r)o(t);return e},RV=t=\u003e{const{regions:e,availableZ:n,layerCount:o,connections:i=[],obstacleRegions:r=[],regionIdPrefix:s=\"free\",portIdPrefix:a=\"shared-port\",traceWidth:c=aV,obstacleMargin:l=cV,portSpacing:d=c+l,portMarginFromSegmentEndpoint:h=3*d/4,maxDensePortsBeforeDecimation:u=hV}=t,p=Array.from({length:o},(t,e)=\u003ee),m=new Map,g=new Map,f=t=\u003et.mutuallyConnectedNetworkId??t.connectionId;for(const t of i){const e=f(t);let n=m.get(e);void 0===n\u0026\u0026(n=m.size,m.set(e,n));for(const e of TV(t))g.has(e)||g.set(e,n)}const y=e.map((t,e)=\u003e{const o=fV(t);return{regionId:`${s}-${e}`,pointIds:[],d:{polygon:t,availableZ:n?.[e]??p,center:{x:(o.minX+o.maxX)/2,y:(o.minY+o.maxY)/2},width:o.maxX-o.minX,height:o.maxY-o.minY}}}),_=y.map((t,e)=\u003e({regionId:t.regionId,serializedRegionIndex:e,polygon:t.d.polygon,availableZ:t.d.availableZ,bounds:fV(t.d.polygon),isObstacle:!1,netId:void 0})),b=r.flatMap((t,e)=\u003e{if(t.polygon.length\u003c3)return[];const n=(t=\u003e{if(Number.isInteger(t.netId)\u0026\u0026t.netId\u003e=0)return t.netId;if(\"string\"==typeof t.mutuallyConnectedNetworkId)return m.get(t.mutuallyConnectedNetworkId);for(const e of t.connectedTo??[]){const t=g.get(e);if(void 0!==t)return t}})(t);if(void 0===n)return[];const o=t.polygon,i=fV(o),r=t.availableZ??p,s=t.regionId??`obstacle-${e}`,a=y.length;y.push({regionId:s,pointIds:[],d:{...t.d??{},polygon:o,availableZ:r,center:{x:(i.minX+i.maxX)/2,y:(i.minY+i.maxY)/2},width:i.maxX-i.minX,height:i.maxY-i.minY,_containsObstacle:!0,_containsTarget:!0,netId:n}});const c={regionId:s,serializedRegionIndex:a,polygon:o,availableZ:r,bounds:i,isObstacle:!0,netId:n};return _.push(c),[c]}),x=[],v=new Map;for(let t=0;t\u003ce.length;t++){const n=e[t];for(let e=0;e\u003cn.length;e++){const o=n[e],i=n[(e+1)%n.length],r=gV(o,i),s=v.get(r)??[];s.push({regionIndex:t,a:o,b:i}),v.set(r,s)}}let S=0;const I=t=\u003e{const{region1Id:e,region2Id:n,pointIndex:o,portPoint:i,z:r,portIdSuffix:s}=t,c=`${a}-${String(S).padStart(5,\"0\")}::p${o}::z${r}${s??\"\"}`;return x.push({portId:c,region1Id:e,region2Id:n,d:{portId:c,x:i.x,y:i.y,z:r,distToCentermostPortOnZ:i.distToCentermostPortOnZ,...i.cramped?{cramped:!0}:{}}}),S+=1,c};for(const t of v.values()){if(2!==t.length)continue;const[e,o]=t,i=n?.[e.regionIndex]??p,r=n?.[o.regionIndex]??p,a=i.filter(t=\u003er.includes(t));if(0===a.length)continue;const c=MV(e.a,e.b,d,h,u);if(0!==c.length)for(let t=0;t\u003cc.length;t++){const n=c[t];for(const i of a){if(b.some(t=\u003et.availableZ.includes(i)\u0026\u0026vV(e.a,e.b,t.polygon)))continue;const r=I({region1Id:`${s}-${e.regionIndex}`,region2Id:`${s}-${o.regionIndex}`,pointIndex:t,portPoint:n,z:i});y[e.regionIndex].pointIds.push(r),y[o.regionIndex].pointIds.push(r)}}}for(const t of b)for(const e of v.values())for(const o of e){if(!vV(o.a,o.b,t.polygon))continue;const e=(n?.[o.regionIndex]??p).filter(e=\u003et.availableZ.includes(e));if(0===e.length)continue;const i=NV(o.a,o.b);if(i)for(const n of e){const e=I({region1Id:`${s}-${o.regionIndex}`,region2Id:t.regionId,pointIndex:0,portPoint:i,z:n,portIdSuffix:\"::obstacle\"});y[o.regionIndex].pointIds.push(e),y[t.serializedRegionIndex].pointIds.push(e)}}for(let t=0;t\u003cb.length;t++){const e=b[t];for(let n=t+1;n\u003cb.length;n++){const t=b[n];if(e.netId!==t.netId)continue;const o=e.availableZ.filter(e=\u003et.availableZ.includes(e));if(0===o.length)continue;const i=CV(e.polygon,t.polygon);if(i)for(const n of o){const o=I({region1Id:e.regionId,region2Id:t.regionId,pointIndex:0,portPoint:{x:i.x,y:i.y,distToCentermostPortOnZ:0},z:n,portIdSuffix:\"::obstacle-contact\"});y[e.serializedRegionIndex].pointIds.push(o),y[t.serializedRegionIndex].pointIds.push(o)}}}const C=(t,e)=\u003e{const n=((t,e)=\u003e{if(Number.isInteger(t.z)\u0026\u0026t.z\u003e=0\u0026\u0026t.z\u003ce)return[t.z];if(Array.isArray(t.zLayers)\u0026\u0026t.zLayers.length\u003e0)return t.zLayers.filter(t=\u003eNumber.isInteger(t)\u0026\u0026t\u003e=0\u0026\u0026t\u003ce);if(\"string\"==typeof t.layer){const n=rV(t.layer,e);return void 0===n?[]:[n]}return Array.isArray(t.layers)\u0026\u0026t.layers.length\u003e0?t.layers.map(t=\u003erV(t,e)).filter(t=\u003evoid 0!==t):[0]})(t,o);let i;const r=_.filter(t=\u003et.isObstacle\u0026\u0026(void 0===e||t.netId===e));for(const e of r){const o=n.find(t=\u003ee.availableZ.includes(t))??e.availableZ[0];if(void 0!==o\u0026\u0026SV(t,e.polygon))return{regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o}}for(const e of _.filter(t=\u003e!t.isObstacle)){const o=n.find(t=\u003ee.availableZ.includes(t))??e.availableZ[0];if(void 0===o)continue;if(SV(t,e.polygon))return{regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o};const r=yV(t,e.bounds);(!i||r\u003ci.distanceSq)\u0026\u0026(i={regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o,distanceSq:r})}return i},P=[];for(const t of i){const e=m.get(f(t)),n=C(t.start,e),o=C(t.end,e);if(!n||!o)throw new Error(`Could not map connection \"${t.connectionId}\" endpoint into a generated region`);const i=`terminal-start-${t.connectionId}`,r=`terminal-end-${t.connectionId}`,s=`terminal-start-port-${t.connectionId}`,a=`terminal-end-port-${t.connectionId}`;y.push({regionId:i,pointIds:[s],d:{polygon:PV(t.start),availableZ:[n.z],center:{x:t.start.x,y:t.start.y},width:1e-6,height:1e-6,_containsTarget:!0}}),y.push({regionId:r,pointIds:[a],d:{polygon:PV(t.end),availableZ:[o.z],center:{x:t.end.x,y:t.end.y},width:1e-6,height:1e-6,_containsTarget:!0}}),x.push({portId:s,region1Id:n.regionId,region2Id:i,d:{portId:s,x:t.start.x,y:t.start.y,z:n.z,distToCentermostPortOnZ:0}}),x.push({portId:a,region1Id:o.regionId,region2Id:r,d:{portId:a,x:t.end.x,y:t.end.y,z:o.z,distToCentermostPortOnZ:0}}),y[n.serializedRegionIndex].pointIds.push(s),y[o.serializedRegionIndex].pointIds.push(a),P.push({connectionId:t.connectionId,mutuallyConnectedNetworkId:t.mutuallyConnectedNetworkId,startRegionId:i,endRegionId:r,simpleRouteConnection:t.simpleRouteConnection})}return{regions:y,ports:x,connections:P}},EV=t=\u003e{const{polygon:e,clearance:n,verticesOnly:o=!1}=t,i=e.points,r=i.length;if(r\u003c3)return[];const s=new xO(i.map(t=\u003emO(t.x,t.y))).orientation()===fE.CCW,a=[];for(let t=0;t\u003cr;t++){const e=i[t],o=i[(t+1)%r],c=gO(o.x-e.x,o.y-e.y);if(0===c.length){a.push(_O(mO(e.x,e.y),gO(1,0)));continue}const l=c.normalize(),d=s?gO(l.y,-l.x):gO(-l.y,l.x),h=mO(e.x+n*d.x,e.y+n*d.y);a.push(_O(h,d))}const c=[];for(let t=0;t\u003cr;t++){const e=a[(t-1+r)%r],n=a[t],o=e.intersect(n);if(o.length\u003e0){const t=o[0];c.push({x:t.x,y:t.y})}else c.push({x:n.pt.x,y:n.pt.y})}if(o)return c;const l=[];for(let t=0;t\u003cr;t++){const e=c[t],n=c[(t+1)%r],o=fO(mO(e.x,e.y),mO(n.x,n.y)).length,i=Math.max(2,Math.ceil(o/20));for(let t=0;t\u003ci;t++){const o=t/i;l.push({x:e.x+o*(n.x-e.x),y:e.y+o*(n.y-e.y)})}}return l},AV=t=\u003e{const{localX:e,localY:n,rect:o}=t,i=Math.cos(o.ccwRotation),r=Math.sin(o.ccwRotation);return{x:o.center.x+e*i-n*r,y:o.center.y+e*r+n*i}},OV=t=\u003enew xO(t.map(t=\u003emO(t.x,t.y))),kV=t=\u003e{const e=[];for(const n of t.faces){const t=[];for(const e of n.vertices)t.push({x:e.x,y:e.y});t.length\u003e=3\u0026\u0026e.push(t)}return e},LV=(t,e,n)=\u003e{const o=e.length;e.push(...t);const i=t.length;for(let t=0;t\u003ci;t++)n.push([o+t,o+(t+1)%i])},DV=t=\u003e{const{bounds:e,vias:n,clearance:o,rects:i,polygons:r=[],viaSegments:s=8,preserveObstacleBoundaries:a=!1}=t,c=[],l=[],d=[],{minX:h,maxX:u,minY:p,maxY:m}=e,g=10,f=[];for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:h+e*(u-h),y:p})}for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:u,y:p+e*(m-p)})}for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:u-e*(u-h),y:m})}for(let t=0;t\u003cg;t++){const e=t/g;f.push({x:h,y:m-e*(m-p)})}d.push(l.length),LV(f,c,l);const y=[];for(const t of n){const e=t.diameter/2+o,n=[];for(let o=0;o\u003cs;o++){const i=2*Math.PI*o/s;n.push({x:t.center.x+e*Math.cos(i),y:t.center.y+e*Math.sin(i)})}y.push(n)}for(const t of i){const e=t.width/2+o,n=t.height/2+o,i=[AV({localX:-e,localY:-n,rect:t}),AV({localX:e,localY:-n,rect:t}),AV({localX:e,localY:n,rect:t}),AV({localX:-e,localY:n,rect:t})];y.push(i)}for(const t of r){if(t.points.length\u003c3)continue;const e=EV({polygon:t,clearance:o,verticesOnly:!0});y.push(e)}const _=a?y:(t=\u003e{if(t.length\u003c=1)return t;try{let e=t.map(OV);for(let t=0;t\u003c2;t++){const t=[],n=new Set;for(let o=0;o\u003ce.length;o++){if(n.has(o))continue;let i=e[o];for(let t=o+1;t\u003ce.length;t++){if(n.has(t))continue;const o=i.box,r=e[t].box;if(!(o.xmin\u003er.xmax+1e-6||o.xmax\u003cr.xmin-1e-6||o.ymin\u003er.ymax+1e-6||o.ymax\u003cr.ymin-1e-6))try{const o=WA.unify(i,e[t]);o.faces.size\u003e0\u0026\u0026(i=o,n.add(t))}catch{}}t.push(i),n.add(o)}e=t}const n=[];for(const t of e){const e=kV(t);n.push(...e)}return n.length\u003e0?n:t}catch{return t}})(y);for(const t of _)d.push(l.length),LV(t,c,l);const b=((t,e,n)=\u003e{const o=new Array(e.length);for(let t=0;t\u003ce.length;t++)for(let e=n.length-1;e\u003e=0;e--)if(t\u003e=n[e]){o[t]=e;break}const i=new Map,r=t.slice();for(let t=0;t\u003ce.length;t++)for(let n=t+1;n\u003ce.length;n++){if(o[t]===o[n])continue;const[s,a]=e[t],[c,l]=e[n],d=r[s],h=r[a],u=r[c],p=r[l],m=h.x-d.x,g=h.y-d.y,f=p.x-u.x,y=p.y-u.y,_=m*y-g*f;if(Math.abs(_)\u003c1e-10)continue;const b=((u.x-d.x)*y-(u.y-d.y)*f)/_,x=((u.x-d.x)*g-(u.y-d.y)*m)/_;if(b\u003e1e-6\u0026\u0026b\u003c.999999\u0026\u0026x\u003e1e-6\u0026\u0026x\u003c.999999){const e=d.x+b*m,o=d.y+b*g,s=r.length;r.push({x:e,y:o}),i.has(t)||i.set(t,[]),i.get(t).push({t:b,idx:s}),i.has(n)||i.set(n,[]),i.get(n).push({t:x,idx:s})}}if(0===i.size)return{pts:t,constraintEdges:e,hadCrossings:!1};const s=[];for(let t=0;t\u003ce.length;t++){const n=i.get(t);if(!n||0===n.length){s.push(e[t]);continue}n.sort((t,e)=\u003et.t-e.t);const[o,r]=e[t];let a=o;for(const t of n)s.push([a,t.idx]),a=t.idx;s.push([a,r])}return{pts:r,constraintEdges:s,hadCrossings:!0}})(c,l,d);return{pts:b.pts.map((t,e)=\u003e({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)})),constraintEdges:b.constraintEdges,hadCrossings:b.hadCrossings}},zV=t=\u003e{const{p:e,a:n,b:o}=t,i=o.x-n.x,r=o.y-n.y,s=i*i+r*r;if(s\u003c1e-10)return Math.hypot(e.x-n.x,e.y-n.y);let a=((e.x-n.x)*i+(e.y-n.y)*r)/s;return a=Math.max(0,Math.min(1,a)),Math.hypot(e.x-n.x-a*i,e.y-n.y-a*r)},FV=(t,e)=\u003e{if(t.length\u003c=3)return 0;const n=eV(t,e),o=new Set(n),i=n.map(t=\u003ee[t]).filter(t=\u003eBoolean(t));let r=0;for(const n of t){if(o.has(n))continue;const t=e[n];if(!t)continue;let s=Number.POSITIVE_INFINITY;for(let e=0;e\u003ci.length;e++){const n=i[e],o=i[(e+1)%i.length];n\u0026\u0026o\u0026\u0026(s=Math.min(s,zV({p:t,a:n,b:o})))}r=Math.max(r,s)}return r},BV=(t,e)=\u003et\u003ce?1e5*t+e:1e5*e+t,jV=(t,e)=\u003e{const n=t.map((e,n)=\u003e[e,t[(n+1)%t.length]]),o=e.map((t,n)=\u003e[t,e[(n+1)%e.length]]),i=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,r]of o)void 0!==r\u0026\u0026t===r\u0026\u0026e===n\u0026\u0026i.add(BV(t,e));if(0===i.size)return null;const r=[];for(const[t,e]of n)void 0!==e\u0026\u0026(i.has(BV(t,e))||r.push([t,e]));for(const[t,e]of o)void 0!==e\u0026\u0026(i.has(BV(t,e))||r.push([t,e]));if(0===r.length)return null;const s=new Map;for(const[t,e]of r)s.set(t,e);const a=r[0]?.[0];if(void 0===a)return null;const c=[a];let l=s.get(a),d=0;for(;void 0!==l\u0026\u0026l!==a\u0026\u0026d++\u003cr.length+5;)c.push(l),l=s.get(l);return l!==a||c.length!==r.length?null:c},$V=(t,e)=\u003et\u003ce?1e5*t+e:1e5*e+t,YV=(t,e)=\u003et\u003ce?1e5*t+e:1e5*e+t,XV=c(T(),1),VV=t=\u003e{const{a:e,b:n,c:o}=t,i=2*(e.x*(n.y-o.y)+n.x*(o.y-e.y)+o.x*(e.y-n.y));if(Math.abs(i)\u003c1e-10)return{x:0,y:0,r2:1e18};const r=e.x*e.x+e.y*e.y,s=n.x*n.x+n.y*n.y,a=o.x*o.x+o.y*o.y,c=(r*(n.y-o.y)+s*(o.y-e.y)+a*(e.y-n.y))/i,l=(r*(o.x-n.x)+s*(e.x-o.x)+a*(n.x-e.x))/i;return{x:c,y:l,r2:(e.x-c)**2+(e.y-l)**2}},WV=(t,e,n)=\u003e[t.a,t.b,t.c].includes(e)\u0026\u0026[t.a,t.b,t.c].includes(n),HV=t=\u003e{const{px:e,py:n,polygonPoints:o,clearance:i}=t;if(o.length\u003c3)return!1;const r=o.map(t=\u003emO(t.x,t.y)),s=[];for(let t=0;t\u003cr.length;t++){const e=r[t],n=r[(t+1)%r.length];s.push(fO(e,n))}const a=new xO;a.addFace(s);const c=mO(e,n);if(a.contains(c))return!0;const[l]=a.distanceTo(c);return l\u003ci-.1},GV=t=\u003e{const{point:e,via:n,clearance:o}=t,i=e.x-n.center.x,r=e.y-n.center.y,s=n.diameter/2+o;return i*i+r*r\u003c=s*s+1e-9},UV=t=\u003e{const{point:e,rect:n,clearance:o}=t,i=Math.cos(-n.ccwRotation),r=Math.sin(-n.ccwRotation),s=e.x-n.center.x,a=e.y-n.center.y,c=s*i-a*r,l=s*r+a*i;return Math.abs(c)\u003c=n.width/2+o+1e-9\u0026\u0026Math.abs(l)\u003c=n.height/2+o+1e-9},ZV=t=\u003eHV({px:t.point.x,py:t.point.y,polygonPoints:t.polygon.points,clearance:t.clearance}),qV=(t,e)=\u003et.x\u003e=e.minX-1e-9\u0026\u0026t.x\u003c=e.maxX+1e-9\u0026\u0026t.y\u003e=e.minY-1e-9\u0026\u0026t.y\u003c=e.maxY+1e-9,JV=t=\u003e{const{point:e,vias:n,rects:o,polygons:i,clearance:r,layerCount:s}=t;let a=0;for(const t of n)GV({point:e,via:t,clearance:r})\u0026\u0026(a|=sV(t,s));for(const t of o)UV({point:e,rect:t,clearance:r})\u0026\u0026(a|=sV(t,s));for(const t of i)ZV({point:e,polygon:t,clearance:r})\u0026\u0026(a|=sV(t,s));return a},KV=t=\u003e{const{triangles:e,pts:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a,layerCount:c}=t,l=nV(c),d=[],h=[];for(const[t,u,p]of e){const e=n[t],m=n[u],g=n[p];if(!e||!m||!g)continue;const f={x:(e.x+m.x+g.x)/3,y:(e.y+m.y+g.y)/3};if(!qV(f,o))continue;const y=l\u0026~JV({point:f,vias:i,rects:s,polygons:a,clearance:r,layerCount:c});0!==y\u0026\u0026(d.push([t,u,p]),h.push(oV(y,c)))}return{triangles:d,triangleAvailableZ:h}},QV=t=\u003e{const{triangles:e,pts:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a}=t;return e.filter(([t,e,c])=\u003e{const l=n[t],d=n[e],h=n[c];if(!l||!d||!h)return!1;if(!(t=\u003e{const{px:e,py:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a}=t,{minX:c,maxX:l,minY:d,maxY:h}=o,u=1e-6*Math.max(l-c,h-d,1);if(e\u003cc-u||e\u003el+u||n\u003cd-u||n\u003eh+u)return!1;for(const t of i){const o=t.diameter/2+r,i=Math.max(0,o-u);if((e-t.center.x)**2+(n-t.center.y)**2\u003ci*i)return!1}for(const t of s){const o=t.width/2+r,i=t.height/2+r,s=Math.max(0,o-u),a=Math.max(0,i-u),c=e-t.center.x,l=n-t.center.y,d=Math.cos(t.ccwRotation),h=Math.sin(t.ccwRotation),p=c*d+l*h,m=-c*h+l*d;if(Math.abs(p)\u003cs\u0026\u0026Math.abs(m)\u003ca)return!1}for(const t of a)if(HV({px:e,py:n,polygonPoints:t.points,clearance:r}))return!1;return!0})({px:(l.x+d.x+h.x)/3,py:(l.y+d.y+h.y)/3,bounds:o,vias:i,clearance:r,rects:s,polygons:a}))return!1;if(a.length\u003e0){const t=[l,d,h,{x:(l.x+d.x)/2,y:(l.y+d.y)/2},{x:(d.x+h.x)/2,y:(d.y+h.y)/2},{x:(h.x+l.x)/2,y:(h.y+l.y)/2}];for(const e of t)for(const t of a)if(HV({px:e.x,py:e.y,polygonPoints:t.points,clearance:r}))return!1}return!0})},tW=t=\u003evoid 0!==t,eW=t=\u003e{const{bounds:e,clearance:n,concavityTolerance:o}=t,i=t.vias??[],r=t.rects??[],s=t.polygons??[];let a,c,l;if(!1!==t.useConstrainedDelaunay){const o=DV({bounds:e,vias:i,clearance:n,rects:r,polygons:s,viaSegments:t.viaSegments,preserveObstacleBoundaries:void 0!==t.layerCount});a=o.pts;const d=((t,e,n={})=\u003e{const o=t.map(t=\u003e[t.x,t.y]);return(0,XV.default)(o,e,{exterior:!!n.includeConstraintInteriors})})(a,o.constraintEdges,{includeConstraintInteriors:void 0!==t.layerCount});if(void 0!==t.layerCount){const o=KV({triangles:d,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s,layerCount:t.layerCount});c=o.triangles,l=o.triangleAvailableZ}else{c=i.length\u003e0||r.length\u003e0||s.length\u003e0?QV({triangles:d,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s}):d}}else{a=(t=\u003e{const{bounds:e,vias:n,clearance:o,rects:i,polygons:r=[],viaSegments:s=24}=t,a=[],{minX:c,maxX:l,minY:d,maxY:h}=e;a.push({x:c,y:d},{x:l,y:d},{x:l,y:h},{x:c,y:h});for(let t=1;t\u003c10;t++){const e=t/10;a.push({x:c+e*(l-c),y:d}),a.push({x:l,y:d+e*(h-d)}),a.push({x:l-e*(l-c),y:h}),a.push({x:c,y:h-e*(h-d)})}for(const t of n){const e=t.diameter/2+o;for(let n=0;n\u003cs;n++){const o=2*Math.PI*n/s;a.push({x:t.center.x+e*Math.cos(o),y:t.center.y+e*Math.sin(o)})}}for(const t of i){const e=t.width/2+o,n=t.height/2+o,i=Math.max(2,Math.ceil(Math.max(2*e,2*n)/20));for(let o=0;o\u003ci;o++){const r=o/i;a.push(AV({localX:2*r*e-e,localY:-n,rect:t})),a.push(AV({localX:e,localY:2*r*n-n,rect:t})),a.push(AV({localX:e-2*r*e,localY:n,rect:t})),a.push(AV({localX:-e,localY:n-2*r*n,rect:t}))}}for(const t of r){if(t.points.length\u003c3)continue;const e=EV({polygon:t,clearance:o});a.push(...e)}return a.map((t,e)=\u003e({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))})({bounds:e,vias:i,clearance:n,rects:r,polygons:s,viaSegments:t.viaSegments});const o=(t=\u003e{const e=t.map((t,e)=\u003e({...t,i:e}));if(e.length\u003c3)return[];let n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),o=Math.min(o,t.y),i=Math.max(i,t.x),r=Math.max(r,t.y);const s=Math.max(i-n,r-o)||1,a=(n+i)/2,c=(o+r)/2,l={x:a-30*s,y:c-s,i:-1},d={x:a,y:c+30*s,i:-2},h={x:a+30*s,y:c-s,i:-3};let u=[{a:l,b:d,c:h,cc:VV({a:l,b:d,c:h})}];for(const t of e){const e=u.filter(e=\u003e{const n=t.x-e.cc.x,o=t.y-e.cc.y;return n*n+o*o\u003ce.cc.r2+1e-6}),n=new Set(e),o=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[i,r]of n){let n=!1;for(const o of e)if(o!==t\u0026\u0026WV(o,i,r)){n=!0;break}n||o.push([i,r])}}u=u.filter(t=\u003e!n.has(t));for(const[e,n]of o)u.push({a:e,b:n,c:t,cc:VV({a:e,b:n,c:t})})}return u.filter(t=\u003et.a.i\u003e=0\u0026\u0026t.b.i\u003e=0\u0026\u0026t.c.i\u003e=0).map(t=\u003e[t.a.i,t.b.i,t.c.i])})(a);if(void 0!==t.layerCount){const d=KV({triangles:o,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s,layerCount:t.layerCount});c=d.triangles,l=d.triangleAvailableZ}else c=QV({triangles:o,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s})}const{cells:d,depths:h,availableZ:u}=!1!==t.usePolyanyaMerge?(t=\u003e{const{triangles:e,pts:n,cellAvailableZ:o,layerMergeMode:i=\"same\"}=t;if(!e.length)return{cells:[],depths:[]};const r=e.length,s=e.map(([t,e,o])=\u003e{const i=n[t],r=n[e],s=n[o];return i\u0026\u0026r\u0026\u0026s\u0026\u0026tV({o:i,a:r,b:s})\u003c0?[t,o,e]:[t,e,o]}),a=o?.map(iV),c=new Array(r).fill(null);for(let t=0;t\u003cr;t++)c[t]=new Map;function l(){for(let t=0;t\u003cc.length;t++)c[t]\u0026\u0026c[t].clear();const t=new Map;for(let e=0;e\u003cs.length;e++){const n=s[e];if(n)for(let o=0;o\u003cn.length;o++){const i=n[o],r=n[(o+1)%n.length],s=YV(i,r),a=t.get(s);a?(c[e].set(o,{neighbor:a.cellIdx,neighborEdge:a.edgePos}),c[a.cellIdx].set(a.edgePos,{neighbor:e,neighborEdge:o})):t.set(s,{cellIdx:e,edgePos:o})}}}function d(t){let e=0;for(let o=0;o\u003ct.length;o++){const i=n[t[o]],r=n[t[(o+1)%t.length]];e+=i.x*r.y-r.x*i.y}return Math.abs(e)/2}function h(t,e){const n=s[t],o=c[t],i=n.length;let r=-1;for(const[t,n]of o)if(n.neighbor===e){r=t;break}if(-1===r)return null;let a=r;for(;;){const t=(a-1+i)%i;if(t===r)break;const n=o.get(t);if(!n||n.neighbor!==e)break;a=t}let l=r;for(;;){const t=(l+1)%i;if(t===a)break;const n=o.get(t);if(!n||n.neighbor!==e)break;l=t}return{firstK:a,lastK:l,sharedCount:(l-a+i)%i+1}}function u(t,e){const o=s[t],r=s[e],c=h(t,e);if(!c)return!1;const{firstK:l,lastK:d,sharedCount:u}=c,p=o.length,m=r.length,g=o[l],f=o[(d+1)%p];let y=-1;for(let t=0;t\u003cm;t++)if(r[t]===g){y=t;break}if(-1===y)return!1;const _=(y-u+m)%m;if(r[_]!==f)return!1;const b=n[o[(l-1+p)%p]],x=n[g],v=n[r[(y+1)%m]];if(tV({o:b,a:x,b:v})\u003c-1e-8)return!1;const S=n[r[(_-1+m)%m]],I=n[f],C=n[o[(d+2)%p]];if(tV({o:S,a:I,b:C})\u003c-1e-8)return!1;if(a){if(0===(a[t]\u0026a[e]))return!1;if(\"same\"===i\u0026\u0026a[t]!==a[e])return!1}return!0}function p(t,e){const n=s[t],o=s[e],i=h(t,e),{firstK:r,lastK:c,sharedCount:l}=i,d=n.length,u=o.length,p=n[r],m=n[(c+1)%d];let g=-1;for(let t=0;t\u003cu;t++)if(o[t]===p){g=t;break}const f=[];f.push(p);const y=u-l-1;for(let t=1;t\u003c=y;t++)f.push(o[(g+t)%u]);f.push(m);const _=d-l-1;for(let t=2;t\u003c=_+1;t++)f.push(n[(c+t)%d]);s[t]=f,s[e]=null,a\u0026\u0026(a[t]=a[t]\u0026a[e],a[e]=0)}l();let m=!0;for(;m;){m=!1,l();for(let t=0;t\u003cs.length;t++){if(!s[t])continue;const e=c[t],n=new Set;for(const[,t]of e)s[t.neighbor]\u0026\u0026n.add(t.neighbor);if(1===n.size){const e=n.values().next().value;u(t,e)\u0026\u0026(p(t,e),m=!0)}}}l();const g=new Array(s.length).fill(0);for(let t=0;t\u003cs.length;t++)s[t]\u0026\u0026(g[t]=d(s[t]));const f=[];function y(t){f.push(t);let e=f.length-1;for(;e\u003e0;){const t=e-1\u003e\u003e1;if(f[t].area\u003e=f[e].area)break;const n=f[t];f[t]=f[e],f[e]=n,e=t}}function _(){if(0===f.length)return;const t=f[0],e=f.pop();if(f.length\u003e0){f[0]=e;let t=0;for(;;){let e=t;const n=2*t+1,o=2*t+2;if(n\u003cf.length\u0026\u0026f[n].area\u003ef[e].area\u0026\u0026(e=n),o\u003cf.length\u0026\u0026f[o].area\u003ef[e].area\u0026\u0026(e=o),e===t)break;const i=f[t];f[t]=f[e],f[e]=i,t=e}}return t}const b=new Set;for(let t=0;t\u003cs.length;t++){if(!s[t])continue;const e=c[t],n=new Set;for(const[,t]of e)s[t.neighbor]\u0026\u0026n.add(t.neighbor);for(const e of n){const n=t\u003ce?1e5*t+e:1e5*e+t;b.has(n)||(b.add(n),u(t,e)\u0026\u0026y({area:g[t]+g[e],xIdx:t,yIdx:e}))}}for(;f.length\u003e0;){const t=_(),{xIdx:e,yIdx:n}=t;if(!s[e]||!s[n])continue;const o=g[e]+g[n];if(Math.abs(o-t.area)\u003e1e-10){u(e,n)\u0026\u0026y({area:o,xIdx:e,yIdx:n});continue}if(!u(e,n))continue;p(e,n),g[e]=d(s[e]),l();const i=c[e],r=new Set;for(const[,t]of i)s[t.neighbor]\u0026\u0026r.add(t.neighbor);for(const t of r)u(e,t)\u0026\u0026y({area:g[e]+g[t],xIdx:e,yIdx:t})}const x=s.filter(t=\u003enull!==t),v=a?s.flatMap((t,e)=\u003enull===t?[]:[oV(a[e])]):void 0,S=x.map(()=\u003e0);return{cells:x,depths:S,...v?{availableZ:v}:{}}})({triangles:c,pts:a,cellAvailableZ:l,layerMergeMode:t.layerMergeMode}):(t=\u003e{const{triangles:e,pts:n,concavityTolerance:o,cellAvailableZ:i,layerMergeMode:r=\"same\"}=t;if(!e.length)return{cells:[],depths:[]};const s=e.map(([t,e,o])=\u003e{const i=n[t],r=n[e],s=n[o];return i\u0026\u0026r\u0026\u0026s\u0026\u0026tV({o:i,a:r,b:s})\u003c0?[t,o,e]:[t,e,o]}),a=i?.map(iV),c=(t,e)=\u003e{if(!a)return;const n=a[t]\u0026a[e];return 0===n||\"same\"===r\u0026\u0026a[t]!==a[e]?0:n};let l=!0,d=0;for(;l\u0026\u0026d++\u003c800;){l=!1;const t=new Map,e=s.map(()=\u003enew Set);for(let n=0;n\u003cs.length;n++){const o=s[n];if(o)for(let i=0;i\u003co.length;i++){const r=o[i],s=o[(i+1)%o.length];if(void 0===r||void 0===s)continue;const a=$V(r,s);if(t.has(a)){const o=t.get(a);void 0!==o\u0026\u0026(e[n]?.add(o),e[o]?.add(n))}else t.set(a,n)}}let i=-1,r=-1,d=null,h=Number.POSITIVE_INFINITY;for(let t=0;t\u003cs.length;t++){const a=e[t];if(a)for(const e of a){if(e\u003c=t)continue;const a=jV(s[t]??[],s[e]??[]);if(!a)continue;if(0===c(t,e))continue;const l=FV(a,n);l\u003c=o+1e-6\u0026\u0026l\u003ch\u0026\u0026(h=l,i=t,r=e,d=a)}}if(i\u003c0||r\u003c0||!d)break;s[i]=d,a\u0026\u0026(a[i]=c(i,r),a.splice(r,1)),s.splice(r,1),l=!0}const h=s.map(t=\u003eFV(t,n));return{cells:s,depths:h,...a?{availableZ:a.map(t=\u003eoV(t))}:{}}})({triangles:c,pts:a,concavityTolerance:o,cellAvailableZ:l,layerMergeMode:t.layerMergeMode}),p=a.map(t=\u003e((t,e)=\u003e({x:Math.min(e.maxX,Math.max(e.minX,t.x)),y:Math.min(e.maxY,Math.max(e.minY,t.y))}))(t,e)),m=d.map(t=\u003et.map(t=\u003ep[t]).filter(tW)),g=d.map(t=\u003eeV(t,p).map(t=\u003ep[t]).filter(tW));return{pts:p,validTris:c,regions:m,hulls:g,depths:h,...u?{availableZ:u}:{}}},nW=t=\u003e{const e=[...new Set(t.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0))].sort((t,e)=\u003et-e);if(0!==e.length)return`z${e.join(\",\")}`},oW=t=\u003e{const e=[];for(let n=0;n\u003c31;n++)t\u00261\u003c\u003cn\u0026\u0026e.push(n);return e},iW=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,rW=t=\u003eiW(t)?{...t}:void 0===t?{}:{value:t},sW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];if(iW(n)){if(\"string\"==typeof n.serializedRegionId)return n.serializedRegionId;if(\"string\"==typeof n.regionId)return n.regionId;if(\"string\"==typeof n.capacityMeshNodeId)return n.capacityMeshNodeId}return`region-${e}`},aW=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];if(iW(n)){if(\"string\"==typeof n.serializedPortId)return n.serializedPortId;if(\"string\"==typeof n.portId)return(o=n.portId).includes(\"::\")?o.slice(0,o.indexOf(\"::\")):o}var o;return`port-${e}`},cW=(t,e)=\u003e{const n=rW(t.topology.regionMetadata?.[e]);if(iW(n.center)||(n.center={x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),\"number\"!=typeof n.width\u0026\u0026(n.width=t.topology.regionWidth[e]),\"number\"!=typeof n.height\u0026\u0026(n.height=t.topology.regionHeight[e]),!Array.isArray(n.availableZ)){const o=t.topology.regionAvailableZMask?.[e]??0;0!==o\u0026\u0026(n.availableZ=oW(o))}return n.layer=nW(Array.isArray(n.availableZ)?n.availableZ:[])??nW((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))??\"z0\",n},lW=(t,e)=\u003e{const n=rW(t.topology.portMetadata?.[e]);return\"number\"!=typeof n.x\u0026\u0026(n.x=t.topology.portX[e]),\"number\"!=typeof n.y\u0026\u0026(n.y=t.topology.portY[e]),\"number\"!=typeof n.z\u0026\u0026(n.z=t.topology.portZ[e]),n.layer=nW([t.topology.portZ[e]])??\"z0\",n},dW=(t,e,n)=\u003e{const o=(t.topology.incidentPortRegion[e]??[]).find(t=\u003et!==n);if(void 0===o)throw new Error(`Port ${e} is not incident to a region outside route region ${n}`);return o},hW=(t,e,n)=\u003e{const{orderedPortIds:o,orderedRegionIds:i}=((t,e,n)=\u003e{if(0===n.length)throw new Error(`Route ${e} has no solved segments`);const o=t.problem.routeStartPort[e],i=t.problem.routeEndPort[e],r=new Map;n.forEach((t,e)=\u003e{const n={...t,segmentIndex:e},o=r.get(t.fromPortId)??[];o.push(n),r.set(t.fromPortId,o);const i=r.get(t.toPortId)??[];i.push(n),r.set(t.toPortId,i)});const s=[o],a=[],c=new Set;let l,d=o;for(;d!==i;){const t=(r.get(d)??[]).filter(t=\u003e!c.has(t.segmentIndex)\u0026\u0026(t.fromPortId===d?t.toPortId:t.fromPortId)!==l);if(1!==t.length)throw new Error(`Route ${e} is not a single ordered path from ${o} to ${i}`);const n=t[0],h=n.fromPortId===d?n.toPortId:n.fromPortId;c.add(n.segmentIndex),a.push(n.regionId),s.push(h),l=d,d=h}if(c.size!==n.length)throw new Error(`Route ${e} contains disconnected solved segments`);return{orderedPortIds:s,orderedRegionIds:a}})(t,e,n),r=i[0],s=i[i.length-1];if(void 0===r||void 0===s)throw new Error(`Route ${e} could not determine endpoint regions`);const a=sW(t,dW(t,o[0],r)),c=sW(t,dW(t,o[o.length-1],s)),l=((t,e,n,o)=\u003e{const i=t.problem.routeMetadata?.[e];return{connectionId:(iW(i)\u0026\u0026\"string\"==typeof i.connectionId?i.connectionId:void 0)??`route-${e}`,startRegionId:(iW(i)\u0026\u0026\"string\"==typeof i.startRegionId?i.startRegionId:void 0)??n,endRegionId:(iW(i)\u0026\u0026\"string\"==typeof i.endRegionId?i.endRegionId:void 0)??o,mutuallyConnectedNetworkId:(iW(i)\u0026\u0026\"string\"==typeof i.mutuallyConnectedNetworkId?i.mutuallyConnectedNetworkId:void 0)??`net-${t.problem.routeNet[e]}`}})(t,e,a,c),d=o.map((e,n)=\u003e{const r={portId:aW(t,e),g:n,h:0,f:n,hops:n,ripRequired:!1,nextRegionId:n\u003ci.length?sW(t,i[n]):l.endRegionId};return n\u003e0\u0026\u0026(r.lastPortId=aW(t,o[n-1]),r.lastRegionId=sW(t,i[n-1])),r});return{connection:l,solvedRoute:{connection:l,path:d,requiredRip:!1}}},uW=t=\u003e{if(!t.solved||t.failed)throw new Error(\"convertToSerializedHyperGraph requires a solved, non-failed solver\");const{topology:e}=t,n=(t=\u003e{const e=Array.from({length:t.problem.routeCount},()=\u003e[]);return t.state.regionSegments.forEach((t,n)=\u003e{for(const[o,i,r]of t)e[o].push({regionId:n,fromPortId:i,toPortId:r})}),e})(t),o=Array.from({length:e.regionCount},(n,o)=\u003e({regionId:sW(t,o),pointIds:e.regionIncidentPorts[o].map(e=\u003eaW(t,e)),d:cW(t,o)})),i=Array.from({length:e.portCount},(n,o)=\u003e{const[i,r]=e.incidentPortRegion[o]??[];if(void 0===i||void 0===r)throw new Error(`Port ${o} is missing incident regions`);return{portId:aW(t,o),region1Id:sW(t,i),region2Id:sW(t,r),d:lW(t,o)}}),r=n.map((e,n)=\u003ehW(t,n,e));return{regions:o,ports:i,connections:r.map(({connection:t})=\u003et),solvedRoutes:r.map(({solvedRoute:t})=\u003et)}},pW=t=\u003et\u003e0\u0026\u0026!(t\u0026t-1),mW=(t,e,n,o,i,r=0)=\u003e.2025*(2*e+1*n+1*o)*(1+i/5)/t+(pW(r)?10*e:0),gW=(t,e,n,o,i,r)=\u003e{const{netIds:s,lesserAngles:a,greaterAngles:c,layerMasks:l}=t;let d=0,h=0;for(let t=0;t\u003cs.length;t++){if(e===s[t])continue;(n\u003ca[t]\u0026\u0026a[t]\u003co)!==(n\u003cc[t]\u0026\u0026c[t]\u003co)\u0026\u0026(0!==(i\u0026l[t])?d++:h++)}return[d,h,r]},fW=class{constructor(t,e){this.items=t,this.compare=e}items;compare;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0}queue(t){this.items.push(t),this.siftUp(this.items.length-1)}dequeue(){const t=this.items[0];if(void 0===t)return;const e=this.items.pop();return this.items.length\u003e0\u0026\u0026(this.items[0]=e,this.siftDown(0)),t}siftUp(t){let e=t;for(;e\u003e0;){const t=e-1\u003e\u003e1,n=this.items[t],o=this.items[e];if(this.compare(n,o)\u003c=0)return;this.items[t]=o,this.items[e]=n,e=t}}siftDown(t){let e=t;const n=this.items.length;for(;;){const t=2*e+1;if(t\u003e=n)return;const o=t+1;let i=t;o\u003cn\u0026\u0026this.compare(this.items[o],this.items[t])\u003c0\u0026\u0026(i=o);const r=this.items[e],s=this.items[i];if(this.compare(r,s)\u003c=0)return;this.items[e]=s,this.items[i]=r,e=i}}},yW=(t,e)=\u003e{const n=[...t],o=(t=\u003e{let e=t\u003e\u003e\u003e0;return()=\u003e{e+=1831565813;let t=e;return t=Math.imul(t^t\u003e\u003e\u003e15,1|t),t^=t+Math.imul(t^t\u003e\u003e\u003e7,61|t),((t^t\u003e\u003e\u003e14)\u003e\u003e\u003e0)/4294967296}})(e);for(let t=n.length-1;t\u003e0;t--){const e=Math.floor(o()*(t+1));[n[t],n[e]]=[n[e],n[t]]}return n},_W=(t,e)=\u003et.routeMetadata?.[e],bW=t=\u003et?.simpleRouteConnection?.pointsToConnect?.map(({pointId:t})=\u003e\"string\"==typeof t?t:null).filter(t=\u003enull!==t)??[],xW=(t,e)=\u003e{const n=_W(t,e)?.connectionId;return\"string\"==typeof n?n:`route-${e}`},vW=(t,e,n)=\u003e{const o=t.portEndpointNetIds[n];if(!o)return!1;for(const t of o)if(t!==e)return!0;return!1},SW=(t,e,n)=\u003e{const o=t.regionNetId[n];return-1!==o\u0026\u0026o!==e},IW=t=\u003e[...new Set(t.routeIds)].filter(e=\u003e!((t,e)=\u003e{const{topology:n,problem:o,problemSetup:i,portAssignment:r,maxPrecheckHops:s}=t,a=o.routeNet[e],c=o.routeStartPort[e],l=o.routeEndPort[e];if(c===l)return!0;const d=t.getStartingNextRegionId(e,c);if(void 0===d)return!1;const h=[{portId:c,nextRegionId:d}],u=new Set([c*n.regionCount+d]);for(let t=0;t\u003ch.length;t++){const e=h[t];if(!SW(o,a,e.nextRegionId))for(const t of n.regionIncidentPorts[e.nextRegionId]??[]){const c=r[t];if(vW(i,a,t))continue;if(t===l){if(-1!==c\u0026\u0026c!==a)continue;return!0}if(t===e.portId)continue;if(-1!==c\u0026\u0026c!==a)continue;if(0===o.portSectionMask[t])continue;const d=n.incidentPortRegion[t]??[],p=d[0]===e.nextRegionId?d[1]:d[0];if(void 0===p||SW(o,a,p))continue;const m=t*n.regionCount+p;if(!u.has(m)){if(u.size\u003e=s)return!0;u.add(m),h.push({portId:t,nextRegionId:p})}}}return!1})(t,e)).map(e=\u003et.getRouteSummary(e)),CW=t=\u003e{const e=new Array(t);for(let n=0;n\u003ct;n++)e[n]=n;return e},PW=.05,MW={r:255,g:64,b:64,a:.72},NW=\"rgba(220, 38, 38, 0.98)\",wW=\"rgba(220, 38, 38, 0.12)\",TW=\"10 6\",RW=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),EW=t=\u003eMath.min(1,Math.max(0,t)),AW=(t,e,n)=\u003eMath.round(t+(e-t)*n),OW=({r:t,g:e,b:n,a:o})=\u003e`rgba(${t}, ${e}, ${n}, ${o})`,kW=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},LW=t=\u003e\"number\"==typeof t.centerRouteId,DW=(t,e)=\u003eLW(t)?e===t.centerRouteId?1:.5:1,zW=(t,e)=\u003e{const n=t.match(/^(rgba|hsla)\\((.*),\\s*([0-9]*\\.?[0-9]+)\\)$/);if(!n)return t;const[,o,i,r]=n,s=EW(Number(r)*e);return`${o}(${i}, ${Number(s.toFixed(3))})`},FW=(t,e,n=.8)=\u003e((t,e,n=.8)=\u003e{const o=`${t.problem.routeNet[e]}:${kW(t,e)}`;let i=0;for(let t=0;t\u003co.length;t++)i=17777*o.charCodeAt(t)+((i\u003c\u003c5)-i);return`hsla(${Math.abs(i)%360}, 70%, 50%, ${n})`})(t,e,n*DW(t,e)),BW=(t,e)=\u003e`net: ${t.problem.routeNet[e]}`,jW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=n?.polygon;if(Array.isArray(o)\u0026\u0026o.length\u003e=3){const t=o.map(t=\u003et.x),e=o.map(t=\u003et.y);return{minX:Math.min(...t),maxX:Math.max(...t),minY:Math.min(...e),maxY:Math.max(...e)}}const i=n?.bounds;if(i\u0026\u0026\"number\"==typeof i.minX\u0026\u0026\"number\"==typeof i.maxX\u0026\u0026\"number\"==typeof i.minY\u0026\u0026\"number\"==typeof i.maxY)return i;const r=t.topology.regionWidth[e],s=t.topology.regionHeight[e],a=t.topology.regionCenterX[e],c=t.topology.regionCenterY[e];return{minX:a-r/2,maxX:a+r/2,minY:c-s/2,maxY:c+s/2}},$W=(t,e)=\u003e({x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),YW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e],o=Array.isArray(n?.availableZ)?n.availableZ.filter(t=\u003e\"number\"==typeof t\u0026\u0026Number.isInteger(t)\u0026\u0026t\u003e=0):[];if(o.length\u003e0)return nW(o)??\"z0\";const i=oW(t.topology.regionAvailableZMask?.[e]??0);if(i.length\u003e0)return nW(i)??\"z0\";const r=[...new Set((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))].sort((t,e)=\u003et-e);return nW(r)??\"z0\"},XW=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e],o=n?.existingRegionCost??0,i=t.state.regionCongestionCost[e]??0,r=t.problem.regionNetId[e];return RW(`region: region-${e}`,`net: ${-1===r?\"free\":`${r}`}`,t.getAdditionalRegionLabel(e),`cost: ${o.toFixed(3)}`,`congestion: ${i.toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},VW=(t,e)=\u003e{const n=t.topology.regionMetadata?.[e];return n?.isConnectionRegion?{r:255,g:100,b:255,a:.6}:n?.isThroughJumper?{r:100,g:200,b:100,a:.5}:n?.isPad?{r:255,g:200,b:100,a:.5}:\"bottom\"===n?.layer?{r:52,g:152,b:219,a:.08}:{r:200,g:200,b:255,a:.1}},WW=(t,e)=\u003e{const n=VW(t,e),o=EW(t.state.regionIntersectionCaches[e]?.existingRegionCost??0),i=Math.pow(o,.8);return OW((s=MW,a=i,{r:AW((r=n).r,s.r,a),g:AW(r.g,s.g,a),b:AW(r.b,s.b,a),a:Number((r.a+(s.a-r.a)*a).toFixed(3))}));var r,s,a},HW=(t,e)=\u003e({x:t.topology.portX[e],y:t.topology.portY[e]}),GW=HW,UW=HW,ZW=(t,e)=\u003enW([t.topology.portZ[e]])??\"z0\",qW=(t,e)=\u003e{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},JW=(t,e,n)=\u003e{if(void 0!==n)return`net: ${t.problem.routeNet[n]}`;const o=t.state.portAssignment[e];if(o\u003e=0)return`net: ${o}`;const i=new Set;for(let n=0;n\u003ct.problem.routeCount;n++)t.problem.routeStartPort[n]!==e\u0026\u0026t.problem.routeEndPort[n]!==e||i.add(t.problem.routeNet[n]);return 0!==i.size?`net: ${Array.from(i).sort((t,e)=\u003et-e).join(\", \")}`:void 0},KW=(t,e)=\u003e`z: ${t.topology.portZ[e]}`,QW=(t,e,n)=\u003eRW(qW(t,e),((t,e)=\u003e{const n=t.topology.incidentPortRegion[e]?.[0],o=t.topology.incidentPortRegion[e]?.[1];return`connects: region-${n??\"?\"} \u003c-\u003e region-${o??\"?\"}`})(t,e),JW(t,e,n)),tH=(t,e,n,o)=\u003e{const i=t.topology.portZ[n],r=t.topology.portZ[o];return i\u003e0\u0026\u0026r\u003e0?{strokeColor:zW(\"rgba(52, 152, 219, 0.95)\",DW(t,e)),strokeDash:\"3 2\"}:i!==r?{strokeColor:zW(\"rgba(22, 160, 133, 0.95)\",DW(t,e)),strokeDash:\"2 4 2\"}:{strokeColor:FW(t,e)}},eH=(t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++)if(t.problem.routeStartPort[n]===e||t.problem.routeEndPort[n]===e)return!0;return!1},nH=(t,e,n)=\u003e{const o=((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ce.length;o++)if(1===e[o])for(const e of t.topology.incidentPortRegion[o]??[])n.add(e);return n})(t,n),i=\"rgba(245, 158, 11, 0.95)\",r=\"rgba(245, 158, 11, 0.08)\";for(const n of o){const o=t.topology.regionMetadata?.[n],s=o?.polygon,a=jW(t,n),c=$W(t,n),l=a.maxX-a.minX,d=a.maxY-a.minY,h=YW(t,n),u=RW(\"section region\",XW(t,n));Array.isArray(s)\u0026\u0026s.length\u003e=3?e.polygons.push({points:s,fill:r,stroke:i,strokeWidth:2,layer:h,label:u}):e.rects.push({center:c,width:Math.max(l-PW,.05),height:Math.max(d-PW,.05),fill:r,stroke:i,layer:h,label:u})}for(let o=0;o\u003cn.length;o++)1===n[o]\u0026\u0026e.circles.push({center:UW(t,o),radius:.07,fill:\"rgba(251, 191, 36, 0.18)\",stroke:i,layer:ZW(t,o),label:RW(QW(t,o),KW(t,o),\"section port\")})},oH=(t,e={})=\u003e{const n={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:\"Tiny HyperGraph\",coordinateSystem:\"cartesian\"},o=((t,e)=\u003e{if(!e?.highlightSectionMask)return;const n=e.sectionPortMask??t.problem.portSectionMask;if(n.length!==t.topology.portCount)return;let o=0,i=0;for(let t=0;t\u003cn.length;t++)1===n[t]?o+=1:i+=1;return 0!==o\u0026\u00260!==i?n:void 0})(t,e);for(let e=0;e\u003ct.topology.regionCount;e++){const o=t.topology.regionMetadata?.[e],i=o?.polygon,r=jW(t,e),s=$W(t,e),a=r.maxX-r.minX,c=r.maxY-r.minY,l=YW(t,e),d=OW(VW(t,e));Array.isArray(i)\u0026\u0026i.length\u003e=3?n.polygons.push({points:i,fill:d,layer:l}):n.rects.push({center:s,width:Math.max(a-PW,.05),height:Math.max(c-PW,.05),fill:WW(t,e),layer:l,label:XW(t,e)})}if(((t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a=FW(t,n),c=kW(t,n),l=BW(t,n);e.points.push({x:r.x,y:r.y,color:a,layer:ZW(t,o),label:RW(`route: ${c}`,l,\"endpoint: start\",qW(t,o),KW(t,o))}),e.points.push({x:s.x,y:s.y,color:a,layer:ZW(t,i),label:RW(`route: ${c}`,l,\"endpoint: end\",qW(t,i),KW(t,i))})}})(t,n),0===t.iterations){for(const t of n.polygons)t.stroke=\"rgba(128, 128, 128, 0.5)\";for(const t of n.rects)t.stroke=\"rgba(128, 128, 128, 0.5)\"}if(0===t.iterations){for(let i=0;i\u003ct.topology.portCount;i++){const r=1===o?.[i];e.showOnlySectionPortsOnIdle\u0026\u0026!r||n.circles.push({center:UW(t,i),radius:.05,fill:t.topology.portZ[i]\u003e0?\"rgba(52, 152, 219, 0.55)\":\"rgba(128, 128, 128, 0.5)\",layer:ZW(t,i),label:RW(QW(t,i),KW(t,i))})}!1!==e.showInitialRouteHints\u0026\u0026((t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a={x:(r.x+s.x)/2,y:(r.y+s.y)/2};e.lines.push({points:[r,s],strokeColor:FW(t,n),strokeDash:\"3 3\",label:kW(t,n)}),e.points.push({x:a.x,y:a.y,color:FW(t,n,1),label:kW(t,n)})}})(t,n)}else((t,e)=\u003e{for(let n=0;n\u003ct.state.regionSegments.length;n++){const o=t.state.regionSegments[n]??[];for(const[i,r,s]of o)e.lines.push({points:[GW(t,r),GW(t,s)],label:RW(`route: ${kW(t,i)}`,`region: region-${n}`),...tH(t,i,r,s)})}})(t,n),((t,e)=\u003e{const n=new Set;for(let o=0;o\u003ct.state.regionSegments.length;o++){const i=t.state.regionSegments[o]??[];for(const[o,r,s]of i)for(const i of[r,s]){const r=`${o}:${i}`;if(n.has(r))continue;n.add(r);const s=GW(t,i);e.points.push({x:s.x,y:s.y,color:FW(t,o,1),layer:ZW(t,i),label:RW(`route: ${kW(t,o)}`,qW(t,i),JW(t,i,o),KW(t,i))})}}})(t,n),(t=\u003eLW(t)\u0026\u0026!0===t.showUnassignedPortsInVisualization)(t)\u0026\u0026((t,e)=\u003e{for(let n=0;n\u003ct.topology.portCount;n++)t.state.portAssignment[n]\u003e=0||eH(t,n)||e.circles.push({center:UW(t,n),radius:.04,fill:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.2)\":\"rgba(128, 128, 128, 0.2)\",stroke:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.6)\":\"rgba(128, 128, 128, 0.6)\",layer:ZW(t,n),label:RW(QW(t,n),KW(t,n),\"state: unassigned\")})})(t,n),LW(t)||(((t,e)=\u003e{const n=t.state.currentRouteId;if(void 0===n||t.solved)return;const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a=FW(t,n),c=kW(t,n);e.lines.push({points:[r,s],strokeColor:a,strokeDash:\"10 5\",label:c})})(t,n),((t,e)=\u003e{if(t.solved)return;const n=t.state.currentRouteId,o=t.state.candidateQueue.toArray().sort((t,e)=\u003et.f-e.f).slice(0,10);for(let i=0;i\u003co.length;i++){const r=o[i],s=GW(t,r.portId),a=0===i;e.points.push({x:s.x,y:s.y,color:a?\"green\":\"rgba(128, 128, 128, 0.25)\",layer:ZW(t,r.portId),label:RW(QW(t,r.portId,n),KW(t,r.portId),`g: ${r.g.toFixed(2)}`,`h: ${r.h.toFixed(2)}`,`f: ${r.f.toFixed(2)}`)})}const i=o[0];if(!i)return;const r=[];let s=i;for(;s;)r.unshift(GW(t,s.portId)),s=s.prevCandidate;r.length\u003e1\u0026\u0026e.lines.push({points:r,strokeColor:void 0!==n?FW(t,n):\"rgba(0, 160, 120, 0.9)\"})})(t,n));o\u0026\u0026nH(t,n,o),((t,e)=\u003e{if(t.failed)for(const n of t.getNeverSuccessfullyRoutedRoutes()){const{routeId:o,connectionId:i,attempts:r,startPortId:s,endPortId:a}=n,c=BW(t,o),l=UW(t,s),d=UW(t,a),h=RW(`never routed: ${i}`,`attempts: ${r}`,c,n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0);e.lines.push({points:[{x:0,y:0},{x:l.x,y:l.y}],strokeColor:NW,strokeDash:TW,layer:ZW(t,s),label:RW(h,\"origin guide\",\"endpoint: start\")}),e.circles.push({center:l,radius:1,fill:wW,stroke:NW,layer:ZW(t,s),label:RW(h,\"endpoint: start\",qW(t,s),KW(t,s))}),e.lines.push({points:[{x:0,y:0},{x:d.x,y:d.y}],strokeColor:NW,strokeDash:TW,layer:ZW(t,a),label:RW(h,\"origin guide\",\"endpoint: end\")}),e.circles.push({center:d,radius:1,fill:wW,stroke:NW,layer:ZW(t,a),label:RW(h,\"endpoint: end\",qW(t,a),KW(t,a))})}})(t,n);const i=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1),r=o?o.reduce((t,e)=\u003et+Number(1===e),0):0;return n.title=[\"Tiny HyperGraph\",`iter=${t.iterations}`,`pending=${i}`,o?`sectionPorts=${r}`:void 0,t.failed?\"failed\":t.solved?\"solved\":\"running\"].filter(Boolean).join(\" | \"),n},iH=()=\u003e({netIds:new Int32Array(0),lesserAngles:new Int32Array(0),greaterAngles:new Int32Array(0),layerMasks:new Int32Array(0),existingCrossingLayerIntersections:0,existingSameLayerIntersections:0,existingEntryExitLayerChanges:0,existingRegionCost:0,existingSegmentCount:0}),rH=(t,e)=\u003et.f-e.f,sH=class extends kt{constructor(t,e,n){super(),this.topology=t,this.problem=e,((t,e)=\u003e{e\u0026\u0026(void 0!==e.DISTANCE_TO_COST\u0026\u0026(t.DISTANCE_TO_COST=e.DISTANCE_TO_COST),void 0!==e.RIP_THRESHOLD_START\u0026\u0026(t.RIP_THRESHOLD_START=e.RIP_THRESHOLD_START),void 0!==e.RIP_THRESHOLD_END\u0026\u0026(t.RIP_THRESHOLD_END=e.RIP_THRESHOLD_END),void 0!==e.RIP_THRESHOLD_RAMP_ATTEMPTS\u0026\u0026(t.RIP_THRESHOLD_RAMP_ATTEMPTS=e.RIP_THRESHOLD_RAMP_ATTEMPTS),void 0!==e.RIP_CONGESTION_REGION_COST_FACTOR\u0026\u0026(t.RIP_CONGESTION_REGION_COST_FACTOR=e.RIP_CONGESTION_REGION_COST_FACTOR),void 0!==e.MAX_ITERATIONS\u0026\u0026(t.MAX_ITERATIONS=e.MAX_ITERATIONS),void 0!==e.VERBOSE\u0026\u0026(t.VERBOSE=e.VERBOSE),void 0!==e.STATIC_REACHABILITY_PRECHECK\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK=e.STATIC_REACHABILITY_PRECHECK),void 0!==e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS\u0026\u0026(t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS=e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS))})(this,n),this.state={portAssignment:new Int32Array(t.portCount).fill(-1),regionSegments:Array.from({length:t.regionCount},()=\u003e[]),regionIntersectionCaches:Array.from({length:t.regionCount},()=\u003eiH()),currentRouteId:void 0,currentRouteNetId:void 0,unroutedRoutes:CW(e.routeCount),candidateQueue:new fW([],rH),candidateBestCostByHopId:new Float64Array(t.portCount*t.regionCount),candidateBestCostGenerationByHopId:new Uint32Array(t.portCount*t.regionCount),candidateBestCostGeneration:1,goalPortId:-1,ripCount:0,regionCongestionCost:new Float64Array(t.regionCount).fill(0)},this.routeAttemptCountByRouteId=new Uint32Array(e.routeCount),this.routeSuccessCountByRouteId=new Uint32Array(e.routeCount)}topology;problem;state;_problemSetup;routeAttemptCountByRouteId;routeSuccessCountByRouteId;hasLoggedNeverSuccessfullyRoutedRoutes=!1;segmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};DISTANCE_TO_COST=.05;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;RIP_CONGESTION_REGION_COST_FACTOR=.1;MAX_ITERATIONS=1e6;VERBOSE=!1;STATIC_REACHABILITY_PRECHECK=!0;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;get problemSetup(){return this._problemSetup||(this._problemSetup=this.computeProblemSetup()),this._problemSetup}computeProblemSetup(){const{topology:t,problem:e}=this,n=t.portX,o=t.portY,i=new Float64Array(t.portCount*e.routeCount),r=Array.from({length:t.portCount},()=\u003enew Set);for(let s=0;s\u003ce.routeCount;s++){r[e.routeStartPort[s]].add(e.routeNet[s]),r[e.routeEndPort[s]].add(e.routeNet[s]);const a=e.routeEndPort[s],c=n[a],l=o[a];for(let r=0;r\u003ct.portCount;r++){const t=n[r]-c,a=o[r]-l;i[r*e.routeCount+s]=Math.hypot(t,a)*this.DISTANCE_TO_COST}}return{portHCostToEndOfRoute:i,portEndpointNetIds:r}}_setup(){if(this.problemSetup,this.STATIC_REACHABILITY_PRECHECK){const t=IW({topology:this.topology,problem:this.problem,problemSetup:this.problemSetup,portAssignment:this.state.portAssignment,routeIds:this.state.unroutedRoutes,maxPrecheckHops:Math.max(0,this.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),getStartingNextRegionId:(t,e)=\u003ethis.getStartingNextRegionId(t,e),getRouteSummary:t=\u003ethis.getRouteSummary(t)});t.length\u003e0\u0026\u0026(this.failed=!0,this.error=(t=\u003e{const e=t.slice(0,5).map(t=\u003e{const e=t.pointIds.length\u003e=2?`${t.pointIds[0]}-\u003e${t.pointIds[1]}`:`${t.startPortId}-\u003e${t.endPortId}`;return`${t.connectionId} (${e})`}).join(\", \"),n=t.length-5;return[\"Static reachability precheck failed:\",`${t.length} route(s) have no legal path under the current reservation and start-region rules`,n\u003e0?`${e}, +${n} more`:e].join(\" \")})(t),this.stats={...this.stats,staticallyUnroutableRouteCount:t.length})}}_step(){const{problem:t,topology:e,state:n}=this;if(void 0===n.currentRouteId){if(0===n.unroutedRoutes.length)return void this.onAllRoutesRouted();n.currentRouteId=n.unroutedRoutes.shift(),n.currentRouteNetId=t.routeNet[n.currentRouteId],this.routeAttemptCountByRouteId[n.currentRouteId]+=1,this.resetCandidateBestCosts();const e=t.routeStartPort[n.currentRouteId];n.candidateQueue.clear();const o=this.getStartingNextRegionId(n.currentRouteId,e);if(void 0===o)return this.failed=!0,void(this.error=`Start port ${e} has no incident regions`);this.setCandidateBestCost(this.getHopId(e,o),0),n.candidateQueue.queue({nextRegionId:o,portId:e,f:0,g:0,h:0}),n.goalPortId=t.routeEndPort[n.currentRouteId]}const o=n.candidateQueue.dequeue();if(!o)return void this.onOutOfCandidates();const i=this.getHopId(o.portId,o.nextRegionId);if(o.g\u003ethis.getCandidateBestCost(i))return;if(this.isRegionReservedForDifferentNet(o.nextRegionId))return;const r=e.regionIncidentPorts[o.nextRegionId];for(const i of r){const r=n.portAssignment[i];if(this.isPortReservedForDifferentNet(i))continue;if(i===n.goalPortId){if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;return void this.onPathFound(o)}if(-1!==r\u0026\u0026r!==n.currentRouteNetId)continue;if(i===o.portId)continue;if(0===t.portSectionMask[i])continue;const s=this.computeG(o,i);if(!Number.isFinite(s))continue;const a=this.computeH(i),c=e.incidentPortRegion[i][0]===o.nextRegionId?e.incidentPortRegion[i][1]:e.incidentPortRegion[i][0];if(void 0===c||this.isRegionReservedForDifferentNet(c))continue;const l={prevRegionId:o.nextRegionId,nextRegionId:c,portId:i,g:s,h:a,f:s+a,prevCandidate:o};if(i===n.goalPortId)return void this.onPathFound(l);const d=this.getHopId(i,c);s\u003e=this.getCandidateBestCost(d)||(this.setCandidateBestCost(d,s),n.candidateQueue.queue(l))}}resetCandidateBestCosts(){const{state:t}=this;if(4294967295===t.candidateBestCostGeneration)return t.candidateBestCostGenerationByHopId.fill(0),void(t.candidateBestCostGeneration=1);t.candidateBestCostGeneration+=1}getCandidateBestCost(t){const{state:e}=this;return e.candidateBestCostGenerationByHopId[t]===e.candidateBestCostGeneration?e.candidateBestCostByHopId[t]:Number.POSITIVE_INFINITY}setCandidateBestCost(t,e){const{state:n}=this;n.candidateBestCostGenerationByHopId[t]=n.candidateBestCostGeneration,n.candidateBestCostByHopId[t]=e}getHopId(t,e){return t*this.topology.regionCount+e}getStartingNextRegionId(t,e){const n=this.topology.incidentPortRegion[e]??[],o=this.problem.routeNet[t];return n.find(t=\u003e-1===this.problem.regionNetId[t])??n.find(t=\u003ethis.problem.regionNetId[t]===o)??n[0]}isPortReservedForDifferentNet(t){const e=this.problemSetup.portEndpointNetIds[t];if(!e)return!1;for(const t of e)if(t!==this.state.currentRouteNetId)return!0;return!1}isRegionReservedForDifferentNet(t){const e=this.problem.regionNetId[t];return-1!==e\u0026\u0026e!==this.state.currentRouteNetId}isKnownSingleLayerRegion(t){const e=this.topology.regionAvailableZMask?.[t]??0;return pW(e)}computeRegionCostForRegion(t,e,n,o,i){return((t,e,n,o,i,r,s=0)=\u003emW(t*e,n,o,i,r,s))(this.topology.regionWidth[t],this.topology.regionHeight[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0)}populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.segmentGeometryScratch,r=o.incidentPortRegion[e],s=o.incidentPortRegion[n],a=r[0]===t||r[1]!==t?o.portAngleForRegion1[e]:o.portAngleForRegion2?.[e]??o.portAngleForRegion1[e],c=s[0]===t||s[1]!==t?o.portAngleForRegion1[n]:o.portAngleForRegion2?.[n]??o.portAngleForRegion1[n],l=o.portZ[e],d=o.portZ[n];return i.lesserAngle=a\u003cc?a:c,i.greaterAngle=a\u003cc?c:a,i.layerMask=1\u003c\u003cl|1\u003c\u003cd,i.entryExitLayerChanges=l!==d?1:0,i}appendSegmentToRegionCache(t,e,n){const{topology:o,state:i}=this,r=i.regionIntersectionCaches[t],s=this.populateSegmentGeometryScratch(t,e,n),[a,c,l]=gW(r,i.currentRouteNetId,s.lesserAngle,s.greaterAngle,s.layerMask,s.entryExitLayerChanges),d=r.netIds.length+1,h=new Int32Array(d);h.set(r.netIds),h[d-1]=i.currentRouteNetId;const u=new Int32Array(d);u.set(r.lesserAngles),u[d-1]=s.lesserAngle;const p=new Int32Array(d);p.set(r.greaterAngles),p[d-1]=s.greaterAngle;const m=new Int32Array(d);m.set(r.layerMasks),m[d-1]=s.layerMask;const g=r.existingSameLayerIntersections+a,f=r.existingCrossingLayerIntersections+c,y=r.existingEntryExitLayerChanges+l,_=u.length;i.regionIntersectionCaches[t]={netIds:h,lesserAngles:u,greaterAngles:p,layerMasks:m,existingSameLayerIntersections:g,existingCrossingLayerIntersections:f,existingEntryExitLayerChanges:y,existingSegmentCount:_,existingRegionCost:this.computeRegionCostForRegion(t,g,f,y,_)}}getSolvedPathSegments(t){const{state:e}=this,n=[];let o=t;for(;o;)n.unshift(o),o=o.prevCandidate;const i=[];for(let t=1;t\u003cn.length;t++)i.push({regionId:n[t-1].nextRegionId,fromPortId:n[t-1].portId,toPortId:n[t].portId});const r=n[n.length-1];return r\u0026\u0026r.portId!==e.goalPortId\u0026\u0026i.push({regionId:r.nextRegionId,fromPortId:r.portId,toPortId:e.goalPortId}),i}resetRoutingStateForRerip(){const{topology:t,problem:e,state:n}=this;n.portAssignment.fill(-1),n.regionSegments=Array.from({length:t.regionCount},()=\u003e[]),n.regionIntersectionCaches=Array.from({length:t.regionCount},()=\u003eiH()),n.currentRouteNetId=void 0,n.currentRouteId=void 0,n.unroutedRoutes=yW(CW(e.routeCount),n.ripCount),n.candidateQueue.clear(),this.resetCandidateBestCosts(),n.goalPortId=-1}getMaxRegionCost(){const{topology:t,state:e}=this;let n=0;for(let o=0;o\u003ct.regionCount;o++){const t=e.regionIntersectionCaches[o]?.existingRegionCost??0;n=Math.max(n,t)}return n}getRouteMetadata(t){return this.problem.routeMetadata?.[t]}getRouteConnectionId(t){const e=this.getRouteMetadata(t)?.connectionId;return\"string\"==typeof e?e:`route-${t}`}getRouteSummary(t){return(({problem:t,routeId:e,getRouteMetadata:n,getRouteConnectionId:o})=\u003e{const i=n?.(e)??_W(t,e);return{routeId:e,connectionId:o?.(e)??xW(t,e),startPortId:t.routeStartPort[e],endPortId:t.routeEndPort[e],startRegionId:\"string\"==typeof i?.startRegionId?i.startRegionId:void 0,endRegionId:\"string\"==typeof i?.endRegionId?i.endRegionId:void 0,pointIds:bW(i)}})({problem:this.problem,routeId:t,getRouteMetadata:t=\u003ethis.getRouteMetadata(t),getRouteConnectionId:t=\u003ethis.getRouteConnectionId(t)})}getAdditionalRegionLabel(t){}getNeverSuccessfullyRoutedRoutes(){const t=[];for(let e=0;e\u003cthis.problem.routeCount;e++){const n=this.routeAttemptCountByRouteId[e];0===n||this.routeSuccessCountByRouteId[e]\u003e0||t.push({...this.getRouteSummary(e),attempts:n})}return t}logNeverSuccessfullyRoutedRoutes(){if(!this.VERBOSE||this.hasLoggedNeverSuccessfullyRoutedRoutes)return;const t=this.getNeverSuccessfullyRoutedRoutes();if(this.hasLoggedNeverSuccessfullyRoutedRoutes=!0,0!==t.length){console.log([\"[TinyHyperGraphSolver:never-routed-summary]\",`count=${t.length}`].join(\" \"));for(const e of t){const t=e.pointIds.length\u003e=2?`${e.pointIds[0]}-\u003e${e.pointIds[1]}`:\"unknown\";console.log([\"[TinyHyperGraphSolver:never-routed]\",`routeId=${e.routeId}`,`connectionId=${e.connectionId}`,`attempts=${e.attempts}`,`pointPath=${t}`,`startRegionId=${e.startRegionId??\"unknown\"}`,`endRegionId=${e.endRegionId??\"unknown\"}`].join(\" \"))}}}logRipEvent(t,e,n={}){this.VERBOSE\u0026\u0026console.log([\"[TinyHyperGraphSolver:rip]\",`ripCount=${this.state.ripCount}`,`maxRegionCostBeforeRip=${e.toFixed(3)}`,`reason=${t}`,...Object.entries(n).map(([t,e])=\u003e`${t}=${\"number\"==typeof e?Number.isInteger(e)?String(e):e.toFixed(3):e}`)].join(\" \"))}onAllRoutesRouted(){const{topology:t,state:e}=this,n=this.RIP_THRESHOLD_RAMP_ATTEMPTS\u003c=0?1:Math.min(1,e.ripCount/this.RIP_THRESHOLD_RAMP_ATTEMPTS),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(t.regionCount);let s=0;for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;r[n]=t,s=Math.max(s,t),t\u003eo\u0026\u0026i.push(n)}if(this.stats={...this.stats,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:s,ripCount:e.ripCount},0===i.length||e.ripCount\u003e=this.RIP_THRESHOLD_RAMP_ATTEMPTS)this.solved=!0;else{for(let n=0;n\u003ct.regionCount;n++)e.regionCongestionCost[n]+=r[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCostBeforeRip:s,reripRegionCount:i.length},this.logRipEvent(\"hot_regions\",s,{hotRegionCount:i.length,currentRipThreshold:o})}}onOutOfCandidates(){const{topology:t,state:e}=this,n=e.currentRouteId,o=this.getMaxRegionCost();for(let n=0;n\u003ct.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;e.regionCongestionCost[n]+=t*this.RIP_CONGESTION_REGION_COST_FACTOR}e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCost:o,maxRegionCostBeforeRip:o,reripReason:\"out_of_candidates\"},this.logRipEvent(\"out_of_candidates\",o,{...void 0===n?{}:{routeId:n,connectionId:this.getRouteConnectionId(n)}})}onPathFound(t){const{state:e}=this,n=e.currentRouteId;if(void 0===n)return;this.routeSuccessCountByRouteId[n]+=1;const o=this.getSolvedPathSegments(t);for(const{regionId:t,fromPortId:i,toPortId:r}of o)e.regionSegments[t].push([n,i,r]),e.portAssignment[i]=e.currentRouteNetId,e.portAssignment[r]=e.currentRouteNetId,this.appendSegmentToRegionCache(t,i,r);e.candidateQueue.clear(),e.currentRouteNetId=void 0,e.currentRouteId=void 0}computeG(t,e){const{topology:n,state:o}=this,i=t.nextRegionId,r=o.regionIntersectionCaches[i],s=this.populateSegmentGeometryScratch(i,t.portId,e),[a,c,l]=gW(r,o.currentRouteNetId,s.lesserAngle,s.greaterAngle,s.layerMask,s.entryExitLayerChanges);if(a\u003e0\u0026\u0026this.isKnownSingleLayerRegion(i))return Number.POSITIVE_INFINITY;const d=this.computeRegionCostForRegion(i,r.existingSameLayerIntersections+a,r.existingCrossingLayerIntersections+c,r.existingEntryExitLayerChanges+l,r.existingSegmentCount+1)-r.existingRegionCost;return t.g+d+o.regionCongestionCost[i]}tryFinalAcceptance(){const t=this.getNeverSuccessfullyRoutedRoutes();this.stats={...this.stats,neverSuccessfullyRoutedRouteCount:t.length},this.logNeverSuccessfullyRoutedRoutes()}computeH(t){return this.problemSetup.portHCostToEndOfRoute[t*this.problem.routeCount+this.state.currentRouteId]}visualize(){return oH(this)}getOutput(){return uW(this)}},aH=t=\u003e{const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;return Number.isFinite(e)?e:void 0},cH=t=\u003e{const e=new Set;for(const n of t.connections??[])e.add(n.startRegionId),e.add(n.endRegionId);const n=new Set(t.regions.filter(t=\u003e(t=\u003e{if(!0!==t.d?._containsObstacle)return!1;if(!0!==t.d?._containsTarget)return!0;const e=aH(t);return void 0===e||-1===e})(t)\u0026\u0026!e.has(t.regionId)).map(t=\u003et.regionId));if(0===n.size)return t;const o=t.ports.filter(t=\u003e!n.has(t.region1Id)\u0026\u0026!n.has(t.region2Id)),i=(t.connections??[]).find(t=\u003en.has(t.startRegionId)||n.has(t.endRegionId));if(i)throw new Error(`Connection \"${i.connectionId}\" references full-obstacle region`);return{...t,regions:t.regions.filter(t=\u003e!n.has(t.regionId)),ports:o}},lH=t=\u003e{const e=t.d?.bounds;if(e)return e;const n=t.d?.center,o=t.d?.width,i=t.d?.height;return n\u0026\u0026\"number\"==typeof n.x\u0026\u0026\"number\"==typeof n.y\u0026\u0026\"number\"==typeof o\u0026\u0026\"number\"==typeof i?{minX:n.x-o/2,maxX:n.x+o/2,minY:n.y-i/2,maxY:n.y+i/2}:{minX:0,maxX:0,minY:0,maxY:0}},dH=t=\u003e{const e=Number(t.d?.z??0);return Number.isFinite(e)?e:0},hH=t=\u003e.005*dH(t),uH=t=\u003eNumber(t.d?.x??0)+hH(t),pH=t=\u003eNumber(t.d?.y??0)+hH(t),mH=(t,e)=\u003e{if(!e)return 0;const n=lH(e),o=uH(t),i=pH(t),r=n.minX\u003c=o\u0026\u0026o\u003c=n.maxX,s=n.minY\u003c=i\u0026\u0026i\u003c=n.maxY;if(s\u0026\u0026o\u003e=n.maxX){const t=Math.max(n.maxY-n.minY,1e-9),e=(i-n.minY)/t;return Math.round(9e3*e)}if(r\u0026\u0026i\u003e=n.maxY){const t=Math.max(n.maxX-n.minX,1e-9),e=(n.maxX-o)/t;return 9e3+Math.round(9e3*e)}if(s\u0026\u0026o\u003c=n.minX){const t=Math.max(n.maxY-n.minY,1e-9),e=(n.maxY-i)/t;return 18e3+Math.round(9e3*e)}if(r\u0026\u0026i\u003c=n.minY){const t=Math.max(n.maxX-n.minX,1e-9),e=(o-n.minX)/t;return 27e3+Math.round(9e3*e)}const a=Math.abs(o-n.minX),c=Math.abs(o-n.maxX),l=Math.abs(i-n.minY),d=Math.abs(i-n.maxY),h=Math.min(a,c,l,d),u=Math.max(n.maxX-n.minX,1e-9),p=Math.max(n.maxY-n.minY,1e-9);if(h===c){const t=(i-n.minY)/p;return Math.round(9e3*t)}if(h===d){const t=(n.maxX-o)/u;return 9e3+Math.round(9e3*t)}if(h===a){const t=(n.maxY-i)/p;return 18e3+Math.round(9e3*t)}const m=(o-n.minX)/u;return 27e3+Math.round(9e3*m)},gH=(t,e)=\u003e{if(!t)return;return[...t.pointIds].sort((t,n)=\u003e{const o=e.get(t),i=e.get(n),r=Number(o?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY),s=Number(i?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY);if(r!==s)return r-s;const a=Number(o?.d?.z??0),c=Number(i?.d?.z??0);return a!==c?a-c:t.localeCompare(n)})[0]},fH=t=\u003e{const e=cH(t),n=new Map,o=new Map,i=new Map,r=new Map((e.solvedRoutes??[]).map(t=\u003e[t.connection.connectionId,t]));e.regions.forEach((t,e)=\u003e{n.set(t.regionId,e)}),e.ports.forEach((t,e)=\u003e{o.set(t.portId,e),i.set(t.portId,t)});const s=e.regions.length,a=e.ports.length,c=e.regions.map(t=\u003et.pointIds.map(t=\u003eo.get(t)).filter(t=\u003evoid 0!==t)),l=Array.from({length:a},()=\u003e[]),d=new Float64Array(s),h=new Float64Array(s),u=new Float64Array(s),p=new Float64Array(s),m=new Int32Array(s),g=new Int32Array(s).fill(-1),f=new Int8Array(s);e.regions.forEach((t,e)=\u003e{const n=(t=\u003e{const e=lH(t),n=\"number\"==typeof t.d?.width?t.d.width:e.maxX-e.minX,o=\"number\"==typeof t.d?.height?t.d.height:e.maxY-e.minY;return{centerX:\"number\"==typeof t.d?.center?.x?t.d.center.x:(e.minX+e.maxX)/2,centerY:\"number\"==typeof t.d?.center?.y?t.d.center.y:(e.minY+e.maxY)/2,width:n,height:o}})(t);d[e]=n.width,h[e]=n.height,u[e]=n.centerX,p[e]=n.centerY,m[e]=(t=\u003e{const e=t.d?.availableZ;if(!Array.isArray(e))return 0;let n=0;for(const t of e)!Number.isInteger(t)||t\u003c0||t\u003e=31||(n|=1\u003c\u003ct);return n})(t);const o=aH(t);void 0!==o\u0026\u0026(g[e]=o,f[e]=1)});const y=new Int32Array(a),_=new Int32Array(a),b=new Float64Array(a),x=new Float64Array(a),v=new Int32Array(a);e.ports.forEach((t,o)=\u003e{const i=n.get(t.region1Id),r=n.get(t.region2Id);if(void 0===i||void 0===r)throw new Error(`Port \"${t.portId}\" references missing regions \"${t.region1Id}\" or \"${t.region2Id}\"`);l[o]=[i,r],b[o]=uH(t),x[o]=pH(t),v[o]=dH(t),y[o]=mH(t,e.regions[i]),_[o]=mH(t,e.regions[r])});const S=e.regions.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedRegionId\",{value:t.regionId,enumerable:!1,configurable:!0,writable:!0}),n})(t,(t=\u003enW(oW(m[t]))??nW((c[t]??[]).map(t=\u003ev[t]))??\"z0\")(e))),I=e.ports.map((t,e)=\u003e((t,e)=\u003e{const n=t.d\u0026\u0026\"object\"==typeof t.d\u0026\u0026!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,\"serializedPortId\",{value:t.portId,enumerable:!1,configurable:!0,writable:!0}),n})(t,nW([v[e]])??\"z0\")),C=e.connections??[],P=new Map;let M=0;const N=t=\u003e{const e=t.mutuallyConnectedNetworkId??t.connectionId;let n=P.get(e);return void 0===n\u0026\u0026(n=M++,P.set(e,n)),n},w=Array.from({length:s},()=\u003enew Set),T=(t,e)=\u003e{const o=n.get(t);if(void 0===o)throw new Error(`Connection references missing region \"${t}\"`);w[o].add(e)};C.forEach(t=\u003e{const e=N(t);T(t.startRegionId,e),T(t.endRegionId,e)}),w.forEach((t,e)=\u003e{1!==f[e]\u0026\u00261===t.size\u0026\u0026(g[e]=[...t][0])});const R=C.map(t=\u003e{const n=r.get(t.connectionId),o=((t,e)=\u003et.ports.filter(t=\u003et.region1Id===e.startRegionId\u0026\u0026t.region2Id===e.endRegionId||t.region2Id===e.startRegionId\u0026\u0026t.region1Id===e.endRegionId).map(t=\u003et.portId))(e,t);return{connection:t,solvedRoute:n,sharedPortIds:o}}).filter(({solvedRoute:t,sharedPortIds:e})=\u003e0===e.length||(t?.path.length??0)\u003e1),E=R.length,A=new Int8Array(a).fill(1),O=new Int32Array(E),k=new Int32Array(E),L=new Int32Array(E);R.forEach(({connection:t,solvedRoute:n},r)=\u003e{const s=gH(e.regions.find(e=\u003ee.regionId===t.startRegionId),i),a=gH(e.regions.find(e=\u003ee.regionId===t.endRegionId),i),c=n?.path[0]?.portId??s,l=n?.path[n.path.length-1]?.portId??a,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)throw new Error(`Connection \"${t.connectionId}\" could not be mapped to route endpoints`);O[r]=d,k[r]=h,L[r]=N(t)});const D={portCount:a,regionCount:s,regionIncidentPorts:c,incidentPortRegion:l,regionWidth:d,regionHeight:h,regionCenterX:u,regionCenterY:p,regionAvailableZMask:m,regionMetadata:S,portAngleForRegion1:y,portAngleForRegion2:_,portX:b,portY:x,portZ:v,portMetadata:I},z={routeCount:E,portSectionMask:A,routeMetadata:R.map(({connection:t})=\u003et),routeStartPort:O,routeEndPort:k,routeNet:L,regionNetId:g},F=[],B=[];for(const{solvedRoute:t}of R){if(!t){F.push([]),B.push([]);continue}const e=[],i=[];for(let r=1;r\u003ct.path.length;r++){const s=t.path[r-1],a=t.path[r],c=s?.portId,l=a?.portId,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)continue;const u=\"string\"==typeof s?.nextRegionId?s.nextRegionId:\"string\"==typeof a?.lastRegionId?a.lastRegionId:void 0;e.push([d,h]),i.push(void 0!==u?n.get(u):void 0)}F.push(e),B.push(i)}return{topology:D,problem:z,solution:{solvedRoutePathSegments:F,solvedRoutePathRegionIds:B}}},yH=(Number.POSITIVE_INFINITY,1e-9),_H=t=\u003e\"object\"==typeof t\u0026\u0026null!==t,bH=(t,e=0)=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)?t:e,xH=t=\u003e{const e=(t=\u003e{const e=Math.min(t.minX,t.maxX),n=Math.max(t.minX,t.maxX),o=Math.min(t.minY,t.maxY),i=Math.max(t.minY,t.maxY);return{minX:e,maxX:n\u003ee?n:e+yH,minY:o,maxY:i\u003eo?i:o+yH}})(t);return[{x:e.maxX,y:e.minY},{x:e.maxX,y:e.maxY},{x:e.minX,y:e.maxY},{x:e.minX,y:e.minY}]},vH=(t,e)=\u003e{const n=t.filter(t=\u003eNumber.isFinite(t.x)\u0026\u0026Number.isFinite(t.y)),o=n.length\u003e=3?n:xH(e),i=(t=\u003e{let e=0;for(let n=0;n\u003ct.length;n++){const o=t[n],i=t[(n+1)%t.length];e+=o.x*i.y-o.y*i.x}return e})(o);if(Math.abs(i)\u003c=Number.EPSILON)return xH(e);return(t=\u003e{if(t.length\u003c3)throw new Error(\"Convex polygon requires at least three points\");return t})(i\u003c0?[...o].reverse():[...o])},SH=t=\u003e{const e=(t=\u003e{const e=t.d,n=e?.bounds;if(n\u0026\u0026\"number\"==typeof n.minX\u0026\u0026\"number\"==typeof n.maxX\u0026\u0026\"number\"==typeof n.minY\u0026\u0026\"number\"==typeof n.maxY)return{minX:n.minX,maxX:n.maxX,minY:n.minY,maxY:n.maxY};const o=e?.center,i=bH(e?.width,0),r=bH(e?.height,0);return o\u0026\u0026\"number\"==typeof o.x\u0026\u0026\"number\"==typeof o.y?{minX:o.x-i/2,maxX:o.x+i/2,minY:o.y-r/2,maxY:o.y+r/2}:{minX:0,maxX:yH,minY:0,maxY:yH}})(t);return vH((t=\u003e{const e=t.d,n=e?.polygon??e?.points??e?.vertices;if(!Array.isArray(n))return;const o=n.map(t=\u003e{if(!_H(t))return;const e=t.x,n=t.y;return\"number\"==typeof e\u0026\u0026\"number\"==typeof n?{x:e,y:n}:void 0}).filter(t=\u003evoid 0!==t);if(o.length\u003e1){const t=o[0],e=o[o.length-1];t.x===e.x\u0026\u0026t.y===e.y\u0026\u0026o.pop()}return o.length\u003e=3?o:void 0})(t)??xH(e),e)},IH=t=\u003e{let e=0,n=0,o=0,i=0,r=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,a=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY;for(let l=0;l\u003ct.length;l++){const d=t[l],h=t[(l+1)%t.length],u=d.x*h.y-h.x*d.y;e+=u,n+=(d.x+h.x)*u,o+=(d.y+h.y)*u,i+=Math.hypot(h.x-d.x,h.y-d.y),r=Math.min(r,d.x),s=Math.max(s,d.x),a=Math.min(a,d.y),c=Math.max(c,d.y)}const l=Math.abs(e)/2,d=Math.abs(e)\u003eNumber.EPSILON?3*e:Number.NaN,h=t.reduce((e,n)=\u003e({x:e.x+n.x/t.length,y:e.y+n.y/t.length}),{x:0,y:0});return{area:l,perimeter:i,centerX:Number.isFinite(d)?n/d:h.x,centerY:Number.isFinite(d)?o/d:h.y,bounds:{minX:r,maxX:s,minY:a,maxY:c}}},CH=(t,e,n,o)=\u003e{if(n\u003c=0)return{boundaryPosition:0,edgeIndex:0,edgeT:0};let i=Number.POSITIVE_INFINITY,r=0,s=0,a=0,c=0;for(let n=0;n\u003ce.length;n++){const o=e[n],l=e[(n+1)%e.length],d=l.x-o.x,h=l.y-o.y,u=d*d+h*h,p=Math.sqrt(u),m=u\u003c=Number.EPSILON?0:((t.x-o.x)*d+(t.y-o.y)*h)/u,g=Math.min(1,Math.max(0,m)),f=o.x+d*g,y=o.y+h*g,_=t.x-f,b=t.y-y,x=_*_+b*b;x\u003ci\u0026\u0026(i=x,r=n,s=g,a=c+p*g),c+=p}return{boundaryPosition:Math.round(a/n*o)%o,edgeIndex:r,edgeT:s}},PH=(t,e)=\u003e{const n=t.regionMetadata?.[e];return _H(n)\u0026\u0026\"string\"==typeof n.serializedRegionId?n.serializedRegionId:`region-${e}`},MH=(t,e)=\u003e{const n=t.portMetadata?.[e];return _H(n)\u0026\u0026\"string\"==typeof n.serializedPortId?n.serializedPortId:`port-${e}`},NH=(t,e,n,o)=\u003e{const i={..._H(t)?{...t}:void 0===t?{}:{value:t},polygon:n,sourceBounds:o};return Object.defineProperty(i,\"serializedRegionId\",{value:e,enumerable:!1,configurable:!0,writable:!0}),i},wH=(t,e)=\u003e{const n=new Map,o=new Map,i=new Map,r=new Map;for(let e=0;e\u003ct.regionCount;e++)n.set(PH(t,e),e);for(let e=0;e\u003ct.portCount;e++)o.set(MH(t,e),e);for(let t=0;t\u003ce.routeCount;t++){const n=e.routeMetadata?.[t];if(!_H(n))continue;\"string\"==typeof n.connectionId\u0026\u0026i.set(n.connectionId,t);const o=\"string\"==typeof n.mutuallyConnectedNetworkId?n.mutuallyConnectedNetworkId:\"string\"==typeof n.connectionId?n.connectionId:void 0;void 0!==o\u0026\u0026r.set(o,e.routeNet[t])}return{serializedRegionIdToRegionId:n,serializedPortIdToPortId:o,connectionIdToRouteId:i,netIdToNetIndex:r}},TH=(t,e,n)=\u003e{const o=t.incidentPortRegion[e];return o[0]===n||o[1]!==n?t.portBoundaryPositionForRegion1[e]:t.portBoundaryPositionForRegion2[e]},RH=class extends sH{constructor(t,e,n){super(t,e,n),this.topology=t,this.problem=e}topology;problem;polySegmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.polySegmentGeometryScratch,r=TH(o,e,t),s=TH(o,n,t),a=o.portZ[e],c=o.portZ[n];return i.lesserAngle=r\u003cs?r:s,i.greaterAngle=r\u003cs?s:r,i.layerMask=1\u003c\u003ca|1\u003c\u003cc,i.entryExitLayerChanges=a!==c?1:0,i}computeRegionCostForRegion(t,e,n,o,i){return mW(this.topology.regionArea[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0)}visualize(){return $H(this)}},EH=(...t)=\u003et.filter(t=\u003eBoolean(t)).join(\"\\n\"),AH=(t,e)=\u003e{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},OH=(t,e,n=.85)=\u003e{const o=`${t.problem.routeNet[e]}:${AH(t,e)}`;let i=0;for(let t=0;t\u003co.length;t++)i=17777*o.charCodeAt(t)+((i\u003c\u003c5)-i);return`hsla(${Math.abs(i)%360}, 70%, 45%, ${n})`},kH=(t,e)=\u003e{const n=t.regionVertexStart[e],o=t.regionVertexCount[e],i=[];for(let e=0;e\u003co;e++){const o=n+e;i.push({x:t.regionVertexX[o],y:t.regionVertexY[o]})}return i},LH=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e]?.existingRegionCost??0,o=Math.min(1,Math.max(0,Math.pow(n,.8))),i=Math.round(245-105*o);return`rgba(245, ${Math.round(248-168*o)}, ${i}, ${.18+.48*o})`},DH=(t,e)=\u003e{const n=t.state.regionIntersectionCaches[e],o=PH(t.topology,e),i=t.problem.regionNetId[e];return EH(`region: ${o}`,`net: ${-1===i?\"free\":i}`,`area: ${t.topology.regionArea[e].toFixed(3)}`,`cost: ${(n?.existingRegionCost??0).toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},zH=(t,e)=\u003enW(oW(t.topology.regionAvailableZMask?.[e]??0))??nW((t.topology.regionIncidentPorts[e]??[]).map(e=\u003et.topology.portZ[e]))??\"z0\",FH=(t,e)=\u003e({x:t.topology.portX[e],y:t.topology.portY[e]}),BH=(t,e)=\u003enW([t.topology.portZ[e]])??\"z0\",jH=(t,e)=\u003e{const[n,o]=t.topology.incidentPortRegion[e]??[];return EH(`port: ${MH(t.topology,e)}`,`connects: ${n??\"?\"} \u003c-\u003e ${o??\"?\"}`,`z: ${t.topology.portZ[e]}`)},$H=t=\u003e{const e={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:\"Poly HyperGraph\",coordinateSystem:\"cartesian\"};for(let n=0;n\u003ct.topology.regionCount;n++)e.polygons.push({points:kH(t.topology,n),fill:LH(t,n),stroke:\"rgba(80, 80, 120, 0.55)\",layer:zH(t,n),label:DH(t,n)});for(let n=0;n\u003ct.topology.portCount;n++)e.circles.push({center:FH(t,n),radius:.05,fill:t.topology.portZ[n]\u003e0?\"rgba(52, 152, 219, 0.55)\":\"rgba(80, 80, 80, 0.45)\",layer:BH(t,n),label:jH(t,n)});((t,e)=\u003e{for(let n=0;n\u003ct.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=AH(t,n),s=OH(t,n);e.points.push({...FH(t,o),color:s,layer:BH(t,o),label:EH(`route: ${r}`,\"endpoint: start\",jH(t,o))}),e.points.push({...FH(t,i),color:s,layer:BH(t,i),label:EH(`route: ${r}`,\"endpoint: end\",jH(t,i))})}})(t,e),((t,e)=\u003e{for(let n=0;n\u003ct.state.regionSegments.length;n++)for(const[o,i,r]of t.state.regionSegments[n]??[])e.lines.push({points:[FH(t,i),FH(t,r)],strokeColor:OH(t,o),layer:nW([t.topology.portZ[i],t.topology.portZ[r]])??\"z0\",label:EH(`route: ${AH(t,o)}`,`region: ${PH(t.topology,n)}`)})})(t,e),((t,e)=\u003e{if(t.solved)return;const n=t.state.candidateQueue.toArray().sort((t,e)=\u003et.f-e.f).slice(0,10);for(let o=0;o\u003cn.length;o++){const i=n[o];e.points.push({...FH(t,i.portId),color:0===o?\"green\":\"rgba(128, 128, 128, 0.4)\",layer:BH(t,i.portId),label:EH(jH(t,i.portId),`g: ${i.g.toFixed(2)}`,`h: ${i.h.toFixed(2)}`,`f: ${i.f.toFixed(2)}`)})}const o=n[0];if(!o)return;const i=[];let r=o;for(;r;)i.unshift(FH(t,r.portId)),r=r.prevCandidate;if(i.length\u003c=1)return;const s=t.state.currentRouteId;e.lines.push({points:i,strokeColor:void 0!==s?OH(t,s,.95):\"rgba(0, 160, 120, 0.95)\",strokeDash:\"4 3\",layer:BH(t,o.portId),label:EH(void 0!==s?`route: ${AH(t,s)}`:void 0,\"active candidate path\",`candidate port: ${MH(t.topology,o.portId)}`)})})(t,e);const n=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1);return e.title=[\"Poly HyperGraph\",`iter=${t.iterations}`,`pending=${n}`,t.failed?\"failed\":t.solved?\"solved\":\"running\"].join(\" | \"),e},YH=(new Int32Array(0),t=\u003e(t.ccwRotationDegrees??0)*Math.PI/180),XH=(t,e=8)=\u003e{const n=t.width/2,o=t.height/2,i=YH(t),r=Math.cos(i),s=Math.sin(i);return Array.from({length:e},(i,a)=\u003e{const c=2*Math.PI*a/e,l=n*Math.cos(c),d=o*Math.sin(c);return{x:t.center.x+l*r-d*s,y:t.center.y+l*s+d*r}})},VH=t=\u003e(t.obstacles??[]).filter(t=\u003e\"oval\"===t.type).map(t=\u003e({points:XH(t),layers:t.layers,zLayers:t.__zLayers,isCopperPour:t.isCopperPour})),WH=(t,e)=\u003e(t.obstacles??[]).flatMap((n,o)=\u003e{if(!Array.isArray(n.connectedTo)||0===n.connectedTo.length)return[];const i=oV(sV(n,t.layerCount),t.layerCount);if(0===i.length)return[];let r;const s=n.type;if(\"rect\"===s)r=((t,e=0)=\u003e{const n=t.width/2+e,o=t.height/2+e,i=YH(t),r=Math.cos(i),s=Math.sin(i);return[{localX:-n,localY:-o},{localX:n,localY:-o},{localX:n,localY:o},{localX:-n,localY:o}].map(({localX:e,localY:n})=\u003e({x:t.center.x+e*r-n*s,y:t.center.y+e*s+n*r}))})(n,e);else{if(\"oval\"!==s)return[];r=EV({polygon:{points:XH(n),layers:n.layers,zLayers:n.__zLayers,isCopperPour:n.isCopperPour},clearance:e,verticesOnly:!0})}return[{regionId:`connected-obstacle-${o}`,polygon:r,availableZ:i,connectedTo:n.connectedTo,d:{obstacleIndex:o,obstacleType:s,connectedTo:n.connectedTo}}]}),HH=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},GH=t=\u003e\"object\"==typeof t\u0026\u0026null!==t?t:{},UH=(t,e)=\u003e{const n=HH(t).serializedRegionId;return\"string\"==typeof n?n:`region-${e}`},ZH=(t,e)=\u003e{const n=GH(t);return\"string\"==typeof n.serializedPortId?n.serializedPortId:\"string\"==typeof n.portId?n.portId:`poly-port-${e}`},qH=t=\u003e{const e=GH(t);return{prevPortPointId:\"string\"==typeof e.prevPortPointId?e.prevPortPointId:void 0,nextPortPointId:\"string\"==typeof e.nextPortPointId?e.nextPortPointId:void 0}},JH=t=\u003e{const e=HH(t).polygon;if(Array.isArray(e)\u0026\u0026!(e.length\u003c3))return e.every(t=\u003e\"object\"==typeof t\u0026\u0026null!==t\u0026\u0026\"number\"==typeof t.x\u0026\u0026\"number\"==typeof t.y)?e:void 0},KH=class extends si{constructor(t){super(),this.params=t,this.effort=t.effort??1,this.clearance=t.srj.defaultObstacleMargin??t.srj.minTraceWidth;const e=e=\u003e{return eW({bounds:t.srj.bounds,rects:(n=t.srj,(n.obstacles??[]).filter(t=\u003e\"rect\"===t.type).map(t=\u003e({center:t.center,width:t.width,height:t.height,ccwRotation:YH(t),layers:t.layers,zLayers:t.__zLayers,isCopperPour:t.isCopperPour}))),polygons:VH(t.srj),clearance:this.clearance,concavityTolerance:t.concavityTolerance??0,layerCount:t.srj.layerCount,layerMergeMode:t.layerMergeMode??\"same\",useConstrainedDelaunay:e,usePolyanyaMerge:t.usePolyanyaMerge??!1,viaSegments:t.viaSegments??8});var n},n=t.useConstrainedDelaunay??!0;try{this.convexRegions=e(n)}catch(t){if(!n)throw t;this.usedUnconstrainedDelaunayFallback=!0,this.convexRegions=e(!1)}var o;this.serializedGraph=RV({regions:this.convexRegions.regions,availableZ:this.convexRegions.availableZ,layerCount:t.srj.layerCount,connections:(o=t.srj,o.connections.flatMap(t=\u003e{const e=t.pointsToConnect??[];if(e.length\u003c2)return[];const n=e[0];return e.slice(1).map((e,o)=\u003e{const i=((t,e,n,o)=\u003e{const i=2===t.pointsToConnect.length?t.name:`${t.name}::${o}`;return{...t,name:i,__rootConnectionNames:t.__rootConnectionNames??[t.name],pointsToConnect:[e,n]}})(t,n,e,o);return{connectionId:i.name,mutuallyConnectedNetworkId:i.__rootConnectionNames?.[0]??i.name,start:n,end:e,simpleRouteConnection:i}})})),obstacleRegions:WH(t.srj,this.clearance),portSpacing:t.portSpacing??lV,portMarginFromSegmentEndpoint:t.portMarginFromSegmentEndpoint??dV}),this.loaded=((t,e={})=\u003e{const n=e.boundaryCoordinateScale??36e3,o=fH(t),{topology:i,problem:r,solution:s}=o,a=new Map(t.regions.map(t=\u003e[t.regionId,t])),c=[];for(let t=0;t\u003ci.regionCount;t++){const e=PH(i,t),n=a.get(e),o=n?SH(n):xH({minX:i.regionCenterX[t]-i.regionWidth[t]/2,maxX:i.regionCenterX[t]+i.regionWidth[t]/2,minY:i.regionCenterY[t]-i.regionHeight[t]/2,maxY:i.regionCenterY[t]+i.regionHeight[t]/2});c.push(o)}const l=c.reduce((t,e)=\u003et+e.length,0),d=new Int32Array(i.regionCount),h=new Int32Array(i.regionCount),u=new Float64Array(l),p=new Float64Array(l),m=new Float64Array(i.regionCount),g=new Float64Array(i.regionCount),f=new Float64Array(i.regionCount),y=new Float64Array(i.regionCount),_=new Float64Array(i.regionCount),b=new Float64Array(i.regionCount),x=new Float64Array(i.regionCount),v=new Float64Array(i.regionCount),S=new Float64Array(i.regionCount),I=new Float64Array(i.regionCount),C=new Array(i.regionCount);let P=0;for(let t=0;t\u003ci.regionCount;t++){const e=c[t],n=IH(e),o=Math.sqrt(Math.max(n.area,yH));d[t]=P,h[t]=e.length,m[t]=n.area,g[t]=n.perimeter,f[t]=n.centerX,y[t]=n.centerY,_[t]=n.bounds.minX,b[t]=n.bounds.maxX,x[t]=n.bounds.minY,v[t]=n.bounds.maxY,S[t]=o,I[t]=o,C[t]=NH(i.regionMetadata?.[t],PH(i,t),e,n.bounds);for(const t of e)u[P]=t.x,p[P]=t.y,P+=1}const M=new Int32Array(i.portCount),N=new Int32Array(i.portCount),w=new Int32Array(i.portCount),T=new Int32Array(i.portCount),R=new Float64Array(i.portCount),E=new Float64Array(i.portCount);for(let t=0;t\u003ci.portCount;t++){const e={x:i.portX[t],y:i.portY[t]},[o,r]=i.incidentPortRegion[t]??[];if(void 0!==o){const i=CH(e,c[o],g[o],n);M[t]=i.boundaryPosition,w[t]=i.edgeIndex,R[t]=i.edgeT}if(void 0!==r){const o=CH(e,c[r],g[r],n);N[t]=o.boundaryPosition,T[t]=o.edgeIndex,E[t]=o.edgeT}}for(let t=0;t\u003ci.regionCount;t++)C[t].layer=nW(oW(i.regionAvailableZMask?.[t]??0))??nW((i.regionIncidentPorts[t]??[]).map(t=\u003ei.portZ[t]))??\"z0\";const A={...i,regionWidth:S,regionHeight:I,regionCenterX:f,regionCenterY:y,regionMetadata:C,portAngleForRegion1:M,portAngleForRegion2:N,regionVertexStart:d,regionVertexCount:h,regionVertexX:u,regionVertexY:p,regionArea:m,regionPerimeter:g,regionBoundsMinX:_,regionBoundsMaxX:b,regionBoundsMinY:x,regionBoundsMaxY:v,portBoundaryPositionForRegion1:M,portBoundaryPositionForRegion2:N,portEdgeIndexForRegion1:w,portEdgeIndexForRegion2:T,portEdgeTForRegion1:R,portEdgeTForRegion2:E};return{topology:A,problem:r,solution:s,mapping:wH(A,r)}})(this.serializedGraph),this.reservedRegionCount=((t,e)=\u003e{const n=t.problem.regionNetId;if(!n)return 0;const o=new Map;for(const t of e.regions){const e=\"number\"==typeof t.d?.netId?t.d.netId:\"number\"==typeof t.d?.NetId?t.d.NetId:void 0;Number.isInteger(e)\u0026\u0026e\u003e=0\u0026\u0026o.set(t.regionId,e)}let i=0;for(let e=0;e\u003ct.topology.regionCount;e++){const r=t.topology.regionMetadata?.[e],s=\"object\"==typeof r\u0026\u0026null!==r?r.serializedRegionId:void 0;if(\"string\"!=typeof s)continue;const a=o.get(s);void 0!==a\u0026\u0026(n[e]=a,i+=1)}return i})(this.loaded,this.serializedGraph);const i={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.max(1,Math.ceil(10*this.effort)),MAX_ITERATIONS:Math.max(1e5,Math.ceil(1e7*this.effort))};this.polySolver=new RH(this.loaded.topology,this.loaded.problem,i),this.activeSubSolver=this.polySolver,this.MAX_ITERATIONS=i.MAX_ITERATIONS+1e3,this.inputNodeWithPortPoints=this.createInputNodesWithPortPoints()}params;getSolverName(){return\"PolyHypergraphPortPointPathingSolver\"}convexRegions;serializedGraph;loaded;polySolver;inputNodeWithPortPoints=[];nodesWithPortPoints=[];reservedRegionCount=0;clearance;effort;usedUnconstrainedDelaunayFallback=!1;createInputNodesWithPortPoints(){const{topology:t}=this.loaded,e=[];for(let n=0;n\u003ct.regionCount;n++){const o=HH(t.regionMetadata?.[n]??{}),i=UH(o,n);if(i.startsWith(\"terminal-\"))continue;const r=(t.regionIncidentPorts[n]??[]).map(e=\u003e{const n=t.incidentPortRegion[e]??[],o=t.portMetadata?.[e];return{portPointId:ZH(o,e),x:t.portX[e],y:t.portY[e],z:t.portZ[e],...qH(o),connectionNodeIds:n.map(e=\u003eUH(t.regionMetadata?.[e],e)),distToCentermostPortOnZ:t.portMetadata?.[e]?.distToCentermostPortOnZ??0,connectsToOffBoardNode:!1}});e.push({capacityMeshNodeId:i,center:{x:t.regionCenterX[n],y:t.regionCenterY[n]},width:t.regionWidth[n],height:t.regionHeight[n],portPoints:r,availableZ:o.availableZ??Array.from({length:this.params.srj.layerCount},(t,e)=\u003ee),_containsObstacle:Boolean(o._containsObstacle),_containsTarget:Boolean(o._containsTarget)})}return e}createAssignedPortPoint(t,e){const n=this.polySolver.problem.routeMetadata?.[t],o=n?(t=\u003et.simpleRouteConnection?.name??t.connectionId)(n):`route-${t}`,i=n?(t=\u003et.simpleRouteConnection?.rootConnectionName??t.mutuallyConnectedNetworkId)(n):void 0,r=this.polySolver.topology.portMetadata?.[e];return{portPointId:ZH(r,e),x:this.polySolver.topology.portX[e],y:this.polySolver.topology.portY[e],z:this.polySolver.topology.portZ[e],connectionName:o,rootConnectionName:i,...qH(r)}}buildOutputNodes(){const{topology:t,state:e}=this.polySolver,n=[];for(let o=0;o\u003ce.regionSegments.length;o++){const i=HH(t.regionMetadata?.[o]??{}),r=UH(i,o);if(r.startsWith(\"terminal-\"))continue;const s=JH(i);if(!s)continue;const a=(e.regionSegments[o]??[]).flatMap(([t,e,n])=\u003e{const o=this.createAssignedPortPoint(t,e),i=this.createAssignedPortPoint(t,n);return o.portPointId\u0026\u0026i.portPointId\u0026\u0026(o.nextPortPointId=i.portPointId,i.prevPortPointId=o.portPointId),[o,i]});0!==a.length\u0026\u0026n.push({capacityMeshNodeId:r,center:{x:t.regionCenterX[o],y:t.regionCenterY[o]},width:t.regionWidth[o],height:t.regionHeight[o],polygon:s,portPoints:a,availableZ:i.availableZ})}this.nodesWithPortPoints=n}_step(){this.polySolver.step(),this.progress=this.polySolver.progress,this.stats={...this.polySolver.stats??{},reservedRegionCount:this.reservedRegionCount,usedUnconstrainedDelaunayFallback:this.usedUnconstrainedDelaunayFallback,regionCount:this.loaded.topology.regionCount,portCount:this.loaded.topology.portCount,routeCount:this.loaded.problem.routeCount},this.polySolver.solved?(this.buildOutputNodes(),this.solved=!0,this.activeSubSolver=null):this.polySolver.failed\u0026\u0026(this.error=this.polySolver.error,this.failed=!0,this.activeSubSolver=null)}getOutput(){return{nodesWithPortPoints:this.nodesWithPortPoints,inputNodeWithPortPoints:this.inputNodeWithPortPoints}}computeNodePf(t){const e=this.nodesWithPortPoints.find(e=\u003ee.capacityMeshNodeId===t.capacityMeshNodeId);if(!e)return null;const n=Ms(e);return Ys({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,layer:\"top\",availableZ:e.availableZ??[]},n.numSameLayerCrossings,n.numEntryExitLayerChanges,n.numTransitionPairCrossings)}getConstructorParams(){return[this.params]}preview(){return this.visualize()}visualize(){return this.polySolver.visualize()}},QH=class extends si{constructor(t){super(),this.inputSrj=t,this.MAX_ITERATIONS=1}inputSrj;outputSrj;_step(){this.outputSrj=mX(this.inputSrj)??this.inputSrj,this.solved=!0}getOutputSimpleRouteJson(){if(!this.outputSrj)throw new Error(\"PreprocessSimpleRouteJsonSolver has not solved yet\");return this.outputSrj}getConstructorParams(){return[this.inputSrj]}visualize(){return this.outputSrj?pi(Ho({...this.outputSrj,traces:[]}),Yj({srj:this.outputSrj})):{lines:[],points:[],rects:[],circles:[]}}},tG=(t,e)=\u003e(t.x-e.x)**2+(t.y-e.y)**2,eG=(t,e,n)=\u003e{if(!n)return;const o=t.filter(({projected:t})=\u003et.connectionName===e\u0026\u0026(void 0===n.z||t.z===n.z));return 0!==o.length?o.reduce((t,e)=\u003etG(e.projected,n)\u003ctG(t.projected,n)?e:t).original:void 0},nG=(t,e)=\u003e{const n=e.projectedRect;if(!n)throw new Error(\"Poly node is missing projectedRect\");const o=n.rectToPolygonMatrix,i=(t=\u003e{if(!t.projectedRect)throw new Error(\"Poly node is missing projectedRect\");return t.portPoints.map(e=\u003e{const n=ZX(e,t.projectedRect);return{original:e,projected:{...e,x:n.x,y:n.y}}})})(e),r=t.route.map(t=\u003e({...t,...HX(o,t)})),s=t.vias.map(t=\u003eHX(o,t)),a=eG(i,t.connectionName,t.route[0]),c=eG(i,t.connectionName,t.route[t.route.length-1]);return a\u0026\u0026r[0]\u0026\u0026(r[0]={...r[0],x:a.x,y:a.y,z:a.z}),c\u0026\u0026r[r.length-1]\u0026\u0026(r[r.length-1]={...r[r.length-1],x:c.x,y:c.y,z:c.z}),{...t,route:r,vias:s,jumpers:t.jumpers?.map(t=\u003e({...t,start:HX(o,t.start),end:HX(o,t.end)}))}},oG=class extends si{getSolverName(){return\"ProjectHighDensityToPolygonSolver\"}routes=[];routesByNodeId=new Map;colorMap;nodePortPoints;rawRoutesByNodeId;constructor({nodePortPoints:t,routesByNodeId:e,colorMap:n}){super(),this.MAX_ITERATIONS=1,this.nodePortPoints=t,this.rawRoutesByNodeId=e instanceof Map?new Map(e):new Map(Object.entries(e)),this.colorMap=n??{}}_step(){this.routes=[],this.routesByNodeId=new Map;for(const t of this.nodePortPoints){const e=(this.rawRoutesByNodeId.get(t.capacityMeshNodeId)??[]).map(e=\u003enG(e,t));e.length\u003e0\u0026\u0026(this.routesByNodeId.set(t.capacityMeshNodeId,e),this.routes.push(...e))}this.solved=!0}getOutput(){return this.routes}getConstructorParams(){return[{nodePortPoints:this.nodePortPoints,routesByNodeId:this.rawRoutesByNodeId,colorMap:this.colorMap}]}visualize(){const t={polygons:this.nodePortPoints.flatMap(t=\u003e[{points:t.polygon,fill:\"rgba(40, 140, 220, 0.06)\",stroke:\"rgba(20, 70, 160, 0.65)\",label:`${t.capacityMeshNodeId} polygon`},...t.projectedRect?[{points:t.projectedRect.targetQuad,fill:\"rgba(255, 165, 0, 0.05)\",stroke:\"rgba(255, 120, 0, 0.45)\",label:`${t.capacityMeshNodeId} projection target`}]:[]]),lines:[],circles:[]};for(const e of this.routes){const n=this.colorMap[e.connectionName]??\"#0000ff\",o=mi(e.route,e.connectionName,n);for(const n of o)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:To(n.color,.5),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?[.1,.3]:void 0});for(const o of e.vias)t.circles.push({center:o,layer:\"z0,1\",radius:e.viaDiameter/2,fill:n,label:`${e.connectionName} via`})}return t}};function iG(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var rG=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),this.equivalentAreaExpansionFactor=n.equivalentAreaExpansionFactor??2,this.minProjectedRectDimension=n.minProjectedRectDimension??3*this.minTraceWidth,void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;polyGraphSolver;attachProjectedRectsSolver;highDensityRouteSolver;projectHighDensityToPolgonSolver;highDensityStitchSolver;traceSimplificationSolver;traceWidthSolver;globalDrcForceImproveSolver;colorMap;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;equivalentAreaExpansionFactor;minProjectedRectDimension;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;highDensityNodePortPoints;projectedHighDensityNodePortPoints;cacheProvider=null;pipelineDef=[iG(\"preprocessSimpleRouteJsonSolver\",QH,t=\u003e[t.originalSrj],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),iG(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),iG(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),iG(\"polyGraphSolver\",KH,t=\u003e[{srj:t.srjWithPointPairs,effort:t.effort,concavityTolerance:t.opts.polyConcavityTolerance,portSpacing:t.opts.polyPortSpacing,portMarginFromSegmentEndpoint:t.opts.polyPortMarginFromSegmentEndpoint}],{onSolved:t=\u003e{t.highDensityNodePortPoints=t.polyGraphSolver?.getOutput().nodesWithPortPoints??[]}}),iG(\"attachProjectedRectsSolver\",JX,t=\u003e[{nodesWithPortPoints:t.highDensityNodePortPoints??[],equivalentAreaExpansionFactor:t.equivalentAreaExpansionFactor,minProjectedRectDimension:t.minProjectedRectDimension,traceWidth:t.minTraceWidth,viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.projectedHighDensityNodePortPoints=t.attachProjectedRectsSolver?.getOutput()??[]}}),iG(\"highDensityRouteSolver\",QX,t=\u003e[{nodePortPoints:t.projectedHighDensityNodePortPoints??[],nodePfById:new Map((t.polyGraphSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.polyGraphSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,effort:t.effort}]),iG(\"projectHighDensityToPolgonSolver\",oG,t=\u003e[{nodePortPoints:t.projectedHighDensityNodePortPoints??[],routesByNodeId:t.highDensityRouteSolver.routesByNodeId,colorMap:t.colorMap}]),iG(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.projectHighDensityToPolgonSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),iG(\"traceSimplificationSolver\",vc,t=\u003e[{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}]),iG(\"traceWidthSolver\",Ic,t=\u003e[{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}]),iG(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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\u0026\u0026(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\"}getProblemVisualization({includeRoutes:t=!0}={}){const e=this.originalSrj,n=[{points:[{x:e.bounds?.minX??-50,y:e.bounds?.minY??-50},{x:e.bounds?.maxX??50,y:e.bounds?.minY??-50},{x:e.bounds?.maxX??50,y:e.bounds?.maxY??50},{x:e.bounds?.minX??-50,y:e.bounds?.maxY??50},{x:e.bounds?.minX??-50,y:e.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}];if(e.outline\u0026\u0026e.outline.length\u003e=2){const t=e.outline.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),n.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const o=Oo(e),i={points:[...e.connections.flatMap(t=\u003et.pointsToConnect.map(n=\u003e({...n,layer:Fo(n,e.layerCount),label:`${t.name} ${n.pcb_port_id??\"\"}`})))],rects:[...(e.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,e.layerCount),label:o(t)}))],lines:n};if(!t)return i;const r=Yj({srj:e});return pi(i,r)}visualize(){if(!this.solved\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.getProblemVisualization(),e=this.getProblemVisualization({includeRoutes:!1}),n=this.polyGraphSolver?.visualize(),o=this.attachProjectedRectsSolver?.visualize(),i=this.highDensityRouteSolver?.visualize(),r=this.projectHighDensityToPolgonSolver?.visualize(),s=this.highDensityStitchSolver?.visualize(),a=this.traceSimplificationSolver?.visualize();return pi(...[t,this.escapeViaLocationSolver?.visualize(),this.netToPointPairsSolver?.visualize(),n,o,i?pi(e,i):null,r?pi(e,r):null,s,a,this.solved?pi({lines:e.lines},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean))}preview(){if(this.projectHighDensityToPolgonSolver){const t=[];for(let e=this.projectHighDensityToPolgonSolver.routes.length-1;e\u003e=0;e--){const n=this.projectHighDensityToPolgonSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.polyGraphSolver?this.polyGraphSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){return this.globalDrcForceImproveSolver?.getOutput()??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 o=n.__netConnectionName??this.originalSrj.connections.find(t=\u003et.name===n.name)?.__netConnectionName,i=e.filter(t=\u003et.connectionName===n.name);for(let e=0;e\u003ci.length;e++){const r=i[e],s={type:\"pcb_trace\",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},sG=t=\u003et.rootConnectionName??t.connectionName,aG=(t,e)=\u003et.flatMap((t,n)=\u003esG(t)===e?[n]:[]),cG=(t,e,n,o)=\u003e{const i=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=t.x-e.x,s=t.y-e.y,a=o**2+i**2,c=0===a?0:Math.max(0,Math.min(1,(r*o+s*i)/a));return Math.hypot(t.x-(e.x+c*o),t.y-(e.y+c*i))},r={x:e.x-t.x,y:e.y-t.y},s={x:o.x-n.x,y:o.y-n.y},a={x:n.x-t.x,y:n.y-t.y},c=(t,e)=\u003et.x*e.y-t.y*e.x,l=c(r,s),d=Math.hypot(r.x,r.y),h=1e-12*(d*Math.hypot(s.x,s.y)+1);if(Math.abs(l)\u003eh){const t=c(a,s)/l,e=c(a,r)/l;if(t\u003e=-1e-12\u0026\u0026t\u003c=1+1e-12\u0026\u0026e\u003e=-1e-12\u0026\u0026e\u003c=1+1e-12)return 0}else if(d\u003e1e-12\u0026\u0026Math.abs(c(a,r))\u003c=h){const i=Math.abs(r.x)\u003e=Math.abs(r.y),s=Math.min(i?t.x:t.y,i?e.x:e.y),a=Math.max(i?t.x:t.y,i?e.x:e.y),c=Math.min(i?n.x:n.y,i?o.x:o.y),l=Math.max(i?n.x:n.y,i?o.x:o.y);if(Math.max(s,c)\u003c=Math.min(a,l)+1e-12)return 0}return Math.min(i(t,n,o),i(e,n,o),i(n,t,e),i(o,t,e))},lG=(t,e)=\u003eMath.hypot(e.x-t.x,e.y-t.y),dG=t=\u003e{let e=0;for(let n=0;n\u003ct.route.length-1;n++)e+=lG(t.route[n],t.route[n+1]);return e},hG=(t,e)=\u003ee.reduce((e,n)=\u003ee+dG(t[n]),0),uG=(t,e)=\u003e{const n=t.__zLayers,o=t.zLayers,i=void 0!==n?n:o;if(void 0!==i){if(!Array.isArray(i)||0===i.length||i.some(t=\u003e!Number.isInteger(t)||t\u003c0||t\u003e=e))throw new Error(\"Obstacle has invalid z-layer indexes\");return i}if(0===t.layers.length)throw new Error(\"Obstacle has no declared layers\");return t.layers.map(t=\u003e{if(\"top\"===t)return 0;if(\"bottom\"===t)return e-1;const n=/^inner(\\d+)$/.exec(t),o=n?Number(n[1]):-1;if(o\u003c=0||o\u003e=e-1)throw new Error(`Obstacle has invalid layer name \"${t}\"`);return o})},pG=t=\u003e{const e=(t,e,n,o)=\u003e{const i=n.center.x-n.width/2-o,r=n.center.x+n.width/2+o,s=n.center.y-n.height/2-o,a=n.center.y+n.height/2+o;if(t.x\u003e=i\u0026\u0026t.x\u003c=r\u0026\u0026t.y\u003e=s\u0026\u0026t.y\u003c=a||e.x\u003e=i\u0026\u0026e.x\u003c=r\u0026\u0026e.y\u003e=s\u0026\u0026e.y\u003c=a)return!0;const c=[{x:i,y:s},{x:r,y:s},{x:r,y:a},{x:i,y:a}];return c.some((n,o)=\u003e0===cG(t,e,n,c[(o+1)%c.length]))};if(t.bounds\u0026\u0026t.meanderPoints.some(e=\u003ee.x\u003ct.bounds.minX||e.x\u003et.bounds.maxX||e.y\u003ct.bounds.minY||e.y\u003et.bounds.maxY))return!1;const n=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},o=sG(t.route),i=t.route.traceThickness/2+t.obstacleMargin;for(let r=0;r\u003ct.meanderPoints.length-1;r++){const s=t.meanderPoints[r],a=t.meanderPoints[r+1];for(const n of t.obstacles){if(!uG(n,t.layerCount).includes(s.z))continue;const c=0===r||r===t.meanderPoints.length-2;if((!n.connectedTo.includes(o)||!c)\u0026\u0026e(s,a,n,i))return!1}for(const e of t.routedRoutes){const i=sG(e)===o;for(const o of e.vias){if(o.zLayers\u0026\u0026!o.zLayers.includes(s.z))continue;const r=Math.hypot(o.x-s.x,o.y-s.y)\u003c=1e-8||Math.hypot(o.x-a.x,o.y-a.y)\u003c=1e-8,c=t.route.traceThickness/2+e.viaDiameter/2+t.obstacleMargin;if((!i||!r)\u0026\u0026n(o,s,a)\u003cc)return!1}if(!i)for(let n=0;n\u003ce.route.length-1;n++){const o=e.route[n],i=e.route[n+1];if(s.z!==o.z||s.z!==i.z)continue;const r=t.route.traceThickness/2+e.traceThickness/2+t.obstacleMargin;if(cG(s,a,o,i)\u003cr)return!1}}}return!0},mG=t=\u003e{const e=[];for(const n of t.routeIndexes){const o=t.routes[n],i=t.minMeanderGap??Math.max(.3,2*o.traceThickness),r=o.traceThickness+i,s=Math.max(t.minimumToothPitch??0,2*r),a=t.minMeanderHeight??r;for(let i=0;i\u003co.route.length-1;i++){const r=o.route[i],c=o.route[i+1],l=lG(r,c);if(l\u003c=0||r.z!==c.z)continue;const d=Math.min(Math.max(0,Math.floor(l/s)-1),t.maxToothCount);for(let o=1;o\u003c=d;o++){const r=l/(o+1),c=[r,Math.sqrt(s*r),s].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e-t)\u003c1e-9)===e),d=o%2==0?[\"balanced\",\"negative\",\"positive\"]:[\"negative\",\"positive\"];for(const r of c)for(const s of d)e.push({routeIndex:n,segmentIndex:i,segmentLength:l,toothCount:o,maximumDepth:t.maximumDepth,minimumHeight:a,toothPitch:r,placement:s,heightProfile:o\u003e1?\"tapered\":\"uniform\"})}}}const n={balanced:0,negative:1,positive:2};return e.sort((t,e)=\u003et.toothCount-e.toothCount||n[t.placement]-n[e.placement]||e.toothPitch-t.toothPitch||e.segmentLength-t.segmentLength)},gG=t=\u003e{if(null===t.centerlineDistanceCost)return 0;const e=t.predictedToothDepths.flatMap((t,e)=\u003et\u003e0?[e]:[]);if(0===e.length)return 0;const n=e.map(e=\u003et.predictedToothDepths[e]),o=Math.max(...n),i=n.reduce((t,e)=\u003et+e,0)/n.length,r=Math.sqrt(n.reduce((t,e)=\u003et+(e-i)**2,0)/n.length),s=e[0],a=(e.at(-1)-s+1)*t.toothPitch,c=o/(t.toothPitch/2),l=t.addedLength/a,d=c/(1+c)*40,h=l/(1+l)*30,u=t.predictedToothDepths.map((e,n)=\u003eMath.sin(Math.PI*(n+1)/(t.predictedToothDepths.length+1))),p=Math.max(...u),m=Math.sqrt(t.predictedToothDepths.reduce((t,e,n)=\u003et+(e-o*u[n]/p)**2,0)/t.predictedToothDepths.length),g=100-d-h-Math.min(10,(\"tapered\"===t.heightProfile?m:r)/i*10)-2*(n.length-1)-7*Math.min(1,t.addedLength/t.segmentLength)-100*t.centerlineDistanceCost,f=t.centerlineDistanceCost\u003e0?g:Math.max(0,g);return Math.round(1e6*f)/1e6},fG=t=\u003e{if(t.toothDepths.length!==t.toothCount)throw new Error(`LengthMatchingSolver: expected ${t.toothCount} tooth depths, received ${t.toothDepths.length}`);if(t.toothDepths.some(t=\u003e!Number.isFinite(t)||t\u003c0))throw new Error(\"LengthMatchingSolver: every meander tooth depth must be a non-negative finite number\");const e=t.route.route[t.segmentIndex],n=t.route.route[t.segmentIndex+1],o=lG(e,n),i=(n.x-e.x)/o,r=(n.y-e.y)/o,s=(o-(t.toothCount-.5)*t.toothPitch)/2,a=[{...e}];for(let n=0;n\u003ct.toothCount;n++){const o=t.toothDepths[n];if(0===o)continue;const c=\"balanced\"===t.placement?n%2==0?-1:1:\"negative\"===t.placement?-1:1,l={x:-r*c,y:i*c},d=s+n*t.toothPitch,h=d+t.toothPitch/2,u={...e,x:e.x+i*d,y:e.y+r*d};a.push(u,{...u,x:u.x+l.x*o,y:u.y+l.y*o},{...e,x:e.x+i*h+l.x*o,y:e.y+r*h+l.y*o},{...e,x:e.x+i*h,y:e.y+r*h})}return a.push({...n}),(t=\u003e{if(t.length\u003c3)return t;const e=[{...t[0]}];for(let n=1;n\u003ct.length-1;n++){const o=t[n-1],i=t[n],r=t[n+1],s=Math.hypot(i.x-o.x,i.y-o.y),a=Math.hypot(r.x-i.x,r.y-i.y);if(0===s||0===a)throw new Error(\"LengthMatchingSolver: meander contains a zero-length segment\");const c={x:(i.x-o.x)/s,y:(i.y-o.y)/s},l={x:(r.x-i.x)/a,y:(r.y-i.y)/a};if(Math.abs(c.x*l.y-c.y*l.x)\u003c1e-9){e.push({...i});continue}const d=Math.min(s,a)/2,h={...i,x:i.x-c.x*d,y:i.y-c.y*d},u={...i,x:i.x+l.x*d,y:i.y+l.y*d},p=e.at(-1);h.x===p.x\u0026\u0026h.y===p.y||e.push(h);for(let t=1;t\u003c6;t++){const n=t/6,o=1-n;e.push({...i,x:o**2*h.x+2*o*n*i.x+n**2*u.x,y:o**2*h.y+2*o*n*i.y+n**2*u.y})}e.push(u)}return e.push({...t[t.length-1]}),e})(a)},yG=t=\u003e[...t.route.route.slice(0,t.segmentIndex),...fG(t),...t.route.route.slice(t.segmentIndex+2)],_G=t=\u003e{const e=dG(t.route),n=(()=\u003e{const e=[];for(let n=0;n\u003ct.candidate.toothCount;n++){const o=Array(t.candidate.toothCount).fill(0);o[n]=t.candidate.maximumDepth;const i=fG({...t.candidate,route:t.route,toothDepths:o});if(t.isGeometryValid(i)){e.push(t.candidate.maximumDepth);continue}let r=0,s=t.candidate.maximumDepth;for(let e=0;e\u003c32;e++){const e=(r+s)/2,o=Array(t.candidate.toothCount).fill(0);o[n]=e;const i=fG({...t.candidate,route:t.route,toothDepths:o});t.isGeometryValid(i)?r=e:s=e}e.push(r)}return e})(),o=(t=\u003e{if(\"tapered\"!==t.heightProfile)return Array(t.toothCount).fill(1);const e=Array.from({length:t.toothCount},(e,n)=\u003eMath.sin(Math.PI*(n+1)/(t.toothCount+1))),n=Math.max(...e);return e.map(t=\u003et/n)})(t.candidate),i=t.candidate.maximumDepth,r=n.map((t,e)=\u003eMath.min(t,i*o[e])),s=[.25,.75],a=r.map(t=\u003et*s[0]),c=r.map(t=\u003et*s[1]),l=yG({...t.candidate,route:t.route,toothDepths:a}),d=yG({...t.candidate,route:t.route,toothDepths:c}),h=[dG({...t.route,route:l})-e,dG({...t.route,route:d})-e],u=yG({...t.candidate,route:t.route,toothDepths:r}),p=dG({...t.route,route:u})-e,m=(h[1]-h[0])/(s[1]-s[0]),g=h[0]-m*s[0],f=m\u003e0\u0026\u0026Number.isFinite(m)?(t.targetAddedLength-g)/m:0,y=Math.min(t.targetAddedLength,p),_=t.targetAddedLength\u003e0\u0026\u0026y\u003e0?(e=\u003e{let n=0,o=t.candidate.maximumDepth;for(let i=0;i\u003c32;i++){const i=(n+o)/2,r=e.maximumToothDepths.map((t,n)=\u003eMath.min(t,i*e.toothHeightWeights[n])),s=yG({...t.candidate,route:t.route,toothDepths:r}),a=dG({...t.route,route:s})-e.originalLength,c=fG({...t.candidate,route:t.route,toothDepths:r});t.isGeometryValid(c)?a\u003ce.targetAddedLength?n=i:o=i:o=i}const i=(n+o)/2;return{depthLevel:i,toothDepths:e.maximumToothDepths.map((t,n)=\u003eMath.min(t,i*e.toothHeightWeights[n]))}})({maximumToothDepths:n,toothHeightWeights:o,originalLength:e,targetAddedLength:y}):{depthLevel:f*i,toothDepths:r.map(t=\u003eMath.max(0,t*f))},b=_.depthLevel/i,x=_.toothDepths,v=yG({...t.candidate,route:t.route,toothDepths:x}),S=dG({...t.route,route:v})-e,I=Math.abs(y-S),C=fG({...t.candidate,route:t.route,toothDepths:x});let P=0;if(t.getCenterlineDistanceCost\u0026\u0026(P=t.getCenterlineDistanceCost(C)),null!==P\u0026\u0026(!Number.isFinite(P)||P\u003c0))throw new Error(\"LengthMatchingSolver: meander centerline distance cost must be a non-negative finite number\");const M=Number.isFinite(b)\u0026\u0026b\u003e0\u0026\u0026b\u003c=1,N=x.every(e=\u003e0===e||e\u003e=t.candidate.minimumHeight),w=t.isGeometryValid(C);let T,R=null;null===P?R=\"no-paired-same-layer-geometry\":M?I\u003et.lengthTolerance?R=\"target-error\":w?N||(R=\"below-minimum-height\"):R=\"invalid-geometry\":R=\"invalid-scale\",T=R?{valid:!1,invalidReason:R}:{valid:!0,invalidReason:null};const E={...t.candidate,connectionName:t.connectionName,maximumToothDepths:n,sampleScaleFactors:s,sampleAddedLengths:h,slope:m,intercept:g,predictedScaleFactor:b,predictedToothDepths:x,predictedRoute:v,addedLength:S,maximumAddedLength:p,resultingError:I,testedSegment:[{...t.route.route[t.candidate.segmentIndex]},{...t.route.route[t.candidate.segmentIndex+1]}],meanderPoints:C,centerlineDistanceCost:P,qualityScore:0,...T};return{...E,qualityScore:gG(E)}},bG=t=\u003e{const e=(t=\u003e{if(\"tapered\"!==t.heightProfile)return Array(t.toothCount).fill(1);const e=Array.from({length:t.toothCount},(e,n)=\u003eMath.sin(Math.PI*(n+1)/(t.toothCount+1))),n=Math.max(...e);return e.map(t=\u003et/n)})(t.candidate),n=Math.max(...e.map(e=\u003et.candidate.minimumHeight/e)),o=t.candidate.maximumDepth/2**30,i=e.map(t=\u003et*(n+o));if(i.some(e=\u003ee\u003et.candidate.maximumDepth))return null;const r=fG({...t.candidate,route:t.route,toothDepths:i});if(!t.isGeometryValid(r))return null;const s=yG({...t.candidate,route:t.route,toothDepths:i}),a=dG({...t.route,route:s})-dG(t.route),c=_G({...t,targetAddedLength:a});return c.valid?c:null},xG=t=\u003e{const e=(t,e)=\u003e{const n=t[e.routeIndex];if(!n)throw new Error(`LengthMatchingSolver: dual meander references missing route ${e.routeIndex}`);const o=[...t];return o[e.routeIndex]={...n,route:e.predictedRoute},o},n=(()=\u003e{if(t.targetAddedLength+t.config.lengthTolerance\u003ct.plan.minimumAddedLength||t.targetAddedLength-t.config.lengthTolerance\u003et.plan.maximumAddedLength)return null;const e=t.plan.attemptOptions.map(t=\u003eMath.min(...t.map(t=\u003et.attempt.addedLength)));let n=Math.max(0,t.targetAddedLength-t.plan.minimumAddedLength),o=e.map((t,e)=\u003ee);for(;n\u003e1e-9\u0026\u0026o.length\u003e0;){const i=n/o.length;let r=0;const s=[];for(const n of o){const o=Math.max(...t.plan.attemptOptions[n].map(t=\u003et.attempt.maximumAddedLength))-e[n],a=Math.min(o,i);e[n]+=a,r+=a,o-a\u003e1e-9\u0026\u0026s.push(n)}if(r\u003c=1e-9)break;n-=r,o=s}return n\u003c=t.config.lengthTolerance?e:null})();if(!n)return null;const o=t.plan.attemptOptions.map((t,e)=\u003e({attemptOptions:t,targetAddedLength:n[e]})).sort((t,e)=\u003ee.attemptOptions[0].candidate.routeIndex-t.attemptOptions[0].candidate.routeIndex||e.attemptOptions[0].candidate.segmentIndex-t.attemptOptions[0].candidate.segmentIndex);let i=[...t.routes];const r=[];for(const n of o){const o=n.attemptOptions[0]?.candidate;if(!o)throw new Error(\"LengthMatchingSolver: empty dual-meander segment options\");const s=i[o.routeIndex];if(!s)throw new Error(`LengthMatchingSolver: missing planned dual-meander route ${o.routeIndex}`);let a=null;for(const e of n.attemptOptions){if(e.attempt.addedLength-t.config.lengthTolerance\u003en.targetAddedLength||e.attempt.maximumAddedLength+t.config.lengthTolerance\u003cn.targetAddedLength)continue;const o=_G({candidate:e.candidate,route:s,connectionName:t.connectionName,targetAddedLength:n.targetAddedLength,lengthTolerance:t.config.lengthTolerance,isGeometryValid:e=\u003epG({route:s,meanderPoints:e,routedRoutes:t.excludedConnectionName?i.filter(e=\u003esG(e)!==t.excludedConnectionName):i,...t.config})});o.valid\u0026\u0026(!a||o.qualityScore\u003ea.qualityScore)\u0026\u0026(a=o)}if(!a)return null;i=e(i,a),r.push(a)}const s=r.reduce((t,e)=\u003et+e.addedLength,0);if(Math.abs(s-t.targetAddedLength)\u003et.config.lengthTolerance)return null;const a=r[0];if(!a)throw new Error(\"LengthMatchingSolver: fitted an empty dual-meander plan\");return{attempts:[a,...r.slice(1)],routes:i,addedLength:s}},vG=t=\u003e{if(0===t.length)throw new Error(\"LengthMatchingSolver: cannot score an empty meander plan\");return t.reduce((t,e)=\u003et+e.qualityScore,0)/t.length-3*(t.length-1)},SG=t=\u003e{const e=t=\u003e[t.candidate.toothCount,t.candidate.placement,t.candidate.heightProfile].join(\":\"),n=new Map;for(const o of t){const t=e(o),i=`${o.candidate.routeIndex}:${o.candidate.segmentIndex}`,r=n.get(t);if(!r){n.set(t,new Map([[i,[o]]]));continue}const s=r.get(i);s?s.push(o):r.set(i,[o])}const o=[];for(const t of n.values()){const e=[...t.values()].map(t=\u003e({attempts:t,maximumAddedLength:Math.max(...t.map(t=\u003et.attempt.maximumAddedLength)),minimumAddedLength:Math.min(...t.map(t=\u003et.attempt.addedLength)),rankingAttempt:t.reduce((t,e)=\u003ee.attempt.qualityScore\u003et.attempt.qualityScore?e:t)})).sort((t,e)=\u003ee.maximumAddedLength-t.maximumAddedLength);for(const t of e)o.push({attempts:[t.rankingAttempt],attemptOptions:[t.attempts],minimumAddedLength:t.minimumAddedLength,maximumAddedLength:t.maximumAddedLength,rankingQualityScore:t.rankingAttempt.attempt.qualityScore});for(let t=2;t\u003c=e.length;t++){const n=e.slice(0,t),i=n.map(t=\u003et.rankingAttempt);o.push({attempts:i,attemptOptions:n.map(t=\u003et.attempts),minimumAddedLength:n.reduce((t,e)=\u003et+e.minimumAddedLength,0),maximumAddedLength:n.reduce((t,e)=\u003et+e.maximumAddedLength,0),rankingQualityScore:vG(i.map(t=\u003et.attempt))})}}return o},IG=class extends Error{connectionName;reason;constructor(t){super(t.message),this.name=\"LengthMatchingNoSolutionError\",this.connectionName=t.connectionName,this.reason=t.reason}},CG=t=\u003e[t.routeIndex,t.segmentIndex,t.toothCount,t.placement,t.toothPitch,t.heightProfile,t.maximumDepth,t.minimumHeight].join(\":\"),PG=t=\u003e{const e=new Map,n=[...t.attempts].sort((t,e)=\u003et.addedLength-e.addedLength);let o=t.targetAddedLength;for(let t=0;t\u003cn.length;t++){const i=n[t],r=Math.min(i.addedLength,o/(n.length-t));e.set(CG(i),{routeIndex:i.routeIndex,segmentIndex:i.segmentIndex,targetAddedLength:r}),o-=r}return e},MG=(t,e)=\u003e`z${uG(t,e).join(\",\")}`,NG=t=\u003e`z${t}`,wG=t=\u003e{if(!t.showAttempt)return;if(!t.attempt)return void(t=\u003e{const e=t.activePair?.candidates[t.activePair.candidateIndex];if(!e)return;const n=t.routes[e.routeIndex];if(!n)return;const o=n.route[e.segmentIndex],i=n.route[e.segmentIndex+1];o\u0026\u0026i\u0026\u0026t.graphics.lines.push({points:[o,i],strokeColor:\"rgba(234, 179, 8, 0.6)\",strokeWidth:2*n.traceThickness,strokeDash:[.1,.1],layer:NG(o.z)})})(t);const e=t.routes[t.attempt.routeIndex],[n,o]=t.attempt.testedSegment,i=t.theme.getConnectionColor(t.attempt.connectionName);t.graphics.lines.push({points:[n,o],strokeColor:t.theme.getTestedSegmentColor(i),strokeWidth:e.traceThickness,strokeDash:[.15,.15],layer:NG(n.z)}),t.attempt.valid?t.graphics.lines.push({points:t.attempt.meanderPoints.map(({x:t,y:e})=\u003e({x:t,y:e})),strokeColor:\"rgba(234, 179, 8, 0.6)\",strokeWidth:2*e.traceThickness,strokeDash:[.1,.1],layer:NG(n.z)}):t.graphics.lines.push({points:t.attempt.meanderPoints.map(({x:t,y:e})=\u003e({x:t,y:e})),strokeColor:t.theme.getRejectedCandidateColor(i),strokeWidth:e.traceThickness,strokeDash:[.1,.1],layer:NG(n.z)}),t.graphics.points.push({x:n.x,y:n.y,color:i,layer:NG(n.z)},{x:o.x,y:o.y,color:i,layer:NG(o.z)})},TG=t=\u003e{const e={lines:[],points:[],rects:[],circles:[]},n=(t=\u003e{for(const e of Object.values(t))Tt(0,e);return{getConnectionColor:(e,n)=\u003et[e]??(n?t[n]:void 0)??(t=\u003et?`hsl(${300*t.split(\"\").reduce((t,e)=\u003et+e.charCodeAt(0),0)/t.length%360}, 100%, 50%)`:\"rgba(0, 0, 0, 0.5)\")(e),getInnerLayerConnectionColor:t=\u003eTt(.5,t),getTestedSegmentColor:t=\u003eTt(.55,t),getRejectedCandidateColor:t=\u003eTt(.45,t),boardBounds:{fill:\"rgba(30,41,59,0.03)\",stroke:\"rgba(30,41,59,0.55)\"},obstacle:{fill:\"rgba(255,0,0,0.25)\",stroke:\"rgba(255,0,0,0.5)\"},via:{fill:\"blue\",stroke:\"none\"}}})(t.colorMap);return(t=\u003e{for(const e of t.routes){const n=sG(e),o=t.theme.getConnectionColor(n,e.connectionName);for(let n=0;n\u003ce.route.length-1;n++){const i=e.route[n],r=e.route[n+1];i.z===r.z\u0026\u0026t.graphics.lines.push({points:[i,r],strokeColor:0===i.z?o:t.theme.getInnerLayerConnectionColor(o),strokeWidth:e.traceThickness,...0===i.z?{}:{strokeDash:[.2,.2]},layer:NG(i.z)})}const i=[...new Set(e.route.map(t=\u003et.z))];for(const n of e.vias)t.graphics.circles.push({center:n,radius:e.viaDiameter/2,fill:t.theme.via.fill,stroke:t.theme.via.stroke,layer:`z${(n.zLayers??i).join(\",\")}`})}})({routes:t.routes,theme:n,graphics:e}),(t=\u003e{if(t.bounds){const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds;t.graphics.rects.push({center:{x:(e+n)/2,y:(o+i)/2},width:n-e,height:i-o,fill:t.theme.boardBounds.fill,stroke:t.theme.boardBounds.stroke,layer:`z${Array.from({length:t.layerCount},(t,e)=\u003ee).join(\",\")}`})}for(const e of t.obstacles)t.graphics.rects.push({center:e.center,width:e.width,height:e.height,ccwRotationDegrees:e.ccwRotationDegrees,fill:t.theme.obstacle.fill,stroke:t.theme.obstacle.stroke,layer:MG(e,t.layerCount)})})({obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,theme:n,graphics:e}),wG({routes:t.routes,attempt:t.currentAttempt,activePair:t.activePair,showAttempt:!t.solved,theme:n,graphics:e}),{...e}},RG=class extends kt{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1e5,this.matchedHdRoutes=t.hdRoutes.map(t=\u003e({...t,route:t.route.map(t=\u003e({...t}))})),this.pairs=t.differentialPairs??[]}params;matchedHdRoutes;pairs;nextPairIndex=0;activePair=null;currentAttempt=null;config=null;candidatesTried=0;getSolverName(){return\"LengthMatchingSolver\"}startNextPair(){const t=this.pairs[this.nextPairIndex++];if(!t)return void(this.solved=!0);((t,e)=\u003e{if(t.connectionNames[0]===t.connectionNames[1])throw new Error(\"LengthMatchingSolver: a differential pair must reference two distinct connections\");if(!Number.isFinite(t.lengthTolerance)||t.lengthTolerance\u003c0)throw new Error(\"LengthMatchingSolver: differential pair lengthTolerance must be a non-negative finite number\");for(const e of[t.minimumCenterlineDistance,t.maximumCenterlineDistance])if(void 0!==e\u0026\u0026(!Number.isFinite(e)||e\u003c=0))throw new Error(\"LengthMatchingSolver: differential pair centerline distances must be positive finite numbers\");if(void 0!==t.minimumCenterlineDistance\u0026\u0026void 0!==t.maximumCenterlineDistance\u0026\u0026t.minimumCenterlineDistance\u003et.maximumCenterlineDistance)throw new Error(\"LengthMatchingSolver: differential pair minimumCenterlineDistance cannot exceed maximumCenterlineDistance\");const n=new Map(e.map(t=\u003e[t.name,t]));for(const e of t.connectionNames){const t=n.get(e);if(!t)throw new Error(`LengthMatchingSolver: differential pair references unknown connection \"${e}\"`);if(2!==t.pointsToConnect.length)throw new Error(`LengthMatchingSolver: differential pair connection \"${e}\" must have exactly two points before MST splitting`)}})(t,this.params.originalConnections);const e=aG(this.matchedHdRoutes,t.connectionNames[0]),n=aG(this.matchedHdRoutes,t.connectionNames[1]);if(0===e.length\u0026\u00260===n.length)return;if(0===e.length||0===n.length)throw new Error(`LengthMatchingSolver: differential pair ${t.connectionNames.join(\"/\")} has routed geometry for only one connection`);const o=hG(this.matchedHdRoutes,e),i=hG(this.matchedHdRoutes,n),r=Math.abs(o-i);if(r\u003c=t.lengthTolerance)return;const s=o\u003ci,a=t.connectionNames[s?0:1],c=t.connectionNames[s?1:0],l=mG({routes:this.matchedHdRoutes,routeIndexes:s?e:n,maximumDepth:this.getConfig().maximumMeanderDepth,minimumToothPitch:this.getConfig().minimumToothPitch,minMeanderGap:this.getConfig().minMeanderGap,minMeanderHeight:this.getConfig().minMeanderHeight,maxToothCount:this.getConfig().maxToothCount});if(0===l.length)throw new IG({message:`LengthMatchingSolver: no same-layer straight segment can tune connection \"${a}\"`,connectionName:a,reason:\"no-meander-candidate\"});this.activePair={pair:t,longerConnectionName:c,longerRouteIndexes:s?n:e,shorterConnectionName:a,targetAddedLength:r,remainingAddedLength:r,candidates:l,candidateIndex:0,lastMatchedSegmentIndexByRoute:new Map,partialAttempts:[],fullAttempts:[],plannedAttemptTargets:null,hasMinimumHeightBlockedAttempt:!1}}acceptAttempt(t,e){const n=this.matchedHdRoutes[e.routeIndex];this.matchedHdRoutes[e.routeIndex]={...n,route:e.predictedRoute},t.remainingAddedLength-=e.addedLength,t.lastMatchedSegmentIndexByRoute.set(e.routeIndex,e.segmentIndex),t.candidateIndex=0,t.partialAttempts=[],t.fullAttempts=[],t.plannedAttemptTargets?.delete(CG(e)),0===t.plannedAttemptTargets?.size\u0026\u0026(t.plannedAttemptTargets=null),t.remainingAddedLength\u003c=t.pair.lengthTolerance\u0026\u0026(this.activePair=null)}tryCandidate(t){let e;for(;!e;){const n=t.candidates[t.candidateIndex++];if(!n)break;const o=t.lastMatchedSegmentIndexByRoute.get(n.routeIndex);(void 0===o||n.segmentIndex\u003co)\u0026\u0026(!t.plannedAttemptTargets||t.plannedAttemptTargets.has(CG(n))\u0026\u0026![...t.plannedAttemptTargets.values()].some(t=\u003et.routeIndex===n.routeIndex\u0026\u0026t.segmentIndex\u003en.segmentIndex))\u0026\u0026(e=n)}if(!e){const e=t.fullAttempts.reduce((t,e)=\u003e!t||e.qualityScore\u003et.qualityScore?e:t,null),n=(t=\u003e{const e=t=\u003e[t.toothCount,t.placement,t.heightProfile].join(\":\"),n=new Map;for(const o of t.attempts){const t=`${o.routeIndex}:${o.segmentIndex}`,i=e(o),r=n.get(i);if(!r){n.set(i,new Map([[t,[o]]]));continue}const s=r.get(t);s?s.push(o):r.set(t,[o])}let o=null;for(const e of n.values()){const n=[...e.values()].map(t=\u003e({attempts:t,maximumCapacityAttempt:t.reduce((t,e)=\u003ee.addedLength\u003et.addedLength?e:t)})).sort((t,e)=\u003ee.maximumCapacityAttempt.addedLength-t.maximumCapacityAttempt.addedLength);let i=0;for(let e=0;e\u003cn.length;e++){if(i+=n[e].maximumCapacityAttempt.addedLength,i+t.lengthTolerance\u003ct.targetAddedLength)continue;const r=n.slice(0,e+1),s=r.map(t=\u003et.maximumCapacityAttempt),a=PG({attempts:s,targetAddedLength:t.targetAddedLength}),c=r.map(e=\u003e{const n=a.get(CG(e.maximumCapacityAttempt));if(!n)throw new Error(`LengthMatchingSolver: missing capacity target for ${CG(e.maximumCapacityAttempt)}`);const o=e.attempts.filter(e=\u003ee.addedLength+t.lengthTolerance\u003e=n.targetAddedLength);if(0===o.length)throw new Error(`LengthMatchingSolver: no pitch can supply planned target for route ${e.maximumCapacityAttempt.routeIndex} segment ${e.maximumCapacityAttempt.segmentIndex}`);return o.reduce((t,e)=\u003ee.qualityScore\u003et.qualityScore||e.qualityScore===t.qualityScore\u0026\u0026e.toothPitch\u003et.toothPitch?e:t)}),l=vG(c);if(!o){o={attempts:c};break}const d=vG(o.attempts);(c.length\u003co.attempts.length||c.length===o.attempts.length\u0026\u0026l\u003ed)\u0026\u0026(o={attempts:c});break}}return o})({attempts:t.partialAttempts,targetAddedLength:t.remainingAddedLength,lengthTolerance:t.pair.lengthTolerance});if(e\u0026\u0026(!n||e.qualityScore\u003e=vG(n.attempts)))return void this.acceptAttempt(t,e);if(!n){if(!(t.hasMinimumHeightBlockedAttempt\u0026\u0026null===t.plannedAttemptTargets\u0026\u00260===t.lastMatchedSegmentIndexByRoute.size))throw new IG({message:`LengthMatchingSolver: linear regression exhausted all segment/tooth combinations for \"${t.shorterConnectionName}\"; required ${t.targetAddedLength.toFixed(4)}mm`,connectionName:t.shorterConnectionName,reason:\"meander-search-exhausted\"});return this.tryDualMeanderPlan(t)}return t.plannedAttemptTargets=PG({attempts:n.attempts,targetAddedLength:t.remainingAddedLength}),t.candidateIndex=0,t.partialAttempts=[],void(t.fullAttempts=[])}const n=this.matchedHdRoutes[e.routeIndex],o=this.getConfig(),i=t.plannedAttemptTargets?.get(CG(e));if(null!==t.plannedAttemptTargets\u0026\u0026void 0===i)throw new Error(`LengthMatchingSolver: missing planned target for ${CG(e)}`);this.currentAttempt=_G({candidate:e,route:n,connectionName:t.shorterConnectionName,targetAddedLength:void 0===i?t.remainingAddedLength:i.targetAddedLength,lengthTolerance:t.pair.lengthTolerance,isGeometryValid:t=\u003epG({route:n,meanderPoints:t,routedRoutes:this.matchedHdRoutes,obstacles:o.obstacles,bounds:o.bounds,layerCount:o.layerCount,obstacleMargin:o.obstacleMargin}),getCenterlineDistanceCost:void 0===t.pair.minimumCenterlineDistance\u0026\u0026void 0===t.pair.maximumCenterlineDistance?void 0:e=\u003e(t=\u003e{let e=0,n=0;for(let o=0;o\u003ct.meanderPoints.length-1;o++){const i=t.meanderPoints[o],r=t.meanderPoints[o+1],s=Math.hypot(r.x-i.x,r.y-i.y);if(0!==s){for(let e=0;e\u003c4;e++){const o=(e+.5)/4,a={x:i.x+(r.x-i.x)*o,y:i.y+(r.y-i.y)*o},c=[];for(const e of t.pairedRoutes)for(let t=0;t\u003ce.route.length-1;t++){const n=e.route[t],o=e.route[t+1];i.z===n.z\u0026\u0026i.z===o.z\u0026\u0026c.push(cG(a,a,n,o))}if(0===c.length)return null;const l=Math.min(...c);n+=s*Math.max(0,(t.minimumCenterlineDistance??Number.NEGATIVE_INFINITY)-l,l-(t.maximumCenterlineDistance??Number.POSITIVE_INFINITY))/4}e+=s}}if(0===e)throw new Error(\"LengthMatchingSolver: cannot measure a zero-length meander centerline\");return n/e})({meanderPoints:e,pairedRoutes:t.longerRouteIndexes.map(t=\u003ethis.matchedHdRoutes[t]),minimumCenterlineDistance:t.pair.minimumCenterlineDistance,maximumCenterlineDistance:t.pair.maximumCenterlineDistance})}),this.candidatesTried++,\"below-minimum-height\"===this.currentAttempt.invalidReason\u0026\u0026(t.hasMinimumHeightBlockedAttempt=!0),this.stats={pair:`${t.pair.connectionNames[0]}/${t.pair.connectionNames[1]}`,candidatesTried:this.candidatesTried,segmentIndex:e.segmentIndex,toothCount:e.toothCount,toothPitch:e.toothPitch,placement:e.placement,predictedScaleFactor:this.currentAttempt.predictedScaleFactor,predictedToothDepths:this.currentAttempt.predictedToothDepths,resultingError:this.currentAttempt.resultingError,qualityScore:this.currentAttempt.qualityScore,accepted:this.currentAttempt.valid},this.currentAttempt.valid\u0026\u0026(null===t.plannedAttemptTargets?t.remainingAddedLength-this.currentAttempt.addedLength\u003c=t.pair.lengthTolerance?t.fullAttempts.push(this.currentAttempt):t.partialAttempts.push(this.currentAttempt):this.acceptAttempt(t,this.currentAttempt))}tryDualMeanderPlan(t){if(t.remainingAddedLength!==t.targetAddedLength)throw new Error(`LengthMatchingSolver: cannot start a dual-meander plan after partially tuning \"${t.shorterConnectionName}\"`);const e=this.getConfig(),n=mG({routes:this.matchedHdRoutes,routeIndexes:t.longerRouteIndexes,maximumDepth:e.maximumMeanderDepth,minimumToothPitch:e.minimumToothPitch,minMeanderGap:e.minMeanderGap,minMeanderHeight:e.minMeanderHeight,maxToothCount:e.maxToothCount}),o=(t=\u003e{const e=(t,e)=\u003et.rankingQualityScore!==e.rankingQualityScore?t.rankingQualityScore\u003ee.rankingQualityScore:t.leftIndex!==e.leftIndex?t.leftIndex\u003ce.leftIndex:t.rightIndex\u003ce.rightIndex,n=(t,n)=\u003e{t.push(n);let o=t.length-1;for(;o\u003e0;){const i=Math.floor((o-1)/2),r=t[i];if(e(r,n))break;t[o]=r,o=i}t[o]=n},o=t=\u003e{const n=t[0],o=t.pop();if(!n||!o||0===t.length)return n;let i=0;for(;;){const n=2*i+1,r=n+1;if(n\u003e=t.length)break;const s=r\u003ct.length\u0026\u0026e(t[r],t[n])?r:n,a=t[s];if(e(o,a))break;t[i]=a,i=s}return t[i]=o,n},i=function*(t){const e=[...t.leftOptions].sort((e,n)=\u003et.getLeftQualityScore(n)-t.getLeftQualityScore(e)),i=[...t.rightOptions].sort((e,n)=\u003et.getRightQualityScore(n)-t.getRightQualityScore(e)),r=[];for(let o=0;o\u003ce.length;o++){const s=i[0];if(!s)break;n(r,{leftIndex:o,rightIndex:0,rankingQualityScore:(t.getLeftQualityScore(e[o])+t.getRightQualityScore(s))/2})}for(;r.length\u003e0;){const s=o(r);yield[e[s.leftIndex],i[s.rightIndex]];const a=s.rightIndex+1,c=i[a];c\u0026\u0026n(r,{leftIndex:s.leftIndex,rightIndex:a,rankingQualityScore:(t.getLeftQualityScore(e[s.leftIndex])+t.getRightQualityScore(c))/2})}},r=(t,e)=\u003e{const n=t[e.routeIndex];if(!n)throw new Error(`LengthMatchingSolver: dual meander references missing route ${e.routeIndex}`);const o=[...t];return o[e.routeIndex]={...n,route:e.predictedRoute},o},s=t=\u003e{const e=t.routes[t.attempt.routeIndex];if(!e)throw new Error(`LengthMatchingSolver: cannot validate missing dual-meander route ${t.attempt.routeIndex}`);return pG({route:e,meanderPoints:t.attempt.meanderPoints,routedRoutes:t.routes,...t.config})},a=t=\u003e{const e=t.routes.filter(e=\u003esG(e)!==t.counterpartConnectionName),n=[];for(const o of t.candidates){const i=t.routes[o.routeIndex];if(!i)throw new Error(`LengthMatchingSolver: dual-meander candidate references missing route ${o.routeIndex}`);const r=bG({candidate:o,route:i,connectionName:t.connectionName,lengthTolerance:t.config.lengthTolerance,isGeometryValid:n=\u003epG({route:i,meanderPoints:n,routedRoutes:e,...t.config})});r\u0026\u0026n.push({candidate:o,attempt:r})}return n},c={obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,obstacleMargin:t.obstacleMargin},l=a({candidates:t.shorterCandidates,routes:t.routes,connectionName:t.shorterConnectionName,counterpartConnectionName:t.longerConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(0===l.length)return null;const d=a({candidates:t.longerCandidates,routes:t.routes,connectionName:t.longerConnectionName,counterpartConnectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}}),h=i({leftOptions:d,rightOptions:l,getLeftQualityScore:t=\u003et.attempt.qualityScore,getRightQualityScore:t=\u003et.attempt.qualityScore});for(const[e,n]of h){const o=Math.max(e.attempt.addedLength,n.attempt.addedLength-t.originalLengthDifference),i=o+t.originalLengthDifference;if(o-t.lengthTolerance\u003ee.attempt.maximumAddedLength||i-t.lengthTolerance\u003en.attempt.maximumAddedLength)continue;const a=t.routes[e.candidate.routeIndex];if(!a)throw new Error(`LengthMatchingSolver: missing longer route ${e.candidate.routeIndex}`);const l=t.routes[n.candidate.routeIndex];if(!l)throw new Error(`LengthMatchingSolver: missing shorter route ${n.candidate.routeIndex}`);const d=t.routes.filter(e=\u003esG(e)!==t.shorterConnectionName),h=_G({candidate:e.candidate,route:a,connectionName:t.longerConnectionName,targetAddedLength:o,lengthTolerance:t.lengthTolerance,isGeometryValid:t=\u003epG({route:a,meanderPoints:t,routedRoutes:d,...c})});if(!h.valid||Math.abs(h.addedLength-o)\u003et.lengthTolerance)continue;const u=r(t.routes,h),p=h.addedLength+t.originalLengthDifference,m=_G({candidate:n.candidate,route:l,connectionName:t.shorterConnectionName,targetAddedLength:p,lengthTolerance:t.lengthTolerance,isGeometryValid:t=\u003epG({route:l,meanderPoints:t,routedRoutes:u,...c})});if(!m.valid)continue;const g=r(u,m),f=aG(g,t.longerConnectionName),y=aG(g,t.shorterConnectionName);if(!(Math.abs(hG(g,y)-hG(g,f))\u003et.lengthTolerance)\u0026\u0026s({attempt:h,routes:g,config:c})\u0026\u0026s({attempt:m,routes:g,config:c}))return{longerAttempts:[h],shorterAttempts:[m]}}const u=i({leftOptions:SG(d),rightOptions:SG(l),getLeftQualityScore:t=\u003et.rankingQualityScore,getRightQualityScore:t=\u003et.rankingQualityScore});for(const[e,n]of u){if(1===e.attempts.length\u0026\u00261===n.attempts.length)continue;const o=Math.max(e.minimumAddedLength,n.minimumAddedLength-t.originalLengthDifference),i=o+t.originalLengthDifference;if(o-t.lengthTolerance\u003ee.maximumAddedLength||i-t.lengthTolerance\u003en.maximumAddedLength)continue;const r=xG({plan:e,targetAddedLength:o,routes:t.routes,connectionName:t.longerConnectionName,excludedConnectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(!r)continue;const a=xG({plan:n,targetAddedLength:r.addedLength+t.originalLengthDifference,routes:r.routes,connectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(!a)continue;const l=aG(a.routes,t.longerConnectionName),d=aG(a.routes,t.shorterConnectionName),h=Math.abs(hG(a.routes,d)-hG(a.routes,l)),u=[...r.attempts,...a.attempts];if(!(h\u003et.lengthTolerance||u.some(t=\u003e!s({attempt:t,routes:a.routes,config:c}))))return{longerAttempts:r.attempts,shorterAttempts:a.attempts}}return null})({routes:this.matchedHdRoutes,longerConnectionName:t.longerConnectionName,shorterConnectionName:t.shorterConnectionName,originalLengthDifference:t.targetAddedLength,lengthTolerance:t.pair.lengthTolerance,longerCandidates:n,shorterCandidates:t.candidates,obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,obstacleMargin:e.obstacleMargin});if(!o)throw new IG({message:`LengthMatchingSolver: linear regression exhausted all segment/tooth combinations for \"${t.shorterConnectionName}\"; required ${t.targetAddedLength.toFixed(4)}mm`,connectionName:t.shorterConnectionName,reason:\"meander-search-exhausted\"});const i=[...this.matchedHdRoutes];for(const t of[...o.longerAttempts,...o.shorterAttempts]){const e=this.matchedHdRoutes[t.routeIndex];if(!e)throw new Error(`LengthMatchingSolver: cannot commit dual meander to missing route ${t.routeIndex}`);i[t.routeIndex]={...e,route:t.predictedRoute}}this.matchedHdRoutes=i,this.currentAttempt=o.shorterAttempts[0];const r=o.longerAttempts.reduce((t,e)=\u003et+e.addedLength,0),s=o.shorterAttempts.reduce((t,e)=\u003et+e.addedLength,0);this.stats={pair:`${t.pair.connectionNames[0]}/${t.pair.connectionNames[1]}`,mode:\"dual-meander\",longerAddedLength:r,shorterAddedLength:s,resultingError:Math.abs(s-r-t.targetAddedLength)},this.activePair=null}getConfig(){return this.config||(this.config=(t=\u003e{const e=t.maximumMeanderDepth??5,n=t.maxToothCount??12;if(!Number.isFinite(e)||e\u003c=0)throw new Error(\"LengthMatchingSolver: maximumMeanderDepth must be a positive finite number\");if(void 0!==t.minimumToothPitch\u0026\u0026(!Number.isFinite(t.minimumToothPitch)||t.minimumToothPitch\u003c=0))throw new Error(\"LengthMatchingSolver: minimumToothPitch must be a positive finite number\");if(void 0!==t.minMeanderGap\u0026\u0026(!Number.isFinite(t.minMeanderGap)||t.minMeanderGap\u003c=0))throw new Error(\"LengthMatchingSolver: minMeanderGap must be a positive finite number\");if(void 0!==t.minMeanderHeight\u0026\u0026(!Number.isFinite(t.minMeanderHeight)||t.minMeanderHeight\u003c=0))throw new Error(\"LengthMatchingSolver: minMeanderHeight must be a positive finite number\");if(void 0!==t.minMeanderHeight\u0026\u0026t.minMeanderHeight\u003ee)throw new Error(\"LengthMatchingSolver: minMeanderHeight cannot exceed maximumMeanderDepth\");if(!Number.isFinite(n)||!Number.isInteger(n)||n\u003c=0)throw new Error(\"LengthMatchingSolver: maxToothCount must be a positive finite integer\");return{maximumMeanderDepth:e,minimumToothPitch:t.minimumToothPitch,minMeanderGap:t.minMeanderGap,minMeanderHeight:t.minMeanderHeight,maxToothCount:n,obstacles:t.obstacles??[],bounds:t.bounds,obstacleMargin:t.obstacleMargin??.15,layerCount:t.layerCount??2,colorMap:t.colorMap??{}}})(this.params)),this.config}_step(){this.getConfig(),this.activePair?this.tryCandidate(this.activePair):this.startNextPair()}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved)throw new Error(\"LengthMatchingSolver: getOutput() called before the solver completed\");return{matchedHdRoutes:this.matchedHdRoutes}}getBestEffortOutput(){const t=structuredClone(this.matchedHdRoutes),e=this.activePair?.fullAttempts??[];let n=null;for(const t of e)(!n||t.qualityScore\u003en.qualityScore)\u0026\u0026(n=t);if(!n)for(const t of this.activePair?.partialAttempts??[])(!n||t.addedLength\u003en.addedLength||t.addedLength===n.addedLength\u0026\u0026t.qualityScore\u003en.qualityScore)\u0026\u0026(n=t);if(n){const e=t[n.routeIndex];e\u0026\u0026(t[n.routeIndex]={...e,route:structuredClone(n.predictedRoute)})}return{matchedHdRoutes:t}}computeProgress(){if(this.solved)return 1;if(0===this.pairs.length)return this.config?1:0;const t=Math.max(0,this.nextPairIndex-1),e=this.activePair?this.activePair.candidateIndex/this.activePair.candidates.length:0;return Math.min(.99,(t+e)/this.pairs.length)}visualize(){const t=this.getConfig();return TG({routes:this.matchedHdRoutes,obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,colorMap:t.colorMap,activePair:this.activePair,currentAttempt:this.currentAttempt,solved:this.solved})}},EG=(t,e)=\u003e{if(\"top\"===t)return 0;if(\"bottom\"===t)return e-1;const n=/^inner(\\d+)$/.exec(t);if(!n)return-1;const o=Number(n[1]);return o\u003e0\u0026\u0026o\u003ce-1?o:-1},AG=(t,e)=\u003e0===t?\"top\":t===e-1?\"bottom\":`inner${t}`,OG=(t,e,n)=\u003e{const o=EG(t,n),i=EG(e,n);if(o\u003c0||i\u003c0)return[];const r=Math.min(o,i),s=Math.max(o,i);return Array.from({length:s-r+1},(t,e)=\u003eAG(r+e,n))},kG=1e-8,LG=(t,e)=\u003e{if(0===t.route.length)throw new Error(`trace \"${t.connection_name}\" has an empty route`);if(t.route.some(t=\u003e\"wire\"!==t.route_type\u0026\u0026\"via\"!==t.route_type))throw new Error(`trace \"${t.connection_name}\" contains unsupported jumper or through-obstacle geometry`);const n=t.route.findIndex(t=\u003e\"wire\"===t.route_type),o=t.route[n],i=t.route.findLast(t=\u003e\"wire\"===t.route_type);if(\"wire\"!==o?.route_type||!i)throw new Error(`trace \"${t.connection_name}\" must contain a wire point`);const r=[],s=[],a=[],c=[];let l=null,d=o.width;if(n\u003e0){let e=o.layer;for(let o=n-1;o\u003e=0;o--){const n=t.route[o];if(\"via\"!==n?.route_type)throw new Error(`trace \"${t.connection_name}\" has unsupported geometry before its first wire`);if(e===n.to_layer)e=n.from_layer;else{if(e!==n.from_layer)throw new Error(`trace \"${t.connection_name}\" has discontinuous leading vias`);e=n.to_layer}}const i=t.route[0];if(\"via\"!==i.route_type)throw new Error(`trace \"${t.connection_name}\" has an invalid leading entry`);l={x:i.x,y:i.y,layer:e,width:o.width},r.push(l)}for(const n of t.route){if(\"wire\"===n.route_type){if(!Number.isFinite(n.x)||!Number.isFinite(n.y)||!Number.isFinite(n.width)||n.width\u003c=0||EG(n.layer,e)\u003c0)throw new Error(`trace \"${t.connection_name}\" has an invalid wire point`);d=Math.max(d,n.width);const o={x:n.x,y:n.y,layer:n.layer,width:n.width};if(l){if(l.layer!==o.layer)throw new Error(`trace \"${t.connection_name}\" changes layers without a via`);Math.hypot(l.x-o.x,l.y-o.y)\u003ekG\u0026\u0026s.push({start:l,end:o,layer:o.layer,width:Math.max(l.width,o.width),connectionName:t.connection_name,terminal:null})}r.push(o),l=o;continue}if(\"via\"!==n.route_type)throw new Error(`trace \"${t.connection_name}\" contains unsupported route geometry`);if(!l)throw new Error(`trace \"${t.connection_name}\" has a leading via`);const o=EG(n.from_layer,e),i=EG(n.to_layer,e),h=n.via_diameter??l.width;if(!Number.isFinite(n.x)||!Number.isFinite(n.y)||o\u003c0||i\u003c0||o===i||void 0!==n.via_diameter\u0026\u0026(!Number.isFinite(n.via_diameter)||n.via_diameter\u003c=0)||void 0!==n.via_hole_diameter\u0026\u0026(!Number.isFinite(n.via_hole_diameter)||n.via_hole_diameter\u003c=0||n.via_hole_diameter\u003e=h))throw new Error(`trace \"${t.connection_name}\" has an invalid via`);const u=l.layer===n.from_layer?n.from_layer:l.layer===n.to_layer?n.to_layer:null;if(!u)throw new Error(`trace \"${t.connection_name}\" has a discontinuous via transition`);Math.hypot(l.x-n.x,l.y-n.y)\u003ekG\u0026\u0026s.push({start:l,end:n,layer:l.layer,width:l.width,connectionName:t.connection_name,terminal:null});const p=u===n.from_layer?n.to_layer:n.from_layer;c.push({...n,from_layer:u,to_layer:p}),a.push({x:n.x,y:n.y,layers:OG(u,p,e),diameter:h,connectionName:t.connection_name,terminal:1===r.length?\"start\":null}),l={x:n.x,y:n.y,layer:p,width:l.width},r.push(l)}if(r.length\u003c2||0===s.length)throw new Error(`trace \"${t.connection_name}\" does not contain a routable path`);s[0].terminal=1===s.length?\"both\":\"start\",s[s.length-1].terminal=1===s.length?\"both\":\"end\";const h=a.at(-1);return h\u0026\u0026Math.hypot(h.x-i.x,h.y-i.y)\u003c=kG\u0026\u0026(h.terminal=\"end\"),{source:t,points:r,segments:s,vias:a,transitions:c,width:d,viaDiameter:t.__postProcessingViaDiameter??d,...o.start_pcb_port_id?{startPortId:o.start_pcb_port_id}:{},...i.end_pcb_port_id?{endPortId:i.end_pcb_port_id}:{}}},DG=(t,e)=\u003e{const n=[],o=[],i=t.route.find(t=\u003e\"wire\"===t.route_type),r=\"wire\"===i?.route_type?i.width:null,s={\"0603\":.95,1206:1.8,\"1206x4_pair\":1.8};let a=null;for(let i=0;i\u003ct.route.length;i++){const c=t.route[i];if(\"wire\"===c.route_type){if(!Number.isFinite(c.x)||!Number.isFinite(c.y)||!Number.isFinite(c.width)||c.width\u003c=0||EG(c.layer,e)\u003c0)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has an invalid wire`);if(a\u0026\u0026a.layer!==c.layer)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" changes layer without a transition`);a\u0026\u0026n.push({start:a,end:c,layer:c.layer,width:Math.max(a.width,c.width),connectionName:t.connection_name,terminal:null}),a=c;continue}if(\"via\"===c.route_type){const s=OG(c.from_layer,c.to_layer,e),l=a,d=c.via_diameter??l?.width??r;if(!Number.isFinite(c.x)||!Number.isFinite(c.y)||s.length\u003c2||null===d||!Number.isFinite(d)||d\u003c=0||void 0!==c.via_hole_diameter\u0026\u0026(!Number.isFinite(c.via_hole_diameter)||c.via_hole_diameter\u003c=0||null!==d\u0026\u0026c.via_hole_diameter\u003e=d))throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has an invalid via`);l\u0026\u0026Math.hypot(l.x-c.x,l.y-c.y)\u003e1e-8\u0026\u0026n.push({start:l,end:c,layer:l.layer,width:l.width,connectionName:t.connection_name,terminal:null}),o.push({x:c.x,y:c.y,layers:s,diameter:d,connectionName:t.connection_name,terminal:0===i?\"start\":i===t.route.length-1?\"end\":null});const h=t.route.slice(i+1).find(t=\u003e\"wire\"===t.route_type),u=l?.layer===c.from_layer?c.to_layer:l?.layer===c.to_layer?c.from_layer:\"wire\"!==h?.route_type||h.layer!==c.from_layer\u0026\u0026h.layer!==c.to_layer?null:h.layer;if(!u)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has a discontinuous via`);a={x:c.x,y:c.y,layer:u,width:l?.width??r??d};continue}if(\"jumper\"===c.route_type){const o=s[c.footprint];if(!Number.isFinite(c.start.x)||!Number.isFinite(c.start.y)||!Number.isFinite(c.end.x)||!Number.isFinite(c.end.y)||EG(c.layer,e)\u003c0)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has an invalid jumper`);if(a\u0026\u0026(a.layer!==c.layer||Math.hypot(a.x-c.start.x,a.y-c.start.y)\u003e1e-8))throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has a discontinuous jumper`);n.push({start:c.start,end:c.end,layer:c.layer,width:o,connectionName:t.connection_name,terminal:null}),a={...c.end,layer:c.layer,width:o};continue}const l=OG(c.from_layer,c.to_layer,e);if(!Number.isFinite(c.start.x)||!Number.isFinite(c.start.y)||!Number.isFinite(c.end.x)||!Number.isFinite(c.end.y)||!Number.isFinite(c.width)||c.width\u003c=0||l.length\u003c2)throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has invalid through-obstacle copper`);if(a\u0026\u0026(a.layer!==c.from_layer\u0026\u0026a.layer!==c.to_layer||Math.hypot(a.x-c.start.x,a.y-c.start.y)\u003e1e-8))throw new Error(`PostProcessingSolver: immutable trace \"${t.connection_name}\" has discontinuous through-obstacle copper`);for(const e of l)n.push({start:c.start,end:c.end,layer:e,width:c.width,connectionName:t.connection_name,terminal:null});const d=a,h=d?.layer===c.to_layer?c.from_layer:c.to_layer;a={...c.end,layer:h,width:c.width}}return{segments:n,vias:o}},zG=(t,e)=\u003e{const n=DG(t,e);return[...n.segments.map((n,o)=\u003e({connectionName:`${t.connection_name}#immutable-segment-${o}`,rootConnectionName:t.connection_name,traceThickness:n.width,viaDiameter:n.width,route:[{x:n.start.x,y:n.start.y,z:EG(n.layer,e),traceThickness:n.width},{x:n.end.x,y:n.end.y,z:EG(n.layer,e),traceThickness:n.width}],vias:[]})),...n.vias.map((n,o)=\u003e({connectionName:`${t.connection_name}#immutable-via-${o}`,rootConnectionName:t.connection_name,traceThickness:n.diameter,viaDiameter:n.diameter,route:[],vias:[{x:n.x,y:n.y,zLayers:n.layers.map(t=\u003eEG(t,e))}]}))]},FG=t=\u003et.segments.reduce((t,e)=\u003et+Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),0),BG=t=\u003e{const{simpleRouteJson:e}=t.params,n=(t=\u003e{const e=new Set(t.reroutedPairs.map(t=\u003et.connectionNames.join(\"\\0\")));return t.declaredPairs.filter(n=\u003e{const o=n.connectionNames.map(e=\u003et.traces.filter(t=\u003et.connection_name===e));if(o.some(t=\u003e1!==t.length))return!1;if(e.has(n.connectionNames.join(\"\\0\")))return!0;const i=o.map(t=\u003et[0]);if(i.some(t=\u003et.route.length\u003c2||\"wire\"!==t.route[0]?.route_type||!t.route.every(t=\u003e\"wire\"===t.route_type||\"via\"===t.route_type)))return!1;const r=i.map(e=\u003eFG(LG(e,t.layerCount)));return Math.abs(r[0]-r[1])\u003en.lengthTolerance+1e-7}).map(t=\u003estructuredClone(t))})({traces:t.result.traces,declaredPairs:e.differentialPairs,reroutedPairs:t.result.reroutedPairs,layerCount:e.layerCount}),o=new Set(n.flatMap(t=\u003et.connectionNames)),i=[],r=[],s=[],a=new Set;for(let n=0;n\u003ct.result.traces.length;n++){const c=t.result.traces[n];if(!o.has(c.connection_name))continue;const l=c.route.every(t=\u003e\"wire\"===t.route_type||\"via\"===t.route_type),d=\"wire\"===c.route[0]?.route_type;if(!l||!d)throw new Error(`PostProcessingSolver: rerouted connection \"${c.connection_name}\" cannot be bound to LengthMatchingSolver`);const h=LG(c,e.layerCount),u=c.route[0];if(\"wire\"!==u.route_type)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" lost its first wire during binding`);const p=[{x:u.x,y:u.y,z:EG(u.layer,e.layerCount),traceThickness:u.width}],m=[],g=[];let f=u.layer,y=u.width;for(const t of c.route.slice(1)){if(\"wire\"===t.route_type){if(t.layer!==f)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" changes layers without a via while binding`);p.push({x:t.x,y:t.y,z:EG(t.layer,e.layerCount),traceThickness:t.width}),y=t.width;continue}if(\"via\"!==t.route_type)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" contains unsupported bound geometry`);const n=f===t.from_layer?t.to_layer:f===t.to_layer?t.from_layer:null;if(!n)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" has a discontinuous bound via`);const o=p.at(-1);Math.hypot(o.x-t.x,o.y-t.y)\u003e1e-8\u0026\u0026p.push({x:t.x,y:t.y,z:EG(f,e.layerCount),traceThickness:y}),p.push({x:t.x,y:t.y,z:EG(n,e.layerCount),traceThickness:y}),m.push({x:t.x,y:t.y,zLayers:OG(t.from_layer,t.to_layer,e.layerCount).map(t=\u003eEG(t,e.layerCount))}),g.push({...t}),f=n}if(p.length\u003c2)throw new Error(`PostProcessingSolver: trace \"${c.connection_name}\" has no bound copper segments`);const _=Math.max(...p.map(t=\u003et.traceThickness??h.width)),b=h.viaDiameter,x=i.length;i.push({connectionName:c.connection_name,traceThickness:_,viaDiameter:b,route:p,vias:m});const v=p[0],S=p.at(-1);r.push({name:c.connection_name,pointsToConnect:[{x:v.x,y:v.y,layer:u.layer,...h.startPortId?{pcb_port_id:h.startPortId}:{}},{x:S.x,y:S.y,layer:h.points.at(-1).layer,...h.endPortId?{pcb_port_id:h.endPortId}:{}}]}),s.push({traceIndex:n,matchedRouteIndex:x,viaTemplates:g,startEndpoint:{...v},endEndpoint:{...S},...h.startPortId?{startPortId:h.startPortId}:{},...h.endPortId?{endPortId:h.endPortId}:{}}),a.add(c.connection_name)}for(const t of o)if(!a.has(t))throw new Error(`PostProcessingSolver: missing LengthMatchingSolver binding for rerouted connection \"${t}\"`);for(const n of t.result.traces)o.has(n.connection_name)||i.push(...zG(n,e.layerCount));const c=e.minTraceToPadEdgeClearance??Math.max(0,...i.filter(t=\u003et.route.length\u003e=2).map(t=\u003et.traceThickness));return{solverParams:{hdRoutes:i,originalConnections:r,differentialPairs:n,obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,obstacleMargin:c},traceBindings:s,baseTraces:structuredClone(t.result.traces)}},jG=t=\u003e{const e=new Map;for(const n of t.differentialPairs)for(const o of n.connectionNames){const n=t.hdRoutes.map((t,e)=\u003e({route:t,hdRouteIndex:e})).filter(({route:t})=\u003et.connectionName===o);1===n.length\u0026\u0026e.set(n[0].hdRouteIndex,o)}const n=t.hdRoutes.map((e,n)=\u003e{const o=[],i=new Map;for(let t=0;t\u003c(e.jumpers?.length??0);t++){const n=e.jumpers[t],o=e.route.map((t,e)=\u003e({point:t,index:e})).filter(({point:t})=\u003eMath.hypot(t.x-n.start.x,t.y-n.start.y)\u003c=1e-8).map(({index:t})=\u003et),r=e.route.map((t,e)=\u003e({point:t,index:e})).filter(({point:t})=\u003eMath.hypot(t.x-n.end.x,t.y-n.end.y)\u003c=1e-8).map(({index:t})=\u003et),s=[...o.flatMap(t=\u003er.filter(e=\u003ee\u003et).map(e=\u003e({startIndex:t,endIndex:e}))),...r.flatMap(t=\u003eo.filter(e=\u003ee\u003et).map(e=\u003e({startIndex:t,endIndex:e})))];if(1!==s.length)throw new Error(`PostProcessingSolver: immutable HD route \"${e.connectionName}\" has an ambiguous jumper traversal`);const a=s[0];if(i.has(a.startIndex)||[...i.values()].some(({endIndex:t})=\u003ea.startIndex\u003ct||a.endIndex\u003c=t))throw new Error(`PostProcessingSolver: immutable HD route \"${e.connectionName}\" has overlapping or unordered jumpers`);i.set(a.startIndex,{endIndex:a.endIndex,jumperIndex:t})}if(e.route.length\u003e0){const n=e.route[0];o.push({route_type:\"wire\",x:n.x,y:n.y,width:n.traceThickness??e.traceThickness,layer:AG(n.z,t.layerCount)});for(let n=0;n\u003ce.route.length-1;n++){const r=e.route[n],s=i.get(n);if(s){const i=e.route[s.endIndex],a=e.jumpers[s.jumperIndex];if(r.z!==i.z)throw new Error(`PostProcessingSolver: immutable HD route \"${e.connectionName}\" changes layers through a jumper`);o.push({route_type:\"jumper\",start:{x:r.x,y:r.y},end:{x:i.x,y:i.y},footprint:a.footprint,layer:AG(r.z,t.layerCount)}),o.push({route_type:\"wire\",x:i.x,y:i.y,width:i.traceThickness??e.traceThickness,layer:AG(i.z,t.layerCount)}),n=s.endIndex-1;continue}const a=e.route[n+1],c=AG(r.z,t.layerCount),l=AG(a.z,t.layerCount);r.z!==a.z\u0026\u0026(\"through_obstacle\"===r.toNextSegmentType?o.push({route_type:\"through_obstacle\",start:{x:r.x,y:r.y},end:{x:a.x,y:a.y},from_layer:c,to_layer:l,width:r.traceThickness??e.traceThickness}):o.push({route_type:\"via\",x:a.x,y:a.y,from_layer:c,to_layer:l,via_diameter:e.viaDiameter})),o.push({route_type:\"wire\",x:a.x,y:a.y,width:a.traceThickness??e.traceThickness,layer:l})}const r=o.filter(t=\u003e\"wire\"===t.route_type),s=e.startPcbPortId??e.route[0]?.pcb_port_id,a=e.endPcbPortId??e.route.at(-1)?.pcb_port_id;s\u0026\u0026r[0]\u0026\u0026(r[0].start_pcb_port_id=s),a\u0026\u0026r.at(-1)\u0026\u0026(r.at(-1).end_pcb_port_id=a)}return{type:\"pcb_trace\",pcb_trace_id:`post_processing_hd_route_${n}`,connection_name:e.connectionName,__postProcessingViaDiameter:e.viaDiameter,route:o}}),o=structuredClone(t.obstacles);for(let n=0;n\u003ct.hdRoutes.length;n++){const i=t.hdRoutes[n],r=new Set([i.connectionName,i.rootConnectionName,i.startPcbPortId,i.endPcbPortId,i.route[0]?.pcb_port_id,i.route.at(-1)?.pcb_port_id,e.get(n)].filter(t=\u003evoid 0!==t));for(const t of o)t.connectedTo.some(t=\u003er.has(t))\u0026\u0026(t.connectedTo=[...new Set([...t.connectedTo,...r])])}return{params:{simpleRouteJson:{traces:n,differentialPairs:structuredClone(t.differentialPairs),obstacles:o,bounds:structuredClone(t.bounds),layerCount:t.layerCount,minTraceToPadEdgeClearance:t.minTraceToPadEdgeClearance},...t.routingGrid?{routingGrid:structuredClone(t.routingGrid)}:{}},routeBindings:[...e.entries()].map(([t,e])=\u003e({hdRouteIndex:t,traceIndex:t,internalConnectionName:e})),sourceHdRoutes:structuredClone(t.hdRoutes)}};function $G(t){const e=structuredClone(t.model.sourceHdRoutes);for(const n of t.model.routeBindings){const o=t.binding.traceBindings.find(t=\u003et.traceIndex===n.traceIndex);if(!o)continue;const i=t.result.matchedHdRoutes[o.matchedRouteIndex],r=e[n.hdRouteIndex];if(!i||!r)throw new Error(`PostProcessingSolver: missing matched or source HD route for \"${n.internalConnectionName}\"`);if(i.connectionName!==n.internalConnectionName)throw new Error(`PostProcessingSolver: matched HD binding changed \"${n.internalConnectionName}\" to \"${i.connectionName}\"`);const s=i.route.map(t=\u003e({...t})),a=(e,o)=\u003e{if(e\u0026\u0026o\u0026\u0026(o.pcb_port_id\u0026\u0026(e.pcb_port_id=o.pcb_port_id),o.insideJumperPad\u0026\u0026t.rejectInsideJumperPad))throw new Error(`PostProcessingSolver: cannot restore jumper-pad metadata on rerouted connection \"${n.internalConnectionName}\"`)};a(s[0],r.route[0]),a(s.at(-1),r.route.at(-1)),e[n.hdRouteIndex]={...r,route:s,vias:structuredClone(i.vias)}}return{hdRoutes:e,postProcessingErrors:[]}}var YG=class extends Error{connectionNames;reason;constructor(t){super(`PostProcessingSolver: differential pair ${t.connectionNames.join(\"/\")} ${t.message}`),this.name=\"DifferentialPairRoutingError\",this.connectionNames=[t.connectionNames[0],t.connectionNames[1]],this.reason=t.reason}},XG=class extends Error{connectionNames;reason;constructor(t){super(t.message),this.name=\"PostProcessingConstraintError\",this.connectionNames=[...t.connectionNames],this.reason=t.reason}},VG=class extends Error{reason=\"grid-capacity-exhausted\";constructor(t){super(t),this.name=\"PostProcessingGridCapacityError\"}},WG=t=\u003e{const e=75e3*t.simpleRouteJson.differentialPairs.length;if(!Number.isSafeInteger(e))throw new Error(\"PostProcessingSolver: derived rerouting iteration bound exceeds the safe integer range\");const n=Math.min(e,8e4);return Math.max(1,n)},HG=t=\u003estructuredClone(t),GG=(t,e,n)=\u003e{const o=t=\u003e{const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}},i=o(t.start),r=o(t.end),s=e.width/2+n,a=e.height/2+n;if(Math.abs(i.x)\u003c=s\u0026\u0026Math.abs(i.y)\u003c=a||Math.abs(r.x)\u003c=s\u0026\u0026Math.abs(r.y)\u003c=a)return!0;const c=[{x:-s,y:-a},{x:s,y:-a},{x:s,y:a},{x:-s,y:a}];return c.some((t,e)=\u003ecG(i,r,t,c[(e+1)%c.length])\u003c=1e-7)},UG=t=\u003e{const e=[],n=[];for(const o of t.immutableTraces){const i=DG(o,t.layerCount);e.push(...i.segments),n.push(...i.vias)}const o=Array.from({length:t.layerCount},()=\u003e[]);for(const n of e){const e=EG(n.layer,t.layerCount);o[e].push(n)}const i=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y)\u003c=1e-8,r=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-e.x-o*s,t.y-e.y-i*s)},s=(t,e,n)=\u003e{const o=-(e.ccwRotationDegrees??0)*Math.PI/180,i=t.x-e.center.x,r=t.y-e.center.y,s=i*Math.cos(o)-r*Math.sin(o),a=i*Math.sin(o)+r*Math.cos(o);return Math.abs(s)\u003c=e.width/2+n\u0026\u0026Math.abs(a)\u003c=e.height/2+n},a=(e,n)=\u003e{const o=EG(n,t.layerCount);return uG(e,t.layerCount).includes(o)},c=(e,n,o)=\u003e{const i=((e,n,o)=\u003e{const i=Math.hypot(n.x,n.y);if(i\u003c=1e-10)throw new Error(\"PostProcessingSolver: cannot orient terminal fanout on a zero-length spine\");const r=-n.y/i*t.side*t.centerlineSpacing/2,s=n.x/i*t.side*t.centerlineSpacing/2,a=\"start\"===o?[t.firstStartTerminal,t.secondStartTerminal]:[t.firstEndTerminal,t.secondEndTerminal],c=[t.firstWidth,t.secondWidth],l=[t.firstConnectionName,t.secondConnectionName];return a.map((t,n)=\u003e{const i=0===n?1:-1,a={x:e.x+r*i,y:e.y+s*i};return{start:\"start\"===o?t:a,end:\"start\"===o?a:t,layer:e.layer,width:c[n],connectionName:l[n],terminal:o}})})(e,n,o),r=i.map(t=\u003e\"start\"===o?t.end:t.start);return i.every(l)\u0026\u0026r.every((n,o)=\u003et.obstacles.every(r=\u003e!a(r,e.layer)||!s(n,r,1.5*i[o].width+(t.terminalMiterMargin??0))))\u0026\u0026cG(i[0].start,i[0].end,i[1].start,i[1].end)\u003e=i[0].width/2+i[1].width/2-1e-7},l=e=\u003e{const i=e.width/2,c=i+(t.minTraceToPadEdgeClearance??e.width),l=EG(e.layer,t.layerCount),d=Math.min(e.start.x,e.end.x),h=Math.max(e.start.x,e.end.x),u=Math.min(e.start.y,e.end.y),p=Math.max(e.start.y,e.end.y);for(const n of[e.start,e.end])if(n.x-i\u003ct.bounds.minX||n.x+i\u003et.bounds.maxX||n.y-i\u003ct.bounds.minY||n.y+i\u003et.bounds.maxY)return!1;for(const n of t.obstacles){if(!a(n,e.layer))continue;const o=Math.hypot(n.width/2+c,n.height/2+c);if(h\u003cn.center.x-o||d\u003en.center.x+o||p\u003cn.center.y-o||u\u003en.center.y+o)continue;const[i,r]=e.connectionName===t.firstConnectionName?[t.firstStartTerminal,t.firstEndTerminal]:[t.secondStartTerminal,t.secondEndTerminal],l=s(i,n,0)\u0026\u0026(s(e.start,n,c)||s(e.end,n,c))\u0026\u0026Math.hypot(e.end.x-i.x,e.end.y-i.y)\u003e=Math.hypot(e.start.x-i.x,e.start.y-i.y),m=s(r,n,0)\u0026\u0026(s(e.start,n,c)||s(e.end,n,c))\u0026\u0026Math.hypot(e.end.x-r.x,e.end.y-r.y)\u003c=Math.hypot(e.start.x-r.x,e.start.y-r.y);if(!(n.connectedTo.includes(e.connectionName)\u0026\u0026(l||m))\u0026\u0026GG(e,n,c))return!1}for(const t of o[l]){const n=e.width/2+t.width/2+Math.max(e.width,t.width);if(!(h+n\u003cMath.min(t.start.x,t.end.x)||d-n\u003eMath.max(t.start.x,t.end.x)||p+n\u003cMath.min(t.start.y,t.end.y)||u-n\u003eMath.max(t.start.y,t.end.y))\u0026\u0026cG(e.start,e.end,t.start,t.end)\u003cn)return!1}for(const t of n)if(t.layers.includes(e.layer)\u0026\u0026r(t,e.start,e.end)\u003ce.width/2+t.diameter/2+e.width)return!1;return!0},d=o=\u003e{const i=o.diameter/2;if(o.x-i\u003ct.bounds.minX||o.x+i\u003et.bounds.maxX||o.y-i\u003ct.bounds.minY||o.y+i\u003et.bounds.maxY)return!1;for(const e of t.obstacles){if(!o.layers.some(t=\u003ea(e,t)))continue;if(!(null!==o.terminal\u0026\u0026e.connectedTo.includes(o.connectionName)\u0026\u0026s(o,e,0))\u0026\u0026s(o,e,i+o.diameter))return!1}for(const t of e){if(!o.layers.includes(t.layer))continue;const e=i+t.width/2+Math.max(o.diameter,t.width);if(r(o,t.start,t.end)\u003ce)return!1}for(const t of n){if(!t.layers.some(t=\u003eo.layers.includes(t)))continue;const e=i+t.diameter/2+Math.max(o.diameter,t.diameter);if(Math.hypot(o.x-t.x,o.y-t.y)\u003ce)return!1}return!0};return{isEdgeValid:(e,n)=\u003e{if(e.layer!==n.layer||!((e,n)=\u003e{const o=Math.hypot(n.x-e.x,n.y-e.y);if(0===o)return[];const r=-(n.y-e.y)/o*t.side*t.centerlineSpacing/2,s=(n.x-e.x)/o*t.side*t.centerlineSpacing/2,a=i(e,t.start),c=i(n,t.end),l=t.terminalFanout?a\u0026\u0026c?\"both\":a?\"start\":c?\"end\":null:null,d=a\u0026\u0026t.terminalFanout?t.firstStartTerminal:{x:e.x+r,y:e.y+s},h=c\u0026\u0026t.terminalFanout?t.firstEndTerminal:{x:n.x+r,y:n.y+s},u=a\u0026\u0026t.terminalFanout?t.secondStartTerminal:{x:e.x-r,y:e.y-s},p=c\u0026\u0026t.terminalFanout?t.secondEndTerminal:{x:n.x-r,y:n.y-s};return[{start:d,end:h,layer:e.layer,width:t.firstWidth,connectionName:t.firstConnectionName,terminal:l},{start:u,end:p,layer:e.layer,width:t.secondWidth,connectionName:t.secondConnectionName,terminal:l}]})(e,n).every(l))return!1;if(t.terminalFanout||void 0===t.terminalMiterMargin)return!0;const o={x:n.x-e.x,y:n.y-e.y};return!(i(e,t.start)\u0026\u0026!c(e,o,\"start\"))\u0026\u0026!(i(n,t.end)\u0026\u0026!c(n,o,\"end\"))},isTerminalFanoutValid:c,isViaValid:(e,n,o)=\u003e{const r=Math.hypot(o.x,o.y);if(r\u003c=1e-10)throw new Error(\"PostProcessingSolver: cannot orient a coupled via on a zero-length spine\");const s=OG(e.layer,n,t.layerCount),a=-o.y/r*t.side*t.centerlineSpacing/2,c=o.x/r*t.side*t.centerlineSpacing/2,l=i(e,t.start)?\"start\":i(e,t.end)?\"end\":null;return[{x:e.x+a,y:e.y+c,layers:s,diameter:t.firstViaDiameter,connectionName:t.firstConnectionName,terminal:l},{x:e.x-a,y:e.y-c,layers:s,diameter:t.secondViaDiameter,connectionName:t.secondConnectionName,terminal:l}].every(d)}}},ZG=(t,e,n)=\u003e{const o=1e-7,i=(t,e)=\u003e{const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}},r=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},s=(t,e,n)=\u003e{const o=EG(e,n);return uG(t,n).includes(o)},a=(t,e,n)=\u003e{const a=t.width/2;if(t.start.x-a\u003ce.bounds.minX-o||t.start.x+a\u003ee.bounds.maxX+o||t.start.y-a\u003ce.bounds.minY-o||t.start.y+a\u003ee.bounds.maxY+o||t.end.x-a\u003ce.bounds.minX-o||t.end.x+a\u003ee.bounds.maxX+o||t.end.y-a\u003ce.bounds.minY-o||t.end.y+a\u003ee.bounds.maxY+o)return!1;for(const n of e.obstacles){if(!s(n,t.layer,e.layerCount))continue;const r=\"both\"===t.terminal?[t.start,t.end]:\"start\"===t.terminal?[t.start]:\"end\"===t.terminal?[t.end]:[];if(!(n.connectedTo.includes(t.connectionName)\u0026\u0026r.some(t=\u003e{const e=i(t,n);return Math.abs(e.x)\u003c=n.width/2+o\u0026\u0026Math.abs(e.y)\u003c=n.height/2+o}))\u0026\u0026GG(t,n,a+(e.minTraceToPadEdgeClearance??t.width)))return!1}for(const e of n.segments){if(e.layer!==t.layer)continue;const n=t.width/2+e.width/2+Math.max(t.width,e.width);if(cG(t.start,t.end,e.start,e.end)\u003cn-o)return!1}for(const e of n.vias){if(!e.layers.includes(t.layer))continue;const n=t.width/2+e.diameter/2+t.width;if(r(e,t.start,t.end)\u003cn-o)return!1}return!0},c=(t,e,n)=\u003e{const a=t.diameter/2;if(t.x-a\u003ce.bounds.minX-o||t.x+a\u003ee.bounds.maxX+o||t.y-a\u003ce.bounds.minY-o||t.y+a\u003ee.bounds.maxY+o)return!1;for(const n of e.obstacles){if(!t.layers.some(t=\u003es(n,t,e.layerCount)))continue;const r=i(t,n);if(!(null!==t.terminal\u0026\u0026n.connectedTo.includes(t.connectionName)\u0026\u0026Math.abs(r.x)\u003c=n.width/2+o\u0026\u0026Math.abs(r.y)\u003c=n.height/2+o)\u0026\u0026Math.abs(r.x)\u003c=n.width/2+a+t.diameter\u0026\u0026Math.abs(r.y)\u003c=n.height/2+a+t.diameter)return!1}for(const e of n.segments){if(!t.layers.includes(e.layer))continue;const n=a+e.width/2+Math.max(t.diameter,e.width);if(r(t,e.start,e.end)\u003cn-o)return!1}for(const e of n.vias){if(!e.layers.some(e=\u003et.layers.includes(e)))continue;const n=a+e.diameter/2+Math.max(t.diameter,e.diameter);if(Math.hypot(t.x-e.x,t.y-e.y)\u003cn-o)return!1}return!0},l=t=\u003e{for(let e=0;e\u003ct.segments.length;e++){const n=t.segments[e];for(let i=e+2;i\u003ct.segments.length;i++){const r=t.segments[i];if(n.layer!==r.layer)continue;if(!(t.segments.slice(e+1,i).reduce((t,e)=\u003et+Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),0)\u003c=n.width+r.width+o)\u0026\u0026cG(n.start,n.end,r.start,r.end)\u003cn.width/2+r.width/2-o)return!0}}for(const e of t.vias)for(const n of t.segments){if(!e.layers.includes(n.layer))continue;if(!(Math.hypot(e.x-n.start.x,e.y-n.start.y)\u003c=o||Math.hypot(e.x-n.end.x,e.y-n.end.y)\u003c=o)\u0026\u0026r(e,n.start,n.end)\u003ce.diameter/2+n.width/2-o)return!0}return!1},d=((t,e)=\u003e{const n=[],o=[];for(const i of t){const t=DG(i,e);n.push(...t.segments),o.push(...t.vias)}return{segments:n,vias:o}})(n.immutableTraces,n.layerCount);if(!((t,e)=\u003e{for(const n of t.segments)for(const t of e.segments){if(n.layer!==t.layer)continue;const e=n.width/2+t.width/2;if(cG(n.start,n.end,t.start,t.end)\u003ce-o)return!1}for(const[n,i]of[[t.vias,e.segments],[e.vias,t.segments]])for(const t of n)for(const e of i)if(t.layers.includes(e.layer)\u0026\u0026r(t,e.start,e.end)\u003ct.diameter/2+e.width/2-o)return!1;for(const n of t.vias)for(const t of e.vias)if(n.layers.some(e=\u003et.layers.includes(e))\u0026\u0026Math.hypot(n.x-t.x,n.y-t.y)\u003cn.diameter/2+t.diameter/2-o)return!1;return!0})(t,e)||l(t)||l(e))return!1;for(const o of[t,e])if(o.segments.some(t=\u003e!a(t,n,d))||o.vias.some(t=\u003e!c(t,n,d)))return!1;return!0},qG=[{x:1,y:0},{x:1,y:1},{x:0,y:1},{x:-1,y:1},{x:-1,y:0},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1}],JG=class{constructor(t){this.input=t;const{bounds:e,grid:n}=t,o={minX:e.minX+n.outerPerimeterWidth,maxX:e.maxX-n.outerPerimeterWidth,minY:e.minY+n.outerPerimeterWidth,maxY:e.maxY-n.outerPerimeterWidth},i=this.createAxis(e.minX,e.maxX,n.outerGridStep,[o.minX,o.maxX]),r=this.createAxis(e.minY,e.maxY,n.outerGridStep,[o.minY,o.maxY]),s=this.createAxis(o.minX,o.maxX,n.innerGridStep,[],t.start.x),a=this.createAxis(o.minY,o.maxY,n.innerGridStep,[],t.start.y),c=this.createGrid(i,r,t=\u003et.x\u003c=o.minX||t.x\u003e=o.maxX||t.y\u003c=o.minY||t.y\u003e=o.maxY),l=this.createGrid(s,a,()=\u003e!0);this.connectLocalNeighbors(c),this.connectLocalNeighbors(l);for(const t of[\"left\",\"right\",\"bottom\",\"top\"])this.connectBoundaries(t,c,l,o);const d=this.nodes.map((t,e)=\u003ee);this.connectEndpoint(t.start,d),this.connectEndpoint(t.end,d)}input;nodes=[];nodeIdByPoint=new Map;endpointNodeIdByPoint=new Map;getPlanarNeighbors(t){const e=this.endpointNodeIdByPoint.get(this.exactKeyFor(t))??this.nodeIdByPoint.get(this.keyFor(t));if(void 0===e)throw new Error(`PostProcessingSolver: coupled path point (${t.x}, ${t.y}) is not on the composite grid`);return[...this.nodes[e].neighborIds].map(e=\u003e({...this.nodes[e].point,layer:t.layer}))}getNodeCount(){return this.nodes.length}getSearchStateCountUpperBound(t){const e=this.nodes.reduce((t,e)=\u003et+e.neighborIds.size,0)*t+1;if(!Number.isSafeInteger(e))throw new Error(\"PostProcessingSolver: composite-grid search-state bound exceeds the safe integer range\");return e}createAxis(t,e,n,o,i=t){const r=[t,e,...o].map(t=\u003e({value:t,fixed:!0}));for(let o=Math.ceil((t-i)/n);i+o*n\u003ce-1e-8;o++)r.push({value:i+o*n,fixed:!1});r.sort((t,e)=\u003et.value-e.value||Number(e.fixed)-Number(t.fixed));const s=[];for(const t of r){const e=s.at(-1);!e||Math.abs(t.value-e.value)\u003e1e-8?s.push(t):t.fixed\u0026\u0026!e.fixed\u0026\u0026(s[s.length-1]=t)}return s.map(t=\u003et.value)}createGrid(t,e,n){return e.map(e=\u003et.map(t=\u003e{const o={x:t,y:e};return n(o)?this.addNode(o):null}))}connectLocalNeighbors(t){for(let e=0;e\u003ct.length;e++)for(let n=0;n\u003c(t[e]?.length??0);n++){const o=t[e][n];if(null!==o)for(const i of qG){const r=t[e+i.y]?.[n+i.x];null!=r\u0026\u0026this.connect(o,r)}}}connectBoundaries(t,e,n,o){const i=\"left\"===t?o.minX:\"right\"===t?o.maxX:\"bottom\"===t?o.minY:o.maxY,r=\"left\"===t||\"right\"===t,s=t=\u003eMath.abs((r?t.x:t.y)-i)\u003c=1e-8,a=t=\u003e{const e=new Set;for(const n of t)for(const t of n)null!==t\u0026\u0026s(this.nodes[t].point)\u0026\u0026e.add(t);return[...e].sort((t,e)=\u003e{const n=this.nodes[t].point,o=this.nodes[e].point;return(r?n.y-o.y:n.x-o.x)||t-e})},c=a(e),l=a(n);if(0===c.length||0===l.length)throw new Error(`PostProcessingSolver: composite grid has no ${t} boundary bridge candidates`);for(const t of c)this.connect(t,this.findNearestAlongBoundary(t,l,r));for(const t of l)this.connect(t,this.findNearestAlongBoundary(t,c,r))}findNearestAlongBoundary(t,e,n){const o=this.nodes[t].point;let i=e[0],r=Number.POSITIVE_INFINITY;for(const t of e){const e=this.nodes[t].point,s=Math.abs(n?o.y-e.y:o.x-e.x);(s\u003cr-1e-8||Math.abs(s-r)\u003c=1e-8\u0026\u0026t\u003ci)\u0026\u0026(r=s,i=t)}return i}connectEndpoint(t,e){const n=this.nodeIdByPoint.get(this.keyFor(t)),o=void 0===n?null:this.nodes[n].point,i=o?.x===t.x\u0026\u0026o.y===t.y?n:this.nodes.push({point:{x:t.x,y:t.y},neighborIds:new Set})-1;this.endpointNodeIdByPoint.set(this.exactKeyFor(t),i);const r=(t,n)=\u003e{const o=this.nodes[t].point,i=e.filter(e=\u003ee!==t).map(t=\u003e({nodeId:t,distance:Math.hypot(this.nodes[t].point.x-o.x,this.nodes[t].point.y-o.y)})).filter(({distance:t})=\u003et\u003e1e-10).sort((t,e)=\u003et.distance-e.distance||t.nodeId-e.nodeId).slice(0,n);if(0===i.length)throw new Error(\"PostProcessingSolver: composite grid has no endpoint connection candidates\");for(const{nodeId:e}of i)this.connect(t,e)};r(i,8);for(const e of qG){const n={x:t.x+e.x*this.input.grid.innerGridStep,y:t.y+e.y*this.input.grid.innerGridStep};if(n.x\u003cthis.input.bounds.minX||n.x\u003ethis.input.bounds.maxX||n.y\u003cthis.input.bounds.minY||n.y\u003ethis.input.bounds.maxY)continue;const o=this.addNode(n);this.connect(i,o),r(o,4)}}addNode(t){const e=this.keyFor(t),n=this.nodeIdByPoint.get(e);if(void 0!==n)return n;const o=this.nodes.length;return this.nodes.push({point:{x:t.x,y:t.y},neighborIds:new Set}),this.nodeIdByPoint.set(e,o),o}connect(t,e){if(t===e)return;const n=this.nodes[t],o=this.nodes[e];n.neighborIds.add(e),o.neighborIds.add(t)}keyFor(t){const e=Object.is(t.x,-0)?0:t.x,n=Object.is(t.y,-0)?0:t.y;return`${e.toFixed(12)}:${n.toFixed(12)}`}exactKeyFor(t){return`${Object.is(t.x,-0)?0:t.x}:${Object.is(t.y,-0)?0:t.y}`}},KG=class{constructor(t){if(this.input=t,this.startLayer=EG(t.start.layer,t.layerCount),this.endLayer=EG(t.end.layer,t.layerCount),this.grid=new JG(t),this.maxSearchStates=this.grid.getSearchStateCountUpperBound(t.layerCount),this.exploredStateLimit=Math.min(this.maxSearchStates,2e4),this.startLayer\u003c0||this.endLayer\u003c0)return this.queue=[],void(this.status=\"exhausted\");const e={point:t.start,direction:null,cost:0,estimate:this.estimate(t.start),parent:null,sequence:0};this.queue=[e],this.bestCosts.set(this.keyFor(t.start,null),0)}input;queue;bestCosts=new Map;startLayer;endLayer;grid;maxSearchStates;exploredStateLimit;current=null;result=null;status=\"searching\";explored=0;nextSequence=1;isComplete(){return\"searching\"!==this.status}getPath(){return this.result}getPreviewPath(){return this.current?this.createPath(this.current):[this.input.start]}getExploredCount(){return this.explored}getProgress(){return\"searching\"!==this.status?1:Math.min(.99,this.explored/this.exploredStateLimit)}getGridNodeCount(){return this.grid.getNodeCount()}step(){if(\"searching\"!==this.status)return;const t=this.popQueue();if(!t)return void(this.status=\"exhausted\");const e=this.bestCosts.get(this.keyFor(t.point,t.direction));if(void 0===e)throw new Error(\"PostProcessingSolver: coupled path queue contains an untracked state\");if(t.cost\u003ee+1e-10)0===this.queue.length\u0026\u0026(this.status=\"exhausted\");else{if(this.current=t,this.explored++,this.explored\u003ethis.maxSearchStates)throw new Error(`PostProcessingSolver: coupled path search exceeded its ${this.maxSearchStates}-state graph invariant limit`);if(this.isEnd(t.point)){const e=this.createPath(t);return e[e.length-1]=this.input.end,this.result=this.simplifyPath(e),void(this.status=\"found\")}this.explored\u003e=this.exploredStateLimit?this.status=\"exhausted\":(this.enqueuePlanarNeighbors(t),this.enqueueViaNeighbors(t),0===this.queue.length\u0026\u0026(this.status=\"exhausted\"))}}isEnd(t){return t.layer===this.input.end.layer\u0026\u0026t.x===this.input.end.x\u0026\u0026t.y===this.input.end.y}estimate(t){return Math.hypot(t.x-this.input.end.x,t.y-this.input.end.y)+3*Math.abs(EG(t.layer,this.input.layerCount)-this.endLayer)}keyFor(t,e){return`${Object.is(t.x,-0)?0:t.x}:${Object.is(t.y,-0)?0:t.y}:${t.layer}:${e?.key??\"start\"}`}createDirection(t,e){const n=e.x-t.x,o=e.y-t.y,i=Math.hypot(n,o);if(i\u003c=1e-10)throw new Error(\"PostProcessingSolver: composite grid produced a zero-length planar edge\");const r=n/i,s=o/i;return{x:r,y:s,key:`${r.toFixed(6)}:${s.toFixed(6)}`}}createPath(t){const e=[];let n=t;for(;n;)e.push(n.point),n=n.parent;return e.reverse()}simplifyPath(t){return t.filter((e,n)=\u003e{if(0===n||n===t.length-1)return!0;const o=t[n-1],i=t[n+1],r={x:e.x-o.x,y:e.y-o.y},s={x:i.x-e.x,y:i.y-e.y},a=r.x*s.y-r.y*s.x,c=Math.hypot(r.x,r.y)*Math.hypot(s.x,s.y);return Math.abs(a)\u003e1e-10*c||e.layer!==o.layer||e.layer!==i.layer})}hasHigherQueuePriority(t,e){return t.estimate!==e.estimate?t.estimate\u003ce.estimate:t.cost!==e.cost?t.cost\u003ce.cost:t.point.x!==e.point.x?t.point.x\u003ce.point.x:t.point.y!==e.point.y?t.point.y\u003ce.point.y:t.point.layer!==e.point.layer?t.point.layer\u003ce.point.layer:t.sequence\u003ce.sequence}pushQueue(t){this.queue.push(t);let e=this.queue.length-1;for(;e\u003e0;){const n=Math.floor((e-1)/2),o=this.queue[n];if(!this.hasHigherQueuePriority(t,o))break;this.queue[e]=o,e=n}this.queue[e]=t}popQueue(){const t=this.queue[0],e=this.queue.pop();if(!t||!e||0===this.queue.length)return t;let n=0;for(;;){const t=2*n+1;if(t\u003e=this.queue.length)break;const o=t+1;let i=t;o\u003cthis.queue.length\u0026\u0026this.hasHigherQueuePriority(this.queue[o],this.queue[t])\u0026\u0026(i=o);const r=this.queue[i];if(!this.hasHigherQueuePriority(r,e))break;this.queue[n]=r,n=i}return this.queue[n]=e,t}enqueuePlanarNeighbors(t){for(const e of this.grid.getPlanarNeighbors(t.point)){if(!this.input.isEdgeValid(t.point,e))continue;const n=this.createDirection(t.point,e),o=null===t.direction||t.direction.key===n.key?0:.18,i=t.cost+Math.hypot(e.x-t.point.x,e.y-t.point.y)+o,r=this.keyFor(e,n);(this.bestCosts.get(r)??Number.POSITIVE_INFINITY)\u003c=i||(this.bestCosts.set(r,i),this.pushQueue({point:e,direction:n,cost:i,estimate:i+this.estimate(e),parent:t,sequence:this.nextSequence++}))}}enqueueViaNeighbors(t){if(!t.direction)return;const e=EG(t.point.layer,this.input.layerCount);for(const n of[e-1,e+1]){if(n\u003c0||n\u003e=this.input.layerCount)continue;const e=AG(n,this.input.layerCount);if(!this.input.isViaValid(t.point,e,t.direction))continue;const o={...t.point,layer:e},i=t.cost+4,r=this.keyFor(o,t.direction);(this.bestCosts.get(r)??Number.POSITIVE_INFINITY)\u003c=i||(this.bestCosts.set(r,i),this.pushQueue({point:o,direction:t.direction,cost:i,estimate:i+this.estimate(o),parent:t,sequence:this.nextSequence++}))}}},QG=t=\u003e{const e=Math.min(t.bounds.maxX-t.bounds.minX,t.bounds.maxY-t.bounds.minY),n=t.config?.innerGridStep??t.defaultInnerGridStep,o=t.config?.outerGridStep??4*n,i=t.config?.outerPerimeterWidth??Math.min(o,e/4);if(!Number.isFinite(n)||n\u003c1e-4)throw new Error(\"PostProcessingSolver: routingGrid.innerGridStep must be finite and at least 0.0001\");if(!Number.isFinite(o)||o\u003c=n)throw new Error(\"PostProcessingSolver: routingGrid.outerGridStep must be finite and greater than innerGridStep\");if(!Number.isFinite(i)||i\u003c=0||2*i\u003e=e)throw new Error(\"PostProcessingSolver: routingGrid.outerPerimeterWidth must be finite, positive, and less than half the smaller board extent\");const r=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY;if((Math.ceil(r/o)+4)*(Math.ceil(s/o)+4)+(Math.ceil((r-2*i)/n)+2)*(Math.ceil((s-2*i)/n)+2)+18\u003e25e4)throw new VG(\"PostProcessingSolver: valid input exceeds the 250000-node optimization grid capacity\");return{innerGridStep:n,outerGridStep:o,outerPerimeterWidth:i}},tU=t=\u003e{const e=-t.pathDirection.y,n=t.pathDirection.x,o=Math.tan(t.maximumTurnDegrees*Math.PI/180),i=Math.max(0,...t.lanes.map(({point:i,polarity:r})=\u003e{const s=i.x-t.anchor.x,a=i.y-t.anchor.y,c=s*t.escapeDirection.x+a*t.escapeDirection.y,l=s*e+a*n,d=r*t.side*t.centerlineSpacing/2;return c+Math.abs(l-d)/o})),r=t.maxUncoupledLength??i;if(i\u003er+1e-8)return null;const s=Math.max(.05,Math.min(.25,t.searchStep/2)),a=Math.max(1,Math.ceil((r-i)/s)+1);for(let o=0;o\u003ca;o++){const a=Math.min(r,i+o*s),c={x:t.anchor.x+t.escapeDirection.x*a,y:t.anchor.y+t.escapeDirection.y*a,layer:t.anchor.layer};if(t.lanes.every(({point:o,polarity:i})=\u003e{const r=i*t.side*t.centerlineSpacing/2,s=c.x+e*r,a=c.y+n*r;return void 0===t.maxUncoupledLength||Math.hypot(s-o.x,a-o.y)\u003c=t.maxUncoupledLength+1e-8})\u0026\u0026t.isValid(c))return c}return null},eU=[.75,.5,1,.25,1.25],nU=100,oU=class{constructor(t){this.input=t,this.pairName=t.pair.connectionNames.join(\"/\"),this.prepared=this.prepare()}input;pairName;prepared;candidates=[];result=null;search=null;nextAttempt=0;exploredNodeCount=0;isComplete(){return null!==this.result}getResult(){if(!this.result)throw new Error(`PostProcessingSolver: differential pair ${this.pairName} is not complete`);return this.result}getPreviewPath(){return this.search?.getPreviewPath()??null}getProgress(){if(this.result)return 1;const t=this.prepared.attempts.length,e=this.search?.getProgress()??0;return Math.min(.99,(this.nextAttempt+e)/t)}getStats(){return{phase:this.search?\"searching\":\"candidate-selection\",pair:this.pairName,attemptIndex:this.nextAttempt,attemptCount:this.prepared.attempts.length,exploredNodeCount:this.exploredNodeCount+(this.search?.getExploredCount()??0),gridNodeCount:this.search?.getGridNodeCount()??0,acceptedCandidateCount:this.candidates.length}}step(){if(this.result)return;const t=this.prepared;if(!this.search){const e=t.attempts[this.nextAttempt];return e?void(this.search=new KG(e.input)):void this.complete()}if(this.search.step(),!this.search.isComplete())return;const e=this.search.getPath();this.exploredNodeCount+=this.search.getExploredCount();const n=t.attempts[this.nextAttempt];if(!n)throw new Error(`PostProcessingSolver: differential pair ${this.pairName} lost its active attempt`);if(this.search=null,this.nextAttempt++,!e)return;const o=(t=\u003e{const e=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y)\u003c=1e-8;if(t.path.length\u003c2)throw new Error(\"PostProcessingSolver: coupled path has fewer than two stations\");const n=(n,o)=\u003e{for(let i=n+o;i\u003e=0\u0026\u0026i\u003ct.path.length;i+=o){const o=t.path[i];if(!e(o,t.path[n]))return o}return null},o=e=\u003e{const o=t.path[e],i=n(e,-1),r=n(e,1),s=(t,e)=\u003e{const n=e.x-t.x,o=e.y-t.y,i=Math.hypot(n,o);if(i\u003c=1e-10)throw new Error(\"PostProcessingSolver: cannot offset a zero-length spine\");return{x:-o/i,y:n/i}},a=t.side*t.centerlineSpacing/2;if(!i||!r){const t=s(i??o,r??o);return{x:t.x*a,y:t.y*a}}if(t.terminalFanout\u0026\u00261===e)return s(i,o);if(t.terminalFanout\u0026\u0026e===t.path.length-2)return s(o,r);if(t.terminalFanout\u0026\u0026t.path[e+1]?.layer!==o.layer)return s(i,o);const c=s(i,o),l=s(o,r),d={x:c.x+l.x,y:c.y+l.y},h=Math.hypot(d.x,d.y);if(h\u003c=1e-10)return null;const u=d.x/h,p=d.y/h,m=a/(u*c.x+p*c.y);return{x:u*m,y:p*m}},i=t.first.points[0],r=t.first.points.at(-1),s=t.reverseSecond?t.second.points.at(-1):t.second.points[0],a=t.reverseSecond?t.second.points[0]:t.second.points.at(-1),c=[[{route_type:\"wire\",x:i.x,y:i.y,width:i.width,layer:i.layer}],[{route_type:\"wire\",x:s.x,y:s.y,width:s.width,layer:s.layer}]],l=[t.first.transitions[0],t.second.transitions[0]];let d=0;const h=t.terminalFanout?1:0,u=t.path.length-2,p=t.path[u],m=t.path[u-1],g=t.terminalFanout\u0026\u0026p?.layer===r.layer\u0026\u0026m?.layer===p.layer,f=t.terminalFanout?g?u-1:t.path.length-1:t.path.length;for(let n=h;n\u003cf;n++){const i=t.path[n],r=o(n);if(!r)return null;for(const o of[0,1]){const s=0===o?1:-1,a={x:i.x+r.x*s,y:i.y+r.y*s},d=c[o],h=t.path[n-1];if(h\u0026\u0026h.layer!==i.layer){if(!e(h,i))throw new Error(\"PostProcessingSolver: a coupled layer transition moved in the plane\");const n=[...d].reverse().find(t=\u003e\"wire\"===t.route_type);if(!n)throw new Error(\"PostProcessingSolver: generated via has no preceding wire\");const r=l[o];d.push({route_type:\"via\",x:n.x,y:n.y,from_layer:h.layer,to_layer:i.layer,via_diameter:r?.via_diameter??(0===o?t.first.viaDiameter:t.second.viaDiameter),...void 0!==r?.via_hole_diameter?{via_hole_diameter:r.via_hole_diameter}:{}}),d.push({route_type:\"wire\",x:n.x,y:n.y,width:0===o?t.first.width:t.second.width,layer:i.layer})}else{const n=d.at(-1);\"wire\"===n?.route_type\u0026\u0026e(n,a)\u0026\u0026n.layer===i.layer||d.push({route_type:\"wire\",...a,width:0===o?t.first.width:t.second.width,layer:i.layer})}}t.path[n-1]?.layer!==i.layer\u0026\u0026n\u003e0\u0026\u0026d++}const y=(e,n)=\u003e{const o=e.at(-1);if(!o||\"wire\"!==o.route_type)throw new Error(\"PostProcessingSolver: terminal fanout has no preceding wire\");const i=e.at(-2);let r=!1;if(\"wire\"===i?.route_type\u0026\u0026i.layer===o.layer\u0026\u0026o.layer===n.layer){const t={x:o.x-i.x,y:o.y-i.y},e={x:n.x-o.x,y:n.y-o.y},s=Math.hypot(t.x,t.y),a=Math.hypot(e.x,e.y);if(s\u003e1e-8\u0026\u0026a\u003e1e-8\u0026\u0026Math.abs(t.x*e.x+t.y*e.y)\u003c=1e-8){const e={x:o.x-t.x/s*a,y:o.y-t.y/s*a};(e.x-i.x)*(t.x/s)+(e.y-i.y)*(t.y/s)\u003e1e-8\u0026\u0026(o.x=e.x,o.y=e.y,r=!0)}}t.terminalFanout\u0026\u0026!r\u0026\u0026o.x!==n.x\u0026\u0026o.y!==n.y\u0026\u0026e.push({route_type:\"wire\",x:n.x,y:o.y,width:n.width,layer:n.layer}),e.push({route_type:\"wire\",x:n.x,y:n.y,width:n.width,layer:n.layer})};y(c[0],r),y(c[1],a),t.reverseSecond\u0026\u0026(c[1]=c[1].reverse().map(t=\u003e\"via\"===t.route_type?{...t,from_layer:t.to_layer,to_layer:t.from_layer}:t));const _=(t,e)=\u003e{const n=t.filter(t=\u003e\"wire\"===t.route_type);for(const t of n)delete t.start_pcb_port_id,delete t.end_pcb_port_id;e.startPortId\u0026\u0026(n[0].start_pcb_port_id=e.startPortId),e.endPortId\u0026\u0026(n.at(-1).end_pcb_port_id=e.endPortId)};_(c[0],t.first),_(c[1],t.second);const b={...t.first.source,route:c[0]},x={...t.second.source,route:c[1]};return{first:b,second:x,firstParsed:LG(b,t.layerCount),secondParsed:LG(x,t.layerCount),edgeGap:t.edgeGap,centerlineDistance:t.centerlineSpacing,bendCount:Math.max(0,t.path.length-d-2),viaPairCount:d}})({first:t.first,second:t.second,reverseSecond:t.reverseSecond,path:e,centerlineSpacing:n.edgeGap+t.first.width/2+t.second.width/2,edgeGap:n.edgeGap,side:n.side,layerCount:this.input.layerCount,terminalFanout:t.terminalFanout});o\u0026\u0026ZG(o.firstParsed,o.secondParsed,t.context)\u0026\u0026this.candidates.push(o)}prepare(){const t=this.input.traces.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:t})=\u003et.connection_name===this.input.pair.connectionNames[0]),e=this.input.traces.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:t})=\u003et.connection_name===this.input.pair.connectionNames[1]);if(1!==t.length||1!==e.length)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"trace-resolution-failure\",message:\"must resolve each connection_name to exactly one non-branching trace\"});if(t[0].index===e[0].index)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"trace-resolution-failure\",message:\"resolved both members to one trace\"});let n,o;try{n=LG(t[0].trace,this.input.layerCount),o=LG(e[0].trace,this.input.layerCount)}catch(t){throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"invalid-routed-geometry\",message:`has unsupported or invalid routed geometry: ${t instanceof Error?t.message:String(t)}`})}const i=n.points[0],r=n.points.at(-1),s=Math.hypot(i.x-o.points[0].x,i.y-o.points[0].y)+Math.hypot(r.x-o.points.at(-1).x,r.y-o.points.at(-1).y),a=Math.hypot(i.x-o.points.at(-1).x,i.y-o.points.at(-1).y)+Math.hypot(r.x-o.points[0].x,r.y-o.points[0].y)+1e-8\u003cs,c=a?o.points.at(-1):o.points[0],l=a?o.points[0]:o.points.at(-1);if(i.layer!==c.layer||r.layer!==l.layer)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"terminal-layer-mismatch\",message:\"does not have common paired layers at both terminal stations\"});const d={x:(i.x+c.x)/2,y:(i.y+c.y)/2,layer:i.layer},h={x:(r.x+l.x)/2,y:(r.y+l.y)/2,layer:r.layer},u=Math.hypot(h.x-d.x,h.y-d.y);if(u\u003c1e-6)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"coincident-terminal-midpoints\",message:\"has coincident terminal-pair midpoints\"});const p={x:-(h.y-d.y)/u,y:(h.x-d.x)/u},m=i.x-c.x,g=i.y-c.y,f=m*p.x+g*p.y\u003e=0?1:-1,y=(t,e)=\u003e{const n=t.x-e.x,o=t.y-e.y,i=Math.hypot(n,o);return i\u003e1e-8\u0026\u0026Math.abs(n*p.x+o*p.y)/i\u003c.5},_=y(i,c)\u0026\u0026y(r,l),b={x:p.y,y:-p.x},x=[i,c].some(t=\u003e(t.x-d.x)*b.x+(t.y-d.y)*b.y\u003e1e-8),v={immutableTraces:this.input.traces.filter((n,o)=\u003eo!==t[0].index\u0026\u0026o!==e[0].index),obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,minTraceToPadEdgeClearance:this.input.minTraceToPadEdgeClearance},S=(t=\u003e{const{minimumCenterlineDistance:e,maximumCenterlineDistance:n}=t;if(void 0===e\u0026\u0026void 0===n)return t.legacyCenterlineDistances;const o=[...void 0!==e\u0026\u0026void 0!==n?[(e+n)/2,e,n,e-.25,n+.25]:void 0!==e?[e,e+.25,e+.5,e-.25,e+1]:[n,n-.25,n-.5,n+.25,n-1],...t.legacyCenterlineDistances];return o.filter((e,n)=\u003ee\u003et.minimumPhysicalDistance\u0026\u0026o.findIndex(t=\u003eMath.abs(t-e)\u003c1e-8)===n)})({minimumCenterlineDistance:this.input.pair.minimumCenterlineDistance,maximumCenterlineDistance:this.input.pair.maximumCenterlineDistance,minimumPhysicalDistance:n.width/2+o.width/2,legacyCenterlineDistances:eU.map(t=\u003et+n.width/2+o.width/2)}).flatMap(t=\u003e{const e=t-n.width/2-o.width/2;return[f,1===f?-1:1].flatMap(s=\u003e{const a=QG({config:this.input.routingGrid,bounds:this.input.bounds,defaultInnerGridStep:Math.max(.25,Math.min(.5,t/2))}),u=(e,a)=\u003eUG({...v,start:e,end:a,firstConnectionName:n.source.connection_name,secondConnectionName:o.source.connection_name,firstStartTerminal:i,firstEndTerminal:r,secondStartTerminal:c,secondEndTerminal:l,firstWidth:n.width,secondWidth:o.width,firstViaDiameter:n.transitions[0]?.via_diameter??n.viaDiameter,secondViaDiameter:o.transitions[0]?.via_diameter??o.viaDiameter,centerlineSpacing:t,side:s,terminalFanout:_,terminalMiterMargin:void 0===this.input.pair.maxUncoupledLength?void 0:t/2});let m=void 0===this.input.pair.maxUncoupledLength?((t,e)=\u003e{if(!x||_)return d;const n=[{terminal:i,offset:e*t/2},{terminal:c,offset:-e*t/2}],o=Math.tan(55*Math.PI/180),r=Math.max(...n.map(({terminal:t,offset:e})=\u003e{const n=(t.x-d.x)*b.x+(t.y-d.y)*b.y,i=(t.x-d.x)*p.x+(t.y-d.y)*p.y;return n+Math.abs(i-e)/o}));return{x:d.x+b.x*r,y:d.y+b.y*r,layer:d.layer}})(t,s):d,g=h;if(!_\u0026\u0026void 0!==this.input.pair.maxUncoupledLength){const e=u(d,h),n=tU({anchor:d,escapeDirection:b,pathDirection:b,centerlineSpacing:t,side:s,lanes:[{point:i,polarity:1},{point:c,polarity:-1}],maxUncoupledLength:this.input.pair.maxUncoupledLength,maximumTurnDegrees:55,searchStep:a.innerGridStep,isValid:t=\u003ee.isTerminalFanoutValid(t,b,\"start\")}),o=tU({anchor:h,escapeDirection:{x:-b.x,y:-b.y},pathDirection:b,centerlineSpacing:t,side:s,lanes:[{point:r,polarity:1},{point:l,polarity:-1}],maxUncoupledLength:this.input.pair.maxUncoupledLength,maximumTurnDegrees:45,searchStep:a.innerGridStep,isValid:t=\u003ee.isTerminalFanoutValid(t,b,\"end\")});if(!n||!o)return[];m=n,g=o;if((g.x-m.x)*b.x+(g.y-m.y)*b.y\u003c=a.innerGridStep)return[]}const f=u(m,g);return[{edgeGap:e,side:s,input:{start:m,end:g,bounds:this.input.bounds,layerCount:this.input.layerCount,grid:a,...f}}]})});return{first:n,second:o,reverseSecond:a,terminalFanout:_,context:v,attempts:S}}complete(){if(0===this.candidates.length)throw new YG({connectionNames:this.input.pair.connectionNames,reason:\"no-valid-candidate\",message:\"could not be improved without violating bounds, copper clearance, or coupled-via constraints\"});this.candidates.sort((t,e)=\u003ethis.score(t)-this.score(e)||t.edgeGap-e.edgeGap),this.result={status:\"accepted\",candidate:this.candidates[0]}}score(t){return(void 0!==this.input.pair.minimumCenterlineDistance||void 0!==this.input.pair.maximumCenterlineDistance?Math.max(0,(this.input.pair.minimumCenterlineDistance??Number.NEGATIVE_INFINITY)-t.centerlineDistance)*nU+Math.max(0,t.centerlineDistance-(this.input.pair.maximumCenterlineDistance??Number.POSITIVE_INFINITY))*nU:t.edgeGap\u003c.5?(.5-t.edgeGap)*nU:t.edgeGap\u003e1?(t.edgeGap-1)*nU:0)+FG(t.firstParsed)+FG(t.secondParsed)+.15*t.bendCount+8*t.viaPairCount}},iU=t=\u003e{const e={lines:[],points:[],rects:[],circles:[]};e.rects.push({center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,fill:\"rgba(30, 70, 120, 0.04)\",stroke:\"rgba(30, 70, 120, 0.55)\",layer:`z${Array.from({length:t.layerCount},(t,e)=\u003ee).join(\",\")}`});for(const n of t.obstacles){const o=uG(n,t.layerCount);e.rects.push({center:n.center,width:n.width,height:n.height,ccwRotationDegrees:n.ccwRotationDegrees,fill:\"rgba(220, 60, 60, 0.16)\",stroke:\"rgba(190, 40, 40, 0.75)\",layer:`z${o.join(\",\")}`})}for(let n=0;n\u003c(t.previewPath?.length??0)-1;n++){const o=t.previewPath[n],i=t.previewPath[n+1];if(o.layer!==i.layer)continue;const r=EG(o.layer,t.layerCount);e.lines.push({points:[o,i],strokeColor:\"#16a34a\",strokeWidth:.08,strokeDash:[.18,.12],layer:`z${r}`})}for(const n of t.traces){if(t.activeConnectionNames?.includes(n.connection_name))continue;const o=\"#2563eb\";let i=null;for(const r of n.route)if(\"wire\"===r.route_type){if(i\u0026\u0026i.layer===r.layer){const n=EG(r.layer,t.layerCount);e.lines.push({points:[i,r],strokeColor:o,strokeWidth:Math.max(i.width,r.width),...0===n?{}:{strokeDash:[.2,.16]},layer:`z${n}`})}i=r}else if(\"via\"===r.route_type){const n=OG(r.from_layer,r.to_layer,t.layerCount).map(e=\u003eEG(e,t.layerCount));if(e.circles.push({center:r,radius:(r.via_diameter??i?.width??.2)/2,fill:\"rgba(37, 99, 235, 0.45)\",stroke:o,layer:`z${n.join(\",\")}`}),i){const t=i.width;i={x:r.x,y:r.y,layer:r.to_layer,width:t}}}}return e},rU=class extends kt{constructor(t){super(),this.params=t,this.outputTraces=HG(t.simpleRouteJson.traces),this.MAX_ITERATIONS=WG(t)}params;outputTraces;reroutedPairs=[];failures=[];nextPairIndex=0;activeConnectionNames=null;activeSession=null;getSolverName(){return\"DifferentialPairReroutingSolver\"}_step(){const t=this.params.simpleRouteJson.differentialPairs[this.nextPairIndex];if(!t)return void this.finish();this.activeConnectionNames=t.connectionNames;try{if(!this.activeSession)return this.activeSession=new oU({pair:t,traces:this.outputTraces,obstacles:this.params.simpleRouteJson.obstacles,bounds:this.params.simpleRouteJson.bounds,layerCount:this.params.simpleRouteJson.layerCount,minTraceToPadEdgeClearance:this.params.simpleRouteJson.minTraceToPadEdgeClearance,routingGrid:this.params.routingGrid}),void(this.stats=this.activeSession.getStats());this.activeSession.step()}catch(e){if(!(e instanceof YG))throw e;return void this.skipFailedPair(t,e)}if(this.stats=this.activeSession.getStats(),!this.activeSession.isComplete())return;const e=this.activeSession.getResult();this.activeSession=null;for(const t of[e.candidate.first,e.candidate.second]){const e=this.outputTraces.findIndex(e=\u003ee.connection_name===t.connection_name);if(e\u003c0)throw new Error(`DifferentialPairReroutingSolver: accepted replacement for unknown connection \"${t.connection_name}\"`);this.outputTraces[e]=t}this.reroutedPairs.push(t),this.nextPairIndex++,this.nextPairIndex!==this.params.simpleRouteJson.differentialPairs.length?this.stats={phase:\"accepted\",pair:t.connectionNames.join(\"/\"),pairIndex:this.nextPairIndex-1,pairCount:this.params.simpleRouteJson.differentialPairs.length}:this.finish()}finish(){this.activeConnectionNames=null,this.solved=!0,this.stats={phase:\"complete\",acceptedPairCount:this.reroutedPairs.length,skippedPairCount:this.failures.length}}skipFailedPair(t,e){this.failures.push({connectionNames:[...t.connectionNames],reason:e.reason,message:e.message}),this.activeSession=null,this.nextPairIndex++,this.nextPairIndex!==this.params.simpleRouteJson.differentialPairs.length?this.stats={phase:\"skipped\",pair:t.connectionNames.join(\"/\"),pairIndex:this.nextPairIndex-1,pairCount:this.params.simpleRouteJson.differentialPairs.length,skippedPairCount:this.failures.length}:this.finish()}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved)throw new Error(\"DifferentialPairReroutingSolver: getOutput() called before completion\");return this.getBestEffortOutput()}getBestEffortOutput(){return{traces:HG(this.outputTraces),reroutedPairs:this.reroutedPairs.map(t=\u003e({...t,connectionNames:[...t.connectionNames]})),failures:this.failures.map(t=\u003e({...t,connectionNames:[...t.connectionNames]}))}}computeProgress(){return this.solved?1:0===this.params.simpleRouteJson.differentialPairs.length?0:(this.nextPairIndex+(this.activeSession?.getProgress()??0))/this.params.simpleRouteJson.differentialPairs.length}visualize(){return iU({traces:this.outputTraces,obstacles:this.params.simpleRouteJson.obstacles,bounds:this.params.simpleRouteJson.bounds,layerCount:this.params.simpleRouteJson.layerCount,activeConnectionNames:this.activeConnectionNames,previewPath:this.activeSession?.getPreviewPath()??null})}},sU=1e-8,aU=class extends kt{constructor(t){super(),this.input=t,this.traces=HG(t.traces),this.MAX_ITERATIONS=Math.max(1,t.reroutedPairs.length+1)}input;traces;nextPairIndex=0;getSolverName(){return\"FortyFiveDegreeSimplificationSolver\"}_step(){const t=this.input.reroutedPairs[this.nextPairIndex];if(!t)return this.solved=!0,void(this.stats={phase:\"complete\",simplifiedPairCount:this.nextPairIndex});this.traces=(t=\u003e{const e=t.pair.connectionNames.join(\"/\"),n=t.pair.connectionNames.map(e=\u003et.traces.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:t})=\u003et.connection_name===e));if(1!==n[0].length||1!==n[1].length)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} must resolve to exactly two traces`);const o=n[0][0].index,i=n[1][0].index;if(o===i)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} resolved both members to one trace`);const r=structuredClone(t.traces),s={immutableTraces:r.filter((t,e)=\u003ee!==o\u0026\u0026e!==i),obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,minTraceToPadEdgeClearance:t.minTraceToPadEdgeClearance},a=n=\u003e{const r=LG(n[o],t.layerCount),s=LG(n[i],t.layerCount);let a=0;for(const[t,n]of[[r.segments,s.segments],[s.segments,r.segments]])for(const o of t){if(null!==o.terminal)continue;const t=n.filter(t=\u003et.layer===o.layer);if(0===t.length)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} lost common-layer interior copper`);a=Math.max(a,Math.min(...t.map(t=\u003ecG(o.start,o.end,t.start,t.end))))}return a},c=e=\u003e{const n=LG(e[o],t.layerCount),r=LG(e[i],t.layerCount);let s=Number.POSITIVE_INFINITY;for(const[t,e]of[[n.segments,r.segments],[r.segments,n.segments]])for(const n of t)if(null===n.terminal)for(const t of e)t.layer===n.layer\u0026\u0026(s=Math.min(s,cG(n.start,n.end,t.start,t.end)-n.width/2-t.width/2));return Number.isFinite(s)?s:null},l=e=\u003e{const n=LG(e[o],t.layerCount),r=LG(e[i],t.layerCount);return ZG(n,r,s)};if(!l(r))throw new Error(`FortyFiveDegreeSimplificationSolver: rerouted pair ${e} has invalid complete copper before simplification`);if(void 0!==t.pair.maxUncoupledLength\u0026\u0026void 0!==t.pair.minimumCenterlineDistance\u0026\u0026void 0!==t.pair.maximumCenterlineDistance\u0026\u0026Math.abs(t.pair.minimumCenterlineDistance-t.pair.maximumCenterlineDistance)\u003c=sU)return r;const d=LG(r[o],t.layerCount),h=LG(r[i],t.layerCount),u=Math.abs(FG(d)-FG(h)),p=c(r),m=t.pair.maximumCenterlineDistance??1+d.width/2+h.width/2,g=Math.min(a(r),m),f=t=\u003e{if(!l(t))return!1;if(a(t)\u003eg+sU)return!1;const e=c(t);return null===p||null===e||e\u003e=p-sU},y=(t,e)=\u003e{const n=Math.abs(e.x-t.x),o=Math.abs(e.y-t.y),i=e.x\u003e=t.x?1:-1,r=e.y\u003e=t.y?1:-1,s=[],a={x:e.x-i*o,y:t.y};(a.x-t.x)*i\u003e=-1e-8\u0026\u0026(a.x-e.x)*i\u003c=sU\u0026\u0026s.push([t,a,e]);const c={x:t.x,y:e.y-r*n};(c.y-t.y)*r\u003e=-1e-8\u0026\u0026(c.y-e.y)*r\u003c=sU\u0026\u0026s.push([t,c,e]);const l={x:t.x+i*Math.min(n,o),y:t.y+r*Math.min(n,o)};return s.push([t,l,e]),s.map((t,e)=\u003e{const n=t.filter((e,n)=\u003e0===n||Math.hypot(e.x-t[n-1].x,e.y-t[n-1].y)\u003esU),o=n.slice(0,-1).map((t,e)=\u003e{const o=n[e+1],i=Math.abs(o.x-t.x),r=Math.abs(o.y-t.y);return{length:Math.hypot(i,r),straight:i\u003c=sU||r\u003c=sU?Math.hypot(i,r):0}});return{points:n,usableStraightLength:Math.max(0,...o.map(t=\u003et.straight)),bendCount:Math.max(0,n.length-2),priority:e}}).filter((t,e,n)=\u003en.findIndex(e=\u003eJSON.stringify(e.points)===JSON.stringify(t.points))===e).sort((t,e)=\u003ee.usableStraightLength-t.usableStraightLength||t.bendCount-e.bendCount||t.priority-e.priority)},_=t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n];if(\"wire\"===o?.route_type)for(let i=t.route.length-1;i\u003e=n+1;i--){if(0===n||i===t.route.length-1)continue;const r=t.route[i];\"wire\"===r?.route_type\u0026\u0026r.layer===o.layer\u0026\u0026(t.route.slice(n+1,i).some(t=\u003e\"wire\"!==t.route_type||t.layer!==o.layer)||e.push({startIndex:n,endIndex:i,skippedPointCount:i-n-1}))}}return e.sort((t,e)=\u003ee.skippedPointCount-t.skippedPointCount||t.startIndex-e.startIndex||e.endIndex-t.endIndex)},b=(t,e,n)=\u003e{const o=t.route[e.startIndex],i=t.route[e.endIndex],r=Math.max(o.width,i.width),s=n.points.slice(1,-1).map(t=\u003e({route_type:\"wire\",...t,width:r,layer:o.layer}));return{...t,route:[...t.route.slice(0,e.startIndex+1),...s,...t.route.slice(e.endIndex)]}};for(const t of[o,i]){let e=!0;for(;e;){e=!1;const n=r[t];for(const s of _(n)){const a=n.route[s.startIndex],c=n.route[s.endIndex],l=n.route.slice(s.startIndex,s.endIndex+1),d=l.slice(0,-1).every((t,e)=\u003e{const n=l[e+1],o=Math.abs(n.x-t.x),i=Math.abs(n.y-t.y);return o\u003c=sU||i\u003c=sU||Math.abs(o-i)\u003c=sU});for(const h of y(a,c)){if(h.points.length\u003e=l.length\u0026\u0026d)continue;const a=b(n,s,h),c=[...r];if(c[t]=a,JSON.stringify(a.route)===JSON.stringify(n.route))continue;if(f(c)){r[t]=a,e=!0;break}const u=t===o?i:o,p=r[u],m=_(p).find(t=\u003et.startIndex===s.startIndex\u0026\u0026t.endIndex===s.endIndex);if(!m)continue;const g=p.route[m.startIndex],x=p.route[m.endIndex];for(const n of y(g,x)){const o=b(p,m,n),i=[...c];if(i[u]=o,f(i)){r[t]=a,r[u]=o,e=!0;break}}if(e)break}if(e)break}}}if(!f(r))throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} produced invalid complete copper`);const x=LG(r[o],t.layerCount),v=LG(r[i],t.layerCount),S=Math.abs(FG(x)-FG(v));return Math.abs(S-u)\u003et.pair.lengthTolerance+sU?structuredClone(t.traces):r})({traces:this.traces,pair:t,obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,minTraceToPadEdgeClearance:this.input.minTraceToPadEdgeClearance}),this.nextPairIndex++,this.stats={phase:\"simplifying\",pair:t.connectionNames.join(\"/\"),pairIndex:this.nextPairIndex-1,pairCount:this.input.reroutedPairs.length}}getConstructorParams(){return[this.input]}getOutput(){if(!this.solved)throw new Error(\"FortyFiveDegreeSimplificationSolver: getOutput() called before completion\");return this.getBestEffortOutput()}getBestEffortOutput(){return{traces:HG(this.traces),reroutedPairs:this.input.reroutedPairs.map(t=\u003e({...t,connectionNames:[...t.connectionNames]}))}}computeProgress(){return this.solved?1:0===this.input.reroutedPairs.length?0:this.nextPairIndex/this.input.reroutedPairs.length}visualize(){return iU({traces:this.traces,obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,activeConnectionNames:this.input.reroutedPairs[this.nextPairIndex]?.connectionNames??null,previewPath:null})}},cU=class extends kt{constructor(t){super(),this.input=t}input;output=null;visualizationTraces=null;getSolverName(){return\"HdRouteReconstructionSolver\"}_step(){this.visualizationTraces=(t=\u003e{const{simpleRouteJson:e}=t.params;if(t.result.matchedHdRoutes.length!==t.binding.solverParams.hdRoutes.length)throw new Error(\"PostProcessingSolver: LengthMatchingSolver changed the search route count\");const n=structuredClone(t.binding.baseTraces);for(const o of t.binding.traceBindings){const i=t.result.matchedHdRoutes[o.matchedRouteIndex];if(!i)throw new Error(`PostProcessingSolver: missing matched route at index ${o.matchedRouteIndex}`);const r=n[o.traceIndex];if(!r)throw new Error(`PostProcessingSolver: missing simplified trace binding at index ${o.traceIndex}`);if(r.connection_name!==i.connectionName)throw new Error(`PostProcessingSolver: route binding changed connection \"${r.connection_name}\" to \"${i.connectionName}\"`);if(i.route.length\u003c2)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" has incomplete geometry`);const s=i.route[0],a=i.route.at(-1);if(Math.hypot(s.x-o.startEndpoint.x,s.y-o.startEndpoint.y)\u003e1e-8||s.z!==o.startEndpoint.z||Math.hypot(a.x-o.endEndpoint.x,a.y-o.endEndpoint.y)\u003e1e-8||a.z!==o.endEndpoint.z)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" moved a preserved endpoint`);const c=[];let l=0;const d=t=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:t.traceThickness??i.traceThickness,layer:AG(t.z,e.layerCount)});c.push(d(i.route[0]));for(let t=1;t\u003ci.route.length;t++){const n=i.route[t-1],r=i.route[t];if(n.z===r.z){c.push(d(r));continue}if(Math.hypot(n.x-r.x,n.y-r.y)\u003e1e-8)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" moves while changing layers`);const s=o.viaTemplates[l++];if(!s)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" added an unbound via`);if(Math.hypot(s.x-r.x,s.y-r.y)\u003e1e-8)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" moved a preserved via`);const a=AG(n.z,e.layerCount),h=AG(r.z,e.layerCount),u=new Set([s.from_layer,s.to_layer]);if(!u.has(a)||!u.has(h))throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" changed a preserved via span`);c.push({...s}),c.push(d(r))}if(l!==o.viaTemplates.length)throw new Error(`PostProcessingSolver: matched connection \"${i.connectionName}\" removed a preserved via`);const h=c.filter(t=\u003e\"wire\"===t.route_type);for(const t of h)delete t.start_pcb_port_id,delete t.end_pcb_port_id;o.startPortId\u0026\u0026(h[0].start_pcb_port_id=o.startPortId),o.endPortId\u0026\u0026(h.at(-1).end_pcb_port_id=o.endPortId),n[o.traceIndex]={...r,route:c}}for(const o of t.binding.solverParams.differentialPairs){const t=o.connectionNames.join(\"/\"),i=o.connectionNames.map(t=\u003en.map((t,e)=\u003e({trace:t,index:e})).filter(({trace:e})=\u003ee.connection_name===t));if(1!==i[0].length||1!==i[1].length)throw new Error(`PostProcessingSolver: reconstructed pair ${t} does not resolve to complete copper`);const r=i[0][0],s=i[1][0],a=LG(r.trace,e.layerCount),c=LG(s.trace,e.layerCount),l=Math.abs(FG(a)-FG(c));if(l\u003eo.lengthTolerance+1e-7)throw new XG({message:`PostProcessingSolver: reconstructed pair ${t} exceeds length tolerance ${o.lengthTolerance} with error ${l}`,connectionNames:[...o.connectionNames],reason:\"length-tolerance-unsatisfied\"});if(!ZG(a,c,{immutableTraces:n.filter((t,e)=\u003ee!==r.index\u0026\u0026e!==s.index),obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,minTraceToPadEdgeClearance:e.minTraceToPadEdgeClearance}))throw new XG({message:`PostProcessingSolver: length matching produced invalid complete copper for pair ${t}`,connectionNames:[...o.connectionNames],reason:\"invalid-final-copper\"})}return n})(this.input),this.output=$G({...this.input,rejectInsideJumperPad:!0}),this.stats={phase:\"complete\",routeCount:this.output.hdRoutes.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){if(!this.output||!this.solved)throw new Error(\"HdRouteReconstructionSolver: getOutput() called before completion\");return structuredClone(this.output)}visualize(){const t=this.visualizationTraces??this.input.simplified.traces,{obstacles:e,bounds:n,layerCount:o}=this.input.params.simpleRouteJson;return iU({traces:t,obstacles:e,bounds:n,layerCount:o,activeConnectionNames:null,previewPath:null})}};var lU=class extends Dt{differentialPairReroutingSolver;fortyFiveDegreeSimplificationSolver;lengthMatchingSolver;hdRouteReconstructionSolver;lengthMatchingBinding=null;model;fallbackOutput=null;postProcessingErrors=[];pipelineDef=[Lt(\"differentialPairReroutingSolver\",rU,t=\u003e[t.model.params]),Lt(\"fortyFiveDegreeSimplificationSolver\",aU,t=\u003e{const e=t.getStageOutput(\"differentialPairReroutingSolver\");if(!e)throw new Error(\"PostProcessingSolver: rerouting stage completed without output\");const{obstacles:n,bounds:o,layerCount:i,minTraceToPadEdgeClearance:r}=t.model.params.simpleRouteJson;return[{...e,obstacles:n,bounds:o,layerCount:i,minTraceToPadEdgeClearance:r}]}),Lt(\"lengthMatchingSolver\",RG,t=\u003e{const e=t.getStageOutput(\"fortyFiveDegreeSimplificationSolver\");if(!e)throw new Error(\"PostProcessingSolver: 45-degree simplification stage completed without output\");return t.lengthMatchingBinding=BG({result:e,params:t.model.params}),[t.lengthMatchingBinding.solverParams]}),Lt(\"hdRouteReconstructionSolver\",cU,t=\u003e{const e=t.getStageOutput(\"fortyFiveDegreeSimplificationSolver\"),n=t.getStageOutput(\"lengthMatchingSolver\");if(!e||!n||!t.lengthMatchingBinding)throw new Error(\"PostProcessingSolver: reconstruction stage is missing a required binding or output\");return[{binding:t.lengthMatchingBinding,result:n,simplified:e,params:t.model.params,model:t.model}]},{onSolved:t=\u003e{const e=t.getStageOutput(\"differentialPairReroutingSolver\");if(!e)throw new Error(\"PostProcessingSolver: cannot summarize missing rerouting output\");t.stats={phase:\"complete\",acceptedPairCount:e.reroutedPairs.length},e.failures.length\u003e0\u0026\u0026(t.stats.skippedPairCount=e.failures.length,t.stats.postProcessingErrorCount=e.failures.length)}})];constructor(t){super(structuredClone(t));let e=null;try{!function(t){if(!t||\"object\"!=typeof t)throw new Error(\"PostProcessingSolver: params must be an object\");if(!Array.isArray(t.hdRoutes))throw new Error(\"PostProcessingSolver: hdRoutes must be an array\");if(!Array.isArray(t.differentialPairs))throw new Error(\"PostProcessingSolver: differentialPairs must be an array\");if(!Array.isArray(t.obstacles))throw new Error(\"PostProcessingSolver: obstacles must be an array\");if(void 0!==t.minTraceToPadEdgeClearance\u0026\u0026(!Number.isFinite(t.minTraceToPadEdgeClearance)||t.minTraceToPadEdgeClearance\u003c0))throw new Error(\"PostProcessingSolver: minTraceToPadEdgeClearance must be finite and nonnegative\");if(!Number.isInteger(t.layerCount)||t.layerCount\u003c1)throw new Error(\"PostProcessingSolver: layerCount must be a positive integer\");for(const e of t.obstacles){if(!e||\"object\"!=typeof e||\"rect\"!==e.type||!e.center||!Number.isFinite(e.center.x)||!Number.isFinite(e.center.y)||!Number.isFinite(e.width)||e.width\u003c=0||!Number.isFinite(e.height)||e.height\u003c=0||!Array.isArray(e.layers)||e.layers.some(t=\u003e\"string\"!=typeof t)||!Array.isArray(e.connectedTo)||e.connectedTo.some(t=\u003e\"string\"!=typeof t||0===t.length)||void 0!==e.ccwRotationDegrees\u0026\u0026!Number.isFinite(e.ccwRotationDegrees))throw new Error(\"PostProcessingSolver: obstacle declaration is invalid\");uG(e,t.layerCount)}const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds??{};if(![e,n,o,i].every(Number.isFinite)||e\u003e=n||o\u003e=i)throw new Error(\"PostProcessingSolver: bounds must have finite positive extents\");const r=new Set(t.differentialPairs.flatMap(t=\u003et.connectionNames));for(const e of t.hdRoutes){if(!e||\"object\"!=typeof e||\"string\"!=typeof e.connectionName||0===e.connectionName.length||void 0!==e.rootConnectionName\u0026\u0026(\"string\"!=typeof e.rootConnectionName||0===e.rootConnectionName.length)||!Number.isFinite(e.traceThickness)||e.traceThickness\u003c=0||!Number.isFinite(e.viaDiameter)||e.viaDiameter\u003c0||0===e.viaDiameter\u0026\u0026r.has(e.connectionName)||!Array.isArray(e.route)||!Array.isArray(e.vias)||void 0!==e.jumpers\u0026\u0026!Array.isArray(e.jumpers))throw new Error(\"PostProcessingSolver: HD route declaration is invalid\");if(void 0!==e.startPcbPortId\u0026\u0026(\"string\"!=typeof e.startPcbPortId||0===e.startPcbPortId.length)||void 0!==e.endPcbPortId\u0026\u0026(\"string\"!=typeof e.endPcbPortId||0===e.endPcbPortId.length))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has invalid terminal metadata`);for(const n of e.route)if(!n||\"object\"!=typeof n||!Number.isFinite(n.x)||!Number.isFinite(n.y)||!Number.isInteger(n.z)||n.z\u003c0||n.z\u003e=t.layerCount||void 0!==n.traceThickness\u0026\u0026(!Number.isFinite(n.traceThickness)||n.traceThickness\u003c=0))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has an invalid route point`);for(const n of e.vias)if(!n||\"object\"!=typeof n||!Number.isFinite(n.x)||!Number.isFinite(n.y)||void 0!==n.zLayers\u0026\u0026(!Array.isArray(n.zLayers)||n.zLayers.some(e=\u003e!Number.isInteger(e)||e\u003c0||e\u003e=t.layerCount)))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has an invalid via`);if(e.vias.length\u003e0\u0026\u0026e.viaDiameter\u003c=0)throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has a non-positive via diameter`);for(const t of e.jumpers??[])if(!(t\u0026\u0026\"object\"==typeof t\u0026\u0026\"jumper\"===t.route_type\u0026\u0026Number.isFinite(t.start?.x)\u0026\u0026Number.isFinite(t.start?.y)\u0026\u0026Number.isFinite(t.end?.x)\u0026\u0026Number.isFinite(t.end?.y)\u0026\u0026[\"0603\",\"1206\",\"1206x4_pair\"].includes(t.footprint)))throw new Error(`PostProcessingSolver: HD route \"${e.connectionName}\" has an invalid jumper`)}const s=new Set;for(const e of t.differentialPairs){if(!e||\"object\"!=typeof e||!Array.isArray(e.connectionNames)||2!==e.connectionNames.length||e.connectionNames[0]===e.connectionNames[1]||!e.connectionNames.every(t=\u003e\"string\"==typeof t\u0026\u0026t.length\u003e0)||!Number.isFinite(e.lengthTolerance)||e.lengthTolerance\u003c0)throw new Error(\"PostProcessingSolver: differential pair declaration is invalid\");for(const t of[e.minimumCenterlineDistance,e.maximumCenterlineDistance])if(void 0!==t\u0026\u0026(!Number.isFinite(t)||t\u003c=0))throw new Error(\"PostProcessingSolver: differential pair centerline distances must be positive finite numbers\");if(void 0!==e.maxUncoupledLength\u0026\u0026(!Number.isFinite(e.maxUncoupledLength)||e.maxUncoupledLength\u003c0))throw new Error(\"PostProcessingSolver: differential pair maxUncoupledLength must be a non-negative finite number\");if(void 0!==e.minimumCenterlineDistance\u0026\u0026void 0!==e.maximumCenterlineDistance\u0026\u0026e.minimumCenterlineDistance\u003ee.maximumCenterlineDistance)throw new Error(\"PostProcessingSolver: differential pair minimumCenterlineDistance cannot exceed maximumCenterlineDistance\");for(const t of e.connectionNames){if(s.has(t))throw new Error(`PostProcessingSolver: connection \"${t}\" belongs to multiple differential pairs`);s.add(t)}}for(const e of[.25,.5])QG({config:t.routingGrid,bounds:t.bounds,defaultInnerGridStep:e})}(t)}catch(t){if(!(t instanceof VG))throw t;e=t}if(this.model=jG(t),e)return void this.finishWithBestEffortOutput({stage:\"differentialPairReroutingSolver\",message:e.message,reason:e.reason});const n=WG(this.model.params)+Math.max(1,t.differentialPairs.length+1)+1e5+10;if(!Number.isSafeInteger(n))throw new Error(\"PostProcessingSolver: derived pipeline iteration bound exceeds the safe integer range\");this.MAX_ITERATIONS=n}getSolverName(){return\"PostProcessingSolver\"}getConstructorParams(){return[structuredClone(this.inputProblem)]}_step(){const t=this.getCurrentStageName();try{super._step()}catch(e){const n=this.classifyOptimizationFailure(e,t);if(!n)throw e;return void this.finishWithBestEffortOutput(n)}if(!this.failed)return;const e=this.classifyIterationFailure(this.error,t);if(!e)throw new Error(this.error??\"PostProcessingSolver failed without an error message\");this.finishWithBestEffortOutput(e)}tryFinalAcceptance(){const t=this.getCurrentStageName();\"differentialPairReroutingSolver\"!==t\u0026\u0026\"lengthMatchingSolver\"!==t||this.finishWithBestEffortOutput({stage:t,message:\"PostProcessingSolver reached its iteration limit\",reason:\"iteration-limit-exhausted\"})}classifyOptimizationFailure(t,e){return\"lengthMatchingSolver\"===e\u0026\u0026t instanceof IG?{stage:e,message:t.message,connectionName:t.connectionName,reason:t.reason}:\"hdRouteReconstructionSolver\"===e\u0026\u0026t instanceof XG||\"differentialPairReroutingSolver\"===e\u0026\u0026t instanceof YG\u0026\u0026\"no-valid-candidate\"===t.reason?{stage:e,message:t.message,connectionNames:[...t.connectionNames],reason:t.reason}:null}classifyIterationFailure(t,e){return\"differentialPairReroutingSolver\"!==e\u0026\u0026\"lengthMatchingSolver\"!==e?null:t\u0026\u0026t.endsWith(\"ran out of iterations\")?{stage:e,message:t,reason:\"iteration-limit-exhausted\"}:null}createBestEffortOutput(t){let e=this.lengthMatchingBinding;if(!e){const t=this.getStageOutput(\"fortyFiveDegreeSimplificationSolver\")??this.fortyFiveDegreeSimplificationSolver?.getBestEffortOutput(),n=this.getStageOutput(\"differentialPairReroutingSolver\")??this.differentialPairReroutingSolver?.getBestEffortOutput(),o=t??n;o\u0026\u0026(e=BG({result:o,params:this.model.params}))}if(!e)return{output:{hdRoutes:structuredClone(this.inputProblem.hdRoutes),postProcessingErrors:[]},source:\"input-hd-routes\"};let n=this.getStageOutput(\"lengthMatchingSolver\");return n||(n=this.lengthMatchingSolver?.getBestEffortOutput()),n\u0026\u0026\"invalid-final-copper\"!==t.reason||(n={matchedHdRoutes:e.solverParams.hdRoutes}),{output:$G({binding:e,result:n,model:this.model}),source:\"best-effort-hd-routes\"}}finishWithBestEffortOutput(t){const e=this.createBestEffortOutput(t),n={type:\"post_processing_error\",...t,returnedRouteSource:e.source};this.postProcessingErrors.push(n),this.fallbackOutput=e.output,this.activeSubSolver=null,this.error=null,this.failed=!1,this.solved=!0,this.progress=1,this.stats={phase:\"complete\",postProcessingErrorCount:this.postProcessingErrors.length}}getOutput(){if(!this.solved)throw new Error(\"PostProcessingSolver: getOutput() called before the solver completed\");const t=this.fallbackOutput??this.getStageOutput(\"hdRouteReconstructionSolver\");if(!t)throw new Error(\"PostProcessingSolver: completed pipeline is missing reconstruction output\");const e=this.getStageOutput(\"differentialPairReroutingSolver\")??this.differentialPairReroutingSolver?.getBestEffortOutput(),n=e?.failures??[];let o=\"input-hd-routes\";(e?.reroutedPairs.length??0)\u003e0\u0026\u0026(o=\"best-effort-hd-routes\");const i=[...n.map(t=\u003e({type:\"post_processing_error\",stage:\"differentialPairReroutingSolver\",message:t.message,connectionNames:[...t.connectionNames],reason:t.reason,returnedRouteSource:o})),...this.postProcessingErrors],r=structuredClone(t);return r.postProcessingErrors=structuredClone(i),r}initialVisualize(){if(this.fallbackOutput)return{lines:this.fallbackOutput.hdRoutes.map(t=\u003e({points:t.route.map(({x:t,y:e})=\u003e({x:t,y:e})),strokeWidth:t.traceThickness}))};const{traces:t,obstacles:e,bounds:n,layerCount:o}=this.model.params.simpleRouteJson;return iU({traces:structuredClone(t),obstacles:e,bounds:n,layerCount:o,activeConnectionNames:null,previewPath:null})}finalVisualize(){if(this.fallbackOutput)return this.initialVisualize();const t=jG({...this.inputProblem,hdRoutes:this.getOutput().hdRoutes}),{traces:e,obstacles:n,bounds:o,layerCount:i}=t.params.simpleRouteJson;return iU({traces:e,obstacles:n,bounds:o,layerCount:i,activeConnectionNames:null,previewPath:null})}},dU=class t{static generators=new Map;static register(e){t.generators.set(e.componentKind,e)}static create(e){const n=e.detectedComponent.componentKind,o=t.generators.get(n);if(!o)throw new Error(`No topology generator registered for component kind \"${n}\"`);return new o(e)}},hU=t=\u003e[t.obstacle.obstacleId??t.obstacle.componentId??\"obstacle\",t.start.x.toFixed(4),t.start.y.toFixed(4),t.end.x.toFixed(4),t.end.y.toFixed(4),t.expansionDirection.x,t.expansionDirection.y].join(\":\"),uU=t=\u003e{let e=0;for(const n of t)e=31*e+n.charCodeAt(0)\u003e\u003e\u003e0;return e},pU=(t,e)=\u003e`hsla(${uU(hU(t))%360},72%,36%,${e})`,mU=t=\u003e{const e=t.expansionDirection;return e.x\u003c0?\"left\":e.x\u003e0?\"right\":e.y\u003c0?\"bottom\":\"top\"},gU=t=\u003e({x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2}),fU=t=\u003e{const e=/^bga-gapfill-(\\d+)-/.exec(t.capacityMeshNodeId);return e?Number.parseInt(e[1],10):null},yU=(t,e)=\u003e{const n=gU(t),o=gU(e),i=n.y-o.y;if(Math.abs(i)\u003e1e-6)return i;const r=n.x-o.x;return Math.abs(r)\u003e1e-6?r:hU(t).localeCompare(hU(e))},_U=t=\u003e{const e=[...t].sort(yU),n=[];let o=e.shift();for(;o\u0026\u0026(n.push(o),0!==e.length);){const t=gU(o);let n=0,i=Number.POSITIVE_INFINITY;for(let o=0;o\u003ce.length;o++){const r=e[o],s=gU(r),a=(s.x-t.x)**2+(s.y-t.y)**2;a\u003ci-1e-9?(i=a,n=o):Math.abs(a-i)\u003c=1e-9\u0026\u0026yU(r,e[n])\u003c0\u0026\u0026(n=o)}o=e.splice(n,1)[0]}return n},bU=(t,e)=\u003e{const n=hU(t),o=e.findIndex(t=\u003ehU(t)===n);return o\u003e=0?`E${o+1}`:`E${uU(n).toString(36).slice(0,4)}`},xU=t=\u003et.flatMap(t=\u003e{const e=Ve(t);return[{obstacle:t,start:{x:e.minX,y:e.minY},end:{x:e.minX,y:e.maxY},expansionDirection:{x:-1,y:0}},{obstacle:t,start:{x:e.maxX,y:e.minY},end:{x:e.maxX,y:e.maxY},expansionDirection:{x:1,y:0}},{obstacle:t,start:{x:e.minX,y:e.minY},end:{x:e.maxX,y:e.minY},expansionDirection:{x:0,y:-1}},{obstacle:t,start:{x:e.minX,y:e.maxY},end:{x:e.maxX,y:e.maxY},expansionDirection:{x:0,y:1}}]}),vU=.001,SU=.001,IU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;meshIndex;allEdges=[];queueEdges=[];disconnectedEdges=[];currentEdge=null;lastSearchBounds=null;lastCandidateMeshNodes=[];lastMatchedMeshNode=null;_setup(){const t=Math.max(this.inputProblem.meshNodes.length,1);this.meshIndex=new Bt(t);for(const t of this.inputProblem.meshNodes){const e=Ve(t);this.meshIndex.add(e.minX,e.minY,e.maxX,e.maxY)}this.meshIndex.finish();const e=xU(this.inputProblem.unmarkedComponentObstacles);this.queueEdges=e,this.allEdges=_U(e),this.currentEdge=null,this.lastSearchBounds=null,this.lastCandidateMeshNodes=[],this.lastMatchedMeshNode=null}_step(){const t=this.queueEdges.shift();if(!t)return this.currentEdge=null,this.lastSearchBounds=null,this.lastCandidateMeshNodes=[],this.lastMatchedMeshNode=null,void(this.solved=!0);this.currentEdge=t,this.lastMatchedMeshNode=null;const e=Math.abs(t.start.x-t.end.x)\u003c=vU,n=e?{minX:t.start.x-SU,maxX:t.start.x+SU,minY:Math.min(t.start.y,t.end.y),maxY:Math.max(t.start.y,t.end.y)}:{minX:Math.min(t.start.x,t.end.x),maxX:Math.max(t.start.x,t.end.x),minY:t.start.y-SU,maxY:t.start.y+SU};this.lastSearchBounds=n;const o=this.meshIndex.search(n.minX,n.minY,n.maxX,n.maxY);this.lastCandidateMeshNodes=o.map(t=\u003ethis.inputProblem.meshNodes[t]);let i=!1;for(const n of o){const o=this.inputProblem.meshNodes[n],r=Ve(o);if(e){if(!(Math.min(r.maxY,Math.max(t.start.y,t.end.y))-Math.max(r.minY,Math.min(t.start.y,t.end.y))\u003evU))continue;if(-1===t.expansionDirection.x\u0026\u0026Math.abs(r.maxX-t.start.x)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}if(1===t.expansionDirection.x\u0026\u0026Math.abs(r.minX-t.start.x)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}continue}if(Math.min(r.maxX,Math.max(t.start.x,t.end.x))-Math.max(r.minX,Math.min(t.start.x,t.end.x))\u003evU){if(-1===t.expansionDirection.y\u0026\u0026Math.abs(r.maxY-t.start.y)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}if(1===t.expansionDirection.y\u0026\u0026Math.abs(r.minY-t.start.y)\u003c=vU){i=!0,this.lastMatchedMeshNode=o;break}}}i||this.disconnectedEdges.push(t)}getOutput(){return this.disconnectedEdges}visualize(){const t=this.disconnectedEdges,e=this.allEdges.length\u003e0?this.allEdges:[...t,...this.currentEdge?[this.currentEdge]:[]],n=this.currentEdge?pU(this.currentEdge,.88):\"rgba(40,40,40,0.4)\",o=this.inputProblem.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(120,120,120,0.18)\":\"rgba(120,120,120,0.08)\",stroke:t._containsObstacle?\"rgba(120,120,120,0.42)\":\"rgba(120,120,120,0.24)\"})),i=this.lastSearchBounds\u0026\u0026this.currentEdge?[{center:(r=this.lastSearchBounds,{x:(r.minX+r.maxX)/2,y:(r.minY+r.maxY)/2}),width:this.lastSearchBounds.maxX-this.lastSearchBounds.minX,height:this.lastSearchBounds.maxY-this.lastSearchBounds.minY,fill:pU(this.currentEdge,.1),stroke:pU(this.currentEdge,.36),label:[bU(this.currentEdge,e),\"search band\"].join(\" \")}]:[];var r;const s=this.lastCandidateMeshNodes.map(t=\u003e({...Dc(t,{rectMargin:.018}),fill:t===this.lastMatchedMeshNode?\"rgba(0,180,90,0.24)\":this.currentEdge?pU(this.currentEdge,.16):\"rgba(80,120,160,0.16)\",stroke:t===this.lastMatchedMeshNode?\"rgba(0,150,80,0.88)\":n,label:[t===this.lastMatchedMeshNode?\"matched\":\"candidate\",t.capacityMeshNodeId,`z:${t.availableZ.join(\",\")}`].join(\"\\n\")})),a=this.inputProblem.unmarkedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(160,160,160,0.10)\",stroke:\"rgba(160,160,160,0.40)\",label:t.obstacleId??t.componentId??\"obstacle\"})),c=t.map(t=\u003e({points:[t.start,t.end],strokeColor:pU(t,.14),strokeWidth:.01,strokeDash:\"5 4\",label:[bU(t,e),mU(t),\"disconnected\"].join(\" \")})),l=[],d=[];if(this.currentEdge){const t=gU(this.currentEdge);l.push({points:[this.currentEdge.start,this.currentEdge.end],strokeColor:pU(this.currentEdge,1),strokeWidth:.06,label:[bU(this.currentEdge,e),mU(this.currentEdge),\"checking\"].join(\" \")},{points:[t,{x:t.x+.16*this.currentEdge.expansionDirection.x,y:t.y+.16*this.currentEdge.expansionDirection.y}],strokeColor:pU(this.currentEdge,.82),strokeWidth:.02,strokeDash:\"3 3\"}),d.push({...t,color:pU(this.currentEdge,1),label:bU(this.currentEdge,e)})}return{rects:[...o,...i,...s,...a],lines:[...c,...l],points:d}}},CU=.001,PU=.001,MU=1e-6,NU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;meshIndex;meshBounds;expandedNodes=[];_setup(){const t=Math.max(this.inputProblem.meshNodes.length,1);this.meshIndex=new Bt(t);let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const t of this.inputProblem.meshNodes){const r=Ve(t);this.meshIndex.add(r.minX,r.minY,r.maxX,r.maxY),e=Math.min(e,r.minX),n=Math.max(n,r.maxX),o=Math.min(o,r.minY),i=Math.max(i,r.maxY)}this.meshIndex.finish(),this.meshBounds=this.inputProblem.meshNodes.length?{minX:e,maxX:n,minY:o,maxY:i}:{minX:0,maxX:0,minY:0,maxY:0}}getObstacleAvailableZ(t){return t.__zLayers??t.layers.map(t=\u003eko(t,this.inputProblem.layerCount))}getSharedOverlapArea(t,e){if(!t.availableZ.some(t=\u003ee.availableZ.includes(t)))return 0;const n=Ve(t),o=Ve(e),i=Math.min(n.maxX,o.maxX)-Math.max(n.minX,o.minX),r=Math.min(n.maxY,o.maxY)-Math.max(n.minY,o.minY);return i\u003c=MU||r\u003c=MU?0:i*r}getNodeObstacleOverlapArea(t,e){const n=this.getObstacleAvailableZ(e);if(!t.availableZ.some(t=\u003en.includes(t)))return 0;const o=Ve(t),i=Ve(e),r=Math.min(o.maxX,i.maxX)-Math.max(o.minX,i.minX),s=Math.min(o.maxY,i.maxY)-Math.max(o.minY,i.minY);return r\u003c=MU||s\u003c=MU?0:r*s}getClosestMeshNode(t,e){const n=Math.abs(t.start.x-t.end.x)\u003c=CU,o=this.getObstacleAvailableZ(t.obstacle),i=n?t.expansionDirection.x\u003c0?{minX:this.meshBounds.minX,maxX:t.start.x,minY:Math.min(t.start.y,t.end.y)-PU,maxY:Math.max(t.start.y,t.end.y)+PU}:{minX:t.start.x,maxX:this.meshBounds.maxX,minY:Math.min(t.start.y,t.end.y)-PU,maxY:Math.max(t.start.y,t.end.y)+PU}:t.expansionDirection.y\u003c0?{minX:Math.min(t.start.x,t.end.x)-PU,maxX:Math.max(t.start.x,t.end.x)+PU,minY:this.meshBounds.minY,maxY:t.start.y}:{minX:Math.min(t.start.x,t.end.x)-PU,maxX:Math.max(t.start.x,t.end.x)+PU,minY:t.start.y,maxY:this.meshBounds.maxY},r=this.meshIndex.search(i.minX,i.minY,i.maxX,i.maxY);let s=null,a=Number.POSITIVE_INFINITY;const c=[...r.map(t=\u003ethis.inputProblem.meshNodes[t]),...e];for(const e of c){if(e._containsObstacle)continue;if(!e.availableZ.some(t=\u003eo.includes(t)))continue;const i=Ve(e);if((n?Math.min(Math.max(t.start.y,t.end.y),i.maxY)-Math.max(Math.min(t.start.y,t.end.y),i.minY):Math.min(Math.max(t.start.x,t.end.x),i.maxX)-Math.max(Math.min(t.start.x,t.end.x),i.minX))\u003c=CU)continue;const r=n?t.expansionDirection.x\u003c0?t.start.x-i.maxX:i.minX-t.start.x:t.expansionDirection.y\u003c0?t.start.y-i.maxY:i.minY-t.start.y;r\u003cCU||(r\u003e=a||(a=r,s=e))}return s}createExpandedNode(t,e,n){const o=Ve(e),i=this.getObstacleAvailableZ(t.obstacle);if(Math.abs(t.start.x-t.end.x)\u003c=CU){const r=Math.max(Math.min(t.start.y,t.end.y),o.minY),s=Math.min(Math.max(t.start.y,t.end.y),o.maxY),a=t.expansionDirection.x\u003c0?o.maxX:t.start.x,c=t.expansionDirection.x\u003c0?t.start.x:o.minX;return c-a\u003c=CU||s-r\u003c=CU?null:{capacityMeshNodeId:`bga-gapfill-${n}-${t.obstacle.obstacleId??\"no-obstacle\"}-${e.capacityMeshNodeId}`,center:{x:(a+c)/2,y:(r+s)/2},width:c-a,height:s-r,layer:`z${i.join(\",\")}`,availableZ:i}}const r=Math.max(Math.min(t.start.x,t.end.x),o.minX),s=Math.min(Math.max(t.start.x,t.end.x),o.maxX),a=t.expansionDirection.y\u003c0?o.maxY:t.start.y,c=t.expansionDirection.y\u003c0?t.start.y:o.minY;return s-r\u003c=CU||c-a\u003c=CU?null:{capacityMeshNodeId:`bga-gapfill-${n}-${t.obstacle.obstacleId??\"no-obstacle\"}-${e.capacityMeshNodeId}`,center:{x:(r+s)/2,y:(a+c)/2},width:s-r,height:c-a,layer:`z${i.join(\",\")}`,availableZ:i}}overlapsExistingGeometry(t,e){for(const e of this.inputProblem.meshNodes)if(this.getSharedOverlapArea(t,e)\u003e0)return!0;for(const n of e)if(this.getSharedOverlapArea(t,n)\u003e0)return!0;for(const e of this.inputProblem.edgesWithObstacle)if(this.getNodeObstacleOverlapArea(t,e.obstacle)\u003e0)return!0;return!1}_step(){const t=[];for(const[e,n]of this.inputProblem.edgesWithObstacle.entries()){const o=this.getClosestMeshNode(n,t);if(!o)continue;const i=this.createExpandedNode(n,o,e);i\u0026\u0026(this.overlapsExistingGeometry(i,t)||t.push(i))}this.expandedNodes=t,this.solved=!0}getOutput(){return this.expandedNodes}visualize(){const t=this.inputProblem.edgesWithObstacle,e=_U(t);return{rects:[...this.inputProblem.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.16)\":\"rgba(0,120,255,0.08)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.35)\":\"rgba(0,120,255,0.28)\"})),...this.expandedNodes.map(n=\u003e{const o=fU(n),i=null===o?null:t[o]??null;return{...Dc(n,{rectMargin:.012,zOffset:.01}),fill:i?pU(i,.24):\"rgba(0,160,100,0.24)\",stroke:i?pU(i,.72):\"rgba(0,160,100,0.68)\",label:[i?bU(i,e):\"E?\",\"expanded\",n.capacityMeshNodeId,`z:${n.availableZ.join(\",\")}`].join(\"\\n\")}})],lines:[...this.inputProblem.edgesWithObstacle.map(t=\u003e({points:[t.start,t.end],strokeColor:pU(t,.9),strokeWidth:.034,label:[bU(t,e),mU(t)].join(\" \")})),...this.inputProblem.edgesWithObstacle.map(t=\u003e{const e=gU(t);return{points:[e,{x:e.x+.16*t.expansionDirection.x,y:e.y+.16*t.expansionDirection.y}],strokeColor:pU(t,.7),strokeWidth:.016,strokeDash:\"3 3\"}})],points:this.inputProblem.edgesWithObstacle.map(t=\u003e({...gU(t),color:pU(t,.95),label:bU(t,e)}))}}},wU=.001,TU=class extends Dt{constructor(t){super(t),this.inputProblem=t}inputProblem;detectEdgesNotConnectedToMesh;expandUnconnectedEdgesToMesh;pipelineDef=[Lt(\"detectEdgesNotConnectedToMesh\",IU,t=\u003e[t.inputProblem]),Lt(\"expandUnconnectedEdgesToMesh\",NU,t=\u003e[{meshNodes:t.inputProblem.meshNodes,edgesWithObstacle:t.detectEdgesNotConnectedToMesh.getOutput(),layerCount:t.inputProblem.layerCount}])];getOutput(){return[...this.inputProblem.meshNodes,...this.expandUnconnectedEdgesToMesh.getOutput()]}getExpandedNodes(){return this.expandUnconnectedEdgesToMesh.getOutput()}getObstacleLayer(t){return`z${(t.obstacle.__zLayers??t.obstacle.layers.map(t=\u003eko(t,this.inputProblem.layerCount))).join(\",\")}`}getObstacleRects(){return this.inputProblem.unmarkedComponentObstacles.map(t=\u003e{const e=t.__zLayers??t.layers.map(t=\u003eko(t,this.inputProblem.layerCount));return{center:t.center,width:t.width,height:t.height,fill:\"rgba(150,150,150,0.08)\",stroke:\"rgba(90,90,90,0.42)\",label:t.obstacleId??t.componentId??\"bga obstacle\",layer:`z${e.join(\",\")}`}})}getBaseMeshRects(){return this.inputProblem.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.025,zOffset:.01}),fill:t._containsObstacle?\"rgba(210,60,60,0.14)\":\"rgba(80,120,160,0.08)\",stroke:t._containsObstacle?\"rgba(190,40,40,0.42)\":\"rgba(80,120,160,0.28)\",label:`mesh ${t.capacityMeshNodeId}\\nz:${t.availableZ.join(\",\")}`}))}initialVisualize(){const t=xU(this.inputProblem.unmarkedComponentObstacles),e=_U(t),n=[...t.map(t=\u003e({points:[t.start,t.end],strokeColor:pU(t,.72),strokeWidth:.018,strokeDash:\"0.05 0.035\",layer:this.getObstacleLayer(t),label:[bU(t,e),mU(t)].join(\" \")})),...t.map(t=\u003e{const e=gU(t);return{points:[e,{x:e.x+.18*t.expansionDirection.x,y:e.y+.18*t.expansionDirection.y}],strokeColor:pU(t,.64),strokeWidth:.012,strokeDash:\"0.035 0.025\",layer:this.getObstacleLayer(t)}})];return{title:\"BGA GapFill: candidate obstacle edges\",rects:[...this.getBaseMeshRects(),...this.getObstacleRects()],lines:n}}finalVisualize(){const t=this.getStageOutput(\"detectEdgesNotConnectedToMesh\")??[],e=this.getStageOutput(\"expandUnconnectedEdgesToMesh\")??[],n=_U(xU(this.inputProblem.unmarkedComponentObstacles)),o=new Map;for(const t of e){const e=fU(t);null!==e\u0026\u0026o.set(e,t)}const i=e.map(e=\u003e{const o=fU(e),i=null===o?null:t[o]??null,r=i?(({expandedNode:t,edge:e,meshNodes:n})=\u003e{const o=Ve(t),i=Math.abs(e.start.x-e.end.x)\u003c=wU;return n.filter(n=\u003e{if(n._containsObstacle)return!1;if(!t.availableZ.some(t=\u003en.availableZ.includes(t)))return!1;const r=Ve(n);return i?!(Math.min(o.maxY,r.maxY)-Math.max(o.minY,r.minY)\u003c=wU)\u0026\u0026(e.expansionDirection.x\u003c0?Math.abs(r.maxX-o.minX)\u003c=wU:Math.abs(r.minX-o.maxX)\u003c=wU):!(Math.min(o.maxX,r.maxX)-Math.max(o.minX,r.minX)\u003c=wU)\u0026\u0026(e.expansionDirection.y\u003c0?Math.abs(r.maxY-o.minY)\u003c=wU:Math.abs(r.minY-o.maxY)\u003c=wU)}).map(t=\u003et.capacityMeshNodeId)})({expandedNode:e,edge:i,meshNodes:this.inputProblem.meshNodes}):[],s=i?bU(i,n):\"E?\",a=null===i?\"rgba(0,160,100,0.72)\":pU(i,.72);return{...Dc(e,{rectMargin:.012,zOffset:.01}),fill:null===i?\"rgba(0,160,100,0.24)\":pU(i,.16),stroke:a,label:[`${s} gap fill`,r.length\u003e0?`to ${r.join(\",\")}`:\"target mesh not adjacent\",`z:${e.availableZ.join(\",\")}`].join(\"\\n\")}}),r=t.map((t,e)=\u003e{const i=o.get(e);return{points:[t.start,t.end],strokeColor:i?pU(t,.68):\"rgba(80,80,80,0.14)\",strokeWidth:i?.026:.008,...i?{}:{strokeDash:\"5 4\"},layer:this.getObstacleLayer(t),label:[[bU(t,n),mU(t)].join(\" \"),i?\"filled\":\"no fill created\"].join(\"\\n\")}}),s=t.flatMap((t,e)=\u003e{const n=gU(t),i=o.get(e);return i?[{points:[n,i.center],strokeColor:pU(t,.42),strokeWidth:.012,strokeDash:\"0.035 0.025\",layer:this.getObstacleLayer(t)}]:[]}),a=t.flatMap((t,e)=\u003eo.has(e)?[{...gU(t),color:pU(t,.82),label:bU(t,n),layer:this.getObstacleLayer(t)}]:[]);return{title:\"BGA GapFill: disconnected edges and created mesh\",rects:[...this.getBaseMeshRects(),...this.getObstacleRects(),...i],lines:[...r,...s],points:a}}};function RU(t,e){const n=[];for(let o=0;o\u003ct.length;o++){const i=t[o];n.push(i);const r=t[o+1];if(void 0===r)continue;const s=Math.round((r-i)/e);if(!(s\u003c=1))for(let t=1;t\u003cs;t++){const e=t/s;n.push(Number((i+(r-i)*e).toFixed(6)))}}return n}var EU=.001;function AU(t){const e=[];for(let n=1;n\u003ct.length;n++){const o=t[n]-t[n-1];o\u003eEU\u0026\u0026e.push(o)}if(0===e.length)return null;const n=Math.min(...e),o=e.filter(t=\u003et\u003c=1.5*n).sort((t,e)=\u003et-e),i=Math.floor(o.length/2);return o.length%2==0?(o[i-1]+o[i])/2:o[i]}function OU(t){return[...new Set(t)].sort((t,e)=\u003et-e)}function kU(t){return Number(t.toFixed(6))}var LU=class t{static fromObstacles(e){if(0===e.length)return null;const n=OU(e.map(t=\u003et.center.x)),o=OU(e.map(t=\u003et.center.y)),i=AU(n),r=AU(o);return null===i||null===r?null:new t({obstacles:e,xCoordinates:RU(n,i),yCoordinates:RU(o,r),pitchX:i,pitchY:r})}xCoordinates;yCoordinates;pitchX;pitchY;originX;originY;rowCount;colCount;padWidth;padHeight;slots=new Map;constructor(t){this.xCoordinates=t.xCoordinates,this.yCoordinates=t.yCoordinates,this.pitchX=t.pitchX,this.pitchY=t.pitchY,this.originX=this.xCoordinates[0],this.originY=this.yCoordinates[0],this.colCount=this.xCoordinates.length,this.rowCount=this.yCoordinates.length,this.padWidth=t.obstacles[0].width,this.padHeight=t.obstacles[0].height;for(const e of t.obstacles){const t=this.getSlotForObstacle(e);t\u0026\u0026this.slots.set(this.getSlotKey(t.row,t.col),{...t,obstacle:e})}}getSlotKey(t,e){return`${t}:${e}`}getAxisIndex(t,e){let n=-1,o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ct.length;i++){const r=Math.abs(t[i]-e);r\u003co\u0026\u0026(o=r,n=i)}return o\u003c=EU?n:null}getAxisCoordinate(t,e){return t[e]}hasPadAt(t,e){return this.slots.has(this.getSlotKey(t,e))}getSlotForObstacle(t){const e=this.getAxisIndex(this.yCoordinates,t.center.y),n=this.getAxisIndex(this.xCoordinates,t.center.x);return null===e||null===n||e\u003c0||e\u003e=this.rowCount||n\u003c0||n\u003e=this.colCount?null:{row:e,col:n}}getSlotCenter(t,e){return{x:this.getAxisCoordinate(this.xCoordinates,e),y:this.getAxisCoordinate(this.yCoordinates,t)}}getHorizontalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t,e+1),i=Math.abs(o.x-n.x);return{orientation:\"horizontal\",row:t,col:e,center:{x:kU((n.x+o.x)/2),y:n.y},width:i-this.padWidth,height:this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)\u0026\u0026this.hasPadAt(t,e+1)}}getVerticalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t+1,e),i=Math.abs(o.y-n.y);return{orientation:\"vertical\",row:t,col:e,center:{x:n.x,y:kU((n.y+o.y)/2)},width:this.padWidth,height:i-this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)\u0026\u0026this.hasPadAt(t+1,e)}}getDiagonalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t+1,e+1),i=Math.abs(o.x-n.x),r=Math.abs(o.y-n.y);return{orientation:\"diagonal\",row:t,col:e,center:{x:kU((n.x+o.x)/2),y:kU((n.y+o.y)/2)},width:i-this.padWidth,height:r-this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)\u0026\u0026this.hasPadAt(t+1,e+1)}}getDiagonalGaps(){const t=[];for(let e=0;e\u003cthis.rowCount-1;e++)for(let n=0;n\u003cthis.colCount-1;n++)t.push(this.getDiagonalGap(e,n));return t.filter(t=\u003et.width\u003eEU\u0026\u0026t.height\u003eEU)}getAxisGaps(){const t=[];for(let e=0;e\u003cthis.rowCount;e++)for(let n=0;n\u003cthis.colCount-1;n++)t.push(this.getHorizontalGap(e,n));for(let e=0;e\u003cthis.rowCount-1;e++)for(let n=0;n\u003cthis.colCount;n++)t.push(this.getVerticalGap(e,n));return t.filter(t=\u003et.width\u003eEU\u0026\u0026t.height\u003eEU)}getMissingSlots(){const t=[];for(let e=0;e\u003cthis.rowCount;e++)for(let n=0;n\u003cthis.colCount;n++)this.hasPadAt(e,n)||t.push({row:e,col:n,center:this.getSlotCenter(e,n),width:this.padWidth,height:this.padHeight});return t}};function DU(t){if([t.point.pointId,t.point.pcb_port_id].filter(t=\u003e\"string\"==typeof t).some(e=\u003et.obstacle.connectedTo.includes(e)))return!0;if(0===t.obstacle.connectedTo.length)return!1;if(Be(t.point,t.obstacle)\u003e.001)return!1;const e=xo(t.point).map(e=\u003eko(e,t.layerCount)),n=t.obstacle.layers.map(e=\u003eko(e,t.layerCount));return e.some(t=\u003en.includes(t))}function zU(t){return t.obstacleId??[t.componentId??\"no-component\",t.center.x,t.center.y,t.width,t.height,t.layers.join(\",\")].join(\":\")}function FU({componentId:t,orientationKey:e,row:n,col:o,center:i,width:r,height:s}){return[\"cmn\",e,t,n,o,i.x,i.y,r,s].join(\"_\")}function BU(t){const{componentId:e,bgaGap:n,freeLayers:o,multiLayerThreshold:i}=t,r=n.width\u003ei\u0026\u0026n.height\u003ei;let s=\"d\";\"horizontal\"===n.orientation\u0026\u0026(s=\"h\"),\"vertical\"===n.orientation\u0026\u0026(s=\"v\");const a=FU({componentId:e,orientationKey:s,row:n.row,col:n.col,center:n.center,width:n.width,height:n.height});return\"diagonal\"===n.orientation\u0026\u0026r||!n.isBetweenTwoPads\u0026\u0026r?[{center:n.center,width:n.width,height:n.height,availableZ:[...o],capacityMeshNodeId:`${a}_all`,layer:\"\"}]:o.map(t=\u003e({center:n.center,width:n.width,height:n.height,availableZ:[t],capacityMeshNodeId:`${a}_${t}`,layer:\"\"}))}function jU(t){const{componentId:e,obstacle:n,freeLayers:o,layerCount:i}=t,r=n.layers.map(t=\u003eko(t,i)),s=o.filter(t=\u003e!r.includes(t)),a=zU(n);return s.map(t=\u003e({capacityMeshNodeId:`free-${e}-${a}-${t}`,center:n.center,width:n.width,height:n.height,layer:`z${t}`,availableZ:[t]}))}function $U(t,e,n){const o=e.layers.map(t=\u003eko(t,n.layerCount)),i=zU(e),r=function(t){for(const e of t.srj.connections)for(const n of e.pointsToConnect)if(DU({point:n,obstacle:t.obstacle,layerCount:t.srj.layerCount}))return e.__rootConnectionNames?.[0]??e.name}({obstacle:e,srj:n});return{capacityMeshNodeId:`obstacle-${t}-${i}-${o.join(\",\")}-${e.center.x}-${e.center.y}`,_containsObstacle:!0,...r?{_containsTarget:!0,_targetConnectionName:r}:{},center:e.center,width:e.width,height:e.height,layer:`z${o.join(\",\")}`,availableZ:o}}var YU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;componentObstacles=[];meshNodes=[];getConstructorParams(){return[this.inputProblem]}_step(){const{srj:t,componentBounds:e,componentId:n,markedComponentObstacles:o,unmarkedComponentObstacles:i}=this.inputProblem,r=t.obstacles.filter(t=\u003e!0===t.isCopperPour).filter(t=\u003eXe(Ve(t),e)).flatMap(e=\u003ee.layers.map(e=\u003eko(e,t.layerCount))),s=Array.from({length:t.layerCount},(t,e)=\u003ee).filter(t=\u003e!r.includes(t));if(this.componentObstacles=o,0===o.length||0===s.length)return void(this.solved=!0);const a=LU.fromObstacles(o);if(!a)return void(this.solved=!0);const c=a.getAxisGaps(),l=a.getDiagonalGaps(),d=a.getMissingSlots(),h=1.2*(this.inputProblem.viaDiameter??Yo(t).padDiameter);this.meshNodes=[...c.flatMap(t=\u003eBU({componentId:n,bgaGap:t,freeLayers:s,multiLayerThreshold:h})),...l.flatMap(t=\u003eBU({componentId:n,bgaGap:t,freeLayers:s,multiLayerThreshold:h})),...d.flatMap(t=\u003efunction(t){const{componentId:e,missingBgaSlot:n,freeLayers:o,multiLayerThreshold:i}=t,r=FU({componentId:e,orientationKey:\"missing\",row:n.row,col:n.col,center:n.center,width:n.width,height:n.height});return n.width\u003ei\u0026\u0026n.height\u003ei?[{center:n.center,width:n.width,height:n.height,availableZ:[...o],capacityMeshNodeId:`${r}_all`,layer:\"\"}]:o.map(t=\u003e({center:n.center,width:n.width,height:n.height,availableZ:[t],capacityMeshNodeId:`${r}_${t}`,layer:\"\"}))}({componentId:n,missingBgaSlot:t,freeLayers:s,multiLayerThreshold:h})),...o.flatMap(e=\u003e[...jU({componentId:n,obstacle:e,freeLayers:s,layerCount:t.layerCount}),$U(n,e,t)]),...i.flatMap(e=\u003e[$U(n,e,t)])],this.meshNodes=function(t){const e=new Map;return t.map(t=\u003e{const n=e.get(t.capacityMeshNodeId)??0;return e.set(t.capacityMeshNodeId,n+1),0===n?t:{...t,capacityMeshNodeId:`${t.capacityMeshNodeId}__dup${n}`}})}(this.meshNodes),this.solved=!0}getOutput(){return this.meshNodes}visualize(){return{rects:[{center:{x:(this.inputProblem.componentBounds.minX+this.inputProblem.componentBounds.maxX)/2,y:(this.inputProblem.componentBounds.minY+this.inputProblem.componentBounds.maxY)/2},width:this.inputProblem.componentBounds.maxX-this.inputProblem.componentBounds.minX,height:this.inputProblem.componentBounds.maxY-this.inputProblem.componentBounds.minY,fill:\"rgba(0,0,0,0)\",stroke:\"rgba(30,30,30,0.65)\",label:`component ${this.inputProblem.componentId}`},...this.inputProblem.markedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,0,0,0.18)\",stroke:\"rgba(255,0,0,0.52)\",label:`pad ${t.obstacleId??\"obstacle\"}`})),...this.inputProblem.unmarkedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.14)\",stroke:\"rgba(255,140,0,0.42)\",label:`foreign ${t.obstacleId??\"obstacle\"}`})),...this.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.14)\":t.capacityMeshNodeId.includes(\"missing\")?\"rgba(0,200,120,0.18)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.36)\":t.capacityMeshNodeId.includes(\"missing\")?\"rgba(0,200,120,0.52)\":\"rgba(0,120,255,0.38)\"}))]}}};function XU(t){return t.capacityMeshNodeId.startsWith(\"bga-gapfill-\")}function VU(t){return JSON.stringify({availableZ:[...t.availableZ].sort((t,e)=\u003et-e),_containsTarget:t._containsTarget??!1,_targetConnectionName:t._targetConnectionName??null,_depth:t._depth??null,_strawNode:t._strawNode??!1,_strawParentCapacityMeshNodeId:t._strawParentCapacityMeshNodeId??null,_qfpRegionType:t._qfpRegionType??null,_isNarrowQfpPadGap:t._isNarrowQfpPadGap??!1,_soicRegionType:t._soicRegionType??null,_offBoardConnectionId:t._offBoardConnectionId??null,_offboardNetName:t._offboardNetName??null,_isVirtualOffboard:t._isVirtualOffboard??!1,_containsObstacle:t._containsObstacle??!1})}function WU(t,e){const n=Ve(t);for(const o of e){if(!t.availableZ.some(t=\u003eo.availableZ.includes(t)))continue;const e=Ve(o);if(Xe(n,e))return!0}return!1}function HU(t){const e=t[0];if(!e)throw new Error(\"createMergedNode requires at least one source node\");let n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const e of t){const t=Ve(e);n=Math.min(n,t.minX),o=Math.max(o,t.maxX),i=Math.min(i,t.minY),r=Math.max(r,t.maxY)}return{...e,capacityMeshNodeId:`merge:${t.map(t=\u003et.capacityMeshNodeId).join(\":\")}`,center:{x:(n+o)/2,y:(i+r)/2},width:o-n,height:r-i}}function GU(t,e,n){return{center:t.center,width:t.width,height:t.height,fill:e,stroke:e,label:n}}var UU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;obstacleNodes=[];passthroughNodes=[];mergedNodes=[];pendingGroups=[];totalGroupCount=0;processedGroupCount=0;debugFilteredNodes=[];debugMergeEvents=[];currentGroupKey=null;currentRootNodeId=null;lastMergedNodeId=null;_setup(){this.obstacleNodes=this.inputProblem.meshNodes.filter(t=\u003e!0===t._containsObstacle),this.passthroughNodes=[],this.mergedNodes=[],this.pendingGroups=[],this.totalGroupCount=0,this.processedGroupCount=0,this.debugFilteredNodes=[],this.debugMergeEvents=[],this.currentGroupKey=null,this.currentRootNodeId=null,this.lastMergedNodeId=null;const t=new Map;for(const e of this.inputProblem.meshNodes){if(!0===e._containsObstacle){this.passthroughNodes.push(e),this.debugFilteredNodes.push({type:\"preserved-obstacle\",node:e,reason:\"contains-obstacle\"});continue}if(XU(e)){this.passthroughNodes.push(e);continue}if(e.availableZ.length!==this.inputProblem.layerCount){this.passthroughNodes.push(e);continue}let n=!1;for(let t=0;t\u003cthis.inputProblem.layerCount;t+=1)if(!e.availableZ.includes(t)){n=!0;break}if(n){this.passthroughNodes.push(e);continue}if(WU(e,this.obstacleNodes)){this.passthroughNodes.push(e),this.debugFilteredNodes.push({type:\"preserved-overlap\",node:e,reason:\"overlaps-obstacle\"});continue}const o=VU(e),i=t.get(o);i?i.push(e):t.set(o,[e])}for(const[e,n]of t.entries())n.length\u003c=1?this.passthroughNodes.push(...n):this.pendingGroups.push({groupKey:e,nodes:n});this.pendingGroups.sort((t,e)=\u003ee.nodes.length-t.nodes.length),this.totalGroupCount=this.pendingGroups.length,this.updateStats(\"setup\")}_step(){const t=this.pendingGroups.shift();if(!t)return this.currentGroupKey=null,this.currentRootNodeId=null,this.solved=!0,void this.updateStats(\"done\");const e=t.nodes[0];this.currentGroupKey=t.groupKey,this.currentRootNodeId=e?e.capacityMeshNodeId:null;const n=function(t){if(!t.nodes[0])return{outputNodes:[],mergeEvents:[]};let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.POSITIVE_INFINITY;for(const r of t.nodes){e=Math.min(e,r.width),n=Math.min(n,r.height);const t=Ve(r);o=Math.min(o,t.minX),i=Math.min(i,t.minY)}const r=new Map,s=[];for(const a of t.nodes){const t=Ve(a),c=Math.round((t.minX-o)/e),l=Math.round((t.minY-i)/n),d=Math.max(1,Math.round(a.width/e)),h=Math.max(1,Math.round(a.height/n));for(let t=0;t\u003ch;t+=1)for(let e=0;e\u003cd;e+=1)r.set(`${c+e},${l+t}`,a);s.push({col:c,row:l})}s.sort((t,e)=\u003et.row-e.row||t.col-e.col);const a=new Set,c=[],l=[];for(const o of s){const i=`${o.col},${o.row}`;if(a.has(i))continue;let s=0;for(;;){const t=`${o.col+s},${o.row}`;if(!r.has(t))break;if(a.has(t))break;s+=1}let d=s,h=1,u=1,p=1;for(let t=1;;t+=1){const i=o.row+t-1;let s=0;for(;s\u003cd;){const t=`${o.col+s},${i}`;if(!r.has(t))break;if(a.has(t))break;s+=1}if(0===s)break;d=Math.min(d,s);for(let o=d;o\u003e=1;o-=1){const i=o*e,r=t*n,s=Math.min(i,r);if((s\u003c=1e-6?Number.POSITIVE_INFINITY:Math.max(i,r)/s)\u003e4)continue;const a=o*t;a\u003ep\u0026\u0026(p=a,h=o,u=t);break}}const m=new Map;for(let t=0;t\u003cu;t+=1)for(let e=0;e\u003ch;e+=1){const n=`${o.col+e},${o.row+t}`,i=r.get(n);i\u0026\u0026(a.add(n),m.set(i.capacityMeshNodeId,i))}const g=[...m.values()];if(g.length\u003c=1){const t=g[0];t\u0026\u0026c.push(t);continue}const f=HU(g);c.push(f),l.push({type:\"merge\",groupKey:t.groupKey,sourceNodes:g,mergedNode:f})}return{outputNodes:c,mergeEvents:l}}(t);this.mergedNodes.push(...n.outputNodes),this.processedGroupCount+=1,this.debugMergeEvents.push(...n.mergeEvents);const o=n.mergeEvents[n.mergeEvents.length-1];o\u0026\u0026(this.lastMergedNodeId=o.mergedNode.capacityMeshNodeId),this.updateStats(n.mergeEvents.length\u003e0?\"merged-group\":\"passthrough-group\")}computeProgress(){return 0===this.totalGroupCount?1:this.processedGroupCount/this.totalGroupCount}updateStats(t){const e=new Set(this.debugMergeEvents.map(t=\u003et.groupKey)),n={lastAction:t,totalGroupCount:this.totalGroupCount,processedGroupCount:this.processedGroupCount,pendingGroupCount:this.pendingGroups.length,mergedNodeCount:this.mergedNodes.length,passthroughNodeCount:this.passthroughNodes.length,gapFillNodeCount:this.passthroughNodes.filter(XU).length,preservedObstacleNodeCount:this.debugFilteredNodes.filter(t=\u003e\"preserved-obstacle\"===t.type).length,preservedOverlapNodeCount:this.debugFilteredNodes.filter(t=\u003e\"preserved-overlap\"===t.type).length,mergeCount:this.debugMergeEvents.length,mergedGroupCount:e.size,currentGroupKey:this.currentGroupKey,currentRootNodeId:this.currentRootNodeId,lastMergedNodeId:this.lastMergedNodeId};this.stats=n}getConstructorParams(){return[this.inputProblem]}getOutput(){return[...this.mergedNodes,...this.passthroughNodes]}visualize(){const t=this.getOutput(),e=this.currentRootNodeId?t.find(t=\u003et.capacityMeshNodeId===this.currentRootNodeId)??null:null,n=this.lastMergedNodeId?t.find(t=\u003et.capacityMeshNodeId===this.lastMergedNodeId)??null:null;return{rects:[...this.debugFilteredNodes.map(t=\u003eGU(t.node,\"preserved-obstacle\"===t.type?\"rgba(255,64,64,0.35)\":\"rgba(255,160,64,0.35)\",t.reason)),...this.passthroughNodes.map(t=\u003eGU(t,t._containsObstacle?\"rgba(255,0,0,0.35)\":XU(t)?\"rgba(0,120,255,0.18)\":\"rgba(160,160,160,0.12)\")),...this.mergedNodes.map(t=\u003eGU(t,\"rgba(120,120,120,0.14)\")),...e?[GU(e,\"rgba(255,215,0,0.35)\",\"active-group\")]:[],...n?[GU(n,\"rgba(0,200,120,0.28)\",\"merged\")]:[]]}}},ZU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;obstacleQueue=[];obstacleQueueIndex=0;meshNodes=[];_setup(){this.obstacleQueue=this.inputProblem.obstacles,this.obstacleQueueIndex=0,this.meshNodes=[...this.inputProblem.meshNodes]}_step(){if(this.obstacleQueueIndex\u003e=this.obstacleQueue.length)return void(this.solved=!0);const t=this.obstacleQueue[this.obstacleQueueIndex],e=t.layers.map(t=\u003eko(t,this.inputProblem.layerCount)),n=[];for(const o of this.meshNodes){if(o._containsObstacle){n.push(o);continue}if(!e.some(t=\u003eo.availableZ.includes(t))){n.push(o);continue}if(!Xe(Ve(o),Ve(t))){n.push(o);continue}if(1===o.availableZ.length)continue;const i=o.availableZ.filter(t=\u003e!e.includes(t));for(const t of i){const e={...o,capacityMeshNodeId:`${o.capacityMeshNodeId}:z${t}`,availableZ:[t],layer:`z${t}`};n.push(e)}}this.meshNodes=n,this.obstacleQueueIndex+=1,this.stats={obstaclesProcessed:this.obstacleQueueIndex,obstacleCount:this.obstacleQueue.length,meshNodeCount:this.meshNodes.length}}computeProgress(){return 0===this.obstacleQueue.length?1:this.obstacleQueueIndex/this.obstacleQueue.length}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.meshNodes}visualize(){const t=this.obstacleQueueIndex\u003cthis.obstacleQueue.length?this.obstacleQueue[this.obstacleQueueIndex]??null:null,e=this.obstacleQueue.slice(0,this.obstacleQueueIndex),n=t?this.obstacleQueue.slice(this.obstacleQueueIndex+1):[];return{rects:[...e.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(160,160,160,0.10)\",stroke:\"rgba(160,160,160,0.35)\",label:`processed ${t.obstacleId??\"obstacle\"}`})),...t?[{center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.22)\",stroke:\"rgba(255,140,0,0.75)\",label:`active ${t.obstacleId??\"obstacle\"}`}]:[],...n.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,0,0,0.05)\",stroke:\"rgba(255,0,0,0.22)\",label:`pending ${t.obstacleId??\"obstacle\"}`})),...this.meshNodes.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.18)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.45)\":\"rgba(0,120,255,0.45)\"}))]}}};dU.register(class extends Dt{constructor(t){super(t),this.inputProblem=t}inputProblem;static componentKind=\"bga\";initialTopologySolver;removeMeshNodeOverlappingWithUnmarkedObstacle;gapfillDueToNodeRemoval;mergeMeshNodes;markedComponentObstacles=[];unmarkedComponentObstacles=[];pipelineDef=[Lt(\"initialTopologySolver\",YU,t=\u003e[{srj:t.inputProblem.inputSrj,componentBounds:t.inputProblem.detectedComponent.bounds,componentId:t.inputProblem.detectedComponent.componentId,markedComponentObstacles:t.markedComponentObstacles,unmarkedComponentObstacles:t.unmarkedComponentObstacles,viaDiameter:t.inputProblem.viaDiameter}]),Lt(\"removeMeshNodeOverlappingWithUnmarkedObstacle\",ZU,t=\u003e[{meshNodes:t.initialTopologySolver.getOutput(),obstacles:t.unmarkedComponentObstacles,layerCount:t.inputProblem.inputSrj.layerCount}]),Lt(\"gapfillDueToNodeRemoval\",TU,t=\u003e[{meshNodes:t.removeMeshNodeOverlappingWithUnmarkedObstacle.getOutput(),unmarkedComponentObstacles:t.unmarkedComponentObstacles,layerCount:t.inputProblem.inputSrj.layerCount}]),Lt(\"mergeMeshNodes\",UU,t=\u003e[{meshNodes:t.gapfillDueToNodeRemoval.getOutput(),layerCount:t.inputProblem.inputSrj.layerCount}])];_setup(){const t=this.inputProblem.detectedComponent.bounds,e=this.inputProblem.detectedComponent.componentId,n=[],o=[];for(const i of this.inputProblem.inputSrj.obstacles){const r=Ve(i);Xe(t,r)\u0026\u0026(i.componentId!==e?o.push(i):n.push(i))}this.markedComponentObstacles=n,this.unmarkedComponentObstacles=o}getConstructorParams(){return[this.inputProblem]}getOutput(){return{routingRegions:this.mergeMeshNodes?.getOutput()??this.gapfillDueToNodeRemoval?.getOutput()??this.removeMeshNodeOverlappingWithUnmarkedObstacle?.getOutput()??[]}}initialVisualize(){return{rects:[{center:{x:(this.inputProblem.detectedComponent.bounds.minX+this.inputProblem.detectedComponent.bounds.maxX)/2,y:(this.inputProblem.detectedComponent.bounds.minY+this.inputProblem.detectedComponent.bounds.maxY)/2},width:this.inputProblem.detectedComponent.bounds.maxX-this.inputProblem.detectedComponent.bounds.minX,height:this.inputProblem.detectedComponent.bounds.maxY-this.inputProblem.detectedComponent.bounds.minY,fill:\"rgba(0,0,0,0)\",stroke:\"rgba(30,30,30,0.65)\",label:`bga ${this.inputProblem.detectedComponent.componentId}`},...this.markedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,0,0,0.18)\",stroke:\"rgba(255,0,0,0.52)\",label:`pad ${t.obstacleId??\"obstacle\"}`})),...this.unmarkedComponentObstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.14)\",stroke:\"rgba(255,140,0,0.42)\",label:`foreign ${t.obstacleId??\"obstacle\"}`}))]}}finalVisualize(){return{rects:this.getOutput().routingRegions.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.16)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.36)\":\"rgba(0,120,255,0.42)\"}))}}});var qU=1e-6;function JU(t,e){return t.__zLayers\u0026\u0026t.__zLayers.length\u003e0?Lo(t.__zLayers,e):Do(t.layers,e)}function KU(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(let t=1;t\u003ce.length;t++){const o=e[t]-e[t-1];o\u003eqU\u0026\u0026n.push(o)}const o=n.length\u003e0?Math.max(qU,Math.min(...n)/4):.001,i=[];for(const t of e){const e=i[i.length-1];(void 0===e||Math.abs(t-e)\u003eo)\u0026\u0026i.push(t)}return i}function QU(t){return Array.from({length:Math.max(0,t)},(t,e)=\u003ee)}var tZ=1e-6;function eZ(t){return t.maxX-t.minX\u003etZ\u0026\u0026t.maxY-t.minY\u003etZ}function nZ(t){return function(t){const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return e\u003c=0?0:n/e}(t)\u003e=1.5}function oZ(t,e){const n=[{side:\"top\",distance:Math.abs(t.center.y-e.minY)},{side:\"right\",distance:Math.abs(e.maxX-t.center.x)},{side:\"bottom\",distance:Math.abs(e.maxY-t.center.y)},{side:\"left\",distance:Math.abs(t.center.x-e.minX)}];return n.sort((t,e)=\u003et.distance-e.distance),n[0].side}function iZ(t,e){return t.map((t,n)=\u003e({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e)}))}function rZ(t,e){return t.map((t,n)=\u003e({key:`thermal-pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e)}))}function sZ(t,e){return!!eZ(t)\u0026\u0026Math.min(t.maxX-t.minX,t.maxY-t.minY)\u003c=e}function aZ({side:t,sideObstacles:e,bounds:n,innerBounds:o,narrowThreshold:i}){const r=[];for(let s=0;s\u003ce.length-1;s++){const a=Ee(e[s]),c=Ee(e[s+1]);let l;l=\"top\"===t?{minX:a.maxX,maxX:c.minX,minY:n.minY,maxY:o.minY}:\"right\"===t?{minX:o.maxX,maxX:n.maxX,minY:a.maxY,maxY:c.minY}:\"bottom\"===t?{minX:a.maxX,maxX:c.minX,minY:o.maxY,maxY:n.maxY}:{minX:n.minX,maxX:o.minX,minY:a.maxY,maxY:c.minY},r.push({key:`${t}-gap-${s}`,bounds:l,regionType:\"pad-gap\",isNarrowPadGap:sZ(l,i)})}return r}function cZ({side:t,sideObstacles:e,thermalPadBounds:n,narrowThreshold:o}){const i=[];for(let r=0;r\u003ce.length;r++){const s=Ee(e[r]),a=e[r-1]?Ee(e[r-1]):null,c=e[r+1]?Ee(e[r+1]):null;let l;l=\"top\"===t?{minX:a?(a.maxX+s.minX)/2:s.minX,maxX:c?(s.maxX+c.minX)/2:s.maxX,minY:s.maxY,maxY:n.minY}:\"right\"===t?{minX:n.maxX,maxX:s.minX,minY:a?(a.maxY+s.minY)/2:s.minY,maxY:c?(s.maxY+c.minY)/2:s.maxY}:\"bottom\"===t?{minX:a?(a.maxX+s.minX)/2:s.minX,maxX:c?(s.maxX+c.minX)/2:s.maxX,minY:n.maxY,maxY:s.minY}:{minX:s.maxX,maxX:n.minX,minY:a?(a.maxY+s.minY)/2:s.minY,maxY:c?(s.maxY+c.minY)/2:s.maxY},i.push({key:`inner-${t}-pad-${r}`,bounds:l,regionType:\"pad-gap\",isNarrowPadGap:sZ(l,o)})}return i}function lZ({bounds:t,innerBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:\"corner-nw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-top\",regionType:\"corner\",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:\"corner-ne-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-top\",regionType:\"corner\",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:\"corner-se-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-se-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:\"corner-se-bottom\",regionType:\"corner\",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-bottom\",regionType:\"corner\",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}function dZ({innerBounds:t,thermalPadBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:\"inner-corner-nw-core\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-nw-top\",regionType:\"corner\",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-nw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:\"inner-corner-ne-core\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-ne-top\",regionType:\"corner\",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:\"inner-corner-ne-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:\"inner-corner-se-core\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-se-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:\"inner-corner-se-bottom\",regionType:\"corner\",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-sw-core\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-sw-bottom\",regionType:\"corner\",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"inner-corner-sw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind=\"qfp_thermalpad\";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=\u003et.componentId===o),s=r.length\u003e0?r:e,{padRingObstacles:a,thermalPadObstacles:c}=function(t){return{padRingObstacles:t.filter(nZ),thermalPadObstacles:t.filter(t=\u003e!nZ(t))}}(s),l=function(t,e){const n={top:[],right:[],bottom:[],left:[]};for(const o of t)n[oZ(o,e)].push(o);return n.top.sort((t,e)=\u003et.center.x-e.center.x),n.bottom.sort((t,e)=\u003et.center.x-e.center.x),n.left.sort((t,e)=\u003et.center.y-e.center.y),n.right.sort((t,e)=\u003et.center.y-e.center.y),n}(a,n),d=function({bounds:t,sideGroups:e}){return{minX:e.left.length\u003e0?Math.max(...e.left.map(t=\u003eEe(t).maxX)):t.minX,maxX:e.right.length\u003e0?Math.min(...e.right.map(t=\u003eEe(t).minX)):t.maxX,minY:e.top.length\u003e0?Math.max(...e.top.map(t=\u003eEe(t).maxY)):t.minY,maxY:e.bottom.length\u003e0?Math.min(...e.bottom.map(t=\u003eEe(t).minY)):t.maxY}}({bounds:n,sideGroups:l}),h=function(t){return 0===t.length?null:t.reduce((t,e)=\u003e{const n=Ee(e);return{minX:Math.min(t.minX,n.minX),maxX:Math.max(t.maxX,n.maxX),minY:Math.min(t.minY,n.minY),maxY:Math.max(t.maxY,n.maxY)}},Ee(t[0]))}(c);if(!h)return this.failed=!0,void(this.error=\"QfpThermalPadTopologyGeneratorSolver requires a thermal pad\");const u=o,p=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,m=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,g=p+2*m,f=this.inputProblem.inputSrj.minTraceWidth+2*m,y=[...iZ(a,t),...rZ(c,t),...aZ({side:\"top\",sideObstacles:l.top,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:\"right\",sideObstacles:l.right,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:\"bottom\",sideObstacles:l.bottom,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:\"left\",sideObstacles:l.left,bounds:n,innerBounds:d,narrowThreshold:f}),...cZ({side:\"top\",sideObstacles:l.top,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:\"right\",sideObstacles:l.right,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:\"bottom\",sideObstacles:l.bottom,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:\"left\",sideObstacles:l.left,thermalPadBounds:h,narrowThreshold:f}),...dZ({innerBounds:d,thermalPadBounds:h,sideGroups:l}),...lZ({bounds:n,innerBounds:d,sideGroups:l})].flatMap(t=\u003efunction({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,isNarrowPadGap:r=!1,obstacleZ:s=[]}){if(!eZ(e))return[];const a=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),c=Math.min(a.width,a.height)\u003eo,l=c?[{availableZ:n.filter(t=\u003e!s.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=\u003es.includes(t)),containsObstacle:!0}].filter(t=\u003et.availableZ.length\u003e0):n.map(t=\u003e({availableZ:[t],containsObstacle:s.includes(t)}));return l.map(e=\u003e({capacityMeshNodeId:1===l.length?t:c?`${t}:${e.containsObstacle?\"obstacle\":\"free\"}`:`${t}:z${e.availableZ[0]}`,center:a.center,width:a.width,height:a.height,layer:`z${e.availableZ.join(\",\")}`,availableZ:e.availableZ,_qfpRegionType:i,_isNarrowQfpPadGap:r,_containsObstacle:e.containsObstacle}))}({nodeId:`qfp_thermalpad:${u}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:g,regionType:t.regionType,isNarrowPadGap:t.isNarrowPadGap,obstacleZ:t.obstacleZ}));this.output={routingRegions:y},this.stats={componentId:o,layerCount:t,viaDiameter:p,obstacleMargin:m,multiLayerThreshold:g,narrowPadGapThreshold:f,thermalPadCount:c.length,perimeterPadCount:a.length,innerCornerRectCount:y.filter(t=\u003et.capacityMeshNodeId.includes(\":inner-corner-\")).length,narrowPadGapNodeCount:y.filter(t=\u003et._isNarrowQfpPadGap).length,topPadCount:l.top.length,rightPadCount:l.right.length,bottomPadCount:l.bottom.length,leftPadCount:l.left.length,multiLayerNodeCount:y.filter(t=\u003et.availableZ.length\u003e1).length,totalMeshNodeCount:y.length},this.solved=!0}getOutput(){if(!this.output)throw new Error(\"QfpThermalPadTopologyGeneratorSolver has not solved yet\");return this.output}});var hZ=1e-6;function uZ(t){return t.maxX-t.minX\u003ehZ\u0026\u0026t.maxY-t.minY\u003ehZ}function pZ(t,e){const n=[{side:\"top\",distance:Math.abs(t.center.y-e.minY)},{side:\"right\",distance:Math.abs(e.maxX-t.center.x)},{side:\"bottom\",distance:Math.abs(e.maxY-t.center.y)},{side:\"left\",distance:Math.abs(t.center.x-e.minX)}];return n.sort((t,e)=\u003et.distance-e.distance),n[0].side}function mZ(t,e){return t.map((t,n)=\u003e({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e),connectedTo:[...t.connectedTo]}))}function gZ(t,e){return!!uZ(t)\u0026\u0026Math.min(t.maxX-t.minX,t.maxY-t.minY)\u003c=e}function fZ({side:t,sideObstacles:e,bounds:n,centralBounds:o,narrowThreshold:i}){const r=[];for(let s=0;s\u003ce.length-1;s++){const a=Ee(e[s]),c=Ee(e[s+1]);let l;l=\"top\"===t?{minX:a.maxX,maxX:c.minX,minY:n.minY,maxY:o.minY}:\"right\"===t?{minX:o.maxX,maxX:n.maxX,minY:a.maxY,maxY:c.minY}:\"bottom\"===t?{minX:a.maxX,maxX:c.minX,minY:o.maxY,maxY:n.maxY}:{minX:n.minX,maxX:o.minX,minY:a.maxY,maxY:c.minY},r.push({key:`${t}-gap-${s}`,bounds:l,regionType:\"pad-gap\",isNarrowPadGap:gZ(l,i)})}return r}function yZ({bounds:t,centralBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:\"corner-nw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-top\",regionType:\"corner\",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:\"corner-nw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:\"corner-ne-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-top\",regionType:\"corner\",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:\"corner-ne-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:\"corner-se-outer\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-se-right\",regionType:\"corner\",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:\"corner-se-bottom\",regionType:\"corner\",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-outer\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-bottom\",regionType:\"corner\",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:\"corner-sw-left\",regionType:\"corner\",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind=\"qfp\";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=\u003et.componentId===o),s=r.length\u003e0?r:e,a=function(t,e){const n={top:[],right:[],bottom:[],left:[]};for(const o of t)n[pZ(o,e)].push(o);return n.top.sort((t,e)=\u003et.center.x-e.center.x),n.bottom.sort((t,e)=\u003et.center.x-e.center.x),n.left.sort((t,e)=\u003et.center.y-e.center.y),n.right.sort((t,e)=\u003et.center.y-e.center.y),n}(s,n),c=function({bounds:t,sideGroups:e}){return{minX:e.left.length\u003e0?Math.max(...e.left.map(t=\u003eEe(t).maxX)):t.minX,maxX:e.right.length\u003e0?Math.min(...e.right.map(t=\u003eEe(t).minX)):t.maxX,minY:e.top.length\u003e0?Math.max(...e.top.map(t=\u003eEe(t).maxY)):t.minY,maxY:e.bottom.length\u003e0?Math.min(...e.bottom.map(t=\u003eEe(t).minY)):t.maxY}}({bounds:n,sideGroups:a}),l=o,d=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,h=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,u=d+2*h,p=this.inputProblem.inputSrj.minTraceWidth+2*h,m=[{key:\"center\",bounds:c,regionType:\"center\"},...mZ(s,t),...fZ({side:\"top\",sideObstacles:a.top,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:\"right\",sideObstacles:a.right,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:\"bottom\",sideObstacles:a.bottom,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:\"left\",sideObstacles:a.left,bounds:n,centralBounds:c,narrowThreshold:p}),...yZ({bounds:n,centralBounds:c,sideGroups:a})].flatMap(t=\u003efunction({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,isNarrowPadGap:r=!1,obstacleZ:s=[],connectedTo:a}){if(!uZ(e))return[];const c=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),l=Math.min(c.width,c.height)\u003eo,d=l?[{availableZ:n.filter(t=\u003e!s.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=\u003es.includes(t)),containsObstacle:!0}].filter(t=\u003et.availableZ.length\u003e0):n.map(t=\u003e({availableZ:[t],containsObstacle:s.includes(t)}));return d.map(e=\u003e({capacityMeshNodeId:1===d.length?t:l?`${t}:${e.containsObstacle?\"obstacle\":\"free\"}`:`${t}:z${e.availableZ[0]}`,center:c.center,width:c.width,height:c.height,layer:`z${e.availableZ.join(\",\")}`,availableZ:e.availableZ,_qfpRegionType:i,_isNarrowQfpPadGap:r,_containsObstacle:e.containsObstacle,_connectedTo:e.containsObstacle?a:void 0}))}({nodeId:`qfp:${l}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:u,regionType:t.regionType,isNarrowPadGap:t.isNarrowPadGap,obstacleZ:t.obstacleZ,connectedTo:t.connectedTo}));this.output={routingRegions:m},this.stats={componentId:o,layerCount:t,viaDiameter:d,obstacleMargin:h,multiLayerThreshold:u,narrowPadGapThreshold:p,narrowPadGapNodeCount:m.filter(t=\u003et._isNarrowQfpPadGap).length,topPadCount:a.top.length,rightPadCount:a.right.length,bottomPadCount:a.bottom.length,leftPadCount:a.left.length,multiLayerNodeCount:m.filter(t=\u003et.availableZ.length\u003e1).length,totalMeshNodeCount:m.length},this.solved=!0}getOutput(){if(!this.output)throw new Error(\"QfpTopologyGeneratorSolver has not solved yet\");return this.output}});var _Z=1e-6;function bZ({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,obstacleZ:r=[],connectedTo:s}){if(!function(t){return t.maxX-t.minX\u003e_Z\u0026\u0026t.maxY-t.minY\u003e_Z}(e))return[];const a=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),c=Math.min(a.width,a.height)\u003eo,l=c?[{availableZ:n.filter(t=\u003e!r.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=\u003er.includes(t)),containsObstacle:!0}].filter(t=\u003et.availableZ.length\u003e0):n.map(t=\u003e({availableZ:[t],containsObstacle:r.includes(t)}));return l.map(e=\u003e({capacityMeshNodeId:1===l.length?t:c?`${t}:${e.containsObstacle?\"obstacle\":\"free\"}`:`${t}:z${e.availableZ[0]}`,center:a.center,width:a.width,height:a.height,layer:`z${e.availableZ.join(\",\")}`,availableZ:e.availableZ,_soicRegionType:i,_containsObstacle:e.containsObstacle,_connectedTo:e.containsObstacle?s:void 0}))}function xZ(t,e){let n=0,o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ce.length;i++){const r=Math.abs(t-e[i]);r\u003co\u0026\u0026(n=i,o=r)}return n}function vZ(t,e){return t.map((t,n)=\u003e({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:\"pad\",obstacleZ:JU(t,e),connectedTo:[...t.connectedTo]}))}function SZ(t,e){if(t.componentId!==e.componentId)return!1;const{bounds:n}=e;return t.center.x\u003e=n.minX\u0026\u0026t.center.x\u003c=n.maxX\u0026\u0026t.center.y\u003e=n.minY\u0026\u0026t.center.y\u003c=n.maxY}function IZ({detectedComponent:t,inputSrj:e}){const n=e.obstacles.filter(e=\u003eSZ(e,t)),o=Array.from({length:e.layerCount},(t,e)=\u003ee),i=o.map(t=\u003evo(t,e.layerCount)),r=Array.from(new Set(n.flatMap(t=\u003et.connectedTo))),{bounds:s}=t;return{obstacleId:`${t.componentId}_component_bounds`,componentId:t.componentId,type:\"rect\",layers:i,__zLayers:o,center:{x:(s.minX+s.maxX)/2,y:(s.minY+s.maxY)/2},width:s.maxX-s.minX,height:s.maxY-s.minY,connectedTo:r}}function CZ(t){if(0===t.length)return{minX:0,maxX:0,minY:0,maxY:0};let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t){const t=Ee(r);e=Math.min(e,t.minX),n=Math.max(n,t.maxX),o=Math.min(o,t.minY),i=Math.max(i,t.maxY)}return{minX:e,maxX:n,minY:o,maxY:i}}function PZ(t){const e=t.componentDetectionOutput??[],n=function({detectedComponents:t,inputSrj:e}){return t.map(t=\u003e{const n=e.obstacles.filter(e=\u003eSZ(e,t));return{componentId:t.componentId,componentKind:t.componentKind,memberObstacleIds:n.map((e,n)=\u003ee.obstacleId??`${t.componentId}:member:${n}`),memberObstacles:n,replacementObstacle:IZ({detectedComponent:t,inputSrj:e})}})}({detectedComponents:e,inputSrj:t.inputSrj}),o=t.globalNoConnectionSrj??(e.length\u003e0?function({detectedComponents:t,inputSrj:e}){return{...structuredClone(e),obstacles:[...e.obstacles.filter(e=\u003e!t.some(t=\u003eSZ(e,t))),...t.map(t=\u003eIZ({detectedComponent:t,inputSrj:e}))]}}({detectedComponents:e,inputSrj:t.inputSrj}):t.inputSrj)??t.brokenSrj?.componentsAsObstaclesSrj,i=t.components??n??t.brokenSrj?.components??[];if(!o)throw new Error(\"MultiGraphTopologyPlannerSolver requires globalNoConnectionSrj or detected components\");return{globalNoConnectionSrj:o,components:i}}function MZ({rects:t,components:e}){return t\u0026\u00260!==e.length?t.filter(t=\u003e!function(t){return\"string\"==typeof t.label\u0026\u0026t.label.startsWith(\"node \")}(t)||!e.some(e=\u003efunction({rect:t,obstacle:e}){if(!t.center||void 0===t.width||void 0===t.height)return!1;const n=1e-9,o=Ve({center:t.center,width:t.width,height:t.height}),i=Ve({center:e.center,width:e.width,height:e.height});return NZ({bounds:o,outerBounds:i,epsilon:n})}({rect:t,obstacle:e.replacementObstacle}))):t}function NZ({bounds:t,outerBounds:e,epsilon:n}){return t.minX\u003e=e.minX-n\u0026\u0026t.maxX\u003c=e.maxX+n\u0026\u0026t.minY\u003e=e.minY-n\u0026\u0026t.maxY\u003c=e.maxY+n}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind=\"soic\";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=\u003et.componentId===o),s=r.length\u003e0?r:e,a=function(t){const e=KU(t.map(t=\u003et.center.y)).length;return 2===KU(t.map(t=\u003et.center.x)).length\u0026\u00262!==e?\"vertical-columns\":\"horizontal-rows\"}(s),c=function({obstacles:t,orientation:e}){const n={left:[],right:[],top:[],bottom:[]};if(\"vertical-columns\"===e){const e=KU(t.map(t=\u003et.center.x));for(const o of t)n[0===xZ(o.center.x,e)?\"left\":\"right\"].push(o);return n.left.sort((t,e)=\u003et.center.y-e.center.y),n.right.sort((t,e)=\u003et.center.y-e.center.y),n}const o=KU(t.map(t=\u003et.center.y));for(const e of t)n[0===xZ(e.center.y,o)?\"top\":\"bottom\"].push(e);return n.top.sort((t,e)=\u003et.center.x-e.center.x),n.bottom.sort((t,e)=\u003et.center.x-e.center.x),n}({obstacles:s,orientation:a}),l=function({bounds:t,orientation:e,sideGroups:n}){return\"vertical-columns\"===e?{minX:Math.max(...n.left.map(t=\u003eEe(t).maxX)),maxX:Math.min(...n.right.map(t=\u003eEe(t).minX)),minY:t.minY,maxY:t.maxY}:{minX:t.minX,maxX:t.maxX,minY:Math.max(...n.top.map(t=\u003eEe(t).maxY)),maxY:Math.min(...n.bottom.map(t=\u003eEe(t).minY))}}({bounds:n,orientation:a,sideGroups:c}),d=o,h=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,u=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,p=2*(h+u),m=\"vertical-columns\"===a?[\"left\",\"right\"]:[\"top\",\"bottom\"],g=[{key:\"center\",bounds:l,regionType:\"center\"},...vZ(s,t),...m.flatMap(t=\u003efunction({side:t,sideObstacles:e,bounds:n,centralBounds:o}){const i=[];for(let r=0;r\u003ce.length-1;r++){const s=Ee(e[r]),a=Ee(e[r+1]);let c;c=\"left\"===t?{minX:n.minX,maxX:o.minX,minY:s.maxY,maxY:a.minY}:\"right\"===t?{minX:o.maxX,maxX:n.maxX,minY:s.maxY,maxY:a.minY}:\"top\"===t?{minX:s.maxX,maxX:a.minX,minY:n.minY,maxY:o.minY}:{minX:s.maxX,maxX:a.minX,minY:o.maxY,maxY:n.maxY},i.push({key:`${t}-gap-${r}`,bounds:c,regionType:\"pad-gap\"})}return i}({side:t,sideObstacles:c[t],bounds:n,centralBounds:l}))],f=g.flatMap(t=\u003ebZ({nodeId:`soic:${d}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:p,regionType:t.regionType,obstacleZ:t.obstacleZ,connectedTo:t.connectedTo}));this.output={routingRegions:f},this.stats={componentId:o,layerCount:t,orientation:a,viaDiameter:h,obstacleMargin:u,multiLayerThreshold:p,firstSidePadCount:c[m[0]].length,secondSidePadCount:c[m[1]].length,multiLayerNodeCount:f.filter(t=\u003et.availableZ.length\u003e1).length,totalMeshNodeCount:f.length},this.solved=!0}getOutput(){if(!this.output)throw new Error(\"SoicTopologyGeneratorSolver has not solved yet\");return this.output}});var wZ=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;activeSubSolver=null;currentIndex=0;componentMeshNodes=[];getConstructorParams(){return[this.inputProblem]}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.failed)return this.error=this.activeSubSolver.error,this.failed=!0,void(this.activeSubSolver=null);if(!this.activeSubSolver.solved)return;return this.componentMeshNodes.push(this.activeSubSolver.getOutput().routingRegions),this.currentIndex+=1,void(this.activeSubSolver=null)}if(this.currentIndex\u003e=this.inputProblem.componentSrjs.length)return void(this.solved=!0);const t=this.inputProblem.componentKinds[this.currentIndex],e=this.inputProblem.componentSrjs[this.currentIndex],n={inputSrj:e,detectedComponent:{componentId:this.inputProblem.componentIds[this.currentIndex],componentKind:t,bounds:{__type:\"rect\",...e.bounds}},viaDiameter:this.inputProblem.viaDiameter,obstacleMargin:this.inputProblem.obstacleMargin};this.activeSubSolver=dU.create(n)}getOutput(){return{componentMeshNodes:this.componentMeshNodes}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.inputProblem.componentSrjs[this.currentIndex]??null,e=this.componentMeshNodes.flatMap(t=\u003et);return{rects:[...t?[{center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,fill:\"rgba(0,0,0,0)\",stroke:\"rgba(255,140,0,0.72)\",label:`active component ${this.inputProblem.componentIds[this.currentIndex]??this.currentIndex}`},...t.obstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(255,140,0,0.10)\",stroke:\"rgba(255,140,0,0.30)\",label:t.obstacleId??t.componentId??\"obstacle\"}))]:[],...e.map(t=\u003e({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?\"rgba(255,0,0,0.14)\":\"rgba(0,120,255,0.12)\",stroke:t._containsObstacle?\"rgba(255,0,0,0.34)\":\"rgba(0,120,255,0.38)\"}))]}}},TZ=.001;function RZ(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(const t of e){const e=n[n.length-1];(void 0===e||Math.abs(t-e)\u003eTZ)\u0026\u0026n.push(t)}return n}function EZ(t){const e=Math.min(...t),n=Math.max(...t);return!(e\u003c=0)\u0026\u0026n/e\u003c=1.01}function AZ(t){if(!function(t){return EZ(t.map(t=\u003et.width))\u0026\u0026EZ(t.map(t=\u003et.height))}(t))return!1;if(!function(t){return t.every(t=\u003e{const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return!(e\u003c=0)\u0026\u0026n/e\u003c=1.5})}(t))return!1;const e=RZ(t.map(t=\u003et.center.y)),n=RZ(t.map(t=\u003et.center.x)),o=e.length,i=n.length;if(o\u003c3||i\u003c3)return!1;const r=o*i;return!((r\u003e0?t.length/r:0)\u003c.5)\u0026\u0026!!function(t,e,n){if(e.length\u003c3)return!1;if(n.length\u003c3)return!1;const o=new Set(e.slice(1,-1)),i=new Set(n.slice(1,-1));let r=0;for(const e of t)o.has(e.center.y)\u0026\u0026i.has(e.center.x)\u0026\u0026(r+=1);return r\u003e=1}(t,e,n)}function OZ(t){return[Math.round(t.width/TZ),Math.round(t.height/TZ),t.layers.join(\",\")].join(\":\")}function kZ(t){if(t.length\u003c3)return!1;const e=[...t].sort((t,e)=\u003et-e),n=e[1]-e[0];return!(n\u003c=TZ)\u0026\u0026e.every((t,o)=\u003e0===o||Math.abs(t-e[o-1]-n)\u003c=TZ)}function LZ(t){const e=function(t){const e=new Map;for(const n of t){const t=Math.round(n.center.y/TZ),o=Math.round(n.center.x/TZ),i=e.get(t)??{y:n.center.y,obstaclesByX:new Map};i.obstaclesByX.set(o,n),e.set(t,i)}return[...e.values()]}(t);let n=[];for(const t of e){const o=[...t.obstaclesByX.keys()];if(!kZ([...t.obstaclesByX.values()].map(t=\u003et.center.x)))continue;const i=e.filter(t=\u003eo.every(e=\u003et.obstaclesByX.has(e)));if(!kZ(i.map(t=\u003et.y)))continue;const r=i.flatMap(t=\u003eo.map(e=\u003et.obstaclesByX.get(e)));r.length\u003en.length\u0026\u0026(n=r)}return n}function DZ(t){if(AZ(t))return t;const e=Map.groupBy(t,OZ);let n=[];for(const t of e.values()){const e=LZ(t);e.length\u003en.length\u0026\u0026(n=e)}return n.length\u003e0?n:null}function zZ(t){const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return e\u003e0\u0026\u0026n/e\u003e=1.5}function FZ({perimeterPadObstacles:t,thermalPadObstacles:e}){if(0===e.length)return!0;if(e.length\u003e4)return!1;const n=CZ(t),o=n.maxX-n.minX,i=n.maxY-n.minY,r=n.minX+.2*o,s=n.maxX-.2*o,a=n.minY+.2*i,c=n.maxY-.2*i,l=Math.min(...t.map(t=\u003eMath.min(t.width,t.height)));return e.every(t=\u003e{const e=Math.min(t.width,t.height);return t.center.x\u003e=r\u0026\u0026t.center.x\u003c=s\u0026\u0026t.center.y\u003e=a\u0026\u0026t.center.y\u003c=c\u0026\u0026e\u003el})}function BZ(t){if(t.length\u003c12)return!1;if(t.length\u003e32)return!1;const{counts:e,maxNearestSideRatio:n}=function(t){const e=CZ(t),n=e.maxX-e.minX,o=e.maxY-e.minY,i={top:0,right:0,bottom:0,left:0};if(n\u003c=0||o\u003c=0)return{counts:i,maxNearestSideRatio:1};let r=0;for(const s of t){const t=s.width\u003es.height,a=[{side:\"top\",distance:Math.abs(s.center.y-e.minY),axisSpan:o,orientationMatches:!t},{side:\"right\",distance:Math.abs(e.maxX-s.center.x),axisSpan:n,orientationMatches:t},{side:\"bottom\",distance:Math.abs(e.maxY-s.center.y),axisSpan:o,orientationMatches:!t},{side:\"left\",distance:Math.abs(s.center.x-e.minX),axisSpan:n,orientationMatches:t}].filter(t=\u003et.orientationMatches).sort((t,e)=\u003et.distance-e.distance)[0];i[a.side]+=1,r=Math.max(r,a.distance/a.axisSpan)}return{counts:i,maxNearestSideRatio:r}}(t);return e.top\u003e=3\u0026\u0026e.right\u003e=3\u0026\u0026e.bottom\u003e=3\u0026\u0026e.left\u003e=3\u0026\u0026n\u003c=.25}function jZ(t){const e=function(t){return t.filter(zZ)}(t);return{perimeterPadObstacles:e,thermalPadObstacles:t.filter(t=\u003e!zZ(t))}}function $Z(t){const e=Math.min(...t),n=Math.max(...t);return!(e\u003c=0)\u0026\u0026n/e\u003c=1.01}function YZ(t,e){let n=0,o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ce.length;i++){const r=Math.abs(t-e[i]);r\u003co\u0026\u0026(n=i,o=r)}return n}function XZ({memberObstacles:t,inputSrj:e}){if(!function(t){return $Z(t.map(t=\u003et.width))\u0026\u0026$Z(t.map(t=\u003et.height))}(t))return!1;const n=RZ(t.map(t=\u003et.center.y)),o=RZ(t.map(t=\u003et.center.x));if(!(2===n.length\u0026\u0026o.length\u003e=4||2===o.length\u0026\u0026n.length\u003e=4))return!1;const i=function({memberObstacles:t,rowAxisValues:e,columnAxisValues:n}){if(2===e.length\u0026\u0026n.length\u003e=4){const n=[[],[]];for(const o of t)n[YZ(o.center.y,e)].push(o);return Math.min(...n[1].map(t=\u003et.center.y-t.height/2))-Math.max(...n[0].map(t=\u003et.center.y+t.height/2))}if(2===n.length\u0026\u0026e.length\u003e=4){const e=[[],[]];for(const o of t)e[YZ(o.center.x,n)].push(o);return Math.min(...e[1].map(t=\u003et.center.x-t.width/2))-Math.max(...e[0].map(t=\u003et.center.x+t.width/2))}return null}({memberObstacles:t,rowAxisValues:n,columnAxisValues:o});if(null===i)return!1;return i\u003e2*(Yo(e).padDiameter+(e.defaultObstacleMargin??.15))}var VZ=[class t{constructor(t){this.params=t}params;static componentKind=\"qfp_thermalpad\";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){const{perimeterPadObstacles:e,thermalPadObstacles:n}=jZ(t);return 0!==n.length\u0026\u0026!!BZ(e)\u0026\u0026FZ({perimeterPadObstacles:e,thermalPadObstacles:n})}(t)}},class t{constructor(t){this.params=t}params;static componentKind=\"qfp\";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){const{perimeterPadObstacles:e,thermalPadObstacles:n}=jZ(t);return!(n.length\u003e0)\u0026\u0026!!FZ({perimeterPadObstacles:e,thermalPadObstacles:n})\u0026\u0026BZ(e)}(t)}},class t{constructor(t){this.params=t}params;static componentKind=\"soic\";componentKind=t.componentKind;static isMatch(t){return XZ(t)}},class t{constructor(t){this.params=t}params;static componentKind=\"bga\";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){return null!==DZ(t)}(t)}}];function WZ(t){return function(t){for(const e of VZ)if(e.isMatch(t))return new e(t);return null}(t)?.componentKind??null}var HZ=class extends kt{inputSrj;initialized=!1;groupedComponentObstacles={};groupedComponentKinds={};unprocessedComponentIds=[];detectedComponents=[];currentComponentId=null;currentMemberObstacles=[];output=null;constructor({inputSrj:t}){super(),this.inputSrj=t}getConstructorParams(){return[{inputSrj:this.inputSrj}]}_step(){this.initialized?this.output?this.solved=!0:null!==this.currentComponentId||this.unprocessedComponentIds.length\u003e0?this.processNextComponent():(this.finalizeOutput(),this.solved=!0):this.initializeDetectionState()}getOutput(){if(!this.output)throw new Error(\"ComponentDetectionSolver has not solved yet\");return this.output}visualize(){const t=[];t.push(...this.inputSrj.obstacles.filter(t=\u003e!t.componentId).map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(120, 120, 120, 0.10)\",stroke:\"rgba(120, 120, 120, 0.40)\",label:t.obstacleId,layer:t.layers.join(\",\"),step:0})));const e=new Set(this.detectedComponents.map(t=\u003et.componentId));for(const n of this.inputSrj.obstacles){if(!n.componentId)continue;if(e.has(n.componentId))continue;const o=n.componentId===this.currentComponentId,i=Ro(n.componentId),r=this.groupedComponentKinds[n.componentId];t.push({center:n.center,width:n.width,height:n.height,fill:To(i,o?.55:.82),stroke:To(i,o?.1:.45),label:r?`${n.componentId} ${r.toUpperCase()}`:n.componentId,layer:n.layers.join(\",\"),step:o?1:0})}for(const e of this.detectedComponents){const n=Ro(e.componentId);t.push({center:{x:(e.bounds.minX+e.bounds.maxX)/2,y:(e.bounds.minY+e.bounds.maxY)/2},width:e.bounds.maxX-e.bounds.minX,height:e.bounds.maxY-e.bounds.minY,fill:To(n,.88),stroke:To(n,.1),label:`${e.componentId} ${e.componentKind.toUpperCase()} region`,step:2})}return{title:this.getVisualizationTitle(),rects:t,lines:[],points:[],circles:[]}}preview(){return this.visualize()}initializeDetectionState(){this.initialized=!0,this.groupedComponentKinds={},this.groupedComponentObstacles=this.groupObstaclesByComponentId({obstacles:this.inputSrj.obstacles}),this.unprocessedComponentIds=Object.keys(this.groupedComponentObstacles).sort(),this.detectedComponents=[],this.currentComponentId=null,this.currentMemberObstacles=[],this.output=null}processNextComponent(){if(!this.currentComponentId){const t=this.unprocessedComponentIds.shift();return t?(this.currentComponentId=t,void(this.currentMemberObstacles=this.groupedComponentObstacles[t]??[])):(this.currentComponentId=null,void(this.currentMemberObstacles=[]))}if(0===this.currentMemberObstacles.length)return this.currentComponentId=null,void(this.currentMemberObstacles=[]);this.detectedComponents.push(this.createDetectedComponent({componentId:this.currentComponentId,componentKind:this.groupedComponentKinds[this.currentComponentId],memberObstacles:this.currentMemberObstacles})),this.currentComponentId=null,this.currentMemberObstacles=[]}finalizeOutput(){this.output=this.detectedComponents.map(t=\u003e({...t,bounds:{...t.bounds}})),this.stats={initialized:this.initialized,totalComponentCount:Object.keys(this.groupedComponentObstacles).length,detectedComponentCount:this.detectedComponents.length,detectedBgaComponentCount:this.detectedComponents.filter(t=\u003e\"bga\"===t.componentKind).length,detectedQfpComponentCount:this.detectedComponents.filter(t=\u003e\"qfp\"===t.componentKind).length,detectedQfpComponentIds:this.detectedComponents.filter(t=\u003e\"qfp\"===t.componentKind).map(t=\u003et.componentId),detectedQfpThermalPadComponentCount:this.detectedComponents.filter(t=\u003e\"qfp_thermalpad\"===t.componentKind).length,detectedQfpThermalPadComponentIds:this.detectedComponents.filter(t=\u003e\"qfp_thermalpad\"===t.componentKind).map(t=\u003et.componentId),detectedSoicComponentCount:this.detectedComponents.filter(t=\u003e\"soic\"===t.componentKind).length,detectedSoicComponentIds:this.detectedComponents.filter(t=\u003e\"soic\"===t.componentKind).map(t=\u003et.componentId),remainingComponentCount:this.unprocessedComponentIds.length,hasActiveComponent:null!==this.currentComponentId}}groupObstaclesByComponentId({obstacles:t}){const e={},n={};for(const n of t)n.componentId\u0026\u0026(e[n.componentId]??=[],e[n.componentId].push(n));const o=Object.entries(e).flatMap(([t,e])=\u003e{const o=this.inputSrj.bounds;if(e.some(t=\u003e!NZ({bounds:Ee(t),outerBounds:o,epsilon:0})))return[];const i=WZ({memberObstacles:e,inputSrj:this.inputSrj});if(!i)return[];n[t]=i;return[[t,\"bga\"===i?DZ(e):e]]});return this.groupedComponentKinds=n,Object.fromEntries(o)}createDetectedComponent({componentId:t,componentKind:e,memberObstacles:n}){return{componentId:t,componentKind:e,bounds:{__type:\"rect\",...CZ(n)}}}getVisualizationTitle(){const t=Object.keys(this.groupedComponentObstacles).length||new Set(this.inputSrj.obstacles.map(t=\u003et.componentId).filter(t=\u003eBoolean(t))).size,e=this.detectedComponents.length;return this.initialized?this.output||this.solved?`Component Detection: done ${e}/${t}`:null!==this.currentComponentId||this.unprocessedComponentIds.length\u003e0?`Component Detection: ${e}/${t} processed`:`Component Detection: finalizing ${e}/${t}`:\"Component Detection: setup\"}},GZ=t=\u003et.componentId\u0026\u0026t.obstacleId?`${t.componentId}\\n${t.obstacleId}`:t.componentId??t.obstacleId??\"obstacle\",UZ=class extends Dt{rectBoundsComponentDetection;pipelineDef=[Lt(\"rectBoundsComponentDetection\",HZ,t=\u003e[{inputSrj:t.inputProblem.inputSrj}])];getConstructorParams(){return[this.inputProblem]}getOutput(){const t=this.getStageOutput(\"rectBoundsComponentDetection\");if(!t)throw new Error(\"ComponentDetectionSolver has not solved yet\");return t}initialVisualize(){const{bounds:t}=this.inputProblem.inputSrj;return{title:\"Component Detection: board and grouped component pads\",rects:[{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,fill:\"rgba(0, 0, 0, 0)\",stroke:\"rgba(40, 40, 40, 0.7)\",label:\"Board bounds\",step:0},...this.inputProblem.inputSrj.obstacles.map(t=\u003e{const e=t.componentId?Ro(t.componentId):null;return{center:t.center,width:t.width,height:t.height,fill:e?To(e,.72):\"rgba(120, 120, 120, 0.10)\",stroke:e?To(e,.28):\"rgba(120, 120, 120, 0.40)\",label:GZ(t),layer:t.layers.join(\",\"),step:t.componentId?1:0}})],lines:[],points:[],circles:[]}}},ZZ=1e-9;function qZ(t){return Ve({center:t.center,width:t.width,height:t.height})}function JZ(t,e){const n={minX:Math.max(t.minX,e.minX),maxX:Math.min(t.maxX,e.maxX),minY:Math.max(t.minY,e.minY),maxY:Math.min(t.maxY,e.maxY)};return KZ(n)?n:null}function KZ(t){const e=t.maxX-t.minX,n=t.maxY-t.minY,o=Number.isFinite(e)\u0026\u0026e\u003eZZ,i=Number.isFinite(n)\u0026\u0026n\u003eZZ;return o\u0026\u0026i}function QZ(t){!function(t){if(!Number.isInteger(t.layerCount))throw new Error(\"TopologyMergingSolver: layerCount must be an integer\");if(t.layerCount\u003c=0)throw new Error(\"TopologyMergingSolver: layerCount must be positive\");if(0===t.nodeGroups.length)throw new Error(\"TopologyMergingSolver: at least one node group is required\");const e=new Set;let n=0;for(const o of t.nodeGroups){if(e.has(o.groupId))throw new Error(`TopologyMergingSolver: duplicate topology group id \"${o.groupId}\"`);if(e.add(o.groupId),n+=o.nodes.length,0===o.nodes.length)throw new Error(`TopologyMergingSolver: topology group \"${o.groupId}\" is empty`);const i=new Set;for(const e of o.nodes){if(i.has(e.capacityMeshNodeId))throw new Error(`TopologyMergingSolver: duplicate node id \"${e.capacityMeshNodeId}\" in group \"${o.groupId}\"`);i.add(e.capacityMeshNodeId),tq({node:e,groupId:o.groupId,layerCount:t.layerCount})}}if(0===n)throw new Error(\"TopologyMergingSolver: topology node groups are empty\")}(t);const e=[],n=new Map;for(let o=0;o\u003ct.nodeGroups.length;o++){const i=t.nodeGroups[o];for(const t of i.nodes){const r={sourceKey:`${i.groupId}:${t.capacityMeshNodeId}`,groupIndex:o,node:t,bounds:qZ(t)};e.push(r),n.set(r.sourceKey,r)}}return{preparedNodes:e,preparedNodeBySourceKey:n}}function tq({node:t,groupId:e,layerCount:n}){if(!KZ(qZ(t)))throw new Error(`TopologyMergingSolver: node \"${t.capacityMeshNodeId}\" in group \"${e}\" has invalid bounds`);if(0===t.availableZ.length)throw new Error(`TopologyMergingSolver: node \"${t.capacityMeshNodeId}\" in group \"${e}\" has no available layers`);const o=[...new Set(t.availableZ)].sort((t,e)=\u003et-e),i=o.some(t=\u003e!Number.isInteger(t)||t\u003c0||t\u003e=n),r=o.length===t.availableZ.length\u0026\u0026o.every((e,n)=\u003ee===t.availableZ[n]);if(i||!r)throw new Error(`TopologyMergingSolver: node \"${t.capacityMeshNodeId}\" in group \"${e}\" has invalid or unsorted availableZ`)}var eq=1e-5,nq=4e-5;function oq({regions:t,preparedNodeBySourceKey:e,nodeGroups:n,provenance:o,preserveSourceIds:i=!0}){i\u0026\u0026(o.groupIndexesByNodeId.clear(),o.sourceKeysByNodeId.clear());const r=[...t].sort((t,e)=\u003et.bounds.minX-e.bounds.minX||t.bounds.minY-e.bounds.minY||t.bounds.maxX-e.bounds.maxX||t.bounds.maxY-e.bounds.maxY||t.availableZ[0]-e.availableZ[0]),s=new Set;return r.map((t,r)=\u003e{const a=t.sourceKeys.map(t=\u003e{const n=e.get(t);if(!n)throw new Error(`TopologyMergingSolver: missing source node for \"${t}\"`);return n}),c=a.map(({node:t})=\u003et),l=function({sourceNodes:t,isComponentTopologyNode:e}){if(1===t.length)return{_isComponentTopologyNode:!!e||t[0]._isComponentTopologyNode};const n=t.map(t=\u003et.capacityMeshNodeId),o=iq(t.map(t=\u003et._targetConnectionName),\"target connection\",n),i=iq(t.map(t=\u003et._offBoardConnectionId),\"off-board connection\",n),r=iq(t.map(t=\u003et._offboardNetName),\"off-board net\",n),s=Array.from(new Set(t.flatMap(t=\u003et._offBoardConnectedCapacityMeshNodeIds??[]))),a=Array.from(new Set(t.flatMap(t=\u003et._connectedTo??[])));return{_containsObstacle:t.some(t=\u003et._containsObstacle)||void 0,_completelyInsideObstacle:t.some(t=\u003et._completelyInsideObstacle)||void 0,_containsTarget:t.some(t=\u003et._containsTarget)||void 0,_targetConnectionName:o,_isVirtualOffboard:t.some(t=\u003et._isVirtualOffboard)||void 0,_offboardNetName:r,_offBoardConnectionId:i,_offBoardConnectedCapacityMeshNodeIds:s.length\u003e0?s:void 0,_qfpRegionType:rq(t.map(t=\u003et._qfpRegionType)),_isNarrowQfpPadGap:t.some(t=\u003et._isNarrowQfpPadGap)||void 0,_soicRegionType:rq(t.map(t=\u003et._soicRegionType)),_isComponentTopologyNode:e||void 0,_connectedTo:a.length\u003e0?a:void 0}}({sourceNodes:c,isComponentTopologyNode:a.some(({groupIndex:t})=\u003en[t].isComponent)}),d=i\u0026\u00261===a.length?a[0].node:null,h=Boolean(d\u0026\u0026function({region:t,sourceNode:e,usedNodeIds:n}){const o=qZ(e),i=Math.abs(t.bounds.minX-o.minX)\u003c=eq\u0026\u0026Math.abs(t.bounds.maxX-o.maxX)\u003c=eq\u0026\u0026Math.abs(t.bounds.minY-o.minY)\u003c=eq\u0026\u0026Math.abs(t.bounds.maxY-o.maxY)\u003c=eq,r=t.availableZ.length===e.availableZ.length\u0026\u0026t.availableZ.every((t,n)=\u003et===e.availableZ[n]);return i\u0026\u0026r\u0026\u0026!n.has(e.capacityMeshNodeId)}({region:t,sourceNode:d,usedNodeIds:s}));let u=h?d.capacityMeshNodeId:`topology_merge_${r}`;for(;s.has(u);)u=`${u}_next`;return s.add(u),i\u0026\u0026(o.groupIndexesByNodeId.set(u,[...new Set(a.map(({groupIndex:t})=\u003et))]),o.sourceKeysByNodeId.set(u,[...t.sourceKeys])),{...d??c[0],...l,capacityMeshNodeId:u,center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,layer:`z${t.availableZ.join(\",\")}`,availableZ:[...t.availableZ],_adjacentNodeIds:void 0,_parent:void 0,_strawNode:void 0,_strawParentCapacityMeshNodeId:void 0}})}function iq(t,e,n){const o=Array.from(new Set(t.filter(t=\u003evoid 0!==t)));if(o.length\u003e1)throw new Error(`TopologyMergingSolver: conflicting ${e} values for overlapping source nodes ${n.join(\", \")}`);return o[0]}function rq(t){const e=Array.from(new Set(t.filter(t=\u003evoid 0!==t)));return 1===e.length?e[0]:void 0}function sq({node:t,sourceKey:e,preparedNodeBySourceKey:n}){const o=n.get(e);if(!o)throw new Error(`TopologyMergingSolver: missing source node for output \"${t.capacityMeshNodeId}\"`);const i=qZ(t),r=i.minX\u003e=o.bounds.minX-nq\u0026\u0026i.maxX\u003c=o.bounds.maxX+nq\u0026\u0026i.minY\u003e=o.bounds.minY-nq\u0026\u0026i.maxY\u003c=o.bounds.maxY+nq,s=t.availableZ.every(t=\u003eo.node.availableZ.includes(t));if(!r||!s)throw new Error(`TopologyMergingSolver: output node \"${t.capacityMeshNodeId}\" escapes its source geometry or layers`)}function aq({groupIndexesA:t,groupIndexesB:e,sourceKeysA:n,sourceKeysB:o,sharedLayers:i,preparedNodeBySourceKey:r}){if(1!==t.length||1!==e.length||t[0]!==e[0]||1!==n.length||1!==o.length||n[0]===o[0])return!1;const s=r.get(n[0]),a=r.get(o[0]);if(!s||!a||0===i.length)return!1;return i.some(t=\u003es.node.availableZ.includes(t)\u0026\u0026a.node.availableZ.includes(t))\u0026\u0026null!==JZ(s.bounds,a.bounds)}function cq(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(const t of e){const e=n[n.length-1];(void 0===e||Math.abs(t-e)\u003eeq)\u0026\u0026n.push(t)}return n}function lq(t,e){return e.x\u003e=t.minX-eq\u0026\u0026e.x\u003c=t.maxX+eq\u0026\u0026e.y\u003e=t.minY-eq\u0026\u0026e.y\u003c=t.maxY+eq}function dq({coveringNodes:t,nodeGroups:e,layerCount:n}){const o=new Map;for(let i=0;i\u003cn;i++){const n=t.filter(({node:t})=\u003et.availableZ.includes(i)).sort((t,e)=\u003et.sourceKey.localeCompare(e.sourceKey));if(0===n.length)continue;const r=new Set(n.map(({groupIndex:t})=\u003et)),s=n.filter(({node:t})=\u003et._containsObstacle\u0026\u0026t._containsTarget),a=s.filter(({groupIndex:t})=\u003e!e[t].isComponent),c=new Set(s.map(({groupIndex:t})=\u003et)),l=s.length\u003e0?a.length\u003e0||1===c.size?\"target-passthrough\":\"target-merged\":1===r.size?\"passthrough\":\"merged\",d=gq({topologyMode:l,nodesOnLayer:n,targetObstacleNodes:s,globalTargetObstacleNodes:a});for(const t of d){const e=JSON.stringify({mode:l,sourceKeys:t}),n=o.get(e);n?n.availableZ.push(i):o.set(e,{availableZ:[i],sourceKeys:t,topologyMode:l,topologySignature:e})}}return[...o.values()]}function hq(t){return JSON.stringify({availableZ:t.availableZ,topologySignature:t.topologySignature})}function uq(t){return JSON.stringify({mergeKey:hq(t),minY:t.bounds.minY.toPrecision(15),maxY:t.bounds.maxY.toPrecision(15)})}function pq(t){return JSON.stringify({mergeKey:hq(t),minX:t.bounds.minX.toPrecision(15),maxX:t.bounds.maxX.toPrecision(15)})}function mq(t,e){const n=new Map;for(const o of t){const t=\"horizontal\"===e?uq(o):pq(o),i=n.get(t)??[];i.push(o),n.set(t,i)}return[...n.values()].flatMap(t=\u003efunction(t,e){const n=[...t].sort((t,n)=\u003e\"horizontal\"===e?t.bounds.minX-n.bounds.minX:t.bounds.minY-n.bounds.minY),o=[];for(const t of n){const n=o[o.length-1],i=void 0!==n\u0026\u0026(\"horizontal\"===e?Math.abs(n.bounds.maxX-t.bounds.minX)\u003c=eq:Math.abs(n.bounds.maxY-t.bounds.minY)\u003c=eq);n\u0026\u0026i?\"horizontal\"===e?n.bounds.maxX=t.bounds.maxX:n.bounds.maxY=t.bounds.maxY:o.push({...t,bounds:{...t.bounds},availableZ:[...t.availableZ],sourceKeys:[...t.sourceKeys]})}return o}(t,e))}function gq({topologyMode:t,nodesOnLayer:e,targetObstacleNodes:n,globalTargetObstacleNodes:o}){if(\"target-passthrough\"===t){return(o.length\u003e0?o:n).map(({sourceKey:t})=\u003e[t])}return\"target-merged\"===t?[n.map(({sourceKey:t})=\u003et).sort()]:\"passthrough\"===t?e.map(({sourceKey:t})=\u003e[t]):[e.map(({sourceKey:t})=\u003et).sort()]}var fq=class extends kt{constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e5;const{preparedNodes:e,preparedNodeBySourceKey:n}=QZ(t);this.preparedNodes=e,this.preparedNodeBySourceKey=n,this.xCoordinates=cq(this.preparedNodes.flatMap(({bounds:t})=\u003e[t.minX,t.maxX])),this.stats={inputNodeCount:this.preparedNodes.length,xSlabCount:Math.max(0,this.xCoordinates.length-1),processedXSlabCount:0,atomicRegionCount:0,outputNodeCount:0}}inputProblem;preparedNodes;preparedNodeBySourceKey;outputProvenance={groupIndexesByNodeId:new Map,sourceKeysByNodeId:new Map};xCoordinates;atomicRegions=[];outputNodes=[];currentXIndex=0;getConstructorParams(){return[this.inputProblem]}_step(){if(1===this.inputProblem.nodeGroups.length)return void this.completePassthroughTopology();if(this.currentXIndex\u003cthis.xCoordinates.length-1)return this.processCurrentXSlab(),this.currentXIndex+=1,this.stats.processedXSlabCount=this.currentXIndex,void(this.stats.atomicRegionCount=this.atomicRegions.length);const t=function(t){let e=t;for(;;){const t=mq(e,\"horizontal\"),n=mq(t,\"vertical\");if(n.length===e.length)return n;e=n}}(function({regions:t,preparedNodeBySourceKey:e}){const n=new Map;for(const e of t)for(const t of e.sourceKeys){const o=n.get(t)??new Set;o.add(e.topologyMode),n.set(t,o)}const o=new Set([...n.entries()].filter(([,t])=\u003e1===t.size\u0026\u0026t.has(\"target-passthrough\")).map(([t])=\u003et));return 0===o.size?t:[...t.filter(t=\u003e\"target-passthrough\"!==t.topologyMode||!o.has(t.sourceKeys[0])),...[...o].map(t=\u003e{const n=e.get(t);if(!n)throw new Error(`TopologyMergingSolver: missing authoritative target source \"${t}\"`);return{bounds:{...n.bounds},availableZ:[...n.node.availableZ],sourceKeys:[t],topologyMode:\"target-passthrough\",topologySignature:JSON.stringify({mode:\"target-passthrough\",sourceKeys:[t]})}})]}({regions:this.atomicRegions,preparedNodeBySourceKey:this.preparedNodeBySourceKey}));this.outputNodes=oq({regions:t,preparedNodeBySourceKey:this.preparedNodeBySourceKey,nodeGroups:this.inputProblem.nodeGroups,provenance:this.outputProvenance}),function({nodes:t,preparedNodeBySourceKey:e,provenance:n}){const o=new Set;for(const i of t){if(o.has(i.capacityMeshNodeId))throw new Error(`TopologyMergingSolver: duplicate output node id \"${i.capacityMeshNodeId}\"`);if(o.add(i.capacityMeshNodeId),!KZ(qZ(i)))throw new Error(`TopologyMergingSolver: output node \"${i.capacityMeshNodeId}\" has invalid bounds`);if(0===i.availableZ.length)throw new Error(`TopologyMergingSolver: output node \"${i.capacityMeshNodeId}\" has no available layers`);const t=n.sourceKeysByNodeId.get(i.capacityMeshNodeId);if(!t)throw new Error(`TopologyMergingSolver: missing output provenance for node \"${i.capacityMeshNodeId}\"`);1===t.length\u0026\u0026sq({node:i,sourceKey:t[0],preparedNodeBySourceKey:e})}for(let o=0;o\u003ct.length;o++){const i=t[o];for(let r=o+1;r\u003ct.length;r++){const o=t[r],s=i.availableZ.filter(t=\u003eo.availableZ.includes(t));if(0===s.length)continue;const a=JZ(qZ(i),qZ(o));if(!a)continue;const c=a.maxX-a.minX,l=a.maxY-a.minY;if(c\u003c=nq||l\u003c=nq)continue;const d=n.groupIndexesByNodeId.get(i.capacityMeshNodeId),h=n.groupIndexesByNodeId.get(o.capacityMeshNodeId);if(!d||!h)throw new Error(`TopologyMergingSolver: missing output provenance for overlapping nodes \"${i.capacityMeshNodeId}\" and \"${o.capacityMeshNodeId}\"`);const u=n.sourceKeysByNodeId.get(i.capacityMeshNodeId),p=n.sourceKeysByNodeId.get(o.capacityMeshNodeId);if(!u||!p)throw new Error(`TopologyMergingSolver: missing source provenance for overlapping nodes \"${i.capacityMeshNodeId}\" and \"${o.capacityMeshNodeId}\"`);if(!aq({groupIndexesA:d,groupIndexesB:h,sourceKeysA:u,sourceKeysB:p,sharedLayers:s,preparedNodeBySourceKey:e}))throw new Error(`TopologyMergingSolver: output nodes \"${i.capacityMeshNodeId}\" and \"${o.capacityMeshNodeId}\" have an unresolved inter-group overlap on a shared layer`)}}}({nodes:this.outputNodes,preparedNodeBySourceKey:this.preparedNodeBySourceKey,provenance:this.outputProvenance}),this.stats.outputNodeCount=this.outputNodes.length,this.stats.compactedRegionCount=t.length,this.solved=!0}getOutput(){if(!this.solved)throw new Error(\"TopologyMergingSolver: getOutput() called before the solver completed\");return this.outputNodes}computeProgress(){const t=Math.max(1,this.xCoordinates.length-1);return this.solved?1:Math.min(.99,this.currentXIndex/t)}visualize(){const t=this.solved?this.outputNodes:oq({regions:this.atomicRegions,preparedNodeBySourceKey:this.preparedNodeBySourceKey,nodeGroups:this.inputProblem.nodeGroups,provenance:this.outputProvenance,preserveSourceIds:!1});return{title:`Topology Merging: ${t.length} refined regions`,coordinateSystem:\"cartesian\",rects:t.map(t=\u003e({...Dc(t,{rectMargin:.01,zOffset:.02}),label:`${t.capacityMeshNodeId}\\navailableZ: ${t.availableZ.join(\",\")}\\ncomponent: ${t._isComponentTopologyNode?\"yes\":\"no\"}`})),lines:[],points:[],circles:[],texts:[]}}completePassthroughTopology(){const t=this.inputProblem.nodeGroups[0];this.outputNodes=t.nodes;for(const e of this.outputNodes)this.outputProvenance.groupIndexesByNodeId.set(e.capacityMeshNodeId,[0]),this.outputProvenance.sourceKeysByNodeId.set(e.capacityMeshNodeId,[`${t.groupId}:${e.capacityMeshNodeId}`]);this.stats.processedXSlabCount=this.stats.xSlabCount,this.stats.atomicRegionCount=0,this.stats.compactedRegionCount=0,this.stats.outputNodeCount=this.outputNodes.length,this.stats.passthroughNodeCount=this.outputNodes.length,this.solved=!0}processCurrentXSlab(){const t=this.xCoordinates[this.currentXIndex],e=this.xCoordinates[this.currentXIndex+1];if(e-t\u003c=eq)return;const n=(t+e)/2,o=this.preparedNodes.filter(({bounds:t})=\u003en\u003e=t.minX-eq\u0026\u0026n\u003c=t.maxX+eq),i=cq(o.flatMap(({bounds:t})=\u003e[t.minY,t.maxY]));for(let r=0;r\u003ci.length-1;r++){const s=i[r],a=i[r+1];if(a-s\u003c=eq)continue;const c={x:n,y:(s+a)/2},l=o.filter(({bounds:t})=\u003elq(t,c));if(0===l.length)continue;const d=dq({coveringNodes:l,nodeGroups:this.inputProblem.nodeGroups,layerCount:this.inputProblem.layerCount});for(const n of d)this.atomicRegions.push({bounds:{minX:t,maxX:e,minY:s,maxY:a},availableZ:n.availableZ,sourceKeys:n.sourceKeys,topologyMode:n.topologyMode,topologySignature:n.topologySignature})}}};function yq({meshNodes:t,components:e}){return 0===e.length?t:t.map(t=\u003e{const n=e.some(e=\u003efunction({node:t,component:e}){const{replacementObstacle:n}=e,o=Math.abs(t.center.x-n.center.x)\u003c=ZZ\u0026\u0026Math.abs(t.center.y-n.center.y)\u003c=ZZ\u0026\u0026Math.abs(t.width-n.width)\u003c=ZZ\u0026\u0026Math.abs(t.height-n.height)\u003c=ZZ;if(\"qfp\"!==e.componentKind\u0026\u0026\"qfp_thermalpad\"!==e.componentKind\u0026\u0026\"soic\"!==e.componentKind)return o;const i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=n.center.y-n.height/2,a=n.center.y+n.height/2,c=t.center.x\u003e=i-ZZ\u0026\u0026t.center.x\u003c=r+ZZ\u0026\u0026t.center.y\u003e=s-ZZ\u0026\u0026t.center.y\u003c=a+ZZ,l=t.width*t.height,d=n.width*n.height,h=c\u0026\u0026l\u003e=.2*d;return o||h}({node:t,component:e}));return n?{...t,_containsObstacle:void 0,_completelyInsideObstacle:void 0,_containsTarget:void 0,_targetConnectionName:void 0,_connectedTo:void 0}:t})}var _q=class extends Dt{globalTopologySolver;componentTopologyBatchSolver;normalizedInput;pipelineDef=[Lt(\"globalTopologySolver\",Kn,t=\u003e[t.getGlobalTopologySolverInput()]),Lt(\"componentTopologyBatchSolver\",wZ,t=\u003e[{componentSrjs:t.getComponentNoConnectionSrjs(),componentIds:t.normalizedInput.components.map(t=\u003et.componentId),componentKinds:t.normalizedInput.components.map(t=\u003et.componentKind),viaDiameter:t.inputProblem.viaDiameter,obstacleMargin:t.inputProblem.obstacleMargin}])];constructor(t){super(t),this.normalizedInput=PZ(t)}getConstructorParams(){return[this.inputProblem]}getOutput(){const t=yq({meshNodes:this.getStageOutput(\"globalTopologySolver\")?.meshNodes??[],components:this.normalizedInput.components}),e=this.getStageOutput(\"componentTopologyBatchSolver\")?.componentMeshNodes??[],n=this.getComponentNoConnectionSrjs();return{globalNoConnectionSrj:this.normalizedInput.globalNoConnectionSrj,componentNoConnectionSrjs:n,globalMeshNodes:t,componentMeshNodes:e}}finalVisualize(){const t=this.getOutput();return{title:\"Topology Planning: generated topology groups\",rects:[...t.componentNoConnectionSrjs.flatMap((t,e)=\u003e{const n=this.normalizedInput.components[e]??null;return t.obstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,fill:\"rgba(120, 120, 120, 0.06)\",stroke:\"rgba(120, 120, 120, 0.35)\",label:t.obstacleId??n?.componentId??\"component-pad\",layer:t.layers.join(\",\")}))}),...[...t.globalMeshNodes,...t.componentMeshNodes.flat()].map(t=\u003e{const e=this.normalizedInput.components.find(e=\u003et.capacityMeshNodeId.includes(e.componentId));return{...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?To(\"red\",.82):\"rgba(0, 120, 255, 0.12)\",stroke:t._containsObstacle?To(\"red\",.3):\"rgba(0, 120, 255, 0.55)\",label:e?`${e.componentKind.toUpperCase()} ${t.capacityMeshNodeId}`:t.capacityMeshNodeId}})],lines:[],points:[],circles:[],texts:[]}}visualize(){return this.filterGlobalRectDiffNodesFromVisualization({visualization:super.visualize()})}preview(){return this.filterGlobalRectDiffNodesFromVisualization({visualization:super.preview()})}getComponentNoConnectionSrjs(){return this.normalizedInput.components.map(t=\u003efunction({inputSrj:t,component:e}){const n=CZ(e.memberObstacles),o=Math.max(t.minViaPadDiameter??t.min_via_pad_diameter??t.minViaDiameter??.3,t.defaultObstacleMargin??.15,2*t.minTraceWidth),i=new Set(e.memberObstacles.flatMap(t=\u003et.connectedTo)),r=t.connections.flatMap(t=\u003et.pointsToConnect.filter(t=\u003e{const e=[t.pointId,t.pcb_port_id].filter(t=\u003e\"string\"==typeof t).some(t=\u003ei.has(t)),r=t.x\u003e=n.minX-o\u0026\u0026t.x\u003c=n.maxX+o\u0026\u0026t.y\u003e=n.minY-o\u0026\u0026t.y\u003c=n.maxY+o;return e\u0026\u0026r})).reduce((t,e)=\u003e({minX:Math.min(t.minX,e.x),maxX:Math.max(t.maxX,e.x),minY:Math.min(t.minY,e.y),maxY:Math.max(t.maxY,e.y)}),n),s=t.obstacles.filter(t=\u003eXe(Ee(t),r)).map(t=\u003e({...t}));return{...structuredClone(t),bounds:r,obstacles:s}}({inputSrj:this.inputProblem.inputSrj,component:t}))}getGlobalTopologySolverInput(){return{simpleRouteJson:this.normalizedInput.globalNoConnectionSrj,maxGapFillPasses:4}}filterGlobalRectDiffNodesFromVisualization({visualization:t}){return{...t,rects:MZ({rects:t.rects,components:this.normalizedInput.components})}}},bq=(t,e)=\u003e{if(t)return Object.entries(e).sort(([t],[e])=\u003ee.length-t.length).find(([e])=\u003et.includes(e))?.[1]},xq=(t,e)=\u003e({...t,points:t.points?.map(t=\u003e({...t,color:bq(t.label,e)??t.color})),lines:t.lines?.map(t=\u003e({...t,strokeColor:bq(t.label,e)??t.strokeColor})),circles:t.circles?.map(t=\u003e{const n=bq(t.label,e);return n?{...t,fill:n,stroke:n}:t})}),vq=class extends si{constructor(t){super(),this.topologyPlanningSolver=t,this.solved=t.solved,this.failed=t.failed,this.error=t.error,this.stats=t.stats}topologyPlanningSolver;getOutput(){return this.topologyPlanningSolver.getOutput().componentMeshNodes.flat()}visualize(){return this.topologyPlanningSolver.finalVisualize()??this.topologyPlanningSolver.visualize()}preview(){return this.visualize()}},Sq=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\u0026\u0026!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026this.tryFinalAcceptance(),!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),\"computeProgress\"in this\u0026\u0026(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error(\"getConstructorParams not implemented\")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved\u0026\u0026!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:[]}}},Iq=t=\u003et.filter(t=\u003eBoolean(t)),Cq=(t,e,n)=\u003e{const o=`${Math.round(100*t.x)},${Math.round(100*t.y)}`,i=e.map(t=\u003e((t,e)=\u003e\"top\"===t?0:\"bottom\"===t?e-1:Number.parseInt(t.slice(5),10))(t,n)).sort().join(\"-\");return`${o}:${i}`},Pq=class{parent=new Map;constructor(t,e=t.traces??[],n={}){for(const e of t.connections)this.unionAll(Iq([e.name,e.source_trace_id,e.rootConnectionName,e.netConnectionName,...e.mergedConnectionNames??[],...e.pointsToConnect.flatMap(e=\u003e[e.pointId,e.pcb_port_id,...n.includePhysicalPositionAliases?[Cq(e,e.layers??[e.layer],t.layerCount)]:[]])]));for(const n of[...e,...t.fixedTraces??[]])this.unionAll(Iq([n.pcb_trace_id,n.connection_name,n.source_trace_id,n.rootConnectionName,...n.mergedConnectionNames??[],...n.connectsTo??[]]));for(const e of t.obstacles)this.unionAll(n.includePhysicalPositionAliases?Iq([e.obstacleId,...e.connectedTo,...e.offBoardConnectsTo??[],Cq(e.center,e.layers,t.layerCount)]):e.connectedTo)}canonicalize(t){return[...new Set(t.map(t=\u003ethis.find(t)))]}unionAll(t){const e=t[0];if(e){this.add(e);for(let n=1;n\u003ct.length;n++)this.union(e,t[n])}}add(t){this.parent.has(t)||this.parent.set(t,t)}find(t){this.add(t);const e=this.parent.get(t);if(e===t)return t;const n=this.find(e);return this.parent.set(t,n),n}union(t,e){const n=this.find(t),o=this.find(e);n!==o\u0026\u0026this.parent.set(o,n)}},Mq=1e-6,Nq=(t,e)=\u003eMath.hypot(e.x-t.x,e.y-t.y),wq=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c=1e-12)return Nq(t,e);const s=Rq(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return Math.hypot(t.x-(e.x+o*s),t.y-(e.y+i*s))},Tq=(t,e,n=1e-6)=\u003eMath.abs(t.x-e.x)\u003c=n\u0026\u0026Math.abs(t.y-e.y)\u003c=n,Rq=(t,e,n)=\u003eMath.max(e,Math.min(n,t)),Eq=(t,e,n)=\u003e(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),Aq=(t,e,n)=\u003eMath.abs(Eq(e,n,t))\u003c=1e-9\u0026\u0026t.x\u003e=Math.min(e.x,n.x)-1e-9\u0026\u0026t.x\u003c=Math.max(e.x,n.x)+1e-9\u0026\u0026t.y\u003e=Math.min(e.y,n.y)-1e-9\u0026\u0026t.y\u003c=Math.max(e.y,n.y)+1e-9,Oq=(t,e,n,o)=\u003e((t,e,n,o)=\u003e{const i=Eq(t,e,n),r=Eq(t,e,o),s=Eq(n,o,t),a=Eq(n,o,e);return i*r\u003c0\u0026\u0026s*a\u003c0||Math.abs(i)\u003c=1e-9\u0026\u0026Aq(n,t,e)||Math.abs(r)\u003c=1e-9\u0026\u0026Aq(o,t,e)||Math.abs(s)\u003c=1e-9\u0026\u0026Aq(t,n,o)||Math.abs(a)\u003c=1e-9\u0026\u0026Aq(e,n,o)})(t,e,n,o)?0:Math.min(wq(t,n,o),wq(e,n,o),wq(n,t,e),wq(o,t,e)),kq=(t,e)=\u003e{let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];if(Aq(t,s,r))return!0;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n},Lq=(t,e,n)=\u003e{if(kq(t,n)||kq(e,n))return 0;let o=Number.POSITIVE_INFINITY;for(let i=0;i\u003cn.length;i++){const r=n[i],s=n[(i+1)%n.length];o=Math.min(o,Oq(t,e,r,s))}return o};function Dq(t,e,n){let o=0,i=1;const r=e.x-t.x,s=e.y-t.y,a=[[-r,t.x-n.minX],[r,n.maxX-t.x],[-s,t.y-n.minY],[s,n.maxY-t.y]];for(const[t,e]of a){if(Math.abs(t)\u003c1e-12){if(e\u003c0)return!1;continue}const n=e/t;if(t\u003c0?o=Math.max(o,n):i=Math.min(i,n),o\u003ei)return!1}return!0}function zq({start:t,end:e,width:n,base:o}){const i=Nq(t,e),r=(t=\u003eRq(1.25*t,.25,.75))(n),s=Math.max(1,Math.ceil(i/r)),a=n/2,c=[];for(let i=0;i\u003cs;i++){const r=i/s,l=(i+1)/s,d=t.x+(e.x-t.x)*r,h=t.y+(e.y-t.y)*r,u=t.x+(e.x-t.x)*l,p=t.y+(e.y-t.y)*l;c.push({...o,minX:Math.min(d,u)-a,minY:Math.min(h,p)-a,maxX:Math.max(d,u)+a,maxY:Math.max(h,p)+a,exactShape:{type:\"segment\",start:{x:d,y:h},end:{x:u,y:p},width:n}})}return c}var Fq=(t,e,n)=\u003e{const o=Math.cos(n),i=Math.sin(n),r=t.x-e.x,s=t.y-e.y;return{x:e.x+r*o-s*i,y:e.y+r*i+s*o}};var Bq=class{nodeIndices=[];priorities=[];get size(){return this.nodeIndices.length}push(t,e){let n=this.nodeIndices.length;for(this.nodeIndices.push(t),this.priorities.push(e);n\u003e0;){const t=n-1\u003e\u003e1;if(this.priorities[t]\u003c=e)break;this.swap(n,t),n=t}}pop(){const t=this.nodeIndices[0],e=this.nodeIndices.pop(),n=this.priorities.pop();if(0===this.nodeIndices.length)return t;this.nodeIndices[0]=e,this.priorities[0]=n;let o=0;for(;;){const t=2*o+1,e=t+1;if(t\u003e=this.nodeIndices.length)break;let n=t;if(e\u003cthis.nodeIndices.length\u0026\u0026this.priorities[e]\u003cthis.priorities[t]\u0026\u0026(n=e),this.priorities[o]\u003c=this.priorities[n])break;this.swap(o,n),o=n}return t}swap(t,e){[this.nodeIndices[t],this.nodeIndices[e]]=[this.nodeIndices[e],this.nodeIndices[t]],[this.priorities[t],this.priorities[e]]=[this.priorities[e],this.priorities[t]]}},jq=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]],$q=[\"#d53535\",\"#3478c8\",\"#8e44ad\",\"#15956f\"],Yq=class extends Sq{problem;searchBounds;rows;columns;origin;nodes=[];open=new Bq;bestCost=new Map;closed=new Set;baseStateCount;stateSpaceUpperBound;endLayerIndices;targetCell;segmentWidthCache=new Map;closedStateCount=0;output=null;constructor(t){super(),this.problem=t;const e=Math.max(t.traceWidth,t.viaDiameter)/2+t.obstacleIndex.clearance,n=Rq(Math.min(t.start.x,t.end.x)-t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),o=Rq(Math.max(t.start.x,t.end.x)+t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),i=Rq(Math.min(t.start.y,t.end.y)-t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),r=Rq(Math.max(t.start.y,t.end.y)+t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),s=Math.floor((n-t.gridOffset.x)/t.gridSize)*t.gridSize+t.gridOffset.x,a=Math.floor((i-t.gridOffset.y)/t.gridSize)*t.gridSize+t.gridOffset.y;this.origin={x:s,y:a},this.columns=Math.max(2,Math.floor((o-s)/t.gridSize)+1),this.rows=Math.max(2,Math.floor((r-a)/t.gridSize)+1),this.searchBounds={minX:s,minY:a,maxX:s+(this.columns-1)*t.gridSize,maxY:a+(this.rows-1)*t.gridSize};const c=this.rows*this.columns*t.layers.length*(t.maxViaCount+1);this.baseStateCount=c,this.stateSpaceUpperBound=c*(this.rows*this.columns+1),this.targetCell=this.pointToCell(t.end),this.endLayerIndices=new Set(t.endLayers.map(e=\u003et.layers.indexOf(e)).filter(t=\u003et\u003e=0));const l=this.pointToCell(t.start);for(const e of t.startLayers){const n=t.layers.indexOf(e);if(n\u003c0||this.endpointCollides(t.start,n))continue;const o={...l,...t.start,layerIndex:n,viaCount:0,viaPoints:[],g:0,f:this.heuristic(t.start),parentIndex:-1},i=this.nodes.length;this.nodes.push(o),this.open.push(i,o.f),this.bestCost.set(this.toStateIndex(o),0)}0!==this.open.size\u0026\u00260!==this.endLayerIndices.size||(this.failed=!0,this.error=\"No collision-free multilayer route endpoint\"),this.MAX_ITERATIONS=Math.min(15e3,Math.max(2e3,2*c)),this.stats=this.createStats()}getSolverName(){return`LayerAwareGridRouteSolver(${this.problem.gridSize.toFixed(3)}mm)`}_step(){if(0===this.open.size)return this.failed=!0,void(this.error=\"No collision-free multilayer grid route found\");const t=this.open.pop(),e=this.nodes[t],n=this.toStateIndex(e);if(!this.closed.has(n)){if(this.closed.add(n),this.closedStateCount++,e.row===this.targetCell.row\u0026\u0026e.column===this.targetCell.column\u0026\u0026this.endLayerIndices.has(e.layerIndex)\u0026\u0026e.viaCount\u003e=this.problem.minViaCount\u0026\u0026!this.segmentCollides(e,this.problem.end))return this.output=this.reconstructRoute(t),this.solved=!0,void(this.stats=this.createStats());this.expandPlanarMoves(t,e),this.expandViaMoves(t,e),this.stats=this.createStats()}}expandPlanarMoves(t,e){for(const[n,o]of jq){const i=e.row+n,r=e.column+o;if(i\u003c0||i\u003e=this.rows||r\u003c0||r\u003e=this.columns)continue;const s=this.cellToPoint(i,r),a=this.getSafeSegmentWidth(e,s);if(a\u003c=0)continue;const c=this.problem.gridSize*(0!==n\u0026\u00260!==o?Math.SQRT2:1)*Math.max(1,(this.problem.traceWidth/a)**this.problem.neckPenaltyExponent);this.enqueueNode({row:i,column:r,...s,layerIndex:e.layerIndex,viaCount:e.viaCount,viaPoints:e.viaPoints,g:e.g+c,parentIndex:t})}}expandViaMoves(t,e){if(e.viaCount\u003e=this.problem.maxViaCount)return;const n=.5*this.problem.gridSize;if(Nq(e,this.problem.start)\u003cn-1e-9||Nq(e,this.problem.end)\u003cn-1e-9)return;const o=e.parentIndex\u003e=0?this.nodes[e.parentIndex]:void 0;if(!o||o.layerIndex===e.layerIndex||!Tq(o,e))for(let n=0;n\u003cthis.problem.layers.length;n++)n!==e.layerIndex\u0026\u0026(this.problem.obstacleIndex.collidesVia({point:e,layers:this.problem.layers,padDiameter:this.problem.viaDiameter,holeDiameter:this.problem.viaHoleDiameter,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreTraceIndices:this.problem.softTraceIndices,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance,blockSameNetObstacles:!0,sameNetObstacleClearance:0,otherNewViaPoints:e.viaPoints,fixedVias:this.problem.fixedVias})||this.enqueueNode({row:e.row,column:e.column,x:e.x,y:e.y,layerIndex:n,viaCount:e.viaCount+1,viaPoints:[...e.viaPoints,{x:e.x,y:e.y}],g:e.g+this.problem.viaCost,parentIndex:t}))}enqueueNode(t){const e=this.toStateIndex(t);if(this.closed.has(e)||t.g\u003e=(this.bestCost.get(e)??Number.POSITIVE_INFINITY))return;this.bestCost.set(e,t.g);const n=t.g+this.heuristic(t),o=this.nodes.length;this.nodes.push({...t,f:n}),this.open.push(o,n)}endpointCollides(t,e){return this.getSafeSegmentWidth({...t,layerIndex:e,viaCount:0},t)\u003c=0}segmentCollides(t,e){return this.getSafeSegmentWidth(t,e)\u003c=0}getSafeSegmentWidth(t,e){const n=this.problem.layers[t.layerIndex],o=1===this.problem.startLayers.length\u0026\u00260===t.viaCount\u0026\u0026n===this.problem.originalStartLayer\u0026\u0026Nq(this.problem.start,t)\u003c=this.problem.maxStartNeckLength+1e-9\u0026\u0026Nq(this.problem.start,e)\u003c=this.problem.maxStartNeckLength+1e-9,i=1===this.problem.endLayers.length\u0026\u0026n===this.problem.originalEndLayer\u0026\u0026Nq(this.problem.end,t)\u003c=this.problem.maxEndNeckLength+1e-9\u0026\u0026Nq(this.problem.end,e)\u003c=this.problem.maxEndNeckLength+1e-9,r=Math.max(o?this.problem.startNeckWidth:0,i?this.problem.endNeckWidth:0),s=[t.x,t.y,e.x,e.y,t.layerIndex,t.viaCount,r].join(\":\"),a=this.segmentWidthCache.get(s);if(void 0!==a)return a;const c=o=\u003e!this.problem.obstacleIndex.collides({start:t,end:e,layer:n,width:o,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreTraceIndices:this.problem.softTraceIndices,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance});let l=0;if(o||i){const t=.025;let e=Math.ceil((r-1e-9)/t),n=Math.floor((this.problem.traceWidth+1e-9)/t);for(;e\u003c=n;){const o=Math.floor((e+n)/2),i=Number((o*t).toFixed(6));c(i)?(l=i,e=o+1):n=o-1}l\u003cr-1e-9\u0026\u0026c(r)\u0026\u0026(l=r)}else l=c(this.problem.traceWidth)?this.problem.traceWidth:0;return this.segmentWidthCache.set(s,l),l}reconstructRoute(t){const e=[];let n=t;for(;n\u003e=0;){const t=this.nodes[n];e.push(t),n=t.parentIndex}e.reverse();const o=e[e.length-1];Tq(o,this.problem.end)||e.push({...o,...this.problem.end,row:this.targetCell.row,column:this.targetCell.column,parentIndex:-1});const i=[];let r=[e[0]];for(let t=1;t\u003ce.length;t++){const n=e[t-1],o=e[t];o.layerIndex!==n.layerIndex?(i.push(r),r=[o]):r.push(o)}i.push(r);const s=[];for(let t=0;t\u003ci.length;t++){const e=this.simplifySection(i[t]),n=e.slice(0,-1).map((t,n)=\u003ethis.getSafeSegmentWidth(t,e[n+1])),o=e.map((t,o)=\u003e({route_type:\"wire\",x:t.x,y:t.y,layer:this.problem.layers[t.layerIndex],width:0===n.length?Math.min(this.problem.startNeckWidth,this.problem.endNeckWidth):0===o?n[0]:o===e.length-1?n[n.length-1]:Math.min(n[o-1],n[o])}));s.push(...o);const r=i[t+1];if(r){const t=this.problem.layers[e.at(-1).layerIndex],n=this.problem.layers[r[0].layerIndex],o=e.at(-1);s.push({route_type:\"via\",x:o.x,y:o.y,from_layer:t,to_layer:n,via_diameter:this.problem.viaDiameter,via_hole_diameter:this.problem.viaHoleDiameter})}}return{route:s,traceWidth:this.problem.traceWidth,startNeckWidth:this.problem.startNeckWidth,endNeckWidth:this.problem.endNeckWidth,gridSize:this.problem.gridSize,gridOffset:this.problem.gridOffset,viaCount:i.length-1}}simplifySection(t){return t.length\u003c=2?t:this.problem.neckPenaltyExponent\u003e1?this.simplifyStrictSection(t):this.simplifyWidthPreservingSection(t)}simplifyStrictSection(t){const e=t.slice(0,-1).map((e,n)=\u003ethis.getSafeSegmentWidth(e,t[n+1])),n=[0];for(let o=0;o\u003ce.length;o++)n.push(n[o]+this.getWidthPenalizedCost(t[o],t[o+1],e[o]));const o=[t[0]];let i=0;for(;i\u003ct.length-1;){let r=t.length-1;for(;r\u003ei+1\u0026\u0026!this.shortcutPreservesRouteQuality(t,e,n,i,r);)r--;o.push(t[r]),i=r}return this.removeRedundantCollinearPoints(o)}shortcutPreservesRouteQuality(t,e,n,o,i){const r=this.getSafeSegmentWidth(t[o],t[i]);if(r\u003c=0)return!1;let s=Number.POSITIVE_INFINITY;for(let t=o;t\u003ci;t++)s=Math.min(s,e[t]);const a=n[i]-n[o];return r\u003e=s-1e-9\u0026\u0026this.getWidthPenalizedCost(t[o],t[i],r)\u003c=a+1e-9}getWidthPenalizedCost(t,e,n){return Nq(t,e)*Math.max(1,(this.problem.traceWidth/n)**this.problem.neckPenaltyExponent)}simplifyWidthPreservingSection(t){const e=t.slice(0,-1).map((e,n)=\u003ethis.getSafeSegmentWidth(e,t[n+1])),n=[0];for(let o=0;o\u003ce.length;o++)n.push(n[o]+Nq(t[o],t[o+1])*Math.max(1,(this.problem.traceWidth/e[o])**this.problem.neckPenaltyExponent));const o=new Float64Array(t.length).fill(Number.POSITIVE_INFINITY),i=new Float64Array(t.length).fill(Number.POSITIVE_INFINITY),r=new Int32Array(t.length).fill(-1);o[0]=0,i[0]=0;for(let s=1;s\u003ct.length;s++){let a=Number.POSITIVE_INFINITY;for(let c=s-1;c\u003e=0;c--){if(a=Math.min(a,e[c]),!Number.isFinite(o[c]))continue;const l=this.getSafeSegmentWidth(t[c],t[s]);if(l\u003ca-1e-9)continue;const d=Nq(t[c],t[s]);if(d*Math.max(1,(this.problem.traceWidth/l)**this.problem.neckPenaltyExponent)\u003en[s]-n[c]+1e-9)continue;const h=o[c]+d*Math.max(0,this.problem.traceWidth-l),u=i[c]+d;(h\u003co[s]-1e-9||Math.abs(h-o[s])\u003c=1e-9\u0026\u0026u\u003ci[s]-1e-9)\u0026\u0026(o[s]=h,i[s]=u,r[s]=c)}}const s=[];let a=t.length-1;for(;a\u003e=0\u0026\u0026(s.push(t[a]),0!==a);)if(a=r[a],a\u003c0)return t;return s.reverse(),this.removeRedundantCollinearPoints(s)}removeRedundantCollinearPoints(t){return t.filter((t,e,n)=\u003e{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x),s=Math.abs(this.getSafeSegmentWidth(o,t)-this.getSafeSegmentWidth(t,i))\u003c1e-9;return Math.abs(r)\u003e1e-8||!s})}pointToCell(t){return{column:Rq(Math.round((t.x-this.origin.x)/this.problem.gridSize),0,this.columns-1),row:Rq(Math.round((t.y-this.origin.y)/this.problem.gridSize),0,this.rows-1)}}cellToPoint(t,e){return{x:this.origin.x+e*this.problem.gridSize,y:this.origin.y+t*this.problem.gridSize}}toStateIndex(t){const e=((t.viaCount*this.problem.layers.length+t.layerIndex)*this.rows+t.row)*this.columns+t.column;if(1!==t.viaCount||0===t.viaPoints.length||Nq(t,t.viaPoints[0])\u003e=this.problem.viaHoleDiameter+this.problem.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance-1e-9)return e;const n=this.pointToCell(t.viaPoints[0]);return e+(1+n.row*this.columns+n.column)*this.baseStateCount}heuristic(t){return Nq(t,this.problem.end)}createStats(){return{phase:\"layer-aware-grid-search\",gridSize:this.problem.gridSize,traceWidth:this.problem.traceWidth,startNeckWidth:this.problem.startNeckWidth,endNeckWidth:this.problem.endNeckWidth,maxViaCount:this.problem.maxViaCount,minViaCount:this.problem.minViaCount,openStates:this.open.size,closedStates:this.closedStateCount,trackedStates:this.bestCost.size,stateSpaceUpperBound:this.stateSpaceUpperBound}}computeProgress(){return Math.min(.99,this.iterations/this.MAX_ITERATIONS)}getOutput(){return this.output}getConstructorParams(){const{obstacleIndex:t,...e}=this.problem;return[e]}visualize(){const t=this.nodes.filter(t=\u003ethis.closed.has(this.toStateIndex(t))).slice(-2e3).map(t=\u003e({x:t.x,y:t.y,color:`${$q[t.layerIndex%$q.length]}55`})),e=[],n=[],o=this.output?.route??[];for(let t=0;t\u003co.length-1;t++){const i=o[t],r=o[t+1];if(\"wire\"===i?.route_type\u0026\u0026\"wire\"===r?.route_type\u0026\u0026i.layer===r.layer){const t=this.problem.layers.indexOf(i.layer);e.push({points:[i,r],strokeColor:$q[t%$q.length]??\"#333\",strokeWidth:i.width})}\"via\"===i?.route_type\u0026\u0026n.push({center:i,radius:(i.via_diameter??this.problem.viaDiameter)/2,fill:\"#d4a017\"})}return{coordinateSystem:\"cartesian\",title:this.getSolverName(),rects:[{center:{x:(this.searchBounds.minX+this.searchBounds.maxX)/2,y:(this.searchBounds.minY+this.searchBounds.maxY)/2},width:this.searchBounds.maxX-this.searchBounds.minX,height:this.searchBounds.maxY-this.searchBounds.minY,stroke:\"#777\"}],points:[...t,{...this.problem.start,color:\"green\",label:\"reroute start\"},{...this.problem.end,color:\"purple\",label:\"reroute target\"}],lines:e,circles:n,texts:[]}}},Xq=[{direction:1,strength:.7},{direction:-1,strength:.7},{direction:1,strength:1},{direction:-1,strength:1}],Vq=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r\u003c=1e-12)return{...e};const s=Rq(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return{x:e.x+o*s,y:e.y+i*s}},Wq=class extends Sq{problem;phase=\"prepare-candidate\";variantCursor=0;relaxationIteration=0;candidatePoints=[];sampledPoints;output=null;constructor(t){super(),this.problem=t,this.sampledPoints=this.sampleRoute(),this.MAX_ITERATIONS=100,this.stats=this.createStats()}getSolverName(){return\"ElasticTracePushSolver\"}_step(){switch(this.phase){case\"prepare-candidate\":if(this.variantCursor\u003e=Xq.length)return this.failed=!0,void(this.error=\"No collision-free elastic displacement found\");this.candidatePoints=this.sampledPoints.map(t=\u003e({...t})),this.relaxationIteration=0,this.phase=\"relax-candidate\";break;case\"relax-candidate\":this.relaxCandidate(),this.relaxationIteration++,this.relaxationIteration\u003e=10\u0026\u0026(this.phase=\"validate-candidate\");break;case\"validate-candidate\":{const t=this.simplifyCandidate(this.candidatePoints);this.pathCollides(t)?(this.variantCursor++,this.phase=\"prepare-candidate\"):(this.output={points:t,traceWidth:this.problem.traceWidth},this.phase=\"complete\");break}case\"complete\":this.solved=!0}this.stats=this.createStats()}sampleRoute(){const t=[],e=Rq(2*this.problem.traceWidth,.2,.45),n=this.problem.trace.route;for(let o=this.problem.range.startIndex;o\u003cthis.problem.range.endIndex;o++){const i=n[o],r=n[o+1];if(\"wire\"!==i?.route_type||\"wire\"!==r?.route_type||i.layer!==r.layer)continue;0===t.length\u0026\u0026t.push({x:i.x,y:i.y});const s=Nq(i,r),a=Math.max(1,Math.ceil(s/e));for(let e=1;e\u003c=a;e++){const n=e/a;t.push({x:i.x+(r.x-i.x)*n,y:i.y+(r.y-i.y)*n})}}return t}relaxCandidate(){const t=Xq[this.variantCursor],e=this.candidatePoints.map(t=\u003e({...t})),n=new Uint8Array(this.candidatePoints.length);for(let o=1;o\u003cthis.candidatePoints.length-1;o++){const i=this.candidatePoints[o],r=this.findNearestCorridorSegment(i);if(!r)continue;const s=Nq(r.segment.start,r.segment.end);if(s\u003c=1e-9)continue;const a=r.segment.width/2+this.problem.traceWidth/2+this.problem.obstacleIndex.clearance+.025;if(r.distance\u003ea+.35)continue;const c={x:(r.segment.start.y-r.segment.end.y)/s*t.direction,y:(r.segment.end.x-r.segment.start.x)/s*t.direction},l=a-((i.x-r.closest.x)*c.x+(i.y-r.closest.y)*c.y);if(l\u003c=0)continue;const d=Math.min(.35,l*t.strength);e[o]={x:i.x+c.x*d,y:i.y+c.y*d},n[o]=1}for(let t=1;t\u003ce.length-1;t++){if(!n[t])continue;const o=e[t-1],i=e[t],r=e[t+1];e[t]={x:.85*i.x+(o.x+r.x)/2*.15,y:.85*i.y+(o.y+r.y)/2*.15}}this.candidatePoints=e}findNearestCorridorSegment(t){let e;for(const n of this.problem.corridor){if(n.layer!==this.problem.layer)continue;const o=Vq(t,n.start,n.end),i=Nq(t,o);(!e||i\u003ce.distance)\u0026\u0026(e={segment:n,closest:o,distance:i})}return e}simplifyCandidate(t){if(t.length\u003c=2)return t;const e=[t[0]];let n=0;for(;n\u003ct.length-1;){let o=t.length-1;for(;o\u003en+1\u0026\u0026this.segmentCollides(t[n],t[o]);)o--;e.push(t[o]),n=o}return e.filter((t,e,n)=\u003e0===e||!Tq(t,n[e-1]))}pathCollides(t){if(t.length\u003c2)return!0;for(let e=0;e\u003ct.length-1;e++)if(this.segmentCollides(t[e],t[e+1]))return!0;return!1}segmentCollides(t,e){return this.problem.obstacleIndex.collides({start:t,end:e,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:-1})}createStats(){const t=Xq[this.variantCursor];return{phase:this.phase,direction:t?.direction,strength:t?.strength,variantCursor:this.variantCursor,relaxationIteration:this.relaxationIteration,sampledPointCount:this.sampledPoints.length}}computeProgress(){return Math.min(.99,(this.variantCursor+this.relaxationIteration/12)/Xq.length)}getOutput(){return this.output}getConstructorParams(){return[this.problem]}visualize(){return{coordinateSystem:\"cartesian\",title:`Elastic trace push: ${this.phase}`,lines:[...this.problem.corridor.map(t=\u003e({points:[t.start,t.end],strokeColor:\"rgba(255, 128, 0, 0.6)\",strokeWidth:t.width})),...this.candidatePoints.length\u003e1?[{points:this.candidatePoints,strokeColor:\"#1769d2\",strokeWidth:this.problem.traceWidth}]:[]],points:[],rects:[],circles:[],texts:[]}}},Hq=(t,e)=\u003e{const n=Math.abs(e.x-t.x),o=Math.abs(e.y-t.y);return n\u003c=Mq||o\u003c=Mq||Math.abs(n-o)\u003c=Mq},Gq=t=\u003e{let e=0;for(let n=0;n\u003ct.length-1;n++)Hq(t[n],t[n+1])||e++;return e},Uq=t=\u003e{let e=0;for(let n=0;n\u003ct.length-1;n++)e+=Nq(t[n],t[n+1]);return e},Zq=t=\u003et.filter((e,n)=\u003e0===n||!Tq(e,t[n-1])),qq=(t,e)=\u003e{const n=e.x-t.x,o=e.y-t.y,i=Math.abs(n),r=Math.abs(o),s=Math.sign(n),a=Math.sign(o),c=[];Hq(t,e)\u0026\u0026c.push([t,e]),c.push([t,{x:e.x,y:t.y},e],[t,{x:t.x,y:e.y},e]),i\u003e=r?c.push([t,{x:e.x-s*r,y:t.y},e],[t,{x:t.x+s*r,y:e.y},e]):c.push([t,{x:t.x,y:e.y-a*i},e],[t,{x:e.x,y:t.y+a*i},e]);const l=new Map;for(const t of c){const e=Zq(t);if(e.length\u003c2||e.some((t,n)=\u003en\u003ce.length-1\u0026\u0026!Hq(t,e[n+1])))continue;const n=e.map(t=\u003e`${t.x.toFixed(6)},${t.y.toFixed(6)}`).join(\";\");l.set(n,e)}return[...l.values()].sort((t,e)=\u003eUq(t)-Uq(e)||t.length-e.length)},Jq=class{nodeIndices=[];priorities=[];get size(){return this.nodeIndices.length}push(t,e){let n=this.nodeIndices.length;for(this.nodeIndices.push(t),this.priorities.push(e);n\u003e0;){const t=n-1\u003e\u003e1;if(this.priorities[t]\u003c=e)break;this.swap(n,t),n=t}}pop(){const t=this.nodeIndices[0],e=this.nodeIndices.pop(),n=this.priorities.pop();if(0===this.nodeIndices.length)return t;this.nodeIndices[0]=e,this.priorities[0]=n;let o=0;for(;;){const t=2*o+1,e=t+1;if(t\u003e=this.nodeIndices.length)break;let n=t;if(e\u003cthis.nodeIndices.length\u0026\u0026this.priorities[e]\u003cthis.priorities[t]\u0026\u0026(n=e),this.priorities[o]\u003c=this.priorities[n])break;this.swap(o,n),o=n}return t}swap(t,e){[this.nodeIndices[t],this.nodeIndices[e]]=[this.nodeIndices[e],this.nodeIndices[t]],[this.priorities[t],this.priorities[e]]=[this.priorities[e],this.priorities[t]]}},Kq=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]],Qq=class extends Sq{problem;searchBounds;rows;columns;origin;nodes=[];open=new Jq;bestCost;closed;closedCellCount=0;targetCell;output=null;constructor(t){super(),this.problem=t;const e=t.traceWidth/2+t.obstacleIndex.clearance,n=Rq(Math.min(t.start.x,t.end.x)-t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),o=Rq(Math.max(t.start.x,t.end.x)+t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),i=Rq(Math.min(t.start.y,t.end.y)-t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),r=Rq(Math.max(t.start.y,t.end.y)+t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),s=Math.floor((n-t.gridOffset.x)/t.gridSize)*t.gridSize+t.gridOffset.x,a=Math.floor((i-t.gridOffset.y)/t.gridSize)*t.gridSize+t.gridOffset.y;if(this.origin={x:s,y:a},this.columns=Math.max(2,Math.floor((o-s)/t.gridSize)+1),this.rows=Math.max(2,Math.floor((r-a)/t.gridSize)+1),this.searchBounds={minX:s,minY:a,maxX:s+(this.columns-1)*t.gridSize,maxY:a+(this.rows-1)*t.gridSize},this.bestCost=new Float64Array(this.rows*this.columns).fill(Number.POSITIVE_INFINITY),this.closed=new Uint8Array(this.rows*this.columns),this.endpointCollides(t.start)||this.endpointCollides(t.end))return this.failed=!0,this.error=\"Grid-route endpoint violates obstacle clearance\",this.targetCell={row:0,column:0},this.MAX_ITERATIONS=1,void(this.stats=this.createStats());const c=this.pointToCell(t.start);this.targetCell=this.pointToCell(t.end);const l={...c,x:t.start.x,y:t.start.y,g:0,f:this.heuristic(t.start),parentIndex:-1};this.nodes.push(l),this.open.push(0,l.f),this.bestCost[this.toFlatIndex(c.row,c.column)]=0,this.MAX_ITERATIONS=Math.min(5e3,Math.max(1e3,this.rows*this.columns*2)),this.stats=this.createStats()}endpointCollides(t){return this.problem.obstacleIndex.collides({start:t,end:t,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance})}getSolverName(){return`ObstacleAwareGridRouteSolver(${this.problem.gridSize.toFixed(3)}mm)`}_step(){if(0===this.open.size)return this.failed=!0,void(this.error=\"No collision-free grid route found\");const t=this.open.pop(),e=this.nodes[t],n=this.toFlatIndex(e.row,e.column);if(!this.closed[n]){if(this.closed[n]=1,this.closedCellCount++,e.row===this.targetCell.row\u0026\u0026e.column===this.targetCell.column\u0026\u0026null!==this.getAllowedConnector(e,this.problem.end))return this.output={points:this.reconstructPath(t),traceWidth:this.problem.traceWidth,gridSize:this.problem.gridSize,gridOffset:this.problem.gridOffset},this.solved=!0,void(this.stats=this.createStats());for(const[n,o]of Kq){const i=e.row+n,r=e.column+o;if(i\u003c0||i\u003e=this.rows||r\u003c0||r\u003e=this.columns)continue;const s=this.toFlatIndex(i,r);if(this.closed[s])continue;const a=this.cellToPoint(i,r),c=this.getAllowedConnector(e,a);if(null===c)continue;const l=-1===e.parentIndex\u0026\u0026this.problem.requireOctilinear?Uq(c):this.problem.gridSize*(0!==n\u0026\u00260!==o?Math.SQRT2:1),d=e.g+l;if(d\u003e=this.bestCost[s])continue;this.bestCost[s]=d;const h=d+this.heuristic(a),u=this.nodes.length;this.nodes.push({row:i,column:r,...a,g:d,f:h,parentIndex:t}),this.open.push(u,h)}this.stats=this.createStats()}}segmentCollides(t,e){return this.problem.obstacleIndex.collides({start:t,end:e,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance})}getAllowedConnector(t,e){return this.problem.requireOctilinear\u0026\u0026(\"parentIndex\"in t\u0026\u0026-1===t.parentIndex||Tq(e,this.problem.end))?qq(t,e).find(t=\u003et.slice(0,-1).every((e,n)=\u003e!this.segmentCollides(e,t[n+1])))??null:this.segmentCollides(t,e)?null:[t,e]}pointToCell(t){return{column:Rq(Math.round((t.x-this.origin.x)/this.problem.gridSize),0,this.columns-1),row:Rq(Math.round((t.y-this.origin.y)/this.problem.gridSize),0,this.rows-1)}}cellToPoint(t,e){return{x:this.origin.x+e*this.problem.gridSize,y:this.origin.y+t*this.problem.gridSize}}toFlatIndex(t,e){return t*this.columns+e}heuristic(t){return Math.hypot(this.problem.end.x-t.x,this.problem.end.y-t.y)}reconstructPath(t){const e=[];let n=t;for(;n\u003e=0;){const t=this.nodes[n];e.push({x:t.x,y:t.y}),n=t.parentIndex}if(e.reverse(),Tq(e[0],this.problem.start)||e.unshift({...this.problem.start}),Tq(e[e.length-1],this.problem.end)||e.push({...this.problem.end}),this.problem.requireOctilinear){const t=[e[0]];for(let n=0;n\u003ce.length-1;n++){const o=e[n],i=e[n+1],r=0===n||n===e.length-2?this.getAllowedConnector(0===n?{...o,parentIndex:-1}:o,i):[o,i];if(!r)return e;t.push(...r.slice(1))}return t.filter((t,e,n)=\u003e{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x);return Math.abs(r)\u003e1e-8||!Hq(o,i)})}const o=[e[0]];let i=0;for(;i\u003ce.length-1;){let t=e.length-1;for(;t\u003ei+1\u0026\u0026this.segmentCollides(e[i],e[t]);)t--;o.push(e[t]),i=t}return o.filter((t,e,n)=\u003e{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x);return Math.abs(r)\u003e1e-8})}createStats(){return{phase:\"obstacle-aware-grid-search\",gridSize:this.problem.gridSize,traceWidth:this.problem.traceWidth,gridOffset:this.problem.gridOffset,openCells:this.open.size,closedCells:this.closedCellCount,gridCells:this.rows*this.columns}}computeProgress(){return Math.min(.99,this.iterations/this.MAX_ITERATIONS)}getOutput(){return this.output}getConstructorParams(){const{obstacleIndex:t,...e}=this.problem;return[e]}visualize(){const t=this.nodes.filter(t=\u003ethis.closed[this.toFlatIndex(t.row,t.column)]).slice(-2e3).map(t=\u003e({x:t.x,y:t.y,color:\"rgba(0,90,255,0.22)\"})),e=this.output?.points??[];return{coordinateSystem:\"cartesian\",title:this.getSolverName(),rects:[{center:{x:(this.searchBounds.minX+this.searchBounds.maxX)/2,y:(this.searchBounds.minY+this.searchBounds.maxY)/2},width:this.searchBounds.maxX-this.searchBounds.minX,height:this.searchBounds.maxY-this.searchBounds.minY,stroke:\"#777\"}],points:[...t,{...this.problem.start,color:\"green\",label:\"reroute start\"},{...this.problem.end,color:\"purple\",label:\"reroute target\"}],lines:e.length\u003e1?[{points:e,strokeColor:\"#00a050\",strokeWidth:this.problem.traceWidth}]:[],circles:[],texts:[]}}},tJ=class{items;clearance;boardEdgeClearance;boardLayers;minViaHoleEdgeToViaHoleEdgeClearance;defaultViaHoleDiameter;bounds;maxIndexedViaHoleDiameter;index;connectionNameSets;copperObjectIds;connectionNameResolver;connectedPads;dynamicTraceIndex;constructor(t,e,n,o=[],i=new Pq(t,e)){var r;this.bounds=t.bounds,this.boardLayers=(r=t.layerCount,[\"top\",...Array.from({length:Math.max(0,r-2)},(t,e)=\u003e`inner${e+1}`),...r\u003e1?[\"bottom\"]:[]]),this.dynamicTraceIndex=n,this.clearance=Math.max(t.defaultObstacleMargin??0,t.minTraceToPadEdgeClearance??0,.1),this.boardEdgeClearance=t.minBoardEdgeClearance??this.clearance,this.minViaHoleEdgeToViaHoleEdgeClearance=Math.max(t.minViaHoleEdgeToViaHoleEdgeClearance??0,.1),this.defaultViaHoleDiameter=t.min_via_hole_diameter??t.minViaHoleDiameter??.3,this.items=[...t.obstacles.flatMap((t,e)=\u003efunction(t,e=.6){const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.max(1,Math.ceil(t.width/e)),i=Math.max(1,Math.ceil(t.height/e)),r=t.width/o,s=t.height/i,a=[];for(let e=0;e\u003ci;e++)for(let i=0;i\u003co;i++){const o={x:t.center.x-t.width/2+(i+.5)*r,y:t.center.y-t.height/2+(e+.5)*s},c=r/2,l=s/2,d=[{x:o.x-c,y:o.y-l},{x:o.x+c,y:o.y-l},{x:o.x+c,y:o.y+l},{x:o.x-c,y:o.y+l}].map(e=\u003eFq(e,t.center,n));a.push({minX:Math.min(...d.map(t=\u003et.x)),minY:Math.min(...d.map(t=\u003et.y)),maxX:Math.max(...d.map(t=\u003et.x)),maxY:Math.max(...d.map(t=\u003et.y)),layers:t.layers,kind:\"obstacle\",obstacleKind:t.connectedTo[0]?.startsWith(\"pcb_via_\")?\"via\":t.connectedTo[0]?.startsWith(\"pcb_smtpad_\")||t.connectedTo[0]?.startsWith(\"pcb_plated_hole_\")?\"pad\":\"other\",connectionNames:t.connectedTo,exactShape:{type:\"polygon\",points:d}})}return a}(t).map(t=\u003e({...t,copperObjectId:`obstacle:${e}`}))),...this.createTraceItems(t.fixedTraces??[],!0),...this.createTraceItems(e),...o],this.maxIndexedViaHoleDiameter=this.items.reduce((t,e)=\u003e\"via\"===e.kind?Math.max(t,e.viaHoleDiameter??this.defaultViaHoleDiameter):t,this.defaultViaHoleDiameter),this.connectionNameResolver=i,this.connectionNameSets=this.items.map(t=\u003enew Set(i.canonicalize(t.connectionNames))),this.copperObjectIds=this.items.map((t,e)=\u003et.copperObjectId??`indexed-item:${e}`),this.connectedPads=t.obstacles.flatMap(t=\u003et.connectedTo.some(t=\u003et.startsWith(\"pcb_smtpad_\")||t.startsWith(\"pcb_plated_hole_\"))?[{obstacle:t,canonicalConnectionNames:new Set(i.canonicalize(t.connectedTo))}]:[]),this.index=this.items.length\u003e0?new Bt(this.items.length):null;for(const t of this.items)this.index.add(t.minX,t.minY,t.maxX,t.maxY);this.index?.finish()}createTraceItems(t,e=!1){const n=[];for(let o=0;o\u003ct.length;o++){const i=t[o],r=e?void 0:o,s=`${e?\"fixed-trace\":\"trace\"}:${o}`,a=!e\u0026\u0026o===this.dynamicTraceIndex,c=[i.connection_name,i.source_trace_id,i.rootConnectionName,...i.mergedConnectionNames??[],...i.connectsTo??[]].filter(t=\u003eBoolean(t));for(let t=0;t\u003ci.route.length;t++){const e=i.route[t];if(\"via\"===e.route_type){const o=e.via_diameter??.6;n.push({minX:e.x-o/2,minY:e.y-o/2,maxX:e.x+o/2,maxY:e.y+o/2,layers:this.boardLayers,kind:\"via\",connectionNames:c,copperObjectId:s,traceIndex:r,routeStartIndex:t,routeEndIndex:t,viaHoleDiameter:e.via_hole_diameter??this.defaultViaHoleDiameter,exactShape:{type:\"circle\",center:{x:e.x,y:e.y},radius:o/2}});continue}if(a)continue;const o=i.route[t+1];\"wire\"===e.route_type\u0026\u0026\"wire\"===o?.route_type\u0026\u0026e.layer===o.layer\u0026\u0026n.push(...zq({start:e,end:o,width:e.width,base:{layers:[e.layer],kind:\"trace\",connectionNames:c,copperObjectId:s,traceIndex:r,routeStartIndex:t,routeEndIndex:t+1}}))}}return n}collides(t){if(this.isOutsideBounds(t))return!0;const{radius:e,candidates:n,canonicalConnectionNames:o}=this.getCollisionCandidates(t);for(const i of n)if(this.itemCollides(i,t,e,o))return!0;return!1}findCollisions(t){const{radius:e,candidates:n,canonicalConnectionNames:o}=this.getCollisionCandidates(t),i=[];for(const r of n)this.itemCollides(r,t,e,o)\u0026\u0026i.push(this.items[r]);return i}getSameNetCopperContactIds(t){const e=t.width/2,n=this.index?.search(Math.min(t.start.x,t.end.x)-e,Math.min(t.start.y,t.end.y)-e,Math.max(t.start.x,t.end.x)+e,Math.max(t.start.y,t.end.y)+e)??[],o=new Set(this.connectionNameResolver.canonicalize(t.connectionNames)),i=new Set;for(const r of n){const n=this.items[r];n.layers.includes(t.layer)\u0026\u0026(n.traceIndex===t.ignoreTraceIndex||t.ignoreTraceIndices?.includes(n.traceIndex??-1)||[...this.connectionNameSets[r]].some(t=\u003eo.has(t))\u0026\u0026this.itemCopperTouches(n,t,e)\u0026\u0026i.add(this.copperObjectIds[r]))}return i}getConnectedPadWidthLimit(t){if(Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y)\u003c=1e-5)return null;const e=this.getConnectedPadWidthLimitAtPoint(t,t.start),n=this.getConnectedPadWidthLimitAtPoint(t,t.end);return null===e?n:null===n?e:Math.min(e,n)}getConnectedPadWidthLimitAtPoint(t,e){const n=this.getConnectedPadsAtPoint(t,e);return 0===n.length?null:Math.max(...n.map(({obstacle:e})=\u003ethis.getPadWidthNormalToQuery(e,t)))}getConnectedPadEndpointWidthLimitAtPoint(t,e){const n=this.getConnectedPadsAtPoint(t,e);return 0===n.length?null:Math.max(...n.map(({obstacle:t})=\u003e{const n=this.getObstacleLocalPoint(e,t);return Math.max(0,2*Math.min(t.width/2-Math.abs(n.x),t.height/2-Math.abs(n.y)))}))}getConnectedPadBoundaryPoint(t,e){const n=\"start\"===e?t.start:t.end,o=\"start\"===e?t.end:t.start,i=this.getConnectedPadsAtPoint(t,n).sort((e,n)=\u003ethis.getPadWidthNormalToQuery(n.obstacle,t)-this.getPadWidthNormalToQuery(e.obstacle,t))[0];return!i||this.pointIsInsideObstacle(o,i.obstacle)?null:this.getObstacleBoundaryPoint(n,o,i.obstacle)}getConnectedPadsAtPoint(t,e){const n=new Set(this.connectionNameResolver.canonicalize(t.connectionNames));return this.connectedPads.filter(({obstacle:o,canonicalConnectionNames:i})=\u003eo.layers.includes(t.layer)\u0026\u0026[...i].some(t=\u003en.has(t))\u0026\u0026this.pointIsInsideObstacle(e,o))}pointIsInsideObstacle(t,e){const{x:n,y:o}=this.getObstacleLocalPoint(t,e);return Math.abs(n)\u003c=e.width/2+1e-9\u0026\u0026Math.abs(o)\u003c=e.height/2+1e-9}getObstacleLocalPoint(t,e){const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=Math.cos(n),i=Math.sin(n),r=t.x-e.center.x,s=t.y-e.center.y;return{x:r*o-s*i,y:r*i+s*o}}getPadWidthNormalToQuery(t,e){const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.hypot(n,o);if(i\u003c=1e-9)return Math.min(t.width,t.height);const r=-o/i,s=n/i,a=-(t.ccwRotationDegrees??0)*Math.PI/180,c=Math.cos(a),l=Math.sin(a),d=r*c-s*l,h=r*l+s*c;return Math.abs(d)*t.width+Math.abs(h)*t.height}getObstacleBoundaryPoint(t,e,n){const o=-(n.ccwRotationDegrees??0)*Math.PI/180,i=Math.cos(o),r=Math.sin(o),s=t=\u003e{const e=t.x-n.center.x,o=t.y-n.center.y;return{x:e*i-o*r,y:e*r+o*i}},a=s(t),c=s(e),l={x:c.x-a.x,y:c.y-a.y},d=[];if(Math.abs(l.x)\u003e1e-12){const t=l.x\u003e0?n.width/2:-n.width/2;d.push((t-a.x)/l.x)}if(Math.abs(l.y)\u003e1e-12){const t=l.y\u003e0?n.height/2:-n.height/2;d.push((t-a.y)/l.y)}const h=Math.min(...d.filter(t=\u003et\u003e=0\u0026\u0026t\u003c=1));return Number.isFinite(h)?{x:t.x+(e.x-t.x)*h,y:t.y+(e.y-t.y)*h}:null}getConnectedLayersAtPoint(t,e){const n=new Set(this.connectionNameResolver.canonicalize(e)),o=new Set,i=this.index?.search(t.x,t.y,t.x,t.y)??[];for(const e of i){const i=this.items[e];if(\"obstacle\"!==i.kind)continue;if(![...this.connectionNameSets[e]].some(t=\u003en.has(t)))continue;if(\"polygon\"===i.exactShape?.type?Lq(t,t,i.exactShape.points)\u003c=1e-9:\"circle\"===i.exactShape?.type?Math.hypot(i.exactShape.center.x-t.x,i.exactShape.center.y-t.y)\u003c=i.exactShape.radius+1e-9:t.x\u003e=i.minX-1e-9\u0026\u0026t.x\u003c=i.maxX+1e-9\u0026\u0026t.y\u003e=i.minY-1e-9\u0026\u0026t.y\u003c=i.maxY+1e-9)for(const t of i.layers)o.add(t)}return[...o]}collidesVia(t){return this.getViaViolationSignatures(t).size\u003e0}getViaViolationSignatures(t){const e=new Set;for(const n of t.layers){const o={start:t.point,end:t.point,layer:n,width:t.padDiameter,connectionNames:t.connectionNames,ignoreTraceIndex:t.ignoreTraceIndex,ignoreTraceIndices:t.ignoreTraceIndices,ignoreRouteRange:t.ignoreRouteRange,obstacleClearance:t.obstacleClearance,blockSameNetObstacles:t.blockSameNetObstacles,sameNetObstacleClearance:t.sameNetObstacleClearance};this.isOutsideBounds(o)\u0026\u0026e.add(`board-edge:${n}`);const{radius:i,candidates:r,canonicalConnectionNames:s}=this.getCollisionCandidates(o);for(const t of r)this.itemCollides(t,o,i,s)\u0026\u0026e.add(`copper:${n}:${this.getViolationObjectId(t)}`)}const n=t.holeDiameter+this.minViaHoleEdgeToViaHoleEdgeClearance;for(const o of t.otherNewViaPoints??[])Math.hypot(o.x-t.point.x,o.y-t.point.y)\u003cn-1e-9\u0026\u0026e.add(`new-via-drill:${o.x},${o.y}:${t.holeDiameter}`);const o=t.fixedVias??[];for(let n=0;n\u003co.length;n++){const i=o[n],r=t.holeDiameter/2+i.holeDiameter/2+this.minViaHoleEdgeToViaHoleEdgeClearance;Math.hypot(i.point.x-t.point.x,i.point.y-t.point.y)\u003cr-1e-9\u0026\u0026e.add(`fixed-via-drill:${n}:${i.point.x},${i.point.y}:${i.holeDiameter}`)}const i=t.holeDiameter/2+this.maxIndexedViaHoleDiameter/2+this.minViaHoleEdgeToViaHoleEdgeClearance,r=this.index?.search(t.point.x-i,t.point.y-i,t.point.x+i,t.point.y+i)??[],s=new Set;for(const n of r){const o=this.items[n];if(\"via\"!==o.kind||\"circle\"!==o.exactShape?.type)continue;if(o.traceIndex===t.ignoreTraceIndex\u0026\u0026t.ignoreRouteRange\u0026\u0026(o.routeEndIndex??-1)\u003e=t.ignoreRouteRange.start\u0026\u0026(o.routeStartIndex??Number.POSITIVE_INFINITY)\u003c=t.ignoreRouteRange.end)continue;if(t.ignoreTraceIndices?.includes(o.traceIndex??-1))continue;const i=`${this.copperObjectIds[n]??\"unknown\"}:${o.routeStartIndex??-1}`;if(s.has(i))continue;s.add(i);const r=o.viaHoleDiameter??this.defaultViaHoleDiameter,a=t.holeDiameter/2+r/2+this.minViaHoleEdgeToViaHoleEdgeClearance;Math.hypot(o.exactShape.center.x-t.point.x,o.exactShape.center.y-t.point.y)\u003ca-1e-9\u0026\u0026e.add(`indexed-via-drill:${this.getViolationObjectId(n)}`)}return e}getViolationObjectId(t){const e=this.items[t],n=this.copperObjectIds[t],o=`${e.routeStartIndex??\"\"}-${e.routeEndIndex??\"\"}`;if(\"obstacle\"===e.kind)return n;if(\"segment\"===e.exactShape?.type){const{start:t,end:i,width:r}=e.exactShape;return`${n}:${e.kind}:${o}:${t.x},${t.y}:${i.x},${i.y}:${r}`}if(\"circle\"===e.exactShape?.type){const{center:t,radius:i}=e.exactShape;return`${n}:${e.kind}:${o}:${t.x},${t.y}:${i}`}return\"polygon\"===e.exactShape?.type?`${n}:${e.kind}:${o}:${e.exactShape.points.map(t=\u003e`${t.x},${t.y}`).join(\";\")}`:`${n}:${e.kind}:${o}:${e.minX},${e.minY},${e.maxX},${e.maxY}`}getCollisionCandidates(t){const e=Math.max(this.clearance,t.obstacleClearance??this.clearance,t.sameNetObstacleClearance??0),n=t.width/2+e,o={minX:Math.min(t.start.x,t.end.x)-n,minY:Math.min(t.start.y,t.end.y)-n,maxX:Math.max(t.start.x,t.end.x)+n,maxY:Math.max(t.start.y,t.end.y)+n};return{radius:n,candidates:this.index?.search(o.minX,o.minY,o.maxX,o.maxY)??[],canonicalConnectionNames:this.connectionNameResolver.canonicalize(t.connectionNames)}}itemCollides(t,e,n,o){const i=this.items[t];if(!i.layers.includes(e.layer))return!1;const r=this.connectionNameSets[t],s=o.some(t=\u003er.has(t));if(s\u0026\u0026(!e.blockSameNetObstacles||\"obstacle\"!==i.kind||\"via\"===i.obstacleKind))return!1;if(\"trace\"===i.kind\u0026\u0026e.ignoreTraceIndices?.includes(i.traceIndex??-1))return!1;if(\"trace\"===i.kind\u0026\u0026i.traceIndex===e.ignoreTraceIndex\u0026\u0026e.ignoreRouteRange\u0026\u0026(i.routeEndIndex??-1)\u003e=e.ignoreRouteRange.start\u0026\u0026(i.routeStartIndex??Number.POSITIVE_INFINITY)\u003c=e.ignoreRouteRange.end)return!1;const a=\"obstacle\"===i.kind\u0026\u0026\"pad\"===i.obstacleKind?s\u0026\u0026e.blockSameNetObstacles?e.sameNetObstacleClearance??e.obstacleClearance??this.clearance:e.obstacleClearance??this.clearance:this.clearance,c=e.width/2+a;return\"segment\"===i.exactShape?.type?Oq(e.start,e.end,i.exactShape.start,i.exactShape.end)\u003c=c+i.exactShape.width/2+1e-9:\"polygon\"===i.exactShape?.type?Lq(e.start,e.end,i.exactShape.points)\u003c=c+1e-9:\"circle\"===i.exactShape?.type?wq(i.exactShape.center,e.start,e.end)\u003c=c+i.exactShape.radius+1e-9:Dq(e.start,e.end,{minX:i.minX-c,minY:i.minY-c,maxX:i.maxX+c,maxY:i.maxY+c})}itemCopperTouches(t,e,n){return\"segment\"===t.exactShape?.type?Oq(e.start,e.end,t.exactShape.start,t.exactShape.end)\u003c=n+t.exactShape.width/2+1e-9:\"polygon\"===t.exactShape?.type?Lq(e.start,e.end,t.exactShape.points)\u003c=n+1e-9:\"circle\"===t.exactShape?.type?wq(t.exactShape.center,e.start,e.end)\u003c=n+t.exactShape.radius+1e-9:Dq(e.start,e.end,{minX:t.minX-n,minY:t.minY-n,maxX:t.maxX+n,maxY:t.maxY+n})}isOutsideBounds(t){const e=t.width/2+this.boardEdgeClearance;return Math.min(t.start.x,t.end.x)-e\u003cthis.bounds.minX||Math.max(t.start.x,t.end.x)+e\u003ethis.bounds.maxX||Math.min(t.start.y,t.end.y)-e\u003cthis.bounds.minY||Math.max(t.start.y,t.end.y)+e\u003ethis.bounds.maxY}},eJ=[{x:0,y:0},{x:.5,y:0},{x:0,y:.5},{x:.5,y:.5}],nJ=t=\u003e\"wire\"===t?.route_type,oJ=class extends Sq{inputProblem;traces;corridor;phase=\"scan-corridor\";corridorCursor=0;blockerCursor=0;offsetCursor=0;resolutionCursor=0;attemptedGridCount=0;blockerIndex;connectionNameResolver;connectionByTraceId=new Map;mutableTraceIndices;blockersByTrace=new Map;blockers=[];currentBlocker=null;currentRange=null;currentTraceWidth=0;gridResolutions=[];currentObstacleIndex=null;output=null;constructor(t,e=new Pq(t.simpleRouteJson,t.traces)){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.corridor=structuredClone(t.corridor),this.mutableTraceIndices=t.mutableTraceIndices?new Set(t.mutableTraceIndices):null,this.connectionNameResolver=e,this.blockerIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,t.powerTraceIndex,[],this.connectionNameResolver),this.activeSubSolver=null,this.MAX_ITERATIONS=25e3,this.stats=this.createStats()}getSolverName(){return\"LocalTraceInflationSolver\"}_step(){if(this.activeSubSolver)return this.stepActiveSubSolver(),void(this.stats=this.createStats());switch(this.phase){case\"scan-corridor\":this.scanNextCorridorSegment();break;case\"select-blocker\":this.selectNextBlocker();break;case\"try-elastic-push\":break;case\"try-grid-candidate\":this.startNextGridCandidate();break;case\"complete\":this.output?this.solved=!0:(this.failed=!0,this.error=\"No locally reroutable trace blocks the power corridor\")}this.stats=this.createStats()}scanNextCorridorSegment(){const t=this.corridor[this.corridorCursor];if(!t)return this.blockers=[...this.blockersByTrace.values()].sort((t,e)=\u003et.traceIndex-e.traceIndex),void(this.phase=\"select-blocker\");const e=this.traces[this.inputProblem.powerTraceIndex],n=this.blockerIndex.findCollisions({start:t.start,end:t.end,layer:t.layer,width:t.width,connectionNames:e?this.getTraceConnectionNames(e):[]});for(const t of n)this.recordBlockingTrace(t);this.corridorCursor++}recordBlockingTrace(t){if(\"trace\"!==t.kind||void 0===t.traceIndex||void 0===t.routeStartIndex||void 0===t.routeEndIndex||t.traceIndex===this.inputProblem.powerTraceIndex||null!==this.mutableTraceIndices\u0026\u0026!this.mutableTraceIndices.has(t.traceIndex))return;const e=this.traces[t.traceIndex];if(!e)return;const n=this.findConnectionForTrace(e);if((n?this.resolveNominalTraceWidth(n):this.getTraceNominalWidth(e))\u003e=(this.inputProblem.pushOnlyNominalWidthsBelow??this.inputProblem.nominalPowerWidth)-Mq)return;const o=this.blockersByTrace.get(t.traceIndex);if(o)return o.firstRouteIndex=Math.min(o.firstRouteIndex,t.routeStartIndex),void(o.lastRouteIndex=Math.max(o.lastRouteIndex,t.routeEndIndex));this.blockersByTrace.set(t.traceIndex,{traceIndex:t.traceIndex,firstRouteIndex:t.routeStartIndex,lastRouteIndex:t.routeEndIndex})}selectNextBlocker(){if(this.currentBlocker=this.blockers[this.blockerCursor]??null,!this.currentBlocker)return void(this.phase=\"complete\");const t=this.findStableAnchorRange(this.currentBlocker);if(!t)return void this.blockerCursor++;const e=this.traces[this.currentBlocker.traceIndex];this.currentRange=t,this.currentTraceWidth=this.getRangeWidth(e,t),this.gridResolutions=this.getGridResolutions(this.currentTraceWidth),this.resolutionCursor=0,this.offsetCursor=0,this.currentObstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,this.currentBlocker.traceIndex,this.createInflatedCorridorItems(),this.connectionNameResolver),this.activeSubSolver=new Wq({trace:e,range:t,layer:e.route[t.startIndex].layer,traceWidth:this.currentTraceWidth,corridor:this.corridor,obstacleIndex:this.currentObstacleIndex,connectionNames:this.getTraceConnectionNames(e)}),this.phase=\"try-elastic-push\"}findStableAnchorRange(t){const e=this.traces[t.traceIndex];if(!e)return null;let n=t.firstRouteIndex,o=t.lastRouteIndex;for(;n\u003e0;){const t=e.route[n];if(nJ(t)\u0026\u0026this.pointClearsCorridor(t))break;n--}for(;o\u003ce.route.length-1;){const t=e.route[o];if(nJ(t)\u0026\u0026this.pointClearsCorridor(t))break;o++}const i=e.route[n],r=e.route[o];if(!nJ(i)||!nJ(r)||i.layer!==r.layer||!this.pointClearsCorridor(i)||!this.pointClearsCorridor(r)||n\u003e=o)return null;const s={startIndex:n,endIndex:o},a=this.getRangeLength(e,s);return!Number.isFinite(a)||a\u003e(this.inputProblem.maxRerouteLength??10)+Mq?null:s}pointClearsCorridor(t){return this.corridor.every(e=\u003e{if(e.layer!==t.layer)return!0;const n=e.width/2+t.width/2+this.blockerIndex.clearance;return wq(t,e.start,e.end)\u003e=n-Mq})}startNextGridCandidate(){if(!this.currentBlocker||!this.currentRange)return void(this.phase=\"select-blocker\");if(this.resolutionCursor\u003e=this.gridResolutions.length)return this.blockerCursor++,void(this.phase=\"select-blocker\");if(this.offsetCursor\u003e=eJ.length)return this.resolutionCursor++,void(this.offsetCursor=0);const t=this.traces[this.currentBlocker.traceIndex],e=t.route[this.currentRange.startIndex],n=t.route[this.currentRange.endIndex];if(!nJ(e)||!nJ(n))return this.blockerCursor++,void(this.phase=\"select-blocker\");const o=this.gridResolutions[this.resolutionCursor],i=eJ[this.offsetCursor],r=this.currentObstacleIndex;if(!r)return this.blockerCursor++,void(this.phase=\"select-blocker\");this.attemptedGridCount++,this.activeSubSolver=new Qq({start:e,end:n,layer:e.layer,traceWidth:this.currentTraceWidth,gridSize:o,gridOffset:{x:i.x*o,y:i.y*o},connectionNames:this.getTraceConnectionNames(t),obstacleIndex:r,ignoreTraceIndex:this.currentBlocker.traceIndex,ignoreRouteRange:{start:this.currentRange.startIndex,end:this.currentRange.endIndex},bounds:this.inputProblem.simpleRouteJson.bounds,searchPadding:Rq(2.5*this.inputProblem.nominalPowerWidth,1.5,4)})}stepActiveSubSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e)return this.applyRoute(e,t instanceof Wq?\"elastic\":\"grid\"),this.activeSubSolver=null,void(this.phase=\"complete\")}this.failedSubSolvers??=[],this.failedSubSolvers.push(t),this.activeSubSolver=null,t instanceof Wq?this.phase=\"try-grid-candidate\":this.offsetCursor++}}applyRoute(t,e){const n=this.currentBlocker,o=this.currentRange,i=this.traces[n.traceIndex],r=i.route[o.startIndex],s=i.route[o.endIndex],a=t.points.map(t=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:this.currentTraceWidth,layer:r.layer}));a[0].width=Math.max(a[0].width,r.width),a[a.length-1].width=Math.max(a[a.length-1].width,s.width),i.route.splice(o.startIndex,o.endIndex-o.startIndex+1,...a),this.output={traces:this.traces,pushedTraceIndex:n.traceIndex,replacedRange:o,strategy:e}}createInflatedCorridorItems(){return this.corridor.flatMap(t=\u003ezq({start:t.start,end:t.end,width:t.width,base:{layers:[t.layer],kind:\"obstacle\",connectionNames:[]}}))}getGridResolutions(t){return[Rq(1.5*t,.1,.3),Rq(.75*t,.08,.18)].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e-t)\u003cMq)===e)}getRangeWidth(t,e){let n=this.inputProblem.simpleRouteJson.minTraceWidth;for(let o=e.startIndex;o\u003c=e.endIndex;o++){const e=t.route[o];nJ(e)\u0026\u0026(n=Math.max(n,e.width))}return n}getRangeLength(t,e){let n=0;for(let o=e.startIndex;o\u003ce.endIndex;o++){const e=t.route[o],i=t.route[o+1];if(!nJ(e)||!nJ(i)||e.layer!==i.layer)return Number.POSITIVE_INFINITY;n+=Nq(e,i)}return n}resolveNominalTraceWidth(t){return Math.max(t.nominalTraceWidth??t.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.inputProblem.simpleRouteJson.minTraceWidth,this.inputProblem.simpleRouteJson.minTraceWidth)}getTraceNominalWidth(t){return t.route.reduce((t,e)=\u003e\"wire\"===e.route_type?Math.max(t,e.width):t,this.inputProblem.simpleRouteJson.minTraceWidth)}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=this.getTraceConnectionNames(t),o=this.inputProblem.simpleRouteJson.connections.find(t=\u003e[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t)).some(t=\u003en.includes(t)))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getTraceConnectionNames(t){return[t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))}createStats(){return{phase:this.phase,corridorSegment:this.corridorCursor,corridorSegmentCount:this.corridor.length,blockingTraceCount:this.blockersByTrace.size,blockerCursor:this.blockerCursor,pushedTraceIndex:this.currentBlocker?.traceIndex,anchorRange:this.currentRange,traceWidth:this.currentTraceWidth,gridSize:this.gridResolutions[this.resolutionCursor],gridOffsetVariant:this.offsetCursor,attemptedGridCount:this.attemptedGridCount}}computeProgress(){return\"scan-corridor\"===this.phase?0===this.corridor.length?.25:this.corridorCursor/this.corridor.length*.25:0===this.blockers.length?.5:Math.min(.99,.25+this.blockerCursor/this.blockers.length)}getOutput(){return this.output}getConstructorParams(){return[this.inputProblem]}visualize(){const t=[];for(let e=0;e\u003cthis.traces.length;e++){const n=this.traces[e];for(let o=0;o\u003cn.route.length-1;o++){const i=n.route[o],r=n.route[o+1];nJ(i)\u0026\u0026nJ(r)\u0026\u0026i.layer===r.layer\u0026\u0026t.push({points:[i,r],strokeColor:e===this.currentBlocker?.traceIndex?\"#1769d2\":\"#777\",strokeWidth:Math.max(i.width,r.width)})}}for(const e of this.corridor)t.push({points:[e.start,e.end],strokeColor:\"rgba(255, 128, 0, 0.55)\",strokeWidth:e.width});return{coordinateSystem:\"cartesian\",title:this.getSolverName(),lines:t,points:[],rects:[],circles:[],texts:[]}}},iJ=1e-6,rJ=(t,e)=\u003eMath.hypot(t.x-e.x,t.y-e.y),sJ=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r\u003c=1e-12?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},aJ=(t,e,n)=\u003e(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),cJ=(t,e,n,o)=\u003e((t,e,n,o)=\u003e{const i=aJ(n,o,t),r=aJ(n,o,e),s=aJ(t,e,n),a=aJ(t,e,o);return(i\u003e0\u0026\u0026r\u003c0||i\u003c0\u0026\u0026r\u003e0)\u0026\u0026(s\u003e0\u0026\u0026a\u003c0||s\u003c0\u0026\u0026a\u003e0)})(t,e,n,o)?0:Math.min(sJ(t,n,o),sJ(e,n,o),sJ(n,t,e),sJ(o,t,e)),lJ=t=\u003e{const e=(t.ccwRotationDegrees??0)*Math.PI/180,n=Math.cos(e),o=Math.sin(e);return[{x:-t.width/2,y:-t.height/2},{x:t.width/2,y:-t.height/2},{x:t.width/2,y:t.height/2},{x:-t.width/2,y:t.height/2}].map(e=\u003e({x:t.center.x+e.x*n-e.y*o,y:t.center.y+e.x*o+e.y*n}))},dJ=t=\u003e{if(!(\"oval\"===t.type||\"circle\"===t.shape))return!1;if(Math.abs(t.width-t.height)\u003eiJ)throw new Error(`Physical connectivity does not yet support non-circular oval obstacle ${t.obstacleId??\"\u003cunknown\u003e\"}`);return!0},hJ=(t,e)=\u003e{for(let n=0;n\u003ce.length;n++)if(sJ(t,e[n],e[(n+1)%e.length])\u003c=iJ)return!0;let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n},uJ=(t,e)=\u003e{if(dJ(e))return Math.max(0,rJ(t,e.center)-e.width/2);const n=lJ(e);return hJ(t,n)?0:Math.min(...n.map((e,o)=\u003esJ(t,e,n[(o+1)%n.length])))},pJ=(t,e)=\u003e{if(dJ(t))return dJ(e)?Math.max(0,rJ(t.center,e.center)-t.width/2-e.width/2):Math.max(0,uJ(t.center,e)-t.width/2);if(dJ(e))return pJ(e,t);const n=lJ(t),o=lJ(e);if(hJ(n[0],o)||hJ(o[0],n))return 0;let i=Number.POSITIVE_INFINITY;for(let t=0;t\u003cn.length;t++)for(let e=0;e\u003co.length;e++)i=Math.min(i,cJ(n[t],n[(t+1)%n.length],o[e],o[(e+1)%o.length]));return i},mJ=(t,e)=\u003e({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),gJ=t=\u003e({minX:t.x,minY:t.y,maxX:t.x,maxY:t.y}),fJ=t=\u003e{if(dJ(t))return mJ(gJ(t.center),t.width/2);const e=lJ(t);return{minX:Math.min(...e.map(t=\u003et.x)),minY:Math.min(...e.map(t=\u003et.y)),maxX:Math.max(...e.map(t=\u003et.x)),maxY:Math.max(...e.map(t=\u003et.y))}},yJ=(t,e)=\u003e{if(!((t,e)=\u003et.layers.some(t=\u003ee.layers.includes(t)))(t,e)||!((t,e)=\u003et.maxX+iJ\u003e=e.minX\u0026\u0026e.maxX+iJ\u003e=t.minX\u0026\u0026t.maxY+iJ\u003e=e.minY\u0026\u0026e.maxY+iJ\u003e=t.minY)(t.bounds,e.bounds))return!1;if(\"bridge-pad\"===t.kind){const n={kind:\"obstacle\",obstacle:t.obstacle,layers:t.layers,bounds:t.bounds};return\"bridge-pad\"===e.kind?yJ(n,{kind:\"obstacle\",obstacle:e.obstacle,layers:e.layers,bounds:e.bounds}):yJ(n,e)}return\"bridge-pad\"===e.kind?yJ(e,t):\"endpoint\"===t.kind?\"endpoint\"===e.kind?rJ(t.point,e.point)\u003c=iJ:\"obstacle\"===e.kind?uJ(t.point,e.obstacle)\u003c=iJ:\"segment\"===e.kind?sJ(t.point,e.start,e.end)\u003c=e.width/2+iJ:rJ(t.point,e.center)\u003c=e.diameter/2+iJ:\"endpoint\"===e.kind?yJ(e,t):\"obstacle\"===t.kind?\"obstacle\"===e.kind?pJ(t.obstacle,e.obstacle)\u003c=iJ:\"segment\"===e.kind?((t,e,n)=\u003e{if(dJ(n))return Math.max(0,sJ(n.center,t,e)-n.width/2);const o=lJ(n);return hJ(t,o)||hJ(e,o)?0:Math.min(...o.map((n,i)=\u003ecJ(t,e,n,o[(i+1)%o.length])))})(e.start,e.end,t.obstacle)\u003c=e.width/2+iJ:uJ(e.center,t.obstacle)\u003c=e.diameter/2+iJ:\"obstacle\"===e.kind?yJ(e,t):\"segment\"===t.kind?\"segment\"===e.kind?cJ(t.start,t.end,e.start,e.end)\u003c=(t.width+e.width)/2+iJ:sJ(e.center,t.start,t.end)\u003c=t.width/2+e.diameter/2+iJ:\"segment\"===e.kind?yJ(e,t):rJ(t.center,e.center)\u003c=(t.diameter+e.diameter)/2+iJ},_J=class{parent;constructor(t){this.parent=Array.from({length:t},(t,e)=\u003ee)}find(t){const e=this.parent[t];if(e===t)return t;const n=this.find(e);return this.parent[t]=n,n}union(t,e){const n=this.find(t),o=this.find(e);n!==o\u0026\u0026(this.parent[o]=n)}},bJ=(t,e)=\u003e{const n=e.indexOf(t.from_layer),o=e.indexOf(t.to_layer);return n\u003c0||o\u003c0?[...new Set([t.from_layer,t.to_layer])]:e.slice(Math.min(n,o),Math.max(n,o)+1)},xJ=t=\u003e[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=\u003eBoolean(t)),vJ=t=\u003e[t.name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],t.netConnectionName,...t.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])].filter(t=\u003eBoolean(t)),SJ=t=\u003e[t.obstacleId,...t.connectedTo,...t.offBoardConnectsTo??[]].filter(t=\u003eBoolean(t)),IJ=(t,e,n,o)=\u003e({kind:\"bridge-contact\",center:{x:t.x,y:t.y},diameter:e,layers:n,bridgeId:o,bounds:mJ(gJ(t),e/2)}),CJ=.01,PJ={\"0603\":{horizontalWidth:.8,horizontalHeight:.95,centerSpacings:[1.65,1.8]},1206:{horizontalWidth:.6,horizontalHeight:1.6,centerSpacings:[3.2]},\"1206x4_pair\":{horizontalWidth:.8,horizontalHeight:.5,centerSpacings:[2.7]}},MJ=(t,e,n)=\u003e{if(!t.layer)throw new Error(`Jumper ${n} is missing its layer`);const o=PJ[t.footprint];if(!o)throw new Error(`Unsupported jumper footprint ${String(t.footprint)} on ${n}`);const i=Math.abs(t.end.x-t.start.x),r=Math.abs(t.end.y-t.start.y),s=t=\u003eo.centerSpacings.some(e=\u003eMath.abs(t-e)\u003cCJ),a=r\u003cCJ\u0026\u0026s(i),c=i\u003cCJ\u0026\u0026s(r);if(!a\u0026\u0026!c)throw new Error(`Jumper ${n} does not match ${t.footprint} pad spacing`);const l={type:\"rect\",center:{...e},width:a?o.horizontalWidth:o.horizontalHeight,height:a?o.horizontalHeight:o.horizontalWidth,layers:[t.layer],connectedTo:[]};return{kind:\"bridge-pad\",obstacle:l,layers:l.layers,bridgeId:n,bounds:fJ(l)}},NJ=(t,e,n)=\u003e{if(t.layer!==n.layer||e.layer!==n.layer)return!1;const o=(t,e)=\u003eMath.abs(t.x-e.x)\u003cCJ\u0026\u0026Math.abs(t.y-e.y)\u003cCJ,i=o(t,n.start)\u0026\u0026o(e,n.end),r=o(t,n.end)\u0026\u0026o(e,n.start);return i||r},wJ=(t,e,n,o)=\u003e{const i=[],r=t.route.flatMap((t,e)=\u003e\"jumper\"===t.route_type?[{routePoint:t,routePointIndex:e}]:[]),s=new Map;for(const e of r){const n=[];for(let o=1;o\u003ct.route.length;o++){const i=t.route[o-1],r=t.route[o];\"wire\"===i?.route_type\u0026\u0026\"wire\"===r?.route_type\u0026\u0026NJ(i,r,e.routePoint)\u0026\u0026n.push(o)}if(1!==n.length)throw new Error(`Jumper ${t.pcb_trace_id}:${e.routePointIndex} matched ${n.length} placeholder wire segments`);const o=n[0];if(s.has(o))throw new Error(`Multiple jumpers matched placeholder segment ${o} on ${t.pcb_trace_id}`);s.set(o,e)}let a;for(let r=0;r\u003ct.route.length;r++){const c=t.route[r];if(\"wire\"===c.route_type){if(a\u0026\u0026a.layer===c.layer\u0026\u0026rJ(a,c)\u003eiJ){const t=a;if(s.get(r));else{const e=t.width/2;i.push({kind:\"segment\",start:{x:t.x,y:t.y},end:{x:c.x,y:c.y},width:t.width,layers:[t.layer],bounds:mJ({minX:Math.min(t.x,c.x),minY:Math.min(t.y,c.y),maxX:Math.max(t.x,c.x),maxY:Math.max(t.y,c.y)},e)})}}a=c;continue}if(a=void 0,\"via\"===c.route_type){const o=t.route[r-1],s=t.route[r+1];for(const e of[o,s])if(\"wire\"===e?.route_type\u0026\u0026rJ(e,c)\u003eiJ)throw new Error(`Via ${t.pcb_trace_id}:${r} is adjacent to a non-colocated wire endpoint`);const a=c.via_diameter??n;i.push({kind:\"via\",center:{x:c.x,y:c.y},diameter:a,layers:bJ(c,e),bounds:mJ(gJ(c),a/2)});continue}const l=`${t.pcb_trace_id}:${r}:${c.route_type}`;if(\"jumper\"===c.route_type){i.push(MJ(c,c.start,l),MJ(c,c.end,l));continue}if(\"through_obstacle\"===c.route_type){if(!o.find(t=\u003et.layers.includes(c.from_layer)\u0026\u0026t.layers.includes(c.to_layer)\u0026\u0026uJ(c.start,t)\u003c=iJ\u0026\u0026uJ(c.end,t)\u003c=iJ))throw new Error(`Through-obstacle marker ${l} has no same-net multilayer obstacle witness`);i.push(IJ(c.start,0,[c.from_layer],l),IJ(c.end,0,[c.to_layer],l));continue}throw new Error(`Unsupported route primitive: ${String(c.route_type)}`)}return i},TJ=(t,e,n)=\u003e{const o=t.pointsToConnect[n];return o.pointId??o.pcb_port_id??`${t.name}[${e}:${n}]`},RJ=t=\u003e{const e={},n={},o=[];for(let i=0;i\u003ct.connections.length;i++){const r=t.connections[i];for(let t=0;t\u003cr.pointsToConnect.length;t++){const s=`${i}:${t}`;e[s]=TJ(r,i,t),n[s]=s,o.push([s])}}return{endpointCount:Object.keys(e).length,endpointLabels:e,componentByEndpointKey:n,endpointComponents:o}},EJ=t=\u003e{if(null===t||\"object\"!=typeof t)return JSON.stringify(t)??String(t);if(Array.isArray(t))return`[${t.map(t=\u003eEJ(t)).join(\",\")}]`;const e=t;return`{${Object.keys(e).sort().map(t=\u003e`${JSON.stringify(t)}:${EJ(e[t])}`).join(\",\")}}`},AJ=(t,e)=\u003e{const n=new Pq(t,e,{includePhysicalPositionAliases:!0}),o=(i=t.layerCount)\u003c=1?[\"top\"]:2===i?[\"top\",\"bottom\"]:[\"top\",...Array.from({length:i-2},(t,e)=\u003e`inner${e+1}`),\"bottom\"];var i;const r=(t=\u003e{const e=t.min_via_hole_diameter??t.minViaHoleDiameter??0;return Math.max(e,t.min_via_pad_diameter??t.minViaPadDiameter??t.minViaDiameter??.6)})(t),s=new Map,a=new Map,c={},l=(t,e)=\u003e{const n=s.get(t)??[];n.push(e),s.set(t,n)};for(let e=0;e\u003ct.connections.length;e++){const o=t.connections[e],i=n.canonicalize(vJ(o));if(1!==i.length)throw new Error(`Connection ${o.name} resolved to ${i.length} canonical nets`);for(let t=0;t\u003co.pointsToConnect.length;t++){const n=o.pointsToConnect[t],r=`${e}:${t}`,s=TJ(o,e,t);c[r]=s;const a={kind:\"endpoint\",endpointKey:r,endpointLabel:s,point:{x:n.x,y:n.y},layers:n.layers??[n.layer],bounds:gJ(n)};for(const t of i)l(t,a)}}for(const e of t.obstacles){const t={kind:\"obstacle\",obstacle:e,layers:e.layers,bounds:fJ(e)};for(const o of n.canonicalize(SJ(e))){const n=a.get(o)??[];n.push(e),a.set(o,n),s.has(o)\u0026\u0026l(o,t)}}for(const i of[...e,...t.fixedTraces??[]]){const t=n.canonicalize(xJ(i));if(1!==t.length)throw new Error(`Trace ${i.pcb_trace_id} resolved to ${t.length} canonical nets`);const e=a.get(t[0])??[],c=wJ(i,o,r,e);for(const e of t)if(s.has(e))for(const t of c)l(e,t)}const d={},h=[];for(const t of s.values()){const e=new _J(t.length),n=new Map;for(let o=0;o\u003ct.length;o++){const i=t[o];if(\"bridge-contact\"!==i.kind\u0026\u0026\"bridge-pad\"!==i.kind)continue;const r=n.get(i.bridgeId);void 0===r?n.set(i.bridgeId,o):e.union(r,o)}const o=t.length\u003e0?new Bt(t.length):null;if(o){for(const e of t)o.add(e.bounds.minX,e.bounds.minY,e.bounds.maxX,e.bounds.maxY);o.finish()}for(let n=0;n\u003ct.length;n++){const i=t[n],r=o?.search(i.bounds.minX-iJ,i.bounds.minY-iJ,i.bounds.maxX+iJ,i.bounds.maxY+iJ)??[];for(const o of r)o\u003c=n||yJ(i,t[o])\u0026\u0026e.union(n,o)}const i=new Map;for(let n=0;n\u003ct.length;n++){const o=t[n];if(\"endpoint\"!==o.kind)continue;const r=e.find(n),s=i.get(r)??[];s.push(o.endpointKey),i.set(r,s)}for(const t of i.values()){t.sort();const e=t[0];h.push(t);for(const n of t){if(void 0!==d[n])throw new Error(`Endpoint ${n} was assigned to multiple canonical nets`);d[n]=e}}}return h.sort(([t=\"\"],[e=\"\"])=\u003et.localeCompare(e)),{endpointCount:Object.keys(c).length,endpointLabels:c,componentByEndpointKey:d,endpointComponents:h}},OJ=class{baseline;inputProblem;baselineCaptureError;baselineTraceSignature;constructor(t,e){this.inputProblem=t,this.baselineTraceSignature=EJ(e);try{this.baseline=AJ(t,e),this.baselineCaptureError=null}catch(e){this.baseline=RJ(t),this.baselineCaptureError=e instanceof Error?e.message:String(e)}}validate(t){if(this.baselineCaptureError){const e=EJ(t)===this.baselineTraceSignature;return{safe:e,candidate:this.baseline,regressions:[],validationError:e?`Connectivity validation is limited to exact trace preservation: ${this.baselineCaptureError}`:`Connectivity validation failed closed: ${this.baselineCaptureError}`}}let e;try{e=AJ(this.inputProblem,t)}catch(t){return{safe:!1,candidate:RJ(this.inputProblem),regressions:[],validationError:`Connectivity validation failed closed: ${t instanceof Error?t.message:String(t)}`}}const n=[];for(const t of this.baseline.endpointComponents){if(t.length\u003c2)continue;const o=new Map;for(const n of t){const t=e.componentByEndpointKey[n]??`missing:${n}`,i=o.get(t)??[];i.push(n),o.set(t,i)}o.size\u003c=1||n.push({baselineEndpointKeys:[...t],baselineEndpointLabels:t.map(t=\u003ethis.baseline.endpointLabels[t]),candidateComponents:[...o.values()]})}return{safe:0===n.length,candidate:e,regressions:n}}},kJ=[{x:0,y:0},{x:.5,y:.5}],LJ=[.15,.2,.25,.3,.4,.5],DJ=t=\u003e\"wire\"===t?.route_type,zJ=t=\u003e\"via\"===t?.route_type,FJ=Array.from({length:24},(t,e)=\u003e{const n=e*Math.PI/12;return{x:Math.cos(n),y:Math.sin(n)}}),BJ=t=\u003e[...new Set(t.map(t=\u003eNumber(t.toFixed(6))))].sort((t,e)=\u003ee-t),jJ=class extends Sq{inputProblem;traces;obstacleIndex;phase=\"repair-vias\";traceCursor=0;routeCursor=0;candidateCursor=0;clearanceTierCursor=0;attemptedCandidateCount=0;attemptedClearanceShoveCount=0;attemptedViaGridCount=0;committedClearanceShoveCount=0;viaPairCountRemoved=0;viaCountRemoved=0;simplifiedPathCount=0;normalizedSegmentCount=0;achievedExtraClearanceCount=0;relocatedViaCount=0;unresolvedViaCount=0;attemptedPushedViaRepairCount=0;committedPushedViaRepairCount=0;padClearanceRerouteCount=0;unresolvedPadClearanceCount=0;initialPadClearanceViolationCount=0;remainingPadClearanceViolationCount=0;initialPadClearanceViolationCountByClearance={};remainingPadClearanceViolationCountByClearance={};budgetLimited=!1;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;connectionNameResolver;connectionByTraceId=new Map;connectivityInvariant;initialConnectivitySafeTraces;mutableTraceIndices;mutableTraceIndexSet;viaRepairTraceIndices;traceIndices;maxRerouteLength;clearancePaddingTiers;desiredPadClearance;initialTraceLengths=new Map;candidates=[];candidateShoveCount=0;rollbackTraces=null;baseCandidateValidated=!1;activeShovePadding=0;viaGridAttempt=null;candidateSetMayUseGridFallback=!1;pendingPushedViaRepair=null;alternatePushedViaRepairs=[];pushedViaRepairRollbackTraces=null;connectivityFinalized=!1;finalizedMutatedTraceIndices=[];resumePhase=\"scan-via-pairs\";constructor(t){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.initialConnectivitySafeTraces=structuredClone(t.traces),this.connectivityInvariant=new OJ(this.inputProblem.simpleRouteJson,this.initialConnectivitySafeTraces),this.connectionNameResolver=new Pq(t.simpleRouteJson,this.traces),this.maxRerouteLength=t.maxRerouteLength??10,this.desiredPadClearance=t.desiredPadClearance,this.clearancePaddingTiers=BJ([...t.clearancePaddingTiers??[.1,.05,0],0]).filter(t=\u003et\u003e=0);const e=this.traces.map((t,e)=\u003ee),n=(t,e,n)=\u003e{const o=[...new Set(t??n)];for(const t of o)if(!Number.isInteger(t)||t\u003c0||t\u003e=this.traces.length)throw new RangeError(`Invalid cleanup ${e} index: ${t}`);return o},o=n(t.traceIndices,\"trace\",e);this.viaRepairTraceIndices=n(t.viaRepairTraceIndices,\"via repair trace\",o),this.mutableTraceIndices=n(t.mutableTraceIndices,\"mutable trace\",o),this.mutableTraceIndexSet=new Set(this.mutableTraceIndices),this.traceIndices=o.filter(t=\u003ethis.resolveNominalTraceWidth(this.traces[t])\u003e=.499999);for(const t of this.traceIndices)this.initialTraceLengths.set(t,this.measureTraceLength(this.traces[t]));this.obstacleIndex=this.createObstacleIndex(),this.initialPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCount=this.initialPadClearanceViolationCount,this.initialPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.remainingPadClearanceViolationCountByClearance={...this.initialPadClearanceViolationCountByClearance},this.activeSubSolver=null,this.MAX_ITERATIONS=1e6,this.stats=this.createStats()}getSolverName(){return\"PowerTraceCleanupSolver\"}_step(){if(this.activeSubSolver)return this.stepActiveShoveSolver(),void(this.stats=this.createStats());switch(this.phase){case\"repair-vias\":this.repairNextVia();break;case\"scan-via-pairs\":this.scanNextViaPair();break;case\"scan-pad-clearance\":this.scanNextPadClearance();break;case\"scan-simplification\":this.scanNextSimplification();break;case\"evaluate-candidate\":this.evaluateCurrentCandidate();break;case\"shove-clearance\":break;case\"route-via-pair\":this.startNextViaGridCandidate();break;case\"complete\":this.ensureConnectivitySafeOutput(),this.solved=!0}this.stats=this.createStats()}repairNextVia(){const t=this.viaRepairTraceIndices[this.traceCursor],e=void 0===t?void 0:this.traces[t];if(!e)return this.traceCursor=0,this.routeCursor=0,this.phase=\"scan-via-pairs\",void this.rebuildObstacleIndex();const n=e.route.findIndex((t,e)=\u003ee\u003e=this.routeCursor\u0026\u0026zJ(t));if(-1===n)return this.traceCursor++,void(this.routeCursor=0);this.routeCursor=n+1;const o=e.route[n],i=e.route[n-1],r=e.route[n+1];if(!zJ(o)||!DJ(i)||!DJ(r))return;const s=this.getTraceConnectionNames(e),a=this.getBaseObstacleClearance();if(!this.obstacleIndex.collidesVia({point:o,layers:this.obstacleIndex.boardLayers,padDiameter:o.via_diameter??.6,holeDiameter:o.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,connectionNames:s,ignoreTraceIndex:t,ignoreRouteRange:{start:n,end:n},obstacleClearance:a,blockSameNetObstacles:!0,sameNetObstacleClearance:0}))return;const c=this.findViaRepair(e,n,a);if(!c){const t=this.findPushableViaRepairs(e,n,a),o=t.shift();return o?(this.alternatePushedViaRepairs=t,void this.startPushedViaRepair(o)):void this.unresolvedViaCount++}e.route.splice(c.startIndex,c.endIndex-c.startIndex+1,...c.route),this.relocatedViaCount++,this.routeCursor=c.startIndex+c.route.length,this.rebuildObstacleIndex()}findViaRepair(t,e,n){const o=this.createViaRepairContext(t,e);if(!o)return null;const i=o.candidates.map(t=\u003e({point:t,movedLength:Nq(o.leftAnchor,t)+Nq(t,o.rightAnchor)})).filter(({movedLength:t})=\u003et\u003c=o.originalLength+Math.min(6,this.maxRerouteLength)+Mq);i.sort((t,e)=\u003et.movedLength-e.movedLength||Nq(t.point,o.via)-Nq(e.point,o.via));for(const t of i)if(this.isViaRepairPointSafe(o,t.point,n))return this.createViaRepairReplacement(o,t.point);return null}findPushableViaRepairs(t,e,n){const o=this.viaRepairTraceIndices[this.traceCursor];if(void 0===o)return[];const i=this.createViaRepairContext(t,e);if(!i)return[];const r=i.candidates.flatMap(t=\u003e{const e=Nq(i.leftAnchor,t)+Nq(t,i.rightAnchor);if(e\u003ei.originalLength+Math.min(6,this.maxRerouteLength)+Mq)return[];const r=new Set,s=this.getViaRepairCollisionQueries(i,t,n);for(const t of s)for(const e of this.obstacleIndex.findCollisions(t)){if(\"trace\"!==e.kind||void 0===e.traceIndex||e.traceIndex===o||!this.mutableTraceIndexSet.has(e.traceIndex))return[];r.add(e.traceIndex)}if(0===r.size||r.size\u003e2)return[];const a=[...r];return this.isViaRepairPointSafe(i,t,n,a)?[{point:t,movedLength:e,blockerCount:r.size,blockerKey:[...r].sort((t,e)=\u003et-e).join(\",\")}]:[]});r.sort((t,e)=\u003et.blockerCount-e.blockerCount||t.movedLength-e.movedLength||Nq(t.point,i.via)-Nq(e.point,i.via));return[...new Map([...r].reverse().map(t=\u003e[t.blockerKey,t])).values(),...r].filter((t,e,n)=\u003en.findIndex(e=\u003ee.point.x===t.point.x\u0026\u0026e.point.y===t.point.y)===e).slice(0,12).map(t=\u003e({traceIndex:o,viaIndex:e,point:t.point,padClearance:n,corridor:[{start:i.leftAnchor,end:t.point,layer:i.leftWire.layer,width:i.leftWire.width},{start:t.point,end:i.rightAnchor,layer:i.rightWire.layer,width:i.rightWire.width},...this.obstacleIndex.boardLayers.map(e=\u003e({start:t.point,end:t.point,layer:e,width:i.viaDiameter}))]}))}createViaRepairContext(t,e){const n=t.route[e],o=t.route[e-1],i=t.route[e+1];if(!zJ(n)||!DJ(o)||!DJ(i))return null;const r=e-1==0||!DJ(t.route[e-2]),s=e+1===t.route.length-1||!DJ(t.route[e+2]),a=r?o:t.route[e-2],c=s?i:t.route[e+2],l=Nq(a,n)+Nq(n,c),d=this.getTraceConnectionNames(t),h=n.via_diameter??.6,u=n.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,p=Math.max(.3,u+this.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance+.05),m=[p,p+.15,p+.3,p+.5,p+.75,p+1,p+1.5,p+2].flatMap(t=\u003eFJ.map(e=\u003e({x:.025*Math.round((n.x+e.x*t)/.025),y:.025*Math.round((n.y+e.y*t)/.025)}))),g=[...m,...m.flatMap(t=\u003e[{x:t.x,y:Math.floor(10*n.y)/10},{x:t.x,y:Math.ceil(10*n.y)/10},{x:Math.floor(10*n.x)/10,y:t.y},{x:Math.ceil(10*n.x)/10,y:t.y}])].filter((t,e,n)=\u003en.findIndex(e=\u003ee.x===t.x\u0026\u0026e.y===t.y)===e);return{trace:t,viaIndex:e,via:n,leftWire:o,rightWire:i,leftIsEndpoint:r,rightIsEndpoint:s,leftAnchor:a,rightAnchor:c,originalLength:l,connectionNames:d,viaDiameter:h,holeDiameter:u,ignoreRouteRange:{start:Math.max(0,e-2),end:Math.min(t.route.length-1,e+2)},candidates:g}}getViaRepairCollisionQueries(t,e,n,o){const i=this.viaRepairTraceIndices[this.traceCursor],r={connectionNames:t.connectionNames,ignoreTraceIndex:i,ignoreTraceIndices:o,ignoreRouteRange:t.ignoreRouteRange,obstacleClearance:n};return[...this.obstacleIndex.boardLayers.map(n=\u003e({...r,start:e,end:e,layer:n,width:t.viaDiameter,blockSameNetObstacles:!0,sameNetObstacleClearance:0})),{...r,start:t.leftAnchor,end:e,layer:t.leftWire.layer,width:t.leftWire.width},{...r,start:e,end:t.rightAnchor,layer:t.rightWire.layer,width:t.rightWire.width}]}isViaRepairPointSafe(t,e,n,o){const i=this.viaRepairTraceIndices[this.traceCursor];return!this.obstacleIndex.collidesVia({point:e,layers:this.obstacleIndex.boardLayers,padDiameter:t.viaDiameter,holeDiameter:t.holeDiameter,connectionNames:t.connectionNames,ignoreTraceIndex:i,ignoreTraceIndices:o,ignoreRouteRange:{start:t.viaIndex,end:t.viaIndex},obstacleClearance:n,blockSameNetObstacles:!0,sameNetObstacleClearance:0})\u0026\u0026!this.getViaRepairCollisionQueries(t,e,n,o).slice(this.obstacleIndex.boardLayers.length).some(t=\u003ethis.obstacleIndex.collides(t))}createViaRepairReplacement(t,e){const n={...t.leftWire,...e},o={...t.via,...e},i={...t.rightWire,...e};return{startIndex:t.viaIndex-1,endIndex:t.viaIndex+1,route:[...t.leftIsEndpoint?[t.leftWire]:[],n,o,i,...t.rightIsEndpoint?[t.rightWire]:[]]}}startPushedViaRepair(t){this.pendingPushedViaRepair=t,this.pushedViaRepairRollbackTraces=structuredClone(this.traces),this.attemptedPushedViaRepairCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem.simpleRouteJson,traces:this.traces,powerTraceIndex:t.traceIndex,nominalPowerWidth:Math.max(...t.corridor.map(t=\u003et.width)),pushOnlyNominalWidthsBelow:Number.POSITIVE_INFINITY,mutableTraceIndices:this.mutableTraceIndices,corridor:t.corridor,maxRerouteLength:this.maxRerouteLength},this.connectionNameResolver)}finishPushedViaRepairSolver(t){const e=this.pendingPushedViaRepair;if(this.activeSubSolver=null,!e)return;if(t.solved){const n=t.getOutput();if(n){this.traces=n.traces,this.rebuildObstacleIndex();const t=this.traces[e.traceIndex],o=t?this.createViaRepairContext(t,e.viaIndex):null;if(o\u0026\u0026this.isViaRepairPointSafe(o,e.point,e.padClearance)){const n=this.createViaRepairReplacement(o,e.point);return t.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...n.route),this.relocatedViaCount++,this.committedPushedViaRepairCount++,this.routeCursor=n.startIndex+n.route.length,this.pendingPushedViaRepair=null,this.alternatePushedViaRepairs=[],this.pushedViaRepairRollbackTraces=null,void this.rebuildObstacleIndex()}}}this.pushedViaRepairRollbackTraces\u0026\u0026(this.traces=this.pushedViaRepairRollbackTraces),this.pendingPushedViaRepair=null,this.pushedViaRepairRollbackTraces=null;const n=this.alternatePushedViaRepairs.shift();if(n)return this.rebuildObstacleIndex(),void this.startPushedViaRepair(n);this.alternatePushedViaRepairs=[],this.unresolvedViaCount++,this.rebuildObstacleIndex()}scanNextViaPair(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.traceCursor=0,this.routeCursor=0,void(this.phase=\"scan-pad-clearance\");const e=this.traces[t],n=e.route.findIndex((t,e)=\u003ee\u003e=this.routeCursor\u0026\u0026\"via\"===t.route_type);if(-1===n)return void this.advanceTrace();const o=e.route.slice(n+1).findIndex(t=\u003e\"via\"===t.route_type);if(-1===o)return void this.advanceTrace();const i=n-1,r=n+1+o+1,s=e.route[i],a=e.route[r];if(this.routeCursor=n+1,!DJ(s)||!DJ(a)||s.layer!==a.layer||Nq(s,a)\u003ethis.maxRerouteLength+Mq)return;const c=this.createCandidates({kind:\"via-pair\",traceIndex:t,startIndex:i,endIndex:r}),l=c[0]?.width??Math.max(s.width,a.width),d=c[0]?.padClearance??this.getCandidatePadClearance(\"via-pair\",t,i,r),h=n=\u003e{const o=e.route[n];return!!DJ(o)\u0026\u0026this.obstacleIndex.findCollisions({start:o,end:o,layer:o.layer,width:l,connectionNames:this.getTraceConnectionNames(e),ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,i-1),end:Math.min(e.route.length-1,r+1)},obstacleClearance:d}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind)},u=e.route[i-1],p=e.route[r+1],m=c.length\u003e0\u0026\u0026h(i)\u0026\u0026DJ(u)\u0026\u0026u.layer===s.layer?i-1:i,g=c.length\u003e0\u0026\u0026h(r)\u0026\u0026DJ(p)\u0026\u0026p.layer===a.layer?r+1:r,f=[{startIndex:i,endIndex:r},{startIndex:m,endIndex:r},{startIndex:i,endIndex:g},{startIndex:m,endIndex:g}].filter((t,e,n)=\u003en.findIndex(e=\u003ee.startIndex===t.startIndex\u0026\u0026e.endIndex===t.endIndex)===e).flatMap(e=\u003ee.startIndex===i\u0026\u0026e.endIndex===r?c:this.createCandidates({kind:\"via-pair\",traceIndex:t,startIndex:e.startIndex,endIndex:e.endIndex}));0!==f.length\u0026\u0026this.beginCandidates(f,\"scan-via-pairs\",!0)}scanNextPadClearance(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.traceCursor=0,this.routeCursor=0,void(this.phase=\"scan-simplification\");const e=this.traces[t];if(this.resolveNominalTraceWidth(e)\u003c.499999)return void this.advanceTrace();const n=this.routeCursor,o=e.route[n],i=e.route[n+1];if(!DJ(o)||!DJ(i)||o.layer!==i.layer)return void(n\u003e=e.route.length-1?this.advanceTrace():this.routeCursor++);if(this.routeCursor++,!this.segmentHasPadClearanceViolation(t,n))return;const r=this.getPadClearanceIntervals(e,n).flatMap(e=\u003ethis.getImprovedPadClearanceTiers(t,e.startIndex,e.endIndex).flatMap(n=\u003ethis.createCandidates({kind:\"pad-clearance\",traceIndex:t,startIndex:e.startIndex,endIndex:e.endIndex,padClearance:n}).slice(0,8)));0!==r.length?this.beginCandidates(r.slice(0,72),\"scan-pad-clearance\",!0):this.unresolvedPadClearanceCount++}segmentHasPadClearanceViolation(t,e){const n=this.traces[t],o=n.route[e],i=n.route[e+1];return!(!DJ(o)||!DJ(i)||o.layer!==i.layer)\u0026\u0026this.obstacleIndex.findCollisions({start:o,end:i,layer:o.layer,width:Math.max(o.width,i.width),connectionNames:this.getTraceConnectionNames(n),ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,e-1),end:Math.min(n.route.length-1,e+2)},obstacleClearance:this.getPadClearanceForTrace(n)}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind)}getPadClearanceIntervals(t,e){const n=t.route[e];if(!DJ(n))return[];const o=[e];let i=0;for(let r=e-1;r\u003e=0;r--){const e=t.route[r],s=t.route[r+1];if(!DJ(e)||!DJ(s)||e.layer!==n.layer||s.layer!==n.layer)break;if(i+=Nq(e,s),i\u003ethis.maxRerouteLength/2+Mq)break;o.push(r)}const r=[e+1];i=0;for(let o=e+1;o\u003ct.route.length-1;o++){const e=t.route[o],s=t.route[o+1];if(!DJ(e)||!DJ(s)||e.layer!==n.layer||s.layer!==n.layer)break;if(i+=Nq(e,s),i\u003ethis.maxRerouteLength/2+Mq)break;r.push(o+1)}return o.flatMap(e=\u003er.map(n=\u003e({startIndex:e,endIndex:n,length:this.measureRouteRange(t,e,n).length}))).filter(t=\u003et.length\u003c=this.maxRerouteLength+Mq\u0026\u0026t.startIndex\u003ct.endIndex).sort((t,e)=\u003ee.length-t.length).slice(0,8)}scanNextSimplification(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),void(this.phase=\"complete\");const e=this.traces[t],n=this.routeCursor,o=e.route[n];if(!DJ(o)||n\u003e=e.route.length-1)return void(n\u003e=e.route.length-1?this.advanceTrace():this.routeCursor++);let i=0;const r=[];for(let t=n+1;t\u003ce.route.length;t++){const s=e.route[t-1],a=e.route[t];if(!DJ(s)||!DJ(a)||s.layer!==o.layer||a.layer!==o.layer)break;if(i+=Nq(s,a),i\u003ethis.maxRerouteLength+Mq)break;const c=this.measureRouteRange(e,n,t);(c.nonOctilinearSegmentCount\u003e0||c.pointCount\u003e3)\u0026\u0026r.push(t)}const s=r.slice(-6).reverse().flatMap(e=\u003ethis.createCandidates({kind:\"simplification\",traceIndex:t,startIndex:n,endIndex:e}));0!==s.length?this.beginCandidates(s,\"scan-simplification\"):this.routeCursor++}createCandidates({kind:t,traceIndex:e,startIndex:n,endIndex:o,padClearance:i}){const r=this.traces[e],s=r.route[n],a=r.route[o];if(!DJ(s)||!DJ(a)||s.layer!==a.layer)return[];const c=this.resolveNominalTraceWidth(r),l=this.measureRouteRange(r,n,o),d=i??this.getCandidatePadClearance(t,e,n,o),h=[],u=qq(s,a);if(\"pad-clearance\"===t\u0026\u00260===Gq([s,a])){const t=Nq(s,a);if(t\u003eMq){const e={x:-(a.y-s.y)/t,y:(a.x-s.x)/t};for(const t of[.25,.5,.75,1,1.5,2])for(const n of[-1,1])u.push([s,{x:s.x+e.x*t*n,y:s.y+e.y*t*n},{x:a.x+e.x*t*n,y:a.y+e.y*t*n},a])}}const p=new Map(u.map(t=\u003e[t.map(t=\u003e`${t.x.toFixed(6)},${t.y.toFixed(6)}`).join(\";\"),t]));for(const i of p.values()){const u=Uq(i);if(u\u003ethis.maxRerouteLength+Mq||\"pad-clearance\"===t\u0026\u0026u\u003e1.35*l.length+.5||\"simplification\"===t\u0026\u0026(u\u003e1.1*l.length+Mq||this.measureTraceLength(r)-l.length+u\u003e1.01*(this.initialTraceLengths.get(e)??this.measureTraceLength(r))+Mq))continue;const p=u\u003c=Mq?c:c-l.deficitArea/u;if(p\u003ec+Mq)continue;const m=.05*Math.ceil(Math.max(this.inputProblem.simpleRouteJson.minTraceWidth,p)/.05-Mq),g=BJ([c,Math.min(c,m),Math.min(c,Math.max(this.inputProblem.simpleRouteJson.minTraceWidth,p))].map(t=\u003eMath.max(t,s.width)));for(const r of g){const u=this.measureCandidate(i,r,c,a.width,s.width);u.deficitArea\u003el.deficitArea+Mq||u.conservativeDeficitArea\u003el.conservativeDeficitArea+Mq||!this.preservesCoverage(u,l)||(\"simplification\"!==t||0!==l.nonOctilinearSegmentCount||u.pointCount\u003cl.pointCount\u0026\u0026u.length\u003cl.length-Mq)\u0026\u0026h.push({kind:t,traceIndex:e,startIndex:n,endIndex:o,layer:s.layer,points:i,width:r,padClearance:d,originalQuality:l})}}return h.slice(0,18)}beginCandidates(t,e,n=!1){this.candidates=t,this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.rollbackTraces=null,this.baseCandidateValidated=!1,this.resumePhase=e,this.candidateSetMayUseGridFallback=n,this.phase=\"evaluate-candidate\"}evaluateCurrentCandidate(){const t=this.candidates[this.candidateCursor];if(!t)return void this.finishCandidateSet(!1);if(!this.baseCandidateValidated){if(!this.candidateCollides(t,0))return this.candidateShoveCount\u003e0?void this.applyCandidate(t,0):(this.baseCandidateValidated=!0,void(this.clearanceTierCursor=0));return this.getPushableTraceIndices(t,0)\u0026\u0026this.candidateShoveCount\u003c2\u0026\u0026this.attemptedClearanceShoveCount\u003c48?void this.startClearanceShove(t,0):void this.advanceCandidate()}const e=this.clearancePaddingTiers[this.clearanceTierCursor];if(void 0===e||e\u003c=Mq)return void this.applyCandidate(t,0);if(this.attemptedCandidateCount++,!this.candidateCollides(t,e))return void this.applyCandidate(t,e);this.getPushableTraceIndices(t,e)\u0026\u0026this.candidateShoveCount\u003c2\u0026\u0026this.attemptedClearanceShoveCount\u003c48?this.startClearanceShove(t,e):(this.rollbackCandidateShoves(),this.clearanceTierCursor++,this.candidateShoveCount=0)}advanceCandidate(){this.rollbackCandidateShoves(),this.candidateCursor++,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1}candidateCollides(t,e){const n=this.traces[t.traceIndex],o=this.getTraceConnectionNames(n);for(let i=0;i\u003ct.points.length-1;i++){const r=this.getCandidateSegmentWidth(t,i);if(this.obstacleIndex.collides({start:t.points[i],end:t.points[i+1],layer:t.layer,width:r+2*e,connectionNames:o,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(n.route.length-1,t.endIndex+1)},obstacleClearance:t.padClearance}))return!0}return!1}getPushableTraceIndices(t,e){const n=this.traces[t.traceIndex],o=this.getTraceConnectionNames(n),i=new Set;for(let r=0;r\u003ct.points.length-1;r++){const s=this.getCandidateSegmentWidth(t,r),a={start:t.points[r],end:t.points[r+1],layer:t.layer,width:s+2*e,connectionNames:o,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(n.route.length-1,t.endIndex+1)},obstacleClearance:t.padClearance};if(!this.obstacleIndex.collides(a))continue;const c=this.obstacleIndex.findCollisions(a);if(0===c.length)return null;for(const e of c){if(\"trace\"!==e.kind||void 0===e.traceIndex||e.traceIndex===t.traceIndex||!this.mutableTraceIndexSet.has(e.traceIndex))return null;const n=this.traces[e.traceIndex];if(!n||this.resolveNominalTraceWidth(n)\u003e=t.width-Mq)return null;i.add(e.traceIndex)}}return i.size\u003e0\u0026\u0026i.size\u003c=2?[...i]:null}startClearanceShove(t,e){this.rollbackTraces??=structuredClone(this.traces),this.activeShovePadding=e;const n=t.width+2*e,o=t.points.slice(0,-1).map((n,o)=\u003e({start:n,end:t.points[o+1],layer:t.layer,width:this.getCandidateSegmentWidth(t,o)+2*e}));this.attemptedClearanceShoveCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem.simpleRouteJson,traces:this.traces,powerTraceIndex:t.traceIndex,nominalPowerWidth:n,pushOnlyNominalWidthsBelow:t.width,mutableTraceIndices:this.mutableTraceIndices,corridor:o,maxRerouteLength:this.maxRerouteLength},this.connectionNameResolver),this.phase=\"shove-clearance\"}getCandidateSegmentWidth(t,e){const n=this.traces[t.traceIndex],o=n.route[t.startIndex],i=n.route[t.endIndex],r=0===e\u0026\u0026DJ(o)?o.width:t.width,s=e===t.points.length-2\u0026\u0026DJ(i)?i.width:t.width;return Math.max(r,s)}stepActiveShoveSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed)if(this.pendingPushedViaRepair\u0026\u0026t instanceof oJ)this.finishPushedViaRepairSolver(t);else if(t instanceof Qq)this.finishViaGridSolver(t);else{if(this.activeSubSolver=null,this.phase=\"evaluate-candidate\",t.solved){const e=t.getOutput();if(e)return this.traces=e.traces,this.candidateShoveCount++,void this.rebuildObstacleIndex()}this.failedSubSolvers??=[],this.failedSubSolvers.push(t),this.rollbackCandidateShoves(),this.activeShovePadding\u003c=Mq?this.advanceCandidate():this.clearanceTierCursor++,this.candidateShoveCount=0}}rollbackCandidateShoves(){this.rollbackTraces\u0026\u0026(this.traces=this.rollbackTraces,this.rollbackTraces=null,this.rebuildObstacleIndex())}applyCandidate(t,e){const n=this.traces[t.traceIndex],o=n.route[t.startIndex],i=n.route[t.endIndex],r=t.points.map((e,n)=\u003e({...0===n?o:n===t.points.length-1?i:{route_type:\"wire\",layer:t.layer,width:t.width},x:e.x,y:e.y,layer:t.layer,width:0===n?o.width:n===t.points.length-1?i.width:t.width})),s=n.route.slice(t.startIndex,t.endIndex+1),a=t.originalQuality.nonOctilinearSegmentCount;if(n.route.splice(t.startIndex,t.endIndex-t.startIndex+1,...r),\"via-pair\"===t.kind){const e=s.filter(t=\u003e\"via\"===t.route_type).length;this.viaPairCountRemoved++,this.viaCountRemoved+=e,this.routeCursor=Math.max(0,t.startIndex-1)}else\"pad-clearance\"===t.kind?(this.padClearanceRerouteCount++,this.routeCursor=t.startIndex+Math.max(1,r.length-1)):(this.simplifiedPathCount++,this.normalizedSegmentCount+=a,this.routeCursor=t.startIndex+Math.max(1,r.length-1));this.committedClearanceShoveCount+=this.candidateShoveCount,e\u003eMq\u0026\u0026this.achievedExtraClearanceCount++,this.rollbackTraces=null,this.candidateShoveCount=0,this.rebuildObstacleIndex(),this.finishCandidateSet(!0)}finishCandidateSet(t){const e=this.candidates[0],n=BJ(this.candidates.filter(t=\u003et.kind===e?.kind).map(t=\u003et.width)),o=BJ(this.candidates.filter(t=\u003et.kind===e?.kind\u0026\u0026t.traceIndex===e.traceIndex\u0026\u0026t.startIndex===e.startIndex\u0026\u0026t.endIndex===e.endIndex).map(t=\u003et.padClearance));if(this.rollbackCandidateShoves(),this.candidates=[],this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1,!t\u0026\u0026this.candidateSetMayUseGridFallback\u0026\u0026e)return this.candidateSetMayUseGridFallback=!1,void this.beginViaGridAttempt(e,n,o);this.candidateSetMayUseGridFallback=!1,t||this.routeCursor++,this.phase=this.resumePhase}beginViaGridAttempt(t,e,n=[t.padClearance]){this.viaGridAttempt={kind:t.kind,traceIndex:t.traceIndex,startIndex:t.startIndex,endIndex:t.endIndex,layer:t.layer,padClearances:n,padClearanceCursor:0,originalQuality:t.originalQuality,widths:e,widthCursor:0,gridSizes:[],gridSizeCursor:0,offsetCursor:0},this.phase=\"route-via-pair\"}startNextViaGridCandidate(){const t=this.viaGridAttempt;if(!t)return void(this.phase=this.resumePhase);if(t.padClearanceCursor\u003e=t.padClearances.length)return\"pad-clearance\"===t.kind\u0026\u0026this.unresolvedPadClearanceCount++,this.viaGridAttempt=null,this.routeCursor++,void(this.phase=this.resumePhase);if(t.widthCursor\u003e=t.widths.length)return t.padClearanceCursor++,t.widthCursor=0,t.gridSizes=[],t.gridSizeCursor=0,void(t.offsetCursor=0);const e=t.widths[t.widthCursor],n=t.padClearances[t.padClearanceCursor];if(0===t.gridSizes.length\u0026\u0026(t.gridSizes=BJ([Rq(e/2,.2,.4),Rq(e/3,.15,.25)])),t.gridSizeCursor\u003e=t.gridSizes.length)return t.widthCursor++,t.gridSizes=[],t.gridSizeCursor=0,void(t.offsetCursor=0);if(t.offsetCursor\u003e=kJ.length)return t.gridSizeCursor++,void(t.offsetCursor=0);const o=this.traces[t.traceIndex],i=o.route[t.startIndex],r=o.route[t.endIndex];if(!DJ(i)||!DJ(r))return this.viaGridAttempt=null,this.routeCursor++,void(this.phase=this.resumePhase);const s=t.gridSizes[t.gridSizeCursor],a=kJ[t.offsetCursor];this.attemptedViaGridCount++,this.activeSubSolver=new Qq({start:i,end:r,layer:t.layer,traceWidth:e,gridSize:s,gridOffset:{x:a.x*s,y:a.y*s},connectionNames:this.getTraceConnectionNames(o),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(o.route.length-1,t.endIndex+1)},bounds:this.inputProblem.simpleRouteJson.bounds,obstacleClearance:n,searchPadding:Math.min(4,Math.max(2,Nq(i,r)/2,3*e)),requireOctilinear:!0})}finishViaGridSolver(t){const e=this.viaGridAttempt;if(this.activeSubSolver=null,t.solved\u0026\u0026e){const n=t.getOutput(),o=this.traces[e.traceIndex];if(n\u0026\u0026o){const t=this.resolveNominalTraceWidth(o),i=this.measureCandidate(n.points,n.traceWidth,t,o.route[e.endIndex].width,o.route[e.startIndex].width);if(0===i.nonOctilinearSegmentCount\u0026\u0026i.length\u003c=this.maxRerouteLength+Mq\u0026\u0026i.deficitArea\u003c=e.originalQuality.deficitArea+Mq\u0026\u0026i.conservativeDeficitArea\u003c=e.originalQuality.conservativeDeficitArea+Mq\u0026\u0026this.preservesCoverage(i,e.originalQuality)){const t={kind:e.kind,traceIndex:e.traceIndex,startIndex:e.startIndex,endIndex:e.endIndex,layer:e.layer,points:n.points,width:n.traceWidth,padClearance:e.padClearances[e.padClearanceCursor],originalQuality:e.originalQuality};return this.viaGridAttempt=null,void this.beginCandidates([t],this.resumePhase,!1)}}}t.failed\u0026\u0026(this.failedSubSolvers??=[],this.failedSubSolvers.push(t)),e\u0026\u0026e.offsetCursor++,this.phase=\"route-via-pair\"}measureRouteRange(t,e,n){const o=this.resolveNominalTraceWidth(t);let i=0,r=0,s=0,a=0,c=0,l=0,d=0;for(let h=e;h\u003c=n;h++){if(DJ(t.route[h])\u0026\u0026d++,h\u003e=n)continue;const e=t.route[h],u=t.route[h+1];if(!DJ(e)||!DJ(u)||e.layer!==u.layer)continue;const p=Nq(e,u);i+=p,r+=p*Math.max(0,o-e.width),e.width\u003e=o-Mq\u0026\u0026(a+=p),s+=p*Math.max(0,o-Math.min(e.width,u.width)),Math.min(e.width,u.width)\u003e=o-Mq\u0026\u0026(c+=p),l+=Gq([e,u])}return{length:i,deficitArea:r,conservativeDeficitArea:s,nominalLength:a,conservativeNominalLength:c,nonOctilinearSegmentCount:l,pointCount:d}}measureTraceLength(t){let e=0;for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];DJ(o)\u0026\u0026DJ(i)\u0026\u0026o.layer===i.layer\u0026\u0026(e+=Nq(o,i))}return e}measureCandidate(t,e,n,o=e,i=e){const r=Uq(t);let s=0,a=0,c=0,l=0;for(let r=0;r\u003ct.length-1;r++){const d=Nq(t[r],t[r+1]),h=0===r?i:e,u=r===t.length-2?o:e,p=Math.min(h,u);s+=d*Math.max(0,n-h),a+=d*Math.max(0,n-p),h\u003e=n-Mq\u0026\u0026(c+=d),p\u003e=n-Mq\u0026\u0026(l+=d)}return{length:r,deficitArea:s,conservativeDeficitArea:a,nominalLength:c,conservativeNominalLength:l,nonOctilinearSegmentCount:Gq(t),pointCount:t.length}}preservesCoverage(t,e){const n=e.length\u003c=Mq?1:e.nominalLength/e.length,o=t.length\u003c=Mq?1:t.nominalLength/t.length,i=e.length\u003c=Mq?1:e.conservativeNominalLength/e.length,r=t.length\u003c=Mq?1:t.conservativeNominalLength/t.length;return!(o+Mq\u003cn||r+Mq\u003ci)\u0026\u0026!(t.length\u003ee.length+Mq\u0026\u0026o\u003c.999999)}advanceTrace(){this.traceCursor++,this.routeCursor=0,this.rebuildObstacleIndex()}createObstacleIndex(){return new tJ(this.inputProblem.simpleRouteJson,this.traces,\"repair-vias\"===this.phase?void 0:this.traceIndices?.[this.traceCursor],[],this.connectionNameResolver)}rebuildObstacleIndex(){this.obstacleIndex=this.createObstacleIndex()}resolveNominalTraceWidth(t){const e=this.findConnectionForTrace(t);return Math.max(e?.nominalTraceWidth??e?.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.inputProblem.simpleRouteJson.minTraceWidth,this.inputProblem.simpleRouteJson.minTraceWidth)}getPadClearanceForTrace(t){const e=this.getBaseObstacleClearance();return this.resolveNominalTraceWidth(t)\u003e=.499999?Math.max(e,this.desiredPadClearance??this.resolveNominalTraceWidth(t)/2):e}getBaseObstacleClearance(){return Math.max(this.inputProblem.simpleRouteJson.defaultObstacleMargin??0,this.inputProblem.simpleRouteJson.minTraceToPadEdgeClearance??0,.1)}getCandidatePadClearance(t,e,n,o){const i=this.traces[e],r=this.getBaseObstacleClearance(),s=this.getPadClearanceForTrace(i);if(\"pad-clearance\"===t)return s;const a=\"via-pair\"===t?Math.min(s,Math.max(r,.15)):s;return this.findExistingPadClearance(e,n,o,r,a)}getImprovedPadClearanceTiers(t,e,n){const o=this.traces[t],i=this.getBaseObstacleClearance(),r=this.getPadClearanceForTrace(o),s=this.findExistingPadClearance(t,e,n,i,r),a=Math.max(.025,Math.min(.05,r/10)),c=[r];for(let t=r-a;t\u003es+a/2;t-=a)c.push(t);return BJ(c).filter(t=\u003et\u003es+Mq)}findExistingPadClearance(t,e,n,o,i){if(this.routeRangeHasPadClearanceViolation(t,e,n,o))return o;if(!this.routeRangeHasPadClearanceViolation(t,e,n,i))return i;let r=o,s=i;for(let o=0;o\u003c7;o++){const o=(r+s)/2;this.routeRangeHasPadClearanceViolation(t,e,n,o)?s=o:r=o}return Math.max(o,Number((r-.001).toFixed(6)))}routeRangeHasPadClearanceViolation(t,e,n,o){const i=this.traces[t],r=this.getTraceConnectionNames(i);for(let s=e;s\u003cn;s++){const a=i.route[s],c=i.route[s+1];if(!DJ(a)||!DJ(c)||a.layer!==c.layer)continue;if(this.obstacleIndex.findCollisions({start:a,end:c,layer:a.layer,width:Math.max(a.width,c.width),connectionNames:r,ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,e-1),end:Math.min(i.route.length-1,n+1)},obstacleClearance:o}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind))return!0}return!1}countPadClearanceViolations(t){let e=0;for(const n of this.traceIndices){const o=this.traces[n];if(!o)continue;const i=this.getTraceConnectionNames(o);for(let r=0;r\u003co.route.length-1;r++){const s=o.route[r],a=o.route[r+1];if(!DJ(s)||!DJ(a)||s.layer!==a.layer)continue;this.obstacleIndex.findCollisions({start:s,end:a,layer:s.layer,width:Math.max(s.width,a.width),connectionNames:i,ignoreTraceIndex:n,ignoreRouteRange:{start:Math.max(0,r-1),end:Math.min(o.route.length-1,r+2)},obstacleClearance:t??this.getPadClearanceForTrace(o)}).some(t=\u003e\"obstacle\"===t.kind\u0026\u0026\"pad\"===t.obstacleKind)\u0026\u0026e++}}return e}countPadClearanceViolationsByTier(){return Object.fromEntries(LJ.map(t=\u003e[t.toFixed(2),this.countPadClearanceViolations(t)]))}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=new Set(this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t))),o=this.inputProblem.simpleRouteJson.connections.find(t=\u003ethis.connectionNameResolver.canonicalize(this.getConnectionNames(t)).some(t=\u003en.has(t)))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getConnectionNames(t){return[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))}getTraceConnectionNames(t){return[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=\u003eBoolean(t))}ensureConnectivitySafeOutput(){if(!this.connectivityFinalized){this.connectivityFinalized=!0,this.connectivityValidationCount++;try{const t=this.connectivityInvariant.validate(this.traces);if(this.connectivityValidationError??=t.validationError??null,t.safe)return void(this.finalizedMutatedTraceIndices=this.getMutatedTraceIndices());this.connectivityRegressionEndpointIds=[...new Set(t.regressions.flatMap(t=\u003et.baselineEndpointLabels))]}catch(t){this.connectivityValidationError=t instanceof Error?t.message:String(t)}this.connectivityRollbackCount++,this.connectivityRollbackMutationStats={committedClearanceShoveCount:this.committedClearanceShoveCount,viaPairCountRemoved:this.viaPairCountRemoved,viaCountRemoved:this.viaCountRemoved,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,achievedExtraClearanceCount:this.achievedExtraClearanceCount,relocatedViaCount:this.relocatedViaCount,committedPushedViaRepairCount:this.committedPushedViaRepairCount,padClearanceRerouteCount:this.padClearanceRerouteCount},this.committedClearanceShoveCount=0,this.viaPairCountRemoved=0,this.viaCountRemoved=0,this.simplifiedPathCount=0,this.normalizedSegmentCount=0,this.achievedExtraClearanceCount=0,this.relocatedViaCount=0,this.committedPushedViaRepairCount=0,this.padClearanceRerouteCount=0,this.traces=structuredClone(this.initialConnectivitySafeTraces),this.obstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,void 0,[],this.connectionNameResolver),this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.finalizedMutatedTraceIndices=this.getMutatedTraceIndices()}}getMutatedTraceIndices(){const t=Math.max(this.initialConnectivitySafeTraces.length,this.traces.length);return Array.from({length:t},(t,e)=\u003ee).filter(t=\u003eJSON.stringify(this.initialConnectivitySafeTraces[t])!==JSON.stringify(this.traces[t]))}createStats(){const t=this.candidates[this.candidateCursor],e=\"repair-vias\"===this.phase?this.viaRepairTraceIndices:this.traceIndices;return{phase:this.phase,budgetLimited:this.budgetLimited,completionReason:\"complete\"===this.phase||this.solved?this.connectivityRollbackCount\u003e0?\"connectivity_rollback\":this.budgetLimited?\"iteration_budget\":this.connectivityValidationError?\"connectivity_validation_unavailable\":\"completed\":null,resultStatus:this.connectivityRollbackCount\u003e0||this.budgetLimited||null!==this.connectivityValidationError?\"best_effort\":\"complete\",traceCursor:this.traceCursor,traceCount:e.length,traceIndex:e[this.traceCursor],routeCursor:this.routeCursor,candidateCursor:this.candidateCursor,candidateCount:this.candidates.length,candidateKind:t?.kind,candidateWidth:t?.width,candidatePointCount:t?.points.length,clearancePadding:this.clearancePaddingTiers[this.clearanceTierCursor],candidateShoveCount:this.candidateShoveCount,attemptedCandidateCount:this.attemptedCandidateCount,attemptedClearanceShoveCount:this.attemptedClearanceShoveCount,attemptedViaGridCount:this.attemptedViaGridCount,committedClearanceShoveCount:this.committedClearanceShoveCount,viaPairCountRemoved:this.viaPairCountRemoved,viaCountRemoved:this.viaCountRemoved,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,achievedExtraClearanceCount:this.achievedExtraClearanceCount,relocatedViaCount:this.relocatedViaCount,unresolvedViaCount:this.unresolvedViaCount,attemptedPushedViaRepairCount:this.attemptedPushedViaRepairCount,committedPushedViaRepairCount:this.committedPushedViaRepairCount,padClearanceRerouteCount:this.padClearanceRerouteCount,unresolvedPadClearanceCount:this.unresolvedPadClearanceCount,initialPadClearanceViolationCount:this.initialPadClearanceViolationCount,remainingPadClearanceViolationCount:this.remainingPadClearanceViolationCount,initialPadClearanceViolationCountByClearance:{...this.initialPadClearanceViolationCountByClearance},remainingPadClearanceViolationCountByClearance:{...this.remainingPadClearanceViolationCountByClearance},connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},mutatedTraceIndices:[...this.finalizedMutatedTraceIndices],spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){if(this.solved||\"complete\"===this.phase)return 1;const t=\"repair-vias\"===this.phase?this.viaRepairTraceIndices:this.traceIndices;if(0===t.length)return 1;const e=\"scan-via-pairs\"===this.resumePhase?0:.5;return Math.min(.99,e+this.traceCursor/t.length*.5)}getConstructorParams(){return[this.inputProblem]}tryFinalAcceptance(){const t=this.pushedViaRepairRollbackTraces??this.rollbackTraces;t\u0026\u0026(this.traces=t),this.activeSubSolver=null,this.rollbackTraces=null,this.pushedViaRepairRollbackTraces=null,this.pendingPushedViaRepair=null,this.alternatePushedViaRepairs=[],this.viaGridAttempt=null,this.candidates=[],this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1,this.candidateSetMayUseGridFallback=!1,this.ensureConnectivitySafeOutput(),this.obstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,void 0,[],this.connectionNameResolver),this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.budgetLimited=!0,this.phase=\"complete\",this.solved=!0,this.progress=1,this.stats=this.createStats()}getOutput(){return structuredClone(this.solved?this.traces:this.initialConnectivitySafeTraces)}visualize(){const t=[],e=[],n=this.candidates[this.candidateCursor];for(let n=0;n\u003cthis.traces.length;n++){const o=this.traces[n];for(const t of o.route)\"via\"===t.route_type\u0026\u0026e.push({center:t,radius:(t.via_diameter??.6)/2,fill:\"#d4a017\",stroke:\"#7a5700\"});for(let e=0;e\u003co.route.length-1;e++){const n=o.route[e],i=o.route[e+1];DJ(n)\u0026\u0026DJ(i)\u0026\u0026n.layer===i.layer\u0026\u0026t.push({points:[n,i],strokeColor:\"bottom\"===n.layer?\"#376fc4\":\"#777\",strokeWidth:n.width})}}if(n)for(let e=0;e\u003cn.points.length-1;e++)t.push({points:[n.points[e],n.points[e+1]],strokeColor:\"#ff7400\",strokeWidth:n.width+2*(this.clearancePaddingTiers[this.clearanceTierCursor]??0)});return{coordinateSystem:\"cartesian\",title:`Power trace cleanup: ${this.phase}`,lines:t,points:[],circles:e,rects:[],texts:[]}}},$J=t=\u003e\"wire\"===t?.route_type,YJ=class extends Sq{inputProblem;traces;obstacleIndex;traceCursor=0;routeCursor=0;repairedSegmentCount=0;repairedPadNeckSegmentCount=0;unresolvedSegmentCount=0;totalWidthReduction=0;budgetLimited=!1;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;connectionNameResolver;nominalWidthByTraceId=new Map;connectivityInvariant;initialConnectivitySafeTraces;minimumTraceWidth;traceIndices;connectivityFinalized=!1;constructor(t){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.initialConnectivitySafeTraces=structuredClone(t.traces),this.connectivityInvariant=new OJ(this.inputProblem.simpleRouteJson,this.initialConnectivitySafeTraces),this.connectionNameResolver=new Pq(t.simpleRouteJson,this.traces),this.minimumTraceWidth=t.simpleRouteJson.minTraceWidth;const e=t.traceIndices?[...new Set(t.traceIndices)]:this.traces.map((t,e)=\u003ee);for(const t of e)if(!Number.isInteger(t)||t\u003c0||t\u003e=this.traces.length)throw new RangeError(`Invalid clearance-repair trace index: ${t}`);this.traceIndices=e,this.obstacleIndex=this.createConservativeObstacleIndex();const n=this.traceIndices.reduce((t,e)=\u003et+Math.max(0,this.traces[e].route.length-1),0);this.MAX_ITERATIONS=Math.max(10,8*n+2*this.traceIndices.length),this.stats=this.createStats()}getSolverName(){return\"PowerTraceClearanceRepairSolver\"}_step(){const t=this.traceIndices[this.traceCursor],e=void 0===t?void 0:this.traces[t];if(!e)return this.ensureConnectivitySafeOutput(),this.solved=!0,void(this.stats=this.createStats());if(this.routeCursor\u003e=e.route.length-1)return this.traceCursor++,this.routeCursor=0,void(this.stats=this.createStats());const n=this.routeCursor++,o=e.route[n],i=e.route[n+1];if(!$J(o)||!$J(i)||o.layer!==i.layer)return void(this.stats=this.createStats());const r=Math.max(o.width,i.width),s={start:o,end:i,layer:o.layer,width:r,connectionNames:this.getTraceConnectionNames(e),ignoreTraceIndex:t,ignoreRouteRange:{start:n,end:n+1}};if(this.repairConnectedPadNeck(e,n,s))return void(this.stats=this.createStats());if(!this.segmentHasForeignTraceCollision(n,r))return void(this.stats=this.createStats());if(this.segmentHasForeignTraceCollision(n,this.minimumTraceWidth))return this.unresolvedSegmentCount++,void(this.stats=this.createStats());let a=this.minimumTraceWidth,c=r;for(let t=0;t\u003c10;t++){const t=(a+c)/2;this.segmentHasForeignTraceCollision(n,t)?c=t:a=t}const l=r\u003e=.5?.025:.0125,d=Math.max(this.minimumTraceWidth,Math.floor((a+Mq)/l)*l),h=this.segmentHasForeignTraceCollision(n,d)?a:d,u=o.width,p=i.width;o.width=Math.min(o.width,h),i.width=Math.min(i.width,h);const m=u-o.width+(p-i.width);if(m\u003c=Mq)return this.unresolvedSegmentCount++,void(this.stats=this.createStats());this.repairedSegmentCount++,this.totalWidthReduction+=m,this.obstacleIndex=this.createConservativeObstacleIndex(),this.routeCursor=Math.max(0,n-1),this.stats=this.createStats()}repairConnectedPadNeck(t,e,n){const o=t.route[e],i=t.route[e+1];if(!$J(o)||!$J(i))return!1;let r=this.obstacleIndex.getConnectedPadWidthLimitAtPoint(n,o),s=this.obstacleIndex.getConnectedPadWidthLimitAtPoint(n,i);0===e\u0026\u0026(r=this.getSmallerLimit(r,this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(n,o))),e+1===t.route.length-1\u0026\u0026(s=this.getSmallerLimit(s,this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(n,i)));const a=r,c=s;if((null===a||o.width\u003c=a+Mq)\u0026\u0026(null===c||i.width\u003c=c+Mq))return!1;const l=o.width,d=i.width;if(null!==a\u0026\u0026(o.width=Math.min(o.width,a)),null!==c\u0026\u0026(i.width=Math.min(i.width,c)),null!==a\u0026\u0026null===c)this.insertPadBoundaryTransition(t,e,n,\"start\",o.width,d);else if(null===a\u0026\u0026null!==c)this.insertPadBoundaryTransition(t,e,n,\"end\",i.width,l);else if(null!==a\u0026\u0026null!==c){const r=this.obstacleIndex.getConnectedPadBoundaryPoint(n,\"start\"),s=this.obstacleIndex.getConnectedPadBoundaryPoint(n,\"end\");r\u0026\u0026s\u0026\u0026(this.insertPadBoundaryTransition(t,e,n,\"start\",o.width,d),this.insertPadBoundaryTransition(t,e+2,n,\"end\",i.width,l))}return this.totalWidthReduction+=l-o.width+(d-i.width),this.repairedPadNeckSegmentCount++,this.obstacleIndex=this.createConservativeObstacleIndex(),this.routeCursor=Math.max(0,e-1),!0}getSmallerLimit(t,e){return null===t?e:null===e?t:Math.min(t,e)}insertPadBoundaryTransition(t,e,n,o,i,r){const s=this.obstacleIndex.getConnectedPadBoundaryPoint(n,o);if(!s)return;const a=\"start\"===o?n.start:n.end,c=\"start\"===o?n.end:n.start,l=Math.hypot(c.x-a.x,c.y-a.y);if(l\u003c=1e-9)return;const d=Math.min(1e-6,l/4),h=(c.x-a.x)/l,u=(c.y-a.y)/l,p={route_type:\"wire\",x:s.x-h*d,y:s.y-u*d,width:i,layer:n.layer},m={...p,x:s.x+h*d,y:s.y+u*d,width:r},g=\"start\"===o?t.route[e+1]:t.route[e],f=\"start\"===o?t.route[e+2]:t.route[e-1];if($J(g)\u0026\u0026\"via\"===f?.route_type){const e=this.resolveNominalTraceWidth(t);this.obstacleIndex.collides({...n,start:g,end:m,width:e})||(g.width=Math.max(g.width,e),m.width=g.width)}t.route.splice(e+1,0,...\"start\"===o?[p,m]:[m,p])}resolveNominalTraceWidth(t){const e=this.nominalWidthByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e;const n=new Set(this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t))),o=this.inputProblem.simpleRouteJson.connections.find(t=\u003ethis.connectionNameResolver.canonicalize([t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))).some(t=\u003en.has(t))),i=Math.max(o?.nominalTraceWidth??o?.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.minimumTraceWidth,this.minimumTraceWidth);return this.nominalWidthByTraceId.set(t.pcb_trace_id,i),i}segmentHasForeignTraceCollision(t,e){const n=this.traceIndices[this.traceCursor],o=void 0===n?void 0:this.traces[n],i=o?.route[t],r=o?.route[t+1];return!!(o\u0026\u0026$J(i)\u0026\u0026$J(r)\u0026\u0026i.layer===r.layer)\u0026\u0026this.obstacleIndex.findCollisions({start:i,end:r,layer:i.layer,width:e,connectionNames:this.getTraceConnectionNames(o),ignoreTraceIndex:n,ignoreRouteRange:{start:t,end:t+1}}).some(t=\u003e\"trace\"===t.kind\u0026\u0026void 0!==t.traceIndex\u0026\u0026t.traceIndex!==n)}createConservativeObstacleIndex(){const t=structuredClone(this.traces);for(const e of t)for(let t=0;t\u003ce.route.length-1;t++){const n=e.route[t],o=e.route[t+1];$J(n)\u0026\u0026$J(o)\u0026\u0026n.layer===o.layer\u0026\u0026(n.width=Math.max(n.width,o.width))}return new tJ(this.inputProblem.simpleRouteJson,t,void 0,[],this.connectionNameResolver)}getTraceConnectionNames(t){return[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=\u003eBoolean(t))}ensureConnectivitySafeOutput(){if(!this.connectivityFinalized){this.connectivityFinalized=!0,this.connectivityValidationCount++;try{const t=this.connectivityInvariant.validate(this.traces);if(this.connectivityValidationError??=t.validationError??null,t.safe)return;this.connectivityRegressionEndpointIds=[...new Set(t.regressions.flatMap(t=\u003et.baselineEndpointLabels))]}catch(t){this.connectivityValidationError=t instanceof Error?t.message:String(t)}this.connectivityRollbackCount++,this.connectivityRollbackMutationStats={repairedSegmentCount:this.repairedSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,totalWidthReduction:this.totalWidthReduction},this.repairedSegmentCount=0,this.repairedPadNeckSegmentCount=0,this.totalWidthReduction=0,this.traces=structuredClone(this.initialConnectivitySafeTraces),this.obstacleIndex=this.createConservativeObstacleIndex()}}createStats(){return{phase:this.solved?\"complete\":\"repair-trace-clearance\",budgetLimited:this.budgetLimited,completionReason:this.solved?this.connectivityRollbackCount\u003e0?\"connectivity_rollback\":this.budgetLimited?\"iteration_budget\":this.connectivityValidationError?\"connectivity_validation_unavailable\":\"completed\":null,resultStatus:this.connectivityRollbackCount\u003e0||this.budgetLimited||null!==this.connectivityValidationError?\"best_effort\":\"complete\",traceCursor:this.traceCursor,traceCount:this.traceIndices.length,traceIndex:this.traceIndices[this.traceCursor],routeCursor:this.routeCursor,repairedSegmentCount:this.repairedSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,unresolvedSegmentCount:this.unresolvedSegmentCount,totalWidthReduction:this.totalWidthReduction,connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){return this.solved||0===this.traceIndices.length?1:Math.min(.99,this.traceCursor/this.traceIndices.length)}tryFinalAcceptance(){this.ensureConnectivitySafeOutput(),this.budgetLimited=!0,this.solved=!0,this.progress=1,this.stats=this.createStats()}getConstructorParams(){return[this.inputProblem]}getOutput(){return structuredClone(this.solved?this.traces:this.initialConnectivitySafeTraces)}visualize(){const t=[];for(let e=0;e\u003cthis.traces.length;e++){const n=this.traces[e];for(let o=0;o\u003cn.route.length-1;o++){const i=n.route[o],r=n.route[o+1];$J(i)\u0026\u0026$J(r)\u0026\u0026i.layer===r.layer\u0026\u0026t.push({points:[i,r],strokeColor:e===this.traceIndices[this.traceCursor]\u0026\u0026o===this.routeCursor?\"#ff7400\":\"bottom\"===i.layer?\"#376fc4\":\"#777\",strokeWidth:Math.max(i.width,r.width)})}}return{coordinateSystem:\"cartesian\",title:\"Power trace direction-independent clearance repair\",lines:t,points:[],circles:[],rects:[],texts:[]}}},XJ=[{x:0,y:0},{x:.5,y:0},{x:0,y:.5},{x:.5,y:.5}],VJ=[{offset:{x:0,y:0},strictNecking:!0},{offset:{x:.5,y:.5},strictNecking:!0},{offset:{x:0,y:0},strictNecking:!1},{offset:{x:.5,y:.5},strictNecking:!1}],WJ=t=\u003e[...new Set(t.map(t=\u003eNumber(t.toFixed(6))))].sort((t,e)=\u003ee-t),HJ=t=\u003e\"wire\"===t?.route_type,GJ=class extends Sq{inputProblem;options;traces;obstacleIndex;connectionNameResolver;connectionByTraceId=new Map;connectivityInvariant;lastConnectivitySafeTraces;traceOrder;selectedOwnedTraceIndices;selectedCleanupTraceIndices;selectedViaRepairTraceIndices;mutableBlockerTraceIndices;immutableTraceIndices;initialImmutableTraceSignatures=new Map;traceOrderCursor=-1;maxPassCount=4;previousWidthDeficit=0;passIndex=0;completedPassCount=0;lastNormalizedWidthDeficitGain=0;normalizedWidthDeficitGainByPass=[];plateauReached=!1;phase=\"scan-trace\";traceIndex=-1;routeSegmentIndex=0;nominalTraceWidth=0;currentIntervals=[];intervalCursor=0;candidateWidths=[];widthCursor=0;gridResolutions=[];resolutionCursor=0;offsetCursor=0;keptTraceCount=0;recreatedTraceCount=0;expandedSegmentCount=0;intermediateExpandedSegmentCount=0;pathWidthUpgradeCount=0;inPlaceWidthProbeCount=0;reroutedSegmentCount=0;unresolvedSegmentCount=0;attemptedGridCount=0;attemptedLayerGridCount=0;attemptedInflationCount=0;pushedTraceCount=0;elasticPushedTraceCount=0;layerReroutedTraceCount=0;insertedViaCount=0;neckedLayerSegmentCount=0;removedViaPairCount=0;removedViaCount=0;simplifiedPathCount=0;normalizedSegmentCount=0;cleanupClearanceShoveCount=0;relocatedViaCount=0;unresolvedViaCount=0;initialImmutableViaViolationCount=0;remainingImmutableViaViolationCount=0;initialImmutableViaViolationPairCount=0;remainingImmutableViaViolationPairCount=0;immutableTraceMutationIds=[];lastSafeImmutableViaViolationSignatures=new Set;immutableViaViolationRollbackCount=0;attemptedImmutableViaViolationCount=null;attemptedImmutableViaViolationPairCount=null;immutableViaViolationRegressionIds=[];padClearanceRerouteCount=0;unresolvedPadClearanceCount=0;repairedTraceClearanceSegmentCount=0;repairedPadNeckSegmentCount=0;unresolvedTraceClearanceSegmentCount=0;sameNetContactRejectionCount=0;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRollbackPhases=[];immutableSafetyRollbackCount=0;immutableSafetyRollbackPhases=[];connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;immutableSafetyRollbackMutationStats=null;discardedExpansionMutationStats=null;initialPadClearanceViolationCount=0;remainingPadClearanceViolationCount=0;initialPadClearanceViolationCountByClearance={};remainingPadClearanceViolationCountByClearance={};budgetLimitedExpansion=!1;finalAcceptanceUsed=!1;cleanupCompleted=!1;clearanceRepairCompleted=!1;cleanupBestEffortAccepted=!1;clearanceRepairBestEffortAccepted=!1;cleanupIterationBudget=0;clearanceRepairIterationBudget=0;expansionPushedTraceIndices=new Set;cleanupMutatedTraceIndices=[];failedSubSolverCount=0;inflationAttemptsBySegment=new Map;layerAttemptCountByTrace=new Map;layerRerouteCountByTrace=new Map;activeInflationKey=null;activeInflationWidth=null;layerAttempt=null;pendingLayerOutput=null;pendingLayerPushCount=0;constructor(t,e={}){super(),this.inputProblem=structuredClone(t),this.options=structuredClone(e),this.traces=structuredClone(t.traces??[]),this.connectionNameResolver=new Pq(this.inputProblem,this.traces),this.lastConnectivitySafeTraces=structuredClone(this.traces),this.connectivityInvariant=new OJ(this.inputProblem,this.lastConnectivitySafeTraces);const n=e.onlyConnectionNames?new Set(this.connectionNameResolver.canonicalize([...e.onlyConnectionNames])):null,o=this.traces.flatMap((t,e)=\u003e{if(!n)return[e];return this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t)).some(t=\u003en.has(t))?[e]:[]}),i=new Map(o.map(t=\u003e[t,this.getInitialTracePriority(this.traces[t])]));this.traceOrder=o.sort((t,e)=\u003ei.get(e)-i.get(t)||t-e),this.selectedOwnedTraceIndices=this.traceOrder.filter(t=\u003ethis.findConnectionForTrace(this.traces[t])),this.selectedCleanupTraceIndices=[...this.selectedOwnedTraceIndices],this.selectedViaRepairTraceIndices=[...this.selectedOwnedTraceIndices],this.mutableBlockerTraceIndices=this.traces.flatMap((t,e)=\u003ethis.findConnectionForTrace(t)?[e]:[]);const r=new Set(this.mutableBlockerTraceIndices);this.immutableTraceIndices=this.traces.flatMap((t,e)=\u003er.has(e)?[]:(this.initialImmutableTraceSignatures.set(e,JSON.stringify(t)),[e])),this.previousWidthDeficit=this.calculateWidthDeficit().deficit,this.obstacleIndex=new tJ(this.inputProblem,this.traces,this.traceIndex\u003e=0?this.traceIndex:void 0,[],this.connectionNameResolver),this.lastSafeImmutableViaViolationSignatures=this.getImmutableViaViolationSignatures(this.traces),this.initialImmutableViaViolationCount=this.countViolatingImmutableVias(this.lastSafeImmutableViaViolationSignatures),this.remainingImmutableViaViolationCount=this.initialImmutableViaViolationCount,this.initialImmutableViaViolationPairCount=this.lastSafeImmutableViaViolationSignatures.size,this.remainingImmutableViaViolationPairCount=this.initialImmutableViaViolationPairCount,this.activeSubSolver=null,this.MAX_ITERATIONS=8e6,this.stats=this.createStats()}getSolverName(){return\"PowerTraceExpanderSolver\"}_step(){if(this.shouldStartBudgetFinalization())return this.startBudgetFinalization(),void(this.stats=this.createStats());if(this.activeSubSolver)return this.stepActiveGridSolver(),void(this.stats=this.createStats());switch(this.phase){case\"scan-trace\":this.scanNextTrace();break;case\"evaluate-segment\":this.evaluateNextSegment();break;case\"try-trace-inflation\":case\"cleanup\":case\"repair-trace-clearance\":break;case\"try-layer-candidate\":this.startNextLayerCandidate();break;case\"try-grid-candidate\":this.startNextGridCandidate();break;case\"complete\":this.acceptConnectivityCheckpoint(this.traces,\"final\"),this.solved=!0}this.stats=this.createStats()}scanNextTrace(){if(this.traceOrderCursor++,this.routeSegmentIndex=0,this.traceOrderCursor\u003e=this.traceOrder.length)return void this.finishOrStartNextPass();this.traceIndex=this.traceOrder[this.traceOrderCursor];const t=this.traces[this.traceIndex];this.findConnectionForTrace(t)?(this.nominalTraceWidth=this.resolveNominalTraceWidth(t),this.traceMeetsNominalWidth(t,this.nominalTraceWidth)?this.keptTraceCount++:(this.rebuildObstacleIndex(),t.route=function(t,e){if(t.length\u003c2)return t.map(t=\u003e({...t}));const n=[];for(let o=0;o\u003ct.length-1;o++){const i=t[o],r=t[o+1];if(n.push({...i}),\"wire\"!==i.route_type||\"wire\"!==r.route_type||i.layer!==r.layer||i.width\u003e=e-Mq)continue;const s=Nq(i,r),a=Math.max(1,Math.ceil(s/e));for(let t=1;t\u003ca;t++){const e=t/a;n.push({route_type:\"wire\",x:i.x+(r.x-i.x)*e,y:i.y+(r.y-i.y)*e,width:i.width,layer:i.layer})}}return n.push({...t[t.length-1]}),n}(t.route,this.nominalTraceWidth),this.recreatedTraceCount++,this.phase=\"evaluate-segment\")):this.keptTraceCount++}finishOrStartNextPass(){const{deficit:t,nominalArea:e}=this.calculateWidthDeficit(),n=this.previousWidthDeficit-t;if(this.lastNormalizedWidthDeficitGain=e\u003c=Mq?0:n/e,this.normalizedWidthDeficitGainByPass.push(this.lastNormalizedWidthDeficitGain),this.plateauReached=this.lastNormalizedWidthDeficitGain\u003c.001,this.completedPassCount=this.passIndex+1,this.passIndex+1\u003cthis.maxPassCount\u0026\u0026this.lastNormalizedWidthDeficitGain\u003e=.001)return this.previousWidthDeficit=t,this.passIndex++,this.traceOrderCursor=-1,this.traceIndex=-1,this.routeSegmentIndex=0,this.inflationAttemptsBySegment.clear(),void(this.phase=\"scan-trace\");this.startCleanup()}startCleanup(){this.acceptConnectivityCheckpoint(this.traces,\"expansion\"),this.traceIndex=this.traces.length,this.phase=\"cleanup\";const t=new jJ({simpleRouteJson:this.inputProblem,traces:this.traces,traceIndices:this.selectedCleanupTraceIndices,viaRepairTraceIndices:this.selectedViaRepairTraceIndices,mutableTraceIndices:this.mutableBlockerTraceIndices,maxRerouteLength:10,desiredPadClearance:this.options.powerTraceToPadClearance}),e=this.getRemainingParentIterationsAfterCurrentStep(),n=0===e?0:Math.max(1,Math.floor(.75*e));t.MAX_ITERATIONS=Math.min(t.MAX_ITERATIONS,n),this.cleanupIterationBudget=t.MAX_ITERATIONS,this.activeSubSolver=t}shouldStartBudgetFinalization(){return!this.budgetLimitedExpansion\u0026\u0026(\"cleanup\"!==this.phase\u0026\u0026\"repair-trace-clearance\"!==this.phase\u0026\u0026\"complete\"!==this.phase\u0026\u0026this.iterations\u003e=this.getExpansionIterationBudget())}getFinalizationIterationReserve(){return Math.min(Math.max(0,this.MAX_ITERATIONS-1),Math.max(1,Math.floor(.125*this.MAX_ITERATIONS)))}getExpansionIterationBudget(){return Math.max(1,this.MAX_ITERATIONS-this.getFinalizationIterationReserve())}startBudgetFinalization(){this.budgetLimitedExpansion=!0,this.activeSubSolver=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.activeInflationKey=null,this.activeInflationWidth=null,this.layerAttempt=null,this.discardInFlightExpansion(),this.startCleanup()}discardInFlightExpansion(){this.discardedExpansionMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}rollbackConnectivityRegressedExpansion(){this.connectivityRollbackMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}rollbackImmutableUnsafeExpansion(){this.immutableSafetyRollbackMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}captureAndResetExpansionMutationStats(){const t={recreatedTraceCount:this.recreatedTraceCount,expandedSegmentCount:this.expandedSegmentCount,intermediateExpandedSegmentCount:this.intermediateExpandedSegmentCount,pathWidthUpgradeCount:this.pathWidthUpgradeCount,reroutedSegmentCount:this.reroutedSegmentCount,pushedTraceCount:this.pushedTraceCount,elasticPushedTraceCount:this.elasticPushedTraceCount,layerReroutedTraceCount:this.layerReroutedTraceCount,insertedViaCount:this.insertedViaCount,neckedLayerSegmentCount:this.neckedLayerSegmentCount};return this.recreatedTraceCount=0,this.expandedSegmentCount=0,this.intermediateExpandedSegmentCount=0,this.pathWidthUpgradeCount=0,this.reroutedSegmentCount=0,this.pushedTraceCount=0,this.elasticPushedTraceCount=0,this.layerReroutedTraceCount=0,this.insertedViaCount=0,this.neckedLayerSegmentCount=0,this.expansionPushedTraceIndices.clear(),t}restoreLastConnectivitySafeTraces(){this.traces=structuredClone(this.lastConnectivitySafeTraces),this.rebuildObstacleIndex()}getRemainingParentIterationsAfterCurrentStep(){return Math.max(0,this.MAX_ITERATIONS-this.iterations-1)}calculateWidthDeficit(){let t=0,e=0;for(const n of this.traceOrder){const o=this.traces[n];if(!this.findConnectionForTrace(o))continue;const i=this.resolveNominalTraceWidth(o);for(let n=0;n\u003co.route.length-1;n++){const r=o.route[n],s=o.route[n+1];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)continue;const a=Nq(r,s),c=r.width;e+=a*i,t+=a*Math.max(0,i-c)}}return{deficit:t,nominalArea:e}}getInitialTracePriority(t){const e=this.resolveNominalTraceWidth(t);let n=0;for(let o=0;o\u003ct.route.length-1;o++){const i=t.route[o],r=t.route[o+1];HJ(i)\u0026\u0026HJ(r)\u0026\u0026i.layer===r.layer\u0026\u0026(n+=Nq(i,r)*Math.max(0,e-Math.min(i.width,r.width)))}return e*n}evaluateNextSegment(){const t=this.traces[this.traceIndex];if(!t)return void(this.phase=\"scan-trace\");const e=this.findNextUnderWidthSegment(t,this.routeSegmentIndex,this.nominalTraceWidth);if(-1===e)return void(this.phase=\"scan-trace\");this.routeSegmentIndex=e;const n=t.route[e],o=t.route[e+1];if(!HJ(n)||!HJ(o))return void this.routeSegmentIndex++;const i=this.getTraceConnectionNames(t),r=Math.min(n.width,o.width),s=this.findMaximumSafeInPlaceWidth(t,e,i);if(s\u003er+Mq){if(n.width=Math.max(n.width,s),o.width=Math.max(o.width,s),s\u003e=this.nominalTraceWidth-Mq)return this.expandedSegmentCount++,void this.routeSegmentIndex++;this.intermediateExpandedSegmentCount++}this.startTraceInflation(t,e)||this.prepareLayerRouteAttempt(t,e)||this.prepareRegularGridCandidates(t,e)}prepareRegularGridCandidates(t,e){if(this.currentIntervals=this.getExponentialIntervalCandidates(t,e,this.nominalTraceWidth),this.intervalCursor=0,this.candidateWidths=this.getCandidateWidths(this.nominalTraceWidth),this.widthCursor=0,this.gridResolutions=[],this.resolutionCursor=0,this.offsetCursor=0,0===this.currentIntervals.length)return this.unresolvedSegmentCount++,void this.routeSegmentIndex++;this.phase=\"try-grid-candidate\"}prepareLayerRouteAttempt(t,e){if(this.nominalTraceWidth\u003c.499999)return!1;const n=!1!==this.options.allowNewVias\u0026\u0026this.inputProblem.layerCount\u003e=2,o=n?2:this.maxPassCount,i=this.layerAttemptCountByTrace.get(this.traceIndex)??0,r=this.layerRerouteCountByTrace.get(this.traceIndex)??0;if(r\u003e=o||i\u003e=o||i\u003ethis.passIndex||i\u003e0\u0026\u00260===r)return!1;const s=t.route[e],a=t.route[e+1];if(!HJ(s)||!HJ(a)||Math.min(s.width,a.width)\u003e=.5*this.nominalTraceWidth-Mq)return!1;const c=this.getExponentialIntervalCandidates(t,e,this.nominalTraceWidth).filter(e=\u003ethis.intervalSupportsLayerRouting(t,e)).sort((e,n)=\u003en.endIndex-e.endIndex||e.startIndex-n.startIndex||this.getRouteIntervalLength(t,n.startIndex,n.endIndex)-this.getRouteIntervalLength(t,e.startIndex,e.endIndex))[0];if(!c)return!1;const l=this.getRouteQuality(t.route.slice(c.startIndex,c.endIndex+1));if(l.deficitArea\u003cthis.nominalTraceWidth)return!1;if(i\u003e0\u0026\u0026l.deficitArea/Math.max(l.length,Mq)\u003c.25)return!1;const d=t.route[c.startIndex],h=t.route[c.endIndex],u=this.getTraceConnectionNames(t),p=n?this.getEndpointLayers(d,u):[d.layer],m=n?this.getEndpointLayers(h,u):[h.layer],g=Math.min(this.nominalTraceWidth,Math.max(d.width,this.findMaximumSafeInPlaceWidth(t,c.startIndex,u))),f=Math.min(this.nominalTraceWidth,Math.max(h.width,this.findMaximumSafeInPlaceWidth(t,c.endIndex-1,u))),y=this.getSoftTraceIndices(this.nominalTraceWidth);return this.layerAttemptCountByTrace.set(this.traceIndex,i+1),this.layerAttempt={interval:c,minViaCount:n?1:0,maxViaCount:n?2:0,candidateWidths:[this.nominalTraceWidth],widthCursor:0,gridResolutions:[Rq(this.nominalTraceWidth/4,.2,.3)],resolutionCursor:0,offsetCursor:0,startLayers:p,endLayers:m,startNeckWidth:g,endNeckWidth:f,softTraceIndices:y},this.phase=\"try-layer-candidate\",!0}intervalSupportsLayerRouting(t,e){if(e.startIndex\u003e=e.endIndex)return!1;for(let n=e.startIndex;n\u003c=e.endIndex;n++){const e=t.route[n];if(!HJ(e))return!1}const n=t.route[e.startIndex],o=t.route[e.endIndex];return n.layer===o.layer}getEndpointLayers(t,e){return[...new Set([t.layer,...this.obstacleIndex.getConnectedLayersAtPoint({x:t.x,y:t.y},e)])].filter(t=\u003ethis.obstacleIndex.boardLayers.includes(t))}getSoftTraceIndices(t){const e=[];for(let n=0;n\u003cthis.traces.length;n++){if(n===this.traceIndex)continue;const o=this.traces[n],i=this.findConnectionForTrace(o);if(!i)continue;Math.max(i.nominalTraceWidth??i.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth,this.inputProblem.minTraceWidth)\u003ct-Mq\u0026\u0026e.push(n)}return e}startNextLayerCandidate(){const t=this.layerAttempt,e=this.traces[this.traceIndex];if(!t||!e)return this.layerAttempt=null,void(this.phase=\"evaluate-segment\");if(t.widthCursor\u003e=t.candidateWidths.length){const t=this.routeSegmentIndex;return this.layerAttempt=null,void this.prepareRegularGridCandidates(e,t)}const n=t.candidateWidths[t.widthCursor];if(0===t.gridResolutions.length\u0026\u0026(t.gridResolutions=this.getGridResolutions(n)),t.resolutionCursor\u003e=t.gridResolutions.length)return t.widthCursor++,t.gridResolutions=[],t.resolutionCursor=0,void(t.offsetCursor=0);if(t.offsetCursor\u003e=VJ.length)return t.resolutionCursor++,void(t.offsetCursor=0);const o=e.route[t.interval.startIndex],i=e.route[t.interval.endIndex];if(!HJ(o)||!HJ(i))return this.layerAttempt=null,void this.prepareRegularGridCandidates(e,this.routeSegmentIndex);const r=t.gridResolutions[t.resolutionCursor],s=VJ[t.offsetCursor],a=s.offset,c=Math.min(t.startNeckWidth,t.endNeckWidth),l=this.inputProblem.min_via_hole_diameter??this.inputProblem.minViaHoleDiameter??.3,d=Math.max(l,this.inputProblem.min_via_pad_diameter??this.inputProblem.minViaPadDiameter??this.inputProblem.minViaDiameter??.6),h=Math.max(this.inputProblem.minTraceWidth,Math.min(s.strictNecking?t.startNeckWidth:c,n)),u=Math.max(this.inputProblem.minTraceWidth,Math.min(s.strictNecking?t.endNeckWidth:c,n)),p=Rq(3*this.nominalTraceWidth,1.5,3);t.maxViaCount\u003e0?this.attemptedLayerGridCount++:this.attemptedGridCount++,this.activeSubSolver=new Yq({start:o,end:i,originalStartLayer:o.layer,originalEndLayer:i.layer,startLayers:t.startLayers,endLayers:t.endLayers,layers:this.obstacleIndex.boardLayers,traceWidth:n,startNeckWidth:h,endNeckWidth:u,maxStartNeckLength:p,maxEndNeckLength:p,neckPenaltyExponent:s.strictNecking?2:1,viaDiameter:d,viaHoleDiameter:l,minViaCount:t.minViaCount,maxViaCount:t.maxViaCount,viaCost:Math.max(1,2*this.nominalTraceWidth),gridSize:r,gridOffset:{x:a.x*r,y:a.y*r},connectionNames:this.getTraceConnectionNames(e),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,t.interval.startIndex-1),end:Math.min(e.route.length-1,t.interval.endIndex+1)},softTraceIndices:t.softTraceIndices,fixedVias:this.getFixedViasOutsideInterval(e,t.interval),bounds:this.inputProblem.bounds,obstacleClearance:this.getDesiredPadClearance(n),searchPadding:Math.min(5,Math.max(2.5,Nq(o,i)/2,4*n))})}startNextGridCandidate(){const t=this.traces[this.traceIndex];if(!t)return void(this.phase=\"scan-trace\");if(this.widthCursor\u003e=this.candidateWidths.length)return this.unresolvedSegmentCount++,this.routeSegmentIndex++,void(this.phase=\"evaluate-segment\");if(this.intervalCursor\u003e=this.currentIntervals.length)return this.widthCursor++,this.intervalCursor=0,this.gridResolutions=[],this.resolutionCursor=0,void(this.offsetCursor=0);const e=this.candidateWidths[this.widthCursor],n=t.route[this.routeSegmentIndex],o=t.route[this.routeSegmentIndex+1];if(HJ(n)\u0026\u0026HJ(o)\u0026\u0026e\u003c=Math.min(n.width,o.width)+Mq)return void(this.widthCursor=this.candidateWidths.length);if(0===this.gridResolutions.length\u0026\u0026(this.gridResolutions=this.getGridResolutions(e)),this.resolutionCursor\u003e=this.gridResolutions.length)return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);if(this.offsetCursor\u003e=XJ.length)return this.resolutionCursor++,void(this.offsetCursor=0);const i=this.currentIntervals[this.intervalCursor],r=t.route[i.startIndex],s=t.route[i.endIndex];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);if(this.endpointCollides(t,i,r,e)||this.endpointCollides(t,i,s,e))return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);const a=this.gridResolutions[this.resolutionCursor],c=XJ[this.offsetCursor],l={x:c.x*a,y:c.y*a};this.attemptedGridCount++,this.activeSubSolver=new Qq({start:r,end:s,layer:r.layer,traceWidth:e,gridSize:a,gridOffset:l,connectionNames:this.getTraceConnectionNames(t),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,i.startIndex-1),end:Math.min(t.route.length-1,i.endIndex+1)},bounds:this.inputProblem.bounds,obstacleClearance:this.getDesiredPadClearance(e),searchPadding:Math.min(5,Math.max(1.5,Nq(r,s)/2,3*e))})}endpointCollides(t,e,n,o){return this.obstacleIndex.collides({start:n,end:n,layer:n.layer,width:o,connectionNames:this.getTraceConnectionNames(t),ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,e.startIndex-1),end:Math.min(t.route.length-1,e.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(o)})}stepActiveGridSolver(){if(this.activeSubSolver instanceof YJ)return void this.stepActiveTraceClearanceRepairSolver();if(this.activeSubSolver instanceof jJ)return void this.stepActiveCleanupSolver();if(this.activeSubSolver instanceof oJ)return void this.stepActiveInflationSolver();if(this.activeSubSolver instanceof Yq)return void this.stepActiveLayerSolver();const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e){const t=this.gridRouteReplacementCollides(e)||this.gridRouteBoundaryCollides(e);if(!t\u0026\u0026this.gridRoutePreservesSameNetContacts(e))return this.applyGridRoute(this.maximizeGridRouteWidth(e)),void(this.activeSubSolver=null);t||this.sameNetContactRejectionCount++}}this.retainFailedSubSolver(t),this.activeSubSolver=null,this.offsetCursor++}}stepActiveCleanupSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved)return this.adoptCleanupOutput(t),this.activeSubSolver=null,void this.startTraceClearanceRepair();this.retainFailedSubSolver(t),this.activeSubSolver=null,this.startTraceClearanceRepair()}}adoptCleanupOutput(t){const e=this.acceptConnectivityCheckpoint(t.getOutput(),\"cleanup\");this.cleanupCompleted=!t.budgetLimited;const n=t.stats;this.connectivityValidationError??=n.connectivityValidationError??null,this.connectivityValidationCount+=Number(n.connectivityValidationCount??0);const o=Number(n.connectivityRollbackCount??0);o\u003e0\u0026\u0026(this.connectivityRollbackCount+=o,this.connectivityRollbackPhases.includes(\"cleanup\")||this.connectivityRollbackPhases.push(\"cleanup\"),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...n.connectivityRegressionEndpointIds??[]])]);const i=e\u0026\u00260===o;this.cleanupBestEffortAccepted=t.budgetLimited\u0026\u0026i,this.cleanupMutatedTraceIndices=i?[...n.mutatedTraceIndices??[]]:[],this.removedViaPairCount=i?Number(n.viaPairCountRemoved??0):0,this.removedViaCount=i?Number(n.viaCountRemoved??0):0,this.simplifiedPathCount=i?Number(n.simplifiedPathCount??0):0,this.normalizedSegmentCount=i?Number(n.normalizedSegmentCount??0):0,this.cleanupClearanceShoveCount=i?Number(n.committedClearanceShoveCount??0):0,this.relocatedViaCount=i?Number(n.relocatedViaCount??0):0,this.unresolvedViaCount=Number(n.unresolvedViaCount??0),this.padClearanceRerouteCount=i?Number(n.padClearanceRerouteCount??0):0,this.unresolvedPadClearanceCount=Number(n.unresolvedPadClearanceCount??0),this.initialPadClearanceViolationCount=Number(n.initialPadClearanceViolationCount??0),this.remainingPadClearanceViolationCount=Number(n.remainingPadClearanceViolationCount??0),this.initialPadClearanceViolationCountByClearance={...n.initialPadClearanceViolationCountByClearance??{}},this.remainingPadClearanceViolationCountByClearance={...n.remainingPadClearanceViolationCountByClearance??{}},this.rebuildObstacleIndex()}startTraceClearanceRepair(){this.phase=\"repair-trace-clearance\";const t=[...new Set([...this.getOwnedTraceIndices(),...this.expansionPushedTraceIndices,...this.cleanupMutatedTraceIndices])],e=new YJ({simpleRouteJson:this.inputProblem,traces:this.traces,traceIndices:t});e.MAX_ITERATIONS=Math.min(e.MAX_ITERATIONS,this.getRemainingParentIterationsAfterCurrentStep()),this.clearanceRepairIterationBudget=e.MAX_ITERATIONS,this.activeSubSolver=e}stepActiveTraceClearanceRepairSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved)return this.adoptClearanceRepairOutput(t),this.activeSubSolver=null,void(this.phase=\"complete\");this.retainFailedSubSolver(t),this.activeSubSolver=null,this.phase=\"complete\"}}adoptClearanceRepairOutput(t){const e=this.acceptConnectivityCheckpoint(t.getOutput(),\"clearance-repair\");this.clearanceRepairCompleted=!t.budgetLimited;const n=t.stats;this.connectivityValidationError??=n.connectivityValidationError??null,this.connectivityValidationCount+=Number(n.connectivityValidationCount??0);const o=Number(n.connectivityRollbackCount??0);o\u003e0\u0026\u0026(this.connectivityRollbackCount+=o,this.connectivityRollbackPhases.includes(\"clearance-repair\")||this.connectivityRollbackPhases.push(\"clearance-repair\"),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...n.connectivityRegressionEndpointIds??[]])]);const i=e\u0026\u00260===o;this.clearanceRepairBestEffortAccepted=t.budgetLimited\u0026\u0026i,this.repairedTraceClearanceSegmentCount=i?Number(n.repairedSegmentCount??0):0,this.repairedPadNeckSegmentCount=i?Number(n.repairedPadNeckSegmentCount??0):0,this.unresolvedTraceClearanceSegmentCount=Number(n.unresolvedSegmentCount??0),this.rebuildObstacleIndex()}stepActiveLayerSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e){const t=!this.layerRouteReplacementCollides(e,!0)\u0026\u0026this.layerRouteImprovesInterval(e),n=t\u0026\u0026this.layerRoutePreservesSameNetContacts(e);if(n){if(this.activeSubSolver=null,this.pendingLayerOutput=e,this.pendingLayerPushCount=0,!this.layerRouteReplacementCollides(e,!1))return void this.applyLayerRoute(e);if(this.startPendingLayerInflation())return;this.pendingLayerOutput=null}t\u0026\u0026!n\u0026\u0026this.sameNetContactRejectionCount++}}this.retainFailedSubSolver(t),this.activeSubSolver=null,this.layerAttempt\u0026\u0026this.layerAttempt.offsetCursor++,this.phase=\"try-layer-candidate\"}}layerRouteReplacementCollides(t,e){const n=this.traces[this.traceIndex],o=this.layerAttempt;if(!n||!o)return!0;const i=this.getTraceConnectionNames(n),r=e?o.softTraceIndices:void 0,s={start:Math.max(0,o.interval.startIndex-1),end:Math.min(n.route.length-1,o.interval.endIndex+1)},a=this.getFixedViasOutsideInterval(n,o.interval);for(let e=0;e\u003ct.route.length;e++){const n=t.route[e];if(\"via\"===n?.route_type){if(this.obstacleIndex.collidesVia({point:n,layers:this.obstacleIndex.boardLayers,padDiameter:n.via_diameter??.6,holeDiameter:n.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,connectionNames:i,ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:r,otherNewViaPoints:t.route.slice(0,e).filter(t=\u003e\"via\"===t.route_type).map(t=\u003e({x:t.x,y:t.y})),fixedVias:a,ignoreRouteRange:s,obstacleClearance:this.getDesiredPadClearance(t.traceWidth),blockSameNetObstacles:!0,sameNetObstacleClearance:0}))return!0;continue}const o=t.route[e+1];if(\"wire\"===n?.route_type\u0026\u0026\"wire\"===o?.route_type\u0026\u0026n.layer===o.layer\u0026\u0026this.obstacleIndex.collides({start:n,end:o,layer:n.layer,width:Math.max(n.width,o.width),connectionNames:i,ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:r,ignoreRouteRange:s,obstacleClearance:this.getDesiredPadClearance(t.traceWidth)}))return!0}return this.layerRouteBoundaryCollides(t,e)}getFixedViasOutsideInterval(t,e){return t.route.flatMap((t,n)=\u003e\"via\"!==t.route_type||n\u003e=e.startIndex\u0026\u0026n\u003c=e.endIndex?[]:[{point:{x:t.x,y:t.y},padDiameter:t.via_diameter??.6,holeDiameter:t.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter}])}layerRouteBoundaryCollides(t,e){const n=this.traces[this.traceIndex],o=this.layerAttempt,i=t.route.find(t=\u003e\"wire\"===t.route_type);let r;for(let e=t.route.length-1;e\u003e=0;e--){const n=t.route[e];if(\"wire\"===n?.route_type){r=n;break}}if(!i||!r)return!0;const s=[{outside:n.route[o.interval.startIndex-1],inside:i},{outside:n.route[o.interval.endIndex+1],inside:r}];for(const i of s)if(HJ(i.outside)\u0026\u0026i.outside.layer===i.inside.layer\u0026\u0026this.obstacleIndex.collides({start:i.outside,end:i.inside,layer:i.inside.layer,width:Math.max(i.outside.width,i.inside.width),connectionNames:this.getTraceConnectionNames(n),ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:e?o.softTraceIndices:void 0,ignoreRouteRange:{start:Math.max(0,o.interval.startIndex-1),end:Math.min(n.route.length-1,o.interval.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(t.traceWidth)}))return!0;return!1}layerRouteImprovesInterval(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=this.getRouteQuality(e.route.slice(n.startIndex,n.endIndex+1)),i=this.getRouteQuality(t.route);return i.length\u003c=o.length+10+Mq\u0026\u0026i.deficitArea\u003c=o.deficitArea-Math.max(.05,.1*o.deficitArea)}getRouteQuality(t){let e=0,n=0;for(let o=0;o\u003ct.length-1;o++){const i=t[o],r=t[o+1];if(!HJ(i)||!HJ(r)||i.layer!==r.layer)continue;const s=Nq(i,r),a=Math.min(i.width,r.width);e+=s,n+=s*Math.max(0,this.nominalTraceWidth-a)}return{length:e,deficitArea:n}}getLayerInflationCorridor(t){const e=[];for(let n=0;n\u003ct.route.length;n++){const o=t.route[n];if(\"via\"===o?.route_type){for(const t of this.obstacleIndex.boardLayers)e.push({start:o,end:o,layer:t,width:o.via_diameter??.6});continue}const i=t.route[n+1];\"wire\"===o?.route_type\u0026\u0026\"wire\"===i?.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({start:o,end:i,layer:o.layer,width:Math.max(o.width,i.width)})}return e}startPendingLayerInflation(){const t=this.pendingLayerOutput;if(!t||this.pendingLayerPushCount\u003e=2)return!1;const e=this.getLayerInflationCorridor(t);return 0!==e.length\u0026\u0026(this.pendingLayerPushCount++,this.attemptedInflationCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem,traces:this.traces,powerTraceIndex:this.traceIndex,nominalPowerWidth:t.traceWidth,mutableTraceIndices:this.mutableBlockerTraceIndices,corridor:e,maxRerouteLength:10},this.connectionNameResolver),this.phase=\"try-trace-inflation\",!0)}applyLayerRoute(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=this.createLayerRouteReplacement(t);e.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...o),t.viaCount\u003e0\u0026\u0026this.layerReroutedTraceCount++,this.layerRerouteCountByTrace.set(this.traceIndex,(this.layerRerouteCountByTrace.get(this.traceIndex)??0)+1),this.reroutedSegmentCount++,this.insertedViaCount+=t.viaCount,t.viaCount\u003e0\u0026\u0026(this.neckedLayerSegmentCount+=o.filter(t=\u003e\"wire\"===t.route_type\u0026\u0026t.width\u003cthis.nominalTraceWidth-Mq).length),this.routeSegmentIndex=n.startIndex,this.currentIntervals=[],this.layerAttempt=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.phase=\"evaluate-segment\"}createLayerRouteReplacement(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=e.route[n.startIndex],i=e.route[n.endIndex],r=structuredClone(t.route),s=r.findIndex(t=\u003e\"wire\"===t.route_type);let a=-1;for(let t=r.length-1;t\u003e=0;t--)if(\"wire\"===r[t]?.route_type){a=t;break}return s\u003e=0\u0026\u0026(r[s]={...o,...r[s]}),a\u003e=0\u0026\u0026(r[a]={...i,...r[a]}),r}layerRoutePreservesSameNetContacts(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval;return this.routeReplacementPreservesSameNetContacts(e,n,this.createLayerRouteReplacement(t))}startTraceInflation(t,e){const n=t.route[e],o=t.route[e+1];if(!HJ(n)||!HJ(o))return!1;const i=Math.min(n.width,o.width),r=this.findBestPushableInflationWidth(t,e,i);if(!r)return!1;const s=this.getLocalInflationCorridor(t,e,r);if(0===s.length)return!1;const a=[this.traceIndex,n.x,n.y,o.x,o.y].join(\":\"),c=this.inflationAttemptsBySegment.get(a)??0;return!(c\u003e=2)\u0026\u0026(this.inflationAttemptsBySegment.set(a,c+1),this.activeInflationKey=a,this.activeInflationWidth=r,this.attemptedInflationCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem,traces:this.traces,powerTraceIndex:this.traceIndex,nominalPowerWidth:r,mutableTraceIndices:this.mutableBlockerTraceIndices,corridor:s,maxRerouteLength:10},this.connectionNameResolver),this.phase=\"try-trace-inflation\",!0)}hasOnlyPushableTraceBlockers(t,e,n){const o=Math.max(0,e-1),i=Math.min(t.route.length-2,e+1),r=new Set;for(let e=o;e\u003c=i;e++){const s=t.route[e],a=t.route[e+1];if(!HJ(s)||!HJ(a)||s.layer!==a.layer)continue;const c={start:s,end:a,layer:s.layer,width:n,connectionNames:this.getTraceConnectionNames(t),ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:o,end:i+1},obstacleClearance:this.getDesiredPadClearance(n)},l=this.obstacleIndex.findCollisions(c);if(0===l.length\u0026\u0026this.obstacleIndex.collides(c))return!1;for(const t of l){if(\"trace\"!==t.kind||void 0===t.traceIndex)return!1;const e=this.traces[t.traceIndex];if(!e)return!1;const o=this.findConnectionForTrace(e);if(!o||(o.nominalTraceWidth??o.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth)\u003e=n-Mq)return!1;r.add(t.traceIndex)}}return r.size\u003e0\u0026\u0026r.size\u003c=2}findBestPushableInflationWidth(t,e,n){const o=this.nominalTraceWidth\u003e=.5?.05:.0125;for(let i=this.nominalTraceWidth;i\u003en+Mq;i-=o){const n=Number(i.toFixed(6));if(this.hasOnlyPushableTraceBlockers(t,e,n))return n}return null}stepActiveInflationSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput(),n=e\u0026\u0026this.sameNetContactsArePreserved(this.traces[e.pushedTraceIndex].route,e.traces[e.pushedTraceIndex].route,this.getTraceConnectionNames(this.traces[e.pushedTraceIndex]),e.pushedTraceIndex);if(e\u0026\u0026n){if(this.traces=e.traces,this.pushedTraceCount++,this.expansionPushedTraceIndices.add(e.pushedTraceIndex),\"elastic\"===e.strategy\u0026\u0026this.elasticPushedTraceCount++,this.activeSubSolver=null,this.activeInflationKey=null,this.activeInflationWidth=null,this.rebuildObstacleIndex(),this.pendingLayerOutput){if(!this.layerRouteReplacementCollides(this.pendingLayerOutput,!1)\u0026\u0026this.layerRoutePreservesSameNetContacts(this.pendingLayerOutput))return void this.applyLayerRoute(this.pendingLayerOutput);if(this.startPendingLayerInflation())return;return this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.layerAttempt\u0026\u0026this.layerAttempt.offsetCursor++,void(this.phase=\"try-layer-candidate\")}return void(this.phase=\"evaluate-segment\")}e\u0026\u0026!n\u0026\u0026this.sameNetContactRejectionCount++}if(this.retainFailedSubSolver(t),this.activeInflationKey\u0026\u0026this.inflationAttemptsBySegment.set(this.activeInflationKey,2),this.activeInflationKey=null,this.activeInflationWidth=null,this.activeSubSolver=null,this.pendingLayerOutput)return this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.layerAttempt\u0026\u0026this.layerAttempt.offsetCursor++,void(this.phase=\"try-layer-candidate\");this.phase=\"evaluate-segment\"}}getLocalInflationCorridor(t,e,n){const o=t.route[e],i=t.route[e+1];if(!HJ(o)||!HJ(i)||o.layer!==i.layer)return[];const r=Rq(4*n,2,4),s=r/2;let a=e,c=0;for(;a\u003e0;){const e=t.route[a-1],n=t.route[a];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(c+o\u003es+Mq)break;c+=o,a--}let l=e+1,d=0;for(;l\u003ct.route.length-1;){const e=t.route[l],n=t.route[l+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(d+o\u003es+Mq)break;d+=o,l++}let h=r-c-d;for(;h\u003eMq\u0026\u0026a\u003e0;){const e=t.route[a-1],n=t.route[a];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(o\u003eh+Mq)break;h-=o,a--}for(;h\u003eMq\u0026\u0026l\u003ct.route.length-1;){const e=t.route[l],n=t.route[l+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(o\u003eh+Mq)break;h-=o,l++}const u=[];for(let e=a;e\u003cl;e++){const o=t.route[e],i=t.route[e+1];HJ(o)\u0026\u0026HJ(i)\u0026\u0026o.layer===i.layer\u0026\u0026u.push({start:o,end:i,layer:o.layer,width:n})}return u}applyGridRoute(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=this.createGridRouteReplacement(t);e.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...o),this.reroutedSegmentCount++,this.routeSegmentIndex=n.startIndex+o.length-1,this.currentIntervals=[],this.phase=\"evaluate-segment\"}createGridRouteReplacement(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=e.route[n.startIndex],i=e.route[n.endIndex],r=t.points.map(e=\u003e({route_type:\"wire\",x:e.x,y:e.y,width:t.traceWidth,layer:o.layer}));return r[0].width=Math.max(o.width,t.traceWidth),r[r.length-1].width=Math.max(i.width,t.traceWidth),r}gridRoutePreservesSameNetContacts(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor];return this.routeReplacementPreservesSameNetContacts(e,n,this.createGridRouteReplacement(t))}routeReplacementPreservesSameNetContacts(t,e,n){const o=this.getTraceConnectionNames(t),i=this.getSameNetContactIds(t.route.slice(e.startIndex,e.endIndex+1),o,this.traceIndex),r=new Set([...this.getSameNetContactIds(t.route.slice(0,e.startIndex+1),o,this.traceIndex),...this.getSameNetContactIds(t.route.slice(e.endIndex),o,this.traceIndex)]),s=new Set([...i].filter(t=\u003e!r.has(t)));if(0===s.size)return!0;const a=this.getSameNetContactIds(n,o,this.traceIndex);return[...s].every(t=\u003ea.has(t))}sameNetContactsArePreserved(t,e,n,o){const i=this.getSameNetContactIds(t,n,o);if(0===i.size)return!0;const r=this.getSameNetContactIds(e,n,o);return[...i].every(t=\u003er.has(t))}getSameNetContactIds(t,e,n){const o=new Set;for(let i=0;i\u003ct.length;i++){const r=t[i];if(\"via\"===r?.route_type){for(const t of this.getViaLayers(r))for(const i of this.obstacleIndex.getSameNetCopperContactIds({start:r,end:r,layer:t,width:r.via_diameter??.6,connectionNames:e,ignoreTraceIndex:n}))o.add(i);continue}const s=t[i+1];if(\"wire\"===r?.route_type\u0026\u0026\"wire\"===s?.route_type\u0026\u0026r.layer===s.layer)for(const t of this.obstacleIndex.getSameNetCopperContactIds({start:r,end:s,layer:r.layer,width:Math.min(r.width,s.width),connectionNames:e,ignoreTraceIndex:n}))o.add(t)}return o}getViaLayers(t){const e=this.obstacleIndex.boardLayers.indexOf(t.from_layer),n=this.obstacleIndex.boardLayers.indexOf(t.to_layer);return e\u003c0||n\u003c0?this.obstacleIndex.boardLayers:this.obstacleIndex.boardLayers.slice(Math.min(e,n),Math.max(e,n)+1)}gridRouteReplacementCollides(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=e.route[n.startIndex],i=e.route[n.endIndex],r=this.getTraceConnectionNames(e);for(let s=0;s\u003ct.points.length-1;s++){const a=Math.max(t.traceWidth,0===s?o.width:0,s===t.points.length-2?i.width:0);if(this.obstacleIndex.collides({start:t.points[s],end:t.points[s+1],layer:o.layer,width:a,connectionNames:r,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,n.startIndex-1),end:Math.min(e.route.length-1,n.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(a)}))return!0}return!1}gridRouteBoundaryCollides(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=this.getTraceConnectionNames(e),i=[{startIndex:n.startIndex-1,endIndex:n.startIndex},{startIndex:n.endIndex,endIndex:n.endIndex+1}];for(const n of i){const i=e.route[n.startIndex],r=e.route[n.endIndex];if(HJ(i)\u0026\u0026HJ(r)\u0026\u0026i.layer===r.layer\u0026\u0026this.obstacleIndex.collides({start:i,end:r,layer:i.layer,width:Math.max(i.width,r.width,t.traceWidth),connectionNames:o,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:n.startIndex,end:n.endIndex},obstacleClearance:this.getDesiredPadClearance(Math.max(i.width,r.width,t.traceWidth))}))return!0}return!1}canExpandSegmentAndEndpoints(t,e,n,o=this.nominalTraceWidth){const i=Math.max(0,e-1),r=Math.min(t.route.length-2,e+1);for(let s=i;s\u003c=r;s++){const a=t.route[s],c=t.route[s+1];if(!HJ(a)||!HJ(c)||a.layer!==c.layer)continue;const l=s\u003c=e+1\u0026\u0026s+1\u003e=e,d=Math.max(a.width,c.width,l?o:0);if(this.obstacleIndex.collides({start:a,end:c,layer:a.layer,width:d,connectionNames:n,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:i,end:r+1},obstacleClearance:this.getDesiredPadClearance(d)}))return!1}return!0}findMaximumSafeInPlaceWidth(t,e,n){const o=t.route[e],i=t.route[e+1];if(!HJ(o)||!HJ(i))return 0;const r=Math.min(o.width,i.width);if(this.probeInPlaceWidth(t,e,n,this.nominalTraceWidth))return this.nominalTraceWidth;let s=r,a=this.nominalTraceWidth;for(let o=0;o\u003c7;o++){const o=(s+a)/2;if(o\u003c=s+Mq)break;this.probeInPlaceWidth(t,e,n,o)?s=o:a=o}const c=this.nominalTraceWidth\u003e=.5?.025:.0125,l=Math.max(r,Math.floor((s+Mq)/c)*c);return l\u003er+Mq\u0026\u0026this.probeInPlaceWidth(t,e,n,l)?l:r}probeInPlaceWidth(t,e,n,o){return this.inPlaceWidthProbeCount++,this.canExpandSegmentAndEndpoints(t,e,n,o)}maximizeGridRouteWidth(t){if(t.traceWidth\u003e=this.nominalTraceWidth-Mq)return t;let e=t.traceWidth,n=this.nominalTraceWidth;for(let o=0;o\u003c7;o++){const o=(e+n)/2,i={...t,traceWidth:o};this.gridRouteReplacementCollides(i)||this.gridRouteBoundaryCollides(i)?n=o:e=o}const o=this.nominalTraceWidth\u003e=.5?.025:.0125,i=Math.max(t.traceWidth,Math.floor((e+Mq)/o)*o);if(i\u003et.traceWidth+Mq){const e={...t,traceWidth:i};if(!this.gridRouteReplacementCollides(e)\u0026\u0026!this.gridRouteBoundaryCollides(e))return this.pathWidthUpgradeCount++,e}return t}getExponentialIntervalCandidates(t,e,n){const o=this.getExponentialIndices(t,e,-1,n,5),i=this.getExponentialIndices(t,e,1,n,10).filter(t=\u003et\u003ee),r=[];for(const e of o)for(const n of i){const o=this.getRouteIntervalLength(t,e,n);o\u003e10.000001||r.push({startIndex:e,endIndex:n,routeLength:o})}return r.sort((t,e)=\u003et.routeLength-e.routeLength).filter((t,e,n)=\u003en.findIndex(e=\u003ee.startIndex===t.startIndex\u0026\u0026e.endIndex===t.endIndex)===e).slice(0,10).map(({startIndex:t,endIndex:e})=\u003e({startIndex:t,endIndex:e}))}getExponentialIndices(t,e,n,o,i){const r=[e];let s=0,a=Math.max(o,.3),c=e,l=e;for(;;){const e=c+n;if(e\u003c0||e\u003e=t.route.length)break;const o=t.route[c],d=t.route[e];if(!HJ(o)||!HJ(d)||o.layer!==d.layer)break;const h=Nq(o,d);if(s+h\u003ei+Mq)break;s+=h,c=e,l=e,s+Mq\u003e=a\u0026\u0026(r.push(e),a*=2)}return r.includes(l)||r.push(l),r}getRouteIntervalLength(t,e,n){let o=0;for(let i=e;i\u003cn;i++){const e=t.route[i],n=t.route[i+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)return Number.POSITIVE_INFINITY;o+=Nq(e,n)}return o}getCandidateWidths(t){const e=this.inputProblem.minTraceWidth;return WJ([t,.875*t,.75*t,.625*t,.5*t,.375*t,.25*t,e]).filter(t=\u003et\u003e=e-Mq)}getGridResolutions(t){return WJ([Math.max(.1,Math.min(.5,t/2)),Math.max(.1,Math.min(.25,t/3))])}resolveNominalTraceWidth(t){const e=this.findConnectionForTrace(t);return Math.max(e?.nominalTraceWidth??e?.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth,this.inputProblem.minTraceWidth)}getDesiredPadClearance(t=this.nominalTraceWidth){const e=Math.max(this.inputProblem.defaultObstacleMargin??0,this.inputProblem.minTraceToPadEdgeClearance??0,.1);return t\u003c.499999||\"cleanup\"!==this.phase?e:Math.max(e,this.options.powerTraceToPadClearance??t/2)}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=this.getTraceConnectionNames(t),o=this.inputProblem.connections.find(t=\u003ethis.connectionMatchesTrace(t,n))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getOwnedTraceIndices(){return[...this.selectedOwnedTraceIndices]}connectionMatchesTrace(t,e){return[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t)).some(t=\u003ee.includes(t))}getTraceConnectionNames(t){return[t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[]].filter(t=\u003eBoolean(t))}traceMeetsNominalWidth(t,e){return t.route.every(t=\u003e\"wire\"!==t.route_type||t.width\u003e=e-Mq)}findNextUnderWidthSegment(t,e,n){for(let o=e;o\u003ct.route.length-1;o++){const e=t.route[o],i=t.route[o+1];if(HJ(e)\u0026\u0026HJ(i)\u0026\u0026e.layer===i.layer\u0026\u0026(e.width\u003cn-Mq||i.width\u003cn-Mq))return o}return-1}getMutatedImmutableTraceIds(t){return this.immutableTraceIndices.flatMap(e=\u003e{const n=t[e];return JSON.stringify(n)===this.initialImmutableTraceSignatures.get(e)?[]:[n?.pcb_trace_id??this.traces[e]?.pcb_trace_id??String(e)]})}getImmutableViaViolationSignatures(t){const e=new Set;if(0===this.immutableTraceIndices.length)return e;const n=new Pq(this.inputProblem,t),o=new tJ(this.inputProblem,t,void 0,[],n);for(const n of this.immutableTraceIndices){const i=t[n];if(!i)continue;const r=[i.pcb_trace_id,i.connection_name,i.source_trace_id,i.rootConnectionName,...i.mergedConnectionNames??[],...i.connectsTo??[]].filter(t=\u003eBoolean(t));for(let t=0;t\u003ci.route.length;t++){const s=i.route[t];if(\"via\"!==s?.route_type)continue;const a=`${i.pcb_trace_id}:${t}`,c=o.getViaViolationSignatures({point:s,layers:o.boardLayers,padDiameter:s.via_diameter??this.inputProblem.min_via_pad_diameter??this.inputProblem.minViaPadDiameter??this.inputProblem.minViaDiameter??.6,holeDiameter:s.via_hole_diameter??o.defaultViaHoleDiameter,connectionNames:r,ignoreTraceIndex:n,ignoreRouteRange:{start:t,end:t},blockSameNetObstacles:!0,sameNetObstacleClearance:0});for(const t of c)e.add(`${a}|${t}`)}}return e}countViolatingImmutableVias(t){return new Set([...t].map(t=\u003et.split(\"|\")[0])).size}acceptConnectivityCheckpoint(t,e){this.connectivityValidationCount++;let n=!1,o=!1;try{const e=this.connectivityInvariant.validate(t),i=this.getMutatedImmutableTraceIds(t),r=this.getImmutableViaViolationSignatures(t),s=[...r].filter(t=\u003e!this.lastSafeImmutableViaViolationSignatures.has(t)),a=s.length\u003e0;if(n=!e.safe,o=i.length\u003e0||a,this.connectivityValidationError??=e.validationError??null,!n\u0026\u0026!o)return this.traces=structuredClone(t),this.lastConnectivitySafeTraces=structuredClone(t),this.remainingImmutableViaViolationCount=this.countViolatingImmutableVias(r),this.remainingImmutableViaViolationPairCount=r.size,this.lastSafeImmutableViaViolationSignatures=r,this.connectivityInvariant=new OJ(this.inputProblem,this.lastConnectivitySafeTraces),!0;this.immutableTraceMutationIds=[...new Set([...this.immutableTraceMutationIds,...i])],a\u0026\u0026(this.immutableViaViolationRollbackCount++,this.attemptedImmutableViaViolationCount=this.countViolatingImmutableVias(r),this.attemptedImmutableViaViolationPairCount=r.size,this.immutableViaViolationRegressionIds=[...new Set([...this.immutableViaViolationRegressionIds,...s])]),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...e.regressions.flatMap(t=\u003et.baselineEndpointLabels)])]}catch(t){n=!0,this.connectivityValidationError=t instanceof Error?t.message:String(t)}return n\u0026\u0026(this.connectivityRollbackCount++,this.connectivityRollbackPhases.includes(e)||this.connectivityRollbackPhases.push(e)),o\u0026\u0026(this.immutableSafetyRollbackCount++,this.immutableSafetyRollbackPhases.includes(e)||this.immutableSafetyRollbackPhases.push(e)),\"expansion\"===e?n?this.rollbackConnectivityRegressedExpansion():this.rollbackImmutableUnsafeExpansion():this.restoreLastConnectivitySafeTraces(),this.remainingImmutableViaViolationCount=this.countViolatingImmutableVias(this.lastSafeImmutableViaViolationSignatures),this.remainingImmutableViaViolationPairCount=this.lastSafeImmutableViaViolationSignatures.size,!1}rebuildObstacleIndex(){this.obstacleIndex=new tJ(this.inputProblem,this.traces,this.traceIndex,[],this.connectionNameResolver)}retainFailedSubSolver(t){this.failedSubSolverCount++,this.failedSubSolvers??=[],this.failedSubSolvers.length\u003c16?this.failedSubSolvers.push(t):this.failedSubSolvers[15]=t}tryFinalAcceptance(){this.finalAcceptanceUsed=!0;let t=!1;this.activeSubSolver instanceof jJ?(this.activeSubSolver.tryFinalAcceptance(),this.adoptCleanupOutput(this.activeSubSolver),t=!0):this.activeSubSolver instanceof YJ\u0026\u0026(this.activeSubSolver.tryFinalAcceptance(),this.adoptClearanceRepairOutput(this.activeSubSolver),t=!0),t||\"cleanup\"===this.phase||\"repair-trace-clearance\"===this.phase||\"complete\"===this.phase||this.discardInFlightExpansion(),this.activeSubSolver=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.activeInflationKey=null,this.activeInflationWidth=null,this.layerAttempt=null,this.acceptConnectivityCheckpoint(this.traces,\"final\"),this.traceIndex=this.traces.length,this.phase=\"complete\",this.rebuildObstacleIndex(),this.progress=1,this.solved=!0,this.stats=this.createStats()}createStats(){return{phase:this.phase,pass:this.passIndex+1,completedPassCount:this.completedPassCount,lastNormalizedWidthDeficitGain:this.lastNormalizedWidthDeficitGain,normalizedWidthDeficitGainByPass:[...this.normalizedWidthDeficitGainByPass],plateauReached:this.plateauReached,traceIndex:this.traceIndex,traceCount:this.traces.length,selectedTraceCount:this.traceOrder.length,routeSegmentIndex:this.routeSegmentIndex,nominalTraceWidth:this.nominalTraceWidth,intervalCursor:this.intervalCursor,intervalCount:this.currentIntervals.length,candidateWidth:this.candidateWidths[this.widthCursor],gridSize:this.gridResolutions[this.resolutionCursor],gridOffsetVariant:this.offsetCursor,keptTraceCount:this.keptTraceCount,recreatedTraceCount:this.recreatedTraceCount,expandedSegmentCount:this.expandedSegmentCount,intermediateExpandedSegmentCount:this.intermediateExpandedSegmentCount,pathWidthUpgradeCount:this.pathWidthUpgradeCount,inPlaceWidthProbeCount:this.inPlaceWidthProbeCount,reroutedSegmentCount:this.reroutedSegmentCount,unresolvedSegmentCount:this.unresolvedSegmentCount,attemptedGridCount:this.attemptedGridCount,attemptedLayerGridCount:this.attemptedLayerGridCount,attemptedInflationCount:this.attemptedInflationCount,activeInflationWidth:this.activeInflationWidth,pushedTraceCount:this.pushedTraceCount,elasticPushedTraceCount:this.elasticPushedTraceCount,layerReroutedTraceCount:this.layerReroutedTraceCount,insertedViaCount:this.insertedViaCount,neckedLayerSegmentCount:this.neckedLayerSegmentCount,removedViaPairCount:this.removedViaPairCount,removedViaCount:this.removedViaCount,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,cleanupClearanceShoveCount:this.cleanupClearanceShoveCount,relocatedViaCount:this.relocatedViaCount,unresolvedViaCount:this.unresolvedViaCount,initialImmutableViaViolationCount:this.initialImmutableViaViolationCount,remainingImmutableViaViolationCount:this.remainingImmutableViaViolationCount,initialImmutableViaViolationPairCount:this.initialImmutableViaViolationPairCount,remainingImmutableViaViolationPairCount:this.remainingImmutableViaViolationPairCount,skippedImmutableViaRepairCount:this.remainingImmutableViaViolationCount,immutableViaViolationRollbackCount:this.immutableViaViolationRollbackCount,attemptedImmutableViaViolationCount:this.attemptedImmutableViaViolationCount,attemptedImmutableViaViolationPairCount:this.attemptedImmutableViaViolationPairCount,immutableViaViolationRegressionIds:[...this.immutableViaViolationRegressionIds],immutableTraceMutationIds:[...this.immutableTraceMutationIds],padClearanceRerouteCount:this.padClearanceRerouteCount,unresolvedPadClearanceCount:this.unresolvedPadClearanceCount,repairedTraceClearanceSegmentCount:this.repairedTraceClearanceSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,unresolvedTraceClearanceSegmentCount:this.unresolvedTraceClearanceSegmentCount,sameNetContactRejectionCount:this.sameNetContactRejectionCount,connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRollbackPhases:[...this.connectivityRollbackPhases],immutableSafetyRollbackCount:this.immutableSafetyRollbackCount,immutableSafetyRollbackPhases:[...this.immutableSafetyRollbackPhases],connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},immutableSafetyRollbackMutationStats:null===this.immutableSafetyRollbackMutationStats?null:{...this.immutableSafetyRollbackMutationStats},expansionPushedTraceIndices:[...this.expansionPushedTraceIndices],cleanupMutatedTraceIndices:[...this.cleanupMutatedTraceIndices],discardedExpansionMutationStats:null===this.discardedExpansionMutationStats?null:{...this.discardedExpansionMutationStats},initialPadClearanceViolationCount:this.initialPadClearanceViolationCount,remainingPadClearanceViolationCount:this.remainingPadClearanceViolationCount,initialPadClearanceViolationCountByClearance:{...this.initialPadClearanceViolationCountByClearance},remainingPadClearanceViolationCountByClearance:{...this.remainingPadClearanceViolationCountByClearance},budgetLimitedExpansion:this.budgetLimitedExpansion,finalAcceptanceUsed:this.finalAcceptanceUsed,cleanupCompleted:this.cleanupCompleted,clearanceRepairCompleted:this.clearanceRepairCompleted,cleanupBestEffortAccepted:this.cleanupBestEffortAccepted,clearanceRepairBestEffortAccepted:this.clearanceRepairBestEffortAccepted,cleanupStatus:this.connectivityRollbackPhases.includes(\"cleanup\")?\"connectivity_rollback\":this.immutableSafetyRollbackPhases.includes(\"cleanup\")?\"immutable_safety_rollback\":this.cleanupBestEffortAccepted?\"budget_limited\":this.cleanupCompleted?\"completed\":\"cleanup\"===this.phase?\"in_progress\":\"not_started\",clearanceRepairStatus:this.connectivityRollbackPhases.includes(\"clearance-repair\")?\"connectivity_rollback\":this.immutableSafetyRollbackPhases.includes(\"clearance-repair\")?\"immutable_safety_rollback\":this.clearanceRepairBestEffortAccepted?\"budget_limited\":this.clearanceRepairCompleted?\"completed\":\"repair-trace-clearance\"===this.phase?\"in_progress\":\"not_started\",cleanupIterationBudget:this.cleanupIterationBudget,clearanceRepairIterationBudget:this.clearanceRepairIterationBudget,completionReason:\"complete\"===this.phase||this.solved?this.connectivityRollbackCount\u003e0?\"connectivity_rollback\":this.immutableSafetyRollbackCount\u003e0?\"immutable_safety_rollback\":this.connectivityValidationError?\"connectivity_validation_unavailable\":this.finalAcceptanceUsed?\"total_iteration_budget\":this.budgetLimitedExpansion?\"expansion_budget\":this.cleanupBestEffortAccepted?\"cleanup_budget\":this.clearanceRepairBestEffortAccepted?\"clearance_repair_budget\":this.remainingImmutableViaViolationCount\u003e0?\"immutable_via_violations_preserved\":\"completed\":null,resultStatus:this.finalAcceptanceUsed||this.budgetLimitedExpansion||this.cleanupBestEffortAccepted||this.clearanceRepairBestEffortAccepted||this.connectivityRollbackCount\u003e0||this.immutableSafetyRollbackCount\u003e0||null!==this.connectivityValidationError||this.remainingImmutableViaViolationCount\u003e0?\"best_effort\":\"complete\",failedSubSolverCount:this.failedSubSolverCount,retainedFailedSubSolverCount:this.failedSubSolvers?.length??0,expansionIterationBudget:this.getExpansionIterationBudget(),finalizationIterationReserve:this.getFinalizationIterationReserve(),spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){return this.solved||\"complete\"===this.phase?1:this.budgetLimitedExpansion?.99:0===this.traceOrder.length?1:Math.min(.99,(this.passIndex+Math.max(0,this.traceOrderCursor)/this.traceOrder.length)/this.maxPassCount)}getConstructorParams(){return[this.inputProblem,this.options]}getOutput(){return structuredClone(this.lastConnectivitySafeTraces)}visualize(){const t=[],e=[];for(let n=0;n\u003cthis.traces.length;n++){const o=this.traces[n],i=this.resolveNominalTraceWidth(o);for(const t of o.route)\"via\"===t.route_type\u0026\u0026e.push({center:t,radius:(t.via_diameter??.6)/2,fill:\"#d4a017\",stroke:\"#7a5700\"});for(let e=0;e\u003co.route.length-1;e++){const r=o.route[e],s=o.route[e+1];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)continue;const a=n===this.traceIndex\u0026\u0026e===this.routeSegmentIndex,c=r.width\u003e=i-Mq\u0026\u0026s.width\u003e=i-Mq,l=\"bottom\"===r.layer;t.push({points:[r,s],strokeColor:a?\"#ff8c00\":c?l?\"#2468c7\":\"#169c45\":l?\"#8b4bb8\":\"#cc3344\",strokeWidth:Math.max(r.width,s.width)})}}return{coordinateSystem:\"cartesian\",title:`Power trace expander: ${this.phase}`,lines:t,points:[],circles:e,rects:this.obstacleIndex.items.filter(t=\u003e\"obstacle\"===t.kind).slice(0,2e3).map(t=\u003e({center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,fill:\"rgba(80,80,80,0.12)\",stroke:\"rgba(80,80,80,0.35)\"})),texts:[]}}},UJ=class extends si{constructor(t,e={}){if(super(),this.inputSrj=t,this.options=e,this.powerTraceExpanderSolver=new GJ(t,e),0===e.onlyConnectionNames?.length)return this.MAX_ITERATIONS=1,this.progress=1,this.solved=!0,void(this.stats={selectedTraceCount:0,bypassed:!0});this.MAX_ITERATIONS=this.powerTraceExpanderSolver.MAX_ITERATIONS+1}inputSrj;options;powerTraceExpanderSolver;_step(){const t=this.powerTraceExpanderSolver;if(t.step(),this.progress=t.progress,this.stats=t.stats,t.failed)return this.error=t.error,void(this.failed=!0);t.solved\u0026\u0026(this.solved=!0)}getConstructorParams(){return[this.inputSrj,this.options]}getOutput(){if(!this.solved)throw new Error(\"Cannot get power trace expansion output before solving\");return this.powerTraceExpanderSolver.getOutput()}visualize(){return Ho({...this.inputSrj,traces:this.getOutput()},{traceColorMode:\"layer\"})}},ZJ=({connections:t,originalConnections:e,layerCount:n,obstacles:o,defaultViaHoleDiameter:i,connMap:r})=\u003e{const s=new Map;for(const t of e)s.has(t.name)||s.set(t.name,t.__netConnectionName);const a=t.map(t=\u003e{if(2!==t.pointsToConnect.length)throw new Error(`Expected Pipeline7 output connection \"${t.name}\" to have two points, got ${t.pointsToConnect.length}`);const[e,n]=t.pointsToConnect;return{connection:t,connectsTo:[e?.pointId,n?.pointId].filter(t=\u003eBoolean(t)),outputConnectionName:t.__netConnectionName??s.get(t.name)??t.__rootConnectionNames?.[0]??t.name}}),c=o.filter(t=\u003e(t.__zLayers?.length??t.layers?.length??0)\u003e1),l=new Map,d=t=\u003e{let e=l.get(t.connectionName);e||(e=new Map,l.set(t.connectionName,e));const n=e.get(t.rootConnectionName);if(n)return n;const o=c.filter(e=\u003efo(e,t,r));return e.set(t.rootConnectionName,o),o};return t=\u003e{const e=[],o=new Map;for(const e of t){const t=o.get(e.connectionName);t?t.push(e):o.set(e.connectionName,[e])}for(const{connection:t,connectsTo:s,outputConnectionName:c}of a){const a=o.get(t.name)??[];for(let o=0;o\u003ca.length;o+=1){const l=a[o];e.push({type:\"pcb_trace\",pcb_trace_id:`${t.name}_${o}`,connection_name:c,connectsTo:s,route:Mo(l,n,{connectionPoints:t.pointsToConnect,defaultViaHoleDiameter:i,connectedMultilayerObstacles:d(l),connMap:r})})}}return e}},qJ=({connections:t,originalConnections:e,hdRoutes:n,layerCount:o,obstacles:i,defaultViaHoleDiameter:r,connMap:s})=\u003eZJ({connections:t,originalConnections:e,layerCount:o,obstacles:i,defaultViaHoleDiameter:r,connMap:s})(n),JJ=t=\u003e{const e=Math.max(t.minTraceWidth+.1,2*t.minTraceWidth);return t.connections.flatMap(n=\u003e(n.nominalTraceWidth??t.nominalTraceWidth??t.minTraceWidth)+1e-6\u003e=e?[n.name]:[])},KJ=(t,e,n=new Map(t.map(t=\u003e[t.connectionName,t])))=\u003e{const o=new Map(e.map(t=\u003e[t.name,t]));return t.map(t=\u003e{if(0===t.route.length)throw new Error(`Cannot lock PCB terminals for empty route \"${t.connectionName}\"`);const e=o.get(t.connectionName);if(!e)throw new Error(`Cannot lock PCB terminals: connection \"${t.connectionName}\" was not found`);if(2!==e.pointsToConnect.length)throw new Error(`Cannot lock PCB terminals for \"${t.connectionName}\": expected 2 connection points, found ${e.pointsToConnect.length}`);const i=n.get(t.connectionName)??t,r=new Map;for(const n of e.pointsToConnect)if(n.pcb_port_id){if(r.has(n.pcb_port_id))throw new Error(`Cannot lock duplicate PCB terminal \"${n.pcb_port_id}\" for \"${t.connectionName}\"`);r.set(n.pcb_port_id,n)}if(0===r.size)return t;const s=[i.startPcbPortId,i.endPcbPortId].filter(t=\u003evoid 0!==t);if(0===s.length)return t;if(new Set(s).size!==s.length||s.some(t=\u003e!r.has(t)))throw new Error(`Cannot lock PCB terminals for \"${t.connectionName}\": route endpoint IDs do not match connection terminal IDs`);const a=i.startPcbPortId?r.get(i.startPcbPortId):void 0,c=i.endPcbPortId?r.get(i.endPcbPortId):void 0,l=t.route.map((e,n)=\u003e{if(0===n\u0026\u0026a)return{...e,x:a.x,y:a.y,pcb_port_id:a.pcb_port_id};if(n===t.route.length-1\u0026\u0026c)return{...e,x:c.x,y:c.y,pcb_port_id:c.pcb_port_id};const o={...e};return delete o.pcb_port_id,o});return{...t,route:l}})},QJ=({originalSrj:t,newlyRoutedTraces:e,currentPreloadedTraces:n,expandedConnectionNames:o,resolveConnectedTraceAliases:i=!1})=\u003e{const r=n??t.traces??[],s=i?tK({originalSrj:t,newlyRoutedTraces:e,preloadedTraces:r,expandedConnectionNames:o}):new Set(r.filter(t=\u003eo.includes(t.connection_name))),a=r.filter(t=\u003e!s.has(t)),c=new Set([...e.map(t=\u003et.pcb_trace_id),...a.map(t=\u003et.pcb_trace_id)]),l=r.filter(t=\u003es.has(t)).map(t=\u003e{const e=t.pcb_trace_id;let n=e,o=2;for(;c.has(n);)n=`${e}_power_expansion_${o++}`;return c.add(n),{...t,pcb_trace_id:n,__replaces_pcb_trace_id:t.__replaces_pcb_trace_id??t.pcb_trace_id}});return{...t,traces:[...e,...l],fixedTraces:a}},tK=({originalSrj:t,newlyRoutedTraces:e,preloadedTraces:n,expandedConnectionNames:o})=\u003e{const i=new Set(n.map(t=\u003et.pcb_trace_id)),r=new Set([...i,...e.map(t=\u003et.pcb_trace_id)]),s=e.map((t,e)=\u003e{if(!i.has(t.pcb_trace_id))return t;const n=`__pipeline7_new_trace_${e}_${t.pcb_trace_id}`;let o=n,s=2;for(;r.has(o);)o=`${n}_${s++}`;return r.add(o),{...t,pcb_trace_id:o}}),a=new Pq({...t,traces:[...s,...n]}),c=new Set(a.canonicalize([...o]));return new Set(n.filter(t=\u003ea.canonicalize([t.connection_name]).some(t=\u003ec.has(t))))};function eK(t){return new Set((t??[]).filter(t=\u003et._isComponentTopologyNode).map(t=\u003et.capacityMeshNodeId))}function nK(t,e){return t.nodeIds.some(t=\u003ee.has(t))}function oK({sharedEdgeSegments:t,componentCapacityMeshNodeIds:e}){return t.filter(t=\u003e!nK(t,e))}function iK(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var rK=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e;const n=fX(t);this.originalSrj=n,this.opts={...e};const o=this.opts;if(this.effort=o.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=o.maxNodeDimension??16,this.maxNodeRatio=o.maxNodeRatio??6,this.minNodeArea=o.minNodeArea??.1**2,this.visualizationTraceColorMode=o.visualizationTraceColorMode??\"layer\",this.setSimpleRouteJson(n),void 0===o.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,n=Math.max(t,e),i=o.targetMinCapacity??.5;o.capacityDepth=$s(n,i)}this.cacheProvider=void 0===o.cacheProvider?oo():null===o.cacheProvider?null:o.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;getSolverName(){return\"AutoroutingPipelineSolver7_MultiGraph\"}preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;componentTopologyGeneratorSolver;topologyPlanningSolver;topologyMergingSolver;globalTopologyGeneratorSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;exactGeometryDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;lengthMatchingPostProcessingSolver;powerTraceExpansionSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;componentDetectionSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;visualizationTraceColorMode;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;sharedEdgeSegmentsWithNecessaryCrampedPortPoints;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[iK(\"preprocessSimpleRouteJsonSolver\",_X,t=\u003e[t.originalSrj,{traceColorMode:t.visualizationTraceColorMode}],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),iK(\"componentDetectionSolver\",UZ,t=\u003e[{inputSrj:t.srj}]),iK(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),iK(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),iK(\"topologyPlanningSolver\",_q,t=\u003e[{inputSrj:t.srjWithPointPairs,componentDetectionOutput:t.componentDetectionSolver.getOutput(),viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.topologyPlanningSolver.getOutput();t.globalTopologyGeneratorSolver=t.topologyPlanningSolver.globalTopologySolver,t.componentTopologyGeneratorSolver=new vq(t.topologyPlanningSolver)}}),iK(\"topologyMergingSolver\",fq,t=\u003e{const e=t.topologyPlanningSolver.getOutput();return[{layerCount:t.srj.layerCount,nodeGroups:[{groupId:\"global\",nodes:e.globalMeshNodes,isComponent:!1},...e.componentMeshNodes.map((t,e)=\u003e({groupId:`component-${e}`,nodes:t,isComponent:!0}))]}]},{onSolved:t=\u003e{t.capacityNodes=t.topologyMergingSolver.getOutput()}}),iK(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver.outputNodes}}),iK(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),iK(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),iK(\"necessaryCrampedPortPointSolver\",sf,t=\u003e{const e=eK(t.capacityNodes);return[{capacityMeshNodes:t.capacityNodes.filter(t=\u003e!e.has(t.capacityMeshNodeId)),sharedEdgeSegments:oK({sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),componentCapacityMeshNodeIds:e}),simpleRouteJson:t.srjWithPointPairs}]},{onSolved:t=\u003e{const e=eK(t.capacityNodes);t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints=function({originalSharedEdgeSegments:t,filteredSharedEdgeSegments:e,componentCapacityMeshNodeIds:n}){const o=new Map(e.map(t=\u003e[t.edgeId,t]));return t.map(t=\u003enK(t,n)?t:o.get(t.edgeId)??t)}({originalSharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),filteredSharedEdgeSegments:t.necessaryCrampedPortPointSolver.getOutput(),componentCapacityMeshNodeIds:e})}}),iK(\"portPointPathingSolver\",jj,t=\u003e{const e=t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints??t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,preserveTerminalPcbPortIds:!0,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0,USE_SELECTIVE_RERIP_ROUTING:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),iK(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),iK(\"highDensityRouteSolver\",zs,t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length\u003e0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!0,growShrinkFallbackToInvalidGeometryOnFailure:!0,captureSearchDebug:!1}]}),iK(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),iK(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2,maxSampleEntries:80}]),iK(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,preserveTerminalPcbPortIds:!0}]),iK(\"traceSimplificationSolver\",vc,t=\u003e[{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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,enableCrossingViaReduction:!0,iterations:2}]),iK(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),iK(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:KJ(t.traceWidthSolver.getHdRoutesWithWidths(),t.netToPointPairsSolver?.newConnections??[],new Map((t.highDensityStitchSolver?.mergedHdRoutes??[]).map(t=\u003e[t.connectionName,t]))),connMap:t.connMap,effort:t.effort,maxIterations:16,enableLargeBoardBroadFallback:!1,enablePostSolveClearanceRelaxation:!1}]),iK(\"exactGeometryDrcForceImproveSolver\",wz,t=\u003e{const e=t.globalDrcForceImproveSolver.getOutput(),n=(t=\u003e{const e={...t.srjWithPointPairs,obstacles:t.originalSrj.obstacles,minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter??t.srjWithPointPairs.minViaDiameter},n=Math.max(Yo(t.originalSrj).padDiameter,e.minTraceWidth)+Math.max(.1,.1),o=new s_(e,{connMap:t.connMap,includeTraceViaOwnerMetadata:!0,traceClearance:.1,viaClearance:.1,spatialCellSize:n}),i=ZJ(t),r=t.originalSrj.traces??[];return({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline7 autorouting DRC evaluation requires HD routes\");const s=i(n),a=r.length?[...r,...s]:s;return o.evaluate(a)}})({connections:t.netToPointPairsSolver?.newConnections??[],originalConnections:t.originalSrj.connections,layerCount:t.srj.layerCount,obstacles:t.srj.obstacles,defaultViaHoleDiameter:t.viaHoleDiameter,connMap:t.connMap,srjWithPointPairs:t.srjWithPointPairs,originalSrj:t.originalSrj});return[{srj:t.srjWithPointPairs,hdRoutes:e,connMap:t.connMap,effort:t.effort,viaHoleDiameter:t.viaHoleDiameter,drcEvaluator:n,viaInPadDrcEvaluator:n,maxIterations:32,enableLargeBoardBroadFallback:!1,enableBroadFallback:!1,enableTargetedErrorSweep:!0,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:t.originalSrj.allowViaInPad??!1,viaInPadMaxIterations:32,broadMaxIterations:12,broadPassMultiplier:3}]}),iK(\"lengthMatchingPostProcessingSolver\",lU,t=\u003e{const e=t.netToPointPairsSolver;if(!e)throw new Error(\"Pipeline7: length-matching post-processing requires NetToPointPairsSolver output\");const n=e.newConnections,o=new Map;for(const e of t.srj.differentialPairs??[])for(const t of e.connectionNames){const e=n.filter(e=\u003ee.name===t||e.__rootConnectionNames?.includes(t)||e.__netConnectionName===t);if(1!==e.length)throw new Error(`Pipeline7: differential pair connection \"${t}\" must resolve to exactly one final point-pair connection, got ${e.length}`);o.set(t,e[0].name)}const i=t.exactGeometryDrcForceImproveSolver.getOutput(),r=(t.srj.differentialPairs??[]).map(t=\u003e{const e=t.connectionNames.map(t=\u003e{const e=o.get(t);if(!e)throw new Error(`Pipeline7: differential pair connection \"${t}\" is missing from final routed output`);return e});if(e[0]===e[1])throw new Error(`Pipeline7: differential pair ${t.connectionNames.join(\"/\")} resolves both members to \"${e[0]}\"`);if(void 0===t.traceGap)return{connectionNames:e,lengthTolerance:t.lengthTolerance,maxUncoupledLength:t.maxUncoupledLength};const n=e.map(t=\u003e{const e=i.filter(e=\u003ee.connectionName===t);if(1!==e.length)throw new Error(`Pipeline7: differential pair connection \"${t}\" must resolve to exactly one final HD route, got ${e.length}`);return e[0]}),r=t.traceGap+n.reduce((t,e)=\u003et+e.traceThickness/2,0);return{connectionNames:e,lengthTolerance:t.lengthTolerance,maxUncoupledLength:t.maxUncoupledLength,minimumCenterlineDistance:r,maximumCenterlineDistance:r}});return[{hdRoutes:i,differentialPairs:r,obstacles:t.srj.obstacles,bounds:t.srj.bounds,layerCount:t.srj.layerCount}]}),iK(\"powerTraceExpansionSolver\",UJ,t=\u003e{const e=t.opts.powerTraceExpansion??{},n=e.onlyConnectionNames??JJ(t.originalSrj);return[QJ({originalSrj:t.originalSrj,newlyRoutedTraces:t.getPrePowerTraceOutputSimplifiedPcbTraces(),expandedConnectionNames:n}),{allowNewVias:!1,...e,onlyConnectionNames:n}]})];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;computeProgress(){const t=this.activeSubSolver?.progress??0;return(this.currentPipelineStepIndex+t)/this.pipelineDef.length}_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\u0026\u0026(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),\"lengthMatchingPostProcessingSolver\"!==t.solverName\u0026\u0026\"powerTraceExpansionSolver\"!==t.solverName||(this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,this.iterations+this.activeSubSolver.MAX_ITERATIONS+1)),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\u0026\u0026this.activeSubSolver)return this.visualizeStage(this.activeSubSolver);const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.componentDetectionSolver?.visualize(),o=this.componentTopologyGeneratorSolver?.visualize(),i=this.globalTopologyGeneratorSolver?.visualize(),r=this.topologyMergingSolver?.visualize(),s=this.nodeDimensionSubdivisionSolver?.visualize(),a=this.nodeTargetMerger?.visualize(),c=this.singleLayerNodeMerger?.visualize(),l=this.strawSolver?.visualize(),d=this.edgeSolver?.visualize(),h=this.deadEndSolver?.visualize(),u=this.availableSegmentPointSolver?.visualize(),p=this.portPointPathingSolver?.visualize(),m=this.multiSectionPortPointOptimizer?.visualize(),g=this.uniformPortDistributionSolver?.visualize(),f=this.highDensityRouteSolver?.visualize(),y=this.highDensityForceImproveSolver?.visualize(),_=this.highDensityRepairSolver?.visualize(),b=this.highDensityStitchSolver?.visualize(),x=this.traceSimplificationSolver?.visualize(),v=this.lengthMatchingPostProcessingSolver?.visualize(),S=this.traceWidthSolver?.visualize(),I=this.necessaryCrampedPortPointSolver?.visualize(),C=(this.highDensityRouteSolver?.visualize(),this.originalSrj),P=C.outline,M=[];if(M.push({points:[{x:C.bounds?.minX??-50,y:C.bounds?.minY??-50},{x:C.bounds?.maxX??50,y:C.bounds?.minY??-50},{x:C.bounds?.maxX??50,y:C.bounds?.maxY??50},{x:C.bounds?.minX??-50,y:C.bounds?.maxY??50},{x:C.bounds?.minX??-50,y:C.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),P\u0026\u0026P.length\u003e=2){const t=P.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),M.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const N=Oo(C),w={points:[...C.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,C.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(C.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,C.layerCount),label:N(t)}))],lines:M},T={traceColorMode:this.visualizationTraceColorMode},R=Yj({srj:C,visualizationOptions:T}),E=pi(w,R),A=this.preprocessSimpleRouteJsonSolver?.visualize(),O=this.globalDrcForceImproveSolver?.visualize(),k=this.exactGeometryDrcForceImproveSolver?.visualize(),L=[E,A,n,o,t,e,i,r,s,a,c,l,d,h,u,I,p,m,g,f?pi(w,f):null,y,_,b,x,S,O,k,v,this.solved?pi({lines:M},Yj({srj:this.originalSrj,visualizationOptions:T}),this.visualizeFinalOutput()):null].filter(Boolean),D=pi(...L);return\"net\"===this.visualizationTraceColorMode?xq(D,this.colorMap):D}visualizeStage(t){const e=t.visualize();return\"net\"===this.visualizationTraceColorMode?xq(e,this.colorMap):e}visualizeFinalOutput(){const t=this.visualizationTraceColorMode,e=this.getOutputSimpleRouteJson();return Ho(e,{traceColorMode:t})}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.componentTopologyGeneratorSolver?this.componentTopologyGeneratorSolver.visualize():this.componentDetectionSolver?this.componentDetectionSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){if(this.lengthMatchingPostProcessingSolver){const{hdRoutes:t}=this.lengthMatchingPostProcessingSolver.getOutput();return t}return this.exactGeometryDrcForceImproveSolver?.getOutput()??this.globalDrcForceImproveSolver?.getOutput()??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\");return this.powerTraceExpansionSolver?this.powerTraceExpansionSolver.getOutput():this.getPrePowerTraceOutputSimplifiedPcbTraces()}getPrePowerTraceOutputSimplifiedPcbTraces(){return qJ({connections:this.netToPointPairsSolver?.newConnections??[],originalConnections:this.originalSrj.connections,hdRoutes:this._getOutputHdRoutes(),layerCount:this.srj.layerCount,obstacles:this.srj.obstacles,defaultViaHoleDiameter:this.viaHoleDiameter,connMap:this.connMap})}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},sK=t=\u003e[...new Set(t)].sort((t,e)=\u003et-e),aK=class extends si{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1}params;outputNodes=[];outputSharedEdgeSegments=[];nodeIdByOriginalAndZ=new Map;getSolverName(){return\"SplitNodesIntoSingleLayerNodeSolver\"}_step(){this.outputNodes=this.params.capacityMeshNodes.flatMap(t=\u003esK(t.availableZ).map(e=\u003e{const n=((t,e)=\u003e`${t}__z${e}`)(t.capacityMeshNodeId,e);return this.nodeIdByOriginalAndZ.set(`${t.capacityMeshNodeId}:${e}`,n),{...t,capacityMeshNodeId:n,layer:`z${e}`,availableZ:[e],_parent:t}})),this.outputSharedEdgeSegments=this.params.sharedEdgeSegments.flatMap(t=\u003ethis.splitSharedEdgeSegment(t)),this.stats={inputNodeCount:this.params.capacityMeshNodes.length,outputNodeCount:this.outputNodes.length,inputPortPointCount:this.params.sharedEdgeSegments.reduce((t,e)=\u003et+e.portPoints.length,0),outputPortPointCount:this.outputSharedEdgeSegments.reduce((t,e)=\u003et+e.portPoints.length,0)},this.solved=!0}getSplitNodeId(t,e){return this.nodeIdByOriginalAndZ.get(`${t}:${e}`)}splitPortPoint(t){return sK(t.availableZ).flatMap(e=\u003e{const n=t.nodeIds.map(t=\u003ethis.getSplitNodeId(t,e));return n[0]\u0026\u0026n[1]?[{...t,segmentPortPointId:`${t.segmentPortPointId}__z${e}`,availableZ:[e],nodeIds:[n[0],n[1]]}]:[]})}splitSharedEdgeSegment(t){const e=new Map;for(const n of t.portPoints.flatMap(t=\u003ethis.splitPortPoint(t))){const t=n.availableZ[0];if(void 0===t)continue;const o=e.get(t)??[];o.push(n),e.set(t,o)}return[...e.entries()].map(([e,n])=\u003e({...t,edgeId:`${t.edgeId}__z${e}`,nodeIds:n[0].nodeIds,availableZ:[e],portPoints:n}))}getOutput(){return{capacityMeshNodes:this.outputNodes,sharedEdgeSegments:this.outputSharedEdgeSegments}}getConstructorParams(){return[this.params]}visualize(){return{rects:this.outputNodes.map(t=\u003e({...Dc(t),label:`${t.capacityMeshNodeId}\\n${t.layer}`})),points:this.outputSharedEdgeSegments.flatMap(t=\u003et.portPoints.map(t=\u003e({x:t.x,y:t.y,label:`${t.segmentPortPointId}\\nz${t.availableZ.join(\",\")}`})))}}};function cK(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var lK=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;nodeSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityForceImproveRoutes;highDensityRepairSolver;highDensityRepairRoutes;highDensityStitchSolver;globalDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;splitNodesIntoSingleLayerNodeSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[cK(\"preprocessSimpleRouteJsonSolver\",_X,t=\u003e[t.originalSrj],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),cK(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),cK(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),cK(\"nodeSolver\",Kn,t=\u003e[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=\u003e{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),cK(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver?.outputNodes??[]}}),cK(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),cK(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),cK(\"necessaryCrampedPortPointSolver\",sf,t=\u003e[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),cK(\"splitNodesIntoSingleLayerNodeSolver\",aK,t=\u003e[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput()}],{onSolved:t=\u003e{t.capacityNodes=t.splitNodesIntoSingleLayerNodeSolver.getOutput().capacityMeshNodes}}),cK(\"portPointPathingSolver\",jj,t=\u003e{const e=t.splitNodesIntoSingleLayerNodeSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:e.capacityMeshNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.sharedEdgeSegments.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections,assignableViaObstacles:t.originalSrj.obstacles});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),cK(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),cK(\"highDensityRouteSolver\",zs,t=\u003e{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length\u003e0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=\u003e[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]}),cK(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.getHighDensityNodePortPointsWithAssignableViasFirst(),hdRoutes:t.getMovableHighDensityRoutes(t.highDensityRouteSolver.routes),colorMap:t.colorMap,totalStepsPerNode:Math.max(20,Math.round(60*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}],{onSolved:t=\u003e{t.highDensityForceImproveRoutes=t.mergeMovableHighDensityRoutesBack(t.highDensityRouteSolver.routes,t.highDensityForceImproveSolver.getOutput())}}),cK(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.getHighDensityNodePortPointsWithAssignableViasFirst(),hdRoutes:t.getMovableHighDensityRoutes(t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes),obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2}],{onSolved:t=\u003e{const e=t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes;t.highDensityRepairRoutes=t.mergeMovableHighDensityRoutesBack(e,t.highDensityRepairSolver.getOutput())}}),cK(\"highDensityStitchSolver\",KY,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairRoutes??t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,allowedLayerTransitionPointKeys:uf(t.originalSrj.obstacles)}]),cK(\"traceSimplificationSolver\",vc,t=\u003e[{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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,iterations:2}]),cK(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),cK(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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\u0026\u0026(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\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.nodeSolver?.visualize(),o=this.nodeDimensionSubdivisionSolver?.visualize(),i=this.nodeTargetMerger?.visualize(),r=this.singleLayerNodeMerger?.visualize(),s=this.strawSolver?.visualize(),a=this.edgeSolver?.visualize(),c=this.deadEndSolver?.visualize(),l=this.availableSegmentPointSolver?.visualize(),d=this.splitNodesIntoSingleLayerNodeSolver?.visualize(),h=this.portPointPathingSolver?.visualize(),u=this.multiSectionPortPointOptimizer?.visualize(),p=this.uniformPortDistributionSolver?.visualize(),m=this.highDensityRouteSolver?.visualize(),g=this.highDensityForceImproveSolver?.visualize(),f=this.highDensityRepairSolver?.visualize(),y=this.highDensityStitchSolver?.visualize(),_=this.traceSimplificationSolver?.visualize(),b=this.necessaryCrampedPortPointSolver?.visualize(),x=(this.highDensityRouteSolver?.visualize(),this.originalSrj),v=x.outline,S=[];if(S.push({points:[{x:x.bounds?.minX??-50,y:x.bounds?.minY??-50},{x:x.bounds?.maxX??50,y:x.bounds?.minY??-50},{x:x.bounds?.maxX??50,y:x.bounds?.maxY??50},{x:x.bounds?.minX??-50,y:x.bounds?.maxY??50},{x:x.bounds?.minX??-50,y:x.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),v\u0026\u0026v.length\u003e=2){const t=v.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),S.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const I=Oo(x),C={points:[...x.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,x.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(x.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,x.layerCount),label:I(t)}))],lines:S},P=Yj({srj:x}),M=[pi(C,P),t,e,n,o,i,r,s,a,c,l,b,d,h,u,p,m?pi(C,m):null,g,f,y,_,this.solved?pi({lines:S},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...M)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){const t=this.globalDrcForceImproveSolver?.getOutput();return t\u0026\u0026this.routesOnlyUsePreplacedVias(t)?t:this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityRepairRoutes??this.highDensityForceImproveRoutes??this.highDensityStitchSolver.mergedHdRoutes}routesOnlyUsePreplacedVias(t){const e=uf(this.originalSrj.obstacles);return 0===e.size||t.every(t=\u003et.vias.every(t=\u003ee.has(af(t))))}getHighDensityNodePortPointsWithAssignableViasFirst(){return[...this.highDensityNodePortPoints??[]].sort((t,e)=\u003e{const n=t.capacityMeshNodeId.startsWith(\"assignable-via:\");return n===e.capacityMeshNodeId.startsWith(\"assignable-via:\")?0:n?-1:1})}getPreplacedAssignableViaObstacles(){return this.originalSrj.obstacles.filter(t=\u003e!0===t.netIsAssignable\u0026\u0026(t.layers?.length??0)\u003e1)}isFixedPreplacedViaRoute(t){const e=this.getPreplacedAssignableViaObstacles();return 0!==e.length\u0026\u00260!==t.vias.length\u0026\u0026e.some(e=\u003e[...t.route,...t.vias].every(t=\u003eBe(t,e)\u003c=0))}getMovableHighDensityRouteIndexes(t){return t.map((t,e)=\u003ethis.isFixedPreplacedViaRoute(t)?-1:e).filter(t=\u003e-1!==t)}getMovableHighDensityRoutes(t){return this.getMovableHighDensityRouteIndexes(t).map(e=\u003et[e])}mergeMovableHighDensityRoutesBack(t,e){const n=this.getMovableHighDensityRouteIndexes(t),o=[...t];for(let t=0;t\u003cn.length;t++)o[n[t]]=e[t];return o}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 o=n.__netConnectionName??this.originalSrj.connections.find(t=\u003et.name===n.name)?.__netConnectionName,i=e.filter(t=\u003et.connectionName===n.name);for(let e=0;e\u003ci.length;e++){const r=i[e],s={type:\"pcb_trace\",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.srj.obstacles,connMap:this.connMap})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},dK=(t,e)=\u003e{const n=t.filter(t=\u003e(t.rootConnectionName??t.connectionName)===e);if(0!==n.length)return n.reduce((t,e)=\u003et+e.route.slice(1).reduce((t,n,o)=\u003e{const i=e.route[o];return t+Math.hypot(n.x-i.x,n.y-i.y)},0),0)},hK=(t,e)=\u003e{const n=new Set(t.flatMap(t=\u003evoid 0===t.maxLengthSkew?[]:t.connectionNames));return e.flatMap(t=\u003e{if(!n.has(t.name))return[];const e=t.pointsToConnect[0],o=t.pointsToConnect.at(-1);if(!e||!o||e===o)throw new Error(`Length matching: bus connection \"${t.name}\" needs at least two points`);return[{...t,pointsToConnect:[e,o]}]})},uK=class extends si{constructor(t){super(),this.params=t,this.differentialPairSolver=new lU({hdRoutes:t.hdRoutes,differentialPairs:t.differentialPairs,obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,minTraceToPadEdgeClearance:t.obstacleMargin}),this.MAX_ITERATIONS=this.differentialPairSolver.MAX_ITERATIONS+1e5+10}params;differentialPairSolver;busLengthMatchingSolver;outputHdRoutes;getSolverName(){return\"LengthMatchingPostProcessingSolver\"}_step(){if(!this.differentialPairSolver.solved)return this.differentialPairSolver.step(),void(this.differentialPairSolver.failed\u0026\u0026(this.failed=!0,this.error=this.differentialPairSolver.error));if(!this.busLengthMatchingSolver){const n=this.differentialPairSolver.getOutput().hdRoutes,o=(t=this.params.buses,e=n,t.flatMap(t=\u003e{const n=t.maxLengthSkew;if(void 0===n||t.connectionNames.length\u003c2)return[];const o=t.connectionNames.map(n=\u003e{const o=dK(e,n);if(void 0===o)throw new Error(`Length matching: bus \"${t.busId}\" has no routed geometry for connection \"${n}\"`);return{connectionName:n,length:o}}),i=o.reduce((t,e)=\u003ee.length\u003et.length?e:t);return o.flatMap(t=\u003et.connectionName===i.connectionName?[]:[{connectionNames:[t.connectionName,i.connectionName],lengthTolerance:n}])}));return 0===o.length?(this.outputHdRoutes=n,void(this.solved=!0)):void(this.busLengthMatchingSolver=new RG({hdRoutes:n,originalConnections:hK(this.params.buses,this.params.connections),differentialPairs:o,obstacles:this.params.obstacles,bounds:this.params.bounds,layerCount:this.params.layerCount,obstacleMargin:this.params.obstacleMargin}))}var t,e;if(this.busLengthMatchingSolver.step(),this.busLengthMatchingSolver.failed)return this.failed=!0,void(this.error=this.busLengthMatchingSolver.error);this.busLengthMatchingSolver.solved\u0026\u0026(this.outputHdRoutes=this.busLengthMatchingSolver.getOutput().matchedHdRoutes,((t,e)=\u003e{for(const n of t){if(void 0===n.maxLengthSkew||n.connectionNames.length\u003c2)continue;const t=n.connectionNames.map(t=\u003e{const o=dK(e,t);if(void 0===o)throw new Error(`Length matching: bus \"${n.busId}\" lost routed geometry for connection \"${t}\"`);return o}),o=Math.max(...t)-Math.min(...t);if(o\u003en.maxLengthSkew+1e-6)throw new Error(`Length matching: bus \"${n.busId}\" routed length skew ${o.toFixed(4)}mm exceeds ${n.maxLengthSkew.toFixed(4)}mm`)}})(this.params.buses,this.outputHdRoutes),this.solved=!0)}getOutput(){if(!this.solved||!this.outputHdRoutes)throw new Error(\"LengthMatchingPostProcessingSolver output requested before completion\");return{hdRoutes:this.outputHdRoutes}}visualize(){return this.busLengthMatchingSolver?.visualize()??this.differentialPairSolver.visualize()}},pK=1e-9,mK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=pK\u0026\u0026Math.abs(t.y-e.y)\u003c=pK\u0026\u0026t.z===e.z,gK=(t,e)=\u003e{if(0===t.length)return void t.push(...e.route);const n=t.at(-1);if(e.route[0]\u0026\u0026mK(n,e.route[0]))t.push(...e.route.slice(1));else{if(!e.route.at(-1)||!mK(n,e.route.at(-1)))throw new Error(`Pipeline9 could not reconnect mutated preloaded segment \"${e.connectionName}\"`);t.push(...e.route.slice(0,-1).reverse())}},fK=(t,e)=\u003e{const n=t.preloadedRoutePositionStart??t.preloadedRouteIndex,o=e.preloadedRoutePositionStart??e.preloadedRouteIndex,i=t.preloadedRoutePositionEnd??n,r=e.preloadedRoutePositionEnd??o;return n-o||i-r||t.preloadedRouteIndex-e.preloadedRouteIndex||t.connectionName.localeCompare(e.connectionName)},yK=t=\u003e{const e=t.route.flatMap(t=\u003e\"wire\"===t.route_type||\"through_obstacle\"===t.route_type?[t.width]:[]);return e.length\u003e0?Math.max(...e):void 0},_K=({trace:t,updatedTraceRoutes:e,layerCount:n,defaultViaHoleDiameter:o,obstacles:i,connMap:r})=\u003e{if(0===e.length)throw new Error(`Pipeline9 lost every fixed route for mutated trace \"${t.pcb_trace_id}\"`);const s=[];let a,c=0,l=0;for(const t of[...e].sort(fK))gK(s,t),c=Math.max(c,t.traceThickness),l=Math.max(l,t.viaDiameter),a??=t.rootConnectionName;const d={connectionName:t.connection_name,rootConnectionName:a,traceThickness:yK(t)??c,viaDiameter:l,route:s,vias:s.slice(0,-1).flatMap((t,e)=\u003e{const n=s[e+1];return t.z!==n.z\u0026\u0026Math.abs(t.x-n.x)\u003c=pK\u0026\u0026Math.abs(t.y-n.y)\u003c=pK?[{x:n.x,y:n.y}]:[]})};return Mo(d,n,{defaultViaHoleDiameter:o,obstacles:i,connMap:r})},bK=(t,e)=\u003et.filter(t=\u003e{if(!0===t.isThroughObstacle)return!1;const n=t.preloadedRoutePositionStart,o=t.preloadedRoutePositionEnd;if(void 0===n||void 0===o)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" is missing route-position metadata`);const i=Math.min(n,o),r=Math.max(n,o);return i\u003e=e.routePositionStart-pK\u0026\u0026r\u003c=e.routePositionEnd+pK}),xK=({trace:t,originalTraceRoutes:e,updatedTraceRoutes:n,layerCount:o,defaultViaHoleDiameter:i,obstacles:r,connMap:s})=\u003e{if(0===n.length)throw new Error(`Pipeline9 lost every fixed route for mutated trace \"${t.pcb_trace_id}\"`);const a=(t=\u003e{const e=[];let n=0;for(let o=0;o\u003ct.route.length;o++)\"through_obstacle\"===t.route[o]?.route_type\u0026\u0026(n\u003co\u0026\u0026e.push({routePositionStart:n,routePositionEnd:o-1}),n=o+1);return n\u003ct.route.length\u0026\u0026e.push({routePositionStart:n,routePositionEnd:t.route.length-1}),e})(t),c=n.filter(t=\u003e!0!==t.isThroughObstacle);for(const t of c){if(1!==a.filter(e=\u003ebK([t],e).includes(t)).length)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" crosses an immutable through-obstacle primitive`)}const l=[];let d=0;for(const c of a){l.push(...t.route.slice(d,c.routePositionStart));const a=bK(e,c),h=bK(n,c);if(a.length\u003e0\u0026\u00260===h.length)throw new Error(`Pipeline9 lost every fixed route for an ordinary section of mutated trace \"${t.pcb_trace_id}\"`);l.push(...h.length\u003e0?_K({trace:t,updatedTraceRoutes:h,layerCount:o,defaultViaHoleDiameter:i,obstacles:r,connMap:s}):t.route.slice(c.routePositionStart,c.routePositionEnd+1)),d=c.routePositionEnd+1}return l.push(...t.route.slice(d)),l},vK=(t,e)=\u003e{const n=new Set(e.map(t=\u003et.pcb_trace_id));return t.map(t=\u003e{if(!n.has(t.pcb_trace_id))return n.add(t.pcb_trace_id),t;const e=`${t.pcb_trace_id}_routed`;let o=e,i=2;for(;n.has(o);)o=`${e}_${i}`,i+=1;return n.add(o),{...t,pcb_trace_id:o}})},SK=(t,e,n)=\u003e{const o=t=\u003e`${t.x}:${t.y}`,i=new Map;for(const t of e){const e=o(t.center),n=i.get(e)??[];n.push(t),i.set(e,n)}const r=new Map;for(const e of t)for(const t of e.pointsToConnect){if(!t.pcb_port_id)continue;const e=r.get(t.pcb_port_id)??new Set,s=\"layers\"in t?t.layers:[t.layer];for(const t of s)e.add(ko(t,n));for(const r of i.get(o(t))??[])if(!(r.layers.length\u003c=1)\u0026\u0026r.connectedTo.includes(t.pcb_port_id))for(const t of r.layers)e.add(ko(t,n));r.set(t.pcb_port_id,e)}return r},IK=(t,e)=\u003enew Map(t.flatMap(t=\u003e{const n=e.getNetConnectedToId(t.connectionName)??(t.rootConnectionName?e.getNetConnectedToId(t.rootConnectionName)??(e.netMap[t.rootConnectionName]?t.rootConnectionName:void 0):void 0);return n?[[t.connectionName,n]]:[]})),CK=1e-9,PK=1e-6,MK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=PK\u0026\u0026Math.abs(t.y-e.y)\u003c=PK\u0026\u0026t.z===e.z,NK=t=\u003enew Map(t.map((t,e)=\u003e[t.pcb_trace_id,e])),wK=(t,e)=\u003e{const n=t[0],o=t.at(-1);if(!n||!o)throw new Error(\"Pipeline9 cannot split an empty preloaded route\");if(n.z!==o.z)throw new Error(\"Pipeline9 cannot partially split a preloaded layer transition\");return{...n,x:n.x+(o.x-n.x)*e,y:n.y+(o.y-n.y)*e}},TK=({traces:t,fixedHdRoutes:e,sections:n})=\u003e{const o=(({traces:t,sections:e})=\u003e{const n=NK(t),o=new Map;for(const t of e){const e=n.get(t.traceId);if(void 0===e)throw new Error(`Pipeline9 hypergraph changed missing preloaded trace \"${t.traceId}\"`);const i=o.get(e)??[];i.push({start:Math.min(t.startRoutePosition,t.endRoutePosition),end:Math.max(t.startRoutePosition,t.endRoutePosition)}),o.set(e,i)}for(const t of o.values())t.sort((t,e)=\u003et.start-e.start||t.end-e.end);return o})({traces:t,sections:n});return e.flatMap(t=\u003e{const e=o.get(t.preloadedTraceIndex);if(!e?.length)return[t];const n=t.preloadedRoutePositionStart,i=t.preloadedRoutePositionEnd;if(void 0===n||void 0===i)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" is missing route-position metadata`);if(Math.abs(i-n)\u003c=CK)return e.some(t=\u003et.start-CK\u003c=n\u0026\u0026n\u003c=t.end+CK)?[]:[t];let r=[{start:n,end:i}];for(const t of e)r=r.flatMap(e=\u003e{if(t.end\u003c=e.start+CK||t.start\u003e=e.end-CK)return[e];const n=[];return t.start\u003ee.start+CK\u0026\u0026n.push({start:e.start,end:Math.min(t.start,e.end)}),t.end\u003ce.end-CK\u0026\u0026n.push({start:Math.max(t.end,e.start),end:e.end}),n});return r.map((e,o)=\u003e{const r=(e.start-n)/(i-n),s=(e.end-n)/(i-n);return{...t,connectionName:`${t.connectionName}_hypergraph_fixed_${o}`,preloadedRoutePositionStart:e.start,preloadedRoutePositionEnd:e.end,route:[wK(t.route,r),wK(t.route,s)],vias:[]}})})},RK=({traces:t,sections:e,stitchedHdRoutes:n,layerCount:o})=\u003e{const i=NK(t);return e.map((t,r)=\u003e{const s=i.get(t.traceId);if(void 0===s)throw new Error(`Pipeline9 cannot materialize missing preloaded trace \"${t.traceId}\"`);const[a,c]=((t,e)=\u003e{const n=t.connection.pointsToConnect.map(t=\u003e({x:t.x,y:t.y,z:ko(bo(t),e)}));if(!n[0]||!n[1])throw new Error(`Pipeline9 changed section \"${t.connectionName}\" is missing an endpoint`);return[n[0],n[1]]})(t,o),l=n.flatMap(e=\u003e{if(e.connectionName!==t.connectionName)return[];const n=(({route:t,sectionStart:e,sectionEnd:n})=\u003e{const o=t.route[0],i=t.route.at(-1);if(!o||!i)return null;const r=o.z===e.z\u0026\u0026i.z===n.z,s=o.z===n.z\u0026\u0026i.z===e.z,a=r?xe(o,e)+xe(i,n):Number.POSITIVE_INFINITY,c=s?xe(o,n)+xe(i,e):Number.POSITIVE_INFINITY;return Number.isFinite(a)||Number.isFinite(c)?a\u003c=c?{score:a,reverse:!1}:{score:c,reverse:!0}:null})({route:e,sectionStart:a,sectionEnd:c});return n?[{route:e,...n}]:[]});l.sort((t,e)=\u003et.score-e.score);const d=l[0],h=l[1];if(!d||h\u0026\u0026Math.abs(h.score-d.score)\u003c=PK)throw new Error(`Pipeline9 expected one nearest stitched route for changed preloaded section \"${t.connectionName}\", got ${l.length}`);const u=(({route:t,reverse:e,sectionStart:n,sectionEnd:o})=\u003e{const i=e?(t=\u003e{const e=[...t].reverse().map(t=\u003e{const{toNextSegmentType:e,...n}=t;return n});for(let n=0;n\u003ct.length-1;n++){const o=t[n]?.toNextSegmentType;o\u0026\u0026(e[t.length-n-2]={...e[t.length-n-2],toNextSegmentType:o})}return e})(t.route):[...t.route];if(!i[0]||!i.at(-1))throw new Error(`Pipeline9 cannot materialize empty route \"${t.connectionName}\"`);return MK(i[0],n)||i.unshift(n),MK(i.at(-1),o)||i.push(o),{...t,route:i}})({route:d.route,reverse:d.reverse,sectionStart:a,sectionEnd:c});return{...u,preloadedTraceIndex:s,preloadedRouteIndex:Number.MAX_SAFE_INTEGER-e.length+r,preloadedRoutePositionStart:t.startRoutePosition,preloadedRoutePositionEnd:t.endRoutePosition,isThroughObstacle:!1}})},EK=1e-6,AK=t=\u003et.map(t=\u003e{const e=[];for(const n of t.route){const o=e.at(-1);if(!o||o.z===n.z||\"through_obstacle\"===o.toNextSegmentType){e.push(n);continue}const i=Math.abs(o.x-n.x)\u003c=EK\u0026\u0026Math.abs(o.y-n.y)\u003c=EK,r=t.vias.some(t=\u003eMath.abs(t.x-o.x)\u003c=EK\u0026\u0026Math.abs(t.y-o.y)\u003c=EK),s=t.vias.some(t=\u003eMath.abs(t.x-n.x)\u003c=EK\u0026\u0026Math.abs(t.y-n.y)\u003c=EK);if(i)e.push(n);else{if(!r\u0026\u0026!s)throw new Error(`Pipeline9 route \"${t.connectionName}\" changes layers from z=${o.z} to z=${n.z} without an explicit via`);if(r===s)throw new Error(`Pipeline9 route \"${t.connectionName}\" has an ambiguous layer transition between (${o.x}, ${o.y}) and (${n.x}, ${n.y})`);r?e.push({x:o.x,y:o.y,z:n.z}):e.push({x:n.x,y:n.y,z:o.z}),e.push(n)}}return{...t,route:e}}),OK=1e-9,kK=t=\u003e({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}),LK=(t,e)=\u003et.x\u003e=e.minX-OK\u0026\u0026t.x\u003c=e.maxX+OK\u0026\u0026t.y\u003e=e.minY-OK\u0026\u0026t.y\u003c=e.maxY+OK,DK=(t,e,n)=\u003en\u003c=OK?t:n\u003e=.999999999?e:{x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n,z:t.z},zK=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;if(Math.abs(o)\u003c=OK\u0026\u0026Math.abs(i)\u003c=OK)return LK(t,n)\u0026\u0026LK(e,n)?{start:t,end:e}:null;let r=0,s=1;const a=[[-o,t.x-n.minX],[o,n.maxX-t.x],[-i,t.y-n.minY],[i,n.maxY-t.y]];for(const[t,e]of a){if(Math.abs(t)\u003c=OK){if(e\u003c0)return null;continue}const n=e/t;if(t\u003c0?r=Math.max(r,n):s=Math.min(s,n),r\u003es+OK)return null}return{start:DK(t,e,r),end:DK(t,e,s)}},FK=t=\u003e{const e=t.sourceRoutes[0],n=`pipeline9_fallback:${e.connectionName}`,o=`${n}:start`,i=`${n}:end`;return[{...t.start.point,portPointId:o,nextPortPointId:i,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName},{...t.end.point,portPointId:i,prevPortPointId:o,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName}]},BK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=OK\u0026\u0026Math.abs(t.y-e.y)\u003c=OK\u0026\u0026t.z===e.z,jK=(t,e)=\u003et.sourceRoute.preloadedTraceIndex===e.sourceRoute.preloadedTraceIndex\u0026\u0026BK(t.sourceRoute.route.at(-1),e.sourceRoute.route[0]),$K=(t,e,n=new Set)=\u003e{const o=new Map,i=[],r=new Set(t.portPoints.map(t=\u003et.z)),s=e.map(e=\u003e((t,e)=\u003e{const n=kK(e);let o,i;for(let e=0;e\u003ct.route.length-1;e++){const r=zK(t.route[e],t.route[e+1],n);r\u0026\u0026(o??={segmentIndex:e,point:r.start},i={segmentIndex:e,point:r.end})}return o\u0026\u0026i?Math.abs(o.point.x-i.point.x)\u003c=OK\u0026\u0026Math.abs(o.point.y-i.point.y)\u003c=OK\u0026\u0026o.point.z===i.point.z?null:{sourceRoute:t,start:o,end:i}:null})(e,t)).filter(t=\u003enull!==t),a=s.filter(t=\u003e!0!==t.sourceRoute.isThroughObstacle\u0026\u0026(((t,e)=\u003e0===e.size||[t.start.point,...t.sourceRoute.route.slice(t.start.segmentIndex+1,t.end.segmentIndex+1),t.end.point].some(t=\u003ee.has(t.z)))(t,r)||n.has(t.sourceRoute.connectionName))).sort((t,e)=\u003et.sourceRoute.preloadedTraceIndex-e.sourceRoute.preloadedTraceIndex||t.sourceRoute.preloadedRouteIndex-e.sourceRoute.preloadedRouteIndex),c=new Set(a.map(t=\u003et.sourceRoute)),l=s.map(t=\u003et.sourceRoute).filter(t=\u003e!c.has(t)),d=[];for(let t=0;t\u003ca.length;t++){const e=a[t],n=a[t-1],o=d.at(-1);n\u0026\u0026o\u0026\u0026jK(n,e)?(o.sourceRoutes.push(e.sourceRoute),o.end=e.end):d.push({sourceRoutes:[e.sourceRoute],start:e.start,end:e.end})}for(const t of d){const e=t.sourceRoutes[0].connectionName;if(o.has(e))throw new Error(`Pipeline9 regional fallback found duplicate fixed route section identity \"${e}\"`);o.set(e,t),i.push(FK(t))}return{nodeWithPortPoints:{...t,portPoints:[...t.portPoints,...i.flatMap(t=\u003et)],portPointsInPairs:[...t.portPointsInPairs??[],...i]},fixedRouteSectionsByConnectionName:o,fixedObstacleRoutes:l}},YK=t=\u003e{const e=[];for(let n=0;n\u003ct.length-1;n++){const o=t[n],i=t[n+1];o.z!==i.z\u0026\u0026Math.abs(o.x-i.x)\u003c=OK\u0026\u0026Math.abs(o.y-i.y)\u003c=OK\u0026\u0026e.push({x:i.x,y:i.y})}return e},XK=(t,e)=\u003eVK({section:t,replacement:e,sourceMutationMasks:new Map,replacementIsMutated:!1}).route,VK=({section:t,replacement:e,sourceMutationMasks:n,replacementIsMutated:o})=\u003e{const i=t.sourceRoutes[0],r=t.sourceRoutes.at(-1),s=((t,e)=\u003e{const n=t.route,o=n[0],i=n.at(-1);if(!o||!i)throw new Error(`Pipeline9 regional fallback produced an empty replacement for \"${e.sourceRoutes[0].connectionName}\"`);const r=Math.hypot(o.x-e.start.point.x,o.y-e.start.point.y)+Math.hypot(i.x-e.end.point.x,i.y-e.end.point.y);return Math.hypot(i.x-e.start.point.x,i.y-e.start.point.y)+Math.hypot(o.x-e.end.point.x,o.y-e.end.point.y)\u003cr?[...n].reverse():n})(e,t),a=[],c=[],l=(t,e)=\u003e{const o=n.get(t.connectionName);if(o\u0026\u0026o.length!==t.route.length-1)throw new Error(`Pipeline9 fixed route mutation mask for \"${t.connectionName}\" has ${o.length} segments, expected ${t.route.length-1}`);return o?.[e]??!1},d=(t,e)=\u003e{const n=a.at(-1);if(n){if(!BK(n,t)){if(n.z!==t.z\u0026\u0026(Math.abs(n.x-t.x)\u003eOK||Math.abs(n.y-t.y)\u003eOK)){const o={...t,z:n.z};BK(n,o)||(a.push(o),c.push(e))}BK(a.at(-1),t)||(a.push(t),c.push(e))}}else a.push(t)};d(i.route[0],!1);for(let e=1;e\u003c=t.start.segmentIndex;e++)d(i.route[e],l(i,e-1));d(t.start.point,l(i,t.start.segmentIndex));const h=c.length;for(const t of s.slice(1,-1))d(t,o);d(t.end.point,o);const u=c.length\u003eh;for(let e=t.end.segmentIndex+1;e\u003cr.route.length;e++)d(r.route[e],l(r,e-1));if(c.length!==a.length-1)throw new Error(`Pipeline9 produced an invalid mutation mask while splicing \"${i.connectionName}\"`);return{route:{...i,preloadedRoutePositionStart:i.preloadedRoutePositionStart,preloadedRoutePositionEnd:r.preloadedRoutePositionEnd,traceThickness:Math.max(...t.sourceRoutes.map(t=\u003et.traceThickness)),viaDiameter:Math.max(...t.sourceRoutes.map(t=\u003et.viaDiameter)),route:a,vias:YK(a)},mutatedSegments:c,replacementProducedSegment:u}},WK=1e-6,HK=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=WK\u0026\u0026Math.abs(t.y-e.y)\u003c=WK\u0026\u0026t.z===e.z,GK=(t,e)=\u003e{for(const n of e)t.at(-1)\u0026\u0026HK(t.at(-1),n)||t.push(n)},UK=t=\u003et.slice(0,-1).flatMap((e,n)=\u003e{const o=t[n+1];return e.z!==o.z\u0026\u0026Math.abs(e.x-o.x)\u003c=WK\u0026\u0026Math.abs(e.y-o.y)\u003c=WK?[{x:o.x,y:o.y}]:[]}),ZK=t=\u003e{const e=t.preloadedRoutePositionStart,n=t.preloadedRoutePositionEnd;if(void 0===e||void 0===n)throw new Error(`Pipeline9 fixed route \"${t.connectionName}\" is missing route-position metadata`);return{start:Math.min(e,n),end:Math.max(e,n)}},qK=(t,e)=\u003e{const n=ZK(t),o=ZK(e);return t.preloadedTraceIndex-e.preloadedTraceIndex||n.start-o.start||n.end-o.end||t.preloadedRouteIndex-e.preloadedRouteIndex||t.connectionName.localeCompare(e.connectionName)},JK=(t,e)=\u003e{const n=t.route.at(-1),o=e.route[0];return Boolean(n\u0026\u0026o\u0026\u0026t.preloadedTraceIndex===e.preloadedTraceIndex\u0026\u0026HK(n,o))},KK=(t,e)=\u003e{const n=t.preloadedRoutePositionStart??t.preloadedRouteIndex;return n+((t.preloadedRoutePositionEnd??t.preloadedRouteIndex)-n)*e/(t.route.length-1)},QK=(t,e)=\u003et.route[e].z!==t.route[e+1].z,tQ=({updatedFixedRoutes:t,regionalMutationMasks:e})=\u003e{const n=[],o=(({updatedFixedRoutes:t,regionalMutationMasks:e})=\u003e{const n=new Map;for(const o of t){if(0===o.route.length)throw new Error(`Pipeline9 cannot normalize empty fixed route \"${o.connectionName}\"`);const t=o.route.length-1;if(n.has(o.connectionName))throw new Error(`Pipeline9 cannot normalize duplicate fixed route \"${o.connectionName}\"`);const i=e.get(o.connectionName);if(i\u0026\u0026i.length!==t)throw new Error(`Pipeline9 fixed route mutation mask for \"${o.connectionName}\" has ${i.length} segments, expected ${t}`);const r=!0!==o.isThroughObstacle\u0026\u00260===(o.jumpers?.length??0);n.set(o.connectionName,Array.from({length:t},(t,e)=\u003er\u0026\u0026(i?.[e]??!1)))}let o=[];const i=()=\u003e{for(;o[0]\u0026\u0026QK(o[0].route,o[0].segmentIndex);){const t=o.shift();n.get(t.route.connectionName)[t.segmentIndex]=!1}for(;o.at(-1)\u0026\u0026QK(o.at(-1).route,o.at(-1).segmentIndex);){const t=o.pop();n.get(t.route.connectionName)[t.segmentIndex]=!1}o=[]};let r;for(const e of[...t].sort(qK)){r\u0026\u0026!JK(r,e)\u0026\u0026i();const t=n.get(e.connectionName);if(0!==t.length){for(let n=0;n\u003ct.length;n++)t[n]?o.push({route:e,segmentIndex:n}):i();r=e}else i(),r=e}return i(),n})({updatedFixedRoutes:t,regionalMutationMasks:e});for(const e of t){const t=e.route.length-1,i=o.get(e.connectionName);if(0===t){n.push({route:e,mutated:!1});continue}const r=[];for(let e=0;e\u003ct;e++){const t=i[e],n=r.at(-1);n?.mutated===t?n.end=e+1:r.push({start:e,end:e+1,mutated:t})}for(const[t,o]of r.entries()){const i=e.route.slice(o.start,o.end+1),s={...e,connectionName:1===r.length?e.connectionName:`${e.connectionName}_mutation_fragment_${t}`,preloadedRouteIndex:e.preloadedRouteIndex+t/(r.length+1),preloadedRoutePositionStart:KK(e,o.start),preloadedRoutePositionEnd:KK(e,o.end),route:i,vias:UK(i)};n.push({route:s,mutated:o.mutated})}}return n},eQ=({updatedFixedRoutes:t,regionalMutationMasks:e})=\u003e{const n=tQ({updatedFixedRoutes:t,regionalMutationMasks:e}),o=n.map(({route:t})=\u003et),i=(t=\u003e{const e=[];let n;for(const o of[...t].sort((t,e)=\u003eqK(t.route,e.route))){const t=o.route;if(!o.mutated){n=void 0;continue}const i=t.route[0],r=t.route.at(-1);if(!i||!r||t.route.length\u003c2)throw new Error(`Pipeline9 cannot simplify empty fixed route \"${t.connectionName}\"`);const s=n?.sourceRoutes.at(-1);n\u0026\u0026s\u0026\u0026JK(s,t)?(n.sourceRoutes.push(t),n.end={segmentIndex:t.route.length-2,point:r}):(n={sourceRoutes:[t],start:{segmentIndex:0,point:i},end:{segmentIndex:t.route.length-2,point:r}},e.push(n))}return e})(n),r=i.map((t,e)=\u003e{const n=((t,e)=\u003e{const n=t.sourceRoutes[0],o=t.sourceRoutes.at(-1);if(!n||!o)throw new Error(\"Pipeline9 cannot simplify an empty mutation section\");const i=[t.start.point];for(const[e,n]of t.sourceRoutes.entries()){const o=0===e,r=e===t.sourceRoutes.length-1,s=o?t.start.segmentIndex+1:0,a=r?t.end.segmentIndex+1:n.route.length;GK(i,n.route.slice(s,a))}if(GK(i,[t.end.point]),i.length\u003c2)throw new Error(`Pipeline9 mutation section for \"${n.connectionName}\" has no routable span`);return{connectionName:`pipeline9_mutated_preload_${n.preloadedTraceIndex}_${e}`,rootConnectionName:n.rootConnectionName,traceThickness:Math.max(...t.sourceRoutes.map(t=\u003et.traceThickness)),viaDiameter:Math.max(...t.sourceRoutes.map(t=\u003et.viaDiameter)),route:i,vias:UK(i)}})(t,e);return{connectionName:n.connectionName,section:t,hdRoute:n}}),s=new Set(r.flatMap(({section:t})=\u003et.sourceRoutes.map(t=\u003et.connectionName)));return{sections:r,immutableHdRoutes:o.filter(t=\u003e!s.has(t.connectionName)),normalizedFixedRoutes:o}},nQ=1e-9,oQ=(t,e,n,o,i)=\u003e{const r=i.getNetConnectedToId(t.connection_name)??t.connection_name,s=[],a=(n,i,a=o,c=[],l,d,h=!1)=\u003e{n.length\u003c2||s.push({connectionName:`${t.connection_name}_fixed_${e}_${s.length}`,rootConnectionName:r,preloadedTraceIndex:e,preloadedRouteIndex:s.length,preloadedRoutePositionStart:l,preloadedRoutePositionEnd:d,isThroughObstacle:h,traceThickness:Math.max(nQ,i),viaDiameter:Math.max(nQ,a),route:n,vias:c})};for(let e=0;e\u003ct.route.length;e++){const i=t.route[e];if(\"via\"===i.route_type){a([{x:i.x,y:i.y,z:ko(i.from_layer,n)},{x:i.x,y:i.y,z:ko(i.to_layer,n)}],nQ,i.via_diameter??o,[{x:i.x,y:i.y}],e,e);continue}if(\"through_obstacle\"===i.route_type){const t=ko(i.from_layer,n),r=ko(i.to_layer,n);for(let n=Math.min(t,r);n\u003c=Math.max(t,r);n++)a([{...i.start,z:n},{...i.end,z:n}],i.width,o,[],e,e+1,!0);continue}const r=t.route[e+1];\"wire\"===i.route_type\u0026\u0026\"wire\"===r?.route_type\u0026\u0026i.layer===r.layer\u0026\u0026a([{x:i.x,y:i.y,z:ko(i.layer,n)},{x:r.x,y:r.y,z:ko(r.layer,n)}],Math.max(i.width,r.width),o,[],e,e+1)}return s};function iQ(t,e){return{x:t.a*e.x+t.b*e.y+t.c,y:t.d*e.x+t.e*e.y+t.f}}var rQ={highResolutionCellSize:.1,highResolutionCellThickness:8,lowResolutionCellSize:.4,traceMargin:.15,traceThickness:.1,viaDiameter:.3,viaMinDistFromBorder:.15},sQ={...rQ},aQ=(t,e,n)=\u003e{const[o,i]=t;if(o===i)return;const r=((t,e)=\u003e{const n=t.portPointId??`${t.connectionName}:${t.x}:${t.y}:${t.z}`,o=e.portPointId??`${e.connectionName}:${e.x}:${e.y}:${e.z}`;return n\u003co?`${n}|${o}`:`${o}|${n}`})(o,i);e.has(r)||(e.add(r),n.push(t))},cQ=(t,e,n)=\u003e{for(let o=0;o\u003ct.length-1;o++)aQ([t[o],t[o+1]],e,n)},lQ=t=\u003e{const e=[],n=new Set,o=(t=\u003e{const e=new Map;for(const n of t)n.portPointId\u0026\u0026e.set(n.portPointId,n);return e})(t);for(const i of t){if(i.prevPortPointId){const t=o.get(i.prevPortPointId);t\u0026\u0026t.connectionName===i.connectionName\u0026\u0026aQ([t,i],n,e)}if(i.nextPortPointId){const t=o.get(i.nextPortPointId);t\u0026\u0026t.connectionName===i.connectionName\u0026\u0026aQ([i,t],n,e)}}if(0===e.length)return cQ(t,n,e),e;const i=(t=\u003e{const e=new Set;for(const[n,o]of t)n.portPointId\u0026\u0026e.add(n.portPointId),o.portPointId\u0026\u0026e.add(o.portPointId);return e})(e),r=t.filter(t=\u003e!t.portPointId||!i.has(t.portPointId));return cQ(r,n,e),e};function dQ(t,e,n){return Math.max(e,Math.min(n,t))}var hQ=[\"left\",\"top\",\"right\",\"bottom\",\"middle\"],uQ=class{f=new Float64Array(1024);seq=new Uint32Array(1024);id=new Int32Array(1024);n=0;push(t,e,n){this.ensureCapacity(this.n+1);let o=this.n++;for(this.f[o]=t,this.seq[o]=e,this.id[o]=n;o\u003e0;){const t=o-1\u003e\u003e1;if(this.less(t,o))break;this.swap(o,t),o=t}}pop(){const t=this.id[0];return this.n--,this.n\u003e0\u0026\u0026(this.f[0]=this.f[this.n],this.seq[0]=this.seq[this.n],this.id[0]=this.id[this.n],this.siftDown(0)),t}get size(){return this.n}clear(){this.n=0}ensureCapacity(t){if(t\u003c=this.f.length)return;let e=this.f.length;for(;e\u003ct;)e*=2;const n=new Float64Array(e);n.set(this.f),this.f=n;const o=new Uint32Array(e);o.set(this.seq),this.seq=o;const i=new Int32Array(e);i.set(this.id),this.id=i}siftDown(t){for(;;){const e=2*t+1,n=e+1;if(e\u003e=this.n)return;let o=e;if(n\u003cthis.n\u0026\u0026!this.less(e,n)\u0026\u0026(o=n),this.less(t,o))return;this.swap(t,o),t=o}}less(t,e){const n=this.f[t],o=this.f[e];return n!==o?n\u003co:this.seq[t]\u003cthis.seq[e]}swap(t,e){const n=this.f[t];this.f[t]=this.f[e],this.f[e]=n;const o=this.seq[t];this.seq[t]=this.seq[e],this.seq[e]=o;const i=this.id[t];this.id[t]=this.id[e],this.id[e]=i}},pQ=class{z=new Int32Array(1024);cellId=new Int32Array(1024);g=new Float64Array(1024);parent=new Int32Array(1024);ripHead=new Int32Array(1024).fill(-1);ripCount=new Int32Array(1024);length=0;clear(){this.length=0}push(t,e,n,o,i,r){this.ensureCapacity(this.length+1);const s=this.length++;return this.z[s]=t,this.cellId[s]=e,this.g[s]=n,this.parent[s]=o,this.ripHead[s]=i,this.ripCount[s]=r,s}ensureCapacity(t){if(t\u003c=this.z.length)return;let e=this.z.length;for(;e\u003ct;)e*=2;const n=new Int32Array(e);n.set(this.z),this.z=n;const o=new Int32Array(e);o.set(this.cellId),this.cellId=o;const i=new Float64Array(e);i.set(this.g),this.g=i;const r=new Int32Array(e);r.set(this.parent),this.parent=r;const s=new Int32Array(e);s.fill(-1),s.set(this.ripHead.subarray(0,this.length)),this.ripHead=s;const a=new Int32Array(e);a.set(this.ripCount.subarray(0,this.length)),this.ripCount=a}},mQ=class{connId=new Int32Array(1024);prev=new Int32Array(1024).fill(-1);length=0;clear(){this.length=0}append(t,e){this.ensureCapacity(this.length+1);const n=this.length++;return this.connId[n]=e,this.prev[n]=t,n}contains(t,e){for(let n=t;n\u003e=0;n=this.prev[n])if(this.connId[n]===e)return!0;return!1}collect(t,e){e.length=0;for(let n=t;n\u003e=0;n=this.prev[n])e.push(this.connId[n])}ensureCapacity(t){if(t\u003c=this.connId.length)return;let e=this.connId.length;for(;e\u003ct;)e*=2;const n=new Int32Array(e);n.set(this.connId),this.connId=n;const o=new Int32Array(e);o.fill(-1),o.set(this.prev.subarray(0,this.length)),this.prev=o}};function gQ(t,e){return e??t.replace(/_mst\\d+$/,\"\")}function fQ(t,e){const n=t.x-e.center.x,o=t.y-e.center.y,i=Math.cos(-e.rotationRadians),r=Math.sin(-e.rotationRadians);return{x:n*i-o*r,y:n*r+o*i}}function yQ(t){return{minX:-t.width/2,minY:-t.height/2,maxX:t.width/2,maxY:t.height/2}}function _Q(t,e,n){return Math.max(e,Math.min(n,t))}function bQ(t,e){for(let n=0;n\u003ct.length;n++)if(t[n]===e)return;t.push(e)}function xQ(t,e){for(let n=0;n\u003ct.length;n++)if(t[n].cellId===e.cellId)return;t.push(e)}function vQ(t,e,n,o,i,r,s){const a=t-_Q(t,o,r),c=e-_Q(e,i,s);return a*a+c*c\u003c=n*n}function SQ(t){const e=t.segmentEnd.x-t.segmentStart.x,n=t.segmentEnd.y-t.segmentStart.y,o=e**2+n**2;if(0===o)return(t.point.x-t.segmentStart.x)**2+(t.point.y-t.segmentStart.y)**2;const i=_Q(((t.point.x-t.segmentStart.x)*e+(t.point.y-t.segmentStart.y)*n)/o,0,1),r=t.segmentStart.x+i*e,s=t.segmentStart.y+i*n;return(t.point.x-r)**2+(t.point.y-s)**2}function IQ(t){const e=_Q(t.point.x,t.rect.minX,t.rect.maxX),n=_Q(t.point.y,t.rect.minY,t.rect.maxY),o=t.point.x-e,i=t.point.y-n;return o*o+i*i}function CQ(t){return(t.second.x-t.first.x)*(t.third.y-t.first.y)-(t.second.y-t.first.y)*(t.third.x-t.first.x)}function PQ(t){return!(Math.abs(CQ({first:t.segmentStart,second:t.segmentEnd,third:t.point}))\u003e1e-9)\u0026\u0026(t.point.x\u003e=Math.min(t.segmentStart.x,t.segmentEnd.x)\u0026\u0026t.point.x\u003c=Math.max(t.segmentStart.x,t.segmentEnd.x)\u0026\u0026t.point.y\u003e=Math.min(t.segmentStart.y,t.segmentEnd.y)\u0026\u0026t.point.y\u003c=Math.max(t.segmentStart.y,t.segmentEnd.y))}function MQ(t){const e=CQ({first:t.firstStart,second:t.firstEnd,third:t.secondStart}),n=CQ({first:t.firstStart,second:t.firstEnd,third:t.secondEnd}),o=CQ({first:t.secondStart,second:t.secondEnd,third:t.firstStart}),i=CQ({first:t.secondStart,second:t.secondEnd,third:t.firstEnd});return e*n\u003c0\u0026\u0026o*i\u003c0||(PQ({point:t.secondStart,segmentStart:t.firstStart,segmentEnd:t.firstEnd})||PQ({point:t.secondEnd,segmentStart:t.firstStart,segmentEnd:t.firstEnd})||PQ({point:t.firstStart,segmentStart:t.secondStart,segmentEnd:t.secondEnd})||PQ({point:t.firstEnd,segmentStart:t.secondStart,segmentEnd:t.secondEnd}))}function NQ(t){return MQ(t)?0:Math.min(SQ({point:t.firstStart,segmentStart:t.secondStart,segmentEnd:t.secondEnd}),SQ({point:t.firstEnd,segmentStart:t.secondStart,segmentEnd:t.secondEnd}),SQ({point:t.secondStart,segmentStart:t.firstStart,segmentEnd:t.firstEnd}),SQ({point:t.secondEnd,segmentStart:t.firstStart,segmentEnd:t.firstEnd}))}function wQ(t){if(function(t){if(0===IQ({point:t.segmentStart,rect:t.rect})||0===IQ({point:t.segmentEnd,rect:t.rect}))return!0;const e=[{x:t.rect.minX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.maxY},{x:t.rect.minX,y:t.rect.maxY}];for(let n=0;n\u003ce.length;n++){const o=(n+1)%e.length;if(MQ({firstStart:t.segmentStart,firstEnd:t.segmentEnd,secondStart:e[n],secondEnd:e[o]}))return!0}return!1}(t))return!0;const e=t.radius**2;if(IQ({point:t.segmentStart,rect:t.rect})\u003c=e||IQ({point:t.segmentEnd,rect:t.rect})\u003c=e)return!0;return[{x:t.rect.minX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.maxY},{x:t.rect.minX,y:t.rect.maxY}].some(n=\u003eSQ({point:n,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd})\u003c=e)}var TQ=class extends kt{getSolverName(){return\"HighDensitySolverB01\"}nodeWithPortPoints;obstacles;highResolutionCellSize;highResolutionCellThickness;lowResolutionCellSize;viaDiameter;MAX_RIPS;maxCellCount;traceThickness;traceMargin;obstacleClearanceMargin;viaMinDistFromBorder;showPenaltyMap;showUsedCellMap;effort;stepMultiplier;hyperParameters;initialPenaltyFn;boundsMinX;boundsMaxX;boundsMinY;boundsMaxY;gridToBoundsTransform;availableZ;zToLayer;layerToZ;layers;fineRows;fineCols;lowScale;bandRows;bandCols;regions;planeSize;cellCenterX;cellCenterY;cellMinX;cellMinY;cellMaxX;cellMaxY;cellWidth;cellHeight;cellRegion;cellRow;cellCol;viaAllowed;neighborOffset;neighborIds;neighborCosts;usedCellsFlat;sharedCellsFlat;portOwnerFlat;penalty2d;ripStateBuckets;visitedStamp;bestGStamp;bestGValue;visitedFlatStamp;sharedCrossRootPortFlat;stamp=0;connNameToId;connIdToName;connIdToRootNet;overlapFriendlyRootNets;usedIndicesByConn;unsolvedSegs;solvedRoutes;activeConnSeg=null;activeConnId=-1;nodePool;heap;ripChain;seqCounter=0;_viaOccs=[];_cellOccs=[];_rippedIds=[];ripCount;totalRipEvents=0;searchIterations=0;consecutiveSkips=0;penaltyCap;baseSearchBudgetIters;_moveCost=0;_moveRippedHead=-1;_moveRipCount=0;traceKeepoutRadius;viaKeepoutRadius;obstacleTraceRootIdsFlat;obstacleViaRootIdsByCell;obstacleRootNameToId;obstacleRootNames;obstacleTracePrimitives;obstacleViaPrimitives;obstacleRectPrimitives;obstacleTraceBlockedCellCount=0;obstacleViaBlockedCellCount=0;get unsolvedConnections(){return this.unsolvedSegs}get solvedConnectionsMap(){const t=new Map;for(let e=0;e\u003cthis.solvedRoutes.length;e++){const n=this.getSolvedRoutesForConn(e);n.length\u003e0\u0026\u0026t.set(e,n)}return t}get activeConnection(){if(!this.activeConnSeg)return null;const t=this.activeConnSeg.startCellId,e=this.activeConnSeg.endCellId;return{connectionName:this.connIdToName[this.activeConnSeg.connId]??\"\",start:{cellId:t,region:hQ[this.cellRegion[t]],row:this.cellRow[t],col:this.cellCol[t],x:this.cellCenterX[t],y:this.cellCenterY[t],z:this.activeConnSeg.startZ},end:{cellId:e,region:hQ[this.cellRegion[e]],row:this.cellRow[e],col:this.cellCol[e],x:this.cellCenterX[e],y:this.cellCenterY[e],z:this.activeConnSeg.endZ}}}get openSet(){return{length:this.heap?.size??0}}get gridStats(){return{cells:this.planeSize||0,layers:this.layers||0,states:(this.planeSize||0)*(this.layers||0),ripStateBuckets:this.ripStateBuckets||0,neighborEdges:this.neighborIds?.length??0,regionCounts:this.regions?Object.fromEntries(this.regions.map(t=\u003e[t.name,t.rows*t.cols])):{},obstacleTraceBlockedCells:this.obstacleTraceBlockedCellCount,obstacleViaBlockedCells:this.obstacleViaBlockedCellCount,obstacleRootCount:this.obstacleRootNames?.length??0,obstacleRectCount:this.obstacleRectPrimitives?.length??0}}constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.obstacles=t.obstacles,this.highResolutionCellSize=t.highResolutionCellSize??.1,this.highResolutionCellThickness=Math.max(1,Math.floor(t.highResolutionCellThickness??8)),this.lowResolutionCellSize=t.lowResolutionCellSize??.4,this.viaDiameter=t.viaDiameter,this.maxCellCount=t.maxCellCount,this.traceThickness=t.traceThickness??.1,this.traceMargin=t.traceMargin??.15,this.obstacleClearanceMargin=t.obstacleClearanceMargin??0,this.viaMinDistFromBorder=t.viaMinDistFromBorder??.15,this.showPenaltyMap=t.showPenaltyMap??!1,this.showUsedCellMap=t.showUsedCellMap??!1,this.effort=t.effort??1,this.stepMultiplier=Math.max(1,Math.floor(t.stepMultiplier??1)),this.hyperParameters={shuffleSeed:0,ripCost:8,ripTracePenalty:.5,ripViaPenalty:.75,viaBaseCost:.1,greedyMultiplier:1.5,sameRootObstacleCostMultiplier:1,...t.hyperParameters},this.MAX_ITERATIONS=1e8,this.MAX_RIPS=200,this.initialPenaltyFn=t.initialPenaltyFn}getConstructorParams(){return[{nodeWithPortPoints:this.nodeWithPortPoints,obstacles:this.obstacles,highResolutionCellSize:this.highResolutionCellSize,highResolutionCellThickness:this.highResolutionCellThickness,lowResolutionCellSize:this.lowResolutionCellSize,viaDiameter:this.viaDiameter,maxCellCount:this.maxCellCount,stepMultiplier:this.stepMultiplier,traceThickness:this.traceThickness,traceMargin:this.traceMargin,obstacleClearanceMargin:this.obstacleClearanceMargin,viaMinDistFromBorder:this.viaMinDistFromBorder,showPenaltyMap:this.showPenaltyMap,showUsedCellMap:this.showUsedCellMap,effort:this.effort,hyperParameters:this.hyperParameters,initialPenaltyFn:this.initialPenaltyFn}]}_setup(){const{nodeWithPortPoints:t}=this,{width:e,height:n,center:o}=t;if(e\u003e15||n\u003e15)return this.error=`HighDensitySolverB01 only supports routing windows up to 15x15mm; received ${e}x${n}mm`,void(this.failed=!0);const i=this.lowResolutionCellSize/this.highResolutionCellSize,r=Math.round(i);if(!Number.isFinite(i)||i\u003c=0||Math.abs(i-r)\u003e1e-9)return this.error=\"lowResolutionCellSize must be a positive integer multiple of highResolutionCellSize\",void(this.failed=!0);this.lowScale=Math.max(1,r),this.availableZ=t.availableZ??[...new Set(t.portPoints.map(t=\u003et.z))].sort((t,e)=\u003et-e),this.layers=this.availableZ.length,this.zToLayer=new Map,this.layerToZ=new Map;for(let t=0;t\u003cthis.availableZ.length;t++){const e=this.availableZ[t];this.zToLayer.set(e,t),this.layerToZ.set(t,e)}this.boundsMinX=o.x-e/2,this.boundsMaxX=o.x+e/2,this.boundsMinY=o.y-n/2,this.boundsMaxY=o.y+n/2,this.traceKeepoutRadius=this.traceMargin+this.traceThickness/2,this.viaKeepoutRadius=this.viaDiameter/2+this.traceKeepoutRadius,this.buildFiveRegionGrid(e,n),this.gridToBoundsTransform=this.computeGridToBoundsTransform();const s=this.layers*this.planeSize;if(void 0!==this.maxCellCount\u0026\u0026s\u003ethis.maxCellCount)return this.error=`Cell count ${s} exceeds maxCellCount ${this.maxCellCount}`,void(this.failed=!0);this.connNameToId=new Map,this.connIdToName=[],this.connIdToRootNet=[],this.overlapFriendlyRootNets=new Set,this.unsolvedSegs=this.buildConnectionSegs(),this.penalty2d=new Float64Array(this.planeSize);const a=e\u003e0?1/e:0,c=n\u003e0?1/n:0;for(let t=0;t\u003cthis.planeSize;t++){let e=0;this.initialPenaltyFn\u0026\u0026(e+=this.initialPenaltyFn({x:this.cellCenterX[t],y:this.cellCenterY[t],px:(this.cellCenterX[t]-this.boundsMinX)*a,py:(this.cellCenterY[t]-this.boundsMinY)*c,cellId:t,region:hQ[this.cellRegion[t]],row:this.cellRow[t],col:this.cellCol[t]})),this.penalty2d[t]=e}this.usedCellsFlat=new Int32Array(s).fill(-1),this.sharedCellsFlat=Array.from({length:s},()=\u003e{}),this.portOwnerFlat=new Int32Array(s).fill(-1),this.sharedCrossRootPortFlat=new Uint8Array(s),this.obstacleTraceRootIdsFlat=Array.from({length:s},()=\u003e{}),this.obstacleViaRootIdsByCell=Array.from({length:this.planeSize},()=\u003e{}),this.obstacleRootNameToId=new Map,this.obstacleRootNames=[],this.obstacleTracePrimitives=[],this.obstacleViaPrimitives=[],this.obstacleRectPrimitives=[];const l=this.rasterizeObstacles();if(l)return this.error=l,void(this.failed=!0);this.ripStateBuckets=1;const d=s;this.visitedStamp=new Uint32Array(d),this.bestGStamp=new Uint32Array(d),this.bestGValue=new Float64Array(d),this.visitedFlatStamp=new Uint32Array(s),this.stamp=0;const h=new Map;for(const t of this.nodeWithPortPoints.portPoints){const e=this.connNameToId.get(t.connectionName);if(void 0===e)continue;const n=this.pointToCell(t),o=n.z*this.planeSize+n.cellId,i=this.connIdToRootNet[e],r=h.get(o);void 0===r?h.set(o,i):r!==i\u0026\u0026(this.sharedCrossRootPortFlat[o]=1);const s=this.portOwnerFlat[o];this.portOwnerFlat[o]=-1===s||s===e?e:-2}this.solvedRoutes=[],this.usedIndicesByConn=[],this.ripCount=[],this.consecutiveSkips=0,this.penaltyCap=.5*this.hyperParameters.ripCost,this.shuffleConnections();const u=function(t){const e=t.planeSize*t.layers,n=t.connectionCount,o=Math.sqrt(n),i=Math.max(1,t.maxIterations),r=dQ(Math.round(e*(8+1.2*o)),15e4,12e6),s=dQ(Math.round(r*t.effort),15e4,12e6),a=dQ(Math.round(.2*i),15e4,2e6);return{maxIterationsIters:Math.max(1,Math.min(i,Math.max(a,s))),baseSearchBudgetIters:dQ(Math.round(e*(10+.8*o)*t.effort),5e4,4e6)}}({planeSize:this.planeSize,layers:this.layers,connectionCount:this.unsolvedSegs.length,effort:this.effort,maxIterations:this.MAX_ITERATIONS});this.baseSearchBudgetIters=u.baseSearchBudgetIters,this.MAX_ITERATIONS=u.maxIterationsIters,this.activeConnSeg=null,this.activeConnId=-1,this.nodePool=new pQ,this.heap=new uQ,this.ripChain=new mQ,this.seqCounter=0}_step(){for(let t=0;t\u003cthis.stepMultiplier;t++){if(this.solved||this.failed)return;this.stepOnce()}}rasterizeObstacles(){for(let t=0;t\u003cthis.obstacles.length;t++){const e=this.obstacles[t];if(\"rect\"===e.type){const n=this.rasterizeRectObstacle(e,t);if(n)return n;continue}if(e.traceThickness\u003c=0||e.viaDiameter\u003c=0||e.route.length\u003c2)return`Obstacle ${t} must have positive trace/via sizes and at least two route points`;const n=gQ(e.connectionName,e.rootConnectionName),o=this.internObstacleRootName(n);for(let n=1;n\u003ce.route.length;n++){const i=e.route[n-1],r=e.route[n];if(!(Number.isFinite(i.x)\u0026\u0026Number.isFinite(i.y)\u0026\u0026Number.isFinite(i.z)\u0026\u0026Number.isFinite(r.x)\u0026\u0026Number.isFinite(r.y)\u0026\u0026Number.isFinite(r.z)))return`Obstacle ${t} contains non-finite route coordinates`;if(i.z===r.z){const n=this.zToLayer.get(i.z);if(void 0===n)return`Obstacle ${t} uses unavailable layer z=${i.z}`;this.rasterizeObstacleTraceSegment({segmentStart:i,segmentEnd:r,layer:n,obstacleRootId:o,obstacleTraceThickness:e.traceThickness})}else if(!e.vias.some(t=\u003et.x===r.x\u0026\u0026t.y===r.y)){const n=this.rasterizeObstacleVia({center:r,obstacleRootId:o,obstacleViaDiameter:e.viaDiameter,zStart:i.z,zEnd:r.z,obstacleIndex:t});if(n)return n}}for(const n of e.vias){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))return`Obstacle ${t} contains non-finite via coordinates`;const i=this.rasterizeObstacleVia({center:n,obstacleRootId:o,obstacleViaDiameter:e.viaDiameter,zStart:n.zStart,zEnd:n.zEnd,obstacleIndex:t});if(i)return i}}return this.obstacleTraceBlockedCellCount=this.obstacleTraceRootIdsFlat.reduce((t,e)=\u003et+(e?1:0),0),this.obstacleViaBlockedCellCount=this.obstacleViaRootIdsByCell.reduce((t,e)=\u003et+(e?1:0),0),null}rasterizeRectObstacle(t,e){if(!Number.isFinite(t.center.x)||!Number.isFinite(t.center.y)||!Number.isFinite(t.width)||!Number.isFinite(t.height)||t.width\u003c=0||t.height\u003c=0)return`Rect obstacle ${e} must have finite geometry and positive dimensions`;const n=[];for(const o of t.zLayers){const t=this.zToLayer.get(o);if(void 0===t)return`Rect obstacle ${e} uses unavailable layer z=${o}`;bQ(n,t)}if(0===n.length)return`Rect obstacle ${e} must apply to at least one layer`;const o=this.internObstacleRootName(gQ(t.connectionName,t.rootConnectionName)),i={rootId:o,center:t.center,width:t.width,height:t.height,rotationRadians:(t.ccwRotationDegrees??0)*Math.PI/180,layers:n};this.obstacleRectPrimitives.push(i);const r=this.transformBoundsPointToGrid(t.center),s=Math.hypot(t.width/2,t.height/2),a=this.getConservativeGridRadius(s+this.traceThickness/2+this.traceMargin);this.forEachCellNearCircle(r.x,r.y,a,t=\u003e{for(const e of n)this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:e*this.planeSize+t,obstacleRootId:o})});const c=this.getConservativeGridRadius(s+this.viaDiameter/2+this.traceMargin);return this.forEachCellNearCircle(r.x,r.y,c,t=\u003e{this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:t,obstacleRootId:o})}),null}internObstacleRootName(t){const e=this.obstacleRootNameToId.get(t);if(void 0!==e)return e;const n=this.obstacleRootNames.length;return this.obstacleRootNames.push(t),this.obstacleRootNameToId.set(t,n),n}rasterizeObstacleTraceSegment(t){this.obstacleTracePrimitives.push({rootId:t.obstacleRootId,layer:t.layer,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd,traceRadius:t.obstacleTraceThickness/2});const e=this.transformBoundsPointToGrid(t.segmentStart),n=this.transformBoundsPointToGrid(t.segmentEnd),o=this.getConservativeGridRadius(t.obstacleTraceThickness/2+this.traceMargin),i=this.getConservativeGridRadius(t.obstacleTraceThickness/2+this.viaDiameter/2+this.traceMargin);this.forEachCellNearSegment({segmentStart:e,segmentEnd:n,radius:o},e=\u003e{this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:t.layer*this.planeSize+e,obstacleRootId:t.obstacleRootId})}),this.forEachCellNearSegment({segmentStart:e,segmentEnd:n,radius:i},e=\u003e{this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:e,obstacleRootId:t.obstacleRootId})})}rasterizeObstacleVia(t){if(void 0===t.zStart!=(void 0===t.zEnd))return`Obstacle ${t.obstacleIndex} via must provide both zStart and zEnd`;let e=Array.from({length:this.layers},(t,e)=\u003ee);if(void 0!==t.zStart\u0026\u0026void 0!==t.zEnd){if(!Number.isFinite(t.zStart)||!Number.isFinite(t.zEnd))return`Obstacle ${t.obstacleIndex} contains a non-finite via layer span`;const n=Math.min(t.zStart,t.zEnd),o=Math.max(t.zStart,t.zEnd);e=this.availableZ.flatMap((t,e)=\u003et\u003e=n\u0026\u0026t\u003c=o?[e]:[])}if(0===e.length)return null;this.obstacleViaPrimitives.push({rootId:t.obstacleRootId,center:t.center,viaRadius:t.obstacleViaDiameter/2,layers:e});const n=this.transformBoundsPointToGrid(t.center),o=this.getConservativeGridRadius(t.obstacleViaDiameter/2+this.traceThickness/2+this.traceMargin),i=this.getConservativeGridRadius(t.obstacleViaDiameter/2+this.viaDiameter/2+this.traceMargin);return this.forEachCellNearCircle(n.x,n.y,Math.max(o,i),r=\u003e{const s=this.getCellRect(r);if(vQ(n.x,n.y,o,s.minX,s.minY,s.maxX,s.maxY))for(const n of e)this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:n*this.planeSize+r,obstacleRootId:t.obstacleRootId});vQ(n.x,n.y,i,s.minX,s.minY,s.maxX,s.maxY)\u0026\u0026this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:r,obstacleRootId:t.obstacleRootId})}),null}forEachCellNearSegment(t,e){const n={x:(t.segmentStart.x+t.segmentEnd.x)/2,y:(t.segmentStart.y+t.segmentEnd.y)/2},o=Math.hypot(t.segmentEnd.x-t.segmentStart.x,t.segmentEnd.y-t.segmentStart.y)/2+t.radius;this.forEachCellNearCircle(n.x,n.y,o,n=\u003e{wQ({segmentStart:t.segmentStart,segmentEnd:t.segmentEnd,radius:t.radius,rect:this.getCellRect(n)})\u0026\u0026e(n)})}getCellRect(t){return{minX:this.cellMinX[t],minY:this.cellMinY[t],maxX:this.cellMaxX[t],maxY:this.cellMaxY[t]}}transformBoundsPointToGrid(t){const e=this.gridToBoundsTransform;return{x:(t.x-e.c)/e.a,y:(t.y-e.f)/e.e}}getConservativeGridRadius(t){return t/Math.min(Math.abs(this.gridToBoundsTransform.a),Math.abs(this.gridToBoundsTransform.e))}addObstacleRootId(t){let e=t.rootIdsByCell[t.cellIndex];e||(e=[],t.rootIdsByCell[t.cellIndex]=e),bQ(e,t.obstacleRootId)}isBlockedByObstacleRoots(t,e){if(!t)return!1;const n=this.connIdToRootNet[e];for(const e of t)if(this.obstacleRootNames[e]!==n)return!0;return!1}hasSameRootObstacle(t,e){if(!t)return!1;const n=this.connIdToRootNet[e];return t.some(t=\u003ethis.obstacleRootNames[t]===n)}isLateralMoveBlockedByObstacleGeometry(t){const e=this.connIdToRootNet[t.activeConn],n=this.activeConnSeg,o=n\u0026\u0026t.layer===n.startZ\u0026\u0026t.fromCellId===n.startCellId?n.startPoint:iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.fromCellId],y:this.cellCenterY[t.fromCellId]}),i=n\u0026\u0026t.layer===n.endZ\u0026\u0026t.toCellId===n.endCellId?n.endPoint:iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.toCellId],y:this.cellCenterY[t.toCellId]});for(const n of this.obstacleTracePrimitives){if(n.layer!==t.layer||this.obstacleRootNames[n.rootId]===e)continue;const r=n.traceRadius+this.traceThickness/2+this.obstacleClearanceMargin;if(NQ({firstStart:o,firstEnd:i,secondStart:n.segmentStart,secondEnd:n.segmentEnd})\u003cr*r)return!0}for(const n of this.obstacleViaPrimitives){if(!n.layers.includes(t.layer)||this.obstacleRootNames[n.rootId]===e)continue;const r=n.viaRadius+this.traceThickness/2+this.obstacleClearanceMargin;if(SQ({point:n.center,segmentStart:o,segmentEnd:i})\u003cr*r)return!0}for(const n of this.obstacleRectPrimitives)if(n.layers.includes(t.layer)\u0026\u0026this.obstacleRootNames[n.rootId]!==e\u0026\u0026wQ({segmentStart:fQ(o,n),segmentEnd:fQ(i,n),radius:this.traceThickness/2+this.obstacleClearanceMargin,rect:yQ(n)}))return!0;return!1}isViaMoveBlockedByObstacleGeometry(t){const e=this.connIdToRootNet[t.activeConn],n=iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.cellId],y:this.cellCenterY[t.cellId]});for(const t of this.obstacleTracePrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=t.traceRadius+this.viaDiameter/2+this.obstacleClearanceMargin;if(SQ({point:n,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd})\u003co*o)return!0}for(const t of this.obstacleViaPrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=t.viaRadius+this.viaDiameter/2+this.obstacleClearanceMargin;if((n.x-t.center.x)**2+(n.y-t.center.y)**2\u003co*o)return!0}for(const t of this.obstacleRectPrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=fQ(n,t),i=this.viaDiameter/2+this.obstacleClearanceMargin;if(IQ({point:o,rect:yQ(t)})\u003ci*i)return!0}return!1}buildFiveRegionGrid(t,e){this.fineCols=Math.max(1,Math.ceil(t/this.highResolutionCellSize)),this.fineRows=Math.max(1,Math.ceil(e/this.highResolutionCellSize)),this.bandCols=Math.min(this.highResolutionCellThickness,Math.floor(this.fineCols/2)),this.bandRows=Math.min(this.highResolutionCellThickness,Math.floor(this.fineRows/2));const n=Math.max(0,this.fineCols-2*this.bandCols),o=Math.max(0,this.fineRows-2*this.bandRows),i=n,r=n;this.regions=[{id:0,name:\"left\",fineOriginRow:0,fineOriginCol:0,fineRows:this.fineRows,fineCols:this.bandCols,cellScale:1,rows:this.fineRows,cols:this.bandCols,offset:0},{id:1,name:\"top\",fineOriginRow:0,fineOriginCol:this.bandCols,fineRows:this.bandRows,fineCols:i,cellScale:1,rows:this.bandRows,cols:i,offset:0},{id:2,name:\"right\",fineOriginRow:0,fineOriginCol:this.fineCols-this.bandCols,fineRows:this.fineRows,fineCols:this.bandCols,cellScale:1,rows:this.fineRows,cols:this.bandCols,offset:0},{id:3,name:\"bottom\",fineOriginRow:this.fineRows-this.bandRows,fineOriginCol:this.bandCols,fineRows:this.bandRows,fineCols:r,cellScale:1,rows:this.bandRows,cols:r,offset:0},{id:4,name:\"middle\",fineOriginRow:this.bandRows,fineOriginCol:this.bandCols,fineRows:o,fineCols:n,cellScale:this.lowScale,rows:o\u003e0?Math.ceil(o/this.lowScale):0,cols:n\u003e0?Math.ceil(n/this.lowScale):0,offset:0}];let s=0;for(let t=0;t\u003cthis.regions.length;t++)this.regions[t].offset=s,s+=this.regions[t].rows*this.regions[t].cols;this.planeSize=s,this.cellCenterX=new Float64Array(this.planeSize),this.cellCenterY=new Float64Array(this.planeSize),this.cellMinX=new Float64Array(this.planeSize),this.cellMinY=new Float64Array(this.planeSize),this.cellMaxX=new Float64Array(this.planeSize),this.cellMaxY=new Float64Array(this.planeSize),this.cellWidth=new Float64Array(this.planeSize),this.cellHeight=new Float64Array(this.planeSize),this.cellRegion=new Uint8Array(this.planeSize),this.cellRow=new Int32Array(this.planeSize),this.cellCol=new Int32Array(this.planeSize),this.viaAllowed=new Uint8Array(this.planeSize);for(let t=0;t\u003cthis.regions.length;t++){const e=this.regions[t];for(let t=0;t\u003ce.rows;t++){const n=e.fineOriginRow+t*e.cellScale,o=Math.min(e.fineOriginRow+e.fineRows,n+e.cellScale),i=this.boundsMinY+n*this.highResolutionCellSize,r=Math.min(this.boundsMaxY,this.boundsMinY+o*this.highResolutionCellSize);for(let n=0;n\u003ce.cols;n++){const o=e.fineOriginCol+n*e.cellScale,s=Math.min(e.fineOriginCol+e.fineCols,o+e.cellScale),a=this.boundsMinX+o*this.highResolutionCellSize,c=Math.min(this.boundsMaxX,this.boundsMinX+s*this.highResolutionCellSize),l=this.cellIdFor(e.id,t,n);this.cellCenterX[l]=(a+c)/2,this.cellCenterY[l]=(i+r)/2,this.cellMinX[l]=a,this.cellMinY[l]=i,this.cellMaxX[l]=c,this.cellMaxY[l]=r,this.cellWidth[l]=c-a,this.cellHeight[l]=r-i,this.cellRegion[l]=e.id,this.cellRow[l]=t,this.cellCol[l]=n;const d=Math.min(this.cellCenterX[l]-this.boundsMinX,this.boundsMaxX-this.cellCenterX[l],this.cellCenterY[l]-this.boundsMinY,this.boundsMaxY-this.cellCenterY[l]);this.viaAllowed[l]=d\u003e=this.viaMinDistFromBorder?1:0}}}const a=Array.from({length:this.planeSize},()=\u003e[]),c=(t,e)=\u003e{if(t===e||t\u003c0||e\u003c0)return;const n=this.cellCenterX[t]-this.cellCenterX[e],o=this.cellCenterY[t]-this.cellCenterY[e],i=Math.hypot(n,o);xQ(a[t],{cellId:e,cost:i}),xQ(a[e],{cellId:t,cost:i})};for(let t=0;t\u003cthis.regions.length;t++){const e=this.regions[t];for(let t=0;t\u003ce.rows;t++)for(let n=0;n\u003ce.cols;n++){const o=this.cellIdFor(e.id,t,n);t+1\u003ce.rows\u0026\u0026c(o,this.cellIdFor(e.id,t+1,n)),n+1\u003ce.cols\u0026\u0026c(o,this.cellIdFor(e.id,t,n+1))}}const l=this.regions[0],d=this.regions[1],h=this.regions[2],u=this.regions[3],p=this.regions[4],m=l.rows\u003e0\u0026\u0026l.cols\u003e0,g=d.rows\u003e0\u0026\u0026d.cols\u003e0,f=h.rows\u003e0\u0026\u0026h.cols\u003e0,y=u.rows\u003e0\u0026\u0026u.cols\u003e0,_=p.rows\u003e0\u0026\u0026p.cols\u003e0;if(m\u0026\u0026g)for(let t=0;t\u003cthis.bandRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(1,t,0));if(g\u0026\u0026f)for(let t=0;t\u003cthis.bandRows;t++)c(this.cellIdFor(1,t,d.cols-1),this.cellIdFor(2,t,0));if(m\u0026\u0026y)for(let t=this.fineRows-this.bandRows;t\u003cthis.fineRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(3,t-(this.fineRows-this.bandRows),0));if(y\u0026\u0026f)for(let t=this.fineRows-this.bandRows;t\u003cthis.fineRows;t++)c(this.cellIdFor(3,t-(this.fineRows-this.bandRows),u.cols-1),this.cellIdFor(2,t,0));if(m\u0026\u0026_)for(let t=this.bandRows;t\u003cthis.fineRows-this.bandRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(4,Math.floor((t-this.bandRows)/this.lowScale),0));if(f\u0026\u0026_)for(let t=this.bandRows;t\u003cthis.fineRows-this.bandRows;t++)c(this.cellIdFor(4,Math.floor((t-this.bandRows)/this.lowScale),p.cols-1),this.cellIdFor(2,t,0));if(g\u0026\u0026_)for(let t=this.bandCols;t\u003cthis.fineCols-this.bandCols;t++)c(this.cellIdFor(1,d.rows-1,t-this.bandCols),this.cellIdFor(4,0,Math.floor((t-this.bandCols)/this.lowScale)));if(y\u0026\u0026_)for(let t=this.bandCols;t\u003cthis.fineCols-this.bandCols;t++)c(this.cellIdFor(4,p.rows-1,Math.floor((t-this.bandCols)/this.lowScale)),this.cellIdFor(3,0,t-this.bandCols));if(!_\u0026\u0026!g\u0026\u0026!y\u0026\u0026m\u0026\u0026f)for(let t=0;t\u003cMath.min(l.rows,h.rows);t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(2,t,0));if(!_\u0026\u0026!m\u0026\u0026!f\u0026\u0026g\u0026\u0026y)for(let t=0;t\u003cMath.min(d.cols,u.cols);t++)c(this.cellIdFor(1,d.rows-1,t),this.cellIdFor(3,0,t));const b=this.flattenNeighborLists(a);this.neighborOffset=b.offset,this.neighborIds=b.ids,this.neighborCosts=b.costs}cellIdFor(t,e,n){const o=this.regions[t];return o.offset+e*o.cols+n}stepOnce(){if(!this.activeConnSeg){if(0===this.unsolvedSegs.length)return void(this.solved=!0);const t=this.unsolvedSegs.shift();this.activeConnSeg=t,this.activeConnId=t.connId,this.nodePool.clear(),this.ripChain.clear(),this.heap.clear(),this.seqCounter=0,this.searchIterations=0,this.nextStamp();const e=this.computeH(t.startZ,t.startCellId,t.endZ,t.endCellId)*this.hyperParameters.greedyMultiplier,n=this.nodePool.push(t.startZ,t.startCellId,0,-1,-1,0),o=t.startZ*this.planeSize+t.startCellId,i=this.getSearchStateIdx(o,0);return this.bestGStamp[i]=this.stamp,this.bestGValue[i]=0,void this.heap.push(e,this.seqCounter++,n)}this.searchIterations++;const t=this.ripCount[this.activeConnId]??0,e=Math.round(this.baseSearchBudgetIters*(1+.25*Math.min(t,10)));if(this.searchIterations\u003ee){const t=this.penalty2d;for(let e=0;e\u003ct.length;e++)t[e]=.9*t[e];return this.unsolvedSegs.push(this.activeConnSeg),this.activeConnSeg=null,this.activeConnId=-1,this.heap.clear(),this.nodePool.clear(),this.consecutiveSkips++,void(this.consecutiveSkips\u003e=Math.max(3,3*this.unsolvedSegs.length)\u0026\u0026(this.error=`Convergence failure: ${this.unsolvedSegs.length} connections stuck`,this.failed=!0))}if(0===this.heap.size)return this.error=`No path found for ${this.connIdToName[this.activeConnId]}`,void(this.failed=!0);const n=this.heap.pop(),o=this.nodePool.z[n],i=this.nodePool.cellId[n],r=this.nodePool.g[n],s=this.nodePool.ripHead[n],a=this.nodePool.ripCount[n],c=o*this.planeSize+i,l=this.getSearchStateIdx(c,a);if(this.visitedStamp[l]===this.stamp)return;this.visitedStamp[l]=this.stamp,this.visitedFlatStamp[c]=this.stamp;const d=this.activeConnSeg;if(o===d.endZ\u0026\u0026i===d.endCellId)return this.finalizeRoute(n),this.activeConnSeg=null,void(this.activeConnId=-1);const h=this.visitedStamp,u=this.stamp,p=this.activeConnId,m=d.endZ,g=d.endCellId,f=this.neighborOffset[i],y=this.neighborOffset[i+1];for(let t=f;t\u003cy;t++){const e=this.neighborIds[t],c=o*this.planeSize+e;if(this.computeMoveCostAndRips(p,o,i,e,!1,s,a,this.neighborCosts[t]),this._moveCost\u003c0)continue;const l=this.getSearchStateIdx(c,this._moveRipCount);if(h[l]===u)continue;const d=r+this._moveCost;if(this.bestGStamp[l]===u\u0026\u0026d\u003e=this.bestGValue[l])continue;this.bestGStamp[l]=u,this.bestGValue[l]=d;const f=d+this.computeH(o,e,m,g)*this.hyperParameters.greedyMultiplier,y=this.nodePool.push(o,e,d,n,this._moveRippedHead,this._moveRipCount);this.heap.push(f,this.seqCounter++,y)}if(this.viaAllowed[i])for(let t=0;t\u003cthis.layers;t++){if(t===o)continue;const e=t*this.planeSize+i;if(this.computeMoveCostAndRips(p,t,i,i,!0,s,a,0),this._moveCost\u003c0)continue;const c=this.getSearchStateIdx(e,this._moveRipCount);if(h[c]===u)continue;const l=r+this._moveCost;if(this.bestGStamp[c]===u\u0026\u0026l\u003e=this.bestGValue[c])continue;this.bestGStamp[c]=u,this.bestGValue[c]=l;const d=l+this.computeH(t,i,m,g)*this.hyperParameters.greedyMultiplier,f=this.nodePool.push(t,i,l,n,this._moveRippedHead,this._moveRipCount);this.heap.push(d,this.seqCounter++,f)}}computeMoveCostAndRips(t,e,n,o,i,r,s,a){let c=0,l=r,d=s;const h=e*this.planeSize+o,u=i?this.obstacleViaRootIdsByCell[o]:[...this.obstacleTraceRootIdsFlat[e*this.planeSize+n]??[],...this.obstacleTraceRootIdsFlat[h]??[]];if(this.isBlockedByObstacleRoots(u,t)\u0026\u0026(i?this.isViaMoveBlockedByObstacleGeometry({activeConn:t,cellId:o}):this.isLateralMoveBlockedByObstacleGeometry({activeConn:t,layer:e,fromCellId:n,toCellId:o})))return this._moveCost=-1,this._moveRippedHead=l,void(this._moveRipCount=d);const p=this.hasSameRootObstacle(u,t);if(i){c+=this.hyperParameters.viaBaseCost,c+=Math.min(this.penalty2d[o],this.penaltyCap);const n=this.portOwnerFlat[h],i=this.allowSharedUse(t,n),r=this.activeConnSeg,s=!!r\u0026\u0026e===r.endZ\u0026\u0026o===r.endCellId;if(n\u003e=0\u0026\u0026n!==t\u0026\u0026!i\u0026\u0026!s)return this._moveCost=-1,void(this._moveRippedHead=l);this.fillViaOccupants(o,t);const a=this._viaOccs;for(let t=0;t\u003ca.length;t++){const e=a[t];this.ripChain.contains(l,e)||(c+=this.hyperParameters.ripCost,l=this.ripChain.append(l,e),d++),c+=this.hyperParameters.ripViaPenalty}}else{c+=a,c+=Math.min(this.penalty2d[o],this.penaltyCap);const n=this.portOwnerFlat[h],i=this.allowSharedUse(t,n),r=this.activeConnSeg,s=!!r\u0026\u0026e===r.endZ\u0026\u0026o===r.endCellId;if(n\u003e=0\u0026\u0026n!==t\u0026\u0026!i\u0026\u0026!s)return this._moveCost=-1,void(this._moveRippedHead=l);this.fillTraceOccupants(h,t,this._cellOccs);for(let t=0;t\u003cthis._cellOccs.length;t++){const e=this._cellOccs[t];this.ripChain.contains(l,e)||(c+=this.hyperParameters.ripCost,l=this.ripChain.append(l,e),d++),c+=this.hyperParameters.ripTracePenalty}}p\u0026\u0026(c*=this.hyperParameters.sameRootObstacleCostMultiplier),this._moveCost=c,this._moveRippedHead=l,this._moveRipCount=d}fillViaOccupants(t,e){const n=this._viaOccs;n.length=0;const o=this.cellCenterX[t],i=this.cellCenterY[t];this.forEachCellNearCircle(o,i,this.viaKeepoutRadius,t=\u003e{if(vQ(o,i,this.viaKeepoutRadius,this.cellMinX[t],this.cellMinY[t],this.cellMaxX[t],this.cellMaxY[t]))for(let o=0;o\u003cthis.layers;o++)this.pushFlatOccupants(o*this.planeSize+t,e,n)})}fillTraceOccupants(t,e,n){n.length=0,this.pushFlatOccupants(t,e,n)}pushFlatOccupants(t,e,n){const o=this.usedCellsFlat[t];-1===o||o===e||this.allowSharedUse(e,o)||bQ(n,o);const i=this.sharedCellsFlat[t];if(i)for(let t=0;t\u003ci.length;t++){const o=i[t];o!==e\u0026\u0026(this.allowSharedUse(e,o)||bQ(n,o))}}addSharedOccupant(t,e){if(this.usedCellsFlat[t]===e)return;let n=this.sharedCellsFlat[t];n||(n=[],this.sharedCellsFlat[t]=n),bQ(n,e)}replaceOccupants(t,e){this.usedCellsFlat[t]=e,this.sharedCellsFlat[t]=void 0}removeOccupant(t,e){const n=this.sharedCellsFlat[t];if(this.usedCellsFlat[t]===e)return void(n\u0026\u0026n.length\u003e0?(this.usedCellsFlat[t]=n.pop(),0===n.length\u0026\u0026(this.sharedCellsFlat[t]=void 0)):this.usedCellsFlat[t]=-1);if(!n)return;const o=n.indexOf(e);-1!==o\u0026\u0026(n.splice(o,1),0===n.length\u0026\u0026(this.sharedCellsFlat[t]=void 0))}allowSharedUse(t,e){if(e\u003c0)return!1;return this.connIdToRootNet[e]===this.connIdToRootNet[t]}shouldSkipFixedPortHalo(t,e){const n=this.portOwnerFlat[t];return n!==e\u0026\u0026(-2===n||!(n\u003c0)\u0026\u0026!this.allowSharedUse(e,n))}nextStamp(){this.stamp=this.stamp+1\u003e\u003e\u003e0,0===this.stamp\u0026\u0026(this.visitedStamp.fill(0),this.bestGStamp.fill(0),this.visitedFlatStamp.fill(0),this.stamp=1)}getSearchStateIdx(t,e){return t}computeH(t,e,n,o){const i=Math.hypot(this.cellCenterX[e]-this.cellCenterX[o],this.cellCenterY[e]-this.cellCenterY[o]);return t===n?i:i+this.hyperParameters.viaBaseCost}internConn(t,e){const n=this.connNameToId.get(t);if(void 0!==n)return n;const o=this.connIdToName.length;return this.connIdToName.push(t),this.connIdToRootNet.push(gQ(t,e)),this.connNameToId.set(t,o),o}buildConnectionSegs(){const t=new Map;for(const e of this.nodeWithPortPoints.portPoints){const n=e.connectionName;t.has(n)||t.set(n,{points:[],rootConnectionName:e.rootConnectionName}),t.get(n).points.push(e)}const e=[],n=new Map;for(const[o,i]of t){const t=i.points,r=lQ(t);if(0===r.length)continue;const s=this.internConn(o,i.rootConnectionName);for(const[t,i]of r){const r=this.pointToCell(t),a=this.pointToCell(i),c=`${r.z}:${r.cellId}`,l=`${a.z}:${a.cellId}`,d=c\u003cl?`${c}|${l}`:`${l}|${c}`,h=this.connIdToRootNet[s],u=`${h}|${d}`,p=n.get(u);if(p){if(this.overlapFriendlyRootNets.add(h),!p.connectionAliases.some(t=\u003et.connectionName===o)){const e=p.startZ===r.z\u0026\u0026p.startCellId===r.cellId\u0026\u0026p.endZ===a.z\u0026\u0026p.endCellId===a.cellId,n=p.startZ===a.z\u0026\u0026p.startCellId===a.cellId\u0026\u0026p.endZ===r.z\u0026\u0026p.endCellId===r.cellId;if(!e\u0026\u0026!n)throw new Error(`Connection alias ${o} does not match canonical segment ${u}`);p.connectionAliases.push({connectionName:o,rootConnectionName:h,startPoint:t,endPoint:i,reversedFromCanonical:!e\u0026\u0026n})}continue}const m={connId:s,startZ:r.z,startCellId:r.cellId,startPoint:t,endZ:a.z,endCellId:a.cellId,endPoint:i,connectionAliases:[{connectionName:o,rootConnectionName:h,startPoint:t,endPoint:i,reversedFromCanonical:!1}]};n.set(u,m),e.push(m)}}return e}pointToCell(t){const e=_Q(Math.floor((t.x-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),n=_Q(Math.floor((t.y-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1);let o=4;e\u003cthis.bandCols?o=0:e\u003e=this.fineCols-this.bandCols?o=2:n\u003cthis.bandRows?o=1:n\u003e=this.fineRows-this.bandRows\u0026\u0026(o=3);const i=this.regions[o],r=n-i.fineOriginRow,s=e-i.fineOriginCol,a=_Q(Math.floor(r/i.cellScale),0,Math.max(0,i.rows-1)),c=_Q(Math.floor(s/i.cellScale),0,Math.max(0,i.cols-1));return{z:this.zToLayer.get(t.z)??0,cellId:this.cellIdFor(o,a,c)}}shuffleConnections(){const t=this.unsolvedSegs;let e=this.hyperParameters.shuffleSeed\u003e\u003e\u003e0;const n=()=\u003e(e=Math.imul(e,1664525)+1013904223\u003e\u003e\u003e0,e/4294967295);for(let e=t.length-1;e\u003e0;e--){const o=Math.floor(n()*(e+1)),i=t[e];t[e]=t[o],t[o]=i}}finalizeRoute(t){this.consecutiveSkips=Math.max(0,this.consecutiveSkips-1);const e=[];let n=t;for(;n\u003e=0;){const t=this.nodePool.z[n],o=this.nodePool.cellId[n];e.push(t*this.planeSize+o),n=this.nodePool.parent[n]}for(e.reverse();e.length\u003e1\u0026\u0026this.sharedCrossRootPortFlat[e[0]];)e.shift();for(;e.length\u003e1\u0026\u0026this.sharedCrossRootPortFlat[e[e.length-1]];)e.pop();const o=this.extractViaCellIds(e),i=this.activeConnId;this.ripChain.collect(this.nodePool.ripHead[t],this._rippedIds);for(let t=0;t\u003cthis._rippedIds.length;t++)if(this.ripTrace(this._rippedIds[t]),this.failed)return;const r=[];for(let t=0;t\u003ce.length;t++){const n=e[t],o=Math.floor(n/this.planeSize),s=n-o*this.planeSize;this.markTraceFootprint(i,o,s,r)}const s=[];for(let t=0;t\u003co.length;t++)this.markViaFootprint(i,o[t],r,s);for(;this.usedIndicesByConn.length\u003c=i;)this.usedIndicesByConn.push(void 0);const a=this.usedIndicesByConn[i]??[];for(a.push(...r),this.usedIndicesByConn[i]=a;this.solvedRoutes.length\u003c=i;)this.solvedRoutes.push(void 0);const c=this.solvedRoutes[i]??[];c.push({connId:i,states:Int32Array.from(e),viaCellIds:Int32Array.from(o),startPoint:this.activeConnSeg.startPoint,endPoint:this.activeConnSeg.endPoint,connectionAliases:this.activeConnSeg.connectionAliases}),this.solvedRoutes[i]=c;for(let t=0;t\u003cs.length;t++)if(this.ripTrace(s[t]),this.failed)return;if(this._rippedIds.length\u003e0||s.length\u003e0){const t=this.penalty2d,e=this.penaltyCap;if(this.totalRipEvents\u003e50)for(let e=0;e\u003ct.length;e++)t[e]=.99*t[e];else for(let n=0;n\u003ct.length;n++)t[n]\u003ee\u0026\u0026(t[n]=.5*t[n])}}extractViaCellIds(t){const e=[];for(let n=1;n\u003ct.length;n++){const o=t[n-1],i=t[n],r=Math.floor(o/this.planeSize),s=Math.floor(i/this.planeSize);r!==s\u0026\u0026e.push(i-s*this.planeSize)}return e}markTraceFootprint(t,e,n,o){const i=this.cellCenterX[n],r=this.cellCenterY[n];this.forEachCellNearCircle(i,r,this.traceKeepoutRadius,s=\u003e{if(!vQ(i,r,this.traceKeepoutRadius,this.cellMinX[s],this.cellMinY[s],this.cellMaxX[s],this.cellMaxY[s]))return;const a=e*this.planeSize+s;if(s!==n\u0026\u0026this.shouldSkipFixedPortHalo(a,t))return;const c=this.usedCellsFlat[a],l=this.allowSharedUse(t,c);(-1===c||c===t||l)\u0026\u0026(-1!==c\u0026\u0026c!==t?this.addSharedOccupant(a,t):this.usedCellsFlat[a]=t,o.push(a))})}markViaFootprint(t,e,n,o){const i=this.cellCenterX[e],r=this.cellCenterY[e];this.forEachCellNearCircle(i,r,this.viaKeepoutRadius,s=\u003e{if(vQ(i,r,this.viaKeepoutRadius,this.cellMinX[s],this.cellMinY[s],this.cellMaxX[s],this.cellMaxY[s]))for(let i=0;i\u003cthis.layers;i++){const r=i*this.planeSize+s;if(s!==e\u0026\u0026this.shouldSkipFixedPortHalo(r,t))continue;if(this.fillTraceOccupants(r,t,this._cellOccs),this._cellOccs.length\u003e0){for(let t=0;t\u003cthis._cellOccs.length;t++)bQ(o,this._cellOccs[t]);this.replaceOccupants(r,t),n.push(r);continue}const a=this.usedCellsFlat[r];-1!==a\u0026\u0026a!==t?this.addSharedOccupant(r,t):this.usedCellsFlat[r]=t,n.push(r)}})}forEachCellNearCircle(t,e,n,o){const i=_Q(Math.floor((t-n-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),r=_Q(Math.floor((t+n-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),s=_Q(Math.floor((e-n-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1),a=_Q(Math.floor((e+n-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1);for(let t=0;t\u003cthis.regions.length;t++){const e=this.regions[t];if(0===e.rows||0===e.cols)continue;const n=Math.max(s,e.fineOriginRow),c=Math.min(a,e.fineOriginRow+e.fineRows-1),l=Math.max(i,e.fineOriginCol),d=Math.min(r,e.fineOriginCol+e.fineCols-1);if(n\u003ec)continue;if(l\u003ed)continue;const h=Math.floor((n-e.fineOriginRow)/e.cellScale),u=Math.floor((c-e.fineOriginRow)/e.cellScale),p=Math.floor((l-e.fineOriginCol)/e.cellScale),m=Math.floor((d-e.fineOriginCol)/e.cellScale);for(let t=h;t\u003c=u;t++)for(let n=p;n\u003c=m;n++)o(this.cellIdFor(e.id,t,n))}}ripTrace(t){for(;this.ripCount.length\u003c=t;)this.ripCount.push(0);if(this.ripCount[t]++,this.totalRipEvents++,this.totalRipEvents\u003e=this.MAX_RIPS)return this.error=`Convergence failure: exceeded MAX_RIPS ${this.MAX_RIPS}`,void(this.failed=!0);const e=this.getSolvedRoutesForConn(t);if(e.length\u003e0)for(const t of e){for(let e=0;e\u003ct.states.length;e++){const n=t.states[e]%this.planeSize;this.penalty2d[n]=this.penalty2d[n]+this.hyperParameters.ripTracePenalty}for(let e=0;e\u003ct.viaCellIds.length;e++){const n=t.viaCellIds[e];this.penalty2d[n]=this.penalty2d[n]+this.hyperParameters.ripViaPenalty}}const n=this.usedIndicesByConn[t];if(n){for(let e=0;e\u003cn.length;e++)this.removeOccupant(n[e],t);this.usedIndicesByConn[t]=void 0}if(e.length\u003e0){this.solvedRoutes[t]=void 0;for(const n of e){const e=n.states[0],o=n.states[n.states.length-1],i=Math.floor(e/this.planeSize),r=Math.floor(o/this.planeSize);this.unsolvedSegs.push({connId:t,startZ:i,startCellId:e-i*this.planeSize,startPoint:n.startPoint,endZ:r,endCellId:o-r*this.planeSize,endPoint:n.endPoint,connectionAliases:n.connectionAliases})}}}flattenNeighborLists(t){const e=new Int32Array(t.length+1);let n=0;for(let o=0;o\u003ct.length;o++)e[o]=n,n+=t[o].length;e[t.length]=n;const o=new Int32Array(n),i=new Float32Array(n);let r=0;for(let e=0;e\u003ct.length;e++){const n=t[e];for(let t=0;t\u003cn.length;t++){const e=n[t];o[r]=e.cellId,i[r]=e.cost,r++}}return{offset:e,ids:o,costs:i}}visualize(){const t=[\"red\",\"blue\",\"orange\",\"green\"],e=this.gridToBoundsTransform,n=[],o=[],i=[],r=[];r.push({center:{x:this.nodeWithPortPoints.center.x,y:this.nodeWithPortPoints.center.y},width:this.nodeWithPortPoints.width,height:this.nodeWithPortPoints.height,stroke:\"gray\"});const s=({route:e,connectionName:n,strokeWidth:i,strokeDash:r,labelPrefix:s})=\u003e{if(e.length\u003c2)return;let a=0;for(let c=1;c\u003ce.length;c+=1){const l=e[c-1];e[c].z!==l.z\u0026\u0026(c-a\u003e=2\u0026\u0026o.push({points:e.slice(a,c).map(t=\u003e({x:t.x,y:t.y})),strokeColor:t[l.z]??\"rgba(128,128,128,0.75)\",strokeWidth:i,strokeDash:r,label:`${s} ${n} z=${l.z}`}),a=c)}if(e.length-a\u003c2)return;const c=e[a].z;o.push({points:e.slice(a).map(t=\u003e({x:t.x,y:t.y})),strokeColor:t[c]??\"rgba(128,128,128,0.75)\",strokeWidth:i,strokeDash:r,label:`${s} ${n} z=${c}`})};for(const t of this.obstacles)if(\"rect\"!==t.type){s({route:t.route,connectionName:t.connectionName,strokeWidth:t.traceThickness,strokeDash:[.12,.08],labelPrefix:\"fixed obstacle\"});for(const e of t.vias)i.push({center:{x:e.x,y:e.y},radius:t.viaDiameter/2,fill:\"rgba(128,0,128,0.25)\",stroke:\"purple\",label:`fixed obstacle ${t.connectionName} via`})}else r.push({center:t.center,width:t.width,height:t.height,fill:\"rgba(128,0,128,0.12)\",stroke:\"purple\",label:`fixed obstacle ${t.connectionName}`});if(this.showPenaltyMap\u0026\u0026this.penalty2d){let t=0;for(let e=0;e\u003cthis.penalty2d.length;e++)this.penalty2d[e]\u003et\u0026\u0026(t=this.penalty2d[e]);if(t\u003e0)for(let n=0;n\u003cthis.planeSize;n++){const o=this.penalty2d[n];if(o\u003c=0)continue;const i=iQ(e,{x:this.cellCenterX[n],y:this.cellCenterY[n]}),s=Math.min(.6,o/t*.6);r.push({center:i,width:this.cellWidth[n]*e.a,height:this.cellHeight[n]*e.e,fill:`rgba(255,165,0,${s.toFixed(3)})`})}}if(this.showUsedCellMap\u0026\u0026this.usedCellsFlat)for(let t=0;t\u003cthis.layers;t++){const n=t*this.planeSize;for(let t=0;t\u003cthis.planeSize;t++){if(-1===this.usedCellsFlat[n+t])continue;const o=iQ(e,{x:this.cellCenterX[t],y:this.cellCenterY[t]});r.push({center:o,width:this.cellWidth[t]*e.a,height:this.cellHeight[t]*e.e,fill:\"rgba(0,0,255,0.5)\"})}}for(const e of this.nodeWithPortPoints.portPoints)n.push({x:e.x,y:e.y,color:t[e.z]??\"gray\",label:e.connectionName});const a=this.getOutput();for(const t of a)s({route:t.route,connectionName:t.connectionName,strokeWidth:this.traceThickness,labelPrefix:\"B01 route\"});for(const t of a)for(const e of t.vias)i.push({center:{x:e.x,y:e.y},radius:this.viaDiameter/2,fill:\"rgba(0,0,0,0.3)\",stroke:\"black\",label:`B01 route ${t.connectionName} via`});if(this.activeConnSeg\u0026\u0026this.visitedFlatStamp){const t=this.stamp;for(let o=0;o\u003cthis.layers;o++){const i=o*this.planeSize;for(let o=0;o\u003cthis.planeSize;o++){if(this.visitedFlatStamp[i+o]!==t)continue;const r=iQ(e,{x:this.cellCenterX[o],y:this.cellCenterY[o]});n.push({x:r.x,y:r.y,color:\"rgba(0,0,255,0.2)\"})}}}return{points:n,lines:o,circles:i,rects:r,coordinateSystem:\"cartesian\",title:`HighDensityB01 [${this.getSolvedRouteCount()} solved, ${this.unsolvedSegs?.length??0} remaining]`}}getOutput(){const t=this.gridToBoundsTransform,e=[];for(let n=0;n\u003cthis.solvedRoutes.length;n++){const o=this.getSolvedRoutesForConn(n);if(0!==o.length)for(const n of o){const o=Array.from(n.states,e=\u003e{const n=Math.floor(e/this.planeSize),o=e-n*this.planeSize,i=iQ(t,{x:this.cellCenterX[o],y:this.cellCenterY[o]});return{x:i.x,y:i.y,z:this.layerToZ.get(n)??n}}),i=Array.from(n.viaCellIds,e=\u003eiQ(t,{x:this.cellCenterX[e],y:this.cellCenterY[e]}));for(const t of n.connectionAliases){const n=(t.reversedFromCanonical?[...o].reverse():o).map(t=\u003e({...t}));n.length\u003e0\u0026\u0026(n[0]={...t.startPoint},n.length\u003e1\u0026\u0026(n[n.length-1]={...t.endPoint})),e.push({connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,regionId:this.nodeWithPortPoints.capacityMeshNodeId,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,route:n,vias:i.map(t=\u003e({...t}))})}}}return e}getSolvedRoutesForConn(t){const e=this.solvedRoutes[t];return e?Array.isArray(e)?e:[e]:[]}getSolvedRouteCount(){let t=0;for(let e=0;e\u003cthis.solvedRoutes.length;e++)t+=this.getSolvedRoutesForConn(e).length;return t}computeGridToBoundsTransform(){let t=1/0,e=-1/0,n=1/0,o=-1/0;for(let i=0;i\u003cthis.planeSize;i++){const r=this.cellCenterX[i],s=this.cellCenterY[i];r\u003ct\u0026\u0026(t=r),r\u003ee\u0026\u0026(e=r),s\u003cn\u0026\u0026(n=s),s\u003eo\u0026\u0026(o=s)}const i=e-t,r=o-n,s=this.boundsMaxX-this.boundsMinX,a=this.boundsMaxY-this.boundsMinY,c=i\u003e0?s/i:1,l=r\u003e0?a/r:1;return{a:c,b:0,c:i\u003e0?this.boundsMinX-c*t:(this.boundsMinX+this.boundsMaxX)/2-t,d:0,e:l,f:r\u003e0?this.boundsMinY-l*n:(this.boundsMinY+this.boundsMaxY)/2-n}}},RQ=new WeakMap,EQ=t=\u003e{const e=RQ.get(t);if(e)return e;const n=[],o=[];for(let e=1;e\u003ct.route.length;e++){const i=t.route[e-1],r=t.route[e],s=Math.hypot(r.x-i.x,r.y-i.y),a=Math.max(i.traceThickness??t.traceThickness,r.traceThickness??t.traceThickness);if(i.z!==r.z\u0026\u0026\"through_obstacle\"===i.toNextSegmentType){const e=Math.min(i.z,r.z),c=Math.max(i.z,r.z);if(s\u003c=1e-9){const n=t.vias.some(t=\u003eMath.hypot(t.x-r.x,t.y-r.y)\u003c=1e-9);o.push({center:{x:r.x,y:r.y},minZ:e,maxZ:c,diameter:n?t.viaDiameter:a});continue}for(let t=e;t\u003c=c;t++)n.push({start:{...i,z:t},end:{...r,z:t},z:t,width:a});continue}s\u003e1e-9\u0026\u0026n.push({start:i,end:i.z===r.z?r:{...r,z:i.z},z:i.z,width:a}),i.z!==r.z\u0026\u0026o.push({center:{x:r.x,y:r.y},minZ:Math.min(i.z,r.z),maxZ:Math.max(i.z,r.z),diameter:t.viaDiameter})}const i={wireSegments:n,viaSpans:o};return RQ.set(t,i),i},AQ=(t,e,n)=\u003e{const o=t.end.x-t.start.x,i=t.end.y-t.start.y,r=Math.hypot(o,i),s={x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2};return Math.abs(o)\u003c=1e-9||Math.abs(i)\u003c=1e-9?[{center:s,width:Math.abs(o)\u003eMath.abs(i)?r:t.width,height:Math.abs(o)\u003eMath.abs(i)?t.width:r}]:rX({center:s,width:r,height:t.width,rotation:180*Math.atan2(i,o)/Math.PI},Math.max(n,Math.ceil(r/e)))},OQ=({fixedObstacleRoutes:t,layerCount:e})=\u003et.flatMap((t,n)=\u003e{const o=[t.connectionName,t.rootConnectionName].filter(t=\u003e\"string\"==typeof t),i=EQ(t);return[...i.wireSegments.flatMap((t,i)=\u003eAQ(t,.75,2).map((r,s)=\u003e({obstacleId:`pipeline9_fixed_obstacle_${n}_wire_${i}_${s}`,type:\"rect\",layers:[vo(t.z,e)],center:r.center,width:r.width,height:r.height,connectedTo:o}))),...i.viaSpans.map((t,i)=\u003e({obstacleId:`pipeline9_fixed_obstacle_${n}_via_${i}`,type:\"rect\",layers:Array.from({length:t.maxZ-t.minZ+1},(n,o)=\u003evo(t.minZ+o,e)),center:t.center,width:t.diameter,height:t.diameter,connectedTo:o}))]}),kQ=(t,e,n)=\u003e{const o=[t.connectionName,t.rootConnectionName].filter(t=\u003e\"string\"==typeof t),i=[e.connectionName,e.rootConnectionName].filter(t=\u003e\"string\"==typeof t);return o.some(t=\u003ei.some(e=\u003et===e||n.areIdsConnected(t,e)))},LQ=(t,e)=\u003et.minX\u003c=e.maxX\u0026\u0026t.maxX\u003e=e.minX\u0026\u0026t.minY\u003c=e.maxY\u0026\u0026t.maxY\u003e=e.minY,DQ=({left:t,right:e,clearance:n,leftBounds:o})=\u003e{const i=EQ(t),r=EQ(e),s=o?i.wireSegments.filter(t=\u003e((t,e)=\u003e{const n={minX:Math.min(t.start.x,t.end.x)-t.width/2,maxX:Math.max(t.start.x,t.end.x)+t.width/2,minY:Math.min(t.start.y,t.end.y)-t.width/2,maxY:Math.max(t.start.y,t.end.y)+t.width/2};return LQ(n,e)})(t,o)):i.wireSegments,a=o?i.viaSpans.filter(t=\u003e((t,e)=\u003e{const n={minX:t.center.x-t.diameter/2,maxX:t.center.x+t.diameter/2,minY:t.center.y-t.diameter/2,maxY:t.center.y+t.diameter/2};return LQ(n,e)})(t,o)):i.viaSpans;for(const t of s){for(const e of r.wireSegments){if(t.z!==e.z)continue;const o=t.width/2+e.width/2+n;if(Ra(t.start,t.end,e.start,e.end)\u003co)return!0}for(const e of r.viaSpans){if(t.z\u003ce.minZ||t.z\u003ee.maxZ)continue;const o=t.width/2+e.diameter/2+n;if(Ra(t.start,t.end,e.center,e.center)\u003co)return!0}}for(const t of a){for(const e of r.wireSegments){if(e.z\u003ct.minZ||e.z\u003et.maxZ)continue;const o=t.diameter/2+e.width/2+n;if(Ra(t.center,t.center,e.start,e.end)\u003co)return!0}for(const e of r.viaSpans){if(t.minZ\u003ee.maxZ||e.minZ\u003et.maxZ)continue;const o=t.diameter/2+e.diameter/2+n;if(Math.hypot(t.center.x-e.center.x,t.center.y-e.center.y)\u003co)return!0}}return!1},zQ=({routes:t,movablePreloadedConnectionNames:e,boardObstacles:n,connMap:o,layerCount:i,viaToPadClearance:r})=\u003et.some(t=\u003e{if(!e.has(t.connectionName))return!1;return EQ(t).viaSpans.some(e=\u003en.some(n=\u003e{if(fo(n,t,o))return!1;const s=((t,e)=\u003e{const n=t.__zLayers??t.zLayers;return n||t.layers.map(t=\u003eko(t,e))})(n,i);return!!s.some(t=\u003et\u003e=e.minZ\u0026\u0026t\u003c=e.maxZ)\u0026\u0026((t,e)=\u003e{const n=-1*(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y,r=o*Math.cos(n)-i*Math.sin(n),s=o*Math.sin(n)+i*Math.cos(n),a=Math.max(Math.abs(r)-e.width/2,0),c=Math.max(Math.abs(s)-e.height/2,0);return Math.hypot(a,c)})(e.center,n)\u003ce.diameter/2+r}))}),FQ=class extends si{params;highDensitySolver;forceImproveSolver;repairSolver;phase=\"route\";constructor(t){super(),this.params=t,this.stats={preloadedViaCandidateRejectionCount:0,forceImproveCandidateRejectionCount:0,repairCandidateRejectionCount:0},this.highDensitySolver=new zs({nodePortPoints:[t.nodeWithPortPoints],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:t.nodePfById,obstacles:t.obstacles,layerCount:t.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!1,growShrinkFallbackToInvalidGeometryOnFailure:!1,growShrinkSolutionValidator:t.boardObstacles\u0026\u0026t.movablePreloadedConnectionNames\u0026\u0026void 0!==t.viaToPadClearance?t=\u003ethis.validateCandidateRoutes(t):void 0}),this.activeSubSolver=this.highDensitySolver,this.MAX_ITERATIONS=1e8*t.effort}getSolverName(){return\"Pipeline9RegionalFallbackSolver\"}validateCandidateRoutes(t){const{boardObstacles:e,movablePreloadedConnectionNames:n,viaToPadClearance:o}=this.params;if(!e||!n||void 0===o)return!0;const i=zQ({routes:t,movablePreloadedConnectionNames:n,boardObstacles:e,connMap:this.params.connMap,layerCount:this.params.layerCount,viaToPadClearance:o});return i\u0026\u0026(this.stats.preloadedViaCandidateRejectionCount=Number(this.stats.preloadedViaCandidateRejectionCount??0)+1),!i}_step(){if(\"route\"===this.phase){if(this.highDensitySolver.step(),this.highDensitySolver.failed)return this.error=this.highDensitySolver.error,void(this.failed=!0);if(!this.highDensitySolver.solved)return;const t=AK(this.highDensitySolver.routes);return this.validateCandidateRoutes(t)?(this.forceImproveSolver=new Yy({nodeWithPortPoints:[this.params.nodeWithPortPoints],hdRoutes:t,colorMap:this.params.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*this.params.effort)),nodeAssignmentMargin:this.params.obstacleMargin}),this.activeSubSolver=this.forceImproveSolver,void(this.phase=\"improve\")):(this.error=\"Pipeline9 regional route output failed its candidate validator\",void(this.failed=!0))}if(\"improve\"===this.phase){if(this.forceImproveSolver.step(),this.forceImproveSolver.failed)return this.error=this.forceImproveSolver.error,void(this.failed=!0);if(!this.forceImproveSolver.solved)return;const t=this.forceImproveSolver.getOutput();return this.validateCandidateRoutes(t)?(this.repairSolver=new AY({nodeWithPortPoints:[this.params.nodeWithPortPoints],hdRoutes:t,obstacles:this.params.obstacles,colorMap:this.params.colorMap,repairMargin:this.params.obstacleMargin,maxSampleEntries:80,connMap:this.params.connMap}),this.activeSubSolver=this.repairSolver,void(this.phase=\"repair\")):(this.stats.forceImproveCandidateRejectionCount=Number(this.stats.forceImproveCandidateRejectionCount??0)+1,this.error=\"Pipeline9 regional force-improve output failed its candidate validator\",void(this.failed=!0))}if(\"repair\"===this.phase){if(this.repairSolver.step(),this.repairSolver.failed)return this.error=this.repairSolver.error,void(this.failed=!0);if(!this.repairSolver.solved)return;const t=this.repairSolver.getOutput();return this.validateCandidateRoutes(t)?(this.activeSubSolver=null,this.phase=\"done\",void(this.solved=!0)):(this.stats.repairCandidateRejectionCount=Number(this.stats.repairCandidateRejectionCount??0)+1,this.error=\"Pipeline9 regional repair output failed its candidate validator\",void(this.failed=!0))}}getOutput(){return this.repairSolver?.getOutput()??this.forceImproveSolver?.getOutput()??this.highDensitySolver.routes}visualize(){return this.repairSolver?.visualize()??this.forceImproveSolver?.visualize()??this.highDensitySolver.visualize()}},BQ=(t,e)=\u003e({minX:t.center.x-t.width/2-e,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2-e,maxY:t.center.y+t.height/2+e}),jQ=(t,e,n)=\u003e{const o=Math.max(n.minX-t.x,0,t.x-n.maxX),i=Math.max(n.minY-t.y,0,t.y-n.maxY);return o*o+i*i\u003c=e*e},$Q=(t,e,n,o)=\u003eMath.min(t.x,e.x)-n\u003c=o.maxX\u0026\u0026Math.max(t.x,e.x)+n\u003e=o.minX\u0026\u0026Math.min(t.y,e.y)-n\u003c=o.maxY\u0026\u0026Math.max(t.y,e.y)+n\u003e=o.minY,YQ=(t,e)=\u003e{const n=t=\u003e({...t,rootConnectionName:e.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName});return{...t,portPoints:t.portPoints.map(n),portPointsInPairs:t.portPointsInPairs?.map(([t,e])=\u003e[n(t),n(e)])}},XQ=({nodeWithPortPoints:t,connMap:e,colorMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a,obstacles:c,layerCount:l})=\u003enew zs({nodePortPoints:[YQ(t,e)],colorMap:n,connMap:e,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a,obstacles:c,layerCount:l,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!1,growShrinkFallbackToInvalidGeometryOnFailure:!1,captureSearchDebug:!1}),VQ=class extends si{fixedHdRoutes;connMap;colorMap;obstacles;layerCount;viaDiameter;traceWidth;obstacleMargin;viaToPadClearance;effort;nodePfById;preserveTerminalPcbPortIds;includeBoardObstacles;enableRegionalFallback;maxB01Rips;routes=[];failedSolvers=[];unsolvedNodePortPoints;fixedRouteReplacements=new Map;removedFixedRouteConnectionNames=new Set;preloadedTraceMutationMasks=new Map;activeRegularSolver=null;activeB01Solver=null;activeFallbackSolver=null;activeFallbackFixedRouteSections=new Map;activeFallbackFixedObstacleRoutes=[];activeFallbackPromotedFixedRouteConnectionNames=new Set;activeFallbackReason=null;activeNode=null;constructor(t){super(),this.fixedHdRoutes=t.fixedHdRoutes,this.connMap=t.connMap,this.colorMap=t.colorMap??{},this.obstacles=t.obstacles,this.layerCount=t.layerCount,this.viaDiameter=t.viaDiameter,this.traceWidth=t.traceWidth,this.obstacleMargin=t.obstacleMargin,this.viaToPadClearance=t.viaToPadClearance,this.effort=t.effort,this.nodePfById=t.nodePfById instanceof Map?new Map(t.nodePfById):new Map(Object.entries(t.nodePfById??{})),this.preserveTerminalPcbPortIds=t.preserveTerminalPcbPortIds??!1,this.includeBoardObstacles=t.includeBoardObstacles??!1,this.enableRegionalFallback=t.enableRegionalFallback??!0,this.maxB01Rips=t.maxB01Rips,this.unsolvedNodePortPoints=[...t.nodePortPoints],this.MAX_ITERATIONS=1e8*this.effort,this.stats={nodeCount:t.nodePortPoints.length,solvedNodeCount:0,fixedObstacleCount:t.fixedHdRoutes.length,fixedObstacleUses:0,boardObstacleUses:0,fallbackNodeCount:0,regularNodeCount:0,b01NodeCount:0,reroutedFixedRouteCount:0,reroutedFixedRouteSectionCount:0,promotedFallbackAttemptCount:0,promotedFixedRouteCount:0,regionalPreloadedViaCandidateRejectionCount:0,regionalForceImproveCandidateRejectionCount:0,regionalRepairCandidateRejectionCount:0}}getSolverName(){return\"Pipeline9HighDensitySolver\"}getUpdatedFixedHdRoutes(){return this.fixedHdRoutes.flatMap(t=\u003ethis.removedFixedRouteConnectionNames.has(t.connectionName)?[]:[this.fixedRouteReplacements.get(t.connectionName)??t])}finishActiveNode(t){const e=this.activeNode?((t,e)=\u003et.map(t=\u003e({...t,rootConnectionName:e.portPoints.find(e=\u003ee.connectionName===t.connectionName)?.rootConnectionName??t.rootConnectionName})))(t,this.activeNode):t;this.routes.push(...this.preserveTerminalPcbPortIds\u0026\u0026this.activeNode?((t,e)=\u003e{const n=e.portPoints.filter(t=\u003evoid 0!==t.pcb_port_id);return t.map(t=\u003e{const e=t.route[0],o=t.route.at(-1),i=n.find(n=\u003evoid 0!==e\u0026\u0026n.connectionName===t.connectionName\u0026\u0026n.x===e.x\u0026\u0026n.y===e.y\u0026\u0026n.z===e.z),r=n.find(e=\u003evoid 0!==o\u0026\u0026e.connectionName===t.connectionName\u0026\u0026e.x===o.x\u0026\u0026e.y===o.y\u0026\u0026e.z===o.z);return{...t,startPcbPortId:i?.pcb_port_id,endPcbPortId:r?.pcb_port_id}})})(e,this.activeNode):e),this.stats.solvedNodeCount=Number(this.stats.solvedNodeCount??0)+1,this.activeB01Solver=null,this.activeRegularSolver=null,this.activeFallbackSolver=null,this.activeFallbackFixedRouteSections.clear(),this.activeFallbackFixedObstacleRoutes=[],this.activeFallbackPromotedFixedRouteConnectionNames.clear(),this.activeFallbackReason=null,this.activeNode=null}startRegularSolver(t){this.activeNode=t,this.activeRegularSolver=XQ({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById,obstacles:this.obstacles,layerCount:this.layerCount}),this.stats.regularNodeCount=Number(this.stats.regularNodeCount??0)+1}startRegionalFallback(t=new Set){if(!this.activeNode)throw new Error(\"Pipeline9 cannot start a regional fallback without an active node\");const e={...YQ(this.activeNode,this.connMap),availableZ:Array.from({length:this.layerCount},(t,e)=\u003ee)},n=$K(e,this.getUpdatedFixedHdRoutes(),t),o=new Set([...n.fixedRouteSectionsByConnectionName.values()].flatMap(t=\u003et.sourceRoutes.map(t=\u003et.connectionName)));for(const e of t)if(!o.has(e))throw new Error(`Pipeline9 could not promote fixed route \"${e}\" into the active regional fallback`);const i=[...t].filter(t=\u003e!this.activeFallbackPromotedFixedRouteConnectionNames.has(t)).length;this.activeFallbackFixedRouteSections=n.fixedRouteSectionsByConnectionName,this.activeFallbackFixedObstacleRoutes=n.fixedObstacleRoutes,this.activeFallbackPromotedFixedRouteConnectionNames=new Set(t);const r=OQ({fixedObstacleRoutes:this.activeFallbackFixedObstacleRoutes,layerCount:this.layerCount});this.activeFallbackSolver=new FQ({nodeWithPortPoints:n.nodeWithPortPoints,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById,obstacles:[...this.obstacles,...r],boardObstacles:this.obstacles,movablePreloadedConnectionNames:o,viaToPadClearance:this.viaToPadClearance,layerCount:this.layerCount}),0===t.size?this.stats.fallbackNodeCount=Number(this.stats.fallbackNodeCount??0)+1:(this.stats.promotedFallbackAttemptCount=Number(this.stats.promotedFallbackAttemptCount??0)+1,this.stats.promotedFixedRouteCount=Number(this.stats.promotedFixedRouteCount??0)+i)}finishRegionalFallback(){if(!this.activeFallbackSolver)return;if(!this.activeNode)throw new Error(\"Pipeline9 cannot finish a regional fallback without an active node\");this.recordRegionalCandidateRejections();const t=[],e=new Map;for(const n of this.activeFallbackSolver.getOutput()){if(!this.activeFallbackFixedRouteSections.has(n.connectionName)){t.push(n);continue}const o=e.get(n.connectionName)??[];o.push(n),e.set(n.connectionName,o)}const n=[],o=[];for(const[t,i]of this.activeFallbackFixedRouteSections){const r=e.get(t)??[];if(0===r.length){o.push(i);continue}if(r.length\u003e1)return this.error=`Pipeline9 regional fallback expected one replacement for fixed route \"${t}\", got ${r.length}`,void(this.failed=!0);const s=VK({section:i,replacement:r[0],sourceMutationMasks:this.preloadedTraceMutationMasks,replacementIsMutated:!0});n.push({connectionName:t,section:i,replacement:s.route,mutatedSegments:s.mutatedSegments,replacementProducedSegment:s.replacementProducedSegment})}const i=[...t,...n.map(({replacement:t})=\u003et)],r=[...this.activeFallbackFixedObstacleRoutes,...o.flatMap(t=\u003et.sourceRoutes)],s=BQ(this.activeNode,this.obstacleMargin+Math.max(this.traceWidth,this.viaDiameter)/2),a=new Map;for(const t of i)for(const e of r)kQ(t,e,this.connMap)||DQ({left:t,right:e,clearance:this.obstacleMargin,leftBounds:s})\u0026\u0026a.set(e.connectionName,e);if(a.size\u003e0){const t=[...a.keys()],e=[...a].flatMap(([t,e])=\u003e!0===e.isThroughObstacle?[]:[t]),n=new Set(this.activeFallbackPromotedFixedRouteConnectionNames);for(const t of e)n.add(t);if(n.size===this.activeFallbackPromotedFixedRouteConnectionNames.size){const e=[...a].flatMap(([t,e])=\u003e!0===e.isThroughObstacle?[t]:[]);return this.error=e.length\u003e0?`Pipeline9 regional fallback conflicts with immutable through-obstacle route(s): ${e.join(\", \")}`:`Pipeline9 promoted regional fallback could not resolve immutable fixed route conflict(s): ${t.join(\", \")}`,void(this.failed=!0)}return void this.startRegionalFallback(n)}const c=new Map;for(const{section:t,replacementProducedSegment:e}of n)if(e)for(const e of t.sourceRoutes){const t=e.preloadedRoutePositionStart,n=e.preloadedRoutePositionEnd;if(void 0===t!=(void 0===n))throw new Error(`Pipeline9 fixed route \"${e.connectionName}\" has incomplete route-position metadata`);const o=Math.min(t??e.preloadedRouteIndex,n??e.preloadedRouteIndex),i=Math.max(t??e.preloadedRouteIndex,n??e.preloadedRouteIndex),r=c.get(e.preloadedTraceIndex);c.set(e.preloadedTraceIndex,{start:Math.min(r?.start??o,o),end:Math.max(r?.end??i,i)})}for(const{connectionName:t,section:e,replacement:o,mutatedSegments:i}of n){this.fixedRouteReplacements.set(t,o),this.preloadedTraceMutationMasks.set(t,i);for(const t of e.sourceRoutes.slice(1))this.removedFixedRouteConnectionNames.add(t.connectionName),this.preloadedTraceMutationMasks.delete(t.connectionName)}const l=$K({...YQ(this.activeNode,this.connMap),portPoints:[],portPointsInPairs:[],availableZ:Array.from({length:this.layerCount},(t,e)=\u003ee)},this.getUpdatedFixedHdRoutes()),d=new Set;for(const t of l.fixedRouteSectionsByConnectionName.values()){const e=t.sourceRoutes[0];if(!e)continue;const n=c.get(e.preloadedTraceIndex);if(n)for(const[o,i]of t.sourceRoutes.entries()){const r=i.preloadedRoutePositionStart??i.preloadedRouteIndex,s=i.preloadedRoutePositionEnd??i.preloadedRouteIndex,a={start:Math.min(r,s),end:Math.max(r,s)},c=a.start===a.end,l=n.start===n.end;if(!(c||l?a.start\u003c=n.end\u0026\u0026n.start\u003c=a.end:a.start\u003cn.end\u0026\u0026n.start\u003ca.end))continue;d.add(e.preloadedTraceIndex);const h=[...this.preloadedTraceMutationMasks.get(i.connectionName)??Array(i.route.length-1).fill(!1)];if(h.length!==i.route.length-1)throw new Error(`Pipeline9 fixed route mutation mask for \"${i.connectionName}\" has ${h.length} segments, expected ${i.route.length-1}`);const u=0===o?t.start.segmentIndex:0,p=o===t.sourceRoutes.length-1?t.end.segmentIndex:i.route.length-2;for(let t=u;t\u003c=p;t++)h[t]=!0;this.preloadedTraceMutationMasks.set(i.connectionName,h)}}for(const t of c.keys())if(!d.has(t))throw new Error(`Pipeline9 could not capture accepted mutation provenance for trace ${t}`);const h=n.reduce((t,{section:e})=\u003et+e.sourceRoutes.length,0);this.stats.reroutedFixedRouteCount=Number(this.stats.reroutedFixedRouteCount??0)+h,this.stats.reroutedFixedRouteSectionCount=Number(this.stats.reroutedFixedRouteSectionCount??0)+n.length,this.finishActiveNode(t)}recordRegionalCandidateRejections(){if(!this.activeFallbackSolver)return;const t=this.activeFallbackSolver.stats;this.stats.regionalPreloadedViaCandidateRejectionCount=Number(this.stats.regionalPreloadedViaCandidateRejectionCount??0)+Number(t.preloadedViaCandidateRejectionCount??0),this.stats.regionalForceImproveCandidateRejectionCount=Number(this.stats.regionalForceImproveCandidateRejectionCount??0)+Number(t.forceImproveCandidateRejectionCount??0),this.stats.regionalRepairCandidateRejectionCount=Number(this.stats.regionalRepairCandidateRejectionCount??0)+Number(t.repairCandidateRejectionCount??0)}finishRegularSolverFailure(t){if(this.activeFallbackReason=`regular high-density routing failed: ${t}`,this.activeRegularSolver=null,!this.enableRegionalFallback)return this.error=`Pipeline9 ${this.activeFallbackReason}`,this.failed=!0,void(this.activeNode=null);this.startRegionalFallback()}_step(){if(this.activeFallbackSolver){if(this.activeFallbackSolver.step(),this.activeFallbackSolver.failed)return this.recordRegionalCandidateRejections(),this.error=[`Pipeline9 primary high-density routing failed: ${this.activeFallbackReason??\"unknown error\"}`,`regional fallback failed: ${this.activeFallbackSolver.error??\"unknown error\"}`].join(\"; \"),this.failed=!0,this.activeFallbackSolver=null,this.activeFallbackFixedRouteSections.clear(),this.activeFallbackFixedObstacleRoutes=[],this.activeFallbackPromotedFixedRouteConnectionNames.clear(),void(this.activeNode=null);if(!this.activeFallbackSolver.solved)return;return void this.finishRegionalFallback()}if(this.activeRegularSolver){if(this.activeRegularSolver.step(),this.activeRegularSolver.failed)return void this.finishRegularSolverFailure(this.activeRegularSolver.error??\"unknown error\");if(!this.activeRegularSolver.solved)return;return void this.finishActiveNode(this.activeRegularSolver.routes)}if(this.activeB01Solver){if(this.activeB01Solver.step(),this.activeB01Solver.failed)return this.failedSolvers.push(this.activeB01Solver),this.activeFallbackReason=`B01 failed: ${this.activeB01Solver.error??\"unknown error\"}`,this.activeB01Solver=null,this.enableRegionalFallback?void this.startRegionalFallback():(this.error=`Pipeline9 ${this.activeFallbackReason}`,this.failed=!0,void(this.activeNode=null));if(!this.activeB01Solver.solved)return;return void this.finishActiveNode(this.activeB01Solver.getOutput())}const t=this.unsolvedNodePortPoints.pop();if(!t)return void(this.solved=!0);const e=BQ(t,this.obstacleMargin),n=Math.max(this.traceWidth,this.viaDiameter)/2,o=this.getUpdatedFixedHdRoutes().filter(o=\u003e((t,e,n,o)=\u003e{const i=new Set(e.availableZ??e.portPoints.map(t=\u003et.z));for(let e=1;e\u003ct.route.length;e++){const r=t.route[e-1],s=t.route[e];if(r.z===s.z){if(i.has(r.z)\u0026\u0026$Q(r,s,t.traceThickness/2+o,n))return!0;continue}const a=Math.min(r.z,s.z),c=Math.max(r.z,s.z);if([...i].some(t=\u003et\u003e=a\u0026\u0026t\u003c=c)\u0026\u0026jQ(s,t.viaDiameter/2+o,n))return!0}return!1})(o,t,e,n)).flatMap(e=\u003e((t,e)=\u003e{const n=new Set(e.availableZ??e.portPoints.map(t=\u003et.z));if(0===n.size)throw new Error(`Pipeline9 B01 node \"${e.capacityMeshNodeId}\" has no available layers`);const o={type:\"route\",connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,traceThickness:t.traceThickness,viaDiameter:t.viaDiameter},i=[];for(let e=1;e\u003ct.route.length;e++){const r=t.route[e-1],s=t.route[e];if(r.z===s.z){if(!n.has(r.z))continue;i.push({...o,route:[r,s],vias:[]});continue}const a=Math.min(r.z,s.z),c=Math.max(r.z,s.z);[...n].some(t=\u003et\u003e=a\u0026\u0026t\u003c=c)\u0026\u0026i.push({...o,route:[r,s],vias:[{x:s.x,y:s.y,zStart:r.z,zEnd:s.z}]})}return i})(e,t));if(this.stats.fixedObstacleUses=Number(this.stats.fixedObstacleUses??0)+o.length,0===o.length)return void this.startRegularSolver(t);const i=(this.includeBoardObstacles?this.obstacles:[]).filter(t=\u003e((t,e)=\u003e{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.abs(Math.cos(n)),i=Math.abs(Math.sin(n)),r=t.width/2*o+t.height/2*i,s=t.width/2*i+t.height/2*o;return t.center.x-r\u003c=e.maxX\u0026\u0026t.center.x+r\u003e=e.minX\u0026\u0026t.center.y-s\u003c=e.maxY\u0026\u0026t.center.y+s\u003e=e.minY})(t,e)).map(e=\u003e(({obstacle:t,node:e,connMap:n,layerCount:o})=\u003e{const i=new Set(e.availableZ??e.portPoints.map(t=\u003et.z)),r=(t.zLayers??t.layers.map(t=\u003eko(t,o))).filter(t=\u003ei.has(t));if(0===r.length)return;const s=t.connectedTo[0]??t.obstacleId??`pipeline9_obstacle_${t.center.x}_${t.center.y}`;return{type:\"rect\",connectionName:s,rootConnectionName:n.getNetConnectedToId(s)??s,center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,zLayers:r}})({obstacle:e,node:t,connMap:this.connMap,layerCount:this.layerCount})).filter(t=\u003evoid 0!==t);if(this.stats.boardObstacleUses=Number(this.stats.boardObstacleUses??0)+i.length,this.activeNode=t,t.width\u003e15||t.height\u003e15)return this.activeFallbackReason=`B01 node \"${t.capacityMeshNodeId}\" exceeds the 15x15mm routing limit (${t.width}x${t.height}mm)`,void this.startRegionalFallback();const r=YQ(t,this.connMap);this.stats.b01NodeCount=Number(this.stats.b01NodeCount??0)+1,this.activeB01Solver=new TQ({...sQ,nodeWithPortPoints:r,obstacles:[...o,...i],viaDiameter:this.viaDiameter,viaMinDistFromBorder:this.viaDiameter/2,traceThickness:this.traceWidth,traceMargin:this.obstacleMargin,obstacleClearanceMargin:.15,effort:this.effort}),void 0!==this.maxB01Rips\u0026\u0026(this.activeB01Solver.MAX_RIPS=this.maxB01Rips)}visualize(){return this.activeFallbackSolver?.visualize()??this.activeRegularSolver?.visualize()??this.activeB01Solver?.visualize()??{lines:this.routes.flatMap(t=\u003et.route.slice(0,-1).map((e,n)=\u003e({points:[e,t.route[n+1]],strokeWidth:t.traceThickness,layer:`z${e.z}`,label:t.connectionName}))),points:[],rects:[],circles:[]}}},WQ=(t,e)=\u003e{const n=e*Math.PI/180;return{x:t.x*Math.cos(n)-t.y*Math.sin(n),y:t.x*Math.sin(n)+t.y*Math.cos(n)}},HQ=({x:t,y:e,width:n,height:o,ccwRotation:i})=\u003e{const r=n/2,s=o/2;return[{x:-r,y:-s},{x:r,y:-s},{x:r,y:s},{x:-r,y:s}].map(n=\u003e{const o=WQ(n,i);return{x:t+o.x,y:e+o.y}})},GQ=t=\u003e{const e=\"rotated_pill\"===t.shape?t.ccw_rotation:0,n=Math.max(Math.max(t.width,t.height)/2-t.radius,0),o=t.width\u003e=t.height?{x:n,y:0}:{x:0,y:n},i=WQ(o,e);return{start:{x:t.x-i.x,y:t.y-i.y},end:{x:t.x+i.x,y:t.y+i.y},radius:t.radius}},UQ=t=\u003e{if(\"pcb_smtpad\"===t.type){if(\"polygon\"===t.shape)return t.points;if(\"rotated_rect\"===t.shape)return HQ({x:t.x,y:t.y,width:t.width,height:t.height,ccwRotation:t.ccw_rotation})}if(\"pcb_plated_hole\"===t.type\u0026\u0026\"rect_pad_width\"in t\u0026\u0026\"rect_pad_height\"in t)return HQ({x:t.x,y:t.y,width:t.rect_pad_width,height:t.rect_pad_height,ccwRotation:\"rect_ccw_rotation\"in t\u0026\u0026\"number\"==typeof t.rect_ccw_rotation?t.rect_ccw_rotation:0});throw new Error(`Expected polygonal pad geometry, got ${t.type} with shape \"${t.shape}\"`)},ZQ=t=\u003et.map((e,n)=\u003e[e,t[(n+1)%t.length]]),qQ=(t,e,n,o)=\u003e{const i=ve(t,e,n,o);if(i)return{distance:0,pointOnA:i,pointOnB:i,center:i};const r=[{pointOnA:t,pointOnB:ze(t,n,o)},{pointOnA:e,pointOnB:ze(e,n,o)},{pointOnA:ze(n,t,e),pointOnB:n},{pointOnA:ze(o,t,e),pointOnB:o}];let s=r[0],a=Ye(s.pointOnA,s.pointOnB);for(const t of r.slice(1)){const e=Ye(t.pointOnA,t.pointOnB);e\u003ca\u0026\u0026(s=t,a=e)}return{distance:Oe(t,e,n,o),pointOnA:s.pointOnA,pointOnB:s.pointOnB,center:{x:(s.pointOnA.x+s.pointOnB.x)/2,y:(s.pointOnA.y+s.pointOnB.y)/2}}};function JQ(t,e){return Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2)}var KQ=1e-9,QQ=1e-9;function t0(t,e){const n=(t.y-e.start.y)*(e.end.x-e.start.x)-(t.x-e.start.x)*(e.end.y-e.start.y);if(Math.abs(n)\u003eKQ)return!1;const o=(t.x-e.start.x)*(e.end.x-e.start.x)+(t.y-e.start.y)*(e.end.y-e.start.y);if(o\u003c-1e-9)return!1;return o\u003c=(e.end.x-e.start.x)**2+(e.end.y-e.start.y)**2+KQ}function e0(t,e){let n=!1;for(let o=0,i=e.length-1;o\u003ce.length;i=o++){const r=e[o],s=e[i];if(t0(t,{start:r,end:s}))return!0;r.y\u003et.y!=s.y\u003et.y\u0026\u0026t.x\u003c(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x\u0026\u0026(n=!n)}return n}function n0(t,e){if(\"pcb_smtpad\"===e.type){if(\"circle\"===e.shape)return JQ(t,e)\u003c=e.radius+QQ;if(\"rect\"===e.shape){const n=e.width/2,o=e.height/2;return Math.abs(t.x-e.x)\u003c=n+QQ\u0026\u0026Math.abs(t.y-e.y)\u003c=o+QQ}if(\"rotated_rect\"===e.shape)return e0(t,UQ(e));if(\"pill\"===e.shape||\"rotated_pill\"===e.shape){if(\"rotated_pill\"===e.shape){const n=GQ(e);return be(t,n.start,n.end)\u003c=n.radius+QQ}const n=e.width/2,o=e.height/2,i=e.radius;if(Math.abs(t.x-e.x)\u003c=n-i+QQ\u0026\u0026Math.abs(t.y-e.y)\u003c=o+QQ)return!0;const r=Math.max(Math.abs(t.x-e.x)-(n-i),0),s=Math.max(Math.abs(t.y-e.y)-(o-i),0),a=i+QQ;return r*r+s*s\u003c=a*a}if(\"polygon\"===e.shape)return e0(t,e.points)}if(\"pcb_plated_hole\"===e.type){if(\"circle\"===e.shape)return JQ(t,e)\u003c=e.outer_diameter/2+QQ;if(\"rect_pad_width\"in e\u0026\u0026\"rect_pad_height\"in e)return e0(t,UQ(e));if(\"oval\"===e.shape||\"pill\"===e.shape)return Math.abs(t.x-e.x)\u003c=e.outer_width/2+QQ\u0026\u0026Math.abs(t.y-e.y)\u003c=e.outer_height/2+QQ}return!1}function o0(t,e,n,o){return Math.sqrt((n-t)**2+(o-e)**2)}var i0=.1,r0=.1,s0=.2,a0=.1,c0=.005,l0=t=\u003et.find(t=\u003e\"pcb_board\"===t.type),d0=(t,e)=\u003et?.[e],h0=t=\u003eEM([t]),u0=t=\u003e{const e=h0(t);return Math.min(e.maxX-e.minX,e.maxY-e.minY)/2},p0=t=\u003e{const e=(t=\u003e{const e=h0(t);return $e({x:e.minX,y:e.minY},{x:e.maxX,y:e.maxY})})(t);return{kind:\"circle\",x:e.x,y:e.y,radius:u0(t)}},m0=t=\u003evM(t).pcb_trace.list().flatMap(t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];\"wire\"===o.route_type\u0026\u0026(\"wire\"===i.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({type:\"pcb_trace_segment\",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:\"width\"in o?o.width:\"width\"in i?i.width:a0,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),g0=t=\u003e{const e=t._pcbTrace.route.flatMap(t=\u003e\"through_pad\"===t.route_type?[t.start,t.end]:[{x:t.x,y:t.y}]),n=e[0],o=e[e.length-1];return n\u0026\u0026o?$e(n,o):$e({x:t.x1,y:t.y1},{x:t.x2,y:t.y2})},f0=({tracePoint:t,obstaclePoint:e,traceRadius:n,obstacleRadius:o})=\u003e{const i=e.x-t.x,r=e.y-t.y,s=Math.hypot(i,r);if(0===s)return $e(t,e);const a=i/s,c=r/s;return $e({x:t.x+a*n,y:t.y+c*n},{x:e.x-a*o,y:e.y-c*o})},y0=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=t.thickness/2;if(\"pcb_via\"===e.type||(\"pcb_via\"===(r=e).type||\"circle\"===r.shape)){const t=\"pcb_via\"===e.type?{x:e.x,y:e.y,radius:e.outer_diameter/2}:p0(e),r=ze(t,n,o);return{gap:De(n,o,t)-i,center:f0({tracePoint:r,obstaclePoint:t,traceRadius:i,obstacleRadius:t.radius})}}var r;if((t=\u003e\"pcb_smtpad\"===t.type\u0026\u0026(\"pill\"===t.shape||\"rotated_pill\"===t.shape))(e)){const n=((t,e)=\u003e{const n=GQ(e),o=qQ({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},n.start,n.end);return{distance:o.distance,center:o.center,radius:n.radius,tracePoint:o.pointOnA,obstaclePoint:o.pointOnB}})(t,e);return{gap:n.distance-i-n.radius,center:f0({tracePoint:n.tracePoint,obstaclePoint:n.obstaclePoint,traceRadius:i,obstacleRadius:n.radius})}}const s=((t,e,n)=\u003e{if(n.length\u003c3)return{distance:Number.POSITIVE_INFINITY,center:t,tracePoint:t,obstaclePoint:t};const o=ZQ(n).map(([n,o])=\u003eve(t,e,n,o)).filter(t=\u003enull!==t);if(o.length\u003e0){const n=e.x-t.x,i=e.y-t.y,r=n*n+i*i;return o.sort((e,o)=\u003e((e.x-t.x)*n+(e.y-t.y)*i)/r-((o.x-t.x)*n+(o.y-t.y)*i)/r),{distance:0,center:o[0],tracePoint:o[0],obstaclePoint:o[0]}}if(Ne(t,n)||Ne(e,n)){const n={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return{distance:0,center:n,tracePoint:n,obstaclePoint:n}}let i=qQ(t,e,n[0],n[1]);for(const[o,r]of ZQ(n).slice(1)){const n=qQ(t,e,o,r);n.distance\u003ci.distance\u0026\u0026(i=n)}return{distance:i.distance,center:i.center,tracePoint:i.pointOnA,obstaclePoint:i.pointOnB}})(n,o,(t=\u003e{if(\"pcb_smtpad\"===t.type\u0026\u0026(\"polygon\"===t.shape||\"rotated_rect\"===t.shape))return{kind:\"polygon\",points:UQ(t)};if(\"pcb_plated_hole\"===t.type\u0026\u0026\"rect_pad_width\"in t\u0026\u0026\"rect_pad_height\"in t)return{kind:\"polygon\",points:UQ(t)};const e=h0(t);return{kind:\"polygon\",points:[{x:e.minX,y:e.minY},{x:e.maxX,y:e.minY},{x:e.maxX,y:e.maxY},{x:e.minX,y:e.maxY}]}})(e).points);return{gap:s.distance-i,center:f0({tracePoint:s.tracePoint,obstaclePoint:s.obstaclePoint,traceRadius:i,obstacleRadius:0})}},_0=t=\u003et\u003c=0,b0=class{buckets;objectsById;getBounds;getId;CELL_SIZE=.4;constructor({objects:t,getBounds:e,getId:n,CELL_SIZE:o}){this.buckets=new Map,this.objectsById=new Map,this.getBounds=e,this.getId=n??(()=\u003ethis._getNextId()),this.CELL_SIZE=o??this.CELL_SIZE;for(const e of t)this.addObject(e)}_idCounter=0;_getNextId(){return\"\"+this._idCounter++}addObject(t){const e=this.getBounds(t),n=this.getId(t),o={...t,spatialIndexId:n};this.objectsById.set(n,o);const i=Math.floor(e.minX/this.CELL_SIZE),r=Math.floor(e.minY/this.CELL_SIZE),s=Math.floor(e.maxX/this.CELL_SIZE),a=Math.floor(e.maxY/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const n=`${t}x${e}`,i=this.buckets.get(n);i?i.push(o):this.buckets.set(n,[o])}}removeObject(t){const e=this.objectsById.get(t);if(!e)return!1;this.objectsById.delete(t);const n=this.getBounds(e),o=Math.floor(n.minX/this.CELL_SIZE),i=Math.floor(n.minY/this.CELL_SIZE),r=Math.floor(n.maxX/this.CELL_SIZE),s=Math.floor(n.maxY/this.CELL_SIZE);for(let e=o;e\u003c=r;e++)for(let n=i;n\u003c=s;n++){const o=`${e}x${n}`,i=this.buckets.get(o);if(i){const e=i.findIndex(e=\u003ee.spatialIndexId===t);-1!==e\u0026\u0026(i.splice(e,1),0===i.length\u0026\u0026this.buckets.delete(o))}}return!0}getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getObjectsInBounds(t,e=0){const n=[],o=new Set,i=Math.floor((t.minX-e)/this.CELL_SIZE),r=Math.floor((t.minY-e)/this.CELL_SIZE),s=Math.floor((t.maxX+e)/this.CELL_SIZE),a=Math.floor((t.maxY+e)/this.CELL_SIZE);for(let t=i;t\u003c=s;t++)for(let e=r;e\u003c=a;e++){const i=`${t}x${e}`,r=this.buckets.get(i)||[];for(const t of r){const e=t.spatialIndexId;o.has(e)||(o.add(e),n.push(t))}}return n}};function x0(t){return\"pcb_trace_segment\"===t.type||\"pcb_smtpad\"===t.type?[t.layer]:\"pcb_plated_hole\"===t.type?Array.isArray(t.layers)?t.layers:[...WS]:\"pcb_hole\"===t.type?[...WS]:\"pcb_via\"===t.type?Array.isArray(t.layers)?t.layers:[...WS]:\"pcb_keepout\"===t.type\u0026\u0026Array.isArray(t.layers)?t.layers:[]}var v0=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=e.minX,r=e.minY,s=e.maxX,a=e.maxY;if(n.x===o.x\u0026\u0026n.y===o.y){const t=Math.max(i,Math.min(s,n.x)),e=Math.max(r,Math.min(a,n.y));return t===n.x\u0026\u0026e===n.y?{x:n.x,y:n.y}:{x:t,y:e}}const c=o.x-n.x,l=o.y-n.y,d=0!==c?(i-n.x)/c:Number.NEGATIVE_INFINITY,h=0!==c?(s-n.x)/c:Number.POSITIVE_INFINITY,u=0!==l?(r-n.y)/l:Number.NEGATIVE_INFINITY,p=0!==l?(a-n.y)/l:Number.POSITIVE_INFINITY,m=Math.max(Math.min(d,h),Math.min(u,p)),g=Math.min(Math.max(d,h),Math.max(u,p));if(m\u003c=g\u0026\u0026g\u003e=0\u0026\u0026m\u003c=1){const t=Math.max(0,Math.min(1,m));return{x:n.x+t*c,y:n.y+t*l}}const f={x:Math.max(i,Math.min(s,n.x)),y:Math.max(r,Math.min(a,n.y))},y={x:Math.max(i,Math.min(s,o.x)),y:Math.max(r,Math.min(a,o.y))},_=(f.x-n.x)**2+(f.y-n.y)**2,b=(y.x-o.x)**2+(y.y-o.y)**2,x=[{start:{x:i,y:r},end:{x:s,y:r}},{start:{x:s,y:r},end:{x:s,y:a}},{start:{x:s,y:a},end:{x:i,y:a}},{start:{x:i,y:a},end:{x:i,y:r}}];let v=Math.min(_,b),S=_\u003c=b?f:y;const I=(t,e,n)=\u003eMath.max(e,Math.min(n,t));for(const t of x){const e={x:o.x-n.x,y:o.y-n.y},i={x:t.end.x-t.start.x,y:t.end.y-t.start.y},r={x:n.x-t.start.x,y:n.y-t.start.y},s=e.x*e.x+e.y*e.y,a=e.x*i.x+e.y*i.y,c=e.x*r.x+e.y*r.y,l=i.x*i.x+i.y*i.y,d=i.x*r.x+i.y*r.y,h=s*l-a*a;if(Math.abs(h)\u003c1e-10)continue;let u=(a*d-l*c)/h,p=(s*d-a*c)/h;u=I(u,0,1),p=I(p,0,1);const m={x:n.x+u*e.x,y:n.y+u*e.y},g={x:t.start.x+p*i.x,y:t.start.y+p*i.y},f=m.x-g.x,y=m.y-g.y,_=f*f+y*y;_\u003cv\u0026\u0026(v=_,S={x:(m.x+g.x)/2,y:(m.y+g.y)/2})}return S},S0=(t,e)=\u003e{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i={x:e.x1,y:e.y1},r={x:e.x2,y:e.y2},s={x:o.x-n.x,y:o.y-n.y},a={x:r.x-i.x,y:r.y-i.y},c=s.x*s.x+s.y*s.y,l=a.x*a.x+a.y*a.y;if(0===c||0===l){if(0===c\u0026\u00260===l)return{x:(n.x+i.x)/2,y:(n.y+i.y)/2};if(0===c){const t=C0(((n.x-i.x)*a.x+(n.y-i.y)*a.y)/l,0,1),e={x:i.x+t*a.x,y:i.y+t*a.y};return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}}const t=C0(((i.x-n.x)*s.x+(i.y-n.y)*s.y)/c,0,1),e={x:n.x+t*s.x,y:n.y+t*s.y};return{x:(e.x+i.x)/2,y:(e.y+i.y)/2}}const d=n.x-i.x,h=n.y-i.y,u=s.x*s.x+s.y*s.y,p=s.x*a.x+s.y*a.y,m=s.x*d+s.y*h,g=a.x*a.x+a.y*a.y,f=a.x*d+a.y*h,y=u*g-p*p;if(y\u003c1e-10)return I0(n,o,i,r,s,a,c,l);let _=(p*f-g*m)/y,b=(u*f-p*m)/y;_=C0(_,0,1),b=C0(b,0,1),b=(_*p+f)/g,b=C0(b,0,1),_=(b*p-m)/u,_=C0(_,0,1);const x=n.x+_*s.x,v=n.y+_*s.y,S=i.x+b*a.x,I=i.y+b*a.y,C=x-S,P=v-I;Math.sqrt(C*C+P*P);return{x:(x+S)/2,y:(v+I)/2}},I0=(t,e,n,o,i,r,s,a)=\u003e{let c=((n.x-t.x)*i.x+(n.y-t.y)*i.y)/s;c=C0(c,0,1);const l={x:t.x+c*i.x,y:t.y+c*i.y};let d=((o.x-t.x)*i.x+(o.y-t.y)*i.y)/s;d=C0(d,0,1);const h={x:t.x+d*i.x,y:t.y+d*i.y};let u=((t.x-n.x)*r.x+(t.y-n.y)*r.y)/a;u=C0(u,0,1);const p={x:n.x+u*r.x,y:n.y+u*r.y};let m=((e.x-n.x)*r.x+(e.y-n.y)*r.y)/a;m=C0(m,0,1);const g={x:n.x+m*r.x,y:n.y+m*r.y},f=[{pointA:l,pointB:n,distance:Math.sqrt((l.x-n.x)**2+(l.y-n.y)**2)},{pointA:h,pointB:o,distance:Math.sqrt((h.x-o.x)**2+(h.y-o.y)**2)},{pointA:t,pointB:p,distance:Math.sqrt((t.x-p.x)**2+(t.y-p.y)**2)},{pointA:e,pointB:g,distance:Math.sqrt((e.x-g.x)**2+(e.y-g.y)**2)}].reduce((t,e)=\u003ee.distance\u003ct.distance?e:t);return{x:(f.pointA.x+f.pointB.x)/2,y:(f.pointA.y+f.pointB.y)/2}},C0=(t,e,n)=\u003eMath.max(e,Math.min(n,t)),P0=t=\u003e{if(\"pcb_trace_segment\"===t.type)return{minX:Math.min(t.x1,t.x2),minY:Math.min(t.y1,t.y2),maxX:Math.max(t.x1,t.x2),maxY:Math.max(t.y1,t.y2)};if(\"pcb_smtpad\"===t.type||\"pcb_plated_hole\"===t.type){if(\"pcb_smtpad\"===t.type\u0026\u0026(\"rotated_rect\"===t.shape||\"polygon\"===t.shape)||\"pcb_plated_hole\"===t.type\u0026\u0026\"rect_pad_width\"in t\u0026\u0026\"rect_pad_height\"in t){const e=UQ(t);return{minX:Math.min(...e.map(t=\u003et.x)),minY:Math.min(...e.map(t=\u003et.y)),maxX:Math.max(...e.map(t=\u003et.x)),maxY:Math.max(...e.map(t=\u003et.y))}}if(\"pcb_smtpad\"===t.type\u0026\u0026\"rotated_pill\"===t.shape){const e=GQ(t);return{minX:Math.min(e.start.x,e.end.x)-e.radius,minY:Math.min(e.start.y,e.end.y)-e.radius,maxX:Math.max(e.start.x,e.end.x)+e.radius,maxY:Math.max(e.start.y,e.end.y)+e.radius}}}return EM([t])};function M0(t){return\"wire\"!==t.route_type?[]:[t.start_pcb_port_id,t.end_pcb_port_id].filter(t=\u003eBoolean(t))}function N0(t){const e=new Set;for(const n of t.route)for(const t of M0(n))e.add(t);return Array.from(e)}function w0(t){const e=new Set;for(const n of t)for(const t of N0(n))e.add(t);return Array.from(e)}var T0=t=\u003e{if(\"pcb_via\"===t.type)return t.outer_diameter/2;if(\"pcb_plated_hole\"===t.type\u0026\u0026\"circle\"===t.shape)return t.outer_diameter/2;if(\"pcb_hole\"===t.type\u0026\u0026\"circle\"===t.hole_shape)return t.hole_diameter/2;if(\"pcb_smtpad\"===t.type\u0026\u0026\"circle\"===t.shape)return t.radius;throw new Error(`Could not determine radius of element: ${JSON.stringify(t)}`)},R0=t=\u003e\"pcb_port\"===t.type?t.pcb_port_id:\"pcb_smtpad\"===t.type?t.pcb_smtpad_id:t.pcb_plated_hole_id;function E0(t,{connMap:e,minClearance:n}={}){const o=[];(t=\u003e{const e=t.filter(t=\u003e\"pcb_port\"===t.type),n=t.filter(t=\u003e\"pcb_smtpad\"===t.type),o=t.filter(t=\u003e\"pcb_trace\"===t.type);function i(t,o={}){const i=o.traceWidth||0,r=e.find(e=\u003eo0(e.x,e.y,t.x,t.y)\u003c.01);if(r)return r.pcb_port_id;if(o.isFirstOrLastPoint){const e=n.find(e=\u003e\"rect\"===e.shape?Math.abs(t.x-e.x)\u003ce.width/2+i/2\u0026\u0026Math.abs(t.y-e.y)\u003ce.height/2+i/2:\"circle\"===e.shape?o0(t.x,t.y,e.x,e.y)\u003ce.radius:\"pill\"===e.shape||\"rotated_pill\"===e.shape?n0(t,e):void 0);if(e)return e.pcb_port_id??null}return null}for(const t of o)for(let e=0;e\u003ct.route.length;e++){const n=t.route[e],o=0===e||e===t.route.length-1;if(\"wire\"===n.route_type){if(!n.start_pcb_port_id\u0026\u00260===e){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.start_pcb_port_id=t)}if(!n.end_pcb_port_id\u0026\u0026e===t.route.length-1){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t\u0026\u0026(n.end_pcb_port_id=t)}}}})(t),e??=ei(t);const i=l0(t);n??=d0(i,\"min_trace_to_pad_edge_clearance\")??.1;const r=vM(t).pcb_trace.list().flatMap(t=\u003e{const e=[];for(let n=0;n\u003ct.route.length-1;n++){const o=t.route[n],i=t.route[n+1];\"wire\"===o.route_type\u0026\u0026(\"wire\"===i.route_type\u0026\u0026o.layer===i.layer\u0026\u0026e.push({type:\"pcb_trace_segment\",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:\"width\"in o?o.width:\"width\"in i?i.width:a0,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),s=vM(t).pcb_smtpad.list(),a=vM(t).pcb_plated_hole.list(),c=vM(t).pcb_port.list(),l=vM(t).pcb_hole.list(),d=vM(t).pcb_via.list(),h=vM(t).pcb_keepout.list(),u=[...c,...s,...a],p=new Map;for(const t of h){const e=new Set(t.excluded_pcb_component_ids??[]);0!==e.size\u0026\u0026p.set(t.pcb_keepout_id,u.filter(t=\u003et.pcb_component_id\u0026\u0026e.has(t.pcb_component_id)).map(R0))}const m=[...r,...s,...a,...l,...d,...h],g=new b0({objects:m,getBounds:P0}),f=e=\u003eNM(t,e),y=(t,e,n)=\u003e_0(n)?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,_=new Set;for(const t of r){const i=n,r=P0(t),s=g.getObjectsInBounds(r,i+t.thickness/2);if(t.x1!==t.x2||t.y1!==t.y2)for(const r of s){if(!x0(r).includes(t.layer))continue;if(\"pcb_keepout\"===r.type\u0026\u0026(p.get(r.pcb_keepout_id)??[]).some(n=\u003ee.areIdsConnected(t.pcb_trace_id,n)))continue;if(\"pcb_trace_segment\"===r.type){const i=r;if(t.layer!==i.layer)continue;if(e.areIdsConnected(t.pcb_trace_id,i.pcb_trace_id))continue;const s=Oe({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:i.x1,y:i.y1},{x:i.x2,y:i.y2})-t.thickness/2-i.thickness/2;if(s\u003en-c0)continue;const a=`overlap_${t.pcb_trace_id}_${i.pcb_trace_id}`,c=`overlap_${i.pcb_trace_id}_${t.pcb_trace_id}`;if(_.has(a))continue;if(_.has(c))continue;_.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),f(i.pcb_trace_id),s),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[],center:S0(t,i),pcb_port_ids:w0([t._pcbTrace,i._pcbTrace])});continue}const s=AM(r);if(e.areIdsConnected(t.pcb_trace_id,\"pcb_trace_id\"in r?r.pcb_trace_id:s))continue;if(\"pcb_smtpad\"===r.type||\"pcb_plated_hole\"===r.type||\"pcb_via\"===r.type){const{gap:e,center:n}=y0(t,r);if(!_0(e))continue;const i=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(i))continue;_.add(i),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),`${r.type} \"${f(s)}\"`,e),pcb_trace_id:t.pcb_trace_id,center:n,source_trace_id:\"\",pcb_trace_error_id:i,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...w0([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)});continue}if(\"pcb_hole\"===r.type){const e=T0(r),i=De({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:r.x,y:r.y,radius:e})-t.thickness/2;if(i\u003en-c0)continue;const a=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(a))continue;_.add(a),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),`${r.type} \"${f(AM(r))}\"`,i),pcb_trace_id:t.pcb_trace_id,center:v0(t,P0(r)),source_trace_id:\"\",pcb_trace_error_id:a,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...w0([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}const a=ke({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},P0(r))-t.thickness/2;if(a+c0\u003ci){const e=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(e))continue;_.add(e),o.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:y(f(t.pcb_trace_id),`${r.type} \"${f(AM(r))}\"`,a),pcb_trace_id:t.pcb_trace_id,source_trace_id:\"\",pcb_trace_error_id:e,pcb_component_ids:[\"pcb_component_id\"in r?r.pcb_component_id:void 0].filter(Boolean),center:v0(t,P0(r)),pcb_port_ids:[...w0([t._pcbTrace]),\"pcb_port_id\"in r?r.pcb_port_id:void 0].filter(Boolean)})}}}return o}function A0(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function O0(t,e){return A0(t,e)\u003c=c0}function k0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];const i=l0(t);n??=d0(i,\"min_via_hole_edge_to_via_hole_edge_clearance\")??i0,e??=ei(t);const r=[],s=new Set;for(let i=0;i\u003co.length;i++)for(let a=i+1;a\u003co.length;a++){const c=o[i],l=o[a];if(O0(c,l))continue;if(!e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=A0(c,l)-c.hole_diameter/2-l.hole_diameter/2;if(d+c0\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");s.has(h)||(s.add(h),r.push({type:\"pcb_via_clearance_error\",pcb_error_id:`same_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return r}function L0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type);if(o.length\u003c2)return[];const i=l0(t);n??=d0(i,\"min_via_hole_edge_to_via_hole_edge_clearance\")??i0,e??=ei(t);const r=[],s=new Set;for(let i=0;i\u003co.length;i++)for(let a=i+1;a\u003co.length;a++){const c=o[i],l=o[a];if(O0(c,l))continue;if(e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=A0(c,l)-c.hole_diameter/2-l.hole_diameter/2;if(d+c0\u003e=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join(\"_\");s.has(h)||(s.add(h),r.push({type:\"pcb_via_clearance_error\",pcb_error_id:`different_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} from different nets are too close together (gap: ${d.toFixed(3)}mm)`,error_type:\"pcb_via_clearance_error\",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return r}function D0(t){return\"through_pad\"===t.route_type?{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2}:{x:t.x,y:t.y}}function z0(t,e,n,o){return\"wire\"===t.route_type\u0026\u0026e.some(e=\u003e{if(!e.pcb_port_id||e.pcb_port_id===n)return!1;const i=o.get(e.pcb_port_id);return i?.some(e=\u003en0({x:t.x,y:t.y},e))??!1})}function F0({firstPoint:t,lastPoint:e,port:n,expectedPorts:o,padMap:i}){let r;const s=\"wire\"===t.route_type?t:void 0,a=\"wire\"===e.route_type?e:void 0,c=M0(t).includes(n.pcb_port_id),l=M0(e).includes(n.pcb_port_id);c\u0026\u0026s?r=s:l\u0026\u0026a||z0(t,o,n.pcb_port_id,i)\u0026\u0026a?r=a:z0(e,o,n.pcb_port_id,i)\u0026\u0026s?r=s:s\u0026\u0026a?r=A0(s,n)\u003c=A0(a,n)?s:a:s?r=s:a\u0026\u0026(r=a);const d=D0(t),h=D0(e);return r?{x:r.x,y:r.y}:{x:(d.x+h.x)/2,y:(d.y+h.y)/2}}function B0(t){const e=[],n=t.filter(t=\u003e\"pcb_port\"===t.type),o=t.filter(t=\u003e\"pcb_trace\"===t.type),i=t.filter(t=\u003e\"source_trace\"===t.type),r=t.filter(t=\u003e\"pcb_smtpad\"===t.type),s=t.filter(t=\u003e\"pcb_plated_hole\"===t.type),a=new Map,c=new ni(t),l=new Set;for(const t of r)t.pcb_port_id\u0026\u0026a.set(t.pcb_port_id,[...a.get(t.pcb_port_id)??[],t]);for(const t of s)t.pcb_port_id\u0026\u0026a.set(t.pcb_port_id,[...a.get(t.pcb_port_id)??[],t]);for(const r of o){if(0===r.route.length)continue;const s=r.route[0],d=r.route[r.route.length-1],h=i.find(t=\u003et.source_trace_id===r.source_trace_id),u=h?n.filter(t=\u003eh.connected_source_port_ids?.includes(t.source_port_id)):[];for(let n=1;n\u003cr.route.length-1;n++){const o=r.route[n-1],i=r.route[n],s=r.route[n+1];if(\"via\"===i.route_type){const a=\"wire\"===o.route_type,c=\"wire\"===s.route_type;if(a\u0026\u0026c){const a=Math.abs(o.x-i.x)\u003c.01\u0026\u0026Math.abs(o.y-i.y)\u003c.01,c=Math.abs(s.x-i.x)\u003c.01\u0026\u0026Math.abs(s.y-i.y)\u003c.01;if(!a||!c){const o=PM(t,r.pcb_trace_id);e.push({type:\"pcb_trace_error\",message:`Via in trace [${o}] is misaligned at position {x: ${i.x}, y: ${i.y}}.`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`misaligned_via_${r.pcb_trace_id}_${n}`,pcb_component_ids:[],pcb_port_ids:[]})}}}}const p=PM(t,r.pcb_trace_id);if(h\u0026\u0026u.length\u003e0){if(l.has(h.source_trace_id))continue;l.add(h.source_trace_id)}for(const n of u){if(!n.pcb_port_id)continue;const l=a.get(n.pcb_port_id);if(!l?.length)continue;let m=!1;const g=[...c.getAllTracesConnectedToTrace(r.pcb_trace_id),...o.filter(t=\u003et.source_trace_id===h?.source_trace_id)];for(const t of g){if(t.pcb_trace_id===r.pcb_trace_id)continue;if(!t.source_trace_id)continue;const e=i.find(e=\u003ee.source_trace_id===t.source_trace_id);if(!h||t.source_trace_id!==h.source_trace_id\u0026\u0026!e?.connected_source_port_ids.includes(n.source_port_id))continue;const o=t.route[0],s=t.route.at(-1);if(N0(t).includes(n.pcb_port_id)||\"wire\"===o?.route_type\u0026\u0026l.some(t=\u003en0(o,t))||\"wire\"===s?.route_type\u0026\u0026l.some(t=\u003en0(s,t))){m=!0;break}}if(m)continue;const f=\"wire\"===s.route_type\u0026\u0026l.some(t=\u003en0({x:s.x,y:s.y},t)),y=\"wire\"===d.route_type\u0026\u0026l.some(t=\u003en0({x:d.x,y:d.y},t));if(!f\u0026\u0026!y){const o=MM(t,n.pcb_port_id).replace(\"pcb_port\",\"\"),i=l[0].type.replace(/pcb_/,\"\"),c=F0({firstPoint:s,lastPoint:d,port:n,expectedPorts:u,padMap:a});e.push({type:\"pcb_trace_error\",message:`Trace [${p}] is missing a connection to ${i}${o}`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`missing_connection_${r.pcb_trace_id}_${n.pcb_port_id}`,center:c,pcb_component_ids:[],pcb_port_ids:[n.pcb_port_id]})}}if(0===u.length){let t=!1,n=!1;const o=\"wire\"===s.route_type\u0026\u0026\"wire\"===d.route_type\u0026\u0026Math.abs(s.x-d.x)\u003c.01\u0026\u0026Math.abs(s.y-d.y)\u003c.01;for(const e of a.values())\"wire\"===s.route_type\u0026\u0026e.some(t=\u003en0({x:s.x,y:s.y},t))\u0026\u0026(t=!0),\"wire\"===d.route_type\u0026\u0026e.some(t=\u003en0({x:d.x,y:d.y},t))\u0026\u0026(n=!0);t||\"wire\"!==s.route_type||e.push({type:\"pcb_trace_error\",message:`Trace [${p}] has disconnected endpoint at (${s.x.toFixed(2)}, ${s.y.toFixed(2)})`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`disconnected_endpoint_${r.pcb_trace_id}_start`,center:{x:s.x,y:s.y},pcb_component_ids:[],pcb_port_ids:[]}),n||\"wire\"!==d.route_type||o\u0026\u0026!t||e.push({type:\"pcb_trace_error\",message:`Trace [${p}] has disconnected endpoint at (${d.x.toFixed(2)}, ${d.y.toFixed(2)})`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:\"pcb_trace_error\",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`disconnected_endpoint_${r.pcb_trace_id}_end`,center:{x:d.x,y:d.y},pcb_component_ids:[],pcb_port_ids:[]})}}return e}function j0(t,e={}){const n=[],o=l0(t);if(!o)return n;const i=e.margin??d0(o,\"min_board_edge_clearance\")??s0,r=function(t){if(t.outline\u0026\u0026t.outline.length\u003e0)return t.outline.map(t=\u003e({x:t.x,y:t.y}));if(t.center\u0026\u0026\"number\"==typeof t.width\u0026\u0026\"number\"==typeof t.height){const e=t.center.x,n=t.center.y,o=t.width/2,i=t.height/2;return[{x:e-o,y:n-i},{x:e+o,y:n-i},{x:e+o,y:n+i},{x:e-o,y:n+i}]}return null}(o);if(!r)return n;const s=vM(t).pcb_trace.list();for(const t of s)if(!(t.route.length\u003c2))for(let e=0;e\u003ct.route.length-1;e++){const o=t.route[e],s=t.route[e+1];if(\"wire\"!==o.route_type||\"wire\"!==s.route_type)continue;const a=\"width\"in o?o.width:\"width\"in s?s.width:.1,c={x:o.x,y:o.y},l={x:s.x,y:s.y};let d=Number.POSITIVE_INFINITY;for(let t=0;t\u003cr.length;t++){const e=Oe(c,l,r[t],r[(t+1)%r.length]);e\u003cd\u0026\u0026(d=e)}const h=a/2+i;if(d\u003ch){const o={type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",pcb_trace_error_id:`trace_too_close_to_board_${t.pcb_trace_id}_segment_${e}`,message:`Trace too close to board edge (${d.toFixed(3)}mm \u003c ${h.toFixed(3)}mm required, margin: ${i}mm)`,pcb_trace_id:t.pcb_trace_id,source_trace_id:t.source_trace_id||\"\",center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2},pcb_component_ids:[],pcb_port_ids:[]};n.push(o)}}return n}function $0(t,{connMap:e,minClearance:n}={}){const o=(t=\u003e[...vM(t).pcb_smtpad.list(),...vM(t).pcb_plated_hole.list()])(t),i=m0(t);if(0===o.length||0===i.length)return[];const r=l0(t);n??=d0(r,\"min_trace_to_pad_edge_clearance\")??r0,e??=ei(t);const s=new b0({objects:o,getBounds:h0,getId:t=\u003eAM(t)}),a=new Map,c=new Set;for(const o of i){const i=s.getObjectsInBounds(P0(o),n+o.thickness/2);for(const r of i){const i=AM(r);if(!x0(r).includes(o.layer))continue;if(e.areIdsConnected(o.pcb_trace_id,i))continue;const s=`${i}_${o.pcb_trace_id}`,{gap:l}=y0(o,r);if(_0(l)){a.delete(s),c.add(s);continue}if(c.has(s))continue;if(l+c0\u003e=n)continue;const d={type:\"pcb_pad_trace_clearance_error\",pcb_pad_trace_clearance_error_id:`pad_trace_clearance_${s}`,error_type:\"pcb_pad_trace_clearance_error\",message:`Pad ${NM(t,i)} and trace ${NM(t,o.pcb_trace_id)} are too close (clearance: ${I_(l)}, minimum: ${I_(n)})`,pcb_pad_id:i,pcb_trace_id:o.pcb_trace_id,minimum_clearance:n,actual_clearance:l,center:g0(o)},h=a.get(s);(!h||l\u003ch.gap)\u0026\u0026a.set(s,{error:d,gap:l})}}return Array.from(a.values()).map(({error:t})=\u003et)}function Y0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=\u003e\"pcb_via\"===t.type),i=m0(t);if(0===o.length||0===i.length)return[];const r=l0(t);n??=d0(r,\"min_trace_to_pad_edge_clearance\")??r0,e??=ei(t);const s=new Map,a=new Set;for(const r of o)for(const o of i){if(!x0(r).includes(o.layer))continue;if(e.areIdsConnected(o.pcb_trace_id,r.pcb_via_id))continue;const i=`${r.pcb_via_id}_${o.pcb_trace_id}`,{gap:c}=y0(o,r);if(_0(c)){s.delete(i),a.add(i);continue}if(a.has(i))continue;if(c+c0\u003e=n)continue;const l={type:\"pcb_via_trace_clearance_error\",pcb_via_trace_clearance_error_id:`via_trace_clearance_${i}`,error_type:\"pcb_via_trace_clearance_error\",message:`Via ${NM(t,r.pcb_via_id)} and trace ${NM(t,o.pcb_trace_id)} are too close (clearance: ${I_(c)}, minimum: ${I_(n)})`,pcb_via_id:r.pcb_via_id,pcb_trace_id:o.pcb_trace_id,minimum_clearance:n,actual_clearance:c,center:g0(o)},d=s.get(i);(!d||c\u003cd.gap)\u0026\u0026s.set(i,{error:l,gap:c})}return Array.from(s.values()).map(({error:t})=\u003et)}var X0=(t,e={})=\u003e{const n=(t=\u003e{const e=ei(t),n=t.filter(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_trace_id).map(t=\u003e[t.pcb_via_id,t.pcb_trace_id]);return e.addConnections(n),e})(t),o=Math.max(e.viaClearance??.1,.1),i=E0(t,{connMap:n,minClearance:e.traceClearance}),r=!1!==e.includeTypedTraceClearance,s=r?Y0(t,{connMap:n,minClearance:e.traceClearance}):[],a=r?$0(t,{connMap:n,minClearance:e.traceClearance}):[],c=[...k0(t,{connMap:n,minClearance:o}),...L0(t,{connMap:n,minClearance:o})],l=[...i,...j0(t),...!1===e.includeTraceContinuity?[]:B0(t),...s,...a,...c],d=t.filter(t=\u003e\"pcb_via\"===t.type),h=new Map(d.map(t=\u003e[t.pcb_via_id,t])),u=l.map(t=\u003e{if(\"pcb_via_trace_clearance_error\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id){const e=h.get(t.pcb_via_id);if(e)return{...t,center:{x:e.x,y:e.y}}}if(\"center\"in t\u0026\u0026t.center)return t;if(\"pcb_center\"in t\u0026\u0026t.pcb_center)return{...t,center:t.pcb_center};if(\"pcb_via_ids\"in t\u0026\u0026Array.isArray(t.pcb_via_ids)){const[e,n]=t.pcb_via_ids,o=h.get(e),i=h.get(n);if(o\u0026\u0026i)return{...t,center:{x:(o.x+i.x)/2,y:(o.y+i.y)/2}}}if(\"pcb_error_id\"in t\u0026\u0026\"string\"==typeof t.pcb_error_id\u0026\u0026(t.pcb_error_id.startsWith(\"same_net_vias_close_\")||t.pcb_error_id.startsWith(\"different_net_vias_close_\"))){const e=t.pcb_error_id.replace(\"same_net_vias_close_\",\"\").replace(\"different_net_vias_close_\",\"\").split(\"_\").filter(Boolean);if(2===e.length){const n=h.get(e[0]),o=h.get(e[1]);if(n\u0026\u0026o)return{...t,center:{x:(n.x+o.x)/2,y:(n.y+o.y)/2}}}}return t}),p=u.filter(t=\u003eBoolean(t.center));return{errors:l,errorsWithCenters:u,locationAwareErrors:p}},V0={traceClearance:.1,viaClearance:.1};var W0=t=\u003et.circuitJsonMetadata??{},H0=({connections:t,obstacles:e})=\u003enew Set([...t.flatMap(t=\u003et.pointsToConnect.flatMap(t=\u003et.pcb_port_id?[t.pcb_port_id]:[])),...e.flatMap(t=\u003e{const e=W0(t).pcb_port_id;return e?[e]:[]})]),G0=t=\u003et.__netConnectionName??t.__rootConnectionNames?.[0]??t.name,U0=t=\u003eArray.from(new Set([t.name,t.__netConnectionName,...t.__rootConnectionNames??[],...t.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])])).filter(t=\u003eBoolean(t)),Z0=(t,e)=\u003e{const n=new Map,o=new Set,i=new Map;for(const r of t){const t=G0(r);for(const e of U0(r)){const i=n.get(e);i\u0026\u0026i!==t?(n.delete(e),o.add(e)):o.has(e)||n.set(e,t)}const s=e.getNetConnectedToId(r.name);if(!s)continue;const a=s,c=i.get(a)??new Set;c.add(t),i.set(a,c)}return{connMap:e,circuitJsonSourceTraceIdBySrjDeclaredConnectionReference:n,circuitJsonSourceTraceIdsByConnectivityNetId:i}},q0=(t,e)=\u003e{const n=t.circuitJsonSourceTraceIdBySrjDeclaredConnectionReference.get(e);if(n)return n;const o=t.connMap.getNetConnectedToId(e);if(!o)return;const i=t.circuitJsonSourceTraceIdsByConnectivityNetId.get(o);return 1===i?.size?i.values().next().value:void 0};function J0(t,e,n=t){const o=[],i=n===t?t.connections:[...t.connections,...n.connections],r=n===t?t.obstacles:n.obstacles,s=Z0(i,ii(n===t?t:{...n,connections:i})),a=H0({connections:i,obstacles:r});if(i.forEach(t=\u003e{const n=t.pointsToConnect.map(t=\u003et.pcb_port_id).filter(t=\u003eBoolean(t)),i=new Set(n),a=t=\u003e(t=\u003eArray.from(new Set(t.flatMap(t=\u003et.connectedTo))))(t).filter(t=\u003e!i.has(t)),c=t.pointsToConnect.map(t=\u003et.pointId).filter(t=\u003eBoolean(t)),l=q0(s,t.name)??G0(t),d=[],h=e.find(e=\u003e(e.connection_name??e.connectionName)===t.name);if(h){const t=t=\u003e\"route_type\"in t\u0026\u0026\"jumper\"===t.route_type?t.start:\"x\"in t\u0026\u0026\"y\"in t?{x:t.x,y:t.y}:{x:0,y:0},e=[t(h.route[0]),t(h.route[h.route.length-1])];for(const t of e)for(const e of r)Be(t,e)\u003c=0\u0026\u0026d.push(e)}const u=o.find(t=\u003e\"source_trace\"===t.type\u0026\u0026t.source_trace_id===l);if(u){const t=u;t.connected_source_port_ids=[...new Set([...t.connected_source_port_ids,...n])],t.connected_source_net_ids=[...new Set([...t.connected_source_net_ids??[],...c,...a(d)])]}else o.push({type:\"source_trace\",source_trace_id:l,connected_source_port_ids:n,connected_source_net_ids:a(d).concat(c)})}),e[0]\u0026\u0026\"type\"in e[0]){const t=new Map(i.map(t=\u003e[t.name,t]));for(const n of e){const e=[...new Set((n.connectsTo??[]).filter(t=\u003ea.has(t)))],i=new Set(e),r=[...new Set((n.connectsTo??[]).filter(t=\u003e!i.has(t)))];if(0===e.length\u0026\u00260===r.length)continue;const c=t.get(n.connection_name),l=q0(s,n.connection_name)??n.connectsTo?.map(t=\u003eq0(s,t)).find(t=\u003evoid 0!==t)??(c?G0(c):n.connection_name),d=o.find(t=\u003e\"source_trace\"===t.type\u0026\u0026t.source_trace_id===l);\"source_trace\"!==d?.type?o.push({type:\"source_trace\",source_trace_id:l,connected_source_port_ids:e,connected_source_net_ids:r}):(d.connected_source_port_ids=[...new Set([...d.connected_source_port_ids,...e])],d.connected_source_net_ids=[...new Set([...d.connected_source_net_ids??[],...r])])}}return o}function K0(t,e,n){let o,i=Number.POSITIVE_INFINITY;for(const r of e){const e=n.get(r);if(!e)continue;const s=Math.hypot(e.x-t.x,e.y-t.y);s\u003ci\u0026\u0026(i=s,o=r)}return o??e[0]}var Q0=new Set([\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\",\"inner7\",\"inner8\"]),t1=t=\u003eQ0.has(t);function e1(t){const e=[],n=new Set,o=new Set,i=function(t){const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{x:t.x,y:t.y});return e}(t),r=H0(t);for(const s of t.obstacles){const t=s.connectedTo,a=W0(s);if(a.pcb_via_id)continue;const c=a.pcb_smtpad_id,l=a.pcb_plated_hole_id,d=[...new Set([...a.pcb_port_id?[a.pcb_port_id]:[],...t.filter(t=\u003er.has(t))])],h=K0(s.center,d,i);if(!c\u0026\u0026!l\u0026\u0026!h)continue;const u=s.layers.filter(t1);if(0===u.length)continue;const p=s.width,m=s.height,g=s.center.x,f=s.center.y,y=s.ccwRotationDegrees;if(Boolean(l)||u.length\u003e1){const t=l??`pcb_plated_hole_${g.toFixed(3)}_${f.toFixed(3)}`;if(o.has(t))continue;if(o.add(t),\"number\"==typeof y\u0026\u0026Number.isFinite(y)){const n=Math.max(.5*Math.min(p,m),.1);e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"rotated_pill_hole_with_rect_pad\",hole_shape:\"rotated_pill\",pad_shape:\"rect\",hole_width:n,hole_height:n,hole_ccw_rotation:y,rect_pad_width:p,rect_pad_height:m,rect_ccw_rotation:y,hole_offset_x:0,hole_offset_y:0,x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}if(Math.abs(p-m)\u003c.001){e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circle\",outer_diameter:Math.max(p,m),hole_diameter:Math.max(.5*Math.min(p,m),.1),x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}e.push({type:\"pcb_plated_hole\",pcb_plated_hole_id:t,shape:\"circular_hole_with_rect_pad\",hole_shape:\"circle\",hole_diameter:Math.max(.5*Math.min(p,m),.1),rect_pad_width:p,rect_pad_height:m,hole_offset_x:0,hole_offset_y:0,x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}const _=c??`pcb_smtpad_${g.toFixed(3)}_${f.toFixed(3)}`;n.has(_)||(n.add(_),\"number\"==typeof y\u0026\u0026Number.isFinite(y)?e.push({type:\"pcb_smtpad\",pcb_smtpad_id:_,layer:u[0],shape:\"rotated_rect\",x:g,y:f,width:p,height:m,ccw_rotation:y,...h?{pcb_port_id:h}:{}}):e.push({type:\"pcb_smtpad\",pcb_smtpad_id:_,layer:u[0],shape:\"rect\",width:p,height:m,x:g,y:f,...h?{pcb_port_id:h}:{}}))}return e}function n1(t,e,n={}){const{minTraceWidth:o=.1,minViaDiameter:i,minViaHoleDiameter:r,originalSrj:s,includeOriginalConnections:a=!1}=n,c=Yo(t),l=i??c.padDiameter,d=t.min_via_hole_diameter??t.minViaHoleDiameter,h=r??d??(void 0!==i?.5*l:c.holeDiameter),u=[];u.push(...J0(t,e,a\u0026\u0026s?s:t)),u.push(...function(t){const e=new Map;return t.connections.forEach(t=\u003e{t.pointsToConnect.forEach(t=\u003e{t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,{type:\"pcb_port\",pcb_port_id:t.pcb_port_id,source_port_id:t.pcb_port_id,x:t.x,y:t.y,layers:xo(t)})})}),Array.from(e.values())}(a\u0026\u0026s?s:t)),u.push(...e1(s??t)),u.push(...function(t,e,n=.3,o=.5*n){const i=[],r=new Set;return t.length\u003e0\u0026\u0026(\"type\"in t[0]\u0026\u0026\"pcb_trace\"===t[0].type?t.forEach(t=\u003e{t.route.forEach(s=\u003e{if(\"via\"===s.route_type){if(!t1(s.from_layer)||!t1(s.to_layer))return;const a=s.via_diameter??n,c=s.via_hole_diameter??o,l=`${s.x},${s.y},${s.from_layer},${s.to_layer}`;r.has(l)||(i.push({type:\"pcb_via\",pcb_via_id:`via_${i.length}`,pcb_trace_id:t.pcb_trace_id,x:s.x,y:s.y,outer_diameter:a,hole_diameter:c,layers:Wy(s,e)}),r.add(l))}})}):t.forEach((t,s)=\u003e{const a=`trace_${s}`,c=t.viaDiameter??n,l=o;for(let n=1;n\u003ct.route.length;n++){const o=t.route[n-1],s=t.route[n];if(o.z!==s.z\u0026\u0026Math.abs(o.x-s.x)\u003c.01\u0026\u0026Math.abs(o.y-s.y)\u003c.01){const t=vo(o.z,e),n=vo(s.z,e),d=`${s.x},${s.y},${t},${n}`;r.has(d)||(i.push({type:\"pcb_via\",pcb_via_id:`via_${i.length}`,pcb_trace_id:a,x:s.x,y:s.y,outer_diameter:c,hole_diameter:l,layers:Wy({from_layer:t,to_layer:n},e)}),r.add(d))}}})),i}(e,t.layerCount,l,h));const p=Z0(t.connections,ii(t));return e.length\u003e0\u0026\u0026(\"type\"in e[0]\u0026\u0026\"pcb_trace\"===e[0].type?e.forEach(t=\u003e{const e=q0(p,t.connection_name)??t.connectsTo?.map(t=\u003eq0(p,t)).find(t=\u003eBoolean(t))??t.connection_name;u.push(function(t,e){return{type:\"pcb_trace\",pcb_trace_id:t.pcb_trace_id,source_trace_id:e,route:t.route.map(t=\u003e{if(\"wire\"===t.route_type){if(!t1(t.layer))return null;const e=\"start_pcb_port_id\"in t\u0026\u0026\"string\"==typeof t.start_pcb_port_id?t.start_pcb_port_id:void 0,n=\"end_pcb_port_id\"in t\u0026\u0026\"string\"==typeof t.end_pcb_port_id?t.end_pcb_port_id:void 0;return{route_type:\"wire\",x:t.x,y:t.y,width:t.width,layer:t.layer,...e?{start_pcb_port_id:e}:{},...n?{end_pcb_port_id:n}:{}}}return\"via\"===t.route_type\u0026\u0026t1(t.from_layer)\u0026\u0026t1(t.to_layer)?{route_type:\"via\",x:t.x,y:t.y,from_layer:t.from_layer,to_layer:t.to_layer}:null}).filter(t=\u003enull!==t)}}(t,e))}):e.forEach((e,n)=\u003e{const i=function(t,e,n,o,i=.1){const r=[];if(!t.jumpers||0===t.jumpers.length)return[{type:\"pcb_trace\",pcb_trace_id:e,source_trace_id:n,route:t.route.map((e,n)=\u003e{const r=0===n,s=n===t.route.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:e.traceThickness??i,layer:vo(e.z,o),...r\u0026\u0026e.pcb_port_id?{start_pcb_port_id:e.pcb_port_id}:{},...s\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})}];const s=[];for(const e of t.jumpers){let n=-1,o=-1;for(let i=0;i\u003ct.route.length;i++){const r=t.route[i];Math.abs(r.x-e.start.x)\u003c.01\u0026\u0026Math.abs(r.y-e.start.y)\u003c.01\u0026\u0026(n=i),Math.abs(r.x-e.end.x)\u003c.01\u0026\u0026Math.abs(r.y-e.end.y)\u003c.01\u0026\u0026(o=i)}-1!==n\u0026\u0026-1!==o\u0026\u0026(n\u003eo\u0026\u0026([n,o]=[o,n]),s.push({startIdx:n,endIdx:o}))}s.sort((t,e)=\u003et.startIdx-e.startIdx);let a=0,c=0;for(const{startIdx:l,endIdx:d}of s){if(l\u003e=a){const s=t.route.slice(a,l+1);s.length\u003e0\u0026\u0026(r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((t,e)=\u003e{const n=0===e\u0026\u00260===a;return{route_type:\"wire\",x:t.x,y:t.y,width:t.traceThickness??i,layer:vo(t.z,o),...n\u0026\u0026t.pcb_port_id?{start_pcb_port_id:t.pcb_port_id}:{}}})}),c++)}a=d}if(a\u003ct.route.length){const s=t.route.slice(a);if(s.length\u003e0){const t=!0;r.push({type:\"pcb_trace\",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((e,n)=\u003e{const r=t\u0026\u0026n===s.length-1;return{route_type:\"wire\",x:e.x,y:e.y,width:e.traceThickness??i,layer:vo(e.z,o),...r\u0026\u0026e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})})}}return r}(e,`trace_${n}`,q0(p,e.connectionName)??e.connectionName,t.layerCount,o);u.push(...i)})),u}var o1=(t,e)=\u003e{const n=new Set(e.flatMap(t=\u003et.__replaces_pcb_trace_id?[t.__replaces_pcb_trace_id]:[]));return[...t.filter(t=\u003e!n.has(t.pcb_trace_id)),...e]},i1=({inputSrj:t,srjWithPointPairs:e,routedTraces:n,drcOptions:o})=\u003e{const i=t.traces??[],r=n1(e,o1(i,n),{minTraceWidth:t.minTraceWidth,minViaDiameter:t.minViaDiameter,originalSrj:t,includeOriginalConnections:!0});return{circuitJson:r,...X0(r,{...V0,...o})}},r1=(t,e)=\u003e{const n=t({hdRoutes:e,traces:[]});return Array.isArray(n)?n:n.errorsWithCenters??n.errors},s1=t=\u003e{const e=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,n=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],o=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids:[]].filter(t=\u003e\"string\"==typeof t),i=e?`overlap_${e}_`:void 0,r=i\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0;if(n.length\u003e0){const t=e\u0026\u0026!n.includes(e)?[e,...n]:[...n];return t.length\u003c2\u0026\u0026r\u0026\u0026!o.includes(r)\u0026\u0026t.push(r),t}return[e,r].filter(t=\u003e\"string\"==typeof t\u0026\u0026!o.includes(t))},a1=t=\u003es1(t).filter((t,e,n)=\u003en.indexOf(t)===e),c1=t=\u003et.reduce((t,e)=\u003e{if(\"number\"==typeof e.actual_clearance\u0026\u0026\"number\"==typeof e.minimum_clearance)return t+Math.max(0,e.minimum_clearance-e.actual_clearance);const n=(\"string\"==typeof e.message?e.message:\"\").match(/gap: (-?\\d+(?:\\.\\d+)?)mm/);return n?t+Math.max(0,.1-Number.parseFloat(n[1])):t+1},0),l1=(t,e)=\u003et.length\u003ce.length||t.length===e.length\u0026\u0026c1(t)\u003cc1(e)-1e-9,d1=({routes:t,newConnections:e,syntheticConnectionNames:n})=\u003e{const o=new Set([...e.map(t=\u003et.name),...n]),i=new Map,r=new Map;for(let e=0;e\u003ct.length;e++){const n=t[e];if(!o.has(n.connectionName))continue;const s=i.get(n.connectionName)??0;i.set(n.connectionName,s+1),r.set(`${n.connectionName}_${s}`,e)}return r},h1=[.03,.1,.25],u1=t=\u003e{let e=0;for(const n of t){if(\"number\"!=typeof n.actual_clearance||!Number.isFinite(n.actual_clearance)||\"number\"!=typeof n.minimum_clearance||!Number.isFinite(n.minimum_clearance))return;if(e+=Math.max(0,n.minimum_clearance-n.actual_clearance),!Number.isFinite(e))return}return e},p1=({errors:t,errorsWithCenters:e,routeIndexByTraceId:n,padPositionById:o})=\u003e{const i=[];let r=0;for(const s of t){const t=\"pcb_via_trace_clearance_error\"===s.type,a=\"pcb_pad_trace_clearance_error\"===s.type;if(!t\u0026\u0026!a||\"string\"!=typeof s.pcb_trace_id||!n.has(s.pcb_trace_id)||\"number\"!=typeof s.actual_clearance||!Number.isFinite(s.actual_clearance)||\"number\"!=typeof s.minimum_clearance||!Number.isFinite(s.minimum_clearance))return;const c=a1(s);if(t\u0026\u0026c.length\u003c2||c.some(t=\u003e!n.has(t)))return;const l=e.find(t=\u003et.type===s.type\u0026\u0026t.pcb_trace_id===s.pcb_trace_id\u0026\u0026t.pcb_pad_id===s.pcb_pad_id\u0026\u0026t.pcb_via_id===s.pcb_via_id),d=a?\"string\"==typeof s.pcb_pad_id?o.get(s.pcb_pad_id):void 0:l?.center??s.center;if(!d||\"object\"!=typeof d)return;if(!(\"x\"in d\u0026\u0026\"y\"in d\u0026\u0026\"number\"==typeof d.x\u0026\u0026Number.isFinite(d.x)\u0026\u0026\"number\"==typeof d.y\u0026\u0026Number.isFinite(d.y)))return;const h={...s,pcb_trace_id:s.pcb_trace_id,actual_clearance:s.actual_clearance,minimum_clearance:s.minimum_clearance,center:{x:d.x,y:d.y}};if(t){if(\"string\"!=typeof s.pcb_via_id)return;i.push({...h,type:\"pcb_via_trace_clearance_error\",pcb_via_id:s.pcb_via_id,pcb_pad_id:void 0})}else{if(\"string\"!=typeof s.pcb_pad_id)return;i.push({...h,type:\"pcb_pad_trace_clearance_error\",pcb_pad_id:s.pcb_pad_id,pcb_via_id:void 0})}if(r+=Math.max(0,s.minimum_clearance-s.actual_clearance),!Number.isFinite(r))return}return{errors:i,deficit:r}},m1=(t,e)=\u003e{const n=[];for(let o=0;o\u003ct.route.length;o+=1){const i=t.route[o];if(\"via\"!==i.route_type){n.push(structuredClone(i));continue}const r=n[n.length-1],s=t.route[o+1],a=\"wire\"===r?.route_type?r.width:\"wire\"===s?.route_type?s.width:e,c=\"wire\"===s?.route_type?s.width:a;\"wire\"===r?.route_type\u0026\u0026r.x===i.x\u0026\u0026r.y===i.y\u0026\u0026r.layer===i.from_layer||n.push({route_type:\"wire\",x:i.x,y:i.y,layer:i.from_layer,width:a}),n.push(structuredClone(i)),\"wire\"===s?.route_type\u0026\u0026s.x===i.x\u0026\u0026s.y===i.y\u0026\u0026s.layer===i.to_layer||n.push({route_type:\"wire\",x:i.x,y:i.y,layer:i.to_layer,width:c})}return{...structuredClone(t),route:n}};function g1(t){const{srj:e,routes:n,routeIndex:o,start:i,end:r,bounds:s,traceThickness:a}=t;if(void 0!==t.maxNodes\u0026\u0026(!Number.isSafeInteger(t.maxNodes)||t.maxNodes\u003c1))throw new Error(\"repair04: maxNodes must be a positive safe integer\");if(t.stats\u0026\u0026(t.stats.nodesPopped=0,t.stats.completionReason=\"no-path\"),!1===t.allowLayerChanges\u0026\u0026i.z!==r.z)return null;const c=n[o],l=new Map,d=t=\u003e{const e=l.get(t);if(void 0===e||e===t)return t;const n=d(e);return l.set(t,n),n},h=t=\u003e{const e=t.filter(t=\u003eBoolean(t));if(!e.length)return;const n=d(e[0]);for(const t of e)l.set(d(t),n)};for(const t of e.connections){const e=t;h([e.name,e.rootConnectionName,e.netConnectionName,e.__netConnectionName,...e.mergedConnectionNames??[],...e.__rootConnectionNames??[],...e.pointsToConnect.flatMap(t=\u003e[t.pcb_port_id,t.pointId])])}for(const t of e.obstacles)h(t.connectedTo);for(const t of n)h([t.connectionName,t.rootConnectionName]);const u=d(c.connectionName),p=t=\u003e\"top\"===t?0:\"bottom\"===t?e.layerCount-1:Number(t.slice(5)),m=[s.minX,s.maxX,s.minY,s.maxY,i.x,i.y,r.x,r.y,a,c.viaDiameter,t.traceClearance,t.viaClearance,e.defaultObstacleMargin??0,e.minTraceToPadEdgeClearance??0,e.minViaEdgeToPadEdgeClearance??0].every(t=\u003eNumber.isFinite(t)\u0026\u0026Math.abs(t)\u003c=1e4),g=[],f=(t,e,n,o,i=!1)=\u003e{const r=o?Math.hypot(o.width,o.height)/2:n,s=o?Math.cos(o.rotation):1,a=o?Math.sin(o.rotation):0,c={minX:Math.min(t.x,e.x)-r,maxX:Math.max(t.x,e.x)+r,minY:Math.min(t.y,e.y)-r,maxY:Math.max(t.y,e.y)+r},l=o\u0026\u0026m?((t,e,n,o,i,r)=\u003e{if(t.x!==e.x||t.y!==e.y||!Number.isFinite(n.rotation)||n.width\u003c=0||n.height\u003c=0||![t.x,t.y,n.width,n.height,r.minX,r.maxX,r.minY,r.maxY].every(t=\u003eNumber.isFinite(t)\u0026\u0026Math.abs(t)\u003c=1e4))return r;const s=o*o+i*i;if(!Number.isFinite(s)||Math.abs(s-1)\u003e1e-12)return r;const a=n.width/2,c=n.height/2,l=(Math.abs(o)*a+Math.abs(i)*c)/s+1e-8,d=(Math.abs(i)*a+Math.abs(o)*c)/s+1e-8,h={minX:t.x-l,maxX:t.x+l,minY:t.y-d,maxY:t.y+d};return h.minX\u003cr.minX||h.maxX\u003er.maxX||h.minY\u003cr.minY||h.maxY\u003er.maxY?r:h})(t,e,o,s,a,c):c;g.push({a:t,b:e,radius:n,rect:o,viaOnly:i,rectCos:s,rectSin:a,rectBounds:o?{minX:-o.width/2,maxX:o.width/2,minY:-o.height/2,maxY:o.height/2}:void 0,visitedQuery:0,...l,minZ:Math.min(t.z,e.z),maxZ:Math.max(t.z,e.z)})};for(const t of e.obstacles){const e=t.connectedTo.some(t=\u003ed(t)===u),n=t.__zLayers??t.zLayers??t.layers.map(p);for(const o of n)f({...t.center,z:o},{...t.center,z:o},0,{width:t.width,height:t.height,rotation:(t.ccwRotationDegrees??0)*Math.PI/180},e)}for(const t of n)if(d(t.connectionName)!==u)for(let e=1;e\u003ct.route.length;e++){const n=t.route[e-1],o=t.route[e];\"through_obstacle\"!==n.toNextSegmentType\u0026\u0026f(n,o,n.z!==o.z?t.viaDiameter/2:Math.max(n.traceThickness??t.traceThickness,o.traceThickness??t.traceThickness)/2)}for(const t of e.traces??[]){if(d(t.connection_name)===u)continue;const n=m1(t,e.minTraceWidth);for(let t=1;t\u003cn.route.length;t++){const e=n.route[t-1],o=n.route[t];\"wire\"===e.route_type\u0026\u0026\"wire\"===o.route_type\u0026\u0026e.layer===o.layer\u0026\u0026f({x:e.x,y:e.y,z:p(e.layer)},{x:o.x,y:o.y,z:p(o.layer)},Math.max(e.width,o.width)/2),\"via\"===o.route_type\u0026\u0026f({x:o.x,y:o.y,z:p(o.from_layer)},{x:o.x,y:o.y,z:p(o.to_layer)},(o.via_diameter??c.viaDiameter)/2)}}const y=new Map,_=Math.max(c.viaDiameter,a)/2+Math.max(t.traceClearance,t.viaClearance,e.defaultObstacleMargin??0,e.minTraceToPadEdgeClearance??0,e.minViaEdgeToPadEdgeClearance??0)+1e-5;for(const t of g)for(let e=Math.floor(Math.max(t.minX,s.minX-_));e\u003c=Math.floor(Math.min(t.maxX,s.maxX+_));e++){let n=y.get(e);for(let o=Math.floor(Math.max(t.minY,s.minY-_));o\u003c=Math.floor(Math.min(t.maxY,s.maxY+_));o++){n||(n=new Map,y.set(e,n));const i=n.get(o);i?i.push(t):n.set(o,[t])}}let b=0;const x={x:0,y:0},v={x:0,y:0},S=(n,o)=\u003e{const i=n.z!==o.z,r=i?c.viaDiameter/2:a/2,s=Math.max(i?t.viaClearance:t.traceClearance,e.defaultObstacleMargin??0,i?e.minViaEdgeToPadEdgeClearance??0:e.minTraceToPadEdgeClearance??0),l=r+s+1e-5,d=++b,h=Math.min(n.x,o.x),u=Math.max(n.x,o.x),p=Math.min(n.y,o.y),m=Math.max(n.y,o.y),g=Math.min(n.z,o.z),f=Math.max(n.z,o.z);for(let e=Math.floor(h-l);e\u003c=Math.floor(u+l);e++){const a=y.get(e);if(a)for(let e=Math.floor(p-l);e\u003c=Math.floor(m+l);e++){const c=a.get(e);if(c)for(const e of c){if(e.viaOnly\u0026\u0026!i)continue;if(e.visitedQuery===d)continue;if(e.visitedQuery=d,e.maxZ\u003cg||e.minZ\u003ef)continue;const a=r+(e.rect?s:i\u0026\u0026e.minZ!==e.maxZ?t.viaClearance:t.traceClearance)+1e-5;if(u+a\u003ce.minX||h-a\u003ee.maxX||m+a\u003ce.minY||p-a\u003ee.maxY)continue;let c;if(e.rect?(x.x=(n.x-e.a.x)*e.rectCos+(n.y-e.a.y)*e.rectSin,x.y=-(n.x-e.a.x)*e.rectSin+(n.y-e.a.y)*e.rectCos,v.x=(o.x-e.a.x)*e.rectCos+(o.y-e.a.y)*e.rectSin,v.y=-(o.x-e.a.x)*e.rectSin+(o.y-e.a.y)*e.rectCos,c=ke(x,v,e.rectBounds)):c=Oe(n,o,e.a,e.b)-e.radius,c\u003ca)return!1}}}return!0};if(!S(i,i)||!S(r,r))return null;const I=t.gridSize??.1;if(!Number.isFinite(I)||I\u003c=0)throw new Error(\"repair04: clearance grid size must be positive and finite\");const C=Math.floor((s.maxX-s.minX)/I),P=Math.floor((s.maxY-s.minY)/I),M=t=\u003e({x:s.minX+(t%C+.5)*I,y:s.minY+(Math.floor(t/C)%P+.5)*I,z:Math.floor(t/(C*P)),traceThickness:a}),N=(t,e,n)=\u003e(n*P+e)*C+t,w=t=\u003eMath.hypot(t.x-r.x,t.y-r.y)+(t.z===r.z?0:1),T=[],R=t=\u003e{T.push(t);let e=T.length-1;for(;e\u003e0;){const n=Math.floor((e-1)/2);if(T[n].priority\u003c=t.priority)break;T[e]=T[n],e=n}T[e]=t},E=()=\u003e{const t=T[0],e=T.pop();if(T.length){let t=0;for(;2*t+1\u003cT.length;){let n=2*t+1;if(n+1\u003cT.length\u0026\u0026T[n+1].priority\u003cT[n].priority\u0026\u0026n++,T[n].priority\u003e=e.priority)break;T[t]=T[n],t=n}T[t]=e}return t},A=new Map,O=new Map,k=(z=i,N(Math.max(0,Math.min(C-1,Math.floor((z.x-s.minX)/I))),Math.max(0,Math.min(P-1,Math.floor((z.y-s.minY)/I))),z.z)),L=k%C,D=Math.floor(k/C)%P;var z;for(let t=-2;t\u003c=2;t++)for(let e=-2;e\u003c=2;e++){const n=L+t,o=D+e;if(n\u003c0||n\u003e=C||o\u003c0||o\u003e=P)continue;const r=N(n,o,i.z),s=M(r);if(!S(i,s))continue;const a=Math.hypot(s.x-i.x,s.y-i.y);A.set(r,a),O.set(r,-1),R({id:r,cost:a,priority:a+w(s)})}const F=C*P*e.layerCount,B=C\u003e0\u0026\u0026P\u003e0\u0026\u0026Number.isSafeInteger(e.layerCount)\u0026\u0026Number.isSafeInteger(F)\u0026\u0026F\u003e0\u0026\u0026Number.isSafeInteger(F*F-1)\u0026\u0026Number.isInteger(i.z)\u0026\u0026i.z\u003e=0\u0026\u0026i.z\u003ce.layerCount,j=new Map;let $=0;for(;T.length\u0026\u0026$\u003c(t.maxNodes??3e4);){const n=E();if($++,t.stats\u0026\u0026(t.stats.nodesPopped=$),n.cost!==A.get(n.id))continue;const o=M(n.id);if(o.z===r.z\u0026\u0026Math.hypot(o.x-r.x,o.y-r.y)\u003c3*I\u0026\u0026S(o,r)){const e=[r];for(let t=n.id;-1!==t;t=O.get(t))e.push(M(t));e.push(i);const o=e.reverse(),s=[i];for(let t=1;t\u003co.length;){let e=t;if(o[t].z===s.at(-1).z)for(let n=t+1;n\u003co.length\u0026\u0026o[n].z===o[t].z;n++)S(s.at(-1),o[n])\u0026\u0026(e=n);s.push(o[e]),t=e+1}return t.stats\u0026\u0026(t.stats.completionReason=\"found\"),s}const s=n.id%C,a=Math.floor(n.id/C)%P,c=[];for(let t=-1;t\u003c=1;t++)for(let e=-1;e\u003c=1;e++)0===t\u0026\u00260===e||s+t\u003c0||s+t\u003e=C||a+e\u003c0||a+e\u003e=P||c.push(N(s+t,a+e,o.z));if(!1!==t.allowLayerChanges)for(let t=0;t\u003ce.layerCount;t++)t!==o.z\u0026\u0026c.push(N(s,a,t));for(const t of c){const e=M(t),i=n.cost+(o.z===e.z?Math.hypot(o.x-e.x,o.y-e.y):1);if(i\u003e=(A.get(t)??1/0))continue;const r=Math.min(n.id,t),s=Math.max(n.id,t),a=B?r*F+s:`${r},${s}`;let c=j.get(a);void 0===c\u0026\u0026(c=S(o,e),j.set(a,c)),c\u0026\u0026(A.set(t,i),O.set(t,n.id),R({id:t,cost:i,priority:i+w(e)}))}}return t.stats\u0026\u0026(t.stats.completionReason=T.length?\"node-limit\":\"no-path\"),null}var f1=(t,e)=\u003e{if(!Number.isInteger(e)||e\u003c1)throw new Error(`Invalid board layer count: ${e}`);const n=Array.from({length:e},(t,n)=\u003e((t,e)=\u003e0===t?\"top\":t===e-1?\"bottom\":`inner${t}`)(n,e)),o=n.findIndex(e=\u003ee===t.from_layer),i=n.findIndex(e=\u003ee===t.to_layer);if(o\u003c0||i\u003c0)throw new Error(`Via span ${t.from_layer} -\u003e ${t.to_layer} is outside the board`);return n.slice(Math.min(o,i),Math.max(o,i)+1)},y1=.005,_1=1e-6,b1=(t,e)=\u003e({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),x1=t=\u003eb1({minX:Math.min(t.start.x,t.end.x),minY:Math.min(t.start.y,t.end.y),maxX:Math.max(t.start.x,t.end.x),maxY:Math.max(t.start.y,t.end.y)},t.width/2),v1=t=\u003e{const e=t.diameter/2;return{minX:t.x-e,minY:t.y-e,maxX:t.x+e,maxY:t.y+e}},S1=t=\u003e({minX:t.x-t.width/2,minY:t.y-t.height/2,maxX:t.x+t.width/2,maxY:t.y+t.height/2}),I1=(t,e)=\u003e`${t}:${e}`,C1=class{constructor(t){this.cellSize=t}cellSize;cells=new Map;insert(t,e){const n=Math.floor(e.minX/this.cellSize),o=Math.floor(e.maxX/this.cellSize),i=Math.floor(e.minY/this.cellSize),r=Math.floor(e.maxY/this.cellSize);for(let e=n;e\u003c=o;e+=1)for(let n=i;n\u003c=r;n+=1){const o=I1(e,n),i=this.cells.get(o);i?i.push(t):this.cells.set(o,[t])}}insertWithCellKeys(t,e){for(const n of e){const e=this.cells.get(n);e?e.push(t):this.cells.set(n,[t])}}getCellKeys(t){const e=Math.floor(t.minX/this.cellSize),n=Math.floor(t.maxX/this.cellSize),o=Math.floor(t.minY/this.cellSize),i=Math.floor(t.maxY/this.cellSize),r=[];for(let t=e;t\u003c=n;t+=1)for(let e=o;e\u003c=i;e+=1)r.push(I1(t,e));return r}queryWithCellKeys(t){const e=new Set;for(const n of t){const t=this.cells.get(n);if(t)for(const n of t)e.add(n)}return[...e]}queryWithCellKeysUsingOrder(t,e){const n=[];for(const o of t){const t=this.cells.get(o);if(t)for(const o of t)o.lastDynamicQueryOrder!==e\u0026\u0026(o.lastDynamicQueryOrder=e,n.push(o))}return n}query(t){const e=Math.floor(t.minX/this.cellSize),n=Math.floor(t.maxX/this.cellSize),o=Math.floor(t.minY/this.cellSize),i=Math.floor(t.maxY/this.cellSize),r=new Set;for(let t=e;t\u003c=n;t+=1)for(let e=o;e\u003c=i;e+=1){const n=this.cells.get(I1(t,e));if(n)for(const t of n)r.add(t)}return[...r]}},P1=(t,e)=\u003e{const n=ve(t.start,t.end,e.start,e.end);if(n)return n;const o=[{left:t.start,right:ze(t.start,e.start,e.end)},{left:t.end,right:ze(t.end,e.start,e.end)},{left:ze(e.start,t.start,t.end),right:e.start},{left:ze(e.end,t.start,t.end),right:e.end}];let i={left:t.start,right:e.start},r=Number.POSITIVE_INFINITY;for(const t of o){const e=Math.hypot(t.left.x-t.right.x,t.left.y-t.right.y);e\u003cr\u0026\u0026(i=t,r=e)}return{x:(i.left.x+i.right.x)/2,y:(i.left.y+i.right.y)/2}},M1=(t,e)=\u003e{const n=ze(e,t.start,t.end);return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}},N1=(t,e)=\u003e{const n=ze({x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},t.start,t.end),o=Math.max(e.minX,Math.min(e.maxX,n.x)),i=Math.max(e.minY,Math.min(e.maxY,n.y));return{x:(n.x+o)/2,y:(n.y+i)/2}},w1=t=\u003e{const e=new Set;for(const n of t.route)\"wire\"===n.route_type\u0026\u0026(n.start_pcb_port_id\u0026\u0026e.add(n.start_pcb_port_id),n.end_pcb_port_id\u0026\u0026e.add(n.end_pcb_port_id));return[...e]},T1=(t,e,n)=\u003en\u003c0?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,R1=class{constructor(t,e={}){if(this.srj=t,this.cacheImmutableTraceGeometry=e.cacheImmutableTraceGeometry??!1,this.useConservativeRectObstaclePrecheck=e.useConservativeRectObstaclePrecheck??!1,this.useTransientDynamicQueryMarkers=e.useTransientDynamicQueryMarkers??!1,this.traceClearance=e.traceClearance??.1,this.viaClearance=Math.max(e.viaClearance??.1,.1),this.viaToPadClearance=e.viaToPadClearance??this.srj.minViaEdgeToPadEdgeClearance??.1,this.connMap=e.connMap,this.includeTraceViaOwnerMetadata=e.includeTraceViaOwnerMetadata??!1,this.cellSize=e.spatialCellSize??this.getDefaultSpatialCellSize(),!Number.isFinite(this.traceClearance)||this.traceClearance\u003c0)throw new Error(\"traceClearance must be a non-negative finite number\");if(!Number.isFinite(this.viaClearance))throw new Error(\"viaClearance must be a finite number\");if(!Number.isFinite(this.viaToPadClearance)||this.viaToPadClearance\u003c0)throw new Error(\"viaToPadClearance must be a non-negative finite number\");if(!Number.isFinite(this.cellSize)||this.cellSize\u003c=0)throw new Error(\"spatialCellSize must be a positive finite number\");if(e.cacheStaticObstacleNetMembership\u0026\u0026this.connMap)throw new Error(\"cacheStaticObstacleNetMembership cannot be combined with connMap\");if(this.cacheImmutableTraceGeometry\u0026\u0026this.connMap)throw new Error(\"cacheImmutableTraceGeometry cannot be combined with connMap\");if(this.useTransientDynamicQueryMarkers\u0026\u0026!this.cacheImmutableTraceGeometry)throw new Error(\"useTransientDynamicQueryMarkers requires cacheImmutableTraceGeometry\");this.compileConnectionAliases(),this.obstacles=this.compileStaticObstacles(),e.cacheStaticObstacleNetMembership\u0026\u0026(this.staticObstacleNets=new Map(this.obstacles.map(t=\u003e[t,new Set(t.connectedTo.map(t=\u003ethis.resolveNetId(t)))]))),this.indexStaticObstacles()}srj;cacheImmutableTraceGeometry;useConservativeRectObstaclePrecheck;useTransientDynamicQueryMarkers;immutableTraceGeometry=new WeakMap;immutableDynamicCellKeys=new WeakMap;immutableDynamicQueryCellKeys=new WeakMap;immutableStaticCandidates=new WeakMap;immutableStaticClearance=new WeakMap;traceClearance;viaClearance;viaToPadClearance;cellSize;connMap;includeTraceViaOwnerMetadata;canonicalNetByAlias=new Map;connMapNetByCanonicalNet=new Map;obstacles;staticObstacleNets;obstacleIndexesByLayer=new Map;lastRunStats={traceCount:0,segmentCount:0,viaCount:0,obstacleCount:0,broadPhaseCandidateCount:0,exactCheckCount:0};getDefaultSpatialCellSize(){const t=Math.max(0,this.srj.bounds.maxX-this.srj.bounds.minX),e=Math.max(0,this.srj.bounds.maxY-this.srj.bounds.minY);return Math.max(.25,Math.max(t,e)/64,(this.srj.minViaDiameter??.3)+Math.max(this.traceClearance,this.viaToPadClearance))}compileConnectionAliases(){const t=new Map;for(const e of this.srj.connections){const n=e.netConnectionName??e.rootConnectionName??e.name,o=[e.name,e.rootConnectionName,e.netConnectionName,...e.mergedConnectionNames??[],...e.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])];for(const e of o){if(!e)continue;this.canonicalNetByAlias.set(e,n);const o=this.connMap?.getNetConnectedToId(e);if(!o)continue;let i=t.get(n);i||(i=new Set,t.set(n,i)),i.add(o)}this.canonicalNetByAlias.set(n,n)}for(const[e,n]of t)1===n.size\u0026\u0026this.connMapNetByCanonicalNet.set(e,n.values().next().value)}resolveNetId(t){const e=this.connMap?.getNetConnectedToId(t);if(e)return e;const n=this.canonicalNetByAlias.get(t);return n?this.connMapNetByCanonicalNet.get(n)??n:t}areConnected(t,e){return t===e||(!!this.connMap?.areIdsConnected(t,e)||this.resolveNetId(t)===this.resolveNetId(e))}compileStaticObstacles(){const t=[],e=new Set,n=new Set;for(const o of this.srj.obstacles){if(0===o.layers.length)continue;const i=o.connectedTo.find(t=\u003et.startsWith(\"pcb_smtpad_\")),r=o.connectedTo.find(t=\u003et.startsWith(\"pcb_plated_hole_\")),s=o.connectedTo.find(t=\u003et.startsWith(\"pcb_port_\"));if(!i\u0026\u0026!r\u0026\u0026!s)continue;const a=o.layers.length\u003e1,c=a?\"pcb_plated_hole\":\"pcb_smtpad\",l=a?r??`pcb_plated_hole_${o.center.x.toFixed(3)}_${o.center.y.toFixed(3)}`:i??`pcb_smtpad_${o.center.x.toFixed(3)}_${o.center.y.toFixed(3)}`,d=a?n:e;if(d.has(l))continue;d.add(l);const h=a\u0026\u0026Math.abs(o.width-o.height)\u003c.001;t.push({kind:\"obstacle\",obstacleType:c,obstacleId:l,connectedTo:o.connectedTo,x:o.center.x,y:o.center.y,width:o.width,height:o.height,...h?{radius:Math.max(o.width,o.height)/2}:{},layers:o.layers,...s?{pcbPortId:s}:{}})}return t}indexStaticObstacles(){for(const t of this.obstacles){const e=b1(S1(t),Math.max(this.traceClearance,this.viaToPadClearance));for(const n of t.layers){let o=this.obstacleIndexesByLayer.get(n);o||(o=new C1(this.cellSize),this.obstacleIndexesByLayer.set(n,o)),o.insert(t,e)}}}getImmutableTraceGeometry(t){const e=this.immutableTraceGeometry.get(t);if(e)return e;const n=this.resolveNetId(t.connection_name),o=w1(t),i=[];for(let e=0;e\u003ct.route.length-1;e++){const r=t.route[e],s=t.route[e+1];\"wire\"===r?.route_type\u0026\u0026\"wire\"===s?.route_type\u0026\u0026r.layer===s.layer\u0026\u0026(Math.abs(r.x-s.x)\u003c=_1\u0026\u0026Math.abs(r.y-s.y)\u003c=_1||i.push({geometryKey:{},kind:\"trace_segment\",traceId:t.pcb_trace_id,netId:n,start:{x:r.x,y:r.y},end:{x:s.x,y:s.y},width:E1(r,s),layer:r.layer,pcbPortIds:o}))}const r=[];for(const e of t.route)\"via\"===e.route_type\u0026\u0026r.push({locationKey:`${e.x},${e.y},${e.from_layer},${e.to_layer}`,point:e,geometryKey:{}});const s={segments:i,vias:r,traceId:t.pcb_trace_id,netId:n};return this.immutableTraceGeometry.set(t,s),s}collectImmutableDynamicGeometry(t){const e=[],n=[],o=new Set;for(const i of t){const t=this.getImmutableTraceGeometry(i);for(const n of t.segments)e.push({geometryKey:n.geometryKey,kind:\"trace_segment\",traceId:n.traceId,netId:n.netId,start:n.start,end:n.end,width:n.width,layer:n.layer,pcbPortIds:n.pcbPortIds,order:e.length});for(const e of t.vias){if(o.has(e.locationKey))continue;o.add(e.locationKey);const i=e.point,r=e.prepared??={geometryKey:e.geometryKey,kind:\"via\",traceId:t.traceId,netId:t.netId,x:i.x,y:i.y,diameter:i.via_diameter??this.srj.minViaDiameter??.3,layers:f1(i,this.srj.layerCount)};n.push({geometryKey:r.geometryKey,kind:\"via\",traceId:r.traceId,netId:r.netId,x:r.x,y:r.y,diameter:r.diameter,layers:r.layers,order:n.length,viaId:`via_${n.length}`})}}return{segments:e,vias:n}}collectDynamicGeometry(t){if(this.cacheImmutableTraceGeometry)return this.collectImmutableDynamicGeometry(t);const e=[],n=[],o=new Set;for(const i of t){const t=this.resolveNetId(i.connection_name),r=w1(i);for(let n=0;n\u003ci.route.length-1;n+=1){const o=i.route[n],s=i.route[n+1];\"wire\"===o?.route_type\u0026\u0026\"wire\"===s?.route_type\u0026\u0026o.layer===s.layer\u0026\u0026(Math.abs(o.x-s.x)\u003c=_1\u0026\u0026Math.abs(o.y-s.y)\u003c=_1||e.push({kind:\"trace_segment\",order:e.length,traceId:i.pcb_trace_id,netId:t,start:{x:o.x,y:o.y},end:{x:s.x,y:s.y},width:E1(o,s),layer:o.layer,pcbPortIds:r}))}for(const e of i.route){if(\"via\"!==e.route_type)continue;const r=`${e.x},${e.y},${e.from_layer},${e.to_layer}`;o.has(r)||(o.add(r),n.push({kind:\"via\",order:n.length,viaId:`via_${n.length}`,traceId:i.pcb_trace_id,netId:t,x:e.x,y:e.y,diameter:e.via_diameter??this.srj.minViaDiameter??.3,layers:f1(e,this.srj.layerCount)}))}}return{segments:e,vias:n}}getImmutableDynamicCellKeys(t,e){const n=t.geometryKey;if(!n)throw new Error(\"Immutable spatial cache requires private entity identities\");let o=this.immutableDynamicCellKeys.get(n);if(!o){const i=\"trace_segment\"===t.kind?x1(t):v1(t);o=e.getCellKeys(b1(i,this.traceClearance)),this.immutableDynamicCellKeys.set(n,o)}return o}getImmutableDynamicQueryCellKeys(t,e,n){const o=t.geometryKey;if(!o)throw new Error(\"Immutable spatial cache requires private entity identities\");let i=this.immutableDynamicQueryCellKeys.get(o);return i||(i=e.getCellKeys(n),this.immutableDynamicQueryCellKeys.set(o,i)),i}getStaticObstacleCandidates(t,e){const n=t.geometryKey;if(!n)throw new Error(\"Immutable spatial cache requires private entity identities\");let o=this.immutableStaticCandidates.get(n);o||(o=new Map,this.immutableStaticCandidates.set(n,o));let i=o.get(e);if(!i){const n=\"trace_segment\"===t.kind?x1(t):v1(t);i=this.obstacleIndexesByLayer.get(e)?.query(n)??[],o.set(e,i)}return i}buildImmutableDynamicIndexes(t,e){const n=new Map,o=(t,e)=\u003e{let o=n.get(t);o||(o=new C1(this.cellSize),n.set(t,o)),o.insertWithCellKeys(e,this.getImmutableDynamicCellKeys(e,o))};for(const e of t)o(e.layer,e);for(const t of e)for(const e of t.layers)o(e,t);return n}buildDynamicIndexes(t,e){if(this.cacheImmutableTraceGeometry)return this.buildImmutableDynamicIndexes(t,e);const n=new Map,o=(t,e,o)=\u003e{let i=n.get(t);i||(i=new C1(this.cellSize),n.set(t,i)),i.insert(e,b1(o,this.traceClearance))};for(const e of t)o(e.layer,e,x1(e));for(const t of e)for(const e of t.layers)o(e,t,v1(t));return n}obstacleSharesNet(t,e){return this.staticObstacleNets?this.staticObstacleNets.get(e).has(this.resolveNetId(t)):e.connectedTo.some(e=\u003ethis.areConnected(t,e))}checkTracePair(t,e){if(this.areConnected(t.netId,e.netId))return;this.lastRunStats.exactCheckCount+=1;const n=Oe(t.start,t.end,e.start,e.end)-t.width/2-e.width/2;if(n\u003ethis.traceClearance-y1)return;const o=`overlap_${t.traceId}_${e.traceId}`;return{type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:T1(t.traceId,`PCB trace ${e.traceId}`,n),pcb_trace_id:t.traceId,source_trace_id:\"\",pcb_trace_error_id:o,minimum_clearance:this.traceClearance,actual_clearance:n,pcb_component_ids:[],pcb_port_ids:[...new Set([...t.pcbPortIds,...e.pcbPortIds])],center:this.cacheImmutableTraceGeometry?{...P1(t,e)}:P1(t,e)}}checkTraceVia(t,e){if(this.areConnected(t.netId,e.netId))return;this.lastRunStats.exactCheckCount+=1;const n=De(t.start,t.end,{x:e.x,y:e.y,radius:e.diameter/2})-t.width/2;if(n\u003ethis.traceClearance-y1)return;const o=`overlap_${t.traceId}_${e.viaId}`;return{type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:T1(t.traceId,`pcb_via \"${e.viaId}\"`,n),pcb_trace_id:t.traceId,...this.includeTraceViaOwnerMetadata?{pcb_trace_ids:[t.traceId,e.traceId],pcb_via_id:e.viaId,pcb_via_ids:[e.viaId]}:{},source_trace_id:\"\",pcb_trace_error_id:o,minimum_clearance:this.traceClearance,actual_clearance:n,pcb_component_ids:[],pcb_port_ids:this.cacheImmutableTraceGeometry?[...t.pcbPortIds]:t.pcbPortIds,center:M1(t,e)}}checkTraceObstacle(t,e){if(this.obstacleSharesNet(t.netId,e))return;this.lastRunStats.exactCheckCount+=1;const n=S1(e);if(this.useConservativeRectObstaclePrecheck\u0026\u0026void 0===e.radius\u0026\u0026((t,e,n)=\u003e{const o=t.width/2+n-y1;return Math.max(e.minX-Math.max(t.start.x,t.end.x),Math.min(t.start.x,t.end.x)-e.maxX,e.minY-Math.max(t.start.y,t.end.y),Math.min(t.start.y,t.end.y)-e.maxY)\u003eo+1e-9\u0026\u0026e.minX\u003c=e.maxX\u0026\u0026e.minY\u003c=e.maxY\u0026\u0026Number.isFinite(o)\u0026\u0026Math.abs(t.start.x)\u003c=1e4\u0026\u0026Math.abs(t.start.y)\u003c=1e4\u0026\u0026Math.abs(t.end.x)\u003c=1e4\u0026\u0026Math.abs(t.end.y)\u003c=1e4\u0026\u0026Math.abs(e.minX)\u003c=1e4\u0026\u0026Math.abs(e.minY)\u003c=1e4\u0026\u0026Math.abs(e.maxX)\u003c=1e4\u0026\u0026Math.abs(e.maxY)\u003c=1e4})(t,n,this.traceClearance))return;const o=(void 0===e.radius?ke(t.start,t.end,n):De(t.start,t.end,{x:e.x,y:e.y,radius:e.radius}))-t.width/2;if(o+y1\u003e=this.traceClearance)return;const i=`overlap_${t.traceId}_${e.obstacleId}`;return{type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:T1(t.traceId,`${e.obstacleType} \"${e.obstacleId}\"`,o),pcb_trace_id:t.traceId,source_trace_id:\"\",pcb_trace_error_id:i,minimum_clearance:this.traceClearance,actual_clearance:o,pcb_component_ids:[],pcb_port_ids:[...new Set([...t.pcbPortIds,...e.pcbPortId?[e.pcbPortId]:[]])],center:void 0===e.radius?N1(t,n):M1(t,e)}}appendTraceObstacleErrors(t,e){const n=this.cacheImmutableTraceGeometry?t.geometryKey:void 0,o=n?this.immutableStaticClearance.get(n):void 0;if(o)return this.lastRunStats.broadPhaseCandidateCount+=o.broadPhaseCandidateCount,void(this.lastRunStats.exactCheckCount+=o.exactCheckCount);const i=this.cacheImmutableTraceGeometry?this.getStaticObstacleCandidates(t,t.layer):this.obstacleIndexesByLayer.get(t.layer)?.query(x1(t))??[],r=e.length,s=this.lastRunStats.exactCheckCount;for(const n of i){this.lastRunStats.broadPhaseCandidateCount+=1;const o=this.checkTraceObstacle(t,n);o\u0026\u0026e.push(o)}n\u0026\u0026e.length===r\u0026\u0026this.immutableStaticClearance.set(n,{broadPhaseCandidateCount:i.length,exactCheckCount:this.lastRunStats.exactCheckCount-s})}checkViaObstacle(t,e){if(this.obstacleSharesNet(t.netId,e))return;this.lastRunStats.exactCheckCount+=1;const n=S1(e),o=(void 0===e.radius?Math.hypot(Math.max(n.minX-t.x,0,t.x-n.maxX),Math.max(n.minY-t.y,0,t.y-n.maxY)):Math.hypot(t.x-e.x,t.y-e.y)-e.radius)-t.diameter/2;if(o+y1\u003e=this.viaToPadClearance)return;const i=`via_pad_clearance_${t.viaId}_${e.obstacleId}`,r={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return{type:\"pcb_pad_pad_clearance_error\",error_type:\"pcb_pad_pad_clearance_error\",pcb_pad_pad_clearance_error_id:i,message:`pcb_via \"${t.viaId}\" and ${e.obstacleType} \"${e.obstacleId}\" are too close (gap: ${o.toFixed(3)}mm)`,pcb_trace_id:t.traceId,pcb_pad_ids:[t.viaId,e.obstacleId],pcb_via_ids:[t.viaId],minimum_clearance:this.viaToPadClearance,actual_clearance:o,center:r}}checkViaPairs(t){if(t.length\u003c2)return[];const e=[],n=new C1(this.cellSize);for(const e of t)n.insert(e,b1(v1(e),this.viaClearance));for(const o of t)for(const t of n.query(v1(o))){if(this.lastRunStats.broadPhaseCandidateCount+=1,t.order\u003c=o.order)continue;this.lastRunStats.exactCheckCount+=1;const n=Math.hypot(o.x-t.x,o.y-t.y);if(n\u003c=_1)continue;const i=n-o.diameter/2-t.diameter/2;if(i+y1\u003e=this.viaClearance)continue;const r=this.areConnected(o.netId,t.netId),s=[o.viaId,t.viaId].sort().join(\"_\"),a={x:(o.x+t.x)/2,y:(o.y+t.y)/2};e.push({type:\"pcb_via_clearance_error\",error_type:\"pcb_via_clearance_error\",pcb_error_id:`${r?\"same_net\":\"different_net\"}_vias_close_${s}`,message:`Vias ${o.viaId} and ${t.viaId}${r?\"\":\" from different nets\"} are too close together (gap: ${i.toFixed(3)}mm)`,pcb_via_ids:[o.viaId,t.viaId],...this.includeTraceViaOwnerMetadata?{pcb_trace_ids:[o.traceId,t.traceId]}:{},pcb_via_pair_net_relation:r?\"same_net\":\"different_net\",minimum_clearance:this.viaClearance,actual_clearance:i,pcb_center:a,center:a})}return e}evaluate(t){return this.evaluateInternal(t,!0)}evaluateLegacy(t){return this.evaluateInternal(t,!1)}evaluateInternal(t,e){const{segments:n,vias:o}=this.collectDynamicGeometry(t),i=this.buildDynamicIndexes(n,o),r=[],s=[];this.lastRunStats={traceCount:t.length,segmentCount:n.length,viaCount:o.length,obstacleCount:this.obstacles.length,broadPhaseCandidateCount:0,exactCheckCount:0};for(const t of n){const e=x1(t),n=i.get(t.layer),o=n?this.cacheImmutableTraceGeometry?this.useTransientDynamicQueryMarkers?n.queryWithCellKeysUsingOrder(this.getImmutableDynamicQueryCellKeys(t,n,e),t.order):n.queryWithCellKeys(this.getImmutableDynamicQueryCellKeys(t,n,e)):n.query(e):[];for(const e of o){if(this.lastRunStats.broadPhaseCandidateCount+=1,\"trace_segment\"===e.kind\u0026\u0026e.order\u003c=t.order)continue;const n=\"trace_segment\"===e.kind?this.checkTracePair(t,e):this.checkTraceVia(t,e);n\u0026\u0026r.push(n)}this.appendTraceObstacleErrors(t,r)}const a=this.checkViaPairs(o);if(e)for(const t of o){const e=new Set;for(const n of t.layers){const o=this.cacheImmutableTraceGeometry?this.getStaticObstacleCandidates(t,n):this.obstacleIndexesByLayer.get(n)?.query(v1(t))??[];for(const n of o){if(e.has(n))continue;e.add(n),this.lastRunStats.broadPhaseCandidateCount+=1;const o=this.checkViaObstacle(t,n);o\u0026\u0026s.push(o)}}}const c=new Map;for(const t of r){const e=String(t.pcb_trace_error_id),n=c.get(e),o=Number(t.actual_clearance);if(!n){c.set(e,{...t,first_contact_center:t.center,first_contact_message:t.message,first_actual_clearance:o,worst_contact_center:t.center,worst_contact_message:t.message,worst_actual_clearance:o});continue}const i=Number(n.worst_actual_clearance);(o\u003ci||!Number.isFinite(i))\u0026\u0026(n.worst_contact_center=t.center,n.worst_contact_message=t.message,n.worst_actual_clearance=o)}const l=[...c.values()].map(t=\u003e({...t,center:\"object\"==typeof t.worst_contact_center?t.worst_contact_center:t.center,message:\"string\"==typeof t.worst_contact_message?t.worst_contact_message:t.message,actual_clearance:\"number\"==typeof t.worst_actual_clearance?t.worst_actual_clearance:t.actual_clearance}));l.push(...s),l.push(...a);const d=l.filter(t=\u003et.center);return{errors:l,errorsWithCenters:d,locationAwareErrors:d}}},E1=(t,e)=\u003et.width??e.width??.1,A1={Hz:{baseUnit:\"Hz\",variants:{MHz:1e6,kHz:1e3,Hz:1}},g:{baseUnit:\"g\",variants:{kg:1e3,g:1}},\"Ω\":{baseUnit:\"Ω\",variants:{\"mΩ\":.001,\"Ω\":1,\"kΩ\":1e3,\"KΩ\":1e3,kohm:1e3,\"MΩ\":1e6,\"GΩ\":1e9,\"TΩ\":1e12}},V:{baseUnit:\"V\",variants:{mV:.001,V:1,kV:1e3,KV:1e3,MV:1e6,GV:1e9,TV:1e12}},A:{baseUnit:\"A\",variants:{\"µA\":1e-6,mA:.001,ma:.001,A:1,kA:1e3,MA:1e6}},F:{baseUnit:\"F\",variants:{pF:1e-12,nF:1e-9,\"µF\":1e-6,uF:1e-6,mF:.001,F:1}},ml:{baseUnit:\"ml\",variants:{ml:1,mL:1,l:1e3,L:1e3}},deg:{baseUnit:\"deg\",variants:{rad:180/Math.PI}},ms:{baseUnit:\"ms\",variants:{fs:1e-12,ps:1e-9,ns:1e-6,us:.001,\"µs\":.001,ms:1,s:1e3}},mm:{baseUnit:\"mm\",variants:{nm:1e-6,\"µm\":.001,um:.001,mm:1,cm:10,dm:100,m:1e3,km:1e6,in:25.4,ft:304.8,IN:25.4,FT:304.8,yd:914.4,mi:1609344,mil:.0254}}},O1=new Set;for(const[t,e]of Object.entries(A1)){O1.add(t);for(const t of Object.keys(e.variants))O1.add(t)}var k1={tera:1e12,T:1e12,giga:1e9,G:1e9,mega:1e6,M:1e6,kilo:1e3,k:1e3,deci:.1,d:.1,centi:.01,c:.01,milli:.001,m:.001,micro:1e-6,u:1e-6,\"µ\":1e-6,nano:1e-9,n:1e-9,pico:1e-12,p:1e-12};function L1(t){if(null==t)return{parsedUnit:null,unitOfValue:null,value:null};if(\"string\"==typeof t\u0026\u0026t.match(/^-?[\\d\\.]+$/))return{value:Number.parseFloat(t),parsedUnit:null,unitOfValue:null};if(\"number\"==typeof t)return{value:t,parsedUnit:null,unitOfValue:null};if(\"object\"==typeof t\u0026\u0026\"x\"in t\u0026\u0026\"y\"in t){const{parsedUnit:e,unitOfValue:n}=L1(t.x),o=L1(t.x),i=L1(t.y);return null===o.value||null===i.value?{parsedUnit:null,unitOfValue:null,value:null}:{parsedUnit:e,unitOfValue:n,value:{x:o.value,y:i.value}}}const e=t.toString().split(\"\").reverse().join(\"\"),n=e.match(/[^\\d\\s]+/)?.[0];if(!n)throw new Error(`Could not determine unit: \"${t}\"`);const o=n.split(\"\").reverse().join(\"\"),i=t.slice(0,-o.length);if(o in k1\u0026\u0026!O1.has(o)){const t=k1[o];return{parsedUnit:null,unitOfValue:null,value:Number.parseFloat(i)*t}}const{baseUnit:r,conversionFactor:s}=function(t){for(const[e,n]of Object.entries(A1))if(t in n.variants)return{baseUnit:n.baseUnit,conversionFactor:n.variants[t]};return{baseUnit:t,conversionFactor:1}}(o);return{parsedUnit:o,unitOfValue:r,value:s*Number.parseFloat(i)}}var D1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),z1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value).transform(t=\u003eNumber.parseFloat(t.toPrecision(12))),F1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),B1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),j1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),$1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),Y1=j1,X1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),V1=k_.string().or(k_.number()).transform(t=\u003eL1(t).value),W1=V1,H1=k_.string().datetime(),G1=k_.string().or(k_.number()).transform(t=\u003e\"number\"==typeof t?t:t.endsWith(\"deg\")?Number.parseFloat(t.split(\"deg\")[0]):t.endsWith(\"rad\")?180*Number.parseFloat(t.split(\"rad\")[0])/Math.PI:Number.parseFloat(t)),U1=k_.number().or(k_.string().endsWith(\"mAh\")).transform(t=\u003e{if(\"string\"==typeof t){const e=t.replace(\"mAh\",\"\"),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error(\"Invalid capacity\");return n}return t}).describe(\"Battery capacity in mAh\"),Z1=k_.object({x:Y1,y:Y1}),q1=k_.object({x:Y1,y:Y1,z:Y1}),J1=k_.object({width:k_.number(),height:k_.number()}),K1=t=\u003ek_.string().optional().default(()=\u003e`${t}_${(t=\u003e{const e=\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";return Array.from({length:t},()=\u003ee[Math.floor(62*Math.random())]).join(\"\")})(10)}`),Q1=k_.enum([\"top_left\",\"top_center\",\"top_right\",\"center_left\",\"center\",\"center_right\",\"bottom_left\",\"bottom_center\",\"bottom_right\"]),t2=(k_.enum([\"top_silkscreen\",\"bottom_silkscreen\",\"top_copper\",\"bottom_copper\",\"top_soldermask\",\"bottom_soldermask\",\"top_fabrication_note\",\"bottom_fabrication_note\",\"top_user_note\",\"bottom_user_note\",\"top_courtyard\",\"bottom_courtyard\",\"inner1_copper\",\"inner2_copper\",\"inner3_copper\",\"inner4_copper\",\"inner5_copper\",\"inner6_copper\",\"edge_cuts\",\"drill\"]),k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()})),e2=Z1.extend({rotation:G1.optional()}),n2=k_.object({size:Z1.optional(),thickness:Y1.optional()}),o2=k_.object({font:n2.optional()}),i2=k_.object({value:k_.string(),at:e2.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:o2.optional()}),r2=k_.object({Reference:i2.optional(),Value:i2.optional(),Datasheet:i2.optional(),Description:i2.optional()}),s2=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),a2=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:e2.optional(),size:Z1.optional(),drill:Y1.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),c2=k_.object({path:k_.string(),offset:q1.optional(),scale:q1.optional(),rotate:q1.optional()}),l2=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:r2.optional(),attributes:s2.optional(),pads:k_.array(a2).optional(),embeddedFonts:k_.boolean().optional(),model:c2.optional()}),d2=k_.object({hide:k_.boolean().optional()}),h2=k_.object({offset:Y1.optional(),hide:k_.boolean().optional()}),u2=k_.object({font:n2.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),p2=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:e2.optional(),effects:u2.optional()}),m2=k_.object({Reference:p2.optional(),Value:p2.optional(),Footprint:p2.optional(),Datasheet:p2.optional(),Description:p2.optional(),ki_keywords:p2.optional(),ki_fp_filters:p2.optional()}),g2=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:d2.optional(),pinNames:h2.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:m2.optional(),embeddedFonts:k_.boolean().optional()}),f2=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),y2=k_.enum([\"jlcpcb\",\"macrofab\",\"pcbway\",\"digikey\",\"mouser\",\"lcsc\"]),_2=k_.object({type:k_.literal(\"source_component\"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(y2,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),b2=_2.extend({ftype:k_.literal(\"simple_capacitor\"),capacitance:z1,max_voltage_rating:B1.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:Y1.optional()}),x2=_2.extend({ftype:k_.literal(\"simple_resistor\"),resistance:D1,display_resistance:k_.string().optional()}),v2=_2.extend({ftype:k_.literal(\"simple_diode\")}),S2=_2.extend({ftype:k_.literal(\"simple_fiducial\")}),I2=v2.extend({ftype:k_.literal(\"simple_led\"),color:k_.string().optional(),wavelength:k_.string().optional()}),C2=_2.extend({ftype:k_.literal(\"simple_ground\")}),P2=_2.extend({ftype:k_.literal(\"simple_chip\")}),M2=_2.extend({ftype:k_.literal(\"simple_power_source\"),voltage:B1}),N2=_2.extend({ftype:k_.literal(\"simple_current_source\"),current:X1,frequency:$1.optional(),peak_to_peak_current:X1.optional(),wave_shape:k_.enum([\"sine\",\"square\",\"triangle\",\"sawtooth\",\"dc\"]).optional().default(\"dc\"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),w2=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),T2=_2.extend({ftype:k_.literal(\"simple_fuse\"),current_rating_amps:k_.number().describe(\"Nominal current in amps the fuse is rated for\"),voltage_rating_volts:k_.number().describe(\"Voltage rating in volts, e.g. ±5V would be 5\")}),R2=_2.extend({ftype:k_.literal(\"simple_battery\"),capacity:U1}),E2=_2.extend({ftype:k_.literal(\"simple_inductor\"),inductance:F1,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),A2=_2.extend({ftype:k_.literal(\"simple_push_button\")}),O2=_2.extend({ftype:k_.literal(\"simple_potentiometer\"),max_resistance:D1,display_max_resistance:k_.string().optional()}),k2=_2.extend({ftype:k_.literal(\"simple_crystal\"),frequency:k_.number().describe(\"Frequency in Hz\"),load_capacitance:k_.number().optional().describe(\"Load capacitance in pF\"),pin_variant:k_.enum([\"two_pin\",\"four_pin\"]).optional()}),L2=_2.extend({ftype:k_.literal(\"simple_pin_header\"),pin_count:k_.number(),gender:k_.enum([\"male\",\"female\"]).optional().default(\"male\")}),D2=_2.extend({ftype:k_.literal(\"simple_connector\"),standard:k_.enum([\"usb_c\",\"m2\"]).optional()}),z2=_2.extend({ftype:k_.literal(\"simple_pinout\")}),F2=_2.extend({ftype:k_.literal(\"simple_resonator\"),load_capacitance:z1,equivalent_series_resistance:D1.optional(),frequency:$1}),B2=_2.extend({ftype:k_.literal(\"simple_transistor\"),transistor_type:k_.enum([\"npn\",\"pnp\"])}),j2=_2.extend({ftype:k_.literal(\"simple_test_point\"),footprint_variant:k_.enum([\"pad\",\"through_hole\"]).optional(),pad_shape:k_.enum([\"rect\",\"circle\"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),$2=_2.extend({ftype:k_.literal(\"simple_mosfet\"),channel_type:k_.enum([\"n\",\"p\"]),mosfet_mode:k_.enum([\"enhancement\",\"depletion\"])}),Y2=_2.extend({ftype:k_.literal(\"simple_op_amp\")}),X2=_2.extend({ftype:k_.literal(\"simple_switch\")}),V2=k_.object({type:k_.literal(\"source_project_metadata\"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),created_at:H1.optional()}),W2=f2.extend({type:k_.literal(\"source_missing_property_error\"),source_missing_property_error_id:K1(\"source_missing_property_error\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_missing_property_error\").default(\"source_missing_property_error\")}).describe(\"The source code is missing a property\"),H2=f2.extend({type:k_.literal(\"source_failed_to_create_component_error\"),source_failed_to_create_component_error_id:K1(\"source_failed_to_create_component_error\"),error_type:k_.literal(\"source_failed_to_create_component_error\").default(\"source_failed_to_create_component_error\"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe(\"Error emitted when a component fails to be constructed\"),G2=f2.extend({type:k_.literal(\"source_invalid_component_property_error\"),source_invalid_component_property_error_id:K1(\"source_invalid_component_property_error\"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_invalid_component_property_error\").default(\"source_invalid_component_property_error\")}).describe(\"The source component property is invalid\"),U2=f2.extend({type:k_.literal(\"source_trace_not_connected_error\"),source_trace_not_connected_error_id:K1(\"source_trace_not_connected_error\"),error_type:k_.literal(\"source_trace_not_connected_error\").default(\"source_trace_not_connected_error\"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe(\"Occurs when a source trace selector does not match any ports\"),Z2=k_.object({type:k_.literal(\"source_property_ignored_warning\"),source_property_ignored_warning_id:K1(\"source_property_ignored_warning\"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"source_property_ignored_warning\").default(\"source_property_ignored_warning\"),message:k_.string()}).describe(\"The source property was ignored\"),q2=k_.object({type:k_.literal(\"source_pin_missing_trace_warning\"),source_pin_missing_trace_warning_id:K1(\"source_pin_missing_trace_warning\"),warning_type:k_.literal(\"source_pin_missing_trace_warning\").default(\"source_pin_missing_trace_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a source component pin is missing a trace connection\"),J2=k_.object({type:k_.literal(\"source_missing_manufacturer_part_number_warning\"),source_missing_manufacturer_part_number_warning_id:K1(\"source_missing_manufacturer_part_number_warning\"),warning_type:k_.literal(\"source_missing_manufacturer_part_number_warning\").default(\"source_missing_manufacturer_part_number_warning\"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a standard connector is missing manufacturer part number\"),K2=_2.extend({ftype:k_.literal(\"simple_voltage_probe\")}),Q2=_2.extend({ftype:k_.literal(\"interconnect\")}),t5=f2.extend({type:k_.literal(\"source_i2c_misconfigured_error\"),source_i2c_misconfigured_error_id:K1(\"source_i2c_misconfigured_error\"),error_type:k_.literal(\"source_i2c_misconfigured_error\").default(\"source_i2c_misconfigured_error\"),source_port_ids:k_.array(k_.string())}).describe(\"Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net\"),e5=_2.extend({ftype:k_.literal(\"simple_voltage_source\"),voltage:B1,frequency:$1.optional(),peak_to_peak_voltage:B1.optional(),wave_shape:k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]).optional(),phase:G1.optional(),duty_cycle:k_.number().optional().describe(\"Duty cycle as a fraction (0 to 1)\")}),n5=k_.union([x2,b2,v2,S2,I2,C2,P2,M2,N2,R2,E2,A2,O2,k2,L2,D2,z2,F2,X2,B2,j2,$2,Y2,T2,K2,Q2,e5,V2,W2,G2,H2,U2,Z2,q2,J2,t5]),o5=k_.object({type:k_.literal(\"source_port\"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(w2),i5=k_.object({type:k_.literal(\"source_component_internal_connection\"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),r5=k_.object({type:k_.literal(\"source_trace\"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),s5=k_.object({type:k_.literal(\"source_group\"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),a5=k_.object({type:k_.literal(\"source_net\"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),c5=k_.object({type:k_.literal(\"source_board\"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe(\"Defines a board in the source domain\"),l5=f2.extend({type:k_.literal(\"source_ambiguous_port_reference\"),source_ambiguous_port_reference_id:K1(\"source_ambiguous_port_reference\"),error_type:k_.literal(\"source_ambiguous_port_reference\").default(\"source_ambiguous_port_reference\"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous\"),d5=k_.object({type:k_.literal(\"source_pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane in the source domain\"),h5=k_.enum([\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\"]),u5=h5.or(k_.object({name:h5})).transform(t=\u003e\"string\"==typeof t?t:t.name),p5=k_.enum([\"top\",\"bottom\"]),m5=k_.object({type:k_.literal(\"source_manually_placed_via\"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe(\"Defines a via that is manually placed in the source domain\"),g5=k_.object({type:k_.literal(\"source_no_power_pin_defined_warning\"),source_no_power_pin_defined_warning_id:K1(\"source_no_power_pin_defined_warning\"),warning_type:k_.literal(\"source_no_power_pin_defined_warning\").default(\"source_no_power_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports with requires_power=true\"),f5=k_.object({type:k_.literal(\"source_no_ground_pin_defined_warning\"),source_no_ground_pin_defined_warning_id:K1(\"source_no_ground_pin_defined_warning\"),warning_type:k_.literal(\"source_no_ground_pin_defined_warning\").default(\"source_no_ground_pin_defined_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a chip has no source ports marked as ground pins\"),y5=k_.object({type:k_.literal(\"source_component_pins_underspecified_warning\"),source_component_pins_underspecified_warning_id:K1(\"source_component_pins_underspecified_warning\"),warning_type:k_.literal(\"source_component_pins_underspecified_warning\").default(\"source_component_pins_underspecified_warning\"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when all ports on a source component are underspecified\"),_5=f2.extend({type:k_.literal(\"source_pin_must_be_connected_error\"),source_pin_must_be_connected_error_id:K1(\"source_pin_must_be_connected_error\"),error_type:k_.literal(\"source_pin_must_be_connected_error\").default(\"source_pin_must_be_connected_error\"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pin with mustBeConnected attribute is not connected to any trace\"),b5=f2.extend({type:k_.literal(\"unknown_error_finding_part\"),unknown_error_finding_part_id:K1(\"unknown_error_finding_part\"),error_type:k_.literal(\"unknown_error_finding_part\").default(\"unknown_error_finding_part\"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when an unexpected error occurs while finding a part\"),x5=k_.object({type:k_.literal(\"schematic_box\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:Y1,height:Y1,is_dashed:k_.boolean().default(!1),x:Y1,y:Y1,subcircuit_id:k_.string().optional()}).describe(\"Draws a box on the schematic\"),v5=k_.object({type:k_.literal(\"schematic_path\"),schematic_path_id:K1(\"schematic_path\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),stroke_width:Y1.nullable().optional(),stroke_color:k_.string().optional(),points:k_.array(Z1),subcircuit_id:k_.string().optional()}),S5=k_.record(k_.object({left_margin:j1.optional(),right_margin:j1.optional(),top_margin:j1.optional(),bottom_margin:j1.optional()})),I5=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),C5=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"top-to-bottom\",\"bottom-to-top\"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum([\"left-to-right\",\"right-to-left\"]).optional()}).optional()}),P5=k_.union([I5,C5]),M5=k_.object({type:k_.literal(\"schematic_component\"),size:J1,center:Z1,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_symbol_id:k_.string().optional(),pin_spacing:j1.optional(),pin_styles:S5.optional(),box_width:j1.optional(),symbol_name:k_.string().optional(),port_arrangement:P5.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),N5=k_.object({kicad_symbol:g2.optional()}).catchall(k_.unknown()),w5=k_.object({type:k_.literal(\"schematic_symbol\"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:N5.optional()}).describe(\"Defines a named schematic symbol that can be referenced by components.\"),T5=k_.object({type:k_.literal(\"schematic_line\"),schematic_line_id:K1(\"schematic_line\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:Y1,y1:Y1,x2:Y1,y2:Y1,stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled line on the schematic\"),R5=k_.object({type:k_.literal(\"schematic_rect\"),schematic_rect_id:K1(\"schematic_rect\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,width:Y1,height:Y1,rotation:G1.default(0),stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled rectangle on the schematic\"),E5=k_.object({type:k_.literal(\"schematic_circle\"),schematic_circle_id:K1(\"schematic_circle\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,radius:Y1,stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled circle on the schematic\"),A5=k_.object({type:k_.literal(\"schematic_arc\"),schematic_arc_id:K1(\"schematic_arc\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,radius:Y1,start_angle_degrees:G1,end_angle_degrees:G1,direction:k_.enum([\"clockwise\",\"counterclockwise\"]).default(\"counterclockwise\"),stroke_width:Y1.nullable().optional(),color:k_.string().default(\"#000000\"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe(\"Draws a styled arc on the schematic\"),O5=k_.object({type:k_.literal(\"schematic_trace\"),schematic_trace_id:k_.string(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),k5=k_.enum([\"center\",\"left\",\"right\",\"top\",\"bottom\"]),L5=k_.object({type:k_.literal(\"schematic_text\"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:Y1,y:Y1}),rotation:k_.number().default(0),anchor:k_.union([k5.describe(\"legacy\"),Q1]).default(\"center\"),color:k_.string().default(\"#000000\"),subcircuit_id:k_.string().optional()}),D5=k_.object({type:k_.literal(\"schematic_port\"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_component_id:k_.string().optional(),center:Z1,facing_direction:k_.enum([\"up\",\"down\",\"left\",\"right\"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe(\"Defines a port on a schematic component\"),z5=k_.object({type:k_.literal(\"schematic_net_label\"),schematic_net_label_id:K1(\"schematic_net_label\"),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:Z1,anchor_position:Z1.optional(),anchor_side:k_.enum([\"top\",\"bottom\",\"left\",\"right\"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),F5=f2.extend({type:k_.literal(\"schematic_error\"),schematic_error_id:k_.string(),error_type:k_.literal(\"schematic_port_not_found\").default(\"schematic_port_not_found\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic error on the schematic\"),B5=f2.extend({type:k_.literal(\"schematic_layout_error\"),schematic_layout_error_id:K1(\"schematic_layout_error\"),error_type:k_.literal(\"schematic_layout_error\").default(\"schematic_layout_error\"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when schematic layout fails for a group\"),j5=k_.object({type:k_.literal(\"schematic_debug_object\"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),$5=j5.extend({shape:k_.literal(\"rect\"),center:Z1,size:J1}),Y5=j5.extend({shape:k_.literal(\"line\"),start:Z1,end:Z1}),X5=j5.extend({shape:k_.literal(\"point\"),center:Z1}),V5=k_.discriminatedUnion(\"shape\",[$5,Y5,X5]),W5=k_.object({type:k_.literal(\"schematic_voltage_probe\"),schematic_voltage_probe_id:k_.string(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:Z1,schematic_trace_id:k_.string(),voltage:B1.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:Q1.optional()}).describe(\"Defines a voltage probe measurement point on a schematic trace\"),H5=k_.object({type:k_.literal(\"schematic_manual_edit_conflict_warning\"),schematic_manual_edit_conflict_warning_id:K1(\"schematic_manual_edit_conflict_warning\"),warning_type:k_.literal(\"schematic_manual_edit_conflict_warning\").default(\"schematic_manual_edit_conflict_warning\"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit schX/schY coordinates\"),G5=k_.object({type:k_.literal(\"schematic_group\"),schematic_group_id:K1(\"schematic_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:j1,height:j1,center:Z1,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe(\"Defines a group of components on the schematic\"),U5=k_.object({type:k_.literal(\"schematic_table\"),schematic_table_id:K1(\"schematic_table\"),anchor_position:Z1,column_widths:k_.array(Y1),row_heights:k_.array(Y1),cell_padding:Y1.optional(),border_width:Y1.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:Q1.optional()}).describe(\"Defines a table on the schematic\"),Z5=k_.object({type:k_.literal(\"schematic_table_cell\"),schematic_table_cell_id:K1(\"schematic_table_cell\"),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:Z1,width:Y1,height:Y1,horizontal_align:k_.enum([\"left\",\"center\",\"right\"]).optional(),vertical_align:k_.enum([\"top\",\"middle\",\"bottom\"]).optional(),font_size:Y1.optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a cell within a schematic_table\"),q5=k_.object({type:k_.literal(\"schematic_sheet\"),schematic_sheet_id:K1(\"schematic_sheet\"),name:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a schematic sheet or page that components can be placed on\"),J5=k_.object({x:Y1,y:Y1,bulge:k_.number().optional()}),K5=k_.object({vertices:k_.array(J5)}),Q5=k_.object({outer_ring:K5,inner_rings:k_.array(K5).default([])}),t3=k_.object({x:Y1,y:Y1,via:k_.boolean().optional(),via_to_layer:u5.optional()}),e3=(k_.array(t3),k_.object({x:Y1,y:Y1,via:k_.boolean().optional(),to_layer:u5.optional(),trace_width:Y1.optional()})),n3=k_.object({min_trace_width:j1.optional(),min_board_edge_clearance:j1.optional(),min_via_hole_edge_to_via_hole_edge_clearance:j1.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:j1.optional(),min_trace_to_pad_edge_clearance:j1.optional(),min_pad_edge_to_pad_edge_clearance:j1.optional(),min_same_net_trace_edge_to_trace_edge_clearance:j1.optional(),min_different_net_trace_edge_to_trace_edge_clearance:j1.optional(),min_via_hole_diameter:j1.optional(),min_via_pad_diameter:j1.optional()}),o3=k_.object({type:k_.literal(\"pcb_component\"),pcb_component_id:K1(\"pcb_component\"),source_component_id:k_.string(),center:Z1,layer:u5,rotation:G1,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this part, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this part, usually corresponding with how the user specified it\"),width:j1,height:j1,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"relative_to_another_component\",\"none\"]).optional(),anchor_position:Z1.optional(),anchor_alignment:Q1.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:Z1.optional(),insertion_direction:k_.enum([\"from_above\",\"from_left\",\"from_right\",\"from_front\",\"from_back\"]).optional(),metadata:k_.object({kicad_footprint:l2.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe(\"Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath\")}).describe(\"Defines a component on the PCB\"),i3=k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),hole_diameter:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),r3=(i3.describe(\"Defines a circular hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),s3=(r3.describe(\"Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"square\"]),hole_diameter:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),a3=(s3.describe(\"Defines a circular or square hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"oval\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),c3=(a3.describe(\"Defines an oval hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),l3=(c3.describe(\"Defines a pill-shaped hole on the PCB\"),k_.object({type:k_.literal(\"pcb_hole\"),pcb_hole_id:K1(\"pcb_hole\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,ccw_rotation:G1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),d3=(l3.describe(\"Defines a rotated pill-shaped hole on the PCB\"),s3.or(a3).or(c3).or(l3).or(i3).or(r3)),h3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),u3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.enum([\"oval\",\"pill\"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,ccw_rotation:G1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),p3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"circular_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"circle\"),pad_shape:k_.literal(\"rect\"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:G1.optional()}),m3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),g3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"rotated_pill_hole_with_rect_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal(\"rotated_pill\"),pad_shape:k_.literal(\"rect\"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:G1,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:G1,hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional()}),f3=k_.object({type:k_.literal(\"pcb_plated_hole\"),shape:k_.literal(\"hole_with_polygon_pad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum([\"circle\",\"oval\",\"pill\",\"rotated_pill\"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:Y1,y:Y1})).min(3),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1(\"pcb_plated_hole\"),soldermask_margin:k_.number().optional(),ccw_rotation:G1.optional()}),y3=k_.union([h3,u3,p3,m3,g3,f3]),_3=k_.object({type:k_.literal(\"pcb_port\"),pcb_port_id:K1(\"pcb_port\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:Y1,y:Y1,layers:k_.array(u5),is_board_pinout:k_.boolean().optional()}).describe(\"Defines a port on the PCB\"),b3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"circle\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,radius:k_.number(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),x3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rect\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),v3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_rect\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:G1,layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),S3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"pill\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),I3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"rotated_pill\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:G1,layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),C3=k_.object({type:k_.literal(\"pcb_smtpad\"),shape:k_.literal(\"polygon\"),pcb_smtpad_id:K1(\"pcb_smtpad\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(Z1),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),P3=k_.discriminatedUnion(\"shape\",[b3,x3,v3,I3,S3,C3]).describe(\"Defines an SMT pad on the PCB\"),M3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"circle\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,radius:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),N3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rect\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),w3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"pill\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),T3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"rotated_rect\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),ccw_rotation:Y1,layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),R3=k_.object({type:k_.literal(\"pcb_solder_paste\"),shape:k_.literal(\"oval\"),pcb_solder_paste_id:K1(\"pcb_solder_paste\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),E3=k_.union([M3,N3,w3,T3,R3]).describe(\"Defines solderpaste on the PCB\"),A3=k_.object({type:k_.literal(\"pcb_text\"),pcb_text_id:K1(\"pcb_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:Z1,layer:u5,width:j1,height:j1,lines:k_.number(),align:k_.enum([\"bottom-left\"])}).describe(\"Defines text on the PCB\"),O3=k_.object({route_type:k_.literal(\"wire\"),x:Y1,y:Y1,width:Y1,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:u5}),k3=k_.object({route_type:k_.literal(\"via\"),x:Y1,y:Y1,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:Y1.optional(),outer_diameter:Y1.optional(),from_layer:u5,to_layer:u5}),L3=k_.union([O3,k3]),D3=k_.object({type:k_.literal(\"pcb_trace\"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:K1(\"pcb_trace\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum([\"constant\",\"interpolated\"]).default(\"constant\").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(L3)}).describe(\"Defines a trace on the PCB\"),z3=k_.object({type:k_.literal(\"pcb_trace_warning\"),pcb_trace_warning_id:K1(\"pcb_trace_warning\"),warning_type:k_.literal(\"pcb_trace_warning\").default(\"pcb_trace_warning\"),message:k_.string(),center:Z1.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace warning on the PCB\"),F3=f2.extend({type:k_.literal(\"pcb_trace_error\"),pcb_trace_error_id:K1(\"pcb_trace_error\"),error_type:k_.literal(\"pcb_trace_error\").default(\"pcb_trace_error\"),center:Z1.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB\"),B3=f2.extend({type:k_.literal(\"pcb_trace_missing_error\"),pcb_trace_missing_error_id:K1(\"pcb_trace_missing_error\"),error_type:k_.literal(\"pcb_trace_missing_error\").default(\"pcb_trace_missing_error\"),center:Z1.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a source trace has no corresponding PCB trace\"),j3=f2.extend({type:k_.literal(\"pcb_port_not_matched_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_port_not_matched_error\").default(\"pcb_port_not_matched_error\"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines a trace error on the PCB where a port is not matched\"),$3=f2.extend({type:k_.literal(\"pcb_port_not_connected_error\"),pcb_port_not_connected_error_id:K1(\"pcb_port_not_connected_error\"),error_type:k_.literal(\"pcb_port_not_connected_error\").default(\"pcb_port_not_connected_error\"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe(\"Defines an error when a pcb port is not connected to any trace\"),Y3=k_.object({type:k_.literal(\"pcb_net\"),pcb_net_id:K1(\"pcb_net\"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe(\"Defines a net on the PCB\"),X3=k_.object({type:k_.literal(\"pcb_via\"),pcb_via_id:K1(\"pcb_via\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:Y1,y:Y1,outer_diameter:Y1.default(\"0.6mm\"),hole_diameter:Y1.default(\"0.25mm\"),from_layer:u5.optional(),to_layer:u5.optional(),layers:k_.array(u5),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe(\"Defines a via on the PCB\"),V3=k_.object({type:k_.literal(\"pcb_board\"),pcb_board_id:K1(\"pcb_board\"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:j1.optional(),height:j1.optional(),center:Z1,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this board, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this board, usually corresponding with how the user specified it\"),thickness:j1.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(Z1).optional(),shape:k_.enum([\"rect\",\"polygon\"]).optional(),material:k_.enum([\"fr4\",\"fr1\"]).default(\"fr4\"),anchor_position:Z1.optional(),anchor_alignment:Q1.optional(),position_mode:k_.enum([\"relative_to_panel_anchor\",\"none\"]).optional()}).merge(n3).describe(\"Defines the board outline of the PCB\"),W3=k_.object({type:k_.literal(\"pcb_panel\"),pcb_panel_id:K1(\"pcb_panel\"),width:j1,height:j1,center:Z1,thickness:j1.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe(\"Defines a PCB panel that can contain multiple boards\"),H3=f2.extend({type:k_.literal(\"pcb_placement_error\"),pcb_placement_error_id:K1(\"pcb_placement_error\"),error_type:k_.literal(\"pcb_placement_error\").default(\"pcb_placement_error\"),subcircuit_id:k_.string().optional()}).describe(\"Defines a placement error on the PCB\"),G3=f2.extend({type:k_.literal(\"pcb_panelization_placement_error\"),pcb_panelization_placement_error_id:K1(\"pcb_panelization_placement_error\"),error_type:k_.literal(\"pcb_panelization_placement_error\").default(\"pcb_panelization_placement_error\"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a panelization placement error on the PCB\"),U3=k_.object({type:k_.literal(\"pcb_trace_hint\"),pcb_trace_hint_id:K1(\"pcb_trace_hint\"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(e3),subcircuit_id:k_.string().optional()}).describe(\"A hint that can be used during generation of a PCB trace\"),Z3=k_.object({type:k_.literal(\"pcb_silkscreen_line\"),pcb_silkscreen_line_id:K1(\"pcb_silkscreen_line\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:Y1.default(\"0.1mm\"),x1:Y1,y1:Y1,x2:Y1,y2:Y1,layer:p5}).describe(\"Defines a silkscreen line on the PCB\"),q3=k_.object({type:k_.literal(\"pcb_silkscreen_path\"),pcb_silkscreen_path_id:K1(\"pcb_silkscreen_path\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,route:k_.array(Z1),stroke_width:j1}).describe(\"Defines a silkscreen path on the PCB\"),J3=k_.object({type:k_.literal(\"pcb_silkscreen_text\"),pcb_silkscreen_text_id:K1(\"pcb_silkscreen_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:j1,top:j1,bottom:j1,right:j1}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:u5,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:Q1.default(\"center\")}).describe(\"Defines silkscreen text on the PCB\"),K3=k_.object({type:k_.literal(\"pcb_copper_text\"),pcb_copper_text_id:K1(\"pcb_copper_text\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"0.2mm\"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:j1,top:j1,bottom:j1,right:j1}).default({left:\"0.2mm\",top:\"0.2mm\",bottom:\"0.2mm\",right:\"0.2mm\"}).optional(),ccw_rotation:k_.number().optional(),layer:u5,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:Q1.default(\"center\")}).describe(\"Defines copper text on the PCB\"),Q3=k_.object({type:k_.literal(\"pcb_silkscreen_rect\"),pcb_silkscreen_rect_id:K1(\"pcb_silkscreen_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:u5,stroke_width:j1.default(\"1mm\"),corner_radius:j1.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen rect on the PCB\"),t4=k_.object({type:k_.literal(\"pcb_silkscreen_circle\"),pcb_silkscreen_circle_id:K1(\"pcb_silkscreen_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:j1,layer:p5,stroke_width:j1.default(\"1mm\"),is_filled:k_.boolean().optional()}).describe(\"Defines a silkscreen circle on the PCB\"),e4=k_.object({type:k_.literal(\"pcb_silkscreen_oval\"),pcb_silkscreen_oval_id:K1(\"pcb_silkscreen_oval\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius_x:Y1,radius_y:Y1,layer:p5,ccw_rotation:G1.optional()}).describe(\"Defines a silkscreen oval on the PCB\"),n4=k_.object({type:k_.literal(\"pcb_silkscreen_pill\"),pcb_silkscreen_pill_id:K1(\"pcb_silkscreen_pill\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:u5,ccw_rotation:k_.number().optional()}).describe(\"Defines a silkscreen pill on the PCB\"),o4=k_.object({type:k_.literal(\"pcb_fabrication_note_text\"),pcb_fabrication_note_text_id:K1(\"pcb_fabrication_note_text\"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"1mm\"),pcb_component_id:k_.string(),text:k_.string(),layer:p5,anchor_position:Z1.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),color:k_.string().optional()}).describe(\"Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators\"),i4=k_.object({type:k_.literal(\"pcb_fabrication_note_path\"),pcb_fabrication_note_path_id:K1(\"pcb_fabrication_note_path\"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:u5,route:k_.array(Z1),stroke_width:j1,color:k_.string().optional()}).describe(\"Defines a fabrication path on the PCB for fabricators or assemblers\"),r4=k_.object({type:k_.literal(\"pcb_fabrication_note_rect\"),pcb_fabrication_note_rect_id:K1(\"pcb_fabrication_note_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5,stroke_width:j1.default(\"0.1mm\"),corner_radius:j1.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a fabrication note rectangle on the PCB\"),s4=k_.object({type:k_.literal(\"pcb_fabrication_note_dimension\"),pcb_fabrication_note_dimension_id:K1(\"pcb_fabrication_note_dimension\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,from:Z1,to:Z1,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:j1.optional(),offset_distance:j1.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:j1.default(\"1mm\"),color:k_.string().optional(),arrow_size:j1.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB fabrication notes\"),a4=k_.object({type:k_.literal(\"pcb_note_text\"),pcb_note_text_id:K1(\"pcb_note_text\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:Y1.default(\"1mm\"),text:k_.string().optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:k_.enum([\"center\",\"top_left\",\"top_right\",\"bottom_left\",\"bottom_right\"]).default(\"center\"),layer:p5.default(\"top\"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a documentation note in text on the PCB\"),c4=k_.object({type:k_.literal(\"pcb_note_rect\"),pcb_note_rect_id:K1(\"pcb_note_rect\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5.default(\"top\"),stroke_width:j1.default(\"0.1mm\"),corner_radius:j1.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe(\"Defines a rectangular documentation note on the PCB\"),l4=k_.object({type:k_.literal(\"pcb_note_path\"),pcb_note_path_id:K1(\"pcb_note_path\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(Z1),layer:p5.default(\"top\"),stroke_width:j1.default(\"0.1mm\"),color:k_.string().optional()}).describe(\"Defines a polyline documentation note on the PCB\"),d4=k_.object({type:k_.literal(\"pcb_note_line\"),pcb_note_line_id:K1(\"pcb_note_line\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:Y1,y1:Y1,x2:Y1,y2:Y1,layer:p5.default(\"top\"),stroke_width:Y1.default(\"0.1mm\"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe(\"Defines a straight documentation note line on the PCB\"),h4=k_.object({type:k_.literal(\"pcb_note_dimension\"),pcb_note_dimension_id:K1(\"pcb_note_dimension\"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:Z1,to:Z1,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:j1.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal(\"tscircuit2024\").default(\"tscircuit2024\"),font_size:j1.default(\"1mm\"),layer:p5.default(\"top\"),color:k_.string().optional(),arrow_size:j1.default(\"1mm\")}).describe(\"Defines a measurement annotation within PCB documentation notes\"),u4=f2.extend({type:k_.literal(\"pcb_footprint_overlap_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_footprint_overlap_error\").default(\"pcb_footprint_overlap_error\"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe(\"Error emitted when a pcb footprint overlaps with another element\"),p4=f2.extend({type:k_.literal(\"pcb_courtyard_overlap_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_courtyard_overlap_error\").default(\"pcb_courtyard_overlap_error\"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe(\"Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another\"),m4=k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"rect\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:Y1,height:Y1,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal(\"pcb_keepout\"),shape:k_.literal(\"circle\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:Y1,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),g4=k_.object({type:k_.literal(\"pcb_cutout\"),pcb_cutout_id:K1(\"pcb_cutout\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),f4=g4.extend({shape:k_.literal(\"rect\"),center:Z1,width:j1,height:j1,rotation:G1.optional(),corner_radius:j1.optional()}),y4=g4.extend({shape:k_.literal(\"circle\"),center:Z1,radius:j1}),_4=g4.extend({shape:k_.literal(\"polygon\"),points:k_.array(Z1)}),b4=g4.extend({shape:k_.literal(\"path\"),route:k_.array(Z1),slot_width:j1,slot_length:j1.optional(),space_between_slots:j1.optional(),slot_corner_radius:j1.optional()}),x4=k_.discriminatedUnion(\"shape\",[f4,y4,_4,b4]).describe(\"Defines a cutout on the PCB, removing board material.\"),v4=f2.extend({type:k_.literal(\"pcb_missing_footprint_error\"),pcb_missing_footprint_error_id:K1(\"pcb_missing_footprint_error\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"pcb_missing_footprint_error\").default(\"pcb_missing_footprint_error\"),source_component_id:k_.string()}).describe(\"Defines a missing footprint error on the PCB\"),S4=f2.extend({type:k_.literal(\"external_footprint_load_error\"),external_footprint_load_error_id:K1(\"external_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal(\"external_footprint_load_error\").default(\"external_footprint_load_error\")}).describe(\"Defines an error when an external footprint fails to load\"),I4=f2.extend({type:k_.literal(\"circuit_json_footprint_load_error\"),circuit_json_footprint_load_error_id:K1(\"circuit_json_footprint_load_error\"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal(\"circuit_json_footprint_load_error\").default(\"circuit_json_footprint_load_error\"),circuit_json:k_.array(k_.any()).optional()}).describe(\"Defines an error when a circuit JSON footprint fails to load\"),C4=k_.object({type:k_.literal(\"pcb_group\"),pcb_group_id:K1(\"pcb_group\"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:j1.optional(),height:j1.optional(),center:Z1,display_offset_x:k_.string().optional().describe(\"How to display the x offset for this group, usually corresponding with how the user specified it\"),display_offset_y:k_.string().optional().describe(\"How to display the y offset for this group, usually corresponding with how the user specified it\"),outline:k_.array(Z1).optional(),anchor_position:Z1.optional(),anchor_alignment:Q1.default(\"center\"),position_mode:k_.enum([\"packed\",\"relative_to_group_anchor\",\"none\"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum([\"packed\",\"none\"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:j1}).optional(),autorouter_used_string:k_.string().optional()}).describe(\"Defines a group of components on the PCB\"),P4=f2.extend({type:k_.literal(\"pcb_autorouting_error\"),pcb_error_id:K1(\"pcb_autorouting_error\"),error_type:k_.literal(\"pcb_autorouting_error\").default(\"pcb_autorouting_error\"),subcircuit_id:k_.string().optional()}).describe(\"The autorouting has failed to route a portion of the board\"),M4=k_.object({type:k_.literal(\"pcb_manual_edit_conflict_warning\"),pcb_manual_edit_conflict_warning_id:K1(\"pcb_manual_edit_conflict_warning\"),warning_type:k_.literal(\"pcb_manual_edit_conflict_warning\").default(\"pcb_manual_edit_conflict_warning\"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe(\"Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates\"),N4=k_.enum([\"x-\",\"x+\",\"y+\",\"y-\"]),w4=k_.object({type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\"),pcb_connector_not_in_accessible_orientation_warning_id:K1(\"pcb_connector_not_in_accessible_orientation_warning\"),warning_type:k_.literal(\"pcb_connector_not_in_accessible_orientation_warning\").default(\"pcb_connector_not_in_accessible_orientation_warning\"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:N4,recommended_facing_direction:N4,subcircuit_id:k_.string().optional()}).describe(\"Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction\"),T4=k_.object({type:k_.literal(\"supplier_footprint_mismatch_warning\"),supplier_footprint_mismatch_warning_id:K1(\"supplier_footprint_mismatch_warning\"),warning_type:k_.literal(\"supplier_footprint_mismatch_warning\").default(\"supplier_footprint_mismatch_warning\"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:y2.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe(\"Warning emitted when a supplier part footprint does not match the expected footprint\"),R4=k_.object({type:k_.literal(\"pcb_breakout_point\"),pcb_breakout_point_id:K1(\"pcb_breakout_point\"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:Y1,y:Y1}).describe(\"Defines a routing target within a pcb_group for a source_trace or source_net\"),E4=k_.object({type:k_.literal(\"pcb_ground_plane\"),pcb_ground_plane_id:K1(\"pcb_ground_plane\"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Defines a ground plane on the PCB\"),A4=k_.object({type:k_.literal(\"pcb_ground_plane_region\"),pcb_ground_plane_region_id:K1(\"pcb_ground_plane_region\"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:u5,points:k_.array(Z1)}).describe(\"Defines a polygon region of a ground plane\"),O4=k_.object({type:k_.literal(\"pcb_thermal_spoke\"),pcb_thermal_spoke_id:K1(\"pcb_thermal_spoke\"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:Y1,spoke_inner_diameter:Y1,spoke_outer_diameter:Y1,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Pattern for connecting a ground plane to a plated hole\"),k4=k_.object({type:k_.literal(\"pcb_copper_pour\"),pcb_copper_pour_id:K1(\"pcb_copper_pour\"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:u5,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),L4=k4.extend({shape:k_.literal(\"rect\"),center:Z1,width:j1,height:j1,rotation:G1.optional()}),D4=k4.extend({shape:k_.literal(\"brep\"),brep_shape:Q5}),z4=k4.extend({shape:k_.literal(\"polygon\"),points:k_.array(Z1)}),F4=k_.discriminatedUnion(\"shape\",[L4,D4,z4]).describe(\"Defines a copper pour on the PCB.\"),B4=f2.extend({type:k_.literal(\"pcb_component_outside_board_error\"),pcb_component_outside_board_error_id:K1(\"pcb_component_outside_board_error\"),error_type:k_.literal(\"pcb_component_outside_board_error\").default(\"pcb_component_outside_board_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Z1,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe(\"Error emitted when a PCB component is placed outside the board boundaries\"),j4=f2.extend({type:k_.literal(\"pcb_component_not_on_board_edge_error\"),pcb_component_not_on_board_edge_error_id:K1(\"pcb_component_not_on_board_edge_error\"),error_type:k_.literal(\"pcb_component_not_on_board_edge_error\").default(\"pcb_component_not_on_board_edge_error\"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Z1,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component that must be placed on the board edge is centered away from the edge\"),$4=f2.extend({type:k_.literal(\"pcb_component_invalid_layer_error\"),pcb_component_invalid_layer_error_id:K1(\"pcb_component_invalid_layer_error\"),error_type:k_.literal(\"pcb_component_invalid_layer_error\").default(\"pcb_component_invalid_layer_error\"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:u5,subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)\"),Y4=f2.extend({type:k_.literal(\"pcb_via_clearance_error\"),pcb_error_id:K1(\"pcb_error\"),error_type:k_.literal(\"pcb_via_clearance_error\").default(\"pcb_via_clearance_error\"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when vias are closer than the allowed clearance\"),X4=f2.extend({type:k_.literal(\"pcb_via_trace_clearance_error\"),pcb_via_trace_clearance_error_id:K1(\"pcb_via_trace_clearance_error\"),error_type:k_.literal(\"pcb_via_trace_clearance_error\").default(\"pcb_via_trace_clearance_error\"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a via and trace are closer than the allowed clearance\"),V4=f2.extend({type:k_.literal(\"pcb_pad_pad_clearance_error\"),pcb_pad_pad_clearance_error_id:K1(\"pcb_pad_pad_clearance_error\"),error_type:k_.literal(\"pcb_pad_pad_clearance_error\").default(\"pcb_pad_pad_clearance_error\"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when pads are closer than the allowed clearance\"),W4=f2.extend({type:k_.literal(\"pcb_pad_trace_clearance_error\"),pcb_pad_trace_clearance_error_id:K1(\"pcb_pad_trace_clearance_error\"),error_type:k_.literal(\"pcb_pad_trace_clearance_error\").default(\"pcb_pad_trace_clearance_error\"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe(\"Error emitted when a pad and trace are closer than allowed clearance\"),H4=k_.object({type:k_.literal(\"pcb_courtyard_rect\"),pcb_courtyard_rect_id:K1(\"pcb_courtyard_rect\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5,ccw_rotation:G1.optional(),color:k_.string().optional()}).describe(\"Defines a courtyard rectangle on the PCB\"),G4=k_.object({type:k_.literal(\"pcb_courtyard_outline\"),pcb_courtyard_outline_id:K1(\"pcb_courtyard_outline\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,outline:k_.array(Z1).min(2)}).describe(\"Defines a courtyard outline on the PCB\"),U4=k_.object({type:k_.literal(\"pcb_courtyard_polygon\"),pcb_courtyard_polygon_id:K1(\"pcb_courtyard_polygon\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,points:k_.array(Z1).min(3),color:k_.string().optional()}).describe(\"Defines a courtyard polygon on the PCB\"),Z4=k_.object({type:k_.literal(\"pcb_courtyard_circle\"),pcb_courtyard_circle_id:K1(\"pcb_courtyard_circle\"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:j1,layer:p5,color:k_.string().optional()}).describe(\"Defines a courtyard circle on the PCB\"),q4=k_.object({type:k_.literal(\"cad_component\"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:q1,rotation:q1.optional(),size:q1.optional(),layer:u5.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:t2.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum([\"x+\",\"x-\",\"y+\",\"y-\",\"z+\",\"z-\"]).optional().describe('The direction in the model\\'s coordinate space that is considered \"up\" or \"coming out of the board surface\"'),model_origin_position:q1.optional(),model_origin_alignment:k_.enum([\"unknown\",\"center\",\"center_of_component_on_board_surface\",\"bottom_center_of_component\"]).optional(),model_object_fit:k_.enum([\"contain_within_bounds\",\"fill_bounds\"]).optional().default(\"contain_within_bounds\"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),anchor_alignment:k_.enum([\"center\",\"center_of_component_on_board_surface\"]).optional().default(\"center\")}).describe(\"Defines a component on the PCB\"),J4=k_.enum([\"sinewave\",\"square\",\"triangle\",\"sawtooth\"]),K4=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),Q4=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:K1(\"simulation_voltage_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:B1}).describe(\"Defines a DC voltage source for simulation\"),t6=k_.object({type:k_.literal(\"simulation_voltage_source\"),simulation_voltage_source_id:K1(\"simulation_voltage_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:B1.optional(),frequency:$1.optional(),peak_to_peak_voltage:B1.optional(),wave_shape:J4.optional(),phase:G1.optional(),duty_cycle:K4.optional()}).describe(\"Defines an AC voltage source for simulation\"),e6=k_.union([Q4,t6]).describe(\"Defines a voltage source for simulation\"),n6=k_.union([k_.string(),k_.number()]).transform(t=\u003e\"string\"==typeof t?t.endsWith(\"%\")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,\"Duty cycle must be non-negative\").max(1,\"Duty cycle cannot be greater than 100%\")),o6=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:K1(\"simulation_current_source\"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:X1}).describe(\"Defines a DC current source for simulation\"),i6=k_.object({type:k_.literal(\"simulation_current_source\"),simulation_current_source_id:K1(\"simulation_current_source\"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:X1.optional(),frequency:$1.optional(),peak_to_peak_current:X1.optional(),wave_shape:J4.optional(),phase:G1.optional(),duty_cycle:n6.optional()}).describe(\"Defines an AC current source for simulation\"),r6=k_.union([o6,i6]).describe(\"Defines a current source for simulation\"),s6=k_.union([k_.literal(\"spice_dc_sweep\"),k_.literal(\"spice_dc_operating_point\"),k_.literal(\"spice_transient_analysis\"),k_.literal(\"spice_ac_analysis\")]),a6=k_.object({type:k_.literal(\"simulation_experiment\"),simulation_experiment_id:K1(\"simulation_experiment\"),name:k_.string(),experiment_type:s6,time_per_step:V1.optional(),start_time_ms:W1.optional(),end_time_ms:W1.optional()}).describe(\"Defines a simulation experiment configuration\"),c6=k_.object({type:k_.literal(\"simulation_transient_voltage_graph\"),simulation_transient_voltage_graph_id:K1(\"simulation_transient_voltage_graph\"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:V1,start_time_ms:W1,end_time_ms:W1,name:k_.string().optional(),color:k_.string().optional()}).describe(\"Stores voltage measurements over time for a simulation\"),l6=k_.object({type:k_.literal(\"simulation_switch\"),simulation_switch_id:K1(\"simulation_switch\"),source_component_id:k_.string().optional(),closes_at:W1.optional(),opens_at:W1.optional(),starts_closed:k_.boolean().optional(),switching_frequency:$1.optional()}).describe(\"Defines a switch for simulation timing control\"),d6=k_.object({type:k_.literal(\"simulation_voltage_probe\"),simulation_voltage_probe_id:K1(\"simulation_voltage_probe\"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe(\"Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.\").superRefine((t,e)=\u003e{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n\u0026\u0026o?e.addIssue({code:k_.ZodIssueCode.custom,message:\"Cannot mix port and net connections in a differential probe.\"}):n?t.signal_input_source_port_id\u0026\u0026t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id.\"}):o\u0026\u0026(t.signal_input_source_net_id\u0026\u0026t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:\"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id.\"}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id\u0026\u0026e.addIssue({code:k_.ZodIssueCode.custom,message:\"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id.\"})}),h6=f2.extend({type:k_.literal(\"simulation_unknown_experiment_error\"),simulation_unknown_experiment_error_id:K1(\"simulation_unknown_experiment_error\"),error_type:k_.literal(\"simulation_unknown_experiment_error\").default(\"simulation_unknown_experiment_error\"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe(\"An unknown error occurred during the simulation experiment.\"),u6=k_.object({type:k_.literal(\"simulation_op_amp\"),simulation_op_amp_id:K1(\"simulation_op_amp\"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe(\"Defines a simple ideal operational amplifier for simulation\"),p6=(k_.union([r5,o5,i5,n5,a5,s5,P2,b2,v2,I2,x2,M2,R2,E2,L2,z2,F2,X2,B2,j2,$2,Y2,O2,A2,d5,m5,c5,V2,G2,U2,q2,J2,g5,f5,y5,_5,b5,t5,l5,o3,d3,v4,S4,I4,M4,w4,T4,y3,m4,_3,Y3,A3,D3,z3,X3,P3,E3,V3,W3,C4,U3,Z3,q3,J3,n4,K3,Q3,t4,e4,F3,B3,H3,G3,j3,$3,Y4,X4,V4,W4,i4,o4,r4,s4,a4,c4,l4,d4,h4,P4,u4,p4,R4,x4,E4,A4,O4,F4,B4,j4,$4,H4,G4,U4,Z4,x5,L5,T5,R5,E5,A5,M5,w5,D5,O5,v5,F5,B5,z5,V5,W5,H5,G5,q5,U5,Z5,q4,e6,r6,a6,c6,l6,d6,h6,u6]),[0,1,-1,2,-2,3,-3,4]),m6=(p6.flatMap(t=\u003ep6.map(e=\u003e[t,e])).sort(([t,e],[n,o])=\u003eMath.abs(t)+Math.abs(e)-Math.abs(n)-Math.abs(o)).length,[.2,.4,.8,1.2].flatMap(t=\u003e[.2,.3,.45,.6].flatMap(e=\u003e[-1,1].map(n=\u003e({halfSpan:t,offset:e,directionSign:n})))).flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,...t}))));[1,-1].flatMap(t=\u003e[1,-1].flatMap(e=\u003e[!1,!0].flatMap(n=\u003e[0,1].map(o=\u003e({routeSide:o,normalDirectionSign:t,tangentDirectionSign:e,reverseEndpointOffsets:n}))))),[0,1].map(t=\u003e({kind:\"displacementChain\",routeSide:t})),[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"segment\",routeSide:e,halfSpan:.4,offset:1.2,directionSign:t}))),[-1,1].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"span\",routeSide:e,spanExpansion:3,offset:1.8,directionSign:t}))),[{dx:-2.4,dy:-.4},{dx:-2.4,dy:.4},{dx:2.4,dy:-.4},{dx:2.4,dy:.4},{dx:-.4,dy:-2.4},{dx:-.4,dy:2.4},{dx:.4,dy:-2.4},{dx:.4,dy:2.4}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:2,...t}))),[{dx:-.17,dy:0},{dx:.17,dy:0},{dx:0,dy:-.17},{dx:0,dy:.17}].flatMap(t=\u003e[0,1].map(e=\u003e({kind:\"waypoint\",routeSide:e,spanExpansion:0,...t})));var g6=1e-8,f6=(t,e,n=0)=\u003et.x\u003e=e.minX+n-g6\u0026\u0026t.x\u003c=e.maxX-n+g6\u0026\u0026t.y\u003e=e.minY+n-g6\u0026\u0026t.y\u003c=e.maxY-n+g6,y6=(t,e,n)=\u003e{let o=0,i=1;for(const[r,s,a,c]of[[t.x,e.x-t.x,n.minX,n.maxX],[t.y,e.y-t.y,n.minY,n.maxY]]){if(void 0===r||void 0===s||void 0===a||void 0===c)throw new Error(\"Invalid segment clipping axis\");if(Math.abs(s)\u003c=g6){if(r\u003ca-g6||r\u003ec+g6)return;continue}const t=(a-r)/s,e=(c-r)/s;if(o=Math.max(o,Math.min(t,e)),i=Math.min(i,Math.max(t,e)),i\u003co-g6)return}return[Math.max(0,o),Math.min(1,i)]},_6=(t,e,n)=\u003e{if(n\u003c=g6)return structuredClone(t);if(n\u003e=.99999999)return structuredClone(e);const o={...structuredClone(t),x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n};return delete o.pcb_port_id,o},b6=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=g6\u0026\u0026Math.abs(t.y-e.y)\u003c=g6\u0026\u0026t.z===e.z,x6=t=\u003eArray.isArray(t)?`[${t.map(x6).join(\",\")}]`:null!==t\u0026\u0026\"object\"==typeof t?`{${Object.keys(t).filter(e=\u003evoid 0!==t[e]).sort().map(e=\u003e`${JSON.stringify(e)}:${x6(t[e])}`).join(\",\")}}`:JSON.stringify(t)??\"undefined\",v6=(t,e,n)=\u003e{if(1===t.route.length)return structuredClone(t.route);const o=e=\u003e{const n=Math.min(Math.floor(e),t.route.length-2);return _6(t.route[n],t.route[n+1],e-n)},i=[o(e)];for(let o=Math.floor(e)+1;o\u003cn-g6;o+=1)i.push(structuredClone(t.route[o]));return n\u003ee+g6\u0026\u0026i.push(o(n)),i},S6=(t,e,n)=\u003e{const o=v6(t,e,n),i=Object.fromEntries(Object.entries(t).filter(([t])=\u003e\"route\"!==t\u0026\u0026\"vias\"!==t)),r=t.vias.filter(t=\u003eo.some(e=\u003eMath.hypot(e.x-t.x,e.y-t.y)\u003c=g6));return x6({metadata:i,points:o,vias:r})},I6=(t,e)=\u003e{const n=t.__zLayers;if(n)return new Set(n);if(t.zLayers)return new Set(t.zLayers);const o=new Set;for(const n of t.layers){const t=\"top\"===n?0:\"bottom\"===n?e-1:/^inner\\d+$/.test(n)?Number(n.slice(5)):-1;if(t\u003c0||t\u003e=e)throw new Error(`repair04 obstacle has an unknown layer: ${n}`);o.add(t)}return o},C6=({srj:t,routes:e,traceClearance:n=.1,viaClearance:o=.1})=\u003e{let i;const r=new Map,s=[];let a=!1;return c=\u003e{const l=i??=((t,e)=\u003e{const n=new Map,o=t=\u003e{const e=n.get(t);if(void 0===e)return n.set(t,t),t;if(e===t)return t;const i=o(e);return n.set(t,i),i},i=t=\u003e{const e=t.filter(t=\u003e\"string\"==typeof t\u0026\u0026t.length\u003e0);if(0===e.length)return;const i=o(e[0]);for(const t of e)n.set(o(t),i)};for(const e of t.connections){const t=e;i([t.name,t.rootConnectionName,t.netConnectionName,t.__netConnectionName,...t.mergedConnectionNames??[],...t.__rootConnectionNames??[],...t.pointsToConnect.flatMap(t=\u003e[t.pointId,t.pcb_port_id])])}for(const e of t.obstacles)i(e.connectedTo);for(const t of e)i([t.connectionName,t.rootConnectionName]);for(const t of n.keys())n.set(t,o(t));return n})(t,e),d=new Map,h=a?s:function*(e){for(let i=0;i\u003ct.obstacles.length;i++){if(r.has(i)){const t=r.get(i);t\u0026\u0026(yield t);continue}const a=t.obstacles[i],c=a.connectedTo.some(t=\u003e/^(pcb_smtpad_|pcb_plated_hole_|pcb_port_)/.test(t)),l=Math.abs((a.ccwRotationDegrees??0)%180)\u003e1e-8,d=\"rect\"===a.type\u0026\u0026a.layers.length\u003e1\u0026\u0026Math.abs(a.width-a.height)\u003c.001;if(c\u0026\u0026!l\u0026\u0026!d){r.set(i,null);continue}if(![a.center.x,a.center.y,a.width,a.height,a.ccwRotationDegrees??0].every(Number.isFinite)||a.width\u003c0||a.height\u003c0)throw new Error(\"repair04 fixed obstacle geometry must be finite and nonnegative\");const h=I6(a,t.layerCount),u=new Set(a.connectedTo.map(t=\u003ee.get(t)??t)),p={minX:-a.width/2,maxX:a.width/2,minY:-a.height/2,maxY:a.height/2},m=(a.ccwRotationDegrees??0)*Math.PI/180,g=Math.cos(m),f=Math.sin(m),y=Math.hypot(a.width,a.height)/2,_=t=\u003e{const e=t.x-a.center.x,n=t.y-a.center.y;return{x:e*g+n*f,y:-e*f+n*g}},b=(t,e,n)=\u003eMath.max(t.x,e.x)+n\u003ca.center.x-y||Math.min(t.x,e.x)-n\u003ea.center.x+y||Math.max(t.y,e.y)+n\u003ca.center.y-y||Math.min(t.y,e.y)-n\u003ea.center.y+y,x=!0===a.obstacleId?.startsWith(\"repair04_board_edge_\"),v=x?0:Math.max(n,t.defaultObstacleMargin??0,t.minTraceToPadEdgeClearance??0),S=x?0:Math.max(o,t.defaultObstacleMargin??0,t.minViaEdgeToPadEdgeClearance??0),I={obstacleIndex:i,obstacle:a,zLayers:h,obstacleNets:u,obstacleBounds:p,toLocal:_,separated:b,wireGap:v,viaGap:S};r.set(i,I),s.push(I),yield I}a=!0}(l);for(const{obstacleIndex:t,obstacle:e,zLayers:n,obstacleNets:o,obstacleBounds:i,toLocal:r,separated:s,wireGap:a,viaGap:u}of h)for(let h=0;h\u003cc.length;h+=1){const p=c[h];if(!(p.route.length\u003c2)\u0026\u0026![p.connectionName,p.rootConnectionName].some(t=\u003evoid 0!==t\u0026\u0026o.has(l.get(t)??t)))for(let o=1;o\u003cp.route.length;o+=1){const c=p.route[o-1],l=p.route[o];if(\"through_obstacle\"===c.toNextSegmentType)continue;if(c.z!==l.z){if(!Array.from(n).some(t=\u003et\u003e=Math.min(c.z,l.z)\u0026\u0026t\u003c=Math.max(c.z,l.z)))continue;if(Math.abs(c.x-l.x)\u003e1e-8||Math.abs(c.y-l.y)\u003e1e-8)throw new Error(\"repair04 found a non-colocated via transition: \"+JSON.stringify({route:p,from:c,to:l}));if(s(c,c,p.viaDiameter/2+u+1e-8))continue;const e=r(c),o=ke(e,e,i),a=p.viaDiameter/2+u-o;if(a\u003c=1e-8)continue;const m=`fixed-obstacle:${h}:${t}:via`;(d.get(m)?.severity??-1/0)\u003ca\u0026\u0026d.set(m,{key:m,center:{x:c.x,y:c.y},routeIndex:h,obstacleIndex:t,kind:\"via\",severity:a});continue}if(!n.has(c.z))continue;const m=Math.max(c.traceThickness??p.traceThickness,l.traceThickness??p.traceThickness)/2;if(s(c,l,m+a+1e-8))continue;const g=m+a-ke(r(c),r(l),i);if(g\u003c=1e-8)continue;const f=`fixed-obstacle:${h}:${t}:wire`;(d.get(f)?.severity??-1/0)\u003cg\u0026\u0026d.set(f,{key:f,center:ze(e.center,c,l),routeIndex:h,obstacleIndex:t,kind:\"wire\",severity:g})}}return Array.from(d.values())}},P6=t=\u003eC6(t)(t.routes),M6=(t,e)=\u003e{const n=[];for(let o=1;o\u003ct.route.length;o++){const i=t.route[o-1],r=t.route[o];if(i.z===r.z||\"through_obstacle\"===i.toNextSegmentType)continue;if(i.x!==r.x||i.y!==r.y||![i.x,i.y,i.z,r.z,t.viaDiameter].every(Number.isFinite)||!Number.isInteger(i.z)||!Number.isInteger(r.z)||Math.min(i.z,r.z)\u003c0||Math.max(i.z,r.z)\u003e=e||t.viaDiameter\u003c=0)throw new Error(\"repair04 new-via guard requires valid colocated vias\");const s=o-1,a=[i.z,r.z];let c=Math.min(i.z,r.z),l=Math.max(i.z,r.z);for(;o+1\u003ct.route.length\u0026\u0026\"through_obstacle\"!==t.route[o].toNextSegmentType;){const n=t.route[o+1];if(n.x!==r.x||n.y!==r.y)break;if(!Number.isInteger(n.z)||n.z\u003c0||n.z\u003e=e)throw new Error(\"repair04 new-via guard found an invalid layer span\");n.z!==a.at(-1)\u0026\u0026a.push(n.z),c=Math.min(c,n.z),l=Math.max(l,n.z),o++}n.push({pointIndices:Array.from({length:o-s+1},(t,e)=\u003es+e),layerSequence:a,x:r.x,y:r.y,minZ:c,maxZ:l,diameter:t.viaDiameter,identity:JSON.stringify([r.x,r.y,c,l,t.viaDiameter])})}return n},N6=({srj:t,viaClearance:e=.1})=\u003e{const n=new Map,o=new Map,i=[e,t.defaultObstacleMargin??0,t.minViaEdgeToPadEdgeClearance??0],r=Math.max(...i),s=e=\u003e{const i=o.get(e.identity);if(i)return i;const s=[];for(let o=0;o\u003ct.obstacles.length;o++){const i=t.obstacles[o];let a=n.get(o);if(!a){const e=i.__zLayers??i.zLayers??i.layers.map(e=\u003e\"top\"===e?0:\"bottom\"===e?t.layerCount-1:/^inner\\d+$/.test(e)?Number(e.slice(5)):-1);if(e.some(e=\u003e!Number.isInteger(e)||e\u003c0||e\u003e=t.layerCount))throw new Error(\"repair04 new-via guard found an unknown obstacle layer\");a={zs:e},n.set(o,a)}if(!a.zs.some(t=\u003et\u003e=e.minZ\u0026\u0026t\u003c=e.maxZ))continue;if(!a.geometry){if(![i.center.x,i.center.y,i.width,i.height,i.ccwRotationDegrees??0].every(Number.isFinite)||i.width\u003c0||i.height\u003c0)throw new Error(\"repair04 new-via guard found invalid obstacle geometry\");const t=(i.ccwRotationDegrees??0)*Math.PI/180;a.geometry={x:i.center.x,y:i.center.y,cosine:Math.cos(t),sine:Math.sin(t),extent:Math.hypot(i.width,i.height)/2,bounds:{minX:-i.width/2,maxX:i.width/2,minY:-i.height/2,maxY:i.height/2}}}const c=a.geometry,l=c.extent+e.diameter/2+r+1e-8;if(Math.abs(e.x-c.x)\u003el||Math.abs(e.y-c.y)\u003el)continue;const d=e.x-c.x,h=e.y-c.y,u={x:d*c.cosine+h*c.sine,y:-d*c.sine+h*c.cosine},p=ke(u,u,c.bounds),m=e.diameter/2+r-p;m\u003c=1e-8||s.push({obstacleIndex:o,severity:m})}return o.set(e.identity,s),s};return({previousRoutes:e,routes:n,includeExistingVias:o=[]})=\u003e{if(e.length!==n.length)throw new Error(\"repair04 new-via guard requires matching route ordering\");if(i.some(t=\u003e!Number.isFinite(t)||t\u003c0))throw new Error(\"repair04 new-via guard requires nonnegative finite margins\");const r=[];for(let i=0;i\u003cn.length;i++){const a=n[i],c=e[i],l=new Set(a.connectionName===c.connectionName\u0026\u0026a.rootConnectionName===c.rootConnectionName?M6(c,t.layerCount).map(t=\u003et.identity):[]),d=M6(a,t.layerCount);for(let t=0;t\u003cd.length;t++){const e=d[t];if(!l.has(e.identity)||o.some(e=\u003ee.routeIndex===i\u0026\u0026e.viaIndex===t))for(const n of s(e))r.push({key:`new-via-pad:${i}:${n.obstacleIndex}:${t}`,routeIndex:i,obstacleIndex:n.obstacleIndex,center:{x:e.x,y:e.y},kind:\"via\",severity:n.severity})}}return r}},w6=t=\u003eN6(t)(t);function T6(t,e){return t.x\u003ee.minX+4e-8\u0026\u0026t.x\u003ce.maxX-4e-8\u0026\u0026t.y\u003ee.minY+4e-8\u0026\u0026t.y\u003ce.maxY-4e-8}function R6(t){const e=[];for(let n=1;n\u003ct.route.length;n++){const o=t.route[n-1],i=t.route[n];if(o.z!==i.z\u0026\u0026\"through_obstacle\"!==o.toNextSegmentType){if(o.x!==i.x||o.y!==i.y)throw new Error(\"repair04: a layer transition must have coincident endpoints\");e.some(t=\u003et.x===i.x\u0026\u0026t.y===i.y)||e.push({x:i.x,y:i.y})}}return{...t,vias:e}}function E6(t){const e=[];for(let n=1;n\u003ct.route.length;n++){const o=t.route[n-1],i=t.route[n];o.z!==i.z\u0026\u0026\"through_obstacle\"!==o.toNextSegmentType\u0026\u0026e.push([o.x,o.y,o.z,i.z])}return JSON.stringify([t.viaDiameter,e])}var A6=class extends kt{input;mutableBounds;engine;fixedTraces;routes;score=null;candidates=null;bestAdjustment=null;lockedPoints;evaluated=0;accepted=0;maxCandidates;candidateAttempts=0;pathSearchNodes=0;pathSearchCalls=0;viaBlockerPathSearchCalls=0;coupledPathSearchCalls=0;threeRoutePathSearchCalls=0;threeRoutePathSearchNodes=0;candidateScores=new Map;routeCache=new WeakMap;fixedObstacleNetContext;fixedObstacleEvaluator;viaPadEvaluator;viaGeometryCache=new WeakMap;constructor(t){if(super(),!Number.isFinite(t.boundaryMargin)||t.boundaryMargin\u003c=0)throw new Error(\"repair04: boundaryMargin must be positive and finite\");const e=t.bounds;if(![e.minX,e.maxX,e.minY,e.maxY].every(Number.isFinite)||e.maxX-e.minX\u003c10-1e-8||e.maxY-e.minY\u003c10-1e-8)throw new Error(\"repair04: bounds must be finite and at least 10 × 10 mm\");if(this.input=structuredClone(t),this.viaPadEvaluator=(({srj:t,viaClearance:e})=\u003eN6({srj:{layerCount:t.layerCount,obstacles:structuredClone(t.obstacles),defaultObstacleMargin:t.defaultObstacleMargin,minViaEdgeToPadEdgeClearance:t.minViaEdgeToPadEdgeClearance},viaClearance:e}))({srj:this.input.srj,viaClearance:this.input.viaClearance}),this.routes=structuredClone(t.routes),this.fixedObstacleNetContext=this.input.routes.map(t=\u003e({...t,route:[]})),this.fixedObstacleEvaluator=(t=\u003eC6({...t,srj:structuredClone(t.srj),routes:t.routes.map(t=\u003e({...t,route:[]}))}))({srj:this.input.srj,routes:this.fixedObstacleNetContext,traceClearance:this.input.traceClearance,viaClearance:this.input.viaClearance}),this.fixedTraces=(t.srj.traces??[]).map(e=\u003em1(e,t.srj.minTraceWidth)),this.mutableBounds={minX:e.minX+t.boundaryMargin,minY:e.minY+t.boundaryMargin,maxX:e.maxX-t.boundaryMargin,maxY:e.maxY-t.boundaryMargin},this.mutableBounds.minX\u003e=this.mutableBounds.maxX||this.mutableBounds.minY\u003e=this.mutableBounds.maxY)throw new Error(\"repair04: boundary collar leaves no mutable area\");if(t.lockedPointIndices.length!==t.routes.length)throw new Error(\"repair04: every route requires a lock mask\");this.lockedPoints=this.routes.map((e,n)=\u003e{if(t.lockedPointIndices[n].length!==e.route.length)throw new Error(\"repair04: lock mask length must match its route\");for(let t=1;t\u003ce.route.length;t++){const n=y6(e.route[t-1],e.route[t],this.mutableBounds);if(n?.some(t=\u003et\u003e1e-8\u0026\u0026t\u003c1-1e-8))throw new Error(\"repair04: boundary crossings require fixed cut points; use extractRepairRegion\")}return e.route.filter((o,i)=\u003et.lockedPointIndices[n][i]||0===i||i===e.route.length-1||o.pcb_port_id||o.insideJumperPad||o.toNextSegmentType||!T6(o,this.mutableBounds))});for(const e of t.movableVias??[]){const n=this.routes[e.routeIndex],o=n\u0026\u0026M6(n,t.srj.layerCount)[e.viaIndex];if(!o||o.pointIndices.some(t=\u003ethis.isLocked(e.routeIndex,n.route[t])))throw new Error(\"repair04: movable via must identify an unlocked existing via\")}for(const e of[\"maxCandidateAttempts\",\"maxPathSearchNodes\"]){const n=t[e];if(void 0!==n\u0026\u0026(!Number.isSafeInteger(n)||n\u003c1))throw new Error(`repair04: ${e} must be a positive safe integer`)}if(this.maxCandidates=t.maxCandidates??8e3,!Number.isInteger(this.maxCandidates)||this.maxCandidates\u003c1)throw new Error(\"repair04: maxCandidates must be a positive integer\");this.MAX_ITERATIONS=2*this.maxCandidates+4,this.engine=new R1(this.input.srj,{cacheStaticObstacleNetMembership:!0,cacheImmutableTraceGeometry:!0,useTransientDynamicQueryMarkers:!0,useConservativeRectObstaclePrecheck:!0,traceClearance:t.traceClearance??.1,viaClearance:t.viaClearance??.1,includeTraceViaOwnerMetadata:!0})}getWorkLimitReason(){return void 0!==this.input.maxCandidateAttempts\u0026\u0026this.candidateAttempts\u003e=this.input.maxCandidateAttempts?\"candidate-attempt-limit\":void 0!==this.input.maxPathSearchNodes\u0026\u0026this.pathSearchNodes\u003e=this.input.maxPathSearchNodes?\"path-search-node-limit\":null}updateWorkStats(t){void 0===this.input.maxCandidateAttempts\u0026\u0026void 0===this.input.maxPathSearchNodes||(this.stats={...this.stats,candidateAttempts:this.candidateAttempts,pathSearchNodes:this.pathSearchNodes,pathSearchCalls:this.pathSearchCalls,...void 0===t?{}:{completionReason:t}})}finishSearch(t){this.bestAdjustment\u0026\u0026(this.routes=this.bestAdjustment.routes,this.candidateScores.clear(),this.score=this.bestAdjustment.score,this.accepted++,this.bestAdjustment=null,this.stats={...this.stats,finalErrorCount:this.score.count,accepted:this.accepted}),this.updateWorkStats(t),this.solved=!0}getRouteCache(t,e){let n=this.routeCache.get(e);n||(n=new Map,this.routeCache.set(e,n));let o=n.get(t);return o||(o={},n.set(t,o)),o}getViaGeometry(t){let e=this.viaGeometryCache.get(t);return e||(e=M6(t,this.input.srj.layerCount),this.viaGeometryCache.set(t,e)),e}getViaPadViolations(t,e){return 0===t.length?this.viaPadEvaluator({previousRoutes:[],routes:[]}):t.flatMap((t,n)=\u003e{const o=this.getRouteCache(n,t),i=e?\"scoredViaViolations\":\"newViaViolations\";if(!o[i]){const r=e?!0!==this.input.allowLayerChanges||this.input.movableVias?.length?(this.input.movableVias??[]).filter(t=\u003et.routeIndex===n).map(t=\u003e({routeIndex:0,viaIndex:t.viaIndex})):this.getViaGeometry(t).flatMap((e,o)=\u003ee.pointIndices.every(e=\u003e!this.isLocked(n,t.route[e]))?[{routeIndex:0,viaIndex:o}]:[]):[];o[i]=this.viaPadEvaluator({previousRoutes:[e?t:this.input.routes[n]],routes:[t],includeExistingVias:r}).map(t=\u003e({...t,routeIndex:n,key:t.key.replace(\"new-via-pad:0:\",`new-via-pad:${n}:`)}))}return o[i]})}getFixedViolations(t){if(0===t.length)return this.fixedObstacleEvaluator(t);const e=t.flatMap((t,e)=\u003evoid 0===this.getRouteCache(e,t).fixedViolations?[e]:[]);if(e.length){const n=this.fixedObstacleNetContext.slice();for(const o of e)n[o]=t[o];const o=this.fixedObstacleEvaluator(n);for(const n of e)this.getRouteCache(n,t[n]).fixedViolations=[];for(const e of o)this.getRouteCache(e.routeIndex,t[e.routeIndex]).fixedViolations.push(e)}return t.flatMap((t,e)=\u003ethis.getRouteCache(e,t).fixedViolations).sort((t,e)=\u003et.obstacleIndex-e.obstacleIndex||t.routeIndex-e.routeIndex)}evaluate(t){const{errors:e}=this.engine.evaluate([...this.fixedTraces,...t.map((t,e)=\u003e{const n=this.getRouteCache(e,t);return n.trace||(n.trace=function(t,e){const n=t=\u003e0===t?\"top\":t===e-1?\"bottom\":`inner${t}`;return t.map((t,e)=\u003e{const o=[];for(let e=0;e\u003ct.route.length;e++){const i=t.route[e],r=t.route[e-1];r\u0026\u0026\"through_obstacle\"!==r.toNextSegmentType\u0026\u0026r.z!==i.z\u0026\u0026r.x===i.x\u0026\u0026r.y===i.y\u0026\u0026o.push({route_type:\"via\",x:i.x,y:i.y,from_layer:n(r.z),to_layer:n(i.z),via_diameter:t.viaDiameter});const s=i.traceThickness??t.traceThickness;o.push({route_type:\"wire\",x:i.x,y:i.y,layer:n(i.z),width:s,...0===e\u0026\u0026i.pcb_port_id?{start_pcb_port_id:i.pcb_port_id}:{},...e===t.route.length-1\u0026\u0026i.pcb_port_id?{end_pcb_port_id:i.pcb_port_id}:{}})}return{type:\"pcb_trace\",pcb_trace_id:`repair04_${e}`,connection_name:t.rootConnectionName??t.connectionName,route:o}})}([t],this.input.srj.layerCount)[0],n.trace.pcb_trace_id=`repair04_${e}`),n.trace})]),n=new Map;for(const o of this.getFixedViolations(t))n.set(o.key,o.severity),e.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:`repair04 fixed obstacle clearance: ${o.key}`,center:o.center,minimum_clearance:o.severity,actual_clearance:0,pcb_trace_id:`repair04_${o.routeIndex}`,pcb_trace_error_id:o.key});for(const n of this.getViaPadViolations(t,!0))e.push({type:\"pcb_trace_error\",error_type:\"pcb_trace_error\",message:`repair04 selected existing via pad clearance: ${n.key}`,center:n.center,minimum_clearance:n.severity,actual_clearance:0,pcb_trace_id:`repair04_${n.routeIndex}`,pcb_trace_error_id:n.key});let o=0;for(const t of e){const e=/gap: (-?[\\d.]+)/.exec(t.message),n=\"number\"==typeof t.actual_clearance?t.actual_clearance:e?Number(e[1]):null,i=\"number\"==typeof t.minimum_clearance?t.minimum_clearance:.1;o+=null!==n?Math.max(0,i-n):1}return{count:e.length,severity:o,errors:e,fixedViolations:n}}isLocked(t,e){return!T6(e,this.mutableBounds)||this.lockedPoints[t].some(t=\u003et.x===e.x\u0026\u0026t.y===e.y)}*generateTaperedSegmentCandidates(t){const e=new Set;for(const{ri:n,pi:o}of t){if(!this.score.errors.some(t=\u003et.pcb_trace_id===`repair04_${n}`))continue;const t=this.routes[n];for(const[i,r]of[[o-2,o+1],[o-2,o],[o-1,o+1],[o-1,o]]){if(e.size\u003e=8)return;if(i\u003c=0||r\u003e=t.route.length-1)continue;const o=`${n}:${i}:${r}`;if(e.has(o))continue;const s=t.route.slice(i,r+1),a=s[0].z;if(!T6(t.route[i-1],this.mutableBounds)||!T6(t.route[r+1],this.mutableBounds)||t.route[i-1].z!==a||t.route[r+1].z!==a||s.some(e=\u003ee.z!==a||this.isLocked(n,e)||Boolean(e.portPointId)||t.vias.some(t=\u003et.x===e.x\u0026\u0026t.y===e.y)))continue;if(!(new Set(s.map(e=\u003ee.traceThickness??t.traceThickness)).size\u003c2)){e.add(o);for(const e of[.1,.05])for(let o=0;o\u003c8;o++){const a=e*Math.cos(o*Math.PI/4),c=e*Math.sin(o*Math.PI/4),l=s.map(t=\u003e({...t,x:t.x+a,y:t.y+c}));l.some(t=\u003e!T6(t,this.mutableBounds))||(yield{routeIndex:n,route:{...t,route:[...t.route.slice(0,i),...l,...t.route.slice(r+1)]}})}}}}}*generateCrossingPairCandidates(){if(this.coupledPathSearchCalls\u003e=4||this.getWorkLimitReason())return;const t=new Set,e=this.score.errors.filter(t=\u003e\"pcb_trace_error\"===t.type\u0026\u0026\"number\"==typeof t.actual_clearance\u0026\u0026t.actual_clearance\u003c0\u0026\u0026void 0!==t.center);for(const n of e){const e=n.center,o=[];for(let t=0;t\u003cthis.routes.length;t++){const n=this.routes[t];if(!n.jumpers?.length)for(let i=1;i\u003cn.route.length;i++){const r=n.route[i-1],s=n.route[i],a=s.x-r.x,c=s.y-r.y,l=a*a+c*c;if(r.z!==s.z||l\u003c1e-12)continue;const d=((e.x-r.x)*a+(e.y-r.y)*c)/l;d\u003c0||d\u003e1||Math.hypot(e.x-r.x-d*a,e.y-r.y-d*c)\u003c1e-6\u0026\u0026o.push({ri:t,pi:i,a:r,b:s})}}for(let e=0;e\u003co.length;e++)for(let i=e+1;i\u003co.length;i++){let r=o[e],s=o[i];if(r.ri===s.ri||r.a.z!==s.a.z)continue;const a=n.pcb_trace_error_id;if(a!==`overlap_repair04_${r.ri}_repair04_${s.ri}`\u0026\u0026a!==`overlap_repair04_${s.ri}_repair04_${r.ri}`)continue;0===this.routes[r.ri].vias.length\u0026\u0026([r,s]=[s,r]);const c=this.routes[r.ri],l=this.routes[s.ri];if(0===c.vias.length||0!==l.vias.length)continue;const d=`${r.ri}:${s.ri}`;if(t.has(d))continue;t.add(d);let h=s.pi-1,u=s.pi;for(;h\u003e0\u0026\u0026!this.isLocked(s.ri,l.route[h]);)h--;for(;u\u003cl.route.length-1\u0026\u0026!this.isLocked(s.ri,l.route[u]);)u++;if(u-h\u003e64||u-h\u003c2||!T6(l.route[h],this.mutableBounds)||!T6(l.route[u],this.mutableBounds))continue;const p=l.route[h].traceThickness??l.traceThickness;if(l.route.slice(h,u+1).some(t=\u003et.z!==s.a.z||t.toNextSegmentType||t.insideJumperPad||(t.traceThickness??l.traceThickness)!==p))continue;const m=this.getViaGeometry(c),g=m.map((t,e)=\u003e({via:t,viaIndex:e,distance:Math.min(...t.pointIndices.map(t=\u003eMath.abs(t-r.pi)))})).sort((t,e)=\u003et.distance-e.distance)[0];if(!g||g.via.pointIndices.some(t=\u003ethis.isLocked(r.ri,c.route[t]))||this.input.movableVias?.length\u0026\u0026!this.input.movableVias.some(t=\u003et.routeIndex===r.ri\u0026\u0026t.viaIndex===g.viaIndex))continue;const f=Math.max(...g.via.pointIndices);let y=r.pi-1;for(;y\u003e0\u0026\u0026!this.isLocked(r.ri,c.route[y]);)y--;if(y\u003e=Math.min(...g.via.pointIndices))continue;const _=s.b.x-s.a.x,b=s.b.y-s.a.y,x=Math.abs(b)\u003e=Math.abs(_)?{x:1,y:0}:{x:0,y:1},v=2*(this.input.traceClearance??.1)+p;for(const t of[-1,1])for(const e of[2,1]){if(this.coupledPathSearchCalls\u003e=4||this.getWorkLimitReason())return;const n=f+e;if(n\u003e=c.route.length)continue;if(c.route.slice(y+1,n).some(t=\u003ethis.isLocked(r.ri,t)))continue;if(!T6(c.route[y],this.mutableBounds)||!T6(c.route[n],this.mutableBounds))continue;const o=c.route[y].traceThickness??c.traceThickness;if(c.route.slice(y,n+1).some(t=\u003et.toNextSegmentType||t.insideJumperPad||(t.traceThickness??c.traceThickness)!==o))continue;const i={...l,route:l.route.map((e,n)=\u003en\u003eh\u0026\u0026n\u003cu?{...e,x:e.x+t*x.x*v,y:e.y+t*x.y*v}:e)};if(i.route.some((t,e)=\u003ee\u003eh\u0026\u0026e\u003cu\u0026\u0026!T6(t,this.mutableBounds)))continue;const a=this.routes.slice();a[s.ri]=i;const d={nodesPopped:0,completionReason:\"no-path\"},p=Math.min(3e4,void 0===this.input.maxPathSearchNodes?3e4:this.input.maxPathSearchNodes-this.pathSearchNodes);if(p\u003c1)return;const g=g1({srj:this.input.srj,routes:a,routeIndex:r.ri,start:c.route[y],end:c.route[n],bounds:this.mutableBounds,traceThickness:o,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,gridSize:o\u003c=.1?o/2:.1,allowLayerChanges:!0,maxNodes:p,stats:d});if(this.coupledPathSearchCalls++,this.pathSearchCalls++,this.pathSearchNodes+=d.nodesPopped,this.updateWorkStats(),!g)continue;const _=R6({...c,route:[...c.route.slice(0,y),...g,...c.route.slice(n+1)]}),b=this.getViaGeometry(_);b.length!==m.length||b.some((t,e)=\u003et.diameter!==m[e].diameter||JSON.stringify(t.layerSequence)!==JSON.stringify(m[e].layerSequence))||(yield{routeIndex:r.ri,route:_,additionalRoutes:[{routeIndex:s.ri,route:i}]})}}}}*generateClearanceCandidates(t,e){const n=new Set;for(const{ri:o,pi:i}of t){if(n.size\u003e=12)break;const t=this.routes[o],r=n=\u003e{const i=t.route[n];return this.isLocked(o,i)||!e\u0026\u0026(n\u003e0\u0026\u0026t.route[n-1].z!==i.z||n+1\u003ct.route.length\u0026\u0026t.route[n+1].z!==i.z)};let s=i-1,a=i;for(;s\u003e0\u0026\u0026!r(s);)s--;for(;a\u003ct.route.length-1\u0026\u0026!r(a);)a++;const c=`${o}:${s}:${a}`;if(n.has(c))continue;n.add(c);const l=t.route[s],d=t.route[a];if(l.x===d.x\u0026\u0026l.y===d.y)continue;const h=t=\u003et.x\u003e=this.mutableBounds.minX-g6\u0026\u0026t.x\u003c=this.mutableBounds.maxX+g6\u0026\u0026t.y\u003e=this.mutableBounds.minY-g6\u0026\u0026t.y\u003c=this.mutableBounds.maxY+g6;if(!h(l)||!h(d))continue;const u=new Set(t.route.slice(s,a+1).map(e=\u003ee.traceThickness??t.traceThickness));if(1!==u.size)continue;const p=[...u][0];if(\"path-search-node-limit\"===this.getWorkLimitReason())return;const m={nodesPopped:0,completionReason:\"no-path\"},g=g1({maxNodes:void 0===this.input.maxPathSearchNodes?void 0:Math.min(3e4,this.input.maxPathSearchNodes-this.pathSearchNodes),stats:m,allowLayerChanges:e,srj:this.input.srj,routes:this.routes,routeIndex:o,start:l,end:d,bounds:this.mutableBounds,traceThickness:p,gridSize:p\u003c=.1?p/2:.1,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1});this.pathSearchCalls++,this.pathSearchNodes+=m.nodesPopped,this.updateWorkStats(),g\u0026\u0026(yield{routeIndex:o,route:R6({...t,route:[...t.route.slice(0,s),...g,...t.route.slice(a+1)]})})}}preservesViaPermissions(t,e){const n=this.input.routes[t],o=this.getViaGeometry(n),i=this.getViaGeometry(e);return e.connectionName===n.connectionName\u0026\u0026e.rootConnectionName===n.rootConnectionName\u0026\u0026e.viaDiameter===n.viaDiameter\u0026\u0026o.length===i.length\u0026\u0026o.every((e,n)=\u003e{const o=i[n];if(JSON.stringify(e.layerSequence)!==JSON.stringify(o.layerSequence)||e.diameter!==o.diameter)return!1;const r=this.input.movableVias?.some(e=\u003ee.routeIndex===t\u0026\u0026e.viaIndex===n);return!0===r||e.x===o.x\u0026\u0026e.y===o.y})}getIndexedViaIds(t,e,n){const o=new Set;if(1!==this.getViaGeometry(e).filter(t=\u003et.x===n.x\u0026\u0026t.y===n.y\u0026\u0026t.identity===n.identity).length)return o;const i=t=\u003e0===t?\"top\":t===this.input.srj.layerCount-1?\"bottom\":`inner${t}`,r=new Set;for(let t=1;t\u003cn.layerSequence.length;t++)r.add(`${n.x},${n.y},${i(n.layerSequence[t-1])},${i(n.layerSequence[t])}`);const s=this.routes.map((n,o)=\u003e{const i=this.getRouteCache(o,o===t?e:n).trace;if(!i)throw new Error(\"repair04: indexed via mapping requires an evaluated route\");return i}),a=new Set;for(const e of[...this.fixedTraces,...s])for(const n of e.route){if(\"via\"!==n.route_type)continue;const i=`${n.x},${n.y},${n.from_layer},${n.to_layer}`;if(a.has(i))continue;const c=`via_${a.size}`;a.add(i),e===s[t]\u0026\u0026r.has(i)\u0026\u0026o.add(c)}return o.size===r.size?o:new Set}*generateViaBlockerCandidates(t,e,n={}){if(this.viaBlockerPathSearchCalls\u003e=4||this.getWorkLimitReason())return;const o=e.evaluatedScore;if(!o||!this.score||e.additionalRoutes?.length||e.routeIndex!==t.routeIndex)return;if(!this.input.movableVias?.some(e=\u003ee.routeIndex===t.routeIndex\u0026\u0026e.viaIndex===t.viaIndex)||!this.preservesViaPermissions(t.routeIndex,e.route))return;if([...o.fixedViolations].some(([t,e])=\u003e!this.score.fixedViolations.has(t)||e\u003ethis.score.fixedViolations.get(t)+g6))return;const i=this.routes[t.routeIndex],r=this.getViaGeometry(i)[t.viaIndex],s=this.getViaGeometry(e.route)[t.viaIndex],a=n.oldIds??=this.getIndexedViaIds(t.routeIndex,i,r);if(!a.size)return;const c=`repair04_${t.routeIndex}`,l=(t,e)=\u003e{const n=t.pcb_via_id,o=t.pcb_trace_id;if(\"pcb_trace_error\"===t.type\u0026\u0026\"string\"==typeof n\u0026\u0026e.has(n)\u0026\u0026\"string\"==typeof o\u0026\u0026o!==c\u0026\u0026t.pcb_trace_error_id===`overlap_${o}_${n}`\u0026\u0026Array.isArray(t.pcb_trace_ids)\u0026\u00262===t.pcb_trace_ids.length\u0026\u0026t.pcb_trace_ids.includes(c)\u0026\u0026t.pcb_trace_ids.includes(o))return o},d=(t,e)=\u003e{const n=new Set;for(const o of t){const t=l(o,e);void 0!==t\u0026\u0026n.add(t)}return n},h=n.oldContacts??=d(this.score.errors,a);if(!h.size)return;if(n.oldNeighborFixed??=this.getFixedViolations(this.routes).some(t=\u003e\"wire\"===t.kind\u0026\u0026h.has(`repair04_${t.routeIndex}`)))return;const u=this.getIndexedViaIds(t.routeIndex,e.route,s);if(a.size!==u.size)return;for(const t of o.errors){if([t.pcb_via_id,...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids:[],...Array.isArray(t.pcb_pad_ids)?t.pcb_pad_ids:[]].some(t=\u003e\"string\"==typeof t\u0026\u0026u.has(t))\u0026\u0026void 0===l(t,u))return}const p=d(o.errors,u);if(1!==p.size||[...p].some(t=\u003eh.has(t)))return;const m=[...p][0];if(!/^repair04_(0|[1-9][0-9]*)$/.test(m))return;const g=Number(m.slice(9)),f=this.routes[g];if(!f||g===t.routeIndex||f.jumpers?.length||f.connectionName===i.connectionName||f.rootConnectionName\u0026\u0026f.rootConnectionName===i.rootConnectionName||f.route.some(t=\u003eBoolean(t.toNextSegmentType||t.insideJumperPad)))return;let y=-1,_=1/0;for(let t=1;t\u003cf.route.length;t++){const e=f.route[t-1],n=f.route[t];if(e.z!==n.z||e.z\u003cs.minZ||e.z\u003es.maxZ)continue;const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,a=r?Math.max(0,Math.min(1,((s.x-e.x)*o+(s.y-e.y)*i)/r)):0,c=Math.hypot(s.x-e.x-a*o,s.y-e.y-a*i);c\u003c_\u0026\u0026(_=c,y=t)}if(y\u003c1)return;const b=t=\u003e{const e=f.route[t];return this.isLocked(g,e)||t\u003e0\u0026\u0026f.route[t-1].z!==e.z||t+1\u003cf.route.length\u0026\u0026f.route[t+1].z!==e.z};let x=y-1,v=y;for(;x\u003e0\u0026\u0026!b(x);)x--;for(;v\u003cf.route.length-1\u0026\u0026!b(v);)v++;const S=f.route[x],I=f.route[v],C=t=\u003et.x\u003e=this.mutableBounds.minX-g6\u0026\u0026t.x\u003c=this.mutableBounds.maxX+g6\u0026\u0026t.y\u003e=this.mutableBounds.minY-g6\u0026\u0026t.y\u003c=this.mutableBounds.maxY+g6;if(S.z!==I.z||!C(S)||!C(I))return;const P=S.traceThickness??f.traceThickness;if(f.route.slice(x,v+1).some(t=\u003e(t.traceThickness??f.traceThickness)!==P))return;const M=Math.min(3e4,void 0===this.input.maxPathSearchNodes?3e4:this.input.maxPathSearchNodes-this.pathSearchNodes);if(M\u003c1)return;const N=this.routes.slice();N[t.routeIndex]=e.route;const w={nodesPopped:0,completionReason:\"no-path\"},T=g1({srj:this.input.srj,routes:N,routeIndex:g,start:I,end:S,bounds:this.mutableBounds,traceThickness:P,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,gridSize:Math.max(.025,P/4),allowLayerChanges:!1,maxNodes:M,stats:w});if(this.viaBlockerPathSearchCalls++,this.pathSearchCalls++,this.pathSearchNodes+=w.nodesPopped,this.updateWorkStats(),!T)return;T.reverse();const R={...f,route:[...f.route.slice(0,x),...T,...f.route.slice(v+1)]};E6(R)===E6(f)\u0026\u0026(yield{routeIndex:e.routeIndex,route:e.route,additionalRoutes:[{routeIndex:g,route:R}]})}*generateExistingViaCandidates(){for(const t of this.input.movableVias??[]){const e=this.routes[t.routeIndex],n=this.getViaGeometry(e)[t.viaIndex];if(n.pointIndices.some(n=\u003ethis.isLocked(t.routeIndex,e.route[n])))continue;const o={};for(const i of[.025,.05,.1,.2,.35,.5,.8,1.2])for(let r=0;r\u003c16;r++){const s=n.x+i*Math.cos(r*Math.PI/8),a=n.y+i*Math.sin(r*Math.PI/8);if(!T6({x:s,y:a,z:n.minZ},this.mutableBounds))continue;const c=e.route.map((t,e)=\u003en.pointIndices.includes(e)?{...t,x:s,y:a}:t),l={routeIndex:t.routeIndex,route:R6({...e,route:c})};yield l,yield*this.generateViaBlockerCandidates(t,l,o)}}}*generateCandidates(){yield*this.generateExistingViaCandidates();for(const t of!0===this.input.allowLayerChanges?!1===this.input.traceOnlyFirst?[!0]:[!1,!0]:[!1]){if(\"path-search-node-limit\"===this.getWorkLimitReason())return;const e=!0===this.input.allowLayerChanges?Math.min(512,Math.floor(this.maxCandidates/4)):Number.MAX_SAFE_INTEGER;if(!t\u0026\u00260===e)continue;let n=0;for(const o of this.generateCandidatesForMode(t)){if(!t){if([o,...o.additionalRoutes??[]].some(({routeIndex:t,route:e})=\u003ethis.input.movableVias?.length?!this.preservesViaPermissions(t,e):E6(e)!==E6(this.routes[t])))continue;if(n++\u003e=e)break}yield o}}}*generateCandidatesForMode(t){const e=this.score.errors.flatMap(t=\u003e{const e=t.center??t.pcb_center;return e?[e]:[]}),n=[];for(let t=0;t\u003cthis.routes.length;t++){const o=this.routes[t];if(!o.jumpers?.length\u0026\u0026!o.route.some(t=\u003et.toNextSegmentType||t.insideJumperPad))for(let i=1;i\u003co.route.length;i++){const r=o.route[i-1],s=o.route[i];if(r.toNextSegmentType||r.insideJumperPad||s.insideJumperPad)continue;let a=1/0,c=.5;const l=s.x-r.x,d=s.y-r.y,h=l*l+d*d;for(const t of e){const e=h?Math.max(0,Math.min(1,((t.x-r.x)*l+(t.y-r.y)*d)/h)):0,n=Math.hypot(t.x-r.x-e*l,t.y-r.y-e*d);n\u003ca\u0026\u0026(a=n,c=e)}a\u003c1.5\u0026\u0026n.push({ri:t,pi:i,distance:a,t:c})}}if(n.sort((t,e)=\u003et.distance-e.distance||t.ri-e.ri||t.pi-e.pi),this.threeRoutePathSearchCalls\u003c18\u0026\u0026!this.getWorkLimitReason()){const t=function*(t){const{routes:e}=t,n=t.violations.filter(t=\u003e\"wire\"===t.kind).sort((t,e)=\u003ee.severity-t.severity||t.routeIndex-e.routeIndex||t.obstacleIndex-e.obstacleIndex);if(!n.length||t.maxSearchCalls\u003c=0||t.remainingNodes()\u003c=0)return;const o=[];let i=0;const r=(t,e,n)=\u003e{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r?Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r)):0;return Math.hypot(t.x-e.x-s*o,t.y-e.y-s*i)},s=(t,e)=\u003e{const n=t.route[e],o=t.route[e-1],i=t.route[e+1];return void 0!==o\u0026\u0026o.z!==n.z||void 0!==i\u0026\u0026i.z!==n.z},a=e=\u003e{const n=t.bounds;return e.x\u003e=n.minX-1e-8\u0026\u0026e.x\u003c=n.maxX+1e-8\u0026\u0026e.y\u003e=n.minY-1e-8\u0026\u0026e.y\u003c=n.maxY+1e-8};for(let n=0;n\u003ce.length;n++){const i=e[n];if(i.jumpers?.length||i.route.some(t=\u003eBoolean(t.toNextSegmentType||t.insideJumperPad)))continue;const r=e=\u003et.isLocked(n,e)||s(i,e);for(let t=0;t\u003ci.route.length-1;){let e=t+1;if(i.route[t].z!==i.route[e].z){t=e;continue}for(;e\u003ci.route.length-1\u0026\u0026!r(e)\u0026\u0026i.route[e+1].z===i.route[t].z;)e++;const c=i.route[t].traceThickness??i.traceThickness;e\u003et\u0026\u0026a(i.route[t])\u0026\u0026a(i.route[e])\u0026\u0026i.route.slice(t,e+1).every(t=\u003e(t.traceThickness??i.traceThickness)===c)\u0026\u0026o.push({ri:n,a:t,b:e,z:i.route[t].z,width:c,distance:1/0,viaEnds:Number(s(i,t))+Number(s(i,e))}),t=e}}const c=new Set;for(const s of n){for(const t of o){t.distance=1/0;const n=e[t.ri];for(let e=t.a+1;e\u003c=t.b;e++)t.distance=Math.min(t.distance,r(s.center,n.route[e-1],n.route[e]))}const n=o.filter(t=\u003et.ri===s.routeIndex).sort((t,e)=\u003et.distance-e.distance||t.a-e.a)[0];if(!n||n.distance\u003e.5)continue;const a=e[n.ri],l=o.filter(t=\u003et.ri!==n.ri\u0026\u0026t.z===n.z\u0026\u0026t.distance\u003c1.5\u0026\u0026e[t.ri].connectionName!==a.connectionName\u0026\u0026(!a.rootConnectionName||e[t.ri].rootConnectionName!==a.rootConnectionName)).sort((t,e)=\u003et.distance-e.distance||t.ri-e.ri||t.a-e.a),d=l[0],h=l.find(t=\u003et.ri!==d?.ri);if(!d||!h)continue;const u=[n,d,h],p=u.map(t=\u003e`${t.ri}:${t.a}:${t.b}`).join(\"|\");if(c.has(p))continue;c.add(p);const m=d.viaEnds\u003e=h.viaEnds?1:2,g=3-m,f=[[m,0,g],[0,1,2],[0,2,1],[1,2,0],[2,1,0],[g,0,m]],y=new Set;for(const n of f){if(y.has(n.join()))continue;y.add(n.join());const o=e.map(t=\u003e({...t}));for(const t of u){const n=e[t.ri];o[t.ri]={...n,route:n.route.slice(0,t.a+1)},o.push({...n,route:n.route.slice(t.b)})}let r=!0;for(const s of n){if(i\u003e=t.maxSearchCalls||t.remainingNodes()\u003c=0)return;const n=u[s],a=e[n.ri],c={nodesPopped:0,completionReason:\"no-path\"},l=g1({srj:t.srj,routes:o,routeIndex:n.ri,start:a.route[n.b],end:a.route[n.a],bounds:t.bounds,traceThickness:n.width,traceClearance:t.traceClearance,viaClearance:t.viaClearance,gridSize:Math.max(.025,n.width/4),allowLayerChanges:!1,maxNodes:Math.min(3e4,t.remainingNodes()),stats:c});if(i++,t.onSearch(c),!l){r=!1;break}l.reverse(),o[n.ri]={...a,route:[...a.route.slice(0,n.a),...l,...a.route.slice(n.b+1)]},o[e.length+s].route=[]}r\u0026\u0026(yield u.map(t=\u003e({routeIndex:t.ri,route:o[t.ri]})))}}}({srj:this.input.srj,routes:this.routes,bounds:this.mutableBounds,violations:this.getFixedViolations(this.routes),isLocked:(t,e)=\u003ethis.isLocked(t,this.routes[t].route[e]),traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,maxSearchCalls:18-this.threeRoutePathSearchCalls,remainingNodes:()=\u003eMath.min(5e5-this.threeRoutePathSearchNodes,void 0===this.input.maxPathSearchNodes?Number.MAX_SAFE_INTEGER:this.input.maxPathSearchNodes-this.pathSearchNodes),onSearch:t=\u003e{this.threeRoutePathSearchCalls++,this.threeRoutePathSearchNodes+=t.nodesPopped,this.pathSearchCalls++,this.pathSearchNodes+=t.nodesPopped,this.updateWorkStats()}});for(const[e,...n]of t)e\u0026\u0026(yield{...e,additionalRoutes:n})}if(t\u0026\u0026(yield*this.generateCrossingPairCandidates()),yield*this.generateTaperedSegmentCandidates(n),yield*this.generateClearanceCandidates(n,t),\"path-search-node-limit\"===this.getWorkLimitReason())return;const o=new Set;for(const{ri:e,pi:i}of n.slice(0,80)){const n=this.routes[e];for(const r of[2,4,8,16]){const s=Math.max(0,i-r),a=Math.min(n.route.length-1,i+r),c=`${e}:${s}:${a}`;if(o.has(c))continue;o.add(c);const l=n.route[s],d=n.route[a];if(l.z!==d.z||!T6(l,this.mutableBounds)||!T6(d,this.mutableBounds))continue;if(n.route.slice(s+1,a).some(t=\u003ethis.isLocked(e,t)))continue;const h=new Set(n.route.slice(s,a+1).map(t=\u003et.traceThickness??n.traceThickness));if(1!==h.size)continue;const u=[...h][0],p=d.x-l.x,m=d.y-l.y,g=Math.hypot(p,m);if(!(g\u003c.1)){yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),...n.route.slice(a)]})};for(const t of[.15,-.15,.35,-.35,.7,-.7,1.5,-1.5])for(const o of[.2,0]){const i={x:l.x+p*o-m/g*t,y:l.y+m*o+p/g*t,z:l.z,traceThickness:u},r={x:l.x+p*(1-o)-m/g*t,y:l.y+m*(1-o)+p/g*t,z:l.z,traceThickness:u};T6(i,this.mutableBounds)\u0026\u0026T6(r,this.mutableBounds)\u0026\u0026(yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),i,r,...n.route.slice(a)]})})}if(t\u0026\u0026g\u003e2*n.viaDiameter+.3)for(let t=0;t\u003cthis.input.srj.layerCount;t++){if(t===l.z)continue;const o={x:l.x+.2*p,y:l.y+.2*m,z:l.z,traceThickness:u},i={x:l.x+.8*p,y:l.y+.8*m,z:l.z,traceThickness:u};yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),o,{...o,z:t},{...i,z:t},i,...n.route.slice(a)]})}}}}}const i=new Set;for(const{ri:e,pi:o,t:r}of n){const n=this.routes[e],s=n.route[o-1],a=n.route[o];for(const t of[o-1,o]){const o=n.route[t],r=`${e}:${o.x}:${o.y}`;if(i.has(r))continue;i.add(r);const s=n.route.map((t,e)=\u003et.x===o.x\u0026\u0026t.y===o.y?e:-1).filter(t=\u003et\u003e=0);if(!s.some(t=\u003ethis.isLocked(e,n.route[t])))for(const t of[.025,.05,.1,.2,.35,.5,.8,1.2])for(let o=0;o\u003c16;o++){const i=t*Math.cos(o*Math.PI/8),r=t*Math.sin(o*Math.PI/8),a=n.route.map((t,e)=\u003es.includes(e)?{...t,x:t.x+i,y:t.y+r}:t);s.some(t=\u003e!T6(a[t],this.mutableBounds))||(yield{routeIndex:e,route:R6({...n,route:a})})}}const c=t=\u003et.x\u003e=this.mutableBounds.minX-1e-8\u0026\u0026t.x\u003c=this.mutableBounds.maxX+1e-8\u0026\u0026t.y\u003e=this.mutableBounds.minY-1e-8\u0026\u0026t.y\u003c=this.mutableBounds.maxY+1e-8;if(s.z!==a.z||!c(s)||!c(a))continue;const l=a.x-s.x,d=a.y-s.y,h=Math.hypot(l,d);if(h\u003c.02)continue;const u=Math.max(s.traceThickness??n.traceThickness,a.traceThickness??n.traceThickness),p=l/h,m=d/h;for(const i of[.4,.8,1.5,3]){const a=Math.max(0,r*h-i),c=Math.min(h,r*h+i);for(const t of[.12,-.12,.25,-.25,.5,-.5,1,-1]){const i={x:s.x+p*a-m*t,y:s.y+m*a+p*t,z:s.z,traceThickness:u},r={x:s.x+p*c-m*t,y:s.y+m*c+p*t,z:s.z,traceThickness:u};T6(i,this.mutableBounds)\u0026\u0026T6(r,this.mutableBounds)\u0026\u0026(yield{routeIndex:e,route:{...n,route:[...n.route.slice(0,o),i,r,...n.route.slice(o)]}})}if(!t||c-a\u003cn.viaDiameter+.15)continue;const l={x:s.x+p*a,y:s.y+m*a,z:s.z,traceThickness:u},d={x:s.x+p*c,y:s.y+m*c,z:s.z,traceThickness:u};if(T6(l,this.mutableBounds)\u0026\u0026T6(d,this.mutableBounds))for(let t=0;t\u003cthis.input.srj.layerCount;t++){if(t===s.z)continue;const i=[l,{...l,z:t},{...d,z:t},d];yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,o),...i,...n.route.slice(o)]})}}}}}_step(){this.score||(this.score=this.evaluate(this.routes),this.stats={initialErrorCount:this.score.count,finalErrorCount:this.score.count,candidates:0,accepted:0},this.candidates=this.generateCandidates(),this.updateWorkStats());const t=this.getWorkLimitReason();if(0===this.score.count||this.evaluated\u003e=this.maxCandidates||t)return void this.finishSearch(0===this.score.count?\"clean\":this.evaluated\u003e=this.maxCandidates?\"candidate-limit\":t);const e=this.candidates.next();if(e.done){const t=this.getWorkLimitReason();return t?void this.finishSearch(t):void(this.bestAdjustment?(this.routes=this.bestAdjustment.routes,this.candidateScores.clear(),this.score=this.bestAdjustment.score,this.bestAdjustment=null,this.accepted++,this.candidates=this.generateCandidates()):(this.updateWorkStats(\"search-exhausted\"),this.solved=!0))}this.candidateAttempts++,this.updateWorkStats();const n=[e.value,...e.value.additionalRoutes??[]];if((!0!==this.input.allowLayerChanges||this.input.movableVias?.length)\u0026\u0026n.some(({routeIndex:t,route:e})=\u003e!this.preservesViaPermissions(t,e)))return;const o=this.routes.slice();for(const{routeIndex:t,route:e}of n)o[t]=e;const i=new Map;for(const t of this.getFixedViolations(o))i.set(t.key,t.severity);const r=[...i].every(([t,e])=\u003ethis.score.fixedViolations.has(t)\u0026\u0026e\u003c=this.score.fixedViolations.get(t)+g6),s=0===this.getViaPadViolations(o,!1).length;let a;if(s\u0026\u0026r){const t=JSON.stringify([e.value.routeIndex,e.value.route,...e.value.additionalRoutes??[]]);a=this.candidateScores.get(t),a||(a=this.evaluate(o),this.candidateScores.size\u003e=128\u0026\u0026this.candidateScores.delete(this.candidateScores.keys().next().value),this.candidateScores.set(t,a))}e.value.evaluatedScore=a,this.evaluated++,a\u0026\u0026s\u0026\u0026r\u0026\u0026a.count\u003cthis.score.count?(this.routes=o,this.candidateScores.clear(),this.score=a,this.accepted++,this.bestAdjustment=null,this.candidates=this.generateCandidates()):a\u0026\u0026r\u0026\u0026s\u0026\u0026a.count===this.score.count\u0026\u0026a.severity\u003c(this.bestAdjustment?.score.severity??this.score.severity)-1e-6\u0026\u0026(this.bestAdjustment={routes:o,score:a}),this.stats={...this.stats,finalErrorCount:this.score.count,candidates:this.evaluated,accepted:this.accepted},this.progress=this.evaluated/this.maxCandidates}getConstructorParams(){return[structuredClone(this.input)]}getOutput(){if(!this.solved||this.failed)throw new Error(\"repair04: getOutput requires a completed solve\");return structuredClone(this.routes)}visualize(){const t=this.input.bounds,e=this.mutableBounds;return{title:\"repair04 — fixed boundary, local copper repair\",rects:[{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,stroke:\"#64748b\",fill:\"rgba(148,163,184,0.15)\"},{center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,stroke:\"#0891b2\",fill:\"transparent\"},...this.input.srj.obstacles.map(t=\u003e({center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,fill:\"rgba(239,68,68,0.22)\",stroke:\"#b91c1c\",layer:`z${t.layers.map(t=\u003e\"top\"===t?0:\"bottom\"===t?this.input.srj.layerCount-1:Number(t.slice(5))).join(\",\")}`}))],lines:this.routes.flatMap(t=\u003et.route.slice(1).flatMap((e,n)=\u003ee.z===t.route[n].z?[{points:[t.route[n],e],strokeColor:0===e.z?\"#dc2626\":\"rgba(37,99,235,0.65)\",strokeWidth:e.traceThickness??t.traceThickness,...0===e.z?{}:{strokeDash:[.2,.12]},layer:`z${e.z}`}]:[])),circles:this.routes.flatMap(t=\u003et.vias.map(e=\u003e{const n=t.route.filter(t=\u003et.x===e.x\u0026\u0026t.y===e.y).map(t=\u003et.z),o=Math.min(...n),i=Math.max(...n);return{center:e,radius:t.viaDiameter/2,fill:\"rgba(37,99,235,0.65)\",stroke:\"#1e40af\",layer:`z${Array.from({length:i-o+1},(t,e)=\u003eo+e).join(\",\")}`}})),points:this.lockedPoints.flat().map(t=\u003e({...t,color:\"#0f172a\",layer:`z${t.z}`}))}}},O6=(t,e,n)=\u003e{if(n\u003c=g6)return structuredClone(t);if(n\u003e=.99999999)return structuredClone(e);const o={...structuredClone(t),x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n};return delete o.start_pcb_port_id,delete o.end_pcb_port_id,o},k6=(t,e)=\u003e{const n=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,s=e.start.x-t.start.x,a=e.start.y-t.start.y,c=n*r-o*i,l=(t,e)=\u003e({x:t.start.x+(t.end.x-t.start.x)*e,y:t.start.y+(t.end.y-t.start.y)*e}),d=(t,e)=\u003e{const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=n*n+o*o,r=i\u003e10000000000000001e-32?Math.max(0,Math.min(1,((t.x-e.start.x)*n+(t.y-e.start.y)*o)/i)):0;return l(e,r)};if(Math.abs(c)\u003eg6){const e=(s*r-a*i)/c,d=(s*o-a*n)/c;if(e\u003e=0\u0026\u0026e\u003c=1\u0026\u0026d\u003e=0\u0026\u0026d\u003c=1){const n=l(t,e);return[n,n]}}else{const i=n*n+o*o;if(i\u003e10000000000000001e-32){const r=(s*n+a*o)/i,c=((e.end.x-t.start.x)*n+(e.end.y-t.start.y)*o)/i,h=Math.max(0,Math.min(r,c)),u=Math.min(1,Math.max(r,c));if(h\u003c=u){const n=l(t,(h+u)/2);return[n,d(n,e)]}}}const h=[[t.start,d(t.start,e)],[t.end,d(t.end,e)],[d(e.start,t),e.start],[d(e.end,t),e.end]];return h.sort((t,e)=\u003eMath.hypot(t[0].x-t[1].x,t[0].y-t[1].y)-Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y)),h[0]},L6=(t,e)=\u003e{const n=\"top\"===t?0:\"bottom\"===t?e-1:/^inner\\d+$/.test(t)?Number(t.slice(5)):-1;if(!Number.isInteger(n)||n\u003c0||n\u003e=e)throw new Error(`repair04 preload has an unknown layer: ${t}`);return n},D6=(t,e,n)=\u003e{const o=((t,e)=\u003e{const n=new Map,o=t=\u003e{const e=n.get(t);if(void 0===e||e===t)return t;const i=o(e);return n.set(t,i),i},i=t=\u003e{const e=t.filter(t=\u003e\"string\"==typeof t\u0026\u0026t.length\u003e0);if(0===e.length)return;const i=o(e[0]);for(const t of e)n.set(o(t),i)};for(const e of t.connections){const t=e;i([t.name,t.rootConnectionName,t.netConnectionName,t.__netConnectionName,...t.mergedConnectionNames??[],...t.__rootConnectionNames??[]])}for(const t of e)i([t.connectionName,t.rootConnectionName]);for(const e of t.traces??[])i([e.connection_name,...e.connectsTo??[]]);return o})(t,e),i=e.map((t,e)=\u003ee),r=t=\u003e{const e=i[t];if(e===t)return t;const n=r(e);return i[t]=n,n},s=new Map;for(let t=0;t\u003ce.length;t+=1){const n=e[t];for(const e of[n.route[0],n.route.at(-1)]){if(!e?.pcb_port_id)continue;const a=JSON.stringify([o(n.connectionName),e.pcb_port_id,e.x,e.y,e.z]),c=s.get(a);void 0===c?s.set(a,t):i[r(t)]=r(c)}}const a=(t,e)=\u003e!(!t.startsWith(\"route:\")||!e.startsWith(\"route:\"))\u0026\u0026r(Number(t.slice(6)))===r(Number(e.slice(6))),c=[],l=[],d=[],h=e.map(()=\u003e({segmentTimes:new Map,viaPositions:[]})),u=t=\u003e{if(f6(t,n)){d.push(t);for(let e=t.minZ;e\u003c=t.maxZ;e+=1)c.push({x:t.x,y:t.y,z:e,radius:t.radius,net:t.net,source:t.source,...void 0!==t.routeIndex?{viaOwner:t.routeIndex}:{}})}};for(let t=0;t\u003ce.length;t+=1){const i=e[t],r=o(i.connectionName),s=`route:${t}`;for(let e=0;e\u003ci.route.length;e+=1){const o=i.route[e];if((0===e||e===i.route.length-1||o.pcb_port_id)\u0026\u0026f6(o,n)\u0026\u0026c.push({x:o.x,y:o.y,z:o.z,radius:(o.traceThickness??i.traceThickness)/2,net:r,source:s}),0===e)continue;const a=i.route[e-1];\"through_obstacle\"!==a.toNextSegmentType\u0026\u0026(a.z===o.z?l.push({start:a,end:o,z:o.z,radius:Math.max(a.traceThickness??i.traceThickness,o.traceThickness??i.traceThickness)/2,net:r,source:s,routeIndex:t,segmentIndex:e-1}):u({x:o.x,y:o.y,minZ:Math.min(a.z,o.z),maxZ:Math.max(a.z,o.z),radius:i.viaDiameter/2,net:r,source:s,routeIndex:t}))}}for(let e=0;e\u003c(t.traces??[]).length;e+=1){const i=m1(t.traces[e],t.minTraceWidth),r=o(i.connection_name),s=`fixed:${e}`;for(let e=0;e\u003ci.route.length;e+=1){const o=i.route[e],a=i.route[e-1];if(\"wire\"===o.route_type){const d=L6(o.layer,t.layerCount);(0===e||e===i.route.length-1||o.start_pcb_port_id||o.end_pcb_port_id)\u0026\u0026f6(o,n)\u0026\u0026c.push({x:o.x,y:o.y,z:d,radius:o.width/2,net:r,source:s}),\"wire\"===a?.route_type\u0026\u0026a.layer===o.layer\u0026\u0026l.push({start:a,end:o,z:d,radius:Math.max(a.width,o.width)/2,net:r,source:s})}else if(\"via\"===o.route_type){const e=L6(o.from_layer,t.layerCount),n=L6(o.to_layer,t.layerCount);u({x:o.x,y:o.y,minZ:Math.min(e,n),maxZ:Math.max(e,n),radius:(o.via_diameter??t.minViaDiameter??.3)/2,net:r,source:s})}}}const p=new Map;for(const t of c){const e=JSON.stringify([t.net,t.z]),n=p.get(e)??[];n.push(t),p.set(e,n)}const m=(t,e)=\u003e{if(void 0===t)return;const n=h[t].viaPositions;n.some(t=\u003eMath.hypot(t.x-e.x,t.y-e.y)\u003c=g6)||n.push({x:e.x,y:e.y})};for(const t of l){if(!y6(t.start,t.end,n))continue;const e=t.end.x-t.start.x,o=t.end.y-t.start.y,i=e*e+o*o;if(!(i\u003c=10000000000000001e-32))for(const r of p.get(JSON.stringify([t.net,t.z]))??[]){if(r.source===t.source||a(r.source,t.source))continue;const s=Math.max(0,Math.min(1,((r.x-t.start.x)*e+(r.y-t.start.y)*o)/i)),c={x:t.start.x+e*s,y:t.start.y+o*s};if(f6(c,n)\u0026\u0026!(Math.hypot(c.x-r.x,c.y-r.y)\u003et.radius+r.radius+g6)){if(void 0!==t.routeIndex\u0026\u0026void 0!==t.segmentIndex){const e=h[t.routeIndex].segmentTimes.get(t.segmentIndex)??[];e.some(t=\u003eMath.abs(t-s)\u003c=g6)||e.push(s),h[t.routeIndex].segmentTimes.set(t.segmentIndex,e)}m(r.viaOwner,r)}}}for(const t of d)for(let e=t.minZ;e\u003c=t.maxZ;e+=1)for(const n of p.get(JSON.stringify([t.net,e]))??[])n.source===t.source||a(n.source,t.source)||Math.hypot(t.x-n.x,t.y-n.y)\u003et.radius+n.radius+g6||(m(t.routeIndex,t),m(n.viaOwner,n));return((t,e,n,o)=\u003e{const i=new Map,r=new Set,s=[],a=(t,e)=\u003e{if(void 0===t.routeIndex||void 0===t.segmentIndex)return;const o=t.end.x-t.start.x,i=t.end.y-t.start.y,r=o*o+i*i;if(r\u003c=10000000000000001e-32)return;const s=Math.max(0,Math.min(1,((e.x-t.start.x)*o+(e.y-t.start.y)*i)/r)),a=n[t.routeIndex].segmentTimes.get(t.segmentIndex)??[];a.some(t=\u003eMath.abs(t-s)\u003c=g6)||a.push(s),n[t.routeIndex].segmentTimes.set(t.segmentIndex,a)};for(const n of t){const t=y6(n.start,n.end,e);if(!t||t[1]-t[0]\u003c=g6)continue;const c=t=\u003e({x:n.start.x+(n.end.x-n.start.x)*t,y:n.start.y+(n.end.y-n.start.y)*t}),l={...n,start:c(t[0]),end:c(t[1])},d=s.length;s.push({original:n,clipped:l});const h=Math.floor((Math.min(l.start.x,l.end.x)-l.radius)/2),u=Math.floor((Math.max(l.start.x,l.end.x)+l.radius)/2),p=Math.floor((Math.min(l.start.y,l.end.y)-l.radius)/2),m=Math.floor((Math.max(l.start.y,l.end.y)+l.radius)/2);for(let t=h;t\u003c=u;t+=1)for(let e=p;e\u003c=m;e+=1){const c=JSON.stringify([l.net,l.z,t,e]),h=i.get(c)??[];for(const t of h){const e=s[t];if(e.original.source===n.source||o(e.original.source,n.source)||void 0===e.original.routeIndex\u0026\u0026void 0===n.routeIndex)continue;const i=`${t}:${d}`;if(r.has(i))continue;r.add(i);const[c,h]=k6(l,e.clipped);Math.hypot(c.x-h.x,c.y-h.y)\u003el.radius+e.clipped.radius+g6||(a(n,c),a(e.original,h))}h.push(d),i.set(c,h)}}})(l,n,h,a),h},z6=(t,e)=\u003e({minX:t.minX-e,maxX:t.maxX+e,minY:t.minY-e,maxY:t.maxY+e}),F6=(t,e,n,o)=\u003e{const i=[];let r;const s=t.route,a=t=\u003e0===t||t===s.length-1||void 0!==s[t]?.pcb_port_id,c=()=\u003e{void 0!==r\u0026\u0026r.points.length\u003e0\u0026\u0026(r.locks[0]=!0,r.locks[r.points.length-1]=!0,i.push(r)),r=void 0};if(1===s.length\u0026\u0026s[0]\u0026\u0026f6(s[0],e))return[{points:structuredClone(s),locks:[!0],start:{segmentIndex:0,t:0},end:{segmentIndex:0,t:0}}];for(let i=0;i\u003cs.length-1;i+=1){const l=s[i],d=s[i+1];if(!l||!d)throw new Error(\"repair04 found a missing route point\");if(![l.x,l.y,l.z,d.x,d.y,d.z].every(Number.isFinite))throw new Error(\"repair04 route coordinates must be finite\");if(l.z!==d.z\u0026\u0026!b6({x:l.x,y:l.y},{x:d.x,y:d.y})\u0026\u0026\"through_obstacle\"!==l.toNextSegmentType)throw new Error(\"repair04 requires colocated points at a via transition\");const h=y6(l,d,e);if(!h){c();continue}const[u,p]=h;if(p-u\u003c=g6\u0026\u0026!b6(l,d)){c();continue}const m=y6(l,d,n),g=[u,p],f=o.segmentTimes.get(i)??[];for(const t of f)t\u003e=u-g6\u0026\u0026t\u003c=p+g6\u0026\u0026g.push(Math.max(u,Math.min(p,t)));if(m\u0026\u0026l.z===d.z)for(const t of m)t\u003eu+g6\u0026\u0026t\u003cp-g6\u0026\u0026g.push(t);g.sort((t,e)=\u003et-e);const y=g.filter((t,e)=\u003e0===e||Math.abs(t-g[e-1])\u003eg6),_=_6(l,d,u);r\u0026\u0026!b6(r.points[r.points.length-1],_)\u0026\u0026c(),r||(r={points:[],locks:[],start:{segmentIndex:i,t:u},end:{segmentIndex:i,t:p}});for(const e of y){const s=_6(l,d,e),c=e\u003c=g6?i:e\u003e=.99999999?i+1:void 0,h=!f6(s,n,4e-8)||f.some(t=\u003eMath.abs(t-e)\u003c=g6)||o.viaPositions.some(t=\u003eMath.hypot(t.x-s.x,t.y-s.y)\u003c=g6)||void 0!==c\u0026\u0026a(c)||\"through_obstacle\"===l.toNextSegmentType||\"through_obstacle\"===s.toNextSegmentType||!0===l.insideJumperPad||!0===d.insideJumperPad||(t.jumpers??[]).some(t=\u003eb6(s,{...t.start,z:s.z})||b6(s,{...t.end,z:s.z})),u=r.points[r.points.length-1];u\u0026\u0026b6(u,s)?r.locks[r.locks.length-1]=r.locks[r.locks.length-1]||h:(r.points.push(s),r.locks.push(h))}r.end={segmentIndex:i,t:p},p\u003c.99999999\u0026\u0026c()}c();for(const t of i)for(let e=1;e\u003ct.points.length;e+=1){const n=t.points[e-1],o=t.points[e];if(n.z!==o.z\u0026\u0026(t.locks[e-1]||t.locks[e])){let n=e-1,i=e;for(;n\u003e0\u0026\u0026b6({x:t.points[n-1].x,y:t.points[n-1].y},{x:o.x,y:o.y});)n-=1;for(;i+1\u003ct.points.length\u0026\u0026b6({x:t.points[i+1].x,y:t.points[i+1].y},{x:o.x,y:o.y});)i+=1;for(let e=n;e\u003c=i;e+=1)t.locks[e]=!0}}return i},B6=(t,e)=\u003e{const n=t.bounds,o=t.outline\u0026\u0026t.outline.length\u003e=3?t.outline:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}],i=[];for(let n=0;n\u003co.length;n+=1){const r=o[n],s=o[(n+1)%o.length],a=y6(r,s,e);if(!a)continue;const c=s.x-r.x,l=s.y-r.y,d=Math.hypot(c,l);if(d\u003c=g6)continue;const h=(a[0]+a[1])/2;i.push({obstacleId:`repair04_board_edge_${n}`,type:\"rect\",center:{x:r.x+c*h,y:r.y+l*h},width:d*(a[1]-a[0]),height:Math.max(2*(t.minBoardEdgeClearance??0),g6),ccwRotationDegrees:180*Math.atan2(l,c)/Math.PI,layers:Array.from({length:t.layerCount},(e,n)=\u003e0===n?\"top\":n===t.layerCount-1?\"bottom\":`inner${n}`),zLayers:Array.from({length:t.layerCount},(t,e)=\u003ee),connectedTo:[]})}return i},j6=({srj:t,routes:e,bounds:n,boundaryMargin:o=.5,clearanceHalo:i})=\u003e{if((t=\u003e{if(!Object.values(t).every(Number.isFinite))throw new Error(\"repair04 bounds must contain finite coordinates\");if(t.maxX-t.minX\u003c9.99999999||t.maxY-t.minY\u003c9.99999999)throw new Error(\"repair04 requires bounds at least 10 mm by 10 mm\")})(n),!Number.isFinite(o)||o\u003c0||void 0!==i\u0026\u0026(!Number.isFinite(i)||i\u003c0))throw new Error(\"repair04 collar and halo must be finite and nonnegative\");const r=Math.max(t.defaultObstacleMargin??.2,t.minTraceToPadEdgeClearance??0,t.minViaEdgeToPadEdgeClearance??0);let s=Math.max(t.minTraceWidth,t.minViaDiameter??0);for(const t of e){s=Math.max(s,t.traceThickness,t.viaDiameter);for(const e of t.route)s=Math.max(s,e.traceThickness??0)}for(const e of t.traces??[])for(const n of e.route)\"wire\"===n.route_type\u0026\u0026(s=Math.max(s,n.width)),\"via\"===n.route_type\u0026\u0026(s=Math.max(s,n.via_diameter??t.minViaDiameter??.3));if(!Number.isFinite(s)||s\u003c=0)throw new Error(\"repair04 requires finite positive copper widths\");const a=Math.max(o,s+r);if(2*a\u003e=Math.min(n.maxX-n.minX,n.maxY-n.minY))throw new Error(\"repair04 bounds are too small for their required copper safety collar\");const c=z6(n,Math.max(i??a,r+s)),l=z6(n,-a),d=D6(t,e,c),h=((t,e,n)=\u003e{const o=[];for(const i of t){const t=m1(i,n),r=[];let s=[];const a=()=\u003e{s.length\u003e0\u0026\u0026r.push(s),s=[]},c=t=\u003e{x6(s[s.length-1])!==x6(t)\u0026\u0026s.push(structuredClone(t))};for(let n=0;n\u003ct.route.length;n+=1){const o=t.route[n],i=t.route[n-1];if(\"wire\"===o.route_type\u0026\u0026\"wire\"===i?.route_type\u0026\u0026o.layer===i.layer){const t=y6(i,o,e);if(!t){a();continue}const n=O6(i,o,t[0]),r=O6(i,o,t[1]),l=s[s.length-1];\"wire\"===l?.route_type\u0026\u0026(l.layer!==n.layer||Math.hypot(l.x-n.x,l.y-n.y)\u003eg6)\u0026\u0026a(),c(n),c(r),t[1]\u003c.99999999\u0026\u0026a()}else if(\"via\"===o.route_type){if(!f6(o,e)){a();continue}if(\"wire\"!==i?.route_type)throw new Error(\"repair04 normalized preload via has no incoming wire\");c(i),c(o);const r=t.route[n+1];if(\"wire\"!==r?.route_type)throw new Error(\"repair04 normalized preload via has no outgoing wire\");c(r)}else if(\"wire\"===o.route_type)f6(o,e)\u0026\u0026c(o);else if(\"start\"in o\u0026\u0026\"end\"in o){const t=y6(o.start,o.end,e);if(!t){a();continue}const n=t=\u003e({x:o.start.x+(o.end.x-o.start.x)*t,y:o.start.y+(o.end.y-o.start.y)*t});c({...structuredClone(o),start:n(t[0]),end:n(t[1])}),t[1]\u003c.99999999\u0026\u0026a()}}a();for(let t=0;t\u003cr.length;t+=1)o.push({...structuredClone(i),pcb_trace_id:1===r.length?i.pcb_trace_id:`${i.pcb_trace_id}__repair04_fixed_${t}`,route:r[t]})}return o})(t.traces??[],c,t.minTraceWidth),u=[],p=[],m=[];for(let t=0;t\u003ce.length;t+=1){const n=e[t];for(const e of F6(n,c,l,d[t])){const o={...structuredClone(Object.fromEntries(Object.entries(n).filter(([t])=\u003e\"route\"!==t\u0026\u0026\"vias\"!==t\u0026\u0026\"jumpers\"!==t))),connectionName:n.connectionName,traceThickness:n.traceThickness,viaDiameter:n.viaDiameter,route:e.points,vias:n.vias.filter(t=\u003ee.points.some(e=\u003eMath.abs(e.x-t.x)\u003c=g6\u0026\u0026Math.abs(e.y-t.y)\u003c=g6)).map(t=\u003estructuredClone(t)),...void 0!==n.jumpers?{jumpers:n.jumpers.filter(t=\u003evoid 0!==y6(t.start,t.end,c)).map(t=\u003estructuredClone(t))}:{}};u.push(o),p.push(e.locks),m.push({sourceRouteIndex:t,start:e.start,end:e.end,sourceGeometryKey:S6(n,e.start.segmentIndex+e.start.t,e.end.segmentIndex+e.end.t),originalFragment:structuredClone(o)})}}const g=new Set([...u.flatMap(t=\u003e[t.connectionName,...t.rootConnectionName?[t.rootConnectionName]:[]]),...h.map(t=\u003et.connection_name)]),f=t.connections.filter(t=\u003eg.has(t.name)||t.pointsToConnect.some(t=\u003ef6(t,c))).map(t=\u003e({...structuredClone(Object.fromEntries(Object.entries(t).filter(([t])=\u003e\"pointsToConnect\"!==t))),name:t.name,pointsToConnect:t.pointsToConnect.filter(t=\u003ef6(t,c)).map(t=\u003estructuredClone(t))}));for(let e=0;e\u003cu.length;e+=1){const n=u[e];let o=f.find(t=\u003et.name===n.connectionName);o||(o={name:n.connectionName,...n.rootConnectionName?{rootConnectionName:n.rootConnectionName}:{},pointsToConnect:[]},f.push(o));for(const[i,r]of[[\"start\",n.route[0]],[\"end\",n.route[n.route.length-1]]]){if(!r)continue;const n=0===r.z?\"top\":r.z===t.layerCount-1?\"bottom\":`inner${r.z}`;o.pointsToConnect.some(t=\u003eMath.abs(t.x-r.x)\u003c=g6\u0026\u0026Math.abs(t.y-r.y)\u003c=g6\u0026\u0026(\"layer\"in t?t.layer===n:t.layers.includes(n)))||o.pointsToConnect.push({x:r.x,y:r.y,layer:n,pointId:`repair04_${e}_${i}`,...r.pcb_port_id?{pcb_port_id:r.pcb_port_id}:{}})}}const y={...Object.fromEntries(Object.entries(t).filter(([t,e])=\u003e\"sourceCircuitJson\"!==t\u0026\u0026\"sourceKicadPcb\"!==t\u0026\u0026(\"number\"==typeof e||\"boolean\"==typeof e||\"string\"==typeof e))),layerCount:t.layerCount,minTraceWidth:t.minTraceWidth,bounds:structuredClone(c),obstacles:[...t.obstacles.filter(t=\u003e((t,e)=\u003e{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=(Math.abs(t.width*Math.cos(n))+Math.abs(t.height*Math.sin(n)))/2,i=(Math.abs(t.width*Math.sin(n))+Math.abs(t.height*Math.cos(n)))/2;return t.center.x+o\u003e=e.minX\u0026\u0026t.center.x-o\u003c=e.maxX\u0026\u0026t.center.y+i\u003e=e.minY\u0026\u0026t.center.y-i\u003c=e.maxY})(t,c)).map(t=\u003estructuredClone(t)),...B6(t,c)],connections:f,...void 0!==t.traces?{traces:h}:{},...void 0!==t.allowJumpers?{allowJumpers:t.allowJumpers}:{},...t.availableJumperTypes?{availableJumperTypes:structuredClone(t.availableJumperTypes)}:{}};return{srj:y,routes:u,bounds:structuredClone(n),contextBounds:c,mutableBounds:l,boundaryMargin:a,lockedPointIndices:p,routeMappings:m}},$6=t=\u003ex6(Object.fromEntries(Object.entries(t).filter(([t])=\u003e\"route\"!==t\u0026\u0026\"vias\"!==t))),Y6=(t,e)=\u003e{const n=[];for(let o=1;o\u003ct.route.length;o+=1){const i=t.route[o-1],r=t.route[o],s=y6(i,r,e),a=s?[...s[0]\u003eg6?[[0,s[0]]]:[],...s[1]\u003c.99999999?[[s[1],1]]:[]]:[[0,1]];s\u0026\u0026!f6(_6(i,r,.5),e,4e-8)\u0026\u00260===a.length\u0026\u0026a.push([0,1]);for(const[t,e]of a)n.push(x6([_6(i,r,t),_6(i,r,e)]))}return n},X6=(t,e,n,o,i,r)=\u003e{if($6(t)!==$6(e))throw new Error(\"repair04 merge rejected changed net, width, jumper, or route metadata\");if(n.length!==t.route.length)throw new Error(\"repair04 merge received an invalid lock mask\");if(0===e.route.length)throw new Error(\"repair04 merge rejected an empty replacement route\");if(x6(t.route[0])!==x6(e.route[0])||x6(t.route[t.route.length-1])!==x6(e.route[e.route.length-1]))throw new Error(\"repair04 merge rejected a moved fragment endpoint\");let s=0;for(let o=0;o\u003ct.route.length;o+=1){if(!n[o])continue;const i=x6(t.route[o]);for(;s\u003ce.route.length\u0026\u0026x6(e.route[s])!==i;)s+=1;if(s===e.route.length)throw new Error(\"repair04 merge rejected a moved or removed locked point\");s+=1}if(x6(Y6(t,o))!==x6(Y6(e,o)))throw new Error(\"repair04 merge rejected modified geometry in the fixed boundary collar\");for(let n=1;n\u003ct.route.length;n+=1){const o=t.route[n-1],i=t.route[n];if(!(\"through_obstacle\"===o.toNextSegmentType||!0===o.insideJumperPad||!0===i.insideJumperPad||(t.jumpers??[]).some(t=\u003eb6(o,{...t.start,z:o.z})\u0026\u0026b6(i,{...t.end,z:i.z})||b6(o,{...t.end,z:o.z})\u0026\u0026b6(i,{...t.start,z:i.z}))))continue;const r=x6([o,i]);if(!e.route.some((t,n)=\u003en+1\u003ce.route.length\u0026\u0026x6([t,e.route[n+1]])===r))throw new Error(\"repair04 merge rejected a changed atomic jumper or through-obstacle span\")}for(const n of e.route){if(![n.x,n.y,n.z].every(Number.isFinite)||!Number.isInteger(n.z)||n.z\u003c0||n.z\u003e=r||!f6(n,i))throw new Error(\"repair04 merge rejected invalid or out-of-region geometry\");if((void 0!==n.pcb_port_id||!0===n.insideJumperPad||void 0!==n.toNextSegmentCircuitJsonMetadata)\u0026\u0026!t.route.some(t=\u003ex6(t)===x6(n)))throw new Error(\"repair04 merge rejected invented or moved terminal/circuit metadata\");if(void 0!==n.traceThickness\u0026\u0026(!Number.isFinite(n.traceThickness)||n.traceThickness\u003c=0||n.traceThickness\u003eMath.max(t.traceThickness,...t.route.map(t=\u003et.traceThickness??0))+g6))throw new Error(\"repair04 merge rejected increased per-point copper width\")}for(let n=1;n\u003ce.route.length;n+=1){const o=e.route[n-1],i=e.route[n];if(\"through_obstacle\"===o.toNextSegmentType\u0026\u0026!t.route.some((e,n)=\u003en+1\u003ct.route.length\u0026\u0026x6([e,t.route[n+1]])===x6([o,i])))throw new Error(\"repair04 merge rejected an invented through-obstacle span\");if(o.z!==i.z\u0026\u0026\"through_obstacle\"!==o.toNextSegmentType\u0026\u0026(Math.abs(o.x-i.x)\u003eg6||Math.abs(o.y-i.y)\u003eg6||!e.vias.some(t=\u003eMath.abs(t.x-o.x)\u003c=g6\u0026\u0026Math.abs(t.y-o.y)\u003c=g6)))throw new Error(\"repair04 merge rejected a disconnected or missing via\")}for(const n of e.vias){if(!(Number.isFinite(n.x)\u0026\u0026Number.isFinite(n.y)\u0026\u0026f6(n,i)\u0026\u0026e.route.some(t=\u003eMath.abs(t.x-n.x)\u003c=g6\u0026\u0026Math.abs(t.y-n.y)\u003c=g6)))throw new Error(\"repair04 merge rejected an invalid via position\");if(!f6(n,o,4e-8)\u0026\u0026!t.vias.some(t=\u003ex6(t)===x6(n)))throw new Error(\"repair04 merge rejected a new via in the boundary collar\")}for(const n of t.vias)if(!f6(n,o,4e-8)\u0026\u0026!e.vias.some(t=\u003ex6(t)===x6(n)))throw new Error(\"repair04 merge rejected a changed via in the boundary collar\")},V6=(t,e)=\u003e{for(const n of e){const e=t[t.length-1];e\u0026\u0026b6(e,n)\u0026\u0026x6(e)===x6(n)||t.push(structuredClone(n))}},W6=(t,e,n)=\u003e{const o=new Set(e.route.map(x6)),i=new Set(n.flatMap(t=\u003et.originalFragment.route.map(x6)).filter(t=\u003e!o.has(t))),r=[];for(const e of t)for(r.push(e);r.length\u003e=3;){const t=r[r.length-3],e=r[r.length-2],n=r[r.length-1];if(!i.has(x6(e)))break;if(t.z!==e.z||e.z!==n.z\u0026\u0026\"through_obstacle\"!==t.toNextSegmentType)break;if(t.toNextSegmentType!==e.toNextSegmentType||t.insideJumperPad!==e.insideJumperPad||t.traceThickness!==e.traceThickness||x6(t.toNextSegmentCircuitJsonMetadata)!==x6(e.toNextSegmentCircuitJsonMetadata))break;const o=n.x-t.x,s=n.y-t.y,a=o*o+s*s;if(a\u003c=10000000000000001e-32)break;const c=(e.x-t.x)*s-(e.y-t.y)*o,l=((e.x-t.x)*o+(e.y-t.y)*s)/a;if(Math.abs(c)\u003eg6*Math.sqrt(a)||l\u003c0||l\u003e1)break;r.splice(r.length-2,1)}return r},H6=t=\u003e{if(!Number.isInteger(t.segmentIndex)||t.segmentIndex\u003c0||!Number.isFinite(t.t)||t.t\u003c0||t.t\u003e1)throw new Error(\"repair04 merge received invalid fragment provenance\");return t.segmentIndex+t.t},G6=({routes:t,region:e,repairedRoutes:n})=\u003e{if(n.length!==e.routeMappings.length||e.lockedPointIndices.length!==n.length)throw new Error(\"repair04 merge requires exactly one replacement for every extracted fragment\");const o=new Map;for(let i=0;i\u003cn.length;i+=1){const r=e.routeMappings[i],s=n[i];if(!t[r.sourceRouteIndex])throw new Error(\"repair04 merge source route no longer exists\");if(X6(r.originalFragment,s,e.lockedPointIndices[i],e.mutableBounds,e.contextBounds,e.srj.layerCount),x6(r.originalFragment)===x6(s))continue;const a=o.get(r.sourceRouteIndex)??[];a.push({mapping:r,repaired:s}),o.set(r.sourceRouteIndex,a)}return t.map((t,e)=\u003e{const n=o.get(e);if(!n)return t;n.sort((t,e)=\u003eH6(t.mapping.start)-H6(e.mapping.start));const i=[];let r=0;for(const{mapping:e,repaired:o}of n){const n=H6(e.start),s=H6(e.end);if(n\u003cr-g6||s\u003cn||s\u003et.route.length-1+g6)throw new Error(\"repair04 merge received overlapping or stale fragment provenance\");if(S6(t,n,s)!==e.sourceGeometryKey)throw new Error(\"repair04 merge rejected stale source geometry\");V6(i,v6(t,r,n)),V6(i,o.route),r=s}V6(i,v6(t,r,t.route.length-1));const s=new Set(n.flatMap(({mapping:t})=\u003et.originalFragment.vias.map(t=\u003e`${t.x},${t.y}`))),a=t.vias.filter(t=\u003e!s.has(`${t.x},${t.y}`)).map(t=\u003estructuredClone(t));for(const{repaired:t}of n)for(const e of t.vias)a.some(t=\u003eMath.abs(t.x-e.x)\u003c=g6\u0026\u0026Math.abs(t.y-e.y)\u003c=g6)||a.push(structuredClone(e));return{...t,route:W6(i,t,n.map(({mapping:t})=\u003et)),vias:a}})},U6=12e4,Z6=[10,16],q6=[3,4,5,6,8],J6=(t,e)=\u003e{const n=\"string\"==typeof t.pcb_pad_id?t.pcb_pad_id:\"string\"==typeof t.pcb_trace_error_id?t.pcb_trace_error_id.match(/(pcb_(?:smtpad|plated_hole|hole|keepout)_\\d+)$/)?.[1]:void 0;if(n){const t=e.obstacles.find(t=\u003et.obstacleId===n||t.connectedTo[0]===n);if(t)return t.center}return(t=\u003e{const e=t.center;return e\u0026\u0026\"object\"==typeof e\u0026\u0026\"x\"in e\u0026\u0026\"y\"in e\u0026\u0026\"number\"==typeof e.x\u0026\u0026\"number\"==typeof e.y?{x:e.x,y:e.y}:void 0})(t)},K6=({error:t,routeIndexByTraceId:e})=\u003e{const n=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,o=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]],i=n?`overlap_${n}_`:void 0,r=i\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0,s=void 0!==r\u0026\u0026o.includes(r);return[n,...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids:[],s?void 0:r].filter(t=\u003e\"string\"==typeof t\u0026\u0026e.has(t)).filter((t,e,n)=\u003en.indexOf(t)===e)},Q6=t=\u003et.filter(t=\u003e\"pcb_via_clearance_error\"===t.type||Array.isArray(t.pcb_via_ids)).length,t9=(t,e)=\u003e{const n=new Map;for(const e of t)n.set(e.connectionName,(n.get(e.connectionName)??0)+1);return t.map((t,o)=\u003e{const i=n.get(t.connectionName)\u003e1?`${t.connectionName}_regional_${o}`:t.connectionName;return i!==t.connectionName\u0026\u0026e.addConnections([[i,t.connectionName,t.rootConnectionName??t.connectionName]]),{...t,connectionName:i,preloadedTraceId:`pipeline9_joint_candidate_${o}`,preloadedTraceIndex:o,preloadedRouteIndex:0,isThroughObstacle:!1}})},e9=(t,e)=\u003et.minX\u003c=e.maxX\u0026\u0026t.maxX\u003e=e.minX\u0026\u0026t.minY\u003c=e.maxY\u0026\u0026t.maxY\u003e=e.minY,n9=t=\u003e({minX:t.center.x-t.diameter/2,maxX:t.center.x+t.diameter/2,minY:t.center.y-t.diameter/2,maxY:t.center.y+t.diameter/2}),o9=t=\u003e({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}),i9=(t,e)=\u003e{const n=EQ(t);return n.wireSegments.some(t=\u003ee9((t=\u003e({minX:Math.min(t.start.x,t.end.x)-t.width/2,maxX:Math.max(t.start.x,t.end.x)+t.width/2,minY:Math.min(t.start.y,t.end.y)-t.width/2,maxY:Math.max(t.start.y,t.end.y)+t.width/2}))(t),e))||n.viaSpans.some(t=\u003ee9(n9(t),e))},r9=({routes:t,fixedObstacleRoutes:e,routeIndex:n,center:o,regionSize:i,srj:r,connMap:s,colorMap:a,viaDiameter:c,traceWidth:l,obstacleMargin:d,effort:h})=\u003e{const u=t9(t,s),p=u[n];if(!p)return;const m={capacityMeshNodeId:`pipeline9_joint_drc_${n}_${i}`,center:o,width:i,height:i,availableZ:Array.from({length:r.layerCount},(t,e)=\u003ee),portPoints:[],portPointsInPairs:[]},g=$K(m,[p]),f=g.fixedRouteSectionsByConnectionName.get(p.connectionName);if(!f)return;const y=u.filter((t,e)=\u003ee!==n),_=new VQ({nodePortPoints:[g.nodeWithPortPoints],fixedHdRoutes:[...y,...e].map(t=\u003e({...t,rootConnectionName:s.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName})),connMap:s,colorMap:a,obstacles:r.obstacles,layerCount:r.layerCount,viaDiameter:c,traceWidth:l,obstacleMargin:d,effort:h,preserveTerminalPcbPortIds:!0,includeBoardObstacles:!0,enableRegionalFallback:!1,maxB01Rips:120});if(_.solve(),!_.solved||_.failed)return;const b=_.routes.find(t=\u003et.connectionName===p.connectionName);return b?{routes:t.map((t,e)=\u003ee===n?{...XK(f,b),connectionName:t.connectionName}:t),usedFallback:Number(_.stats.fallbackNodeCount??0)\u003e0}:void 0},s9=({routes:t,fixedRouteCopperSpatialIndex:e,center:n,regionSize:o,srj:i,connMap:r,colorMap:s,viaDiameter:a,traceWidth:c,obstacleMargin:l,effort:d})=\u003e{const h=t9(t,r),u={capacityMeshNodeId:\"pipeline9_joint_drc_regular_fallback\",center:n,width:o,height:o,availableZ:Array.from({length:i.layerCount},(t,e)=\u003ee),portPoints:[],portPointsInPairs:[]},p=$K(u,h);if(0===p.fixedRouteSectionsByConnectionName.size)return;if(!(t=\u003e{const e=kK(t);return t.portPoints.every(t=\u003e\"on-boundary\"===rs({point:t,bounds:e}))})(p.nodeWithPortPoints))return;const m=[...p.fixedRouteSectionsByConnectionName.values()].flatMap(t=\u003et.sourceRoutes).reduce((t,e)=\u003e{const n=EQ(e);return Math.max(t,e.viaDiameter/2,...n.wireSegments.map(t=\u003et.width/2),...n.viaSpans.map(t=\u003et.diameter/2))},Math.max(c/2,a/2)),g={minX:n.x-o/2-l-m,maxX:n.x+o/2+l+m,minY:n.y-o/2-l-m,maxY:n.y+o/2+l+m},f=e.getRoutesOverlappingBounds(g),y=OQ({fixedObstacleRoutes:f,layerCount:i.layerCount}),_=new FQ({nodeWithPortPoints:p.nodeWithPortPoints,colorMap:s,connMap:r,viaDiameter:a,traceWidth:c,obstacleMargin:l,effort:d,obstacles:[...i.obstacles,...y],layerCount:i.layerCount});if(_.solve(),!_.solved||_.failed)return;const b=_.getOutput(),x=new Map(b.map(t=\u003e[t.connectionName,t])),v=new Map,S=new Set;for(const[t,e]of p.fixedRouteSectionsByConnectionName){const n=x.get(t);if(!n)return;v.set(e.sourceRoutes[0].preloadedTraceIndex,XK(e,n));for(const t of e.sourceRoutes.slice(1))S.add(t.preloadedTraceIndex)}const I=h.flatMap((e,n)=\u003eS.has(n)?[]:[{...v.get(n)??e,connectionName:t[n].connectionName}]);return(({candidateRoutes:t,fixedObstacleRoutes:e,obstacleMargin:n,connMap:o,candidateBounds:i})=\u003e{for(const r of t)for(const t of e)if(!kQ(r,t,o)\u0026\u0026DQ({left:r,right:t,clearance:n,leftBounds:i}))return!0;return!1})({candidateRoutes:I,fixedObstacleRoutes:f,obstacleMargin:l,connMap:r,candidateBounds:g})?void 0:I},a9=({srj:t,routes:e,fixedObstacleRoutes:n,newConnections:o,syntheticConnectionNames:i,drcEvaluator:r,initialErrors:s,allowTracePairRepair:a=!1,preloadRepairTraceIds:c,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m})=\u003e{let g=e,f=s??r1(r,g),y=0,_=0,b=0,x=0,v=!1;const S=(t=\u003e{if(!Number.isInteger(t)||t\u003c0)throw new Error(\"Pipeline9 regional repair route count must be nonnegative\");const e=Math.floor(7e3/Math.max(1,t));return Math.max(16,Math.min(192,e))})(e.length),I=f.filter(t=\u003e(({error:t,preloadRepairTraceIds:e})=\u003e!!s1(t).some(t=\u003ee.has(t))||(t.__collapsed_trace_participants??[]).flatMap(t=\u003enew Set(t.evaluationTraceIds).size\u003e1?[t.solverTraceId]:[]).some(t=\u003ee.collidingFixedTraceIds?.has(t)))({error:t,preloadRepairTraceIds:c})).length,C=d1({routes:g,newConnections:o,syntheticConnectionNames:i}),P=a\u0026\u0026f.some(t=\u003e((t,e)=\u003e!(\"pcb_trace_error\"!==t.type||\"string\"==typeof t.pcb_via_id||Array.isArray(t.pcb_via_ids)\u0026\u0026t.pcb_via_ids.length\u003e0)\u0026\u00262===K6({error:t,routeIndexByTraceId:e}).length)(t,C));if(0===I\u0026\u0026!P)return{routes:g,attemptedCandidateCount:y,acceptedCandidateCount:_,fallbackCandidateCount:b,candidateSearchCount:x,candidateSearchBudget:S,candidateSearchBudgetExhausted:v,safeTraceLayerRepairSkippedForBudget:!1,remainingDrcIssueCount:f.length,preloadEligibleDrcIssueCount:I,preloadRepairAttempted:!1};const M=(t=\u003e{const e=new Map,n=(t,n)=\u003e{const o=Math.floor(n.minX/4),i=Math.floor(n.maxX/4),r=Math.floor(n.minY/4),s=Math.floor(n.maxY/4);for(let n=o;n\u003c=i;n++)for(let o=r;o\u003c=s;o++){const i=`${n}:${o}`,r=e.get(i)??new Set;r.add(t),e.set(i,r)}};for(let e=0;e\u003ct.length;e++){const o=EQ(t[e]);for(const t of o.wireSegments)for(const o of AQ(t,4,1))n(e,o9(o));for(const t of o.viaSpans)n(e,n9(t))}return{getRoutesOverlappingBounds:n=\u003e{const o=new Set,i=Math.floor(n.minX/4),r=Math.floor(n.maxX/4),s=Math.floor(n.minY/4),a=Math.floor(n.maxY/4);for(let t=i;t\u003c=r;t++)for(let n=s;n\u003c=a;n++)for(const i of e.get(`${t}:${n}`)??[])o.add(i);return[...o].sort((t,e)=\u003et-e).map(e=\u003et[e]).filter(t=\u003ei9(t,n))}}})(n);for(let e=0;e\u003c2\u0026\u0026!v;e++){let e=!1;const s=d1({routes:g,newConnections:o,syntheticConnectionNames:i}),a=f.filter(t=\u003e(\"pcb_trace_error\"===t.type||\"pcb_pad_trace_clearance_error\"===t.type||\"pcb_via_trace_clearance_error\"===t.type||\"pcb_via_clearance_error\"===t.type)\u0026\u0026\"string\"==typeof t.pcb_trace_id);for(const o of a){if(v)break;const i=J6(o,t),a=K6({error:o,routeIndexByTraceId:s});if(!i)continue;let c=g,I=f;for(const e of a.slice(0,2)){if(v)break;const o=s.get(e);if(void 0!==o){for(const e of q6){if(x\u003e=S){v=!0;break}x++;const s=r9({routes:g,fixedObstacleRoutes:n,routeIndex:o,center:i,regionSize:e,srj:t,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m});if(!s)continue;y++,s.usedFallback\u0026\u0026b++;const a=r1(r,s.routes);if(l1(a,I)\u0026\u0026(c=s.routes,I=a),0===I.length)break}if(0===I.length)break}}if(c!==g||v||(x\u003e=S?v=!0:x++),c===g\u0026\u0026!v){const e=s9({routes:g,fixedRouteCopperSpatialIndex:M,center:i,regionSize:3,srj:t,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m});if(e){y++,b++;const t=r1(r,e);l1(t,I)\u0026\u0026(c=e,I=t)}}if(c!==g\u0026\u0026(g=c,f=I,_++,e=!0),v)break}if(!e||0===f.length)break}if(_\u003e0\u0026\u0026f.length\u003e0){const e=iD({...t,traces:void 0},g,m,1,l);if(e!==g){const t=r1(r,e);Q6(t)\u003c=Q6(f)\u0026\u0026l1(t,f)\u0026\u0026(g=e,f=t)}}const N=f.some(t=\u003e\"pcb_trace_error\"===t.type||\"pcb_pad_trace_clearance_error\"===t.type),w=N\u0026\u0026v;if(N\u0026\u0026!v){const e=new Nz({srj:{...t,traces:void 0},hdRoutes:g,connMap:l,effort:m,drcEvaluator:r,maxIterations:8,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1});if(e.solve(),e.failed)throw new Error(`Pipeline9 post-regional safe trace-layer repair failed: ${e.error??\"unknown error\"}`);const n=e.getOutput(),o=r1(r,n);l1(o,f)\u0026\u0026(g=n,f=o)}return{routes:g,attemptedCandidateCount:y,acceptedCandidateCount:_,fallbackCandidateCount:b,candidateSearchCount:x,candidateSearchBudget:S,candidateSearchBudgetExhausted:v,safeTraceLayerRepairSkippedForBudget:w,remainingDrcIssueCount:f.length,preloadEligibleDrcIssueCount:I,preloadRepairAttempted:I\u003e0}},c9=[.9,.72],l9=Array.from({length:16},(t,e)=\u003ee*Math.PI/8),d9=t=\u003e\"pcb_pad_trace_clearance_error\"===t.type||\"pcb_trace_error\"===t.type\u0026\u0026!(Array.isArray(t.pcb_trace_ids)\u0026\u0026t.pcb_trace_ids.length\u003e=2),h9=t=\u003e{if(\"string\"==typeof t.pcb_pad_id)return t.pcb_pad_id;if(\"string\"==typeof t.pcb_trace_error_id){const e=t.pcb_trace_error_id.match(/(pcb_(?:smtpad|plated_hole|hole|keepout)_\\d+)$/)?.[1];if(e)return e}const e=\"string\"==typeof t.message?t.message:\"\";return e.match(/(?:pcb_smtpad|pcb_plated_hole|pcb_hole|pcb_keepout)\\[#?([^\\]\"]+)\\]/)?.[1]},u9=(t,e)=\u003e{if(!e)return;const n=e.startsWith(\"pcb_\")?e:`pcb_${e}`;return t.obstacles.find(t=\u003et.obstacleId===n||t.connectedTo[0]===n)},p9=({srj:t,pcbPortId:e,z:n,portPositionMap:o})=\u003e{const i=vo(n,t.layerCount),r=o.get(e),s=t.obstacles.filter(t=\u003et.layers.includes(i)\u0026\u0026t.connectedTo.includes(e));return r?s.reduce((t,e)=\u003et?Math.hypot(e.center.x-r.x,e.center.y-r.y)\u003cMath.hypot(t.center.x-r.x,t.center.y-r.y)?e:t:e,void 0):s[0]},m9=({terminalObstacle:t,conflictingObstacle:e,traceRadius:n})=\u003e{const o=Math.max(0,t.width/2-n),i=Math.max(0,t.height/2-n),r=(t.ccwRotationDegrees??0)*Math.PI/180;return c9.flatMap(e=\u003el9.map(n=\u003e{const s={x:Math.cos(n)*o*e,y:Math.sin(n)*i*e},a=(l=r,{x:(c=s).x*Math.cos(l)-c.y*Math.sin(l),y:c.x*Math.sin(l)+c.y*Math.cos(l)});var c,l;return{x:t.center.x+a.x,y:t.center.y+a.y}})).sort((t,n)=\u003eMath.hypot(n.x-e.center.x,n.y-e.center.y)-Math.hypot(t.x-e.center.x,t.y-e.center.y)).slice(0,16)},g9=({routes:t,routeIndex:e,endpointIndex:n,point:o,bounds:i,collapseAdjacent:r})=\u003e{const s=(t=\u003et.map(t=\u003e({...t,route:t.route.map(t=\u003e({...t})),vias:t.vias.map(t=\u003e({...t}))})))(t),a=s[e];if(!a||a.route.length\u003c2)return;const c=0===n?0:a.route.length-1,l=0===n?1:c-1,d=a.route[c],h=a.route[l];if(!d||!h||d.z!==h.z)return;const u=a.traceThickness/2;if(!(o.x-u\u003ci.minX||o.x+u\u003ei.maxX||o.y-u\u003ci.minY||o.y+u\u003ei.maxY)){if(a.route[c]={...d,...o},r){const t=0===n?l+1:l-1,e=a.route[t],i=a.vias.some(t=\u003et.x===h.x\u0026\u0026t.y===h.y);if(!e||e.z!==d.z||void 0!==h.pcb_port_id||i)return;a.route[l]={...h,...o}}return s}},f9=({srj:t,originalSrj:e,routes:n,newConnections:o,syntheticConnectionNames:i,drcEvaluator:r})=\u003e{let s=n,a=r1(r,s),c=0,l=0;const d=(t=\u003e{const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id\u0026\u0026e.set(t.pcb_port_id,t);return e})(e);for(let n=0;n\u003c2;n++){let n=!1;const h=d1({routes:s,newConnections:o,syntheticConnectionNames:i});for(const o of a.filter(d9)){if(c\u003e=256)break;if(\"string\"!=typeof o.pcb_trace_id)continue;const i=h.get(o.pcb_trace_id),u=u9(t,h9(o));if(void 0===i||!u)continue;const p=s[i];let m=s,g=a;t:for(const n of[0,-1]){const o=0===n?p.route[0]:p.route.at(-1);if(!o||\"string\"!=typeof o.pcb_port_id)continue;const a=p9({srj:e,pcbPortId:o.pcb_port_id,z:o.z,portPositionMap:d});if(!a||a===u)continue;const l=Math.hypot(u.width,u.height)/2+Math.hypot(a.width,a.height)/2+.5;if(!(Math.hypot(o.x-u.center.x,o.y-u.center.y)\u003el))for(const e of m9({terminalObstacle:a,conflictingObstacle:u,traceRadius:p.traceThickness/2}))for(const o of[!1,!0]){if(c\u003e=256)break t;const a=g9({routes:s,routeIndex:i,endpointIndex:n,point:e,bounds:t.bounds,collapseAdjacent:o});if(!a)continue;c++;const l=r1(r,a);l1(l,g)\u0026\u0026(m=a,g=l)}}m!==s\u0026\u0026(s=m,a=g,l++,n=!0)}if(!n||0===a.length)break}return{routes:s,attemptedCandidateCount:c,acceptedCandidateCount:l,remainingErrors:a}},y9=[\"pcb_trace_error_id\",\"pcb_error_id\",\"pcb_via_trace_clearance_error_id\",\"pcb_pad_trace_clearance_error_id\"],_9=(t,e)=\u003e{let n=t;const o=[...e].sort(([t],[e])=\u003ee.length-t.length);for(const[t,e]of o)n=n.replaceAll(t,e);return n},b9=(t,e)=\u003e{const n=String(t.type??t.error_type??\"unknown\");if(\"pcb_via_clearance_error\"===n)return((t,e)=\u003e{const n=[...\"string\"==typeof t.pcb_trace_id?[t.pcb_trace_id]:[],...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[]].map(t=\u003e_9(t,e)).filter((t,e,n)=\u003en.indexOf(t)===e).sort(),o=t.center\u0026\u0026\"object\"==typeof t.center?t.center:t.pcb_center\u0026\u0026\"object\"==typeof t.pcb_center?t.pcb_center:void 0,i=\"number\"==typeof o?.x\u0026\u0026\"number\"==typeof o.y?{x:o.x,y:o.y}:void 0,r=\"string\"==typeof t.pcb_via_pair_net_relation?t.pcb_via_pair_net_relation:void 0;if(0!==n.length\u0026\u0026i\u0026\u0026r)return`pcb_via_clearance_error:${JSON.stringify({traceIds:n,center:i,netRelation:r})}`})(t,e);for(const o of y9){const i=t[o];if(\"string\"==typeof i)return`${n}:${_9(i,e)}`}const o=Object.fromEntries(Object.entries(t).filter(([t,e])=\u003e(t.endsWith(\"_id\")||t.endsWith(\"_ids\"))\u0026\u0026(\"string\"==typeof e||Array.isArray(e))).sort(([t],[e])=\u003et.localeCompare(e)).map(([t,n])=\u003e[t,\"string\"==typeof n?_9(n,e):n]));return`${n}:${JSON.stringify(o)}`},x9=({errors:t,baselineErrors:e,originalTraceIdByPreparedTraceId:n=new Map})=\u003e{const o=new Set(e.filter(t=\u003e!(t=\u003e\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(\"missing_connection_\"))(t)).map(t=\u003eb9(t,new Map)));return o.delete(void 0),t.filter(t=\u003e{const e=b9(t,n);return void 0===e||!o.has(e)})},v9=1.5,S9=({errorsWithCenters:t,traces:e,layerCount:n,defaultViaDiameter:o,connMap:i})=\u003e{const r=(t=\u003et.flatMap(t=\u003e{if(\"pcb_trace_error\"!==t.type||!Array.isArray(t.pcb_port_ids)||t.pcb_port_ids.length\u003c4)return[];const e=t.center;return e\u0026\u0026\"object\"==typeof e\u0026\u0026\"x\"in e\u0026\u0026\"y\"in e\u0026\u0026\"number\"==typeof e.x\u0026\u0026\"number\"==typeof e.y?[{x:e.x,y:e.y}]:[]}))(t),s=new Set;for(let t=0;t\u003ce.length;t++){const a=e[t],c=oQ(a,t,n,o,i);r.some(t=\u003ec.some(e=\u003e{const n=e.route.map(t=\u003et.x),o=e.route.map(t=\u003et.y);return Math.min(...n)\u003c=t.x+v9\u0026\u0026Math.max(...n)\u003e=t.x-v9\u0026\u0026Math.min(...o)\u003c=t.y+v9\u0026\u0026Math.max(...o)\u003e=t.y-v9}))\u0026\u0026s.add(a.pcb_trace_id)}return s},I9=({routes:t,otherHdRoutes:e,obstacles:n,colorMap:o,layerCount:i,connMap:r})=\u003e{const s=IK([...t,...e],r),a=new tc({inputHdRoutes:t,otherHdRoutes:e,netByConnectionName:s,obstacles:n,colorMap:o,layerCount:i,connMap:r});if(a.solve(),a.failed)throw new Error(`Pipeline9 could not merge movable preloaded vias: ${a.error??\"unknown error\"}`);return a.getMergedViaHdRoutes()??t},C9=({errors:t,circuitJson:e,newTraceIds:n})=\u003e{const o=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.map(t=\u003e{const e=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,i=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],r=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]].filter((t,e,n)=\u003en.indexOf(t)===e);if(e\u0026\u0026\"string\"==typeof t.pcb_trace_error_id){const s=`overlap_${e}_`,a=t.pcb_trace_error_id.startsWith(s)?t.pcb_trace_error_id.slice(s.length):void 0,c=void 0!==a\u0026\u0026(r.includes(a)||o.has(a)\u0026\u0026!i.includes(a)),l=i.find(t=\u003et!==e\u0026\u0026n.has(t))??(a\u0026\u0026!c?a:void 0);if(!n.has(e)\u0026\u00260===r.length\u0026\u0026l\u0026\u0026n.has(l)){const n=[l,e,...i].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,pcb_trace_id:l,pcb_trace_ids:n,pcb_trace_error_id:`overlap_${l}_${e}`}}}const s=r.flatMap(t=\u003e{const e=o.get(t);return e?[e]:[]}).filter((t,e,n)=\u003en.indexOf(t)===e),a=s.length\u003e0?s:i.filter(t=\u003et!==e),c=a.find(t=\u003en.has(t));if(c\u0026\u0026(!e||!n.has(e))){const n=[c,...e?[e]:[],...i,...a].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,pcb_trace_id:c,pcb_trace_ids:n,pcb_via_id:r[0],pcb_via_ids:r}}if(r.length\u003e0){const n=[...e?[e]:[],...i,...a].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,pcb_trace_ids:n,pcb_via_id:r[0],pcb_via_ids:r}}return t})},P9=1e-9,M9=t=\u003e{const e=new Set,n=[];for(const o of t)for(const t of o.route){if(\"via\"!==t.route_type)continue;const i=`${t.x},${t.y},${t.from_layer},${t.to_layer}`;e.has(i)||(e.add(i),n.push({type:\"pcb_via\",pcb_via_id:`via_${n.length}`,pcb_trace_id:o.pcb_trace_id}))}return n},N9=({errors:t,circuitJson:e,evaluatedTraceIds:n})=\u003e{const o=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.map(t=\u003e{const e=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]],i=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,r=i?`overlap_${i}_`:void 0,s=r\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(r)?t.pcb_trace_error_id.slice(r.length):void 0,a=\"string\"==typeof t.pcb_trace_error_id?t.pcb_trace_error_id.match(/_(via_\\d+)$/)?.[1]:void 0,c=0!==e.length||!a||!o.has(a)||s\u0026\u0026n.has(s)?void 0:a,l=[...e,...c?[c]:[]].filter((t,e,n)=\u003en.indexOf(t)===e),d=[...\"string\"==typeof t.pcb_trace_id?[t.pcb_trace_id]:[],...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],...l.flatMap(t=\u003e{const e=o.get(t);return e?[e]:[]})].filter((t,e,n)=\u003en.indexOf(t)===e);return{...t,...l.length\u003e0?{pcb_via_id:l[0],pcb_via_ids:l}:{},...l.length\u003e0\u0026\u0026d.length\u003e0?{pcb_trace_ids:d}:{}}})},w9=(t,e)=\u003eMath.abs(t.x-e.x)\u003c=P9\u0026\u0026Math.abs(t.y-e.y)\u003c=P9\u0026\u0026t.z===e.z,T9=({trace:t,sectionGroup:e,syntheticConnectionName:n,connMap:o})=\u003e{const i=e.routes;if(0===i.length)throw new Error(`Pipeline9 cannot exactly repair empty preloaded section for trace \"${t.pcb_trace_id}\"`);const r=[];for(const e of i){if(0===r.length){r.push(...e.route);continue}const n=r.at(-1);if(e.route[0]\u0026\u0026w9(n,e.route[0]))r.push(...e.route.slice(1));else{if(!e.route.at(-1)||!w9(n,e.route.at(-1)))throw new Error(`Pipeline9 cannot reconnect preloaded trace \"${t.pcb_trace_id}\" for exact repair`);r.push(...e.route.slice(0,-1).reverse())}}const s=0===e.routePositionStart,a=e.routePositionEnd===t.route.length-1,c=s?t.connectsTo?.[0]:null,l=a?t.connectsTo?.at(-1):null;return c\u0026\u0026r[0]\u0026\u0026(r[0]={...r[0],pcb_port_id:c}),l\u0026\u0026r.at(-1)\u0026\u0026(r[r.length-1]={...r.at(-1),pcb_port_id:l}),{connectionName:n,rootConnectionName:o.getNetConnectedToId(t.connection_name)??t.connection_name,traceThickness:Math.max(...i.map(t=\u003et.traceThickness)),viaDiameter:Math.max(...i.map(t=\u003et.viaDiameter)),route:r,vias:r.slice(0,-1).flatMap((t,e)=\u003e{const n=r[e+1];return t.z!==n.z\u0026\u0026(o=t,i=n,Math.abs(o.x-i.x)\u003c=P9\u0026\u0026Math.abs(o.y-i.y)\u003c=P9)?[{x:n.x,y:n.y}]:[];var o,i})}},R9=({trace:t,traceIndex:e,layerCount:n,defaultViaDiameter:o,connMap:i})=\u003e{const r=t.route.flatMap((t,e)=\u003e\"through_obstacle\"===t.route_type?[e]:[]),s=new Map,a=oQ(t,e,n,o,i);for(const e of a){const n=e.preloadedRoutePositionStart,o=e.preloadedRoutePositionEnd;if(void 0===n||void 0===o)throw new Error(`Pipeline9 preloaded trace section is missing route positions for \"${t.pcb_trace_id}\"`);if(\"through_obstacle\"===t.route[n]?.route_type)continue;const i=r.filter(t=\u003et\u003cn).length,a=s.get(i)??{routePositionStart:n,routePositionEnd:o,routes:[]};a.routePositionStart=Math.min(a.routePositionStart,n),a.routePositionEnd=Math.max(a.routePositionEnd,o),a.routes.push(e),s.set(i,a)}return[...s.values()]},E9=(t,e)=\u003et.map(t=\u003e{const n=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=\u003e\"string\"==typeof t):[],o=\"string\"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,i=o?`overlap_${o}_`:void 0,r=i\u0026\u0026\"string\"==typeof t.pcb_trace_error_id\u0026\u0026t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0,s=[...\"string\"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]],a=void 0!==r\u0026\u0026s.includes(r),c=[o,...n,a?void 0:r].filter(t=\u003e\"string\"==typeof t),l=new Map;for(const t of c){const n=e.get(t)??t,o=l.get(n)??new Set;o.add(t),l.set(n,o)}const d=[...l].flatMap(([t,e])=\u003ee.size\u003e1?[{solverTraceId:t,evaluationTraceIds:[...e]}]:[]),h=o?e.get(o)??o:void 0,u=n.map(t=\u003ee.get(t)??t),p=r?a?r:e.get(r)??r:void 0;return h!==o||u.some((t,e)=\u003et!==n[e])||p!==r?{...t,...o?{pcb_trace_id:h}:{},...Array.isArray(t.pcb_trace_ids)?{pcb_trace_ids:u}:{},...h\u0026\u0026p?{pcb_trace_error_id:`overlap_${h}_${p}`}:{},...d.length\u003e0?{__collapsed_trace_participants:d}:{}}:t}),A9=(t,e)=\u003e{const n=t.hdRoute.route[0],o=t.hdRoute.route.at(-1);return{name:t.syntheticConnectionName,rootConnectionName:t.hdRoute.rootConnectionName,__netConnectionName:t.originalTrace.connection_name,nominalTraceWidth:t.hdRoute.traceThickness,pointsToConnect:[{x:n.x,y:n.y,layer:vo(n.z,e),pointId:`${t.syntheticConnectionName}:start`},{x:o.x,y:o.y,layer:vo(o.z,e),pointId:`${t.syntheticConnectionName}:end`}]}},O9=({originalTrace:t,repairedSections:e})=\u003e{const n=[];let o=0;for(const i of[...e].sort((t,e)=\u003et.routePositionStart-e.routePositionStart)){if(i.routePositionStart\u003co)throw new Error(`Pipeline9 found overlapping repaired sections for preloaded trace \"${t.pcb_trace_id}\"`);n.push(...t.route.slice(o,i.routePositionStart),...i.route),o=i.routePositionEnd+1}return n.push(...t.route.slice(o)),{...t,__replaces_pcb_trace_id:t.pcb_trace_id,route:n}},k9=class extends si{params;inputNewHdRoutes;inputUpdatedPreloadedTraces;movablePreloadedSections;fixedPreloadedObstacleRoutes;syntheticConnectionNames;exactRepairSolver;drcEvaluator;cachedReferenceDrcEvaluator;clearancePrecisionDrcEvaluator;clearancePrecisionIndexedDrcEvaluator;clearanceMarginDrcEvaluator;referenceDrcValidationCount=0;referenceDrcFalseNegativeCount=0;indexedDrcEvaluationCount=0;indexedDrcCacheHitCount=0;indexedDrcEvaluationTimeMs=0;indexedDrcCandidateCache=new Map;combinedOutput;cacheIndexedDrcResult(t,e){if(this.indexedDrcCandidateCache.size\u003e=64){const t=this.indexedDrcCandidateCache.keys().next().value;void 0!==t\u0026\u0026this.indexedDrcCandidateCache.delete(t)}this.indexedDrcCandidateCache.set(t,e)}constructor(t){super(),this.params=t,this.inputNewHdRoutes=t.newHdRoutes,this.inputUpdatedPreloadedTraces=t.updatedPreloadedTraces;const e=t.updatedPreloadedTraces.filter(e=\u003et.mutatedPreloadedTraceIds.has(e.pcb_trace_id)),n=ZJ({connections:t.newConnections,originalConnections:t.originalSrj.connections,layerCount:t.layerCount,obstacles:t.obstacles,defaultViaHoleDiameter:t.defaultViaHoleDiameter,connMap:t.connMap}),o=n(t.newHdRoutes),i=new Set(o.map(t=\u003et.pcb_trace_id)),r=(({originalPreloadedTraces:t,mutatedPreloadedTraces:e,newTraces:n})=\u003e{const o=new Set(n.map(t=\u003et.pcb_trace_id)),i=new Map(e.map(t=\u003e[t.pcb_trace_id,t])),r=new Set([...t.map(t=\u003et.pcb_trace_id),...o]),s=new Map;return{routedTraces:[...t.filter(t=\u003eo.has(t.pcb_trace_id)).map(t=\u003e{const e=i.get(t.pcb_trace_id)??t,n=`${t.pcb_trace_id}_preloaded`;let o=n,a=2;for(;r.has(o);)o=`${n}_${a}`,a+=1;return r.add(o),s.set(o,t.pcb_trace_id),{...e,pcb_trace_id:o,__replaces_pcb_trace_id:t.pcb_trace_id}}),...e.filter(t=\u003e!o.has(t.pcb_trace_id)),...n],originalPreloadedTraceIdByPreparedTraceId:s}})({originalPreloadedTraces:t.originalSrj.traces??[],mutatedPreloadedTraces:e,newTraces:o}),s=t.originalSrj.minTraceToPadEdgeClearance??V0.traceClearance??.1,a=V0.viaClearance??.1,c=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:[],drcOptions:{traceClearance:s}}),l=new Set((t.originalSrj.traces??[]).map(t=\u003et.pcb_trace_id)),d=N9({errors:c.errors,circuitJson:c.circuitJson,evaluatedTraceIds:l}),h=N9({errors:c.errorsWithCenters,circuitJson:c.circuitJson,evaluatedTraceIds:l}),u=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:r.routedTraces,drcOptions:{traceClearance:s}}),p=new Set(o1(t.originalSrj.traces??[],r.routedTraces).map(t=\u003et.pcb_trace_id)),m=N9({errors:u.errors,circuitJson:u.circuitJson,evaluatedTraceIds:p}),g=N9({errors:u.errorsWithCenters,circuitJson:u.circuitJson,evaluatedTraceIds:p}),f={...u,errors:x9({errors:m,baselineErrors:d,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId}),errorsWithCenters:x9({errors:g,baselineErrors:h,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId})},y=(({errors:t,circuitJson:e})=\u003e{const n=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[])),o=new Set;for(const e of t){const t=\"string\"==typeof e.pcb_trace_id?e.pcb_trace_id:void 0,i=[...\"string\"==typeof e.pcb_via_id?[e.pcb_via_id]:[],...Array.isArray(e.pcb_via_ids)?e.pcb_via_ids.filter(t=\u003e\"string\"==typeof t):[]];if(\"string\"==typeof e.pcb_trace_id\u0026\u0026o.add(e.pcb_trace_id),Array.isArray(e.pcb_trace_ids))for(const t of e.pcb_trace_ids)\"string\"==typeof t\u0026\u0026o.add(t);if(\"string\"==typeof e.pcb_via_id){const t=n.get(e.pcb_via_id);t\u0026\u0026o.add(t)}if(Array.isArray(e.pcb_via_ids))for(const t of e.pcb_via_ids){if(\"string\"!=typeof t)continue;const e=n.get(t);e\u0026\u0026o.add(e)}const r=t?`overlap_${t}_`:void 0;if(r\u0026\u0026\"string\"==typeof e.pcb_trace_error_id\u0026\u0026e.pcb_trace_error_id.startsWith(r)){const t=e.pcb_trace_error_id.slice(r.length);i.includes(t)||o.add(t)}}return o})({errors:f.errors,circuitJson:f.circuitJson}),_=new Map(t.updatedPreloadedTraces.map(t=\u003e[t.pcb_trace_id,t])),b=new Set;for(const t of y){const e=r.originalPreloadedTraceIdByPreparedTraceId.get(t);e\u0026\u0026_.has(e)?b.add(e):!i.has(t)\u0026\u0026_.has(t)\u0026\u0026b.add(t)}for(const e of S9({errorsWithCenters:f.errorsWithCenters,traces:t.updatedPreloadedTraces,layerCount:t.layerCount,defaultViaDiameter:t.defaultViaDiameter,connMap:t.connMap}))b.add(e);this.movablePreloadedSections=[];for(const e of b){const n=_.get(e);if(!n)throw new Error(`Pipeline9 cannot find preloaded trace \"${e}\" selected for exact repair`);const o=t.updatedPreloadedTraces.findIndex(t=\u003et.pcb_trace_id===e),i=R9({trace:n,traceIndex:o,layerCount:t.layerCount,defaultViaDiameter:t.defaultViaDiameter,connMap:t.connMap});for(const[e,o]of i.entries()){const i=`pipeline9_preloaded_drc_${this.movablePreloadedSections.length}`;this.movablePreloadedSections.push({originalTrace:n,originalRoutePositionStart:o.routePositionStart,originalRoutePositionEnd:o.routePositionEnd,syntheticConnectionName:i,evaluationTraceId:`${n.pcb_trace_id}__pipeline9_section_${e}`,hdRoute:T9({trace:n,sectionGroup:o,syntheticConnectionName:i,connMap:t.connMap})})}}this.syntheticConnectionNames=new Set(this.movablePreloadedSections.map(t=\u003et.syntheticConnectionName));const x=new Set(this.movablePreloadedSections.map(t=\u003et.originalTrace.pcb_trace_id));this.fixedPreloadedObstacleRoutes=t.updatedPreloadedTraces.flatMap((e,n)=\u003e{const o=oQ(e,n,t.layerCount,t.defaultViaDiameter,t.connMap);return x.has(e.pcb_trace_id)?o.filter(t=\u003e{const n=t.preloadedRoutePositionStart;return void 0!==n\u0026\u0026\"through_obstacle\"===e.route[n]?.route_type}):o});const v=new Map;for(const[t,e]of this.movablePreloadedSections.entries()){const n=e.originalTrace.pcb_trace_id,o=v.get(n)??[];o.push(t),v.set(n,o)}for(const e of(({errors:t,circuitJson:e,originalTraceIdByPreparedTraceId:n})=\u003e{const o=new Map(e.flatMap(t=\u003e\"pcb_via\"===t.type\u0026\u0026\"string\"==typeof t.pcb_via_id\u0026\u0026\"string\"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.flatMap(t=\u003e{if(\"pcb_via_clearance_error\"!==t.type||!Array.isArray(t.pcb_via_ids)||\"number\"!=typeof t.actual_clearance||t.actual_clearance\u003e=0)return[];const e=t.pcb_via_ids.flatMap(t=\u003e{if(\"string\"!=typeof t)return[];const e=o.get(t);return e?[n.get(e)??e]:[]}).filter((t,e,n)=\u003en.indexOf(t)===e);return e.length\u003e0?[e]:[]})})({errors:f.errors,circuitJson:f.circuitJson,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId})){const n=e.flatMap(t=\u003ev.get(t)??[]).filter((t,e,n)=\u003en.indexOf(t)===e);if(0===n.length)continue;const o=new Set(n),i=I9({routes:n.map(t=\u003ethis.movablePreloadedSections[t].hdRoute),otherHdRoutes:[...t.newHdRoutes,...this.fixedPreloadedObstacleRoutes,...this.movablePreloadedSections.flatMap((t,e)=\u003eo.has(e)?[]:[t.hdRoute])],obstacles:t.obstacles,colorMap:t.colorMap,layerCount:t.layerCount,connMap:t.connMap});for(let t=0;t\u003cn.length;t++)this.movablePreloadedSections[n[t]].hdRoute=i[t]}if(this.stats={initialJointDrcIssueCount:f.errors.length,baselineJointDrcIssueCount:c.errors.length,initialJointDrcIssueCountByType:f.errors.reduce((t,e)=\u003e{const n=String(e.type??e.error_type??\"unknown\");return t[n]=(t[n]??0)+1,t},{}),movablePreloadedTraceCount:x.size,movablePreloadedSectionCount:this.movablePreloadedSections.length,exactRepairConfiguredMaxIterations:32,exactRepairConfiguredViaInPadMaxIterations:32,exactRepairConfiguredBroadMaxIterations:12},0===f.errors.length)return void(this.solved=!0);const S=new Set(this.movablePreloadedSections.map(t=\u003et.originalTrace.pcb_trace_id)),I=e.filter(t=\u003e!S.has(t.pcb_trace_id)),C=new Map(this.movablePreloadedSections.map(e=\u003e[e.syntheticConnectionName,A9(e,t.layerCount)])),{traces:P,...M}=t.srjWithPointPairs,N={...M,connections:[...t.srjWithPointPairs.connections,...C.values()]},w=new s_({...N,obstacles:t.originalSrj.obstacles,minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter??t.defaultViaDiameter},{connMap:t.connMap,traceClearance:s,viaClearance:a,includeTraceViaOwnerMetadata:!0,spatialCellSize:Math.max(t.defaultViaDiameter,t.originalSrj.minTraceWidth)+Math.max(s,a)}),T=w.evaluate(t.originalSrj.traces??[]),R=M9(t.originalSrj.traces??[]),E={...T,errors:N9({errors:T.errors,circuitJson:R,evaluatedTraceIds:l}),errorsWithCenters:N9({errors:T.errorsWithCenters,circuitJson:R,evaluatedTraceIds:l})};let A;const O=e=\u003e{const o=e.filter(t=\u003e!this.syntheticConnectionNames.has(t.connectionName)),i=n(o),r=vK(i,t.originalSrj.traces??[]),s=new Set,a=new Map,c=this.movablePreloadedSections.map(n=\u003e{const o=e.find(t=\u003et.connectionName===n.syntheticConnectionName);if(!o)throw new Error(`Pipeline9 joint DRC repair lost preloaded section \"${n.syntheticConnectionName}\"`);const i=n.originalTrace.pcb_trace_id;a.set(n.evaluationTraceId,i);const r=!s.has(i);return s.add(i),{...n.originalTrace,pcb_trace_id:n.evaluationTraceId,...r?{__replaces_pcb_trace_id:i}:{__replaces_pcb_trace_id:void 0},route:Mo(o,t.layerCount,{defaultViaHoleDiameter:t.defaultViaHoleDiameter,obstacles:t.obstacles,connMap:t.connMap})}}),l=new Map;for(let t=0;t\u003ci.length;t++)l.set(r[t].pcb_trace_id,i[t].pcb_trace_id);for(const t of this.movablePreloadedSections)l.set(t.evaluationTraceId,`${t.syntheticConnectionName}_0`);const d=new Set(l.values()),h=[...I,...c,...r];return{evaluatedTraces:o1(t.originalSrj.traces??[],h),movableTraceIds:d,originalTraceIdByEvaluationTraceId:a,routedTraces:h,solverTraceIdByEvaluationTraceId:l}},k=({errors:t,errorsWithCenters:e,circuitJson:n,movableTraceIds:o,solverTraceIdByEvaluationTraceId:i})=\u003e{const r=n.map(t=\u003e{if(!(\"pcb_trace_id\"in t)||\"string\"!=typeof t.pcb_trace_id)return t;const e=i.get(t.pcb_trace_id);return e?{...t,pcb_trace_id:e}:t});return{errors:C9({errors:E9(t,i),circuitJson:r,newTraceIds:o}),errorsWithCenters:C9({errors:E9(e,i),circuitJson:r,newTraceIds:o})}},L=({routes:e,hdRoutes:n},o=!0)=\u003e{const i=e??n;if(!i)throw new Error(\"Pipeline9 reference DRC repair requires HD routes\");const r=O(i),a=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:r.routedTraces,drcOptions:{traceClearance:s,includeTraceContinuity:o}}),c=new Set(r.evaluatedTraces.map(t=\u003et.pcb_trace_id)),l=N9({errors:a.errors,circuitJson:a.circuitJson,evaluatedTraceIds:c}),u=N9({errors:a.errorsWithCenters,circuitJson:a.circuitJson,evaluatedTraceIds:c}),p=x9({errors:l,baselineErrors:d,originalTraceIdByPreparedTraceId:r.originalTraceIdByEvaluationTraceId}),m=x9({errors:u,baselineErrors:h,originalTraceIdByPreparedTraceId:r.originalTraceIdByEvaluationTraceId});return k({errors:p,errorsWithCenters:m,circuitJson:a.circuitJson,movableTraceIds:r.movableTraceIds,solverTraceIdByEvaluationTraceId:r.solverTraceIdByEvaluationTraceId})},D=({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline9 cached reference DRC requires HD routes\");const o=JSON.stringify(n);if(A?.candidateKey===o)return A.result;this.referenceDrcValidationCount+=1;const i=L({traces:[],routes:n,hdRoutes:n});return A={candidateKey:o,result:i},i};this.cachedReferenceDrcEvaluator=D,this.clearancePrecisionDrcEvaluator=({routes:t,hdRoutes:e})=\u003eL({traces:[],routes:t,hdRoutes:e},!1);const z=e=\u003e{const n=O(e);return n1(t.srjWithPointPairs,n.routedTraces,{minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter,originalSrj:t.originalSrj,includeOriginalConnections:!0})};let F;this.clearanceMarginDrcEvaluator=(t,e,n)=\u003e(F?.routes!==n\u0026\u0026(F={routes:n,circuitJson:z(n)}),(({circuitJson:t,originalCircuitJson:e,targets:n})=\u003e{const o=new Map(t.filter(t=\u003e\"pcb_trace\"===t.type).map(t=\u003e[t.pcb_trace_id,t])),i=new Map(e.filter(t=\u003e\"pcb_trace\"===t.type).map(t=\u003e[t.pcb_trace_id,t])),r=t.filter(t=\u003e\"pcb_via\"===t.type),s=new Map;for(const e of t)\"pcb_via\"===e.type?s.set(e.pcb_via_id,e):\"pcb_smtpad\"===e.type?s.set(e.pcb_smtpad_id,e):\"pcb_plated_hole\"===e.type\u0026\u0026s.set(e.pcb_plated_hole_id,e);const a=[];for(const t of n){const n=\"pcb_via_trace_clearance_error\"===t.type,c=n?t.pcb_via_id:t.pcb_pad_id;if(!n\u0026\u0026\"pcb_pad_trace_clearance_error\"!==t.type||\"string\"!=typeof t.pcb_trace_id||\"string\"!=typeof c||\"number\"!=typeof t.minimum_clearance||!Number.isFinite(t.minimum_clearance)||t.minimum_clearance\u003c=0)throw new Error(\"Pipeline9 clearance margin requires a valid target pair\");const l=i.get(t.pcb_trace_id),d=e.find(t=\u003en?\"pcb_via\"===t.type\u0026\u0026t.pcb_via_id===c:\"pcb_smtpad\"===t.type\u0026\u0026t.pcb_smtpad_id===c||\"pcb_plated_hole\"===t.type\u0026\u0026t.pcb_plated_hole_id===c);if(!l||!d)throw new Error(`Pipeline9 clearance margin has no original target ${c}/${t.pcb_trace_id}`);const h=o.get(t.pcb_trace_id);let u=s.get(c);if(n){if(\"pcb_via\"!==d.type||\"string\"!=typeof d.pcb_trace_id)throw new Error(\"Pipeline9 clearance margin requires the original via owner\");const t=i.get(d.pcb_trace_id);if(!t)throw new Error(\"Pipeline9 clearance margin lost the original via owner\");const e=t.route.filter(t=\u003e\"via\"===t.route_type),n=e.map((t,e)=\u003e({segment:t,index:e})).filter(({segment:t})=\u003et.x===d.x\u0026\u0026t.y===d.y\u0026\u0026d.layers.includes(t.from_layer)\u0026\u0026d.layers.includes(t.to_layer)\u0026\u0026(t.from_layer===d.layers[0]\u0026\u0026t.to_layer===d.layers.at(-1)||t.to_layer===d.layers[0]\u0026\u0026t.from_layer===d.layers.at(-1))).filter(({segment:t},e,n)=\u003en.findIndex(e=\u003ee.segment.from_layer===t.from_layer\u0026\u0026e.segment.to_layer===t.to_layer)===e);if(0===n.length)throw new Error(\"Pipeline9 clearance margin lost the original via transition\");if(1!==n.length)return{status:\"unsupported-identity\"};const s=n[0].index,a=o.get(d.pcb_trace_id),c=a?.route.filter(t=\u003e\"via\"===t.route_type);if(!c||c.length!==e.length||c.some((t,n)=\u003et.from_layer!==e[n].from_layer||t.to_layer!==e[n].to_layer))return{status:\"unsupported-identity\"};const l=c[s];u=r.filter(t=\u003et.x===l.x\u0026\u0026t.y===l.y\u0026\u0026t.layers.join()===d.layers.join()).reduce((t,e)=\u003e!t||e.outer_diameter\u003et.outer_diameter?e:t,void 0)}if(!(h\u0026\u0026u\u0026\u0026\"x\"in u\u0026\u0026\"y\"in u))return{status:\"unsupported-identity\"};const p={minClearance:t.minimum_clearance+1},m=n?Y0([h,u],p):$0([h,u],p),g=t.minimum_clearance+.01;for(const e of m){const n=e.actual_clearance;if(\"number\"!=typeof n||!Number.isFinite(n))throw new Error(\"Pipeline9 clearance margin requires a finite measurement\");n\u003e=g||a.push({...t,...\"pcb_via\"===u.type?{pcb_via_id:u.pcb_via_id,pcb_via_ids:[u.pcb_via_id]}:{},actual_clearance:n,minimum_clearance:g,center:{x:u.x,y:u.y}})}}return{status:\"measured\",errors:a}})({circuitJson:z(t),originalCircuitJson:F.circuitJson,targets:e})),this.clearancePrecisionIndexedDrcEvaluator=({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline9 clearance ranking requires HD routes\");const o=O(n);return w.evaluate(o.evaluatedTraces)};const B=({routes:t,hdRoutes:e})=\u003e{const n=t??e;if(!n)throw new Error(\"Pipeline9 joint DRC repair requires HD routes\");const o=JSON.stringify(n),i=this.indexedDrcCandidateCache.get(o);if(void 0!==i)return this.indexedDrcCacheHitCount+=1,i;const r=performance.now();this.indexedDrcEvaluationCount+=1;const s=O(n),a=w.evaluate(s.evaluatedTraces),c=M9(s.evaluatedTraces),l=new Set(s.evaluatedTraces.map(t=\u003et.pcb_trace_id)),d=N9({errors:a.errors,circuitJson:c,evaluatedTraceIds:l}),h=N9({errors:a.errorsWithCenters,circuitJson:c,evaluatedTraceIds:l}),u=x9({errors:d,baselineErrors:E.errors,originalTraceIdByPreparedTraceId:s.originalTraceIdByEvaluationTraceId}),p=x9({errors:h,baselineErrors:E.errorsWithCenters,originalTraceIdByPreparedTraceId:s.originalTraceIdByEvaluationTraceId});if(0===u.length){const t=this.referenceDrcValidationCount,e=D({traces:[],routes:n,hdRoutes:n}),i=Array.isArray(e)?e:e.errors;return this.referenceDrcValidationCount\u003et\u0026\u0026i.length\u003e0\u0026\u0026(this.referenceDrcFalseNegativeCount+=1),this.indexedDrcEvaluationTimeMs+=performance.now()-r,this.cacheIndexedDrcResult(o,e),e}const m=k({errors:u,errorsWithCenters:p,circuitJson:c,movableTraceIds:s.movableTraceIds,solverTraceIdByEvaluationTraceId:s.solverTraceIdByEvaluationTraceId});return this.indexedDrcEvaluationTimeMs+=performance.now()-r,this.cacheIndexedDrcResult(o,m),m};this.drcEvaluator=B,this.exactRepairSolver=new wz({srj:N,hdRoutes:[...t.newHdRoutes,...this.movablePreloadedSections.map(t=\u003et.hdRoute)],connMap:t.connMap,effort:t.effort,viaHoleDiameter:t.defaultViaHoleDiameter,drcEvaluator:B,viaInPadDrcEvaluator:B,maxIterations:32,enableBroadFallback:!1,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!0,enableTraceViaOwnerTargeting:!0,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:t.originalSrj.allowViaInPad??!1,viaInPadMaxIterations:32,broadMaxIterations:12,broadPassMultiplier:3}),this.activeSubSolver=this.exactRepairSolver,this.MAX_ITERATIONS=this.exactRepairSolver.MAX_ITERATIONS+1}getSolverName(){return\"Pipeline9JointDrcRepairSolver\"}_step(){if(!this.exactRepairSolver)return void(this.solved=!0);if(this.exactRepairSolver.step(),this.progress=this.exactRepairSolver.progress,this.exactRepairSolver.failed)return this.failed=!0,void(this.error=this.exactRepairSolver.error);if(!this.exactRepairSolver.solved)return;let t=this.exactRepairSolver.getOutput();const e=this.exactRepairSolver.stats.finalDrcIssueCount,n=\"number\"==typeof e\u0026\u0026Number.isFinite(e)\u0026\u0026e\u003e=0?e:void 0;let o,i=0,r=0,s=0,a=!1;const c=this.cachedReferenceDrcEvaluator({traces:[],routes:t,hdRoutes:t}),l=Array.isArray(c)?c:c.errors;if(o=l.length,l.length\u003e0){const e=(({srj:t,routes:e,newConnections:n,syntheticConnectionNames:o,connMap:i,indexedDrcEvaluator:r,candidateDrcEvaluator:s,marginDrcEvaluator:a,drcEvaluator:c,initialErrors:l,initialErrorsWithCenters:d=l})=\u003e{const h={routes:e,attemptedCandidateCount:0,candidateValidationCount:0,referenceValidationCount:0,repaired:!1};if((t.traces?.length??0)\u003e0||o.size\u003e0)return h;if(0===l.length)return h;const u=d1({routes:e,newConnections:n,syntheticConnectionNames:o}),p=new Map;for(const e of t.obstacles)for(const t of[e.obstacleId,e.circuitJsonMetadata?.pcb_smtpad_id,e.circuitJsonMetadata?.pcb_plated_hole_id,e.connectedTo[0]])\"string\"==typeof t\u0026\u0026p.set(t,e.center);const m=p1({errors:l,errorsWithCenters:d,routeIndexByTraceId:u,padPositionById:p});if(!m)return h;let g=m;const f=m.errors,y=m.errors.map(t=\u003e({...t,minimum_clearance:t.minimum_clearance+.01})),_=u1(y);if(void 0===_)return h;let b={errors:y,deficit:_},x=e,v=0,S=0,I=0;for(let n=0;n\u003c8;n++){const n=new Map;for(const t of[...b.errors,...g.errors]){const e=JSON.stringify([t.type,t.pcb_trace_id,t.pcb_pad_id,t.pcb_via_id]);n.set(e,t)}const o=[...n.values()];let l;for(const e of h1){const n=kk(x);if(!$D(t,n,o,u,e,i,!0,!0,!0,!1))continue;const s=aD(n);v++;const a=r({traces:[],routes:s,hdRoutes:s}),c=u1(Array.isArray(a)?a:a.errors);void 0!==c\u0026\u0026(!l||c\u003cl.deficit)\u0026\u0026(l={routes:s,deficit:c})}if(!l)break;S++;const d=s({traces:[],routes:l.routes,hdRoutes:l.routes}),h=Array.isArray(d)?d:d.errors,m=p1({errors:h,errorsWithCenters:Array.isArray(d)?d:d.errorsWithCenters??d.errors,routeIndexByTraceId:u,padPositionById:p});if(!m)break;const y=a(l.routes,f,e);if(\"unsupported-identity\"===y.status)break;const _=y.errors,C=p1({errors:_,errorsWithCenters:_,routeIndexByTraceId:u,padPositionById:p});if(!C)break;if(0===h.length\u0026\u00260===_.length){I++;const t=c({traces:[],routes:l.routes,hdRoutes:l.routes});if(0===(Array.isArray(t)?t:t.errors).length)return{routes:l.routes,attemptedCandidateCount:v,candidateValidationCount:S,referenceValidationCount:I,repaired:!0};break}if(m.deficit+C.deficit\u003e=g.deficit+b.deficit-1e-9)break;x=l.routes,g=m,b=C}return{routes:e,attemptedCandidateCount:v,candidateValidationCount:S,referenceValidationCount:I,repaired:!1}})({srj:this.params.srj,routes:t,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,connMap:this.params.connMap,indexedDrcEvaluator:this.clearancePrecisionIndexedDrcEvaluator,candidateDrcEvaluator:this.clearancePrecisionDrcEvaluator,marginDrcEvaluator:this.clearanceMarginDrcEvaluator,drcEvaluator:this.cachedReferenceDrcEvaluator,initialErrors:l,initialErrorsWithCenters:Array.isArray(c)?c:c.errorsWithCenters??c.errors});i=e.attemptedCandidateCount,r=e.candidateValidationCount,s=e.referenceValidationCount,a=e.repaired,e.repaired\u0026\u0026(t=e.routes,o=0)}if(0===o)return this.combinedOutput=t,this.stats={...this.stats,...this.exactRepairSolver.stats,postExactIndexedDrcIssueCount:n,postExactReferenceValidationAttempted:!0,postExactReferenceDrcIssueCount:0,postExactReferenceAccepted:!0,clearancePrecisionCandidateCount:i,clearancePrecisionCandidateValidationCount:r,clearancePrecisionReferenceValidationCount:s,clearancePrecisionRepaired:a,boundedRegionalRepairAttemptedRegionCount:0,boundedRegionalRepairAcceptedRegionCount:0,boundedRegionalRepairCandidateAttemptCount:0,boundedRegionalRepairPathSearchNodeCount:0,boundedRegionalRepairReferenceValidationCount:0,boundedRegionalRepairRepaired:!1,boundedRegionalRepairTimeMs:0,regionalB01RepairCandidateCount:0,regionalB01RepairAcceptedCount:0,regionalB01RepairFallbackCandidateCount:0,regionalB01RepairCandidateSearchCount:0,regionalB01RepairCandidateSearchBudget:0,regionalB01RepairCandidateSearchBudgetExhausted:!1,regionalB01RepairSafeTraceLayerSkippedForBudget:!1,regionalB01RepairRemainingDrcIssueCount:0,regionalB01RepairPreloadEligibleDrcIssueCount:0,regionalB01RepairAttempted:!1,regionalB01RepairTraceIdCount:0,terminalEscapeCandidateCount:0,terminalEscapeAcceptedCount:0,referenceDrcValidationCount:this.referenceDrcValidationCount,referenceDrcFalseNegativeCount:this.referenceDrcFalseNegativeCount,indexedDrcEvaluationCount:this.indexedDrcEvaluationCount,indexedDrcCacheHitCount:this.indexedDrcCacheHitCount,indexedDrcEvaluationTimeMs:this.indexedDrcEvaluationTimeMs,indexedDrcCandidateCacheSize:this.indexedDrcCandidateCache.size,indexedDrcCandidateCacheCapacity:64},void(this.solved=!0);const d=f9({srj:this.params.srj,originalSrj:this.params.originalSrj,routes:t,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.drcEvaluator}),h=(({routes:t,newConnections:e,syntheticConnectionNames:n,fixedPreloadedObstacleRoutes:o,updatedPreloadedTraces:i})=\u003e{const r=new Set,s=Object.assign(new Set,{collidingFixedTraceIds:r}),a=d1({routes:t,newConnections:e,syntheticConnectionNames:n}),c=new Set;for(const[e,o]of a)n.has(t[o].connectionName)?s.add(e):c.add(e);for(const t of o){const e=i[t.preloadedTraceIndex];if(!e)throw new Error(`Pipeline9 fixed preload route has invalid trace index ${t.preloadedTraceIndex}`);c.has(e.pcb_trace_id)?r.add(e.pcb_trace_id):s.add(e.pcb_trace_id)}return s})({routes:d.routes,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,fixedPreloadedObstacleRoutes:this.fixedPreloadedObstacleRoutes,updatedPreloadedTraces:this.params.updatedPreloadedTraces}),u=a9({srj:this.params.srj,routes:d.routes,fixedObstacleRoutes:this.fixedPreloadedObstacleRoutes,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.drcEvaluator,initialErrors:d.remainingErrors,allowTracePairRepair:!0,preloadRepairTraceIds:h,connMap:this.params.connMap,colorMap:this.params.colorMap,viaDiameter:this.params.defaultViaDiameter,traceWidth:this.params.srj.minTraceWidth,obstacleMargin:this.params.srj.defaultObstacleMargin??this.params.srj.minTraceToPadEdgeClearance??.15,effort:this.params.effort}),p=performance.now(),m=(({originalSrj:t,routes:e,syntheticConnectionNames:n,drcEvaluator:o})=\u003e{const i={routes:e,attemptedRegionCount:0,acceptedRegionCount:0,candidateAttemptCount:0,pathSearchNodeCount:0,referenceValidationCount:0,initialDrcIssueCount:void 0,finalDrcIssueCount:void 0,repaired:!1};if(t.traces?.length||n.size\u003e0)return i;const r=Math.max(t.defaultObstacleMargin??.2,t.minTraceToPadEdgeClearance??0,t.minViaEdgeToPadEdgeClearance??0);let s=Math.max(t.minTraceWidth,t.minViaDiameter??0);for(const t of e){s=Math.max(s,t.traceThickness,t.viaDiameter);for(const e of t.route)s=Math.max(s,e.traceThickness??0)}const a=Math.max(.5,s+r),c=Z6.filter(t=\u003e!Number.isFinite(a)||2*a\u003ct);if(0===c.length)return i;let l=e,d=o({traces:[],routes:e,hdRoutes:e});i.referenceValidationCount++;let h=Array.isArray(d)?d:d.errors;if(i.initialDrcIssueCount=h.length,i.finalDrcIssueCount=h.length,0===h.length)return i;const u={...fX(t),traces:void 0},p=[];let m=new Map(P6({srj:u,routes:l}).map(t=\u003e[t.key,t.severity]));for(;i.attemptedRegionCount\u003c4;){const t=(Array.isArray(d)?d:d.errorsWithCenters??d.errors).map(t=\u003et.center??t.pcb_center).filter(t=\u003enull!==t\u0026\u0026\"object\"==typeof t\u0026\u0026\"x\"in t\u0026\u0026\"y\"in t\u0026\u0026\"number\"==typeof t.x\u0026\u0026\"number\"==typeof t.y\u0026\u0026Number.isFinite(t.x)\u0026\u0026Number.isFinite(t.y));let e;for(const n of c){const o=t.find(({x:t,y:e})=\u003e!p.some(({bounds:o,size:i})=\u003en===i\u0026\u0026t\u003e=o.minX\u0026\u0026t\u003c=o.maxX\u0026\u0026e\u003e=o.minY\u0026\u0026e\u003c=o.maxY));if(o){e={center:o,size:n};break}}if(!e)break;const{center:n,size:r}=e,s=j6({srj:u,routes:l,bounds:{minX:n.x-r/2,maxX:n.x+r/2,minY:n.y-r/2,maxY:n.y+r/2}});if(p.push({bounds:s.mutableBounds,size:r}),i.attemptedRegionCount++,0===s.routes.length)continue;const a=new A6({srj:s.srj,routes:s.routes,bounds:s.bounds,boundaryMargin:s.boundaryMargin,lockedPointIndices:s.lockedPointIndices,maxCandidates:256,maxCandidateAttempts:256,maxPathSearchNodes:U6,allowLayerChanges:!0,traceOnlyFirst:!1});if(a.solve(),a.failed)throw new Error(`Pipeline9 bounded regional repair failed: ${a.error}`);const{candidateAttempts:g,pathSearchNodes:f}=a.stats;if(!Number.isSafeInteger(g)||g\u003c0||g\u003e256||!Number.isSafeInteger(f)||f\u003c0||f\u003eU6)throw new Error(\"Pipeline9 bounded regional repair exceeded its work budget\");i.candidateAttemptCount+=g,i.pathSearchNodeCount+=f;const y=G6({routes:l,region:s,repairedRoutes:a.getOutput()});if(y.every((t,e)=\u003et===l[e]))continue;const _=P6({srj:u,routes:y});if(!_.every(({key:t,severity:e})=\u003em.has(t)\u0026\u0026e\u003c=m.get(t)+1e-8)||w6({srj:u,previousRoutes:l,routes:y}).length\u003e0)continue;const b=o({traces:[],routes:y,hdRoutes:y});i.referenceValidationCount++;const x=Array.isArray(b)?b:b.errors;if(!(x.length\u003e=h.length)\u0026\u0026(l=y,h=x,d=b,m=new Map(_.map(t=\u003e[t.key,t.severity])),i.acceptedRegionCount++,i.finalDrcIssueCount=h.length,0===h.length))return i.routes=l,i.repaired=!0,i}return i})({originalSrj:this.params.originalSrj,routes:u.routes,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.cachedReferenceDrcEvaluator});this.combinedOutput=m.routes,this.stats={...this.stats,...this.exactRepairSolver.stats,postExactIndexedDrcIssueCount:n,postExactReferenceValidationAttempted:!0,postExactReferenceDrcIssueCount:o,postExactReferenceAccepted:!1,clearancePrecisionCandidateCount:i,clearancePrecisionCandidateValidationCount:r,clearancePrecisionReferenceValidationCount:s,clearancePrecisionRepaired:a,boundedRegionalRepairAttemptedRegionCount:m.attemptedRegionCount,boundedRegionalRepairAcceptedRegionCount:m.acceptedRegionCount,boundedRegionalRepairCandidateAttemptCount:m.candidateAttemptCount,boundedRegionalRepairPathSearchNodeCount:m.pathSearchNodeCount,boundedRegionalRepairReferenceValidationCount:m.referenceValidationCount,boundedRegionalRepairRepaired:m.repaired,boundedRegionalRepairTimeMs:performance.now()-p,regionalB01RepairCandidateCount:u.attemptedCandidateCount,regionalB01RepairAcceptedCount:u.acceptedCandidateCount,regionalB01RepairFallbackCandidateCount:u.fallbackCandidateCount,regionalB01RepairCandidateSearchCount:u.candidateSearchCount,regionalB01RepairCandidateSearchBudget:u.candidateSearchBudget,regionalB01RepairCandidateSearchBudgetExhausted:u.candidateSearchBudgetExhausted,regionalB01RepairSafeTraceLayerSkippedForBudget:u.safeTraceLayerRepairSkippedForBudget,regionalB01RepairRemainingDrcIssueCount:u.remainingDrcIssueCount,regionalB01RepairPreloadEligibleDrcIssueCount:u.preloadEligibleDrcIssueCount,regionalB01RepairAttempted:u.preloadRepairAttempted,regionalB01RepairTraceIdCount:h.size+(h.collidingFixedTraceIds?.size??0),terminalEscapeCandidateCount:d.attemptedCandidateCount,terminalEscapeAcceptedCount:d.acceptedCandidateCount,referenceDrcValidationCount:this.referenceDrcValidationCount,referenceDrcFalseNegativeCount:this.referenceDrcFalseNegativeCount,indexedDrcEvaluationCount:this.indexedDrcEvaluationCount,indexedDrcCacheHitCount:this.indexedDrcCacheHitCount,indexedDrcEvaluationTimeMs:this.indexedDrcEvaluationTimeMs,indexedDrcCandidateCacheSize:this.indexedDrcCandidateCache.size,indexedDrcCandidateCacheCapacity:64},this.solved=!0}getCombinedOutput(){return this.combinedOutput??this.exactRepairSolver?.getOutput()??this.inputNewHdRoutes}getOutput(){return this.getCombinedOutput().filter(t=\u003e!this.syntheticConnectionNames.has(t.connectionName))}getUpdatedPreloadedTraces(){const t=new Map(this.getCombinedOutput().map(t=\u003e[t.connectionName,t])),e=new Map;for(const n of this.movablePreloadedSections){const o=t.get(n.syntheticConnectionName);if(!o)throw new Error(`Pipeline9 joint DRC repair output is missing \"${n.syntheticConnectionName}\"`);const i=n.originalTrace.pcb_trace_id,r=e.get(i)??[];r.push({routePositionStart:n.originalRoutePositionStart,routePositionEnd:n.originalRoutePositionEnd,route:Mo(o,this.params.layerCount,{defaultViaHoleDiameter:this.params.defaultViaHoleDiameter,obstacles:this.params.obstacles,connMap:this.params.connMap})}),e.set(i,r)}const n=new Map([...e].map(([t,e])=\u003e{const n=this.inputUpdatedPreloadedTraces.find(e=\u003ee.pcb_trace_id===t);if(!n)throw new Error(`Pipeline9 cannot find preloaded trace \"${t}\" while rebuilding repaired sections`);return[t,O9({originalTrace:n,repairedSections:e})]}));return this.inputUpdatedPreloadedTraces.map(t=\u003en.get(t.pcb_trace_id)??t)}getMutatedPreloadedTraces(){const t=new Set([...this.params.mutatedPreloadedTraceIds,...this.movablePreloadedSections.map(t=\u003et.originalTrace.pcb_trace_id)]);return this.getUpdatedPreloadedTraces().filter(e=\u003et.has(e.pcb_trace_id))}visualize(){return this.exactRepairSolver?.visualize()??{}}},L9=1e-6,D9=(t,e,n)=\u003e{const o=ko(t,n),i=ko(e,n);return Array.from({length:Math.abs(i-o)+1},(t,e)=\u003eMath.min(o,i)+e)},z9=t=\u003e\"wire\"===t.route_type,F9=(t,e,n)=\u003et.portPoints.filter(t=\u003et.availableZ.includes(n)\u0026\u0026!(t._preloadedTracePortAssignments??[]).some(t=\u003et.z===n\u0026\u0026t.fixedNetId!==e.fixedNetId)).map(t=\u003e({portPoint:t,distance:be(t,e.start,e.end)})).sort((t,e)=\u003et.distance-e.distance||t.portPoint.distToCentermostPortOnZ-e.portPoint.distToCentermostPortOnZ||t.portPoint.segmentPortPointId.localeCompare(e.portPoint.segmentPortPointId))[0]?.portPoint,B9=(t,e,n)=\u003e{t._preloadedFixedNetIds=[...new Set([...t._preloadedFixedNetIds??[],e.fixedNetId])].sort();const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.start.x)*o+(t.y-e.start.y)*i)/r)),a={traceId:e.traceId,fixedNetId:e.fixedNetId,routePosition:e.routePositionStart+s*(e.routePositionEnd-e.routePositionStart),tracePoint:{x:e.start.x+s*o,y:e.start.y+s*i},z:n},c=t._preloadedTracePortAssignments??[];c.some(t=\u003et.traceId===a.traceId\u0026\u0026t.fixedNetId===a.fixedNetId\u0026\u0026t.z===a.z\u0026\u0026Math.abs(t.routePosition-a.routePosition)\u003c=L9)||(t._preloadedTracePortAssignments=[...c,a].sort((t,e)=\u003et.traceId.localeCompare(e.traceId)||t.routePosition-e.routePosition||t.z-e.z))},j9=class extends si{constructor(t,e){super(),this.sharedEdgeSegments=t,this.srj=e,this.MAX_ITERATIONS=1,this.primitives=(t=\u003e{const e=[],n=ii(t);for(const o of t.traces??[]){if(!o.connection_name)throw new Error(`Preloaded trace \"${o.pcb_trace_id}\" is missing a connection name`);const i=n.getNetConnectedToId(o.connection_name)??o.connection_name;for(const[n,r]of o.route.entries())if(\"via\"===r.route_type)e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n,zLayers:D9(r.from_layer,r.to_layer,t.layerCount),start:r,end:r});else if(\"through_obstacle\"===r.route_type)e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n+1,zLayers:D9(r.from_layer,r.to_layer,t.layerCount),start:r.start,end:r.end});else if(\"jumper\"===r.route_type){const s=ko(r.layer,t.layerCount);for(const[t,a]of[r.start,r.end].entries())e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n+t,routePositionEnd:n+t,zLayers:[s],start:a,end:a})}for(let n=0;n\u003co.route.length-1;n++){const r=o.route[n],s=o.route[n+1];z9(r)\u0026\u0026z9(s)\u0026\u0026r.layer===s.layer\u0026\u0026e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n+1,zLayers:[ko(r.layer,t.layerCount)],start:r,end:s})}}return e})(e)}sharedEdgeSegments;srj;primitives;getSolverName(){return\"PreloadedTraceGraphSolver\"}_step(){for(const t of this.primitives)for(const e of this.sharedEdgeSegments)if(!(Ra(t.start,t.end,e.start,e.end)\u003eL9))for(const n of t.zLayers){if(!e.availableZ.includes(n))continue;const o=F9(e,t,n);o\u0026\u0026B9(o,t,n)}const t=this.sharedEdgeSegments.flatMap(t=\u003et.portPoints),e=t.filter(t=\u003e(t._preloadedFixedNetIds?.length??0)\u003e0);this.stats={preloadedTraceCount:this.srj.traces?.length??0,preloadedTraceShapeCount:this.primitives.length,inputBoundaryCount:this.sharedEdgeSegments.length,outputBoundaryCount:this.sharedEdgeSegments.length,inputPortCount:t.length,outputPortCount:t.length,preloadedPortCount:e.length,tracePortAssignmentCount:e.reduce((t,e)=\u003et+(e._preloadedTracePortAssignments?.length??0),0),topologyChanged:!1},this.solved=!0}getOutput(){if(!this.solved)throw new Error(\"PreloadedTraceGraphSolver has not solved yet\");return this.sharedEdgeSegments}},$9=class extends _X{_step(){const{traces:t,...e}=this.inputSrj,n=fX(e),o=fX(aX(yX(n)));this.outputSrj=void 0===t?o:{...o,traces:t},this.solved=!0}};function Y9(t){return new Set((t??[]).filter(t=\u003et._isComponentTopologyNode).map(t=\u003et.capacityMeshNodeId))}function X9(t,e){return t.nodeIds.some(t=\u003ee.has(t))}function V9({sharedEdgeSegments:t,componentCapacityMeshNodeIds:e}){return t.filter(t=\u003e!X9(t,e))}function W9(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var H9=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e;const n=fX(t);this.originalSrj=n,this.opts={...e};const o=this.opts;if(this.effort=o.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=o.maxNodeDimension??15,this.maxNodeRatio=o.maxNodeRatio??6,this.minNodeArea=o.minNodeArea??.1**2,this.visualizationTraceColorMode=o.visualizationTraceColorMode??\"layer\",this.setSimpleRouteJson(n),void 0===o.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,n=Math.max(t,e),i=o.targetMinCapacity??.5;o.capacityDepth=$s(n,i)}this.cacheProvider=void 0===o.cacheProvider?oo():null===o.cacheProvider?null:o.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;getSolverName(){return\"AutoroutingPipelineSolver9_PreloadedTraceGraph\"}preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;componentTopologyGeneratorSolver;topologyPlanningSolver;topologyMergingSolver;globalTopologyGeneratorSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;pipeline9JointDrcRepairSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;mutatedPreloadedTraceSimplificationSolver;lengthMatchingPostProcessingSolver;powerTraceExpansionSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;preloadedTraceGraphSolver;componentDetectionSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;visualizationTraceColorMode;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;sharedEdgeSegmentsWithNecessaryCrampedPortPoints;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[W9(\"preprocessSimpleRouteJsonSolver\",$9,t=\u003e[t.originalSrj,{traceColorMode:t.visualizationTraceColorMode}],{onSolved:t=\u003e{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),W9(\"componentDetectionSolver\",UZ,t=\u003e[{inputSrj:t.srj}]),W9(\"escapeViaLocationSolver\",Uj,t=\u003e[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),W9(\"netToPointPairsSolver\",ga,t=\u003e{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),W9(\"topologyPlanningSolver\",_q,t=\u003e[{inputSrj:t.srjWithPointPairs,componentDetectionOutput:t.componentDetectionSolver.getOutput(),viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=\u003e{t.topologyPlanningSolver.getOutput();t.globalTopologyGeneratorSolver=t.topologyPlanningSolver.globalTopologySolver,t.componentTopologyGeneratorSolver=new vq(t.topologyPlanningSolver)}}),W9(\"topologyMergingSolver\",fq,t=\u003e{const e=t.topologyPlanningSolver.getOutput();return[{layerCount:t.srj.layerCount,nodeGroups:[{groupId:\"global\",nodes:e.globalMeshNodes,isComponent:!1},...e.componentMeshNodes.map((t,e)=\u003e({groupId:`component-${e}`,nodes:t,isComponent:!0}))]}]},{onSolved:t=\u003e{t.capacityNodes=t.topologyMergingSolver.getOutput()}}),W9(\"nodeDimensionSubdivisionSolver\",Tz,t=\u003e[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=\u003e{t.capacityNodes=t.nodeDimensionSubdivisionSolver.outputNodes}}),W9(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),W9(\"availableSegmentPointSolver\",ci,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),W9(\"necessaryCrampedPortPointSolver\",sf,t=\u003e{const e=Y9(t.capacityNodes);return[{capacityMeshNodes:t.capacityNodes.filter(t=\u003e!e.has(t.capacityMeshNodeId)),sharedEdgeSegments:V9({sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),componentCapacityMeshNodeIds:e}),simpleRouteJson:t.srjWithPointPairs}]},{onSolved:t=\u003e{const e=Y9(t.capacityNodes);t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints=function({originalSharedEdgeSegments:t,filteredSharedEdgeSegments:e,componentCapacityMeshNodeIds:n}){const o=new Map(e.map(t=\u003e[t.edgeId,t]));return t.map(t=\u003eX9(t,n)?t:o.get(t.edgeId)??t)}({originalSharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),filteredSharedEdgeSegments:t.necessaryCrampedPortPointSolver.getOutput(),componentCapacityMeshNodeIds:e})}}),W9(\"preloadedTraceGraphSolver\",j9,t=\u003e[t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints,t.srjWithPointPairs]),W9(\"portPointPathingSolver\",jj,t=\u003e{const e=t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints??t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=\u003et.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,preserveTerminalPcbPortIds:!0,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0,USE_SELECTIVE_RERIP_ROUTING:!0,USE_PARTIAL_RIP_ROUTING_WITH_PRELOADED_TRACES:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),W9(\"uniformPortDistributionSolver\",go,t=\u003e[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),W9(\"highDensityRouteSolver\",VQ,t=\u003e{const e=t.portPointPathingSolver;if(!e)throw new Error(\"Pipeline9 invariant violated: high-density routing requires the completed port-point pathing solver\");const n=e.getOutput(),o=t.uniformPortDistributionSolver?.getOutput()??[],i=n.nodesWithPortPoints,r=o.length\u003e0?o:i;t.highDensityNodePortPoints=structuredClone(r);const s=(t.originalSrj.traces??[]).flatMap((e,n)=\u003eoQ(e,n,t.originalSrj.layerCount,t.viaDiameter,t.connMap));return[{nodePortPoints:r,fixedHdRoutes:TK({traces:t.originalSrj.traces??[],fixedHdRoutes:s,sections:t.getChangedPreloadedTraceSections()}),connMap:t.connMap,colorMap:t.colorMap,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,viaToPadClearance:t.srj.minViaEdgeToPadEdgeClearance,effort:t.effort,includeBoardObstacles:!0,nodePfById:new Map(n.inputNodeWithPortPoints.map(t=\u003e[t.capacityMeshNodeId,e.computeNodePf(t)])),preserveTerminalPcbPortIds:!0}]}),W9(\"highDensityForceImproveSolver\",Yy,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:AK(t.highDensityRouteSolver.routes),colorMap:t.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),W9(\"highDensityRepairSolver\",AY,t=\u003e[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2,maxSampleEntries:80,connMap:t.connMap}]),W9(\"highDensityStitchSolver\",KY,t=\u003e[{connections:[...t.srjWithPointPairs.connections,...t.getChangedPreloadedTraceSections().map(t=\u003et.connection)],hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,preserveTerminalPcbPortIds:!0,preferSameLayerTerminalEndpoints:!0}]),W9(\"traceSimplificationSolver\",vc,t=\u003e{const e=t.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces.flatMap((e,n)=\u003eoQ(e,n,t.originalSrj.layerCount,t.viaDiameter,t.connMap).map(t=\u003e({...t,rootConnectionName:e.connection_name}))),n=new Set(t.getChangedPreloadedTraceSections().map(t=\u003et.connectionName)),o=t.highDensityStitchSolver.mergedHdRoutes.filter(t=\u003e!n.has(t.connectionName)),i=IK([...o,...e],t.connMap);return[{hdRoutes:o,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,otherHdRoutes:e,netByConnectionName:i,enableCrossingViaReduction:!0,terminalLayerIndicesByPcbPortId:SK(t.srj.connections,t.srj.obstacles,t.srj.layerCount),iterations:2}]}),W9(\"mutatedPreloadedTraceSimplificationSolver\",vc,t=\u003e{const e=t.getPreparedMutatedPreloadedTraceSections(),n=e.sections.map(t=\u003et.hdRoute),o=[...e.immutableHdRoutes,...t.traceSimplificationSolver.simplifiedHdRoutes];return[{hdRoutes:n,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,otherHdRoutes:o,netByConnectionName:IK([...n,...o],t.connMap),enableCrossingViaReduction:!0,preserveRouteEndpoints:!0,iterations:2}]}),W9(\"traceWidthSolver\",Ic,t=\u003e[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srjWithPointPairs.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),W9(\"globalDrcForceImproveSolver\",Nz,t=\u003e[{srj:t.getSrjWithMaterializedPreloadedTraces(),hdRoutes:KJ(t.traceWidthSolver.getHdRoutesWithWidths(),t.netToPointPairsSolver?.newConnections??[],new Map((t.highDensityStitchSolver?.mergedHdRoutes??[]).map(t=\u003e[t.connectionName,t]))),connMap:t.connMap,effort:t.effort,maxIterations:16,enableLargeBoardBroadFallback:!1,enablePostSolveClearanceRelaxation:!1}]),W9(\"pipeline9JointDrcRepairSolver\",k9,t=\u003e{const e=t.getPreloadedTraceUpdatesAfterHighDensity(),n=t.getSrjWithMaterializedPreloadedTraces();return[{srj:n,srjWithPointPairs:n,originalSrj:t.originalSrj,newConnections:t.netToPointPairsSolver?.newConnections??[],newHdRoutes:t.globalDrcForceImproveSolver.getOutput(),updatedPreloadedTraces:e.updatedPreloadedTraces,mutatedPreloadedTraceIds:new Set(e.mutatedPreloadedTraces.map(t=\u003et.pcb_trace_id)),connMap:t.connMap,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,defaultViaHoleDiameter:t.viaHoleDiameter,effort:t.effort,colorMap:t.colorMap}]}),W9(\"lengthMatchingPostProcessingSolver\",uK,t=\u003e{const e=t.netToPointPairsSolver;if(!e)throw new Error(\"Pipeline9: length-matching post-processing requires NetToPointPairsSolver output\");const n=e.newConnections,o=new Map;for(const e of t.srj.differentialPairs??[])for(const t of e.connectionNames){const e=n.filter(e=\u003ee.name===t||e.__rootConnectionNames?.includes(t)||e.__netConnectionName===t);if(1!==e.length)throw new Error(`Pipeline9: differential pair connection \"${t}\" must resolve to exactly one final point-pair connection, got ${e.length}`);o.set(t,e[0].name)}const i=t.pipeline9JointDrcRepairSolver.getOutput(),r=(t.srj.differentialPairs??[]).map(t=\u003e{const e=t.connectionNames.map(t=\u003e{const e=o.get(t);if(!e)throw new Error(`Pipeline9: differential pair connection \"${t}\" is missing from final routed output`);return e});if(e[0]===e[1])throw new Error(`Pipeline9: differential pair ${t.connectionNames.join(\"/\")} resolves both members to \"${e[0]}\"`);if(void 0===t.traceGap)return{connectionNames:e,lengthTolerance:t.lengthTolerance};const n=e.map(t=\u003e{const e=i.filter(e=\u003ee.connectionName===t);if(1!==e.length)throw new Error(`Pipeline9: differential pair connection \"${t}\" must resolve to exactly one final HD route, got ${e.length}`);return e[0]}),r=t.traceGap+n.reduce((t,e)=\u003et+e.traceThickness/2,0);return{connectionNames:e,lengthTolerance:t.lengthTolerance,minimumCenterlineDistance:r,maximumCenterlineDistance:r}});return[{hdRoutes:i,differentialPairs:r,buses:t.srj.buses??[],connections:t.srj.connections,obstacles:t.srj.obstacles,bounds:t.srj.bounds,layerCount:t.srj.layerCount,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15}]}),W9(\"powerTraceExpansionSolver\",UJ,t=\u003e{const e=t.opts.powerTraceExpansion??{},n=e.onlyConnectionNames??JJ(t.originalSrj);return[QJ({originalSrj:t.originalSrj,newlyRoutedTraces:t.getNewTracesBeforePowerExpansion(),currentPreloadedTraces:t.getUpdatedPreloadedTraces(),expandedConnectionNames:n,resolveConnectedTraceAliases:!0}),{allowNewVias:!1,...e,onlyConnectionNames:n}]})];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;computeProgress(){const t=this.activeSubSolver?.progress??0;return(this.currentPipelineStepIndex+t)/this.pipelineDef.length}_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\u0026\u0026(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),\"lengthMatchingPostProcessingSolver\"!==t.solverName\u0026\u0026\"powerTraceExpansionSolver\"!==t.solverName||(this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,this.iterations+this.activeSubSolver.MAX_ITERATIONS+1)),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\u0026\u0026this.activeSubSolver)return this.visualizeStage(this.activeSubSolver);const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.componentDetectionSolver?.visualize(),o=this.componentTopologyGeneratorSolver?.visualize(),i=this.globalTopologyGeneratorSolver?.visualize(),r=this.topologyMergingSolver?.visualize(),s=this.nodeDimensionSubdivisionSolver?.visualize(),a=this.nodeTargetMerger?.visualize(),c=this.singleLayerNodeMerger?.visualize(),l=this.strawSolver?.visualize(),d=this.edgeSolver?.visualize(),h=this.deadEndSolver?.visualize(),u=this.availableSegmentPointSolver?.visualize(),p=this.portPointPathingSolver?.visualize(),m=this.multiSectionPortPointOptimizer?.visualize(),g=this.uniformPortDistributionSolver?.visualize(),f=this.highDensityRouteSolver?.visualize(),y=this.highDensityForceImproveSolver?.visualize(),_=this.highDensityRepairSolver?.visualize(),b=this.highDensityStitchSolver?.visualize(),x=this.traceSimplificationSolver?.visualize(),v=this.mutatedPreloadedTraceSimplificationSolver?.visualize(),S=this.lengthMatchingPostProcessingSolver?.visualize(),I=this.powerTraceExpansionSolver?.visualize(),C=this.traceWidthSolver?.visualize(),P=this.necessaryCrampedPortPointSolver?.visualize(),M=(this.highDensityRouteSolver?.visualize(),this.originalSrj),N=M.outline,w=[];if(w.push({points:[{x:M.bounds?.minX??-50,y:M.bounds?.minY??-50},{x:M.bounds?.maxX??50,y:M.bounds?.minY??-50},{x:M.bounds?.maxX??50,y:M.bounds?.maxY??50},{x:M.bounds?.minX??-50,y:M.bounds?.maxY??50},{x:M.bounds?.minX??-50,y:M.bounds?.minY??-50}],strokeColor:\"rgba(255,0,0,0.25)\"}),N\u0026\u0026N.length\u003e=2){const t=N.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),w.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const T=Oo(M),R={points:[...M.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,M.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(M.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,M.layerCount),label:T(t)}))],lines:w},E={traceColorMode:this.visualizationTraceColorMode},A=Yj({srj:M,visualizationOptions:E}),O=pi(R,A),k=this.preprocessSimpleRouteJsonSolver?.visualize(),L=this.globalDrcForceImproveSolver?.visualize(),D=this.pipeline9JointDrcRepairSolver?.visualize(),z=[O,k,n,o,t,e,i,r,s,a,c,l,d,h,u,P,p,m,g,f?pi(R,f):null,y,_,b,x,v,C,L,D,S,I,this.solved?pi({lines:w},Yj({srj:this.originalSrj,visualizationOptions:E}),this.visualizeFinalOutput()):null].filter(Boolean),F=pi(...z);return\"net\"===this.visualizationTraceColorMode?xq(F,this.colorMap):F}visualizeStage(t){const e=t.visualize();return\"net\"===this.visualizationTraceColorMode?xq(e,this.colorMap):e}visualizeFinalOutput(){const t=this.visualizationTraceColorMode,e=this.getOutputSimpleRouteJson();return Ho(e,{traceColorMode:t})}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.componentTopologyGeneratorSolver?this.componentTopologyGeneratorSolver.visualize():this.componentDetectionSolver?this.componentDetectionSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){if(((this.originalSrj.differentialPairs?.length??0)\u003e0||(this.originalSrj.buses??[]).some(t=\u003evoid 0!==t.maxLengthSkew))\u0026\u0026this.lengthMatchingPostProcessingSolver){const{hdRoutes:t}=this.lengthMatchingPostProcessingSolver.getOutput();return t}return this.pipeline9JointDrcRepairSolver?.getOutput()??this.globalDrcForceImproveSolver?.getOutput()??this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOriginalFixedHdRoutes(){return(this.originalSrj.traces??[]).flatMap((t,e)=\u003eoQ(t,e,this.originalSrj.layerCount,this.viaDiameter,this.connMap))}getChangedPreloadedTraceSections(){return this.portPointPathingSolver?.getOutput().changedPreloadedTraceSections??[]}getPreloadedFixedRouteStateAfterHighDensity(){const t=this.getOriginalFixedHdRoutes(),e=this.getChangedPreloadedTraceSections(),n=TK({traces:this.originalSrj.traces??[],fixedHdRoutes:t,sections:e}),o=0===e.length?[]:RK({traces:this.originalSrj.traces??[],sections:e,stitchedHdRoutes:this.highDensityStitchSolver?.mergedHdRoutes??[],layerCount:this.originalSrj.layerCount}),i=new Set(e.map(t=\u003et.traceId)),r=t.filter(t=\u003ei.has(this.originalSrj.traces?.[t.preloadedTraceIndex]?.pcb_trace_id??\"\")).map(t=\u003et.connectionName);return{originalFixedRoutes:t,updatedFixedRoutes:[...this.highDensityRouteSolver?.getUpdatedFixedHdRoutes()??n,...o],replacedConnectionNames:new Set([...this.highDensityRouteSolver?.fixedRouteReplacements.keys()??[],...r]),mutationMasks:new Map([...this.highDensityRouteSolver?.preloadedTraceMutationMasks??[],...o.map(t=\u003e[t.connectionName,Array(t.route.length-1).fill(!0)])])}}getPreparedMutatedPreloadedTraceSections(){const t=this.getPreloadedFixedRouteStateAfterHighDensity();return eQ({updatedFixedRoutes:t.updatedFixedRoutes,regionalMutationMasks:t.mutationMasks})}getPreloadedTraceUpdatesAfterHighDensity(){const t=this.getPreloadedFixedRouteStateAfterHighDensity(),e=this.getPreparedMutatedPreloadedTraceSections(),n=!0===this.mutatedPreloadedTraceSimplificationSolver?.solved?(({updatedFixedRoutes:t,sections:e,simplifiedHdRoutes:n})=\u003e{const o=new Set(e.map(t=\u003et.connectionName)),i=new Map(n.map(t=\u003e[t.connectionName,t]));if(i.size!==e.length||n.some(t=\u003e!o.has(t.connectionName)))throw new Error(`Pipeline9 trace simplification changed the mutation-section set (expected ${e.length}, got ${n.length})`);const r=new Map,s=new Set;for(const t of e){const e=i.get(t.connectionName);if(!e)throw new Error(`Pipeline9 trace simplification lost mutation section \"${t.connectionName}\"`);const n=e.route[0],o=e.route.at(-1);if(!(n\u0026\u0026o\u0026\u0026HK(n,t.section.start.point)\u0026\u0026HK(o,t.section.end.point)))throw new Error(`Pipeline9 trace simplification changed mutation-section boundary \"${t.connectionName}\"`);const a=XK(t.section,e),c=t.section.sourceRoutes[0];s.add(c.connectionName);for(const e of t.section.sourceRoutes){if(r.has(e.connectionName))throw new Error(`Pipeline9 attempted to simplify fixed route \"${e.connectionName}\" more than once`);r.set(e.connectionName,a)}}return t.flatMap(t=\u003e{const e=r.get(t.connectionName);return e?s.has(t.connectionName)?[e]:[]:[t]})})({updatedFixedRoutes:e.normalizedFixedRoutes,sections:e.sections,simplifiedHdRoutes:this.mutatedPreloadedTraceSimplificationSolver.simplifiedHdRoutes}):t.updatedFixedRoutes;return(({originalTraces:t,originalFixedRoutes:e,updatedFixedRoutes:n,replacedConnectionNames:o,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a})=\u003e{const c=new Map,l=new Map;for(const t of e){const e=c.get(t.preloadedTraceIndex)??[];e.push(t),c.set(t.preloadedTraceIndex,e)}for(const t of n){const e=l.get(t.preloadedTraceIndex)??[];e.push(t),l.set(t.preloadedTraceIndex,e)}const d=[];return{updatedPreloadedTraces:t.map((t,e)=\u003e{const n=(c.get(e)??[]).sort(fK);if(!n.some(t=\u003eo.has(t.connectionName)))return t;const h=(l.get(e)??[]).sort(fK),u=t.route.some(t=\u003e\"through_obstacle\"===t.route_type),p={...t,__replaces_pcb_trace_id:t.pcb_trace_id,route:u?xK({trace:t,originalTraceRoutes:n,updatedTraceRoutes:h,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a}):_K({trace:t,updatedTraceRoutes:h,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a})};return d.push(p),p}),mutatedPreloadedTraces:d}})({originalTraces:this.originalSrj.traces??[],originalFixedRoutes:t.originalFixedRoutes,updatedFixedRoutes:n,replacedConnectionNames:t.replacedConnectionNames,layerCount:this.originalSrj.layerCount,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.originalSrj.obstacles,connMap:this.connMap})}getSrjWithMaterializedPreloadedTraces(){return{...this.srjWithPointPairs,traces:this.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces}}getUpdatedPreloadedTraces(){return this.pipeline9JointDrcRepairSolver?.getUpdatedPreloadedTraces()??this.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces}getMutatedPreloadedTraces(){return this.pipeline9JointDrcRepairSolver?.getMutatedPreloadedTraces()??this.getPreloadedTraceUpdatesAfterHighDensity().mutatedPreloadedTraces}getNewTracesBeforePowerExpansion(){if(!this.highDensityRouteSolver)throw new Error(\"Cannot get new traces before high-density routing\");const t=qJ({connections:this.netToPointPairsSolver?.newConnections??[],originalConnections:this.originalSrj.connections,hdRoutes:this._getOutputHdRoutes(),layerCount:this.srj.layerCount,obstacles:this.srj.obstacles,defaultViaHoleDiameter:this.viaHoleDiameter,connMap:this.connMap});return vK(t,this.originalSrj.traces??[])}getPowerTraceExpansionFixedTraces(){if(!this.powerTraceExpansionSolver)throw new Error(\"Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver\");return this.powerTraceExpansionSolver.inputSrj.fixedTraces}getOutputSimplifiedPcbTraces(){if(!this.solved)throw new Error(\"Cannot get output before solving is complete\");if(!this.powerTraceExpansionSolver)throw new Error(\"Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver\");return[...this.getPowerTraceExpansionFixedTraces().filter(t=\u003evoid 0!==t.__replaces_pcb_trace_id),...this.powerTraceExpansionSolver.getOutput()]}getOutputSimpleRouteJson(){if(!this.solved)throw new Error(\"Cannot get output before solving is complete\");if(!this.powerTraceExpansionSolver)throw new Error(\"Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver\");const t=[...this.getPowerTraceExpansionFixedTraces(),...this.powerTraceExpansionSolver.getOutput()];return{...this.originalSrj,traces:t}}},G9=String(\"0.0.886\"),U9=({nodeWithPortPoints:t,obstacleMargin:e,traceWidth:n,viaDiameter:o})=\u003e{const i=ro(t),r=e+Math.max(n,o)/2+1e-6;return{minX:t.center.x+8*(i.minX-t.center.x)-r,maxX:t.center.x+8*(i.maxX-t.center.x)+r,minY:t.center.y+8*(i.minY-t.center.y)-r,maxY:t.center.y+8*(i.maxY-t.center.y)+r}},Z9=(t,e)=\u003e{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.abs(Math.cos(n)),i=Math.abs(Math.sin(n)),r=t.width/2,s=t.height/2,a=Math.max(r,r*o+s*i),c=Math.max(s,r*i+s*o);return t.center.x-a\u003c=e.maxX\u0026\u0026t.center.x+a\u003e=e.minX\u0026\u0026t.center.y-c\u003c=e.maxY\u0026\u0026t.center.y+c\u003e=e.minY},q9=(t,e)=\u003e{for(const n of[e.connectionName,e.rootConnectionName,e.portPointId,e.pcb_port_id,e.prevPortPointId,e.nextPortPointId])void 0!==n\u0026\u0026t.add(n)},J9=(t,e)=\u003eObject.fromEntries(Object.entries(t.netMap).flatMap(([t,n])=\u003e{const o=n.filter(t=\u003ee.has(t));return o.length\u003e0||e.has(t)?[[t,o]]:[]})),K9=({obstacle:t,connectedTo:e,preserveRotation:n})=\u003e({type:\"rect\",layers:t.layers,...void 0===t.zLayers?{}:{zLayers:t.zLayers},...void 0===t.__zLayers?{}:{__zLayers:t.__zLayers},center:t.center,width:t.width,height:t.height,...n\u0026\u0026void 0!==t.ccwRotationDegrees?{ccwRotationDegrees:t.ccwRotationDegrees}:{},connectedTo:e,...void 0===t.circuitJsonMetadata?{}:{circuitJsonMetadata:t.circuitJsonMetadata}});function Q9({nodeWithPortPoints:t,connMap:e,obstacles:n,obstacleMargin:o,traceWidth:i,viaDiameter:r}){const s=U9({nodeWithPortPoints:t,obstacleMargin:o,traceWidth:i,viaDiameter:r}),a=new Set;for(const e of t.portPoints)q9(a,e);for(const e of t.portPointsInPairs??[])q9(a,e[0]),q9(a,e[1]);const c=n.flatMap(n=\u003e{if(!Z9(n,s))return[];const o=(({obstacle:t,nodeWithPortPoints:e,connMap:n})=\u003e{const o=new Set(e.portPoints.flatMap(t=\u003e{const e=n.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName;return[t.connectionName,e]})),i=new Set(t.connectedTo.filter(t=\u003eo.has(t))),r=new Map;for(const t of o){const e=n.getNetConnectedToId(t)??t,o=r.get(e)??[];o.push(t),r.set(e,o)}for(const e of r.values()){if([...i].some(t=\u003ee.some(e=\u003ee===t||n.areIdsConnected(e,t))))continue;const o=t.connectedTo.find(t=\u003ee.some(e=\u003ee===t||n.areIdsConnected(e,t)));void 0!==o\u0026\u0026i.add(o)}return[...i]})({obstacle:n,nodeWithPortPoints:t,connMap:e});for(const t of o)a.add(t);return[K9({obstacle:n,connectedTo:o,preserveRotation:!0})]});return{connectivityNetMap:J9(e,a),obstacles:c}}var t8=(...t)=\u003e{const e=new Map;for(const n of t)for(const[t,o]of Object.entries(n)){const n=e.get(t)??new Set;for(const t of o)n.add(t);e.set(t,n)}return Object.fromEntries([...e].map(([t,e])=\u003e[t,[...e]]))};function e8({nodeWithPortPoints:t,connMap:e,colorMap:n,obstacles:o,obstacleMargin:i,traceWidth:r,viaDiameter:s}){const a=U9({nodeWithPortPoints:t,obstacleMargin:i,traceWidth:r,viaDiameter:s}),c=(t=\u003e[...new Set(t.portPoints.map(t=\u003et.connectionName))])(t),l=o.flatMap(t=\u003e{if(!Z9(t,a))return[];const n=c.filter(n=\u003et.connectedTo.some(t=\u003et===n||e.areIdsConnected(n,t)));return 0===n.length?[]:[K9({obstacle:t,connectedTo:n,preserveRotation:!1})]}),d=new Set;for(const e of t.portPoints)q9(d,e);for(const e of t.portPointsInPairs??[])q9(d,e[0]),q9(d,e[1]);for(const t of l)for(const e of[t.circuitJsonMetadata?.pcb_smtpad_id,t.circuitJsonMetadata?.pcb_plated_hole_id,t.circuitJsonMetadata?.pcb_port_id,t.circuitJsonMetadata?.pcb_via_id,...t.connectedTo??[]])void 0!==e\u0026\u0026d.add(e);return{connectivityNetMap:J9(e,d),colorMap:Object.fromEntries(Object.entries(n??{}).filter(([t])=\u003ed.has(t))),obstacles:l}}var n8=\"https://hd-cache2.tscircuit.com\",o8=31e4,i8=1835008,r8=16777216,s8=class extends Error{constructor(t,e){super(e),this.reason=t,this.name=\"HdCache2RequestError\"}reason},a8=t=\u003et instanceof Error?t.message:String(t),c8=new Set([\"pcb_smtpad_id\",\"pcb_plated_hole_id\",\"pcb_port_id\",\"pcb_via_id\",\"source_component_name\",\"source_port_name\"]),l8=t=\u003e!(!t||\"object\"!=typeof t||Array.isArray(t))\u0026\u0026Object.entries(t).every(([t,e])=\u003ec8.has(t)\u0026\u0026\"string\"==typeof e),d8=(t,e)=\u003eMath.abs(t-e)\u003c=1e-9*Math.max(1,Math.abs(t),Math.abs(e)),h8=1e-6,u8=(t,e)=\u003e{const n=\"ordinary\"===e?h8:.001,o=new Set;for(let i=0;i\u003ct.route.length-1;i++){const r=t.route[i],s=t.route[i+1],a=r.z!==s.z;if(\"through_obstacle\"===r.toNextSegmentType){if(!a)return!1;continue}if(void 0!==r.toNextSegmentCircuitJsonMetadata)return!1;if(!a)continue;const c=[],l=[];for(const[e,o]of t.vias.entries())Math.hypot(o.x-r.x,o.y-r.y)\u003c=n\u0026\u0026c.push(e),Math.hypot(o.x-s.x,o.y-s.y)\u003c=n\u0026\u0026l.push(e);if(Math.hypot(r.x-s.x,r.y-s.y)\u003c=h8){if(0===c.length)return!1;for(const t of c)o.add(t)}else{if(\"regional-fallback\"===e)return!1;if(0===c.length==(0===l.length))return!1;for(const t of[...c,...l])o.add(t)}}const i=t.route.at(-1);return void 0===i.toNextSegmentType\u0026\u0026void 0===i.toNextSegmentCircuitJsonMetadata\u0026\u0026t.vias.every((t,e)=\u003eo.has(e))},p8=(t,e,n)=\u003e{if(!Array.isArray(t))return!1;const o=new Map;for(const t of e.nodeWithPortPoints.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}const i=new Set(e.nodeWithPortPoints.availableZ??e.nodeWithPortPoints.portPoints.map(t=\u003et.z)),r=U9({nodeWithPortPoints:e.nodeWithPortPoints,obstacleMargin:e.obstacleMargin,traceWidth:e.traceWidth,viaDiameter:e.viaDiameter}),s=(t,e)=\u003e(o.get(e)??[]).some(e=\u003e\"number\"==typeof t.x\u0026\u0026d8(t.x,e.x)\u0026\u0026\"number\"==typeof t.y\u0026\u0026d8(t.y,e.y)\u0026\u0026t.z===e.z);for(const a of t){if(!a||\"object\"!=typeof a)return!1;const t=a;if(\"string\"!=typeof t.connectionName||0===t.connectionName.length||!o.has(t.connectionName)||\"number\"!=typeof t.traceThickness||!Number.isFinite(t.traceThickness)||t.traceThickness\u003c=0||\"number\"!=typeof t.viaDiameter||!Number.isFinite(t.viaDiameter)||t.viaDiameter\u003c=0||!d8(t.viaDiameter,e.viaDiameter)||!Array.isArray(t.route)||t.route.length\u003c2||!Array.isArray(t.vias))return!1;for(const e of[t.rootConnectionName,t.startPcbPortId,t.endPcbPortId,t.regionId])if(void 0!==e\u0026\u0026\"string\"!=typeof e)return!1;for(const o of t.route){if(!o||\"object\"!=typeof o)return!1;const t=o;if(\"number\"!=typeof t.x||!Number.isFinite(t.x)||\"number\"!=typeof t.y||!Number.isFinite(t.y)||t.x\u003cr.minX||t.x\u003er.maxX||t.y\u003cr.minY||t.y\u003er.maxY||\"number\"!=typeof t.z||!Number.isInteger(t.z)||t.z\u003c0||t.z\u003e=e.layerCount||\"ordinary\"===n\u0026\u0026!i.has(t.z))return!1;if(void 0!==t.traceThickness\u0026\u0026(\"number\"!=typeof t.traceThickness||!Number.isFinite(t.traceThickness)||t.traceThickness\u003c=0))return!1;if(void 0!==t.pcb_port_id\u0026\u0026\"string\"!=typeof t.pcb_port_id)return!1;if(void 0!==t.insideJumperPad\u0026\u0026\"boolean\"!=typeof t.insideJumperPad)return!1;if(void 0!==t.toNextSegmentType\u0026\u0026\"through_obstacle\"!==t.toNextSegmentType)return!1;if(void 0!==t.toNextSegmentCircuitJsonMetadata\u0026\u0026!l8(t.toNextSegmentCircuitJsonMetadata))return!1}const c=t.route;if(!(\"ordinary\"!==n||s(c[0],t.connectionName)\u0026\u0026s(c.at(-1),t.connectionName)))return!1;for(const e of t.vias){if(!e||\"object\"!=typeof e)return!1;const t=e;if(\"number\"!=typeof t.x||!Number.isFinite(t.x)||\"number\"!=typeof t.y||!Number.isFinite(t.y)||t.x\u003cr.minX||t.x\u003er.maxX||t.y\u003cr.minY||t.y\u003er.maxY)return!1}if(!u8(t,n))return!1;if(void 0!==t.jumpers){if(!Array.isArray(t.jumpers))return!1;for(const e of t.jumpers){if(!e||\"object\"!=typeof e)return!1;const t=e,n=t.start,o=t.end;if(\"jumper\"!==t.route_type||\"0603\"!==t.footprint\u0026\u0026\"1206\"!==t.footprint\u0026\u0026\"1206x4_pair\"!==t.footprint||!n||\"number\"!=typeof n.x||!Number.isFinite(n.x)||\"number\"!=typeof n.y||!Number.isFinite(n.y)||!o||\"number\"!=typeof o.x||!Number.isFinite(o.x)||\"number\"!=typeof o.y||!Number.isFinite(o.y)||n.x\u003cr.minX||n.x\u003er.maxX||n.y\u003cr.minY||n.y\u003er.maxY||o.x\u003cr.minX||o.x\u003er.maxX||o.y\u003cr.minY||o.y\u003er.maxY)return!1}}}const a=t;return\"ordinary\"===n?((t,e)=\u003e{const n=e.portPointsInPairs??[];if(n.length\u003e0){for(const[e,o]of n)if(!xs(t,e.connectionName,_s(e)).has(_s(o)))return!1;return!0}const o=new Map;for(const t of e.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}for(const[e,n]of o)for(const[o,i]of Dr(n))if(!xs(t,e,_s(o)).has(_s(i)))return!1;return!0})(a,e.nodeWithPortPoints):((t,e)=\u003e{const n=(t,e)=\u003e{if(t.z!==e.z)return!1;const n=t.x-e.x,o=t.y-e.y;return Math.hypot(n,o)\u003c=.001},o=new Map;for(const i of t){const t=i.route.some((t,e)=\u003e{const n=i.route[e+1];return!(void 0===n||d8(t.x,n.x)\u0026\u0026d8(t.y,n.y)\u0026\u0026t.z===n.z)}),r=i.route[0],s=i.route.at(-1);if(!t||!r||!s)return!1;const a=e.portPoints.filter(t=\u003et.connectionName===i.connectionName);if(!a.some(t=\u003en(r,t))||!a.some(t=\u003en(s,t)))return!1;const c=o.get(i.connectionName)??[];c.push({start:r,end:s}),o.set(i.connectionName,c)}const i=(t,e,i)=\u003e{if(n(e,i))return!0;const r=o.get(t)??[],s=[],a=new Set;for(const[t,o]of r.entries())(n(e,o.start)||n(e,o.end))\u0026\u0026(s.push(t),a.add(t));for(;s.length\u003e0;){const t=r[s.pop()];if(n(i,t.start)||n(i,t.end))return!0;for(const[e,o]of r.entries())a.has(e)||(n(t.start,o.start)||n(t.start,o.end)||n(t.end,o.start)||n(t.end,o.end))\u0026\u0026(a.add(e),s.push(e))}return!1},r=e.portPointsInPairs??[];if(r.length\u003e0)return r.every(([t,e])=\u003ei(t.connectionName,t,e));const s=new Map;for(const t of e.portPoints){const e=s.get(t.connectionName)??[];e.push(t),s.set(t.connectionName,e)}return[...s].every(([,t])=\u003eDr(t).every(([t,e])=\u003ei(t.connectionName,t,e)))})(a,e.nodeWithPortPoints)},m8=class{constructor(t,e=n8,n={}){this.autorouterVersion=t,this.serverUrl=e;const{cacheVersion:o}=n;if(void 0!==o\u0026\u00260===o.trim().length)throw new Error(\"hd-cache2 cacheVersion must not be empty\");this.cacheVersion=o}autorouterVersion;serverUrl;cacheVersion;stats={batchRequestsStarted:0,batchRequestsCompleted:0,batchItemsStarted:0,batchBodyBytesStarted:0,batchMaxBodyBytes:0,batchCacheMisses:0,singleRequestsStarted:0,batchInvalidLines:0,batchUnknownRequestIds:0,batchDuplicateRequestIds:0};solveMany(t){const e=t.map((t,e)=\u003ethis.createPendingSolve(String(e),t)),n=e.filter(t=\u003enull!==t.serializedItem),{batches:o,singletonSolves:i}=this.prepareBatches(n);for(const t of o)this.fetchBatch(t);for(const t of i)this.launchSingleSolve(t);return e.map(t=\u003et.promise)}createPendingSolve(t,e){let n;const o={requestId:t,input:e,serializedItem:null,promise:new Promise(t=\u003e{n=t}),resolve:n,settled:!1,singleSolveStarted:!1};try{o.serializedItem=JSON.stringify({requestId:t,input:e})}catch(t){this.settleWithFallback(o,\"request_serialization_error\",a8(t))}return o}settle(t,e){t.settled||(t.settled=!0,t.resolve(e))}settleWithFallback(t,e,n){this.settle(t,{kind:\"local-fallback\",reason:e,error:n})}parseSuccessfulResponse(t,e){if(!t||\"object\"!=typeof t||Array.isArray(t))throw new s8(\"invalid_response\",\"hd-cache2 returned a non-object response\");const n=t;if(!0!==n.ok)throw new s8(\"remote_error\",\"string\"==typeof n.message?n.message:\"hd-cache2 returned an unsuccessful response\");if(n.autorouterVersion!==this.autorouterVersion)throw new s8(\"version_mismatch\",`hd-cache2 returned autorouter version ${String(n.autorouterVersion)}, expected ${this.autorouterVersion}`);if(n.cacheVersion!==this.cacheVersion)throw new s8(\"cache_version_mismatch\",`hd-cache2 returned cache version ${String(n.cacheVersion)}, expected ${String(this.cacheVersion)}`);if(\"cache\"!==n.source\u0026\u0026\"solver\"!==n.source)throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid cache source\");if(\"ordinary\"!==n.solutionStage\u0026\u0026\"regional-fallback\"!==n.solutionStage)throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid solution stage\");if(\"regional-fallback\"===n.solutionStage\u0026\u0026(!e.enableRegionalFallback||\"string\"!=typeof n.ordinaryFailure||0===n.ordinaryFailure.length))throw new s8(\"invalid_response\",\"hd-cache2 returned invalid regional fallback metadata\");if(\"ordinary\"===n.solutionStage\u0026\u0026Object.prototype.hasOwnProperty.call(n,\"ordinaryFailure\"))throw new s8(\"invalid_response\",\"hd-cache2 returned regional metadata on an ordinary result\");if(\"ordinary\"===n.solutionStage\u0026\u0026\"failed\"===n.status\u0026\u0026e.enableRegionalFallback)throw new s8(\"invalid_response\",\"hd-cache2 returned an intermediate ordinary failure\");if(\"solved\"===n.status\u0026\u0026p8(n.routes,e,n.solutionStage))return n;if(\"failed\"===n.status\u0026\u0026\"string\"==typeof n.error\u0026\u0026n.error.length\u003e0)return n;throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid solve result\")}parseBatchCacheMiss(t){if(!1!==t.ok||\"CACHE_MISS\"!==t.code)return null;if(t.autorouterVersion!==this.autorouterVersion)throw new s8(\"version_mismatch\",`hd-cache2 returned autorouter version ${String(t.autorouterVersion)}, expected ${this.autorouterVersion}`);if(t.cacheVersion!==this.cacheVersion)throw new s8(\"cache_version_mismatch\",`hd-cache2 returned cache version ${String(t.cacheVersion)}, expected ${String(this.cacheVersion)}`);if(\"string\"!=typeof t.message)throw new s8(\"invalid_response\",\"hd-cache2 returned an invalid cache miss response\");return t}async fetchSingle(t){const e=new AbortController;let n=!1;const o=setTimeout(()=\u003e{n=!0,e.abort(new Error(\"hd-cache2 transport timed out after 310000ms\"))},o8);o.unref?.();try{const n={autorouterVersion:this.autorouterVersion,...void 0===this.cacheVersion?{}:{cacheVersion:this.cacheVersion},input:t.input};let o;try{o=JSON.stringify(n)}catch(t){throw new s8(\"request_serialization_error\",a8(t))}const r=await fetch((i=this.serverUrl,/\\/solve\\/?$/.test(i)?i.replace(/\\/+$/,\"\"):`${i.replace(/\\/+$/,\"\")}/solve`),{method:\"POST\",headers:{accept:\"application/json\",\"content-type\":\"application/json\"},body:o,signal:e.signal}),s=await r.text();let a=null;try{a=s?JSON.parse(s):null}catch{if(!r.ok)throw new s8(\"http_error\",`hd-cache2 request failed with status ${r.status}`);throw new s8(\"invalid_json\",`hd-cache2 returned invalid JSON with status ${r.status}`)}if(!r.ok){const t=a\u0026\u0026\"object\"==typeof a\u0026\u0026\"message\"in a\u0026\u0026\"string\"==typeof a.message?a.message:`hd-cache2 request failed with status ${r.status}`;throw new s8(\"http_error\",t)}this.settle(t,{kind:\"remote\",response:this.parseSuccessfulResponse(a,t.input)})}catch(e){const o=e instanceof s8?e.reason:n?\"transport_timeout\":\"transport_error\";this.settleWithFallback(t,o,a8(e))}finally{clearTimeout(o)}var i}launchSingleSolve(t){t.singleSolveStarted||t.settled||(t.singleSolveStarted=!0,this.stats.singleRequestsStarted+=1,this.fetchSingle(t))}handleBatchResponseLine(t,e,n){if(0===t.trim().length)return;if(t.length\u003er8)throw new s8(\"response_too_large\",\"hd-cache2 returned an oversized batch result line\");let o;try{o=JSON.parse(t)}catch{return void(this.stats.batchInvalidLines+=1)}if(!o||\"object\"!=typeof o||Array.isArray(o))return void(this.stats.batchInvalidLines+=1);const i=o,r=i.requestId;if(\"string\"!=typeof r)return void(this.stats.batchInvalidLines+=1);const s=e.get(r);if(s)if(n.has(r))this.stats.batchDuplicateRequestIds+=1;else{n.add(r);try{if(this.parseBatchCacheMiss(i))return this.stats.batchCacheMisses+=1,void this.launchSingleSolve(s);this.settle(s,{kind:\"remote\",response:this.parseSuccessfulResponse(i,s.input)})}catch(t){this.stats.batchInvalidLines+=1,this.settleWithFallback(s,t instanceof s8?t.reason:\"invalid_response\",a8(t))}}else this.stats.batchUnknownRequestIds+=1}async readBatchResponse(t,e){if(!t.body)throw new s8(\"invalid_response\",\"hd-cache2 returned an empty batch response body\");const n=new Map(e.items.map(t=\u003e[t.requestId,t])),o=new Set,i=new TextDecoder,r=t.body.getReader();let s=\"\";for(;o.size\u003ce.items.length;){const{done:t,value:e}=await r.read();if(s+=i.decode(e,{stream:!t}),s.length\u003er8\u0026\u0026!s.includes(\"\\n\"))throw new s8(\"response_too_large\",\"hd-cache2 returned an oversized unterminated batch result line\");let a=s.indexOf(\"\\n\");for(;a\u003e=0;){const t=s.slice(0,a);s=s.slice(a+1),this.handleBatchResponseLine(t,n,o),a=s.indexOf(\"\\n\")}if(t){s.trim().length\u003e0\u0026\u0026this.handleBatchResponseLine(s,n,o);break}}if(o.size!==e.items.length)for(const t of e.items)o.has(t.requestId)||this.settleWithFallback(t,\"missing_response\",`hd-cache2 batch ended without result ${t.requestId}`);else await r.cancel().catch(()=\u003e{})}async fetchBatch(t){const e=new AbortController;let n=!1;const o=setTimeout(()=\u003e{n=!0,e.abort(new Error(\"hd-cache2 batch transport timed out after 310000ms\"))},o8);o.unref?.(),this.stats.batchRequestsStarted+=1,this.stats.batchItemsStarted+=t.items.length,this.stats.batchBodyBytesStarted+=t.bodyBytes,this.stats.batchMaxBodyBytes=Math.max(this.stats.batchMaxBodyBytes,t.bodyBytes);try{const n=await fetch((t=\u003e{const e=t.replace(/\\/+$/,\"\");return/\\/solve-batch$/.test(e)?e:/\\/solve$/.test(e)?e.replace(/\\/solve$/,\"/solve-batch\"):`${e}/solve-batch`})(this.serverUrl),{method:\"POST\",headers:{accept:\"application/x-ndjson\",\"content-type\":\"application/json\"},body:t.body,signal:e.signal});if(!n.ok){const t=await n.text().catch(()=\u003e\"\");let e=`hd-cache2 batch request failed with status ${n.status}`;try{const n=t?JSON.parse(t):null;n\u0026\u0026\"object\"==typeof n\u0026\u0026\"message\"in n\u0026\u0026\"string\"==typeof n.message\u0026\u0026(e=n.message)}catch{}throw new s8(\"http_error\",e)}await this.readBatchResponse(n,t)}catch(e){const o=e instanceof s8?e.reason:n?\"transport_timeout\":\"transport_error\";for(const n of t.items)n.singleSolveStarted||this.settleWithFallback(n,o,a8(e))}finally{clearTimeout(o),this.stats.batchRequestsCompleted+=1}}prepareBatches(t){const e=new TextEncoder,n=void 0===this.cacheVersion?\"\":`,\"cacheVersion\":${JSON.stringify(this.cacheVersion)}`,o=`{\"autorouterVersion\":${JSON.stringify(this.autorouterVersion)}${n},\"items\":[`,i=e.encode(o+\"]}\").byteLength,r=[],s=[];let a=[],c=i;const l=()=\u003e{0!==a.length\u0026\u0026(r.push({body:`${o}${a.map(t=\u003et.serializedItem).join(\",\")}]}`,bodyBytes:c,items:a}),a=[],c=i)};for(const n of t){const t=e.encode(n.serializedItem).byteLength,o=0===a.length?0:1;i+t\u003ei8?(l(),s.push(n)):((a.length\u003e=100||c+o+t\u003ei8)\u0026\u0026l(),a.push(n),c+=(1===a.length?0:1)+t)}return l(),{batches:r,singletonSolves:s}}},g8=\"ordinary_then_regional_without_fixed_copper_v1\",f8=class extends VQ{autorouterVersion;hdCache2ServerUrl;hdCache2CacheVersion;requestTimeoutMs;hdCache2Client;launchedRemoteSolves=!1;waitingForRemoteNode=null;remoteRequestByNode=new Map;remoteResultByNode=new Map;logicallyTimedOutNodes=new Set;constructor({autorouterVersion:t,hdCache2ServerUrl:e,hdCache2CacheVersion:n,requestTimeoutMs:o,...i}){if(super(i),1!==i.effort)throw new Error(`Pipeline9 networked high-density routing requires effort=1, received ${i.effort}`);if(this.requestTimeoutMs=o??3e4,!Number.isFinite(this.requestTimeoutMs)||this.requestTimeoutMs\u003c=0)throw new Error(`Pipeline9 network request timeout must be a positive number, received ${this.requestTimeoutMs}`);this.autorouterVersion=t,this.hdCache2ServerUrl=e??n8,this.hdCache2CacheVersion=n,this.hdCache2Client=new m8(this.autorouterVersion,this.hdCache2ServerUrl,{cacheVersion:n}),this.pendingEffects=[],this.stats={...this.stats,remoteRequestsStarted:0,remoteRequestsCompleted:0,remoteBatchRequestsStarted:0,remoteBatchRequestsCompleted:0,remoteBatchItemsStarted:0,remoteBatchBodyBytesStarted:0,remoteBatchMaxBodyBytes:0,remoteBatchCacheMisses:0,remoteSingleRequestsStarted:0,remoteBatchInvalidLines:0,remoteBatchUnknownRequestIds:0,remoteBatchDuplicateRequestIds:0,remoteCacheHits:0,remoteSolverResults:0,remoteSolvedResults:0,remoteFailedResults:0,remoteOrdinaryResults:0,remoteRegionalFallbackResults:0,remoteRegionalFallbackResultsApplied:0,remoteRegionalFallbackResultsDeferredToLocal:0,remoteTransportFallbacks:0,remoteLogicalTimeoutFallbacks:0,remoteFallbackReasonCounts:{}}}getSolverName(){return\"Pipeline9NetworkedHighDensitySolver\"}async waitForAllRemoteRequests(){const t=[...this.remoteRequestByNode.values()];0!==t.length?(await Promise.all(t.map(({promise:t})=\u003et)),this.syncClientStats()):this.syncClientStats()}createNodeInput(t){const e=this.enableRegionalFallback?Q9({nodeWithPortPoints:t,connMap:this.connMap,obstacles:this.obstacles,obstacleMargin:this.obstacleMargin,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter}):{connectivityNetMap:{},obstacles:[]},n=e8({nodeWithPortPoints:t,connMap:this.connMap,colorMap:this.colorMap,obstacles:this.enableRegionalFallback?e.obstacles:this.obstacles,obstacleMargin:this.obstacleMargin,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter});return{solvePolicy:g8,enableRegionalFallback:this.enableRegionalFallback,nodeWithPortPoints:t,connectivityNetMap:t8(n.connectivityNetMap,e.connectivityNetMap),colorMap:n.colorMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:1,obstacles:n.obstacles,regionalObstacles:e.obstacles,layerCount:this.layerCount,nodePf:this.nodePfById.get(t.capacityMeshNodeId)??null}}syncClientStats(){const t=this.hdCache2Client.stats;this.stats.remoteBatchRequestsStarted=t.batchRequestsStarted,this.stats.remoteBatchRequestsCompleted=t.batchRequestsCompleted,this.stats.remoteBatchItemsStarted=t.batchItemsStarted,this.stats.remoteBatchBodyBytesStarted=t.batchBodyBytesStarted,this.stats.remoteBatchMaxBodyBytes=t.batchMaxBodyBytes,this.stats.remoteBatchCacheMisses=t.batchCacheMisses,this.stats.remoteSingleRequestsStarted=t.singleRequestsStarted,this.stats.remoteBatchInvalidLines=t.batchInvalidLines,this.stats.remoteBatchUnknownRequestIds=t.batchUnknownRequestIds,this.stats.remoteBatchDuplicateRequestIds=t.batchDuplicateRequestIds}recordFallbackReason(t){const e=this.stats.remoteFallbackReasonCounts;e[t]=(e[t]??0)+1}trackRemoteSolve(t,e){const n=performance.now()+this.requestTimeoutMs;this.stats.remoteRequestsStarted+=1;const o=e.then(e=\u003e{const n=this.logicallyTimedOutNodes.has(t);n||this.remoteResultByNode.set(t,e),\"remote\"===e.kind?(\"cache\"===e.response.source\u0026\u0026(this.stats.remoteCacheHits+=1),\"solver\"===e.response.source\u0026\u0026(this.stats.remoteSolverResults+=1),\"solved\"===e.response.status?this.stats.remoteSolvedResults+=1:this.stats.remoteFailedResults+=1):n||(this.stats.remoteTransportFallbacks+=1,this.recordFallbackReason(e.reason)),this.stats.remoteRequestsCompleted+=1,this.syncClientStats()});this.remoteRequestByNode.set(t,{promise:o,deadlineAt:n})}launchRemoteSolves(){const t=[],e=[...this.unsolvedNodePortPoints].reverse();for(const n of e)try{t.push({node:n,input:this.createNodeInput(n)})}catch(t){this.trackRemoteSolve(n,Promise.resolve({kind:\"local-fallback\",reason:\"request_serialization_error\",error:t instanceof Error?t.message:String(t)}))}const n=this.hdCache2Client.solveMany(t.map(({input:t})=\u003et));for(const[e,o]of n.entries())this.trackRemoteSolve(t[e].node,o);this.syncClientStats()}async waitForCurrentRemoteNode(t,e){const n=e.deadlineAt-performance.now();if(n\u003c=0)return void this.recordLogicalTimeout(t);let o;const i=await Promise.race([e.promise.then(()=\u003e\"request-settled\"),new Promise(t=\u003e{o=setTimeout(()=\u003et(\"logical-timeout\"),n)})]);void 0!==o\u0026\u0026clearTimeout(o),\"logical-timeout\"===i\u0026\u0026this.recordLogicalTimeout(t)}recordLogicalTimeout(t){this.logicallyTimedOutNodes.add(t),this.stats.remoteLogicalTimeoutFallbacks+=1,this.stats.remoteTransportFallbacks+=1,this.recordFallbackReason(\"logical_timeout\")}startRegularSolver(t){const e=this.remoteResultByNode.get(t);if(!e){const e=this.remoteRequestByNode.get(t);if(e){this.waitingForRemoteNode=t;const n=this.waitForCurrentRemoteNode(t,e);n.then(()=\u003e{this.waitingForRemoteNode===t\u0026\u0026(this.pendingEffects=[])});const o={name:`hd-cache2:${t.capacityMeshNodeId}`,promise:n};return void(this.pendingEffects=[o])}return void super.startRegularSolver(t)}this.applyRemoteResultToRegularNode(t,e)}applyRemoteResultToRegularNode(t,e){if(\"local-fallback\"!==e.kind){if(this.stats.regularNodeCount=Number(this.stats.regularNodeCount??0)+1,this.activeNode=t,\"regional-fallback\"===e.response.solutionStage){if(this.stats.remoteRegionalFallbackResults+=1,!this.canUseNoFixedCopperRegionalResult(t))return this.stats.remoteRegionalFallbackResultsDeferredToLocal+=1,void this.finishRegularSolverFailure(e.response.ordinaryFailure);this.stats.remoteRegionalFallbackResultsApplied+=1,this.stats.fallbackNodeCount=Number(this.stats.fallbackNodeCount??0)+1}else this.stats.remoteOrdinaryResults+=1;if(\"failed\"===e.response.status)return this.error=e.response.error,this.failed=!0,void(this.activeNode=null);this.finishActiveNode(e.response.routes)}else super.startRegularSolver(t)}canUseNoFixedCopperRegionalResult(t){const e={...YQ(t,this.connMap),availableZ:Array.from({length:this.layerCount},(t,e)=\u003ee)},n=$K(e,this.getUpdatedFixedHdRoutes());return 0===n.fixedRouteSectionsByConnectionName.size\u0026\u00260===n.fixedObstacleRoutes.length}_step(){if(this.syncClientStats(),this.launchedRemoteSolves||(this.launchedRemoteSolves=!0,this.launchRemoteSolves()),this.waitingForRemoteNode){const t=this.waitingForRemoteNode;if(this.logicallyTimedOutNodes.has(t))return this.waitingForRemoteNode=null,this.pendingEffects=[],void super.startRegularSolver(t);const e=this.remoteResultByNode.get(t);if(!e)return;return this.waitingForRemoteNode=null,this.pendingEffects=[],void this.applyRemoteResultToRegularNode(t,e)}super._step()}},y8=class extends H9{hdCache2ServerUrl;hdCache2CacheVersion;getSolverName(){return\"AutoroutingPipelineSolver9_Networked\"}constructor(t,e={}){if(super(t,e),1!==this.effort)throw new Error(`AutoroutingPipelineSolver9_Networked is only available at effort=1, received ${this.effort}`);this.hdCache2ServerUrl=e.hdCache2ServerUrl??n8,this.hdCache2CacheVersion=e.hdCache2CacheVersion,this.replaceHighDensityPipelineStep()}replaceHighDensityPipelineStep(){const t=this.pipelineDef.findIndex(t=\u003e\"highDensityRouteSolver\"===t.solverName),e=this.pipelineDef[t];if(!e)throw new Error(\"Pipeline9 highDensityRouteSolver step is missing\");const n=e.getConstructorParams;this.pipelineDef[t]={...e,solverClass:f8,getConstructorParams:t=\u003e{const[e]=n(t);return[{...e,autorouterVersion:G9,hdCache2ServerUrl:t.hdCache2ServerUrl,hdCache2CacheVersion:t.hdCache2CacheVersion}]}}}async stepAsync(){if(this.solved||this.failed)return;this.step();const t=vX(this);0!==t.length\u0026\u0026(await Promise.race(t.map(t=\u003et.promise.then(()=\u003et.name,()=\u003et.name))),this.solved||this.failed||this.step())}async solveAsync(){const t=Date.now();for(;!this.solved\u0026\u0026!this.failed;)await this.stepAsync();this.timeToSolve=Date.now()-t}async solveUntilPhaseAsync(t){for(;this.getCurrentPhase()!==t\u0026\u0026!this.solved\u0026\u0026!this.failed;)await this.stepAsync()}solve(){throw new Error(\"AutoroutingPipelineSolver9_Networked requires async execution. Use solveAsync() or stepAsync().\")}solveUntilPhase(t){throw new Error(\"AutoroutingPipelineSolver9_Networked requires solveUntilPhaseAsync().\")}};function _8(t){if(t.solvePolicy!==g8)throw new Error(`Unsupported Pipeline9 networked solve policy ${String(t.solvePolicy)}`);if(1!==t.effort)throw new Error(`Pipeline9 networked high-density solving requires effort=1, received ${t.effort}`);const e=new ti(t.connectivityNetMap),n=(({input:t,connMap:e})=\u003e{const n=XQ({nodeWithPortPoints:t.nodeWithPortPoints,colorMap:t.colorMap,connMap:e,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:{[t.nodeWithPortPoints.capacityMeshNodeId]:t.nodePf},obstacles:t.obstacles,layerCount:t.layerCount});return n.solve(),n.solved?{status:\"solved\",routes:n.routes}:{status:\"failed\",error:n.error||\"Pipeline9 ordinary high-density solver failed\"}})({input:t,connMap:e});if(\"solved\"===n.status)return{status:\"solved\",solutionStage:\"ordinary\",routes:n.routes};const o=n.error;if(!t.enableRegionalFallback)return{status:\"failed\",solutionStage:\"ordinary\",error:`Pipeline9 regular high-density routing failed: ${o}`};const i=YQ(t.nodeWithPortPoints,e),r=$K({...i,availableZ:Array.from({length:t.layerCount},(t,e)=\u003ee)},[]),s=new FQ({nodeWithPortPoints:r.nodeWithPortPoints,colorMap:t.colorMap,connMap:e,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:{[t.nodeWithPortPoints.capacityMeshNodeId]:t.nodePf},obstacles:t.regionalObstacles,layerCount:t.layerCount});if(s.solve(),s.solved)return{status:\"solved\",solutionStage:\"regional-fallback\",ordinaryFailure:o,routes:s.getOutput()};return{status:\"failed\",solutionStage:\"regional-fallback\",ordinaryFailure:o,error:[`Pipeline9 primary high-density routing failed: regular high-density routing failed: ${o}`,`regional fallback failed: ${s.error||\"Pipeline9 regional fallback solver failed\"}`].join(\"; \")}}var b8=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\u0026\u0026!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026this.tryFinalAcceptance(),!this.solved\u0026\u0026this.iterations\u003e=this.MAX_ITERATIONS\u0026\u0026(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),\"computeProgress\"in this\u0026\u0026(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error(\"getConstructorParams not implemented\")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved\u0026\u0026!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 x8(t){const e=`${t.connectionName}:source-${t.sourcePointIndex}`;return{boundaryExitPointId:`fanout-exit:${e}`,planeExitPointId:`fanout-plane:${e}`,traceId:`fanout:${e}`,viaObstacleId:`fanout-via:${e}`,planeEndpointPointId:`fanout-plane-endpoint-point:${e}`,planeEndpointTraceId:`fanout-plane-endpoint:${e}`,planeEndpointViaObstacleId:`fanout-plane-endpoint-via:${e}`}}function v8(t,e,n=!1){const o=n?t.planeEndpointVia:t.via;if(!o)return null;const i=o.spanLayers.map(n=\u003e{const o=e.indexOf(n);if(o\u003c0)throw new Error(`FanoutSolver: via for \"${t.connectionName}\" uses unknown layer \"${n}\"`);return o}),r=x8(t);return{obstacleId:n?r.planeEndpointViaObstacleId:r.viaObstacleId,type:\"rect\",center:o.center,width:o.diameter,height:o.diameter,layers:o.spanLayers,zLayers:i,__zLayers:i,connectedTo:[t.connectionName,t.trace.pcb_trace_id]}}function S8(t){const{inputSrj:e,plans:n,layerNames:o}=t,i=e.connections.map(t=\u003e({...t,pointsToConnect:t.pointsToConnect.map(t=\u003e({...t}))})),r=[],s=new Set;for(const t of n){const e=i[t.connectionIndex];if(!e)throw new Error(`FanoutSolver: output connection index ${t.connectionIndex} is missing`);const n=x8(t);e.pointsToConnect[t.sourcePointIndex]={x:t.exitPoint.x,y:t.exitPoint.y,layer:t.targetLayer,pointId:\"plane\"===t.termination.type?n.planeExitPointId:n.boundaryExitPointId},\"plane\"===t.termination.type\u0026\u0026s.add(t.connectionName);const a=v8(t,o);a\u0026\u0026r.push(a);const c=v8(t,o,!0);c\u0026\u0026r.push(c)}const a=n.flatMap(t=\u003e[t.trace,...t.planeEndpointTrace?[t.planeEndpointTrace]:[]]),c=a.flatMap(t=\u003et.route.filter(t=\u003e\"x\"in t\u0026\u0026\"y\"in t)),l=Math.max(e.defaultObstacleMargin??0,e.minTraceWidth),d=0===c.length?{...e.bounds}:{minX:Math.min(e.bounds.minX,...c.map(t=\u003et.x-l)),maxX:Math.max(e.bounds.maxX,...c.map(t=\u003et.x+l)),minY:Math.min(e.bounds.minY,...c.map(t=\u003et.y-l)),maxY:Math.max(e.bounds.maxY,...c.map(t=\u003et.y+l))};return{...e,fanoutPlaneConnectivity:n.flatMap(t=\u003e\"plane\"===t.termination.type?[{connectionName:t.connectionName,layer:t.termination.layer}]:[]),bounds:d,connections:i.filter(t=\u003e!s.has(t.name)),buses:e.buses?.map(t=\u003e({...t,connectionNames:t.connectionNames.filter(t=\u003e!s.has(t))})).filter(t=\u003et.connectionNames.length\u003e0),obstacles:[...e.obstacles.map(t=\u003e({...t,center:{...t.center},layers:[...t.layers],connectedTo:[...t.connectedTo]})),...r],traces:[...(e.traces??[]).map(t=\u003e({...t,route:t.route.map(t=\u003e({...t}))})),...a]}}var I8=1e-9;function C8(t){return\"circle\"===t.shape}function P8(t,e){const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}}function M8(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function N8(t,e,n){const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r\u003cI8?0:((t.x-e.x)*o+(t.y-e.y)*i)/r,a=Math.max(0,Math.min(1,s));return Math.hypot(t.x-(e.x+a*o),t.y-(e.y+a*i))}function w8(t,e,n){return(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x)}function T8(t,e,n,o){return function(t,e,n,o){const i=w8(n,o,t),r=w8(n,o,e),s=w8(t,e,n),a=w8(t,e,o);return(i\u003e0\u0026\u0026r\u003c0||i\u003c0\u0026\u0026r\u003e0)\u0026\u0026(s\u003e0\u0026\u0026a\u003c0||s\u003c0\u0026\u0026a\u003e0)}(t,e,n,o)?0:Math.min(N8(t,n,o),N8(e,n,o),N8(n,t,e),N8(o,t,e))}function R8(t,e,n=1e-9){if(C8(e))return M8(t,e.center)\u003c=e.width/2+n;const o=P8(t,e);return Math.abs(o.x)\u003c=e.width/2+n\u0026\u0026Math.abs(o.y)\u003c=e.height/2+n}function E8(t,e){if(C8(e))return Math.max(0,M8(t,e.center)-e.width/2);const n=P8(t,e),o=Math.max(Math.abs(n.x)-e.width/2,0),i=Math.max(Math.abs(n.y)-e.height/2,0);return Math.hypot(o,i)}function A8(t,e){if(C8(e))return Math.max(0,N8(e.center,t.start,t.end)-e.width/2);const n=P8(t.start,e),o=P8(t.end,e);if(Math.abs(n.x)\u003c=e.width/2+I8\u0026\u0026Math.abs(n.y)\u003c=e.height/2+I8)return 0;if(Math.abs(o.x)\u003c=e.width/2+I8\u0026\u0026Math.abs(o.y)\u003c=e.height/2+I8)return 0;const i=-e.width/2,r=e.width/2,s=-e.height/2,a=e.height/2,c=[{x:i,y:s},{x:r,y:s},{x:r,y:a},{x:i,y:a}];let l=Number.POSITIVE_INFINITY;for(let t=0;t\u003cc.length;t++)l=Math.min(l,T8(n,o,c[t],c[(t+1)%c.length]));return l}function O8(t,e,n){if(t.layer!==e.layer)return!0;const o=(t.width+e.width)/2+n;return T8(t.start,t.end,e.start,e.end)\u003e=o-I8}function k8(t){if(!Number.isInteger(t)||t\u003c1)throw new Error(`FanoutSolver: layerCount must be a positive integer, received ${t}`);return 1===t?[\"top\"]:2===t?[\"top\",\"bottom\"]:[\"top\",...Array.from({length:t-2},(t,e)=\u003e`inner${e+1}`),\"bottom\"]}function L8(t,e,n){const o=n.indexOf(t),i=n.indexOf(e);if(o\u003c0||i\u003c0)throw new Error(`FanoutSolver: cannot build via span from \"${t}\" to \"${e}\"`);const r=Math.min(o,i),s=Math.max(o,i);return n.slice(r,s+1)}var D8=new WeakMap;function z8(t){return t.netConnectionName??t.rootConnectionName??t.name}function F8(t,e,n){if(!e)return!1;const o=t.get(e)??new Set,i=o.size;return o.add(n),t.set(e,o),o.size!==i}function B8(t,e){const n=new Set;for(const o of e)for(const e of t.get(o)??[])n.add(e);return n}function j8(t){const e=D8.get(t);if(e)return e;const n=function(t){const e=new Map,n=new Map;for(const o of t.connections){const t=z8(o);e.set(o.name,t),F8(n,o.name,t),F8(n,o.rootConnectionName,t),F8(n,o.netConnectionName,t);for(const e of o.pointsToConnect)F8(n,e.pointId,t),F8(n,e.pcb_port_id,t)}for(const o of t.traces??[]){const t=o.connection_name?e.get(o.connection_name):void 0;if(t){F8(n,o.pcb_trace_id,t);for(const e of o.connectsTo??[])F8(n,e,t)}}for(let e=0;e\u003c2;e++){let e=!1;for(const o of t.obstacles){const t=B8(n,o.connectedTo);if(1!==t.size)continue;const i=[...t][0];for(const t of o.connectedTo)e=F8(n,t,i)||e}if(!e)break}const o=new Map,i=t=\u003e{const e=o.get(t)??t;if(o.set(t,e),e===t)return t;const n=i(e);return o.set(t,n),n},r=(t,e)=\u003e{const n=i(t),r=i(e);n!==r\u0026\u0026o.set(r,n)};for(const t of n.values()){const[e,...n]=[...t];if(e)for(const t of n)r(e,t)}for(const e of[...t.obstacles.map(t=\u003et.connectedTo),...(t.traces??[]).map(t=\u003et.connectsTo??[])]){const[t,...o]=[...B8(n,e)];if(t)for(const e of o)r(t,e)}for(const[t,n]of e)e.set(t,i(n));for(const[t,e]of n)n.set(t,new Set([...e].map(t=\u003ei(t))));return{connectionNetKeys:e,tokenNetKeys:n}}(t);return D8.set(t,n),n}function $8(t,e,n){const o=j8(t),i=o.connectionNetKeys.get(e),r=o.connectionNetKeys.get(n);return void 0!==i\u0026\u0026i===r}function Y8(t,e,n){const o=j8(t),i=o.connectionNetKeys.get(n);return!!i\u0026\u0026e.connectedTo.some(t=\u003eo.tokenNetKeys.get(t)?.has(i))}var X8=1e-6;function V8(t){return\"layer\"in t?[t.layer]:t.layers}function W8(t,e){return t.some(t=\u003ee.includes(t))}function H8(t,e){const n=[];let o;for(const i of t.route)\"via\"!==i.route_type?\"wire\"===i.route_type\u0026\u0026(o\u0026\u0026o.layer===i.layer\u0026\u0026M8(o,i)\u003eX8\u0026\u0026n.push({type:\"segment\",segment:{start:{x:o.x,y:o.y},end:{x:i.x,y:i.y},width:i.width,layer:i.layer}}),o=i):(n.push({type:\"via\",center:{x:i.x,y:i.y},diameter:i.via_diameter??0,layers:L8(i.from_layer,i.to_layer,e)}),o=void 0);return n}function G8(t,e){return\"plane\"===t.type\u0026\u0026\"plane\"===e.type?t.layer===e.layer:\"plane\"===t.type\u0026\u0026\"via\"===e.type?e.layers.includes(t.layer):\"via\"===t.type\u0026\u0026\"plane\"===e.type?G8(e,t):\"plane\"===t.type\u0026\u0026\"segment\"===e.type?t.layer===e.segment.layer:\"segment\"===t.type\u0026\u0026\"plane\"===e.type?G8(e,t):\"endpoint\"===t.type\u0026\u0026\"endpoint\"===e.type?W8(t.layers,e.layers)\u0026\u0026M8(t.point,e.point)\u003c=X8:\"endpoint\"===t.type\u0026\u0026\"obstacle\"===e.type?W8(t.layers,e.obstacle.layers)\u0026\u0026R8(t.point,e.obstacle,X8):\"obstacle\"===t.type\u0026\u0026\"endpoint\"===e.type?G8(e,t):\"endpoint\"===t.type\u0026\u0026\"segment\"===e.type?t.layers.includes(e.segment.layer)\u0026\u0026N8(t.point,e.segment.start,e.segment.end)\u003c=e.segment.width/2+X8:\"segment\"===t.type\u0026\u0026\"endpoint\"===e.type?G8(e,t):\"endpoint\"===t.type\u0026\u0026\"via\"===e.type?W8(t.layers,e.layers)\u0026\u0026M8(t.point,e.center)\u003c=e.diameter/2+X8:\"via\"===t.type\u0026\u0026\"endpoint\"===e.type?G8(e,t):\"obstacle\"===t.type\u0026\u0026\"segment\"===e.type?t.obstacle.layers.includes(e.segment.layer)\u0026\u0026A8(e.segment,t.obstacle)\u003c=e.segment.width/2+X8:\"segment\"===t.type\u0026\u0026\"obstacle\"===e.type?G8(e,t):\"obstacle\"===t.type\u0026\u0026\"via\"===e.type?W8(t.obstacle.layers,e.layers)\u0026\u0026E8(e.center,t.obstacle)\u003c=e.diameter/2+X8:\"via\"===t.type\u0026\u0026\"obstacle\"===e.type?G8(e,t):\"segment\"===t.type\u0026\u0026\"segment\"===e.type?t.segment.layer===e.segment.layer\u0026\u0026T8(t.segment.start,t.segment.end,e.segment.start,e.segment.end)\u003c=(t.segment.width+e.segment.width)/2+X8:\"segment\"===t.type\u0026\u0026\"via\"===e.type?e.layers.includes(t.segment.layer)\u0026\u0026N8(e.center,t.segment.start,t.segment.end)\u003c=e.diameter/2+t.segment.width/2+X8:\"via\"===t.type\u0026\u0026\"segment\"===e.type?G8(e,t):\"via\"===t.type\u0026\u0026\"via\"===e.type\u0026\u0026(W8(t.layers,e.layers)\u0026\u0026M8(t.center,e.center)\u003c=(t.diameter+e.diameter)/2+X8)}var U8=class{parent;constructor(t){this.parent=Array.from({length:t},(t,e)=\u003ee)}find(t){const e=this.parent[t];if(e===t)return t;const n=this.find(e);return this.parent[t]=n,n}union(t,e){const n=this.find(t),o=this.find(e);n!==o\u0026\u0026(this.parent[o]=n)}};function Z8(t,e,n){return Boolean(e.connection_name\u0026\u0026$8(t,e.connection_name,n.name))}function q8(t){const{inputSrj:e,routedSrj:n}=t,o=n.fanoutPlaneConnectivity,i=k8(n.layerCount),r=new Map;for(const t of e.connections){const e=z8(t),n=r.get(e)??[];n.push(t),r.set(e,n)}const s=[];let a=0,c=0;for(const t of r.values()){const r=t[0],l=t.flatMap(t=\u003et.pointsToConnect.map((e,n)=\u003e({type:\"endpoint\",connectionName:t.name,endpointIndex:n,point:e,layers:V8(e)}))),d=e.obstacles.filter(t=\u003eY8(e,t,r.name)).map(t=\u003e({type:\"obstacle\",obstacle:t})),h=(n.traces??[]).filter(t=\u003eZ8(e,t,r)).flatMap(t=\u003eH8(t,i)),u=[...new Set((o??[]).flatMap(t=\u003e$8(e,t.connectionName,r.name)?[t.layer]:[]))].map(t=\u003e({type:\"plane\",layer:t})),p=[...l,...d,...h,...u],m=new U8(p.length);for(let t=0;t\u003cp.length;t++)for(let e=t+1;e\u003cp.length;e++)G8(p[t],p[e])\u0026\u0026m.union(t,e);const g=new Map;for(let t=0;t\u003cl.length;t++){const e=l[t],n=g.get(e.connectionName)??[];n[e.endpointIndex]=t,g.set(e.connectionName,n)}for(const e of t){const t=g.get(e.name)??[],n=t[0],o=void 0===n?void 0:m.find(n),i=t.flatMap((t,e)=\u003evoid 0===o||m.find(t)!==o?[e]:[]);c+=t.length-i.length,0===i.length?a++:s.push({code:\"original-endpoints-disconnected\",connectionName:e.name,disconnectedEndpointIndices:i,message:`Connection ${e.name} has no physical copper path from endpoint 0 to original endpoint${1===i.length?\"\":\"s\"} ${i.join(\", \")}`})}}const l=e.connections.reduce((t,e)=\u003et+e.pointsToConnect.length,0);return{valid:0===s.length,checkedConnectionCount:e.connections.length,connectedConnectionCount:a,checkedEndpointCount:l,connectedEndpointCount:c,issues:s}}var J8=1e-6;function K8(t){const{inputSrj:e,segment:n,bodyObstacle:o,connectionName:i}=t;if(o.connectedTo.length\u003e0||!o.componentId)return!1;const r=e.obstacles.filter(t=\u003et.componentId===o.componentId\u0026\u0026t.layers.includes(n.layer)\u0026\u0026Y8(e,t,i));for(const t of r)for(const[e,i]of[[n.start,n.end],[n.end,n.start]]){if(!R8(e,t,J8))continue;const n={x:e.x-o.center.x,y:e.y-o.center.y},r={x:i.x-e.x,y:i.y-e.y};if(n.x*r.x+n.y*r.y\u003eJ8)return!0}return!1}function Q8(t,e){return M8(t,e)\u003c=J8}function t7(t,e){t.push(e)}function e7(t){const{srj:e,trace:n,connectionName:o,layerNames:i,issues:r}=t,s=[],a=[];let c,l;for(const t of n.route){if(\"via\"===t.route_type){const s=L8(t.from_layer,t.to_layer,i);a.push({center:{x:t.x,y:t.y},diameter:t.via_diameter??e.minViaPadDiameter??e.minTraceWidth,spanLayers:s}),c\u0026\u0026Q8(c,t)\u0026\u0026c.layer===t.from_layer||t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} reaches a via without a matching ${t.from_layer} wire endpoint`}),l=t;continue}\"wire\"===t.route_type?l?(Q8(t,l)\u0026\u0026t.layer===l.to_layer||t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} does not continue from its via on ${l.to_layer}`}),c=t,l=void 0):(c\u0026\u0026(c.layer!==t.layer?t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} changes from ${c.layer} to ${t.layer} without a via`}):Q8(c,t)||s.push({start:{x:c.x,y:c.y},end:{x:t.x,y:t.y},width:t.width,layer:t.layer})),c=t):(t7(r,{code:\"unsupported-route-point\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} contains unsupported ${t.route_type} geometry`}),c=void 0,l=void 0)}return l\u0026\u0026t7(r,{code:\"disconnected-trace\",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} ends at a via without a wire on ${l.to_layer}`}),{trace:n,connectionName:o,segments:s,vias:a}}function n7(t){const{inputSrj:e,routedSrj:n,clearance:o}=t,i=[],r=k8(n.layerCount),s=[],a=[e,n].flatMap(t=\u003et.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({connectionName:t.name,point:e}))));for(const t of n.traces??[]){const o=t.connection_name;o\u0026\u0026e.connections.some(t=\u003et.name===o)?s.push(e7({srj:n,trace:t,connectionName:o,layerNames:r,issues:i})):t7(i,{code:\"unknown-trace-connection\",traceId:t.pcb_trace_id,...o?{connectionName:o}:{},message:`Trace ${t.pcb_trace_id} does not identify an input connection`})}for(const t of s){for(const n of t.segments)for(const r of e.obstacles){if(!r.layers.includes(n.layer)||Y8(e,r,t.connectionName))continue;if(K8({inputSrj:e,segment:n,bodyObstacle:r,connectionName:t.connectionName}))continue;const s=A8(n,r),a=n.width/2+o;s\u003ca-J8\u0026\u0026t7(i,{code:\"trace-obstacle-clearance\",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,layer:n.layer,obstacleId:r.obstacleId,message:`Trace ${t.trace.pcb_trace_id} on ${n.layer} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId}; ${a.toFixed(4)}mm is required`})}for(const n of t.vias){const r=a.find(({point:t})=\u003eM8(n.center,t)\u003c=J8);r\u0026\u0026t7(i,{code:\"via-at-endpoint\",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,otherConnectionName:r.connectionName,message:`Via in ${t.trace.pcb_trace_id} is placed directly at an original or routed connection endpoint`});for(const r of e.obstacles){if(!r.layers.some(t=\u003en.spanLayers.includes(t))||Y8(e,r,t.connectionName))continue;const s=E8(n.center,r),a=n.diameter/2+o;s\u003ca-J8\u0026\u0026t7(i,{code:\"via-obstacle-clearance\",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,obstacleId:r.obstacleId,message:`Via in ${t.trace.pcb_trace_id} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId} on its layer span; ${a.toFixed(4)}mm is required`})}}}for(let t=0;t\u003cs.length;t++){const n=s[t];for(let r=t+1;r\u003cs.length;r++){const t=s[r];if(!$8(e,n.connectionName,t.connectionName)){for(const e of n.segments){for(const r of t.segments)O8(e,r,o)||t7(i,{code:\"different-net-trace-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:e.layer,message:`Different-net traces ${n.trace.pcb_trace_id} and ${t.trace.pcb_trace_id} intersect or violate clearance on ${e.layer}`});for(const r of t.vias)!r.spanLayers.includes(e.layer)||N8(r.center,e.start,e.end)\u003e=r.diameter/2+e.width/2+o-J8||t7(i,{code:\"different-net-trace-via-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:e.layer,message:`Trace ${n.trace.pcb_trace_id} violates via clearance to ${t.trace.pcb_trace_id} on ${e.layer}`})}for(const e of n.vias){for(const r of t.segments)!e.spanLayers.includes(r.layer)||N8(e.center,r.start,r.end)\u003e=e.diameter/2+r.width/2+o-J8||t7(i,{code:\"different-net-trace-via-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:r.layer,message:`Via in ${n.trace.pcb_trace_id} violates trace clearance to ${t.trace.pcb_trace_id} on ${r.layer}`});for(const r of t.vias)!e.spanLayers.some(t=\u003er.spanLayers.includes(t))||M8(e.center,r.center)\u003e=(e.diameter+r.diameter)/2+o-J8||t7(i,{code:\"different-net-via-clearance\",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,message:`Different-net vias in ${n.trace.pcb_trace_id} and ${t.trace.pcb_trace_id} violate clearance on an overlapping layer span`})}}}}return{valid:0===i.length,checkedTraceCount:n.traces?.length??0,checkedSegmentCount:s.reduce((t,e)=\u003et+e.segments.length,0),checkedViaCount:s.reduce((t,e)=\u003et+e.vias.length,0),issues:i}}var o7=1e-9;function i7(t,e){if(\"layer\"in t)return t.layer;if(e\u0026\u0026t.layers.includes(e))return e;const n=t.layers[0];if(!n)throw new Error(\"Endpoint completion received a layerless point\");return n}function r7(t){const e=[];for(const n of t)e.at(-1)\u0026\u0026M8(e.at(-1),n)\u003co7||e.push(n);return e}function s7(t,e){const n=r7(t);if(n.length\u003c3)return n;const o=[n[0]];for(let t=1;t\u003cn.length-1;t++){const i=n[t-1],r=n[t],s=n[t+1],a=M8(i,r),c=M8(r,s),l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c};if(Math.abs(l.x*d.x+l.y*d.y)\u003e1e-6){o.push(r);continue}const h=Math.min(e,a/2,c/2);o.push({x:r.x-l.x*h,y:r.y-l.y*h}),o.push({x:r.x+d.x*h,y:r.y+d.y*h})}return o.push(n.at(-1)),r7(o)}function a7(t){const{inputSrj:e,plan:n}=t,o=i7(n.targetPoint),i=function(t){const{inputSrj:e,connectionName:n,target:o,targetLayer:i}=t;return e.obstacles.find(t=\u003et.layers.includes(i)\u0026\u0026Y8(e,t,n)\u0026\u0026R8(o,t,1e-6))}({inputSrj:e,connectionName:n.connectionName,target:n.targetPoint,targetLayer:o}),r=e.obstacles.find(t=\u003et.componentId===i?.componentId\u0026\u00260===t.connectedTo.length),s=r?{x:n.targetPoint.x-r.center.x,y:n.targetPoint.y-r.center.y}:{x:n.targetPoint.x-n.sourcePoint.x,y:n.targetPoint.y-n.sourcePoint.y},a=Math.hypot(s.x,s.y),c=a\u003eo7?{x:s.x/a,y:s.y/a}:{x:1,y:0};return{outward:c,perpendicular:{x:-c.y,y:c.x}}}function c7(t){const{plan:e,branchStart:n,viaPoint:o,assignedLayerPath:i,terminalApproach:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,candidateIndex:l,chamfer:d}=t,h=i7(e.targetPoint),u=s7(i,d),p=s7([o,...r?[r]:[],e.targetPoint],d),m=u.map(t=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:s,layer:n.layer}));n.layer!==h\u0026\u0026(m.push({route_type:\"via\",x:o.x,y:o.y,from_layer:n.layer,to_layer:h,via_diameter:a,via_hole_diameter:c}),m.push({route_type:\"wire\",x:o.x,y:o.y,width:s,layer:h}));for(const t of p.slice(1))m.push({route_type:\"wire\",x:t.x,y:t.y,width:s,layer:h});return{type:\"pcb_trace\",pcb_trace_id:(g={connectionName:e.connectionName,sourcePointIndex:e.sourcePointIndex,candidateIndex:l},`fanout-completion:${g.connectionName}:source-${g.sourcePointIndex}:${g.candidateIndex}`),connection_name:e.connectionName,route:m};var g}function l7(t,e){return!t.issues.some(t=\u003et.connectionName===e)}function d7(t){const{trace:e,endpointSrjs:n}=t,o=n.flatMap(t=\u003et.connections.flatMap(t=\u003et.pointsToConnect));return e.route.some(t=\u003e\"via\"===t.route_type\u0026\u0026o.some(e=\u003eM8(t,e)\u003c=1e-6))}function h7(t){const{inputSrj:e,fanoutSrj:n,plan:o,acceptedTraces:i,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,clearance:c}=t,{outward:l,perpendicular:d}=a7({inputSrj:e,plan:o}),h=[...o.via?[{x:o.via.center.x,y:o.via.center.y,layer:o.targetLayer}]:[],{x:o.sourcePoint.x,y:o.sourcePoint.y,layer:o.sourceLayer}];let u=[],p=Number.POSITIVE_INFINITY,m=0;const g=e.connections.length\u003e32?600:Number.POSITIVE_INFINITY,f=\"plane\"===o.termination.type?g7({trace:o.trace,endpoint:o.exitPoint,layer:o.sourceLayer,distances:[.2,.3,.4]}):[],y=[...\"plane\"===o.termination.type\u0026\u0026o.via?[{...o.via.center}]:[],...f,...[.4,.8,1.2,1.6].flatMap(t=\u003e[0,.4,-.4,.8,-.8,1.2,-1.2,1.6,-1.6].map(e=\u003e({x:o.sourcePoint.x+l.x*t+d.x*e,y:o.sourcePoint.y+l.y*t+d.y*e})))];for(const t of y){const y=[...\"plane\"===o.termination.type?[{...t,layer:o.targetLayer}]:[],...h,...f.flatMap(e=\u003eM8(e,t)\u003c=1e-6?[{...e,layer:o.sourceLayer}]:[])];for(const h of y){const f=M8(h,t)\u003c=1e-6?[[h]]:[[h,t],[h,{x:t.x,y:h.y},t],[h,{x:h.x,y:t.y},t],...[.4,-.4].map(e=\u003e[h,{x:h.x+e,y:h.y},{x:h.x+e,y:t.y},t])];for(const y of f){const f=[void 0,...[.4,.8].map(t=\u003e({x:o.targetPoint.x+l.x*t,y:o.targetPoint.y+l.y*t})),...[.4,-.4].map(t=\u003e({x:o.targetPoint.x+.4*l.x+d.x*t,y:o.targetPoint.y+.4*l.y+d.y*t}))];for(const l of f){if(m\u003e=g)return{blockingConnectionNames:u};const d=c7({plan:o,branchStart:h,viaPoint:t,assignedLayerPath:y,terminalApproach:l,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,candidateIndex:m++,chamfer:0});if(d7({trace:d,endpointSrjs:[e,n]}))continue;const f={...n,traces:[...n.traces??[],...i,d]},_=n7({inputSrj:e,routedSrj:f,clearance:c});if(!_.valid){_.issues.length\u003cp\u0026\u0026(p=_.issues.length,u=[...new Set(_.issues.flatMap(t=\u003e[t.connectionName,t.otherConnectionName].flatMap(t=\u003et\u0026\u0026t!==o.connectionName?[t]:[])))]);continue}if(l7(q8({inputSrj:e,routedSrj:f}),o.connectionName))return{trace:d,blockingConnectionNames:[]}}}}}return{blockingConnectionNames:u}}function u7(t){const{inputSrj:e,fanoutSrj:n,plans:o,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a}=t,c=[],l=[],d=new Set;for(const t of o){const o=h7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:c,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});if(o.trace)c.push(o.trace);else{l.push(t.connectionName);for(const t of o.blockingConnectionNames)d.add(t)}}const h={...n,traces:[...n.traces??[],...c]};return{traces:c,failedConnectionNames:l,blockingConnectionNames:[...d],connectivity:q8({inputSrj:e,routedSrj:h}),drc:n7({inputSrj:e,routedSrj:h,clearance:a})}}function p7(t){let e,n=0;for(const o of t.route)\"wire\"===o.route_type?(e?.layer===o.layer\u0026\u0026(n+=M8(e,o)),e=o):e=void 0;return n}function m7(t){const e=k8(t.layerCount),n=[];for(const o of t.traces??[]){let i;for(const r of o.route)if(\"via\"!==r.route_type)if(\"wire\"===r.route_type){if(i?.layer===r.layer){const t=M8(i,r);t\u003eo7\u0026\u0026n.push({obstacleId:`endpoint-completion-keepout:${o.pcb_trace_id}:segment:${n.length}`,type:\"rect\",center:{x:(i.x+r.x)/2,y:(i.y+r.y)/2},width:t,height:Math.max(i.width,r.width),ccwRotationDegrees:180*Math.atan2(r.y-i.y,r.x-i.x)/Math.PI,layers:[r.layer],connectedTo:[o.connection_name]})}i=r}else i=void 0;else n.push({obstacleId:`endpoint-completion-keepout:${o.pcb_trace_id}:via:${n.length}`,type:\"rect\",center:{x:r.x,y:r.y},width:r.via_diameter??t.minViaPadDiameter??.3,height:r.via_diameter??t.minViaPadDiameter??.3,layers:L8(r.from_layer,r.to_layer,e),connectedTo:[o.connection_name]}),i=void 0}return n}function g7(t){const{trace:e,endpoint:n,layer:o,distances:i}=t,r=e.route.findLastIndex(t=\u003e\"wire\"===t.route_type\u0026\u0026t.layer===o\u0026\u0026M8(t,n)\u003c=1e-6);return r\u003c0?[]:i.flatMap(t=\u003e{let i=t,s=n;for(let t=r-1;t\u003e=0;t--){const n=e.route[t];if(\"wire\"!==n?.route_type||n.layer!==o)break;const r=M8(s,n);if(!(r\u003c=o7)){if(i\u003cr-1e-6)return[{x:s.x+(n.x-s.x)*i/r,y:s.y+(n.y-s.y)*i/r}];i-=r,s=n}}return[]})}function f7(t){const{inputSrj:e,fanoutSrj:n,plan:o,acceptedTraces:i,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,clearance:c}=t,l={x:o.exitPoint.x,y:o.exitPoint.y,layer:o.targetLayer},d=o.targetPoint,h=i7(d);let u=0;const p=t=\u003e{const l=c7({plan:o,branchStart:t.start,viaPoint:t.viaPoint,assignedLayerPath:[t.start,t.viaPoint],terminalApproach:t.terminalApproach,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,candidateIndex:1e4+u++,chamfer:Math.max(r,.1)});if(d7({trace:l,endpointSrjs:[e,n]}))return;const d={...n,traces:[...n.traces??[],...i,l]};return n7({inputSrj:e,routedSrj:d,clearance:c}).valid\u0026\u0026l7(q8({inputSrj:e,routedSrj:d}),o.connectionName)?l:void 0};if(l.layer!==h){const t=g7({trace:o.trace,endpoint:o.exitPoint,layer:o.targetLayer,distances:[.4,.8,1.2,1.6]});for(const e of t){const t={...e,layer:o.targetLayer};for(const n of[void 0,{x:d.x,y:e.y},{x:e.x,y:d.y}]){const o=p({start:t,viaPoint:e,terminalApproach:n});if(o)return o}}}const m=[[d],[{x:d.x,y:l.y},d],[{x:l.x,y:d.y},d]];for(const t of m){const e=t[0],n=M8(l,e),o=l.layer===h?[0]:[.4,.8,1.2,1.6];for(const i of o){if(l.layer!==h\u0026\u0026(n\u003c=i+.2||i\u003c=1e-6))continue;const o=p({start:l,viaPoint:l.layer===h?{x:l.x,y:l.y}:{x:l.x+(e.x-l.x)*i/n,y:l.y+(e.y-l.y)*i/n},terminalApproach:t.length\u003e1?e:void 0});if(o)return o}}}function y7(t){const{inputSrj:e,fanoutSrj:n,plans:o,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a,effort:c=1,routeDownstreamConnections:l}=t,d=[],h=n7({inputSrj:e,routedSrj:n,clearance:a}),u=q8({inputSrj:e,routedSrj:n}),p=o.filter(t=\u003ei7(t.sourcePoint)!==i7(t.targetPoint)\u0026\u0026M8(t.sourcePoint,t.targetPoint)\u003c=.25\u0026\u0026!l7(u,t.connectionName));let m={traces:[],failedConnectionNames:p.map(t=\u003et.connectionName),blockingConnectionNames:[],connectivity:u,drc:h},g=0;if(h.valid){let t=[];const o=new Map(p.map((t,e)=\u003e[t.connectionName,e])),c=e.connections.length\u003e32?1:3;for(let l=0;l\u003cc;l++){const c=new Map(t.map((t,e)=\u003e[t,e])),l=u7({inputSrj:e,fanoutSrj:n,plans:p.toSorted((t,e)=\u003e(c.get(t.connectionName)??Number.MAX_SAFE_INTEGER)-(c.get(e.connectionName)??Number.MAX_SAFE_INTEGER)||(o.get(t.connectionName)??0)-(o.get(e.connectionName)??0)),traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});if(g++,l.drc.valid\u0026\u0026(l.connectivity.connectedConnectionCount\u003em.connectivity.connectedConnectionCount||l.connectivity.connectedConnectionCount===m.connectivity.connectedConnectionCount\u0026\u0026l.traces.length\u003cm.traces.length)\u0026\u0026(m=l),t=[...new Set([...l.failedConnectionNames,...l.blockingConnectionNames,...t])],0===l.failedConnectionNames.length)break}}else d.push(\"Fanout prefix failed emitted-copper DRC; skipped completion\");const f=new Set(p.map(t=\u003et.connectionName)),y=o.filter(t=\u003e!f.has(t.connectionName)\u0026\u0026!l7(u,t.connectionName)),_=[];if(h.valid)for(const t of y){const o=f7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:[...m.traces,..._],traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});o\u0026\u0026_.push(o)}const b={...n,traces:[...n.traces??[],...m.traces,..._]},x=new Set(q8({inputSrj:e,routedSrj:b}).issues.map(t=\u003et.connectionName)),v=n.connections.filter(t=\u003e!f.has(t.name)\u0026\u0026x.has(t.name));let S=[];if(h.valid\u0026\u0026v.length\u003e0\u0026\u0026v.length\u003c=12\u0026\u0026l){const t=new Set(v.map(t=\u003et.name)),o={...n,connections:v,buses:n.buses?.map(e=\u003e({...e,connectionNames:e.connectionNames.filter(e=\u003et.has(e))})).filter(t=\u003et.connectionNames.length\u003e0),obstacles:[...n.obstacles,...m7(n)],traces:[]};try{const i=l(o,{effort:c});S=function(t){const{inputSrj:e,fanoutSrj:n,localTraces:o,candidates:i,clearance:r}=t,s=[...n.traces??[],...o],a={...n,traces:s},c=q8({inputSrj:e,routedSrj:a}),l=i.filter(t=\u003et.route.length\u003e1\u0026\u0026t.route.every(t=\u003e\"wire\"===t.route_type||\"via\"===t.route_type)\u0026\u0026!d7({trace:t,endpointSrjs:[e,n]})).filter(t=\u003e{const o=q8({inputSrj:e,routedSrj:{...n,traces:[...s,t]}});return o.connectedConnectionCount\u003ec.connectedConnectionCount\u0026\u0026l7(o,t.connection_name)}),d={...n,traces:[...s,...l]};if(n7({inputSrj:e,routedSrj:d,clearance:r}).valid)return l;const h=[];for(const t of l.toSorted((t,e)=\u003ep7(t)-p7(e))){const o={...n,traces:[...s,...h,t]};if(!n7({inputSrj:e,routedSrj:o,clearance:r}).valid)continue;const i=q8({inputSrj:e,routedSrj:{...n,traces:[...s,...h]}}),a=q8({inputSrj:e,routedSrj:o});a.connectedConnectionCount\u003ei.connectedConnectionCount\u0026\u0026l7(a,t.connection_name)\u0026\u0026h.push(t)}return h}({inputSrj:e,fanoutSrj:n,localTraces:[...m.traces,..._],candidates:i.filter(e=\u003et.has(e.connection_name)),clearance:a})}catch(t){d.push(`Downstream router failed: ${t instanceof Error?t.message:String(t)}`)}}else!h.valid\u0026\u0026v.length\u003e0?d.push(\"Skipped downstream router because the endpoint-completion baseline failed emitted-copper DRC\"):v.length\u003e12?d.push(`Skipped downstream router for ${v.length} unresolved connections (bounded at 12)`):v.length\u003e0\u0026\u0026!l\u0026\u0026d.push(`Skipped downstream router for ${v.length} unresolved connections because no routeDownstreamConnections callback was provided`);const I=[...m.traces,..._,...S];for(const t of y){if(l7(q8({inputSrj:e,routedSrj:{...n,traces:[...n.traces??[],...I]}}),t.connectionName))continue;const o=f7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:I,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});o\u0026\u0026I.push(o)}const C=function(t){const{fanoutSrj:e,completionTraces:n}=t,o=new Map(n.flatMap(t=\u003e{const e=t.route.find(t=\u003e\"wire\"===t.route_type);return e?[[t.connection_name,{x:e.x,y:e.y,layer:e.layer}]]:[]})),i=(e.traces??[]).map(t=\u003e{if(!t.pcb_trace_id.startsWith(\"fanout:\"))return t;const e=o.get(t.connection_name);if(!e)return t;let n;for(let o=0;o\u003ct.route.length;o++){const i=t.route[o];if(\"wire\"===i?.route_type){if(void 0!==n){const o=t.route[n];if(\"wire\"===o?.route_type\u0026\u0026o.layer===e.layer\u0026\u0026i.layer===e.layer\u0026\u0026N8(e,o,i)\u003c=1e-6){const r=t.route.slice(0,n+1);return M8(o,e)\u003e1e-6\u0026\u0026r.push({route_type:\"wire\",x:e.x,y:e.y,width:i.width,layer:e.layer}),{...t,route:r}}}n=o}else n=void 0}return t});return{...e,traces:i}}({fanoutSrj:{...n,traces:[...n.traces??[],...I]},completionTraces:I}),P=q8({inputSrj:e,routedSrj:C}),M=n7({inputSrj:e,routedSrj:C,clearance:a});return M.valid?{simpleRouteJson:C,traces:I,report:{attemptedLocalConnectionCount:p.length,attemptedDownstreamConnectionCount:y.length,completionTraceCount:I.length,searchPassCount:g,errors:d,connectivity:P,drc:M}}:(d.push(\"Final endpoint-completion output failed emitted-copper DRC\"),{simpleRouteJson:n,traces:[],report:{attemptedLocalConnectionCount:p.length,attemptedDownstreamConnectionCount:y.length,completionTraceCount:0,searchPassCount:g,errors:d,connectivity:q8({inputSrj:e,routedSrj:n}),drc:h}})}var _7=new Set([\"left\",\"right\",\"top\",\"bottom\",\"top-left\",\"top-right\",\"bottom-left\",\"bottom-right\"]),b7={top_left:{direction:\"up\",preferredExit:\"top-left\"},top_middle:{direction:\"up\",preferredExit:\"top\"},top_right:{direction:\"up\",preferredExit:\"top-right\"},right_top:{direction:\"right\",preferredExit:\"top-right\"},right_middle:{direction:\"right\",preferredExit:\"right\"},right_bottom:{direction:\"right\",preferredExit:\"bottom-right\"},bottom_right:{direction:\"down\",preferredExit:\"bottom-right\"},bottom_middle:{direction:\"down\",preferredExit:\"bottom\"},bottom_left:{direction:\"down\",preferredExit:\"bottom-left\"},left_bottom:{direction:\"left\",preferredExit:\"bottom-left\"},left_middle:{direction:\"left\",preferredExit:\"left\"},left_top:{direction:\"left\",preferredExit:\"top-left\"},top:{direction:\"up\",preferredExit:\"top\"},right:{direction:\"right\",preferredExit:\"right\"},bottom:{direction:\"down\",preferredExit:\"bottom\"},left:{direction:\"left\",preferredExit:\"left\"}};function x7(t){const e=[...t].sort((t,e)=\u003et-e),n=[];for(const t of e)(0===n.length||Math.abs(n[n.length-1]-t)\u003e1e-6)\u0026\u0026n.push(t);return n}function v7(t){let e=Number.POSITIVE_INFINITY;for(let n=1;n\u003ct.length;n++){const o=t[n]-t[n-1];o\u003e1e-6\u0026\u0026(e=Math.min(e,o))}return e}function S7(t,e){const n=\"x\"===e?\"y\":\"x\";let o=Number.POSITIVE_INFINITY;for(let i=0;i\u003ct.length;i++){const r=t[i];for(let s=i+1;s\u003ct.length;s++){const i=t[s];if(Math.abs(r.center[n]-i.center[n])\u003e1e-6)continue;const a=Math.abs(r.center[e]-i.center[e]);a\u003e1e-6\u0026\u0026(o=Math.min(o,a))}}return o}function I7(t){return{minX:Math.min(...t.map(t=\u003et.center.x-t.width/2)),maxX:Math.max(...t.map(t=\u003et.center.x+t.width/2)),minY:Math.min(...t.map(t=\u003et.center.y-t.height/2)),maxY:Math.max(...t.map(t=\u003et.center.y+t.height/2))}}function C7(t,e){const n=e.componentBounds?.[t.componentId];if(!n){const e=2.25*t.pitchX,n=2.25*t.pitchY;return{minX:t.bounds.minX-e,maxX:t.bounds.maxX+e,minY:t.bounds.minY-n,maxY:t.bounds.maxY+n}}if([n.minX,n.maxX,n.minY,n.maxY].some(t=\u003e!Number.isFinite(t))||n.minX\u003e=n.maxX||n.minY\u003e=n.maxY)throw new Error(`FanoutSolver: componentBounds for \"${t.componentId}\" must contain finite, increasing bounds`);if(n.minX\u003et.bounds.minX+1e-6||n.maxX\u003ct.bounds.maxX-1e-6||n.minY\u003et.bounds.minY+1e-6||n.maxY\u003ct.bounds.maxY-1e-6)throw new Error(`FanoutSolver: componentBounds for \"${t.componentId}\" must contain every component pad`);return{...n}}function P7(t,e){if([t.minX,t.maxX,t.minY,t.maxY].some(t=\u003e!Number.isFinite(t))||t.minX\u003e=t.maxX||t.minY\u003e=t.maxY)throw new Error(\"FanoutSolver: sharedBoundary must contain finite, increasing bounds\");for(const n of e)if(t.minX\u003en.bounds.minX+1e-6||t.maxX\u003cn.bounds.maxX-1e-6||t.minY\u003en.bounds.minY+1e-6||t.maxY\u003cn.bounds.maxY-1e-6)throw new Error(`FanoutSolver: sharedBoundary must contain every pad of component \"${n.componentId}\"`);return{...t}}function M7(t){return\"layer\"in t?[t.layer]:t.layers}function N7(t){const{point:e,connection:n,componentGrids:o}=t,i=M7(e),r=[];for(const t of o){const o=t.obstacles.filter(t=\u003et.layers.some(t=\u003ei.includes(t))).filter(t=\u003eR8(e,t,1e-5)).sort((t,o)=\u003e{const i=t.connectedTo.includes(n.name)||t.connectedTo.includes(e.pointId??\"\")||t.connectedTo.includes(e.pcb_port_id??\"\");return i!==(o.connectedTo.includes(n.name)||o.connectedTo.includes(e.pointId??\"\")||o.connectedTo.includes(e.pcb_port_id??\"\"))?i?-1:1:t.width*t.height-o.width*o.height});o[0]\u0026\u0026r.push({grid:t,obstacle:o[0]})}return r}function w7(t){for(const e of t.pointsToConnect)if(\"layers\"in e\u0026\u0026e.busId)return e.busId;const e=/^BUS[_:-]([^_:-]+)(?:[_:-]\\d+)?$/i.exec(t.name);return e?.[1]??null}function T7(t,e){if(void 0!==e){if(!_7.has(e))throw new Error(`FanoutSolver: bus \"${t}\" has invalid preferredExit \"${e}\"`);return e}}function R7(t){if(void 0===t)return;if(0===t.length)throw new Error(\"FanoutSolver: availableCornersAndSides must contain at least one boundary region\");const e=[],n=new Set;for(const o of t){const t=b7[o];if(!t)throw new Error(`FanoutSolver: invalid availableCornersAndSides value \"${o}\"`);const i=`${t.direction}:${t.preferredExit}`;n.has(i)||(n.add(i),e.push(t))}return e}function E7(t,e){if(void 0===e||\"boundary\"===e.type)return{type:\"boundary\"};if(\"plane\"!==e.type||\"string\"!=typeof e.layer||0===e.layer.length)throw new Error(`FanoutSolver: bus \"${t}\" has an invalid termination target`);return{type:\"plane\",layer:e.layer}}function A7(t,e,n,o){const i=e.pointsToConnect.filter((t,e)=\u003ee!==n).sort((e,n)=\u003eM8(t,n)-M8(t,e))[0];if(!i\u0026\u0026\"plane\"===o.type)return t;if(!i)throw new Error(`FanoutSolver: connection \"${e.name}\" has no target beyond its BGA pad`);return i}function O7(t,e){let n=0,o=0;for(const t of e){const e=t.exitTargetPoint??t.targetPoint;n+=e.x-t.sourcePoint.x,o+=e.y-t.sourcePoint.y}if(Math.abs(n)\u003c1e-9\u0026\u0026Math.abs(o)\u003c1e-9)throw new Error(`FanoutSolver: cannot infer an escape direction for bus \"${t}\"`);return Math.abs(n)\u003e=Math.abs(o)?n\u003e=0?\"right\":\"left\":o\u003e=0?\"up\":\"down\"}function k7(t){return{x:t.reduce((t,e)=\u003et+e.sourcePoint.x,0)/t.length,y:t.reduce((t,e)=\u003et+e.sourcePoint.y,0)/t.length}}function L7(t,e,n){switch(e){case\"left\":return t.x-n.minX;case\"right\":return n.maxX-t.x;case\"up\":return n.maxY-t.y;case\"down\":return t.y-n.minY}}function D7(t,e){return\"up\"===t.direction||\"down\"===t.direction?t.preferredExit.endsWith(\"left\")?e.minX:t.preferredExit.endsWith(\"right\")?e.maxX:(e.minX+e.maxX)/2:t.preferredExit.startsWith(\"top\")?e.maxY:t.preferredExit.startsWith(\"bottom\")?e.minY:(e.minY+e.maxY)/2}function z7(t,e){return\"up\"===e||\"down\"===e?t.x:t.y}function F7(t){const{busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s}=t,a=s.filter(t=\u003e!(void 0!==n\u0026\u0026t.direction!==n||void 0!==o\u0026\u0026t.preferredExit!==o));if(0===a.length)throw new Error(`FanoutSolver: bus \"${e}\" cannot use its requested exit with availableCornersAndSides`);const c=n?void 0:function(t,e){try{return O7(t,e)}catch{return}}(e,i),l=c?a.filter(t=\u003et.direction===c):[],d=l.length\u003e0?l:a,h=k7(i);return[...d].toSorted((t,e)=\u003eL7(h,t.direction,r)-L7(h,e.direction,r)||Math.abs(z7(h,t.direction)-D7(t,r))-Math.abs(z7(h,e.direction)-D7(e,r))||t.preferredExit.localeCompare(e.preferredExit))[0]}function B7(t){const{busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s}=t;if(s)return F7({busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s});if(!o)return{direction:n??O7(e,i)};const a=function(t){switch(t){case\"left\":return[\"left\"];case\"right\":return[\"right\"];case\"top\":return[\"up\"];case\"bottom\":return[\"down\"];case\"top-left\":return[\"up\",\"left\"];case\"top-right\":return[\"up\",\"right\"];case\"bottom-left\":return[\"down\",\"left\"];case\"bottom-right\":return[\"down\",\"right\"]}}(o);if(n){if(!a.includes(n))throw new Error(`FanoutSolver: bus \"${e}\" direction \"${n}\" is incompatible with preferredExit \"${o}\"`);return{direction:n,preferredExit:o}}if(1===a.length)return{direction:a[0],preferredExit:o};let c;try{c=O7(e,i)}catch{c=void 0}if(c\u0026\u0026a.includes(c))return{direction:c,preferredExit:o};const l=k7(i);return{direction:a.toSorted((t,e)=\u003eL7(l,t,r)-L7(l,e,r)||t.localeCompare(e))[0],preferredExit:o}}function j7(t,e){const n=function(t){const e=new Map;for(const n of t){if(!n.componentId||n.isCopperPour)continue;const t=e.get(n.componentId)??[];t.push(n),e.set(n.componentId,t)}const n=[];for(const[t,o]of e){const e=x7(o.map(t=\u003et.center.x)),i=x7(o.map(t=\u003et.center.y)),r=S7(o,\"x\"),s=S7(o,\"y\"),a=v7(e),c=v7(i),l=Math.min(...[r,s,a,c].filter(Number.isFinite)),d=Math.max(...o.flatMap(t=\u003e[t.width,t.height])),h=Number.isFinite(l)?l:d,u=Number.isFinite(r)?r:Number.isFinite(a)?a:h,p=Number.isFinite(s)?s:Number.isFinite(c)?c:h;n.push({componentId:t,obstacles:o,xCoordinates:e,yCoordinates:i,pitchX:u,pitchY:p,bounds:I7(o)})}return n}(t.obstacles);if(0===n.length\u0026\u0026t.connections.length\u003e0)throw new Error(\"FanoutSolver: no componentId-tagged pad footprint was found\");const o=new Map(t.connections.map((t,e)=\u003e[t.name,e])),i=function(t,e){const n=e.buses??t.buses,o=new Map,i=new Set,r=new Set(t.connections.map(t=\u003et.name));for(const t of n??[]){if(o.has(t.busId))throw new Error(`FanoutSolver: duplicate bus id \"${t.busId}\"`);for(const e of t.connectionNames){if(!r.has(e))throw new Error(`FanoutSolver: bus \"${t.busId}\" references unknown connection \"${e}\"`);if(i.has(e))throw new Error(`FanoutSolver: connection \"${e}\" belongs to more than one bus`);i.add(e)}const n=E7(t.busId,t.termination),s=T7(t.busId,e.busExitPreferences?.[t.busId]??t.preferredExit??e.defaultPreferredExit);if(\"plane\"===n.type\u0026\u0026void 0!==s)throw new Error(`FanoutSolver: plane-terminated bus \"${t.busId}\" cannot also specify preferredExit`);o.set(t.busId,{...t,sourceComponentId:t.sourceComponentId??e.sourceComponentId,direction:e.busDirections?.[t.busId]??t.direction??e.defaultDirection,preferredExit:s,termination:n})}for(const n of t.connections){if(i.has(n.name))continue;const t=w7(n);if(t){const i=o.get(t);o.set(t,{busId:t,connectionNames:[...i?.connectionNames??[],n.name],direction:e.busDirections?.[t]??i?.direction??e.defaultDirection,sourceComponentId:i?.sourceComponentId??e.sourceComponentId,preferredExit:T7(t,e.busExitPreferences?.[t]??i?.preferredExit??e.defaultPreferredExit),termination:i?.termination??{type:\"boundary\"}})}else{const t=`connection:${n.name}`;o.set(t,{busId:t,connectionNames:[n.name],sourceComponentId:e.sourceComponentId,direction:e.busDirections?.[t]??e.defaultDirection,preferredExit:T7(t,e.busExitPreferences?.[t]??e.defaultPreferredExit),termination:{type:\"boundary\"}})}}return[...o.values()]}(t,e).map(e=\u003e{for(const[t,n]of Object.entries(e.connectionExitTargets??{})){if(!e.connectionNames.includes(t))throw new Error(`FanoutSolver: connectionExitTargets contains connection \"${t}\" outside bus \"${e.busId}\"`);if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error(`FanoutSolver: connectionExitTargets for connection \"${t}\" must contain finite x and y coordinates`)}const i=e.connectionNames.map(e=\u003e{const n=o.get(e);if(void 0===n)throw new Error(`FanoutSolver: connection \"${e}\" is missing from the input`);return t.connections[n]}),r=function(t){const{busSpec:e,connections:n,componentGrids:o}=t,i=new Map;for(const t of n){const e=new Set;for(const n of t.pointsToConnect)for(const i of N7({point:n,connection:t,componentGrids:o}))e.add(i.grid.componentId);for(const t of e)i.set(t,(i.get(t)??0)+1)}const r=[...o].sort((t,e)=\u003e{const n=(i.get(e.componentId)??0)-(i.get(t.componentId)??0);return 0!==n?n:e.obstacles.length-t.obstacles.length})[0],s=e.sourceComponentId?o.find(t=\u003et.componentId===e.sourceComponentId):void 0;if(e.sourceComponentId\u0026\u0026!s)throw new Error(`FanoutSolver: source component \"${e.sourceComponentId}\" for bus \"${e.busId}\" was not found`);const a=s??r,c=a?i.get(a.componentId)??0:0;if(!a||c!==n.length)throw new Error(e.sourceComponentId?`FanoutSolver: source component \"${e.sourceComponentId}\" is not an endpoint on every connection in bus \"${e.busId}\"`:`FanoutSolver: bus \"${e.busId}\" does not have one component endpoint on every connection`);return a}({busSpec:e,connections:i,componentGrids:n}),s=i.map(t=\u003efunction(t){const{connection:e,connectionIndex:n,sourceGrid:o,componentGrids:i,termination:r,exitTargetPoint:s}=t;for(let t=0;t\u003ce.pointsToConnect.length;t++){const a=e.pointsToConnect[t],c=N7({point:a,connection:e,componentGrids:i}).find(t=\u003et.grid.componentId===o.componentId);if(!c)continue;const l=M7(a).find(t=\u003ec.obstacle.layers.includes(t));if(!l)throw new Error(`FanoutSolver: connection \"${e.name}\" has no source layer shared with its BGA pad`);const d=A7(a,e,t,r);return{connection:e,connectionIndex:n,sourcePoint:a,sourcePointIndex:t,sourceLayer:l,sourceObstacle:c.obstacle,targetPoint:d,exitTargetPoint:s??d}}throw new Error(`FanoutSolver: connection \"${e.name}\" does not touch component \"${o.componentId}\"`)}({connection:t,connectionIndex:o.get(t.name),sourceGrid:r,componentGrids:n,termination:e.termination??{type:\"boundary\"},exitTargetPoint:e.connectionExitTargets?.[t.name]}));return{busSpec:e,sourceGrid:r,preparedConnections:s}}),r=function(t,e){if(e.sharedBoundary)return P7(e.sharedBoundary,t);const n=t.map(t=\u003eC7(t,e)),o=2.25*Math.max(...t.flatMap(t=\u003e[t.pitchX,t.pitchY]));return P7({minX:Math.min(...n.map(t=\u003et.minX))-o,maxX:Math.max(...n.map(t=\u003et.maxX))+o,minY:Math.min(...n.map(t=\u003et.minY))-o,maxY:Math.max(...n.map(t=\u003et.maxY))+o},t)}([...new Map(i.map(({sourceGrid:t})=\u003e[t.componentId,t])).values()],e),s=R7(e.availableCornersAndSides),a=[];for(const{busSpec:t,sourceGrid:n,preparedConnections:o}of i){const i=B7({busId:t.busId,explicitDirection:t.direction??e.busDirections?.[t.busId],preferredExit:t.preferredExit,connections:o,sharedBoundary:r,availableRegions:\"plane\"===t.termination?.type?void 0:s});a.push({busId:t.busId,direction:i.direction,preferredExit:i.preferredExit,termination:t.termination??{type:\"boundary\"},connections:o,componentId:n.componentId,componentObstacles:n.obstacles,componentBounds:C7(n,e),sharedBoundary:r,xCoordinates:[...n.xCoordinates],yCoordinates:[...n.yCoordinates],pitchX:n.pitchX,pitchY:n.pitchY})}return a}function $7(t){return\"left\"===t||\"right\"===t}function Y7(t){return\"right\"===t||\"up\"===t?1:-1}function X7(t,e){return $7(e)?t.x:t.y}function V7(t,e){return $7(e)?t.y:t.x}function W7(t,e,n){return $7(n)?{x:t,y:e}:{x:e,y:t}}function H7(t){switch(t.direction){case\"right\":return t.sharedBoundary.maxX;case\"left\":return t.sharedBoundary.minX;case\"up\":return t.sharedBoundary.maxY;case\"down\":return t.sharedBoundary.minY}}function G7(t){return $7(t.direction)?t.pitchX:t.pitchY}function U7(t){const e=$7(t.direction)?t.xCoordinates:t.yCoordinates,n=t.connections.reduce((e,n)=\u003ee+X7(n.sourcePoint,t.direction),0)/t.connections.length,o=Y7(t.direction)\u003e0?Math.max(...e):Math.min(...e);return Math.abs(n-o)\u003c1e-6}function Z7(t,e){const n=[...t.connections].sort((e,n)=\u003eV7(e.sourcePoint,t.direction)-V7(n.sourcePoint,t.direction)).findIndex(t=\u003et.connectionIndex===e.connectionIndex);if(n\u003c0)throw new Error(`FanoutSolver: connection \"${e.connection.name}\" is missing from bus \"${t.busId}\"`);return n}function q7(t,e){return t.x\u003e=e.minX-1e-6\u0026\u0026t.x\u003c=e.maxX+1e-6\u0026\u0026t.y\u003e=e.minY-1e-6\u0026\u0026t.y\u003c=e.maxY+1e-6}function J7(t,e,n,o,i){const r=e-t,s=Math.floor((r-o)/(n+o)+1e-9);if(s\u003c1)return[];const a=t+(r-(s*n+(s-1)*o))/2+n/2;return Array.from({length:s},(t,e)=\u003e({value:a+e*(n+o),kind:i}))}function K7(t){const e=V7(t.connection.exitTargetPoint??t.connection.targetPoint,t.bus.direction),n=$7(t.bus.direction)?t.bus.sharedBoundary.minY:t.bus.sharedBoundary.minX,o=$7(t.bus.direction)?t.bus.sharedBoundary.maxY:t.bus.sharedBoundary.maxX;return Math.max(n+t.traceWidth/2,Math.min(o-t.traceWidth/2,e))}function Q7(t){const{bus:e,connection:n,targetUsesVia:o,interstitialEscape:i,compactBusTracks:r,traceWidth:s,viaDiameter:a,clearance:c}=t,l=($7(e.direction)?e.yCoordinates:e.xCoordinates).toSorted((t,e)=\u003et-e),d=V7(n.sourcePoint,e.direction);if(r){const t=Z7(e,n);return(l[0]+l.at(-1))/2+(t-(e.connections.length-1)/2)*(s+c)}if(!o||!i)return d;const h=function(t){const e=($7(t.direction)?t.xCoordinates:t.yCoordinates).toSorted((t,e)=\u003et-e),n=t.connections.reduce((e,n)=\u003ee+X7(n.sourcePoint,t.direction),0)/t.connections.length,o=Y7(t.direction)\u003e0?e.at(-1):e[0];return Math.abs(o-n)/G7(t)}(e),u=s+c,p=Math.ceil(e.connections.length/2),m=(p-1)*u,g=a/2+s/2+c+.001,f=Math.round(h)+1,y=f*g+(f-1)*m,_=Z7(e,n),b=l[0],x=l.at(-1),v=_\u003cp?b-y-(p-_-1)*u:x+y+(_-p)*u,S=$7(e.direction)?e.sharedBoundary.minY:e.sharedBoundary.minX,I=$7(e.direction)?e.sharedBoundary.maxY:e.sharedBoundary.maxX;return Math.max(S+s/2,Math.min(I-s/2,v))}function ttt(t){const e=Y7(t.direction),n=[...t.connections].sort((n,o)=\u003e{const i=e*(X7(o.sourcePoint,t.direction)-X7(n.sourcePoint,t.direction));return Math.abs(i)\u003e1e-6?i:V7(n.sourcePoint,t.direction)-V7(o.sourcePoint,t.direction)}),o=[...t.connections].sort((n,o)=\u003eV7(n.sourcePoint,t.direction)-V7(o.sourcePoint,t.direction)||e*(X7(o.sourcePoint,t.direction)-X7(n.sourcePoint,t.direction))),i=[n,[...n].reverse(),o,[...o].reverse()];for(let t=1;t\u003cMath.min(n.length,8);t++)i.push([...n.slice(t),...n.slice(0,t)]);return i}function ett(t,e,n,o,i){M8(e,n)\u003c1e-9||t.push({start:e,end:n,width:o,layer:i})}function ntt(t){const{preparedConnection:e,bus:n,targetLayer:o,track:i,exitAxis:r,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,viaHandedness:d,interstitialEscape:h,spreadLaneIndex:u,clearance:p,terminateAtVia:m}=t,g={x:e.sourcePoint.x,y:e.sourcePoint.y},f=Y7(n.direction),y=G7(n),_=function(t){return $7(t.direction)?t.pitchY:t.pitchX}(n),b=o!==e.sourceLayer,x=$7(n.direction)?e.sourceObstacle.width:e.sourceObstacle.height,v=b\u0026\u0026!U7(n)?x\u003e=y?x/2+c/2+p+.001:.5*y:b?Math.max(.5*y,x/2+(b?c:a)/2+p+.001):x/2+a/2+p+.001,S=X7(g,n.direction)+f*v,I=V7(g,n.direction)+d*_*.5,C=W7(S,I,n.direction),P=c/2+a/2+p+.001+u*(a+p),M=h\u0026\u0026y\u003e=P+c/2+p,N=M?W7(S+f*P,I,n.direction):C,w=W7(M?X7(N,n.direction):S+f*Math.abs(i-I),i,n.direction),T=m?C:W7(r,i,n.direction),R=[],E=[];let A;if(E.push({route_type:\"wire\",x:g.x,y:g.y,width:a,layer:e.sourceLayer,start_pcb_port_id:e.sourcePoint.pcb_port_id}),ett(R,g,C,a,e.sourceLayer),E.push({route_type:\"wire\",x:C.x,y:C.y,width:a,layer:e.sourceLayer}),o!==e.sourceLayer){const t=L8(e.sourceLayer,o,s);A={center:C,diameter:c,holeDiameter:l,fromLayer:e.sourceLayer,toLayer:o,spanLayers:t},E.push({route_type:\"via\",x:C.x,y:C.y,from_layer:e.sourceLayer,to_layer:o,via_diameter:c,via_hole_diameter:l}),E.push({route_type:\"wire\",x:C.x,y:C.y,width:a,layer:o})}const O=m?[C]:M?function(t,e){if(t.length\u003c3)return t;const n=[t[0]];for(let o=1;o\u003ct.length-1;o++){const i=t[o-1],r=t[o],s=t[o+1],a=M8(i,r),c=M8(r,s);if(a\u003c1e-9||c\u003c1e-9)continue;const l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c},h=l.x*d.x+l.y*d.y;if(Math.abs(h)\u003e1e-6){n.push(r);continue}const u=Math.min(e,a/2,c/2);n.push({x:r.x-l.x*u,y:r.y-l.y*u}),n.push({x:r.x+d.x*u,y:r.y+d.y*u})}return n.push(t.at(-1)),n}([C,N,w,T],Math.max(a+p,2*a)):[C,w,T];for(let t=1;t\u003cO.length;t++){const e=O[t-1],n=O[t];ett(R,e,n,a,o),E.push({route_type:\"wire\",x:n.x,y:n.y,width:a,layer:o})}const k=x8({connectionName:e.connection.name,sourcePointIndex:e.sourcePointIndex});return{busId:n.busId,connectionName:e.connection.name,connectionIndex:e.connectionIndex,sourcePointIndex:e.sourcePointIndex,sourcePoint:e.sourcePoint,sourceObstacle:e.sourceObstacle,sourceLayer:e.sourceLayer,targetPoint:e.targetPoint,targetLayer:o,termination:n.termination,direction:n.direction,exitPoint:T,trace:{type:\"pcb_trace\",pcb_trace_id:k.traceId,connection_name:e.connection.name,connectsTo:[...e.sourcePoint.pointId?[e.sourcePoint.pointId]:[],...e.sourcePoint.pcb_port_id?[e.sourcePoint.pcb_port_id]:[],k.boundaryExitPointId],route:E},segments:R,via:A,length:R.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}function ott(t){const{preparedConnection:e,bus:n,viaDiameter:o,clearance:i}=t,{sourcePoint:r,targetPoint:s}=e,a=.5*Math.max(n.pitchX,n.pitchY);if(M8(r,s)\u003c=1e-6||M8(r,s)\u003ea)return[];const c=(()=\u003e{switch(n.direction){case\"left\":return{x:-1,y:0};case\"right\":return{x:1,y:0};case\"up\":return{x:0,y:1};case\"down\":return{x:0,y:-1}}})(),l=Math.SQRT1_2,d=[c,...[{x:l,y:l},{x:l,y:-l},{x:-l,y:l},{x:-l,y:-l},{x:1,y:0},{x:-1,y:0},{x:0,y:1},{x:0,y:-1}].toSorted((t,e)=\u003ee.x*c.x+e.y*c.y-(t.x*c.x+t.y*c.y))],h=Math.max(o,o/2+i),u=[h,Math.max(h,.5*Math.min(n.pitchX,n.pitchY)),Math.max(h,.625*Math.min(n.pitchX,n.pitchY)),Math.max(h,.75*Math.min(n.pitchX,n.pitchY))],p=[];for(const t of[r,s])for(const e of u)for(const n of d){const o={x:t.x+n.x*e,y:t.y+n.y*e};M8(o,r)\u003c=1e-6||M8(o,s)\u003c=1e-6||p.some(t=\u003eM8(t,o)\u003c=1e-6)||p.push(o)}return p}function itt(t){const{plan:e,preparedConnection:n,planeLayer:o,viaPoint:i,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c}=t,l={x:n.targetPoint.x,y:n.targetPoint.y},d=function(t){const e=\"layer\"in t?t.layer:t.layers[0];if(!e)throw new Error(\"FanoutSolver: plane endpoint has no copper layer\");return e}(n.targetPoint),h=L8(o,d,r);if(!h.includes(o))throw new Error(`FanoutSolver: via for \"${n.connection.name}\" does not cross plane ${o}`);const u=[{start:i,end:l,width:s,layer:d}],p={center:i,diameter:a,holeDiameter:c,fromLayer:o,toLayer:d,spanLayers:h},m=x8({connectionName:n.connection.name,sourcePointIndex:n.sourcePointIndex}),g={type:\"pcb_trace\",pcb_trace_id:m.planeEndpointTraceId,connection_name:n.connection.name,connectsTo:[...n.targetPoint.pointId?[n.targetPoint.pointId]:[],...n.targetPoint.pcb_port_id?[n.targetPoint.pcb_port_id]:[],m.planeEndpointPointId],route:[{route_type:\"wire\",...i,width:s,layer:o},{route_type:\"via\",...i,from_layer:o,to_layer:d,via_diameter:a,via_hole_diameter:c},{route_type:\"wire\",...i,width:s,layer:d},{route_type:\"wire\",...l,width:s,layer:d}]};return{...e,planeEndpointTrace:g,planeEndpointSegments:u,planeEndpointVia:p,length:e.length+u.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}function rtt(t){const{segment:e,plan:n,segmentIndex:o,srj:i,allowSameNetMerges:r,obstacles:s,clearance:a}=t;for(const t of s)if(t.layers.includes(e.layer)\u0026\u0026!t.connectedTo.includes(n.connectionName)\u0026\u0026!(r\u0026\u0026Y8(i,t,n.connectionName)||K8({inputSrj:i,segment:e,bodyObstacle:t,connectionName:n.connectionName})||0===o\u0026\u0026t===n.sourceObstacle\u0026\u0026e.layer===n.sourceLayer||!(A8(e,t)\u003ce.width/2+a-1e-9)))return!1;return!0}function stt(t){return[...t.segments,...t.planeEndpointSegments??[]]}function att(t){return[t.via,t.planeEndpointVia].filter(t=\u003eBoolean(t))}function ctt(t){const{plan:e,srj:n,sharedBoundary:o,clearance:i,allowSameNetMerges:r}=t,s=function(t,e){return{minX:Math.min(t.minX,e.minX),maxX:Math.max(t.maxX,e.maxX),minY:Math.min(t.minY,e.minY),maxY:Math.max(t.maxY,e.maxY)}}(n.bounds,o);if(!q7(e.exitPoint,s)||stt(e).some(t=\u003e!q7(t.start,s)||!q7(t.end,s)))return!1;const a=stt(e);for(let t=0;t\u003ca.length;t++)if(!rtt({segment:a[t],plan:e,segmentIndex:t\u003ce.segments.length?t:-1,srj:n,allowSameNetMerges:r,obstacles:n.obstacles,clearance:i}))return!1;for(const t of att(e))for(const o of n.obstacles)if(o.layers.some(e=\u003et.spanLayers.includes(e))\u0026\u0026(!r||!Y8(n,o,e.connectionName))\u0026\u0026E8(t.center,o)\u003ct.diameter/2+i-1e-9)return!1;return!0}function ltt(t){const{plan:e,otherPlans:n,staticClearanceCache:o,blockingBusCounts:i,cacheKey:r,srj:s,sharedBoundary:a,clearance:c,allowSameNetMerges:l}=t;let d=o?.get(r);return void 0===d\u0026\u0026(d=ctt({plan:e,srj:s,sharedBoundary:a,clearance:c,allowSameNetMerges:l}),o?.set(r,d)),d\u0026\u0026function(t){const{plan:e,otherPlans:n,srj:o,allowSameNetMerges:i,clearance:r,blockingBusCounts:s}=t;for(const t of n){if(i\u0026\u0026$8(o,e.connectionName,t.connectionName))continue;if(e.sourcePoint.pcb_port_id\u0026\u0026e.sourcePoint.pcb_port_id===t.sourcePoint.pcb_port_id||e.sourcePoint.pointId\u0026\u0026e.sourcePoint.pointId===t.sourcePoint.pointId)continue;const n=()=\u003e{t.busId!==e.busId\u0026\u0026s?.set(t.busId,(s.get(t.busId)??0)+1)},a=stt(e),c=stt(t),l=att(e),d=att(t);for(const t of a){for(const e of c)if(!O8(t,e,r))return n(),!1;for(const e of d)if(e.spanLayers.includes(t.layer)\u0026\u0026N8(e.center,t.start,t.end)\u003ce.diameter/2+t.width/2+r-1e-9)return n(),!1}for(const t of l){for(const e of c)if(t.spanLayers.includes(e.layer)\u0026\u0026N8(t.center,e.start,e.end)\u003ct.diameter/2+e.width/2+r-1e-9)return n(),!1;for(const e of d)if(t.spanLayers.some(t=\u003ee.spanLayers.includes(t))\u0026\u0026M8(t.center,e.center)\u003c(t.diameter+e.diameter)/2+r-1e-9)return n(),!1}}return!0}({plan:e,otherPlans:n,srj:s,allowSameNetMerges:l,clearance:c,blockingBusCounts:i})}function dtt(t,e=1){const{srj:n,bus:o,targetLayer:i,acceptedPlans:r,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,clearance:d,compactBusTracks:h,staticClearanceCache:u,blockingBusCounts:p,allowSameNetMerges:m=!1}=t;if(!Number.isInteger(e)||e\u003c1)throw new Error(`FanoutSolver: maxAlternatives must be a positive integer, received ${e}`);if(\"plane\"===o.termination.type){const e=function(t){const{srj:e,bus:n,targetLayer:o,acceptedPlans:i,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,clearance:l,staticClearanceCache:d,blockingBusCounts:h,allowSameNetMerges:u=!1}=t,p=n.connections[0]?.sourceObstacle;if(!p||\"plane\"!==n.termination.type)return null;const m=n.connections[0].sourceLayer;if(o===m)return null;const g=[n.direction,...[\"left\",\"right\",\"up\",\"down\"].filter(t=\u003et!==n.direction)];for(const t of g){const m=t===n.direction?n:{...n,direction:t},g=$7(t)?p.width:p.height,f=G7(m)/2-g/2\u003e=a/2+l-1e-9,y=f?[0]:[1,-1];for(const p of y)for(const g of ttt(m)){const y=[];let _=!0;for(const b of g){const g=V7(b.sourcePoint,t),x=ntt({preparedConnection:b,bus:m,targetLayer:o,track:g,exitAxis:H7(m),layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,viaHandedness:p,interstitialEscape:!f,spreadLaneIndex:0,clearance:l,terminateAtVia:!0}),v=[...ott({preparedConnection:b,bus:m,viaDiameter:a,clearance:l}).map(t=\u003eitt({plan:x,preparedConnection:b,planeLayer:o,viaPoint:t,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c})),x].find((r,s)=\u003eltt({plan:r,otherPlans:[...i,...y],staticClearanceCache:d,blockingBusCounts:h,cacheKey:`plane:${n.busId}:${o}:${t}:${b.connectionIndex}:${p}:${s}`,srj:e,sharedBoundary:n.sharedBoundary,clearance:l,allowSameNetMerges:u}));if(!v){_=!1;break}y.push(v)}if(_)return y}}return null}(t);return e?[e]:[]}const g=H7(o),f=o.connections[0]?.sourceObstacle;if(!f)return[[]];const y=$7(o.direction)?f.width:f.height,_=o.connections[0].sourceLayer,b=i!==_,x=U7(o),v=G7(o)/2-y/2\u003e=c/2+d-1e-9,S=b\u0026\u0026!x\u0026\u0026!v,I=b?v||x?[0]:[1,-1]:[0],C=[],P=new Set,M=(t,f,y,_)=\u003e{if(C.length\u003e=e)return;if(y\u003e=t.length)return void(t=\u003e{const e=t.map(t=\u003e`${t.connectionIndex}:${t.targetLayer}:${t.exitPoint.x}:${t.exitPoint.y}:${t.segments.map(t=\u003e`${t.start.x},${t.start.y},${t.end.x},${t.end.y},${t.layer}`).join(\";\")}`).join(\"|\");P.has(e)||(P.add(e),C.push(t))})(_);const x=t[y],v=Z7(o,x),I=[K7({bus:o,connection:x,traceWidth:a}),Q7({bus:o,connection:x,targetUsesVia:b,interstitialEscape:S,compactBusTracks:h,traceWidth:a,viaDiameter:c,clearance:d})].filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e-t)\u003c1e-9)===e).flatMap(t=\u003efunction(t){const{bus:e,connection:n,preferredTrack:o,traceWidth:i,clearance:r}=t,s=($7(e.direction)?e.yCoordinates:e.xCoordinates).toSorted((t,e)=\u003et-e),a=Math.max(...e.componentObstacles.map(t=\u003e$7(e.direction)?t.height/2:t.width/2)),c=$7(e.direction)?e.sharedBoundary.minY:e.sharedBoundary.minX,l=$7(e.direction)?e.sharedBoundary.maxY:e.sharedBoundary.maxX,d=l-c,h=l,u=[{value:o,kind:\"preferred\"},...J7(c,s[0]-a,i,r,\"margin\")];for(let t=0;t\u003cs.length;t++)u.push({value:s[t],kind:\"corridor\"}),t\u003cs.length-1\u0026\u0026u.push(...J7(s[t]+a,s[t+1]-a,i,r,\"gap\"));u.push(...J7(s.at(-1)+a,h,i,r,\"margin\"));const p=V7(n.sourcePoint,e.direction),m=(s[0]+s.at(-1))/2;return u.filter(t=\u003eMath.abs(t.value-p)\u003c=d+1e-9).filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e.value-t.value)\u003c1e-9)===e).sort((t,e)=\u003eMath.abs(t.value-o)-Math.abs(e.value-o)-.001*(Math.abs(t.value-m)-Math.abs(e.value-m)))}({bus:o,connection:x,preferredTrack:t,traceWidth:a,clearance:d})).filter((t,e,n)=\u003en.findIndex(e=\u003eMath.abs(e.value-t.value)\u003c1e-9)===e);for(let h=0;h\u003cI.length;h++){const b=I[h],P=ntt({preparedConnection:x,bus:o,targetLayer:i,track:b.value,exitAxis:g,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,viaHandedness:f,interstitialEscape:S,spreadLaneIndex:Math.min(v,o.connections.length-v-1),clearance:d,terminateAtVia:!1});if(ltt({plan:P,otherPlans:[...r,..._],staticClearanceCache:u,blockingBusCounts:p,cacheKey:`boundary:${o.busId}:${i}:${x.connectionIndex}:${f}:${h}`,srj:n,sharedBoundary:o.sharedBoundary,clearance:d,allowSameNetMerges:m})){if(M(t,f,y+1,[..._,P]),C.length\u003e=e)return;if(1===e)return}}};for(const t of I)for(const n of ttt(o))if(M(n,t,0,[]),C.length\u003e=e)return C;return C}function htt(t){return dtt(t,1)[0]??null}var utt=1e-9,ptt=\"1\"===globalThis.process?.env?.FANOUT_FLOW_DEBUG;function mtt(t){const e=t.connection;return t.sourceObstacle.connectedTo.find(t=\u003et.startsWith(\"connectivity_net\"))??e.netConnectionName??t.connection.name.replace(/::fanout:\\d+$/,\"\")}function gtt(t,e){return t===e.connection.sourceObstacle||t.connectedTo.includes(e.connection.connection.name)||t.connectedTo.includes(e.netKey)}function ftt(t,e){const n=e.x-t.x,o=e.y-t.y,i=Math.abs(n),r=Math.abs(o);return i\u003cutt||r\u003cutt||Math.abs(i-r)\u003cutt?[t,e]:i\u003er?[t,{x:t.x+Math.sign(n)*r,y:e.y},e]:[t,{x:e.x,y:t.y+Math.sign(o)*i},e]}function ytt(t){if(t.length\u003c2)return t;const e=[t[0]];for(const n of t.slice(1)){const t=e.at(-1),o=Math.abs(n.x-t.x),i=Math.abs(n.y-t.y);o\u003cutt||i\u003cutt||Math.abs(o-i)\u003cutt?e.push(n):e.push(...ftt(n,t).reverse().slice(1))}return _tt(e)}function _tt(t){if(t.length\u003c3)return t;const e=[t[0]];for(let n=1;n\u003ct.length-1;n++){const o=e.at(-1),i=t[n],r=t[n+1];Math.sign(i.x-o.x)===Math.sign(r.x-i.x)\u0026\u0026Math.sign(i.y-o.y)===Math.sign(r.y-i.y)||e.push(i)}return e.push(t.at(-1)),e}function btt(t,e){if(t.length\u003c3)return t;const n=[t[0]];for(let o=1;o\u003ct.length-1;o++){const i=t[o-1],r=t[o],s=t[o+1],a=M8(i,r),c=M8(r,s);if(a\u003cutt||c\u003cutt)continue;const l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c};if(Math.abs(l.x*d.x+l.y*d.y)\u003e1e-6){n.push(r);continue}const h=Math.min(e,a/2,c/2);n.push({x:r.x-l.x*h,y:r.y-l.y*h}),n.push({x:r.x+d.x*h,y:r.y+d.y*h})}return n.push(t.at(-1)),_tt(n)}function xtt(t,e){const n=[];for(let o=1;o\u003ct.length;o++)M8(t[o-1],t[o])\u003cutt||n.push({start:t[o-1],end:t[o],width:e,layer:\"top\"});return n}var vtt=class{edges;levels;nextEdges;constructor(t){this.edges=Array.from({length:t},()=\u003e[]),this.levels=new Int32Array(t),this.nextEdges=new Int32Array(t)}addEdge(t,e,n,o={}){const i={to:e,reverseIndex:this.edges[e].length,capacity:n,initialCapacity:n,...o},r={to:t,reverseIndex:this.edges[t].length,capacity:0,initialCapacity:0};this.edges[t].push(i),this.edges[e].push(r)}buildLevels(t,e){this.levels.fill(-1);const n=new Int32Array(this.edges.length);let o=0,i=0;for(n[i++]=t,this.levels[t]=0;o\u003ci;){const t=n[o++];for(const e of this.edges[t])e.capacity\u003c=0||this.levels[e.to]\u003e=0||(this.levels[e.to]=this.levels[t]+1,n[i++]=e.to)}return this.levels[e]\u003e=0}sendFlow(t,e){if(t===e)return 1;for(let n=this.nextEdges[t];n\u003cthis.edges[t].length;n++,this.nextEdges[t]=n){const o=this.edges[t][n];if(o.capacity\u003c=0||this.levels[o.to]!==this.levels[t]+1)continue;const i=this.sendFlow(o.to,e);if(0!==i)return o.capacity-=i,this.edges[o.to][o.reverseIndex].capacity+=i,i}return 0}maximumFlow(t,e,n){let o=0;for(;o\u003cn\u0026\u0026this.buildLevels(t,e);)for(this.nextEdges.fill(0);o\u003cn;){const n=this.sendFlow(t,e);if(0===n)break;o+=n}return o}};function Stt(t){const{direction:e,availableDirections:n,items:o,grid:i,obstacles:r,traceWidth:s,clearance:a,occupiedNodes:c,acceptedSegments:l,connectorSelectionOffset:d=0}=t;if(0===o.length)return{routes:[],usedNodes:[],unmatchedItems:[]};const{boundary:h,step:u,columnCount:p,rowCount:m,nodeCount:g}=i,f=t=\u003ei.points[t],y=s/2+a,_=s+a,b=new Uint8Array(g);for(let t=0;t\u003cg;t++)!c[t]\u0026\u0026i.obstacleFreeNodes[t]\u0026\u0026(b[t]=1);const x=(t,e)=\u003e{const n=xtt(t,s);return n.every(t=\u003er.every(n=\u003egtt(n,e)||A8(t,n)\u003e=y-utt))\u0026\u0026n.every(t=\u003el.every(e=\u003eT8(t.start,t.end,e.start,e.end)\u003e=_-utt))},v=new Map;for(const t of o){const e=`${t.source.x.toFixed(6)}:${t.source.y.toFixed(6)}:${t.netKey}`,n=v.get(e)??[];n.push(t),v.set(e,n)}const S=Array.from({length:3721},(t,e)=\u003e{const n=e%61-30,o=Math.floor(e/61)-30;return{x:n,y:o,distanceSquared:n*n+o*o}}).sort((t,e)=\u003et.distanceSquared-e.distanceSquared),I=[];for(const t of v.values()){const e=t[0],n=Math.hypot(e.connection.sourceObstacle.width/2,e.connection.sourceObstacle.height/2)+a+2*u,o=Math.round((e.source.x-h.minX)/u),i=Math.round((e.source.y-h.minY)/u),r=[],s=new Set;for(const t of S){const a=o+t.x,c=i+t.y;if(a\u003c0||a\u003e=p||c\u003c0||c\u003e=m)continue;const l=c*p+a;if(!b[l]||s.has(l))continue;if(M8(e.source,f(l))\u003en)continue;const d=ftt(e.source,f(l));if(x(d,e)\u0026\u0026(s.add(l),r.push({node:l,connectorPoints:d}),r.length\u003e=12))break}if(0===r.length)return null;I.push({item:e,equivalentItems:t,candidates:r})}const C=[];for(const t of[...I].sort((t,e)=\u003et.candidates.length-e.candidates.length)){const e=0===t.candidates.length?0:d%t.candidates.length,n=[...t.candidates.slice(e),...t.candidates.slice(0,e)].find(e=\u003e{const n=xtt(e.connectorPoints,s);return C.every(e=\u003ee.netKey===t.item.netKey||n.every(t=\u003ee.segments.every(e=\u003eT8(t.start,t.end,e.start,e.end)\u003e=_-utt)))});if(!n)return null;t.candidates=[n],C.push({netKey:t.item.netKey,segments:xtt(n.connectorPoints,s)})}const P=new Set(I.map(t=\u003et.candidates[0].node));for(const t of C)for(const e of t.segments){const t=Math.max(0,Math.floor((Math.min(e.start.x,e.end.x)-_-h.minX)/u)),n=Math.min(p-1,Math.ceil((Math.max(e.start.x,e.end.x)+_-h.minX)/u)),o=Math.max(0,Math.floor((Math.min(e.start.y,e.end.y)-_-h.minY)/u)),i=Math.min(m-1,Math.ceil((Math.max(e.start.y,e.end.y)+_-h.minY)/u));for(let r=o;r\u003c=i;r++)for(let o=t;o\u003c=n;o++){const t=r*p+o;if(!b[t]||P.has(t))continue;const n=f(t);T8(e.start,e.end,n,n)\u003c_-utt\u0026\u0026(b[t]=0)}}const M=1+I.length,N=M+g,w=N+g,T=new vtt(w+1);for(let t=0;t\u003cI.length;t++){const e=1+t;T.addEdge(0,e,1);for(const n of I[t].candidates)T.addEdge(e,M+n.node,1,{gridNode:n.node})}for(let t=0;t\u003cg;t++){if(!b[t])continue;T.addEdge(M+t,N+t,1);const o=t%p,r=Math.floor(t/p);for(const e of i.neighbors[t])b[e]\u0026\u0026T.addEdge(N+t,M+e,1,{gridNode:e});(\"any\"===e\u0026\u0026((!n||n.has(\"left\"))\u0026\u00260===o||(!n||n.has(\"right\"))\u0026\u0026o===p-1||(!n||n.has(\"down\"))\u0026\u00260===r||(!n||n.has(\"up\"))\u0026\u0026r===m-1)||\"left\"===e\u0026\u00260===o||\"right\"===e\u0026\u0026o===p-1||\"down\"===e\u0026\u00260===r||\"up\"===e\u0026\u0026r===m-1)\u0026\u0026T.addEdge(N+t,w,1,{isSink:!0})}const R=T.maximumFlow(0,w,I.length),E=t=\u003e{const e=1+t;return T.edges[0].some(t=\u003et.to===e\u0026\u00261===t.initialCapacity\u0026\u00260===t.capacity)};if(R!==I.length\u0026\u0026ptt){const t=I.flatMap((t,e)=\u003eE(e)?[]:[t.item.connection.connection.name]);console.error(\"single-layer flow group failed\",{direction:e,achievedFlow:R,requiredFlow:I.length,unmatchedConnections:t})}const A=[],O=[],k=[];for(let t=0;t\u003cI.length;t++){const e=I[t];if(!E(t)){k.push(...e.equivalentItems);continue}const n=1+t,o=T.edges[n].find(t=\u003e1===t.initialCapacity\u0026\u00260===t.capacity\u0026\u0026void 0!==t.gridNode);if(void 0===o?.gridNode)return null;const i=e.candidates.find(t=\u003et.node===o.gridNode);if(!i)return null;const r=[f(i.node)];let a=i.node;const c=[a];for(let t=0;t\u003c=g;t++){const t=N+a,e=T.edges[t].find(t=\u003e1===t.initialCapacity\u0026\u00260===t.capacity\u0026\u0026(void 0!==t.gridNode||t.isSink));if(!e)return null;if(e.isSink)break;if(void 0===e.gridNode)return null;a=e.gridNode,c.push(a),r.push(f(a))}O.push(...c);const l=ytt(btt(_tt([...i.connectorPoints,...r.slice(1)]),u/2)),d=xtt(l,s);for(const t of e.equivalentItems)A.push({item:t,points:l,segments:d})}return{routes:A,usedNodes:O,unmatchedItems:k}}function Itt(t,e){const n=ftt(t,e),o=ftt(e,t).reverse();return n.length===o.length\u0026\u0026n.every((t,e)=\u003eM8(t,o[e])\u003cutt)?[n]:[n,o]}function Ctt(t,e){return Math.abs(t.x-e.minX)\u003cutt?\"left\":Math.abs(t.x-e.maxX)\u003cutt?\"right\":Math.abs(t.y-e.minY)\u003cutt?\"down\":Math.abs(t.y-e.maxY)\u003cutt?\"up\":null}function Ptt(t){const{items:e,grid:n,obstacles:o,traceWidth:i,clearance:r,availableBoundaryRegions:s}=t,a=s?new Set(s.map(t=\u003et.direction)):void 0,c=new Set(e.filter(t=\u003et.connection.sourceObstacle.width\u003e2\u0026\u0026t.connection.sourceObstacle.height\u003e2));let l=null;for(let t=0;t\u003c4;t++){const t=e.filter(t=\u003e!c.has(t));let s=null;for(let e=0;e\u003c4;e++){const c=Stt({direction:\"any\",availableDirections:a,items:t,grid:n,obstacles:o,traceWidth:i,clearance:r,occupiedNodes:new Uint8Array(n.nodeCount),acceptedSegments:[],connectorSelectionOffset:e});if(c\u0026\u0026((!s||c.routes.length\u003es.routes.length)\u0026\u0026(s=c),c.routes.length===t.length))break}if(!s)return null;if(s.routes.length===t.length){l=s;break}const d=new Map;for(const e of t)d.set(e.netKey,(d.get(e.netKey)??0)+1);let h=!1;for(const t of s.unmatchedItems)(d.get(t.netKey)??0)\u003c2||(c.add(t),h=!0);if(!h)return null}if(!l)return null;const d=[...l.routes],h=i/2+r,u=i+r;for(const t of c){const e=d.filter(e=\u003ee.item.netKey===t.netKey).flatMap(t=\u003et.points.map((e,n)=\u003e({route:t,point:e,pointIndex:n}))).sort((e,n)=\u003eNumber(n.route.item.bus.componentId===t.bus.componentId)-Number(e.route.item.bus.componentId===t.bus.componentId)||M8(t.source,e.point)-M8(t.source,n.point));let n=null;for(const r of e){for(const e of Itt(t.source,r.point)){const s=xtt(e,i),a=s.every(e=\u003eo.every(n=\u003egtt(n,t)||A8(e,n)\u003e=h-utt)),c=s.every(e=\u003ed.every(n=\u003en.item.netKey===t.netKey||n.segments.every(t=\u003eT8(e.start,e.end,t.start,t.end)\u003e=u-utt)));if(!a||!c)continue;const l=ytt(_tt([...e,...r.route.points.slice(r.pointIndex+1)]));n={item:t,points:l,segments:xtt(l,i)};break}if(n)break}if(!n)return null;d.push(n)}const p=d.map(t=\u003efunction(t,e){const{item:n,points:o,segments:i}=t,r=o.map((t,o)=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:e,layer:\"top\",...0===o\u0026\u0026n.connection.sourcePoint.pcb_port_id?{start_pcb_port_id:n.connection.sourcePoint.pcb_port_id}:{}})),s=x8({connectionName:n.connection.connection.name,sourcePointIndex:n.connection.sourcePointIndex});return{busId:n.bus.busId,connectionName:n.connection.connection.name,connectionIndex:n.connection.connectionIndex,sourcePointIndex:n.connection.sourcePointIndex,sourcePoint:n.connection.sourcePoint,sourceObstacle:n.connection.sourceObstacle,sourceLayer:n.connection.sourceLayer,targetPoint:n.connection.targetPoint,targetLayer:\"top\",termination:n.bus.termination,direction:n.bus.direction,exitPoint:o.at(-1),trace:{type:\"pcb_trace\",pcb_trace_id:s.traceId,connection_name:n.connection.connection.name,connectsTo:[...n.connection.sourcePoint.pointId?[n.connection.sourcePoint.pointId]:[],...n.connection.sourcePoint.pcb_port_id?[n.connection.sourcePoint.pcb_port_id]:[],s.boundaryExitPointId],route:r},segments:i,length:i.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}(t,i));if(!function(t){const{plans:e,items:n,obstacles:o,traceWidth:i,clearance:r}=t,s=new Map(n.map(t=\u003e[t.connection.connection.name,t.netKey])),a=new Map,c=new Map;for(const t of e){const e=s.get(t.connectionName),n=a.get(e)??[],o=c.get(e)??new Set;for(const e of t.segments){const t=[e.start,e.end].map(t=\u003e`${t.x.toFixed(6)}:${t.y.toFixed(6)}`).sort().join(\":\");o.has(t)||(o.add(t),n.push(e))}a.set(e,n),c.set(e,o)}const l=i/2+r;for(const[t,e]of a)for(const n of e)for(const e of o)if(!(e.connectedTo.includes(t)||A8(n,e)\u003e=l-utt))return ptt\u0026\u0026console.error(\"single-layer route violates obstacle clearance\",{netKey:t,segment:n,obstacleId:e.obstacleId,distance:A8(n,e),requiredObstacleDistance:l}),!1;const d=i+r,h=[...a];for(let t=0;t\u003ch.length;t++)for(let e=t+1;e\u003ch.length;e++)for(const n of h[t][1])for(const o of h[e][1])if(T8(n.start,n.end,o.start,o.end)\u003cd-utt)return ptt\u0026\u0026console.error(\"single-layer routes violate copper clearance\",{firstNetKey:h[t][0],secondNetKey:h[e][0],first:n,second:o,distance:T8(n.start,n.end,o.start,o.end),requiredRouteDistance:d}),!1;return!0}({plans:p,items:e,obstacles:o,traceWidth:i,clearance:r}))return ptt\u0026\u0026console.error(\"single-layer adaptive exits failed exact clearance\"),null;for(const t of p){const o=Ctt(t.exitPoint,n.boundary);if(!o||a\u0026\u0026!a.has(o))return null;const i=e.find(e=\u003ee.connection.connection.name===t.connectionName);i.bus.direction=o;const r=s?.filter(t=\u003et.direction===o),c=\"up\"===o||\"down\"===o?t.exitPoint.x:t.exitPoint.y;i.bus.preferredExit=r?.toSorted((t,e)=\u003eMath.abs(c-D7(t,n.boundary))-Math.abs(c-D7(e,n.boundary)))[0]?.preferredExit??(\"up\"===o?\"top\":\"down\"===o?\"bottom\":o),t.direction=o}const m=new Map(p.map(t=\u003e[t.connectionName,t]));return e.map(t=\u003em.get(t.connection.connection.name))}function Mtt(t){const{srj:e,buses:n,traceWidth:o,clearance:i,availableBoundaryRegions:r}=t;if(n.some(t=\u003e1!==t.connections.length))return null;const s=n.flatMap(t=\u003et.connections.map(e=\u003e({bus:t,connection:e,source:{x:e.sourcePoint.x,y:e.sourcePoint.y},netKey:mtt(e)}))),a=e.obstacles.filter(t=\u003et.layers.includes(\"top\")),c=n[0]?.sharedBoundary;if(!c)return[];const l=function(t){const{boundary:e,obstacles:n,traceWidth:o,clearance:i}=t,r=o+i,s=Math.round((e.maxX-e.minX)/r)+1,a=Math.round((e.maxY-e.minY)/r)+1,c=s*a,l=Array.from({length:c},(t,n)=\u003e({x:e.minX+n%s*r,y:e.minY+Math.floor(n/s)*r})),d=o/2+i,h=new Map;for(let t=0;t\u003cn.length;t++){const e=n[t],o=Math.floor((e.center.x-e.width/2-d)/1),i=Math.floor((e.center.x+e.width/2+d)/1),r=Math.floor((e.center.y-e.height/2-d)/1),s=Math.floor((e.center.y+e.height/2+d)/1);for(let e=o;e\u003c=i;e++)for(let n=r;n\u003c=s;n++){const o=`${e}:${n}`,i=h.get(o)??[];i.push(t),h.set(o,i)}}const u=(t,e=t)=\u003e{const o=Math.floor(Math.min(t.x,e.x)/1),i=Math.floor(Math.max(t.x,e.x)/1),r=Math.floor(Math.min(t.y,e.y)/1),s=Math.floor(Math.max(t.y,e.y)/1),a=new Set;for(let t=o;t\u003c=i;t++)for(let e=r;e\u003c=s;e++)for(const n of h.get(`${t}:${e}`)??[])a.add(n);return[...a].map(t=\u003en[t])},p=new Uint8Array(c);for(let t=0;t\u003cc;t++){const e=l[t];u(e).every(t=\u003eE8(e,t)\u003e=d-utt)\u0026\u0026(p[t]=1)}const m=Array.from({length:c},()=\u003e[]);for(let t=0;t\u003cc;t++){if(!p[t])continue;const e=t%s,n=Math.floor(t/s);for(const[i,r]of[[1,0],[0,1]]){const c=e+i,h=n+r;if(c\u003e=s||h\u003e=a)continue;const g=h*s+c;if(!p[g])continue;const f={start:l[t],end:l[g],width:o,layer:\"top\"};u(f.start,f.end).some(t=\u003eA8(f,t)\u003cd-utt)||(m[t].push(g),m[g].push(t))}}return{boundary:e,step:r,columnCount:s,rowCount:a,nodeCount:c,points:l,obstacleFreeNodes:p,neighbors:m}}({boundary:c,obstacles:a,traceWidth:o,clearance:i});ptt\u0026\u0026console.error(\"single-layer adaptive-exit grid ready\",{nodeCount:l.nodeCount});const d=Ptt({items:s,grid:l,obstacles:a,traceWidth:o,clearance:i,availableBoundaryRegions:r});return d||null}function Ntt(t){return\"left\"===t||\"right\"===t}function wtt(t){return\"right\"===t||\"up\"===t?1:-1}function Ttt(t,e){return Ntt(e)?t.x:t.y}function Rtt(t,e){return Ntt(e)?t.y:t.x}function Ett(t,e,n){return Ntt(n)?{x:t,y:e}:{x:e,y:t}}function Att(t){switch(t.direction){case\"right\":return t.sharedBoundary.maxX;case\"left\":return t.sharedBoundary.minX;case\"up\":return t.sharedBoundary.maxY;case\"down\":return t.sharedBoundary.minY}}function Ott(t){if(t.length\u003c3)return t;const e=[t[0]];for(let n=1;n\u003ct.length-1;n++){const o=e.at(-1),i=t[n],r=t[n+1],s={x:Math.sign(i.x-o.x),y:Math.sign(i.y-o.y)},a={x:Math.sign(r.x-i.x),y:Math.sign(r.y-i.y)};s.x===a.x\u0026\u0026s.y===a.y||e.push(i)}return e.push(t.at(-1)),e}function ktt(t,e){const n=[];for(let o=1;o\u003ct.length;o++)M8(t[o-1],t[o])\u003c1e-9||n.push({start:t[o-1],end:t[o],width:e,layer:\"top\"});return n}function Ltt(t){const{item:e,srj:n,acceptedSegments:o,traceWidth:i,clearance:r}=t,s=e.cornerChannelPrefixes;if(!s)return null;const a=e.direction,c=wtt(a),l=Att(e.bus),d=i+r,h=i/2+r,u=Ntt(a)?e.bus.sharedBoundary.minY:e.bus.sharedBoundary.minX,p=Ntt(a)?e.bus.sharedBoundary.maxY:e.bus.sharedBoundary.maxX,m=u+i/2,g=p-i/2,f=Rtt(e.connection.exitTargetPoint??e.connection.targetPoint,a),y=d/2,_=new Set([Math.max(m,Math.min(g,f))]);for(let t=Math.ceil(m/y)*y;t\u003c=g+1e-9;t+=y)_.add(Number(t.toFixed(9)));const b=[..._].toSorted((t,e)=\u003eMath.abs(t-f)-Math.abs(e-f));for(const t of s){const s=t.at(-1),u=Rtt(s,a);for(const p of b){const m=Math.abs(p-u),g=Ett(Ttt(s,a)+c*d,u,a),f=Ett(Ttt(g,a)+c*m,p,a);if(c*(l-Ttt(f,a))\u003c-1e-9)continue;const y=Ett(l,p,a),_=[...t,g,...m\u003e1e-9?[f]:[]];M8(_.at(-1),y)\u003e1e-9\u0026\u0026_.push(y);const b=Ott(_),x=ktt(b,i);if(!x.every(t=\u003en.obstacles.every(n=\u003en===e.connection.sourceObstacle||!n.layers.includes(\"top\")||A8(t,n)\u003e=h-1e-9)))continue;if(x.every(t=\u003eo.every(e=\u003eT8(t.start,t.end,e.start,e.end)\u003e=i+r-1e-9)))return{item:e,points:b,track:p}}}return null}function Dtt(t){const{route:e,direction:n,exitAxis:o,signedShift:i,maximumShift:r,obstacles:s,requiredObstacleDistance:a}=t;if(r\u003c=1e-9||Math.abs(i)\u003c=1e-9)return 0;const c=Math.sign(i),l=t=\u003e{if(t\u003c=1e-9)return!0;const i={start:Ett(o-wtt(n)*t,e.track,n),end:Ett(o,e.track+c*t,n),width:0,layer:\"top\"};return s.every(t=\u003et===e.item.connection.sourceObstacle||!t.layers.includes(\"top\")||A8(i,t)\u003e=a-1e-9)};if(l(r))return r;let d=0,h=r;for(let t=0;t\u003c32;t++){const t=(d+h)/2;l(t)?d=t:h=t}return d}function ztt(t){const{requestedTracks:e,currentTracks:n,candidateTracks:o,maximumShifts:i}=t,r=e.length+1,s=o.length+1,a=Array.from({length:r},()=\u003enew Float64Array(s).fill(Number.POSITIVE_INFINITY)),c=Array.from({length:r},()=\u003enew Uint8Array(s));a[0].fill(0);for(let t=1;t\u003cr;t++)for(let r=1;r\u003cs;r++){const s=a[t][r-1],l=Math.abs(e[t-1]-o[r-1]),d=Math.abs(n[t-1]-o[r-1])\u003ei[t-1]+1e-9?Number.POSITIVE_INFINITY:a[t-1][r-1]+l;d\u003cs?(a[t][r]=d,c[t][r]=1):a[t][r]=s}if(!Number.isFinite(a.at(-1).at(-1)))return null;const l=[];let d=e.length,h=o.length;for(;d\u003e0\u0026\u0026h\u003e0;)c[d][h]\u0026\u0026(l.push(o[h-1]),d--),h--;return d\u003e0?null:l.reverse()}function Ftt(t){const{direction:e,activeRoutes:n,obstacles:o,boundaryMinimum:i,boundaryMaximum:r,traceWidth:s,clearance:a,requestedTracks:c,maximumShifts:l}=t,d=s+a,h=s/2+a;let u=null,p=Number.POSITIVE_INFINITY;for(const t of Array.from({length:Math.round(d/s)},(t,e)=\u003ee*s)){const a=[];for(let n=Math.ceil((i-t)/d)*d+t;n\u003c=r+1e-9;n+=d){const t=Math.round(n/s)*s;o.every(n=\u003e{const o=Rtt(n.center,e),i=Ntt(e)?n.height:n.width;return Math.abs(t-o)\u003e=i/2+h-1e-9})\u0026\u0026a.push(t)}const m=ztt({requestedTracks:c,currentTracks:n.map(t=\u003et.track),candidateTracks:a,maximumShifts:l});if(!m)continue;const g=m.reduce((t,e,n)=\u003et+Math.abs(e-c[n]),0);g\u003cp\u0026\u0026(p=g,u=m)}return u}function Btt(t,e){switch(e){case\"up\":return\"top-left\"===t?\"minimum\":\"top-right\"===t?\"maximum\":null;case\"down\":return\"bottom-left\"===t?\"minimum\":\"bottom-right\"===t?\"maximum\":null;case\"left\":return\"bottom-left\"===t?\"minimum\":\"top-left\"===t?\"maximum\":null;case\"right\":return\"bottom-right\"===t?\"minimum\":\"top-right\"===t?\"maximum\":null}}function jtt(t){const{items:e,direction:n,boundaryMinimum:o,boundaryMaximum:i,traceWidth:r,clearance:s,borderDistribution:a,currentTrackByConnectionName:c}=t,l=t=\u003ec.get(t.connection.connection.name)??Rtt(t.source,n),d=[...e].toSorted((t,e)=\u003el(t)-l(e)||t.connection.connection.name.localeCompare(e.connection.connection.name)),h=r+s,u=o+r/2,p=i-r/2;if(p-u\u003ch*Math.max(d.length-1,0)-1e-9)return null;const m=d.map(l);let g=[...m],f=h;const y=new Set;if(\"even\"===a\u0026\u0026d.length\u003e1){const t=m[0],e=m.at(-1),n=Math.max(h,(e-t)/(d.length-1)),o=t=\u003e{const e=[...m],n=Math.floor(d.length/2),o=d.length%2==0?n-1:n;if(o!==n){const i=e[n]-e[o];if(i\u003ct){const r=(t-i)/2;e[o]=e[o]-r,e[n]=e[n]+r}}for(let n=o-1;n\u003e=0;n--)e[n]=Math.min(e[n],e[n+1]-t);for(let o=n+1;o\u003ce.length;o++)e[o]=Math.max(e[o],e[o-1]+t);return e},i=t=\u003et[0]\u003e=u-1e-9\u0026\u0026t.at(-1)\u003c=p+1e-9;if(g=o(n),i(g))f=n;else{let t=h,e=n;if(g=o(t),!i(g))return null;for(let n=0;n\u003c32;n++){const n=(t+e)/2,r=o(n);i(r)?(t=n,g=r):e=n}f=t}for(const t of d)y.add(t.connection.connection.name)}const _=[],b=[];for(let t=0;t\u003cd.length;t++){const e=d[t],o=e.bus.preferredExit;if(!o?.includes(\"-\"))continue;const i=Btt(o,n);if(!i)return null;y.add(e.connection.connection.name),\"minimum\"===i?_.push(t):b.push(t)}if(_.some((t,e)=\u003et!==e)||b.some((t,e)=\u003et!==d.length-b.length+e))return null;const x=2*h;if(_.length\u003e0){g[0]=u+x;for(let t=1;t\u003c_.length;t++){const e=Math.max(f,m[t]-m[t-1]);g[t]=g[t-1]+e}}if(b.length\u003e0){const t=d.length-1;g[t]=p-x;for(let e=t-1;e\u003e=d.length-b.length;e--){const t=Math.max(f,m[e+1]-m[e]);g[e]=g[e+1]-t}}return{byConnectionName:new Map(d.map((t,e)=\u003e[t.connection.connection.name,g[e]])),enforcedConnectionNames:y}}function $tt(t){const{item:e,points:n,segments:o}=t,i=n.map((t,n)=\u003e({route_type:\"wire\",x:t.x,y:t.y,width:o[0]?.width??.1,layer:\"top\",...0===n\u0026\u0026e.connection.sourcePoint.pcb_port_id?{start_pcb_port_id:e.connection.sourcePoint.pcb_port_id}:{}})),r=x8({connectionName:e.connection.connection.name,sourcePointIndex:e.connection.sourcePointIndex});return{busId:e.bus.busId,connectionName:e.connection.connection.name,connectionIndex:e.connection.connectionIndex,sourcePointIndex:e.connection.sourcePointIndex,sourcePoint:e.connection.sourcePoint,sourceObstacle:e.connection.sourceObstacle,sourceLayer:e.connection.sourceLayer,targetPoint:e.connection.targetPoint,targetLayer:\"top\",termination:e.bus.termination,direction:e.direction,exitPoint:n.at(-1),trace:{type:\"pcb_trace\",pcb_trace_id:r.traceId,connection_name:e.connection.connection.name,connectsTo:[...e.connection.sourcePoint.pointId?[e.connection.sourcePoint.pointId]:[],...e.connection.sourcePoint.pcb_port_id?[e.connection.sourcePoint.pcb_port_id]:[],r.boundaryExitPointId],route:i},segments:o,length:o.reduce((t,e)=\u003et+M8(e.start,e.end),0)}}function Ytt(t){const{srj:e,buses:n,traceWidth:o,clearance:i,borderDistribution:r}=t,s=o/2+i,a=new Map,c=new Map,l=n.flatMap(t=\u003et.connections.map(n=\u003e{const r={x:n.sourcePoint.x,y:n.sourcePoint.y},s=function(t){const{srj:e,bus:n,connection:o,traceWidth:i,clearance:r}=t,s=n.direction,a=wtt(s),c={x:o.sourcePoint.x,y:o.sourcePoint.y},l=Ttt(c,s),d=Rtt(c,s),h=i/2+r,u=(()=\u003e{switch(s){case\"right\":return n.componentBounds.maxX+h;case\"left\":return n.componentBounds.minX-h;case\"up\":return n.componentBounds.maxY+h;case\"down\":return n.componentBounds.minY-h}})(),p=t=\u003eMath.min(...e.obstacles.filter(t=\u003et!==o.sourceObstacle\u0026\u0026t.layers.includes(\"top\")).map(e=\u003eA8(t,e))),m={start:c,end:Ett(u,d,s),width:i,layer:\"top\"};if(p(m)\u003e=h-1e-9)return null;const g=Ntt(s)?{minimum:n.componentBounds.minY,maximum:n.componentBounds.maxY}:{minimum:n.componentBounds.minX,maximum:n.componentBounds.maxX},f=a*(u-l),y=Rtt(o.exitTargetPoint??o.targetPoint,s),_=i+r,b=Att(n),x=[-1,1].map(t=\u003e{const e=t*((t\u003c0?g.minimum-h:g.maximum+h)-d),o=Math.max(f,e),r=Ett(l+a*o,d+t*o,s);if(a*(b-Ttt(r,s))\u003c_-1e-9)return null;const u=[c,r];if(!u.every(t=\u003et.x\u003e=n.sharedBoundary.minX-1e-9\u0026\u0026t.x\u003c=n.sharedBoundary.maxX+1e-9\u0026\u0026t.y\u003e=n.sharedBoundary.minY-1e-9\u0026\u0026t.y\u003c=n.sharedBoundary.maxY+1e-9))return null;const m=Math.min(...ktt(u,i).map(p));return m\u003ch-1e-9?null:{points:u,obstacleDistance:m,targetDistance:Math.abs(Rtt(r,s)-y)}}).filter(t=\u003enull!==t).toSorted((t,e)=\u003ee.obstacleDistance-t.obstacleDistance||t.targetDistance-e.targetDistance);return x.length\u003e0?x.map(t=\u003et.points):null}({srj:e,bus:t,connection:n,traceWidth:o,clearance:i});return{bus:t,connection:n,direction:t.direction,source:r,...s?{cornerChannelPrefixes:s}:{}}}));for(const t of[\"left\",\"right\",\"up\",\"down\"]){const n=wtt(t),d=l.filter(e=\u003ee.direction===t\u0026\u0026!e.cornerChannelPrefixes);if(0===d.length)continue;const h=Ntt(t)?d[0].bus.sharedBoundary.minY:d[0].bus.sharedBoundary.minX,u=Ntt(t)?d[0].bus.sharedBoundary.maxY:d[0].bus.sharedBoundary.maxX,p=Att(d[0].bus),m=new Map,g=new Map,f=new Map;for(const e of d){const n=Ttt(e.source,t),o=n.toFixed(6);f.set(o,n);const i=m.get(o)??[];i.push(e),m.set(o,i)}for(const[n,o]of m){const i=f.get(n),r=new Set(o.map(t=\u003et.bus.componentId));g.set(n,e.obstacles.filter(e=\u003ee.layers.includes(\"top\")\u0026\u0026!!e.componentId\u0026\u0026r.has(e.componentId)\u0026\u0026Math.abs(Ttt(e.center,t)-i)\u003c1e-6))}const y=[...f.values()].toSorted((t,e)=\u003en*(t-e)),_=new Map;for(let e=0;e\u003cy.length;e++){const r=y[e],a=r.toFixed(6);for(const e of m.get(a)??[]){const o=Ntt(t)?e.connection.sourceObstacle.width:e.connection.sourceObstacle.height,i=Math.max(e.connection.sourceObstacle.width,e.connection.sourceObstacle.height)\u003c1.5?o/2+s:0,a=Ett(r+n*i,Rtt(e.source,t),t);_.set(e.connection.connection.name,{item:e,points:M8(e.source,a)\u003e1e-9?[e.source,a]:[e.source],track:Rtt(e.source,t)})}const c=y[e+1]??p;if(0===_.size||n*(c-r)\u003c=1e-9)continue;const l=[..._.values()].toSorted((t,e)=\u003et.track-e.track||t.item.connection.connection.name.localeCompare(e.item.connection.connection.name)),d=y.slice(e+1,e+3).flatMap(t=\u003eg.get(t.toFixed(6))??[]),f=l.map(e=\u003eMath.abs(c-Ttt(e.points.at(-1),t))),b=Ftt({direction:t,activeRoutes:l,obstacles:d,boundaryMinimum:h,boundaryMaximum:u,traceWidth:o,clearance:i,requestedTracks:l.map(t=\u003et.track),maximumShifts:f});if(!b)return null;for(let e=0;e\u003cl.length;e++){const o=l[e],i=b[e],r=Math.abs(i-o.track),s=Ett(Ttt(o.points.at(-1),t)+n*r,i,t);M8(o.points.at(-1),s)\u003e1e-9\u0026\u0026o.points.push(s);const a=Ett(c,i,t);M8(o.points.at(-1),a)\u003e1e-9\u0026\u0026o.points.push(a),o.track=i}}const b=jtt({items:d,direction:t,boundaryMinimum:h,boundaryMaximum:u,traceWidth:o,clearance:i,borderDistribution:r,currentTrackByConnectionName:new Map([..._.values()].map(t=\u003e[t.item.connection.connection.name,t.track]))});if(!b)return null;const x=[..._.values()].toSorted((t,e)=\u003et.track-e.track||t.item.connection.connection.name.localeCompare(e.item.connection.connection.name)),v=new Map,S=o+i;let I=S;for(const t of x){const e=t.item.connection.connection.name;if(!b.enforcedConnectionNames.has(e))continue;b.byConnectionName.get(e)-t.track\u003e=-1e-9||(v.set(e,I),I+=2*S)}let C=S;for(let t=x.length-1;t\u003e=0;t--){const e=x[t],n=e.item.connection.connection.name;if(!b.enforcedConnectionNames.has(n))continue;b.byConnectionName.get(n)-e.track\u003c=1e-9||(v.set(n,C),C+=2*S)}for(const o of x){const i=o.item.connection.connection.name,r=b.byConnectionName.get(i)??o.track,a=v.get(i)??0,c=o.points.at(-2),l=c?n*(p-Ttt(c,t)):0,d=r-o.track,h=Math.min(Math.abs(d),Math.max(0,l-a)),u=Dtt({route:o,direction:t,exitAxis:p,signedShift:d,maximumShift:h,obstacles:e.obstacles,requiredObstacleDistance:s}),m=Math.sign(d)*u;b.byConnectionName.set(i,o.track+m)}for(const t of b.enforcedConnectionNames)c.set(t,b.byConnectionName.get(t));for(const e of x){const o=e.item.connection.connection.name,i=b.byConnectionName.get(o)??e.track,r=Math.abs(i-e.track),s=v.get(o)??0,a=p-n*(r\u003e1e-9?s+r:0),c=e.points.at(-1);if(Math.abs(Ttt(c,t)-p)\u003e1e-6)return null;const l=e.points.at(-2);if(l\u0026\u0026(Math.abs(Rtt(l,t)-e.track)\u003e1e-6||n*(a-Ttt(l,t))\u003c-1e-6))return null;const d=Ett(a,e.track,t);l\u0026\u0026M8(l,d)\u003c1e-9?e.points.pop():e.points[e.points.length-1]=d}for(const e of x){const o=e.item.connection.connection.name,i=b.byConnectionName.get(o)??e.track,r=Math.abs(i-e.track),s=v.get(o)??0;r\u003e1e-9\u0026\u0026s\u003e1e-9\u0026\u0026e.points.push(Ett(Ttt(e.points.at(-1),t)+n*s,e.track,t)),r\u003e1e-9\u0026\u0026(e.points.push(Ett(Ttt(e.points.at(-1),t)+n*r,i,t)),e.track=i);const c=Ett(p,e.track,t);if(M8(e.points.at(-1),c)\u003e1e-9){if(n*(p-Ttt(e.points.at(-1),t))\u003c-1e-6)return null;e.points.push(c)}a.set(o,e)}}const d=[...a.values()].flatMap(t=\u003ektt(Ott(t.points),o));for(const t of l){if(!t.cornerChannelPrefixes)continue;const n=Ltt({item:t,srj:e,acceptedSegments:d,traceWidth:o,clearance:i});if(!n)return null;a.set(t.connection.connection.name,n),d.push(...ktt(Ott(n.points),o))}if(a.size!==l.length)return null;const h=(o+i)/2+1e-6;for(const[t,e]of c){const n=a.get(t);if(!n||Math.abs(n.track-e)\u003eh)return null}const u=l.map(t=\u003e{const e=Ott(a.get(t.connection.connection.name).points);return{item:t,points:e,segments:ktt(e,o)}});return function(t){const{paths:e,obstacles:n,traceWidth:o,clearance:i}=t,r=o/2+i,s=o+i;for(const t of e){if(Math.abs(Ttt(t.points.at(-1),t.item.direction)-Att(t.item.bus))\u003e1e-6)return!1;for(const e of t.segments)for(const o of n)if(o!==t.item.connection.sourceObstacle\u0026\u0026o.layers.includes(\"top\")\u0026\u0026A8(e,o)\u003cr-1e-9)return!1}for(let t=0;t\u003ce.length;t++)for(let n=t+1;n\u003ce.length;n++)for(const o of e[t].segments)for(const t of e[n].segments)if(T8(o.start,o.end,t.start,t.end)\u003cs-1e-9)return!1;return!0}({paths:u,obstacles:e.obstacles,traceWidth:o,clearance:i})?u.map($tt):null}var Xtt=1e-6;function Vtt(t,e){return M8(t,e)\u003c=Xtt}function Wtt(t){return\"layer\"in t?[t.layer]:t.layers}function Htt(t){return[...t.segments,...t.planeEndpointSegments??[]]}function Gtt(t){return[t.via,t.planeEndpointVia].filter(t=\u003eBoolean(t))}function Utt(t,e){return Vtt(t,e)\u0026\u0026Wtt(t).join(\"\\0\")===Wtt(e).join(\"\\0\")\u0026\u0026t.pointId===e.pointId\u0026\u0026t.pcb_port_id===e.pcb_port_id}function Ztt(t,e){const n=t.x\u003e=e.minX-Xtt\u0026\u0026t.x\u003c=e.maxX+Xtt\u0026\u0026t.y\u003e=e.minY-Xtt\u0026\u0026t.y\u003c=e.maxY+Xtt,o=Math.abs(t.x-e.minX)\u003c=Xtt||Math.abs(t.x-e.maxX)\u003c=Xtt||Math.abs(t.y-e.minY)\u003c=Xtt||Math.abs(t.y-e.maxY)\u003c=Xtt;return n\u0026\u0026o}function qtt(t,e){return t.x\u003e=e.minX-Xtt\u0026\u0026t.x\u003c=e.maxX+Xtt\u0026\u0026t.y\u003e=e.minY-Xtt\u0026\u0026t.y\u003c=e.maxY+Xtt}function Jtt(t,e,n,o,i){t.push({code:e,message:n,...o?{connectionName:o.connectionName,busId:o.busId}:{},...i?{otherConnectionName:i}:{}})}function Ktt(t){const{trace:e,plan:n,issues:o}=t,i=[];let r,s;for(const t of e.route)\"via\"!==t.route_type?\"wire\"===t.route_type?s?(Vtt(t,s)\u0026\u0026t.layer===s.to_layer||Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} does not continue from its via on ${s.to_layer}`,n),r=t,s=void 0):(r\u0026\u0026(r.layer!==t.layer?Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} changes from ${r.layer} to ${t.layer} without a via`,n):Vtt(r,t)||i.push({start:{x:r.x,y:r.y},end:{x:t.x,y:t.y},width:t.width,layer:t.layer})),r=t):Jtt(o,\"unsupported-route-point\",`Trace ${e.pcb_trace_id} contains unsupported ${t.route_type} geometry`,n):(r\u0026\u0026Vtt(r,t)\u0026\u0026r.layer===t.from_layer||Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} reaches a via without a matching ${t.from_layer} wire endpoint`,n),s=t);return s\u0026\u0026Jtt(o,\"disconnected-trace\",`Trace ${e.pcb_trace_id} ends at a via without a wire on ${s.to_layer}`,n),i}function Qtt(t){const{plan:e,preparedBus:n,inputSrj:o,outputSrj:i,sharedBoundary:r,issues:s}=t,a=o.connections[e.connectionIndex];if(!a||a.name!==e.connectionName)return void Jtt(s,\"connection-mismatch\",`Plan index ${e.connectionIndex} does not identify connection ${e.connectionName}`,e);const c=n?.connections.find(t=\u003et.connectionIndex===e.connectionIndex);if(c\u0026\u0026c.sourcePointIndex===e.sourcePointIndex\u0026\u0026Utt(c.sourcePoint,e.sourcePoint)\u0026\u0026c.sourceObstacle.obstacleId===e.sourceObstacle.obstacleId||Jtt(s,\"source-mismatch\",`Plan ${e.connectionName} does not start at its prepared component endpoint`,e),n?.termination.type!==e.termination.type\u0026\u0026Jtt(s,\"termination-mismatch\",`Plan ${e.connectionName} does not use its bus termination`,e),0===e.segments.length||e.length\u003c=Xtt)Jtt(s,\"not-broken-out\",`Plan ${e.connectionName} has no non-zero escape geometry`,e);else{const t={minX:Math.min(o.bounds.minX,r.minX),maxX:Math.max(o.bounds.maxX,r.maxX),minY:Math.min(o.bounds.minY,r.minY),maxY:Math.max(o.bounds.maxY,r.maxY)};e.segments.some(e=\u003e!qtt(e.start,t)||!qtt(e.end,t))\u0026\u0026Jtt(s,\"outside-routing-bounds\",`Plan ${e.connectionName} leaves the routable SRJ/shared-boundary area`,e),Vtt(e.segments[0].start,e.sourcePoint)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} does not start at its source pad`,e),Vtt(e.segments.at(-1).end,e.exitPoint)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} does not end at its declared exit`,e);for(let t=1;t\u003ce.segments.length;t++){const n=e.segments[t-1],o=e.segments[t];Vtt(n.end,o.start)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} has a gap between route segments`,e),n.layer===o.layer||e.via\u0026\u0026Vtt(n.end,e.via.center)\u0026\u0026e.via.spanLayers.includes(n.layer)\u0026\u0026e.via.spanLayers.includes(o.layer)||Jtt(s,\"disconnected-trace\",`Plan ${e.connectionName} changes layers without a connecting via`,e)}}const l=Ktt({trace:e.trace,plan:e,issues:s});if((l.length!==e.segments.length||l.some((t,n)=\u003e{const o=e.segments[n];return!o||t.layer!==o.layer||Math.abs(t.width-o.width)\u003eXtt||!Vtt(t.start,o.start)||!Vtt(t.end,o.end)}))\u0026\u0026Jtt(s,\"trace-plan-mismatch\",`Trace ${e.trace.pcb_trace_id} does not encode its declared route segments`,e),e.planeEndpointTrace||e.planeEndpointSegments||e.planeEndpointVia)if(e.planeEndpointTrace\u0026\u0026e.planeEndpointSegments\u0026\u0026e.planeEndpointVia){const t=Ktt({trace:e.planeEndpointTrace,plan:e,issues:s});(t.length!==e.planeEndpointSegments.length||t.some((t,n)=\u003e{const o=e.planeEndpointSegments?.[n];return!o||t.layer!==o.layer||Math.abs(t.width-o.width)\u003eXtt||!Vtt(t.start,o.start)||!Vtt(t.end,o.end)})||M8(e.planeEndpointVia.center,e.targetPoint)\u003c=Xtt)\u0026\u0026Jtt(s,\"trace-plan-mismatch\",`Trace ${e.planeEndpointTrace.pcb_trace_id} does not encode a valid offset plane-to-endpoint dogbone`,e)}else Jtt(s,\"trace-plan-mismatch\",`Plane endpoint geometry for ${e.connectionName} is incomplete`,e);const d=e.trace.route.find(t=\u003e\"x\"in t\u0026\u0026\"y\"in t),h=[...e.trace.route].reverse().find(t=\u003e\"x\"in t\u0026\u0026\"y\"in t);d\u0026\u0026h\u0026\u0026Vtt(d,e.sourcePoint)\u0026\u0026Vtt(h,e.exitPoint)||Jtt(s,\"disconnected-trace\",`Trace ${e.trace.pcb_trace_id} does not span its source and exit`,e);const u=i.connections.find(t=\u003et.name===e.connectionName);if(\"boundary\"===e.termination.type)if(u){const t=u.pointsToConnect[e.sourcePointIndex];t\u0026\u0026Vtt(t,e.exitPoint)\u0026\u0026\"layer\"in t\u0026\u0026t.layer===e.targetLayer||Jtt(s,\"output-exit-mismatch\",`Output connection ${e.connectionName} is not attached to its fanout exit`,e);for(let t=0;t\u003ca.pointsToConnect.length;t++){if(t===e.sourcePointIndex)continue;const n=a.pointsToConnect[t],o=u.pointsToConnect[t];n\u0026\u0026o\u0026\u0026Utt(n,o)||Jtt(s,\"downstream-endpoint-lost\",`Output connection ${e.connectionName} did not retain downstream endpoint ${t}`,e)}}else Jtt(s,\"output-connection-missing\",`Boundary connection ${e.connectionName} was removed from the output`,e);else u\u0026\u0026Jtt(s,\"plane-connection-retained\",`Plane-terminated connection ${e.connectionName} remains in the output`,e)}function tet(t,e){const n=Htt(t),o=Htt(e),i=Gtt(t),r=Gtt(e);for(const t of n){for(const e of o)if(t.layer===e.layer\u0026\u0026T8(t.start,t.end,e.start,e.end)\u003c=(t.width+e.width)/2+Xtt)return!0;for(const e of r)if(e.spanLayers.includes(t.layer)\u0026\u0026N8(e.center,t.start,t.end)\u003c=e.diameter/2+t.width/2+Xtt)return!0}for(const t of i){for(const e of o)if(t.spanLayers.includes(e.layer)\u0026\u0026N8(t.center,e.start,e.end)\u003c=t.diameter/2+e.width/2+Xtt)return!0;for(const e of r)if(t.spanLayers.some(t=\u003ee.spanLayers.includes(t))\u0026\u0026M8(t.center,e.center)\u003c=(t.diameter+e.diameter)/2+Xtt)return!0}return!1}function eet(t){const{inputSrj:e,outputSrj:n,plans:o,preparedBuses:i,sharedBoundary:r,clearance:s}=t,a=[],c=new Map,l=new Map(i.map(t=\u003e[t.busId,t]));for(const t of o){const e=c.get(t.connectionName)??[];e.push(t),c.set(t.connectionName,e)}for(const t of e.connections){const e=c.get(t.name)??[];0===e.length?Jtt(a,\"missing-plan\",`Connection ${t.name} has no fanout plan`):e.length\u003e1\u0026\u0026Jtt(a,\"duplicate-plan\",`Connection ${t.name} has ${e.length} fanout plans`,e[0])}for(const t of o)e.connections.some(e=\u003ee.name===t.connectionName)?Qtt({plan:t,preparedBus:l.get(t.busId),inputSrj:e,outputSrj:n,sharedBoundary:r,issues:a}):Jtt(a,\"unknown-plan\",`Plan ${t.connectionName} is not an input connection`,t);const d=function(t){const{plans:e,inputSrj:n,sharedBoundary:o,issues:i}=t,r=new Set,s=new Map;for(const t of e)s.set(t,[]);for(let t=0;t\u003ce.length;t++){const i=e[t];(\"plane\"===i.termination.type?Boolean(i.via):i.segments.some(t=\u003eZtt(t.start,o)||Ztt(t.end,o)))\u0026\u0026r.add(i);for(let o=t+1;o\u003ce.length;o++){const t=e[o];$8(n,i.connectionName,t.connectionName)\u0026\u0026tet(i,t)\u0026\u0026(s.get(i).push(t),s.get(t).push(i))}}const a=[...r];for(;a.length\u003e0;){const t=a.shift();for(const e of s.get(t)??[])r.has(e)||(r.add(e),a.push(e))}for(const t of e)r.has(t)||Jtt(i,\"not-broken-out\",\"boundary\"===t.termination.type?`Connection ${t.connectionName} has no continuous same-net copper path to the shared boundary`:`Plane connection ${t.connectionName} has no terminating via`,t);return r}({plans:o,inputSrj:e,sharedBoundary:r,issues:a});return function(t){const{plans:e,inputSrj:n,clearance:o,issues:i}=t;for(const t of e){const e=Htt(t);for(let r=0;r\u003ce.length;r++){const s=e[r];for(const e of n.obstacles){if(!e.layers.includes(s.layer))continue;if(Y8(n,e,t.connectionName))continue;if(0===r\u0026\u0026e.obstacleId===t.sourceObstacle.obstacleId\u0026\u0026s.layer===t.sourceLayer)continue;if(K8({inputSrj:n,segment:s,bodyObstacle:e,connectionName:t.connectionName}))continue;const a=A8(s,e),c=s.width/2+o;a\u003cc-1e-9\u0026\u0026Jtt(i,\"obstacle-clearance\",`Trace ${t.connectionName} on ${s.layer} is ${a.toFixed(4)}mm from different-net obstacle ${e.obstacleId}; ${c.toFixed(4)}mm is required`,t)}}for(const e of Gtt(t))for(const r of n.obstacles){if(!r.layers.some(t=\u003ee.spanLayers.includes(t))||Y8(n,r,t.connectionName))continue;const s=E8(e.center,r),a=e.diameter/2+o;s\u003ca-1e-9\u0026\u0026Jtt(i,\"via-obstacle-clearance\",`Via ${t.connectionName} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId} on its layer span; ${a.toFixed(4)}mm is required`,t)}}for(let t=0;t\u003ce.length;t++){const r=e[t];for(let s=t+1;s\u003ce.length;s++){const t=e[s];if($8(n,r.connectionName,t.connectionName))continue;const a=Htt(r),c=Htt(t),l=Gtt(r),d=Gtt(t);for(const e of a){for(const n of c)O8(e,n,o)||Jtt(i,\"different-net-trace-clearance\",`Different-net traces ${r.connectionName} and ${t.connectionName} intersect or violate clearance on ${e.layer}`,r,t.connectionName);for(const n of d)n.spanLayers.includes(e.layer)\u0026\u0026N8(n.center,e.start,e.end)\u003cn.diameter/2+e.width/2+o-1e-9\u0026\u0026Jtt(i,\"different-net-trace-via-clearance\",`Trace ${r.connectionName} violates via clearance to ${t.connectionName} on ${e.layer}`,r,t.connectionName)}for(const e of l){for(const n of c)e.spanLayers.includes(n.layer)\u0026\u0026N8(e.center,n.start,n.end)\u003ce.diameter/2+n.width/2+o-1e-9\u0026\u0026Jtt(i,\"different-net-trace-via-clearance\",`Via ${r.connectionName} violates trace clearance to ${t.connectionName} on ${n.layer}`,r,t.connectionName);for(const n of d)e.spanLayers.some(t=\u003en.spanLayers.includes(t))\u0026\u0026M8(e.center,n.center)\u003c(e.diameter+n.diameter)/2+o-1e-9\u0026\u0026Jtt(i,\"different-net-via-clearance\",`Vias ${r.connectionName} and ${t.connectionName} violate clearance on an overlapping layer span`,r,t.connectionName)}}}}({plans:o,inputSrj:e,clearance:s,issues:a}),{valid:0===a.length,checkedConnectionCount:e.connections.length,brokenOutConnectionCount:new Set([...d].map(t=\u003et.connectionName)).size,issues:a}}var net=[\"#ef4444\",\"#2563eb\",\"#16a34a\",\"#9333ea\",\"#f59e0b\",\"#0891b2\",\"#db2777\",\"#65a30d\",\"#4f46e5\",\"#ea580c\"];function oet(t){if(!Number.isInteger(t)||t\u003c0)throw new Error(`FanoutSolver: copper layer index must be a non-negative integer, received ${t}`);return net[t%net.length]}var iet=new Set([\"top\",\"bottom\",\"inner1\",\"inner2\",\"inner3\",\"inner4\",\"inner5\",\"inner6\",\"inner7\",\"inner8\"]),ret={\"0603\":{padLength:.8,padWidth:.95},1206:{padLength:.6,padWidth:1.6},\"1206x4_pair\":{padLength:.8,padWidth:.5}},set=(t,e)=\u003e{const n=t.indexOf(e);if(n\u003c0)throw new Error(`FanoutSolver: cannot visualize unknown copper layer \"${e}\"`);return n},aet=(t,e)=\u003e`z${[...new Set(e.map(e=\u003eset(t,e)))].sort((t,e)=\u003et-e).join(\",\")}`,cet=t=\u003e{const e=\"layers\"in t?t.layers:void 0;return e\u0026\u0026e.length\u003e0?e:[t.layer]},det=(t,e)=\u003et.__zLayers\u0026\u0026t.__zLayers.length\u003e0?[...new Set(t.__zLayers)].filter(t=\u003eNumber.isInteger(t)\u0026\u0026t\u003e=0\u0026\u0026t\u003ce.length).sort((t,e)=\u003et-e):[...new Set(t.layers.map(t=\u003eset(e,t)))].sort((t,e)=\u003et-e),het=(t,e,n)=\u003e{const o=set(t,e),i=set(t,n);return t.slice(Math.min(o,i),Math.max(o,i)+1)},uet=(...t)=\u003et.find(t=\u003e\"number\"==typeof t\u0026\u0026Number.isFinite(t)),pet=t=\u003e{const e=uet(t.min_via_hole_diameter,t.minViaHoleDiameter),n=uet(t.min_via_pad_diameter,t.minViaPadDiameter,t.minViaDiameter);return Math.max(n??t.minViaDiameter??.3,e??0)},met=(t,e)=\u003e{let n={blue:[0,0,255],orange:[255,165,0],purple:[128,0,128],red:[255,0,0]}[t],o=1;const i=/^rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)$/.exec(t);i\u0026\u0026(n=[Number(i[1]),Number(i[2]),Number(i[3])],o=void 0===i[4]?1:Number(i[4]));const r=/^hsl\\(\\s*([\\d.-]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%\\s*\\)$/.exec(t);if(r\u0026\u0026(n=((t,e,n)=\u003e{const o=(1-Math.abs(2*n-1))*e,i=(t%360+360)%360/60,r=o*(1-Math.abs(i%2-1)),[s,a,c]=i\u003c1?[o,r,0]:i\u003c2?[r,o,0]:i\u003c3?[0,o,r]:i\u003c4?[0,r,o]:i\u003c5?[r,0,o]:[o,0,r],l=n-o/2;return[s,a,c].map(t=\u003eMath.round(255*(t+l)))})(Number(r[1]),Number(r[2])/100,Number(r[3])/100)),!n)return t;const s=+Math.max(0,100*o-100*e).toFixed(2)/100;if(s\u003e=1){const t=n.map(t=\u003eMath.round(t).toString(16).padStart(2,\"0\")).join(\"\");return t[0]===t[1]\u0026\u0026t[2]===t[3]\u0026\u0026t[4]===t[5]?`#${t[0]}${t[2]}${t[4]}`:`#${t}`}return`rgba(${n.join(\",\")},${s})`},get=t=\u003e{const e=new Map,n=(t,n)=\u003e{if(!t)return;const o=e.get(t)??[];o.includes(n)||o.push(n),e.set(t,o)};for(const e of t.connections){const t=e.__rootConnectionNames??[e.name];for(const o of t){n(e.name,o),n(o,o),n(e.__netConnectionName,o);for(const t of e.pointsToConnect)n(t.pointId,o),n(t.pcb_port_id,o)}}return t=\u003e{const n=(t=\u003e{const e=new Set;return t.filter(t=\u003e!e.has(t)\u0026\u0026(e.add(t),!0))})([...t.connectedTo.flatMap(t=\u003ee.get(t)??[]),...(t.offBoardConnectsTo??[]).flatMap(t=\u003ee.get(t)??[])]).join(\", \");return t.layers.map(t=\u003en?`${t}\\n${n}`:t).join(\"\\n\")}};function fet(t){const e=k8(t.layerCount),n=(t.traces??[]).some(t=\u003et.route.some((e,n)=\u003e{const o=t.route[n+1];return\"wire\"===e.route_type\u0026\u0026\"wire\"===o?.route_type\u0026\u0026o.layer===e.layer\u0026\u0026!iet.has(e.layer)})),o=new Set(t.connections.map(({name:t})=\u003et)),i=n?[...new Set((t.traces??[]).map(({connection_name:t})=\u003et).filter(t=\u003et\u0026\u0026!o.has(t)))].map(t=\u003e({name:t,pointsToConnect:[]})):[],r=[...t.connections,...i],s=(a=r,Object.fromEntries(a.map((t,e)=\u003e[t.name,`hsl(${340*e/a.length}, 100%, 50%)`])));var a;const c=get({...t,connections:r}),l=[],d=[],h=[],u=[];for(const t of r)for(const n of t.pointsToConnect){const o=cet(n),i=t.__rootConnectionNames??[t.name];u.push({x:n.x,y:n.y,color:s[t.name],layer:aet(e,o),label:[t.name,i.join(\", \"),o.join(\",\")].join(\"\\n\")})}for(const o of t.traces??[]){const i=o.route.filter(t=\u003e\"jumper\"===t.route_type),r=(t,e)=\u003ei.some(n=\u003e{const o=.01;return Math.abs(t.x-n.start.x)\u003co\u0026\u0026Math.abs(t.y-n.start.y)\u003co\u0026\u0026Math.abs(e.x-n.end.x)\u003co\u0026\u0026Math.abs(e.y-n.end.y)\u003co||Math.abs(t.x-n.end.x)\u003co\u0026\u0026Math.abs(t.y-n.end.y)\u003co\u0026\u0026Math.abs(e.x-n.start.x)\u003co\u0026\u0026Math.abs(e.y-n.start.y)\u003co});for(const i of o.route)if(\"via\"===i.route_type){const r=het(e,i.from_layer,i.to_layer);d.push({center:{x:i.x,y:i.y},radius:(i.via_diameter??pet(t))/2,fill:n?s[o.connection_name]:\"blue\",stroke:\"none\",layer:aet(e,r)})}else\"through_obstacle\"===i.route_type\u0026\u0026l.push({points:[i.start,i.end],strokeColor:met(s[o.connection_name]??\"purple\",.35),strokeWidth:i.width,strokeDash:[.1,.1],layer:aet(e,[i.from_layer,i.to_layer]),label:`${o.connection_name} through_obstacle`});for(let t=0;t\u003co.route.length-1;t++){const i=o.route[t],a=o.route[t+1];if(\"jumper\"===i.route_type){const t=s[o.connection_name]??\"rgba(255, 165, 0, 0.8)\",n=ret[\"1206x4_pair\"===i.footprint?\"1206x4_pair\":\"0603\"],r=Math.abs(i.end.x-i.start.x)\u003eMath.abs(i.end.y-i.start.y),a=r?n.padLength:n.padWidth,c=r?n.padWidth:n.padLength,d=aet(e,[i.layer]);for(const e of[i.start,i.end])h.push({center:e,width:a,height:c,fill:met(t,.5),stroke:\"rgba(0, 0, 0, 0.5)\",layer:d});l.push({points:[i.start,i.end],strokeColor:\"rgba(100, 100, 100, 0.8)\",strokeWidth:.3*n.padWidth,layer:d})}else if(\"wire\"===i.route_type\u0026\u0026\"wire\"===a.route_type\u0026\u0026a.layer===i.layer\u0026\u0026!r(i,a)){const t=set(e,i.layer);l.push({points:[{x:i.x,y:i.y},{x:a.x,y:a.y}],layer:`z${t}`,strokeWidth:i.width,strokeColor:oet(t),...n?{label:o.connection_name}:{}})}}}for(const n of t.obstacles){if(n.isCopperPour)continue;const t=det(n,e);if(0===t.length)throw new Error(`FanoutSolver: cannot visualize obstacle \"${n.obstacleId??\"unknown\"}\" without a valid layer`);const o=1===t.length?e[t[0]]:void 0,i=met(\"bottom\"===o?\"blue\":\"red\",.5**t.length),r=n.shape,s={center:n.center,fill:i,layer:`z${t.join(\",\")}`,label:c(n)};\"circle\"===r?d.push({...s,radius:Math.min(n.width,n.height)/2}):h.push({...s,width:n.width,height:n.height,ccwRotationDegrees:n.ccwRotationDegrees})}for(const n of t.jumpers??[])for(const t of n.pads)h.push({center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,fill:\"rgba(255, 165, 0, 0.3)\",stroke:\"rgba(255, 165, 0, 0.8)\",layer:aet(e,t.layers)});return{rects:h,circles:d,lines:l,points:u}}function yet(t,e){if(!Number.isFinite(e)||e\u003c=0)throw new Error(`FanoutSolver: ${t} must be a positive number, received ${e}`);return e}function _et(t,e,n){const o=new Map(e.map(t=\u003e[t.busId,t.connections.length])),i=new Map;for(const[e,r]of Object.entries(t))i.set(r,(i.get(r)??0)+(n?o.get(e)??1:1));return[...i.values()].reduce((t,e)=\u003et+e*e,0)}function bet(t){return t.balanceLayerLoadByConnectionCount?.25:.01}function xet(t){return t.reduce((t,e)=\u003et+Number(Boolean(e.via))+Number(Boolean(e.planeEndpointVia)),0)}function vet(t){const e=t.connections.reduce((e,n)=\u003ee+(\"left\"===t.direction||\"right\"===t.direction?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length;switch(t.direction){case\"right\":return t.sharedBoundary.maxX-e;case\"left\":return e-t.sharedBoundary.minX;case\"up\":return t.sharedBoundary.maxY-e;case\"down\":return e-t.sharedBoundary.minY}}function Iet(t){const e=\"left\"===t.direction||\"right\"===t.direction;return t.connections.some(t=\u003e{const n=t.exitTargetPoint??t.targetPoint,o=e?t.sourcePoint.y:t.sourcePoint.x,i=e?n.y:n.x;return Math.abs(o-i)\u003e1e-6})}function Cet(t){const e=\"left\"===t.direction||\"right\"===t.direction,n=e?t.xCoordinates:t.yCoordinates,o=t.connections.reduce((t,n)=\u003et+(e?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length,i=\"right\"===t.direction||\"up\"===t.direction?Math.max(...n):Math.min(...n);return Math.abs(o-i)\u003c1e-6}function Pet(t){const e=\"left\"===t.direction||\"right\"===t.direction,n=e?t.xCoordinates:t.yCoordinates,o=t.connections.reduce((t,n)=\u003et+(e?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length,i=\"right\"===t.direction||\"up\"===t.direction?Math.max(...n):Math.min(...n),r=e?t.pitchX:t.pitchY;return Math.round(Math.abs(o-i)/r)}function Met(t){const{buses:e,escapeLayers:n,escapeLayersByBusId:o}=t,i={},r=new Map;let s=0;for(const t of e){const e=r.get(t.componentId)??new Set;e.add(t.direction),r.set(t.componentId,e)}for(const t of e){const e=t.connections[0]?.sourceLayer;if(!e)throw new Error(`FanoutSolver: bus \"${t.busId}\" has no connections`);if(\"plane\"===t.termination.type){i[t.busId]=t.termination.layer;continue}const a=o[t.busId]??n,c=a.filter(t=\u003et!==e);if(a.includes(e)\u0026\u0026(Iet(t)||Cet(t)))i[t.busId]=e;else if(c.length\u003e0){const e=r.get(t.componentId);if(e.has(\"left\")\u0026\u0026e.has(\"right\")||e.has(\"up\")\u0026\u0026e.has(\"down\")){const e=Pet(t);i[t.busId]=c[Math.max(e-1,0)%c.length]}else i[t.busId]=c[s%c.length],s++}else i[t.busId]=e}return i}function Net(t){const{bus:e,srj:n,config:o,staticClearanceCache:i}=t,r=o.escapeLayers.filter(t=\u003enull!==htt({srj:n,bus:e,targetLayer:t,acceptedPlans:[],layerNames:o.layerNames,traceWidth:o.traceWidth,viaDiameter:o.viaDiameter,viaHoleDiameter:o.viaHoleDiameter,clearance:o.clearance,compactBusTracks:o.compactBusTracks,allowSameNetMerges:o.allowSameNetMerges,staticClearanceCache:i}));return r.length\u003e0?r:o.escapeLayers}var wet=class extends b8{constructor(t,e={}){super(),this.inputSrj=t,this.options=e,this.config=function(t,e){const n=yet(\"traceWidth\",e.traceWidth??t.nominalTraceWidth??t.minTraceWidth),o=yet(\"viaDiameter\",e.viaDiameter??t.minViaPadDiameter??t.min_via_pad_diameter??t.minViaDiameter??Math.max(2*n,.3)),i=yet(\"viaHoleDiameter\",e.viaHoleDiameter??t.minViaHoleDiameter??t.min_via_hole_diameter??.5*o);if(i\u003e=o)throw new Error(`FanoutSolver: viaHoleDiameter ${i} must be smaller than viaDiameter ${o}`);const r=yet(\"clearance\",e.clearance??t.minViaEdgeToPadEdgeClearance??t.minTraceToPadEdgeClearance??t.defaultObstacleMargin??t.minTraceWidth),s=k8(t.layerCount),a=e.escapeLayers??s;for(const e of a)if(!s.includes(e))throw new Error(`FanoutSolver: escape layer \"${e}\" is not available in a ${t.layerCount}-layer SimpleRouteJson`);if(new Set(a).size!==a.length)throw new Error(\"FanoutSolver: escapeLayers contains duplicates\");const c=e.borderDistribution??\"preserve\";if(\"preserve\"!==c\u0026\u0026\"even\"!==c)throw new Error(`FanoutSolver: borderDistribution must be \"preserve\" or \"even\", received \"${c}\"`);return{traceWidth:n,viaDiameter:o,viaHoleDiameter:i,clearance:r,compactBusTracks:e.compactBusTracks??!1,allowSameNetMerges:e.allowSameNetMerges??!1,singleLayerPushAndShove:e.singleLayerPushAndShove??!1,singleLayerAdaptiveExits:e.singleLayerAdaptiveExits??!1,borderDistribution:c,layerNames:s,escapeLayers:a,maxLayerCombinations:void 0===e.maxLayerCombinations?256:yet(\"maxLayerCombinations\",e.maxLayerCombinations),balanceLayerLoadByConnectionCount:e.balanceLayerLoadByConnectionCount??!1}}(t,e),this.preparedBuses=j7(t,e);for(const t of this.preparedBuses){if(\"plane\"!==t.termination.type)continue;const e=t.termination.layer;if(!this.config.layerNames.includes(e))throw new Error(`FanoutSolver: plane-terminated bus \"${t.busId}\" targets unavailable layer \"${e}\"`);if(t.connections.some(t=\u003et.sourceLayer===e))throw new Error(`FanoutSolver: plane-terminated bus \"${t.busId}\" must target a layer below its source pad`)}const n=this.preparedBuses.filter(t=\u003e\"boundary\"===t.termination.type).map(t=\u003et.busId),o=Object.fromEntries(this.preparedBuses.flatMap(t=\u003e\"plane\"===t.termination.type?[[t.busId,t.termination.layer]]:[])),i=Object.fromEntries(this.preparedBuses.flatMap(e=\u003e\"plane\"===e.termination.type?[]:[[e.busId,Net({bus:e,srj:t,config:this.config,staticClearanceCache:this.routeStaticClearanceCache})]]));this.escapeLayersByBusId=i;const r=function(t){const{busIds:e,layers:n,layersByBusId:o,maxAssignments:i}=t;if(0===n.length)throw new Error(\"FanoutSolver: no escape layers are available\");if(!Number.isInteger(i)||i\u003c1)throw new Error(`FanoutSolver: maxLayerCombinations must be positive, received ${i}`);const r=e.map(t=\u003eo?.[t]??n),s=r.findIndex(t=\u003e0===t.length);if(s\u003e=0)throw new Error(`FanoutSolver: no escape layers are available for bus \"${e[s]}\"`);const a=r.reduce((t,e)=\u003et*e.length,1),c=Math.min(i,Number.isFinite(a)?a:i),l=[],d=new Set;function h(t){const n={};for(let o=0;o\u003ce.length;o++)n[e[o]]=r[o][t[o]];const o=JSON.stringify(n);d.has(o)||(d.add(o),l.push(n))}if(a\u003c=i){for(let t=0;t\u003cc;t++){const n=[];let o=t;for(let t=0;t\u003ce.length;t++){const e=r[t].length,i=o%e;o=Math.floor(o/e),n.push((i+t)%e)}h(n)}return l}function u(t){let e=0|t;return e=Math.imul(e^e\u003e\u003e\u003e16,569420461),e=Math.imul(e^e\u003e\u003e\u003e15,1935289751),(e^e\u003e\u003e\u003e15)\u003e\u003e\u003e0}const p=e.map((t,e)=\u003ee%r[e].length);h(p);const m=Math.max(...r.map(t=\u003et.length));for(let t=1;t\u003cm\u0026\u0026l.length\u003cc;t++)h(p.map((e,n)=\u003e(e+t)%r[n].length));for(let t=0;t\u003ce.length\u0026\u0026l.length\u003cc;t++)for(let e=1;e\u003cr[t].length\u0026\u0026l.length\u003cc;e++){const n=[...p];n[t]=(p[t]+e)%r[t].length,h(n)}for(let t=1;l.length\u003cc\u0026\u0026t\u003c20*c;t++)h(e.map((e,n)=\u003eu(2654435761*t+2246822507*n)%r[n].length));return l}({busIds:n,layers:this.config.escapeLayers,layersByBusId:i,maxAssignments:this.config.maxLayerCombinations}).map(t=\u003e({...t,...o}));this.layerAssignments=function(t){const{preferredAssignment:e,generatedAssignments:n,maxAssignments:o}=t,i=JSON.stringify(e);return[e,...n.filter(t=\u003eJSON.stringify(t)!==i)].slice(0,o)}({preferredAssignment:Met({buses:this.preparedBuses,escapeLayers:this.config.escapeLayers,escapeLayersByBusId:i}),generatedAssignments:r,maxAssignments:this.config.maxLayerCombinations}),this.MAX_ITERATIONS=this.config.maxLayerCombinations+2}inputSrj;options;preparedBuses;attempts=[];layerAssignments;config;escapeLayersByBusId;evaluatedAssignmentKeys=new Set;queuedAssignmentKeys=new Set;assignmentRepairDepthByKey=new Map;pendingRepairAssignments=[];routeStaticClearanceCache=new Map;routingPrefixCache=new Map;groupedBeamEvaluated=!1;nextAssignmentIndex=0;nextGeneratedAssignmentIndex=0;bestAttempt=null;endpointCompletion=null;getSolverName(){return\"FanoutSolver\"}completeBestAttemptEndpoints(){this.options.completeOriginalEndpoints\u0026\u0026!this.endpointCompletion\u0026\u0026this.bestAttempt\u0026\u0026(this.endpointCompletion=y7({inputSrj:this.inputSrj,fanoutSrj:this.bestAttempt.outputSrj,plans:this.bestAttempt.plans,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,effort:this.options.endpointCompletionEffort,routeDownstreamConnections:this.options.routeDownstreamConnections}))}getValidationBoundary(){if(this.options.sharedBoundary)return this.options.sharedBoundary;const t=this.preparedBuses[0]?.sharedBoundary;return t?this.preparedBuses.slice(1).reduce((t,e)=\u003e({minX:Math.min(t.minX,e.sharedBoundary.minX),maxX:Math.max(t.maxX,e.sharedBoundary.maxX),minY:Math.min(t.minY,e.sharedBoundary.minY),maxY:Math.max(t.maxY,e.sharedBoundary.maxY)}),{...t}):this.inputSrj.bounds}validateCompletePlans(t,e){return eet({inputSrj:this.inputSrj,outputSrj:e,plans:t,preparedBuses:this.preparedBuses,sharedBoundary:this.getValidationBoundary(),clearance:this.config.clearance})}evaluateAssignmentWithStrategy(t,e,n){let o=[],i=[],r=new Map;const s=1===this.config.escapeLayers.length;if(s\u0026\u0026this.config.singleLayerPushAndShove){const t={srj:this.inputSrj,buses:this.preparedBuses,traceWidth:this.config.traceWidth,clearance:this.config.clearance,borderDistribution:this.config.borderDistribution},e=Ytt(t)??(this.config.singleLayerAdaptiveExits?Mtt({...t,availableBoundaryRegions:R7(this.options.availableCornersAndSides)}):null);e?o.push(...e):i.push(...this.preparedBuses.map(t=\u003et.busId))}const a=[...this.preparedBuses].sort((t,o)=\u003eNumber(\"plane\"===o.termination.type)-Number(\"plane\"===t.termination.type)||(\"group-by-layer\"===n?(e[t.busId]??\"\").localeCompare(e[o.busId]??\"\"):0)||o.componentObstacles.length-t.componentObstacles.length||(s?vet(o)-vet(t):o.connections.length-t.connections.length||(\"deep-first\"===n?vet(o)-vet(t):vet(t)-vet(o))));let c,l=`${n}|`;for(const n of s\u0026\u0026this.config.singleLayerPushAndShove?[]:a){const s=e[n.busId];if(!s)throw new Error(`FanoutSolver: assignment ${t} has no layer for bus \"${n.busId}\"`);l+=`${n.busId.length}:${n.busId};${s.length}:${s};`;const a=this.routingPrefixCache.get(l);if(a){o=[...a.plans],i=[...a.failedBusIds],r=new Map(a.blockingBusCounts);continue}const c=new Map,d=htt({srj:this.inputSrj,bus:n,targetLayer:s,acceptedPlans:o,layerNames:this.config.layerNames,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,compactBusTracks:this.config.compactBusTracks,allowSameNetMerges:this.config.allowSameNetMerges,staticClearanceCache:this.routeStaticClearanceCache,blockingBusCounts:c});if(d)o.push(...d);else{i.push(n.busId);for(const[t,e]of c)r.set(t,(r.get(t)??0)+e)}this.routingPrefixCache.set(l,{plans:[...o],failedBusIds:[...i],blockingBusCounts:new Map(r)})}let d=S8({inputSrj:this.inputSrj,plans:o,layerNames:this.config.layerNames});const h=o.length===this.inputSrj.connections.length?this.validateCompletePlans(o,d):null;h\u0026\u0026!h.valid\u0026\u0026(c=h.issues,o=[],i=this.preparedBuses.map(t=\u003et.busId),r.clear(),d=S8({inputSrj:this.inputSrj,plans:o,layerNames:this.config.layerNames}));const u=this.preparedBuses.length-i.length,p=o.reduce((t,e)=\u003et+e.length,0),m=1e6*(this.inputSrj.connections.length-o.length)+1e5*i.length+p+.1*xet(o)+_et(e,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config);return{summary:{assignmentIndex:t,busLayerAssignments:e,routedBusCount:u,routedConnectionCount:o.length,failedBusIds:i,score:m,...c?{validationIssues:c}:{}},plans:o,blockingBusIds:[...r.entries()].toSorted(([,t],[,e])=\u003ee-t).map(([t])=\u003et),outputSrj:d}}evaluateAssignment(t,e){let n=this.evaluateAssignmentWithStrategy(t,e,\"default\");if(n.summary.routedConnectionCount===this.inputSrj.connections.length)return n;for(const o of[\"group-by-layer\",\"deep-first\"]){const i=this.evaluateAssignmentWithStrategy(t,e,o);if(i.summary.score\u003cn.summary.score\u0026\u0026(n=i),n.summary.routedConnectionCount===this.inputSrj.connections.length)return n}return n}evaluateGroupedBeam(t,e=!1){if(this.config.escapeLayers.length\u003c2)return null;if(this.preparedBuses.length\u003e56)return null;const n=this.inputSrj.connections.length;if(n\u003e64)return null;if(1!==new Set(this.preparedBuses.map(t=\u003et.componentId)).size)return null;const o=[...this.preparedBuses].sort((t,n)=\u003e{const o=\"plane\"===t.termination.type?1:this.escapeLayersByBusId[t.busId]?.length??this.config.escapeLayers.length,i=\"plane\"===n.termination.type?1:this.escapeLayersByBusId[n.busId]?.length??this.config.escapeLayers.length;return Number(\"plane\"===n.termination.type)-Number(\"plane\"===t.termination.type)||(e?t.direction.localeCompare(n.direction):0)||o-i||n.componentObstacles.length-t.componentObstacles.length||n.connections.length-t.connections.length||Pet(n)-Pet(t)||t.busId.localeCompare(n.busId)}),i=n\u003c=24,r=this.preparedBuses.some(t=\u003et.connections.length\u003e1),s=i?48:n\u003c=32?24:12,a=i\u0026\u0026!r?4:1;let c=[{assignment:{},plans:[]}];const l=t=\u003et.plans.reduce((t,e)=\u003et+e.length,0)+.1*xet(t.plans)+1e4*this.preparedBuses.reduce((e,n)=\u003e{if(\"boundary\"!==n.termination.type||!Iet(n))return e;const o=n.connections[0]?.sourceLayer;return t.assignment[n.busId]===o?e:e+n.connections.length},0)+_et(t.assignment,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config);for(const t of o){const e=[];for(const n of c){const o=\"plane\"===t.termination.type?[t.termination.layer]:this.escapeLayersByBusId[t.busId]??this.config.escapeLayers,i=new Map;for(const[t,e]of Object.entries(n.assignment)){const n=this.preparedBuses.find(e=\u003ee.busId===t);i.set(e,(i.get(e)??0)+(this.config.balanceLayerLoadByConnectionCount?n?.connections.length??1:1))}const r=t.connections[0]?.sourceLayer,s=Iet(t),c=o.toSorted((t,e)=\u003e(i.get(t)??0)-(i.get(e)??0)||(s?Number(e===r)-Number(t===r):Number(t===r)-Number(e===r))||t.localeCompare(e));for(const o of c){const i=dtt({srj:this.inputSrj,bus:t,targetLayer:o,acceptedPlans:n.plans,layerNames:this.config.layerNames,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,compactBusTracks:this.config.compactBusTracks,allowSameNetMerges:this.config.allowSameNetMerges,staticClearanceCache:this.routeStaticClearanceCache},a);for(const r of i)e.push({assignment:{...n.assignment,[t.busId]:o},plans:[...n.plans,...r]})}}if(0===e.length)return null;e.sort((t,e)=\u003e{const n=l(t)-l(e);return Math.abs(n)\u003e1e-9?n:JSON.stringify(t.assignment).localeCompare(JSON.stringify(e.assignment))});const n=new Map;c=[];for(const t of e){const e=JSON.stringify(t.assignment),o=n.get(e)??0;if(!(o\u003e=2)\u0026\u0026(n.set(e,o+1),c.push(t),c.length\u003e=s))break}}const d=c[0];if(!d)return null;const h=S8({inputSrj:this.inputSrj,plans:d.plans,layerNames:this.config.layerNames});if(d.plans.length===this.inputSrj.connections.length\u0026\u0026!this.validateCompletePlans(d.plans,h).valid)return null;const u=d.plans.length===this.inputSrj.connections.length?d.plans.reduce((t,e)=\u003et+e.length,0)+.1*xet(d.plans)+_et(d.assignment,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config):Number.POSITIVE_INFINITY;if(!Number.isFinite(u))return null;return{summary:{assignmentIndex:t,busLayerAssignments:d.assignment,routedBusCount:this.preparedBuses.length,routedConnectionCount:d.plans.length,failedBusIds:[],score:u},plans:d.plans,blockingBusIds:[],outputSrj:h}}prioritizeFailedBusRepairs(t,e,n){const o=JSON.stringify(t),i=this.assignmentRepairDepthByKey.get(o)??0;if(i\u003e=2)return;const r=[],s=new Set,a=t=\u003e{const e=JSON.stringify(t);s.has(e)||this.evaluatedAssignmentKeys.has(e)||this.queuedAssignmentKeys.has(e)||(s.add(e),this.queuedAssignmentKeys.add(e),this.assignmentRepairDepthByKey.set(e,i+1),r.push(t))},c=[];for(let t=0;t\u003cMath.max(e.length,n.length);t++){const o=e[t],i=n[t];o\u0026\u0026!c.includes(o)\u0026\u0026c.push(o),i\u0026\u0026!c.includes(i)\u0026\u0026c.push(i)}for(const o of e){const e=t[o],i=this.escapeLayersByBusId[o];if(e\u0026\u0026i){for(const s of n.slice(0,4)){const n=t[s],c=this.escapeLayersByBusId[s];if(n\u0026\u0026c\u0026\u0026i.includes(n)\u0026\u0026c.includes(e)\u0026\u0026(a({...t,[o]:n,[s]:e}),r.length\u003e=8))break}if(r.length\u003e=8)break}}for(const e of c){const n=t[e],o=this.escapeLayersByBusId[e];if(!n||!o)continue;const i=o.indexOf(n);for(let s=1;s\u003co.length;s++){const c=o[(Math.max(i,0)+s)%o.length];if(c!==n\u0026\u0026(a({...t,[e]:c}),r.length\u003e=8))break}if(r.length\u003e=8)break}this.pendingRepairAssignments.push(...r)}hasCompleteBestAttempt(){return this.bestAttempt?.summary.routedConnectionCount===this.inputSrj.connections.length}shouldEvaluateGroupedBeam(){if(this.groupedBeamEvaluated||0===this.nextAssignmentIndex)return!1;return this.hasCompleteBestAttempt()||0===this.pendingRepairAssignments.length||this.nextAssignmentIndex\u003e=this.config.maxLayerCombinations}_step(){if(this.shouldEvaluateGroupedBeam()){this.groupedBeamEvaluated=!0;let t=this.evaluateGroupedBeam(-1);if(t||(t=this.evaluateGroupedBeam(-1,!0)),t){this.attempts.push(t.summary),(!this.bestAttempt||t.summary.score\u003cthis.bestAttempt.summary.score)\u0026\u0026(this.bestAttempt=t);const e=this.bestAttempt.summary;return this.stats={assignment:e.assignmentIndex\u003c0?0:e.assignmentIndex+1,assignmentCount:this.config.maxLayerCombinations,routedBuses:`${e.routedBusCount}/${this.preparedBuses.length}`,routedConnections:`${e.routedConnectionCount}/${this.inputSrj.connections.length}`,failedBuses:\"none\",bestScore:e.score},this.completeBestAttemptEndpoints(),void(this.solved=!0)}if(this.hasCompleteBestAttempt())return this.completeBestAttemptEndpoints(),void(this.solved=!0)}let t;for(;!t\u0026\u0026this.nextAssignmentIndex\u003cthis.config.maxLayerCombinations;){const e=this.nextAssignmentIndex%3==0;let n,o=!1;if(!this.groupedBeamEvaluated\u0026\u0026this.nextAssignmentIndex\u003e0?(n=this.pendingRepairAssignments.pop(),o=void 0!==n):e?n=this.layerAssignments[this.nextGeneratedAssignmentIndex++]:(n=this.pendingRepairAssignments.pop(),o=void 0!==n),n||!this.groupedBeamEvaluated\u0026\u00260!==this.nextAssignmentIndex||(n=e?this.pendingRepairAssignments.pop():this.layerAssignments[this.nextGeneratedAssignmentIndex++],o=e\u0026\u0026void 0!==n),!n)break;const i=JSON.stringify(n);o\u0026\u0026this.queuedAssignmentKeys.delete(i),this.evaluatedAssignmentKeys.has(i)||(t=n)}if(!t\u0026\u0026!this.groupedBeamEvaluated)return;if(!t)return void(this.hasCompleteBestAttempt()?(this.completeBestAttemptEndpoints(),this.solved=!0):(this.failed=!0,this.error=this.bestAttempt?`FanoutSolver: best layer assignment routed ${this.bestAttempt.summary.routedConnectionCount}/${this.inputSrj.connections.length} connections`:\"FanoutSolver: no layer assignment could be evaluated\"));const e=this.evaluateAssignment(this.nextAssignmentIndex,t);this.nextAssignmentIndex++,this.evaluatedAssignmentKeys.add(JSON.stringify(t)),(!this.bestAttempt||e.summary.routedConnectionCount\u003e=this.bestAttempt.summary.routedConnectionCount)\u0026\u0026this.prioritizeFailedBusRepairs(t,e.summary.failedBusIds,e.blockingBusIds),this.attempts.push(e.summary),(!this.bestAttempt||e.summary.score\u003cthis.bestAttempt.summary.score)\u0026\u0026(this.bestAttempt=e),this.stats={assignment:e.summary.assignmentIndex+1,assignmentCount:this.config.maxLayerCombinations,routedBuses:`${e.summary.routedBusCount}/${this.preparedBuses.length}`,routedConnections:`${e.summary.routedConnectionCount}/${this.inputSrj.connections.length}`,failedBuses:e.summary.failedBusIds.join(\", \")||\"none\",bestScore:this.bestAttempt.summary.score},this.groupedBeamEvaluated\u0026\u0026e.summary.routedConnectionCount===this.inputSrj.connections.length\u0026\u0026(this.completeBestAttemptEndpoints(),this.solved=!0)}computeProgress(){return this.solved||this.failed?1:this.nextAssignmentIndex/this.config.maxLayerCombinations}getConstructorParams(){return[this.inputSrj,this.options]}getOutput(){if(!this.solved||!this.bestAttempt)throw new Error(\"FanoutSolver: getOutput() called before a complete fanout was solved\");const t=this.validateCompletePlans(this.bestAttempt.plans,this.bestAttempt.outputSrj);if(!t.valid)throw new Error(`FanoutSolver: completed output failed validation: ${t.issues[0]?.message??\"unknown validation error\"}`);const e=this.endpointCompletion?.simpleRouteJson??this.bestAttempt.outputSrj,n=new Map((e.traces??[]).map(t=\u003e[t.pcb_trace_id,t]));return{simpleRouteJson:this.endpointCompletion?.simpleRouteJson??this.bestAttempt.outputSrj,fanoutTraces:this.bestAttempt.plans.flatMap(t=\u003e[n.get(t.trace.pcb_trace_id)??t.trace,...t.planeEndpointTrace?[n.get(t.planeEndpointTrace.pcb_trace_id)??t.planeEndpointTrace]:[]]),completionTraces:this.endpointCompletion?.traces??[],...this.endpointCompletion?{endpointCompletion:this.endpointCompletion.report}:{},planeTerminations:this.bestAttempt.plans.flatMap(t=\u003e\"plane\"===t.termination.type\u0026\u0026t.via?[{busId:t.busId,connectionName:t.connectionName,layer:t.termination.layer,via:t.via}]:[]),busLayerAssignments:this.bestAttempt.summary.busLayerAssignments,busDirections:Object.fromEntries(this.preparedBuses.map(t=\u003e[t.busId,t.direction])),attempts:[...this.attempts],validation:t}}getOutputSimpleRouteJson(){return this.getOutput().simpleRouteJson}visualize(){return fet(this.endpointCompletion?.simpleRouteJson??this.bestAttempt?.outputSrj??this.inputSrj)}};function Tet(t){const{minX:e,maxX:n}=t.bounds,o=(e+n)/2;if(!Number.isFinite(o))throw new Error(`Detected component ${t.componentId} has bad bounds`);return o}function Ret(t){const{minY:e,maxY:n}=t.bounds,o=(e+n)/2;if(!Number.isFinite(o))throw new Error(`Detected component ${t.componentId} has bad bounds`);return o}function Eet(t,e){const n=(function(t,e){const[n,o]=Tet(t)\u003cTet(e)?[t,e]:[e,t];return o.bounds.minX-n.bounds.maxX}(t,e)-2)/2;return Math.min(4.5,n)}function Aet(t,e){const n=e.filter(t=\u003e\"bga\"===t.componentKind).map(e=\u003efunction(t,e){const n=t.obstacles.filter(t=\u003et.componentId===e.componentId);if(0===n.length)throw new Error(`Detected component ${e.componentId} has no physical obstacles`);return{...e,bounds:{__type:\"rect\",minX:Math.min(...n.map(t=\u003et.center.x-t.width/2)),maxX:Math.max(...n.map(t=\u003et.center.x+t.width/2)),minY:Math.min(...n.map(t=\u003et.center.y-t.height/2)),maxY:Math.max(...n.map(t=\u003et.center.y+t.height/2))}}}(t,e)).toSorted((t,e)=\u003eTet(t)-Tet(e));if(2!==n.length)throw new Error(`Pipeline 10 requires exactly two detected BGAs; found ${n.map(t=\u003et.componentId).join(\", \")||\"none\"}`);const[o,i]=n;if(o.componentId===i.componentId)throw new Error(\"Pipeline 10 requires two distinct BGA component IDs\");if(Eet(o,i)\u003c2)throw new Error(\"Pipeline 10 cannot provide 2mm fanout margins while retaining a 2mm routing corridor\");return{first:o,second:i}}function Oet(t,e){const{minX:n,maxX:o,minY:i,maxY:r}=t.bounds;return{minX:n-e,maxX:o+e,minY:i-e,maxY:r+e}}function ket(t){const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds;return{minX:e,maxX:n,minY:o,maxY:i}}function Let({inputSrj:t,source:e,target:n}){const o=Eet(e,n),i=Oet(e,o),r=Tet(n)\u003eTet(e)?\"right\":\"left\",s=\"right\"===r?\"left\":\"right\";return t.connections.map((t,n)=\u003e{const a=t.pointsToConnect.filter(t=\u003et.x\u003e=e.bounds.minX\u0026\u0026t.x\u003c=e.bounds.maxX\u0026\u0026t.y\u003e=e.bounds.minY\u0026\u0026t.y\u003c=e.bounds.maxY);if(1!==a.length)throw new Error(`Connection ${t.name} must touch ${e.componentId} exactly once before fanout`);const c=a[0],l=\"right\"===r?i.maxX-c.x:c.x-i.minX,d=[{direction:\"up\",distance:i.maxY-c.y},{direction:\"down\",distance:c.y-i.minY},{direction:s,distance:\"right\"===s?i.maxX-c.x:c.x-i.minX}].toSorted((t,e)=\u003et.distance-e.distance)[0].direction,h=l\u003c=o+1.2?r:d;let u=\"up\"===h?\"top\":\"down\"===h?\"bottom\":h;return\"up\"===h?u=c.x\u003cTet(e)?\"top-left\":\"top-right\":\"down\"===h?u=c.x\u003cTet(e)?\"bottom-left\":\"bottom-right\":c.y\u003eRet(e)+1e-6?u=\"right\"===h?\"top-right\":\"top-left\":c.y\u003cRet(e)-1e-6\u0026\u0026(u=\"right\"===h?\"bottom-right\":\"bottom-left\"),{busId:`pipeline10_fanout:${e.componentId}:${n}`,connectionNames:[t.name],sourceComponentId:e.componentId,direction:h,preferredExit:u,termination:{type:\"boundary\"}}})}function Det({inputSrj:t,source:e,target:n}){const o=Eet(e,n);return{buses:Let({inputSrj:t,source:e,target:n}),sourceComponentId:e.componentId,availableCornersAndSides:[\"top_left\",\"top_middle\",\"top_right\",\"right_top\",\"right_middle\",\"right_bottom\",\"bottom_right\",\"bottom_middle\",\"bottom_left\",\"left_bottom\",\"left_middle\",\"left_top\"],componentBounds:{[e.componentId]:ket(e)},sharedBoundary:Oet(e,o),maxLayerCombinations:256,balanceLayerLoadByConnectionCount:!0,compactBusTracks:!0,borderDistribution:\"even\"}}var zet=class extends kt{constructor(t){super(),this.inputProblem=t,this.fanoutSolver=new wet(t.inputSrj,t.options),this.activeSubSolver=this.fanoutSolver,this.MAX_ITERATIONS=this.fanoutSolver.MAX_ITERATIONS+1}inputProblem;fanoutSolver;_step(){if(this.fanoutSolver.step(),this.progress=this.fanoutSolver.progress,this.stats={...this.fanoutSolver.stats},this.fanoutSolver.failed)return this.error=this.fanoutSolver.error??\"Fanout solver failed\",this.failed=!0,void(this.activeSubSolver=null);this.fanoutSolver.solved\u0026\u0026(this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.fanoutSolver.getOutput()}getOutputSimpleRouteJson(){return this.fanoutSolver.getOutputSimpleRouteJson()}visualize(){return this.fanoutSolver.visualize()}preview(){return this.fanoutSolver.preview()}},Fet=class extends kt{constructor(t){super(),this.inputProblem=t,this.autoroutingPipelineSolver=new H9(t.inputSrj,t.options),this.activeSubSolver=this.autoroutingPipelineSolver,this.MAX_ITERATIONS=this.autoroutingPipelineSolver.MAX_ITERATIONS+1}inputProblem;autoroutingPipelineSolver;_step(){if(this.autoroutingPipelineSolver.step(),this.progress=this.autoroutingPipelineSolver.progress,this.stats={...this.autoroutingPipelineSolver.stats},this.autoroutingPipelineSolver.failed)return this.error=this.autoroutingPipelineSolver.error??\"Autorouting pipeline failed\",this.failed=!0,void(this.activeSubSolver=null);this.autoroutingPipelineSolver.solved\u0026\u0026(this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.autoroutingPipelineSolver.getOutputSimpleRouteJson()}visualize(){return this.autoroutingPipelineSolver.visualize()}preview(){return this.autoroutingPipelineSolver.preview()}},Bet=class extends Dt{componentDetectionSolver;firstBgaFanoutSolver;secondBgaFanoutSolver;autoroutingPipelineSolver;get currentPipelineStepIndex(){return this.currentPipelineStageIndex}get startTimeOfPhase(){return this.startTimeOfStage}get timeSpentOnPhase(){return this.timeSpentOnStage}pipelineDef=[Lt(\"componentDetectionSolver\",UZ,t=\u003e[{inputSrj:t.inputProblem.inputSrj}]),Lt(\"firstBgaFanoutSolver\",zet,t=\u003e{const e=Aet(t.inputProblem.inputSrj,t.componentDetectionSolver.getOutput());return[{inputSrj:t.inputProblem.inputSrj,options:Det({inputSrj:t.inputProblem.inputSrj,source:e.first,target:e.second})}]}),Lt(\"secondBgaFanoutSolver\",zet,t=\u003e{const e=Aet(t.inputProblem.inputSrj,t.componentDetectionSolver.getOutput()),n=t.firstBgaFanoutSolver.getOutputSimpleRouteJson();return[{inputSrj:n,options:Det({inputSrj:n,source:e.second,target:e.first})}]}),Lt(\"autoroutingPipelineSolver\",Fet,t=\u003e[{inputSrj:t.secondBgaFanoutSolver.getOutputSimpleRouteJson(),options:t.inputProblem.options}])];constructor(t,e={}){super({inputSrj:t,options:e}),this.MAX_ITERATIONS=1e8*(e.effort??1)+1024}getSolverName(){return\"AutoroutingPipelineSolver10_BgaFanout\"}getConstructorParams(){return[this.inputProblem.inputSrj,this.inputProblem.options]}getOutput(){if(!this.autoroutingPipelineSolver?.solved)throw new Error(\"Pipeline 10 has not solved yet\");return this.autoroutingPipelineSolver.getOutput()}getOutputSimpleRouteJson(){return this.getOutput()}getOutputSimplifiedPcbTraces(){return this.getOutput().traces??[]}get srjWithPointPairs(){return this.autoroutingPipelineSolver?.autoroutingPipelineSolver.srjWithPointPairs}initialVisualize(){return Ho(this.inputProblem.inputSrj)}finalVisualize(){return Ho(this.getOutput())}},jet=class extends kt{constructor(t){super(),this.inputProblem=t,this.simplifiedRouteByTraceId=new Map(t.simplifiedHdRoutes.map(t=\u003e[t.connectionName,t])),this.MAX_ITERATIONS=t.preparedInput.preparedTraces.length+1}inputProblem;simplifiedRouteByTraceId;outputTraces=[];nextTraceIndex=0;getSolverName(){return\"ApplyTraceSimplificationSolver\"}_step(){const t=this.inputProblem.preparedInput.preparedTraces,e=t[this.nextTraceIndex];e?(this.outputTraces.push(this.applyTrace(e)),this.nextTraceIndex++,this.progress=this.nextTraceIndex/Math.max(1,t.length)):this.finishApplication()}applyTrace(t){if(!t.mutableHdRoute)return structuredClone(t.originalTrace);const e=this.simplifiedRouteByTraceId.get(t.originalTrace.pcb_trace_id);if(!e||void 0===t.uniformTraceWidth)throw new Error(`Simplification removed trace \"${t.originalTrace.pcb_trace_id}\"`);const n=Mo(e,this.inputProblem.preparedInput.srj.layerCount,{defaultViaHoleDiameter:t.viaHoleDiameter,obstacles:this.inputProblem.preparedInput.srj.obstacles,connMap:this.inputProblem.preparedInput.connMap}),o=n.filter(t=\u003e\"jumper\"===t.route_type),i=((t,e)=\u003et.map(t=\u003e\"wire\"===t.route_type||\"through_obstacle\"===t.route_type?{...t,width:e}:t))([...structuredClone(t.leadingTerminalVias),...n.filter(t=\u003e\"jumper\"!==t.route_type),...structuredClone(t.trailingTerminalVias),...o],t.uniformTraceWidth);return((t,e)=\u003e{const n=t.filter(t=\u003e\"wire\"===t.route_type);e.startPcbPortId\u0026\u0026n[0]\u0026\u0026(n[0].start_pcb_port_id=e.startPcbPortId),e.endPcbPortId\u0026\u0026n.at(-1)\u0026\u0026(n.at(-1).end_pcb_port_id=e.endPcbPortId)})(i,e),{...structuredClone(t.originalTrace),route:i}}finishApplication(){const t=this.inputProblem.preparedInput.preparedTraces;this.stats={inputTraceCount:t.length,outputTraceCount:this.outputTraces.length,inputRoutePointCount:t.reduce((t,e)=\u003et+e.originalTrace.route.length,0),outputRoutePointCount:this.outputTraces.reduce((t,e)=\u003et+e.route.length,0)},this.progress=1,this.solved=!0}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error(\"Cannot get applied traces before conversion completes\");return{...structuredClone(this.inputProblem.preparedInput.originalSrj),traces:structuredClone(this.outputTraces)}}},$et=(t,e)=\u003e{const n=t.at(-1);if(n\u0026\u0026(o=n,i=e,Math.abs(o.x-i.x)\u003c=1e-9\u0026\u0026Math.abs(o.y-i.y)\u003c=1e-9\u0026\u0026o.z===i.z))return void 0!==e.traceThickness\u0026\u0026(n.traceThickness=e.traceThickness),void(void 0!==e.pcb_port_id\u0026\u0026(n.pcb_port_id=e.pcb_port_id));var o,i;t.push(e)},Yet=(t,e,n)=\u003e{for(let o=e+1;o\u003ct.length;o++){const e=t[o];if(\"wire\"===e.route_type)return ko(e.layer,n);if(\"through_obstacle\"===e.route_type)return ko(e.from_layer,n)}},Xet=({fromZ:t,toZ:e,previousZ:n,nextZ:o})=\u003en===t?[t,e]:n===e?[e,t]:o===e?[t,e]:o===t?[e,t]:[t,e],Vet=(t,e)=\u003e{for(const e of t)if(\"via\"===e.route_type\u0026\u0026void 0!==e.via_diameter)return e.via_diameter;return e},Wet=(t,e)=\u003e{const n=\"start\"===e?t:[...t].reverse();for(const t of n){if(\"wire\"!==t.route_type)continue;const n=\"start\"===e?t.start_pcb_port_id:t.end_pcb_port_id;if(n)return n}},Het=t=\u003e({route_type:\"jumper\",start:{...t.start},end:{...t.end},footprint:t.footprint}),Get=(t,e)=\u003e{for(const e of t.route)if(\"via\"===e.route_type\u0026\u0026void 0!==e.via_hole_diameter)return e.via_hole_diameter;return e},Uet=class extends kt{preparedInput;seenTraceIds=new Set;nextTraceIndex=0;constructor(t){super();const e=structuredClone(t.inputSrj),n=fX(e),o=ii(n);this.preparedInput={originalSrj:e,srj:n,connMap:o,colorMap:wo(n,o),immutableHdRoutes:[],mutableHdRoutes:[],netByConnectionName:new Map,options:{...t.options},preparedTraces:[]},this.MAX_ITERATIONS=(n.traces?.length??0)+1}getSolverName(){return\"PrepareTraceSimplificationSolver\"}_step(){const t=this.preparedInput.srj.traces??[],e=t[this.nextTraceIndex];if(!e)return this.stats={inputTraceCount:t.length,mutableTraceCount:this.preparedInput.mutableHdRoutes.length,immutableTraceCount:t.length-this.preparedInput.mutableHdRoutes.length},this.progress=1,void(this.solved=!0);this.prepareTrace(e,this.nextTraceIndex),this.nextTraceIndex++,this.progress=this.nextTraceIndex/Math.max(1,t.length)}prepareTrace(t,e){if(this.seenTraceIds.has(t.pcb_trace_id))throw new Error(`Duplicate pcb_trace_id \"${t.pcb_trace_id}\"`);this.seenTraceIds.add(t.pcb_trace_id);const n=Yo(this.preparedInput.srj),o=(t=\u003e{const e=t.route.flatMap(t=\u003e\"wire\"===t.route_type||\"through_obstacle\"===t.route_type?[t.width]:[]),n=e[0];if(void 0!==n\u0026\u0026!e.some(t=\u003eMath.abs(t-n)\u003e1e-9))return n})(t),{traceToSimplify:i,leadingTerminalVias:r,trailingTerminalVias:s}=(t=\u003e{let e=0;for(;\"via\"===t.route[e]?.route_type;)e++;let n=t.route.length;for(;\"jumper\"===t.route[n-1]?.route_type;)n--;let o=n;for(;o\u003ee\u0026\u0026\"via\"===t.route[o-1]?.route_type;)o--;return{traceToSimplify:{...t,route:[...t.route.slice(e,o),...t.route.slice(n)]},leadingTerminalVias:t.route.slice(0,e),trailingTerminalVias:t.route.slice(o,n)}})(t),a=this.preparedInput.connMap.getNetConnectedToId(t.connection_name)??t.connection_name,c=void 0===o?void 0:((t,e)=\u003e{const n=[],o=[],i=[],r=((t,e)=\u003e{for(const e of t)if(\"wire\"===e.route_type||\"through_obstacle\"===e.route_type)return e.width;return e})(t.route,e.defaultTraceThickness);for(let s=0;s\u003ct.route.length;s++){const a=t.route[s];if(\"jumper\"===a.route_type){i.push(Het(a));continue}if(\"wire\"===a.route_type){$et(n,{x:a.x,y:a.y,z:ko(a.layer,e.layerCount),traceThickness:a.width,pcb_port_id:a.start_pcb_port_id??a.end_pcb_port_id});continue}const c=ko(a.from_layer,e.layerCount),l=ko(a.to_layer,e.layerCount),[d,h]=Xet({fromZ:c,toZ:l,previousZ:n.at(-1)?.z,nextZ:Yet(t.route,s,e.layerCount)});if(\"via\"===a.route_type){$et(n,{x:a.x,y:a.y,z:d,traceThickness:r}),$et(n,{x:a.x,y:a.y,z:h,traceThickness:r}),o.push({x:a.x,y:a.y});continue}const u=d===c,p=u?a.start:a.end,m=u?a.end:a.start;$et(n,{...p,z:d,traceThickness:a.width,toNextSegmentType:\"through_obstacle\",...a.circuitJsonMetadata?{toNextSegmentCircuitJsonMetadata:a.circuitJsonMetadata}:{}}),$et(n,{...m,z:h,traceThickness:a.width})}return{connectionName:t.pcb_trace_id,rootConnectionName:e.rootConnectionName,startPcbPortId:Wet(t.route,\"start\"),endPcbPortId:Wet(t.route,\"end\"),traceThickness:r,viaDiameter:Vet(t.route,e.defaultViaDiameter),route:n,vias:o,...i.length\u003e0?{jumpers:i}:{}}})(i,{layerCount:this.preparedInput.srj.layerCount,defaultTraceThickness:o,defaultViaDiameter:n.padDiameter,rootConnectionName:a}),l=c\u0026\u0026c.route.length\u003e=2?c:void 0;if(this.preparedInput.preparedTraces.push({originalTrace:t,mutableHdRoute:l,leadingTerminalVias:r,trailingTerminalVias:s,uniformTraceWidth:o,viaHoleDiameter:Get(t,n.holeDiameter)}),!l)return void this.preparedInput.immutableHdRoutes.push(...oQ(t,e,this.preparedInput.srj.layerCount,n.padDiameter,this.preparedInput.connMap));this.preparedInput.mutableHdRoutes.push(l),this.preparedInput.netByConnectionName.set(l.connectionName,a),this.preparedInput.colorMap[l.connectionName]=this.preparedInput.colorMap[a]??this.preparedInput.colorMap[t.connection_name]??\"#2563eb\";const d={...t,route:[...r,...s]};this.preparedInput.immutableHdRoutes.push(...oQ(d,e,this.preparedInput.srj.layerCount,n.padDiameter,this.preparedInput.connMap))}getOutput(){if(!this.solved)throw new Error(\"Cannot get prepared traces before preparation completes\");return this.preparedInput}},Zet=class extends kt{constructor(t){super(),this.inputProblem=t;const e=t.preparedInput,n=Yo(e.srj);this.traceSimplificationSolver=new vc({hdRoutes:e.mutableHdRoutes,otherHdRoutes:e.immutableHdRoutes,obstacles:e.srj.obstacles,connMap:e.connMap,colorMap:e.colorMap,outline:e.srj.outline,defaultViaDiameter:n.padDiameter,layerCount:e.srj.layerCount,minTraceToPadEdgeClearance:e.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:e.srj.minBoardEdgeClearance,netByConnectionName:e.netByConnectionName,enableCrossingViaReduction:e.options.enableCrossingViaReduction??!0,preserveRouteEndpoints:!0,useTraceWidthAwareClearance:!0,enableVertexShortcuts:e.options.enableVertexShortcuts??!0}),this.traceSimplificationSolver.MAX_SIMPLIFICATION_PIPELINE_LOOPS=e.options.iterations??2,this.activeSubSolver=this.traceSimplificationSolver,this.MAX_ITERATIONS=this.traceSimplificationSolver.MAX_ITERATIONS+1}inputProblem;traceSimplificationSolver;getSolverName(){return\"TraceSimplificationStageSolver\"}_step(){if(this.traceSimplificationSolver.step(),this.progress=this.traceSimplificationSolver.progress,this.stats={...this.traceSimplificationSolver.stats},this.traceSimplificationSolver.failed)return this.error=this.traceSimplificationSolver.error??\"Trace simplification failed\",this.failed=!0,void(this.activeSubSolver=null);this.traceSimplificationSolver.solved\u0026\u0026(this.progress=1,this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error(\"Cannot get simplified routes before cleanup completes\");return structuredClone(this.traceSimplificationSolver.simplifiedHdRoutes)}visualize(){return this.traceSimplificationSolver.visualize()}preview(){return this.traceSimplificationSolver.preview()}},qet=class extends kt{constructor(t){super(),this.inputProblem=t;const e=t.preparedInput;this.drcEngine=new s_(e.srj,{connMap:e.connMap,traceClearance:e.srj.minTraceToPadEdgeClearance??.1,viaClearance:.1}),this.MAX_ITERATIONS=3}inputProblem;drcEngine;phase=\"baseline\";baselineErrorCounts={};outputErrorCounts={};getSolverName(){return\"ValidateTraceSimplificationSolver\"}_step(){return\"baseline\"===this.phase?(this.baselineErrorCounts=this.evaluateErrorCounts(this.inputProblem.preparedInput.originalSrj),this.phase=\"output\",void(this.progress=1/3)):\"output\"===this.phase?(this.outputErrorCounts=this.evaluateErrorCounts(this.inputProblem.outputSrj),this.phase=\"compare\",void(this.progress=2/3)):(this.assertNoNewDrcErrors(),this.stats={baselineErrorCounts:this.baselineErrorCounts,outputErrorCounts:this.outputErrorCounts},this.progress=1,void(this.solved=!0))}evaluateErrorCounts(t){return(t=\u003e{const e={};for(const n of t.errors)e[n.type]=(e[n.type]??0)+1;return e})(this.drcEngine.evaluate(t.traces??[]))}assertNoNewDrcErrors(){const t=[...new Set([...Object.keys(this.baselineErrorCounts),...Object.keys(this.outputErrorCounts)])].filter(t=\u003e(this.outputErrorCounts[t]??0)\u003e(this.baselineErrorCounts[t]??0));if(0===t.length)return;const e=t.map(t=\u003e`${t}: ${this.baselineErrorCounts[t]??0} -\u003e ${this.outputErrorCounts[t]??0}`).join(\", \");throw new Error(`Pipeline 11 simplification introduced DRC errors (${e})`)}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error(\"Cannot get Pipeline 11 output before DRC validation\");return structuredClone(this.inputProblem.outputSrj)}},Jet=class extends Dt{prepareTraceSimplificationSolver;traceSimplificationStageSolver;applyTraceSimplificationSolver;validateTraceSimplificationSolver;pipelineDef=[Lt(\"prepareTraceSimplificationSolver\",Uet,t=\u003e[{inputSrj:t.inputProblem.inputSrj,options:t.inputProblem.options}]),Lt(\"traceSimplificationStageSolver\",Zet,t=\u003e[{preparedInput:t.prepareTraceSimplificationSolver.getOutput()}]),Lt(\"applyTraceSimplificationSolver\",jet,t=\u003e[{preparedInput:t.prepareTraceSimplificationSolver.getOutput(),simplifiedHdRoutes:t.traceSimplificationStageSolver.getOutput()}]),Lt(\"validateTraceSimplificationSolver\",qet,t=\u003e[{preparedInput:t.prepareTraceSimplificationSolver.getOutput(),outputSrj:t.applyTraceSimplificationSolver.getOutput()}])];constructor(t,e={}){if(void 0!==e.iterations\u0026\u0026(!Number.isInteger(e.iterations)||e.iterations\u003c1))throw new Error(\"Simplification iterations must be a positive integer\");super({inputSrj:t,options:{...e}}),this.MAX_ITERATIONS=1e8}getSolverName(){return\"AutoroutingPipelineSolver11_Simplification\"}getConstructorParams(){return[this.inputProblem.inputSrj,this.inputProblem.options]}getOutput(){if(!this.validateTraceSimplificationSolver?.solved)throw new Error(\"Pipeline 11 simplification has not solved yet\");return this.validateTraceSimplificationSolver.getOutput()}getOutputSimpleRouteJson(){return this.getOutput()}getOutputSimplifiedPcbTraces(){return structuredClone(this.getOutput().traces??[])}initialVisualize(){return Ho(this.inputProblem.inputSrj)}finalVisualize(){return Ho(this.getOutput())}},Ket=class extends kc{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e}srj;opts;MAX_SIZE_FOR_SINGLE_LAYER_NODES=2;isObstacleAssignable(t){return Boolean(t?.netIsAssignable)}getOverlappingAssignableObstacles(t){return this.getXYZOverlappingObstacles(t).filter(t=\u003ethis.isObstacleAssignable(t))}shouldNodeBeXYSubdivided(t){return!(t._depth\u003e=this.MAX_DEPTH)\u0026\u0026(!!t._containsTarget||(!(!t._containsObstacle||t._completelyInsideObstacle)||1===t.availableZ.length\u0026\u0026(t.width\u003ethis.MAX_SIZE_FOR_SINGLE_LAYER_NODES||t.height\u003ethis.MAX_SIZE_FOR_SINGLE_LAYER_NODES)))}shouldFilterNodeForObstacle(t){if(!t._containsObstacle)return!1;return!(this.getOverlappingAssignableObstacles(t).length\u003e0)\u0026\u0026(1!==t.availableZ.length||this.shouldFilterSingleLayerNodeForObstacle(t))}insertAssignableObstaclesAsNodes(){const t=this.srj.obstacles.filter(t=\u003ethis.isObstacleAssignable(t)),e=new Map;for(const n of t){const t=[];for(const e of this.finishedNodes){this.getXYZOverlappingObstacles(e).some(t=\u003et===n)\u0026\u0026t.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=\u003e!n.has(t));for(const n of t){const t=e.get(n)||[],o=n.layers\u0026\u0026n.layers.length\u003e0?Array.from(new Set(n.layers.map(t=\u003eko(t,this.srj.layerCount)))).sort((t,e)=\u003et-e):Array.from({length:this.srj.layerCount},(t,e)=\u003ethis.srj.layerCount-e-1);let i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=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,o=e.center.y-e.height/2,c=e.center.y+e.height/2;i=Math.min(i,t),r=Math.max(r,n),s=Math.min(s,o),a=Math.max(a,c)}const c=r-i,l=a-s,d=(i+r)/2,h=(s+a)/2;let u=!1;for(const t of this.srj.connections){for(const e of t.pointsToConnect)if(e.x\u003e=i\u0026\u0026e.x\u003c=r\u0026\u0026e.y\u003e=s\u0026\u0026e.y\u003c=a){u=!0;break}if(u)break}const p={capacityMeshNodeId:`assignable_via_${n.center.x}_${n.center.y}`,center:{x:d,y:h},width:c,height:l,layer:1===o.length?`z${o[0]}`:`z${o.join(\",\")}`,availableZ:o,_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=[],o=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),i=t.availableZ.length\u003e1\u0026\u0026!e;if(e)o.push(t);else{if(i){const e=this.getZSubdivisionChildNodes(t);for(const t of e)!t._containsTarget\u0026\u0026this.shouldFilterNodeForObstacle(t)||(this.shouldNodeBeXYSubdivided(t)?o.push(t):(t._containsObstacle=!1,n.push(t)));continue}this.shouldFilterNodeForObstacle(t)\u0026\u0026!t._containsTarget||n.push(t)}}this.unfinishedNodes.push(...o),this.finishedNodes.push(...n)}},Qet=.005,tnt=class extends si{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\u003e1?(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)=\u003et[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])=\u003et.capacityMeshNodeId),this.nextBatchNodeIds=[],this.batchHadModifications=!1}computeAdjacentNodeIdsForFirstBatch(t){const e=Math.max(...t.map(t=\u003eMath.max(...t.availableZ))),n=[];for(let o=0;o\u003c=e;o++)n.push(new hi(t.filter(t=\u003et.availableZ[0]===o)));for(const e of t){const t=[],o=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of o)n._containsTarget\u0026\u0026n._targetConnectionName!==e._targetConnectionName||e._containsTarget\u0026\u0026(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId\u0026\u0026li(e,n)\u0026\u0026t.push(n);e._adjacentNodeIds=t.map(t=\u003et.capacityMeshNodeId)}}getAdjacentSameLayerUnprocessedNodes(t){const e=[],n=Array.from(new Set((t._adjacentNodeIds??[]).map(t=\u003ethis.nodeMap.get(t)))).filter(e=\u003ee\u0026\u0026e.capacityMeshNodeId!==t.capacityMeshNodeId);n.sort((t,e)=\u003et.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=\u003ethis.nodeMap.get(t))),this.hasComputedAdjacentNodeIds=!0);let t=this.currentBatchNodeIds.pop();for(;t\u0026\u0026this.absorbedNodeIds.has(t);)t=this.currentBatchNodeIds.pop();if(!t)return this.batchHadModifications?(this.currentBatchNodeIds=this.nextBatchNodeIds.sort((t,e)=\u003e{const n=this.nodeMap.get(t),o=this.nodeMap.get(e);return n.width*n.height-o.width*o.height}),this.nextBatchNodeIds=[],void(this.batchHadModifications=!1)):(this.solved=!0,void this.newNodes.push(...this.nextBatchNodeIds.map(t=\u003ethis.nodeMap.get(t))));const e=this.nodeMap.get(t);let n=!1;const o=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===o.length)return void this.nextBatchNodeIds.push(t);const i=t=\u003e{for(const e of t)this.absorbedNodeIds.add(e.capacityMeshNodeId);e._adjacentNodeIds=Array.from(new Set([...e._adjacentNodeIds??[],...t.flatMap(t=\u003et._adjacentNodeIds??[])].filter(t=\u003et!==e.capacityMeshNodeId\u0026\u0026!this.absorbedNodeIds.has(t))))},r=o.filter(t=\u003et.center.x\u003ce.center.x\u0026\u0026Math.abs(t.center.y-e.center.y)\u003ce.height/2);if(r.length\u003e0){const{width:t,height:o}=r[0],s=r.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(r.reduce((t,e)=\u003et+e.height,0)-e.height)\u003cQet\u0026\u0026s\u0026\u0026(e.width+=t,e.center.x=e.center.x-t/2,i(r),n=!0)}const s=o.filter(t=\u003et.center.x\u003ee.center.x\u0026\u0026Math.abs(t.center.y-e.center.y)\u003ce.height/2);if(s.length\u003e0\u0026\u0026!n){const{width:t,height:o}=s[0],r=s.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(s.reduce((t,e)=\u003et+e.height,0)-e.height)\u003cQet\u0026\u0026r\u0026\u0026(e.width+=t,e.center.x=e.center.x+t/2,i(s),n=!0)}const a=o.filter(t=\u003et.center.y\u003ee.center.y\u0026\u0026Math.abs(t.center.x-e.center.x)\u003ce.width/2);if(a.length\u003e0\u0026\u0026!n){const{width:t,height:o}=a[0],r=a.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(a.reduce((t,e)=\u003et+e.width,0)-e.width)\u003cQet\u0026\u0026r\u0026\u0026(e.height+=o,e.center.y=e.center.y+o/2,i(a),n=!0)}const c=o.filter(t=\u003et.center.y\u003ce.center.y\u0026\u0026Math.abs(t.center.x-e.center.x)\u003ce.width/2);if(c.length\u003e0\u0026\u0026!n){const{width:t,height:o}=c[0],r=c.every(e=\u003ee.width===t\u0026\u0026e.height===o);Math.abs(c.reduce((t,e)=\u003et+e.width,0)-e.width)\u003cQet\u0026\u0026r\u0026\u0026(e.height+=o,e.center.y=e.center.y-o/2,i(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(Dc(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e\u0026\u0026(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const o of this.currentBatchNodeIds){const i=this.nodeMap.get(o);if(!this.absorbedNodeIds.has(o)\u0026\u0026i){const r=Dc(i,{rectMargin:.01});o===e?r.stroke=\"rgba(0, 255, 0, 0.8)\":n?.some(t=\u003et.capacityMeshNodeId===o)?r.stroke=\"rgba(128, 0, 128, 0.8)\":r.stroke=\"rgba(255, 165, 0, 0.8)\",r.layer=`z${i.availableZ.join(\",\")}`,r.label=`${r.label}\\n(unprocessed)`,t.rects.push(r)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)\u0026\u0026n){const e=Dc(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}},ent=class extends si{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,o=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;const s=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,l=t.center.y-t.height/2,d=t.center.y+t.height/2;n=Math.min(n,e),o=Math.max(o,c),i=Math.min(i,l),r=Math.max(r,d);for(const e of t.availableZ)s.add(e);t._containsTarget\u0026\u0026(a=!0)}const c=o-n,l=r-i,d=(n+o)/2,h=(i+r)/2,u=Array.from(s).sort((t,e)=\u003et-e),p={capacityMeshNodeId:`merged_via_${t.center.x}_${t.center.y}`,center:{x:d,y:h},width:c,height:l,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=Dc(e);e._assignedViaObstacle\u0026\u0026(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=Dc(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}},nnt=class extends si{constructor(t){const{simpleRouteJson:e,nodes:n,edges:o,colorMap:i,MAX_ITERATIONS:r=1e6,hyperParameters:s={}}=t;super(),this.inputParams=t,this.hyperParameters=s,this.MAX_ITERATIONS=r,this.simpleRouteJson=e,this.nodes=n,this.edges=o,this.colorMap=i??{},this.nodeMap=new Map(this.nodes.map(t=\u003e[t.capacityMeshNodeId,t])),this.nodeEdgeMap=ai(this.edges);const a=this.nodes.filter(t=\u003et._containsTarget);this.unprocessedConnectionPairs=Xi(this.simpleRouteJson.connections.map(t=\u003e{const[e,n]=t.pointsToConnect;return{start:a.find(t=\u003exe(t.center,e)\u003ct.width/2),end:a.find(t=\u003exe(t.center,n)\u003ct.width/2),connection:t}}),this.hyperParameters.SHUFFLE_SEED??0),this.viaNodes=this.nodes.filter(t=\u003et.availableZ.length\u003e1)}inputParams;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=\u003e!t._completelyInsideObstacle\u0026\u0026!t._containsObstacle).filter(t=\u003e!this.usedNodeMap.has(t.capacityMeshNodeId));if(e.length\u003e0){const n=e.reduce((e,n)=\u003e{const o=this._dist(e,t.start);return this._dist(n,t.start)\u003co?n:e});this.closestViaForConnectionStartMap.set(t,n);const o=e.reduce((e,n)=\u003e{const o=this._dist(e,t.end);return this._dist(n,t.end)\u003co?n:e});this.closestViaForConnectionEndMap.set(t,o)}}}_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\u0026\u0026!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\u0026\u0026(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\u0026\u00260===this.visitedNodes.size){const t=this._dist(e,n),o={prevCandidate:null,node:e,g:0,h:t,f:this.GREEDY_MULTIPLIER*t};this.queuedCandidateNodes.push(o)}let o;for(this.queuedCandidateNodes.sort((t,e)=\u003et.f-e.f);this.queuedCandidateNodes.length\u0026\u0026!o;){const t=this.queuedCandidateNodes.shift();this.visitedNodes.has(t.node.capacityMeshNodeId)||(o=t)}if(!o)return this.failed=!0,void(this.error=\"No viable candidates left\");if(this.visitedNodes.add(o.node.capacityMeshNodeId),o.node.capacityMeshNodeId===n.capacityMeshNodeId){const e=[];let n=o;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 i=this.getNeighbors(o.node);for(const t of i){const e=t.capacityMeshNodeId;if(this.visitedNodes.has(e))continue;const i=this.computeG(o,t,n),r=this.computeH(o,t,n),s=i+this.GREEDY_MULTIPLIER*r,a=this.queuedCandidateNodes.findIndex(t=\u003et.node.capacityMeshNodeId===e);if(a\u003e=0){if(this.queuedCandidateNodes[a].g\u003c=i)continue;this.queuedCandidateNodes.splice(a,1)}this.queuedCandidateNodes.push({prevCandidate:o,node:t,g:i,h:r,f:s})}}getNeighbors(t){const e=new Set,n=this.nodeEdgeMap.get(t.capacityMeshNodeId)??[];for(const o of n){const[n,i]=o.nodeIds,r=n===t.capacityMeshNodeId?i:n,s=this.nodeMap.get(r);s\u0026\u0026e.add(s)}const o=this.activeSubpath?.layer;return Array.from(e).filter(t=\u003e!(t.capacityMeshNodeId!==this.activeSubpath?.end.capacityMeshNodeId)||!t._containsObstacle\u0026\u0026(!t._containsTarget\u0026\u0026(!this.usedNodeMap.has(t.capacityMeshNodeId)\u0026\u0026!(void 0!==o\u0026\u0026!t.availableZ.includes(o)))))}clearCandidateNodes(){this.queuedCandidateNodes=[],this.visitedNodes=new Set}computeG(t,e,n){const o=this._dist(t.node,e);return t.g+o}computeH(t,e,n){return this._dist(e,n)}createSolvedRoute(t,e){const n=[];for(let e=0;e\u003ct.length;e++){const o=t[e];o.path?0===e?n.push(...o.path):n.push(...o.path.slice(1)):(0===e\u0026\u0026n.push(o.start),e===t.length-1\u0026\u0026n.push(o.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,$i(e.reduce((t,e)=\u003et+16807*e%2147483647,0))()\u003cn))return[{start:t.start,end:t.end,solved:!1,layer:t.start.availableZ[0]??0}];const o=this.getClosestVia(t.start),i=this.getFarVia(o,t.end),r=t.start.availableZ[0]??0,s=t.end.availableZ[0]??0,a=[];return a.push({start:t.start,end:o,solved:!1,layer:r}),r===s?(a.push({start:o,end:i,solved:!1,layer:0===r?1:0}),a.push({start:i,end:t.end,solved:!1,layer:s})):a.push({start:o,end:t.end,solved:!1,layer:s}),a}getClosestVia(t){if(0===this.viaNodes.length)return t;const e=new Set;for(const[t,n]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair\u0026\u0026e.add(n.capacityMeshNodeId);for(const[t,n]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair\u0026\u0026e.add(n.capacityMeshNodeId);const n=this.viaNodes.filter(t=\u003e!t._completelyInsideObstacle\u0026\u0026!t._containsObstacle).filter(t=\u003e!this.usedNodeMap.has(t.capacityMeshNodeId)).filter(t=\u003e!e.has(t.capacityMeshNodeId));if(0===n.length){const e=this.viaNodes.filter(t=\u003e!t._completelyInsideObstacle\u0026\u0026!t._containsObstacle).filter(t=\u003e!this.usedNodeMap.has(t.capacityMeshNodeId));return 0===e.length?t:(e.sort((e,n)=\u003ethis._dist(e,t)-this._dist(n,t)),e[0])}n.sort((e,n)=\u003ethis._dist(e,t)-this._dist(n,t));const o=this.hyperParameters.MAX_CLOSEST_VIA_SKIP??0;if(o\u003e0\u0026\u0026n.length\u003e1){const t=$i((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length),e=Math.floor(t()*(o+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,o=new Set;for(const[t,e]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair\u0026\u0026o.add(e.capacityMeshNodeId);for(const[t,e]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair\u0026\u0026o.add(e.capacityMeshNodeId);const i=this.viaNodes.filter(e=\u003e!this.usedNodeMap.has(e.capacityMeshNodeId)\u0026\u0026e.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026!e._completelyInsideObstacle\u0026\u0026!e._containsObstacle\u0026\u0026!o.has(e.capacityMeshNodeId)\u0026\u0026this._dist(e,t)\u003e=n);if(0===i.length){const o=this.viaNodes.filter(e=\u003ee.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026!e._completelyInsideObstacle\u0026\u0026!e._containsObstacle\u0026\u0026!this.usedNodeMap.has(e.capacityMeshNodeId)\u0026\u0026this._dist(e,t)\u003e=n).sort((t,n)=\u003ethis._dist(t,e)-this._dist(n,e));if(o.length\u003e0)return o[0];return this.viaNodes.filter(e=\u003ee.capacityMeshNodeId!==t.capacityMeshNodeId\u0026\u0026!e._completelyInsideObstacle\u0026\u0026!e._containsObstacle\u0026\u0026!this.usedNodeMap.has(e.capacityMeshNodeId)).sort((t,n)=\u003ethis._dist(t,e)-this._dist(n,e))[0]??t}i.sort((t,n)=\u003ethis._dist(t,e)-this._dist(n,e));const r=this.hyperParameters.MAX_FURTHEST_VIA_SKIP??0;if(r\u003e0\u0026\u0026i.length\u003e1){const t=$i((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length+1e3),e=Math.floor(t()*(r+1));return i[Math.min(e,i.length-1)]}return i[0]}getCapacityPaths(){const t=[];for(const e of this.solvedRoutes){const n=e.path;n\u0026\u0026n.length\u003e0\u0026\u0026t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,nodeIds:n.map(t=\u003et.capacityMeshNodeId)})}return t}visualize(){const t={lines:[],points:[],rects:[],circles:[]},e=t=\u003e!!t\u0026\u0026\"number\"==typeof t.x\u0026\u0026\"number\"==typeof t.y\u0026\u0026!Number.isNaN(t.x)\u0026\u0026!Number.isNaN(t.y)\u0026\u0026Number.isFinite(t.x)\u0026\u0026Number.isFinite(t.y),n=t=\u003e\"number\"==typeof t\u0026\u0026!Number.isNaN(t)\u0026\u0026Number.isFinite(t);for(const o of this.nodes){const i=this.queuedCandidateNodes.some(t=\u003et.node.capacityMeshNodeId===o.capacityMeshNodeId),r=this.queuedCandidateNodes.find(t=\u003et.node.capacityMeshNodeId===o.capacityMeshNodeId);if(e(o.center)\u0026\u0026n(o.width)\u0026\u0026n(o.height)){const e=Dc(o,{rectMargin:.025,zOffset:.01});t.rects.push({...e,fill:i?\"rgba(255, 128, 255, 0.5)\":o._containsTarget?\"rgba(0, 150, 255, 0.15)\":o._containsObstacle?\"rgba(255, 0, 0, 0.1)\":\"rgba(200, 200, 200, 0.05)\",label:[`ID: ${o.capacityMeshNodeId}`,`Size: ${o.width.toFixed(2)}x${o.height.toFixed(2)}`,`Z: ${o.availableZ.join(\", \")}`,r?`g: ${r.g.toFixed(2)}`:\"\",r?`h: ${r.h.toFixed(2)}`:\"\",r?`f: ${r.f.toFixed(2)}`:\"\",o._containsTarget?\"TARGET\":\"\",o._containsObstacle?\"OBSTACLE\":\"\"].filter(t=\u003et).join(\"\\n\")})}}for(const n of this.edges){const[o,i]=n.nodeIds,r=this.nodeMap.get(o),s=this.nodeMap.get(i);r?.center\u0026\u0026s?.center\u0026\u0026e(r.center)\u0026\u0026e(s.center)\u0026\u0026t.lines.push({points:[r.center,s.center],strokeColor:\"rgba(150, 150, 150, 0.2)\"})}for(let n=0;n\u003cthis.solvedRoutes.length;n++){const o=this.solvedRoutes[n],i=o.path,r=\"blue\";for(let o=0;o\u003ci.length-1;o++){const s=i[o],a=i[o+1];if(s?.center\u0026\u0026a?.center\u0026\u0026e(s.center)\u0026\u0026e(a.center)){const e=s.availableZ.includes(1)\u0026\u0026a.availableZ.includes(1),o=n%5*.02;t.lines.push({points:[{x:s.center.x+o,y:s.center.y+o},{x:a.center.x+o,y:a.center.y+o}],strokeColor:r,strokeDash:e?\"5 5\":void 0})}}if(i.length\u003e0){const n=i[0],r=i[i.length-1];n?.center\u0026\u0026e(n.center)\u0026\u0026t.points.push({x:n.center.x,y:n.center.y,label:`START: ${o.connection.name}`}),r?.center\u0026\u0026e(r.center)\u0026\u0026t.points.push({x:r.center.x,y:r.center.y,label:`END: ${o.connection.name}`})}}if(this.solvedSubpaths)for(let n=0;n\u003cthis.solvedSubpaths.length;n++){const o=this.solvedSubpaths[n];if(o.path\u0026\u0026o.path.length\u003e1)for(let n=0;n\u003co.path.length-1;n++){const i=o.path[n],r=o.path[n+1];i?.center\u0026\u0026r?.center\u0026\u0026e(i.center)\u0026\u0026e(r.center)\u0026\u0026t.lines.push({points:[i.center,r.center],strokeColor:\"green\",strokeDash:1===o.layer?\"3 3\":void 0})}}if(this.activeSubpath){const n=this.activeSubpath.start?.center,o=this.activeSubpath.end?.center;n\u0026\u0026o\u0026\u0026e(n)\u0026\u0026e(o)\u0026\u0026(t.lines.push({points:[n,o],strokeColor:\"orange\",strokeDash:\"5 5\"}),t.points.push({x:n.x,y:n.y,label:\"ACTIVE START\"}),t.points.push({x:o.x,y:o.y,label:\"ACTIVE END\"}))}const o=this.queuedCandidateNodes.slice(0,10).sort((t,e)=\u003et.f-e.f);for(let n=0;n\u003co.length;n++){const i=.6*(1-n/10),r=[];let s=o[n];for(;s;)r.push(s.node),s=s.prevCandidate;if(r.reverse(),r.length\u003e1){const n=r.map(t=\u003et.center).filter(t=\u003ee(t));n.length\u003e1\u0026\u0026t.lines.push({points:n,strokeColor:To(\"purple\",1-i),strokeDash:1===this.activeSubpath?.layer?\"4 2\":void 0})}}if(this.activeConnectionPair){const n=this.activeConnectionPair.start?.center,o=this.activeConnectionPair.end?.center;n\u0026\u0026o\u0026\u0026e(n)\u0026\u0026e(o)\u0026\u0026t.lines.push({points:[n,o],strokeColor:\"cyan\",strokeDash:\"20 5\"})}if(this.ogUnprocessedSubpaths\u0026\u00263===this.ogUnprocessedSubpaths.length){const[,o]=this.ogUnprocessedSubpaths;if(o.start?.center\u0026\u0026e(o.start.center)){const e=Math.max(o.start.width||0,o.start.height||0);n(e)\u0026\u0026e\u003e0\u0026\u0026(t.circles.push({center:o.start.center,radius:e,stroke:\"blue\"}),t.points.push({x:o.start.center.x,y:o.start.center.y,label:\"DIRECTIVE VIA 1\"}))}if(o.end?.center\u0026\u0026e(o.end.center)){const e=Math.max(o.end.width||0,o.end.height||0);n(e)\u0026\u0026e\u003e0\u0026\u0026(t.circles.push({center:o.end.center,radius:e,stroke:\"purple\"}),t.points.push({x:o.end.center.x,y:o.end.center.y,label:\"DIRECTIVE VIA 2\"}))}}if(this.queuedCandidateNodes.length\u003e0)for(const n of this.queuedCandidateNodes){const o=n.node;o?.center\u0026\u0026e(o.center)\u0026\u0026t.circles.push({center:o.center,radius:.05,fill:\"rgba(255, 255, 0, 0.6)\",stroke:\"yellow\"})}if(this.visitedNodes.size\u003e0)for(const n of this.visitedNodes){const o=this.nodeMap.get(n);o?.center\u0026\u0026e(o.center)\u0026\u0026t.circles.push({center:o.center,radius:.08,fill:\"rgba(128, 128, 128, 0.5)\",stroke:\"gray\"})}return t}},ont=class extends ys{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,o=e\u003e0?n/e:0;return t.iterations/t.MAX_ITERATIONS+(1-o)}computeH(t){const e=t.unprocessedConnectionPairs.length+t.solvedRoutes.length+(t.activeConnectionPair?1:0),n=t.solvedRoutes.length;return e\u003e0?1-n/e:0}generateSolver(t){return new nnt({...this.constructorParams,hyperParameters:{...this.constructorParams.hyperParameters,...t}})}};function int(t){const e=new Map;for(const n of t)e.set(n.capacityMeshNodeId,n);return e}function rnt(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}var snt=class extends si{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=int(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\u0026\u0026e.offBoardConnectsTo.length\u003e0\u0026\u0026this.assignableNodes.push(t)}}initializePendingEdges(){const t=new Map;for(const e of this.assignableNodes){const n=e._assignedViaObstacle;if(n?.offBoardConnectsTo)for(const o of n.offBoardConnectsTo)t.has(o)||t.set(o,[]),t.get(o).push(e)}this.pendingEdges=[];for(const[e,n]of t)if(n.length\u003e1)for(let t=0;t\u003cn.length;t++)for(let o=t+1;o\u003cn.length;o++)this.pendingEdges.push({node1:n[t],node2:n[o],netName:e})}_step(){switch(this.animationState){case\"showing_nodes\":if(this.assignableNodes.length\u003e0){const t=this.assignableNodes.shift();this.shownNodes.push(t)}else this.animationState=\"showing_edges\";break;case\"showing_edges\":if(this.pendingEdges.length\u003e0){const{node1:t,node2:e,netName:n}=this.pendingEdges.shift(),o=this.createOffboardEdge(t,e,n);this.enhancedEdges.push(o),this.createdEdges.push(o)}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=[],o=new Set(this.shownNodes.map(t=\u003et.capacityMeshNodeId));for(const e of this.capacityEdges){if(e.isOffboardEdge)continue;if(o.has(e.nodeIds[0])||o.has(e.nodeIds[1])){const n=this.nodeMap.get(e.nodeIds[0]),o=this.nodeMap.get(e.nodeIds[1]);n\u0026\u0026o\u0026\u0026t.push({points:[n.center,o.center],strokeColor:\"rgba(0, 200, 0, 0.5)\",strokeWidth:.05})}}for(let t=0;t\u003cthis.shownNodes.length;t++){const o=this.shownNodes[t],i=o._assignedViaObstacle,r=t===this.shownNodes.length-1\u0026\u0026\"showing_nodes\"===this.animationState;n.push({center:o.center,width:o.width,height:o.height,fill:r?\"rgba(255, 165, 0, 0.5)\":\"rgba(173, 216, 230, 0.5)\",stroke:r?\"orange\":\"blue\",strokeWidth:r?.15:.1}),e.push({x:o.center.x,y:o.center.y,color:r?\"orange\":\"blue\",label:`${r?\"NEW: \":\"\"}${o.capacityMeshNodeId}\\n${i?.offBoardConnectsTo?.join(\", \")||\"\"}`})}for(let n=0;n\u003cthis.createdEdges.length;n++){const o=this.createdEdges[n],i=n===this.createdEdges.length-1\u0026\u0026\"showing_edges\"===this.animationState,r=this.nodeMap.get(o.nodeIds[0]),s=this.nodeMap.get(o.nodeIds[1]);if(r\u0026\u0026s){t.push({points:[r.center,s.center],strokeColor:i?\"red\":\"orange\",strokeWidth:i?.2:.1,strokeDasharray:\"0.3,0.15\"});const n=rnt(r.center,s.center);e.push({x:n.x,y:n.y,color:i?\"red\":\"orange\",label:`${i?\"NEW: \":\"\"}⚡ ${o.offboardNetName}`})}}let i=\"Offboard Capacity Node Solver\";switch(this.animationState){case\"showing_nodes\":i+=` - Showing nodes (${this.shownNodes.length}/${this.shownNodes.length+this.assignableNodes.length})`;break;case\"showing_edges\":i+=` - Creating edges (${this.createdEdges.length}/${this.createdEdges.length+this.pendingEdges.length})`;break;case\"done\":i+=` - Done (${this.shownNodes.length} nodes, ${this.createdEdges.length} edges)`}return{lines:t,points:e,rects:n,title:i}}getVirtualOffboardNodes(){return[]}getOffboardEdges(){return this.enhancedEdges.filter(t=\u003et.isOffboardEdge)}},ant=class extends si{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:o}){super(),this.inputPaths=[...t],this.capacityEdges=e,this.originalConnections=o,this.nodeMap=int(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=\u003et.isFragmentedPath)?this.animationState=\"showing_fragment\":this.fragmentedPaths.push(...this.currentFragments);break;case\"showing_fragment\":if(this.currentFragmentIndex\u003cthis.currentFragments.length){const t=this.currentFragments[this.currentFragmentIndex];this.fragmentedPaths.push(t),this.currentFragmentIndex++}else this.currentPath\u0026\u0026(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=\u003ee.name===t.connectionName);if(n)for(let t=0;t\u003ce.length;t++){const o=e[t];if(!o.isFragmentedPath)continue;const i=n.pointsToConnect.filter(t=\u003e{for(const e of o.nodeIds){const n=this.nodeMap.get(e);if(n\u0026\u0026Xj(t,n))return!0}return!1}),r=0===t,s=r?o.nodeIds[o.nodeIds.length-1]:o.nodeIds[0],a=this.nodeMap.get(s);if(i.length\u003e0\u0026\u0026a){const t=i[0],e={x:a.center.x,y:a.center.y,layer:bo(t)},s=r?[...i,e]:[e,...i];this.fragmentedConnections.push({name:o.connectionName,pointsToConnect:s,__netConnectionName:n.__netConnectionName,__rootConnectionNames:n.__rootConnectionNames})}}}splitPath(t){const{nodeIds:e}=t;if(e.length\u003c2)return[t];const n=[];for(let t=0;t\u003ce.length-1;t++){const o=this.capacityEdges.find(n=\u003en.nodeIds[0]===e[t]\u0026\u0026n.nodeIds[1]===e[t+1]||n.nodeIds[0]===e[t+1]\u0026\u0026n.nodeIds[1]===e[t]);o\u0026\u0026o.isOffboardEdge\u0026\u0026n.push(t)}if(0===n.length)return[t];const o=[];let i=0,r=0;for(const s of n){const n=e.slice(i,s+1);if(n.length\u003e=1){const e=this.nextFragmentId++;o.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${r++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}i=s+1}if(i\u003ce.length){const n=e.slice(i);if(n.length\u003e=1){const e=this.nextFragmentId++;o.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${r++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}}return o.length\u003e0?o:[t]}getFragmentedPaths(){return this.fragmentedPaths}getFragmentedConnections(){return this.fragmentedConnections}getFragmentedOriginalConnectionNames(){return this.fragmentedOriginalConnectionNames}visualize(){const t=[],e=[],n=[];if(\"showing_original_path\"===this.animationState\u0026\u0026this.currentPath\u0026\u0026this.drawPath({path:this.currentPath,color:\"gray\",lines:t,points:e,rects:n,labelPrefix:\"Original: \"}),this.fragmentedPaths.forEach((o,i)=\u003e{if(o.isFragmentedPath){const r=i%2==0?\"blue\":\"red\";this.drawPath({path:o,color:r,lines:t,points:e,rects:n,labelPrefix:`Frag ${i}: `})}else this.drawPath({path:o,color:\"green\",lines:t,points:e,rects:n,labelPrefix:\"\"})}),\"showing_fragment\"===this.animationState\u0026\u0026this.currentFragmentIndex\u003e0){const o=this.fragmentedPaths.length-1;if(o\u003e=0){const i=this.fragmentedPaths[o];i.isFragmentedPath\u0026\u0026this.drawPath({path:i,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]),o=this.nodeMap.get(e.nodeIds[1]);n\u0026\u0026o\u0026\u0026t.push({points:[n.center,o.center],strokeColor:\"orange\",strokeWidth:.15,strokeDasharray:\"0.3,0.15\"})}let o=\"Offboard Path Fragment Solver\";return\"showing_original_path\"===this.animationState?o+=\" - Analyzing path...\":\"showing_fragment\"===this.animationState?o+=` - Fragment ${this.currentFragmentIndex}/${this.currentFragments.length}`:o+=` - Done (${this.fragmentedPaths.filter(t=\u003et.isFragmentedPath).length} fragments)`,{lines:t,points:e,rects:n,title:o}}drawPath(t){const{path:e,color:n,lines:o,points:i,rects:r,labelPrefix:s}=t,a=[];for(let t=0;t\u003ce.nodeIds.length;t++){const o=e.nodeIds[t],c=this.nodeMap.get(o);c\u0026\u0026(a.push(c.center),r.push({center:c.center,width:.8*c.width,height:.8*c.height,stroke:n,strokeWidth:.05,fill:`${n}33`}),0!==t\u0026\u0026t!==e.nodeIds.length-1||i.push({x:c.center.x,y:c.center.y,color:n,label:`${s}${e.connectionName}\\n${o}`}))}a.length\u003e1\u0026\u0026o.push({points:a,strokeColor:n,strokeWidth:.1})}};function cnt(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var lnt=class extends si{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,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),r=n.targetMinCapacity??.5;n.capacityDepth=$s(i,r)}this.connMap=ii(t),this.colorMap=wo(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;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=[cnt(\"netToPointPairsSolver\",ma,t=\u003e[t.srj,t.colorMap,ri(t.srj)],{onSolved:t=\u003e{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,this.connMap),t.connMap=ii(t.srjWithPointPairs)}}),cnt(\"nodeSolver\",Ket,t=\u003e[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=\u003e{t.capacityNodes=t.nodeSolver?.finishedNodes}}),cnt(\"mergeAssignableViaNodes\",ent,t=\u003e[t.nodeSolver?.finishedNodes],{onSolved:t=\u003e{t.capacityNodes=t.mergeAssignableViaNodes?.newNodes}}),cnt(\"singleLayerNodeMerger\",tnt,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),cnt(\"edgeSolver\",ui,t=\u003e[t.capacityNodes],{onSolved:t=\u003e{t.capacityEdges=t.edgeSolver?.edges}}),cnt(\"offboardCapacityNodeSolver\",snt,t=\u003e[{capacityNodes:t.capacityNodes,capacityEdges:t.capacityEdges||[]}],{onSolved:t=\u003e{t.capacityEdges=t.offboardCapacityNodeSolver?.enhancedEdges||t.capacityEdges}}),cnt(\"deadEndSolver\",Qc,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges}],{onSolved:t=\u003e{const e=t.deadEndSolver?.removedNodeIds;t.capacityNodes=t.capacityNodes.filter(t=\u003e!e.has(t.capacityMeshNodeId)),t.capacityEdges=t.capacityEdges.filter(t=\u003et.nodeIds.every(t=\u003e!e.has(t)))}}),cnt(\"initialPathingHyperSolver\",ont,t=\u003e[{simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,hyperParameters:{MAX_CAPACITY_FACTOR:1}}],{onSolved:t=\u003e{const e=t.initialPathingHyperSolver?.winningSolver;e\u0026\u0026(t.initialPathingSolver=e)}}),cnt(\"offboardPathFragmentSolver\",ant,t=\u003e[{capacityPaths:t.initialPathingSolver?.getCapacityPaths()||[],capacityEdges:t.capacityEdges||[],capacityNodes:t.capacityNodes||[],connections:t.srjWithPointPairs?.connections||[]}],{onSolved:t=\u003e{const e=t.offboardPathFragmentSolver;if(!e)return;const n=e.getFragmentedPaths();for(const e of n)if(e.isFragmentedPath\u0026\u0026e.mstPairConnectionName){const n=t.colorMap[e.mstPairConnectionName];n\u0026\u0026!t.colorMap[e.connectionName]\u0026\u0026(t.colorMap[e.connectionName]=n)}const o=e.getFragmentedOriginalConnectionNames(),i=e.getFragmentedConnections();o.size\u003e0\u0026\u0026t.srjWithPointPairs\u0026\u0026(t.srjWithPointPairs={...t.srjWithPointPairs,connections:[...t.srjWithPointPairs.connections.filter(t=\u003e!o.has(t.name)),...i]},t.connMap=ii(t.srjWithPointPairs))}}),cnt(\"edgeToPortSegmentSolver\",Nc,t=\u003e[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.offboardPathFragmentSolver?.getFragmentedPaths()||t.initialPathingSolver?.getCapacityPaths()||[],colorMap:t.colorMap}]),cnt(\"segmentToPointSolver\",Lc,t=\u003e{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments\u0026\u0026t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=\u003e{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),cnt(\"unravelMultiSectionSolver\",gl,t=\u003e[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),cnt(\"highDensityRouteSolver\",zs,t=\u003e[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap}]),cnt(\"highDensityStitchSolver\",Ca,t=\u003e[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),cnt(\"uselessViaRemovalSolver1\",Xa,t=\u003e[{unsimplifiedHdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount,connMap:t.connMap}]),cnt(\"multiSimplifiedPathSolver1\",Za,t=\u003e[{unsimplifiedHdRoutes:t.uselessViaRemovalSolver1?.getOptimizedHdRoutes()||t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline}]),cnt(\"uselessViaRemovalSolver2\",Xa,t=\u003e[{unsimplifiedHdRoutes:t.multiSimplifiedPathSolver1.simplifiedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount,connMap:t.connMap}]),cnt(\"multiSimplifiedPathSolver2\",Za,t=\u003e[{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\u0026\u0026(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\u0026\u0026this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),o=this.mergeAssignableViaNodes?.visualize(),i=this.singleLayerNodeMerger?.visualize(),r=this.strawSolver?.visualize(),s=this.edgeSolver?.visualize(),a=(this.offboardCapacityNodeSolver?.visualize(),this.deadEndSolver?.visualize()),c=this.initialPathingSolver?.visualize(),l=this.offboardPathFragmentSolver?.visualize(),d=this.pathingOptimizer?.visualize(),h=this.edgeToPortSegmentSolver?.visualize(),u=this.segmentToPointSolver?.visualize(),p=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),m=this.highDensityRouteSolver?.visualize(),g=this.highDensityStitchSolver?.visualize(),f=this.uselessViaRemovalSolver1?.visualize(),y=this.uselessViaRemovalSolver2?.visualize(),_=this.multiSimplifiedPathSolver1?.visualize(),b=this.multiSimplifiedPathSolver2?.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\u0026\u0026x.length\u003e=2){const t=x.map(t=\u003e({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:\"rgba(0, 136, 255, 0.95)\"})}const S=Oo(this.srj),I={points:[...this.srj.connections.flatMap(t=\u003et.pointsToConnect.map(e=\u003e({...e,layer:Fo(e,this.srj.layerCount),label:`${t.name} ${e.pcb_port_id??\"\"}`})))],rects:[...(this.srj.obstacles??[]).filter(t=\u003e!t.isCopperPour).map(t=\u003e({...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)\",layer:jo(t,this.srj.layerCount),label:S(t)}))],lines:v},C=[I,t,e,n,o,i,r,s,a,c,l,d,h,u,p,m?pi(I,m):null,g,f,_,y,b,this.solved?pi({lines:v},Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...C)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e\u003e=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=\u003e({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length\u003e200)break}return{lines:t}}if(this.pathingOptimizer){const t=[];for(const e of this.pathingOptimizer.connectionsWithNodes)e.path\u0026\u0026t.push({points:e.path.map(t=\u003e({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 o of n){const n=o.__netConnectionName,i=o.__rootConnectionNames?.[0],r=e.filter(t=\u003et.connectionName===o.name);for(let e=0;e\u003cr.length;e++){const s=r[e],a={type:\"pcb_trace\",pcb_trace_id:`${o.name}_${e}`,connection_name:n??i??o.name,route:Mo(s,this.srj.layerCount)};t.push(a)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},dnt=1e-9,hnt=t=\u003e(t=\u003e\"wire\"===t.route_type)(t)||(t=\u003e\"via\"===t.route_type)(t)?t:(t=\u003e\"through_obstacle\"===t.route_type)(t)\u0026\u0026Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y)\u003c=dnt?{route_type:t.route_type,x:t.start.x,y:t.start.y,from_layer:t.from_layer,to_layer:t.to_layer,width:t.width}:null,unt=(t,e)=\u003et.layer??e.layer??t.to_layer??e.from_layer??t.from_layer??e.to_layer??\"top\",pnt=(t,e,n)=\u003et.width??e.width??n,mnt=(t,e,n,o,i)=\u003e({x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n,layer:o,width:i}),gnt=(t,e)=\u003e({...t,x:Math.abs(t.x-e.minX)\u003c1e-6?e.minX:Math.abs(t.x-e.maxX)\u003c1e-6?e.maxX:t.x,y:Math.abs(t.y-e.minY)\u003c1e-6?e.minY:Math.abs(t.y-e.maxY)\u003c1e-6?e.maxY:t.y}),fnt=({x:t,y:e,layer:n})=\u003e({x:t,y:e,layer:n}),ynt=({x:t,y:e,layer:n,width:o})=\u003e({route_type:\"wire\",x:t,y:e,layer:n,width:o}),_nt=(t,e,n)=\u003e{const o=e.x-t.x,i=e.y-t.y;let r=0,s=1;const a=(t,e)=\u003e{if(Math.abs(t)\u003cdnt)return e\u003e=0;const n=e/t;if(t\u003c0){if(n\u003es)return!1;n\u003er\u0026\u0026(r=n)}else{if(n\u003cr)return!1;n\u003cs\u0026\u0026(s=n)}return!0};return a(-o,t.x-n.minX)\u0026\u0026a(o,n.maxX-t.x)\u0026\u0026a(-i,t.y-n.minY)\u0026\u0026a(i,n.maxY-t.y)?{startT:r,endT:s}:null},bnt=(t,e)=\u003et.x\u003e=e.minX-1e-6\u0026\u0026t.x\u003c=e.maxX+1e-6\u0026\u0026t.y\u003e=e.minY-1e-6\u0026\u0026t.y\u003c=e.maxY+1e-6\u0026\u0026(Math.abs(t.x-e.minX)\u003c=1e-6||Math.abs(t.x-e.maxX)\u003c=1e-6||Math.abs(t.y-e.minY)\u003c=1e-6||Math.abs(t.y-e.maxY)\u003c=1e-6),xnt=(t,e,n,o,i)=\u003e{var r,s;(r=o,s=i,Math.hypot(r.x-s.x,r.y-s.y)\u003c=dnt)||t.push({type:\"pcb_trace\",pcb_trace_id:`${e.pcb_trace_id}_keep_${n}`,connection_name:e.connection_name,route:[ynt(o),ynt(i)]})},vnt=({obstacleId:t,start:e,end:n,layer:o,width:i})=\u003e{const r=n.x-e.x,s=n.y-e.y,a=Math.hypot(r,s);return a\u003ei+dnt?null:{obstacleId:t,type:\"rect\",layers:[o],center:{x:(e.x+n.x)/2,y:(e.y+n.y)/2},width:a,height:i,ccwRotationDegrees:180*Math.atan2(s,r)/Math.PI,connectedTo:[]}},Snt=({connection:t,point:e,endpointIndex:n})=\u003e({obstacleId:`${t.name}_route_endpoint_${n}`,type:\"rect\",layers:[e.layer],center:{x:e.x,y:e.y},width:e.width,height:e.width,connectedTo:[t.name,t.__rootConnectionNames?.[0]??t.name]}),Int=({trace:t,ripIndex:e,start:n,end:o,region:i,allowInteriorStart:r,allowInteriorEnd:s})=\u003e{if(!r\u0026\u0026!bnt(n,i)||!s\u0026\u0026!bnt(o,i))return null;const a=(({trace:t,ripIndex:e,start:n,end:o})=\u003e({name:`${t.connection_name}_reroute_${t.pcb_trace_id}_${e}`,__rootConnectionNames:[t.connection_name],pointsToConnect:[fnt(n),fnt(o)]}))({trace:t,ripIndex:e,start:n,end:o});return{connection:a,endpointObstacles:[Snt({connection:a,point:n,endpointIndex:0}),Snt({connection:a,point:o,endpointIndex:1})]}},Cnt=(t,e,n)=\u003e{const o=[],i=[],r=[],s=[];let a=null,c=!1,l=0,d=!1;for(let h=0;h\u003ct.route.length-1;h++){const u=hnt(t.route[h]),p=hnt(t.route[h+1]);if(!u||!p)return null;const m=unt(u,p),g=pnt(u,p,n),f=_nt(u,p,e),y=mnt(u,p,0,m,g),_=mnt(u,p,1,m,g),b=0===h;if(!f){xnt(o,t,l++,y,_);continue}if(d=!0,f.startT\u003ednt){const e=mnt(u,p,f.startT,m,g),n=vnt({obstacleId:`${t.pcb_trace_id}_keep_${l}_bounds`,start:y,end:e,layer:m,width:g});n\u0026\u0026s.push(n),xnt(o,t,l++,y,e)}const x=mnt(u,p,f.endT,m,g),v=gnt(mnt(u,p,f.startT,m,g),e),S=gnt(mnt(u,p,f.endT,m,g),e);if(a||(a=v,c=b\u0026\u0026f.startT\u003c=dnt),f.endT\u003c.999999999){const n=Int({trace:t,ripIndex:i.length,start:a,end:S,region:e,allowInteriorStart:c});n\u0026\u0026(i.push(n.connection),r.push(...n.endpointObstacles)),a=null,c=!1;const d=vnt({obstacleId:`${t.pcb_trace_id}_keep_${l}_bounds`,start:x,end:_,layer:m,width:g});d\u0026\u0026s.push(d),xnt(o,t,l++,x,_)}}if(a){const n=t.route.slice().reverse().map(hnt).find(t=\u003eBoolean(t));if(n){const o=Int({trace:t,ripIndex:i.length,start:a,end:{x:n.x,y:n.y,layer:n.layer??n.from_layer??a.layer,width:a.width},region:e,allowInteriorStart:c,allowInteriorEnd:!0});o\u0026\u0026(i.push(o.connection),r.push(...o.endpointObstacles))}}return{keptTraces:o,rerouteConnections:i,rerouteEndpointObstacles:r,clippedTraceSegmentObstacles:s,hadIntersection:d}},Pnt=(t,e)=\u003e{const n=structuredClone(t),o=[],i=[],r=[],s=[];for(const n of t.traces??[]){const a=Cnt(n,e,t.minTraceWidth);a?a.hadIntersection?(o.push(...a.keptTraces),i.push(...a.rerouteConnections),r.push(...a.rerouteEndpointObstacles),s.push(...a.clippedTraceSegmentObstacles)):o.push(structuredClone(n)):o.push(structuredClone(n))}const a=((t,e)=\u003e{const n={minX:t.minX,maxX:t.maxX,minY:t.minY,maxY:t.maxY};for(const t of e){const e=Ee(t);n.minX=Math.min(n.minX,e.minX),n.maxX=Math.max(n.maxX,e.maxX),n.minY=Math.min(n.minY,e.minY),n.maxY=Math.max(n.maxY,e.maxY)}return n})(e,[...r,...s]);return{...n,bounds:a,obstacles:[...n.obstacles,...r],traces:o,connections:i}},Mnt=(t,e)=\u003e{const n=new Map(e.connections.map(t=\u003e[t.name,t.__rootConnectionNames?.[0]??t.name])),o=(e.traces??[]).map(t=\u003e{const e=n.get(t.connection_name);return e?{...structuredClone(t),connection_name:e}:structuredClone(t)});return{...structuredClone(t),traces:o,jumpers:e.jumpers?structuredClone(e.jumpers):structuredClone(t.jumpers)}},Nnt=(t,e,n=[])=\u003e[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join(\"\\n\"),wnt=1.8,Tnt=.95,Rnt=.8,Ent=.95,Ant=class extends si{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;regionId;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.regionId=t.regionId,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=xe(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\u0026\u0026this.existingJumpers.push(...t.jumpers);const n=Math.ceil(5*(this.numRoutes+1));let o=this.boundsSize.width/this.cellStep,i=this.boundsSize.height/this.cellStep;for(;o*i\u003en**2\u0026\u0026!(this.cellStep\u003et.minDistBetweenEnteringPoints);)this.cellStep*=2,o=this.boundsSize.width/this.cellStep,i=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR;const r=Math.abs(this.A.x-this.bounds.minX)\u003c.001\u0026\u0026Math.abs(this.B.x-this.bounds.minX)\u003c.001||Math.abs(this.A.x-this.bounds.maxX)\u003c.001\u0026\u0026Math.abs(this.B.x-this.bounds.maxX)\u003c.001||Math.abs(this.A.y-this.bounds.minY)\u003c.001\u0026\u0026Math.abs(this.B.y-this.bounds.minY)\u003c.001||Math.abs(this.A.y-this.bounds.maxY)\u003c.001\u0026\u0026Math.abs(this.B.y-this.bounds.maxY)\u003c.001;this.futureConnections\u0026\u00260===this.futureConnections.length\u0026\u00260===this.obstacleRoutes.length\u0026\u0026!r\u0026\u0026this.handleSimpleCases();const s={x:t.A.x,y:t.A.y};this.initialNodeGridOffset={x:s.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:s.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 Wi([{...t.A,...s,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,regionId:this.regionId,route:[{x:t.x,y:t.y,z:0},{x:e.x,y:e.y,z:0}],traceThickness:this.traceThickness,jumpers:[]}}get jumperPenaltyDistance(){return wnt+this.straightLineDistance*this.JUMPER_PENALTY_FACTOR}isNodeTooCloseToObstacle(t,e){e??=this.obstacleMargin;for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){const o=Ont(n);for(const n of o)if(be(t,n.A,n.B)\u003cthis.traceThickness+e)return!0}for(const o of n.jumpers||[])if(this.isNodeTooCloseToJumper(t,o,e))return!0}return!1}isNodeTooCloseToJumper(t,e,n){const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=Math.abs(o)\u003eMath.abs(i),s=(r?Rnt:Ent)/2+n,a=(r?Ent:Rnt)/2+n;return Math.abs(t.x-e.start.x)\u003cs\u0026\u0026Math.abs(t.y-e.start.y)\u003ca||Math.abs(t.x-e.end.x)\u003cs\u0026\u0026Math.abs(t.y-e.end.y)\u003ca}isNodeTooCloseToEdge(t){const e=t.gComponents?.distFromStart??0\u003cthis.obstacleMargin/2?-this.obstacleMargin/2:this.obstacleMargin/2,n=t.x\u003cthis.bounds.minX+e||t.x\u003ethis.bounds.maxX-e||t.y\u003cthis.bounds.minY+e||t.y\u003ethis.bounds.maxY-e;return(!n||!(xe(t,this.B)\u003c2*e||xe(t,this.A)\u003c2*e))\u0026\u0026n}doesPathToParentIntersectObstacle(t){const e=t.parent;if(!e)return!1;for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){for(const o of Ont(n))if(fe(t,e,o.A,o.B))return!0;for(const o of n.jumpers||[])if(this.doesSegmentIntersectJumperPads(t,e,o))return!0}}return!1}doesSegmentIntersectJumperPads(t,e,n){const o=this.obstacleMargin,i=n.end.x-n.start.x,r=n.end.y-n.start.y,s=Math.abs(i)\u003eMath.abs(r),a=(s?Rnt:Ent)/2+o,c=(s?Ent:Rnt)/2+o;return!!this.doesSegmentIntersectRect(t,e,n.start,a,c)||!!this.doesSegmentIntersectRect(t,e,n.end,a,c)}doesSegmentIntersectRect(t,e,n,o,i){const r=n.x-o,s=n.x+o,a=n.y-i,c=n.y+i;if(t.x\u003e=r\u0026\u0026t.x\u003c=s\u0026\u0026t.y\u003e=a\u0026\u0026t.y\u003c=c)return!0;if(e.x\u003e=r\u0026\u0026e.x\u003c=s\u0026\u0026e.y\u003e=a\u0026\u0026e.y\u003c=c)return!0;const l=[{A:{x:r,y:a},B:{x:s,y:a}},{A:{x:s,y:a},B:{x:s,y:c}},{A:{x:s,y:c},B:{x:r,y:c}},{A:{x:r,y:c},B:{x:r,y:a}}];for(const n of l)if(fe(t,e,n.A,n.B))return!0;return!1}findObstaclesBetween(t,e){const n=[];for(const o of this.obstacleRoutes){const i=this.connMap?.areIdsConnected?.(this.connectionName,o.connectionName);if(!i)for(const i of Ont(o))fe(t,e,i.A,i.B)\u0026\u0026n.push({A:i.A,B:i.B})}return n}computeHComponents(t){const e=xe(t,this.roundedGoalPosition),n=this.getObstacleProximityPenalty(t),o=this.getEdgeProximityPenalty(t),i=this.getFutureConnectionStartEndPenalty(t),r=this.getFutureConnectionLinePenalty(t),s=t.parent,a=s?.hComponents,c=s?xe(t,s):0,l=(t,n)=\u003e{if(void 0===n||c\u003c1e-9||e\u003c1e-9)return t;const o=(t-n)/c;return(t+Math.max(0,t+o*e))/2},d=l(n,a?.obstacleProximityRate),h=l(o,a?.edgeProximityRate),u=l(i,a?.futureConnectionStartEndProximityRate),p=l(r,a?.futureConnectionLineRate),m=d*e,g=h*e,f=u*e,y=p*e;return{distanceToGoal:e,obstacleProximity:m,edgeProximity:g,futureConnectionStartEndProximityPenalty:f,futureConnectionLine:y,total:e+m+g+f+y,obstacleProximityRate:n,edgeProximityRate:o,futureConnectionStartEndProximityRate:i,futureConnectionLineRate:r}}computeH(t){return this.computeHComponents(t).total}computeGComponents(t){const e=t.parent,n=e?xe(t,e):0,o=e?.gComponents??{distFromStart:0,weightedMmNearObstacle:0,weightedMmNearEdge:0,weightedMmNearFutureConnectionStartEnd:0,weightedMmNearFutureConnectionLine:0,jumperPenalty:0,jumperPadFutureConnectionPenalty:0,total:0},i=o.distFromStart+n,r=o.weightedMmNearObstacle+this.getObstacleProximityPenalty(t)*n,s=o.weightedMmNearEdge+this.getEdgeProximityPenalty(t)*n,a=o.weightedMmNearFutureConnectionStartEnd+this.getFutureConnectionStartEndPenalty(t)*n,c=o.weightedMmNearFutureConnectionLine+this.getFutureConnectionLinePenalty(t)*n;let l=o.jumperPenalty,d=o.jumperPadFutureConnectionPenalty;t.isJumperExit\u0026\u0026(l+=this.jumperPenaltyDistance,d+=this.getJumperPadFutureConnectionPenalty(t));return{distFromStart:i,weightedMmNearObstacle:r,weightedMmNearEdge:s,weightedMmNearFutureConnectionStartEnd:a,weightedMmNearFutureConnectionLine:c,jumperPenalty:l,jumperPadFutureConnectionPenalty:d,total:i+r+s+a+c+l+d}}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 o of this.futureConnections)for(const i of o.points){const o=xe(t,i);o\u003ce\u0026\u0026(e=o,n=i)}return n}getFutureConnectionStartEndPenalty(t){let e=0;const n=this.getClosestFutureConnectionPoint(t);if(n){const o=xe(t,n);if(o\u003ethis.FUTURE_CONNECTION_START_END_PROXIMITY)return 0;const i=o/this.FUTURE_CONNECTION_START_END_PROXIMITY;e=this.FUTURE_CONNECTION_START_END_PENALTY*(1-i)**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\u003c2)continue;const o=be(t,n.points[0],n.points[n.points.length-1]);e=Math.min(e,o)}if(e*=n,e\u003cthis.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 o=1/0;for(const t of this.futureConnections)for(const i of t.points){const t=xe(e,i),r=xe(n,i),s=Math.min(t,r);o=Math.min(o,s)}if(o\u003cthis.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY){const t=o/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 o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){for(const o of Ont(n))e=Math.min(e,be(t,o.A,o.B));for(const o of n.jumpers||[])e=Math.min(e,this.distanceToJumperPads(t,o))}}return e}distanceToJumperPads(t,e){const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.abs(n)\u003eMath.abs(o),r=(i?Rnt:Ent)/2,s=(i?Ent:Rnt)/2;return Math.min(this.pointToRectDistance(t,e.start,r,s),this.pointToRectDistance(t,e.end,r,s))}pointToRectDistance(t,e,n,o){const i=Math.max(Math.abs(t.x-e.x)-n,0),r=Math.max(Math.abs(t.y-e.y)-o,0);return Math.hypot(i,r)}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)),o=this.OBSTACLE_PROX_SIGMA;return this.OBSTACLE_PROX_PENALTY_FACTOR*Math.exp(-n/o)}getEdgeProximityPenalty(t){const e=this.getClearanceToEdge(t),n=this.EDGE_PROX_SIGMA;if(e\u003e2*this.EDGE_PROX_SIGMA)return 0;const o=xe(t,this.B),i=Math.min(1,o/(2*this.EDGE_PROX_SIGMA));return this.EDGE_PROX_PENALTY_FACTOR*Math.exp(-e/n)*i}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)\u003cthis.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 o of n){const n=2*wnt,i=t.x+o.dx*n,r=t.y+o.dy*n,s=this.findObstaclesBetween(t,{x:i,y:r});if(s.length\u003e0)for(const n of s){const i=this.calculateJumperExit(t,n,o);i\u0026\u0026!this.exploredNodes.has(this.getNodeKey(i))\u0026\u0026(this.isNodeTooCloseToObstacle(i)||this.isNodeTooCloseToEdge(i)||!this.isJumperPlacementValid(t,i)||(i.gComponents=this.computeGComponents(i),i.hComponents=this.computeHComponents(i),i.g=i.gComponents.total,i.h=i.hComponents.total,i.f=this.computeF(i.g,i.h),e.push(i)))}}return e}calculateJumperExit(t,e,n){const o=wnt,i=Math.sqrt(n.dx*n.dx+n.dy*n.dy),r=n.dx/i,s=n.dy/i,a=t.x+r*o,c=t.y+s*o;return a\u003cthis.bounds.minX||a\u003ethis.bounds.maxX||c\u003cthis.bounds.minY||c\u003ethis.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,o=e.y-t.y,i=Math.abs(n)\u003eMath.abs(o),r=(i?Rnt:Ent)/2,s=(i?Ent:Rnt)/2,a=this.obstacleMargin,c=[t,e];for(const t of c){const e=[t,{x:t.x-r,y:t.y-s},{x:t.x+r,y:t.y-s},{x:t.x-r,y:t.y+s},{x:t.x+r,y:t.y+s},{x:t.x-r,y:t.y},{x:t.x+r,y:t.y},{x:t.x,y:t.y-s},{x:t.x,y:t.y+s}];for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(o)continue;const i=Ont(n);for(const n of i){for(const t of e)if(be(t,n.A,n.B)\u003cthis.traceThickness+a)return!0;if(this.doesSegmentIntersectRect(n.A,n.B,t,r+a,s+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 o=this.getJumpersInPath(t);for(const t of o)if(this.doJumpersOverlap(n,t))return!1;return!0}doJumpersOverlap(t,e){const n=this.obstacleMargin,o=Math.min(t.start.x,t.end.x)-Tnt/2-n,i=Math.max(t.start.x,t.end.x)+Tnt/2+n,r=Math.min(t.start.y,t.end.y)-Tnt/2-n,s=Math.max(t.start.y,t.end.y)+Tnt/2+n,a=Math.min(e.start.x,e.end.x)-Tnt/2-n,c=Math.max(e.start.x,e.end.x)+Tnt/2+n,l=Math.min(e.start.y,e.end.y)-Tnt/2-n,d=Math.max(e.start.y,e.end.y)+Tnt/2+n;return!(i\u003ca||o\u003ec||s\u003cl||r\u003ed)}getJumpersInPath(t){const e=[];let n=t;for(;n\u0026\u0026n.parent;)n.isJumperExit\u0026\u0026n.jumperEntry\u0026\u0026e.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:o,maxY:i,minY:r}=this.bounds;for(let s=-1;s\u003c=1;s++)for(let a=-1;a\u003c=1;a++){if(0===s\u0026\u00260===a)continue;if(!this.ALLOW_DIAGONAL\u0026\u00260!==s\u0026\u00260!==a)continue;const c=t.x+s*this.cellStep,l=t.y+a*this.cellStep,d=knt(c,o,n),h=knt(l,r,i),u={...t,parent:t,x:d,y:h,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 s=this.getJumperNeighbors(t);return e.push(...s),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\u003ce.length;t++){const o=e[t];o.isJumperExit\u0026\u0026o.jumperEntry\u0026\u0026n.push({route_type:\"jumper\",start:o.jumperEntry,end:{x:o.x,y:o.y},footprint:\"0603\"})}this.solvedPath={connectionName:this.connectionName,rootConnectionName:this.rootConnectionName,regionId:this.regionId,traceThickness:this.traceThickness,route:e.map(t=\u003e({x:t.x,y:t.y,z:0})).concat([{x:this.B.x,y:this.B.y,z:0}]),jumpers:n}}computeProgress(t,e){if(void 0===e)return Number.NaN;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\u0026\u0026e\u0026\u0026this.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=xe(t,this.roundedGoalPosition);this.progress=this.computeProgress(t,n),n\u003c=this.cellStep*Math.SQRT2\u0026\u0026!this.doesPathToParentIntersectObstacle({...t,parent:t,x:this.B.x,y:this.B.y})\u0026\u0026(this.solved=!0,this.setSolvedPath(t));const o=this.getNeighbors(t);for(const t of o)this.candidates.enqueue(t)}drawJumperPads(t,e,n,o,i,r){const s=e.end.x-e.start.x,a=e.end.y-e.start.y,c=Rnt,l=Ent,d=Math.abs(s)\u003eMath.abs(a),h=d?c:l,u=d?l:c;t.rects.push({center:{x:e.start.x,y:e.start.y},width:h,height:u,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:o??\"jumper\",step:i,label:r}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:h,height:u,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:o??\"jumper\",step:i,label:r}),t.lines.push({points:[e.start,e.end],strokeColor:\"rgba(100, 100, 100, 0.8)\",strokeWidth:.3*l,layer:o??\"jumper-body\",step:i,label:r})}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:Nnt(this.connectionName,this.rootConnectionName,[\"Input A\",`z: ${this.A.z}`]),color:\"orange\"}),t.points.push({x:this.B.x,y:this.B.y,label:Nnt(this.connectionName,this.rootConnectionName,[\"Input B\",`z: ${this.B.z}`]),color:\"orange\"}),t.lines.push({points:[this.A,this.B],strokeColor:\"rgba(255, 0, 0, 0.5)\",label:Nnt(this.connectionName,this.rootConnectionName,[\"Direct Input Connection\"])});for(let e=0;e\u003cthis.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let o=0;o\u003cn.route.length-1;o++)t.lines.push({points:[n.route[o],n.route[o+1]],strokeColor:\"rgba(255, 0, 0, 0.75)\",strokeWidth:n.traceThickness,label:Nnt(n.connectionName,n.rootConnectionName,[\"Obstacle Route\"]),layer:`obstacle${e.toString()}`});for(const o of n.jumpers||[])this.drawJumperPads(t,o,\"rgba(255, 0, 0, 0.5)\",`obstacle-jumper-${e}`,void 0,Nnt(n.connectionName,n.rootConnectionName,[\"Obstacle Jumper\"]))}for(let e=0;e\u003cthis.futureConnections.length;e++){const n=this.futureConnections[e];if(n.points.length\u003c2)continue;const o=n.points[0],i=n.points[n.points.length-1];t.lines.push({points:[o,i],strokeColor:\"rgba(0, 100, 255, 0.6)\",strokeWidth:this.traceThickness,label:Nnt(n.connectionName,n.rootConnectionName,[\"Future\"]),layer:`future-connection-${e}`})}for(let e=0;e\u003cthis.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[o,i]=n.split(\",\").map(Number),r=n.endsWith(\"_j\"),s=this.debug_exploredNodeValues.get(n),a=s?.gComponents,c=s?.hComponents,l=c?.distanceToGoal??0,d=[r?\"Explored (jumper)\":\"Explored\"];d.push(`g.distFromStart: ${a?.distFromStart.toFixed(2)??\"?\"}`),d.push(`g.nearObstacle: ${a?.weightedMmNearObstacle.toFixed(2)??\"?\"}`),d.push(`g.nearEdge: ${a?.weightedMmNearEdge.toFixed(2)??\"?\"}`),d.push(`g.nearFutStrtEnd: ${a?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??\"?\"}`),d.push(`g.nearFutLine: ${a?.weightedMmNearFutureConnectionLine.toFixed(2)??\"?\"}`),d.push(`g.jumper: ${a?.jumperPenalty.toFixed(2)??\"?\"}`),d.push(`g.jumperPadFutPenalty: ${a?.jumperPadFutureConnectionPenalty.toFixed(2)??\"?\"}`),d.push(`h.goalDist: ${l.toFixed(2)}`),d.push(`h.obstacleProx: ${c?.obstacleProximity.toFixed(2)??\"?\"} (${l\u003e0?((c?.obstacleProximity??0)/l).toFixed(3):0}/mm)`),d.push(`h.edgeProx: ${c?.edgeProximity.toFixed(2)??\"?\"} (${l\u003e0?((c?.edgeProximity??0)/l).toFixed(3):0}/mm)`),d.push(`h.futureConnPt: ${c?.futureConnectionStartEndProximityPenalty.toFixed(2)??\"?\"} (${l\u003e0?((c?.futureConnectionStartEndProximityPenalty??0)/l).toFixed(3):0}/mm)`),d.push(`h.futureConnLine: ${c?.futureConnectionLine.toFixed(2)??\"?\"} (${l\u003e0?((c?.futureConnectionLine??0)/l).toFixed(3):0}/mm)`),d.push(`g: ${s?.g.toFixed(2)??\"?\"}`),d.push(`h: ${s?.h.toFixed(2)??\"?\"}`),d.push(`f: ${s?.f.toFixed(2)??\"?\"}`);const h=d.join(\"\\n\");t.rects.push({center:{x:o+this.initialNodeGridOffset.x,y:i+this.initialNodeGridOffset.y},fill:r?`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:h})}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\u003ce.length;n++){const o=e[n],i=o.isJumperExit??!1,r=o.gComponents,s=o.hComponents,a=s?.distanceToGoal??0,c=[`Candidate #${n+1}${i?\" (jumper)\":\"\"}`];c.push(`g.distFromStart: ${r?.distFromStart.toFixed(2)??\"?\"}`),c.push(`g.nearObstacle: ${r?.weightedMmNearObstacle.toFixed(2)??\"?\"}`),c.push(`g.nearEdge: ${r?.weightedMmNearEdge.toFixed(2)??\"?\"}`),c.push(`g.nearFutureConnPt: ${r?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??\"?\"}`),c.push(`g.nearFutureConnLine: ${r?.weightedMmNearFutureConnectionLine.toFixed(2)??\"?\"}`),c.push(`g.jumper: ${r?.jumperPenalty.toFixed(2)??\"?\"}`),c.push(`g.jumperPadFutureConn: ${r?.jumperPadFutureConnectionPenalty.toFixed(2)??\"?\"}`),c.push(`g: ${o.g.toFixed(2)}`),c.push(`h.goalDist: ${a.toFixed(2)}`),c.push(`h.obstacleProx: ${s?.obstacleProximity.toFixed(2)??\"?\"} (${a\u003e0?((s?.obstacleProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.edgeProx: ${s?.edgeProximity.toFixed(2)??\"?\"} (${a\u003e0?((s?.edgeProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnPt: ${s?.futureConnectionStartEndProximityPenalty.toFixed(2)??\"?\"} (${a\u003e0?((s?.futureConnectionStartEndProximityPenalty??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnLine: ${s?.futureConnectionLine.toFixed(2)??\"?\"} (${a\u003e0?((s?.futureConnectionLine??0)/a).toFixed(3):0}/mm)`),c.push(`h: ${o.h.toFixed(2)}`),c.push(`f: ${o.f.toFixed(2)}`);const l=c.join(\"\\n\");t.points.push({x:o.x,y:o.y,color:\"gray\",label:l})}if(this.solvedPath){t.lines.push({points:this.solvedPath.route,strokeColor:\"green\",label:Nnt(this.solvedPath.connectionName,this.solvedPath.rootConnectionName,[\"Solved Route\"]),strokeWidth:this.traceThickness});for(const e of this.solvedPath.jumpers)this.drawJumperPads(t,e,\"rgba(0, 200, 0, 0.8)\",\"solved-jumper\",void 0,Nnt(this.solvedPath.connectionName,this.solvedPath.rootConnectionName,[\"Solved Jumper\"]))}const{minX:n,minY:o,maxX:i,maxY:r}=this.bounds;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:r},{x:n,y:r},{x:n,y:o}],strokeColor:\"rgba(255, 0, 0, 0.25)\",strokeDash:\"4 4\",layer:\"border\"}),t}};function Ont(t){const e=[];for(let n=0;n\u003ct.route.length-1;n++)if(t.route[n].z===t.route[n+1].z){const o=t.route[n],i=t.route[n+1],r=t.jumpers?.some(t=\u003e{const e=Math.abs(t.start.x-o.x)\u003c.001\u0026\u0026Math.abs(t.start.y-o.y)\u003c.001\u0026\u0026Math.abs(t.end.x-i.x)\u003c.001\u0026\u0026Math.abs(t.end.y-i.y)\u003c.001,n=Math.abs(t.start.x-i.x)\u003c.001\u0026\u0026Math.abs(t.start.y-i.y)\u003c.001\u0026\u0026Math.abs(t.end.x-o.x)\u003c.001\u0026\u0026Math.abs(t.end.y-o.y)\u003c.001;return e||n});r||e.push({z:o.z,A:o,B:i})}return e}function knt(t,e,n){return Math.max(e,Math.min(t,n))}var Lnt=.8,Dnt=.95,znt=(t,e,n=[])=\u003e[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join(\"\\n\"),Fnt=class extends si{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 o=new Map;for(const t of e.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}this.unsolvedConnections=[];for(const[t,e]of o){const n=Dr(e);for(const[e,o]of n)this.unsolvedConnections.push({connectionName:t,rootConnectionName:e.rootConnectionName??o.rootConnectionName,points:[{x:e.x,y:e.y,z:0},{x:o.x,y:o.y,z:0}]});if(0===n.length\u0026\u00261===e.length){const[n]=e;this.unsolvedConnections.push({connectionName:t,rootConnectionName:n?.rootConnectionName,points:n?[{x:n.x,y:n.y,z:0}]:[]})}}this.hyperParameters.SHUFFLE_SEED\u0026\u0026(this.unsolvedConnections=Xi(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=\u003e({...e,points:Xi(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Vi(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\u0026\u0026(this.failedSubSolvers.push(this.activeSubSolver),this.lastActiveSubSolver=this.activeSubSolver,this.activeSubSolver=null,this.error=this.failedSubSolvers.map(t=\u003et.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,o=Math.abs(e.x-n.x)\u003c1e-6,i=Math.abs(e.y-n.y)\u003c1e-6;if(o\u0026\u0026i)return}const{connectionName:e,rootConnectionName:n,points:o}=t;this.activeSubSolver=new Ant({connectionName:e,rootConnectionName:n,regionId:this.nodeWithPortPoints.capacityMeshNodeId,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:ro(this.nodeWithPortPoints),A:{x:o[0].x,y:o[0].y,z:0},B:{x:o[o.length-1].x,y:o[o.length-1].y,z:0},obstacleRoutes:this.solvedRoutes.filter(t=\u003e(!n||t.rootConnectionName!==n)\u0026\u0026!this.connMap?.areIdsConnected(t.connectionName,e)),futureConnections:this.unsolvedConnections,hyperParameters:this.hyperParameters,connMap:this.connMap,traceThickness:this.traceWidth})}drawJumperPads(t,e,n,o,i){const r=e.end.x-e.start.x,s=e.end.y-e.start.y,a=Lnt,c=Dnt,l=Math.abs(r)\u003eMath.abs(s),d=l?a:c,h=l?c:a;t.rects.push({center:{x:e.start.x,y:e.start.y},width:d,height:h,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:\"jumper\",label:i}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:d,height:h,fill:n,stroke:\"rgba(0, 0, 0, 0.5)\",layer:\"jumper\",label:i}),t.lines.push({points:[e.start,e.end],strokeColor:\"rgba(100, 100, 100, 0.8)\",strokeWidth:.3*c,layer:\"jumper-body\",label:i})}visualize(){if(this.activeSubSolver\u0026\u0026!this.solved)return this.activeSubSolver.visualize();if(this.failed\u0026\u0026this.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:znt(e.connectionName,e.rootConnectionName,[\"layer: 0 (single-layer)\"]),color:this.colorMap[e.connectionName]??\"blue\"});for(let e=0;e\u003cthis.solvedRoutes.length;e++){const n=this.solvedRoutes[e];if(n.route.length\u003e0){const o=this.colorMap[n.connectionName]??\"blue\";for(let e=0;e\u003cn.route.length-1;e++){const i=n.route[e],r=n.route[e+1];t.lines.push({points:[i,r],strokeColor:To(o,.2),layer:\"route-layer-0\",strokeWidth:n.traceThickness,label:znt(n.connectionName,n.rootConnectionName,[\"layer: 0\"])})}for(const i of n.jumpers)this.drawJumperPads(t,i,To(o,.5),e,znt(n.connectionName,n.rootConnectionName,[\"jumper\"]))}}const e=ro(this.nodeWithPortPoints),{minX:n,minY:o,maxX:i,maxY:r}=e;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:r},{x:n,y:r},{x:n,y:o}],strokeColor:\"rgba(255, 0, 0, 0.25)\",strokeDash:\"4 4\",layer:\"border\"}),t}},Bnt=Ss;export{G9 as AUTOROUTER_VERSION,lnt as AssignableAutoroutingPipeline1Solver,Wl as AssignableAutoroutingPipeline2,ef as AssignableAutoroutingPipeline3,JX as AttachProjectedRectsSolver,yl as AutoroutingPipeline1_OriginalUnravel,rK as AutoroutingPipelineSolver,Bet as AutoroutingPipelineSolver10_BgaFanout,Jet as AutoroutingPipelineSolver11_Simplification,Pc as AutoroutingPipelineSolver2_PortPointPathing,Nf as AutoroutingPipelineSolver3_HgPortPointPathing,xX as AutoroutingPipelineSolver4,xX as AutoroutingPipelineSolver4_TinyHypergraph,EX as AutoroutingPipelineSolver5,EX as AutoroutingPipelineSolver5_HdCache,rG as AutoroutingPipelineSolver6,rG as AutoroutingPipelineSolver6_PolyHypergraph,rK as AutoroutingPipelineSolver7_MultiGraph,lK as AutoroutingPipelineSolver8,y8 as AutoroutingPipelineSolver9_Networked,H9 as AutoroutingPipelineSolver9_PreloadedTraceGraph,Mc as CapacityMeshSolver,Pd as CurvyIntraNodeSolver,n8 as DEFAULT_HD_CACHE2_SERVER_URL,wz as GlobalDrcBranchPortfolioSolver,Nz as GlobalDrcForceImproveSolver,Ls as GrowShrinkHighDensityIntraNodeSolver,Qg as HighDensitySolver,Bnt as HyperSingleIntraNodeSolver,Qn as InMemoryCache,Fnt as IntraNodeSolverWithJumpers,eo as LocalStorageCache,g8 as PIPELINE9_NETWORKED_SOLVE_POLICY,QX as PolyHighDensitySolver,KX as PolyIntraNodeSolver,KX as PolySingleIntraNodeSolver,Ss as PortfolioSingleIntraNodeSolver,oG as ProjectHighDensityToPolygonSolver,Ant as SingleHighDensityRouteWithJumpersSolver,$s as calculateOptimalCapacityDepth,Ho as convertSrjToGraphicsObject,oo as getGlobalInMemoryCache,no as getGlobalLocalStorageCache,Pnt as getRerouteSimpleRouteJson,js as getTunedTotalCapacity1,Mnt as reconnectReroutedSimpleRouteJsonRegion,io as setupGlobalCaches,_8 as solvePipeline9NetworkedHighDensityNode};\n/*! Bundled license information:\n\nis-buffer/index.js:\n (*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh \u003chttps://feross.org\u003e\n * @license MIT\n *)\n\ndeep-rename-keys/index.js:\n (*!\n * deep-rename-keys \u003chttps://github.com/jonschlinkert/deep-rename-keys\u003e\n *\n * Copyright (c) 2015 Jon Schlinkert, contributors.\n * Licensed under the MIT license.\n *)\n\n@tscircuit/curvy-trace-solver/dist/index.js:\n@tscircuit/find-convex-regions/dist/index.js:\n (*! Bundled license information:\n \n is-buffer/index.js:\n (*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh \u003chttps://feross.org\u003e\n * @license MIT\n *)\n \n deep-rename-keys/index.js:\n (*!\n * deep-rename-keys \u003chttps://github.com/jonschlinkert/deep-rename-keys\u003e\n *\n * Copyright (c) 2015 Jon Schlinkert, contributors.\n * Licensed under the MIT license.\n *)\n *)\n\n@tscircuit/hypergraph/dist/index.js:\n (*! Bundled license information:\n \n @tscircuit/find-convex-regions/dist/index.js:\n (*! Bundled license information:\n \n is-buffer/index.js:\n (*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh \u003chttps://feross.org\u003e\n * @license MIT\n *)\n \n deep-rename-keys/index.js:\n (*!\n * deep-rename-keys \u003chttps://github.com/jonschlinkert/deep-rename-keys\u003e\n *\n * Copyright (c) 2015 Jon Schlinkert, contributors.\n * Licensed under the MIT license.\n *)\n *)\n *)\n*///# sourceMappingURL=index.js.map","content_mimetype":"text/javascript","created_at":"2026-09-08T16:51:04.318Z"}; window.SSR_PACKAGE_RELEASES = [{"package_release_id":"dadcc3e3-2713-4e98-887f-4b6137bd5354","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.21","github_commit_sha":null,"is_locked":false,"is_latest":true,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-09-08T16:51:00.213Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-c972a675127a917f4275e6ed2e8d118e","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=dadcc3e3-2713-4e98-887f-4b6137bd5354\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=dadcc3e3-2713-4e98-887f-4b6137bd5354\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=dadcc3e3-2713-4e98-887f-4b6137bd5354\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"87ce88af-6ebc-4d18-8566-4157e21ea81e","user_code_job_started_at":"2026-09-08T16:52:33.622Z","user_code_job_completed_at":"2026-09-08T16:59:59.297Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=d6b4ee33048d45c49f3c2aa07288211b524699d6de79c1297a7ac825a214cef2","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"1bd43346-33f3-4cde-bfc0-0d0f5ef7be46","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.20","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-09-08T15:16:56.192Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-d11498066a18b91f14cfef35200ce692","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1bd43346-33f3-4cde-bfc0-0d0f5ef7be46\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1bd43346-33f3-4cde-bfc0-0d0f5ef7be46\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1bd43346-33f3-4cde-bfc0-0d0f5ef7be46\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"25ade5eb-73d1-47ce-9823-5f98374536ec","user_code_job_started_at":"2026-09-08T15:18:02.030Z","user_code_job_completed_at":"2026-09-08T15:25:40.398Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=89a479e0fa012d7b67eda0b76d5ebc3715268e252699e7ddd07a3464689ff513","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8c74453a-83e2-4172-bcda-666d01f22b9f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.19","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-09-08T15:06:14.644Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-d91e0490b469149ed15fbb1a51ebd6c4","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"1eb0a04c-ecf7-497e-af22-0e9b9527afed","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.18","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-09-08T14:59:07.818Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-d29c5c93da4790e226795ec61a311545","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"310748ea-1f54-4e0b-bcb0-e26de0418bbe","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.17","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-20T09:08:27.021Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-3ab68ad76231274fced8daa9b4d216d1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"31871f8c-83e2-47f0-968e-30522688d9b6","user_code_job_started_at":"2026-09-07T20:49:28.128Z","user_code_job_completed_at":"2026-09-07T21:05:41.129Z","user_code_job_error":{"message":"Your code failed to build (exit code 1), see build logs for the error details","error_code":"user_code_build_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=295f4c032a00680940217b249f3b3f4fc21ade71a404fb9d8dd81770696f8397","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"de03c299-1b05-400b-9a9e-29d42c16b2bc","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.16","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-17T16:56:08.078Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-d8dbda73d7ae6158f52f028821fc56ee","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"3bf37cdc-0107-4eac-9892-f247c5e18661","user_code_job_started_at":"2026-08-17T16:58:40.245Z","user_code_job_completed_at":"2026-08-17T17:28:41.191Z","user_code_job_error":{"message":"Build timed out after 30 minutes","error_code":"user_code_job_timeout"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=76d319070ca1fa7f302a7515628d2639daeeecb6a5981c696f85e46107e3b9b9","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"0e701bc3-f617-464c-b79c-8117d2c86339","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.15","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-12T16:15:42.323Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-1d696f35b011352aeb71a3a73b619442","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0e701bc3-f617-464c-b79c-8117d2c86339\u0026file_path=dist%2Fleft%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0e701bc3-f617-464c-b79c-8117d2c86339\u0026file_path=dist%2Fleft%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0e701bc3-f617-464c-b79c-8117d2c86339\u0026file_path=dist%2Fleft%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"b70c43ef-2eed-47b4-b330-04f89859db6a","user_code_job_started_at":"2026-08-12T19:18:18.738Z","user_code_job_completed_at":"2026-08-12T19:28:03.200Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=12aa44a3f0616a1a15b3a1b0b9f58c05bbb5a610306d691dd1254f2acd6c484b","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"051bc4bf-1895-4c06-848e-06f0dca2393d","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.14","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-12T15:57:48.194Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-0c5e9892ec1ff3b912eed0a8c52f86d6","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"27e8a9f6-e7eb-447a-8734-0d94020b0275","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.13","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-12T15:50:05.533Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-9c0370a7e35c6d29e28e2ecfd1a35f0d","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"09680cad-cb3a-43bc-b3d9-3977d56d794c","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.12","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-12T15:44:02.661Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-5db3a4d5fec54b23a1879189c3ae3cbb","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"9800209a-d5a4-4a4b-940a-d0269c8f63b6","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.11","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-11T15:04:42.562Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-566054e353ef8fe7b66172bc2fae98b0","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9800209a-d5a4-4a4b-940a-d0269c8f63b6\u0026file_path=dist%2Fleft%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9800209a-d5a4-4a4b-940a-d0269c8f63b6\u0026file_path=dist%2Fleft%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9800209a-d5a4-4a4b-940a-d0269c8f63b6\u0026file_path=dist%2Fleft%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"30a6cf6d-8331-40a2-88c1-c288ec518721","user_code_job_started_at":"2026-08-12T06:03:29.394Z","user_code_job_completed_at":"2026-08-12T06:05:35.547Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=9786155159a44073aca7f275639c5bba8096798efe9ea7bbec0ac5bff5dbbff4","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"dfee26ad-0833-46ab-80ba-c79f11c42204","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.10","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-11T15:00:53.088Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-3323412296cadec0032dc46d61871214","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"ab72b3d5-3b6f-492c-97d2-683e46ee727f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.9","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-10T12:08:14.180Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-c3f01b7ce05c51934f420bc6f5a6bef2","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ab72b3d5-3b6f-492c-97d2-683e46ee727f\u0026file_path=dist%2Fleft%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ab72b3d5-3b6f-492c-97d2-683e46ee727f\u0026file_path=dist%2Fleft%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ab72b3d5-3b6f-492c-97d2-683e46ee727f\u0026file_path=dist%2Fleft%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"a09c97ff-fc3a-43f6-adb6-fdecc09ac5a4","user_code_job_started_at":"2026-08-10T12:14:11.619Z","user_code_job_completed_at":"2026-08-10T12:22:41.299Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=bd272eacf6b19c9d8bca9ff7025a50289e8cc5dcce91b374d4398239f9b8fdc6","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"aab741d2-66d6-4141-a56f-dec9a93f0745","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.8","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T12:05:54.107Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":null,"circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8d099371-81f4-4556-9b50-06c5ff43530c","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.7","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T12:01:26.302Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-90b8b592fc532bc050dfa0051f22721d","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"b5644906-1850-4f7e-bc7f-384131bc85d5","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.6","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T11:57:22.892Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-645c7d3e9b78aedbd409f63ea760ff03","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"bf68f755-3410-47ae-a8f7-bf1842ede84f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.5","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-10T10:36:56.206Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-fae103c87d843cdbb7d5853edd5e00a1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"62b3be01-12c5-415f-af59-2eb8cd87f0a2","user_code_job_started_at":"2026-08-10T10:39:53.625Z","user_code_job_completed_at":"2026-08-10T10:46:01.744Z","user_code_job_error":{"message":"Your code failed to build (exit code 1), see build logs for the error details","error_code":"user_code_build_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=5b7af5faf2794cb43b7c2ef0edf4af78aee1d8f2cbf54dc1148ababea99e1991","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"12026e15-765c-488a-9886-a89e93409099","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.4","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T10:32:18.439Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-640370fe7412c50c2a81985dc4c85ea1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"49831c5f-ff27-4706-b8d9-7a0fe1662179","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.3","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T10:28:40.595Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-abd2412878570b9cbce9d060b8e64f90","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"2bbe2022-8ce9-4466-bce4-9d3460eb7620","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-10T10:24:34.733Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-0c6ef3495ed62c8311da6c2a4a5ce1f1","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"511d059e-9f7c-4d44-b609-44cd623b4972","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-09T20:30:50.584Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-932b3b7914f4275cc095769b0f588268","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"af3b8d2e-6b0e-4354-9c73-14b62b65bd8d","user_code_job_started_at":"2026-08-10T09:05:50.472Z","user_code_job_completed_at":"2026-08-10T09:11:56.569Z","user_code_job_error":{"message":"Your code failed to build (exit code 1), see build logs for the error details","error_code":"user_code_build_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=858f0f5564ef737003bbfa6e781aeca055df3ed980065067ac7a494d91462263","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"0c2b43a3-54ff-41cc-9c2a-3c072a4bfce4","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"2.0.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-09T20:27:15.716Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-09c3251b45a913a702805e1ecccbb7b5","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"6243441b-092b-4166-b003-a232a9cb59ff","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.3","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-06T14:45:44.407Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-f8665c2de359b48d96d3d32c1ca7d0f8","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"3fcb8ef5-0e39-440c-a18f-1c682ef1e73d","user_code_job_started_at":"2026-08-06T14:45:50.004Z","user_code_job_completed_at":"2026-08-06T14:49:33.535Z","user_code_job_error":{"message":"There was an error running the job on our infrastructure, this is probably not your code, see build logs","error_code":"user_code_job_infrastructure_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=cbd18a5931f35b3cf6d4679c66ba2eeffba4e991283dff69751626b4d0c8bd62","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8c27b90d-b11f-403c-8691-41f218374a8f","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-08-06T13:40:38.469Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-e220e519e921d21de687f0af4239252c","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"ea20fb0d-e807-43f9-ba83-8978b2a9cd04","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-06T13:38:39.968Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-234591a7f9c087d813fd8d5ecbda0d46","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ea20fb0d-e807-43f9-ba83-8978b2a9cd04\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ea20fb0d-e807-43f9-ba83-8978b2a9cd04\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ea20fb0d-e807-43f9-ba83-8978b2a9cd04\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"5155b2ea-d7ed-41fc-80c6-d6311b4b55b4","user_code_job_started_at":"2026-08-06T13:38:48.763Z","user_code_job_completed_at":"2026-08-06T13:40:21.516Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=2d9c8a936d46c3ed4f25c54515d1eb4ff16872ade7b430062b7a024bd40f6dee","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c","package_id":"4dcf7237-6a2a-458d-ab13-f2fb4c221b56","version":"1.0.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-06T13:15:02.283Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-1def03398d147a237eb937a952295e79","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b80fb022-a9cf-48de-bee1-cf4e0bfd1e9c\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"97b18410-03ef-4231-98d7-89ecd9b787a4","user_code_job_started_at":"2026-08-06T13:15:08.904Z","user_code_job_completed_at":"2026-08-06T13:16:24.373Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=279a064e6ac1ab57ef793fb8ad3a32d71e6b5262e3dd6104e362a8d55c2f7b68","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null}]; window.SSR_PACKAGE_BUILDS = []; window.SSR_RELATED_PACKAGES = [{"package_id":"307fe261-5d71-417c-bc01-7835cd4f4abe","creator_account_id":"96f144ef-7dfe-4068-aac0-8753c8ab5f62","latest_package_release_id":"3c938c18-451d-4aea-8ecc-b5e5f561e6c6","last_built_release_id":"3c938c18-451d-4aea-8ecc-b5e5f561e6c6","latest_package_release_fs_sha":"md5-d17042528d94ca0759bc1345f41464bb","latest_pcb_preview_image_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.2","license":"unset","owner_org_id":"f46c84e5-2ffb-44f6-a4fa-47ad19769e7a","org_owner_tscircuit_handle":"test-1","owner_github_username":"test-1","github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"imrishabh18/boost-converter","unscoped_name":"boost-converter","star_count":0,"created_at":"2026-05-18T12:43:26.451Z","updated_at":"2026-05-19T18:52:38.681Z","ai_description":"This code defines a PCB schematic and 3D model layout focusing on a power conversion circuit with components like USB-C connector, MT3608 step-up regulator, inductor, diode, input/output capacitors, and resistors arranged on a double-layer PCB.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"same_author","thumbnail_url":"https://registry-api.tscircuit.com/package_files/view?package_release_id=3c938c18-451d-4aea-8ecc-b5e5f561e6c6\u0026file_path=dist%2Findex%2Fpcb.svg"},{"package_id":"1bb71080-c9d9-4806-8dad-9546e8b9913b","creator_account_id":"03854e77-22c2-44a0-9cfc-2d4ed6741105","latest_package_release_id":"92d10956-aa95-4eba-8e98-42e66c16f463","last_built_release_id":"92d10956-aa95-4eba-8e98-42e66c16f463","latest_package_release_fs_sha":"md5-73c7349eef4667e7cbc7beecb7e35036","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.5","license":"unset","owner_org_id":"7978967e-b956-4ac2-b813-667a08f6310a","org_owner_tscircuit_handle":"abse","owner_github_username":null,"github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"abse/boostxl-uln2003","unscoped_name":"boostxl-uln2003","star_count":0,"created_at":"2026-08-12T10:10:06.978Z","updated_at":"2026-08-12T22:29:23.783Z","ai_description":"This code defines a React component that models a through-hole or surface-mount LED with specified pin labels, footprint, silkscreen, and 3D CAD model for PCB layout.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"similar_ai_description","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=92d10956-aa95-4eba-8e98-42e66c16f463\u0026file_path=dist%2Findex%2Fpcb.svg"},{"package_id":"7065b9a6-03de-43a1-ba42-2a0ead33b548","creator_account_id":"1f745cb8-1b99-4215-905f-f8e3dc29bc28","latest_package_release_id":"5746ef1e-d91a-4043-9db3-2cc17f89d777","last_built_release_id":"5746ef1e-d91a-4043-9db3-2cc17f89d777","latest_package_release_fs_sha":"md5-27fc15676f25d1e3a229466d1de0fe7a","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.1","license":"unset","owner_org_id":"60917f07-d371-4c51-854f-e2bd7dab9e5a","org_owner_tscircuit_handle":"hrithik18k","owner_github_username":null,"github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"hrithik18k/smart-switch-pcb","unscoped_name":"smart-switch-pcb","star_count":0,"created_at":"2026-09-09T11:12:10.428Z","updated_at":"2026-09-09T11:56:59.112Z","ai_description":"The AO3400A component models a SOT-23 N-channel MOSFET with labeled pins for Gate, Source, and Drain, including 3D CAD models and schematic symbols for electronic circuit design.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"random","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fpcb.svg"}]; window.SSR_PACKAGE_ROUTE = {"author":"imrishabh18","packageName":"corne-keyboard","packageNameWithScope":"imrishabh18/corne-keyboard","version":null,"isLegacyRoute":false,"kind":"file","filePath":"debug-autorouter.mjs"};
)}function Nb(t,e){return!("v4"!==e&&e||!fb.test(t))||!("v6"!==e&&e||!_b.test(t))}function wb(t,e){if(!pb.test(t))return!1;try{const[n]=t.split(".");if(!n)return!1;const o=n.replace(/-/g,"+").replace(/_/g,"/").padEnd(n.length+(4-n.length%4)%4,"="),i=JSON.parse(atob(o));return"object"==typeof i&&null!==i&&((!("typ"in i)||"JWT"===i?.typ)&&(!!i.alg&&(!e||i.alg===e)))}catch{return!1}}function Tb(t,e){return!("v4"!==e&&e||!yb.test(t))||!("v6"!==e&&e||!bb.test(t))}var Rb=class t extends ab{_parse(t){this._def.coerce&&(t.data=String(t.data));if(this._getType(t)!==L_.string){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.string,received:e.parsedType}),q_}const e=new Z_;let n;for(const o of this._def.checks)if("min"===o.kind)t.data.length<o.value&&(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_small,minimum:o.value,type:"string",inclusive:!0,exact:!1,message:o.message}),e.dirty());else if("max"===o.kind)t.data.length>o.value&&(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_big,maximum:o.value,type:"string",inclusive:!0,exact:!1,message:o.message}),e.dirty());else if("length"===o.kind){const i=t.data.length>o.value,r=t.data.length<o.value;(i||r)&&(n=this._getOrReturnCtx(t,n),i?H_(n,{code:z_.too_big,maximum:o.value,type:"string",inclusive:!0,exact:!0,message:o.message}):r&&H_(n,{code:z_.too_small,minimum:o.value,type:"string",inclusive:!0,exact:!0,message:o.message}),e.dirty())}else if("email"===o.kind)gb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"email",code:z_.invalid_string,message:o.message}),e.dirty());else if("emoji"===o.kind)sb||(sb=new RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+quot;,"u")),sb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"emoji",code:z_.invalid_string,message:o.message}),e.dirty());else if("uuid"===o.kind)hb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"uuid",code:z_.invalid_string,message:o.message}),e.dirty());else if("nanoid"===o.kind)ub.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"nanoid",code:z_.invalid_string,message:o.message}),e.dirty());else if("cuid"===o.kind)cb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"cuid",code:z_.invalid_string,message:o.message}),e.dirty());else if("cuid2"===o.kind)lb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"cuid2",code:z_.invalid_string,message:o.message}),e.dirty());else if("ulid"===o.kind)db.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"ulid",code:z_.invalid_string,message:o.message}),e.dirty());else if("url"===o.kind)try{new URL(t.data)}catch{n=this._getOrReturnCtx(t,n),H_(n,{validation:"url",code:z_.invalid_string,message:o.message}),e.dirty()}else if("regex"===o.kind){o.regex.lastIndex=0;o.regex.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"regex",code:z_.invalid_string,message:o.message}),e.dirty())}else if("trim"===o.kind)t.data=t.data.trim();else if("includes"===o.kind)t.data.includes(o.value,o.position)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{includes:o.value,position:o.position},message:o.message}),e.dirty());else if("toLowerCase"===o.kind)t.data=t.data.toLowerCase();else if("toUpperCase"===o.kind)t.data=t.data.toUpperCase();else if("startsWith"===o.kind)t.data.startsWith(o.value)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{startsWith:o.value},message:o.message}),e.dirty());else if("endsWith"===o.kind)t.data.endsWith(o.value)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:{endsWith:o.value},message:o.message}),e.dirty());else if("datetime"===o.kind){Mb(o).test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:"datetime",message:o.message}),e.dirty())}else if("date"===o.kind){Ib.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:"date",message:o.message}),e.dirty())}else if("time"===o.kind){Pb(o).test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.invalid_string,validation:"time",message:o.message}),e.dirty())}else"duration"===o.kind?mb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"duration",code:z_.invalid_string,message:o.message}),e.dirty()):"ip"===o.kind?Nb(t.data,o.version)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"ip",code:z_.invalid_string,message:o.message}),e.dirty()):"jwt"===o.kind?wb(t.data,o.alg)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"jwt",code:z_.invalid_string,message:o.message}),e.dirty()):"cidr"===o.kind?Tb(t.data,o.version)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"cidr",code:z_.invalid_string,message:o.message}),e.dirty()):"base64"===o.kind?xb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"base64",code:z_.invalid_string,message:o.message}),e.dirty()):"base64url"===o.kind?vb.test(t.data)||(n=this._getOrReturnCtx(t,n),H_(n,{validation:"base64url",code:z_.invalid_string,message:o.message}),e.dirty()):R_.assertNever(o);return{status:e.value,value:t.data}}_regex(t,e,n){return this.refinement(e=>t.test(e),{validation:e,code:z_.invalid_string,...G_.errToObj(n)})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}email(t){return this._addCheck({kind:"email",...G_.errToObj(t)})}url(t){return this._addCheck({kind:"url",...G_.errToObj(t)})}emoji(t){return this._addCheck({kind:"emoji",...G_.errToObj(t)})}uuid(t){return this._addCheck({kind:"uuid",...G_.errToObj(t)})}nanoid(t){return this._addCheck({kind:"nanoid",...G_.errToObj(t)})}cuid(t){return this._addCheck({kind:"cuid",...G_.errToObj(t)})}cuid2(t){return this._addCheck({kind:"cuid2",...G_.errToObj(t)})}ulid(t){return this._addCheck({kind:"ulid",...G_.errToObj(t)})}base64(t){return this._addCheck({kind:"base64",...G_.errToObj(t)})}base64url(t){return this._addCheck({kind:"base64url",...G_.errToObj(t)})}jwt(t){return this._addCheck({kind:"jwt",...G_.errToObj(t)})}ip(t){return this._addCheck({kind:"ip",...G_.errToObj(t)})}cidr(t){return this._addCheck({kind:"cidr",...G_.errToObj(t)})}datetime(t){return"string"==typeof t?this._addCheck({kind:"datetime",precision:null,offset:!1,local:!1,message:t}):this._addCheck({kind:"datetime",precision:void 0===t?.precision?null:t?.precision,offset:t?.offset??!1,local:t?.local??!1,...G_.errToObj(t?.message)})}date(t){return this._addCheck({kind:"date",message:t})}time(t){return"string"==typeof t?this._addCheck({kind:"time",precision:null,message:t}):this._addCheck({kind:"time",precision:void 0===t?.precision?null:t?.precision,...G_.errToObj(t?.message)})}duration(t){return this._addCheck({kind:"duration",...G_.errToObj(t)})}regex(t,e){return this._addCheck({kind:"regex",regex:t,...G_.errToObj(e)})}includes(t,e){return this._addCheck({kind:"includes",value:t,position:e?.position,...G_.errToObj(e?.message)})}startsWith(t,e){return this._addCheck({kind:"startsWith",value:t,...G_.errToObj(e)})}endsWith(t,e){return this._addCheck({kind:"endsWith",value:t,...G_.errToObj(e)})}min(t,e){return this._addCheck({kind:"min",value:t,...G_.errToObj(e)})}max(t,e){return this._addCheck({kind:"max",value:t,...G_.errToObj(e)})}length(t,e){return this._addCheck({kind:"length",value:t,...G_.errToObj(e)})}nonempty(t){return this.min(1,G_.errToObj(t))}trim(){return new t({...this._def,checks:[...this._def.checks,{kind:"trim"}]})}toLowerCase(){return new t({...this._def,checks:[...this._def.checks,{kind:"toLowerCase"}]})}toUpperCase(){return new t({...this._def,checks:[...this._def.checks,{kind:"toUpperCase"}]})}get isDatetime(){return!!this._def.checks.find(t=>"datetime"===t.kind)}get isDate(){return!!this._def.checks.find(t=>"date"===t.kind)}get isTime(){return!!this._def.checks.find(t=>"time"===t.kind)}get isDuration(){return!!this._def.checks.find(t=>"duration"===t.kind)}get isEmail(){return!!this._def.checks.find(t=>"email"===t.kind)}get isURL(){return!!this._def.checks.find(t=>"url"===t.kind)}get isEmoji(){return!!this._def.checks.find(t=>"emoji"===t.kind)}get isUUID(){return!!this._def.checks.find(t=>"uuid"===t.kind)}get isNANOID(){return!!this._def.checks.find(t=>"nanoid"===t.kind)}get isCUID(){return!!this._def.checks.find(t=>"cuid"===t.kind)}get isCUID2(){return!!this._def.checks.find(t=>"cuid2"===t.kind)}get isULID(){return!!this._def.checks.find(t=>"ulid"===t.kind)}get isIP(){return!!this._def.checks.find(t=>"ip"===t.kind)}get isCIDR(){return!!this._def.checks.find(t=>"cidr"===t.kind)}get isBase64(){return!!this._def.checks.find(t=>"base64"===t.kind)}get isBase64url(){return!!this._def.checks.find(t=>"base64url"===t.kind)}get minLength(){let t=null;for(const e of this._def.checks)"min"===e.kind&&(null===t||e.value>t)&&(t=e.value);return t}get maxLength(){let t=null;for(const e of this._def.checks)"max"===e.kind&&(null===t||e.value<t)&&(t=e.value);return t}};function Eb(t,e){const n=(t.toString().split(".")[1]||"").length,o=(e.toString().split(".")[1]||"").length,i=n>o?n:o;return Number.parseInt(t.toFixed(i).replace(".",""))%Number.parseInt(e.toFixed(i).replace(".",""))/10**i}Rb.create=t=>new Rb({checks:[],typeName:xx.ZodString,coerce:t?.coerce??!1,...rb(t)});var Ab=class t extends ab{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(t){this._def.coerce&&(t.data=Number(t.data));if(this._getType(t)!==L_.number){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.number,received:e.parsedType}),q_}let e;const n=new Z_;for(const o of this._def.checks)if("int"===o.kind)R_.isInteger(t.data)||(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.invalid_type,expected:"integer",received:"float",message:o.message}),n.dirty());else if("min"===o.kind){(o.inclusive?t.data<o.value:t.data<=o.value)&&(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_small,minimum:o.value,type:"number",inclusive:o.inclusive,exact:!1,message:o.message}),n.dirty())}else if("max"===o.kind){(o.inclusive?t.data>o.value:t.data>=o.value)&&(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_big,maximum:o.value,type:"number",inclusive:o.inclusive,exact:!1,message:o.message}),n.dirty())}else"multipleOf"===o.kind?0!==Eb(t.data,o.value)&&(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_multiple_of,multipleOf:o.value,message:o.message}),n.dirty()):"finite"===o.kind?Number.isFinite(t.data)||(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_finite,message:o.message}),n.dirty()):R_.assertNever(o);return{status:n.value,value:t.data}}gte(t,e){return this.setLimit("min",t,!0,G_.toString(e))}gt(t,e){return this.setLimit("min",t,!1,G_.toString(e))}lte(t,e){return this.setLimit("max",t,!0,G_.toString(e))}lt(t,e){return this.setLimit("max",t,!1,G_.toString(e))}setLimit(e,n,o,i){return new t({...this._def,checks:[...this._def.checks,{kind:e,value:n,inclusive:o,message:G_.toString(i)}]})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}int(t){return this._addCheck({kind:"int",message:G_.toString(t)})}positive(t){return this._addCheck({kind:"min",value:0,inclusive:!1,message:G_.toString(t)})}negative(t){return this._addCheck({kind:"max",value:0,inclusive:!1,message:G_.toString(t)})}nonpositive(t){return this._addCheck({kind:"max",value:0,inclusive:!0,message:G_.toString(t)})}nonnegative(t){return this._addCheck({kind:"min",value:0,inclusive:!0,message:G_.toString(t)})}multipleOf(t,e){return this._addCheck({kind:"multipleOf",value:t,message:G_.toString(e)})}finite(t){return this._addCheck({kind:"finite",message:G_.toString(t)})}safe(t){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:G_.toString(t)})._addCheck({kind:"max",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:G_.toString(t)})}get minValue(){let t=null;for(const e of this._def.checks)"min"===e.kind&&(null===t||e.value>t)&&(t=e.value);return t}get maxValue(){let t=null;for(const e of this._def.checks)"max"===e.kind&&(null===t||e.value<t)&&(t=e.value);return t}get isInt(){return!!this._def.checks.find(t=>"int"===t.kind||"multipleOf"===t.kind&&R_.isInteger(t.value))}get isFinite(){let t=null,e=null;for(const n of this._def.checks){if("finite"===n.kind||"int"===n.kind||"multipleOf"===n.kind)return!0;"min"===n.kind?(null===e||n.value>e)&&(e=n.value):"max"===n.kind&&(null===t||n.value<t)&&(t=n.value)}return Number.isFinite(e)&&Number.isFinite(t)}};Ab.create=t=>new Ab({checks:[],typeName:xx.ZodNumber,coerce:t?.coerce||!1,...rb(t)});var Ob=class t extends ab{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(t){if(this._def.coerce)try{t.data=BigInt(t.data)}catch{return this._getInvalidInput(t)}if(this._getType(t)!==L_.bigint)return this._getInvalidInput(t);let e;const n=new Z_;for(const o of this._def.checks)if("min"===o.kind){(o.inclusive?t.data<o.value:t.data<=o.value)&&(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_small,type:"bigint",minimum:o.value,inclusive:o.inclusive,message:o.message}),n.dirty())}else if("max"===o.kind){(o.inclusive?t.data>o.value:t.data>=o.value)&&(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.too_big,type:"bigint",maximum:o.value,inclusive:o.inclusive,message:o.message}),n.dirty())}else"multipleOf"===o.kind?t.data%o.value!==BigInt(0)&&(e=this._getOrReturnCtx(t,e),H_(e,{code:z_.not_multiple_of,multipleOf:o.value,message:o.message}),n.dirty()):R_.assertNever(o);return{status:n.value,value:t.data}}_getInvalidInput(t){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.bigint,received:e.parsedType}),q_}gte(t,e){return this.setLimit("min",t,!0,G_.toString(e))}gt(t,e){return this.setLimit("min",t,!1,G_.toString(e))}lte(t,e){return this.setLimit("max",t,!0,G_.toString(e))}lt(t,e){return this.setLimit("max",t,!1,G_.toString(e))}setLimit(e,n,o,i){return new t({...this._def,checks:[...this._def.checks,{kind:e,value:n,inclusive:o,message:G_.toString(i)}]})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}positive(t){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!1,message:G_.toString(t)})}negative(t){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!1,message:G_.toString(t)})}nonpositive(t){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!0,message:G_.toString(t)})}nonnegative(t){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!0,message:G_.toString(t)})}multipleOf(t,e){return this._addCheck({kind:"multipleOf",value:t,message:G_.toString(e)})}get minValue(){let t=null;for(const e of this._def.checks)"min"===e.kind&&(null===t||e.value>t)&&(t=e.value);return t}get maxValue(){let t=null;for(const e of this._def.checks)"max"===e.kind&&(null===t||e.value<t)&&(t=e.value);return t}};Ob.create=t=>new Ob({checks:[],typeName:xx.ZodBigInt,coerce:t?.coerce??!1,...rb(t)});var kb=class extends ab{_parse(t){this._def.coerce&&(t.data=Boolean(t.data));if(this._getType(t)!==L_.boolean){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.boolean,received:e.parsedType}),q_}return K_(t.data)}};kb.create=t=>new kb({typeName:xx.ZodBoolean,coerce:t?.coerce||!1,...rb(t)});var Lb=class t extends ab{_parse(t){this._def.coerce&&(t.data=new Date(t.data));if(this._getType(t)!==L_.date){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.date,received:e.parsedType}),q_}if(Number.isNaN(t.data.getTime())){return H_(this._getOrReturnCtx(t),{code:z_.invalid_date}),q_}const e=new Z_;let n;for(const o of this._def.checks)"min"===o.kind?t.data.getTime()<o.value&&(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_small,message:o.message,inclusive:!0,exact:!1,minimum:o.value,type:"date"}),e.dirty()):"max"===o.kind?t.data.getTime()>o.value&&(n=this._getOrReturnCtx(t,n),H_(n,{code:z_.too_big,message:o.message,inclusive:!0,exact:!1,maximum:o.value,type:"date"}),e.dirty()):R_.assertNever(o);return{status:e.value,value:new Date(t.data.getTime())}}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}min(t,e){return this._addCheck({kind:"min",value:t.getTime(),message:G_.toString(e)})}max(t,e){return this._addCheck({kind:"max",value:t.getTime(),message:G_.toString(e)})}get minDate(){let t=null;for(const e of this._def.checks)"min"===e.kind&&(null===t||e.value>t)&&(t=e.value);return null!=t?new Date(t):null}get maxDate(){let t=null;for(const e of this._def.checks)"max"===e.kind&&(null===t||e.value<t)&&(t=e.value);return null!=t?new Date(t):null}};Lb.create=t=>new Lb({checks:[],coerce:t?.coerce||!1,typeName:xx.ZodDate,...rb(t)});var Db=class extends ab{_parse(t){if(this._getType(t)!==L_.symbol){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.symbol,received:e.parsedType}),q_}return K_(t.data)}};Db.create=t=>new Db({typeName:xx.ZodSymbol,...rb(t)});var zb=class extends ab{_parse(t){if(this._getType(t)!==L_.undefined){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.undefined,received:e.parsedType}),q_}return K_(t.data)}};zb.create=t=>new zb({typeName:xx.ZodUndefined,...rb(t)});var Fb=class extends ab{_parse(t){if(this._getType(t)!==L_.null){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.null,received:e.parsedType}),q_}return K_(t.data)}};Fb.create=t=>new Fb({typeName:xx.ZodNull,...rb(t)});var Bb=class extends ab{constructor(){super(...arguments),this._any=!0}_parse(t){return K_(t.data)}};Bb.create=t=>new Bb({typeName:xx.ZodAny,...rb(t)});var jb=class extends ab{constructor(){super(...arguments),this._unknown=!0}_parse(t){return K_(t.data)}};jb.create=t=>new jb({typeName:xx.ZodUnknown,...rb(t)});var $b=class extends ab{_parse(t){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.never,received:e.parsedType}),q_}};$b.create=t=>new $b({typeName:xx.ZodNever,...rb(t)});var Yb=class extends ab{_parse(t){if(this._getType(t)!==L_.undefined){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.void,received:e.parsedType}),q_}return K_(t.data)}};Yb.create=t=>new Yb({typeName:xx.ZodVoid,...rb(t)});var Xb=class t extends ab{_parse(t){const{ctx:e,status:n}=this._processInputParams(t),o=this._def;if(e.parsedType!==L_.array)return H_(e,{code:z_.invalid_type,expected:L_.array,received:e.parsedType}),q_;if(null!==o.exactLength){const t=e.data.length>o.exactLength.value,i=e.data.length<o.exactLength.value;(t||i)&&(H_(e,{code:t?z_.too_big:z_.too_small,minimum:i?o.exactLength.value:void 0,maximum:t?o.exactLength.value:void 0,type:"array",inclusive:!0,exact:!0,message:o.exactLength.message}),n.dirty())}if(null!==o.minLength&&e.data.length<o.minLength.value&&(H_(e,{code:z_.too_small,minimum:o.minLength.value,type:"array",inclusive:!0,exact:!1,message:o.minLength.message}),n.dirty()),null!==o.maxLength&&e.data.length>o.maxLength.value&&(H_(e,{code:z_.too_big,maximum:o.maxLength.value,type:"array",inclusive:!0,exact:!1,message:o.maxLength.message}),n.dirty()),e.common.async)return Promise.all([...e.data].map((t,n)=>o.type._parseAsync(new ob(e,t,e.path,n)))).then(t=>Z_.mergeArray(n,t));const i=[...e.data].map((t,n)=>o.type._parseSync(new ob(e,t,e.path,n)));return Z_.mergeArray(n,i)}get element(){return this._def.type}min(e,n){return new t({...this._def,minLength:{value:e,message:G_.toString(n)}})}max(e,n){return new t({...this._def,maxLength:{value:e,message:G_.toString(n)}})}length(e,n){return new t({...this._def,exactLength:{value:e,message:G_.toString(n)}})}nonempty(t){return this.min(1,t)}};function Vb(t){if(t instanceof Wb){const e={};for(const n in t.shape){const o=t.shape[n];e[n]=lx.create(Vb(o))}return new Wb({...t._def,shape:()=>e})}return t instanceof Xb?new Xb({...t._def,type:Vb(t.element)}):t instanceof lx?lx.create(Vb(t.unwrap())):t instanceof dx?dx.create(Vb(t.unwrap())):t instanceof Jb?Jb.create(t.items.map(t=>Vb(t))):t}Xb.create=(t,e)=>new Xb({type:t,minLength:null,maxLength:null,exactLength:null,typeName:xx.ZodArray,...rb(e)});var Wb=class t extends ab{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(null!==this._cached)return this._cached;const t=this._def.shape(),e=R_.objectKeys(t);return this._cached={shape:t,keys:e},this._cached}_parse(t){if(this._getType(t)!==L_.object){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.object,received:e.parsedType}),q_}const{status:e,ctx:n}=this._processInputParams(t),{shape:o,keys:i}=this._getCached(),r=[];if(!(this._def.catchall instanceof $b&&"strip"===this._def.unknownKeys))for(const t in n.data)i.includes(t)||r.push(t);const s=[];for(const t of i){const e=o[t],i=n.data[t];s.push({key:{status:"valid",value:t},value:e._parse(new ob(n,i,n.path,t)),alwaysSet:t in n.data})}if(this._def.catchall instanceof $b){const t=this._def.unknownKeys;if("passthrough"===t)for(const t of r)s.push({key:{status:"valid",value:t},value:{status:"valid",value:n.data[t]}});else if("strict"===t)r.length>0&&(H_(n,{code:z_.unrecognized_keys,keys:r}),e.dirty());else if("strip"!==t)throw new Error("Internal ZodObject error: invalid unknownKeys value.")}else{const t=this._def.catchall;for(const e of r){const o=n.data[e];s.push({key:{status:"valid",value:e},value:t._parse(new ob(n,o,n.path,e)),alwaysSet:e in n.data})}}return n.common.async?Promise.resolve().then(async()=>{const t=[];for(const e of s){const n=await e.key,o=await e.value;t.push({key:n,value:o,alwaysSet:e.alwaysSet})}return t}).then(t=>Z_.mergeObjectSync(e,t)):Z_.mergeObjectSync(e,s)}get shape(){return this._def.shape()}strict(e){return G_.errToObj,new t({...this._def,unknownKeys:"strict",...void 0!==e?{errorMap:(t,n)=>{const o=this._def.errorMap?.(t,n).message??n.defaultError;return"unrecognized_keys"===t.code?{message:G_.errToObj(e).message??o}:{message:o}}}:{}})}strip(){return new t({...this._def,unknownKeys:"strip"})}passthrough(){return new t({...this._def,unknownKeys:"passthrough"})}extend(e){return new t({...this._def,shape:()=>({...this._def.shape(),...e})})}merge(e){return new t({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=>({...this._def.shape(),...e._def.shape()}),typeName:xx.ZodObject})}setKey(t,e){return this.augment({[t]:e})}catchall(e){return new t({...this._def,catchall:e})}pick(e){const n={};for(const t of R_.objectKeys(e))e[t]&&this.shape[t]&&(n[t]=this.shape[t]);return new t({...this._def,shape:()=>n})}omit(e){const n={};for(const t of R_.objectKeys(this.shape))e[t]||(n[t]=this.shape[t]);return new t({...this._def,shape:()=>n})}deepPartial(){return Vb(this)}partial(e){const n={};for(const t of R_.objectKeys(this.shape)){const o=this.shape[t];e&&!e[t]?n[t]=o:n[t]=o.optional()}return new t({...this._def,shape:()=>n})}required(e){const n={};for(const t of R_.objectKeys(this.shape))if(e&&!e[t])n[t]=this.shape[t];else{let e=this.shape[t];for(;e instanceof lx;)e=e._def.innerType;n[t]=e}return new t({...this._def,shape:()=>n})}keyof(){return ix(R_.objectKeys(this.shape))}};Wb.create=(t,e)=>new Wb({shape:()=>t,unknownKeys:"strip",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)}),Wb.strictCreate=(t,e)=>new Wb({shape:()=>t,unknownKeys:"strict",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)}),Wb.lazycreate=(t,e)=>new Wb({shape:t,unknownKeys:"strip",catchall:$b.create(),typeName:xx.ZodObject,...rb(e)});var Hb=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n=this._def.options;if(e.common.async)return Promise.all(n.map(async t=>{const n={...e,common:{...e.common,issues:[]},parent:null};return{result:await t._parseAsync({data:e.data,path:e.path,parent:n}),ctx:n}})).then(function(t){for(const e of t)if("valid"===e.result.status)return e.result;for(const n of t)if("dirty"===n.result.status)return e.common.issues.push(...n.ctx.common.issues),n.result;const n=t.map(t=>new B_(t.ctx.common.issues));return H_(e,{code:z_.invalid_union,unionErrors:n}),q_});{let t;const o=[];for(const i of n){const n={...e,common:{...e.common,issues:[]},parent:null},r=i._parseSync({data:e.data,path:e.path,parent:n});if("valid"===r.status)return r;"dirty"!==r.status||t||(t={result:r,ctx:n}),n.common.issues.length&&o.push(n.common.issues)}if(t)return e.common.issues.push(...t.ctx.common.issues),t.result;const i=o.map(t=>new B_(t));return H_(e,{code:z_.invalid_union,unionErrors:i}),q_}}get options(){return this._def.options}};Hb.create=(t,e)=>new Hb({options:t,typeName:xx.ZodUnion,...rb(e)});var Gb=t=>t instanceof nx?Gb(t.schema):t instanceof cx?Gb(t.innerType()):t instanceof ox?[t.value]:t instanceof rx?t.options:t instanceof sx?R_.objectValues(t.enum):t instanceof hx?Gb(t._def.innerType):t instanceof zb?[void 0]:t instanceof Fb?[null]:t instanceof lx?[void 0,...Gb(t.unwrap())]:t instanceof dx?[null,...Gb(t.unwrap())]:t instanceof gx||t instanceof yx?Gb(t.unwrap()):t instanceof ux?Gb(t._def.innerType):[],Ub=class t extends ab{_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.object)return H_(e,{code:z_.invalid_type,expected:L_.object,received:e.parsedType}),q_;const n=this.discriminator,o=e.data[n],i=this.optionsMap.get(o);return i?e.common.async?i._parseAsync({data:e.data,path:e.path,parent:e}):i._parseSync({data:e.data,path:e.path,parent:e}):(H_(e,{code:z_.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[n]}),q_)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,n,o){const i=new Map;for(const t of n){const n=Gb(t.shape[e]);if(!n.length)throw new Error(`A discriminator value for key \`${e}\` could not be extracted from all schema options`);for(const o of n){if(i.has(o))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(o)}`);i.set(o,t)}}return new t({typeName:xx.ZodDiscriminatedUnion,discriminator:e,options:n,optionsMap:i,...rb(o)})}};function Zb(t,e){const n=D_(t),o=D_(e);if(t===e)return{valid:!0,data:t};if(n===L_.object&&o===L_.object){const n=R_.objectKeys(e),o=R_.objectKeys(t).filter(t=>-1!==n.indexOf(t)),i={...t,...e};for(const n of o){const o=Zb(t[n],e[n]);if(!o.valid)return{valid:!1};i[n]=o.data}return{valid:!0,data:i}}if(n===L_.array&&o===L_.array){if(t.length!==e.length)return{valid:!1};const n=[];for(let o=0;o<t.length;o++){const i=Zb(t[o],e[o]);if(!i.valid)return{valid:!1};n.push(i.data)}return{valid:!0,data:n}}return n===L_.date&&o===L_.date&&+t===+e?{valid:!0,data:t}:{valid:!1}}var qb=class extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t),o=(t,o)=>{if(Q_(t)||Q_(o))return q_;const i=Zb(t.value,o.value);return i.valid?((tb(t)||tb(o))&&e.dirty(),{status:e.value,value:i.data}):(H_(n,{code:z_.invalid_intersection_types}),q_)};return n.common.async?Promise.all([this._def.left._parseAsync({data:n.data,path:n.path,parent:n}),this._def.right._parseAsync({data:n.data,path:n.path,parent:n})]).then(([t,e])=>o(t,e)):o(this._def.left._parseSync({data:n.data,path:n.path,parent:n}),this._def.right._parseSync({data:n.data,path:n.path,parent:n}))}};qb.create=(t,e,n)=>new qb({left:t,right:e,typeName:xx.ZodIntersection,...rb(n)});var Jb=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.array)return H_(n,{code:z_.invalid_type,expected:L_.array,received:n.parsedType}),q_;if(n.data.length<this._def.items.length)return H_(n,{code:z_.too_small,minimum:this._def.items.length,inclusive:!0,exact:!1,type:"array"}),q_;!this._def.rest&&n.data.length>this._def.items.length&&(H_(n,{code:z_.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:"array"}),e.dirty());const o=[...n.data].map((t,e)=>{const o=this._def.items[e]||this._def.rest;return o?o._parse(new ob(n,t,n.path,e)):null}).filter(t=>!!t);return n.common.async?Promise.all(o).then(t=>Z_.mergeArray(e,t)):Z_.mergeArray(e,o)}get items(){return this._def.items}rest(e){return new t({...this._def,rest:e})}};Jb.create=(t,e)=>{if(!Array.isArray(t))throw new Error("You must pass an array of schemas to z.tuple([ ... ])");return new Jb({items:t,typeName:xx.ZodTuple,rest:null,...rb(e)})};var Kb=class t extends ab{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.object)return H_(n,{code:z_.invalid_type,expected:L_.object,received:n.parsedType}),q_;const o=[],i=this._def.keyType,r=this._def.valueType;for(const t in n.data)o.push({key:i._parse(new ob(n,t,n.path,t)),value:r._parse(new ob(n,n.data[t],n.path,t)),alwaysSet:t in n.data});return n.common.async?Z_.mergeObjectAsync(e,o):Z_.mergeObjectSync(e,o)}get element(){return this._def.valueType}static create(e,n,o){return new t(n instanceof ab?{keyType:e,valueType:n,typeName:xx.ZodRecord,...rb(o)}:{keyType:Rb.create(),valueType:e,typeName:xx.ZodRecord,...rb(n)})}},Qb=class extends ab{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.map)return H_(n,{code:z_.invalid_type,expected:L_.map,received:n.parsedType}),q_;const o=this._def.keyType,i=this._def.valueType,r=[...n.data.entries()].map(([t,e],r)=>({key:o._parse(new ob(n,t,n.path,[r,"key"])),value:i._parse(new ob(n,e,n.path,[r,"value"]))}));if(n.common.async){const t=new Map;return Promise.resolve().then(async()=>{for(const n of r){const o=await n.key,i=await n.value;if("aborted"===o.status||"aborted"===i.status)return q_;"dirty"!==o.status&&"dirty"!==i.status||e.dirty(),t.set(o.value,i.value)}return{status:e.value,value:t}})}{const t=new Map;for(const n of r){const o=n.key,i=n.value;if("aborted"===o.status||"aborted"===i.status)return q_;"dirty"!==o.status&&"dirty"!==i.status||e.dirty(),t.set(o.value,i.value)}return{status:e.value,value:t}}}};Qb.create=(t,e,n)=>new Qb({valueType:e,keyType:t,typeName:xx.ZodMap,...rb(n)});var tx=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.parsedType!==L_.set)return H_(n,{code:z_.invalid_type,expected:L_.set,received:n.parsedType}),q_;const o=this._def;null!==o.minSize&&n.data.size<o.minSize.value&&(H_(n,{code:z_.too_small,minimum:o.minSize.value,type:"set",inclusive:!0,exact:!1,message:o.minSize.message}),e.dirty()),null!==o.maxSize&&n.data.size>o.maxSize.value&&(H_(n,{code:z_.too_big,maximum:o.maxSize.value,type:"set",inclusive:!0,exact:!1,message:o.maxSize.message}),e.dirty());const i=this._def.valueType;function r(t){const n=new Set;for(const o of t){if("aborted"===o.status)return q_;"dirty"===o.status&&e.dirty(),n.add(o.value)}return{status:e.value,value:n}}const s=[...n.data.values()].map((t,e)=>i._parse(new ob(n,t,n.path,e)));return n.common.async?Promise.all(s).then(t=>r(t)):r(s)}min(e,n){return new t({...this._def,minSize:{value:e,message:G_.toString(n)}})}max(e,n){return new t({...this._def,maxSize:{value:e,message:G_.toString(n)}})}size(t,e){return this.min(t,e).max(t,e)}nonempty(t){return this.min(1,t)}};tx.create=(t,e)=>new tx({valueType:t,minSize:null,maxSize:null,typeName:xx.ZodSet,...rb(e)});var ex=class t extends ab{constructor(){super(...arguments),this.validate=this.implement}_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.function)return H_(e,{code:z_.invalid_type,expected:L_.function,received:e.parsedType}),q_;function n(t,n){return V_({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,X_(),j_].filter(t=>!!t),issueData:{code:z_.invalid_arguments,argumentsError:n}})}function o(t,n){return V_({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,X_(),j_].filter(t=>!!t),issueData:{code:z_.invalid_return_type,returnTypeError:n}})}const i={errorMap:e.common.contextualErrorMap},r=e.data;if(this._def.returns instanceof ax){const t=this;return K_(async function(...e){const s=new B_([]),a=await t._def.args.parseAsync(e,i).catch(t=>{throw s.addIssue(n(e,t)),s}),c=await Reflect.apply(r,this,a);return await t._def.returns._def.type.parseAsync(c,i).catch(t=>{throw s.addIssue(o(c,t)),s})})}{const t=this;return K_(function(...e){const s=t._def.args.safeParse(e,i);if(!s.success)throw new B_([n(e,s.error)]);const a=Reflect.apply(r,this,s.data),c=t._def.returns.safeParse(a,i);if(!c.success)throw new B_([o(a,c.error)]);return c.data})}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new t({...this._def,args:Jb.create(e).rest(jb.create())})}returns(e){return new t({...this._def,returns:e})}implement(t){return this.parse(t)}strictImplement(t){return this.parse(t)}static create(e,n,o){return new t({args:e||Jb.create([]).rest(jb.create()),returns:n||jb.create(),typeName:xx.ZodFunction,...rb(o)})}},nx=class extends ab{get schema(){return this._def.getter()}_parse(t){const{ctx:e}=this._processInputParams(t);return this._def.getter()._parse({data:e.data,path:e.path,parent:e})}};nx.create=(t,e)=>new nx({getter:t,typeName:xx.ZodLazy,...rb(e)});var ox=class extends ab{_parse(t){if(t.data!==this._def.value){const e=this._getOrReturnCtx(t);return H_(e,{received:e.data,code:z_.invalid_literal,expected:this._def.value}),q_}return{status:"valid",value:t.data}}get value(){return this._def.value}};function ix(t,e){return new rx({values:t,typeName:xx.ZodEnum,...rb(e)})}ox.create=(t,e)=>new ox({value:t,typeName:xx.ZodLiteral,...rb(e)});var rx=class t extends ab{_parse(t){if("string"!=typeof t.data){const e=this._getOrReturnCtx(t),n=this._def.values;return H_(e,{expected:R_.joinValues(n),received:e.parsedType,code:z_.invalid_type}),q_}if(this._cache||(this._cache=new Set(this._def.values)),!this._cache.has(t.data)){const e=this._getOrReturnCtx(t),n=this._def.values;return H_(e,{received:e.data,code:z_.invalid_enum_value,options:n}),q_}return K_(t.data)}get options(){return this._def.values}get enum(){const t={};for(const e of this._def.values)t[e]=e;return t}get Values(){const t={};for(const e of this._def.values)t[e]=e;return t}get Enum(){const t={};for(const e of this._def.values)t[e]=e;return t}extract(e,n=this._def){return t.create(e,{...this._def,...n})}exclude(e,n=this._def){return t.create(this.options.filter(t=>!e.includes(t)),{...this._def,...n})}};rx.create=ix;var sx=class extends ab{_parse(t){const e=R_.getValidEnumValues(this._def.values),n=this._getOrReturnCtx(t);if(n.parsedType!==L_.string&&n.parsedType!==L_.number){const t=R_.objectValues(e);return H_(n,{expected:R_.joinValues(t),received:n.parsedType,code:z_.invalid_type}),q_}if(this._cache||(this._cache=new Set(R_.getValidEnumValues(this._def.values))),!this._cache.has(t.data)){const t=R_.objectValues(e);return H_(n,{received:n.data,code:z_.invalid_enum_value,options:t}),q_}return K_(t.data)}get enum(){return this._def.values}};sx.create=(t,e)=>new sx({values:t,typeName:xx.ZodNativeEnum,...rb(e)});var ax=class extends ab{unwrap(){return this._def.type}_parse(t){const{ctx:e}=this._processInputParams(t);if(e.parsedType!==L_.promise&&!1===e.common.async)return H_(e,{code:z_.invalid_type,expected:L_.promise,received:e.parsedType}),q_;const n=e.parsedType===L_.promise?e.data:Promise.resolve(e.data);return K_(n.then(t=>this._def.type.parseAsync(t,{path:e.path,errorMap:e.common.contextualErrorMap})))}};ax.create=(t,e)=>new ax({type:t,typeName:xx.ZodPromise,...rb(e)});var cx=class extends ab{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===xx.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(t){const{status:e,ctx:n}=this._processInputParams(t),o=this._def.effect||null,i={addIssue:t=>{H_(n,t),t.fatal?e.abort():e.dirty()},get path(){return n.path}};if(i.addIssue=i.addIssue.bind(i),"preprocess"===o.type){const t=o.transform(n.data,i);if(n.common.async)return Promise.resolve(t).then(async t=>{if("aborted"===e.value)return q_;const o=await this._def.schema._parseAsync({data:t,path:n.path,parent:n});return"aborted"===o.status?q_:"dirty"===o.status||"dirty"===e.value?J_(o.value):o});{if("aborted"===e.value)return q_;const o=this._def.schema._parseSync({data:t,path:n.path,parent:n});return"aborted"===o.status?q_:"dirty"===o.status||"dirty"===e.value?J_(o.value):o}}if("refinement"===o.type){const t=t=>{const e=o.refinement(t,i);if(n.common.async)return Promise.resolve(e);if(e instanceof Promise)throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");return t};if(!1===n.common.async){const o=this._def.schema._parseSync({data:n.data,path:n.path,parent:n});return"aborted"===o.status?q_:("dirty"===o.status&&e.dirty(),t(o.value),{status:e.value,value:o.value})}return this._def.schema._parseAsync({data:n.data,path:n.path,parent:n}).then(n=>"aborted"===n.status?q_:("dirty"===n.status&&e.dirty(),t(n.value).then(()=>({status:e.value,value:n.value}))))}if("transform"===o.type){if(!1===n.common.async){const t=this._def.schema._parseSync({data:n.data,path:n.path,parent:n});if(!eb(t))return q_;const r=o.transform(t.value,i);if(r instanceof Promise)throw new Error("Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.");return{status:e.value,value:r}}return this._def.schema._parseAsync({data:n.data,path:n.path,parent:n}).then(t=>eb(t)?Promise.resolve(o.transform(t.value,i)).then(t=>({status:e.value,value:t})):q_)}R_.assertNever(o)}};cx.create=(t,e,n)=>new cx({schema:t,typeName:xx.ZodEffects,effect:e,...rb(n)}),cx.createWithPreprocess=(t,e,n)=>new cx({schema:e,effect:{type:"preprocess",transform:t},typeName:xx.ZodEffects,...rb(n)});var lx=class extends ab{_parse(t){return this._getType(t)===L_.undefined?K_(void 0):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}};lx.create=(t,e)=>new lx({innerType:t,typeName:xx.ZodOptional,...rb(e)});var dx=class extends ab{_parse(t){return this._getType(t)===L_.null?K_(null):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}};dx.create=(t,e)=>new dx({innerType:t,typeName:xx.ZodNullable,...rb(e)});var hx=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t);let n=e.data;return e.parsedType===L_.undefined&&(n=this._def.defaultValue()),this._def.innerType._parse({data:n,path:e.path,parent:e})}removeDefault(){return this._def.innerType}};hx.create=(t,e)=>new hx({innerType:t,typeName:xx.ZodDefault,defaultValue:"function"==typeof e.default?e.default:()=>e.default,...rb(e)});var ux=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n={...e,common:{...e.common,issues:[]}},o=this._def.innerType._parse({data:n.data,path:n.path,parent:{...n}});return nb(o)?o.then(t=>({status:"valid",value:"valid"===t.status?t.value:this._def.catchValue({get error(){return new B_(n.common.issues)},input:n.data})})):{status:"valid",value:"valid"===o.status?o.value:this._def.catchValue({get error(){return new B_(n.common.issues)},input:n.data})}}removeCatch(){return this._def.innerType}};ux.create=(t,e)=>new ux({innerType:t,typeName:xx.ZodCatch,catchValue:"function"==typeof e.catch?e.catch:()=>e.catch,...rb(e)});var px=class extends ab{_parse(t){if(this._getType(t)!==L_.nan){const e=this._getOrReturnCtx(t);return H_(e,{code:z_.invalid_type,expected:L_.nan,received:e.parsedType}),q_}return{status:"valid",value:t.data}}};px.create=t=>new px({typeName:xx.ZodNaN,...rb(t)});var mx=Symbol("zod_brand"),gx=class extends ab{_parse(t){const{ctx:e}=this._processInputParams(t),n=e.data;return this._def.type._parse({data:n,path:e.path,parent:e})}unwrap(){return this._def.type}},fx=class t extends ab{_parse(t){const{status:e,ctx:n}=this._processInputParams(t);if(n.common.async){return(async()=>{const t=await this._def.in._parseAsync({data:n.data,path:n.path,parent:n});return"aborted"===t.status?q_:"dirty"===t.status?(e.dirty(),J_(t.value)):this._def.out._parseAsync({data:t.value,path:n.path,parent:n})})()}{const t=this._def.in._parseSync({data:n.data,path:n.path,parent:n});return"aborted"===t.status?q_:"dirty"===t.status?(e.dirty(),{status:"dirty",value:t.value}):this._def.out._parseSync({data:t.value,path:n.path,parent:n})}}static create(e,n){return new t({in:e,out:n,typeName:xx.ZodPipeline})}},yx=class extends ab{_parse(t){const e=this._def.innerType._parse(t),n=t=>(eb(t)&&(t.value=Object.freeze(t.value)),t);return nb(e)?e.then(t=>n(t)):n(e)}unwrap(){return this._def.innerType}};function _x(t,e){const n="function"==typeof t?t(e):"string"==typeof t?{message:t}:t;return"string"==typeof n?{message:n}:n}function bx(t,e={},n){return t?Bb.create().superRefine((o,i)=>{const r=t(o);if(r instanceof Promise)return r.then(t=>{if(!t){const t=_x(e,o),r=t.fatal??n??!0;i.addIssue({code:"custom",...t,fatal:r})}});if(!r){const t=_x(e,o),r=t.fatal??n??!0;i.addIssue({code:"custom",...t,fatal:r})}}):Bb.create()}yx.create=(t,e)=>new yx({innerType:t,typeName:xx.ZodReadonly,...rb(e)});var xx,vx,Sx={object:Wb.lazycreate};(vx=xx||(xx={})).ZodString="ZodString",vx.ZodNumber="ZodNumber",vx.ZodNaN="ZodNaN",vx.ZodBigInt="ZodBigInt",vx.ZodBoolean="ZodBoolean",vx.ZodDate="ZodDate",vx.ZodSymbol="ZodSymbol",vx.ZodUndefined="ZodUndefined",vx.ZodNull="ZodNull",vx.ZodAny="ZodAny",vx.ZodUnknown="ZodUnknown",vx.ZodNever="ZodNever",vx.ZodVoid="ZodVoid",vx.ZodArray="ZodArray",vx.ZodObject="ZodObject",vx.ZodUnion="ZodUnion",vx.ZodDiscriminatedUnion="ZodDiscriminatedUnion",vx.ZodIntersection="ZodIntersection",vx.ZodTuple="ZodTuple",vx.ZodRecord="ZodRecord",vx.ZodMap="ZodMap",vx.ZodSet="ZodSet",vx.ZodFunction="ZodFunction",vx.ZodLazy="ZodLazy",vx.ZodLiteral="ZodLiteral",vx.ZodEnum="ZodEnum",vx.ZodEffects="ZodEffects",vx.ZodNativeEnum="ZodNativeEnum",vx.ZodOptional="ZodOptional",vx.ZodNullable="ZodNullable",vx.ZodDefault="ZodDefault",vx.ZodCatch="ZodCatch",vx.ZodPromise="ZodPromise",vx.ZodBranded="ZodBranded",vx.ZodPipeline="ZodPipeline",vx.ZodReadonly="ZodReadonly";var Ix=(t,e={message:`Input not instance of ${t.name}`})=>bx(e=>e instanceof t,e),Cx=Rb.create,Px=Ab.create,Mx=px.create,Nx=Ob.create,wx=kb.create,Tx=Lb.create,Rx=Db.create,Ex=zb.create,Ax=Fb.create,Ox=Bb.create,kx=jb.create,Lx=$b.create,Dx=Yb.create,zx=Xb.create,Fx=Wb.create,Bx=Wb.strictCreate,jx=Hb.create,$x=Ub.create,Yx=qb.create,Xx=Jb.create,Vx=Kb.create,Wx=Qb.create,Hx=tx.create,Gx=ex.create,Ux=nx.create,Zx=ox.create,qx=rx.create,Jx=sx.create,Kx=ax.create,Qx=cx.create,tv=lx.create,ev=dx.create,nv=cx.createWithPreprocess,ov=fx.create,iv=()=>Cx().optional(),rv=()=>Px().optional(),sv=()=>wx().optional(),av={string:t=>Rb.create({...t,coerce:!0}),number:t=>Ab.create({...t,coerce:!0}),boolean:t=>kb.create({...t,coerce:!0}),bigint:t=>Ob.create({...t,coerce:!0}),date:t=>Lb.create({...t,coerce:!0})},cv=q_,lv=k_.string().or(k_.number()).transform(t=>T_(t,"Ω").value),dv=k_.string().or(k_.number()).transform(t=>T_(t,"F").value).transform(t=>Number.parseFloat(t.toPrecision(12))),hv=k_.string().or(k_.number()).transform(t=>T_(t,"H").value),uv=k_.string().or(k_.number()).transform(t=>T_(t,"V").value),pv=k_.string().or(k_.number()).transform(t=>T_(t).value),mv=k_.string().or(k_.number()).transform(t=>T_(t,"Hz").value),gv=pv,fv=k_.string().or(k_.number()).transform(t=>T_(t,"A").value),yv=k_.string().or(k_.number()).transform(t=>T_(t).value),_v=yv,bv=yv,xv=k_.string().datetime(),vv=k_.string().or(k_.number()).transform(t=>"number"==typeof t?t:t.endsWith("deg")?Number.parseFloat(t.split("deg")[0]):t.endsWith("rad")?180*Number.parseFloat(t.split("rad")[0])/Math.PI:Number.parseFloat(t)),Sv=k_.number().or(k_.string().endsWith("mAh")).transform(t=>{if("string"==typeof t){const e=t.replace("mAh",""),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error("Invalid capacity");return n}return t}).describe("Battery capacity in mAh"),Iv=k_.object({x:gv,y:gv}),Cv=Iv,Pv=k_.object({x:gv,y:gv,z:gv}),Mv=Pv,Nv=k_.object({width:k_.number(),height:k_.number()}),wv=t=>k_.string().optional().default(()=>`${t}_${(t=>{const e="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";return Array.from({length:t},()=>e[Math.floor(62*Math.random())]).join("")})(10)}`),Tv=k_.enum(["top_left","top_center","top_right","center_left","center","center_right","bottom_left","bottom_center","bottom_right"]),Rv=k_.enum(["top_silkscreen","bottom_silkscreen","top_copper","bottom_copper","top_soldermask","bottom_soldermask","top_fabrication_note","bottom_fabrication_note","top_user_note","bottom_user_note","top_courtyard","bottom_courtyard","inner1_copper","inner2_copper","inner3_copper","inner4_copper","inner5_copper","inner6_copper","inner7_copper","inner8_copper","edge_cuts","drill"]),Ev=k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()}),Av=Iv.extend({rotation:vv.optional()}),Ov=k_.object({size:Iv.optional(),thickness:gv.optional()}),kv=k_.object({font:Ov.optional()}),Lv=k_.object({value:k_.string(),at:Av.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:kv.optional()}),Dv=k_.object({Reference:Lv.optional(),Value:Lv.optional(),Datasheet:Lv.optional(),Description:Lv.optional()}),zv=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),Fv=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:Av.optional(),size:Iv.optional(),drill:gv.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),Bv=k_.object({path:k_.string(),offset:Pv.optional(),scale:Pv.optional(),rotate:Pv.optional()}),jv=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:Dv.optional(),attributes:zv.optional(),pads:k_.array(Fv).optional(),embeddedFonts:k_.boolean().optional(),model:Bv.optional()}),$v=k_.object({hide:k_.boolean().optional()}),Yv=k_.object({offset:gv.optional(),hide:k_.boolean().optional()}),Xv=k_.object({font:Ov.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),Vv=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:Av.optional(),effects:Xv.optional()}),Wv=k_.object({Reference:Vv.optional(),Value:Vv.optional(),Footprint:Vv.optional(),Datasheet:Vv.optional(),Description:Vv.optional(),ki_keywords:Vv.optional(),ki_fp_filters:Vv.optional()}),Hv=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:$v.optional(),pinNames:Yv.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:Wv.optional(),embeddedFonts:k_.boolean().optional()}),Gv=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),Uv=k_.enum(["jlcpcb","macrofab","pcbway","digikey","mouser","lcsc"]),Zv=k_.object({type:k_.literal("source_component"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(Uv,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),qv=Zv.extend({ftype:k_.literal("simple_capacitor"),capacitance:dv,max_voltage_rating:uv.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:gv.optional()}),Jv=Zv.extend({ftype:k_.literal("simple_resistor"),resistance:lv,display_resistance:k_.string().optional()}),Kv=Zv.extend({ftype:k_.literal("simple_diode")}),Qv=Zv.extend({ftype:k_.literal("simple_fiducial")}),tS=Kv.extend({ftype:k_.literal("simple_led"),color:k_.string().optional(),wavelength:k_.string().optional()}),eS=Zv.extend({ftype:k_.literal("simple_ground")}),nS=Zv.extend({ftype:k_.literal("simple_chip")}),oS=Zv.extend({ftype:k_.literal("simple_power_source"),voltage:uv}),iS=Zv.extend({ftype:k_.literal("simple_current_source"),current:fv,frequency:mv.optional(),peak_to_peak_current:fv.optional(),wave_shape:k_.enum(["sine","square","triangle","sawtooth","dc"]).optional().default("dc"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),rS=Zv.extend({ftype:k_.literal("simple_fuse"),current_rating_amps:k_.number().describe("Nominal current in amps the fuse is rated for"),voltage_rating_volts:k_.number().describe("Voltage rating in volts, e.g. ±5V would be 5")}),sS=Zv.extend({ftype:k_.literal("simple_ammeter")}),aS=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),cS=Zv.extend({ftype:k_.literal("simple_battery"),capacity:Sv}),lS=Zv.extend({ftype:k_.literal("simple_inductor"),inductance:hv,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),dS=Zv.extend({ftype:k_.literal("simple_push_button")}),hS=Zv.extend({ftype:k_.literal("simple_potentiometer"),max_resistance:lv,display_max_resistance:k_.string().optional()}),uS=Zv.extend({ftype:k_.literal("simple_crystal"),frequency:k_.number().describe("Frequency in Hz"),load_capacitance:k_.number().optional().describe("Load capacitance in pF"),pin_variant:k_.enum(["two_pin","four_pin"]).optional()}),pS=Zv.extend({ftype:k_.literal("simple_pin_header"),pin_count:k_.number(),gender:k_.enum(["male","female"]).optional().default("male")}),mS=Zv.extend({ftype:k_.literal("simple_connector"),standard:k_.enum(["usb_c","m2"]).optional()}),gS=Zv.extend({ftype:k_.literal("simple_pinout")}),fS=Zv.extend({ftype:k_.literal("simple_resonator"),load_capacitance:dv,equivalent_series_resistance:lv.optional(),frequency:mv}),yS=Zv.extend({ftype:k_.literal("simple_transistor"),transistor_type:k_.enum(["npn","pnp"])}),_S=Zv.extend({ftype:k_.literal("simple_test_point"),footprint_variant:k_.enum(["pad","through_hole"]).optional(),pad_shape:k_.enum(["rect","circle"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),bS=Zv.extend({ftype:k_.literal("simple_mosfet"),channel_type:k_.enum(["n","p"]),mosfet_mode:k_.enum(["enhancement","depletion"])}),xS=Zv.extend({ftype:k_.literal("simple_op_amp")}),vS=Zv.extend({ftype:k_.literal("simple_switch")}),SS=k_.object({type:k_.literal("source_project_metadata"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),source_filesystem_md5_hash:k_.string().optional(),created_at:xv.optional()}),IS=Gv.extend({type:k_.literal("source_missing_property_error"),source_missing_property_error_id:wv("source_missing_property_error"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal("source_missing_property_error").default("source_missing_property_error")}).describe("The source code is missing a property"),CS=Gv.extend({type:k_.literal("source_failed_to_create_component_error"),source_failed_to_create_component_error_id:wv("source_failed_to_create_component_error"),error_type:k_.literal("source_failed_to_create_component_error").default("source_failed_to_create_component_error"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe("Error emitted when a component fails to be constructed"),PS=Gv.extend({type:k_.literal("source_invalid_component_property_error"),source_invalid_component_property_error_id:wv("source_invalid_component_property_error"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal("source_invalid_component_property_error").default("source_invalid_component_property_error")}).describe("The source component property is invalid"),MS=Gv.extend({type:k_.literal("source_trace_not_connected_error"),source_trace_not_connected_error_id:wv("source_trace_not_connected_error"),error_type:k_.literal("source_trace_not_connected_error").default("source_trace_not_connected_error"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe("Occurs when a source trace selector does not match any ports"),NS=k_.object({type:k_.literal("source_property_ignored_warning"),source_property_ignored_warning_id:wv("source_property_ignored_warning"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal("source_property_ignored_warning").default("source_property_ignored_warning"),message:k_.string()}).describe("The source property was ignored"),wS=k_.object({type:k_.literal("source_pin_missing_trace_warning"),source_pin_missing_trace_warning_id:wv("source_pin_missing_trace_warning"),warning_type:k_.literal("source_pin_missing_trace_warning").default("source_pin_missing_trace_warning"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a source component pin is missing a trace connection"),TS=k_.object({type:k_.literal("source_missing_manufacturer_part_number_warning"),source_missing_manufacturer_part_number_warning_id:wv("source_missing_manufacturer_part_number_warning"),warning_type:k_.literal("source_missing_manufacturer_part_number_warning").default("source_missing_manufacturer_part_number_warning"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a standard connector is missing manufacturer part number"),RS=k_.object({type:k_.literal("source_refdes_convention_warning"),source_refdes_convention_warning_id:wv("source_refdes_convention_warning"),warning_type:k_.literal("source_refdes_convention_warning").default("source_refdes_convention_warning"),message:k_.string(),source_component_id:k_.string(),refdes:k_.string(),source_component_ftype:k_.string(),expected_prefixes:k_.array(k_.string()),actual_prefix:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a source component reference designator does not match the component type convention"),ES=Zv.extend({ftype:k_.literal("simple_voltage_probe")}),AS=Zv.extend({ftype:k_.literal("interconnect")}),OS=Gv.extend({type:k_.literal("source_i2c_misconfigured_error"),source_i2c_misconfigured_error_id:wv("source_i2c_misconfigured_error"),error_type:k_.literal("source_i2c_misconfigured_error").default("source_i2c_misconfigured_error"),source_port_ids:k_.array(k_.string())}).describe("Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net"),kS=Gv.extend({type:k_.literal("source_component_misconfigured_error"),source_component_misconfigured_error_id:wv("source_component_misconfigured_error"),error_type:k_.literal("source_component_misconfigured_error").default("source_component_misconfigured_error"),source_component_ids:k_.array(k_.string()),source_port_ids:k_.array(k_.string()).optional()}).describe("Error emitted when one or more source components have an invalid or conflicting configuration"),LS=Zv.extend({ftype:k_.literal("simple_voltage_source"),voltage:uv,frequency:mv.optional(),peak_to_peak_voltage:uv.optional(),wave_shape:k_.enum(["sinewave","square","triangle","sawtooth"]).optional(),phase:vv.optional(),duty_cycle:k_.number().optional().describe("Duty cycle as a fraction (0 to 1)"),pulse_delay:bv.optional(),rise_time:bv.optional(),fall_time:bv.optional(),pulse_width:bv.optional(),period:bv.optional()}),DS=k_.union([Jv,qv,Kv,Qv,tS,eS,nS,oS,iS,sS,cS,lS,dS,hS,uS,pS,mS,gS,fS,vS,yS,_S,bS,xS,rS,ES,AS,LS,SS,IS,PS,CS,MS,NS,wS,TS,RS,OS,kS]),zS=k_.object({type:k_.literal("source_port"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(aS),FS=k_.object({type:k_.literal("source_component_internal_connection"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),BS=k_.object({type:k_.literal("source_trace"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),name:k_.string().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),jS=k_.object({type:k_.literal("source_group"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),$S=k_.object({type:k_.literal("source_net"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),YS=k_.object({type:k_.literal("source_board"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe("Defines a board in the source domain"),XS=Gv.extend({type:k_.literal("source_ambiguous_port_reference"),source_ambiguous_port_reference_id:wv("source_ambiguous_port_reference"),error_type:k_.literal("source_ambiguous_port_reference").default("source_ambiguous_port_reference"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe("Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous"),VS=k_.object({type:k_.literal("source_pcb_ground_plane"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe("Defines a ground plane in the source domain"),WS=["top","bottom","inner1","inner2","inner3","inner4","inner5","inner6","inner7","inner8"],HS=k_.enum(WS),GS=HS.or(k_.object({name:HS})).transform(t=>"string"==typeof t?t:t.name),US=k_.enum(["top","bottom"]),ZS=k_.object({type:k_.literal("source_manually_placed_via"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe("Defines a via that is manually placed in the source domain"),qS=k_.object({type:k_.literal("source_unnamed_trace_warning"),source_unnamed_trace_warning_id:wv("source_unnamed_trace_warning"),warning_type:k_.literal("source_unnamed_trace_warning").default("source_unnamed_trace_warning"),message:k_.string(),source_trace_id:k_.string(),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a source trace is missing a name"),JS=k_.object({type:k_.literal("source_no_power_pin_defined_warning"),source_no_power_pin_defined_warning_id:wv("source_no_power_pin_defined_warning"),warning_type:k_.literal("source_no_power_pin_defined_warning").default("source_no_power_pin_defined_warning"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a chip has no source ports with requires_power=true"),KS=k_.object({type:k_.literal("source_no_ground_pin_defined_warning"),source_no_ground_pin_defined_warning_id:wv("source_no_ground_pin_defined_warning"),warning_type:k_.literal("source_no_ground_pin_defined_warning").default("source_no_ground_pin_defined_warning"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a chip has no source ports marked as ground pins"),QS=k_.object({type:k_.literal("source_component_pins_underspecified_warning"),source_component_pins_underspecified_warning_id:wv("source_component_pins_underspecified_warning"),warning_type:k_.literal("source_component_pins_underspecified_warning").default("source_component_pins_underspecified_warning"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Warning emitted when all ports on a source component are underspecified"),tI=Gv.extend({type:k_.literal("source_pin_must_be_connected_error"),source_pin_must_be_connected_error_id:wv("source_pin_must_be_connected_error"),error_type:k_.literal("source_pin_must_be_connected_error").default("source_pin_must_be_connected_error"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe("Error emitted when a pin with mustBeConnected attribute is not connected to any trace"),eI=Gv.extend({type:k_.literal("unknown_error_finding_part"),unknown_error_finding_part_id:wv("unknown_error_finding_part"),error_type:k_.literal("unknown_error_finding_part").default("unknown_error_finding_part"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when an unexpected error occurs while finding a part"),nI=k_.object({type:k_.literal("source_part_not_found_warning"),source_part_not_found_warning_id:wv("source_part_not_found_warning"),warning_type:k_.literal("source_part_not_found_warning").default("source_part_not_found_warning"),message:k_.string(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:Uv.optional(),manufacturer_part_number:k_.string().optional(),supplier_part_number:k_.string().optional(),part_name:k_.string().optional()}).describe("Warning emitted when a requested part can not be found"),oI=k_.object({type:k_.literal("schematic_box"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:gv,height:gv,is_dashed:k_.boolean().default(!1),x:gv,y:gv,subcircuit_id:k_.string().optional()}).describe("Draws a box on the schematic"),iI=k_.object({type:k_.literal("schematic_path"),schematic_path_id:wv("schematic_path"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),is_dashed:k_.boolean().default(!1),stroke_width:gv.nullable().optional(),stroke_color:k_.string().optional(),dash_length:gv.optional(),dash_gap:gv.optional(),points:k_.array(Iv),subcircuit_id:k_.string().optional()}),rI=k_.record(k_.object({left_margin:pv.optional(),right_margin:pv.optional(),top_margin:pv.optional(),bottom_margin:pv.optional()})),sI=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),aI=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum(["top-to-bottom","bottom-to-top"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum(["top-to-bottom","bottom-to-top"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum(["left-to-right","right-to-left"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum(["left-to-right","right-to-left"]).optional()}).optional()}),cI=k_.union([sI,aI]),lI=k_.object({type:k_.literal("schematic_component"),size:Nv,center:Iv,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_sheet_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),pin_spacing:pv.optional(),pin_styles:rI.optional(),box_width:pv.optional(),symbol_name:k_.string().optional(),port_arrangement:cI.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),dI=k_.object({kicad_symbol:Hv.optional()}).catchall(k_.unknown()),hI=k_.object({type:k_.literal("schematic_symbol"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:dI.optional()}).describe("Defines a named schematic symbol that can be referenced by components."),uI=k_.object({type:k_.literal("schematic_line"),schematic_line_id:wv("schematic_line"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:gv,y1:gv,x2:gv,y2:gv,stroke_width:gv.nullable().optional(),color:k_.string().default("#000000"),is_dashed:k_.boolean().default(!1),dash_length:gv.optional(),dash_gap:gv.optional(),subcircuit_id:k_.string().optional()}).describe("Draws a styled line on the schematic"),pI=k_.object({type:k_.literal("schematic_rect"),schematic_rect_id:wv("schematic_rect"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,width:gv,height:gv,rotation:vv.default(0),stroke_width:gv.nullable().optional(),color:k_.string().default("#000000"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe("Draws a styled rectangle on the schematic"),mI=k_.object({type:k_.literal("schematic_circle"),schematic_circle_id:wv("schematic_circle"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,radius:gv,stroke_width:gv.nullable().optional(),color:k_.string().default("#000000"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe("Draws a styled circle on the schematic"),gI=k_.object({type:k_.literal("schematic_arc"),schematic_arc_id:wv("schematic_arc"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Iv,radius:gv,start_angle_degrees:vv,end_angle_degrees:vv,direction:k_.enum(["clockwise","counterclockwise"]).default("counterclockwise"),stroke_width:gv.nullable().optional(),color:k_.string().default("#000000"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe("Draws a styled arc on the schematic"),fI=k_.object({type:k_.literal("schematic_trace"),schematic_trace_id:k_.string(),schematic_sheet_id:k_.string().optional(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),yI=k_.enum(["center","left","right","top","bottom"]),_I=k_.object({type:k_.literal("schematic_text"),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:gv,y:gv}),rotation:k_.number().default(0),anchor:k_.union([yI.describe("legacy"),Tv]).default("center"),color:k_.string().default("#000000"),subcircuit_id:k_.string().optional()}),bI=k_.object({type:k_.literal("schematic_port"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_sheet_id:k_.string().optional(),schematic_component_id:k_.string().optional(),center:Iv,facing_direction:k_.enum(["up","down","left","right"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum(["top","bottom","left","right"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe("Defines a port on a schematic component"),xI=k_.object({type:k_.literal("schematic_net_label"),schematic_net_label_id:wv("schematic_net_label"),schematic_sheet_id:k_.string().optional(),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:Iv,anchor_position:Iv.optional(),anchor_side:k_.enum(["top","bottom","left","right"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),vI=Gv.extend({type:k_.literal("schematic_error"),schematic_error_id:k_.string(),error_type:k_.literal("schematic_port_not_found").default("schematic_port_not_found"),subcircuit_id:k_.string().optional()}).describe("Defines a schematic error on the schematic"),SI=Gv.extend({type:k_.literal("schematic_layout_error"),schematic_layout_error_id:wv("schematic_layout_error"),error_type:k_.literal("schematic_layout_error").default("schematic_layout_error"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe("Error emitted when schematic layout fails for a group"),II=k_.object({type:k_.literal("schematic_debug_object"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),CI=II.extend({shape:k_.literal("rect"),center:Iv,size:Nv}),PI=II.extend({shape:k_.literal("line"),start:Iv,end:Iv}),MI=II.extend({shape:k_.literal("point"),center:Iv}),NI=k_.discriminatedUnion("shape",[CI,PI,MI]),wI=k_.object({type:k_.literal("schematic_voltage_probe"),schematic_voltage_probe_id:k_.string(),schematic_sheet_id:k_.string().optional(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:Iv,schematic_trace_id:k_.string(),voltage:uv.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:Tv.optional()}).describe("Defines a voltage probe measurement point on a schematic trace"),TI=k_.object({type:k_.literal("schematic_manual_edit_conflict_warning"),schematic_manual_edit_conflict_warning_id:wv("schematic_manual_edit_conflict_warning"),warning_type:k_.literal("schematic_manual_edit_conflict_warning").default("schematic_manual_edit_conflict_warning"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe("Warning emitted when a component has both manual placement and explicit schX/schY coordinates"),RI=k_.object({type:k_.literal("schematic_group"),schematic_group_id:wv("schematic_group"),schematic_sheet_id:k_.string().optional(),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:pv,height:pv,center:Iv,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe("Defines a group of components on the schematic"),EI=k_.object({type:k_.literal("schematic_table"),schematic_table_id:wv("schematic_table"),schematic_sheet_id:k_.string().optional(),anchor_position:Iv,column_widths:k_.array(gv),row_heights:k_.array(gv),cell_padding:gv.optional(),border_width:gv.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:Tv.optional()}).describe("Defines a table on the schematic"),AI=k_.object({type:k_.literal("schematic_table_cell"),schematic_table_cell_id:wv("schematic_table_cell"),schematic_sheet_id:k_.string().optional(),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:Iv,width:gv,height:gv,horizontal_align:k_.enum(["left","center","right"]).optional(),vertical_align:k_.enum(["top","middle","bottom"]).optional(),font_size:gv.optional(),subcircuit_id:k_.string().optional()}).describe("Defines a cell within a schematic_table"),OI=k_.object({type:k_.literal("schematic_sheet"),schematic_sheet_id:wv("schematic_sheet"),name:k_.string().optional(),sheet_index:k_.number().optional(),subcircuit_id:k_.string().optional(),outline_color:k_.string().optional()}).describe("Defines a schematic sheet or page that components can be placed on"),kI=k_.object({x:gv,y:gv,bulge:k_.number().optional()}),LI=k_.object({vertices:k_.array(kI)}),DI=k_.object({outer_ring:LI,inner_rings:k_.array(LI).default([])}),zI=k_.object({x:gv,y:gv,via:k_.boolean().optional(),via_to_layer:GS.optional()}),FI=k_.array(zI),BI=k_.object({x:gv,y:gv,via:k_.boolean().optional(),to_layer:GS.optional(),trace_width:gv.optional()}),jI=k_.object({min_trace_width:pv.optional(),min_board_edge_clearance:pv.optional(),min_via_hole_edge_to_via_hole_edge_clearance:pv.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:pv.optional(),min_trace_to_pad_edge_clearance:pv.optional(),min_pad_edge_to_pad_edge_clearance:pv.optional(),min_same_net_trace_edge_to_trace_edge_clearance:pv.optional(),min_different_net_trace_edge_to_trace_edge_clearance:pv.optional(),min_via_edge_to_pad_edge_clearance:pv.optional(),min_via_hole_diameter:pv.optional(),min_via_pad_diameter:pv.optional()}),$I=k_.object({type:k_.literal("pcb_component"),pcb_component_id:wv("pcb_component"),source_component_id:k_.string(),center:Iv,layer:GS,rotation:vv,display_offset_x:k_.string().optional().describe("How to display the x offset for this part, usually corresponding with how the user specified it"),display_offset_y:k_.string().optional().describe("How to display the y offset for this part, usually corresponding with how the user specified it"),width:pv,height:pv,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum(["packed","relative_to_group_anchor","relative_to_another_component","none"]).optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:Iv.optional(),insertion_direction:k_.enum(["from_above","from_left","from_right","from_front","from_back"]).optional(),metadata:k_.object({kicad_footprint:jv.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe("Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath")}).describe("Defines a component on the PCB"),YI=k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:wv("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("circle"),hole_diameter:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),XI=YI.describe("Defines a circular hole on the PCB"),VI=k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:wv("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("rect"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),WI=VI.describe("Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square."),HI=k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:wv("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum(["circle","square"]),hole_diameter:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),GI=HI.describe("Defines a circular or square hole on the PCB"),UI=k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:wv("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("oval"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),ZI=UI.describe("Defines an oval hole on the PCB"),qI=k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:wv("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("pill"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),JI=qI.describe("Defines a pill-shaped hole on the PCB"),KI=k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:wv("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("rotated_pill"),hole_width:k_.number(),hole_height:k_.number(),x:gv,y:gv,ccw_rotation:vv,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),QI=KI.describe("Defines a rotated pill-shaped hole on the PCB"),tC=HI.or(UI).or(qI).or(KI).or(YI).or(VI),eC=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("circle"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv("pcb_plated_hole"),soldermask_margin:k_.number().optional()}),nC=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.enum(["oval","pill"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,ccw_rotation:vv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv("pcb_plated_hole"),soldermask_margin:k_.number().optional()}),oC=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("circular_hole_with_rect_pad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal("circle"),pad_shape:k_.literal("rect"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv("pcb_plated_hole"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:vv.optional()}),iC=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("pill_hole_with_rect_pad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal("pill"),pad_shape:k_.literal("rect"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv("pcb_plated_hole"),soldermask_margin:k_.number().optional()}),rC=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("rotated_pill_hole_with_rect_pad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal("rotated_pill"),pad_shape:k_.literal("rect"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:vv,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:vv,hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv("pcb_plated_hole"),soldermask_margin:k_.number().optional()}),sC=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("hole_with_polygon_pad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum(["circle","oval","pill","rotated_pill"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:gv,y:gv})).min(3),hole_offset_x:gv.default(0),hole_offset_y:gv.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:gv,y:gv,layers:k_.array(GS),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:wv("pcb_plated_hole"),soldermask_margin:k_.number().optional(),ccw_rotation:vv.optional()}),aC=k_.union([eC,nC,oC,iC,rC,sC]),cC=k_.object({type:k_.literal("pcb_port"),pcb_port_id:wv("pcb_port"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:gv,y:gv,layers:k_.array(GS),is_board_pinout:k_.boolean().optional()}).describe("Defines a port on the PCB"),lC=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("circle"),pcb_smtpad_id:wv("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,radius:k_.number(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),dC=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("rect"),pcb_smtpad_id:wv("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),hC=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("rotated_rect"),pcb_smtpad_id:wv("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:vv,layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),uC=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("pill"),pcb_smtpad_id:wv("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),pC=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("rotated_pill"),pcb_smtpad_id:wv("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:vv,layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),mC=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("polygon"),pcb_smtpad_id:wv("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(Iv),layer:GS,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),gC=k_.discriminatedUnion("shape",[lC,dC,hC,pC,uC,mC]).describe("Defines an SMT pad on the PCB"),fC=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("circle"),pcb_solder_paste_id:wv("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,radius:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),yC=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("rect"),pcb_solder_paste_id:wv("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),_C=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("pill"),pcb_solder_paste_id:wv("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),radius:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),bC=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("rotated_rect"),pcb_solder_paste_id:wv("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),ccw_rotation:gv,layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),xC=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("oval"),pcb_solder_paste_id:wv("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:gv,y:gv,width:k_.number(),height:k_.number(),layer:GS,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),vC=k_.union([fC,yC,_C,bC,xC]).describe("Defines solderpaste on the PCB"),SC=k_.object({type:k_.literal("pcb_text"),pcb_text_id:wv("pcb_text"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:Iv,layer:GS,width:pv,height:pv,lines:k_.number(),align:k_.enum(["bottom-left"])}).describe("Defines text on the PCB"),IC=k_.object({route_type:k_.literal("wire"),x:gv,y:gv,width:gv,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:GS}),CC=k_.object({route_type:k_.literal("via"),x:gv,y:gv,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:gv.optional(),outer_diameter:gv.optional(),from_layer:GS,to_layer:GS}),PC=k_.object({route_type:k_.literal("through_pad"),start:Iv,end:Iv,width:gv,start_layer:GS,end_layer:GS,pcb_smtpad_id:k_.string().optional(),pcb_plated_hole_id:k_.string().optional()}),MC=k_.union([IC,CC,PC]),NC=k_.object({type:k_.literal("pcb_trace"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:wv("pcb_trace"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum(["constant","interpolated"]).default("constant").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(MC)}).describe("Defines a trace on the PCB"),wC=k_.object({type:k_.literal("pcb_trace_warning"),pcb_trace_warning_id:wv("pcb_trace_warning"),warning_type:k_.literal("pcb_trace_warning").default("pcb_trace_warning"),message:k_.string(),center:Iv.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines a trace warning on the PCB"),TC=k_.object({type:k_.literal("pcb_trace_too_long_warning"),pcb_trace_too_long_warning_id:wv("pcb_trace_too_long_warning"),warning_type:k_.literal("pcb_trace_too_long_warning").default("pcb_trace_too_long_warning"),message:k_.string(),pcb_trace_id:k_.string(),source_net_id:k_.string().optional(),source_trace_id:k_.string().optional(),actual_trace_length:gv,maximum_trace_length:gv,subcircuit_id:k_.string().optional()}).describe("Warning emitted when a PCB trace is longer than its maximum allowed length"),RC=Gv.extend({type:k_.literal("pcb_trace_error"),pcb_trace_error_id:wv("pcb_trace_error"),error_type:k_.literal("pcb_trace_error").default("pcb_trace_error"),center:Iv.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines a trace error on the PCB"),EC=Gv.extend({type:k_.literal("pcb_trace_missing_error"),pcb_trace_missing_error_id:wv("pcb_trace_missing_error"),error_type:k_.literal("pcb_trace_missing_error").default("pcb_trace_missing_error"),center:Iv.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines an error when a source trace has no corresponding PCB trace"),AC=Gv.extend({type:k_.literal("pcb_port_not_matched_error"),pcb_error_id:wv("pcb_error"),error_type:k_.literal("pcb_port_not_matched_error").default("pcb_port_not_matched_error"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines a trace error on the PCB where a port is not matched"),OC=Gv.extend({type:k_.literal("pcb_port_not_connected_error"),pcb_port_not_connected_error_id:wv("pcb_port_not_connected_error"),error_type:k_.literal("pcb_port_not_connected_error").default("pcb_port_not_connected_error"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines an error when a pcb port is not connected to any trace"),kC=k_.object({type:k_.literal("pcb_net"),pcb_net_id:wv("pcb_net"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe("Defines a net on the PCB"),LC=k_.object({type:k_.literal("pcb_via"),pcb_via_id:wv("pcb_via"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:gv,y:gv,outer_diameter:gv.default("0.6mm"),hole_diameter:gv.default("0.25mm"),from_layer:GS.optional(),to_layer:GS.optional(),layers:k_.array(GS),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe("Defines a via on the PCB"),DC=k_.object({type:k_.literal("pcb_board"),pcb_board_id:wv("pcb_board"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:pv.optional(),height:pv.optional(),center:Iv,display_offset_x:k_.string().optional().describe("How to display the x offset for this board, usually corresponding with how the user specified it"),display_offset_y:k_.string().optional().describe("How to display the y offset for this board, usually corresponding with how the user specified it"),thickness:pv.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(Iv).optional(),shape:k_.enum(["rect","polygon"]).optional(),material:k_.enum(["fr4","fr1"]).default("fr4"),solder_mask_color:k_.string().optional(),silkscreen_color:k_.string().optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.optional(),position_mode:k_.enum(["relative_to_panel_anchor","none"]).optional()}).merge(jI).describe("Defines the board outline of the PCB"),zC=k_.object({type:k_.literal("pcb_panel"),pcb_panel_id:wv("pcb_panel"),width:pv,height:pv,center:Iv,thickness:pv.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe("Defines a PCB panel that can contain multiple boards"),FC=Gv.extend({type:k_.literal("pcb_placement_error"),pcb_placement_error_id:wv("pcb_placement_error"),error_type:k_.literal("pcb_placement_error").default("pcb_placement_error"),subcircuit_id:k_.string().optional()}).describe("Defines a placement error on the PCB"),BC=Gv.extend({type:k_.literal("pcb_panelization_placement_error"),pcb_panelization_placement_error_id:wv("pcb_panelization_placement_error"),error_type:k_.literal("pcb_panelization_placement_error").default("pcb_panelization_placement_error"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Defines a panelization placement error on the PCB"),jC=k_.object({type:k_.literal("pcb_trace_hint"),pcb_trace_hint_id:wv("pcb_trace_hint"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(BI),subcircuit_id:k_.string().optional()}).describe("A hint that can be used during generation of a PCB trace"),$C=k_.object({type:k_.literal("pcb_silkscreen_line"),pcb_silkscreen_line_id:wv("pcb_silkscreen_line"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:gv.default("0.1mm"),x1:gv,y1:gv,x2:gv,y2:gv,layer:US}).describe("Defines a silkscreen line on the PCB"),YC=k_.object({type:k_.literal("pcb_silkscreen_path"),pcb_silkscreen_path_id:wv("pcb_silkscreen_path"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,route:k_.array(Iv),stroke_width:pv}).describe("Defines a silkscreen path on the PCB"),XC=k_.object({type:k_.literal("pcb_silkscreen_text"),pcb_silkscreen_text_id:wv("pcb_silkscreen_text"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:gv.default("0.2mm"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:pv,top:pv,bottom:pv,right:pv}).default({left:"0.2mm",top:"0.2mm",bottom:"0.2mm",right:"0.2mm"}).optional(),ccw_rotation:k_.number().optional(),layer:GS,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:Tv.default("center")}).describe("Defines silkscreen text on the PCB"),VC=k_.object({type:k_.literal("pcb_copper_text"),pcb_copper_text_id:wv("pcb_copper_text"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:gv.default("0.2mm"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:pv,top:pv,bottom:pv,right:pv}).default({left:"0.2mm",top:"0.2mm",bottom:"0.2mm",right:"0.2mm"}).optional(),ccw_rotation:k_.number().optional(),layer:GS,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:Tv.default("center")}).describe("Defines copper text on the PCB"),WC=k_.object({type:k_.literal("pcb_silkscreen_rect"),pcb_silkscreen_rect_id:wv("pcb_silkscreen_rect"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:GS,stroke_width:pv.default("1mm"),corner_radius:pv.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe("Defines a silkscreen rect on the PCB"),HC=k_.object({type:k_.literal("pcb_silkscreen_circle"),pcb_silkscreen_circle_id:wv("pcb_silkscreen_circle"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:pv,layer:US,stroke_width:pv.default("1mm"),is_filled:k_.boolean().optional()}).describe("Defines a silkscreen circle on the PCB"),GC=k_.object({type:k_.literal("pcb_silkscreen_oval"),pcb_silkscreen_oval_id:wv("pcb_silkscreen_oval"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius_x:gv,radius_y:gv,layer:US,ccw_rotation:vv.optional()}).describe("Defines a silkscreen oval on the PCB"),UC=k_.object({type:k_.literal("pcb_silkscreen_graphic"),pcb_silkscreen_graphic_id:wv("pcb_silkscreen_graphic"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,image_asset:Ev.optional()}).extend({shape:k_.literal("brep"),brep_shape:DI}).describe("Defines a BRep silkscreen graphic on the PCB"),ZC=k_.discriminatedUnion("shape",[UC]).describe("Defines a silkscreen graphic on the PCB"),qC=k_.object({type:k_.literal("pcb_silkscreen_pill"),pcb_silkscreen_pill_id:wv("pcb_silkscreen_pill"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:GS,ccw_rotation:k_.number().optional()}).describe("Defines a silkscreen pill on the PCB"),JC=k_.object({type:k_.literal("pcb_fabrication_note_text"),pcb_fabrication_note_text_id:wv("pcb_fabrication_note_text"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:gv.default("1mm"),pcb_component_id:k_.string(),text:k_.string(),ccw_rotation:k_.number().optional(),layer:US,anchor_position:Iv.default({x:0,y:0}),anchor_alignment:k_.enum(["center","top_left","top_right","bottom_left","bottom_right"]).default("center"),color:k_.string().optional()}).describe("Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators"),KC=k_.object({type:k_.literal("pcb_fabrication_note_path"),pcb_fabrication_note_path_id:wv("pcb_fabrication_note_path"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:GS,route:k_.array(Iv),stroke_width:pv,color:k_.string().optional()}).describe("Defines a fabrication path on the PCB for fabricators or assemblers"),QC=k_.object({type:k_.literal("pcb_fabrication_note_rect"),pcb_fabrication_note_rect_id:wv("pcb_fabrication_note_rect"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US,stroke_width:pv.default("0.1mm"),corner_radius:pv.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe("Defines a fabrication note rectangle on the PCB"),tP=k_.object({type:k_.literal("pcb_fabrication_note_dimension"),pcb_fabrication_note_dimension_id:wv("pcb_fabrication_note_dimension"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,from:Iv,to:Iv,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:pv.optional(),offset_distance:pv.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:pv.default("1mm"),color:k_.string().optional(),arrow_size:pv.default("1mm")}).describe("Defines a measurement annotation within PCB fabrication notes"),eP=k_.object({type:k_.literal("pcb_note_text"),pcb_note_text_id:wv("pcb_note_text"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:gv.default("1mm"),text:k_.string().optional(),anchor_position:Iv.default({x:0,y:0}),anchor_alignment:k_.enum(["center","top_left","top_right","bottom_left","bottom_right"]).default("center"),layer:US.default("top"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe("Defines a documentation note in text on the PCB"),nP=k_.object({type:k_.literal("pcb_note_rect"),pcb_note_rect_id:wv("pcb_note_rect"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US.default("top"),stroke_width:pv.default("0.1mm"),corner_radius:pv.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe("Defines a rectangular documentation note on the PCB"),oP=k_.object({type:k_.literal("pcb_note_path"),pcb_note_path_id:wv("pcb_note_path"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(Iv),layer:US.default("top"),stroke_width:pv.default("0.1mm"),color:k_.string().optional()}).describe("Defines a polyline documentation note on the PCB"),iP=k_.object({type:k_.literal("pcb_note_line"),pcb_note_line_id:wv("pcb_note_line"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:gv,y1:gv,x2:gv,y2:gv,layer:US.default("top"),stroke_width:gv.default("0.1mm"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe("Defines a straight documentation note line on the PCB"),rP=k_.object({type:k_.literal("pcb_note_dimension"),pcb_note_dimension_id:wv("pcb_note_dimension"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:Iv,to:Iv,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:pv.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:pv.default("1mm"),layer:US.default("top"),color:k_.string().optional(),arrow_size:pv.default("1mm")}).describe("Defines a measurement annotation within PCB documentation notes"),sP=Gv.extend({type:k_.literal("pcb_footprint_overlap_error"),pcb_error_id:wv("pcb_error"),error_type:k_.literal("pcb_footprint_overlap_error").default("pcb_footprint_overlap_error"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe("Error emitted when a pcb footprint overlaps with another element"),aP=Gv.extend({type:k_.literal("pcb_courtyard_overlap_error"),pcb_error_id:wv("pcb_error"),error_type:k_.literal("pcb_courtyard_overlap_error").default("pcb_courtyard_overlap_error"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe("Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another"),cP=k_.object({type:k_.literal("pcb_keepout"),shape:k_.literal("rect"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:gv,height:gv,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal("pcb_keepout"),shape:k_.literal("circle"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:gv,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),lP=k_.object({type:k_.literal("pcb_cutout"),pcb_cutout_id:wv("pcb_cutout"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),dP=lP.extend({shape:k_.literal("rect"),center:Iv,width:pv,height:pv,rotation:vv.optional(),corner_radius:pv.optional()}),hP=lP.extend({shape:k_.literal("circle"),center:Iv,radius:pv}),uP=lP.extend({shape:k_.literal("polygon"),points:k_.array(Iv)}),pP=lP.extend({shape:k_.literal("path"),route:k_.array(Iv),slot_width:pv,slot_length:pv.optional(),space_between_slots:pv.optional(),slot_corner_radius:pv.optional()}),mP=k_.discriminatedUnion("shape",[dP,hP,uP,pP]).describe("Defines a cutout on the PCB, removing board material."),gP=Gv.extend({type:k_.literal("pcb_missing_footprint_error"),pcb_missing_footprint_error_id:wv("pcb_missing_footprint_error"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal("pcb_missing_footprint_error").default("pcb_missing_footprint_error"),source_component_id:k_.string()}).describe("Defines a missing footprint error on the PCB"),fP=Gv.extend({type:k_.literal("external_footprint_load_error"),external_footprint_load_error_id:wv("external_footprint_load_error"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal("external_footprint_load_error").default("external_footprint_load_error")}).describe("Defines an error when an external footprint fails to load"),yP=Gv.extend({type:k_.literal("circuit_json_footprint_load_error"),circuit_json_footprint_load_error_id:wv("circuit_json_footprint_load_error"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal("circuit_json_footprint_load_error").default("circuit_json_footprint_load_error"),circuit_json:k_.array(k_.any()).optional()}).describe("Defines an error when a circuit JSON footprint fails to load"),_P=k_.object({type:k_.literal("pcb_group"),pcb_group_id:wv("pcb_group"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:pv.optional(),height:pv.optional(),center:Iv,display_offset_x:k_.string().optional().describe("How to display the x offset for this group, usually corresponding with how the user specified it"),display_offset_y:k_.string().optional().describe("How to display the y offset for this group, usually corresponding with how the user specified it"),outline:k_.array(Iv).optional(),anchor_position:Iv.optional(),anchor_alignment:Tv.default("center"),position_mode:k_.enum(["packed","relative_to_group_anchor","none"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum(["packed","none"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:pv}).optional(),autorouter_used_string:k_.string().optional()}).describe("Defines a group of components on the PCB"),bP=Gv.extend({type:k_.literal("pcb_autorouting_error"),pcb_error_id:wv("pcb_autorouting_error"),error_type:k_.literal("pcb_autorouting_error").default("pcb_autorouting_error"),subcircuit_id:k_.string().optional()}).describe("The autorouting has failed to route a portion of the board"),xP=k_.object({type:k_.literal("pcb_manual_edit_conflict_warning"),pcb_manual_edit_conflict_warning_id:wv("pcb_manual_edit_conflict_warning"),warning_type:k_.literal("pcb_manual_edit_conflict_warning").default("pcb_manual_edit_conflict_warning"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe("Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates"),vP=k_.enum(["x-","x+","y+","y-"]),SP=k_.object({type:k_.literal("pcb_connector_not_in_accessible_orientation_warning"),pcb_connector_not_in_accessible_orientation_warning_id:wv("pcb_connector_not_in_accessible_orientation_warning"),warning_type:k_.literal("pcb_connector_not_in_accessible_orientation_warning").default("pcb_connector_not_in_accessible_orientation_warning"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:vP,recommended_facing_direction:vP,subcircuit_id:k_.string().optional()}).describe("Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction"),IP=k_.object({type:k_.literal("supplier_footprint_mismatch_warning"),supplier_footprint_mismatch_warning_id:wv("supplier_footprint_mismatch_warning"),warning_type:k_.literal("supplier_footprint_mismatch_warning").default("supplier_footprint_mismatch_warning"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:Uv.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe("Warning emitted when a supplier part footprint does not match the expected footprint"),CP=k_.object({type:k_.literal("pcb_breakout_point"),pcb_breakout_point_id:wv("pcb_breakout_point"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:gv,y:gv}).describe("Defines a routing target within a pcb_group for a source_trace or source_net"),PP=k_.object({type:k_.literal("pcb_ground_plane"),pcb_ground_plane_id:wv("pcb_ground_plane"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Defines a ground plane on the PCB"),MP=k_.object({type:k_.literal("pcb_ground_plane_region"),pcb_ground_plane_region_id:wv("pcb_ground_plane_region"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:GS,points:k_.array(Iv)}).describe("Defines a polygon region of a ground plane"),NP=k_.object({type:k_.literal("pcb_thermal_spoke"),pcb_thermal_spoke_id:wv("pcb_thermal_spoke"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:gv,spoke_inner_diameter:gv,spoke_outer_diameter:gv,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Pattern for connecting a ground plane to a plated hole"),wP=k_.object({type:k_.literal("pcb_copper_pour"),pcb_copper_pour_id:wv("pcb_copper_pour"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:GS,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),TP=wP.extend({shape:k_.literal("rect"),center:Iv,width:pv,height:pv,rotation:vv.optional()}),RP=wP.extend({shape:k_.literal("brep"),brep_shape:DI}),EP=wP.extend({shape:k_.literal("polygon"),points:k_.array(Iv)}),AP=k_.discriminatedUnion("shape",[TP,RP,EP]).describe("Defines a copper pour on the PCB."),OP=Gv.extend({type:k_.literal("pcb_component_outside_board_error"),pcb_component_outside_board_error_id:wv("pcb_component_outside_board_error"),error_type:k_.literal("pcb_component_outside_board_error").default("pcb_component_outside_board_error"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Iv,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe("Error emitted when a PCB component is placed outside the board boundaries"),kP=Gv.extend({type:k_.literal("pcb_component_not_on_board_edge_error"),pcb_component_not_on_board_edge_error_id:wv("pcb_component_not_on_board_edge_error"),error_type:k_.literal("pcb_component_not_on_board_edge_error").default("pcb_component_not_on_board_edge_error"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Iv,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when a component that must be placed on the board edge is centered away from the edge"),LP=Gv.extend({type:k_.literal("pcb_component_invalid_layer_error"),pcb_component_invalid_layer_error_id:wv("pcb_component_invalid_layer_error"),error_type:k_.literal("pcb_component_invalid_layer_error").default("pcb_component_invalid_layer_error"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:GS,subcircuit_id:k_.string().optional()}).describe("Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)"),DP=Gv.extend({type:k_.literal("pcb_via_clearance_error"),pcb_error_id:wv("pcb_error"),error_type:k_.literal("pcb_via_clearance_error").default("pcb_via_clearance_error"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when vias are closer than the allowed clearance"),zP=Gv.extend({type:k_.literal("pcb_via_trace_clearance_error"),pcb_via_trace_clearance_error_id:wv("pcb_via_trace_clearance_error"),error_type:k_.literal("pcb_via_trace_clearance_error").default("pcb_via_trace_clearance_error"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when a via and trace are closer than the allowed clearance"),FP=Gv.extend({type:k_.literal("pcb_pad_pad_clearance_error"),pcb_pad_pad_clearance_error_id:wv("pcb_pad_pad_clearance_error"),error_type:k_.literal("pcb_pad_pad_clearance_error").default("pcb_pad_pad_clearance_error"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when pads are closer than the allowed clearance"),BP=Gv.extend({type:k_.literal("pcb_pad_trace_clearance_error"),pcb_pad_trace_clearance_error_id:wv("pcb_pad_trace_clearance_error"),error_type:k_.literal("pcb_pad_trace_clearance_error").default("pcb_pad_trace_clearance_error"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:gv.optional(),actual_clearance:gv.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when a pad and trace are closer than allowed clearance"),jP=k_.object({type:k_.literal("pcb_courtyard_rect"),pcb_courtyard_rect_id:wv("pcb_courtyard_rect"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,layer:US,ccw_rotation:vv.optional(),color:k_.string().optional()}).describe("Defines a courtyard rectangle on the PCB"),$P=k_.object({type:k_.literal("pcb_courtyard_outline"),pcb_courtyard_outline_id:wv("pcb_courtyard_outline"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,outline:k_.array(Iv).min(2)}).describe("Defines a courtyard outline on the PCB"),YP=k_.object({type:k_.literal("pcb_courtyard_polygon"),pcb_courtyard_polygon_id:wv("pcb_courtyard_polygon"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:US,points:k_.array(Iv).min(3),color:k_.string().optional()}).describe("Defines a courtyard polygon on the PCB"),XP=k_.object({type:k_.literal("pcb_courtyard_circle"),pcb_courtyard_circle_id:wv("pcb_courtyard_circle"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,radius:pv,layer:US,color:k_.string().optional()}).describe("Defines a courtyard circle on the PCB"),VP=k_.object({type:k_.literal("pcb_courtyard_pill"),pcb_courtyard_pill_id:wv("pcb_courtyard_pill"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Iv,width:pv,height:pv,radius:pv,layer:US,color:k_.string().optional()}).describe("Defines a courtyard pill on the PCB"),WP=["obj","stl","3mf","gltf","glb","step","wrl"],HP=["x+","x-","y+","y-","z+","z-"],GP={obj:"z+",stl:"z+","3mf":"z+",gltf:"y+",glb:"y+",step:"z+",wrl:"y+"},UP=k_.object({type:k_.literal("cad_component"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:Pv,rotation:Pv.optional(),size:Pv.optional(),layer:GS.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:Ev.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum(HP).optional().describe('The direction in the model\'s coordinate space that is considered "up" or "coming out of the board surface"'),model_origin_position:Pv.optional(),model_origin_alignment:k_.enum(["unknown","center","center_of_component_on_board_surface","bottom_center_of_component"]).optional(),model_object_fit:k_.enum(["contain_within_bounds","fill_bounds"]).optional().default("contain_within_bounds"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),show_as_bounding_box:k_.boolean().optional(),anchor_alignment:k_.enum(["center","center_of_component_on_board_surface"]).optional().default("center")}).describe("Defines a component on the PCB"),ZP=k_.enum(["sinewave","square","triangle","sawtooth"]),qP=k_.union([k_.string(),k_.number()]).transform(t=>"string"==typeof t?t.endsWith("%")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,"Duty cycle must be non-negative").max(1,"Duty cycle cannot be greater than 100%")),JP=k_.object({type:k_.literal("simulation_voltage_source"),simulation_voltage_source_id:wv("simulation_voltage_source"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:uv}).describe("Defines a DC voltage source for simulation"),KP=k_.object({type:k_.literal("simulation_voltage_source"),simulation_voltage_source_id:wv("simulation_voltage_source"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:uv.optional(),frequency:mv.optional(),peak_to_peak_voltage:uv.optional(),wave_shape:ZP.optional(),phase:vv.optional(),duty_cycle:qP.optional(),pulse_delay:bv.optional(),rise_time:bv.optional(),fall_time:bv.optional(),pulse_width:bv.optional(),period:bv.optional()}).describe("Defines an AC voltage source for simulation"),QP=k_.union([JP,KP]).describe("Defines a voltage source for simulation"),tM=k_.union([k_.string(),k_.number()]).transform(t=>"string"==typeof t?t.endsWith("%")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,"Duty cycle must be non-negative").max(1,"Duty cycle cannot be greater than 100%")),eM=k_.object({type:k_.literal("simulation_current_source"),simulation_current_source_id:wv("simulation_current_source"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:fv}).describe("Defines a DC current source for simulation"),nM=k_.object({type:k_.literal("simulation_current_source"),simulation_current_source_id:wv("simulation_current_source"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:fv.optional(),frequency:mv.optional(),peak_to_peak_current:fv.optional(),wave_shape:ZP.optional(),phase:vv.optional(),duty_cycle:tM.optional()}).describe("Defines an AC current source for simulation"),oM=k_.union([eM,nM]).describe("Defines a current source for simulation"),iM=k_.union([k_.literal("spice_dc_sweep"),k_.literal("spice_dc_operating_point"),k_.literal("spice_transient_analysis"),k_.literal("spice_ac_analysis")]),rM=k_.object({method:k_.enum(["trap","gear"]).optional(),reltol:k_.union([k_.number(),k_.string()]).optional(),abstol:k_.union([k_.number(),k_.string()]).optional(),vntol:k_.union([k_.number(),k_.string()]).optional()}).describe("SPICE solver options for a simulation experiment"),sM=k_.object({type:k_.literal("simulation_experiment"),simulation_experiment_id:wv("simulation_experiment"),name:k_.string(),experiment_type:iM,time_per_step:yv.optional(),start_time_ms:bv.optional(),end_time_ms:bv.optional(),spice_options:rM.optional()}).describe("Defines a simulation experiment configuration"),aM=k_.object({type:k_.literal("simulation_transient_voltage_graph"),simulation_transient_voltage_graph_id:wv("simulation_transient_voltage_graph"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:yv,start_time_ms:bv,end_time_ms:bv,name:k_.string().optional(),color:k_.string().optional()}).describe("Stores voltage measurements over time for a simulation"),cM=k_.object({type:k_.literal("simulation_transient_current_graph"),simulation_transient_current_graph_id:wv("simulation_transient_current_graph"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),current_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:yv,start_time_ms:bv,end_time_ms:bv,name:k_.string().optional(),color:k_.string().optional()}).describe("Stores current measurements over time for a simulation"),lM=k_.object({type:k_.literal("simulation_switch"),simulation_switch_id:wv("simulation_switch"),source_component_id:k_.string().optional(),closes_at:bv.optional(),opens_at:bv.optional(),starts_closed:k_.boolean().optional(),switching_frequency:mv.optional()}).describe("Defines a switch for simulation timing control"),dM=k_.object({type:k_.literal("simulation_voltage_probe"),simulation_voltage_probe_id:wv("simulation_voltage_probe"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe("Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.").superRefine((t,e)=>{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n&&o?e.addIssue({code:k_.ZodIssueCode.custom,message:"Cannot mix port and net connections in a differential probe."}):n?t.signal_input_source_port_id&&t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id."}):o&&(t.signal_input_source_net_id&&t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id."}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id&&e.addIssue({code:k_.ZodIssueCode.custom,message:"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id."})}),hM=k_.object({type:k_.literal("simulation_current_probe"),simulation_current_probe_id:wv("simulation_current_probe"),source_component_id:k_.string().optional(),name:k_.string().optional(),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe("Defines a current probe for simulation. It measures current flowing from the positive endpoint to the negative endpoint.").superRefine((t,e)=>{const n=!!t.positive_source_port_id,o=!!t.negative_source_port_id,i=!!t.positive_source_net_id,r=!!t.negative_source_net_id,s=n||o,a=i||r;s&&a?e.addIssue({code:k_.ZodIssueCode.custom,message:"Cannot mix port and net connections in a current probe."}):s?n&&o||e.addIssue({code:k_.ZodIssueCode.custom,message:"Current probe using source ports requires both positive_source_port_id and negative_source_port_id."}):a?i&&r||e.addIssue({code:k_.ZodIssueCode.custom,message:"Current probe using source nets requires both positive_source_net_id and negative_source_net_id."}):e.addIssue({code:k_.ZodIssueCode.custom,message:"A current probe must have either positive/negative source port ids or positive/negative source net ids."})}),uM=Gv.extend({type:k_.literal("simulation_unknown_experiment_error"),simulation_unknown_experiment_error_id:wv("simulation_unknown_experiment_error"),error_type:k_.literal("simulation_unknown_experiment_error").default("simulation_unknown_experiment_error"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("An unknown error occurred during the simulation experiment."),pM=k_.object({type:k_.literal("simulation_op_amp"),simulation_op_amp_id:wv("simulation_op_amp"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe("Defines a simple ideal operational amplifier for simulation"),mM=k_.object({type:k_.literal("simulation_spice_subcircuit"),simulation_spice_subcircuit_id:wv("simulation_spice_subcircuit"),source_component_id:k_.string(),spice_pin_to_source_port_map:k_.record(k_.string(),k_.string()),subcircuit_source:k_.string()}).describe("Defines a custom SPICE subcircuit model for simulation"),gM=t=>void 0!==t,fM=k_.object({type:k_.literal("simulation_oscilloscope_trace"),simulation_oscilloscope_trace_id:wv("simulation_oscilloscope_trace"),simulation_transient_voltage_graph_id:k_.string().optional(),simulation_transient_current_graph_id:k_.string().optional(),simulation_voltage_probe_id:k_.string().optional(),simulation_current_probe_id:k_.string().optional(),display_name:k_.string().optional(),color:k_.string().optional(),display_center_value:k_.number().optional(),display_center_offset_divs:k_.number().optional(),volts_per_div:k_.number().positive().optional(),amps_per_div:k_.number().positive().optional()}).describe("Defines how a simulation measurement is rendered as an oscilloscope-style trace.").superRefine((t,e)=>{const n=[t.simulation_transient_voltage_graph_id,t.simulation_voltage_probe_id].filter(gM).length,o=[t.simulation_transient_current_graph_id,t.simulation_current_probe_id].filter(gM).length;n+o!==1&&e.addIssue({code:k_.ZodIssueCode.custom,message:"An oscilloscope trace must reference exactly one voltage graph, current graph, voltage probe, or current probe."}),n>0&&void 0!==t.amps_per_div&&e.addIssue({code:k_.ZodIssueCode.custom,message:"Voltage oscilloscope traces must use volts_per_div, not amps_per_div."}),o>0&&void 0!==t.volts_per_div&&e.addIssue({code:k_.ZodIssueCode.custom,message:"Current oscilloscope traces must use amps_per_div, not volts_per_div."})}),yM=k_.union([BS,zS,FS,DS,$S,jS,nS,qv,Kv,tS,Jv,oS,cS,lS,pS,gS,fS,vS,yS,_S,bS,xS,hS,dS,VS,ZS,YS,SS,PS,MS,wS,qS,TS,RS,JS,KS,QS,tI,eI,nI,OS,kS,XS,$I,tC,gP,fP,yP,xP,SP,IP,aC,cP,cC,kC,SC,NC,wC,TC,LC,gC,vC,DC,zC,_P,jC,$C,YC,XC,qC,VC,WC,HC,GC,ZC,RC,EC,FC,BC,AC,OC,DP,zP,FP,BP,KC,JC,QC,tP,eP,nP,oP,iP,rP,bP,sP,aP,CP,mP,PP,MP,NP,AP,OP,kP,LP,jP,$P,YP,XP,VP,oI,_I,uI,pI,mI,gI,lI,hI,bI,fI,iI,vI,SI,xI,NI,wI,TI,RI,OI,EI,AI,UP,QP,oM,sM,aM,cM,lM,dM,hM,fM,uM,pM,mM]),_M=yM;function bM(t,e,n){if(!e||!n)return;let o=t.get(e);o||(o=new Set,t.set(e,o)),o.add(n);let i=t.get(n);i||(i=new Set,t.set(n,i)),i.add(e)}var xM=(t,e={})=>{const n=t;let o=n._internal_store;if(!o){o={counts:{},editCount:0},n._internal_store=o;for(const t of n){const e=t.type,n=t[`${e}_id`];if(!n)continue;const i=Number.parseInt(n.split("_").pop());Number.isNaN(i)||(o.counts[e]=Math.max(o.counts[e]??0,i))}}const i=new Proxy({},{get:(t,r)=>{if("toArray"===r)return()=>(n.editCount=o.editCount,n);if("editCount"===r)return o.editCount;if("subtree"===r)return t=>xM(function(t,e){if(!e.subcircuit_id&&!e.source_group_id)return[...t];let n=e;if(e.subcircuit_id){const o=new Set([e.subcircuit_id]),i=new Map,r=new Map;for(const e of t)if("source_group"===e.type){const t=e.source_group_id,n=e.subcircuit_id;n&&r.set(t,n);const o=e.parent_source_group_id;o&&(i.has(o)||i.set(o,[]),i.get(o).push(t))}let s;for(const[t,n]of r)if(n===e.subcircuit_id){s=t;break}if(s){const t=e=>{const n=i.get(e)||[];for(const e of n){const n=r.get(e);n&&o.add(n),t(e)}};t(s),n={...e,subcircuit_ids:Array.from(o)}}}const o=new Map;for(const e of t){const t=e[`${e.type}_id`];"string"==typeof t&&o.set(t,e)}const i=new Map;for(const e of t){const t=Object.entries(e);for(const[n,r]of t)if("parent_source_group_id"!==n)if(n.endsWith("_id")&&"string"==typeof r)bM(i,e,o.get(r));else if(n.endsWith("_ids")&&Array.isArray(r))for(const t of r)"string"==typeof t&&bM(i,e,o.get(t))}const r=[],s=new Set;for(const e of t){let t=!1;(n.subcircuit_id&&"subcircuit_id"in e&&e.subcircuit_id===n.subcircuit_id||n.subcircuit_ids&&"subcircuit_id"in e&&e.subcircuit_id&&n.subcircuit_ids.includes(e.subcircuit_id)||n.source_group_id&&"source_group_id"in e&&e.source_group_id===n.source_group_id||n.source_group_id&&"member_source_group_ids"in e&&Array.isArray(e.member_source_group_ids)&&e.member_source_group_ids.includes(n.source_group_id))&&(t=!0),t&&(r.push(e),s.add(e))}for(;r.length>0;){const t=r.shift(),e=i.get(t);if(e)for(const t of e)s.has(t)||(s.add(t),r.push(t))}return t.filter(t=>s.has(t))}(n,t),e);if("insert"===r)return t=>{const i=t.type;if(!i)throw new Error("insert requires an element with a type");o.counts[i]??=-1,o.counts[i]++;const r=o.counts[i],s={...t,type:i,[`${i}_id`]:`${i}_${r}`};if(e.validateInserts){(S_[i]??_M).parse(s)}return n.push(s),o.editCount++,s};if("insertAll"===r)return t=>t.map(t=>i.insert(t));const s=r;return{get:t=>n.find(e=>e.type===s&&e[`${s}_id`]===t),getUsing:t=>{const e=Object.keys(t);if(1!==e.length)throw new Error("getUsing requires exactly one key, e.g. { pcb_component_id }");const o=e[0],i=o.replace("_id",""),r=n.find(e=>e.type===i&&e[o]===t[o]);return r?n.find(t=>t.type===s&&t[`${s}_id`]===r[`${s}_id`]):null},getWhere:t=>{const e=Object.keys(t);return n.find(n=>n.type===s&&e.every(e=>n[e]===t[e]))},list:t=>{const e=t?Object.keys(t):[];return n.filter(n=>n.type===s&&e.every(e=>n[e]===t[e]))},insert:t=>{o.counts[s]??=-1,o.counts[s]++;const i=o.counts[s],r={type:s,[`${s}_id`]:`${s}_${i}`,...t};if(e.validateInserts){(S_[s]??_M).parse(r)}return n.push(r),o.editCount++,r},delete:t=>{const e=n.find(e=>e[`${s}_id`]===t);e&&(n.splice(n.indexOf(e),1),o.editCount++)},update:(t,e)=>{const i=n.find(e=>e.type===s&&e[`${s}_id`]===t);return i?(Object.assign(i,e),o.editCount++,i):null},select:t=>{if("source_component"===s)return n.find(e=>"source_component"===e.type&&e.name===t.replace(/\./g,""));if("pcb_port"===s||"source_port"===s||"schematic_port"===s){const[e,o]=t.replace(/\./g,"").split(/[\s\>]+/),i=n.find(t=>"source_component"===t.type&&t.name===e);if(!i)return null;const r=n.find(t=>"source_port"===t.type&&t.source_component_id===i.source_component_id&&(t.name===o||(t.port_hints??[]).includes(o)));if(!r)return null;if("source_port"===s)return r;if("pcb_port"===s)return n.find(t=>"pcb_port"===t.type&&t.source_port_id===r.source_port_id);if("schematic_port"===s)return n.find(t=>"schematic_port"===t.type&&t.source_port_id===r.source_port_id)}}}}});return i};xM.unparsed=xM;var vM=xM;function SM(t){const e=t.type;return`${e}:${t[`${e}_id`]}`}var IM=(t,e={})=>{let n=t._internal_store_indexed;if(!n){n={counts:{},editCount:0,indexes:{}};for(const e of t){const t=e.type,o=e[`${t}_id`];if(!o)continue;const i=Number.parseInt(o.split("_").pop()||"");Number.isNaN(i)||(n.counts[t]=Math.max(n.counts[t]??0,i))}const o=e.indexConfig||{},i=n.indexes;if(o.byId&&(i.byId=new Map),o.byType&&(i.byType=new Map),o.byRelation&&(i.byRelation=new Map),o.bySubcircuit&&(i.bySubcircuit=new Map),o.byCustomField&&o.byCustomField.length>0){i.byCustomField=new Map;for(const t of o.byCustomField)i.byCustomField.set(t,new Map)}for(const e of t){if(o.byId){const t=SM(e);i.byId.set(t,e)}if(o.byType){const t=i.byType.get(e.type)||[];t.push(e),i.byType.set(e.type,t)}if(o.byRelation){const t=Object.entries(e);for(const[n,o]of t)if(n.endsWith("_id")&&n!==`${e.type}_id`&&"string"==typeof o){const t=i.byRelation.get(n)||new Map,r=t.get(o)||[];r.push(e),t.set(o,r),i.byRelation.set(n,t)}}if(o.bySubcircuit&&"subcircuit_id"in e){const t=e.subcircuit_id;if(t&&"string"==typeof t){const n=i.bySubcircuit.get(t)||[];n.push(e),i.bySubcircuit.set(t,n)}}if(o.byCustomField&&i.byCustomField)for(const t of o.byCustomField)if(t in e){const n=e[t];if(void 0!==n&&("string"==typeof n||"number"==typeof n)){const o=String(n),r=i.byCustomField.get(t),s=r.get(o)||[];s.push(e),r.set(o,s)}}}t._internal_store_indexed=n}return new Proxy({},{get:(o,i)=>{if("toArray"===i)return()=>(t.editCount=n.editCount,t);if("editCount"===i)return n.editCount;const r=i;return{get:o=>{const i=e.indexConfig||{};if(i.byId&&n.indexes.byId)return n.indexes.byId.get(`${r}:${o}`)||null;if(i.byType&&n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=>t[`${r}_id`]===o)||null}return t.find(t=>t.type===r&&t[`${r}_id`]===o)||null},getUsing:o=>{const i=e.indexConfig||{},s=Object.keys(o);if(1!==s.length)throw new Error("getUsing requires exactly one key, e.g. { pcb_component_id }");const a=s[0],c=a.replace("_id","");if(i.byRelation&&n.indexes.byRelation){const e=n.indexes.byRelation.get(a);if(e){const s=(e.get(o[a])||[]).find(t=>t.type===c);if(!s)return null;const l=s[`${r}_id`];if(i.byId&&n.indexes.byId)return n.indexes.byId.get(`${r}:${l}`)||null;if(i.byType&&n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=>t[`${r}_id`]===l)||null}return t.find(t=>t.type===r&&t[`${r}_id`]===l)||null}}const l=t.find(t=>t.type===c&&t[a]===o[a]);return l&&t.find(t=>t.type===r&&t[`${r}_id`]===l[`${r}_id`])||null},getWhere:o=>{const i=e.indexConfig||{},s=Object.keys(o);if(1===s.length&&i.byCustomField&&n.indexes.byCustomField){const t=s[0],e=n.indexes.byCustomField.get(t);if(e){const n=String(o[t]);return(e.get(n)||[]).find(t=>t.type===r)||null}}if("subcircuit_id"in o&&i.bySubcircuit&&n.indexes.bySubcircuit){const t=o.subcircuit_id;return(n.indexes.bySubcircuit.get(t)||[]).find(t=>t.type===r&&s.every(e=>t[e]===o[e]))||null}if(i.byType&&n.indexes.byType){return(n.indexes.byType.get(r)||[]).find(t=>s.every(e=>t[e]===o[e]))||null}return t.find(t=>t.type===r&&s.every(e=>t[e]===o[e]))||null},list:o=>{const i=e.indexConfig||{},s=o?Object.keys(o):[];if(0===s.length&&i.byType&&n.indexes.byType)return n.indexes.byType.get(r)||[];if(1===s.length&&"subcircuit_id"===s[0]&&i.bySubcircuit&&n.indexes.bySubcircuit){const t=o.subcircuit_id;return(n.indexes.bySubcircuit.get(t)||[]).filter(t=>t.type===r)}let a;return a=i.byType&&n.indexes.byType?n.indexes.byType.get(r)||[]:t.filter(t=>t.type===r),s.length>0?a.filter(t=>s.every(e=>t[e]===o[e])):a},insert:o=>{n.counts[r]??=-1,n.counts[r]++;const i=n.counts[r],s={type:r,[`${r}_id`]:`${r}_${i}`,...o};if(e.validateInserts){(S_[r]??_M).parse(s)}t.push(s),n.editCount++;const a=e.indexConfig||{};if(a.byId&&n.indexes.byId){const t=SM(s);n.indexes.byId.set(t,s)}if(a.byType&&n.indexes.byType){const t=n.indexes.byType.get(r)||[];t.push(s),n.indexes.byType.set(r,t)}if(a.byRelation&&n.indexes.byRelation){const t=Object.entries(s);for(const[e,o]of t)if(e.endsWith("_id")&&e!==`${s.type}_id`&&"string"==typeof o){const t=n.indexes.byRelation.get(e)||new Map,i=t.get(o)||[];i.push(s),t.set(o,i),n.indexes.byRelation.set(e,t)}}if(a.bySubcircuit&&n.indexes.bySubcircuit&&"subcircuit_id"in s){const t=s.subcircuit_id;if(t&&"string"==typeof t){const e=n.indexes.bySubcircuit.get(t)||[];e.push(s),n.indexes.bySubcircuit.set(t,e)}}if(a.byCustomField&&n.indexes.byCustomField)for(const t of a.byCustomField)if(t in s){const e=s[t];if(void 0!==e&&("string"==typeof e||"number"==typeof e)){const o=String(e),i=n.indexes.byCustomField.get(t),r=i.get(o)||[];r.push(s),i.set(o,r)}}return s},delete:o=>{const i=e.indexConfig||{};let s;if(i.byId&&n.indexes.byId)s=n.indexes.byId.get(`${r}:${o}`);else if(i.byType&&n.indexes.byType){const t=n.indexes.byType.get(r)||[];s=t.find(t=>t[`${r}_id`]===o)}else s=t.find(t=>t[`${r}_id`]===o);if(!s)return;const a=t.indexOf(s);if(a>=0&&(t.splice(a,1),n.editCount++),i.byId&&n.indexes.byId){const t=SM(s);n.indexes.byId.delete(t)}if(i.byType&&n.indexes.byType){const t=(n.indexes.byType.get(r)||[]).filter(t=>t[`${r}_id`]!==o);n.indexes.byType.set(r,t)}if(i.byRelation&&n.indexes.byRelation)for(const[t,e]of n.indexes.byRelation.entries())for(const[t,n]of e.entries()){const o=n.filter(t=>t!==s);0===o.length?e.delete(t):e.set(t,o)}if(i.bySubcircuit&&n.indexes.bySubcircuit&&"subcircuit_id"in s){const t=s.subcircuit_id;if(t){const e=(n.indexes.bySubcircuit.get(t)||[]).filter(t=>t!==s);0===e.length?n.indexes.bySubcircuit.delete(t):n.indexes.bySubcircuit.set(t,e)}}if(i.byCustomField&&n.indexes.byCustomField)for(const t of n.indexes.byCustomField.values())for(const[e,n]of t.entries()){const o=n.filter(t=>t!==s);0===o.length?t.delete(e):t.set(e,o)}},update:(o,i)=>{const s=e.indexConfig||{};let a;if(s.byId&&n.indexes.byId)a=n.indexes.byId.get(`${r}:${o}`);else if(s.byType&&n.indexes.byType){const t=n.indexes.byType.get(r)||[];a=t.find(t=>t[`${r}_id`]===o)}else a=t.find(t=>t.type===r&&t[`${r}_id`]===o);if(!a)return null;if(s.byRelation&&n.indexes.byRelation){const t=Object.entries(a);for(const[e,o]of t)if(e.endsWith("_id")&&e!==`${a.type}_id`&&"string"==typeof o&&e in i&&i[e]!==o){const t=n.indexes.byRelation.get(e);if(t){const e=(t.get(o)||[]).filter(t=>t!==a);0===e.length?t.delete(o):t.set(o,e)}}}if(s.bySubcircuit&&n.indexes.bySubcircuit&&"subcircuit_id"in a&&"subcircuit_id"in i){const t=a.subcircuit_id;if(t!==i.subcircuit_id){const e=(n.indexes.bySubcircuit.get(t)||[]).filter(t=>t!==a);0===e.length?n.indexes.bySubcircuit.delete(t):n.indexes.bySubcircuit.set(t,e)}}if(s.byCustomField&&n.indexes.byCustomField)for(const t of s.byCustomField)if(t in a&&t in i&&a[t]!==i[t]){const e=n.indexes.byCustomField.get(t);if(e){const n=String(a[t]),o=(e.get(n)||[]).filter(t=>t!==a);0===o.length?e.delete(n):e.set(n,o)}}if(Object.assign(a,i),n.editCount++,s.byRelation&&n.indexes.byRelation){const t=Object.entries(a);for(const[e,o]of t)if(e.endsWith("_id")&&e!==`${a.type}_id`&&"string"==typeof o&&e in i){const t=n.indexes.byRelation.get(e)||new Map,i=t.get(o)||[];i.includes(a)||(i.push(a),t.set(o,i),n.indexes.byRelation.set(e,t))}}if(s.bySubcircuit&&n.indexes.bySubcircuit&&"subcircuit_id"in a&&"subcircuit_id"in i){const t=a.subcircuit_id;if(t&&"string"==typeof t){const e=n.indexes.bySubcircuit.get(t)||[];e.includes(a)||(e.push(a),n.indexes.bySubcircuit.set(t,e))}}if(s.byCustomField&&n.indexes.byCustomField)for(const t of s.byCustomField)if(t in a&&t in i){const e=a[t];if(void 0!==e&&("string"==typeof e||"number"==typeof e)){const o=String(e),i=n.indexes.byCustomField.get(t),r=i.get(o)||[];r.includes(a)||(r.push(a),i.set(o,r))}}return a},select:e=>{if("source_component"===r)return t.find(t=>"source_component"===t.type&&t.name===e.replace(/\./g,""))||null;if("pcb_port"===r||"source_port"===r||"schematic_port"===r){const[n,o]=e.replace(/\./g,"").split(/[\s\>]+/),i=t.find(t=>"source_component"===t.type&&t.name===n);if(!i)return null;const s=t.find(t=>"source_port"===t.type&&t.source_component_id===i.source_component_id&&(t.name===o||(t.port_hints??[]).includes(o)));if(!s)return null;if("source_port"===r)return s;if("pcb_port"===r)return t.find(t=>"pcb_port"===t.type&&t.source_port_id===s.source_port_id)||null;if("schematic_port"===r)return t.find(t=>"schematic_port"===t.type&&t.source_port_id===s.source_port_id)||null}return null}}}})};IM.unparsed=IM;var CM=t=>t[`${t.type}_id`];function PM(t,e){const n=xM(t).pcb_trace.get(e);if(!n)return`trace[${e}]`;const o=n.route.flatMap(t=>[t.start_pcb_port_id,t.end_pcb_port_id]).filter(Boolean);if(0===o.length)return`trace[${e}]`;return`trace[${o.map(e=>{const n=function(e){const n=xM(t).pcb_port.get(e);if(!n)return null;const o=n.pcb_component_id?xM(t).pcb_component.get(n.pcb_component_id):void 0;if(!o)return null;const i=xM(t).source_component.get(o.source_component_id);if(!i)return null;const r=xM(t).source_port.get(n.source_port_id),s=r?.port_hints?r.port_hints[1]:"";return{componentName:i.name,portHint:s}}(e);return n?`.${n.componentName} > port.${n.portHint}`:`port[${e}]`}).join(", ")}]`}var MM=(t,e)=>{const n=xM(t).pcb_port.get(e);if(!n)return`pcb_port[#${e}]`;const o=n.pcb_component_id?xM(t).pcb_component.get(n.pcb_component_id):void 0;if(!o)return`pcb_port[#${e}]`;const i=xM(t).source_component.get(o.source_component_id);if(!i)return`pcb_port[#${e}]`;const r=xM(t).source_port.get(n.source_port_id);if(!r)return`pcb_port[#${e}]`;let s;return s=r?.port_hints&&r.port_hints.length>0||r.port_hints&&r.port_hints.length>0?r.port_hints[0]:e,`pcb_port[.${i.name} > .${s}]`};var NM=(t,e)=>{if("string"==typeof e){const n=((t,e)=>t.find(t=>CM(t)===e)??null)(t,e);return NM(t,n)}switch(e.type){case"pcb_port":return MM(t,e.pcb_port_id);case"pcb_smtpad":return function(t,e){const n=xM(t).pcb_smtpad.get(e);return n&&n.pcb_port_id?MM(t,n.pcb_port_id):`smtpad[${e}]`}(t,e.pcb_smtpad_id);case"pcb_trace":return PM(t,e.pcb_trace_id);case"source_component":return`source_component[${e.name}]`;default:return`${e.type}[#${CM(e)}]`}},wM=(t,e)=>({minX:Math.min(t.minX,e.minX),minY:Math.min(t.minY,e.minY),maxX:Math.max(t.maxX,e.maxX),maxY:Math.max(t.maxY,e.maxY)}),TM=(t,e,n)=>{const o=n/2;return{minX:t-o,minY:e-o,maxX:t+o,maxY:e+o}},RM=(t,e,n,o,i)=>{const r=n/2,s=o/2,a=i*Math.PI/180,c=Math.cos(a),l=Math.sin(a),d=[{x:-r,y:-s},{x:r,y:-s},{x:r,y:s},{x:-r,y:s}].map(n=>({x:t+n.x*c-n.y*l,y:e+n.x*l+n.y*c}));return{minX:Math.min(...d.map(t=>t.x)),minY:Math.min(...d.map(t=>t.y)),maxX:Math.max(...d.map(t=>t.x)),maxY:Math.max(...d.map(t=>t.y))}},EM=t=>{let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t){if(!r.type.startsWith("pcb_"))continue;if("pcb_smtpad"===r.type&&"polygon"===r.shape&&Array.isArray(r.points)){for(const t of r.points)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);continue}if("pcb_hole"===r.type&&"circle"===r.hole_shape){const t=TM(r.x,r.y,r.hole_diameter);e=Math.min(e,t.minX),n=Math.min(n,t.minY),o=Math.max(o,t.maxX),i=Math.max(i,t.maxY);continue}if("pcb_plated_hole"===r.type){let t;if("outer_diameter"in r&&"number"==typeof r.outer_diameter?t=TM(r.x,r.y,r.outer_diameter):"hole_diameter"in r&&"number"==typeof r.hole_diameter&&(t=TM(r.x,r.y,r.hole_diameter)),"rect_pad_width"in r&&"number"==typeof r.rect_pad_width&&"rect_pad_height"in r&&"number"==typeof r.rect_pad_height){const e=RM(r.x,r.y,r.rect_pad_width,r.rect_pad_height,"rect_ccw_rotation"in r?r.rect_ccw_rotation??0:0);t=t?wM(t,e):e}if("hole_diameter"in r&&"number"==typeof r.hole_diameter){const e=TM(r.x+("hole_offset_x"in r?r.hole_offset_x??0:0),r.y+("hole_offset_y"in r?r.hole_offset_y??0:0),r.hole_diameter);t=t?wM(t,e):e}if(t){e=Math.min(e,t.minX),n=Math.min(n,t.minY),o=Math.max(o,t.maxX),i=Math.max(i,t.maxY);continue}}let t,s,a,c;if("x"in r&&"y"in r&&(t=Number(r.x),s=Number(r.y)),"outer_diameter"in r&&(a=Number(r.outer_diameter),c=Number(r.outer_diameter)),"width"in r&&(a=Number(r.width)),"height"in r&&(c=Number(r.height)),"center"in r&&(t=r.center.x,s=r.center.y),void 0!==t&&void 0!==s)e=Math.min(e,t),n=Math.min(n,s),o=Math.max(o,t),i=Math.max(i,s),void 0!==a&&void 0!==c&&(e=Math.min(e,t-a/2),n=Math.min(n,s-c/2),o=Math.max(o,t+a/2),i=Math.max(i,s+c/2)),"radius"in r&&(e=Math.min(e,t-r.radius),n=Math.min(n,s-r.radius),o=Math.max(o,t+r.radius),i=Math.max(i,s+r.radius));else if("pcb_trace"===r.type)for(const t of r.route)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);else if("pcb_courtyard_outline"===r.type)for(const t of r.outline)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);else if("pcb_courtyard_polygon"===r.type)for(const t of r.points)e=Math.min(e,t.x),n=Math.min(n,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y)}return{minX:e,minY:n,maxX:o,maxY:i}},AM=t=>t[`${t.type}_id`],OM={Hz:{baseUnit:"Hz",variants:{MHz:1e6,kHz:1e3,Hz:1}},g:{baseUnit:"g",variants:{kg:1e3,g:1}},"Ω":{baseUnit:"Ω",variants:{"mΩ":.001,"Ω":1,"kΩ":1e3,"KΩ":1e3,kohm:1e3,"MΩ":1e6,"GΩ":1e9,"TΩ":1e12}},V:{baseUnit:"V",variants:{mV:.001,V:1,kV:1e3,KV:1e3,MV:1e6,GV:1e9,TV:1e12}},A:{baseUnit:"A",variants:{"µA":1e-6,mA:.001,ma:.001,A:1,kA:1e3,MA:1e6}},F:{baseUnit:"F",variants:{pF:1e-12,nF:1e-9,"µF":1e-6,uF:1e-6,mF:.001,F:1}},ml:{baseUnit:"ml",variants:{ml:1,mL:1,l:1e3,L:1e3}},deg:{baseUnit:"deg",variants:{rad:180/Math.PI}},ms:{baseUnit:"ms",variants:{fs:1e-12,ps:1e-9,ns:1e-6,us:.001,"µs":.001,ms:1,s:1e3}},mm:{baseUnit:"mm",variants:{nm:1e-6,"µm":.001,um:.001,mm:1,cm:10,dm:100,m:1e3,km:1e6,in:25.4,ft:304.8,IN:25.4,FT:304.8,yd:914.4,mi:1609344,mil:.0254}}},kM=new Set;for(const[t,e]of Object.entries(OM)){kM.add(t);for(const t of Object.keys(e.variants))kM.add(t)}var LM={tera:1e12,T:1e12,giga:1e9,G:1e9,mega:1e6,M:1e6,kilo:1e3,k:1e3,deci:.1,d:.1,centi:.01,c:.01,milli:.001,m:.001,micro:1e-6,u:1e-6,"µ":1e-6,nano:1e-9,n:1e-9,pico:1e-12,p:1e-12};function DM(t){if(null==t)return{parsedUnit:null,unitOfValue:null,value:null};if("string"==typeof t&&t.match(/^-?[\d\.]+$/))return{value:Number.parseFloat(t),parsedUnit:null,unitOfValue:null};if("number"==typeof t)return{value:t,parsedUnit:null,unitOfValue:null};if("object"==typeof t&&"x"in t&&"y"in t){const{parsedUnit:e,unitOfValue:n}=DM(t.x),o=DM(t.x),i=DM(t.y);return null===o.value||null===i.value?{parsedUnit:null,unitOfValue:null,value:null}:{parsedUnit:e,unitOfValue:n,value:{x:o.value,y:i.value}}}const e=t.toString().split("").reverse().join(""),n=e.match(/[^\d\s]+/)?.[0];if(!n)throw new Error(`Could not determine unit: "${t}"`);const o=n.split("").reverse().join(""),i=t.slice(0,-o.length);if(o in LM&&!kM.has(o)){const t=LM[o];return{parsedUnit:null,unitOfValue:null,value:Number.parseFloat(i)*t}}const{baseUnit:r,conversionFactor:s}=function(t){for(const[e,n]of Object.entries(OM))if(t in n.variants)return{baseUnit:n.baseUnit,conversionFactor:n.variants[t]};return{baseUnit:t,conversionFactor:1}}(o);return{parsedUnit:o,unitOfValue:r,value:s*Number.parseFloat(i)}}var zM=k_.string().or(k_.number()).transform(t=>DM(t).value),FM=k_.string().or(k_.number()).transform(t=>DM(t).value).transform(t=>Number.parseFloat(t.toPrecision(12))),BM=k_.string().or(k_.number()).transform(t=>DM(t).value),jM=k_.string().or(k_.number()).transform(t=>DM(t).value),$M=k_.string().or(k_.number()).transform(t=>DM(t).value),YM=k_.string().or(k_.number()).transform(t=>DM(t).value),XM=$M,VM=k_.string().or(k_.number()).transform(t=>DM(t).value),WM=k_.string().or(k_.number()).transform(t=>DM(t).value),HM=WM,GM=k_.string().datetime(),UM=k_.string().or(k_.number()).transform(t=>"number"==typeof t?t:t.endsWith("deg")?Number.parseFloat(t.split("deg")[0]):t.endsWith("rad")?180*Number.parseFloat(t.split("rad")[0])/Math.PI:Number.parseFloat(t)),ZM=k_.number().or(k_.string().endsWith("mAh")).transform(t=>{if("string"==typeof t){const e=t.replace("mAh",""),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error("Invalid capacity");return n}return t}).describe("Battery capacity in mAh"),qM=k_.object({x:XM,y:XM}),JM=k_.object({x:XM,y:XM,z:XM}),KM=k_.object({width:k_.number(),height:k_.number()}),QM=t=>k_.string().optional().default(()=>`${t}_${(t=>{const e="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";return Array.from({length:t},()=>e[Math.floor(62*Math.random())]).join("")})(10)}`),tN=k_.enum(["top_left","top_center","top_right","center_left","center","center_right","bottom_left","bottom_center","bottom_right"]),eN=(k_.enum(["top_silkscreen","bottom_silkscreen","top_copper","bottom_copper","top_soldermask","bottom_soldermask","top_fabrication_note","bottom_fabrication_note","top_user_note","bottom_user_note","top_courtyard","bottom_courtyard","inner1_copper","inner2_copper","inner3_copper","inner4_copper","inner5_copper","inner6_copper","edge_cuts","drill"]),k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()})),nN=qM.extend({rotation:UM.optional()}),oN=k_.object({size:qM.optional(),thickness:XM.optional()}),iN=k_.object({font:oN.optional()}),rN=k_.object({value:k_.string(),at:nN.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:iN.optional()}),sN=k_.object({Reference:rN.optional(),Value:rN.optional(),Datasheet:rN.optional(),Description:rN.optional()}),aN=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),cN=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:nN.optional(),size:qM.optional(),drill:XM.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),lN=k_.object({path:k_.string(),offset:JM.optional(),scale:JM.optional(),rotate:JM.optional()}),dN=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:sN.optional(),attributes:aN.optional(),pads:k_.array(cN).optional(),embeddedFonts:k_.boolean().optional(),model:lN.optional()}),hN=k_.object({hide:k_.boolean().optional()}),uN=k_.object({offset:XM.optional(),hide:k_.boolean().optional()}),pN=k_.object({font:oN.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),mN=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:nN.optional(),effects:pN.optional()}),gN=k_.object({Reference:mN.optional(),Value:mN.optional(),Footprint:mN.optional(),Datasheet:mN.optional(),Description:mN.optional(),ki_keywords:mN.optional(),ki_fp_filters:mN.optional()}),fN=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:hN.optional(),pinNames:uN.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:gN.optional(),embeddedFonts:k_.boolean().optional()}),yN=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),_N=k_.enum(["jlcpcb","macrofab","pcbway","digikey","mouser","lcsc"]),bN=k_.object({type:k_.literal("source_component"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(_N,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),xN=bN.extend({ftype:k_.literal("simple_capacitor"),capacitance:FM,max_voltage_rating:jM.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:XM.optional()}),vN=bN.extend({ftype:k_.literal("simple_resistor"),resistance:zM,display_resistance:k_.string().optional()}),SN=bN.extend({ftype:k_.literal("simple_diode")}),IN=bN.extend({ftype:k_.literal("simple_fiducial")}),CN=SN.extend({ftype:k_.literal("simple_led"),color:k_.string().optional(),wavelength:k_.string().optional()}),PN=bN.extend({ftype:k_.literal("simple_ground")}),MN=bN.extend({ftype:k_.literal("simple_chip")}),NN=bN.extend({ftype:k_.literal("simple_power_source"),voltage:jM}),wN=bN.extend({ftype:k_.literal("simple_current_source"),current:VM,frequency:YM.optional(),peak_to_peak_current:VM.optional(),wave_shape:k_.enum(["sine","square","triangle","sawtooth","dc"]).optional().default("dc"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),TN=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),RN=bN.extend({ftype:k_.literal("simple_fuse"),current_rating_amps:k_.number().describe("Nominal current in amps the fuse is rated for"),voltage_rating_volts:k_.number().describe("Voltage rating in volts, e.g. ±5V would be 5")}),EN=bN.extend({ftype:k_.literal("simple_battery"),capacity:ZM}),AN=bN.extend({ftype:k_.literal("simple_inductor"),inductance:BM,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),ON=bN.extend({ftype:k_.literal("simple_push_button")}),kN=bN.extend({ftype:k_.literal("simple_potentiometer"),max_resistance:zM,display_max_resistance:k_.string().optional()}),LN=bN.extend({ftype:k_.literal("simple_crystal"),frequency:k_.number().describe("Frequency in Hz"),load_capacitance:k_.number().optional().describe("Load capacitance in pF"),pin_variant:k_.enum(["two_pin","four_pin"]).optional()}),DN=bN.extend({ftype:k_.literal("simple_pin_header"),pin_count:k_.number(),gender:k_.enum(["male","female"]).optional().default("male")}),zN=bN.extend({ftype:k_.literal("simple_connector"),standard:k_.enum(["usb_c","m2"]).optional()}),FN=bN.extend({ftype:k_.literal("simple_pinout")}),BN=bN.extend({ftype:k_.literal("simple_resonator"),load_capacitance:FM,equivalent_series_resistance:zM.optional(),frequency:YM}),jN=bN.extend({ftype:k_.literal("simple_transistor"),transistor_type:k_.enum(["npn","pnp"])}),$N=bN.extend({ftype:k_.literal("simple_test_point"),footprint_variant:k_.enum(["pad","through_hole"]).optional(),pad_shape:k_.enum(["rect","circle"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),YN=bN.extend({ftype:k_.literal("simple_mosfet"),channel_type:k_.enum(["n","p"]),mosfet_mode:k_.enum(["enhancement","depletion"])}),XN=bN.extend({ftype:k_.literal("simple_op_amp")}),VN=bN.extend({ftype:k_.literal("simple_switch")}),WN=k_.object({type:k_.literal("source_project_metadata"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),created_at:GM.optional()}),HN=yN.extend({type:k_.literal("source_missing_property_error"),source_missing_property_error_id:QM("source_missing_property_error"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal("source_missing_property_error").default("source_missing_property_error")}).describe("The source code is missing a property"),GN=yN.extend({type:k_.literal("source_failed_to_create_component_error"),source_failed_to_create_component_error_id:QM("source_failed_to_create_component_error"),error_type:k_.literal("source_failed_to_create_component_error").default("source_failed_to_create_component_error"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe("Error emitted when a component fails to be constructed"),UN=yN.extend({type:k_.literal("source_invalid_component_property_error"),source_invalid_component_property_error_id:QM("source_invalid_component_property_error"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal("source_invalid_component_property_error").default("source_invalid_component_property_error")}).describe("The source component property is invalid"),ZN=yN.extend({type:k_.literal("source_trace_not_connected_error"),source_trace_not_connected_error_id:QM("source_trace_not_connected_error"),error_type:k_.literal("source_trace_not_connected_error").default("source_trace_not_connected_error"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe("Occurs when a source trace selector does not match any ports"),qN=k_.object({type:k_.literal("source_property_ignored_warning"),source_property_ignored_warning_id:QM("source_property_ignored_warning"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal("source_property_ignored_warning").default("source_property_ignored_warning"),message:k_.string()}).describe("The source property was ignored"),JN=k_.object({type:k_.literal("source_pin_missing_trace_warning"),source_pin_missing_trace_warning_id:QM("source_pin_missing_trace_warning"),warning_type:k_.literal("source_pin_missing_trace_warning").default("source_pin_missing_trace_warning"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a source component pin is missing a trace connection"),KN=k_.object({type:k_.literal("source_missing_manufacturer_part_number_warning"),source_missing_manufacturer_part_number_warning_id:QM("source_missing_manufacturer_part_number_warning"),warning_type:k_.literal("source_missing_manufacturer_part_number_warning").default("source_missing_manufacturer_part_number_warning"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a standard connector is missing manufacturer part number"),QN=bN.extend({ftype:k_.literal("simple_voltage_probe")}),tw=bN.extend({ftype:k_.literal("interconnect")}),ew=yN.extend({type:k_.literal("source_i2c_misconfigured_error"),source_i2c_misconfigured_error_id:QM("source_i2c_misconfigured_error"),error_type:k_.literal("source_i2c_misconfigured_error").default("source_i2c_misconfigured_error"),source_port_ids:k_.array(k_.string())}).describe("Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net"),nw=bN.extend({ftype:k_.literal("simple_voltage_source"),voltage:jM,frequency:YM.optional(),peak_to_peak_voltage:jM.optional(),wave_shape:k_.enum(["sinewave","square","triangle","sawtooth"]).optional(),phase:UM.optional(),duty_cycle:k_.number().optional().describe("Duty cycle as a fraction (0 to 1)")}),ow=k_.union([vN,xN,SN,IN,CN,PN,MN,NN,wN,EN,AN,ON,kN,LN,DN,zN,FN,BN,VN,jN,$N,YN,XN,RN,QN,tw,nw,WN,HN,UN,GN,ZN,qN,JN,KN,ew]),iw=k_.object({type:k_.literal("source_port"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(TN),rw=k_.object({type:k_.literal("source_component_internal_connection"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),sw=k_.object({type:k_.literal("source_trace"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),aw=k_.object({type:k_.literal("source_group"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),cw=k_.object({type:k_.literal("source_net"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),lw=k_.object({type:k_.literal("source_board"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe("Defines a board in the source domain"),dw=yN.extend({type:k_.literal("source_ambiguous_port_reference"),source_ambiguous_port_reference_id:QM("source_ambiguous_port_reference"),error_type:k_.literal("source_ambiguous_port_reference").default("source_ambiguous_port_reference"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe("Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous"),hw=k_.object({type:k_.literal("source_pcb_ground_plane"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe("Defines a ground plane in the source domain"),uw=["top","bottom","inner1","inner2","inner3","inner4","inner5","inner6"],pw=k_.enum(uw),mw=pw.or(k_.object({name:pw})).transform(t=>"string"==typeof t?t:t.name),gw=k_.enum(["top","bottom"]),fw=k_.object({type:k_.literal("source_manually_placed_via"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe("Defines a via that is manually placed in the source domain"),yw=k_.object({type:k_.literal("source_no_power_pin_defined_warning"),source_no_power_pin_defined_warning_id:QM("source_no_power_pin_defined_warning"),warning_type:k_.literal("source_no_power_pin_defined_warning").default("source_no_power_pin_defined_warning"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a chip has no source ports with requires_power=true"),_w=k_.object({type:k_.literal("source_no_ground_pin_defined_warning"),source_no_ground_pin_defined_warning_id:QM("source_no_ground_pin_defined_warning"),warning_type:k_.literal("source_no_ground_pin_defined_warning").default("source_no_ground_pin_defined_warning"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a chip has no source ports marked as ground pins"),bw=k_.object({type:k_.literal("source_component_pins_underspecified_warning"),source_component_pins_underspecified_warning_id:QM("source_component_pins_underspecified_warning"),warning_type:k_.literal("source_component_pins_underspecified_warning").default("source_component_pins_underspecified_warning"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Warning emitted when all ports on a source component are underspecified"),xw=yN.extend({type:k_.literal("source_pin_must_be_connected_error"),source_pin_must_be_connected_error_id:QM("source_pin_must_be_connected_error"),error_type:k_.literal("source_pin_must_be_connected_error").default("source_pin_must_be_connected_error"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe("Error emitted when a pin with mustBeConnected attribute is not connected to any trace"),vw=yN.extend({type:k_.literal("unknown_error_finding_part"),unknown_error_finding_part_id:QM("unknown_error_finding_part"),error_type:k_.literal("unknown_error_finding_part").default("unknown_error_finding_part"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when an unexpected error occurs while finding a part"),Sw=k_.object({type:k_.literal("schematic_box"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:XM,height:XM,is_dashed:k_.boolean().default(!1),x:XM,y:XM,subcircuit_id:k_.string().optional()}).describe("Draws a box on the schematic"),Iw=k_.object({type:k_.literal("schematic_path"),schematic_path_id:QM("schematic_path"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),stroke_width:XM.nullable().optional(),stroke_color:k_.string().optional(),points:k_.array(qM),subcircuit_id:k_.string().optional()}),Cw=k_.record(k_.object({left_margin:$M.optional(),right_margin:$M.optional(),top_margin:$M.optional(),bottom_margin:$M.optional()})),Pw=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),Mw=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum(["top-to-bottom","bottom-to-top"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum(["top-to-bottom","bottom-to-top"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum(["left-to-right","right-to-left"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum(["left-to-right","right-to-left"]).optional()}).optional()}),Nw=k_.union([Pw,Mw]),ww=k_.object({type:k_.literal("schematic_component"),size:KM,center:qM,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_symbol_id:k_.string().optional(),pin_spacing:$M.optional(),pin_styles:Cw.optional(),box_width:$M.optional(),symbol_name:k_.string().optional(),port_arrangement:Nw.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),Tw=k_.object({kicad_symbol:fN.optional()}).catchall(k_.unknown()),Rw=k_.object({type:k_.literal("schematic_symbol"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:Tw.optional()}).describe("Defines a named schematic symbol that can be referenced by components."),Ew=k_.object({type:k_.literal("schematic_line"),schematic_line_id:QM("schematic_line"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:XM,y1:XM,x2:XM,y2:XM,stroke_width:XM.nullable().optional(),color:k_.string().default("#000000"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe("Draws a styled line on the schematic"),Aw=k_.object({type:k_.literal("schematic_rect"),schematic_rect_id:QM("schematic_rect"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,width:XM,height:XM,rotation:UM.default(0),stroke_width:XM.nullable().optional(),color:k_.string().default("#000000"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe("Draws a styled rectangle on the schematic"),Ow=k_.object({type:k_.literal("schematic_circle"),schematic_circle_id:QM("schematic_circle"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,radius:XM,stroke_width:XM.nullable().optional(),color:k_.string().default("#000000"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe("Draws a styled circle on the schematic"),kw=k_.object({type:k_.literal("schematic_arc"),schematic_arc_id:QM("schematic_arc"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:qM,radius:XM,start_angle_degrees:UM,end_angle_degrees:UM,direction:k_.enum(["clockwise","counterclockwise"]).default("counterclockwise"),stroke_width:XM.nullable().optional(),color:k_.string().default("#000000"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe("Draws a styled arc on the schematic"),Lw=k_.object({type:k_.literal("schematic_trace"),schematic_trace_id:k_.string(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),Dw=k_.enum(["center","left","right","top","bottom"]),zw=k_.object({type:k_.literal("schematic_text"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:XM,y:XM}),rotation:k_.number().default(0),anchor:k_.union([Dw.describe("legacy"),tN]).default("center"),color:k_.string().default("#000000"),subcircuit_id:k_.string().optional()}),Fw=k_.object({type:k_.literal("schematic_port"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_component_id:k_.string().optional(),center:qM,facing_direction:k_.enum(["up","down","left","right"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum(["top","bottom","left","right"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe("Defines a port on a schematic component"),Bw=k_.object({type:k_.literal("schematic_net_label"),schematic_net_label_id:QM("schematic_net_label"),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:qM,anchor_position:qM.optional(),anchor_side:k_.enum(["top","bottom","left","right"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),jw=yN.extend({type:k_.literal("schematic_error"),schematic_error_id:k_.string(),error_type:k_.literal("schematic_port_not_found").default("schematic_port_not_found"),subcircuit_id:k_.string().optional()}).describe("Defines a schematic error on the schematic"),$w=yN.extend({type:k_.literal("schematic_layout_error"),schematic_layout_error_id:QM("schematic_layout_error"),error_type:k_.literal("schematic_layout_error").default("schematic_layout_error"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe("Error emitted when schematic layout fails for a group"),Yw=k_.object({type:k_.literal("schematic_debug_object"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),Xw=Yw.extend({shape:k_.literal("rect"),center:qM,size:KM}),Vw=Yw.extend({shape:k_.literal("line"),start:qM,end:qM}),Ww=Yw.extend({shape:k_.literal("point"),center:qM}),Hw=k_.discriminatedUnion("shape",[Xw,Vw,Ww]),Gw=k_.object({type:k_.literal("schematic_voltage_probe"),schematic_voltage_probe_id:k_.string(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:qM,schematic_trace_id:k_.string(),voltage:jM.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:tN.optional()}).describe("Defines a voltage probe measurement point on a schematic trace"),Uw=k_.object({type:k_.literal("schematic_manual_edit_conflict_warning"),schematic_manual_edit_conflict_warning_id:QM("schematic_manual_edit_conflict_warning"),warning_type:k_.literal("schematic_manual_edit_conflict_warning").default("schematic_manual_edit_conflict_warning"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe("Warning emitted when a component has both manual placement and explicit schX/schY coordinates"),Zw=k_.object({type:k_.literal("schematic_group"),schematic_group_id:QM("schematic_group"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:$M,height:$M,center:qM,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe("Defines a group of components on the schematic"),qw=k_.object({type:k_.literal("schematic_table"),schematic_table_id:QM("schematic_table"),anchor_position:qM,column_widths:k_.array(XM),row_heights:k_.array(XM),cell_padding:XM.optional(),border_width:XM.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:tN.optional()}).describe("Defines a table on the schematic"),Jw=k_.object({type:k_.literal("schematic_table_cell"),schematic_table_cell_id:QM("schematic_table_cell"),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:qM,width:XM,height:XM,horizontal_align:k_.enum(["left","center","right"]).optional(),vertical_align:k_.enum(["top","middle","bottom"]).optional(),font_size:XM.optional(),subcircuit_id:k_.string().optional()}).describe("Defines a cell within a schematic_table"),Kw=k_.object({type:k_.literal("schematic_sheet"),schematic_sheet_id:QM("schematic_sheet"),name:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Defines a schematic sheet or page that components can be placed on"),Qw=k_.object({x:XM,y:XM,bulge:k_.number().optional()}),tT=k_.object({vertices:k_.array(Qw)}),eT=k_.object({outer_ring:tT,inner_rings:k_.array(tT).default([])}),nT=k_.object({x:XM,y:XM,via:k_.boolean().optional(),via_to_layer:mw.optional()}),oT=(k_.array(nT),k_.object({x:XM,y:XM,via:k_.boolean().optional(),to_layer:mw.optional(),trace_width:XM.optional()})),iT=k_.object({min_trace_width:$M.optional(),min_board_edge_clearance:$M.optional(),min_via_hole_edge_to_via_hole_edge_clearance:$M.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:$M.optional(),min_trace_to_pad_edge_clearance:$M.optional(),min_pad_edge_to_pad_edge_clearance:$M.optional(),min_same_net_trace_edge_to_trace_edge_clearance:$M.optional(),min_different_net_trace_edge_to_trace_edge_clearance:$M.optional(),min_via_hole_diameter:$M.optional(),min_via_pad_diameter:$M.optional()}),rT=k_.object({type:k_.literal("pcb_component"),pcb_component_id:QM("pcb_component"),source_component_id:k_.string(),center:qM,layer:mw,rotation:UM,display_offset_x:k_.string().optional().describe("How to display the x offset for this part, usually corresponding with how the user specified it"),display_offset_y:k_.string().optional().describe("How to display the y offset for this part, usually corresponding with how the user specified it"),width:$M,height:$M,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum(["packed","relative_to_group_anchor","relative_to_another_component","none"]).optional(),anchor_position:qM.optional(),anchor_alignment:tN.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:qM.optional(),insertion_direction:k_.enum(["from_above","from_left","from_right","from_front","from_back"]).optional(),metadata:k_.object({kicad_footprint:dN.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe("Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath")}).describe("Defines a component on the PCB"),sT=k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:QM("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("circle"),hole_diameter:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),aT=(sT.describe("Defines a circular hole on the PCB"),k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:QM("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("rect"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),cT=(aT.describe("Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square."),k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:QM("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum(["circle","square"]),hole_diameter:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),lT=(cT.describe("Defines a circular or square hole on the PCB"),k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:QM("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("oval"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),dT=(lT.describe("Defines an oval hole on the PCB"),k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:QM("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("pill"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),hT=(dT.describe("Defines a pill-shaped hole on the PCB"),k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:QM("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("rotated_pill"),hole_width:k_.number(),hole_height:k_.number(),x:XM,y:XM,ccw_rotation:UM,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),uT=(hT.describe("Defines a rotated pill-shaped hole on the PCB"),cT.or(lT).or(dT).or(hT).or(sT).or(aT)),pT=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("circle"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM("pcb_plated_hole"),soldermask_margin:k_.number().optional()}),mT=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.enum(["oval","pill"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,ccw_rotation:UM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM("pcb_plated_hole"),soldermask_margin:k_.number().optional()}),gT=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("circular_hole_with_rect_pad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal("circle"),pad_shape:k_.literal("rect"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM("pcb_plated_hole"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:UM.optional()}),fT=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("pill_hole_with_rect_pad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal("pill"),pad_shape:k_.literal("rect"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM("pcb_plated_hole"),soldermask_margin:k_.number().optional()}),yT=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("rotated_pill_hole_with_rect_pad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal("rotated_pill"),pad_shape:k_.literal("rect"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:UM,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:UM,hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM("pcb_plated_hole"),soldermask_margin:k_.number().optional()}),_T=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("hole_with_polygon_pad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum(["circle","oval","pill","rotated_pill"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:XM,y:XM})).min(3),hole_offset_x:XM.default(0),hole_offset_y:XM.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:XM,y:XM,layers:k_.array(mw),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:QM("pcb_plated_hole"),soldermask_margin:k_.number().optional(),ccw_rotation:UM.optional()}),bT=k_.union([pT,mT,gT,fT,yT,_T]),xT=k_.object({type:k_.literal("pcb_port"),pcb_port_id:QM("pcb_port"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:XM,y:XM,layers:k_.array(mw),is_board_pinout:k_.boolean().optional()}).describe("Defines a port on the PCB"),vT=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("circle"),pcb_smtpad_id:QM("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,radius:k_.number(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),ST=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("rect"),pcb_smtpad_id:QM("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),IT=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("rotated_rect"),pcb_smtpad_id:QM("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:UM,layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),CT=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("pill"),pcb_smtpad_id:QM("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),PT=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("rotated_pill"),pcb_smtpad_id:QM("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:UM,layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),MT=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("polygon"),pcb_smtpad_id:QM("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(qM),layer:mw,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),NT=k_.discriminatedUnion("shape",[vT,ST,IT,PT,CT,MT]).describe("Defines an SMT pad on the PCB"),wT=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("circle"),pcb_solder_paste_id:QM("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,radius:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),TT=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("rect"),pcb_solder_paste_id:QM("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),RT=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("pill"),pcb_solder_paste_id:QM("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),radius:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),ET=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("rotated_rect"),pcb_solder_paste_id:QM("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),ccw_rotation:XM,layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),AT=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("oval"),pcb_solder_paste_id:QM("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:XM,y:XM,width:k_.number(),height:k_.number(),layer:mw,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),OT=k_.union([wT,TT,RT,ET,AT]).describe("Defines solderpaste on the PCB"),kT=k_.object({type:k_.literal("pcb_text"),pcb_text_id:QM("pcb_text"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:qM,layer:mw,width:$M,height:$M,lines:k_.number(),align:k_.enum(["bottom-left"])}).describe("Defines text on the PCB"),LT=k_.object({route_type:k_.literal("wire"),x:XM,y:XM,width:XM,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:mw}),DT=k_.object({route_type:k_.literal("via"),x:XM,y:XM,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:XM.optional(),outer_diameter:XM.optional(),from_layer:mw,to_layer:mw}),zT=k_.union([LT,DT]),FT=k_.object({type:k_.literal("pcb_trace"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:QM("pcb_trace"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum(["constant","interpolated"]).default("constant").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(zT)}).describe("Defines a trace on the PCB"),BT=k_.object({type:k_.literal("pcb_trace_warning"),pcb_trace_warning_id:QM("pcb_trace_warning"),warning_type:k_.literal("pcb_trace_warning").default("pcb_trace_warning"),message:k_.string(),center:qM.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines a trace warning on the PCB"),jT=yN.extend({type:k_.literal("pcb_trace_error"),pcb_trace_error_id:QM("pcb_trace_error"),error_type:k_.literal("pcb_trace_error").default("pcb_trace_error"),center:qM.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines a trace error on the PCB"),$T=yN.extend({type:k_.literal("pcb_trace_missing_error"),pcb_trace_missing_error_id:QM("pcb_trace_missing_error"),error_type:k_.literal("pcb_trace_missing_error").default("pcb_trace_missing_error"),center:qM.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines an error when a source trace has no corresponding PCB trace"),YT=yN.extend({type:k_.literal("pcb_port_not_matched_error"),pcb_error_id:QM("pcb_error"),error_type:k_.literal("pcb_port_not_matched_error").default("pcb_port_not_matched_error"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines a trace error on the PCB where a port is not matched"),XT=yN.extend({type:k_.literal("pcb_port_not_connected_error"),pcb_port_not_connected_error_id:QM("pcb_port_not_connected_error"),error_type:k_.literal("pcb_port_not_connected_error").default("pcb_port_not_connected_error"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines an error when a pcb port is not connected to any trace"),VT=k_.object({type:k_.literal("pcb_net"),pcb_net_id:QM("pcb_net"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe("Defines a net on the PCB"),WT=k_.object({type:k_.literal("pcb_via"),pcb_via_id:QM("pcb_via"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:XM,y:XM,outer_diameter:XM.default("0.6mm"),hole_diameter:XM.default("0.25mm"),from_layer:mw.optional(),to_layer:mw.optional(),layers:k_.array(mw),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe("Defines a via on the PCB"),HT=k_.object({type:k_.literal("pcb_board"),pcb_board_id:QM("pcb_board"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:$M.optional(),height:$M.optional(),center:qM,display_offset_x:k_.string().optional().describe("How to display the x offset for this board, usually corresponding with how the user specified it"),display_offset_y:k_.string().optional().describe("How to display the y offset for this board, usually corresponding with how the user specified it"),thickness:$M.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(qM).optional(),shape:k_.enum(["rect","polygon"]).optional(),material:k_.enum(["fr4","fr1"]).default("fr4"),anchor_position:qM.optional(),anchor_alignment:tN.optional(),position_mode:k_.enum(["relative_to_panel_anchor","none"]).optional()}).merge(iT).describe("Defines the board outline of the PCB"),GT=k_.object({type:k_.literal("pcb_panel"),pcb_panel_id:QM("pcb_panel"),width:$M,height:$M,center:qM,thickness:$M.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe("Defines a PCB panel that can contain multiple boards"),UT=yN.extend({type:k_.literal("pcb_placement_error"),pcb_placement_error_id:QM("pcb_placement_error"),error_type:k_.literal("pcb_placement_error").default("pcb_placement_error"),subcircuit_id:k_.string().optional()}).describe("Defines a placement error on the PCB"),ZT=yN.extend({type:k_.literal("pcb_panelization_placement_error"),pcb_panelization_placement_error_id:QM("pcb_panelization_placement_error"),error_type:k_.literal("pcb_panelization_placement_error").default("pcb_panelization_placement_error"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Defines a panelization placement error on the PCB"),qT=k_.object({type:k_.literal("pcb_trace_hint"),pcb_trace_hint_id:QM("pcb_trace_hint"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(oT),subcircuit_id:k_.string().optional()}).describe("A hint that can be used during generation of a PCB trace"),JT=k_.object({type:k_.literal("pcb_silkscreen_line"),pcb_silkscreen_line_id:QM("pcb_silkscreen_line"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:XM.default("0.1mm"),x1:XM,y1:XM,x2:XM,y2:XM,layer:gw}).describe("Defines a silkscreen line on the PCB"),KT=k_.object({type:k_.literal("pcb_silkscreen_path"),pcb_silkscreen_path_id:QM("pcb_silkscreen_path"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,route:k_.array(qM),stroke_width:$M}).describe("Defines a silkscreen path on the PCB"),QT=k_.object({type:k_.literal("pcb_silkscreen_text"),pcb_silkscreen_text_id:QM("pcb_silkscreen_text"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:XM.default("0.2mm"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:$M,top:$M,bottom:$M,right:$M}).default({left:"0.2mm",top:"0.2mm",bottom:"0.2mm",right:"0.2mm"}).optional(),ccw_rotation:k_.number().optional(),layer:mw,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:tN.default("center")}).describe("Defines silkscreen text on the PCB"),tR=k_.object({type:k_.literal("pcb_copper_text"),pcb_copper_text_id:QM("pcb_copper_text"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:XM.default("0.2mm"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:$M,top:$M,bottom:$M,right:$M}).default({left:"0.2mm",top:"0.2mm",bottom:"0.2mm",right:"0.2mm"}).optional(),ccw_rotation:k_.number().optional(),layer:mw,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:tN.default("center")}).describe("Defines copper text on the PCB"),eR=k_.object({type:k_.literal("pcb_silkscreen_rect"),pcb_silkscreen_rect_id:QM("pcb_silkscreen_rect"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:mw,stroke_width:$M.default("1mm"),corner_radius:$M.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe("Defines a silkscreen rect on the PCB"),nR=k_.object({type:k_.literal("pcb_silkscreen_circle"),pcb_silkscreen_circle_id:QM("pcb_silkscreen_circle"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:$M,layer:gw,stroke_width:$M.default("1mm"),is_filled:k_.boolean().optional()}).describe("Defines a silkscreen circle on the PCB"),oR=k_.object({type:k_.literal("pcb_silkscreen_oval"),pcb_silkscreen_oval_id:QM("pcb_silkscreen_oval"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius_x:XM,radius_y:XM,layer:gw,ccw_rotation:UM.optional()}).describe("Defines a silkscreen oval on the PCB"),iR=k_.object({type:k_.literal("pcb_silkscreen_pill"),pcb_silkscreen_pill_id:QM("pcb_silkscreen_pill"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:mw,ccw_rotation:k_.number().optional()}).describe("Defines a silkscreen pill on the PCB"),rR=k_.object({type:k_.literal("pcb_fabrication_note_text"),pcb_fabrication_note_text_id:QM("pcb_fabrication_note_text"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:XM.default("1mm"),pcb_component_id:k_.string(),text:k_.string(),layer:gw,anchor_position:qM.default({x:0,y:0}),anchor_alignment:k_.enum(["center","top_left","top_right","bottom_left","bottom_right"]).default("center"),color:k_.string().optional()}).describe("Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators"),sR=k_.object({type:k_.literal("pcb_fabrication_note_path"),pcb_fabrication_note_path_id:QM("pcb_fabrication_note_path"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:mw,route:k_.array(qM),stroke_width:$M,color:k_.string().optional()}).describe("Defines a fabrication path on the PCB for fabricators or assemblers"),aR=k_.object({type:k_.literal("pcb_fabrication_note_rect"),pcb_fabrication_note_rect_id:QM("pcb_fabrication_note_rect"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw,stroke_width:$M.default("0.1mm"),corner_radius:$M.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe("Defines a fabrication note rectangle on the PCB"),cR=k_.object({type:k_.literal("pcb_fabrication_note_dimension"),pcb_fabrication_note_dimension_id:QM("pcb_fabrication_note_dimension"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,from:qM,to:qM,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:$M.optional(),offset_distance:$M.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:$M.default("1mm"),color:k_.string().optional(),arrow_size:$M.default("1mm")}).describe("Defines a measurement annotation within PCB fabrication notes"),lR=k_.object({type:k_.literal("pcb_note_text"),pcb_note_text_id:QM("pcb_note_text"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:XM.default("1mm"),text:k_.string().optional(),anchor_position:qM.default({x:0,y:0}),anchor_alignment:k_.enum(["center","top_left","top_right","bottom_left","bottom_right"]).default("center"),layer:gw.default("top"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe("Defines a documentation note in text on the PCB"),dR=k_.object({type:k_.literal("pcb_note_rect"),pcb_note_rect_id:QM("pcb_note_rect"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw.default("top"),stroke_width:$M.default("0.1mm"),corner_radius:$M.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe("Defines a rectangular documentation note on the PCB"),hR=k_.object({type:k_.literal("pcb_note_path"),pcb_note_path_id:QM("pcb_note_path"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(qM),layer:gw.default("top"),stroke_width:$M.default("0.1mm"),color:k_.string().optional()}).describe("Defines a polyline documentation note on the PCB"),uR=k_.object({type:k_.literal("pcb_note_line"),pcb_note_line_id:QM("pcb_note_line"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:XM,y1:XM,x2:XM,y2:XM,layer:gw.default("top"),stroke_width:XM.default("0.1mm"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe("Defines a straight documentation note line on the PCB"),pR=k_.object({type:k_.literal("pcb_note_dimension"),pcb_note_dimension_id:QM("pcb_note_dimension"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:qM,to:qM,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:$M.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:$M.default("1mm"),layer:gw.default("top"),color:k_.string().optional(),arrow_size:$M.default("1mm")}).describe("Defines a measurement annotation within PCB documentation notes"),mR=yN.extend({type:k_.literal("pcb_footprint_overlap_error"),pcb_error_id:QM("pcb_error"),error_type:k_.literal("pcb_footprint_overlap_error").default("pcb_footprint_overlap_error"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe("Error emitted when a pcb footprint overlaps with another element"),gR=yN.extend({type:k_.literal("pcb_courtyard_overlap_error"),pcb_error_id:QM("pcb_error"),error_type:k_.literal("pcb_courtyard_overlap_error").default("pcb_courtyard_overlap_error"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe("Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another"),fR=k_.object({type:k_.literal("pcb_keepout"),shape:k_.literal("rect"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:XM,height:XM,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal("pcb_keepout"),shape:k_.literal("circle"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:XM,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),yR=k_.object({type:k_.literal("pcb_cutout"),pcb_cutout_id:QM("pcb_cutout"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),_R=yR.extend({shape:k_.literal("rect"),center:qM,width:$M,height:$M,rotation:UM.optional(),corner_radius:$M.optional()}),bR=yR.extend({shape:k_.literal("circle"),center:qM,radius:$M}),xR=yR.extend({shape:k_.literal("polygon"),points:k_.array(qM)}),vR=yR.extend({shape:k_.literal("path"),route:k_.array(qM),slot_width:$M,slot_length:$M.optional(),space_between_slots:$M.optional(),slot_corner_radius:$M.optional()}),SR=k_.discriminatedUnion("shape",[_R,bR,xR,vR]).describe("Defines a cutout on the PCB, removing board material."),IR=yN.extend({type:k_.literal("pcb_missing_footprint_error"),pcb_missing_footprint_error_id:QM("pcb_missing_footprint_error"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal("pcb_missing_footprint_error").default("pcb_missing_footprint_error"),source_component_id:k_.string()}).describe("Defines a missing footprint error on the PCB"),CR=yN.extend({type:k_.literal("external_footprint_load_error"),external_footprint_load_error_id:QM("external_footprint_load_error"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal("external_footprint_load_error").default("external_footprint_load_error")}).describe("Defines an error when an external footprint fails to load"),PR=yN.extend({type:k_.literal("circuit_json_footprint_load_error"),circuit_json_footprint_load_error_id:QM("circuit_json_footprint_load_error"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal("circuit_json_footprint_load_error").default("circuit_json_footprint_load_error"),circuit_json:k_.array(k_.any()).optional()}).describe("Defines an error when a circuit JSON footprint fails to load"),MR=k_.object({type:k_.literal("pcb_group"),pcb_group_id:QM("pcb_group"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:$M.optional(),height:$M.optional(),center:qM,display_offset_x:k_.string().optional().describe("How to display the x offset for this group, usually corresponding with how the user specified it"),display_offset_y:k_.string().optional().describe("How to display the y offset for this group, usually corresponding with how the user specified it"),outline:k_.array(qM).optional(),anchor_position:qM.optional(),anchor_alignment:tN.default("center"),position_mode:k_.enum(["packed","relative_to_group_anchor","none"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum(["packed","none"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:$M}).optional(),autorouter_used_string:k_.string().optional()}).describe("Defines a group of components on the PCB"),NR=yN.extend({type:k_.literal("pcb_autorouting_error"),pcb_error_id:QM("pcb_autorouting_error"),error_type:k_.literal("pcb_autorouting_error").default("pcb_autorouting_error"),subcircuit_id:k_.string().optional()}).describe("The autorouting has failed to route a portion of the board"),wR=k_.object({type:k_.literal("pcb_manual_edit_conflict_warning"),pcb_manual_edit_conflict_warning_id:QM("pcb_manual_edit_conflict_warning"),warning_type:k_.literal("pcb_manual_edit_conflict_warning").default("pcb_manual_edit_conflict_warning"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe("Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates"),TR=k_.enum(["x-","x+","y+","y-"]),RR=k_.object({type:k_.literal("pcb_connector_not_in_accessible_orientation_warning"),pcb_connector_not_in_accessible_orientation_warning_id:QM("pcb_connector_not_in_accessible_orientation_warning"),warning_type:k_.literal("pcb_connector_not_in_accessible_orientation_warning").default("pcb_connector_not_in_accessible_orientation_warning"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:TR,recommended_facing_direction:TR,subcircuit_id:k_.string().optional()}).describe("Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction"),ER=k_.object({type:k_.literal("supplier_footprint_mismatch_warning"),supplier_footprint_mismatch_warning_id:QM("supplier_footprint_mismatch_warning"),warning_type:k_.literal("supplier_footprint_mismatch_warning").default("supplier_footprint_mismatch_warning"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:_N.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe("Warning emitted when a supplier part footprint does not match the expected footprint"),AR=k_.object({type:k_.literal("pcb_breakout_point"),pcb_breakout_point_id:QM("pcb_breakout_point"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:XM,y:XM}).describe("Defines a routing target within a pcb_group for a source_trace or source_net"),OR=k_.object({type:k_.literal("pcb_ground_plane"),pcb_ground_plane_id:QM("pcb_ground_plane"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Defines a ground plane on the PCB"),kR=k_.object({type:k_.literal("pcb_ground_plane_region"),pcb_ground_plane_region_id:QM("pcb_ground_plane_region"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:mw,points:k_.array(qM)}).describe("Defines a polygon region of a ground plane"),LR=k_.object({type:k_.literal("pcb_thermal_spoke"),pcb_thermal_spoke_id:QM("pcb_thermal_spoke"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:XM,spoke_inner_diameter:XM,spoke_outer_diameter:XM,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Pattern for connecting a ground plane to a plated hole"),DR=k_.object({type:k_.literal("pcb_copper_pour"),pcb_copper_pour_id:QM("pcb_copper_pour"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:mw,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),zR=DR.extend({shape:k_.literal("rect"),center:qM,width:$M,height:$M,rotation:UM.optional()}),FR=DR.extend({shape:k_.literal("brep"),brep_shape:eT}),BR=DR.extend({shape:k_.literal("polygon"),points:k_.array(qM)}),jR=k_.discriminatedUnion("shape",[zR,FR,BR]).describe("Defines a copper pour on the PCB."),$R=yN.extend({type:k_.literal("pcb_component_outside_board_error"),pcb_component_outside_board_error_id:QM("pcb_component_outside_board_error"),error_type:k_.literal("pcb_component_outside_board_error").default("pcb_component_outside_board_error"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:qM,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe("Error emitted when a PCB component is placed outside the board boundaries"),YR=yN.extend({type:k_.literal("pcb_component_not_on_board_edge_error"),pcb_component_not_on_board_edge_error_id:QM("pcb_component_not_on_board_edge_error"),error_type:k_.literal("pcb_component_not_on_board_edge_error").default("pcb_component_not_on_board_edge_error"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:qM,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when a component that must be placed on the board edge is centered away from the edge"),XR=yN.extend({type:k_.literal("pcb_component_invalid_layer_error"),pcb_component_invalid_layer_error_id:QM("pcb_component_invalid_layer_error"),error_type:k_.literal("pcb_component_invalid_layer_error").default("pcb_component_invalid_layer_error"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:mw,subcircuit_id:k_.string().optional()}).describe("Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)"),VR=yN.extend({type:k_.literal("pcb_via_clearance_error"),pcb_error_id:QM("pcb_error"),error_type:k_.literal("pcb_via_clearance_error").default("pcb_via_clearance_error"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when vias are closer than the allowed clearance"),WR=yN.extend({type:k_.literal("pcb_via_trace_clearance_error"),pcb_via_trace_clearance_error_id:QM("pcb_via_trace_clearance_error"),error_type:k_.literal("pcb_via_trace_clearance_error").default("pcb_via_trace_clearance_error"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when a via and trace are closer than the allowed clearance"),HR=yN.extend({type:k_.literal("pcb_pad_pad_clearance_error"),pcb_pad_pad_clearance_error_id:QM("pcb_pad_pad_clearance_error"),error_type:k_.literal("pcb_pad_pad_clearance_error").default("pcb_pad_pad_clearance_error"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when pads are closer than the allowed clearance"),GR=yN.extend({type:k_.literal("pcb_pad_trace_clearance_error"),pcb_pad_trace_clearance_error_id:QM("pcb_pad_trace_clearance_error"),error_type:k_.literal("pcb_pad_trace_clearance_error").default("pcb_pad_trace_clearance_error"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:XM.optional(),actual_clearance:XM.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when a pad and trace are closer than allowed clearance"),UR=k_.object({type:k_.literal("pcb_courtyard_rect"),pcb_courtyard_rect_id:QM("pcb_courtyard_rect"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,width:$M,height:$M,layer:gw,ccw_rotation:UM.optional(),color:k_.string().optional()}).describe("Defines a courtyard rectangle on the PCB"),ZR=k_.object({type:k_.literal("pcb_courtyard_outline"),pcb_courtyard_outline_id:QM("pcb_courtyard_outline"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,outline:k_.array(qM).min(2)}).describe("Defines a courtyard outline on the PCB"),qR=k_.object({type:k_.literal("pcb_courtyard_polygon"),pcb_courtyard_polygon_id:QM("pcb_courtyard_polygon"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:gw,points:k_.array(qM).min(3),color:k_.string().optional()}).describe("Defines a courtyard polygon on the PCB"),JR=k_.object({type:k_.literal("pcb_courtyard_circle"),pcb_courtyard_circle_id:QM("pcb_courtyard_circle"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:qM,radius:$M,layer:gw,color:k_.string().optional()}).describe("Defines a courtyard circle on the PCB"),KR=k_.object({type:k_.literal("cad_component"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:JM,rotation:JM.optional(),size:JM.optional(),layer:mw.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:eN.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum(["x+","x-","y+","y-","z+","z-"]).optional().describe('The direction in the model\'s coordinate space that is considered "up" or "coming out of the board surface"'),model_origin_position:JM.optional(),model_origin_alignment:k_.enum(["unknown","center","center_of_component_on_board_surface","bottom_center_of_component"]).optional(),model_object_fit:k_.enum(["contain_within_bounds","fill_bounds"]).optional().default("contain_within_bounds"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),anchor_alignment:k_.enum(["center","center_of_component_on_board_surface"]).optional().default("center")}).describe("Defines a component on the PCB"),QR=k_.enum(["sinewave","square","triangle","sawtooth"]),tE=k_.union([k_.string(),k_.number()]).transform(t=>"string"==typeof t?t.endsWith("%")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,"Duty cycle must be non-negative").max(1,"Duty cycle cannot be greater than 100%")),eE=k_.object({type:k_.literal("simulation_voltage_source"),simulation_voltage_source_id:QM("simulation_voltage_source"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:jM}).describe("Defines a DC voltage source for simulation"),nE=k_.object({type:k_.literal("simulation_voltage_source"),simulation_voltage_source_id:QM("simulation_voltage_source"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:jM.optional(),frequency:YM.optional(),peak_to_peak_voltage:jM.optional(),wave_shape:QR.optional(),phase:UM.optional(),duty_cycle:tE.optional()}).describe("Defines an AC voltage source for simulation"),oE=k_.union([eE,nE]).describe("Defines a voltage source for simulation"),iE=k_.union([k_.string(),k_.number()]).transform(t=>"string"==typeof t?t.endsWith("%")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,"Duty cycle must be non-negative").max(1,"Duty cycle cannot be greater than 100%")),rE=k_.object({type:k_.literal("simulation_current_source"),simulation_current_source_id:QM("simulation_current_source"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:VM}).describe("Defines a DC current source for simulation"),sE=k_.object({type:k_.literal("simulation_current_source"),simulation_current_source_id:QM("simulation_current_source"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:VM.optional(),frequency:YM.optional(),peak_to_peak_current:VM.optional(),wave_shape:QR.optional(),phase:UM.optional(),duty_cycle:iE.optional()}).describe("Defines an AC current source for simulation"),aE=k_.union([rE,sE]).describe("Defines a current source for simulation"),cE=k_.union([k_.literal("spice_dc_sweep"),k_.literal("spice_dc_operating_point"),k_.literal("spice_transient_analysis"),k_.literal("spice_ac_analysis")]),lE=k_.object({type:k_.literal("simulation_experiment"),simulation_experiment_id:QM("simulation_experiment"),name:k_.string(),experiment_type:cE,time_per_step:WM.optional(),start_time_ms:HM.optional(),end_time_ms:HM.optional()}).describe("Defines a simulation experiment configuration"),dE=k_.object({type:k_.literal("simulation_transient_voltage_graph"),simulation_transient_voltage_graph_id:QM("simulation_transient_voltage_graph"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:WM,start_time_ms:HM,end_time_ms:HM,name:k_.string().optional(),color:k_.string().optional()}).describe("Stores voltage measurements over time for a simulation"),hE=k_.object({type:k_.literal("simulation_switch"),simulation_switch_id:QM("simulation_switch"),source_component_id:k_.string().optional(),closes_at:HM.optional(),opens_at:HM.optional(),starts_closed:k_.boolean().optional(),switching_frequency:YM.optional()}).describe("Defines a switch for simulation timing control"),uE=k_.object({type:k_.literal("simulation_voltage_probe"),simulation_voltage_probe_id:QM("simulation_voltage_probe"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe("Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.").superRefine((t,e)=>{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n&&o?e.addIssue({code:k_.ZodIssueCode.custom,message:"Cannot mix port and net connections in a differential probe."}):n?t.signal_input_source_port_id&&t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id."}):o&&(t.signal_input_source_net_id&&t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id."}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id&&e.addIssue({code:k_.ZodIssueCode.custom,message:"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id."})}),pE=yN.extend({type:k_.literal("simulation_unknown_experiment_error"),simulation_unknown_experiment_error_id:QM("simulation_unknown_experiment_error"),error_type:k_.literal("simulation_unknown_experiment_error").default("simulation_unknown_experiment_error"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("An unknown error occurred during the simulation experiment."),mE=k_.object({type:k_.literal("simulation_op_amp"),simulation_op_amp_id:QM("simulation_op_amp"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe("Defines a simple ideal operational amplifier for simulation"),gE=(k_.union([sw,iw,rw,ow,cw,aw,MN,xN,SN,CN,vN,NN,EN,AN,DN,FN,BN,VN,jN,$N,YN,XN,kN,ON,hw,fw,lw,WN,UN,ZN,JN,KN,yw,_w,bw,xw,vw,ew,dw,rT,uT,IR,CR,PR,wR,RR,ER,bT,fR,xT,VT,kT,FT,BT,WT,NT,OT,HT,GT,MR,qT,JT,KT,QT,iR,tR,eR,nR,oR,jT,$T,UT,ZT,YT,XT,VR,WR,HR,GR,sR,rR,aR,cR,lR,dR,hR,uR,pR,NR,mR,gR,AR,SR,OR,kR,LR,jR,$R,YR,XR,UR,ZR,qR,JR,Sw,zw,Ew,Aw,Ow,kw,ww,Rw,Fw,Lw,Iw,jw,$w,Bw,Hw,Gw,Uw,Zw,Kw,qw,Jw,KR,oE,aE,lE,dE,hE,uE,pE,mE]),!0),fE={CCW:-1,CW:1,NOT_ORIENTABLE:0},yE=2*Math.PI,_E=Object.freeze({__proto__:null,BOUNDARY:2,CCW:gE,CONTAINS:3,CW:!1,END_VERTEX:2,INSIDE:1,INTERLACE:4,NOT_VERTEX:0,ORIENTATION:fE,OUTSIDE:0,OVERLAP_OPPOSITE:2,OVERLAP_SAME:1,PIx2:yE,START_VERTEX:1}),bE=1e-6;function xE(t){bE=t}function vE(){return bE}function SE(t){return t<bE&&t>-bE}function IE(t,e){return t-e<bE&&t-e>-bE}function CE(t,e){return t-e>bE}function PE(t,e){return t-e<-bE}var ME={Utils:Object.freeze({__proto__:null,DECIMALS:3,EQ:IE,EQ_0:SE,GE:function(t,e){return t-e>-bE},GT:CE,LE:function(t,e){return t-e<bE},LT:PE,getTolerance:vE,setTolerance:xE}),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 _E)ME[t]=_E[t];Object.defineProperty(ME,"DP_TOL",{get:function(){return vE()},set:function(t){xE(t)}});var NE=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")}};ME.Errors=NE;var wE=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=[],o=t||this.first,i=e||this.last,r=o;if(void 0===r)return n;do{n.push(r),r=r.next}while(r!==i.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 NE.INFINITE_LOOP;e=e.next,n=n.next.next}while(e!=t)}},TE={stroke:"black"},RE=class{constructor(t=TE){for(const e in t)this[e]=t[e];this.stroke=t.stroke??TE.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 EE(t){return new RE(t).toAttributesString()}function AE(t,e){let n=[],[o,i,r]=t.standard,[s,a,c]=e.standard,l=o*a-i*s,d=r*a-i*c,h=o*c-r*s;if(!ME.Utils.EQ_0(l)){let t,e;0===i?(t=r/o,e=h/l):0===a?(t=c/s,e=h/l):0===o?(t=d/l,e=r/i):0===s?(t=d/l,e=c/a):(t=d/l,e=h/l),n.push(new ME.Point(t,e))}return n}function OE(t,e){let n=[],o=e.pc.projectionOn(t),i=e.pc.distanceTo(o)[0];if(ME.Utils.EQ(i,e.r))n.push(o);else if(ME.Utils.LT(i,e.r)){let r,s,a=Math.sqrt(e.r*e.r-i*i);r=t.norm.rotate90CCW().multiply(a),s=o.translate(r),n.push(s),r=t.norm.rotate90CW().multiply(a),s=o.translate(r),n.push(s)}return n}function kE(t,e){let n=[];for(let o of e.toSegments()){let e=DE(o,t);for(let t of e)eA(t,n)||n.push(t)}return n}function LE(t,e){let n=[];if(0===kE(t,e.box).length)return n;let o=OE(t,new ME.Circle(e.pc,e.r));for(let t of o)t.on(e)&&n.push(t);return n}function DE(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:AE(new ME.Line(t.ps,t.pe),e)}function zE(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 o=new ME.Line(t.ps,t.pe),i=new ME.Line(e.ps,e.pe);if(o.incidentTo(i))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 if(o.parallelTo(i)){const o=new ME.Vector(t.ps,t.pe),i=new ME.Vector(e.ps,e.pe),r=new ME.Vector(t.ps,e.ps),s=o.cross(i);if(!ME.Utils.EQ_0(s)){const a=r.cross(i)/s,c=r.cross(o)/s;ME.Utils.GE(a,0)&&ME.Utils.LE(a,1)&&ME.Utils.GE(c,0)&&ME.Utils.LE(c,1)&&n.push(FE(t.ps.translate(o.multiply(a)),t,e))}}else{let r=AE(o,i);r.length>0&&BE(r[0],t)&&BE(r[0],e)&&n.push(FE(r[0],t,e))}return n}function FE(t,e,n){for(const o of[e.ps,e.pe,n.ps,n.pe])if(t.equalTo(o))return o;return t}function BE(t,e){const n=e.box;return ME.Utils.LE(t.x,n.xmax)&&ME.Utils.GE(t.x,n.xmin)&&ME.Utils.LE(t.y,n.ymax)&&ME.Utils.GE(t.y,n.ymin)}function jE(t,e){let n=[];if(t.isZeroLength()){let[o,i]=t.ps.distanceTo(e.pc);return ME.Utils.EQ(o,e.r)&&n.push(t.ps),n}let o=OE(new ME.Line(t.ps,t.pe),e);for(let e of o)e.on(t)&&n.push(e);return n}function $E(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)&&n.push(t.ps),n;let o=OE(new ME.Line(t.ps,t.pe),new ME.Circle(e.pc,e.r));for(let i of o)i.on(t)&&i.on(e)&&n.push(i);return n}function YE(t,e){let n=[],o=new ME.Vector(t.pc,e.pc),i=t.r,r=e.r;if(ME.Utils.EQ_0(i)||ME.Utils.EQ_0(r))return n;if(ME.Utils.EQ_0(o.x)&&ME.Utils.EQ_0(o.y)&&ME.Utils.EQ(i,r))return n.push(t.pc.translate(-i,0)),n;let s,a=t.pc.distanceTo(e.pc)[0];if(ME.Utils.GT(a,i+r))return n;if(ME.Utils.LT(a,Math.abs(i-r)))return n;if(o.x/=a,o.y/=a,ME.Utils.EQ(a,i+r)||ME.Utils.EQ(a,Math.abs(i-r)))return s=t.pc.translate(i*o.x,i*o.y),n.push(s),n;let c=i*i/(2*a)-r*r/(2*a)+a/2,l=t.pc.translate(c*o.x,c*o.y),d=Math.sqrt(i*i-c*c);return s=l.translate(o.rotate90CCW().multiply(d)),n.push(s),s=l.translate(o.rotate90CW().multiply(d)),n.push(s),n}function XE(t,e){let n=[];if(t.pc.equalTo(e.pc)&&ME.Utils.EQ(t.r,e.r)){let o;return o=t.start,o.on(e)&&n.push(o),o=t.end,o.on(e)&&n.push(o),o=e.start,o.on(t)&&n.push(o),o=e.end,o.on(t)&&n.push(o),n}let o=new ME.Circle(t.pc,t.r),i=new ME.Circle(e.pc,e.r),r=o.intersect(i);for(let o of r)o.on(t)&&o.on(e)&&n.push(o);return n}function VE(t,e){let n=[];if(e.pc.equalTo(t.pc)&&ME.Utils.EQ(e.r,t.r))return n.push(t.start),n.push(t.end),n;let o=YE(e,new ME.Circle(t.pc,t.r));for(let e of o)e.on(t)&&n.push(e);return n}function WE(t,e){return t.isSegment?zE(t.shape,e):$E(e,t.shape)}function HE(t,e){return t.isSegment?$E(t.shape,e):XE(t.shape,e)}function GE(t,e){return t.isSegment?DE(t.shape,e):LE(e,t.shape)}function UE(t,e){return t.isSegment?jE(t.shape,e):VE(t.shape,e)}function ZE(t,e){let n=[];for(let o of e.edges)for(let e of WE(o,t))n.push(e);return n}function qE(t,e){let n=[];for(let o of e.edges)for(let e of HE(o,t))n.push(e);return n}function JE(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of GE(o,t))eA(e,n)||n.push(e);return t.sortPoints(n)}function KE(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of UE(o,t))n.push(e);return n}function QE(t,e){return t.isSegment?WE(e,t.shape):t.isArc?HE(e,t.shape):t.isLine?GE(e,t.shape):t.isRay?(n=e,o=t.shape,n.isSegment?oA(o,n.shape):iA(o,n.shape)):[];var n,o}function tA(t,e){let n=[];if(e.isEmpty()||t.shape.box.not_intersect(e.box))return n;let o=e.edges.search(t.shape.box);for(let e of o)n=[...n,...QE(t,e)];return n}function eA(t,e){return e.some(e=>e.equalTo(t))}function nA(t){return new ME.Line(t.start,t.norm)}function oA(t,e){return DE(e,nA(t)).filter(e=>t.contains(e))}function iA(t,e){return LE(nA(t),e).filter(e=>t.contains(e))}function rA(t,e){return OE(nA(t),e).filter(e=>t.contains(e))}function sA(t,e){return AE(nA(t),e).filter(e=>t.contains(e))}function aA(t,e){return JE(nA(t),e).filter(e=>t.contains(e))}function cA(t,e){if(t.intersect&&t.intersect instanceof Function)return t.intersect(e);throw NE.UNSUPPORTED_SHAPE_TYPE}function lA(t,e){let n=[];for(let o of e)n=[...n,...cA(t,o.shape)];return n}var dA=class t extends wE{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,o=t=>t instanceof ME.Segment||t instanceof ME.Arc||t instanceof ME.Ray,i=t=>t instanceof ME.Segment||t instanceof ME.Arc;if(!(1===n&&(t=>t instanceof ME.Segment||t instanceof ME.Arc||t instanceof ME.Ray||t instanceof ME.Line)(e[0])||n>1&&o(e[0])&&o(e[n-1])&&e.slice(1,n-1).every(i)))throw ME.Errors.ILLEGAL_PARAMETERS;this.isInfinite=e.some(t=>t instanceof ME.Ray||t instanceof ME.Line);for(let t of e){let e=new ME.Edge(t);this.append(e)}this.setArcLength()}}get edges(){return[...this]}get box(){return this.edges.reduce((t,e)=>t.merge(e.box),new ME.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 o=new ME.Edge(n[0]),i=e.prev;return this.insert(o,i),e.shape=n[1],o}getChain(t,e){let n=[];for(let o=t;o!==e.next;o=o.next)n.push(o);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 ME.Point){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Line){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Circle){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Segment){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Arc){const[e,n]=ME.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ME.Box){const[e,n]=ME.Distance.shape2multiline(new ME.Polygon(t),this);return[e,n.reverse()]}if(t instanceof ME.Multiline)return ME.Distance.multiline2multiline(this,t);throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}intersect(t){return t instanceof ME.Multiline?function(t,e){let n=[];for(let o of t)for(let t of e)n=[...n,...cA(o.shape,t.shape)];return n}(this,t):lA(t,this)}contains(t){if(t instanceof ME.Point)return this.edges.some(e=>e.shape.contains(t));throw ME.Errors.UNSUPPORTED_SHAPE_TYPE}translate(e){return new t(this.edges.map(t=>t.shape.translate(e)))}rotate(e=0,n=new ME.Point){return new t(this.edges.map(t=>t.shape.rotate(e,n)))}transform(e=new ME.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 ${EE({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}};ME.Multiline=dA;function hA(t,e,n){let o=n.length,i=t.shape.split(e);if(0===i.length)return;let r=0;r=null===i[0]?0:null===i[1]?t.shape.length:i[0].length;let s,a=0;IE(r,0)&&(a|=1),IE(r,t.shape.length)&&(a|=2),s=r===1/0?i[0].coord(e):2&a&&t.next&&0===t.next.arc_length?0:t.arc_length+r,n.push({id:o,pt:e,arc_length:s,edge_before:t,edge_after:void 0,face:t.face,is_vertex:a})}function uA(t){t.int_points1_sorted=pA(t.int_points1),t.int_points2_sorted=pA(t.int_points2)}function pA(t){let e=new Map,n=0;for(let o of t)e.has(o.face)||(e.set(o.face,n),n++);for(let n of t)n.faceId=e.get(n.face);return t.slice().sort(mA)}function mA(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 gA(t){if(t.int_points1.length<2)return;let e,n,o,i,r=!1;for(let s=0;s<t.int_points1_sorted.length;s++)if(-1!==t.int_points1_sorted[s].id){e=t.int_points1_sorted[s],n=t.int_points2[e.id];for(let a=s+1;a<t.int_points1_sorted.length&&(o=t.int_points1_sorted[a],IE(o.arc_length,e.arc_length));a++)-1!==o.id&&(i=t.int_points2[o.id],-1!==i.id&&o.edge_before===e.edge_before&&o.edge_after===e.edge_after&&i.edge_before===n.edge_before&&i.edge_after===n.edge_after&&(o.id=-1,i.id=-1,r=!0))}n=t.int_points2_sorted[0],e=t.int_points1[n.id];for(let o=1;o<t.int_points2_sorted.length;o++){let i=t.int_points2_sorted[o];if(-1===i.id)continue;if(-1===n.id||!IE(i.arc_length,n.arc_length)){n=i,e=t.int_points1[n.id];continue}let s=t.int_points1[i.id];s.edge_before===e.edge_before&&s.edge_after===e.edge_after&&i.edge_before===n.edge_before&&i.edge_after===n.edge_after&&(s.id=-1,i.id=-1,r=!0)}r&&(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 fA(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 yA(t,e){for(let n of t)n.edge_before&&n.edge_before.setInclusion(e),n.edge_after&&n.edge_after.setInclusion(e)}function _A(t,e,n){let o,i,r=1;if(1===t.length)return 1;o=t[e];for(let s=e+1;s<t.length&&o.face===n&&(i=t[s],i.pt.equalTo(o.pt)&&i.edge_before===o.edge_before&&i.edge_after===o.edge_after);s++)r++;return r}function bA(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 o=t.addVertex(n.pt,e);n.edge_before=o}for(let n of e)n.edge_before?n.edge_after=n.edge_before.next:t instanceof dA&&1&n.is_vertex&&(n.edge_after=t.first)}}function xA(t,e,n){const o=t.edge_before,i=e.edge_after,r=n.length;o.next=n[0],n[0].prev=o,n[r-1].next=i,i.prev=n[r-1]}ME.multiline=(...t)=>new ME.Multiline(...t);var{INSIDE:vA,OUTSIDE:SA,BOUNDARY:IA,OVERLAP_SAME:CA,OVERLAP_OPPOSITE:PA}=_E,{NOT_VERTEX:MA,START_VERTEX:NA,END_VERTEX:wA}=_E;function TA(t,e){let n=e.clone().reverse(),[o,i]=LA(t,n,3,!0);return o}function RA(t,e){let[n,o]=LA(t,e,2,!0);return n}function EA(t,e){let[n,o]=LA(t,e,2,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=>t.shape)];let r=[];for(let t of o.faces)r=[...r,...[...t.edges].map(t=>t.shape)];return[i,r]}function AA(t,e){let[n,o]=LA(t,e,3,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=>t.shape)];return i}function OA(t,e){let n=t.clone(),o=e.clone(),i=DA(n,o);return uA(i),bA(n,i.int_points1_sorted),bA(o,i.int_points2_sorted),gA(i),uA(i),[i.int_points1_sorted.map(t=>t.pt),i.int_points2_sorted.map(t=>t.pt)]}function kA(t,e,n,o){let i=zA(t,n.int_points1),r=zA(e,n.int_points2);for(FA(i,e),FA(r,t),fA(n.int_points1),fA(n.int_points2),yA(n.int_points1,e),yA(n.int_points2,t);BA(t,e,n.int_points1,n.int_points1_sorted,n.int_points2,n););!function(t){let e,n,o,i=t.int_points1.length;for(let r=0;r<i;r++){let s=t.int_points1_sorted[r];s.face!==e&&(n=r,e=s.face);let a,c=r,l=_A(t.int_points1_sorted,r,e);a=c+l<i&&t.int_points1_sorted[c+l].face===e?c+l:n;let d=_A(t.int_points1_sorted,a,e);o=null;for(let n=a;n<a+d;n++){let i=t.int_points1_sorted[n];if(i.face===e&&t.int_points2[i.id].face===t.int_points2[s.id].face){o=i;break}}if(null===o)continue;let h=s.edge_after,u=o.edge_before;if(2!==h.bv||2!==u.bv)continue;if(h!==u)continue;let p=t.int_points2[s.id],m=t.int_points2[o.id],g=p.edge_after,f=m.edge_before;2===g.bv&&2===f.bv&&g===f||(p=t.int_points2[o.id],m=t.int_points2[s.id],g=p.edge_after,f=m.edge_before),2===g.bv&&2===f.bv&&g===f&&h.setOverlap(g)}}(n),jA(t,o,n.int_points1_sorted,!0),jA(e,o,n.int_points2_sorted,!1),XA(t,i,o,!0),XA(e,r,o,!1)}function LA(t,e,n,o){let i=t.clone(),r=e.clone(),s=DA(i,r);return uA(s),bA(i,s.int_points1_sorted),bA(r,s.int_points2_sorted),gA(s),uA(s),kA(i,r,s,n),o&&function(t,e,n){!function(t,e,n,o){for(let n of e.faces){for(let e of n)t.edges.add(e);void 0===o.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],o=n.int_points2[t];if(void 0!==e.edge_before&&void 0===e.edge_after&&void 0===o.edge_before&&void 0!==o.edge_after&&(e.edge_before.next=o.edge_after,o.edge_after.prev=e.edge_before,e.edge_after=o.edge_after,o.edge_before=e.edge_before),void 0!==o.edge_before&&void 0===o.edge_after&&void 0===e.edge_before&&void 0!==e.edge_after&&(o.edge_before.next=e.edge_after,e.edge_after.prev=o.edge_before,o.edge_after=e.edge_after,e.edge_before=o.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!==o.edge_before&&void 0===o.edge_after)for(let t of n.int_points2_sorted)t!==o&&void 0===t.edge_before&&void 0!==t.edge_after&&t.pt.equalTo(o.pt)&&(o.edge_before.next=t.edge_after,t.edge_after.prev=o.edge_before,o.edge_after=t.edge_after,t.edge_before=o.edge_before)}}(0,0,n),$A(t,n.int_points1),$A(e,n.int_points2),YA(t,n.int_points1,n.int_points2),YA(t,n.int_points2,n.int_points1),VA(t),VA(e)}(i,r,s),[i,r]}function DA(t,e){let n={int_points1:[],int_points2:[]};for(let o of t.edges){let t=e.edges.search(o.box);for(let e of t){let t=o.shape.intersect(e.shape);for(let i of t)hA(o,i,n.int_points1),hA(e,i,n.int_points2)}}return n}function zA(t,e){let n=[];for(let o of t.faces)e.find(t=>t.face===o)||n.push(o);return n}function FA(t,e){for(let n of t)n.first.bv=n.first.bvStart=n.first.bvEnd=void 0,n.first.setInclusion(e)}function BA(t,e,n,o,i,r){let s,a,c,l=o.length,d=!1;for(let h=0;h<l;h++){let u=o[h];u.face!==s&&(a=h,s=u.face);let p,m=h,g=_A(o,h,s);p=m+g<l&&o[m+g].face===s?m+g:a;let f=_A(o,p,s);c=null;for(let t=p;t<p+f;t++){let e=o[t];if(e.face===s&&i[e.id].face===i[u.id].face){c=e;break}}if(null===c)continue;let y=u.edge_after,_=c.edge_before;if(y.bv!==IA||_.bv==IA)if(y.bv==IA||_.bv!==IA){if(y.bv===IA&&_.bv===IA&&y!=_||y.bv===vA&&_.bv===SA||y.bv===SA&&_.bv===vA){let t=y.next;for(;t!=_;)t.bvStart=void 0,t.bvEnd=void 0,t.bv=void 0,t.setInclusion(e),t=t.next}if(y.bv===IA&&_.bv===IA&&y!=_){let t,e=y.next;for(;e!=_;){if(e.bv!=IA)if(void 0===t)t=e.bv;else if(e.bv!=t)throw NE.UNRESOLVED_BOUNDARY_CONFLICT;e=e.next}null!=t&&(y.bv=t,_.bv=t);continue}if(y.bv===vA&&_.bv===SA||y.bv===SA&&_.bv===vA){let o=y;for(;o!=_;){if(o.bvStart===y.bv&&o.bvEnd===_.bv){let[s,a]=o.shape.distanceTo(e);if(s<10*ME.DP_TOL){hA(o,a.ps,n);let s=n[n.length-1];if(s.is_vertex&NA)s.edge_after=o,s.edge_before=o.prev,o.bvStart=IA,o.bv=void 0,o.setInclusion(e);else if(s.is_vertex&wA)s.edge_after=o.next,o.bvEnd=IA,o.bv=void 0,o.setInclusion(e);else{let t=e.addVertex(s.pt,o);s.edge_before=t,s.edge_after=t.next,t.setInclusion(e),t.next.bvStart=IA,t.next.bvEnd=void 0,t.next.bv=void 0,t.next.setInclusion(e)}let c=e.findEdgeByPoint(a.pe);hA(c,a.pe,i);let l=i[i.length-1];if(l.is_vertex&NA)l.edge_after=c,l.edge_before=c.prev;else if(l.is_vertex&wA)l.edge_after=c.next;else{let n=i.find(t=>t.edge_after===c),o=e.addVertex(l.pt,c);l.edge_before=o,l.edge_after=o.next,n&&(n.edge_after=o),o.bvStart=void 0,o.bvEnd=IA,o.bv=void 0,o.setInclusion(t),o.next.bvStart=IA,o.next.bvEnd=void 0,o.next.bv=void 0,o.next.setInclusion(t)}uA(r),d=!0;break}}o=o.next}if(d)break;throw NE.UNRESOLVED_BOUNDARY_CONFLICT}}else _.bv=y.bv;else y.bv=_.bv}return d}function jA(t,e,n,o){if(!n)return;let i,r,s,a;for(let c=0;c<n.length;c++){if(s=n[c],s.face!==i&&(r=c,i=s.face),i.isEmpty())continue;let l,d=c,h=_A(n,c,i);l=d+h<n.length&&n[d+h].face===s.face?d+h:r,a=n[l];let u=l,p=_A(n,u,i),m=s.edge_after,g=a.edge_before;if(m.bv===vA&&g.bv===vA&&1===e||m.bv===SA&&g.bv===SA&&2===e||(m.bv===SA||g.bv===SA)&&3===e&&!o||(m.bv===vA||g.bv===vA)&&3===e&&o||m.bv===IA&&g.bv===IA&&m.overlap&CA&&o||m.bv===IA&&g.bv===IA&&m.overlap&PA){t.removeChain(i,m,g);for(let t=d;t<d+h;t++)n[t].edge_after=void 0;for(let t=u;t<u+p;t++)n[t].edge_before=void 0}c+=h-1}}function $A(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 YA(t,e,n){for(let o of e){if(void 0===o.edge_before||void 0===o.edge_after)continue;if(o.face)continue;if(o.edge_after.face||o.edge_before.face)continue;let i=o.edge_after,r=o.edge_before;try{wE.testInfiniteLoop(i)}catch(t){throw NE.CANNOT_COMPLETE_BOOLEAN_OPERATION}let s=t.addFace(i,r);for(let t of e)t.edge_before&&t.edge_after&&t.edge_before.face===s&&t.edge_after.face===s&&(t.face=s);for(let t of n)t.edge_before&&t.edge_after&&t.edge_before.face===s&&t.edge_after.face===s&&(t.face=s)}}function XA(t,e,n,o){for(let i of e){let e=i.first.bv;(1===n&&e===vA||3===n&&e===vA&&o||3===n&&e===SA&&!o||2===n&&e===SA)&&t.deleteFace(i)}}function VA(t){const e=[];for(const n of t.edges)n.face&&t.faces.has(n.face)||e.push(n);for(const n of e)t.edges.delete(n)}var WA=Object.freeze({__proto__:null,BOOLEAN_INTERSECT:2,BOOLEAN_SUBTRACT:3,BOOLEAN_UNION:1,calculateIntersections:OA,innerClip:EA,intersect:RA,outerClip:AA,removeNotRelevantChains:jA,removeOldFaces:$A,restoreFaces:YA,subtract:TA,unify:function(t,e){let[n,o]=LA(t,e,1,!0);return n}}),HA=RegExp("T.F..FFF.|T.F...F.."),GA=RegExp("T........|.T.......|...T.....|....T...."),UA=RegExp("FT.......|F..T.....|F...T...."),ZA=RegExp("T.F..F..."),qA=RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF..."),JA=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 HA.test(this.toString())}intersect(){return GA.test(this.toString())}touch(){return UA.test(this.toString())}inside(){return ZA.test(this.toString())}covered(){return qA.test(this.toString())}};function KA(t,e){let n,o=new ME.Ray(e),i=new ME.Line(o.pt,o.norm);const r=new ME.Box(o.box.xmin-ME.DP_TOL,o.box.ymin-ME.DP_TOL,o.box.xmax+ME.DP_TOL,o.box.ymax+ME.DP_TOL);if(t.box.not_intersect(r))return ME.OUTSIDE;let s=t.edges.search(r);if(0===s.length)return ME.OUTSIDE;for(let t of s)if(t.shape.contains(e))return ME.BOUNDARY;let a=[...t.faces],c=[];for(let t of s)for(let n of o.intersect(t.shape)){if(n.equalTo(e))return ME.BOUNDARY;c.push({pt:n,edge:t,face_index:a.indexOf(t.face)})}c.sort((t,e)=>PE(t.pt.x,e.pt.x)?-1:CE(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 l=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(;SE(n.length);)n=n.prev;let o=n.shape.tangentInEnd(),r=e.pt.translate(o),s=e.edge.shape.tangentInStart(),a=e.pt.translate(s),d=r.leftTo(i),h=a.leftTo(i);(d&&!h||!d&&h)&&l++}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(;SE(n.length);)n=n.next;let o=n.shape.tangentInStart(),r=e.pt.translate(o),s=e.edge.shape.tangentInEnd(),a=e.pt.translate(s),d=r.leftTo(i),h=a.leftTo(i);(d&&!h||!d&&h)&&l++}else if(e.edge.shape instanceof ME.Segment)l++;else{let t=e.edge.shape.box;IE(e.pt.y,t.ymin)||IE(e.pt.y,t.ymax)||l++}}return n=l%2==1?1:0,n}function QA(t,e){return oO(t,e).intersect()}function tO(t,e){return oO(t,e).inside()}function eO(t,e){return oO(t,e).covered()}function nO(t,e){return eO(e,t)}function oO(t,e){return t instanceof ME.Line&&e instanceof ME.Line?function(t,e){let n=new JA,o=AE(t,e);0===o.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=o,n.I2E=t.split(o),n.E2I=e.split(o));return n}(t,e):t instanceof ME.Line&&e instanceof ME.Circle?function(t,e){let n=new JA,o=OE(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new dA([t]),r=t.sortPoints(o);i.split(r);let s=i.toShapes();n.I2I=[s[1]],n.I2B=r,n.I2E=[s[0],s[2]],n.E2I=new ME.Polygon([e.toArc()]).cutWithLine(t)}return n}(t,e):t instanceof ME.Line&&e instanceof ME.Box?function(t,e){let n=new JA,o=kE(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new dA([t]),r=t.sortPoints(o);i.split(r);let s=i.toShapes();e.toSegments().some(t=>t.contains(o[0])&&t.contains(o[1]))?(n.I2I=[],n.I2B=[s[1]],n.I2E=[s[0],s[2]],n.E2I=[e]):(n.I2I=[s[1]],n.I2B=r,n.I2E=[s[0],s[2]],n.E2I=new ME.Polygon(e.toSegments()).cutWithLine(t))}return n}(t,e):t instanceof ME.Line&&e instanceof ME.Polygon?function(t,e){let n=new JA,o=JE(t,e),i=new dA([t]),r=o.length>0?o.slice():t.sortPoints(o);return i.split(r),[...i].forEach(t=>t.setInclusion(e)),n.I2I=[...i].filter(t=>t.bv===ME.INSIDE).map(t=>t.shape),n.I2B=[...i].slice(1).map(t=>t.bv===ME.BOUNDARY?t.shape:t.shape.start),n.I2E=[...i].filter(t=>t.bv===ME.OUTSIDE).map(t=>t.shape),n.E2I=e.cutWithLine(t),n}(t,e):(t instanceof ME.Segment||t instanceof ME.Arc)&&e instanceof ME.Polygon?iO(t,e):(t instanceof ME.Segment||t instanceof ME.Arc)&&(e instanceof ME.Circle||e instanceof ME.Box)?iO(t,new ME.Polygon(e)):t instanceof ME.Polygon&&e instanceof ME.Polygon?rO(t,e):(t instanceof ME.Circle||t instanceof ME.Box)&&(e instanceof ME.Circle||e instanceof ME.Box)?rO(new ME.Polygon(t),new ME.Polygon(e)):(t instanceof ME.Circle||t instanceof ME.Box)&&e instanceof ME.Polygon?rO(new ME.Polygon(t),e):t instanceof ME.Polygon&&(e instanceof ME.Circle||e instanceof ME.Box)?rO(t,new ME.Polygon(e)):void 0}function iO(t,e){let n=new JA,o=function(t,e){return t instanceof ME.Line?JE(t,e):t instanceof ME.Segment?ZE(t,e):t instanceof ME.Arc?qE(t,e):[]}(t,e),i=o.length>0?o.slice():t.sortPoints(o),r=new dA([t]);r.split(i),[...r].forEach(t=>t.setInclusion(e)),n.I2I=[...r].filter(t=>t.bv===ME.INSIDE).map(t=>t.shape),n.I2B=[...r].slice(1).map(t=>t.bv===ME.BOUNDARY?t.shape:t.shape.start),n.I2E=[...r].filter(t=>t.bv===ME.OUTSIDE).map(t=>t.shape),n.B2I=[],n.B2B=[],n.B2E=[];for(let o of[t.start,t.end])switch(KA(e,o)){case ME.INSIDE:n.B2I.push(o);break;case ME.BOUNDARY:n.B2B.push(o);break;case ME.OUTSIDE:n.B2E.push(o)}return n}function rO(t,e){let n=new JA,[o,i]=OA(t,e),r=RA(t,e),s=TA(t,e),a=TA(e,t),[c,l]=EA(t,e),d=AA(t,e),h=AA(e,t);return n.I2I=r.isEmpty()?[]:[r],n.I2B=l,n.I2E=s.isEmpty()?[]:[s],n.B2I=c,n.B2B=o,n.B2E=d,n.E2I=a.isEmpty()?[]:[a],n.E2B=h,n}var sO=Object.freeze({__proto__:null,contain:function(t,e){return tO(e,t)},cover:nO,covered:eO,disjoint:function(t,e){return!QA(t,e)},equal:function(t,e){return oO(t,e).equal()},inside:tO,intersect:QA,relate:oO,touch:function(t,e){return oO(t,e).touch()}}),aO=class t{constructor(t=1,e=0,n=0,o=1,i=0,r=0){this.a=t,this.b=e,this.c=n,this.d=o,this.tx=i,this.ty=r}fromMatrix3x3(e){const[n,o,i]=e[0],[r,s,a]=e[1];return new t(n,r,o,s,i,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,o;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 NE.ILLEGAL_PARAMETERS;n=e[0],o=e[1]}else n=e[0].x,o=e[0].y;return this.multiply(new t(1,0,0,1,n,o))}rotate(e,n=0,o=0){let i=Math.cos(e),r=Math.sin(e);return this.translate(n,o).multiply(new t(i,r,-r,i,0,0)).translate(-n,-o)}scale(e,n){return this.multiply(new t(e,0,0,n,0,0))}equalTo(t){return!!ME.Utils.EQ(this.tx,t.tx)&&(!!ME.Utils.EQ(this.ty,t.ty)&&(!!ME.Utils.EQ(this.a,t.a)&&(!!ME.Utils.EQ(this.b,t.b)&&(!!ME.Utils.EQ(this.c,t.c)&&!!ME.Utils.EQ(this.d,t.d)))))}};ME.Matrix=aO;ME.matrix=(...t)=>new ME.Matrix(...t);var cO=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,o=this.clone();return o.low=e,o.high=n,o}output(){return[this.low,this.high]}comparable_less_than(t,e){return t<e}},lO=class t extends cO{clone(){return new t(this.low,this.high)}},dO=class{constructor(t,e,n=null,o=null,i=null,r=0){if(this.left=n,this.right=o,this.parent=i,this.color=r,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,o=n;t>o&&([t,o]=[o,t]),this.item.key=new lO(t,o)}}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(),o=t.requireKey();return n.comparable_less_than(e,o.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(),o=t.requireKey();return n.comparable_less_than(o.high,e)}},hO=class t{constructor(){this.root=null,this.nil_node=new dO}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 o of e.item.values)t.push({key:n,value:o})}),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 dO(t));if(n)return n.item.values.push(e),n;const o=new dO(t,e,this.nil_node,this.nil_node,null,1);return this.tree_insert(o),this.recalc_max(o),o}exist(t,e=t){const n=this.tree_search(this.root,new dO(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 dO(t));if(!n)return;if(arguments.length<2)return this.tree_delete(n),n;const o=n.item.values.findIndex(t=>t&&t.equal_to?t.equal_to(e):t===e);return o>=0?(n.item.values.splice(o,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 dO(t),o=[];this.tree_search_interval(this.root,n,o);const i=[];for(const t of o)for(const n of t.item.values)i.push(e(n,t.item.key));return i}intersect_any(t){const e=new dO(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 o of t.item.values)n.insert(t.item.key,e(o,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 dO(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,o=t;for(;o&&o!==this.nil_node;)o.less_than(e)?o.intersect(e)?(n=o,o=o.left):o=o.right:(n&&!o.less_than(n)||(n=o),o=o.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,o;if(t.right!==this.nil_node)e=this.local_minimum(t.right);else{for(n=t,o=t.parent;null!=o&&o.right===n;)n=o,o=o.parent;e=o}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,o=0;if(0===t.color&&e++,n=t.left!==this.nil_node?this.testBlackHeightProperty(t.left):1,o=t.right!==this.nil_node?this.testBlackHeightProperty(t.right):1,n!==o)throw new Error("Red-black height property violated");return e+=n,e}},uO=class extends Set{constructor(t){super(t),this.index=new hO,this.forEach(t=>this.index.insert(t))}add(t){let e=this.size;const{key:n,value:o}=t,i=n||t.box,r=o||t;return super.add(r),this.size>e&&this.index.insert(i,r),this}delete(t){const{key:e,value:n}=t,o=e||t.box,i=n||t;let r=super.delete(i);return r&&this.index.remove(o,i),r}clear(){super.clear(),this.index=new hO}search(t){return this.index.search(t)}hit(t){let e=new ME.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(),"")}};ME.PlanarSet=uO;var pO=class{get name(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform((new aO).translate(...t))}rotate(t,e=new ME.Point){return this.transform((new aO).rotate(t,e.x,e.y))}scale(t,e){return this.transform((new aO).scale(t,e))}transform(...t){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw NE.CANNOT_INVOKE_ABSTRACT_METHOD}};ME.Point=class t extends pO{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 NE.ILLEGAL_PARAMETERS}}get box(){return new ME.Box(this.x,this.y,this.x,this.y)}clone(){return new ME.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return ME.Utils.EQ(this.x,t.x)&&ME.Utils.EQ(this.y,t.y)}lessThan(t){return!!ME.Utils.LT(this.y,t.y)||!(!ME.Utils.EQ(this.y,t.y)||!ME.Utils.LT(this.x,t.x))}transform(t){return new ME.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let e=new ME.Vector(this,t.pt);if(ME.Utils.EQ_0(e.cross(t.norm)))return t.pt.clone();let n=e.dot(t.norm),o=t.norm.multiply(n);return this.translate(o)}leftTo(t){let e=new ME.Vector(t.pt,this);return ME.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 ME.Segment(this,e)]}return e instanceof ME.Line?ME.Distance.point2line(this,e):e instanceof ME.Circle?ME.Distance.point2circle(this,e):e instanceof ME.Segment?ME.Distance.point2segment(this,e):e instanceof ME.Arc?ME.Distance.point2arc(this,e):e instanceof ME.Box?ME.Distance.point2polygon(this,new ME.Polygon(e)):e instanceof ME.Polygon?ME.Distance.point2polygon(this,e):e instanceof ME.PlanarSet?ME.Distance.shape2planarSet(this,e):e instanceof ME.Multiline?ME.Distance.shape2multiline(this,e):void 0}on(t){if(t instanceof ME.Point)return this.equalTo(t);if(t.contains&&t.contains instanceof Function)return t.contains(this);throw ME.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 ${EE({fill:"red",...t})} />`}};var mO=(...t)=>new ME.Point(...t);ME.point=mO;ME.Vector=class extends pO{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 ME.Point&&n instanceof ME.Point)return this.x=n.x-e.x,void(this.y=n.y-e.y)}throw NE.ILLEGAL_PARAMETERS}}clone(){return new ME.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 ME.Utils.EQ_0(this.length)}equalTo(t){return ME.Utils.EQ(this.x,t.x)&&ME.Utils.EQ(this.y,t.y)}multiply(t){return new ME.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 NE.ZERO_DIVISION;return new ME.Vector(this.x/this.length,this.y/this.length)}rotate(t,e=new ME.Point){if(0===e.x&&0===e.y)return this.transform((new aO).rotate(t));throw NE.OPERATION_IS_NOT_SUPPORTED}transform(t){return new ME.Vector(t.transform([this.x,this.y]))}rotate90CCW(){return new ME.Vector(-this.y,this.x)}rotate90CW(){return new ME.Vector(this.y,-this.x)}invert(){return new ME.Vector(-this.x,-this.y)}add(t){return new ME.Vector(this.x+t.x,this.y+t.y)}subtract(t){return new ME.Vector(this.x-t.x,this.y-t.y)}angleTo(t){let e=this.normalize(),n=t.normalize(),o=Math.atan2(e.cross(n),e.dot(n));return o<0&&(o+=2*Math.PI),o}projectionOn(t){let e=t.normalize(),n=this.dot(e);return e.multiply(n)}get name(){return"vector"}};var gO=(...t)=>new ME.Vector(...t);ME.vector=gO;ME.Segment=class t extends pO{constructor(...t){if(super(),this.ps=new ME.Point,this.pe=new ME.Point,0!==t.length){if(1===t.length&&t[0]instanceof Array&&4===t[0].length){let e=t[0];return this.ps=new ME.Point(e[0],e[1]),void(this.pe=new ME.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 ME.Point(e.x,e.y),void(this.pe=new ME.Point(n.x,n.y))}if(!(1===t.length&&t[0]instanceof ME.Point)){if(2===t.length&&t[0]instanceof ME.Point&&t[1]instanceof ME.Point)return this.ps=t[0].clone(),void(this.pe=t[1].clone());if(4===t.length)return this.ps=new ME.Point(t[0],t[1]),void(this.pe=new ME.Point(t[2],t[3]));throw NE.ILLEGAL_PARAMETERS}this.ps=t[0].clone()}}clone(){return new ME.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 ME.Vector(this.start,this.end).slope}get box(){return new ME.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 ME.Utils.EQ_0(this.distanceToPoint(t))}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?DE(this,t):t instanceof ME.Ray?oA(t,this):t instanceof ME.Segment?zE(this,t):t instanceof ME.Circle?jE(this,t):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=zE(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?$E(this,t):t instanceof ME.Polygon?ZE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2segment(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.segment2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.segment2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2segment(this,t);return[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.segment2arc(this,t);return[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline)return ME.Distance.shape2multiline(this,t)}tangentInStart(){return new ME.Vector(this.start,this.end).normalize()}tangentInEnd(){return new ME.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 ME.Segment(this.start,t),new ME.Segment(t,this.end)]}middle(){return new ME.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 ME.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]=ME.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 ME.Matrix){return new t(this.ps.transform(e),this.pe.transform(e))}isZeroLength(){return this.ps.equalTo(this.pe)}sortPoints(t){return new ME.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}" ${EE(t)} />`}};var fO=(...t)=>new ME.Segment(...t);ME.segment=fO;var{vector:yO}=ME;ME.Line=class t extends pO{constructor(...e){if(super(),this.pt=new ME.Point,this.norm=new ME.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 ME.Point(t),void(this.norm=new ME.Vector(n))}if(2===e.length){let n=e[0],o=e[1];if(n instanceof ME.Point&&o instanceof ME.Point)return this.pt=n,this.norm=t.points2norm(n,o),void(this.norm.dot(yO(this.pt.x,this.pt.y))>=0&&this.norm.invert());if(n instanceof ME.Point&&o instanceof ME.Vector){if(ME.Utils.EQ_0(o.x)&&ME.Utils.EQ_0(o.y))throw NE.ILLEGAL_PARAMETERS;return this.pt=n.clone(),this.norm=o.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(yO(this.pt.x,this.pt.y))>=0&&this.norm.invert())}if(n instanceof ME.Vector&&o instanceof ME.Point){if(ME.Utils.EQ_0(n.x)&&ME.Utils.EQ_0(n.y))throw NE.ILLEGAL_PARAMETERS;return this.pt=o.clone(),this.norm=n.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(yO(this.pt.x,this.pt.y))>=0&&this.norm.invert())}}throw NE.ILLEGAL_PARAMETERS}}clone(){return new ME.Line(this.pt,this.norm)}get start(){}get end(){}get length(){return Number.POSITIVE_INFINITY}get box(){return new ME.Box(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)}get middle(){}get slope(){return new ME.Vector(this.norm.y,-this.norm.x).slope}get standard(){return[this.norm.x,this.norm.y,this.norm.dot(yO(this.pt.x,this.pt.y))]}parallelTo(t){return ME.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 ME.Vector(this.pt,t);return ME.Utils.EQ_0(this.norm.dot(e))}coord(t){return yO(t.x,t.y).cross(this.norm)}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?AE(this,t):t instanceof ME.Ray?sA(t,this):t instanceof ME.Circle?OE(this,t):t instanceof ME.Box?kE(this,t):t instanceof ME.Segment?DE(t,this):t instanceof ME.Arc?LE(this,t):t instanceof ME.Polygon?JE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.circle2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2line(t,this);return[e,n.reverse()]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2line(t,this);return[e,n.reverse()]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}}split(t){if(t instanceof ME.Point)return[new ME.Ray(t,this.norm),new ME.Ray(t,this.norm)];{let e=new ME.Multiline([this]),n=this.sortPoints(t);return e.split(n),e.toShapes()}}rotate(t,e=new ME.Point){return new ME.Line(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new ME.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=kE(this,t);if(0===n.length)return"";let o=n[0],i=2===n.length?n[1]:n.find(t=>!t.equalTo(o));return void 0===i&&(i=o),new ME.Segment(o,i).svg(e)}static points2norm(t,e){if(t.equalTo(e))throw NE.ILLEGAL_PARAMETERS;return new ME.Vector(t,e).normalize().rotate90CCW()}};var _O=(...t)=>new ME.Line(...t);ME.line=_O;ME.Circle=class extends pO{constructor(...t){if(super(),this.pc=new ME.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 ME.Point(e),this.r=n}else{let[e,n]=[...t];e&&e instanceof ME.Point&&(this.pc=e.clone()),void 0!==n&&(this.r=n)}}clone(){return new ME.Circle(this.pc.clone(),this.r)}get center(){return this.pc}get box(){return new ME.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 ME.Point?ME.Utils.LE(t.distanceTo(this.center)[0],this.r):t instanceof ME.Segment?ME.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&ME.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof ME.Arc?0===this.intersect(t).length&&ME.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&ME.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof ME.Circle?0===this.intersect(t).length&&ME.Utils.LE(t.r,this.r)&&ME.Utils.LE(t.center.distanceTo(this.center)[0],this.r):void 0}toArc(t=!0){return new ME.Arc(this.center,this.r,Math.PI,-Math.PI,t)}scale(t,e){if(t!==e)throw NE.OPERATION_IS_NOT_SUPPORTED;if(0!==this.pc.x||0!==this.pc.y)throw NE.OPERATION_IS_NOT_SUPPORTED;return new ME.Circle(this.pc,this.r*t)}transform(t=new ME.Matrix){return new ME.Circle(this.pc.transform(t),this.r)}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?OE(t,this):t instanceof ME.Ray?rA(t,this):t instanceof ME.Segment?jE(t,this):t instanceof ME.Circle?YE(t,this):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=jE(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?VE(t,this):t instanceof ME.Polygon?KE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.circle2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.circle2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline){let[e,n]=ME.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 ${EE({fill:"none",...t})} />`}};ME.circle=(...t)=>new ME.Circle(...t);ME.Arc=class extends pO{constructor(...t){if(super(),this.pc=new ME.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:o,endAngle:i,counterClockwise:r}=t[0];this.pc=new ME.Point(e.x,e.y),this.r=n,this.startAngle=o,this.endAngle=i,this.counterClockwise=r}else{let[e,n,o,i,r]=[...t];e&&e instanceof ME.Point&&(this.pc=e.clone()),void 0!==n&&(this.r=n),void 0!==o&&(this.startAngle=o),void 0!==i&&(this.endAngle=i),void 0!==r&&(this.counterClockwise=r)}}clone(){return new ME.Arc(this.pc.clone(),this.r,this.startAngle,this.endAngle,this.counterClockwise)}get sweep(){let t=this.startAngle,e=this.endAngle;if(ME.Utils.EQ(Math.abs(t-e),ME.PIx2))return ME.PIx2;Math.abs(t)>ME.PIx2&&(t-=Math.trunc(t/ME.PIx2)*ME.PIx2),t<0&&(t+=ME.PIx2),Math.abs(e)>ME.PIx2&&(e-=Math.trunc(e/ME.PIx2)*ME.PIx2),e<0&&(e+=ME.PIx2);let n=this.counterClockwise?e-t:t-e;return n<0&&(n+=ME.PIx2),n}get start(){return new ME.Point(this.pc.x+this.r,this.pc.y).rotate(this.startAngle,this.pc)}get end(){return new ME.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 ME.Box);return t=t.merge(this.end.box),t}contains(t){if(!ME.Utils.EQ(this.pc.distanceTo(t)[0],this.r))return!1;if(t.equalTo(this.start))return!0;let e=new ME.Vector(this.pc,t).slope,n=new ME.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise);return ME.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 ME.Vector(this.pc,t).slope;return[new ME.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise),new ME.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 ME.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 ME.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 ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?LE(t,this):t instanceof ME.Ray?iA(t,this):t instanceof ME.Circle?VE(this,t):t instanceof ME.Segment?$E(t,this):t instanceof ME.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=$E(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ME.Arc?XE(this,t):t instanceof ME.Polygon?qE(this,t):t instanceof ME.Multiline?lA(this,t):void 0}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle){let[e,n]=ME.Distance.arc2circle(this,t);return[e,n]}if(t instanceof ME.Line){let[e,n]=ME.Distance.arc2line(this,t);return[e,n]}if(t instanceof ME.Segment){let[e,n]=ME.Distance.segment2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Arc){let[e,n]=ME.Distance.arc2arc(this,t);return[e,n]}if(t instanceof ME.Box){let[e,n]=ME.Distance.shape2polygon(this,new ME.Polygon(t));return[e,n]}if(t instanceof ME.Polygon){let[e,n]=ME.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ME.PlanarSet){let[e,n]=ME.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ME.Multiline)return ME.Distance.shape2multiline(this,t)}breakToFunctional(){let t=[],e=[0,Math.PI/2,Math.PI,3*Math.PI/2],n=this.startAngle,o=this.endAngle;ME.Utils.EQ(Math.abs(n-o),ME.PIx2)&&(o=n),Math.abs(n)>ME.PIx2&&(n-=Math.trunc(n/ME.PIx2)*ME.PIx2),n<0&&(n+=ME.PIx2),Math.abs(o)>ME.PIx2&&(o-=Math.trunc(o/ME.PIx2)*ME.PIx2),o<0&&(o+=ME.PIx2);let i,r,s,a=n;this.counterClockwise?(r=Math.ceil(n/(Math.PI/2))%4,s=1):(r=Math.floor(n/(Math.PI/2))%4,s=-1);for(let o=0,c=r;o<4;o++,c=(c+s+4)%4){if(i=e[c],i===a)continue;let o=this.counterClockwise?i-n:n-i;if(o<0&&(o+=ME.PIx2),o>this.sweep)break;t.push(new ME.Arc(this.pc,this.r,a,i,this.counterClockwise)),a=i}return 0===t.length?(t.push(this),t):(i=o,a!==i&&t.push(new ME.Arc(this.pc,this.r,a,i,this.counterClockwise)),t)}tangentInStart(){let t=new ME.Vector(this.pc,this.start),e=this.counterClockwise?Math.PI/2:-Math.PI/2;return t.rotate(e).normalize()}tangentInEnd(){let t=new ME.Vector(this.pc,this.end),e=this.counterClockwise?-Math.PI/2:Math.PI/2;return t.rotate(e).normalize()}reverse(){return new ME.Arc(this.pc,this.r,this.endAngle,this.startAngle,!this.counterClockwise)}transform(t=new ME.Matrix){let e=this.start.transform(t),n=this.end.transform(t),o=this.pc.transform(t),i=this.counterClockwise;return t.a*t.d<0&&(i=!i),ME.Arc.arcSE(o,e,n,i)}static arcSE(t,e,n,o){let{vector:i}=ME,r=i(t,e).slope,s=i(t,n).slope;ME.Utils.EQ(r,s)&&(s+=2*Math.PI,o=!0);let a=i(t,e).length;return new ME.Arc(t,a,r,s,o)}definiteIntegral(t=0){return this.breakToFunctional().reduce((e,n)=>e+n.circularSegmentDefiniteIntegral(t),0)}circularSegmentDefiniteIntegral(t){let e=new ME.Segment(this.start,this.end).definiteIntegral(t),n=ME.Utils.EQ(this.sweep,ME.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}=ME;return t.slice().sort((t,n)=>{let o=e(this.pc,t).slope,i=e(this.pc,n).slope;return o<i?-1:o>i?1:0})}get name(){return"arc"}svg(t={}){let e=this.sweep<=Math.PI?"0":"1",n=this.counterClockwise?"1":"0";if(ME.Utils.EQ(this.sweep,2*Math.PI)){return new ME.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 ${EE({fill:"none",...t})} />`}};ME.arc=(...t)=>new ME.Arc(...t);ME.Box=class t extends pO{constructor(t=void 0,e=void 0,n=void 0,o=void 0){super(),this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}clone(){return new t(this.xmin,this.ymin,this.xmax,this.ymax)}get low(){return new ME.Point(this.xmin,this.ymin)}get high(){return new ME.Point(this.xmax,this.ymax)}get max(){return this.clone()}get center(){return new ME.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,o){this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}extend(e){return e<=0?this.clone():new t(this.xmin-e,this.ymin-e,this.xmax+e,this.ymax+e)}toPoints(){return[new ME.Point(this.xmin,this.ymin),new ME.Point(this.xmax,this.ymin),new ME.Point(this.xmax,this.ymax),new ME.Point(this.xmin,this.ymax)]}toSegments(){let t=this.toPoints();return[new ME.Segment(t[0],t[1]),new ME.Segment(t[1],t[2]),new ME.Segment(t[2],t[3]),new ME.Segment(t[3],t[0])]}rotate(t,e=new ME.Point){throw NE.OPERATION_IS_NOT_SUPPORTED}transform(e=new ME.Matrix){return this.toPoints().map(t=>t.transform(e)).reduce((t,e)=>t.merge(e.box),new t)}contains(t){return t instanceof ME.Point?t.x>=this.xmin&&t.x<=this.xmax&&t.y>=this.ymin&&t.y<=this.ymax:t instanceof ME.Segment?t.vertices.every(t=>this.contains(t)):t instanceof ME.Box?t.toSegments().every(t=>this.contains(t)):t instanceof ME.Circle?this.contains(t.box):t instanceof ME.Arc?t.vertices.every(t=>this.contains(t))&&this.toSegments().every(e=>0===$E(e,t).length):!(t instanceof ME.Line||t instanceof ME.Ray)&&(t instanceof ME.Multiline?t.toShapes().every(t=>this.contains(t)):t instanceof ME.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 ${EE({fill:"none",...t})} />`}};ME.box=(...t)=>new ME.Box(...t);ME.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 ME.Segment}get isArc(){return this.shape instanceof ME.Arc}get isLine(){return this.shape instanceof ME.Line}get isRay(){return this.shape instanceof ME.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 ME.Line||this.shape instanceof ME.Ray)return this.bv=ME.OUTSIDE,this.bv;if(void 0===this.bvStart&&(this.bvStart=KA(t,this.start)),void 0===this.bvEnd&&(this.bvEnd=KA(t,this.end)),this.bvStart===ME.OUTSIDE||this.bvEnd==ME.OUTSIDE)this.bv=ME.OUTSIDE;else if(this.bvStart===ME.INSIDE||this.bvEnd==ME.INSIDE)this.bv=ME.INSIDE;else{let e=KA(t,this.middle());this.bv=e}return this.bv}setOverlap(t){let e,n=this.shape,o=t.shape;n instanceof ME.Segment&&o instanceof ME.Segment?n.start.equalTo(o.start)&&n.end.equalTo(o.end)?e=ME.OVERLAP_SAME:n.start.equalTo(o.end)&&n.end.equalTo(o.start)&&(e=ME.OVERLAP_OPPOSITE):(n instanceof ME.Arc&&o instanceof ME.Arc||n instanceof ME.Segment&&o instanceof ME.Arc||n instanceof ME.Arc&&o instanceof ME.Segment)&&(n.start.equalTo(o.start)&&n.end.equalTo(o.end)&&n.middle().equalTo(o.middle())?e=ME.OVERLAP_SAME:n.start.equalTo(o.end)&&n.end.equalTo(o.start)&&n.middle().equalTo(o.middle())&&(e=ME.OVERLAP_OPPOSITE)),void 0===this.overlap&&(this.overlap=e),void 0===t.overlap&&(t.overlap=e)}svg(){if(this.shape instanceof ME.Segment)return` L${this.shape.end.x},${this.shape.end.y}`;if(this.shape instanceof ME.Arc){let t,e=this.shape,n=e.counterClockwise?"1":"0";if(ME.Utils.EQ(e.sweep,2*Math.PI)){let o=e.counterClockwise?1:-1,i=new ME.Arc(e.pc,e.r,e.startAngle,e.startAngle+o*Math.PI,e.counterClockwise),r=new ME.Arc(e.pc,e.r,e.startAngle+o*Math.PI,e.endAngle,e.counterClockwise);return t="0",` A${i.r},${i.r} 0 ${t},${n} ${i.end.x},${i.end.y}\n A${r.r},${r.r} 0 ${t},${n} ${r.end.x},${r.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 bO=class extends wE{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}};ME.Face=class t extends bO{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 o=n[0];if(0===o.length)return;if(o.every(t=>t instanceof ME.Point)){let n=t.points2segments(o);this.shapes2face(e.edges,n)}else if(o.every(t=>t instanceof Array&&2===t.length)){let n=o.map(t=>new ME.Point(t[0],t[1])),i=t.points2segments(n);this.shapes2face(e.edges,i)}else if(o.every(t=>t instanceof ME.Segment||t instanceof ME.Arc))this.shapes2face(e.edges,o);else if(o.every(t=>"segment"===t.name||"arc"===t.name)){let t=[];for(let e of o){let n;n="segment"===e.name?new ME.Segment(e):new ME.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 ME.Circle)this.shapes2face(e.edges,[n[0].toArc(gE)]);else if(n[0]instanceof ME.Box){let t=n[0];this.shapes2face(e.edges,[new ME.Segment(new ME.Point(t.xmin,t.ymin),new ME.Point(t.xmax,t.ymin)),new ME.Segment(new ME.Point(t.xmax,t.ymin),new ME.Point(t.xmax,t.ymax)),new ME.Segment(new ME.Point(t.xmax,t.ymax),new ME.Point(t.xmin,t.ymax)),new ME.Segment(new ME.Point(t.xmin,t.ymax),new ME.Point(t.xmin,t.ymin))])}2===n.length&&n[0]instanceof ME.Edge&&n[1]instanceof ME.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 ME.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 ME.Segment(t[n],t[(n+1)%t.length]));return e}shapes2face(t,e){for(let n of e){let e=new ME.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();ME.Utils.EQ_0(t)?this._orientation=fE.NOT_ORIENTABLE:ME.Utils.LT(t,0)?this._orientation=fE.CCW:this._orientation=fE.CW}return this._orientation}isSimple(e){return 0===t.getSelfIntersections(this,e,!0).length}static getSelfIntersections(t,e,n=!1){let o=[];for(let i of t){let r=e.search(i.box);for(let e of r){if(i===e)continue;if(e.face!==t)continue;if(i.shape instanceof ME.Segment&&e.shape instanceof ME.Segment&&(i.next===e||i.prev===e))continue;let r=i.shape.intersect(e.shape);for(let t of r)if((!t.equalTo(i.start)||!t.equalTo(e.end)||e!==i.prev)&&(!t.equalTo(i.end)||!t.equalTo(e.start)||e!==i.next)&&(o.push(t),n))break;if(o.length>0&&n)break}if(o.length>0&&n)break}return o}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 ME.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}};ME.Ray=class t extends pO{constructor(...t){if(super(),this.pt=new ME.Point,this.norm=new ME.Vector(0,1),0!==t.length&&(t.length>=1&&t[0]instanceof ME.Point&&(this.pt=t[0].clone()),1!==t.length)){if(!(2===t.length&&t[1]instanceof ME.Vector))throw NE.ILLEGAL_PARAMETERS;this.norm=t[1].clone()}}clone(){return new t(this.pt,this.norm)}get slope(){return new ME.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new ME.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 ME.Vector(this.pt,t);return ME.Utils.EQ_0(this.norm.dot(e))&&ME.Utils.GE(e.cross(this.norm),0)}coord(t){return gO(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new ME.Segment(this.pt,t),new ME.Ray(t,this.norm)]:[]}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Segment?oA(this,t):t instanceof ME.Arc?iA(this,t):t instanceof ME.Line?sA(this,t):t instanceof ME.Ray?(n=t,AE(nA(e=this),nA(n)).filter(t=>e.contains(t)).filter(t=>n.contains(t))):t instanceof ME.Circle?rA(this,t):t instanceof ME.Box?(i=t,kE(nA(o=this),i).filter(t=>o.contains(t))):t instanceof ME.Polygon?aA(this,t):t instanceof ME.Multiline?lA(this,t):void 0;var e,n,o,i}rotate(t,e=new ME.Point){return new ME.Ray(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new ME.Ray(this.pt.transform(t),this.norm.clone())}get name(){return"ray"}svg(t,e={}){let n=kE(new ME.Line(this.pt,this.norm),t);return n=n.filter(t=>this.contains(t)),0===n.length||2===n.length?"":new ME.Segment(this.pt,n[0]).svg(e)}};ME.ray=(...t)=>new ME.Ray(...t);var xO=class t{constructor(){this.faces=new ME.PlanarSet,this.edges=new ME.PlanarSet;let t=[...arguments];if(1===t.length&&(t[0]instanceof Array&&t[0].length>0||t[0]instanceof ME.Circle||t[0]instanceof ME.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 ME.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 ME.Face(this,e));else this.faces.add(new ME.Face(this,t));else this.faces.add(new ME.Face(this,e))}}get box(){return[...this.faces].reduce((t,e)=>t.merge(e.box),new ME.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 ME.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 o=e;o!==n.next;o=o.next)if(t.remove(o),this.edges.delete(o),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 o=new ME.Edge(n[0]),i=e.prev;return e.face.insert(o,i),this.edges.delete(e),this.edges.add(o),e.shape=n[1],this.edges.add(e),o}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 o,i,r={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let t of n.edges)for(let n of e.edges){let e=QE(t,n);for(let o of e)hA(t,o,r.int_points1),hA(n,o,r.int_points2)}if(0===r.int_points1.length)return e;r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2),bA(n,r.int_points1_sorted),bA(e,r.int_points2_sorted),gA(r),r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2),fA(r.int_points1),yA(r.int_points1,e);for(let t of r.int_points1_sorted)t.edge_before&&t.edge_after&&t.edge_before.bv===t.edge_after.bv&&(r.int_points2[t.id]=-1,t.id=-1);if(r.int_points1=r.int_points1.filter(t=>t.id>=0),r.int_points2=r.int_points2.filter(t=>t.id>=0),r.int_points1.forEach((t,e)=>{t.id=e}),r.int_points2.forEach((t,e)=>{t.id=e}),0===r.int_points1.length)return e;r.int_points1_sorted=pA(r.int_points1),r.int_points2_sorted=pA(r.int_points2);for(let t=1;t<r.int_points1_sorted.length;t++)if(i=r.int_points1_sorted[t],o=r.int_points1_sorted[t-1],i.edge_before&&1===i.edge_before.bv){let t=o.edge_after,s=i.edge_before,a=n.getChain(t,s);xA(r.int_points2[o.id],r.int_points2[i.id],a),a.forEach(t=>e.edges.add(t)),a=a.reverse().map(t=>new ME.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];xA(r.int_points2[i.id],r.int_points2[o.id],a),a.forEach(t=>e.edges.add(t))}return e.recreateFaces(),e}cutWithLine(t){let e=new dA([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 o of t){let t=[...o.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()?fE.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 ME.Point){let e=KA(this,t);return 1===e||2===e}return nO(this,t)}distanceTo(t){if(t instanceof ME.Point){let[e,n]=ME.Distance.point2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Circle||t instanceof ME.Line||t instanceof ME.Segment||t instanceof ME.Arc){let[e,n]=ME.Distance.shape2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof ME.Box)return this.distanceTo(new ME.Polygon(t));if(t instanceof ME.Polygon){let e,n,o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of this.edges){let r=o[0];[e,n]=ME.Distance.shape2planarSet(i.shape,t.edges,r),ME.Utils.LT(e,r)&&(o=[e,n])}return o}}intersect(t){return t instanceof ME.Point?this.contains(t)?[t]:[]:t instanceof ME.Line?JE(t,this):t instanceof ME.Ray?aA(t,this):t instanceof ME.Circle?KE(t,this):t instanceof ME.Segment?ZE(t,this):t instanceof ME.Arc?qE(t,this):t instanceof ME.Polygon?function(t,e){let n=[];if(t.isEmpty()||e.isEmpty())return n;if(t.box.not_intersect(e.box))return n;for(let o of t.edges)n=[...n,...tA(o,e)];return n}(t,this):t instanceof ME.Multiline?function(t,e){let n=[];if(e.isEmpty()||0===t.size)return n;for(let o of t)n=[...n,...tA(o,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 ME.Point){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=>t.rotate(e,n)));return o}scale(e,n){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=>t.scale(e,n)));return o}transform(e=new ME.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 ${EE({fillRule:"evenodd",fill:"lightcyan",...t})} d="`;for(let t of this.faces)e+=`\n${t.svg()}`;return e+='" >\n</path>',e}};ME.Polygon=xO;ME.polygon=(...t)=>new ME.Polygon(...t);var{Circle:vO,Line:SO,Point:IO,Vector:CO,Utils:PO}=ME;ME.Inversion=class t{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,e){const n=new CO(t.pc,e),o=t.r*t.r,i=n.dot(n);return PO.EQ_0(i)?new IO(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY):t.pc.translate(n.multiply(o/i))}static inverseCircle(t,e){const n=t.pc.distanceTo(e.pc)[0];if(PO.EQ(n,e.r)){let n=t.r*t.r/(2*e.r),o=new CO(t.pc,e.pc);o=o.normalize();let i=t.pc.translate(o.multiply(n));return new SO(i,o)}{let n=new CO(t.pc,e.pc),o=t.r*t.r/(n.dot(n)-e.r*e.r),i=t.pc.translate(n.multiply(o)),r=Math.abs(o)*e.r;return new vO(i,r)}}static inverseLine(t,e){const[n,o]=t.pc.distanceTo(e);if(PO.EQ_0(n))return e.clone();{let e=t.r*t.r/(2*n),i=new CO(t.pc,o.end);return i=i.multiply(e/n),new vO(t.pc.translate(i),e)}}inverse(e){return e instanceof IO?t.inversePoint(this.circle,e):e instanceof vO?t.inverseCircle(this.circle,e):e instanceof SO?t.inverseLine(this.circle,e):void 0}};ME.inversion=t=>new ME.Inversion(t);ME.Distance=class t{static point2point(t,e){return t.distanceTo(e)}static point2line(t,e){let n=t.projectionOn(e);return[new ME.Vector(t,n).length,new ME.Segment(t,n)]}static point2circle(t,e){let[n,o]=t.distanceTo(e.center);if(ME.Utils.EQ_0(n))return[e.r,new ME.Segment(t,e.toArc().start)];{let o=Math.abs(n-e.r),i=new ME.Vector(e.pc,t).normalize().multiply(e.r),r=e.pc.translate(i);return[o,new ME.Segment(t,r)]}}static point2segment(e,n){if(n.start.equalTo(n.end))return t.point2point(e,n.start);let o,i,r=new ME.Vector(n.start,n.end),s=new ME.Vector(n.start,e),a=new ME.Vector(n.end,e),c=r.dot(s),l=-r.dot(a);if(ME.Utils.GE(c,0)&&ME.Utils.GE(l,0)){let t=n.tangentInStart();return o=Math.abs(t.cross(s)),i=n.start.translate(t.multiply(t.dot(s))),[o,new ME.Segment(e,i)]}return c<0?e.distanceTo(n.start):e.distanceTo(n.end)}static point2arc(e,n){let o,i,r=new ME.Circle(n.pc,n.r),s=[];return[o,i]=t.point2circle(e,r),i.end.on(n)&&s.push(t.point2circle(e,r)),s.push(t.point2point(e,n.start)),s.push(t.point2point(e,n.end)),t.sort(s),s[0]}static point2edge(e,n){return n.shape instanceof ME.Segment?t.point2segment(e,n.shape):t.point2arc(e,n.shape)}static segment2line(e,n){let o=e.intersect(n);if(o.length>0)return[0,new ME.Segment(o[0],o[0])];let i=[];return i.push(t.point2line(e.start,n)),i.push(t.point2line(e.end,n)),t.sort(i),i[0]}static segment2segment(e,n){let o=zE(e,n);if(o.length>0)return[0,new ME.Segment(o[0],o[0])];let i,r,s=[];return[i,r]=t.point2segment(n.start,e),s.push([i,r.reverse()]),[i,r]=t.point2segment(n.end,e),s.push([i,r.reverse()]),s.push(t.point2segment(e.start,n)),s.push(t.point2segment(e.end,n)),t.sort(s),s[0]}static segment2circle(e,n){let o=e.intersect(n);if(o.length>0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Line(e.ps,e.pe),[r,s]=t.point2line(n.center,i);if(ME.Utils.GE(r,n.r)&&s.end.on(e))return t.point2circle(s.end,n);{let[o,i]=t.point2circle(e.start,n),[r,s]=t.point2circle(e.end,n);return ME.Utils.LT(o,r)?[o,i]:[r,s]}}static segment2arc(e,n){let o=e.intersect(n);if(o.length>0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Line(e.ps,e.pe),r=new ME.Circle(n.pc,n.r),[s,a]=t.point2line(r.center,i);if(ME.Utils.GE(s,r.r)&&a.end.on(e)){let[e,o]=t.point2circle(a.end,r);if(o.end.on(n))return[e,o]}let c,l,d=[];return d.push(t.point2arc(e.start,n)),d.push(t.point2arc(e.end,n)),[c,l]=t.point2segment(n.start,e),d.push([c,l.reverse()]),[c,l]=t.point2segment(n.end,e),d.push([c,l.reverse()]),t.sort(d),d[0]}static circle2circle(e,n){let o=e.intersect(n);if(o.length>0)return[0,new ME.Segment(o[0],o[0])];if(e.center.equalTo(n.center)){let o=e.toArc(),i=n.toArc();return t.point2point(o.start,i.start)}{let o=new ME.Line(e.center,n.center),i=o.intersect(e),r=o.intersect(n),s=[];return s.push(t.point2point(i[0],r[0])),s.push(t.point2point(i[0],r[1])),s.push(t.point2point(i[1],r[0])),s.push(t.point2point(i[1],r[1])),t.sort(s),s[0]}}static circle2line(e,n){let o=e.intersect(n);if(o.length>0)return[0,new ME.Segment(o[0],o[0])];let[i,r]=t.point2line(e.center,n),[s,a]=t.point2circle(r.end,e);return a=a.reverse(),[s,a]}static arc2line(e,n){let o=n.intersect(e);if(o.length>0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),[r,s]=t.point2line(i.center,n);if(!ME.Utils.GE(r,i.r)){let o=[];return o.push(t.point2line(e.start,n)),o.push(t.point2line(e.end,n)),t.sort(o),o[0]}{let[n,o]=t.point2circle(s.end,i);if(o.end.on(e))return[n,o]}}static arc2circle(e,n){let o=e.intersect(n);if(o.length>0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),[r,s]=t.circle2circle(i,n);if(s.start.on(e))return[r,s];{let o=[];return o.push(t.point2circle(e.start,n)),o.push(t.point2circle(e.end,n)),t.sort(o),o[0]}}static arc2arc(e,n){let o=e.intersect(n);if(o.length>0)return[0,new ME.Segment(o[0],o[0])];let i=new ME.Circle(e.center,e.r),r=new ME.Circle(n.center,n.r),[s,a]=t.circle2circle(i,r);if(a.start.on(e)&&a.end.on(n))return[s,a];{let o,i,r=[];return[o,i]=t.point2arc(e.start,n),i.end.on(n)&&r.push([o,i]),[o,i]=t.point2arc(e.end,n),i.end.on(n)&&r.push([o,i]),[o,i]=t.point2arc(n.start,e),i.end.on(e)&&r.push([o,i.reverse()]),[o,i]=t.point2arc(n.end,e),i.end.on(e)&&r.push([o,i.reverse()]),[o,i]=t.point2point(e.start,n.start),r.push([o,i]),[o,i]=t.point2point(e.start,n.end),r.push([o,i]),[o,i]=t.point2point(e.end,n.start),r.push([o,i]),[o,i]=t.point2point(e.end,n.end),r.push([o,i]),t.sort(r),r[0]}}static point2polygon(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of n.edges){let[n,r]=t.point2edge(e,i);ME.Utils.LT(n,o[0])&&(o=[n,r])}return o}static shape2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new ME.Segment];for(let o of e.edges){let[e,i]=t.distanceTo(o.shape);ME.Utils.LT(e,n[0])&&(n=[e,i])}return n}static polygon2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new ME.Segment];for(let o of t.edges)for(let t of e.edges){let[e,i]=o.shape.distanceTo(t.shape);ME.Utils.LT(e,n[0])&&(n=[e,i])}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)),o=Math.max(Math.max(t.ymin-e.ymax,0),Math.max(e.ymin-t.ymax,0)),i=n*n+o*o,r=t.merge(e),s=r.xmax-r.xmin,a=r.ymax-r.ymin;return[i,s*s+a*a]}static minmax_tree_process_level(e,n,o,i){let r,s;for(let a of n){[r,s]=t.box2box_minmax(e.box,a.item.key);for(let t of a.item.values)t instanceof ME.Edge?i.insert([r,s],t.shape):i.insert([r,s],t);ME.Utils.LT(s,o)&&(o=s)}if(0===n.length)return o;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[i,r]=t.box2box_minmax(e.box,n.max);return ME.Utils.LE(i,o)});return o=t.minmax_tree_process_level(e,a,o,i)}static minmax_tree(e,n,o){let i=new hO,r=[n.index.root],s=o<Number.POSITIVE_INFINITY?o*o:Number.POSITIVE_INFINITY;return s=t.minmax_tree_process_level(e,r,s,i),i}static minmax_tree_calc_distance(e,n,o){let i,r;if(null!=n&&!n.isNil()){if([i,r]=t.minmax_tree_calc_distance(e,n.left,o),r)return[i,r];if(ME.Utils.LT(i[0],Math.sqrt(n.item.key.low)))return[i,!0];let[s,a]=t.distanceToArray(e,n.item.values);return ME.Utils.LT(s,i[0])&&(i=[s,a]),[i,r]=t.minmax_tree_calc_distance(e,n.right,i),[i,r]}return[o,!1]}static shape2planarSet(e,n,o=Number.POSITIVE_INFINITY){let i=[o,new ME.Segment],r=!1;if(n instanceof ME.PlanarSet){let s=t.minmax_tree(e,n,o);[i,r]=t.minmax_tree_calc_distance(e,s.root,i)}return i}static sort(t){t.sort((t,e)=>ME.Utils.LT(t[0],e[0])?-1:ME.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 ME.Segment];for(let o of e){let[e,i]=t.distanceTo(o);ME.Utils.LT(e,n[0])&&(n=[e,i])}return n}static shape2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of n){let[n,r]=t.distance(e,i.shape);ME.Utils.LT(n,o[0])&&(o=[n,r])}return o}static multiline2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new ME.Segment];for(let i of e)for(let e of n){let[n,r]=t.distance(i.shape,e.shape);ME.Utils.LT(n,o[0])&&(o=[n,r])}return o}};var{Multiline:MO,Point:NO,Segment:wO,Polygon:TO}=ME;function RO(t){return new NO(t.split(" ").map(Number))}function EO(t){return t.split(", ").map(RO)}function AO(t){const e=EO(t);let n=[];for(let t=0;t<e.length-1;t++)n.push(new wO(e[t],e[t+1]));return new MO(n)}function OO(t){const e=t.replace(/\(\(/,"").replace(/\)\)$/,"").split("), ("),n=new TO;let o;return e.forEach((t,e)=>{let i=t.split(", ").map(t=>new NO(t.split(" ").map(Number)));const r=n.addFace(i);0===e?o=r.orientation():r.orientation()===o&&r.reverse()}),n}function kO(t){if(t.startsWith("POLYGON")){return OO(t.replace(/^POLYGON /,""))}return function(t){const e=t.split(/\)\), \(\(/).map(t=>"(("+t+"))").map(OO),n=new TO;return e.reduce((t,e)=>[...t,...e?.faces],[]).forEach(t=>n.addFace([...t?.shapes])),n}(t.replace(/^MULTIPOLYGON \(\(\((.*)\)\)\)$/,"$1"))}function LO(t){return t.split("\n")?.every(t=>t.includes("POINT"))}function DO(t){return t.split("\n")?.every(t=>t.includes("LINESTRING"))}function zO(t,e,n,o){return Math.sqrt((n-t)**2+(o-e)**2)}ME.isWktString=function(t){return t.startsWith("POINT")||LO(t)||t.startsWith("LINESTRING")||DO(t)||t.startsWith("MULTILINESTRING")||t.startsWith("POLYGON")||t.startsWith("MULTIPOINT")||t.startsWith("MULTIPOLYGON")||t.startsWith("GEOMETRYCOLLECTION")},ME.parseWKT=function t(e){if(e.startsWith("POINT")){return RO(e.replace(/^POINT \(/,"").replace(/\)$/,""))}if(e.startsWith("MULTIPOINT")){return EO(e.replace(/^MULTIPOINT \(/,"").replace(/\)$/,""))}if(e.startsWith("LINESTRING")){return AO(e.replace(/^LINESTRING \(/,"").replace(/\)$/,""))}if(e.startsWith("MULTILINESTRING")){return function(t){return t.replace(/\(\(/,"").replace(/\)\)$/,"").split("), (").map(AO)}(e.replace(/^MULTILINESTRING /,""))}if(e.startsWith("POLYGON")||e.startsWith("MULTIPOLYGON"))return kO(e);if(e.startsWith("GEOMETRYCOLLECTION")){const n=/(?<type>POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \((?:[^\(\)]|\([^\)]*\))*\)/g,o=e.match(n);o[0].startsWith("GEOMETRYCOLLECTION")&&(o[0]=o[0].replace("GEOMETRYCOLLECTION (",""));return o.map(t).map(t=>t instanceof Array?t:[t]).reduce((t,e)=>[...t,...e],[])}return LO(e)?function(t){return t.split("\n").map(t=>t.match(/\(([^)]+)\)/)[1]).map(RO)}(e):DO(e)?function(t){return t.split("\n").map(t=>t.match(/\(([^)]+)\)/)[1]).map(AO).reduce((t,e)=>[...t,...e],[])}(e):[]},ME.BooleanOperations=WA,ME.Relations=sO;var FO=class{buckets;objectsById;getBounds;getId;CELL_SIZE=.4;constructor({objects:t,getBounds:e,getId:n,CELL_SIZE:o}){this.buckets=new Map,this.objectsById=new Map,this.getBounds=e,this.getId=n??(()=>this._getNextId()),this.CELL_SIZE=o??this.CELL_SIZE;for(const e of t)this.addObject(e)}_idCounter=0;_getNextId(){return""+this._idCounter++}addObject(t){const e=this.getBounds(t),n=this.getId(t),o={...t,spatialIndexId:n};this.objectsById.set(n,o);const i=Math.floor(e.minX/this.CELL_SIZE),r=Math.floor(e.minY/this.CELL_SIZE),s=Math.floor(e.maxX/this.CELL_SIZE),a=Math.floor(e.maxY/this.CELL_SIZE);for(let t=i;t<=s;t++)for(let e=r;e<=a;e++){const n=`${t}x${e}`,i=this.buckets.get(n);i?i.push(o):this.buckets.set(n,[o])}}removeObject(t){const e=this.objectsById.get(t);if(!e)return!1;this.objectsById.delete(t);const n=this.getBounds(e),o=Math.floor(n.minX/this.CELL_SIZE),i=Math.floor(n.minY/this.CELL_SIZE),r=Math.floor(n.maxX/this.CELL_SIZE),s=Math.floor(n.maxY/this.CELL_SIZE);for(let e=o;e<=r;e++)for(let n=i;n<=s;n++){const o=`${e}x${n}`,i=this.buckets.get(o);if(i){const e=i.findIndex(e=>e.spatialIndexId===t);-1!==e&&(i.splice(e,1),0===i.length&&this.buckets.delete(o))}}return!0}getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getObjectsInBounds(t,e=0){const n=[],o=new Set,i=Math.floor((t.minX-e)/this.CELL_SIZE),r=Math.floor((t.minY-e)/this.CELL_SIZE),s=Math.floor((t.maxX+e)/this.CELL_SIZE),a=Math.floor((t.maxY+e)/this.CELL_SIZE);for(let t=i;t<=s;t++)for(let e=r;e<=a;e++){const i=`${t}x${e}`,r=this.buckets.get(i)||[];for(const t of r){const e=t.spatialIndexId;o.has(e)||(o.add(e),n.push(t))}}return n}},BO=.1,jO=.1,$O=BO,YO=BO,XO=.005;function VO(t){return"pcb_trace_segment"===t.type||"pcb_smtpad"===t.type?[t.layer]:"pcb_plated_hole"===t.type?Array.isArray(t.layers)?t.layers:[...uw]:"pcb_hole"===t.type?[...uw]:"pcb_via"===t.type?Array.isArray(t.layers)?t.layers:[...uw]:"pcb_keepout"===t.type&&Array.isArray(t.layers)?t.layers:[]}var WO=(t,e)=>{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=e.minX,r=e.minY,s=e.maxX,a=e.maxY;if(n.x===o.x&&n.y===o.y){const t=Math.max(i,Math.min(s,n.x)),e=Math.max(r,Math.min(a,n.y));return t===n.x&&e===n.y?{x:n.x,y:n.y}:{x:t,y:e}}const c=o.x-n.x,l=o.y-n.y,d=0!==c?(i-n.x)/c:Number.NEGATIVE_INFINITY,h=0!==c?(s-n.x)/c:Number.POSITIVE_INFINITY,u=0!==l?(r-n.y)/l:Number.NEGATIVE_INFINITY,p=0!==l?(a-n.y)/l:Number.POSITIVE_INFINITY,m=Math.max(Math.min(d,h),Math.min(u,p)),g=Math.min(Math.max(d,h),Math.max(u,p));if(m<=g&&g>=0&&m<=1){const t=Math.max(0,Math.min(1,m));return{x:n.x+t*c,y:n.y+t*l}}const f={x:Math.max(i,Math.min(s,n.x)),y:Math.max(r,Math.min(a,n.y))},y={x:Math.max(i,Math.min(s,o.x)),y:Math.max(r,Math.min(a,o.y))},_=(f.x-n.x)**2+(f.y-n.y)**2,b=(y.x-o.x)**2+(y.y-o.y)**2,x=[{start:{x:i,y:r},end:{x:s,y:r}},{start:{x:s,y:r},end:{x:s,y:a}},{start:{x:s,y:a},end:{x:i,y:a}},{start:{x:i,y:a},end:{x:i,y:r}}];let v=Math.min(_,b),S=_<=b?f:y;const I=(t,e,n)=>Math.max(e,Math.min(n,t));for(const t of x){const e={x:o.x-n.x,y:o.y-n.y},i={x:t.end.x-t.start.x,y:t.end.y-t.start.y},r={x:n.x-t.start.x,y:n.y-t.start.y},s=e.x*e.x+e.y*e.y,a=e.x*i.x+e.y*i.y,c=e.x*r.x+e.y*r.y,l=i.x*i.x+i.y*i.y,d=i.x*r.x+i.y*r.y,h=s*l-a*a;if(Math.abs(h)<1e-10)continue;let u=(a*d-l*c)/h,p=(s*d-a*c)/h;u=I(u,0,1),p=I(p,0,1);const m={x:n.x+u*e.x,y:n.y+u*e.y},g={x:t.start.x+p*i.x,y:t.start.y+p*i.y},f=m.x-g.x,y=m.y-g.y,_=f*f+y*y;_<v&&(v=_,S={x:(m.x+g.x)/2,y:(m.y+g.y)/2})}return S},HO=(t,e)=>{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i={x:e.x1,y:e.y1},r={x:e.x2,y:e.y2},s={x:o.x-n.x,y:o.y-n.y},a={x:r.x-i.x,y:r.y-i.y},c=s.x*s.x+s.y*s.y,l=a.x*a.x+a.y*a.y;if(0===c||0===l){if(0===c&&0===l)return{x:(n.x+i.x)/2,y:(n.y+i.y)/2};if(0===c){const t=UO(((n.x-i.x)*a.x+(n.y-i.y)*a.y)/l,0,1),e={x:i.x+t*a.x,y:i.y+t*a.y};return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}}const t=UO(((i.x-n.x)*s.x+(i.y-n.y)*s.y)/c,0,1),e={x:n.x+t*s.x,y:n.y+t*s.y};return{x:(e.x+i.x)/2,y:(e.y+i.y)/2}}const d=n.x-i.x,h=n.y-i.y,u=s.x*s.x+s.y*s.y,p=s.x*a.x+s.y*a.y,m=s.x*d+s.y*h,g=a.x*a.x+a.y*a.y,f=a.x*d+a.y*h,y=u*g-p*p;if(y<1e-10)return GO(n,o,i,r,s,a,c,l);let _=(p*f-g*m)/y,b=(u*f-p*m)/y;_=UO(_,0,1),b=UO(b,0,1),b=(_*p+f)/g,b=UO(b,0,1),_=(b*p-m)/u,_=UO(_,0,1);const x=n.x+_*s.x,v=n.y+_*s.y,S=i.x+b*a.x,I=i.y+b*a.y,C=x-S,P=v-I;Math.sqrt(C*C+P*P);return{x:(x+S)/2,y:(v+I)/2}},GO=(t,e,n,o,i,r,s,a)=>{let c=((n.x-t.x)*i.x+(n.y-t.y)*i.y)/s;c=UO(c,0,1);const l={x:t.x+c*i.x,y:t.y+c*i.y};let d=((o.x-t.x)*i.x+(o.y-t.y)*i.y)/s;d=UO(d,0,1);const h={x:t.x+d*i.x,y:t.y+d*i.y};let u=((t.x-n.x)*r.x+(t.y-n.y)*r.y)/a;u=UO(u,0,1);const p={x:n.x+u*r.x,y:n.y+u*r.y};let m=((e.x-n.x)*r.x+(e.y-n.y)*r.y)/a;m=UO(m,0,1);const g={x:n.x+m*r.x,y:n.y+m*r.y},f=[{pointA:l,pointB:n,distance:Math.sqrt((l.x-n.x)**2+(l.y-n.y)**2)},{pointA:h,pointB:o,distance:Math.sqrt((h.x-o.x)**2+(h.y-o.y)**2)},{pointA:t,pointB:p,distance:Math.sqrt((t.x-p.x)**2+(t.y-p.y)**2)},{pointA:e,pointB:g,distance:Math.sqrt((e.x-g.x)**2+(e.y-g.y)**2)}].reduce((t,e)=>e.distance<t.distance?e:t);return{x:(f.pointA.x+f.pointB.x)/2,y:(f.pointA.y+f.pointB.y)/2}},UO=(t,e,n)=>Math.max(e,Math.min(n,t)),ZO=t=>"pcb_trace_segment"===t.type?{minX:Math.min(t.x1,t.x2),minY:Math.min(t.y1,t.y2),maxX:Math.max(t.x1,t.x2),maxY:Math.max(t.y1,t.y2)}:EM([t]);function qO(t){const e=new Set;for(const n of t.route)"wire"===n.route_type&&(n.start_pcb_port_id&&e.add(n.start_pcb_port_id),n.end_pcb_port_id&&e.add(n.end_pcb_port_id));return Array.from(e)}function JO(t){const e=new Set;for(const n of t)for(const t of qO(n))e.add(t);return Array.from(e)}var KO=t=>{if("pcb_via"===t.type)return t.outer_diameter/2;if("pcb_plated_hole"===t.type&&"circle"===t.shape)return t.outer_diameter/2;if("pcb_hole"===t.type&&"circle"===t.hole_shape)return t.hole_diameter/2;if("pcb_smtpad"===t.type&&"circle"===t.shape)return t.radius;throw new Error(`Could not determine radius of element: ${JSON.stringify(t)}`)};function QO(t,{connMap:e,minClearance:n=.1}={}){const o=[];(t=>{const e=t.filter(t=>"pcb_port"===t.type),n=t.filter(t=>"pcb_smtpad"===t.type),o=t.filter(t=>"pcb_trace"===t.type);function i(t,o={}){const i=o.traceWidth||0,r=e.find(e=>zO(e.x,e.y,t.x,t.y)<.01);if(r)return r.pcb_port_id;if(o.isFirstOrLastPoint){const e=n.find(e=>"rect"===e.shape?Math.abs(t.x-e.x)<e.width/2+i/2&&Math.abs(t.y-e.y)<e.height/2+i/2:"circle"===e.shape?zO(t.x,t.y,e.x,e.y)<e.radius:void 0);if(e)return e.pcb_port_id??null}return null}for(const t of o)for(let e=0;e<t.route.length;e++){const n=t.route[e],o=0===e||e===t.route.length-1;if("wire"===n.route_type){if(!n.start_pcb_port_id&&0===e){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t&&(n.start_pcb_port_id=t)}if(!n.end_pcb_port_id&&e===t.route.length-1){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t&&(n.end_pcb_port_id=t)}}}})(t),e??=v_(t);const i=vM(t).pcb_trace.list().flatMap(t=>{const e=[];for(let n=0;n<t.route.length-1;n++){const o=t.route[n],i=t.route[n+1];"wire"===o.route_type&&("wire"===i.route_type&&o.layer===i.layer&&e.push({type:"pcb_trace_segment",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:"width"in o?o.width:"width"in i?i.width:jO,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),r=vM(t).pcb_smtpad.list(),s=vM(t).pcb_plated_hole.list(),a=vM(t).pcb_hole.list(),c=vM(t).pcb_via.list(),l=vM(t).pcb_keepout.list(),d=[...i,...r,...s,...a,...c,...l],h=new FO({objects:d,getBounds:ZO}),u=e=>NM(t,e),p=(t,e,n)=>n<0?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,m=new Set;for(const t of i){const i=n,r=ZO(t),s=h.getObjectsInBounds(r,i+t.thickness/2);if(t.x1!==t.x2||t.y1!==t.y2)for(const r of s){if(!VO(r).includes(t.layer))continue;if("pcb_trace_segment"===r.type){const i=r;if(t.layer!==i.layer)continue;if(e.areIdsConnected(t.pcb_trace_id,i.pcb_trace_id))continue;const s=Oe({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:i.x1,y:i.y1},{x:i.x2,y:i.y2})-t.thickness/2-i.thickness/2;if(s>n-XO)continue;const a=`overlap_${t.pcb_trace_id}_${i.pcb_trace_id}`,c=`overlap_${i.pcb_trace_id}_${t.pcb_trace_id}`;if(m.has(a))continue;if(m.has(c))continue;m.add(a),o.push({type:"pcb_trace_error",error_type:"pcb_trace_error",message:p(u(t.pcb_trace_id),u(i.pcb_trace_id),s),pcb_trace_id:t.pcb_trace_id,source_trace_id:"",pcb_trace_error_id:a,pcb_component_ids:[],center:HO(t,i),pcb_port_ids:JO([t._pcbTrace,i._pcbTrace])});continue}const s=AM(r);if(e.areIdsConnected(t.pcb_trace_id,"pcb_trace_id"in r?r.pcb_trace_id:s))continue;if("pcb_via"===r.type||"pcb_plated_hole"===r.type&&"circle"===r.shape||"pcb_hole"===r.type||"pcb_smtpad"===r.type&&"circle"===r.shape){const e=KO(r),i=De({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:r.x,y:r.y,radius:e})-t.thickness/2;if(i>n-XO)continue;const a=`overlap_${t.pcb_trace_id}_${s}`;if(m.has(a))continue;m.add(a),o.push({type:"pcb_trace_error",error_type:"pcb_trace_error",message:p(u(t.pcb_trace_id),`${r.type} "${u(AM(r))}"`,i),pcb_trace_id:t.pcb_trace_id,center:WO(t,ZO(r)),source_trace_id:"",pcb_trace_error_id:a,pcb_component_ids:["pcb_component_id"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...JO([t._pcbTrace]),"pcb_port_id"in r?r.pcb_port_id:void 0].filter(Boolean)})}const a=ke({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},ZO(r))-t.thickness/2;if(a+XO<i){const e=`overlap_${t.pcb_trace_id}_${s}`;if(m.has(e))continue;m.add(e),o.push({type:"pcb_trace_error",error_type:"pcb_trace_error",message:p(u(t.pcb_trace_id),`${r.type} "${u(AM(r))}"`,a),pcb_trace_id:t.pcb_trace_id,source_trace_id:"",pcb_trace_error_id:e,pcb_component_ids:["pcb_component_id"in r?r.pcb_component_id:void 0].filter(Boolean),center:WO(t,ZO(r)),pcb_port_ids:[...JO([t._pcbTrace]),"pcb_port_id"in r?r.pcb_port_id:void 0].filter(Boolean)})}}}return o}function tk(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function ek(t,e){return tk(t,e)<=XO}function nk(t,{connMap:e,minClearance:n=$O}={}){const o=t.filter(t=>"pcb_via"===t.type);if(o.length<2)return[];e??=v_(t);const i=[],r=new Set;for(let s=0;s<o.length;s++)for(let a=s+1;a<o.length;a++){const c=o[s],l=o[a];if(ek(c,l))continue;if(!e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=tk(c,l)-c.outer_diameter/2-l.outer_diameter/2;if(d+XO>=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join("_");r.has(h)||(r.add(h),i.push({type:"pcb_via_clearance_error",pcb_error_id:`same_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} are too close together (gap: ${d.toFixed(3)}mm)`,error_type:"pcb_via_clearance_error",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return i}function ok(t,{connMap:e,minClearance:n=YO}={}){const o=t.filter(t=>"pcb_via"===t.type);if(o.length<2)return[];e??=v_(t);const i=[],r=new Set;for(let s=0;s<o.length;s++)for(let a=s+1;a<o.length;a++){const c=o[s],l=o[a];if(ek(c,l))continue;if(e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=tk(c,l)-c.outer_diameter/2-l.outer_diameter/2;if(d+XO>=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join("_");r.has(h)||(r.add(h),i.push({type:"pcb_via_clearance_error",pcb_error_id:`different_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} from different nets are too close together (gap: ${d.toFixed(3)}mm)`,error_type:"pcb_via_clearance_error",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return i}var ik=t=>({minSpacing:t,minClearance:t}),rk={traceClearance:.1,viaClearance:.1},sk=t=>(t=>"layer"in t)(t)?[t.layer]:t.layers;function ak(t,e,n){let o,i=Number.POSITIVE_INFINITY;for(const r of e){const e=n.get(r);if(!e)continue;const s=Math.hypot(e.x-t.x,e.y-t.y);s<i&&(i=s,o=r)}return o??e[0]}function ck(t){const e=[],n=new Set,o=new Set,i=function(t){const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id&&e.set(t.pcb_port_id,{x:t.x,y:t.y});return e}(t);for(const r of t.obstacles){const t=r.connectedTo,s=t.find(t=>t.startsWith("pcb_smtpad_")),a=t.find(t=>t.startsWith("pcb_plated_hole_")),c=t.filter(t=>t.startsWith("pcb_port_")),l=ak(r.center,c,i);if(!s&&!a&&!l)continue;const d=r.layers;if(0===d.length)continue;const h=r.width,u=r.height,p=r.center.x,m=r.center.y,g=r.ccwRotationDegrees,f="number"==typeof g&&Number.isFinite(g);if(d.length>1){const t=a??`pcb_plated_hole_${p.toFixed(3)}_${m.toFixed(3)}`;if(o.has(t))continue;if(o.add(t),f){const n=Math.max(.5*Math.min(h,u),.1);e.push({type:"pcb_plated_hole",pcb_plated_hole_id:t,shape:"rotated_pill_hole_with_rect_pad",hole_shape:"rotated_pill",pad_shape:"rect",hole_width:n,hole_height:n,hole_ccw_rotation:g,rect_pad_width:h,rect_pad_height:u,rect_ccw_rotation:g,hole_offset_x:0,hole_offset_y:0,x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}if(Math.abs(h-u)<.001){e.push({type:"pcb_plated_hole",pcb_plated_hole_id:t,shape:"circle",outer_diameter:Math.max(h,u),hole_diameter:Math.max(.5*Math.min(h,u),.1),x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}e.push({type:"pcb_plated_hole",pcb_plated_hole_id:t,shape:"circular_hole_with_rect_pad",hole_shape:"circle",hole_diameter:Math.max(.5*Math.min(h,u),.1),rect_pad_width:h,rect_pad_height:u,hole_offset_x:0,hole_offset_y:0,x:p,y:m,layers:d,...l?{pcb_port_id:l}:{}});continue}const y=s??`pcb_smtpad_${p.toFixed(3)}_${m.toFixed(3)}`;n.has(y)||(n.add(y),f?e.push({type:"pcb_smtpad",pcb_smtpad_id:y,layer:d[0],shape:"rotated_rect",x:p,y:m,width:h,height:u,ccw_rotation:g,...l?{pcb_port_id:l}:{}}):e.push({type:"pcb_smtpad",pcb_smtpad_id:y,layer:d[0],shape:"rect",width:h,height:u,x:p,y:m,...l?{pcb_port_id:l}:{}}))}return e}function lk(t,e,n=.1,o=t.minViaDiameter??.3){const i=[];i.push(...function(t,e){const n=[];return t.connections.forEach(o=>{const i=o.pointsToConnect.filter(t=>t.pcb_port_id).map(t=>t.pcb_port_id).filter(Boolean),r=o.netConnectionName||o.rootConnectionName||o.name,s=[],a=e.find(t=>(t.connection_name??t.connectionName)===o.name);if(a){const e=t=>"route_type"in t&&"jumper"===t.route_type?t.start:"x"in t&&"y"in t?{x:t.x,y:t.y}:{x:0,y:0},n=[e(a.route[0]),e(a.route[a.route.length-1])];for(const e of n)for(const n of t.obstacles)Be(e,n)<=0&&s.push(n)}const c=n.find(t=>"source_trace"===t.type&&t.source_trace_id===r);if(c){const t=c;t.connected_source_port_ids=[...new Set([...t.connected_source_port_ids,...i])]}else n.push({type:"source_trace",source_trace_id:r,connected_source_port_ids:i.concat(s.flatMap(t=>[`obstacle_${t.center.x.toFixed(3)}_${t.center.y.toFixed(3)}_${t.layers.join(".")}`,...t.connectedTo])),connected_source_net_ids:[]})}),n}(t,e)),i.push(...function(t){const e=new Map;return t.connections.forEach(t=>{t.pointsToConnect.forEach(t=>{t.pcb_port_id&&e.set(t.pcb_port_id,{type:"pcb_port",pcb_port_id:t.pcb_port_id,source_port_id:t.pcb_port_id,x:t.x,y:t.y,layers:sk(t)})})}),Array.from(e.values())}(t)),i.push(...ck(t)),i.push(...function(t,e,n=.3){const o=[],i=new Set;return t.length>0&&("type"in t[0]&&"pcb_trace"===t[0].type?t.forEach(t=>{t.route.forEach(r=>{if("via"===r.route_type){const s=r.via_diameter??n,a=`${r.x},${r.y},${r.from_layer},${r.to_layer}`;i.has(a)||(o.push({type:"pcb_via",pcb_via_id:`via_${o.length}`,pcb_trace_id:t.pcb_trace_id,x:r.x,y:r.y,outer_diameter:s,hole_diameter:.5*s,layers:Wy(r,e)}),i.add(a))}})}):t.forEach((t,r)=>{const s=`trace_${r}`,a=t.viaDiameter??n;for(let n=1;n<t.route.length;n++){const r=t.route[n-1],c=t.route[n];if(r.z!==c.z&&Math.abs(r.x-c.x)<.01&&Math.abs(r.y-c.y)<.01){const t=Vy(r.z,e),n=Vy(c.z,e),l=`${c.x},${c.y},${t},${n}`;i.has(l)||(o.push({type:"pcb_via",pcb_via_id:`via_${o.length}`,pcb_trace_id:s,x:c.x,y:c.y,outer_diameter:a,hole_diameter:.5*a,layers:Wy({from_layer:t,to_layer:n},e)}),i.add(l))}}})),o}(e,t.layerCount,o));const r=new Map;return t.connections.forEach(t=>{r.set(t.name,t.netConnectionName||t.rootConnectionName||t.name)}),e.length>0&&("type"in e[0]&&"pcb_trace"===e[0].type?e.forEach(t=>{const e=t.connection_name;i.push(function(t,e){return{type:"pcb_trace",pcb_trace_id:t.pcb_trace_id,source_trace_id:e,route:t.route.map(t=>"wire"===t.route_type?{route_type:"wire",x:t.x,y:t.y,width:t.width,layer:t.layer,start_pcb_port_id:t.start_pcb_port_id,end_pcb_port_id:t.end_pcb_port_id}:"via"===t.route_type?{route_type:"via",x:t.x,y:t.y,from_layer:t.from_layer,to_layer:t.to_layer}:null).filter(t=>null!==t)}}(t,r.get(e)||e))}):e.forEach((e,o)=>{const s=e.connectionName,a=function(t,e,n,o=.1,i){const r=[];if(!t.jumpers||0===t.jumpers.length)return[{type:"pcb_trace",pcb_trace_id:e,source_trace_id:n,route:t.route.map((e,n)=>{const r=0===n,s=n===t.route.length-1;return{route_type:"wire",x:e.x,y:e.y,width:o,layer:Vy(e.z,i),...r&&e.pcb_port_id?{start_pcb_port_id:e.pcb_port_id}:{},...s&&e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})}];const s=[];for(const e of t.jumpers){let n=-1,o=-1;for(let i=0;i<t.route.length;i++){const r=t.route[i];Math.abs(r.x-e.start.x)<.01&&Math.abs(r.y-e.start.y)<.01&&(n=i),Math.abs(r.x-e.end.x)<.01&&Math.abs(r.y-e.end.y)<.01&&(o=i)}-1!==n&&-1!==o&&(n>o&&([n,o]=[o,n]),s.push({startIdx:n,endIdx:o}))}s.sort((t,e)=>t.startIdx-e.startIdx);let a=0,c=0;for(const{startIdx:l,endIdx:d}of s){if(l>=a){const s=t.route.slice(a,l+1);s.length>0&&(r.push({type:"pcb_trace",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((t,e)=>{const n=0===e&&0===a;return{route_type:"wire",x:t.x,y:t.y,width:o,layer:Vy(t.z,i),...n&&t.pcb_port_id?{start_pcb_port_id:t.pcb_port_id}:{}}})}),c++)}a=d}if(a<t.route.length){const s=t.route.slice(a);if(s.length>0){const t=!0;r.push({type:"pcb_trace",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((e,n)=>{const r=t&&n===s.length-1;return{route_type:"wire",x:e.x,y:e.y,width:o,layer:Vy(e.z,i),...r&&e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})})}}return r}(e,`trace_${o}`,r.get(s)||s,n,t.layerCount);i.push(...a)})),i}var dk=t=>t.rootConnectionName??t.connectionName,hk=(t,e)=>{if(t&&e)return t.getNetConnectedToId(e)},uk=(t,e,n)=>{if(!e)return!1;if(t===e)return!0;if(n?.areIdsConnected(t,e))return!0;const o=hk(n,t),i=hk(n,e);return!(!o||o!==e&&o!==i)||!(!i||i!==t&&i!==o)},pk=(t,e,n)=>e.connectedTo?.some(e=>uk(t,e,n))??!1,mk=(t,e,n)=>Math.max(e,Math.min(t,n)),gk=(t,e)=>{t.x=mk(t.x,e.minX,e.maxX),t.y=mk(t.y,e.minY,e.maxY)},fk=(t,e)=>({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),yk=(t,e)=>({minCellX:Math.floor(t.minX/e),maxCellX:Math.floor(t.maxX/e),minCellY:Math.floor(t.minY/e),maxCellY:Math.floor(t.maxY/e)}),_k=(t,e)=>`${t}:${e}`,bk=(t,e,n)=>{const o=new Map;for(let i=0;i<t.length;i+=1){const r=t[i];if(!r)continue;const s=yk(e(r),n);for(let t=s.minCellX;t<=s.maxCellX;t+=1)for(let e=s.minCellY;e<=s.maxCellY;e+=1){const n=_k(t,e),r=o.get(n);r?r.push(i):o.set(n,[i])}}return o},xk=(t,e,n)=>{const o=new Set,i=yk(e,n);for(let e=i.minCellX;e<=i.maxCellX;e+=1)for(let n=i.minCellY;n<=i.maxCellY;n+=1){const i=t.get(_k(e,n));if(i)for(const t of i)o.add(t)}return[...o].sort((t,e)=>t-e)},vk=1e-6,Sk=(t,e,n)=>{if(0===t.length)return[];const o=n?.traceThickness??.1,i=t[0],r=t.at(-1),s=t=>{if(t.pcb_port_id)return t.pcb_port_id;const o=Vy(t.z,e);return n?.connectionPoints?.find(e=>{return e.pcb_port_id&&(n=e,i=t,Math.abs(n.x-i.x)<=vk&&Math.abs(n.y-i.y)<=vk)&&sk(e).includes(o);var n,i})?.pcb_port_id},a=s(i),c=s(r),l=[{route_type:"wire",x:i.x,y:i.y,width:o,layer:Vy(i.z,e),...a?{start_pcb_port_id:a}:{},...1===t.length&&c?{end_pcb_port_id:c}:{}}];for(let i=1;i<t.length;i+=1){const r=t[i-1],s=t[i];r&&s&&(r.z!==s.z&&r.x===s.x&&r.y===s.y&&l.push({route_type:"via",x:s.x,y:s.y,from_layer:Vy(r.z,e),to_layer:Vy(s.z,e),...n?.viaDiameter?{via_diameter:n.viaDiameter}:{}}),l.push({route_type:"wire",x:s.x,y:s.y,width:o,layer:Vy(s.z,e),...i===t.length-1&&c?{end_pcb_port_id:c}:{}}))}return l},Ik=(t,e)=>({x:Ae(t.x,e.minX,e.maxX),y:Ae(t.y,e.minY,e.maxY)}),Ck=(t,e)=>{const n=t.x-e.center.x,o=t.y-e.center.y;return e.circular?Math.max(0,Math.hypot(n,o)-e.halfWidth):je(R(e.worldToLocal,t),{minX:-e.halfWidth,maxX:e.halfWidth,minY:-e.halfHeight,maxY:e.halfHeight})},Pk=(t,e)=>({kind:"line",start:t,end:e,bounds:We([t,e])}),Mk=(t,e)=>({kind:"circle",center:t,radius:e,bounds:Ve({center:t,width:2*e,height:2*e})}),Nk=t=>{const e=t.clearance+h_;if(t.circular)return[Mk(t.center,t.halfWidth+e)];const n=(e,n)=>R(t.localToWorld,{x:e,y:n}),{halfWidth:o,halfHeight:i}=t;return[Pk(n(-o,-i-e),n(o,-i-e)),Pk(n(o+e,-i),n(o+e,i)),Pk(n(o,i+e),n(-o,i+e)),Pk(n(-o-e,i),n(-o-e,-i)),Mk(n(-o,-i),e),Mk(n(o,-i),e),Mk(n(o,i),e),Mk(n(-o,i),e)]},wk=(t,e)=>{if("circle"===e.kind){const n=t.x-e.center.x,o=t.y-e.center.y,i=Math.hypot(n,o);return 0===i?[{x:e.center.x+e.radius,y:e.center.y},{x:e.center.x-e.radius,y:e.center.y},{x:e.center.x,y:e.center.y+e.radius},{x:e.center.x,y:e.center.y-e.radius}]:[{x:e.center.x+n*e.radius/i,y:e.center.y+o*e.radius/i}]}return[e.start,e.end,ze(t,e.start,e.end)]},Tk=(t,e)=>{const n=t.end.x-t.start.x,o=t.end.y-t.start.y,i=t.start.x-e.center.x,r=t.start.y-e.center.y,s=n*n+o*o;if(0===s)return[];const a=2*(i*n+r*o),c=a*a-4*s*(i*i+r*r-e.radius*e.radius);if(c<0)return[];const l=Math.sqrt(c);return[(-a-l)/(2*s),(-a+l)/(2*s)].filter(t=>t>=0&&t<=1).map(e=>({x:t.start.x+n*e,y:t.start.y+o*e}))},Rk=(t,e)=>{if("line"===t.kind&&"circle"===e.kind)return Tk(t,e);if("circle"===t.kind&&"line"===e.kind)return Tk(e,t);if("line"===t.kind&&"line"===e.kind){const n=ve(t.start,t.end,e.start,e.end);return n?[n]:[]}if("circle"!==t.kind||"circle"!==e.kind)return[];const n=e.center.x-t.center.x,o=e.center.y-t.center.y,i=Math.hypot(n,o);if(0===i||i>t.radius+e.radius||i<Math.abs(t.radius-e.radius))return[];const r=(t.radius**2-e.radius**2+i**2)/(2*i),s=Math.sqrt(Math.max(0,t.radius**2-r**2)),a=t.center.x+n*r/i,c=t.center.y+o*r/i;return[{x:a-o*s/i,y:c+n*s/i},{x:a+o*s/i,y:c-n*s/i}]},Ek=(t,e,n,o,i)=>{const r=new Set(function(t,e,n=1){if(0===n)throw new Error("step cannot be 0");let o,i;void 0===e?(o=0,i=t):(o=t,i=e);const r=[];if(n>0)for(let t=o;t<i;t+=n)r.push(t);else for(let t=o;t>i;t+=n)r.push(t);return r}(Math.min(...o),Math.max(...o)+1).map(e=>Vy(e,t.layerCount)));return t.obstacles.filter(t=>!t.isCopperPour&&t.layers.some(t=>r.has(t))).map(o=>{const r="number"==typeof o.ccwRotationDegrees&&Number.isFinite(o.ccwRotationDegrees),s=!r&&o.layers.length>1&&Math.abs(o.width-o.height)<.001,a=D(k(o.center.x,o.center.y),j(r?o.ccwRotationDegrees:0)),c=s?Math.max(o.width,o.height)/2:o.width/2,l=s?c:o.height/2,d=pk(dk(e),o,i)||pk(e.connectionName,o,i),h=n+(d?0:y_(t)),u=We(E(a,[{x:-c,y:-l},{x:c,y:-l},{x:c,y:l},{x:-c,y:l}])),p=h+h_;return{center:o.center,halfWidth:c,halfHeight:l,localToWorld:a,worldToLocal:A(a),circular:s,clearance:h,bounds:{minX:u.minX-p,maxX:u.maxX+p,minY:u.minY-p,maxY:u.maxY+p}}})},Ak=(t,e,n,o)=>{const i=Math.min(...t.zLayers),r=Math.max(...t.zLayers),s=e.filter(e=>e.z>=i&&e.z<=r&&!uk(t.rootConnectionName,e.rootConnectionName,o)).map(e=>({segment:e,required:t.radius+e.radius+n})).filter(({segment:e,required:n})=>be(t,e.start,e.end)<=n+p_),a=s.flatMap(({segment:t,required:e})=>{const{start:n,end:o}=t,i=Math.sqrt(Ye(n,o));if(i<=h_)return[];const r=e+h_,s=(o.y-n.y)/i*r,a=(n.x-o.x)/i*r;return[Pk({x:n.x+s,y:n.y+a},{x:o.x+s,y:o.y+a}),Pk({x:n.x-s,y:n.y-a},{x:o.x-s,y:o.y-a}),Mk(n,r),Mk(o,r)]}).filter(e=>je(t,e.bounds)<=p_),c=[],l=e=>{Ye(e,t)>p_**2||c.some(t=>Ye(t,e)<1e-12)||s.some(({segment:t,required:n})=>be(e,t.start,t.end)<n)||c.push(e)};l(t);for(let e=0;e<a.length;e+=1){const n=a[e];for(const e of wk(t,n))l(e);for(let t=e+1;t<a.length;t+=1){const e=a[t];if(Xe(n.bounds,e.bounds))for(const t of Rk(n,e))l(t)}}return c.sort((e,n)=>Ye(e,t)-Ye(n,t))},Ok=t=>({...t,route:t.route.map(t=>({...t})),vias:t.vias.map(t=>({...t}))}),kk=t=>t.map(Ok),Lk=(t,e)=>{const n=new Set(e);return t.map((t,e)=>n.has(e)?Ok(t):t)},Dk=(t,e)=>Math.abs(t.x-e.x)<=u_&&Math.abs(t.y-e.y)<=u_,zk=["pcb_smtpad","pcb_plated_hole","pcb_hole","pcb_keepout"],Fk=t=>"string"==typeof t.type?t.type:"string"==typeof t.error_type?t.error_type:void 0,Bk=t=>{if("pcb_pad_trace_clearance_error"===Fk(t))return!0;const e="string"==typeof t.message?t.message.toLowerCase():"";return(e.includes("pcb_trace")||e.includes("pcb trace"))&&zk.some(t=>e.includes(t))},jk=t=>{const e="string"==typeof t.message?t.message:"",n=e.match(/gap: (-?\d+(?:\.\d+)?)mm/),o=e.match(/required: (-?\d+(?:\.\d+)?)mm/);if(n&&o){const t=Number.parseFloat(n[1]),e=Number.parseFloat(o[1]);if(Number.isFinite(t)&&Number.isFinite(e))return Math.max(0,e-t)}if(n){const t=Number.parseFloat(n[1]),e=rk.traceClearance??.1;if(Number.isFinite(t))return Math.max(0,e-t)}return 1},$k={projectEngineError:t=>({...t,center:"object"==typeof t.first_contact_center?t.first_contact_center:t.center,message:"string"==typeof t.first_contact_message?t.first_contact_message:t.message,actual_clearance:"number"==typeof t.first_actual_clearance?t.first_actual_clearance:t.actual_clearance}),getErrorSeverity:jk},Yk={projectEngineError:t=>t,getErrorSeverity:t=>{const e=Number(t.minimum_clearance),n=Number(t.worst_actual_clearance);return Number.isFinite(e)&&Number.isFinite(n)?Math.max(0,e-n):jk(t)}},Xk=(t,e=jk)=>t.reduce((t,n)=>t+e(n),0),Vk=(t,e,n,o,i,r=$k)=>{const s=i&&!n?t:((t,e)=>e?{...t,connections:t.connections.map(t=>{const n=hk(e,t.name)??hk(e,t.rootConnectionName)??t.netConnectionName;return n?{...t,netConnectionName:n}:t}),obstacles:t.obstacles.map(t=>{const n=new Set(t.connectedTo);for(const o of t.connectedTo){const t=hk(e,o);t&&n.add(t)}return{...t,connectedTo:[...n]}})}:t)(t,o),{traces:a,traceRouteIndexById:c}=((t,e)=>{const n=[],o=new Map,i=new Map;for(let t=0;t<e.length;t+=1){const n=e[t];if(!n)continue;const o=i.get(n.connectionName);o?o.push({route:n,routeIndex:t}):i.set(n.connectionName,[{route:n,routeIndex:t}])}for(const e of t.connections){const r=i.get(e.name)??[];for(let i=0;i<r.length;i+=1){const s=r[i];if(!s)continue;const a=`${e.name}_${i}`;n.push({type:"pcb_trace",pcb_trace_id:a,connection_name:e.netConnectionName??e.rootConnectionName??e.name,route:Sk(s.route.route,t.layerCount,{traceThickness:s.route.traceThickness??e.nominalTraceWidth??t.nominalTraceWidth??t.minTraceWidth,viaDiameter:s.route.viaDiameter??t.minViaDiameter,connectionPoints:e.pointsToConnect})}),o.set(a,s.routeIndex)}}return{traces:n,traceRouteIndexById:o}})(s,e),l=n?.({srj:s,routes:e,traces:a});if(l){const t=Array.isArray(l)?l:l.errors,e=Array.isArray(l)?l:l.errorsWithCenters??l.errors;return{errors:e,count:t.length,issueScore:Xk(e,r.getErrorSeverity),legacyIssueScore:Xk(e.filter(t=>!uD(t)),r.getErrorSeverity),traceRouteIndexById:c}}const d=i?.evaluate(a)??((t,e={})=>{const n=Math.max(e.viaClearance??.1,.1),o=[...QO(t,ik(e.traceClearance)),...nk(t,ik(n)),...ok(t,ik(n))],i=t.filter(t=>"pcb_via"===t.type),r=new Map(i.map(t=>[t.pcb_via_id,t])),s=o.map(t=>{if("center"in t&&t.center)return t;if("pcb_center"in t&&t.pcb_center)return{...t,center:t.pcb_center};if("pcb_via_ids"in t&&Array.isArray(t.pcb_via_ids)){const[e,n]=t.pcb_via_ids;if("string"!=typeof e||"string"!=typeof n)return t;const o=r.get(e),i=r.get(n);if(o&&i)return{...t,center:{x:(o.x+i.x)/2,y:(o.y+i.y)/2}}}if("pcb_error_id"in t&&"string"==typeof t.pcb_error_id&&(t.pcb_error_id.startsWith("same_net_vias_close_")||t.pcb_error_id.startsWith("different_net_vias_close_"))){const e=t.pcb_error_id.replace("same_net_vias_close_","").replace("different_net_vias_close_","").split("_").filter(Boolean);if(2===e.length){const n=e[0],o=e[1];if(!n||!o)return t;const i=r.get(n),s=r.get(o);if(i&&s)return{...t,center:{x:(i.x+s.x)/2,y:(i.y+s.y)/2}}}}return t}),a=s.filter(t=>Boolean(t.center));return{errors:o,errorsWithCenters:s,locationAwareErrors:a}})(lk(s,a,s.minTraceWidth,s.minViaDiameter),{...rk,traceClearance:s.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:s.minTraceToPadEdgeClearance??rk.viaClearance}),h=d.errors,u=(d.errorsWithCenters.length>0?d.errorsWithCenters:d.errors).map(t=>r.projectEngineError(t));return{errors:u,count:h.length,issueScore:Xk(u,r.getErrorSeverity),legacyIssueScore:Xk(u.filter(t=>!uD(t)),r.getErrorSeverity),traceRouteIndexById:c}},Wk=(t,e,n,o,i)=>Vk(t,e,n,o,i,$k),Hk=(t,e,n,o,i)=>Vk(t,e,n,o,i,Yk),Gk=(t,e=.3)=>{const n=[];for(let o=0;o<t.length;o+=1){const i=t[o];if(!i)continue;const r=new Set;for(let t=0;t<i.route.length-1;t+=1){const s=i.route[t],a=i.route[t+1];if(!s||!a)continue;if(s.z===a.z||!Dk(s,a))continue;const c=[t,t+1];for(let e=t-1;e>=0;e-=1){const t=i.route[e];if(!t||!Dk(t,s))break;c.push(e)}for(let e=t+2;e<i.route.length;e+=1){const t=i.route[e];if(!t||!Dk(t,s))break;c.push(e)}const l=[...new Set(c)];if(l.some(t=>r.has(t)))continue;for(const t of l)r.add(t);const d=l.filter(t=>0===t||t===i.route.length-1),h=d.some(t=>Boolean(i.route[t]?.pcb_port_id));n.push({routeIndex:o,rootConnectionName:dk(i),pointIndexes:l,zLayers:[...new Set(l.map(t=>i.route[t].z))],x:s.x,y:s.y,radius:(i.viaDiameter??e)/2,movable:0===d.length,canCanonicalize:0===d.length||!h})}}return n},Uk=(t,e)=>{const n=[];for(let o=0;o<t.route.length-1;o+=1){const i=t.route[o],r=t.route[o+1];i&&r&&(i.z!==r.z||Dk(i,r)||n.push({routeIndex:e,rootConnectionName:dk(t),startIndex:o,endIndex:o+1,start:i,end:r,z:i.z,radius:(t.traceThickness??.1)/2}))}return n},Zk=t=>t.flatMap((t,e)=>Uk(t,e)),qk=t=>({minX:t.x,minY:t.y,maxX:t.x,maxY:t.y}),Jk=t=>({minX:Math.min(t.start.x,t.end.x),minY:Math.min(t.start.y,t.end.y),maxX:Math.max(t.start.x,t.end.x),maxY:Math.max(t.start.y,t.end.y)}),Kk=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}),Qk=(t,e)=>{if(t.zLayers&&t.zLayers.length>0)return t.zLayers;const n=Array.from({length:e},(t,e)=>e).filter(n=>t.layers.includes(Vy(n,e)));return n.length>0?n:Array.from({length:e},(t,e)=>e)},tL=(t,e,n)=>{const o=e.reduce((t,e)=>Math.max(t,e.radius),(t.minViaDiameter??.3)/2),i=n.reduce((t,e)=>Math.max(t,e.radius),t.minTraceWidth/2),r=(rk.traceClearance??.1)+g_;return Math.max(2*o+.2+g_,o+i+r,2*i+r,i+f_(t)+g_,o+y_(t)+g_)},eL=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r<=h_)return{x:e.x,y:e.y,t:0};const s=mk(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return{x:e.x+o*s,y:e.y+i*s,t:s}},nL=(t,e)=>eL(t,e.start,e.end),oL=(t,e)=>{const n=e.width/2,o=e.height/2,i=Math.max(Math.abs(t.x-e.center.x)-n,0),r=Math.max(Math.abs(t.y-e.center.y)-o,0);return Math.hypot(i,r)},iL=(t,e)=>t.x>=e.center.x-e.width/2-u_&&t.x<=e.center.x+e.width/2+u_&&t.y>=e.center.y-e.height/2-u_&&t.y<=e.center.y+e.height/2+u_,rL=(t,e,n,o)=>t.obstacles.find(i=>pk(dk(e),i,o)&&Qk(i,t.layerCount).includes(n.z)&&iL(n,i)),sL=(t,e,n=.6,o)=>{let i;for(const r of t.obstacles){if(o&&!o(r))continue;const t=oL(e,r);t>n||(!i||t<i.distance)&&(i={obstacle:r,distance:t})}return i?.obstacle},aL=(t,e,n)=>{const o=e.width/2,i=e.height/2,r=mk(t.x,e.center.x-o,e.center.x+o),s=mk(t.y,e.center.y-i,e.center.y+i);let a=t.x-r,c=t.y-s,l=Math.hypot(a,c);if(l<=h_){o-Math.abs(t.x-e.center.x)<i-Math.abs(t.y-e.center.y)?(a=t.x>=e.center.x?1:-1,c=0,l=0):(a=0,c=t.y>=e.center.y?1:-1,l=0)}const d=n-l;if(d<=0)return;const h=Math.hypot(a,c);return{direction:{x:h>h_?a/h:1,y:h>h_?c/h:0},penetration:d}},cL=(t,e,n,o)=>{const i=e.message;if("string"!=typeof i||!i.includes("pcb_"))return n;const r=Array.isArray(e.pcb_pad_ids)?e.pcb_pad_ids.filter(t=>"string"==typeof t):[],s=t.obstacles.find(t=>r.some(e=>t.connectedTo.includes(e))&&(o?.(t)??!0));return s?s.center:sL(t,n,.6,o)?.center??n},lL=(t,e)=>{const n=t.route[e];if(!n)return[];const o=[e];for(let i=e-1;i>=0;i-=1){const e=t.route[i];if(!e||!Dk(e,n))break;o.push(i)}for(let i=e+1;i<t.route.length;i+=1){const e=t.route[i];if(!e||!Dk(e,n))break;o.push(i)}return[...new Set(o)]},dL=(t,e)=>{if(e<=0||e>=t.route.length-1)return;const n=lL(t,e);return n.includes(0)||n.includes(t.route.length-1)?void 0:n},hL=(t,e)=>t.x>=e.minX-u_&&t.x<=e.maxX+u_&&t.y>=e.minY-u_&&t.y<=e.maxY+u_,uL=(t,e)=>Math.min(t.x-e.minX,e.maxX-t.x,t.y-e.minY,e.maxY-t.y),pL=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,r=t.x-e.x,s=o*(t.y-e.y)-i*r;if(Math.abs(s)>u_)return!1;const a=Math.min(e.x,n.x)-u_,c=Math.max(e.x,n.x)+u_,l=Math.min(e.y,n.y)-u_,d=Math.max(e.y,n.y)+u_;return t.x>=a&&t.x<=c&&t.y>=l&&t.y<=d},mL=(t,e)=>{if(e.length<3)return!0;for(let n=0;n<e.length;n+=1){const o=e[n],i=e[(n+1)%e.length];if(o&&i&&pL(t,o,i))return!0}let n=!1;for(let o=0,i=e.length-1;o<e.length;i=o,o+=1){const r=e[o],s=e[i];if(!r||!s)continue;r.y>t.y!=s.y>t.y&&t.x<(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x&&(n=!n)}return n},gL=(t,e)=>{const n=Math.hypot(t,e);if(!(n<=h_))return{x:t/n,y:e/n}},fL=(t,e)=>t.outline&&t.outline.length>=3?((t,e)=>{const n=mL(t,e);let o;for(let n=0;n<e.length;n+=1){const i=e[n],r=e[(n+1)%e.length];if(!i||!r)continue;const s=eL(t,i,r),a=Math.hypot(t.x-s.x,t.y-s.y);(!o||a<o.distance)&&(o={projection:s,start:i,end:r,distance:a})}if(!o)return;const i=gL(n?t.x-o.projection.x:o.projection.x-t.x,n?t.y-o.projection.y:o.projection.y-t.y);if(i)return i;const r=o.end.x-o.start.x,s=o.end.y-o.start.y,a=Math.hypot(r,s);if(a<=h_)return;const c=(t=>{let e=0;for(let n=0;n<t.length;n+=1){const o=t[n],i=t[(n+1)%t.length];o&&i&&(e+=o.x*i.y-i.x*o.y)}return e/2})(e)>=0;return{x:c?-s/a:s/a,y:c?r/a:-r/a}})(e,t.outline):((t,e)=>{const n=t.x-e.minX,o=e.maxX-t.x,i=t.y-e.minY,r=e.maxY-t.y,s=Math.min(n,o,i,r);let a=0,c=0;return n<=s+u_&&(a+=1),o<=s+u_&&(a-=1),i<=s+u_&&(c+=1),r<=s+u_&&(c-=1),gL(a,c)})(e,t.bounds),yL=(t,e)=>t.outline&&t.outline.length>=3?mL(e,t.outline):hL(e,t.bounds),_L=(t,e)=>{if(t.outline&&t.outline.length>=3){const n=((t,e)=>{let n=Number.POSITIVE_INFINITY;for(let o=0;o<e.length;o+=1){const i=e[o],r=e[(o+1)%e.length];i&&r&&(n=Math.min(n,be(t,i,r)))}return n})(e,t.outline);return mL(e,t.outline)?n:-n}return uL(e,t.bounds)},bL=(t,e,n)=>{if(Math.abs(e.x-n.x)<=u_&&Math.abs(e.y-n.y)<=u_)return Math.min(_L(t,e),_L(t,n));if(t.outline&&t.outline.length>=3){if(!mL(e,t.outline)||!mL(n,t.outline))return Math.min(_L(t,e),_L(t,n));let o=Number.POSITIVE_INFINITY;for(let i=0;i<t.outline.length;i+=1){const r=t.outline[i],s=t.outline[(i+1)%t.outline.length];r&&s&&(o=Math.min(o,Oe(e,n,r,s)))}return o}return hL(e,t.bounds)&&hL(n,t.bounds)?Math.min(uL(e,t.bounds),uL(n,t.bounds)):Math.min(_L(t,e),_L(t,n))},xL=(t,e)=>e+Math.max(.16,t.defaultObstacleMargin??0,rk.traceClearance??.1),vL=(t,e,n)=>e<t-u_&&Math.min(t,e)<=n+u_,SL=(t,e,n,o,i)=>{const r=t*n.x+e*n.y,s=-Math.max(0,o-i);if(r>=s-u_)return{x:t,y:e};const a=s-r;return{x:t+n.x*a,y:e+n.y*a}},IL=(t,e,n,o,i)=>{const r=fL(t,e);return r?SL(n,o,r,_L(t,e),xL(t,i)):{x:n,y:o}},CL=(t,e,n,o)=>{const i=[...new Set(n)].sort((t,e)=>t-e);if(0===i.length)return Number.POSITIVE_INFINITY;const r=new Set(i),s=t=>o?.get(t)??e.route[t];let a=Number.POSITIVE_INFINITY;for(const e of i){const n=s(e);n&&(a=Math.min(a,_L(t,n)))}for(let n=0;n<e.route.length-1;n+=1){if(!r.has(n)&&!r.has(n+1))continue;const e=s(n),o=s(n+1);e&&o&&(a=Math.min(a,bL(t,e,o)))}return a},PL=(t,e,n,o,i,r)=>{const s=[...new Set(n)].sort((t,e)=>t-e);if(0===s.length)return;const a=((t,e,n,o,i,r)=>{const s=[...new Set(n)].sort((t,e)=>t-e);let a={x:o,y:i};const c=xL(t,r);for(let n=0;n<Math.max(1,s.length);n+=1){let n=!1;for(const o of s){const i=e.route[o];if(!i)continue;const r=fL(t,i);if(!r)continue;const s=SL(a.x,a.y,r,_L(t,i),c);(Math.abs(s.x-a.x)>h_||Math.abs(s.y-a.y)>h_)&&(a=s,n=!0)}if(!n)break}return a})(t,e,s,o,i,r);if(Math.abs(a.x)<=h_&&Math.abs(a.y)<=h_)return;const c=new Map;for(const t of s){const n=e.route[t];if(!n)continue;const o={x:n.x+a.x,y:n.y+a.y};c.set(t,o)}const l=CL(t,e,s),d=CL(t,e,s,c);if(d<r-u_)return;const h=xL(t,r);return vL(l,d,h)?void 0:a},ML=(t,e,n,o,i,r,s)=>{const a=t[e];if(!a)return!1;const c=dL(a,n);if(!c)return!1;const l=PL(r,a,c,o,i,s);if(!l)return!1;let d=!1;for(const t of c){const e=a.route[t];e&&(e.x+=l.x,e.y+=l.y,gk(e,r.bounds),d=!0)}return d},NL=(t,e,n,o,i,r)=>dL(e,n)??((t,e,n,o,i,r)=>{const s=e.route[n];if(!s||s.pcb_port_id||0!==n&&n!==e.route.length-1)return;const a=rL(t,e,s,r);if(!a)return;const c={...s,x:s.x+o,y:s.y+i};return yL(t,c)&&iL(c,a)?lL(e,n):void 0})(t,e,n,o,i,r),wL=(t,e,n,o,i,r)=>{const s=PL(i,t,e,n,o,r);if(!s)return!1;let a=!1;for(const n of e){const e=t.route[n];e&&(e.x+=s.x,e.y+=s.y,gk(e,i.bounds),a=!0)}return a},TL=(t,e,n,o,i,r)=>{const s=e.route[n];if(!s)return!1;if(s.pcb_port_id)return!1;const a=rL(t,e,s,r);return!!a&&iL({...s,x:s.x+o,y:s.y+i},a)},RL=(t,e,n,o)=>{const i=e.route[n];if(i&&!i.pcb_port_id)return rL(t,e,i,o)},EL=(t,e,n,o,i,r,s)=>{const a=t[e];if(!a||0===a.route.length)return!1;const c=((t,e,n,o,i)=>{let r=Number.NEGATIVE_INFINITY,s=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY,c=Number.POSITIVE_INFINITY;for(const n of[0,e.route.length-1]){const o=e.route[n],l=RL(t,e,n,i);if(!o||!l)return;r=Math.max(r,l.center.x-l.width/2-o.x),s=Math.min(s,l.center.x+l.width/2-o.x),a=Math.max(a,l.center.y-l.height/2-o.y),c=Math.min(c,l.center.y+l.height/2-o.y)}if(!(r>s||a>c))return{x:mk(n,r,s),y:mk(o,a,c)}})(i,a,n,o,s);if(!c)return!1;const l=a.route.map((t,e)=>e),d=PL(i,a,l,c.x,c.y,r);if(!d)return!1;const h=a.route.length-1;if(!TL(i,a,0,d.x,d.y,s)||!TL(i,a,h,d.x,d.y,s))return!1;let u=!1;for(const t of a.route)t.x+=d.x,t.y+=d.y,gk(t,i.bounds),u=!0;return u},AL=(t,e,n)=>{const o=e.x-t.x,i=e.y-t.y,r=n.x-e.x,s=n.y-e.y;return Math.abs(o*s-i*r)<=u_},OL=(t,e)=>{if(t.z!==e.z)return!1;const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=t.x-e.start.x,r=t.y-e.start.y;return Math.abs(n*r-o*i)<=u_},kL=(t,e)=>{const n=((t,e)=>{const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.max(u_,.12*(t.traceThickness??.1)),r=Math.abs(o)<=i,s=Math.abs(n)<=i;let a=e.startIndex,c=e.endIndex;if(r||s){const n=r?(e.start.y+e.end.y)/2:(e.start.x+e.end.x)/2;for(;a>0;){const o=t.route[a-1];if(!o||o.z!==e.z||Math.abs((r?o.y:o.x)-n)>i)break;a-=1}for(;c<t.route.length-1;){const o=t.route[c+1];if(!o||o.z!==e.z||Math.abs((r?o.y:o.x)-n)>i)break;c+=1}return Array.from({length:c-a+1},(t,e)=>a+e)}for(;a>0;){const n=t.route[a-1],o=t.route[a],i=t.route[a+1];if(!(n&&o&&i&&n.z===e.z&&OL(n,e)&&AL(n,o,i)))break;a-=1}for(;c<t.route.length-1;){const n=t.route[c-1],o=t.route[c],i=t.route[c+1];if(!(n&&o&&i&&i.z===e.z&&OL(i,e)&&AL(n,o,i)))break;c+=1}return Array.from({length:c-a+1},(t,e)=>a+e)})(t,e);if(n.length<=2)return;const o=[];for(const e of n){const n=dL(t,e);if(!n)return;o.push(...n)}return[...new Set(o)]},LL=(t,e)=>e>0&&e<t.route.length-1&&!((t,e)=>{const n=t.route[e];if(!n)return!1;const o=t.route[e-1],i=t.route[e+1];return o&&o.z!==n.z&&Dk(o,n)||i&&i.z!==n.z&&Dk(i,n)})(t,e),DL=(t,e,n)=>{const o=t.route[e.startIndex],i=t.route[e.endIndex];return!(!o||!i)&&(o.z===e.z&&i.z===e.z&&(!!((t,e)=>Jk(t).maxX>=e.minX-u_&&Jk(t).minX<=e.maxX+u_&&Jk(t).maxY>=e.minY-u_&&Jk(t).minY<=e.maxY+u_)(e,n)&&(LL(t,e.startIndex)||LL(t,e.endIndex))))},zL=(t,e,n,o,i,r,s)=>{const a=t[e.routeIndex];if(!a)return!1;const c=((t,e,n,o)=>{const i=fk(Kk(n),o);let r=e.startIndex,s=e.startIndex;for(;r>0;){const n={...e,startIndex:r-1,endIndex:r,start:t.route[r-1],end:t.route[r]};if(!t.route[r-1]||!DL(t,n,i))break;r-=1}for(;s<t.route.length-2;){const n={...e,startIndex:s+1,endIndex:s+2,start:t.route[s+1],end:t.route[s+2]};if(!t.route[s+2]||!DL(t,n,i))break;s+=1}const a=[];for(let e=r;e<=s+1;e+=1)LL(t,e)&&a.push(e);return[...new Set(a)]})(a,e,n,o);return!(c.length<=2)&&wL(a,c,i,r,s,e.radius)},FL=(t,e)=>{const n=nL(e,t),o=n.x-e.x,i=n.y-e.y,r=Math.hypot(o,i),s=t.end.x-t.start.x,a=t.end.y-t.start.y,c=Math.hypot(s,a),l=t.routeIndex%2==0?1:-1;return{projection:n,direction:r>h_?{x:o/r,y:i/r}:c>h_?{x:-a/c*l,y:s/c*l}:{x:1,y:0}}},BL=(t,e,n,o,i)=>{const r=t[e.routeIndex];if(!r)return!1;const s=IL(i,e,n,o,e.radius);if(Math.abs(s.x)<=h_&&Math.abs(s.y)<=h_)return!1;const a={x:e.x+s.x,y:e.y+s.y},c=_L(i,e),l=_L(i,a);if(l<e.radius-u_)return!1;const d=xL(i,e.radius);if(vL(c,l,d))return!1;e.x+=s.x,e.y+=s.y,gk(e,i.bounds);for(const t of e.pointIndexes){const n=r.route[t];n&&(n.x=e.x,n.y=e.y)}return!0},jL=(t,e)=>{const n=Gk(t),o=n.find(t=>t.routeIndex===e.routeIndex&&t.pointIndexes.some(t=>e.pointIndexes.includes(t)));return o?n.filter(t=>t.rootConnectionName===o.rootConnectionName&&Math.hypot(t.x-o.x,t.y-o.y)<=u_):[]},$L=(t,e,n,o,i)=>e.movable&&jL(t,e).length<=1&&BL(t,e,n,o,i),YL=(t,e,n,o,i=1)=>{const{projection:r,direction:s}=FL(e,n),a=p_*i,c=1-r.t,l=r.t,d=ML(t,e.routeIndex,e.startIndex,s.x*a*c,s.y*a*c,o,e.radius),h=ML(t,e.routeIndex,e.endIndex,s.x*a*l,s.y*a*l,o,e.radius);return!(!d&&!h)||((t,e,n,o,i)=>{const r=t[e.routeIndex];if(!r)return!1;const{projection:s,direction:a}=FL(e,n),c=IL(o,s,a.x*p_*i,a.y*p_*i,e.radius);if(Math.abs(c.x)<=h_&&Math.abs(c.y)<=h_)return!1;const l={...r.route[e.startIndex],x:s.x+c.x,y:s.y+c.y};if(gk(l,o.bounds),be(l,e.start,e.end)<=u_)return!1;const d=r.route[e.startIndex],h=r.route[e.endIndex];if(!d||!h)return!1;const u=bL(o,d,h),p=Math.min(_L(o,l),bL(o,d,l),bL(o,l,h));if(p<e.radius-u_)return!1;const m=xL(o,e.radius);return!vL(u,p,m)&&(r.route.splice(e.endIndex,0,l),!0)})(t,e,n,o,i)},XL=(t,e,n,o,i,r=1)=>{const s=e.radius+f_(o)+g_,a=nD(e,n,s);if(!a)return!1;const c=Math.min(.3*Math.abs(r),a.penetration+g_),l=a.direction.x*c,d=a.direction.y*c,h=t[e.routeIndex];if(!h)return!1;const u=!(t=>{for(let e=0;e<t.route.length-1;e+=1){const n=t.route[e],o=t.route[e+1];if(n&&o&&n.z!==o.z&&Dk(n,o))return!0}return!1})(h);if(u&&EL(t,e.routeIndex,l,d,o,e.radius,i))return!0;const p=zL(t,e,n,s,l,d,o)||((t,e,n,o,i)=>{const r=t[e.routeIndex];if(!r)return!1;const s=kL(r,e);return!!s&&wL(r,s,n,o,i,e.radius)})(t,e,l,d,o)||((t,e,n,o,i,r)=>{const s=t[e.routeIndex];if(!s)return!1;const a=NL(i,s,e.startIndex,n,o,r),c=NL(i,s,e.endIndex,n,o,r);if(!a||!c)return!1;const l=[...new Set([...a,...c])],d=PL(i,s,l,n,o,e.radius);if(!d)return!1;let h=!1;for(const t of l){const e=s.route[t];e&&(e.x+=d.x,e.y+=d.y,gk(e,i.bounds),h=!0)}return h})(t,e,l,d,o,i);if(p)return!0;if(!u&&EL(t,e.routeIndex,l,d,o,e.radius,i))return!0;const m=n.width/2,g=n.height/2,f=(Math.abs(a.direction.y)>=Math.abs(a.direction.x)?[{...h.route[e.startIndex],x:n.center.x-m-s,y:n.center.y+a.direction.y*(g+s)},{...h.route[e.startIndex],x:n.center.x+m+s,y:n.center.y+a.direction.y*(g+s)}]:[{...h.route[e.startIndex],x:n.center.x+a.direction.x*(m+s),y:n.center.y-g-s},{...h.route[e.startIndex],x:n.center.x+a.direction.x*(m+s),y:n.center.y+g+s}]).map(t=>{const{t:n}=nL(t,e),i={x:e.start.x+(e.end.x-e.start.x)*n,y:e.start.y+(e.end.y-e.start.y)*n},r=IL(o,i,t.x-i.x,t.y-i.y,e.radius);return t.x=i.x+r.x,t.y=i.y+r.y,gk(t,o.bounds),{point:t,t:n,moved:Math.abs(r.x)>h_||Math.abs(r.y)>h_,awayFromObstacleMotion:r.x*a.direction.x+r.y*a.direction.y}}).sort((t,e)=>t.t-e.t);if(!f.some(({moved:t})=>t))return!1;if(!f.some(({awayFromObstacleMotion:t})=>t>u_))return!1;const y=f.map(({point:t})=>t);if(y.every(t=>be(t,e.start,e.end)<=u_))return!1;if(y.some(t=>!yL(o,t)))return!1;const _=h.route[e.startIndex],b=h.route[e.endIndex],x=y[0],v=y[1];if(!(_&&b&&x&&v))return!1;const S=bL(o,_,b),I=Math.min(_L(o,x),_L(o,v),bL(o,_,x),bL(o,x,v),bL(o,v,b));if(I<e.radius-u_)return!1;const C=xL(o,e.radius);return!vL(S,I,C)&&(h.route.splice(e.endIndex,0,...y),!0)},VL=(t,e,n)=>{let o;for(const i of t){if(void 0!==n&&i.routeIndex!==n)continue;const t=nL(e,i),r=Math.hypot(t.x-e.x,t.y-e.y);(!o||r<o.distance)&&(o={segment:i,distance:r})}return o?.segment},WL=(t,e,n)=>{let o;for(const i of t){if(void 0!==n&&i.routeIndex!==n)continue;const t=Math.hypot(i.x-e.x,i.y-e.y);(!o||t<o.distance)&&(o={via:i,distance:t})}return o?.via},HL=(t,e)=>{const n=t.map(t=>({via:t,distance:Math.hypot(t.x-e.x,t.y-e.y)})).sort((t,e)=>t.distance-e.distance).slice(0,2).map(({via:t})=>t);return 2===n.length?n:void 0},GL=(t,e,n,o)=>{const i=e.x-n.x,r=e.y-n.y,s=Math.hypot(i,r);return $L(t,e,(s>h_?i/s:1)*p_,(s>h_?r/s:0)*p_,o)},UL=(t,e)=>{const n=nL(t.start,e),o=nL(t.end,e),i=nL(e.start,t),r=nL(e.end,t);return[{leftT:0,rightT:n.t,leftPoint:t.start,rightPoint:n},{leftT:1,rightT:o.t,leftPoint:t.end,rightPoint:o},{leftT:i.t,rightT:0,leftPoint:i,rightPoint:e.start},{leftT:r.t,rightT:1,leftPoint:r,rightPoint:e.end}].sort((t,e)=>Math.hypot(t.leftPoint.x-t.rightPoint.x,t.leftPoint.y-t.rightPoint.y)-Math.hypot(e.leftPoint.x-e.rightPoint.x,e.leftPoint.y-e.rightPoint.y))},ZL=(t,e,n,o,i,r)=>{const s=mk(r,0,1),a=1-s,c=s,l=ML(t,e.routeIndex,e.startIndex,n*a,o*a,i,e.radius),d=ML(t,e.routeIndex,e.endIndex,n*c,o*c,i,e.radius);return l||d},qL=(t,e,n,o,i,r=.035,s=!1)=>{if(!s&&uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const a=e.radius+n.radius+.2+g_,c=e.x-n.x,l=e.y-n.y,d=Math.hypot(c,l),h=a-d;if(h<=0)return!1;const u=1.618*(97*e.routeIndex+13*n.routeIndex),p=d>h_?c/d:Math.cos(u),m=d>h_?l/d:Math.sin(u),g=Number(e.movable)+Number(n.movable);if(0===g)return!1;const f=Math.min(r,h/g),y=$L(t,e,p*f,m*f,o),_=$L(t,n,-p*f,-m*f,o);return y||_},JL=(t,e,n,o,i)=>{if(!uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const[r,s]=e.canCanonicalize?n.canCanonicalize&&e.routeIndex<=n.routeIndex?[e,n]:[n,e]:[e,n];return((t,e,n,o)=>{if(!n.canCanonicalize)return!1;const i=e.x-n.x,r=e.y-n.y;if(!n.movable&&Math.hypot(i,r)>n.radius+u_)return!1;const s=t[n.routeIndex];if(!s)return!1;const a={x:n.x,y:n.y},c=n.pointIndexes.map(t=>{const e=s.route[t];return e?{pointIndex:t,x:e.x,y:e.y}:void 0});if(BL(t,n,i,r,o)&&Dk(n,e))return!0;n.x=a.x,n.y=a.y;for(const t of c){if(!t)continue;const e=s.route[t.pointIndex];e&&(e.x=t.x,e.y=t.y)}return!1})(t,r,s,o)},KL=(t,e,n,o,i,r=.035,s=2,a=!1)=>{if(uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const c=nL(e,n),l=e.x-c.x,d=e.y-c.y,h=Math.hypot(l,d),u=e.radius+n.radius+(rk.traceClearance??.1)+g_-h;if(u<=0)return!1;const p=n.end.x-n.start.x,m=n.end.y-n.start.y,g=Math.hypot(p,m),f=e.routeIndex%2==0?1:-1,y=h>h_?l/h:g>h_?-m/g*f:1,_=h>h_?d/h:g>h_?p/g*f:0,b=Math.min(r,u/s),x=a?((t,e,n,o,i)=>{const r=jL(t,e);if(0===r.length||r.some(e=>!e.movable||void 0===t[e.routeIndex]))return!1;const s=r.reduce((t,e)=>e.radius>t.radius?e:t);if(!BL(t,s,n,o,i))return!1;for(const e of r){if(e===s)continue;e.x=s.x,e.y=s.y;const n=t[e.routeIndex];for(const t of e.pointIndexes){const e=n.route[t];e&&(e.x=s.x,e.y=s.y)}}return!0})(t,e,y*b,_*b,o):$L(t,e,y*b,_*b,o),v=ZL(t,n,-y*b,-_*b,o,c.t);return x||v},QL=(t,e,n,o,i)=>{if(e.z!==n.z||uk(e.rootConnectionName,n.rootConnectionName,i))return!1;const[r]=UL(e,n);if(!r)return!1;const s=r.leftPoint.x-r.rightPoint.x,a=r.leftPoint.y-r.rightPoint.y,c=Math.hypot(s,a),l=e.radius+n.radius+(rk.traceClearance??.1)+g_-c;if(l<=0)return!1;const d=e.end.x-e.start.x,h=e.end.y-e.start.y,u=Math.hypot(d,h),p=(e.routeIndex+n.routeIndex)%2==0?1:-1,m=c>h_?s/c:u>h_?-h/u*p:1,g=c>h_?a/c:u>h_?d/u*p:0,f=Math.min(m_,l/2),y=ZL(t,e,m*f,g*f,o,r.leftT),_=ZL(t,n,-m*f,-g*f,o,r.rightT);return y||_},tD=(t,e,n)=>Qk(t,n).includes(e.z),eD=(t,e,n,o,i)=>{const r=e[n];if(!r)return;const s=Uk(r,n);if(0===s.length)return;const a=dk(r),c=VL(s,o);if(!c)return;const l=sL(t,o,.6,e=>!pk(a,e,i)&&tD(e,c,t.layerCount));if(l)return{obstacle:l,segment:c};const d=sL(t,o,.6,e=>!pk(a,e,i)&&s.some(n=>tD(e,n,t.layerCount)));if(!d)return;const h=VL(s.filter(e=>tD(d,e,t.layerCount)),o);return h?{obstacle:d,segment:h}:void 0},nD=(t,e,n)=>{const o=e.width/2,i=e.height/2,r=[{x:e.center.x-o,y:e.center.y-i},{x:e.center.x+o,y:e.center.y-i},{x:e.center.x+o,y:e.center.y+i},{x:e.center.x-o,y:e.center.y+i}],s=[e.center,...r].map(e=>nL(e,t)),a=[{point:t.start,t:0},{point:t.end,t:1},{point:{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2},t:.5},...s.map(t=>({point:{x:t.x,y:t.y},t:t.t}))];let c;const l=Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y);for(const o of a){const i=aL(o.point,e,n);if(!i)continue;const r=l>h_?Math.abs(((t.end.x-t.start.x)*i.direction.y-(t.end.y-t.start.y)*i.direction.x)/l):0;(!c||i.penetration>c.penetration+h_||Math.abs(i.penetration-c.penetration)<=h_&&r>c.normality)&&(c={...i,normality:r,t:o.t})}return c},oD=(t,e,n,o=!1)=>{let i=!1;const r=Gk(e),s=Zk(e),a=tL(t,r,s),c=Math.max(1,2*a),l=bk(r,qk,c),d=bk(s,Jk,c);for(let s=0;s<r.length;s+=1){const d=r[s];if(!d)continue;const h=xk(l,fk(qk(d),a),c);for(const a of h){if(a<=s)continue;const c=r[a];c&&(i=qL(e,d,c,t,n,m_,o)||i)}}for(let o=0;o<r.length;o+=1){const l=r[o];if(!l)continue;const h=xk(d,fk(qk(l),a),c);for(const o of h){const r=s[o];r&&(i=KL(e,l,r,t,n)||i)}}for(let o=0;o<s.length;o+=1){const r=s[o];if(!r)continue;const l=xk(d,fk(Jk(r),a),c);for(const a of l){if(a<=o)continue;const c=s[a];c&&(i=QL(e,r,c,t,n)||i)}}return((t,e,n,o,i,r,s,a)=>{let c=!1;const l=t.minTraceWidth/2+f_(t)+g_,d=(t.minViaDiameter??.3)/2+y_(t)+g_;for(const h of t.obstacles){if(h.isCopperPour)continue;const u=Kk(h),p=xk(i,fk(u,d),s);for(const o of p){const i=n[o];if(!i)continue;if(pk(i.rootConnectionName,h,a))continue;const r=aL(i,h,d);if(!r)continue;const s=Math.min(m_,r.penetration);c=$L(e,i,r.direction.x*s,r.direction.y*s,t)||c}const m=xk(r,fk(u,l),s);for(const n of m){const i=o[n];if(!i)continue;if(pk(i.rootConnectionName,h,a)||!tD(h,i,t.layerCount))continue;const r=nD(i,h,l);if(!r)continue;const s=Math.min(m_,r.penetration);c=ZL(e,i,r.direction.x*s,r.direction.y*s,t,r.t)||c}}return c})(t,e,r,s,l,d,c,n)||i},iD=(t,e,n,o=1,i,r=!1,s=!0)=>{const a=kk(e),c=Math.max(2,Math.round(12*Math.max(1,n)*o));let l=!1;for(let e=0;e<c;e+=1){if(!oD(t,a,i,r))break;l=!0}return l&&s&&((t,e,n)=>{let o=!1;const i=Gk(e),r=Zk(e),s=tL(t,i,r),a=Math.max(1,2*s),c=bk(r,Jk,a);for(const l of i){const i=xk(c,fk(qk(l),s),a);for(const s of i){const i=r[s];i&&(o=KL(e,l,i,t,n,m_,1.75)||o)}}})(t,a,i),l?aD(a):e},rD=t=>{const e=[];for(let n=0;n<t.route.length-1;n+=1){const o=t.route[n],i=t.route[n+1];if(!o||!i)continue;if("through_obstacle"===o.toNextSegmentType)continue;if(o.z===i.z||!Dk(o,i))continue;const r={x:o.x,y:o.y},s=e.at(-1);s&&Dk(s,r)||e.push(r)}return e},sD=t=>({...t,vias:rD(t)}),aD=t=>t.map(sD),cD=(t,e)=>{const n=new Set(e);return t.map((t,e)=>n.has(e)?sD(t):t)},lD=t=>{const e=t.pcb_trace_id;if("string"!=typeof e)return;const n=e.match(/^trace_(\d+)/);return n?Number.parseInt(n[1],10):void 0},dD=t=>{const e=t.center??t.pcb_center;if(!e||"object"!=typeof e)return;const n=e;return"number"==typeof n.x&&"number"==typeof n.y?{x:n.x,y:n.y}:void 0},hD=(t,e=!0)=>t.errors.filter(t=>(t=>"pcb_via_clearance_error"===Fk(t)||Array.isArray(t.pcb_via_ids))(t)&&(e||!uD(t))).length,uD=t=>"pcb_pad_pad_clearance_error"===Fk(t)&&Array.isArray(t.pcb_via_ids)&&1===t.pcb_via_ids.length,pD=t=>{const e=Object.entries(t).filter(([t,e])=>"source_trace_id"!==t&&(t.endsWith("_id")||t.endsWith("_ids"))&&void 0!==e&&""!==e).sort(([t],[e])=>t.localeCompare(e)),n="string"==typeof t.message?t.message.replace(/-?\d+\.\d+/g,"#"):"";return JSON.stringify([Fk(t),e,n])},mD=t=>Math.max(t.errors.filter(t=>!uD(t)).length,t.count-t.errors.filter(uD).length),gD=t=>{const e=mD(t);return e>0?e:t.count},fD=t=>{if(0===mD(t))return t.issueScore;const e=t.errors.filter(t=>!uD(t));return t.errors.some(uD)?Xk(e):t.legacyIssueScore??Xk(e)},yD=(t,e)=>{const n=mD(t),o=mD(e);return n!==o?n<o:!(n>0)&&t.count<e.count},_D=t=>{const e=t.filter(t=>!uD(t));return e.length>0?e:t},bD=(t,e)=>{const n=t.pcb_trace_id;return"string"==typeof n?e.get(n)??lD(t):lD(t)},xD=(t,e,n,o,i)=>{const r=n.pcb_port_id;if(!r)return!1;const s=(i??e.viaDiameter)/2;return t.obstacles.some(i=>{const a=Qk(i,t.layerCount);return!(1!==a.length||a[0]!==n.z||!i.connectedTo.includes(r)||n.x-s<i.center.x-i.width/2-h_||n.x+s>i.center.x+i.width/2+h_||n.y-s<i.center.y-i.height/2-h_||n.y+s>i.center.y+i.height/2+h_)&&(pk(dk(e),i,o)||pk(e.connectionName,i,o))})},vD=[0,1,-1,2,-2,3,-3,4],SD=vD.flatMap(t=>vD.map(e=>[t,e])).sort(([t,e],[n,o])=>Math.abs(t)+Math.abs(e)-Math.abs(n)-Math.abs(o)),ID=SD.length,CD=(t,e,n)=>t.x-e>=n.minX-h_&&t.x+e<=n.maxX+h_&&t.y-e>=n.minY-h_&&t.y+e<=n.maxY+h_,PD=(t,e)=>{const n=t.at(-1);n&&Dk(n,e)&&n.z===e.z&&n.pcb_port_id===e.pcb_port_id||t.push(e)},MD=(t,e,n,o,i,r,s,a=0,c=!1)=>{const l=Fk(n);if("pcb_pad_trace_clearance_error"!==l&&"pcb_trace_error"!==l)return!1;if(i<0||i>=t.layerCount)return!1;const d=e[o];if(!d||d.route.length<2)return!1;const h=d.route.map(t=>({...t})),u=h[0],p=h.at(-1);if(!u||!p)return!1;const m=dD(n);if(!m)return!1;const g=Bk(n),f=g?eD(t,e,o,m,s):void 0,y=g?f?.segment:VL(Uk(d,o),m);if(!y||y.z===i)return!1;let _=y.startIndex,b=y.endIndex;const x="full"===r?h.length:r;for(let t=0;t<x;t+=1){let t=!1;const e=h[_-1];e?.z===y.z&&(_-=1,t=!0);const n=h[b+1];if(n?.z===y.z&&(b+=1,t=!0),!t)break}const v=0===_&&u.pcb_port_id,S=b===h.length-1&&p.pcb_port_id,I=d.viaDiameter/2,C=SD[a%ID];let P=!1;const M=e=>{const n="start"===e?u:p,o=((t,e,n,o)=>{const i=n.pcb_port_id;if(i)return t.obstacles.find(r=>{const s=Qk(r,t.layerCount);return!(1!==s.length||s[0]!==n.z||!r.connectedTo.includes(i)||!iL(n,r))&&(pk(dk(e),r,o)||pk(e.connectionName,r,o))})})(t,d,n,s),r=((t,e)=>{const n="start"===e?t[0]:t.at(-1);if(!n)return;const o="start"===e?Array.from({length:t.length-1},(t,e)=>e+1):Array.from({length:t.length-1},(e,n)=>t.length-n-2);for(const e of o){const o=t[e];if(!o)continue;const i=o.x-n.x,r=o.y-n.y,s=Math.hypot(i,r);if(!(s<=h_))return{x:i/s,y:r/s}}})(h,e);if(!o||!r)return;const a=((t,e,n,o)=>{let i=0,r=Math.hypot(e.width,e.height)+2*o;const s=o+h_,a=e=>({x:t.x+n.x*e,y:t.y+n.y*e});if(!(oL(a(r),e)<s)){for(;r-i>h_;){const t=(i+r)/2;oL(a(t),e)>=s?r=t:i=t}return a(r)}})(n,o,((t,e)=>{const n=e*Math.PI/4,o=Math.cos(n),i=Math.sin(n);return{x:t.x*o-t.y*i,y:t.x*i+t.y*o}})(r,"start"===e?C[0]:C[1]),I);if(!a||!CD(a,I,t.bounds)||oL(a,o)+h_<I)return;if(!c)return a;const l=((t,e,n,o,i,r)=>{const s=o+(t.minBoardEdgeClearance??0),a={minX:t.bounds.minX+s,maxX:t.bounds.maxX-s,minY:t.bounds.minY+s,maxY:t.bounds.maxY-s};if(a.minX>a.maxX||a.minY>a.maxY)return;const c=Ek(t,e,o,i,r),l=t=>Me(t,a)&&c.every(e=>Ck(t,e)>=e.clearance),d=Ik(n,a);if(l(d))return Me(n,a)?n:d;const h=c.filter(t=>Ck(d,t)<t.clearance),u=new Set(h);for(let t=0;t<h.length;t+=1)for(const e of c)!u.has(e)&&Xe(h[t].bounds,e.bounds)&&(u.add(e),h.push(e));const p=h.flatMap(Nk),m={x:a.minX,y:a.minY},g={x:a.maxX,y:a.minY},f={x:a.maxX,y:a.maxY},y={x:a.minX,y:a.maxY};let _;p.push(Pk(m,g),Pk(g,f),Pk(f,y),Pk(y,m));let b=Number.POSITIVE_INFINITY;const x=t=>{const e=Ye(t,n);e<b&&l(t)&&(_=t,b=e)};for(const t of p)for(const e of wk(n,t))x(e);for(let t=0;t<p.length;t+=1){const e=p[t];if(!(Ye(n,Ik(n,e.bounds))>b))for(let o=t+1;o<p.length;o+=1){const t=p[o];if(Xe(e.bounds,t.bounds)&&!(Ye(n,Ik(n,t.bounds))>b))for(const n of Rk(e,t))x(n)}}return _})(t,d,a,I,[y.z,i],s);return P||=void 0!==l&&l!==a,l},N=v?M("start"):void 0,w=S?M("end"):void 0;if(v&&!N||S&&!w||c&&!P)return!1;const T=[];for(let t=0;t<_;t+=1)PD(T,h[t]);const R=h[_],E=_>0&&Dk(h[_-1],R),A=h[b],O=b<h.length-1&&Dk(h[b+1],A);v?(PD(T,u),PD(T,{...u,...N,pcb_port_id:void 0}),PD(T,{...u,...N,z:i,pcb_port_id:void 0})):(E||PD(T,{...R,pcb_port_id:void 0}),PD(T,{...R,z:i,pcb_port_id:void 0}));const k=S?b-1:b;for(let t=_+1;t<=k;t+=1)PD(T,{...h[t],z:i,pcb_port_id:void 0});S?(PD(T,{...p,...w,z:i,pcb_port_id:void 0}),PD(T,{...p,...w,pcb_port_id:void 0}),PD(T,p)):O||PD(T,{...A,pcb_port_id:void 0});for(let t=b+1;t<h.length;t+=1)PD(T,h[t]);for(let t=1;t<T.length-1;t+=1)T[t].pcb_port_id=void 0;const L=t.minBoardEdgeClearance??.2,D=Uk(d,o),z=Gk([d]);for(let e=1;e<T.length;e+=1){const n=T[e-1],o=T[e];if(n.z===o.z&&!D.some(t=>pL(n,t.start,t.end)&&pL(o,t.start,t.end))&&bL(t,n,o)<d.traceThickness/2+L)return!1;if(n.z!==o.z&&"through_obstacle"!==n.toNextSegmentType&&!z.some(t=>Dk(t,o)&&t.radius>=I)&&_L(t,o)<I+L)return!1}return d.route=T,!0},ND=(t,e,n,o,i,r,s)=>{const a=Fk(n);if("pcb_pad_trace_clearance_error"!==a&&"pcb_trace_error"!==a)return!1;if(i<0||i>=t.layerCount)return!1;const c=bD(n,o);if(void 0===c)return!1;const l=e[c];if(!l||l.route.length<2)return!1;const d=l.route[0],h=l.route.at(-1);if(!d||!h||d.z!==h.z||i===d.z)return!1;if(l.route.some(t=>t.z!==d.z))return!1;if(!d.pcb_port_id||!h.pcb_port_id)return!1;if(!xD(t,l,d,r,s)||!xD(t,l,h,r,s))return!1;const u=l.route.map(t=>({...t}));return l.route=[u[0],{...u[0],z:i,pcb_port_id:void 0},...u.slice(1,-1).map(t=>({...t,z:i})),{...u.at(-1),z:i,pcb_port_id:void 0},u.at(-1)],!0},wD=(t,e,n,o,i,r,s)=>{if("pcb_pad_trace_clearance_error"!==Fk(n))return!1;const a=bD(n,o);if(void 0===a)return!1;const c=e[a];if(!c||c.route.length<4)return!1;const l=c.route.map(t=>({...t}));if("start"===i){const e=l[0];if(!xD(t,c,e,r,s))return!1;let n=-1;for(let t=1;t<l.length;t+=1)if(l[t].z!==e.z){n=t;break}if(n<=0)return!1;const o=n-1;if(!Dk(l[o],l[n]))return!1;let i=n;for(;i+1<l.length&&Dk(l[n],l[i+1]);)i+=1;const a=l[i].z,d=l.slice(o,i+1).map(t=>t.z);return c.route=[e,...d.slice(1).map(t=>({...e,z:t,pcb_port_id:void 0})),...l.slice(1,o+1).map(t=>({...t,z:a})),...l.slice(i+1)],!0}const d=l.at(-1);if(!xD(t,c,d,r,s))return!1;let h=-1;for(let t=l.length-2;t>=0;t-=1)if(l[t].z!==d.z){h=t;break}if(h<0||h>=l.length-1)return!1;const u=h+1;if(!Dk(l[h],l[u]))return!1;let p=h;for(;p-1>=0&&Dk(l[h],l[p-1]);)p-=1;const m=l[p].z,g=l.slice(p,u+1).map(t=>t.z);return c.route=[...l.slice(0,p+1),...l.slice(u+1,-1).map(t=>({...t,z:m})),{...d,z:m,pcb_port_id:void 0},...g.slice(1,-1).map(t=>({...d,z:t,pcb_port_id:void 0})),d],!0},TD=(t,e)=>{const n=t.pcb_trace_id;if("string"!=typeof n)return;if(Array.isArray(t.pcb_via_ids)&&t.pcb_via_ids.length>0)return;const o=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=>"string"==typeof t):[],i=t.pcb_trace_error_id,r=`overlap_${n}_`,s="string"==typeof i&&i.startsWith(r)?i.slice(r.length):void 0,a=[n,...o,...s?[s]:[]],c=[...new Set(a.map(t=>e.get(t)).filter(t=>void 0!==t))];return c.length>=2?[c[0],c[1]]:void 0},RD=(t,e,n,o,i)=>{if("pcb_trace_error"!==Fk(n))return;const r=TD(n,o);if(!r)return;const s=n.worst_contact_center??n.center;if(!s||"object"!=typeof s)return;const a=s;if("number"!=typeof a.x||"number"!=typeof a.y)return;const c={x:a.x,y:a.y},l=Zk(e),d=VL(l,c,r[0]),h=VL(l,c,r[1]);if(!d||!h||d.z!==h.z)return;const[u]=UL(d,h);if(!u)return;const p=u.leftPoint.x-u.rightPoint.x,m=u.leftPoint.y-u.rightPoint.y,g=Math.hypot(p,m),f=Number(n.minimum_clearance),y=Number.isFinite(f)?f:rk.traceClearance??.1,_=d.radius+h.radius+y-g;if(_<=h_)return;const b=0===i?d:h,x=0===i?u.leftT:u.rightT,v=(1-x)**2+x**2;if(v<=h_)return;const S=_/v,I=0===i?u.leftPoint:u.rightPoint,C=0===i?u.rightPoint:u.leftPoint,P=0===i?1:-1,M=b.end.x-b.start.x,N=b.end.y-b.start.y,w=Math.hypot(M,N),T=(b.routeIndex+(0===i?h.routeIndex:d.routeIndex))%2==0?1:-1,R=g>h_?(I.x-C.x)/g:w>h_?-N/w*T*P:P,E=g>h_?(I.y-C.y)/g:w>h_?M/w*T*P:0;return ZL(e,b,R*S,E*S,t,x)?{movedRouteIndex:b.routeIndex}:void 0},ED=t=>{const{srj:e,via:n,segment:o,segments:i,initialTarget:r,requiredTraceDistance:s,requiredObstacleDistance:a,connMap:c}=t,l=Math.min(...n.zLayers),d=Math.max(...n.zLayers),h=e.obstacles.filter(t=>!t.isCopperPour&&!pk(n.rootConnectionName,t,c)&&Qk(t,e.layerCount).some(t=>t>=l&&t<=d)),u=h.filter(t=>Boolean(aL(r,t,a))),p=[r,...Ak(n,i,s-n.radius-o.radius,c),...u.flatMap(t=>(t=>{const{point:e,obstacle:n,requiredDistance:o}=t,i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=n.center.y-n.height/2,a=n.center.y+n.height/2,c=Math.max(i-e.x,e.x-r,0),l=Math.max(s-e.y,e.y-a,0),d=[];if(c<o){const t=Math.sqrt(o*o-c*c);d.push({x:e.x,y:s-t-h_},{x:e.x,y:a+t+h_})}if(l<o){const t=Math.sqrt(o*o-l*l);d.push({x:i-t-h_,y:e.y},{x:r+t+h_,y:e.y})}return d})({point:r,obstacle:t,requiredDistance:a}))];return p.filter(t=>{if(!CD(t,n.radius,e.bounds))return!1;const r=nL(t,o);return!(Math.hypot(t.x-r.x,t.y-r.y)<s-h_)&&(!i.some(e=>e.z>=l&&e.z<=d&&!uk(n.rootConnectionName,e.rootConnectionName,c)&&be(t,e.start,e.end)<s+e.radius-o.radius-h_)&&h.every(e=>oL(t,e)>=a-h_))}).sort((t,e)=>Math.hypot(t.x-n.x,t.y-n.y)-Math.hypot(e.x-n.x,e.y-n.y))[0]},AD=(t,e,n,o,i,r)=>{if("pcb_trace_error"!==Fk(n))return!1;const s="string"==typeof n.pcb_trace_error_id?n.pcb_trace_error_id.toLowerCase():"",a="string"==typeof n.message?n.message.toLowerCase():"";if(!("string"==typeof n.pcb_via_id||Array.isArray(n.pcb_via_ids)||s.includes("_via_")||a.includes("via")))return!1;if(bD(n,o)!==i)return!1;if(TD(n,o))return!1;const c=n.worst_contact_center??n.center;if(!c||"object"!=typeof c)return!1;const l=c;if("number"!=typeof l.x||"number"!=typeof l.y)return!1;const d={x:l.x,y:l.y},h=Zk(e),u=VL(h,d,i),p=Array.isArray(n.pcb_trace_ids)?n.pcb_trace_ids.filter(t=>"string"==typeof t&&t!==n.pcb_trace_id):[],m=p.map(t=>o.get(t)).filter(t=>void 0!==t),g=Gk(e),f=WL(p.length>0?g.filter(t=>m.includes(t.routeIndex)):g,d);if(!u||!f||!f.movable||uk(f.rootConnectionName,u.rootConnectionName,r))return!1;const y=nL(f,u),_=f.x-y.x,b=f.y-y.y,x=Math.hypot(_,b),v=Number(n.minimum_clearance),S=Number.isFinite(v)?v:rk.traceClearance??.1,I=f.radius+u.radius+S-x;if(I<=h_)return!1;const C=u.end.x-u.start.x,P=u.end.y-u.start.y,M=Math.hypot(C,P),N=f.routeIndex%2==0?1:-1,w=x>h_?_/x:M>h_?-P/M*N:1,T=x>h_?b/x:M>h_?C/M*N:0,R=f.radius+u.radius+S,E=f.radius+y_(t)+g_,A={x:f.x+w*(I+g_),y:f.y+T*(I+g_)},O=ED({srj:t,via:f,segment:u,segments:h,initialTarget:A,requiredTraceDistance:R,requiredObstacleDistance:E,connMap:r});return!!O&&$L(e,f,O.x-f.x,O.y-f.y,t)},OD=(t,e,n)=>{if("pcb_trace_error"!==Fk(e))return;const o=dD(e),i=t[n];if(!o||!i)return;const r=VL(Uk(i,n),o);return r?{center:o,route:i,segment:r}:void 0},kD=(t,e,n,o)=>{const i=OD(t,e,n);if(!i)return;const{route:r,segment:s}=i,a=Math.max(0,s.startIndex-o),c=Math.min(r.route.length-1,s.endIndex+o),l=r.route.slice(a,c+1),d=l[0],h=l.at(-1);return d&&h&&!l.some(t=>t.z!==d.z)&&d.z===h.z?{route:r,spanStartIndex:a,spanEndIndex:c,start:d,end:h}:void 0},LD=(t,e,n,o,i,r,s=0,a,c)=>{if(r<0||r>=t.layerCount)return!1;const l=TD(n,o);if(!l)return!1;const d=l[i],h=OD(e,n,d);if(!h||h.segment.z===r)return!1;const{route:u,segment:p}=h;let m=p.startIndex,g=p.endIndex;for(let t=0;t<s;t+=1){const t=u.route[m-1];t?.z===p.z&&(m-=1);const e=u.route[g+1];e?.z===p.z&&(g+=1)}if(0===m&&u.route[0]?.pcb_port_id&&!xD(t,u,u.route[0],a,c)||g===u.route.length-1&&u.route.at(-1)?.pcb_port_id&&!xD(t,u,u.route.at(-1),a,c))return!1;const f=u.route[m],y=u.route[g];if(!f||!y||f.z!==y.z)return!1;const _=u.route.slice(m,g+1).map(t=>({...t,z:r,pcb_port_id:void 0}));return u.route.splice(m,g-m+1,{...f},..._,{...y}),!0},DD=(t,e,n,o,i,r)=>{if(o<=0||i<=0)return!1;const s=OD(t,e,n);if(!s)return!1;const{center:a,route:c,segment:l}=s,d=l.end.x-l.start.x,h=l.end.y-l.start.y,u=Math.hypot(d,h);if(u<=h_)return!1;const p=nL(a,l),m=mk(p.t-o/u,.02,.98),g=mk(p.t+o/u,.02,.98);if(m>=g)return!1;const f=t=>({x:l.start.x+d*t,y:l.start.y+h*t,z:l.z}),y=f(m),_=f(g),b=-h/u*r,x=d/u*r,v=c.route[l.startIndex],S=c.route[l.endIndex];return c.route.splice(l.startIndex,2,{...v},y,{...y,x:y.x+b*i,y:y.y+x*i},{..._,x:_.x+b*i,y:_.y+x*i},_,{...S}),!0},zD=(t,e,n,o,i,r,s,a=!1)=>{if(!Number.isInteger(i)||i<0||i>=t.layerCount)return!1;const c=dD(n),l=e[o],d=l?.route[0],h=l?.route.at(-1);if(!l||!c||!d||!h||d.z!==h.z||d.z===i||l.jumpers?.length||l.route.some(t=>t.z!==d.z||"through_obstacle"===t.toNextSegmentType))return!1;const u=h.x-d.x,p=h.y-d.y,m=Math.hypot(u,p);if(m<=h_||m>8)return!1;const g=u/m,f=p/m,y=f*r,_=-g*r,b=t=>(t.x-c.x)*g+(t.y-c.y)*f,x=(t,e,n)=>({x:c.x+g*t+y*e,y:c.y+f*t+_*e,z:n}),v=(l.viaDiameter??t.minViaDiameter??.3)+(t.minTraceToPadEdgeClearance??rk.traceClearance??.1),S=(a?1.25:-.75)*v,I=(a?-.75:1.25)*v,C=b(d)+.5*v*s,P=b(h)+v*s,M=x(C,S,d.z),N=x(P,I,d.z),w=x(C,2*v,i),T=x(P,2*v,i),R=[{...d},M,{...M,z:i},w,T,{...N,z:i},N,{...h}],E=t.minBoardEdgeClearance??0,A=(l.viaDiameter??t.minViaDiameter??.3)/2,O=l.traceThickness/2;if([M,N].some(e=>_L(t,e)+u_<A+E))return!1;for(let e=0;e<R.length-1;e+=1){const n=R[e],o=R[e+1];if(n.z===o.z&&bL(t,n,o)+u_<O+E)return!1}return l.route.splice(0,l.route.length,...R),!0},FD=(t,e,n,o,i,r,s)=>{if(!Number.isInteger(i)||i<1||r<=0)return!1;const a=kD(e,n,o,i);if(!a)return!1;const{route:c,spanStartIndex:l,spanEndIndex:d,start:h,end:u}=a,p=u.x-h.x,m=u.y-h.y,g=Math.hypot(p,m);if(g<=h_)return!1;const f=-m/g*s*r,y=p/g*s*r,_={...h,x:h.x+f,y:h.y+y,pcb_port_id:void 0},b={...u,x:u.x+f,y:u.y+y,pcb_port_id:void 0};return!(!hL(_,t.bounds)||!hL(b,t.bounds))&&(c.route.splice(l,d-l+1,{...h},_,b,{...u}),!0)},BD=(t,e,n,o,i,r)=>{if(!Number.isInteger(i)||i<0)return!1;const s=kD(e,n,o,i);if(!s)return!1;const{route:a,spanStartIndex:c,spanEndIndex:l,start:d,end:h}=s;return!(Math.hypot(r.x-d.x,r.y-d.y)<=h_||Math.hypot(r.x-h.x,r.y-h.y)<=h_||!hL(r,t.bounds))&&(a.route.splice(c,l-c+1,{...d},{x:r.x,y:r.y,z:d.z},{...h}),!0)},jD=(t,e,n,o,i,r)=>{if(r){const e=mD(t),n=mD(r);if(e!==n)return e<n}const s=gD(t),a=fD(t);return s<n||s===n&&a<o||s===n&&e<i},$D=(t,e,n,o,i,r,s=!0,a=!1,c=!0,l=!1)=>{let d=!1;const h=Gk(e),u=Zk(e);for(const p of n){const n=dD(p);if(!n)continue;let m=n;const g=p.pcb_via_ids,f="pcb_via_clearance_error"===Fk(p),y=uD(p),_=Array.isArray(g)&&g.length>0,b=!f&&!y&&_&&("string"==typeof p.pcb_trace_id||Array.isArray(p.pcb_trace_ids)),x=l&&b;if(_&&!b){m=cL(t,p,n);const c=bD(p,o),l=g.length>1?HL(h,n):void 0;if(l){const n=a&&"pcb_via_clearance_error"===Fk(p)&&"same_net"===p.pcb_via_pair_net_relation,o=s&&"pcb_via_clearance_error"===Fk(p);d=(n?JL(e,l[0],l[1],t,r):qL(e,l[0],l[1],t,r,.16*Math.abs(i),o))||d}else{const o=WL(h,n,c);o&&(d=GL(e,o,m,t)||d)}continue}const v=p.pcb_trace_id,S=bD(p,o);if(x&&void 0===S)continue;const I=Array.isArray(p.pcb_trace_ids)?p.pcb_trace_ids.filter(t=>"string"==typeof t):[];if(x&&"string"==typeof v&&void 0!==S&&I.includes(v)&&I.some(t=>t!==v&&!o.has(t))){const o=WL(h,n,S);if(o){d=GL(e,o,n,t)||d;continue}}const C=s&&!b?TD(p,o):void 0;if(C){const o=VL(u,n,C[0]),i=VL(u,n,C[1]);if(o&&i&&QL(e,o,i,t,r)){d=!0;continue}}const P=Bk(p),M=P&&void 0!==S?eD(t,e,S,n,r):void 0,N=P?M?.segment:VL(u,n,S);if(N){const o=P?M?.obstacle:sL(t,n);if(P&&!o)continue;m=P?o?.center??n:cL(t,p,n);const s=x?void 0:WL(h,n),a="pcb_via_trace_clearance_error"===Fk(p),l="string"==typeof p.pcb_trace_error_id?p.pcb_trace_error_id.toLowerCase():"",u="string"==typeof p.message?p.message.toLowerCase():"",g=a||"string"==typeof p.pcb_via_id||Array.isArray(p.pcb_via_ids)||l.includes("_via_")||u.includes("via"),f=Array.isArray(p.pcb_port_ids)&&p.pcb_port_ids.length>0;if(s&&!uk(s.rootConnectionName,N.rootConnectionName,r)&&(a||Math.hypot(s.x-n.x,s.y-n.y)<.45)){if(KL(e,s,N,t,r,.3*Math.abs(i),1,c)&&(d=!0,g&&!f))continue}d=(void 0!==o&&(P||!pk(N.rootConnectionName,o,r)&&tD(o,N,t.layerCount))?XL(e,N,o,t,r,i):YL(e,N,m,t,i))||d}const w=x?void 0:WL(h,n);w&&Math.hypot(w.x-n.x,w.y-n.y)<.35&&(d=GL(e,w,m,t)||d)}return d},YD=1e-6,XD=.006,VD=[1,.5,.25,.1,.05,.025],WD=(t,e)=>(e.traceThickness??t.minTraceWidth)/2,HD=t=>t.minTraceToPadEdgeClearance??.1,GD=(t,e)=>e.viaDiameter??t.minViaDiameter??.3,UD=(t,e)=>xe(t,e)<YD,ZD=t=>{const e=[],n=t=>{e.some(e=>UD(e,t))||e.push({x:t.x,y:t.y})};for(const e of t.vias)n(e);for(let e=0;e<t.route.length-1;e+=1){const o=t.route[e],i=t.route[e+1];o&&i&&o.z!==i.z&&(UD(o,i)&&n(o))}return e},qD=t=>xe({x:0,y:0},t)<YD?{x:0,y:0}:Fe({x:0,y:0},t),JD=(t,e)=>{if(t.zLayers&&t.zLayers.length>0)return t.zLayers;const n=Array.from({length:e},(t,e)=>e).filter(n=>t.layers.includes(Vy(n,e)));return n.length>0?n:Array.from({length:e},(t,e)=>e)},KD=(t,e,n)=>uk(dk(t),dk(e),n)||uk(dk(t),e.connectionName,n)||uk(t.connectionName,dk(e),n)||uk(t.connectionName,e.connectionName,n),QD=(t,e,n)=>pk(dk(t),e,n)||pk(t.connectionName,e,n),tz=(t,e,n,o)=>!n.pcb_port_id&&t.obstacles.some(i=>QD(e,i,o)&&JD(i,t.layerCount).includes(n.z)&&((t,e)=>t.x>=e.center.x-e.width/2-YD&&t.x<=e.center.x+e.width/2+YD&&t.y>=e.center.y-e.height/2-YD&&t.y<=e.center.y+e.height/2+YD)(n,i)),ez=(t,e,n,o,i)=>{if(!((t,e)=>t.zLayers.includes(e))(i,n.z))return Number.POSITIVE_INFINITY;const r=WD(t,e);return"pad"===i.kind?Le(n,o,i.obstacle)-(HD(t)+r+XD):be(i.center,n,o)-(HD(t)+r+i.diameter/2+XD)},nz=(t,e,n)=>{const o="pad"===n.kind?n.obstacle.center:n.center,i=ze(o,t,e);let r=qD({x:i.x-o.x,y:i.y-o.y});if(Math.abs(r.x)<YD&&Math.abs(r.y)<YD){const n=e.x-t.x,i=e.y-t.y,s=$e(t,e),a=qD({x:-i,y:n}),c={x:-a.x,y:-a.y};r=xe({x:s.x+a.x,y:s.y+a.y},o)>=xe({x:s.x+c.x,y:s.y+c.y},o)?a:c}return r},oz=(t,e,n,o)=>{if(n<=0||n>=e.route.length-1){const i=e.route[n];return!i||!tz(t,e,i,o)}const i=e.route[n];if(!i||i.insideJumperPad)return!0;const r=e.route[n-1],s=e.route[n+1];return!(!r||r.z===i.z)||(!(!s||s.z===i.z)||e.vias.some(t=>UD(t,i)))},iz=(t,e,n)=>{let o=0;for(let i=0;i<e.route.length-1;i+=1){const r=e.route[i],s=e.route[i+1];if(r&&s&&r.z===s.z&&!UD(r,s))for(const i of n){const n=ez(t,e,r,s,i);if(!(n>=0)&&(o+=n*n,"pad"===i.kind)){if(Le(r,s,i.obstacle)<YD){o+=.01/(be(i.obstacle.center,r,s)+.01)}}}}return o},rz=(t,e,n,o)=>{let i=0;for(let r=0;r<e.route.length-1;r+=1){const s=e.route[r],a=e.route[r+1];if(s&&a&&s.z===a.z&&!UD(s,a))for(const r of n)if(!KD(e,r,o)){for(let n=0;n<r.route.length-1;n+=1){const o=r.route[n],c=r.route[n+1];if(!o||!c||o.z!==s.z||c.z!==s.z||UD(o,c))continue;const l=Oe(s,a,o,c)-WD(t,e)-WD(t,r),d=HD(t)+XD-l;d>0&&(i+=d*d)}for(const n of ZD(r)){const o=be(n,s,a)-WD(t,e)-GD(t,r)/2,c=HD(t)+XD-o;c>0&&(i+=c*c)}}}return i},sz=(t,e,n,o,i)=>{const r=e.route.map(()=>({x:0,y:0}));for(let s=0;s<e.route.length-1;s+=1){const a=e.route[s],c=e.route[s+1];if(a&&c&&a.z===c.z&&!UD(a,c)){for(const o of n){const n=ez(t,e,a,c,o);if(n>=0)continue;const l=nz(a,c,o);if(Math.abs(l.x)<YD&&Math.abs(l.y)<YD)continue;const d=!oz(t,e,s,i),h=!oz(t,e,s+1,i);if(!d&&!h)continue;const u=-n,p=d&&h?.5:d?1:0,m=d&&h?.5:h?1:0;r[s].x+=l.x*u*p,r[s].y+=l.y*u*p,r[s+1].x+=l.x*u*m,r[s+1].y+=l.y*u*m}for(const n of o)if(!KD(e,n,i))for(let o=0;o<n.route.length-1;o+=1){const l=n.route[o],d=n.route[o+1];if(!l||!d||l.z!==a.z||d.z!==a.z||UD(l,d))continue;const h=Oe(a,c,l,d)-WD(t,e)-WD(t,n),u=t.minTraceToPadEdgeClearance+XD-h;if(u<=0)continue;const p=$e(a,c),m=ze(p,l,d);let g=qD({x:p.x-m.x,y:p.y-m.y});if(Math.abs(g.x)<YD&&Math.abs(g.y)<YD){const t=c.x-a.x,e=c.y-a.y;g=qD({x:-e,y:t})}const f=!oz(t,e,s,i),y=!oz(t,e,s+1,i);if(!f&&!y)continue;const _=f&&y?.5:f?1:0,b=f&&y?.5:y?1:0;r[s].x+=g.x*u*_,r[s].y+=g.y*u*_,r[s+1].x+=g.x*u*b,r[s+1].y+=g.y*u*b}}}return r},az=(t,e,n,o,i)=>({...e,route:e.route.map((r,s)=>{if(oz(t,e,s,i))return{...r};const a=((t,e)=>{const n=xe({x:0,y:0},t);if(n<=e||n<YD)return t;const o=e/n;return{x:t.x*o,y:t.y*o}})(n[s]??{x:0,y:0},.5);return{...r,x:r.x+a.x*o,y:r.y+a.y*o}}),vias:e.vias.map(t=>({...t})),jumpers:e.jumpers?[...e.jumpers]:void 0}),cz=(t,e)=>e.route.every(e=>e.x>=t.bounds.minX-YD&&e.x<=t.bounds.maxX+YD&&e.y>=t.bounds.minY-YD&&e.y<=t.bounds.maxY+YD),lz=(t,e,n,o,i)=>{const r=((t,e,n,o)=>{const i=[];for(const e of t.obstacles)e.isCopperPour||QD(n,e,o)||i.push({kind:"pad",obstacle:e,zLayers:JD(e,t.layerCount)});const r=Array.from({length:t.layerCount},(t,e)=>e);for(const s of e)if(s!==n&&!KD(n,s,o))for(const e of ZD(s))i.push({kind:"via",center:{x:e.x,y:e.y},diameter:GD(t,s),zLayers:r,connectionName:s.connectionName,rootConnectionName:s.rootConnectionName});return i})(t,e,n,i),s=e.filter((t,e)=>e!==o&&t!==n);let a=n,c=iz(t,a,r)+rz(t,a,s,i);for(let e=0;e<160&&!(c<=YD);e+=1){const e=sz(t,a,r,s,i);if(e.every(t=>xe(t,{x:0,y:0})<1e-9))break;let n=null,o=c;for(const l of VD){const d=az(t,a,e,l,i),h=iz(t,d,r)+rz(t,d,s,i);if(h<c-1e-6&&cz(t,d)){n=d,o=h;break}}if(!n)break;a=n,c=o}return a},dz=1e-6,hz=[1,.5,.25,.1,.05,.025],uz=(t,e)=>t.some(t=>e.includes(t)),pz=(t,e,n,o)=>(pk(t.rootConnectionName,n,o)||pk(e.connectionName,n,o))&&oL(t,n)<=dz,mz=(t,e,n,o)=>{const i=[],r=e[n.routeIndex];if(!r)return i;for(const e of t.obstacles){if(e.isCopperPour||pz(n,r,e,o))continue;const s=Qk(e,t.layerCount);uz(n.zLayers,s)&&i.push({obstacle:e})}return i},gz=(t,e,n)=>oL(e,n.obstacle)-(e.radius+t.minViaEdgeToPadEdgeClearance+.006),fz=(t,e,n,o)=>Gk(e,t.minViaDiameter).filter(t=>t.routeIndex===n).reduce((n,i)=>n+((t,e,n,o)=>{let i=0;for(const r of mz(t,e,n,o)){const e=gz(t,n,r);!(e>=0)&&(i+=e*e,oL(n,r.obstacle)<dz)&&(i+=.01/(xe(n,r.obstacle.center)+.01))}return i})(t,e,i,o),0),yz=(t,e,n,o)=>{const i=e[n];if(!i)return[];const r=i.route.map(()=>({x:0,y:0})),s=Gk(e,t.minViaDiameter).filter(t=>t.routeIndex===n);for(const n of s)if(n.movable)for(const i of mz(t,e,n,o)){const e=n.radius+t.minViaEdgeToPadEdgeClearance+.006,o=aL(n,i.obstacle,e);if(o)for(const t of n.pointIndexes)r[t].x+=o.direction.x*o.penetration,r[t].y+=o.direction.y*o.penetration}return r},_z=(t,e,n,o)=>{const i=new Set(Gk([e],t.minViaDiameter).flatMap(t=>t.movable?t.pointIndexes:[]));return{...e,route:e.route.map((t,e)=>{if(!i.has(e))return{...t};const r=((t,e)=>{const n=xe({x:0,y:0},t);if(n<=e||n<dz)return t;const o=e/n;return{x:t.x*o,y:t.y*o}})(n[e]??{x:0,y:0},.5);return{...t,x:t.x+r.x*o,y:t.y+r.y*o}}),vias:e.vias.map(t=>({...t})),jumpers:e.jumpers?[...e.jumpers]:void 0}},bz=(t,e)=>e.route.every(e=>e.x>=t.bounds.minX-dz&&e.x<=t.bounds.maxX+dz&&e.y>=t.bounds.minY-dz&&e.y<=t.bounds.maxY+dz),xz=(t,e,n,o,i)=>{let r=n,s=fz(t,e,o,i);for(let n=0;n<160&&!(s<=dz);n+=1){const n=yz(t,e,o,i);if(n.every(t=>xe(t,{x:0,y:0})<1e-9))break;let a=null,c=s;for(const l of hz){const d=_z(t,r,n,l),h=[...e];h[o]=d;const u=fz(t,h,o,i);if(u<s-1e-6&&bz(t,d)){a=d,c=u;break}}if(!a)break;e[o]=a,r=a,s=c}return r},vz=[.2,.4,.8,1.2].flatMap(t=>[.2,.3,.45,.6].flatMap(e=>[-1,1].map(n=>({halfSpan:t,offset:e,directionSign:n})))),Sz=vz.flatMap(t=>[0,1].map(e=>({kind:"segment",routeSide:e,...t}))),Iz=[1,-1].flatMap(t=>[1,-1].flatMap(e=>[!1,!0].flatMap(n=>[0,1].map(o=>({routeSide:o,normalDirectionSign:t,tangentDirectionSign:e,reverseEndpointOffsets:n}))))),Cz=[0,1].map(t=>({kind:"displacementChain",routeSide:t})),Pz=[...Cz,...[-1,1].flatMap(t=>[0,1].map(e=>({kind:"segment",routeSide:e,halfSpan:.4,offset:1.2,directionSign:t}))),...[-1,1].flatMap(t=>[0,1].map(e=>({kind:"span",routeSide:e,spanExpansion:3,offset:1.8,directionSign:t}))),...[{dx:-2.4,dy:-.4},{dx:-2.4,dy:.4},{dx:2.4,dy:-.4},{dx:2.4,dy:.4},{dx:-.4,dy:-2.4},{dx:-.4,dy:2.4},{dx:.4,dy:-2.4},{dx:.4,dy:2.4}].flatMap(t=>[0,1].map(e=>({kind:"waypoint",routeSide:e,spanExpansion:2,...t}))),...[{dx:-.17,dy:0},{dx:.17,dy:0},{dx:0,dy:-.17},{dx:0,dy:.17}].flatMap(t=>[0,1].map(e=>({kind:"waypoint",routeSide:e,spanExpansion:0,...t}))),...Sz],Mz=[0,1,2],Nz=class extends kt{srj;inputHdRoutes;guardedInputHdRoutes;connMap;effort;drcEvaluator;referenceDrcEvaluator;autoroutingDrcEngine;viaHoleDiameter;configuredMaxIterations;enableBroadFallback;enableLargeBoardBroadFallback;enableTargetedErrorSweep;enablePostSolveClearanceRelaxation;enableSafeTraceLayerMoves;enableViaInPadLayerMoves;enableTraceViaOwnerTargeting;outputHdRoutes;initialDrcIssueCount;initialRepairDrcIssueCount;initialLowCountErrorsHaveMovableTraces=!1;broadForceAccepted=!1;targetedForceAccepted=!1;candidateAttempts=0;viaInPadCandidateAttempts=0;viaInPadCandidatesAccepted=0;padTopologyErrorCursor=0;safeTraceLayerCursorByErrorId=new Map;traceLayerCorridorCursorByErrorId=new Map;tracePairDetourCursorByErrorId=new Map;errorCursor=0;stalledIterations=0;bestDrcIssueCountSeen;bestDrcIssueScoreSeen;lastDrcCountImprovementCheckIteration=0;drcCountPlateauChecks=0;largeBoardBroadFallbackMisses=0;outputSnapshot;legacyCleanCheckpoint;viaPadRepairRolledBack=!1;referenceInputDrcIssueCount;referenceCandidateDrcIssueCount;referenceCandidateRolledBack=!1;referenceInputSnapshot;inputSnapshot;constructor(t){if(super(),this.srj=t.srj,this.inputHdRoutes=t.hdRoutes,this.guardedInputHdRoutes=aD(kk(t.hdRoutes)),this.connMap=t.connMap,this.effort=t.effort??1,this.drcEvaluator=t.drcEvaluator,this.referenceDrcEvaluator=t.referenceDrcEvaluator,this.autoroutingDrcEngine=t.autoroutingDrcEngine??(t.drcEvaluator?void 0:new s_(t.srj,{connMap:t.connMap,traceClearance:t.srj.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:t.srj.minTraceToPadEdgeClearance??rk.viaClearance,includeTraceViaOwnerMetadata:t.enableTraceViaOwnerTargeting??!1})),void 0!==t.viaHoleDiameter&&(!Number.isFinite(t.viaHoleDiameter)||t.viaHoleDiameter<=0))throw new Error("viaHoleDiameter must be a positive finite number");this.viaHoleDiameter=t.viaHoleDiameter,this.configuredMaxIterations=t.maxIterations,this.enableBroadFallback=t.enableBroadFallback??!0,this.enableLargeBoardBroadFallback=t.enableLargeBoardBroadFallback??!0,this.enableTargetedErrorSweep=t.enableTargetedErrorSweep??!1,this.enablePostSolveClearanceRelaxation=t.enablePostSolveClearanceRelaxation??!0,this.enableSafeTraceLayerMoves=t.enableSafeTraceLayerMoves??!1,this.enableViaInPadLayerMoves=t.enableViaInPadLayerMoves??!1,this.enableTraceViaOwnerTargeting=t.enableTraceViaOwnerTargeting??!1,this.outputHdRoutes=t.hdRoutes,this.referenceDrcEvaluator&&(this.referenceInputSnapshot=this.getReferenceDrcSnapshot(this.inputHdRoutes)),this.MAX_ITERATIONS=this.configuredMaxIterations??__(this.effort)}getConstructorParams(){return[{srj:this.srj,hdRoutes:this.inputHdRoutes,connMap:this.connMap,effort:this.effort,drcEvaluator:this.drcEvaluator,referenceDrcEvaluator:this.referenceDrcEvaluator,autoroutingDrcEngine:this.autoroutingDrcEngine,viaHoleDiameter:this.viaHoleDiameter,maxIterations:this.configuredMaxIterations,enableBroadFallback:this.enableBroadFallback,enableLargeBoardBroadFallback:this.enableLargeBoardBroadFallback,enableTargetedErrorSweep:this.enableTargetedErrorSweep,enablePostSolveClearanceRelaxation:this.enablePostSolveClearanceRelaxation,enableSafeTraceLayerMoves:this.enableSafeTraceLayerMoves,enableViaInPadLayerMoves:this.enableViaInPadLayerMoves,enableTraceViaOwnerTargeting:this.enableTraceViaOwnerTargeting}]}updateStats(t){this.stats={initialDrcIssueCount:this.initialDrcIssueCount??t.count,finalDrcIssueCount:t.count,globalDrcForceImproveMaxIterations:this.MAX_ITERATIONS,globalDrcForceImproveBroadForceAccepted:this.broadForceAccepted,globalDrcForceImproveTargetedForceAccepted:this.targetedForceAccepted,globalDrcForceImproveCandidateAttempts:this.candidateAttempts,globalDrcForceImproveViaInPadCandidateAttempts:this.viaInPadCandidateAttempts,globalDrcForceImproveViaInPadCandidatesAccepted:this.viaInPadCandidatesAccepted,globalDrcForceImproveStalledIterations:this.stalledIterations,globalDrcForceImproveBestDrcIssueCountSeen:this.bestDrcIssueCountSeen??t.count,globalDrcForceImproveBestDrcIssueScoreSeen:this.bestDrcIssueScoreSeen??t.issueScore,globalDrcForceImproveDrcCountPlateauChecks:this.drcCountPlateauChecks,globalDrcForceImproveLargeBoardBroadFallbackMisses:this.largeBoardBroadFallbackMisses,globalDrcForceImproveViaPadRepairRolledBack:this.viaPadRepairRolledBack,globalDrcForceImproveReferenceInputDrcIssueCount:this.referenceInputDrcIssueCount,globalDrcForceImproveReferenceCandidateDrcIssueCount:this.referenceCandidateDrcIssueCount,globalDrcForceImproveReferenceCandidateRolledBack:this.referenceCandidateRolledBack}}finishAtLegacyCleanCheckpoint(){const t=this.legacyCleanCheckpoint;return!!t&&(this.outputHdRoutes=t.routes,this.outputSnapshot=t.snapshot,this.viaPadRepairRolledBack=!0,this.updateStats(t.snapshot),this.solved=!0,!0)}increaseMaxIterationsForDrcIssueCount(t){void 0===this.configuredMaxIterations?this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,((t,e)=>Math.max(__(e),Math.ceil(t*d_*Math.max(1,e))))(t,this.effort),((t,e)=>t>120&&e>0?192:48)(this.inputHdRoutes.length,t)):this.MAX_ITERATIONS=this.configuredMaxIterations}getSnapshot(t){return(this.initialLowCountErrorsHaveMovableTraces?Hk:Wk)(this.srj,t,this.drcEvaluator,this.connMap,this.autoroutingDrcEngine)}getReferenceDrcSnapshot(t){const e={traces:[],srj:this.srj,routes:t,hdRoutes:t},n=this.referenceDrcEvaluator?.getCachedResult?.(e);if(n){const t=Array.isArray(n)?n:n.errors;return{errors:t,count:t.length}}return Wk(this.srj,t,this.referenceDrcEvaluator,this.connMap,this.autoroutingDrcEngine)}getViaIssueCount(t){return hD(t)}getRepairIssueCount(t){return gD(t)}getRepairIssueScore(t){return fD(t)}acceptSolvedRoutes(t,e){const n=this.enablePostSolveClearanceRelaxation?((t,e,n)=>{if(void 0===t.minTraceToPadEdgeClearance||t.minTraceToPadEdgeClearance<=0)return e;let o=!1;const i=kk(e);for(let e=0;e<4;e+=1)for(let e=0;e<i.length;e+=1){const r=i[e];if(!r)continue;const s=lz(t,i,r,e,n);s!==r&&(i[e]=s,o=!0)}return o?i:e})(this.srj,t,this.connMap):t,o=this.enablePostSolveClearanceRelaxation?((t,e,n)=>{if(void 0===t.minViaEdgeToPadEdgeClearance||t.minViaEdgeToPadEdgeClearance<=0)return e;let o=!1;const i=kk(e);for(let e=0;e<4;e+=1)for(let e=0;e<i.length;e+=1){const r=i[e];if(!r)continue;const s=xz(t,i,r,e,n);s!==r&&(i[e]=s,o=!0)}return o?aD(i):e})(this.srj,n,this.connMap):t,i=o===t?e:this.getSnapshot(o),r=i.count<e.count||i.count===e.count&&i.issueScore<=e.issueScore;let s=r?o:t,a=r?i:e;const c=this.inputSnapshot??this.getSnapshot(this.guardedInputHdRoutes);if(this.referenceDrcEvaluator){const t=this.referenceInputSnapshot,e=this.getReferenceDrcSnapshot(s);this.referenceInputDrcIssueCount=t.count,this.referenceCandidateDrcIssueCount=e.count,e.count>t.count&&(s=this.guardedInputHdRoutes,a=c,this.referenceCandidateRolledBack=!0)}this.outputHdRoutes=s,this.outputSnapshot=a,this.stalledIterations=0,this.updateStats(a),this.solved=!0}updateDrcCountPlateauState(t){const e=this.getRepairIssueCount(t),n=this.getRepairIssueScore(t);this.bestDrcIssueCountSeen??=e,this.bestDrcIssueScoreSeen??=n;const o=this.initialRepairDrcIssueCount??e,i=this.inputHdRoutes.length>120&&o>0;if((o>=20||i)&&this.iterations<192)return(e<this.bestDrcIssueCountSeen||e===this.bestDrcIssueCountSeen&&n<this.bestDrcIssueScoreSeen)&&(this.bestDrcIssueCountSeen=e,this.bestDrcIssueScoreSeen=n),void(i&&this.largeBoardBroadFallbackMisses>=2&&(this.solved=!0));const r=(t=>t>=20?8:t<=2?1:2)(o);if(!(this.iterations-this.lastDrcCountImprovementCheckIteration<r)){if(this.lastDrcCountImprovementCheckIteration=this.iterations,e<this.bestDrcIssueCountSeen||e===this.bestDrcIssueCountSeen&&n<this.bestDrcIssueScoreSeen)return this.bestDrcIssueCountSeen=e,this.bestDrcIssueScoreSeen=n,void(this.drcCountPlateauChecks=0);this.drcCountPlateauChecks+=1,this.drcCountPlateauChecks>=2&&(this.solved=!0)}}_step(){let t=this.outputHdRoutes,e=this.outputSnapshot??this.getSnapshot(t);const n=mD(e);if(this.legacyCleanCheckpoint&&n>0)return void this.finishAtLegacyCleanCheckpoint();if(!this.legacyCleanCheckpoint&&0===n&&e.errors.some(uD)&&(this.legacyCleanCheckpoint={routes:aD(kk(t)),snapshot:e}),void 0===this.initialDrcIssueCount){this.inputSnapshot=e,this.initialDrcIssueCount=e.count,this.initialRepairDrcIssueCount=this.getRepairIssueCount(e);const n=_D(e.errors);this.initialLowCountErrorsHaveMovableTraces=this.initialRepairDrcIssueCount>0&&this.initialRepairDrcIssueCount<=3&&n.every(t=>void 0!==bD(t,e.traceRouteIndexById)),this.initialLowCountErrorsHaveMovableTraces&&(e=this.getSnapshot(t)),this.bestDrcIssueCountSeen=this.getRepairIssueCount(e),this.bestDrcIssueScoreSeen=this.getRepairIssueScore(e),this.increaseMaxIterationsForDrcIssueCount(this.getRepairIssueCount(e))}if(0===e.count)return void this.acceptSolvedRoutes(t,e);let o=this.getRepairIssueCount(e),i=this.getRepairIssueScore(e),r=this.getViaIssueCount(e);const s=e.errors.filter(t=>Boolean(dD(t)));if(0===s.length)return void this.acceptSolvedRoutes(t,e);const a=(c=this.effort,Math.max(1,Math.round(3*Math.max(1,c))));var c;let l=0,d=0,h=!1,u=!1,p=!1;const m=_D(s),g=this.enableTargetedErrorSweep?m.find(t=>"pcb_via_clearance_error"===t.type&&"same_net"===t.pcb_via_pair_net_relation):void 0,f=this.enableTargetedErrorSweep&&(this.iterations-1)%8==0,y=g??(f?m.find(t=>"pcb_via_clearance_error"===t.type):void 0),_=y?[y,...m.filter(t=>t!==y)]:m,b=Math.min(_.length,Math.max(1,Math.ceil(this.effort))),x=y?0:this.errorCursor%_.length,v=this.enableTargetedErrorSweep?((t,e)=>{const n=Math.max(2,Math.round(12*Math.max(1,e)));return t.filter(t=>"pcb_trace_error"===Fk(t)).slice(0,n)})(s,this.effort):[],S=o<=1||this.initialLowCountErrorsHaveMovableTraces,I=!this.initialLowCountErrorsHaveMovableTraces&&o<=8&&this.srj.layerCount>1,C=y?[]:s.filter(t=>"pcb_pad_trace_clearance_error"===t.type||(this.enableSafeTraceLayerMoves||S||I)&&"pcb_trace_error"===t.type),P=C.map((t,e)=>C[(this.padTopologyErrorCursor+e)%C.length]);for(const n of this.enableSafeTraceLayerMoves||this.enableViaInPadLayerMoves?P:[]){const s=!this.enableSafeTraceLayerMoves||d>=a,c=!this.enableViaInPadLayerMoves||l>=a;if(u||s&&c)break;let p;this.padTopologyErrorCursor=(C.indexOf(n)+1)%C.length;const m="string"==typeof n.pcb_trace_error_id?n.pcb_trace_error_id:"string"==typeof n.pcb_trace_id?n.pcb_trace_id:void 0,g=bD(n,e.traceRouteIndexById),f=TD(n,e.traceRouteIndexById);if(this.enableTraceViaOwnerTargeting&&void 0!==g&&Array.isArray(n.pcb_via_ids)&&1===n.pcb_via_ids.length&&l<a){const o=kk(t);if(AD(this.srj,o,n,e.traceRouteIndexById,g,this.connMap)){const t=aD(o),n=this.getSnapshot(t),i=this.getViaIssueCount(n);l+=1,this.candidateAttempts+=1,i<=r&&yD(n,e)&&(p={routes:t,snapshot:n,viaIssueCount:i,usesViaInPad:!1})}}if(this.enableSafeTraceLayerMoves&&void 0!==g){const o=f??[g],i=o.length*this.srj.layerCount*Mz.length,s=o.length*this.srj.layerCount*ID,c=i+s,l=Bk(n),h=l?0:i,u=l?s:0;let y=m?this.safeTraceLayerCursorByErrorId.get(m)??0:0,_=0;for(;d<a&&_<c;){const i=y;y=(y+1)%c,_+=1;const a=i>=h&&i<h+s,l=i-(a?h:u),m=l%o.length,g=Math.floor(l/o.length),f=g%this.srj.layerCount,b=a?"full":Mz[Math.floor(g/this.srj.layerCount)%Mz.length],x=a?Math.floor(g/this.srj.layerCount):0,v=o[m];let S=!1;for(const o of[!1,!0]){const i=Lk(t,[v]);if(!MD(this.srj,i,n,v,f,b,this.connMap,x,o))continue;const s=cD(i,[v]);S=!0,this.candidateAttempts+=1;const a=this.getSnapshot(s),c=this.getViaIssueCount(a),l=p?.snapshot??e;c<=(p?.viaIssueCount??r)&&(yD(a,l)||void 0!==p&&gD(a)===gD(l)&&a.count<l.count)&&(p={routes:s,snapshot:a,viaIssueCount:c,usesViaInPad:!1})}S&&(d+=1)}m&&this.safeTraceLayerCursorByErrorId.set(m,y)}if(this.enableSafeTraceLayerMoves&&I&&m&&f){let o=this.traceLayerCorridorCursorByErrorId.get(m)??0,i=0;for(;l<a&&i<Iz.length;){const s=Iz[o%Iz.length];o+=1,i+=1;const a=f[s.routeSide],c=t[a]?.route[0]?.z;if(void 0===c)continue;const d=(c+1)%this.srj.layerCount,h=Lk(t,[a]);if(!zD(this.srj,h,n,a,d,s.normalDirectionSign,s.tangentDirectionSign,s.reverseEndpointOffsets))continue;const u=cD(h,[a]);l+=1,this.candidateAttempts+=1;const m=this.getSnapshot(u),g=this.getViaIssueCount(m),y=p?.snapshot??e;g<=(p?.viaIssueCount??r)&&yD(m,y)&&(p={routes:u,snapshot:m,viaIssueCount:g,usesViaInPad:!1})}this.traceLayerCorridorCursorByErrorId.set(m,o)}if(this.enableSafeTraceLayerMoves&&m&&(this.initialLowCountErrorsHaveMovableTraces&&(f||void 0!==g)||!this.initialLowCountErrorsHaveMovableTraces&&f)){const s=this.initialLowCountErrorsHaveMovableTraces?Pz:S?[...Cz,...Sz]:Cz,c=f??[g];let d=this.tracePairDetourCursorByErrorId.get(m)??0,u=0;for(;l<a&&u<s.length;){const m=s[d%s.length];d+=1,u+=1;const g=c[m.routeSide];if(void 0===g)continue;const f=this.initialLowCountErrorsHaveMovableTraces&&n.worst_contact_center?{...n,center:n.worst_contact_center,message:n.worst_contact_message??n.message,actual_clearance:n.worst_actual_clearance??n.actual_clearance}:n;if("displacementChain"===m.kind){const n=kk(t),s=RD(this.srj,n,f,e.traceRouteIndexById,m.routeSide);if(!s)continue;h=!0,l+=1,this.candidateAttempts+=1;let c=aD(n),d=this.getSnapshot(c),u=this.getViaIssueCount(d),g=this.getRepairIssueCount(d);if(g>0&&l<a){const t=kk(c);let e=!1;for(const n of d.errors)e=AD(this.srj,t,n,d.traceRouteIndexById,s.movedRouteIndex,this.connMap)||e;if(e){l+=1,this.candidateAttempts+=1;const e=aD(t),n=this.getSnapshot(e),o=this.getViaIssueCount(n);jD(n,o,g,this.getRepairIssueScore(d),u,d)&&(c=e,d=n,u=o,g=this.getRepairIssueCount(d))}}const y=p?this.getRepairIssueCount(p.snapshot):o,_=p?this.getRepairIssueScore(p.snapshot):i,b=p?.viaIssueCount??r;if(u<=b&&jD(d,u,y,_,b,p?.snapshot??e)&&(p={routes:c,snapshot:d,viaIssueCount:u,usesViaInPad:!1}),0===g)break;continue}const y=Lk(t,[g]);if(!("segment"===m.kind?DD(y,f,g,m.halfSpan,m.offset,m.directionSign):"span"===m.kind?FD(this.srj,y,f,g,m.spanExpansion,m.offset,m.directionSign):BD(this.srj,y,f,g,m.spanExpansion,{x:f.center.x+m.dx,y:f.center.y+m.dy})))continue;const _=cD(y,[g]);h=!0,l+=1,this.candidateAttempts+=1;const b=this.getSnapshot(_),x=this.getViaIssueCount(b),v=p?this.getRepairIssueCount(p.snapshot):o,S=p?this.getRepairIssueScore(p.snapshot):i,I=p?.viaIssueCount??r;(this.initialLowCountErrorsHaveMovableTraces?jD(b,x,v,S,I,p?.snapshot??e):x<=I&&yD(b,p?.snapshot??e))&&(p={routes:_,snapshot:b,viaIssueCount:x,usesViaInPad:!1})}this.tracePairDetourCursorByErrorId.set(m,d)}for(const s of this.enableViaInPadLayerMoves?["start","end"]:[]){if(l>=a)break;if(void 0===g)break;const c=Lk(t,[g]);if(!wD(this.srj,c,n,e.traceRouteIndexById,s,this.connMap,this.viaHoleDiameter))continue;const d=cD(c,[g]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const h=this.getSnapshot(d),u=this.getViaIssueCount(h),m=p?this.getRepairIssueCount(p.snapshot):o,f=p?this.getRepairIssueScore(p.snapshot):i;jD(h,u,m,f,p?.viaIssueCount??r,p?.snapshot??e)&&(p={routes:d,snapshot:h,viaIssueCount:u,usesViaInPad:!0})}const y=this.enableViaInPadLayerMoves?this.srj.layerCount:0;for(let s=0;s<y&&!(l>=a)&&void 0!==g;s+=1){const a=Lk(t,[g]);if(!ND(this.srj,a,n,e.traceRouteIndexById,s,this.connMap,this.viaHoleDiameter))continue;const c=cD(a,[g]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const d=this.getSnapshot(c),h=this.getViaIssueCount(d),u=p?this.getRepairIssueCount(p.snapshot):o,m=p?this.getRepairIssueScore(p.snapshot):i;jD(d,h,u,m,p?.viaIssueCount??r,p?.snapshot??e)&&(p={routes:c,snapshot:d,viaIssueCount:h,usesViaInPad:!0})}if(this.enableViaInPadLayerMoves&&S&&f){const s=this.iterations%2==0?[0,1]:[1,0],c=this.iterations%3;for(const d of s)for(let s=0;s<this.srj.layerCount&&!(l>=a);s+=1){const a=f[d],h=Lk(t,[a]);if(!LD(this.srj,h,n,e.traceRouteIndexById,d,s,c,this.connMap,this.viaHoleDiameter))continue;const u=cD(h,[a]);this.viaInPadCandidateAttempts+=1,l+=1,this.candidateAttempts+=1;const m=this.getSnapshot(u),g=this.getViaIssueCount(m),y=p?this.getRepairIssueCount(p.snapshot):o,_=p?this.getRepairIssueScore(p.snapshot):i;jD(m,g,y,_,p?.viaIssueCount??r,p?.snapshot??e)&&(p={routes:u,snapshot:m,viaIssueCount:g,usesViaInPad:!0})}}p&&(t=p.routes,e=p.snapshot,o=this.getRepairIssueCount(e),i=this.getRepairIssueScore(e),r=p.viaIssueCount,this.targetedForceAccepted=!0,p.usesViaInPad&&(this.viaInPadCandidatesAccepted+=1),u=!0)}if(!u&&v.length>=2){const n=kk(t);let s=!1;for(const t of v)s=$D(this.srj,n,[t],e.traceRouteIndexById,1,this.connMap,!0,this.enableTargetedErrorSweep,!1,this.enableTraceViaOwnerTargeting)||s;if(s){const s=aD(n);l+=1,this.candidateAttempts+=1;const a=this.getSnapshot(s),c=this.getViaIssueCount(a);if(jD(a,c,o,i,r,e)&&(t=s,e=a,o=this.getRepairIssueCount(a),i=this.getRepairIssueScore(a),r=c,this.targetedForceAccepted=!0,u=!0,0===a.count))return void this.acceptSolvedRoutes(t,e)}}for(let n=0;n<b&&l<a&&!u;n+=1){const s=(x+n)%_.length,c=_[s];if(!c)continue;this.errorCursor=(s+1)%_.length;const d=1===o;for(const n of b_(this.effort)){if(l>=a)break;const s=kk(t);if(!$D(this.srj,s,[c],e.traceRouteIndexById,n,this.connMap,!0,this.enableTargetedErrorSweep,d,this.enableTraceViaOwnerTargeting))continue;const h=aD(s);l+=1,this.candidateAttempts+=1;const p=this.getSnapshot(h),m=this.getViaIssueCount(p);if(jD(p,m,o,i,r,e)){if(t=h,e=p,o=this.getRepairIssueCount(p),i=this.getRepairIssueScore(p),r=m,this.targetedForceAccepted=!0,u=!0,0===p.count)return void this.acceptSolvedRoutes(t,e);break}}if(u)break}const M=t.length<=120,N=(w=s.length,Math.max(16,Math.min(64,2*w)));var w;const T=this.enableLargeBoardBroadFallback&&this.MAX_ITERATIONS>=192&&!M&&this.stalledIterations>0&&this.stalledIterations%N===0;if(this.enableBroadFallback&&!u&&(M||this.effort>=2&&this.stalledIterations>=2||T)){p=T;for(const n of[1,2]){const s=iD(this.srj,t,this.effort,n,this.connMap,void 0===this.drcEvaluator,!1);if(s===t)continue;const a=this.getSnapshot(s),c=this.getViaIssueCount(a);if(jD(a,c,o,i,r,e)&&(t=s,e=a,o=this.getRepairIssueCount(a),i=this.getRepairIssueScore(a),r=c,this.broadForceAccepted=!0,u=!0,0===a.count))return void this.acceptSolvedRoutes(t,e)}}u?this.largeBoardBroadFallbackMisses=0:p&&(this.largeBoardBroadFallbackMisses+=1),this.outputHdRoutes=t,this.outputSnapshot=e,this.stalledIterations=u?0:this.stalledIterations+1,h||this.updateDrcCountPlateauState(e),this.updateStats(e),(this.solved||0===o)&&this.acceptSolvedRoutes(t,e)}tryFinalAcceptance(){const t=this.outputSnapshot??this.getSnapshot(this.outputHdRoutes);this.legacyCleanCheckpoint&&mD(t)>0&&this.finishAtLegacyCleanCheckpoint()||this.acceptSolvedRoutes(this.outputHdRoutes,t)}getOutput(){return this.outputHdRoutes}visualize(){return super.visualize()}preview(){return this.visualize()}},wz=class extends kt{params;inputHdRoutes;guardedInputHdRoutes;broadMaxIterations;broadPassMultiplier;autoroutingDrcEngine;legacyDrcEvaluator;outputHdRoutes;phase="start";inputSnapshot;baselineSolver;baselineSnapshot;broadInputSnapshot;broadSnapshot;broadSolver;safeTraceLayerInputRoutes;safeTraceLayerInputSnapshot;safeTraceLayerSolver;safeTraceLayerPhaseAccepted=!1;mixedSafeTraceLayerSolver;mixedSafeTraceLayerPhaseAccepted=!1;legacySafeTraceLayerRoutes;legacySafeTraceLayerSnapshot;legacySafeTraceLayerSelectedSolver;viaInPadSolver;portfolioSelectedSolver;selectedSolver;referenceInputDrcIssueCount;referenceCandidateDrcIssueCount;referenceCandidateRolledBack=!1;mixedReferenceInputDrcIssueCount;mixedReferenceCandidateDrcIssueCount;referenceInputSnapshot;constructor(t){if(super(),!Number.isFinite(t.broadPassMultiplier))throw new Error("broadPassMultiplier must be a finite number");if(t.broadPassMultiplier<=0)throw new Error("broadPassMultiplier must be greater than zero");if(!Number.isInteger(t.broadMaxIterations))throw new Error("broadMaxIterations must be an integer");if(t.broadMaxIterations<=0)throw new Error("broadMaxIterations must be greater than zero");if(void 0!==t.viaInPadMaxIterations&&!Number.isInteger(t.viaInPadMaxIterations))throw new Error("viaInPadMaxIterations must be an integer");if(void 0!==t.viaInPadMaxIterations&&t.viaInPadMaxIterations<=0)throw new Error("viaInPadMaxIterations must be greater than zero");this.autoroutingDrcEngine=t.autoroutingDrcEngine??(t.drcEvaluator?void 0:new s_(t.srj,{connMap:t.connMap,traceClearance:t.srj.minTraceToPadEdgeClearance??rk.traceClearance,viaClearance:t.srj.minTraceToPadEdgeClearance??rk.viaClearance,includeTraceViaOwnerMetadata:t.enableTraceViaOwnerTargeting??!1})),this.legacyDrcEvaluator=e=>{const n=t.drcEvaluator?.evaluateLegacy??t.drcEvaluator,o=n?n(e):this.autoroutingDrcEngine.evaluateLegacy(e.traces),i=Array.isArray(o)?o:o.errors,r=Array.isArray(o)?o:o.errorsWithCenters??o.errors;return{errors:i.filter(t=>!uD(t)),errorsWithCenters:r.filter(t=>!uD(t))}},this.params={...t,autoroutingDrcEngine:this.autoroutingDrcEngine},this.inputHdRoutes=t.hdRoutes,this.guardedInputHdRoutes=aD(kk(t.hdRoutes)),this.broadMaxIterations=t.broadMaxIterations,this.broadPassMultiplier=t.broadPassMultiplier,this.outputHdRoutes=t.hdRoutes,this.params.referenceDrcEvaluator&&(this.referenceInputSnapshot=this.getReferenceDrcSnapshot(this.inputHdRoutes))}getConstructorParams(){return[{...this.params,hdRoutes:this.inputHdRoutes}]}stepBranch(t,e){if(this.activeSubSolver=t,t.step(),t.failed)throw new Error(`${e} DRC repair branch failed: ${t.error}`)}getReferenceDrcSnapshot(t){const e={traces:[],srj:this.params.srj,routes:t,hdRoutes:t},n=this.params.referenceDrcEvaluator?.getCachedResult?.(e);if(n){const t=Array.isArray(n)?n:n.errors;return{errors:t,count:t.length}}return Wk(this.params.srj,t,this.params.referenceDrcEvaluator,this.params.connMap,this.autoroutingDrcEngine)}finishWithOutput(t,e,n){let o=t,i=e;if(this.params.referenceDrcEvaluator){const t=this.referenceInputSnapshot,e=this.getReferenceDrcSnapshot(o);this.referenceInputDrcIssueCount=t.count,this.referenceCandidateDrcIssueCount=e.count,(e.count>t.count||e.count===t.count&&((t,e)=>{const n=new Set(e.map(pD));return t.some(t=>!n.has(pD(t)))})(e.errors,t.errors))&&(o=this.guardedInputHdRoutes,i=this.inputSnapshot,this.referenceCandidateRolledBack=!0)}this.outputHdRoutes=o,this.selectedSolver=n,this.activeSubSolver=null,this.phase="done",this.progress=1,this.stats={...this.portfolioSelectedSolver?.stats??{},...n?.stats??{},finalDrcIssueCount:i.count,drcBranchPortfolioInitialDrcIssueCount:this.inputSnapshot?.count??e.count,drcBranchPortfolioBaselineDrcIssueCount:this.baselineSnapshot?.count??e.count,drcBranchPortfolioBroadInitialDrcIssueCount:this.broadInputSnapshot?.count,drcBranchPortfolioBroadFinalDrcIssueCount:this.broadSnapshot?.count,drcBranchPortfolioBroadMaxIterations:this.broadMaxIterations,drcBranchPortfolioBroadBranchAttempted:Boolean(this.broadSolver),drcBranchPortfolioBroadBranchAccepted:void 0!==this.portfolioSelectedSolver&&this.portfolioSelectedSolver===this.broadSolver,drcBranchPortfolioSafeTraceLayerPhaseAttempted:Boolean(this.safeTraceLayerSolver),drcBranchPortfolioSafeTraceLayerPhaseAccepted:this.safeTraceLayerPhaseAccepted,drcBranchPortfolioMixedSafeTraceLayerPhaseAttempted:Boolean(this.mixedSafeTraceLayerSolver),drcBranchPortfolioMixedSafeTraceLayerPhaseAccepted:this.mixedSafeTraceLayerPhaseAccepted,drcBranchPortfolioViaInPadPhaseAttempted:Boolean(this.viaInPadSolver),drcBranchPortfolioViaInPadMaxIterations:this.params.viaInPadMaxIterations,drcBranchPortfolioFinalNonViaPadDrcIssueCount:mD(i),drcBranchPortfolioReferenceInputDrcIssueCount:this.referenceInputDrcIssueCount,drcBranchPortfolioReferenceCandidateDrcIssueCount:this.referenceCandidateDrcIssueCount,drcBranchPortfolioReferenceCandidateRolledBack:this.referenceCandidateRolledBack,drcBranchPortfolioMixedReferenceInputDrcIssueCount:this.mixedReferenceInputDrcIssueCount,drcBranchPortfolioMixedReferenceCandidateDrcIssueCount:this.mixedReferenceCandidateDrcIssueCount},this.solved=!0}startBaselineBranch(){this.baselineSolver=new Nz({...this.params,hdRoutes:this.inputHdRoutes,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.baselineSolver,this.phase="baseline"}startSafeTraceLayerPhase(t,e,n){this.portfolioSelectedSolver=n,this.params.enableSafeTraceLayerMoves?(this.safeTraceLayerInputRoutes=t,this.safeTraceLayerInputSnapshot=e,this.safeTraceLayerSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.safeTraceLayerSolver,this.phase="safeTraceLayer"):this.startViaInPadPhase(t,e,n)}startViaInPadPhase(t,e,n){this.portfolioSelectedSolver=n;const o=this.params.enableViaInPadLayerMoves&&void 0!==this.params.viaInPadDrcEvaluator;e.errors.some(uD)||o?(this.viaInPadSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.params.viaInPadDrcEvaluator??this.params.drcEvaluator,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:this.params.enableViaInPadLayerMoves}),this.activeSubSolver=this.viaInPadSolver,this.phase="viaInPad"):this.finishWithOutput(t,e,n)}startMixedSafeTraceLayerPhase(t,e,n){this.legacySafeTraceLayerRoutes=t,this.legacySafeTraceLayerSnapshot=e,this.legacySafeTraceLayerSelectedSolver=n,this.mixedSafeTraceLayerSolver=new Nz({...this.params,hdRoutes:this.safeTraceLayerInputRoutes,drcEvaluator:this.params.drcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.params.viaInPadMaxIterations??this.params.maxIterations,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.mixedSafeTraceLayerSolver,this.phase="mixedSafeTraceLayer"}startBroadBranch(){const t=iD(this.params.srj,this.inputHdRoutes,this.params.effort??1,this.broadPassMultiplier,this.params.connMap);this.broadInputSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),yD(this.broadInputSnapshot,this.baselineSnapshot)?(this.broadSolver=new Nz({...this.params,hdRoutes:t,drcEvaluator:this.legacyDrcEvaluator,referenceDrcEvaluator:void 0,maxIterations:this.broadMaxIterations,enableSafeTraceLayerMoves:!1,enableViaInPadLayerMoves:!1}),this.activeSubSolver=this.broadSolver,this.phase="broad"):this.startSafeTraceLayerPhase(this.baselineSolver.getOutput(),this.baselineSnapshot,this.baselineSolver)}_step(){if("start"===this.phase)return this.inputSnapshot=Wk(this.params.srj,this.inputHdRoutes,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),0===mD(this.inputSnapshot)?void this.startViaInPadPhase(this.inputHdRoutes,this.inputSnapshot):void this.startBaselineBranch();if("baseline"===this.phase){if(this.stepBranch(this.baselineSolver,"baseline"),!this.baselineSolver.solved)return;const t=this.baselineSolver.getOutput();return this.baselineSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),0===mD(this.baselineSnapshot)?void this.startViaInPadPhase(t,this.baselineSnapshot,this.baselineSolver):void(this.params.enableSafeTraceLayerMoves&&this.baselineSnapshot.count<=3?this.startSafeTraceLayerPhase(t,this.baselineSnapshot,this.baselineSolver):this.startBroadBranch())}if("broad"===this.phase){if(this.stepBranch(this.broadSolver,"broad"),!this.broadSolver.solved)return;const t=this.broadSolver.getOutput();return this.broadSnapshot=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),yD(this.broadSnapshot,this.baselineSnapshot)?void this.startSafeTraceLayerPhase(t,this.broadSnapshot,this.broadSolver):void this.startSafeTraceLayerPhase(this.baselineSolver.getOutput(),this.baselineSnapshot,this.baselineSolver)}if("safeTraceLayer"===this.phase){if(this.stepBranch(this.safeTraceLayerSolver,"safe trace-layer"),!this.safeTraceLayerSolver.solved)return;const t=this.safeTraceLayerSolver.getOutput(),e=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),n=hD(this.safeTraceLayerInputSnapshot,!1),o=hD(e,!1);this.safeTraceLayerPhaseAccepted=o<=n&&jD(e,o,this.safeTraceLayerInputSnapshot.count,this.safeTraceLayerInputSnapshot.issueScore,n,this.safeTraceLayerInputSnapshot);const i=this.safeTraceLayerPhaseAccepted?t:this.safeTraceLayerInputRoutes,r=this.safeTraceLayerPhaseAccepted?e:this.safeTraceLayerInputSnapshot,s=this.safeTraceLayerPhaseAccepted?this.safeTraceLayerSolver:this.portfolioSelectedSolver;return r.count>0&&!this.broadInputSnapshot?void this.startBroadBranch():mD(r)>0&&this.safeTraceLayerInputSnapshot.errors.some(uD)?void this.startMixedSafeTraceLayerPhase(i,r,s):void this.startViaInPadPhase(i,r,s)}if("mixedSafeTraceLayer"===this.phase){if(this.stepBranch(this.mixedSafeTraceLayerSolver,"mixed safe trace-layer"),!this.mixedSafeTraceLayerSolver.solved)return;const t=this.mixedSafeTraceLayerSolver.getOutput(),e=Wk(this.params.srj,t,this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine),n=mD(e)<=mD(this.legacySafeTraceLayerSnapshot);let o=!0;if(this.params.referenceDrcEvaluator){const e=this.getReferenceDrcSnapshot(this.legacySafeTraceLayerRoutes),n=this.getReferenceDrcSnapshot(t);this.mixedReferenceInputDrcIssueCount=e.count,this.mixedReferenceCandidateDrcIssueCount=n.count,o=n.count<=e.count}return this.mixedSafeTraceLayerPhaseAccepted=n&&o,void this.startViaInPadPhase(this.mixedSafeTraceLayerPhaseAccepted?t:this.legacySafeTraceLayerRoutes,this.mixedSafeTraceLayerPhaseAccepted?e:this.legacySafeTraceLayerSnapshot,this.mixedSafeTraceLayerPhaseAccepted?this.mixedSafeTraceLayerSolver:this.legacySafeTraceLayerSelectedSolver)}if("viaInPad"===this.phase){if(this.stepBranch(this.viaInPadSolver,"via-in-pad"),!this.viaInPadSolver.solved)return;const t=this.viaInPadSolver.getOutput(),e=Wk(this.params.srj,t,this.params.viaInPadDrcEvaluator??this.params.drcEvaluator,this.params.connMap,this.autoroutingDrcEngine);this.finishWithOutput(t,e,this.viaInPadSolver)}}getOutput(){return this.outputHdRoutes}visualize(){const t=this.activeSubSolver??this.selectedSolver;return t?.visualize()??super.visualize()}preview(){const t=this.activeSubSolver??this.selectedSolver;return t?.preview()??this.visualize()}},Tz=class extends si{constructor(t,e,n=Number.POSITIVE_INFINITY,o=.010000000000000002){super(),this.nodes=t,this.maxNodeDimension=e,this.maxNodeRatio=n,this.minNodeArea=o,this.outputNodes=[]}nodes;maxNodeDimension;maxNodeRatio;minNodeArea;outputNodes;getSolverName(){return"NodeDimensionSubdivisionSolver"}getSubdivisionGrid(t){const e=Number.isFinite(this.maxNodeDimension)&&this.maxNodeDimension>0,n=Number.isFinite(this.maxNodeRatio)&&this.maxNodeRatio>0;let o=e?Math.max(1,Math.ceil(t.width/this.maxNodeDimension)):1,i=e?Math.max(1,Math.ceil(t.height/this.maxNodeDimension)):1;if(n&&t.width>0&&t.height>0)for(;;){const e=t.width/o,n=t.height/i;if((e>=n?e/n:n/e)<=this.maxNodeRatio)break;e>=n?o++:i++}return{cols:o,rows:i}}shouldRemoveNode(t){const e=Number.isFinite(this.minNodeArea)&&this.minNodeArea>0;if(!Number.isFinite(t.width)||!Number.isFinite(t.height))return!0;if(!e||t.width*t.height>=this.minNodeArea)return!1;if(Math.min(t.width,t.height)<.002)return!0;if(t._containsTarget)return!1;let n=0;for(const e of this.nodes)if(e.capacityMeshNodeId!==t.capacityMeshNodeId&&t.availableZ.some(t=>e.availableZ.includes(t))&&li(t,e)){if(e._containsTarget)return!1;if(n++,n>=2)return!1}return!0}subdivideNode(t){if(this.shouldRemoveNode(t))return[];const{cols:e,rows:n}=this.getSubdivisionGrid(t);if(1===e&&1===n)return[t];const o=t.width/e,i=t.height/n,r=t.center.x-t.width/2,s=t.center.y-t.height/2,a=[];for(let c=0;c<n;c++)for(let n=0;n<e;n++)a.push({...t,capacityMeshNodeId:`${t.capacityMeshNodeId}__sub_${c}_${n}`,center:{x:r+o*(n+.5),y:s+i*(c+.5)},width:o,height:i,availableZ:[...t.availableZ]});return a}_step(){const t=this.nodes.length;let e=0,n=0,o=0;for(const t of this.nodes){const i=!Number.isFinite(t.width)||!Number.isFinite(t.height),r=this.subdivideNode(t);0!==r.length?(r.length>1&&e++,this.outputNodes.push(...r)):i?o++:n++}this.stats={inputNodeCount:t,outputNodeCount:this.outputNodes.length,subdividedNodeCount:e,removedSmallNodeCount:n,removedInvalidNodeCount:o,maxNodeDimension:this.maxNodeDimension,maxNodeRatio:this.maxNodeRatio,minNodeArea:this.minNodeArea},this.solved=!0}visualize(){return{rects:this.outputNodes.map(t=>({center:t.center,width:t.width,height:t.height,label:`${t.capacityMeshNodeId}\n${t.width.toFixed(2)}x${t.height.toFixed(2)}`,layer:`z${t.availableZ.join(",")}`,fill:"rgba(0, 200, 255, 0.08)",stroke:"rgba(0, 120, 180, 0.5)"}))}}},Rz=t=>{const e=[...new Set(t.filter(t=>"number"==typeof t&&Number.isInteger(t)&&t>=0))].sort((t,e)=>t-e);if(0!==e.length)return`z${e.join(",")}`},Ez=t=>{const e=[];for(let n=0;n<31;n++)t&1<<n&&e.push(n);return e},Az=t=>"object"==typeof t&&null!==t,Oz=t=>Az(t)?{...t}:void 0===t?{}:{value:t},kz=(t,e)=>{const n=t.topology.regionMetadata?.[e];if(Az(n)){if("string"==typeof n.serializedRegionId)return n.serializedRegionId;if("string"==typeof n.regionId)return n.regionId;if("string"==typeof n.capacityMeshNodeId)return n.capacityMeshNodeId}return`region-${e}`},Lz=(t,e)=>{const n=t.topology.portMetadata?.[e];if(Az(n)){if("string"==typeof n.serializedPortId)return n.serializedPortId;if("string"==typeof n.portId)return(o=n.portId).includes("::")?o.slice(0,o.indexOf("::")):o}var o;return`port-${e}`},Dz=(t,e)=>{const n=t.problem.routeMetadata?.[e];return Az(n)&&"string"==typeof n.connectionId?n.connectionId:`route-${e}`},zz=(t,e)=>{const n=Oz(t.topology.regionMetadata?.[e]);if(Az(n.center)||(n.center={x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),"number"!=typeof n.width&&(n.width=t.topology.regionWidth[e]),"number"!=typeof n.height&&(n.height=t.topology.regionHeight[e]),!Array.isArray(n.availableZ)){const o=t.topology.regionAvailableZMask?.[e]??0;0!==o&&(n.availableZ=Ez(o))}return n.layer=Rz(Array.isArray(n.availableZ)?n.availableZ:[])??Rz((t.topology.regionIncidentPorts[e]??[]).map(e=>t.topology.portZ[e]))??"z0",n},Fz=(t,e)=>{const n=Oz(t.topology.portMetadata?.[e]);return"number"!=typeof n.x&&(n.x=t.topology.portX[e]),"number"!=typeof n.y&&(n.y=t.topology.portY[e]),"number"!=typeof n.z&&(n.z=t.topology.portZ[e]),n.layer=Rz([t.topology.portZ[e]])??"z0",n},Bz=(t,e,n)=>{const o=(t.topology.incidentPortRegion[e]??[]).find(t=>t!==n);if(void 0===o)throw new Error(`Port ${e} is not incident to a region outside route region ${n}`);return o},jz=(t,e,n)=>{const{orderedPortIds:o,orderedRegionIds:i}=((t,e,n)=>{if(0===n.length)throw new Error(`Route ${e} has no solved segments`);const o=t.problem.routeStartPort[e],i=t.problem.routeEndPort[e],r=new Map;n.forEach((t,e)=>{const n={...t,segmentIndex:e},o=r.get(t.fromPortId)??[];o.push(n),r.set(t.fromPortId,o);const i=r.get(t.toPortId)??[];i.push(n),r.set(t.toPortId,i)});const s=[o],a=[],c=(t,e,n)=>{if(t===i)return!0;for(const o of r.get(t)??[]){if(e.has(o.segmentIndex))continue;const i=o.fromPortId===t?o.toPortId:o.fromPortId;if(!n.has(i)){if(e.add(o.segmentIndex),n.add(i),a.push(o.regionId),s.push(i),c(i,e,n))return!0;s.pop(),a.pop(),n.delete(i),e.delete(o.segmentIndex)}}return!1};if(!c(o,new Set,new Set([o])))throw new Error(`Route ${e} is not a single ordered path from ${o} to ${i}`);return{orderedPortIds:s,orderedRegionIds:a}})(t,e,n),r=i[0],s=i[i.length-1];if(void 0===r||void 0===s)throw new Error(`Route ${e} could not determine endpoint regions`);const a=kz(t,Bz(t,o[0],r)),c=kz(t,Bz(t,o[o.length-1],s)),l=((t,e,n,o)=>{const i=t.problem.routeMetadata?.[e];return{connectionId:Dz(t,e),startRegionId:(Az(i)&&"string"==typeof i.startRegionId?i.startRegionId:void 0)??n,endRegionId:(Az(i)&&"string"==typeof i.endRegionId?i.endRegionId:void 0)??o,mutuallyConnectedNetworkId:(Az(i)&&"string"==typeof i.mutuallyConnectedNetworkId?i.mutuallyConnectedNetworkId:void 0)??`net-${t.problem.routeNet[e]}`}})(t,e,a,c),d=o.map((e,n)=>{const r={portId:Lz(t,e),g:n,h:0,f:n,hops:n,ripRequired:!1,nextRegionId:n<i.length?kz(t,i[n]):l.endRegionId};return n>0&&(r.lastPortId=Lz(t,o[n-1]),r.lastRegionId=kz(t,i[n-1])),r});return{connection:l,solvedRoute:{connection:l,path:d,requiredRip:!1}}},$z=t=>{if(!t.solved||t.failed)throw new Error("convertToSerializedHyperGraph requires a solved, non-failed solver");const{topology:e}=t,n=(t=>{const e=Array.from({length:t.problem.routeCount},()=>[]);return t.state.regionSegments.forEach((t,n)=>{for(const[o,i,r]of t)e[o].push({regionId:n,fromPortId:i,toPortId:r})}),e})(t),o=Array.from({length:e.regionCount},(n,o)=>{const i=t.state.regionSegments[o].map(([e,n,o])=>({regionPort1Id:Lz(t,n),regionPort2Id:Lz(t,o),connectionId:Dz(t,e)}));return{regionId:kz(t,o),pointIds:e.regionIncidentPorts[o].map(e=>Lz(t,e)),d:zz(t,o),...i.length>0&&{assignments:i}}}),i=Array.from({length:e.portCount},(n,o)=>{const[i,r]=e.incidentPortRegion[o]??[];if(void 0===i||void 0===r)throw new Error(`Port ${o} is missing incident regions`);return{portId:Lz(t,o),region1Id:kz(t,i),region2Id:kz(t,r),d:Fz(t,o)}}),r=n.map((e,n)=>jz(t,n,e));return{regions:o,ports:i,connections:r.map(({connection:t})=>t),solvedRoutes:r.map(({solvedRoute:t})=>t)}},Yz=.3,Xz=t=>t>0&&!(t&t-1),Vz=(t,e,n,o,i,r=0,s=.3,a=0)=>(2*e+1*n+1*o)*(s+.15)**2*(1+i/5)/t+(Xz(r)?10*e:0)+a*(i/Wz(r))**2*.1**2/t,Wz=t=>{if(0===t)return 2;let e=t>>>0,n=0;for(;0!==e;)n+=1&e,e>>>=1;return n},Hz=(t,e,n,o,i,r)=>{const{netIds:s,lesserAngles:a,greaterAngles:c,layerMasks:l}=t;let d=0,h=0;for(let t=0;t<s.length;t++){if(e===s[t])continue;(n<a[t]&&a[t]<o)!==(n<c[t]&&c[t]<o)&&(0!==(i&l[t])?d++:h++)}return[d,h,r]},Gz=(t,e,n)=>{const o=t.routeStartPort[e],i=t.routeEndPort[e],r=new Map;for(const{fromPortId:t,toPortId:e}of n){const n=r.get(t)??new Set;n.add(e),r.set(t,n);const o=r.get(e)??new Set;o.add(t),r.set(e,o)}const s=new Set,a=[o];for(;a.length>0;){const t=a.pop();if(!s.has(t)){s.add(t);for(const e of r.get(t)??[])a.push(e)}}if(!s.has(i))throw new Error(`Initial assignments for route ${e} do not connect ${o} to ${i}`);if(n.some(({fromPortId:t,toPortId:e})=>!s.has(t)||!s.has(e)))throw new Error(`Initial assignments for route ${e} contain disconnected segments`)},Uz=({topology:t,problem:e,state:n,routeSuccessCountByRouteId:o,appendSegmentToRegionCache:i})=>{const r=e.initialAssignments??[];if(0===r.length)return;const s=new Map;for(const n of r){const{routeId:o,regionId:i,fromPortId:r,toPortId:a}=n;if(!Number.isInteger(o)||o<0||o>=e.routeCount)throw new Error(`Initial assignment references invalid route ${o}`);if(!Number.isInteger(i)||i<0||i>=t.regionCount)throw new Error(`Initial assignment references invalid region ${i}`);for(const e of[r,a]){if(!Number.isInteger(e)||e<0||e>=t.portCount)throw new Error(`Initial assignment references invalid port ${e}`);if(!t.incidentPortRegion[e]?.includes(i))throw new Error(`Initial assignment port ${e} is not incident to region ${i}`)}const c=s.get(o)??[];c.push(n),s.set(o,c)}for(const[t,n]of s)Gz(e,t,n);const a=new Set(s.keys());for(const{routeId:t,regionId:o,fromPortId:s,toPortId:a}of r){const r=e.routeNet[t];for(const t of[s,a]){const e=n.portAssignment[t];if(-1!==e&&e!==r)throw new Error(`Initial assignment port ${t} is assigned to multiple nets`);n.portAssignment[t]=r}n.currentRouteNetId=r,n.regionSegments[o].push([t,s,a]),i(o,s,a)}n.currentRouteNetId=void 0,n.unroutedRoutes=n.unroutedRoutes.filter(t=>!a.has(t));for(const t of a)o[t]=1;return{initialAssignmentCount:r.length,initiallyRoutedRouteCount:a.size}},Zz=class{constructor(t,e){this.items=t,this.compare=e}items;compare;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0}queue(t){this.items.push(t),this.siftUp(this.items.length-1)}dequeue(){const t=this.items[0];if(void 0===t)return;const e=this.items.pop();return this.items.length>0&&(this.items[0]=e,this.siftDown(0)),t}siftUp(t){let e=t;for(;e>0;){const t=e-1>>1,n=this.items[t],o=this.items[e];if(this.compare(n,o)<=0)return;this.items[t]=o,this.items[e]=n,e=t}}siftDown(t){let e=t;const n=this.items.length;for(;;){const t=2*e+1;if(t>=n)return;const o=t+1;let i=t;o<n&&this.compare(this.items[o],this.items[t])<0&&(i=o);const r=this.items[e],s=this.items[i];if(this.compare(r,s)<=0)return;this.items[e]=s,this.items[i]=r,e=i}}},qz=(t,e)=>{const n=[...t],o=(t=>{let e=t>>>0;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}})(e);for(let t=n.length-1;t>0;t--){const e=Math.floor(o()*(t+1));[n[t],n[e]]=[n[e],n[t]]}return n},Jz=(t,e)=>t.routeMetadata?.[e],Kz=t=>t?.simpleRouteConnection?.pointsToConnect?.map(({pointId:t})=>"string"==typeof t?t:null).filter(t=>null!==t)??[],Qz=(t,e)=>{const n=Jz(t,e)?.connectionId;return"string"==typeof n?n:`route-${e}`},tF=(t,e,n)=>{const o=t.portEndpointNetIds[n];if(!o)return!1;for(const t of o)if(t!==e)return!0;return!1},eF=(t,e,n)=>{const o=t.regionNetId[n];return-1!==o&&o!==e},nF=t=>[...new Set(t.routeIds)].filter(e=>!((t,e)=>{const{topology:n,problem:o,problemSetup:i,portAssignment:r,maxPrecheckHops:s}=t,a=o.routeNet[e],c=o.routeStartPort[e],l=o.routeEndPort[e];if(c===l)return!0;const d=t.getStartingNextRegionId(e,c);if(void 0===d)return!1;const h=[{portId:c,nextRegionId:d}],u=new Set([c*n.regionCount+d]);for(let t=0;t<h.length;t++){const e=h[t];if(!eF(o,a,e.nextRegionId))for(const t of n.regionIncidentPorts[e.nextRegionId]??[]){const c=r[t];if(tF(i,a,t))continue;if(t===l){if(-1!==c&&c!==a)continue;return!0}if(t===e.portId)continue;if(-1!==c&&c!==a)continue;if(0===o.portSectionMask[t])continue;const d=n.incidentPortRegion[t]??[],p=d[0]===e.nextRegionId?d[1]:d[0];if(void 0===p||eF(o,a,p))continue;const m=t*n.regionCount+p;if(!u.has(m)){if(u.size>=s)return!0;u.add(m),h.push({portId:t,nextRegionId:p})}}}return!1})(t,e)).map(e=>t.getRouteSummary(e)),oF=t=>{const e=new Array(t);for(let n=0;n<t;n++)e[n]=n;return e},iF="rgba(220, 38, 38, 0.98)",rF="rgba(220, 38, 38, 0.18)",sF=(...t)=>t.filter(t=>Boolean(t)).join("\n"),aF=(t,e)=>{const n=.005*t.topology.portZ[e];return{x:t.topology.portX[e]+n,y:t.topology.portY[e]+n}},cF=(t,e)=>Rz([t.topology.portZ[e]])??"z0",lF=(t,e)=>{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},dF=(t,e)=>`z: ${t.topology.portZ[e]}`,hF=(t,e)=>((t,e,n)=>{const o=t.topology.portZ[e],i=t.topology.portZ[n];return o===i?`z: ${o}`:`z: ${o} -> ${i}`})(t,t.problem.routeStartPort[e],t.problem.routeEndPort[e]),uF=(t,e)=>`net: ${t.problem.routeNet[e]}`,pF=.05,mF={r:255,g:64,b:64,a:.72},gF="rgba(220, 38, 38, 0.98)",fF="rgba(220, 38, 38, 0.12)",yF="10 6",_F=(...t)=>t.filter(t=>Boolean(t)).join("\n"),bF=t=>Math.min(1,Math.max(0,t)),xF=(t,e,n)=>Math.round(t+(e-t)*n),vF=({r:t,g:e,b:n,a:o})=>`rgba(${t}, ${e}, ${n}, ${o})`,SF=(t,e)=>{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},IF=t=>"number"==typeof t.centerRouteId,CF=(t,e)=>IF(t)?e===t.centerRouteId?1:.5:1,PF=(t,e)=>{const n=t.match(/^(rgba|hsla)\((.*),\s*([0-9]*\.?[0-9]+)\)$/);if(!n)return t;const[,o,i,r]=n,s=bF(Number(r)*e);return`${o}(${i}, ${Number(s.toFixed(3))})`},MF=(t,e,n=.8)=>((t,e,n=.8)=>{const o=`${t.problem.routeNet[e]}:${SF(t,e)}`;let i=0;for(let t=0;t<o.length;t++)i=17777*o.charCodeAt(t)+((i<<5)-i);return`hsla(${Math.abs(i)%360}, 70%, 50%, ${n})`})(t,e,n*CF(t,e)),NF=(t,e)=>`net: ${t.problem.routeNet[e]}`,wF=(t,e)=>{const n=t.topology.regionMetadata?.[e],o=n?.polygon;if(Array.isArray(o)&&o.length>=3){const t=o.map(t=>t.x),e=o.map(t=>t.y);return{minX:Math.min(...t),maxX:Math.max(...t),minY:Math.min(...e),maxY:Math.max(...e)}}const i=n?.bounds;if(i&&"number"==typeof i.minX&&"number"==typeof i.maxX&&"number"==typeof i.minY&&"number"==typeof i.maxY)return i;const r=t.topology.regionWidth[e],s=t.topology.regionHeight[e],a=t.topology.regionCenterX[e],c=t.topology.regionCenterY[e];return{minX:a-r/2,maxX:a+r/2,minY:c-s/2,maxY:c+s/2}},TF=(t,e)=>({x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),RF=(t,e)=>{const n=t.topology.regionMetadata?.[e],o=Array.isArray(n?.availableZ)?n.availableZ.filter(t=>"number"==typeof t&&Number.isInteger(t)&&t>=0):[];if(o.length>0)return Rz(o)??"z0";const i=Ez(t.topology.regionAvailableZMask?.[e]??0);if(i.length>0)return Rz(i)??"z0";const r=[...new Set((t.topology.regionIncidentPorts[e]??[]).map(e=>t.topology.portZ[e]))].sort((t,e)=>t-e);return Rz(r)??"z0"},EF=(t,e)=>{const n=t.state.regionIntersectionCaches[e],o=n?.existingRegionCost??0,i=t.state.regionCongestionCost[e]??0,r=t.problem.regionNetId[e];return _F(`region: region-${e}`,`net: ${-1===r?"free":`${r}`}`,t.getAdditionalRegionLabel(e),`cost: ${o.toFixed(3)}`,`congestion: ${i.toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},AF=(t,e)=>{const n=t.topology.regionMetadata?.[e];return n?.isConnectionRegion?{r:255,g:100,b:255,a:.6}:n?.isThroughJumper?{r:100,g:200,b:100,a:.5}:n?.isPad?{r:255,g:200,b:100,a:.5}:"bottom"===n?.layer?{r:52,g:152,b:219,a:.08}:{r:200,g:200,b:255,a:.1}},OF=(t,e)=>{const n=AF(t,e),o=bF(t.state.regionIntersectionCaches[e]?.existingRegionCost??0);return vF((r=mF,s=o**.8,{r:xF((i=n).r,r.r,s),g:xF(i.g,r.g,s),b:xF(i.b,r.b,s),a:Number((i.a+(r.a-i.a)*s).toFixed(3))}));var i,r,s},kF=(t,e)=>{const n=((t,e)=>({x:t.topology.portX[e],y:t.topology.portY[e]}))(t,e),o=.005*t.topology.portZ[e];return{x:n.x+o,y:n.y+o}},LF=kF,DF=(t,e)=>Rz([t.topology.portZ[e]])??"z0",zF=(t,e)=>{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},FF=(t,e,n)=>{if(void 0!==n)return`net: ${t.problem.routeNet[n]}`;const o=t.state.portAssignment[e];if(o>=0)return`net: ${o}`;const i=new Set;for(let n=0;n<t.problem.routeCount;n++)t.problem.routeStartPort[n]!==e&&t.problem.routeEndPort[n]!==e||i.add(t.problem.routeNet[n]);return 0!==i.size?`net: ${Array.from(i).sort((t,e)=>t-e).join(", ")}`:void 0},BF=(t,e)=>`z: ${t.topology.portZ[e]}`,jF=(t,e,n)=>{const o=t.topology.portZ[e],i=t.topology.portZ[n];return o===i?`z: ${o}`:`z: ${o} -> ${i}`},$F=(t,e)=>jF(t,t.problem.routeStartPort[e],t.problem.routeEndPort[e]),YF=(t,e,n)=>_F(zF(t,e),((t,e)=>{const n=t.topology.incidentPortRegion[e]?.[0],o=t.topology.incidentPortRegion[e]?.[1];return`connects: region-${n??"?"} <-> region-${o??"?"}`})(t,e),FF(t,e,n)),XF=(t,e,n,o)=>{const i=t.topology.portZ[n];return i!==t.topology.portZ[o]?{strokeColor:PF("rgba(22, 160, 133, 0.95)",CF(t,e)),strokeDash:"2 4 2"}:i>0?{strokeColor:PF("rgba(52, 152, 219, 0.95)",CF(t,e)),strokeDash:"3 2"}:{strokeColor:MF(t,e)}},VF=(t,e)=>{for(let n=0;n<t.state.regionSegments.length;n++){const o=t.state.regionSegments[n]??[];for(const[i,r,s]of o)e.lines.push({points:[kF(t,r),kF(t,s)],label:_F(`route: ${SF(t,i)}`,`region: region-${n}`,jF(t,r,s)),layer:DF(t,r),...XF(t,i,r,s)})}},WF=(t,e)=>{const n=new Set;for(let o=0;o<t.state.regionSegments.length;o++){const i=t.state.regionSegments[o]??[];for(const[o,r,s]of i)for(const i of[r,s]){const r=`${o}:${i}`;if(n.has(r))continue;n.add(r);const s=kF(t,i);e.points.push({x:s.x,y:s.y,color:MF(t,o,1),layer:DF(t,i),label:_F(`route: ${SF(t,o)}`,zF(t,i),FF(t,i,o),BF(t,i))})}}},HF=(t,e)=>{for(let n=0;n<t.problem.routeCount;n++)if(t.problem.routeStartPort[n]===e||t.problem.routeEndPort[n]===e)return!0;return!1},GF=(t,e,n)=>{const o=((t,e)=>{const n=new Set;for(let o=0;o<e.length;o++)if(1===e[o])for(const e of t.topology.incidentPortRegion[o]??[])n.add(e);return n})(t,n),i="rgba(245, 158, 11, 0.95)",r="rgba(245, 158, 11, 0.08)";for(const n of o){const o=t.topology.regionMetadata?.[n],s=o?.polygon,a=wF(t,n),c=TF(t,n),l=a.maxX-a.minX,d=a.maxY-a.minY,h=RF(t,n),u=_F("section region",EF(t,n));Array.isArray(s)&&s.length>=3?e.polygons.push({points:s,fill:r,stroke:i,strokeWidth:2,layer:h,label:u}):e.rects.push({center:c,width:Math.max(l-pF,.05),height:Math.max(d-pF,.05),fill:r,stroke:i,layer:h,label:u})}for(let o=0;o<n.length;o++)1===n[o]&&e.circles.push({center:LF(t,o),radius:.07,fill:"rgba(251, 191, 36, 0.18)",stroke:i,layer:DF(t,o),label:_F(YF(t,o),BF(t,o),"section port")})},UF=(t,e={})=>{const n={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:"Tiny HyperGraph",coordinateSystem:"cartesian"},o=((t,e)=>{if(!e?.highlightSectionMask)return;const n=e.sectionPortMask??t.problem.portSectionMask;if(n.length!==t.topology.portCount)return;let o=0,i=0;for(let t=0;t<n.length;t++)1===n[t]?o+=1:i+=1;return 0!==o&&0!==i?n:void 0})(t,e),i=(t=>{const e=t.getStaticallyUnroutableRoutes();if(0!==e.length)return new Set(e.map(t=>t.routeId))})(t);for(let e=0;e<t.topology.regionCount;e++){const o=t.topology.regionMetadata?.[e],i=o?.polygon,r=wF(t,e),s=TF(t,e),a=r.maxX-r.minX,c=r.maxY-r.minY,l=RF(t,e),d=vF(AF(t,e));Array.isArray(i)&&i.length>=3?n.polygons.push({points:i,fill:d,layer:l}):n.rects.push({center:s,width:Math.max(a-pF,.05),height:Math.max(c-pF,.05),fill:OF(t,e),layer:l,label:EF(t,e)})}if(((t,e,n)=>{for(let o=0;o<t.problem.routeCount;o++){if(n&&!n.has(o))continue;const i=t.problem.routeStartPort[o],r=t.problem.routeEndPort[o],s=kF(t,i),a=kF(t,r),c=MF(t,o),l=SF(t,o),d=NF(t,o);e.points.push({x:s.x,y:s.y,color:c,layer:DF(t,i),label:_F(`route: ${l}`,d,"endpoint: start",zF(t,i),BF(t,i))}),e.points.push({x:a.x,y:a.y,color:c,layer:DF(t,r),label:_F(`route: ${l}`,d,"endpoint: end",zF(t,r),BF(t,r))})}})(t,n,i),0===t.iterations){for(const t of n.polygons)t.stroke="rgba(128, 128, 128, 0.5)";for(const t of n.rects)t.stroke="rgba(128, 128, 128, 0.5)"}if(0===t.iterations){for(let i=0;i<t.topology.portCount;i++){const r=1===o?.[i];e.showOnlySectionPortsOnIdle&&!r||n.circles.push({center:LF(t,i),radius:.05,fill:t.topology.portZ[i]>0?"rgba(52, 152, 219, 0.55)":"rgba(128, 128, 128, 0.5)",layer:DF(t,i),label:_F(YF(t,i),BF(t,i))})}if(i)((t,e)=>{for(const n of t.getStaticallyUnroutableRoutes()){const{routeId:o,connectionId:i,startPortId:r,endPortId:s}=n,a=aF(t,r),c=aF(t,s),l=sF(`static reachability failed: ${i}`,uF(t,o),n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0,n.pointIds.length>=2?`points: ${n.pointIds.join(" -> ")}`:void 0,hF(t,o));e.lines.push({points:[a,c],strokeColor:iF,strokeDash:"8 4",label:l}),e.circles.push({center:a,radius:.12,fill:rF,stroke:iF,layer:cF(t,r),label:sF(l,"endpoint: start",lF(t,r),dF(t,r))}),e.circles.push({center:c,radius:.12,fill:rF,stroke:iF,layer:cF(t,s),label:sF(l,"endpoint: end",lF(t,s),dF(t,s))})}})(t,n);else{const o=new Set;for(const e of t.state.regionSegments)for(const[t]of e)o.add(t);if(o.size>0&&(VF(t,n),WF(t,n)),!1!==e.showInitialRouteHints){const e=new Set(t.state.unroutedRoutes);void 0!==t.state.currentRouteId&&e.add(t.state.currentRouteId),((t,e,n)=>{for(let o=0;o<t.problem.routeCount;o++){if(n&&!n.has(o))continue;const i=t.problem.routeStartPort[o],r=t.problem.routeEndPort[o],s=kF(t,i),a=kF(t,r),c={x:(s.x+a.x)/2,y:(s.y+a.y)/2};e.lines.push({points:[s,a],strokeColor:MF(t,o),strokeDash:"3 3",layer:DF(t,i),label:_F(SF(t,o),$F(t,o))}),e.points.push({x:c.x,y:c.y,color:MF(t,o,1),layer:DF(t,i),label:_F(SF(t,o),$F(t,o))})}})(t,n,e)}}}else VF(t,n),WF(t,n),(t=>IF(t)&&!0===t.showUnassignedPortsInVisualization)(t)&&((t,e)=>{for(let n=0;n<t.topology.portCount;n++)t.state.portAssignment[n]>=0||HF(t,n)||e.circles.push({center:LF(t,n),radius:.04,fill:t.topology.portZ[n]>0?"rgba(52, 152, 219, 0.2)":"rgba(128, 128, 128, 0.2)",stroke:t.topology.portZ[n]>0?"rgba(52, 152, 219, 0.6)":"rgba(128, 128, 128, 0.6)",layer:DF(t,n),label:_F(YF(t,n),BF(t,n),"state: unassigned")})})(t,n),IF(t)||(((t,e)=>{const n=t.state.currentRouteId;if(void 0===n||t.solved)return;const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=kF(t,o),s=kF(t,i),a=MF(t,n),c=SF(t,n);e.lines.push({points:[r,s],strokeColor:a,strokeDash:"10 5",label:_F(c,$F(t,n))})})(t,n),((t,e)=>{if(t.solved)return;const n=t.state.currentRouteId,o=t.state.candidateQueue.toArray().sort((t,e)=>t.f-e.f).slice(0,10);for(let i=0;i<o.length;i++){const r=o[i],s=kF(t,r.portId),a=0===i;e.points.push({x:s.x,y:s.y,color:a?"green":"rgba(128, 128, 128, 0.25)",layer:DF(t,r.portId),label:_F(YF(t,r.portId,n),BF(t,r.portId),`g: ${r.g.toFixed(2)}`,`h: ${r.h.toFixed(2)}`,`f: ${r.f.toFixed(2)}`)})}const i=o[0];if(!i)return;const r=[];let s=i;for(;s;)r.unshift(kF(t,s.portId)),s=s.prevCandidate;r.length>1&&e.lines.push({points:r,strokeColor:void 0!==n?MF(t,n):"rgba(0, 160, 120, 0.9)"})})(t,n));o&&GF(t,n,o),((t,e)=>{if(t.failed)for(const n of t.getNeverSuccessfullyRoutedRoutes()){const{routeId:o,connectionId:i,attempts:r,startPortId:s,endPortId:a}=n,c=NF(t,o),l=LF(t,s),d=LF(t,a),h=_F(`never routed: ${i}`,`attempts: ${r}`,c,n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0);e.lines.push({points:[{x:0,y:0},{x:l.x,y:l.y}],strokeColor:gF,strokeDash:yF,layer:DF(t,s),label:_F(h,"origin guide","endpoint: start")}),e.circles.push({center:l,radius:1,fill:fF,stroke:gF,layer:DF(t,s),label:_F(h,"endpoint: start",zF(t,s),BF(t,s))}),e.lines.push({points:[{x:0,y:0},{x:d.x,y:d.y}],strokeColor:gF,strokeDash:yF,layer:DF(t,a),label:_F(h,"origin guide","endpoint: end")}),e.circles.push({center:d,radius:1,fill:fF,stroke:gF,layer:DF(t,a),label:_F(h,"endpoint: end",zF(t,a),BF(t,a))})}})(t,n);const r=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1),s=o?o.reduce((t,e)=>t+Number(1===e),0):0;return n.title=["Tiny HyperGraph",`iter=${t.iterations}`,`pending=${r}`,o?`sectionPorts=${s}`:void 0,i?`staticReachabilityFailed=${i.size}`:void 0,t.failed?"failed":t.solved?"solved":"running"].filter(Boolean).join(" | "),n},ZF=5e4,qF=()=>({netIds:new Int32Array(0),lesserAngles:new Int32Array(0),greaterAngles:new Int32Array(0),layerMasks:new Int32Array(0),existingCrossingLayerIntersections:0,existingSameLayerIntersections:0,existingEntryExitLayerChanges:0,existingRegionCost:0,existingSegmentCount:0}),JF=t=>({netIds:new Int32Array(t.netIds),lesserAngles:new Int32Array(t.lesserAngles),greaterAngles:new Int32Array(t.greaterAngles),layerMasks:new Int32Array(t.layerMasks),existingCrossingLayerIntersections:t.existingCrossingLayerIntersections,existingSameLayerIntersections:t.existingSameLayerIntersections,existingEntryExitLayerChanges:t.existingEntryExitLayerChanges,existingRegionCost:t.existingRegionCost,existingSegmentCount:t.existingSegmentCount}),KF=t=>{return{portAssignment:new Int32Array(t.portAssignment),regionSegments:(e=t.regionSegments,e.map(t=>t.map(([t,e,n])=>[t,e,n]))),regionIntersectionCaches:t.regionIntersectionCaches.map(JF),regionCongestionCost:new Float64Array(t.regionCongestionCost),ripCount:t.ripCount};var e},QF=(t,e)=>{e&&(void 0!==e.minViaPadDiameter&&(t.minViaPadDiameter=e.minViaPadDiameter),void 0!==e.DISTANCE_TO_COST&&(t.DISTANCE_TO_COST=e.DISTANCE_TO_COST),void 0!==e.RIP_THRESHOLD_START&&(t.RIP_THRESHOLD_START=e.RIP_THRESHOLD_START),void 0!==e.RIP_THRESHOLD_END&&(t.RIP_THRESHOLD_END=e.RIP_THRESHOLD_END),void 0!==e.RIP_THRESHOLD_RAMP_ATTEMPTS&&(t.RIP_THRESHOLD_RAMP_ATTEMPTS=e.RIP_THRESHOLD_RAMP_ATTEMPTS),void 0!==e.RIP_CONGESTION_REGION_COST_FACTOR&&(t.RIP_CONGESTION_REGION_COST_FACTOR=e.RIP_CONGESTION_REGION_COST_FACTOR),void 0!==e.TRACE_DENSITY_COST_FACTOR&&(t.TRACE_DENSITY_COST_FACTOR=Math.max(0,e.TRACE_DENSITY_COST_FACTOR)),void 0!==e.USE_LAZY_ROUTE_HEURISTIC&&(t.USE_LAZY_ROUTE_HEURISTIC=e.USE_LAZY_ROUTE_HEURISTIC),void 0!==e.USE_SPARSE_CANDIDATE_STORAGE&&(t.USE_SPARSE_CANDIDATE_STORAGE=e.USE_SPARSE_CANDIDATE_STORAGE),void 0!==e.MAX_ITERATIONS&&(t.MAX_ITERATIONS=e.MAX_ITERATIONS),void 0!==e.VERBOSE&&(t.VERBOSE=e.VERBOSE),void 0!==e.STATIC_REACHABILITY_PRECHECK&&(t.STATIC_REACHABILITY_PRECHECK=e.STATIC_REACHABILITY_PRECHECK),void 0!==e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS&&(t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS=e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),void 0!==e.ACCEPT_BEST_SOLUTION_ON_TIMEOUT&&(t.ACCEPT_BEST_SOLUTION_ON_TIMEOUT=e.ACCEPT_BEST_SOLUTION_ON_TIMEOUT),void 0!==e.GREEDY_FINAL_ROUTE_ITERS&&(t.GREEDY_FINAL_ROUTE_ITERS=e.GREEDY_FINAL_ROUTE_ITERS),void 0!==e.PARTIAL_RIP_ENABLED&&(t.PARTIAL_RIP_ENABLED=e.PARTIAL_RIP_ENABLED),void 0!==e.PARTIAL_RIP_MIN_ROUTE_COUNT&&(t.PARTIAL_RIP_MIN_ROUTE_COUNT=e.PARTIAL_RIP_MIN_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_MAX_ROUTE_COUNT&&(t.PARTIAL_RIP_MAX_ROUTE_COUNT=e.PARTIAL_RIP_MAX_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_MAX_DISTANCE&&(t.PARTIAL_RIP_MAX_DISTANCE=e.PARTIAL_RIP_MAX_DISTANCE),void 0!==e.PARTIAL_RIP_QUALITY_MAX_DISTANCE&&(t.PARTIAL_RIP_QUALITY_MAX_DISTANCE=e.PARTIAL_RIP_QUALITY_MAX_DISTANCE),void 0!==e.PARTIAL_RIP_MAX_ATTEMPTS&&(t.PARTIAL_RIP_MAX_ATTEMPTS=e.PARTIAL_RIP_MAX_ATTEMPTS),void 0!==e.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS&&(t.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS=e.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS),void 0!==e.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT&&(t.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT=e.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT),void 0!==e.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO&&(t.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO=e.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO),void 0!==e.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO&&(t.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO=e.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO),void 0!==e.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO&&(t.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO=e.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO),void 0!==e.OUTSIDE_IN_ROUTING&&(t.OUTSIDE_IN_ROUTING=e.OUTSIDE_IN_ROUTING),void 0!==e.OUTSIDE_IN_MAX_DISTANCE&&(t.OUTSIDE_IN_MAX_DISTANCE=e.OUTSIDE_IN_MAX_DISTANCE))},tB=t=>({minViaPadDiameter:t.minViaPadDiameter,DISTANCE_TO_COST:t.DISTANCE_TO_COST,RIP_THRESHOLD_START:t.RIP_THRESHOLD_START,RIP_THRESHOLD_END:t.RIP_THRESHOLD_END,RIP_THRESHOLD_RAMP_ATTEMPTS:t.RIP_THRESHOLD_RAMP_ATTEMPTS,RIP_CONGESTION_REGION_COST_FACTOR:t.RIP_CONGESTION_REGION_COST_FACTOR,TRACE_DENSITY_COST_FACTOR:t.TRACE_DENSITY_COST_FACTOR,USE_LAZY_ROUTE_HEURISTIC:t.USE_LAZY_ROUTE_HEURISTIC,USE_SPARSE_CANDIDATE_STORAGE:t.USE_SPARSE_CANDIDATE_STORAGE,MAX_ITERATIONS:t.MAX_ITERATIONS,VERBOSE:t.VERBOSE,STATIC_REACHABILITY_PRECHECK:t.STATIC_REACHABILITY_PRECHECK,STATIC_REACHABILITY_PRECHECK_MAX_HOPS:t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:t.ACCEPT_BEST_SOLUTION_ON_TIMEOUT,GREEDY_FINAL_ROUTE_ITERS:t.GREEDY_FINAL_ROUTE_ITERS,PARTIAL_RIP_ENABLED:t.PARTIAL_RIP_ENABLED,PARTIAL_RIP_MIN_ROUTE_COUNT:t.PARTIAL_RIP_MIN_ROUTE_COUNT,PARTIAL_RIP_MAX_ROUTE_COUNT:t.PARTIAL_RIP_MAX_ROUTE_COUNT,PARTIAL_RIP_MAX_DISTANCE:t.PARTIAL_RIP_MAX_DISTANCE,PARTIAL_RIP_QUALITY_MAX_DISTANCE:t.PARTIAL_RIP_QUALITY_MAX_DISTANCE,PARTIAL_RIP_MAX_ATTEMPTS:t.PARTIAL_RIP_MAX_ATTEMPTS,PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS:t.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:t.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT,PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO:t.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO,PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO:t.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO,PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO:t.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO,OUTSIDE_IN_ROUTING:t.OUTSIDE_IN_ROUTING,OUTSIDE_IN_MAX_DISTANCE:t.OUTSIDE_IN_MAX_DISTANCE}),eB=(t,e)=>t.f-e.f,nB=class extends kt{constructor(t,e,n){super(),this.topology=t,this.problem=e,QF(this,n);let o=1;const i=new Int32Array(t.portCount).fill(-1),r=new Int32Array(t.portCount).fill(-1);for(let e=0;e<t.portCount;e++){const n=t.incidentPortRegion[e]??[];n.length>o&&(o=n.length),i[e]=n[0]??-1,r[e]=n[1]??-1}this.candidateHopSlotStride=o,this.candidateFirstRegionByPortId=i,this.candidateSecondRegionByPortId=r;const s=t.portCount*o;this.candidateHopCapacity=s,this.state={portAssignment:new Int32Array(t.portCount).fill(-1),regionSegments:Array.from({length:t.regionCount},()=>[]),regionIntersectionCaches:Array.from({length:t.regionCount},()=>qF()),currentRouteId:void 0,currentRouteNetId:void 0,unroutedRoutes:oF(e.routeCount),candidateQueue:new Zz([],eB),candidateBestCostByHopId:this.USE_SPARSE_CANDIDATE_STORAGE?new Map:new Float64Array(s),candidateBestCostGenerationByHopId:this.USE_SPARSE_CANDIDATE_STORAGE?new Map:new Uint32Array(s),candidateBestCostGeneration:1,goalPortId:-1,ripCount:0,regionCongestionCost:new Float64Array(t.regionCount).fill(0)},this.routeAttemptCountByRouteId=new Uint32Array(e.routeCount),this.routeSuccessCountByRouteId=new Uint32Array(e.routeCount);const a=Uz({topology:t,problem:e,state:this.state,routeSuccessCountByRouteId:this.routeSuccessCountByRouteId,appendSegmentToRegionCache:(t,e,n)=>this.appendSegmentToRegionCache(t,e,n)});a&&(this.stats={...this.stats,...a})}topology;problem;state;candidateHopSlotStride;candidateHopCapacity;candidateFirstRegionByPortId;candidateSecondRegionByPortId;candidateOverflowBestCost;_problemSetup;routeAttemptCountByRouteId;routeSuccessCountByRouteId;bestSolvedStateSnapshot;bestSolvedStateSummary;hasLoggedNeverSuccessfullyRoutedRoutes=!1;staticallyUnroutableRoutes=[];segmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};ADD_SEGMENT_DISTANCE_TO_G=!1;DISTANCE_TO_COST=.05;minViaPadDiameter=Yz;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;RIP_CONGESTION_REGION_COST_FACTOR=.1;TRACE_DENSITY_COST_FACTOR=0;USE_LAZY_ROUTE_HEURISTIC=!1;USE_SPARSE_CANDIDATE_STORAGE=!1;MAX_ITERATIONS=1e6;VERBOSE=!1;STATIC_REACHABILITY_PRECHECK=!0;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;ACCEPT_BEST_SOLUTION_ON_TIMEOUT=!0;GREEDY_FINAL_ROUTE_ITERS=4;PARTIAL_RIP_ENABLED=!1;PARTIAL_RIP_MIN_ROUTE_COUNT=0;PARTIAL_RIP_MAX_ROUTE_COUNT=Number.POSITIVE_INFINITY;PARTIAL_RIP_MAX_DISTANCE=12;PARTIAL_RIP_QUALITY_MAX_DISTANCE;PARTIAL_RIP_MAX_ATTEMPTS=Number.POSITIVE_INFINITY;PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS=0;PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT=Number.POSITIVE_INFINITY;PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO=0;PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO=.2;PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO=.1;OUTSIDE_IN_ROUTING=!1;OUTSIDE_IN_MAX_DISTANCE=24;get problemSetup(){return this._problemSetup||(this._problemSetup=this.computeProblemSetup()),this._problemSetup}computeProblemSetup(){const{topology:t,problem:e}=this,n=this.USE_LAZY_ROUTE_HEURISTIC?void 0:new Float64Array(t.portCount*e.routeCount),o=t.portX,i=t.portY,r=Array.from({length:t.portCount},()=>new Set),s=new Int32Array(t.portCount).fill(-1),a=(t,e)=>{r[t].add(e);const n=s[t];-1===n?s[t]=e:n!==e&&(s[t]=-2)};for(let r=0;r<e.routeCount;r++){const s=e.routeNet[r];if(a(e.routeStartPort[r],s),a(e.routeEndPort[r],s),n){const s=e.routeEndPort[r],a=o[s],c=i[s];for(let s=0;s<t.portCount;s++){const t=o[s]-a,l=i[s]-c;n[s*e.routeCount+r]=Math.sqrt(t*t+l*l)*this.DISTANCE_TO_COST}}}return{portHCostToEndOfRoute:n,portEndpointNetIds:r,portEndpointReservationNetId:s}}_setup(){if(this.problemSetup,this.STATIC_REACHABILITY_PRECHECK){const t=nF({topology:this.topology,problem:this.problem,problemSetup:this.problemSetup,portAssignment:this.state.portAssignment,routeIds:this.state.unroutedRoutes,maxPrecheckHops:Math.max(0,this.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),getStartingNextRegionId:(t,e)=>this.getStartingNextRegionId(t,e),getRouteSummary:t=>this.getRouteSummary(t)});this.staticallyUnroutableRoutes=t,t.length>0&&(this.failed=!0,this.error=(t=>{const e=t.slice(0,5).map(t=>{const e=t.pointIds.length>=2?`${t.pointIds[0]}->${t.pointIds[1]}`:`${t.startPortId}->${t.endPortId}`;return`${t.connectionId} (${e})`}).join(", "),n=t.length-5;return["Static reachability precheck failed:",`${t.length} route(s) have no legal path under the current reservation and start-region rules`,n>0?`${e}, +${n} more`:e].join(" ")})(t),this.stats={...this.stats,staticallyUnroutableRouteCount:t.length})}}_step(){const{problem:t,topology:e,state:n}=this;if(void 0===n.currentRouteId){if(0===n.unroutedRoutes.length)return void this.onAllRoutesRouted();n.currentRouteId=n.unroutedRoutes.shift(),n.currentRouteNetId=t.routeNet[n.currentRouteId],this.routeAttemptCountByRouteId[n.currentRouteId]+=1,this.resetCandidateBestCosts();const e=this.getRouteStartPortId(n.currentRouteId);n.candidateQueue.clear();const o=this.getStartingNextRegionId(n.currentRouteId,e);if(void 0===o)return this.failed=!0,void(this.error=`Start port ${e} has no incident regions`);this.setCandidateBestCost(this.getHopId(e,o),0),n.candidateQueue.queue({nextRegionId:o,portId:e,f:0,g:0,h:0}),n.goalPortId=this.getRouteEndPortId(n.currentRouteId)}const o=n.candidateQueue.dequeue();if(!o)return void this.onOutOfCandidates();const i=this.getHopId(o.portId,o.nextRegionId);if(o.g>this.getCandidateBestCost(i))return;if(this.isRegionReservedForDifferentNet(o.nextRegionId))return;const r=e.regionIncidentPorts[o.nextRegionId];for(const i of r){const r=n.portAssignment[i];if(this.isPortReservedForDifferentNet(i))continue;if(i===n.goalPortId){if(-1!==r&&r!==n.currentRouteNetId)continue;return void this.onPathFound(o)}if(-1!==r&&r!==n.currentRouteNetId)continue;if(i===o.portId)continue;if(0===t.portSectionMask[i])continue;const s=e.incidentPortRegion[i][0]===o.nextRegionId?e.incidentPortRegion[i][1]:e.incidentPortRegion[i][0];if(void 0===s||this.isRegionReservedForDifferentNet(s))continue;const a=this.getHopId(i,s);if(!0===n.candidateQueue.isClosedHop?.(i,s))continue;const c=this.getCandidateBestCost(a);if(o.g>=c)continue;const l=this.computeG(o,i,c);if(!Number.isFinite(l)||l>=c)continue;const d=this.computeH(i),h={prevRegionId:o.nextRegionId,nextRegionId:s,portId:i,g:l,h:d,f:l+d,prevCandidate:o};if(i===n.goalPortId)return void this.onPathFound(h);this.setCandidateBestCost(a,l),n.candidateQueue.queue(h)}}resetCandidateBestCosts(){const{state:t}=this;if(this.candidateOverflowBestCost?.clear(),4294967295===t.candidateBestCostGeneration)return t.candidateBestCostByHopId instanceof Map&&t.candidateBestCostByHopId.clear(),t.candidateBestCostGenerationByHopId instanceof Map?t.candidateBestCostGenerationByHopId.clear():t.candidateBestCostGenerationByHopId.fill(0),void(t.candidateBestCostGeneration=1);t.candidateBestCostGeneration+=1}getCandidateBestCost(t){if(t<0)return this.candidateOverflowBestCost?.get(t)??Number.POSITIVE_INFINITY;const{state:e}=this,n=e.candidateBestCostGenerationByHopId;return(n instanceof Map?n.get(t):n[t])===e.candidateBestCostGeneration?e.candidateBestCostByHopId instanceof Map?e.candidateBestCostByHopId.get(t):e.candidateBestCostByHopId[t]:Number.POSITIVE_INFINITY}setCandidateBestCost(t,e){if(t<0)return this.candidateOverflowBestCost||(this.candidateOverflowBestCost=new Map),void this.candidateOverflowBestCost.set(t,e);const{state:n}=this;n.candidateBestCostGenerationByHopId instanceof Map?n.candidateBestCostGenerationByHopId.set(t,n.candidateBestCostGeneration):n.candidateBestCostGenerationByHopId[t]=n.candidateBestCostGeneration,n.candidateBestCostByHopId instanceof Map?n.candidateBestCostByHopId.set(t,e):n.candidateBestCostByHopId[t]=e}getHopId(t,e){const n=t*this.candidateHopSlotStride;if(this.candidateFirstRegionByPortId[t]===e)return n;if(this.candidateSecondRegionByPortId[t]===e)return n+1;const o=this.topology.incidentPortRegion[t];for(let t=2;t<(o?.length??0);t++)if(o[t]===e)return n+t;return-(t*this.topology.regionCount+e)-1}getStartingNextRegionId(t,e){const n=this.topology.incidentPortRegion[e]??[],o=this.problem.routeNet[t];return n.find(t=>-1===this.problem.regionNetId[t])??n.find(t=>this.problem.regionNetId[t]===o)??n[0]}getRouteStartPortId(t){return this.problem.routeStartPort[t]}getRouteEndPortId(t){return this.problem.routeEndPort[t]}isPortReservedForDifferentNet(t){const e=this.problemSetup.portEndpointReservationNetId[t]??-1;return-2===e||-1!==e&&e!==this.state.currentRouteNetId}isRegionReservedForDifferentNet(t){const e=this.problem.regionNetId[t];return-1!==e&&e!==this.state.currentRouteNetId}isKnownSingleLayerRegion(t){const e=this.topology.regionAvailableZMask?.[t]??0;return Xz(e)}computeRegionCostForRegion(t,e,n,o,i){return((t,e,n,o,i,r,s=0,a=.3,c=0)=>Vz(t*e,n,o,i,r,s,a,c))(this.topology.regionWidth[t],this.topology.regionHeight[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0,this.minViaPadDiameter,this.TRACE_DENSITY_COST_FACTOR)}populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.segmentGeometryScratch,r=this.candidateFirstRegionByPortId[e]===t||this.candidateSecondRegionByPortId[e]!==t?o.portAngleForRegion1[e]:o.portAngleForRegion2?.[e]??o.portAngleForRegion1[e],s=this.candidateFirstRegionByPortId[n]===t||this.candidateSecondRegionByPortId[n]!==t?o.portAngleForRegion1[n]:o.portAngleForRegion2?.[n]??o.portAngleForRegion1[n],a=o.portZ[e],c=o.portZ[n];return i.lesserAngle=r<s?r:s,i.greaterAngle=r<s?s:r,i.layerMask=1<<a|1<<c,i.entryExitLayerChanges=a!==c?1:0,i}appendSegmentToRegionCache(t,e,n){const{state:o}=this,i=o.regionIntersectionCaches[t],r=this.populateSegmentGeometryScratch(t,e,n),[s,a,c]=Hz(i,o.currentRouteNetId,r.lesserAngle,r.greaterAngle,r.layerMask,r.entryExitLayerChanges),l=i.netIds.length+1,d=new Int32Array(l);d.set(i.netIds),d[l-1]=o.currentRouteNetId;const h=new Int32Array(l);h.set(i.lesserAngles),h[l-1]=r.lesserAngle;const u=new Int32Array(l);u.set(i.greaterAngles),u[l-1]=r.greaterAngle;const p=new Int32Array(l);p.set(i.layerMasks),p[l-1]=r.layerMask;const m=i.existingSameLayerIntersections+s,g=i.existingCrossingLayerIntersections+a,f=i.existingEntryExitLayerChanges+c,y=h.length;o.regionIntersectionCaches[t]={netIds:d,lesserAngles:h,greaterAngles:u,layerMasks:p,existingSameLayerIntersections:m,existingCrossingLayerIntersections:g,existingEntryExitLayerChanges:f,existingSegmentCount:y,existingRegionCost:this.computeRegionCostForRegion(t,m,g,f,y)}}getSolvedPathSegments(t){const{state:e}=this,n=[];let o=t;for(;o;)n.unshift(o),o=o.prevCandidate;const i=[];for(let t=1;t<n.length;t++)i.push({regionId:n[t-1].nextRegionId,fromPortId:n[t-1].portId,toPortId:n[t].portId});const r=n[n.length-1];return r&&r.portId!==e.goalPortId&&i.push({regionId:r.nextRegionId,fromPortId:r.portId,toPortId:e.goalPortId}),i}resetRoutingStateForRerip(){const{topology:t,problem:e,state:n}=this;n.portAssignment.fill(-1),n.regionSegments=Array.from({length:t.regionCount},()=>[]),n.regionIntersectionCaches=Array.from({length:t.regionCount},()=>qF()),n.currentRouteNetId=void 0,n.currentRouteId=void 0,n.unroutedRoutes=qz(oF(e.routeCount),n.ripCount),n.candidateQueue.clear(),this.resetCandidateBestCosts(),n.goalPortId=-1}getMaxRegionCost(){const{topology:t,state:e}=this;let n=0;for(let o=0;o<t.regionCount;o++){const t=e.regionIntersectionCaches[o]?.existingRegionCost??0;n=Math.max(n,t)}return n}getRouteMetadata(t){return this.problem.routeMetadata?.[t]}getRouteConnectionId(t){const e=this.getRouteMetadata(t)?.connectionId;return"string"==typeof e?e:`route-${t}`}getRouteSummary(t){return(({problem:t,routeId:e,getRouteMetadata:n,getRouteConnectionId:o})=>{const i=n?.(e)??Jz(t,e);return{routeId:e,connectionId:o?.(e)??Qz(t,e),startPortId:t.routeStartPort[e],endPortId:t.routeEndPort[e],startRegionId:"string"==typeof i?.startRegionId?i.startRegionId:void 0,endRegionId:"string"==typeof i?.endRegionId?i.endRegionId:void 0,pointIds:Kz(i)}})({problem:this.problem,routeId:t,getRouteMetadata:t=>this.getRouteMetadata(t),getRouteConnectionId:t=>this.getRouteConnectionId(t)})}getAdditionalRegionLabel(t){}getNeverSuccessfullyRoutedRoutes(){const t=[];for(let e=0;e<this.problem.routeCount;e++){const n=this.routeAttemptCountByRouteId[e];0===n||this.routeSuccessCountByRouteId[e]>0||t.push({...this.getRouteSummary(e),attempts:n})}return t}getStaticallyUnroutableRoutes(){return this.staticallyUnroutableRoutes}logNeverSuccessfullyRoutedRoutes(){if(!this.VERBOSE||this.hasLoggedNeverSuccessfullyRoutedRoutes)return;const t=this.getNeverSuccessfullyRoutedRoutes();if(this.hasLoggedNeverSuccessfullyRoutedRoutes=!0,0!==t.length){console.log(["[TinyHyperGraphSolver:never-routed-summary]",`count=${t.length}`].join(" "));for(const e of t){const t=e.pointIds.length>=2?`${e.pointIds[0]}->${e.pointIds[1]}`:"unknown";console.log(["[TinyHyperGraphSolver:never-routed]",`routeId=${e.routeId}`,`connectionId=${e.connectionId}`,`attempts=${e.attempts}`,`pointPath=${t}`,`startRegionId=${e.startRegionId??"unknown"}`,`endRegionId=${e.endRegionId??"unknown"}`].join(" "))}}}logRipEvent(t,e,n={}){this.VERBOSE&&console.log(["[TinyHyperGraphSolver:rip]",`ripCount=${this.state.ripCount}`,`maxRegionCostBeforeRip=${e.toFixed(3)}`,`reason=${t}`,...Object.entries(n).map(([t,e])=>`${t}=${"number"==typeof e?Number.isInteger(e)?String(e):e.toFixed(3):e}`)].join(" "))}compareRegionCostSummaries(t,e){return t.maxRegionCost!==e.maxRegionCost?t.maxRegionCost-e.maxRegionCost:t.totalRegionCost-e.totalRegionCost}captureBestSolvedState(t){this.bestSolvedStateSummary&&this.compareRegionCostSummaries(t,this.bestSolvedStateSummary)>=0||this.replaceBestSolvedState(t)}replaceBestSolvedState(t){this.bestSolvedStateSummary=t,this.bestSolvedStateSnapshot=KF({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches,regionCongestionCost:this.state.regionCongestionCost,ripCount:this.state.ripCount})}restoreBestSolvedState(){if(!this.bestSolvedStateSnapshot)return;const t=KF(this.bestSolvedStateSnapshot);this.state.portAssignment=t.portAssignment,this.state.regionSegments=t.regionSegments,this.state.regionIntersectionCaches=t.regionIntersectionCaches,this.state.regionCongestionCost=t.regionCongestionCost,this.state.ripCount=t.ripCount,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1}getRemainingRouteIdsForGreedyFinalRoute(){const t=new Set(this.state.unroutedRoutes);return void 0!==this.state.currentRouteId&&t.add(this.state.currentRouteId),[...t]}applySnapshotToGreedyFinalRouteSolver(t,e,n){const o=KF(e);t.state.portAssignment=o.portAssignment,t.state.regionSegments=o.regionSegments,t.state.regionIntersectionCaches=o.regionIntersectionCaches,t.state.regionCongestionCost=o.regionCongestionCost,t.state.ripCount=0,t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.state.unroutedRoutes=[...n],t.state.candidateQueue.clear(),t.resetCandidateBestCosts(),t.state.goalPortId=-1}summarizeSolvedState(t){let e=0,n=0;for(const o of t.state.regionIntersectionCaches){const t=o.existingRegionCost;e=Math.max(e,t),n+=t}return{maxRegionCost:e,totalRegionCost:n}}tryGreedyFinalRouteAcceptance(){const t=Math.max(0,Math.floor(this.GREEDY_FINAL_ROUTE_ITERS));if(0===t)return!1;const e=this.getRemainingRouteIdsForGreedyFinalRoute();if(0===e.length)return!1;const n=KF({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches,regionCongestionCost:this.state.regionCongestionCost,ripCount:this.state.ripCount});for(let o=0;o<t;o++){const t=0===o?e:qz(e,this.state.ripCount+o),i=new oB(this.topology,this.problem,{...tB(this),ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!1,GREEDY_FINAL_ROUTE_ITERS:0,MAX_ITERATIONS:ZF,RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!1});if(this.applySnapshotToGreedyFinalRouteSolver(i,n,t),i.solve(),i.solved&&!i.failed)return this.bestSolvedStateSnapshot=KF({portAssignment:i.state.portAssignment,regionSegments:i.state.regionSegments,regionIntersectionCaches:i.state.regionIntersectionCaches,regionCongestionCost:i.state.regionCongestionCost,ripCount:i.state.ripCount}),this.bestSolvedStateSummary=this.summarizeSolvedState(i),this.restoreBestSolvedState(),this.stats={...this.stats,acceptedGreedyFinalRouteOnTimeout:!0,greedyFinalRouteIter:o,greedyFinalRouteRemainingRouteCount:e.length,greedyFinalRouteMaxIterations:ZF,neverSuccessfullyRoutedRouteCount:0,maxRegionCost:this.bestSolvedStateSummary.maxRegionCost,totalRegionCost:this.bestSolvedStateSummary.totalRegionCost,bestMaxRegionCost:this.bestSolvedStateSummary.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary.totalRegionCost},this.solved=!0,this.failed=!1,this.error=null,!0}return this.stats={...this.stats,greedyFinalRouteAttemptCount:t,greedyFinalRouteRemainingRouteCount:e.length,greedyFinalRouteMaxIterations:ZF},!1}onAllRoutesRouted(){const{topology:t,state:e}=this,n=this.RIP_THRESHOLD_RAMP_ATTEMPTS<=0?1:Math.min(1,e.ripCount/this.RIP_THRESHOLD_RAMP_ATTEMPTS),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(t.regionCount);let s=0,a=0;for(let n=0;n<t.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;r[n]=t,s=Math.max(s,t),a+=t,t>o&&i.push(n)}if(this.captureBestSolvedState({maxRegionCost:s,totalRegionCost:a}),this.stats={...this.stats,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:s,totalRegionCost:a,bestMaxRegionCost:this.bestSolvedStateSummary?.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary?.totalRegionCost,ripCount:e.ripCount},0===i.length||e.ripCount>=this.RIP_THRESHOLD_RAMP_ATTEMPTS)this.solved=!0;else{for(let n=0;n<t.regionCount;n++)e.regionCongestionCost[n]+=r[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCostBeforeRip:s,reripRegionCount:i.length},this.logRipEvent("hot_regions",s,{hotRegionCount:i.length,currentRipThreshold:o})}}onOutOfCandidates(){const{topology:t,state:e}=this,n=e.currentRouteId,o=this.getMaxRegionCost();for(let n=0;n<t.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;e.regionCongestionCost[n]+=t*this.RIP_CONGESTION_REGION_COST_FACTOR}e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCost:o,maxRegionCostBeforeRip:o,reripReason:"out_of_candidates"},this.logRipEvent("out_of_candidates",o,{...void 0===n?{}:{routeId:n,connectionId:this.getRouteConnectionId(n)}})}onPathFound(t){const{state:e}=this,n=e.currentRouteId;if(void 0===n)return;this.routeSuccessCountByRouteId[n]+=1;const o=this.getSolvedPathSegments(t);for(const{regionId:t,fromPortId:i,toPortId:r}of o)e.regionSegments[t].push([n,i,r]),e.portAssignment[i]=e.currentRouteNetId,e.portAssignment[r]=e.currentRouteNetId,this.appendSegmentToRegionCache(t,i,r);e.candidateQueue.clear(),e.currentRouteNetId=void 0,e.currentRouteId=void 0}computeG(t,e,n=Number.POSITIVE_INFINITY,o){const{state:i,topology:r}=this,s=t.nextRegionId,a=i.regionIntersectionCaches[s];let c=0;if(this.ADD_SEGMENT_DISTANCE_TO_G){let n=o;if(void 0===n){const o=r.portX[t.portId]-r.portX[e],i=r.portY[t.portId]-r.portY[e];n=Math.sqrt(o*o+i*i)}c=n*this.DISTANCE_TO_COST}if(t.g+i.regionCongestionCost[s]+(this.problem.portPenalty?.[e]??0)+c>n+1e-9)return Number.POSITIVE_INFINITY;const l=t.portId,d=this.candidateFirstRegionByPortId[l]===s||this.candidateSecondRegionByPortId[l]!==s?r.portAngleForRegion1[l]:r.portAngleForRegion2?.[l]??r.portAngleForRegion1[l],h=this.candidateFirstRegionByPortId[e]===s||this.candidateSecondRegionByPortId[e]!==s?r.portAngleForRegion1[e]:r.portAngleForRegion2?.[e]??r.portAngleForRegion1[e],u=d<h?d:h,p=d<h?h:d,m=r.portZ[l],g=r.portZ[e],f=1<<m|1<<g,y=m!==g?1:0,[_,b,x]=Hz(a,i.currentRouteNetId,u,p,f,y);if(_>0&&this.isKnownSingleLayerRegion(s))return Number.POSITIVE_INFINITY;const v=this.computeRegionCostForRegion(s,a.existingSameLayerIntersections+_,a.existingCrossingLayerIntersections+b,a.existingEntryExitLayerChanges+x,a.existingSegmentCount+1)-a.existingRegionCost;return t.g+v+i.regionCongestionCost[s]+(this.problem.portPenalty?.[e]??0)+c}tryFinalAcceptance(){const t=this.getNeverSuccessfullyRoutedRoutes();if(this.stats={...this.stats,neverSuccessfullyRoutedRouteCount:t.length},this.ACCEPT_BEST_SOLUTION_ON_TIMEOUT&&this.bestSolvedStateSnapshot&&this.bestSolvedStateSummary)return this.restoreBestSolvedState(),this.stats={...this.stats,acceptedBestSolutionOnTimeout:!0,maxRegionCost:this.bestSolvedStateSummary.maxRegionCost,totalRegionCost:this.bestSolvedStateSummary.totalRegionCost,bestMaxRegionCost:this.bestSolvedStateSummary.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary.totalRegionCost},this.solved=!0,this.failed=!1,void(this.error=null);this.ACCEPT_BEST_SOLUTION_ON_TIMEOUT&&this.tryGreedyFinalRouteAcceptance()||this.logNeverSuccessfullyRoutedRoutes()}computeH(t){const e=this.problemSetup.portHCostToEndOfRoute;if(e)return e[t*this.problem.routeCount+this.state.currentRouteId];const n=this.getRouteEndPortId(this.state.currentRouteId),o=this.topology.portX[t]-this.topology.portX[n],i=this.topology.portY[t]-this.topology.portY[n];return Math.sqrt(o*o+i*i)*this.DISTANCE_TO_COST}visualize(){return UF(this)}getOutput(){return $z(this)}},oB=class extends nB{computeG(t,e){return t.g}},iB=class{constructor(t,e){this.regionCount=t,this.compactHopIndex=e,e&&(this.hopStateGeneration=new Uint32Array(e.hopCapacity),this.hopIndexOrClosed=new Int32Array(e.hopCapacity))}regionCount;compactHopIndex;items=[];indexByHopId=new Map;closedHopIds=new Set;hopStateGeneration;hopIndexOrClosed;currentHopStateGeneration=1;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0,this.indexByHopId.clear(),this.closedHopIds.clear(),this.hopStateGeneration&&(4294967295===this.currentHopStateGeneration?(this.hopStateGeneration.fill(0),this.currentHopStateGeneration=1):this.currentHopStateGeneration+=1)}isClosedHop(t,e){return this.isHopClosed(this.getHopIdFromValues(t,e))}queue(t){const e=this.getHopId(t);if(this.isHopClosed(e))return;const n=this.getQueuedHopIndex(e);if(void 0!==n){const e=this.items[n];if(t.g>=e.g)return;return this.items[n]=t,void(t.f<=e.f?this.siftUp(n):this.siftDown(n))}const o=this.items.length;this.items.push(t),this.siftUp(o)}dequeue(){const t=this.items[0];if(!t)return;const e=this.getHopId(t);this.closeHop(e);const n=this.items.pop();return this.items.length>0&&(this.items[0]=n,this.siftDown(0)),t}getHopId(t){return this.getHopIdFromValues(t.portId,t.nextRegionId)}getHopIdFromValues(t,e){const n=this.compactHopIndex;if(!n)return t*this.regionCount+e;const o=t*n.hopSlotStride;if(n.firstRegionByPortId[t]===e)return o;if(n.secondRegionByPortId[t]===e)return o+1;const i=n.incidentPortRegion[t];for(let t=2;t<(i?.length??0);t++)if(i[t]===e)return o+t;return-(t*this.regionCount+e)-1}getQueuedHopIndex(t){if(t>=0&&this.hopStateGeneration?.[t]===this.currentHopStateGeneration){const e=this.hopIndexOrClosed[t];return e>=0?e:void 0}return this.indexByHopId.get(t)}isHopClosed(t){return t>=0&&this.hopStateGeneration?.[t]===this.currentHopStateGeneration?-1===this.hopIndexOrClosed[t]:this.closedHopIds.has(t)}setQueuedHopIndex(t,e){if(t>=0&&this.hopStateGeneration)return this.hopStateGeneration[t]=this.currentHopStateGeneration,void(this.hopIndexOrClosed[t]=e);this.indexByHopId.set(t,e)}closeHop(t){if(t>=0&&this.hopStateGeneration)return this.hopStateGeneration[t]=this.currentHopStateGeneration,void(this.hopIndexOrClosed[t]=-1);this.indexByHopId.delete(t),this.closedHopIds.add(t)}siftUp(t){const e=this.items[t];let n=t;for(;n>0;){const t=n-1>>1,o=this.items[t];if(o.f<=e.f)break;this.items[n]=o,this.setQueuedHopIndex(this.getHopId(o),n),n=t}this.items[n]=e,this.setQueuedHopIndex(this.getHopId(e),n)}siftDown(t){const e=this.items[t];let n=t;for(;;){const t=2*n+1;if(t>=this.items.length)break;const o=t+1,i=o<this.items.length&&this.items[o].f<this.items[t].f?o:t,r=this.items[i];if(e.f<=r.f)break;this.items[n]=r,this.setQueuedHopIndex(this.getHopId(r),n),n=i}this.items[n]=e,this.setQueuedHopIndex(this.getHopId(e),n)}},rB=class extends nB{constructor(t,e,n){super(t,e,n),this.ADD_SEGMENT_DISTANCE_TO_G=!0}_setup(){super._setup(),this.state.candidateQueue=new iB(this.topology.regionCount,{hopCapacity:this.candidateHopCapacity,hopSlotStride:this.candidateHopSlotStride,firstRegionByPortId:this.candidateFirstRegionByPortId,secondRegionByPortId:this.candidateSecondRegionByPortId,incidentPortRegion:this.topology.incidentPortRegion})}onPathFound(t){const e=this.state.goalPortId;if(t.portId===e)return void super.onPathFound(t);const n=this.computeG(t,e);if(!Number.isFinite(n))return;const o=this.getHopId(e,t.nextRegionId);n>=this.getCandidateBestCost(o)||(this.setCandidateBestCost(o,n),this.state.candidateQueue.queue({prevRegionId:t.nextRegionId,nextRegionId:t.nextRegionId,portId:e,g:n,h:0,f:n,prevCandidate:t}))}},sB=new Set,aB=class extends rB{partialRipRoutePlans=new Map;outsideInRouteSearch;oneSidedFallbackRouteId;partialRipWindowDistance;partialRipCount=0;partiallyRippedRouteCount=0;partiallyRippedSegmentCount=0;retainedPartialRipSegmentCount=0;outsideInRouteCount=0;outsideInCompletedRouteCount=0;outsideInFallbackRouteCount=0;outsideInForwardExpansionCount=0;outsideInReverseExpansionCount=0;outsideInDistancePruneCount=0;completedRoundSummaries=[];firstCompletedRoundSummary;partialRipQualityBaselineSummary;bestSolvedRoundSummary;partialRipTargetReached=!1;useComplexityAwareSelection=!1;constructor(t,e,n){super(t,e,n),void 0===n?.PARTIAL_RIP_ENABLED&&(this.PARTIAL_RIP_ENABLED=!0),void 0===n?.OUTSIDE_IN_ROUTING&&(this.OUTSIDE_IN_ROUTING=!0),this.PARTIAL_RIP_ENABLED&&void 0===n?.PARTIAL_RIP_MAX_ATTEMPTS&&(this.PARTIAL_RIP_MAX_ATTEMPTS=10),(e.routeCount<Math.max(0,this.PARTIAL_RIP_MIN_ROUTE_COUNT)||e.routeCount>Math.max(0,this.PARTIAL_RIP_MAX_ROUTE_COUNT))&&(this.PARTIAL_RIP_ENABLED=!1,this.OUTSIDE_IN_ROUTING=!1),this.useComplexityAwareSelection=e.routeCount>=Math.max(0,this.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT)}getRouteStartPortId(t){return this.PARTIAL_RIP_ENABLED?this.partialRipRoutePlans.get(t)?.activeStartPortId??super.getRouteStartPortId(t):super.getRouteStartPortId(t)}getRouteEndPortId(t){return this.PARTIAL_RIP_ENABLED?this.partialRipRoutePlans.get(t)?.activeEndPortId??super.getRouteEndPortId(t):super.getRouteEndPortId(t)}getStartingNextRegionId(t,e){if(!this.PARTIAL_RIP_ENABLED)return super.getStartingNextRegionId(t,e);const n=this.partialRipRoutePlans.get(t);return n&&n.activeStartPortId===e?n.forcedStartRegionId:super.getStartingNextRegionId(t,e)}getEndingNextRegionId(t,e){const n=this.partialRipRoutePlans.get(t);return n&&n.activeEndPortId===e?n.forcedEndRegionId:super.getStartingNextRegionId(t,e)}computeH(t){if(!this.PARTIAL_RIP_ENABLED)return super.computeH(t);const e=this.state.currentRouteId;if(void 0===e||!this.partialRipRoutePlans.has(e))return super.computeH(t);const n=this.getRouteEndPortId(e),o=this.topology.portX[t]-this.topology.portX[n],i=this.topology.portY[t]-this.topology.portY[n];return Math.sqrt(o*o+i*i)*this.DISTANCE_TO_COST}onPathFound(t){if(!this.PARTIAL_RIP_ENABLED&&!this.OUTSIDE_IN_ROUTING)return void super.onPathFound(t);const e=this.state.currentRouteId,n=void 0!==e&&this.outsideInRouteSearch?.routeId===e;super.onPathFound(t),void 0!==e&&void 0===this.state.currentRouteId&&(this.partialRipRoutePlans.delete(e),n&&(this.outsideInCompletedRouteCount+=1),this.oneSidedFallbackRouteId===e&&(this.oneSidedFallbackRouteId=void 0)),this.outsideInRouteSearch=void 0,this.publishOutsideInStats()}resetRoutingStateForRerip(){this.PARTIAL_RIP_ENABLED||this.OUTSIDE_IN_ROUTING?(this.partialRipRoutePlans.clear(),this.outsideInRouteSearch=void 0,this.oneSidedFallbackRouteId=void 0,super.resetRoutingStateForRerip()):super.resetRoutingStateForRerip()}clearPartialRipPlans(t){for(const e of t)this.partialRipRoutePlans.delete(e)}getRouteIdsPreferredForPreservation(){return sB}getCommittedRouteSegments(t){const e=[];for(let n=0;n<this.state.regionSegments.length;n++)for(const[o,i,r]of this.state.regionSegments[n]??[])o===t&&e.push({segmentIndex:e.length,regionId:n,fromPortId:i,toPortId:r});if(0===e.length)return;const n=new Map;for(const t of e)for(const e of[t.fromPortId,t.toPortId]){const o=n.get(e)??[];o.push(t.segmentIndex),n.set(e,o)}const o=this.problem.routeEndPort[t],i=[],r=new Set,s=new Set([this.problem.routeStartPort[t]]),a=t=>{if(t===o)return!0;for(const o of n.get(t)??[]){if(r.has(o))continue;const n=e[o],c=n.fromPortId===t?n.toPortId:n.fromPortId;if(!s.has(c)){if(r.add(o),s.add(c),i.push({regionId:n.regionId,fromPortId:t,toPortId:c}),a(c))return!0;i.pop(),s.delete(c),r.delete(o)}}return!1};return a(this.problem.routeStartPort[t])&&r.size===e.length?i:void 0}getSegmentDistance(t){const e=this.topology.portX[t.fromPortId]-this.topology.portX[t.toPortId],n=this.topology.portY[t.fromPortId]-this.topology.portY[t.toPortId];return Math.sqrt(e*e+n*n)}getPartialRipWindow(t,e,n){let o,i=Number.NEGATIVE_INFINITY;for(let r=0;r<t.length;r++){const s=t[r];if(!e.has(s.regionId))continue;const a=n[s.regionId]??0;a>i&&(i=a,o=r)}if(void 0===o)return;const r=Math.max(0,this.partialRipWindowDistance??this.PARTIAL_RIP_MAX_DISTANCE);let s=o,a=o,c=this.getSegmentDistance(t[o])/2,l=c;for(;s>0;){const e=this.getSegmentDistance(t[s-1]);if(c+e>r)break;s-=1,c+=e}for(;a+1<t.length;){const e=this.getSegmentDistance(t[a+1]);if(l+e>r)break;a+=1,l+=e}return{startIndex:s,endIndex:a}}appendRetainedSegment(t,e,n){t[n.regionId].push([e,n.fromPortId,n.toPortId])}preparePartialRip(t,e){if(!this.PARTIAL_RIP_ENABLED||0===t.length)return!1;const n=new Set(t);if(void 0===this.partialRipWindowDistance){let n=0;for(const o of t)n=Math.max(n,e[o]??0);const o=Math.max(0,this.PARTIAL_RIP_MAX_DISTANCE),i=Math.max(o,this.PARTIAL_RIP_QUALITY_MAX_DISTANCE??2*o);this.partialRipWindowDistance=n<=1.5*this.RIP_THRESHOLD_END?i:o}const o=new Set;for(const e of t)for(const[t]of this.state.regionSegments[e]??[])o.add(t);if(0===o.size)return!1;const i=this.getRouteIdsPreferredForPreservation(),r=[...o].some(t=>!i.has(t)),s=Array.from({length:this.topology.regionCount},()=>[]),a=new Map;let c=0,l=0;for(let t=0;t<this.problem.routeCount;t++){const d=this.getCommittedRouteSegments(t);if(!d)return!1;if(!o.has(t)||r&&i.has(t)){for(const e of d)this.appendRetainedSegment(s,t,e),l+=1;continue}const h=this.getPartialRipWindow(d,n,e);if(!h)return!1;for(let e=0;e<d.length;e++){const n=d[e];e>=h.startIndex&&e<=h.endIndex?c+=1:(this.appendRetainedSegment(s,t,n),l+=1)}const u=d[h.startIndex],p=d[h.endIndex];a.set(t,{routeId:t,activeStartPortId:u.fromPortId,activeEndPortId:p.toPortId,forcedStartRegionId:u.regionId,forcedEndRegionId:p.regionId,rippedSegmentCount:h.endIndex-h.startIndex+1,retainedSegmentCount:d.length-(h.endIndex-h.startIndex+1)})}return 0!==a.size&&0!==c&&(this.partialRipRoutePlans=a,this.rebuildRetainedRoutingState(s,[...a.keys()]),this.partialRipCount+=1,this.partiallyRippedRouteCount+=a.size,this.partiallyRippedSegmentCount+=c,this.retainedPartialRipSegmentCount+=l,this.publishPartialRipStats(),!0)}rebuildRetainedRoutingState(t,e){this.state.portAssignment.fill(-1),this.state.regionSegments=Array.from({length:this.topology.regionCount},()=>[]),this.state.regionIntersectionCaches=Array.from({length:this.topology.regionCount},()=>qF()),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=e,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.outsideInRouteSearch=void 0,this.oneSidedFallbackRouteId=void 0;for(let e=0;e<t.length;e++)for(const[n,o,i]of t[e]??[]){const t=this.problem.routeNet[n];this.state.currentRouteNetId=t;for(const e of[o,i]){const n=this.state.portAssignment[e];if(-1!==n&&n!==t)throw new Error(`OutsideInPartialRipTinyHyperGraphSolver: retained port ${e} belongs to multiple nets`);this.state.portAssignment[e]=t}this.state.regionSegments[e].push([n,o,i]),this.appendSegmentToRegionCache(e,o,i)}this.state.currentRouteNetId=void 0}publishPartialRipStats(){this.stats={...this.stats,partialRipCount:this.partialRipCount,partiallyRippedRouteCount:this.partiallyRippedRouteCount,partiallyRippedSegmentCount:this.partiallyRippedSegmentCount,retainedPartialRipSegmentCount:this.retainedPartialRipSegmentCount,partialRipMaxDistance:this.partialRipWindowDistance??this.PARTIAL_RIP_MAX_DISTANCE,partialRipBaseMaxDistance:this.PARTIAL_RIP_MAX_DISTANCE,partialRipQualityMaxDistance:this.PARTIAL_RIP_QUALITY_MAX_DISTANCE??2*this.PARTIAL_RIP_MAX_DISTANCE,partialRipMaxAttempts:this.PARTIAL_RIP_MAX_ATTEMPTS}}publishOutsideInStats(){this.stats={...this.stats,outsideInRouteCount:this.outsideInRouteCount,outsideInCompletedRouteCount:this.outsideInCompletedRouteCount,outsideInFallbackRouteCount:this.outsideInFallbackRouteCount,outsideInForwardExpansionCount:this.outsideInForwardExpansionCount,outsideInReverseExpansionCount:this.outsideInReverseExpansionCount,outsideInDistancePruneCount:this.outsideInDistancePruneCount,outsideInMaxDistance:this.OUTSIDE_IN_MAX_DISTANCE}}createOutsideInFrontier(t,e,n){const o=new Zz([],(t,e)=>t.f===e.f?t.g-e.g:t.f-e.f),i=this.topology.portX[t]-this.topology.portX[n],r=this.topology.portY[t]-this.topology.portY[n],s=Math.sqrt(i*i+r*r)*this.DISTANCE_TO_COST,a={portId:t,nextRegionId:e,f:s,g:0,h:s,travelDistance:0};return o.queue(a),{queue:o,bestCostByHopId:new Map([[this.getHopId(t,e),0]]),settledByPortId:new Map,settledByRegionId:new Map,targetPortId:n}}startOutsideInRouteSearch(t){const e=this.getRouteStartPortId(t),n=this.getRouteEndPortId(t),o=this.getStartingNextRegionId(t,e),i=this.getEndingNextRegionId(t,n);return void 0!==o&&void 0!==i&&(this.state.goalPortId=n,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.outsideInRouteSearch={routeId:t,forward:this.createOutsideInFrontier(e,o,n),reverse:this.createOutsideInFrontier(n,i,e),expandForwardNext:!0,distanceLimitHit:!1,bestJoinedCost:Number.POSITIVE_INFINITY},this.outsideInRouteCount+=1,this.publishOutsideInStats(),!0)}dequeueFreshCandidate(t){for(;t.queue.length>0;){const e=t.queue.dequeue(),n=this.getHopId(e.portId,e.nextRegionId);if(e.g<=(t.bestCostByHopId.get(n)??1/0))return e}}recordSettledCandidate(t,e){const n=t.settledByPortId.get(e.portId);(!n||e.g<n.g)&&t.settledByPortId.set(e.portId,e);const o=t.settledByRegionId.get(e.nextRegionId)??[];o.push(e),o.sort((t,e)=>t.g-e.g),o.length>16&&(o.length=16),t.settledByRegionId.set(e.nextRegionId,o)}getCandidatePath(t){const e=[];let n=t;for(;n;)e.push(n),n=n.prevCandidate;return e.reverse(),e}buildJoinedCandidate(t,e){const n=this.getCandidatePath(t),o=this.getCandidatePath(e),i=n.map(({portId:t})=>t),r=n.slice(0,-1).map(({nextRegionId:t})=>t);if(t.portId!==e.portId){if(t.nextRegionId!==e.nextRegionId)return;const n=this.topology.portX[t.portId]-this.topology.portX[e.portId],o=this.topology.portY[t.portId]-this.topology.portY[e.portId],s=Math.sqrt(n*n+o*o);if(t.travelDistance+e.travelDistance+s>2*this.OUTSIDE_IN_MAX_DISTANCE)return;const a=this.computeG(t,e.portId);if(!Number.isFinite(a))return;r.push(t.nextRegionId),i.push(e.portId)}for(let t=o.length-2;t>=0;t--){const e=o[t];r.push(e.nextRegionId),i.push(e.portId)}if(new Set(i).size!==i.length||r.length+1!==i.length)return;let s={portId:i[0],nextRegionId:r[0],f:0,g:0,h:0};for(let t=1;t<i.length;t++)s={portId:i[t],prevRegionId:r[t-1],nextRegionId:r[t]??r[t-1],prevCandidate:s,f:0,g:0,h:0};const a=t.portId===e.portId?0:this.computeG(t,e.portId)-t.g;return{candidate:s,cost:t.g+e.g+a}}considerOutsideInJoins(t,e){const n=this.outsideInRouteSearch,o=e?n.reverse:n.forward,i=t=>{!t||t.cost>=n.bestJoinedCost||(n.bestJoinedCandidate=t.candidate,n.bestJoinedCost=t.cost,n.remainingPostMeetingExpansions=24)},r=o.settledByPortId.get(t.portId);r&&i(e?this.buildJoinedCandidate(t,r):this.buildJoinedCandidate(r,t));for(const n of o.settledByRegionId.get(t.nextRegionId)??[])i(e?this.buildJoinedCandidate(t,n):this.buildJoinedCandidate(n,t))}commitBestOutsideInJoin(){const t=this.outsideInRouteSearch?.bestJoinedCandidate;return!!t&&(this.onPathFound(t),!0)}expandOutsideInFrontier(t){const e=this.outsideInRouteSearch,n=t?e.forward:e.reverse,o=this.dequeueFreshCandidate(n);if(!o)return!1;if(t?this.outsideInForwardExpansionCount+=1:this.outsideInReverseExpansionCount+=1,this.isRegionReservedForDifferentNet(o.nextRegionId))return!0;this.recordSettledCandidate(n,o),this.considerOutsideInJoins(o,t);for(const t of this.topology.regionIncidentPorts[o.nextRegionId]??[]){if(t===o.portId)continue;if(this.isPortReservedForDifferentNet(t))continue;const i=this.state.portAssignment[t];if(-1!==i&&i!==this.state.currentRouteNetId)continue;if(t!==n.targetPortId&&0===this.problem.portSectionMask[t])continue;const r=this.topology.portX[o.portId]-this.topology.portX[t],s=this.topology.portY[o.portId]-this.topology.portY[t],a=Math.sqrt(r*r+s*s),c=o.travelDistance+a;if(c>this.OUTSIDE_IN_MAX_DISTANCE){e.distanceLimitHit=!0,this.outsideInDistancePruneCount+=1;continue}const l=this.topology.incidentPortRegion[t]?.[0]===o.nextRegionId?this.topology.incidentPortRegion[t]?.[1]:this.topology.incidentPortRegion[t]?.[0];if(void 0===l||this.isRegionReservedForDifferentNet(l))continue;const d=this.getHopId(t,l),h=n.bestCostByHopId.get(d)??1/0;if(o.g>=h)continue;const u=this.computeG(o,t,h,a);if(!Number.isFinite(u)||u>=h)continue;n.bestCostByHopId.set(d,u);const p=this.topology.portX[t]-this.topology.portX[n.targetPortId],m=this.topology.portY[t]-this.topology.portY[n.targetPortId],g=Math.sqrt(p*p+m*m)*this.DISTANCE_TO_COST;n.queue.queue({portId:t,prevRegionId:o.nextRegionId,nextRegionId:l,prevCandidate:o,f:u+g,g:u,h:g,travelDistance:c})}return!0}fallBackToOneSidedRouteSearch(){const t=this.state.currentRouteId;void 0!==t&&(this.outsideInRouteSearch=void 0,this.outsideInFallbackRouteCount+=1,this.oneSidedFallbackRouteId=t,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.goalPortId=-1,this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.unroutedRoutes.unshift(t),this.publishOutsideInStats())}_step(){if(!this.OUTSIDE_IN_ROUTING)return void super._step();const t=this.state.currentRouteId??this.state.unroutedRoutes[0];if(void 0!==t&&!this.partialRipRoutePlans.has(t))return void super._step();if(void 0!==this.oneSidedFallbackRouteId)return void super._step();if(void 0===this.state.currentRouteId){if(0===this.state.unroutedRoutes.length)return void this.onAllRoutesRouted();const t=this.state.unroutedRoutes.shift();if(this.state.currentRouteId=t,this.state.currentRouteNetId=this.problem.routeNet[t],this.routeAttemptCountByRouteId[t]+=1,!this.startOutsideInRouteSearch(t))return this.failed=!0,void(this.error=`Route ${t} has an endpoint without an incident region`)}const e=this.outsideInRouteSearch;if(!e)return;let n=this.expandOutsideInFrontier(e.expandForwardNext);if(void 0!==this.state.currentRouteId&&(n||(n=this.expandOutsideInFrontier(!e.expandForwardNext),void 0!==this.state.currentRouteId)))if(e.expandForwardNext=!e.expandForwardNext,e.bestJoinedCandidate&&(e.remainingPostMeetingExpansions=(e.remainingPostMeetingExpansions??1)-1,(e.remainingPostMeetingExpansions??0)<=0))this.commitBestOutsideInJoin();else{if(!n&&0===e.forward.queue.length&&0===e.reverse.queue.length){if(this.commitBestOutsideInJoin())return;this.outsideInRouteSearch=void 0,e.distanceLimitHit?this.fallBackToOneSidedRouteSearch():this.onOutOfCandidates()}this.publishOutsideInStats()}}shouldReplaceBestSolvedState(t){const e=this.bestSolvedRoundSummary;if(!e)return!0;if(!this.useComplexityAwareSelection)return this.compareRegionCostSummaries(t,e)<0;const n=this.partialRipQualityBaselineSummary;if(!n)return this.compareRegionCostSummaries(t,e)<0;const o=this.firstCompletedRoundSummary??n,i=o.maxRegionCost*(1+Math.max(0,this.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO)),r=o.totalRegionCost*(1+Math.max(0,this.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO)),s=t.maxRegionCost<=i&&t.totalRegionCost<=r;return s!==(e.maxRegionCost<=i&&e.totalRegionCost<=r)?s:s&&t.segmentCount!==e.segmentCount?t.segmentCount<e.segmentCount:this.compareRegionCostSummaries(t,e)<0}onAllRoutesRouted(){if(!this.PARTIAL_RIP_ENABLED)return void super.onAllRoutesRouted();const{state:t,topology:e}=this,n=Math.min(this.RIP_THRESHOLD_RAMP_ATTEMPTS,this.PARTIAL_RIP_MAX_ATTEMPTS),o=Math.max(0,this.RIP_THRESHOLD_RAMP_ATTEMPTS),i=o<=0?1:Math.min(1,t.ripCount/o),r=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*i,s=new Float64Array(e.regionCount),a=[];let c=0,l=0,d=0,h=0,u=0;for(let n=0;n<e.regionCount;n++){const e=t.regionIntersectionCaches[n]?.existingRegionCost??0;s[n]=e,c=Math.max(c,e),l+=e;const o=t.regionSegments[n]?.length??0;d+=o,h=Math.max(h,o),u+=o*o,e>r&&a.push(n)}const p={maxRegionCost:c,totalRegionCost:l},m={...p,ripCount:t.ripCount,segmentCount:d,maxRegionSegmentCount:h,squaredRegionSegmentCount:u};this.completedRoundSummaries.push(m),this.firstCompletedRoundSummary??=m,void 0===this.partialRipQualityBaselineSummary&&t.ripCount>=Math.max(0,this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS)&&(this.partialRipQualityBaselineSummary=m);this.shouldReplaceBestSolvedState(m)&&(this.replaceBestSolvedState(p),this.bestSolvedRoundSummary=m);const g=this.firstCompletedRoundSummary,f=this.partialRipQualityBaselineSummary??g,y=Math.max(0,this.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO),_=Math.max(0,this.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO),b=f.maxRegionCost*(1-y),x=f.totalRegionCost*(1+_),v=this.useComplexityAwareSelection&&t.ripCount>f.ripCount&&y>0&&c<=b&&l<=x&&d<=f.segmentCount;if(v&&(this.partialRipTargetReached=!0),this.stats={...this.stats,currentRipThreshold:r,hotRegionCount:a.length,maxRegionCost:c,totalRegionCost:l,bestMaxRegionCost:this.bestSolvedStateSummary?.maxRegionCost,bestTotalRegionCost:this.bestSolvedStateSummary?.totalRegionCost,ripCount:t.ripCount,completedRoundSummaries:this.completedRoundSummaries.map(t=>({...t})),firstMaxRegionCost:g.maxRegionCost,firstTotalRegionCost:g.totalRegionCost,firstSegmentCount:g.segmentCount,firstMaxRegionSegmentCount:g.maxRegionSegmentCount,firstSquaredRegionSegmentCount:g.squaredRegionSegmentCount,partialRipQualityBaselineRipCount:f.ripCount,partialRipQualityBaselineMaxRegionCost:f.maxRegionCost,partialRipQualityBaselineTotalRegionCost:f.totalRegionCost,partialRipQualityBaselineSegmentCount:f.segmentCount,partialRipQualityBaselineMaxRegionSegmentCount:f.maxRegionSegmentCount,partialRipQualityBaselineSquaredRegionSegmentCount:f.squaredRegionSegmentCount,bestSolvedSegmentCount:this.bestSolvedRoundSummary?.segmentCount,bestSolvedMaxRegionSegmentCount:this.bestSolvedRoundSummary?.maxRegionSegmentCount,bestSolvedSquaredRegionSegmentCount:this.bestSolvedRoundSummary?.squaredRegionSegmentCount,partialRipTargetMaxRegionCost:b,partialRipMaxTargetTotalRegionCost:x,partialRipComplexityAwareSelection:this.useComplexityAwareSelection,partialRipComplexitySelectionMinRouteCount:this.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT,partialRipMaxRegionCostGrowthRatio:this.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO,partialRipTargetReached:this.partialRipTargetReached},this.publishPartialRipStats(),0===a.length||v||t.ripCount>=n)return this.restoreBestSolvedState(),void(this.solved=!0);for(let n=0;n<e.regionCount;n++)t.regionCongestionCost[n]+=s[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;const S=t.ripCount<Math.max(0,this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS);t.ripCount+=1;const I=!S&&this.preparePartialRip(a,s);I||this.resetRoutingStateForRerip();const C=S?"warmup_full":I?"partial":"full_fallback";this.stats={...this.stats,ripCount:t.ripCount,maxRegionCostBeforeRip:c,reripRegionCount:a.length,reripMode:C,partialRipWarmupFullRipAttempts:this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS},this.logRipEvent("hot_regions",c,{hotRegionCount:a.length,currentRipThreshold:r,reripMode:C,partialRouteCount:I?this.partialRipRoutePlans.size:0})}},cB=t=>{const e="number"==typeof t.d?.netId?t.d.netId:"number"==typeof t.d?.NetId?t.d.NetId:void 0;return Number.isFinite(e)?e:void 0},lB=t=>{const e=new Set;for(const n of t.connections??[])e.add(n.startRegionId),e.add(n.endRegionId);const n=new Set(t.regions.filter(t=>(t=>{if(!0!==t.d?._containsObstacle)return!1;const e=cB(t);return void 0===e||-1===e})(t)&&!e.has(t.regionId)).map(t=>t.regionId));if(0===n.size)return t;const o=t.ports.filter(t=>!n.has(t.region1Id)&&!n.has(t.region2Id)),i=(t.connections??[]).find(t=>n.has(t.startRegionId)||n.has(t.endRegionId));if(i)throw new Error(`Connection "${i.connectionId}" references full-obstacle region`);return{...t,regions:t.regions.filter(t=>!n.has(t.regionId)),ports:o}},dB=t=>{const e=t.d?.bounds;if(e)return e;const n=t.d?.center,o=t.d?.width,i=t.d?.height;return n&&"number"==typeof n.x&&"number"==typeof n.y&&"number"==typeof o&&"number"==typeof i?{minX:n.x-o/2,maxX:n.x+o/2,minY:n.y-i/2,maxY:n.y+i/2}:{minX:0,maxX:0,minY:0,maxY:0}},hB=t=>Number(t.d?.x??0),uB=t=>Number(t.d?.y??0),pB=(t,e)=>{if(!e)return 0;const n=dB(e),o=hB(t),i=uB(t),r=n.minX<=o&&o<=n.maxX,s=n.minY<=i&&i<=n.maxY;if(s&&o>=n.maxX){const t=Math.max(n.maxY-n.minY,1e-9),e=(i-n.minY)/t;return Math.round(9e3*e)}if(r&&i>=n.maxY){const t=Math.max(n.maxX-n.minX,1e-9),e=(n.maxX-o)/t;return 9e3+Math.round(9e3*e)}if(s&&o<=n.minX){const t=Math.max(n.maxY-n.minY,1e-9),e=(n.maxY-i)/t;return 18e3+Math.round(9e3*e)}if(r&&i<=n.minY){const t=Math.max(n.maxX-n.minX,1e-9),e=(o-n.minX)/t;return 27e3+Math.round(9e3*e)}const a=Math.abs(o-n.minX),c=Math.abs(o-n.maxX),l=Math.abs(i-n.minY),d=Math.abs(i-n.maxY),h=Math.min(a,c,l,d),u=Math.max(n.maxX-n.minX,1e-9),p=Math.max(n.maxY-n.minY,1e-9);if(h===c){const t=(i-n.minY)/p;return Math.round(9e3*t)}if(h===d){const t=(n.maxX-o)/u;return 9e3+Math.round(9e3*t)}if(h===a){const t=(n.maxY-i)/p;return 18e3+Math.round(9e3*t)}const m=(o-n.minX)/u;return 27e3+Math.round(9e3*m)},mB=(t,e)=>{if(!t)return;return[...t.pointIds].sort((t,n)=>{const o=e.get(t),i=e.get(n),r=Number(o?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY),s=Number(i?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY);if(r!==s)return r-s;const a=Number(o?.d?.z??0),c=Number(i?.d?.z??0);return a!==c?a-c:t.localeCompare(n)})[0]},gB=t=>{const e=lB(t),n=new Map,o=new Map,i=new Map,r=new Map((e.solvedRoutes??[]).map(t=>[t.connection.connectionId,t]));e.regions.forEach((t,e)=>{n.set(t.regionId,e)}),e.ports.forEach((t,e)=>{o.set(t.portId,e),i.set(t.portId,t)});const s=e.regions.length,a=e.ports.length,c=e.regions.map(t=>t.pointIds.map(t=>o.get(t)).filter(t=>void 0!==t)),l=Array.from({length:a},()=>[]),d=new Float64Array(s),h=new Float64Array(s),u=new Float64Array(s),p=new Float64Array(s),m=new Int32Array(s),g=new Int32Array(s).fill(-1),f=new Int8Array(s);e.regions.forEach((t,e)=>{const n=(t=>{const e=dB(t),n="number"==typeof t.d?.width?t.d.width:e.maxX-e.minX,o="number"==typeof t.d?.height?t.d.height:e.maxY-e.minY;return{centerX:"number"==typeof t.d?.center?.x?t.d.center.x:(e.minX+e.maxX)/2,centerY:"number"==typeof t.d?.center?.y?t.d.center.y:(e.minY+e.maxY)/2,width:n,height:o}})(t);d[e]=n.width,h[e]=n.height,u[e]=n.centerX,p[e]=n.centerY,m[e]=(t=>{const e=t.d?.availableZ;if(!Array.isArray(e))return 0;let n=0;for(const t of e)!Number.isInteger(t)||t<0||t>=31||(n|=1<<t);return n})(t);const o=cB(t);void 0!==o&&(g[e]=o,f[e]=1)});const y=new Int32Array(a),_=new Int32Array(a),b=new Float64Array(a),x=new Float64Array(a),v=new Int32Array(a);e.ports.forEach((t,o)=>{const i=n.get(t.region1Id),r=n.get(t.region2Id);if(void 0===i||void 0===r)throw new Error(`Port "${t.portId}" references missing regions "${t.region1Id}" or "${t.region2Id}"`);l[o]=[i,r],b[o]=hB(t),x[o]=uB(t),v[o]=(t=>{const e=Number(t.d?.z??0);return Number.isFinite(e)?e:0})(t),y[o]=pB(t,e.regions[i]),_[o]=pB(t,e.regions[r])});const S=e.regions.map((t,e)=>((t,e)=>{const n=t.d&&"object"==typeof t.d&&!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,"serializedRegionId",{value:t.regionId,enumerable:!1,configurable:!0,writable:!0}),n})(t,(t=>Rz(Ez(m[t]))??Rz((c[t]??[]).map(t=>v[t]))??"z0")(e))),I=e.ports.map((t,e)=>((t,e)=>{const n=t.d&&"object"==typeof t.d&&!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,"serializedPortId",{value:t.portId,enumerable:!1,configurable:!0,writable:!0}),n})(t,Rz([v[e]])??"z0")),C=e.connections??[],P=new Map;let M=0;const N=t=>{const e=t.mutuallyConnectedNetworkId??t.connectionId;let n=P.get(e);return void 0===n&&(n=M++,P.set(e,n)),n},w=Array.from({length:s},()=>new Set),T=(t,e)=>{const o=n.get(t);if(void 0===o)throw new Error(`Connection references missing region "${t}"`);w[o].add(e)};C.forEach(t=>{const e=N(t);T(t.startRegionId,e),T(t.endRegionId,e)}),w.forEach((t,e)=>{1!==f[e]&&1===t.size&&(g[e]=[...t][0])});const R=C.map(t=>{const n=r.get(t.connectionId),o=((t,e)=>t.ports.filter(t=>t.region1Id===e.startRegionId&&t.region2Id===e.endRegionId||t.region2Id===e.startRegionId&&t.region1Id===e.endRegionId).map(t=>t.portId))(e,t);return{connection:t,solvedRoute:n,sharedPortIds:o}}).filter(({solvedRoute:t,sharedPortIds:e})=>0===e.length||(t?.path.length??0)>1),E=R.length,A=new Map(R.map(({connection:t},e)=>[t.connectionId,e])),O=new Int8Array(a).fill(1),k=new Int32Array(E),L=new Int32Array(E),D=new Int32Array(E);R.forEach(({connection:t,solvedRoute:n},r)=>{const s=mB(e.regions.find(e=>e.regionId===t.startRegionId),i),a=mB(e.regions.find(e=>e.regionId===t.endRegionId),i),c=n?.path[0]?.portId??s,l=n?.path[n.path.length-1]?.portId??a,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)throw new Error(`Connection "${t.connectionId}" could not be mapped to route endpoints`);k[r]=d,L[r]=h,D[r]=N(t)});const z={portCount:a,regionCount:s,regionIncidentPorts:c,incidentPortRegion:l,regionWidth:d,regionHeight:h,regionCenterX:u,regionCenterY:p,regionAvailableZMask:m,regionMetadata:S,portAngleForRegion1:y,portAngleForRegion2:_,portX:b,portY:x,portZ:v,portMetadata:I},F=e.regions.flatMap((t,e)=>(t.assignments??[]).map(n=>{const i=A.get(n.connectionId);if(void 0===i)throw new Error(`Region "${t.regionId}" assignment references unknown routable connection "${n.connectionId}"`);const r=o.get(n.regionPort1Id),s=o.get(n.regionPort2Id);if(void 0===r||void 0===s)throw new Error(`Region "${t.regionId}" assignment references missing port "${void 0===r?n.regionPort1Id:n.regionPort2Id}"`);if(!c[e]?.includes(r)||!c[e]?.includes(s))throw new Error(`Region "${t.regionId}" assignment ports must both belong to the region`);return{routeId:i,regionId:e,fromPortId:r,toPortId:s}})),B=Float64Array.from(e.ports,t=>{const e=Number(t.d?.tinyHypergraphPortPenalty??0);return Number.isFinite(e)&&e>0?e:0}),j=B.some(t=>t>0),$={routeCount:E,portSectionMask:O,routeMetadata:R.map(({connection:t})=>t),routeStartPort:k,routeEndPort:L,routeNet:D,regionNetId:g,...F.length>0&&{initialAssignments:F},...j&&{portPenalty:B}},Y=[],X=[];for(const{solvedRoute:t}of R){if(!t){Y.push([]),X.push([]);continue}const e=[],i=[];for(let r=1;r<t.path.length;r++){const s=t.path[r-1],a=t.path[r],c=s?.portId,l=a?.portId,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)continue;const u="string"==typeof s?.nextRegionId?s.nextRegionId:"string"==typeof a?.lastRegionId?a.lastRegionId:void 0;e.push([d,h]),i.push(void 0!==u?n.get(u):void 0)}Y.push(e),X.push(i)}return{topology:z,problem:$,solution:{solvedRoutePathSegments:Y,solvedRoutePathRegionIds:X}}},fB=t=>"object"==typeof t&&null!==t,yB=t=>Array.isArray(t)?t.map(t=>yB(t)):fB(t)?Object.fromEntries(Object.entries(t).map(([t,e])=>[t,yB(e)])):t,_B=t=>fB(t)?{...t}:void 0===t?{}:{value:t},bB=(t,e=0)=>"number"==typeof t&&Number.isFinite(t)?t:e,xB=t=>({x:bB(t.d?.x),y:bB(t.d?.y)}),vB=t=>[t.region1Id,t.region2Id].sort().join("\0"),SB=(t,e)=>Math.hypot(t.x-e.x,t.y-e.y),IB=t=>{const e=Math.hypot(t.x,t.y);if(!(e<=1e-9))return{x:t.x/e,y:t.y/e}},CB=t=>{const e=t?.d?.center;if(fB(e))return{x:bB(e.x),y:bB(e.y)};const n=(t=>{const e=t?.d?.bounds;if(fB(e)&&"number"==typeof e.minX&&"number"==typeof e.maxX&&"number"==typeof e.minY&&"number"==typeof e.maxY)return{minX:e.minX,maxX:e.maxX,minY:e.minY,maxY:e.maxY};const n=t?.d?.center,o=bB(t?.d?.width),i=bB(t?.d?.height);if(fB(n)){const t=bB(n.x),e=bB(n.y);return{minX:t-o/2,maxX:t+o/2,minY:e-i/2,maxY:e+i/2}}return{minX:0,maxX:0,minY:0,maxY:0}})(t);return{x:(n.minX+n.maxX)/2,y:(n.minY+n.maxY)/2}},PB=(t,e)=>{const n=vB(t),o=xB(t);let i,r=Number.POSITIVE_INFINITY;for(const s of e){if(s.portId===t.portId)continue;if(vB(s)!==n)continue;const e=SB(o,xB(s));e<=1e-9||e>=r||(i=s,r=e)}return i},MB=(t,e,n)=>{const o=xB(t);if(e){const t=xB(e),n=IB({x:o.x-t.x,y:o.y-t.y});if(n)return n}return((t,e)=>{const n=CB(e.get(t.region1Id)),o=CB(e.get(t.region2Id));return IB({x:-(o.y-n.y),y:o.x-n.x})??{x:1,y:0}})(t,n)},NB=(t,e,n)=>{const o=`${t}::dup${e}`;if(!n.has(o))return n.add(o),o;for(let t=2;;t++){const e=`${o}-${t}`;if(!n.has(e))return n.add(e),e}},wB=(t,e,n)=>{const o=t.indexOf(e);-1!==o?t.splice(o+1,0,...n):t.push(...n)},TB=(t,e)=>{const n=t.portMetadata?.[e];if(fB(n)){if("string"==typeof n.serializedPortId)return n.serializedPortId;if("string"==typeof n.portId)return n.portId}return`port-${e}`},RB=(t,e)=>({routeCount:1,portSectionMask:new Int8Array(t.portSectionMask),routeMetadata:void 0===t.routeMetadata?void 0:[t.routeMetadata[e]],routeStartPort:Int32Array.from([t.routeStartPort[e]]),routeEndPort:Int32Array.from([t.routeEndPort[e]]),routeNet:Int32Array.from([t.routeNet[e]]),regionNetId:new Int32Array(t.regionNetId),portPenalty:void 0===t.portPenalty?void 0:new Float64Array(t.portPenalty)}),EB=t=>{const e=new Set;for(const n of t.state.regionSegments)for(const[,t,o]of n)e.add(t),e.add(o);return 0===e.size&&1===t.problem.routeCount&&(e.add(t.problem.routeStartPort[0]),e.add(t.problem.routeEndPort[0])),e},AB=class extends kt{constructor(t,e={}){super(),this.serializedHyperGraph=t,this.options=e}serializedHyperGraph;options;revisedSerializedHyperGraph;report={portUseCounts:{},duplicatedPorts:[]};getDuplicatePortProximity(){return this.options.duplicatePortProximity??.05}getIndividualRouteSolveOptions(){return{RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!1,...this.options.routeSolveOptions}}getPortUseCounts(){const{topology:t,problem:e}=gB(this.serializedHyperGraph);!1===this.options.useSerializedPortPenalties&&(e.portPenalty=void 0);const n=new Map;for(let o=0;o<e.routeCount;o++){const i=RB(e,o),r=new nB(t,i,this.getIndividualRouteSolveOptions());if(r.solve(),!r.solved||r.failed)throw new Error(`Route ${o} could not be solved independently: ${r.error??"unknown error"}`);for(const e of EB(r)){const o=TB(t,e);n.set(o,(n.get(o)??0)+1)}}return n}duplicateCongestedPorts(t){const e=this.getDuplicatePortProximity();if(!(e>0))throw new Error("duplicatePortProximity must be greater than zero");const{solvedRoutes:n,...o}=this.serializedHyperGraph,i=this.serializedHyperGraph.regions.map(t=>({...t,pointIds:[...t.pointIds],d:yB(t.d)})),r=this.serializedHyperGraph.ports.map(t=>({...t,d:yB(t.d)})),s=new Map(i.map(t=>[t.regionId,t])),a=new Map(r.map(t=>[t.portId,t])),c=new Set(r.map(t=>t.portId)),l=[];for(const[n,o]of[...t.entries()].sort(([t],[e])=>t.localeCompare(e))){if(o<=1)continue;const t=a.get(n);if(!t)continue;const i=o-1,d=PB(t,this.serializedHyperGraph.ports),h=MB(t,d,s),u=xB(t),p=[];for(let s=1;s<=i;s++){const a=NB(n,s,c),l=e*s/(i+1),d=_B(yB(t.d));d.x=u.x+h.x*l,d.y=u.y+h.y*l,d.duplicatedFromPortId=n,d.duplicateIndex=s,d.duplicatePortUseCount=o,d.duplicatePortProximity=e,d.repairReason="congested-port",r.push({...t,portId:a,d:d}),p.push(a)}for(const e of[t.region1Id,t.region2Id]){const t=s.get(e);t&&wB(t.pointIds,n,p)}l.push({sourcePortId:n,duplicatePortIds:p,useCount:o})}return this.report={portUseCounts:Object.fromEntries([...t.entries()].sort()),duplicatedPorts:l},{...o,regions:i,ports:r,connections:void 0===this.serializedHyperGraph.connections?void 0:yB(this.serializedHyperGraph.connections)}}_setup(){try{const t=this.getPortUseCounts();this.revisedSerializedHyperGraph=this.duplicateCongestedPorts(t),this.stats={...this.stats,duplicateSourcePortCount:this.report.duplicatedPorts.length,duplicatedPortCount:this.report.duplicatedPorts.reduce((t,e)=>t+e.duplicatePortIds.length,0)},this.solved=!0}catch(t){this.failed=!0,this.error=t instanceof Error?t.message:String(t)}}_step(){this.failed||(this.solved=!0)}getOutput(){if(!this.revisedSerializedHyperGraph||this.failed)throw new Error("DuplicateCongestedPortSolver does not have a repaired topology output");return this.revisedSerializedHyperGraph}},OB=(t,e)=>{const n=t.owners.size-e.owners.size;if(0!==n)return n;const o=t.distance-e.distance;return 0!==o?o:t.queueOrder-e.queueOrder},kB=class{heap=[];push(t){this.heap.push(t);let e=this.heap.length-1;for(;e>0;){const t=Math.floor((e-1)/2);if(OB(this.heap[t],this.heap[e])<=0)break;[this.heap[t],this.heap[e]]=[this.heap[e],this.heap[t]],e=t}}pop(){const t=this.heap[0],e=this.heap.pop();if(!t||!e)return null;if(0===this.heap.length)return t;this.heap[0]=e;let n=0;for(;;){const t=2*n+1,e=t+1;let o=n;if(t<this.heap.length&&OB(this.heap[t],this.heap[o])<0&&(o=t),e<this.heap.length&&OB(this.heap[e],this.heap[o])<0&&(o=e),o===n)break;[this.heap[n],this.heap[o]]=[this.heap[o],this.heap[n]],n=o}return t}},LB=(t,e)=>!(t.distance>e.distance)&&((t,e)=>{if(t.size>e.size)return!1;for(const n of t)if(!e.has(n))return!1;return!0})(t.owners,e.owners),DB=(t,e)=>{const n=[],o=[];let i=t;for(;null!==i;)n.push(i.state),null!==i.incomingHop&&o.push(i.incomingHop),i=i.parent;return n.reverse(),o.reverse(),{found:!0,states:n,hops:o,owners:new Set(t.owners),distance:t.distance,expandedLabelCount:e}},zB=t=>{for(;;){const e=t.pop();if(null===e)return null;if(e.active)return e}},FB=(t,e)=>{QF(t,e),e&&(void 0!==e.MAX_RIPS&&(t.MAX_RIPS=e.MAX_RIPS),void 0!==e.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT&&(t.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=e.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT),void 0!==e.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST&&(t.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=e.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST))},BB=t=>t.map(t=>t.map(([t,e,n])=>[t,e,n])),jB=t=>({netIds:new Int32Array(t.netIds),lesserAngles:new Int32Array(t.lesserAngles),greaterAngles:new Int32Array(t.greaterAngles),layerMasks:new Int32Array(t.layerMasks),existingCrossingLayerIntersections:t.existingCrossingLayerIntersections,existingSameLayerIntersections:t.existingSameLayerIntersections,existingEntryExitLayerChanges:t.existingEntryExitLayerChanges,existingRegionCost:t.existingRegionCost,existingSegmentCount:t.existingSegmentCount}),$B=t=>({portAssignment:new Int32Array(t.portAssignment),regionSegments:BB(t.regionSegments),regionIntersectionCaches:t.regionIntersectionCaches.map(jB)}),YB=(t,e)=>{const n=$B(e);t.state.portAssignment=n.portAssignment,t.state.regionSegments=n.regionSegments,t.state.regionIntersectionCaches=n.regionIntersectionCaches},XB=t=>{let e=0,n=0;for(let o=0;o<t.length;o++){const i=t[o]?.existingRegionCost??0;e=Math.max(e,i),n+=i}return{maxRegionCost:e,totalRegionCost:n}},VB=(t,e)=>t.maxRegionCost!==e.maxRegionCost?t.maxRegionCost-e.maxRegionCost:t.totalRegionCost-e.totalRegionCost,WB=(t,e,n)=>{const o=t.incidentPortRegion[e]??[],i=t.incidentPortRegion[n]??[],r=o.find(t=>i.includes(t));if(void 0===r)throw new Error(`Ports ${e} and ${n} do not share a region`);return r},HB=(t,e,n,o)=>{const i=n.solvedRoutePathSegments[o]??[],r=n.solvedRoutePathRegionIds?.[o]??[],s=e.routeStartPort[o],a=e.routeEndPort[o];if(0===i.length){if(s===a)return{orderedPortIds:[s],orderedRegionIds:[]};throw new Error(`Route ${o} does not have an existing solved path`)}const c=new Map;i.forEach(([t,e],n)=>{const o={segmentIndex:n,fromPortId:t,toPortId:e,regionId:r[n]},i=c.get(t)??[];i.push(o),c.set(t,i);const s=c.get(e)??[];s.push(o),c.set(e,s)});const l=[s],d=[],h=new Set;let u,p=s;for(;p!==a;){const e=(c.get(p)??[]).filter(({segmentIndex:t,fromPortId:e,toPortId:n})=>{if(h.has(t))return!1;return(e===p?n:e)!==u});if(1!==e.length)throw new Error(`Route ${o} is not a single ordered path from ${s} to ${a}`);const n=e[0],i=n.fromPortId===p?n.toPortId:n.fromPortId;h.add(n.segmentIndex),d.push(n.regionId??WB(t,n.fromPortId,n.toPortId)),l.push(i),u=p,p=i}if(h.size!==i.length)throw new Error(`Route ${o} contains disconnected solved segments`);return{orderedPortIds:l,orderedRegionIds:d}},GB=(t,e,n,o)=>{const i=new nB(t,e,o);return((t,e)=>{t.state.portAssignment.fill(-1),t.state.regionSegments=Array.from({length:t.topology.regionCount},()=>[]),t.state.regionIntersectionCaches=Array.from({length:t.topology.regionCount},()=>qF()),t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.state.unroutedRoutes=[],t.state.candidateQueue.clear(),t.resetCandidateBestCosts(),t.state.goalPortId=-1,t.state.ripCount=0,t.state.regionCongestionCost.fill(0);for(let n=0;n<e.length;n++)for(const[o,i,r]of e[n]??[])t.state.currentRouteNetId=t.problem.routeNet[o],t.state.regionSegments[n].push([o,i,r]),t.state.portAssignment[i]=t.state.currentRouteNetId,t.state.portAssignment[r]=t.state.currentRouteNetId,t.appendSegmentToRegionCache(n,i,r);t.state.currentRouteId=void 0,t.state.currentRouteNetId=void 0,t.solved=!0,t.failed=!1,t.error=null})(i,n),i},UB=(t,e,n)=>{const o=new Int32Array(e.routeStartPort),i=new Int32Array(e.routeEndPort),r=Array.from({length:e.routeCount},(t,e)=>({routeId:e,fixedSegments:[]})),s=[];for(let a=0;a<e.routeCount;a++){const c=r[a],{orderedPortIds:l,orderedRegionIds:d}=HB(t,e,n,a),h=[];let u;for(let t=0;t<l.length;t++){const n=l[t],o=1===e.portSectionMask[n];o&&void 0===u?u=t:o||void 0===u||(h.push({startIndex:u,endIndex:t-1}),u=void 0)}if(void 0!==u&&h.push({startIndex:u,endIndex:l.length-1}),0===h.length){for(let t=1;t<l.length;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});continue}if(h.length>1)throw new Error(`Route ${a} enters the section multiple times; only one contiguous section span is currently supported`);const p=h[0],m=Math.max(0,p.startIndex-1),g=Math.min(l.length-1,p.endIndex+1);if(g<=m)throw new Error(`Route ${a} does not have a valid section span`);for(let t=1;t<=m;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});for(let t=g+1;t<l.length;t++)c.fixedSegments.push({regionId:d[t-1],fromPortId:l[t-1],toPortId:l[t]});c.activeStartPortId=l[m],c.activeEndPortId=l[g],c.forcedStartRegionId=d[m],o[a]=c.activeStartPortId,i[a]=c.activeEndPortId,s.push(a)}return{sectionProblem:{routeCount:e.routeCount,portSectionMask:new Int8Array(e.portSectionMask),routeMetadata:e.routeMetadata,routeStartPort:o,routeEndPort:i,routeNet:new Int32Array(e.routeNet),regionNetId:new Int32Array(e.regionNetId),portPenalty:void 0===e.portPenalty?void 0:new Float64Array(e.portPenalty)},routePlans:r,activeRouteIds:s}},ZB=(t,e,n)=>UB(t,e,n).activeRouteIds,qB=class extends nB{constructor(t,e,n,o,i,r,s,a){super(t,e,a),this.routePlans=n,this.activeRouteIds=o,this.mutableRegionIds=i,this.immutableRegionSummary=r,this.baselineSummary=s,FB(this,a),this.state.unroutedRoutes=[...o],this.applyFixedSegments(),this.fixedSnapshot=$B({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches})}routePlans;activeRouteIds;mutableRegionIds;immutableRegionSummary;baselineSummary;bestSnapshot;fixedSnapshot;bestSummary;baselineBeatRipCount;previousBestMaxRegionCost=Number.POSITIVE_INFINITY;ripsSinceBestMaxRegionCostImprovement=0;MAX_RIPS=Number.POSITIVE_INFINITY;MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=Number.POSITIVE_INFINITY;EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=Number.POSITIVE_INFINITY;applyFixedSegments(){for(const t of this.routePlans)for(const{regionId:e,fromPortId:n,toPortId:o}of t.fixedSegments)this.state.currentRouteNetId=this.problem.routeNet[t.routeId],this.state.regionSegments[e].push([t.routeId,n,o]),this.state.portAssignment[n]=this.state.currentRouteNetId,this.state.portAssignment[o]=this.state.currentRouteNetId,this.appendSegmentToRegionCache(e,n,o);this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0}captureBestState(t){this.bestSummary&&VB(t,this.bestSummary)>=0||(this.bestSummary=t,this.bestSnapshot=$B({portAssignment:this.state.portAssignment,regionSegments:this.state.regionSegments,regionIntersectionCaches:this.state.regionIntersectionCaches}))}restoreBestState(){this.bestSnapshot&&(YB(this,this.bestSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1)}getStartingNextRegionId(t,e){const n=this.routePlans[t]?.forcedStartRegionId;return void 0!==n?n:super.getStartingNextRegionId(t,e)}resetRoutingStateForRerip(){if(!this.fixedSnapshot)return super.resetRoutingStateForRerip(),this.state.unroutedRoutes=qz([...this.activeRouteIds],this.state.ripCount),void this.applyFixedSegments();YB(this,this.fixedSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=qz([...this.activeRouteIds],this.state.ripCount),this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1}onAllRoutesRouted(){const{state:t}=this,e=Math.min(this.MAX_RIPS,this.RIP_THRESHOLD_RAMP_ATTEMPTS),n=e<=0?1:Math.min(1,t.ripCount/e),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(this.mutableRegionIds.length);let s=0,a=0;for(let e=0;e<this.mutableRegionIds.length;e++){const n=this.mutableRegionIds[e],c=t.regionIntersectionCaches[n]?.existingRegionCost??0;r[e]=c,s=Math.max(s,c),a+=c,c>o&&i.push(n)}const c=Math.max(this.immutableRegionSummary.maxRegionCost,s),l=this.immutableRegionSummary.totalRegionCost+a;this.captureBestState({maxRegionCost:c,totalRegionCost:l});const d=this.bestSummary??{maxRegionCost:c,totalRegionCost:l};if(d.maxRegionCost<this.previousBestMaxRegionCost-Number.EPSILON?(this.previousBestMaxRegionCost=d.maxRegionCost,this.ripsSinceBestMaxRegionCostImprovement=0):this.ripsSinceBestMaxRegionCostImprovement+=1,void 0===this.baselineBeatRipCount&&d.maxRegionCost<this.baselineSummary.maxRegionCost-Number.EPSILON&&(this.baselineBeatRipCount=t.ripCount),this.stats={...this.stats,activeRouteCount:this.activeRouteIds.length,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:c,totalRegionCost:l,bestMaxRegionCost:d.maxRegionCost,bestTotalRegionCost:d.totalRegionCost,ripCount:t.ripCount},0===i.length||t.ripCount>=e||this.ripsSinceBestMaxRegionCostImprovement>=this.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT||void 0!==this.baselineBeatRipCount&&t.ripCount-this.baselineBeatRipCount>=this.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST)return this.restoreBestState(),void(this.solved=!0);for(let e=0;e<this.mutableRegionIds.length;e++){const n=this.mutableRegionIds[e];t.regionCongestionCost[n]+=r[e]*this.RIP_CONGESTION_REGION_COST_FACTOR}t.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:t.ripCount,reripRegionCount:i.length}}onOutOfCandidates(){const{state:t}=this;for(const e of this.mutableRegionIds){const n=t.regionIntersectionCaches[e]?.existingRegionCost??0;t.regionCongestionCost[e]+=n*this.RIP_CONGESTION_REGION_COST_FACTOR}t.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:t.ripCount,reripReason:"out_of_candidates"}}tryFinalAcceptance(){if(this.bestSnapshot)return this.restoreBestState(),void(this.solved=!0);this.fixedSnapshot&&YB(this,this.fixedSnapshot),this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=[...this.activeRouteIds],this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.stats={...this.stats,acceptedFixedSectionStateOnTimeout:!0},this.solved=!0}visualize(){return UF(this,{highlightSectionMask:!0,showInitialRouteHints:!1,showOnlySectionPortsOnIdle:!0})}},JB=class extends kt{constructor(t,e,n,o){super(),this.topology=t,this.problem=e,this.initialSolution=n,FB(this,o),this.baselineSolver=((t,e,n,o)=>{const i=Array.from({length:t.regionCount},()=>[]);for(let o=0;o<e.routeCount;o++){const{orderedPortIds:r,orderedRegionIds:s}=HB(t,e,n,o);for(let t=1;t<r.length;t++){const e=r[t-1],n=r[t];i[s[t-1]].push([o,e,n])}}return GB(t,e,i,o)})(t,e,n,tB(this)),this.baselineSummary=XB(this.baselineSolver.state.regionIntersectionCaches),this.sectionRegionIds=((t,e)=>{const n=new Set;for(let o=0;o<e.portSectionMask.length;o++)if(1===e.portSectionMask[o])for(const e of t.incidentPortRegion[o]??[])n.add(e);return[...n]})(t,e),this.sectionBaselineSummary=((t,e)=>{let n=0,o=0;for(const i of e){const e=t[i]?.existingRegionCost??0;n=Math.max(n,e),o+=e}return{maxRegionCost:n,totalRegionCost:o}})(this.baselineSolver.state.regionIntersectionCaches,this.sectionRegionIds),this.outsideSectionBaselineSummary=((t,e)=>{const n=new Set(e);let o=0,i=0;for(let e=0;e<t.length;e++){if(n.has(e))continue;const r=t[e]?.existingRegionCost??0;o=Math.max(o,r),i+=r}return{maxRegionCost:o,totalRegionCost:i}})(this.baselineSolver.state.regionIntersectionCaches,this.sectionRegionIds),this.applySectionRipPolicy()}topology;problem;initialSolution;baselineSolver;baselineSummary;sectionBaselineSummary;outsideSectionBaselineSummary;sectionRegionIds;optimizedSolver;sectionSolver;activeRouteIds=[];DISTANCE_TO_COST=.05;minViaPadDiameter=Yz;VERBOSE=!1;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;MAX_RIPS=Number.POSITIVE_INFINITY;MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT=10;EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST=10;RIP_CONGESTION_REGION_COST_FACTOR=.1;MAX_ITERATIONS=1e6;STATIC_REACHABILITY_PRECHECK=!1;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;ACCEPT_BEST_SOLUTION_ON_TIMEOUT=!0;GREEDY_FINAL_ROUTE_ITERS=4;applySectionRipPolicy(){this.RIP_THRESHOLD_START=.05,this.RIP_THRESHOLD_END=Math.max(this.RIP_THRESHOLD_START,this.sectionBaselineSummary.maxRegionCost),this.MAX_RIPS=Math.min(this.MAX_RIPS,20)}_setup(){this.applySectionRipPolicy();const{sectionProblem:t,routePlans:e,activeRouteIds:n}=UB(this.topology,this.problem,this.initialSolution);if(this.activeRouteIds=n,0===n.length)return this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,activeRouteCount:0,initialMaxRegionCost:this.baselineSummary.maxRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,optimized:!1},void(this.solved=!0);var o;this.sectionSolver=new qB(this.topology,t,e,n,this.sectionRegionIds,this.outsideSectionBaselineSummary,this.baselineSummary,{...tB(o=this),MAX_RIPS:o.MAX_RIPS,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:o.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:o.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST}),this.activeSubSolver=this.sectionSolver,this.stats={...this.stats,sectionBaselineMaxRegionCost:this.sectionBaselineSummary.maxRegionCost,sectionBaselineTotalRegionCost:this.sectionBaselineSummary.totalRegionCost,effectiveRipThresholdStart:this.RIP_THRESHOLD_START,effectiveRipThresholdEnd:this.RIP_THRESHOLD_END,effectiveMaxRips:this.MAX_RIPS}}_step(){if(!this.sectionSolver)return void(this.solved=!0);if(this.sectionSolver.step(),this.stats={...this.stats,...this.sectionSolver.stats,activeRouteCount:this.activeRouteIds.length},this.sectionSolver.failed)return this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,finalTotalRegionCost:this.baselineSummary.totalRegionCost,optimized:!1,sectionSearchFailedFallbackToBaseline:!0,sectionSearchError:this.sectionSolver.error},void(this.solved=!0);if(!this.sectionSolver.solved)return;const t=GB(this.topology,this.problem,BB(this.sectionSolver.state.regionSegments),tB(this)),e=XB(t.state.regionIntersectionCaches),n=VB(e,this.baselineSummary)<0;this.optimizedSolver=n?t:this.baselineSolver;const o=n?e:this.baselineSummary;this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,candidateMaxRegionCost:e.maxRegionCost,candidateTotalRegionCost:e.totalRegionCost,finalMaxRegionCost:o.maxRegionCost,finalTotalRegionCost:o.totalRegionCost,optimized:n},this.solved=!0}tryFinalAcceptance(){this.optimizedSolver=this.baselineSolver,this.stats={...this.stats,initialMaxRegionCost:this.baselineSummary.maxRegionCost,initialTotalRegionCost:this.baselineSummary.totalRegionCost,finalMaxRegionCost:this.baselineSummary.maxRegionCost,finalTotalRegionCost:this.baselineSummary.totalRegionCost,optimized:!1,sectionSolverTimeoutFallbackToBaseline:!0},this.solved=!0,this.failed=!1,this.error=null}getSolvedSolver(){if(!this.solved||this.failed||!this.optimizedSolver)throw new Error("TinyHyperGraphSectionSolver does not have a solved output yet");return this.optimizedSolver}visualize(){return this.optimizedSolver?UF(this.optimizedSolver,{highlightSectionMask:!0}):this.sectionSolver?this.sectionSolver.visualize():UF(this.baselineSolver,{highlightSectionMask:!0,showInitialRouteHints:!1,showOnlySectionPortsOnIdle:!0})}getOutput(){return this.getSolvedSolver().getOutput()}},KB=["self-touch","onehop-all","onehop-touch","twohop-all","twohop-touch"],QB={"self-all":0,"self-touch":0,"onehop-all":1,"onehop-touch":1,"twohop-all":2,"twohop-touch":2,"threehop-all":3,"threehop-touch":3,"fourhop-all":4,"fourhop-touch":4},tj=(t,e)=>{const n=new Set(e);for(const o of e)for(const e of t.regionIncidentPorts[o]??[])for(const o of t.incidentPortRegion[e]??[])n.add(o);return[...n]},ej=(t,e,n)=>{let o=[...new Set(e)];for(let e=0;e<n;e+=1)o=tj(t,o);return o},nj=(t,e,n)=>e.flatMap(e=>n.map(n=>((t,e,n)=>({label:`hot-${e}-${n}`,family:n,regionIds:ej(t,[e],QB[n]),portSelectionRule:n.endsWith("-all")?"all-incident-regions-selected":"touches-selected-region"}))(t,e,n))),oj={RIP_THRESHOLD_RAMP_ATTEMPTS:5},ij={DISTANCE_TO_COST:.05,RIP_THRESHOLD_RAMP_ATTEMPTS:16,RIP_CONGESTION_REGION_COST_FACTOR:.1,MAX_ITERATIONS:5e4,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:6,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:Number.POSITIVE_INFINITY},rj=t=>t.state.regionIntersectionCaches.reduce((t,e)=>Math.max(t,e.existingRegionCost),0),sj=(t,e)=>{const n=gB(t),o=new JB(n.topology,n.problem,n.solution,e);return rj(o.baselineSolver)},aj=(t,e,n)=>{const o=new Set(e);return Int8Array.from({length:t.portCount},(e,i)=>{const r=t.incidentPortRegion[i]??[];return"touches-selected-region"===n?r.some(t=>o.has(t))?1:0:r.length>0&&r.every(t=>o.has(t))?1:0})},cj=(t,e)=>({routeCount:t.routeCount,portSectionMask:e,routeMetadata:t.routeMetadata,routeStartPort:new Int32Array(t.routeStartPort),routeEndPort:new Int32Array(t.routeEndPort),routeNet:new Int32Array(t.routeNet),regionNetId:new Int32Array(t.regionNetId),portPenalty:void 0===t.portPenalty?void 0:new Float64Array(t.portPenalty)}),lj=(t,e,n,o,i,r)=>{const s=performance.now(),a=performance.now(),c=new JB(e,n,o,r),l=rj(c.baselineSolver),d=performance.now()-a;let h,u,p=l,m=new Int8Array(e.portCount),g=0,f=0,y=0,_=0,b=0,x=0,v=0;const S=new Set,I=i?.maxHotRegions??r.MAX_HOT_REGIONS??2;for(const s of((t,e,n,o)=>{const i=t.state.regionIntersectionCaches.map((t,e)=>({regionId:e,regionCost:t.existingRegionCost})).filter(({regionCost:t})=>t>0).sort((t,e)=>e.regionCost-t.regionCost).slice(0,n).map(({regionId:t})=>t);return nj(e,i,o)})(t,e,I,i?.candidateFamilies??[...KB])){const t=cj(n,aj(e,s.regionIds,s.portSelectionRule));g+=1;const i=t.portSectionMask.join(",");if(S.has(i))y+=1;else{S.add(i);try{const n=performance.now(),i=ZB(e,t,o);if(_+=performance.now()-n,0===i.length)continue;f+=1;const a=performance.now(),c=new JB(e,t,o,r);b+=performance.now()-a;const l=performance.now();if(c.solve(),x+=performance.now()-l,c.failed||!c.solved)continue;if(Number(c.stats.finalMaxRegionCost??rj(c.getSolvedSolver()))<p-1e-9){const e=performance.now(),n=sj(c.getOutput(),r);v+=performance.now()-e,n<p-1e-9&&(p=n,m=new Int8Array(t.portSectionMask),h=s.label,u=s.family)}}catch{}}}return{portSectionMask:m,baselineMaxRegionCost:l,finalMaxRegionCost:p,generatedCandidateCount:g,candidateCount:f,duplicateCandidateCount:y,totalMs:performance.now()-s,baselineEvaluationMs:d,candidateEligibilityMs:_,candidateInitMs:b,candidateSolveMs:x,candidateReplayScoreMs:v,winningCandidateLabel:h,winningCandidateFamily:u}},dj=class extends Dt{initialVisualizationSolver;selectedSectionMask;selectedSectionCandidateLabel;selectedSectionCandidateFamily;constructor(t){super(t),this.MAX_ITERATIONS=2e5}loadHyperGraph(t){return gB(t)}getSolveGraphOptions(){return{...oj,...void 0===this.inputProblem.minViaPadDiameter?{}:{minViaPadDiameter:this.inputProblem.minViaPadDiameter},...this.inputProblem.solveGraphOptions}}getSectionSolverOptions(){return{...ij,...void 0===this.inputProblem.minViaPadDiameter?{}:{minViaPadDiameter:this.inputProblem.minViaPadDiameter},...this.inputProblem.sectionSolverOptions}}pipelineDef=[{solverName:"solveGraph",solverClass:nB,getConstructorParams:t=>{const{topology:e,problem:n}=t.loadHyperGraph(t.inputProblem.serializedHyperGraph);return[e,n,t.getSolveGraphOptions()]}},{solverName:"optimizeSection",solverClass:JB,getConstructorParams:t=>t.getSectionStageParams()}];getSectionStageParams(){const t=this.getStageOutput("solveGraph");if(!t)throw new Error("solveGraph did not produce a solved serialized hypergraph");const e=this.getSolver("solveGraph");if(!e)throw new Error("solveGraph solver is unavailable");const n=this.getSectionSolverOptions(),{topology:o,problem:i,solution:r}=this.loadHyperGraph(t),s=this.inputProblem.createSectionMask?this.inputProblem.createSectionMask({serializedHyperGraph:this.inputProblem.serializedHyperGraph,solvedSerializedHyperGraph:t,solvedSolver:e,topology:o,problem:i,solution:r}):(()=>{const t=lj(e,o,i,r,this.inputProblem.sectionSearchConfig,n);return this.selectedSectionCandidateLabel=t.winningCandidateLabel,this.selectedSectionCandidateFamily=t.winningCandidateFamily,this.stats={...this.stats,sectionSearchGeneratedCandidateCount:t.generatedCandidateCount,sectionSearchCandidateCount:t.candidateCount,sectionSearchDuplicateCandidateCount:t.duplicateCandidateCount,sectionSearchBaselineMaxRegionCost:t.baselineMaxRegionCost,sectionSearchFinalMaxRegionCost:t.finalMaxRegionCost,sectionSearchDelta:t.baselineMaxRegionCost-t.finalMaxRegionCost,selectedSectionCandidateLabel:t.winningCandidateLabel??null,selectedSectionCandidateFamily:t.winningCandidateFamily??null,sectionSearchMs:t.totalMs,sectionSearchBaselineEvaluationMs:t.baselineEvaluationMs,sectionSearchCandidateEligibilityMs:t.candidateEligibilityMs,sectionSearchCandidateInitMs:t.candidateInitMs,sectionSearchCandidateSolveMs:t.candidateSolveMs,sectionSearchCandidateReplayScoreMs:t.candidateReplayScoreMs},t.portSectionMask})();return this.selectedSectionMask=new Int8Array(s),i.portSectionMask=new Int8Array(s),this.stats={...this.stats,sectionMaskPortCount:[...s].filter(t=>1===t).length},[o,i,r,n]}getInitialVisualizationSolver(){if(!this.initialVisualizationSolver){const{topology:t,problem:e}=this.loadHyperGraph(this.inputProblem.serializedHyperGraph);this.initialVisualizationSolver=new nB(t,e,this.getSolveGraphOptions())}return this.initialVisualizationSolver}initialVisualize(){return this.getInitialVisualizationSolver().visualize()}visualize(){return 0===this.iterations?this.initialVisualize()??super.visualize():super.visualize()}getOutput(){return this.getStageOutput("optimizeSection")??this.getStageOutput("solveGraph")??null}tryFinalAcceptance(){this.getStageOutput("solveGraph")&&(this.stats={...this.stats,acceptedSolveGraphOutputOnSectionPipelineTimeout:!0},this.activeSubSolver=void 0,this.solved=!0,this.failed=!1,this.error=null)}};var hj=class extends aB{failedOwnerPairCounts=new Map;selectiveReripStats={selectiveRipCount:0,selectivelyRippedRouteCount:0,globalReripCount:0,alternateBlockerSearchCount:0,alternateOwnerCount:0,failedOwnerPairCount:0,maxFailedOwnerPairCount:0,failedOwnerPairs:[],lastDirectOwnerRouteIds:[],lastRepeatedOwnerRouteIds:[],lastAlternateOwnerRouteIds:[],lastRippedRouteIds:[],lastRelaxedSearchExpandedLabelCount:0,lastAlternateSearchExpandedLabelCount:0};selectiveReripCongestionUpdateCount=0;constructor(t,e,n){super(t,e,n)}getSelectiveReripStats(){return{...this.selectiveReripStats,failedOwnerPairs:this.selectiveReripStats.failedOwnerPairs.map(t=>({...t})),lastDirectOwnerRouteIds:[...this.selectiveReripStats.lastDirectOwnerRouteIds],lastRepeatedOwnerRouteIds:[...this.selectiveReripStats.lastRepeatedOwnerRouteIds],lastAlternateOwnerRouteIds:[...this.selectiveReripStats.lastAlternateOwnerRouteIds],lastRippedRouteIds:[...this.selectiveReripStats.lastRippedRouteIds]}}onOutOfCandidates(){const t=this.state.currentRouteId;if(void 0===t)throw new Error("SelectiveReripTinyHyperGraphSolver: candidate search exhausted without a current route");const e=this.findRelaxedBlockerPathPreferringPreservedRoutes();if(!e.found||0===e.owners.size)return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=e.found?"no_blocker_path":e.reason,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=[],this.selectiveReripStats.lastRepeatedOwnerRouteIds=[],this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=0,super.onOutOfCandidates(),void this.publishSelectiveReripStats();const n=[...e.owners],o=[];for(const e of n){this.incrementFailedOwnerPair(t,e)>=2&&o.push(e)}if(n.some(e=>this.hasFailedOwnerPath(e,t)))return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason="failed_owner_cycle",this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=0,this.failedOwnerPairCounts.clear(),super.onOutOfCandidates(),void this.publishSelectiveReripStats();let i;if(o.length>0&&(this.selectiveReripStats.alternateBlockerSearchCount+=1,i=this.findRelaxedBlockerPathPreferringPreservedRoutes(new Set(o)),!i.found))return this.selectiveReripStats.globalReripCount+=1,this.selectiveReripStats.globalReripReason=i.reason,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=[],this.selectiveReripStats.lastRippedRouteIds=[],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=i.expandedLabelCount,super.onOutOfCandidates(),void this.publishSelectiveReripStats();const r=i?.found?[...i.owners]:void 0,s=function(t){const e=new Set(t.alternateOwnerRouteIds??t.directOwnerRouteIds);if(e.delete(t.failedRouteId),0===e.size)throw new Error(`SelectiveReripTinyHyperGraphSolver: route ${t.failedRouteId} has blocker resources but no distinct committed owner can be reripped`);return e}({failedRouteId:t,directOwnerRouteIds:n,alternateOwnerRouteIds:r});this.clearPartialRipPlans(s);const a=(r??[]).filter(t=>!e.owners.has(t));this.selectiveReripCongestionUpdateCount<1&&(this.addCongestionCostForSelectiveRerip(),this.selectiveReripCongestionUpdateCount+=1),this.rebuildCommittedState(s),this.state.ripCount+=1,this.state.currentRouteId=void 0,this.state.currentRouteNetId=void 0,this.state.unroutedRoutes=function(t){const e=t.pendingRouteIds.filter(e=>e!==t.failedRouteId&&!t.rippedRouteIds.has(e)),n=[...t.rippedRouteIds].filter(e=>e!==t.failedRouteId);return[t.failedRouteId,...e,...n]}({failedRouteId:t,pendingRouteIds:this.state.unroutedRoutes,rippedRouteIds:s}),this.state.candidateQueue.clear(),this.resetCandidateBestCosts(),this.state.goalPortId=-1,this.selectiveReripStats.selectiveRipCount+=1,this.selectiveReripStats.selectivelyRippedRouteCount+=s.size,this.selectiveReripStats.alternateOwnerCount+=a.length,this.selectiveReripStats.lastFailedRouteId=t,this.selectiveReripStats.lastDirectOwnerRouteIds=n,this.selectiveReripStats.lastRepeatedOwnerRouteIds=o,this.selectiveReripStats.lastAlternateOwnerRouteIds=a,this.selectiveReripStats.lastRippedRouteIds=[...s],this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount=e.expandedLabelCount,this.selectiveReripStats.lastAlternateSearchExpandedLabelCount=i?.expandedLabelCount??0,this.publishSelectiveReripStats()}addCongestionCostForSelectiveRerip(){for(let t=0;t<this.topology.regionCount;t++){const e=this.state.regionIntersectionCaches[t]?.existingRegionCost??0;this.state.regionCongestionCost[t]+=e*this.RIP_CONGESTION_REGION_COST_FACTOR}}findRelaxedBlockerPath(t=new Set){const e=this.state.currentRouteId,n=this.state.currentRouteNetId;if(void 0===e||void 0===n)throw new Error("SelectiveReripTinyHyperGraphSolver: blocker search requires a current route and net");const o=this.getRouteStartPortId(e),i=this.getRouteEndPortId(e),r=this.getStartingNextRegionId(e,o);if(void 0===r)throw new Error(`SelectiveReripTinyHyperGraphSolver: route ${this.describeRoute(e)} has no starting region for blocker search`);const s=this.getPortOwners();return(t=>{const e=t.maxExpandedLabels??Number.POSITIVE_INFINITY;if(e!==Number.POSITIVE_INFINITY&&(!Number.isInteger(e)||e<0))throw new Error("maxExpandedLabels must be a non-negative integer");const n=new Map,o=new kB;let i=0,r=0;const s={state:t.start,stateKey:t.getStateKey(t.start),owners:new Set,distance:0,parent:null,incomingHop:null,queueOrder:i++,active:!0};for(n.set(s.stateKey,[s]),o.push(s);;){const s=zB(o);if(null===s)return{found:!1,reason:"no_path",expandedLabelCount:r};if(t.isGoal(s.state))return DB(s,r);if(r>=e)return{found:!1,reason:"expansion_limit",expandedLabelCount:r};r++;for(const e of t.getHops(s.state)){if(!Number.isFinite(e.distance)||e.distance<0)throw new Error("Distinct-owner blocker hops require finite distances >= 0");const r=new Set(s.owners);for(const t of e.owners??[])r.add(t);const a=s.distance+e.distance;if(!Number.isFinite(a))throw new Error("Distinct-owner blocker path distance overflowed");const c={state:e.state,stateKey:t.getStateKey(e.state),owners:r,distance:a,parent:s,incomingHop:e,queueOrder:i++,active:!0},l=n.get(c.stateKey)??[];if(l.some(t=>LB(t,c)))continue;const d=[];for(const t of l)LB(c,t)?t.active=!1:d.push(t);d.push(c),n.set(c.stateKey,d),o.push(c)}}})({start:{portId:o,nextRegionId:r},getStateKey:({portId:t,nextRegionId:e})=>this.getHopId(t,e),isGoal:({portId:t})=>t===i,getHops:e=>this.getRelaxedSearchHops({state:e,goalPortId:i,routeNetId:n,portOwners:s,forbiddenOwnerRouteIds:t}),maxExpandedLabels:this.getRelaxedSearchExpansionLimit()})}findRelaxedBlockerPathPreferringPreservedRoutes(t=new Set){const e=this.getRouteIdsPreferredForPreservation();if(0===e.size)return this.findRelaxedBlockerPath(t);const n=new Set(t);for(const t of e)n.add(t);const o=this.findRelaxedBlockerPath(n);return o.found&&o.owners.size>0?o:this.findRelaxedBlockerPath(t)}getRelaxedSearchExpansionLimit(){let t=0;for(const e of this.topology.incidentPortRegion)t+=e.length;const e=Math.max(4,Math.ceil(Math.log2(this.problem.routeCount+1)));return Math.max(4096,t*e*4)}getRelaxedSearchHops(t){const{state:e,goalPortId:n,routeNetId:o}=t;if(this.isRegionReservedForDifferentNet(e.nextRegionId))return[];const i=[];for(const r of this.topology.regionIncidentPorts[e.nextRegionId]??[]){if(r===e.portId)continue;if(this.isPortReservedForDifferentNet(r))continue;if(r!==n&&0===this.problem.portSectionMask[r])continue;const s=this.getHopBlockerResources({regionId:e.nextRegionId,fromPortId:e.portId,toPortId:r,routeNetId:o,portOwners:t.portOwners}),a=[...new Set(s.flatMap(t=>t.owners))];if(a.some(e=>t.forbiddenOwnerRouteIds.has(e)))continue;let c=e.nextRegionId;if(r!==n){const[t,n]=this.topology.incidentPortRegion[r]??[];if(c=t===e.nextRegionId?n:t,void 0===c||this.isRegionReservedForDifferentNet(c))continue}i.push({state:{portId:r,nextRegionId:c},distance:Math.hypot(this.topology.portX[e.portId]-this.topology.portX[r],this.topology.portY[e.portId]-this.topology.portY[r]),owners:a,data:{resources:s}})}return i}getHopBlockerResources(t){const e=[],n=this.state.portAssignment[t.toPortId];if(-1!==n&&n!==t.routeNetId){const o=[...t.portOwners.get(t.toPortId)??new Set].filter(e=>this.problem.routeNet[e]!==t.routeNetId);if(0===o.length)throw new Error(`SelectiveReripTinyHyperGraphSolver: port ${t.toPortId} is assigned to foreign net ${n} without a committed route owner`);e.push({kind:"port",portId:t.toPortId,owners:o})}const o=this.getHardBlockedCrossingOwners(t.regionId,t.fromPortId,t.toPortId);return o.length>0&&e.push({kind:"same_layer_intersection",regionId:t.regionId,fromPortId:t.fromPortId,toPortId:t.toPortId,owners:o}),e}getPortOwners(){const t=new Map;for(const e of this.state.regionSegments)for(const[n,o,i]of e)for(const e of[o,i]){const o=t.get(e)??new Set;o.add(n),t.set(e,o)}return t}getHardBlockedCrossingOwners(t,e,n){if(!this.isKnownSingleLayerRegion(t))return[];const o=this.state.currentRouteNetId;if(void 0===o)throw new Error("SelectiveReripTinyHyperGraphSolver: crossing ownership requires a current route net");const i=new Set;for(const[r,s,a]of this.state.regionSegments[t]??[])this.problem.routeNet[r]!==o&&this.segmentsCrossOnSameLayer(t,e,n,s,a)&&i.add(r);return[...i]}segmentsCrossOnSameLayer(t,e,n,o,i){const r={...this.populateSegmentGeometryScratch(t,e,n)},s={...this.populateSegmentGeometryScratch(t,o,i)};if(0===(r.layerMask&s.layerMask))return!1;if(r.lesserAngle===s.lesserAngle||r.lesserAngle===s.greaterAngle||r.greaterAngle===s.lesserAngle||r.greaterAngle===s.greaterAngle)return!1;return(r.lesserAngle<s.lesserAngle&&s.lesserAngle<r.greaterAngle)!==(r.lesserAngle<s.greaterAngle&&s.greaterAngle<r.greaterAngle)}rebuildCommittedState(t){this.state.regionSegments=this.state.regionSegments.map(e=>e.filter(([e])=>!t.has(e))),this.state.portAssignment.fill(-1),this.state.regionIntersectionCaches=Array.from({length:this.topology.regionCount},()=>qF());for(let t=0;t<this.state.regionSegments.length;t++)for(const[e,n,o]of this.state.regionSegments[t]){const i=this.problem.routeNet[e];this.state.currentRouteNetId=i;for(const t of[n,o]){const e=this.state.portAssignment[t];if(-1!==e&&e!==i)throw new Error(`SelectiveReripTinyHyperGraphSolver: rebuilding committed routes found cross-net ownership at port ${t} between net ${e} and net ${i}`);this.state.portAssignment[t]=i}this.appendSegmentToRegionCache(t,n,o)}this.state.currentRouteNetId=void 0}incrementFailedOwnerPair(t,e){const n=this.failedOwnerPairCounts.get(t)??new Map,o=(n.get(e)??0)+1;return n.set(e,o),this.failedOwnerPairCounts.set(t,n),o}hasFailedOwnerPath(t,e){const n=[t],o=new Set;for(;n.length>0;){const t=n.pop();if(t===e)return!0;o.has(t)||(o.add(t),n.push(...this.failedOwnerPairCounts.get(t)?.keys()??[]))}return!1}publishSelectiveReripStats(){const t=[];for(const[e,n]of this.failedOwnerPairCounts)for(const[o,i]of n)t.push({failedRouteId:e,ownerRouteId:o,count:i});t.sort((t,e)=>t.failedRouteId-e.failedRouteId||t.ownerRouteId-e.ownerRouteId),this.selectiveReripStats.failedOwnerPairs=t,this.selectiveReripStats.failedOwnerPairCount=t.length,this.selectiveReripStats.maxFailedOwnerPairCount=Math.max(0,...t.map(({count:t})=>t)),this.stats={...this.stats,...this.getSelectiveReripStats()}}describeRoute(t){const e=this.problem.routeMetadata?.[t]?.connectionId;return void 0===e?String(t):`${t} (${String(e)})`}};new Int32Array(0);var uj=class extends hj{initialAssignmentRouteIds;getRouteIdsPreferredForPreservation(){return this.initialAssignmentRouteIds||(this.initialAssignmentRouteIds=new Set((this.problem.initialAssignments??[]).map(t=>t.routeId))),this.initialAssignmentRouteIds}resetRoutingStateForRerip(){super.resetRoutingStateForRerip(),this.problem.initialAssignments?.length&&Uz({topology:this.topology,problem:this.problem,state:this.state,routeSuccessCountByRouteId:this.routeSuccessCountByRouteId,appendSegmentToRegionCache:(t,e,n)=>this.appendSegmentToRegionCache(t,e,n)})}},pj=t=>{if("object"!=typeof t||null===t)return!1;const e=t,n=e.preloadedTraceSection;return"string"==typeof e.connectionId&&"string"==typeof n?.traceId&&"number"==typeof n.startRoutePosition&&"number"==typeof n.endRoutePosition&&"number"==typeof n.startPoint?.x&&"number"==typeof n.startPoint.y&&"number"==typeof n.startPoint.z&&"number"==typeof n.endPoint?.x&&"number"==typeof n.endPoint.y&&"number"==typeof n.endPoint.z},mj=(t,e)=>`__tscircuit_preloaded_trace__:${JSON.stringify([t,e])}`,gj=t=>[t.region1Id,t.region2Id],fj=(t,e)=>{const n=new Set(gj(e));return gj(t).filter(t=>n.has(t))},yj=(t,e,n)=>{const o=t[e],i=t[e+1],r=fj(o.port,i.port);if(0===r.length)return;if(1===r.length)return r[0];const s=t[e+2];if(s){const t=new Set(fj(i.port,s.port)),e=r.find(e=>t.has(e));if(e)return e}return n&&r.includes(n)?n:[...r].sort()[0]},_j=(t,e)=>gj(t).find(t=>t!==e)??e,bj=t=>{const e=new Set((t.connections??[]).filter(pj).map(t=>t.connectionId)),n=t.ports.filter(t=>(t.d?._preloadedTracePortAssignments?.length??0)>0).length,o=t.regions.reduce((t,n)=>t+(n.assignments??[]).filter(t=>e.has(t.connectionId)).length,0);return{preloadedTraceCount:e.size,preloadedPortCount:n,preloadedAssignmentCount:o}},xj=t=>"object"==typeof t&&null!==t?t:{},vj=t=>"object"==typeof t&&null!==t?t:{},Sj=1e-6,Ij={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,PARTIAL_RIP_MIN_ROUTE_COUNT:100,PARTIAL_RIP_MAX_ROUTE_COUNT:350,PARTIAL_RIP_MAX_ATTEMPTS:7,PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS:1,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:100,PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO:.02,PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO:.05,PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO:.1},Cj={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT:6,EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST:Number.POSITIVE_INFINITY},Pj=t=>Math.max(t,.01),Mj=t=>Number.isFinite(t)?{minViaPadDiameter:t}:{},Nj=(t,e)=>{const n=Pj(t);return{...Ij,...Mj(e),USE_SPARSE_CANDIDATE_STORAGE:!1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.ceil(10*n),MAX_ITERATIONS:Math.ceil(2e6*n)}},wj=(t,e)=>{const n=Pj(t);return{...Cj,...Mj(e),USE_SPARSE_CANDIDATE_STORAGE:!1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.ceil(16*n),MAX_ITERATIONS:Math.ceil(1e6*n)}},Tj=t=>(t.solveGraphOptions?.MAX_ITERATIONS??1e6)+(t.sectionSolverOptions?.MAX_ITERATIONS??1e6)+1e6,Rj=t=>t.mutuallyConnectedNetworkId,Ej=(t,e)=>t.simpleRouteConnection?.pointsToConnect[e],Aj=t=>{const e=Ej(t.routeMetadata,t.endpointIndex);if(!e)return t.fallbackZ;const n=xo(e).map(e=>ko(e,t.layerCount));return t.regionAvailableZ.find(t=>n.includes(t))??t.fallbackZ},Oj=(t,e)=>{const n=t.d,o=n.bounds;return{capacityMeshNodeId:t.d.capacityMeshNodeId,center:{x:t.d.center.x,y:t.d.center.y},width:t.d.width,height:t.d.height,availableZ:[...t.d.availableZ],...o?{bounds:{minX:o.minX,maxX:o.maxX,minY:o.minY,maxY:o.maxY}}:{},_containsObstacle:t.d._containsObstacle,_containsTarget:t.d._containsTarget,_offBoardConnectionId:t.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:void 0===t.d._offBoardConnectedCapacityMeshNodeIds?void 0:[...t.d._offBoardConnectedCapacityMeshNodeIds],_qfpRegionType:n._qfpRegionType,_isNarrowQfpPadGap:n._isNarrowQfpPadGap,...void 0!==e?{netId:e}:{}}},kj=t=>{const e=t.d;return{portId:t.d.portId,x:t.d.x,y:t.d.y,z:t.d.z,prevPortPointId:e.prevPortPointId,nextPortPointId:e.nextPortPointId,distToCentermostPortOnZ:t.d.distToCentermostPortOnZ,tinyHypergraphPortPenalty:t.d.tinyHypergraphPortPenalty,cramped:t.d.cramped,_preloadedFixedNetIds:t.d._preloadedFixedNetIds,_preloadedTracePortAssignments:t.d._preloadedTracePortAssignments}},Lj=t=>{const e=function(){const t=new Map;return e=>{const n=e.mutuallyConnectedNetworkId;let o=t.get(n);return void 0===o&&(o=t.size,t.set(n,o)),o}}(),n=function(t){const e=new Map,n=new Set,o=new Map;for(const i of t.params.connections){const r=i.mutuallyConnectedNetworkId,s=t.getNetIndex({connectionId:i.connectionId,mutuallyConnectedNetworkId:r});for(const t of[i.connectionId,r])o.set(t,s);for(const o of i.simpleRouteConnection.pointsToConnect)for(const i of t.params.graph.regions){if(!gf({point:o,region:i,layerCount:t.params.layerCount}))continue;if(void 0===o.pcb_port_id&&!0!==i.d._containsTarget){n.add(i.regionId);continue}let r=e.get(i.regionId);r||(r=new Set,e.set(i.regionId,r)),r.add(s)}}for(const n of t.params.graph.regions)for(const t of n.d._connectedTo??[]){const i=o.get(t);if(void 0===i)continue;let r=e.get(n.regionId);r||(r=new Set,e.set(n.regionId,r)),r.add(i)}const i=new Map;for(const t of n)i.set(t,-1);for(const[t,n]of e)1===n.size&&i.set(t,[...n][0]);return i}({params:t,getNetIndex:e}),o=t.graph.regions.map(t=>({regionId:t.regionId,pointIds:t.ports.map(t=>t.d.portId),d:Oj(t,n.get(t.regionId))})),i=t.graph.ports.map(t=>({portId:t.d.portId,region1Id:t.region1.regionId,region2Id:t.region2.regionId,d:kj(t)})),r=t.connections.map(t=>({connectionId:t.connectionId,mutuallyConnectedNetworkId:t.mutuallyConnectedNetworkId,startRegionId:t.startRegion.regionId,endRegionId:t.endRegion.regionId,simpleRouteConnection:t.simpleRouteConnection})),s=[];for(const n of t.connections){const r={connectionId:n.connectionId,mutuallyConnectedNetworkId:n.mutuallyConnectedNetworkId,simpleRouteConnection:n.simpleRouteConnection},a=e(r),c=Ej(r,0),l=Ej(r,1),d=n.startRegion.d.availableZ[0]??0,h=n.endRegion.d.availableZ[0]??0,u=Aj({routeMetadata:r,endpointIndex:0,fallbackZ:d,regionAvailableZ:n.startRegion.d.availableZ,layerCount:t.layerCount}),p=Aj({routeMetadata:r,endpointIndex:1,fallbackZ:h,regionAvailableZ:n.endRegion.d.availableZ,layerCount:t.layerCount}),m=`tiny-terminal:start-region:${n.connectionId}`,g=`tiny-terminal:end-region:${n.connectionId}`,f=`tiny-terminal:start-port:${n.connectionId}`,y=`tiny-terminal:end-port:${n.connectionId}`;o.push({regionId:m,pointIds:[f],d:{capacityMeshNodeId:m,center:{x:c?.x??n.startRegion.d.center.x,y:c?.y??n.startRegion.d.center.y},width:Sj,height:Sj,availableZ:[u],_containsTarget:!0,_tinyTerminal:!0,_tinyTerminalNetId:n.mutuallyConnectedNetworkId,netId:a}}),o.push({regionId:g,pointIds:[y],d:{capacityMeshNodeId:g,center:{x:l?.x??n.endRegion.d.center.x,y:l?.y??n.endRegion.d.center.y},width:Sj,height:Sj,availableZ:[p],_containsTarget:!0,_tinyTerminal:!0,_tinyTerminalNetId:n.mutuallyConnectedNetworkId,netId:a}}),i.push({portId:f,region1Id:n.startRegion.regionId,region2Id:m,d:{portId:f,x:c?.x??n.startRegion.d.center.x,y:c?.y??n.startRegion.d.center.y,z:u,distToCentermostPortOnZ:0,_tinyTerminal:!0,...t.preserveTerminalPcbPortIds&&c?.pcb_port_id?{pcb_port_id:c.pcb_port_id}:{}}}),i.push({portId:y,region1Id:n.endRegion.regionId,region2Id:g,d:{portId:y,x:l?.x??n.endRegion.d.center.x,y:l?.y??n.endRegion.d.center.y,z:p,distToCentermostPortOnZ:0,_tinyTerminal:!0,...t.preserveTerminalPcbPortIds&&l?.pcb_port_id?{pcb_port_id:l.pcb_port_id}:{}}});const _=o.find(t=>t.regionId===n.startRegion.regionId),b=o.find(t=>t.regionId===n.endRegion.regionId);_?.pointIds.push(f),b?.pointIds.push(y),s.push({connection:{connectionId:n.connectionId},path:[{portId:f},{portId:y}]})}const a={regions:o,ports:i,connections:r,solvedRoutes:s};return(t=>{const e=new Map,n=new Map,o=new Set((t.connections??[]).flatMap(t=>[t.startRegionId,t.endRegionId])),i=new Set(t.regions.filter(t=>{const e="number"==typeof t.d?.netId?t.d.netId:"number"==typeof t.d?.NetId?t.d.NetId:void 0;return!0===t.d?._containsObstacle&&(void 0===e||-1===e)&&!o.has(t.regionId)}).map(t=>t.regionId));let r=0;for(const o of t.ports){const t=o.d,s=t?._preloadedTracePortAssignments??[];if(s.length>0&&r++,!i.has(o.region1Id)&&!i.has(o.region2Id))for(const t of s){const i=n.get(t.traceId);if(void 0!==i&&i!==t.fixedNetId)throw new Error(`Preloaded trace "${t.traceId}" maps to multiple canonical nets`);n.set(t.traceId,t.fixedNetId);const r=e.get(t.traceId)??[];r.push({port:o,assignment:t}),e.set(t.traceId,r)}}const s=new Map(t.regions.map(t=>[t.regionId,t])),a=t.connections??=[],c=t.solvedRoutes??=[];let l=0,d=0;for(const[t,o]of e){o.sort((t,e)=>t.assignment.routePosition-e.assignment.routePosition||t.assignment.z-e.assignment.z||t.port.portId.localeCompare(e.port.portId));const e=o.filter(({port:t},e)=>0===e||t.portId!==o[e-1].port.portId);if(e.length<2)continue;const i=[];let r;for(let t=0;t<e.length-1;t++){const n=e[t],o=e[t+1];if(n.assignment.z===o.assignment.z&&Math.abs(n.assignment.routePosition-o.assignment.routePosition)<=1e-6){r=void 0;continue}const s=yj(e,t,r);s?(i.push({regionId:s,from:n,to:o}),r=s):r=void 0}const h=[];for(const t of i){const e=h.at(-1);e&&e.at(-1).to.port.portId===t.from.port.portId?e.push(t):h.push([t])}for(const[e,o]of h.entries()){const i=mj(t,e);for(const e of o){const n=s.get(e.regionId);if(!n)throw new Error(`Preloaded trace "${t}" references missing region "${e.regionId}"`);n.assignments=[...n.assignments??[],{regionPort1Id:e.from.port.portId,regionPort2Id:e.to.port.portId,connectionId:i}],d++}const r=o[0],l=o.at(-1),h=r.from.port,u=l.to.port,p={connectionId:i,mutuallyConnectedNetworkId:n.get(t)??t,startRegionId:_j(h,r.regionId),endRegionId:_j(u,l.regionId),preloadedTraceSection:{traceId:t,startRoutePosition:r.from.assignment.routePosition,endRoutePosition:l.to.assignment.routePosition,startPoint:{x:r.from.assignment.tracePoint.x,y:r.from.assignment.tracePoint.y,z:r.from.assignment.z},endPoint:{x:l.to.assignment.tracePoint.x,y:l.to.assignment.tracePoint.y,z:l.to.assignment.z}}};a.push(p),c.push({requiredRip:!1,connection:p,path:[h,u].map(t=>({portId:t.portId,g:0,h:0,f:0,hops:0,ripRequired:!1}))})}h.length>0&&l++}})(a),a},Dj=t=>{const e=new Map;for(let n=0;n<t.problem.routeNet.length;n++){const o=t.problem.routeMetadata?.[n],i=o?.mutuallyConnectedNetworkId;if("string"!=typeof i||0===i.length)throw new Error(`Tiny hypergraph route ${n} is missing a net ID`);e.set(i,t.problem.routeNet[n])}for(let n=0;n<t.problem.regionNetId.length;n++){const o=t.topology.regionMetadata?.[n]?._tinyTerminalNetId;if("string"!=typeof o)continue;const i=e.get(o);void 0!==i&&(t.problem.regionNetId[n]=i)}},zj=t=>{const e=new Map;t.topology.regionMetadata?.forEach((t,n)=>{"string"==typeof t.serializedRegionId&&e.set(t.serializedRegionId,n)});const n=new Set;for(const e of t.problem.routeMetadata??[])pj(e)||("string"==typeof e.startRegionId&&n.add(e.startRegionId),"string"==typeof e.endRegionId&&n.add(e.endRegionId));for(const o of t.problem.routeMetadata??[])if(pj(o))for(const i of[o.startRegionId,o.endRegionId]){if("string"!=typeof i||n.has(i))continue;const o=e.get(i);if(void 0===o)continue;const r=t.topology.regionMetadata?.[o];"number"==typeof r?.netId||"number"==typeof r?.NetId||(t.problem.regionNetId[o]=-1)}},Fj=t=>{if(t.problem.metadataPortPenaltiesApplied)return 0;let e=0,n=void 0!==t.problem.portPenalty;for(let o=0;o<t.topology.portCount;o++){const i=Number(t.topology.portMetadata?.[o]?.tinyHypergraphPortPenalty),r=Number.isFinite(i)&&i>0?i:0;r>0&&e++,t.problem.portPenalty?.[o]!==r&&(n=!1)}if(n)return t.problem.metadataPortPenaltiesApplied=!0,e;e=0;const o=t.problem.portPenalty?new Float64Array(t.problem.portPenalty):new Float64Array(t.topology.portCount);for(let n=0;n<t.topology.portCount;n++){const i=Number(t.topology.portMetadata?.[n]?.tinyHypergraphPortPenalty);!Number.isFinite(i)||i<=0||(o[n]+=i,e++)}return e>0&&(t.problem.portPenalty=o),t.problem.metadataPortPenaltiesApplied=!0,e},Bj=class extends dj{configuredSolvers=new WeakSet;duplicatePortPenaltyCount=0;metadataPortPenaltyCount=0;crampedPortPenaltyCount=0;preloadedPortCount=0;preloadedFixedSegmentCount=0;crampedPortTraversalPenalty;useSelectiveReripRouting;constructor(t,e){super(t),this.useSelectiveReripRouting=e,this.crampedPortTraversalPenalty=150;const n=bj(t.serializedHyperGraph);if(this.preloadedPortCount=n.preloadedPortCount,this.preloadedFixedSegmentCount=n.preloadedAssignmentCount,e){const t=this.pipelineDef.find(t=>"solveGraph"===t.solverName);if(!t)throw new Error("Tiny hypergraph pipeline is missing the solveGraph stage");t.solverClass=uj}this.MAX_ITERATIONS=Tj(t)}loadHyperGraph(t){const e=super.loadHyperGraph(t);((t,e)=>{const n=new Map;for(const t of e.connections??[])pj(t)&&n.set(t.connectionId,t.preloadedTraceSection);for(const e of t.problem.routeMetadata??[]){const t=n.get(e.connectionId);t&&(e.preloadedTraceSection=t)}})(e,this.inputProblem.serializedHyperGraph);const n=Fj(e),{duplicatePortPenaltyCount:o,crampedPortPenaltyCount:i}=((t,e)=>{let n=0,o=0;const i=t.problem.portPenalty?new Float64Array(t.problem.portPenalty):new Float64Array(t.topology.portCount);for(let r=0;r<t.topology.portCount;r++){const s=t.topology.portMetadata?.[r];"string"==typeof s?.duplicatedFromPortId&&(i[r]+=150,n++),s?.cramped&&e>0&&(i[r]+=e,o++)}return(n>0||o>0)&&(t.problem.portPenalty=i),{duplicatePortPenaltyCount:n,crampedPortPenaltyCount:o}})(e,this.crampedPortTraversalPenalty);return Dj(e),zj(e),this.metadataPortPenaltyCount=Math.max(this.metadataPortPenaltyCount,n),this.duplicatePortPenaltyCount=Math.max(this.duplicatePortPenaltyCount,o),this.crampedPortPenaltyCount=Math.max(this.crampedPortPenaltyCount,i),e}_step(){super._step(),this.configureSolver(this.activeSubSolver)}getInitialVisualizationSolver(){if(this.useSelectiveReripRouting&&!this.initialVisualizationSolver){const{topology:t,problem:e}=this.loadHyperGraph(this.inputProblem.serializedHyperGraph);this.initialVisualizationSolver=new uj(t,e,this.getSolveGraphOptions())}const t=super.getInitialVisualizationSolver();return this.configureSolver(t),t}getSolvedTinySolver(){const t=this.getSolver("optimizeSection");if(t?.solved&&!t.failed)return t.getSolvedSolver();const e=this.getSolver("solveGraph");if(e?.solved&&!e.failed)return e;throw new Error("TinyHyperGraph section pipeline does not have a solved graph")}configureSolver(t){if(t&&!this.configuredSolvers.has(t)){if(t instanceof JB||t instanceof nB){const e=t;Fj(e),Dj(e),zj(e)}this.configuredSolvers.add(t)}}},jj=class extends si{constructor(t){super(),this.params=t;const e=(t=>t.map(t=>{const e=t.simpleRouteConnection;if(!e)throw new Error(`TinyHypergraphPortPointPathingSolver requires a SimpleRouteConnection for "${t.connectionId}"`);const n=t.mutuallyConnectedNetworkId;if(!n)throw new Error(`TinyHypergraphPortPointPathingSolver requires a net ID for "${t.connectionId}"`);return{...t,mutuallyConnectedNetworkId:n,simpleRouteConnection:e}}))(t.connections),n=t.flags.USE_SELECTIVE_RERIP_ROUTING?function(t,e){const n=new Map;for(const o of t){const t=e(o);n.set(t,(n.get(t)??0)+1)}return t.map((t,e)=>({connection:t,index:e})).sort((t,o)=>(n.get(e(o.connection))??0)-(n.get(e(t.connection))??0)||t.index-o.index).map(({connection:t})=>t)}(e,Rj):e;this.rootConnectionNameByConnectionId=new Map(n.map(t=>[t.connectionId,t.simpleRouteConnection.__rootConnectionNames?.[0]]));const o=Lj({...t,connections:n});this.originalPreloadedSegmentKeysByConnectionId=(t=>{const e=new Map;for(const n of t.connections??[])pj(n)&&e.set(n.connectionId,new Set);for(const n of t.regions)for(const t of n.assignments??[]){const o=e.get(t.connectionId);if(!o)continue;const[i,r]=[t.regionPort1Id,t.regionPort2Id].sort();o.add(JSON.stringify([n.regionId,i,r]))}return e})(o);const i=bj(o),r=i.preloadedPortCount>0,s=r&&!0===t.flags.USE_PARTIAL_RIP_ROUTING_WITH_PRELOADED_TRACES,a=s?Math.max(o.connections?.length??0,i.preloadedAssignmentCount):void 0;let c=o;if(n.length<=180){const e=new AB(o,{duplicatePortProximity:.05,useSerializedPortPenalties:!1,routeSolveOptions:{...Mj(t.minViaPadDiameter),USE_SPARSE_CANDIDATE_STORAGE:!1,ACCEPT_BEST_SOLUTION_ON_TIMEOUT:!0,GREEDY_FINAL_ROUTE_ITERS:4,MAX_ITERATIONS:Math.ceil(2e6*Pj(t.effort)),RIP_THRESHOLD_RAMP_ATTEMPTS:0,STATIC_REACHABILITY_PRECHECK:!0}});if(e.solve(),e.failed)this.duplicateCongestedPortError=e.error??"unknown error";else{this.duplicateCongestedPortReport=e.report,c=e.getOutput();for(const t of c.ports){const e=vj(t.d);"string"==typeof e.duplicatedFromPortId&&(delete e._preloadedFixedNetIds,delete e._preloadedTracePortAssignments)}}}else this.duplicateCongestedPortError=`Skipped for ${n.length} connections`;this.duplicatedPortCount=this.duplicateCongestedPortReport?.duplicatedPorts.reduce((t,e)=>t+e.duplicatePortIds.length,0)??0;const l=((t,e,n,o=!0,i)=>{const r=t.connections?.length??0,s=i??r,a=Ij.PARTIAL_RIP_MIN_ROUTE_COUNT??0,c=Ij.PARTIAL_RIP_MAX_ROUTE_COUNT??Number.POSITIVE_INFINITY,l=o&&s>=a&&s<=c;return{serializedHyperGraph:t,createSectionMask:({topology:t})=>new Int8Array(t.portCount),solveGraphOptions:{...Nj(e,n),...l?{PARTIAL_RIP_MIN_ROUTE_COUNT:0,PARTIAL_RIP_MAX_ROUTE_COUNT:Number.POSITIVE_INFINITY,PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT:0}:{PARTIAL_RIP_ENABLED:!1,OUTSIDE_IN_ROUTING:!1}},sectionSolverOptions:wj(e,n)}})({...c,solvedRoutes:o.solvedRoutes},t.effort,t.minViaPadDiameter,!r||s,a);this.tinyPipelineSolver=new Bj(l,!0===t.flags.USE_SELECTIVE_RERIP_ROUTING),this.primaryTinyPipelineSolver=this.tinyPipelineSolver,n.length>=30&&n.length<=99&&(this.alternativeTinyPipelineInput={...l,solveGraphOptions:{...l.solveGraphOptions,TRACE_DENSITY_COST_FACTOR:1}}),this.MAX_ITERATIONS=Tj(l)*(this.alternativeTinyPipelineInput?2:1),this.originalRegionById=new Map(t.graph.regions.map(t=>[t.regionId,t])),this.originalRegionIds=new Set(this.originalRegionById.keys()),this.inputNodeWithPortPoints=((t,e)=>{const n=new Map(e.regions.map(t=>[t.regionId,t])),o=new Map(e.ports.map(t=>[t.portId,t]));return t.graph.regions.map(t=>{const e=n.get(t.regionId),i=(e?.pointIds??t.ports.map(t=>t.d.portId)).map(t=>o.get(t)).filter(t=>t&&!vj(t.d)._tinyTerminal).map(t=>{const e=t,o=vj(e.d),i=n.get(e.region1Id),r=n.get(e.region2Id),s=Boolean(xj(i?.d)._offBoardConnectionId??xj(r?.d)._offBoardConnectionId);return{portPointId:e.portId,x:Number(o.x??0),y:Number(o.y??0),z:Number(o.z??0),prevPortPointId:"string"==typeof o.prevPortPointId?o.prevPortPointId:void 0,nextPortPointId:"string"==typeof o.nextPortPointId?o.nextPortPointId:void 0,connectionNodeIds:[e.region1Id,e.region2Id],distToCentermostPortOnZ:Number(o.distToCentermostPortOnZ??0),cramped:Boolean(o.cramped),connectsToOffBoardNode:s}});return{capacityMeshNodeId:t.d.capacityMeshNodeId,center:t.d.center,width:t.d.width,height:t.d.height,portPoints:i,availableZ:t.d.availableZ,_containsObstacle:t.d._containsObstacle,_containsTarget:t.d._containsTarget,_offBoardConnectionId:t.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t.d._offBoardConnectedCapacityMeshNodeIds,_qfpRegionType:t.d._qfpRegionType,_isNarrowQfpPadGap:t.d._isNarrowQfpPadGap}})})(t,c)}params;tinyPipelineSolver;primaryTinyPipelineSolver;alternativeTinyPipelineSolver;alternativeTinyPipelineInput;candidatePortfolioPhase="primary";primaryCandidateSummary;alternativeCandidateSummary;alternativeCandidateEvaluated=!1;selectedCandidate="primary";duplicateCongestedPortReport;duplicateCongestedPortError;duplicatedPortCount=0;inputNodeWithPortPoints;originalRegionById;originalRegionIds;rootConnectionNameByConnectionId;originalPreloadedSegmentKeysByConnectionId;getSolverName(){return"TinyHypergraphPortPointPathingSolver"}getChangedPreloadedRouteIds(t){const e=new Map,n=new Map;for(let o=0;o<t.problem.routeCount;o++){const i=this.getRouteMetadata(t,o);pj(i)&&(e.set(i.connectionId,o),n.set(o,new Set))}for(let e=0;e<t.state.regionSegments.length;e++){const o=t.topology.regionMetadata?.[e]?.serializedRegionId;for(const[i,r,s]of t.state.regionSegments[e]??[]){const e=n.get(i);if(!e)continue;const a=t.topology.portMetadata?.[r]?.serializedPortId,c=t.topology.portMetadata?.[s]?.serializedPortId;if("string"!=typeof o||"string"!=typeof a||"string"!=typeof c)throw new Error(`Tiny hypergraph preloaded route ${i} has a segment without serialized topology IDs`);const[l,d]=[a,c].sort();e.add(JSON.stringify([o,l,d]))}}const o=new Set;for(const[t,i]of this.originalPreloadedSegmentKeysByConnectionId){const r=e.get(t);if(void 0===r)throw new Error(`Tiny hypergraph lost preloaded trace section "${t}"`);const s=n.get(r);if(i.size>0&&0===s.size)throw new Error(`Tiny hypergraph lost preloaded trace section "${t}"`);(i.size!==s.size||[...i].some(t=>!s.has(t)))&&o.add(r)}return o}summarizePipelineCandidate(t){const e=t.getSolvedTinySolver();let n=0,o=0,i=0,r=0,s=0,a=0;const c=e.topology.regionMetadata??[];for(let t=0;t<e.state.regionSegments.length;t++){const l=e.state.regionSegments[t];s+=l.length;for(const[,t,n]of l)e.topology.portZ[t]!==e.topology.portZ[n]&&(a+=1);const d=c[t]?.capacityMeshNodeId;if(!d||!this.originalRegionIds.has(d))continue;const h=this.originalRegionById.get(d);if(!h||0===l.length)continue;const u=l.map(([t,n,o])=>[this.createAssignedPortPoint(e,t,n),this.createAssignedPortPoint(e,t,o)]),p={capacityMeshNodeId:h.d.capacityMeshNodeId,center:h.d.center,width:h.d.width,height:h.d.height,portPoints:u.flat(),portPointsInPairs:u,availableZ:h.d.availableZ},m=Ms(p),g=Ys(h.d,m.numSameLayerCrossings,m.numEntryExitLayerChanges,m.numTransitionPairCrossings);n+=g,o+=g*g,i=Math.max(i,g),r+=p.portPoints.length**2}return{nodePfSum:n,nodePfSquaredSum:o,nodePfMax:i,squaredNodePortPointCount:r,segmentCount:s,layerChangeCount:a,changedPreloadedTraceSectionCount:this.getChangedPreloadedRouteIds(e).size}}shouldEvaluateAlternative(t){const e=this.primaryTinyPipelineSolver.getSolvedTinySolver().problem.routeCount;return void 0!==this.alternativeTinyPipelineInput&&((t,e)=>t.nodePfSum>4&&t.nodePfMax>1&&t.squaredNodePortPointCount/Math.max(1,e)>=125)(t,e)}shouldSelectAlternative(t,e){return((t,e,n)=>{if(e.changedPreloadedTraceSectionCount>t.changedPreloadedTraceSectionCount)return!1;const o=n>40?.92:.95,i=e.nodePfSum<=.9*t.nodePfSum&&e.nodePfSquaredSum<=.85*t.nodePfSquaredSum&&e.nodePfMax<=.85*t.nodePfMax&&e.squaredNodePortPointCount<.98*t.squaredNodePortPointCount&&e.segmentCount<=.97*t.segmentCount;return e.nodePfSum<=1.03*t.nodePfSum&&e.nodePfSquaredSum<=1.06*t.nodePfSquaredSum&&(e.squaredNodePortPointCount<t.squaredNodePortPointCount*o||i)})(t,e,this.primaryTinyPipelineSolver.getSolvedTinySolver().problem.routeCount)}finishCandidatePortfolio(){this.candidatePortfolioPhase="complete",this.solved=this.tinyPipelineSolver.solved,this.failed=this.tinyPipelineSolver.failed,this.error=this.tinyPipelineSolver.error??null}getSolveGraphBenchmarkMetrics(){const t=this.tinyPipelineSolver.getSolver("solveGraph");if(!t)return;const e=t.state.regionSegments.map(t=>t.length),n="alternative"===this.selectedCandidate?this.alternativeCandidateSummary:this.primaryCandidateSummary,o=t.stats,i=this.tinyPipelineSolver.getStageStats().solveGraph;return{routeCount:t.problem.routeCount,traceDensityCandidateEvaluated:this.alternativeCandidateEvaluated,traceDensityCandidateSelected:"alternative"===this.selectedCandidate,downstreamNodePfSum:n?.nodePfSum,downstreamNodePfSquaredSum:n?.nodePfSquaredSum,downstreamNodePfMax:n?.nodePfMax,downstreamSquaredNodePortPointCount:n?.squaredNodePortPointCount,changedPreloadedTraceSectionCount:n?.changedPreloadedTraceSectionCount,iterations:t.iterations,timeMs:i?.timeSpent,ripCount:o.ripCount,partialRipCount:o.partialRipCount,partiallyRippedRouteCount:o.partiallyRippedRouteCount,partiallyRippedSegmentCount:o.partiallyRippedSegmentCount,retainedPartialRipSegmentCount:o.retainedPartialRipSegmentCount,firstMaxRegionCost:o.firstMaxRegionCost,bestMaxRegionCost:o.bestMaxRegionCost,firstTotalRegionCost:o.firstTotalRegionCost,bestTotalRegionCost:o.bestTotalRegionCost,firstSegmentCount:o.firstSegmentCount,bestSolvedSegmentCount:o.bestSolvedSegmentCount,bestSolvedMaxRegionSegmentCount:o.bestSolvedMaxRegionSegmentCount,bestSolvedSquaredRegionSegmentCount:o.bestSolvedSquaredRegionSegmentCount,finalMaxRegionSegmentCount:Math.max(0,...e),finalSquaredRegionSegmentCount:e.reduce((t,e)=>t+e*e,0),finalSegmentCount:n?.segmentCount,finalLayerChangeCount:n?.layerChangeCount,warmupFullRipAttempts:o.partialRipWarmupFullRipAttempts,complexityAwareSelection:o.partialRipComplexityAwareSelection,targetReached:o.partialRipTargetReached,outsideInCompletedRouteCount:o.outsideInCompletedRouteCount,outsideInFallbackRouteCount:o.outsideInFallbackRouteCount,outsideInForwardExpansionCount:o.outsideInForwardExpansionCount,outsideInReverseExpansionCount:o.outsideInReverseExpansionCount}}_step(){this.tinyPipelineSolver.step(),"primary"===this.candidatePortfolioPhase&&this.primaryTinyPipelineSolver.failed?(this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio()):"primary"===this.candidatePortfolioPhase&&this.primaryTinyPipelineSolver.solved?(this.primaryCandidateSummary=this.summarizePipelineCandidate(this.primaryTinyPipelineSolver),this.shouldEvaluateAlternative(this.primaryCandidateSummary)?(this.alternativeCandidateEvaluated=!0,this.alternativeTinyPipelineSolver=new Bj(this.alternativeTinyPipelineInput,!0===this.params.flags.USE_SELECTIVE_RERIP_ROUTING),this.tinyPipelineSolver=this.alternativeTinyPipelineSolver,this.candidatePortfolioPhase="alternative"):(this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio())):"alternative"===this.candidatePortfolioPhase&&(this.tinyPipelineSolver.solved||this.tinyPipelineSolver.failed)&&(this.tinyPipelineSolver.solved&&!this.tinyPipelineSolver.failed&&(this.alternativeCandidateSummary=this.summarizePipelineCandidate(this.tinyPipelineSolver)),this.alternativeCandidateSummary&&this.primaryCandidateSummary&&this.shouldSelectAlternative(this.primaryCandidateSummary,this.alternativeCandidateSummary)?(this.selectedCandidate="alternative",this.primaryTinyPipelineSolver=void 0,this.alternativeTinyPipelineSolver=void 0):(this.tinyPipelineSolver=this.primaryTinyPipelineSolver,this.alternativeTinyPipelineSolver=void 0),this.alternativeTinyPipelineInput=void 0,this.finishCandidatePortfolio());const t=this.tinyPipelineSolver.getSolver("optimizeSection"),e=this.getCurrentTinySolver();this.solved="complete"===this.candidatePortfolioPhase&&this.tinyPipelineSolver.solved,this.failed="complete"===this.candidatePortfolioPhase&&this.tinyPipelineSolver.failed,this.error=this.failed?this.tinyPipelineSolver.error??null:null,this.progress="complete"===this.candidatePortfolioPhase?1:"alternative"===this.candidatePortfolioPhase?.5+.5*this.tinyPipelineSolver.progress:this.alternativeTinyPipelineInput?.5*this.tinyPipelineSolver.progress:this.tinyPipelineSolver.progress,this.stats={duplicateCongestedPortSourceCount:this.duplicateCongestedPortReport?.duplicatedPorts.length??0,duplicateCongestedPortCount:this.duplicateCongestedPortReport?.duplicatedPorts.reduce((t,e)=>t+e.duplicatePortIds.length,0)??0,duplicateCongestedPortFallbackToOriginal:Boolean(this.duplicateCongestedPortError),duplicateCongestedPortPenalty:this.duplicatedPortCount>0?150:0,duplicateCongestedPortPenaltyCount:this.tinyPipelineSolver.duplicatePortPenaltyCount,metadataPortPenaltyCount:this.tinyPipelineSolver.metadataPortPenaltyCount,crampedPortPenalty:this.tinyPipelineSolver.crampedPortTraversalPenalty,crampedPortPenaltyCount:this.tinyPipelineSolver.crampedPortPenaltyCount,preloadedPortCount:this.tinyPipelineSolver.preloadedPortCount,preloadedFixedSegmentCount:this.tinyPipelineSolver.preloadedFixedSegmentCount,duplicateCongestedPortError:this.duplicateCongestedPortError,candidatePortfolioPhase:this.candidatePortfolioPhase,candidatePortfolioSelectedCandidate:this.selectedCandidate,candidatePortfolioPrimarySummary:this.primaryCandidateSummary,candidatePortfolioAlternativeSummary:this.alternativeCandidateSummary,...this.tinyPipelineSolver.stats??{},...e?.stats??{},...t?.stats??{},currentStage:this.tinyPipelineSolver.getCurrentStageName(),stageStats:this.tinyPipelineSolver.getStageStats()},this.activeSubSolver=this.tinyPipelineSolver.activeSubSolver??null}preview(){return this.visualize()}getCurrentTinySolver(){const t=this.tinyPipelineSolver.getSolver("optimizeSection");if(t?.solved&&!t.failed)return t.getSolvedSolver();const e=this.tinyPipelineSolver.getSolver("solveGraph");return e||void 0}getSolvedTinySolver(){return this.tinyPipelineSolver.getSolvedTinySolver()}getRouteMetadata(t,e){return t.problem.routeMetadata?.[e]}createAssignedPortPoint(t,e,n){const o=this.getRouteMetadata(t,e),i=o?(t=>t.simpleRouteConnection?.name??t.connectionId)(o):`route-${e}`,r=o?this.rootConnectionNameByConnectionId.get(o.connectionId)??o.mutuallyConnectedNetworkId:void 0,s=t.topology.portMetadata?.[n];return{portPointId:String(s?.serializedPortId??s?.portId??`tiny-port-${n}`),x:t.topology.portX[n],y:t.topology.portY[n],z:t.topology.portZ[n],connectionName:i,rootConnectionName:r,...this.params.preserveTerminalPcbPortIds&&"string"==typeof s?.pcb_port_id?{pcb_port_id:s.pcb_port_id}:{},prevPortPointId:"string"==typeof s?.prevPortPointId?s.prevPortPointId:void 0,nextPortPointId:"string"==typeof s?.nextPortPointId?s.nextPortPointId:void 0}}getOutput(){const t=this.getSolvedTinySolver(),e=[],n=t.state.regionSegments,o=t.topology.regionMetadata??[],i=this.getChangedPreloadedRouteIds(t);for(let r=0;r<n.length;r++){const s=o[r]?.capacityMeshNodeId;if(!s||!this.originalRegionIds.has(s))continue;const a=this.originalRegionById.get(s);if(!a)continue;const c=n[r].filter(([e])=>{const n=this.getRouteMetadata(t,e);return!pj(n)||i.has(e)}).map(([e,n,o])=>{const i=this.createAssignedPortPoint(t,e,n),r=this.createAssignedPortPoint(t,e,o);return i.portPointId&&r.portPointId&&(i.nextPortPointId=r.portPointId,r.prevPortPointId=i.portPointId),[i,r]}),l=c.flat();0!==l.length&&e.push({capacityMeshNodeId:a.d.capacityMeshNodeId,center:a.d.center,width:a.d.width,height:a.d.height,portPoints:l,portPointsInPairs:c,availableZ:a.d.availableZ})}const r=[...i].map(e=>{const n=this.getRouteMetadata(t,e);if(!pj(n))throw new Error(`Changed preloaded hypergraph route ${e} is missing section metadata`);const o=n.preloadedTraceSection;return{connectionName:n.connectionId,traceId:o.traceId,startRoutePosition:o.startRoutePosition,endRoutePosition:o.endRoutePosition,connection:{name:n.connectionId,__rootConnectionNames:[n.mutuallyConnectedNetworkId],pointsToConnect:[{x:o.startPoint.x,y:o.startPoint.y,layer:vo(o.startPoint.z,this.params.layerCount)},{x:o.endPoint.x,y:o.endPoint.y,layer:vo(o.endPoint.z,this.params.layerCount)}]}}});return this.stats.changedPreloadedTraceSectionCount=r.length,{nodesWithPortPoints:e,inputNodeWithPortPoints:this.inputNodeWithPortPoints,changedPreloadedTraceSections:r}}computeNodePf(t){const e=this.getOutput().nodesWithPortPoints.find(e=>e.capacityMeshNodeId===t.capacityMeshNodeId),n=this.originalRegionById.get(t.capacityMeshNodeId);if(!e||!n)return null;const o=Ms(e);return Ys(n.d,o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.numTransitionPairCrossings)}tryFinalAcceptance(){}getConstructorParams(){return[this.params]}visualize(){return this.tinyPipelineSolver.visualize()}},$j=(t,e)=>{if(!t||"none"===t)return t;try{const n=gt(t);return`rgba(${n.red},${n.green},${n.blue},${e})`}catch{return To(t,1-e)}},Yj=({srj:t,opacity:e=.25,visualizationOptions:n={}})=>{const o=Ho({...t,obstacles:[]},n);return{...o,points:[],lines:o.lines?.map(t=>({...t,strokeColor:$j(t.strokeColor,e)})),rects:o.rects?.map(t=>({...t,fill:$j(t.fill,e),stroke:$j(t.stroke,e)})),circles:o.circles?.map(t=>({...t,fill:$j(t.fill,e),stroke:$j(t.stroke,e)}))}};function Xj(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 Vj="escape-via:",Wj=1e-4,Hj=t=>t.obstacleId??[t.layers.join("."),t.center.x.toFixed(4),t.center.y.toFixed(4),t.width.toFixed(4),t.height.toFixed(4)].join(":"),Gj=(t,e,n=1e-4)=>xe(t,e)<=n,Uj=class extends si{constructor(t,e={}){super(),this.ogSrj=t,this.viaDiameter=e.viaDiameter??Yo(t).padDiameter,this.viaRadius=this.viaDiameter/2,this.minTraceWidth=e.minTraceWidth??t.minTraceWidth,this.obstacleMargin=e.obstacleMargin??t.defaultObstacleMargin??.15,this.requiredViaToPadClearance=Math.max(this.obstacleMargin,t.minViaEdgeToPadEdgeClearance??0),this.escapeOffset=this.viaRadius+Math.max(this.minTraceWidth/2,this.requiredViaToPadClearance),this.requiredTraceClearance=this.minTraceWidth/2+this.obstacleMargin/2,this.requiredViaToViaClearance=this.viaDiameter+this.obstacleMargin,this.outputSrj=t,this.escapeViaMetadataByPointId=new Map,this.createdEscapeVias=[]}ogSrj;getSolverName(){return"EscapeViaLocationSolver"}viaDiameter;viaRadius;minTraceWidth;obstacleMargin;escapeOffset;requiredTraceClearance;requiredViaToPadClearance;requiredViaToViaClearance;outputSrj;escapeViaMetadataByPointId;createdEscapeVias;nextEscapeViaIndex=0;getConnectionNetIds(t){return new Set([t.name,...t.__rootConnectionNames??[],t.__netConnectionName].filter(t=>Boolean(t)))}obstacleMatchesConnectionNet(t,e){return t.connectedTo.some(t=>e.has(t))}getObstacleZs(t){return t.__zLayers&&t.__zLayers.length>0?t.__zLayers:t.layers.map(t=>ko(t,this.ogSrj.layerCount))}getViaSpanLayers(t,e){const n=ko(t,this.ogSrj.layerCount),o=ko(e,this.ogSrj.layerCount),i=Math.min(n,o),r=Math.max(n,o),s=Array.from({length:r-i+1},(t,e)=>i+e);return{__zLayers:s,layers:s.map(t=>vo(t,this.ogSrj.layerCount))}}createEscapeViaObstacle(t){const{escapeVia:e,connectionNetIds:n}=t,{layers:o,__zLayers:i}=this.getViaSpanLayers(e.sourceLayer,e.targetLayer);return{obstacleId:`escape-via-obstacle:${e.pointId}`,type:"rect",layers:o,__zLayers:i,center:{x:e.x,y:e.y},width:this.viaDiameter,height:this.viaDiameter,connectedTo:Array.from(n)}}selectSourceObstacle(t){const{point:e,sourceLayer:n,connectionNetIds:o}=t;return this.ogSrj.obstacles.filter(t=>!t.isCopperPour&&t.layers.includes(n)&&Xj(e,t)).sort((t,n)=>{const i=t.connectedTo.includes(e.pointId??"")||t.connectedTo.includes(e.pcb_port_id??"")||this.obstacleMatchesConnectionNet(t,o);return i!==(n.connectedTo.includes(e.pointId??"")||n.connectedTo.includes(e.pcb_port_id??"")||this.obstacleMatchesConnectionNet(n,o))?i?-1:1:t.width*t.height-n.width*n.height})[0]}getCandidatePositions(t,e){if(!e)return this.dedupeCandidatePositions([{x:t.x+this.escapeOffset,y:t.y},{x:t.x-this.escapeOffset,y:t.y},{x:t.x,y:t.y+this.escapeOffset},{x:t.x,y:t.y-this.escapeOffset},{x:t.x+this.escapeOffset,y:t.y+this.escapeOffset},{x:t.x+this.escapeOffset,y:t.y-this.escapeOffset},{x:t.x-this.escapeOffset,y:t.y+this.escapeOffset},{x:t.x-this.escapeOffset,y:t.y-this.escapeOffset}]);const n=e.center.x-e.width/2,o=e.center.x+e.width/2,i=e.center.y-e.height/2,r=e.center.y+e.height/2,s=n-this.escapeOffset,a=o+this.escapeOffset,c=i-this.escapeOffset,l=r+this.escapeOffset,d=this.getEdgeSamples(i,r,t.y),h=this.getEdgeSamples(n,o,t.x),u=[];for(const t of d)u.push({x:s,y:t},{x:a,y:t});for(const t of h)u.push({x:t,y:c},{x:t,y:l});return this.dedupeCandidatePositions(u)}dedupeCandidatePositions(t){const e=[];for(const n of t)e.some(t=>Gj(t,n))||e.push(n);return e}pushEdgeSample(t,e,n,o){const i=Math.max(n,Math.min(o,e));t.some(t=>Math.abs(t-i)<=Wj)||t.push(i)}getEdgeSamples(t,e,n){const o=[],i=e-t;if(this.pushEdgeSample(o,n,t,e),i<=Wj)return o;this.pushEdgeSample(o,t,t,e),this.pushEdgeSample(o,e,t,e),this.pushEdgeSample(o,(t+e)/2,t,e);const r=Math.max(t,Math.min(e,n)),s=Math.max(this.requiredViaToViaClearance,Wj),a=Math.ceil(i/s);for(let n=1;n<=a;n++){const i=n*s;this.pushEdgeSample(o,r+i,t,e),this.pushEdgeSample(o,r-i,t,e)}return o}isInsideBoard(t){return!!(t.x>=this.ogSrj.bounds.minX+this.viaRadius&&t.x<=this.ogSrj.bounds.maxX-this.viaRadius&&t.y>=this.ogSrj.bounds.minY+this.viaRadius&&t.y<=this.ogSrj.bounds.maxY-this.viaRadius)&&(!(this.ogSrj.outline&&this.ogSrj.outline.length>=3)||za(t,this.ogSrj.outline))}hasClearEscapePath(t){const{sourcePoint:e,candidate:n,sourceLayer:o,sourceObstacle:i}=t;if(this.ogSrj.outline&&this.ogSrj.outline.length>=3){if(Fa({start:e,end:n,polygon:this.ogSrj.outline,margin:this.requiredTraceClearance}))return!1}for(const t of this.ogSrj.obstacles){if(t===i)continue;if(!t.layers.includes(o))continue;if(Xj(n,t))return!1;const r=Cl(t);if(Math.min(...r.map(t=>Ra(e,n,t.start,t.end)))+Wj<this.requiredTraceClearance)return!1}return!0}getBoardBoundarySegments(){if(this.ogSrj.outline&&this.ogSrj.outline.length>=3)return this.ogSrj.outline.map((t,e)=>({start:t,end:this.ogSrj.outline[(e+1)%this.ogSrj.outline.length]}));const{minX:t,maxX:e,minY:n,maxY:o}=this.ogSrj.bounds;return[{start:{x:t,y:n},end:{x:e,y:n}},{start:{x:e,y:n},end:{x:e,y:o}},{start:{x:e,y:o},end:{x:t,y:o}},{start:{x:t,y:o},end:{x:t,y:n}}]}getRayProbeDistance(){const{minX:t,maxX:e,minY:n,maxY:o}=this.ogSrj.bounds;return 2*Math.hypot(e-t,o-n)+this.viaDiameter}getRayIntersectionDistance(t){const{rayStart:e,rayEnd:n,segmentStart:o,segmentEnd:i}=t;if(!fe(e,n,o,i))return null;const r=ve(e,n,o,i);if(!r)return null;const s=xe(e,r);return s<=Wj?null:s}getProjectedFreeSpace(t){const{sourcePoint:e,candidate:n}=t,o=n.x-e.x,i=n.y-e.y;return Math.abs(o)<=Wj||Math.abs(i)<=Wj?this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:o,y:i},travelDistance:xe(e,n)}):Math.min(this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:0,y:Math.sign(i)},travelDistance:Math.abs(i)}),this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:Math.sign(o),y:Math.sign(i)},travelDistance:xe(e,n)}),this.getProjectedFreeSpaceAlongDirection({...t,direction:{x:Math.sign(o),y:0},travelDistance:Math.abs(o)}))}getProjectedFreeSpaceAlongDirection(t){const{sourcePoint:e,sourceLayer:n,sourceObstacle:o,direction:i,travelDistance:r}=t,s=Math.hypot(i.x,i.y);if(s<=Wj||r<=Wj)return 0;const a=this.getRayProbeDistance(),c=i.x/s,l=i.y/s,d={x:e.x+c*a,y:e.y+l*a};let h=Number.POSITIVE_INFINITY;for(const t of this.ogSrj.obstacles)if(t!==o&&t.layers.includes(n))for(const n of Cl(t)){const t=this.getRayIntersectionDistance({rayStart:e,rayEnd:d,segmentStart:n.start,segmentEnd:n.end});null!==t&&(h=Math.min(h,t))}for(const t of this.getBoardBoundarySegments()){const n=this.getRayIntersectionDistance({rayStart:e,rayEnd:d,segmentStart:t.start,segmentEnd:t.end});null!==n&&(h=Math.min(h,n))}return Number.isFinite(h)?Math.max(0,h-r):0}getMinBlockingClearance(t){const{candidate:e,connectionNetIds:n,sourceZ:o,targetZ:i}=t,r=Math.min(o,i),s=Math.max(o,i);let a=Number.POSITIVE_INFINITY;for(const t of this.ogSrj.obstacles){const n=this.getObstacleZs(t);if(!n.some(t=>t>=r&&t<=s))continue;if(t.isCopperPour&&!n.includes(o))continue;const i=Be(e,t)-this.viaRadius;if(a=Math.min(a,i),a+Wj<this.requiredViaToPadClearance)return a}return a}getMinPlacedEscapeViaClearance(t){let e=Number.POSITIVE_INFINITY;for(const n of this.createdEscapeVias){const o=xe(t,n)-this.viaDiameter;if(e=Math.min(e,o),e+Wj<this.obstacleMargin)return e}return e}selectPointOwner(t){const{point:e,groupConnections:n,matchingCopperPours:o}=t,i=ua(e),r=n.map(t=>({connection:t,pointIndex:t.pointsToConnect.findIndex(t=>ua(t)===i)})).filter(t=>-1!==t.pointIndex);return 0===r.length?null:(r.sort((t,e)=>{const n=o.some(e=>this.obstacleMatchesConnectionNet(e,this.getConnectionNetIds(t.connection)));return n!==o.some(t=>this.obstacleMatchesConnectionNet(t,this.getConnectionNetIds(e.connection)))?n?-1:1:t.pointIndex-e.pointIndex}),r[0])}findBestEscapeViaCandidate(t){const{connection:e,point:n,pointIndex:o,matchingCopperPours:i,connectionNetIds:r,sourceObstacle:s}=t;if(!_o(n))return null;const a=n.layer,c=ko(a,this.ogSrj.layerCount),l=s??this.selectSourceObstacle({point:n,sourceLayer:a,connectionNetIds:r}),d=this.getCandidatePositions(n,l);let h=null;for(const t of i){const i=t.layers[0];if(!i||i===a)continue;const s=ko(i,this.ogSrj.layerCount),u=Hj(t);for(const p of d){if(!this.isInsideBoard(p))continue;if(!Xj(p,t))continue;if(!this.hasClearEscapePath({sourcePoint:n,candidate:p,sourceLayer:a,sourceObstacle:l}))continue;const d=this.getMinBlockingClearance({candidate:p,connectionNetIds:r,sourceZ:c,targetZ:s});if(d+Wj<this.requiredViaToPadClearance)continue;const m=this.getMinPlacedEscapeViaClearance(p);if(m+Wj<this.obstacleMargin)continue;const g=this.getProjectedFreeSpace({sourcePoint:n,candidate:p,sourceLayer:a,sourceObstacle:l}),f=Math.min(g,3),y=100*d-xe(n,p)-.5*Math.abs(s-c)+2*f+(Number.isFinite(m)?10*Math.min(m,this.requiredViaToViaClearance):0);(!h||y>h.score)&&(h={pointId:`${Vj}${e.name}:${n.pointId??`p${o}`}:${i}:${this.nextEscapeViaIndex++}`,x:p.x,y:p.y,connectionName:e.name,rootConnectionName:e.__rootConnectionNames?.[0]??e.name,sourcePointIndex:o,sourcePointId:n.pointId,sourceLayer:a,targetLayer:i,targetPourKey:u,score:y})}}return h}buildPointPlacementPlans(t){const{mergedConnection:e,groupConnections:n,matchingCopperPours:o,connectionNetIds:i}=t,r=[];for(const t of e.pointsToConnect){const e=this.selectPointOwner({point:t,groupConnections:n,matchingCopperPours:o});if(!e)continue;const s=_o(t)?this.selectSourceObstacle({point:t,sourceLayer:t.layer,connectionNetIds:i}):void 0,a=_o(t)?this.getCandidatePositions(t,s).length:0;r.push({point:t,pointOwner:e,sourceObstacle:s,candidateCount:a})}return r.sort((t,e)=>{if(t.candidateCount!==e.candidateCount)return t.candidateCount-e.candidateCount;const n=(t.sourceObstacle?.width??0)*(t.sourceObstacle?.height??0),o=(e.sourceObstacle?.width??0)*(e.sourceObstacle?.height??0);return n!==o?n-o:t.pointOwner.pointIndex-e.pointOwner.pointIndex})}_step(){const t=this.ogSrj.obstacles.filter(t=>t.isCopperPour),e=this.ogSrj.connections,n=e.map(t=>structuredClone(t)),o=new Map(n.map(t=>[t.name,t])),i=structuredClone(this.ogSrj.obstacles),r=pa([...e]);for(const n of r){const r=new Set(n.__rootConnectionNames??[n.name]),s=e.filter(t=>(t.__rootConnectionNames??[t.name]).some(t=>r.has(t)));if(0===s.length)continue;const a=new Set;for(const t of s)for(const e of this.getConnectionNetIds(t))a.add(e);const c=t.filter(t=>this.obstacleMatchesConnectionNet(t,a));if(0===c.length)continue;const l=new Map,d=new Map,h=this.buildPointPlacementPlans({mergedConnection:n,groupConnections:s,matchingCopperPours:c,connectionNetIds:a});for(const{point:t,pointOwner:e,sourceObstacle:n}of h){const r=this.findBestEscapeViaCandidate({connection:e.connection,point:t,pointIndex:e.pointIndex,matchingCopperPours:c,connectionNetIds:a,sourceObstacle:n});if(!r)continue;const s=o.get(e.connection.name);if(!s)continue;if(s.pointsToConnect.some(t=>_o(t)&&t.layer===r.sourceLayer&&Gj(t,r)))continue;s.pointsToConnect.push({x:r.x,y:r.y,layer:r.sourceLayer,pointId:r.pointId,terminalVia:{toLayer:r.targetLayer,viaDiameter:this.viaDiameter}}),this.escapeViaMetadataByPointId.set(r.pointId,r),this.createdEscapeVias.push(r),i.push(this.createEscapeViaObstacle({escapeVia:r,connectionNetIds:this.getConnectionNetIds(e.connection)}));const h=l.get(r.targetPourKey);h?h.push(r.pointId):l.set(r.targetPourKey,[r.pointId]),d.has(r.targetPourKey)||d.set(r.targetPourKey,e.connection.name)}for(const[t,e]of l.entries()){if(e.length<=1)continue;const n=d.get(t);if(!n)continue;const i=o.get(n);i&&(i.externallyConnectedPointIds=[...i.externallyConnectedPointIds??[],e])}}this.outputSrj={...structuredClone(this.ogSrj),connections:n,obstacles:i},this.solved=!0}getOutputSimpleRouteJson(){return structuredClone(this.outputSrj)}getEscapeViaMetadataByPointId(){return new Map(this.escapeViaMetadataByPointId)}visualize(){return{title:"Escape Via Location Solver",points:this.outputSrj.connections.flatMap(t=>t.pointsToConnect.map(e=>({x:e.x,y:e.y,color:!0===e.pointId?.startsWith(Vj)?"#0f766e":"#dc2626",label:!0===e.pointId?.startsWith(Vj)?`${t.name}\nescape via`:t.name}))),lines:this.createdEscapeVias.map(t=>{const e=this.outputSrj.connections.find(e=>e.name===t.connectionName)?.pointsToConnect[t.sourcePointIndex]??null;return{points:e?[{x:e.x,y:e.y},{x:t.x,y:t.y}]:[{x:t.x,y:t.y}],strokeColor:"#0f766e"}}),circles:this.createdEscapeVias.map(t=>({center:{x:t.x,y:t.y},radius:this.viaRadius,strokeColor:"#0f766e",label:`${t.connectionName}\n${t.targetLayer}`})),rects:this.outputSrj.obstacles.filter(t=>!t.isCopperPour).map(t=>({...t,fill:"rgba(220,38,38,0.12)"}))}}},Zj=t=>({...t}),qj=t=>({...t,route:t.route?.map(Zj),vias:t.vias?.map(t=>({...t}))}),Jj=t=>t.map(qj),Kj="#0000FF",Qj=.15,t$=1e-6,e$=.1,n$=["top","bottom","left","right"],o$=t=>t.x*t.x+t.y*t.y,i$=(t,e)=>({x:t.x-e.x,y:t.y-e.y}),r$=(t,e,n)=>{const o=i$(n,e),i=o$(o);if(i<=t$)return Math.sqrt(o$(i$(t,e)));const r=(a=i$(t,e),c=o,s=(a.x*c.x+a.y*c.y)/i,Math.max(0,Math.min(1,s)));var s,a,c;const l={x:e.x+o.x*r,y:e.y+o.y*r};return Math.sqrt(o$(i$(t,l)))},s$=t=>1===t?.z?"bottom":"top",a$=(t,e,n)=>(t.z??0)===(e.z??0)&&((e.z??0)===(n.z??0)&&(t.x===e.x&&e.x===n.x||t.y===e.y&&e.y===n.y)),c$=(t,e,n)=>{const o=n?.get(t);if(o)return o;const i=t.route??[],r=t.traceThickness??Qj;let s=Number.POSITIVE_INFINITY,a=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY,l=Number.NEGATIVE_INFINITY,d=!1;const h=(t,e,n)=>{s=Math.min(s,t-n),a=Math.min(a,e-n),c=Math.max(c,t+n),l=Math.max(l,e+n),d=!0},u={segments:[],segmentsByLayer:{top:[],bottom:[]},vias:(t.vias??[]).map(n=>{const o=(n.diameter??t.viaDiameter??.3)/2;return h(n.x,n.y,o),{center:{x:n.x,y:n.y},radius:o,routeIndex:e}}),bounds:{minX:0,minY:0,maxX:0,maxY:0}};for(let t=0;t<i.length-1;){const n=i[t];let o=t+1,s=i[o];const a=r/2;for(n&&h(n.x,n.y,a),s&&h(s.x,s.y,a);o<i.length-1;){const t=i[o],e=i[o+1];if(!n||!t||!e)break;if(s$(n)!==s$(t))break;if(s$(t)!==s$(e))break;if(!a$(n,t,e))break;o+=1,s=e,h(e.x,e.y,a)}if(!n||!s){t+=1;continue}const c=s$(n),l={start:n,end:s,routeIndex:e,pointIndex:t,endPointIndex:o,thickness:r,halfThickness:a,layer:c,minX:Math.min(n.x,s.x)-a,maxX:Math.max(n.x,s.x)+a,minY:Math.min(n.y,s.y)-a,maxY:Math.max(n.y,s.y)+a};u.segments.push(l),u.segmentsByLayer[c].push(l),t=o}if(!d)for(const t of i)h(t.x,t.y,r/2);return u.bounds=d?{minX:s,minY:a,maxX:c,maxY:l}:{minX:0,minY:0,maxX:0,maxY:0},n?.set(t,u),u},l$=(t,e,n)=>e.x<=Math.max(t.x,n.x)+tamp;&e.x>=Math.min(t.x,n.x)-tamp;&e.y<=Math.max(t.y,n.y)+tamp;&e.y>=Math.min(t.y,n.y)-t$,d$=(t,e,n)=>(e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y),h$=(t,e,n,o)=>((t,e,n,o)=>{const i=d$(t,e,n),r=d$(t,e,o),s=d$(n,o,t),a=d$(n,o,e);return!!(Math.abs(i)<=tamp;&l$(t,n,e))||!!(Math.abs(r)<=tamp;&l$(t,o,e))||!!(Math.abs(s)<=tamp;&l$(n,t,o))||!!(Math.abs(a)<=tamp;&l$(n,e,o))||i>0!=r>0&&s>0!=a>0})(t,e,n,o)?0:Math.min(r$(t,n,o),r$(e,n,o),r$(n,t,e),r$(o,t,e)),u$=(t,e)=>Math.abs(t.x-e.x)<=tamp;&Math.abs(t.y-e.y)<=t$,p$=(t,e)=>u$(t.start,e.start)||u$(t.start,e.end)||u$(t.end,e.start)||u$(t.end,e.end),m$=t=>{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=>Boolean(t));return Array.from(new Set(e))},g$=(t,e)=>{const n=m$(t),o=m$(e);return 0!==n.length&&0!==o.length&&n.some(t=>o.includes(t))},f$=(t,e,n)=>t.minX-n<=e.maxX&&t.maxX+n>=e.minX&&t.minY-n<=e.maxY&&t.maxY+n>=e.minY,y$=(t,e,n)=>{const o=n+t.halfThickness+e.halfThickness-t$;return t.minX-n<=e.maxX&&t.maxX+n>=e.minX&&t.minY-n<=e.maxY&&t.maxY+n>=e.minY&&o>0},_$=(t,e,n,o)=>{const i=o+n.halfThickness+e-t$,r=t.x-i,s=t.x+i,a=t.y-i,c=t.y+i;return r<=n.maxX&&s>=n.minX&&a<=n.maxY&&c>=n.minY},b$=(t,e)=>{const n=new WeakMap,o=t.map((t,e)=>c$(t,e,n)),i=[],r=new Set,s=t=>{r.has(t.label)||(r.add(t.label),i.push(t))};for(let n=0;n<o.length;n+=1){const i=o[n];if(i)for(let r=n+1;r<o.length;r+=1){const a=o[r];if(a&&(!g$(t[n],t[r])&&f$(i.bounds,a.bounds,e))){for(const t of["top","bottom"]){const o=i.segmentsByLayer[t],c=a.segmentsByLayer[t];for(const i of o)for(const o of c){if(p$(i,o))continue;if(!y$(i,o,e))continue;const a=e+(i.thickness+o.thickness)/2-t$;if(h$(i.start,i.end,o.start,o.end)>=a)continue;s({center:{x:(Math.max(i.minX-e,o.minX-e)+Math.min(i.maxX+e,o.maxX+e))/2,y:(Math.max(i.minY-e,o.minY-e)+Math.min(i.maxY+e,o.maxY+e))/2},label:`trace-violation:${n}:s${i.pointIndex}:${r}:s${o.pointIndex}:${t}`})}}for(const t of i.segments)for(const[o,i]of a.vias.entries()){if(!_$(i.center,i.radius,t,e))continue;const a=e+t.halfThickness+i.radius-t$;r$(i.center,t.start,t.end)>=a||s({center:i.center,label:`trace-violation:${n}:s${t.pointIndex}:${r}:v${o}`})}for(const t of a.segments)for(const[o,a]of i.vias.entries()){if(!_$(a.center,a.radius,t,e))continue;const i=e+t.halfThickness+a.radius-t$;r$(a.center,t.start,t.end)>=i||s({center:a.center,label:`trace-violation:${n}:v${o}:${r}:s${t.pointIndex}`})}}}}return(t=>{const e=[];for(const n of t){const t=e.find(t=>{return e=t.center,o=n.center,Math.hypot(e.x-o.x,e.y-o.y)<=.28;var e,o});t?(t.center={x:(t.center.x*t.count+n.center.x)/(t.count+1),y:(t.center.y*t.count+n.center.y)/(t.count+1)},t.labels.push(n.label),t.count+=1):e.push({center:n.center,labels:[n.label],count:1})}return e.map((t,e)=>({center:t.center,radius:Math.min(.3,.2+.035*Math.sqrt(t.count-1)),stroke:"#f59e0b",fill:"rgba(245, 158, 11, 0.46)",label:1===t.count?t.labels[0]:`trace-violations:${e}:count-${t.count}`}))})(i)},x$=({routeIndexes:t,layers:e,routePointIndexes:n})=>`${t[0]}:${e[0]}:${n[0].join(",")}:${t[1]}:${e[1]}:${n[1].join(",")}`,v$=(t,e,n,o,i,r,s)=>{const a=((t,e,n,o,i,r)=>t<n?`${t}:${e}:${i.join(",")}:${n}:${o}:${r.join(",")}`:`${n}:${o}:${r.join(",")}:${t}:${e}:${i.join(",")}`)(e,n,o,i,r,s),c=t.get(a);if(c){const[t,n]=e<o?[r,s]:[s,r];for(const e of t)c.routePointIndexes[0].includes(e)||c.routePointIndexes[0].push(e);for(const t of n)c.routePointIndexes[1].includes(t)||c.routePointIndexes[1].push(t);return c.routePointIndexes[0].sort((t,e)=>t-e),void c.routePointIndexes[1].sort((t,e)=>t-e)}e<o?t.set(a,{routeIndexes:[e,o],layers:[n,i],routePointIndexes:[[...new Set(r)].sort((t,e)=>t-e),[...new Set(s)].sort((t,e)=>t-e)]}):t.set(a,{routeIndexes:[o,e],layers:[i,n],routePointIndexes:[[...new Set(s)].sort((t,e)=>t-e),[...new Set(r)].sort((t,e)=>t-e)]})},S$=t=>{const e=[];for(let n=t.pointIndex;n<=t.endPointIndex;n+=1)e.push(n);return e},I$=(t,e)=>!e||t.some(t=>e.has(t)),C$=(t,e)=>{const n=t.route??[],o=[];for(let t=0;t<n.length;t+=1){const i=n[t];i&&(Math.abs(i.x-e.center.x)<=tamp;&Math.abs(i.y-e.center.y)<=tamp;&o.push(t))}return o},P$=(t,e,n)=>t.minX-n<=e.maxX&&t.maxX+n>=e.minX&&t.minY-n<=e.maxY&&t.maxY+n>=e.minY,M$=(t,e,n)=>{const o=n+t.halfThickness+e.halfThickness-t$;return t.minX-n<=e.maxX&&t.maxX+n>=e.minX&&t.minY-n<=e.maxY&&t.maxY+n>=e.minY&&o>0},N$=(t,e,n,o)=>{const i=o+n.halfThickness+e-t$,r=t.x-i,s=t.x+i,a=t.y-i,c=t.y+i;return r<=n.maxX&&s>=n.minX&&a<=n.maxY&&c>=n.minY},w$=(t,e,n)=>{const o=n+t.radius+e.radius-t$;return Math.abs(t.center.x-e.center.x)<=o&&Math.abs(t.center.y-e.center.y)<=o},T$=(t,e,n,o,i)=>{const r=t.map((t,e)=>c$(t,e,o)),s=new Map;if(0===e.size)return[];const a=Array.from(e),c=new Map,l=t=>{const e=c.get(t);if(e)return e;const o=r[t];if(!o)return[];const i=[];for(let e=0;e<r.length;e+=1){if(e===t)continue;const s=r[e];s&&(P$(o.bounds,s.bounds,n)&&i.push(e))}return c.set(t,i),i};for(const t of a){const o=r[t];if(!o)continue;const a=l(t),c=i?.get(t);for(const l of o.segments){const o=S$(l);if(I$(o,c))for(const c of a){if(t>c&&e.has(c))continue;const a=r[c];if(!a)continue;const d=i?.get(c),h=a.segmentsByLayer[l.layer];for(const t of h){const e=S$(t);if(!I$(e,d))continue;if(p$(l,t))continue;if(!M$(l,t,n))continue;const i=n+(l.thickness+t.thickness)/2-t$;h$(l.start,l.end,t.start,t.end)<i&&v$(s,l.routeIndex,l.layer,t.routeIndex,t.layer,o,e)}}}}for(const o of a){const a=r[o];if(!a)continue;const c=l(o),d=i?.get(o);for(const l of a.vias){const a=C$(t[l.routeIndex],l);if(I$(a,d))for(const t of c){if(o>t&&e.has(t))continue;const c=r[t];if(!c)continue;const d=i?.get(t);for(const t of c.segments){const e=S$(t);if(!I$(e,d))continue;if(!N$(l.center,l.radius,t,n))continue;const o=n+t.thickness/2+l.radius-t$;r$(l.center,t.start,t.end)<o&&v$(s,t.routeIndex,t.layer,l.routeIndex,"via",e,a)}}}}for(const e of a){const o=r[e];if(!o)continue;const a=l(e),c=i?.get(e);for(const e of o.segments){const o=S$(e);if(I$(o,c))for(const c of a){const a=r[c];if(!a)continue;const l=i?.get(c);for(const i of a.vias){const r=C$(t[i.routeIndex],i);if(!I$(r,l))continue;if(!N$(i.center,i.radius,e,n))continue;const a=n+e.thickness/2+i.radius-t$;r$(i.center,e.start,e.end)<a&&v$(s,e.routeIndex,e.layer,i.routeIndex,"via",o,r)}}}}for(const o of a){const a=r[o];if(!a)continue;const c=l(o),d=i?.get(o);for(const l of a.vias){const a=C$(t[l.routeIndex],l);if(I$(a,d))for(const d of c){if(o>d&&e.has(d))continue;const c=r[d];if(!c)continue;const h=i?.get(d);for(const e of c.vias){const o=C$(t[e.routeIndex],e);if(!I$(o,h))continue;if(!w$(l,e,n))continue;const i=n+l.radius+e.radius-t$;Math.hypot(l.center.x-e.center.x,l.center.y-e.center.y)<i&&v$(s,l.routeIndex,"via",e.routeIndex,"via",a,o)}}}}return Array.from(s.values())},R$=(t,e)=>t.x>=e.minX-tamp;&t.x<=e.maxX+tamp;&t.y>=e.minY-tamp;&t.y<=e.maxY+t$,E$=(t,e,n)=>{switch(e){case"left":return{minX:t.minX,maxX:t.minX+n,minY:t.minY,maxY:t.maxY};case"right":return{minX:t.maxX-n,maxX:t.maxX,minY:t.minY,maxY:t.maxY};case"top":return{minX:t.minX,maxX:t.maxX,minY:t.maxY-n,maxY:t.maxY};case"bottom":return{minX:t.minX,maxX:t.maxX,minY:t.minY,maxY:t.minY+n}}},A$=(t,e,n)=>{const o=e.x-t.x,i=e.y-t.y;let r=0,s=1;const a=(t,e)=>{if(Math.abs(t)<=t$)return e>=-1e-6;const n=e/t;return t<0?!(n>s)&&(n>r&&(r=n),!0):!(n<r)&&(n<s&&(s=n),!0)};if(!(a(-o,t.x-n.minX)&&a(o,n.maxX-t.x)&&a(-i,t.y-n.minY)&&a(i,n.maxY-t.y)))return 0;const c=Math.hypot(o,i);return Math.max(0,s-r)*c},O$=(t,e)=>n$.filter(n=>{switch(n){case"left":return Math.abs(t.x-e.minX)<=t$;case"right":return Math.abs(t.x-e.maxX)<=t$;case"top":return Math.abs(t.y-e.maxY)<=t$;case"bottom":return Math.abs(t.y-e.minY)<=t$}return!1}),k$=(t,e)=>{const n=[];return t.x<e.minX-tamp;&n.push("left"),t.x>e.maxX+tamp;&n.push("right"),t.y>e.maxY+tamp;&n.push("top"),t.y<e.minY-tamp;&n.push("bottom"),n},L$=(t,e,n)=>{const o=e.x-t.x,i=e.y-t.y;switch(n){case"left":case"right":return Math.abs(o)<=tamp;&Math.abs(i)>t$;case"top":case"bottom":return Math.abs(i)<=tamp;&Math.abs(o)>t$}},D$=(t,e,n)=>{const o=[],i=Math.max(n,t$),r=Math.min(.1,i/4);for(let n=0;n<t.length;n+=1){const s=t[n],a=s?.route??[];for(let t=0;t<a.length-1;t+=1){const c=a[t],l=a[t+1];if(!c||!l)continue;const d=k$(c,e),h=k$(l,e),u=O$(c,e),p=O$(l,e),m=n$.filter(t=>{if(s.connectedPadSides?.includes(t))return!1;return!(A$(c,l,E$(e,t,i))<=r)&&!!L$(c,l,t)}),g=!R$(c,e)||!R$(l,e),f=Array.from(new Set([...m,...d,...h]));(g||0!==f.length)&&o.push({routeIndex:n,connectionName:s.connectionName??s.rootConnectionName??`route-${n}`,segmentIndex:t,touchedSides:f,startSides:u,endSides:p,start:c,end:l})}}return o},z$=t=>t?.center&&t.width&&t.height?{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,width:t.width,height:t.height,center:t.center}:null,F$=t=>"bottom"===t?Kj:"#FF0000",B$=t=>{const e=t.route??[],n=[];if(e.length<2)return n;let o=s$(e[0]),i=[e[0]];for(let r=1;r<e.length;r+=1){const s=e[r],a=s$(s);a===o?i.push(s):(i.length>=2&&n.push({points:i,strokeColor:F$(o),strokeWidth:t.traceThickness??Qj,label:t.connectionName??"route"}),o=a,i=[e[r-1],s])}return i.length>=2&&n.push({points:i,strokeColor:F$(o),strokeWidth:t.traceThickness??Qj,label:t.connectionName??"route"}),n},j$=(t,e)=>({title:`HighDensityRepair02 Initial State (margin=${e})`,routes:t}),$=t=>{const e=[];for(const n of t){const t=e[e.length-1];t&&t.z===n.z&&u$(t,n)||e.push(n)}return e},Y$=(t,e,n)=>{const o=Math.max(0,t.minX-e.maxX,e.minX-t.maxX),i=Math.max(0,t.minY-e.maxY,e.minY-t.maxY);return Math.hypot(o,i)<=n+t$},X$=(t,e)=>{let n=Number.POSITIVE_INFINITY;for(const o of t.segments)for(const t of e.segments){if(o.layer!==t.layer)continue;const e=h$(o.start,o.end,t.start,t.end)-(o.thickness+t.thickness)/2;n=Math.min(n,e)}return n},V$=({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,maximumAllowedClearance:o})=>{const i=new WeakMap,r=new WeakMap,s=[],a=Array.from(n).sort((t,e)=>t-e),c=t.map((t,e)=>c$(t,e,i)),l=e.map((t,e)=>c$(t,e,r)),d=new Set;for(const t of a)for(let n=0;n<e.length;n+=1){if(n===t)continue;const e=Math.min(t,n),i=Math.max(t,n),r=`${e}:${i}`;if(d.has(r))continue;d.add(r);const a=l[e],h=l[i];if(!a||!h||!Y$(a.bounds,h.bounds,o))continue;const u=X$(a,h);if(!Number.isFinite(u)||u>o+t$||!c[e]||!c[i])continue;const p=X$(c[e],c[i]);!Number.isFinite(p)||u>=p-t$||s.push({routeIndexes:[e,i],previousClearance:p,nextClearance:u})}return s},W$=.001,H$=(t,e)=>t.map(t=>{const n=t.route??[];return 0===n.length?t:{...t,route:n.map((t,o)=>0===o||o===n.length-1?((t,e)=>{const n={...t};return Math.abs(n.x-e.minX)<=W$?n.x=e.minX:Math.abs(n.x-e.maxX)<=Wamp;&(n.x=e.maxX),Math.abs(n.y-e.minY)<=W$?n.y=e.minY:Math.abs(n.y-e.maxY)<=Wamp;&(n.y=e.maxY),n})(t,e):t)}}),G$=(t,e)=>Array.from(e).flatMap(e=>B$(t[e]).map(t=>({...t,strokeColor:"#000000",strokeWidth:t.strokeWidth,label:`candidate:${t.label}`}))),U$=(t,e,n,o,i)=>{const r="rgba(0, 0, 0, 0)";switch(e){case"left":return{center:{x:t.minX+n/2,y:t.center.y},width:n,height:t.height,stroke:r,fill:o,label:i};case"right":return{center:{x:t.maxX-n/2,y:t.center.y},width:n,height:t.height,stroke:r,fill:o,label:i};case"top":return{center:{x:t.center.x,y:t.maxY-n/2},width:t.width,height:n,stroke:r,fill:o,label:i};case"bottom":return{center:{x:t.center.x,y:t.minY+n/2},width:t.width,height:n,stroke:r,fill:o,label:i}}},Z$=({routes:t,candidateRoutes:e,candidateRouteIndexes:n,originalRoutes:o,boundary:i,side:r,margin:s,rejected:a,rejectionReason:c})=>{const l=Array.from(n).map(t=>e[t].connectionName??`route-${t}`);return{title:a?`${r} move rejected (${c})`:`${r} move accepted`,routes:a?t:e,originalRoutes:o,activeSide:r,candidateRouteNames:l,overlayLines:a?G$(e,n):[],overlayRects:[U$(i,r,s,a?"rgba(220, 38, 38, 0.14)":"rgba(16, 185, 129, 0.14)",a?`rejected:${r}`:`accepted:${r}`)]}},q$=(t,e,n,o)=>{const i=(t?.adjacentObstacles??[]).some(t=>((t,e,n,o)=>{const i=(t=>t.center&&t.width&&t.height?{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}:null)(t);if(!i)return!1;switch(n){case"left":return i.maxX>=e.minX-tamp;&i.minX<=e.minX+o+t$;case"right":return i.minX<=e.maxX+tamp;&i.maxX>=e.maxX-o-t$;case"top":return i.minY<=e.maxY+tamp;&i.maxY>=e.maxY-o-t$;case"bottom":return i.maxY>=e.minY-tamp;&i.minY<=e.minY+o+t$}})(t,e,n,o));return{hasObstacle:i,moveAmount:i?o:o/2}},J$=({start:t,end:e,side:n,boundary:o,amount:i,targetAxisValue:r})=>{const s=(({side:t,boundary:e,amount:n,targetAxisValue:o})=>{const i=o??(()=>{switch(t){case"left":return e.minX+n;case"right":return e.maxX-n;case"top":return e.maxY-n;case"bottom":return e.minY+n}})();switch(t){case"left":case"right":return Math.min(Math.max(i,e.minX),e.maxX);case"top":case"bottom":return Math.min(Math.max(i,e.minY),e.maxY)}})({side:n,boundary:o,amount:i,targetAxisValue:r});switch(n){case"left":case"right":return $([t,{x:s,y:t.y,z:t.z},{x:s,y:e.y,z:e.z},e]);case"top":case"bottom":return $([t,{x:t.x,y:s,z:t.z},{x:e.x,y:s,z:e.z},e])}},K$=(t,e,n,o,i,r,s,a=!1)=>{const c=t.route??[];if(c.length<2||0===e.length)return qj(t);const l=a?i:Math.max(i,r),d=((t,e)=>{switch(t){case"left":return{x:e,y:0};case"right":return{x:-e,y:0};case"top":return{x:0,y:-e};case"bottom":return{x:0,y:e}}})(o,l);if(a||(t.vias?.length??0)>0||c.length>2){const n=qj(t),o=n.route??[];for(const t of e){const e=o[t];e&&(o[t]={...e,x:e.x+d.x,y:e.y+d.y})}for(const o of n.vias??[]){e.some(e=>{const n=t.route?.[e];return!!n&&u$(n,o)})&&(o.x+=d.x,o.y+=d.y)}return n}const h=qj(t);if(2===c.length&&2===e.length&&0===e[0]&&1===e[1]){const e=c[0],i=c[1];return qj({...t,route:J$({start:e,end:i,side:o,boundary:n,amount:l,targetAxisValue:s})})}return h},Q$=(t,e,n)=>{switch(n){case"left":return t.x-e.minX;case"right":return e.maxX-t.x;case"top":return e.maxY-t.y;case"bottom":return t.y-e.minY}},tY=(t,e,n)=>{const o=(t=>{const e=t.route??[];if(0===e.length)return[];const n=[];for(let t=0;t<e.length;t+=1){const o=e[t];if(!o)continue;0===t||t===e.length-1||n.push(o);const i=e[t+1];i&&n.push({x:(o.x+i.x)/2,y:(o.y+i.y)/2})}return n})(t);return 0===o.length?Number.POSITIVE_INFINITY:o.reduce((t,o)=>Math.min(t,Q$(o,e,n)),Number.POSITIVE_INFINITY)},eY=(t,e,n=[])=>{const o=t.route??[],i=[],r=new Set,s=0===e.length||e.includes("via");if(2===o.length)return[0,1];const a=t=>{if(t<=0||t>=o.length-1)return;if(r.has(t))return;const n=o[t];n&&(s||e.includes(s$(n)))&&(r.add(t),i.push(t))};if(n.length>0)for(const t of n)a(t);else for(let t=1;t<o.length-1;t+=1)a(t);for(let t=0;t<i.length;t+=1){const e=i[t],n=o[e];if(n)for(let t=1;t<o.length-1;t+=1){if(r.has(t))continue;const e=o[t];e&&(e.z!==n.z&&u$(e,n)&&(r.add(t),i.push(t)))}}return i.sort((t,e)=>t-e),i},nY=(t,e)=>Math.max(0,...(t.route??[]).map(t=>Math.max(e.minX-t.x,t.x-e.maxX,e.minY-t.y,t.y-e.maxY,0))),oY=(t,e,n,o)=>Q$(t,e,n)<=o+t$,iY=(t,e,n,o)=>{const i=t.route??[],r=[],s=new Set;let a=1,c=i.length-2;for(;a<i.length-1&&u$(i[a],i[0]);)a+=1;for(;c>0&&u$(i[c],i[i.length-1]);)c-=1;for(let t=a;t<=c;t+=1)oY(i[t],e,n,o)&&(s.add(t),r.push(t));for(let t=0;t<r.length;t+=1){const e=i[r[t]];if(e)for(let t=a;t<=c;t+=1){if(s.has(t))continue;const n=i[t];n&&(n.z!==e.z&&u$(n,e)&&(s.add(t),r.push(t)))}}return 0===r.length&&2===i.length&&i.some(t=>oY(t,e,n,o))?[0,1]:(r.sort((t,e)=>t-e),r)},rY=(t,e,n)=>{const o=t.route??[],i=0===n?o[0]:o[o.length-1];return i?n$.filter(t=>Q$(i,e,t)<=t$):[]},sY=(t,e,n)=>{const o=t.route??[],i=e.route??[];if(0===o.length||0===i.length)return!0;for(const e of[0,-1]){const o=rY(t,n,e);if(0===o.length)continue;const r=0===e?i[0]:i[i.length-1];if(!r)return!1;for(const t of o)if(Q$(r,n,t)>t$)return!1}return!0},aY=(t,e)=>Math.hypot(e.x-t.x,e.y-t.y),cY=(t,e,n,o)=>{const i=t.route??[];if(0===i.length)return"none";let r=!1;for(let t=0;t<i.length;t+=1){const s=i[t];if(s&&oY(s,e,n,o)){if(0!==t&&t!==i.length-1)return"interior";r=!0}}for(let t=0;t<i.length-1;t+=1){const r=i[t],s=i[t+1];if(r&&s&&(oY(r,e,n,o)&&oY(s,e,n,o)&&!(aY(r,s)<=t$)))return"interior"}return r?"endpoint":"none"},lY=({currentRoutes:t,routeIndex:e,side:n,moveSide:o=n,boundary:i,margin:r,moveAmount:s,geometryCache:a})=>{const c=t[e],l=2===(c.route?.length??0),d=iY(c,i,n,r);if(0===d.length)return null;const h=new Set,u=new Map,p=new Set,m=t.slice();let g=!1,f="overlap";const y=new Set([e]),_=new Map([[e,new Set]]),b=new Map([[e,new Set]]),x=[e];let v=0,S=null,I=null,C=null,P=null;const M=t=>new Set(t.map(t=>x$(t))),N=()=>S||(S=T$(t,h,r,a,u),S),w=()=>C||(C=T$(t,h,0,a,u),C),T=()=>P||(P=T$(m,h,0,a,u),P);for(;v<x.length&&!g;){const c=x[v];if(v+=1,y.delete(c),h.has(c))continue;const l=m[c],d=Array.from(_.get(c)??[]),w=Array.from(b.get(c)??[]);_.delete(c),b.delete(c);const T=c===e?iY(l,i,n,r):eY(l,d,w);if(0===T.length){if(c===e)return null;g=!0,f="eventual-overlap";break}const R=l.route??[],E=c===e?void 0:"left"===o||"right"===o?(R[T[0]]?.x??0)+("left"===o?s:-s):(R[T[0]]?.y??0)+("top"===o?-s:s);m[c]=K$(l,T,i,o,s,r,E,c!==e),h.add(c),u.set(c,new Set(T)),S=null,I=null,C=null,P=null,2===(l.route?.length??0)&&p.add(c);const A=nY(t[c],i);if(nY(m[c],i)>A+1e-6){g=!0,f="boundary";break}if(!sY(t[c],m[c],i)){g=!0,f="endpoint-boundary";break}const O=T$(m,new Set([c]),r,a,new Map([[c,new Set(T)]]));for(const t of O){if(M(N()).has(x$(t)))continue;const[e,n]=t.routeIndexes,o=h.has(e),i=h.has(n);if(o&&i)continue;const r=o?n:e,s=o?t.layers[1]:t.layers[0],a=o?t.routePointIndexes[1]:t.routePointIndexes[0];if(h.has(r)||y.has(r)){if(y.has(r)){const t=_.get(r)??new Set;t.add(s),_.set(r,t);const e=b.get(r)??new Set;for(const t of a)e.add(t);b.set(r,e)}}else y.add(r),x.push(r),_.set(r,new Set([s])),b.set(r,new Set(a))}}if(!g&&h.size>1){const t=M(N()),e=M(I||(I=T$(m,h,r,a,u),I));for(const n of e)if(!t.has(n)){g=!0,f="eventual-overlap";break}}if(!g&&h.size>1){const t=M(w()),e=M(T());for(const n of e)if(!t.has(n)){g=!0,f="eventual-overlap";break}}if(!g){const e=new Set(T$(t,h,0,a).map(t=>x$(t))),n=T$(m,h,0,a);for(const t of n){const n=x$(t);if(!e.has(n)){g=!0,f="eventual-overlap";break}}}if(!g){const e=(({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,boundary:o,activeSide:i})=>{const r=n$.filter(t=>t!==i),s=[];for(const i of n){const n=t[i],a=e[i];if(n&&a)for(const t of r){const e=tY(n,o,t),r=tY(a,o,t);e>tamp;&r<=tamp;&s.push({routeIndex:i,side:t,previousClearance:e,nextClearance:r})}}return s})({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,boundary:i,activeSide:n});e.length>0&&(g=!0,f="boundary-touch")}if(!g){const e=(({currentRoutes:t,candidateRoutes:e,candidateRouteIndexes:n,geometryCache:o,currentConflicts:i,candidateConflicts:r})=>{const s=i??T$(t,n,0,o),a=r??T$(e,n,0,o),c=new Set(s.map(t=>x$(t)));return a.filter(t=>{const o=x$(t);if(c.has(o))return!1;const[i,r]=t.routeIndexes,[s,a]=t.layers,l=n.has(i),d=n.has(r);if(l&&d)return!1;const h=l?a:s,u=e[l?r:i];return!!u&&0===eY(u,[h]).length})})({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,geometryCache:a,currentConflicts:w(),candidateConflicts:T()});e.length>0&&(g=!0,f="fixed-trace-touch")}if(!g){V$({currentRoutes:t,candidateRoutes:m,candidateRouteIndexes:h,maximumAllowedClearance:Math.min(r/2,e$)}).length>0&&(g=!0,f="trace-clearance")}return!g&&((t,e,n,o,i,r)=>Array.from(n).some(n=>{const s=t[n],a=e[n];return n$.filter(t=>t!==i).some(t=>{const e=cY(s,o,t,r),n=cY(a,o,t,r);return"none"===e&&"none"!==n})}))(t,m,h,i,n,r)&&(g=!0,f="side-regression"),{isTwoPointRoute:l,movableIndexes:d,candidateRouteIndexes:h,movedTwoPointRouteIndexes:p,candidateRoutes:m,rejected:g,rejectionReason:f}},dY=(t,e,n,o,i)=>{const r=t.route??[];if(0===e.length)return null;if("top"===o||"bottom"===o){const t=e.reduce((t,e)=>t+(r[e]?.x??n.center.x),0)/e.length;return t<n.center.x-i/2?"right":t>n.center.x+i/2?"left":null}const s=e.reduce((t,e)=>t+(r[e]?.y??n.center.y),0)/e.length;return s>n.center.y+i/2?"bottom":s<n.center.y-i/2?"top":null},hY=({side:t,sample:e,boundary:n,margin:o,repairedRoutes:i,frames:r,captureProgressFrames:s,lockedTwoPointRoutes:a,geometryCache:c,allowTwoPointWithoutObstacle:l=!1})=>{const{hasObstacle:d,moveAmount:h}=q$(e,n,t,o);s&&r.push(((t,e,n,o,i,r)=>({title:`${n} boundary analysis: move=${i.toFixed(3)} (${r?"obstacle-side":"clear-side"})`,routes:t,activeSide:n,overlayRects:[U$(e,n,o,"rgba(245, 158, 11, 0.16)",`strip:${n}`)]}))(Jj(i),n,t,o,h,d));const u=new Set;let p=0;for(let e=0;e<i.length;e+=1){if(u.has(e))continue;if(a.has(e))continue;const m=i[e];if(m.connectedPadSides?.includes(t))continue;if(2===(m.route?.length??0)&&!d&&!l)continue;let g=lY({currentRoutes:i,routeIndex:e,side:t,boundary:n,margin:o,moveAmount:h,geometryCache:c});if(g){if(g.rejected){const r=dY(m,g.movableIndexes,n,t,o);if(r){const s=lY({currentRoutes:i,routeIndex:e,side:t,moveSide:r,boundary:n,margin:o,moveAmount:h,geometryCache:c});s&&!s.rejected&&(g=s)}}if(s&&r.push(Z$({routes:Jj(i),candidateRoutes:g.candidateRoutes,candidateRouteIndexes:g.candidateRouteIndexes,originalRoutes:g.rejected?void 0:Array.from(g.candidateRouteIndexes).map(t=>qj(i[t])),boundary:n,side:t,margin:o,rejected:g.rejected,rejectionReason:g.rejectionReason})),!g.rejected){i.splice(0,i.length,...g.candidateRoutes);for(const t of g.movedTwoPointRouteIndexes)a.add(t);p+=1}u.add(e)}}return{movesAccepted:p}},uY=(t,e,n,o)=>oY(t,e,n,o),pY=(t,e,n,o)=>{switch(n){case"left":return{...t,x:Math.min(e.minX+o,e.maxX)};case"right":return{...t,x:Math.max(e.maxX-o,e.minX)};case"top":return{...t,y:Math.max(e.maxY-o,e.minY)};case"bottom":return{...t,y:Math.min(e.minY+o,e.maxY)}}},mY=t=>`${t.routeIndexes[0]}:${t.layers[0]}:${t.routeIndexes[1]}:${t.layers[1]}`,gY=t=>{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=>Boolean(t));return Array.from(new Set(e))},fY=(t,e)=>{const n=gY(t),o=gY(e);return 0!==n.length&&0!==o.length&&n.some(t=>o.includes(t))},yY=(t,e,n)=>t?D$([t],e,n).length:0,_Y=(t,e,n,o)=>{const i=new Set(T$(t,new Set([n]),o).map(x$));return T$(e,new Set([n]),o).some(t=>!i.has(x$(t)))},bY=(t,e,n)=>D$(t,e,n).length,xY=t=>{if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=>Boolean(t));return Array.from(new Set(e))},vY=(t,e)=>T$(t,new Set(t.map((t,e)=>e)),e$,e).filter(e=>!("via"===e.layers[0]&&"via"===e.layers[1]||((t,e)=>{const n=xY(t),o=xY(e);return 0!==n.length&&0!==o.length&&n.some(t=>o.includes(t))})(t[e.routeIndexes[0]],t[e.routeIndexes[1]]))).length,SY=t=>{const e=n$;return[...e.slice(t%e.length),...e.slice(0,t%e.length)]},IY=(t,e,n=!1)=>{const o=z$(t?.nodeWithPortPoints),i=o?((t,e)=>t.map(t=>{const n=t.route??[];let o=!1;const i=n.map(t=>{let n=t.x,i=t.y;return n<e.minX?n=e.minX:n>e.maxX&&(n=e.maxX),i<e.minY?i=e.minY:i>e.maxY&&(i=e.maxY),n===t.x&&i===t.y?t:(o=!0,{...t,x:n,y:i})});return o?{...t,route:i}:t}))(H$(Jj(t?.nodeHdRoutes??[]),o),o):Jj(t?.nodeHdRoutes??[]),r=Math.max(e??.4,.05),s=Jj(i);if(!o)return{boundary:null,baseRoutes:i,repairedRoutes:s,margin:r,frames:[{title:"HighDensityRepair02 Missing Boundary",routes:s}]};const a=n?[j$(Jj(s),r)]:[],c=new WeakMap;let l=bY(s,o,r);for(let e=0;e<1;e+=1){const i=new Set;let d=0;for(const l of SY(e)){const{movesAccepted:h}=hY({side:l,sample:t,boundary:o,frames:a,margin:r,repairedRoutes:s,captureProgressFrames:n,lockedTwoPointRoutes:i,geometryCache:c,allowTwoPointWithoutObstacle:e>=1});d+=h}const h=bY(s,o,r);if(0===d)break;if(0===h)break;if(h>=l)break;l=h}const d=Jj(s),h=vY(s,c);(({routes:t,boundary:e,margin:n,geometryCache:o})=>{const i=D$(t,e,n);if(0===i.length)return{movesAccepted:0};const r=new Map;for(const t of i){const e=r.get(t.routeIndex)??new Set;for(const n of t.touchedSides)e.add(n);r.set(t.routeIndex,e)}const s=[8e-6,.01,n/4,n/2,n+8e-6];let a=0;const c=(i,r,s)=>{const a=r.route??[];if(a.length<2)return!1;const c={...r,route:$(a)};if((c.route?.length??0)<2)return!1;const l=t.slice();if(l[i]=c,yY(l[i],e,n)>=s)return!1;const d=e=>fY(t[e.routeIndexes[0]],t[e.routeIndexes[1]]),h=new Set(T$(t,new Set([i]),0,o).filter(t=>!d(t)).map(mY));return!T$(l,new Set([i]),0,o).filter(t=>!d(t)).some(t=>!h.has(mY(t)))&&!(V$({currentRoutes:t,candidateRoutes:l,candidateRouteIndexes:new Set([i]),maximumAllowedClearance:Math.min(n/2,e$)}).filter(e=>!fY(t[e.routeIndexes[0]],t[e.routeIndexes[1]])).length>0||(t[i]=c,0))},l=(n,o,i,r)=>{if(0===o.length)return!1;for(const a of s){const s=t[n],l=qj(s),d=l.route??[];let h=!1;for(const t of o){const n=d[t];n&&(d[t]=pY(n,e,i,a),h=!0)}if(!h)return!1;if(c(n,l,r))return!0}return!1},d=(t,n)=>{const o=[];return"top"===n||"bottom"===n?(Math.abs(t.x-e.minX)<=tamp;&o.push("left"),Math.abs(t.x-e.maxX)<=tamp;&o.push("right")):(Math.abs(t.y-e.minY)<=tamp;&o.push("bottom"),Math.abs(t.y-e.maxY)<=tamp;&o.push("top")),o},h=(o,i,r)=>{const a=t[o],l=a.route??[];if(2!==l.length)return!1;const[h,u]=l;if(!uY(h,e,i,n))return!1;if(!uY(u,e,i,n))return!1;const p=d(h,i),m=d(u,i);for(const t of s){let n=pY(h,e,i,t),s=pY(u,e,i,t);for(const o of p)n=pY(n,e,o,t);for(const n of m)s=pY(s,e,n,t);const l={...a,route:[h,n,s,u]};if(c(o,l,r))return!0}return!1};for(const[o,i]of r)if(t[o])for(const r of i){let i=!0;for(;i;){i=!1;const s=t[o].route??[];if(2===s.length){const i=yY(t[o],e,n);i>0&&h(o,r,i)&&(a+=1);break}if(s.length<3)break;const c=yY(t[o],e,n);if(0===c)break;const d=[];for(let t=1;t<s.length-1;t+=1){const o=s[t];o&&uY(o,e,r,n)&&d.push(t)}if(0===d.length)break;if(l(o,d,r,c)){a+=1,i=!0;continue}let u=!1,p=c,m=0;for(;m<d.length;){let i=m;for(;i+1<d.length&&d[i+1]===d[i]+1;)i+=1;l(o,d.slice(m,i+1),r,p)&&(a+=1,u=!0,p=yY(t[o],e,n)),m=i+1}if(!u){const i=t[o].route??[];let s=c;for(let c=1;c<i.length-1;c+=1){const d=i[c];d&&uY(d,e,r,n)&&l(o,[c],r,s)&&(a+=1,u=!0,s=yY(t[o],e,n))}}u&&(i=!0)}}for(const[o,i]of r){const r=t[o];if(!r)continue;const s=r.route??[];if(s.length<=2)continue;const c=yY(t[o],e,n);if(0!==c)for(const l of i){if(!s.every(t=>uY(t,e,l,n)))continue;const i=s[0]?.z;if(!s.every(t=>t.z===i))continue;const d={...r,route:[s[0],s[s.length-1]]},u=t[o];t[o]=d,h(o,l,c)?a+=1:t[o]=u;break}}})({routes:d,boundary:o,margin:r,geometryCache:c});return vY(d,c)<=h&&s.splice(0,s.length,...d),(({routes:t,boundary:e,clearanceMargin:n})=>{for(let o=0;o<t.length;o+=1){const i=t[o];if((i.route??[]).length<=2)continue;const r=n,s=Math.max(e.width/2-t$,0),a=Math.max(e.height/2-t$,0),c=Math.min(r,s),l=Math.min(r,a),d=i.connectedPadSides??[],h=e.minX+(d.includes("left")?0:c),u=e.maxX-(d.includes("right")?0:c),p=e.minY+(d.includes("bottom")?0:l),m=e.maxY-(d.includes("top")?0:l),g=qj(i),f=g.route??[];let y=!1;for(let t=1;t<f.length-1;t+=1){const e=f[t];if(!e)continue;const n=Math.min(Math.max(e.x,h),u),o=Math.min(Math.max(e.y,p),m);(Math.abs(n-e.x)>t$||Math.abs(o-e.y)>t$)&&(e.x=n,e.y=o,y=!0)}if(!y)continue;if(g.route=$(f),(g.route?.length??0)<2)continue;const _=Jj(t);_[o]=g;const b=_Y(t,_,o,0),x=_Y(t,_,o,n),v=V$({currentRoutes:t,candidateRoutes:_,candidateRouteIndexes:new Set([o]),maximumAllowedClearance:n}).length>0;b||x||v||(t[o]=g)}})({routes:s,boundary:o,clearanceMargin:r}),a.push(((t,e,n)=>({title:`HighDensityRepair02 Final State (margin=${n})`,routes:t,originalRoutes:e}))(Jj(s),Jj(i),r)),{boundary:o,baseRoutes:i,repairedRoutes:s,frames:a,margin:r}},CY=class extends kt{constructor(t={}){super(),this.params=t,this.showBoundryViolationMarkers=t.showBoundryViolationMarkers??!1}params;frames=[];currentFrameIndex=0;showBoundryViolationMarkers;repairedRoutes=[];_setup(){this.buildFrames();const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();this.stats={boundryViolationCount:t,traceViolationCount:e,margin:this.params.margin??.4,frames:this.frames.length,currentFrame:this.currentFrameIndex}}_step(){if(this.frames.length<=1){const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();return this.showBoundryViolationMarkers=!0,this.stats={...this.stats,boundryViolationCount:t,traceViolationCount:e},void(this.solved=!0)}this.currentFrameIndex<this.frames.length-1&&(this.currentFrameIndex+=1);const t=this.getCurrentBoundryViolationCount(),e=this.getCurrentTraceViolationCount();this.stats={boundryViolationCount:t,traceViolationCount:e,margin:this.params.margin??.4,frames:this.frames.length,currentFrame:this.currentFrameIndex,title:this.frames[this.currentFrameIndex]?.title},this.currentFrameIndex>=this.frames.length-1&&(this.showBoundryViolationMarkers=!0,this.solved=!0)}getConstructorParams(){return[this.params]}getOutput(){const t=this.getCurrentTraceViolationCount();return{margin:this.params.margin??.4,repairedRoutes:this.repairedRoutes,frameCount:this.frames.length,traceViolationCount:t}}setShowBoundryViolationMarkers(t){this.showBoundryViolationMarkers=t}buildFrames(){const t=IY(this.params.sample,this.params.margin,this.params.captureProgressFrames??!1);this.frames=t.frames,this.repairedRoutes=t.repairedRoutes}getCurrentFrame(){const t=this.params.sample;return this.frames[this.currentFrameIndex]??{title:"HighDensityRepair02",routes:Jj(t?.nodeHdRoutes??[])}}getBoundryViolationsForFrame(t){const e=z$(this.params.sample?.nodeWithPortPoints);return e?D$(t.routes,e,this.params.margin??.4):[]}getCurrentBoundryViolationCount(){return this.getBoundryViolationsForFrame(this.getCurrentFrame()).length}getRouteNetNames(t){if(!t)return[];const e=[t.connectionName,t.rootConnectionName].filter(t=>Boolean(t));return Array.from(new Set(e))}areRoutesSameNet(t,e){const n=this.getRouteNetNames(t),o=this.getRouteNetNames(e);return 0!==n.length&&0!==o.length&&n.some(t=>o.includes(t))}getCurrentTraceViolationCount(){const t=this.getCurrentFrame().routes,e=new Set(t.map((t,e)=>e));return T$(t,e,e$).filter(e=>!("via"===e.layers[0]&&"via"===e.layers[1]||this.areRoutesSameNet(t[e.routeIndexes[0]],t[e.routeIndexes[1]]))).length}visualize(){const t=this.params.sample,e=t?.nodeWithPortPoints,n=t?.adjacentObstacles??[],o=this.getCurrentFrame(),i=z$(e),r=i&&e?.capacityMeshNodeId?[{center:i.center,width:i.width,height:i.height,stroke:"#1d4ed8",fill:"rgba(29, 78, 216, 0.08)",label:e.capacityMeshNodeId}]:i?[{center:i.center,width:i.width,height:i.height,stroke:"#1d4ed8",fill:"rgba(29, 78, 216, 0.08)",label:"capacity-node"}]:[],s=n.filter(t=>t.center&&t.width&&t.height).map((t,e)=>({center:t.center,width:t.width,height:t.height,stroke:"oval"===t.type?"#a855f7":"#dc2626",fill:"oval"===t.type?"rgba(168, 85, 247, 0.12)":"rgba(220, 38, 38, 0.08)",label:t.type?`obstacle:${t.type}:${e}`:`obstacle:${e}`})),a=this.showBoundryViolationMarkers&&i?this.getBoundryViolationsForFrame(o).map(t=>{const e=t.end.x-t.start.x,n=t.end.y-t.start.y,o=Math.max(Math.hypot(e,n),.2),i=Math.abs(e)>=Math.abs(n);return{center:{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2},width:i?o:.18,height:i?.18:o,stroke:"#b45309",fill:"rgba(250, 204, 21, 0.45)",label:`boundry-violation:${t.routeIndex}:${t.segmentIndex}`}}):[];const c=this.showBoundryViolationMarkers?b$(o.routes,e$):[],l=[...(e?.portPoints??[]).map(t=>({x:t.x,y:t.y,color:"#0f766e",label:t.connectionName??t.portPointId??"port-point"})),...o.routes.flatMap(t=>t.route??[]).map(t=>({x:t.x,y:t.y,color:"bottom"===s$(t)?Kj:"#0ea5e9",label:""})),...o.overlayPoints??[]],d=[...(o.originalRoutes??[]).flatMap(t=>B$(t).map(t=>({...t,strokeColor:"#111111",strokeWidth:Math.max(.6*t.strokeWidth,.05),label:`original:${t.label}`}))),...o.routes.filter(t=>(t.route?.length??0)>=2).flatMap(t=>B$(t)),...o.overlayLines??[]],h=o.routes.flatMap(t=>(t.vias??[]).map(e=>({center:{x:e.x,y:e.y},radius:(e.diameter??t.viaDiameter??.3)/2,stroke:"#7c3aed",fill:"rgba(124, 58, 237, 0.2)",label:t.connectionName?`via:${t.connectionName}`:"via"})));return h.push(...c),{coordinateSystem:"cartesian",title:o.title,rects:[...r,...s,...o.overlayRects??[],...a],points:l,lines:d,circles:h,arrows:o.overlayArrows}}},PY=(t,e,n,o)=>{const i=.001,r=new Set;for(const s of[e.route[0],e.route.at(-1)]){if(!s)continue;n.some(t=>t.__zLayers.includes(s.z)&&fo(t,e,o)&&Math.abs(s.x-t.center.x)<=t.width/2+i&&Math.abs(s.y-t.center.y)<=t.height/2+i)&&(Math.abs(s.x-(t.center.x-t.width/2))<=i&&r.add("left"),Math.abs(s.x-(t.center.x+t.width/2))<=i&&r.add("right"),Math.abs(s.y-(t.center.y-t.height/2))<=i&&r.add("bottom"),Math.abs(s.y-(t.center.y+t.height/2))<=i&&r.add("top"))}return[...r]},MY=(t,e=0)=>({minX:t.center.x-t.width/2-e,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2-e,maxY:t.center.y+t.height/2+e}),NY=(t,e,n=0)=>{const o=MY(e,n);return t.x>=o.minX&&t.x<=o.maxX&&t.y>=o.minY&&t.y<=o.maxY},wY=(t,e,n)=>t.route.length>0&&e.some(e=>(t=>(t.__zLayers?.length??t.layers?.length??0)>1)(e)&&fo(e,t,n)&&t.route.every(t=>((t,e)=>{const n=e.width/2,o=e.height/2;return Math.abs(t.x-e.center.x)<=n&&Math.abs(t.y-e.center.y)<=o})(t,e))),TY=(t,e,n)=>{if(t.regionId){const n=e.findIndex(e=>e.capacityMeshNodeId===t.regionId);if(-1!==n)return n}const o=[...t.route.map(({x:t,y:e})=>({x:t,y:e})),...t.vias.map(({x:t,y:e})=>({x:t,y:e}))];for(let t=0;t<e.length;t++){const i=e[t];if(o.every(t=>NY(t,i,n)))return t}return-1},RY=(t,e)=>({connectionName:t.connectionName??e.connectionName,rootConnectionName:t.rootConnectionName??e.rootConnectionName,...e.startPcbPortId?{startPcbPortId:e.startPcbPortId}:{},...e.endPcbPortId?{endPcbPortId:e.endPcbPortId}:{},regionId:t.capacityMeshNodeId??e.regionId,traceThickness:t.traceThickness??e.traceThickness,viaDiameter:t.viaDiameter??e.viaDiameter,route:t.route?.map(t=>({x:t.x,y:t.y,z:t.z??0}))??e.route,vias:t.vias?.map(t=>({x:t.x,y:t.y}))??e.vias,jumpers:e.jumpers}),EY=(t,e,n,o,i)=>{const r=MY(t,n);return e.search(r).filter(t=>{return e=r,n=(t=>({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}))(t),e.minX<=n.maxX&&e.maxX>=n.minX&&e.minY<=n.maxY&&e.maxY>=n.minY;var e,n}).filter(t=>!i||!o.some(e=>fo(t,e,i))).map(t=>({type:t.type,center:t.center,width:t.width,height:t.height}))},AY=class extends si{repairMargin;sampleEntries;originalHdRoutes;originalNodeWithPortPoints;originalObstacles;obstacleSHI;colorMap;connMap;repairedRoutesByIndex=new Map;activeSampleIndex=0;activeSubSolver=null;latestVisualization={};constructor(t){super(),this.repairMargin=t.repairMargin??.2,this.originalHdRoutes=t.hdRoutes,this.originalNodeWithPortPoints=t.nodeWithPortPoints,this.originalObstacles=t.obstacles,this.obstacleSHI=new Na("flatbush",this.originalObstacles),this.colorMap=t.colorMap??{},this.connMap=t.connMap;const e=new Map;for(let n=0;n<t.hdRoutes.length;n++){if(wY(t.hdRoutes[n],t.obstacles,t.connMap))continue;const o=TY(t.hdRoutes[n],t.nodeWithPortPoints,this.repairMargin);if(-1===o)continue;const i=e.get(o)??[];i.push(n),e.set(o,i)}const n=Kr(t.obstacles,Math.max(2,...t.nodeWithPortPoints.flatMap(t=>t.availableZ?.map(t=>t+1)??[]))),o=Array.from(e.entries()).map(([e,o])=>{const i=t.nodeWithPortPoints[e];return{node:i,routeIndexes:o,sample:{nodeWithPortPoints:{capacityMeshNodeId:i.capacityMeshNodeId,center:i.center,width:i.width,height:i.height,portPoints:i.portPoints.map(t=>({x:t.x,y:t.y,z:t.z,connectionName:t.connectionName,portPointId:t.portPointId,prevPortPointId:t.prevPortPointId,nextPortPointId:t.nextPortPointId}))},nodeHdRoutes:o.map(e=>{return{...(o=t.hdRoutes[e],{capacityMeshNodeId:o.regionId,connectionName:o.connectionName,rootConnectionName:o.rootConnectionName,route:o.route.map(t=>({x:t.x,y:t.y,z:t.z})),traceThickness:o.traceThickness,vias:o.vias.map(t=>({x:t.x,y:t.y,diameter:o.viaDiameter})),viaDiameter:o.viaDiameter}),...t.connMap?{connectedPadSides:PY(i,t.hdRoutes[e],n,t.connMap)}:{}};var o}),adjacentObstacles:EY(i,this.obstacleSHI,this.repairMargin,o.map(e=>t.hdRoutes[e]),t.connMap)}}});this.sampleEntries=void 0!==t.maxSampleEntries&&o.length>t.maxSampleEntries?[]:o,this.MAX_ITERATIONS=Math.max(1e3*this.sampleEntries.length,1e5),this.stats={sampleCount:this.sampleEntries.length,skippedSampleCount:o.length>this.sampleEntries.length?o.length:0,repairedNodeCount:0,repairedRouteCount:0}}getSolverName(){return"Pipeline4HighDensityRepairSolver"}getConstructorParams(){return[{nodeWithPortPoints:this.sampleEntries.map(t=>t.node),hdRoutes:this.originalHdRoutes,obstacles:this.originalObstacles,repairMargin:this.repairMargin,colorMap:this.colorMap,connMap:this.connMap}]}_step(){const t=this.sampleEntries[this.activeSampleIndex];if(t){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.latestVisualization=this.activeSubSolver.visualize(),this.activeSubSolver.failed)return this.failed=!0,this.error=this.activeSubSolver.error??`High density repair failed for node ${t.node.capacityMeshNodeId}`,void(this.activeSubSolver=null);if(!this.activeSubSolver.solved)return;const e=this.activeSubSolver.getOutput().repairedRoutes;for(let n=0;n<t.routeIndexes.length;n++){const o=t.routeIndexes[n],i=this.originalHdRoutes[o],r=e[n];this.repairedRoutesByIndex.set(o,r?RY(r,i):i)}return this.activeSubSolver=null,this.activeSampleIndex+=1,this.stats={sampleCount:this.sampleEntries.length,repairedNodeCount:this.activeSampleIndex,repairedRouteCount:this.repairedRoutesByIndex.size},void(this.activeSampleIndex>=this.sampleEntries.length&&(this.solved=!0))}this.activeSubSolver=new CY({sample:t.sample,margin:this.repairMargin}),this.latestVisualization=this.activeSubSolver.visualize()}else this.solved=!0}getOutput(){return this.originalHdRoutes.map((t,e)=>this.repairedRoutesByIndex.get(e)??t)}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();if(!this.solved)return this.latestVisualization;const t=[],e=[];for(const n of this.getOutput()){const o=this.colorMap[n.connectionName]??"#0ea5e9";for(let e=0;e<n.route.length-1;e++){const i=n.route[e],r=n.route[e+1];i.z===r.z&&t.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:0===i.z?o:To(o,.5),strokeWidth:n.traceThickness,layer:`z${i.z}`,strokeDash:0!==i.z?[.1,.3]:void 0})}for(const t of n.vias)e.push({center:{x:t.x,y:t.y},radius:n.viaDiameter/2,stroke:o,fill:"rgba(14,165,233,0.12)"})}return{title:"Pipeline4 High Density Repair",lines:t,circles:e}}},OY=1e-6,kY=({startGap:t,endGap:e,segmentGap:n,requiredGap:o})=>{const i=t<o&&e>=o-OY&&n>=t-OY,r=e<o&&t>=o-OY&&n>=e-OY,s=t<o&&e<o&&n>=Math.min(t,e)-OY;return i||r||s},LY=class{minClearance;rootsByConnection=new Map;sameNetCache=new Map;segments=[];vias=[];segmentIndexesByLayer;viaIndex;constructor({hdRoutes:t,minClearance:e=.1}){this.minClearance=e;for(const e of t)this.addRoute(e);this.buildSpatialIndexes()}addRoute(t){const e=this.rootsByConnection.get(t.connectionName)??new Set;e.add(t.rootConnectionName??t.connectionName),this.rootsByConnection.set(t.connectionName,e),this.sameNetCache.clear();for(let e=0;e<t.route.length-1;e+=1){const n=t.route[e],o=t.route[e+1];if(n.z!==o.z)continue;if(n.insideJumperPad&&o.insideJumperPad)continue;const i={connectionName:t.connectionName,start:n,end:o,traceThickness:t.traceThickness};this.segments.push(i),this.insertSegmentIntoSpatialIndex(i)}for(const e of t.vias){const n={connectionName:t.connectionName,x:e.x,y:e.y,diameter:t.viaDiameter};this.vias.push(n),this.insertViaIntoSpatialIndex(n)}}insertSegmentIntoSpatialIndex(t){if(!this.segmentIndexesByLayer)return;let e=this.segmentIndexesByLayer.get(t.start.z);e||(e=new Pa,this.segmentIndexesByLayer.set(t.start.z,e));const n=t.traceThickness/2;e.insert(t,Math.min(t.start.x,t.end.x)-n,Math.min(t.start.y,t.end.y)-n,Math.max(t.start.x,t.end.x)+n,Math.max(t.start.y,t.end.y)+n)}insertViaIntoSpatialIndex(t){if(!this.viaIndex)return;const e=t.diameter/2;this.viaIndex.insert(t,t.x-e,t.y-e,t.x+e,t.y+e)}buildSpatialIndexes(){this.segmentIndexesByLayer=new Map;const t=new Map;for(const e of this.segments){const n=t.get(e.start.z);n?n.push(e):t.set(e.start.z,[e])}for(const[e,n]of t){const t=new Pa;t.bulkLoad(n.map(t=>{const e=t.traceThickness/2;return{item:t,minX:Math.min(t.start.x,t.end.x)-e,minY:Math.min(t.start.y,t.end.y)-e,maxX:Math.max(t.start.x,t.end.x)+e,maxY:Math.max(t.start.y,t.end.y)+e}})),this.segmentIndexesByLayer.set(e,t)}this.viaIndex=new Pa,this.viaIndex.bulkLoad(this.vias.map(t=>{const e=t.diameter/2;return{item:t,minX:t.x-e,minY:t.y-e,maxX:t.x+e,maxY:t.y+e}}))}areSameNet(t,e){if(t===e)return!0;const n=this.sameNetCache.get(t)?.get(e);if(void 0!==n)return n;const o=this.rootsByConnection.get(t),i=this.rootsByConnection.get(e);let r=!1;if(o&&i)for(const t of o)if(i.has(t)){r=!0;break}let s=this.sameNetCache.get(t);return s||(s=new Map,this.sameNetCache.set(t,s)),s.set(e,r),r}isSegmentClear({connectionName:t,start:e,end:n,traceThickness:o}){const i=o/2,r=this.minClearance+i,s=Math.min(e.x,n.x)-r,a=Math.min(e.y,n.y)-r,c=Math.max(e.x,n.x)+r,l=Math.max(e.y,n.y)+r,d=this.segmentIndexesByLayer?.get(e.z)?.search(s,a,c,l)??[];for(const o of d){if(this.areSameNet(t,o.connectionName))continue;const r=this.minClearance+i+o.traceThickness/2,s=Ra(e,n,o.start,o.end);if(s<r&&!kY({startGap:be(e,o.start,o.end),endGap:be(n,o.start,o.end),segmentGap:s,requiredGap:r}))return!1}const h=this.viaIndex?.search(s,a,c,l)??[];for(const o of h){if(this.areSameNet(t,o.connectionName))continue;const r=this.minClearance+i+o.diameter/2,s=be(o,e,n);if(s<r&&!kY({startGap:Math.hypot(e.x-o.x,e.y-o.y),endGap:Math.hypot(n.x-o.x,n.y-o.y),segmentGap:s,requiredGap:r}))return!1}return!0}},DY=1e-9,zY=1.25,FY=(t,e)=>t<e?-1:t>e?1:0,BY=(t,e)=>FY(t.z,e.z)||FY(t.x,e.x)||FY(t.y,e.y),jY=t=>`${t.z.toFixed(6)}:${t.x.toFixed(6)}:${t.y.toFixed(6)}`,$Y=t=>{const e=t.route.map(jY).join("|"),n=[...t.route].reverse().map(jY).join("|");return e<=n?e:n},YY=(t,e)=>{const n=t.connectionName.localeCompare(e.connectionName);if(0!==n)return n;const o=(t.rootConnectionName??"").localeCompare(e.rootConnectionName??"");if(0!==o)return o;const i=$Y(t).localeCompare($Y(e));return 0!==i?i:FY(t.traceThickness,e.traceThickness)||FY(t.viaDiameter,e.viaDiameter)||FY(t.route.length,e.route.length)||FY(t.vias.length,e.vias.length)||FY(t.jumpers?.length??0,e.jumpers?.length??0)},XY=1e5,VY=.001,WY=1.000000001,HY=class extends si{getSolverName(){return"SingleHighDensityRouteStitchSolver3"}mergedHdRoute;remainingHdRoutes;start;end;colorMap;allowedLayerTransitionPointKeys;isStitchSegmentClear;stitchClearanceMode;isPlanarStitchClear(t,e){return this.isStitchSegmentClear({connectionName:this.mergedHdRoute.connectionName,start:t,end:e,traceThickness:this.mergedHdRoute.traceThickness})}constructor(t){super();const e=[...t.hdRoutes].sort(YY);if(this.remainingHdRoutes=e,this.colorMap=t.colorMap??{},this.allowedLayerTransitionPointKeys=t.allowedLayerTransitionPointKeys,this.isStitchSegmentClear=t.isStitchSegmentClear,this.stitchClearanceMode=t.stitchClearanceMode,0===e.length){this.start=t.start,this.end=t.end;const n=t.defaultTraceThickness??.15,o=[{x:t.start.x,y:t.start.y,z:t.start.z}],i=[];if(t.start.z!==t.end.z){if(t.allowedLayerTransitionPointKeys&&!t.allowedLayerTransitionPointKeys.has(af(t.start)))return this.failed=!0,void(this.error=`Layer transition at ${af(t.start)} is not allowed`);o.push({x:t.start.x,y:t.start.y,z:t.end.z}),i.push({x:t.start.x,y:t.start.y})}const r=o[o.length-1],s={x:t.end.x,y:t.end.y,z:t.end.z},a={connectionName:t.connectionName,start:r,end:s,traceThickness:n};return xe(r,s)>VY&&!this.isStitchSegmentClear(a)&&"require_clear"===this.stitchClearanceMode?(this.failed=!0,void(this.error=`Terminal stitch for "${t.connectionName}" violates copper clearance`)):(o.push(s),this.mergedHdRoute={connectionName:t.connectionName,...t.preserveTerminalPcbPortIds&&t.start.pcb_port_id?{startPcbPortId:t.start.pcb_port_id}:{},...t.preserveTerminalPcbPortIds&&t.end.pcb_port_id?{endPcbPortId:t.end.pcb_port_id}:{},rootConnectionName:e[0]?.rootConnectionName,route:o,vias:i,jumpers:[],viaDiameter:t.defaultViaDiameter??.3,traceThickness:n},void(this.solved=!0))}const n=new Set((t.preserveTerminalPcbPortIds?[t.start.pcb_port_id,t.end.pcb_port_id]:[]).filter(t=>void 0!==t));if(t.preserveTerminalPcbPortIds&&t.start.pcb_port_id&&t.start.pcb_port_id===t.end.pcb_port_id)throw new Error(`SingleHighDensityRouteStitchSolver3 received duplicate PCB terminal "${t.start.pcb_port_id}" for "${t.connectionName}"`);const o=e.flatMap(t=>[t.startPcbPortId,t.endPcbPortId]).filter(t=>void 0!==t);if(n.size>0)for(const e of o)if(!n.has(e))throw new Error(`SingleHighDensityRouteStitchSolver3 found unknown PCB terminal "${e}" on "${t.connectionName}"`);let i=1/0,r=e[0],s="start-to-end";for(const n of e){const e=n.route[0],o=n.route[n.route.length-1],a=xe(t.start,e),c=xe(t.start,o),l=xe(t.end,e),d=xe(t.end,o),h=Math.min(a,c,l,d);(h<i-DY||Math.abs(h-i)<=DY&&YY(n,r)<0)&&(i=h,r=n,s=Math.min(l,d)<Math.min(a,c)-DY||Math.abs(Math.min(l,d)-Math.min(a,c))<=DY&&BY(t.end,t.start)<0?"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 a=r.route[0],c=r.route[r.route.length-1],l=xe(this.start,a),d=xe(this.start,c),h=l<d-DY||Math.abs(l-d)<=DY&&BY(a,c)<=0?a:c,u=h===a?r.startPcbPortId:r.endPcbPortId;if(u&&this.start.pcb_port_id&&u!==this.start.pcb_port_id)throw new Error(`SingleHighDensityRouteStitchSolver3 terminal identity disagrees with route orientation for "${t.connectionName}"`);this.mergedHdRoute={connectionName:t.connectionName,...t.preserveTerminalPcbPortIds&&this.start.pcb_port_id?{startPcbPortId:this.start.pcb_port_id}:{},...t.preserveTerminalPcbPortIds&&this.end.pcb_port_id?{endPcbPortId:this.end.pcb_port_id}:{},rootConnectionName:r.rootConnectionName,route:[{x:this.start.x,y:this.start.y,z:h.z}],vias:[],jumpers:[],viaDiameter:r.viaDiameter,traceThickness:r.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&&xe(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],e={...this.end,z:t.z},n=xe(t,e);if(n>VY&&n<=zY){if(!this.isPlanarStitchClear(t,e)&&"require_clear"===this.stitchClearanceMode)return this.failed=!0,void(this.error=`Terminal stitch for "${this.mergedHdRoute.connectionName}" violates copper clearance`);this.mergedHdRoute.route.push({x:this.end.x,y:this.end.y,z:t.z})}return void(this.solved=!0)}const t=this.mergedHdRoute.route[this.mergedHdRoute.route.length-1];let e=-1,n="first",o=1/0,i=!1;for(let r=0;r<this.remainingHdRoutes.length;r++){const s=this.remainingHdRoutes[r],a=s.route[0],c=s.route[s.route.length-1],l=xe(t,a),d=xe(t,c);let h=1/0;if(t.z===a.z){if(l<VY)h=l;else if(l<=1){const e=this.isPlanarStitchClear(t,a);if(e||"prefer_clear"===this.stitchClearanceMode){h=XY+(e?0:WY)+l}else i=!0}}else l<VY&&(!this.allowedLayerTransitionPointKeys||this.allowedLayerTransitionPointKeys.has(af(a)))&&(h=1e3+l);h<o&&(o=h,e=r,n="first");let u=1/0;if(t.z===c.z){if(d<VY)u=d;else if(d<=1){const e=this.isPlanarStitchClear(t,c);if(e||"prefer_clear"===this.stitchClearanceMode){u=XY+(e?0:WY)+d}else i=!0}}else d<VY&&(!this.allowedLayerTransitionPointKeys||this.allowedLayerTransitionPointKeys.has(af(c)))&&(u=1e3+d);u<o&&(o=u,e=r,n="last")}if(-1===e)return i?(this.failed=!0,void(this.error=`Route stitch for "${this.mergedHdRoute.connectionName}" violates copper clearance`)):void(this.remainingHdRoutes=[]);const r=this.remainingHdRoutes[e];let s;this.remainingHdRoutes.splice(e,1),s="first"===n?r.route:(t=>{const e=[...t].reverse().map(t=>{const{toNextSegmentType:e,...n}=t;return n});for(let n=0;n<t.length-1;n++){const o=t[n]?.toNextSegmentType;if(!o)continue;const i=t.length-n-2;e[i]={...e[i],toNextSegmentType:o}}return e})(r.route),s.length>0&&xe(t,s[0])<VY&&t.z===s[0].z?(s[0].toNextSegmentType&&(t.toNextSegmentType=s[0].toNextSegmentType),this.mergedHdRoute.route.push(...s.slice(1))):this.mergedHdRoute.route.push(...s),this.mergedHdRoute.vias.push(...r.vias),r.jumpers&&this.mergedHdRoute.jumpers.push(...r.jumpers)}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Single High Density Route Stitch Solver 3"};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=_a(this.mergedHdRoute.jumpers,{color:"green",label:this.mergedHdRoute.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const e of this.remainingHdRoutes){t.lines?.push({points:e.route.map(t=>({x:t.x,y:t.y})),strokeColor:"orange"});for(const n of e.route)t.points?.push({x:n.x,y:n.y,color:"orange"});for(const n of e.vias)t.circles?.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"orange"});if(e.jumpers&&e.jumpers.length>0){const n=_a(e.jumpers,{color:"orange",label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}return t}},GY=class{constructor(t=!1){this.preferSameLayerTerminalEndpoints=t}preferSameLayerTerminalEndpoints;endpointClusters=new Map;getEndpointKey(t,e){const n=this.endpointClusters.get(t)??[];let o,i=1/0;for(const t of n){if(t.point.z!==e.z)continue;const n=xe(t.point,e);n<=.1&&(n<i-DY||Math.abs(n-i)<=DY&&(!o||BY(t.point,o.point)<0))&&(o=t,i=n)}if(o)return o.key;const r=`${t}:endpoint_${n.length}`;return n.push({key:r,point:{x:e.x,y:e.y,z:e.z}}),this.endpointClusters.set(t,n),r}getClusters(t){return this.endpointClusters.get(t)??[]}getClosestEndpointKey(t,e,n){const o=e.flatMap(t=>[t.route[0],t.route[t.route.length-1]]),i=o.filter(t=>t.z===n.z),r=this.preferSameLayerTerminalEndpoints&&i.length>0?i:o;let s=null,a=null,c=1/0;for(const e of r){const o=xe(n,e),i=this.getEndpointKey(t,e);(o<c-DY||Math.abs(o-c)<=DY&&(null===s||i.localeCompare(s)<0||i===s&&null!==a&&BY(e,a)<0))&&(c=o,s=i,a=e)}return s}},UY=(t,e,n)=>{const o=t.get(e)??[];o.some(t=>t.nextHash===n.nextHash&&t.routeIndex===n.routeIndex)||(o.push(n),t.set(e,o))},ZY=t=>{const e=[...t.possibleEndpoints].sort(BY),n=e.reduce((e,n)=>{const o=xe(n,t.globalStart),i=xe(e,t.globalStart);return o<i-DY||Math.abs(o-i)<=DY&&BY(n,e)<0?n:e}),o=e.filter(t=>t!==n),i=(o.length>0?o:t.possibleEndpoints).reduce((e,n)=>{const o=xe(n,t.globalEnd),i=xe(e,t.globalEnd);return o<i-DY||Math.abs(o-i)<=DY&&BY(n,e)<0?n:e});return{start:n,end:i}},qY=t=>{const e=[...t.terminals].sort(BY);let n=e[0],o=xe(t.islandEndpoint,n);for(const i of e.slice(1)){const e=xe(t.islandEndpoint,i);(e<o-DY||Math.abs(e-o)<=DY&&BY(i,n)<0)&&(n=i,o=e)}return o<=zY?n:t.islandEndpoint},JY=t=>{if(t.hdRoutes.length<=2)return t.hdRoutes;const e=[...t.hdRoutes].sort(YY),n=t.endpointIndex.getClosestEndpointKey(t.connectionName,e,t.start),o=t.endpointIndex.getClosestEndpointKey(t.connectionName,e,t.end);if(!n||!o||n===o)return e;const i=new Map;for(let n=0;n<e.length;n++){const o=e[n],r=t.endpointIndex.getEndpointKey(t.connectionName,o.route[0]),s=t.endpointIndex.getEndpointKey(t.connectionName,o.route[o.route.length-1]);UY(i,r,{nextHash:s,routeIndex:n}),UY(i,s,{nextHash:r,routeIndex:n})}const r=[...t.endpointIndex.getClusters(t.connectionName)].sort((t,e)=>BY(t.point,e.point));for(let t=0;t<r.length;t++){const e=r[t];for(let n=t+1;n<r.length;n++){const t=r[n];e.point.z===t.point.z&&(xe(e.point,t.point)>1||(UY(i,e.key,{nextHash:t.key,routeIndex:null}),UY(i,t.key,{nextHash:e.key,routeIndex:null})))}}for(const[t,n]of i.entries())i.set(t,[...n].sort((t,n)=>{if(null===t.routeIndex&&null!==n.routeIndex)return 1;if(null!==t.routeIndex&&null===n.routeIndex)return-1;if(null!==t.routeIndex&&null!==n.routeIndex){const o=YY(e[t.routeIndex],e[n.routeIndex]);if(0!==o)return o}return t.nextHash.localeCompare(n.nextHash)}));const s=[n],a=new Set([n]),c=new Map;for(;s.length>0;){const t=s.shift();if(t===o)break;for(const e of i.get(t)??[])a.has(e.nextHash)||(a.add(e.nextHash),c.set(e.nextHash,{prevHash:t,routeIndex:e.routeIndex}),s.push(e.nextHash))}if(!a.has(o))return e;const l=[];let d=o;for(;d!==n;){const t=c.get(d);if(!t)return e;null!==t.routeIndex&&l.push(t.routeIndex),d=t.prevHash}if(0===l.length)return t.hdRoutes;const h=l.reverse().map(t=>e[t]);return h.length>0&&!t.canStitchBetweenTerminals({connectionName:t.connectionName,hdRoutes:h,start:t.start,end:t.end})?e:h},KY=class extends si{getSolverName(){return"MultipleHighDensityRouteStitchSolver3"}unsolvedRoutes;activeSolver=null;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;allowedLayerTransitionPointKeys;preserveTerminalPcbPortIds;endpointIndex;clearanceValidator;canStitchBetweenTerminals(t){const e=new HY({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter,allowedLayerTransitionPointKeys:this.allowedLayerTransitionPointKeys,preserveTerminalPcbPortIds:this.preserveTerminalPcbPortIds,isStitchSegmentClear:t=>this.clearanceValidator.isSegmentClear(t),stitchClearanceMode:"require_clear"});for(;!e.solved&&!e.failed&&e.iterations<e.MAX_ITERATIONS;)e.step();if(e.failed)return!1;const n=e.mergedHdRoute.route[0],o=e.mergedHdRoute.route[e.mergedHdRoute.route.length-1],i=xe(n,t.start)+xe(o,t.end),r=xe(n,t.end)+xe(o,t.start);return Math.min(i,r)<=zY}getSharedRootPathRoutes(t){const e=t.rootConnectionName;if(!e)return null;const n=new Set(t.hdRoutes),o=t.allHdRoutes.filter(t=>(t.rootConnectionName??t.connectionName)===e);if(o.every(t=>n.has(t)))return null;const i=JY({connectionName:t.connectionName,hdRoutes:o,start:t.start,end:t.end,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=>this.canStitchBetweenTerminals(t)});return!i.some(t=>!n.has(t))||i.length>=o.length?null:i}constructor(t){super(),this.endpointIndex=new GY(t.preferSameLayerTerminalEndpoints),this.colorMap=t.colorMap??{},this.allowedLayerTransitionPointKeys=t.allowedLayerTransitionPointKeys,this.preserveTerminalPcbPortIds=t.preserveTerminalPcbPortIds??!1;const e=[...t.hdRoutes].sort(YY);this.clearanceValidator=new LY({hdRoutes:e});const n=e[0];this.defaultTraceThickness=n?.traceThickness??.15,this.defaultViaDiameter=n?.viaDiameter??t.defaultViaDiameter??.3;const o=new fa({}),i=[],r=new Map;for(let t=0;t<e.length;t++){const n=e[t],o=n.route[0],r=n.route[n.route.length-1];i.push([`route_island_${t}`,this.endpointIndex.getEndpointKey(n.connectionName,o),this.endpointIndex.getEndpointKey(n.connectionName,r)])}o.addConnections(i);for(const t of i)for(const e of t.slice(1))r.set(e,(r.get(e)??0)+1);this.unsolvedRoutes=[];const s=Array.from(new Set(Object.values(o.idToNetMap)));for(const n of s){const i=o.getIdsConnectedToNet(n),s=e.filter((t,e)=>i.includes(`route_island_${e}`));if(0===s.length)continue;const a=t.connections.find(t=>t.name===s[0].connectionName),c=s.flatMap(t=>[t.route[0],t.route[t.route.length-1]]),l=new Map,d=[];for(const t of c){const e=this.endpointIndex.getEndpointKey(s[0].connectionName,t);l.has(e)||l.set(e,t),1===r.get(e)&&d.push(t)}const h=d.length>0?d:[...l.values()];if(0===h.length)continue;let u,p;if(h.length>=2){const e={...a.pointsToConnect[0],z:ko(bo(a.pointsToConnect[0]),t.layerCount)},n={...a.pointsToConnect[1],z:ko(bo(a.pointsToConnect[1]),t.layerCount)};({start:u,end:p}=ZY({possibleEndpoints:h,globalStart:e,globalEnd:n})),xe(u,a.pointsToConnect[1])<xe(p,a.pointsToConnect[0])&&([u,p]=[p,u]),u=qY({islandEndpoint:u,terminals:[e,n]}),p=qY({islandEndpoint:p,terminals:[e,n]})}else u={...a.pointsToConnect[0],z:ko(bo(a.pointsToConnect[0]),t.layerCount)},p={...a.pointsToConnect[1],z:ko(bo(a.pointsToConnect[1]),t.layerCount)};const m=JY({connectionName:s[0].connectionName,hdRoutes:s,start:u,end:p,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=>this.canStitchBetweenTerminals(t)});this.unsolvedRoutes.push({connectionName:s[0].connectionName,hdRoutes:m,start:u,end:p})}const a=new Map;for(const t of this.unsolvedRoutes){const e=a.get(t.connectionName);e?e.push(t):a.set(t.connectionName,[t])}this.unsolvedRoutes=Array.from(a.entries()).flatMap(([n,o])=>{const i=t.connections.find(t=>t.name===n),r=o.some(t=>t.hdRoutes.some(t=>t.route.length<2)),s=o.length>1&&(t=>{for(let e=0;e<t.length;e++)for(let n=e+1;n<t.length;n++){const o=[t[e].start,t[e].end],i=[t[n].start,t[n].end];for(const t of o)for(const e of i)if(t.z===e.z&&xe(t,e)<=1)return!0}return!1})(o);if(!i)return o;const a={...i.pointsToConnect[0],z:ko(bo(i.pointsToConnect[0]),t.layerCount)},c={...i.pointsToConnect[1],z:ko(bo(i.pointsToConnect[1]),t.layerCount)},l=o.flatMap(t=>t.hdRoutes),d=o.length>1?this.getSharedRootPathRoutes({connectionName:n,rootConnectionName:i.__rootConnectionNames?.[0]??l[0]?.rootConnectionName,hdRoutes:l,allHdRoutes:e,start:a,end:c}):null;return r||s||d?[{connectionName:n,hdRoutes:d??JY({connectionName:n,hdRoutes:l,start:a,end:c,endpointIndex:this.endpointIndex,canStitchBetweenTerminals:t=>this.canStitchBetweenTerminals(t)}),start:a,end:c}]:o}),this.MAX_ITERATIONS=1e5}_step(){if(this.activeSolver)return this.activeSolver.step(),void(this.activeSolver.solved?(this.activeSolver instanceof HY&&(this.clearanceValidator.addRoute(this.activeSolver.mergedHdRoute),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 HY({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter,allowedLayerTransitionPointKeys:this.allowedLayerTransitionPointKeys,preserveTerminalPcbPortIds:this.preserveTerminalPcbPortIds,isStitchSegmentClear:t=>this.clearanceValidator.isSegmentClear(t),stitchClearanceMode:"prefer_clear"}):this.solved=!0}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Multiple High Density Route Stitch Solver 3"};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 o=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e<n.route.length-1;e++){const i=n.route[e],r=n.route[e+1],s=0!==i.z?To(o,.5):o;t.lines?.push({points:[{x:i.x,y:i.y},{x:r.x,y:r.y}],strokeColor:s,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?To(o,.5):o;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:o});if(n.jumpers&&n.jumpers.length>0){const e=_a(n.jumpers,{color:o,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}return t}},QY=t=>(t%360+360)%360,tX=(t,e)=>{const{ccwRotationDegrees:n,...o}=t,i=(t=>{const e=QY(t),n=[0,90,180,270];for(const t of n)if(Math.min(Math.abs(e-t),360-Math.abs(e-t))<=.01)return t;return null})(e);return 90===i||270===i?{...o,width:t.height,height:t.width}:o},eX=t=>"layers"in t?t.layers:[t.layer],nX=(t,e)=>!(eX(t).length>0&&!eX(t).some(t=>e.layers.includes(t)))&&Me(t,Ve(e)),oX=(t,e)=>{const{minX:n,maxX:o,minY:i,maxY:r}=Ve(e);return{x:Math.max(n,Math.min(o,t.x)),y:Math.max(i,Math.min(r,t.y))}},iX=(t,e)=>t.obstacleId??`${t.componentId??"obstacle"}_${e}`;function rX(t,e=2){const{center:n,width:o,height:i,rotation:r}=t,s=[],a=Math.max(1,Math.ceil(e)),c=r*Math.PI/180,l=Math.cos(c),d=Math.sin(c);if(o>=i){const t=o/a;for(let e=0;e<a;e++){const o=(e-a/2+.5)*t,r=o*l,c=o*d,h=Math.abs(t*l)+Math.abs(i*d),u=Math.abs(t*d)+Math.abs(i*l);s.push({center:{x:n.x+r,y:n.y+c},width:h,height:u})}}else{const t=i/a;for(let e=0;e<a;e++){const i=(e-a/2+.5)*t,r=-i*d,c=i*l,h=Math.abs(o*l)+Math.abs(t*d),u=Math.abs(o*d)+Math.abs(t*l);s.push({center:{x:n.x+r,y:n.y+c},width:h,height:u})}}return s}var sX=t=>{if("oval"===t.type)return sX({...t,type:"rect"});const e=t.ccwRotationDegrees;if("number"!=typeof e||!Number.isFinite(e))return[t];if((t=>{const e=QY(t);return[0,90,180,270].some(t=>Math.min(Math.abs(e-t),360-Math.abs(e-t))<=.01)})(e))return[tX(t,e)];const{ccwRotationDegrees:n,...o}=t,i={center:t.center,width:t.width,height:t.height,rotation:e},r=(t=>{const e=Math.max(t.width,t.height),n=Math.min(t.width,t.height);return t.obstacleId?.startsWith("trace_obstacle_")?Math.max(2,Math.ceil(e/.75)):n<=0?2:e/n<2||n>=.9?null:Math.max(2,Math.ceil(e/.75))})(t),s=t.connectedTo.length>0&&!t.obstacleId?.startsWith("trace_obstacle_")?(t=>{const e=t.rotation*Math.PI/180,n=Math.cos(e),o=Math.sin(e),i=[-1,1].flatMap(e=>[-1,1].map(i=>{const r=e*(t.width/2),s=i*(t.height/2);return{x:t.center.x+r*n-s*o,y:t.center.y+r*o+s*n}})),r=[i[0],i[2],i[3],i[1]],s=Math.min(...r.map(t=>t.x)),a=Math.max(...r.map(t=>t.x)),c=Math.min(...r.map(t=>t.y)),l=Math.max(...r.map(t=>t.y)),d=a-s<=l-c?"x":"y",h="x"===d?s:c,u="x"===d?a:l,p=Math.max(1,Math.ceil((u-h)/.4)),m=(u-h)/p,g=(t,e,n)=>{const o=[],i=t=>t[d];for(let r=0;r<t.length;r++){const s=t[r],a=t[(r+1)%t.length],c=i(s),l=i(a),d=n?c>=e:c<=e,h=n?l>=e:l<=e;if(d&&o.push(s),d===h)continue;const u=(e-c)/(l-c);o.push({x:s.x+(a.x-s.x)*u,y:s.y+(a.y-s.y)*u})}return o},f=[];for(let t=0;t<p;t++){const e=h+t*m,n=t===p-1?u:e+m,o=g(g(r,e,!0),n,!1);if(0===o.length)continue;const i=Math.min(...o.map(t=>t.x)),s=Math.max(...o.map(t=>t.x)),a=Math.min(...o.map(t=>t.y)),c=Math.max(...o.map(t=>t.y));f.push({center:{x:(i+s)/2,y:(a+c)/2},width:s-i,height:c-a})}return f})(i):null===r?((t,e)=>{const{center:n,width:o,height:i,rotation:r}=t,s=Math.max(1,Math.ceil(o/e)),a=Math.max(1,Math.ceil(i/e)),c=o/s,l=i/a,d=r*Math.PI/180,h=Math.cos(d),u=Math.sin(d),p=[];for(let t=0;t<s;t++){const e=(t-s/2+.5)*c;for(let t=0;t<a;t++){const o=(t-a/2+.5)*l;p.push({center:{x:n.x+e*h-o*u,y:n.y+e*u+o*h},width:Math.abs(c*h)+Math.abs(l*u),height:Math.abs(c*u)+Math.abs(l*h)})}}return p})(i,(t=>t.obstacleId?.startsWith("trace_obstacle_")?.75:.4)(t)):t.obstacleId?.startsWith("trace_obstacle_")?rX(i,r):((t,e)=>{const{center:n,width:o,height:i,rotation:r}=t,s=Math.max(o,i),a=Math.min(o,i),c=Math.max(1,Math.ceil(e)),l=s/c,d=r*Math.PI/180,h=Math.cos(d),u=Math.sin(d),p=Math.max(l,.75*a),m=[];for(let t=0;t<c;t++){const e=(t-c/2+.5)*l,r=o>=i?e*h:-e*u,s=o>=i?e*u:e*h;m.push({center:{x:n.x+r,y:n.y+s},width:p,height:p})}return m})(i,r),a=t.connectedTo.length>0?s.reduce((e,n,o)=>{const i=s[e],r=(i.center.x-t.center.x)**2+(i.center.y-t.center.y)**2;return(n.center.x-t.center.x)**2+(n.center.y-t.center.y)**2<r?o:e},0):-1;return s.map((t,e)=>({...o,obstacleId:e===a?o.obstacleId:o.obstacleId?`${o.obstacleId}_approx_${e}`:void 0,connectedTo:o.connectedTo,center:t.center,width:t.width,height:t.height}))},aX=t=>{const e=new Map,n=new Map,o=new Map;for(const[i,r]of t.obstacles.entries()){const t=sX(r),s=iX(r,i);n.set(s,t),o.set(s,r);for(const n of t){const t=[n.center.x.toFixed(6),n.center.y.toFixed(6),n.width.toFixed(6),n.height.toFixed(6),n.layers.join(",")].join(":"),o=e.get(t);o?o.connectedTo=[...new Set([...o.connectedTo,...n.connectedTo])]:e.set(t,n)}}const i=t.connections.map(t=>({...t,pointsToConnect:t.pointsToConnect.map(t=>{const e=(t=>[t.pointId,t.pcb_port_id].filter(t=>Boolean(t)))(t);if(0===e.length)return t;for(const[i,r]of o){if(!e.some(t=>r.connectedTo.includes(t)))continue;if(!nX(t,r))continue;const o=n.get(i)??[];if(0===o.length)continue;if(o.some(e=>nX(t,e)))return t;let s=o[0],a=Number.POSITIVE_INFINITY;for(const e of o){const n=xe(oX(t,e),t);n<a&&(a=n,s=e)}return{...t,...oX(t,s)}}return t})}));return{...t,connections:i,obstacles:[...e.values()]}},cX=.001,lX=t=>"wire"===t.route_type,dX=t=>"via"===t.route_type,hX=t=>"through_obstacle"===t.route_type,uX=(t,e,n)=>{const o=ko(t,n),i=ko(e,n),r=Math.min(o,i),s=Math.max(o,i);return Array.from({length:s-r+1},(t,e)=>vo(r+e,n))},pX=({obstacleId:t,start:e,end:n,width:o,layer:i,connectedTo:r})=>{const s=n.x-e.x,a=n.y-e.y,c=Math.hypot(s,a);return c<=cX?null:{obstacleId:t,type:"rect",layers:[i],center:{x:(e.x+n.x)/2,y:(e.y+n.y)/2},width:c,height:Math.max(o,cX),ccwRotationDegrees:180*Math.atan2(a,s)/Math.PI,connectedTo:r}};function mX(t){if(!t)return t;const e=(t=>{if(!t)return[];const e=[],n=Yo(t);for(const[o,i]of(t.traces??[]).entries()){const r=i.connectsTo??[];for(let s=0;s<i.route.length;s++){const a=i.route[s];if(dX(a)){const c=a.via_diameter??n.padDiameter;e.push({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${s}_via`,type:"rect",layers:uX(a.from_layer,a.to_layer,t.layerCount),center:{x:a.x,y:a.y},width:Math.max(c,cX),height:Math.max(c,cX),connectedTo:r});continue}if(hX(a)){const n=pX({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${s}_through`,start:a.start,end:a.end,width:a.width,layer:a.from_layer,connectedTo:r});n&&(n.layers=uX(a.from_layer,a.to_layer,t.layerCount),e.push(n))}}for(let t=0;t<i.route.length-1;t++){const n=i.route[t],s=i.route[t+1];if(!lX(n)||!lX(s)||n.layer!==s.layer)continue;const a=pX({obstacleId:`trace_obstacle_${i.pcb_trace_id}_${o}_${t}_wire`,start:n,end:s,width:n.width,layer:n.layer,connectedTo:r});a&&e.push(a)}}return e})(t);return 0===e.length?t:{...t,obstacles:[...t.obstacles??[],...e]}}function gX(t,e){const n=function(t,e){const n=Lo(t.__zLayers??t.zLayers??[],e);if(n.length>0)return n;const o=Do(t.layers,e);if(o.length>0)return o;throw new Error(`Obstacle "${t.obstacleId??"unknown"}" has no layers on this ${e}-layer board`)}(t,e);return{...t,layers:n.map(t=>vo(t,e)),zLayers:n,__zLayers:n}}function fX(t){return{...t,obstacles:t.obstacles.map(e=>gX(e,t.layerCount)),jumpers:t.jumpers?.map(e=>({...e,pads:e.pads.map(e=>gX(e,t.layerCount))}))}}var yX=t=>{const e=t.obstacles.filter(e=>!((t,e)=>!(t=>(t.connectedTo?.length??0)>0||(t.offBoardConnectsTo?.length??0)>0||!0===t.netIsAssignable)(t)&&(e.outline&&e.outline.length>=3?!Te(t,e.outline):!Xe({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.bounds)))(e,t)),n=e.length!==t.obstacles.length,o=n&&t.outline&&t.outline.length>=3?(t=>{if(t.width&&t.height&&t.center){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,width:t.width,height:t.height,center:{x:t.center.x,y:t.center.y}}}if(!t.outline||0===t.outline.length)throw new Error("Unable to compute board bounds. pcb_board must include width/height/center or a non-empty outline.");let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t.outline)e=Math.min(e,r.x),n=Math.min(n,r.y),o=Math.max(o,r.x),i=Math.max(i,r.y);const r=o-e,s=i-n;return{minX:e,minY:n,maxX:o,maxY:i,width:r,height:s,center:{x:e+r/2,y:n+s/2}}})({type:"pcb_board",pcb_board_id:"__autorouting_board_outline__",center:{x:0,y:0},thickness:1,num_layers:t.layerCount,material:"fr4",outline:t.outline}):t.bounds;return n?{...t,obstacles:e,bounds:o}:t},_X=class extends si{constructor(t,e={}){super(),this.inputSrj=t,this.visualizationOptions=e,this.MAX_ITERATIONS=1}inputSrj;visualizationOptions;outputSrj;_step(){const t=fX(this.inputSrj),e=mX(t)??t,n=aX(yX(e));this.outputSrj=fX(n),this.solved=!0}getOutputSimpleRouteJson(){if(!this.outputSrj)throw new Error("PreprocessSimpleRouteJsonSolver has not solved yet");return this.outputSrj}getConstructorParams(){return[this.inputSrj,this.visualizationOptions]}visualize(){return this.outputSrj?pi(Ho({...this.outputSrj,traces:[]},this.visualizationOptions),Yj({srj:this.outputSrj,visualizationOptions:this.visualizationOptions})):{lines:[],points:[],rects:[],circles:[]}}};function bX(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var xX=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;nodeSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[bX("preprocessSimpleRouteJsonSolver",_X,t=>[t.originalSrj],{onSolved:t=>{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),bX("escapeViaLocationSolver",Uj,t=>[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=>{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),bX("netToPointPairsSolver",ga,t=>{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),bX("nodeSolver",Kn,t=>[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),bX("nodeDimensionSubdivisionSolver",Tz,t=>[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=>{t.capacityNodes=t.nodeDimensionSubdivisionSolver?.outputNodes??[]}}),bX("edgeSolver",ui,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),bX("availableSegmentPointSolver",ci,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),bX("necessaryCrampedPortPointSolver",sf,t=>[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),bX("portPointPathingSolver",jj,t=>{const e=t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=>t.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),bX("uniformPortDistributionSolver",go,t=>[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),bX("highDensityRouteSolver",zs,t=>{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=(e.length>0?e:n).map(e=>ws(e)?{...e,availableZ:Array.from({length:t.srj.layerCount},(t,e)=>e)}:e);return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=>[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0}]}),bX("highDensityForceImproveSolver",Yy,t=>[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,totalStepsPerNode:Math.max(20,Math.round(60*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),bX("highDensityRepairSolver",AY,t=>[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2}]),bX("highDensityStitchSolver",KY,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),bX("traceSimplificationSolver",vc,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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,iterations:2}]),bX("traceWidthSolver",Ic,t=>[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),bX("globalDrcForceImproveSolver",Nz,t=>[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.nodeSolver?.visualize(),o=this.nodeDimensionSubdivisionSolver?.visualize(),i=this.nodeTargetMerger?.visualize(),r=this.singleLayerNodeMerger?.visualize(),s=this.strawSolver?.visualize(),a=this.edgeSolver?.visualize(),c=this.deadEndSolver?.visualize(),l=this.availableSegmentPointSolver?.visualize(),d=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),u=this.uniformPortDistributionSolver?.visualize(),p=this.highDensityRouteSolver?.visualize(),m=this.highDensityForceImproveSolver?.visualize(),g=this.highDensityRepairSolver?.visualize(),f=this.highDensityStitchSolver?.visualize(),y=this.traceSimplificationSolver?.visualize(),_=this.necessaryCrampedPortPointSolver?.visualize(),b=(this.highDensityRouteSolver?.visualize(),this.originalSrj),x=b.outline,v=[];if(v.push({points:[{x:b.bounds?.minX??-50,y:b.bounds?.minY??-50},{x:b.bounds?.maxX??50,y:b.bounds?.minY??-50},{x:b.bounds?.maxX??50,y:b.bounds?.maxY??50},{x:b.bounds?.minX??-50,y:b.bounds?.maxY??50},{x:b.bounds?.minX??-50,y:b.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 S=Oo(b),I={points:[...b.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,layer:Fo(e,b.layerCount),label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(b.obstacles??[]).filter(t=>!t.isCopperPour).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)",layer:jo(t,b.layerCount),label:S(t)}))],lines:v},C=Yj({srj:b}),P=[pi(I,C),t,e,n,o,i,r,s,a,c,l,_,d,h,u,p?pi(I,p):null,m,g,f,y,this.solved?pi({lines:v},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...P)}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.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){return this.globalDrcForceImproveSolver?.getOutput()??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 o=n.__netConnectionName??this.originalSrj.connections.find(t=>t.name===n.name)?.__netConnectionName,i=e.filter(t=>t.connectionName===n.name);for(let e=0;e<i.length;e++){const r=i[e],s={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.srj.obstacles,connMap:this.connMap})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},vX=t=>{const e=[];let n=t;for(;n;)e.push(n),n=n.activeSubSolver;for(let t=e.length-1;t>=0;t--){const n=e[t]?.pendingEffects?.filter(Boolean)??[];if(n.length>0)return n}return[]},SX=t=>/\/solve\/?$/.test(t)?t.replace(/\/+$/,""):`${t.replace(/\/+$/,"")}/solve`,IX=(t,e,n)=>{const o=(t=>{const e=new Map;for(const n of t.portPoints)n.rootConnectionName&&!e.has(n.connectionName)&&e.set(n.connectionName,n.rootConnectionName);return e})(t);return e.map(t=>({connectionName:t.connectionName,rootConnectionName:t.rootConnectionName??o.get(t.connectionName)??void 0,traceThickness:t.traceThickness??n.traceWidth,viaDiameter:t.viaDiameter??n.viaDiameter,route:(t.route??[]).map(t=>({x:t.x,y:t.y,z:t.z,...t.insideJumperPad?{insideJumperPad:!0}:{}})),vias:(t.vias??[]).map(t=>({x:t.x,y:t.y})),...t.jumpers?{jumpers:t.jumpers}:{}}))},CX=(t,e)=>{if(0===t.length)return null;const n=Math.min(Math.max(e,0),1),o=(t.length-1)*n,i=Math.floor(o),r=Math.ceil(o),s=t[i],a=t[r];return i===r?s:s+(a-s)*(o-i)},PX=t=>new Set(t.portPoints.map(t=>t.connectionName)).size,MX=t=>!(PX(t)<3)&&1!==(t.availableZ?.length??0),NX=t=>t?.MULTI_HEAD_POLYLINE_SOLVER?"MultiHeadPolyLineIntraNodeSolver3":t?.CLOSED_FORM_SINGLE_TRANSITION?"SingleTransitionIntraNodeSolver":t?.CLOSED_FORM_TWO_TRACE_SAME_LAYER?"TwoCrossingRoutesHighDensitySolver":t?.CLOSED_FORM_TWO_TRACE_TRANSITION_CROSSING?"SingleTransitionCrossingRouteSolver":t?.HIGH_DENSITY_A01?"HighDensitySolverA01":t?.HIGH_DENSITY_A03?"HighDensitySolverA03":"SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost",wX=t=>{if(t instanceof rr){const e=NX(t.hyperParameters);return t.cacheHit?`${e} [cached]`:e}if(t instanceof er)return NX(t.hyperParameters);if(t&&"object"==typeof t&&"getSolverName"in t&&"function"==typeof t.getSolverName)return t.getSolverName();const e=t?.constructor;return"string"==typeof e?.name?e.name:"unknown"},TX=t=>t.winningSolver?wX(t.winningSolver):wX(t),RX=class extends si{getSolverName(){return"Pipeline5HdCacheHighDensitySolver"}unsolvedNodePortPoints;colorMap;connMap;viaDiameter;traceWidth;obstacleMargin;obstacles;layerCount;hdCacheBaseUrl;fetchImpl;nodePfById;routes=[];nodeSolveMetadataById=new Map;launchedRemoteSolves=!1;solvedRoutesByNodeIndex=new Map;failedNodeResults=[];remoteResponseMeasurements=[];constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,obstacles:s,layerCount:a,nodePfById:c,hdCacheBaseUrl:l,fetchImpl:d}){super(),this.unsolvedNodePortPoints=t,this.colorMap=e??{},this.connMap=n,this.viaDiameter=o??.3,this.traceWidth=i??.15,this.obstacleMargin=r??.15,this.obstacles=s??[],this.layerCount=a??2,this.hdCacheBaseUrl=l??"https://hd-cache.tscircuit.com",this.fetchImpl=(d??globalThis.fetch).bind(globalThis),this.nodePfById=c instanceof Map?new Map(c):new Map(Object.entries(c??{})),this.pendingEffects=[],this.stats={localDirectNodeCount:0,localSolvedNodeCount:0,localFallbackNodeCount:0,remoteFallbackNodeCount:0,remoteRequestsStarted:0,remoteRequestsCompleted:0,remoteResponseSampleCount:0,remoteKOrderSampleCount:0,slowestRemoteResponseMs:null,slowestRemoteResponseNodeId:null,p50RemoteResponseMs:null,p50RemoteKOrder:null,p95RemoteKOrder:null,remoteSources:{}}}computeProgress(){return 0===this.unsolvedNodePortPoints.length?1:this.nodeSolveMetadataById.size/this.unsolvedNodePortPoints.length}solveNodeLocally(t,e,n={}){const o=new Ss({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,obstacles:this.obstacles,layerCount:this.layerCount});if(o.solve(),o.failed){const e=o.error??`Local intra-node solver failed for ${t.capacityMeshNodeId}`,i=PX(t);return this.failedNodeResults.push({node:t,error:n.remoteFailure&&"local-fallback"===n.resolution?`Remote solve failed (${n.remoteFailure}); local fallback failed (${e})`:e}),void this.recordNodeSolveMetadata(t,{status:"failed",resolution:"failed",solverType:TX(o),supervisorType:o.getSolverName(),iterations:o.iterations,pairCount:i,routeCount:0,remoteAttempt:"local-fallback"===n.resolution?{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:"error",durationMs:n.remoteDurationMs,error:n.remoteFailure??e}:{attempted:!1},error:e})}this.solvedRoutesByNodeIndex.set(e,o.solvedRoutes);const i=PX(t);this.recordNodeSolveMetadata(t,{status:"solved",resolution:n.resolution??"local",solverType:TX(o),supervisorType:o.getSolverName(),iterations:o.iterations,pairCount:i,routeCount:o.solvedRoutes.length,remoteAttempt:"local-fallback"===n.resolution?{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:"error",durationMs:n.remoteDurationMs,error:n.remoteFailure}:{attempted:!1}}),"local-fallback"===n.resolution?(this.stats.localFallbackNodeCount+=1,this.stats.remoteFallbackNodeCount+=1):this.stats.localDirectNodeCount+=1,this.stats.localSolvedNodeCount+=1}async solveNodeViaHdCache(t,e){const n=SX(this.hdCacheBaseUrl),o={"content-type":"application/json"},i={nodeWithPortPoints:t},r=JSON.stringify(i),s=Date.now();let a,c,l,d=null,h=null;try{const i=await this.fetchImpl(n,{method:"POST",headers:o,body:r});if(a=i.status,c=i.ok,l=await i.text(),d=Date.now()-s,h=l?JSON.parse(l):null,!i.ok)throw new Error(h?.message??l??`hd-cache request failed with status ${i.status}`);if(!h?.ok||null===h.routes)throw new Error(h?.message??`hd-cache returned no routes for ${t.capacityMeshNodeId}`);const u=IX(t,h.routes,{traceWidth:this.traceWidth,viaDiameter:this.viaDiameter});this.solvedRoutesByNodeIndex.set(e,u),this.recordNodeSolveMetadata(t,{status:"solved",resolution:"remote",solverType:`hd-cache.tscircuit.com [${h.source}]`,iterations:null,pairCount:PX(t),routeCount:u.length,remoteAttempt:{attempted:!0,endpoint:SX(this.hdCacheBaseUrl),source:h.source,durationMs:d}}),this.recordRemoteSource(h.source)}catch(u){d??=Date.now()-s;const p=(t=>t instanceof Error?t.message:String(t))(u);this.recordFailedHdCacheRequest({nodeId:t.capacityMeshNodeId,pairCount:PX(t),failedAt:(new Date).toISOString(),durationMs:d,error:p,url:n,request:{method:"POST",headers:o,body:r,bodyJson:i},response:void 0!==a||void 0!==c||void 0!==l||null!==h?{status:a,ok:c,text:l,body:h}:void 0}),this.recordRemoteSource("error"),this.solveNodeLocally(t,e,{resolution:"local-fallback",remoteFailure:p,remoteDurationMs:d})}finally{this.recordRemoteResponseMetrics(t.capacityMeshNodeId,d??Date.now()-s,(u=h?.kOrder,"number"==typeof u&&Number.isFinite(u)?h.kOrder:null)),this.stats.remoteRequestsCompleted+=1}var u}launchRemoteSolves(){const t=[];this.unsolvedNodePortPoints.forEach((e,n)=>{if(!MX(e))return void this.solveNodeLocally(e,n);const o={name:`hd-cache:${e.capacityMeshNodeId}`,promise:Promise.resolve()};o.promise=this.solveNodeViaHdCache(e,n).finally(()=>{this.pendingEffects=this.pendingEffects?.filter(t=>t!==o)}),t.push(o)}),this.pendingEffects=t,this.stats.remoteRequestsStarted=t.length}recordRemoteSource(t){this.stats.remoteSources[t]=(this.stats.remoteSources[t]??0)+1}recordRemoteResponseMetrics(t,e,n){this.remoteResponseMeasurements.push({nodeId:t,durationMs:e,kOrder:n}),this.stats.remoteResponseSampleCount=this.remoteResponseMeasurements.length,this.stats.remoteKOrderSampleCount=this.remoteResponseMeasurements.filter(t=>null!==t.kOrder).length;let o=null;for(const t of this.remoteResponseMeasurements)(!o||t.durationMs>o.durationMs)&&(o=t);this.stats.slowestRemoteResponseMs=o?.durationMs??null,this.stats.slowestRemoteResponseNodeId=o?.nodeId??null;const i=this.remoteResponseMeasurements.map(t=>t.durationMs).sort((t,e)=>t-e);this.stats.p50RemoteResponseMs=CX(i,.5);const r=this.remoteResponseMeasurements.map(t=>t.kOrder).filter(t=>null!==t).sort((t,e)=>t-e);this.stats.p50RemoteKOrder=CX(r,.5),this.stats.p95RemoteKOrder=CX(r,.95)}recordFailedHdCacheRequest(t){const e=(()=>{if("undefined"==typeof window)return null;const t=window;return Array.isArray(t.__FAILED_HD_CACHE_REQUESTS)||(t.__FAILED_HD_CACHE_REQUESTS=[]),t.__FAILED_HD_CACHE_REQUESTS})();e&&e.push(t)}recordNodeSolveMetadata(t,e){this.nodeSolveMetadataById.set(t.capacityMeshNodeId,{...e,node:t,nodePf:this.nodePfById.get(t.capacityMeshNodeId)??null})}ensureFailedNodeMetadata(){for(const t of this.failedNodeResults)this.nodeSolveMetadataById.has(t.node.capacityMeshNodeId)||this.recordNodeSolveMetadata(t.node,{status:"failed",resolution:"failed",solverType:"unknown",iterations:null,pairCount:PX(t.node),routeCount:0,remoteAttempt:{attempted:MX(t.node),source:"error",error:t.error},error:t.error})}getVisibleRoutes(){if(this.solved)return this.routes;const t=[];for(let e=0;e<this.unsolvedNodePortPoints.length;e++)t.push(...this.solvedRoutesByNodeIndex.get(e)??[]);return t}createNodeMarkerLabel(t,e){return["hd_node_marker",`node: ${t}`,`status: ${e.status}`,`resolution: ${e.resolution}`,`solver: ${e.solverType}`,...e.supervisorType?[`supervisor: ${e.supervisorType}`]:[],...null!==e.iterations?[`iterations: ${e.iterations}`]:[],`pairCount: ${e.pairCount}`,`routes: ${e.routeCount}`,`nodePf: ${e.nodePf??"n/a"}`,"remoteAttempted: "+(e.remoteAttempt.attempted?"yes":"no"),...e.remoteAttempt.source?[`remoteSource: ${e.remoteAttempt.source}`]:[],...void 0!==e.remoteAttempt.durationMs?[`remoteDurationMs: ${e.remoteAttempt.durationMs}`]:[],...e.remoteAttempt.error?[`remoteError: ${e.remoteAttempt.error}`]:[],`portPoints: ${e.node.portPoints.length}`,...e.error?[`error: ${e.error}`]:[]].join("\n")}_step(){if(!this.launchedRemoteSolves)return this.launchedRemoteSolves=!0,void this.launchRemoteSolves();if(!((this.pendingEffects?.length??0)>0)){if(this.failedNodeResults.length>0){this.ensureFailedNodeMetadata();const t=this.failedNodeResults[0];return this.failed=!0,void(this.error=`Failed to solve ${this.failedNodeResults.length} nodes via hd-cache. First failure: ${t?.node.capacityMeshNodeId} (${t?.error})`)}this.routes=[];for(let t=0;t<this.unsolvedNodePortPoints.length;t++)this.routes.push(...this.solvedRoutesByNodeIndex.get(t)??[]);this.solved=!0}}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.getVisibleRoutes()){const n=mi(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const o of n)t.lines.push({points:o.points,label:o.connectionName,strokeColor:0===o.z?o.color:To(o.color,.75),layer:`z${o.z}`,strokeWidth:e.traceThickness,strokeDash:0!==o.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,n]of this.nodeSolveMetadataById){const o=n.node.center.x-n.node.width/2,i=n.node.center.x+n.node.width/2,r=n.node.center.y-n.node.height/2,s=n.node.center.y+n.node.height/2,a=this.createNodeMarkerLabel(e,n),c="solved"===n.status?"blue":"red",l="solved"===n.status?.03:.08;if(t.lines.push({points:[{x:o,y:r},{x:i,y:r}],layer:"hd_node_boundaries",strokeColor:c,strokeDash:"6, 4",strokeWidth:l,label:a},{points:[{x:i,y:r},{x:i,y:s}],layer:"hd_node_boundaries",strokeColor:c,strokeDash:"6, 4",strokeWidth:l,label:a},{points:[{x:i,y:s},{x:o,y:s}],layer:"hd_node_boundaries",strokeColor:c,strokeDash:"6, 4",strokeWidth:l,label:a},{points:[{x:o,y:s},{x:o,y:r}],layer:"hd_node_boundaries",strokeColor:c,strokeDash:"6, 4",strokeWidth:l,label:a}),"solved"===n.status)t.points.push({x:n.node.center.x,y:n.node.center.y,color:c,layer:"hd_node_markers",label:a});else{t.lines.push({points:[{x:0,y:0},{x:n.node.center.x,y:n.node.center.y}],layer:"hd_failed_node_guides",strokeColor:c,strokeDash:"8, 6",strokeWidth:.05,label:a});const e=Math.max(n.node.width,1.2),o=Math.max(n.node.height,1.2),i=e/2,r=o/2;t.rects.push({center:n.node.center,layer:"hd_node_markers",width:e,height:o,fill:"rgba(255, 0, 0, 0.3)",stroke:c,label:a}),t.circles.push({center:n.node.center,radius:Math.max(.6*Math.max(e,o),1.1),layer:"hd_node_markers",fill:"rgba(255, 0, 0, 0.08)",stroke:c,label:a}),t.lines.push({points:[{x:n.node.center.x-i,y:n.node.center.y-r},{x:n.node.center.x+i,y:n.node.center.y+r}],layer:"hd_node_markers",strokeColor:c,strokeWidth:.16,label:a},{points:[{x:n.node.center.x-i,y:n.node.center.y+r},{x:n.node.center.x+i,y:n.node.center.y-r}],layer:"hd_node_markers",strokeColor:c,strokeWidth:.16,label:a})}}return t}},EX=class extends xX{hdCacheBaseUrl;hdCacheFetch;constructor(t,e={}){super(t,{...e,maxNodeDimension:e.maxNodeDimension??7,maxNodeRatio:e.maxNodeRatio??4}),this.hdCacheBaseUrl=e.hdCacheBaseUrl??"https://hd-cache.tscircuit.com",this.hdCacheFetch=e.hdCacheFetch,this.replaceHighDensityPipelineStep()}replaceHighDensityPipelineStep(){const t=this.pipelineDef.findIndex(t=>"highDensityRouteSolver"===t.solverName);if(-1===t)throw new Error("Pipeline4 highDensityRouteSolver step is missing");this.pipelineDef[t]={...this.pipelineDef[t],solverClass:RX,getConstructorParams:t=>{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length>0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=>[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,hdCacheBaseUrl:t.hdCacheBaseUrl,fetchImpl:t.hdCacheFetch}]}}}async stepAsync(){if(this.solved||this.failed)return;this.step();const t=vX(this);0!==t.length&&(await Promise.race(t.map(t=>t.promise.then(()=>t.name,()=>t.name))),this.solved||this.failed||this.step())}async solveAsync(){const t=Date.now();for(;!this.solved&&!this.failed;)await this.stepAsync();this.timeToSolve=Date.now()-t}solve(){throw new Error("AutoroutingPipelineSolver5_HdCache requires async execution. Use solveAsync() or stepAsync().")}},AX=1e-9,OX=Math.PI/2,kX=(t,e)=>t.x*e.y-t.y*e.x,LX=(t,e)=>t.x*e.x+t.y*e.y,DX=t=>{let e=t%OX;return e<0&&(e+=OX),OX-e<1e-8?0:e},zX=t=>{const e=Math.cos(t),n=Math.sin(t);return{u:{x:e,y:n},v:{x:-n,y:e}}},FX=t=>{let e=0;for(let n=0;n<t.length;n++){const o=t[n],i=t[(n+1)%t.length];e+=o.x*i.y-i.x*o.y}return e/2},BX=t=>Math.abs(FX(t)),jX=t=>{const e=FX(t);if(Math.abs(e)<AX){const e=t.reduce((t,e)=>({x:t.x+e.x,y:t.y+e.y}),{x:0,y:0});return{x:e.x/Math.max(1,t.length),y:e.y/Math.max(1,t.length)}}let n=0,o=0;for(let e=0;e<t.length;e++){const i=t[e],r=t[(e+1)%t.length],s=i.x*r.y-r.x*i.y;n+=(i.x+r.x)*s,o+=(i.y+r.y)*s}const i=1/(6*e);return{x:n*i,y:o*i}},$X=t=>FX(t)>=0?[...t]:[...t].reverse(),YX=(t,e)=>{const n=new Set;n.add(0);for(let t=0;t<90;t++)n.add(t/90*OX);for(let e=0;e<t.length;e++){const o=t[e],i=t[(e+1)%t.length],r=Math.atan2(i.y-o.y,i.x-o.x);n.add(DX(r)),n.add(DX(r+OX))}const o=n=>{const o=((t,e=jX(t),n=0)=>{const o=$X(t),{u:i,v:r}=zX(n),s=o.map((t,n)=>{const s=o[(n+1)%o.length],a=s.x-t.x,c=s.y-t.y,l={x:a,y:c};return{hxCoeff:Math.abs(kX(l,i)),hyCoeff:Math.abs(kX(l,r)),limit:a*(e.y-t.y)-c*(e.x-t.x)}});if(s.some(t=>t.limit<-1e-7))throw new Error("Projected rect center is outside polygon");let a=Number.POSITIVE_INFINITY;for(const t of s)t.hxCoeff>AX&&(a=Math.min(a,t.limit/t.hxCoeff));if(!Number.isFinite(a)||a<=AX)return{center:e,width:1e-6,height:1e-6,ccwRotationRadians:n,ccwRotationDegrees:180*n/Math.PI};const c=t=>{let e=Number.POSITIVE_INFINITY;for(const n of s){const o=n.limit-n.hxCoeff*t;if(o<-1e-8)return 0;n.hyCoeff>AX&&(e=Math.min(e,o/n.hyCoeff))}return Number.isFinite(e)?Math.max(0,e):0},l=t=>t*c(t);let d=0,h=a;for(let t=0;t<80;t++){const t=d+(h-d)/3,e=h-(h-d)/3;l(t)<l(e)?d=t:h=e}const u=(d+h)/2,p=c(u);return{center:e,width:Math.max(1e-6,2*u),height:Math.max(1e-6,2*p),ccwRotationRadians:n,ccwRotationDegrees:180*n/Math.PI}})(t,e,n);return{rect:o,area:o.width*o.height}};let i=o(0),r=0;for(const t of n){const e=o(t);e.area>i.area+1e-8&&(i=e,r=t)}const s=OX/90;let a=r-s,c=r+s;for(let t=0;t<60;t++){const t=a+(c-a)/3,e=c-(c-a)/3;o(t).area<o(e).area?a=t:c=e}const l=o(DX((a+c)/2));return l.area>i.area+1e-8?l.rect:i.rect},XX=(t,e,n,o)=>{const i=o.x-n.x,r=o.y-n.y,s=e.x*r-e.y*i;if(Math.abs(s)<AX)return;const a=n.x-t.x,c=n.y-t.y,l=(a*r-c*i)/s,d=(a*e.y-c*e.x)/s;return l<-1e-8||d<-1e-8||d>1+1e-8?void 0:{x:t.x+e.x*l,y:t.y+e.y*l,rayT:l}},VX=(t,e)=>{const n=[],o=[];for(let i=0;i<4;i++){const{x:r,y:s}=t[i],a=e[i].x,c=e[i].y;n.push([r,s,1,0,0,0,-a*r,-a*s]),o.push(a),n.push([0,0,0,r,s,1,-c*r,-c*s]),o.push(c)}const i=((t,e)=>{const n=e.length,o=t.map((t,n)=>[...t,e[n]]);for(let t=0;t<n;t++){let e=t;for(let i=t+1;i<n;i++)Math.abs(o[i][t])>Math.abs(o[e][t])&&(e=i);if(Math.abs(o[e][t])<AX)throw new Error("Could not solve homography");[o[t],o[e]]=[o[e],o[t]];const i=o[t][t];for(let e=t;e<=n;e++)o[t][e]=o[t][e]/i;for(let e=0;e<n;e++){if(e===t)continue;const i=o[e][t];for(let r=t;r<=n;r++)o[e][r]=o[e][r]-i*o[t][r]}}return o.map(t=>t[n])})(n,o);return[i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7],1]},WX=(t,e)=>{const n=Math.cos(e),o=Math.sin(e);return[n,-o,t.x-n*t.x+o*t.y,o,n,t.y-o*t.x-n*t.y,0,0,1]},HX=(t,e)=>{const n=t[6]*e.x+t[7]*e.y+t[8];return Math.abs(n)<AX?{x:e.x,y:e.y}:{x:(t[0]*e.x+t[1]*e.y+t[2])/n,y:(t[3]*e.x+t[4]*e.y+t[5])/n}},GX=(t,e,n)=>{const{u:o,v:i}=zX(n);return{x:e.x+t.x*o.x+t.y*i.x,y:e.y+t.x*o.y+t.y*i.y}},UX=(t,e)=>GX({x:t.x-e.center.x,y:t.y-e.center.y},e.center,e.ccwRotationRadians),ZX=(t,e)=>{const n=((t,e,n)=>{const{u:o,v:i}=zX(n),r={x:t.x-e.x,y:t.y-e.y};return{x:LX(r,o),y:LX(r,i)}})(t,e.center,e.ccwRotationRadians);if(Math.abs(n.x)<AX&&Math.abs(n.y)<AX)return{...e.center};const o=e.width/2,i=e.height/2,r=Math.abs(n.x)>AX?o/Math.abs(n.x):1/0,s=Math.abs(n.y)>AX?i/Math.abs(n.y):1/0,a=Math.min(r,s);return{x:e.center.x+n.x*a,y:e.center.y+n.y*a}},qX=(t,e=0,n=0)=>{const o=((t,e)=>{const n=$X(e);for(let e=0;e<n.length;e++){const o=n[e],i=n[(e+1)%n.length];if((i.x-o.x)*(t.y-o.y)-(i.y-o.y)*(t.x-o.x)<-1e-7)return!1}return!0})(jX(t),t)?[...t]:(t=>{const e=[...t].filter((t,e,n)=>n.findIndex(e=>Math.abs(e.x-t.x)<1e-9&&Math.abs(e.y-t.y)<1e-9)===e).sort((t,e)=>t.x-e.x||t.y-e.y);if(e.length<=3)return e;const n=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),o=[];for(const t of e){for(;o.length>=2&&n(o[o.length-2],o[o.length-1],t)<=1e-9;)o.pop();o.push(t)}const i=[];for(let t=e.length-1;t>=0;t--){const o=e[t];for(;i.length>=2&&n(i[i.length-2],i[i.length-1],o)<=1e-9;)i.pop();i.push(o)}return o.pop(),i.pop(),[...o,...i]})(t),i=jX(o),r=YX(o,i),s=BX(o),a=r.width*r.height,c=(l=e,Math.max(0,l));var l;const d=a+Math.max(0,s-a)*c,h=a>AX&&d>a?Math.sqrt(d/a):1,u=Math.max(0,n),p=Math.max(r.width*h,u),m=Math.max(r.height*h,u),g=DX(r.ccwRotationRadians),f=180*g/Math.PI,y=(t=>{const e=t.width/2,n=t.height/2;return[{x:t.center.x-e,y:t.center.y-n},{x:t.center.x+e,y:t.center.y-n},{x:t.center.x+e,y:t.center.y+n},{x:t.center.x-e,y:t.center.y+n}]})({center:i,width:p,height:m}),_=(t=>{const e=t.width/2,n=t.height/2;return[GX({x:-e,y:-n},t.center,t.ccwRotationRadians),GX({x:e,y:-n},t.center,t.ccwRotationRadians),GX({x:e,y:n},t.center,t.ccwRotationRadians),GX({x:-e,y:n},t.center,t.ccwRotationRadians)]})({center:i,width:p,height:m,ccwRotationRadians:g}),b=_.map(t=>{const e={x:t.x-i.x,y:t.y-i.y},n=((t,e,n)=>{let o;for(let i=0;i<n.length;i++){const r=XX(t,e,n[i],n[(i+1)%n.length]);r&&(!o||r.rayT<o.rayT)&&(o=r)}return o})(i,e,o);return n?{x:n.x,y:n.y}:t});let x=BX(b)>AX?b:_;let v,S;try{v=VX(y,x),S=(t=>{const[e,n,o,i,r,s,a,c,l]=t,d=r*l-s*c,h=-(i*l-s*a),u=i*c-r*a,p=-(n*l-o*c),m=e*l-o*a,g=-(e*c-n*a),f=n*s-o*r,y=-(e*s-o*i),_=e*r-n*i,b=e*d+n*h+o*u;if(Math.abs(b)<AX)throw new Error("Cannot invert singular 3x3 matrix");const x=1/b;return[d*x,p*x,f*x,h*x,m*x,y*x,u*x,g*x,_*x]})(v)}catch{x=_,v=WX(i,g),S=WX(i,-g)}return{center:i,width:p,height:m,innerWidth:r.width,innerHeight:r.height,ccwRotationDegrees:f,ccwRotationRadians:g,polygonArea:s,equivalentAreaExpansionFactor:c,targetQuad:x,rectToPolygonMatrix:v,polygonToRectMatrix:S}},JX=class extends si{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1}params;getSolverName(){return"AttachProjectedRectsSolver"}outputNodes=[];projectionAdjustmentByNodeId=new Map;_step(){this.projectionAdjustmentByNodeId.clear(),this.outputNodes=this.params.nodesWithPortPoints.map(t=>{const e=this.params.equivalentAreaExpansionFactor??0,n=this.params.minProjectedRectDimension??0,o=(({traceWidth:t,viaDiameter:e,obstacleMargin:n,minProjectedRectDimension:o})=>Math.max(o,e??0,(t??0)+2*(n??0)))({traceWidth:this.params.traceWidth,viaDiameter:this.params.viaDiameter,obstacleMargin:this.params.obstacleMargin,minProjectedRectDimension:n});let i=qX(t.polygon,e,n);if(Math.min(i.width,i.height)>o+(this.params.traceWidth??0))return{...t,center:i.center,width:i.width,height:i.height,projectedRect:i};const r=qX(t.polygon,1,n);return(({node:t,projectedRect:e,conservativeProjectedRect:n,requiredRoutingCorridorWidth:o,traceWidth:i})=>{if(o<=0)return!1;const r=Math.min(e.width,e.height),s=Math.min(n.width,n.height),a=Math.max(e.width,e.height),c=Math.max(n.width,n.height),l=o+(i??0),d=Math.floor(r/o),h=Math.floor(s/o);return new Set(t.portPoints.map(t=>t.connectionName)).size>1&&d<=h&&r<=l&&a-c>=o&&e.equivalentAreaExpansionFactor>1})({node:t,projectedRect:i,conservativeProjectedRect:r,requiredRoutingCorridorWidth:o,traceWidth:this.params.traceWidth})&&(i=r,this.projectionAdjustmentByNodeId.set(t.capacityMeshNodeId,"corridor-expansion-factor-1")),{...t,center:i.center,width:i.width,height:i.height,projectedRect:i}}),this.solved=!0}getOutput(){return this.outputNodes}getConstructorParams(){return[this.params]}visualize(){const t=this.outputNodes.length>0?this.outputNodes:this.params.nodesWithPortPoints;return{polygons:t.map(t=>({points:t.polygon,fill:"rgba(40, 140, 220, 0.06)",stroke:"rgba(20, 70, 160, 0.95)",strokeWidth:.04,label:`${t.capacityMeshNodeId} polygon`})),lines:t.map(t=>({points:[...t.polygon,t.polygon[0]],strokeColor:"rgba(20, 70, 160, 0.95)",strokeWidth:.04,label:`${t.capacityMeshNodeId} polygon outline`})),rects:t.flatMap(t=>t.projectedRect?[{center:t.projectedRect.center,width:t.projectedRect.width,height:t.projectedRect.height,ccwRotationDegrees:t.projectedRect.ccwRotationDegrees,fill:"rgba(255, 165, 0, 0.16)",stroke:"rgba(255, 140, 0, 0.8)",label:`${t.capacityMeshNodeId} projectedRect`}]:[]),points:t.flatMap(t=>t.portPoints.map(t=>({x:t.x,y:t.y,color:"rgba(30, 30, 30, 0.85)",label:t.connectionName})))}}},KX=class extends si{constructor(t){super(),this.params=t;const{nodeWithPortPoints:e}=t;if(!e.projectedRect)throw new Error("Poly node is missing projectedRect");this.projectedPorts=e.portPoints.map(t=>{const n=ZX(t,e.projectedRect);return{original:t,projected:{...t,x:n.x,y:n.y}}}),this.projectedNode={capacityMeshNodeId:e.capacityMeshNodeId,center:e.projectedRect.center,width:e.projectedRect.width,height:e.projectedRect.height,availableZ:e.availableZ,portPoints:this.projectedPorts.map(({projected:t})=>t)},this.highDensitySolver=new Ss({nodeWithPortPoints:this.projectedNode,colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort}),this.activeSubSolver=this.highDensitySolver,this.MAX_ITERATIONS=this.highDensitySolver.MAX_ITERATIONS+1e3}params;getSolverName(){return"PolySingleIntraNodeSolver"}highDensitySolver;projectedNode;solvedRoutes=[];projectedPorts;_step(){this.highDensitySolver.step(),this.progress=this.highDensitySolver.progress,this.stats=this.highDensitySolver.stats,this.highDensitySolver.solved?(this.solvedRoutes=this.highDensitySolver.solvedRoutes,this.solved=!0,this.activeSubSolver=null):this.highDensitySolver.failed&&(this.error=this.highDensitySolver.error,this.failed=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.params]}visualize(){const t=this.params.nodeWithPortPoints,e=t.projectedRect,n={polygons:[{points:t.polygon,fill:"rgba(60, 160, 220, 0.10)",stroke:"rgba(40, 90, 150, 0.7)",label:`${t.capacityMeshNodeId} polygon`},...e?[{points:e.targetQuad,fill:"rgba(255, 165, 0, 0.08)",stroke:"rgba(255, 120, 0, 0.65)",label:`${t.capacityMeshNodeId} distortion target`}]:[]],rects:e?[{center:e.center,width:e.width,height:e.height,ccwRotationDegrees:e.ccwRotationDegrees,fill:"rgba(255, 165, 0, 0.14)",stroke:"rgba(255, 120, 0, 0.8)",label:`${t.capacityMeshNodeId} projectedRect`}]:[],points:[...t.portPoints.map(t=>({x:t.x,y:t.y,color:"rgba(0, 80, 160, 0.85)",label:`${t.connectionName} original`})),...this.projectedPorts.map(({projected:t})=>({x:t.x,y:t.y,color:"rgba(255, 120, 0, 0.85)",label:`${t.connectionName} projected`}))]};return pi(n,this.highDensitySolver.visualize())}},QX=class extends si{getSolverName(){return"PolyHighDensitySolver"}unsolvedNodePortPoints;nodePortPoints;routes=[];routesByNodeId=new Map;failedSolvers=[];activeSubSolver=null;colorMap;connMap;viaDiameter;traceWidth;obstacleMargin;effort;nodePfById;constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a}){super(),this.nodePortPoints=[...t],this.unsolvedNodePortPoints=[...t],this.colorMap=e??{},this.connMap=n,this.viaDiameter=o??.3,this.traceWidth=i??.15,this.obstacleMargin=r??.15,this.effort=s??1,this.MAX_ITERATIONS=1e7*this.effort,this.nodePfById=a instanceof Map?new Map(a):new Map(Object.entries(a??{}))}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){const t=this.activeSubSolver.params.nodeWithPortPoints.capacityMeshNodeId,e=this.activeSubSolver.solvedRoutes;this.routesByNodeId.set(t,[...this.routesByNodeId.get(t)??[],...e]),this.routes.push(...this.activeSubSolver.solvedRoutes),this.activeSubSolver=null}else this.activeSubSolver.failed&&(this.failedSolvers.push(this.activeSubSolver),this.activeSubSolver=null);return}if(0===this.unsolvedNodePortPoints.length)return this.failedSolvers.length>0?(this.failed=!0,void(this.error=`Failed to solve ${this.failedSolvers.length} poly nodes, ${this.failedSolvers.slice(0,5).map(t=>t.params.nodeWithPortPoints.capacityMeshNodeId).join(", ")}. err0: ${this.failedSolvers[0]?.error}`)):void(this.solved=!0);const t=this.unsolvedNodePortPoints.pop();this.activeSubSolver=new KX({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort})}computeProgress(){const t=this.routes.length+this.failedSolvers.length+this.unsolvedNodePortPoints.length+(this.activeSubSolver?1:0);return 0===t?1:(this.routes.length+this.failedSolvers.length+(this.activeSubSolver?.progress??0))/t}getConstructorParams(){return[{nodePortPoints:this.nodePortPoints,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById}]}visualize(){const t={polygons:this.nodePortPoints.map(t=>({points:t.polygon,fill:"rgba(180, 180, 180, 0.05)",stroke:"rgba(120, 120, 120, 0.25)",label:`${t.capacityMeshNodeId} polygon`})),rects:this.nodePortPoints.flatMap(t=>t.projectedRect?[{center:t.projectedRect.center,width:t.projectedRect.width,height:t.projectedRect.height,ccwRotationDegrees:t.projectedRect.ccwRotationDegrees,fill:"rgba(255, 165, 0, 0.08)",stroke:"rgba(255, 120, 0, 0.65)",label:`${t.capacityMeshNodeId} projectedRect`}]:[]),lines:[],circles:[],points:this.nodePortPoints.flatMap(t=>t.portPoints.map(t=>({x:t.x,y:t.y,color:"rgba(80, 80, 80, 0.5)",label:`${t.connectionName} original`})))};for(const[e,n]of this.routesByNodeId){const o=this.nodePortPoints.find(t=>t.capacityMeshNodeId===e),i=o?.projectedRect;if(i)for(const e of n){const n=this.colorMap[e.connectionName]??"#0000ff",o={...e,route:e.route.map(t=>({...t,...UX(t,i)})),vias:e.vias.map(t=>UX(t,i))},r=mi(o.route,e.connectionName,n);for(const n of r)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:To(n.color,.5),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?[.1,.3]:void 0});for(const i of o.vias)t.circles.push({center:i,layer:"z0,1",radius:e.viaDiameter/2,fill:n,label:`${e.connectionName} via`})}}const e=this.activeSubSolver?.visualize();return e&&t.polygons.push(...this.unsolvedNodePortPoints.map(t=>({points:t.polygon,fill:"rgba(180, 180, 180, 0.08)",stroke:"rgba(120, 120, 120, 0.4)",label:t.capacityMeshNodeId}))),e?pi(t,e):t}},tV=t=>{const{o:e,a:n,b:o}=t;return(n.x-e.x)*(o.y-e.y)-(n.y-e.y)*(o.x-e.x)},eV=(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 o=[],i=[];for(const t of n){for(;o.length>=2;){const e=o[o.length-2],n=o[o.length-1];if(!e||!n||tV({o:e,a:n,b:t})>1e-10)break;o.pop()}o.push(t)}for(let t=n.length-1;t>=0;t--){const e=n[t];if(e){for(;i.length>=2;){const t=i[i.length-2],n=i[i.length-1];if(!t||!n||tV({o:t,a:n,b:e})>1e-10)break;i.pop()}i.push(e)}}return o.pop(),i.pop(),o.concat(i).map(t=>t.i)},nV=t=>{const e=Math.max(0,Math.min(30,Math.floor(t)));return 0===e?0:(1<<e)-1},oV=(t,e=31)=>{const n=[],o=Math.max(0,Math.min(31,Math.floor(e)));for(let e=0;e<o;e++)t&1<<e&&n.push(e);return n},iV=t=>{let e=0;for(const n of t)Number.isInteger(n)&&n>=0&&n<31&&(e|=1<<n);return e},rV=(t,e)=>{const n=t.trim().toLowerCase();if("top"===n)return 0;if("bottom"===n)return Math.max(0,e-1);const o=n.match(/^inner(\d+)$/);if(o?.[1]){const t=Number(o[1]);return t>=0&&t<e?t:void 0}const i=n.match(/^layer(\d+)$/);if(i?.[1]){const t=Number(i[1])-1;return t>=0&&t<e?t:void 0}const r=n.match(/^z(\d+)$/);if(r?.[1]){const t=Number(r[1]);return t>=0&&t<e?t:void 0}},sV=(t,e)=>{const n=nV(e),o=t.zLayers;if(Array.isArray(o)&&o.length>0)return iV(o)&n;const i=t.layers;if(Array.isArray(i)&&i.length>0){let t=0;for(const n of i){const o=rV(n,e);void 0!==o&&(t|=1<<o)}return t&n}return n},aV=.1,cV=.15,lV=aV+cV,dV=3*lV/4,hV=5,uV=1e-9,pV=t=>Math.round(1e6*t)/1e6,mV=t=>`${pV(t.x)},${pV(t.y)}`,gV=(t,e)=>{const n=mV(t),o=mV(e);return n<o?`${n}|${o}`:`${o}|${n}`},fV=t=>{let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t)e=Math.min(e,r.x),n=Math.max(n,r.x),o=Math.min(o,r.y),i=Math.max(i,r.y);return{minX:e,maxX:n,minY:o,maxY:i}},yV=(t,e)=>{const n=t.x<e.minX?e.minX-t.x:t.x>e.maxX?t.x-e.maxX:0,o=t.y<e.minY?e.minY-t.y:t.y>e.maxY?t.y-e.maxY:0;return n*n+o*o},_V=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r<1e-18)return!1;const s=((t.x-e.x)*o+(t.y-e.y)*i)/r;if(s<-1e-9||s>1+1e-9)return!1;const a=e.x+s*o,c=e.y+s*i;return(t.x-a)**2+(t.y-c)**2<1e-12},bV=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r<uV)return(t.x-e.x)**2+(t.y-e.y)**2;const s=Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r)),a=e.x+s*o,c=e.y+s*i;return(t.x-a)**2+(t.y-c)**2},xV=(t,e)=>({x:(t.x+e.x)/2,y:(t.y+e.y)/2}),vV=(t,e,n,o=.001)=>{const i=o*o;return((t,e)=>{let n=Number.POSITIVE_INFINITY;for(let o=0;o<e.length;o++){const i=e[o],r=e[(o+1)%e.length];n=Math.min(n,bV(t,i,r))}return n})(xV(t,e),n)<=i},SV=(t,e)=>{let n=!1;for(let o=0,i=e.length-1;o<e.length;i=o++){const r=e[o],s=e[i];if(_V(t,r,s))return!0;r.y>t.y!=s.y>t.y&&t.x<(s.x-r.x)*(t.y-r.y)/(s.y-r.y+1e-12)+r.x&&(n=!n)}return n},IV=(t,e,n,o)=>{const i=e.x-t.x,r=e.y-t.y,s=o.x-n.x,a=o.y-n.y,c=i*a-r*s;if(Math.abs(c)<uV){for(const i of[t,e])if(_V(i,n,o))return i;for(const i of[n,o])if(_V(i,t,e))return i;return}const l=((n.x-t.x)*a-(n.y-t.y)*s)/c,d=((n.x-t.x)*r-(n.y-t.y)*i)/c;if(!(l<-1e-9||l>1.000000001||d<-1e-9||d>1.000000001))return{x:t.x+l*i,y:t.y+l*r}},CV=(t,e)=>{for(const n of t)if(SV(n,e))return n;for(const n of e)if(SV(n,t))return n;for(let n=0;n<t.length;n++){const o=t[n],i=t[(n+1)%t.length];for(let t=0;t<e.length;t++){const n=e[t],r=e[(t+1)%e.length],s=IV(o,i,n,r);if(s)return s}}},PV=(t,e=1e-6)=>[{x:t.x-e,y:t.y-e},{x:t.x+e,y:t.y-e},{x:t.x,y:t.y+e}],MV=(t,e,n,o,i)=>{const r=e.x-t.x,s=e.y-t.y,a=Math.hypot(r,s);if(a<uV)return[];const c=Number.isFinite(n)&&n>uV?n:lV,l=Number.isFinite(o)?Math.max(0,o):dV,d=Math.min(l,a/2),h=a-2*d;if(h<=.75*c)return[{x:(t.x+e.x)/2,y:(t.y+e.y)/2,distToCentermostPortOnZ:0,cramped:!0}];const u=Math.max(1,Math.floor(h/c)+1),p=Number.isFinite(i)&&i>0?Math.floor(i):hV,m=u>p?p+Math.floor(u/4):u;if(m<=1)return[{x:(t.x+e.x)/2,y:(t.y+e.y)/2,distToCentermostPortOnZ:0,cramped:!1}];const g=a/2,f=Array.from({length:m},(e,n)=>{const o=d+h*n/(m-1),i=o/a;return{x:t.x+r*i,y:t.y+s*i,distanceFromStart:o}}),y=f.reduce((t,e)=>Math.abs(e.distanceFromStart-g)<Math.abs(t-g)?e.distanceFromStart:t,f[0].distanceFromStart);return f.map(({x:t,y:e,distanceFromStart:n})=>({x:t,y:e,distToCentermostPortOnZ:Math.abs(n-y),cramped:!1}))},NV=(t,e)=>{if(!(Math.hypot(e.x-t.x,e.y-t.y)<uV))return{...xV(t,e),distToCentermostPortOnZ:0,cramped:!1}},wV=(t,e)=>{if("object"!=typeof t||null===t)return;const n=t[e];return"string"==typeof n?n:void 0},TV=t=>{const e=new Set,n=t=>{"string"==typeof t&&t.length>0&&e.add(t)},o=t=>{n(t.pointId),n(t.pcb_port_id)};n(t.connectionId),n(t.mutuallyConnectedNetworkId),o(t.start),o(t.end);const i=t.simpleRouteConnection;n(wV(i,"name")),n(wV(i,"source_trace_id")),n(wV(i,"rootConnectionName"));const r="object"==typeof i&&null!==i?i.pointsToConnect:void 0;if(Array.isArray(r))for(const t of r)o(t);return e},RV=t=>{const{regions:e,availableZ:n,layerCount:o,connections:i=[],obstacleRegions:r=[],regionIdPrefix:s="free",portIdPrefix:a="shared-port",traceWidth:c=aV,obstacleMargin:l=cV,portSpacing:d=c+l,portMarginFromSegmentEndpoint:h=3*d/4,maxDensePortsBeforeDecimation:u=hV}=t,p=Array.from({length:o},(t,e)=>e),m=new Map,g=new Map,f=t=>t.mutuallyConnectedNetworkId??t.connectionId;for(const t of i){const e=f(t);let n=m.get(e);void 0===n&&(n=m.size,m.set(e,n));for(const e of TV(t))g.has(e)||g.set(e,n)}const y=e.map((t,e)=>{const o=fV(t);return{regionId:`${s}-${e}`,pointIds:[],d:{polygon:t,availableZ:n?.[e]??p,center:{x:(o.minX+o.maxX)/2,y:(o.minY+o.maxY)/2},width:o.maxX-o.minX,height:o.maxY-o.minY}}}),_=y.map((t,e)=>({regionId:t.regionId,serializedRegionIndex:e,polygon:t.d.polygon,availableZ:t.d.availableZ,bounds:fV(t.d.polygon),isObstacle:!1,netId:void 0})),b=r.flatMap((t,e)=>{if(t.polygon.length<3)return[];const n=(t=>{if(Number.isInteger(t.netId)&&t.netId>=0)return t.netId;if("string"==typeof t.mutuallyConnectedNetworkId)return m.get(t.mutuallyConnectedNetworkId);for(const e of t.connectedTo??[]){const t=g.get(e);if(void 0!==t)return t}})(t);if(void 0===n)return[];const o=t.polygon,i=fV(o),r=t.availableZ??p,s=t.regionId??`obstacle-${e}`,a=y.length;y.push({regionId:s,pointIds:[],d:{...t.d??{},polygon:o,availableZ:r,center:{x:(i.minX+i.maxX)/2,y:(i.minY+i.maxY)/2},width:i.maxX-i.minX,height:i.maxY-i.minY,_containsObstacle:!0,_containsTarget:!0,netId:n}});const c={regionId:s,serializedRegionIndex:a,polygon:o,availableZ:r,bounds:i,isObstacle:!0,netId:n};return _.push(c),[c]}),x=[],v=new Map;for(let t=0;t<e.length;t++){const n=e[t];for(let e=0;e<n.length;e++){const o=n[e],i=n[(e+1)%n.length],r=gV(o,i),s=v.get(r)??[];s.push({regionIndex:t,a:o,b:i}),v.set(r,s)}}let S=0;const I=t=>{const{region1Id:e,region2Id:n,pointIndex:o,portPoint:i,z:r,portIdSuffix:s}=t,c=`${a}-${String(S).padStart(5,"0")}::p${o}::z${r}${s??""}`;return x.push({portId:c,region1Id:e,region2Id:n,d:{portId:c,x:i.x,y:i.y,z:r,distToCentermostPortOnZ:i.distToCentermostPortOnZ,...i.cramped?{cramped:!0}:{}}}),S+=1,c};for(const t of v.values()){if(2!==t.length)continue;const[e,o]=t,i=n?.[e.regionIndex]??p,r=n?.[o.regionIndex]??p,a=i.filter(t=>r.includes(t));if(0===a.length)continue;const c=MV(e.a,e.b,d,h,u);if(0!==c.length)for(let t=0;t<c.length;t++){const n=c[t];for(const i of a){if(b.some(t=>t.availableZ.includes(i)&&vV(e.a,e.b,t.polygon)))continue;const r=I({region1Id:`${s}-${e.regionIndex}`,region2Id:`${s}-${o.regionIndex}`,pointIndex:t,portPoint:n,z:i});y[e.regionIndex].pointIds.push(r),y[o.regionIndex].pointIds.push(r)}}}for(const t of b)for(const e of v.values())for(const o of e){if(!vV(o.a,o.b,t.polygon))continue;const e=(n?.[o.regionIndex]??p).filter(e=>t.availableZ.includes(e));if(0===e.length)continue;const i=NV(o.a,o.b);if(i)for(const n of e){const e=I({region1Id:`${s}-${o.regionIndex}`,region2Id:t.regionId,pointIndex:0,portPoint:i,z:n,portIdSuffix:"::obstacle"});y[o.regionIndex].pointIds.push(e),y[t.serializedRegionIndex].pointIds.push(e)}}for(let t=0;t<b.length;t++){const e=b[t];for(let n=t+1;n<b.length;n++){const t=b[n];if(e.netId!==t.netId)continue;const o=e.availableZ.filter(e=>t.availableZ.includes(e));if(0===o.length)continue;const i=CV(e.polygon,t.polygon);if(i)for(const n of o){const o=I({region1Id:e.regionId,region2Id:t.regionId,pointIndex:0,portPoint:{x:i.x,y:i.y,distToCentermostPortOnZ:0},z:n,portIdSuffix:"::obstacle-contact"});y[e.serializedRegionIndex].pointIds.push(o),y[t.serializedRegionIndex].pointIds.push(o)}}}const C=(t,e)=>{const n=((t,e)=>{if(Number.isInteger(t.z)&&t.z>=0&&t.z<e)return[t.z];if(Array.isArray(t.zLayers)&&t.zLayers.length>0)return t.zLayers.filter(t=>Number.isInteger(t)&&t>=0&&t<e);if("string"==typeof t.layer){const n=rV(t.layer,e);return void 0===n?[]:[n]}return Array.isArray(t.layers)&&t.layers.length>0?t.layers.map(t=>rV(t,e)).filter(t=>void 0!==t):[0]})(t,o);let i;const r=_.filter(t=>t.isObstacle&&(void 0===e||t.netId===e));for(const e of r){const o=n.find(t=>e.availableZ.includes(t))??e.availableZ[0];if(void 0!==o&&SV(t,e.polygon))return{regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o}}for(const e of _.filter(t=>!t.isObstacle)){const o=n.find(t=>e.availableZ.includes(t))??e.availableZ[0];if(void 0===o)continue;if(SV(t,e.polygon))return{regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o};const r=yV(t,e.bounds);(!i||r<i.distanceSq)&&(i={regionId:e.regionId,serializedRegionIndex:e.serializedRegionIndex,z:o,distanceSq:r})}return i},P=[];for(const t of i){const e=m.get(f(t)),n=C(t.start,e),o=C(t.end,e);if(!n||!o)throw new Error(`Could not map connection "${t.connectionId}" endpoint into a generated region`);const i=`terminal-start-${t.connectionId}`,r=`terminal-end-${t.connectionId}`,s=`terminal-start-port-${t.connectionId}`,a=`terminal-end-port-${t.connectionId}`;y.push({regionId:i,pointIds:[s],d:{polygon:PV(t.start),availableZ:[n.z],center:{x:t.start.x,y:t.start.y},width:1e-6,height:1e-6,_containsTarget:!0}}),y.push({regionId:r,pointIds:[a],d:{polygon:PV(t.end),availableZ:[o.z],center:{x:t.end.x,y:t.end.y},width:1e-6,height:1e-6,_containsTarget:!0}}),x.push({portId:s,region1Id:n.regionId,region2Id:i,d:{portId:s,x:t.start.x,y:t.start.y,z:n.z,distToCentermostPortOnZ:0}}),x.push({portId:a,region1Id:o.regionId,region2Id:r,d:{portId:a,x:t.end.x,y:t.end.y,z:o.z,distToCentermostPortOnZ:0}}),y[n.serializedRegionIndex].pointIds.push(s),y[o.serializedRegionIndex].pointIds.push(a),P.push({connectionId:t.connectionId,mutuallyConnectedNetworkId:t.mutuallyConnectedNetworkId,startRegionId:i,endRegionId:r,simpleRouteConnection:t.simpleRouteConnection})}return{regions:y,ports:x,connections:P}},EV=t=>{const{polygon:e,clearance:n,verticesOnly:o=!1}=t,i=e.points,r=i.length;if(r<3)return[];const s=new xO(i.map(t=>mO(t.x,t.y))).orientation()===fE.CCW,a=[];for(let t=0;t<r;t++){const e=i[t],o=i[(t+1)%r],c=gO(o.x-e.x,o.y-e.y);if(0===c.length){a.push(_O(mO(e.x,e.y),gO(1,0)));continue}const l=c.normalize(),d=s?gO(l.y,-l.x):gO(-l.y,l.x),h=mO(e.x+n*d.x,e.y+n*d.y);a.push(_O(h,d))}const c=[];for(let t=0;t<r;t++){const e=a[(t-1+r)%r],n=a[t],o=e.intersect(n);if(o.length>0){const t=o[0];c.push({x:t.x,y:t.y})}else c.push({x:n.pt.x,y:n.pt.y})}if(o)return c;const l=[];for(let t=0;t<r;t++){const e=c[t],n=c[(t+1)%r],o=fO(mO(e.x,e.y),mO(n.x,n.y)).length,i=Math.max(2,Math.ceil(o/20));for(let t=0;t<i;t++){const o=t/i;l.push({x:e.x+o*(n.x-e.x),y:e.y+o*(n.y-e.y)})}}return l},AV=t=>{const{localX:e,localY:n,rect:o}=t,i=Math.cos(o.ccwRotation),r=Math.sin(o.ccwRotation);return{x:o.center.x+e*i-n*r,y:o.center.y+e*r+n*i}},OV=t=>new xO(t.map(t=>mO(t.x,t.y))),kV=t=>{const e=[];for(const n of t.faces){const t=[];for(const e of n.vertices)t.push({x:e.x,y:e.y});t.length>=3&&e.push(t)}return e},LV=(t,e,n)=>{const o=e.length;e.push(...t);const i=t.length;for(let t=0;t<i;t++)n.push([o+t,o+(t+1)%i])},DV=t=>{const{bounds:e,vias:n,clearance:o,rects:i,polygons:r=[],viaSegments:s=8,preserveObstacleBoundaries:a=!1}=t,c=[],l=[],d=[],{minX:h,maxX:u,minY:p,maxY:m}=e,g=10,f=[];for(let t=0;t<g;t++){const e=t/g;f.push({x:h+e*(u-h),y:p})}for(let t=0;t<g;t++){const e=t/g;f.push({x:u,y:p+e*(m-p)})}for(let t=0;t<g;t++){const e=t/g;f.push({x:u-e*(u-h),y:m})}for(let t=0;t<g;t++){const e=t/g;f.push({x:h,y:m-e*(m-p)})}d.push(l.length),LV(f,c,l);const y=[];for(const t of n){const e=t.diameter/2+o,n=[];for(let o=0;o<s;o++){const i=2*Math.PI*o/s;n.push({x:t.center.x+e*Math.cos(i),y:t.center.y+e*Math.sin(i)})}y.push(n)}for(const t of i){const e=t.width/2+o,n=t.height/2+o,i=[AV({localX:-e,localY:-n,rect:t}),AV({localX:e,localY:-n,rect:t}),AV({localX:e,localY:n,rect:t}),AV({localX:-e,localY:n,rect:t})];y.push(i)}for(const t of r){if(t.points.length<3)continue;const e=EV({polygon:t,clearance:o,verticesOnly:!0});y.push(e)}const _=a?y:(t=>{if(t.length<=1)return t;try{let e=t.map(OV);for(let t=0;t<2;t++){const t=[],n=new Set;for(let o=0;o<e.length;o++){if(n.has(o))continue;let i=e[o];for(let t=o+1;t<e.length;t++){if(n.has(t))continue;const o=i.box,r=e[t].box;if(!(o.xmin>r.xmax+1e-6||o.xmax<r.xmin-1e-6||o.ymin>r.ymax+1e-6||o.ymax<r.ymin-1e-6))try{const o=WA.unify(i,e[t]);o.faces.size>0&&(i=o,n.add(t))}catch{}}t.push(i),n.add(o)}e=t}const n=[];for(const t of e){const e=kV(t);n.push(...e)}return n.length>0?n:t}catch{return t}})(y);for(const t of _)d.push(l.length),LV(t,c,l);const b=((t,e,n)=>{const o=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]){o[t]=e;break}const i=new Map,r=t.slice();for(let t=0;t<e.length;t++)for(let n=t+1;n<e.length;n++){if(o[t]===o[n])continue;const[s,a]=e[t],[c,l]=e[n],d=r[s],h=r[a],u=r[c],p=r[l],m=h.x-d.x,g=h.y-d.y,f=p.x-u.x,y=p.y-u.y,_=m*y-g*f;if(Math.abs(_)<1e-10)continue;const b=((u.x-d.x)*y-(u.y-d.y)*f)/_,x=((u.x-d.x)*g-(u.y-d.y)*m)/_;if(b>1e-6&&b<.999999&&x>1e-6&&x<.999999){const e=d.x+b*m,o=d.y+b*g,s=r.length;r.push({x:e,y:o}),i.has(t)||i.set(t,[]),i.get(t).push({t:b,idx:s}),i.has(n)||i.set(n,[]),i.get(n).push({t:x,idx:s})}}if(0===i.size)return{pts:t,constraintEdges:e,hadCrossings:!1};const s=[];for(let t=0;t<e.length;t++){const n=i.get(t);if(!n||0===n.length){s.push(e[t]);continue}n.sort((t,e)=>t.t-e.t);const[o,r]=e[t];let a=o;for(const t of n)s.push([a,t.idx]),a=t.idx;s.push([a,r])}return{pts:r,constraintEdges:s,hadCrossings:!0}})(c,l,d);return{pts:b.pts.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)})),constraintEdges:b.constraintEdges,hadCrossings:b.hadCrossings}},zV=t=>{const{p:e,a:n,b:o}=t,i=o.x-n.x,r=o.y-n.y,s=i*i+r*r;if(s<1e-10)return Math.hypot(e.x-n.x,e.y-n.y);let a=((e.x-n.x)*i+(e.y-n.y)*r)/s;return a=Math.max(0,Math.min(1,a)),Math.hypot(e.x-n.x-a*i,e.y-n.y-a*r)},FV=(t,e)=>{if(t.length<=3)return 0;const n=eV(t,e),o=new Set(n),i=n.map(t=>e[t]).filter(t=>Boolean(t));let r=0;for(const n of t){if(o.has(n))continue;const t=e[n];if(!t)continue;let s=Number.POSITIVE_INFINITY;for(let e=0;e<i.length;e++){const n=i[e],o=i[(e+1)%i.length];n&&o&&(s=Math.min(s,zV({p:t,a:n,b:o})))}r=Math.max(r,s)}return r},BV=(t,e)=>t<e?1e5*t+e:1e5*e+t,jV=(t,e)=>{const n=t.map((e,n)=>[e,t[(n+1)%t.length]]),o=e.map((t,n)=>[t,e[(n+1)%e.length]]),i=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,r]of o)void 0!==r&&t===r&&e===n&&i.add(BV(t,e));if(0===i.size)return null;const r=[];for(const[t,e]of n)void 0!==e&&(i.has(BV(t,e))||r.push([t,e]));for(const[t,e]of o)void 0!==e&&(i.has(BV(t,e))||r.push([t,e]));if(0===r.length)return null;const s=new Map;for(const[t,e]of r)s.set(t,e);const a=r[0]?.[0];if(void 0===a)return null;const c=[a];let l=s.get(a),d=0;for(;void 0!==l&&l!==a&&d++<r.length+5;)c.push(l),l=s.get(l);return l!==a||c.length!==r.length?null:c},$V=(t,e)=>t<e?1e5*t+e:1e5*e+t,YV=(t,e)=>t<e?1e5*t+e:1e5*e+t,XV=c(T(),1),VV=t=>{const{a:e,b:n,c:o}=t,i=2*(e.x*(n.y-o.y)+n.x*(o.y-e.y)+o.x*(e.y-n.y));if(Math.abs(i)<1e-10)return{x:0,y:0,r2:1e18};const r=e.x*e.x+e.y*e.y,s=n.x*n.x+n.y*n.y,a=o.x*o.x+o.y*o.y,c=(r*(n.y-o.y)+s*(o.y-e.y)+a*(e.y-n.y))/i,l=(r*(o.x-n.x)+s*(e.x-o.x)+a*(n.x-e.x))/i;return{x:c,y:l,r2:(e.x-c)**2+(e.y-l)**2}},WV=(t,e,n)=>[t.a,t.b,t.c].includes(e)&&[t.a,t.b,t.c].includes(n),HV=t=>{const{px:e,py:n,polygonPoints:o,clearance:i}=t;if(o.length<3)return!1;const r=o.map(t=>mO(t.x,t.y)),s=[];for(let t=0;t<r.length;t++){const e=r[t],n=r[(t+1)%r.length];s.push(fO(e,n))}const a=new xO;a.addFace(s);const c=mO(e,n);if(a.contains(c))return!0;const[l]=a.distanceTo(c);return l<i-.1},GV=t=>{const{point:e,via:n,clearance:o}=t,i=e.x-n.center.x,r=e.y-n.center.y,s=n.diameter/2+o;return i*i+r*r<=s*s+1e-9},UV=t=>{const{point:e,rect:n,clearance:o}=t,i=Math.cos(-n.ccwRotation),r=Math.sin(-n.ccwRotation),s=e.x-n.center.x,a=e.y-n.center.y,c=s*i-a*r,l=s*r+a*i;return Math.abs(c)<=n.width/2+o+1e-9&&Math.abs(l)<=n.height/2+o+1e-9},ZV=t=>HV({px:t.point.x,py:t.point.y,polygonPoints:t.polygon.points,clearance:t.clearance}),qV=(t,e)=>t.x>=e.minX-1e-9&&t.x<=e.maxX+1e-9&&t.y>=e.minY-1e-9&&t.y<=e.maxY+1e-9,JV=t=>{const{point:e,vias:n,rects:o,polygons:i,clearance:r,layerCount:s}=t;let a=0;for(const t of n)GV({point:e,via:t,clearance:r})&&(a|=sV(t,s));for(const t of o)UV({point:e,rect:t,clearance:r})&&(a|=sV(t,s));for(const t of i)ZV({point:e,polygon:t,clearance:r})&&(a|=sV(t,s));return a},KV=t=>{const{triangles:e,pts:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a,layerCount:c}=t,l=nV(c),d=[],h=[];for(const[t,u,p]of e){const e=n[t],m=n[u],g=n[p];if(!e||!m||!g)continue;const f={x:(e.x+m.x+g.x)/3,y:(e.y+m.y+g.y)/3};if(!qV(f,o))continue;const y=l&~JV({point:f,vias:i,rects:s,polygons:a,clearance:r,layerCount:c});0!==y&&(d.push([t,u,p]),h.push(oV(y,c)))}return{triangles:d,triangleAvailableZ:h}},QV=t=>{const{triangles:e,pts:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a}=t;return e.filter(([t,e,c])=>{const l=n[t],d=n[e],h=n[c];if(!l||!d||!h)return!1;if(!(t=>{const{px:e,py:n,bounds:o,vias:i,clearance:r,rects:s,polygons:a}=t,{minX:c,maxX:l,minY:d,maxY:h}=o,u=1e-6*Math.max(l-c,h-d,1);if(e<c-u||e>l+u||n<d-u||n>h+u)return!1;for(const t of i){const o=t.diameter/2+r,i=Math.max(0,o-u);if((e-t.center.x)**2+(n-t.center.y)**2<i*i)return!1}for(const t of s){const o=t.width/2+r,i=t.height/2+r,s=Math.max(0,o-u),a=Math.max(0,i-u),c=e-t.center.x,l=n-t.center.y,d=Math.cos(t.ccwRotation),h=Math.sin(t.ccwRotation),p=c*d+l*h,m=-c*h+l*d;if(Math.abs(p)<s&&Math.abs(m)<a)return!1}for(const t of a)if(HV({px:e,py:n,polygonPoints:t.points,clearance:r}))return!1;return!0})({px:(l.x+d.x+h.x)/3,py:(l.y+d.y+h.y)/3,bounds:o,vias:i,clearance:r,rects:s,polygons:a}))return!1;if(a.length>0){const t=[l,d,h,{x:(l.x+d.x)/2,y:(l.y+d.y)/2},{x:(d.x+h.x)/2,y:(d.y+h.y)/2},{x:(h.x+l.x)/2,y:(h.y+l.y)/2}];for(const e of t)for(const t of a)if(HV({px:e.x,py:e.y,polygonPoints:t.points,clearance:r}))return!1}return!0})},tW=t=>void 0!==t,eW=t=>{const{bounds:e,clearance:n,concavityTolerance:o}=t,i=t.vias??[],r=t.rects??[],s=t.polygons??[];let a,c,l;if(!1!==t.useConstrainedDelaunay){const o=DV({bounds:e,vias:i,clearance:n,rects:r,polygons:s,viaSegments:t.viaSegments,preserveObstacleBoundaries:void 0!==t.layerCount});a=o.pts;const d=((t,e,n={})=>{const o=t.map(t=>[t.x,t.y]);return(0,XV.default)(o,e,{exterior:!!n.includeConstraintInteriors})})(a,o.constraintEdges,{includeConstraintInteriors:void 0!==t.layerCount});if(void 0!==t.layerCount){const o=KV({triangles:d,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s,layerCount:t.layerCount});c=o.triangles,l=o.triangleAvailableZ}else{c=i.length>0||r.length>0||s.length>0?QV({triangles:d,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s}):d}}else{a=(t=>{const{bounds:e,vias:n,clearance:o,rects:i,polygons:r=[],viaSegments:s=24}=t,a=[],{minX:c,maxX:l,minY:d,maxY:h}=e;a.push({x:c,y:d},{x:l,y:d},{x:l,y:h},{x:c,y:h});for(let t=1;t<10;t++){const e=t/10;a.push({x:c+e*(l-c),y:d}),a.push({x:l,y:d+e*(h-d)}),a.push({x:l-e*(l-c),y:h}),a.push({x:c,y:h-e*(h-d)})}for(const t of n){const e=t.diameter/2+o;for(let n=0;n<s;n++){const o=2*Math.PI*n/s;a.push({x:t.center.x+e*Math.cos(o),y:t.center.y+e*Math.sin(o)})}}for(const t of i){const e=t.width/2+o,n=t.height/2+o,i=Math.max(2,Math.ceil(Math.max(2*e,2*n)/20));for(let o=0;o<i;o++){const r=o/i;a.push(AV({localX:2*r*e-e,localY:-n,rect:t})),a.push(AV({localX:e,localY:2*r*n-n,rect:t})),a.push(AV({localX:e-2*r*e,localY:n,rect:t})),a.push(AV({localX:-e,localY:n-2*r*n,rect:t}))}}for(const t of r){if(t.points.length<3)continue;const e=EV({polygon:t,clearance:o});a.push(...e)}return a.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))})({bounds:e,vias:i,clearance:n,rects:r,polygons:s,viaSegments:t.viaSegments});const o=(t=>{const e=t.map((t,e)=>({...t,i:e}));if(e.length<3)return[];let n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),o=Math.min(o,t.y),i=Math.max(i,t.x),r=Math.max(r,t.y);const s=Math.max(i-n,r-o)||1,a=(n+i)/2,c=(o+r)/2,l={x:a-30*s,y:c-s,i:-1},d={x:a,y:c+30*s,i:-2},h={x:a+30*s,y:c-s,i:-3};let u=[{a:l,b:d,c:h,cc:VV({a:l,b:d,c:h})}];for(const t of e){const e=u.filter(e=>{const n=t.x-e.cc.x,o=t.y-e.cc.y;return n*n+o*o<e.cc.r2+1e-6}),n=new Set(e),o=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[i,r]of n){let n=!1;for(const o of e)if(o!==t&&WV(o,i,r)){n=!0;break}n||o.push([i,r])}}u=u.filter(t=>!n.has(t));for(const[e,n]of o)u.push({a:e,b:n,c:t,cc:VV({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])})(a);if(void 0!==t.layerCount){const d=KV({triangles:o,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s,layerCount:t.layerCount});c=d.triangles,l=d.triangleAvailableZ}else c=QV({triangles:o,pts:a,bounds:e,vias:i,clearance:n,rects:r,polygons:s})}const{cells:d,depths:h,availableZ:u}=!1!==t.usePolyanyaMerge?(t=>{const{triangles:e,pts:n,cellAvailableZ:o,layerMergeMode:i="same"}=t;if(!e.length)return{cells:[],depths:[]};const r=e.length,s=e.map(([t,e,o])=>{const i=n[t],r=n[e],s=n[o];return i&&r&&s&&tV({o:i,a:r,b:s})<0?[t,o,e]:[t,e,o]}),a=o?.map(iV),c=new Array(r).fill(null);for(let t=0;t<r;t++)c[t]=new Map;function l(){for(let t=0;t<c.length;t++)c[t]&&c[t].clear();const t=new Map;for(let e=0;e<s.length;e++){const n=s[e];if(n)for(let o=0;o<n.length;o++){const i=n[o],r=n[(o+1)%n.length],s=YV(i,r),a=t.get(s);a?(c[e].set(o,{neighbor:a.cellIdx,neighborEdge:a.edgePos}),c[a.cellIdx].set(a.edgePos,{neighbor:e,neighborEdge:o})):t.set(s,{cellIdx:e,edgePos:o})}}}function d(t){let e=0;for(let o=0;o<t.length;o++){const i=n[t[o]],r=n[t[(o+1)%t.length]];e+=i.x*r.y-r.x*i.y}return Math.abs(e)/2}function h(t,e){const n=s[t],o=c[t],i=n.length;let r=-1;for(const[t,n]of o)if(n.neighbor===e){r=t;break}if(-1===r)return null;let a=r;for(;;){const t=(a-1+i)%i;if(t===r)break;const n=o.get(t);if(!n||n.neighbor!==e)break;a=t}let l=r;for(;;){const t=(l+1)%i;if(t===a)break;const n=o.get(t);if(!n||n.neighbor!==e)break;l=t}return{firstK:a,lastK:l,sharedCount:(l-a+i)%i+1}}function u(t,e){const o=s[t],r=s[e],c=h(t,e);if(!c)return!1;const{firstK:l,lastK:d,sharedCount:u}=c,p=o.length,m=r.length,g=o[l],f=o[(d+1)%p];let y=-1;for(let t=0;t<m;t++)if(r[t]===g){y=t;break}if(-1===y)return!1;const _=(y-u+m)%m;if(r[_]!==f)return!1;const b=n[o[(l-1+p)%p]],x=n[g],v=n[r[(y+1)%m]];if(tV({o:b,a:x,b:v})<-1e-8)return!1;const S=n[r[(_-1+m)%m]],I=n[f],C=n[o[(d+2)%p]];if(tV({o:S,a:I,b:C})<-1e-8)return!1;if(a){if(0===(a[t]&a[e]))return!1;if("same"===i&&a[t]!==a[e])return!1}return!0}function p(t,e){const n=s[t],o=s[e],i=h(t,e),{firstK:r,lastK:c,sharedCount:l}=i,d=n.length,u=o.length,p=n[r],m=n[(c+1)%d];let g=-1;for(let t=0;t<u;t++)if(o[t]===p){g=t;break}const f=[];f.push(p);const y=u-l-1;for(let t=1;t<=y;t++)f.push(o[(g+t)%u]);f.push(m);const _=d-l-1;for(let t=2;t<=_+1;t++)f.push(n[(c+t)%d]);s[t]=f,s[e]=null,a&&(a[t]=a[t]&a[e],a[e]=0)}l();let m=!0;for(;m;){m=!1,l();for(let t=0;t<s.length;t++){if(!s[t])continue;const e=c[t],n=new Set;for(const[,t]of e)s[t.neighbor]&&n.add(t.neighbor);if(1===n.size){const e=n.values().next().value;u(t,e)&&(p(t,e),m=!0)}}}l();const g=new Array(s.length).fill(0);for(let t=0;t<s.length;t++)s[t]&&(g[t]=d(s[t]));const f=[];function y(t){f.push(t);let e=f.length-1;for(;e>0;){const t=e-1>>1;if(f[t].area>=f[e].area)break;const n=f[t];f[t]=f[e],f[e]=n,e=t}}function _(){if(0===f.length)return;const t=f[0],e=f.pop();if(f.length>0){f[0]=e;let t=0;for(;;){let e=t;const n=2*t+1,o=2*t+2;if(n<f.length&&f[n].area>f[e].area&&(e=n),o<f.length&&f[o].area>f[e].area&&(e=o),e===t)break;const i=f[t];f[t]=f[e],f[e]=i,t=e}}return t}const b=new Set;for(let t=0;t<s.length;t++){if(!s[t])continue;const e=c[t],n=new Set;for(const[,t]of e)s[t.neighbor]&&n.add(t.neighbor);for(const e of n){const n=t<e?1e5*t+e:1e5*e+t;b.has(n)||(b.add(n),u(t,e)&&y({area:g[t]+g[e],xIdx:t,yIdx:e}))}}for(;f.length>0;){const t=_(),{xIdx:e,yIdx:n}=t;if(!s[e]||!s[n])continue;const o=g[e]+g[n];if(Math.abs(o-t.area)>1e-10){u(e,n)&&y({area:o,xIdx:e,yIdx:n});continue}if(!u(e,n))continue;p(e,n),g[e]=d(s[e]),l();const i=c[e],r=new Set;for(const[,t]of i)s[t.neighbor]&&r.add(t.neighbor);for(const t of r)u(e,t)&&y({area:g[e]+g[t],xIdx:e,yIdx:t})}const x=s.filter(t=>null!==t),v=a?s.flatMap((t,e)=>null===t?[]:[oV(a[e])]):void 0,S=x.map(()=>0);return{cells:x,depths:S,...v?{availableZ:v}:{}}})({triangles:c,pts:a,cellAvailableZ:l,layerMergeMode:t.layerMergeMode}):(t=>{const{triangles:e,pts:n,concavityTolerance:o,cellAvailableZ:i,layerMergeMode:r="same"}=t;if(!e.length)return{cells:[],depths:[]};const s=e.map(([t,e,o])=>{const i=n[t],r=n[e],s=n[o];return i&&r&&s&&tV({o:i,a:r,b:s})<0?[t,o,e]:[t,e,o]}),a=i?.map(iV),c=(t,e)=>{if(!a)return;const n=a[t]&a[e];return 0===n||"same"===r&&a[t]!==a[e]?0:n};let l=!0,d=0;for(;l&&d++<800;){l=!1;const t=new Map,e=s.map(()=>new Set);for(let n=0;n<s.length;n++){const o=s[n];if(o)for(let i=0;i<o.length;i++){const r=o[i],s=o[(i+1)%o.length];if(void 0===r||void 0===s)continue;const a=$V(r,s);if(t.has(a)){const o=t.get(a);void 0!==o&&(e[n]?.add(o),e[o]?.add(n))}else t.set(a,n)}}let i=-1,r=-1,d=null,h=Number.POSITIVE_INFINITY;for(let t=0;t<s.length;t++){const a=e[t];if(a)for(const e of a){if(e<=t)continue;const a=jV(s[t]??[],s[e]??[]);if(!a)continue;if(0===c(t,e))continue;const l=FV(a,n);l<=o+1e-6&&l<h&&(h=l,i=t,r=e,d=a)}}if(i<0||r<0||!d)break;s[i]=d,a&&(a[i]=c(i,r),a.splice(r,1)),s.splice(r,1),l=!0}const h=s.map(t=>FV(t,n));return{cells:s,depths:h,...a?{availableZ:a.map(t=>oV(t))}:{}}})({triangles:c,pts:a,concavityTolerance:o,cellAvailableZ:l,layerMergeMode:t.layerMergeMode}),p=a.map(t=>((t,e)=>({x:Math.min(e.maxX,Math.max(e.minX,t.x)),y:Math.min(e.maxY,Math.max(e.minY,t.y))}))(t,e)),m=d.map(t=>t.map(t=>p[t]).filter(tW)),g=d.map(t=>eV(t,p).map(t=>p[t]).filter(tW));return{pts:p,validTris:c,regions:m,hulls:g,depths:h,...u?{availableZ:u}:{}}},nW=t=>{const e=[...new Set(t.filter(t=>"number"==typeof t&&Number.isInteger(t)&&t>=0))].sort((t,e)=>t-e);if(0!==e.length)return`z${e.join(",")}`},oW=t=>{const e=[];for(let n=0;n<31;n++)t&1<<n&&e.push(n);return e},iW=t=>"object"==typeof t&&null!==t,rW=t=>iW(t)?{...t}:void 0===t?{}:{value:t},sW=(t,e)=>{const n=t.topology.regionMetadata?.[e];if(iW(n)){if("string"==typeof n.serializedRegionId)return n.serializedRegionId;if("string"==typeof n.regionId)return n.regionId;if("string"==typeof n.capacityMeshNodeId)return n.capacityMeshNodeId}return`region-${e}`},aW=(t,e)=>{const n=t.topology.portMetadata?.[e];if(iW(n)){if("string"==typeof n.serializedPortId)return n.serializedPortId;if("string"==typeof n.portId)return(o=n.portId).includes("::")?o.slice(0,o.indexOf("::")):o}var o;return`port-${e}`},cW=(t,e)=>{const n=rW(t.topology.regionMetadata?.[e]);if(iW(n.center)||(n.center={x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),"number"!=typeof n.width&&(n.width=t.topology.regionWidth[e]),"number"!=typeof n.height&&(n.height=t.topology.regionHeight[e]),!Array.isArray(n.availableZ)){const o=t.topology.regionAvailableZMask?.[e]??0;0!==o&&(n.availableZ=oW(o))}return n.layer=nW(Array.isArray(n.availableZ)?n.availableZ:[])??nW((t.topology.regionIncidentPorts[e]??[]).map(e=>t.topology.portZ[e]))??"z0",n},lW=(t,e)=>{const n=rW(t.topology.portMetadata?.[e]);return"number"!=typeof n.x&&(n.x=t.topology.portX[e]),"number"!=typeof n.y&&(n.y=t.topology.portY[e]),"number"!=typeof n.z&&(n.z=t.topology.portZ[e]),n.layer=nW([t.topology.portZ[e]])??"z0",n},dW=(t,e,n)=>{const o=(t.topology.incidentPortRegion[e]??[]).find(t=>t!==n);if(void 0===o)throw new Error(`Port ${e} is not incident to a region outside route region ${n}`);return o},hW=(t,e,n)=>{const{orderedPortIds:o,orderedRegionIds:i}=((t,e,n)=>{if(0===n.length)throw new Error(`Route ${e} has no solved segments`);const o=t.problem.routeStartPort[e],i=t.problem.routeEndPort[e],r=new Map;n.forEach((t,e)=>{const n={...t,segmentIndex:e},o=r.get(t.fromPortId)??[];o.push(n),r.set(t.fromPortId,o);const i=r.get(t.toPortId)??[];i.push(n),r.set(t.toPortId,i)});const s=[o],a=[],c=new Set;let l,d=o;for(;d!==i;){const t=(r.get(d)??[]).filter(t=>!c.has(t.segmentIndex)&&(t.fromPortId===d?t.toPortId:t.fromPortId)!==l);if(1!==t.length)throw new Error(`Route ${e} is not a single ordered path from ${o} to ${i}`);const n=t[0],h=n.fromPortId===d?n.toPortId:n.fromPortId;c.add(n.segmentIndex),a.push(n.regionId),s.push(h),l=d,d=h}if(c.size!==n.length)throw new Error(`Route ${e} contains disconnected solved segments`);return{orderedPortIds:s,orderedRegionIds:a}})(t,e,n),r=i[0],s=i[i.length-1];if(void 0===r||void 0===s)throw new Error(`Route ${e} could not determine endpoint regions`);const a=sW(t,dW(t,o[0],r)),c=sW(t,dW(t,o[o.length-1],s)),l=((t,e,n,o)=>{const i=t.problem.routeMetadata?.[e];return{connectionId:(iW(i)&&"string"==typeof i.connectionId?i.connectionId:void 0)??`route-${e}`,startRegionId:(iW(i)&&"string"==typeof i.startRegionId?i.startRegionId:void 0)??n,endRegionId:(iW(i)&&"string"==typeof i.endRegionId?i.endRegionId:void 0)??o,mutuallyConnectedNetworkId:(iW(i)&&"string"==typeof i.mutuallyConnectedNetworkId?i.mutuallyConnectedNetworkId:void 0)??`net-${t.problem.routeNet[e]}`}})(t,e,a,c),d=o.map((e,n)=>{const r={portId:aW(t,e),g:n,h:0,f:n,hops:n,ripRequired:!1,nextRegionId:n<i.length?sW(t,i[n]):l.endRegionId};return n>0&&(r.lastPortId=aW(t,o[n-1]),r.lastRegionId=sW(t,i[n-1])),r});return{connection:l,solvedRoute:{connection:l,path:d,requiredRip:!1}}},uW=t=>{if(!t.solved||t.failed)throw new Error("convertToSerializedHyperGraph requires a solved, non-failed solver");const{topology:e}=t,n=(t=>{const e=Array.from({length:t.problem.routeCount},()=>[]);return t.state.regionSegments.forEach((t,n)=>{for(const[o,i,r]of t)e[o].push({regionId:n,fromPortId:i,toPortId:r})}),e})(t),o=Array.from({length:e.regionCount},(n,o)=>({regionId:sW(t,o),pointIds:e.regionIncidentPorts[o].map(e=>aW(t,e)),d:cW(t,o)})),i=Array.from({length:e.portCount},(n,o)=>{const[i,r]=e.incidentPortRegion[o]??[];if(void 0===i||void 0===r)throw new Error(`Port ${o} is missing incident regions`);return{portId:aW(t,o),region1Id:sW(t,i),region2Id:sW(t,r),d:lW(t,o)}}),r=n.map((e,n)=>hW(t,n,e));return{regions:o,ports:i,connections:r.map(({connection:t})=>t),solvedRoutes:r.map(({solvedRoute:t})=>t)}},pW=t=>t>0&&!(t&t-1),mW=(t,e,n,o,i,r=0)=>.2025*(2*e+1*n+1*o)*(1+i/5)/t+(pW(r)?10*e:0),gW=(t,e,n,o,i,r)=>{const{netIds:s,lesserAngles:a,greaterAngles:c,layerMasks:l}=t;let d=0,h=0;for(let t=0;t<s.length;t++){if(e===s[t])continue;(n<a[t]&&a[t]<o)!==(n<c[t]&&c[t]<o)&&(0!==(i&l[t])?d++:h++)}return[d,h,r]},fW=class{constructor(t,e){this.items=t,this.compare=e}items;compare;get length(){return this.items.length}toArray(){return[...this.items]}clear(){this.items.length=0}queue(t){this.items.push(t),this.siftUp(this.items.length-1)}dequeue(){const t=this.items[0];if(void 0===t)return;const e=this.items.pop();return this.items.length>0&&(this.items[0]=e,this.siftDown(0)),t}siftUp(t){let e=t;for(;e>0;){const t=e-1>>1,n=this.items[t],o=this.items[e];if(this.compare(n,o)<=0)return;this.items[t]=o,this.items[e]=n,e=t}}siftDown(t){let e=t;const n=this.items.length;for(;;){const t=2*e+1;if(t>=n)return;const o=t+1;let i=t;o<n&&this.compare(this.items[o],this.items[t])<0&&(i=o);const r=this.items[e],s=this.items[i];if(this.compare(r,s)<=0)return;this.items[e]=s,this.items[i]=r,e=i}}},yW=(t,e)=>{const n=[...t],o=(t=>{let e=t>>>0;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}})(e);for(let t=n.length-1;t>0;t--){const e=Math.floor(o()*(t+1));[n[t],n[e]]=[n[e],n[t]]}return n},_W=(t,e)=>t.routeMetadata?.[e],bW=t=>t?.simpleRouteConnection?.pointsToConnect?.map(({pointId:t})=>"string"==typeof t?t:null).filter(t=>null!==t)??[],xW=(t,e)=>{const n=_W(t,e)?.connectionId;return"string"==typeof n?n:`route-${e}`},vW=(t,e,n)=>{const o=t.portEndpointNetIds[n];if(!o)return!1;for(const t of o)if(t!==e)return!0;return!1},SW=(t,e,n)=>{const o=t.regionNetId[n];return-1!==o&&o!==e},IW=t=>[...new Set(t.routeIds)].filter(e=>!((t,e)=>{const{topology:n,problem:o,problemSetup:i,portAssignment:r,maxPrecheckHops:s}=t,a=o.routeNet[e],c=o.routeStartPort[e],l=o.routeEndPort[e];if(c===l)return!0;const d=t.getStartingNextRegionId(e,c);if(void 0===d)return!1;const h=[{portId:c,nextRegionId:d}],u=new Set([c*n.regionCount+d]);for(let t=0;t<h.length;t++){const e=h[t];if(!SW(o,a,e.nextRegionId))for(const t of n.regionIncidentPorts[e.nextRegionId]??[]){const c=r[t];if(vW(i,a,t))continue;if(t===l){if(-1!==c&&c!==a)continue;return!0}if(t===e.portId)continue;if(-1!==c&&c!==a)continue;if(0===o.portSectionMask[t])continue;const d=n.incidentPortRegion[t]??[],p=d[0]===e.nextRegionId?d[1]:d[0];if(void 0===p||SW(o,a,p))continue;const m=t*n.regionCount+p;if(!u.has(m)){if(u.size>=s)return!0;u.add(m),h.push({portId:t,nextRegionId:p})}}}return!1})(t,e)).map(e=>t.getRouteSummary(e)),CW=t=>{const e=new Array(t);for(let n=0;n<t;n++)e[n]=n;return e},PW=.05,MW={r:255,g:64,b:64,a:.72},NW="rgba(220, 38, 38, 0.98)",wW="rgba(220, 38, 38, 0.12)",TW="10 6",RW=(...t)=>t.filter(t=>Boolean(t)).join("\n"),EW=t=>Math.min(1,Math.max(0,t)),AW=(t,e,n)=>Math.round(t+(e-t)*n),OW=({r:t,g:e,b:n,a:o})=>`rgba(${t}, ${e}, ${n}, ${o})`,kW=(t,e)=>{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},LW=t=>"number"==typeof t.centerRouteId,DW=(t,e)=>LW(t)?e===t.centerRouteId?1:.5:1,zW=(t,e)=>{const n=t.match(/^(rgba|hsla)\((.*),\s*([0-9]*\.?[0-9]+)\)$/);if(!n)return t;const[,o,i,r]=n,s=EW(Number(r)*e);return`${o}(${i}, ${Number(s.toFixed(3))})`},FW=(t,e,n=.8)=>((t,e,n=.8)=>{const o=`${t.problem.routeNet[e]}:${kW(t,e)}`;let i=0;for(let t=0;t<o.length;t++)i=17777*o.charCodeAt(t)+((i<<5)-i);return`hsla(${Math.abs(i)%360}, 70%, 50%, ${n})`})(t,e,n*DW(t,e)),BW=(t,e)=>`net: ${t.problem.routeNet[e]}`,jW=(t,e)=>{const n=t.topology.regionMetadata?.[e],o=n?.polygon;if(Array.isArray(o)&&o.length>=3){const t=o.map(t=>t.x),e=o.map(t=>t.y);return{minX:Math.min(...t),maxX:Math.max(...t),minY:Math.min(...e),maxY:Math.max(...e)}}const i=n?.bounds;if(i&&"number"==typeof i.minX&&"number"==typeof i.maxX&&"number"==typeof i.minY&&"number"==typeof i.maxY)return i;const r=t.topology.regionWidth[e],s=t.topology.regionHeight[e],a=t.topology.regionCenterX[e],c=t.topology.regionCenterY[e];return{minX:a-r/2,maxX:a+r/2,minY:c-s/2,maxY:c+s/2}},$W=(t,e)=>({x:t.topology.regionCenterX[e],y:t.topology.regionCenterY[e]}),YW=(t,e)=>{const n=t.topology.regionMetadata?.[e],o=Array.isArray(n?.availableZ)?n.availableZ.filter(t=>"number"==typeof t&&Number.isInteger(t)&&t>=0):[];if(o.length>0)return nW(o)??"z0";const i=oW(t.topology.regionAvailableZMask?.[e]??0);if(i.length>0)return nW(i)??"z0";const r=[...new Set((t.topology.regionIncidentPorts[e]??[]).map(e=>t.topology.portZ[e]))].sort((t,e)=>t-e);return nW(r)??"z0"},XW=(t,e)=>{const n=t.state.regionIntersectionCaches[e],o=n?.existingRegionCost??0,i=t.state.regionCongestionCost[e]??0,r=t.problem.regionNetId[e];return RW(`region: region-${e}`,`net: ${-1===r?"free":`${r}`}`,t.getAdditionalRegionLabel(e),`cost: ${o.toFixed(3)}`,`congestion: ${i.toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},VW=(t,e)=>{const n=t.topology.regionMetadata?.[e];return n?.isConnectionRegion?{r:255,g:100,b:255,a:.6}:n?.isThroughJumper?{r:100,g:200,b:100,a:.5}:n?.isPad?{r:255,g:200,b:100,a:.5}:"bottom"===n?.layer?{r:52,g:152,b:219,a:.08}:{r:200,g:200,b:255,a:.1}},WW=(t,e)=>{const n=VW(t,e),o=EW(t.state.regionIntersectionCaches[e]?.existingRegionCost??0),i=Math.pow(o,.8);return OW((s=MW,a=i,{r:AW((r=n).r,s.r,a),g:AW(r.g,s.g,a),b:AW(r.b,s.b,a),a:Number((r.a+(s.a-r.a)*a).toFixed(3))}));var r,s,a},HW=(t,e)=>({x:t.topology.portX[e],y:t.topology.portY[e]}),GW=HW,UW=HW,ZW=(t,e)=>nW([t.topology.portZ[e]])??"z0",qW=(t,e)=>{const n=t.topology.portMetadata?.[e];return`port: ${n?.serializedPortId??n?.portId??`port-${e}`}`},JW=(t,e,n)=>{if(void 0!==n)return`net: ${t.problem.routeNet[n]}`;const o=t.state.portAssignment[e];if(o>=0)return`net: ${o}`;const i=new Set;for(let n=0;n<t.problem.routeCount;n++)t.problem.routeStartPort[n]!==e&&t.problem.routeEndPort[n]!==e||i.add(t.problem.routeNet[n]);return 0!==i.size?`net: ${Array.from(i).sort((t,e)=>t-e).join(", ")}`:void 0},KW=(t,e)=>`z: ${t.topology.portZ[e]}`,QW=(t,e,n)=>RW(qW(t,e),((t,e)=>{const n=t.topology.incidentPortRegion[e]?.[0],o=t.topology.incidentPortRegion[e]?.[1];return`connects: region-${n??"?"} <-> region-${o??"?"}`})(t,e),JW(t,e,n)),tH=(t,e,n,o)=>{const i=t.topology.portZ[n],r=t.topology.portZ[o];return i>0&&r>0?{strokeColor:zW("rgba(52, 152, 219, 0.95)",DW(t,e)),strokeDash:"3 2"}:i!==r?{strokeColor:zW("rgba(22, 160, 133, 0.95)",DW(t,e)),strokeDash:"2 4 2"}:{strokeColor:FW(t,e)}},eH=(t,e)=>{for(let n=0;n<t.problem.routeCount;n++)if(t.problem.routeStartPort[n]===e||t.problem.routeEndPort[n]===e)return!0;return!1},nH=(t,e,n)=>{const o=((t,e)=>{const n=new Set;for(let o=0;o<e.length;o++)if(1===e[o])for(const e of t.topology.incidentPortRegion[o]??[])n.add(e);return n})(t,n),i="rgba(245, 158, 11, 0.95)",r="rgba(245, 158, 11, 0.08)";for(const n of o){const o=t.topology.regionMetadata?.[n],s=o?.polygon,a=jW(t,n),c=$W(t,n),l=a.maxX-a.minX,d=a.maxY-a.minY,h=YW(t,n),u=RW("section region",XW(t,n));Array.isArray(s)&&s.length>=3?e.polygons.push({points:s,fill:r,stroke:i,strokeWidth:2,layer:h,label:u}):e.rects.push({center:c,width:Math.max(l-PW,.05),height:Math.max(d-PW,.05),fill:r,stroke:i,layer:h,label:u})}for(let o=0;o<n.length;o++)1===n[o]&&e.circles.push({center:UW(t,o),radius:.07,fill:"rgba(251, 191, 36, 0.18)",stroke:i,layer:ZW(t,o),label:RW(QW(t,o),KW(t,o),"section port")})},oH=(t,e={})=>{const n={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:"Tiny HyperGraph",coordinateSystem:"cartesian"},o=((t,e)=>{if(!e?.highlightSectionMask)return;const n=e.sectionPortMask??t.problem.portSectionMask;if(n.length!==t.topology.portCount)return;let o=0,i=0;for(let t=0;t<n.length;t++)1===n[t]?o+=1:i+=1;return 0!==o&&0!==i?n:void 0})(t,e);for(let e=0;e<t.topology.regionCount;e++){const o=t.topology.regionMetadata?.[e],i=o?.polygon,r=jW(t,e),s=$W(t,e),a=r.maxX-r.minX,c=r.maxY-r.minY,l=YW(t,e),d=OW(VW(t,e));Array.isArray(i)&&i.length>=3?n.polygons.push({points:i,fill:d,layer:l}):n.rects.push({center:s,width:Math.max(a-PW,.05),height:Math.max(c-PW,.05),fill:WW(t,e),layer:l,label:XW(t,e)})}if(((t,e)=>{for(let n=0;n<t.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a=FW(t,n),c=kW(t,n),l=BW(t,n);e.points.push({x:r.x,y:r.y,color:a,layer:ZW(t,o),label:RW(`route: ${c}`,l,"endpoint: start",qW(t,o),KW(t,o))}),e.points.push({x:s.x,y:s.y,color:a,layer:ZW(t,i),label:RW(`route: ${c}`,l,"endpoint: end",qW(t,i),KW(t,i))})}})(t,n),0===t.iterations){for(const t of n.polygons)t.stroke="rgba(128, 128, 128, 0.5)";for(const t of n.rects)t.stroke="rgba(128, 128, 128, 0.5)"}if(0===t.iterations){for(let i=0;i<t.topology.portCount;i++){const r=1===o?.[i];e.showOnlySectionPortsOnIdle&&!r||n.circles.push({center:UW(t,i),radius:.05,fill:t.topology.portZ[i]>0?"rgba(52, 152, 219, 0.55)":"rgba(128, 128, 128, 0.5)",layer:ZW(t,i),label:RW(QW(t,i),KW(t,i))})}!1!==e.showInitialRouteHints&&((t,e)=>{for(let n=0;n<t.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a={x:(r.x+s.x)/2,y:(r.y+s.y)/2};e.lines.push({points:[r,s],strokeColor:FW(t,n),strokeDash:"3 3",label:kW(t,n)}),e.points.push({x:a.x,y:a.y,color:FW(t,n,1),label:kW(t,n)})}})(t,n)}else((t,e)=>{for(let n=0;n<t.state.regionSegments.length;n++){const o=t.state.regionSegments[n]??[];for(const[i,r,s]of o)e.lines.push({points:[GW(t,r),GW(t,s)],label:RW(`route: ${kW(t,i)}`,`region: region-${n}`),...tH(t,i,r,s)})}})(t,n),((t,e)=>{const n=new Set;for(let o=0;o<t.state.regionSegments.length;o++){const i=t.state.regionSegments[o]??[];for(const[o,r,s]of i)for(const i of[r,s]){const r=`${o}:${i}`;if(n.has(r))continue;n.add(r);const s=GW(t,i);e.points.push({x:s.x,y:s.y,color:FW(t,o,1),layer:ZW(t,i),label:RW(`route: ${kW(t,o)}`,qW(t,i),JW(t,i,o),KW(t,i))})}}})(t,n),(t=>LW(t)&&!0===t.showUnassignedPortsInVisualization)(t)&&((t,e)=>{for(let n=0;n<t.topology.portCount;n++)t.state.portAssignment[n]>=0||eH(t,n)||e.circles.push({center:UW(t,n),radius:.04,fill:t.topology.portZ[n]>0?"rgba(52, 152, 219, 0.2)":"rgba(128, 128, 128, 0.2)",stroke:t.topology.portZ[n]>0?"rgba(52, 152, 219, 0.6)":"rgba(128, 128, 128, 0.6)",layer:ZW(t,n),label:RW(QW(t,n),KW(t,n),"state: unassigned")})})(t,n),LW(t)||(((t,e)=>{const n=t.state.currentRouteId;if(void 0===n||t.solved)return;const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=GW(t,o),s=GW(t,i),a=FW(t,n),c=kW(t,n);e.lines.push({points:[r,s],strokeColor:a,strokeDash:"10 5",label:c})})(t,n),((t,e)=>{if(t.solved)return;const n=t.state.currentRouteId,o=t.state.candidateQueue.toArray().sort((t,e)=>t.f-e.f).slice(0,10);for(let i=0;i<o.length;i++){const r=o[i],s=GW(t,r.portId),a=0===i;e.points.push({x:s.x,y:s.y,color:a?"green":"rgba(128, 128, 128, 0.25)",layer:ZW(t,r.portId),label:RW(QW(t,r.portId,n),KW(t,r.portId),`g: ${r.g.toFixed(2)}`,`h: ${r.h.toFixed(2)}`,`f: ${r.f.toFixed(2)}`)})}const i=o[0];if(!i)return;const r=[];let s=i;for(;s;)r.unshift(GW(t,s.portId)),s=s.prevCandidate;r.length>1&&e.lines.push({points:r,strokeColor:void 0!==n?FW(t,n):"rgba(0, 160, 120, 0.9)"})})(t,n));o&&nH(t,n,o),((t,e)=>{if(t.failed)for(const n of t.getNeverSuccessfullyRoutedRoutes()){const{routeId:o,connectionId:i,attempts:r,startPortId:s,endPortId:a}=n,c=BW(t,o),l=UW(t,s),d=UW(t,a),h=RW(`never routed: ${i}`,`attempts: ${r}`,c,n.startRegionId?`startRegionId: ${n.startRegionId}`:void 0,n.endRegionId?`endRegionId: ${n.endRegionId}`:void 0);e.lines.push({points:[{x:0,y:0},{x:l.x,y:l.y}],strokeColor:NW,strokeDash:TW,layer:ZW(t,s),label:RW(h,"origin guide","endpoint: start")}),e.circles.push({center:l,radius:1,fill:wW,stroke:NW,layer:ZW(t,s),label:RW(h,"endpoint: start",qW(t,s),KW(t,s))}),e.lines.push({points:[{x:0,y:0},{x:d.x,y:d.y}],strokeColor:NW,strokeDash:TW,layer:ZW(t,a),label:RW(h,"origin guide","endpoint: end")}),e.circles.push({center:d,radius:1,fill:wW,stroke:NW,layer:ZW(t,a),label:RW(h,"endpoint: end",qW(t,a),KW(t,a))})}})(t,n);const i=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1),r=o?o.reduce((t,e)=>t+Number(1===e),0):0;return n.title=["Tiny HyperGraph",`iter=${t.iterations}`,`pending=${i}`,o?`sectionPorts=${r}`:void 0,t.failed?"failed":t.solved?"solved":"running"].filter(Boolean).join(" | "),n},iH=()=>({netIds:new Int32Array(0),lesserAngles:new Int32Array(0),greaterAngles:new Int32Array(0),layerMasks:new Int32Array(0),existingCrossingLayerIntersections:0,existingSameLayerIntersections:0,existingEntryExitLayerChanges:0,existingRegionCost:0,existingSegmentCount:0}),rH=(t,e)=>t.f-e.f,sH=class extends kt{constructor(t,e,n){super(),this.topology=t,this.problem=e,((t,e)=>{e&&(void 0!==e.DISTANCE_TO_COST&&(t.DISTANCE_TO_COST=e.DISTANCE_TO_COST),void 0!==e.RIP_THRESHOLD_START&&(t.RIP_THRESHOLD_START=e.RIP_THRESHOLD_START),void 0!==e.RIP_THRESHOLD_END&&(t.RIP_THRESHOLD_END=e.RIP_THRESHOLD_END),void 0!==e.RIP_THRESHOLD_RAMP_ATTEMPTS&&(t.RIP_THRESHOLD_RAMP_ATTEMPTS=e.RIP_THRESHOLD_RAMP_ATTEMPTS),void 0!==e.RIP_CONGESTION_REGION_COST_FACTOR&&(t.RIP_CONGESTION_REGION_COST_FACTOR=e.RIP_CONGESTION_REGION_COST_FACTOR),void 0!==e.MAX_ITERATIONS&&(t.MAX_ITERATIONS=e.MAX_ITERATIONS),void 0!==e.VERBOSE&&(t.VERBOSE=e.VERBOSE),void 0!==e.STATIC_REACHABILITY_PRECHECK&&(t.STATIC_REACHABILITY_PRECHECK=e.STATIC_REACHABILITY_PRECHECK),void 0!==e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS&&(t.STATIC_REACHABILITY_PRECHECK_MAX_HOPS=e.STATIC_REACHABILITY_PRECHECK_MAX_HOPS))})(this,n),this.state={portAssignment:new Int32Array(t.portCount).fill(-1),regionSegments:Array.from({length:t.regionCount},()=>[]),regionIntersectionCaches:Array.from({length:t.regionCount},()=>iH()),currentRouteId:void 0,currentRouteNetId:void 0,unroutedRoutes:CW(e.routeCount),candidateQueue:new fW([],rH),candidateBestCostByHopId:new Float64Array(t.portCount*t.regionCount),candidateBestCostGenerationByHopId:new Uint32Array(t.portCount*t.regionCount),candidateBestCostGeneration:1,goalPortId:-1,ripCount:0,regionCongestionCost:new Float64Array(t.regionCount).fill(0)},this.routeAttemptCountByRouteId=new Uint32Array(e.routeCount),this.routeSuccessCountByRouteId=new Uint32Array(e.routeCount)}topology;problem;state;_problemSetup;routeAttemptCountByRouteId;routeSuccessCountByRouteId;hasLoggedNeverSuccessfullyRoutedRoutes=!1;segmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};DISTANCE_TO_COST=.05;RIP_THRESHOLD_START=.05;RIP_THRESHOLD_END=.8;RIP_THRESHOLD_RAMP_ATTEMPTS=50;RIP_CONGESTION_REGION_COST_FACTOR=.1;MAX_ITERATIONS=1e6;VERBOSE=!1;STATIC_REACHABILITY_PRECHECK=!0;STATIC_REACHABILITY_PRECHECK_MAX_HOPS=16;get problemSetup(){return this._problemSetup||(this._problemSetup=this.computeProblemSetup()),this._problemSetup}computeProblemSetup(){const{topology:t,problem:e}=this,n=t.portX,o=t.portY,i=new Float64Array(t.portCount*e.routeCount),r=Array.from({length:t.portCount},()=>new Set);for(let s=0;s<e.routeCount;s++){r[e.routeStartPort[s]].add(e.routeNet[s]),r[e.routeEndPort[s]].add(e.routeNet[s]);const a=e.routeEndPort[s],c=n[a],l=o[a];for(let r=0;r<t.portCount;r++){const t=n[r]-c,a=o[r]-l;i[r*e.routeCount+s]=Math.hypot(t,a)*this.DISTANCE_TO_COST}}return{portHCostToEndOfRoute:i,portEndpointNetIds:r}}_setup(){if(this.problemSetup,this.STATIC_REACHABILITY_PRECHECK){const t=IW({topology:this.topology,problem:this.problem,problemSetup:this.problemSetup,portAssignment:this.state.portAssignment,routeIds:this.state.unroutedRoutes,maxPrecheckHops:Math.max(0,this.STATIC_REACHABILITY_PRECHECK_MAX_HOPS),getStartingNextRegionId:(t,e)=>this.getStartingNextRegionId(t,e),getRouteSummary:t=>this.getRouteSummary(t)});t.length>0&&(this.failed=!0,this.error=(t=>{const e=t.slice(0,5).map(t=>{const e=t.pointIds.length>=2?`${t.pointIds[0]}->${t.pointIds[1]}`:`${t.startPortId}->${t.endPortId}`;return`${t.connectionId} (${e})`}).join(", "),n=t.length-5;return["Static reachability precheck failed:",`${t.length} route(s) have no legal path under the current reservation and start-region rules`,n>0?`${e}, +${n} more`:e].join(" ")})(t),this.stats={...this.stats,staticallyUnroutableRouteCount:t.length})}}_step(){const{problem:t,topology:e,state:n}=this;if(void 0===n.currentRouteId){if(0===n.unroutedRoutes.length)return void this.onAllRoutesRouted();n.currentRouteId=n.unroutedRoutes.shift(),n.currentRouteNetId=t.routeNet[n.currentRouteId],this.routeAttemptCountByRouteId[n.currentRouteId]+=1,this.resetCandidateBestCosts();const e=t.routeStartPort[n.currentRouteId];n.candidateQueue.clear();const o=this.getStartingNextRegionId(n.currentRouteId,e);if(void 0===o)return this.failed=!0,void(this.error=`Start port ${e} has no incident regions`);this.setCandidateBestCost(this.getHopId(e,o),0),n.candidateQueue.queue({nextRegionId:o,portId:e,f:0,g:0,h:0}),n.goalPortId=t.routeEndPort[n.currentRouteId]}const o=n.candidateQueue.dequeue();if(!o)return void this.onOutOfCandidates();const i=this.getHopId(o.portId,o.nextRegionId);if(o.g>this.getCandidateBestCost(i))return;if(this.isRegionReservedForDifferentNet(o.nextRegionId))return;const r=e.regionIncidentPorts[o.nextRegionId];for(const i of r){const r=n.portAssignment[i];if(this.isPortReservedForDifferentNet(i))continue;if(i===n.goalPortId){if(-1!==r&&r!==n.currentRouteNetId)continue;return void this.onPathFound(o)}if(-1!==r&&r!==n.currentRouteNetId)continue;if(i===o.portId)continue;if(0===t.portSectionMask[i])continue;const s=this.computeG(o,i);if(!Number.isFinite(s))continue;const a=this.computeH(i),c=e.incidentPortRegion[i][0]===o.nextRegionId?e.incidentPortRegion[i][1]:e.incidentPortRegion[i][0];if(void 0===c||this.isRegionReservedForDifferentNet(c))continue;const l={prevRegionId:o.nextRegionId,nextRegionId:c,portId:i,g:s,h:a,f:s+a,prevCandidate:o};if(i===n.goalPortId)return void this.onPathFound(l);const d=this.getHopId(i,c);s>=this.getCandidateBestCost(d)||(this.setCandidateBestCost(d,s),n.candidateQueue.queue(l))}}resetCandidateBestCosts(){const{state:t}=this;if(4294967295===t.candidateBestCostGeneration)return t.candidateBestCostGenerationByHopId.fill(0),void(t.candidateBestCostGeneration=1);t.candidateBestCostGeneration+=1}getCandidateBestCost(t){const{state:e}=this;return e.candidateBestCostGenerationByHopId[t]===e.candidateBestCostGeneration?e.candidateBestCostByHopId[t]:Number.POSITIVE_INFINITY}setCandidateBestCost(t,e){const{state:n}=this;n.candidateBestCostGenerationByHopId[t]=n.candidateBestCostGeneration,n.candidateBestCostByHopId[t]=e}getHopId(t,e){return t*this.topology.regionCount+e}getStartingNextRegionId(t,e){const n=this.topology.incidentPortRegion[e]??[],o=this.problem.routeNet[t];return n.find(t=>-1===this.problem.regionNetId[t])??n.find(t=>this.problem.regionNetId[t]===o)??n[0]}isPortReservedForDifferentNet(t){const e=this.problemSetup.portEndpointNetIds[t];if(!e)return!1;for(const t of e)if(t!==this.state.currentRouteNetId)return!0;return!1}isRegionReservedForDifferentNet(t){const e=this.problem.regionNetId[t];return-1!==e&&e!==this.state.currentRouteNetId}isKnownSingleLayerRegion(t){const e=this.topology.regionAvailableZMask?.[t]??0;return pW(e)}computeRegionCostForRegion(t,e,n,o,i){return((t,e,n,o,i,r,s=0)=>mW(t*e,n,o,i,r,s))(this.topology.regionWidth[t],this.topology.regionHeight[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0)}populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.segmentGeometryScratch,r=o.incidentPortRegion[e],s=o.incidentPortRegion[n],a=r[0]===t||r[1]!==t?o.portAngleForRegion1[e]:o.portAngleForRegion2?.[e]??o.portAngleForRegion1[e],c=s[0]===t||s[1]!==t?o.portAngleForRegion1[n]:o.portAngleForRegion2?.[n]??o.portAngleForRegion1[n],l=o.portZ[e],d=o.portZ[n];return i.lesserAngle=a<c?a:c,i.greaterAngle=a<c?c:a,i.layerMask=1<<l|1<<d,i.entryExitLayerChanges=l!==d?1:0,i}appendSegmentToRegionCache(t,e,n){const{topology:o,state:i}=this,r=i.regionIntersectionCaches[t],s=this.populateSegmentGeometryScratch(t,e,n),[a,c,l]=gW(r,i.currentRouteNetId,s.lesserAngle,s.greaterAngle,s.layerMask,s.entryExitLayerChanges),d=r.netIds.length+1,h=new Int32Array(d);h.set(r.netIds),h[d-1]=i.currentRouteNetId;const u=new Int32Array(d);u.set(r.lesserAngles),u[d-1]=s.lesserAngle;const p=new Int32Array(d);p.set(r.greaterAngles),p[d-1]=s.greaterAngle;const m=new Int32Array(d);m.set(r.layerMasks),m[d-1]=s.layerMask;const g=r.existingSameLayerIntersections+a,f=r.existingCrossingLayerIntersections+c,y=r.existingEntryExitLayerChanges+l,_=u.length;i.regionIntersectionCaches[t]={netIds:h,lesserAngles:u,greaterAngles:p,layerMasks:m,existingSameLayerIntersections:g,existingCrossingLayerIntersections:f,existingEntryExitLayerChanges:y,existingSegmentCount:_,existingRegionCost:this.computeRegionCostForRegion(t,g,f,y,_)}}getSolvedPathSegments(t){const{state:e}=this,n=[];let o=t;for(;o;)n.unshift(o),o=o.prevCandidate;const i=[];for(let t=1;t<n.length;t++)i.push({regionId:n[t-1].nextRegionId,fromPortId:n[t-1].portId,toPortId:n[t].portId});const r=n[n.length-1];return r&&r.portId!==e.goalPortId&&i.push({regionId:r.nextRegionId,fromPortId:r.portId,toPortId:e.goalPortId}),i}resetRoutingStateForRerip(){const{topology:t,problem:e,state:n}=this;n.portAssignment.fill(-1),n.regionSegments=Array.from({length:t.regionCount},()=>[]),n.regionIntersectionCaches=Array.from({length:t.regionCount},()=>iH()),n.currentRouteNetId=void 0,n.currentRouteId=void 0,n.unroutedRoutes=yW(CW(e.routeCount),n.ripCount),n.candidateQueue.clear(),this.resetCandidateBestCosts(),n.goalPortId=-1}getMaxRegionCost(){const{topology:t,state:e}=this;let n=0;for(let o=0;o<t.regionCount;o++){const t=e.regionIntersectionCaches[o]?.existingRegionCost??0;n=Math.max(n,t)}return n}getRouteMetadata(t){return this.problem.routeMetadata?.[t]}getRouteConnectionId(t){const e=this.getRouteMetadata(t)?.connectionId;return"string"==typeof e?e:`route-${t}`}getRouteSummary(t){return(({problem:t,routeId:e,getRouteMetadata:n,getRouteConnectionId:o})=>{const i=n?.(e)??_W(t,e);return{routeId:e,connectionId:o?.(e)??xW(t,e),startPortId:t.routeStartPort[e],endPortId:t.routeEndPort[e],startRegionId:"string"==typeof i?.startRegionId?i.startRegionId:void 0,endRegionId:"string"==typeof i?.endRegionId?i.endRegionId:void 0,pointIds:bW(i)}})({problem:this.problem,routeId:t,getRouteMetadata:t=>this.getRouteMetadata(t),getRouteConnectionId:t=>this.getRouteConnectionId(t)})}getAdditionalRegionLabel(t){}getNeverSuccessfullyRoutedRoutes(){const t=[];for(let e=0;e<this.problem.routeCount;e++){const n=this.routeAttemptCountByRouteId[e];0===n||this.routeSuccessCountByRouteId[e]>0||t.push({...this.getRouteSummary(e),attempts:n})}return t}logNeverSuccessfullyRoutedRoutes(){if(!this.VERBOSE||this.hasLoggedNeverSuccessfullyRoutedRoutes)return;const t=this.getNeverSuccessfullyRoutedRoutes();if(this.hasLoggedNeverSuccessfullyRoutedRoutes=!0,0!==t.length){console.log(["[TinyHyperGraphSolver:never-routed-summary]",`count=${t.length}`].join(" "));for(const e of t){const t=e.pointIds.length>=2?`${e.pointIds[0]}->${e.pointIds[1]}`:"unknown";console.log(["[TinyHyperGraphSolver:never-routed]",`routeId=${e.routeId}`,`connectionId=${e.connectionId}`,`attempts=${e.attempts}`,`pointPath=${t}`,`startRegionId=${e.startRegionId??"unknown"}`,`endRegionId=${e.endRegionId??"unknown"}`].join(" "))}}}logRipEvent(t,e,n={}){this.VERBOSE&&console.log(["[TinyHyperGraphSolver:rip]",`ripCount=${this.state.ripCount}`,`maxRegionCostBeforeRip=${e.toFixed(3)}`,`reason=${t}`,...Object.entries(n).map(([t,e])=>`${t}=${"number"==typeof e?Number.isInteger(e)?String(e):e.toFixed(3):e}`)].join(" "))}onAllRoutesRouted(){const{topology:t,state:e}=this,n=this.RIP_THRESHOLD_RAMP_ATTEMPTS<=0?1:Math.min(1,e.ripCount/this.RIP_THRESHOLD_RAMP_ATTEMPTS),o=this.RIP_THRESHOLD_START+(this.RIP_THRESHOLD_END-this.RIP_THRESHOLD_START)*n,i=[],r=new Float64Array(t.regionCount);let s=0;for(let n=0;n<t.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;r[n]=t,s=Math.max(s,t),t>o&&i.push(n)}if(this.stats={...this.stats,currentRipThreshold:o,hotRegionCount:i.length,maxRegionCost:s,ripCount:e.ripCount},0===i.length||e.ripCount>=this.RIP_THRESHOLD_RAMP_ATTEMPTS)this.solved=!0;else{for(let n=0;n<t.regionCount;n++)e.regionCongestionCost[n]+=r[n]*this.RIP_CONGESTION_REGION_COST_FACTOR;e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCostBeforeRip:s,reripRegionCount:i.length},this.logRipEvent("hot_regions",s,{hotRegionCount:i.length,currentRipThreshold:o})}}onOutOfCandidates(){const{topology:t,state:e}=this,n=e.currentRouteId,o=this.getMaxRegionCost();for(let n=0;n<t.regionCount;n++){const t=e.regionIntersectionCaches[n]?.existingRegionCost??0;e.regionCongestionCost[n]+=t*this.RIP_CONGESTION_REGION_COST_FACTOR}e.ripCount+=1,this.resetRoutingStateForRerip(),this.stats={...this.stats,ripCount:e.ripCount,maxRegionCost:o,maxRegionCostBeforeRip:o,reripReason:"out_of_candidates"},this.logRipEvent("out_of_candidates",o,{...void 0===n?{}:{routeId:n,connectionId:this.getRouteConnectionId(n)}})}onPathFound(t){const{state:e}=this,n=e.currentRouteId;if(void 0===n)return;this.routeSuccessCountByRouteId[n]+=1;const o=this.getSolvedPathSegments(t);for(const{regionId:t,fromPortId:i,toPortId:r}of o)e.regionSegments[t].push([n,i,r]),e.portAssignment[i]=e.currentRouteNetId,e.portAssignment[r]=e.currentRouteNetId,this.appendSegmentToRegionCache(t,i,r);e.candidateQueue.clear(),e.currentRouteNetId=void 0,e.currentRouteId=void 0}computeG(t,e){const{topology:n,state:o}=this,i=t.nextRegionId,r=o.regionIntersectionCaches[i],s=this.populateSegmentGeometryScratch(i,t.portId,e),[a,c,l]=gW(r,o.currentRouteNetId,s.lesserAngle,s.greaterAngle,s.layerMask,s.entryExitLayerChanges);if(a>0&&this.isKnownSingleLayerRegion(i))return Number.POSITIVE_INFINITY;const d=this.computeRegionCostForRegion(i,r.existingSameLayerIntersections+a,r.existingCrossingLayerIntersections+c,r.existingEntryExitLayerChanges+l,r.existingSegmentCount+1)-r.existingRegionCost;return t.g+d+o.regionCongestionCost[i]}tryFinalAcceptance(){const t=this.getNeverSuccessfullyRoutedRoutes();this.stats={...this.stats,neverSuccessfullyRoutedRouteCount:t.length},this.logNeverSuccessfullyRoutedRoutes()}computeH(t){return this.problemSetup.portHCostToEndOfRoute[t*this.problem.routeCount+this.state.currentRouteId]}visualize(){return oH(this)}getOutput(){return uW(this)}},aH=t=>{const e="number"==typeof t.d?.netId?t.d.netId:"number"==typeof t.d?.NetId?t.d.NetId:void 0;return Number.isFinite(e)?e:void 0},cH=t=>{const e=new Set;for(const n of t.connections??[])e.add(n.startRegionId),e.add(n.endRegionId);const n=new Set(t.regions.filter(t=>(t=>{if(!0!==t.d?._containsObstacle)return!1;if(!0!==t.d?._containsTarget)return!0;const e=aH(t);return void 0===e||-1===e})(t)&&!e.has(t.regionId)).map(t=>t.regionId));if(0===n.size)return t;const o=t.ports.filter(t=>!n.has(t.region1Id)&&!n.has(t.region2Id)),i=(t.connections??[]).find(t=>n.has(t.startRegionId)||n.has(t.endRegionId));if(i)throw new Error(`Connection "${i.connectionId}" references full-obstacle region`);return{...t,regions:t.regions.filter(t=>!n.has(t.regionId)),ports:o}},lH=t=>{const e=t.d?.bounds;if(e)return e;const n=t.d?.center,o=t.d?.width,i=t.d?.height;return n&&"number"==typeof n.x&&"number"==typeof n.y&&"number"==typeof o&&"number"==typeof i?{minX:n.x-o/2,maxX:n.x+o/2,minY:n.y-i/2,maxY:n.y+i/2}:{minX:0,maxX:0,minY:0,maxY:0}},dH=t=>{const e=Number(t.d?.z??0);return Number.isFinite(e)?e:0},hH=t=>.005*dH(t),uH=t=>Number(t.d?.x??0)+hH(t),pH=t=>Number(t.d?.y??0)+hH(t),mH=(t,e)=>{if(!e)return 0;const n=lH(e),o=uH(t),i=pH(t),r=n.minX<=o&&o<=n.maxX,s=n.minY<=i&&i<=n.maxY;if(s&&o>=n.maxX){const t=Math.max(n.maxY-n.minY,1e-9),e=(i-n.minY)/t;return Math.round(9e3*e)}if(r&&i>=n.maxY){const t=Math.max(n.maxX-n.minX,1e-9),e=(n.maxX-o)/t;return 9e3+Math.round(9e3*e)}if(s&&o<=n.minX){const t=Math.max(n.maxY-n.minY,1e-9),e=(n.maxY-i)/t;return 18e3+Math.round(9e3*e)}if(r&&i<=n.minY){const t=Math.max(n.maxX-n.minX,1e-9),e=(o-n.minX)/t;return 27e3+Math.round(9e3*e)}const a=Math.abs(o-n.minX),c=Math.abs(o-n.maxX),l=Math.abs(i-n.minY),d=Math.abs(i-n.maxY),h=Math.min(a,c,l,d),u=Math.max(n.maxX-n.minX,1e-9),p=Math.max(n.maxY-n.minY,1e-9);if(h===c){const t=(i-n.minY)/p;return Math.round(9e3*t)}if(h===d){const t=(n.maxX-o)/u;return 9e3+Math.round(9e3*t)}if(h===a){const t=(n.maxY-i)/p;return 18e3+Math.round(9e3*t)}const m=(o-n.minX)/u;return 27e3+Math.round(9e3*m)},gH=(t,e)=>{if(!t)return;return[...t.pointIds].sort((t,n)=>{const o=e.get(t),i=e.get(n),r=Number(o?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY),s=Number(i?.d?.distToCentermostPortOnZ??Number.POSITIVE_INFINITY);if(r!==s)return r-s;const a=Number(o?.d?.z??0),c=Number(i?.d?.z??0);return a!==c?a-c:t.localeCompare(n)})[0]},fH=t=>{const e=cH(t),n=new Map,o=new Map,i=new Map,r=new Map((e.solvedRoutes??[]).map(t=>[t.connection.connectionId,t]));e.regions.forEach((t,e)=>{n.set(t.regionId,e)}),e.ports.forEach((t,e)=>{o.set(t.portId,e),i.set(t.portId,t)});const s=e.regions.length,a=e.ports.length,c=e.regions.map(t=>t.pointIds.map(t=>o.get(t)).filter(t=>void 0!==t)),l=Array.from({length:a},()=>[]),d=new Float64Array(s),h=new Float64Array(s),u=new Float64Array(s),p=new Float64Array(s),m=new Int32Array(s),g=new Int32Array(s).fill(-1),f=new Int8Array(s);e.regions.forEach((t,e)=>{const n=(t=>{const e=lH(t),n="number"==typeof t.d?.width?t.d.width:e.maxX-e.minX,o="number"==typeof t.d?.height?t.d.height:e.maxY-e.minY;return{centerX:"number"==typeof t.d?.center?.x?t.d.center.x:(e.minX+e.maxX)/2,centerY:"number"==typeof t.d?.center?.y?t.d.center.y:(e.minY+e.maxY)/2,width:n,height:o}})(t);d[e]=n.width,h[e]=n.height,u[e]=n.centerX,p[e]=n.centerY,m[e]=(t=>{const e=t.d?.availableZ;if(!Array.isArray(e))return 0;let n=0;for(const t of e)!Number.isInteger(t)||t<0||t>=31||(n|=1<<t);return n})(t);const o=aH(t);void 0!==o&&(g[e]=o,f[e]=1)});const y=new Int32Array(a),_=new Int32Array(a),b=new Float64Array(a),x=new Float64Array(a),v=new Int32Array(a);e.ports.forEach((t,o)=>{const i=n.get(t.region1Id),r=n.get(t.region2Id);if(void 0===i||void 0===r)throw new Error(`Port "${t.portId}" references missing regions "${t.region1Id}" or "${t.region2Id}"`);l[o]=[i,r],b[o]=uH(t),x[o]=pH(t),v[o]=dH(t),y[o]=mH(t,e.regions[i]),_[o]=mH(t,e.regions[r])});const S=e.regions.map((t,e)=>((t,e)=>{const n=t.d&&"object"==typeof t.d&&!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,"serializedRegionId",{value:t.regionId,enumerable:!1,configurable:!0,writable:!0}),n})(t,(t=>nW(oW(m[t]))??nW((c[t]??[]).map(t=>v[t]))??"z0")(e))),I=e.ports.map((t,e)=>((t,e)=>{const n=t.d&&"object"==typeof t.d&&!Array.isArray(t.d)?{...t.d}:{value:t.d};return n.layer=e,Object.defineProperty(n,"serializedPortId",{value:t.portId,enumerable:!1,configurable:!0,writable:!0}),n})(t,nW([v[e]])??"z0")),C=e.connections??[],P=new Map;let M=0;const N=t=>{const e=t.mutuallyConnectedNetworkId??t.connectionId;let n=P.get(e);return void 0===n&&(n=M++,P.set(e,n)),n},w=Array.from({length:s},()=>new Set),T=(t,e)=>{const o=n.get(t);if(void 0===o)throw new Error(`Connection references missing region "${t}"`);w[o].add(e)};C.forEach(t=>{const e=N(t);T(t.startRegionId,e),T(t.endRegionId,e)}),w.forEach((t,e)=>{1!==f[e]&&1===t.size&&(g[e]=[...t][0])});const R=C.map(t=>{const n=r.get(t.connectionId),o=((t,e)=>t.ports.filter(t=>t.region1Id===e.startRegionId&&t.region2Id===e.endRegionId||t.region2Id===e.startRegionId&&t.region1Id===e.endRegionId).map(t=>t.portId))(e,t);return{connection:t,solvedRoute:n,sharedPortIds:o}}).filter(({solvedRoute:t,sharedPortIds:e})=>0===e.length||(t?.path.length??0)>1),E=R.length,A=new Int8Array(a).fill(1),O=new Int32Array(E),k=new Int32Array(E),L=new Int32Array(E);R.forEach(({connection:t,solvedRoute:n},r)=>{const s=gH(e.regions.find(e=>e.regionId===t.startRegionId),i),a=gH(e.regions.find(e=>e.regionId===t.endRegionId),i),c=n?.path[0]?.portId??s,l=n?.path[n.path.length-1]?.portId??a,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)throw new Error(`Connection "${t.connectionId}" could not be mapped to route endpoints`);O[r]=d,k[r]=h,L[r]=N(t)});const D={portCount:a,regionCount:s,regionIncidentPorts:c,incidentPortRegion:l,regionWidth:d,regionHeight:h,regionCenterX:u,regionCenterY:p,regionAvailableZMask:m,regionMetadata:S,portAngleForRegion1:y,portAngleForRegion2:_,portX:b,portY:x,portZ:v,portMetadata:I},z={routeCount:E,portSectionMask:A,routeMetadata:R.map(({connection:t})=>t),routeStartPort:O,routeEndPort:k,routeNet:L,regionNetId:g},F=[],B=[];for(const{solvedRoute:t}of R){if(!t){F.push([]),B.push([]);continue}const e=[],i=[];for(let r=1;r<t.path.length;r++){const s=t.path[r-1],a=t.path[r],c=s?.portId,l=a?.portId,d=void 0!==c?o.get(c):void 0,h=void 0!==l?o.get(l):void 0;if(void 0===d||void 0===h)continue;const u="string"==typeof s?.nextRegionId?s.nextRegionId:"string"==typeof a?.lastRegionId?a.lastRegionId:void 0;e.push([d,h]),i.push(void 0!==u?n.get(u):void 0)}F.push(e),B.push(i)}return{topology:D,problem:z,solution:{solvedRoutePathSegments:F,solvedRoutePathRegionIds:B}}},yH=(Number.POSITIVE_INFINITY,1e-9),_H=t=>"object"==typeof t&&null!==t,bH=(t,e=0)=>"number"==typeof t&&Number.isFinite(t)?t:e,xH=t=>{const e=(t=>{const e=Math.min(t.minX,t.maxX),n=Math.max(t.minX,t.maxX),o=Math.min(t.minY,t.maxY),i=Math.max(t.minY,t.maxY);return{minX:e,maxX:n>e?n:e+yH,minY:o,maxY:i>o?i:o+yH}})(t);return[{x:e.maxX,y:e.minY},{x:e.maxX,y:e.maxY},{x:e.minX,y:e.maxY},{x:e.minX,y:e.minY}]},vH=(t,e)=>{const n=t.filter(t=>Number.isFinite(t.x)&&Number.isFinite(t.y)),o=n.length>=3?n:xH(e),i=(t=>{let e=0;for(let n=0;n<t.length;n++){const o=t[n],i=t[(n+1)%t.length];e+=o.x*i.y-o.y*i.x}return e})(o);if(Math.abs(i)<=Number.EPSILON)return xH(e);return(t=>{if(t.length<3)throw new Error("Convex polygon requires at least three points");return t})(i<0?[...o].reverse():[...o])},SH=t=>{const e=(t=>{const e=t.d,n=e?.bounds;if(n&&"number"==typeof n.minX&&"number"==typeof n.maxX&&"number"==typeof n.minY&&"number"==typeof n.maxY)return{minX:n.minX,maxX:n.maxX,minY:n.minY,maxY:n.maxY};const o=e?.center,i=bH(e?.width,0),r=bH(e?.height,0);return o&&"number"==typeof o.x&&"number"==typeof o.y?{minX:o.x-i/2,maxX:o.x+i/2,minY:o.y-r/2,maxY:o.y+r/2}:{minX:0,maxX:yH,minY:0,maxY:yH}})(t);return vH((t=>{const e=t.d,n=e?.polygon??e?.points??e?.vertices;if(!Array.isArray(n))return;const o=n.map(t=>{if(!_H(t))return;const e=t.x,n=t.y;return"number"==typeof e&&"number"==typeof n?{x:e,y:n}:void 0}).filter(t=>void 0!==t);if(o.length>1){const t=o[0],e=o[o.length-1];t.x===e.x&&t.y===e.y&&o.pop()}return o.length>=3?o:void 0})(t)??xH(e),e)},IH=t=>{let e=0,n=0,o=0,i=0,r=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,a=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY;for(let l=0;l<t.length;l++){const d=t[l],h=t[(l+1)%t.length],u=d.x*h.y-h.x*d.y;e+=u,n+=(d.x+h.x)*u,o+=(d.y+h.y)*u,i+=Math.hypot(h.x-d.x,h.y-d.y),r=Math.min(r,d.x),s=Math.max(s,d.x),a=Math.min(a,d.y),c=Math.max(c,d.y)}const l=Math.abs(e)/2,d=Math.abs(e)>Number.EPSILON?3*e:Number.NaN,h=t.reduce((e,n)=>({x:e.x+n.x/t.length,y:e.y+n.y/t.length}),{x:0,y:0});return{area:l,perimeter:i,centerX:Number.isFinite(d)?n/d:h.x,centerY:Number.isFinite(d)?o/d:h.y,bounds:{minX:r,maxX:s,minY:a,maxY:c}}},CH=(t,e,n,o)=>{if(n<=0)return{boundaryPosition:0,edgeIndex:0,edgeT:0};let i=Number.POSITIVE_INFINITY,r=0,s=0,a=0,c=0;for(let n=0;n<e.length;n++){const o=e[n],l=e[(n+1)%e.length],d=l.x-o.x,h=l.y-o.y,u=d*d+h*h,p=Math.sqrt(u),m=u<=Number.EPSILON?0:((t.x-o.x)*d+(t.y-o.y)*h)/u,g=Math.min(1,Math.max(0,m)),f=o.x+d*g,y=o.y+h*g,_=t.x-f,b=t.y-y,x=_*_+b*b;x<i&&(i=x,r=n,s=g,a=c+p*g),c+=p}return{boundaryPosition:Math.round(a/n*o)%o,edgeIndex:r,edgeT:s}},PH=(t,e)=>{const n=t.regionMetadata?.[e];return _H(n)&&"string"==typeof n.serializedRegionId?n.serializedRegionId:`region-${e}`},MH=(t,e)=>{const n=t.portMetadata?.[e];return _H(n)&&"string"==typeof n.serializedPortId?n.serializedPortId:`port-${e}`},NH=(t,e,n,o)=>{const i={..._H(t)?{...t}:void 0===t?{}:{value:t},polygon:n,sourceBounds:o};return Object.defineProperty(i,"serializedRegionId",{value:e,enumerable:!1,configurable:!0,writable:!0}),i},wH=(t,e)=>{const n=new Map,o=new Map,i=new Map,r=new Map;for(let e=0;e<t.regionCount;e++)n.set(PH(t,e),e);for(let e=0;e<t.portCount;e++)o.set(MH(t,e),e);for(let t=0;t<e.routeCount;t++){const n=e.routeMetadata?.[t];if(!_H(n))continue;"string"==typeof n.connectionId&&i.set(n.connectionId,t);const o="string"==typeof n.mutuallyConnectedNetworkId?n.mutuallyConnectedNetworkId:"string"==typeof n.connectionId?n.connectionId:void 0;void 0!==o&&r.set(o,e.routeNet[t])}return{serializedRegionIdToRegionId:n,serializedPortIdToPortId:o,connectionIdToRouteId:i,netIdToNetIndex:r}},TH=(t,e,n)=>{const o=t.incidentPortRegion[e];return o[0]===n||o[1]!==n?t.portBoundaryPositionForRegion1[e]:t.portBoundaryPositionForRegion2[e]},RH=class extends sH{constructor(t,e,n){super(t,e,n),this.topology=t,this.problem=e}topology;problem;polySegmentGeometryScratch={lesserAngle:0,greaterAngle:0,layerMask:0,entryExitLayerChanges:0};populateSegmentGeometryScratch(t,e,n){const{topology:o}=this,i=this.polySegmentGeometryScratch,r=TH(o,e,t),s=TH(o,n,t),a=o.portZ[e],c=o.portZ[n];return i.lesserAngle=r<s?r:s,i.greaterAngle=r<s?s:r,i.layerMask=1<<a|1<<c,i.entryExitLayerChanges=a!==c?1:0,i}computeRegionCostForRegion(t,e,n,o,i){return mW(this.topology.regionArea[t],e,n,o,i,this.topology.regionAvailableZMask?.[t]??0)}visualize(){return $H(this)}},EH=(...t)=>t.filter(t=>Boolean(t)).join("\n"),AH=(t,e)=>{const n=t.problem.routeMetadata?.[e];return n?.connectionId??n?.mutuallyConnectedNetworkId??`route-${e}`},OH=(t,e,n=.85)=>{const o=`${t.problem.routeNet[e]}:${AH(t,e)}`;let i=0;for(let t=0;t<o.length;t++)i=17777*o.charCodeAt(t)+((i<<5)-i);return`hsla(${Math.abs(i)%360}, 70%, 45%, ${n})`},kH=(t,e)=>{const n=t.regionVertexStart[e],o=t.regionVertexCount[e],i=[];for(let e=0;e<o;e++){const o=n+e;i.push({x:t.regionVertexX[o],y:t.regionVertexY[o]})}return i},LH=(t,e)=>{const n=t.state.regionIntersectionCaches[e]?.existingRegionCost??0,o=Math.min(1,Math.max(0,Math.pow(n,.8))),i=Math.round(245-105*o);return`rgba(245, ${Math.round(248-168*o)}, ${i}, ${.18+.48*o})`},DH=(t,e)=>{const n=t.state.regionIntersectionCaches[e],o=PH(t.topology,e),i=t.problem.regionNetId[e];return EH(`region: ${o}`,`net: ${-1===i?"free":i}`,`area: ${t.topology.regionArea[e].toFixed(3)}`,`cost: ${(n?.existingRegionCost??0).toFixed(3)}`,`same layer X: ${n?.existingSameLayerIntersections??0}`,`trans X: ${n?.existingCrossingLayerIntersections??0}`,`entry exit X: ${n?.existingEntryExitLayerChanges??0}`)},zH=(t,e)=>nW(oW(t.topology.regionAvailableZMask?.[e]??0))??nW((t.topology.regionIncidentPorts[e]??[]).map(e=>t.topology.portZ[e]))??"z0",FH=(t,e)=>({x:t.topology.portX[e],y:t.topology.portY[e]}),BH=(t,e)=>nW([t.topology.portZ[e]])??"z0",jH=(t,e)=>{const[n,o]=t.topology.incidentPortRegion[e]??[];return EH(`port: ${MH(t.topology,e)}`,`connects: ${n??"?"} <-> ${o??"?"}`,`z: ${t.topology.portZ[e]}`)},$H=t=>{const e={arrows:[],circles:[],infiniteLines:[],lines:[],points:[],polygons:[],rects:[],texts:[],title:"Poly HyperGraph",coordinateSystem:"cartesian"};for(let n=0;n<t.topology.regionCount;n++)e.polygons.push({points:kH(t.topology,n),fill:LH(t,n),stroke:"rgba(80, 80, 120, 0.55)",layer:zH(t,n),label:DH(t,n)});for(let n=0;n<t.topology.portCount;n++)e.circles.push({center:FH(t,n),radius:.05,fill:t.topology.portZ[n]>0?"rgba(52, 152, 219, 0.55)":"rgba(80, 80, 80, 0.45)",layer:BH(t,n),label:jH(t,n)});((t,e)=>{for(let n=0;n<t.problem.routeCount;n++){const o=t.problem.routeStartPort[n],i=t.problem.routeEndPort[n],r=AH(t,n),s=OH(t,n);e.points.push({...FH(t,o),color:s,layer:BH(t,o),label:EH(`route: ${r}`,"endpoint: start",jH(t,o))}),e.points.push({...FH(t,i),color:s,layer:BH(t,i),label:EH(`route: ${r}`,"endpoint: end",jH(t,i))})}})(t,e),((t,e)=>{for(let n=0;n<t.state.regionSegments.length;n++)for(const[o,i,r]of t.state.regionSegments[n]??[])e.lines.push({points:[FH(t,i),FH(t,r)],strokeColor:OH(t,o),layer:nW([t.topology.portZ[i],t.topology.portZ[r]])??"z0",label:EH(`route: ${AH(t,o)}`,`region: ${PH(t.topology,n)}`)})})(t,e),((t,e)=>{if(t.solved)return;const n=t.state.candidateQueue.toArray().sort((t,e)=>t.f-e.f).slice(0,10);for(let o=0;o<n.length;o++){const i=n[o];e.points.push({...FH(t,i.portId),color:0===o?"green":"rgba(128, 128, 128, 0.4)",layer:BH(t,i.portId),label:EH(jH(t,i.portId),`g: ${i.g.toFixed(2)}`,`h: ${i.h.toFixed(2)}`,`f: ${i.f.toFixed(2)}`)})}const o=n[0];if(!o)return;const i=[];let r=o;for(;r;)i.unshift(FH(t,r.portId)),r=r.prevCandidate;if(i.length<=1)return;const s=t.state.currentRouteId;e.lines.push({points:i,strokeColor:void 0!==s?OH(t,s,.95):"rgba(0, 160, 120, 0.95)",strokeDash:"4 3",layer:BH(t,o.portId),label:EH(void 0!==s?`route: ${AH(t,s)}`:void 0,"active candidate path",`candidate port: ${MH(t.topology,o.portId)}`)})})(t,e);const n=t.state.unroutedRoutes.length+(void 0===t.state.currentRouteId?0:1);return e.title=["Poly HyperGraph",`iter=${t.iterations}`,`pending=${n}`,t.failed?"failed":t.solved?"solved":"running"].join(" | "),e},YH=(new Int32Array(0),t=>(t.ccwRotationDegrees??0)*Math.PI/180),XH=(t,e=8)=>{const n=t.width/2,o=t.height/2,i=YH(t),r=Math.cos(i),s=Math.sin(i);return Array.from({length:e},(i,a)=>{const c=2*Math.PI*a/e,l=n*Math.cos(c),d=o*Math.sin(c);return{x:t.center.x+l*r-d*s,y:t.center.y+l*s+d*r}})},VH=t=>(t.obstacles??[]).filter(t=>"oval"===t.type).map(t=>({points:XH(t),layers:t.layers,zLayers:t.__zLayers,isCopperPour:t.isCopperPour})),WH=(t,e)=>(t.obstacles??[]).flatMap((n,o)=>{if(!Array.isArray(n.connectedTo)||0===n.connectedTo.length)return[];const i=oV(sV(n,t.layerCount),t.layerCount);if(0===i.length)return[];let r;const s=n.type;if("rect"===s)r=((t,e=0)=>{const n=t.width/2+e,o=t.height/2+e,i=YH(t),r=Math.cos(i),s=Math.sin(i);return[{localX:-n,localY:-o},{localX:n,localY:-o},{localX:n,localY:o},{localX:-n,localY:o}].map(({localX:e,localY:n})=>({x:t.center.x+e*r-n*s,y:t.center.y+e*s+n*r}))})(n,e);else{if("oval"!==s)return[];r=EV({polygon:{points:XH(n),layers:n.layers,zLayers:n.__zLayers,isCopperPour:n.isCopperPour},clearance:e,verticesOnly:!0})}return[{regionId:`connected-obstacle-${o}`,polygon:r,availableZ:i,connectedTo:n.connectedTo,d:{obstacleIndex:o,obstacleType:s,connectedTo:n.connectedTo}}]}),HH=t=>"object"==typeof t&&null!==t?t:{},GH=t=>"object"==typeof t&&null!==t?t:{},UH=(t,e)=>{const n=HH(t).serializedRegionId;return"string"==typeof n?n:`region-${e}`},ZH=(t,e)=>{const n=GH(t);return"string"==typeof n.serializedPortId?n.serializedPortId:"string"==typeof n.portId?n.portId:`poly-port-${e}`},qH=t=>{const e=GH(t);return{prevPortPointId:"string"==typeof e.prevPortPointId?e.prevPortPointId:void 0,nextPortPointId:"string"==typeof e.nextPortPointId?e.nextPortPointId:void 0}},JH=t=>{const e=HH(t).polygon;if(Array.isArray(e)&&!(e.length<3))return e.every(t=>"object"==typeof t&&null!==t&&"number"==typeof t.x&&"number"==typeof t.y)?e:void 0},KH=class extends si{constructor(t){super(),this.params=t,this.effort=t.effort??1,this.clearance=t.srj.defaultObstacleMargin??t.srj.minTraceWidth;const e=e=>{return eW({bounds:t.srj.bounds,rects:(n=t.srj,(n.obstacles??[]).filter(t=>"rect"===t.type).map(t=>({center:t.center,width:t.width,height:t.height,ccwRotation:YH(t),layers:t.layers,zLayers:t.__zLayers,isCopperPour:t.isCopperPour}))),polygons:VH(t.srj),clearance:this.clearance,concavityTolerance:t.concavityTolerance??0,layerCount:t.srj.layerCount,layerMergeMode:t.layerMergeMode??"same",useConstrainedDelaunay:e,usePolyanyaMerge:t.usePolyanyaMerge??!1,viaSegments:t.viaSegments??8});var n},n=t.useConstrainedDelaunay??!0;try{this.convexRegions=e(n)}catch(t){if(!n)throw t;this.usedUnconstrainedDelaunayFallback=!0,this.convexRegions=e(!1)}var o;this.serializedGraph=RV({regions:this.convexRegions.regions,availableZ:this.convexRegions.availableZ,layerCount:t.srj.layerCount,connections:(o=t.srj,o.connections.flatMap(t=>{const e=t.pointsToConnect??[];if(e.length<2)return[];const n=e[0];return e.slice(1).map((e,o)=>{const i=((t,e,n,o)=>{const i=2===t.pointsToConnect.length?t.name:`${t.name}::${o}`;return{...t,name:i,__rootConnectionNames:t.__rootConnectionNames??[t.name],pointsToConnect:[e,n]}})(t,n,e,o);return{connectionId:i.name,mutuallyConnectedNetworkId:i.__rootConnectionNames?.[0]??i.name,start:n,end:e,simpleRouteConnection:i}})})),obstacleRegions:WH(t.srj,this.clearance),portSpacing:t.portSpacing??lV,portMarginFromSegmentEndpoint:t.portMarginFromSegmentEndpoint??dV}),this.loaded=((t,e={})=>{const n=e.boundaryCoordinateScale??36e3,o=fH(t),{topology:i,problem:r,solution:s}=o,a=new Map(t.regions.map(t=>[t.regionId,t])),c=[];for(let t=0;t<i.regionCount;t++){const e=PH(i,t),n=a.get(e),o=n?SH(n):xH({minX:i.regionCenterX[t]-i.regionWidth[t]/2,maxX:i.regionCenterX[t]+i.regionWidth[t]/2,minY:i.regionCenterY[t]-i.regionHeight[t]/2,maxY:i.regionCenterY[t]+i.regionHeight[t]/2});c.push(o)}const l=c.reduce((t,e)=>t+e.length,0),d=new Int32Array(i.regionCount),h=new Int32Array(i.regionCount),u=new Float64Array(l),p=new Float64Array(l),m=new Float64Array(i.regionCount),g=new Float64Array(i.regionCount),f=new Float64Array(i.regionCount),y=new Float64Array(i.regionCount),_=new Float64Array(i.regionCount),b=new Float64Array(i.regionCount),x=new Float64Array(i.regionCount),v=new Float64Array(i.regionCount),S=new Float64Array(i.regionCount),I=new Float64Array(i.regionCount),C=new Array(i.regionCount);let P=0;for(let t=0;t<i.regionCount;t++){const e=c[t],n=IH(e),o=Math.sqrt(Math.max(n.area,yH));d[t]=P,h[t]=e.length,m[t]=n.area,g[t]=n.perimeter,f[t]=n.centerX,y[t]=n.centerY,_[t]=n.bounds.minX,b[t]=n.bounds.maxX,x[t]=n.bounds.minY,v[t]=n.bounds.maxY,S[t]=o,I[t]=o,C[t]=NH(i.regionMetadata?.[t],PH(i,t),e,n.bounds);for(const t of e)u[P]=t.x,p[P]=t.y,P+=1}const M=new Int32Array(i.portCount),N=new Int32Array(i.portCount),w=new Int32Array(i.portCount),T=new Int32Array(i.portCount),R=new Float64Array(i.portCount),E=new Float64Array(i.portCount);for(let t=0;t<i.portCount;t++){const e={x:i.portX[t],y:i.portY[t]},[o,r]=i.incidentPortRegion[t]??[];if(void 0!==o){const i=CH(e,c[o],g[o],n);M[t]=i.boundaryPosition,w[t]=i.edgeIndex,R[t]=i.edgeT}if(void 0!==r){const o=CH(e,c[r],g[r],n);N[t]=o.boundaryPosition,T[t]=o.edgeIndex,E[t]=o.edgeT}}for(let t=0;t<i.regionCount;t++)C[t].layer=nW(oW(i.regionAvailableZMask?.[t]??0))??nW((i.regionIncidentPorts[t]??[]).map(t=>i.portZ[t]))??"z0";const A={...i,regionWidth:S,regionHeight:I,regionCenterX:f,regionCenterY:y,regionMetadata:C,portAngleForRegion1:M,portAngleForRegion2:N,regionVertexStart:d,regionVertexCount:h,regionVertexX:u,regionVertexY:p,regionArea:m,regionPerimeter:g,regionBoundsMinX:_,regionBoundsMaxX:b,regionBoundsMinY:x,regionBoundsMaxY:v,portBoundaryPositionForRegion1:M,portBoundaryPositionForRegion2:N,portEdgeIndexForRegion1:w,portEdgeIndexForRegion2:T,portEdgeTForRegion1:R,portEdgeTForRegion2:E};return{topology:A,problem:r,solution:s,mapping:wH(A,r)}})(this.serializedGraph),this.reservedRegionCount=((t,e)=>{const n=t.problem.regionNetId;if(!n)return 0;const o=new Map;for(const t of e.regions){const e="number"==typeof t.d?.netId?t.d.netId:"number"==typeof t.d?.NetId?t.d.NetId:void 0;Number.isInteger(e)&&e>=0&&o.set(t.regionId,e)}let i=0;for(let e=0;e<t.topology.regionCount;e++){const r=t.topology.regionMetadata?.[e],s="object"==typeof r&&null!==r?r.serializedRegionId:void 0;if("string"!=typeof s)continue;const a=o.get(s);void 0!==a&&(n[e]=a,i+=1)}return i})(this.loaded,this.serializedGraph);const i={DISTANCE_TO_COST:.05,RIP_THRESHOLD_START:.05,RIP_THRESHOLD_END:.8,RIP_CONGESTION_REGION_COST_FACTOR:.1,RIP_THRESHOLD_RAMP_ATTEMPTS:Math.max(1,Math.ceil(10*this.effort)),MAX_ITERATIONS:Math.max(1e5,Math.ceil(1e7*this.effort))};this.polySolver=new RH(this.loaded.topology,this.loaded.problem,i),this.activeSubSolver=this.polySolver,this.MAX_ITERATIONS=i.MAX_ITERATIONS+1e3,this.inputNodeWithPortPoints=this.createInputNodesWithPortPoints()}params;getSolverName(){return"PolyHypergraphPortPointPathingSolver"}convexRegions;serializedGraph;loaded;polySolver;inputNodeWithPortPoints=[];nodesWithPortPoints=[];reservedRegionCount=0;clearance;effort;usedUnconstrainedDelaunayFallback=!1;createInputNodesWithPortPoints(){const{topology:t}=this.loaded,e=[];for(let n=0;n<t.regionCount;n++){const o=HH(t.regionMetadata?.[n]??{}),i=UH(o,n);if(i.startsWith("terminal-"))continue;const r=(t.regionIncidentPorts[n]??[]).map(e=>{const n=t.incidentPortRegion[e]??[],o=t.portMetadata?.[e];return{portPointId:ZH(o,e),x:t.portX[e],y:t.portY[e],z:t.portZ[e],...qH(o),connectionNodeIds:n.map(e=>UH(t.regionMetadata?.[e],e)),distToCentermostPortOnZ:t.portMetadata?.[e]?.distToCentermostPortOnZ??0,connectsToOffBoardNode:!1}});e.push({capacityMeshNodeId:i,center:{x:t.regionCenterX[n],y:t.regionCenterY[n]},width:t.regionWidth[n],height:t.regionHeight[n],portPoints:r,availableZ:o.availableZ??Array.from({length:this.params.srj.layerCount},(t,e)=>e),_containsObstacle:Boolean(o._containsObstacle),_containsTarget:Boolean(o._containsTarget)})}return e}createAssignedPortPoint(t,e){const n=this.polySolver.problem.routeMetadata?.[t],o=n?(t=>t.simpleRouteConnection?.name??t.connectionId)(n):`route-${t}`,i=n?(t=>t.simpleRouteConnection?.rootConnectionName??t.mutuallyConnectedNetworkId)(n):void 0,r=this.polySolver.topology.portMetadata?.[e];return{portPointId:ZH(r,e),x:this.polySolver.topology.portX[e],y:this.polySolver.topology.portY[e],z:this.polySolver.topology.portZ[e],connectionName:o,rootConnectionName:i,...qH(r)}}buildOutputNodes(){const{topology:t,state:e}=this.polySolver,n=[];for(let o=0;o<e.regionSegments.length;o++){const i=HH(t.regionMetadata?.[o]??{}),r=UH(i,o);if(r.startsWith("terminal-"))continue;const s=JH(i);if(!s)continue;const a=(e.regionSegments[o]??[]).flatMap(([t,e,n])=>{const o=this.createAssignedPortPoint(t,e),i=this.createAssignedPortPoint(t,n);return o.portPointId&&i.portPointId&&(o.nextPortPointId=i.portPointId,i.prevPortPointId=o.portPointId),[o,i]});0!==a.length&&n.push({capacityMeshNodeId:r,center:{x:t.regionCenterX[o],y:t.regionCenterY[o]},width:t.regionWidth[o],height:t.regionHeight[o],polygon:s,portPoints:a,availableZ:i.availableZ})}this.nodesWithPortPoints=n}_step(){this.polySolver.step(),this.progress=this.polySolver.progress,this.stats={...this.polySolver.stats??{},reservedRegionCount:this.reservedRegionCount,usedUnconstrainedDelaunayFallback:this.usedUnconstrainedDelaunayFallback,regionCount:this.loaded.topology.regionCount,portCount:this.loaded.topology.portCount,routeCount:this.loaded.problem.routeCount},this.polySolver.solved?(this.buildOutputNodes(),this.solved=!0,this.activeSubSolver=null):this.polySolver.failed&&(this.error=this.polySolver.error,this.failed=!0,this.activeSubSolver=null)}getOutput(){return{nodesWithPortPoints:this.nodesWithPortPoints,inputNodeWithPortPoints:this.inputNodeWithPortPoints}}computeNodePf(t){const e=this.nodesWithPortPoints.find(e=>e.capacityMeshNodeId===t.capacityMeshNodeId);if(!e)return null;const n=Ms(e);return Ys({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,layer:"top",availableZ:e.availableZ??[]},n.numSameLayerCrossings,n.numEntryExitLayerChanges,n.numTransitionPairCrossings)}getConstructorParams(){return[this.params]}preview(){return this.visualize()}visualize(){return this.polySolver.visualize()}},QH=class extends si{constructor(t){super(),this.inputSrj=t,this.MAX_ITERATIONS=1}inputSrj;outputSrj;_step(){this.outputSrj=mX(this.inputSrj)??this.inputSrj,this.solved=!0}getOutputSimpleRouteJson(){if(!this.outputSrj)throw new Error("PreprocessSimpleRouteJsonSolver has not solved yet");return this.outputSrj}getConstructorParams(){return[this.inputSrj]}visualize(){return this.outputSrj?pi(Ho({...this.outputSrj,traces:[]}),Yj({srj:this.outputSrj})):{lines:[],points:[],rects:[],circles:[]}}},tG=(t,e)=>(t.x-e.x)**2+(t.y-e.y)**2,eG=(t,e,n)=>{if(!n)return;const o=t.filter(({projected:t})=>t.connectionName===e&&(void 0===n.z||t.z===n.z));return 0!==o.length?o.reduce((t,e)=>tG(e.projected,n)<tG(t.projected,n)?e:t).original:void 0},nG=(t,e)=>{const n=e.projectedRect;if(!n)throw new Error("Poly node is missing projectedRect");const o=n.rectToPolygonMatrix,i=(t=>{if(!t.projectedRect)throw new Error("Poly node is missing projectedRect");return t.portPoints.map(e=>{const n=ZX(e,t.projectedRect);return{original:e,projected:{...e,x:n.x,y:n.y}}})})(e),r=t.route.map(t=>({...t,...HX(o,t)})),s=t.vias.map(t=>HX(o,t)),a=eG(i,t.connectionName,t.route[0]),c=eG(i,t.connectionName,t.route[t.route.length-1]);return a&&r[0]&&(r[0]={...r[0],x:a.x,y:a.y,z:a.z}),c&&r[r.length-1]&&(r[r.length-1]={...r[r.length-1],x:c.x,y:c.y,z:c.z}),{...t,route:r,vias:s,jumpers:t.jumpers?.map(t=>({...t,start:HX(o,t.start),end:HX(o,t.end)}))}},oG=class extends si{getSolverName(){return"ProjectHighDensityToPolygonSolver"}routes=[];routesByNodeId=new Map;colorMap;nodePortPoints;rawRoutesByNodeId;constructor({nodePortPoints:t,routesByNodeId:e,colorMap:n}){super(),this.MAX_ITERATIONS=1,this.nodePortPoints=t,this.rawRoutesByNodeId=e instanceof Map?new Map(e):new Map(Object.entries(e)),this.colorMap=n??{}}_step(){this.routes=[],this.routesByNodeId=new Map;for(const t of this.nodePortPoints){const e=(this.rawRoutesByNodeId.get(t.capacityMeshNodeId)??[]).map(e=>nG(e,t));e.length>0&&(this.routesByNodeId.set(t.capacityMeshNodeId,e),this.routes.push(...e))}this.solved=!0}getOutput(){return this.routes}getConstructorParams(){return[{nodePortPoints:this.nodePortPoints,routesByNodeId:this.rawRoutesByNodeId,colorMap:this.colorMap}]}visualize(){const t={polygons:this.nodePortPoints.flatMap(t=>[{points:t.polygon,fill:"rgba(40, 140, 220, 0.06)",stroke:"rgba(20, 70, 160, 0.65)",label:`${t.capacityMeshNodeId} polygon`},...t.projectedRect?[{points:t.projectedRect.targetQuad,fill:"rgba(255, 165, 0, 0.05)",stroke:"rgba(255, 120, 0, 0.45)",label:`${t.capacityMeshNodeId} projection target`}]:[]]),lines:[],circles:[]};for(const e of this.routes){const n=this.colorMap[e.connectionName]??"#0000ff",o=mi(e.route,e.connectionName,n);for(const n of o)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:To(n.color,.5),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?[.1,.3]:void 0});for(const o of e.vias)t.circles.push({center:o,layer:"z0,1",radius:e.viaDiameter/2,fill:n,label:`${e.connectionName} via`})}return t}};function iG(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var rG=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),this.equivalentAreaExpansionFactor=n.equivalentAreaExpansionFactor??2,this.minProjectedRectDimension=n.minProjectedRectDimension??3*this.minTraceWidth,void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;polyGraphSolver;attachProjectedRectsSolver;highDensityRouteSolver;projectHighDensityToPolgonSolver;highDensityStitchSolver;traceSimplificationSolver;traceWidthSolver;globalDrcForceImproveSolver;colorMap;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;equivalentAreaExpansionFactor;minProjectedRectDimension;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;highDensityNodePortPoints;projectedHighDensityNodePortPoints;cacheProvider=null;pipelineDef=[iG("preprocessSimpleRouteJsonSolver",QH,t=>[t.originalSrj],{onSolved:t=>{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),iG("escapeViaLocationSolver",Uj,t=>[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=>{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),iG("netToPointPairsSolver",ga,t=>{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),iG("polyGraphSolver",KH,t=>[{srj:t.srjWithPointPairs,effort:t.effort,concavityTolerance:t.opts.polyConcavityTolerance,portSpacing:t.opts.polyPortSpacing,portMarginFromSegmentEndpoint:t.opts.polyPortMarginFromSegmentEndpoint}],{onSolved:t=>{t.highDensityNodePortPoints=t.polyGraphSolver?.getOutput().nodesWithPortPoints??[]}}),iG("attachProjectedRectsSolver",JX,t=>[{nodesWithPortPoints:t.highDensityNodePortPoints??[],equivalentAreaExpansionFactor:t.equivalentAreaExpansionFactor,minProjectedRectDimension:t.minProjectedRectDimension,traceWidth:t.minTraceWidth,viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=>{t.projectedHighDensityNodePortPoints=t.attachProjectedRectsSolver?.getOutput()??[]}}),iG("highDensityRouteSolver",QX,t=>[{nodePortPoints:t.projectedHighDensityNodePortPoints??[],nodePfById:new Map((t.polyGraphSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=>[e.capacityMeshNodeId,t.polyGraphSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,effort:t.effort}]),iG("projectHighDensityToPolgonSolver",oG,t=>[{nodePortPoints:t.projectedHighDensityNodePortPoints??[],routesByNodeId:t.highDensityRouteSolver.routesByNodeId,colorMap:t.colorMap}]),iG("highDensityStitchSolver",KY,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.projectHighDensityToPolgonSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),iG("traceSimplificationSolver",vc,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}]),iG("traceWidthSolver",Ic,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}]),iG("globalDrcForceImproveSolver",Nz,t=>[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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"}getProblemVisualization({includeRoutes:t=!0}={}){const e=this.originalSrj,n=[{points:[{x:e.bounds?.minX??-50,y:e.bounds?.minY??-50},{x:e.bounds?.maxX??50,y:e.bounds?.minY??-50},{x:e.bounds?.maxX??50,y:e.bounds?.maxY??50},{x:e.bounds?.minX??-50,y:e.bounds?.maxY??50},{x:e.bounds?.minX??-50,y:e.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}];if(e.outline&&e.outline.length>=2){const t=e.outline.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),n.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const o=Oo(e),i={points:[...e.connections.flatMap(t=>t.pointsToConnect.map(n=>({...n,layer:Fo(n,e.layerCount),label:`${t.name} ${n.pcb_port_id??""}`})))],rects:[...(e.obstacles??[]).filter(t=>!t.isCopperPour).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)",layer:jo(t,e.layerCount),label:o(t)}))],lines:n};if(!t)return i;const r=Yj({srj:e});return pi(i,r)}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.getProblemVisualization(),e=this.getProblemVisualization({includeRoutes:!1}),n=this.polyGraphSolver?.visualize(),o=this.attachProjectedRectsSolver?.visualize(),i=this.highDensityRouteSolver?.visualize(),r=this.projectHighDensityToPolgonSolver?.visualize(),s=this.highDensityStitchSolver?.visualize(),a=this.traceSimplificationSolver?.visualize();return pi(...[t,this.escapeViaLocationSolver?.visualize(),this.netToPointPairsSolver?.visualize(),n,o,i?pi(e,i):null,r?pi(e,r):null,s,a,this.solved?pi({lines:e.lines},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean))}preview(){if(this.projectHighDensityToPolgonSolver){const t=[];for(let e=this.projectHighDensityToPolgonSolver.routes.length-1;e>=0;e--){const n=this.projectHighDensityToPolgonSolver.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.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.polyGraphSolver?this.polyGraphSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){return this.globalDrcForceImproveSolver?.getOutput()??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 o=n.__netConnectionName??this.originalSrj.connections.find(t=>t.name===n.name)?.__netConnectionName,i=e.filter(t=>t.connectionName===n.name);for(let e=0;e<i.length;e++){const r=i[e],s={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},sG=t=>t.rootConnectionName??t.connectionName,aG=(t,e)=>t.flatMap((t,n)=>sG(t)===e?[n]:[]),cG=(t,e,n,o)=>{const i=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,r=t.x-e.x,s=t.y-e.y,a=o**2+i**2,c=0===a?0:Math.max(0,Math.min(1,(r*o+s*i)/a));return Math.hypot(t.x-(e.x+c*o),t.y-(e.y+c*i))},r={x:e.x-t.x,y:e.y-t.y},s={x:o.x-n.x,y:o.y-n.y},a={x:n.x-t.x,y:n.y-t.y},c=(t,e)=>t.x*e.y-t.y*e.x,l=c(r,s),d=Math.hypot(r.x,r.y),h=1e-12*(d*Math.hypot(s.x,s.y)+1);if(Math.abs(l)>h){const t=c(a,s)/l,e=c(a,r)/l;if(t>=-1e-12&&t<=1+1e-12&&e>=-1e-12&&e<=1+1e-12)return 0}else if(d>1e-12&&Math.abs(c(a,r))<=h){const i=Math.abs(r.x)>=Math.abs(r.y),s=Math.min(i?t.x:t.y,i?e.x:e.y),a=Math.max(i?t.x:t.y,i?e.x:e.y),c=Math.min(i?n.x:n.y,i?o.x:o.y),l=Math.max(i?n.x:n.y,i?o.x:o.y);if(Math.max(s,c)<=Math.min(a,l)+1e-12)return 0}return Math.min(i(t,n,o),i(e,n,o),i(n,t,e),i(o,t,e))},lG=(t,e)=>Math.hypot(e.x-t.x,e.y-t.y),dG=t=>{let e=0;for(let n=0;n<t.route.length-1;n++)e+=lG(t.route[n],t.route[n+1]);return e},hG=(t,e)=>e.reduce((e,n)=>e+dG(t[n]),0),uG=(t,e)=>{const n=t.__zLayers,o=t.zLayers,i=void 0!==n?n:o;if(void 0!==i){if(!Array.isArray(i)||0===i.length||i.some(t=>!Number.isInteger(t)||t<0||t>=e))throw new Error("Obstacle has invalid z-layer indexes");return i}if(0===t.layers.length)throw new Error("Obstacle has no declared layers");return t.layers.map(t=>{if("top"===t)return 0;if("bottom"===t)return e-1;const n=/^inner(\d+)$/.exec(t),o=n?Number(n[1]):-1;if(o<=0||o>=e-1)throw new Error(`Obstacle has invalid layer name "${t}"`);return o})},pG=t=>{const e=(t,e,n,o)=>{const i=n.center.x-n.width/2-o,r=n.center.x+n.width/2+o,s=n.center.y-n.height/2-o,a=n.center.y+n.height/2+o;if(t.x>=i&&t.x<=r&&t.y>=s&&t.y<=a||e.x>=i&&e.x<=r&&e.y>=s&&e.y<=a)return!0;const c=[{x:i,y:s},{x:r,y:s},{x:r,y:a},{x:i,y:a}];return c.some((n,o)=>0===cG(t,e,n,c[(o+1)%c.length]))};if(t.bounds&&t.meanderPoints.some(e=>e.x<t.bounds.minX||e.x>t.bounds.maxX||e.y<t.bounds.minY||e.y>t.bounds.maxY))return!1;const n=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},o=sG(t.route),i=t.route.traceThickness/2+t.obstacleMargin;for(let r=0;r<t.meanderPoints.length-1;r++){const s=t.meanderPoints[r],a=t.meanderPoints[r+1];for(const n of t.obstacles){if(!uG(n,t.layerCount).includes(s.z))continue;const c=0===r||r===t.meanderPoints.length-2;if((!n.connectedTo.includes(o)||!c)&&e(s,a,n,i))return!1}for(const e of t.routedRoutes){const i=sG(e)===o;for(const o of e.vias){if(o.zLayers&&!o.zLayers.includes(s.z))continue;const r=Math.hypot(o.x-s.x,o.y-s.y)<=1e-8||Math.hypot(o.x-a.x,o.y-a.y)<=1e-8,c=t.route.traceThickness/2+e.viaDiameter/2+t.obstacleMargin;if((!i||!r)&&n(o,s,a)<c)return!1}if(!i)for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1];if(s.z!==o.z||s.z!==i.z)continue;const r=t.route.traceThickness/2+e.traceThickness/2+t.obstacleMargin;if(cG(s,a,o,i)<r)return!1}}}return!0},mG=t=>{const e=[];for(const n of t.routeIndexes){const o=t.routes[n],i=t.minMeanderGap??Math.max(.3,2*o.traceThickness),r=o.traceThickness+i,s=Math.max(t.minimumToothPitch??0,2*r),a=t.minMeanderHeight??r;for(let i=0;i<o.route.length-1;i++){const r=o.route[i],c=o.route[i+1],l=lG(r,c);if(l<=0||r.z!==c.z)continue;const d=Math.min(Math.max(0,Math.floor(l/s)-1),t.maxToothCount);for(let o=1;o<=d;o++){const r=l/(o+1),c=[r,Math.sqrt(s*r),s].filter((t,e,n)=>n.findIndex(e=>Math.abs(e-t)<1e-9)===e),d=o%2==0?["balanced","negative","positive"]:["negative","positive"];for(const r of c)for(const s of d)e.push({routeIndex:n,segmentIndex:i,segmentLength:l,toothCount:o,maximumDepth:t.maximumDepth,minimumHeight:a,toothPitch:r,placement:s,heightProfile:o>1?"tapered":"uniform"})}}}const n={balanced:0,negative:1,positive:2};return e.sort((t,e)=>t.toothCount-e.toothCount||n[t.placement]-n[e.placement]||e.toothPitch-t.toothPitch||e.segmentLength-t.segmentLength)},gG=t=>{if(null===t.centerlineDistanceCost)return 0;const e=t.predictedToothDepths.flatMap((t,e)=>t>0?[e]:[]);if(0===e.length)return 0;const n=e.map(e=>t.predictedToothDepths[e]),o=Math.max(...n),i=n.reduce((t,e)=>t+e,0)/n.length,r=Math.sqrt(n.reduce((t,e)=>t+(e-i)**2,0)/n.length),s=e[0],a=(e.at(-1)-s+1)*t.toothPitch,c=o/(t.toothPitch/2),l=t.addedLength/a,d=c/(1+c)*40,h=l/(1+l)*30,u=t.predictedToothDepths.map((e,n)=>Math.sin(Math.PI*(n+1)/(t.predictedToothDepths.length+1))),p=Math.max(...u),m=Math.sqrt(t.predictedToothDepths.reduce((t,e,n)=>t+(e-o*u[n]/p)**2,0)/t.predictedToothDepths.length),g=100-d-h-Math.min(10,("tapered"===t.heightProfile?m:r)/i*10)-2*(n.length-1)-7*Math.min(1,t.addedLength/t.segmentLength)-100*t.centerlineDistanceCost,f=t.centerlineDistanceCost>0?g:Math.max(0,g);return Math.round(1e6*f)/1e6},fG=t=>{if(t.toothDepths.length!==t.toothCount)throw new Error(`LengthMatchingSolver: expected ${t.toothCount} tooth depths, received ${t.toothDepths.length}`);if(t.toothDepths.some(t=>!Number.isFinite(t)||t<0))throw new Error("LengthMatchingSolver: every meander tooth depth must be a non-negative finite number");const e=t.route.route[t.segmentIndex],n=t.route.route[t.segmentIndex+1],o=lG(e,n),i=(n.x-e.x)/o,r=(n.y-e.y)/o,s=(o-(t.toothCount-.5)*t.toothPitch)/2,a=[{...e}];for(let n=0;n<t.toothCount;n++){const o=t.toothDepths[n];if(0===o)continue;const c="balanced"===t.placement?n%2==0?-1:1:"negative"===t.placement?-1:1,l={x:-r*c,y:i*c},d=s+n*t.toothPitch,h=d+t.toothPitch/2,u={...e,x:e.x+i*d,y:e.y+r*d};a.push(u,{...u,x:u.x+l.x*o,y:u.y+l.y*o},{...e,x:e.x+i*h+l.x*o,y:e.y+r*h+l.y*o},{...e,x:e.x+i*h,y:e.y+r*h})}return a.push({...n}),(t=>{if(t.length<3)return t;const e=[{...t[0]}];for(let n=1;n<t.length-1;n++){const o=t[n-1],i=t[n],r=t[n+1],s=Math.hypot(i.x-o.x,i.y-o.y),a=Math.hypot(r.x-i.x,r.y-i.y);if(0===s||0===a)throw new Error("LengthMatchingSolver: meander contains a zero-length segment");const c={x:(i.x-o.x)/s,y:(i.y-o.y)/s},l={x:(r.x-i.x)/a,y:(r.y-i.y)/a};if(Math.abs(c.x*l.y-c.y*l.x)<1e-9){e.push({...i});continue}const d=Math.min(s,a)/2,h={...i,x:i.x-c.x*d,y:i.y-c.y*d},u={...i,x:i.x+l.x*d,y:i.y+l.y*d},p=e.at(-1);h.x===p.x&&h.y===p.y||e.push(h);for(let t=1;t<6;t++){const n=t/6,o=1-n;e.push({...i,x:o**2*h.x+2*o*n*i.x+n**2*u.x,y:o**2*h.y+2*o*n*i.y+n**2*u.y})}e.push(u)}return e.push({...t[t.length-1]}),e})(a)},yG=t=>[...t.route.route.slice(0,t.segmentIndex),...fG(t),...t.route.route.slice(t.segmentIndex+2)],_G=t=>{const e=dG(t.route),n=(()=>{const e=[];for(let n=0;n<t.candidate.toothCount;n++){const o=Array(t.candidate.toothCount).fill(0);o[n]=t.candidate.maximumDepth;const i=fG({...t.candidate,route:t.route,toothDepths:o});if(t.isGeometryValid(i)){e.push(t.candidate.maximumDepth);continue}let r=0,s=t.candidate.maximumDepth;for(let e=0;e<32;e++){const e=(r+s)/2,o=Array(t.candidate.toothCount).fill(0);o[n]=e;const i=fG({...t.candidate,route:t.route,toothDepths:o});t.isGeometryValid(i)?r=e:s=e}e.push(r)}return e})(),o=(t=>{if("tapered"!==t.heightProfile)return Array(t.toothCount).fill(1);const e=Array.from({length:t.toothCount},(e,n)=>Math.sin(Math.PI*(n+1)/(t.toothCount+1))),n=Math.max(...e);return e.map(t=>t/n)})(t.candidate),i=t.candidate.maximumDepth,r=n.map((t,e)=>Math.min(t,i*o[e])),s=[.25,.75],a=r.map(t=>t*s[0]),c=r.map(t=>t*s[1]),l=yG({...t.candidate,route:t.route,toothDepths:a}),d=yG({...t.candidate,route:t.route,toothDepths:c}),h=[dG({...t.route,route:l})-e,dG({...t.route,route:d})-e],u=yG({...t.candidate,route:t.route,toothDepths:r}),p=dG({...t.route,route:u})-e,m=(h[1]-h[0])/(s[1]-s[0]),g=h[0]-m*s[0],f=m>0&&Number.isFinite(m)?(t.targetAddedLength-g)/m:0,y=Math.min(t.targetAddedLength,p),_=t.targetAddedLength>0&&y>0?(e=>{let n=0,o=t.candidate.maximumDepth;for(let i=0;i<32;i++){const i=(n+o)/2,r=e.maximumToothDepths.map((t,n)=>Math.min(t,i*e.toothHeightWeights[n])),s=yG({...t.candidate,route:t.route,toothDepths:r}),a=dG({...t.route,route:s})-e.originalLength,c=fG({...t.candidate,route:t.route,toothDepths:r});t.isGeometryValid(c)?a<e.targetAddedLength?n=i:o=i:o=i}const i=(n+o)/2;return{depthLevel:i,toothDepths:e.maximumToothDepths.map((t,n)=>Math.min(t,i*e.toothHeightWeights[n]))}})({maximumToothDepths:n,toothHeightWeights:o,originalLength:e,targetAddedLength:y}):{depthLevel:f*i,toothDepths:r.map(t=>Math.max(0,t*f))},b=_.depthLevel/i,x=_.toothDepths,v=yG({...t.candidate,route:t.route,toothDepths:x}),S=dG({...t.route,route:v})-e,I=Math.abs(y-S),C=fG({...t.candidate,route:t.route,toothDepths:x});let P=0;if(t.getCenterlineDistanceCost&&(P=t.getCenterlineDistanceCost(C)),null!==P&&(!Number.isFinite(P)||P<0))throw new Error("LengthMatchingSolver: meander centerline distance cost must be a non-negative finite number");const M=Number.isFinite(b)&&b>0&&b<=1,N=x.every(e=>0===e||e>=t.candidate.minimumHeight),w=t.isGeometryValid(C);let T,R=null;null===P?R="no-paired-same-layer-geometry":M?I>t.lengthTolerance?R="target-error":w?N||(R="below-minimum-height"):R="invalid-geometry":R="invalid-scale",T=R?{valid:!1,invalidReason:R}:{valid:!0,invalidReason:null};const E={...t.candidate,connectionName:t.connectionName,maximumToothDepths:n,sampleScaleFactors:s,sampleAddedLengths:h,slope:m,intercept:g,predictedScaleFactor:b,predictedToothDepths:x,predictedRoute:v,addedLength:S,maximumAddedLength:p,resultingError:I,testedSegment:[{...t.route.route[t.candidate.segmentIndex]},{...t.route.route[t.candidate.segmentIndex+1]}],meanderPoints:C,centerlineDistanceCost:P,qualityScore:0,...T};return{...E,qualityScore:gG(E)}},bG=t=>{const e=(t=>{if("tapered"!==t.heightProfile)return Array(t.toothCount).fill(1);const e=Array.from({length:t.toothCount},(e,n)=>Math.sin(Math.PI*(n+1)/(t.toothCount+1))),n=Math.max(...e);return e.map(t=>t/n)})(t.candidate),n=Math.max(...e.map(e=>t.candidate.minimumHeight/e)),o=t.candidate.maximumDepth/2**30,i=e.map(t=>t*(n+o));if(i.some(e=>e>t.candidate.maximumDepth))return null;const r=fG({...t.candidate,route:t.route,toothDepths:i});if(!t.isGeometryValid(r))return null;const s=yG({...t.candidate,route:t.route,toothDepths:i}),a=dG({...t.route,route:s})-dG(t.route),c=_G({...t,targetAddedLength:a});return c.valid?c:null},xG=t=>{const e=(t,e)=>{const n=t[e.routeIndex];if(!n)throw new Error(`LengthMatchingSolver: dual meander references missing route ${e.routeIndex}`);const o=[...t];return o[e.routeIndex]={...n,route:e.predictedRoute},o},n=(()=>{if(t.targetAddedLength+t.config.lengthTolerance<t.plan.minimumAddedLength||t.targetAddedLength-t.config.lengthTolerance>t.plan.maximumAddedLength)return null;const e=t.plan.attemptOptions.map(t=>Math.min(...t.map(t=>t.attempt.addedLength)));let n=Math.max(0,t.targetAddedLength-t.plan.minimumAddedLength),o=e.map((t,e)=>e);for(;n>1e-9&&o.length>0;){const i=n/o.length;let r=0;const s=[];for(const n of o){const o=Math.max(...t.plan.attemptOptions[n].map(t=>t.attempt.maximumAddedLength))-e[n],a=Math.min(o,i);e[n]+=a,r+=a,o-a>1e-9&&s.push(n)}if(r<=1e-9)break;n-=r,o=s}return n<=t.config.lengthTolerance?e:null})();if(!n)return null;const o=t.plan.attemptOptions.map((t,e)=>({attemptOptions:t,targetAddedLength:n[e]})).sort((t,e)=>e.attemptOptions[0].candidate.routeIndex-t.attemptOptions[0].candidate.routeIndex||e.attemptOptions[0].candidate.segmentIndex-t.attemptOptions[0].candidate.segmentIndex);let i=[...t.routes];const r=[];for(const n of o){const o=n.attemptOptions[0]?.candidate;if(!o)throw new Error("LengthMatchingSolver: empty dual-meander segment options");const s=i[o.routeIndex];if(!s)throw new Error(`LengthMatchingSolver: missing planned dual-meander route ${o.routeIndex}`);let a=null;for(const e of n.attemptOptions){if(e.attempt.addedLength-t.config.lengthTolerance>n.targetAddedLength||e.attempt.maximumAddedLength+t.config.lengthTolerance<n.targetAddedLength)continue;const o=_G({candidate:e.candidate,route:s,connectionName:t.connectionName,targetAddedLength:n.targetAddedLength,lengthTolerance:t.config.lengthTolerance,isGeometryValid:e=>pG({route:s,meanderPoints:e,routedRoutes:t.excludedConnectionName?i.filter(e=>sG(e)!==t.excludedConnectionName):i,...t.config})});o.valid&&(!a||o.qualityScore>a.qualityScore)&&(a=o)}if(!a)return null;i=e(i,a),r.push(a)}const s=r.reduce((t,e)=>t+e.addedLength,0);if(Math.abs(s-t.targetAddedLength)>t.config.lengthTolerance)return null;const a=r[0];if(!a)throw new Error("LengthMatchingSolver: fitted an empty dual-meander plan");return{attempts:[a,...r.slice(1)],routes:i,addedLength:s}},vG=t=>{if(0===t.length)throw new Error("LengthMatchingSolver: cannot score an empty meander plan");return t.reduce((t,e)=>t+e.qualityScore,0)/t.length-3*(t.length-1)},SG=t=>{const e=t=>[t.candidate.toothCount,t.candidate.placement,t.candidate.heightProfile].join(":"),n=new Map;for(const o of t){const t=e(o),i=`${o.candidate.routeIndex}:${o.candidate.segmentIndex}`,r=n.get(t);if(!r){n.set(t,new Map([[i,[o]]]));continue}const s=r.get(i);s?s.push(o):r.set(i,[o])}const o=[];for(const t of n.values()){const e=[...t.values()].map(t=>({attempts:t,maximumAddedLength:Math.max(...t.map(t=>t.attempt.maximumAddedLength)),minimumAddedLength:Math.min(...t.map(t=>t.attempt.addedLength)),rankingAttempt:t.reduce((t,e)=>e.attempt.qualityScore>t.attempt.qualityScore?e:t)})).sort((t,e)=>e.maximumAddedLength-t.maximumAddedLength);for(const t of e)o.push({attempts:[t.rankingAttempt],attemptOptions:[t.attempts],minimumAddedLength:t.minimumAddedLength,maximumAddedLength:t.maximumAddedLength,rankingQualityScore:t.rankingAttempt.attempt.qualityScore});for(let t=2;t<=e.length;t++){const n=e.slice(0,t),i=n.map(t=>t.rankingAttempt);o.push({attempts:i,attemptOptions:n.map(t=>t.attempts),minimumAddedLength:n.reduce((t,e)=>t+e.minimumAddedLength,0),maximumAddedLength:n.reduce((t,e)=>t+e.maximumAddedLength,0),rankingQualityScore:vG(i.map(t=>t.attempt))})}}return o},IG=class extends Error{connectionName;reason;constructor(t){super(t.message),this.name="LengthMatchingNoSolutionError",this.connectionName=t.connectionName,this.reason=t.reason}},CG=t=>[t.routeIndex,t.segmentIndex,t.toothCount,t.placement,t.toothPitch,t.heightProfile,t.maximumDepth,t.minimumHeight].join(":"),PG=t=>{const e=new Map,n=[...t.attempts].sort((t,e)=>t.addedLength-e.addedLength);let o=t.targetAddedLength;for(let t=0;t<n.length;t++){const i=n[t],r=Math.min(i.addedLength,o/(n.length-t));e.set(CG(i),{routeIndex:i.routeIndex,segmentIndex:i.segmentIndex,targetAddedLength:r}),o-=r}return e},MG=(t,e)=>`z${uG(t,e).join(",")}`,NG=t=>`z${t}`,wG=t=>{if(!t.showAttempt)return;if(!t.attempt)return void(t=>{const e=t.activePair?.candidates[t.activePair.candidateIndex];if(!e)return;const n=t.routes[e.routeIndex];if(!n)return;const o=n.route[e.segmentIndex],i=n.route[e.segmentIndex+1];o&&i&&t.graphics.lines.push({points:[o,i],strokeColor:"rgba(234, 179, 8, 0.6)",strokeWidth:2*n.traceThickness,strokeDash:[.1,.1],layer:NG(o.z)})})(t);const e=t.routes[t.attempt.routeIndex],[n,o]=t.attempt.testedSegment,i=t.theme.getConnectionColor(t.attempt.connectionName);t.graphics.lines.push({points:[n,o],strokeColor:t.theme.getTestedSegmentColor(i),strokeWidth:e.traceThickness,strokeDash:[.15,.15],layer:NG(n.z)}),t.attempt.valid?t.graphics.lines.push({points:t.attempt.meanderPoints.map(({x:t,y:e})=>({x:t,y:e})),strokeColor:"rgba(234, 179, 8, 0.6)",strokeWidth:2*e.traceThickness,strokeDash:[.1,.1],layer:NG(n.z)}):t.graphics.lines.push({points:t.attempt.meanderPoints.map(({x:t,y:e})=>({x:t,y:e})),strokeColor:t.theme.getRejectedCandidateColor(i),strokeWidth:e.traceThickness,strokeDash:[.1,.1],layer:NG(n.z)}),t.graphics.points.push({x:n.x,y:n.y,color:i,layer:NG(n.z)},{x:o.x,y:o.y,color:i,layer:NG(o.z)})},TG=t=>{const e={lines:[],points:[],rects:[],circles:[]},n=(t=>{for(const e of Object.values(t))Tt(0,e);return{getConnectionColor:(e,n)=>t[e]??(n?t[n]:void 0)??(t=>t?`hsl(${300*t.split("").reduce((t,e)=>t+e.charCodeAt(0),0)/t.length%360}, 100%, 50%)`:"rgba(0, 0, 0, 0.5)")(e),getInnerLayerConnectionColor:t=>Tt(.5,t),getTestedSegmentColor:t=>Tt(.55,t),getRejectedCandidateColor:t=>Tt(.45,t),boardBounds:{fill:"rgba(30,41,59,0.03)",stroke:"rgba(30,41,59,0.55)"},obstacle:{fill:"rgba(255,0,0,0.25)",stroke:"rgba(255,0,0,0.5)"},via:{fill:"blue",stroke:"none"}}})(t.colorMap);return(t=>{for(const e of t.routes){const n=sG(e),o=t.theme.getConnectionColor(n,e.connectionName);for(let n=0;n<e.route.length-1;n++){const i=e.route[n],r=e.route[n+1];i.z===r.z&&t.graphics.lines.push({points:[i,r],strokeColor:0===i.z?o:t.theme.getInnerLayerConnectionColor(o),strokeWidth:e.traceThickness,...0===i.z?{}:{strokeDash:[.2,.2]},layer:NG(i.z)})}const i=[...new Set(e.route.map(t=>t.z))];for(const n of e.vias)t.graphics.circles.push({center:n,radius:e.viaDiameter/2,fill:t.theme.via.fill,stroke:t.theme.via.stroke,layer:`z${(n.zLayers??i).join(",")}`})}})({routes:t.routes,theme:n,graphics:e}),(t=>{if(t.bounds){const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds;t.graphics.rects.push({center:{x:(e+n)/2,y:(o+i)/2},width:n-e,height:i-o,fill:t.theme.boardBounds.fill,stroke:t.theme.boardBounds.stroke,layer:`z${Array.from({length:t.layerCount},(t,e)=>e).join(",")}`})}for(const e of t.obstacles)t.graphics.rects.push({center:e.center,width:e.width,height:e.height,ccwRotationDegrees:e.ccwRotationDegrees,fill:t.theme.obstacle.fill,stroke:t.theme.obstacle.stroke,layer:MG(e,t.layerCount)})})({obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,theme:n,graphics:e}),wG({routes:t.routes,attempt:t.currentAttempt,activePair:t.activePair,showAttempt:!t.solved,theme:n,graphics:e}),{...e}},RG=class extends kt{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1e5,this.matchedHdRoutes=t.hdRoutes.map(t=>({...t,route:t.route.map(t=>({...t}))})),this.pairs=t.differentialPairs??[]}params;matchedHdRoutes;pairs;nextPairIndex=0;activePair=null;currentAttempt=null;config=null;candidatesTried=0;getSolverName(){return"LengthMatchingSolver"}startNextPair(){const t=this.pairs[this.nextPairIndex++];if(!t)return void(this.solved=!0);((t,e)=>{if(t.connectionNames[0]===t.connectionNames[1])throw new Error("LengthMatchingSolver: a differential pair must reference two distinct connections");if(!Number.isFinite(t.lengthTolerance)||t.lengthTolerance<0)throw new Error("LengthMatchingSolver: differential pair lengthTolerance must be a non-negative finite number");for(const e of[t.minimumCenterlineDistance,t.maximumCenterlineDistance])if(void 0!==e&&(!Number.isFinite(e)||e<=0))throw new Error("LengthMatchingSolver: differential pair centerline distances must be positive finite numbers");if(void 0!==t.minimumCenterlineDistance&&void 0!==t.maximumCenterlineDistance&&t.minimumCenterlineDistance>t.maximumCenterlineDistance)throw new Error("LengthMatchingSolver: differential pair minimumCenterlineDistance cannot exceed maximumCenterlineDistance");const n=new Map(e.map(t=>[t.name,t]));for(const e of t.connectionNames){const t=n.get(e);if(!t)throw new Error(`LengthMatchingSolver: differential pair references unknown connection "${e}"`);if(2!==t.pointsToConnect.length)throw new Error(`LengthMatchingSolver: differential pair connection "${e}" must have exactly two points before MST splitting`)}})(t,this.params.originalConnections);const e=aG(this.matchedHdRoutes,t.connectionNames[0]),n=aG(this.matchedHdRoutes,t.connectionNames[1]);if(0===e.length&&0===n.length)return;if(0===e.length||0===n.length)throw new Error(`LengthMatchingSolver: differential pair ${t.connectionNames.join("/")} has routed geometry for only one connection`);const o=hG(this.matchedHdRoutes,e),i=hG(this.matchedHdRoutes,n),r=Math.abs(o-i);if(r<=t.lengthTolerance)return;const s=o<i,a=t.connectionNames[s?0:1],c=t.connectionNames[s?1:0],l=mG({routes:this.matchedHdRoutes,routeIndexes:s?e:n,maximumDepth:this.getConfig().maximumMeanderDepth,minimumToothPitch:this.getConfig().minimumToothPitch,minMeanderGap:this.getConfig().minMeanderGap,minMeanderHeight:this.getConfig().minMeanderHeight,maxToothCount:this.getConfig().maxToothCount});if(0===l.length)throw new IG({message:`LengthMatchingSolver: no same-layer straight segment can tune connection "${a}"`,connectionName:a,reason:"no-meander-candidate"});this.activePair={pair:t,longerConnectionName:c,longerRouteIndexes:s?n:e,shorterConnectionName:a,targetAddedLength:r,remainingAddedLength:r,candidates:l,candidateIndex:0,lastMatchedSegmentIndexByRoute:new Map,partialAttempts:[],fullAttempts:[],plannedAttemptTargets:null,hasMinimumHeightBlockedAttempt:!1}}acceptAttempt(t,e){const n=this.matchedHdRoutes[e.routeIndex];this.matchedHdRoutes[e.routeIndex]={...n,route:e.predictedRoute},t.remainingAddedLength-=e.addedLength,t.lastMatchedSegmentIndexByRoute.set(e.routeIndex,e.segmentIndex),t.candidateIndex=0,t.partialAttempts=[],t.fullAttempts=[],t.plannedAttemptTargets?.delete(CG(e)),0===t.plannedAttemptTargets?.size&&(t.plannedAttemptTargets=null),t.remainingAddedLength<=t.pair.lengthTolerance&&(this.activePair=null)}tryCandidate(t){let e;for(;!e;){const n=t.candidates[t.candidateIndex++];if(!n)break;const o=t.lastMatchedSegmentIndexByRoute.get(n.routeIndex);(void 0===o||n.segmentIndex<o)&&(!t.plannedAttemptTargets||t.plannedAttemptTargets.has(CG(n))&&![...t.plannedAttemptTargets.values()].some(t=>t.routeIndex===n.routeIndex&&t.segmentIndex>n.segmentIndex))&&(e=n)}if(!e){const e=t.fullAttempts.reduce((t,e)=>!t||e.qualityScore>t.qualityScore?e:t,null),n=(t=>{const e=t=>[t.toothCount,t.placement,t.heightProfile].join(":"),n=new Map;for(const o of t.attempts){const t=`${o.routeIndex}:${o.segmentIndex}`,i=e(o),r=n.get(i);if(!r){n.set(i,new Map([[t,[o]]]));continue}const s=r.get(t);s?s.push(o):r.set(t,[o])}let o=null;for(const e of n.values()){const n=[...e.values()].map(t=>({attempts:t,maximumCapacityAttempt:t.reduce((t,e)=>e.addedLength>t.addedLength?e:t)})).sort((t,e)=>e.maximumCapacityAttempt.addedLength-t.maximumCapacityAttempt.addedLength);let i=0;for(let e=0;e<n.length;e++){if(i+=n[e].maximumCapacityAttempt.addedLength,i+t.lengthTolerance<t.targetAddedLength)continue;const r=n.slice(0,e+1),s=r.map(t=>t.maximumCapacityAttempt),a=PG({attempts:s,targetAddedLength:t.targetAddedLength}),c=r.map(e=>{const n=a.get(CG(e.maximumCapacityAttempt));if(!n)throw new Error(`LengthMatchingSolver: missing capacity target for ${CG(e.maximumCapacityAttempt)}`);const o=e.attempts.filter(e=>e.addedLength+t.lengthTolerance>=n.targetAddedLength);if(0===o.length)throw new Error(`LengthMatchingSolver: no pitch can supply planned target for route ${e.maximumCapacityAttempt.routeIndex} segment ${e.maximumCapacityAttempt.segmentIndex}`);return o.reduce((t,e)=>e.qualityScore>t.qualityScore||e.qualityScore===t.qualityScore&&e.toothPitch>t.toothPitch?e:t)}),l=vG(c);if(!o){o={attempts:c};break}const d=vG(o.attempts);(c.length<o.attempts.length||c.length===o.attempts.length&&l>d)&&(o={attempts:c});break}}return o})({attempts:t.partialAttempts,targetAddedLength:t.remainingAddedLength,lengthTolerance:t.pair.lengthTolerance});if(e&&(!n||e.qualityScore>=vG(n.attempts)))return void this.acceptAttempt(t,e);if(!n){if(!(t.hasMinimumHeightBlockedAttempt&&null===t.plannedAttemptTargets&&0===t.lastMatchedSegmentIndexByRoute.size))throw new IG({message:`LengthMatchingSolver: linear regression exhausted all segment/tooth combinations for "${t.shorterConnectionName}"; required ${t.targetAddedLength.toFixed(4)}mm`,connectionName:t.shorterConnectionName,reason:"meander-search-exhausted"});return this.tryDualMeanderPlan(t)}return t.plannedAttemptTargets=PG({attempts:n.attempts,targetAddedLength:t.remainingAddedLength}),t.candidateIndex=0,t.partialAttempts=[],void(t.fullAttempts=[])}const n=this.matchedHdRoutes[e.routeIndex],o=this.getConfig(),i=t.plannedAttemptTargets?.get(CG(e));if(null!==t.plannedAttemptTargets&&void 0===i)throw new Error(`LengthMatchingSolver: missing planned target for ${CG(e)}`);this.currentAttempt=_G({candidate:e,route:n,connectionName:t.shorterConnectionName,targetAddedLength:void 0===i?t.remainingAddedLength:i.targetAddedLength,lengthTolerance:t.pair.lengthTolerance,isGeometryValid:t=>pG({route:n,meanderPoints:t,routedRoutes:this.matchedHdRoutes,obstacles:o.obstacles,bounds:o.bounds,layerCount:o.layerCount,obstacleMargin:o.obstacleMargin}),getCenterlineDistanceCost:void 0===t.pair.minimumCenterlineDistance&&void 0===t.pair.maximumCenterlineDistance?void 0:e=>(t=>{let e=0,n=0;for(let o=0;o<t.meanderPoints.length-1;o++){const i=t.meanderPoints[o],r=t.meanderPoints[o+1],s=Math.hypot(r.x-i.x,r.y-i.y);if(0!==s){for(let e=0;e<4;e++){const o=(e+.5)/4,a={x:i.x+(r.x-i.x)*o,y:i.y+(r.y-i.y)*o},c=[];for(const e of t.pairedRoutes)for(let t=0;t<e.route.length-1;t++){const n=e.route[t],o=e.route[t+1];i.z===n.z&&i.z===o.z&&c.push(cG(a,a,n,o))}if(0===c.length)return null;const l=Math.min(...c);n+=s*Math.max(0,(t.minimumCenterlineDistance??Number.NEGATIVE_INFINITY)-l,l-(t.maximumCenterlineDistance??Number.POSITIVE_INFINITY))/4}e+=s}}if(0===e)throw new Error("LengthMatchingSolver: cannot measure a zero-length meander centerline");return n/e})({meanderPoints:e,pairedRoutes:t.longerRouteIndexes.map(t=>this.matchedHdRoutes[t]),minimumCenterlineDistance:t.pair.minimumCenterlineDistance,maximumCenterlineDistance:t.pair.maximumCenterlineDistance})}),this.candidatesTried++,"below-minimum-height"===this.currentAttempt.invalidReason&&(t.hasMinimumHeightBlockedAttempt=!0),this.stats={pair:`${t.pair.connectionNames[0]}/${t.pair.connectionNames[1]}`,candidatesTried:this.candidatesTried,segmentIndex:e.segmentIndex,toothCount:e.toothCount,toothPitch:e.toothPitch,placement:e.placement,predictedScaleFactor:this.currentAttempt.predictedScaleFactor,predictedToothDepths:this.currentAttempt.predictedToothDepths,resultingError:this.currentAttempt.resultingError,qualityScore:this.currentAttempt.qualityScore,accepted:this.currentAttempt.valid},this.currentAttempt.valid&&(null===t.plannedAttemptTargets?t.remainingAddedLength-this.currentAttempt.addedLength<=t.pair.lengthTolerance?t.fullAttempts.push(this.currentAttempt):t.partialAttempts.push(this.currentAttempt):this.acceptAttempt(t,this.currentAttempt))}tryDualMeanderPlan(t){if(t.remainingAddedLength!==t.targetAddedLength)throw new Error(`LengthMatchingSolver: cannot start a dual-meander plan after partially tuning "${t.shorterConnectionName}"`);const e=this.getConfig(),n=mG({routes:this.matchedHdRoutes,routeIndexes:t.longerRouteIndexes,maximumDepth:e.maximumMeanderDepth,minimumToothPitch:e.minimumToothPitch,minMeanderGap:e.minMeanderGap,minMeanderHeight:e.minMeanderHeight,maxToothCount:e.maxToothCount}),o=(t=>{const e=(t,e)=>t.rankingQualityScore!==e.rankingQualityScore?t.rankingQualityScore>e.rankingQualityScore:t.leftIndex!==e.leftIndex?t.leftIndex<e.leftIndex:t.rightIndex<e.rightIndex,n=(t,n)=>{t.push(n);let o=t.length-1;for(;o>0;){const i=Math.floor((o-1)/2),r=t[i];if(e(r,n))break;t[o]=r,o=i}t[o]=n},o=t=>{const n=t[0],o=t.pop();if(!n||!o||0===t.length)return n;let i=0;for(;;){const n=2*i+1,r=n+1;if(n>=t.length)break;const s=r<t.length&&e(t[r],t[n])?r:n,a=t[s];if(e(o,a))break;t[i]=a,i=s}return t[i]=o,n},i=function*(t){const e=[...t.leftOptions].sort((e,n)=>t.getLeftQualityScore(n)-t.getLeftQualityScore(e)),i=[...t.rightOptions].sort((e,n)=>t.getRightQualityScore(n)-t.getRightQualityScore(e)),r=[];for(let o=0;o<e.length;o++){const s=i[0];if(!s)break;n(r,{leftIndex:o,rightIndex:0,rankingQualityScore:(t.getLeftQualityScore(e[o])+t.getRightQualityScore(s))/2})}for(;r.length>0;){const s=o(r);yield[e[s.leftIndex],i[s.rightIndex]];const a=s.rightIndex+1,c=i[a];c&&n(r,{leftIndex:s.leftIndex,rightIndex:a,rankingQualityScore:(t.getLeftQualityScore(e[s.leftIndex])+t.getRightQualityScore(c))/2})}},r=(t,e)=>{const n=t[e.routeIndex];if(!n)throw new Error(`LengthMatchingSolver: dual meander references missing route ${e.routeIndex}`);const o=[...t];return o[e.routeIndex]={...n,route:e.predictedRoute},o},s=t=>{const e=t.routes[t.attempt.routeIndex];if(!e)throw new Error(`LengthMatchingSolver: cannot validate missing dual-meander route ${t.attempt.routeIndex}`);return pG({route:e,meanderPoints:t.attempt.meanderPoints,routedRoutes:t.routes,...t.config})},a=t=>{const e=t.routes.filter(e=>sG(e)!==t.counterpartConnectionName),n=[];for(const o of t.candidates){const i=t.routes[o.routeIndex];if(!i)throw new Error(`LengthMatchingSolver: dual-meander candidate references missing route ${o.routeIndex}`);const r=bG({candidate:o,route:i,connectionName:t.connectionName,lengthTolerance:t.config.lengthTolerance,isGeometryValid:n=>pG({route:i,meanderPoints:n,routedRoutes:e,...t.config})});r&&n.push({candidate:o,attempt:r})}return n},c={obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,obstacleMargin:t.obstacleMargin},l=a({candidates:t.shorterCandidates,routes:t.routes,connectionName:t.shorterConnectionName,counterpartConnectionName:t.longerConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(0===l.length)return null;const d=a({candidates:t.longerCandidates,routes:t.routes,connectionName:t.longerConnectionName,counterpartConnectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}}),h=i({leftOptions:d,rightOptions:l,getLeftQualityScore:t=>t.attempt.qualityScore,getRightQualityScore:t=>t.attempt.qualityScore});for(const[e,n]of h){const o=Math.max(e.attempt.addedLength,n.attempt.addedLength-t.originalLengthDifference),i=o+t.originalLengthDifference;if(o-t.lengthTolerance>e.attempt.maximumAddedLength||i-t.lengthTolerance>n.attempt.maximumAddedLength)continue;const a=t.routes[e.candidate.routeIndex];if(!a)throw new Error(`LengthMatchingSolver: missing longer route ${e.candidate.routeIndex}`);const l=t.routes[n.candidate.routeIndex];if(!l)throw new Error(`LengthMatchingSolver: missing shorter route ${n.candidate.routeIndex}`);const d=t.routes.filter(e=>sG(e)!==t.shorterConnectionName),h=_G({candidate:e.candidate,route:a,connectionName:t.longerConnectionName,targetAddedLength:o,lengthTolerance:t.lengthTolerance,isGeometryValid:t=>pG({route:a,meanderPoints:t,routedRoutes:d,...c})});if(!h.valid||Math.abs(h.addedLength-o)>t.lengthTolerance)continue;const u=r(t.routes,h),p=h.addedLength+t.originalLengthDifference,m=_G({candidate:n.candidate,route:l,connectionName:t.shorterConnectionName,targetAddedLength:p,lengthTolerance:t.lengthTolerance,isGeometryValid:t=>pG({route:l,meanderPoints:t,routedRoutes:u,...c})});if(!m.valid)continue;const g=r(u,m),f=aG(g,t.longerConnectionName),y=aG(g,t.shorterConnectionName);if(!(Math.abs(hG(g,y)-hG(g,f))>t.lengthTolerance)&&s({attempt:h,routes:g,config:c})&&s({attempt:m,routes:g,config:c}))return{longerAttempts:[h],shorterAttempts:[m]}}const u=i({leftOptions:SG(d),rightOptions:SG(l),getLeftQualityScore:t=>t.rankingQualityScore,getRightQualityScore:t=>t.rankingQualityScore});for(const[e,n]of u){if(1===e.attempts.length&&1===n.attempts.length)continue;const o=Math.max(e.minimumAddedLength,n.minimumAddedLength-t.originalLengthDifference),i=o+t.originalLengthDifference;if(o-t.lengthTolerance>e.maximumAddedLength||i-t.lengthTolerance>n.maximumAddedLength)continue;const r=xG({plan:e,targetAddedLength:o,routes:t.routes,connectionName:t.longerConnectionName,excludedConnectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(!r)continue;const a=xG({plan:n,targetAddedLength:r.addedLength+t.originalLengthDifference,routes:r.routes,connectionName:t.shorterConnectionName,config:{...c,lengthTolerance:t.lengthTolerance}});if(!a)continue;const l=aG(a.routes,t.longerConnectionName),d=aG(a.routes,t.shorterConnectionName),h=Math.abs(hG(a.routes,d)-hG(a.routes,l)),u=[...r.attempts,...a.attempts];if(!(h>t.lengthTolerance||u.some(t=>!s({attempt:t,routes:a.routes,config:c}))))return{longerAttempts:r.attempts,shorterAttempts:a.attempts}}return null})({routes:this.matchedHdRoutes,longerConnectionName:t.longerConnectionName,shorterConnectionName:t.shorterConnectionName,originalLengthDifference:t.targetAddedLength,lengthTolerance:t.pair.lengthTolerance,longerCandidates:n,shorterCandidates:t.candidates,obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,obstacleMargin:e.obstacleMargin});if(!o)throw new IG({message:`LengthMatchingSolver: linear regression exhausted all segment/tooth combinations for "${t.shorterConnectionName}"; required ${t.targetAddedLength.toFixed(4)}mm`,connectionName:t.shorterConnectionName,reason:"meander-search-exhausted"});const i=[...this.matchedHdRoutes];for(const t of[...o.longerAttempts,...o.shorterAttempts]){const e=this.matchedHdRoutes[t.routeIndex];if(!e)throw new Error(`LengthMatchingSolver: cannot commit dual meander to missing route ${t.routeIndex}`);i[t.routeIndex]={...e,route:t.predictedRoute}}this.matchedHdRoutes=i,this.currentAttempt=o.shorterAttempts[0];const r=o.longerAttempts.reduce((t,e)=>t+e.addedLength,0),s=o.shorterAttempts.reduce((t,e)=>t+e.addedLength,0);this.stats={pair:`${t.pair.connectionNames[0]}/${t.pair.connectionNames[1]}`,mode:"dual-meander",longerAddedLength:r,shorterAddedLength:s,resultingError:Math.abs(s-r-t.targetAddedLength)},this.activePair=null}getConfig(){return this.config||(this.config=(t=>{const e=t.maximumMeanderDepth??5,n=t.maxToothCount??12;if(!Number.isFinite(e)||e<=0)throw new Error("LengthMatchingSolver: maximumMeanderDepth must be a positive finite number");if(void 0!==t.minimumToothPitch&&(!Number.isFinite(t.minimumToothPitch)||t.minimumToothPitch<=0))throw new Error("LengthMatchingSolver: minimumToothPitch must be a positive finite number");if(void 0!==t.minMeanderGap&&(!Number.isFinite(t.minMeanderGap)||t.minMeanderGap<=0))throw new Error("LengthMatchingSolver: minMeanderGap must be a positive finite number");if(void 0!==t.minMeanderHeight&&(!Number.isFinite(t.minMeanderHeight)||t.minMeanderHeight<=0))throw new Error("LengthMatchingSolver: minMeanderHeight must be a positive finite number");if(void 0!==t.minMeanderHeight&&t.minMeanderHeight>e)throw new Error("LengthMatchingSolver: minMeanderHeight cannot exceed maximumMeanderDepth");if(!Number.isFinite(n)||!Number.isInteger(n)||n<=0)throw new Error("LengthMatchingSolver: maxToothCount must be a positive finite integer");return{maximumMeanderDepth:e,minimumToothPitch:t.minimumToothPitch,minMeanderGap:t.minMeanderGap,minMeanderHeight:t.minMeanderHeight,maxToothCount:n,obstacles:t.obstacles??[],bounds:t.bounds,obstacleMargin:t.obstacleMargin??.15,layerCount:t.layerCount??2,colorMap:t.colorMap??{}}})(this.params)),this.config}_step(){this.getConfig(),this.activePair?this.tryCandidate(this.activePair):this.startNextPair()}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved)throw new Error("LengthMatchingSolver: getOutput() called before the solver completed");return{matchedHdRoutes:this.matchedHdRoutes}}getBestEffortOutput(){const t=structuredClone(this.matchedHdRoutes),e=this.activePair?.fullAttempts??[];let n=null;for(const t of e)(!n||t.qualityScore>n.qualityScore)&&(n=t);if(!n)for(const t of this.activePair?.partialAttempts??[])(!n||t.addedLength>n.addedLength||t.addedLength===n.addedLength&&t.qualityScore>n.qualityScore)&&(n=t);if(n){const e=t[n.routeIndex];e&&(t[n.routeIndex]={...e,route:structuredClone(n.predictedRoute)})}return{matchedHdRoutes:t}}computeProgress(){if(this.solved)return 1;if(0===this.pairs.length)return this.config?1:0;const t=Math.max(0,this.nextPairIndex-1),e=this.activePair?this.activePair.candidateIndex/this.activePair.candidates.length:0;return Math.min(.99,(t+e)/this.pairs.length)}visualize(){const t=this.getConfig();return TG({routes:this.matchedHdRoutes,obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,colorMap:t.colorMap,activePair:this.activePair,currentAttempt:this.currentAttempt,solved:this.solved})}},EG=(t,e)=>{if("top"===t)return 0;if("bottom"===t)return e-1;const n=/^inner(\d+)$/.exec(t);if(!n)return-1;const o=Number(n[1]);return o>0&&o<e-1?o:-1},AG=(t,e)=>0===t?"top":t===e-1?"bottom":`inner${t}`,OG=(t,e,n)=>{const o=EG(t,n),i=EG(e,n);if(o<0||i<0)return[];const r=Math.min(o,i),s=Math.max(o,i);return Array.from({length:s-r+1},(t,e)=>AG(r+e,n))},kG=1e-8,LG=(t,e)=>{if(0===t.route.length)throw new Error(`trace "${t.connection_name}" has an empty route`);if(t.route.some(t=>"wire"!==t.route_type&&"via"!==t.route_type))throw new Error(`trace "${t.connection_name}" contains unsupported jumper or through-obstacle geometry`);const n=t.route.findIndex(t=>"wire"===t.route_type),o=t.route[n],i=t.route.findLast(t=>"wire"===t.route_type);if("wire"!==o?.route_type||!i)throw new Error(`trace "${t.connection_name}" must contain a wire point`);const r=[],s=[],a=[],c=[];let l=null,d=o.width;if(n>0){let e=o.layer;for(let o=n-1;o>=0;o--){const n=t.route[o];if("via"!==n?.route_type)throw new Error(`trace "${t.connection_name}" has unsupported geometry before its first wire`);if(e===n.to_layer)e=n.from_layer;else{if(e!==n.from_layer)throw new Error(`trace "${t.connection_name}" has discontinuous leading vias`);e=n.to_layer}}const i=t.route[0];if("via"!==i.route_type)throw new Error(`trace "${t.connection_name}" has an invalid leading entry`);l={x:i.x,y:i.y,layer:e,width:o.width},r.push(l)}for(const n of t.route){if("wire"===n.route_type){if(!Number.isFinite(n.x)||!Number.isFinite(n.y)||!Number.isFinite(n.width)||n.width<=0||EG(n.layer,e)<0)throw new Error(`trace "${t.connection_name}" has an invalid wire point`);d=Math.max(d,n.width);const o={x:n.x,y:n.y,layer:n.layer,width:n.width};if(l){if(l.layer!==o.layer)throw new Error(`trace "${t.connection_name}" changes layers without a via`);Math.hypot(l.x-o.x,l.y-o.y)>kG&&s.push({start:l,end:o,layer:o.layer,width:Math.max(l.width,o.width),connectionName:t.connection_name,terminal:null})}r.push(o),l=o;continue}if("via"!==n.route_type)throw new Error(`trace "${t.connection_name}" contains unsupported route geometry`);if(!l)throw new Error(`trace "${t.connection_name}" has a leading via`);const o=EG(n.from_layer,e),i=EG(n.to_layer,e),h=n.via_diameter??l.width;if(!Number.isFinite(n.x)||!Number.isFinite(n.y)||o<0||i<0||o===i||void 0!==n.via_diameter&&(!Number.isFinite(n.via_diameter)||n.via_diameter<=0)||void 0!==n.via_hole_diameter&&(!Number.isFinite(n.via_hole_diameter)||n.via_hole_diameter<=0||n.via_hole_diameter>=h))throw new Error(`trace "${t.connection_name}" has an invalid via`);const u=l.layer===n.from_layer?n.from_layer:l.layer===n.to_layer?n.to_layer:null;if(!u)throw new Error(`trace "${t.connection_name}" has a discontinuous via transition`);Math.hypot(l.x-n.x,l.y-n.y)>kG&&s.push({start:l,end:n,layer:l.layer,width:l.width,connectionName:t.connection_name,terminal:null});const p=u===n.from_layer?n.to_layer:n.from_layer;c.push({...n,from_layer:u,to_layer:p}),a.push({x:n.x,y:n.y,layers:OG(u,p,e),diameter:h,connectionName:t.connection_name,terminal:1===r.length?"start":null}),l={x:n.x,y:n.y,layer:p,width:l.width},r.push(l)}if(r.length<2||0===s.length)throw new Error(`trace "${t.connection_name}" does not contain a routable path`);s[0].terminal=1===s.length?"both":"start",s[s.length-1].terminal=1===s.length?"both":"end";const h=a.at(-1);return h&&Math.hypot(h.x-i.x,h.y-i.y)<=kG&&(h.terminal="end"),{source:t,points:r,segments:s,vias:a,transitions:c,width:d,viaDiameter:t.__postProcessingViaDiameter??d,...o.start_pcb_port_id?{startPortId:o.start_pcb_port_id}:{},...i.end_pcb_port_id?{endPortId:i.end_pcb_port_id}:{}}},DG=(t,e)=>{const n=[],o=[],i=t.route.find(t=>"wire"===t.route_type),r="wire"===i?.route_type?i.width:null,s={"0603":.95,1206:1.8,"1206x4_pair":1.8};let a=null;for(let i=0;i<t.route.length;i++){const c=t.route[i];if("wire"===c.route_type){if(!Number.isFinite(c.x)||!Number.isFinite(c.y)||!Number.isFinite(c.width)||c.width<=0||EG(c.layer,e)<0)throw new Error(`PostProcessingSolver: immutable trace "${t.connection_name}" has an invalid wire`);if(a&&a.layer!==c.layer)throw new Error(`PostProcessingSolver: immutable trace "${t.connection_name}" changes layer without a transition`);a&&n.push({start:a,end:c,layer:c.layer,width:Math.max(a.width,c.width),connectionName:t.connection_name,terminal:null}),a=c;continue}if("via"===c.route_type){const s=OG(c.from_layer,c.to_layer,e),l=a,d=c.via_diameter??l?.width??r;if(!Number.isFinite(c.x)||!Number.isFinite(c.y)||s.length<2||null===d||!Number.isFinite(d)||d<=0||void 0!==c.via_hole_diameter&&(!Number.isFinite(c.via_hole_diameter)||c.via_hole_diameter<=0||null!==d&&c.via_hole_diameter>=d))throw new Error(`PostProcessingSolver: immutable trace "${t.connection_name}" has an invalid via`);l&&Math.hypot(l.x-c.x,l.y-c.y)>1e-8&&n.push({start:l,end:c,layer:l.layer,width:l.width,connectionName:t.connection_name,terminal:null}),o.push({x:c.x,y:c.y,layers:s,diameter:d,connectionName:t.connection_name,terminal:0===i?"start":i===t.route.length-1?"end":null});const h=t.route.slice(i+1).find(t=>"wire"===t.route_type),u=l?.layer===c.from_layer?c.to_layer:l?.layer===c.to_layer?c.from_layer:"wire"!==h?.route_type||h.layer!==c.from_layer&&h.layer!==c.to_layer?null:h.layer;if(!u)throw new Error(`PostProcessingSolver: immutable trace "${t.connection_name}" has a discontinuous via`);a={x:c.x,y:c.y,layer:u,width:l?.width??r??d};continue}if("jumper"===c.route_type){const o=s[c.footprint];if(!Number.isFinite(c.start.x)||!Number.isFinite(c.start.y)||!Number.isFinite(c.end.x)||!Number.isFinite(c.end.y)||EG(c.layer,e)<0)throw new Error(`PostProcessingSolver: immutable trace "${t.connection_name}" has an invalid jumper`);if(a&&(a.layer!==c.layer||Math.hypot(a.x-c.start.x,a.y-c.start.y)>1e-8))throw new Error(`PostProcessingSolver: immutable trace "${t.connection_name}" has a discontinuous jumper`);n.push({start:c.start,end:c.end,layer:c.layer,width:o,connectionName:t.connection_name,terminal:null}),a={...c.end,layer:c.layer,width:o};continue}const l=OG(c.from_layer,c.to_layer,e);if(!Number.isFinite(c.start.x)||!Number.isFinite(c.start.y)||!Number.isFinite(c.end.x)||!Number.isFinite(c.end.y)||!Number.isFinite(c.width)||c.width<=0||l.length<2)throw new Error(`PostProcessingSolver: immutable trace "${t.connection_name}" has invalid through-obstacle copper`);if(a&&(a.layer!==c.from_layer&&a.layer!==c.to_layer||Math.hypot(a.x-c.start.x,a.y-c.start.y)>1e-8))throw new Error(`PostProcessingSolver: immutable trace "${t.connection_name}" has discontinuous through-obstacle copper`);for(const e of l)n.push({start:c.start,end:c.end,layer:e,width:c.width,connectionName:t.connection_name,terminal:null});const d=a,h=d?.layer===c.to_layer?c.from_layer:c.to_layer;a={...c.end,layer:h,width:c.width}}return{segments:n,vias:o}},zG=(t,e)=>{const n=DG(t,e);return[...n.segments.map((n,o)=>({connectionName:`${t.connection_name}#immutable-segment-${o}`,rootConnectionName:t.connection_name,traceThickness:n.width,viaDiameter:n.width,route:[{x:n.start.x,y:n.start.y,z:EG(n.layer,e),traceThickness:n.width},{x:n.end.x,y:n.end.y,z:EG(n.layer,e),traceThickness:n.width}],vias:[]})),...n.vias.map((n,o)=>({connectionName:`${t.connection_name}#immutable-via-${o}`,rootConnectionName:t.connection_name,traceThickness:n.diameter,viaDiameter:n.diameter,route:[],vias:[{x:n.x,y:n.y,zLayers:n.layers.map(t=>EG(t,e))}]}))]},FG=t=>t.segments.reduce((t,e)=>t+Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),0),BG=t=>{const{simpleRouteJson:e}=t.params,n=(t=>{const e=new Set(t.reroutedPairs.map(t=>t.connectionNames.join("\0")));return t.declaredPairs.filter(n=>{const o=n.connectionNames.map(e=>t.traces.filter(t=>t.connection_name===e));if(o.some(t=>1!==t.length))return!1;if(e.has(n.connectionNames.join("\0")))return!0;const i=o.map(t=>t[0]);if(i.some(t=>t.route.length<2||"wire"!==t.route[0]?.route_type||!t.route.every(t=>"wire"===t.route_type||"via"===t.route_type)))return!1;const r=i.map(e=>FG(LG(e,t.layerCount)));return Math.abs(r[0]-r[1])>n.lengthTolerance+1e-7}).map(t=>structuredClone(t))})({traces:t.result.traces,declaredPairs:e.differentialPairs,reroutedPairs:t.result.reroutedPairs,layerCount:e.layerCount}),o=new Set(n.flatMap(t=>t.connectionNames)),i=[],r=[],s=[],a=new Set;for(let n=0;n<t.result.traces.length;n++){const c=t.result.traces[n];if(!o.has(c.connection_name))continue;const l=c.route.every(t=>"wire"===t.route_type||"via"===t.route_type),d="wire"===c.route[0]?.route_type;if(!l||!d)throw new Error(`PostProcessingSolver: rerouted connection "${c.connection_name}" cannot be bound to LengthMatchingSolver`);const h=LG(c,e.layerCount),u=c.route[0];if("wire"!==u.route_type)throw new Error(`PostProcessingSolver: trace "${c.connection_name}" lost its first wire during binding`);const p=[{x:u.x,y:u.y,z:EG(u.layer,e.layerCount),traceThickness:u.width}],m=[],g=[];let f=u.layer,y=u.width;for(const t of c.route.slice(1)){if("wire"===t.route_type){if(t.layer!==f)throw new Error(`PostProcessingSolver: trace "${c.connection_name}" changes layers without a via while binding`);p.push({x:t.x,y:t.y,z:EG(t.layer,e.layerCount),traceThickness:t.width}),y=t.width;continue}if("via"!==t.route_type)throw new Error(`PostProcessingSolver: trace "${c.connection_name}" contains unsupported bound geometry`);const n=f===t.from_layer?t.to_layer:f===t.to_layer?t.from_layer:null;if(!n)throw new Error(`PostProcessingSolver: trace "${c.connection_name}" has a discontinuous bound via`);const o=p.at(-1);Math.hypot(o.x-t.x,o.y-t.y)>1e-8&&p.push({x:t.x,y:t.y,z:EG(f,e.layerCount),traceThickness:y}),p.push({x:t.x,y:t.y,z:EG(n,e.layerCount),traceThickness:y}),m.push({x:t.x,y:t.y,zLayers:OG(t.from_layer,t.to_layer,e.layerCount).map(t=>EG(t,e.layerCount))}),g.push({...t}),f=n}if(p.length<2)throw new Error(`PostProcessingSolver: trace "${c.connection_name}" has no bound copper segments`);const _=Math.max(...p.map(t=>t.traceThickness??h.width)),b=h.viaDiameter,x=i.length;i.push({connectionName:c.connection_name,traceThickness:_,viaDiameter:b,route:p,vias:m});const v=p[0],S=p.at(-1);r.push({name:c.connection_name,pointsToConnect:[{x:v.x,y:v.y,layer:u.layer,...h.startPortId?{pcb_port_id:h.startPortId}:{}},{x:S.x,y:S.y,layer:h.points.at(-1).layer,...h.endPortId?{pcb_port_id:h.endPortId}:{}}]}),s.push({traceIndex:n,matchedRouteIndex:x,viaTemplates:g,startEndpoint:{...v},endEndpoint:{...S},...h.startPortId?{startPortId:h.startPortId}:{},...h.endPortId?{endPortId:h.endPortId}:{}}),a.add(c.connection_name)}for(const t of o)if(!a.has(t))throw new Error(`PostProcessingSolver: missing LengthMatchingSolver binding for rerouted connection "${t}"`);for(const n of t.result.traces)o.has(n.connection_name)||i.push(...zG(n,e.layerCount));const c=e.minTraceToPadEdgeClearance??Math.max(0,...i.filter(t=>t.route.length>=2).map(t=>t.traceThickness));return{solverParams:{hdRoutes:i,originalConnections:r,differentialPairs:n,obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,obstacleMargin:c},traceBindings:s,baseTraces:structuredClone(t.result.traces)}},jG=t=>{const e=new Map;for(const n of t.differentialPairs)for(const o of n.connectionNames){const n=t.hdRoutes.map((t,e)=>({route:t,hdRouteIndex:e})).filter(({route:t})=>t.connectionName===o);1===n.length&&e.set(n[0].hdRouteIndex,o)}const n=t.hdRoutes.map((e,n)=>{const o=[],i=new Map;for(let t=0;t<(e.jumpers?.length??0);t++){const n=e.jumpers[t],o=e.route.map((t,e)=>({point:t,index:e})).filter(({point:t})=>Math.hypot(t.x-n.start.x,t.y-n.start.y)<=1e-8).map(({index:t})=>t),r=e.route.map((t,e)=>({point:t,index:e})).filter(({point:t})=>Math.hypot(t.x-n.end.x,t.y-n.end.y)<=1e-8).map(({index:t})=>t),s=[...o.flatMap(t=>r.filter(e=>e>t).map(e=>({startIndex:t,endIndex:e}))),...r.flatMap(t=>o.filter(e=>e>t).map(e=>({startIndex:t,endIndex:e})))];if(1!==s.length)throw new Error(`PostProcessingSolver: immutable HD route "${e.connectionName}" has an ambiguous jumper traversal`);const a=s[0];if(i.has(a.startIndex)||[...i.values()].some(({endIndex:t})=>a.startIndex<t||a.endIndex<=t))throw new Error(`PostProcessingSolver: immutable HD route "${e.connectionName}" has overlapping or unordered jumpers`);i.set(a.startIndex,{endIndex:a.endIndex,jumperIndex:t})}if(e.route.length>0){const n=e.route[0];o.push({route_type:"wire",x:n.x,y:n.y,width:n.traceThickness??e.traceThickness,layer:AG(n.z,t.layerCount)});for(let n=0;n<e.route.length-1;n++){const r=e.route[n],s=i.get(n);if(s){const i=e.route[s.endIndex],a=e.jumpers[s.jumperIndex];if(r.z!==i.z)throw new Error(`PostProcessingSolver: immutable HD route "${e.connectionName}" changes layers through a jumper`);o.push({route_type:"jumper",start:{x:r.x,y:r.y},end:{x:i.x,y:i.y},footprint:a.footprint,layer:AG(r.z,t.layerCount)}),o.push({route_type:"wire",x:i.x,y:i.y,width:i.traceThickness??e.traceThickness,layer:AG(i.z,t.layerCount)}),n=s.endIndex-1;continue}const a=e.route[n+1],c=AG(r.z,t.layerCount),l=AG(a.z,t.layerCount);r.z!==a.z&&("through_obstacle"===r.toNextSegmentType?o.push({route_type:"through_obstacle",start:{x:r.x,y:r.y},end:{x:a.x,y:a.y},from_layer:c,to_layer:l,width:r.traceThickness??e.traceThickness}):o.push({route_type:"via",x:a.x,y:a.y,from_layer:c,to_layer:l,via_diameter:e.viaDiameter})),o.push({route_type:"wire",x:a.x,y:a.y,width:a.traceThickness??e.traceThickness,layer:l})}const r=o.filter(t=>"wire"===t.route_type),s=e.startPcbPortId??e.route[0]?.pcb_port_id,a=e.endPcbPortId??e.route.at(-1)?.pcb_port_id;s&&r[0]&&(r[0].start_pcb_port_id=s),a&&r.at(-1)&&(r.at(-1).end_pcb_port_id=a)}return{type:"pcb_trace",pcb_trace_id:`post_processing_hd_route_${n}`,connection_name:e.connectionName,__postProcessingViaDiameter:e.viaDiameter,route:o}}),o=structuredClone(t.obstacles);for(let n=0;n<t.hdRoutes.length;n++){const i=t.hdRoutes[n],r=new Set([i.connectionName,i.rootConnectionName,i.startPcbPortId,i.endPcbPortId,i.route[0]?.pcb_port_id,i.route.at(-1)?.pcb_port_id,e.get(n)].filter(t=>void 0!==t));for(const t of o)t.connectedTo.some(t=>r.has(t))&&(t.connectedTo=[...new Set([...t.connectedTo,...r])])}return{params:{simpleRouteJson:{traces:n,differentialPairs:structuredClone(t.differentialPairs),obstacles:o,bounds:structuredClone(t.bounds),layerCount:t.layerCount,minTraceToPadEdgeClearance:t.minTraceToPadEdgeClearance},...t.routingGrid?{routingGrid:structuredClone(t.routingGrid)}:{}},routeBindings:[...e.entries()].map(([t,e])=>({hdRouteIndex:t,traceIndex:t,internalConnectionName:e})),sourceHdRoutes:structuredClone(t.hdRoutes)}};function $G(t){const e=structuredClone(t.model.sourceHdRoutes);for(const n of t.model.routeBindings){const o=t.binding.traceBindings.find(t=>t.traceIndex===n.traceIndex);if(!o)continue;const i=t.result.matchedHdRoutes[o.matchedRouteIndex],r=e[n.hdRouteIndex];if(!i||!r)throw new Error(`PostProcessingSolver: missing matched or source HD route for "${n.internalConnectionName}"`);if(i.connectionName!==n.internalConnectionName)throw new Error(`PostProcessingSolver: matched HD binding changed "${n.internalConnectionName}" to "${i.connectionName}"`);const s=i.route.map(t=>({...t})),a=(e,o)=>{if(e&&o&&(o.pcb_port_id&&(e.pcb_port_id=o.pcb_port_id),o.insideJumperPad&&t.rejectInsideJumperPad))throw new Error(`PostProcessingSolver: cannot restore jumper-pad metadata on rerouted connection "${n.internalConnectionName}"`)};a(s[0],r.route[0]),a(s.at(-1),r.route.at(-1)),e[n.hdRouteIndex]={...r,route:s,vias:structuredClone(i.vias)}}return{hdRoutes:e,postProcessingErrors:[]}}var YG=class extends Error{connectionNames;reason;constructor(t){super(`PostProcessingSolver: differential pair ${t.connectionNames.join("/")} ${t.message}`),this.name="DifferentialPairRoutingError",this.connectionNames=[t.connectionNames[0],t.connectionNames[1]],this.reason=t.reason}},XG=class extends Error{connectionNames;reason;constructor(t){super(t.message),this.name="PostProcessingConstraintError",this.connectionNames=[...t.connectionNames],this.reason=t.reason}},VG=class extends Error{reason="grid-capacity-exhausted";constructor(t){super(t),this.name="PostProcessingGridCapacityError"}},WG=t=>{const e=75e3*t.simpleRouteJson.differentialPairs.length;if(!Number.isSafeInteger(e))throw new Error("PostProcessingSolver: derived rerouting iteration bound exceeds the safe integer range");const n=Math.min(e,8e4);return Math.max(1,n)},HG=t=>structuredClone(t),GG=(t,e,n)=>{const o=t=>{const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}},i=o(t.start),r=o(t.end),s=e.width/2+n,a=e.height/2+n;if(Math.abs(i.x)<=s&&Math.abs(i.y)<=a||Math.abs(r.x)<=s&&Math.abs(r.y)<=a)return!0;const c=[{x:-s,y:-a},{x:s,y:-a},{x:s,y:a},{x:-s,y:a}];return c.some((t,e)=>cG(i,r,t,c[(e+1)%c.length])<=1e-7)},UG=t=>{const e=[],n=[];for(const o of t.immutableTraces){const i=DG(o,t.layerCount);e.push(...i.segments),n.push(...i.vias)}const o=Array.from({length:t.layerCount},()=>[]);for(const n of e){const e=EG(n.layer,t.layerCount);o[e].push(n)}const i=(t,e)=>Math.hypot(t.x-e.x,t.y-e.y)<=1e-8,r=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-e.x-o*s,t.y-e.y-i*s)},s=(t,e,n)=>{const o=-(e.ccwRotationDegrees??0)*Math.PI/180,i=t.x-e.center.x,r=t.y-e.center.y,s=i*Math.cos(o)-r*Math.sin(o),a=i*Math.sin(o)+r*Math.cos(o);return Math.abs(s)<=e.width/2+n&&Math.abs(a)<=e.height/2+n},a=(e,n)=>{const o=EG(n,t.layerCount);return uG(e,t.layerCount).includes(o)},c=(e,n,o)=>{const i=((e,n,o)=>{const i=Math.hypot(n.x,n.y);if(i<=1e-10)throw new Error("PostProcessingSolver: cannot orient terminal fanout on a zero-length spine");const r=-n.y/i*t.side*t.centerlineSpacing/2,s=n.x/i*t.side*t.centerlineSpacing/2,a="start"===o?[t.firstStartTerminal,t.secondStartTerminal]:[t.firstEndTerminal,t.secondEndTerminal],c=[t.firstWidth,t.secondWidth],l=[t.firstConnectionName,t.secondConnectionName];return a.map((t,n)=>{const i=0===n?1:-1,a={x:e.x+r*i,y:e.y+s*i};return{start:"start"===o?t:a,end:"start"===o?a:t,layer:e.layer,width:c[n],connectionName:l[n],terminal:o}})})(e,n,o),r=i.map(t=>"start"===o?t.end:t.start);return i.every(l)&&r.every((n,o)=>t.obstacles.every(r=>!a(r,e.layer)||!s(n,r,1.5*i[o].width+(t.terminalMiterMargin??0))))&&cG(i[0].start,i[0].end,i[1].start,i[1].end)>=i[0].width/2+i[1].width/2-1e-7},l=e=>{const i=e.width/2,c=i+(t.minTraceToPadEdgeClearance??e.width),l=EG(e.layer,t.layerCount),d=Math.min(e.start.x,e.end.x),h=Math.max(e.start.x,e.end.x),u=Math.min(e.start.y,e.end.y),p=Math.max(e.start.y,e.end.y);for(const n of[e.start,e.end])if(n.x-i<t.bounds.minX||n.x+i>t.bounds.maxX||n.y-i<t.bounds.minY||n.y+i>t.bounds.maxY)return!1;for(const n of t.obstacles){if(!a(n,e.layer))continue;const o=Math.hypot(n.width/2+c,n.height/2+c);if(h<n.center.x-o||d>n.center.x+o||p<n.center.y-o||u>n.center.y+o)continue;const[i,r]=e.connectionName===t.firstConnectionName?[t.firstStartTerminal,t.firstEndTerminal]:[t.secondStartTerminal,t.secondEndTerminal],l=s(i,n,0)&&(s(e.start,n,c)||s(e.end,n,c))&&Math.hypot(e.end.x-i.x,e.end.y-i.y)>=Math.hypot(e.start.x-i.x,e.start.y-i.y),m=s(r,n,0)&&(s(e.start,n,c)||s(e.end,n,c))&&Math.hypot(e.end.x-r.x,e.end.y-r.y)<=Math.hypot(e.start.x-r.x,e.start.y-r.y);if(!(n.connectedTo.includes(e.connectionName)&&(l||m))&&GG(e,n,c))return!1}for(const t of o[l]){const n=e.width/2+t.width/2+Math.max(e.width,t.width);if(!(h+n<Math.min(t.start.x,t.end.x)||d-n>Math.max(t.start.x,t.end.x)||p+n<Math.min(t.start.y,t.end.y)||u-n>Math.max(t.start.y,t.end.y))&&cG(e.start,e.end,t.start,t.end)<n)return!1}for(const t of n)if(t.layers.includes(e.layer)&&r(t,e.start,e.end)<e.width/2+t.diameter/2+e.width)return!1;return!0},d=o=>{const i=o.diameter/2;if(o.x-i<t.bounds.minX||o.x+i>t.bounds.maxX||o.y-i<t.bounds.minY||o.y+i>t.bounds.maxY)return!1;for(const e of t.obstacles){if(!o.layers.some(t=>a(e,t)))continue;if(!(null!==o.terminal&&e.connectedTo.includes(o.connectionName)&&s(o,e,0))&&s(o,e,i+o.diameter))return!1}for(const t of e){if(!o.layers.includes(t.layer))continue;const e=i+t.width/2+Math.max(o.diameter,t.width);if(r(o,t.start,t.end)<e)return!1}for(const t of n){if(!t.layers.some(t=>o.layers.includes(t)))continue;const e=i+t.diameter/2+Math.max(o.diameter,t.diameter);if(Math.hypot(o.x-t.x,o.y-t.y)<e)return!1}return!0};return{isEdgeValid:(e,n)=>{if(e.layer!==n.layer||!((e,n)=>{const o=Math.hypot(n.x-e.x,n.y-e.y);if(0===o)return[];const r=-(n.y-e.y)/o*t.side*t.centerlineSpacing/2,s=(n.x-e.x)/o*t.side*t.centerlineSpacing/2,a=i(e,t.start),c=i(n,t.end),l=t.terminalFanout?a&&c?"both":a?"start":c?"end":null:null,d=a&&t.terminalFanout?t.firstStartTerminal:{x:e.x+r,y:e.y+s},h=c&&t.terminalFanout?t.firstEndTerminal:{x:n.x+r,y:n.y+s},u=a&&t.terminalFanout?t.secondStartTerminal:{x:e.x-r,y:e.y-s},p=c&&t.terminalFanout?t.secondEndTerminal:{x:n.x-r,y:n.y-s};return[{start:d,end:h,layer:e.layer,width:t.firstWidth,connectionName:t.firstConnectionName,terminal:l},{start:u,end:p,layer:e.layer,width:t.secondWidth,connectionName:t.secondConnectionName,terminal:l}]})(e,n).every(l))return!1;if(t.terminalFanout||void 0===t.terminalMiterMargin)return!0;const o={x:n.x-e.x,y:n.y-e.y};return!(i(e,t.start)&&!c(e,o,"start"))&&!(i(n,t.end)&&!c(n,o,"end"))},isTerminalFanoutValid:c,isViaValid:(e,n,o)=>{const r=Math.hypot(o.x,o.y);if(r<=1e-10)throw new Error("PostProcessingSolver: cannot orient a coupled via on a zero-length spine");const s=OG(e.layer,n,t.layerCount),a=-o.y/r*t.side*t.centerlineSpacing/2,c=o.x/r*t.side*t.centerlineSpacing/2,l=i(e,t.start)?"start":i(e,t.end)?"end":null;return[{x:e.x+a,y:e.y+c,layers:s,diameter:t.firstViaDiameter,connectionName:t.firstConnectionName,terminal:l},{x:e.x-a,y:e.y-c,layers:s,diameter:t.secondViaDiameter,connectionName:t.secondConnectionName,terminal:l}].every(d)}}},ZG=(t,e,n)=>{const o=1e-7,i=(t,e)=>{const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}},r=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},s=(t,e,n)=>{const o=EG(e,n);return uG(t,n).includes(o)},a=(t,e,n)=>{const a=t.width/2;if(t.start.x-a<e.bounds.minX-o||t.start.x+a>e.bounds.maxX+o||t.start.y-a<e.bounds.minY-o||t.start.y+a>e.bounds.maxY+o||t.end.x-a<e.bounds.minX-o||t.end.x+a>e.bounds.maxX+o||t.end.y-a<e.bounds.minY-o||t.end.y+a>e.bounds.maxY+o)return!1;for(const n of e.obstacles){if(!s(n,t.layer,e.layerCount))continue;const r="both"===t.terminal?[t.start,t.end]:"start"===t.terminal?[t.start]:"end"===t.terminal?[t.end]:[];if(!(n.connectedTo.includes(t.connectionName)&&r.some(t=>{const e=i(t,n);return Math.abs(e.x)<=n.width/2+o&&Math.abs(e.y)<=n.height/2+o}))&&GG(t,n,a+(e.minTraceToPadEdgeClearance??t.width)))return!1}for(const e of n.segments){if(e.layer!==t.layer)continue;const n=t.width/2+e.width/2+Math.max(t.width,e.width);if(cG(t.start,t.end,e.start,e.end)<n-o)return!1}for(const e of n.vias){if(!e.layers.includes(t.layer))continue;const n=t.width/2+e.diameter/2+t.width;if(r(e,t.start,t.end)<n-o)return!1}return!0},c=(t,e,n)=>{const a=t.diameter/2;if(t.x-a<e.bounds.minX-o||t.x+a>e.bounds.maxX+o||t.y-a<e.bounds.minY-o||t.y+a>e.bounds.maxY+o)return!1;for(const n of e.obstacles){if(!t.layers.some(t=>s(n,t,e.layerCount)))continue;const r=i(t,n);if(!(null!==t.terminal&&n.connectedTo.includes(t.connectionName)&&Math.abs(r.x)<=n.width/2+o&&Math.abs(r.y)<=n.height/2+o)&&Math.abs(r.x)<=n.width/2+a+t.diameter&&Math.abs(r.y)<=n.height/2+a+t.diameter)return!1}for(const e of n.segments){if(!t.layers.includes(e.layer))continue;const n=a+e.width/2+Math.max(t.diameter,e.width);if(r(t,e.start,e.end)<n-o)return!1}for(const e of n.vias){if(!e.layers.some(e=>t.layers.includes(e)))continue;const n=a+e.diameter/2+Math.max(t.diameter,e.diameter);if(Math.hypot(t.x-e.x,t.y-e.y)<n-o)return!1}return!0},l=t=>{for(let e=0;e<t.segments.length;e++){const n=t.segments[e];for(let i=e+2;i<t.segments.length;i++){const r=t.segments[i];if(n.layer!==r.layer)continue;if(!(t.segments.slice(e+1,i).reduce((t,e)=>t+Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),0)<=n.width+r.width+o)&&cG(n.start,n.end,r.start,r.end)<n.width/2+r.width/2-o)return!0}}for(const e of t.vias)for(const n of t.segments){if(!e.layers.includes(n.layer))continue;if(!(Math.hypot(e.x-n.start.x,e.y-n.start.y)<=o||Math.hypot(e.x-n.end.x,e.y-n.end.y)<=o)&&r(e,n.start,n.end)<e.diameter/2+n.width/2-o)return!0}return!1},d=((t,e)=>{const n=[],o=[];for(const i of t){const t=DG(i,e);n.push(...t.segments),o.push(...t.vias)}return{segments:n,vias:o}})(n.immutableTraces,n.layerCount);if(!((t,e)=>{for(const n of t.segments)for(const t of e.segments){if(n.layer!==t.layer)continue;const e=n.width/2+t.width/2;if(cG(n.start,n.end,t.start,t.end)<e-o)return!1}for(const[n,i]of[[t.vias,e.segments],[e.vias,t.segments]])for(const t of n)for(const e of i)if(t.layers.includes(e.layer)&&r(t,e.start,e.end)<t.diameter/2+e.width/2-o)return!1;for(const n of t.vias)for(const t of e.vias)if(n.layers.some(e=>t.layers.includes(e))&&Math.hypot(n.x-t.x,n.y-t.y)<n.diameter/2+t.diameter/2-o)return!1;return!0})(t,e)||l(t)||l(e))return!1;for(const o of[t,e])if(o.segments.some(t=>!a(t,n,d))||o.vias.some(t=>!c(t,n,d)))return!1;return!0},qG=[{x:1,y:0},{x:1,y:1},{x:0,y:1},{x:-1,y:1},{x:-1,y:0},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1}],JG=class{constructor(t){this.input=t;const{bounds:e,grid:n}=t,o={minX:e.minX+n.outerPerimeterWidth,maxX:e.maxX-n.outerPerimeterWidth,minY:e.minY+n.outerPerimeterWidth,maxY:e.maxY-n.outerPerimeterWidth},i=this.createAxis(e.minX,e.maxX,n.outerGridStep,[o.minX,o.maxX]),r=this.createAxis(e.minY,e.maxY,n.outerGridStep,[o.minY,o.maxY]),s=this.createAxis(o.minX,o.maxX,n.innerGridStep,[],t.start.x),a=this.createAxis(o.minY,o.maxY,n.innerGridStep,[],t.start.y),c=this.createGrid(i,r,t=>t.x<=o.minX||t.x>=o.maxX||t.y<=o.minY||t.y>=o.maxY),l=this.createGrid(s,a,()=>!0);this.connectLocalNeighbors(c),this.connectLocalNeighbors(l);for(const t of["left","right","bottom","top"])this.connectBoundaries(t,c,l,o);const d=this.nodes.map((t,e)=>e);this.connectEndpoint(t.start,d),this.connectEndpoint(t.end,d)}input;nodes=[];nodeIdByPoint=new Map;endpointNodeIdByPoint=new Map;getPlanarNeighbors(t){const e=this.endpointNodeIdByPoint.get(this.exactKeyFor(t))??this.nodeIdByPoint.get(this.keyFor(t));if(void 0===e)throw new Error(`PostProcessingSolver: coupled path point (${t.x}, ${t.y}) is not on the composite grid`);return[...this.nodes[e].neighborIds].map(e=>({...this.nodes[e].point,layer:t.layer}))}getNodeCount(){return this.nodes.length}getSearchStateCountUpperBound(t){const e=this.nodes.reduce((t,e)=>t+e.neighborIds.size,0)*t+1;if(!Number.isSafeInteger(e))throw new Error("PostProcessingSolver: composite-grid search-state bound exceeds the safe integer range");return e}createAxis(t,e,n,o,i=t){const r=[t,e,...o].map(t=>({value:t,fixed:!0}));for(let o=Math.ceil((t-i)/n);i+o*n<e-1e-8;o++)r.push({value:i+o*n,fixed:!1});r.sort((t,e)=>t.value-e.value||Number(e.fixed)-Number(t.fixed));const s=[];for(const t of r){const e=s.at(-1);!e||Math.abs(t.value-e.value)>1e-8?s.push(t):t.fixed&&!e.fixed&&(s[s.length-1]=t)}return s.map(t=>t.value)}createGrid(t,e,n){return e.map(e=>t.map(t=>{const o={x:t,y:e};return n(o)?this.addNode(o):null}))}connectLocalNeighbors(t){for(let e=0;e<t.length;e++)for(let n=0;n<(t[e]?.length??0);n++){const o=t[e][n];if(null!==o)for(const i of qG){const r=t[e+i.y]?.[n+i.x];null!=r&&this.connect(o,r)}}}connectBoundaries(t,e,n,o){const i="left"===t?o.minX:"right"===t?o.maxX:"bottom"===t?o.minY:o.maxY,r="left"===t||"right"===t,s=t=>Math.abs((r?t.x:t.y)-i)<=1e-8,a=t=>{const e=new Set;for(const n of t)for(const t of n)null!==t&&s(this.nodes[t].point)&&e.add(t);return[...e].sort((t,e)=>{const n=this.nodes[t].point,o=this.nodes[e].point;return(r?n.y-o.y:n.x-o.x)||t-e})},c=a(e),l=a(n);if(0===c.length||0===l.length)throw new Error(`PostProcessingSolver: composite grid has no ${t} boundary bridge candidates`);for(const t of c)this.connect(t,this.findNearestAlongBoundary(t,l,r));for(const t of l)this.connect(t,this.findNearestAlongBoundary(t,c,r))}findNearestAlongBoundary(t,e,n){const o=this.nodes[t].point;let i=e[0],r=Number.POSITIVE_INFINITY;for(const t of e){const e=this.nodes[t].point,s=Math.abs(n?o.y-e.y:o.x-e.x);(s<r-1e-8||Math.abs(s-r)<=1e-8&&t<i)&&(r=s,i=t)}return i}connectEndpoint(t,e){const n=this.nodeIdByPoint.get(this.keyFor(t)),o=void 0===n?null:this.nodes[n].point,i=o?.x===t.x&&o.y===t.y?n:this.nodes.push({point:{x:t.x,y:t.y},neighborIds:new Set})-1;this.endpointNodeIdByPoint.set(this.exactKeyFor(t),i);const r=(t,n)=>{const o=this.nodes[t].point,i=e.filter(e=>e!==t).map(t=>({nodeId:t,distance:Math.hypot(this.nodes[t].point.x-o.x,this.nodes[t].point.y-o.y)})).filter(({distance:t})=>t>1e-10).sort((t,e)=>t.distance-e.distance||t.nodeId-e.nodeId).slice(0,n);if(0===i.length)throw new Error("PostProcessingSolver: composite grid has no endpoint connection candidates");for(const{nodeId:e}of i)this.connect(t,e)};r(i,8);for(const e of qG){const n={x:t.x+e.x*this.input.grid.innerGridStep,y:t.y+e.y*this.input.grid.innerGridStep};if(n.x<this.input.bounds.minX||n.x>this.input.bounds.maxX||n.y<this.input.bounds.minY||n.y>this.input.bounds.maxY)continue;const o=this.addNode(n);this.connect(i,o),r(o,4)}}addNode(t){const e=this.keyFor(t),n=this.nodeIdByPoint.get(e);if(void 0!==n)return n;const o=this.nodes.length;return this.nodes.push({point:{x:t.x,y:t.y},neighborIds:new Set}),this.nodeIdByPoint.set(e,o),o}connect(t,e){if(t===e)return;const n=this.nodes[t],o=this.nodes[e];n.neighborIds.add(e),o.neighborIds.add(t)}keyFor(t){const e=Object.is(t.x,-0)?0:t.x,n=Object.is(t.y,-0)?0:t.y;return`${e.toFixed(12)}:${n.toFixed(12)}`}exactKeyFor(t){return`${Object.is(t.x,-0)?0:t.x}:${Object.is(t.y,-0)?0:t.y}`}},KG=class{constructor(t){if(this.input=t,this.startLayer=EG(t.start.layer,t.layerCount),this.endLayer=EG(t.end.layer,t.layerCount),this.grid=new JG(t),this.maxSearchStates=this.grid.getSearchStateCountUpperBound(t.layerCount),this.exploredStateLimit=Math.min(this.maxSearchStates,2e4),this.startLayer<0||this.endLayer<0)return this.queue=[],void(this.status="exhausted");const e={point:t.start,direction:null,cost:0,estimate:this.estimate(t.start),parent:null,sequence:0};this.queue=[e],this.bestCosts.set(this.keyFor(t.start,null),0)}input;queue;bestCosts=new Map;startLayer;endLayer;grid;maxSearchStates;exploredStateLimit;current=null;result=null;status="searching";explored=0;nextSequence=1;isComplete(){return"searching"!==this.status}getPath(){return this.result}getPreviewPath(){return this.current?this.createPath(this.current):[this.input.start]}getExploredCount(){return this.explored}getProgress(){return"searching"!==this.status?1:Math.min(.99,this.explored/this.exploredStateLimit)}getGridNodeCount(){return this.grid.getNodeCount()}step(){if("searching"!==this.status)return;const t=this.popQueue();if(!t)return void(this.status="exhausted");const e=this.bestCosts.get(this.keyFor(t.point,t.direction));if(void 0===e)throw new Error("PostProcessingSolver: coupled path queue contains an untracked state");if(t.cost>e+1e-10)0===this.queue.length&&(this.status="exhausted");else{if(this.current=t,this.explored++,this.explored>this.maxSearchStates)throw new Error(`PostProcessingSolver: coupled path search exceeded its ${this.maxSearchStates}-state graph invariant limit`);if(this.isEnd(t.point)){const e=this.createPath(t);return e[e.length-1]=this.input.end,this.result=this.simplifyPath(e),void(this.status="found")}this.explored>=this.exploredStateLimit?this.status="exhausted":(this.enqueuePlanarNeighbors(t),this.enqueueViaNeighbors(t),0===this.queue.length&&(this.status="exhausted"))}}isEnd(t){return t.layer===this.input.end.layer&&t.x===this.input.end.x&&t.y===this.input.end.y}estimate(t){return Math.hypot(t.x-this.input.end.x,t.y-this.input.end.y)+3*Math.abs(EG(t.layer,this.input.layerCount)-this.endLayer)}keyFor(t,e){return`${Object.is(t.x,-0)?0:t.x}:${Object.is(t.y,-0)?0:t.y}:${t.layer}:${e?.key??"start"}`}createDirection(t,e){const n=e.x-t.x,o=e.y-t.y,i=Math.hypot(n,o);if(i<=1e-10)throw new Error("PostProcessingSolver: composite grid produced a zero-length planar edge");const r=n/i,s=o/i;return{x:r,y:s,key:`${r.toFixed(6)}:${s.toFixed(6)}`}}createPath(t){const e=[];let n=t;for(;n;)e.push(n.point),n=n.parent;return e.reverse()}simplifyPath(t){return t.filter((e,n)=>{if(0===n||n===t.length-1)return!0;const o=t[n-1],i=t[n+1],r={x:e.x-o.x,y:e.y-o.y},s={x:i.x-e.x,y:i.y-e.y},a=r.x*s.y-r.y*s.x,c=Math.hypot(r.x,r.y)*Math.hypot(s.x,s.y);return Math.abs(a)>1e-10*c||e.layer!==o.layer||e.layer!==i.layer})}hasHigherQueuePriority(t,e){return t.estimate!==e.estimate?t.estimate<e.estimate:t.cost!==e.cost?t.cost<e.cost:t.point.x!==e.point.x?t.point.x<e.point.x:t.point.y!==e.point.y?t.point.y<e.point.y:t.point.layer!==e.point.layer?t.point.layer<e.point.layer:t.sequence<e.sequence}pushQueue(t){this.queue.push(t);let e=this.queue.length-1;for(;e>0;){const n=Math.floor((e-1)/2),o=this.queue[n];if(!this.hasHigherQueuePriority(t,o))break;this.queue[e]=o,e=n}this.queue[e]=t}popQueue(){const t=this.queue[0],e=this.queue.pop();if(!t||!e||0===this.queue.length)return t;let n=0;for(;;){const t=2*n+1;if(t>=this.queue.length)break;const o=t+1;let i=t;o<this.queue.length&&this.hasHigherQueuePriority(this.queue[o],this.queue[t])&&(i=o);const r=this.queue[i];if(!this.hasHigherQueuePriority(r,e))break;this.queue[n]=r,n=i}return this.queue[n]=e,t}enqueuePlanarNeighbors(t){for(const e of this.grid.getPlanarNeighbors(t.point)){if(!this.input.isEdgeValid(t.point,e))continue;const n=this.createDirection(t.point,e),o=null===t.direction||t.direction.key===n.key?0:.18,i=t.cost+Math.hypot(e.x-t.point.x,e.y-t.point.y)+o,r=this.keyFor(e,n);(this.bestCosts.get(r)??Number.POSITIVE_INFINITY)<=i||(this.bestCosts.set(r,i),this.pushQueue({point:e,direction:n,cost:i,estimate:i+this.estimate(e),parent:t,sequence:this.nextSequence++}))}}enqueueViaNeighbors(t){if(!t.direction)return;const e=EG(t.point.layer,this.input.layerCount);for(const n of[e-1,e+1]){if(n<0||n>=this.input.layerCount)continue;const e=AG(n,this.input.layerCount);if(!this.input.isViaValid(t.point,e,t.direction))continue;const o={...t.point,layer:e},i=t.cost+4,r=this.keyFor(o,t.direction);(this.bestCosts.get(r)??Number.POSITIVE_INFINITY)<=i||(this.bestCosts.set(r,i),this.pushQueue({point:o,direction:t.direction,cost:i,estimate:i+this.estimate(o),parent:t,sequence:this.nextSequence++}))}}},QG=t=>{const e=Math.min(t.bounds.maxX-t.bounds.minX,t.bounds.maxY-t.bounds.minY),n=t.config?.innerGridStep??t.defaultInnerGridStep,o=t.config?.outerGridStep??4*n,i=t.config?.outerPerimeterWidth??Math.min(o,e/4);if(!Number.isFinite(n)||n<1e-4)throw new Error("PostProcessingSolver: routingGrid.innerGridStep must be finite and at least 0.0001");if(!Number.isFinite(o)||o<=n)throw new Error("PostProcessingSolver: routingGrid.outerGridStep must be finite and greater than innerGridStep");if(!Number.isFinite(i)||i<=0||2*i>=e)throw new Error("PostProcessingSolver: routingGrid.outerPerimeterWidth must be finite, positive, and less than half the smaller board extent");const r=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY;if((Math.ceil(r/o)+4)*(Math.ceil(s/o)+4)+(Math.ceil((r-2*i)/n)+2)*(Math.ceil((s-2*i)/n)+2)+18>25e4)throw new VG("PostProcessingSolver: valid input exceeds the 250000-node optimization grid capacity");return{innerGridStep:n,outerGridStep:o,outerPerimeterWidth:i}},tU=t=>{const e=-t.pathDirection.y,n=t.pathDirection.x,o=Math.tan(t.maximumTurnDegrees*Math.PI/180),i=Math.max(0,...t.lanes.map(({point:i,polarity:r})=>{const s=i.x-t.anchor.x,a=i.y-t.anchor.y,c=s*t.escapeDirection.x+a*t.escapeDirection.y,l=s*e+a*n,d=r*t.side*t.centerlineSpacing/2;return c+Math.abs(l-d)/o})),r=t.maxUncoupledLength??i;if(i>r+1e-8)return null;const s=Math.max(.05,Math.min(.25,t.searchStep/2)),a=Math.max(1,Math.ceil((r-i)/s)+1);for(let o=0;o<a;o++){const a=Math.min(r,i+o*s),c={x:t.anchor.x+t.escapeDirection.x*a,y:t.anchor.y+t.escapeDirection.y*a,layer:t.anchor.layer};if(t.lanes.every(({point:o,polarity:i})=>{const r=i*t.side*t.centerlineSpacing/2,s=c.x+e*r,a=c.y+n*r;return void 0===t.maxUncoupledLength||Math.hypot(s-o.x,a-o.y)<=t.maxUncoupledLength+1e-8})&&t.isValid(c))return c}return null},eU=[.75,.5,1,.25,1.25],nU=100,oU=class{constructor(t){this.input=t,this.pairName=t.pair.connectionNames.join("/"),this.prepared=this.prepare()}input;pairName;prepared;candidates=[];result=null;search=null;nextAttempt=0;exploredNodeCount=0;isComplete(){return null!==this.result}getResult(){if(!this.result)throw new Error(`PostProcessingSolver: differential pair ${this.pairName} is not complete`);return this.result}getPreviewPath(){return this.search?.getPreviewPath()??null}getProgress(){if(this.result)return 1;const t=this.prepared.attempts.length,e=this.search?.getProgress()??0;return Math.min(.99,(this.nextAttempt+e)/t)}getStats(){return{phase:this.search?"searching":"candidate-selection",pair:this.pairName,attemptIndex:this.nextAttempt,attemptCount:this.prepared.attempts.length,exploredNodeCount:this.exploredNodeCount+(this.search?.getExploredCount()??0),gridNodeCount:this.search?.getGridNodeCount()??0,acceptedCandidateCount:this.candidates.length}}step(){if(this.result)return;const t=this.prepared;if(!this.search){const e=t.attempts[this.nextAttempt];return e?void(this.search=new KG(e.input)):void this.complete()}if(this.search.step(),!this.search.isComplete())return;const e=this.search.getPath();this.exploredNodeCount+=this.search.getExploredCount();const n=t.attempts[this.nextAttempt];if(!n)throw new Error(`PostProcessingSolver: differential pair ${this.pairName} lost its active attempt`);if(this.search=null,this.nextAttempt++,!e)return;const o=(t=>{const e=(t,e)=>Math.hypot(t.x-e.x,t.y-e.y)<=1e-8;if(t.path.length<2)throw new Error("PostProcessingSolver: coupled path has fewer than two stations");const n=(n,o)=>{for(let i=n+o;i>=0&&i<t.path.length;i+=o){const o=t.path[i];if(!e(o,t.path[n]))return o}return null},o=e=>{const o=t.path[e],i=n(e,-1),r=n(e,1),s=(t,e)=>{const n=e.x-t.x,o=e.y-t.y,i=Math.hypot(n,o);if(i<=1e-10)throw new Error("PostProcessingSolver: cannot offset a zero-length spine");return{x:-o/i,y:n/i}},a=t.side*t.centerlineSpacing/2;if(!i||!r){const t=s(i??o,r??o);return{x:t.x*a,y:t.y*a}}if(t.terminalFanout&&1===e)return s(i,o);if(t.terminalFanout&&e===t.path.length-2)return s(o,r);if(t.terminalFanout&&t.path[e+1]?.layer!==o.layer)return s(i,o);const c=s(i,o),l=s(o,r),d={x:c.x+l.x,y:c.y+l.y},h=Math.hypot(d.x,d.y);if(h<=1e-10)return null;const u=d.x/h,p=d.y/h,m=a/(u*c.x+p*c.y);return{x:u*m,y:p*m}},i=t.first.points[0],r=t.first.points.at(-1),s=t.reverseSecond?t.second.points.at(-1):t.second.points[0],a=t.reverseSecond?t.second.points[0]:t.second.points.at(-1),c=[[{route_type:"wire",x:i.x,y:i.y,width:i.width,layer:i.layer}],[{route_type:"wire",x:s.x,y:s.y,width:s.width,layer:s.layer}]],l=[t.first.transitions[0],t.second.transitions[0]];let d=0;const h=t.terminalFanout?1:0,u=t.path.length-2,p=t.path[u],m=t.path[u-1],g=t.terminalFanout&&p?.layer===r.layer&&m?.layer===p.layer,f=t.terminalFanout?g?u-1:t.path.length-1:t.path.length;for(let n=h;n<f;n++){const i=t.path[n],r=o(n);if(!r)return null;for(const o of[0,1]){const s=0===o?1:-1,a={x:i.x+r.x*s,y:i.y+r.y*s},d=c[o],h=t.path[n-1];if(h&&h.layer!==i.layer){if(!e(h,i))throw new Error("PostProcessingSolver: a coupled layer transition moved in the plane");const n=[...d].reverse().find(t=>"wire"===t.route_type);if(!n)throw new Error("PostProcessingSolver: generated via has no preceding wire");const r=l[o];d.push({route_type:"via",x:n.x,y:n.y,from_layer:h.layer,to_layer:i.layer,via_diameter:r?.via_diameter??(0===o?t.first.viaDiameter:t.second.viaDiameter),...void 0!==r?.via_hole_diameter?{via_hole_diameter:r.via_hole_diameter}:{}}),d.push({route_type:"wire",x:n.x,y:n.y,width:0===o?t.first.width:t.second.width,layer:i.layer})}else{const n=d.at(-1);"wire"===n?.route_type&&e(n,a)&&n.layer===i.layer||d.push({route_type:"wire",...a,width:0===o?t.first.width:t.second.width,layer:i.layer})}}t.path[n-1]?.layer!==i.layer&&n>0&&d++}const y=(e,n)=>{const o=e.at(-1);if(!o||"wire"!==o.route_type)throw new Error("PostProcessingSolver: terminal fanout has no preceding wire");const i=e.at(-2);let r=!1;if("wire"===i?.route_type&&i.layer===o.layer&&o.layer===n.layer){const t={x:o.x-i.x,y:o.y-i.y},e={x:n.x-o.x,y:n.y-o.y},s=Math.hypot(t.x,t.y),a=Math.hypot(e.x,e.y);if(s>1e-8&&a>1e-8&&Math.abs(t.x*e.x+t.y*e.y)<=1e-8){const e={x:o.x-t.x/s*a,y:o.y-t.y/s*a};(e.x-i.x)*(t.x/s)+(e.y-i.y)*(t.y/s)>1e-8&&(o.x=e.x,o.y=e.y,r=!0)}}t.terminalFanout&&!r&&o.x!==n.x&&o.y!==n.y&&e.push({route_type:"wire",x:n.x,y:o.y,width:n.width,layer:n.layer}),e.push({route_type:"wire",x:n.x,y:n.y,width:n.width,layer:n.layer})};y(c[0],r),y(c[1],a),t.reverseSecond&&(c[1]=c[1].reverse().map(t=>"via"===t.route_type?{...t,from_layer:t.to_layer,to_layer:t.from_layer}:t));const _=(t,e)=>{const n=t.filter(t=>"wire"===t.route_type);for(const t of n)delete t.start_pcb_port_id,delete t.end_pcb_port_id;e.startPortId&&(n[0].start_pcb_port_id=e.startPortId),e.endPortId&&(n.at(-1).end_pcb_port_id=e.endPortId)};_(c[0],t.first),_(c[1],t.second);const b={...t.first.source,route:c[0]},x={...t.second.source,route:c[1]};return{first:b,second:x,firstParsed:LG(b,t.layerCount),secondParsed:LG(x,t.layerCount),edgeGap:t.edgeGap,centerlineDistance:t.centerlineSpacing,bendCount:Math.max(0,t.path.length-d-2),viaPairCount:d}})({first:t.first,second:t.second,reverseSecond:t.reverseSecond,path:e,centerlineSpacing:n.edgeGap+t.first.width/2+t.second.width/2,edgeGap:n.edgeGap,side:n.side,layerCount:this.input.layerCount,terminalFanout:t.terminalFanout});o&&ZG(o.firstParsed,o.secondParsed,t.context)&&this.candidates.push(o)}prepare(){const t=this.input.traces.map((t,e)=>({trace:t,index:e})).filter(({trace:t})=>t.connection_name===this.input.pair.connectionNames[0]),e=this.input.traces.map((t,e)=>({trace:t,index:e})).filter(({trace:t})=>t.connection_name===this.input.pair.connectionNames[1]);if(1!==t.length||1!==e.length)throw new YG({connectionNames:this.input.pair.connectionNames,reason:"trace-resolution-failure",message:"must resolve each connection_name to exactly one non-branching trace"});if(t[0].index===e[0].index)throw new YG({connectionNames:this.input.pair.connectionNames,reason:"trace-resolution-failure",message:"resolved both members to one trace"});let n,o;try{n=LG(t[0].trace,this.input.layerCount),o=LG(e[0].trace,this.input.layerCount)}catch(t){throw new YG({connectionNames:this.input.pair.connectionNames,reason:"invalid-routed-geometry",message:`has unsupported or invalid routed geometry: ${t instanceof Error?t.message:String(t)}`})}const i=n.points[0],r=n.points.at(-1),s=Math.hypot(i.x-o.points[0].x,i.y-o.points[0].y)+Math.hypot(r.x-o.points.at(-1).x,r.y-o.points.at(-1).y),a=Math.hypot(i.x-o.points.at(-1).x,i.y-o.points.at(-1).y)+Math.hypot(r.x-o.points[0].x,r.y-o.points[0].y)+1e-8<s,c=a?o.points.at(-1):o.points[0],l=a?o.points[0]:o.points.at(-1);if(i.layer!==c.layer||r.layer!==l.layer)throw new YG({connectionNames:this.input.pair.connectionNames,reason:"terminal-layer-mismatch",message:"does not have common paired layers at both terminal stations"});const d={x:(i.x+c.x)/2,y:(i.y+c.y)/2,layer:i.layer},h={x:(r.x+l.x)/2,y:(r.y+l.y)/2,layer:r.layer},u=Math.hypot(h.x-d.x,h.y-d.y);if(u<1e-6)throw new YG({connectionNames:this.input.pair.connectionNames,reason:"coincident-terminal-midpoints",message:"has coincident terminal-pair midpoints"});const p={x:-(h.y-d.y)/u,y:(h.x-d.x)/u},m=i.x-c.x,g=i.y-c.y,f=m*p.x+g*p.y>=0?1:-1,y=(t,e)=>{const n=t.x-e.x,o=t.y-e.y,i=Math.hypot(n,o);return i>1e-8&&Math.abs(n*p.x+o*p.y)/i<.5},_=y(i,c)&&y(r,l),b={x:p.y,y:-p.x},x=[i,c].some(t=>(t.x-d.x)*b.x+(t.y-d.y)*b.y>1e-8),v={immutableTraces:this.input.traces.filter((n,o)=>o!==t[0].index&&o!==e[0].index),obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,minTraceToPadEdgeClearance:this.input.minTraceToPadEdgeClearance},S=(t=>{const{minimumCenterlineDistance:e,maximumCenterlineDistance:n}=t;if(void 0===e&&void 0===n)return t.legacyCenterlineDistances;const o=[...void 0!==e&&void 0!==n?[(e+n)/2,e,n,e-.25,n+.25]:void 0!==e?[e,e+.25,e+.5,e-.25,e+1]:[n,n-.25,n-.5,n+.25,n-1],...t.legacyCenterlineDistances];return o.filter((e,n)=>e>t.minimumPhysicalDistance&&o.findIndex(t=>Math.abs(t-e)<1e-8)===n)})({minimumCenterlineDistance:this.input.pair.minimumCenterlineDistance,maximumCenterlineDistance:this.input.pair.maximumCenterlineDistance,minimumPhysicalDistance:n.width/2+o.width/2,legacyCenterlineDistances:eU.map(t=>t+n.width/2+o.width/2)}).flatMap(t=>{const e=t-n.width/2-o.width/2;return[f,1===f?-1:1].flatMap(s=>{const a=QG({config:this.input.routingGrid,bounds:this.input.bounds,defaultInnerGridStep:Math.max(.25,Math.min(.5,t/2))}),u=(e,a)=>UG({...v,start:e,end:a,firstConnectionName:n.source.connection_name,secondConnectionName:o.source.connection_name,firstStartTerminal:i,firstEndTerminal:r,secondStartTerminal:c,secondEndTerminal:l,firstWidth:n.width,secondWidth:o.width,firstViaDiameter:n.transitions[0]?.via_diameter??n.viaDiameter,secondViaDiameter:o.transitions[0]?.via_diameter??o.viaDiameter,centerlineSpacing:t,side:s,terminalFanout:_,terminalMiterMargin:void 0===this.input.pair.maxUncoupledLength?void 0:t/2});let m=void 0===this.input.pair.maxUncoupledLength?((t,e)=>{if(!x||_)return d;const n=[{terminal:i,offset:e*t/2},{terminal:c,offset:-e*t/2}],o=Math.tan(55*Math.PI/180),r=Math.max(...n.map(({terminal:t,offset:e})=>{const n=(t.x-d.x)*b.x+(t.y-d.y)*b.y,i=(t.x-d.x)*p.x+(t.y-d.y)*p.y;return n+Math.abs(i-e)/o}));return{x:d.x+b.x*r,y:d.y+b.y*r,layer:d.layer}})(t,s):d,g=h;if(!_&&void 0!==this.input.pair.maxUncoupledLength){const e=u(d,h),n=tU({anchor:d,escapeDirection:b,pathDirection:b,centerlineSpacing:t,side:s,lanes:[{point:i,polarity:1},{point:c,polarity:-1}],maxUncoupledLength:this.input.pair.maxUncoupledLength,maximumTurnDegrees:55,searchStep:a.innerGridStep,isValid:t=>e.isTerminalFanoutValid(t,b,"start")}),o=tU({anchor:h,escapeDirection:{x:-b.x,y:-b.y},pathDirection:b,centerlineSpacing:t,side:s,lanes:[{point:r,polarity:1},{point:l,polarity:-1}],maxUncoupledLength:this.input.pair.maxUncoupledLength,maximumTurnDegrees:45,searchStep:a.innerGridStep,isValid:t=>e.isTerminalFanoutValid(t,b,"end")});if(!n||!o)return[];m=n,g=o;if((g.x-m.x)*b.x+(g.y-m.y)*b.y<=a.innerGridStep)return[]}const f=u(m,g);return[{edgeGap:e,side:s,input:{start:m,end:g,bounds:this.input.bounds,layerCount:this.input.layerCount,grid:a,...f}}]})});return{first:n,second:o,reverseSecond:a,terminalFanout:_,context:v,attempts:S}}complete(){if(0===this.candidates.length)throw new YG({connectionNames:this.input.pair.connectionNames,reason:"no-valid-candidate",message:"could not be improved without violating bounds, copper clearance, or coupled-via constraints"});this.candidates.sort((t,e)=>this.score(t)-this.score(e)||t.edgeGap-e.edgeGap),this.result={status:"accepted",candidate:this.candidates[0]}}score(t){return(void 0!==this.input.pair.minimumCenterlineDistance||void 0!==this.input.pair.maximumCenterlineDistance?Math.max(0,(this.input.pair.minimumCenterlineDistance??Number.NEGATIVE_INFINITY)-t.centerlineDistance)*nU+Math.max(0,t.centerlineDistance-(this.input.pair.maximumCenterlineDistance??Number.POSITIVE_INFINITY))*nU:t.edgeGap<.5?(.5-t.edgeGap)*nU:t.edgeGap>1?(t.edgeGap-1)*nU:0)+FG(t.firstParsed)+FG(t.secondParsed)+.15*t.bendCount+8*t.viaPairCount}},iU=t=>{const e={lines:[],points:[],rects:[],circles:[]};e.rects.push({center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,fill:"rgba(30, 70, 120, 0.04)",stroke:"rgba(30, 70, 120, 0.55)",layer:`z${Array.from({length:t.layerCount},(t,e)=>e).join(",")}`});for(const n of t.obstacles){const o=uG(n,t.layerCount);e.rects.push({center:n.center,width:n.width,height:n.height,ccwRotationDegrees:n.ccwRotationDegrees,fill:"rgba(220, 60, 60, 0.16)",stroke:"rgba(190, 40, 40, 0.75)",layer:`z${o.join(",")}`})}for(let n=0;n<(t.previewPath?.length??0)-1;n++){const o=t.previewPath[n],i=t.previewPath[n+1];if(o.layer!==i.layer)continue;const r=EG(o.layer,t.layerCount);e.lines.push({points:[o,i],strokeColor:"#16a34a",strokeWidth:.08,strokeDash:[.18,.12],layer:`z${r}`})}for(const n of t.traces){if(t.activeConnectionNames?.includes(n.connection_name))continue;const o="#2563eb";let i=null;for(const r of n.route)if("wire"===r.route_type){if(i&&i.layer===r.layer){const n=EG(r.layer,t.layerCount);e.lines.push({points:[i,r],strokeColor:o,strokeWidth:Math.max(i.width,r.width),...0===n?{}:{strokeDash:[.2,.16]},layer:`z${n}`})}i=r}else if("via"===r.route_type){const n=OG(r.from_layer,r.to_layer,t.layerCount).map(e=>EG(e,t.layerCount));if(e.circles.push({center:r,radius:(r.via_diameter??i?.width??.2)/2,fill:"rgba(37, 99, 235, 0.45)",stroke:o,layer:`z${n.join(",")}`}),i){const t=i.width;i={x:r.x,y:r.y,layer:r.to_layer,width:t}}}}return e},rU=class extends kt{constructor(t){super(),this.params=t,this.outputTraces=HG(t.simpleRouteJson.traces),this.MAX_ITERATIONS=WG(t)}params;outputTraces;reroutedPairs=[];failures=[];nextPairIndex=0;activeConnectionNames=null;activeSession=null;getSolverName(){return"DifferentialPairReroutingSolver"}_step(){const t=this.params.simpleRouteJson.differentialPairs[this.nextPairIndex];if(!t)return void this.finish();this.activeConnectionNames=t.connectionNames;try{if(!this.activeSession)return this.activeSession=new oU({pair:t,traces:this.outputTraces,obstacles:this.params.simpleRouteJson.obstacles,bounds:this.params.simpleRouteJson.bounds,layerCount:this.params.simpleRouteJson.layerCount,minTraceToPadEdgeClearance:this.params.simpleRouteJson.minTraceToPadEdgeClearance,routingGrid:this.params.routingGrid}),void(this.stats=this.activeSession.getStats());this.activeSession.step()}catch(e){if(!(e instanceof YG))throw e;return void this.skipFailedPair(t,e)}if(this.stats=this.activeSession.getStats(),!this.activeSession.isComplete())return;const e=this.activeSession.getResult();this.activeSession=null;for(const t of[e.candidate.first,e.candidate.second]){const e=this.outputTraces.findIndex(e=>e.connection_name===t.connection_name);if(e<0)throw new Error(`DifferentialPairReroutingSolver: accepted replacement for unknown connection "${t.connection_name}"`);this.outputTraces[e]=t}this.reroutedPairs.push(t),this.nextPairIndex++,this.nextPairIndex!==this.params.simpleRouteJson.differentialPairs.length?this.stats={phase:"accepted",pair:t.connectionNames.join("/"),pairIndex:this.nextPairIndex-1,pairCount:this.params.simpleRouteJson.differentialPairs.length}:this.finish()}finish(){this.activeConnectionNames=null,this.solved=!0,this.stats={phase:"complete",acceptedPairCount:this.reroutedPairs.length,skippedPairCount:this.failures.length}}skipFailedPair(t,e){this.failures.push({connectionNames:[...t.connectionNames],reason:e.reason,message:e.message}),this.activeSession=null,this.nextPairIndex++,this.nextPairIndex!==this.params.simpleRouteJson.differentialPairs.length?this.stats={phase:"skipped",pair:t.connectionNames.join("/"),pairIndex:this.nextPairIndex-1,pairCount:this.params.simpleRouteJson.differentialPairs.length,skippedPairCount:this.failures.length}:this.finish()}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved)throw new Error("DifferentialPairReroutingSolver: getOutput() called before completion");return this.getBestEffortOutput()}getBestEffortOutput(){return{traces:HG(this.outputTraces),reroutedPairs:this.reroutedPairs.map(t=>({...t,connectionNames:[...t.connectionNames]})),failures:this.failures.map(t=>({...t,connectionNames:[...t.connectionNames]}))}}computeProgress(){return this.solved?1:0===this.params.simpleRouteJson.differentialPairs.length?0:(this.nextPairIndex+(this.activeSession?.getProgress()??0))/this.params.simpleRouteJson.differentialPairs.length}visualize(){return iU({traces:this.outputTraces,obstacles:this.params.simpleRouteJson.obstacles,bounds:this.params.simpleRouteJson.bounds,layerCount:this.params.simpleRouteJson.layerCount,activeConnectionNames:this.activeConnectionNames,previewPath:this.activeSession?.getPreviewPath()??null})}},sU=1e-8,aU=class extends kt{constructor(t){super(),this.input=t,this.traces=HG(t.traces),this.MAX_ITERATIONS=Math.max(1,t.reroutedPairs.length+1)}input;traces;nextPairIndex=0;getSolverName(){return"FortyFiveDegreeSimplificationSolver"}_step(){const t=this.input.reroutedPairs[this.nextPairIndex];if(!t)return this.solved=!0,void(this.stats={phase:"complete",simplifiedPairCount:this.nextPairIndex});this.traces=(t=>{const e=t.pair.connectionNames.join("/"),n=t.pair.connectionNames.map(e=>t.traces.map((t,e)=>({trace:t,index:e})).filter(({trace:t})=>t.connection_name===e));if(1!==n[0].length||1!==n[1].length)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} must resolve to exactly two traces`);const o=n[0][0].index,i=n[1][0].index;if(o===i)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} resolved both members to one trace`);const r=structuredClone(t.traces),s={immutableTraces:r.filter((t,e)=>e!==o&&e!==i),obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,minTraceToPadEdgeClearance:t.minTraceToPadEdgeClearance},a=n=>{const r=LG(n[o],t.layerCount),s=LG(n[i],t.layerCount);let a=0;for(const[t,n]of[[r.segments,s.segments],[s.segments,r.segments]])for(const o of t){if(null!==o.terminal)continue;const t=n.filter(t=>t.layer===o.layer);if(0===t.length)throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} lost common-layer interior copper`);a=Math.max(a,Math.min(...t.map(t=>cG(o.start,o.end,t.start,t.end))))}return a},c=e=>{const n=LG(e[o],t.layerCount),r=LG(e[i],t.layerCount);let s=Number.POSITIVE_INFINITY;for(const[t,e]of[[n.segments,r.segments],[r.segments,n.segments]])for(const n of t)if(null===n.terminal)for(const t of e)t.layer===n.layer&&(s=Math.min(s,cG(n.start,n.end,t.start,t.end)-n.width/2-t.width/2));return Number.isFinite(s)?s:null},l=e=>{const n=LG(e[o],t.layerCount),r=LG(e[i],t.layerCount);return ZG(n,r,s)};if(!l(r))throw new Error(`FortyFiveDegreeSimplificationSolver: rerouted pair ${e} has invalid complete copper before simplification`);if(void 0!==t.pair.maxUncoupledLength&&void 0!==t.pair.minimumCenterlineDistance&&void 0!==t.pair.maximumCenterlineDistance&&Math.abs(t.pair.minimumCenterlineDistance-t.pair.maximumCenterlineDistance)<=sU)return r;const d=LG(r[o],t.layerCount),h=LG(r[i],t.layerCount),u=Math.abs(FG(d)-FG(h)),p=c(r),m=t.pair.maximumCenterlineDistance??1+d.width/2+h.width/2,g=Math.min(a(r),m),f=t=>{if(!l(t))return!1;if(a(t)>g+sU)return!1;const e=c(t);return null===p||null===e||e>=p-sU},y=(t,e)=>{const n=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,s=[],a={x:e.x-i*o,y:t.y};(a.x-t.x)*i>=-1e-8&&(a.x-e.x)*i<=sU&&s.push([t,a,e]);const c={x:t.x,y:e.y-r*n};(c.y-t.y)*r>=-1e-8&&(c.y-e.y)*r<=sU&&s.push([t,c,e]);const l={x:t.x+i*Math.min(n,o),y:t.y+r*Math.min(n,o)};return s.push([t,l,e]),s.map((t,e)=>{const n=t.filter((e,n)=>0===n||Math.hypot(e.x-t[n-1].x,e.y-t[n-1].y)>sU),o=n.slice(0,-1).map((t,e)=>{const o=n[e+1],i=Math.abs(o.x-t.x),r=Math.abs(o.y-t.y);return{length:Math.hypot(i,r),straight:i<=sU||r<=sU?Math.hypot(i,r):0}});return{points:n,usableStraightLength:Math.max(0,...o.map(t=>t.straight)),bendCount:Math.max(0,n.length-2),priority:e}}).filter((t,e,n)=>n.findIndex(e=>JSON.stringify(e.points)===JSON.stringify(t.points))===e).sort((t,e)=>e.usableStraightLength-t.usableStraightLength||t.bendCount-e.bendCount||t.priority-e.priority)},_=t=>{const e=[];for(let n=0;n<t.route.length-1;n++){const o=t.route[n];if("wire"===o?.route_type)for(let i=t.route.length-1;i>=n+1;i--){if(0===n||i===t.route.length-1)continue;const r=t.route[i];"wire"===r?.route_type&&r.layer===o.layer&&(t.route.slice(n+1,i).some(t=>"wire"!==t.route_type||t.layer!==o.layer)||e.push({startIndex:n,endIndex:i,skippedPointCount:i-n-1}))}}return e.sort((t,e)=>e.skippedPointCount-t.skippedPointCount||t.startIndex-e.startIndex||e.endIndex-t.endIndex)},b=(t,e,n)=>{const o=t.route[e.startIndex],i=t.route[e.endIndex],r=Math.max(o.width,i.width),s=n.points.slice(1,-1).map(t=>({route_type:"wire",...t,width:r,layer:o.layer}));return{...t,route:[...t.route.slice(0,e.startIndex+1),...s,...t.route.slice(e.endIndex)]}};for(const t of[o,i]){let e=!0;for(;e;){e=!1;const n=r[t];for(const s of _(n)){const a=n.route[s.startIndex],c=n.route[s.endIndex],l=n.route.slice(s.startIndex,s.endIndex+1),d=l.slice(0,-1).every((t,e)=>{const n=l[e+1],o=Math.abs(n.x-t.x),i=Math.abs(n.y-t.y);return o<=sU||i<=sU||Math.abs(o-i)<=sU});for(const h of y(a,c)){if(h.points.length>=l.length&&d)continue;const a=b(n,s,h),c=[...r];if(c[t]=a,JSON.stringify(a.route)===JSON.stringify(n.route))continue;if(f(c)){r[t]=a,e=!0;break}const u=t===o?i:o,p=r[u],m=_(p).find(t=>t.startIndex===s.startIndex&&t.endIndex===s.endIndex);if(!m)continue;const g=p.route[m.startIndex],x=p.route[m.endIndex];for(const n of y(g,x)){const o=b(p,m,n),i=[...c];if(i[u]=o,f(i)){r[t]=a,r[u]=o,e=!0;break}}if(e)break}if(e)break}}}if(!f(r))throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${e} produced invalid complete copper`);const x=LG(r[o],t.layerCount),v=LG(r[i],t.layerCount),S=Math.abs(FG(x)-FG(v));return Math.abs(S-u)>t.pair.lengthTolerance+sU?structuredClone(t.traces):r})({traces:this.traces,pair:t,obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,minTraceToPadEdgeClearance:this.input.minTraceToPadEdgeClearance}),this.nextPairIndex++,this.stats={phase:"simplifying",pair:t.connectionNames.join("/"),pairIndex:this.nextPairIndex-1,pairCount:this.input.reroutedPairs.length}}getConstructorParams(){return[this.input]}getOutput(){if(!this.solved)throw new Error("FortyFiveDegreeSimplificationSolver: getOutput() called before completion");return this.getBestEffortOutput()}getBestEffortOutput(){return{traces:HG(this.traces),reroutedPairs:this.input.reroutedPairs.map(t=>({...t,connectionNames:[...t.connectionNames]}))}}computeProgress(){return this.solved?1:0===this.input.reroutedPairs.length?0:this.nextPairIndex/this.input.reroutedPairs.length}visualize(){return iU({traces:this.traces,obstacles:this.input.obstacles,bounds:this.input.bounds,layerCount:this.input.layerCount,activeConnectionNames:this.input.reroutedPairs[this.nextPairIndex]?.connectionNames??null,previewPath:null})}},cU=class extends kt{constructor(t){super(),this.input=t}input;output=null;visualizationTraces=null;getSolverName(){return"HdRouteReconstructionSolver"}_step(){this.visualizationTraces=(t=>{const{simpleRouteJson:e}=t.params;if(t.result.matchedHdRoutes.length!==t.binding.solverParams.hdRoutes.length)throw new Error("PostProcessingSolver: LengthMatchingSolver changed the search route count");const n=structuredClone(t.binding.baseTraces);for(const o of t.binding.traceBindings){const i=t.result.matchedHdRoutes[o.matchedRouteIndex];if(!i)throw new Error(`PostProcessingSolver: missing matched route at index ${o.matchedRouteIndex}`);const r=n[o.traceIndex];if(!r)throw new Error(`PostProcessingSolver: missing simplified trace binding at index ${o.traceIndex}`);if(r.connection_name!==i.connectionName)throw new Error(`PostProcessingSolver: route binding changed connection "${r.connection_name}" to "${i.connectionName}"`);if(i.route.length<2)throw new Error(`PostProcessingSolver: matched connection "${i.connectionName}" has incomplete geometry`);const s=i.route[0],a=i.route.at(-1);if(Math.hypot(s.x-o.startEndpoint.x,s.y-o.startEndpoint.y)>1e-8||s.z!==o.startEndpoint.z||Math.hypot(a.x-o.endEndpoint.x,a.y-o.endEndpoint.y)>1e-8||a.z!==o.endEndpoint.z)throw new Error(`PostProcessingSolver: matched connection "${i.connectionName}" moved a preserved endpoint`);const c=[];let l=0;const d=t=>({route_type:"wire",x:t.x,y:t.y,width:t.traceThickness??i.traceThickness,layer:AG(t.z,e.layerCount)});c.push(d(i.route[0]));for(let t=1;t<i.route.length;t++){const n=i.route[t-1],r=i.route[t];if(n.z===r.z){c.push(d(r));continue}if(Math.hypot(n.x-r.x,n.y-r.y)>1e-8)throw new Error(`PostProcessingSolver: matched connection "${i.connectionName}" moves while changing layers`);const s=o.viaTemplates[l++];if(!s)throw new Error(`PostProcessingSolver: matched connection "${i.connectionName}" added an unbound via`);if(Math.hypot(s.x-r.x,s.y-r.y)>1e-8)throw new Error(`PostProcessingSolver: matched connection "${i.connectionName}" moved a preserved via`);const a=AG(n.z,e.layerCount),h=AG(r.z,e.layerCount),u=new Set([s.from_layer,s.to_layer]);if(!u.has(a)||!u.has(h))throw new Error(`PostProcessingSolver: matched connection "${i.connectionName}" changed a preserved via span`);c.push({...s}),c.push(d(r))}if(l!==o.viaTemplates.length)throw new Error(`PostProcessingSolver: matched connection "${i.connectionName}" removed a preserved via`);const h=c.filter(t=>"wire"===t.route_type);for(const t of h)delete t.start_pcb_port_id,delete t.end_pcb_port_id;o.startPortId&&(h[0].start_pcb_port_id=o.startPortId),o.endPortId&&(h.at(-1).end_pcb_port_id=o.endPortId),n[o.traceIndex]={...r,route:c}}for(const o of t.binding.solverParams.differentialPairs){const t=o.connectionNames.join("/"),i=o.connectionNames.map(t=>n.map((t,e)=>({trace:t,index:e})).filter(({trace:e})=>e.connection_name===t));if(1!==i[0].length||1!==i[1].length)throw new Error(`PostProcessingSolver: reconstructed pair ${t} does not resolve to complete copper`);const r=i[0][0],s=i[1][0],a=LG(r.trace,e.layerCount),c=LG(s.trace,e.layerCount),l=Math.abs(FG(a)-FG(c));if(l>o.lengthTolerance+1e-7)throw new XG({message:`PostProcessingSolver: reconstructed pair ${t} exceeds length tolerance ${o.lengthTolerance} with error ${l}`,connectionNames:[...o.connectionNames],reason:"length-tolerance-unsatisfied"});if(!ZG(a,c,{immutableTraces:n.filter((t,e)=>e!==r.index&&e!==s.index),obstacles:e.obstacles,bounds:e.bounds,layerCount:e.layerCount,minTraceToPadEdgeClearance:e.minTraceToPadEdgeClearance}))throw new XG({message:`PostProcessingSolver: length matching produced invalid complete copper for pair ${t}`,connectionNames:[...o.connectionNames],reason:"invalid-final-copper"})}return n})(this.input),this.output=$G({...this.input,rejectInsideJumperPad:!0}),this.stats={phase:"complete",routeCount:this.output.hdRoutes.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){if(!this.output||!this.solved)throw new Error("HdRouteReconstructionSolver: getOutput() called before completion");return structuredClone(this.output)}visualize(){const t=this.visualizationTraces??this.input.simplified.traces,{obstacles:e,bounds:n,layerCount:o}=this.input.params.simpleRouteJson;return iU({traces:t,obstacles:e,bounds:n,layerCount:o,activeConnectionNames:null,previewPath:null})}};var lU=class extends Dt{differentialPairReroutingSolver;fortyFiveDegreeSimplificationSolver;lengthMatchingSolver;hdRouteReconstructionSolver;lengthMatchingBinding=null;model;fallbackOutput=null;postProcessingErrors=[];pipelineDef=[Lt("differentialPairReroutingSolver",rU,t=>[t.model.params]),Lt("fortyFiveDegreeSimplificationSolver",aU,t=>{const e=t.getStageOutput("differentialPairReroutingSolver");if(!e)throw new Error("PostProcessingSolver: rerouting stage completed without output");const{obstacles:n,bounds:o,layerCount:i,minTraceToPadEdgeClearance:r}=t.model.params.simpleRouteJson;return[{...e,obstacles:n,bounds:o,layerCount:i,minTraceToPadEdgeClearance:r}]}),Lt("lengthMatchingSolver",RG,t=>{const e=t.getStageOutput("fortyFiveDegreeSimplificationSolver");if(!e)throw new Error("PostProcessingSolver: 45-degree simplification stage completed without output");return t.lengthMatchingBinding=BG({result:e,params:t.model.params}),[t.lengthMatchingBinding.solverParams]}),Lt("hdRouteReconstructionSolver",cU,t=>{const e=t.getStageOutput("fortyFiveDegreeSimplificationSolver"),n=t.getStageOutput("lengthMatchingSolver");if(!e||!n||!t.lengthMatchingBinding)throw new Error("PostProcessingSolver: reconstruction stage is missing a required binding or output");return[{binding:t.lengthMatchingBinding,result:n,simplified:e,params:t.model.params,model:t.model}]},{onSolved:t=>{const e=t.getStageOutput("differentialPairReroutingSolver");if(!e)throw new Error("PostProcessingSolver: cannot summarize missing rerouting output");t.stats={phase:"complete",acceptedPairCount:e.reroutedPairs.length},e.failures.length>0&&(t.stats.skippedPairCount=e.failures.length,t.stats.postProcessingErrorCount=e.failures.length)}})];constructor(t){super(structuredClone(t));let e=null;try{!function(t){if(!t||"object"!=typeof t)throw new Error("PostProcessingSolver: params must be an object");if(!Array.isArray(t.hdRoutes))throw new Error("PostProcessingSolver: hdRoutes must be an array");if(!Array.isArray(t.differentialPairs))throw new Error("PostProcessingSolver: differentialPairs must be an array");if(!Array.isArray(t.obstacles))throw new Error("PostProcessingSolver: obstacles must be an array");if(void 0!==t.minTraceToPadEdgeClearance&&(!Number.isFinite(t.minTraceToPadEdgeClearance)||t.minTraceToPadEdgeClearance<0))throw new Error("PostProcessingSolver: minTraceToPadEdgeClearance must be finite and nonnegative");if(!Number.isInteger(t.layerCount)||t.layerCount<1)throw new Error("PostProcessingSolver: layerCount must be a positive integer");for(const e of t.obstacles){if(!e||"object"!=typeof e||"rect"!==e.type||!e.center||!Number.isFinite(e.center.x)||!Number.isFinite(e.center.y)||!Number.isFinite(e.width)||e.width<=0||!Number.isFinite(e.height)||e.height<=0||!Array.isArray(e.layers)||e.layers.some(t=>"string"!=typeof t)||!Array.isArray(e.connectedTo)||e.connectedTo.some(t=>"string"!=typeof t||0===t.length)||void 0!==e.ccwRotationDegrees&&!Number.isFinite(e.ccwRotationDegrees))throw new Error("PostProcessingSolver: obstacle declaration is invalid");uG(e,t.layerCount)}const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds??{};if(![e,n,o,i].every(Number.isFinite)||e>=n||o>=i)throw new Error("PostProcessingSolver: bounds must have finite positive extents");const r=new Set(t.differentialPairs.flatMap(t=>t.connectionNames));for(const e of t.hdRoutes){if(!e||"object"!=typeof e||"string"!=typeof e.connectionName||0===e.connectionName.length||void 0!==e.rootConnectionName&&("string"!=typeof e.rootConnectionName||0===e.rootConnectionName.length)||!Number.isFinite(e.traceThickness)||e.traceThickness<=0||!Number.isFinite(e.viaDiameter)||e.viaDiameter<0||0===e.viaDiameter&&r.has(e.connectionName)||!Array.isArray(e.route)||!Array.isArray(e.vias)||void 0!==e.jumpers&&!Array.isArray(e.jumpers))throw new Error("PostProcessingSolver: HD route declaration is invalid");if(void 0!==e.startPcbPortId&&("string"!=typeof e.startPcbPortId||0===e.startPcbPortId.length)||void 0!==e.endPcbPortId&&("string"!=typeof e.endPcbPortId||0===e.endPcbPortId.length))throw new Error(`PostProcessingSolver: HD route "${e.connectionName}" has invalid terminal metadata`);for(const n of e.route)if(!n||"object"!=typeof n||!Number.isFinite(n.x)||!Number.isFinite(n.y)||!Number.isInteger(n.z)||n.z<0||n.z>=t.layerCount||void 0!==n.traceThickness&&(!Number.isFinite(n.traceThickness)||n.traceThickness<=0))throw new Error(`PostProcessingSolver: HD route "${e.connectionName}" has an invalid route point`);for(const n of e.vias)if(!n||"object"!=typeof n||!Number.isFinite(n.x)||!Number.isFinite(n.y)||void 0!==n.zLayers&&(!Array.isArray(n.zLayers)||n.zLayers.some(e=>!Number.isInteger(e)||e<0||e>=t.layerCount)))throw new Error(`PostProcessingSolver: HD route "${e.connectionName}" has an invalid via`);if(e.vias.length>0&&e.viaDiameter<=0)throw new Error(`PostProcessingSolver: HD route "${e.connectionName}" has a non-positive via diameter`);for(const t of e.jumpers??[])if(!(t&&"object"==typeof t&&"jumper"===t.route_type&&Number.isFinite(t.start?.x)&&Number.isFinite(t.start?.y)&&Number.isFinite(t.end?.x)&&Number.isFinite(t.end?.y)&&["0603","1206","1206x4_pair"].includes(t.footprint)))throw new Error(`PostProcessingSolver: HD route "${e.connectionName}" has an invalid jumper`)}const s=new Set;for(const e of t.differentialPairs){if(!e||"object"!=typeof e||!Array.isArray(e.connectionNames)||2!==e.connectionNames.length||e.connectionNames[0]===e.connectionNames[1]||!e.connectionNames.every(t=>"string"==typeof t&&t.length>0)||!Number.isFinite(e.lengthTolerance)||e.lengthTolerance<0)throw new Error("PostProcessingSolver: differential pair declaration is invalid");for(const t of[e.minimumCenterlineDistance,e.maximumCenterlineDistance])if(void 0!==t&&(!Number.isFinite(t)||t<=0))throw new Error("PostProcessingSolver: differential pair centerline distances must be positive finite numbers");if(void 0!==e.maxUncoupledLength&&(!Number.isFinite(e.maxUncoupledLength)||e.maxUncoupledLength<0))throw new Error("PostProcessingSolver: differential pair maxUncoupledLength must be a non-negative finite number");if(void 0!==e.minimumCenterlineDistance&&void 0!==e.maximumCenterlineDistance&&e.minimumCenterlineDistance>e.maximumCenterlineDistance)throw new Error("PostProcessingSolver: differential pair minimumCenterlineDistance cannot exceed maximumCenterlineDistance");for(const t of e.connectionNames){if(s.has(t))throw new Error(`PostProcessingSolver: connection "${t}" belongs to multiple differential pairs`);s.add(t)}}for(const e of[.25,.5])QG({config:t.routingGrid,bounds:t.bounds,defaultInnerGridStep:e})}(t)}catch(t){if(!(t instanceof VG))throw t;e=t}if(this.model=jG(t),e)return void this.finishWithBestEffortOutput({stage:"differentialPairReroutingSolver",message:e.message,reason:e.reason});const n=WG(this.model.params)+Math.max(1,t.differentialPairs.length+1)+1e5+10;if(!Number.isSafeInteger(n))throw new Error("PostProcessingSolver: derived pipeline iteration bound exceeds the safe integer range");this.MAX_ITERATIONS=n}getSolverName(){return"PostProcessingSolver"}getConstructorParams(){return[structuredClone(this.inputProblem)]}_step(){const t=this.getCurrentStageName();try{super._step()}catch(e){const n=this.classifyOptimizationFailure(e,t);if(!n)throw e;return void this.finishWithBestEffortOutput(n)}if(!this.failed)return;const e=this.classifyIterationFailure(this.error,t);if(!e)throw new Error(this.error??"PostProcessingSolver failed without an error message");this.finishWithBestEffortOutput(e)}tryFinalAcceptance(){const t=this.getCurrentStageName();"differentialPairReroutingSolver"!==t&&"lengthMatchingSolver"!==t||this.finishWithBestEffortOutput({stage:t,message:"PostProcessingSolver reached its iteration limit",reason:"iteration-limit-exhausted"})}classifyOptimizationFailure(t,e){return"lengthMatchingSolver"===e&&t instanceof IG?{stage:e,message:t.message,connectionName:t.connectionName,reason:t.reason}:"hdRouteReconstructionSolver"===e&&t instanceof XG||"differentialPairReroutingSolver"===e&&t instanceof YG&&"no-valid-candidate"===t.reason?{stage:e,message:t.message,connectionNames:[...t.connectionNames],reason:t.reason}:null}classifyIterationFailure(t,e){return"differentialPairReroutingSolver"!==e&&"lengthMatchingSolver"!==e?null:t&&t.endsWith("ran out of iterations")?{stage:e,message:t,reason:"iteration-limit-exhausted"}:null}createBestEffortOutput(t){let e=this.lengthMatchingBinding;if(!e){const t=this.getStageOutput("fortyFiveDegreeSimplificationSolver")??this.fortyFiveDegreeSimplificationSolver?.getBestEffortOutput(),n=this.getStageOutput("differentialPairReroutingSolver")??this.differentialPairReroutingSolver?.getBestEffortOutput(),o=t??n;o&&(e=BG({result:o,params:this.model.params}))}if(!e)return{output:{hdRoutes:structuredClone(this.inputProblem.hdRoutes),postProcessingErrors:[]},source:"input-hd-routes"};let n=this.getStageOutput("lengthMatchingSolver");return n||(n=this.lengthMatchingSolver?.getBestEffortOutput()),n&&"invalid-final-copper"!==t.reason||(n={matchedHdRoutes:e.solverParams.hdRoutes}),{output:$G({binding:e,result:n,model:this.model}),source:"best-effort-hd-routes"}}finishWithBestEffortOutput(t){const e=this.createBestEffortOutput(t),n={type:"post_processing_error",...t,returnedRouteSource:e.source};this.postProcessingErrors.push(n),this.fallbackOutput=e.output,this.activeSubSolver=null,this.error=null,this.failed=!1,this.solved=!0,this.progress=1,this.stats={phase:"complete",postProcessingErrorCount:this.postProcessingErrors.length}}getOutput(){if(!this.solved)throw new Error("PostProcessingSolver: getOutput() called before the solver completed");const t=this.fallbackOutput??this.getStageOutput("hdRouteReconstructionSolver");if(!t)throw new Error("PostProcessingSolver: completed pipeline is missing reconstruction output");const e=this.getStageOutput("differentialPairReroutingSolver")??this.differentialPairReroutingSolver?.getBestEffortOutput(),n=e?.failures??[];let o="input-hd-routes";(e?.reroutedPairs.length??0)>0&&(o="best-effort-hd-routes");const i=[...n.map(t=>({type:"post_processing_error",stage:"differentialPairReroutingSolver",message:t.message,connectionNames:[...t.connectionNames],reason:t.reason,returnedRouteSource:o})),...this.postProcessingErrors],r=structuredClone(t);return r.postProcessingErrors=structuredClone(i),r}initialVisualize(){if(this.fallbackOutput)return{lines:this.fallbackOutput.hdRoutes.map(t=>({points:t.route.map(({x:t,y:e})=>({x:t,y:e})),strokeWidth:t.traceThickness}))};const{traces:t,obstacles:e,bounds:n,layerCount:o}=this.model.params.simpleRouteJson;return iU({traces:structuredClone(t),obstacles:e,bounds:n,layerCount:o,activeConnectionNames:null,previewPath:null})}finalVisualize(){if(this.fallbackOutput)return this.initialVisualize();const t=jG({...this.inputProblem,hdRoutes:this.getOutput().hdRoutes}),{traces:e,obstacles:n,bounds:o,layerCount:i}=t.params.simpleRouteJson;return iU({traces:e,obstacles:n,bounds:o,layerCount:i,activeConnectionNames:null,previewPath:null})}},dU=class t{static generators=new Map;static register(e){t.generators.set(e.componentKind,e)}static create(e){const n=e.detectedComponent.componentKind,o=t.generators.get(n);if(!o)throw new Error(`No topology generator registered for component kind "${n}"`);return new o(e)}},hU=t=>[t.obstacle.obstacleId??t.obstacle.componentId??"obstacle",t.start.x.toFixed(4),t.start.y.toFixed(4),t.end.x.toFixed(4),t.end.y.toFixed(4),t.expansionDirection.x,t.expansionDirection.y].join(":"),uU=t=>{let e=0;for(const n of t)e=31*e+n.charCodeAt(0)>>>0;return e},pU=(t,e)=>`hsla(${uU(hU(t))%360},72%,36%,${e})`,mU=t=>{const e=t.expansionDirection;return e.x<0?"left":e.x>0?"right":e.y<0?"bottom":"top"},gU=t=>({x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2}),fU=t=>{const e=/^bga-gapfill-(\d+)-/.exec(t.capacityMeshNodeId);return e?Number.parseInt(e[1],10):null},yU=(t,e)=>{const n=gU(t),o=gU(e),i=n.y-o.y;if(Math.abs(i)>1e-6)return i;const r=n.x-o.x;return Math.abs(r)>1e-6?r:hU(t).localeCompare(hU(e))},_U=t=>{const e=[...t].sort(yU),n=[];let o=e.shift();for(;o&&(n.push(o),0!==e.length);){const t=gU(o);let n=0,i=Number.POSITIVE_INFINITY;for(let o=0;o<e.length;o++){const r=e[o],s=gU(r),a=(s.x-t.x)**2+(s.y-t.y)**2;a<i-1e-9?(i=a,n=o):Math.abs(a-i)<=1e-9&&yU(r,e[n])<0&&(n=o)}o=e.splice(n,1)[0]}return n},bU=(t,e)=>{const n=hU(t),o=e.findIndex(t=>hU(t)===n);return o>=0?`E${o+1}`:`E${uU(n).toString(36).slice(0,4)}`},xU=t=>t.flatMap(t=>{const e=Ve(t);return[{obstacle:t,start:{x:e.minX,y:e.minY},end:{x:e.minX,y:e.maxY},expansionDirection:{x:-1,y:0}},{obstacle:t,start:{x:e.maxX,y:e.minY},end:{x:e.maxX,y:e.maxY},expansionDirection:{x:1,y:0}},{obstacle:t,start:{x:e.minX,y:e.minY},end:{x:e.maxX,y:e.minY},expansionDirection:{x:0,y:-1}},{obstacle:t,start:{x:e.minX,y:e.maxY},end:{x:e.maxX,y:e.maxY},expansionDirection:{x:0,y:1}}]}),vU=.001,SU=.001,IU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;meshIndex;allEdges=[];queueEdges=[];disconnectedEdges=[];currentEdge=null;lastSearchBounds=null;lastCandidateMeshNodes=[];lastMatchedMeshNode=null;_setup(){const t=Math.max(this.inputProblem.meshNodes.length,1);this.meshIndex=new Bt(t);for(const t of this.inputProblem.meshNodes){const e=Ve(t);this.meshIndex.add(e.minX,e.minY,e.maxX,e.maxY)}this.meshIndex.finish();const e=xU(this.inputProblem.unmarkedComponentObstacles);this.queueEdges=e,this.allEdges=_U(e),this.currentEdge=null,this.lastSearchBounds=null,this.lastCandidateMeshNodes=[],this.lastMatchedMeshNode=null}_step(){const t=this.queueEdges.shift();if(!t)return this.currentEdge=null,this.lastSearchBounds=null,this.lastCandidateMeshNodes=[],this.lastMatchedMeshNode=null,void(this.solved=!0);this.currentEdge=t,this.lastMatchedMeshNode=null;const e=Math.abs(t.start.x-t.end.x)<=vU,n=e?{minX:t.start.x-SU,maxX:t.start.x+SU,minY:Math.min(t.start.y,t.end.y),maxY:Math.max(t.start.y,t.end.y)}:{minX:Math.min(t.start.x,t.end.x),maxX:Math.max(t.start.x,t.end.x),minY:t.start.y-SU,maxY:t.start.y+SU};this.lastSearchBounds=n;const o=this.meshIndex.search(n.minX,n.minY,n.maxX,n.maxY);this.lastCandidateMeshNodes=o.map(t=>this.inputProblem.meshNodes[t]);let i=!1;for(const n of o){const o=this.inputProblem.meshNodes[n],r=Ve(o);if(e){if(!(Math.min(r.maxY,Math.max(t.start.y,t.end.y))-Math.max(r.minY,Math.min(t.start.y,t.end.y))>vU))continue;if(-1===t.expansionDirection.x&&Math.abs(r.maxX-t.start.x)<=vU){i=!0,this.lastMatchedMeshNode=o;break}if(1===t.expansionDirection.x&&Math.abs(r.minX-t.start.x)<=vU){i=!0,this.lastMatchedMeshNode=o;break}continue}if(Math.min(r.maxX,Math.max(t.start.x,t.end.x))-Math.max(r.minX,Math.min(t.start.x,t.end.x))>vU){if(-1===t.expansionDirection.y&&Math.abs(r.maxY-t.start.y)<=vU){i=!0,this.lastMatchedMeshNode=o;break}if(1===t.expansionDirection.y&&Math.abs(r.minY-t.start.y)<=vU){i=!0,this.lastMatchedMeshNode=o;break}}}i||this.disconnectedEdges.push(t)}getOutput(){return this.disconnectedEdges}visualize(){const t=this.disconnectedEdges,e=this.allEdges.length>0?this.allEdges:[...t,...this.currentEdge?[this.currentEdge]:[]],n=this.currentEdge?pU(this.currentEdge,.88):"rgba(40,40,40,0.4)",o=this.inputProblem.meshNodes.map(t=>({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?"rgba(120,120,120,0.18)":"rgba(120,120,120,0.08)",stroke:t._containsObstacle?"rgba(120,120,120,0.42)":"rgba(120,120,120,0.24)"})),i=this.lastSearchBounds&&this.currentEdge?[{center:(r=this.lastSearchBounds,{x:(r.minX+r.maxX)/2,y:(r.minY+r.maxY)/2}),width:this.lastSearchBounds.maxX-this.lastSearchBounds.minX,height:this.lastSearchBounds.maxY-this.lastSearchBounds.minY,fill:pU(this.currentEdge,.1),stroke:pU(this.currentEdge,.36),label:[bU(this.currentEdge,e),"search band"].join(" ")}]:[];var r;const s=this.lastCandidateMeshNodes.map(t=>({...Dc(t,{rectMargin:.018}),fill:t===this.lastMatchedMeshNode?"rgba(0,180,90,0.24)":this.currentEdge?pU(this.currentEdge,.16):"rgba(80,120,160,0.16)",stroke:t===this.lastMatchedMeshNode?"rgba(0,150,80,0.88)":n,label:[t===this.lastMatchedMeshNode?"matched":"candidate",t.capacityMeshNodeId,`z:${t.availableZ.join(",")}`].join("\n")})),a=this.inputProblem.unmarkedComponentObstacles.map(t=>({center:t.center,width:t.width,height:t.height,fill:"rgba(160,160,160,0.10)",stroke:"rgba(160,160,160,0.40)",label:t.obstacleId??t.componentId??"obstacle"})),c=t.map(t=>({points:[t.start,t.end],strokeColor:pU(t,.14),strokeWidth:.01,strokeDash:"5 4",label:[bU(t,e),mU(t),"disconnected"].join(" ")})),l=[],d=[];if(this.currentEdge){const t=gU(this.currentEdge);l.push({points:[this.currentEdge.start,this.currentEdge.end],strokeColor:pU(this.currentEdge,1),strokeWidth:.06,label:[bU(this.currentEdge,e),mU(this.currentEdge),"checking"].join(" ")},{points:[t,{x:t.x+.16*this.currentEdge.expansionDirection.x,y:t.y+.16*this.currentEdge.expansionDirection.y}],strokeColor:pU(this.currentEdge,.82),strokeWidth:.02,strokeDash:"3 3"}),d.push({...t,color:pU(this.currentEdge,1),label:bU(this.currentEdge,e)})}return{rects:[...o,...i,...s,...a],lines:[...c,...l],points:d}}},CU=.001,PU=.001,MU=1e-6,NU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;meshIndex;meshBounds;expandedNodes=[];_setup(){const t=Math.max(this.inputProblem.meshNodes.length,1);this.meshIndex=new Bt(t);let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const t of this.inputProblem.meshNodes){const r=Ve(t);this.meshIndex.add(r.minX,r.minY,r.maxX,r.maxY),e=Math.min(e,r.minX),n=Math.max(n,r.maxX),o=Math.min(o,r.minY),i=Math.max(i,r.maxY)}this.meshIndex.finish(),this.meshBounds=this.inputProblem.meshNodes.length?{minX:e,maxX:n,minY:o,maxY:i}:{minX:0,maxX:0,minY:0,maxY:0}}getObstacleAvailableZ(t){return t.__zLayers??t.layers.map(t=>ko(t,this.inputProblem.layerCount))}getSharedOverlapArea(t,e){if(!t.availableZ.some(t=>e.availableZ.includes(t)))return 0;const n=Ve(t),o=Ve(e),i=Math.min(n.maxX,o.maxX)-Math.max(n.minX,o.minX),r=Math.min(n.maxY,o.maxY)-Math.max(n.minY,o.minY);return i<=MU||r<=MU?0:i*r}getNodeObstacleOverlapArea(t,e){const n=this.getObstacleAvailableZ(e);if(!t.availableZ.some(t=>n.includes(t)))return 0;const o=Ve(t),i=Ve(e),r=Math.min(o.maxX,i.maxX)-Math.max(o.minX,i.minX),s=Math.min(o.maxY,i.maxY)-Math.max(o.minY,i.minY);return r<=MU||s<=MU?0:r*s}getClosestMeshNode(t,e){const n=Math.abs(t.start.x-t.end.x)<=CU,o=this.getObstacleAvailableZ(t.obstacle),i=n?t.expansionDirection.x<0?{minX:this.meshBounds.minX,maxX:t.start.x,minY:Math.min(t.start.y,t.end.y)-PU,maxY:Math.max(t.start.y,t.end.y)+PU}:{minX:t.start.x,maxX:this.meshBounds.maxX,minY:Math.min(t.start.y,t.end.y)-PU,maxY:Math.max(t.start.y,t.end.y)+PU}:t.expansionDirection.y<0?{minX:Math.min(t.start.x,t.end.x)-PU,maxX:Math.max(t.start.x,t.end.x)+PU,minY:this.meshBounds.minY,maxY:t.start.y}:{minX:Math.min(t.start.x,t.end.x)-PU,maxX:Math.max(t.start.x,t.end.x)+PU,minY:t.start.y,maxY:this.meshBounds.maxY},r=this.meshIndex.search(i.minX,i.minY,i.maxX,i.maxY);let s=null,a=Number.POSITIVE_INFINITY;const c=[...r.map(t=>this.inputProblem.meshNodes[t]),...e];for(const e of c){if(e._containsObstacle)continue;if(!e.availableZ.some(t=>o.includes(t)))continue;const i=Ve(e);if((n?Math.min(Math.max(t.start.y,t.end.y),i.maxY)-Math.max(Math.min(t.start.y,t.end.y),i.minY):Math.min(Math.max(t.start.x,t.end.x),i.maxX)-Math.max(Math.min(t.start.x,t.end.x),i.minX))<=CU)continue;const r=n?t.expansionDirection.x<0?t.start.x-i.maxX:i.minX-t.start.x:t.expansionDirection.y<0?t.start.y-i.maxY:i.minY-t.start.y;r<CU||(r>=a||(a=r,s=e))}return s}createExpandedNode(t,e,n){const o=Ve(e),i=this.getObstacleAvailableZ(t.obstacle);if(Math.abs(t.start.x-t.end.x)<=CU){const r=Math.max(Math.min(t.start.y,t.end.y),o.minY),s=Math.min(Math.max(t.start.y,t.end.y),o.maxY),a=t.expansionDirection.x<0?o.maxX:t.start.x,c=t.expansionDirection.x<0?t.start.x:o.minX;return c-a<=CU||s-r<=CU?null:{capacityMeshNodeId:`bga-gapfill-${n}-${t.obstacle.obstacleId??"no-obstacle"}-${e.capacityMeshNodeId}`,center:{x:(a+c)/2,y:(r+s)/2},width:c-a,height:s-r,layer:`z${i.join(",")}`,availableZ:i}}const r=Math.max(Math.min(t.start.x,t.end.x),o.minX),s=Math.min(Math.max(t.start.x,t.end.x),o.maxX),a=t.expansionDirection.y<0?o.maxY:t.start.y,c=t.expansionDirection.y<0?t.start.y:o.minY;return s-r<=CU||c-a<=CU?null:{capacityMeshNodeId:`bga-gapfill-${n}-${t.obstacle.obstacleId??"no-obstacle"}-${e.capacityMeshNodeId}`,center:{x:(r+s)/2,y:(a+c)/2},width:s-r,height:c-a,layer:`z${i.join(",")}`,availableZ:i}}overlapsExistingGeometry(t,e){for(const e of this.inputProblem.meshNodes)if(this.getSharedOverlapArea(t,e)>0)return!0;for(const n of e)if(this.getSharedOverlapArea(t,n)>0)return!0;for(const e of this.inputProblem.edgesWithObstacle)if(this.getNodeObstacleOverlapArea(t,e.obstacle)>0)return!0;return!1}_step(){const t=[];for(const[e,n]of this.inputProblem.edgesWithObstacle.entries()){const o=this.getClosestMeshNode(n,t);if(!o)continue;const i=this.createExpandedNode(n,o,e);i&&(this.overlapsExistingGeometry(i,t)||t.push(i))}this.expandedNodes=t,this.solved=!0}getOutput(){return this.expandedNodes}visualize(){const t=this.inputProblem.edgesWithObstacle,e=_U(t);return{rects:[...this.inputProblem.meshNodes.map(t=>({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?"rgba(255,0,0,0.16)":"rgba(0,120,255,0.08)",stroke:t._containsObstacle?"rgba(255,0,0,0.35)":"rgba(0,120,255,0.28)"})),...this.expandedNodes.map(n=>{const o=fU(n),i=null===o?null:t[o]??null;return{...Dc(n,{rectMargin:.012,zOffset:.01}),fill:i?pU(i,.24):"rgba(0,160,100,0.24)",stroke:i?pU(i,.72):"rgba(0,160,100,0.68)",label:[i?bU(i,e):"E?","expanded",n.capacityMeshNodeId,`z:${n.availableZ.join(",")}`].join("\n")}})],lines:[...this.inputProblem.edgesWithObstacle.map(t=>({points:[t.start,t.end],strokeColor:pU(t,.9),strokeWidth:.034,label:[bU(t,e),mU(t)].join(" ")})),...this.inputProblem.edgesWithObstacle.map(t=>{const e=gU(t);return{points:[e,{x:e.x+.16*t.expansionDirection.x,y:e.y+.16*t.expansionDirection.y}],strokeColor:pU(t,.7),strokeWidth:.016,strokeDash:"3 3"}})],points:this.inputProblem.edgesWithObstacle.map(t=>({...gU(t),color:pU(t,.95),label:bU(t,e)}))}}},wU=.001,TU=class extends Dt{constructor(t){super(t),this.inputProblem=t}inputProblem;detectEdgesNotConnectedToMesh;expandUnconnectedEdgesToMesh;pipelineDef=[Lt("detectEdgesNotConnectedToMesh",IU,t=>[t.inputProblem]),Lt("expandUnconnectedEdgesToMesh",NU,t=>[{meshNodes:t.inputProblem.meshNodes,edgesWithObstacle:t.detectEdgesNotConnectedToMesh.getOutput(),layerCount:t.inputProblem.layerCount}])];getOutput(){return[...this.inputProblem.meshNodes,...this.expandUnconnectedEdgesToMesh.getOutput()]}getExpandedNodes(){return this.expandUnconnectedEdgesToMesh.getOutput()}getObstacleLayer(t){return`z${(t.obstacle.__zLayers??t.obstacle.layers.map(t=>ko(t,this.inputProblem.layerCount))).join(",")}`}getObstacleRects(){return this.inputProblem.unmarkedComponentObstacles.map(t=>{const e=t.__zLayers??t.layers.map(t=>ko(t,this.inputProblem.layerCount));return{center:t.center,width:t.width,height:t.height,fill:"rgba(150,150,150,0.08)",stroke:"rgba(90,90,90,0.42)",label:t.obstacleId??t.componentId??"bga obstacle",layer:`z${e.join(",")}`}})}getBaseMeshRects(){return this.inputProblem.meshNodes.map(t=>({...Dc(t,{rectMargin:.025,zOffset:.01}),fill:t._containsObstacle?"rgba(210,60,60,0.14)":"rgba(80,120,160,0.08)",stroke:t._containsObstacle?"rgba(190,40,40,0.42)":"rgba(80,120,160,0.28)",label:`mesh ${t.capacityMeshNodeId}\nz:${t.availableZ.join(",")}`}))}initialVisualize(){const t=xU(this.inputProblem.unmarkedComponentObstacles),e=_U(t),n=[...t.map(t=>({points:[t.start,t.end],strokeColor:pU(t,.72),strokeWidth:.018,strokeDash:"0.05 0.035",layer:this.getObstacleLayer(t),label:[bU(t,e),mU(t)].join(" ")})),...t.map(t=>{const e=gU(t);return{points:[e,{x:e.x+.18*t.expansionDirection.x,y:e.y+.18*t.expansionDirection.y}],strokeColor:pU(t,.64),strokeWidth:.012,strokeDash:"0.035 0.025",layer:this.getObstacleLayer(t)}})];return{title:"BGA GapFill: candidate obstacle edges",rects:[...this.getBaseMeshRects(),...this.getObstacleRects()],lines:n}}finalVisualize(){const t=this.getStageOutput("detectEdgesNotConnectedToMesh")??[],e=this.getStageOutput("expandUnconnectedEdgesToMesh")??[],n=_U(xU(this.inputProblem.unmarkedComponentObstacles)),o=new Map;for(const t of e){const e=fU(t);null!==e&&o.set(e,t)}const i=e.map(e=>{const o=fU(e),i=null===o?null:t[o]??null,r=i?(({expandedNode:t,edge:e,meshNodes:n})=>{const o=Ve(t),i=Math.abs(e.start.x-e.end.x)<=wU;return n.filter(n=>{if(n._containsObstacle)return!1;if(!t.availableZ.some(t=>n.availableZ.includes(t)))return!1;const r=Ve(n);return i?!(Math.min(o.maxY,r.maxY)-Math.max(o.minY,r.minY)<=wU)&&(e.expansionDirection.x<0?Math.abs(r.maxX-o.minX)<=wU:Math.abs(r.minX-o.maxX)<=wU):!(Math.min(o.maxX,r.maxX)-Math.max(o.minX,r.minX)<=wU)&&(e.expansionDirection.y<0?Math.abs(r.maxY-o.minY)<=wU:Math.abs(r.minY-o.maxY)<=wU)}).map(t=>t.capacityMeshNodeId)})({expandedNode:e,edge:i,meshNodes:this.inputProblem.meshNodes}):[],s=i?bU(i,n):"E?",a=null===i?"rgba(0,160,100,0.72)":pU(i,.72);return{...Dc(e,{rectMargin:.012,zOffset:.01}),fill:null===i?"rgba(0,160,100,0.24)":pU(i,.16),stroke:a,label:[`${s} gap fill`,r.length>0?`to ${r.join(",")}`:"target mesh not adjacent",`z:${e.availableZ.join(",")}`].join("\n")}}),r=t.map((t,e)=>{const i=o.get(e);return{points:[t.start,t.end],strokeColor:i?pU(t,.68):"rgba(80,80,80,0.14)",strokeWidth:i?.026:.008,...i?{}:{strokeDash:"5 4"},layer:this.getObstacleLayer(t),label:[[bU(t,n),mU(t)].join(" "),i?"filled":"no fill created"].join("\n")}}),s=t.flatMap((t,e)=>{const n=gU(t),i=o.get(e);return i?[{points:[n,i.center],strokeColor:pU(t,.42),strokeWidth:.012,strokeDash:"0.035 0.025",layer:this.getObstacleLayer(t)}]:[]}),a=t.flatMap((t,e)=>o.has(e)?[{...gU(t),color:pU(t,.82),label:bU(t,n),layer:this.getObstacleLayer(t)}]:[]);return{title:"BGA GapFill: disconnected edges and created mesh",rects:[...this.getBaseMeshRects(),...this.getObstacleRects(),...i],lines:[...r,...s],points:a}}};function RU(t,e){const n=[];for(let o=0;o<t.length;o++){const i=t[o];n.push(i);const r=t[o+1];if(void 0===r)continue;const s=Math.round((r-i)/e);if(!(s<=1))for(let t=1;t<s;t++){const e=t/s;n.push(Number((i+(r-i)*e).toFixed(6)))}}return n}var EU=.001;function AU(t){const e=[];for(let n=1;n<t.length;n++){const o=t[n]-t[n-1];o>EU&&e.push(o)}if(0===e.length)return null;const n=Math.min(...e),o=e.filter(t=>t<=1.5*n).sort((t,e)=>t-e),i=Math.floor(o.length/2);return o.length%2==0?(o[i-1]+o[i])/2:o[i]}function OU(t){return[...new Set(t)].sort((t,e)=>t-e)}function kU(t){return Number(t.toFixed(6))}var LU=class t{static fromObstacles(e){if(0===e.length)return null;const n=OU(e.map(t=>t.center.x)),o=OU(e.map(t=>t.center.y)),i=AU(n),r=AU(o);return null===i||null===r?null:new t({obstacles:e,xCoordinates:RU(n,i),yCoordinates:RU(o,r),pitchX:i,pitchY:r})}xCoordinates;yCoordinates;pitchX;pitchY;originX;originY;rowCount;colCount;padWidth;padHeight;slots=new Map;constructor(t){this.xCoordinates=t.xCoordinates,this.yCoordinates=t.yCoordinates,this.pitchX=t.pitchX,this.pitchY=t.pitchY,this.originX=this.xCoordinates[0],this.originY=this.yCoordinates[0],this.colCount=this.xCoordinates.length,this.rowCount=this.yCoordinates.length,this.padWidth=t.obstacles[0].width,this.padHeight=t.obstacles[0].height;for(const e of t.obstacles){const t=this.getSlotForObstacle(e);t&&this.slots.set(this.getSlotKey(t.row,t.col),{...t,obstacle:e})}}getSlotKey(t,e){return`${t}:${e}`}getAxisIndex(t,e){let n=-1,o=Number.POSITIVE_INFINITY;for(let i=0;i<t.length;i++){const r=Math.abs(t[i]-e);r<o&&(o=r,n=i)}return o<=EU?n:null}getAxisCoordinate(t,e){return t[e]}hasPadAt(t,e){return this.slots.has(this.getSlotKey(t,e))}getSlotForObstacle(t){const e=this.getAxisIndex(this.yCoordinates,t.center.y),n=this.getAxisIndex(this.xCoordinates,t.center.x);return null===e||null===n||e<0||e>=this.rowCount||n<0||n>=this.colCount?null:{row:e,col:n}}getSlotCenter(t,e){return{x:this.getAxisCoordinate(this.xCoordinates,e),y:this.getAxisCoordinate(this.yCoordinates,t)}}getHorizontalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t,e+1),i=Math.abs(o.x-n.x);return{orientation:"horizontal",row:t,col:e,center:{x:kU((n.x+o.x)/2),y:n.y},width:i-this.padWidth,height:this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)&&this.hasPadAt(t,e+1)}}getVerticalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t+1,e),i=Math.abs(o.y-n.y);return{orientation:"vertical",row:t,col:e,center:{x:n.x,y:kU((n.y+o.y)/2)},width:this.padWidth,height:i-this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)&&this.hasPadAt(t+1,e)}}getDiagonalGap(t,e){const n=this.getSlotCenter(t,e),o=this.getSlotCenter(t+1,e+1),i=Math.abs(o.x-n.x),r=Math.abs(o.y-n.y);return{orientation:"diagonal",row:t,col:e,center:{x:kU((n.x+o.x)/2),y:kU((n.y+o.y)/2)},width:i-this.padWidth,height:r-this.padHeight,isBetweenTwoPads:this.hasPadAt(t,e)&&this.hasPadAt(t+1,e+1)}}getDiagonalGaps(){const t=[];for(let e=0;e<this.rowCount-1;e++)for(let n=0;n<this.colCount-1;n++)t.push(this.getDiagonalGap(e,n));return t.filter(t=>t.width>EU&&t.height>EU)}getAxisGaps(){const t=[];for(let e=0;e<this.rowCount;e++)for(let n=0;n<this.colCount-1;n++)t.push(this.getHorizontalGap(e,n));for(let e=0;e<this.rowCount-1;e++)for(let n=0;n<this.colCount;n++)t.push(this.getVerticalGap(e,n));return t.filter(t=>t.width>EU&&t.height>EU)}getMissingSlots(){const t=[];for(let e=0;e<this.rowCount;e++)for(let n=0;n<this.colCount;n++)this.hasPadAt(e,n)||t.push({row:e,col:n,center:this.getSlotCenter(e,n),width:this.padWidth,height:this.padHeight});return t}};function DU(t){if([t.point.pointId,t.point.pcb_port_id].filter(t=>"string"==typeof t).some(e=>t.obstacle.connectedTo.includes(e)))return!0;if(0===t.obstacle.connectedTo.length)return!1;if(Be(t.point,t.obstacle)>.001)return!1;const e=xo(t.point).map(e=>ko(e,t.layerCount)),n=t.obstacle.layers.map(e=>ko(e,t.layerCount));return e.some(t=>n.includes(t))}function zU(t){return t.obstacleId??[t.componentId??"no-component",t.center.x,t.center.y,t.width,t.height,t.layers.join(",")].join(":")}function FU({componentId:t,orientationKey:e,row:n,col:o,center:i,width:r,height:s}){return["cmn",e,t,n,o,i.x,i.y,r,s].join("_")}function BU(t){const{componentId:e,bgaGap:n,freeLayers:o,multiLayerThreshold:i}=t,r=n.width>i&&n.height>i;let s="d";"horizontal"===n.orientation&&(s="h"),"vertical"===n.orientation&&(s="v");const a=FU({componentId:e,orientationKey:s,row:n.row,col:n.col,center:n.center,width:n.width,height:n.height});return"diagonal"===n.orientation&&r||!n.isBetweenTwoPads&&r?[{center:n.center,width:n.width,height:n.height,availableZ:[...o],capacityMeshNodeId:`${a}_all`,layer:""}]:o.map(t=>({center:n.center,width:n.width,height:n.height,availableZ:[t],capacityMeshNodeId:`${a}_${t}`,layer:""}))}function jU(t){const{componentId:e,obstacle:n,freeLayers:o,layerCount:i}=t,r=n.layers.map(t=>ko(t,i)),s=o.filter(t=>!r.includes(t)),a=zU(n);return s.map(t=>({capacityMeshNodeId:`free-${e}-${a}-${t}`,center:n.center,width:n.width,height:n.height,layer:`z${t}`,availableZ:[t]}))}function $U(t,e,n){const o=e.layers.map(t=>ko(t,n.layerCount)),i=zU(e),r=function(t){for(const e of t.srj.connections)for(const n of e.pointsToConnect)if(DU({point:n,obstacle:t.obstacle,layerCount:t.srj.layerCount}))return e.__rootConnectionNames?.[0]??e.name}({obstacle:e,srj:n});return{capacityMeshNodeId:`obstacle-${t}-${i}-${o.join(",")}-${e.center.x}-${e.center.y}`,_containsObstacle:!0,...r?{_containsTarget:!0,_targetConnectionName:r}:{},center:e.center,width:e.width,height:e.height,layer:`z${o.join(",")}`,availableZ:o}}var YU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;componentObstacles=[];meshNodes=[];getConstructorParams(){return[this.inputProblem]}_step(){const{srj:t,componentBounds:e,componentId:n,markedComponentObstacles:o,unmarkedComponentObstacles:i}=this.inputProblem,r=t.obstacles.filter(t=>!0===t.isCopperPour).filter(t=>Xe(Ve(t),e)).flatMap(e=>e.layers.map(e=>ko(e,t.layerCount))),s=Array.from({length:t.layerCount},(t,e)=>e).filter(t=>!r.includes(t));if(this.componentObstacles=o,0===o.length||0===s.length)return void(this.solved=!0);const a=LU.fromObstacles(o);if(!a)return void(this.solved=!0);const c=a.getAxisGaps(),l=a.getDiagonalGaps(),d=a.getMissingSlots(),h=1.2*(this.inputProblem.viaDiameter??Yo(t).padDiameter);this.meshNodes=[...c.flatMap(t=>BU({componentId:n,bgaGap:t,freeLayers:s,multiLayerThreshold:h})),...l.flatMap(t=>BU({componentId:n,bgaGap:t,freeLayers:s,multiLayerThreshold:h})),...d.flatMap(t=>function(t){const{componentId:e,missingBgaSlot:n,freeLayers:o,multiLayerThreshold:i}=t,r=FU({componentId:e,orientationKey:"missing",row:n.row,col:n.col,center:n.center,width:n.width,height:n.height});return n.width>i&&n.height>i?[{center:n.center,width:n.width,height:n.height,availableZ:[...o],capacityMeshNodeId:`${r}_all`,layer:""}]:o.map(t=>({center:n.center,width:n.width,height:n.height,availableZ:[t],capacityMeshNodeId:`${r}_${t}`,layer:""}))}({componentId:n,missingBgaSlot:t,freeLayers:s,multiLayerThreshold:h})),...o.flatMap(e=>[...jU({componentId:n,obstacle:e,freeLayers:s,layerCount:t.layerCount}),$U(n,e,t)]),...i.flatMap(e=>[$U(n,e,t)])],this.meshNodes=function(t){const e=new Map;return t.map(t=>{const n=e.get(t.capacityMeshNodeId)??0;return e.set(t.capacityMeshNodeId,n+1),0===n?t:{...t,capacityMeshNodeId:`${t.capacityMeshNodeId}__dup${n}`}})}(this.meshNodes),this.solved=!0}getOutput(){return this.meshNodes}visualize(){return{rects:[{center:{x:(this.inputProblem.componentBounds.minX+this.inputProblem.componentBounds.maxX)/2,y:(this.inputProblem.componentBounds.minY+this.inputProblem.componentBounds.maxY)/2},width:this.inputProblem.componentBounds.maxX-this.inputProblem.componentBounds.minX,height:this.inputProblem.componentBounds.maxY-this.inputProblem.componentBounds.minY,fill:"rgba(0,0,0,0)",stroke:"rgba(30,30,30,0.65)",label:`component ${this.inputProblem.componentId}`},...this.inputProblem.markedComponentObstacles.map(t=>({center:t.center,width:t.width,height:t.height,fill:"rgba(255,0,0,0.18)",stroke:"rgba(255,0,0,0.52)",label:`pad ${t.obstacleId??"obstacle"}`})),...this.inputProblem.unmarkedComponentObstacles.map(t=>({center:t.center,width:t.width,height:t.height,fill:"rgba(255,140,0,0.14)",stroke:"rgba(255,140,0,0.42)",label:`foreign ${t.obstacleId??"obstacle"}`})),...this.meshNodes.map(t=>({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?"rgba(255,0,0,0.14)":t.capacityMeshNodeId.includes("missing")?"rgba(0,200,120,0.18)":"rgba(0,120,255,0.12)",stroke:t._containsObstacle?"rgba(255,0,0,0.36)":t.capacityMeshNodeId.includes("missing")?"rgba(0,200,120,0.52)":"rgba(0,120,255,0.38)"}))]}}};function XU(t){return t.capacityMeshNodeId.startsWith("bga-gapfill-")}function VU(t){return JSON.stringify({availableZ:[...t.availableZ].sort((t,e)=>t-e),_containsTarget:t._containsTarget??!1,_targetConnectionName:t._targetConnectionName??null,_depth:t._depth??null,_strawNode:t._strawNode??!1,_strawParentCapacityMeshNodeId:t._strawParentCapacityMeshNodeId??null,_qfpRegionType:t._qfpRegionType??null,_isNarrowQfpPadGap:t._isNarrowQfpPadGap??!1,_soicRegionType:t._soicRegionType??null,_offBoardConnectionId:t._offBoardConnectionId??null,_offboardNetName:t._offboardNetName??null,_isVirtualOffboard:t._isVirtualOffboard??!1,_containsObstacle:t._containsObstacle??!1})}function WU(t,e){const n=Ve(t);for(const o of e){if(!t.availableZ.some(t=>o.availableZ.includes(t)))continue;const e=Ve(o);if(Xe(n,e))return!0}return!1}function HU(t){const e=t[0];if(!e)throw new Error("createMergedNode requires at least one source node");let n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(const e of t){const t=Ve(e);n=Math.min(n,t.minX),o=Math.max(o,t.maxX),i=Math.min(i,t.minY),r=Math.max(r,t.maxY)}return{...e,capacityMeshNodeId:`merge:${t.map(t=>t.capacityMeshNodeId).join(":")}`,center:{x:(n+o)/2,y:(i+r)/2},width:o-n,height:r-i}}function GU(t,e,n){return{center:t.center,width:t.width,height:t.height,fill:e,stroke:e,label:n}}var UU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;obstacleNodes=[];passthroughNodes=[];mergedNodes=[];pendingGroups=[];totalGroupCount=0;processedGroupCount=0;debugFilteredNodes=[];debugMergeEvents=[];currentGroupKey=null;currentRootNodeId=null;lastMergedNodeId=null;_setup(){this.obstacleNodes=this.inputProblem.meshNodes.filter(t=>!0===t._containsObstacle),this.passthroughNodes=[],this.mergedNodes=[],this.pendingGroups=[],this.totalGroupCount=0,this.processedGroupCount=0,this.debugFilteredNodes=[],this.debugMergeEvents=[],this.currentGroupKey=null,this.currentRootNodeId=null,this.lastMergedNodeId=null;const t=new Map;for(const e of this.inputProblem.meshNodes){if(!0===e._containsObstacle){this.passthroughNodes.push(e),this.debugFilteredNodes.push({type:"preserved-obstacle",node:e,reason:"contains-obstacle"});continue}if(XU(e)){this.passthroughNodes.push(e);continue}if(e.availableZ.length!==this.inputProblem.layerCount){this.passthroughNodes.push(e);continue}let n=!1;for(let t=0;t<this.inputProblem.layerCount;t+=1)if(!e.availableZ.includes(t)){n=!0;break}if(n){this.passthroughNodes.push(e);continue}if(WU(e,this.obstacleNodes)){this.passthroughNodes.push(e),this.debugFilteredNodes.push({type:"preserved-overlap",node:e,reason:"overlaps-obstacle"});continue}const o=VU(e),i=t.get(o);i?i.push(e):t.set(o,[e])}for(const[e,n]of t.entries())n.length<=1?this.passthroughNodes.push(...n):this.pendingGroups.push({groupKey:e,nodes:n});this.pendingGroups.sort((t,e)=>e.nodes.length-t.nodes.length),this.totalGroupCount=this.pendingGroups.length,this.updateStats("setup")}_step(){const t=this.pendingGroups.shift();if(!t)return this.currentGroupKey=null,this.currentRootNodeId=null,this.solved=!0,void this.updateStats("done");const e=t.nodes[0];this.currentGroupKey=t.groupKey,this.currentRootNodeId=e?e.capacityMeshNodeId:null;const n=function(t){if(!t.nodes[0])return{outputNodes:[],mergeEvents:[]};let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.POSITIVE_INFINITY;for(const r of t.nodes){e=Math.min(e,r.width),n=Math.min(n,r.height);const t=Ve(r);o=Math.min(o,t.minX),i=Math.min(i,t.minY)}const r=new Map,s=[];for(const a of t.nodes){const t=Ve(a),c=Math.round((t.minX-o)/e),l=Math.round((t.minY-i)/n),d=Math.max(1,Math.round(a.width/e)),h=Math.max(1,Math.round(a.height/n));for(let t=0;t<h;t+=1)for(let e=0;e<d;e+=1)r.set(`${c+e},${l+t}`,a);s.push({col:c,row:l})}s.sort((t,e)=>t.row-e.row||t.col-e.col);const a=new Set,c=[],l=[];for(const o of s){const i=`${o.col},${o.row}`;if(a.has(i))continue;let s=0;for(;;){const t=`${o.col+s},${o.row}`;if(!r.has(t))break;if(a.has(t))break;s+=1}let d=s,h=1,u=1,p=1;for(let t=1;;t+=1){const i=o.row+t-1;let s=0;for(;s<d;){const t=`${o.col+s},${i}`;if(!r.has(t))break;if(a.has(t))break;s+=1}if(0===s)break;d=Math.min(d,s);for(let o=d;o>=1;o-=1){const i=o*e,r=t*n,s=Math.min(i,r);if((s<=1e-6?Number.POSITIVE_INFINITY:Math.max(i,r)/s)>4)continue;const a=o*t;a>p&&(p=a,h=o,u=t);break}}const m=new Map;for(let t=0;t<u;t+=1)for(let e=0;e<h;e+=1){const n=`${o.col+e},${o.row+t}`,i=r.get(n);i&&(a.add(n),m.set(i.capacityMeshNodeId,i))}const g=[...m.values()];if(g.length<=1){const t=g[0];t&&c.push(t);continue}const f=HU(g);c.push(f),l.push({type:"merge",groupKey:t.groupKey,sourceNodes:g,mergedNode:f})}return{outputNodes:c,mergeEvents:l}}(t);this.mergedNodes.push(...n.outputNodes),this.processedGroupCount+=1,this.debugMergeEvents.push(...n.mergeEvents);const o=n.mergeEvents[n.mergeEvents.length-1];o&&(this.lastMergedNodeId=o.mergedNode.capacityMeshNodeId),this.updateStats(n.mergeEvents.length>0?"merged-group":"passthrough-group")}computeProgress(){return 0===this.totalGroupCount?1:this.processedGroupCount/this.totalGroupCount}updateStats(t){const e=new Set(this.debugMergeEvents.map(t=>t.groupKey)),n={lastAction:t,totalGroupCount:this.totalGroupCount,processedGroupCount:this.processedGroupCount,pendingGroupCount:this.pendingGroups.length,mergedNodeCount:this.mergedNodes.length,passthroughNodeCount:this.passthroughNodes.length,gapFillNodeCount:this.passthroughNodes.filter(XU).length,preservedObstacleNodeCount:this.debugFilteredNodes.filter(t=>"preserved-obstacle"===t.type).length,preservedOverlapNodeCount:this.debugFilteredNodes.filter(t=>"preserved-overlap"===t.type).length,mergeCount:this.debugMergeEvents.length,mergedGroupCount:e.size,currentGroupKey:this.currentGroupKey,currentRootNodeId:this.currentRootNodeId,lastMergedNodeId:this.lastMergedNodeId};this.stats=n}getConstructorParams(){return[this.inputProblem]}getOutput(){return[...this.mergedNodes,...this.passthroughNodes]}visualize(){const t=this.getOutput(),e=this.currentRootNodeId?t.find(t=>t.capacityMeshNodeId===this.currentRootNodeId)??null:null,n=this.lastMergedNodeId?t.find(t=>t.capacityMeshNodeId===this.lastMergedNodeId)??null:null;return{rects:[...this.debugFilteredNodes.map(t=>GU(t.node,"preserved-obstacle"===t.type?"rgba(255,64,64,0.35)":"rgba(255,160,64,0.35)",t.reason)),...this.passthroughNodes.map(t=>GU(t,t._containsObstacle?"rgba(255,0,0,0.35)":XU(t)?"rgba(0,120,255,0.18)":"rgba(160,160,160,0.12)")),...this.mergedNodes.map(t=>GU(t,"rgba(120,120,120,0.14)")),...e?[GU(e,"rgba(255,215,0,0.35)","active-group")]:[],...n?[GU(n,"rgba(0,200,120,0.28)","merged")]:[]]}}},ZU=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;obstacleQueue=[];obstacleQueueIndex=0;meshNodes=[];_setup(){this.obstacleQueue=this.inputProblem.obstacles,this.obstacleQueueIndex=0,this.meshNodes=[...this.inputProblem.meshNodes]}_step(){if(this.obstacleQueueIndex>=this.obstacleQueue.length)return void(this.solved=!0);const t=this.obstacleQueue[this.obstacleQueueIndex],e=t.layers.map(t=>ko(t,this.inputProblem.layerCount)),n=[];for(const o of this.meshNodes){if(o._containsObstacle){n.push(o);continue}if(!e.some(t=>o.availableZ.includes(t))){n.push(o);continue}if(!Xe(Ve(o),Ve(t))){n.push(o);continue}if(1===o.availableZ.length)continue;const i=o.availableZ.filter(t=>!e.includes(t));for(const t of i){const e={...o,capacityMeshNodeId:`${o.capacityMeshNodeId}:z${t}`,availableZ:[t],layer:`z${t}`};n.push(e)}}this.meshNodes=n,this.obstacleQueueIndex+=1,this.stats={obstaclesProcessed:this.obstacleQueueIndex,obstacleCount:this.obstacleQueue.length,meshNodeCount:this.meshNodes.length}}computeProgress(){return 0===this.obstacleQueue.length?1:this.obstacleQueueIndex/this.obstacleQueue.length}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.meshNodes}visualize(){const t=this.obstacleQueueIndex<this.obstacleQueue.length?this.obstacleQueue[this.obstacleQueueIndex]??null:null,e=this.obstacleQueue.slice(0,this.obstacleQueueIndex),n=t?this.obstacleQueue.slice(this.obstacleQueueIndex+1):[];return{rects:[...e.map(t=>({center:t.center,width:t.width,height:t.height,fill:"rgba(160,160,160,0.10)",stroke:"rgba(160,160,160,0.35)",label:`processed ${t.obstacleId??"obstacle"}`})),...t?[{center:t.center,width:t.width,height:t.height,fill:"rgba(255,140,0,0.22)",stroke:"rgba(255,140,0,0.75)",label:`active ${t.obstacleId??"obstacle"}`}]:[],...n.map(t=>({center:t.center,width:t.width,height:t.height,fill:"rgba(255,0,0,0.05)",stroke:"rgba(255,0,0,0.22)",label:`pending ${t.obstacleId??"obstacle"}`})),...this.meshNodes.map(t=>({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?"rgba(255,0,0,0.18)":"rgba(0,120,255,0.12)",stroke:t._containsObstacle?"rgba(255,0,0,0.45)":"rgba(0,120,255,0.45)"}))]}}};dU.register(class extends Dt{constructor(t){super(t),this.inputProblem=t}inputProblem;static componentKind="bga";initialTopologySolver;removeMeshNodeOverlappingWithUnmarkedObstacle;gapfillDueToNodeRemoval;mergeMeshNodes;markedComponentObstacles=[];unmarkedComponentObstacles=[];pipelineDef=[Lt("initialTopologySolver",YU,t=>[{srj:t.inputProblem.inputSrj,componentBounds:t.inputProblem.detectedComponent.bounds,componentId:t.inputProblem.detectedComponent.componentId,markedComponentObstacles:t.markedComponentObstacles,unmarkedComponentObstacles:t.unmarkedComponentObstacles,viaDiameter:t.inputProblem.viaDiameter}]),Lt("removeMeshNodeOverlappingWithUnmarkedObstacle",ZU,t=>[{meshNodes:t.initialTopologySolver.getOutput(),obstacles:t.unmarkedComponentObstacles,layerCount:t.inputProblem.inputSrj.layerCount}]),Lt("gapfillDueToNodeRemoval",TU,t=>[{meshNodes:t.removeMeshNodeOverlappingWithUnmarkedObstacle.getOutput(),unmarkedComponentObstacles:t.unmarkedComponentObstacles,layerCount:t.inputProblem.inputSrj.layerCount}]),Lt("mergeMeshNodes",UU,t=>[{meshNodes:t.gapfillDueToNodeRemoval.getOutput(),layerCount:t.inputProblem.inputSrj.layerCount}])];_setup(){const t=this.inputProblem.detectedComponent.bounds,e=this.inputProblem.detectedComponent.componentId,n=[],o=[];for(const i of this.inputProblem.inputSrj.obstacles){const r=Ve(i);Xe(t,r)&&(i.componentId!==e?o.push(i):n.push(i))}this.markedComponentObstacles=n,this.unmarkedComponentObstacles=o}getConstructorParams(){return[this.inputProblem]}getOutput(){return{routingRegions:this.mergeMeshNodes?.getOutput()??this.gapfillDueToNodeRemoval?.getOutput()??this.removeMeshNodeOverlappingWithUnmarkedObstacle?.getOutput()??[]}}initialVisualize(){return{rects:[{center:{x:(this.inputProblem.detectedComponent.bounds.minX+this.inputProblem.detectedComponent.bounds.maxX)/2,y:(this.inputProblem.detectedComponent.bounds.minY+this.inputProblem.detectedComponent.bounds.maxY)/2},width:this.inputProblem.detectedComponent.bounds.maxX-this.inputProblem.detectedComponent.bounds.minX,height:this.inputProblem.detectedComponent.bounds.maxY-this.inputProblem.detectedComponent.bounds.minY,fill:"rgba(0,0,0,0)",stroke:"rgba(30,30,30,0.65)",label:`bga ${this.inputProblem.detectedComponent.componentId}`},...this.markedComponentObstacles.map(t=>({center:t.center,width:t.width,height:t.height,fill:"rgba(255,0,0,0.18)",stroke:"rgba(255,0,0,0.52)",label:`pad ${t.obstacleId??"obstacle"}`})),...this.unmarkedComponentObstacles.map(t=>({center:t.center,width:t.width,height:t.height,fill:"rgba(255,140,0,0.14)",stroke:"rgba(255,140,0,0.42)",label:`foreign ${t.obstacleId??"obstacle"}`}))]}}finalVisualize(){return{rects:this.getOutput().routingRegions.map(t=>({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?"rgba(255,0,0,0.16)":"rgba(0,120,255,0.12)",stroke:t._containsObstacle?"rgba(255,0,0,0.36)":"rgba(0,120,255,0.42)"}))}}});var qU=1e-6;function JU(t,e){return t.__zLayers&&t.__zLayers.length>0?Lo(t.__zLayers,e):Do(t.layers,e)}function KU(t){const e=[...t].sort((t,e)=>t-e),n=[];for(let t=1;t<e.length;t++){const o=e[t]-e[t-1];o>qU&&n.push(o)}const o=n.length>0?Math.max(qU,Math.min(...n)/4):.001,i=[];for(const t of e){const e=i[i.length-1];(void 0===e||Math.abs(t-e)>o)&&i.push(t)}return i}function QU(t){return Array.from({length:Math.max(0,t)},(t,e)=>e)}var tZ=1e-6;function eZ(t){return t.maxX-t.minX>tZ&&t.maxY-t.minY>tZ}function nZ(t){return function(t){const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return e<=0?0:n/e}(t)>=1.5}function oZ(t,e){const n=[{side:"top",distance:Math.abs(t.center.y-e.minY)},{side:"right",distance:Math.abs(e.maxX-t.center.x)},{side:"bottom",distance:Math.abs(e.maxY-t.center.y)},{side:"left",distance:Math.abs(t.center.x-e.minX)}];return n.sort((t,e)=>t.distance-e.distance),n[0].side}function iZ(t,e){return t.map((t,n)=>({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:"pad",obstacleZ:JU(t,e)}))}function rZ(t,e){return t.map((t,n)=>({key:`thermal-pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:"pad",obstacleZ:JU(t,e)}))}function sZ(t,e){return!!eZ(t)&&Math.min(t.maxX-t.minX,t.maxY-t.minY)<=e}function aZ({side:t,sideObstacles:e,bounds:n,innerBounds:o,narrowThreshold:i}){const r=[];for(let s=0;s<e.length-1;s++){const a=Ee(e[s]),c=Ee(e[s+1]);let l;l="top"===t?{minX:a.maxX,maxX:c.minX,minY:n.minY,maxY:o.minY}:"right"===t?{minX:o.maxX,maxX:n.maxX,minY:a.maxY,maxY:c.minY}:"bottom"===t?{minX:a.maxX,maxX:c.minX,minY:o.maxY,maxY:n.maxY}:{minX:n.minX,maxX:o.minX,minY:a.maxY,maxY:c.minY},r.push({key:`${t}-gap-${s}`,bounds:l,regionType:"pad-gap",isNarrowPadGap:sZ(l,i)})}return r}function cZ({side:t,sideObstacles:e,thermalPadBounds:n,narrowThreshold:o}){const i=[];for(let r=0;r<e.length;r++){const s=Ee(e[r]),a=e[r-1]?Ee(e[r-1]):null,c=e[r+1]?Ee(e[r+1]):null;let l;l="top"===t?{minX:a?(a.maxX+s.minX)/2:s.minX,maxX:c?(s.maxX+c.minX)/2:s.maxX,minY:s.maxY,maxY:n.minY}:"right"===t?{minX:n.maxX,maxX:s.minX,minY:a?(a.maxY+s.minY)/2:s.minY,maxY:c?(s.maxY+c.minY)/2:s.maxY}:"bottom"===t?{minX:a?(a.maxX+s.minX)/2:s.minX,maxX:c?(s.maxX+c.minX)/2:s.maxX,minY:n.maxY,maxY:s.minY}:{minX:s.maxX,maxX:n.minX,minY:a?(a.maxY+s.minY)/2:s.minY,maxY:c?(s.maxY+c.minY)/2:s.maxY},i.push({key:`inner-${t}-pad-${r}`,bounds:l,regionType:"pad-gap",isNarrowPadGap:sZ(l,o)})}return i}function lZ({bounds:t,innerBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:"corner-nw-outer",regionType:"corner",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:"corner-nw-top",regionType:"corner",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:"corner-nw-left",regionType:"corner",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:"corner-ne-outer",regionType:"corner",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:"corner-ne-top",regionType:"corner",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:"corner-ne-right",regionType:"corner",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:"corner-se-outer",regionType:"corner",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:"corner-se-right",regionType:"corner",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:"corner-se-bottom",regionType:"corner",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:"corner-sw-outer",regionType:"corner",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:"corner-sw-bottom",regionType:"corner",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:"corner-sw-left",regionType:"corner",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}function dZ({innerBounds:t,thermalPadBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:"inner-corner-nw-core",regionType:"corner",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:"inner-corner-nw-top",regionType:"corner",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:"inner-corner-nw-left",regionType:"corner",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:"inner-corner-ne-core",regionType:"corner",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:"inner-corner-ne-top",regionType:"corner",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:"inner-corner-ne-right",regionType:"corner",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:"inner-corner-se-core",regionType:"corner",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:"inner-corner-se-right",regionType:"corner",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:"inner-corner-se-bottom",regionType:"corner",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:"inner-corner-sw-core",regionType:"corner",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:"inner-corner-sw-bottom",regionType:"corner",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:"inner-corner-sw-left",regionType:"corner",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind="qfp_thermalpad";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=>t.componentId===o),s=r.length>0?r:e,{padRingObstacles:a,thermalPadObstacles:c}=function(t){return{padRingObstacles:t.filter(nZ),thermalPadObstacles:t.filter(t=>!nZ(t))}}(s),l=function(t,e){const n={top:[],right:[],bottom:[],left:[]};for(const o of t)n[oZ(o,e)].push(o);return n.top.sort((t,e)=>t.center.x-e.center.x),n.bottom.sort((t,e)=>t.center.x-e.center.x),n.left.sort((t,e)=>t.center.y-e.center.y),n.right.sort((t,e)=>t.center.y-e.center.y),n}(a,n),d=function({bounds:t,sideGroups:e}){return{minX:e.left.length>0?Math.max(...e.left.map(t=>Ee(t).maxX)):t.minX,maxX:e.right.length>0?Math.min(...e.right.map(t=>Ee(t).minX)):t.maxX,minY:e.top.length>0?Math.max(...e.top.map(t=>Ee(t).maxY)):t.minY,maxY:e.bottom.length>0?Math.min(...e.bottom.map(t=>Ee(t).minY)):t.maxY}}({bounds:n,sideGroups:l}),h=function(t){return 0===t.length?null:t.reduce((t,e)=>{const n=Ee(e);return{minX:Math.min(t.minX,n.minX),maxX:Math.max(t.maxX,n.maxX),minY:Math.min(t.minY,n.minY),maxY:Math.max(t.maxY,n.maxY)}},Ee(t[0]))}(c);if(!h)return this.failed=!0,void(this.error="QfpThermalPadTopologyGeneratorSolver requires a thermal pad");const u=o,p=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,m=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,g=p+2*m,f=this.inputProblem.inputSrj.minTraceWidth+2*m,y=[...iZ(a,t),...rZ(c,t),...aZ({side:"top",sideObstacles:l.top,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:"right",sideObstacles:l.right,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:"bottom",sideObstacles:l.bottom,bounds:n,innerBounds:d,narrowThreshold:f}),...aZ({side:"left",sideObstacles:l.left,bounds:n,innerBounds:d,narrowThreshold:f}),...cZ({side:"top",sideObstacles:l.top,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:"right",sideObstacles:l.right,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:"bottom",sideObstacles:l.bottom,thermalPadBounds:h,narrowThreshold:f}),...cZ({side:"left",sideObstacles:l.left,thermalPadBounds:h,narrowThreshold:f}),...dZ({innerBounds:d,thermalPadBounds:h,sideGroups:l}),...lZ({bounds:n,innerBounds:d,sideGroups:l})].flatMap(t=>function({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,isNarrowPadGap:r=!1,obstacleZ:s=[]}){if(!eZ(e))return[];const a=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),c=Math.min(a.width,a.height)>o,l=c?[{availableZ:n.filter(t=>!s.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=>s.includes(t)),containsObstacle:!0}].filter(t=>t.availableZ.length>0):n.map(t=>({availableZ:[t],containsObstacle:s.includes(t)}));return l.map(e=>({capacityMeshNodeId:1===l.length?t:c?`${t}:${e.containsObstacle?"obstacle":"free"}`:`${t}:z${e.availableZ[0]}`,center:a.center,width:a.width,height:a.height,layer:`z${e.availableZ.join(",")}`,availableZ:e.availableZ,_qfpRegionType:i,_isNarrowQfpPadGap:r,_containsObstacle:e.containsObstacle}))}({nodeId:`qfp_thermalpad:${u}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:g,regionType:t.regionType,isNarrowPadGap:t.isNarrowPadGap,obstacleZ:t.obstacleZ}));this.output={routingRegions:y},this.stats={componentId:o,layerCount:t,viaDiameter:p,obstacleMargin:m,multiLayerThreshold:g,narrowPadGapThreshold:f,thermalPadCount:c.length,perimeterPadCount:a.length,innerCornerRectCount:y.filter(t=>t.capacityMeshNodeId.includes(":inner-corner-")).length,narrowPadGapNodeCount:y.filter(t=>t._isNarrowQfpPadGap).length,topPadCount:l.top.length,rightPadCount:l.right.length,bottomPadCount:l.bottom.length,leftPadCount:l.left.length,multiLayerNodeCount:y.filter(t=>t.availableZ.length>1).length,totalMeshNodeCount:y.length},this.solved=!0}getOutput(){if(!this.output)throw new Error("QfpThermalPadTopologyGeneratorSolver has not solved yet");return this.output}});var hZ=1e-6;function uZ(t){return t.maxX-t.minX>hZ&&t.maxY-t.minY>hZ}function pZ(t,e){const n=[{side:"top",distance:Math.abs(t.center.y-e.minY)},{side:"right",distance:Math.abs(e.maxX-t.center.x)},{side:"bottom",distance:Math.abs(e.maxY-t.center.y)},{side:"left",distance:Math.abs(t.center.x-e.minX)}];return n.sort((t,e)=>t.distance-e.distance),n[0].side}function mZ(t,e){return t.map((t,n)=>({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:"pad",obstacleZ:JU(t,e),connectedTo:[...t.connectedTo]}))}function gZ(t,e){return!!uZ(t)&&Math.min(t.maxX-t.minX,t.maxY-t.minY)<=e}function fZ({side:t,sideObstacles:e,bounds:n,centralBounds:o,narrowThreshold:i}){const r=[];for(let s=0;s<e.length-1;s++){const a=Ee(e[s]),c=Ee(e[s+1]);let l;l="top"===t?{minX:a.maxX,maxX:c.minX,minY:n.minY,maxY:o.minY}:"right"===t?{minX:o.maxX,maxX:n.maxX,minY:a.maxY,maxY:c.minY}:"bottom"===t?{minX:a.maxX,maxX:c.minX,minY:o.maxY,maxY:n.maxY}:{minX:n.minX,maxX:o.minX,minY:a.maxY,maxY:c.minY},r.push({key:`${t}-gap-${s}`,bounds:l,regionType:"pad-gap",isNarrowPadGap:gZ(l,i)})}return r}function yZ({bounds:t,centralBounds:e,sideGroups:n}){const o=n.top[0]?Ee(n.top[0]):null,i=n.top.at(-1)?Ee(n.top.at(-1)):null,r=n.right[0]?Ee(n.right[0]):null,s=n.right.at(-1)?Ee(n.right.at(-1)):null,a=n.bottom[0]?Ee(n.bottom[0]):null,c=n.bottom.at(-1)?Ee(n.bottom.at(-1)):null,l=n.left[0]?Ee(n.left[0]):null,d=n.left.at(-1)?Ee(n.left.at(-1)):null;return[{key:"corner-nw-outer",regionType:"corner",bounds:{minX:t.minX,maxX:e.minX,minY:t.minY,maxY:e.minY}},{key:"corner-nw-top",regionType:"corner",bounds:{minX:e.minX,maxX:o?.minX??e.minX,minY:t.minY,maxY:e.minY}},{key:"corner-nw-left",regionType:"corner",bounds:{minX:t.minX,maxX:e.minX,minY:e.minY,maxY:l?.minY??e.minY}},{key:"corner-ne-outer",regionType:"corner",bounds:{minX:e.maxX,maxX:t.maxX,minY:t.minY,maxY:e.minY}},{key:"corner-ne-top",regionType:"corner",bounds:{minX:i?.maxX??e.maxX,maxX:e.maxX,minY:t.minY,maxY:e.minY}},{key:"corner-ne-right",regionType:"corner",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.minY,maxY:r?.minY??e.minY}},{key:"corner-se-outer",regionType:"corner",bounds:{minX:e.maxX,maxX:t.maxX,minY:e.maxY,maxY:t.maxY}},{key:"corner-se-right",regionType:"corner",bounds:{minX:e.maxX,maxX:t.maxX,minY:s?.maxY??e.maxY,maxY:e.maxY}},{key:"corner-se-bottom",regionType:"corner",bounds:{minX:c?.maxX??e.maxX,maxX:e.maxX,minY:e.maxY,maxY:t.maxY}},{key:"corner-sw-outer",regionType:"corner",bounds:{minX:t.minX,maxX:e.minX,minY:e.maxY,maxY:t.maxY}},{key:"corner-sw-bottom",regionType:"corner",bounds:{minX:e.minX,maxX:a?.minX??e.minX,minY:e.maxY,maxY:t.maxY}},{key:"corner-sw-left",regionType:"corner",bounds:{minX:t.minX,maxX:e.minX,minY:d?.maxY??e.maxY,maxY:e.maxY}}]}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind="qfp";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=>t.componentId===o),s=r.length>0?r:e,a=function(t,e){const n={top:[],right:[],bottom:[],left:[]};for(const o of t)n[pZ(o,e)].push(o);return n.top.sort((t,e)=>t.center.x-e.center.x),n.bottom.sort((t,e)=>t.center.x-e.center.x),n.left.sort((t,e)=>t.center.y-e.center.y),n.right.sort((t,e)=>t.center.y-e.center.y),n}(s,n),c=function({bounds:t,sideGroups:e}){return{minX:e.left.length>0?Math.max(...e.left.map(t=>Ee(t).maxX)):t.minX,maxX:e.right.length>0?Math.min(...e.right.map(t=>Ee(t).minX)):t.maxX,minY:e.top.length>0?Math.max(...e.top.map(t=>Ee(t).maxY)):t.minY,maxY:e.bottom.length>0?Math.min(...e.bottom.map(t=>Ee(t).minY)):t.maxY}}({bounds:n,sideGroups:a}),l=o,d=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,h=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,u=d+2*h,p=this.inputProblem.inputSrj.minTraceWidth+2*h,m=[{key:"center",bounds:c,regionType:"center"},...mZ(s,t),...fZ({side:"top",sideObstacles:a.top,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:"right",sideObstacles:a.right,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:"bottom",sideObstacles:a.bottom,bounds:n,centralBounds:c,narrowThreshold:p}),...fZ({side:"left",sideObstacles:a.left,bounds:n,centralBounds:c,narrowThreshold:p}),...yZ({bounds:n,centralBounds:c,sideGroups:a})].flatMap(t=>function({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,isNarrowPadGap:r=!1,obstacleZ:s=[],connectedTo:a}){if(!uZ(e))return[];const c=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),l=Math.min(c.width,c.height)>o,d=l?[{availableZ:n.filter(t=>!s.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=>s.includes(t)),containsObstacle:!0}].filter(t=>t.availableZ.length>0):n.map(t=>({availableZ:[t],containsObstacle:s.includes(t)}));return d.map(e=>({capacityMeshNodeId:1===d.length?t:l?`${t}:${e.containsObstacle?"obstacle":"free"}`:`${t}:z${e.availableZ[0]}`,center:c.center,width:c.width,height:c.height,layer:`z${e.availableZ.join(",")}`,availableZ:e.availableZ,_qfpRegionType:i,_isNarrowQfpPadGap:r,_containsObstacle:e.containsObstacle,_connectedTo:e.containsObstacle?a:void 0}))}({nodeId:`qfp:${l}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:u,regionType:t.regionType,isNarrowPadGap:t.isNarrowPadGap,obstacleZ:t.obstacleZ,connectedTo:t.connectedTo}));this.output={routingRegions:m},this.stats={componentId:o,layerCount:t,viaDiameter:d,obstacleMargin:h,multiLayerThreshold:u,narrowPadGapThreshold:p,narrowPadGapNodeCount:m.filter(t=>t._isNarrowQfpPadGap).length,topPadCount:a.top.length,rightPadCount:a.right.length,bottomPadCount:a.bottom.length,leftPadCount:a.left.length,multiLayerNodeCount:m.filter(t=>t.availableZ.length>1).length,totalMeshNodeCount:m.length},this.solved=!0}getOutput(){if(!this.output)throw new Error("QfpTopologyGeneratorSolver has not solved yet");return this.output}});var _Z=1e-6;function bZ({nodeId:t,bounds:e,availableZ:n,multiLayerThreshold:o,regionType:i,obstacleZ:r=[],connectedTo:s}){if(!function(t){return t.maxX-t.minX>_Z&&t.maxY-t.minY>_Z}(e))return[];const a=function(t){return{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY}}(e),c=Math.min(a.width,a.height)>o,l=c?[{availableZ:n.filter(t=>!r.includes(t)),containsObstacle:!1},{availableZ:n.filter(t=>r.includes(t)),containsObstacle:!0}].filter(t=>t.availableZ.length>0):n.map(t=>({availableZ:[t],containsObstacle:r.includes(t)}));return l.map(e=>({capacityMeshNodeId:1===l.length?t:c?`${t}:${e.containsObstacle?"obstacle":"free"}`:`${t}:z${e.availableZ[0]}`,center:a.center,width:a.width,height:a.height,layer:`z${e.availableZ.join(",")}`,availableZ:e.availableZ,_soicRegionType:i,_containsObstacle:e.containsObstacle,_connectedTo:e.containsObstacle?s:void 0}))}function xZ(t,e){let n=0,o=Number.POSITIVE_INFINITY;for(let i=0;i<e.length;i++){const r=Math.abs(t-e[i]);r<o&&(n=i,o=r)}return n}function vZ(t,e){return t.map((t,n)=>({key:`pad:${t.obstacleId??n}`,bounds:Ee(t),regionType:"pad",obstacleZ:JU(t,e),connectedTo:[...t.connectedTo]}))}function SZ(t,e){if(t.componentId!==e.componentId)return!1;const{bounds:n}=e;return t.center.x>=n.minX&&t.center.x<=n.maxX&&t.center.y>=n.minY&&t.center.y<=n.maxY}function IZ({detectedComponent:t,inputSrj:e}){const n=e.obstacles.filter(e=>SZ(e,t)),o=Array.from({length:e.layerCount},(t,e)=>e),i=o.map(t=>vo(t,e.layerCount)),r=Array.from(new Set(n.flatMap(t=>t.connectedTo))),{bounds:s}=t;return{obstacleId:`${t.componentId}_component_bounds`,componentId:t.componentId,type:"rect",layers:i,__zLayers:o,center:{x:(s.minX+s.maxX)/2,y:(s.minY+s.maxY)/2},width:s.maxX-s.minX,height:s.maxY-s.minY,connectedTo:r}}function CZ(t){if(0===t.length)return{minX:0,maxX:0,minY:0,maxY:0};let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t){const t=Ee(r);e=Math.min(e,t.minX),n=Math.max(n,t.maxX),o=Math.min(o,t.minY),i=Math.max(i,t.maxY)}return{minX:e,maxX:n,minY:o,maxY:i}}function PZ(t){const e=t.componentDetectionOutput??[],n=function({detectedComponents:t,inputSrj:e}){return t.map(t=>{const n=e.obstacles.filter(e=>SZ(e,t));return{componentId:t.componentId,componentKind:t.componentKind,memberObstacleIds:n.map((e,n)=>e.obstacleId??`${t.componentId}:member:${n}`),memberObstacles:n,replacementObstacle:IZ({detectedComponent:t,inputSrj:e})}})}({detectedComponents:e,inputSrj:t.inputSrj}),o=t.globalNoConnectionSrj??(e.length>0?function({detectedComponents:t,inputSrj:e}){return{...structuredClone(e),obstacles:[...e.obstacles.filter(e=>!t.some(t=>SZ(e,t))),...t.map(t=>IZ({detectedComponent:t,inputSrj:e}))]}}({detectedComponents:e,inputSrj:t.inputSrj}):t.inputSrj)??t.brokenSrj?.componentsAsObstaclesSrj,i=t.components??n??t.brokenSrj?.components??[];if(!o)throw new Error("MultiGraphTopologyPlannerSolver requires globalNoConnectionSrj or detected components");return{globalNoConnectionSrj:o,components:i}}function MZ({rects:t,components:e}){return t&&0!==e.length?t.filter(t=>!function(t){return"string"==typeof t.label&&t.label.startsWith("node ")}(t)||!e.some(e=>function({rect:t,obstacle:e}){if(!t.center||void 0===t.width||void 0===t.height)return!1;const n=1e-9,o=Ve({center:t.center,width:t.width,height:t.height}),i=Ve({center:e.center,width:e.width,height:e.height});return NZ({bounds:o,outerBounds:i,epsilon:n})}({rect:t,obstacle:e.replacementObstacle}))):t}function NZ({bounds:t,outerBounds:e,epsilon:n}){return t.minX>=e.minX-n&&t.maxX<=e.maxX+n&&t.minY>=e.minY-n&&t.maxY<=e.maxY+n}dU.register(class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;static componentKind="soic";output=null;getConstructorParams(){return[this.inputProblem]}_step(){if(this.output)return void(this.solved=!0);const{layerCount:t,obstacles:e}=this.inputProblem.inputSrj,{bounds:n,componentId:o}=this.inputProblem.detectedComponent,i=QU(t),r=e.filter(t=>t.componentId===o),s=r.length>0?r:e,a=function(t){const e=KU(t.map(t=>t.center.y)).length;return 2===KU(t.map(t=>t.center.x)).length&&2!==e?"vertical-columns":"horizontal-rows"}(s),c=function({obstacles:t,orientation:e}){const n={left:[],right:[],top:[],bottom:[]};if("vertical-columns"===e){const e=KU(t.map(t=>t.center.x));for(const o of t)n[0===xZ(o.center.x,e)?"left":"right"].push(o);return n.left.sort((t,e)=>t.center.y-e.center.y),n.right.sort((t,e)=>t.center.y-e.center.y),n}const o=KU(t.map(t=>t.center.y));for(const e of t)n[0===xZ(e.center.y,o)?"top":"bottom"].push(e);return n.top.sort((t,e)=>t.center.x-e.center.x),n.bottom.sort((t,e)=>t.center.x-e.center.x),n}({obstacles:s,orientation:a}),l=function({bounds:t,orientation:e,sideGroups:n}){return"vertical-columns"===e?{minX:Math.max(...n.left.map(t=>Ee(t).maxX)),maxX:Math.min(...n.right.map(t=>Ee(t).minX)),minY:t.minY,maxY:t.maxY}:{minX:t.minX,maxX:t.maxX,minY:Math.max(...n.top.map(t=>Ee(t).maxY)),maxY:Math.min(...n.bottom.map(t=>Ee(t).minY))}}({bounds:n,orientation:a,sideGroups:c}),d=o,h=this.inputProblem.viaDiameter??Yo(this.inputProblem.inputSrj).padDiameter,u=this.inputProblem.obstacleMargin??this.inputProblem.inputSrj.defaultObstacleMargin??.15,p=2*(h+u),m="vertical-columns"===a?["left","right"]:["top","bottom"],g=[{key:"center",bounds:l,regionType:"center"},...vZ(s,t),...m.flatMap(t=>function({side:t,sideObstacles:e,bounds:n,centralBounds:o}){const i=[];for(let r=0;r<e.length-1;r++){const s=Ee(e[r]),a=Ee(e[r+1]);let c;c="left"===t?{minX:n.minX,maxX:o.minX,minY:s.maxY,maxY:a.minY}:"right"===t?{minX:o.maxX,maxX:n.maxX,minY:s.maxY,maxY:a.minY}:"top"===t?{minX:s.maxX,maxX:a.minX,minY:n.minY,maxY:o.minY}:{minX:s.maxX,maxX:a.minX,minY:o.maxY,maxY:n.maxY},i.push({key:`${t}-gap-${r}`,bounds:c,regionType:"pad-gap"})}return i}({side:t,sideObstacles:c[t],bounds:n,centralBounds:l}))],f=g.flatMap(t=>bZ({nodeId:`soic:${d}:${t.key}`,bounds:t.bounds,availableZ:i,multiLayerThreshold:p,regionType:t.regionType,obstacleZ:t.obstacleZ,connectedTo:t.connectedTo}));this.output={routingRegions:f},this.stats={componentId:o,layerCount:t,orientation:a,viaDiameter:h,obstacleMargin:u,multiLayerThreshold:p,firstSidePadCount:c[m[0]].length,secondSidePadCount:c[m[1]].length,multiLayerNodeCount:f.filter(t=>t.availableZ.length>1).length,totalMeshNodeCount:f.length},this.solved=!0}getOutput(){if(!this.output)throw new Error("SoicTopologyGeneratorSolver has not solved yet");return this.output}});var wZ=class extends kt{constructor(t){super(),this.inputProblem=t}inputProblem;activeSubSolver=null;currentIndex=0;componentMeshNodes=[];getConstructorParams(){return[this.inputProblem]}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.failed)return this.error=this.activeSubSolver.error,this.failed=!0,void(this.activeSubSolver=null);if(!this.activeSubSolver.solved)return;return this.componentMeshNodes.push(this.activeSubSolver.getOutput().routingRegions),this.currentIndex+=1,void(this.activeSubSolver=null)}if(this.currentIndex>=this.inputProblem.componentSrjs.length)return void(this.solved=!0);const t=this.inputProblem.componentKinds[this.currentIndex],e=this.inputProblem.componentSrjs[this.currentIndex],n={inputSrj:e,detectedComponent:{componentId:this.inputProblem.componentIds[this.currentIndex],componentKind:t,bounds:{__type:"rect",...e.bounds}},viaDiameter:this.inputProblem.viaDiameter,obstacleMargin:this.inputProblem.obstacleMargin};this.activeSubSolver=dU.create(n)}getOutput(){return{componentMeshNodes:this.componentMeshNodes}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.inputProblem.componentSrjs[this.currentIndex]??null,e=this.componentMeshNodes.flatMap(t=>t);return{rects:[...t?[{center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,fill:"rgba(0,0,0,0)",stroke:"rgba(255,140,0,0.72)",label:`active component ${this.inputProblem.componentIds[this.currentIndex]??this.currentIndex}`},...t.obstacles.map(t=>({center:t.center,width:t.width,height:t.height,fill:"rgba(255,140,0,0.10)",stroke:"rgba(255,140,0,0.30)",label:t.obstacleId??t.componentId??"obstacle"}))]:[],...e.map(t=>({...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?"rgba(255,0,0,0.14)":"rgba(0,120,255,0.12)",stroke:t._containsObstacle?"rgba(255,0,0,0.34)":"rgba(0,120,255,0.38)"}))]}}},TZ=.001;function RZ(t){const e=[...t].sort((t,e)=>t-e),n=[];for(const t of e){const e=n[n.length-1];(void 0===e||Math.abs(t-e)>TZ)&&n.push(t)}return n}function EZ(t){const e=Math.min(...t),n=Math.max(...t);return!(e<=0)&&n/e<=1.01}function AZ(t){if(!function(t){return EZ(t.map(t=>t.width))&&EZ(t.map(t=>t.height))}(t))return!1;if(!function(t){return t.every(t=>{const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return!(e<=0)&&n/e<=1.5})}(t))return!1;const e=RZ(t.map(t=>t.center.y)),n=RZ(t.map(t=>t.center.x)),o=e.length,i=n.length;if(o<3||i<3)return!1;const r=o*i;return!((r>0?t.length/r:0)<.5)&&!!function(t,e,n){if(e.length<3)return!1;if(n.length<3)return!1;const o=new Set(e.slice(1,-1)),i=new Set(n.slice(1,-1));let r=0;for(const e of t)o.has(e.center.y)&&i.has(e.center.x)&&(r+=1);return r>=1}(t,e,n)}function OZ(t){return[Math.round(t.width/TZ),Math.round(t.height/TZ),t.layers.join(",")].join(":")}function kZ(t){if(t.length<3)return!1;const e=[...t].sort((t,e)=>t-e),n=e[1]-e[0];return!(n<=TZ)&&e.every((t,o)=>0===o||Math.abs(t-e[o-1]-n)<=TZ)}function LZ(t){const e=function(t){const e=new Map;for(const n of t){const t=Math.round(n.center.y/TZ),o=Math.round(n.center.x/TZ),i=e.get(t)??{y:n.center.y,obstaclesByX:new Map};i.obstaclesByX.set(o,n),e.set(t,i)}return[...e.values()]}(t);let n=[];for(const t of e){const o=[...t.obstaclesByX.keys()];if(!kZ([...t.obstaclesByX.values()].map(t=>t.center.x)))continue;const i=e.filter(t=>o.every(e=>t.obstaclesByX.has(e)));if(!kZ(i.map(t=>t.y)))continue;const r=i.flatMap(t=>o.map(e=>t.obstaclesByX.get(e)));r.length>n.length&&(n=r)}return n}function DZ(t){if(AZ(t))return t;const e=Map.groupBy(t,OZ);let n=[];for(const t of e.values()){const e=LZ(t);e.length>n.length&&(n=e)}return n.length>0?n:null}function zZ(t){const e=Math.min(t.width,t.height),n=Math.max(t.width,t.height);return e>0&&n/e>=1.5}function FZ({perimeterPadObstacles:t,thermalPadObstacles:e}){if(0===e.length)return!0;if(e.length>4)return!1;const n=CZ(t),o=n.maxX-n.minX,i=n.maxY-n.minY,r=n.minX+.2*o,s=n.maxX-.2*o,a=n.minY+.2*i,c=n.maxY-.2*i,l=Math.min(...t.map(t=>Math.min(t.width,t.height)));return e.every(t=>{const e=Math.min(t.width,t.height);return t.center.x>=r&&t.center.x<=s&&t.center.y>=a&&t.center.y<=c&&e>l})}function BZ(t){if(t.length<12)return!1;if(t.length>32)return!1;const{counts:e,maxNearestSideRatio:n}=function(t){const e=CZ(t),n=e.maxX-e.minX,o=e.maxY-e.minY,i={top:0,right:0,bottom:0,left:0};if(n<=0||o<=0)return{counts:i,maxNearestSideRatio:1};let r=0;for(const s of t){const t=s.width>s.height,a=[{side:"top",distance:Math.abs(s.center.y-e.minY),axisSpan:o,orientationMatches:!t},{side:"right",distance:Math.abs(e.maxX-s.center.x),axisSpan:n,orientationMatches:t},{side:"bottom",distance:Math.abs(e.maxY-s.center.y),axisSpan:o,orientationMatches:!t},{side:"left",distance:Math.abs(s.center.x-e.minX),axisSpan:n,orientationMatches:t}].filter(t=>t.orientationMatches).sort((t,e)=>t.distance-e.distance)[0];i[a.side]+=1,r=Math.max(r,a.distance/a.axisSpan)}return{counts:i,maxNearestSideRatio:r}}(t);return e.top>=3&&e.right>=3&&e.bottom>=3&&e.left>=3&&n<=.25}function jZ(t){const e=function(t){return t.filter(zZ)}(t);return{perimeterPadObstacles:e,thermalPadObstacles:t.filter(t=>!zZ(t))}}function $Z(t){const e=Math.min(...t),n=Math.max(...t);return!(e<=0)&&n/e<=1.01}function YZ(t,e){let n=0,o=Number.POSITIVE_INFINITY;for(let i=0;i<e.length;i++){const r=Math.abs(t-e[i]);r<o&&(n=i,o=r)}return n}function XZ({memberObstacles:t,inputSrj:e}){if(!function(t){return $Z(t.map(t=>t.width))&&$Z(t.map(t=>t.height))}(t))return!1;const n=RZ(t.map(t=>t.center.y)),o=RZ(t.map(t=>t.center.x));if(!(2===n.length&&o.length>=4||2===o.length&&n.length>=4))return!1;const i=function({memberObstacles:t,rowAxisValues:e,columnAxisValues:n}){if(2===e.length&&n.length>=4){const n=[[],[]];for(const o of t)n[YZ(o.center.y,e)].push(o);return Math.min(...n[1].map(t=>t.center.y-t.height/2))-Math.max(...n[0].map(t=>t.center.y+t.height/2))}if(2===n.length&&e.length>=4){const e=[[],[]];for(const o of t)e[YZ(o.center.x,n)].push(o);return Math.min(...e[1].map(t=>t.center.x-t.width/2))-Math.max(...e[0].map(t=>t.center.x+t.width/2))}return null}({memberObstacles:t,rowAxisValues:n,columnAxisValues:o});if(null===i)return!1;return i>2*(Yo(e).padDiameter+(e.defaultObstacleMargin??.15))}var VZ=[class t{constructor(t){this.params=t}params;static componentKind="qfp_thermalpad";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){const{perimeterPadObstacles:e,thermalPadObstacles:n}=jZ(t);return 0!==n.length&&!!BZ(e)&&FZ({perimeterPadObstacles:e,thermalPadObstacles:n})}(t)}},class t{constructor(t){this.params=t}params;static componentKind="qfp";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){const{perimeterPadObstacles:e,thermalPadObstacles:n}=jZ(t);return!(n.length>0)&&!!FZ({perimeterPadObstacles:e,thermalPadObstacles:n})&&BZ(e)}(t)}},class t{constructor(t){this.params=t}params;static componentKind="soic";componentKind=t.componentKind;static isMatch(t){return XZ(t)}},class t{constructor(t){this.params=t}params;static componentKind="bga";componentKind=t.componentKind;static isMatch({memberObstacles:t}){return function(t){return null!==DZ(t)}(t)}}];function WZ(t){return function(t){for(const e of VZ)if(e.isMatch(t))return new e(t);return null}(t)?.componentKind??null}var HZ=class extends kt{inputSrj;initialized=!1;groupedComponentObstacles={};groupedComponentKinds={};unprocessedComponentIds=[];detectedComponents=[];currentComponentId=null;currentMemberObstacles=[];output=null;constructor({inputSrj:t}){super(),this.inputSrj=t}getConstructorParams(){return[{inputSrj:this.inputSrj}]}_step(){this.initialized?this.output?this.solved=!0:null!==this.currentComponentId||this.unprocessedComponentIds.length>0?this.processNextComponent():(this.finalizeOutput(),this.solved=!0):this.initializeDetectionState()}getOutput(){if(!this.output)throw new Error("ComponentDetectionSolver has not solved yet");return this.output}visualize(){const t=[];t.push(...this.inputSrj.obstacles.filter(t=>!t.componentId).map(t=>({center:t.center,width:t.width,height:t.height,fill:"rgba(120, 120, 120, 0.10)",stroke:"rgba(120, 120, 120, 0.40)",label:t.obstacleId,layer:t.layers.join(","),step:0})));const e=new Set(this.detectedComponents.map(t=>t.componentId));for(const n of this.inputSrj.obstacles){if(!n.componentId)continue;if(e.has(n.componentId))continue;const o=n.componentId===this.currentComponentId,i=Ro(n.componentId),r=this.groupedComponentKinds[n.componentId];t.push({center:n.center,width:n.width,height:n.height,fill:To(i,o?.55:.82),stroke:To(i,o?.1:.45),label:r?`${n.componentId} ${r.toUpperCase()}`:n.componentId,layer:n.layers.join(","),step:o?1:0})}for(const e of this.detectedComponents){const n=Ro(e.componentId);t.push({center:{x:(e.bounds.minX+e.bounds.maxX)/2,y:(e.bounds.minY+e.bounds.maxY)/2},width:e.bounds.maxX-e.bounds.minX,height:e.bounds.maxY-e.bounds.minY,fill:To(n,.88),stroke:To(n,.1),label:`${e.componentId} ${e.componentKind.toUpperCase()} region`,step:2})}return{title:this.getVisualizationTitle(),rects:t,lines:[],points:[],circles:[]}}preview(){return this.visualize()}initializeDetectionState(){this.initialized=!0,this.groupedComponentKinds={},this.groupedComponentObstacles=this.groupObstaclesByComponentId({obstacles:this.inputSrj.obstacles}),this.unprocessedComponentIds=Object.keys(this.groupedComponentObstacles).sort(),this.detectedComponents=[],this.currentComponentId=null,this.currentMemberObstacles=[],this.output=null}processNextComponent(){if(!this.currentComponentId){const t=this.unprocessedComponentIds.shift();return t?(this.currentComponentId=t,void(this.currentMemberObstacles=this.groupedComponentObstacles[t]??[])):(this.currentComponentId=null,void(this.currentMemberObstacles=[]))}if(0===this.currentMemberObstacles.length)return this.currentComponentId=null,void(this.currentMemberObstacles=[]);this.detectedComponents.push(this.createDetectedComponent({componentId:this.currentComponentId,componentKind:this.groupedComponentKinds[this.currentComponentId],memberObstacles:this.currentMemberObstacles})),this.currentComponentId=null,this.currentMemberObstacles=[]}finalizeOutput(){this.output=this.detectedComponents.map(t=>({...t,bounds:{...t.bounds}})),this.stats={initialized:this.initialized,totalComponentCount:Object.keys(this.groupedComponentObstacles).length,detectedComponentCount:this.detectedComponents.length,detectedBgaComponentCount:this.detectedComponents.filter(t=>"bga"===t.componentKind).length,detectedQfpComponentCount:this.detectedComponents.filter(t=>"qfp"===t.componentKind).length,detectedQfpComponentIds:this.detectedComponents.filter(t=>"qfp"===t.componentKind).map(t=>t.componentId),detectedQfpThermalPadComponentCount:this.detectedComponents.filter(t=>"qfp_thermalpad"===t.componentKind).length,detectedQfpThermalPadComponentIds:this.detectedComponents.filter(t=>"qfp_thermalpad"===t.componentKind).map(t=>t.componentId),detectedSoicComponentCount:this.detectedComponents.filter(t=>"soic"===t.componentKind).length,detectedSoicComponentIds:this.detectedComponents.filter(t=>"soic"===t.componentKind).map(t=>t.componentId),remainingComponentCount:this.unprocessedComponentIds.length,hasActiveComponent:null!==this.currentComponentId}}groupObstaclesByComponentId({obstacles:t}){const e={},n={};for(const n of t)n.componentId&&(e[n.componentId]??=[],e[n.componentId].push(n));const o=Object.entries(e).flatMap(([t,e])=>{const o=this.inputSrj.bounds;if(e.some(t=>!NZ({bounds:Ee(t),outerBounds:o,epsilon:0})))return[];const i=WZ({memberObstacles:e,inputSrj:this.inputSrj});if(!i)return[];n[t]=i;return[[t,"bga"===i?DZ(e):e]]});return this.groupedComponentKinds=n,Object.fromEntries(o)}createDetectedComponent({componentId:t,componentKind:e,memberObstacles:n}){return{componentId:t,componentKind:e,bounds:{__type:"rect",...CZ(n)}}}getVisualizationTitle(){const t=Object.keys(this.groupedComponentObstacles).length||new Set(this.inputSrj.obstacles.map(t=>t.componentId).filter(t=>Boolean(t))).size,e=this.detectedComponents.length;return this.initialized?this.output||this.solved?`Component Detection: done ${e}/${t}`:null!==this.currentComponentId||this.unprocessedComponentIds.length>0?`Component Detection: ${e}/${t} processed`:`Component Detection: finalizing ${e}/${t}`:"Component Detection: setup"}},GZ=t=>t.componentId&&t.obstacleId?`${t.componentId}\n${t.obstacleId}`:t.componentId??t.obstacleId??"obstacle",UZ=class extends Dt{rectBoundsComponentDetection;pipelineDef=[Lt("rectBoundsComponentDetection",HZ,t=>[{inputSrj:t.inputProblem.inputSrj}])];getConstructorParams(){return[this.inputProblem]}getOutput(){const t=this.getStageOutput("rectBoundsComponentDetection");if(!t)throw new Error("ComponentDetectionSolver has not solved yet");return t}initialVisualize(){const{bounds:t}=this.inputProblem.inputSrj;return{title:"Component Detection: board and grouped component pads",rects:[{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,fill:"rgba(0, 0, 0, 0)",stroke:"rgba(40, 40, 40, 0.7)",label:"Board bounds",step:0},...this.inputProblem.inputSrj.obstacles.map(t=>{const e=t.componentId?Ro(t.componentId):null;return{center:t.center,width:t.width,height:t.height,fill:e?To(e,.72):"rgba(120, 120, 120, 0.10)",stroke:e?To(e,.28):"rgba(120, 120, 120, 0.40)",label:GZ(t),layer:t.layers.join(","),step:t.componentId?1:0}})],lines:[],points:[],circles:[]}}},ZZ=1e-9;function qZ(t){return Ve({center:t.center,width:t.width,height:t.height})}function JZ(t,e){const n={minX:Math.max(t.minX,e.minX),maxX:Math.min(t.maxX,e.maxX),minY:Math.max(t.minY,e.minY),maxY:Math.min(t.maxY,e.maxY)};return KZ(n)?n:null}function KZ(t){const e=t.maxX-t.minX,n=t.maxY-t.minY,o=Number.isFinite(e)&&e>ZZ,i=Number.isFinite(n)&&n>ZZ;return o&&i}function QZ(t){!function(t){if(!Number.isInteger(t.layerCount))throw new Error("TopologyMergingSolver: layerCount must be an integer");if(t.layerCount<=0)throw new Error("TopologyMergingSolver: layerCount must be positive");if(0===t.nodeGroups.length)throw new Error("TopologyMergingSolver: at least one node group is required");const e=new Set;let n=0;for(const o of t.nodeGroups){if(e.has(o.groupId))throw new Error(`TopologyMergingSolver: duplicate topology group id "${o.groupId}"`);if(e.add(o.groupId),n+=o.nodes.length,0===o.nodes.length)throw new Error(`TopologyMergingSolver: topology group "${o.groupId}" is empty`);const i=new Set;for(const e of o.nodes){if(i.has(e.capacityMeshNodeId))throw new Error(`TopologyMergingSolver: duplicate node id "${e.capacityMeshNodeId}" in group "${o.groupId}"`);i.add(e.capacityMeshNodeId),tq({node:e,groupId:o.groupId,layerCount:t.layerCount})}}if(0===n)throw new Error("TopologyMergingSolver: topology node groups are empty")}(t);const e=[],n=new Map;for(let o=0;o<t.nodeGroups.length;o++){const i=t.nodeGroups[o];for(const t of i.nodes){const r={sourceKey:`${i.groupId}:${t.capacityMeshNodeId}`,groupIndex:o,node:t,bounds:qZ(t)};e.push(r),n.set(r.sourceKey,r)}}return{preparedNodes:e,preparedNodeBySourceKey:n}}function tq({node:t,groupId:e,layerCount:n}){if(!KZ(qZ(t)))throw new Error(`TopologyMergingSolver: node "${t.capacityMeshNodeId}" in group "${e}" has invalid bounds`);if(0===t.availableZ.length)throw new Error(`TopologyMergingSolver: node "${t.capacityMeshNodeId}" in group "${e}" has no available layers`);const o=[...new Set(t.availableZ)].sort((t,e)=>t-e),i=o.some(t=>!Number.isInteger(t)||t<0||t>=n),r=o.length===t.availableZ.length&&o.every((e,n)=>e===t.availableZ[n]);if(i||!r)throw new Error(`TopologyMergingSolver: node "${t.capacityMeshNodeId}" in group "${e}" has invalid or unsorted availableZ`)}var eq=1e-5,nq=4e-5;function oq({regions:t,preparedNodeBySourceKey:e,nodeGroups:n,provenance:o,preserveSourceIds:i=!0}){i&&(o.groupIndexesByNodeId.clear(),o.sourceKeysByNodeId.clear());const r=[...t].sort((t,e)=>t.bounds.minX-e.bounds.minX||t.bounds.minY-e.bounds.minY||t.bounds.maxX-e.bounds.maxX||t.bounds.maxY-e.bounds.maxY||t.availableZ[0]-e.availableZ[0]),s=new Set;return r.map((t,r)=>{const a=t.sourceKeys.map(t=>{const n=e.get(t);if(!n)throw new Error(`TopologyMergingSolver: missing source node for "${t}"`);return n}),c=a.map(({node:t})=>t),l=function({sourceNodes:t,isComponentTopologyNode:e}){if(1===t.length)return{_isComponentTopologyNode:!!e||t[0]._isComponentTopologyNode};const n=t.map(t=>t.capacityMeshNodeId),o=iq(t.map(t=>t._targetConnectionName),"target connection",n),i=iq(t.map(t=>t._offBoardConnectionId),"off-board connection",n),r=iq(t.map(t=>t._offboardNetName),"off-board net",n),s=Array.from(new Set(t.flatMap(t=>t._offBoardConnectedCapacityMeshNodeIds??[]))),a=Array.from(new Set(t.flatMap(t=>t._connectedTo??[])));return{_containsObstacle:t.some(t=>t._containsObstacle)||void 0,_completelyInsideObstacle:t.some(t=>t._completelyInsideObstacle)||void 0,_containsTarget:t.some(t=>t._containsTarget)||void 0,_targetConnectionName:o,_isVirtualOffboard:t.some(t=>t._isVirtualOffboard)||void 0,_offboardNetName:r,_offBoardConnectionId:i,_offBoardConnectedCapacityMeshNodeIds:s.length>0?s:void 0,_qfpRegionType:rq(t.map(t=>t._qfpRegionType)),_isNarrowQfpPadGap:t.some(t=>t._isNarrowQfpPadGap)||void 0,_soicRegionType:rq(t.map(t=>t._soicRegionType)),_isComponentTopologyNode:e||void 0,_connectedTo:a.length>0?a:void 0}}({sourceNodes:c,isComponentTopologyNode:a.some(({groupIndex:t})=>n[t].isComponent)}),d=i&&1===a.length?a[0].node:null,h=Boolean(d&&function({region:t,sourceNode:e,usedNodeIds:n}){const o=qZ(e),i=Math.abs(t.bounds.minX-o.minX)<=eq&&Math.abs(t.bounds.maxX-o.maxX)<=eq&&Math.abs(t.bounds.minY-o.minY)<=eq&&Math.abs(t.bounds.maxY-o.maxY)<=eq,r=t.availableZ.length===e.availableZ.length&&t.availableZ.every((t,n)=>t===e.availableZ[n]);return i&&r&&!n.has(e.capacityMeshNodeId)}({region:t,sourceNode:d,usedNodeIds:s}));let u=h?d.capacityMeshNodeId:`topology_merge_${r}`;for(;s.has(u);)u=`${u}_next`;return s.add(u),i&&(o.groupIndexesByNodeId.set(u,[...new Set(a.map(({groupIndex:t})=>t))]),o.sourceKeysByNodeId.set(u,[...t.sourceKeys])),{...d??c[0],...l,capacityMeshNodeId:u,center:{x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY,layer:`z${t.availableZ.join(",")}`,availableZ:[...t.availableZ],_adjacentNodeIds:void 0,_parent:void 0,_strawNode:void 0,_strawParentCapacityMeshNodeId:void 0}})}function iq(t,e,n){const o=Array.from(new Set(t.filter(t=>void 0!==t)));if(o.length>1)throw new Error(`TopologyMergingSolver: conflicting ${e} values for overlapping source nodes ${n.join(", ")}`);return o[0]}function rq(t){const e=Array.from(new Set(t.filter(t=>void 0!==t)));return 1===e.length?e[0]:void 0}function sq({node:t,sourceKey:e,preparedNodeBySourceKey:n}){const o=n.get(e);if(!o)throw new Error(`TopologyMergingSolver: missing source node for output "${t.capacityMeshNodeId}"`);const i=qZ(t),r=i.minX>=o.bounds.minX-nq&&i.maxX<=o.bounds.maxX+nq&&i.minY>=o.bounds.minY-nq&&i.maxY<=o.bounds.maxY+nq,s=t.availableZ.every(t=>o.node.availableZ.includes(t));if(!r||!s)throw new Error(`TopologyMergingSolver: output node "${t.capacityMeshNodeId}" escapes its source geometry or layers`)}function aq({groupIndexesA:t,groupIndexesB:e,sourceKeysA:n,sourceKeysB:o,sharedLayers:i,preparedNodeBySourceKey:r}){if(1!==t.length||1!==e.length||t[0]!==e[0]||1!==n.length||1!==o.length||n[0]===o[0])return!1;const s=r.get(n[0]),a=r.get(o[0]);if(!s||!a||0===i.length)return!1;return i.some(t=>s.node.availableZ.includes(t)&&a.node.availableZ.includes(t))&&null!==JZ(s.bounds,a.bounds)}function cq(t){const e=[...t].sort((t,e)=>t-e),n=[];for(const t of e){const e=n[n.length-1];(void 0===e||Math.abs(t-e)>eq)&&n.push(t)}return n}function lq(t,e){return e.x>=t.minX-eq&&e.x<=t.maxX+eq&&e.y>=t.minY-eq&&e.y<=t.maxY+eq}function dq({coveringNodes:t,nodeGroups:e,layerCount:n}){const o=new Map;for(let i=0;i<n;i++){const n=t.filter(({node:t})=>t.availableZ.includes(i)).sort((t,e)=>t.sourceKey.localeCompare(e.sourceKey));if(0===n.length)continue;const r=new Set(n.map(({groupIndex:t})=>t)),s=n.filter(({node:t})=>t._containsObstacle&&t._containsTarget),a=s.filter(({groupIndex:t})=>!e[t].isComponent),c=new Set(s.map(({groupIndex:t})=>t)),l=s.length>0?a.length>0||1===c.size?"target-passthrough":"target-merged":1===r.size?"passthrough":"merged",d=gq({topologyMode:l,nodesOnLayer:n,targetObstacleNodes:s,globalTargetObstacleNodes:a});for(const t of d){const e=JSON.stringify({mode:l,sourceKeys:t}),n=o.get(e);n?n.availableZ.push(i):o.set(e,{availableZ:[i],sourceKeys:t,topologyMode:l,topologySignature:e})}}return[...o.values()]}function hq(t){return JSON.stringify({availableZ:t.availableZ,topologySignature:t.topologySignature})}function uq(t){return JSON.stringify({mergeKey:hq(t),minY:t.bounds.minY.toPrecision(15),maxY:t.bounds.maxY.toPrecision(15)})}function pq(t){return JSON.stringify({mergeKey:hq(t),minX:t.bounds.minX.toPrecision(15),maxX:t.bounds.maxX.toPrecision(15)})}function mq(t,e){const n=new Map;for(const o of t){const t="horizontal"===e?uq(o):pq(o),i=n.get(t)??[];i.push(o),n.set(t,i)}return[...n.values()].flatMap(t=>function(t,e){const n=[...t].sort((t,n)=>"horizontal"===e?t.bounds.minX-n.bounds.minX:t.bounds.minY-n.bounds.minY),o=[];for(const t of n){const n=o[o.length-1],i=void 0!==n&&("horizontal"===e?Math.abs(n.bounds.maxX-t.bounds.minX)<=eq:Math.abs(n.bounds.maxY-t.bounds.minY)<=eq);n&&i?"horizontal"===e?n.bounds.maxX=t.bounds.maxX:n.bounds.maxY=t.bounds.maxY:o.push({...t,bounds:{...t.bounds},availableZ:[...t.availableZ],sourceKeys:[...t.sourceKeys]})}return o}(t,e))}function gq({topologyMode:t,nodesOnLayer:e,targetObstacleNodes:n,globalTargetObstacleNodes:o}){if("target-passthrough"===t){return(o.length>0?o:n).map(({sourceKey:t})=>[t])}return"target-merged"===t?[n.map(({sourceKey:t})=>t).sort()]:"passthrough"===t?e.map(({sourceKey:t})=>[t]):[e.map(({sourceKey:t})=>t).sort()]}var fq=class extends kt{constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e5;const{preparedNodes:e,preparedNodeBySourceKey:n}=QZ(t);this.preparedNodes=e,this.preparedNodeBySourceKey=n,this.xCoordinates=cq(this.preparedNodes.flatMap(({bounds:t})=>[t.minX,t.maxX])),this.stats={inputNodeCount:this.preparedNodes.length,xSlabCount:Math.max(0,this.xCoordinates.length-1),processedXSlabCount:0,atomicRegionCount:0,outputNodeCount:0}}inputProblem;preparedNodes;preparedNodeBySourceKey;outputProvenance={groupIndexesByNodeId:new Map,sourceKeysByNodeId:new Map};xCoordinates;atomicRegions=[];outputNodes=[];currentXIndex=0;getConstructorParams(){return[this.inputProblem]}_step(){if(1===this.inputProblem.nodeGroups.length)return void this.completePassthroughTopology();if(this.currentXIndex<this.xCoordinates.length-1)return this.processCurrentXSlab(),this.currentXIndex+=1,this.stats.processedXSlabCount=this.currentXIndex,void(this.stats.atomicRegionCount=this.atomicRegions.length);const t=function(t){let e=t;for(;;){const t=mq(e,"horizontal"),n=mq(t,"vertical");if(n.length===e.length)return n;e=n}}(function({regions:t,preparedNodeBySourceKey:e}){const n=new Map;for(const e of t)for(const t of e.sourceKeys){const o=n.get(t)??new Set;o.add(e.topologyMode),n.set(t,o)}const o=new Set([...n.entries()].filter(([,t])=>1===t.size&&t.has("target-passthrough")).map(([t])=>t));return 0===o.size?t:[...t.filter(t=>"target-passthrough"!==t.topologyMode||!o.has(t.sourceKeys[0])),...[...o].map(t=>{const n=e.get(t);if(!n)throw new Error(`TopologyMergingSolver: missing authoritative target source "${t}"`);return{bounds:{...n.bounds},availableZ:[...n.node.availableZ],sourceKeys:[t],topologyMode:"target-passthrough",topologySignature:JSON.stringify({mode:"target-passthrough",sourceKeys:[t]})}})]}({regions:this.atomicRegions,preparedNodeBySourceKey:this.preparedNodeBySourceKey}));this.outputNodes=oq({regions:t,preparedNodeBySourceKey:this.preparedNodeBySourceKey,nodeGroups:this.inputProblem.nodeGroups,provenance:this.outputProvenance}),function({nodes:t,preparedNodeBySourceKey:e,provenance:n}){const o=new Set;for(const i of t){if(o.has(i.capacityMeshNodeId))throw new Error(`TopologyMergingSolver: duplicate output node id "${i.capacityMeshNodeId}"`);if(o.add(i.capacityMeshNodeId),!KZ(qZ(i)))throw new Error(`TopologyMergingSolver: output node "${i.capacityMeshNodeId}" has invalid bounds`);if(0===i.availableZ.length)throw new Error(`TopologyMergingSolver: output node "${i.capacityMeshNodeId}" has no available layers`);const t=n.sourceKeysByNodeId.get(i.capacityMeshNodeId);if(!t)throw new Error(`TopologyMergingSolver: missing output provenance for node "${i.capacityMeshNodeId}"`);1===t.length&&sq({node:i,sourceKey:t[0],preparedNodeBySourceKey:e})}for(let o=0;o<t.length;o++){const i=t[o];for(let r=o+1;r<t.length;r++){const o=t[r],s=i.availableZ.filter(t=>o.availableZ.includes(t));if(0===s.length)continue;const a=JZ(qZ(i),qZ(o));if(!a)continue;const c=a.maxX-a.minX,l=a.maxY-a.minY;if(c<=nq||l<=nq)continue;const d=n.groupIndexesByNodeId.get(i.capacityMeshNodeId),h=n.groupIndexesByNodeId.get(o.capacityMeshNodeId);if(!d||!h)throw new Error(`TopologyMergingSolver: missing output provenance for overlapping nodes "${i.capacityMeshNodeId}" and "${o.capacityMeshNodeId}"`);const u=n.sourceKeysByNodeId.get(i.capacityMeshNodeId),p=n.sourceKeysByNodeId.get(o.capacityMeshNodeId);if(!u||!p)throw new Error(`TopologyMergingSolver: missing source provenance for overlapping nodes "${i.capacityMeshNodeId}" and "${o.capacityMeshNodeId}"`);if(!aq({groupIndexesA:d,groupIndexesB:h,sourceKeysA:u,sourceKeysB:p,sharedLayers:s,preparedNodeBySourceKey:e}))throw new Error(`TopologyMergingSolver: output nodes "${i.capacityMeshNodeId}" and "${o.capacityMeshNodeId}" have an unresolved inter-group overlap on a shared layer`)}}}({nodes:this.outputNodes,preparedNodeBySourceKey:this.preparedNodeBySourceKey,provenance:this.outputProvenance}),this.stats.outputNodeCount=this.outputNodes.length,this.stats.compactedRegionCount=t.length,this.solved=!0}getOutput(){if(!this.solved)throw new Error("TopologyMergingSolver: getOutput() called before the solver completed");return this.outputNodes}computeProgress(){const t=Math.max(1,this.xCoordinates.length-1);return this.solved?1:Math.min(.99,this.currentXIndex/t)}visualize(){const t=this.solved?this.outputNodes:oq({regions:this.atomicRegions,preparedNodeBySourceKey:this.preparedNodeBySourceKey,nodeGroups:this.inputProblem.nodeGroups,provenance:this.outputProvenance,preserveSourceIds:!1});return{title:`Topology Merging: ${t.length} refined regions`,coordinateSystem:"cartesian",rects:t.map(t=>({...Dc(t,{rectMargin:.01,zOffset:.02}),label:`${t.capacityMeshNodeId}\navailableZ: ${t.availableZ.join(",")}\ncomponent: ${t._isComponentTopologyNode?"yes":"no"}`})),lines:[],points:[],circles:[],texts:[]}}completePassthroughTopology(){const t=this.inputProblem.nodeGroups[0];this.outputNodes=t.nodes;for(const e of this.outputNodes)this.outputProvenance.groupIndexesByNodeId.set(e.capacityMeshNodeId,[0]),this.outputProvenance.sourceKeysByNodeId.set(e.capacityMeshNodeId,[`${t.groupId}:${e.capacityMeshNodeId}`]);this.stats.processedXSlabCount=this.stats.xSlabCount,this.stats.atomicRegionCount=0,this.stats.compactedRegionCount=0,this.stats.outputNodeCount=this.outputNodes.length,this.stats.passthroughNodeCount=this.outputNodes.length,this.solved=!0}processCurrentXSlab(){const t=this.xCoordinates[this.currentXIndex],e=this.xCoordinates[this.currentXIndex+1];if(e-t<=eq)return;const n=(t+e)/2,o=this.preparedNodes.filter(({bounds:t})=>n>=t.minX-eq&&n<=t.maxX+eq),i=cq(o.flatMap(({bounds:t})=>[t.minY,t.maxY]));for(let r=0;r<i.length-1;r++){const s=i[r],a=i[r+1];if(a-s<=eq)continue;const c={x:n,y:(s+a)/2},l=o.filter(({bounds:t})=>lq(t,c));if(0===l.length)continue;const d=dq({coveringNodes:l,nodeGroups:this.inputProblem.nodeGroups,layerCount:this.inputProblem.layerCount});for(const n of d)this.atomicRegions.push({bounds:{minX:t,maxX:e,minY:s,maxY:a},availableZ:n.availableZ,sourceKeys:n.sourceKeys,topologyMode:n.topologyMode,topologySignature:n.topologySignature})}}};function yq({meshNodes:t,components:e}){return 0===e.length?t:t.map(t=>{const n=e.some(e=>function({node:t,component:e}){const{replacementObstacle:n}=e,o=Math.abs(t.center.x-n.center.x)<=ZZ&&Math.abs(t.center.y-n.center.y)<=ZZ&&Math.abs(t.width-n.width)<=ZZ&&Math.abs(t.height-n.height)<=ZZ;if("qfp"!==e.componentKind&&"qfp_thermalpad"!==e.componentKind&&"soic"!==e.componentKind)return o;const i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=n.center.y-n.height/2,a=n.center.y+n.height/2,c=t.center.x>=i-ZZ&&t.center.x<=r+ZZ&&t.center.y>=s-ZZ&&t.center.y<=a+ZZ,l=t.width*t.height,d=n.width*n.height,h=c&&l>=.2*d;return o||h}({node:t,component:e}));return n?{...t,_containsObstacle:void 0,_completelyInsideObstacle:void 0,_containsTarget:void 0,_targetConnectionName:void 0,_connectedTo:void 0}:t})}var _q=class extends Dt{globalTopologySolver;componentTopologyBatchSolver;normalizedInput;pipelineDef=[Lt("globalTopologySolver",Kn,t=>[t.getGlobalTopologySolverInput()]),Lt("componentTopologyBatchSolver",wZ,t=>[{componentSrjs:t.getComponentNoConnectionSrjs(),componentIds:t.normalizedInput.components.map(t=>t.componentId),componentKinds:t.normalizedInput.components.map(t=>t.componentKind),viaDiameter:t.inputProblem.viaDiameter,obstacleMargin:t.inputProblem.obstacleMargin}])];constructor(t){super(t),this.normalizedInput=PZ(t)}getConstructorParams(){return[this.inputProblem]}getOutput(){const t=yq({meshNodes:this.getStageOutput("globalTopologySolver")?.meshNodes??[],components:this.normalizedInput.components}),e=this.getStageOutput("componentTopologyBatchSolver")?.componentMeshNodes??[],n=this.getComponentNoConnectionSrjs();return{globalNoConnectionSrj:this.normalizedInput.globalNoConnectionSrj,componentNoConnectionSrjs:n,globalMeshNodes:t,componentMeshNodes:e}}finalVisualize(){const t=this.getOutput();return{title:"Topology Planning: generated topology groups",rects:[...t.componentNoConnectionSrjs.flatMap((t,e)=>{const n=this.normalizedInput.components[e]??null;return t.obstacles.map(t=>({center:t.center,width:t.width,height:t.height,fill:"rgba(120, 120, 120, 0.06)",stroke:"rgba(120, 120, 120, 0.35)",label:t.obstacleId??n?.componentId??"component-pad",layer:t.layers.join(",")}))}),...[...t.globalMeshNodes,...t.componentMeshNodes.flat()].map(t=>{const e=this.normalizedInput.components.find(e=>t.capacityMeshNodeId.includes(e.componentId));return{...Dc(t,{rectMargin:.01}),fill:t._containsObstacle?To("red",.82):"rgba(0, 120, 255, 0.12)",stroke:t._containsObstacle?To("red",.3):"rgba(0, 120, 255, 0.55)",label:e?`${e.componentKind.toUpperCase()} ${t.capacityMeshNodeId}`:t.capacityMeshNodeId}})],lines:[],points:[],circles:[],texts:[]}}visualize(){return this.filterGlobalRectDiffNodesFromVisualization({visualization:super.visualize()})}preview(){return this.filterGlobalRectDiffNodesFromVisualization({visualization:super.preview()})}getComponentNoConnectionSrjs(){return this.normalizedInput.components.map(t=>function({inputSrj:t,component:e}){const n=CZ(e.memberObstacles),o=Math.max(t.minViaPadDiameter??t.min_via_pad_diameter??t.minViaDiameter??.3,t.defaultObstacleMargin??.15,2*t.minTraceWidth),i=new Set(e.memberObstacles.flatMap(t=>t.connectedTo)),r=t.connections.flatMap(t=>t.pointsToConnect.filter(t=>{const e=[t.pointId,t.pcb_port_id].filter(t=>"string"==typeof t).some(t=>i.has(t)),r=t.x>=n.minX-o&&t.x<=n.maxX+o&&t.y>=n.minY-o&&t.y<=n.maxY+o;return e&&r})).reduce((t,e)=>({minX:Math.min(t.minX,e.x),maxX:Math.max(t.maxX,e.x),minY:Math.min(t.minY,e.y),maxY:Math.max(t.maxY,e.y)}),n),s=t.obstacles.filter(t=>Xe(Ee(t),r)).map(t=>({...t}));return{...structuredClone(t),bounds:r,obstacles:s}}({inputSrj:this.inputProblem.inputSrj,component:t}))}getGlobalTopologySolverInput(){return{simpleRouteJson:this.normalizedInput.globalNoConnectionSrj,maxGapFillPasses:4}}filterGlobalRectDiffNodesFromVisualization({visualization:t}){return{...t,rects:MZ({rects:t.rects,components:this.normalizedInput.components})}}},bq=(t,e)=>{if(t)return Object.entries(e).sort(([t],[e])=>e.length-t.length).find(([e])=>t.includes(e))?.[1]},xq=(t,e)=>({...t,points:t.points?.map(t=>({...t,color:bq(t.label,e)??t.color})),lines:t.lines?.map(t=>({...t,strokeColor:bq(t.label,e)??t.strokeColor})),circles:t.circles?.map(t=>{const n=bq(t.label,e);return n?{...t,fill:n,stroke:n}:t})}),vq=class extends si{constructor(t){super(),this.topologyPlanningSolver=t,this.solved=t.solved,this.failed=t.failed,this.error=t.error,this.stats=t.stats}topologyPlanningSolver;getOutput(){return this.topologyPlanningSolver.getOutput().componentMeshNodes.flat()}visualize(){return this.topologyPlanningSolver.finalVisualize()??this.topologyPlanningSolver.visualize()}preview(){return this.visualize()}},Sq=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:[]}}},Iq=t=>t.filter(t=>Boolean(t)),Cq=(t,e,n)=>{const o=`${Math.round(100*t.x)},${Math.round(100*t.y)}`,i=e.map(t=>((t,e)=>"top"===t?0:"bottom"===t?e-1:Number.parseInt(t.slice(5),10))(t,n)).sort().join("-");return`${o}:${i}`},Pq=class{parent=new Map;constructor(t,e=t.traces??[],n={}){for(const e of t.connections)this.unionAll(Iq([e.name,e.source_trace_id,e.rootConnectionName,e.netConnectionName,...e.mergedConnectionNames??[],...e.pointsToConnect.flatMap(e=>[e.pointId,e.pcb_port_id,...n.includePhysicalPositionAliases?[Cq(e,e.layers??[e.layer],t.layerCount)]:[]])]));for(const n of[...e,...t.fixedTraces??[]])this.unionAll(Iq([n.pcb_trace_id,n.connection_name,n.source_trace_id,n.rootConnectionName,...n.mergedConnectionNames??[],...n.connectsTo??[]]));for(const e of t.obstacles)this.unionAll(n.includePhysicalPositionAliases?Iq([e.obstacleId,...e.connectedTo,...e.offBoardConnectsTo??[],Cq(e.center,e.layers,t.layerCount)]):e.connectedTo)}canonicalize(t){return[...new Set(t.map(t=>this.find(t)))]}unionAll(t){const e=t[0];if(e){this.add(e);for(let n=1;n<t.length;n++)this.union(e,t[n])}}add(t){this.parent.has(t)||this.parent.set(t,t)}find(t){this.add(t);const e=this.parent.get(t);if(e===t)return t;const n=this.find(e);return this.parent.set(t,n),n}union(t,e){const n=this.find(t),o=this.find(e);n!==o&&this.parent.set(o,n)}},Mq=1e-6,Nq=(t,e)=>Math.hypot(e.x-t.x,e.y-t.y),wq=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r<=1e-12)return Nq(t,e);const s=Rq(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return Math.hypot(t.x-(e.x+o*s),t.y-(e.y+i*s))},Tq=(t,e,n=1e-6)=>Math.abs(t.x-e.x)<=n&&Math.abs(t.y-e.y)<=n,Rq=(t,e,n)=>Math.max(e,Math.min(n,t)),Eq=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),Aq=(t,e,n)=>Math.abs(Eq(e,n,t))<=1e-9&&t.x>=Math.min(e.x,n.x)-1e-9&&t.x<=Math.max(e.x,n.x)+1e-9&&t.y>=Math.min(e.y,n.y)-1e-9&&t.y<=Math.max(e.y,n.y)+1e-9,Oq=(t,e,n,o)=>((t,e,n,o)=>{const i=Eq(t,e,n),r=Eq(t,e,o),s=Eq(n,o,t),a=Eq(n,o,e);return i*r<0&&s*a<0||Math.abs(i)<=1e-9&&Aq(n,t,e)||Math.abs(r)<=1e-9&&Aq(o,t,e)||Math.abs(s)<=1e-9&&Aq(t,n,o)||Math.abs(a)<=1e-9&&Aq(e,n,o)})(t,e,n,o)?0:Math.min(wq(t,n,o),wq(e,n,o),wq(n,t,e),wq(o,t,e)),kq=(t,e)=>{let n=!1;for(let o=0,i=e.length-1;o<e.length;i=o++){const r=e[o],s=e[i];if(Aq(t,s,r))return!0;r.y>t.y!=s.y>t.y&&t.x<(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x&&(n=!n)}return n},Lq=(t,e,n)=>{if(kq(t,n)||kq(e,n))return 0;let o=Number.POSITIVE_INFINITY;for(let i=0;i<n.length;i++){const r=n[i],s=n[(i+1)%n.length];o=Math.min(o,Oq(t,e,r,s))}return o};function Dq(t,e,n){let o=0,i=1;const r=e.x-t.x,s=e.y-t.y,a=[[-r,t.x-n.minX],[r,n.maxX-t.x],[-s,t.y-n.minY],[s,n.maxY-t.y]];for(const[t,e]of a){if(Math.abs(t)<1e-12){if(e<0)return!1;continue}const n=e/t;if(t<0?o=Math.max(o,n):i=Math.min(i,n),o>i)return!1}return!0}function zq({start:t,end:e,width:n,base:o}){const i=Nq(t,e),r=(t=>Rq(1.25*t,.25,.75))(n),s=Math.max(1,Math.ceil(i/r)),a=n/2,c=[];for(let i=0;i<s;i++){const r=i/s,l=(i+1)/s,d=t.x+(e.x-t.x)*r,h=t.y+(e.y-t.y)*r,u=t.x+(e.x-t.x)*l,p=t.y+(e.y-t.y)*l;c.push({...o,minX:Math.min(d,u)-a,minY:Math.min(h,p)-a,maxX:Math.max(d,u)+a,maxY:Math.max(h,p)+a,exactShape:{type:"segment",start:{x:d,y:h},end:{x:u,y:p},width:n}})}return c}var Fq=(t,e,n)=>{const o=Math.cos(n),i=Math.sin(n),r=t.x-e.x,s=t.y-e.y;return{x:e.x+r*o-s*i,y:e.y+r*i+s*o}};var Bq=class{nodeIndices=[];priorities=[];get size(){return this.nodeIndices.length}push(t,e){let n=this.nodeIndices.length;for(this.nodeIndices.push(t),this.priorities.push(e);n>0;){const t=n-1>>1;if(this.priorities[t]<=e)break;this.swap(n,t),n=t}}pop(){const t=this.nodeIndices[0],e=this.nodeIndices.pop(),n=this.priorities.pop();if(0===this.nodeIndices.length)return t;this.nodeIndices[0]=e,this.priorities[0]=n;let o=0;for(;;){const t=2*o+1,e=t+1;if(t>=this.nodeIndices.length)break;let n=t;if(e<this.nodeIndices.length&&this.priorities[e]<this.priorities[t]&&(n=e),this.priorities[o]<=this.priorities[n])break;this.swap(o,n),o=n}return t}swap(t,e){[this.nodeIndices[t],this.nodeIndices[e]]=[this.nodeIndices[e],this.nodeIndices[t]],[this.priorities[t],this.priorities[e]]=[this.priorities[e],this.priorities[t]]}},jq=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]],$q=["#d53535","#3478c8","#8e44ad","#15956f"],Yq=class extends Sq{problem;searchBounds;rows;columns;origin;nodes=[];open=new Bq;bestCost=new Map;closed=new Set;baseStateCount;stateSpaceUpperBound;endLayerIndices;targetCell;segmentWidthCache=new Map;closedStateCount=0;output=null;constructor(t){super(),this.problem=t;const e=Math.max(t.traceWidth,t.viaDiameter)/2+t.obstacleIndex.clearance,n=Rq(Math.min(t.start.x,t.end.x)-t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),o=Rq(Math.max(t.start.x,t.end.x)+t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),i=Rq(Math.min(t.start.y,t.end.y)-t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),r=Rq(Math.max(t.start.y,t.end.y)+t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),s=Math.floor((n-t.gridOffset.x)/t.gridSize)*t.gridSize+t.gridOffset.x,a=Math.floor((i-t.gridOffset.y)/t.gridSize)*t.gridSize+t.gridOffset.y;this.origin={x:s,y:a},this.columns=Math.max(2,Math.floor((o-s)/t.gridSize)+1),this.rows=Math.max(2,Math.floor((r-a)/t.gridSize)+1),this.searchBounds={minX:s,minY:a,maxX:s+(this.columns-1)*t.gridSize,maxY:a+(this.rows-1)*t.gridSize};const c=this.rows*this.columns*t.layers.length*(t.maxViaCount+1);this.baseStateCount=c,this.stateSpaceUpperBound=c*(this.rows*this.columns+1),this.targetCell=this.pointToCell(t.end),this.endLayerIndices=new Set(t.endLayers.map(e=>t.layers.indexOf(e)).filter(t=>t>=0));const l=this.pointToCell(t.start);for(const e of t.startLayers){const n=t.layers.indexOf(e);if(n<0||this.endpointCollides(t.start,n))continue;const o={...l,...t.start,layerIndex:n,viaCount:0,viaPoints:[],g:0,f:this.heuristic(t.start),parentIndex:-1},i=this.nodes.length;this.nodes.push(o),this.open.push(i,o.f),this.bestCost.set(this.toStateIndex(o),0)}0!==this.open.size&&0!==this.endLayerIndices.size||(this.failed=!0,this.error="No collision-free multilayer route endpoint"),this.MAX_ITERATIONS=Math.min(15e3,Math.max(2e3,2*c)),this.stats=this.createStats()}getSolverName(){return`LayerAwareGridRouteSolver(${this.problem.gridSize.toFixed(3)}mm)`}_step(){if(0===this.open.size)return this.failed=!0,void(this.error="No collision-free multilayer grid route found");const t=this.open.pop(),e=this.nodes[t],n=this.toStateIndex(e);if(!this.closed.has(n)){if(this.closed.add(n),this.closedStateCount++,e.row===this.targetCell.row&&e.column===this.targetCell.column&&this.endLayerIndices.has(e.layerIndex)&&e.viaCount>=this.problem.minViaCount&&!this.segmentCollides(e,this.problem.end))return this.output=this.reconstructRoute(t),this.solved=!0,void(this.stats=this.createStats());this.expandPlanarMoves(t,e),this.expandViaMoves(t,e),this.stats=this.createStats()}}expandPlanarMoves(t,e){for(const[n,o]of jq){const i=e.row+n,r=e.column+o;if(i<0||i>=this.rows||r<0||r>=this.columns)continue;const s=this.cellToPoint(i,r),a=this.getSafeSegmentWidth(e,s);if(a<=0)continue;const c=this.problem.gridSize*(0!==n&&0!==o?Math.SQRT2:1)*Math.max(1,(this.problem.traceWidth/a)**this.problem.neckPenaltyExponent);this.enqueueNode({row:i,column:r,...s,layerIndex:e.layerIndex,viaCount:e.viaCount,viaPoints:e.viaPoints,g:e.g+c,parentIndex:t})}}expandViaMoves(t,e){if(e.viaCount>=this.problem.maxViaCount)return;const n=.5*this.problem.gridSize;if(Nq(e,this.problem.start)<n-1e-9||Nq(e,this.problem.end)<n-1e-9)return;const o=e.parentIndex>=0?this.nodes[e.parentIndex]:void 0;if(!o||o.layerIndex===e.layerIndex||!Tq(o,e))for(let n=0;n<this.problem.layers.length;n++)n!==e.layerIndex&&(this.problem.obstacleIndex.collidesVia({point:e,layers:this.problem.layers,padDiameter:this.problem.viaDiameter,holeDiameter:this.problem.viaHoleDiameter,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreTraceIndices:this.problem.softTraceIndices,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance,blockSameNetObstacles:!0,sameNetObstacleClearance:0,otherNewViaPoints:e.viaPoints,fixedVias:this.problem.fixedVias})||this.enqueueNode({row:e.row,column:e.column,x:e.x,y:e.y,layerIndex:n,viaCount:e.viaCount+1,viaPoints:[...e.viaPoints,{x:e.x,y:e.y}],g:e.g+this.problem.viaCost,parentIndex:t}))}enqueueNode(t){const e=this.toStateIndex(t);if(this.closed.has(e)||t.g>=(this.bestCost.get(e)??Number.POSITIVE_INFINITY))return;this.bestCost.set(e,t.g);const n=t.g+this.heuristic(t),o=this.nodes.length;this.nodes.push({...t,f:n}),this.open.push(o,n)}endpointCollides(t,e){return this.getSafeSegmentWidth({...t,layerIndex:e,viaCount:0},t)<=0}segmentCollides(t,e){return this.getSafeSegmentWidth(t,e)<=0}getSafeSegmentWidth(t,e){const n=this.problem.layers[t.layerIndex],o=1===this.problem.startLayers.length&&0===t.viaCount&&n===this.problem.originalStartLayer&&Nq(this.problem.start,t)<=this.problem.maxStartNeckLength+1e-9&&Nq(this.problem.start,e)<=this.problem.maxStartNeckLength+1e-9,i=1===this.problem.endLayers.length&&n===this.problem.originalEndLayer&&Nq(this.problem.end,t)<=this.problem.maxEndNeckLength+1e-9&&Nq(this.problem.end,e)<=this.problem.maxEndNeckLength+1e-9,r=Math.max(o?this.problem.startNeckWidth:0,i?this.problem.endNeckWidth:0),s=[t.x,t.y,e.x,e.y,t.layerIndex,t.viaCount,r].join(":"),a=this.segmentWidthCache.get(s);if(void 0!==a)return a;const c=o=>!this.problem.obstacleIndex.collides({start:t,end:e,layer:n,width:o,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreTraceIndices:this.problem.softTraceIndices,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance});let l=0;if(o||i){const t=.025;let e=Math.ceil((r-1e-9)/t),n=Math.floor((this.problem.traceWidth+1e-9)/t);for(;e<=n;){const o=Math.floor((e+n)/2),i=Number((o*t).toFixed(6));c(i)?(l=i,e=o+1):n=o-1}l<r-1e-9&&c(r)&&(l=r)}else l=c(this.problem.traceWidth)?this.problem.traceWidth:0;return this.segmentWidthCache.set(s,l),l}reconstructRoute(t){const e=[];let n=t;for(;n>=0;){const t=this.nodes[n];e.push(t),n=t.parentIndex}e.reverse();const o=e[e.length-1];Tq(o,this.problem.end)||e.push({...o,...this.problem.end,row:this.targetCell.row,column:this.targetCell.column,parentIndex:-1});const i=[];let r=[e[0]];for(let t=1;t<e.length;t++){const n=e[t-1],o=e[t];o.layerIndex!==n.layerIndex?(i.push(r),r=[o]):r.push(o)}i.push(r);const s=[];for(let t=0;t<i.length;t++){const e=this.simplifySection(i[t]),n=e.slice(0,-1).map((t,n)=>this.getSafeSegmentWidth(t,e[n+1])),o=e.map((t,o)=>({route_type:"wire",x:t.x,y:t.y,layer:this.problem.layers[t.layerIndex],width:0===n.length?Math.min(this.problem.startNeckWidth,this.problem.endNeckWidth):0===o?n[0]:o===e.length-1?n[n.length-1]:Math.min(n[o-1],n[o])}));s.push(...o);const r=i[t+1];if(r){const t=this.problem.layers[e.at(-1).layerIndex],n=this.problem.layers[r[0].layerIndex],o=e.at(-1);s.push({route_type:"via",x:o.x,y:o.y,from_layer:t,to_layer:n,via_diameter:this.problem.viaDiameter,via_hole_diameter:this.problem.viaHoleDiameter})}}return{route:s,traceWidth:this.problem.traceWidth,startNeckWidth:this.problem.startNeckWidth,endNeckWidth:this.problem.endNeckWidth,gridSize:this.problem.gridSize,gridOffset:this.problem.gridOffset,viaCount:i.length-1}}simplifySection(t){return t.length<=2?t:this.problem.neckPenaltyExponent>1?this.simplifyStrictSection(t):this.simplifyWidthPreservingSection(t)}simplifyStrictSection(t){const e=t.slice(0,-1).map((e,n)=>this.getSafeSegmentWidth(e,t[n+1])),n=[0];for(let o=0;o<e.length;o++)n.push(n[o]+this.getWidthPenalizedCost(t[o],t[o+1],e[o]));const o=[t[0]];let i=0;for(;i<t.length-1;){let r=t.length-1;for(;r>i+1&&!this.shortcutPreservesRouteQuality(t,e,n,i,r);)r--;o.push(t[r]),i=r}return this.removeRedundantCollinearPoints(o)}shortcutPreservesRouteQuality(t,e,n,o,i){const r=this.getSafeSegmentWidth(t[o],t[i]);if(r<=0)return!1;let s=Number.POSITIVE_INFINITY;for(let t=o;t<i;t++)s=Math.min(s,e[t]);const a=n[i]-n[o];return r>=s-1e-9&&this.getWidthPenalizedCost(t[o],t[i],r)<=a+1e-9}getWidthPenalizedCost(t,e,n){return Nq(t,e)*Math.max(1,(this.problem.traceWidth/n)**this.problem.neckPenaltyExponent)}simplifyWidthPreservingSection(t){const e=t.slice(0,-1).map((e,n)=>this.getSafeSegmentWidth(e,t[n+1])),n=[0];for(let o=0;o<e.length;o++)n.push(n[o]+Nq(t[o],t[o+1])*Math.max(1,(this.problem.traceWidth/e[o])**this.problem.neckPenaltyExponent));const o=new Float64Array(t.length).fill(Number.POSITIVE_INFINITY),i=new Float64Array(t.length).fill(Number.POSITIVE_INFINITY),r=new Int32Array(t.length).fill(-1);o[0]=0,i[0]=0;for(let s=1;s<t.length;s++){let a=Number.POSITIVE_INFINITY;for(let c=s-1;c>=0;c--){if(a=Math.min(a,e[c]),!Number.isFinite(o[c]))continue;const l=this.getSafeSegmentWidth(t[c],t[s]);if(l<a-1e-9)continue;const d=Nq(t[c],t[s]);if(d*Math.max(1,(this.problem.traceWidth/l)**this.problem.neckPenaltyExponent)>n[s]-n[c]+1e-9)continue;const h=o[c]+d*Math.max(0,this.problem.traceWidth-l),u=i[c]+d;(h<o[s]-1e-9||Math.abs(h-o[s])<=1e-9&&u<i[s]-1e-9)&&(o[s]=h,i[s]=u,r[s]=c)}}const s=[];let a=t.length-1;for(;a>=0&&(s.push(t[a]),0!==a);)if(a=r[a],a<0)return t;return s.reverse(),this.removeRedundantCollinearPoints(s)}removeRedundantCollinearPoints(t){return t.filter((t,e,n)=>{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x),s=Math.abs(this.getSafeSegmentWidth(o,t)-this.getSafeSegmentWidth(t,i))<1e-9;return Math.abs(r)>1e-8||!s})}pointToCell(t){return{column:Rq(Math.round((t.x-this.origin.x)/this.problem.gridSize),0,this.columns-1),row:Rq(Math.round((t.y-this.origin.y)/this.problem.gridSize),0,this.rows-1)}}cellToPoint(t,e){return{x:this.origin.x+e*this.problem.gridSize,y:this.origin.y+t*this.problem.gridSize}}toStateIndex(t){const e=((t.viaCount*this.problem.layers.length+t.layerIndex)*this.rows+t.row)*this.columns+t.column;if(1!==t.viaCount||0===t.viaPoints.length||Nq(t,t.viaPoints[0])>=this.problem.viaHoleDiameter+this.problem.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance-1e-9)return e;const n=this.pointToCell(t.viaPoints[0]);return e+(1+n.row*this.columns+n.column)*this.baseStateCount}heuristic(t){return Nq(t,this.problem.end)}createStats(){return{phase:"layer-aware-grid-search",gridSize:this.problem.gridSize,traceWidth:this.problem.traceWidth,startNeckWidth:this.problem.startNeckWidth,endNeckWidth:this.problem.endNeckWidth,maxViaCount:this.problem.maxViaCount,minViaCount:this.problem.minViaCount,openStates:this.open.size,closedStates:this.closedStateCount,trackedStates:this.bestCost.size,stateSpaceUpperBound:this.stateSpaceUpperBound}}computeProgress(){return Math.min(.99,this.iterations/this.MAX_ITERATIONS)}getOutput(){return this.output}getConstructorParams(){const{obstacleIndex:t,...e}=this.problem;return[e]}visualize(){const t=this.nodes.filter(t=>this.closed.has(this.toStateIndex(t))).slice(-2e3).map(t=>({x:t.x,y:t.y,color:`${$q[t.layerIndex%$q.length]}55`})),e=[],n=[],o=this.output?.route??[];for(let t=0;t<o.length-1;t++){const i=o[t],r=o[t+1];if("wire"===i?.route_type&&"wire"===r?.route_type&&i.layer===r.layer){const t=this.problem.layers.indexOf(i.layer);e.push({points:[i,r],strokeColor:$q[t%$q.length]??"#333",strokeWidth:i.width})}"via"===i?.route_type&&n.push({center:i,radius:(i.via_diameter??this.problem.viaDiameter)/2,fill:"#d4a017"})}return{coordinateSystem:"cartesian",title:this.getSolverName(),rects:[{center:{x:(this.searchBounds.minX+this.searchBounds.maxX)/2,y:(this.searchBounds.minY+this.searchBounds.maxY)/2},width:this.searchBounds.maxX-this.searchBounds.minX,height:this.searchBounds.maxY-this.searchBounds.minY,stroke:"#777"}],points:[...t,{...this.problem.start,color:"green",label:"reroute start"},{...this.problem.end,color:"purple",label:"reroute target"}],lines:e,circles:n,texts:[]}}},Xq=[{direction:1,strength:.7},{direction:-1,strength:.7},{direction:1,strength:1},{direction:-1,strength:1}],Vq=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i;if(r<=1e-12)return{...e};const s=Rq(((t.x-e.x)*o+(t.y-e.y)*i)/r,0,1);return{x:e.x+o*s,y:e.y+i*s}},Wq=class extends Sq{problem;phase="prepare-candidate";variantCursor=0;relaxationIteration=0;candidatePoints=[];sampledPoints;output=null;constructor(t){super(),this.problem=t,this.sampledPoints=this.sampleRoute(),this.MAX_ITERATIONS=100,this.stats=this.createStats()}getSolverName(){return"ElasticTracePushSolver"}_step(){switch(this.phase){case"prepare-candidate":if(this.variantCursor>=Xq.length)return this.failed=!0,void(this.error="No collision-free elastic displacement found");this.candidatePoints=this.sampledPoints.map(t=>({...t})),this.relaxationIteration=0,this.phase="relax-candidate";break;case"relax-candidate":this.relaxCandidate(),this.relaxationIteration++,this.relaxationIteration>=10&&(this.phase="validate-candidate");break;case"validate-candidate":{const t=this.simplifyCandidate(this.candidatePoints);this.pathCollides(t)?(this.variantCursor++,this.phase="prepare-candidate"):(this.output={points:t,traceWidth:this.problem.traceWidth},this.phase="complete");break}case"complete":this.solved=!0}this.stats=this.createStats()}sampleRoute(){const t=[],e=Rq(2*this.problem.traceWidth,.2,.45),n=this.problem.trace.route;for(let o=this.problem.range.startIndex;o<this.problem.range.endIndex;o++){const i=n[o],r=n[o+1];if("wire"!==i?.route_type||"wire"!==r?.route_type||i.layer!==r.layer)continue;0===t.length&&t.push({x:i.x,y:i.y});const s=Nq(i,r),a=Math.max(1,Math.ceil(s/e));for(let e=1;e<=a;e++){const n=e/a;t.push({x:i.x+(r.x-i.x)*n,y:i.y+(r.y-i.y)*n})}}return t}relaxCandidate(){const t=Xq[this.variantCursor],e=this.candidatePoints.map(t=>({...t})),n=new Uint8Array(this.candidatePoints.length);for(let o=1;o<this.candidatePoints.length-1;o++){const i=this.candidatePoints[o],r=this.findNearestCorridorSegment(i);if(!r)continue;const s=Nq(r.segment.start,r.segment.end);if(s<=1e-9)continue;const a=r.segment.width/2+this.problem.traceWidth/2+this.problem.obstacleIndex.clearance+.025;if(r.distance>a+.35)continue;const c={x:(r.segment.start.y-r.segment.end.y)/s*t.direction,y:(r.segment.end.x-r.segment.start.x)/s*t.direction},l=a-((i.x-r.closest.x)*c.x+(i.y-r.closest.y)*c.y);if(l<=0)continue;const d=Math.min(.35,l*t.strength);e[o]={x:i.x+c.x*d,y:i.y+c.y*d},n[o]=1}for(let t=1;t<e.length-1;t++){if(!n[t])continue;const o=e[t-1],i=e[t],r=e[t+1];e[t]={x:.85*i.x+(o.x+r.x)/2*.15,y:.85*i.y+(o.y+r.y)/2*.15}}this.candidatePoints=e}findNearestCorridorSegment(t){let e;for(const n of this.problem.corridor){if(n.layer!==this.problem.layer)continue;const o=Vq(t,n.start,n.end),i=Nq(t,o);(!e||i<e.distance)&&(e={segment:n,closest:o,distance:i})}return e}simplifyCandidate(t){if(t.length<=2)return t;const e=[t[0]];let n=0;for(;n<t.length-1;){let o=t.length-1;for(;o>n+1&&this.segmentCollides(t[n],t[o]);)o--;e.push(t[o]),n=o}return e.filter((t,e,n)=>0===e||!Tq(t,n[e-1]))}pathCollides(t){if(t.length<2)return!0;for(let e=0;e<t.length-1;e++)if(this.segmentCollides(t[e],t[e+1]))return!0;return!1}segmentCollides(t,e){return this.problem.obstacleIndex.collides({start:t,end:e,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:-1})}createStats(){const t=Xq[this.variantCursor];return{phase:this.phase,direction:t?.direction,strength:t?.strength,variantCursor:this.variantCursor,relaxationIteration:this.relaxationIteration,sampledPointCount:this.sampledPoints.length}}computeProgress(){return Math.min(.99,(this.variantCursor+this.relaxationIteration/12)/Xq.length)}getOutput(){return this.output}getConstructorParams(){return[this.problem]}visualize(){return{coordinateSystem:"cartesian",title:`Elastic trace push: ${this.phase}`,lines:[...this.problem.corridor.map(t=>({points:[t.start,t.end],strokeColor:"rgba(255, 128, 0, 0.6)",strokeWidth:t.width})),...this.candidatePoints.length>1?[{points:this.candidatePoints,strokeColor:"#1769d2",strokeWidth:this.problem.traceWidth}]:[]],points:[],rects:[],circles:[],texts:[]}}},Hq=(t,e)=>{const n=Math.abs(e.x-t.x),o=Math.abs(e.y-t.y);return n<=Mq||o<=Mq||Math.abs(n-o)<=Mq},Gq=t=>{let e=0;for(let n=0;n<t.length-1;n++)Hq(t[n],t[n+1])||e++;return e},Uq=t=>{let e=0;for(let n=0;n<t.length-1;n++)e+=Nq(t[n],t[n+1]);return e},Zq=t=>t.filter((e,n)=>0===n||!Tq(e,t[n-1])),qq=(t,e)=>{const n=e.x-t.x,o=e.y-t.y,i=Math.abs(n),r=Math.abs(o),s=Math.sign(n),a=Math.sign(o),c=[];Hq(t,e)&&c.push([t,e]),c.push([t,{x:e.x,y:t.y},e],[t,{x:t.x,y:e.y},e]),i>=r?c.push([t,{x:e.x-s*r,y:t.y},e],[t,{x:t.x+s*r,y:e.y},e]):c.push([t,{x:t.x,y:e.y-a*i},e],[t,{x:e.x,y:t.y+a*i},e]);const l=new Map;for(const t of c){const e=Zq(t);if(e.length<2||e.some((t,n)=>n<e.length-1&&!Hq(t,e[n+1])))continue;const n=e.map(t=>`${t.x.toFixed(6)},${t.y.toFixed(6)}`).join(";");l.set(n,e)}return[...l.values()].sort((t,e)=>Uq(t)-Uq(e)||t.length-e.length)},Jq=class{nodeIndices=[];priorities=[];get size(){return this.nodeIndices.length}push(t,e){let n=this.nodeIndices.length;for(this.nodeIndices.push(t),this.priorities.push(e);n>0;){const t=n-1>>1;if(this.priorities[t]<=e)break;this.swap(n,t),n=t}}pop(){const t=this.nodeIndices[0],e=this.nodeIndices.pop(),n=this.priorities.pop();if(0===this.nodeIndices.length)return t;this.nodeIndices[0]=e,this.priorities[0]=n;let o=0;for(;;){const t=2*o+1,e=t+1;if(t>=this.nodeIndices.length)break;let n=t;if(e<this.nodeIndices.length&&this.priorities[e]<this.priorities[t]&&(n=e),this.priorities[o]<=this.priorities[n])break;this.swap(o,n),o=n}return t}swap(t,e){[this.nodeIndices[t],this.nodeIndices[e]]=[this.nodeIndices[e],this.nodeIndices[t]],[this.priorities[t],this.priorities[e]]=[this.priorities[e],this.priorities[t]]}},Kq=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]],Qq=class extends Sq{problem;searchBounds;rows;columns;origin;nodes=[];open=new Jq;bestCost;closed;closedCellCount=0;targetCell;output=null;constructor(t){super(),this.problem=t;const e=t.traceWidth/2+t.obstacleIndex.clearance,n=Rq(Math.min(t.start.x,t.end.x)-t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),o=Rq(Math.max(t.start.x,t.end.x)+t.searchPadding,t.bounds.minX+e,t.bounds.maxX-e),i=Rq(Math.min(t.start.y,t.end.y)-t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),r=Rq(Math.max(t.start.y,t.end.y)+t.searchPadding,t.bounds.minY+e,t.bounds.maxY-e),s=Math.floor((n-t.gridOffset.x)/t.gridSize)*t.gridSize+t.gridOffset.x,a=Math.floor((i-t.gridOffset.y)/t.gridSize)*t.gridSize+t.gridOffset.y;if(this.origin={x:s,y:a},this.columns=Math.max(2,Math.floor((o-s)/t.gridSize)+1),this.rows=Math.max(2,Math.floor((r-a)/t.gridSize)+1),this.searchBounds={minX:s,minY:a,maxX:s+(this.columns-1)*t.gridSize,maxY:a+(this.rows-1)*t.gridSize},this.bestCost=new Float64Array(this.rows*this.columns).fill(Number.POSITIVE_INFINITY),this.closed=new Uint8Array(this.rows*this.columns),this.endpointCollides(t.start)||this.endpointCollides(t.end))return this.failed=!0,this.error="Grid-route endpoint violates obstacle clearance",this.targetCell={row:0,column:0},this.MAX_ITERATIONS=1,void(this.stats=this.createStats());const c=this.pointToCell(t.start);this.targetCell=this.pointToCell(t.end);const l={...c,x:t.start.x,y:t.start.y,g:0,f:this.heuristic(t.start),parentIndex:-1};this.nodes.push(l),this.open.push(0,l.f),this.bestCost[this.toFlatIndex(c.row,c.column)]=0,this.MAX_ITERATIONS=Math.min(5e3,Math.max(1e3,this.rows*this.columns*2)),this.stats=this.createStats()}endpointCollides(t){return this.problem.obstacleIndex.collides({start:t,end:t,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance})}getSolverName(){return`ObstacleAwareGridRouteSolver(${this.problem.gridSize.toFixed(3)}mm)`}_step(){if(0===this.open.size)return this.failed=!0,void(this.error="No collision-free grid route found");const t=this.open.pop(),e=this.nodes[t],n=this.toFlatIndex(e.row,e.column);if(!this.closed[n]){if(this.closed[n]=1,this.closedCellCount++,e.row===this.targetCell.row&&e.column===this.targetCell.column&&null!==this.getAllowedConnector(e,this.problem.end))return this.output={points:this.reconstructPath(t),traceWidth:this.problem.traceWidth,gridSize:this.problem.gridSize,gridOffset:this.problem.gridOffset},this.solved=!0,void(this.stats=this.createStats());for(const[n,o]of Kq){const i=e.row+n,r=e.column+o;if(i<0||i>=this.rows||r<0||r>=this.columns)continue;const s=this.toFlatIndex(i,r);if(this.closed[s])continue;const a=this.cellToPoint(i,r),c=this.getAllowedConnector(e,a);if(null===c)continue;const l=-1===e.parentIndex&&this.problem.requireOctilinear?Uq(c):this.problem.gridSize*(0!==n&&0!==o?Math.SQRT2:1),d=e.g+l;if(d>=this.bestCost[s])continue;this.bestCost[s]=d;const h=d+this.heuristic(a),u=this.nodes.length;this.nodes.push({row:i,column:r,...a,g:d,f:h,parentIndex:t}),this.open.push(u,h)}this.stats=this.createStats()}}segmentCollides(t,e){return this.problem.obstacleIndex.collides({start:t,end:e,layer:this.problem.layer,width:this.problem.traceWidth,connectionNames:this.problem.connectionNames,ignoreTraceIndex:this.problem.ignoreTraceIndex,ignoreRouteRange:this.problem.ignoreRouteRange,obstacleClearance:this.problem.obstacleClearance})}getAllowedConnector(t,e){return this.problem.requireOctilinear&&("parentIndex"in t&&-1===t.parentIndex||Tq(e,this.problem.end))?qq(t,e).find(t=>t.slice(0,-1).every((e,n)=>!this.segmentCollides(e,t[n+1])))??null:this.segmentCollides(t,e)?null:[t,e]}pointToCell(t){return{column:Rq(Math.round((t.x-this.origin.x)/this.problem.gridSize),0,this.columns-1),row:Rq(Math.round((t.y-this.origin.y)/this.problem.gridSize),0,this.rows-1)}}cellToPoint(t,e){return{x:this.origin.x+e*this.problem.gridSize,y:this.origin.y+t*this.problem.gridSize}}toFlatIndex(t,e){return t*this.columns+e}heuristic(t){return Math.hypot(this.problem.end.x-t.x,this.problem.end.y-t.y)}reconstructPath(t){const e=[];let n=t;for(;n>=0;){const t=this.nodes[n];e.push({x:t.x,y:t.y}),n=t.parentIndex}if(e.reverse(),Tq(e[0],this.problem.start)||e.unshift({...this.problem.start}),Tq(e[e.length-1],this.problem.end)||e.push({...this.problem.end}),this.problem.requireOctilinear){const t=[e[0]];for(let n=0;n<e.length-1;n++){const o=e[n],i=e[n+1],r=0===n||n===e.length-2?this.getAllowedConnector(0===n?{...o,parentIndex:-1}:o,i):[o,i];if(!r)return e;t.push(...r.slice(1))}return t.filter((t,e,n)=>{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x);return Math.abs(r)>1e-8||!Hq(o,i)})}const o=[e[0]];let i=0;for(;i<e.length-1;){let t=e.length-1;for(;t>i+1&&this.segmentCollides(e[i],e[t]);)t--;o.push(e[t]),i=t}return o.filter((t,e,n)=>{if(0===e||e===n.length-1)return!0;const o=n[e-1],i=n[e+1],r=(t.x-o.x)*(i.y-t.y)-(t.y-o.y)*(i.x-t.x);return Math.abs(r)>1e-8})}createStats(){return{phase:"obstacle-aware-grid-search",gridSize:this.problem.gridSize,traceWidth:this.problem.traceWidth,gridOffset:this.problem.gridOffset,openCells:this.open.size,closedCells:this.closedCellCount,gridCells:this.rows*this.columns}}computeProgress(){return Math.min(.99,this.iterations/this.MAX_ITERATIONS)}getOutput(){return this.output}getConstructorParams(){const{obstacleIndex:t,...e}=this.problem;return[e]}visualize(){const t=this.nodes.filter(t=>this.closed[this.toFlatIndex(t.row,t.column)]).slice(-2e3).map(t=>({x:t.x,y:t.y,color:"rgba(0,90,255,0.22)"})),e=this.output?.points??[];return{coordinateSystem:"cartesian",title:this.getSolverName(),rects:[{center:{x:(this.searchBounds.minX+this.searchBounds.maxX)/2,y:(this.searchBounds.minY+this.searchBounds.maxY)/2},width:this.searchBounds.maxX-this.searchBounds.minX,height:this.searchBounds.maxY-this.searchBounds.minY,stroke:"#777"}],points:[...t,{...this.problem.start,color:"green",label:"reroute start"},{...this.problem.end,color:"purple",label:"reroute target"}],lines:e.length>1?[{points:e,strokeColor:"#00a050",strokeWidth:this.problem.traceWidth}]:[],circles:[],texts:[]}}},tJ=class{items;clearance;boardEdgeClearance;boardLayers;minViaHoleEdgeToViaHoleEdgeClearance;defaultViaHoleDiameter;bounds;maxIndexedViaHoleDiameter;index;connectionNameSets;copperObjectIds;connectionNameResolver;connectedPads;dynamicTraceIndex;constructor(t,e,n,o=[],i=new Pq(t,e)){var r;this.bounds=t.bounds,this.boardLayers=(r=t.layerCount,["top",...Array.from({length:Math.max(0,r-2)},(t,e)=>`inner${e+1}`),...r>1?["bottom"]:[]]),this.dynamicTraceIndex=n,this.clearance=Math.max(t.defaultObstacleMargin??0,t.minTraceToPadEdgeClearance??0,.1),this.boardEdgeClearance=t.minBoardEdgeClearance??this.clearance,this.minViaHoleEdgeToViaHoleEdgeClearance=Math.max(t.minViaHoleEdgeToViaHoleEdgeClearance??0,.1),this.defaultViaHoleDiameter=t.min_via_hole_diameter??t.minViaHoleDiameter??.3,this.items=[...t.obstacles.flatMap((t,e)=>function(t,e=.6){const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.max(1,Math.ceil(t.width/e)),i=Math.max(1,Math.ceil(t.height/e)),r=t.width/o,s=t.height/i,a=[];for(let e=0;e<i;e++)for(let i=0;i<o;i++){const o={x:t.center.x-t.width/2+(i+.5)*r,y:t.center.y-t.height/2+(e+.5)*s},c=r/2,l=s/2,d=[{x:o.x-c,y:o.y-l},{x:o.x+c,y:o.y-l},{x:o.x+c,y:o.y+l},{x:o.x-c,y:o.y+l}].map(e=>Fq(e,t.center,n));a.push({minX:Math.min(...d.map(t=>t.x)),minY:Math.min(...d.map(t=>t.y)),maxX:Math.max(...d.map(t=>t.x)),maxY:Math.max(...d.map(t=>t.y)),layers:t.layers,kind:"obstacle",obstacleKind:t.connectedTo[0]?.startsWith("pcb_via_")?"via":t.connectedTo[0]?.startsWith("pcb_smtpad_")||t.connectedTo[0]?.startsWith("pcb_plated_hole_")?"pad":"other",connectionNames:t.connectedTo,exactShape:{type:"polygon",points:d}})}return a}(t).map(t=>({...t,copperObjectId:`obstacle:${e}`}))),...this.createTraceItems(t.fixedTraces??[],!0),...this.createTraceItems(e),...o],this.maxIndexedViaHoleDiameter=this.items.reduce((t,e)=>"via"===e.kind?Math.max(t,e.viaHoleDiameter??this.defaultViaHoleDiameter):t,this.defaultViaHoleDiameter),this.connectionNameResolver=i,this.connectionNameSets=this.items.map(t=>new Set(i.canonicalize(t.connectionNames))),this.copperObjectIds=this.items.map((t,e)=>t.copperObjectId??`indexed-item:${e}`),this.connectedPads=t.obstacles.flatMap(t=>t.connectedTo.some(t=>t.startsWith("pcb_smtpad_")||t.startsWith("pcb_plated_hole_"))?[{obstacle:t,canonicalConnectionNames:new Set(i.canonicalize(t.connectedTo))}]:[]),this.index=this.items.length>0?new Bt(this.items.length):null;for(const t of this.items)this.index.add(t.minX,t.minY,t.maxX,t.maxY);this.index?.finish()}createTraceItems(t,e=!1){const n=[];for(let o=0;o<t.length;o++){const i=t[o],r=e?void 0:o,s=`${e?"fixed-trace":"trace"}:${o}`,a=!e&&o===this.dynamicTraceIndex,c=[i.connection_name,i.source_trace_id,i.rootConnectionName,...i.mergedConnectionNames??[],...i.connectsTo??[]].filter(t=>Boolean(t));for(let t=0;t<i.route.length;t++){const e=i.route[t];if("via"===e.route_type){const o=e.via_diameter??.6;n.push({minX:e.x-o/2,minY:e.y-o/2,maxX:e.x+o/2,maxY:e.y+o/2,layers:this.boardLayers,kind:"via",connectionNames:c,copperObjectId:s,traceIndex:r,routeStartIndex:t,routeEndIndex:t,viaHoleDiameter:e.via_hole_diameter??this.defaultViaHoleDiameter,exactShape:{type:"circle",center:{x:e.x,y:e.y},radius:o/2}});continue}if(a)continue;const o=i.route[t+1];"wire"===e.route_type&&"wire"===o?.route_type&&e.layer===o.layer&&n.push(...zq({start:e,end:o,width:e.width,base:{layers:[e.layer],kind:"trace",connectionNames:c,copperObjectId:s,traceIndex:r,routeStartIndex:t,routeEndIndex:t+1}}))}}return n}collides(t){if(this.isOutsideBounds(t))return!0;const{radius:e,candidates:n,canonicalConnectionNames:o}=this.getCollisionCandidates(t);for(const i of n)if(this.itemCollides(i,t,e,o))return!0;return!1}findCollisions(t){const{radius:e,candidates:n,canonicalConnectionNames:o}=this.getCollisionCandidates(t),i=[];for(const r of n)this.itemCollides(r,t,e,o)&&i.push(this.items[r]);return i}getSameNetCopperContactIds(t){const e=t.width/2,n=this.index?.search(Math.min(t.start.x,t.end.x)-e,Math.min(t.start.y,t.end.y)-e,Math.max(t.start.x,t.end.x)+e,Math.max(t.start.y,t.end.y)+e)??[],o=new Set(this.connectionNameResolver.canonicalize(t.connectionNames)),i=new Set;for(const r of n){const n=this.items[r];n.layers.includes(t.layer)&&(n.traceIndex===t.ignoreTraceIndex||t.ignoreTraceIndices?.includes(n.traceIndex??-1)||[...this.connectionNameSets[r]].some(t=>o.has(t))&&this.itemCopperTouches(n,t,e)&&i.add(this.copperObjectIds[r]))}return i}getConnectedPadWidthLimit(t){if(Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y)<=1e-5)return null;const e=this.getConnectedPadWidthLimitAtPoint(t,t.start),n=this.getConnectedPadWidthLimitAtPoint(t,t.end);return null===e?n:null===n?e:Math.min(e,n)}getConnectedPadWidthLimitAtPoint(t,e){const n=this.getConnectedPadsAtPoint(t,e);return 0===n.length?null:Math.max(...n.map(({obstacle:e})=>this.getPadWidthNormalToQuery(e,t)))}getConnectedPadEndpointWidthLimitAtPoint(t,e){const n=this.getConnectedPadsAtPoint(t,e);return 0===n.length?null:Math.max(...n.map(({obstacle:t})=>{const n=this.getObstacleLocalPoint(e,t);return Math.max(0,2*Math.min(t.width/2-Math.abs(n.x),t.height/2-Math.abs(n.y)))}))}getConnectedPadBoundaryPoint(t,e){const n="start"===e?t.start:t.end,o="start"===e?t.end:t.start,i=this.getConnectedPadsAtPoint(t,n).sort((e,n)=>this.getPadWidthNormalToQuery(n.obstacle,t)-this.getPadWidthNormalToQuery(e.obstacle,t))[0];return!i||this.pointIsInsideObstacle(o,i.obstacle)?null:this.getObstacleBoundaryPoint(n,o,i.obstacle)}getConnectedPadsAtPoint(t,e){const n=new Set(this.connectionNameResolver.canonicalize(t.connectionNames));return this.connectedPads.filter(({obstacle:o,canonicalConnectionNames:i})=>o.layers.includes(t.layer)&&[...i].some(t=>n.has(t))&&this.pointIsInsideObstacle(e,o))}pointIsInsideObstacle(t,e){const{x:n,y:o}=this.getObstacleLocalPoint(t,e);return Math.abs(n)<=e.width/2+1e-9&&Math.abs(o)<=e.height/2+1e-9}getObstacleLocalPoint(t,e){const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=Math.cos(n),i=Math.sin(n),r=t.x-e.center.x,s=t.y-e.center.y;return{x:r*o-s*i,y:r*i+s*o}}getPadWidthNormalToQuery(t,e){const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.hypot(n,o);if(i<=1e-9)return Math.min(t.width,t.height);const r=-o/i,s=n/i,a=-(t.ccwRotationDegrees??0)*Math.PI/180,c=Math.cos(a),l=Math.sin(a),d=r*c-s*l,h=r*l+s*c;return Math.abs(d)*t.width+Math.abs(h)*t.height}getObstacleBoundaryPoint(t,e,n){const o=-(n.ccwRotationDegrees??0)*Math.PI/180,i=Math.cos(o),r=Math.sin(o),s=t=>{const e=t.x-n.center.x,o=t.y-n.center.y;return{x:e*i-o*r,y:e*r+o*i}},a=s(t),c=s(e),l={x:c.x-a.x,y:c.y-a.y},d=[];if(Math.abs(l.x)>1e-12){const t=l.x>0?n.width/2:-n.width/2;d.push((t-a.x)/l.x)}if(Math.abs(l.y)>1e-12){const t=l.y>0?n.height/2:-n.height/2;d.push((t-a.y)/l.y)}const h=Math.min(...d.filter(t=>t>=0&&t<=1));return Number.isFinite(h)?{x:t.x+(e.x-t.x)*h,y:t.y+(e.y-t.y)*h}:null}getConnectedLayersAtPoint(t,e){const n=new Set(this.connectionNameResolver.canonicalize(e)),o=new Set,i=this.index?.search(t.x,t.y,t.x,t.y)??[];for(const e of i){const i=this.items[e];if("obstacle"!==i.kind)continue;if(![...this.connectionNameSets[e]].some(t=>n.has(t)))continue;if("polygon"===i.exactShape?.type?Lq(t,t,i.exactShape.points)<=1e-9:"circle"===i.exactShape?.type?Math.hypot(i.exactShape.center.x-t.x,i.exactShape.center.y-t.y)<=i.exactShape.radius+1e-9:t.x>=i.minX-1e-9&&t.x<=i.maxX+1e-9&&t.y>=i.minY-1e-9&&t.y<=i.maxY+1e-9)for(const t of i.layers)o.add(t)}return[...o]}collidesVia(t){return this.getViaViolationSignatures(t).size>0}getViaViolationSignatures(t){const e=new Set;for(const n of t.layers){const o={start:t.point,end:t.point,layer:n,width:t.padDiameter,connectionNames:t.connectionNames,ignoreTraceIndex:t.ignoreTraceIndex,ignoreTraceIndices:t.ignoreTraceIndices,ignoreRouteRange:t.ignoreRouteRange,obstacleClearance:t.obstacleClearance,blockSameNetObstacles:t.blockSameNetObstacles,sameNetObstacleClearance:t.sameNetObstacleClearance};this.isOutsideBounds(o)&&e.add(`board-edge:${n}`);const{radius:i,candidates:r,canonicalConnectionNames:s}=this.getCollisionCandidates(o);for(const t of r)this.itemCollides(t,o,i,s)&&e.add(`copper:${n}:${this.getViolationObjectId(t)}`)}const n=t.holeDiameter+this.minViaHoleEdgeToViaHoleEdgeClearance;for(const o of t.otherNewViaPoints??[])Math.hypot(o.x-t.point.x,o.y-t.point.y)<n-1e-9&&e.add(`new-via-drill:${o.x},${o.y}:${t.holeDiameter}`);const o=t.fixedVias??[];for(let n=0;n<o.length;n++){const i=o[n],r=t.holeDiameter/2+i.holeDiameter/2+this.minViaHoleEdgeToViaHoleEdgeClearance;Math.hypot(i.point.x-t.point.x,i.point.y-t.point.y)<r-1e-9&&e.add(`fixed-via-drill:${n}:${i.point.x},${i.point.y}:${i.holeDiameter}`)}const i=t.holeDiameter/2+this.maxIndexedViaHoleDiameter/2+this.minViaHoleEdgeToViaHoleEdgeClearance,r=this.index?.search(t.point.x-i,t.point.y-i,t.point.x+i,t.point.y+i)??[],s=new Set;for(const n of r){const o=this.items[n];if("via"!==o.kind||"circle"!==o.exactShape?.type)continue;if(o.traceIndex===t.ignoreTraceIndex&&t.ignoreRouteRange&&(o.routeEndIndex??-1)>=t.ignoreRouteRange.start&&(o.routeStartIndex??Number.POSITIVE_INFINITY)<=t.ignoreRouteRange.end)continue;if(t.ignoreTraceIndices?.includes(o.traceIndex??-1))continue;const i=`${this.copperObjectIds[n]??"unknown"}:${o.routeStartIndex??-1}`;if(s.has(i))continue;s.add(i);const r=o.viaHoleDiameter??this.defaultViaHoleDiameter,a=t.holeDiameter/2+r/2+this.minViaHoleEdgeToViaHoleEdgeClearance;Math.hypot(o.exactShape.center.x-t.point.x,o.exactShape.center.y-t.point.y)<a-1e-9&&e.add(`indexed-via-drill:${this.getViolationObjectId(n)}`)}return e}getViolationObjectId(t){const e=this.items[t],n=this.copperObjectIds[t],o=`${e.routeStartIndex??""}-${e.routeEndIndex??""}`;if("obstacle"===e.kind)return n;if("segment"===e.exactShape?.type){const{start:t,end:i,width:r}=e.exactShape;return`${n}:${e.kind}:${o}:${t.x},${t.y}:${i.x},${i.y}:${r}`}if("circle"===e.exactShape?.type){const{center:t,radius:i}=e.exactShape;return`${n}:${e.kind}:${o}:${t.x},${t.y}:${i}`}return"polygon"===e.exactShape?.type?`${n}:${e.kind}:${o}:${e.exactShape.points.map(t=>`${t.x},${t.y}`).join(";")}`:`${n}:${e.kind}:${o}:${e.minX},${e.minY},${e.maxX},${e.maxY}`}getCollisionCandidates(t){const e=Math.max(this.clearance,t.obstacleClearance??this.clearance,t.sameNetObstacleClearance??0),n=t.width/2+e,o={minX:Math.min(t.start.x,t.end.x)-n,minY:Math.min(t.start.y,t.end.y)-n,maxX:Math.max(t.start.x,t.end.x)+n,maxY:Math.max(t.start.y,t.end.y)+n};return{radius:n,candidates:this.index?.search(o.minX,o.minY,o.maxX,o.maxY)??[],canonicalConnectionNames:this.connectionNameResolver.canonicalize(t.connectionNames)}}itemCollides(t,e,n,o){const i=this.items[t];if(!i.layers.includes(e.layer))return!1;const r=this.connectionNameSets[t],s=o.some(t=>r.has(t));if(s&&(!e.blockSameNetObstacles||"obstacle"!==i.kind||"via"===i.obstacleKind))return!1;if("trace"===i.kind&&e.ignoreTraceIndices?.includes(i.traceIndex??-1))return!1;if("trace"===i.kind&&i.traceIndex===e.ignoreTraceIndex&&e.ignoreRouteRange&&(i.routeEndIndex??-1)>=e.ignoreRouteRange.start&&(i.routeStartIndex??Number.POSITIVE_INFINITY)<=e.ignoreRouteRange.end)return!1;const a="obstacle"===i.kind&&"pad"===i.obstacleKind?s&&e.blockSameNetObstacles?e.sameNetObstacleClearance??e.obstacleClearance??this.clearance:e.obstacleClearance??this.clearance:this.clearance,c=e.width/2+a;return"segment"===i.exactShape?.type?Oq(e.start,e.end,i.exactShape.start,i.exactShape.end)<=c+i.exactShape.width/2+1e-9:"polygon"===i.exactShape?.type?Lq(e.start,e.end,i.exactShape.points)<=c+1e-9:"circle"===i.exactShape?.type?wq(i.exactShape.center,e.start,e.end)<=c+i.exactShape.radius+1e-9:Dq(e.start,e.end,{minX:i.minX-c,minY:i.minY-c,maxX:i.maxX+c,maxY:i.maxY+c})}itemCopperTouches(t,e,n){return"segment"===t.exactShape?.type?Oq(e.start,e.end,t.exactShape.start,t.exactShape.end)<=n+t.exactShape.width/2+1e-9:"polygon"===t.exactShape?.type?Lq(e.start,e.end,t.exactShape.points)<=n+1e-9:"circle"===t.exactShape?.type?wq(t.exactShape.center,e.start,e.end)<=n+t.exactShape.radius+1e-9:Dq(e.start,e.end,{minX:t.minX-n,minY:t.minY-n,maxX:t.maxX+n,maxY:t.maxY+n})}isOutsideBounds(t){const e=t.width/2+this.boardEdgeClearance;return Math.min(t.start.x,t.end.x)-e<this.bounds.minX||Math.max(t.start.x,t.end.x)+e>this.bounds.maxX||Math.min(t.start.y,t.end.y)-e<this.bounds.minY||Math.max(t.start.y,t.end.y)+e>this.bounds.maxY}},eJ=[{x:0,y:0},{x:.5,y:0},{x:0,y:.5},{x:.5,y:.5}],nJ=t=>"wire"===t?.route_type,oJ=class extends Sq{inputProblem;traces;corridor;phase="scan-corridor";corridorCursor=0;blockerCursor=0;offsetCursor=0;resolutionCursor=0;attemptedGridCount=0;blockerIndex;connectionNameResolver;connectionByTraceId=new Map;mutableTraceIndices;blockersByTrace=new Map;blockers=[];currentBlocker=null;currentRange=null;currentTraceWidth=0;gridResolutions=[];currentObstacleIndex=null;output=null;constructor(t,e=new Pq(t.simpleRouteJson,t.traces)){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.corridor=structuredClone(t.corridor),this.mutableTraceIndices=t.mutableTraceIndices?new Set(t.mutableTraceIndices):null,this.connectionNameResolver=e,this.blockerIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,t.powerTraceIndex,[],this.connectionNameResolver),this.activeSubSolver=null,this.MAX_ITERATIONS=25e3,this.stats=this.createStats()}getSolverName(){return"LocalTraceInflationSolver"}_step(){if(this.activeSubSolver)return this.stepActiveSubSolver(),void(this.stats=this.createStats());switch(this.phase){case"scan-corridor":this.scanNextCorridorSegment();break;case"select-blocker":this.selectNextBlocker();break;case"try-elastic-push":break;case"try-grid-candidate":this.startNextGridCandidate();break;case"complete":this.output?this.solved=!0:(this.failed=!0,this.error="No locally reroutable trace blocks the power corridor")}this.stats=this.createStats()}scanNextCorridorSegment(){const t=this.corridor[this.corridorCursor];if(!t)return this.blockers=[...this.blockersByTrace.values()].sort((t,e)=>t.traceIndex-e.traceIndex),void(this.phase="select-blocker");const e=this.traces[this.inputProblem.powerTraceIndex],n=this.blockerIndex.findCollisions({start:t.start,end:t.end,layer:t.layer,width:t.width,connectionNames:e?this.getTraceConnectionNames(e):[]});for(const t of n)this.recordBlockingTrace(t);this.corridorCursor++}recordBlockingTrace(t){if("trace"!==t.kind||void 0===t.traceIndex||void 0===t.routeStartIndex||void 0===t.routeEndIndex||t.traceIndex===this.inputProblem.powerTraceIndex||null!==this.mutableTraceIndices&&!this.mutableTraceIndices.has(t.traceIndex))return;const e=this.traces[t.traceIndex];if(!e)return;const n=this.findConnectionForTrace(e);if((n?this.resolveNominalTraceWidth(n):this.getTraceNominalWidth(e))>=(this.inputProblem.pushOnlyNominalWidthsBelow??this.inputProblem.nominalPowerWidth)-Mq)return;const o=this.blockersByTrace.get(t.traceIndex);if(o)return o.firstRouteIndex=Math.min(o.firstRouteIndex,t.routeStartIndex),void(o.lastRouteIndex=Math.max(o.lastRouteIndex,t.routeEndIndex));this.blockersByTrace.set(t.traceIndex,{traceIndex:t.traceIndex,firstRouteIndex:t.routeStartIndex,lastRouteIndex:t.routeEndIndex})}selectNextBlocker(){if(this.currentBlocker=this.blockers[this.blockerCursor]??null,!this.currentBlocker)return void(this.phase="complete");const t=this.findStableAnchorRange(this.currentBlocker);if(!t)return void this.blockerCursor++;const e=this.traces[this.currentBlocker.traceIndex];this.currentRange=t,this.currentTraceWidth=this.getRangeWidth(e,t),this.gridResolutions=this.getGridResolutions(this.currentTraceWidth),this.resolutionCursor=0,this.offsetCursor=0,this.currentObstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,this.currentBlocker.traceIndex,this.createInflatedCorridorItems(),this.connectionNameResolver),this.activeSubSolver=new Wq({trace:e,range:t,layer:e.route[t.startIndex].layer,traceWidth:this.currentTraceWidth,corridor:this.corridor,obstacleIndex:this.currentObstacleIndex,connectionNames:this.getTraceConnectionNames(e)}),this.phase="try-elastic-push"}findStableAnchorRange(t){const e=this.traces[t.traceIndex];if(!e)return null;let n=t.firstRouteIndex,o=t.lastRouteIndex;for(;n>0;){const t=e.route[n];if(nJ(t)&&this.pointClearsCorridor(t))break;n--}for(;o<e.route.length-1;){const t=e.route[o];if(nJ(t)&&this.pointClearsCorridor(t))break;o++}const i=e.route[n],r=e.route[o];if(!nJ(i)||!nJ(r)||i.layer!==r.layer||!this.pointClearsCorridor(i)||!this.pointClearsCorridor(r)||n>=o)return null;const s={startIndex:n,endIndex:o},a=this.getRangeLength(e,s);return!Number.isFinite(a)||a>(this.inputProblem.maxRerouteLength??10)+Mq?null:s}pointClearsCorridor(t){return this.corridor.every(e=>{if(e.layer!==t.layer)return!0;const n=e.width/2+t.width/2+this.blockerIndex.clearance;return wq(t,e.start,e.end)>=n-Mq})}startNextGridCandidate(){if(!this.currentBlocker||!this.currentRange)return void(this.phase="select-blocker");if(this.resolutionCursor>=this.gridResolutions.length)return this.blockerCursor++,void(this.phase="select-blocker");if(this.offsetCursor>=eJ.length)return this.resolutionCursor++,void(this.offsetCursor=0);const t=this.traces[this.currentBlocker.traceIndex],e=t.route[this.currentRange.startIndex],n=t.route[this.currentRange.endIndex];if(!nJ(e)||!nJ(n))return this.blockerCursor++,void(this.phase="select-blocker");const o=this.gridResolutions[this.resolutionCursor],i=eJ[this.offsetCursor],r=this.currentObstacleIndex;if(!r)return this.blockerCursor++,void(this.phase="select-blocker");this.attemptedGridCount++,this.activeSubSolver=new Qq({start:e,end:n,layer:e.layer,traceWidth:this.currentTraceWidth,gridSize:o,gridOffset:{x:i.x*o,y:i.y*o},connectionNames:this.getTraceConnectionNames(t),obstacleIndex:r,ignoreTraceIndex:this.currentBlocker.traceIndex,ignoreRouteRange:{start:this.currentRange.startIndex,end:this.currentRange.endIndex},bounds:this.inputProblem.simpleRouteJson.bounds,searchPadding:Rq(2.5*this.inputProblem.nominalPowerWidth,1.5,4)})}stepActiveSubSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e)return this.applyRoute(e,t instanceof Wq?"elastic":"grid"),this.activeSubSolver=null,void(this.phase="complete")}this.failedSubSolvers??=[],this.failedSubSolvers.push(t),this.activeSubSolver=null,t instanceof Wq?this.phase="try-grid-candidate":this.offsetCursor++}}applyRoute(t,e){const n=this.currentBlocker,o=this.currentRange,i=this.traces[n.traceIndex],r=i.route[o.startIndex],s=i.route[o.endIndex],a=t.points.map(t=>({route_type:"wire",x:t.x,y:t.y,width:this.currentTraceWidth,layer:r.layer}));a[0].width=Math.max(a[0].width,r.width),a[a.length-1].width=Math.max(a[a.length-1].width,s.width),i.route.splice(o.startIndex,o.endIndex-o.startIndex+1,...a),this.output={traces:this.traces,pushedTraceIndex:n.traceIndex,replacedRange:o,strategy:e}}createInflatedCorridorItems(){return this.corridor.flatMap(t=>zq({start:t.start,end:t.end,width:t.width,base:{layers:[t.layer],kind:"obstacle",connectionNames:[]}}))}getGridResolutions(t){return[Rq(1.5*t,.1,.3),Rq(.75*t,.08,.18)].filter((t,e,n)=>n.findIndex(e=>Math.abs(e-t)<Mq)===e)}getRangeWidth(t,e){let n=this.inputProblem.simpleRouteJson.minTraceWidth;for(let o=e.startIndex;o<=e.endIndex;o++){const e=t.route[o];nJ(e)&&(n=Math.max(n,e.width))}return n}getRangeLength(t,e){let n=0;for(let o=e.startIndex;o<e.endIndex;o++){const e=t.route[o],i=t.route[o+1];if(!nJ(e)||!nJ(i)||e.layer!==i.layer)return Number.POSITIVE_INFINITY;n+=Nq(e,i)}return n}resolveNominalTraceWidth(t){return Math.max(t.nominalTraceWidth??t.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.inputProblem.simpleRouteJson.minTraceWidth,this.inputProblem.simpleRouteJson.minTraceWidth)}getTraceNominalWidth(t){return t.route.reduce((t,e)=>"wire"===e.route_type?Math.max(t,e.width):t,this.inputProblem.simpleRouteJson.minTraceWidth)}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=this.getTraceConnectionNames(t),o=this.inputProblem.simpleRouteJson.connections.find(t=>[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=>Boolean(t)).some(t=>n.includes(t)))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getTraceConnectionNames(t){return[t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[]].filter(t=>Boolean(t))}createStats(){return{phase:this.phase,corridorSegment:this.corridorCursor,corridorSegmentCount:this.corridor.length,blockingTraceCount:this.blockersByTrace.size,blockerCursor:this.blockerCursor,pushedTraceIndex:this.currentBlocker?.traceIndex,anchorRange:this.currentRange,traceWidth:this.currentTraceWidth,gridSize:this.gridResolutions[this.resolutionCursor],gridOffsetVariant:this.offsetCursor,attemptedGridCount:this.attemptedGridCount}}computeProgress(){return"scan-corridor"===this.phase?0===this.corridor.length?.25:this.corridorCursor/this.corridor.length*.25:0===this.blockers.length?.5:Math.min(.99,.25+this.blockerCursor/this.blockers.length)}getOutput(){return this.output}getConstructorParams(){return[this.inputProblem]}visualize(){const t=[];for(let e=0;e<this.traces.length;e++){const n=this.traces[e];for(let o=0;o<n.route.length-1;o++){const i=n.route[o],r=n.route[o+1];nJ(i)&&nJ(r)&&i.layer===r.layer&&t.push({points:[i,r],strokeColor:e===this.currentBlocker?.traceIndex?"#1769d2":"#777",strokeWidth:Math.max(i.width,r.width)})}}for(const e of this.corridor)t.push({points:[e.start,e.end],strokeColor:"rgba(255, 128, 0, 0.55)",strokeWidth:e.width});return{coordinateSystem:"cartesian",title:this.getSolverName(),lines:t,points:[],rects:[],circles:[],texts:[]}}},iJ=1e-6,rJ=(t,e)=>Math.hypot(t.x-e.x,t.y-e.y),sJ=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r<=1e-12?0:Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r));return Math.hypot(t.x-(e.x+s*o),t.y-(e.y+s*i))},aJ=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),cJ=(t,e,n,o)=>((t,e,n,o)=>{const i=aJ(n,o,t),r=aJ(n,o,e),s=aJ(t,e,n),a=aJ(t,e,o);return(i>0&&r<0||i<0&&r>0)&&(s>0&&a<0||s<0&&a>0)})(t,e,n,o)?0:Math.min(sJ(t,n,o),sJ(e,n,o),sJ(n,t,e),sJ(o,t,e)),lJ=t=>{const e=(t.ccwRotationDegrees??0)*Math.PI/180,n=Math.cos(e),o=Math.sin(e);return[{x:-t.width/2,y:-t.height/2},{x:t.width/2,y:-t.height/2},{x:t.width/2,y:t.height/2},{x:-t.width/2,y:t.height/2}].map(e=>({x:t.center.x+e.x*n-e.y*o,y:t.center.y+e.x*o+e.y*n}))},dJ=t=>{if(!("oval"===t.type||"circle"===t.shape))return!1;if(Math.abs(t.width-t.height)>iJ)throw new Error(`Physical connectivity does not yet support non-circular oval obstacle ${t.obstacleId??"<unknown>"}`);return!0},hJ=(t,e)=>{for(let n=0;n<e.length;n++)if(sJ(t,e[n],e[(n+1)%e.length])<=iJ)return!0;let n=!1;for(let o=0,i=e.length-1;o<e.length;i=o++){const r=e[o],s=e[i];r.y>t.y!=s.y>t.y&&t.x<(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x&&(n=!n)}return n},uJ=(t,e)=>{if(dJ(e))return Math.max(0,rJ(t,e.center)-e.width/2);const n=lJ(e);return hJ(t,n)?0:Math.min(...n.map((e,o)=>sJ(t,e,n[(o+1)%n.length])))},pJ=(t,e)=>{if(dJ(t))return dJ(e)?Math.max(0,rJ(t.center,e.center)-t.width/2-e.width/2):Math.max(0,uJ(t.center,e)-t.width/2);if(dJ(e))return pJ(e,t);const n=lJ(t),o=lJ(e);if(hJ(n[0],o)||hJ(o[0],n))return 0;let i=Number.POSITIVE_INFINITY;for(let t=0;t<n.length;t++)for(let e=0;e<o.length;e++)i=Math.min(i,cJ(n[t],n[(t+1)%n.length],o[e],o[(e+1)%o.length]));return i},mJ=(t,e)=>({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),gJ=t=>({minX:t.x,minY:t.y,maxX:t.x,maxY:t.y}),fJ=t=>{if(dJ(t))return mJ(gJ(t.center),t.width/2);const e=lJ(t);return{minX:Math.min(...e.map(t=>t.x)),minY:Math.min(...e.map(t=>t.y)),maxX:Math.max(...e.map(t=>t.x)),maxY:Math.max(...e.map(t=>t.y))}},yJ=(t,e)=>{if(!((t,e)=>t.layers.some(t=>e.layers.includes(t)))(t,e)||!((t,e)=>t.maxX+iJ>=e.minX&&e.maxX+iJ>=t.minX&&t.maxY+iJ>=e.minY&&e.maxY+iJ>=t.minY)(t.bounds,e.bounds))return!1;if("bridge-pad"===t.kind){const n={kind:"obstacle",obstacle:t.obstacle,layers:t.layers,bounds:t.bounds};return"bridge-pad"===e.kind?yJ(n,{kind:"obstacle",obstacle:e.obstacle,layers:e.layers,bounds:e.bounds}):yJ(n,e)}return"bridge-pad"===e.kind?yJ(e,t):"endpoint"===t.kind?"endpoint"===e.kind?rJ(t.point,e.point)<=iJ:"obstacle"===e.kind?uJ(t.point,e.obstacle)<=iJ:"segment"===e.kind?sJ(t.point,e.start,e.end)<=e.width/2+iJ:rJ(t.point,e.center)<=e.diameter/2+iJ:"endpoint"===e.kind?yJ(e,t):"obstacle"===t.kind?"obstacle"===e.kind?pJ(t.obstacle,e.obstacle)<=iJ:"segment"===e.kind?((t,e,n)=>{if(dJ(n))return Math.max(0,sJ(n.center,t,e)-n.width/2);const o=lJ(n);return hJ(t,o)||hJ(e,o)?0:Math.min(...o.map((n,i)=>cJ(t,e,n,o[(i+1)%o.length])))})(e.start,e.end,t.obstacle)<=e.width/2+iJ:uJ(e.center,t.obstacle)<=e.diameter/2+iJ:"obstacle"===e.kind?yJ(e,t):"segment"===t.kind?"segment"===e.kind?cJ(t.start,t.end,e.start,e.end)<=(t.width+e.width)/2+iJ:sJ(e.center,t.start,t.end)<=t.width/2+e.diameter/2+iJ:"segment"===e.kind?yJ(e,t):rJ(t.center,e.center)<=(t.diameter+e.diameter)/2+iJ},_J=class{parent;constructor(t){this.parent=Array.from({length:t},(t,e)=>e)}find(t){const e=this.parent[t];if(e===t)return t;const n=this.find(e);return this.parent[t]=n,n}union(t,e){const n=this.find(t),o=this.find(e);n!==o&&(this.parent[o]=n)}},bJ=(t,e)=>{const n=e.indexOf(t.from_layer),o=e.indexOf(t.to_layer);return n<0||o<0?[...new Set([t.from_layer,t.to_layer])]:e.slice(Math.min(n,o),Math.max(n,o)+1)},xJ=t=>[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=>Boolean(t)),vJ=t=>[t.name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],t.netConnectionName,...t.pointsToConnect.flatMap(t=>[t.pointId,t.pcb_port_id])].filter(t=>Boolean(t)),SJ=t=>[t.obstacleId,...t.connectedTo,...t.offBoardConnectsTo??[]].filter(t=>Boolean(t)),IJ=(t,e,n,o)=>({kind:"bridge-contact",center:{x:t.x,y:t.y},diameter:e,layers:n,bridgeId:o,bounds:mJ(gJ(t),e/2)}),CJ=.01,PJ={"0603":{horizontalWidth:.8,horizontalHeight:.95,centerSpacings:[1.65,1.8]},1206:{horizontalWidth:.6,horizontalHeight:1.6,centerSpacings:[3.2]},"1206x4_pair":{horizontalWidth:.8,horizontalHeight:.5,centerSpacings:[2.7]}},MJ=(t,e,n)=>{if(!t.layer)throw new Error(`Jumper ${n} is missing its layer`);const o=PJ[t.footprint];if(!o)throw new Error(`Unsupported jumper footprint ${String(t.footprint)} on ${n}`);const i=Math.abs(t.end.x-t.start.x),r=Math.abs(t.end.y-t.start.y),s=t=>o.centerSpacings.some(e=>Math.abs(t-e)<CJ),a=r<CJ&&s(i),c=i<CJ&&s(r);if(!a&&!c)throw new Error(`Jumper ${n} does not match ${t.footprint} pad spacing`);const l={type:"rect",center:{...e},width:a?o.horizontalWidth:o.horizontalHeight,height:a?o.horizontalHeight:o.horizontalWidth,layers:[t.layer],connectedTo:[]};return{kind:"bridge-pad",obstacle:l,layers:l.layers,bridgeId:n,bounds:fJ(l)}},NJ=(t,e,n)=>{if(t.layer!==n.layer||e.layer!==n.layer)return!1;const o=(t,e)=>Math.abs(t.x-e.x)<CJ&&Math.abs(t.y-e.y)<CJ,i=o(t,n.start)&&o(e,n.end),r=o(t,n.end)&&o(e,n.start);return i||r},wJ=(t,e,n,o)=>{const i=[],r=t.route.flatMap((t,e)=>"jumper"===t.route_type?[{routePoint:t,routePointIndex:e}]:[]),s=new Map;for(const e of r){const n=[];for(let o=1;o<t.route.length;o++){const i=t.route[o-1],r=t.route[o];"wire"===i?.route_type&&"wire"===r?.route_type&&NJ(i,r,e.routePoint)&&n.push(o)}if(1!==n.length)throw new Error(`Jumper ${t.pcb_trace_id}:${e.routePointIndex} matched ${n.length} placeholder wire segments`);const o=n[0];if(s.has(o))throw new Error(`Multiple jumpers matched placeholder segment ${o} on ${t.pcb_trace_id}`);s.set(o,e)}let a;for(let r=0;r<t.route.length;r++){const c=t.route[r];if("wire"===c.route_type){if(a&&a.layer===c.layer&&rJ(a,c)>iJ){const t=a;if(s.get(r));else{const e=t.width/2;i.push({kind:"segment",start:{x:t.x,y:t.y},end:{x:c.x,y:c.y},width:t.width,layers:[t.layer],bounds:mJ({minX:Math.min(t.x,c.x),minY:Math.min(t.y,c.y),maxX:Math.max(t.x,c.x),maxY:Math.max(t.y,c.y)},e)})}}a=c;continue}if(a=void 0,"via"===c.route_type){const o=t.route[r-1],s=t.route[r+1];for(const e of[o,s])if("wire"===e?.route_type&&rJ(e,c)>iJ)throw new Error(`Via ${t.pcb_trace_id}:${r} is adjacent to a non-colocated wire endpoint`);const a=c.via_diameter??n;i.push({kind:"via",center:{x:c.x,y:c.y},diameter:a,layers:bJ(c,e),bounds:mJ(gJ(c),a/2)});continue}const l=`${t.pcb_trace_id}:${r}:${c.route_type}`;if("jumper"===c.route_type){i.push(MJ(c,c.start,l),MJ(c,c.end,l));continue}if("through_obstacle"===c.route_type){if(!o.find(t=>t.layers.includes(c.from_layer)&&t.layers.includes(c.to_layer)&&uJ(c.start,t)<=iJ&&uJ(c.end,t)<=iJ))throw new Error(`Through-obstacle marker ${l} has no same-net multilayer obstacle witness`);i.push(IJ(c.start,0,[c.from_layer],l),IJ(c.end,0,[c.to_layer],l));continue}throw new Error(`Unsupported route primitive: ${String(c.route_type)}`)}return i},TJ=(t,e,n)=>{const o=t.pointsToConnect[n];return o.pointId??o.pcb_port_id??`${t.name}[${e}:${n}]`},RJ=t=>{const e={},n={},o=[];for(let i=0;i<t.connections.length;i++){const r=t.connections[i];for(let t=0;t<r.pointsToConnect.length;t++){const s=`${i}:${t}`;e[s]=TJ(r,i,t),n[s]=s,o.push([s])}}return{endpointCount:Object.keys(e).length,endpointLabels:e,componentByEndpointKey:n,endpointComponents:o}},EJ=t=>{if(null===t||"object"!=typeof t)return JSON.stringify(t)??String(t);if(Array.isArray(t))return`[${t.map(t=>EJ(t)).join(",")}]`;const e=t;return`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${EJ(e[t])}`).join(",")}}`},AJ=(t,e)=>{const n=new Pq(t,e,{includePhysicalPositionAliases:!0}),o=(i=t.layerCount)<=1?["top"]:2===i?["top","bottom"]:["top",...Array.from({length:i-2},(t,e)=>`inner${e+1}`),"bottom"];var i;const r=(t=>{const e=t.min_via_hole_diameter??t.minViaHoleDiameter??0;return Math.max(e,t.min_via_pad_diameter??t.minViaPadDiameter??t.minViaDiameter??.6)})(t),s=new Map,a=new Map,c={},l=(t,e)=>{const n=s.get(t)??[];n.push(e),s.set(t,n)};for(let e=0;e<t.connections.length;e++){const o=t.connections[e],i=n.canonicalize(vJ(o));if(1!==i.length)throw new Error(`Connection ${o.name} resolved to ${i.length} canonical nets`);for(let t=0;t<o.pointsToConnect.length;t++){const n=o.pointsToConnect[t],r=`${e}:${t}`,s=TJ(o,e,t);c[r]=s;const a={kind:"endpoint",endpointKey:r,endpointLabel:s,point:{x:n.x,y:n.y},layers:n.layers??[n.layer],bounds:gJ(n)};for(const t of i)l(t,a)}}for(const e of t.obstacles){const t={kind:"obstacle",obstacle:e,layers:e.layers,bounds:fJ(e)};for(const o of n.canonicalize(SJ(e))){const n=a.get(o)??[];n.push(e),a.set(o,n),s.has(o)&&l(o,t)}}for(const i of[...e,...t.fixedTraces??[]]){const t=n.canonicalize(xJ(i));if(1!==t.length)throw new Error(`Trace ${i.pcb_trace_id} resolved to ${t.length} canonical nets`);const e=a.get(t[0])??[],c=wJ(i,o,r,e);for(const e of t)if(s.has(e))for(const t of c)l(e,t)}const d={},h=[];for(const t of s.values()){const e=new _J(t.length),n=new Map;for(let o=0;o<t.length;o++){const i=t[o];if("bridge-contact"!==i.kind&&"bridge-pad"!==i.kind)continue;const r=n.get(i.bridgeId);void 0===r?n.set(i.bridgeId,o):e.union(r,o)}const o=t.length>0?new Bt(t.length):null;if(o){for(const e of t)o.add(e.bounds.minX,e.bounds.minY,e.bounds.maxX,e.bounds.maxY);o.finish()}for(let n=0;n<t.length;n++){const i=t[n],r=o?.search(i.bounds.minX-iJ,i.bounds.minY-iJ,i.bounds.maxX+iJ,i.bounds.maxY+iJ)??[];for(const o of r)o<=n||yJ(i,t[o])&&e.union(n,o)}const i=new Map;for(let n=0;n<t.length;n++){const o=t[n];if("endpoint"!==o.kind)continue;const r=e.find(n),s=i.get(r)??[];s.push(o.endpointKey),i.set(r,s)}for(const t of i.values()){t.sort();const e=t[0];h.push(t);for(const n of t){if(void 0!==d[n])throw new Error(`Endpoint ${n} was assigned to multiple canonical nets`);d[n]=e}}}return h.sort(([t=""],[e=""])=>t.localeCompare(e)),{endpointCount:Object.keys(c).length,endpointLabels:c,componentByEndpointKey:d,endpointComponents:h}},OJ=class{baseline;inputProblem;baselineCaptureError;baselineTraceSignature;constructor(t,e){this.inputProblem=t,this.baselineTraceSignature=EJ(e);try{this.baseline=AJ(t,e),this.baselineCaptureError=null}catch(e){this.baseline=RJ(t),this.baselineCaptureError=e instanceof Error?e.message:String(e)}}validate(t){if(this.baselineCaptureError){const e=EJ(t)===this.baselineTraceSignature;return{safe:e,candidate:this.baseline,regressions:[],validationError:e?`Connectivity validation is limited to exact trace preservation: ${this.baselineCaptureError}`:`Connectivity validation failed closed: ${this.baselineCaptureError}`}}let e;try{e=AJ(this.inputProblem,t)}catch(t){return{safe:!1,candidate:RJ(this.inputProblem),regressions:[],validationError:`Connectivity validation failed closed: ${t instanceof Error?t.message:String(t)}`}}const n=[];for(const t of this.baseline.endpointComponents){if(t.length<2)continue;const o=new Map;for(const n of t){const t=e.componentByEndpointKey[n]??`missing:${n}`,i=o.get(t)??[];i.push(n),o.set(t,i)}o.size<=1||n.push({baselineEndpointKeys:[...t],baselineEndpointLabels:t.map(t=>this.baseline.endpointLabels[t]),candidateComponents:[...o.values()]})}return{safe:0===n.length,candidate:e,regressions:n}}},kJ=[{x:0,y:0},{x:.5,y:.5}],LJ=[.15,.2,.25,.3,.4,.5],DJ=t=>"wire"===t?.route_type,zJ=t=>"via"===t?.route_type,FJ=Array.from({length:24},(t,e)=>{const n=e*Math.PI/12;return{x:Math.cos(n),y:Math.sin(n)}}),BJ=t=>[...new Set(t.map(t=>Number(t.toFixed(6))))].sort((t,e)=>e-t),jJ=class extends Sq{inputProblem;traces;obstacleIndex;phase="repair-vias";traceCursor=0;routeCursor=0;candidateCursor=0;clearanceTierCursor=0;attemptedCandidateCount=0;attemptedClearanceShoveCount=0;attemptedViaGridCount=0;committedClearanceShoveCount=0;viaPairCountRemoved=0;viaCountRemoved=0;simplifiedPathCount=0;normalizedSegmentCount=0;achievedExtraClearanceCount=0;relocatedViaCount=0;unresolvedViaCount=0;attemptedPushedViaRepairCount=0;committedPushedViaRepairCount=0;padClearanceRerouteCount=0;unresolvedPadClearanceCount=0;initialPadClearanceViolationCount=0;remainingPadClearanceViolationCount=0;initialPadClearanceViolationCountByClearance={};remainingPadClearanceViolationCountByClearance={};budgetLimited=!1;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;connectionNameResolver;connectionByTraceId=new Map;connectivityInvariant;initialConnectivitySafeTraces;mutableTraceIndices;mutableTraceIndexSet;viaRepairTraceIndices;traceIndices;maxRerouteLength;clearancePaddingTiers;desiredPadClearance;initialTraceLengths=new Map;candidates=[];candidateShoveCount=0;rollbackTraces=null;baseCandidateValidated=!1;activeShovePadding=0;viaGridAttempt=null;candidateSetMayUseGridFallback=!1;pendingPushedViaRepair=null;alternatePushedViaRepairs=[];pushedViaRepairRollbackTraces=null;connectivityFinalized=!1;finalizedMutatedTraceIndices=[];resumePhase="scan-via-pairs";constructor(t){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.initialConnectivitySafeTraces=structuredClone(t.traces),this.connectivityInvariant=new OJ(this.inputProblem.simpleRouteJson,this.initialConnectivitySafeTraces),this.connectionNameResolver=new Pq(t.simpleRouteJson,this.traces),this.maxRerouteLength=t.maxRerouteLength??10,this.desiredPadClearance=t.desiredPadClearance,this.clearancePaddingTiers=BJ([...t.clearancePaddingTiers??[.1,.05,0],0]).filter(t=>t>=0);const e=this.traces.map((t,e)=>e),n=(t,e,n)=>{const o=[...new Set(t??n)];for(const t of o)if(!Number.isInteger(t)||t<0||t>=this.traces.length)throw new RangeError(`Invalid cleanup ${e} index: ${t}`);return o},o=n(t.traceIndices,"trace",e);this.viaRepairTraceIndices=n(t.viaRepairTraceIndices,"via repair trace",o),this.mutableTraceIndices=n(t.mutableTraceIndices,"mutable trace",o),this.mutableTraceIndexSet=new Set(this.mutableTraceIndices),this.traceIndices=o.filter(t=>this.resolveNominalTraceWidth(this.traces[t])>=.499999);for(const t of this.traceIndices)this.initialTraceLengths.set(t,this.measureTraceLength(this.traces[t]));this.obstacleIndex=this.createObstacleIndex(),this.initialPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCount=this.initialPadClearanceViolationCount,this.initialPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.remainingPadClearanceViolationCountByClearance={...this.initialPadClearanceViolationCountByClearance},this.activeSubSolver=null,this.MAX_ITERATIONS=1e6,this.stats=this.createStats()}getSolverName(){return"PowerTraceCleanupSolver"}_step(){if(this.activeSubSolver)return this.stepActiveShoveSolver(),void(this.stats=this.createStats());switch(this.phase){case"repair-vias":this.repairNextVia();break;case"scan-via-pairs":this.scanNextViaPair();break;case"scan-pad-clearance":this.scanNextPadClearance();break;case"scan-simplification":this.scanNextSimplification();break;case"evaluate-candidate":this.evaluateCurrentCandidate();break;case"shove-clearance":break;case"route-via-pair":this.startNextViaGridCandidate();break;case"complete":this.ensureConnectivitySafeOutput(),this.solved=!0}this.stats=this.createStats()}repairNextVia(){const t=this.viaRepairTraceIndices[this.traceCursor],e=void 0===t?void 0:this.traces[t];if(!e)return this.traceCursor=0,this.routeCursor=0,this.phase="scan-via-pairs",void this.rebuildObstacleIndex();const n=e.route.findIndex((t,e)=>e>=this.routeCursor&&zJ(t));if(-1===n)return this.traceCursor++,void(this.routeCursor=0);this.routeCursor=n+1;const o=e.route[n],i=e.route[n-1],r=e.route[n+1];if(!zJ(o)||!DJ(i)||!DJ(r))return;const s=this.getTraceConnectionNames(e),a=this.getBaseObstacleClearance();if(!this.obstacleIndex.collidesVia({point:o,layers:this.obstacleIndex.boardLayers,padDiameter:o.via_diameter??.6,holeDiameter:o.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,connectionNames:s,ignoreTraceIndex:t,ignoreRouteRange:{start:n,end:n},obstacleClearance:a,blockSameNetObstacles:!0,sameNetObstacleClearance:0}))return;const c=this.findViaRepair(e,n,a);if(!c){const t=this.findPushableViaRepairs(e,n,a),o=t.shift();return o?(this.alternatePushedViaRepairs=t,void this.startPushedViaRepair(o)):void this.unresolvedViaCount++}e.route.splice(c.startIndex,c.endIndex-c.startIndex+1,...c.route),this.relocatedViaCount++,this.routeCursor=c.startIndex+c.route.length,this.rebuildObstacleIndex()}findViaRepair(t,e,n){const o=this.createViaRepairContext(t,e);if(!o)return null;const i=o.candidates.map(t=>({point:t,movedLength:Nq(o.leftAnchor,t)+Nq(t,o.rightAnchor)})).filter(({movedLength:t})=>t<=o.originalLength+Math.min(6,this.maxRerouteLength)+Mq);i.sort((t,e)=>t.movedLength-e.movedLength||Nq(t.point,o.via)-Nq(e.point,o.via));for(const t of i)if(this.isViaRepairPointSafe(o,t.point,n))return this.createViaRepairReplacement(o,t.point);return null}findPushableViaRepairs(t,e,n){const o=this.viaRepairTraceIndices[this.traceCursor];if(void 0===o)return[];const i=this.createViaRepairContext(t,e);if(!i)return[];const r=i.candidates.flatMap(t=>{const e=Nq(i.leftAnchor,t)+Nq(t,i.rightAnchor);if(e>i.originalLength+Math.min(6,this.maxRerouteLength)+Mq)return[];const r=new Set,s=this.getViaRepairCollisionQueries(i,t,n);for(const t of s)for(const e of this.obstacleIndex.findCollisions(t)){if("trace"!==e.kind||void 0===e.traceIndex||e.traceIndex===o||!this.mutableTraceIndexSet.has(e.traceIndex))return[];r.add(e.traceIndex)}if(0===r.size||r.size>2)return[];const a=[...r];return this.isViaRepairPointSafe(i,t,n,a)?[{point:t,movedLength:e,blockerCount:r.size,blockerKey:[...r].sort((t,e)=>t-e).join(",")}]:[]});r.sort((t,e)=>t.blockerCount-e.blockerCount||t.movedLength-e.movedLength||Nq(t.point,i.via)-Nq(e.point,i.via));return[...new Map([...r].reverse().map(t=>[t.blockerKey,t])).values(),...r].filter((t,e,n)=>n.findIndex(e=>e.point.x===t.point.x&&e.point.y===t.point.y)===e).slice(0,12).map(t=>({traceIndex:o,viaIndex:e,point:t.point,padClearance:n,corridor:[{start:i.leftAnchor,end:t.point,layer:i.leftWire.layer,width:i.leftWire.width},{start:t.point,end:i.rightAnchor,layer:i.rightWire.layer,width:i.rightWire.width},...this.obstacleIndex.boardLayers.map(e=>({start:t.point,end:t.point,layer:e,width:i.viaDiameter}))]}))}createViaRepairContext(t,e){const n=t.route[e],o=t.route[e-1],i=t.route[e+1];if(!zJ(n)||!DJ(o)||!DJ(i))return null;const r=e-1==0||!DJ(t.route[e-2]),s=e+1===t.route.length-1||!DJ(t.route[e+2]),a=r?o:t.route[e-2],c=s?i:t.route[e+2],l=Nq(a,n)+Nq(n,c),d=this.getTraceConnectionNames(t),h=n.via_diameter??.6,u=n.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,p=Math.max(.3,u+this.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance+.05),m=[p,p+.15,p+.3,p+.5,p+.75,p+1,p+1.5,p+2].flatMap(t=>FJ.map(e=>({x:.025*Math.round((n.x+e.x*t)/.025),y:.025*Math.round((n.y+e.y*t)/.025)}))),g=[...m,...m.flatMap(t=>[{x:t.x,y:Math.floor(10*n.y)/10},{x:t.x,y:Math.ceil(10*n.y)/10},{x:Math.floor(10*n.x)/10,y:t.y},{x:Math.ceil(10*n.x)/10,y:t.y}])].filter((t,e,n)=>n.findIndex(e=>e.x===t.x&&e.y===t.y)===e);return{trace:t,viaIndex:e,via:n,leftWire:o,rightWire:i,leftIsEndpoint:r,rightIsEndpoint:s,leftAnchor:a,rightAnchor:c,originalLength:l,connectionNames:d,viaDiameter:h,holeDiameter:u,ignoreRouteRange:{start:Math.max(0,e-2),end:Math.min(t.route.length-1,e+2)},candidates:g}}getViaRepairCollisionQueries(t,e,n,o){const i=this.viaRepairTraceIndices[this.traceCursor],r={connectionNames:t.connectionNames,ignoreTraceIndex:i,ignoreTraceIndices:o,ignoreRouteRange:t.ignoreRouteRange,obstacleClearance:n};return[...this.obstacleIndex.boardLayers.map(n=>({...r,start:e,end:e,layer:n,width:t.viaDiameter,blockSameNetObstacles:!0,sameNetObstacleClearance:0})),{...r,start:t.leftAnchor,end:e,layer:t.leftWire.layer,width:t.leftWire.width},{...r,start:e,end:t.rightAnchor,layer:t.rightWire.layer,width:t.rightWire.width}]}isViaRepairPointSafe(t,e,n,o){const i=this.viaRepairTraceIndices[this.traceCursor];return!this.obstacleIndex.collidesVia({point:e,layers:this.obstacleIndex.boardLayers,padDiameter:t.viaDiameter,holeDiameter:t.holeDiameter,connectionNames:t.connectionNames,ignoreTraceIndex:i,ignoreTraceIndices:o,ignoreRouteRange:{start:t.viaIndex,end:t.viaIndex},obstacleClearance:n,blockSameNetObstacles:!0,sameNetObstacleClearance:0})&&!this.getViaRepairCollisionQueries(t,e,n,o).slice(this.obstacleIndex.boardLayers.length).some(t=>this.obstacleIndex.collides(t))}createViaRepairReplacement(t,e){const n={...t.leftWire,...e},o={...t.via,...e},i={...t.rightWire,...e};return{startIndex:t.viaIndex-1,endIndex:t.viaIndex+1,route:[...t.leftIsEndpoint?[t.leftWire]:[],n,o,i,...t.rightIsEndpoint?[t.rightWire]:[]]}}startPushedViaRepair(t){this.pendingPushedViaRepair=t,this.pushedViaRepairRollbackTraces=structuredClone(this.traces),this.attemptedPushedViaRepairCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem.simpleRouteJson,traces:this.traces,powerTraceIndex:t.traceIndex,nominalPowerWidth:Math.max(...t.corridor.map(t=>t.width)),pushOnlyNominalWidthsBelow:Number.POSITIVE_INFINITY,mutableTraceIndices:this.mutableTraceIndices,corridor:t.corridor,maxRerouteLength:this.maxRerouteLength},this.connectionNameResolver)}finishPushedViaRepairSolver(t){const e=this.pendingPushedViaRepair;if(this.activeSubSolver=null,!e)return;if(t.solved){const n=t.getOutput();if(n){this.traces=n.traces,this.rebuildObstacleIndex();const t=this.traces[e.traceIndex],o=t?this.createViaRepairContext(t,e.viaIndex):null;if(o&&this.isViaRepairPointSafe(o,e.point,e.padClearance)){const n=this.createViaRepairReplacement(o,e.point);return t.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...n.route),this.relocatedViaCount++,this.committedPushedViaRepairCount++,this.routeCursor=n.startIndex+n.route.length,this.pendingPushedViaRepair=null,this.alternatePushedViaRepairs=[],this.pushedViaRepairRollbackTraces=null,void this.rebuildObstacleIndex()}}}this.pushedViaRepairRollbackTraces&&(this.traces=this.pushedViaRepairRollbackTraces),this.pendingPushedViaRepair=null,this.pushedViaRepairRollbackTraces=null;const n=this.alternatePushedViaRepairs.shift();if(n)return this.rebuildObstacleIndex(),void this.startPushedViaRepair(n);this.alternatePushedViaRepairs=[],this.unresolvedViaCount++,this.rebuildObstacleIndex()}scanNextViaPair(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.traceCursor=0,this.routeCursor=0,void(this.phase="scan-pad-clearance");const e=this.traces[t],n=e.route.findIndex((t,e)=>e>=this.routeCursor&&"via"===t.route_type);if(-1===n)return void this.advanceTrace();const o=e.route.slice(n+1).findIndex(t=>"via"===t.route_type);if(-1===o)return void this.advanceTrace();const i=n-1,r=n+1+o+1,s=e.route[i],a=e.route[r];if(this.routeCursor=n+1,!DJ(s)||!DJ(a)||s.layer!==a.layer||Nq(s,a)>this.maxRerouteLength+Mq)return;const c=this.createCandidates({kind:"via-pair",traceIndex:t,startIndex:i,endIndex:r}),l=c[0]?.width??Math.max(s.width,a.width),d=c[0]?.padClearance??this.getCandidatePadClearance("via-pair",t,i,r),h=n=>{const o=e.route[n];return!!DJ(o)&&this.obstacleIndex.findCollisions({start:o,end:o,layer:o.layer,width:l,connectionNames:this.getTraceConnectionNames(e),ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,i-1),end:Math.min(e.route.length-1,r+1)},obstacleClearance:d}).some(t=>"obstacle"===t.kind&&"pad"===t.obstacleKind)},u=e.route[i-1],p=e.route[r+1],m=c.length>0&&h(i)&&DJ(u)&&u.layer===s.layer?i-1:i,g=c.length>0&&h(r)&&DJ(p)&&p.layer===a.layer?r+1:r,f=[{startIndex:i,endIndex:r},{startIndex:m,endIndex:r},{startIndex:i,endIndex:g},{startIndex:m,endIndex:g}].filter((t,e,n)=>n.findIndex(e=>e.startIndex===t.startIndex&&e.endIndex===t.endIndex)===e).flatMap(e=>e.startIndex===i&&e.endIndex===r?c:this.createCandidates({kind:"via-pair",traceIndex:t,startIndex:e.startIndex,endIndex:e.endIndex}));0!==f.length&&this.beginCandidates(f,"scan-via-pairs",!0)}scanNextPadClearance(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.traceCursor=0,this.routeCursor=0,void(this.phase="scan-simplification");const e=this.traces[t];if(this.resolveNominalTraceWidth(e)<.499999)return void this.advanceTrace();const n=this.routeCursor,o=e.route[n],i=e.route[n+1];if(!DJ(o)||!DJ(i)||o.layer!==i.layer)return void(n>=e.route.length-1?this.advanceTrace():this.routeCursor++);if(this.routeCursor++,!this.segmentHasPadClearanceViolation(t,n))return;const r=this.getPadClearanceIntervals(e,n).flatMap(e=>this.getImprovedPadClearanceTiers(t,e.startIndex,e.endIndex).flatMap(n=>this.createCandidates({kind:"pad-clearance",traceIndex:t,startIndex:e.startIndex,endIndex:e.endIndex,padClearance:n}).slice(0,8)));0!==r.length?this.beginCandidates(r.slice(0,72),"scan-pad-clearance",!0):this.unresolvedPadClearanceCount++}segmentHasPadClearanceViolation(t,e){const n=this.traces[t],o=n.route[e],i=n.route[e+1];return!(!DJ(o)||!DJ(i)||o.layer!==i.layer)&&this.obstacleIndex.findCollisions({start:o,end:i,layer:o.layer,width:Math.max(o.width,i.width),connectionNames:this.getTraceConnectionNames(n),ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,e-1),end:Math.min(n.route.length-1,e+2)},obstacleClearance:this.getPadClearanceForTrace(n)}).some(t=>"obstacle"===t.kind&&"pad"===t.obstacleKind)}getPadClearanceIntervals(t,e){const n=t.route[e];if(!DJ(n))return[];const o=[e];let i=0;for(let r=e-1;r>=0;r--){const e=t.route[r],s=t.route[r+1];if(!DJ(e)||!DJ(s)||e.layer!==n.layer||s.layer!==n.layer)break;if(i+=Nq(e,s),i>this.maxRerouteLength/2+Mq)break;o.push(r)}const r=[e+1];i=0;for(let o=e+1;o<t.route.length-1;o++){const e=t.route[o],s=t.route[o+1];if(!DJ(e)||!DJ(s)||e.layer!==n.layer||s.layer!==n.layer)break;if(i+=Nq(e,s),i>this.maxRerouteLength/2+Mq)break;r.push(o+1)}return o.flatMap(e=>r.map(n=>({startIndex:e,endIndex:n,length:this.measureRouteRange(t,e,n).length}))).filter(t=>t.length<=this.maxRerouteLength+Mq&&t.startIndex<t.endIndex).sort((t,e)=>e.length-t.length).slice(0,8)}scanNextSimplification(){const t=this.traceIndices[this.traceCursor];if(void 0===t)return this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),void(this.phase="complete");const e=this.traces[t],n=this.routeCursor,o=e.route[n];if(!DJ(o)||n>=e.route.length-1)return void(n>=e.route.length-1?this.advanceTrace():this.routeCursor++);let i=0;const r=[];for(let t=n+1;t<e.route.length;t++){const s=e.route[t-1],a=e.route[t];if(!DJ(s)||!DJ(a)||s.layer!==o.layer||a.layer!==o.layer)break;if(i+=Nq(s,a),i>this.maxRerouteLength+Mq)break;const c=this.measureRouteRange(e,n,t);(c.nonOctilinearSegmentCount>0||c.pointCount>3)&&r.push(t)}const s=r.slice(-6).reverse().flatMap(e=>this.createCandidates({kind:"simplification",traceIndex:t,startIndex:n,endIndex:e}));0!==s.length?this.beginCandidates(s,"scan-simplification"):this.routeCursor++}createCandidates({kind:t,traceIndex:e,startIndex:n,endIndex:o,padClearance:i}){const r=this.traces[e],s=r.route[n],a=r.route[o];if(!DJ(s)||!DJ(a)||s.layer!==a.layer)return[];const c=this.resolveNominalTraceWidth(r),l=this.measureRouteRange(r,n,o),d=i??this.getCandidatePadClearance(t,e,n,o),h=[],u=qq(s,a);if("pad-clearance"===t&&0===Gq([s,a])){const t=Nq(s,a);if(t>Mq){const e={x:-(a.y-s.y)/t,y:(a.x-s.x)/t};for(const t of[.25,.5,.75,1,1.5,2])for(const n of[-1,1])u.push([s,{x:s.x+e.x*t*n,y:s.y+e.y*t*n},{x:a.x+e.x*t*n,y:a.y+e.y*t*n},a])}}const p=new Map(u.map(t=>[t.map(t=>`${t.x.toFixed(6)},${t.y.toFixed(6)}`).join(";"),t]));for(const i of p.values()){const u=Uq(i);if(u>this.maxRerouteLength+Mq||"pad-clearance"===t&&u>1.35*l.length+.5||"simplification"===t&&(u>1.1*l.length+Mq||this.measureTraceLength(r)-l.length+u>1.01*(this.initialTraceLengths.get(e)??this.measureTraceLength(r))+Mq))continue;const p=u<=Mq?c:c-l.deficitArea/u;if(p>c+Mq)continue;const m=.05*Math.ceil(Math.max(this.inputProblem.simpleRouteJson.minTraceWidth,p)/.05-Mq),g=BJ([c,Math.min(c,m),Math.min(c,Math.max(this.inputProblem.simpleRouteJson.minTraceWidth,p))].map(t=>Math.max(t,s.width)));for(const r of g){const u=this.measureCandidate(i,r,c,a.width,s.width);u.deficitArea>l.deficitArea+Mq||u.conservativeDeficitArea>l.conservativeDeficitArea+Mq||!this.preservesCoverage(u,l)||("simplification"!==t||0!==l.nonOctilinearSegmentCount||u.pointCount<l.pointCount&&u.length<l.length-Mq)&&h.push({kind:t,traceIndex:e,startIndex:n,endIndex:o,layer:s.layer,points:i,width:r,padClearance:d,originalQuality:l})}}return h.slice(0,18)}beginCandidates(t,e,n=!1){this.candidates=t,this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.rollbackTraces=null,this.baseCandidateValidated=!1,this.resumePhase=e,this.candidateSetMayUseGridFallback=n,this.phase="evaluate-candidate"}evaluateCurrentCandidate(){const t=this.candidates[this.candidateCursor];if(!t)return void this.finishCandidateSet(!1);if(!this.baseCandidateValidated){if(!this.candidateCollides(t,0))return this.candidateShoveCount>0?void this.applyCandidate(t,0):(this.baseCandidateValidated=!0,void(this.clearanceTierCursor=0));return this.getPushableTraceIndices(t,0)&&this.candidateShoveCount<2&&this.attemptedClearanceShoveCount<48?void this.startClearanceShove(t,0):void this.advanceCandidate()}const e=this.clearancePaddingTiers[this.clearanceTierCursor];if(void 0===e||e<=Mq)return void this.applyCandidate(t,0);if(this.attemptedCandidateCount++,!this.candidateCollides(t,e))return void this.applyCandidate(t,e);this.getPushableTraceIndices(t,e)&&this.candidateShoveCount<2&&this.attemptedClearanceShoveCount<48?this.startClearanceShove(t,e):(this.rollbackCandidateShoves(),this.clearanceTierCursor++,this.candidateShoveCount=0)}advanceCandidate(){this.rollbackCandidateShoves(),this.candidateCursor++,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1}candidateCollides(t,e){const n=this.traces[t.traceIndex],o=this.getTraceConnectionNames(n);for(let i=0;i<t.points.length-1;i++){const r=this.getCandidateSegmentWidth(t,i);if(this.obstacleIndex.collides({start:t.points[i],end:t.points[i+1],layer:t.layer,width:r+2*e,connectionNames:o,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(n.route.length-1,t.endIndex+1)},obstacleClearance:t.padClearance}))return!0}return!1}getPushableTraceIndices(t,e){const n=this.traces[t.traceIndex],o=this.getTraceConnectionNames(n),i=new Set;for(let r=0;r<t.points.length-1;r++){const s=this.getCandidateSegmentWidth(t,r),a={start:t.points[r],end:t.points[r+1],layer:t.layer,width:s+2*e,connectionNames:o,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(n.route.length-1,t.endIndex+1)},obstacleClearance:t.padClearance};if(!this.obstacleIndex.collides(a))continue;const c=this.obstacleIndex.findCollisions(a);if(0===c.length)return null;for(const e of c){if("trace"!==e.kind||void 0===e.traceIndex||e.traceIndex===t.traceIndex||!this.mutableTraceIndexSet.has(e.traceIndex))return null;const n=this.traces[e.traceIndex];if(!n||this.resolveNominalTraceWidth(n)>=t.width-Mq)return null;i.add(e.traceIndex)}}return i.size>0&&i.size<=2?[...i]:null}startClearanceShove(t,e){this.rollbackTraces??=structuredClone(this.traces),this.activeShovePadding=e;const n=t.width+2*e,o=t.points.slice(0,-1).map((n,o)=>({start:n,end:t.points[o+1],layer:t.layer,width:this.getCandidateSegmentWidth(t,o)+2*e}));this.attemptedClearanceShoveCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem.simpleRouteJson,traces:this.traces,powerTraceIndex:t.traceIndex,nominalPowerWidth:n,pushOnlyNominalWidthsBelow:t.width,mutableTraceIndices:this.mutableTraceIndices,corridor:o,maxRerouteLength:this.maxRerouteLength},this.connectionNameResolver),this.phase="shove-clearance"}getCandidateSegmentWidth(t,e){const n=this.traces[t.traceIndex],o=n.route[t.startIndex],i=n.route[t.endIndex],r=0===e&&DJ(o)?o.width:t.width,s=e===t.points.length-2&&DJ(i)?i.width:t.width;return Math.max(r,s)}stepActiveShoveSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed)if(this.pendingPushedViaRepair&&t instanceof oJ)this.finishPushedViaRepairSolver(t);else if(t instanceof Qq)this.finishViaGridSolver(t);else{if(this.activeSubSolver=null,this.phase="evaluate-candidate",t.solved){const e=t.getOutput();if(e)return this.traces=e.traces,this.candidateShoveCount++,void this.rebuildObstacleIndex()}this.failedSubSolvers??=[],this.failedSubSolvers.push(t),this.rollbackCandidateShoves(),this.activeShovePadding<=Mq?this.advanceCandidate():this.clearanceTierCursor++,this.candidateShoveCount=0}}rollbackCandidateShoves(){this.rollbackTraces&&(this.traces=this.rollbackTraces,this.rollbackTraces=null,this.rebuildObstacleIndex())}applyCandidate(t,e){const n=this.traces[t.traceIndex],o=n.route[t.startIndex],i=n.route[t.endIndex],r=t.points.map((e,n)=>({...0===n?o:n===t.points.length-1?i:{route_type:"wire",layer:t.layer,width:t.width},x:e.x,y:e.y,layer:t.layer,width:0===n?o.width:n===t.points.length-1?i.width:t.width})),s=n.route.slice(t.startIndex,t.endIndex+1),a=t.originalQuality.nonOctilinearSegmentCount;if(n.route.splice(t.startIndex,t.endIndex-t.startIndex+1,...r),"via-pair"===t.kind){const e=s.filter(t=>"via"===t.route_type).length;this.viaPairCountRemoved++,this.viaCountRemoved+=e,this.routeCursor=Math.max(0,t.startIndex-1)}else"pad-clearance"===t.kind?(this.padClearanceRerouteCount++,this.routeCursor=t.startIndex+Math.max(1,r.length-1)):(this.simplifiedPathCount++,this.normalizedSegmentCount+=a,this.routeCursor=t.startIndex+Math.max(1,r.length-1));this.committedClearanceShoveCount+=this.candidateShoveCount,e>Mq&&this.achievedExtraClearanceCount++,this.rollbackTraces=null,this.candidateShoveCount=0,this.rebuildObstacleIndex(),this.finishCandidateSet(!0)}finishCandidateSet(t){const e=this.candidates[0],n=BJ(this.candidates.filter(t=>t.kind===e?.kind).map(t=>t.width)),o=BJ(this.candidates.filter(t=>t.kind===e?.kind&&t.traceIndex===e.traceIndex&&t.startIndex===e.startIndex&&t.endIndex===e.endIndex).map(t=>t.padClearance));if(this.rollbackCandidateShoves(),this.candidates=[],this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1,!t&&this.candidateSetMayUseGridFallback&&e)return this.candidateSetMayUseGridFallback=!1,void this.beginViaGridAttempt(e,n,o);this.candidateSetMayUseGridFallback=!1,t||this.routeCursor++,this.phase=this.resumePhase}beginViaGridAttempt(t,e,n=[t.padClearance]){this.viaGridAttempt={kind:t.kind,traceIndex:t.traceIndex,startIndex:t.startIndex,endIndex:t.endIndex,layer:t.layer,padClearances:n,padClearanceCursor:0,originalQuality:t.originalQuality,widths:e,widthCursor:0,gridSizes:[],gridSizeCursor:0,offsetCursor:0},this.phase="route-via-pair"}startNextViaGridCandidate(){const t=this.viaGridAttempt;if(!t)return void(this.phase=this.resumePhase);if(t.padClearanceCursor>=t.padClearances.length)return"pad-clearance"===t.kind&&this.unresolvedPadClearanceCount++,this.viaGridAttempt=null,this.routeCursor++,void(this.phase=this.resumePhase);if(t.widthCursor>=t.widths.length)return t.padClearanceCursor++,t.widthCursor=0,t.gridSizes=[],t.gridSizeCursor=0,void(t.offsetCursor=0);const e=t.widths[t.widthCursor],n=t.padClearances[t.padClearanceCursor];if(0===t.gridSizes.length&&(t.gridSizes=BJ([Rq(e/2,.2,.4),Rq(e/3,.15,.25)])),t.gridSizeCursor>=t.gridSizes.length)return t.widthCursor++,t.gridSizes=[],t.gridSizeCursor=0,void(t.offsetCursor=0);if(t.offsetCursor>=kJ.length)return t.gridSizeCursor++,void(t.offsetCursor=0);const o=this.traces[t.traceIndex],i=o.route[t.startIndex],r=o.route[t.endIndex];if(!DJ(i)||!DJ(r))return this.viaGridAttempt=null,this.routeCursor++,void(this.phase=this.resumePhase);const s=t.gridSizes[t.gridSizeCursor],a=kJ[t.offsetCursor];this.attemptedViaGridCount++,this.activeSubSolver=new Qq({start:i,end:r,layer:t.layer,traceWidth:e,gridSize:s,gridOffset:{x:a.x*s,y:a.y*s},connectionNames:this.getTraceConnectionNames(o),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:t.traceIndex,ignoreRouteRange:{start:Math.max(0,t.startIndex-1),end:Math.min(o.route.length-1,t.endIndex+1)},bounds:this.inputProblem.simpleRouteJson.bounds,obstacleClearance:n,searchPadding:Math.min(4,Math.max(2,Nq(i,r)/2,3*e)),requireOctilinear:!0})}finishViaGridSolver(t){const e=this.viaGridAttempt;if(this.activeSubSolver=null,t.solved&&e){const n=t.getOutput(),o=this.traces[e.traceIndex];if(n&&o){const t=this.resolveNominalTraceWidth(o),i=this.measureCandidate(n.points,n.traceWidth,t,o.route[e.endIndex].width,o.route[e.startIndex].width);if(0===i.nonOctilinearSegmentCount&&i.length<=this.maxRerouteLength+Mq&&i.deficitArea<=e.originalQuality.deficitArea+Mq&&i.conservativeDeficitArea<=e.originalQuality.conservativeDeficitArea+Mq&&this.preservesCoverage(i,e.originalQuality)){const t={kind:e.kind,traceIndex:e.traceIndex,startIndex:e.startIndex,endIndex:e.endIndex,layer:e.layer,points:n.points,width:n.traceWidth,padClearance:e.padClearances[e.padClearanceCursor],originalQuality:e.originalQuality};return this.viaGridAttempt=null,void this.beginCandidates([t],this.resumePhase,!1)}}}t.failed&&(this.failedSubSolvers??=[],this.failedSubSolvers.push(t)),e&&e.offsetCursor++,this.phase="route-via-pair"}measureRouteRange(t,e,n){const o=this.resolveNominalTraceWidth(t);let i=0,r=0,s=0,a=0,c=0,l=0,d=0;for(let h=e;h<=n;h++){if(DJ(t.route[h])&&d++,h>=n)continue;const e=t.route[h],u=t.route[h+1];if(!DJ(e)||!DJ(u)||e.layer!==u.layer)continue;const p=Nq(e,u);i+=p,r+=p*Math.max(0,o-e.width),e.width>=o-Mq&&(a+=p),s+=p*Math.max(0,o-Math.min(e.width,u.width)),Math.min(e.width,u.width)>=o-Mq&&(c+=p),l+=Gq([e,u])}return{length:i,deficitArea:r,conservativeDeficitArea:s,nominalLength:a,conservativeNominalLength:c,nonOctilinearSegmentCount:l,pointCount:d}}measureTraceLength(t){let e=0;for(let n=0;n<t.route.length-1;n++){const o=t.route[n],i=t.route[n+1];DJ(o)&&DJ(i)&&o.layer===i.layer&&(e+=Nq(o,i))}return e}measureCandidate(t,e,n,o=e,i=e){const r=Uq(t);let s=0,a=0,c=0,l=0;for(let r=0;r<t.length-1;r++){const d=Nq(t[r],t[r+1]),h=0===r?i:e,u=r===t.length-2?o:e,p=Math.min(h,u);s+=d*Math.max(0,n-h),a+=d*Math.max(0,n-p),h>=n-Mq&&(c+=d),p>=n-Mq&&(l+=d)}return{length:r,deficitArea:s,conservativeDeficitArea:a,nominalLength:c,conservativeNominalLength:l,nonOctilinearSegmentCount:Gq(t),pointCount:t.length}}preservesCoverage(t,e){const n=e.length<=Mq?1:e.nominalLength/e.length,o=t.length<=Mq?1:t.nominalLength/t.length,i=e.length<=Mq?1:e.conservativeNominalLength/e.length,r=t.length<=Mq?1:t.conservativeNominalLength/t.length;return!(o+Mq<n||r+Mq<i)&&!(t.length>e.length+Mq&&o<.999999)}advanceTrace(){this.traceCursor++,this.routeCursor=0,this.rebuildObstacleIndex()}createObstacleIndex(){return new tJ(this.inputProblem.simpleRouteJson,this.traces,"repair-vias"===this.phase?void 0:this.traceIndices?.[this.traceCursor],[],this.connectionNameResolver)}rebuildObstacleIndex(){this.obstacleIndex=this.createObstacleIndex()}resolveNominalTraceWidth(t){const e=this.findConnectionForTrace(t);return Math.max(e?.nominalTraceWidth??e?.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.inputProblem.simpleRouteJson.minTraceWidth,this.inputProblem.simpleRouteJson.minTraceWidth)}getPadClearanceForTrace(t){const e=this.getBaseObstacleClearance();return this.resolveNominalTraceWidth(t)>=.499999?Math.max(e,this.desiredPadClearance??this.resolveNominalTraceWidth(t)/2):e}getBaseObstacleClearance(){return Math.max(this.inputProblem.simpleRouteJson.defaultObstacleMargin??0,this.inputProblem.simpleRouteJson.minTraceToPadEdgeClearance??0,.1)}getCandidatePadClearance(t,e,n,o){const i=this.traces[e],r=this.getBaseObstacleClearance(),s=this.getPadClearanceForTrace(i);if("pad-clearance"===t)return s;const a="via-pair"===t?Math.min(s,Math.max(r,.15)):s;return this.findExistingPadClearance(e,n,o,r,a)}getImprovedPadClearanceTiers(t,e,n){const o=this.traces[t],i=this.getBaseObstacleClearance(),r=this.getPadClearanceForTrace(o),s=this.findExistingPadClearance(t,e,n,i,r),a=Math.max(.025,Math.min(.05,r/10)),c=[r];for(let t=r-a;t>s+a/2;t-=a)c.push(t);return BJ(c).filter(t=>t>s+Mq)}findExistingPadClearance(t,e,n,o,i){if(this.routeRangeHasPadClearanceViolation(t,e,n,o))return o;if(!this.routeRangeHasPadClearanceViolation(t,e,n,i))return i;let r=o,s=i;for(let o=0;o<7;o++){const o=(r+s)/2;this.routeRangeHasPadClearanceViolation(t,e,n,o)?s=o:r=o}return Math.max(o,Number((r-.001).toFixed(6)))}routeRangeHasPadClearanceViolation(t,e,n,o){const i=this.traces[t],r=this.getTraceConnectionNames(i);for(let s=e;s<n;s++){const a=i.route[s],c=i.route[s+1];if(!DJ(a)||!DJ(c)||a.layer!==c.layer)continue;if(this.obstacleIndex.findCollisions({start:a,end:c,layer:a.layer,width:Math.max(a.width,c.width),connectionNames:r,ignoreTraceIndex:t,ignoreRouteRange:{start:Math.max(0,e-1),end:Math.min(i.route.length-1,n+1)},obstacleClearance:o}).some(t=>"obstacle"===t.kind&&"pad"===t.obstacleKind))return!0}return!1}countPadClearanceViolations(t){let e=0;for(const n of this.traceIndices){const o=this.traces[n];if(!o)continue;const i=this.getTraceConnectionNames(o);for(let r=0;r<o.route.length-1;r++){const s=o.route[r],a=o.route[r+1];if(!DJ(s)||!DJ(a)||s.layer!==a.layer)continue;this.obstacleIndex.findCollisions({start:s,end:a,layer:s.layer,width:Math.max(s.width,a.width),connectionNames:i,ignoreTraceIndex:n,ignoreRouteRange:{start:Math.max(0,r-1),end:Math.min(o.route.length-1,r+2)},obstacleClearance:t??this.getPadClearanceForTrace(o)}).some(t=>"obstacle"===t.kind&&"pad"===t.obstacleKind)&&e++}}return e}countPadClearanceViolationsByTier(){return Object.fromEntries(LJ.map(t=>[t.toFixed(2),this.countPadClearanceViolations(t)]))}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=new Set(this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t))),o=this.inputProblem.simpleRouteJson.connections.find(t=>this.connectionNameResolver.canonicalize(this.getConnectionNames(t)).some(t=>n.has(t)))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getConnectionNames(t){return[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=>Boolean(t))}getTraceConnectionNames(t){return[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=>Boolean(t))}ensureConnectivitySafeOutput(){if(!this.connectivityFinalized){this.connectivityFinalized=!0,this.connectivityValidationCount++;try{const t=this.connectivityInvariant.validate(this.traces);if(this.connectivityValidationError??=t.validationError??null,t.safe)return void(this.finalizedMutatedTraceIndices=this.getMutatedTraceIndices());this.connectivityRegressionEndpointIds=[...new Set(t.regressions.flatMap(t=>t.baselineEndpointLabels))]}catch(t){this.connectivityValidationError=t instanceof Error?t.message:String(t)}this.connectivityRollbackCount++,this.connectivityRollbackMutationStats={committedClearanceShoveCount:this.committedClearanceShoveCount,viaPairCountRemoved:this.viaPairCountRemoved,viaCountRemoved:this.viaCountRemoved,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,achievedExtraClearanceCount:this.achievedExtraClearanceCount,relocatedViaCount:this.relocatedViaCount,committedPushedViaRepairCount:this.committedPushedViaRepairCount,padClearanceRerouteCount:this.padClearanceRerouteCount},this.committedClearanceShoveCount=0,this.viaPairCountRemoved=0,this.viaCountRemoved=0,this.simplifiedPathCount=0,this.normalizedSegmentCount=0,this.achievedExtraClearanceCount=0,this.relocatedViaCount=0,this.committedPushedViaRepairCount=0,this.padClearanceRerouteCount=0,this.traces=structuredClone(this.initialConnectivitySafeTraces),this.obstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,void 0,[],this.connectionNameResolver),this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.finalizedMutatedTraceIndices=this.getMutatedTraceIndices()}}getMutatedTraceIndices(){const t=Math.max(this.initialConnectivitySafeTraces.length,this.traces.length);return Array.from({length:t},(t,e)=>e).filter(t=>JSON.stringify(this.initialConnectivitySafeTraces[t])!==JSON.stringify(this.traces[t]))}createStats(){const t=this.candidates[this.candidateCursor],e="repair-vias"===this.phase?this.viaRepairTraceIndices:this.traceIndices;return{phase:this.phase,budgetLimited:this.budgetLimited,completionReason:"complete"===this.phase||this.solved?this.connectivityRollbackCount>0?"connectivity_rollback":this.budgetLimited?"iteration_budget":this.connectivityValidationError?"connectivity_validation_unavailable":"completed":null,resultStatus:this.connectivityRollbackCount>0||this.budgetLimited||null!==this.connectivityValidationError?"best_effort":"complete",traceCursor:this.traceCursor,traceCount:e.length,traceIndex:e[this.traceCursor],routeCursor:this.routeCursor,candidateCursor:this.candidateCursor,candidateCount:this.candidates.length,candidateKind:t?.kind,candidateWidth:t?.width,candidatePointCount:t?.points.length,clearancePadding:this.clearancePaddingTiers[this.clearanceTierCursor],candidateShoveCount:this.candidateShoveCount,attemptedCandidateCount:this.attemptedCandidateCount,attemptedClearanceShoveCount:this.attemptedClearanceShoveCount,attemptedViaGridCount:this.attemptedViaGridCount,committedClearanceShoveCount:this.committedClearanceShoveCount,viaPairCountRemoved:this.viaPairCountRemoved,viaCountRemoved:this.viaCountRemoved,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,achievedExtraClearanceCount:this.achievedExtraClearanceCount,relocatedViaCount:this.relocatedViaCount,unresolvedViaCount:this.unresolvedViaCount,attemptedPushedViaRepairCount:this.attemptedPushedViaRepairCount,committedPushedViaRepairCount:this.committedPushedViaRepairCount,padClearanceRerouteCount:this.padClearanceRerouteCount,unresolvedPadClearanceCount:this.unresolvedPadClearanceCount,initialPadClearanceViolationCount:this.initialPadClearanceViolationCount,remainingPadClearanceViolationCount:this.remainingPadClearanceViolationCount,initialPadClearanceViolationCountByClearance:{...this.initialPadClearanceViolationCountByClearance},remainingPadClearanceViolationCountByClearance:{...this.remainingPadClearanceViolationCountByClearance},connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},mutatedTraceIndices:[...this.finalizedMutatedTraceIndices],spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){if(this.solved||"complete"===this.phase)return 1;const t="repair-vias"===this.phase?this.viaRepairTraceIndices:this.traceIndices;if(0===t.length)return 1;const e="scan-via-pairs"===this.resumePhase?0:.5;return Math.min(.99,e+this.traceCursor/t.length*.5)}getConstructorParams(){return[this.inputProblem]}tryFinalAcceptance(){const t=this.pushedViaRepairRollbackTraces??this.rollbackTraces;t&&(this.traces=t),this.activeSubSolver=null,this.rollbackTraces=null,this.pushedViaRepairRollbackTraces=null,this.pendingPushedViaRepair=null,this.alternatePushedViaRepairs=[],this.viaGridAttempt=null,this.candidates=[],this.candidateCursor=0,this.clearanceTierCursor=0,this.candidateShoveCount=0,this.baseCandidateValidated=!1,this.candidateSetMayUseGridFallback=!1,this.ensureConnectivitySafeOutput(),this.obstacleIndex=new tJ(this.inputProblem.simpleRouteJson,this.traces,void 0,[],this.connectionNameResolver),this.remainingPadClearanceViolationCount=this.countPadClearanceViolations(),this.remainingPadClearanceViolationCountByClearance=this.countPadClearanceViolationsByTier(),this.budgetLimited=!0,this.phase="complete",this.solved=!0,this.progress=1,this.stats=this.createStats()}getOutput(){return structuredClone(this.solved?this.traces:this.initialConnectivitySafeTraces)}visualize(){const t=[],e=[],n=this.candidates[this.candidateCursor];for(let n=0;n<this.traces.length;n++){const o=this.traces[n];for(const t of o.route)"via"===t.route_type&&e.push({center:t,radius:(t.via_diameter??.6)/2,fill:"#d4a017",stroke:"#7a5700"});for(let e=0;e<o.route.length-1;e++){const n=o.route[e],i=o.route[e+1];DJ(n)&&DJ(i)&&n.layer===i.layer&&t.push({points:[n,i],strokeColor:"bottom"===n.layer?"#376fc4":"#777",strokeWidth:n.width})}}if(n)for(let e=0;e<n.points.length-1;e++)t.push({points:[n.points[e],n.points[e+1]],strokeColor:"#ff7400",strokeWidth:n.width+2*(this.clearancePaddingTiers[this.clearanceTierCursor]??0)});return{coordinateSystem:"cartesian",title:`Power trace cleanup: ${this.phase}`,lines:t,points:[],circles:e,rects:[],texts:[]}}},$J=t=>"wire"===t?.route_type,YJ=class extends Sq{inputProblem;traces;obstacleIndex;traceCursor=0;routeCursor=0;repairedSegmentCount=0;repairedPadNeckSegmentCount=0;unresolvedSegmentCount=0;totalWidthReduction=0;budgetLimited=!1;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;connectionNameResolver;nominalWidthByTraceId=new Map;connectivityInvariant;initialConnectivitySafeTraces;minimumTraceWidth;traceIndices;connectivityFinalized=!1;constructor(t){super(),this.inputProblem=structuredClone(t),this.traces=structuredClone(t.traces),this.initialConnectivitySafeTraces=structuredClone(t.traces),this.connectivityInvariant=new OJ(this.inputProblem.simpleRouteJson,this.initialConnectivitySafeTraces),this.connectionNameResolver=new Pq(t.simpleRouteJson,this.traces),this.minimumTraceWidth=t.simpleRouteJson.minTraceWidth;const e=t.traceIndices?[...new Set(t.traceIndices)]:this.traces.map((t,e)=>e);for(const t of e)if(!Number.isInteger(t)||t<0||t>=this.traces.length)throw new RangeError(`Invalid clearance-repair trace index: ${t}`);this.traceIndices=e,this.obstacleIndex=this.createConservativeObstacleIndex();const n=this.traceIndices.reduce((t,e)=>t+Math.max(0,this.traces[e].route.length-1),0);this.MAX_ITERATIONS=Math.max(10,8*n+2*this.traceIndices.length),this.stats=this.createStats()}getSolverName(){return"PowerTraceClearanceRepairSolver"}_step(){const t=this.traceIndices[this.traceCursor],e=void 0===t?void 0:this.traces[t];if(!e)return this.ensureConnectivitySafeOutput(),this.solved=!0,void(this.stats=this.createStats());if(this.routeCursor>=e.route.length-1)return this.traceCursor++,this.routeCursor=0,void(this.stats=this.createStats());const n=this.routeCursor++,o=e.route[n],i=e.route[n+1];if(!$J(o)||!$J(i)||o.layer!==i.layer)return void(this.stats=this.createStats());const r=Math.max(o.width,i.width),s={start:o,end:i,layer:o.layer,width:r,connectionNames:this.getTraceConnectionNames(e),ignoreTraceIndex:t,ignoreRouteRange:{start:n,end:n+1}};if(this.repairConnectedPadNeck(e,n,s))return void(this.stats=this.createStats());if(!this.segmentHasForeignTraceCollision(n,r))return void(this.stats=this.createStats());if(this.segmentHasForeignTraceCollision(n,this.minimumTraceWidth))return this.unresolvedSegmentCount++,void(this.stats=this.createStats());let a=this.minimumTraceWidth,c=r;for(let t=0;t<10;t++){const t=(a+c)/2;this.segmentHasForeignTraceCollision(n,t)?c=t:a=t}const l=r>=.5?.025:.0125,d=Math.max(this.minimumTraceWidth,Math.floor((a+Mq)/l)*l),h=this.segmentHasForeignTraceCollision(n,d)?a:d,u=o.width,p=i.width;o.width=Math.min(o.width,h),i.width=Math.min(i.width,h);const m=u-o.width+(p-i.width);if(m<=Mq)return this.unresolvedSegmentCount++,void(this.stats=this.createStats());this.repairedSegmentCount++,this.totalWidthReduction+=m,this.obstacleIndex=this.createConservativeObstacleIndex(),this.routeCursor=Math.max(0,n-1),this.stats=this.createStats()}repairConnectedPadNeck(t,e,n){const o=t.route[e],i=t.route[e+1];if(!$J(o)||!$J(i))return!1;let r=this.obstacleIndex.getConnectedPadWidthLimitAtPoint(n,o),s=this.obstacleIndex.getConnectedPadWidthLimitAtPoint(n,i);0===e&&(r=this.getSmallerLimit(r,this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(n,o))),e+1===t.route.length-1&&(s=this.getSmallerLimit(s,this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(n,i)));const a=r,c=s;if((null===a||o.width<=a+Mq)&&(null===c||i.width<=c+Mq))return!1;const l=o.width,d=i.width;if(null!==a&&(o.width=Math.min(o.width,a)),null!==c&&(i.width=Math.min(i.width,c)),null!==a&&null===c)this.insertPadBoundaryTransition(t,e,n,"start",o.width,d);else if(null===a&&null!==c)this.insertPadBoundaryTransition(t,e,n,"end",i.width,l);else if(null!==a&&null!==c){const r=this.obstacleIndex.getConnectedPadBoundaryPoint(n,"start"),s=this.obstacleIndex.getConnectedPadBoundaryPoint(n,"end");r&&s&&(this.insertPadBoundaryTransition(t,e,n,"start",o.width,d),this.insertPadBoundaryTransition(t,e+2,n,"end",i.width,l))}return this.totalWidthReduction+=l-o.width+(d-i.width),this.repairedPadNeckSegmentCount++,this.obstacleIndex=this.createConservativeObstacleIndex(),this.routeCursor=Math.max(0,e-1),!0}getSmallerLimit(t,e){return null===t?e:null===e?t:Math.min(t,e)}insertPadBoundaryTransition(t,e,n,o,i,r){const s=this.obstacleIndex.getConnectedPadBoundaryPoint(n,o);if(!s)return;const a="start"===o?n.start:n.end,c="start"===o?n.end:n.start,l=Math.hypot(c.x-a.x,c.y-a.y);if(l<=1e-9)return;const d=Math.min(1e-6,l/4),h=(c.x-a.x)/l,u=(c.y-a.y)/l,p={route_type:"wire",x:s.x-h*d,y:s.y-u*d,width:i,layer:n.layer},m={...p,x:s.x+h*d,y:s.y+u*d,width:r},g="start"===o?t.route[e+1]:t.route[e],f="start"===o?t.route[e+2]:t.route[e-1];if($J(g)&&"via"===f?.route_type){const e=this.resolveNominalTraceWidth(t);this.obstacleIndex.collides({...n,start:g,end:m,width:e})||(g.width=Math.max(g.width,e),m.width=g.width)}t.route.splice(e+1,0,..."start"===o?[p,m]:[m,p])}resolveNominalTraceWidth(t){const e=this.nominalWidthByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e;const n=new Set(this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t))),o=this.inputProblem.simpleRouteJson.connections.find(t=>this.connectionNameResolver.canonicalize([t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=>Boolean(t))).some(t=>n.has(t))),i=Math.max(o?.nominalTraceWidth??o?.width??this.inputProblem.simpleRouteJson.nominalTraceWidth??this.minimumTraceWidth,this.minimumTraceWidth);return this.nominalWidthByTraceId.set(t.pcb_trace_id,i),i}segmentHasForeignTraceCollision(t,e){const n=this.traceIndices[this.traceCursor],o=void 0===n?void 0:this.traces[n],i=o?.route[t],r=o?.route[t+1];return!!(o&&$J(i)&&$J(r)&&i.layer===r.layer)&&this.obstacleIndex.findCollisions({start:i,end:r,layer:i.layer,width:e,connectionNames:this.getTraceConnectionNames(o),ignoreTraceIndex:n,ignoreRouteRange:{start:t,end:t+1}}).some(t=>"trace"===t.kind&&void 0!==t.traceIndex&&t.traceIndex!==n)}createConservativeObstacleIndex(){const t=structuredClone(this.traces);for(const e of t)for(let t=0;t<e.route.length-1;t++){const n=e.route[t],o=e.route[t+1];$J(n)&&$J(o)&&n.layer===o.layer&&(n.width=Math.max(n.width,o.width))}return new tJ(this.inputProblem.simpleRouteJson,t,void 0,[],this.connectionNameResolver)}getTraceConnectionNames(t){return[t.pcb_trace_id,t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[],...t.connectsTo??[]].filter(t=>Boolean(t))}ensureConnectivitySafeOutput(){if(!this.connectivityFinalized){this.connectivityFinalized=!0,this.connectivityValidationCount++;try{const t=this.connectivityInvariant.validate(this.traces);if(this.connectivityValidationError??=t.validationError??null,t.safe)return;this.connectivityRegressionEndpointIds=[...new Set(t.regressions.flatMap(t=>t.baselineEndpointLabels))]}catch(t){this.connectivityValidationError=t instanceof Error?t.message:String(t)}this.connectivityRollbackCount++,this.connectivityRollbackMutationStats={repairedSegmentCount:this.repairedSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,totalWidthReduction:this.totalWidthReduction},this.repairedSegmentCount=0,this.repairedPadNeckSegmentCount=0,this.totalWidthReduction=0,this.traces=structuredClone(this.initialConnectivitySafeTraces),this.obstacleIndex=this.createConservativeObstacleIndex()}}createStats(){return{phase:this.solved?"complete":"repair-trace-clearance",budgetLimited:this.budgetLimited,completionReason:this.solved?this.connectivityRollbackCount>0?"connectivity_rollback":this.budgetLimited?"iteration_budget":this.connectivityValidationError?"connectivity_validation_unavailable":"completed":null,resultStatus:this.connectivityRollbackCount>0||this.budgetLimited||null!==this.connectivityValidationError?"best_effort":"complete",traceCursor:this.traceCursor,traceCount:this.traceIndices.length,traceIndex:this.traceIndices[this.traceCursor],routeCursor:this.routeCursor,repairedSegmentCount:this.repairedSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,unresolvedSegmentCount:this.unresolvedSegmentCount,totalWidthReduction:this.totalWidthReduction,connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){return this.solved||0===this.traceIndices.length?1:Math.min(.99,this.traceCursor/this.traceIndices.length)}tryFinalAcceptance(){this.ensureConnectivitySafeOutput(),this.budgetLimited=!0,this.solved=!0,this.progress=1,this.stats=this.createStats()}getConstructorParams(){return[this.inputProblem]}getOutput(){return structuredClone(this.solved?this.traces:this.initialConnectivitySafeTraces)}visualize(){const t=[];for(let e=0;e<this.traces.length;e++){const n=this.traces[e];for(let o=0;o<n.route.length-1;o++){const i=n.route[o],r=n.route[o+1];$J(i)&&$J(r)&&i.layer===r.layer&&t.push({points:[i,r],strokeColor:e===this.traceIndices[this.traceCursor]&&o===this.routeCursor?"#ff7400":"bottom"===i.layer?"#376fc4":"#777",strokeWidth:Math.max(i.width,r.width)})}}return{coordinateSystem:"cartesian",title:"Power trace direction-independent clearance repair",lines:t,points:[],circles:[],rects:[],texts:[]}}},XJ=[{x:0,y:0},{x:.5,y:0},{x:0,y:.5},{x:.5,y:.5}],VJ=[{offset:{x:0,y:0},strictNecking:!0},{offset:{x:.5,y:.5},strictNecking:!0},{offset:{x:0,y:0},strictNecking:!1},{offset:{x:.5,y:.5},strictNecking:!1}],WJ=t=>[...new Set(t.map(t=>Number(t.toFixed(6))))].sort((t,e)=>e-t),HJ=t=>"wire"===t?.route_type,GJ=class extends Sq{inputProblem;options;traces;obstacleIndex;connectionNameResolver;connectionByTraceId=new Map;connectivityInvariant;lastConnectivitySafeTraces;traceOrder;selectedOwnedTraceIndices;selectedCleanupTraceIndices;selectedViaRepairTraceIndices;mutableBlockerTraceIndices;immutableTraceIndices;initialImmutableTraceSignatures=new Map;traceOrderCursor=-1;maxPassCount=4;previousWidthDeficit=0;passIndex=0;completedPassCount=0;lastNormalizedWidthDeficitGain=0;normalizedWidthDeficitGainByPass=[];plateauReached=!1;phase="scan-trace";traceIndex=-1;routeSegmentIndex=0;nominalTraceWidth=0;currentIntervals=[];intervalCursor=0;candidateWidths=[];widthCursor=0;gridResolutions=[];resolutionCursor=0;offsetCursor=0;keptTraceCount=0;recreatedTraceCount=0;expandedSegmentCount=0;intermediateExpandedSegmentCount=0;pathWidthUpgradeCount=0;inPlaceWidthProbeCount=0;reroutedSegmentCount=0;unresolvedSegmentCount=0;attemptedGridCount=0;attemptedLayerGridCount=0;attemptedInflationCount=0;pushedTraceCount=0;elasticPushedTraceCount=0;layerReroutedTraceCount=0;insertedViaCount=0;neckedLayerSegmentCount=0;removedViaPairCount=0;removedViaCount=0;simplifiedPathCount=0;normalizedSegmentCount=0;cleanupClearanceShoveCount=0;relocatedViaCount=0;unresolvedViaCount=0;initialImmutableViaViolationCount=0;remainingImmutableViaViolationCount=0;initialImmutableViaViolationPairCount=0;remainingImmutableViaViolationPairCount=0;immutableTraceMutationIds=[];lastSafeImmutableViaViolationSignatures=new Set;immutableViaViolationRollbackCount=0;attemptedImmutableViaViolationCount=null;attemptedImmutableViaViolationPairCount=null;immutableViaViolationRegressionIds=[];padClearanceRerouteCount=0;unresolvedPadClearanceCount=0;repairedTraceClearanceSegmentCount=0;repairedPadNeckSegmentCount=0;unresolvedTraceClearanceSegmentCount=0;sameNetContactRejectionCount=0;connectivityValidationCount=0;connectivityRollbackCount=0;connectivityRollbackPhases=[];immutableSafetyRollbackCount=0;immutableSafetyRollbackPhases=[];connectivityRegressionEndpointIds=[];connectivityValidationError=null;connectivityRollbackMutationStats=null;immutableSafetyRollbackMutationStats=null;discardedExpansionMutationStats=null;initialPadClearanceViolationCount=0;remainingPadClearanceViolationCount=0;initialPadClearanceViolationCountByClearance={};remainingPadClearanceViolationCountByClearance={};budgetLimitedExpansion=!1;finalAcceptanceUsed=!1;cleanupCompleted=!1;clearanceRepairCompleted=!1;cleanupBestEffortAccepted=!1;clearanceRepairBestEffortAccepted=!1;cleanupIterationBudget=0;clearanceRepairIterationBudget=0;expansionPushedTraceIndices=new Set;cleanupMutatedTraceIndices=[];failedSubSolverCount=0;inflationAttemptsBySegment=new Map;layerAttemptCountByTrace=new Map;layerRerouteCountByTrace=new Map;activeInflationKey=null;activeInflationWidth=null;layerAttempt=null;pendingLayerOutput=null;pendingLayerPushCount=0;constructor(t,e={}){super(),this.inputProblem=structuredClone(t),this.options=structuredClone(e),this.traces=structuredClone(t.traces??[]),this.connectionNameResolver=new Pq(this.inputProblem,this.traces),this.lastConnectivitySafeTraces=structuredClone(this.traces),this.connectivityInvariant=new OJ(this.inputProblem,this.lastConnectivitySafeTraces);const n=e.onlyConnectionNames?new Set(this.connectionNameResolver.canonicalize([...e.onlyConnectionNames])):null,o=this.traces.flatMap((t,e)=>{if(!n)return[e];return this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(t)).some(t=>n.has(t))?[e]:[]}),i=new Map(o.map(t=>[t,this.getInitialTracePriority(this.traces[t])]));this.traceOrder=o.sort((t,e)=>i.get(e)-i.get(t)||t-e),this.selectedOwnedTraceIndices=this.traceOrder.filter(t=>this.findConnectionForTrace(this.traces[t])),this.selectedCleanupTraceIndices=[...this.selectedOwnedTraceIndices],this.selectedViaRepairTraceIndices=[...this.selectedOwnedTraceIndices],this.mutableBlockerTraceIndices=this.traces.flatMap((t,e)=>this.findConnectionForTrace(t)?[e]:[]);const r=new Set(this.mutableBlockerTraceIndices);this.immutableTraceIndices=this.traces.flatMap((t,e)=>r.has(e)?[]:(this.initialImmutableTraceSignatures.set(e,JSON.stringify(t)),[e])),this.previousWidthDeficit=this.calculateWidthDeficit().deficit,this.obstacleIndex=new tJ(this.inputProblem,this.traces,this.traceIndex>=0?this.traceIndex:void 0,[],this.connectionNameResolver),this.lastSafeImmutableViaViolationSignatures=this.getImmutableViaViolationSignatures(this.traces),this.initialImmutableViaViolationCount=this.countViolatingImmutableVias(this.lastSafeImmutableViaViolationSignatures),this.remainingImmutableViaViolationCount=this.initialImmutableViaViolationCount,this.initialImmutableViaViolationPairCount=this.lastSafeImmutableViaViolationSignatures.size,this.remainingImmutableViaViolationPairCount=this.initialImmutableViaViolationPairCount,this.activeSubSolver=null,this.MAX_ITERATIONS=8e6,this.stats=this.createStats()}getSolverName(){return"PowerTraceExpanderSolver"}_step(){if(this.shouldStartBudgetFinalization())return this.startBudgetFinalization(),void(this.stats=this.createStats());if(this.activeSubSolver)return this.stepActiveGridSolver(),void(this.stats=this.createStats());switch(this.phase){case"scan-trace":this.scanNextTrace();break;case"evaluate-segment":this.evaluateNextSegment();break;case"try-trace-inflation":case"cleanup":case"repair-trace-clearance":break;case"try-layer-candidate":this.startNextLayerCandidate();break;case"try-grid-candidate":this.startNextGridCandidate();break;case"complete":this.acceptConnectivityCheckpoint(this.traces,"final"),this.solved=!0}this.stats=this.createStats()}scanNextTrace(){if(this.traceOrderCursor++,this.routeSegmentIndex=0,this.traceOrderCursor>=this.traceOrder.length)return void this.finishOrStartNextPass();this.traceIndex=this.traceOrder[this.traceOrderCursor];const t=this.traces[this.traceIndex];this.findConnectionForTrace(t)?(this.nominalTraceWidth=this.resolveNominalTraceWidth(t),this.traceMeetsNominalWidth(t,this.nominalTraceWidth)?this.keptTraceCount++:(this.rebuildObstacleIndex(),t.route=function(t,e){if(t.length<2)return t.map(t=>({...t}));const n=[];for(let o=0;o<t.length-1;o++){const i=t[o],r=t[o+1];if(n.push({...i}),"wire"!==i.route_type||"wire"!==r.route_type||i.layer!==r.layer||i.width>=e-Mq)continue;const s=Nq(i,r),a=Math.max(1,Math.ceil(s/e));for(let t=1;t<a;t++){const e=t/a;n.push({route_type:"wire",x:i.x+(r.x-i.x)*e,y:i.y+(r.y-i.y)*e,width:i.width,layer:i.layer})}}return n.push({...t[t.length-1]}),n}(t.route,this.nominalTraceWidth),this.recreatedTraceCount++,this.phase="evaluate-segment")):this.keptTraceCount++}finishOrStartNextPass(){const{deficit:t,nominalArea:e}=this.calculateWidthDeficit(),n=this.previousWidthDeficit-t;if(this.lastNormalizedWidthDeficitGain=e<=Mq?0:n/e,this.normalizedWidthDeficitGainByPass.push(this.lastNormalizedWidthDeficitGain),this.plateauReached=this.lastNormalizedWidthDeficitGain<.001,this.completedPassCount=this.passIndex+1,this.passIndex+1<this.maxPassCount&&this.lastNormalizedWidthDeficitGain>=.001)return this.previousWidthDeficit=t,this.passIndex++,this.traceOrderCursor=-1,this.traceIndex=-1,this.routeSegmentIndex=0,this.inflationAttemptsBySegment.clear(),void(this.phase="scan-trace");this.startCleanup()}startCleanup(){this.acceptConnectivityCheckpoint(this.traces,"expansion"),this.traceIndex=this.traces.length,this.phase="cleanup";const t=new jJ({simpleRouteJson:this.inputProblem,traces:this.traces,traceIndices:this.selectedCleanupTraceIndices,viaRepairTraceIndices:this.selectedViaRepairTraceIndices,mutableTraceIndices:this.mutableBlockerTraceIndices,maxRerouteLength:10,desiredPadClearance:this.options.powerTraceToPadClearance}),e=this.getRemainingParentIterationsAfterCurrentStep(),n=0===e?0:Math.max(1,Math.floor(.75*e));t.MAX_ITERATIONS=Math.min(t.MAX_ITERATIONS,n),this.cleanupIterationBudget=t.MAX_ITERATIONS,this.activeSubSolver=t}shouldStartBudgetFinalization(){return!this.budgetLimitedExpansion&&("cleanup"!==this.phase&&"repair-trace-clearance"!==this.phase&&"complete"!==this.phase&&this.iterations>=this.getExpansionIterationBudget())}getFinalizationIterationReserve(){return Math.min(Math.max(0,this.MAX_ITERATIONS-1),Math.max(1,Math.floor(.125*this.MAX_ITERATIONS)))}getExpansionIterationBudget(){return Math.max(1,this.MAX_ITERATIONS-this.getFinalizationIterationReserve())}startBudgetFinalization(){this.budgetLimitedExpansion=!0,this.activeSubSolver=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.activeInflationKey=null,this.activeInflationWidth=null,this.layerAttempt=null,this.discardInFlightExpansion(),this.startCleanup()}discardInFlightExpansion(){this.discardedExpansionMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}rollbackConnectivityRegressedExpansion(){this.connectivityRollbackMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}rollbackImmutableUnsafeExpansion(){this.immutableSafetyRollbackMutationStats=this.captureAndResetExpansionMutationStats(),this.restoreLastConnectivitySafeTraces()}captureAndResetExpansionMutationStats(){const t={recreatedTraceCount:this.recreatedTraceCount,expandedSegmentCount:this.expandedSegmentCount,intermediateExpandedSegmentCount:this.intermediateExpandedSegmentCount,pathWidthUpgradeCount:this.pathWidthUpgradeCount,reroutedSegmentCount:this.reroutedSegmentCount,pushedTraceCount:this.pushedTraceCount,elasticPushedTraceCount:this.elasticPushedTraceCount,layerReroutedTraceCount:this.layerReroutedTraceCount,insertedViaCount:this.insertedViaCount,neckedLayerSegmentCount:this.neckedLayerSegmentCount};return this.recreatedTraceCount=0,this.expandedSegmentCount=0,this.intermediateExpandedSegmentCount=0,this.pathWidthUpgradeCount=0,this.reroutedSegmentCount=0,this.pushedTraceCount=0,this.elasticPushedTraceCount=0,this.layerReroutedTraceCount=0,this.insertedViaCount=0,this.neckedLayerSegmentCount=0,this.expansionPushedTraceIndices.clear(),t}restoreLastConnectivitySafeTraces(){this.traces=structuredClone(this.lastConnectivitySafeTraces),this.rebuildObstacleIndex()}getRemainingParentIterationsAfterCurrentStep(){return Math.max(0,this.MAX_ITERATIONS-this.iterations-1)}calculateWidthDeficit(){let t=0,e=0;for(const n of this.traceOrder){const o=this.traces[n];if(!this.findConnectionForTrace(o))continue;const i=this.resolveNominalTraceWidth(o);for(let n=0;n<o.route.length-1;n++){const r=o.route[n],s=o.route[n+1];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)continue;const a=Nq(r,s),c=r.width;e+=a*i,t+=a*Math.max(0,i-c)}}return{deficit:t,nominalArea:e}}getInitialTracePriority(t){const e=this.resolveNominalTraceWidth(t);let n=0;for(let o=0;o<t.route.length-1;o++){const i=t.route[o],r=t.route[o+1];HJ(i)&&HJ(r)&&i.layer===r.layer&&(n+=Nq(i,r)*Math.max(0,e-Math.min(i.width,r.width)))}return e*n}evaluateNextSegment(){const t=this.traces[this.traceIndex];if(!t)return void(this.phase="scan-trace");const e=this.findNextUnderWidthSegment(t,this.routeSegmentIndex,this.nominalTraceWidth);if(-1===e)return void(this.phase="scan-trace");this.routeSegmentIndex=e;const n=t.route[e],o=t.route[e+1];if(!HJ(n)||!HJ(o))return void this.routeSegmentIndex++;const i=this.getTraceConnectionNames(t),r=Math.min(n.width,o.width),s=this.findMaximumSafeInPlaceWidth(t,e,i);if(s>r+Mq){if(n.width=Math.max(n.width,s),o.width=Math.max(o.width,s),s>=this.nominalTraceWidth-Mq)return this.expandedSegmentCount++,void this.routeSegmentIndex++;this.intermediateExpandedSegmentCount++}this.startTraceInflation(t,e)||this.prepareLayerRouteAttempt(t,e)||this.prepareRegularGridCandidates(t,e)}prepareRegularGridCandidates(t,e){if(this.currentIntervals=this.getExponentialIntervalCandidates(t,e,this.nominalTraceWidth),this.intervalCursor=0,this.candidateWidths=this.getCandidateWidths(this.nominalTraceWidth),this.widthCursor=0,this.gridResolutions=[],this.resolutionCursor=0,this.offsetCursor=0,0===this.currentIntervals.length)return this.unresolvedSegmentCount++,void this.routeSegmentIndex++;this.phase="try-grid-candidate"}prepareLayerRouteAttempt(t,e){if(this.nominalTraceWidth<.499999)return!1;const n=!1!==this.options.allowNewVias&&this.inputProblem.layerCount>=2,o=n?2:this.maxPassCount,i=this.layerAttemptCountByTrace.get(this.traceIndex)??0,r=this.layerRerouteCountByTrace.get(this.traceIndex)??0;if(r>=o||i>=o||i>this.passIndex||i>0&&0===r)return!1;const s=t.route[e],a=t.route[e+1];if(!HJ(s)||!HJ(a)||Math.min(s.width,a.width)>=.5*this.nominalTraceWidth-Mq)return!1;const c=this.getExponentialIntervalCandidates(t,e,this.nominalTraceWidth).filter(e=>this.intervalSupportsLayerRouting(t,e)).sort((e,n)=>n.endIndex-e.endIndex||e.startIndex-n.startIndex||this.getRouteIntervalLength(t,n.startIndex,n.endIndex)-this.getRouteIntervalLength(t,e.startIndex,e.endIndex))[0];if(!c)return!1;const l=this.getRouteQuality(t.route.slice(c.startIndex,c.endIndex+1));if(l.deficitArea<this.nominalTraceWidth)return!1;if(i>0&&l.deficitArea/Math.max(l.length,Mq)<.25)return!1;const d=t.route[c.startIndex],h=t.route[c.endIndex],u=this.getTraceConnectionNames(t),p=n?this.getEndpointLayers(d,u):[d.layer],m=n?this.getEndpointLayers(h,u):[h.layer],g=Math.min(this.nominalTraceWidth,Math.max(d.width,this.findMaximumSafeInPlaceWidth(t,c.startIndex,u))),f=Math.min(this.nominalTraceWidth,Math.max(h.width,this.findMaximumSafeInPlaceWidth(t,c.endIndex-1,u))),y=this.getSoftTraceIndices(this.nominalTraceWidth);return this.layerAttemptCountByTrace.set(this.traceIndex,i+1),this.layerAttempt={interval:c,minViaCount:n?1:0,maxViaCount:n?2:0,candidateWidths:[this.nominalTraceWidth],widthCursor:0,gridResolutions:[Rq(this.nominalTraceWidth/4,.2,.3)],resolutionCursor:0,offsetCursor:0,startLayers:p,endLayers:m,startNeckWidth:g,endNeckWidth:f,softTraceIndices:y},this.phase="try-layer-candidate",!0}intervalSupportsLayerRouting(t,e){if(e.startIndex>=e.endIndex)return!1;for(let n=e.startIndex;n<=e.endIndex;n++){const e=t.route[n];if(!HJ(e))return!1}const n=t.route[e.startIndex],o=t.route[e.endIndex];return n.layer===o.layer}getEndpointLayers(t,e){return[...new Set([t.layer,...this.obstacleIndex.getConnectedLayersAtPoint({x:t.x,y:t.y},e)])].filter(t=>this.obstacleIndex.boardLayers.includes(t))}getSoftTraceIndices(t){const e=[];for(let n=0;n<this.traces.length;n++){if(n===this.traceIndex)continue;const o=this.traces[n],i=this.findConnectionForTrace(o);if(!i)continue;Math.max(i.nominalTraceWidth??i.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth,this.inputProblem.minTraceWidth)<t-Mq&&e.push(n)}return e}startNextLayerCandidate(){const t=this.layerAttempt,e=this.traces[this.traceIndex];if(!t||!e)return this.layerAttempt=null,void(this.phase="evaluate-segment");if(t.widthCursor>=t.candidateWidths.length){const t=this.routeSegmentIndex;return this.layerAttempt=null,void this.prepareRegularGridCandidates(e,t)}const n=t.candidateWidths[t.widthCursor];if(0===t.gridResolutions.length&&(t.gridResolutions=this.getGridResolutions(n)),t.resolutionCursor>=t.gridResolutions.length)return t.widthCursor++,t.gridResolutions=[],t.resolutionCursor=0,void(t.offsetCursor=0);if(t.offsetCursor>=VJ.length)return t.resolutionCursor++,void(t.offsetCursor=0);const o=e.route[t.interval.startIndex],i=e.route[t.interval.endIndex];if(!HJ(o)||!HJ(i))return this.layerAttempt=null,void this.prepareRegularGridCandidates(e,this.routeSegmentIndex);const r=t.gridResolutions[t.resolutionCursor],s=VJ[t.offsetCursor],a=s.offset,c=Math.min(t.startNeckWidth,t.endNeckWidth),l=this.inputProblem.min_via_hole_diameter??this.inputProblem.minViaHoleDiameter??.3,d=Math.max(l,this.inputProblem.min_via_pad_diameter??this.inputProblem.minViaPadDiameter??this.inputProblem.minViaDiameter??.6),h=Math.max(this.inputProblem.minTraceWidth,Math.min(s.strictNecking?t.startNeckWidth:c,n)),u=Math.max(this.inputProblem.minTraceWidth,Math.min(s.strictNecking?t.endNeckWidth:c,n)),p=Rq(3*this.nominalTraceWidth,1.5,3);t.maxViaCount>0?this.attemptedLayerGridCount++:this.attemptedGridCount++,this.activeSubSolver=new Yq({start:o,end:i,originalStartLayer:o.layer,originalEndLayer:i.layer,startLayers:t.startLayers,endLayers:t.endLayers,layers:this.obstacleIndex.boardLayers,traceWidth:n,startNeckWidth:h,endNeckWidth:u,maxStartNeckLength:p,maxEndNeckLength:p,neckPenaltyExponent:s.strictNecking?2:1,viaDiameter:d,viaHoleDiameter:l,minViaCount:t.minViaCount,maxViaCount:t.maxViaCount,viaCost:Math.max(1,2*this.nominalTraceWidth),gridSize:r,gridOffset:{x:a.x*r,y:a.y*r},connectionNames:this.getTraceConnectionNames(e),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,t.interval.startIndex-1),end:Math.min(e.route.length-1,t.interval.endIndex+1)},softTraceIndices:t.softTraceIndices,fixedVias:this.getFixedViasOutsideInterval(e,t.interval),bounds:this.inputProblem.bounds,obstacleClearance:this.getDesiredPadClearance(n),searchPadding:Math.min(5,Math.max(2.5,Nq(o,i)/2,4*n))})}startNextGridCandidate(){const t=this.traces[this.traceIndex];if(!t)return void(this.phase="scan-trace");if(this.widthCursor>=this.candidateWidths.length)return this.unresolvedSegmentCount++,this.routeSegmentIndex++,void(this.phase="evaluate-segment");if(this.intervalCursor>=this.currentIntervals.length)return this.widthCursor++,this.intervalCursor=0,this.gridResolutions=[],this.resolutionCursor=0,void(this.offsetCursor=0);const e=this.candidateWidths[this.widthCursor],n=t.route[this.routeSegmentIndex],o=t.route[this.routeSegmentIndex+1];if(HJ(n)&&HJ(o)&&e<=Math.min(n.width,o.width)+Mq)return void(this.widthCursor=this.candidateWidths.length);if(0===this.gridResolutions.length&&(this.gridResolutions=this.getGridResolutions(e)),this.resolutionCursor>=this.gridResolutions.length)return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);if(this.offsetCursor>=XJ.length)return this.resolutionCursor++,void(this.offsetCursor=0);const i=this.currentIntervals[this.intervalCursor],r=t.route[i.startIndex],s=t.route[i.endIndex];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);if(this.endpointCollides(t,i,r,e)||this.endpointCollides(t,i,s,e))return this.intervalCursor++,this.resolutionCursor=0,void(this.offsetCursor=0);const a=this.gridResolutions[this.resolutionCursor],c=XJ[this.offsetCursor],l={x:c.x*a,y:c.y*a};this.attemptedGridCount++,this.activeSubSolver=new Qq({start:r,end:s,layer:r.layer,traceWidth:e,gridSize:a,gridOffset:l,connectionNames:this.getTraceConnectionNames(t),obstacleIndex:this.obstacleIndex,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,i.startIndex-1),end:Math.min(t.route.length-1,i.endIndex+1)},bounds:this.inputProblem.bounds,obstacleClearance:this.getDesiredPadClearance(e),searchPadding:Math.min(5,Math.max(1.5,Nq(r,s)/2,3*e))})}endpointCollides(t,e,n,o){return this.obstacleIndex.collides({start:n,end:n,layer:n.layer,width:o,connectionNames:this.getTraceConnectionNames(t),ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,e.startIndex-1),end:Math.min(t.route.length-1,e.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(o)})}stepActiveGridSolver(){if(this.activeSubSolver instanceof YJ)return void this.stepActiveTraceClearanceRepairSolver();if(this.activeSubSolver instanceof jJ)return void this.stepActiveCleanupSolver();if(this.activeSubSolver instanceof oJ)return void this.stepActiveInflationSolver();if(this.activeSubSolver instanceof Yq)return void this.stepActiveLayerSolver();const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e){const t=this.gridRouteReplacementCollides(e)||this.gridRouteBoundaryCollides(e);if(!t&&this.gridRoutePreservesSameNetContacts(e))return this.applyGridRoute(this.maximizeGridRouteWidth(e)),void(this.activeSubSolver=null);t||this.sameNetContactRejectionCount++}}this.retainFailedSubSolver(t),this.activeSubSolver=null,this.offsetCursor++}}stepActiveCleanupSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved)return this.adoptCleanupOutput(t),this.activeSubSolver=null,void this.startTraceClearanceRepair();this.retainFailedSubSolver(t),this.activeSubSolver=null,this.startTraceClearanceRepair()}}adoptCleanupOutput(t){const e=this.acceptConnectivityCheckpoint(t.getOutput(),"cleanup");this.cleanupCompleted=!t.budgetLimited;const n=t.stats;this.connectivityValidationError??=n.connectivityValidationError??null,this.connectivityValidationCount+=Number(n.connectivityValidationCount??0);const o=Number(n.connectivityRollbackCount??0);o>0&&(this.connectivityRollbackCount+=o,this.connectivityRollbackPhases.includes("cleanup")||this.connectivityRollbackPhases.push("cleanup"),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...n.connectivityRegressionEndpointIds??[]])]);const i=e&&0===o;this.cleanupBestEffortAccepted=t.budgetLimited&&i,this.cleanupMutatedTraceIndices=i?[...n.mutatedTraceIndices??[]]:[],this.removedViaPairCount=i?Number(n.viaPairCountRemoved??0):0,this.removedViaCount=i?Number(n.viaCountRemoved??0):0,this.simplifiedPathCount=i?Number(n.simplifiedPathCount??0):0,this.normalizedSegmentCount=i?Number(n.normalizedSegmentCount??0):0,this.cleanupClearanceShoveCount=i?Number(n.committedClearanceShoveCount??0):0,this.relocatedViaCount=i?Number(n.relocatedViaCount??0):0,this.unresolvedViaCount=Number(n.unresolvedViaCount??0),this.padClearanceRerouteCount=i?Number(n.padClearanceRerouteCount??0):0,this.unresolvedPadClearanceCount=Number(n.unresolvedPadClearanceCount??0),this.initialPadClearanceViolationCount=Number(n.initialPadClearanceViolationCount??0),this.remainingPadClearanceViolationCount=Number(n.remainingPadClearanceViolationCount??0),this.initialPadClearanceViolationCountByClearance={...n.initialPadClearanceViolationCountByClearance??{}},this.remainingPadClearanceViolationCountByClearance={...n.remainingPadClearanceViolationCountByClearance??{}},this.rebuildObstacleIndex()}startTraceClearanceRepair(){this.phase="repair-trace-clearance";const t=[...new Set([...this.getOwnedTraceIndices(),...this.expansionPushedTraceIndices,...this.cleanupMutatedTraceIndices])],e=new YJ({simpleRouteJson:this.inputProblem,traces:this.traces,traceIndices:t});e.MAX_ITERATIONS=Math.min(e.MAX_ITERATIONS,this.getRemainingParentIterationsAfterCurrentStep()),this.clearanceRepairIterationBudget=e.MAX_ITERATIONS,this.activeSubSolver=e}stepActiveTraceClearanceRepairSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved)return this.adoptClearanceRepairOutput(t),this.activeSubSolver=null,void(this.phase="complete");this.retainFailedSubSolver(t),this.activeSubSolver=null,this.phase="complete"}}adoptClearanceRepairOutput(t){const e=this.acceptConnectivityCheckpoint(t.getOutput(),"clearance-repair");this.clearanceRepairCompleted=!t.budgetLimited;const n=t.stats;this.connectivityValidationError??=n.connectivityValidationError??null,this.connectivityValidationCount+=Number(n.connectivityValidationCount??0);const o=Number(n.connectivityRollbackCount??0);o>0&&(this.connectivityRollbackCount+=o,this.connectivityRollbackPhases.includes("clearance-repair")||this.connectivityRollbackPhases.push("clearance-repair"),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...n.connectivityRegressionEndpointIds??[]])]);const i=e&&0===o;this.clearanceRepairBestEffortAccepted=t.budgetLimited&&i,this.repairedTraceClearanceSegmentCount=i?Number(n.repairedSegmentCount??0):0,this.repairedPadNeckSegmentCount=i?Number(n.repairedPadNeckSegmentCount??0):0,this.unresolvedTraceClearanceSegmentCount=Number(n.unresolvedSegmentCount??0),this.rebuildObstacleIndex()}stepActiveLayerSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput();if(e){const t=!this.layerRouteReplacementCollides(e,!0)&&this.layerRouteImprovesInterval(e),n=t&&this.layerRoutePreservesSameNetContacts(e);if(n){if(this.activeSubSolver=null,this.pendingLayerOutput=e,this.pendingLayerPushCount=0,!this.layerRouteReplacementCollides(e,!1))return void this.applyLayerRoute(e);if(this.startPendingLayerInflation())return;this.pendingLayerOutput=null}t&&!n&&this.sameNetContactRejectionCount++}}this.retainFailedSubSolver(t),this.activeSubSolver=null,this.layerAttempt&&this.layerAttempt.offsetCursor++,this.phase="try-layer-candidate"}}layerRouteReplacementCollides(t,e){const n=this.traces[this.traceIndex],o=this.layerAttempt;if(!n||!o)return!0;const i=this.getTraceConnectionNames(n),r=e?o.softTraceIndices:void 0,s={start:Math.max(0,o.interval.startIndex-1),end:Math.min(n.route.length-1,o.interval.endIndex+1)},a=this.getFixedViasOutsideInterval(n,o.interval);for(let e=0;e<t.route.length;e++){const n=t.route[e];if("via"===n?.route_type){if(this.obstacleIndex.collidesVia({point:n,layers:this.obstacleIndex.boardLayers,padDiameter:n.via_diameter??.6,holeDiameter:n.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter,connectionNames:i,ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:r,otherNewViaPoints:t.route.slice(0,e).filter(t=>"via"===t.route_type).map(t=>({x:t.x,y:t.y})),fixedVias:a,ignoreRouteRange:s,obstacleClearance:this.getDesiredPadClearance(t.traceWidth),blockSameNetObstacles:!0,sameNetObstacleClearance:0}))return!0;continue}const o=t.route[e+1];if("wire"===n?.route_type&&"wire"===o?.route_type&&n.layer===o.layer&&this.obstacleIndex.collides({start:n,end:o,layer:n.layer,width:Math.max(n.width,o.width),connectionNames:i,ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:r,ignoreRouteRange:s,obstacleClearance:this.getDesiredPadClearance(t.traceWidth)}))return!0}return this.layerRouteBoundaryCollides(t,e)}getFixedViasOutsideInterval(t,e){return t.route.flatMap((t,n)=>"via"!==t.route_type||n>=e.startIndex&&n<=e.endIndex?[]:[{point:{x:t.x,y:t.y},padDiameter:t.via_diameter??.6,holeDiameter:t.via_hole_diameter??this.obstacleIndex.defaultViaHoleDiameter}])}layerRouteBoundaryCollides(t,e){const n=this.traces[this.traceIndex],o=this.layerAttempt,i=t.route.find(t=>"wire"===t.route_type);let r;for(let e=t.route.length-1;e>=0;e--){const n=t.route[e];if("wire"===n?.route_type){r=n;break}}if(!i||!r)return!0;const s=[{outside:n.route[o.interval.startIndex-1],inside:i},{outside:n.route[o.interval.endIndex+1],inside:r}];for(const i of s)if(HJ(i.outside)&&i.outside.layer===i.inside.layer&&this.obstacleIndex.collides({start:i.outside,end:i.inside,layer:i.inside.layer,width:Math.max(i.outside.width,i.inside.width),connectionNames:this.getTraceConnectionNames(n),ignoreTraceIndex:this.traceIndex,ignoreTraceIndices:e?o.softTraceIndices:void 0,ignoreRouteRange:{start:Math.max(0,o.interval.startIndex-1),end:Math.min(n.route.length-1,o.interval.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(t.traceWidth)}))return!0;return!1}layerRouteImprovesInterval(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=this.getRouteQuality(e.route.slice(n.startIndex,n.endIndex+1)),i=this.getRouteQuality(t.route);return i.length<=o.length+10+Mq&&i.deficitArea<=o.deficitArea-Math.max(.05,.1*o.deficitArea)}getRouteQuality(t){let e=0,n=0;for(let o=0;o<t.length-1;o++){const i=t[o],r=t[o+1];if(!HJ(i)||!HJ(r)||i.layer!==r.layer)continue;const s=Nq(i,r),a=Math.min(i.width,r.width);e+=s,n+=s*Math.max(0,this.nominalTraceWidth-a)}return{length:e,deficitArea:n}}getLayerInflationCorridor(t){const e=[];for(let n=0;n<t.route.length;n++){const o=t.route[n];if("via"===o?.route_type){for(const t of this.obstacleIndex.boardLayers)e.push({start:o,end:o,layer:t,width:o.via_diameter??.6});continue}const i=t.route[n+1];"wire"===o?.route_type&&"wire"===i?.route_type&&o.layer===i.layer&&e.push({start:o,end:i,layer:o.layer,width:Math.max(o.width,i.width)})}return e}startPendingLayerInflation(){const t=this.pendingLayerOutput;if(!t||this.pendingLayerPushCount>=2)return!1;const e=this.getLayerInflationCorridor(t);return 0!==e.length&&(this.pendingLayerPushCount++,this.attemptedInflationCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem,traces:this.traces,powerTraceIndex:this.traceIndex,nominalPowerWidth:t.traceWidth,mutableTraceIndices:this.mutableBlockerTraceIndices,corridor:e,maxRerouteLength:10},this.connectionNameResolver),this.phase="try-trace-inflation",!0)}applyLayerRoute(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=this.createLayerRouteReplacement(t);e.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...o),t.viaCount>0&&this.layerReroutedTraceCount++,this.layerRerouteCountByTrace.set(this.traceIndex,(this.layerRerouteCountByTrace.get(this.traceIndex)??0)+1),this.reroutedSegmentCount++,this.insertedViaCount+=t.viaCount,t.viaCount>0&&(this.neckedLayerSegmentCount+=o.filter(t=>"wire"===t.route_type&&t.width<this.nominalTraceWidth-Mq).length),this.routeSegmentIndex=n.startIndex,this.currentIntervals=[],this.layerAttempt=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.phase="evaluate-segment"}createLayerRouteReplacement(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval,o=e.route[n.startIndex],i=e.route[n.endIndex],r=structuredClone(t.route),s=r.findIndex(t=>"wire"===t.route_type);let a=-1;for(let t=r.length-1;t>=0;t--)if("wire"===r[t]?.route_type){a=t;break}return s>=0&&(r[s]={...o,...r[s]}),a>=0&&(r[a]={...i,...r[a]}),r}layerRoutePreservesSameNetContacts(t){const e=this.traces[this.traceIndex],n=this.layerAttempt.interval;return this.routeReplacementPreservesSameNetContacts(e,n,this.createLayerRouteReplacement(t))}startTraceInflation(t,e){const n=t.route[e],o=t.route[e+1];if(!HJ(n)||!HJ(o))return!1;const i=Math.min(n.width,o.width),r=this.findBestPushableInflationWidth(t,e,i);if(!r)return!1;const s=this.getLocalInflationCorridor(t,e,r);if(0===s.length)return!1;const a=[this.traceIndex,n.x,n.y,o.x,o.y].join(":"),c=this.inflationAttemptsBySegment.get(a)??0;return!(c>=2)&&(this.inflationAttemptsBySegment.set(a,c+1),this.activeInflationKey=a,this.activeInflationWidth=r,this.attemptedInflationCount++,this.activeSubSolver=new oJ({simpleRouteJson:this.inputProblem,traces:this.traces,powerTraceIndex:this.traceIndex,nominalPowerWidth:r,mutableTraceIndices:this.mutableBlockerTraceIndices,corridor:s,maxRerouteLength:10},this.connectionNameResolver),this.phase="try-trace-inflation",!0)}hasOnlyPushableTraceBlockers(t,e,n){const o=Math.max(0,e-1),i=Math.min(t.route.length-2,e+1),r=new Set;for(let e=o;e<=i;e++){const s=t.route[e],a=t.route[e+1];if(!HJ(s)||!HJ(a)||s.layer!==a.layer)continue;const c={start:s,end:a,layer:s.layer,width:n,connectionNames:this.getTraceConnectionNames(t),ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:o,end:i+1},obstacleClearance:this.getDesiredPadClearance(n)},l=this.obstacleIndex.findCollisions(c);if(0===l.length&&this.obstacleIndex.collides(c))return!1;for(const t of l){if("trace"!==t.kind||void 0===t.traceIndex)return!1;const e=this.traces[t.traceIndex];if(!e)return!1;const o=this.findConnectionForTrace(e);if(!o||(o.nominalTraceWidth??o.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth)>=n-Mq)return!1;r.add(t.traceIndex)}}return r.size>0&&r.size<=2}findBestPushableInflationWidth(t,e,n){const o=this.nominalTraceWidth>=.5?.05:.0125;for(let i=this.nominalTraceWidth;i>n+Mq;i-=o){const n=Number(i.toFixed(6));if(this.hasOnlyPushableTraceBlockers(t,e,n))return n}return null}stepActiveInflationSolver(){const t=this.activeSubSolver;if(t.step(),t.solved||t.failed){if(t.solved){const e=t.getOutput(),n=e&&this.sameNetContactsArePreserved(this.traces[e.pushedTraceIndex].route,e.traces[e.pushedTraceIndex].route,this.getTraceConnectionNames(this.traces[e.pushedTraceIndex]),e.pushedTraceIndex);if(e&&n){if(this.traces=e.traces,this.pushedTraceCount++,this.expansionPushedTraceIndices.add(e.pushedTraceIndex),"elastic"===e.strategy&&this.elasticPushedTraceCount++,this.activeSubSolver=null,this.activeInflationKey=null,this.activeInflationWidth=null,this.rebuildObstacleIndex(),this.pendingLayerOutput){if(!this.layerRouteReplacementCollides(this.pendingLayerOutput,!1)&&this.layerRoutePreservesSameNetContacts(this.pendingLayerOutput))return void this.applyLayerRoute(this.pendingLayerOutput);if(this.startPendingLayerInflation())return;return this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.layerAttempt&&this.layerAttempt.offsetCursor++,void(this.phase="try-layer-candidate")}return void(this.phase="evaluate-segment")}e&&!n&&this.sameNetContactRejectionCount++}if(this.retainFailedSubSolver(t),this.activeInflationKey&&this.inflationAttemptsBySegment.set(this.activeInflationKey,2),this.activeInflationKey=null,this.activeInflationWidth=null,this.activeSubSolver=null,this.pendingLayerOutput)return this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.layerAttempt&&this.layerAttempt.offsetCursor++,void(this.phase="try-layer-candidate");this.phase="evaluate-segment"}}getLocalInflationCorridor(t,e,n){const o=t.route[e],i=t.route[e+1];if(!HJ(o)||!HJ(i)||o.layer!==i.layer)return[];const r=Rq(4*n,2,4),s=r/2;let a=e,c=0;for(;a>0;){const e=t.route[a-1],n=t.route[a];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(c+o>s+Mq)break;c+=o,a--}let l=e+1,d=0;for(;l<t.route.length-1;){const e=t.route[l],n=t.route[l+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(d+o>s+Mq)break;d+=o,l++}let h=r-c-d;for(;h>Mq&&a>0;){const e=t.route[a-1],n=t.route[a];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(o>h+Mq)break;h-=o,a--}for(;h>Mq&&l<t.route.length-1;){const e=t.route[l],n=t.route[l+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)break;const o=Nq(e,n);if(o>h+Mq)break;h-=o,l++}const u=[];for(let e=a;e<l;e++){const o=t.route[e],i=t.route[e+1];HJ(o)&&HJ(i)&&o.layer===i.layer&&u.push({start:o,end:i,layer:o.layer,width:n})}return u}applyGridRoute(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=this.createGridRouteReplacement(t);e.route.splice(n.startIndex,n.endIndex-n.startIndex+1,...o),this.reroutedSegmentCount++,this.routeSegmentIndex=n.startIndex+o.length-1,this.currentIntervals=[],this.phase="evaluate-segment"}createGridRouteReplacement(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=e.route[n.startIndex],i=e.route[n.endIndex],r=t.points.map(e=>({route_type:"wire",x:e.x,y:e.y,width:t.traceWidth,layer:o.layer}));return r[0].width=Math.max(o.width,t.traceWidth),r[r.length-1].width=Math.max(i.width,t.traceWidth),r}gridRoutePreservesSameNetContacts(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor];return this.routeReplacementPreservesSameNetContacts(e,n,this.createGridRouteReplacement(t))}routeReplacementPreservesSameNetContacts(t,e,n){const o=this.getTraceConnectionNames(t),i=this.getSameNetContactIds(t.route.slice(e.startIndex,e.endIndex+1),o,this.traceIndex),r=new Set([...this.getSameNetContactIds(t.route.slice(0,e.startIndex+1),o,this.traceIndex),...this.getSameNetContactIds(t.route.slice(e.endIndex),o,this.traceIndex)]),s=new Set([...i].filter(t=>!r.has(t)));if(0===s.size)return!0;const a=this.getSameNetContactIds(n,o,this.traceIndex);return[...s].every(t=>a.has(t))}sameNetContactsArePreserved(t,e,n,o){const i=this.getSameNetContactIds(t,n,o);if(0===i.size)return!0;const r=this.getSameNetContactIds(e,n,o);return[...i].every(t=>r.has(t))}getSameNetContactIds(t,e,n){const o=new Set;for(let i=0;i<t.length;i++){const r=t[i];if("via"===r?.route_type){for(const t of this.getViaLayers(r))for(const i of this.obstacleIndex.getSameNetCopperContactIds({start:r,end:r,layer:t,width:r.via_diameter??.6,connectionNames:e,ignoreTraceIndex:n}))o.add(i);continue}const s=t[i+1];if("wire"===r?.route_type&&"wire"===s?.route_type&&r.layer===s.layer)for(const t of this.obstacleIndex.getSameNetCopperContactIds({start:r,end:s,layer:r.layer,width:Math.min(r.width,s.width),connectionNames:e,ignoreTraceIndex:n}))o.add(t)}return o}getViaLayers(t){const e=this.obstacleIndex.boardLayers.indexOf(t.from_layer),n=this.obstacleIndex.boardLayers.indexOf(t.to_layer);return e<0||n<0?this.obstacleIndex.boardLayers:this.obstacleIndex.boardLayers.slice(Math.min(e,n),Math.max(e,n)+1)}gridRouteReplacementCollides(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=e.route[n.startIndex],i=e.route[n.endIndex],r=this.getTraceConnectionNames(e);for(let s=0;s<t.points.length-1;s++){const a=Math.max(t.traceWidth,0===s?o.width:0,s===t.points.length-2?i.width:0);if(this.obstacleIndex.collides({start:t.points[s],end:t.points[s+1],layer:o.layer,width:a,connectionNames:r,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:Math.max(0,n.startIndex-1),end:Math.min(e.route.length-1,n.endIndex+1)},obstacleClearance:this.getDesiredPadClearance(a)}))return!0}return!1}gridRouteBoundaryCollides(t){const e=this.traces[this.traceIndex],n=this.currentIntervals[this.intervalCursor],o=this.getTraceConnectionNames(e),i=[{startIndex:n.startIndex-1,endIndex:n.startIndex},{startIndex:n.endIndex,endIndex:n.endIndex+1}];for(const n of i){const i=e.route[n.startIndex],r=e.route[n.endIndex];if(HJ(i)&&HJ(r)&&i.layer===r.layer&&this.obstacleIndex.collides({start:i,end:r,layer:i.layer,width:Math.max(i.width,r.width,t.traceWidth),connectionNames:o,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:n.startIndex,end:n.endIndex},obstacleClearance:this.getDesiredPadClearance(Math.max(i.width,r.width,t.traceWidth))}))return!0}return!1}canExpandSegmentAndEndpoints(t,e,n,o=this.nominalTraceWidth){const i=Math.max(0,e-1),r=Math.min(t.route.length-2,e+1);for(let s=i;s<=r;s++){const a=t.route[s],c=t.route[s+1];if(!HJ(a)||!HJ(c)||a.layer!==c.layer)continue;const l=s<=e+1&&s+1>=e,d=Math.max(a.width,c.width,l?o:0);if(this.obstacleIndex.collides({start:a,end:c,layer:a.layer,width:d,connectionNames:n,ignoreTraceIndex:this.traceIndex,ignoreRouteRange:{start:i,end:r+1},obstacleClearance:this.getDesiredPadClearance(d)}))return!1}return!0}findMaximumSafeInPlaceWidth(t,e,n){const o=t.route[e],i=t.route[e+1];if(!HJ(o)||!HJ(i))return 0;const r=Math.min(o.width,i.width);if(this.probeInPlaceWidth(t,e,n,this.nominalTraceWidth))return this.nominalTraceWidth;let s=r,a=this.nominalTraceWidth;for(let o=0;o<7;o++){const o=(s+a)/2;if(o<=s+Mq)break;this.probeInPlaceWidth(t,e,n,o)?s=o:a=o}const c=this.nominalTraceWidth>=.5?.025:.0125,l=Math.max(r,Math.floor((s+Mq)/c)*c);return l>r+Mq&&this.probeInPlaceWidth(t,e,n,l)?l:r}probeInPlaceWidth(t,e,n,o){return this.inPlaceWidthProbeCount++,this.canExpandSegmentAndEndpoints(t,e,n,o)}maximizeGridRouteWidth(t){if(t.traceWidth>=this.nominalTraceWidth-Mq)return t;let e=t.traceWidth,n=this.nominalTraceWidth;for(let o=0;o<7;o++){const o=(e+n)/2,i={...t,traceWidth:o};this.gridRouteReplacementCollides(i)||this.gridRouteBoundaryCollides(i)?n=o:e=o}const o=this.nominalTraceWidth>=.5?.025:.0125,i=Math.max(t.traceWidth,Math.floor((e+Mq)/o)*o);if(i>t.traceWidth+Mq){const e={...t,traceWidth:i};if(!this.gridRouteReplacementCollides(e)&&!this.gridRouteBoundaryCollides(e))return this.pathWidthUpgradeCount++,e}return t}getExponentialIntervalCandidates(t,e,n){const o=this.getExponentialIndices(t,e,-1,n,5),i=this.getExponentialIndices(t,e,1,n,10).filter(t=>t>e),r=[];for(const e of o)for(const n of i){const o=this.getRouteIntervalLength(t,e,n);o>10.000001||r.push({startIndex:e,endIndex:n,routeLength:o})}return r.sort((t,e)=>t.routeLength-e.routeLength).filter((t,e,n)=>n.findIndex(e=>e.startIndex===t.startIndex&&e.endIndex===t.endIndex)===e).slice(0,10).map(({startIndex:t,endIndex:e})=>({startIndex:t,endIndex:e}))}getExponentialIndices(t,e,n,o,i){const r=[e];let s=0,a=Math.max(o,.3),c=e,l=e;for(;;){const e=c+n;if(e<0||e>=t.route.length)break;const o=t.route[c],d=t.route[e];if(!HJ(o)||!HJ(d)||o.layer!==d.layer)break;const h=Nq(o,d);if(s+h>i+Mq)break;s+=h,c=e,l=e,s+Mq>=a&&(r.push(e),a*=2)}return r.includes(l)||r.push(l),r}getRouteIntervalLength(t,e,n){let o=0;for(let i=e;i<n;i++){const e=t.route[i],n=t.route[i+1];if(!HJ(e)||!HJ(n)||e.layer!==n.layer)return Number.POSITIVE_INFINITY;o+=Nq(e,n)}return o}getCandidateWidths(t){const e=this.inputProblem.minTraceWidth;return WJ([t,.875*t,.75*t,.625*t,.5*t,.375*t,.25*t,e]).filter(t=>t>=e-Mq)}getGridResolutions(t){return WJ([Math.max(.1,Math.min(.5,t/2)),Math.max(.1,Math.min(.25,t/3))])}resolveNominalTraceWidth(t){const e=this.findConnectionForTrace(t);return Math.max(e?.nominalTraceWidth??e?.width??this.inputProblem.nominalTraceWidth??this.inputProblem.minTraceWidth,this.inputProblem.minTraceWidth)}getDesiredPadClearance(t=this.nominalTraceWidth){const e=Math.max(this.inputProblem.defaultObstacleMargin??0,this.inputProblem.minTraceToPadEdgeClearance??0,.1);return t<.499999||"cleanup"!==this.phase?e:Math.max(e,this.options.powerTraceToPadClearance??t/2)}findConnectionForTrace(t){const e=this.connectionByTraceId.get(t.pcb_trace_id);if(void 0!==e)return e??void 0;const n=this.getTraceConnectionNames(t),o=this.inputProblem.connections.find(t=>this.connectionMatchesTrace(t,n))??null;return this.connectionByTraceId.set(t.pcb_trace_id,o),o??void 0}getOwnedTraceIndices(){return[...this.selectedOwnedTraceIndices]}connectionMatchesTrace(t,e){return[t.name,t.source_trace_id,t.rootConnectionName,t.netConnectionName,...t.mergedConnectionNames??[]].filter(t=>Boolean(t)).some(t=>e.includes(t))}getTraceConnectionNames(t){return[t.connection_name,t.source_trace_id,t.rootConnectionName,...t.mergedConnectionNames??[]].filter(t=>Boolean(t))}traceMeetsNominalWidth(t,e){return t.route.every(t=>"wire"!==t.route_type||t.width>=e-Mq)}findNextUnderWidthSegment(t,e,n){for(let o=e;o<t.route.length-1;o++){const e=t.route[o],i=t.route[o+1];if(HJ(e)&&HJ(i)&&e.layer===i.layer&&(e.width<n-Mq||i.width<n-Mq))return o}return-1}getMutatedImmutableTraceIds(t){return this.immutableTraceIndices.flatMap(e=>{const n=t[e];return JSON.stringify(n)===this.initialImmutableTraceSignatures.get(e)?[]:[n?.pcb_trace_id??this.traces[e]?.pcb_trace_id??String(e)]})}getImmutableViaViolationSignatures(t){const e=new Set;if(0===this.immutableTraceIndices.length)return e;const n=new Pq(this.inputProblem,t),o=new tJ(this.inputProblem,t,void 0,[],n);for(const n of this.immutableTraceIndices){const i=t[n];if(!i)continue;const r=[i.pcb_trace_id,i.connection_name,i.source_trace_id,i.rootConnectionName,...i.mergedConnectionNames??[],...i.connectsTo??[]].filter(t=>Boolean(t));for(let t=0;t<i.route.length;t++){const s=i.route[t];if("via"!==s?.route_type)continue;const a=`${i.pcb_trace_id}:${t}`,c=o.getViaViolationSignatures({point:s,layers:o.boardLayers,padDiameter:s.via_diameter??this.inputProblem.min_via_pad_diameter??this.inputProblem.minViaPadDiameter??this.inputProblem.minViaDiameter??.6,holeDiameter:s.via_hole_diameter??o.defaultViaHoleDiameter,connectionNames:r,ignoreTraceIndex:n,ignoreRouteRange:{start:t,end:t},blockSameNetObstacles:!0,sameNetObstacleClearance:0});for(const t of c)e.add(`${a}|${t}`)}}return e}countViolatingImmutableVias(t){return new Set([...t].map(t=>t.split("|")[0])).size}acceptConnectivityCheckpoint(t,e){this.connectivityValidationCount++;let n=!1,o=!1;try{const e=this.connectivityInvariant.validate(t),i=this.getMutatedImmutableTraceIds(t),r=this.getImmutableViaViolationSignatures(t),s=[...r].filter(t=>!this.lastSafeImmutableViaViolationSignatures.has(t)),a=s.length>0;if(n=!e.safe,o=i.length>0||a,this.connectivityValidationError??=e.validationError??null,!n&&!o)return this.traces=structuredClone(t),this.lastConnectivitySafeTraces=structuredClone(t),this.remainingImmutableViaViolationCount=this.countViolatingImmutableVias(r),this.remainingImmutableViaViolationPairCount=r.size,this.lastSafeImmutableViaViolationSignatures=r,this.connectivityInvariant=new OJ(this.inputProblem,this.lastConnectivitySafeTraces),!0;this.immutableTraceMutationIds=[...new Set([...this.immutableTraceMutationIds,...i])],a&&(this.immutableViaViolationRollbackCount++,this.attemptedImmutableViaViolationCount=this.countViolatingImmutableVias(r),this.attemptedImmutableViaViolationPairCount=r.size,this.immutableViaViolationRegressionIds=[...new Set([...this.immutableViaViolationRegressionIds,...s])]),this.connectivityRegressionEndpointIds=[...new Set([...this.connectivityRegressionEndpointIds,...e.regressions.flatMap(t=>t.baselineEndpointLabels)])]}catch(t){n=!0,this.connectivityValidationError=t instanceof Error?t.message:String(t)}return n&&(this.connectivityRollbackCount++,this.connectivityRollbackPhases.includes(e)||this.connectivityRollbackPhases.push(e)),o&&(this.immutableSafetyRollbackCount++,this.immutableSafetyRollbackPhases.includes(e)||this.immutableSafetyRollbackPhases.push(e)),"expansion"===e?n?this.rollbackConnectivityRegressedExpansion():this.rollbackImmutableUnsafeExpansion():this.restoreLastConnectivitySafeTraces(),this.remainingImmutableViaViolationCount=this.countViolatingImmutableVias(this.lastSafeImmutableViaViolationSignatures),this.remainingImmutableViaViolationPairCount=this.lastSafeImmutableViaViolationSignatures.size,!1}rebuildObstacleIndex(){this.obstacleIndex=new tJ(this.inputProblem,this.traces,this.traceIndex,[],this.connectionNameResolver)}retainFailedSubSolver(t){this.failedSubSolverCount++,this.failedSubSolvers??=[],this.failedSubSolvers.length<16?this.failedSubSolvers.push(t):this.failedSubSolvers[15]=t}tryFinalAcceptance(){this.finalAcceptanceUsed=!0;let t=!1;this.activeSubSolver instanceof jJ?(this.activeSubSolver.tryFinalAcceptance(),this.adoptCleanupOutput(this.activeSubSolver),t=!0):this.activeSubSolver instanceof YJ&&(this.activeSubSolver.tryFinalAcceptance(),this.adoptClearanceRepairOutput(this.activeSubSolver),t=!0),t||"cleanup"===this.phase||"repair-trace-clearance"===this.phase||"complete"===this.phase||this.discardInFlightExpansion(),this.activeSubSolver=null,this.pendingLayerOutput=null,this.pendingLayerPushCount=0,this.activeInflationKey=null,this.activeInflationWidth=null,this.layerAttempt=null,this.acceptConnectivityCheckpoint(this.traces,"final"),this.traceIndex=this.traces.length,this.phase="complete",this.rebuildObstacleIndex(),this.progress=1,this.solved=!0,this.stats=this.createStats()}createStats(){return{phase:this.phase,pass:this.passIndex+1,completedPassCount:this.completedPassCount,lastNormalizedWidthDeficitGain:this.lastNormalizedWidthDeficitGain,normalizedWidthDeficitGainByPass:[...this.normalizedWidthDeficitGainByPass],plateauReached:this.plateauReached,traceIndex:this.traceIndex,traceCount:this.traces.length,selectedTraceCount:this.traceOrder.length,routeSegmentIndex:this.routeSegmentIndex,nominalTraceWidth:this.nominalTraceWidth,intervalCursor:this.intervalCursor,intervalCount:this.currentIntervals.length,candidateWidth:this.candidateWidths[this.widthCursor],gridSize:this.gridResolutions[this.resolutionCursor],gridOffsetVariant:this.offsetCursor,keptTraceCount:this.keptTraceCount,recreatedTraceCount:this.recreatedTraceCount,expandedSegmentCount:this.expandedSegmentCount,intermediateExpandedSegmentCount:this.intermediateExpandedSegmentCount,pathWidthUpgradeCount:this.pathWidthUpgradeCount,inPlaceWidthProbeCount:this.inPlaceWidthProbeCount,reroutedSegmentCount:this.reroutedSegmentCount,unresolvedSegmentCount:this.unresolvedSegmentCount,attemptedGridCount:this.attemptedGridCount,attemptedLayerGridCount:this.attemptedLayerGridCount,attemptedInflationCount:this.attemptedInflationCount,activeInflationWidth:this.activeInflationWidth,pushedTraceCount:this.pushedTraceCount,elasticPushedTraceCount:this.elasticPushedTraceCount,layerReroutedTraceCount:this.layerReroutedTraceCount,insertedViaCount:this.insertedViaCount,neckedLayerSegmentCount:this.neckedLayerSegmentCount,removedViaPairCount:this.removedViaPairCount,removedViaCount:this.removedViaCount,simplifiedPathCount:this.simplifiedPathCount,normalizedSegmentCount:this.normalizedSegmentCount,cleanupClearanceShoveCount:this.cleanupClearanceShoveCount,relocatedViaCount:this.relocatedViaCount,unresolvedViaCount:this.unresolvedViaCount,initialImmutableViaViolationCount:this.initialImmutableViaViolationCount,remainingImmutableViaViolationCount:this.remainingImmutableViaViolationCount,initialImmutableViaViolationPairCount:this.initialImmutableViaViolationPairCount,remainingImmutableViaViolationPairCount:this.remainingImmutableViaViolationPairCount,skippedImmutableViaRepairCount:this.remainingImmutableViaViolationCount,immutableViaViolationRollbackCount:this.immutableViaViolationRollbackCount,attemptedImmutableViaViolationCount:this.attemptedImmutableViaViolationCount,attemptedImmutableViaViolationPairCount:this.attemptedImmutableViaViolationPairCount,immutableViaViolationRegressionIds:[...this.immutableViaViolationRegressionIds],immutableTraceMutationIds:[...this.immutableTraceMutationIds],padClearanceRerouteCount:this.padClearanceRerouteCount,unresolvedPadClearanceCount:this.unresolvedPadClearanceCount,repairedTraceClearanceSegmentCount:this.repairedTraceClearanceSegmentCount,repairedPadNeckSegmentCount:this.repairedPadNeckSegmentCount,unresolvedTraceClearanceSegmentCount:this.unresolvedTraceClearanceSegmentCount,sameNetContactRejectionCount:this.sameNetContactRejectionCount,connectivityValidationCount:this.connectivityValidationCount,connectivityRollbackCount:this.connectivityRollbackCount,connectivityRollbackPhases:[...this.connectivityRollbackPhases],immutableSafetyRollbackCount:this.immutableSafetyRollbackCount,immutableSafetyRollbackPhases:[...this.immutableSafetyRollbackPhases],connectivityRegressionEndpointIds:[...this.connectivityRegressionEndpointIds],connectivityValidationError:this.connectivityValidationError,connectivityRollbackMutationStats:null===this.connectivityRollbackMutationStats?null:{...this.connectivityRollbackMutationStats},immutableSafetyRollbackMutationStats:null===this.immutableSafetyRollbackMutationStats?null:{...this.immutableSafetyRollbackMutationStats},expansionPushedTraceIndices:[...this.expansionPushedTraceIndices],cleanupMutatedTraceIndices:[...this.cleanupMutatedTraceIndices],discardedExpansionMutationStats:null===this.discardedExpansionMutationStats?null:{...this.discardedExpansionMutationStats},initialPadClearanceViolationCount:this.initialPadClearanceViolationCount,remainingPadClearanceViolationCount:this.remainingPadClearanceViolationCount,initialPadClearanceViolationCountByClearance:{...this.initialPadClearanceViolationCountByClearance},remainingPadClearanceViolationCountByClearance:{...this.remainingPadClearanceViolationCountByClearance},budgetLimitedExpansion:this.budgetLimitedExpansion,finalAcceptanceUsed:this.finalAcceptanceUsed,cleanupCompleted:this.cleanupCompleted,clearanceRepairCompleted:this.clearanceRepairCompleted,cleanupBestEffortAccepted:this.cleanupBestEffortAccepted,clearanceRepairBestEffortAccepted:this.clearanceRepairBestEffortAccepted,cleanupStatus:this.connectivityRollbackPhases.includes("cleanup")?"connectivity_rollback":this.immutableSafetyRollbackPhases.includes("cleanup")?"immutable_safety_rollback":this.cleanupBestEffortAccepted?"budget_limited":this.cleanupCompleted?"completed":"cleanup"===this.phase?"in_progress":"not_started",clearanceRepairStatus:this.connectivityRollbackPhases.includes("clearance-repair")?"connectivity_rollback":this.immutableSafetyRollbackPhases.includes("clearance-repair")?"immutable_safety_rollback":this.clearanceRepairBestEffortAccepted?"budget_limited":this.clearanceRepairCompleted?"completed":"repair-trace-clearance"===this.phase?"in_progress":"not_started",cleanupIterationBudget:this.cleanupIterationBudget,clearanceRepairIterationBudget:this.clearanceRepairIterationBudget,completionReason:"complete"===this.phase||this.solved?this.connectivityRollbackCount>0?"connectivity_rollback":this.immutableSafetyRollbackCount>0?"immutable_safety_rollback":this.connectivityValidationError?"connectivity_validation_unavailable":this.finalAcceptanceUsed?"total_iteration_budget":this.budgetLimitedExpansion?"expansion_budget":this.cleanupBestEffortAccepted?"cleanup_budget":this.clearanceRepairBestEffortAccepted?"clearance_repair_budget":this.remainingImmutableViaViolationCount>0?"immutable_via_violations_preserved":"completed":null,resultStatus:this.finalAcceptanceUsed||this.budgetLimitedExpansion||this.cleanupBestEffortAccepted||this.clearanceRepairBestEffortAccepted||this.connectivityRollbackCount>0||this.immutableSafetyRollbackCount>0||null!==this.connectivityValidationError||this.remainingImmutableViaViolationCount>0?"best_effort":"complete",failedSubSolverCount:this.failedSubSolverCount,retainedFailedSubSolverCount:this.failedSubSolvers?.length??0,expansionIterationBudget:this.getExpansionIterationBudget(),finalizationIterationReserve:this.getFinalizationIterationReserve(),spatialIndexRectCount:this.obstacleIndex.items.length}}computeProgress(){return this.solved||"complete"===this.phase?1:this.budgetLimitedExpansion?.99:0===this.traceOrder.length?1:Math.min(.99,(this.passIndex+Math.max(0,this.traceOrderCursor)/this.traceOrder.length)/this.maxPassCount)}getConstructorParams(){return[this.inputProblem,this.options]}getOutput(){return structuredClone(this.lastConnectivitySafeTraces)}visualize(){const t=[],e=[];for(let n=0;n<this.traces.length;n++){const o=this.traces[n],i=this.resolveNominalTraceWidth(o);for(const t of o.route)"via"===t.route_type&&e.push({center:t,radius:(t.via_diameter??.6)/2,fill:"#d4a017",stroke:"#7a5700"});for(let e=0;e<o.route.length-1;e++){const r=o.route[e],s=o.route[e+1];if(!HJ(r)||!HJ(s)||r.layer!==s.layer)continue;const a=n===this.traceIndex&&e===this.routeSegmentIndex,c=r.width>=i-Mq&&s.width>=i-Mq,l="bottom"===r.layer;t.push({points:[r,s],strokeColor:a?"#ff8c00":c?l?"#2468c7":"#169c45":l?"#8b4bb8":"#cc3344",strokeWidth:Math.max(r.width,s.width)})}}return{coordinateSystem:"cartesian",title:`Power trace expander: ${this.phase}`,lines:t,points:[],circles:e,rects:this.obstacleIndex.items.filter(t=>"obstacle"===t.kind).slice(0,2e3).map(t=>({center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,fill:"rgba(80,80,80,0.12)",stroke:"rgba(80,80,80,0.35)"})),texts:[]}}},UJ=class extends si{constructor(t,e={}){if(super(),this.inputSrj=t,this.options=e,this.powerTraceExpanderSolver=new GJ(t,e),0===e.onlyConnectionNames?.length)return this.MAX_ITERATIONS=1,this.progress=1,this.solved=!0,void(this.stats={selectedTraceCount:0,bypassed:!0});this.MAX_ITERATIONS=this.powerTraceExpanderSolver.MAX_ITERATIONS+1}inputSrj;options;powerTraceExpanderSolver;_step(){const t=this.powerTraceExpanderSolver;if(t.step(),this.progress=t.progress,this.stats=t.stats,t.failed)return this.error=t.error,void(this.failed=!0);t.solved&&(this.solved=!0)}getConstructorParams(){return[this.inputSrj,this.options]}getOutput(){if(!this.solved)throw new Error("Cannot get power trace expansion output before solving");return this.powerTraceExpanderSolver.getOutput()}visualize(){return Ho({...this.inputSrj,traces:this.getOutput()},{traceColorMode:"layer"})}},ZJ=({connections:t,originalConnections:e,layerCount:n,obstacles:o,defaultViaHoleDiameter:i,connMap:r})=>{const s=new Map;for(const t of e)s.has(t.name)||s.set(t.name,t.__netConnectionName);const a=t.map(t=>{if(2!==t.pointsToConnect.length)throw new Error(`Expected Pipeline7 output connection "${t.name}" to have two points, got ${t.pointsToConnect.length}`);const[e,n]=t.pointsToConnect;return{connection:t,connectsTo:[e?.pointId,n?.pointId].filter(t=>Boolean(t)),outputConnectionName:t.__netConnectionName??s.get(t.name)??t.__rootConnectionNames?.[0]??t.name}}),c=o.filter(t=>(t.__zLayers?.length??t.layers?.length??0)>1),l=new Map,d=t=>{let e=l.get(t.connectionName);e||(e=new Map,l.set(t.connectionName,e));const n=e.get(t.rootConnectionName);if(n)return n;const o=c.filter(e=>fo(e,t,r));return e.set(t.rootConnectionName,o),o};return t=>{const e=[],o=new Map;for(const e of t){const t=o.get(e.connectionName);t?t.push(e):o.set(e.connectionName,[e])}for(const{connection:t,connectsTo:s,outputConnectionName:c}of a){const a=o.get(t.name)??[];for(let o=0;o<a.length;o+=1){const l=a[o];e.push({type:"pcb_trace",pcb_trace_id:`${t.name}_${o}`,connection_name:c,connectsTo:s,route:Mo(l,n,{connectionPoints:t.pointsToConnect,defaultViaHoleDiameter:i,connectedMultilayerObstacles:d(l),connMap:r})})}}return e}},qJ=({connections:t,originalConnections:e,hdRoutes:n,layerCount:o,obstacles:i,defaultViaHoleDiameter:r,connMap:s})=>ZJ({connections:t,originalConnections:e,layerCount:o,obstacles:i,defaultViaHoleDiameter:r,connMap:s})(n),JJ=t=>{const e=Math.max(t.minTraceWidth+.1,2*t.minTraceWidth);return t.connections.flatMap(n=>(n.nominalTraceWidth??t.nominalTraceWidth??t.minTraceWidth)+1e-6>=e?[n.name]:[])},KJ=(t,e,n=new Map(t.map(t=>[t.connectionName,t])))=>{const o=new Map(e.map(t=>[t.name,t]));return t.map(t=>{if(0===t.route.length)throw new Error(`Cannot lock PCB terminals for empty route "${t.connectionName}"`);const e=o.get(t.connectionName);if(!e)throw new Error(`Cannot lock PCB terminals: connection "${t.connectionName}" was not found`);if(2!==e.pointsToConnect.length)throw new Error(`Cannot lock PCB terminals for "${t.connectionName}": expected 2 connection points, found ${e.pointsToConnect.length}`);const i=n.get(t.connectionName)??t,r=new Map;for(const n of e.pointsToConnect)if(n.pcb_port_id){if(r.has(n.pcb_port_id))throw new Error(`Cannot lock duplicate PCB terminal "${n.pcb_port_id}" for "${t.connectionName}"`);r.set(n.pcb_port_id,n)}if(0===r.size)return t;const s=[i.startPcbPortId,i.endPcbPortId].filter(t=>void 0!==t);if(0===s.length)return t;if(new Set(s).size!==s.length||s.some(t=>!r.has(t)))throw new Error(`Cannot lock PCB terminals for "${t.connectionName}": route endpoint IDs do not match connection terminal IDs`);const a=i.startPcbPortId?r.get(i.startPcbPortId):void 0,c=i.endPcbPortId?r.get(i.endPcbPortId):void 0,l=t.route.map((e,n)=>{if(0===n&&a)return{...e,x:a.x,y:a.y,pcb_port_id:a.pcb_port_id};if(n===t.route.length-1&&c)return{...e,x:c.x,y:c.y,pcb_port_id:c.pcb_port_id};const o={...e};return delete o.pcb_port_id,o});return{...t,route:l}})},QJ=({originalSrj:t,newlyRoutedTraces:e,currentPreloadedTraces:n,expandedConnectionNames:o,resolveConnectedTraceAliases:i=!1})=>{const r=n??t.traces??[],s=i?tK({originalSrj:t,newlyRoutedTraces:e,preloadedTraces:r,expandedConnectionNames:o}):new Set(r.filter(t=>o.includes(t.connection_name))),a=r.filter(t=>!s.has(t)),c=new Set([...e.map(t=>t.pcb_trace_id),...a.map(t=>t.pcb_trace_id)]),l=r.filter(t=>s.has(t)).map(t=>{const e=t.pcb_trace_id;let n=e,o=2;for(;c.has(n);)n=`${e}_power_expansion_${o++}`;return c.add(n),{...t,pcb_trace_id:n,__replaces_pcb_trace_id:t.__replaces_pcb_trace_id??t.pcb_trace_id}});return{...t,traces:[...e,...l],fixedTraces:a}},tK=({originalSrj:t,newlyRoutedTraces:e,preloadedTraces:n,expandedConnectionNames:o})=>{const i=new Set(n.map(t=>t.pcb_trace_id)),r=new Set([...i,...e.map(t=>t.pcb_trace_id)]),s=e.map((t,e)=>{if(!i.has(t.pcb_trace_id))return t;const n=`__pipeline7_new_trace_${e}_${t.pcb_trace_id}`;let o=n,s=2;for(;r.has(o);)o=`${n}_${s++}`;return r.add(o),{...t,pcb_trace_id:o}}),a=new Pq({...t,traces:[...s,...n]}),c=new Set(a.canonicalize([...o]));return new Set(n.filter(t=>a.canonicalize([t.connection_name]).some(t=>c.has(t))))};function eK(t){return new Set((t??[]).filter(t=>t._isComponentTopologyNode).map(t=>t.capacityMeshNodeId))}function nK(t,e){return t.nodeIds.some(t=>e.has(t))}function oK({sharedEdgeSegments:t,componentCapacityMeshNodeIds:e}){return t.filter(t=>!nK(t,e))}function iK(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var rK=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e;const n=fX(t);this.originalSrj=n,this.opts={...e};const o=this.opts;if(this.effort=o.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=o.maxNodeDimension??16,this.maxNodeRatio=o.maxNodeRatio??6,this.minNodeArea=o.minNodeArea??.1**2,this.visualizationTraceColorMode=o.visualizationTraceColorMode??"layer",this.setSimpleRouteJson(n),void 0===o.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,n=Math.max(t,e),i=o.targetMinCapacity??.5;o.capacityDepth=$s(n,i)}this.cacheProvider=void 0===o.cacheProvider?oo():null===o.cacheProvider?null:o.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;getSolverName(){return"AutoroutingPipelineSolver7_MultiGraph"}preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;componentTopologyGeneratorSolver;topologyPlanningSolver;topologyMergingSolver;globalTopologyGeneratorSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;exactGeometryDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;lengthMatchingPostProcessingSolver;powerTraceExpansionSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;componentDetectionSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;visualizationTraceColorMode;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;sharedEdgeSegmentsWithNecessaryCrampedPortPoints;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[iK("preprocessSimpleRouteJsonSolver",_X,t=>[t.originalSrj,{traceColorMode:t.visualizationTraceColorMode}],{onSolved:t=>{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),iK("componentDetectionSolver",UZ,t=>[{inputSrj:t.srj}]),iK("escapeViaLocationSolver",Uj,t=>[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=>{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),iK("netToPointPairsSolver",ga,t=>{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),iK("topologyPlanningSolver",_q,t=>[{inputSrj:t.srjWithPointPairs,componentDetectionOutput:t.componentDetectionSolver.getOutput(),viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=>{t.topologyPlanningSolver.getOutput();t.globalTopologyGeneratorSolver=t.topologyPlanningSolver.globalTopologySolver,t.componentTopologyGeneratorSolver=new vq(t.topologyPlanningSolver)}}),iK("topologyMergingSolver",fq,t=>{const e=t.topologyPlanningSolver.getOutput();return[{layerCount:t.srj.layerCount,nodeGroups:[{groupId:"global",nodes:e.globalMeshNodes,isComponent:!1},...e.componentMeshNodes.map((t,e)=>({groupId:`component-${e}`,nodes:t,isComponent:!0}))]}]},{onSolved:t=>{t.capacityNodes=t.topologyMergingSolver.getOutput()}}),iK("nodeDimensionSubdivisionSolver",Tz,t=>[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=>{t.capacityNodes=t.nodeDimensionSubdivisionSolver.outputNodes}}),iK("edgeSolver",ui,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),iK("availableSegmentPointSolver",ci,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),iK("necessaryCrampedPortPointSolver",sf,t=>{const e=eK(t.capacityNodes);return[{capacityMeshNodes:t.capacityNodes.filter(t=>!e.has(t.capacityMeshNodeId)),sharedEdgeSegments:oK({sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),componentCapacityMeshNodeIds:e}),simpleRouteJson:t.srjWithPointPairs}]},{onSolved:t=>{const e=eK(t.capacityNodes);t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints=function({originalSharedEdgeSegments:t,filteredSharedEdgeSegments:e,componentCapacityMeshNodeIds:n}){const o=new Map(e.map(t=>[t.edgeId,t]));return t.map(t=>nK(t,n)?t:o.get(t.edgeId)??t)}({originalSharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),filteredSharedEdgeSegments:t.necessaryCrampedPortPointSolver.getOutput(),componentCapacityMeshNodeIds:e})}}),iK("portPointPathingSolver",jj,t=>{const e=t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints??t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=>t.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,preserveTerminalPcbPortIds:!0,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0,USE_SELECTIVE_RERIP_ROUTING:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),iK("uniformPortDistributionSolver",go,t=>[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),iK("highDensityRouteSolver",zs,t=>{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length>0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=>[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!0,growShrinkFallbackToInvalidGeometryOnFailure:!0,captureSearchDebug:!1}]}),iK("highDensityForceImproveSolver",Yy,t=>[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),iK("highDensityRepairSolver",AY,t=>[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2,maxSampleEntries:80}]),iK("highDensityStitchSolver",KY,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,preserveTerminalPcbPortIds:!0}]),iK("traceSimplificationSolver",vc,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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,enableCrossingViaReduction:!0,iterations:2}]),iK("traceWidthSolver",Ic,t=>[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),iK("globalDrcForceImproveSolver",Nz,t=>[{srj:t.srjWithPointPairs,hdRoutes:KJ(t.traceWidthSolver.getHdRoutesWithWidths(),t.netToPointPairsSolver?.newConnections??[],new Map((t.highDensityStitchSolver?.mergedHdRoutes??[]).map(t=>[t.connectionName,t]))),connMap:t.connMap,effort:t.effort,maxIterations:16,enableLargeBoardBroadFallback:!1,enablePostSolveClearanceRelaxation:!1}]),iK("exactGeometryDrcForceImproveSolver",wz,t=>{const e=t.globalDrcForceImproveSolver.getOutput(),n=(t=>{const e={...t.srjWithPointPairs,obstacles:t.originalSrj.obstacles,minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter??t.srjWithPointPairs.minViaDiameter},n=Math.max(Yo(t.originalSrj).padDiameter,e.minTraceWidth)+Math.max(.1,.1),o=new s_(e,{connMap:t.connMap,includeTraceViaOwnerMetadata:!0,traceClearance:.1,viaClearance:.1,spatialCellSize:n}),i=ZJ(t),r=t.originalSrj.traces??[];return({routes:t,hdRoutes:e})=>{const n=t??e;if(!n)throw new Error("Pipeline7 autorouting DRC evaluation requires HD routes");const s=i(n),a=r.length?[...r,...s]:s;return o.evaluate(a)}})({connections:t.netToPointPairsSolver?.newConnections??[],originalConnections:t.originalSrj.connections,layerCount:t.srj.layerCount,obstacles:t.srj.obstacles,defaultViaHoleDiameter:t.viaHoleDiameter,connMap:t.connMap,srjWithPointPairs:t.srjWithPointPairs,originalSrj:t.originalSrj});return[{srj:t.srjWithPointPairs,hdRoutes:e,connMap:t.connMap,effort:t.effort,viaHoleDiameter:t.viaHoleDiameter,drcEvaluator:n,viaInPadDrcEvaluator:n,maxIterations:32,enableLargeBoardBroadFallback:!1,enableBroadFallback:!1,enableTargetedErrorSweep:!0,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:t.originalSrj.allowViaInPad??!1,viaInPadMaxIterations:32,broadMaxIterations:12,broadPassMultiplier:3}]}),iK("lengthMatchingPostProcessingSolver",lU,t=>{const e=t.netToPointPairsSolver;if(!e)throw new Error("Pipeline7: length-matching post-processing requires NetToPointPairsSolver output");const n=e.newConnections,o=new Map;for(const e of t.srj.differentialPairs??[])for(const t of e.connectionNames){const e=n.filter(e=>e.name===t||e.__rootConnectionNames?.includes(t)||e.__netConnectionName===t);if(1!==e.length)throw new Error(`Pipeline7: differential pair connection "${t}" must resolve to exactly one final point-pair connection, got ${e.length}`);o.set(t,e[0].name)}const i=t.exactGeometryDrcForceImproveSolver.getOutput(),r=(t.srj.differentialPairs??[]).map(t=>{const e=t.connectionNames.map(t=>{const e=o.get(t);if(!e)throw new Error(`Pipeline7: differential pair connection "${t}" is missing from final routed output`);return e});if(e[0]===e[1])throw new Error(`Pipeline7: differential pair ${t.connectionNames.join("/")} resolves both members to "${e[0]}"`);if(void 0===t.traceGap)return{connectionNames:e,lengthTolerance:t.lengthTolerance,maxUncoupledLength:t.maxUncoupledLength};const n=e.map(t=>{const e=i.filter(e=>e.connectionName===t);if(1!==e.length)throw new Error(`Pipeline7: differential pair connection "${t}" must resolve to exactly one final HD route, got ${e.length}`);return e[0]}),r=t.traceGap+n.reduce((t,e)=>t+e.traceThickness/2,0);return{connectionNames:e,lengthTolerance:t.lengthTolerance,maxUncoupledLength:t.maxUncoupledLength,minimumCenterlineDistance:r,maximumCenterlineDistance:r}});return[{hdRoutes:i,differentialPairs:r,obstacles:t.srj.obstacles,bounds:t.srj.bounds,layerCount:t.srj.layerCount}]}),iK("powerTraceExpansionSolver",UJ,t=>{const e=t.opts.powerTraceExpansion??{},n=e.onlyConnectionNames??JJ(t.originalSrj);return[QJ({originalSrj:t.originalSrj,newlyRoutedTraces:t.getPrePowerTraceOutputSimplifiedPcbTraces(),expandedConnectionNames:n}),{allowNewVias:!1,...e,onlyConnectionNames:n}]})];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;computeProgress(){const t=this.activeSubSolver?.progress??0;return(this.currentPipelineStepIndex+t)/this.pipelineDef.length}_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),"lengthMatchingPostProcessingSolver"!==t.solverName&&"powerTraceExpansionSolver"!==t.solverName||(this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,this.iterations+this.activeSubSolver.MAX_ITERATIONS+1)),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.visualizeStage(this.activeSubSolver);const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.componentDetectionSolver?.visualize(),o=this.componentTopologyGeneratorSolver?.visualize(),i=this.globalTopologyGeneratorSolver?.visualize(),r=this.topologyMergingSolver?.visualize(),s=this.nodeDimensionSubdivisionSolver?.visualize(),a=this.nodeTargetMerger?.visualize(),c=this.singleLayerNodeMerger?.visualize(),l=this.strawSolver?.visualize(),d=this.edgeSolver?.visualize(),h=this.deadEndSolver?.visualize(),u=this.availableSegmentPointSolver?.visualize(),p=this.portPointPathingSolver?.visualize(),m=this.multiSectionPortPointOptimizer?.visualize(),g=this.uniformPortDistributionSolver?.visualize(),f=this.highDensityRouteSolver?.visualize(),y=this.highDensityForceImproveSolver?.visualize(),_=this.highDensityRepairSolver?.visualize(),b=this.highDensityStitchSolver?.visualize(),x=this.traceSimplificationSolver?.visualize(),v=this.lengthMatchingPostProcessingSolver?.visualize(),S=this.traceWidthSolver?.visualize(),I=this.necessaryCrampedPortPointSolver?.visualize(),C=(this.highDensityRouteSolver?.visualize(),this.originalSrj),P=C.outline,M=[];if(M.push({points:[{x:C.bounds?.minX??-50,y:C.bounds?.minY??-50},{x:C.bounds?.maxX??50,y:C.bounds?.minY??-50},{x:C.bounds?.maxX??50,y:C.bounds?.maxY??50},{x:C.bounds?.minX??-50,y:C.bounds?.maxY??50},{x:C.bounds?.minX??-50,y:C.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),P&&P.length>=2){const t=P.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),M.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const N=Oo(C),w={points:[...C.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,layer:Fo(e,C.layerCount),label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(C.obstacles??[]).filter(t=>!t.isCopperPour).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)",layer:jo(t,C.layerCount),label:N(t)}))],lines:M},T={traceColorMode:this.visualizationTraceColorMode},R=Yj({srj:C,visualizationOptions:T}),E=pi(w,R),A=this.preprocessSimpleRouteJsonSolver?.visualize(),O=this.globalDrcForceImproveSolver?.visualize(),k=this.exactGeometryDrcForceImproveSolver?.visualize(),L=[E,A,n,o,t,e,i,r,s,a,c,l,d,h,u,I,p,m,g,f?pi(w,f):null,y,_,b,x,S,O,k,v,this.solved?pi({lines:M},Yj({srj:this.originalSrj,visualizationOptions:T}),this.visualizeFinalOutput()):null].filter(Boolean),D=pi(...L);return"net"===this.visualizationTraceColorMode?xq(D,this.colorMap):D}visualizeStage(t){const e=t.visualize();return"net"===this.visualizationTraceColorMode?xq(e,this.colorMap):e}visualizeFinalOutput(){const t=this.visualizationTraceColorMode,e=this.getOutputSimpleRouteJson();return Ho(e,{traceColorMode:t})}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.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.componentTopologyGeneratorSolver?this.componentTopologyGeneratorSolver.visualize():this.componentDetectionSolver?this.componentDetectionSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){if(this.lengthMatchingPostProcessingSolver){const{hdRoutes:t}=this.lengthMatchingPostProcessingSolver.getOutput();return t}return this.exactGeometryDrcForceImproveSolver?.getOutput()??this.globalDrcForceImproveSolver?.getOutput()??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");return this.powerTraceExpansionSolver?this.powerTraceExpansionSolver.getOutput():this.getPrePowerTraceOutputSimplifiedPcbTraces()}getPrePowerTraceOutputSimplifiedPcbTraces(){return qJ({connections:this.netToPointPairsSolver?.newConnections??[],originalConnections:this.originalSrj.connections,hdRoutes:this._getOutputHdRoutes(),layerCount:this.srj.layerCount,obstacles:this.srj.obstacles,defaultViaHoleDiameter:this.viaHoleDiameter,connMap:this.connMap})}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},sK=t=>[...new Set(t)].sort((t,e)=>t-e),aK=class extends si{constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1}params;outputNodes=[];outputSharedEdgeSegments=[];nodeIdByOriginalAndZ=new Map;getSolverName(){return"SplitNodesIntoSingleLayerNodeSolver"}_step(){this.outputNodes=this.params.capacityMeshNodes.flatMap(t=>sK(t.availableZ).map(e=>{const n=((t,e)=>`${t}__z${e}`)(t.capacityMeshNodeId,e);return this.nodeIdByOriginalAndZ.set(`${t.capacityMeshNodeId}:${e}`,n),{...t,capacityMeshNodeId:n,layer:`z${e}`,availableZ:[e],_parent:t}})),this.outputSharedEdgeSegments=this.params.sharedEdgeSegments.flatMap(t=>this.splitSharedEdgeSegment(t)),this.stats={inputNodeCount:this.params.capacityMeshNodes.length,outputNodeCount:this.outputNodes.length,inputPortPointCount:this.params.sharedEdgeSegments.reduce((t,e)=>t+e.portPoints.length,0),outputPortPointCount:this.outputSharedEdgeSegments.reduce((t,e)=>t+e.portPoints.length,0)},this.solved=!0}getSplitNodeId(t,e){return this.nodeIdByOriginalAndZ.get(`${t}:${e}`)}splitPortPoint(t){return sK(t.availableZ).flatMap(e=>{const n=t.nodeIds.map(t=>this.getSplitNodeId(t,e));return n[0]&&n[1]?[{...t,segmentPortPointId:`${t.segmentPortPointId}__z${e}`,availableZ:[e],nodeIds:[n[0],n[1]]}]:[]})}splitSharedEdgeSegment(t){const e=new Map;for(const n of t.portPoints.flatMap(t=>this.splitPortPoint(t))){const t=n.availableZ[0];if(void 0===t)continue;const o=e.get(t)??[];o.push(n),e.set(t,o)}return[...e.entries()].map(([e,n])=>({...t,edgeId:`${t.edgeId}__z${e}`,nodeIds:n[0].nodeIds,availableZ:[e],portPoints:n}))}getOutput(){return{capacityMeshNodes:this.outputNodes,sharedEdgeSegments:this.outputSharedEdgeSegments}}getConstructorParams(){return[this.params]}visualize(){return{rects:this.outputNodes.map(t=>({...Dc(t),label:`${t.capacityMeshNodeId}\n${t.layer}`})),points:this.outputSharedEdgeSegments.flatMap(t=>t.portPoints.map(t=>({x:t.x,y:t.y,label:`${t.segmentPortPointId}\nz${t.availableZ.join(",")}`})))}}};function cK(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var lK=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.originalSrj=t,this.opts={...e};const n=this.opts;if(this.effort=n.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=n.maxNodeDimension??16,this.maxNodeRatio=n.maxNodeRatio??6,this.minNodeArea=n.minNodeArea??.1**2,this.setSimpleRouteJson(t),void 0===n.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,o=Math.max(t,e),i=n.targetMinCapacity??.5;n.capacityDepth=$s(o,i)}this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;nodeSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityForceImproveRoutes;highDensityRepairSolver;highDensityRepairRoutes;highDensityStitchSolver;globalDrcForceImproveSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;splitNodesIntoSingleLayerNodeSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[cK("preprocessSimpleRouteJsonSolver",_X,t=>[t.originalSrj],{onSolved:t=>{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),cK("escapeViaLocationSolver",Uj,t=>[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=>{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),cK("netToPointPairsSolver",ga,t=>{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),cK("nodeSolver",Kn,t=>[{simpleRouteJson:t.srjWithPointPairs,maxGapFillPasses:4}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),cK("nodeDimensionSubdivisionSolver",Tz,t=>[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=>{t.capacityNodes=t.nodeDimensionSubdivisionSolver?.outputNodes??[]}}),cK("edgeSolver",ui,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),cK("availableSegmentPointSolver",ci,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),cK("necessaryCrampedPortPointSolver",sf,t=>[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),cK("splitNodesIntoSingleLayerNodeSolver",aK,t=>[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput()}],{onSolved:t=>{t.capacityNodes=t.splitNodesIntoSingleLayerNodeSolver.getOutput().capacityMeshNodes}}),cK("portPointPathingSolver",jj,t=>{const e=t.splitNodesIntoSingleLayerNodeSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:e.capacityMeshNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.sharedEdgeSegments.flatMap(t=>t.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections,assignableViaObstacles:t.originalSrj.obstacles});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),cK("uniformPortDistributionSolver",go,t=>[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),cK("highDensityRouteSolver",zs,t=>{const e=t.uniformPortDistributionSolver?.getOutput()??[],n=t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],o=e.length>0?e:n;return t.highDensityNodePortPoints=structuredClone(o),[{nodePortPoints:o,nodePfById:new Map((t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[]).map(e=>[e.capacityMeshNodeId,t.portPointPathingSolver?.computeNodePf(e)??null])),colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]}),cK("highDensityForceImproveSolver",Yy,t=>[{nodeWithPortPoints:t.getHighDensityNodePortPointsWithAssignableViasFirst(),hdRoutes:t.getMovableHighDensityRoutes(t.highDensityRouteSolver.routes),colorMap:t.colorMap,totalStepsPerNode:Math.max(20,Math.round(60*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}],{onSolved:t=>{t.highDensityForceImproveRoutes=t.mergeMovableHighDensityRoutesBack(t.highDensityRouteSolver.routes,t.highDensityForceImproveSolver.getOutput())}}),cK("highDensityRepairSolver",AY,t=>[{nodeWithPortPoints:t.getHighDensityNodePortPointsWithAssignableViasFirst(),hdRoutes:t.getMovableHighDensityRoutes(t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes),obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2}],{onSolved:t=>{const e=t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes;t.highDensityRepairRoutes=t.mergeMovableHighDensityRoutesBack(e,t.highDensityRepairSolver.getOutput())}}),cK("highDensityStitchSolver",KY,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRepairRoutes??t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveRoutes??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,allowedLayerTransitionPointKeys:uf(t.originalSrj.obstacles)}]),cK("traceSimplificationSolver",vc,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,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,iterations:2}]),cK("traceWidthSolver",Ic,t=>[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),cK("globalDrcForceImproveSolver",Nz,t=>[{srj:t.srjWithPointPairs,hdRoutes:t.traceWidthSolver.getHdRoutesWithWidths(),effort:t.effort}])];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}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.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.nodeSolver?.visualize(),o=this.nodeDimensionSubdivisionSolver?.visualize(),i=this.nodeTargetMerger?.visualize(),r=this.singleLayerNodeMerger?.visualize(),s=this.strawSolver?.visualize(),a=this.edgeSolver?.visualize(),c=this.deadEndSolver?.visualize(),l=this.availableSegmentPointSolver?.visualize(),d=this.splitNodesIntoSingleLayerNodeSolver?.visualize(),h=this.portPointPathingSolver?.visualize(),u=this.multiSectionPortPointOptimizer?.visualize(),p=this.uniformPortDistributionSolver?.visualize(),m=this.highDensityRouteSolver?.visualize(),g=this.highDensityForceImproveSolver?.visualize(),f=this.highDensityRepairSolver?.visualize(),y=this.highDensityStitchSolver?.visualize(),_=this.traceSimplificationSolver?.visualize(),b=this.necessaryCrampedPortPointSolver?.visualize(),x=(this.highDensityRouteSolver?.visualize(),this.originalSrj),v=x.outline,S=[];if(S.push({points:[{x:x.bounds?.minX??-50,y:x.bounds?.minY??-50},{x:x.bounds?.maxX??50,y:x.bounds?.minY??-50},{x:x.bounds?.maxX??50,y:x.bounds?.maxY??50},{x:x.bounds?.minX??-50,y:x.bounds?.maxY??50},{x:x.bounds?.minX??-50,y:x.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),v&&v.length>=2){const t=v.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),S.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const I=Oo(x),C={points:[...x.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,layer:Fo(e,x.layerCount),label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(x.obstacles??[]).filter(t=>!t.isCopperPour).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)",layer:jo(t,x.layerCount),label:I(t)}))],lines:S},P=Yj({srj:x}),M=[pi(C,P),t,e,n,o,i,r,s,a,c,l,b,d,h,u,p,m?pi(C,m):null,g,f,y,_,this.solved?pi({lines:S},Yj({srj:this.originalSrj}),Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...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}}return this.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){const t=this.globalDrcForceImproveSolver?.getOutput();return t&&this.routesOnlyUsePreplacedVias(t)?t:this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityRepairRoutes??this.highDensityForceImproveRoutes??this.highDensityStitchSolver.mergedHdRoutes}routesOnlyUsePreplacedVias(t){const e=uf(this.originalSrj.obstacles);return 0===e.size||t.every(t=>t.vias.every(t=>e.has(af(t))))}getHighDensityNodePortPointsWithAssignableViasFirst(){return[...this.highDensityNodePortPoints??[]].sort((t,e)=>{const n=t.capacityMeshNodeId.startsWith("assignable-via:");return n===e.capacityMeshNodeId.startsWith("assignable-via:")?0:n?-1:1})}getPreplacedAssignableViaObstacles(){return this.originalSrj.obstacles.filter(t=>!0===t.netIsAssignable&&(t.layers?.length??0)>1)}isFixedPreplacedViaRoute(t){const e=this.getPreplacedAssignableViaObstacles();return 0!==e.length&&0!==t.vias.length&&e.some(e=>[...t.route,...t.vias].every(t=>Be(t,e)<=0))}getMovableHighDensityRouteIndexes(t){return t.map((t,e)=>this.isFixedPreplacedViaRoute(t)?-1:e).filter(t=>-1!==t)}getMovableHighDensityRoutes(t){return this.getMovableHighDensityRouteIndexes(t).map(e=>t[e])}mergeMovableHighDensityRoutesBack(t,e){const n=this.getMovableHighDensityRouteIndexes(t),o=[...t];for(let t=0;t<n.length;t++)o[n[t]]=e[t];return o}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 o=n.__netConnectionName??this.originalSrj.connections.find(t=>t.name===n.name)?.__netConnectionName,i=e.filter(t=>t.connectionName===n.name);for(let e=0;e<i.length;e++){const r=i[e],s={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.__rootConnectionNames?.[0]??n.name,route:Mo(r,this.srj.layerCount,{connectionPoints:n.pointsToConnect,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.srj.obstacles,connMap:this.connMap})};t.push(s)}}return t}getOutputSimpleRouteJson(){return{...this.originalSrj,traces:this.getOutputSimplifiedPcbTraces()}}},dK=(t,e)=>{const n=t.filter(t=>(t.rootConnectionName??t.connectionName)===e);if(0!==n.length)return n.reduce((t,e)=>t+e.route.slice(1).reduce((t,n,o)=>{const i=e.route[o];return t+Math.hypot(n.x-i.x,n.y-i.y)},0),0)},hK=(t,e)=>{const n=new Set(t.flatMap(t=>void 0===t.maxLengthSkew?[]:t.connectionNames));return e.flatMap(t=>{if(!n.has(t.name))return[];const e=t.pointsToConnect[0],o=t.pointsToConnect.at(-1);if(!e||!o||e===o)throw new Error(`Length matching: bus connection "${t.name}" needs at least two points`);return[{...t,pointsToConnect:[e,o]}]})},uK=class extends si{constructor(t){super(),this.params=t,this.differentialPairSolver=new lU({hdRoutes:t.hdRoutes,differentialPairs:t.differentialPairs,obstacles:t.obstacles,bounds:t.bounds,layerCount:t.layerCount,minTraceToPadEdgeClearance:t.obstacleMargin}),this.MAX_ITERATIONS=this.differentialPairSolver.MAX_ITERATIONS+1e5+10}params;differentialPairSolver;busLengthMatchingSolver;outputHdRoutes;getSolverName(){return"LengthMatchingPostProcessingSolver"}_step(){if(!this.differentialPairSolver.solved)return this.differentialPairSolver.step(),void(this.differentialPairSolver.failed&&(this.failed=!0,this.error=this.differentialPairSolver.error));if(!this.busLengthMatchingSolver){const n=this.differentialPairSolver.getOutput().hdRoutes,o=(t=this.params.buses,e=n,t.flatMap(t=>{const n=t.maxLengthSkew;if(void 0===n||t.connectionNames.length<2)return[];const o=t.connectionNames.map(n=>{const o=dK(e,n);if(void 0===o)throw new Error(`Length matching: bus "${t.busId}" has no routed geometry for connection "${n}"`);return{connectionName:n,length:o}}),i=o.reduce((t,e)=>e.length>t.length?e:t);return o.flatMap(t=>t.connectionName===i.connectionName?[]:[{connectionNames:[t.connectionName,i.connectionName],lengthTolerance:n}])}));return 0===o.length?(this.outputHdRoutes=n,void(this.solved=!0)):void(this.busLengthMatchingSolver=new RG({hdRoutes:n,originalConnections:hK(this.params.buses,this.params.connections),differentialPairs:o,obstacles:this.params.obstacles,bounds:this.params.bounds,layerCount:this.params.layerCount,obstacleMargin:this.params.obstacleMargin}))}var t,e;if(this.busLengthMatchingSolver.step(),this.busLengthMatchingSolver.failed)return this.failed=!0,void(this.error=this.busLengthMatchingSolver.error);this.busLengthMatchingSolver.solved&&(this.outputHdRoutes=this.busLengthMatchingSolver.getOutput().matchedHdRoutes,((t,e)=>{for(const n of t){if(void 0===n.maxLengthSkew||n.connectionNames.length<2)continue;const t=n.connectionNames.map(t=>{const o=dK(e,t);if(void 0===o)throw new Error(`Length matching: bus "${n.busId}" lost routed geometry for connection "${t}"`);return o}),o=Math.max(...t)-Math.min(...t);if(o>n.maxLengthSkew+1e-6)throw new Error(`Length matching: bus "${n.busId}" routed length skew ${o.toFixed(4)}mm exceeds ${n.maxLengthSkew.toFixed(4)}mm`)}})(this.params.buses,this.outputHdRoutes),this.solved=!0)}getOutput(){if(!this.solved||!this.outputHdRoutes)throw new Error("LengthMatchingPostProcessingSolver output requested before completion");return{hdRoutes:this.outputHdRoutes}}visualize(){return this.busLengthMatchingSolver?.visualize()??this.differentialPairSolver.visualize()}},pK=1e-9,mK=(t,e)=>Math.abs(t.x-e.x)<=pK&&Math.abs(t.y-e.y)<=pK&&t.z===e.z,gK=(t,e)=>{if(0===t.length)return void t.push(...e.route);const n=t.at(-1);if(e.route[0]&&mK(n,e.route[0]))t.push(...e.route.slice(1));else{if(!e.route.at(-1)||!mK(n,e.route.at(-1)))throw new Error(`Pipeline9 could not reconnect mutated preloaded segment "${e.connectionName}"`);t.push(...e.route.slice(0,-1).reverse())}},fK=(t,e)=>{const n=t.preloadedRoutePositionStart??t.preloadedRouteIndex,o=e.preloadedRoutePositionStart??e.preloadedRouteIndex,i=t.preloadedRoutePositionEnd??n,r=e.preloadedRoutePositionEnd??o;return n-o||i-r||t.preloadedRouteIndex-e.preloadedRouteIndex||t.connectionName.localeCompare(e.connectionName)},yK=t=>{const e=t.route.flatMap(t=>"wire"===t.route_type||"through_obstacle"===t.route_type?[t.width]:[]);return e.length>0?Math.max(...e):void 0},_K=({trace:t,updatedTraceRoutes:e,layerCount:n,defaultViaHoleDiameter:o,obstacles:i,connMap:r})=>{if(0===e.length)throw new Error(`Pipeline9 lost every fixed route for mutated trace "${t.pcb_trace_id}"`);const s=[];let a,c=0,l=0;for(const t of[...e].sort(fK))gK(s,t),c=Math.max(c,t.traceThickness),l=Math.max(l,t.viaDiameter),a??=t.rootConnectionName;const d={connectionName:t.connection_name,rootConnectionName:a,traceThickness:yK(t)??c,viaDiameter:l,route:s,vias:s.slice(0,-1).flatMap((t,e)=>{const n=s[e+1];return t.z!==n.z&&Math.abs(t.x-n.x)<=pK&&Math.abs(t.y-n.y)<=pK?[{x:n.x,y:n.y}]:[]})};return Mo(d,n,{defaultViaHoleDiameter:o,obstacles:i,connMap:r})},bK=(t,e)=>t.filter(t=>{if(!0===t.isThroughObstacle)return!1;const n=t.preloadedRoutePositionStart,o=t.preloadedRoutePositionEnd;if(void 0===n||void 0===o)throw new Error(`Pipeline9 fixed route "${t.connectionName}" is missing route-position metadata`);const i=Math.min(n,o),r=Math.max(n,o);return i>=e.routePositionStart-pK&&r<=e.routePositionEnd+pK}),xK=({trace:t,originalTraceRoutes:e,updatedTraceRoutes:n,layerCount:o,defaultViaHoleDiameter:i,obstacles:r,connMap:s})=>{if(0===n.length)throw new Error(`Pipeline9 lost every fixed route for mutated trace "${t.pcb_trace_id}"`);const a=(t=>{const e=[];let n=0;for(let o=0;o<t.route.length;o++)"through_obstacle"===t.route[o]?.route_type&&(n<o&&e.push({routePositionStart:n,routePositionEnd:o-1}),n=o+1);return n<t.route.length&&e.push({routePositionStart:n,routePositionEnd:t.route.length-1}),e})(t),c=n.filter(t=>!0!==t.isThroughObstacle);for(const t of c){if(1!==a.filter(e=>bK([t],e).includes(t)).length)throw new Error(`Pipeline9 fixed route "${t.connectionName}" crosses an immutable through-obstacle primitive`)}const l=[];let d=0;for(const c of a){l.push(...t.route.slice(d,c.routePositionStart));const a=bK(e,c),h=bK(n,c);if(a.length>0&&0===h.length)throw new Error(`Pipeline9 lost every fixed route for an ordinary section of mutated trace "${t.pcb_trace_id}"`);l.push(...h.length>0?_K({trace:t,updatedTraceRoutes:h,layerCount:o,defaultViaHoleDiameter:i,obstacles:r,connMap:s}):t.route.slice(c.routePositionStart,c.routePositionEnd+1)),d=c.routePositionEnd+1}return l.push(...t.route.slice(d)),l},vK=(t,e)=>{const n=new Set(e.map(t=>t.pcb_trace_id));return t.map(t=>{if(!n.has(t.pcb_trace_id))return n.add(t.pcb_trace_id),t;const e=`${t.pcb_trace_id}_routed`;let o=e,i=2;for(;n.has(o);)o=`${e}_${i}`,i+=1;return n.add(o),{...t,pcb_trace_id:o}})},SK=(t,e,n)=>{const o=t=>`${t.x}:${t.y}`,i=new Map;for(const t of e){const e=o(t.center),n=i.get(e)??[];n.push(t),i.set(e,n)}const r=new Map;for(const e of t)for(const t of e.pointsToConnect){if(!t.pcb_port_id)continue;const e=r.get(t.pcb_port_id)??new Set,s="layers"in t?t.layers:[t.layer];for(const t of s)e.add(ko(t,n));for(const r of i.get(o(t))??[])if(!(r.layers.length<=1)&&r.connectedTo.includes(t.pcb_port_id))for(const t of r.layers)e.add(ko(t,n));r.set(t.pcb_port_id,e)}return r},IK=(t,e)=>new Map(t.flatMap(t=>{const n=e.getNetConnectedToId(t.connectionName)??(t.rootConnectionName?e.getNetConnectedToId(t.rootConnectionName)??(e.netMap[t.rootConnectionName]?t.rootConnectionName:void 0):void 0);return n?[[t.connectionName,n]]:[]})),CK=1e-9,PK=1e-6,MK=(t,e)=>Math.abs(t.x-e.x)<=PK&&Math.abs(t.y-e.y)<=PK&&t.z===e.z,NK=t=>new Map(t.map((t,e)=>[t.pcb_trace_id,e])),wK=(t,e)=>{const n=t[0],o=t.at(-1);if(!n||!o)throw new Error("Pipeline9 cannot split an empty preloaded route");if(n.z!==o.z)throw new Error("Pipeline9 cannot partially split a preloaded layer transition");return{...n,x:n.x+(o.x-n.x)*e,y:n.y+(o.y-n.y)*e}},TK=({traces:t,fixedHdRoutes:e,sections:n})=>{const o=(({traces:t,sections:e})=>{const n=NK(t),o=new Map;for(const t of e){const e=n.get(t.traceId);if(void 0===e)throw new Error(`Pipeline9 hypergraph changed missing preloaded trace "${t.traceId}"`);const i=o.get(e)??[];i.push({start:Math.min(t.startRoutePosition,t.endRoutePosition),end:Math.max(t.startRoutePosition,t.endRoutePosition)}),o.set(e,i)}for(const t of o.values())t.sort((t,e)=>t.start-e.start||t.end-e.end);return o})({traces:t,sections:n});return e.flatMap(t=>{const e=o.get(t.preloadedTraceIndex);if(!e?.length)return[t];const n=t.preloadedRoutePositionStart,i=t.preloadedRoutePositionEnd;if(void 0===n||void 0===i)throw new Error(`Pipeline9 fixed route "${t.connectionName}" is missing route-position metadata`);if(Math.abs(i-n)<=CK)return e.some(t=>t.start-CK<=n&&n<=t.end+CK)?[]:[t];let r=[{start:n,end:i}];for(const t of e)r=r.flatMap(e=>{if(t.end<=e.start+CK||t.start>=e.end-CK)return[e];const n=[];return t.start>e.start+CK&&n.push({start:e.start,end:Math.min(t.start,e.end)}),t.end<e.end-CK&&n.push({start:Math.max(t.end,e.start),end:e.end}),n});return r.map((e,o)=>{const r=(e.start-n)/(i-n),s=(e.end-n)/(i-n);return{...t,connectionName:`${t.connectionName}_hypergraph_fixed_${o}`,preloadedRoutePositionStart:e.start,preloadedRoutePositionEnd:e.end,route:[wK(t.route,r),wK(t.route,s)],vias:[]}})})},RK=({traces:t,sections:e,stitchedHdRoutes:n,layerCount:o})=>{const i=NK(t);return e.map((t,r)=>{const s=i.get(t.traceId);if(void 0===s)throw new Error(`Pipeline9 cannot materialize missing preloaded trace "${t.traceId}"`);const[a,c]=((t,e)=>{const n=t.connection.pointsToConnect.map(t=>({x:t.x,y:t.y,z:ko(bo(t),e)}));if(!n[0]||!n[1])throw new Error(`Pipeline9 changed section "${t.connectionName}" is missing an endpoint`);return[n[0],n[1]]})(t,o),l=n.flatMap(e=>{if(e.connectionName!==t.connectionName)return[];const n=(({route:t,sectionStart:e,sectionEnd:n})=>{const o=t.route[0],i=t.route.at(-1);if(!o||!i)return null;const r=o.z===e.z&&i.z===n.z,s=o.z===n.z&&i.z===e.z,a=r?xe(o,e)+xe(i,n):Number.POSITIVE_INFINITY,c=s?xe(o,n)+xe(i,e):Number.POSITIVE_INFINITY;return Number.isFinite(a)||Number.isFinite(c)?a<=c?{score:a,reverse:!1}:{score:c,reverse:!0}:null})({route:e,sectionStart:a,sectionEnd:c});return n?[{route:e,...n}]:[]});l.sort((t,e)=>t.score-e.score);const d=l[0],h=l[1];if(!d||h&&Math.abs(h.score-d.score)<=PK)throw new Error(`Pipeline9 expected one nearest stitched route for changed preloaded section "${t.connectionName}", got ${l.length}`);const u=(({route:t,reverse:e,sectionStart:n,sectionEnd:o})=>{const i=e?(t=>{const e=[...t].reverse().map(t=>{const{toNextSegmentType:e,...n}=t;return n});for(let n=0;n<t.length-1;n++){const o=t[n]?.toNextSegmentType;o&&(e[t.length-n-2]={...e[t.length-n-2],toNextSegmentType:o})}return e})(t.route):[...t.route];if(!i[0]||!i.at(-1))throw new Error(`Pipeline9 cannot materialize empty route "${t.connectionName}"`);return MK(i[0],n)||i.unshift(n),MK(i.at(-1),o)||i.push(o),{...t,route:i}})({route:d.route,reverse:d.reverse,sectionStart:a,sectionEnd:c});return{...u,preloadedTraceIndex:s,preloadedRouteIndex:Number.MAX_SAFE_INTEGER-e.length+r,preloadedRoutePositionStart:t.startRoutePosition,preloadedRoutePositionEnd:t.endRoutePosition,isThroughObstacle:!1}})},EK=1e-6,AK=t=>t.map(t=>{const e=[];for(const n of t.route){const o=e.at(-1);if(!o||o.z===n.z||"through_obstacle"===o.toNextSegmentType){e.push(n);continue}const i=Math.abs(o.x-n.x)<=EK&&Math.abs(o.y-n.y)<=EK,r=t.vias.some(t=>Math.abs(t.x-o.x)<=EK&&Math.abs(t.y-o.y)<=EK),s=t.vias.some(t=>Math.abs(t.x-n.x)<=EK&&Math.abs(t.y-n.y)<=EK);if(i)e.push(n);else{if(!r&&!s)throw new Error(`Pipeline9 route "${t.connectionName}" changes layers from z=${o.z} to z=${n.z} without an explicit via`);if(r===s)throw new Error(`Pipeline9 route "${t.connectionName}" has an ambiguous layer transition between (${o.x}, ${o.y}) and (${n.x}, ${n.y})`);r?e.push({x:o.x,y:o.y,z:n.z}):e.push({x:n.x,y:n.y,z:o.z}),e.push(n)}}return{...t,route:e}}),OK=1e-9,kK=t=>({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}),LK=(t,e)=>t.x>=e.minX-OK&&t.x<=e.maxX+OK&&t.y>=e.minY-OK&&t.y<=e.maxY+OK,DK=(t,e,n)=>n<=OK?t:n>=.999999999?e:{x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n,z:t.z},zK=(t,e,n)=>{const o=e.x-t.x,i=e.y-t.y;if(Math.abs(o)<=OK&&Math.abs(i)<=OK)return LK(t,n)&&LK(e,n)?{start:t,end:e}:null;let r=0,s=1;const a=[[-o,t.x-n.minX],[o,n.maxX-t.x],[-i,t.y-n.minY],[i,n.maxY-t.y]];for(const[t,e]of a){if(Math.abs(t)<=OK){if(e<0)return null;continue}const n=e/t;if(t<0?r=Math.max(r,n):s=Math.min(s,n),r>s+OK)return null}return{start:DK(t,e,r),end:DK(t,e,s)}},FK=t=>{const e=t.sourceRoutes[0],n=`pipeline9_fallback:${e.connectionName}`,o=`${n}:start`,i=`${n}:end`;return[{...t.start.point,portPointId:o,nextPortPointId:i,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName},{...t.end.point,portPointId:i,prevPortPointId:o,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName}]},BK=(t,e)=>Math.abs(t.x-e.x)<=OK&&Math.abs(t.y-e.y)<=OK&&t.z===e.z,jK=(t,e)=>t.sourceRoute.preloadedTraceIndex===e.sourceRoute.preloadedTraceIndex&&BK(t.sourceRoute.route.at(-1),e.sourceRoute.route[0]),$K=(t,e,n=new Set)=>{const o=new Map,i=[],r=new Set(t.portPoints.map(t=>t.z)),s=e.map(e=>((t,e)=>{const n=kK(e);let o,i;for(let e=0;e<t.route.length-1;e++){const r=zK(t.route[e],t.route[e+1],n);r&&(o??={segmentIndex:e,point:r.start},i={segmentIndex:e,point:r.end})}return o&&i?Math.abs(o.point.x-i.point.x)<=OK&&Math.abs(o.point.y-i.point.y)<=OK&&o.point.z===i.point.z?null:{sourceRoute:t,start:o,end:i}:null})(e,t)).filter(t=>null!==t),a=s.filter(t=>!0!==t.sourceRoute.isThroughObstacle&&(((t,e)=>0===e.size||[t.start.point,...t.sourceRoute.route.slice(t.start.segmentIndex+1,t.end.segmentIndex+1),t.end.point].some(t=>e.has(t.z)))(t,r)||n.has(t.sourceRoute.connectionName))).sort((t,e)=>t.sourceRoute.preloadedTraceIndex-e.sourceRoute.preloadedTraceIndex||t.sourceRoute.preloadedRouteIndex-e.sourceRoute.preloadedRouteIndex),c=new Set(a.map(t=>t.sourceRoute)),l=s.map(t=>t.sourceRoute).filter(t=>!c.has(t)),d=[];for(let t=0;t<a.length;t++){const e=a[t],n=a[t-1],o=d.at(-1);n&&o&&jK(n,e)?(o.sourceRoutes.push(e.sourceRoute),o.end=e.end):d.push({sourceRoutes:[e.sourceRoute],start:e.start,end:e.end})}for(const t of d){const e=t.sourceRoutes[0].connectionName;if(o.has(e))throw new Error(`Pipeline9 regional fallback found duplicate fixed route section identity "${e}"`);o.set(e,t),i.push(FK(t))}return{nodeWithPortPoints:{...t,portPoints:[...t.portPoints,...i.flatMap(t=>t)],portPointsInPairs:[...t.portPointsInPairs??[],...i]},fixedRouteSectionsByConnectionName:o,fixedObstacleRoutes:l}},YK=t=>{const e=[];for(let n=0;n<t.length-1;n++){const o=t[n],i=t[n+1];o.z!==i.z&&Math.abs(o.x-i.x)<=OK&&Math.abs(o.y-i.y)<=OK&&e.push({x:i.x,y:i.y})}return e},XK=(t,e)=>VK({section:t,replacement:e,sourceMutationMasks:new Map,replacementIsMutated:!1}).route,VK=({section:t,replacement:e,sourceMutationMasks:n,replacementIsMutated:o})=>{const i=t.sourceRoutes[0],r=t.sourceRoutes.at(-1),s=((t,e)=>{const n=t.route,o=n[0],i=n.at(-1);if(!o||!i)throw new Error(`Pipeline9 regional fallback produced an empty replacement for "${e.sourceRoutes[0].connectionName}"`);const r=Math.hypot(o.x-e.start.point.x,o.y-e.start.point.y)+Math.hypot(i.x-e.end.point.x,i.y-e.end.point.y);return Math.hypot(i.x-e.start.point.x,i.y-e.start.point.y)+Math.hypot(o.x-e.end.point.x,o.y-e.end.point.y)<r?[...n].reverse():n})(e,t),a=[],c=[],l=(t,e)=>{const o=n.get(t.connectionName);if(o&&o.length!==t.route.length-1)throw new Error(`Pipeline9 fixed route mutation mask for "${t.connectionName}" has ${o.length} segments, expected ${t.route.length-1}`);return o?.[e]??!1},d=(t,e)=>{const n=a.at(-1);if(n){if(!BK(n,t)){if(n.z!==t.z&&(Math.abs(n.x-t.x)>OK||Math.abs(n.y-t.y)>OK)){const o={...t,z:n.z};BK(n,o)||(a.push(o),c.push(e))}BK(a.at(-1),t)||(a.push(t),c.push(e))}}else a.push(t)};d(i.route[0],!1);for(let e=1;e<=t.start.segmentIndex;e++)d(i.route[e],l(i,e-1));d(t.start.point,l(i,t.start.segmentIndex));const h=c.length;for(const t of s.slice(1,-1))d(t,o);d(t.end.point,o);const u=c.length>h;for(let e=t.end.segmentIndex+1;e<r.route.length;e++)d(r.route[e],l(r,e-1));if(c.length!==a.length-1)throw new Error(`Pipeline9 produced an invalid mutation mask while splicing "${i.connectionName}"`);return{route:{...i,preloadedRoutePositionStart:i.preloadedRoutePositionStart,preloadedRoutePositionEnd:r.preloadedRoutePositionEnd,traceThickness:Math.max(...t.sourceRoutes.map(t=>t.traceThickness)),viaDiameter:Math.max(...t.sourceRoutes.map(t=>t.viaDiameter)),route:a,vias:YK(a)},mutatedSegments:c,replacementProducedSegment:u}},WK=1e-6,HK=(t,e)=>Math.abs(t.x-e.x)<=WK&&Math.abs(t.y-e.y)<=WK&&t.z===e.z,GK=(t,e)=>{for(const n of e)t.at(-1)&&HK(t.at(-1),n)||t.push(n)},UK=t=>t.slice(0,-1).flatMap((e,n)=>{const o=t[n+1];return e.z!==o.z&&Math.abs(e.x-o.x)<=WK&&Math.abs(e.y-o.y)<=WK?[{x:o.x,y:o.y}]:[]}),ZK=t=>{const e=t.preloadedRoutePositionStart,n=t.preloadedRoutePositionEnd;if(void 0===e||void 0===n)throw new Error(`Pipeline9 fixed route "${t.connectionName}" is missing route-position metadata`);return{start:Math.min(e,n),end:Math.max(e,n)}},qK=(t,e)=>{const n=ZK(t),o=ZK(e);return t.preloadedTraceIndex-e.preloadedTraceIndex||n.start-o.start||n.end-o.end||t.preloadedRouteIndex-e.preloadedRouteIndex||t.connectionName.localeCompare(e.connectionName)},JK=(t,e)=>{const n=t.route.at(-1),o=e.route[0];return Boolean(n&&o&&t.preloadedTraceIndex===e.preloadedTraceIndex&&HK(n,o))},KK=(t,e)=>{const n=t.preloadedRoutePositionStart??t.preloadedRouteIndex;return n+((t.preloadedRoutePositionEnd??t.preloadedRouteIndex)-n)*e/(t.route.length-1)},QK=(t,e)=>t.route[e].z!==t.route[e+1].z,tQ=({updatedFixedRoutes:t,regionalMutationMasks:e})=>{const n=[],o=(({updatedFixedRoutes:t,regionalMutationMasks:e})=>{const n=new Map;for(const o of t){if(0===o.route.length)throw new Error(`Pipeline9 cannot normalize empty fixed route "${o.connectionName}"`);const t=o.route.length-1;if(n.has(o.connectionName))throw new Error(`Pipeline9 cannot normalize duplicate fixed route "${o.connectionName}"`);const i=e.get(o.connectionName);if(i&&i.length!==t)throw new Error(`Pipeline9 fixed route mutation mask for "${o.connectionName}" has ${i.length} segments, expected ${t}`);const r=!0!==o.isThroughObstacle&&0===(o.jumpers?.length??0);n.set(o.connectionName,Array.from({length:t},(t,e)=>r&&(i?.[e]??!1)))}let o=[];const i=()=>{for(;o[0]&&QK(o[0].route,o[0].segmentIndex);){const t=o.shift();n.get(t.route.connectionName)[t.segmentIndex]=!1}for(;o.at(-1)&&QK(o.at(-1).route,o.at(-1).segmentIndex);){const t=o.pop();n.get(t.route.connectionName)[t.segmentIndex]=!1}o=[]};let r;for(const e of[...t].sort(qK)){r&&!JK(r,e)&&i();const t=n.get(e.connectionName);if(0!==t.length){for(let n=0;n<t.length;n++)t[n]?o.push({route:e,segmentIndex:n}):i();r=e}else i(),r=e}return i(),n})({updatedFixedRoutes:t,regionalMutationMasks:e});for(const e of t){const t=e.route.length-1,i=o.get(e.connectionName);if(0===t){n.push({route:e,mutated:!1});continue}const r=[];for(let e=0;e<t;e++){const t=i[e],n=r.at(-1);n?.mutated===t?n.end=e+1:r.push({start:e,end:e+1,mutated:t})}for(const[t,o]of r.entries()){const i=e.route.slice(o.start,o.end+1),s={...e,connectionName:1===r.length?e.connectionName:`${e.connectionName}_mutation_fragment_${t}`,preloadedRouteIndex:e.preloadedRouteIndex+t/(r.length+1),preloadedRoutePositionStart:KK(e,o.start),preloadedRoutePositionEnd:KK(e,o.end),route:i,vias:UK(i)};n.push({route:s,mutated:o.mutated})}}return n},eQ=({updatedFixedRoutes:t,regionalMutationMasks:e})=>{const n=tQ({updatedFixedRoutes:t,regionalMutationMasks:e}),o=n.map(({route:t})=>t),i=(t=>{const e=[];let n;for(const o of[...t].sort((t,e)=>qK(t.route,e.route))){const t=o.route;if(!o.mutated){n=void 0;continue}const i=t.route[0],r=t.route.at(-1);if(!i||!r||t.route.length<2)throw new Error(`Pipeline9 cannot simplify empty fixed route "${t.connectionName}"`);const s=n?.sourceRoutes.at(-1);n&&s&&JK(s,t)?(n.sourceRoutes.push(t),n.end={segmentIndex:t.route.length-2,point:r}):(n={sourceRoutes:[t],start:{segmentIndex:0,point:i},end:{segmentIndex:t.route.length-2,point:r}},e.push(n))}return e})(n),r=i.map((t,e)=>{const n=((t,e)=>{const n=t.sourceRoutes[0],o=t.sourceRoutes.at(-1);if(!n||!o)throw new Error("Pipeline9 cannot simplify an empty mutation section");const i=[t.start.point];for(const[e,n]of t.sourceRoutes.entries()){const o=0===e,r=e===t.sourceRoutes.length-1,s=o?t.start.segmentIndex+1:0,a=r?t.end.segmentIndex+1:n.route.length;GK(i,n.route.slice(s,a))}if(GK(i,[t.end.point]),i.length<2)throw new Error(`Pipeline9 mutation section for "${n.connectionName}" has no routable span`);return{connectionName:`pipeline9_mutated_preload_${n.preloadedTraceIndex}_${e}`,rootConnectionName:n.rootConnectionName,traceThickness:Math.max(...t.sourceRoutes.map(t=>t.traceThickness)),viaDiameter:Math.max(...t.sourceRoutes.map(t=>t.viaDiameter)),route:i,vias:UK(i)}})(t,e);return{connectionName:n.connectionName,section:t,hdRoute:n}}),s=new Set(r.flatMap(({section:t})=>t.sourceRoutes.map(t=>t.connectionName)));return{sections:r,immutableHdRoutes:o.filter(t=>!s.has(t.connectionName)),normalizedFixedRoutes:o}},nQ=1e-9,oQ=(t,e,n,o,i)=>{const r=i.getNetConnectedToId(t.connection_name)??t.connection_name,s=[],a=(n,i,a=o,c=[],l,d,h=!1)=>{n.length<2||s.push({connectionName:`${t.connection_name}_fixed_${e}_${s.length}`,rootConnectionName:r,preloadedTraceIndex:e,preloadedRouteIndex:s.length,preloadedRoutePositionStart:l,preloadedRoutePositionEnd:d,isThroughObstacle:h,traceThickness:Math.max(nQ,i),viaDiameter:Math.max(nQ,a),route:n,vias:c})};for(let e=0;e<t.route.length;e++){const i=t.route[e];if("via"===i.route_type){a([{x:i.x,y:i.y,z:ko(i.from_layer,n)},{x:i.x,y:i.y,z:ko(i.to_layer,n)}],nQ,i.via_diameter??o,[{x:i.x,y:i.y}],e,e);continue}if("through_obstacle"===i.route_type){const t=ko(i.from_layer,n),r=ko(i.to_layer,n);for(let n=Math.min(t,r);n<=Math.max(t,r);n++)a([{...i.start,z:n},{...i.end,z:n}],i.width,o,[],e,e+1,!0);continue}const r=t.route[e+1];"wire"===i.route_type&&"wire"===r?.route_type&&i.layer===r.layer&&a([{x:i.x,y:i.y,z:ko(i.layer,n)},{x:r.x,y:r.y,z:ko(r.layer,n)}],Math.max(i.width,r.width),o,[],e,e+1)}return s};function iQ(t,e){return{x:t.a*e.x+t.b*e.y+t.c,y:t.d*e.x+t.e*e.y+t.f}}var rQ={highResolutionCellSize:.1,highResolutionCellThickness:8,lowResolutionCellSize:.4,traceMargin:.15,traceThickness:.1,viaDiameter:.3,viaMinDistFromBorder:.15},sQ={...rQ},aQ=(t,e,n)=>{const[o,i]=t;if(o===i)return;const r=((t,e)=>{const n=t.portPointId??`${t.connectionName}:${t.x}:${t.y}:${t.z}`,o=e.portPointId??`${e.connectionName}:${e.x}:${e.y}:${e.z}`;return n<o?`${n}|${o}`:`${o}|${n}`})(o,i);e.has(r)||(e.add(r),n.push(t))},cQ=(t,e,n)=>{for(let o=0;o<t.length-1;o++)aQ([t[o],t[o+1]],e,n)},lQ=t=>{const e=[],n=new Set,o=(t=>{const e=new Map;for(const n of t)n.portPointId&&e.set(n.portPointId,n);return e})(t);for(const i of t){if(i.prevPortPointId){const t=o.get(i.prevPortPointId);t&&t.connectionName===i.connectionName&&aQ([t,i],n,e)}if(i.nextPortPointId){const t=o.get(i.nextPortPointId);t&&t.connectionName===i.connectionName&&aQ([i,t],n,e)}}if(0===e.length)return cQ(t,n,e),e;const i=(t=>{const e=new Set;for(const[n,o]of t)n.portPointId&&e.add(n.portPointId),o.portPointId&&e.add(o.portPointId);return e})(e),r=t.filter(t=>!t.portPointId||!i.has(t.portPointId));return cQ(r,n,e),e};function dQ(t,e,n){return Math.max(e,Math.min(n,t))}var hQ=["left","top","right","bottom","middle"],uQ=class{f=new Float64Array(1024);seq=new Uint32Array(1024);id=new Int32Array(1024);n=0;push(t,e,n){this.ensureCapacity(this.n+1);let o=this.n++;for(this.f[o]=t,this.seq[o]=e,this.id[o]=n;o>0;){const t=o-1>>1;if(this.less(t,o))break;this.swap(o,t),o=t}}pop(){const t=this.id[0];return this.n--,this.n>0&&(this.f[0]=this.f[this.n],this.seq[0]=this.seq[this.n],this.id[0]=this.id[this.n],this.siftDown(0)),t}get size(){return this.n}clear(){this.n=0}ensureCapacity(t){if(t<=this.f.length)return;let e=this.f.length;for(;e<t;)e*=2;const n=new Float64Array(e);n.set(this.f),this.f=n;const o=new Uint32Array(e);o.set(this.seq),this.seq=o;const i=new Int32Array(e);i.set(this.id),this.id=i}siftDown(t){for(;;){const e=2*t+1,n=e+1;if(e>=this.n)return;let o=e;if(n<this.n&&!this.less(e,n)&&(o=n),this.less(t,o))return;this.swap(t,o),t=o}}less(t,e){const n=this.f[t],o=this.f[e];return n!==o?n<o:this.seq[t]<this.seq[e]}swap(t,e){const n=this.f[t];this.f[t]=this.f[e],this.f[e]=n;const o=this.seq[t];this.seq[t]=this.seq[e],this.seq[e]=o;const i=this.id[t];this.id[t]=this.id[e],this.id[e]=i}},pQ=class{z=new Int32Array(1024);cellId=new Int32Array(1024);g=new Float64Array(1024);parent=new Int32Array(1024);ripHead=new Int32Array(1024).fill(-1);ripCount=new Int32Array(1024);length=0;clear(){this.length=0}push(t,e,n,o,i,r){this.ensureCapacity(this.length+1);const s=this.length++;return this.z[s]=t,this.cellId[s]=e,this.g[s]=n,this.parent[s]=o,this.ripHead[s]=i,this.ripCount[s]=r,s}ensureCapacity(t){if(t<=this.z.length)return;let e=this.z.length;for(;e<t;)e*=2;const n=new Int32Array(e);n.set(this.z),this.z=n;const o=new Int32Array(e);o.set(this.cellId),this.cellId=o;const i=new Float64Array(e);i.set(this.g),this.g=i;const r=new Int32Array(e);r.set(this.parent),this.parent=r;const s=new Int32Array(e);s.fill(-1),s.set(this.ripHead.subarray(0,this.length)),this.ripHead=s;const a=new Int32Array(e);a.set(this.ripCount.subarray(0,this.length)),this.ripCount=a}},mQ=class{connId=new Int32Array(1024);prev=new Int32Array(1024).fill(-1);length=0;clear(){this.length=0}append(t,e){this.ensureCapacity(this.length+1);const n=this.length++;return this.connId[n]=e,this.prev[n]=t,n}contains(t,e){for(let n=t;n>=0;n=this.prev[n])if(this.connId[n]===e)return!0;return!1}collect(t,e){e.length=0;for(let n=t;n>=0;n=this.prev[n])e.push(this.connId[n])}ensureCapacity(t){if(t<=this.connId.length)return;let e=this.connId.length;for(;e<t;)e*=2;const n=new Int32Array(e);n.set(this.connId),this.connId=n;const o=new Int32Array(e);o.fill(-1),o.set(this.prev.subarray(0,this.length)),this.prev=o}};function gQ(t,e){return e??t.replace(/_mst\d+$/,"")}function fQ(t,e){const n=t.x-e.center.x,o=t.y-e.center.y,i=Math.cos(-e.rotationRadians),r=Math.sin(-e.rotationRadians);return{x:n*i-o*r,y:n*r+o*i}}function yQ(t){return{minX:-t.width/2,minY:-t.height/2,maxX:t.width/2,maxY:t.height/2}}function _Q(t,e,n){return Math.max(e,Math.min(n,t))}function bQ(t,e){for(let n=0;n<t.length;n++)if(t[n]===e)return;t.push(e)}function xQ(t,e){for(let n=0;n<t.length;n++)if(t[n].cellId===e.cellId)return;t.push(e)}function vQ(t,e,n,o,i,r,s){const a=t-_Q(t,o,r),c=e-_Q(e,i,s);return a*a+c*c<=n*n}function SQ(t){const e=t.segmentEnd.x-t.segmentStart.x,n=t.segmentEnd.y-t.segmentStart.y,o=e**2+n**2;if(0===o)return(t.point.x-t.segmentStart.x)**2+(t.point.y-t.segmentStart.y)**2;const i=_Q(((t.point.x-t.segmentStart.x)*e+(t.point.y-t.segmentStart.y)*n)/o,0,1),r=t.segmentStart.x+i*e,s=t.segmentStart.y+i*n;return(t.point.x-r)**2+(t.point.y-s)**2}function IQ(t){const e=_Q(t.point.x,t.rect.minX,t.rect.maxX),n=_Q(t.point.y,t.rect.minY,t.rect.maxY),o=t.point.x-e,i=t.point.y-n;return o*o+i*i}function CQ(t){return(t.second.x-t.first.x)*(t.third.y-t.first.y)-(t.second.y-t.first.y)*(t.third.x-t.first.x)}function PQ(t){return!(Math.abs(CQ({first:t.segmentStart,second:t.segmentEnd,third:t.point}))>1e-9)&&(t.point.x>=Math.min(t.segmentStart.x,t.segmentEnd.x)&&t.point.x<=Math.max(t.segmentStart.x,t.segmentEnd.x)&&t.point.y>=Math.min(t.segmentStart.y,t.segmentEnd.y)&&t.point.y<=Math.max(t.segmentStart.y,t.segmentEnd.y))}function MQ(t){const e=CQ({first:t.firstStart,second:t.firstEnd,third:t.secondStart}),n=CQ({first:t.firstStart,second:t.firstEnd,third:t.secondEnd}),o=CQ({first:t.secondStart,second:t.secondEnd,third:t.firstStart}),i=CQ({first:t.secondStart,second:t.secondEnd,third:t.firstEnd});return e*n<0&&o*i<0||(PQ({point:t.secondStart,segmentStart:t.firstStart,segmentEnd:t.firstEnd})||PQ({point:t.secondEnd,segmentStart:t.firstStart,segmentEnd:t.firstEnd})||PQ({point:t.firstStart,segmentStart:t.secondStart,segmentEnd:t.secondEnd})||PQ({point:t.firstEnd,segmentStart:t.secondStart,segmentEnd:t.secondEnd}))}function NQ(t){return MQ(t)?0:Math.min(SQ({point:t.firstStart,segmentStart:t.secondStart,segmentEnd:t.secondEnd}),SQ({point:t.firstEnd,segmentStart:t.secondStart,segmentEnd:t.secondEnd}),SQ({point:t.secondStart,segmentStart:t.firstStart,segmentEnd:t.firstEnd}),SQ({point:t.secondEnd,segmentStart:t.firstStart,segmentEnd:t.firstEnd}))}function wQ(t){if(function(t){if(0===IQ({point:t.segmentStart,rect:t.rect})||0===IQ({point:t.segmentEnd,rect:t.rect}))return!0;const e=[{x:t.rect.minX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.maxY},{x:t.rect.minX,y:t.rect.maxY}];for(let n=0;n<e.length;n++){const o=(n+1)%e.length;if(MQ({firstStart:t.segmentStart,firstEnd:t.segmentEnd,secondStart:e[n],secondEnd:e[o]}))return!0}return!1}(t))return!0;const e=t.radius**2;if(IQ({point:t.segmentStart,rect:t.rect})<=e||IQ({point:t.segmentEnd,rect:t.rect})<=e)return!0;return[{x:t.rect.minX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.minY},{x:t.rect.maxX,y:t.rect.maxY},{x:t.rect.minX,y:t.rect.maxY}].some(n=>SQ({point:n,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd})<=e)}var TQ=class extends kt{getSolverName(){return"HighDensitySolverB01"}nodeWithPortPoints;obstacles;highResolutionCellSize;highResolutionCellThickness;lowResolutionCellSize;viaDiameter;MAX_RIPS;maxCellCount;traceThickness;traceMargin;obstacleClearanceMargin;viaMinDistFromBorder;showPenaltyMap;showUsedCellMap;effort;stepMultiplier;hyperParameters;initialPenaltyFn;boundsMinX;boundsMaxX;boundsMinY;boundsMaxY;gridToBoundsTransform;availableZ;zToLayer;layerToZ;layers;fineRows;fineCols;lowScale;bandRows;bandCols;regions;planeSize;cellCenterX;cellCenterY;cellMinX;cellMinY;cellMaxX;cellMaxY;cellWidth;cellHeight;cellRegion;cellRow;cellCol;viaAllowed;neighborOffset;neighborIds;neighborCosts;usedCellsFlat;sharedCellsFlat;portOwnerFlat;penalty2d;ripStateBuckets;visitedStamp;bestGStamp;bestGValue;visitedFlatStamp;sharedCrossRootPortFlat;stamp=0;connNameToId;connIdToName;connIdToRootNet;overlapFriendlyRootNets;usedIndicesByConn;unsolvedSegs;solvedRoutes;activeConnSeg=null;activeConnId=-1;nodePool;heap;ripChain;seqCounter=0;_viaOccs=[];_cellOccs=[];_rippedIds=[];ripCount;totalRipEvents=0;searchIterations=0;consecutiveSkips=0;penaltyCap;baseSearchBudgetIters;_moveCost=0;_moveRippedHead=-1;_moveRipCount=0;traceKeepoutRadius;viaKeepoutRadius;obstacleTraceRootIdsFlat;obstacleViaRootIdsByCell;obstacleRootNameToId;obstacleRootNames;obstacleTracePrimitives;obstacleViaPrimitives;obstacleRectPrimitives;obstacleTraceBlockedCellCount=0;obstacleViaBlockedCellCount=0;get unsolvedConnections(){return this.unsolvedSegs}get solvedConnectionsMap(){const t=new Map;for(let e=0;e<this.solvedRoutes.length;e++){const n=this.getSolvedRoutesForConn(e);n.length>0&&t.set(e,n)}return t}get activeConnection(){if(!this.activeConnSeg)return null;const t=this.activeConnSeg.startCellId,e=this.activeConnSeg.endCellId;return{connectionName:this.connIdToName[this.activeConnSeg.connId]??"",start:{cellId:t,region:hQ[this.cellRegion[t]],row:this.cellRow[t],col:this.cellCol[t],x:this.cellCenterX[t],y:this.cellCenterY[t],z:this.activeConnSeg.startZ},end:{cellId:e,region:hQ[this.cellRegion[e]],row:this.cellRow[e],col:this.cellCol[e],x:this.cellCenterX[e],y:this.cellCenterY[e],z:this.activeConnSeg.endZ}}}get openSet(){return{length:this.heap?.size??0}}get gridStats(){return{cells:this.planeSize||0,layers:this.layers||0,states:(this.planeSize||0)*(this.layers||0),ripStateBuckets:this.ripStateBuckets||0,neighborEdges:this.neighborIds?.length??0,regionCounts:this.regions?Object.fromEntries(this.regions.map(t=>[t.name,t.rows*t.cols])):{},obstacleTraceBlockedCells:this.obstacleTraceBlockedCellCount,obstacleViaBlockedCells:this.obstacleViaBlockedCellCount,obstacleRootCount:this.obstacleRootNames?.length??0,obstacleRectCount:this.obstacleRectPrimitives?.length??0}}constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.obstacles=t.obstacles,this.highResolutionCellSize=t.highResolutionCellSize??.1,this.highResolutionCellThickness=Math.max(1,Math.floor(t.highResolutionCellThickness??8)),this.lowResolutionCellSize=t.lowResolutionCellSize??.4,this.viaDiameter=t.viaDiameter,this.maxCellCount=t.maxCellCount,this.traceThickness=t.traceThickness??.1,this.traceMargin=t.traceMargin??.15,this.obstacleClearanceMargin=t.obstacleClearanceMargin??0,this.viaMinDistFromBorder=t.viaMinDistFromBorder??.15,this.showPenaltyMap=t.showPenaltyMap??!1,this.showUsedCellMap=t.showUsedCellMap??!1,this.effort=t.effort??1,this.stepMultiplier=Math.max(1,Math.floor(t.stepMultiplier??1)),this.hyperParameters={shuffleSeed:0,ripCost:8,ripTracePenalty:.5,ripViaPenalty:.75,viaBaseCost:.1,greedyMultiplier:1.5,sameRootObstacleCostMultiplier:1,...t.hyperParameters},this.MAX_ITERATIONS=1e8,this.MAX_RIPS=200,this.initialPenaltyFn=t.initialPenaltyFn}getConstructorParams(){return[{nodeWithPortPoints:this.nodeWithPortPoints,obstacles:this.obstacles,highResolutionCellSize:this.highResolutionCellSize,highResolutionCellThickness:this.highResolutionCellThickness,lowResolutionCellSize:this.lowResolutionCellSize,viaDiameter:this.viaDiameter,maxCellCount:this.maxCellCount,stepMultiplier:this.stepMultiplier,traceThickness:this.traceThickness,traceMargin:this.traceMargin,obstacleClearanceMargin:this.obstacleClearanceMargin,viaMinDistFromBorder:this.viaMinDistFromBorder,showPenaltyMap:this.showPenaltyMap,showUsedCellMap:this.showUsedCellMap,effort:this.effort,hyperParameters:this.hyperParameters,initialPenaltyFn:this.initialPenaltyFn}]}_setup(){const{nodeWithPortPoints:t}=this,{width:e,height:n,center:o}=t;if(e>15||n>15)return this.error=`HighDensitySolverB01 only supports routing windows up to 15x15mm; received ${e}x${n}mm`,void(this.failed=!0);const i=this.lowResolutionCellSize/this.highResolutionCellSize,r=Math.round(i);if(!Number.isFinite(i)||i<=0||Math.abs(i-r)>1e-9)return this.error="lowResolutionCellSize must be a positive integer multiple of highResolutionCellSize",void(this.failed=!0);this.lowScale=Math.max(1,r),this.availableZ=t.availableZ??[...new Set(t.portPoints.map(t=>t.z))].sort((t,e)=>t-e),this.layers=this.availableZ.length,this.zToLayer=new Map,this.layerToZ=new Map;for(let t=0;t<this.availableZ.length;t++){const e=this.availableZ[t];this.zToLayer.set(e,t),this.layerToZ.set(t,e)}this.boundsMinX=o.x-e/2,this.boundsMaxX=o.x+e/2,this.boundsMinY=o.y-n/2,this.boundsMaxY=o.y+n/2,this.traceKeepoutRadius=this.traceMargin+this.traceThickness/2,this.viaKeepoutRadius=this.viaDiameter/2+this.traceKeepoutRadius,this.buildFiveRegionGrid(e,n),this.gridToBoundsTransform=this.computeGridToBoundsTransform();const s=this.layers*this.planeSize;if(void 0!==this.maxCellCount&&s>this.maxCellCount)return this.error=`Cell count ${s} exceeds maxCellCount ${this.maxCellCount}`,void(this.failed=!0);this.connNameToId=new Map,this.connIdToName=[],this.connIdToRootNet=[],this.overlapFriendlyRootNets=new Set,this.unsolvedSegs=this.buildConnectionSegs(),this.penalty2d=new Float64Array(this.planeSize);const a=e>0?1/e:0,c=n>0?1/n:0;for(let t=0;t<this.planeSize;t++){let e=0;this.initialPenaltyFn&&(e+=this.initialPenaltyFn({x:this.cellCenterX[t],y:this.cellCenterY[t],px:(this.cellCenterX[t]-this.boundsMinX)*a,py:(this.cellCenterY[t]-this.boundsMinY)*c,cellId:t,region:hQ[this.cellRegion[t]],row:this.cellRow[t],col:this.cellCol[t]})),this.penalty2d[t]=e}this.usedCellsFlat=new Int32Array(s).fill(-1),this.sharedCellsFlat=Array.from({length:s},()=>{}),this.portOwnerFlat=new Int32Array(s).fill(-1),this.sharedCrossRootPortFlat=new Uint8Array(s),this.obstacleTraceRootIdsFlat=Array.from({length:s},()=>{}),this.obstacleViaRootIdsByCell=Array.from({length:this.planeSize},()=>{}),this.obstacleRootNameToId=new Map,this.obstacleRootNames=[],this.obstacleTracePrimitives=[],this.obstacleViaPrimitives=[],this.obstacleRectPrimitives=[];const l=this.rasterizeObstacles();if(l)return this.error=l,void(this.failed=!0);this.ripStateBuckets=1;const d=s;this.visitedStamp=new Uint32Array(d),this.bestGStamp=new Uint32Array(d),this.bestGValue=new Float64Array(d),this.visitedFlatStamp=new Uint32Array(s),this.stamp=0;const h=new Map;for(const t of this.nodeWithPortPoints.portPoints){const e=this.connNameToId.get(t.connectionName);if(void 0===e)continue;const n=this.pointToCell(t),o=n.z*this.planeSize+n.cellId,i=this.connIdToRootNet[e],r=h.get(o);void 0===r?h.set(o,i):r!==i&&(this.sharedCrossRootPortFlat[o]=1);const s=this.portOwnerFlat[o];this.portOwnerFlat[o]=-1===s||s===e?e:-2}this.solvedRoutes=[],this.usedIndicesByConn=[],this.ripCount=[],this.consecutiveSkips=0,this.penaltyCap=.5*this.hyperParameters.ripCost,this.shuffleConnections();const u=function(t){const e=t.planeSize*t.layers,n=t.connectionCount,o=Math.sqrt(n),i=Math.max(1,t.maxIterations),r=dQ(Math.round(e*(8+1.2*o)),15e4,12e6),s=dQ(Math.round(r*t.effort),15e4,12e6),a=dQ(Math.round(.2*i),15e4,2e6);return{maxIterationsIters:Math.max(1,Math.min(i,Math.max(a,s))),baseSearchBudgetIters:dQ(Math.round(e*(10+.8*o)*t.effort),5e4,4e6)}}({planeSize:this.planeSize,layers:this.layers,connectionCount:this.unsolvedSegs.length,effort:this.effort,maxIterations:this.MAX_ITERATIONS});this.baseSearchBudgetIters=u.baseSearchBudgetIters,this.MAX_ITERATIONS=u.maxIterationsIters,this.activeConnSeg=null,this.activeConnId=-1,this.nodePool=new pQ,this.heap=new uQ,this.ripChain=new mQ,this.seqCounter=0}_step(){for(let t=0;t<this.stepMultiplier;t++){if(this.solved||this.failed)return;this.stepOnce()}}rasterizeObstacles(){for(let t=0;t<this.obstacles.length;t++){const e=this.obstacles[t];if("rect"===e.type){const n=this.rasterizeRectObstacle(e,t);if(n)return n;continue}if(e.traceThickness<=0||e.viaDiameter<=0||e.route.length<2)return`Obstacle ${t} must have positive trace/via sizes and at least two route points`;const n=gQ(e.connectionName,e.rootConnectionName),o=this.internObstacleRootName(n);for(let n=1;n<e.route.length;n++){const i=e.route[n-1],r=e.route[n];if(!(Number.isFinite(i.x)&&Number.isFinite(i.y)&&Number.isFinite(i.z)&&Number.isFinite(r.x)&&Number.isFinite(r.y)&&Number.isFinite(r.z)))return`Obstacle ${t} contains non-finite route coordinates`;if(i.z===r.z){const n=this.zToLayer.get(i.z);if(void 0===n)return`Obstacle ${t} uses unavailable layer z=${i.z}`;this.rasterizeObstacleTraceSegment({segmentStart:i,segmentEnd:r,layer:n,obstacleRootId:o,obstacleTraceThickness:e.traceThickness})}else if(!e.vias.some(t=>t.x===r.x&&t.y===r.y)){const n=this.rasterizeObstacleVia({center:r,obstacleRootId:o,obstacleViaDiameter:e.viaDiameter,zStart:i.z,zEnd:r.z,obstacleIndex:t});if(n)return n}}for(const n of e.vias){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))return`Obstacle ${t} contains non-finite via coordinates`;const i=this.rasterizeObstacleVia({center:n,obstacleRootId:o,obstacleViaDiameter:e.viaDiameter,zStart:n.zStart,zEnd:n.zEnd,obstacleIndex:t});if(i)return i}}return this.obstacleTraceBlockedCellCount=this.obstacleTraceRootIdsFlat.reduce((t,e)=>t+(e?1:0),0),this.obstacleViaBlockedCellCount=this.obstacleViaRootIdsByCell.reduce((t,e)=>t+(e?1:0),0),null}rasterizeRectObstacle(t,e){if(!Number.isFinite(t.center.x)||!Number.isFinite(t.center.y)||!Number.isFinite(t.width)||!Number.isFinite(t.height)||t.width<=0||t.height<=0)return`Rect obstacle ${e} must have finite geometry and positive dimensions`;const n=[];for(const o of t.zLayers){const t=this.zToLayer.get(o);if(void 0===t)return`Rect obstacle ${e} uses unavailable layer z=${o}`;bQ(n,t)}if(0===n.length)return`Rect obstacle ${e} must apply to at least one layer`;const o=this.internObstacleRootName(gQ(t.connectionName,t.rootConnectionName)),i={rootId:o,center:t.center,width:t.width,height:t.height,rotationRadians:(t.ccwRotationDegrees??0)*Math.PI/180,layers:n};this.obstacleRectPrimitives.push(i);const r=this.transformBoundsPointToGrid(t.center),s=Math.hypot(t.width/2,t.height/2),a=this.getConservativeGridRadius(s+this.traceThickness/2+this.traceMargin);this.forEachCellNearCircle(r.x,r.y,a,t=>{for(const e of n)this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:e*this.planeSize+t,obstacleRootId:o})});const c=this.getConservativeGridRadius(s+this.viaDiameter/2+this.traceMargin);return this.forEachCellNearCircle(r.x,r.y,c,t=>{this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:t,obstacleRootId:o})}),null}internObstacleRootName(t){const e=this.obstacleRootNameToId.get(t);if(void 0!==e)return e;const n=this.obstacleRootNames.length;return this.obstacleRootNames.push(t),this.obstacleRootNameToId.set(t,n),n}rasterizeObstacleTraceSegment(t){this.obstacleTracePrimitives.push({rootId:t.obstacleRootId,layer:t.layer,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd,traceRadius:t.obstacleTraceThickness/2});const e=this.transformBoundsPointToGrid(t.segmentStart),n=this.transformBoundsPointToGrid(t.segmentEnd),o=this.getConservativeGridRadius(t.obstacleTraceThickness/2+this.traceMargin),i=this.getConservativeGridRadius(t.obstacleTraceThickness/2+this.viaDiameter/2+this.traceMargin);this.forEachCellNearSegment({segmentStart:e,segmentEnd:n,radius:o},e=>{this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:t.layer*this.planeSize+e,obstacleRootId:t.obstacleRootId})}),this.forEachCellNearSegment({segmentStart:e,segmentEnd:n,radius:i},e=>{this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:e,obstacleRootId:t.obstacleRootId})})}rasterizeObstacleVia(t){if(void 0===t.zStart!=(void 0===t.zEnd))return`Obstacle ${t.obstacleIndex} via must provide both zStart and zEnd`;let e=Array.from({length:this.layers},(t,e)=>e);if(void 0!==t.zStart&&void 0!==t.zEnd){if(!Number.isFinite(t.zStart)||!Number.isFinite(t.zEnd))return`Obstacle ${t.obstacleIndex} contains a non-finite via layer span`;const n=Math.min(t.zStart,t.zEnd),o=Math.max(t.zStart,t.zEnd);e=this.availableZ.flatMap((t,e)=>t>=n&&t<=o?[e]:[])}if(0===e.length)return null;this.obstacleViaPrimitives.push({rootId:t.obstacleRootId,center:t.center,viaRadius:t.obstacleViaDiameter/2,layers:e});const n=this.transformBoundsPointToGrid(t.center),o=this.getConservativeGridRadius(t.obstacleViaDiameter/2+this.traceThickness/2+this.traceMargin),i=this.getConservativeGridRadius(t.obstacleViaDiameter/2+this.viaDiameter/2+this.traceMargin);return this.forEachCellNearCircle(n.x,n.y,Math.max(o,i),r=>{const s=this.getCellRect(r);if(vQ(n.x,n.y,o,s.minX,s.minY,s.maxX,s.maxY))for(const n of e)this.addObstacleRootId({rootIdsByCell:this.obstacleTraceRootIdsFlat,cellIndex:n*this.planeSize+r,obstacleRootId:t.obstacleRootId});vQ(n.x,n.y,i,s.minX,s.minY,s.maxX,s.maxY)&&this.addObstacleRootId({rootIdsByCell:this.obstacleViaRootIdsByCell,cellIndex:r,obstacleRootId:t.obstacleRootId})}),null}forEachCellNearSegment(t,e){const n={x:(t.segmentStart.x+t.segmentEnd.x)/2,y:(t.segmentStart.y+t.segmentEnd.y)/2},o=Math.hypot(t.segmentEnd.x-t.segmentStart.x,t.segmentEnd.y-t.segmentStart.y)/2+t.radius;this.forEachCellNearCircle(n.x,n.y,o,n=>{wQ({segmentStart:t.segmentStart,segmentEnd:t.segmentEnd,radius:t.radius,rect:this.getCellRect(n)})&&e(n)})}getCellRect(t){return{minX:this.cellMinX[t],minY:this.cellMinY[t],maxX:this.cellMaxX[t],maxY:this.cellMaxY[t]}}transformBoundsPointToGrid(t){const e=this.gridToBoundsTransform;return{x:(t.x-e.c)/e.a,y:(t.y-e.f)/e.e}}getConservativeGridRadius(t){return t/Math.min(Math.abs(this.gridToBoundsTransform.a),Math.abs(this.gridToBoundsTransform.e))}addObstacleRootId(t){let e=t.rootIdsByCell[t.cellIndex];e||(e=[],t.rootIdsByCell[t.cellIndex]=e),bQ(e,t.obstacleRootId)}isBlockedByObstacleRoots(t,e){if(!t)return!1;const n=this.connIdToRootNet[e];for(const e of t)if(this.obstacleRootNames[e]!==n)return!0;return!1}hasSameRootObstacle(t,e){if(!t)return!1;const n=this.connIdToRootNet[e];return t.some(t=>this.obstacleRootNames[t]===n)}isLateralMoveBlockedByObstacleGeometry(t){const e=this.connIdToRootNet[t.activeConn],n=this.activeConnSeg,o=n&&t.layer===n.startZ&&t.fromCellId===n.startCellId?n.startPoint:iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.fromCellId],y:this.cellCenterY[t.fromCellId]}),i=n&&t.layer===n.endZ&&t.toCellId===n.endCellId?n.endPoint:iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.toCellId],y:this.cellCenterY[t.toCellId]});for(const n of this.obstacleTracePrimitives){if(n.layer!==t.layer||this.obstacleRootNames[n.rootId]===e)continue;const r=n.traceRadius+this.traceThickness/2+this.obstacleClearanceMargin;if(NQ({firstStart:o,firstEnd:i,secondStart:n.segmentStart,secondEnd:n.segmentEnd})<r*r)return!0}for(const n of this.obstacleViaPrimitives){if(!n.layers.includes(t.layer)||this.obstacleRootNames[n.rootId]===e)continue;const r=n.viaRadius+this.traceThickness/2+this.obstacleClearanceMargin;if(SQ({point:n.center,segmentStart:o,segmentEnd:i})<r*r)return!0}for(const n of this.obstacleRectPrimitives)if(n.layers.includes(t.layer)&&this.obstacleRootNames[n.rootId]!==e&&wQ({segmentStart:fQ(o,n),segmentEnd:fQ(i,n),radius:this.traceThickness/2+this.obstacleClearanceMargin,rect:yQ(n)}))return!0;return!1}isViaMoveBlockedByObstacleGeometry(t){const e=this.connIdToRootNet[t.activeConn],n=iQ(this.gridToBoundsTransform,{x:this.cellCenterX[t.cellId],y:this.cellCenterY[t.cellId]});for(const t of this.obstacleTracePrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=t.traceRadius+this.viaDiameter/2+this.obstacleClearanceMargin;if(SQ({point:n,segmentStart:t.segmentStart,segmentEnd:t.segmentEnd})<o*o)return!0}for(const t of this.obstacleViaPrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=t.viaRadius+this.viaDiameter/2+this.obstacleClearanceMargin;if((n.x-t.center.x)**2+(n.y-t.center.y)**2<o*o)return!0}for(const t of this.obstacleRectPrimitives){if(this.obstacleRootNames[t.rootId]===e)continue;const o=fQ(n,t),i=this.viaDiameter/2+this.obstacleClearanceMargin;if(IQ({point:o,rect:yQ(t)})<i*i)return!0}return!1}buildFiveRegionGrid(t,e){this.fineCols=Math.max(1,Math.ceil(t/this.highResolutionCellSize)),this.fineRows=Math.max(1,Math.ceil(e/this.highResolutionCellSize)),this.bandCols=Math.min(this.highResolutionCellThickness,Math.floor(this.fineCols/2)),this.bandRows=Math.min(this.highResolutionCellThickness,Math.floor(this.fineRows/2));const n=Math.max(0,this.fineCols-2*this.bandCols),o=Math.max(0,this.fineRows-2*this.bandRows),i=n,r=n;this.regions=[{id:0,name:"left",fineOriginRow:0,fineOriginCol:0,fineRows:this.fineRows,fineCols:this.bandCols,cellScale:1,rows:this.fineRows,cols:this.bandCols,offset:0},{id:1,name:"top",fineOriginRow:0,fineOriginCol:this.bandCols,fineRows:this.bandRows,fineCols:i,cellScale:1,rows:this.bandRows,cols:i,offset:0},{id:2,name:"right",fineOriginRow:0,fineOriginCol:this.fineCols-this.bandCols,fineRows:this.fineRows,fineCols:this.bandCols,cellScale:1,rows:this.fineRows,cols:this.bandCols,offset:0},{id:3,name:"bottom",fineOriginRow:this.fineRows-this.bandRows,fineOriginCol:this.bandCols,fineRows:this.bandRows,fineCols:r,cellScale:1,rows:this.bandRows,cols:r,offset:0},{id:4,name:"middle",fineOriginRow:this.bandRows,fineOriginCol:this.bandCols,fineRows:o,fineCols:n,cellScale:this.lowScale,rows:o>0?Math.ceil(o/this.lowScale):0,cols:n>0?Math.ceil(n/this.lowScale):0,offset:0}];let s=0;for(let t=0;t<this.regions.length;t++)this.regions[t].offset=s,s+=this.regions[t].rows*this.regions[t].cols;this.planeSize=s,this.cellCenterX=new Float64Array(this.planeSize),this.cellCenterY=new Float64Array(this.planeSize),this.cellMinX=new Float64Array(this.planeSize),this.cellMinY=new Float64Array(this.planeSize),this.cellMaxX=new Float64Array(this.planeSize),this.cellMaxY=new Float64Array(this.planeSize),this.cellWidth=new Float64Array(this.planeSize),this.cellHeight=new Float64Array(this.planeSize),this.cellRegion=new Uint8Array(this.planeSize),this.cellRow=new Int32Array(this.planeSize),this.cellCol=new Int32Array(this.planeSize),this.viaAllowed=new Uint8Array(this.planeSize);for(let t=0;t<this.regions.length;t++){const e=this.regions[t];for(let t=0;t<e.rows;t++){const n=e.fineOriginRow+t*e.cellScale,o=Math.min(e.fineOriginRow+e.fineRows,n+e.cellScale),i=this.boundsMinY+n*this.highResolutionCellSize,r=Math.min(this.boundsMaxY,this.boundsMinY+o*this.highResolutionCellSize);for(let n=0;n<e.cols;n++){const o=e.fineOriginCol+n*e.cellScale,s=Math.min(e.fineOriginCol+e.fineCols,o+e.cellScale),a=this.boundsMinX+o*this.highResolutionCellSize,c=Math.min(this.boundsMaxX,this.boundsMinX+s*this.highResolutionCellSize),l=this.cellIdFor(e.id,t,n);this.cellCenterX[l]=(a+c)/2,this.cellCenterY[l]=(i+r)/2,this.cellMinX[l]=a,this.cellMinY[l]=i,this.cellMaxX[l]=c,this.cellMaxY[l]=r,this.cellWidth[l]=c-a,this.cellHeight[l]=r-i,this.cellRegion[l]=e.id,this.cellRow[l]=t,this.cellCol[l]=n;const d=Math.min(this.cellCenterX[l]-this.boundsMinX,this.boundsMaxX-this.cellCenterX[l],this.cellCenterY[l]-this.boundsMinY,this.boundsMaxY-this.cellCenterY[l]);this.viaAllowed[l]=d>=this.viaMinDistFromBorder?1:0}}}const a=Array.from({length:this.planeSize},()=>[]),c=(t,e)=>{if(t===e||t<0||e<0)return;const n=this.cellCenterX[t]-this.cellCenterX[e],o=this.cellCenterY[t]-this.cellCenterY[e],i=Math.hypot(n,o);xQ(a[t],{cellId:e,cost:i}),xQ(a[e],{cellId:t,cost:i})};for(let t=0;t<this.regions.length;t++){const e=this.regions[t];for(let t=0;t<e.rows;t++)for(let n=0;n<e.cols;n++){const o=this.cellIdFor(e.id,t,n);t+1<e.rows&&c(o,this.cellIdFor(e.id,t+1,n)),n+1<e.cols&&c(o,this.cellIdFor(e.id,t,n+1))}}const l=this.regions[0],d=this.regions[1],h=this.regions[2],u=this.regions[3],p=this.regions[4],m=l.rows>0&&l.cols>0,g=d.rows>0&&d.cols>0,f=h.rows>0&&h.cols>0,y=u.rows>0&&u.cols>0,_=p.rows>0&&p.cols>0;if(m&&g)for(let t=0;t<this.bandRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(1,t,0));if(g&&f)for(let t=0;t<this.bandRows;t++)c(this.cellIdFor(1,t,d.cols-1),this.cellIdFor(2,t,0));if(m&&y)for(let t=this.fineRows-this.bandRows;t<this.fineRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(3,t-(this.fineRows-this.bandRows),0));if(y&&f)for(let t=this.fineRows-this.bandRows;t<this.fineRows;t++)c(this.cellIdFor(3,t-(this.fineRows-this.bandRows),u.cols-1),this.cellIdFor(2,t,0));if(m&&_)for(let t=this.bandRows;t<this.fineRows-this.bandRows;t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(4,Math.floor((t-this.bandRows)/this.lowScale),0));if(f&&_)for(let t=this.bandRows;t<this.fineRows-this.bandRows;t++)c(this.cellIdFor(4,Math.floor((t-this.bandRows)/this.lowScale),p.cols-1),this.cellIdFor(2,t,0));if(g&&_)for(let t=this.bandCols;t<this.fineCols-this.bandCols;t++)c(this.cellIdFor(1,d.rows-1,t-this.bandCols),this.cellIdFor(4,0,Math.floor((t-this.bandCols)/this.lowScale)));if(y&&_)for(let t=this.bandCols;t<this.fineCols-this.bandCols;t++)c(this.cellIdFor(4,p.rows-1,Math.floor((t-this.bandCols)/this.lowScale)),this.cellIdFor(3,0,t-this.bandCols));if(!_&&!g&&!y&&m&&f)for(let t=0;t<Math.min(l.rows,h.rows);t++)c(this.cellIdFor(0,t,l.cols-1),this.cellIdFor(2,t,0));if(!_&&!m&&!f&&g&&y)for(let t=0;t<Math.min(d.cols,u.cols);t++)c(this.cellIdFor(1,d.rows-1,t),this.cellIdFor(3,0,t));const b=this.flattenNeighborLists(a);this.neighborOffset=b.offset,this.neighborIds=b.ids,this.neighborCosts=b.costs}cellIdFor(t,e,n){const o=this.regions[t];return o.offset+e*o.cols+n}stepOnce(){if(!this.activeConnSeg){if(0===this.unsolvedSegs.length)return void(this.solved=!0);const t=this.unsolvedSegs.shift();this.activeConnSeg=t,this.activeConnId=t.connId,this.nodePool.clear(),this.ripChain.clear(),this.heap.clear(),this.seqCounter=0,this.searchIterations=0,this.nextStamp();const e=this.computeH(t.startZ,t.startCellId,t.endZ,t.endCellId)*this.hyperParameters.greedyMultiplier,n=this.nodePool.push(t.startZ,t.startCellId,0,-1,-1,0),o=t.startZ*this.planeSize+t.startCellId,i=this.getSearchStateIdx(o,0);return this.bestGStamp[i]=this.stamp,this.bestGValue[i]=0,void this.heap.push(e,this.seqCounter++,n)}this.searchIterations++;const t=this.ripCount[this.activeConnId]??0,e=Math.round(this.baseSearchBudgetIters*(1+.25*Math.min(t,10)));if(this.searchIterations>e){const t=this.penalty2d;for(let e=0;e<t.length;e++)t[e]=.9*t[e];return this.unsolvedSegs.push(this.activeConnSeg),this.activeConnSeg=null,this.activeConnId=-1,this.heap.clear(),this.nodePool.clear(),this.consecutiveSkips++,void(this.consecutiveSkips>=Math.max(3,3*this.unsolvedSegs.length)&&(this.error=`Convergence failure: ${this.unsolvedSegs.length} connections stuck`,this.failed=!0))}if(0===this.heap.size)return this.error=`No path found for ${this.connIdToName[this.activeConnId]}`,void(this.failed=!0);const n=this.heap.pop(),o=this.nodePool.z[n],i=this.nodePool.cellId[n],r=this.nodePool.g[n],s=this.nodePool.ripHead[n],a=this.nodePool.ripCount[n],c=o*this.planeSize+i,l=this.getSearchStateIdx(c,a);if(this.visitedStamp[l]===this.stamp)return;this.visitedStamp[l]=this.stamp,this.visitedFlatStamp[c]=this.stamp;const d=this.activeConnSeg;if(o===d.endZ&&i===d.endCellId)return this.finalizeRoute(n),this.activeConnSeg=null,void(this.activeConnId=-1);const h=this.visitedStamp,u=this.stamp,p=this.activeConnId,m=d.endZ,g=d.endCellId,f=this.neighborOffset[i],y=this.neighborOffset[i+1];for(let t=f;t<y;t++){const e=this.neighborIds[t],c=o*this.planeSize+e;if(this.computeMoveCostAndRips(p,o,i,e,!1,s,a,this.neighborCosts[t]),this._moveCost<0)continue;const l=this.getSearchStateIdx(c,this._moveRipCount);if(h[l]===u)continue;const d=r+this._moveCost;if(this.bestGStamp[l]===u&&d>=this.bestGValue[l])continue;this.bestGStamp[l]=u,this.bestGValue[l]=d;const f=d+this.computeH(o,e,m,g)*this.hyperParameters.greedyMultiplier,y=this.nodePool.push(o,e,d,n,this._moveRippedHead,this._moveRipCount);this.heap.push(f,this.seqCounter++,y)}if(this.viaAllowed[i])for(let t=0;t<this.layers;t++){if(t===o)continue;const e=t*this.planeSize+i;if(this.computeMoveCostAndRips(p,t,i,i,!0,s,a,0),this._moveCost<0)continue;const c=this.getSearchStateIdx(e,this._moveRipCount);if(h[c]===u)continue;const l=r+this._moveCost;if(this.bestGStamp[c]===u&&l>=this.bestGValue[c])continue;this.bestGStamp[c]=u,this.bestGValue[c]=l;const d=l+this.computeH(t,i,m,g)*this.hyperParameters.greedyMultiplier,f=this.nodePool.push(t,i,l,n,this._moveRippedHead,this._moveRipCount);this.heap.push(d,this.seqCounter++,f)}}computeMoveCostAndRips(t,e,n,o,i,r,s,a){let c=0,l=r,d=s;const h=e*this.planeSize+o,u=i?this.obstacleViaRootIdsByCell[o]:[...this.obstacleTraceRootIdsFlat[e*this.planeSize+n]??[],...this.obstacleTraceRootIdsFlat[h]??[]];if(this.isBlockedByObstacleRoots(u,t)&&(i?this.isViaMoveBlockedByObstacleGeometry({activeConn:t,cellId:o}):this.isLateralMoveBlockedByObstacleGeometry({activeConn:t,layer:e,fromCellId:n,toCellId:o})))return this._moveCost=-1,this._moveRippedHead=l,void(this._moveRipCount=d);const p=this.hasSameRootObstacle(u,t);if(i){c+=this.hyperParameters.viaBaseCost,c+=Math.min(this.penalty2d[o],this.penaltyCap);const n=this.portOwnerFlat[h],i=this.allowSharedUse(t,n),r=this.activeConnSeg,s=!!r&&e===r.endZ&&o===r.endCellId;if(n>=0&&n!==t&&!i&&!s)return this._moveCost=-1,void(this._moveRippedHead=l);this.fillViaOccupants(o,t);const a=this._viaOccs;for(let t=0;t<a.length;t++){const e=a[t];this.ripChain.contains(l,e)||(c+=this.hyperParameters.ripCost,l=this.ripChain.append(l,e),d++),c+=this.hyperParameters.ripViaPenalty}}else{c+=a,c+=Math.min(this.penalty2d[o],this.penaltyCap);const n=this.portOwnerFlat[h],i=this.allowSharedUse(t,n),r=this.activeConnSeg,s=!!r&&e===r.endZ&&o===r.endCellId;if(n>=0&&n!==t&&!i&&!s)return this._moveCost=-1,void(this._moveRippedHead=l);this.fillTraceOccupants(h,t,this._cellOccs);for(let t=0;t<this._cellOccs.length;t++){const e=this._cellOccs[t];this.ripChain.contains(l,e)||(c+=this.hyperParameters.ripCost,l=this.ripChain.append(l,e),d++),c+=this.hyperParameters.ripTracePenalty}}p&&(c*=this.hyperParameters.sameRootObstacleCostMultiplier),this._moveCost=c,this._moveRippedHead=l,this._moveRipCount=d}fillViaOccupants(t,e){const n=this._viaOccs;n.length=0;const o=this.cellCenterX[t],i=this.cellCenterY[t];this.forEachCellNearCircle(o,i,this.viaKeepoutRadius,t=>{if(vQ(o,i,this.viaKeepoutRadius,this.cellMinX[t],this.cellMinY[t],this.cellMaxX[t],this.cellMaxY[t]))for(let o=0;o<this.layers;o++)this.pushFlatOccupants(o*this.planeSize+t,e,n)})}fillTraceOccupants(t,e,n){n.length=0,this.pushFlatOccupants(t,e,n)}pushFlatOccupants(t,e,n){const o=this.usedCellsFlat[t];-1===o||o===e||this.allowSharedUse(e,o)||bQ(n,o);const i=this.sharedCellsFlat[t];if(i)for(let t=0;t<i.length;t++){const o=i[t];o!==e&&(this.allowSharedUse(e,o)||bQ(n,o))}}addSharedOccupant(t,e){if(this.usedCellsFlat[t]===e)return;let n=this.sharedCellsFlat[t];n||(n=[],this.sharedCellsFlat[t]=n),bQ(n,e)}replaceOccupants(t,e){this.usedCellsFlat[t]=e,this.sharedCellsFlat[t]=void 0}removeOccupant(t,e){const n=this.sharedCellsFlat[t];if(this.usedCellsFlat[t]===e)return void(n&&n.length>0?(this.usedCellsFlat[t]=n.pop(),0===n.length&&(this.sharedCellsFlat[t]=void 0)):this.usedCellsFlat[t]=-1);if(!n)return;const o=n.indexOf(e);-1!==o&&(n.splice(o,1),0===n.length&&(this.sharedCellsFlat[t]=void 0))}allowSharedUse(t,e){if(e<0)return!1;return this.connIdToRootNet[e]===this.connIdToRootNet[t]}shouldSkipFixedPortHalo(t,e){const n=this.portOwnerFlat[t];return n!==e&&(-2===n||!(n<0)&&!this.allowSharedUse(e,n))}nextStamp(){this.stamp=this.stamp+1>>>0,0===this.stamp&&(this.visitedStamp.fill(0),this.bestGStamp.fill(0),this.visitedFlatStamp.fill(0),this.stamp=1)}getSearchStateIdx(t,e){return t}computeH(t,e,n,o){const i=Math.hypot(this.cellCenterX[e]-this.cellCenterX[o],this.cellCenterY[e]-this.cellCenterY[o]);return t===n?i:i+this.hyperParameters.viaBaseCost}internConn(t,e){const n=this.connNameToId.get(t);if(void 0!==n)return n;const o=this.connIdToName.length;return this.connIdToName.push(t),this.connIdToRootNet.push(gQ(t,e)),this.connNameToId.set(t,o),o}buildConnectionSegs(){const t=new Map;for(const e of this.nodeWithPortPoints.portPoints){const n=e.connectionName;t.has(n)||t.set(n,{points:[],rootConnectionName:e.rootConnectionName}),t.get(n).points.push(e)}const e=[],n=new Map;for(const[o,i]of t){const t=i.points,r=lQ(t);if(0===r.length)continue;const s=this.internConn(o,i.rootConnectionName);for(const[t,i]of r){const r=this.pointToCell(t),a=this.pointToCell(i),c=`${r.z}:${r.cellId}`,l=`${a.z}:${a.cellId}`,d=c<l?`${c}|${l}`:`${l}|${c}`,h=this.connIdToRootNet[s],u=`${h}|${d}`,p=n.get(u);if(p){if(this.overlapFriendlyRootNets.add(h),!p.connectionAliases.some(t=>t.connectionName===o)){const e=p.startZ===r.z&&p.startCellId===r.cellId&&p.endZ===a.z&&p.endCellId===a.cellId,n=p.startZ===a.z&&p.startCellId===a.cellId&&p.endZ===r.z&&p.endCellId===r.cellId;if(!e&&!n)throw new Error(`Connection alias ${o} does not match canonical segment ${u}`);p.connectionAliases.push({connectionName:o,rootConnectionName:h,startPoint:t,endPoint:i,reversedFromCanonical:!e&&n})}continue}const m={connId:s,startZ:r.z,startCellId:r.cellId,startPoint:t,endZ:a.z,endCellId:a.cellId,endPoint:i,connectionAliases:[{connectionName:o,rootConnectionName:h,startPoint:t,endPoint:i,reversedFromCanonical:!1}]};n.set(u,m),e.push(m)}}return e}pointToCell(t){const e=_Q(Math.floor((t.x-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),n=_Q(Math.floor((t.y-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1);let o=4;e<this.bandCols?o=0:e>=this.fineCols-this.bandCols?o=2:n<this.bandRows?o=1:n>=this.fineRows-this.bandRows&&(o=3);const i=this.regions[o],r=n-i.fineOriginRow,s=e-i.fineOriginCol,a=_Q(Math.floor(r/i.cellScale),0,Math.max(0,i.rows-1)),c=_Q(Math.floor(s/i.cellScale),0,Math.max(0,i.cols-1));return{z:this.zToLayer.get(t.z)??0,cellId:this.cellIdFor(o,a,c)}}shuffleConnections(){const t=this.unsolvedSegs;let e=this.hyperParameters.shuffleSeed>>>0;const n=()=>(e=Math.imul(e,1664525)+1013904223>>>0,e/4294967295);for(let e=t.length-1;e>0;e--){const o=Math.floor(n()*(e+1)),i=t[e];t[e]=t[o],t[o]=i}}finalizeRoute(t){this.consecutiveSkips=Math.max(0,this.consecutiveSkips-1);const e=[];let n=t;for(;n>=0;){const t=this.nodePool.z[n],o=this.nodePool.cellId[n];e.push(t*this.planeSize+o),n=this.nodePool.parent[n]}for(e.reverse();e.length>1&&this.sharedCrossRootPortFlat[e[0]];)e.shift();for(;e.length>1&&this.sharedCrossRootPortFlat[e[e.length-1]];)e.pop();const o=this.extractViaCellIds(e),i=this.activeConnId;this.ripChain.collect(this.nodePool.ripHead[t],this._rippedIds);for(let t=0;t<this._rippedIds.length;t++)if(this.ripTrace(this._rippedIds[t]),this.failed)return;const r=[];for(let t=0;t<e.length;t++){const n=e[t],o=Math.floor(n/this.planeSize),s=n-o*this.planeSize;this.markTraceFootprint(i,o,s,r)}const s=[];for(let t=0;t<o.length;t++)this.markViaFootprint(i,o[t],r,s);for(;this.usedIndicesByConn.length<=i;)this.usedIndicesByConn.push(void 0);const a=this.usedIndicesByConn[i]??[];for(a.push(...r),this.usedIndicesByConn[i]=a;this.solvedRoutes.length<=i;)this.solvedRoutes.push(void 0);const c=this.solvedRoutes[i]??[];c.push({connId:i,states:Int32Array.from(e),viaCellIds:Int32Array.from(o),startPoint:this.activeConnSeg.startPoint,endPoint:this.activeConnSeg.endPoint,connectionAliases:this.activeConnSeg.connectionAliases}),this.solvedRoutes[i]=c;for(let t=0;t<s.length;t++)if(this.ripTrace(s[t]),this.failed)return;if(this._rippedIds.length>0||s.length>0){const t=this.penalty2d,e=this.penaltyCap;if(this.totalRipEvents>50)for(let e=0;e<t.length;e++)t[e]=.99*t[e];else for(let n=0;n<t.length;n++)t[n]>e&&(t[n]=.5*t[n])}}extractViaCellIds(t){const e=[];for(let n=1;n<t.length;n++){const o=t[n-1],i=t[n],r=Math.floor(o/this.planeSize),s=Math.floor(i/this.planeSize);r!==s&&e.push(i-s*this.planeSize)}return e}markTraceFootprint(t,e,n,o){const i=this.cellCenterX[n],r=this.cellCenterY[n];this.forEachCellNearCircle(i,r,this.traceKeepoutRadius,s=>{if(!vQ(i,r,this.traceKeepoutRadius,this.cellMinX[s],this.cellMinY[s],this.cellMaxX[s],this.cellMaxY[s]))return;const a=e*this.planeSize+s;if(s!==n&&this.shouldSkipFixedPortHalo(a,t))return;const c=this.usedCellsFlat[a],l=this.allowSharedUse(t,c);(-1===c||c===t||l)&&(-1!==c&&c!==t?this.addSharedOccupant(a,t):this.usedCellsFlat[a]=t,o.push(a))})}markViaFootprint(t,e,n,o){const i=this.cellCenterX[e],r=this.cellCenterY[e];this.forEachCellNearCircle(i,r,this.viaKeepoutRadius,s=>{if(vQ(i,r,this.viaKeepoutRadius,this.cellMinX[s],this.cellMinY[s],this.cellMaxX[s],this.cellMaxY[s]))for(let i=0;i<this.layers;i++){const r=i*this.planeSize+s;if(s!==e&&this.shouldSkipFixedPortHalo(r,t))continue;if(this.fillTraceOccupants(r,t,this._cellOccs),this._cellOccs.length>0){for(let t=0;t<this._cellOccs.length;t++)bQ(o,this._cellOccs[t]);this.replaceOccupants(r,t),n.push(r);continue}const a=this.usedCellsFlat[r];-1!==a&&a!==t?this.addSharedOccupant(r,t):this.usedCellsFlat[r]=t,n.push(r)}})}forEachCellNearCircle(t,e,n,o){const i=_Q(Math.floor((t-n-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),r=_Q(Math.floor((t+n-this.boundsMinX)/this.highResolutionCellSize),0,this.fineCols-1),s=_Q(Math.floor((e-n-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1),a=_Q(Math.floor((e+n-this.boundsMinY)/this.highResolutionCellSize),0,this.fineRows-1);for(let t=0;t<this.regions.length;t++){const e=this.regions[t];if(0===e.rows||0===e.cols)continue;const n=Math.max(s,e.fineOriginRow),c=Math.min(a,e.fineOriginRow+e.fineRows-1),l=Math.max(i,e.fineOriginCol),d=Math.min(r,e.fineOriginCol+e.fineCols-1);if(n>c)continue;if(l>d)continue;const h=Math.floor((n-e.fineOriginRow)/e.cellScale),u=Math.floor((c-e.fineOriginRow)/e.cellScale),p=Math.floor((l-e.fineOriginCol)/e.cellScale),m=Math.floor((d-e.fineOriginCol)/e.cellScale);for(let t=h;t<=u;t++)for(let n=p;n<=m;n++)o(this.cellIdFor(e.id,t,n))}}ripTrace(t){for(;this.ripCount.length<=t;)this.ripCount.push(0);if(this.ripCount[t]++,this.totalRipEvents++,this.totalRipEvents>=this.MAX_RIPS)return this.error=`Convergence failure: exceeded MAX_RIPS ${this.MAX_RIPS}`,void(this.failed=!0);const e=this.getSolvedRoutesForConn(t);if(e.length>0)for(const t of e){for(let e=0;e<t.states.length;e++){const n=t.states[e]%this.planeSize;this.penalty2d[n]=this.penalty2d[n]+this.hyperParameters.ripTracePenalty}for(let e=0;e<t.viaCellIds.length;e++){const n=t.viaCellIds[e];this.penalty2d[n]=this.penalty2d[n]+this.hyperParameters.ripViaPenalty}}const n=this.usedIndicesByConn[t];if(n){for(let e=0;e<n.length;e++)this.removeOccupant(n[e],t);this.usedIndicesByConn[t]=void 0}if(e.length>0){this.solvedRoutes[t]=void 0;for(const n of e){const e=n.states[0],o=n.states[n.states.length-1],i=Math.floor(e/this.planeSize),r=Math.floor(o/this.planeSize);this.unsolvedSegs.push({connId:t,startZ:i,startCellId:e-i*this.planeSize,startPoint:n.startPoint,endZ:r,endCellId:o-r*this.planeSize,endPoint:n.endPoint,connectionAliases:n.connectionAliases})}}}flattenNeighborLists(t){const e=new Int32Array(t.length+1);let n=0;for(let o=0;o<t.length;o++)e[o]=n,n+=t[o].length;e[t.length]=n;const o=new Int32Array(n),i=new Float32Array(n);let r=0;for(let e=0;e<t.length;e++){const n=t[e];for(let t=0;t<n.length;t++){const e=n[t];o[r]=e.cellId,i[r]=e.cost,r++}}return{offset:e,ids:o,costs:i}}visualize(){const t=["red","blue","orange","green"],e=this.gridToBoundsTransform,n=[],o=[],i=[],r=[];r.push({center:{x:this.nodeWithPortPoints.center.x,y:this.nodeWithPortPoints.center.y},width:this.nodeWithPortPoints.width,height:this.nodeWithPortPoints.height,stroke:"gray"});const s=({route:e,connectionName:n,strokeWidth:i,strokeDash:r,labelPrefix:s})=>{if(e.length<2)return;let a=0;for(let c=1;c<e.length;c+=1){const l=e[c-1];e[c].z!==l.z&&(c-a>=2&&o.push({points:e.slice(a,c).map(t=>({x:t.x,y:t.y})),strokeColor:t[l.z]??"rgba(128,128,128,0.75)",strokeWidth:i,strokeDash:r,label:`${s} ${n} z=${l.z}`}),a=c)}if(e.length-a<2)return;const c=e[a].z;o.push({points:e.slice(a).map(t=>({x:t.x,y:t.y})),strokeColor:t[c]??"rgba(128,128,128,0.75)",strokeWidth:i,strokeDash:r,label:`${s} ${n} z=${c}`})};for(const t of this.obstacles)if("rect"!==t.type){s({route:t.route,connectionName:t.connectionName,strokeWidth:t.traceThickness,strokeDash:[.12,.08],labelPrefix:"fixed obstacle"});for(const e of t.vias)i.push({center:{x:e.x,y:e.y},radius:t.viaDiameter/2,fill:"rgba(128,0,128,0.25)",stroke:"purple",label:`fixed obstacle ${t.connectionName} via`})}else r.push({center:t.center,width:t.width,height:t.height,fill:"rgba(128,0,128,0.12)",stroke:"purple",label:`fixed obstacle ${t.connectionName}`});if(this.showPenaltyMap&&this.penalty2d){let t=0;for(let e=0;e<this.penalty2d.length;e++)this.penalty2d[e]>t&&(t=this.penalty2d[e]);if(t>0)for(let n=0;n<this.planeSize;n++){const o=this.penalty2d[n];if(o<=0)continue;const i=iQ(e,{x:this.cellCenterX[n],y:this.cellCenterY[n]}),s=Math.min(.6,o/t*.6);r.push({center:i,width:this.cellWidth[n]*e.a,height:this.cellHeight[n]*e.e,fill:`rgba(255,165,0,${s.toFixed(3)})`})}}if(this.showUsedCellMap&&this.usedCellsFlat)for(let t=0;t<this.layers;t++){const n=t*this.planeSize;for(let t=0;t<this.planeSize;t++){if(-1===this.usedCellsFlat[n+t])continue;const o=iQ(e,{x:this.cellCenterX[t],y:this.cellCenterY[t]});r.push({center:o,width:this.cellWidth[t]*e.a,height:this.cellHeight[t]*e.e,fill:"rgba(0,0,255,0.5)"})}}for(const e of this.nodeWithPortPoints.portPoints)n.push({x:e.x,y:e.y,color:t[e.z]??"gray",label:e.connectionName});const a=this.getOutput();for(const t of a)s({route:t.route,connectionName:t.connectionName,strokeWidth:this.traceThickness,labelPrefix:"B01 route"});for(const t of a)for(const e of t.vias)i.push({center:{x:e.x,y:e.y},radius:this.viaDiameter/2,fill:"rgba(0,0,0,0.3)",stroke:"black",label:`B01 route ${t.connectionName} via`});if(this.activeConnSeg&&this.visitedFlatStamp){const t=this.stamp;for(let o=0;o<this.layers;o++){const i=o*this.planeSize;for(let o=0;o<this.planeSize;o++){if(this.visitedFlatStamp[i+o]!==t)continue;const r=iQ(e,{x:this.cellCenterX[o],y:this.cellCenterY[o]});n.push({x:r.x,y:r.y,color:"rgba(0,0,255,0.2)"})}}}return{points:n,lines:o,circles:i,rects:r,coordinateSystem:"cartesian",title:`HighDensityB01 [${this.getSolvedRouteCount()} solved, ${this.unsolvedSegs?.length??0} remaining]`}}getOutput(){const t=this.gridToBoundsTransform,e=[];for(let n=0;n<this.solvedRoutes.length;n++){const o=this.getSolvedRoutesForConn(n);if(0!==o.length)for(const n of o){const o=Array.from(n.states,e=>{const n=Math.floor(e/this.planeSize),o=e-n*this.planeSize,i=iQ(t,{x:this.cellCenterX[o],y:this.cellCenterY[o]});return{x:i.x,y:i.y,z:this.layerToZ.get(n)??n}}),i=Array.from(n.viaCellIds,e=>iQ(t,{x:this.cellCenterX[e],y:this.cellCenterY[e]}));for(const t of n.connectionAliases){const n=(t.reversedFromCanonical?[...o].reverse():o).map(t=>({...t}));n.length>0&&(n[0]={...t.startPoint},n.length>1&&(n[n.length-1]={...t.endPoint})),e.push({connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,regionId:this.nodeWithPortPoints.capacityMeshNodeId,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,route:n,vias:i.map(t=>({...t}))})}}}return e}getSolvedRoutesForConn(t){const e=this.solvedRoutes[t];return e?Array.isArray(e)?e:[e]:[]}getSolvedRouteCount(){let t=0;for(let e=0;e<this.solvedRoutes.length;e++)t+=this.getSolvedRoutesForConn(e).length;return t}computeGridToBoundsTransform(){let t=1/0,e=-1/0,n=1/0,o=-1/0;for(let i=0;i<this.planeSize;i++){const r=this.cellCenterX[i],s=this.cellCenterY[i];r<t&&(t=r),r>e&&(e=r),s<n&&(n=s),s>o&&(o=s)}const i=e-t,r=o-n,s=this.boundsMaxX-this.boundsMinX,a=this.boundsMaxY-this.boundsMinY,c=i>0?s/i:1,l=r>0?a/r:1;return{a:c,b:0,c:i>0?this.boundsMinX-c*t:(this.boundsMinX+this.boundsMaxX)/2-t,d:0,e:l,f:r>0?this.boundsMinY-l*n:(this.boundsMinY+this.boundsMaxY)/2-n}}},RQ=new WeakMap,EQ=t=>{const e=RQ.get(t);if(e)return e;const n=[],o=[];for(let e=1;e<t.route.length;e++){const i=t.route[e-1],r=t.route[e],s=Math.hypot(r.x-i.x,r.y-i.y),a=Math.max(i.traceThickness??t.traceThickness,r.traceThickness??t.traceThickness);if(i.z!==r.z&&"through_obstacle"===i.toNextSegmentType){const e=Math.min(i.z,r.z),c=Math.max(i.z,r.z);if(s<=1e-9){const n=t.vias.some(t=>Math.hypot(t.x-r.x,t.y-r.y)<=1e-9);o.push({center:{x:r.x,y:r.y},minZ:e,maxZ:c,diameter:n?t.viaDiameter:a});continue}for(let t=e;t<=c;t++)n.push({start:{...i,z:t},end:{...r,z:t},z:t,width:a});continue}s>1e-9&&n.push({start:i,end:i.z===r.z?r:{...r,z:i.z},z:i.z,width:a}),i.z!==r.z&&o.push({center:{x:r.x,y:r.y},minZ:Math.min(i.z,r.z),maxZ:Math.max(i.z,r.z),diameter:t.viaDiameter})}const i={wireSegments:n,viaSpans:o};return RQ.set(t,i),i},AQ=(t,e,n)=>{const o=t.end.x-t.start.x,i=t.end.y-t.start.y,r=Math.hypot(o,i),s={x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2};return Math.abs(o)<=1e-9||Math.abs(i)<=1e-9?[{center:s,width:Math.abs(o)>Math.abs(i)?r:t.width,height:Math.abs(o)>Math.abs(i)?t.width:r}]:rX({center:s,width:r,height:t.width,rotation:180*Math.atan2(i,o)/Math.PI},Math.max(n,Math.ceil(r/e)))},OQ=({fixedObstacleRoutes:t,layerCount:e})=>t.flatMap((t,n)=>{const o=[t.connectionName,t.rootConnectionName].filter(t=>"string"==typeof t),i=EQ(t);return[...i.wireSegments.flatMap((t,i)=>AQ(t,.75,2).map((r,s)=>({obstacleId:`pipeline9_fixed_obstacle_${n}_wire_${i}_${s}`,type:"rect",layers:[vo(t.z,e)],center:r.center,width:r.width,height:r.height,connectedTo:o}))),...i.viaSpans.map((t,i)=>({obstacleId:`pipeline9_fixed_obstacle_${n}_via_${i}`,type:"rect",layers:Array.from({length:t.maxZ-t.minZ+1},(n,o)=>vo(t.minZ+o,e)),center:t.center,width:t.diameter,height:t.diameter,connectedTo:o}))]}),kQ=(t,e,n)=>{const o=[t.connectionName,t.rootConnectionName].filter(t=>"string"==typeof t),i=[e.connectionName,e.rootConnectionName].filter(t=>"string"==typeof t);return o.some(t=>i.some(e=>t===e||n.areIdsConnected(t,e)))},LQ=(t,e)=>t.minX<=e.maxX&&t.maxX>=e.minX&&t.minY<=e.maxY&&t.maxY>=e.minY,DQ=({left:t,right:e,clearance:n,leftBounds:o})=>{const i=EQ(t),r=EQ(e),s=o?i.wireSegments.filter(t=>((t,e)=>{const n={minX:Math.min(t.start.x,t.end.x)-t.width/2,maxX:Math.max(t.start.x,t.end.x)+t.width/2,minY:Math.min(t.start.y,t.end.y)-t.width/2,maxY:Math.max(t.start.y,t.end.y)+t.width/2};return LQ(n,e)})(t,o)):i.wireSegments,a=o?i.viaSpans.filter(t=>((t,e)=>{const n={minX:t.center.x-t.diameter/2,maxX:t.center.x+t.diameter/2,minY:t.center.y-t.diameter/2,maxY:t.center.y+t.diameter/2};return LQ(n,e)})(t,o)):i.viaSpans;for(const t of s){for(const e of r.wireSegments){if(t.z!==e.z)continue;const o=t.width/2+e.width/2+n;if(Ra(t.start,t.end,e.start,e.end)<o)return!0}for(const e of r.viaSpans){if(t.z<e.minZ||t.z>e.maxZ)continue;const o=t.width/2+e.diameter/2+n;if(Ra(t.start,t.end,e.center,e.center)<o)return!0}}for(const t of a){for(const e of r.wireSegments){if(e.z<t.minZ||e.z>t.maxZ)continue;const o=t.diameter/2+e.width/2+n;if(Ra(t.center,t.center,e.start,e.end)<o)return!0}for(const e of r.viaSpans){if(t.minZ>e.maxZ||e.minZ>t.maxZ)continue;const o=t.diameter/2+e.diameter/2+n;if(Math.hypot(t.center.x-e.center.x,t.center.y-e.center.y)<o)return!0}}return!1},zQ=({routes:t,movablePreloadedConnectionNames:e,boardObstacles:n,connMap:o,layerCount:i,viaToPadClearance:r})=>t.some(t=>{if(!e.has(t.connectionName))return!1;return EQ(t).viaSpans.some(e=>n.some(n=>{if(fo(n,t,o))return!1;const s=((t,e)=>{const n=t.__zLayers??t.zLayers;return n||t.layers.map(t=>ko(t,e))})(n,i);return!!s.some(t=>t>=e.minZ&&t<=e.maxZ)&&((t,e)=>{const n=-1*(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y,r=o*Math.cos(n)-i*Math.sin(n),s=o*Math.sin(n)+i*Math.cos(n),a=Math.max(Math.abs(r)-e.width/2,0),c=Math.max(Math.abs(s)-e.height/2,0);return Math.hypot(a,c)})(e.center,n)<e.diameter/2+r}))}),FQ=class extends si{params;highDensitySolver;forceImproveSolver;repairSolver;phase="route";constructor(t){super(),this.params=t,this.stats={preloadedViaCandidateRejectionCount:0,forceImproveCandidateRejectionCount:0,repairCandidateRejectionCount:0},this.highDensitySolver=new zs({nodePortPoints:[t.nodeWithPortPoints],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:t.nodePfById,obstacles:t.obstacles,layerCount:t.layerCount,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!1,growShrinkFallbackToInvalidGeometryOnFailure:!1,growShrinkSolutionValidator:t.boardObstacles&&t.movablePreloadedConnectionNames&&void 0!==t.viaToPadClearance?t=>this.validateCandidateRoutes(t):void 0}),this.activeSubSolver=this.highDensitySolver,this.MAX_ITERATIONS=1e8*t.effort}getSolverName(){return"Pipeline9RegionalFallbackSolver"}validateCandidateRoutes(t){const{boardObstacles:e,movablePreloadedConnectionNames:n,viaToPadClearance:o}=this.params;if(!e||!n||void 0===o)return!0;const i=zQ({routes:t,movablePreloadedConnectionNames:n,boardObstacles:e,connMap:this.params.connMap,layerCount:this.params.layerCount,viaToPadClearance:o});return i&&(this.stats.preloadedViaCandidateRejectionCount=Number(this.stats.preloadedViaCandidateRejectionCount??0)+1),!i}_step(){if("route"===this.phase){if(this.highDensitySolver.step(),this.highDensitySolver.failed)return this.error=this.highDensitySolver.error,void(this.failed=!0);if(!this.highDensitySolver.solved)return;const t=AK(this.highDensitySolver.routes);return this.validateCandidateRoutes(t)?(this.forceImproveSolver=new Yy({nodeWithPortPoints:[this.params.nodeWithPortPoints],hdRoutes:t,colorMap:this.params.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*this.params.effort)),nodeAssignmentMargin:this.params.obstacleMargin}),this.activeSubSolver=this.forceImproveSolver,void(this.phase="improve")):(this.error="Pipeline9 regional route output failed its candidate validator",void(this.failed=!0))}if("improve"===this.phase){if(this.forceImproveSolver.step(),this.forceImproveSolver.failed)return this.error=this.forceImproveSolver.error,void(this.failed=!0);if(!this.forceImproveSolver.solved)return;const t=this.forceImproveSolver.getOutput();return this.validateCandidateRoutes(t)?(this.repairSolver=new AY({nodeWithPortPoints:[this.params.nodeWithPortPoints],hdRoutes:t,obstacles:this.params.obstacles,colorMap:this.params.colorMap,repairMargin:this.params.obstacleMargin,maxSampleEntries:80,connMap:this.params.connMap}),this.activeSubSolver=this.repairSolver,void(this.phase="repair")):(this.stats.forceImproveCandidateRejectionCount=Number(this.stats.forceImproveCandidateRejectionCount??0)+1,this.error="Pipeline9 regional force-improve output failed its candidate validator",void(this.failed=!0))}if("repair"===this.phase){if(this.repairSolver.step(),this.repairSolver.failed)return this.error=this.repairSolver.error,void(this.failed=!0);if(!this.repairSolver.solved)return;const t=this.repairSolver.getOutput();return this.validateCandidateRoutes(t)?(this.activeSubSolver=null,this.phase="done",void(this.solved=!0)):(this.stats.repairCandidateRejectionCount=Number(this.stats.repairCandidateRejectionCount??0)+1,this.error="Pipeline9 regional repair output failed its candidate validator",void(this.failed=!0))}}getOutput(){return this.repairSolver?.getOutput()??this.forceImproveSolver?.getOutput()??this.highDensitySolver.routes}visualize(){return this.repairSolver?.visualize()??this.forceImproveSolver?.visualize()??this.highDensitySolver.visualize()}},BQ=(t,e)=>({minX:t.center.x-t.width/2-e,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2-e,maxY:t.center.y+t.height/2+e}),jQ=(t,e,n)=>{const o=Math.max(n.minX-t.x,0,t.x-n.maxX),i=Math.max(n.minY-t.y,0,t.y-n.maxY);return o*o+i*i<=e*e},$Q=(t,e,n,o)=>Math.min(t.x,e.x)-n<=o.maxX&&Math.max(t.x,e.x)+n>=o.minX&&Math.min(t.y,e.y)-n<=o.maxY&&Math.max(t.y,e.y)+n>=o.minY,YQ=(t,e)=>{const n=t=>({...t,rootConnectionName:e.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName});return{...t,portPoints:t.portPoints.map(n),portPointsInPairs:t.portPointsInPairs?.map(([t,e])=>[n(t),n(e)])}},XQ=({nodeWithPortPoints:t,connMap:e,colorMap:n,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a,obstacles:c,layerCount:l})=>new zs({nodePortPoints:[YQ(t,e)],colorMap:n,connMap:e,viaDiameter:o,traceWidth:i,obstacleMargin:r,effort:s,nodePfById:a,obstacles:c,layerCount:l,useGrowShrinkHighDensityIntraNodeSolver:!0,preserveTerminalPcbPortIds:!1,growShrinkFallbackToInvalidGeometryOnFailure:!1,captureSearchDebug:!1}),VQ=class extends si{fixedHdRoutes;connMap;colorMap;obstacles;layerCount;viaDiameter;traceWidth;obstacleMargin;viaToPadClearance;effort;nodePfById;preserveTerminalPcbPortIds;includeBoardObstacles;enableRegionalFallback;maxB01Rips;routes=[];failedSolvers=[];unsolvedNodePortPoints;fixedRouteReplacements=new Map;removedFixedRouteConnectionNames=new Set;preloadedTraceMutationMasks=new Map;activeRegularSolver=null;activeB01Solver=null;activeFallbackSolver=null;activeFallbackFixedRouteSections=new Map;activeFallbackFixedObstacleRoutes=[];activeFallbackPromotedFixedRouteConnectionNames=new Set;activeFallbackReason=null;activeNode=null;constructor(t){super(),this.fixedHdRoutes=t.fixedHdRoutes,this.connMap=t.connMap,this.colorMap=t.colorMap??{},this.obstacles=t.obstacles,this.layerCount=t.layerCount,this.viaDiameter=t.viaDiameter,this.traceWidth=t.traceWidth,this.obstacleMargin=t.obstacleMargin,this.viaToPadClearance=t.viaToPadClearance,this.effort=t.effort,this.nodePfById=t.nodePfById instanceof Map?new Map(t.nodePfById):new Map(Object.entries(t.nodePfById??{})),this.preserveTerminalPcbPortIds=t.preserveTerminalPcbPortIds??!1,this.includeBoardObstacles=t.includeBoardObstacles??!1,this.enableRegionalFallback=t.enableRegionalFallback??!0,this.maxB01Rips=t.maxB01Rips,this.unsolvedNodePortPoints=[...t.nodePortPoints],this.MAX_ITERATIONS=1e8*this.effort,this.stats={nodeCount:t.nodePortPoints.length,solvedNodeCount:0,fixedObstacleCount:t.fixedHdRoutes.length,fixedObstacleUses:0,boardObstacleUses:0,fallbackNodeCount:0,regularNodeCount:0,b01NodeCount:0,reroutedFixedRouteCount:0,reroutedFixedRouteSectionCount:0,promotedFallbackAttemptCount:0,promotedFixedRouteCount:0,regionalPreloadedViaCandidateRejectionCount:0,regionalForceImproveCandidateRejectionCount:0,regionalRepairCandidateRejectionCount:0}}getSolverName(){return"Pipeline9HighDensitySolver"}getUpdatedFixedHdRoutes(){return this.fixedHdRoutes.flatMap(t=>this.removedFixedRouteConnectionNames.has(t.connectionName)?[]:[this.fixedRouteReplacements.get(t.connectionName)??t])}finishActiveNode(t){const e=this.activeNode?((t,e)=>t.map(t=>({...t,rootConnectionName:e.portPoints.find(e=>e.connectionName===t.connectionName)?.rootConnectionName??t.rootConnectionName})))(t,this.activeNode):t;this.routes.push(...this.preserveTerminalPcbPortIds&&this.activeNode?((t,e)=>{const n=e.portPoints.filter(t=>void 0!==t.pcb_port_id);return t.map(t=>{const e=t.route[0],o=t.route.at(-1),i=n.find(n=>void 0!==e&&n.connectionName===t.connectionName&&n.x===e.x&&n.y===e.y&&n.z===e.z),r=n.find(e=>void 0!==o&&e.connectionName===t.connectionName&&e.x===o.x&&e.y===o.y&&e.z===o.z);return{...t,startPcbPortId:i?.pcb_port_id,endPcbPortId:r?.pcb_port_id}})})(e,this.activeNode):e),this.stats.solvedNodeCount=Number(this.stats.solvedNodeCount??0)+1,this.activeB01Solver=null,this.activeRegularSolver=null,this.activeFallbackSolver=null,this.activeFallbackFixedRouteSections.clear(),this.activeFallbackFixedObstacleRoutes=[],this.activeFallbackPromotedFixedRouteConnectionNames.clear(),this.activeFallbackReason=null,this.activeNode=null}startRegularSolver(t){this.activeNode=t,this.activeRegularSolver=XQ({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById,obstacles:this.obstacles,layerCount:this.layerCount}),this.stats.regularNodeCount=Number(this.stats.regularNodeCount??0)+1}startRegionalFallback(t=new Set){if(!this.activeNode)throw new Error("Pipeline9 cannot start a regional fallback without an active node");const e={...YQ(this.activeNode,this.connMap),availableZ:Array.from({length:this.layerCount},(t,e)=>e)},n=$K(e,this.getUpdatedFixedHdRoutes(),t),o=new Set([...n.fixedRouteSectionsByConnectionName.values()].flatMap(t=>t.sourceRoutes.map(t=>t.connectionName)));for(const e of t)if(!o.has(e))throw new Error(`Pipeline9 could not promote fixed route "${e}" into the active regional fallback`);const i=[...t].filter(t=>!this.activeFallbackPromotedFixedRouteConnectionNames.has(t)).length;this.activeFallbackFixedRouteSections=n.fixedRouteSectionsByConnectionName,this.activeFallbackFixedObstacleRoutes=n.fixedObstacleRoutes,this.activeFallbackPromotedFixedRouteConnectionNames=new Set(t);const r=OQ({fixedObstacleRoutes:this.activeFallbackFixedObstacleRoutes,layerCount:this.layerCount});this.activeFallbackSolver=new FQ({nodeWithPortPoints:n.nodeWithPortPoints,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:this.effort,nodePfById:this.nodePfById,obstacles:[...this.obstacles,...r],boardObstacles:this.obstacles,movablePreloadedConnectionNames:o,viaToPadClearance:this.viaToPadClearance,layerCount:this.layerCount}),0===t.size?this.stats.fallbackNodeCount=Number(this.stats.fallbackNodeCount??0)+1:(this.stats.promotedFallbackAttemptCount=Number(this.stats.promotedFallbackAttemptCount??0)+1,this.stats.promotedFixedRouteCount=Number(this.stats.promotedFixedRouteCount??0)+i)}finishRegionalFallback(){if(!this.activeFallbackSolver)return;if(!this.activeNode)throw new Error("Pipeline9 cannot finish a regional fallback without an active node");this.recordRegionalCandidateRejections();const t=[],e=new Map;for(const n of this.activeFallbackSolver.getOutput()){if(!this.activeFallbackFixedRouteSections.has(n.connectionName)){t.push(n);continue}const o=e.get(n.connectionName)??[];o.push(n),e.set(n.connectionName,o)}const n=[],o=[];for(const[t,i]of this.activeFallbackFixedRouteSections){const r=e.get(t)??[];if(0===r.length){o.push(i);continue}if(r.length>1)return this.error=`Pipeline9 regional fallback expected one replacement for fixed route "${t}", got ${r.length}`,void(this.failed=!0);const s=VK({section:i,replacement:r[0],sourceMutationMasks:this.preloadedTraceMutationMasks,replacementIsMutated:!0});n.push({connectionName:t,section:i,replacement:s.route,mutatedSegments:s.mutatedSegments,replacementProducedSegment:s.replacementProducedSegment})}const i=[...t,...n.map(({replacement:t})=>t)],r=[...this.activeFallbackFixedObstacleRoutes,...o.flatMap(t=>t.sourceRoutes)],s=BQ(this.activeNode,this.obstacleMargin+Math.max(this.traceWidth,this.viaDiameter)/2),a=new Map;for(const t of i)for(const e of r)kQ(t,e,this.connMap)||DQ({left:t,right:e,clearance:this.obstacleMargin,leftBounds:s})&&a.set(e.connectionName,e);if(a.size>0){const t=[...a.keys()],e=[...a].flatMap(([t,e])=>!0===e.isThroughObstacle?[]:[t]),n=new Set(this.activeFallbackPromotedFixedRouteConnectionNames);for(const t of e)n.add(t);if(n.size===this.activeFallbackPromotedFixedRouteConnectionNames.size){const e=[...a].flatMap(([t,e])=>!0===e.isThroughObstacle?[t]:[]);return this.error=e.length>0?`Pipeline9 regional fallback conflicts with immutable through-obstacle route(s): ${e.join(", ")}`:`Pipeline9 promoted regional fallback could not resolve immutable fixed route conflict(s): ${t.join(", ")}`,void(this.failed=!0)}return void this.startRegionalFallback(n)}const c=new Map;for(const{section:t,replacementProducedSegment:e}of n)if(e)for(const e of t.sourceRoutes){const t=e.preloadedRoutePositionStart,n=e.preloadedRoutePositionEnd;if(void 0===t!=(void 0===n))throw new Error(`Pipeline9 fixed route "${e.connectionName}" has incomplete route-position metadata`);const o=Math.min(t??e.preloadedRouteIndex,n??e.preloadedRouteIndex),i=Math.max(t??e.preloadedRouteIndex,n??e.preloadedRouteIndex),r=c.get(e.preloadedTraceIndex);c.set(e.preloadedTraceIndex,{start:Math.min(r?.start??o,o),end:Math.max(r?.end??i,i)})}for(const{connectionName:t,section:e,replacement:o,mutatedSegments:i}of n){this.fixedRouteReplacements.set(t,o),this.preloadedTraceMutationMasks.set(t,i);for(const t of e.sourceRoutes.slice(1))this.removedFixedRouteConnectionNames.add(t.connectionName),this.preloadedTraceMutationMasks.delete(t.connectionName)}const l=$K({...YQ(this.activeNode,this.connMap),portPoints:[],portPointsInPairs:[],availableZ:Array.from({length:this.layerCount},(t,e)=>e)},this.getUpdatedFixedHdRoutes()),d=new Set;for(const t of l.fixedRouteSectionsByConnectionName.values()){const e=t.sourceRoutes[0];if(!e)continue;const n=c.get(e.preloadedTraceIndex);if(n)for(const[o,i]of t.sourceRoutes.entries()){const r=i.preloadedRoutePositionStart??i.preloadedRouteIndex,s=i.preloadedRoutePositionEnd??i.preloadedRouteIndex,a={start:Math.min(r,s),end:Math.max(r,s)},c=a.start===a.end,l=n.start===n.end;if(!(c||l?a.start<=n.end&&n.start<=a.end:a.start<n.end&&n.start<a.end))continue;d.add(e.preloadedTraceIndex);const h=[...this.preloadedTraceMutationMasks.get(i.connectionName)??Array(i.route.length-1).fill(!1)];if(h.length!==i.route.length-1)throw new Error(`Pipeline9 fixed route mutation mask for "${i.connectionName}" has ${h.length} segments, expected ${i.route.length-1}`);const u=0===o?t.start.segmentIndex:0,p=o===t.sourceRoutes.length-1?t.end.segmentIndex:i.route.length-2;for(let t=u;t<=p;t++)h[t]=!0;this.preloadedTraceMutationMasks.set(i.connectionName,h)}}for(const t of c.keys())if(!d.has(t))throw new Error(`Pipeline9 could not capture accepted mutation provenance for trace ${t}`);const h=n.reduce((t,{section:e})=>t+e.sourceRoutes.length,0);this.stats.reroutedFixedRouteCount=Number(this.stats.reroutedFixedRouteCount??0)+h,this.stats.reroutedFixedRouteSectionCount=Number(this.stats.reroutedFixedRouteSectionCount??0)+n.length,this.finishActiveNode(t)}recordRegionalCandidateRejections(){if(!this.activeFallbackSolver)return;const t=this.activeFallbackSolver.stats;this.stats.regionalPreloadedViaCandidateRejectionCount=Number(this.stats.regionalPreloadedViaCandidateRejectionCount??0)+Number(t.preloadedViaCandidateRejectionCount??0),this.stats.regionalForceImproveCandidateRejectionCount=Number(this.stats.regionalForceImproveCandidateRejectionCount??0)+Number(t.forceImproveCandidateRejectionCount??0),this.stats.regionalRepairCandidateRejectionCount=Number(this.stats.regionalRepairCandidateRejectionCount??0)+Number(t.repairCandidateRejectionCount??0)}finishRegularSolverFailure(t){if(this.activeFallbackReason=`regular high-density routing failed: ${t}`,this.activeRegularSolver=null,!this.enableRegionalFallback)return this.error=`Pipeline9 ${this.activeFallbackReason}`,this.failed=!0,void(this.activeNode=null);this.startRegionalFallback()}_step(){if(this.activeFallbackSolver){if(this.activeFallbackSolver.step(),this.activeFallbackSolver.failed)return this.recordRegionalCandidateRejections(),this.error=[`Pipeline9 primary high-density routing failed: ${this.activeFallbackReason??"unknown error"}`,`regional fallback failed: ${this.activeFallbackSolver.error??"unknown error"}`].join("; "),this.failed=!0,this.activeFallbackSolver=null,this.activeFallbackFixedRouteSections.clear(),this.activeFallbackFixedObstacleRoutes=[],this.activeFallbackPromotedFixedRouteConnectionNames.clear(),void(this.activeNode=null);if(!this.activeFallbackSolver.solved)return;return void this.finishRegionalFallback()}if(this.activeRegularSolver){if(this.activeRegularSolver.step(),this.activeRegularSolver.failed)return void this.finishRegularSolverFailure(this.activeRegularSolver.error??"unknown error");if(!this.activeRegularSolver.solved)return;return void this.finishActiveNode(this.activeRegularSolver.routes)}if(this.activeB01Solver){if(this.activeB01Solver.step(),this.activeB01Solver.failed)return this.failedSolvers.push(this.activeB01Solver),this.activeFallbackReason=`B01 failed: ${this.activeB01Solver.error??"unknown error"}`,this.activeB01Solver=null,this.enableRegionalFallback?void this.startRegionalFallback():(this.error=`Pipeline9 ${this.activeFallbackReason}`,this.failed=!0,void(this.activeNode=null));if(!this.activeB01Solver.solved)return;return void this.finishActiveNode(this.activeB01Solver.getOutput())}const t=this.unsolvedNodePortPoints.pop();if(!t)return void(this.solved=!0);const e=BQ(t,this.obstacleMargin),n=Math.max(this.traceWidth,this.viaDiameter)/2,o=this.getUpdatedFixedHdRoutes().filter(o=>((t,e,n,o)=>{const i=new Set(e.availableZ??e.portPoints.map(t=>t.z));for(let e=1;e<t.route.length;e++){const r=t.route[e-1],s=t.route[e];if(r.z===s.z){if(i.has(r.z)&&$Q(r,s,t.traceThickness/2+o,n))return!0;continue}const a=Math.min(r.z,s.z),c=Math.max(r.z,s.z);if([...i].some(t=>t>=a&&t<=c)&&jQ(s,t.viaDiameter/2+o,n))return!0}return!1})(o,t,e,n)).flatMap(e=>((t,e)=>{const n=new Set(e.availableZ??e.portPoints.map(t=>t.z));if(0===n.size)throw new Error(`Pipeline9 B01 node "${e.capacityMeshNodeId}" has no available layers`);const o={type:"route",connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,traceThickness:t.traceThickness,viaDiameter:t.viaDiameter},i=[];for(let e=1;e<t.route.length;e++){const r=t.route[e-1],s=t.route[e];if(r.z===s.z){if(!n.has(r.z))continue;i.push({...o,route:[r,s],vias:[]});continue}const a=Math.min(r.z,s.z),c=Math.max(r.z,s.z);[...n].some(t=>t>=a&&t<=c)&&i.push({...o,route:[r,s],vias:[{x:s.x,y:s.y,zStart:r.z,zEnd:s.z}]})}return i})(e,t));if(this.stats.fixedObstacleUses=Number(this.stats.fixedObstacleUses??0)+o.length,0===o.length)return void this.startRegularSolver(t);const i=(this.includeBoardObstacles?this.obstacles:[]).filter(t=>((t,e)=>{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.abs(Math.cos(n)),i=Math.abs(Math.sin(n)),r=t.width/2*o+t.height/2*i,s=t.width/2*i+t.height/2*o;return t.center.x-r<=e.maxX&&t.center.x+r>=e.minX&&t.center.y-s<=e.maxY&&t.center.y+s>=e.minY})(t,e)).map(e=>(({obstacle:t,node:e,connMap:n,layerCount:o})=>{const i=new Set(e.availableZ??e.portPoints.map(t=>t.z)),r=(t.zLayers??t.layers.map(t=>ko(t,o))).filter(t=>i.has(t));if(0===r.length)return;const s=t.connectedTo[0]??t.obstacleId??`pipeline9_obstacle_${t.center.x}_${t.center.y}`;return{type:"rect",connectionName:s,rootConnectionName:n.getNetConnectedToId(s)??s,center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,zLayers:r}})({obstacle:e,node:t,connMap:this.connMap,layerCount:this.layerCount})).filter(t=>void 0!==t);if(this.stats.boardObstacleUses=Number(this.stats.boardObstacleUses??0)+i.length,this.activeNode=t,t.width>15||t.height>15)return this.activeFallbackReason=`B01 node "${t.capacityMeshNodeId}" exceeds the 15x15mm routing limit (${t.width}x${t.height}mm)`,void this.startRegionalFallback();const r=YQ(t,this.connMap);this.stats.b01NodeCount=Number(this.stats.b01NodeCount??0)+1,this.activeB01Solver=new TQ({...sQ,nodeWithPortPoints:r,obstacles:[...o,...i],viaDiameter:this.viaDiameter,viaMinDistFromBorder:this.viaDiameter/2,traceThickness:this.traceWidth,traceMargin:this.obstacleMargin,obstacleClearanceMargin:.15,effort:this.effort}),void 0!==this.maxB01Rips&&(this.activeB01Solver.MAX_RIPS=this.maxB01Rips)}visualize(){return this.activeFallbackSolver?.visualize()??this.activeRegularSolver?.visualize()??this.activeB01Solver?.visualize()??{lines:this.routes.flatMap(t=>t.route.slice(0,-1).map((e,n)=>({points:[e,t.route[n+1]],strokeWidth:t.traceThickness,layer:`z${e.z}`,label:t.connectionName}))),points:[],rects:[],circles:[]}}},WQ=(t,e)=>{const n=e*Math.PI/180;return{x:t.x*Math.cos(n)-t.y*Math.sin(n),y:t.x*Math.sin(n)+t.y*Math.cos(n)}},HQ=({x:t,y:e,width:n,height:o,ccwRotation:i})=>{const r=n/2,s=o/2;return[{x:-r,y:-s},{x:r,y:-s},{x:r,y:s},{x:-r,y:s}].map(n=>{const o=WQ(n,i);return{x:t+o.x,y:e+o.y}})},GQ=t=>{const e="rotated_pill"===t.shape?t.ccw_rotation:0,n=Math.max(Math.max(t.width,t.height)/2-t.radius,0),o=t.width>=t.height?{x:n,y:0}:{x:0,y:n},i=WQ(o,e);return{start:{x:t.x-i.x,y:t.y-i.y},end:{x:t.x+i.x,y:t.y+i.y},radius:t.radius}},UQ=t=>{if("pcb_smtpad"===t.type){if("polygon"===t.shape)return t.points;if("rotated_rect"===t.shape)return HQ({x:t.x,y:t.y,width:t.width,height:t.height,ccwRotation:t.ccw_rotation})}if("pcb_plated_hole"===t.type&&"rect_pad_width"in t&&"rect_pad_height"in t)return HQ({x:t.x,y:t.y,width:t.rect_pad_width,height:t.rect_pad_height,ccwRotation:"rect_ccw_rotation"in t&&"number"==typeof t.rect_ccw_rotation?t.rect_ccw_rotation:0});throw new Error(`Expected polygonal pad geometry, got ${t.type} with shape "${t.shape}"`)},ZQ=t=>t.map((e,n)=>[e,t[(n+1)%t.length]]),qQ=(t,e,n,o)=>{const i=ve(t,e,n,o);if(i)return{distance:0,pointOnA:i,pointOnB:i,center:i};const r=[{pointOnA:t,pointOnB:ze(t,n,o)},{pointOnA:e,pointOnB:ze(e,n,o)},{pointOnA:ze(n,t,e),pointOnB:n},{pointOnA:ze(o,t,e),pointOnB:o}];let s=r[0],a=Ye(s.pointOnA,s.pointOnB);for(const t of r.slice(1)){const e=Ye(t.pointOnA,t.pointOnB);e<a&&(s=t,a=e)}return{distance:Oe(t,e,n,o),pointOnA:s.pointOnA,pointOnB:s.pointOnB,center:{x:(s.pointOnA.x+s.pointOnB.x)/2,y:(s.pointOnA.y+s.pointOnB.y)/2}}};function JQ(t,e){return Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2)}var KQ=1e-9,QQ=1e-9;function t0(t,e){const n=(t.y-e.start.y)*(e.end.x-e.start.x)-(t.x-e.start.x)*(e.end.y-e.start.y);if(Math.abs(n)>KQ)return!1;const o=(t.x-e.start.x)*(e.end.x-e.start.x)+(t.y-e.start.y)*(e.end.y-e.start.y);if(o<-1e-9)return!1;return o<=(e.end.x-e.start.x)**2+(e.end.y-e.start.y)**2+KQ}function e0(t,e){let n=!1;for(let o=0,i=e.length-1;o<e.length;i=o++){const r=e[o],s=e[i];if(t0(t,{start:r,end:s}))return!0;r.y>t.y!=s.y>t.y&&t.x<(s.x-r.x)*(t.y-r.y)/(s.y-r.y)+r.x&&(n=!n)}return n}function n0(t,e){if("pcb_smtpad"===e.type){if("circle"===e.shape)return JQ(t,e)<=e.radius+QQ;if("rect"===e.shape){const n=e.width/2,o=e.height/2;return Math.abs(t.x-e.x)<=n+QQ&&Math.abs(t.y-e.y)<=o+QQ}if("rotated_rect"===e.shape)return e0(t,UQ(e));if("pill"===e.shape||"rotated_pill"===e.shape){if("rotated_pill"===e.shape){const n=GQ(e);return be(t,n.start,n.end)<=n.radius+QQ}const n=e.width/2,o=e.height/2,i=e.radius;if(Math.abs(t.x-e.x)<=n-i+QQ&&Math.abs(t.y-e.y)<=o+QQ)return!0;const r=Math.max(Math.abs(t.x-e.x)-(n-i),0),s=Math.max(Math.abs(t.y-e.y)-(o-i),0),a=i+QQ;return r*r+s*s<=a*a}if("polygon"===e.shape)return e0(t,e.points)}if("pcb_plated_hole"===e.type){if("circle"===e.shape)return JQ(t,e)<=e.outer_diameter/2+QQ;if("rect_pad_width"in e&&"rect_pad_height"in e)return e0(t,UQ(e));if("oval"===e.shape||"pill"===e.shape)return Math.abs(t.x-e.x)<=e.outer_width/2+QQ&&Math.abs(t.y-e.y)<=e.outer_height/2+QQ}return!1}function o0(t,e,n,o){return Math.sqrt((n-t)**2+(o-e)**2)}var i0=.1,r0=.1,s0=.2,a0=.1,c0=.005,l0=t=>t.find(t=>"pcb_board"===t.type),d0=(t,e)=>t?.[e],h0=t=>EM([t]),u0=t=>{const e=h0(t);return Math.min(e.maxX-e.minX,e.maxY-e.minY)/2},p0=t=>{const e=(t=>{const e=h0(t);return $e({x:e.minX,y:e.minY},{x:e.maxX,y:e.maxY})})(t);return{kind:"circle",x:e.x,y:e.y,radius:u0(t)}},m0=t=>vM(t).pcb_trace.list().flatMap(t=>{const e=[];for(let n=0;n<t.route.length-1;n++){const o=t.route[n],i=t.route[n+1];"wire"===o.route_type&&("wire"===i.route_type&&o.layer===i.layer&&e.push({type:"pcb_trace_segment",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:"width"in o?o.width:"width"in i?i.width:a0,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),g0=t=>{const e=t._pcbTrace.route.flatMap(t=>"through_pad"===t.route_type?[t.start,t.end]:[{x:t.x,y:t.y}]),n=e[0],o=e[e.length-1];return n&&o?$e(n,o):$e({x:t.x1,y:t.y1},{x:t.x2,y:t.y2})},f0=({tracePoint:t,obstaclePoint:e,traceRadius:n,obstacleRadius:o})=>{const i=e.x-t.x,r=e.y-t.y,s=Math.hypot(i,r);if(0===s)return $e(t,e);const a=i/s,c=r/s;return $e({x:t.x+a*n,y:t.y+c*n},{x:e.x-a*o,y:e.y-c*o})},y0=(t,e)=>{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=t.thickness/2;if("pcb_via"===e.type||("pcb_via"===(r=e).type||"circle"===r.shape)){const t="pcb_via"===e.type?{x:e.x,y:e.y,radius:e.outer_diameter/2}:p0(e),r=ze(t,n,o);return{gap:De(n,o,t)-i,center:f0({tracePoint:r,obstaclePoint:t,traceRadius:i,obstacleRadius:t.radius})}}var r;if((t=>"pcb_smtpad"===t.type&&("pill"===t.shape||"rotated_pill"===t.shape))(e)){const n=((t,e)=>{const n=GQ(e),o=qQ({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},n.start,n.end);return{distance:o.distance,center:o.center,radius:n.radius,tracePoint:o.pointOnA,obstaclePoint:o.pointOnB}})(t,e);return{gap:n.distance-i-n.radius,center:f0({tracePoint:n.tracePoint,obstaclePoint:n.obstaclePoint,traceRadius:i,obstacleRadius:n.radius})}}const s=((t,e,n)=>{if(n.length<3)return{distance:Number.POSITIVE_INFINITY,center:t,tracePoint:t,obstaclePoint:t};const o=ZQ(n).map(([n,o])=>ve(t,e,n,o)).filter(t=>null!==t);if(o.length>0){const n=e.x-t.x,i=e.y-t.y,r=n*n+i*i;return o.sort((e,o)=>((e.x-t.x)*n+(e.y-t.y)*i)/r-((o.x-t.x)*n+(o.y-t.y)*i)/r),{distance:0,center:o[0],tracePoint:o[0],obstaclePoint:o[0]}}if(Ne(t,n)||Ne(e,n)){const n={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return{distance:0,center:n,tracePoint:n,obstaclePoint:n}}let i=qQ(t,e,n[0],n[1]);for(const[o,r]of ZQ(n).slice(1)){const n=qQ(t,e,o,r);n.distance<i.distance&&(i=n)}return{distance:i.distance,center:i.center,tracePoint:i.pointOnA,obstaclePoint:i.pointOnB}})(n,o,(t=>{if("pcb_smtpad"===t.type&&("polygon"===t.shape||"rotated_rect"===t.shape))return{kind:"polygon",points:UQ(t)};if("pcb_plated_hole"===t.type&&"rect_pad_width"in t&&"rect_pad_height"in t)return{kind:"polygon",points:UQ(t)};const e=h0(t);return{kind:"polygon",points:[{x:e.minX,y:e.minY},{x:e.maxX,y:e.minY},{x:e.maxX,y:e.maxY},{x:e.minX,y:e.maxY}]}})(e).points);return{gap:s.distance-i,center:f0({tracePoint:s.tracePoint,obstaclePoint:s.obstaclePoint,traceRadius:i,obstacleRadius:0})}},_0=t=>t<=0,b0=class{buckets;objectsById;getBounds;getId;CELL_SIZE=.4;constructor({objects:t,getBounds:e,getId:n,CELL_SIZE:o}){this.buckets=new Map,this.objectsById=new Map,this.getBounds=e,this.getId=n??(()=>this._getNextId()),this.CELL_SIZE=o??this.CELL_SIZE;for(const e of t)this.addObject(e)}_idCounter=0;_getNextId(){return""+this._idCounter++}addObject(t){const e=this.getBounds(t),n=this.getId(t),o={...t,spatialIndexId:n};this.objectsById.set(n,o);const i=Math.floor(e.minX/this.CELL_SIZE),r=Math.floor(e.minY/this.CELL_SIZE),s=Math.floor(e.maxX/this.CELL_SIZE),a=Math.floor(e.maxY/this.CELL_SIZE);for(let t=i;t<=s;t++)for(let e=r;e<=a;e++){const n=`${t}x${e}`,i=this.buckets.get(n);i?i.push(o):this.buckets.set(n,[o])}}removeObject(t){const e=this.objectsById.get(t);if(!e)return!1;this.objectsById.delete(t);const n=this.getBounds(e),o=Math.floor(n.minX/this.CELL_SIZE),i=Math.floor(n.minY/this.CELL_SIZE),r=Math.floor(n.maxX/this.CELL_SIZE),s=Math.floor(n.maxY/this.CELL_SIZE);for(let e=o;e<=r;e++)for(let n=i;n<=s;n++){const o=`${e}x${n}`,i=this.buckets.get(o);if(i){const e=i.findIndex(e=>e.spatialIndexId===t);-1!==e&&(i.splice(e,1),0===i.length&&this.buckets.delete(o))}}return!0}getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getObjectsInBounds(t,e=0){const n=[],o=new Set,i=Math.floor((t.minX-e)/this.CELL_SIZE),r=Math.floor((t.minY-e)/this.CELL_SIZE),s=Math.floor((t.maxX+e)/this.CELL_SIZE),a=Math.floor((t.maxY+e)/this.CELL_SIZE);for(let t=i;t<=s;t++)for(let e=r;e<=a;e++){const i=`${t}x${e}`,r=this.buckets.get(i)||[];for(const t of r){const e=t.spatialIndexId;o.has(e)||(o.add(e),n.push(t))}}return n}};function x0(t){return"pcb_trace_segment"===t.type||"pcb_smtpad"===t.type?[t.layer]:"pcb_plated_hole"===t.type?Array.isArray(t.layers)?t.layers:[...WS]:"pcb_hole"===t.type?[...WS]:"pcb_via"===t.type?Array.isArray(t.layers)?t.layers:[...WS]:"pcb_keepout"===t.type&&Array.isArray(t.layers)?t.layers:[]}var v0=(t,e)=>{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i=e.minX,r=e.minY,s=e.maxX,a=e.maxY;if(n.x===o.x&&n.y===o.y){const t=Math.max(i,Math.min(s,n.x)),e=Math.max(r,Math.min(a,n.y));return t===n.x&&e===n.y?{x:n.x,y:n.y}:{x:t,y:e}}const c=o.x-n.x,l=o.y-n.y,d=0!==c?(i-n.x)/c:Number.NEGATIVE_INFINITY,h=0!==c?(s-n.x)/c:Number.POSITIVE_INFINITY,u=0!==l?(r-n.y)/l:Number.NEGATIVE_INFINITY,p=0!==l?(a-n.y)/l:Number.POSITIVE_INFINITY,m=Math.max(Math.min(d,h),Math.min(u,p)),g=Math.min(Math.max(d,h),Math.max(u,p));if(m<=g&&g>=0&&m<=1){const t=Math.max(0,Math.min(1,m));return{x:n.x+t*c,y:n.y+t*l}}const f={x:Math.max(i,Math.min(s,n.x)),y:Math.max(r,Math.min(a,n.y))},y={x:Math.max(i,Math.min(s,o.x)),y:Math.max(r,Math.min(a,o.y))},_=(f.x-n.x)**2+(f.y-n.y)**2,b=(y.x-o.x)**2+(y.y-o.y)**2,x=[{start:{x:i,y:r},end:{x:s,y:r}},{start:{x:s,y:r},end:{x:s,y:a}},{start:{x:s,y:a},end:{x:i,y:a}},{start:{x:i,y:a},end:{x:i,y:r}}];let v=Math.min(_,b),S=_<=b?f:y;const I=(t,e,n)=>Math.max(e,Math.min(n,t));for(const t of x){const e={x:o.x-n.x,y:o.y-n.y},i={x:t.end.x-t.start.x,y:t.end.y-t.start.y},r={x:n.x-t.start.x,y:n.y-t.start.y},s=e.x*e.x+e.y*e.y,a=e.x*i.x+e.y*i.y,c=e.x*r.x+e.y*r.y,l=i.x*i.x+i.y*i.y,d=i.x*r.x+i.y*r.y,h=s*l-a*a;if(Math.abs(h)<1e-10)continue;let u=(a*d-l*c)/h,p=(s*d-a*c)/h;u=I(u,0,1),p=I(p,0,1);const m={x:n.x+u*e.x,y:n.y+u*e.y},g={x:t.start.x+p*i.x,y:t.start.y+p*i.y},f=m.x-g.x,y=m.y-g.y,_=f*f+y*y;_<v&&(v=_,S={x:(m.x+g.x)/2,y:(m.y+g.y)/2})}return S},S0=(t,e)=>{const n={x:t.x1,y:t.y1},o={x:t.x2,y:t.y2},i={x:e.x1,y:e.y1},r={x:e.x2,y:e.y2},s={x:o.x-n.x,y:o.y-n.y},a={x:r.x-i.x,y:r.y-i.y},c=s.x*s.x+s.y*s.y,l=a.x*a.x+a.y*a.y;if(0===c||0===l){if(0===c&&0===l)return{x:(n.x+i.x)/2,y:(n.y+i.y)/2};if(0===c){const t=C0(((n.x-i.x)*a.x+(n.y-i.y)*a.y)/l,0,1),e={x:i.x+t*a.x,y:i.y+t*a.y};return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}}const t=C0(((i.x-n.x)*s.x+(i.y-n.y)*s.y)/c,0,1),e={x:n.x+t*s.x,y:n.y+t*s.y};return{x:(e.x+i.x)/2,y:(e.y+i.y)/2}}const d=n.x-i.x,h=n.y-i.y,u=s.x*s.x+s.y*s.y,p=s.x*a.x+s.y*a.y,m=s.x*d+s.y*h,g=a.x*a.x+a.y*a.y,f=a.x*d+a.y*h,y=u*g-p*p;if(y<1e-10)return I0(n,o,i,r,s,a,c,l);let _=(p*f-g*m)/y,b=(u*f-p*m)/y;_=C0(_,0,1),b=C0(b,0,1),b=(_*p+f)/g,b=C0(b,0,1),_=(b*p-m)/u,_=C0(_,0,1);const x=n.x+_*s.x,v=n.y+_*s.y,S=i.x+b*a.x,I=i.y+b*a.y,C=x-S,P=v-I;Math.sqrt(C*C+P*P);return{x:(x+S)/2,y:(v+I)/2}},I0=(t,e,n,o,i,r,s,a)=>{let c=((n.x-t.x)*i.x+(n.y-t.y)*i.y)/s;c=C0(c,0,1);const l={x:t.x+c*i.x,y:t.y+c*i.y};let d=((o.x-t.x)*i.x+(o.y-t.y)*i.y)/s;d=C0(d,0,1);const h={x:t.x+d*i.x,y:t.y+d*i.y};let u=((t.x-n.x)*r.x+(t.y-n.y)*r.y)/a;u=C0(u,0,1);const p={x:n.x+u*r.x,y:n.y+u*r.y};let m=((e.x-n.x)*r.x+(e.y-n.y)*r.y)/a;m=C0(m,0,1);const g={x:n.x+m*r.x,y:n.y+m*r.y},f=[{pointA:l,pointB:n,distance:Math.sqrt((l.x-n.x)**2+(l.y-n.y)**2)},{pointA:h,pointB:o,distance:Math.sqrt((h.x-o.x)**2+(h.y-o.y)**2)},{pointA:t,pointB:p,distance:Math.sqrt((t.x-p.x)**2+(t.y-p.y)**2)},{pointA:e,pointB:g,distance:Math.sqrt((e.x-g.x)**2+(e.y-g.y)**2)}].reduce((t,e)=>e.distance<t.distance?e:t);return{x:(f.pointA.x+f.pointB.x)/2,y:(f.pointA.y+f.pointB.y)/2}},C0=(t,e,n)=>Math.max(e,Math.min(n,t)),P0=t=>{if("pcb_trace_segment"===t.type)return{minX:Math.min(t.x1,t.x2),minY:Math.min(t.y1,t.y2),maxX:Math.max(t.x1,t.x2),maxY:Math.max(t.y1,t.y2)};if("pcb_smtpad"===t.type||"pcb_plated_hole"===t.type){if("pcb_smtpad"===t.type&&("rotated_rect"===t.shape||"polygon"===t.shape)||"pcb_plated_hole"===t.type&&"rect_pad_width"in t&&"rect_pad_height"in t){const e=UQ(t);return{minX:Math.min(...e.map(t=>t.x)),minY:Math.min(...e.map(t=>t.y)),maxX:Math.max(...e.map(t=>t.x)),maxY:Math.max(...e.map(t=>t.y))}}if("pcb_smtpad"===t.type&&"rotated_pill"===t.shape){const e=GQ(t);return{minX:Math.min(e.start.x,e.end.x)-e.radius,minY:Math.min(e.start.y,e.end.y)-e.radius,maxX:Math.max(e.start.x,e.end.x)+e.radius,maxY:Math.max(e.start.y,e.end.y)+e.radius}}}return EM([t])};function M0(t){return"wire"!==t.route_type?[]:[t.start_pcb_port_id,t.end_pcb_port_id].filter(t=>Boolean(t))}function N0(t){const e=new Set;for(const n of t.route)for(const t of M0(n))e.add(t);return Array.from(e)}function w0(t){const e=new Set;for(const n of t)for(const t of N0(n))e.add(t);return Array.from(e)}var T0=t=>{if("pcb_via"===t.type)return t.outer_diameter/2;if("pcb_plated_hole"===t.type&&"circle"===t.shape)return t.outer_diameter/2;if("pcb_hole"===t.type&&"circle"===t.hole_shape)return t.hole_diameter/2;if("pcb_smtpad"===t.type&&"circle"===t.shape)return t.radius;throw new Error(`Could not determine radius of element: ${JSON.stringify(t)}`)},R0=t=>"pcb_port"===t.type?t.pcb_port_id:"pcb_smtpad"===t.type?t.pcb_smtpad_id:t.pcb_plated_hole_id;function E0(t,{connMap:e,minClearance:n}={}){const o=[];(t=>{const e=t.filter(t=>"pcb_port"===t.type),n=t.filter(t=>"pcb_smtpad"===t.type),o=t.filter(t=>"pcb_trace"===t.type);function i(t,o={}){const i=o.traceWidth||0,r=e.find(e=>o0(e.x,e.y,t.x,t.y)<.01);if(r)return r.pcb_port_id;if(o.isFirstOrLastPoint){const e=n.find(e=>"rect"===e.shape?Math.abs(t.x-e.x)<e.width/2+i/2&&Math.abs(t.y-e.y)<e.height/2+i/2:"circle"===e.shape?o0(t.x,t.y,e.x,e.y)<e.radius:"pill"===e.shape||"rotated_pill"===e.shape?n0(t,e):void 0);if(e)return e.pcb_port_id??null}return null}for(const t of o)for(let e=0;e<t.route.length;e++){const n=t.route[e],o=0===e||e===t.route.length-1;if("wire"===n.route_type){if(!n.start_pcb_port_id&&0===e){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t&&(n.start_pcb_port_id=t)}if(!n.end_pcb_port_id&&e===t.route.length-1){const t=i(n,{isFirstOrLastPoint:o,traceWidth:n.width});t&&(n.end_pcb_port_id=t)}}}})(t),e??=ei(t);const i=l0(t);n??=d0(i,"min_trace_to_pad_edge_clearance")??.1;const r=vM(t).pcb_trace.list().flatMap(t=>{const e=[];for(let n=0;n<t.route.length-1;n++){const o=t.route[n],i=t.route[n+1];"wire"===o.route_type&&("wire"===i.route_type&&o.layer===i.layer&&e.push({type:"pcb_trace_segment",pcb_trace_id:t.pcb_trace_id,_pcbTrace:t,thickness:"width"in o?o.width:"width"in i?i.width:a0,layer:o.layer,x1:o.x,y1:o.y,x2:i.x,y2:i.y}))}return e}),s=vM(t).pcb_smtpad.list(),a=vM(t).pcb_plated_hole.list(),c=vM(t).pcb_port.list(),l=vM(t).pcb_hole.list(),d=vM(t).pcb_via.list(),h=vM(t).pcb_keepout.list(),u=[...c,...s,...a],p=new Map;for(const t of h){const e=new Set(t.excluded_pcb_component_ids??[]);0!==e.size&&p.set(t.pcb_keepout_id,u.filter(t=>t.pcb_component_id&&e.has(t.pcb_component_id)).map(R0))}const m=[...r,...s,...a,...l,...d,...h],g=new b0({objects:m,getBounds:P0}),f=e=>NM(t,e),y=(t,e,n)=>_0(n)?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,_=new Set;for(const t of r){const i=n,r=P0(t),s=g.getObjectsInBounds(r,i+t.thickness/2);if(t.x1!==t.x2||t.y1!==t.y2)for(const r of s){if(!x0(r).includes(t.layer))continue;if("pcb_keepout"===r.type&&(p.get(r.pcb_keepout_id)??[]).some(n=>e.areIdsConnected(t.pcb_trace_id,n)))continue;if("pcb_trace_segment"===r.type){const i=r;if(t.layer!==i.layer)continue;if(e.areIdsConnected(t.pcb_trace_id,i.pcb_trace_id))continue;const s=Oe({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:i.x1,y:i.y1},{x:i.x2,y:i.y2})-t.thickness/2-i.thickness/2;if(s>n-c0)continue;const a=`overlap_${t.pcb_trace_id}_${i.pcb_trace_id}`,c=`overlap_${i.pcb_trace_id}_${t.pcb_trace_id}`;if(_.has(a))continue;if(_.has(c))continue;_.add(a),o.push({type:"pcb_trace_error",error_type:"pcb_trace_error",message:y(f(t.pcb_trace_id),f(i.pcb_trace_id),s),pcb_trace_id:t.pcb_trace_id,source_trace_id:"",pcb_trace_error_id:a,pcb_component_ids:[],center:S0(t,i),pcb_port_ids:w0([t._pcbTrace,i._pcbTrace])});continue}const s=AM(r);if(e.areIdsConnected(t.pcb_trace_id,"pcb_trace_id"in r?r.pcb_trace_id:s))continue;if("pcb_smtpad"===r.type||"pcb_plated_hole"===r.type||"pcb_via"===r.type){const{gap:e,center:n}=y0(t,r);if(!_0(e))continue;const i=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(i))continue;_.add(i),o.push({type:"pcb_trace_error",error_type:"pcb_trace_error",message:y(f(t.pcb_trace_id),`${r.type} "${f(s)}"`,e),pcb_trace_id:t.pcb_trace_id,center:n,source_trace_id:"",pcb_trace_error_id:i,pcb_component_ids:["pcb_component_id"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...w0([t._pcbTrace]),"pcb_port_id"in r?r.pcb_port_id:void 0].filter(Boolean)});continue}if("pcb_hole"===r.type){const e=T0(r),i=De({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},{x:r.x,y:r.y,radius:e})-t.thickness/2;if(i>n-c0)continue;const a=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(a))continue;_.add(a),o.push({type:"pcb_trace_error",error_type:"pcb_trace_error",message:y(f(t.pcb_trace_id),`${r.type} "${f(AM(r))}"`,i),pcb_trace_id:t.pcb_trace_id,center:v0(t,P0(r)),source_trace_id:"",pcb_trace_error_id:a,pcb_component_ids:["pcb_component_id"in r?r.pcb_component_id:void 0].filter(Boolean),pcb_port_ids:[...w0([t._pcbTrace]),"pcb_port_id"in r?r.pcb_port_id:void 0].filter(Boolean)})}const a=ke({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},P0(r))-t.thickness/2;if(a+c0<i){const e=`overlap_${t.pcb_trace_id}_${s}`;if(_.has(e))continue;_.add(e),o.push({type:"pcb_trace_error",error_type:"pcb_trace_error",message:y(f(t.pcb_trace_id),`${r.type} "${f(AM(r))}"`,a),pcb_trace_id:t.pcb_trace_id,source_trace_id:"",pcb_trace_error_id:e,pcb_component_ids:["pcb_component_id"in r?r.pcb_component_id:void 0].filter(Boolean),center:v0(t,P0(r)),pcb_port_ids:[...w0([t._pcbTrace]),"pcb_port_id"in r?r.pcb_port_id:void 0].filter(Boolean)})}}}return o}function A0(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function O0(t,e){return A0(t,e)<=c0}function k0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=>"pcb_via"===t.type);if(o.length<2)return[];const i=l0(t);n??=d0(i,"min_via_hole_edge_to_via_hole_edge_clearance")??i0,e??=ei(t);const r=[],s=new Set;for(let i=0;i<o.length;i++)for(let a=i+1;a<o.length;a++){const c=o[i],l=o[a];if(O0(c,l))continue;if(!e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=A0(c,l)-c.hole_diameter/2-l.hole_diameter/2;if(d+c0>=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join("_");s.has(h)||(s.add(h),r.push({type:"pcb_via_clearance_error",pcb_error_id:`same_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} are too close together (gap: ${d.toFixed(3)}mm)`,error_type:"pcb_via_clearance_error",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return r}function L0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=>"pcb_via"===t.type);if(o.length<2)return[];const i=l0(t);n??=d0(i,"min_via_hole_edge_to_via_hole_edge_clearance")??i0,e??=ei(t);const r=[],s=new Set;for(let i=0;i<o.length;i++)for(let a=i+1;a<o.length;a++){const c=o[i],l=o[a];if(O0(c,l))continue;if(e.areIdsConnected(c.pcb_via_id,l.pcb_via_id))continue;const d=A0(c,l)-c.hole_diameter/2-l.hole_diameter/2;if(d+c0>=n)continue;const h=[c.pcb_via_id,l.pcb_via_id].sort().join("_");s.has(h)||(s.add(h),r.push({type:"pcb_via_clearance_error",pcb_error_id:`different_net_vias_close_${h}`,message:`Vias ${NM(t,c.pcb_via_id)} and ${NM(t,l.pcb_via_id)} from different nets are too close together (gap: ${d.toFixed(3)}mm)`,error_type:"pcb_via_clearance_error",pcb_via_ids:[c.pcb_via_id,l.pcb_via_id],minimum_clearance:n,actual_clearance:d,pcb_center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2}}))}return r}function D0(t){return"through_pad"===t.route_type?{x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2}:{x:t.x,y:t.y}}function z0(t,e,n,o){return"wire"===t.route_type&&e.some(e=>{if(!e.pcb_port_id||e.pcb_port_id===n)return!1;const i=o.get(e.pcb_port_id);return i?.some(e=>n0({x:t.x,y:t.y},e))??!1})}function F0({firstPoint:t,lastPoint:e,port:n,expectedPorts:o,padMap:i}){let r;const s="wire"===t.route_type?t:void 0,a="wire"===e.route_type?e:void 0,c=M0(t).includes(n.pcb_port_id),l=M0(e).includes(n.pcb_port_id);c&&s?r=s:l&&a||z0(t,o,n.pcb_port_id,i)&&a?r=a:z0(e,o,n.pcb_port_id,i)&&s?r=s:s&&a?r=A0(s,n)<=A0(a,n)?s:a:s?r=s:a&&(r=a);const d=D0(t),h=D0(e);return r?{x:r.x,y:r.y}:{x:(d.x+h.x)/2,y:(d.y+h.y)/2}}function B0(t){const e=[],n=t.filter(t=>"pcb_port"===t.type),o=t.filter(t=>"pcb_trace"===t.type),i=t.filter(t=>"source_trace"===t.type),r=t.filter(t=>"pcb_smtpad"===t.type),s=t.filter(t=>"pcb_plated_hole"===t.type),a=new Map,c=new ni(t),l=new Set;for(const t of r)t.pcb_port_id&&a.set(t.pcb_port_id,[...a.get(t.pcb_port_id)??[],t]);for(const t of s)t.pcb_port_id&&a.set(t.pcb_port_id,[...a.get(t.pcb_port_id)??[],t]);for(const r of o){if(0===r.route.length)continue;const s=r.route[0],d=r.route[r.route.length-1],h=i.find(t=>t.source_trace_id===r.source_trace_id),u=h?n.filter(t=>h.connected_source_port_ids?.includes(t.source_port_id)):[];for(let n=1;n<r.route.length-1;n++){const o=r.route[n-1],i=r.route[n],s=r.route[n+1];if("via"===i.route_type){const a="wire"===o.route_type,c="wire"===s.route_type;if(a&&c){const a=Math.abs(o.x-i.x)<.01&&Math.abs(o.y-i.y)<.01,c=Math.abs(s.x-i.x)<.01&&Math.abs(s.y-i.y)<.01;if(!a||!c){const o=PM(t,r.pcb_trace_id);e.push({type:"pcb_trace_error",message:`Via in trace [${o}] is misaligned at position {x: ${i.x}, y: ${i.y}}.`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:"pcb_trace_error",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`misaligned_via_${r.pcb_trace_id}_${n}`,pcb_component_ids:[],pcb_port_ids:[]})}}}}const p=PM(t,r.pcb_trace_id);if(h&&u.length>0){if(l.has(h.source_trace_id))continue;l.add(h.source_trace_id)}for(const n of u){if(!n.pcb_port_id)continue;const l=a.get(n.pcb_port_id);if(!l?.length)continue;let m=!1;const g=[...c.getAllTracesConnectedToTrace(r.pcb_trace_id),...o.filter(t=>t.source_trace_id===h?.source_trace_id)];for(const t of g){if(t.pcb_trace_id===r.pcb_trace_id)continue;if(!t.source_trace_id)continue;const e=i.find(e=>e.source_trace_id===t.source_trace_id);if(!h||t.source_trace_id!==h.source_trace_id&&!e?.connected_source_port_ids.includes(n.source_port_id))continue;const o=t.route[0],s=t.route.at(-1);if(N0(t).includes(n.pcb_port_id)||"wire"===o?.route_type&&l.some(t=>n0(o,t))||"wire"===s?.route_type&&l.some(t=>n0(s,t))){m=!0;break}}if(m)continue;const f="wire"===s.route_type&&l.some(t=>n0({x:s.x,y:s.y},t)),y="wire"===d.route_type&&l.some(t=>n0({x:d.x,y:d.y},t));if(!f&&!y){const o=MM(t,n.pcb_port_id).replace("pcb_port",""),i=l[0].type.replace(/pcb_/,""),c=F0({firstPoint:s,lastPoint:d,port:n,expectedPorts:u,padMap:a});e.push({type:"pcb_trace_error",message:`Trace [${p}] is missing a connection to ${i}${o}`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:"pcb_trace_error",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`missing_connection_${r.pcb_trace_id}_${n.pcb_port_id}`,center:c,pcb_component_ids:[],pcb_port_ids:[n.pcb_port_id]})}}if(0===u.length){let t=!1,n=!1;const o="wire"===s.route_type&&"wire"===d.route_type&&Math.abs(s.x-d.x)<.01&&Math.abs(s.y-d.y)<.01;for(const e of a.values())"wire"===s.route_type&&e.some(t=>n0({x:s.x,y:s.y},t))&&(t=!0),"wire"===d.route_type&&e.some(t=>n0({x:d.x,y:d.y},t))&&(n=!0);t||"wire"!==s.route_type||e.push({type:"pcb_trace_error",message:`Trace [${p}] has disconnected endpoint at (${s.x.toFixed(2)}, ${s.y.toFixed(2)})`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:"pcb_trace_error",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`disconnected_endpoint_${r.pcb_trace_id}_start`,center:{x:s.x,y:s.y},pcb_component_ids:[],pcb_port_ids:[]}),n||"wire"!==d.route_type||o&&!t||e.push({type:"pcb_trace_error",message:`Trace [${p}] has disconnected endpoint at (${d.x.toFixed(2)}, ${d.y.toFixed(2)})`,source_trace_id:h?.source_trace_id||r.source_trace_id||`!${r.pcb_trace_id}`,error_type:"pcb_trace_error",pcb_trace_id:r.pcb_trace_id,pcb_trace_error_id:`disconnected_endpoint_${r.pcb_trace_id}_end`,center:{x:d.x,y:d.y},pcb_component_ids:[],pcb_port_ids:[]})}}return e}function j0(t,e={}){const n=[],o=l0(t);if(!o)return n;const i=e.margin??d0(o,"min_board_edge_clearance")??s0,r=function(t){if(t.outline&&t.outline.length>0)return t.outline.map(t=>({x:t.x,y:t.y}));if(t.center&&"number"==typeof t.width&&"number"==typeof t.height){const e=t.center.x,n=t.center.y,o=t.width/2,i=t.height/2;return[{x:e-o,y:n-i},{x:e+o,y:n-i},{x:e+o,y:n+i},{x:e-o,y:n+i}]}return null}(o);if(!r)return n;const s=vM(t).pcb_trace.list();for(const t of s)if(!(t.route.length<2))for(let e=0;e<t.route.length-1;e++){const o=t.route[e],s=t.route[e+1];if("wire"!==o.route_type||"wire"!==s.route_type)continue;const a="width"in o?o.width:"width"in s?s.width:.1,c={x:o.x,y:o.y},l={x:s.x,y:s.y};let d=Number.POSITIVE_INFINITY;for(let t=0;t<r.length;t++){const e=Oe(c,l,r[t],r[(t+1)%r.length]);e<d&&(d=e)}const h=a/2+i;if(d<h){const o={type:"pcb_trace_error",error_type:"pcb_trace_error",pcb_trace_error_id:`trace_too_close_to_board_${t.pcb_trace_id}_segment_${e}`,message:`Trace too close to board edge (${d.toFixed(3)}mm < ${h.toFixed(3)}mm required, margin: ${i}mm)`,pcb_trace_id:t.pcb_trace_id,source_trace_id:t.source_trace_id||"",center:{x:(c.x+l.x)/2,y:(c.y+l.y)/2},pcb_component_ids:[],pcb_port_ids:[]};n.push(o)}}return n}function $0(t,{connMap:e,minClearance:n}={}){const o=(t=>[...vM(t).pcb_smtpad.list(),...vM(t).pcb_plated_hole.list()])(t),i=m0(t);if(0===o.length||0===i.length)return[];const r=l0(t);n??=d0(r,"min_trace_to_pad_edge_clearance")??r0,e??=ei(t);const s=new b0({objects:o,getBounds:h0,getId:t=>AM(t)}),a=new Map,c=new Set;for(const o of i){const i=s.getObjectsInBounds(P0(o),n+o.thickness/2);for(const r of i){const i=AM(r);if(!x0(r).includes(o.layer))continue;if(e.areIdsConnected(o.pcb_trace_id,i))continue;const s=`${i}_${o.pcb_trace_id}`,{gap:l}=y0(o,r);if(_0(l)){a.delete(s),c.add(s);continue}if(c.has(s))continue;if(l+c0>=n)continue;const d={type:"pcb_pad_trace_clearance_error",pcb_pad_trace_clearance_error_id:`pad_trace_clearance_${s}`,error_type:"pcb_pad_trace_clearance_error",message:`Pad ${NM(t,i)} and trace ${NM(t,o.pcb_trace_id)} are too close (clearance: ${I_(l)}, minimum: ${I_(n)})`,pcb_pad_id:i,pcb_trace_id:o.pcb_trace_id,minimum_clearance:n,actual_clearance:l,center:g0(o)},h=a.get(s);(!h||l<h.gap)&&a.set(s,{error:d,gap:l})}}return Array.from(a.values()).map(({error:t})=>t)}function Y0(t,{connMap:e,minClearance:n}={}){const o=t.filter(t=>"pcb_via"===t.type),i=m0(t);if(0===o.length||0===i.length)return[];const r=l0(t);n??=d0(r,"min_trace_to_pad_edge_clearance")??r0,e??=ei(t);const s=new Map,a=new Set;for(const r of o)for(const o of i){if(!x0(r).includes(o.layer))continue;if(e.areIdsConnected(o.pcb_trace_id,r.pcb_via_id))continue;const i=`${r.pcb_via_id}_${o.pcb_trace_id}`,{gap:c}=y0(o,r);if(_0(c)){s.delete(i),a.add(i);continue}if(a.has(i))continue;if(c+c0>=n)continue;const l={type:"pcb_via_trace_clearance_error",pcb_via_trace_clearance_error_id:`via_trace_clearance_${i}`,error_type:"pcb_via_trace_clearance_error",message:`Via ${NM(t,r.pcb_via_id)} and trace ${NM(t,o.pcb_trace_id)} are too close (clearance: ${I_(c)}, minimum: ${I_(n)})`,pcb_via_id:r.pcb_via_id,pcb_trace_id:o.pcb_trace_id,minimum_clearance:n,actual_clearance:c,center:g0(o)},d=s.get(i);(!d||c<d.gap)&&s.set(i,{error:l,gap:c})}return Array.from(s.values()).map(({error:t})=>t)}var X0=(t,e={})=>{const n=(t=>{const e=ei(t),n=t.filter(t=>"pcb_via"===t.type&&"string"==typeof t.pcb_trace_id).map(t=>[t.pcb_via_id,t.pcb_trace_id]);return e.addConnections(n),e})(t),o=Math.max(e.viaClearance??.1,.1),i=E0(t,{connMap:n,minClearance:e.traceClearance}),r=!1!==e.includeTypedTraceClearance,s=r?Y0(t,{connMap:n,minClearance:e.traceClearance}):[],a=r?$0(t,{connMap:n,minClearance:e.traceClearance}):[],c=[...k0(t,{connMap:n,minClearance:o}),...L0(t,{connMap:n,minClearance:o})],l=[...i,...j0(t),...!1===e.includeTraceContinuity?[]:B0(t),...s,...a,...c],d=t.filter(t=>"pcb_via"===t.type),h=new Map(d.map(t=>[t.pcb_via_id,t])),u=l.map(t=>{if("pcb_via_trace_clearance_error"===t.type&&"string"==typeof t.pcb_via_id){const e=h.get(t.pcb_via_id);if(e)return{...t,center:{x:e.x,y:e.y}}}if("center"in t&&t.center)return t;if("pcb_center"in t&&t.pcb_center)return{...t,center:t.pcb_center};if("pcb_via_ids"in t&&Array.isArray(t.pcb_via_ids)){const[e,n]=t.pcb_via_ids,o=h.get(e),i=h.get(n);if(o&&i)return{...t,center:{x:(o.x+i.x)/2,y:(o.y+i.y)/2}}}if("pcb_error_id"in t&&"string"==typeof t.pcb_error_id&&(t.pcb_error_id.startsWith("same_net_vias_close_")||t.pcb_error_id.startsWith("different_net_vias_close_"))){const e=t.pcb_error_id.replace("same_net_vias_close_","").replace("different_net_vias_close_","").split("_").filter(Boolean);if(2===e.length){const n=h.get(e[0]),o=h.get(e[1]);if(n&&o)return{...t,center:{x:(n.x+o.x)/2,y:(n.y+o.y)/2}}}}return t}),p=u.filter(t=>Boolean(t.center));return{errors:l,errorsWithCenters:u,locationAwareErrors:p}},V0={traceClearance:.1,viaClearance:.1};var W0=t=>t.circuitJsonMetadata??{},H0=({connections:t,obstacles:e})=>new Set([...t.flatMap(t=>t.pointsToConnect.flatMap(t=>t.pcb_port_id?[t.pcb_port_id]:[])),...e.flatMap(t=>{const e=W0(t).pcb_port_id;return e?[e]:[]})]),G0=t=>t.__netConnectionName??t.__rootConnectionNames?.[0]??t.name,U0=t=>Array.from(new Set([t.name,t.__netConnectionName,...t.__rootConnectionNames??[],...t.pointsToConnect.flatMap(t=>[t.pointId,t.pcb_port_id])])).filter(t=>Boolean(t)),Z0=(t,e)=>{const n=new Map,o=new Set,i=new Map;for(const r of t){const t=G0(r);for(const e of U0(r)){const i=n.get(e);i&&i!==t?(n.delete(e),o.add(e)):o.has(e)||n.set(e,t)}const s=e.getNetConnectedToId(r.name);if(!s)continue;const a=s,c=i.get(a)??new Set;c.add(t),i.set(a,c)}return{connMap:e,circuitJsonSourceTraceIdBySrjDeclaredConnectionReference:n,circuitJsonSourceTraceIdsByConnectivityNetId:i}},q0=(t,e)=>{const n=t.circuitJsonSourceTraceIdBySrjDeclaredConnectionReference.get(e);if(n)return n;const o=t.connMap.getNetConnectedToId(e);if(!o)return;const i=t.circuitJsonSourceTraceIdsByConnectivityNetId.get(o);return 1===i?.size?i.values().next().value:void 0};function J0(t,e,n=t){const o=[],i=n===t?t.connections:[...t.connections,...n.connections],r=n===t?t.obstacles:n.obstacles,s=Z0(i,ii(n===t?t:{...n,connections:i})),a=H0({connections:i,obstacles:r});if(i.forEach(t=>{const n=t.pointsToConnect.map(t=>t.pcb_port_id).filter(t=>Boolean(t)),i=new Set(n),a=t=>(t=>Array.from(new Set(t.flatMap(t=>t.connectedTo))))(t).filter(t=>!i.has(t)),c=t.pointsToConnect.map(t=>t.pointId).filter(t=>Boolean(t)),l=q0(s,t.name)??G0(t),d=[],h=e.find(e=>(e.connection_name??e.connectionName)===t.name);if(h){const t=t=>"route_type"in t&&"jumper"===t.route_type?t.start:"x"in t&&"y"in t?{x:t.x,y:t.y}:{x:0,y:0},e=[t(h.route[0]),t(h.route[h.route.length-1])];for(const t of e)for(const e of r)Be(t,e)<=0&&d.push(e)}const u=o.find(t=>"source_trace"===t.type&&t.source_trace_id===l);if(u){const t=u;t.connected_source_port_ids=[...new Set([...t.connected_source_port_ids,...n])],t.connected_source_net_ids=[...new Set([...t.connected_source_net_ids??[],...c,...a(d)])]}else o.push({type:"source_trace",source_trace_id:l,connected_source_port_ids:n,connected_source_net_ids:a(d).concat(c)})}),e[0]&&"type"in e[0]){const t=new Map(i.map(t=>[t.name,t]));for(const n of e){const e=[...new Set((n.connectsTo??[]).filter(t=>a.has(t)))],i=new Set(e),r=[...new Set((n.connectsTo??[]).filter(t=>!i.has(t)))];if(0===e.length&&0===r.length)continue;const c=t.get(n.connection_name),l=q0(s,n.connection_name)??n.connectsTo?.map(t=>q0(s,t)).find(t=>void 0!==t)??(c?G0(c):n.connection_name),d=o.find(t=>"source_trace"===t.type&&t.source_trace_id===l);"source_trace"!==d?.type?o.push({type:"source_trace",source_trace_id:l,connected_source_port_ids:e,connected_source_net_ids:r}):(d.connected_source_port_ids=[...new Set([...d.connected_source_port_ids,...e])],d.connected_source_net_ids=[...new Set([...d.connected_source_net_ids??[],...r])])}}return o}function K0(t,e,n){let o,i=Number.POSITIVE_INFINITY;for(const r of e){const e=n.get(r);if(!e)continue;const s=Math.hypot(e.x-t.x,e.y-t.y);s<i&&(i=s,o=r)}return o??e[0]}var Q0=new Set(["top","bottom","inner1","inner2","inner3","inner4","inner5","inner6","inner7","inner8"]),t1=t=>Q0.has(t);function e1(t){const e=[],n=new Set,o=new Set,i=function(t){const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id&&e.set(t.pcb_port_id,{x:t.x,y:t.y});return e}(t),r=H0(t);for(const s of t.obstacles){const t=s.connectedTo,a=W0(s);if(a.pcb_via_id)continue;const c=a.pcb_smtpad_id,l=a.pcb_plated_hole_id,d=[...new Set([...a.pcb_port_id?[a.pcb_port_id]:[],...t.filter(t=>r.has(t))])],h=K0(s.center,d,i);if(!c&&!l&&!h)continue;const u=s.layers.filter(t1);if(0===u.length)continue;const p=s.width,m=s.height,g=s.center.x,f=s.center.y,y=s.ccwRotationDegrees;if(Boolean(l)||u.length>1){const t=l??`pcb_plated_hole_${g.toFixed(3)}_${f.toFixed(3)}`;if(o.has(t))continue;if(o.add(t),"number"==typeof y&&Number.isFinite(y)){const n=Math.max(.5*Math.min(p,m),.1);e.push({type:"pcb_plated_hole",pcb_plated_hole_id:t,shape:"rotated_pill_hole_with_rect_pad",hole_shape:"rotated_pill",pad_shape:"rect",hole_width:n,hole_height:n,hole_ccw_rotation:y,rect_pad_width:p,rect_pad_height:m,rect_ccw_rotation:y,hole_offset_x:0,hole_offset_y:0,x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}if(Math.abs(p-m)<.001){e.push({type:"pcb_plated_hole",pcb_plated_hole_id:t,shape:"circle",outer_diameter:Math.max(p,m),hole_diameter:Math.max(.5*Math.min(p,m),.1),x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}e.push({type:"pcb_plated_hole",pcb_plated_hole_id:t,shape:"circular_hole_with_rect_pad",hole_shape:"circle",hole_diameter:Math.max(.5*Math.min(p,m),.1),rect_pad_width:p,rect_pad_height:m,hole_offset_x:0,hole_offset_y:0,x:g,y:f,layers:u,...h?{pcb_port_id:h}:{}});continue}const _=c??`pcb_smtpad_${g.toFixed(3)}_${f.toFixed(3)}`;n.has(_)||(n.add(_),"number"==typeof y&&Number.isFinite(y)?e.push({type:"pcb_smtpad",pcb_smtpad_id:_,layer:u[0],shape:"rotated_rect",x:g,y:f,width:p,height:m,ccw_rotation:y,...h?{pcb_port_id:h}:{}}):e.push({type:"pcb_smtpad",pcb_smtpad_id:_,layer:u[0],shape:"rect",width:p,height:m,x:g,y:f,...h?{pcb_port_id:h}:{}}))}return e}function n1(t,e,n={}){const{minTraceWidth:o=.1,minViaDiameter:i,minViaHoleDiameter:r,originalSrj:s,includeOriginalConnections:a=!1}=n,c=Yo(t),l=i??c.padDiameter,d=t.min_via_hole_diameter??t.minViaHoleDiameter,h=r??d??(void 0!==i?.5*l:c.holeDiameter),u=[];u.push(...J0(t,e,a&&s?s:t)),u.push(...function(t){const e=new Map;return t.connections.forEach(t=>{t.pointsToConnect.forEach(t=>{t.pcb_port_id&&e.set(t.pcb_port_id,{type:"pcb_port",pcb_port_id:t.pcb_port_id,source_port_id:t.pcb_port_id,x:t.x,y:t.y,layers:xo(t)})})}),Array.from(e.values())}(a&&s?s:t)),u.push(...e1(s??t)),u.push(...function(t,e,n=.3,o=.5*n){const i=[],r=new Set;return t.length>0&&("type"in t[0]&&"pcb_trace"===t[0].type?t.forEach(t=>{t.route.forEach(s=>{if("via"===s.route_type){if(!t1(s.from_layer)||!t1(s.to_layer))return;const a=s.via_diameter??n,c=s.via_hole_diameter??o,l=`${s.x},${s.y},${s.from_layer},${s.to_layer}`;r.has(l)||(i.push({type:"pcb_via",pcb_via_id:`via_${i.length}`,pcb_trace_id:t.pcb_trace_id,x:s.x,y:s.y,outer_diameter:a,hole_diameter:c,layers:Wy(s,e)}),r.add(l))}})}):t.forEach((t,s)=>{const a=`trace_${s}`,c=t.viaDiameter??n,l=o;for(let n=1;n<t.route.length;n++){const o=t.route[n-1],s=t.route[n];if(o.z!==s.z&&Math.abs(o.x-s.x)<.01&&Math.abs(o.y-s.y)<.01){const t=vo(o.z,e),n=vo(s.z,e),d=`${s.x},${s.y},${t},${n}`;r.has(d)||(i.push({type:"pcb_via",pcb_via_id:`via_${i.length}`,pcb_trace_id:a,x:s.x,y:s.y,outer_diameter:c,hole_diameter:l,layers:Wy({from_layer:t,to_layer:n},e)}),r.add(d))}}})),i}(e,t.layerCount,l,h));const p=Z0(t.connections,ii(t));return e.length>0&&("type"in e[0]&&"pcb_trace"===e[0].type?e.forEach(t=>{const e=q0(p,t.connection_name)??t.connectsTo?.map(t=>q0(p,t)).find(t=>Boolean(t))??t.connection_name;u.push(function(t,e){return{type:"pcb_trace",pcb_trace_id:t.pcb_trace_id,source_trace_id:e,route:t.route.map(t=>{if("wire"===t.route_type){if(!t1(t.layer))return null;const e="start_pcb_port_id"in t&&"string"==typeof t.start_pcb_port_id?t.start_pcb_port_id:void 0,n="end_pcb_port_id"in t&&"string"==typeof t.end_pcb_port_id?t.end_pcb_port_id:void 0;return{route_type:"wire",x:t.x,y:t.y,width:t.width,layer:t.layer,...e?{start_pcb_port_id:e}:{},...n?{end_pcb_port_id:n}:{}}}return"via"===t.route_type&&t1(t.from_layer)&&t1(t.to_layer)?{route_type:"via",x:t.x,y:t.y,from_layer:t.from_layer,to_layer:t.to_layer}:null}).filter(t=>null!==t)}}(t,e))}):e.forEach((e,n)=>{const i=function(t,e,n,o,i=.1){const r=[];if(!t.jumpers||0===t.jumpers.length)return[{type:"pcb_trace",pcb_trace_id:e,source_trace_id:n,route:t.route.map((e,n)=>{const r=0===n,s=n===t.route.length-1;return{route_type:"wire",x:e.x,y:e.y,width:e.traceThickness??i,layer:vo(e.z,o),...r&&e.pcb_port_id?{start_pcb_port_id:e.pcb_port_id}:{},...s&&e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})}];const s=[];for(const e of t.jumpers){let n=-1,o=-1;for(let i=0;i<t.route.length;i++){const r=t.route[i];Math.abs(r.x-e.start.x)<.01&&Math.abs(r.y-e.start.y)<.01&&(n=i),Math.abs(r.x-e.end.x)<.01&&Math.abs(r.y-e.end.y)<.01&&(o=i)}-1!==n&&-1!==o&&(n>o&&([n,o]=[o,n]),s.push({startIdx:n,endIdx:o}))}s.sort((t,e)=>t.startIdx-e.startIdx);let a=0,c=0;for(const{startIdx:l,endIdx:d}of s){if(l>=a){const s=t.route.slice(a,l+1);s.length>0&&(r.push({type:"pcb_trace",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((t,e)=>{const n=0===e&&0===a;return{route_type:"wire",x:t.x,y:t.y,width:t.traceThickness??i,layer:vo(t.z,o),...n&&t.pcb_port_id?{start_pcb_port_id:t.pcb_port_id}:{}}})}),c++)}a=d}if(a<t.route.length){const s=t.route.slice(a);if(s.length>0){const t=!0;r.push({type:"pcb_trace",pcb_trace_id:`${e}_${c}`,source_trace_id:n,route:s.map((e,n)=>{const r=t&&n===s.length-1;return{route_type:"wire",x:e.x,y:e.y,width:e.traceThickness??i,layer:vo(e.z,o),...r&&e.pcb_port_id?{end_pcb_port_id:e.pcb_port_id}:{}}})})}}return r}(e,`trace_${n}`,q0(p,e.connectionName)??e.connectionName,t.layerCount,o);u.push(...i)})),u}var o1=(t,e)=>{const n=new Set(e.flatMap(t=>t.__replaces_pcb_trace_id?[t.__replaces_pcb_trace_id]:[]));return[...t.filter(t=>!n.has(t.pcb_trace_id)),...e]},i1=({inputSrj:t,srjWithPointPairs:e,routedTraces:n,drcOptions:o})=>{const i=t.traces??[],r=n1(e,o1(i,n),{minTraceWidth:t.minTraceWidth,minViaDiameter:t.minViaDiameter,originalSrj:t,includeOriginalConnections:!0});return{circuitJson:r,...X0(r,{...V0,...o})}},r1=(t,e)=>{const n=t({hdRoutes:e,traces:[]});return Array.isArray(n)?n:n.errorsWithCenters??n.errors},s1=t=>{const e="string"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,n=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=>"string"==typeof t):[],o=[..."string"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids:[]].filter(t=>"string"==typeof t),i=e?`overlap_${e}_`:void 0,r=i&&"string"==typeof t.pcb_trace_error_id&&t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0;if(n.length>0){const t=e&&!n.includes(e)?[e,...n]:[...n];return t.length<2&&r&&!o.includes(r)&&t.push(r),t}return[e,r].filter(t=>"string"==typeof t&&!o.includes(t))},a1=t=>s1(t).filter((t,e,n)=>n.indexOf(t)===e),c1=t=>t.reduce((t,e)=>{if("number"==typeof e.actual_clearance&&"number"==typeof e.minimum_clearance)return t+Math.max(0,e.minimum_clearance-e.actual_clearance);const n=("string"==typeof e.message?e.message:"").match(/gap: (-?\d+(?:\.\d+)?)mm/);return n?t+Math.max(0,.1-Number.parseFloat(n[1])):t+1},0),l1=(t,e)=>t.length<e.length||t.length===e.length&&c1(t)<c1(e)-1e-9,d1=({routes:t,newConnections:e,syntheticConnectionNames:n})=>{const o=new Set([...e.map(t=>t.name),...n]),i=new Map,r=new Map;for(let e=0;e<t.length;e++){const n=t[e];if(!o.has(n.connectionName))continue;const s=i.get(n.connectionName)??0;i.set(n.connectionName,s+1),r.set(`${n.connectionName}_${s}`,e)}return r},h1=[.03,.1,.25],u1=t=>{let e=0;for(const n of t){if("number"!=typeof n.actual_clearance||!Number.isFinite(n.actual_clearance)||"number"!=typeof n.minimum_clearance||!Number.isFinite(n.minimum_clearance))return;if(e+=Math.max(0,n.minimum_clearance-n.actual_clearance),!Number.isFinite(e))return}return e},p1=({errors:t,errorsWithCenters:e,routeIndexByTraceId:n,padPositionById:o})=>{const i=[];let r=0;for(const s of t){const t="pcb_via_trace_clearance_error"===s.type,a="pcb_pad_trace_clearance_error"===s.type;if(!t&&!a||"string"!=typeof s.pcb_trace_id||!n.has(s.pcb_trace_id)||"number"!=typeof s.actual_clearance||!Number.isFinite(s.actual_clearance)||"number"!=typeof s.minimum_clearance||!Number.isFinite(s.minimum_clearance))return;const c=a1(s);if(t&&c.length<2||c.some(t=>!n.has(t)))return;const l=e.find(t=>t.type===s.type&&t.pcb_trace_id===s.pcb_trace_id&&t.pcb_pad_id===s.pcb_pad_id&&t.pcb_via_id===s.pcb_via_id),d=a?"string"==typeof s.pcb_pad_id?o.get(s.pcb_pad_id):void 0:l?.center??s.center;if(!d||"object"!=typeof d)return;if(!("x"in d&&"y"in d&&"number"==typeof d.x&&Number.isFinite(d.x)&&"number"==typeof d.y&&Number.isFinite(d.y)))return;const h={...s,pcb_trace_id:s.pcb_trace_id,actual_clearance:s.actual_clearance,minimum_clearance:s.minimum_clearance,center:{x:d.x,y:d.y}};if(t){if("string"!=typeof s.pcb_via_id)return;i.push({...h,type:"pcb_via_trace_clearance_error",pcb_via_id:s.pcb_via_id,pcb_pad_id:void 0})}else{if("string"!=typeof s.pcb_pad_id)return;i.push({...h,type:"pcb_pad_trace_clearance_error",pcb_pad_id:s.pcb_pad_id,pcb_via_id:void 0})}if(r+=Math.max(0,s.minimum_clearance-s.actual_clearance),!Number.isFinite(r))return}return{errors:i,deficit:r}},m1=(t,e)=>{const n=[];for(let o=0;o<t.route.length;o+=1){const i=t.route[o];if("via"!==i.route_type){n.push(structuredClone(i));continue}const r=n[n.length-1],s=t.route[o+1],a="wire"===r?.route_type?r.width:"wire"===s?.route_type?s.width:e,c="wire"===s?.route_type?s.width:a;"wire"===r?.route_type&&r.x===i.x&&r.y===i.y&&r.layer===i.from_layer||n.push({route_type:"wire",x:i.x,y:i.y,layer:i.from_layer,width:a}),n.push(structuredClone(i)),"wire"===s?.route_type&&s.x===i.x&&s.y===i.y&&s.layer===i.to_layer||n.push({route_type:"wire",x:i.x,y:i.y,layer:i.to_layer,width:c})}return{...structuredClone(t),route:n}};function g1(t){const{srj:e,routes:n,routeIndex:o,start:i,end:r,bounds:s,traceThickness:a}=t;if(void 0!==t.maxNodes&&(!Number.isSafeInteger(t.maxNodes)||t.maxNodes<1))throw new Error("repair04: maxNodes must be a positive safe integer");if(t.stats&&(t.stats.nodesPopped=0,t.stats.completionReason="no-path"),!1===t.allowLayerChanges&&i.z!==r.z)return null;const c=n[o],l=new Map,d=t=>{const e=l.get(t);if(void 0===e||e===t)return t;const n=d(e);return l.set(t,n),n},h=t=>{const e=t.filter(t=>Boolean(t));if(!e.length)return;const n=d(e[0]);for(const t of e)l.set(d(t),n)};for(const t of e.connections){const e=t;h([e.name,e.rootConnectionName,e.netConnectionName,e.__netConnectionName,...e.mergedConnectionNames??[],...e.__rootConnectionNames??[],...e.pointsToConnect.flatMap(t=>[t.pcb_port_id,t.pointId])])}for(const t of e.obstacles)h(t.connectedTo);for(const t of n)h([t.connectionName,t.rootConnectionName]);const u=d(c.connectionName),p=t=>"top"===t?0:"bottom"===t?e.layerCount-1:Number(t.slice(5)),m=[s.minX,s.maxX,s.minY,s.maxY,i.x,i.y,r.x,r.y,a,c.viaDiameter,t.traceClearance,t.viaClearance,e.defaultObstacleMargin??0,e.minTraceToPadEdgeClearance??0,e.minViaEdgeToPadEdgeClearance??0].every(t=>Number.isFinite(t)&&Math.abs(t)<=1e4),g=[],f=(t,e,n,o,i=!1)=>{const r=o?Math.hypot(o.width,o.height)/2:n,s=o?Math.cos(o.rotation):1,a=o?Math.sin(o.rotation):0,c={minX:Math.min(t.x,e.x)-r,maxX:Math.max(t.x,e.x)+r,minY:Math.min(t.y,e.y)-r,maxY:Math.max(t.y,e.y)+r},l=o&&m?((t,e,n,o,i,r)=>{if(t.x!==e.x||t.y!==e.y||!Number.isFinite(n.rotation)||n.width<=0||n.height<=0||![t.x,t.y,n.width,n.height,r.minX,r.maxX,r.minY,r.maxY].every(t=>Number.isFinite(t)&&Math.abs(t)<=1e4))return r;const s=o*o+i*i;if(!Number.isFinite(s)||Math.abs(s-1)>1e-12)return r;const a=n.width/2,c=n.height/2,l=(Math.abs(o)*a+Math.abs(i)*c)/s+1e-8,d=(Math.abs(i)*a+Math.abs(o)*c)/s+1e-8,h={minX:t.x-l,maxX:t.x+l,minY:t.y-d,maxY:t.y+d};return h.minX<r.minX||h.maxX>r.maxX||h.minY<r.minY||h.maxY>r.maxY?r:h})(t,e,o,s,a,c):c;g.push({a:t,b:e,radius:n,rect:o,viaOnly:i,rectCos:s,rectSin:a,rectBounds:o?{minX:-o.width/2,maxX:o.width/2,minY:-o.height/2,maxY:o.height/2}:void 0,visitedQuery:0,...l,minZ:Math.min(t.z,e.z),maxZ:Math.max(t.z,e.z)})};for(const t of e.obstacles){const e=t.connectedTo.some(t=>d(t)===u),n=t.__zLayers??t.zLayers??t.layers.map(p);for(const o of n)f({...t.center,z:o},{...t.center,z:o},0,{width:t.width,height:t.height,rotation:(t.ccwRotationDegrees??0)*Math.PI/180},e)}for(const t of n)if(d(t.connectionName)!==u)for(let e=1;e<t.route.length;e++){const n=t.route[e-1],o=t.route[e];"through_obstacle"!==n.toNextSegmentType&&f(n,o,n.z!==o.z?t.viaDiameter/2:Math.max(n.traceThickness??t.traceThickness,o.traceThickness??t.traceThickness)/2)}for(const t of e.traces??[]){if(d(t.connection_name)===u)continue;const n=m1(t,e.minTraceWidth);for(let t=1;t<n.route.length;t++){const e=n.route[t-1],o=n.route[t];"wire"===e.route_type&&"wire"===o.route_type&&e.layer===o.layer&&f({x:e.x,y:e.y,z:p(e.layer)},{x:o.x,y:o.y,z:p(o.layer)},Math.max(e.width,o.width)/2),"via"===o.route_type&&f({x:o.x,y:o.y,z:p(o.from_layer)},{x:o.x,y:o.y,z:p(o.to_layer)},(o.via_diameter??c.viaDiameter)/2)}}const y=new Map,_=Math.max(c.viaDiameter,a)/2+Math.max(t.traceClearance,t.viaClearance,e.defaultObstacleMargin??0,e.minTraceToPadEdgeClearance??0,e.minViaEdgeToPadEdgeClearance??0)+1e-5;for(const t of g)for(let e=Math.floor(Math.max(t.minX,s.minX-_));e<=Math.floor(Math.min(t.maxX,s.maxX+_));e++){let n=y.get(e);for(let o=Math.floor(Math.max(t.minY,s.minY-_));o<=Math.floor(Math.min(t.maxY,s.maxY+_));o++){n||(n=new Map,y.set(e,n));const i=n.get(o);i?i.push(t):n.set(o,[t])}}let b=0;const x={x:0,y:0},v={x:0,y:0},S=(n,o)=>{const i=n.z!==o.z,r=i?c.viaDiameter/2:a/2,s=Math.max(i?t.viaClearance:t.traceClearance,e.defaultObstacleMargin??0,i?e.minViaEdgeToPadEdgeClearance??0:e.minTraceToPadEdgeClearance??0),l=r+s+1e-5,d=++b,h=Math.min(n.x,o.x),u=Math.max(n.x,o.x),p=Math.min(n.y,o.y),m=Math.max(n.y,o.y),g=Math.min(n.z,o.z),f=Math.max(n.z,o.z);for(let e=Math.floor(h-l);e<=Math.floor(u+l);e++){const a=y.get(e);if(a)for(let e=Math.floor(p-l);e<=Math.floor(m+l);e++){const c=a.get(e);if(c)for(const e of c){if(e.viaOnly&&!i)continue;if(e.visitedQuery===d)continue;if(e.visitedQuery=d,e.maxZ<g||e.minZ>f)continue;const a=r+(e.rect?s:i&&e.minZ!==e.maxZ?t.viaClearance:t.traceClearance)+1e-5;if(u+a<e.minX||h-a>e.maxX||m+a<e.minY||p-a>e.maxY)continue;let c;if(e.rect?(x.x=(n.x-e.a.x)*e.rectCos+(n.y-e.a.y)*e.rectSin,x.y=-(n.x-e.a.x)*e.rectSin+(n.y-e.a.y)*e.rectCos,v.x=(o.x-e.a.x)*e.rectCos+(o.y-e.a.y)*e.rectSin,v.y=-(o.x-e.a.x)*e.rectSin+(o.y-e.a.y)*e.rectCos,c=ke(x,v,e.rectBounds)):c=Oe(n,o,e.a,e.b)-e.radius,c<a)return!1}}}return!0};if(!S(i,i)||!S(r,r))return null;const I=t.gridSize??.1;if(!Number.isFinite(I)||I<=0)throw new Error("repair04: clearance grid size must be positive and finite");const C=Math.floor((s.maxX-s.minX)/I),P=Math.floor((s.maxY-s.minY)/I),M=t=>({x:s.minX+(t%C+.5)*I,y:s.minY+(Math.floor(t/C)%P+.5)*I,z:Math.floor(t/(C*P)),traceThickness:a}),N=(t,e,n)=>(n*P+e)*C+t,w=t=>Math.hypot(t.x-r.x,t.y-r.y)+(t.z===r.z?0:1),T=[],R=t=>{T.push(t);let e=T.length-1;for(;e>0;){const n=Math.floor((e-1)/2);if(T[n].priority<=t.priority)break;T[e]=T[n],e=n}T[e]=t},E=()=>{const t=T[0],e=T.pop();if(T.length){let t=0;for(;2*t+1<T.length;){let n=2*t+1;if(n+1<T.length&&T[n+1].priority<T[n].priority&&n++,T[n].priority>=e.priority)break;T[t]=T[n],t=n}T[t]=e}return t},A=new Map,O=new Map,k=(z=i,N(Math.max(0,Math.min(C-1,Math.floor((z.x-s.minX)/I))),Math.max(0,Math.min(P-1,Math.floor((z.y-s.minY)/I))),z.z)),L=k%C,D=Math.floor(k/C)%P;var z;for(let t=-2;t<=2;t++)for(let e=-2;e<=2;e++){const n=L+t,o=D+e;if(n<0||n>=C||o<0||o>=P)continue;const r=N(n,o,i.z),s=M(r);if(!S(i,s))continue;const a=Math.hypot(s.x-i.x,s.y-i.y);A.set(r,a),O.set(r,-1),R({id:r,cost:a,priority:a+w(s)})}const F=C*P*e.layerCount,B=C>0&&P>0&&Number.isSafeInteger(e.layerCount)&&Number.isSafeInteger(F)&&F>0&&Number.isSafeInteger(F*F-1)&&Number.isInteger(i.z)&&i.z>=0&&i.z<e.layerCount,j=new Map;let $=0;for(;T.length&<(t.maxNodes??3e4);){const n=E();if($++,t.stats&&(t.stats.nodesPopped=$),n.cost!==A.get(n.id))continue;const o=M(n.id);if(o.z===r.z&&Math.hypot(o.x-r.x,o.y-r.y)<3*I&&S(o,r)){const e=[r];for(let t=n.id;-1!==t;t=O.get(t))e.push(M(t));e.push(i);const o=e.reverse(),s=[i];for(let t=1;t<o.length;){let e=t;if(o[t].z===s.at(-1).z)for(let n=t+1;n<o.length&&o[n].z===o[t].z;n++)S(s.at(-1),o[n])&&(e=n);s.push(o[e]),t=e+1}return t.stats&&(t.stats.completionReason="found"),s}const s=n.id%C,a=Math.floor(n.id/C)%P,c=[];for(let t=-1;t<=1;t++)for(let e=-1;e<=1;e++)0===t&&0===e||s+t<0||s+t>=C||a+e<0||a+e>=P||c.push(N(s+t,a+e,o.z));if(!1!==t.allowLayerChanges)for(let t=0;t<e.layerCount;t++)t!==o.z&&c.push(N(s,a,t));for(const t of c){const e=M(t),i=n.cost+(o.z===e.z?Math.hypot(o.x-e.x,o.y-e.y):1);if(i>=(A.get(t)??1/0))continue;const r=Math.min(n.id,t),s=Math.max(n.id,t),a=B?r*F+s:`${r},${s}`;let c=j.get(a);void 0===c&&(c=S(o,e),j.set(a,c)),c&&(A.set(t,i),O.set(t,n.id),R({id:t,cost:i,priority:i+w(e)}))}}return t.stats&&(t.stats.completionReason=T.length?"node-limit":"no-path"),null}var f1=(t,e)=>{if(!Number.isInteger(e)||e<1)throw new Error(`Invalid board layer count: ${e}`);const n=Array.from({length:e},(t,n)=>((t,e)=>0===t?"top":t===e-1?"bottom":`inner${t}`)(n,e)),o=n.findIndex(e=>e===t.from_layer),i=n.findIndex(e=>e===t.to_layer);if(o<0||i<0)throw new Error(`Via span ${t.from_layer} -> ${t.to_layer} is outside the board`);return n.slice(Math.min(o,i),Math.max(o,i)+1)},y1=.005,_1=1e-6,b1=(t,e)=>({minX:t.minX-e,minY:t.minY-e,maxX:t.maxX+e,maxY:t.maxY+e}),x1=t=>b1({minX:Math.min(t.start.x,t.end.x),minY:Math.min(t.start.y,t.end.y),maxX:Math.max(t.start.x,t.end.x),maxY:Math.max(t.start.y,t.end.y)},t.width/2),v1=t=>{const e=t.diameter/2;return{minX:t.x-e,minY:t.y-e,maxX:t.x+e,maxY:t.y+e}},S1=t=>({minX:t.x-t.width/2,minY:t.y-t.height/2,maxX:t.x+t.width/2,maxY:t.y+t.height/2}),I1=(t,e)=>`${t}:${e}`,C1=class{constructor(t){this.cellSize=t}cellSize;cells=new Map;insert(t,e){const n=Math.floor(e.minX/this.cellSize),o=Math.floor(e.maxX/this.cellSize),i=Math.floor(e.minY/this.cellSize),r=Math.floor(e.maxY/this.cellSize);for(let e=n;e<=o;e+=1)for(let n=i;n<=r;n+=1){const o=I1(e,n),i=this.cells.get(o);i?i.push(t):this.cells.set(o,[t])}}insertWithCellKeys(t,e){for(const n of e){const e=this.cells.get(n);e?e.push(t):this.cells.set(n,[t])}}getCellKeys(t){const e=Math.floor(t.minX/this.cellSize),n=Math.floor(t.maxX/this.cellSize),o=Math.floor(t.minY/this.cellSize),i=Math.floor(t.maxY/this.cellSize),r=[];for(let t=e;t<=n;t+=1)for(let e=o;e<=i;e+=1)r.push(I1(t,e));return r}queryWithCellKeys(t){const e=new Set;for(const n of t){const t=this.cells.get(n);if(t)for(const n of t)e.add(n)}return[...e]}queryWithCellKeysUsingOrder(t,e){const n=[];for(const o of t){const t=this.cells.get(o);if(t)for(const o of t)o.lastDynamicQueryOrder!==e&&(o.lastDynamicQueryOrder=e,n.push(o))}return n}query(t){const e=Math.floor(t.minX/this.cellSize),n=Math.floor(t.maxX/this.cellSize),o=Math.floor(t.minY/this.cellSize),i=Math.floor(t.maxY/this.cellSize),r=new Set;for(let t=e;t<=n;t+=1)for(let e=o;e<=i;e+=1){const n=this.cells.get(I1(t,e));if(n)for(const t of n)r.add(t)}return[...r]}},P1=(t,e)=>{const n=ve(t.start,t.end,e.start,e.end);if(n)return n;const o=[{left:t.start,right:ze(t.start,e.start,e.end)},{left:t.end,right:ze(t.end,e.start,e.end)},{left:ze(e.start,t.start,t.end),right:e.start},{left:ze(e.end,t.start,t.end),right:e.end}];let i={left:t.start,right:e.start},r=Number.POSITIVE_INFINITY;for(const t of o){const e=Math.hypot(t.left.x-t.right.x,t.left.y-t.right.y);e<r&&(i=t,r=e)}return{x:(i.left.x+i.right.x)/2,y:(i.left.y+i.right.y)/2}},M1=(t,e)=>{const n=ze(e,t.start,t.end);return{x:(n.x+e.x)/2,y:(n.y+e.y)/2}},N1=(t,e)=>{const n=ze({x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},t.start,t.end),o=Math.max(e.minX,Math.min(e.maxX,n.x)),i=Math.max(e.minY,Math.min(e.maxY,n.y));return{x:(n.x+o)/2,y:(n.y+i)/2}},w1=t=>{const e=new Set;for(const n of t.route)"wire"===n.route_type&&(n.start_pcb_port_id&&e.add(n.start_pcb_port_id),n.end_pcb_port_id&&e.add(n.end_pcb_port_id));return[...e]},T1=(t,e,n)=>n<0?`PCB trace ${t} overlaps with ${e} (accidental contact)`:`PCB trace ${t} is too close to ${e} (gap: ${n.toFixed(3)}mm)`,R1=class{constructor(t,e={}){if(this.srj=t,this.cacheImmutableTraceGeometry=e.cacheImmutableTraceGeometry??!1,this.useConservativeRectObstaclePrecheck=e.useConservativeRectObstaclePrecheck??!1,this.useTransientDynamicQueryMarkers=e.useTransientDynamicQueryMarkers??!1,this.traceClearance=e.traceClearance??.1,this.viaClearance=Math.max(e.viaClearance??.1,.1),this.viaToPadClearance=e.viaToPadClearance??this.srj.minViaEdgeToPadEdgeClearance??.1,this.connMap=e.connMap,this.includeTraceViaOwnerMetadata=e.includeTraceViaOwnerMetadata??!1,this.cellSize=e.spatialCellSize??this.getDefaultSpatialCellSize(),!Number.isFinite(this.traceClearance)||this.traceClearance<0)throw new Error("traceClearance must be a non-negative finite number");if(!Number.isFinite(this.viaClearance))throw new Error("viaClearance must be a finite number");if(!Number.isFinite(this.viaToPadClearance)||this.viaToPadClearance<0)throw new Error("viaToPadClearance must be a non-negative finite number");if(!Number.isFinite(this.cellSize)||this.cellSize<=0)throw new Error("spatialCellSize must be a positive finite number");if(e.cacheStaticObstacleNetMembership&&this.connMap)throw new Error("cacheStaticObstacleNetMembership cannot be combined with connMap");if(this.cacheImmutableTraceGeometry&&this.connMap)throw new Error("cacheImmutableTraceGeometry cannot be combined with connMap");if(this.useTransientDynamicQueryMarkers&&!this.cacheImmutableTraceGeometry)throw new Error("useTransientDynamicQueryMarkers requires cacheImmutableTraceGeometry");this.compileConnectionAliases(),this.obstacles=this.compileStaticObstacles(),e.cacheStaticObstacleNetMembership&&(this.staticObstacleNets=new Map(this.obstacles.map(t=>[t,new Set(t.connectedTo.map(t=>this.resolveNetId(t)))]))),this.indexStaticObstacles()}srj;cacheImmutableTraceGeometry;useConservativeRectObstaclePrecheck;useTransientDynamicQueryMarkers;immutableTraceGeometry=new WeakMap;immutableDynamicCellKeys=new WeakMap;immutableDynamicQueryCellKeys=new WeakMap;immutableStaticCandidates=new WeakMap;immutableStaticClearance=new WeakMap;traceClearance;viaClearance;viaToPadClearance;cellSize;connMap;includeTraceViaOwnerMetadata;canonicalNetByAlias=new Map;connMapNetByCanonicalNet=new Map;obstacles;staticObstacleNets;obstacleIndexesByLayer=new Map;lastRunStats={traceCount:0,segmentCount:0,viaCount:0,obstacleCount:0,broadPhaseCandidateCount:0,exactCheckCount:0};getDefaultSpatialCellSize(){const t=Math.max(0,this.srj.bounds.maxX-this.srj.bounds.minX),e=Math.max(0,this.srj.bounds.maxY-this.srj.bounds.minY);return Math.max(.25,Math.max(t,e)/64,(this.srj.minViaDiameter??.3)+Math.max(this.traceClearance,this.viaToPadClearance))}compileConnectionAliases(){const t=new Map;for(const e of this.srj.connections){const n=e.netConnectionName??e.rootConnectionName??e.name,o=[e.name,e.rootConnectionName,e.netConnectionName,...e.mergedConnectionNames??[],...e.pointsToConnect.flatMap(t=>[t.pointId,t.pcb_port_id])];for(const e of o){if(!e)continue;this.canonicalNetByAlias.set(e,n);const o=this.connMap?.getNetConnectedToId(e);if(!o)continue;let i=t.get(n);i||(i=new Set,t.set(n,i)),i.add(o)}this.canonicalNetByAlias.set(n,n)}for(const[e,n]of t)1===n.size&&this.connMapNetByCanonicalNet.set(e,n.values().next().value)}resolveNetId(t){const e=this.connMap?.getNetConnectedToId(t);if(e)return e;const n=this.canonicalNetByAlias.get(t);return n?this.connMapNetByCanonicalNet.get(n)??n:t}areConnected(t,e){return t===e||(!!this.connMap?.areIdsConnected(t,e)||this.resolveNetId(t)===this.resolveNetId(e))}compileStaticObstacles(){const t=[],e=new Set,n=new Set;for(const o of this.srj.obstacles){if(0===o.layers.length)continue;const i=o.connectedTo.find(t=>t.startsWith("pcb_smtpad_")),r=o.connectedTo.find(t=>t.startsWith("pcb_plated_hole_")),s=o.connectedTo.find(t=>t.startsWith("pcb_port_"));if(!i&&!r&&!s)continue;const a=o.layers.length>1,c=a?"pcb_plated_hole":"pcb_smtpad",l=a?r??`pcb_plated_hole_${o.center.x.toFixed(3)}_${o.center.y.toFixed(3)}`:i??`pcb_smtpad_${o.center.x.toFixed(3)}_${o.center.y.toFixed(3)}`,d=a?n:e;if(d.has(l))continue;d.add(l);const h=a&&Math.abs(o.width-o.height)<.001;t.push({kind:"obstacle",obstacleType:c,obstacleId:l,connectedTo:o.connectedTo,x:o.center.x,y:o.center.y,width:o.width,height:o.height,...h?{radius:Math.max(o.width,o.height)/2}:{},layers:o.layers,...s?{pcbPortId:s}:{}})}return t}indexStaticObstacles(){for(const t of this.obstacles){const e=b1(S1(t),Math.max(this.traceClearance,this.viaToPadClearance));for(const n of t.layers){let o=this.obstacleIndexesByLayer.get(n);o||(o=new C1(this.cellSize),this.obstacleIndexesByLayer.set(n,o)),o.insert(t,e)}}}getImmutableTraceGeometry(t){const e=this.immutableTraceGeometry.get(t);if(e)return e;const n=this.resolveNetId(t.connection_name),o=w1(t),i=[];for(let e=0;e<t.route.length-1;e++){const r=t.route[e],s=t.route[e+1];"wire"===r?.route_type&&"wire"===s?.route_type&&r.layer===s.layer&&(Math.abs(r.x-s.x)<=_1&&Math.abs(r.y-s.y)<=_1||i.push({geometryKey:{},kind:"trace_segment",traceId:t.pcb_trace_id,netId:n,start:{x:r.x,y:r.y},end:{x:s.x,y:s.y},width:E1(r,s),layer:r.layer,pcbPortIds:o}))}const r=[];for(const e of t.route)"via"===e.route_type&&r.push({locationKey:`${e.x},${e.y},${e.from_layer},${e.to_layer}`,point:e,geometryKey:{}});const s={segments:i,vias:r,traceId:t.pcb_trace_id,netId:n};return this.immutableTraceGeometry.set(t,s),s}collectImmutableDynamicGeometry(t){const e=[],n=[],o=new Set;for(const i of t){const t=this.getImmutableTraceGeometry(i);for(const n of t.segments)e.push({geometryKey:n.geometryKey,kind:"trace_segment",traceId:n.traceId,netId:n.netId,start:n.start,end:n.end,width:n.width,layer:n.layer,pcbPortIds:n.pcbPortIds,order:e.length});for(const e of t.vias){if(o.has(e.locationKey))continue;o.add(e.locationKey);const i=e.point,r=e.prepared??={geometryKey:e.geometryKey,kind:"via",traceId:t.traceId,netId:t.netId,x:i.x,y:i.y,diameter:i.via_diameter??this.srj.minViaDiameter??.3,layers:f1(i,this.srj.layerCount)};n.push({geometryKey:r.geometryKey,kind:"via",traceId:r.traceId,netId:r.netId,x:r.x,y:r.y,diameter:r.diameter,layers:r.layers,order:n.length,viaId:`via_${n.length}`})}}return{segments:e,vias:n}}collectDynamicGeometry(t){if(this.cacheImmutableTraceGeometry)return this.collectImmutableDynamicGeometry(t);const e=[],n=[],o=new Set;for(const i of t){const t=this.resolveNetId(i.connection_name),r=w1(i);for(let n=0;n<i.route.length-1;n+=1){const o=i.route[n],s=i.route[n+1];"wire"===o?.route_type&&"wire"===s?.route_type&&o.layer===s.layer&&(Math.abs(o.x-s.x)<=_1&&Math.abs(o.y-s.y)<=_1||e.push({kind:"trace_segment",order:e.length,traceId:i.pcb_trace_id,netId:t,start:{x:o.x,y:o.y},end:{x:s.x,y:s.y},width:E1(o,s),layer:o.layer,pcbPortIds:r}))}for(const e of i.route){if("via"!==e.route_type)continue;const r=`${e.x},${e.y},${e.from_layer},${e.to_layer}`;o.has(r)||(o.add(r),n.push({kind:"via",order:n.length,viaId:`via_${n.length}`,traceId:i.pcb_trace_id,netId:t,x:e.x,y:e.y,diameter:e.via_diameter??this.srj.minViaDiameter??.3,layers:f1(e,this.srj.layerCount)}))}}return{segments:e,vias:n}}getImmutableDynamicCellKeys(t,e){const n=t.geometryKey;if(!n)throw new Error("Immutable spatial cache requires private entity identities");let o=this.immutableDynamicCellKeys.get(n);if(!o){const i="trace_segment"===t.kind?x1(t):v1(t);o=e.getCellKeys(b1(i,this.traceClearance)),this.immutableDynamicCellKeys.set(n,o)}return o}getImmutableDynamicQueryCellKeys(t,e,n){const o=t.geometryKey;if(!o)throw new Error("Immutable spatial cache requires private entity identities");let i=this.immutableDynamicQueryCellKeys.get(o);return i||(i=e.getCellKeys(n),this.immutableDynamicQueryCellKeys.set(o,i)),i}getStaticObstacleCandidates(t,e){const n=t.geometryKey;if(!n)throw new Error("Immutable spatial cache requires private entity identities");let o=this.immutableStaticCandidates.get(n);o||(o=new Map,this.immutableStaticCandidates.set(n,o));let i=o.get(e);if(!i){const n="trace_segment"===t.kind?x1(t):v1(t);i=this.obstacleIndexesByLayer.get(e)?.query(n)??[],o.set(e,i)}return i}buildImmutableDynamicIndexes(t,e){const n=new Map,o=(t,e)=>{let o=n.get(t);o||(o=new C1(this.cellSize),n.set(t,o)),o.insertWithCellKeys(e,this.getImmutableDynamicCellKeys(e,o))};for(const e of t)o(e.layer,e);for(const t of e)for(const e of t.layers)o(e,t);return n}buildDynamicIndexes(t,e){if(this.cacheImmutableTraceGeometry)return this.buildImmutableDynamicIndexes(t,e);const n=new Map,o=(t,e,o)=>{let i=n.get(t);i||(i=new C1(this.cellSize),n.set(t,i)),i.insert(e,b1(o,this.traceClearance))};for(const e of t)o(e.layer,e,x1(e));for(const t of e)for(const e of t.layers)o(e,t,v1(t));return n}obstacleSharesNet(t,e){return this.staticObstacleNets?this.staticObstacleNets.get(e).has(this.resolveNetId(t)):e.connectedTo.some(e=>this.areConnected(t,e))}checkTracePair(t,e){if(this.areConnected(t.netId,e.netId))return;this.lastRunStats.exactCheckCount+=1;const n=Oe(t.start,t.end,e.start,e.end)-t.width/2-e.width/2;if(n>this.traceClearance-y1)return;const o=`overlap_${t.traceId}_${e.traceId}`;return{type:"pcb_trace_error",error_type:"pcb_trace_error",message:T1(t.traceId,`PCB trace ${e.traceId}`,n),pcb_trace_id:t.traceId,source_trace_id:"",pcb_trace_error_id:o,minimum_clearance:this.traceClearance,actual_clearance:n,pcb_component_ids:[],pcb_port_ids:[...new Set([...t.pcbPortIds,...e.pcbPortIds])],center:this.cacheImmutableTraceGeometry?{...P1(t,e)}:P1(t,e)}}checkTraceVia(t,e){if(this.areConnected(t.netId,e.netId))return;this.lastRunStats.exactCheckCount+=1;const n=De(t.start,t.end,{x:e.x,y:e.y,radius:e.diameter/2})-t.width/2;if(n>this.traceClearance-y1)return;const o=`overlap_${t.traceId}_${e.viaId}`;return{type:"pcb_trace_error",error_type:"pcb_trace_error",message:T1(t.traceId,`pcb_via "${e.viaId}"`,n),pcb_trace_id:t.traceId,...this.includeTraceViaOwnerMetadata?{pcb_trace_ids:[t.traceId,e.traceId],pcb_via_id:e.viaId,pcb_via_ids:[e.viaId]}:{},source_trace_id:"",pcb_trace_error_id:o,minimum_clearance:this.traceClearance,actual_clearance:n,pcb_component_ids:[],pcb_port_ids:this.cacheImmutableTraceGeometry?[...t.pcbPortIds]:t.pcbPortIds,center:M1(t,e)}}checkTraceObstacle(t,e){if(this.obstacleSharesNet(t.netId,e))return;this.lastRunStats.exactCheckCount+=1;const n=S1(e);if(this.useConservativeRectObstaclePrecheck&&void 0===e.radius&&((t,e,n)=>{const o=t.width/2+n-y1;return Math.max(e.minX-Math.max(t.start.x,t.end.x),Math.min(t.start.x,t.end.x)-e.maxX,e.minY-Math.max(t.start.y,t.end.y),Math.min(t.start.y,t.end.y)-e.maxY)>o+1e-9&&e.minX<=e.maxX&&e.minY<=e.maxY&&Number.isFinite(o)&&Math.abs(t.start.x)<=1e4&&Math.abs(t.start.y)<=1e4&&Math.abs(t.end.x)<=1e4&&Math.abs(t.end.y)<=1e4&&Math.abs(e.minX)<=1e4&&Math.abs(e.minY)<=1e4&&Math.abs(e.maxX)<=1e4&&Math.abs(e.maxY)<=1e4})(t,n,this.traceClearance))return;const o=(void 0===e.radius?ke(t.start,t.end,n):De(t.start,t.end,{x:e.x,y:e.y,radius:e.radius}))-t.width/2;if(o+y1>=this.traceClearance)return;const i=`overlap_${t.traceId}_${e.obstacleId}`;return{type:"pcb_trace_error",error_type:"pcb_trace_error",message:T1(t.traceId,`${e.obstacleType} "${e.obstacleId}"`,o),pcb_trace_id:t.traceId,source_trace_id:"",pcb_trace_error_id:i,minimum_clearance:this.traceClearance,actual_clearance:o,pcb_component_ids:[],pcb_port_ids:[...new Set([...t.pcbPortIds,...e.pcbPortId?[e.pcbPortId]:[]])],center:void 0===e.radius?N1(t,n):M1(t,e)}}appendTraceObstacleErrors(t,e){const n=this.cacheImmutableTraceGeometry?t.geometryKey:void 0,o=n?this.immutableStaticClearance.get(n):void 0;if(o)return this.lastRunStats.broadPhaseCandidateCount+=o.broadPhaseCandidateCount,void(this.lastRunStats.exactCheckCount+=o.exactCheckCount);const i=this.cacheImmutableTraceGeometry?this.getStaticObstacleCandidates(t,t.layer):this.obstacleIndexesByLayer.get(t.layer)?.query(x1(t))??[],r=e.length,s=this.lastRunStats.exactCheckCount;for(const n of i){this.lastRunStats.broadPhaseCandidateCount+=1;const o=this.checkTraceObstacle(t,n);o&&e.push(o)}n&&e.length===r&&this.immutableStaticClearance.set(n,{broadPhaseCandidateCount:i.length,exactCheckCount:this.lastRunStats.exactCheckCount-s})}checkViaObstacle(t,e){if(this.obstacleSharesNet(t.netId,e))return;this.lastRunStats.exactCheckCount+=1;const n=S1(e),o=(void 0===e.radius?Math.hypot(Math.max(n.minX-t.x,0,t.x-n.maxX),Math.max(n.minY-t.y,0,t.y-n.maxY)):Math.hypot(t.x-e.x,t.y-e.y)-e.radius)-t.diameter/2;if(o+y1>=this.viaToPadClearance)return;const i=`via_pad_clearance_${t.viaId}_${e.obstacleId}`,r={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return{type:"pcb_pad_pad_clearance_error",error_type:"pcb_pad_pad_clearance_error",pcb_pad_pad_clearance_error_id:i,message:`pcb_via "${t.viaId}" and ${e.obstacleType} "${e.obstacleId}" are too close (gap: ${o.toFixed(3)}mm)`,pcb_trace_id:t.traceId,pcb_pad_ids:[t.viaId,e.obstacleId],pcb_via_ids:[t.viaId],minimum_clearance:this.viaToPadClearance,actual_clearance:o,center:r}}checkViaPairs(t){if(t.length<2)return[];const e=[],n=new C1(this.cellSize);for(const e of t)n.insert(e,b1(v1(e),this.viaClearance));for(const o of t)for(const t of n.query(v1(o))){if(this.lastRunStats.broadPhaseCandidateCount+=1,t.order<=o.order)continue;this.lastRunStats.exactCheckCount+=1;const n=Math.hypot(o.x-t.x,o.y-t.y);if(n<=_1)continue;const i=n-o.diameter/2-t.diameter/2;if(i+y1>=this.viaClearance)continue;const r=this.areConnected(o.netId,t.netId),s=[o.viaId,t.viaId].sort().join("_"),a={x:(o.x+t.x)/2,y:(o.y+t.y)/2};e.push({type:"pcb_via_clearance_error",error_type:"pcb_via_clearance_error",pcb_error_id:`${r?"same_net":"different_net"}_vias_close_${s}`,message:`Vias ${o.viaId} and ${t.viaId}${r?"":" from different nets"} are too close together (gap: ${i.toFixed(3)}mm)`,pcb_via_ids:[o.viaId,t.viaId],...this.includeTraceViaOwnerMetadata?{pcb_trace_ids:[o.traceId,t.traceId]}:{},pcb_via_pair_net_relation:r?"same_net":"different_net",minimum_clearance:this.viaClearance,actual_clearance:i,pcb_center:a,center:a})}return e}evaluate(t){return this.evaluateInternal(t,!0)}evaluateLegacy(t){return this.evaluateInternal(t,!1)}evaluateInternal(t,e){const{segments:n,vias:o}=this.collectDynamicGeometry(t),i=this.buildDynamicIndexes(n,o),r=[],s=[];this.lastRunStats={traceCount:t.length,segmentCount:n.length,viaCount:o.length,obstacleCount:this.obstacles.length,broadPhaseCandidateCount:0,exactCheckCount:0};for(const t of n){const e=x1(t),n=i.get(t.layer),o=n?this.cacheImmutableTraceGeometry?this.useTransientDynamicQueryMarkers?n.queryWithCellKeysUsingOrder(this.getImmutableDynamicQueryCellKeys(t,n,e),t.order):n.queryWithCellKeys(this.getImmutableDynamicQueryCellKeys(t,n,e)):n.query(e):[];for(const e of o){if(this.lastRunStats.broadPhaseCandidateCount+=1,"trace_segment"===e.kind&&e.order<=t.order)continue;const n="trace_segment"===e.kind?this.checkTracePair(t,e):this.checkTraceVia(t,e);n&&r.push(n)}this.appendTraceObstacleErrors(t,r)}const a=this.checkViaPairs(o);if(e)for(const t of o){const e=new Set;for(const n of t.layers){const o=this.cacheImmutableTraceGeometry?this.getStaticObstacleCandidates(t,n):this.obstacleIndexesByLayer.get(n)?.query(v1(t))??[];for(const n of o){if(e.has(n))continue;e.add(n),this.lastRunStats.broadPhaseCandidateCount+=1;const o=this.checkViaObstacle(t,n);o&&s.push(o)}}}const c=new Map;for(const t of r){const e=String(t.pcb_trace_error_id),n=c.get(e),o=Number(t.actual_clearance);if(!n){c.set(e,{...t,first_contact_center:t.center,first_contact_message:t.message,first_actual_clearance:o,worst_contact_center:t.center,worst_contact_message:t.message,worst_actual_clearance:o});continue}const i=Number(n.worst_actual_clearance);(o<i||!Number.isFinite(i))&&(n.worst_contact_center=t.center,n.worst_contact_message=t.message,n.worst_actual_clearance=o)}const l=[...c.values()].map(t=>({...t,center:"object"==typeof t.worst_contact_center?t.worst_contact_center:t.center,message:"string"==typeof t.worst_contact_message?t.worst_contact_message:t.message,actual_clearance:"number"==typeof t.worst_actual_clearance?t.worst_actual_clearance:t.actual_clearance}));l.push(...s),l.push(...a);const d=l.filter(t=>t.center);return{errors:l,errorsWithCenters:d,locationAwareErrors:d}}},E1=(t,e)=>t.width??e.width??.1,A1={Hz:{baseUnit:"Hz",variants:{MHz:1e6,kHz:1e3,Hz:1}},g:{baseUnit:"g",variants:{kg:1e3,g:1}},"Ω":{baseUnit:"Ω",variants:{"mΩ":.001,"Ω":1,"kΩ":1e3,"KΩ":1e3,kohm:1e3,"MΩ":1e6,"GΩ":1e9,"TΩ":1e12}},V:{baseUnit:"V",variants:{mV:.001,V:1,kV:1e3,KV:1e3,MV:1e6,GV:1e9,TV:1e12}},A:{baseUnit:"A",variants:{"µA":1e-6,mA:.001,ma:.001,A:1,kA:1e3,MA:1e6}},F:{baseUnit:"F",variants:{pF:1e-12,nF:1e-9,"µF":1e-6,uF:1e-6,mF:.001,F:1}},ml:{baseUnit:"ml",variants:{ml:1,mL:1,l:1e3,L:1e3}},deg:{baseUnit:"deg",variants:{rad:180/Math.PI}},ms:{baseUnit:"ms",variants:{fs:1e-12,ps:1e-9,ns:1e-6,us:.001,"µs":.001,ms:1,s:1e3}},mm:{baseUnit:"mm",variants:{nm:1e-6,"µm":.001,um:.001,mm:1,cm:10,dm:100,m:1e3,km:1e6,in:25.4,ft:304.8,IN:25.4,FT:304.8,yd:914.4,mi:1609344,mil:.0254}}},O1=new Set;for(const[t,e]of Object.entries(A1)){O1.add(t);for(const t of Object.keys(e.variants))O1.add(t)}var k1={tera:1e12,T:1e12,giga:1e9,G:1e9,mega:1e6,M:1e6,kilo:1e3,k:1e3,deci:.1,d:.1,centi:.01,c:.01,milli:.001,m:.001,micro:1e-6,u:1e-6,"µ":1e-6,nano:1e-9,n:1e-9,pico:1e-12,p:1e-12};function L1(t){if(null==t)return{parsedUnit:null,unitOfValue:null,value:null};if("string"==typeof t&&t.match(/^-?[\d\.]+$/))return{value:Number.parseFloat(t),parsedUnit:null,unitOfValue:null};if("number"==typeof t)return{value:t,parsedUnit:null,unitOfValue:null};if("object"==typeof t&&"x"in t&&"y"in t){const{parsedUnit:e,unitOfValue:n}=L1(t.x),o=L1(t.x),i=L1(t.y);return null===o.value||null===i.value?{parsedUnit:null,unitOfValue:null,value:null}:{parsedUnit:e,unitOfValue:n,value:{x:o.value,y:i.value}}}const e=t.toString().split("").reverse().join(""),n=e.match(/[^\d\s]+/)?.[0];if(!n)throw new Error(`Could not determine unit: "${t}"`);const o=n.split("").reverse().join(""),i=t.slice(0,-o.length);if(o in k1&&!O1.has(o)){const t=k1[o];return{parsedUnit:null,unitOfValue:null,value:Number.parseFloat(i)*t}}const{baseUnit:r,conversionFactor:s}=function(t){for(const[e,n]of Object.entries(A1))if(t in n.variants)return{baseUnit:n.baseUnit,conversionFactor:n.variants[t]};return{baseUnit:t,conversionFactor:1}}(o);return{parsedUnit:o,unitOfValue:r,value:s*Number.parseFloat(i)}}var D1=k_.string().or(k_.number()).transform(t=>L1(t).value),z1=k_.string().or(k_.number()).transform(t=>L1(t).value).transform(t=>Number.parseFloat(t.toPrecision(12))),F1=k_.string().or(k_.number()).transform(t=>L1(t).value),B1=k_.string().or(k_.number()).transform(t=>L1(t).value),j1=k_.string().or(k_.number()).transform(t=>L1(t).value),$1=k_.string().or(k_.number()).transform(t=>L1(t).value),Y1=j1,X1=k_.string().or(k_.number()).transform(t=>L1(t).value),V1=k_.string().or(k_.number()).transform(t=>L1(t).value),W1=V1,H1=k_.string().datetime(),G1=k_.string().or(k_.number()).transform(t=>"number"==typeof t?t:t.endsWith("deg")?Number.parseFloat(t.split("deg")[0]):t.endsWith("rad")?180*Number.parseFloat(t.split("rad")[0])/Math.PI:Number.parseFloat(t)),U1=k_.number().or(k_.string().endsWith("mAh")).transform(t=>{if("string"==typeof t){const e=t.replace("mAh",""),n=Number.parseFloat(e);if(Number.isNaN(n))throw new Error("Invalid capacity");return n}return t}).describe("Battery capacity in mAh"),Z1=k_.object({x:Y1,y:Y1}),q1=k_.object({x:Y1,y:Y1,z:Y1}),J1=k_.object({width:k_.number(),height:k_.number()}),K1=t=>k_.string().optional().default(()=>`${t}_${(t=>{const e="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";return Array.from({length:t},()=>e[Math.floor(62*Math.random())]).join("")})(10)}`),Q1=k_.enum(["top_left","top_center","top_right","center_left","center","center_right","bottom_left","bottom_center","bottom_right"]),t2=(k_.enum(["top_silkscreen","bottom_silkscreen","top_copper","bottom_copper","top_soldermask","bottom_soldermask","top_fabrication_note","bottom_fabrication_note","top_user_note","bottom_user_note","top_courtyard","bottom_courtyard","inner1_copper","inner2_copper","inner3_copper","inner4_copper","inner5_copper","inner6_copper","edge_cuts","drill"]),k_.object({project_relative_path:k_.string(),url:k_.string(),mimetype:k_.string()})),e2=Z1.extend({rotation:G1.optional()}),n2=k_.object({size:Z1.optional(),thickness:Y1.optional()}),o2=k_.object({font:n2.optional()}),i2=k_.object({value:k_.string(),at:e2.optional(),layer:k_.string().optional(),uuid:k_.string().optional(),hide:k_.boolean().optional(),effects:o2.optional()}),r2=k_.object({Reference:i2.optional(),Value:i2.optional(),Datasheet:i2.optional(),Description:i2.optional()}),s2=k_.object({through_hole:k_.boolean().optional(),smd:k_.boolean().optional(),exclude_from_pos_files:k_.boolean().optional(),exclude_from_bom:k_.boolean().optional()}),a2=k_.object({name:k_.string(),type:k_.string(),shape:k_.string().optional(),at:e2.optional(),size:Z1.optional(),drill:Y1.optional(),layers:k_.array(k_.string()).optional(),removeUnusedLayers:k_.boolean().optional(),uuid:k_.string().optional()}),c2=k_.object({path:k_.string(),offset:q1.optional(),scale:q1.optional(),rotate:q1.optional()}),l2=k_.object({footprintName:k_.string().optional(),version:k_.union([k_.number(),k_.string()]).optional(),generator:k_.string().optional(),generatorVersion:k_.union([k_.number(),k_.string()]).optional(),layer:k_.string().optional(),properties:r2.optional(),attributes:s2.optional(),pads:k_.array(a2).optional(),embeddedFonts:k_.boolean().optional(),model:c2.optional()}),d2=k_.object({hide:k_.boolean().optional()}),h2=k_.object({offset:Y1.optional(),hide:k_.boolean().optional()}),u2=k_.object({font:n2.optional(),justify:k_.union([k_.string(),k_.array(k_.string())]).optional(),hide:k_.boolean().optional()}),p2=k_.object({value:k_.string(),id:k_.union([k_.number(),k_.string()]).optional(),at:e2.optional(),effects:u2.optional()}),m2=k_.object({Reference:p2.optional(),Value:p2.optional(),Footprint:p2.optional(),Datasheet:p2.optional(),Description:p2.optional(),ki_keywords:p2.optional(),ki_fp_filters:p2.optional()}),g2=k_.object({symbolName:k_.string().optional(),extends:k_.string().optional(),pinNumbers:d2.optional(),pinNames:h2.optional(),excludeFromSim:k_.boolean().optional(),inBom:k_.boolean().optional(),onBoard:k_.boolean().optional(),properties:m2.optional(),embeddedFonts:k_.boolean().optional()}),f2=k_.object({error_type:k_.string(),message:k_.string(),is_fatal:k_.boolean().optional()}),y2=k_.enum(["jlcpcb","macrofab","pcbway","digikey","mouser","lcsc"]),_2=k_.object({type:k_.literal("source_component"),ftype:k_.string().optional(),source_component_id:k_.string(),name:k_.string(),manufacturer_part_number:k_.string().optional(),supplier_part_numbers:k_.record(y2,k_.array(k_.string())).optional(),display_value:k_.string().optional(),display_name:k_.string().optional(),are_pins_interchangeable:k_.boolean().optional(),internally_connected_source_port_ids:k_.array(k_.array(k_.string())).optional(),source_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}),b2=_2.extend({ftype:k_.literal("simple_capacitor"),capacitance:z1,max_voltage_rating:B1.optional(),display_capacitance:k_.string().optional(),max_decoupling_trace_length:Y1.optional()}),x2=_2.extend({ftype:k_.literal("simple_resistor"),resistance:D1,display_resistance:k_.string().optional()}),v2=_2.extend({ftype:k_.literal("simple_diode")}),S2=_2.extend({ftype:k_.literal("simple_fiducial")}),I2=v2.extend({ftype:k_.literal("simple_led"),color:k_.string().optional(),wavelength:k_.string().optional()}),C2=_2.extend({ftype:k_.literal("simple_ground")}),P2=_2.extend({ftype:k_.literal("simple_chip")}),M2=_2.extend({ftype:k_.literal("simple_power_source"),voltage:B1}),N2=_2.extend({ftype:k_.literal("simple_current_source"),current:X1,frequency:$1.optional(),peak_to_peak_current:X1.optional(),wave_shape:k_.enum(["sine","square","triangle","sawtooth","dc"]).optional().default("dc"),phase:k_.number().optional(),duty_cycle:k_.number().min(0).max(1).optional()}),w2=k_.object({must_be_connected:k_.boolean().optional(),provides_power:k_.boolean().optional(),requires_power:k_.boolean().optional(),provides_ground:k_.boolean().optional(),requires_ground:k_.boolean().optional(),provides_voltage:k_.union([k_.string(),k_.number()]).optional(),requires_voltage:k_.union([k_.string(),k_.number()]).optional(),do_not_connect:k_.boolean().optional(),include_in_board_pinout:k_.boolean().optional(),can_use_internal_pullup:k_.boolean().optional(),is_using_internal_pullup:k_.boolean().optional(),needs_external_pullup:k_.boolean().optional(),can_use_internal_pulldown:k_.boolean().optional(),is_using_internal_pulldown:k_.boolean().optional(),needs_external_pulldown:k_.boolean().optional(),can_use_open_drain:k_.boolean().optional(),is_using_open_drain:k_.boolean().optional(),can_use_push_pull:k_.boolean().optional(),is_using_push_pull:k_.boolean().optional(),should_have_decoupling_capacitor:k_.boolean().optional(),recommended_decoupling_capacitor_capacitance:k_.union([k_.string(),k_.number()]).optional(),is_configured_for_i2c_sda:k_.boolean().optional(),is_configured_for_i2c_scl:k_.boolean().optional(),is_configured_for_spi_mosi:k_.boolean().optional(),is_configured_for_spi_miso:k_.boolean().optional(),is_configured_for_spi_sck:k_.boolean().optional(),is_configured_for_spi_cs:k_.boolean().optional(),is_configured_for_uart_tx:k_.boolean().optional(),is_configured_for_uart_rx:k_.boolean().optional(),supports_i2c_sda:k_.boolean().optional(),supports_i2c_scl:k_.boolean().optional(),supports_spi_mosi:k_.boolean().optional(),supports_spi_miso:k_.boolean().optional(),supports_spi_sck:k_.boolean().optional(),supports_spi_cs:k_.boolean().optional(),supports_uart_tx:k_.boolean().optional(),supports_uart_rx:k_.boolean().optional()}),T2=_2.extend({ftype:k_.literal("simple_fuse"),current_rating_amps:k_.number().describe("Nominal current in amps the fuse is rated for"),voltage_rating_volts:k_.number().describe("Voltage rating in volts, e.g. ±5V would be 5")}),R2=_2.extend({ftype:k_.literal("simple_battery"),capacity:U1}),E2=_2.extend({ftype:k_.literal("simple_inductor"),inductance:F1,display_inductance:k_.string().optional(),max_current_rating:k_.number().optional()}),A2=_2.extend({ftype:k_.literal("simple_push_button")}),O2=_2.extend({ftype:k_.literal("simple_potentiometer"),max_resistance:D1,display_max_resistance:k_.string().optional()}),k2=_2.extend({ftype:k_.literal("simple_crystal"),frequency:k_.number().describe("Frequency in Hz"),load_capacitance:k_.number().optional().describe("Load capacitance in pF"),pin_variant:k_.enum(["two_pin","four_pin"]).optional()}),L2=_2.extend({ftype:k_.literal("simple_pin_header"),pin_count:k_.number(),gender:k_.enum(["male","female"]).optional().default("male")}),D2=_2.extend({ftype:k_.literal("simple_connector"),standard:k_.enum(["usb_c","m2"]).optional()}),z2=_2.extend({ftype:k_.literal("simple_pinout")}),F2=_2.extend({ftype:k_.literal("simple_resonator"),load_capacitance:z1,equivalent_series_resistance:D1.optional(),frequency:$1}),B2=_2.extend({ftype:k_.literal("simple_transistor"),transistor_type:k_.enum(["npn","pnp"])}),j2=_2.extend({ftype:k_.literal("simple_test_point"),footprint_variant:k_.enum(["pad","through_hole"]).optional(),pad_shape:k_.enum(["rect","circle"]).optional(),pad_diameter:k_.union([k_.number(),k_.string()]).optional(),hole_diameter:k_.union([k_.number(),k_.string()]).optional(),width:k_.union([k_.number(),k_.string()]).optional(),height:k_.union([k_.number(),k_.string()]).optional()}),$2=_2.extend({ftype:k_.literal("simple_mosfet"),channel_type:k_.enum(["n","p"]),mosfet_mode:k_.enum(["enhancement","depletion"])}),Y2=_2.extend({ftype:k_.literal("simple_op_amp")}),X2=_2.extend({ftype:k_.literal("simple_switch")}),V2=k_.object({type:k_.literal("source_project_metadata"),name:k_.string().optional(),software_used_string:k_.string().optional(),project_url:k_.string().optional(),created_at:H1.optional()}),W2=f2.extend({type:k_.literal("source_missing_property_error"),source_missing_property_error_id:K1("source_missing_property_error"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal("source_missing_property_error").default("source_missing_property_error")}).describe("The source code is missing a property"),H2=f2.extend({type:k_.literal("source_failed_to_create_component_error"),source_failed_to_create_component_error_id:K1("source_failed_to_create_component_error"),error_type:k_.literal("source_failed_to_create_component_error").default("source_failed_to_create_component_error"),component_name:k_.string().optional(),subcircuit_id:k_.string().optional(),parent_source_component_id:k_.string().optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),schematic_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional()}).describe("Error emitted when a component fails to be constructed"),G2=f2.extend({type:k_.literal("source_invalid_component_property_error"),source_invalid_component_property_error_id:K1("source_invalid_component_property_error"),source_component_id:k_.string(),property_name:k_.string(),property_value:k_.unknown().optional(),expected_format:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal("source_invalid_component_property_error").default("source_invalid_component_property_error")}).describe("The source component property is invalid"),U2=f2.extend({type:k_.literal("source_trace_not_connected_error"),source_trace_not_connected_error_id:K1("source_trace_not_connected_error"),error_type:k_.literal("source_trace_not_connected_error").default("source_trace_not_connected_error"),subcircuit_id:k_.string().optional(),source_group_id:k_.string().optional(),source_trace_id:k_.string().optional(),connected_source_port_ids:k_.array(k_.string()).optional(),selectors_not_found:k_.array(k_.string()).optional()}).describe("Occurs when a source trace selector does not match any ports"),Z2=k_.object({type:k_.literal("source_property_ignored_warning"),source_property_ignored_warning_id:K1("source_property_ignored_warning"),source_component_id:k_.string(),property_name:k_.string(),subcircuit_id:k_.string().optional(),error_type:k_.literal("source_property_ignored_warning").default("source_property_ignored_warning"),message:k_.string()}).describe("The source property was ignored"),q2=k_.object({type:k_.literal("source_pin_missing_trace_warning"),source_pin_missing_trace_warning_id:K1("source_pin_missing_trace_warning"),warning_type:k_.literal("source_pin_missing_trace_warning").default("source_pin_missing_trace_warning"),message:k_.string(),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a source component pin is missing a trace connection"),J2=k_.object({type:k_.literal("source_missing_manufacturer_part_number_warning"),source_missing_manufacturer_part_number_warning_id:K1("source_missing_manufacturer_part_number_warning"),warning_type:k_.literal("source_missing_manufacturer_part_number_warning").default("source_missing_manufacturer_part_number_warning"),message:k_.string(),source_component_id:k_.string(),standard:k_.string(),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a standard connector is missing manufacturer part number"),K2=_2.extend({ftype:k_.literal("simple_voltage_probe")}),Q2=_2.extend({ftype:k_.literal("interconnect")}),t5=f2.extend({type:k_.literal("source_i2c_misconfigured_error"),source_i2c_misconfigured_error_id:K1("source_i2c_misconfigured_error"),error_type:k_.literal("source_i2c_misconfigured_error").default("source_i2c_misconfigured_error"),source_port_ids:k_.array(k_.string())}).describe("Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net"),e5=_2.extend({ftype:k_.literal("simple_voltage_source"),voltage:B1,frequency:$1.optional(),peak_to_peak_voltage:B1.optional(),wave_shape:k_.enum(["sinewave","square","triangle","sawtooth"]).optional(),phase:G1.optional(),duty_cycle:k_.number().optional().describe("Duty cycle as a fraction (0 to 1)")}),n5=k_.union([x2,b2,v2,S2,I2,C2,P2,M2,N2,R2,E2,A2,O2,k2,L2,D2,z2,F2,X2,B2,j2,$2,Y2,T2,K2,Q2,e5,V2,W2,G2,H2,U2,Z2,q2,J2,t5]),o5=k_.object({type:k_.literal("source_port"),pin_number:k_.number().optional(),port_hints:k_.array(k_.string()).optional(),name:k_.string(),source_port_id:k_.string(),source_component_id:k_.string().optional(),source_group_id:k_.string().optional(),most_frequently_referenced_by_name:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}).merge(w2),i5=k_.object({type:k_.literal("source_component_internal_connection"),source_component_internal_connection_id:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}),r5=k_.object({type:k_.literal("source_trace"),source_trace_id:k_.string(),connected_source_port_ids:k_.array(k_.string()),connected_source_net_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),max_length:k_.number().optional(),min_trace_thickness:k_.number().optional(),display_name:k_.string().optional()}),s5=k_.object({type:k_.literal("source_group"),source_group_id:k_.string(),subcircuit_id:k_.string().optional(),parent_subcircuit_id:k_.string().optional(),parent_source_group_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),was_automatically_named:k_.boolean().optional()}),a5=k_.object({type:k_.literal("source_net"),source_net_id:k_.string(),name:k_.string(),member_source_group_ids:k_.array(k_.string()),is_power:k_.boolean().optional(),is_ground:k_.boolean().optional(),is_digital_signal:k_.boolean().optional(),is_analog_signal:k_.boolean().optional(),is_positive_voltage_source:k_.boolean().optional(),trace_width:k_.number().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),c5=k_.object({type:k_.literal("source_board"),source_board_id:k_.string(),source_group_id:k_.string(),title:k_.string().optional()}).describe("Defines a board in the source domain"),l5=f2.extend({type:k_.literal("source_ambiguous_port_reference"),source_ambiguous_port_reference_id:K1("source_ambiguous_port_reference"),error_type:k_.literal("source_ambiguous_port_reference").default("source_ambiguous_port_reference"),source_port_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe("Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous"),d5=k_.object({type:k_.literal("source_pcb_ground_plane"),source_pcb_ground_plane_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional()}).describe("Defines a ground plane in the source domain"),h5=k_.enum(["top","bottom","inner1","inner2","inner3","inner4","inner5","inner6"]),u5=h5.or(k_.object({name:h5})).transform(t=>"string"==typeof t?t:t.name),p5=k_.enum(["top","bottom"]),m5=k_.object({type:k_.literal("source_manually_placed_via"),source_manually_placed_via_id:k_.string(),source_group_id:k_.string(),source_net_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional()}).describe("Defines a via that is manually placed in the source domain"),g5=k_.object({type:k_.literal("source_no_power_pin_defined_warning"),source_no_power_pin_defined_warning_id:K1("source_no_power_pin_defined_warning"),warning_type:k_.literal("source_no_power_pin_defined_warning").default("source_no_power_pin_defined_warning"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a chip has no source ports with requires_power=true"),f5=k_.object({type:k_.literal("source_no_ground_pin_defined_warning"),source_no_ground_pin_defined_warning_id:K1("source_no_ground_pin_defined_warning"),warning_type:k_.literal("source_no_ground_pin_defined_warning").default("source_no_ground_pin_defined_warning"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Warning emitted when a chip has no source ports marked as ground pins"),y5=k_.object({type:k_.literal("source_component_pins_underspecified_warning"),source_component_pins_underspecified_warning_id:K1("source_component_pins_underspecified_warning"),warning_type:k_.literal("source_component_pins_underspecified_warning").default("source_component_pins_underspecified_warning"),message:k_.string(),source_component_id:k_.string(),source_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Warning emitted when all ports on a source component are underspecified"),_5=f2.extend({type:k_.literal("source_pin_must_be_connected_error"),source_pin_must_be_connected_error_id:K1("source_pin_must_be_connected_error"),error_type:k_.literal("source_pin_must_be_connected_error").default("source_pin_must_be_connected_error"),source_component_id:k_.string(),source_port_id:k_.string(),subcircuit_id:k_.string().optional()}).describe("Error emitted when a pin with mustBeConnected attribute is not connected to any trace"),b5=f2.extend({type:k_.literal("unknown_error_finding_part"),unknown_error_finding_part_id:K1("unknown_error_finding_part"),error_type:k_.literal("unknown_error_finding_part").default("unknown_error_finding_part"),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when an unexpected error occurs while finding a part"),x5=k_.object({type:k_.literal("schematic_box"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),width:Y1,height:Y1,is_dashed:k_.boolean().default(!1),x:Y1,y:Y1,subcircuit_id:k_.string().optional()}).describe("Draws a box on the schematic"),v5=k_.object({type:k_.literal("schematic_path"),schematic_path_id:K1("schematic_path"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),fill_color:k_.string().optional(),is_filled:k_.boolean().optional(),stroke_width:Y1.nullable().optional(),stroke_color:k_.string().optional(),points:k_.array(Z1),subcircuit_id:k_.string().optional()}),S5=k_.record(k_.object({left_margin:j1.optional(),right_margin:j1.optional(),top_margin:j1.optional(),bottom_margin:j1.optional()})),I5=k_.object({left_size:k_.number(),right_size:k_.number(),top_size:k_.number().optional(),bottom_size:k_.number().optional()}),C5=k_.object({left_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum(["top-to-bottom","bottom-to-top"]).optional()}).optional(),right_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum(["top-to-bottom","bottom-to-top"]).optional()}).optional(),top_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum(["left-to-right","right-to-left"]).optional()}).optional(),bottom_side:k_.object({pins:k_.array(k_.number()),direction:k_.enum(["left-to-right","right-to-left"]).optional()}).optional()}),P5=k_.union([I5,C5]),M5=k_.object({type:k_.literal("schematic_component"),size:J1,center:Z1,source_component_id:k_.string().optional(),schematic_component_id:k_.string(),schematic_symbol_id:k_.string().optional(),pin_spacing:j1.optional(),pin_styles:S5.optional(),box_width:j1.optional(),symbol_name:k_.string().optional(),port_arrangement:P5.optional(),port_labels:k_.record(k_.string()).optional(),symbol_display_value:k_.string().optional(),subcircuit_id:k_.string().optional(),schematic_group_id:k_.string().optional(),is_schematic_group:k_.boolean().optional(),source_group_id:k_.string().optional(),is_box_with_pins:k_.boolean().optional().default(!0)}),N5=k_.object({kicad_symbol:g2.optional()}).catchall(k_.unknown()),w5=k_.object({type:k_.literal("schematic_symbol"),schematic_symbol_id:k_.string(),name:k_.string().optional(),metadata:N5.optional()}).describe("Defines a named schematic symbol that can be referenced by components."),T5=k_.object({type:k_.literal("schematic_line"),schematic_line_id:K1("schematic_line"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),x1:Y1,y1:Y1,x2:Y1,y2:Y1,stroke_width:Y1.nullable().optional(),color:k_.string().default("#000000"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe("Draws a styled line on the schematic"),R5=k_.object({type:k_.literal("schematic_rect"),schematic_rect_id:K1("schematic_rect"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,width:Y1,height:Y1,rotation:G1.default(0),stroke_width:Y1.nullable().optional(),color:k_.string().default("#000000"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe("Draws a styled rectangle on the schematic"),E5=k_.object({type:k_.literal("schematic_circle"),schematic_circle_id:K1("schematic_circle"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,radius:Y1,stroke_width:Y1.nullable().optional(),color:k_.string().default("#000000"),is_filled:k_.boolean().default(!1),fill_color:k_.string().optional(),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe("Draws a styled circle on the schematic"),A5=k_.object({type:k_.literal("schematic_arc"),schematic_arc_id:K1("schematic_arc"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),center:Z1,radius:Y1,start_angle_degrees:G1,end_angle_degrees:G1,direction:k_.enum(["clockwise","counterclockwise"]).default("counterclockwise"),stroke_width:Y1.nullable().optional(),color:k_.string().default("#000000"),is_dashed:k_.boolean().default(!1),subcircuit_id:k_.string().optional()}).describe("Draws a styled arc on the schematic"),O5=k_.object({type:k_.literal("schematic_trace"),schematic_trace_id:k_.string(),source_trace_id:k_.string().optional(),junctions:k_.array(k_.object({x:k_.number(),y:k_.number()})),edges:k_.array(k_.object({from:k_.object({x:k_.number(),y:k_.number()}),to:k_.object({x:k_.number(),y:k_.number()}),is_crossing:k_.boolean().optional(),from_schematic_port_id:k_.string().optional(),to_schematic_port_id:k_.string().optional()})),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional()}),k5=k_.enum(["center","left","right","top","bottom"]),L5=k_.object({type:k_.literal("schematic_text"),schematic_component_id:k_.string().optional(),schematic_symbol_id:k_.string().optional(),schematic_text_id:k_.string(),text:k_.string(),font_size:k_.number().default(.18),position:k_.object({x:Y1,y:Y1}),rotation:k_.number().default(0),anchor:k_.union([k5.describe("legacy"),Q1]).default("center"),color:k_.string().default("#000000"),subcircuit_id:k_.string().optional()}),D5=k_.object({type:k_.literal("schematic_port"),schematic_port_id:k_.string(),source_port_id:k_.string(),schematic_component_id:k_.string().optional(),center:Z1,facing_direction:k_.enum(["up","down","left","right"]).optional(),distance_from_component_edge:k_.number().optional(),side_of_component:k_.enum(["top","bottom","left","right"]).optional(),true_ccw_index:k_.number().optional(),pin_number:k_.number().optional(),display_pin_label:k_.string().optional(),subcircuit_id:k_.string().optional(),is_connected:k_.boolean().optional(),has_input_arrow:k_.boolean().optional(),has_output_arrow:k_.boolean().optional(),is_drawn_with_inversion_circle:k_.boolean().optional()}).describe("Defines a port on a schematic component"),z5=k_.object({type:k_.literal("schematic_net_label"),schematic_net_label_id:K1("schematic_net_label"),schematic_trace_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_net_id:k_.string(),center:Z1,anchor_position:Z1.optional(),anchor_side:k_.enum(["top","bottom","left","right"]),text:k_.string(),symbol_name:k_.string().optional(),is_movable:k_.boolean().optional(),subcircuit_id:k_.string().optional()}),F5=f2.extend({type:k_.literal("schematic_error"),schematic_error_id:k_.string(),error_type:k_.literal("schematic_port_not_found").default("schematic_port_not_found"),subcircuit_id:k_.string().optional()}).describe("Defines a schematic error on the schematic"),B5=f2.extend({type:k_.literal("schematic_layout_error"),schematic_layout_error_id:K1("schematic_layout_error"),error_type:k_.literal("schematic_layout_error").default("schematic_layout_error"),source_group_id:k_.string(),schematic_group_id:k_.string(),subcircuit_id:k_.string().optional()}).describe("Error emitted when schematic layout fails for a group"),j5=k_.object({type:k_.literal("schematic_debug_object"),label:k_.string().optional(),subcircuit_id:k_.string().optional()}),$5=j5.extend({shape:k_.literal("rect"),center:Z1,size:J1}),Y5=j5.extend({shape:k_.literal("line"),start:Z1,end:Z1}),X5=j5.extend({shape:k_.literal("point"),center:Z1}),V5=k_.discriminatedUnion("shape",[$5,Y5,X5]),W5=k_.object({type:k_.literal("schematic_voltage_probe"),schematic_voltage_probe_id:k_.string(),source_component_id:k_.string().optional(),name:k_.string().optional(),position:Z1,schematic_trace_id:k_.string(),voltage:B1.optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional(),label_alignment:Q1.optional()}).describe("Defines a voltage probe measurement point on a schematic trace"),H5=k_.object({type:k_.literal("schematic_manual_edit_conflict_warning"),schematic_manual_edit_conflict_warning_id:K1("schematic_manual_edit_conflict_warning"),warning_type:k_.literal("schematic_manual_edit_conflict_warning").default("schematic_manual_edit_conflict_warning"),message:k_.string(),schematic_component_id:k_.string(),schematic_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe("Warning emitted when a component has both manual placement and explicit schX/schY coordinates"),G5=k_.object({type:k_.literal("schematic_group"),schematic_group_id:K1("schematic_group"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:j1,height:j1,center:Z1,schematic_component_ids:k_.array(k_.string()),show_as_schematic_box:k_.boolean().optional(),name:k_.string().optional(),description:k_.string().optional()}).describe("Defines a group of components on the schematic"),U5=k_.object({type:k_.literal("schematic_table"),schematic_table_id:K1("schematic_table"),anchor_position:Z1,column_widths:k_.array(Y1),row_heights:k_.array(Y1),cell_padding:Y1.optional(),border_width:Y1.optional(),subcircuit_id:k_.string().optional(),schematic_component_id:k_.string().optional(),anchor:Q1.optional()}).describe("Defines a table on the schematic"),Z5=k_.object({type:k_.literal("schematic_table_cell"),schematic_table_cell_id:K1("schematic_table_cell"),schematic_table_id:k_.string(),start_row_index:k_.number(),end_row_index:k_.number(),start_column_index:k_.number(),end_column_index:k_.number(),text:k_.string().optional(),center:Z1,width:Y1,height:Y1,horizontal_align:k_.enum(["left","center","right"]).optional(),vertical_align:k_.enum(["top","middle","bottom"]).optional(),font_size:Y1.optional(),subcircuit_id:k_.string().optional()}).describe("Defines a cell within a schematic_table"),q5=k_.object({type:k_.literal("schematic_sheet"),schematic_sheet_id:K1("schematic_sheet"),name:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Defines a schematic sheet or page that components can be placed on"),J5=k_.object({x:Y1,y:Y1,bulge:k_.number().optional()}),K5=k_.object({vertices:k_.array(J5)}),Q5=k_.object({outer_ring:K5,inner_rings:k_.array(K5).default([])}),t3=k_.object({x:Y1,y:Y1,via:k_.boolean().optional(),via_to_layer:u5.optional()}),e3=(k_.array(t3),k_.object({x:Y1,y:Y1,via:k_.boolean().optional(),to_layer:u5.optional(),trace_width:Y1.optional()})),n3=k_.object({min_trace_width:j1.optional(),min_board_edge_clearance:j1.optional(),min_via_hole_edge_to_via_hole_edge_clearance:j1.optional(),min_plated_hole_drill_edge_to_drill_edge_clearance:j1.optional(),min_trace_to_pad_edge_clearance:j1.optional(),min_pad_edge_to_pad_edge_clearance:j1.optional(),min_same_net_trace_edge_to_trace_edge_clearance:j1.optional(),min_different_net_trace_edge_to_trace_edge_clearance:j1.optional(),min_via_hole_diameter:j1.optional(),min_via_pad_diameter:j1.optional()}),o3=k_.object({type:k_.literal("pcb_component"),pcb_component_id:K1("pcb_component"),source_component_id:k_.string(),center:Z1,layer:u5,rotation:G1,display_offset_x:k_.string().optional().describe("How to display the x offset for this part, usually corresponding with how the user specified it"),display_offset_y:k_.string().optional().describe("How to display the y offset for this part, usually corresponding with how the user specified it"),width:j1,height:j1,do_not_place:k_.boolean().optional(),is_allowed_to_be_off_board:k_.boolean().optional(),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),position_mode:k_.enum(["packed","relative_to_group_anchor","relative_to_another_component","none"]).optional(),anchor_position:Z1.optional(),anchor_alignment:Q1.optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),cable_insertion_center:Z1.optional(),insertion_direction:k_.enum(["from_above","from_left","from_right","from_front","from_back"]).optional(),metadata:k_.object({kicad_footprint:l2.optional()}).optional(),obstructs_within_bounds:k_.boolean().default(!0).describe("Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath")}).describe("Defines a component on the PCB"),i3=k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:K1("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("circle"),hole_diameter:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),r3=(i3.describe("Defines a circular hole on the PCB"),k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:K1("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("rect"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),s3=(r3.describe("Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square."),k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:K1("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.enum(["circle","square"]),hole_diameter:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),a3=(s3.describe("Defines a circular or square hole on the PCB"),k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:K1("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("oval"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),c3=(a3.describe("Defines an oval hole on the PCB"),k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:K1("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("pill"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),l3=(c3.describe("Defines a pill-shaped hole on the PCB"),k_.object({type:k_.literal("pcb_hole"),pcb_hole_id:K1("pcb_hole"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_component_id:k_.string().optional(),hole_shape:k_.literal("rotated_pill"),hole_width:k_.number(),hole_height:k_.number(),x:Y1,y:Y1,ccw_rotation:G1,is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()})),d3=(l3.describe("Defines a rotated pill-shaped hole on the PCB"),s3.or(a3).or(c3).or(l3).or(i3).or(r3)),h3=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("circle"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_diameter:k_.number(),hole_diameter:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1("pcb_plated_hole"),soldermask_margin:k_.number().optional()}),u3=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.enum(["oval","pill"]),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),outer_width:k_.number(),outer_height:k_.number(),hole_width:k_.number(),hole_height:k_.number(),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,ccw_rotation:G1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1("pcb_plated_hole"),soldermask_margin:k_.number().optional()}),p3=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("circular_hole_with_rect_pad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal("circle"),pad_shape:k_.literal("rect"),hole_diameter:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1("pcb_plated_hole"),soldermask_margin:k_.number().optional(),rect_ccw_rotation:G1.optional()}),m3=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("pill_hole_with_rect_pad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal("pill"),pad_shape:k_.literal("rect"),hole_width:k_.number(),hole_height:k_.number(),rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1("pcb_plated_hole"),soldermask_margin:k_.number().optional()}),g3=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("rotated_pill_hole_with_rect_pad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.literal("rotated_pill"),pad_shape:k_.literal("rect"),hole_width:k_.number(),hole_height:k_.number(),hole_ccw_rotation:G1,rect_pad_width:k_.number(),rect_pad_height:k_.number(),rect_border_radius:k_.number().optional(),rect_ccw_rotation:G1,hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1("pcb_plated_hole"),soldermask_margin:k_.number().optional()}),f3=k_.object({type:k_.literal("pcb_plated_hole"),shape:k_.literal("hole_with_polygon_pad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),hole_shape:k_.enum(["circle","oval","pill","rotated_pill"]),hole_diameter:k_.number().optional(),hole_width:k_.number().optional(),hole_height:k_.number().optional(),pad_outline:k_.array(k_.object({x:Y1,y:Y1})).min(3),hole_offset_x:Y1.default(0),hole_offset_y:Y1.default(0),is_covered_with_solder_mask:k_.boolean().optional(),x:Y1,y:Y1,layers:k_.array(u5),port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),pcb_plated_hole_id:K1("pcb_plated_hole"),soldermask_margin:k_.number().optional(),ccw_rotation:G1.optional()}),y3=k_.union([h3,u3,p3,m3,g3,f3]),_3=k_.object({type:k_.literal("pcb_port"),pcb_port_id:K1("pcb_port"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_port_id:k_.string(),pcb_component_id:k_.string().optional(),x:Y1,y:Y1,layers:k_.array(u5),is_board_pinout:k_.boolean().optional()}).describe("Defines a port on the PCB"),b3=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("circle"),pcb_smtpad_id:K1("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,radius:k_.number(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),x3=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("rect"),pcb_smtpad_id:K1("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),v3=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("rotated_rect"),pcb_smtpad_id:K1("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),rect_border_radius:k_.number().optional(),corner_radius:k_.number().optional(),ccw_rotation:G1,layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional(),soldermask_margin_left:k_.number().optional(),soldermask_margin_top:k_.number().optional(),soldermask_margin_right:k_.number().optional(),soldermask_margin_bottom:k_.number().optional()}),S3=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("pill"),pcb_smtpad_id:K1("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),I3=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("rotated_pill"),pcb_smtpad_id:K1("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),ccw_rotation:G1,layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),C3=k_.object({type:k_.literal("pcb_smtpad"),shape:k_.literal("polygon"),pcb_smtpad_id:K1("pcb_smtpad"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),points:k_.array(Z1),layer:u5,port_hints:k_.array(k_.string()).optional(),pcb_component_id:k_.string().optional(),pcb_port_id:k_.string().optional(),is_covered_with_solder_mask:k_.boolean().optional(),soldermask_margin:k_.number().optional()}),P3=k_.discriminatedUnion("shape",[b3,x3,v3,I3,S3,C3]).describe("Defines an SMT pad on the PCB"),M3=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("circle"),pcb_solder_paste_id:K1("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,radius:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),N3=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("rect"),pcb_solder_paste_id:K1("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),w3=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("pill"),pcb_solder_paste_id:K1("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),radius:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),T3=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("rotated_rect"),pcb_solder_paste_id:K1("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),ccw_rotation:Y1,layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),R3=k_.object({type:k_.literal("pcb_solder_paste"),shape:k_.literal("oval"),pcb_solder_paste_id:K1("pcb_solder_paste"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),x:Y1,y:Y1,width:k_.number(),height:k_.number(),layer:u5,pcb_component_id:k_.string().optional(),pcb_smtpad_id:k_.string().optional()}),E3=k_.union([M3,N3,w3,T3,R3]).describe("Defines solderpaste on the PCB"),A3=k_.object({type:k_.literal("pcb_text"),pcb_text_id:K1("pcb_text"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),text:k_.string(),center:Z1,layer:u5,width:j1,height:j1,lines:k_.number(),align:k_.enum(["bottom-left"])}).describe("Defines text on the PCB"),O3=k_.object({route_type:k_.literal("wire"),x:Y1,y:Y1,width:Y1,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),start_pcb_port_id:k_.string().optional(),end_pcb_port_id:k_.string().optional(),layer:u5}),k3=k_.object({route_type:k_.literal("via"),x:Y1,y:Y1,copper_pour_id:k_.string().optional(),is_inside_copper_pour:k_.boolean().optional(),hole_diameter:Y1.optional(),outer_diameter:Y1.optional(),from_layer:u5,to_layer:u5}),L3=k_.union([O3,k3]),D3=k_.object({type:k_.literal("pcb_trace"),source_trace_id:k_.string().optional(),pcb_component_id:k_.string().optional(),pcb_trace_id:K1("pcb_trace"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),route_thickness_mode:k_.enum(["constant","interpolated"]).default("constant").optional(),route_order_index:k_.number().optional(),should_round_corners:k_.boolean().optional(),trace_length:k_.number().optional(),highlight_color:k_.string().optional(),route:k_.array(L3)}).describe("Defines a trace on the PCB"),z3=k_.object({type:k_.literal("pcb_trace_warning"),pcb_trace_warning_id:K1("pcb_trace_warning"),warning_type:k_.literal("pcb_trace_warning").default("pcb_trace_warning"),message:k_.string(),center:Z1.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines a trace warning on the PCB"),F3=f2.extend({type:k_.literal("pcb_trace_error"),pcb_trace_error_id:K1("pcb_trace_error"),error_type:k_.literal("pcb_trace_error").default("pcb_trace_error"),center:Z1.optional(),pcb_trace_id:k_.string(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines a trace error on the PCB"),B3=f2.extend({type:k_.literal("pcb_trace_missing_error"),pcb_trace_missing_error_id:K1("pcb_trace_missing_error"),error_type:k_.literal("pcb_trace_missing_error").default("pcb_trace_missing_error"),center:Z1.optional(),source_trace_id:k_.string(),pcb_component_ids:k_.array(k_.string()),pcb_port_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines an error when a source trace has no corresponding PCB trace"),j3=f2.extend({type:k_.literal("pcb_port_not_matched_error"),pcb_error_id:K1("pcb_error"),error_type:k_.literal("pcb_port_not_matched_error").default("pcb_port_not_matched_error"),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines a trace error on the PCB where a port is not matched"),$3=f2.extend({type:k_.literal("pcb_port_not_connected_error"),pcb_port_not_connected_error_id:K1("pcb_port_not_connected_error"),error_type:k_.literal("pcb_port_not_connected_error").default("pcb_port_not_connected_error"),pcb_port_ids:k_.array(k_.string()),pcb_component_ids:k_.array(k_.string()),subcircuit_id:k_.string().optional()}).describe("Defines an error when a pcb port is not connected to any trace"),Y3=k_.object({type:k_.literal("pcb_net"),pcb_net_id:K1("pcb_net"),source_net_id:k_.string().optional(),highlight_color:k_.string().optional()}).describe("Defines a net on the PCB"),X3=k_.object({type:k_.literal("pcb_via"),pcb_via_id:K1("pcb_via"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),x:Y1,y:Y1,outer_diameter:Y1.default("0.6mm"),hole_diameter:Y1.default("0.25mm"),from_layer:u5.optional(),to_layer:u5.optional(),layers:k_.array(u5),pcb_trace_id:k_.string().optional(),net_is_assignable:k_.boolean().optional(),net_assigned:k_.boolean().optional(),is_tented:k_.boolean().optional()}).describe("Defines a via on the PCB"),V3=k_.object({type:k_.literal("pcb_board"),pcb_board_id:K1("pcb_board"),pcb_panel_id:k_.string().optional(),carrier_pcb_board_id:k_.string().optional(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),is_mounted_to_carrier_board:k_.boolean().optional(),width:j1.optional(),height:j1.optional(),center:Z1,display_offset_x:k_.string().optional().describe("How to display the x offset for this board, usually corresponding with how the user specified it"),display_offset_y:k_.string().optional().describe("How to display the y offset for this board, usually corresponding with how the user specified it"),thickness:j1.optional().default(1.4),num_layers:k_.number().optional().default(4),outline:k_.array(Z1).optional(),shape:k_.enum(["rect","polygon"]).optional(),material:k_.enum(["fr4","fr1"]).default("fr4"),anchor_position:Z1.optional(),anchor_alignment:Q1.optional(),position_mode:k_.enum(["relative_to_panel_anchor","none"]).optional()}).merge(n3).describe("Defines the board outline of the PCB"),W3=k_.object({type:k_.literal("pcb_panel"),pcb_panel_id:K1("pcb_panel"),width:j1,height:j1,center:Z1,thickness:j1.optional().default(1.4),covered_with_solder_mask:k_.boolean().optional().default(!0)}).describe("Defines a PCB panel that can contain multiple boards"),H3=f2.extend({type:k_.literal("pcb_placement_error"),pcb_placement_error_id:K1("pcb_placement_error"),error_type:k_.literal("pcb_placement_error").default("pcb_placement_error"),subcircuit_id:k_.string().optional()}).describe("Defines a placement error on the PCB"),G3=f2.extend({type:k_.literal("pcb_panelization_placement_error"),pcb_panelization_placement_error_id:K1("pcb_panelization_placement_error"),error_type:k_.literal("pcb_panelization_placement_error").default("pcb_panelization_placement_error"),pcb_panel_id:k_.string().optional(),pcb_board_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Defines a panelization placement error on the PCB"),U3=k_.object({type:k_.literal("pcb_trace_hint"),pcb_trace_hint_id:K1("pcb_trace_hint"),pcb_port_id:k_.string(),pcb_component_id:k_.string(),route:k_.array(e3),subcircuit_id:k_.string().optional()}).describe("A hint that can be used during generation of a PCB trace"),Z3=k_.object({type:k_.literal("pcb_silkscreen_line"),pcb_silkscreen_line_id:K1("pcb_silkscreen_line"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),stroke_width:Y1.default("0.1mm"),x1:Y1,y1:Y1,x2:Y1,y2:Y1,layer:p5}).describe("Defines a silkscreen line on the PCB"),q3=k_.object({type:k_.literal("pcb_silkscreen_path"),pcb_silkscreen_path_id:K1("pcb_silkscreen_path"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,route:k_.array(Z1),stroke_width:j1}).describe("Defines a silkscreen path on the PCB"),J3=k_.object({type:k_.literal("pcb_silkscreen_text"),pcb_silkscreen_text_id:K1("pcb_silkscreen_text"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:Y1.default("0.2mm"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:j1,top:j1,bottom:j1,right:j1}).default({left:"0.2mm",top:"0.2mm",bottom:"0.2mm",right:"0.2mm"}).optional(),ccw_rotation:k_.number().optional(),layer:u5,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:Q1.default("center")}).describe("Defines silkscreen text on the PCB"),K3=k_.object({type:k_.literal("pcb_copper_text"),pcb_copper_text_id:K1("pcb_copper_text"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:Y1.default("0.2mm"),pcb_component_id:k_.string(),text:k_.string(),is_knockout:k_.boolean().default(!1).optional(),knockout_padding:k_.object({left:j1,top:j1,bottom:j1,right:j1}).default({left:"0.2mm",top:"0.2mm",bottom:"0.2mm",right:"0.2mm"}).optional(),ccw_rotation:k_.number().optional(),layer:u5,is_mirrored:k_.boolean().default(!1).optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:Q1.default("center")}).describe("Defines copper text on the PCB"),Q3=k_.object({type:k_.literal("pcb_silkscreen_rect"),pcb_silkscreen_rect_id:K1("pcb_silkscreen_rect"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:u5,stroke_width:j1.default("1mm"),corner_radius:j1.optional(),is_filled:k_.boolean().default(!0).optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),ccw_rotation:k_.number().optional()}).describe("Defines a silkscreen rect on the PCB"),t4=k_.object({type:k_.literal("pcb_silkscreen_circle"),pcb_silkscreen_circle_id:K1("pcb_silkscreen_circle"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:j1,layer:p5,stroke_width:j1.default("1mm"),is_filled:k_.boolean().optional()}).describe("Defines a silkscreen circle on the PCB"),e4=k_.object({type:k_.literal("pcb_silkscreen_oval"),pcb_silkscreen_oval_id:K1("pcb_silkscreen_oval"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius_x:Y1,radius_y:Y1,layer:p5,ccw_rotation:G1.optional()}).describe("Defines a silkscreen oval on the PCB"),n4=k_.object({type:k_.literal("pcb_silkscreen_pill"),pcb_silkscreen_pill_id:K1("pcb_silkscreen_pill"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:u5,ccw_rotation:k_.number().optional()}).describe("Defines a silkscreen pill on the PCB"),o4=k_.object({type:k_.literal("pcb_fabrication_note_text"),pcb_fabrication_note_text_id:K1("pcb_fabrication_note_text"),subcircuit_id:k_.string().optional(),pcb_group_id:k_.string().optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:Y1.default("1mm"),pcb_component_id:k_.string(),text:k_.string(),layer:p5,anchor_position:Z1.default({x:0,y:0}),anchor_alignment:k_.enum(["center","top_left","top_right","bottom_left","bottom_right"]).default("center"),color:k_.string().optional()}).describe("Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators"),i4=k_.object({type:k_.literal("pcb_fabrication_note_path"),pcb_fabrication_note_path_id:K1("pcb_fabrication_note_path"),pcb_component_id:k_.string(),subcircuit_id:k_.string().optional(),layer:u5,route:k_.array(Z1),stroke_width:j1,color:k_.string().optional()}).describe("Defines a fabrication path on the PCB for fabricators or assemblers"),r4=k_.object({type:k_.literal("pcb_fabrication_note_rect"),pcb_fabrication_note_rect_id:K1("pcb_fabrication_note_rect"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5,stroke_width:j1.default("0.1mm"),corner_radius:j1.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe("Defines a fabrication note rectangle on the PCB"),s4=k_.object({type:k_.literal("pcb_fabrication_note_dimension"),pcb_fabrication_note_dimension_id:K1("pcb_fabrication_note_dimension"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,from:Z1,to:Z1,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset:j1.optional(),offset_distance:j1.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:j1.default("1mm"),color:k_.string().optional(),arrow_size:j1.default("1mm")}).describe("Defines a measurement annotation within PCB fabrication notes"),a4=k_.object({type:k_.literal("pcb_note_text"),pcb_note_text_id:K1("pcb_note_text"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:Y1.default("1mm"),text:k_.string().optional(),anchor_position:Z1.default({x:0,y:0}),anchor_alignment:k_.enum(["center","top_left","top_right","bottom_left","bottom_right"]).default("center"),layer:p5.default("top"),is_mirrored_from_top_view:k_.boolean().optional(),color:k_.string().optional()}).describe("Defines a documentation note in text on the PCB"),c4=k_.object({type:k_.literal("pcb_note_rect"),pcb_note_rect_id:K1("pcb_note_rect"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5.default("top"),stroke_width:j1.default("0.1mm"),corner_radius:j1.optional(),is_filled:k_.boolean().optional(),has_stroke:k_.boolean().optional(),is_stroke_dashed:k_.boolean().optional(),color:k_.string().optional()}).describe("Defines a rectangular documentation note on the PCB"),l4=k_.object({type:k_.literal("pcb_note_path"),pcb_note_path_id:K1("pcb_note_path"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),route:k_.array(Z1),layer:p5.default("top"),stroke_width:j1.default("0.1mm"),color:k_.string().optional()}).describe("Defines a polyline documentation note on the PCB"),d4=k_.object({type:k_.literal("pcb_note_line"),pcb_note_line_id:K1("pcb_note_line"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),text:k_.string().optional(),x1:Y1,y1:Y1,x2:Y1,y2:Y1,layer:p5.default("top"),stroke_width:Y1.default("0.1mm"),color:k_.string().optional(),is_dashed:k_.boolean().optional()}).describe("Defines a straight documentation note line on the PCB"),h4=k_.object({type:k_.literal("pcb_note_dimension"),pcb_note_dimension_id:K1("pcb_note_dimension"),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),name:k_.string().optional(),from:Z1,to:Z1,text:k_.string().optional(),text_ccw_rotation:k_.number().optional(),offset_distance:j1.optional(),offset_direction:k_.object({x:k_.number(),y:k_.number()}).optional(),font:k_.literal("tscircuit2024").default("tscircuit2024"),font_size:j1.default("1mm"),layer:p5.default("top"),color:k_.string().optional(),arrow_size:j1.default("1mm")}).describe("Defines a measurement annotation within PCB documentation notes"),u4=f2.extend({type:k_.literal("pcb_footprint_overlap_error"),pcb_error_id:K1("pcb_error"),error_type:k_.literal("pcb_footprint_overlap_error").default("pcb_footprint_overlap_error"),pcb_smtpad_ids:k_.array(k_.string()).optional(),pcb_plated_hole_ids:k_.array(k_.string()).optional(),pcb_hole_ids:k_.array(k_.string()).optional(),pcb_keepout_ids:k_.array(k_.string()).optional()}).describe("Error emitted when a pcb footprint overlaps with another element"),p4=f2.extend({type:k_.literal("pcb_courtyard_overlap_error"),pcb_error_id:K1("pcb_error"),error_type:k_.literal("pcb_courtyard_overlap_error").default("pcb_courtyard_overlap_error"),pcb_component_ids:k_.tuple([k_.string(),k_.string()])}).describe("Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another"),m4=k_.object({type:k_.literal("pcb_keepout"),shape:k_.literal("rect"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:Y1,height:Y1,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()}).or(k_.object({type:k_.literal("pcb_keepout"),shape:k_.literal("circle"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:Y1,pcb_keepout_id:k_.string(),layers:k_.array(k_.string()),description:k_.string().optional()})),g4=k_.object({type:k_.literal("pcb_cutout"),pcb_cutout_id:K1("pcb_cutout"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),pcb_board_id:k_.string().optional(),pcb_panel_id:k_.string().optional()}),f4=g4.extend({shape:k_.literal("rect"),center:Z1,width:j1,height:j1,rotation:G1.optional(),corner_radius:j1.optional()}),y4=g4.extend({shape:k_.literal("circle"),center:Z1,radius:j1}),_4=g4.extend({shape:k_.literal("polygon"),points:k_.array(Z1)}),b4=g4.extend({shape:k_.literal("path"),route:k_.array(Z1),slot_width:j1,slot_length:j1.optional(),space_between_slots:j1.optional(),slot_corner_radius:j1.optional()}),x4=k_.discriminatedUnion("shape",[f4,y4,_4,b4]).describe("Defines a cutout on the PCB, removing board material."),v4=f2.extend({type:k_.literal("pcb_missing_footprint_error"),pcb_missing_footprint_error_id:K1("pcb_missing_footprint_error"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal("pcb_missing_footprint_error").default("pcb_missing_footprint_error"),source_component_id:k_.string()}).describe("Defines a missing footprint error on the PCB"),S4=f2.extend({type:k_.literal("external_footprint_load_error"),external_footprint_load_error_id:K1("external_footprint_load_error"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),error_type:k_.literal("external_footprint_load_error").default("external_footprint_load_error")}).describe("Defines an error when an external footprint fails to load"),I4=f2.extend({type:k_.literal("circuit_json_footprint_load_error"),circuit_json_footprint_load_error_id:K1("circuit_json_footprint_load_error"),pcb_component_id:k_.string(),source_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),error_type:k_.literal("circuit_json_footprint_load_error").default("circuit_json_footprint_load_error"),circuit_json:k_.array(k_.any()).optional()}).describe("Defines an error when a circuit JSON footprint fails to load"),C4=k_.object({type:k_.literal("pcb_group"),pcb_group_id:K1("pcb_group"),source_group_id:k_.string(),is_subcircuit:k_.boolean().optional(),subcircuit_id:k_.string().optional(),width:j1.optional(),height:j1.optional(),center:Z1,display_offset_x:k_.string().optional().describe("How to display the x offset for this group, usually corresponding with how the user specified it"),display_offset_y:k_.string().optional().describe("How to display the y offset for this group, usually corresponding with how the user specified it"),outline:k_.array(Z1).optional(),anchor_position:Z1.optional(),anchor_alignment:Q1.default("center"),position_mode:k_.enum(["packed","relative_to_group_anchor","none"]).optional(),positioned_relative_to_pcb_group_id:k_.string().optional(),positioned_relative_to_pcb_board_id:k_.string().optional(),pcb_component_ids:k_.array(k_.string()),child_layout_mode:k_.enum(["packed","none"]).optional(),name:k_.string().optional(),description:k_.string().optional(),layout_mode:k_.string().optional(),autorouter_configuration:k_.object({trace_clearance:j1}).optional(),autorouter_used_string:k_.string().optional()}).describe("Defines a group of components on the PCB"),P4=f2.extend({type:k_.literal("pcb_autorouting_error"),pcb_error_id:K1("pcb_autorouting_error"),error_type:k_.literal("pcb_autorouting_error").default("pcb_autorouting_error"),subcircuit_id:k_.string().optional()}).describe("The autorouting has failed to route a portion of the board"),M4=k_.object({type:k_.literal("pcb_manual_edit_conflict_warning"),pcb_manual_edit_conflict_warning_id:K1("pcb_manual_edit_conflict_warning"),warning_type:k_.literal("pcb_manual_edit_conflict_warning").default("pcb_manual_edit_conflict_warning"),message:k_.string(),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),source_component_id:k_.string()}).describe("Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates"),N4=k_.enum(["x-","x+","y+","y-"]),w4=k_.object({type:k_.literal("pcb_connector_not_in_accessible_orientation_warning"),pcb_connector_not_in_accessible_orientation_warning_id:K1("pcb_connector_not_in_accessible_orientation_warning"),warning_type:k_.literal("pcb_connector_not_in_accessible_orientation_warning").default("pcb_connector_not_in_accessible_orientation_warning"),message:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string().optional(),pcb_board_id:k_.string().optional(),facing_direction:N4,recommended_facing_direction:N4,subcircuit_id:k_.string().optional()}).describe("Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction"),T4=k_.object({type:k_.literal("supplier_footprint_mismatch_warning"),supplier_footprint_mismatch_warning_id:K1("supplier_footprint_mismatch_warning"),warning_type:k_.literal("supplier_footprint_mismatch_warning").default("supplier_footprint_mismatch_warning"),message:k_.string(),source_component_id:k_.string(),pcb_component_id:k_.string().optional(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),supplier_name:y2.optional(),supplier_part_number:k_.string().optional(),supplier_footprint_url:k_.string().optional(),footprint_copper_intersection_over_union:k_.number()}).describe("Warning emitted when a supplier part footprint does not match the expected footprint"),R4=k_.object({type:k_.literal("pcb_breakout_point"),pcb_breakout_point_id:K1("pcb_breakout_point"),pcb_group_id:k_.string(),subcircuit_id:k_.string().optional(),source_trace_id:k_.string().optional(),source_port_id:k_.string().optional(),source_net_id:k_.string().optional(),x:Y1,y:Y1}).describe("Defines a routing target within a pcb_group for a source_trace or source_net"),E4=k_.object({type:k_.literal("pcb_ground_plane"),pcb_ground_plane_id:K1("pcb_ground_plane"),source_pcb_ground_plane_id:k_.string(),source_net_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Defines a ground plane on the PCB"),A4=k_.object({type:k_.literal("pcb_ground_plane_region"),pcb_ground_plane_region_id:K1("pcb_ground_plane_region"),pcb_ground_plane_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:u5,points:k_.array(Z1)}).describe("Defines a polygon region of a ground plane"),O4=k_.object({type:k_.literal("pcb_thermal_spoke"),pcb_thermal_spoke_id:K1("pcb_thermal_spoke"),pcb_ground_plane_id:k_.string(),shape:k_.string(),spoke_count:k_.number(),spoke_thickness:Y1,spoke_inner_diameter:Y1,spoke_outer_diameter:Y1,pcb_plated_hole_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Pattern for connecting a ground plane to a plated hole"),k4=k_.object({type:k_.literal("pcb_copper_pour"),pcb_copper_pour_id:K1("pcb_copper_pour"),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:u5,source_net_id:k_.string().optional(),covered_with_solder_mask:k_.boolean().optional().default(!0)}),L4=k4.extend({shape:k_.literal("rect"),center:Z1,width:j1,height:j1,rotation:G1.optional()}),D4=k4.extend({shape:k_.literal("brep"),brep_shape:Q5}),z4=k4.extend({shape:k_.literal("polygon"),points:k_.array(Z1)}),F4=k_.discriminatedUnion("shape",[L4,D4,z4]).describe("Defines a copper pour on the PCB."),B4=f2.extend({type:k_.literal("pcb_component_outside_board_error"),pcb_component_outside_board_error_id:K1("pcb_component_outside_board_error"),error_type:k_.literal("pcb_component_outside_board_error").default("pcb_component_outside_board_error"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Z1,component_bounds:k_.object({min_x:k_.number(),max_x:k_.number(),min_y:k_.number(),max_y:k_.number()}),subcircuit_id:k_.string().optional(),source_component_id:k_.string().optional()}).describe("Error emitted when a PCB component is placed outside the board boundaries"),j4=f2.extend({type:k_.literal("pcb_component_not_on_board_edge_error"),pcb_component_not_on_board_edge_error_id:K1("pcb_component_not_on_board_edge_error"),error_type:k_.literal("pcb_component_not_on_board_edge_error").default("pcb_component_not_on_board_edge_error"),pcb_component_id:k_.string(),pcb_board_id:k_.string(),component_center:Z1,pad_to_nearest_board_edge_distance:k_.number(),source_component_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when a component that must be placed on the board edge is centered away from the edge"),$4=f2.extend({type:k_.literal("pcb_component_invalid_layer_error"),pcb_component_invalid_layer_error_id:K1("pcb_component_invalid_layer_error"),error_type:k_.literal("pcb_component_invalid_layer_error").default("pcb_component_invalid_layer_error"),pcb_component_id:k_.string().optional(),source_component_id:k_.string(),layer:u5,subcircuit_id:k_.string().optional()}).describe("Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)"),Y4=f2.extend({type:k_.literal("pcb_via_clearance_error"),pcb_error_id:K1("pcb_error"),error_type:k_.literal("pcb_via_clearance_error").default("pcb_via_clearance_error"),pcb_via_ids:k_.array(k_.string()).min(2),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),pcb_center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when vias are closer than the allowed clearance"),X4=f2.extend({type:k_.literal("pcb_via_trace_clearance_error"),pcb_via_trace_clearance_error_id:K1("pcb_via_trace_clearance_error"),error_type:k_.literal("pcb_via_trace_clearance_error").default("pcb_via_trace_clearance_error"),pcb_via_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when a via and trace are closer than the allowed clearance"),V4=f2.extend({type:k_.literal("pcb_pad_pad_clearance_error"),pcb_pad_pad_clearance_error_id:K1("pcb_pad_pad_clearance_error"),error_type:k_.literal("pcb_pad_pad_clearance_error").default("pcb_pad_pad_clearance_error"),pcb_pad_ids:k_.array(k_.string()).min(2),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when pads are closer than the allowed clearance"),W4=f2.extend({type:k_.literal("pcb_pad_trace_clearance_error"),pcb_pad_trace_clearance_error_id:K1("pcb_pad_trace_clearance_error"),error_type:k_.literal("pcb_pad_trace_clearance_error").default("pcb_pad_trace_clearance_error"),pcb_pad_id:k_.string(),pcb_trace_id:k_.string(),minimum_clearance:Y1.optional(),actual_clearance:Y1.optional(),center:k_.object({x:k_.number().optional(),y:k_.number().optional()}).optional(),subcircuit_id:k_.string().optional()}).describe("Error emitted when a pad and trace are closer than allowed clearance"),H4=k_.object({type:k_.literal("pcb_courtyard_rect"),pcb_courtyard_rect_id:K1("pcb_courtyard_rect"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,width:j1,height:j1,layer:p5,ccw_rotation:G1.optional(),color:k_.string().optional()}).describe("Defines a courtyard rectangle on the PCB"),G4=k_.object({type:k_.literal("pcb_courtyard_outline"),pcb_courtyard_outline_id:K1("pcb_courtyard_outline"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,outline:k_.array(Z1).min(2)}).describe("Defines a courtyard outline on the PCB"),U4=k_.object({type:k_.literal("pcb_courtyard_polygon"),pcb_courtyard_polygon_id:K1("pcb_courtyard_polygon"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),layer:p5,points:k_.array(Z1).min(3),color:k_.string().optional()}).describe("Defines a courtyard polygon on the PCB"),Z4=k_.object({type:k_.literal("pcb_courtyard_circle"),pcb_courtyard_circle_id:K1("pcb_courtyard_circle"),pcb_component_id:k_.string(),pcb_group_id:k_.string().optional(),subcircuit_id:k_.string().optional(),center:Z1,radius:j1,layer:p5,color:k_.string().optional()}).describe("Defines a courtyard circle on the PCB"),q4=k_.object({type:k_.literal("cad_component"),cad_component_id:k_.string(),pcb_component_id:k_.string(),source_component_id:k_.string(),position:q1,rotation:q1.optional(),size:q1.optional(),layer:u5.optional(),subcircuit_id:k_.string().optional(),footprinter_string:k_.string().optional(),model_obj_url:k_.string().optional(),model_stl_url:k_.string().optional(),model_3mf_url:k_.string().optional(),model_gltf_url:k_.string().optional(),model_glb_url:k_.string().optional(),model_step_url:k_.string().optional(),model_wrl_url:k_.string().optional(),model_asset:t2.optional(),model_unit_to_mm_scale_factor:k_.number().optional(),model_board_normal_direction:k_.enum(["x+","x-","y+","y-","z+","z-"]).optional().describe('The direction in the model\'s coordinate space that is considered "up" or "coming out of the board surface"'),model_origin_position:q1.optional(),model_origin_alignment:k_.enum(["unknown","center","center_of_component_on_board_surface","bottom_center_of_component"]).optional(),model_object_fit:k_.enum(["contain_within_bounds","fill_bounds"]).optional().default("contain_within_bounds"),model_jscad:k_.any().optional(),show_as_translucent_model:k_.boolean().optional(),anchor_alignment:k_.enum(["center","center_of_component_on_board_surface"]).optional().default("center")}).describe("Defines a component on the PCB"),J4=k_.enum(["sinewave","square","triangle","sawtooth"]),K4=k_.union([k_.string(),k_.number()]).transform(t=>"string"==typeof t?t.endsWith("%")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,"Duty cycle must be non-negative").max(1,"Duty cycle cannot be greater than 100%")),Q4=k_.object({type:k_.literal("simulation_voltage_source"),simulation_voltage_source_id:K1("simulation_voltage_source"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),voltage:B1}).describe("Defines a DC voltage source for simulation"),t6=k_.object({type:k_.literal("simulation_voltage_source"),simulation_voltage_source_id:K1("simulation_voltage_source"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),voltage:B1.optional(),frequency:$1.optional(),peak_to_peak_voltage:B1.optional(),wave_shape:J4.optional(),phase:G1.optional(),duty_cycle:K4.optional()}).describe("Defines an AC voltage source for simulation"),e6=k_.union([Q4,t6]).describe("Defines a voltage source for simulation"),n6=k_.union([k_.string(),k_.number()]).transform(t=>"string"==typeof t?t.endsWith("%")?parseFloat(t.slice(0,-1))/100:parseFloat(t):t).pipe(k_.number().min(0,"Duty cycle must be non-negative").max(1,"Duty cycle cannot be greater than 100%")),o6=k_.object({type:k_.literal("simulation_current_source"),simulation_current_source_id:K1("simulation_current_source"),is_dc_source:k_.literal(!0).optional().default(!0),positive_source_port_id:k_.string().optional(),negative_source_port_id:k_.string().optional(),positive_source_net_id:k_.string().optional(),negative_source_net_id:k_.string().optional(),current:X1}).describe("Defines a DC current source for simulation"),i6=k_.object({type:k_.literal("simulation_current_source"),simulation_current_source_id:K1("simulation_current_source"),is_dc_source:k_.literal(!1),terminal1_source_port_id:k_.string().optional(),terminal2_source_port_id:k_.string().optional(),terminal1_source_net_id:k_.string().optional(),terminal2_source_net_id:k_.string().optional(),current:X1.optional(),frequency:$1.optional(),peak_to_peak_current:X1.optional(),wave_shape:J4.optional(),phase:G1.optional(),duty_cycle:n6.optional()}).describe("Defines an AC current source for simulation"),r6=k_.union([o6,i6]).describe("Defines a current source for simulation"),s6=k_.union([k_.literal("spice_dc_sweep"),k_.literal("spice_dc_operating_point"),k_.literal("spice_transient_analysis"),k_.literal("spice_ac_analysis")]),a6=k_.object({type:k_.literal("simulation_experiment"),simulation_experiment_id:K1("simulation_experiment"),name:k_.string(),experiment_type:s6,time_per_step:V1.optional(),start_time_ms:W1.optional(),end_time_ms:W1.optional()}).describe("Defines a simulation experiment configuration"),c6=k_.object({type:k_.literal("simulation_transient_voltage_graph"),simulation_transient_voltage_graph_id:K1("simulation_transient_voltage_graph"),simulation_experiment_id:k_.string(),timestamps_ms:k_.array(k_.number()).optional(),voltage_levels:k_.array(k_.number()),source_component_id:k_.string().optional(),subcircuit_connectivity_map_key:k_.string().optional(),time_per_step:V1,start_time_ms:W1,end_time_ms:W1,name:k_.string().optional(),color:k_.string().optional()}).describe("Stores voltage measurements over time for a simulation"),l6=k_.object({type:k_.literal("simulation_switch"),simulation_switch_id:K1("simulation_switch"),source_component_id:k_.string().optional(),closes_at:W1.optional(),opens_at:W1.optional(),starts_closed:k_.boolean().optional(),switching_frequency:$1.optional()}).describe("Defines a switch for simulation timing control"),d6=k_.object({type:k_.literal("simulation_voltage_probe"),simulation_voltage_probe_id:K1("simulation_voltage_probe"),source_component_id:k_.string().optional(),name:k_.string().optional(),signal_input_source_port_id:k_.string().optional(),signal_input_source_net_id:k_.string().optional(),reference_input_source_port_id:k_.string().optional(),reference_input_source_net_id:k_.string().optional(),subcircuit_id:k_.string().optional(),color:k_.string().optional()}).describe("Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points.").superRefine((t,e)=>{if(t.reference_input_source_port_id||t.reference_input_source_net_id){const n=!!t.signal_input_source_port_id||!!t.reference_input_source_port_id,o=!!t.signal_input_source_net_id||!!t.reference_input_source_net_id;n&&o?e.addIssue({code:k_.ZodIssueCode.custom,message:"Cannot mix port and net connections in a differential probe."}):n?t.signal_input_source_port_id&&t.reference_input_source_port_id||e.addIssue({code:k_.ZodIssueCode.custom,message:"Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id."}):o&&(t.signal_input_source_net_id&&t.reference_input_source_net_id||e.addIssue({code:k_.ZodIssueCode.custom,message:"Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id."}))}else!!t.signal_input_source_port_id==!!t.signal_input_source_net_id&&e.addIssue({code:k_.ZodIssueCode.custom,message:"A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id."})}),h6=f2.extend({type:k_.literal("simulation_unknown_experiment_error"),simulation_unknown_experiment_error_id:K1("simulation_unknown_experiment_error"),error_type:k_.literal("simulation_unknown_experiment_error").default("simulation_unknown_experiment_error"),simulation_experiment_id:k_.string().optional(),subcircuit_id:k_.string().optional()}).describe("An unknown error occurred during the simulation experiment."),u6=k_.object({type:k_.literal("simulation_op_amp"),simulation_op_amp_id:K1("simulation_op_amp"),source_component_id:k_.string().optional(),inverting_input_source_port_id:k_.string(),non_inverting_input_source_port_id:k_.string(),output_source_port_id:k_.string(),positive_supply_source_port_id:k_.string(),negative_supply_source_port_id:k_.string()}).describe("Defines a simple ideal operational amplifier for simulation"),p6=(k_.union([r5,o5,i5,n5,a5,s5,P2,b2,v2,I2,x2,M2,R2,E2,L2,z2,F2,X2,B2,j2,$2,Y2,O2,A2,d5,m5,c5,V2,G2,U2,q2,J2,g5,f5,y5,_5,b5,t5,l5,o3,d3,v4,S4,I4,M4,w4,T4,y3,m4,_3,Y3,A3,D3,z3,X3,P3,E3,V3,W3,C4,U3,Z3,q3,J3,n4,K3,Q3,t4,e4,F3,B3,H3,G3,j3,$3,Y4,X4,V4,W4,i4,o4,r4,s4,a4,c4,l4,d4,h4,P4,u4,p4,R4,x4,E4,A4,O4,F4,B4,j4,$4,H4,G4,U4,Z4,x5,L5,T5,R5,E5,A5,M5,w5,D5,O5,v5,F5,B5,z5,V5,W5,H5,G5,q5,U5,Z5,q4,e6,r6,a6,c6,l6,d6,h6,u6]),[0,1,-1,2,-2,3,-3,4]),m6=(p6.flatMap(t=>p6.map(e=>[t,e])).sort(([t,e],[n,o])=>Math.abs(t)+Math.abs(e)-Math.abs(n)-Math.abs(o)).length,[.2,.4,.8,1.2].flatMap(t=>[.2,.3,.45,.6].flatMap(e=>[-1,1].map(n=>({halfSpan:t,offset:e,directionSign:n})))).flatMap(t=>[0,1].map(e=>({kind:"segment",routeSide:e,...t}))));[1,-1].flatMap(t=>[1,-1].flatMap(e=>[!1,!0].flatMap(n=>[0,1].map(o=>({routeSide:o,normalDirectionSign:t,tangentDirectionSign:e,reverseEndpointOffsets:n}))))),[0,1].map(t=>({kind:"displacementChain",routeSide:t})),[-1,1].flatMap(t=>[0,1].map(e=>({kind:"segment",routeSide:e,halfSpan:.4,offset:1.2,directionSign:t}))),[-1,1].flatMap(t=>[0,1].map(e=>({kind:"span",routeSide:e,spanExpansion:3,offset:1.8,directionSign:t}))),[{dx:-2.4,dy:-.4},{dx:-2.4,dy:.4},{dx:2.4,dy:-.4},{dx:2.4,dy:.4},{dx:-.4,dy:-2.4},{dx:-.4,dy:2.4},{dx:.4,dy:-2.4},{dx:.4,dy:2.4}].flatMap(t=>[0,1].map(e=>({kind:"waypoint",routeSide:e,spanExpansion:2,...t}))),[{dx:-.17,dy:0},{dx:.17,dy:0},{dx:0,dy:-.17},{dx:0,dy:.17}].flatMap(t=>[0,1].map(e=>({kind:"waypoint",routeSide:e,spanExpansion:0,...t})));var g6=1e-8,f6=(t,e,n=0)=>t.x>=e.minX+n-g6&&t.x<=e.maxX-n+g6&&t.y>=e.minY+n-g6&&t.y<=e.maxY-n+g6,y6=(t,e,n)=>{let o=0,i=1;for(const[r,s,a,c]of[[t.x,e.x-t.x,n.minX,n.maxX],[t.y,e.y-t.y,n.minY,n.maxY]]){if(void 0===r||void 0===s||void 0===a||void 0===c)throw new Error("Invalid segment clipping axis");if(Math.abs(s)<=g6){if(r<a-g6||r>c+g6)return;continue}const t=(a-r)/s,e=(c-r)/s;if(o=Math.max(o,Math.min(t,e)),i=Math.min(i,Math.max(t,e)),i<o-g6)return}return[Math.max(0,o),Math.min(1,i)]},_6=(t,e,n)=>{if(n<=g6)return structuredClone(t);if(n>=.99999999)return structuredClone(e);const o={...structuredClone(t),x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n};return delete o.pcb_port_id,o},b6=(t,e)=>Math.abs(t.x-e.x)<=g6&&Math.abs(t.y-e.y)<=g6&&t.z===e.z,x6=t=>Array.isArray(t)?`[${t.map(x6).join(",")}]`:null!==t&&"object"==typeof t?`{${Object.keys(t).filter(e=>void 0!==t[e]).sort().map(e=>`${JSON.stringify(e)}:${x6(t[e])}`).join(",")}}`:JSON.stringify(t)??"undefined",v6=(t,e,n)=>{if(1===t.route.length)return structuredClone(t.route);const o=e=>{const n=Math.min(Math.floor(e),t.route.length-2);return _6(t.route[n],t.route[n+1],e-n)},i=[o(e)];for(let o=Math.floor(e)+1;o<n-g6;o+=1)i.push(structuredClone(t.route[o]));return n>e+g6&&i.push(o(n)),i},S6=(t,e,n)=>{const o=v6(t,e,n),i=Object.fromEntries(Object.entries(t).filter(([t])=>"route"!==t&&"vias"!==t)),r=t.vias.filter(t=>o.some(e=>Math.hypot(e.x-t.x,e.y-t.y)<=g6));return x6({metadata:i,points:o,vias:r})},I6=(t,e)=>{const n=t.__zLayers;if(n)return new Set(n);if(t.zLayers)return new Set(t.zLayers);const o=new Set;for(const n of t.layers){const t="top"===n?0:"bottom"===n?e-1:/^inner\d+$/.test(n)?Number(n.slice(5)):-1;if(t<0||t>=e)throw new Error(`repair04 obstacle has an unknown layer: ${n}`);o.add(t)}return o},C6=({srj:t,routes:e,traceClearance:n=.1,viaClearance:o=.1})=>{let i;const r=new Map,s=[];let a=!1;return c=>{const l=i??=((t,e)=>{const n=new Map,o=t=>{const e=n.get(t);if(void 0===e)return n.set(t,t),t;if(e===t)return t;const i=o(e);return n.set(t,i),i},i=t=>{const e=t.filter(t=>"string"==typeof t&&t.length>0);if(0===e.length)return;const i=o(e[0]);for(const t of e)n.set(o(t),i)};for(const e of t.connections){const t=e;i([t.name,t.rootConnectionName,t.netConnectionName,t.__netConnectionName,...t.mergedConnectionNames??[],...t.__rootConnectionNames??[],...t.pointsToConnect.flatMap(t=>[t.pointId,t.pcb_port_id])])}for(const e of t.obstacles)i(e.connectedTo);for(const t of e)i([t.connectionName,t.rootConnectionName]);for(const t of n.keys())n.set(t,o(t));return n})(t,e),d=new Map,h=a?s:function*(e){for(let i=0;i<t.obstacles.length;i++){if(r.has(i)){const t=r.get(i);t&&(yield t);continue}const a=t.obstacles[i],c=a.connectedTo.some(t=>/^(pcb_smtpad_|pcb_plated_hole_|pcb_port_)/.test(t)),l=Math.abs((a.ccwRotationDegrees??0)%180)>1e-8,d="rect"===a.type&&a.layers.length>1&&Math.abs(a.width-a.height)<.001;if(c&&!l&&!d){r.set(i,null);continue}if(![a.center.x,a.center.y,a.width,a.height,a.ccwRotationDegrees??0].every(Number.isFinite)||a.width<0||a.height<0)throw new Error("repair04 fixed obstacle geometry must be finite and nonnegative");const h=I6(a,t.layerCount),u=new Set(a.connectedTo.map(t=>e.get(t)??t)),p={minX:-a.width/2,maxX:a.width/2,minY:-a.height/2,maxY:a.height/2},m=(a.ccwRotationDegrees??0)*Math.PI/180,g=Math.cos(m),f=Math.sin(m),y=Math.hypot(a.width,a.height)/2,_=t=>{const e=t.x-a.center.x,n=t.y-a.center.y;return{x:e*g+n*f,y:-e*f+n*g}},b=(t,e,n)=>Math.max(t.x,e.x)+n<a.center.x-y||Math.min(t.x,e.x)-n>a.center.x+y||Math.max(t.y,e.y)+n<a.center.y-y||Math.min(t.y,e.y)-n>a.center.y+y,x=!0===a.obstacleId?.startsWith("repair04_board_edge_"),v=x?0:Math.max(n,t.defaultObstacleMargin??0,t.minTraceToPadEdgeClearance??0),S=x?0:Math.max(o,t.defaultObstacleMargin??0,t.minViaEdgeToPadEdgeClearance??0),I={obstacleIndex:i,obstacle:a,zLayers:h,obstacleNets:u,obstacleBounds:p,toLocal:_,separated:b,wireGap:v,viaGap:S};r.set(i,I),s.push(I),yield I}a=!0}(l);for(const{obstacleIndex:t,obstacle:e,zLayers:n,obstacleNets:o,obstacleBounds:i,toLocal:r,separated:s,wireGap:a,viaGap:u}of h)for(let h=0;h<c.length;h+=1){const p=c[h];if(!(p.route.length<2)&&![p.connectionName,p.rootConnectionName].some(t=>void 0!==t&&o.has(l.get(t)??t)))for(let o=1;o<p.route.length;o+=1){const c=p.route[o-1],l=p.route[o];if("through_obstacle"===c.toNextSegmentType)continue;if(c.z!==l.z){if(!Array.from(n).some(t=>t>=Math.min(c.z,l.z)&&t<=Math.max(c.z,l.z)))continue;if(Math.abs(c.x-l.x)>1e-8||Math.abs(c.y-l.y)>1e-8)throw new Error("repair04 found a non-colocated via transition: "+JSON.stringify({route:p,from:c,to:l}));if(s(c,c,p.viaDiameter/2+u+1e-8))continue;const e=r(c),o=ke(e,e,i),a=p.viaDiameter/2+u-o;if(a<=1e-8)continue;const m=`fixed-obstacle:${h}:${t}:via`;(d.get(m)?.severity??-1/0)<a&&d.set(m,{key:m,center:{x:c.x,y:c.y},routeIndex:h,obstacleIndex:t,kind:"via",severity:a});continue}if(!n.has(c.z))continue;const m=Math.max(c.traceThickness??p.traceThickness,l.traceThickness??p.traceThickness)/2;if(s(c,l,m+a+1e-8))continue;const g=m+a-ke(r(c),r(l),i);if(g<=1e-8)continue;const f=`fixed-obstacle:${h}:${t}:wire`;(d.get(f)?.severity??-1/0)<g&&d.set(f,{key:f,center:ze(e.center,c,l),routeIndex:h,obstacleIndex:t,kind:"wire",severity:g})}}return Array.from(d.values())}},P6=t=>C6(t)(t.routes),M6=(t,e)=>{const n=[];for(let o=1;o<t.route.length;o++){const i=t.route[o-1],r=t.route[o];if(i.z===r.z||"through_obstacle"===i.toNextSegmentType)continue;if(i.x!==r.x||i.y!==r.y||![i.x,i.y,i.z,r.z,t.viaDiameter].every(Number.isFinite)||!Number.isInteger(i.z)||!Number.isInteger(r.z)||Math.min(i.z,r.z)<0||Math.max(i.z,r.z)>=e||t.viaDiameter<=0)throw new Error("repair04 new-via guard requires valid colocated vias");const s=o-1,a=[i.z,r.z];let c=Math.min(i.z,r.z),l=Math.max(i.z,r.z);for(;o+1<t.route.length&&"through_obstacle"!==t.route[o].toNextSegmentType;){const n=t.route[o+1];if(n.x!==r.x||n.y!==r.y)break;if(!Number.isInteger(n.z)||n.z<0||n.z>=e)throw new Error("repair04 new-via guard found an invalid layer span");n.z!==a.at(-1)&&a.push(n.z),c=Math.min(c,n.z),l=Math.max(l,n.z),o++}n.push({pointIndices:Array.from({length:o-s+1},(t,e)=>s+e),layerSequence:a,x:r.x,y:r.y,minZ:c,maxZ:l,diameter:t.viaDiameter,identity:JSON.stringify([r.x,r.y,c,l,t.viaDiameter])})}return n},N6=({srj:t,viaClearance:e=.1})=>{const n=new Map,o=new Map,i=[e,t.defaultObstacleMargin??0,t.minViaEdgeToPadEdgeClearance??0],r=Math.max(...i),s=e=>{const i=o.get(e.identity);if(i)return i;const s=[];for(let o=0;o<t.obstacles.length;o++){const i=t.obstacles[o];let a=n.get(o);if(!a){const e=i.__zLayers??i.zLayers??i.layers.map(e=>"top"===e?0:"bottom"===e?t.layerCount-1:/^inner\d+$/.test(e)?Number(e.slice(5)):-1);if(e.some(e=>!Number.isInteger(e)||e<0||e>=t.layerCount))throw new Error("repair04 new-via guard found an unknown obstacle layer");a={zs:e},n.set(o,a)}if(!a.zs.some(t=>t>=e.minZ&&t<=e.maxZ))continue;if(!a.geometry){if(![i.center.x,i.center.y,i.width,i.height,i.ccwRotationDegrees??0].every(Number.isFinite)||i.width<0||i.height<0)throw new Error("repair04 new-via guard found invalid obstacle geometry");const t=(i.ccwRotationDegrees??0)*Math.PI/180;a.geometry={x:i.center.x,y:i.center.y,cosine:Math.cos(t),sine:Math.sin(t),extent:Math.hypot(i.width,i.height)/2,bounds:{minX:-i.width/2,maxX:i.width/2,minY:-i.height/2,maxY:i.height/2}}}const c=a.geometry,l=c.extent+e.diameter/2+r+1e-8;if(Math.abs(e.x-c.x)>l||Math.abs(e.y-c.y)>l)continue;const d=e.x-c.x,h=e.y-c.y,u={x:d*c.cosine+h*c.sine,y:-d*c.sine+h*c.cosine},p=ke(u,u,c.bounds),m=e.diameter/2+r-p;m<=1e-8||s.push({obstacleIndex:o,severity:m})}return o.set(e.identity,s),s};return({previousRoutes:e,routes:n,includeExistingVias:o=[]})=>{if(e.length!==n.length)throw new Error("repair04 new-via guard requires matching route ordering");if(i.some(t=>!Number.isFinite(t)||t<0))throw new Error("repair04 new-via guard requires nonnegative finite margins");const r=[];for(let i=0;i<n.length;i++){const a=n[i],c=e[i],l=new Set(a.connectionName===c.connectionName&&a.rootConnectionName===c.rootConnectionName?M6(c,t.layerCount).map(t=>t.identity):[]),d=M6(a,t.layerCount);for(let t=0;t<d.length;t++){const e=d[t];if(!l.has(e.identity)||o.some(e=>e.routeIndex===i&&e.viaIndex===t))for(const n of s(e))r.push({key:`new-via-pad:${i}:${n.obstacleIndex}:${t}`,routeIndex:i,obstacleIndex:n.obstacleIndex,center:{x:e.x,y:e.y},kind:"via",severity:n.severity})}}return r}},w6=t=>N6(t)(t);function T6(t,e){return t.x>e.minX+4e-8&&t.x<e.maxX-4e-8&&t.y>e.minY+4e-8&&t.y<e.maxY-4e-8}function R6(t){const e=[];for(let n=1;n<t.route.length;n++){const o=t.route[n-1],i=t.route[n];if(o.z!==i.z&&"through_obstacle"!==o.toNextSegmentType){if(o.x!==i.x||o.y!==i.y)throw new Error("repair04: a layer transition must have coincident endpoints");e.some(t=>t.x===i.x&&t.y===i.y)||e.push({x:i.x,y:i.y})}}return{...t,vias:e}}function E6(t){const e=[];for(let n=1;n<t.route.length;n++){const o=t.route[n-1],i=t.route[n];o.z!==i.z&&"through_obstacle"!==o.toNextSegmentType&&e.push([o.x,o.y,o.z,i.z])}return JSON.stringify([t.viaDiameter,e])}var A6=class extends kt{input;mutableBounds;engine;fixedTraces;routes;score=null;candidates=null;bestAdjustment=null;lockedPoints;evaluated=0;accepted=0;maxCandidates;candidateAttempts=0;pathSearchNodes=0;pathSearchCalls=0;viaBlockerPathSearchCalls=0;coupledPathSearchCalls=0;threeRoutePathSearchCalls=0;threeRoutePathSearchNodes=0;candidateScores=new Map;routeCache=new WeakMap;fixedObstacleNetContext;fixedObstacleEvaluator;viaPadEvaluator;viaGeometryCache=new WeakMap;constructor(t){if(super(),!Number.isFinite(t.boundaryMargin)||t.boundaryMargin<=0)throw new Error("repair04: boundaryMargin must be positive and finite");const e=t.bounds;if(![e.minX,e.maxX,e.minY,e.maxY].every(Number.isFinite)||e.maxX-e.minX<10-1e-8||e.maxY-e.minY<10-1e-8)throw new Error("repair04: bounds must be finite and at least 10 × 10 mm");if(this.input=structuredClone(t),this.viaPadEvaluator=(({srj:t,viaClearance:e})=>N6({srj:{layerCount:t.layerCount,obstacles:structuredClone(t.obstacles),defaultObstacleMargin:t.defaultObstacleMargin,minViaEdgeToPadEdgeClearance:t.minViaEdgeToPadEdgeClearance},viaClearance:e}))({srj:this.input.srj,viaClearance:this.input.viaClearance}),this.routes=structuredClone(t.routes),this.fixedObstacleNetContext=this.input.routes.map(t=>({...t,route:[]})),this.fixedObstacleEvaluator=(t=>C6({...t,srj:structuredClone(t.srj),routes:t.routes.map(t=>({...t,route:[]}))}))({srj:this.input.srj,routes:this.fixedObstacleNetContext,traceClearance:this.input.traceClearance,viaClearance:this.input.viaClearance}),this.fixedTraces=(t.srj.traces??[]).map(e=>m1(e,t.srj.minTraceWidth)),this.mutableBounds={minX:e.minX+t.boundaryMargin,minY:e.minY+t.boundaryMargin,maxX:e.maxX-t.boundaryMargin,maxY:e.maxY-t.boundaryMargin},this.mutableBounds.minX>=this.mutableBounds.maxX||this.mutableBounds.minY>=this.mutableBounds.maxY)throw new Error("repair04: boundary collar leaves no mutable area");if(t.lockedPointIndices.length!==t.routes.length)throw new Error("repair04: every route requires a lock mask");this.lockedPoints=this.routes.map((e,n)=>{if(t.lockedPointIndices[n].length!==e.route.length)throw new Error("repair04: lock mask length must match its route");for(let t=1;t<e.route.length;t++){const n=y6(e.route[t-1],e.route[t],this.mutableBounds);if(n?.some(t=>t>1e-8&&t<1-1e-8))throw new Error("repair04: boundary crossings require fixed cut points; use extractRepairRegion")}return e.route.filter((o,i)=>t.lockedPointIndices[n][i]||0===i||i===e.route.length-1||o.pcb_port_id||o.insideJumperPad||o.toNextSegmentType||!T6(o,this.mutableBounds))});for(const e of t.movableVias??[]){const n=this.routes[e.routeIndex],o=n&&M6(n,t.srj.layerCount)[e.viaIndex];if(!o||o.pointIndices.some(t=>this.isLocked(e.routeIndex,n.route[t])))throw new Error("repair04: movable via must identify an unlocked existing via")}for(const e of["maxCandidateAttempts","maxPathSearchNodes"]){const n=t[e];if(void 0!==n&&(!Number.isSafeInteger(n)||n<1))throw new Error(`repair04: ${e} must be a positive safe integer`)}if(this.maxCandidates=t.maxCandidates??8e3,!Number.isInteger(this.maxCandidates)||this.maxCandidates<1)throw new Error("repair04: maxCandidates must be a positive integer");this.MAX_ITERATIONS=2*this.maxCandidates+4,this.engine=new R1(this.input.srj,{cacheStaticObstacleNetMembership:!0,cacheImmutableTraceGeometry:!0,useTransientDynamicQueryMarkers:!0,useConservativeRectObstaclePrecheck:!0,traceClearance:t.traceClearance??.1,viaClearance:t.viaClearance??.1,includeTraceViaOwnerMetadata:!0})}getWorkLimitReason(){return void 0!==this.input.maxCandidateAttempts&&this.candidateAttempts>=this.input.maxCandidateAttempts?"candidate-attempt-limit":void 0!==this.input.maxPathSearchNodes&&this.pathSearchNodes>=this.input.maxPathSearchNodes?"path-search-node-limit":null}updateWorkStats(t){void 0===this.input.maxCandidateAttempts&&void 0===this.input.maxPathSearchNodes||(this.stats={...this.stats,candidateAttempts:this.candidateAttempts,pathSearchNodes:this.pathSearchNodes,pathSearchCalls:this.pathSearchCalls,...void 0===t?{}:{completionReason:t}})}finishSearch(t){this.bestAdjustment&&(this.routes=this.bestAdjustment.routes,this.candidateScores.clear(),this.score=this.bestAdjustment.score,this.accepted++,this.bestAdjustment=null,this.stats={...this.stats,finalErrorCount:this.score.count,accepted:this.accepted}),this.updateWorkStats(t),this.solved=!0}getRouteCache(t,e){let n=this.routeCache.get(e);n||(n=new Map,this.routeCache.set(e,n));let o=n.get(t);return o||(o={},n.set(t,o)),o}getViaGeometry(t){let e=this.viaGeometryCache.get(t);return e||(e=M6(t,this.input.srj.layerCount),this.viaGeometryCache.set(t,e)),e}getViaPadViolations(t,e){return 0===t.length?this.viaPadEvaluator({previousRoutes:[],routes:[]}):t.flatMap((t,n)=>{const o=this.getRouteCache(n,t),i=e?"scoredViaViolations":"newViaViolations";if(!o[i]){const r=e?!0!==this.input.allowLayerChanges||this.input.movableVias?.length?(this.input.movableVias??[]).filter(t=>t.routeIndex===n).map(t=>({routeIndex:0,viaIndex:t.viaIndex})):this.getViaGeometry(t).flatMap((e,o)=>e.pointIndices.every(e=>!this.isLocked(n,t.route[e]))?[{routeIndex:0,viaIndex:o}]:[]):[];o[i]=this.viaPadEvaluator({previousRoutes:[e?t:this.input.routes[n]],routes:[t],includeExistingVias:r}).map(t=>({...t,routeIndex:n,key:t.key.replace("new-via-pad:0:",`new-via-pad:${n}:`)}))}return o[i]})}getFixedViolations(t){if(0===t.length)return this.fixedObstacleEvaluator(t);const e=t.flatMap((t,e)=>void 0===this.getRouteCache(e,t).fixedViolations?[e]:[]);if(e.length){const n=this.fixedObstacleNetContext.slice();for(const o of e)n[o]=t[o];const o=this.fixedObstacleEvaluator(n);for(const n of e)this.getRouteCache(n,t[n]).fixedViolations=[];for(const e of o)this.getRouteCache(e.routeIndex,t[e.routeIndex]).fixedViolations.push(e)}return t.flatMap((t,e)=>this.getRouteCache(e,t).fixedViolations).sort((t,e)=>t.obstacleIndex-e.obstacleIndex||t.routeIndex-e.routeIndex)}evaluate(t){const{errors:e}=this.engine.evaluate([...this.fixedTraces,...t.map((t,e)=>{const n=this.getRouteCache(e,t);return n.trace||(n.trace=function(t,e){const n=t=>0===t?"top":t===e-1?"bottom":`inner${t}`;return t.map((t,e)=>{const o=[];for(let e=0;e<t.route.length;e++){const i=t.route[e],r=t.route[e-1];r&&"through_obstacle"!==r.toNextSegmentType&&r.z!==i.z&&r.x===i.x&&r.y===i.y&&o.push({route_type:"via",x:i.x,y:i.y,from_layer:n(r.z),to_layer:n(i.z),via_diameter:t.viaDiameter});const s=i.traceThickness??t.traceThickness;o.push({route_type:"wire",x:i.x,y:i.y,layer:n(i.z),width:s,...0===e&&i.pcb_port_id?{start_pcb_port_id:i.pcb_port_id}:{},...e===t.route.length-1&&i.pcb_port_id?{end_pcb_port_id:i.pcb_port_id}:{}})}return{type:"pcb_trace",pcb_trace_id:`repair04_${e}`,connection_name:t.rootConnectionName??t.connectionName,route:o}})}([t],this.input.srj.layerCount)[0],n.trace.pcb_trace_id=`repair04_${e}`),n.trace})]),n=new Map;for(const o of this.getFixedViolations(t))n.set(o.key,o.severity),e.push({type:"pcb_trace_error",error_type:"pcb_trace_error",message:`repair04 fixed obstacle clearance: ${o.key}`,center:o.center,minimum_clearance:o.severity,actual_clearance:0,pcb_trace_id:`repair04_${o.routeIndex}`,pcb_trace_error_id:o.key});for(const n of this.getViaPadViolations(t,!0))e.push({type:"pcb_trace_error",error_type:"pcb_trace_error",message:`repair04 selected existing via pad clearance: ${n.key}`,center:n.center,minimum_clearance:n.severity,actual_clearance:0,pcb_trace_id:`repair04_${n.routeIndex}`,pcb_trace_error_id:n.key});let o=0;for(const t of e){const e=/gap: (-?[\d.]+)/.exec(t.message),n="number"==typeof t.actual_clearance?t.actual_clearance:e?Number(e[1]):null,i="number"==typeof t.minimum_clearance?t.minimum_clearance:.1;o+=null!==n?Math.max(0,i-n):1}return{count:e.length,severity:o,errors:e,fixedViolations:n}}isLocked(t,e){return!T6(e,this.mutableBounds)||this.lockedPoints[t].some(t=>t.x===e.x&&t.y===e.y)}*generateTaperedSegmentCandidates(t){const e=new Set;for(const{ri:n,pi:o}of t){if(!this.score.errors.some(t=>t.pcb_trace_id===`repair04_${n}`))continue;const t=this.routes[n];for(const[i,r]of[[o-2,o+1],[o-2,o],[o-1,o+1],[o-1,o]]){if(e.size>=8)return;if(i<=0||r>=t.route.length-1)continue;const o=`${n}:${i}:${r}`;if(e.has(o))continue;const s=t.route.slice(i,r+1),a=s[0].z;if(!T6(t.route[i-1],this.mutableBounds)||!T6(t.route[r+1],this.mutableBounds)||t.route[i-1].z!==a||t.route[r+1].z!==a||s.some(e=>e.z!==a||this.isLocked(n,e)||Boolean(e.portPointId)||t.vias.some(t=>t.x===e.x&&t.y===e.y)))continue;if(!(new Set(s.map(e=>e.traceThickness??t.traceThickness)).size<2)){e.add(o);for(const e of[.1,.05])for(let o=0;o<8;o++){const a=e*Math.cos(o*Math.PI/4),c=e*Math.sin(o*Math.PI/4),l=s.map(t=>({...t,x:t.x+a,y:t.y+c}));l.some(t=>!T6(t,this.mutableBounds))||(yield{routeIndex:n,route:{...t,route:[...t.route.slice(0,i),...l,...t.route.slice(r+1)]}})}}}}}*generateCrossingPairCandidates(){if(this.coupledPathSearchCalls>=4||this.getWorkLimitReason())return;const t=new Set,e=this.score.errors.filter(t=>"pcb_trace_error"===t.type&&"number"==typeof t.actual_clearance&&t.actual_clearance<0&&void 0!==t.center);for(const n of e){const e=n.center,o=[];for(let t=0;t<this.routes.length;t++){const n=this.routes[t];if(!n.jumpers?.length)for(let i=1;i<n.route.length;i++){const r=n.route[i-1],s=n.route[i],a=s.x-r.x,c=s.y-r.y,l=a*a+c*c;if(r.z!==s.z||l<1e-12)continue;const d=((e.x-r.x)*a+(e.y-r.y)*c)/l;d<0||d>1||Math.hypot(e.x-r.x-d*a,e.y-r.y-d*c)<1e-6&&o.push({ri:t,pi:i,a:r,b:s})}}for(let e=0;e<o.length;e++)for(let i=e+1;i<o.length;i++){let r=o[e],s=o[i];if(r.ri===s.ri||r.a.z!==s.a.z)continue;const a=n.pcb_trace_error_id;if(a!==`overlap_repair04_${r.ri}_repair04_${s.ri}`&&a!==`overlap_repair04_${s.ri}_repair04_${r.ri}`)continue;0===this.routes[r.ri].vias.length&&([r,s]=[s,r]);const c=this.routes[r.ri],l=this.routes[s.ri];if(0===c.vias.length||0!==l.vias.length)continue;const d=`${r.ri}:${s.ri}`;if(t.has(d))continue;t.add(d);let h=s.pi-1,u=s.pi;for(;h>0&&!this.isLocked(s.ri,l.route[h]);)h--;for(;u<l.route.length-1&&!this.isLocked(s.ri,l.route[u]);)u++;if(u-h>64||u-h<2||!T6(l.route[h],this.mutableBounds)||!T6(l.route[u],this.mutableBounds))continue;const p=l.route[h].traceThickness??l.traceThickness;if(l.route.slice(h,u+1).some(t=>t.z!==s.a.z||t.toNextSegmentType||t.insideJumperPad||(t.traceThickness??l.traceThickness)!==p))continue;const m=this.getViaGeometry(c),g=m.map((t,e)=>({via:t,viaIndex:e,distance:Math.min(...t.pointIndices.map(t=>Math.abs(t-r.pi)))})).sort((t,e)=>t.distance-e.distance)[0];if(!g||g.via.pointIndices.some(t=>this.isLocked(r.ri,c.route[t]))||this.input.movableVias?.length&&!this.input.movableVias.some(t=>t.routeIndex===r.ri&&t.viaIndex===g.viaIndex))continue;const f=Math.max(...g.via.pointIndices);let y=r.pi-1;for(;y>0&&!this.isLocked(r.ri,c.route[y]);)y--;if(y>=Math.min(...g.via.pointIndices))continue;const _=s.b.x-s.a.x,b=s.b.y-s.a.y,x=Math.abs(b)>=Math.abs(_)?{x:1,y:0}:{x:0,y:1},v=2*(this.input.traceClearance??.1)+p;for(const t of[-1,1])for(const e of[2,1]){if(this.coupledPathSearchCalls>=4||this.getWorkLimitReason())return;const n=f+e;if(n>=c.route.length)continue;if(c.route.slice(y+1,n).some(t=>this.isLocked(r.ri,t)))continue;if(!T6(c.route[y],this.mutableBounds)||!T6(c.route[n],this.mutableBounds))continue;const o=c.route[y].traceThickness??c.traceThickness;if(c.route.slice(y,n+1).some(t=>t.toNextSegmentType||t.insideJumperPad||(t.traceThickness??c.traceThickness)!==o))continue;const i={...l,route:l.route.map((e,n)=>n>h&&n<u?{...e,x:e.x+t*x.x*v,y:e.y+t*x.y*v}:e)};if(i.route.some((t,e)=>e>h&&e<u&&!T6(t,this.mutableBounds)))continue;const a=this.routes.slice();a[s.ri]=i;const d={nodesPopped:0,completionReason:"no-path"},p=Math.min(3e4,void 0===this.input.maxPathSearchNodes?3e4:this.input.maxPathSearchNodes-this.pathSearchNodes);if(p<1)return;const g=g1({srj:this.input.srj,routes:a,routeIndex:r.ri,start:c.route[y],end:c.route[n],bounds:this.mutableBounds,traceThickness:o,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,gridSize:o<=.1?o/2:.1,allowLayerChanges:!0,maxNodes:p,stats:d});if(this.coupledPathSearchCalls++,this.pathSearchCalls++,this.pathSearchNodes+=d.nodesPopped,this.updateWorkStats(),!g)continue;const _=R6({...c,route:[...c.route.slice(0,y),...g,...c.route.slice(n+1)]}),b=this.getViaGeometry(_);b.length!==m.length||b.some((t,e)=>t.diameter!==m[e].diameter||JSON.stringify(t.layerSequence)!==JSON.stringify(m[e].layerSequence))||(yield{routeIndex:r.ri,route:_,additionalRoutes:[{routeIndex:s.ri,route:i}]})}}}}*generateClearanceCandidates(t,e){const n=new Set;for(const{ri:o,pi:i}of t){if(n.size>=12)break;const t=this.routes[o],r=n=>{const i=t.route[n];return this.isLocked(o,i)||!e&&(n>0&&t.route[n-1].z!==i.z||n+1<t.route.length&&t.route[n+1].z!==i.z)};let s=i-1,a=i;for(;s>0&&!r(s);)s--;for(;a<t.route.length-1&&!r(a);)a++;const c=`${o}:${s}:${a}`;if(n.has(c))continue;n.add(c);const l=t.route[s],d=t.route[a];if(l.x===d.x&&l.y===d.y)continue;const h=t=>t.x>=this.mutableBounds.minX-g6&&t.x<=this.mutableBounds.maxX+g6&&t.y>=this.mutableBounds.minY-g6&&t.y<=this.mutableBounds.maxY+g6;if(!h(l)||!h(d))continue;const u=new Set(t.route.slice(s,a+1).map(e=>e.traceThickness??t.traceThickness));if(1!==u.size)continue;const p=[...u][0];if("path-search-node-limit"===this.getWorkLimitReason())return;const m={nodesPopped:0,completionReason:"no-path"},g=g1({maxNodes:void 0===this.input.maxPathSearchNodes?void 0:Math.min(3e4,this.input.maxPathSearchNodes-this.pathSearchNodes),stats:m,allowLayerChanges:e,srj:this.input.srj,routes:this.routes,routeIndex:o,start:l,end:d,bounds:this.mutableBounds,traceThickness:p,gridSize:p<=.1?p/2:.1,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1});this.pathSearchCalls++,this.pathSearchNodes+=m.nodesPopped,this.updateWorkStats(),g&&(yield{routeIndex:o,route:R6({...t,route:[...t.route.slice(0,s),...g,...t.route.slice(a+1)]})})}}preservesViaPermissions(t,e){const n=this.input.routes[t],o=this.getViaGeometry(n),i=this.getViaGeometry(e);return e.connectionName===n.connectionName&&e.rootConnectionName===n.rootConnectionName&&e.viaDiameter===n.viaDiameter&&o.length===i.length&&o.every((e,n)=>{const o=i[n];if(JSON.stringify(e.layerSequence)!==JSON.stringify(o.layerSequence)||e.diameter!==o.diameter)return!1;const r=this.input.movableVias?.some(e=>e.routeIndex===t&&e.viaIndex===n);return!0===r||e.x===o.x&&e.y===o.y})}getIndexedViaIds(t,e,n){const o=new Set;if(1!==this.getViaGeometry(e).filter(t=>t.x===n.x&&t.y===n.y&&t.identity===n.identity).length)return o;const i=t=>0===t?"top":t===this.input.srj.layerCount-1?"bottom":`inner${t}`,r=new Set;for(let t=1;t<n.layerSequence.length;t++)r.add(`${n.x},${n.y},${i(n.layerSequence[t-1])},${i(n.layerSequence[t])}`);const s=this.routes.map((n,o)=>{const i=this.getRouteCache(o,o===t?e:n).trace;if(!i)throw new Error("repair04: indexed via mapping requires an evaluated route");return i}),a=new Set;for(const e of[...this.fixedTraces,...s])for(const n of e.route){if("via"!==n.route_type)continue;const i=`${n.x},${n.y},${n.from_layer},${n.to_layer}`;if(a.has(i))continue;const c=`via_${a.size}`;a.add(i),e===s[t]&&r.has(i)&&o.add(c)}return o.size===r.size?o:new Set}*generateViaBlockerCandidates(t,e,n={}){if(this.viaBlockerPathSearchCalls>=4||this.getWorkLimitReason())return;const o=e.evaluatedScore;if(!o||!this.score||e.additionalRoutes?.length||e.routeIndex!==t.routeIndex)return;if(!this.input.movableVias?.some(e=>e.routeIndex===t.routeIndex&&e.viaIndex===t.viaIndex)||!this.preservesViaPermissions(t.routeIndex,e.route))return;if([...o.fixedViolations].some(([t,e])=>!this.score.fixedViolations.has(t)||e>this.score.fixedViolations.get(t)+g6))return;const i=this.routes[t.routeIndex],r=this.getViaGeometry(i)[t.viaIndex],s=this.getViaGeometry(e.route)[t.viaIndex],a=n.oldIds??=this.getIndexedViaIds(t.routeIndex,i,r);if(!a.size)return;const c=`repair04_${t.routeIndex}`,l=(t,e)=>{const n=t.pcb_via_id,o=t.pcb_trace_id;if("pcb_trace_error"===t.type&&"string"==typeof n&&e.has(n)&&"string"==typeof o&&o!==c&&t.pcb_trace_error_id===`overlap_${o}_${n}`&&Array.isArray(t.pcb_trace_ids)&&2===t.pcb_trace_ids.length&&t.pcb_trace_ids.includes(c)&&t.pcb_trace_ids.includes(o))return o},d=(t,e)=>{const n=new Set;for(const o of t){const t=l(o,e);void 0!==t&&n.add(t)}return n},h=n.oldContacts??=d(this.score.errors,a);if(!h.size)return;if(n.oldNeighborFixed??=this.getFixedViolations(this.routes).some(t=>"wire"===t.kind&&h.has(`repair04_${t.routeIndex}`)))return;const u=this.getIndexedViaIds(t.routeIndex,e.route,s);if(a.size!==u.size)return;for(const t of o.errors){if([t.pcb_via_id,...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids:[],...Array.isArray(t.pcb_pad_ids)?t.pcb_pad_ids:[]].some(t=>"string"==typeof t&&u.has(t))&&void 0===l(t,u))return}const p=d(o.errors,u);if(1!==p.size||[...p].some(t=>h.has(t)))return;const m=[...p][0];if(!/^repair04_(0|[1-9][0-9]*)$/.test(m))return;const g=Number(m.slice(9)),f=this.routes[g];if(!f||g===t.routeIndex||f.jumpers?.length||f.connectionName===i.connectionName||f.rootConnectionName&&f.rootConnectionName===i.rootConnectionName||f.route.some(t=>Boolean(t.toNextSegmentType||t.insideJumperPad)))return;let y=-1,_=1/0;for(let t=1;t<f.route.length;t++){const e=f.route[t-1],n=f.route[t];if(e.z!==n.z||e.z<s.minZ||e.z>s.maxZ)continue;const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,a=r?Math.max(0,Math.min(1,((s.x-e.x)*o+(s.y-e.y)*i)/r)):0,c=Math.hypot(s.x-e.x-a*o,s.y-e.y-a*i);c<_&&(_=c,y=t)}if(y<1)return;const b=t=>{const e=f.route[t];return this.isLocked(g,e)||t>0&&f.route[t-1].z!==e.z||t+1<f.route.length&&f.route[t+1].z!==e.z};let x=y-1,v=y;for(;x>0&&!b(x);)x--;for(;v<f.route.length-1&&!b(v);)v++;const S=f.route[x],I=f.route[v],C=t=>t.x>=this.mutableBounds.minX-g6&&t.x<=this.mutableBounds.maxX+g6&&t.y>=this.mutableBounds.minY-g6&&t.y<=this.mutableBounds.maxY+g6;if(S.z!==I.z||!C(S)||!C(I))return;const P=S.traceThickness??f.traceThickness;if(f.route.slice(x,v+1).some(t=>(t.traceThickness??f.traceThickness)!==P))return;const M=Math.min(3e4,void 0===this.input.maxPathSearchNodes?3e4:this.input.maxPathSearchNodes-this.pathSearchNodes);if(M<1)return;const N=this.routes.slice();N[t.routeIndex]=e.route;const w={nodesPopped:0,completionReason:"no-path"},T=g1({srj:this.input.srj,routes:N,routeIndex:g,start:I,end:S,bounds:this.mutableBounds,traceThickness:P,traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,gridSize:Math.max(.025,P/4),allowLayerChanges:!1,maxNodes:M,stats:w});if(this.viaBlockerPathSearchCalls++,this.pathSearchCalls++,this.pathSearchNodes+=w.nodesPopped,this.updateWorkStats(),!T)return;T.reverse();const R={...f,route:[...f.route.slice(0,x),...T,...f.route.slice(v+1)]};E6(R)===E6(f)&&(yield{routeIndex:e.routeIndex,route:e.route,additionalRoutes:[{routeIndex:g,route:R}]})}*generateExistingViaCandidates(){for(const t of this.input.movableVias??[]){const e=this.routes[t.routeIndex],n=this.getViaGeometry(e)[t.viaIndex];if(n.pointIndices.some(n=>this.isLocked(t.routeIndex,e.route[n])))continue;const o={};for(const i of[.025,.05,.1,.2,.35,.5,.8,1.2])for(let r=0;r<16;r++){const s=n.x+i*Math.cos(r*Math.PI/8),a=n.y+i*Math.sin(r*Math.PI/8);if(!T6({x:s,y:a,z:n.minZ},this.mutableBounds))continue;const c=e.route.map((t,e)=>n.pointIndices.includes(e)?{...t,x:s,y:a}:t),l={routeIndex:t.routeIndex,route:R6({...e,route:c})};yield l,yield*this.generateViaBlockerCandidates(t,l,o)}}}*generateCandidates(){yield*this.generateExistingViaCandidates();for(const t of!0===this.input.allowLayerChanges?!1===this.input.traceOnlyFirst?[!0]:[!1,!0]:[!1]){if("path-search-node-limit"===this.getWorkLimitReason())return;const e=!0===this.input.allowLayerChanges?Math.min(512,Math.floor(this.maxCandidates/4)):Number.MAX_SAFE_INTEGER;if(!t&&0===e)continue;let n=0;for(const o of this.generateCandidatesForMode(t)){if(!t){if([o,...o.additionalRoutes??[]].some(({routeIndex:t,route:e})=>this.input.movableVias?.length?!this.preservesViaPermissions(t,e):E6(e)!==E6(this.routes[t])))continue;if(n++>=e)break}yield o}}}*generateCandidatesForMode(t){const e=this.score.errors.flatMap(t=>{const e=t.center??t.pcb_center;return e?[e]:[]}),n=[];for(let t=0;t<this.routes.length;t++){const o=this.routes[t];if(!o.jumpers?.length&&!o.route.some(t=>t.toNextSegmentType||t.insideJumperPad))for(let i=1;i<o.route.length;i++){const r=o.route[i-1],s=o.route[i];if(r.toNextSegmentType||r.insideJumperPad||s.insideJumperPad)continue;let a=1/0,c=.5;const l=s.x-r.x,d=s.y-r.y,h=l*l+d*d;for(const t of e){const e=h?Math.max(0,Math.min(1,((t.x-r.x)*l+(t.y-r.y)*d)/h)):0,n=Math.hypot(t.x-r.x-e*l,t.y-r.y-e*d);n<a&&(a=n,c=e)}a<1.5&&n.push({ri:t,pi:i,distance:a,t:c})}}if(n.sort((t,e)=>t.distance-e.distance||t.ri-e.ri||t.pi-e.pi),this.threeRoutePathSearchCalls<18&&!this.getWorkLimitReason()){const t=function*(t){const{routes:e}=t,n=t.violations.filter(t=>"wire"===t.kind).sort((t,e)=>e.severity-t.severity||t.routeIndex-e.routeIndex||t.obstacleIndex-e.obstacleIndex);if(!n.length||t.maxSearchCalls<=0||t.remainingNodes()<=0)return;const o=[];let i=0;const r=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r?Math.max(0,Math.min(1,((t.x-e.x)*o+(t.y-e.y)*i)/r)):0;return Math.hypot(t.x-e.x-s*o,t.y-e.y-s*i)},s=(t,e)=>{const n=t.route[e],o=t.route[e-1],i=t.route[e+1];return void 0!==o&&o.z!==n.z||void 0!==i&&i.z!==n.z},a=e=>{const n=t.bounds;return e.x>=n.minX-1e-8&&e.x<=n.maxX+1e-8&&e.y>=n.minY-1e-8&&e.y<=n.maxY+1e-8};for(let n=0;n<e.length;n++){const i=e[n];if(i.jumpers?.length||i.route.some(t=>Boolean(t.toNextSegmentType||t.insideJumperPad)))continue;const r=e=>t.isLocked(n,e)||s(i,e);for(let t=0;t<i.route.length-1;){let e=t+1;if(i.route[t].z!==i.route[e].z){t=e;continue}for(;e<i.route.length-1&&!r(e)&&i.route[e+1].z===i.route[t].z;)e++;const c=i.route[t].traceThickness??i.traceThickness;e>t&&a(i.route[t])&&a(i.route[e])&&i.route.slice(t,e+1).every(t=>(t.traceThickness??i.traceThickness)===c)&&o.push({ri:n,a:t,b:e,z:i.route[t].z,width:c,distance:1/0,viaEnds:Number(s(i,t))+Number(s(i,e))}),t=e}}const c=new Set;for(const s of n){for(const t of o){t.distance=1/0;const n=e[t.ri];for(let e=t.a+1;e<=t.b;e++)t.distance=Math.min(t.distance,r(s.center,n.route[e-1],n.route[e]))}const n=o.filter(t=>t.ri===s.routeIndex).sort((t,e)=>t.distance-e.distance||t.a-e.a)[0];if(!n||n.distance>.5)continue;const a=e[n.ri],l=o.filter(t=>t.ri!==n.ri&&t.z===n.z&&t.distance<1.5&&e[t.ri].connectionName!==a.connectionName&&(!a.rootConnectionName||e[t.ri].rootConnectionName!==a.rootConnectionName)).sort((t,e)=>t.distance-e.distance||t.ri-e.ri||t.a-e.a),d=l[0],h=l.find(t=>t.ri!==d?.ri);if(!d||!h)continue;const u=[n,d,h],p=u.map(t=>`${t.ri}:${t.a}:${t.b}`).join("|");if(c.has(p))continue;c.add(p);const m=d.viaEnds>=h.viaEnds?1:2,g=3-m,f=[[m,0,g],[0,1,2],[0,2,1],[1,2,0],[2,1,0],[g,0,m]],y=new Set;for(const n of f){if(y.has(n.join()))continue;y.add(n.join());const o=e.map(t=>({...t}));for(const t of u){const n=e[t.ri];o[t.ri]={...n,route:n.route.slice(0,t.a+1)},o.push({...n,route:n.route.slice(t.b)})}let r=!0;for(const s of n){if(i>=t.maxSearchCalls||t.remainingNodes()<=0)return;const n=u[s],a=e[n.ri],c={nodesPopped:0,completionReason:"no-path"},l=g1({srj:t.srj,routes:o,routeIndex:n.ri,start:a.route[n.b],end:a.route[n.a],bounds:t.bounds,traceThickness:n.width,traceClearance:t.traceClearance,viaClearance:t.viaClearance,gridSize:Math.max(.025,n.width/4),allowLayerChanges:!1,maxNodes:Math.min(3e4,t.remainingNodes()),stats:c});if(i++,t.onSearch(c),!l){r=!1;break}l.reverse(),o[n.ri]={...a,route:[...a.route.slice(0,n.a),...l,...a.route.slice(n.b+1)]},o[e.length+s].route=[]}r&&(yield u.map(t=>({routeIndex:t.ri,route:o[t.ri]})))}}}({srj:this.input.srj,routes:this.routes,bounds:this.mutableBounds,violations:this.getFixedViolations(this.routes),isLocked:(t,e)=>this.isLocked(t,this.routes[t].route[e]),traceClearance:this.input.traceClearance??.1,viaClearance:this.input.viaClearance??.1,maxSearchCalls:18-this.threeRoutePathSearchCalls,remainingNodes:()=>Math.min(5e5-this.threeRoutePathSearchNodes,void 0===this.input.maxPathSearchNodes?Number.MAX_SAFE_INTEGER:this.input.maxPathSearchNodes-this.pathSearchNodes),onSearch:t=>{this.threeRoutePathSearchCalls++,this.threeRoutePathSearchNodes+=t.nodesPopped,this.pathSearchCalls++,this.pathSearchNodes+=t.nodesPopped,this.updateWorkStats()}});for(const[e,...n]of t)e&&(yield{...e,additionalRoutes:n})}if(t&&(yield*this.generateCrossingPairCandidates()),yield*this.generateTaperedSegmentCandidates(n),yield*this.generateClearanceCandidates(n,t),"path-search-node-limit"===this.getWorkLimitReason())return;const o=new Set;for(const{ri:e,pi:i}of n.slice(0,80)){const n=this.routes[e];for(const r of[2,4,8,16]){const s=Math.max(0,i-r),a=Math.min(n.route.length-1,i+r),c=`${e}:${s}:${a}`;if(o.has(c))continue;o.add(c);const l=n.route[s],d=n.route[a];if(l.z!==d.z||!T6(l,this.mutableBounds)||!T6(d,this.mutableBounds))continue;if(n.route.slice(s+1,a).some(t=>this.isLocked(e,t)))continue;const h=new Set(n.route.slice(s,a+1).map(t=>t.traceThickness??n.traceThickness));if(1!==h.size)continue;const u=[...h][0],p=d.x-l.x,m=d.y-l.y,g=Math.hypot(p,m);if(!(g<.1)){yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),...n.route.slice(a)]})};for(const t of[.15,-.15,.35,-.35,.7,-.7,1.5,-1.5])for(const o of[.2,0]){const i={x:l.x+p*o-m/g*t,y:l.y+m*o+p/g*t,z:l.z,traceThickness:u},r={x:l.x+p*(1-o)-m/g*t,y:l.y+m*(1-o)+p/g*t,z:l.z,traceThickness:u};T6(i,this.mutableBounds)&&T6(r,this.mutableBounds)&&(yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),i,r,...n.route.slice(a)]})})}if(t&&g>2*n.viaDiameter+.3)for(let t=0;t<this.input.srj.layerCount;t++){if(t===l.z)continue;const o={x:l.x+.2*p,y:l.y+.2*m,z:l.z,traceThickness:u},i={x:l.x+.8*p,y:l.y+.8*m,z:l.z,traceThickness:u};yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,s+1),o,{...o,z:t},{...i,z:t},i,...n.route.slice(a)]})}}}}}const i=new Set;for(const{ri:e,pi:o,t:r}of n){const n=this.routes[e],s=n.route[o-1],a=n.route[o];for(const t of[o-1,o]){const o=n.route[t],r=`${e}:${o.x}:${o.y}`;if(i.has(r))continue;i.add(r);const s=n.route.map((t,e)=>t.x===o.x&&t.y===o.y?e:-1).filter(t=>t>=0);if(!s.some(t=>this.isLocked(e,n.route[t])))for(const t of[.025,.05,.1,.2,.35,.5,.8,1.2])for(let o=0;o<16;o++){const i=t*Math.cos(o*Math.PI/8),r=t*Math.sin(o*Math.PI/8),a=n.route.map((t,e)=>s.includes(e)?{...t,x:t.x+i,y:t.y+r}:t);s.some(t=>!T6(a[t],this.mutableBounds))||(yield{routeIndex:e,route:R6({...n,route:a})})}}const c=t=>t.x>=this.mutableBounds.minX-1e-8&&t.x<=this.mutableBounds.maxX+1e-8&&t.y>=this.mutableBounds.minY-1e-8&&t.y<=this.mutableBounds.maxY+1e-8;if(s.z!==a.z||!c(s)||!c(a))continue;const l=a.x-s.x,d=a.y-s.y,h=Math.hypot(l,d);if(h<.02)continue;const u=Math.max(s.traceThickness??n.traceThickness,a.traceThickness??n.traceThickness),p=l/h,m=d/h;for(const i of[.4,.8,1.5,3]){const a=Math.max(0,r*h-i),c=Math.min(h,r*h+i);for(const t of[.12,-.12,.25,-.25,.5,-.5,1,-1]){const i={x:s.x+p*a-m*t,y:s.y+m*a+p*t,z:s.z,traceThickness:u},r={x:s.x+p*c-m*t,y:s.y+m*c+p*t,z:s.z,traceThickness:u};T6(i,this.mutableBounds)&&T6(r,this.mutableBounds)&&(yield{routeIndex:e,route:{...n,route:[...n.route.slice(0,o),i,r,...n.route.slice(o)]}})}if(!t||c-a<n.viaDiameter+.15)continue;const l={x:s.x+p*a,y:s.y+m*a,z:s.z,traceThickness:u},d={x:s.x+p*c,y:s.y+m*c,z:s.z,traceThickness:u};if(T6(l,this.mutableBounds)&&T6(d,this.mutableBounds))for(let t=0;t<this.input.srj.layerCount;t++){if(t===s.z)continue;const i=[l,{...l,z:t},{...d,z:t},d];yield{routeIndex:e,route:R6({...n,route:[...n.route.slice(0,o),...i,...n.route.slice(o)]})}}}}}_step(){this.score||(this.score=this.evaluate(this.routes),this.stats={initialErrorCount:this.score.count,finalErrorCount:this.score.count,candidates:0,accepted:0},this.candidates=this.generateCandidates(),this.updateWorkStats());const t=this.getWorkLimitReason();if(0===this.score.count||this.evaluated>=this.maxCandidates||t)return void this.finishSearch(0===this.score.count?"clean":this.evaluated>=this.maxCandidates?"candidate-limit":t);const e=this.candidates.next();if(e.done){const t=this.getWorkLimitReason();return t?void this.finishSearch(t):void(this.bestAdjustment?(this.routes=this.bestAdjustment.routes,this.candidateScores.clear(),this.score=this.bestAdjustment.score,this.bestAdjustment=null,this.accepted++,this.candidates=this.generateCandidates()):(this.updateWorkStats("search-exhausted"),this.solved=!0))}this.candidateAttempts++,this.updateWorkStats();const n=[e.value,...e.value.additionalRoutes??[]];if((!0!==this.input.allowLayerChanges||this.input.movableVias?.length)&&n.some(({routeIndex:t,route:e})=>!this.preservesViaPermissions(t,e)))return;const o=this.routes.slice();for(const{routeIndex:t,route:e}of n)o[t]=e;const i=new Map;for(const t of this.getFixedViolations(o))i.set(t.key,t.severity);const r=[...i].every(([t,e])=>this.score.fixedViolations.has(t)&&e<=this.score.fixedViolations.get(t)+g6),s=0===this.getViaPadViolations(o,!1).length;let a;if(s&&r){const t=JSON.stringify([e.value.routeIndex,e.value.route,...e.value.additionalRoutes??[]]);a=this.candidateScores.get(t),a||(a=this.evaluate(o),this.candidateScores.size>=128&&this.candidateScores.delete(this.candidateScores.keys().next().value),this.candidateScores.set(t,a))}e.value.evaluatedScore=a,this.evaluated++,a&&s&&r&&a.count<this.score.count?(this.routes=o,this.candidateScores.clear(),this.score=a,this.accepted++,this.bestAdjustment=null,this.candidates=this.generateCandidates()):a&&r&&s&&a.count===this.score.count&&a.severity<(this.bestAdjustment?.score.severity??this.score.severity)-1e-6&&(this.bestAdjustment={routes:o,score:a}),this.stats={...this.stats,finalErrorCount:this.score.count,candidates:this.evaluated,accepted:this.accepted},this.progress=this.evaluated/this.maxCandidates}getConstructorParams(){return[structuredClone(this.input)]}getOutput(){if(!this.solved||this.failed)throw new Error("repair04: getOutput requires a completed solve");return structuredClone(this.routes)}visualize(){const t=this.input.bounds,e=this.mutableBounds;return{title:"repair04 — fixed boundary, local copper repair",rects:[{center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},width:t.maxX-t.minX,height:t.maxY-t.minY,stroke:"#64748b",fill:"rgba(148,163,184,0.15)"},{center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,stroke:"#0891b2",fill:"transparent"},...this.input.srj.obstacles.map(t=>({center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,fill:"rgba(239,68,68,0.22)",stroke:"#b91c1c",layer:`z${t.layers.map(t=>"top"===t?0:"bottom"===t?this.input.srj.layerCount-1:Number(t.slice(5))).join(",")}`}))],lines:this.routes.flatMap(t=>t.route.slice(1).flatMap((e,n)=>e.z===t.route[n].z?[{points:[t.route[n],e],strokeColor:0===e.z?"#dc2626":"rgba(37,99,235,0.65)",strokeWidth:e.traceThickness??t.traceThickness,...0===e.z?{}:{strokeDash:[.2,.12]},layer:`z${e.z}`}]:[])),circles:this.routes.flatMap(t=>t.vias.map(e=>{const n=t.route.filter(t=>t.x===e.x&&t.y===e.y).map(t=>t.z),o=Math.min(...n),i=Math.max(...n);return{center:e,radius:t.viaDiameter/2,fill:"rgba(37,99,235,0.65)",stroke:"#1e40af",layer:`z${Array.from({length:i-o+1},(t,e)=>o+e).join(",")}`}})),points:this.lockedPoints.flat().map(t=>({...t,color:"#0f172a",layer:`z${t.z}`}))}}},O6=(t,e,n)=>{if(n<=g6)return structuredClone(t);if(n>=.99999999)return structuredClone(e);const o={...structuredClone(t),x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n};return delete o.start_pcb_port_id,delete o.end_pcb_port_id,o},k6=(t,e)=>{const n=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,s=e.start.x-t.start.x,a=e.start.y-t.start.y,c=n*r-o*i,l=(t,e)=>({x:t.start.x+(t.end.x-t.start.x)*e,y:t.start.y+(t.end.y-t.start.y)*e}),d=(t,e)=>{const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=n*n+o*o,r=i>10000000000000001e-32?Math.max(0,Math.min(1,((t.x-e.start.x)*n+(t.y-e.start.y)*o)/i)):0;return l(e,r)};if(Math.abs(c)>g6){const e=(s*r-a*i)/c,d=(s*o-a*n)/c;if(e>=0&&e<=1&&d>=0&&d<=1){const n=l(t,e);return[n,n]}}else{const i=n*n+o*o;if(i>10000000000000001e-32){const r=(s*n+a*o)/i,c=((e.end.x-t.start.x)*n+(e.end.y-t.start.y)*o)/i,h=Math.max(0,Math.min(r,c)),u=Math.min(1,Math.max(r,c));if(h<=u){const n=l(t,(h+u)/2);return[n,d(n,e)]}}}const h=[[t.start,d(t.start,e)],[t.end,d(t.end,e)],[d(e.start,t),e.start],[d(e.end,t),e.end]];return h.sort((t,e)=>Math.hypot(t[0].x-t[1].x,t[0].y-t[1].y)-Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y)),h[0]},L6=(t,e)=>{const n="top"===t?0:"bottom"===t?e-1:/^inner\d+$/.test(t)?Number(t.slice(5)):-1;if(!Number.isInteger(n)||n<0||n>=e)throw new Error(`repair04 preload has an unknown layer: ${t}`);return n},D6=(t,e,n)=>{const o=((t,e)=>{const n=new Map,o=t=>{const e=n.get(t);if(void 0===e||e===t)return t;const i=o(e);return n.set(t,i),i},i=t=>{const e=t.filter(t=>"string"==typeof t&&t.length>0);if(0===e.length)return;const i=o(e[0]);for(const t of e)n.set(o(t),i)};for(const e of t.connections){const t=e;i([t.name,t.rootConnectionName,t.netConnectionName,t.__netConnectionName,...t.mergedConnectionNames??[],...t.__rootConnectionNames??[]])}for(const t of e)i([t.connectionName,t.rootConnectionName]);for(const e of t.traces??[])i([e.connection_name,...e.connectsTo??[]]);return o})(t,e),i=e.map((t,e)=>e),r=t=>{const e=i[t];if(e===t)return t;const n=r(e);return i[t]=n,n},s=new Map;for(let t=0;t<e.length;t+=1){const n=e[t];for(const e of[n.route[0],n.route.at(-1)]){if(!e?.pcb_port_id)continue;const a=JSON.stringify([o(n.connectionName),e.pcb_port_id,e.x,e.y,e.z]),c=s.get(a);void 0===c?s.set(a,t):i[r(t)]=r(c)}}const a=(t,e)=>!(!t.startsWith("route:")||!e.startsWith("route:"))&&r(Number(t.slice(6)))===r(Number(e.slice(6))),c=[],l=[],d=[],h=e.map(()=>({segmentTimes:new Map,viaPositions:[]})),u=t=>{if(f6(t,n)){d.push(t);for(let e=t.minZ;e<=t.maxZ;e+=1)c.push({x:t.x,y:t.y,z:e,radius:t.radius,net:t.net,source:t.source,...void 0!==t.routeIndex?{viaOwner:t.routeIndex}:{}})}};for(let t=0;t<e.length;t+=1){const i=e[t],r=o(i.connectionName),s=`route:${t}`;for(let e=0;e<i.route.length;e+=1){const o=i.route[e];if((0===e||e===i.route.length-1||o.pcb_port_id)&&f6(o,n)&&c.push({x:o.x,y:o.y,z:o.z,radius:(o.traceThickness??i.traceThickness)/2,net:r,source:s}),0===e)continue;const a=i.route[e-1];"through_obstacle"!==a.toNextSegmentType&&(a.z===o.z?l.push({start:a,end:o,z:o.z,radius:Math.max(a.traceThickness??i.traceThickness,o.traceThickness??i.traceThickness)/2,net:r,source:s,routeIndex:t,segmentIndex:e-1}):u({x:o.x,y:o.y,minZ:Math.min(a.z,o.z),maxZ:Math.max(a.z,o.z),radius:i.viaDiameter/2,net:r,source:s,routeIndex:t}))}}for(let e=0;e<(t.traces??[]).length;e+=1){const i=m1(t.traces[e],t.minTraceWidth),r=o(i.connection_name),s=`fixed:${e}`;for(let e=0;e<i.route.length;e+=1){const o=i.route[e],a=i.route[e-1];if("wire"===o.route_type){const d=L6(o.layer,t.layerCount);(0===e||e===i.route.length-1||o.start_pcb_port_id||o.end_pcb_port_id)&&f6(o,n)&&c.push({x:o.x,y:o.y,z:d,radius:o.width/2,net:r,source:s}),"wire"===a?.route_type&&a.layer===o.layer&&l.push({start:a,end:o,z:d,radius:Math.max(a.width,o.width)/2,net:r,source:s})}else if("via"===o.route_type){const e=L6(o.from_layer,t.layerCount),n=L6(o.to_layer,t.layerCount);u({x:o.x,y:o.y,minZ:Math.min(e,n),maxZ:Math.max(e,n),radius:(o.via_diameter??t.minViaDiameter??.3)/2,net:r,source:s})}}}const p=new Map;for(const t of c){const e=JSON.stringify([t.net,t.z]),n=p.get(e)??[];n.push(t),p.set(e,n)}const m=(t,e)=>{if(void 0===t)return;const n=h[t].viaPositions;n.some(t=>Math.hypot(t.x-e.x,t.y-e.y)<=g6)||n.push({x:e.x,y:e.y})};for(const t of l){if(!y6(t.start,t.end,n))continue;const e=t.end.x-t.start.x,o=t.end.y-t.start.y,i=e*e+o*o;if(!(i<=10000000000000001e-32))for(const r of p.get(JSON.stringify([t.net,t.z]))??[]){if(r.source===t.source||a(r.source,t.source))continue;const s=Math.max(0,Math.min(1,((r.x-t.start.x)*e+(r.y-t.start.y)*o)/i)),c={x:t.start.x+e*s,y:t.start.y+o*s};if(f6(c,n)&&!(Math.hypot(c.x-r.x,c.y-r.y)>t.radius+r.radius+g6)){if(void 0!==t.routeIndex&&void 0!==t.segmentIndex){const e=h[t.routeIndex].segmentTimes.get(t.segmentIndex)??[];e.some(t=>Math.abs(t-s)<=g6)||e.push(s),h[t.routeIndex].segmentTimes.set(t.segmentIndex,e)}m(r.viaOwner,r)}}}for(const t of d)for(let e=t.minZ;e<=t.maxZ;e+=1)for(const n of p.get(JSON.stringify([t.net,e]))??[])n.source===t.source||a(n.source,t.source)||Math.hypot(t.x-n.x,t.y-n.y)>t.radius+n.radius+g6||(m(t.routeIndex,t),m(n.viaOwner,n));return((t,e,n,o)=>{const i=new Map,r=new Set,s=[],a=(t,e)=>{if(void 0===t.routeIndex||void 0===t.segmentIndex)return;const o=t.end.x-t.start.x,i=t.end.y-t.start.y,r=o*o+i*i;if(r<=10000000000000001e-32)return;const s=Math.max(0,Math.min(1,((e.x-t.start.x)*o+(e.y-t.start.y)*i)/r)),a=n[t.routeIndex].segmentTimes.get(t.segmentIndex)??[];a.some(t=>Math.abs(t-s)<=g6)||a.push(s),n[t.routeIndex].segmentTimes.set(t.segmentIndex,a)};for(const n of t){const t=y6(n.start,n.end,e);if(!t||t[1]-t[0]<=g6)continue;const c=t=>({x:n.start.x+(n.end.x-n.start.x)*t,y:n.start.y+(n.end.y-n.start.y)*t}),l={...n,start:c(t[0]),end:c(t[1])},d=s.length;s.push({original:n,clipped:l});const h=Math.floor((Math.min(l.start.x,l.end.x)-l.radius)/2),u=Math.floor((Math.max(l.start.x,l.end.x)+l.radius)/2),p=Math.floor((Math.min(l.start.y,l.end.y)-l.radius)/2),m=Math.floor((Math.max(l.start.y,l.end.y)+l.radius)/2);for(let t=h;t<=u;t+=1)for(let e=p;e<=m;e+=1){const c=JSON.stringify([l.net,l.z,t,e]),h=i.get(c)??[];for(const t of h){const e=s[t];if(e.original.source===n.source||o(e.original.source,n.source)||void 0===e.original.routeIndex&&void 0===n.routeIndex)continue;const i=`${t}:${d}`;if(r.has(i))continue;r.add(i);const[c,h]=k6(l,e.clipped);Math.hypot(c.x-h.x,c.y-h.y)>l.radius+e.clipped.radius+g6||(a(n,c),a(e.original,h))}h.push(d),i.set(c,h)}}})(l,n,h,a),h},z6=(t,e)=>({minX:t.minX-e,maxX:t.maxX+e,minY:t.minY-e,maxY:t.maxY+e}),F6=(t,e,n,o)=>{const i=[];let r;const s=t.route,a=t=>0===t||t===s.length-1||void 0!==s[t]?.pcb_port_id,c=()=>{void 0!==r&&r.points.length>0&&(r.locks[0]=!0,r.locks[r.points.length-1]=!0,i.push(r)),r=void 0};if(1===s.length&&s[0]&&f6(s[0],e))return[{points:structuredClone(s),locks:[!0],start:{segmentIndex:0,t:0},end:{segmentIndex:0,t:0}}];for(let i=0;i<s.length-1;i+=1){const l=s[i],d=s[i+1];if(!l||!d)throw new Error("repair04 found a missing route point");if(![l.x,l.y,l.z,d.x,d.y,d.z].every(Number.isFinite))throw new Error("repair04 route coordinates must be finite");if(l.z!==d.z&&!b6({x:l.x,y:l.y},{x:d.x,y:d.y})&&"through_obstacle"!==l.toNextSegmentType)throw new Error("repair04 requires colocated points at a via transition");const h=y6(l,d,e);if(!h){c();continue}const[u,p]=h;if(p-u<=g6&&!b6(l,d)){c();continue}const m=y6(l,d,n),g=[u,p],f=o.segmentTimes.get(i)??[];for(const t of f)t>=u-g6&&t<=p+g6&&g.push(Math.max(u,Math.min(p,t)));if(m&&l.z===d.z)for(const t of m)t>u+g6&&t<p-g6&&g.push(t);g.sort((t,e)=>t-e);const y=g.filter((t,e)=>0===e||Math.abs(t-g[e-1])>g6),_=_6(l,d,u);r&&!b6(r.points[r.points.length-1],_)&&c(),r||(r={points:[],locks:[],start:{segmentIndex:i,t:u},end:{segmentIndex:i,t:p}});for(const e of y){const s=_6(l,d,e),c=e<=g6?i:e>=.99999999?i+1:void 0,h=!f6(s,n,4e-8)||f.some(t=>Math.abs(t-e)<=g6)||o.viaPositions.some(t=>Math.hypot(t.x-s.x,t.y-s.y)<=g6)||void 0!==c&&a(c)||"through_obstacle"===l.toNextSegmentType||"through_obstacle"===s.toNextSegmentType||!0===l.insideJumperPad||!0===d.insideJumperPad||(t.jumpers??[]).some(t=>b6(s,{...t.start,z:s.z})||b6(s,{...t.end,z:s.z})),u=r.points[r.points.length-1];u&&b6(u,s)?r.locks[r.locks.length-1]=r.locks[r.locks.length-1]||h:(r.points.push(s),r.locks.push(h))}r.end={segmentIndex:i,t:p},p<.99999999&&c()}c();for(const t of i)for(let e=1;e<t.points.length;e+=1){const n=t.points[e-1],o=t.points[e];if(n.z!==o.z&&(t.locks[e-1]||t.locks[e])){let n=e-1,i=e;for(;n>0&&b6({x:t.points[n-1].x,y:t.points[n-1].y},{x:o.x,y:o.y});)n-=1;for(;i+1<t.points.length&&b6({x:t.points[i+1].x,y:t.points[i+1].y},{x:o.x,y:o.y});)i+=1;for(let e=n;e<=i;e+=1)t.locks[e]=!0}}return i},B6=(t,e)=>{const n=t.bounds,o=t.outline&&t.outline.length>=3?t.outline:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}],i=[];for(let n=0;n<o.length;n+=1){const r=o[n],s=o[(n+1)%o.length],a=y6(r,s,e);if(!a)continue;const c=s.x-r.x,l=s.y-r.y,d=Math.hypot(c,l);if(d<=g6)continue;const h=(a[0]+a[1])/2;i.push({obstacleId:`repair04_board_edge_${n}`,type:"rect",center:{x:r.x+c*h,y:r.y+l*h},width:d*(a[1]-a[0]),height:Math.max(2*(t.minBoardEdgeClearance??0),g6),ccwRotationDegrees:180*Math.atan2(l,c)/Math.PI,layers:Array.from({length:t.layerCount},(e,n)=>0===n?"top":n===t.layerCount-1?"bottom":`inner${n}`),zLayers:Array.from({length:t.layerCount},(t,e)=>e),connectedTo:[]})}return i},j6=({srj:t,routes:e,bounds:n,boundaryMargin:o=.5,clearanceHalo:i})=>{if((t=>{if(!Object.values(t).every(Number.isFinite))throw new Error("repair04 bounds must contain finite coordinates");if(t.maxX-t.minX<9.99999999||t.maxY-t.minY<9.99999999)throw new Error("repair04 requires bounds at least 10 mm by 10 mm")})(n),!Number.isFinite(o)||o<0||void 0!==i&&(!Number.isFinite(i)||i<0))throw new Error("repair04 collar and halo must be finite and nonnegative");const r=Math.max(t.defaultObstacleMargin??.2,t.minTraceToPadEdgeClearance??0,t.minViaEdgeToPadEdgeClearance??0);let s=Math.max(t.minTraceWidth,t.minViaDiameter??0);for(const t of e){s=Math.max(s,t.traceThickness,t.viaDiameter);for(const e of t.route)s=Math.max(s,e.traceThickness??0)}for(const e of t.traces??[])for(const n of e.route)"wire"===n.route_type&&(s=Math.max(s,n.width)),"via"===n.route_type&&(s=Math.max(s,n.via_diameter??t.minViaDiameter??.3));if(!Number.isFinite(s)||s<=0)throw new Error("repair04 requires finite positive copper widths");const a=Math.max(o,s+r);if(2*a>=Math.min(n.maxX-n.minX,n.maxY-n.minY))throw new Error("repair04 bounds are too small for their required copper safety collar");const c=z6(n,Math.max(i??a,r+s)),l=z6(n,-a),d=D6(t,e,c),h=((t,e,n)=>{const o=[];for(const i of t){const t=m1(i,n),r=[];let s=[];const a=()=>{s.length>0&&r.push(s),s=[]},c=t=>{x6(s[s.length-1])!==x6(t)&&s.push(structuredClone(t))};for(let n=0;n<t.route.length;n+=1){const o=t.route[n],i=t.route[n-1];if("wire"===o.route_type&&"wire"===i?.route_type&&o.layer===i.layer){const t=y6(i,o,e);if(!t){a();continue}const n=O6(i,o,t[0]),r=O6(i,o,t[1]),l=s[s.length-1];"wire"===l?.route_type&&(l.layer!==n.layer||Math.hypot(l.x-n.x,l.y-n.y)>g6)&&a(),c(n),c(r),t[1]<.99999999&&a()}else if("via"===o.route_type){if(!f6(o,e)){a();continue}if("wire"!==i?.route_type)throw new Error("repair04 normalized preload via has no incoming wire");c(i),c(o);const r=t.route[n+1];if("wire"!==r?.route_type)throw new Error("repair04 normalized preload via has no outgoing wire");c(r)}else if("wire"===o.route_type)f6(o,e)&&c(o);else if("start"in o&&"end"in o){const t=y6(o.start,o.end,e);if(!t){a();continue}const n=t=>({x:o.start.x+(o.end.x-o.start.x)*t,y:o.start.y+(o.end.y-o.start.y)*t});c({...structuredClone(o),start:n(t[0]),end:n(t[1])}),t[1]<.99999999&&a()}}a();for(let t=0;t<r.length;t+=1)o.push({...structuredClone(i),pcb_trace_id:1===r.length?i.pcb_trace_id:`${i.pcb_trace_id}__repair04_fixed_${t}`,route:r[t]})}return o})(t.traces??[],c,t.minTraceWidth),u=[],p=[],m=[];for(let t=0;t<e.length;t+=1){const n=e[t];for(const e of F6(n,c,l,d[t])){const o={...structuredClone(Object.fromEntries(Object.entries(n).filter(([t])=>"route"!==t&&"vias"!==t&&"jumpers"!==t))),connectionName:n.connectionName,traceThickness:n.traceThickness,viaDiameter:n.viaDiameter,route:e.points,vias:n.vias.filter(t=>e.points.some(e=>Math.abs(e.x-t.x)<=g6&&Math.abs(e.y-t.y)<=g6)).map(t=>structuredClone(t)),...void 0!==n.jumpers?{jumpers:n.jumpers.filter(t=>void 0!==y6(t.start,t.end,c)).map(t=>structuredClone(t))}:{}};u.push(o),p.push(e.locks),m.push({sourceRouteIndex:t,start:e.start,end:e.end,sourceGeometryKey:S6(n,e.start.segmentIndex+e.start.t,e.end.segmentIndex+e.end.t),originalFragment:structuredClone(o)})}}const g=new Set([...u.flatMap(t=>[t.connectionName,...t.rootConnectionName?[t.rootConnectionName]:[]]),...h.map(t=>t.connection_name)]),f=t.connections.filter(t=>g.has(t.name)||t.pointsToConnect.some(t=>f6(t,c))).map(t=>({...structuredClone(Object.fromEntries(Object.entries(t).filter(([t])=>"pointsToConnect"!==t))),name:t.name,pointsToConnect:t.pointsToConnect.filter(t=>f6(t,c)).map(t=>structuredClone(t))}));for(let e=0;e<u.length;e+=1){const n=u[e];let o=f.find(t=>t.name===n.connectionName);o||(o={name:n.connectionName,...n.rootConnectionName?{rootConnectionName:n.rootConnectionName}:{},pointsToConnect:[]},f.push(o));for(const[i,r]of[["start",n.route[0]],["end",n.route[n.route.length-1]]]){if(!r)continue;const n=0===r.z?"top":r.z===t.layerCount-1?"bottom":`inner${r.z}`;o.pointsToConnect.some(t=>Math.abs(t.x-r.x)<=g6&&Math.abs(t.y-r.y)<=g6&&("layer"in t?t.layer===n:t.layers.includes(n)))||o.pointsToConnect.push({x:r.x,y:r.y,layer:n,pointId:`repair04_${e}_${i}`,...r.pcb_port_id?{pcb_port_id:r.pcb_port_id}:{}})}}const y={...Object.fromEntries(Object.entries(t).filter(([t,e])=>"sourceCircuitJson"!==t&&"sourceKicadPcb"!==t&&("number"==typeof e||"boolean"==typeof e||"string"==typeof e))),layerCount:t.layerCount,minTraceWidth:t.minTraceWidth,bounds:structuredClone(c),obstacles:[...t.obstacles.filter(t=>((t,e)=>{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=(Math.abs(t.width*Math.cos(n))+Math.abs(t.height*Math.sin(n)))/2,i=(Math.abs(t.width*Math.sin(n))+Math.abs(t.height*Math.cos(n)))/2;return t.center.x+o>=e.minX&&t.center.x-o<=e.maxX&&t.center.y+i>=e.minY&&t.center.y-i<=e.maxY})(t,c)).map(t=>structuredClone(t)),...B6(t,c)],connections:f,...void 0!==t.traces?{traces:h}:{},...void 0!==t.allowJumpers?{allowJumpers:t.allowJumpers}:{},...t.availableJumperTypes?{availableJumperTypes:structuredClone(t.availableJumperTypes)}:{}};return{srj:y,routes:u,bounds:structuredClone(n),contextBounds:c,mutableBounds:l,boundaryMargin:a,lockedPointIndices:p,routeMappings:m}},$6=t=>x6(Object.fromEntries(Object.entries(t).filter(([t])=>"route"!==t&&"vias"!==t))),Y6=(t,e)=>{const n=[];for(let o=1;o<t.route.length;o+=1){const i=t.route[o-1],r=t.route[o],s=y6(i,r,e),a=s?[...s[0]>g6?[[0,s[0]]]:[],...s[1]<.99999999?[[s[1],1]]:[]]:[[0,1]];s&&!f6(_6(i,r,.5),e,4e-8)&&0===a.length&&a.push([0,1]);for(const[t,e]of a)n.push(x6([_6(i,r,t),_6(i,r,e)]))}return n},X6=(t,e,n,o,i,r)=>{if($6(t)!==$6(e))throw new Error("repair04 merge rejected changed net, width, jumper, or route metadata");if(n.length!==t.route.length)throw new Error("repair04 merge received an invalid lock mask");if(0===e.route.length)throw new Error("repair04 merge rejected an empty replacement route");if(x6(t.route[0])!==x6(e.route[0])||x6(t.route[t.route.length-1])!==x6(e.route[e.route.length-1]))throw new Error("repair04 merge rejected a moved fragment endpoint");let s=0;for(let o=0;o<t.route.length;o+=1){if(!n[o])continue;const i=x6(t.route[o]);for(;s<e.route.length&&x6(e.route[s])!==i;)s+=1;if(s===e.route.length)throw new Error("repair04 merge rejected a moved or removed locked point");s+=1}if(x6(Y6(t,o))!==x6(Y6(e,o)))throw new Error("repair04 merge rejected modified geometry in the fixed boundary collar");for(let n=1;n<t.route.length;n+=1){const o=t.route[n-1],i=t.route[n];if(!("through_obstacle"===o.toNextSegmentType||!0===o.insideJumperPad||!0===i.insideJumperPad||(t.jumpers??[]).some(t=>b6(o,{...t.start,z:o.z})&&b6(i,{...t.end,z:i.z})||b6(o,{...t.end,z:o.z})&&b6(i,{...t.start,z:i.z}))))continue;const r=x6([o,i]);if(!e.route.some((t,n)=>n+1<e.route.length&&x6([t,e.route[n+1]])===r))throw new Error("repair04 merge rejected a changed atomic jumper or through-obstacle span")}for(const n of e.route){if(![n.x,n.y,n.z].every(Number.isFinite)||!Number.isInteger(n.z)||n.z<0||n.z>=r||!f6(n,i))throw new Error("repair04 merge rejected invalid or out-of-region geometry");if((void 0!==n.pcb_port_id||!0===n.insideJumperPad||void 0!==n.toNextSegmentCircuitJsonMetadata)&&!t.route.some(t=>x6(t)===x6(n)))throw new Error("repair04 merge rejected invented or moved terminal/circuit metadata");if(void 0!==n.traceThickness&&(!Number.isFinite(n.traceThickness)||n.traceThickness<=0||n.traceThickness>Math.max(t.traceThickness,...t.route.map(t=>t.traceThickness??0))+g6))throw new Error("repair04 merge rejected increased per-point copper width")}for(let n=1;n<e.route.length;n+=1){const o=e.route[n-1],i=e.route[n];if("through_obstacle"===o.toNextSegmentType&&!t.route.some((e,n)=>n+1<t.route.length&&x6([e,t.route[n+1]])===x6([o,i])))throw new Error("repair04 merge rejected an invented through-obstacle span");if(o.z!==i.z&&"through_obstacle"!==o.toNextSegmentType&&(Math.abs(o.x-i.x)>g6||Math.abs(o.y-i.y)>g6||!e.vias.some(t=>Math.abs(t.x-o.x)<=g6&&Math.abs(t.y-o.y)<=g6)))throw new Error("repair04 merge rejected a disconnected or missing via")}for(const n of e.vias){if(!(Number.isFinite(n.x)&&Number.isFinite(n.y)&&f6(n,i)&&e.route.some(t=>Math.abs(t.x-n.x)<=g6&&Math.abs(t.y-n.y)<=g6)))throw new Error("repair04 merge rejected an invalid via position");if(!f6(n,o,4e-8)&&!t.vias.some(t=>x6(t)===x6(n)))throw new Error("repair04 merge rejected a new via in the boundary collar")}for(const n of t.vias)if(!f6(n,o,4e-8)&&!e.vias.some(t=>x6(t)===x6(n)))throw new Error("repair04 merge rejected a changed via in the boundary collar")},V6=(t,e)=>{for(const n of e){const e=t[t.length-1];e&&b6(e,n)&&x6(e)===x6(n)||t.push(structuredClone(n))}},W6=(t,e,n)=>{const o=new Set(e.route.map(x6)),i=new Set(n.flatMap(t=>t.originalFragment.route.map(x6)).filter(t=>!o.has(t))),r=[];for(const e of t)for(r.push(e);r.length>=3;){const t=r[r.length-3],e=r[r.length-2],n=r[r.length-1];if(!i.has(x6(e)))break;if(t.z!==e.z||e.z!==n.z&&"through_obstacle"!==t.toNextSegmentType)break;if(t.toNextSegmentType!==e.toNextSegmentType||t.insideJumperPad!==e.insideJumperPad||t.traceThickness!==e.traceThickness||x6(t.toNextSegmentCircuitJsonMetadata)!==x6(e.toNextSegmentCircuitJsonMetadata))break;const o=n.x-t.x,s=n.y-t.y,a=o*o+s*s;if(a<=10000000000000001e-32)break;const c=(e.x-t.x)*s-(e.y-t.y)*o,l=((e.x-t.x)*o+(e.y-t.y)*s)/a;if(Math.abs(c)>g6*Math.sqrt(a)||l<0||l>1)break;r.splice(r.length-2,1)}return r},H6=t=>{if(!Number.isInteger(t.segmentIndex)||t.segmentIndex<0||!Number.isFinite(t.t)||t.t<0||t.t>1)throw new Error("repair04 merge received invalid fragment provenance");return t.segmentIndex+t.t},G6=({routes:t,region:e,repairedRoutes:n})=>{if(n.length!==e.routeMappings.length||e.lockedPointIndices.length!==n.length)throw new Error("repair04 merge requires exactly one replacement for every extracted fragment");const o=new Map;for(let i=0;i<n.length;i+=1){const r=e.routeMappings[i],s=n[i];if(!t[r.sourceRouteIndex])throw new Error("repair04 merge source route no longer exists");if(X6(r.originalFragment,s,e.lockedPointIndices[i],e.mutableBounds,e.contextBounds,e.srj.layerCount),x6(r.originalFragment)===x6(s))continue;const a=o.get(r.sourceRouteIndex)??[];a.push({mapping:r,repaired:s}),o.set(r.sourceRouteIndex,a)}return t.map((t,e)=>{const n=o.get(e);if(!n)return t;n.sort((t,e)=>H6(t.mapping.start)-H6(e.mapping.start));const i=[];let r=0;for(const{mapping:e,repaired:o}of n){const n=H6(e.start),s=H6(e.end);if(n<r-g6||s<n||s>t.route.length-1+g6)throw new Error("repair04 merge received overlapping or stale fragment provenance");if(S6(t,n,s)!==e.sourceGeometryKey)throw new Error("repair04 merge rejected stale source geometry");V6(i,v6(t,r,n)),V6(i,o.route),r=s}V6(i,v6(t,r,t.route.length-1));const s=new Set(n.flatMap(({mapping:t})=>t.originalFragment.vias.map(t=>`${t.x},${t.y}`))),a=t.vias.filter(t=>!s.has(`${t.x},${t.y}`)).map(t=>structuredClone(t));for(const{repaired:t}of n)for(const e of t.vias)a.some(t=>Math.abs(t.x-e.x)<=g6&&Math.abs(t.y-e.y)<=g6)||a.push(structuredClone(e));return{...t,route:W6(i,t,n.map(({mapping:t})=>t)),vias:a}})},U6=12e4,Z6=[10,16],q6=[3,4,5,6,8],J6=(t,e)=>{const n="string"==typeof t.pcb_pad_id?t.pcb_pad_id:"string"==typeof t.pcb_trace_error_id?t.pcb_trace_error_id.match(/(pcb_(?:smtpad|plated_hole|hole|keepout)_\d+)$/)?.[1]:void 0;if(n){const t=e.obstacles.find(t=>t.obstacleId===n||t.connectedTo[0]===n);if(t)return t.center}return(t=>{const e=t.center;return e&&"object"==typeof e&&"x"in e&&"y"in e&&"number"==typeof e.x&&"number"==typeof e.y?{x:e.x,y:e.y}:void 0})(t)},K6=({error:t,routeIndexByTraceId:e})=>{const n="string"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,o=[..."string"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=>"string"==typeof t):[]],i=n?`overlap_${n}_`:void 0,r=i&&"string"==typeof t.pcb_trace_error_id&&t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0,s=void 0!==r&&o.includes(r);return[n,...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids:[],s?void 0:r].filter(t=>"string"==typeof t&&e.has(t)).filter((t,e,n)=>n.indexOf(t)===e)},Q6=t=>t.filter(t=>"pcb_via_clearance_error"===t.type||Array.isArray(t.pcb_via_ids)).length,t9=(t,e)=>{const n=new Map;for(const e of t)n.set(e.connectionName,(n.get(e.connectionName)??0)+1);return t.map((t,o)=>{const i=n.get(t.connectionName)>1?`${t.connectionName}_regional_${o}`:t.connectionName;return i!==t.connectionName&&e.addConnections([[i,t.connectionName,t.rootConnectionName??t.connectionName]]),{...t,connectionName:i,preloadedTraceId:`pipeline9_joint_candidate_${o}`,preloadedTraceIndex:o,preloadedRouteIndex:0,isThroughObstacle:!1}})},e9=(t,e)=>t.minX<=e.maxX&&t.maxX>=e.minX&&t.minY<=e.maxY&&t.maxY>=e.minY,n9=t=>({minX:t.center.x-t.diameter/2,maxX:t.center.x+t.diameter/2,minY:t.center.y-t.diameter/2,maxY:t.center.y+t.diameter/2}),o9=t=>({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}),i9=(t,e)=>{const n=EQ(t);return n.wireSegments.some(t=>e9((t=>({minX:Math.min(t.start.x,t.end.x)-t.width/2,maxX:Math.max(t.start.x,t.end.x)+t.width/2,minY:Math.min(t.start.y,t.end.y)-t.width/2,maxY:Math.max(t.start.y,t.end.y)+t.width/2}))(t),e))||n.viaSpans.some(t=>e9(n9(t),e))},r9=({routes:t,fixedObstacleRoutes:e,routeIndex:n,center:o,regionSize:i,srj:r,connMap:s,colorMap:a,viaDiameter:c,traceWidth:l,obstacleMargin:d,effort:h})=>{const u=t9(t,s),p=u[n];if(!p)return;const m={capacityMeshNodeId:`pipeline9_joint_drc_${n}_${i}`,center:o,width:i,height:i,availableZ:Array.from({length:r.layerCount},(t,e)=>e),portPoints:[],portPointsInPairs:[]},g=$K(m,[p]),f=g.fixedRouteSectionsByConnectionName.get(p.connectionName);if(!f)return;const y=u.filter((t,e)=>e!==n),_=new VQ({nodePortPoints:[g.nodeWithPortPoints],fixedHdRoutes:[...y,...e].map(t=>({...t,rootConnectionName:s.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName})),connMap:s,colorMap:a,obstacles:r.obstacles,layerCount:r.layerCount,viaDiameter:c,traceWidth:l,obstacleMargin:d,effort:h,preserveTerminalPcbPortIds:!0,includeBoardObstacles:!0,enableRegionalFallback:!1,maxB01Rips:120});if(_.solve(),!_.solved||_.failed)return;const b=_.routes.find(t=>t.connectionName===p.connectionName);return b?{routes:t.map((t,e)=>e===n?{...XK(f,b),connectionName:t.connectionName}:t),usedFallback:Number(_.stats.fallbackNodeCount??0)>0}:void 0},s9=({routes:t,fixedRouteCopperSpatialIndex:e,center:n,regionSize:o,srj:i,connMap:r,colorMap:s,viaDiameter:a,traceWidth:c,obstacleMargin:l,effort:d})=>{const h=t9(t,r),u={capacityMeshNodeId:"pipeline9_joint_drc_regular_fallback",center:n,width:o,height:o,availableZ:Array.from({length:i.layerCount},(t,e)=>e),portPoints:[],portPointsInPairs:[]},p=$K(u,h);if(0===p.fixedRouteSectionsByConnectionName.size)return;if(!(t=>{const e=kK(t);return t.portPoints.every(t=>"on-boundary"===rs({point:t,bounds:e}))})(p.nodeWithPortPoints))return;const m=[...p.fixedRouteSectionsByConnectionName.values()].flatMap(t=>t.sourceRoutes).reduce((t,e)=>{const n=EQ(e);return Math.max(t,e.viaDiameter/2,...n.wireSegments.map(t=>t.width/2),...n.viaSpans.map(t=>t.diameter/2))},Math.max(c/2,a/2)),g={minX:n.x-o/2-l-m,maxX:n.x+o/2+l+m,minY:n.y-o/2-l-m,maxY:n.y+o/2+l+m},f=e.getRoutesOverlappingBounds(g),y=OQ({fixedObstacleRoutes:f,layerCount:i.layerCount}),_=new FQ({nodeWithPortPoints:p.nodeWithPortPoints,colorMap:s,connMap:r,viaDiameter:a,traceWidth:c,obstacleMargin:l,effort:d,obstacles:[...i.obstacles,...y],layerCount:i.layerCount});if(_.solve(),!_.solved||_.failed)return;const b=_.getOutput(),x=new Map(b.map(t=>[t.connectionName,t])),v=new Map,S=new Set;for(const[t,e]of p.fixedRouteSectionsByConnectionName){const n=x.get(t);if(!n)return;v.set(e.sourceRoutes[0].preloadedTraceIndex,XK(e,n));for(const t of e.sourceRoutes.slice(1))S.add(t.preloadedTraceIndex)}const I=h.flatMap((e,n)=>S.has(n)?[]:[{...v.get(n)??e,connectionName:t[n].connectionName}]);return(({candidateRoutes:t,fixedObstacleRoutes:e,obstacleMargin:n,connMap:o,candidateBounds:i})=>{for(const r of t)for(const t of e)if(!kQ(r,t,o)&&DQ({left:r,right:t,clearance:n,leftBounds:i}))return!0;return!1})({candidateRoutes:I,fixedObstacleRoutes:f,obstacleMargin:l,connMap:r,candidateBounds:g})?void 0:I},a9=({srj:t,routes:e,fixedObstacleRoutes:n,newConnections:o,syntheticConnectionNames:i,drcEvaluator:r,initialErrors:s,allowTracePairRepair:a=!1,preloadRepairTraceIds:c,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m})=>{let g=e,f=s??r1(r,g),y=0,_=0,b=0,x=0,v=!1;const S=(t=>{if(!Number.isInteger(t)||t<0)throw new Error("Pipeline9 regional repair route count must be nonnegative");const e=Math.floor(7e3/Math.max(1,t));return Math.max(16,Math.min(192,e))})(e.length),I=f.filter(t=>(({error:t,preloadRepairTraceIds:e})=>!!s1(t).some(t=>e.has(t))||(t.__collapsed_trace_participants??[]).flatMap(t=>new Set(t.evaluationTraceIds).size>1?[t.solverTraceId]:[]).some(t=>e.collidingFixedTraceIds?.has(t)))({error:t,preloadRepairTraceIds:c})).length,C=d1({routes:g,newConnections:o,syntheticConnectionNames:i}),P=a&&f.some(t=>((t,e)=>!("pcb_trace_error"!==t.type||"string"==typeof t.pcb_via_id||Array.isArray(t.pcb_via_ids)&&t.pcb_via_ids.length>0)&&2===K6({error:t,routeIndexByTraceId:e}).length)(t,C));if(0===I&&!P)return{routes:g,attemptedCandidateCount:y,acceptedCandidateCount:_,fallbackCandidateCount:b,candidateSearchCount:x,candidateSearchBudget:S,candidateSearchBudgetExhausted:v,safeTraceLayerRepairSkippedForBudget:!1,remainingDrcIssueCount:f.length,preloadEligibleDrcIssueCount:I,preloadRepairAttempted:!1};const M=(t=>{const e=new Map,n=(t,n)=>{const o=Math.floor(n.minX/4),i=Math.floor(n.maxX/4),r=Math.floor(n.minY/4),s=Math.floor(n.maxY/4);for(let n=o;n<=i;n++)for(let o=r;o<=s;o++){const i=`${n}:${o}`,r=e.get(i)??new Set;r.add(t),e.set(i,r)}};for(let e=0;e<t.length;e++){const o=EQ(t[e]);for(const t of o.wireSegments)for(const o of AQ(t,4,1))n(e,o9(o));for(const t of o.viaSpans)n(e,n9(t))}return{getRoutesOverlappingBounds:n=>{const o=new Set,i=Math.floor(n.minX/4),r=Math.floor(n.maxX/4),s=Math.floor(n.minY/4),a=Math.floor(n.maxY/4);for(let t=i;t<=r;t++)for(let n=s;n<=a;n++)for(const i of e.get(`${t}:${n}`)??[])o.add(i);return[...o].sort((t,e)=>t-e).map(e=>t[e]).filter(t=>i9(t,n))}}})(n);for(let e=0;e<2&&!v;e++){let e=!1;const s=d1({routes:g,newConnections:o,syntheticConnectionNames:i}),a=f.filter(t=>("pcb_trace_error"===t.type||"pcb_pad_trace_clearance_error"===t.type||"pcb_via_trace_clearance_error"===t.type||"pcb_via_clearance_error"===t.type)&&"string"==typeof t.pcb_trace_id);for(const o of a){if(v)break;const i=J6(o,t),a=K6({error:o,routeIndexByTraceId:s});if(!i)continue;let c=g,I=f;for(const e of a.slice(0,2)){if(v)break;const o=s.get(e);if(void 0!==o){for(const e of q6){if(x>=S){v=!0;break}x++;const s=r9({routes:g,fixedObstacleRoutes:n,routeIndex:o,center:i,regionSize:e,srj:t,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m});if(!s)continue;y++,s.usedFallback&&b++;const a=r1(r,s.routes);if(l1(a,I)&&(c=s.routes,I=a),0===I.length)break}if(0===I.length)break}}if(c!==g||v||(x>=S?v=!0:x++),c===g&&!v){const e=s9({routes:g,fixedRouteCopperSpatialIndex:M,center:i,regionSize:3,srj:t,connMap:l,colorMap:d,viaDiameter:h,traceWidth:u,obstacleMargin:p,effort:m});if(e){y++,b++;const t=r1(r,e);l1(t,I)&&(c=e,I=t)}}if(c!==g&&(g=c,f=I,_++,e=!0),v)break}if(!e||0===f.length)break}if(_>0&&f.length>0){const e=iD({...t,traces:void 0},g,m,1,l);if(e!==g){const t=r1(r,e);Q6(t)<=Q6(f)&&l1(t,f)&&(g=e,f=t)}}const N=f.some(t=>"pcb_trace_error"===t.type||"pcb_pad_trace_clearance_error"===t.type),w=N&&v;if(N&&!v){const e=new Nz({srj:{...t,traces:void 0},hdRoutes:g,connMap:l,effort:m,drcEvaluator:r,maxIterations:8,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!1,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:!1});if(e.solve(),e.failed)throw new Error(`Pipeline9 post-regional safe trace-layer repair failed: ${e.error??"unknown error"}`);const n=e.getOutput(),o=r1(r,n);l1(o,f)&&(g=n,f=o)}return{routes:g,attemptedCandidateCount:y,acceptedCandidateCount:_,fallbackCandidateCount:b,candidateSearchCount:x,candidateSearchBudget:S,candidateSearchBudgetExhausted:v,safeTraceLayerRepairSkippedForBudget:w,remainingDrcIssueCount:f.length,preloadEligibleDrcIssueCount:I,preloadRepairAttempted:I>0}},c9=[.9,.72],l9=Array.from({length:16},(t,e)=>e*Math.PI/8),d9=t=>"pcb_pad_trace_clearance_error"===t.type||"pcb_trace_error"===t.type&&!(Array.isArray(t.pcb_trace_ids)&&t.pcb_trace_ids.length>=2),h9=t=>{if("string"==typeof t.pcb_pad_id)return t.pcb_pad_id;if("string"==typeof t.pcb_trace_error_id){const e=t.pcb_trace_error_id.match(/(pcb_(?:smtpad|plated_hole|hole|keepout)_\d+)$/)?.[1];if(e)return e}const e="string"==typeof t.message?t.message:"";return e.match(/(?:pcb_smtpad|pcb_plated_hole|pcb_hole|pcb_keepout)\[#?([^\]"]+)\]/)?.[1]},u9=(t,e)=>{if(!e)return;const n=e.startsWith("pcb_")?e:`pcb_${e}`;return t.obstacles.find(t=>t.obstacleId===n||t.connectedTo[0]===n)},p9=({srj:t,pcbPortId:e,z:n,portPositionMap:o})=>{const i=vo(n,t.layerCount),r=o.get(e),s=t.obstacles.filter(t=>t.layers.includes(i)&&t.connectedTo.includes(e));return r?s.reduce((t,e)=>t?Math.hypot(e.center.x-r.x,e.center.y-r.y)<Math.hypot(t.center.x-r.x,t.center.y-r.y)?e:t:e,void 0):s[0]},m9=({terminalObstacle:t,conflictingObstacle:e,traceRadius:n})=>{const o=Math.max(0,t.width/2-n),i=Math.max(0,t.height/2-n),r=(t.ccwRotationDegrees??0)*Math.PI/180;return c9.flatMap(e=>l9.map(n=>{const s={x:Math.cos(n)*o*e,y:Math.sin(n)*i*e},a=(l=r,{x:(c=s).x*Math.cos(l)-c.y*Math.sin(l),y:c.x*Math.sin(l)+c.y*Math.cos(l)});var c,l;return{x:t.center.x+a.x,y:t.center.y+a.y}})).sort((t,n)=>Math.hypot(n.x-e.center.x,n.y-e.center.y)-Math.hypot(t.x-e.center.x,t.y-e.center.y)).slice(0,16)},g9=({routes:t,routeIndex:e,endpointIndex:n,point:o,bounds:i,collapseAdjacent:r})=>{const s=(t=>t.map(t=>({...t,route:t.route.map(t=>({...t})),vias:t.vias.map(t=>({...t}))})))(t),a=s[e];if(!a||a.route.length<2)return;const c=0===n?0:a.route.length-1,l=0===n?1:c-1,d=a.route[c],h=a.route[l];if(!d||!h||d.z!==h.z)return;const u=a.traceThickness/2;if(!(o.x-u<i.minX||o.x+u>i.maxX||o.y-u<i.minY||o.y+u>i.maxY)){if(a.route[c]={...d,...o},r){const t=0===n?l+1:l-1,e=a.route[t],i=a.vias.some(t=>t.x===h.x&&t.y===h.y);if(!e||e.z!==d.z||void 0!==h.pcb_port_id||i)return;a.route[l]={...h,...o}}return s}},f9=({srj:t,originalSrj:e,routes:n,newConnections:o,syntheticConnectionNames:i,drcEvaluator:r})=>{let s=n,a=r1(r,s),c=0,l=0;const d=(t=>{const e=new Map;for(const n of t.connections)for(const t of n.pointsToConnect)t.pcb_port_id&&e.set(t.pcb_port_id,t);return e})(e);for(let n=0;n<2;n++){let n=!1;const h=d1({routes:s,newConnections:o,syntheticConnectionNames:i});for(const o of a.filter(d9)){if(c>=256)break;if("string"!=typeof o.pcb_trace_id)continue;const i=h.get(o.pcb_trace_id),u=u9(t,h9(o));if(void 0===i||!u)continue;const p=s[i];let m=s,g=a;t:for(const n of[0,-1]){const o=0===n?p.route[0]:p.route.at(-1);if(!o||"string"!=typeof o.pcb_port_id)continue;const a=p9({srj:e,pcbPortId:o.pcb_port_id,z:o.z,portPositionMap:d});if(!a||a===u)continue;const l=Math.hypot(u.width,u.height)/2+Math.hypot(a.width,a.height)/2+.5;if(!(Math.hypot(o.x-u.center.x,o.y-u.center.y)>l))for(const e of m9({terminalObstacle:a,conflictingObstacle:u,traceRadius:p.traceThickness/2}))for(const o of[!1,!0]){if(c>=256)break t;const a=g9({routes:s,routeIndex:i,endpointIndex:n,point:e,bounds:t.bounds,collapseAdjacent:o});if(!a)continue;c++;const l=r1(r,a);l1(l,g)&&(m=a,g=l)}}m!==s&&(s=m,a=g,l++,n=!0)}if(!n||0===a.length)break}return{routes:s,attemptedCandidateCount:c,acceptedCandidateCount:l,remainingErrors:a}},y9=["pcb_trace_error_id","pcb_error_id","pcb_via_trace_clearance_error_id","pcb_pad_trace_clearance_error_id"],_9=(t,e)=>{let n=t;const o=[...e].sort(([t],[e])=>e.length-t.length);for(const[t,e]of o)n=n.replaceAll(t,e);return n},b9=(t,e)=>{const n=String(t.type??t.error_type??"unknown");if("pcb_via_clearance_error"===n)return((t,e)=>{const n=[..."string"==typeof t.pcb_trace_id?[t.pcb_trace_id]:[],...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=>"string"==typeof t):[]].map(t=>_9(t,e)).filter((t,e,n)=>n.indexOf(t)===e).sort(),o=t.center&&"object"==typeof t.center?t.center:t.pcb_center&&"object"==typeof t.pcb_center?t.pcb_center:void 0,i="number"==typeof o?.x&&"number"==typeof o.y?{x:o.x,y:o.y}:void 0,r="string"==typeof t.pcb_via_pair_net_relation?t.pcb_via_pair_net_relation:void 0;if(0!==n.length&&i&&r)return`pcb_via_clearance_error:${JSON.stringify({traceIds:n,center:i,netRelation:r})}`})(t,e);for(const o of y9){const i=t[o];if("string"==typeof i)return`${n}:${_9(i,e)}`}const o=Object.fromEntries(Object.entries(t).filter(([t,e])=>(t.endsWith("_id")||t.endsWith("_ids"))&&("string"==typeof e||Array.isArray(e))).sort(([t],[e])=>t.localeCompare(e)).map(([t,n])=>[t,"string"==typeof n?_9(n,e):n]));return`${n}:${JSON.stringify(o)}`},x9=({errors:t,baselineErrors:e,originalTraceIdByPreparedTraceId:n=new Map})=>{const o=new Set(e.filter(t=>!(t=>"string"==typeof t.pcb_trace_error_id&&t.pcb_trace_error_id.startsWith("missing_connection_"))(t)).map(t=>b9(t,new Map)));return o.delete(void 0),t.filter(t=>{const e=b9(t,n);return void 0===e||!o.has(e)})},v9=1.5,S9=({errorsWithCenters:t,traces:e,layerCount:n,defaultViaDiameter:o,connMap:i})=>{const r=(t=>t.flatMap(t=>{if("pcb_trace_error"!==t.type||!Array.isArray(t.pcb_port_ids)||t.pcb_port_ids.length<4)return[];const e=t.center;return e&&"object"==typeof e&&"x"in e&&"y"in e&&"number"==typeof e.x&&"number"==typeof e.y?[{x:e.x,y:e.y}]:[]}))(t),s=new Set;for(let t=0;t<e.length;t++){const a=e[t],c=oQ(a,t,n,o,i);r.some(t=>c.some(e=>{const n=e.route.map(t=>t.x),o=e.route.map(t=>t.y);return Math.min(...n)<=t.x+v9&&Math.max(...n)>=t.x-v9&&Math.min(...o)<=t.y+v9&&Math.max(...o)>=t.y-v9}))&&s.add(a.pcb_trace_id)}return s},I9=({routes:t,otherHdRoutes:e,obstacles:n,colorMap:o,layerCount:i,connMap:r})=>{const s=IK([...t,...e],r),a=new tc({inputHdRoutes:t,otherHdRoutes:e,netByConnectionName:s,obstacles:n,colorMap:o,layerCount:i,connMap:r});if(a.solve(),a.failed)throw new Error(`Pipeline9 could not merge movable preloaded vias: ${a.error??"unknown error"}`);return a.getMergedViaHdRoutes()??t},C9=({errors:t,circuitJson:e,newTraceIds:n})=>{const o=new Map(e.flatMap(t=>"pcb_via"===t.type&&"string"==typeof t.pcb_via_id&&"string"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.map(t=>{const e="string"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,i=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=>"string"==typeof t):[],r=[..."string"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=>"string"==typeof t):[]].filter((t,e,n)=>n.indexOf(t)===e);if(e&&"string"==typeof t.pcb_trace_error_id){const s=`overlap_${e}_`,a=t.pcb_trace_error_id.startsWith(s)?t.pcb_trace_error_id.slice(s.length):void 0,c=void 0!==a&&(r.includes(a)||o.has(a)&&!i.includes(a)),l=i.find(t=>t!==e&&n.has(t))??(a&&!c?a:void 0);if(!n.has(e)&&0===r.length&&l&&n.has(l)){const n=[l,e,...i].filter((t,e,n)=>n.indexOf(t)===e);return{...t,pcb_trace_id:l,pcb_trace_ids:n,pcb_trace_error_id:`overlap_${l}_${e}`}}}const s=r.flatMap(t=>{const e=o.get(t);return e?[e]:[]}).filter((t,e,n)=>n.indexOf(t)===e),a=s.length>0?s:i.filter(t=>t!==e),c=a.find(t=>n.has(t));if(c&&(!e||!n.has(e))){const n=[c,...e?[e]:[],...i,...a].filter((t,e,n)=>n.indexOf(t)===e);return{...t,pcb_trace_id:c,pcb_trace_ids:n,pcb_via_id:r[0],pcb_via_ids:r}}if(r.length>0){const n=[...e?[e]:[],...i,...a].filter((t,e,n)=>n.indexOf(t)===e);return{...t,pcb_trace_ids:n,pcb_via_id:r[0],pcb_via_ids:r}}return t})},P9=1e-9,M9=t=>{const e=new Set,n=[];for(const o of t)for(const t of o.route){if("via"!==t.route_type)continue;const i=`${t.x},${t.y},${t.from_layer},${t.to_layer}`;e.has(i)||(e.add(i),n.push({type:"pcb_via",pcb_via_id:`via_${n.length}`,pcb_trace_id:o.pcb_trace_id}))}return n},N9=({errors:t,circuitJson:e,evaluatedTraceIds:n})=>{const o=new Map(e.flatMap(t=>"pcb_via"===t.type&&"string"==typeof t.pcb_via_id&&"string"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.map(t=>{const e=[..."string"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=>"string"==typeof t):[]],i="string"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,r=i?`overlap_${i}_`:void 0,s=r&&"string"==typeof t.pcb_trace_error_id&&t.pcb_trace_error_id.startsWith(r)?t.pcb_trace_error_id.slice(r.length):void 0,a="string"==typeof t.pcb_trace_error_id?t.pcb_trace_error_id.match(/_(via_\d+)$/)?.[1]:void 0,c=0!==e.length||!a||!o.has(a)||s&&n.has(s)?void 0:a,l=[...e,...c?[c]:[]].filter((t,e,n)=>n.indexOf(t)===e),d=[..."string"==typeof t.pcb_trace_id?[t.pcb_trace_id]:[],...Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=>"string"==typeof t):[],...l.flatMap(t=>{const e=o.get(t);return e?[e]:[]})].filter((t,e,n)=>n.indexOf(t)===e);return{...t,...l.length>0?{pcb_via_id:l[0],pcb_via_ids:l}:{},...l.length>0&&d.length>0?{pcb_trace_ids:d}:{}}})},w9=(t,e)=>Math.abs(t.x-e.x)<=P9&&Math.abs(t.y-e.y)<=P9&&t.z===e.z,T9=({trace:t,sectionGroup:e,syntheticConnectionName:n,connMap:o})=>{const i=e.routes;if(0===i.length)throw new Error(`Pipeline9 cannot exactly repair empty preloaded section for trace "${t.pcb_trace_id}"`);const r=[];for(const e of i){if(0===r.length){r.push(...e.route);continue}const n=r.at(-1);if(e.route[0]&&w9(n,e.route[0]))r.push(...e.route.slice(1));else{if(!e.route.at(-1)||!w9(n,e.route.at(-1)))throw new Error(`Pipeline9 cannot reconnect preloaded trace "${t.pcb_trace_id}" for exact repair`);r.push(...e.route.slice(0,-1).reverse())}}const s=0===e.routePositionStart,a=e.routePositionEnd===t.route.length-1,c=s?t.connectsTo?.[0]:null,l=a?t.connectsTo?.at(-1):null;return c&&r[0]&&(r[0]={...r[0],pcb_port_id:c}),l&&r.at(-1)&&(r[r.length-1]={...r.at(-1),pcb_port_id:l}),{connectionName:n,rootConnectionName:o.getNetConnectedToId(t.connection_name)??t.connection_name,traceThickness:Math.max(...i.map(t=>t.traceThickness)),viaDiameter:Math.max(...i.map(t=>t.viaDiameter)),route:r,vias:r.slice(0,-1).flatMap((t,e)=>{const n=r[e+1];return t.z!==n.z&&(o=t,i=n,Math.abs(o.x-i.x)<=P9&&Math.abs(o.y-i.y)<=P9)?[{x:n.x,y:n.y}]:[];var o,i})}},R9=({trace:t,traceIndex:e,layerCount:n,defaultViaDiameter:o,connMap:i})=>{const r=t.route.flatMap((t,e)=>"through_obstacle"===t.route_type?[e]:[]),s=new Map,a=oQ(t,e,n,o,i);for(const e of a){const n=e.preloadedRoutePositionStart,o=e.preloadedRoutePositionEnd;if(void 0===n||void 0===o)throw new Error(`Pipeline9 preloaded trace section is missing route positions for "${t.pcb_trace_id}"`);if("through_obstacle"===t.route[n]?.route_type)continue;const i=r.filter(t=>t<n).length,a=s.get(i)??{routePositionStart:n,routePositionEnd:o,routes:[]};a.routePositionStart=Math.min(a.routePositionStart,n),a.routePositionEnd=Math.max(a.routePositionEnd,o),a.routes.push(e),s.set(i,a)}return[...s.values()]},E9=(t,e)=>t.map(t=>{const n=Array.isArray(t.pcb_trace_ids)?t.pcb_trace_ids.filter(t=>"string"==typeof t):[],o="string"==typeof t.pcb_trace_id?t.pcb_trace_id:void 0,i=o?`overlap_${o}_`:void 0,r=i&&"string"==typeof t.pcb_trace_error_id&&t.pcb_trace_error_id.startsWith(i)?t.pcb_trace_error_id.slice(i.length):void 0,s=[..."string"==typeof t.pcb_via_id?[t.pcb_via_id]:[],...Array.isArray(t.pcb_via_ids)?t.pcb_via_ids.filter(t=>"string"==typeof t):[]],a=void 0!==r&&s.includes(r),c=[o,...n,a?void 0:r].filter(t=>"string"==typeof t),l=new Map;for(const t of c){const n=e.get(t)??t,o=l.get(n)??new Set;o.add(t),l.set(n,o)}const d=[...l].flatMap(([t,e])=>e.size>1?[{solverTraceId:t,evaluationTraceIds:[...e]}]:[]),h=o?e.get(o)??o:void 0,u=n.map(t=>e.get(t)??t),p=r?a?r:e.get(r)??r:void 0;return h!==o||u.some((t,e)=>t!==n[e])||p!==r?{...t,...o?{pcb_trace_id:h}:{},...Array.isArray(t.pcb_trace_ids)?{pcb_trace_ids:u}:{},...h&&p?{pcb_trace_error_id:`overlap_${h}_${p}`}:{},...d.length>0?{__collapsed_trace_participants:d}:{}}:t}),A9=(t,e)=>{const n=t.hdRoute.route[0],o=t.hdRoute.route.at(-1);return{name:t.syntheticConnectionName,rootConnectionName:t.hdRoute.rootConnectionName,__netConnectionName:t.originalTrace.connection_name,nominalTraceWidth:t.hdRoute.traceThickness,pointsToConnect:[{x:n.x,y:n.y,layer:vo(n.z,e),pointId:`${t.syntheticConnectionName}:start`},{x:o.x,y:o.y,layer:vo(o.z,e),pointId:`${t.syntheticConnectionName}:end`}]}},O9=({originalTrace:t,repairedSections:e})=>{const n=[];let o=0;for(const i of[...e].sort((t,e)=>t.routePositionStart-e.routePositionStart)){if(i.routePositionStart<o)throw new Error(`Pipeline9 found overlapping repaired sections for preloaded trace "${t.pcb_trace_id}"`);n.push(...t.route.slice(o,i.routePositionStart),...i.route),o=i.routePositionEnd+1}return n.push(...t.route.slice(o)),{...t,__replaces_pcb_trace_id:t.pcb_trace_id,route:n}},k9=class extends si{params;inputNewHdRoutes;inputUpdatedPreloadedTraces;movablePreloadedSections;fixedPreloadedObstacleRoutes;syntheticConnectionNames;exactRepairSolver;drcEvaluator;cachedReferenceDrcEvaluator;clearancePrecisionDrcEvaluator;clearancePrecisionIndexedDrcEvaluator;clearanceMarginDrcEvaluator;referenceDrcValidationCount=0;referenceDrcFalseNegativeCount=0;indexedDrcEvaluationCount=0;indexedDrcCacheHitCount=0;indexedDrcEvaluationTimeMs=0;indexedDrcCandidateCache=new Map;combinedOutput;cacheIndexedDrcResult(t,e){if(this.indexedDrcCandidateCache.size>=64){const t=this.indexedDrcCandidateCache.keys().next().value;void 0!==t&&this.indexedDrcCandidateCache.delete(t)}this.indexedDrcCandidateCache.set(t,e)}constructor(t){super(),this.params=t,this.inputNewHdRoutes=t.newHdRoutes,this.inputUpdatedPreloadedTraces=t.updatedPreloadedTraces;const e=t.updatedPreloadedTraces.filter(e=>t.mutatedPreloadedTraceIds.has(e.pcb_trace_id)),n=ZJ({connections:t.newConnections,originalConnections:t.originalSrj.connections,layerCount:t.layerCount,obstacles:t.obstacles,defaultViaHoleDiameter:t.defaultViaHoleDiameter,connMap:t.connMap}),o=n(t.newHdRoutes),i=new Set(o.map(t=>t.pcb_trace_id)),r=(({originalPreloadedTraces:t,mutatedPreloadedTraces:e,newTraces:n})=>{const o=new Set(n.map(t=>t.pcb_trace_id)),i=new Map(e.map(t=>[t.pcb_trace_id,t])),r=new Set([...t.map(t=>t.pcb_trace_id),...o]),s=new Map;return{routedTraces:[...t.filter(t=>o.has(t.pcb_trace_id)).map(t=>{const e=i.get(t.pcb_trace_id)??t,n=`${t.pcb_trace_id}_preloaded`;let o=n,a=2;for(;r.has(o);)o=`${n}_${a}`,a+=1;return r.add(o),s.set(o,t.pcb_trace_id),{...e,pcb_trace_id:o,__replaces_pcb_trace_id:t.pcb_trace_id}}),...e.filter(t=>!o.has(t.pcb_trace_id)),...n],originalPreloadedTraceIdByPreparedTraceId:s}})({originalPreloadedTraces:t.originalSrj.traces??[],mutatedPreloadedTraces:e,newTraces:o}),s=t.originalSrj.minTraceToPadEdgeClearance??V0.traceClearance??.1,a=V0.viaClearance??.1,c=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:[],drcOptions:{traceClearance:s}}),l=new Set((t.originalSrj.traces??[]).map(t=>t.pcb_trace_id)),d=N9({errors:c.errors,circuitJson:c.circuitJson,evaluatedTraceIds:l}),h=N9({errors:c.errorsWithCenters,circuitJson:c.circuitJson,evaluatedTraceIds:l}),u=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:r.routedTraces,drcOptions:{traceClearance:s}}),p=new Set(o1(t.originalSrj.traces??[],r.routedTraces).map(t=>t.pcb_trace_id)),m=N9({errors:u.errors,circuitJson:u.circuitJson,evaluatedTraceIds:p}),g=N9({errors:u.errorsWithCenters,circuitJson:u.circuitJson,evaluatedTraceIds:p}),f={...u,errors:x9({errors:m,baselineErrors:d,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId}),errorsWithCenters:x9({errors:g,baselineErrors:h,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId})},y=(({errors:t,circuitJson:e})=>{const n=new Map(e.flatMap(t=>"pcb_via"===t.type&&"string"==typeof t.pcb_via_id&&"string"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[])),o=new Set;for(const e of t){const t="string"==typeof e.pcb_trace_id?e.pcb_trace_id:void 0,i=[..."string"==typeof e.pcb_via_id?[e.pcb_via_id]:[],...Array.isArray(e.pcb_via_ids)?e.pcb_via_ids.filter(t=>"string"==typeof t):[]];if("string"==typeof e.pcb_trace_id&&o.add(e.pcb_trace_id),Array.isArray(e.pcb_trace_ids))for(const t of e.pcb_trace_ids)"string"==typeof t&&o.add(t);if("string"==typeof e.pcb_via_id){const t=n.get(e.pcb_via_id);t&&o.add(t)}if(Array.isArray(e.pcb_via_ids))for(const t of e.pcb_via_ids){if("string"!=typeof t)continue;const e=n.get(t);e&&o.add(e)}const r=t?`overlap_${t}_`:void 0;if(r&&"string"==typeof e.pcb_trace_error_id&&e.pcb_trace_error_id.startsWith(r)){const t=e.pcb_trace_error_id.slice(r.length);i.includes(t)||o.add(t)}}return o})({errors:f.errors,circuitJson:f.circuitJson}),_=new Map(t.updatedPreloadedTraces.map(t=>[t.pcb_trace_id,t])),b=new Set;for(const t of y){const e=r.originalPreloadedTraceIdByPreparedTraceId.get(t);e&&_.has(e)?b.add(e):!i.has(t)&&_.has(t)&&b.add(t)}for(const e of S9({errorsWithCenters:f.errorsWithCenters,traces:t.updatedPreloadedTraces,layerCount:t.layerCount,defaultViaDiameter:t.defaultViaDiameter,connMap:t.connMap}))b.add(e);this.movablePreloadedSections=[];for(const e of b){const n=_.get(e);if(!n)throw new Error(`Pipeline9 cannot find preloaded trace "${e}" selected for exact repair`);const o=t.updatedPreloadedTraces.findIndex(t=>t.pcb_trace_id===e),i=R9({trace:n,traceIndex:o,layerCount:t.layerCount,defaultViaDiameter:t.defaultViaDiameter,connMap:t.connMap});for(const[e,o]of i.entries()){const i=`pipeline9_preloaded_drc_${this.movablePreloadedSections.length}`;this.movablePreloadedSections.push({originalTrace:n,originalRoutePositionStart:o.routePositionStart,originalRoutePositionEnd:o.routePositionEnd,syntheticConnectionName:i,evaluationTraceId:`${n.pcb_trace_id}__pipeline9_section_${e}`,hdRoute:T9({trace:n,sectionGroup:o,syntheticConnectionName:i,connMap:t.connMap})})}}this.syntheticConnectionNames=new Set(this.movablePreloadedSections.map(t=>t.syntheticConnectionName));const x=new Set(this.movablePreloadedSections.map(t=>t.originalTrace.pcb_trace_id));this.fixedPreloadedObstacleRoutes=t.updatedPreloadedTraces.flatMap((e,n)=>{const o=oQ(e,n,t.layerCount,t.defaultViaDiameter,t.connMap);return x.has(e.pcb_trace_id)?o.filter(t=>{const n=t.preloadedRoutePositionStart;return void 0!==n&&"through_obstacle"===e.route[n]?.route_type}):o});const v=new Map;for(const[t,e]of this.movablePreloadedSections.entries()){const n=e.originalTrace.pcb_trace_id,o=v.get(n)??[];o.push(t),v.set(n,o)}for(const e of(({errors:t,circuitJson:e,originalTraceIdByPreparedTraceId:n})=>{const o=new Map(e.flatMap(t=>"pcb_via"===t.type&&"string"==typeof t.pcb_via_id&&"string"==typeof t.pcb_trace_id?[[t.pcb_via_id,t.pcb_trace_id]]:[]));return t.flatMap(t=>{if("pcb_via_clearance_error"!==t.type||!Array.isArray(t.pcb_via_ids)||"number"!=typeof t.actual_clearance||t.actual_clearance>=0)return[];const e=t.pcb_via_ids.flatMap(t=>{if("string"!=typeof t)return[];const e=o.get(t);return e?[n.get(e)??e]:[]}).filter((t,e,n)=>n.indexOf(t)===e);return e.length>0?[e]:[]})})({errors:f.errors,circuitJson:f.circuitJson,originalTraceIdByPreparedTraceId:r.originalPreloadedTraceIdByPreparedTraceId})){const n=e.flatMap(t=>v.get(t)??[]).filter((t,e,n)=>n.indexOf(t)===e);if(0===n.length)continue;const o=new Set(n),i=I9({routes:n.map(t=>this.movablePreloadedSections[t].hdRoute),otherHdRoutes:[...t.newHdRoutes,...this.fixedPreloadedObstacleRoutes,...this.movablePreloadedSections.flatMap((t,e)=>o.has(e)?[]:[t.hdRoute])],obstacles:t.obstacles,colorMap:t.colorMap,layerCount:t.layerCount,connMap:t.connMap});for(let t=0;t<n.length;t++)this.movablePreloadedSections[n[t]].hdRoute=i[t]}if(this.stats={initialJointDrcIssueCount:f.errors.length,baselineJointDrcIssueCount:c.errors.length,initialJointDrcIssueCountByType:f.errors.reduce((t,e)=>{const n=String(e.type??e.error_type??"unknown");return t[n]=(t[n]??0)+1,t},{}),movablePreloadedTraceCount:x.size,movablePreloadedSectionCount:this.movablePreloadedSections.length,exactRepairConfiguredMaxIterations:32,exactRepairConfiguredViaInPadMaxIterations:32,exactRepairConfiguredBroadMaxIterations:12},0===f.errors.length)return void(this.solved=!0);const S=new Set(this.movablePreloadedSections.map(t=>t.originalTrace.pcb_trace_id)),I=e.filter(t=>!S.has(t.pcb_trace_id)),C=new Map(this.movablePreloadedSections.map(e=>[e.syntheticConnectionName,A9(e,t.layerCount)])),{traces:P,...M}=t.srjWithPointPairs,N={...M,connections:[...t.srjWithPointPairs.connections,...C.values()]},w=new s_({...N,obstacles:t.originalSrj.obstacles,minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter??t.defaultViaDiameter},{connMap:t.connMap,traceClearance:s,viaClearance:a,includeTraceViaOwnerMetadata:!0,spatialCellSize:Math.max(t.defaultViaDiameter,t.originalSrj.minTraceWidth)+Math.max(s,a)}),T=w.evaluate(t.originalSrj.traces??[]),R=M9(t.originalSrj.traces??[]),E={...T,errors:N9({errors:T.errors,circuitJson:R,evaluatedTraceIds:l}),errorsWithCenters:N9({errors:T.errorsWithCenters,circuitJson:R,evaluatedTraceIds:l})};let A;const O=e=>{const o=e.filter(t=>!this.syntheticConnectionNames.has(t.connectionName)),i=n(o),r=vK(i,t.originalSrj.traces??[]),s=new Set,a=new Map,c=this.movablePreloadedSections.map(n=>{const o=e.find(t=>t.connectionName===n.syntheticConnectionName);if(!o)throw new Error(`Pipeline9 joint DRC repair lost preloaded section "${n.syntheticConnectionName}"`);const i=n.originalTrace.pcb_trace_id;a.set(n.evaluationTraceId,i);const r=!s.has(i);return s.add(i),{...n.originalTrace,pcb_trace_id:n.evaluationTraceId,...r?{__replaces_pcb_trace_id:i}:{__replaces_pcb_trace_id:void 0},route:Mo(o,t.layerCount,{defaultViaHoleDiameter:t.defaultViaHoleDiameter,obstacles:t.obstacles,connMap:t.connMap})}}),l=new Map;for(let t=0;t<i.length;t++)l.set(r[t].pcb_trace_id,i[t].pcb_trace_id);for(const t of this.movablePreloadedSections)l.set(t.evaluationTraceId,`${t.syntheticConnectionName}_0`);const d=new Set(l.values()),h=[...I,...c,...r];return{evaluatedTraces:o1(t.originalSrj.traces??[],h),movableTraceIds:d,originalTraceIdByEvaluationTraceId:a,routedTraces:h,solverTraceIdByEvaluationTraceId:l}},k=({errors:t,errorsWithCenters:e,circuitJson:n,movableTraceIds:o,solverTraceIdByEvaluationTraceId:i})=>{const r=n.map(t=>{if(!("pcb_trace_id"in t)||"string"!=typeof t.pcb_trace_id)return t;const e=i.get(t.pcb_trace_id);return e?{...t,pcb_trace_id:e}:t});return{errors:C9({errors:E9(t,i),circuitJson:r,newTraceIds:o}),errorsWithCenters:C9({errors:E9(e,i),circuitJson:r,newTraceIds:o})}},L=({routes:e,hdRoutes:n},o=!0)=>{const i=e??n;if(!i)throw new Error("Pipeline9 reference DRC repair requires HD routes");const r=O(i),a=i1({inputSrj:t.originalSrj,srjWithPointPairs:t.srjWithPointPairs,routedTraces:r.routedTraces,drcOptions:{traceClearance:s,includeTraceContinuity:o}}),c=new Set(r.evaluatedTraces.map(t=>t.pcb_trace_id)),l=N9({errors:a.errors,circuitJson:a.circuitJson,evaluatedTraceIds:c}),u=N9({errors:a.errorsWithCenters,circuitJson:a.circuitJson,evaluatedTraceIds:c}),p=x9({errors:l,baselineErrors:d,originalTraceIdByPreparedTraceId:r.originalTraceIdByEvaluationTraceId}),m=x9({errors:u,baselineErrors:h,originalTraceIdByPreparedTraceId:r.originalTraceIdByEvaluationTraceId});return k({errors:p,errorsWithCenters:m,circuitJson:a.circuitJson,movableTraceIds:r.movableTraceIds,solverTraceIdByEvaluationTraceId:r.solverTraceIdByEvaluationTraceId})},D=({routes:t,hdRoutes:e})=>{const n=t??e;if(!n)throw new Error("Pipeline9 cached reference DRC requires HD routes");const o=JSON.stringify(n);if(A?.candidateKey===o)return A.result;this.referenceDrcValidationCount+=1;const i=L({traces:[],routes:n,hdRoutes:n});return A={candidateKey:o,result:i},i};this.cachedReferenceDrcEvaluator=D,this.clearancePrecisionDrcEvaluator=({routes:t,hdRoutes:e})=>L({traces:[],routes:t,hdRoutes:e},!1);const z=e=>{const n=O(e);return n1(t.srjWithPointPairs,n.routedTraces,{minTraceWidth:t.originalSrj.minTraceWidth,minViaDiameter:t.originalSrj.minViaDiameter,originalSrj:t.originalSrj,includeOriginalConnections:!0})};let F;this.clearanceMarginDrcEvaluator=(t,e,n)=>(F?.routes!==n&&(F={routes:n,circuitJson:z(n)}),(({circuitJson:t,originalCircuitJson:e,targets:n})=>{const o=new Map(t.filter(t=>"pcb_trace"===t.type).map(t=>[t.pcb_trace_id,t])),i=new Map(e.filter(t=>"pcb_trace"===t.type).map(t=>[t.pcb_trace_id,t])),r=t.filter(t=>"pcb_via"===t.type),s=new Map;for(const e of t)"pcb_via"===e.type?s.set(e.pcb_via_id,e):"pcb_smtpad"===e.type?s.set(e.pcb_smtpad_id,e):"pcb_plated_hole"===e.type&&s.set(e.pcb_plated_hole_id,e);const a=[];for(const t of n){const n="pcb_via_trace_clearance_error"===t.type,c=n?t.pcb_via_id:t.pcb_pad_id;if(!n&&"pcb_pad_trace_clearance_error"!==t.type||"string"!=typeof t.pcb_trace_id||"string"!=typeof c||"number"!=typeof t.minimum_clearance||!Number.isFinite(t.minimum_clearance)||t.minimum_clearance<=0)throw new Error("Pipeline9 clearance margin requires a valid target pair");const l=i.get(t.pcb_trace_id),d=e.find(t=>n?"pcb_via"===t.type&&t.pcb_via_id===c:"pcb_smtpad"===t.type&&t.pcb_smtpad_id===c||"pcb_plated_hole"===t.type&&t.pcb_plated_hole_id===c);if(!l||!d)throw new Error(`Pipeline9 clearance margin has no original target ${c}/${t.pcb_trace_id}`);const h=o.get(t.pcb_trace_id);let u=s.get(c);if(n){if("pcb_via"!==d.type||"string"!=typeof d.pcb_trace_id)throw new Error("Pipeline9 clearance margin requires the original via owner");const t=i.get(d.pcb_trace_id);if(!t)throw new Error("Pipeline9 clearance margin lost the original via owner");const e=t.route.filter(t=>"via"===t.route_type),n=e.map((t,e)=>({segment:t,index:e})).filter(({segment:t})=>t.x===d.x&&t.y===d.y&&d.layers.includes(t.from_layer)&&d.layers.includes(t.to_layer)&&(t.from_layer===d.layers[0]&&t.to_layer===d.layers.at(-1)||t.to_layer===d.layers[0]&&t.from_layer===d.layers.at(-1))).filter(({segment:t},e,n)=>n.findIndex(e=>e.segment.from_layer===t.from_layer&&e.segment.to_layer===t.to_layer)===e);if(0===n.length)throw new Error("Pipeline9 clearance margin lost the original via transition");if(1!==n.length)return{status:"unsupported-identity"};const s=n[0].index,a=o.get(d.pcb_trace_id),c=a?.route.filter(t=>"via"===t.route_type);if(!c||c.length!==e.length||c.some((t,n)=>t.from_layer!==e[n].from_layer||t.to_layer!==e[n].to_layer))return{status:"unsupported-identity"};const l=c[s];u=r.filter(t=>t.x===l.x&&t.y===l.y&&t.layers.join()===d.layers.join()).reduce((t,e)=>!t||e.outer_diameter>t.outer_diameter?e:t,void 0)}if(!(h&&u&&"x"in u&&"y"in u))return{status:"unsupported-identity"};const p={minClearance:t.minimum_clearance+1},m=n?Y0([h,u],p):$0([h,u],p),g=t.minimum_clearance+.01;for(const e of m){const n=e.actual_clearance;if("number"!=typeof n||!Number.isFinite(n))throw new Error("Pipeline9 clearance margin requires a finite measurement");n>=g||a.push({...t,..."pcb_via"===u.type?{pcb_via_id:u.pcb_via_id,pcb_via_ids:[u.pcb_via_id]}:{},actual_clearance:n,minimum_clearance:g,center:{x:u.x,y:u.y}})}}return{status:"measured",errors:a}})({circuitJson:z(t),originalCircuitJson:F.circuitJson,targets:e})),this.clearancePrecisionIndexedDrcEvaluator=({routes:t,hdRoutes:e})=>{const n=t??e;if(!n)throw new Error("Pipeline9 clearance ranking requires HD routes");const o=O(n);return w.evaluate(o.evaluatedTraces)};const B=({routes:t,hdRoutes:e})=>{const n=t??e;if(!n)throw new Error("Pipeline9 joint DRC repair requires HD routes");const o=JSON.stringify(n),i=this.indexedDrcCandidateCache.get(o);if(void 0!==i)return this.indexedDrcCacheHitCount+=1,i;const r=performance.now();this.indexedDrcEvaluationCount+=1;const s=O(n),a=w.evaluate(s.evaluatedTraces),c=M9(s.evaluatedTraces),l=new Set(s.evaluatedTraces.map(t=>t.pcb_trace_id)),d=N9({errors:a.errors,circuitJson:c,evaluatedTraceIds:l}),h=N9({errors:a.errorsWithCenters,circuitJson:c,evaluatedTraceIds:l}),u=x9({errors:d,baselineErrors:E.errors,originalTraceIdByPreparedTraceId:s.originalTraceIdByEvaluationTraceId}),p=x9({errors:h,baselineErrors:E.errorsWithCenters,originalTraceIdByPreparedTraceId:s.originalTraceIdByEvaluationTraceId});if(0===u.length){const t=this.referenceDrcValidationCount,e=D({traces:[],routes:n,hdRoutes:n}),i=Array.isArray(e)?e:e.errors;return this.referenceDrcValidationCount>t&&i.length>0&&(this.referenceDrcFalseNegativeCount+=1),this.indexedDrcEvaluationTimeMs+=performance.now()-r,this.cacheIndexedDrcResult(o,e),e}const m=k({errors:u,errorsWithCenters:p,circuitJson:c,movableTraceIds:s.movableTraceIds,solverTraceIdByEvaluationTraceId:s.solverTraceIdByEvaluationTraceId});return this.indexedDrcEvaluationTimeMs+=performance.now()-r,this.cacheIndexedDrcResult(o,m),m};this.drcEvaluator=B,this.exactRepairSolver=new wz({srj:N,hdRoutes:[...t.newHdRoutes,...this.movablePreloadedSections.map(t=>t.hdRoute)],connMap:t.connMap,effort:t.effort,viaHoleDiameter:t.defaultViaHoleDiameter,drcEvaluator:B,viaInPadDrcEvaluator:B,maxIterations:32,enableBroadFallback:!1,enableLargeBoardBroadFallback:!1,enableTargetedErrorSweep:!0,enableTraceViaOwnerTargeting:!0,enablePostSolveClearanceRelaxation:!1,enableSafeTraceLayerMoves:!0,enableViaInPadLayerMoves:t.originalSrj.allowViaInPad??!1,viaInPadMaxIterations:32,broadMaxIterations:12,broadPassMultiplier:3}),this.activeSubSolver=this.exactRepairSolver,this.MAX_ITERATIONS=this.exactRepairSolver.MAX_ITERATIONS+1}getSolverName(){return"Pipeline9JointDrcRepairSolver"}_step(){if(!this.exactRepairSolver)return void(this.solved=!0);if(this.exactRepairSolver.step(),this.progress=this.exactRepairSolver.progress,this.exactRepairSolver.failed)return this.failed=!0,void(this.error=this.exactRepairSolver.error);if(!this.exactRepairSolver.solved)return;let t=this.exactRepairSolver.getOutput();const e=this.exactRepairSolver.stats.finalDrcIssueCount,n="number"==typeof e&&Number.isFinite(e)&&e>=0?e:void 0;let o,i=0,r=0,s=0,a=!1;const c=this.cachedReferenceDrcEvaluator({traces:[],routes:t,hdRoutes:t}),l=Array.isArray(c)?c:c.errors;if(o=l.length,l.length>0){const e=(({srj:t,routes:e,newConnections:n,syntheticConnectionNames:o,connMap:i,indexedDrcEvaluator:r,candidateDrcEvaluator:s,marginDrcEvaluator:a,drcEvaluator:c,initialErrors:l,initialErrorsWithCenters:d=l})=>{const h={routes:e,attemptedCandidateCount:0,candidateValidationCount:0,referenceValidationCount:0,repaired:!1};if((t.traces?.length??0)>0||o.size>0)return h;if(0===l.length)return h;const u=d1({routes:e,newConnections:n,syntheticConnectionNames:o}),p=new Map;for(const e of t.obstacles)for(const t of[e.obstacleId,e.circuitJsonMetadata?.pcb_smtpad_id,e.circuitJsonMetadata?.pcb_plated_hole_id,e.connectedTo[0]])"string"==typeof t&&p.set(t,e.center);const m=p1({errors:l,errorsWithCenters:d,routeIndexByTraceId:u,padPositionById:p});if(!m)return h;let g=m;const f=m.errors,y=m.errors.map(t=>({...t,minimum_clearance:t.minimum_clearance+.01})),_=u1(y);if(void 0===_)return h;let b={errors:y,deficit:_},x=e,v=0,S=0,I=0;for(let n=0;n<8;n++){const n=new Map;for(const t of[...b.errors,...g.errors]){const e=JSON.stringify([t.type,t.pcb_trace_id,t.pcb_pad_id,t.pcb_via_id]);n.set(e,t)}const o=[...n.values()];let l;for(const e of h1){const n=kk(x);if(!$D(t,n,o,u,e,i,!0,!0,!0,!1))continue;const s=aD(n);v++;const a=r({traces:[],routes:s,hdRoutes:s}),c=u1(Array.isArray(a)?a:a.errors);void 0!==c&&(!l||c<l.deficit)&&(l={routes:s,deficit:c})}if(!l)break;S++;const d=s({traces:[],routes:l.routes,hdRoutes:l.routes}),h=Array.isArray(d)?d:d.errors,m=p1({errors:h,errorsWithCenters:Array.isArray(d)?d:d.errorsWithCenters??d.errors,routeIndexByTraceId:u,padPositionById:p});if(!m)break;const y=a(l.routes,f,e);if("unsupported-identity"===y.status)break;const _=y.errors,C=p1({errors:_,errorsWithCenters:_,routeIndexByTraceId:u,padPositionById:p});if(!C)break;if(0===h.length&&0===_.length){I++;const t=c({traces:[],routes:l.routes,hdRoutes:l.routes});if(0===(Array.isArray(t)?t:t.errors).length)return{routes:l.routes,attemptedCandidateCount:v,candidateValidationCount:S,referenceValidationCount:I,repaired:!0};break}if(m.deficit+C.deficit>=g.deficit+b.deficit-1e-9)break;x=l.routes,g=m,b=C}return{routes:e,attemptedCandidateCount:v,candidateValidationCount:S,referenceValidationCount:I,repaired:!1}})({srj:this.params.srj,routes:t,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,connMap:this.params.connMap,indexedDrcEvaluator:this.clearancePrecisionIndexedDrcEvaluator,candidateDrcEvaluator:this.clearancePrecisionDrcEvaluator,marginDrcEvaluator:this.clearanceMarginDrcEvaluator,drcEvaluator:this.cachedReferenceDrcEvaluator,initialErrors:l,initialErrorsWithCenters:Array.isArray(c)?c:c.errorsWithCenters??c.errors});i=e.attemptedCandidateCount,r=e.candidateValidationCount,s=e.referenceValidationCount,a=e.repaired,e.repaired&&(t=e.routes,o=0)}if(0===o)return this.combinedOutput=t,this.stats={...this.stats,...this.exactRepairSolver.stats,postExactIndexedDrcIssueCount:n,postExactReferenceValidationAttempted:!0,postExactReferenceDrcIssueCount:0,postExactReferenceAccepted:!0,clearancePrecisionCandidateCount:i,clearancePrecisionCandidateValidationCount:r,clearancePrecisionReferenceValidationCount:s,clearancePrecisionRepaired:a,boundedRegionalRepairAttemptedRegionCount:0,boundedRegionalRepairAcceptedRegionCount:0,boundedRegionalRepairCandidateAttemptCount:0,boundedRegionalRepairPathSearchNodeCount:0,boundedRegionalRepairReferenceValidationCount:0,boundedRegionalRepairRepaired:!1,boundedRegionalRepairTimeMs:0,regionalB01RepairCandidateCount:0,regionalB01RepairAcceptedCount:0,regionalB01RepairFallbackCandidateCount:0,regionalB01RepairCandidateSearchCount:0,regionalB01RepairCandidateSearchBudget:0,regionalB01RepairCandidateSearchBudgetExhausted:!1,regionalB01RepairSafeTraceLayerSkippedForBudget:!1,regionalB01RepairRemainingDrcIssueCount:0,regionalB01RepairPreloadEligibleDrcIssueCount:0,regionalB01RepairAttempted:!1,regionalB01RepairTraceIdCount:0,terminalEscapeCandidateCount:0,terminalEscapeAcceptedCount:0,referenceDrcValidationCount:this.referenceDrcValidationCount,referenceDrcFalseNegativeCount:this.referenceDrcFalseNegativeCount,indexedDrcEvaluationCount:this.indexedDrcEvaluationCount,indexedDrcCacheHitCount:this.indexedDrcCacheHitCount,indexedDrcEvaluationTimeMs:this.indexedDrcEvaluationTimeMs,indexedDrcCandidateCacheSize:this.indexedDrcCandidateCache.size,indexedDrcCandidateCacheCapacity:64},void(this.solved=!0);const d=f9({srj:this.params.srj,originalSrj:this.params.originalSrj,routes:t,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.drcEvaluator}),h=(({routes:t,newConnections:e,syntheticConnectionNames:n,fixedPreloadedObstacleRoutes:o,updatedPreloadedTraces:i})=>{const r=new Set,s=Object.assign(new Set,{collidingFixedTraceIds:r}),a=d1({routes:t,newConnections:e,syntheticConnectionNames:n}),c=new Set;for(const[e,o]of a)n.has(t[o].connectionName)?s.add(e):c.add(e);for(const t of o){const e=i[t.preloadedTraceIndex];if(!e)throw new Error(`Pipeline9 fixed preload route has invalid trace index ${t.preloadedTraceIndex}`);c.has(e.pcb_trace_id)?r.add(e.pcb_trace_id):s.add(e.pcb_trace_id)}return s})({routes:d.routes,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,fixedPreloadedObstacleRoutes:this.fixedPreloadedObstacleRoutes,updatedPreloadedTraces:this.params.updatedPreloadedTraces}),u=a9({srj:this.params.srj,routes:d.routes,fixedObstacleRoutes:this.fixedPreloadedObstacleRoutes,newConnections:this.params.newConnections,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.drcEvaluator,initialErrors:d.remainingErrors,allowTracePairRepair:!0,preloadRepairTraceIds:h,connMap:this.params.connMap,colorMap:this.params.colorMap,viaDiameter:this.params.defaultViaDiameter,traceWidth:this.params.srj.minTraceWidth,obstacleMargin:this.params.srj.defaultObstacleMargin??this.params.srj.minTraceToPadEdgeClearance??.15,effort:this.params.effort}),p=performance.now(),m=(({originalSrj:t,routes:e,syntheticConnectionNames:n,drcEvaluator:o})=>{const i={routes:e,attemptedRegionCount:0,acceptedRegionCount:0,candidateAttemptCount:0,pathSearchNodeCount:0,referenceValidationCount:0,initialDrcIssueCount:void 0,finalDrcIssueCount:void 0,repaired:!1};if(t.traces?.length||n.size>0)return i;const r=Math.max(t.defaultObstacleMargin??.2,t.minTraceToPadEdgeClearance??0,t.minViaEdgeToPadEdgeClearance??0);let s=Math.max(t.minTraceWidth,t.minViaDiameter??0);for(const t of e){s=Math.max(s,t.traceThickness,t.viaDiameter);for(const e of t.route)s=Math.max(s,e.traceThickness??0)}const a=Math.max(.5,s+r),c=Z6.filter(t=>!Number.isFinite(a)||2*a<t);if(0===c.length)return i;let l=e,d=o({traces:[],routes:e,hdRoutes:e});i.referenceValidationCount++;let h=Array.isArray(d)?d:d.errors;if(i.initialDrcIssueCount=h.length,i.finalDrcIssueCount=h.length,0===h.length)return i;const u={...fX(t),traces:void 0},p=[];let m=new Map(P6({srj:u,routes:l}).map(t=>[t.key,t.severity]));for(;i.attemptedRegionCount<4;){const t=(Array.isArray(d)?d:d.errorsWithCenters??d.errors).map(t=>t.center??t.pcb_center).filter(t=>null!==t&&"object"==typeof t&&"x"in t&&"y"in t&&"number"==typeof t.x&&"number"==typeof t.y&&Number.isFinite(t.x)&&Number.isFinite(t.y));let e;for(const n of c){const o=t.find(({x:t,y:e})=>!p.some(({bounds:o,size:i})=>n===i&&t>=o.minX&&t<=o.maxX&&e>=o.minY&&e<=o.maxY));if(o){e={center:o,size:n};break}}if(!e)break;const{center:n,size:r}=e,s=j6({srj:u,routes:l,bounds:{minX:n.x-r/2,maxX:n.x+r/2,minY:n.y-r/2,maxY:n.y+r/2}});if(p.push({bounds:s.mutableBounds,size:r}),i.attemptedRegionCount++,0===s.routes.length)continue;const a=new A6({srj:s.srj,routes:s.routes,bounds:s.bounds,boundaryMargin:s.boundaryMargin,lockedPointIndices:s.lockedPointIndices,maxCandidates:256,maxCandidateAttempts:256,maxPathSearchNodes:U6,allowLayerChanges:!0,traceOnlyFirst:!1});if(a.solve(),a.failed)throw new Error(`Pipeline9 bounded regional repair failed: ${a.error}`);const{candidateAttempts:g,pathSearchNodes:f}=a.stats;if(!Number.isSafeInteger(g)||g<0||g>256||!Number.isSafeInteger(f)||f<0||f>U6)throw new Error("Pipeline9 bounded regional repair exceeded its work budget");i.candidateAttemptCount+=g,i.pathSearchNodeCount+=f;const y=G6({routes:l,region:s,repairedRoutes:a.getOutput()});if(y.every((t,e)=>t===l[e]))continue;const _=P6({srj:u,routes:y});if(!_.every(({key:t,severity:e})=>m.has(t)&&e<=m.get(t)+1e-8)||w6({srj:u,previousRoutes:l,routes:y}).length>0)continue;const b=o({traces:[],routes:y,hdRoutes:y});i.referenceValidationCount++;const x=Array.isArray(b)?b:b.errors;if(!(x.length>=h.length)&&(l=y,h=x,d=b,m=new Map(_.map(t=>[t.key,t.severity])),i.acceptedRegionCount++,i.finalDrcIssueCount=h.length,0===h.length))return i.routes=l,i.repaired=!0,i}return i})({originalSrj:this.params.originalSrj,routes:u.routes,syntheticConnectionNames:this.syntheticConnectionNames,drcEvaluator:this.cachedReferenceDrcEvaluator});this.combinedOutput=m.routes,this.stats={...this.stats,...this.exactRepairSolver.stats,postExactIndexedDrcIssueCount:n,postExactReferenceValidationAttempted:!0,postExactReferenceDrcIssueCount:o,postExactReferenceAccepted:!1,clearancePrecisionCandidateCount:i,clearancePrecisionCandidateValidationCount:r,clearancePrecisionReferenceValidationCount:s,clearancePrecisionRepaired:a,boundedRegionalRepairAttemptedRegionCount:m.attemptedRegionCount,boundedRegionalRepairAcceptedRegionCount:m.acceptedRegionCount,boundedRegionalRepairCandidateAttemptCount:m.candidateAttemptCount,boundedRegionalRepairPathSearchNodeCount:m.pathSearchNodeCount,boundedRegionalRepairReferenceValidationCount:m.referenceValidationCount,boundedRegionalRepairRepaired:m.repaired,boundedRegionalRepairTimeMs:performance.now()-p,regionalB01RepairCandidateCount:u.attemptedCandidateCount,regionalB01RepairAcceptedCount:u.acceptedCandidateCount,regionalB01RepairFallbackCandidateCount:u.fallbackCandidateCount,regionalB01RepairCandidateSearchCount:u.candidateSearchCount,regionalB01RepairCandidateSearchBudget:u.candidateSearchBudget,regionalB01RepairCandidateSearchBudgetExhausted:u.candidateSearchBudgetExhausted,regionalB01RepairSafeTraceLayerSkippedForBudget:u.safeTraceLayerRepairSkippedForBudget,regionalB01RepairRemainingDrcIssueCount:u.remainingDrcIssueCount,regionalB01RepairPreloadEligibleDrcIssueCount:u.preloadEligibleDrcIssueCount,regionalB01RepairAttempted:u.preloadRepairAttempted,regionalB01RepairTraceIdCount:h.size+(h.collidingFixedTraceIds?.size??0),terminalEscapeCandidateCount:d.attemptedCandidateCount,terminalEscapeAcceptedCount:d.acceptedCandidateCount,referenceDrcValidationCount:this.referenceDrcValidationCount,referenceDrcFalseNegativeCount:this.referenceDrcFalseNegativeCount,indexedDrcEvaluationCount:this.indexedDrcEvaluationCount,indexedDrcCacheHitCount:this.indexedDrcCacheHitCount,indexedDrcEvaluationTimeMs:this.indexedDrcEvaluationTimeMs,indexedDrcCandidateCacheSize:this.indexedDrcCandidateCache.size,indexedDrcCandidateCacheCapacity:64},this.solved=!0}getCombinedOutput(){return this.combinedOutput??this.exactRepairSolver?.getOutput()??this.inputNewHdRoutes}getOutput(){return this.getCombinedOutput().filter(t=>!this.syntheticConnectionNames.has(t.connectionName))}getUpdatedPreloadedTraces(){const t=new Map(this.getCombinedOutput().map(t=>[t.connectionName,t])),e=new Map;for(const n of this.movablePreloadedSections){const o=t.get(n.syntheticConnectionName);if(!o)throw new Error(`Pipeline9 joint DRC repair output is missing "${n.syntheticConnectionName}"`);const i=n.originalTrace.pcb_trace_id,r=e.get(i)??[];r.push({routePositionStart:n.originalRoutePositionStart,routePositionEnd:n.originalRoutePositionEnd,route:Mo(o,this.params.layerCount,{defaultViaHoleDiameter:this.params.defaultViaHoleDiameter,obstacles:this.params.obstacles,connMap:this.params.connMap})}),e.set(i,r)}const n=new Map([...e].map(([t,e])=>{const n=this.inputUpdatedPreloadedTraces.find(e=>e.pcb_trace_id===t);if(!n)throw new Error(`Pipeline9 cannot find preloaded trace "${t}" while rebuilding repaired sections`);return[t,O9({originalTrace:n,repairedSections:e})]}));return this.inputUpdatedPreloadedTraces.map(t=>n.get(t.pcb_trace_id)??t)}getMutatedPreloadedTraces(){const t=new Set([...this.params.mutatedPreloadedTraceIds,...this.movablePreloadedSections.map(t=>t.originalTrace.pcb_trace_id)]);return this.getUpdatedPreloadedTraces().filter(e=>t.has(e.pcb_trace_id))}visualize(){return this.exactRepairSolver?.visualize()??{}}},L9=1e-6,D9=(t,e,n)=>{const o=ko(t,n),i=ko(e,n);return Array.from({length:Math.abs(i-o)+1},(t,e)=>Math.min(o,i)+e)},z9=t=>"wire"===t.route_type,F9=(t,e,n)=>t.portPoints.filter(t=>t.availableZ.includes(n)&&!(t._preloadedTracePortAssignments??[]).some(t=>t.z===n&&t.fixedNetId!==e.fixedNetId)).map(t=>({portPoint:t,distance:be(t,e.start,e.end)})).sort((t,e)=>t.distance-e.distance||t.portPoint.distToCentermostPortOnZ-e.portPoint.distToCentermostPortOnZ||t.portPoint.segmentPortPointId.localeCompare(e.portPoint.segmentPortPointId))[0]?.portPoint,B9=(t,e,n)=>{t._preloadedFixedNetIds=[...new Set([...t._preloadedFixedNetIds??[],e.fixedNetId])].sort();const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=o*o+i*i,s=0===r?0:Math.max(0,Math.min(1,((t.x-e.start.x)*o+(t.y-e.start.y)*i)/r)),a={traceId:e.traceId,fixedNetId:e.fixedNetId,routePosition:e.routePositionStart+s*(e.routePositionEnd-e.routePositionStart),tracePoint:{x:e.start.x+s*o,y:e.start.y+s*i},z:n},c=t._preloadedTracePortAssignments??[];c.some(t=>t.traceId===a.traceId&&t.fixedNetId===a.fixedNetId&&t.z===a.z&&Math.abs(t.routePosition-a.routePosition)<=L9)||(t._preloadedTracePortAssignments=[...c,a].sort((t,e)=>t.traceId.localeCompare(e.traceId)||t.routePosition-e.routePosition||t.z-e.z))},j9=class extends si{constructor(t,e){super(),this.sharedEdgeSegments=t,this.srj=e,this.MAX_ITERATIONS=1,this.primitives=(t=>{const e=[],n=ii(t);for(const o of t.traces??[]){if(!o.connection_name)throw new Error(`Preloaded trace "${o.pcb_trace_id}" is missing a connection name`);const i=n.getNetConnectedToId(o.connection_name)??o.connection_name;for(const[n,r]of o.route.entries())if("via"===r.route_type)e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n,zLayers:D9(r.from_layer,r.to_layer,t.layerCount),start:r,end:r});else if("through_obstacle"===r.route_type)e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n+1,zLayers:D9(r.from_layer,r.to_layer,t.layerCount),start:r.start,end:r.end});else if("jumper"===r.route_type){const s=ko(r.layer,t.layerCount);for(const[t,a]of[r.start,r.end].entries())e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n+t,routePositionEnd:n+t,zLayers:[s],start:a,end:a})}for(let n=0;n<o.route.length-1;n++){const r=o.route[n],s=o.route[n+1];z9(r)&&z9(s)&&r.layer===s.layer&&e.push({traceId:o.pcb_trace_id,fixedNetId:i,connectionName:o.connection_name,routePositionStart:n,routePositionEnd:n+1,zLayers:[ko(r.layer,t.layerCount)],start:r,end:s})}}return e})(e)}sharedEdgeSegments;srj;primitives;getSolverName(){return"PreloadedTraceGraphSolver"}_step(){for(const t of this.primitives)for(const e of this.sharedEdgeSegments)if(!(Ra(t.start,t.end,e.start,e.end)>L9))for(const n of t.zLayers){if(!e.availableZ.includes(n))continue;const o=F9(e,t,n);o&&B9(o,t,n)}const t=this.sharedEdgeSegments.flatMap(t=>t.portPoints),e=t.filter(t=>(t._preloadedFixedNetIds?.length??0)>0);this.stats={preloadedTraceCount:this.srj.traces?.length??0,preloadedTraceShapeCount:this.primitives.length,inputBoundaryCount:this.sharedEdgeSegments.length,outputBoundaryCount:this.sharedEdgeSegments.length,inputPortCount:t.length,outputPortCount:t.length,preloadedPortCount:e.length,tracePortAssignmentCount:e.reduce((t,e)=>t+(e._preloadedTracePortAssignments?.length??0),0),topologyChanged:!1},this.solved=!0}getOutput(){if(!this.solved)throw new Error("PreloadedTraceGraphSolver has not solved yet");return this.sharedEdgeSegments}},$9=class extends _X{_step(){const{traces:t,...e}=this.inputSrj,n=fX(e),o=fX(aX(yX(n)));this.outputSrj=void 0===t?o:{...o,traces:t},this.solved=!0}};function Y9(t){return new Set((t??[]).filter(t=>t._isComponentTopologyNode).map(t=>t.capacityMeshNodeId))}function X9(t,e){return t.nodeIds.some(t=>e.has(t))}function V9({sharedEdgeSegments:t,componentCapacityMeshNodeIds:e}){return t.filter(t=>!X9(t,e))}function W9(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var H9=class extends si{constructor(t,e={}){super(),this.srj=t,this.opts=e;const n=fX(t);this.originalSrj=n,this.opts={...e};const o=this.opts;if(this.effort=o.effort??1,this.MAX_ITERATIONS=1e8*this.effort,this.maxNodeDimension=o.maxNodeDimension??15,this.maxNodeRatio=o.maxNodeRatio??6,this.minNodeArea=o.minNodeArea??.1**2,this.visualizationTraceColorMode=o.visualizationTraceColorMode??"layer",this.setSimpleRouteJson(n),void 0===o.capacityDepth){const t=this.srj.bounds.maxX-this.srj.bounds.minX,e=this.srj.bounds.maxY-this.srj.bounds.minY,n=Math.max(t,e),i=o.targetMinCapacity??.5;o.capacityDepth=$s(n,i)}this.cacheProvider=void 0===o.cacheProvider?oo():null===o.cacheProvider?null:o.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;getSolverName(){return"AutoroutingPipelineSolver9_PreloadedTraceGraph"}preprocessSimpleRouteJsonSolver;escapeViaLocationSolver;netToPointPairsSolver;componentTopologyGeneratorSolver;topologyPlanningSolver;topologyMergingSolver;globalTopologyGeneratorSolver;nodeDimensionSubdivisionSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityForceImproveSolver;highDensityRepairSolver;highDensityStitchSolver;globalDrcForceImproveSolver;pipeline9JointDrcRepairSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;mutatedPreloadedTraceSimplificationSolver;lengthMatchingPostProcessingSolver;powerTraceExpansionSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;preloadedTraceGraphSolver;componentDetectionSolver;viaDiameter;viaHoleDiameter;minTraceWidth;effort;maxNodeDimension;maxNodeRatio;minNodeArea;visualizationTraceColorMode;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithEscapeViaLocations;srjWithPointPairs;originalSrj;capacityNodes=null;capacityEdges=null;sharedEdgeSegmentsWithNecessaryCrampedPortPoints;highDensityNodePortPoints;cacheProvider=null;pipelineDef=[W9("preprocessSimpleRouteJsonSolver",$9,t=>[t.originalSrj,{traceColorMode:t.visualizationTraceColorMode}],{onSolved:t=>{t.setSimpleRouteJson(t.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson())}}),W9("componentDetectionSolver",UZ,t=>[{inputSrj:t.srj}]),W9("escapeViaLocationSolver",Uj,t=>[t.srj,{viaDiameter:t.viaDiameter,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=>{t.srjWithEscapeViaLocations=t.escapeViaLocationSolver?.getOutputSimpleRouteJson()}}),W9("netToPointPairsSolver",ga,t=>{const e=t.srjWithEscapeViaLocations??t.srj;return[e,t.colorMap,ri(e)]},{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,t.connMap),t.connMap=ii(t.srjWithPointPairs)}}),W9("topologyPlanningSolver",_q,t=>[{inputSrj:t.srjWithPointPairs,componentDetectionOutput:t.componentDetectionSolver.getOutput(),viaDiameter:t.viaDiameter,obstacleMargin:t.srj.defaultObstacleMargin??.15}],{onSolved:t=>{t.topologyPlanningSolver.getOutput();t.globalTopologyGeneratorSolver=t.topologyPlanningSolver.globalTopologySolver,t.componentTopologyGeneratorSolver=new vq(t.topologyPlanningSolver)}}),W9("topologyMergingSolver",fq,t=>{const e=t.topologyPlanningSolver.getOutput();return[{layerCount:t.srj.layerCount,nodeGroups:[{groupId:"global",nodes:e.globalMeshNodes,isComponent:!1},...e.componentMeshNodes.map((t,e)=>({groupId:`component-${e}`,nodes:t,isComponent:!0}))]}]},{onSolved:t=>{t.capacityNodes=t.topologyMergingSolver.getOutput()}}),W9("nodeDimensionSubdivisionSolver",Tz,t=>[t.capacityNodes,t.maxNodeDimension,t.maxNodeRatio,t.minNodeArea],{onSolved:t=>{t.capacityNodes=t.nodeDimensionSubdivisionSolver.outputNodes}}),W9("edgeSolver",ui,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),W9("availableSegmentPointSolver",ci,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),W9("necessaryCrampedPortPointSolver",sf,t=>{const e=Y9(t.capacityNodes);return[{capacityMeshNodes:t.capacityNodes.filter(t=>!e.has(t.capacityMeshNodeId)),sharedEdgeSegments:V9({sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),componentCapacityMeshNodeIds:e}),simpleRouteJson:t.srjWithPointPairs}]},{onSolved:t=>{const e=Y9(t.capacityNodes);t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints=function({originalSharedEdgeSegments:t,filteredSharedEdgeSegments:e,componentCapacityMeshNodeIds:n}){const o=new Map(e.map(t=>[t.edgeId,t]));return t.map(t=>X9(t,n)?t:o.get(t.edgeId)??t)}({originalSharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),filteredSharedEdgeSegments:t.necessaryCrampedPortPointSolver.getOutput(),componentCapacityMeshNodeIds:e})}}),W9("preloadedTraceGraphSolver",j9,t=>[t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints,t.srjWithPointPairs]),W9("portPointPathingSolver",jj,t=>{const e=t.sharedEdgeSegmentsWithNecessaryCrampedPortPoints??t.necessaryCrampedPortPointSolver?.getOutput()??t.availableSegmentPointSolver.getOutput(),{graph:n,connections:o}=bf({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,connectivityMap:t.connMap,segmentPortPoints:e.flatMap(t=>t.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:n,connections:o,layerCount:t.srj.layerCount,effort:t.effort,preserveTerminalPcbPortIds:!0,minViaPadDiameter:t.viaDiameter,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0,USE_SELECTIVE_RERIP_ROUTING:!0,USE_PARTIAL_RIP_ROUTING_WITH_PRELOADED_TRACES:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,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}}]}),W9("uniformPortDistributionSolver",go,t=>[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),W9("highDensityRouteSolver",VQ,t=>{const e=t.portPointPathingSolver;if(!e)throw new Error("Pipeline9 invariant violated: high-density routing requires the completed port-point pathing solver");const n=e.getOutput(),o=t.uniformPortDistributionSolver?.getOutput()??[],i=n.nodesWithPortPoints,r=o.length>0?o:i;t.highDensityNodePortPoints=structuredClone(r);const s=(t.originalSrj.traces??[]).flatMap((e,n)=>oQ(e,n,t.originalSrj.layerCount,t.viaDiameter,t.connMap));return[{nodePortPoints:r,fixedHdRoutes:TK({traces:t.originalSrj.traces??[],fixedHdRoutes:s,sections:t.getChangedPreloadedTraceSections()}),connMap:t.connMap,colorMap:t.colorMap,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,viaToPadClearance:t.srj.minViaEdgeToPadEdgeClearance,effort:t.effort,includeBoardObstacles:!0,nodePfById:new Map(n.inputNodeWithPortPoints.map(t=>[t.capacityMeshNodeId,e.computeNodePf(t)])),preserveTerminalPcbPortIds:!0}]}),W9("highDensityForceImproveSolver",Yy,t=>[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:AK(t.highDensityRouteSolver.routes),colorMap:t.colorMap,totalStepsPerNode:Math.max(12,Math.round(20*t.effort)),nodeAssignmentMargin:t.srj.defaultObstacleMargin??.2}]),W9("highDensityRepairSolver",AY,t=>[{nodeWithPortPoints:t.highDensityNodePortPoints??[],hdRoutes:t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,obstacles:t.srj.obstacles,colorMap:t.colorMap,repairMargin:t.srj.defaultObstacleMargin??.2,maxSampleEntries:80,connMap:t.connMap}]),W9("highDensityStitchSolver",KY,t=>[{connections:[...t.srjWithPointPairs.connections,...t.getChangedPreloadedTraceSections().map(t=>t.connection)],hdRoutes:t.highDensityRepairSolver?.getOutput()??t.highDensityForceImproveSolver?.getOutput()??t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,preserveTerminalPcbPortIds:!0,preferSameLayerTerminalEndpoints:!0}]),W9("traceSimplificationSolver",vc,t=>{const e=t.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces.flatMap((e,n)=>oQ(e,n,t.originalSrj.layerCount,t.viaDiameter,t.connMap).map(t=>({...t,rootConnectionName:e.connection_name}))),n=new Set(t.getChangedPreloadedTraceSections().map(t=>t.connectionName)),o=t.highDensityStitchSolver.mergedHdRoutes.filter(t=>!n.has(t.connectionName)),i=IK([...o,...e],t.connMap);return[{hdRoutes:o,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,otherHdRoutes:e,netByConnectionName:i,enableCrossingViaReduction:!0,terminalLayerIndicesByPcbPortId:SK(t.srj.connections,t.srj.obstacles,t.srj.layerCount),iterations:2}]}),W9("mutatedPreloadedTraceSimplificationSolver",vc,t=>{const e=t.getPreparedMutatedPreloadedTraceSections(),n=e.sections.map(t=>t.hdRoute),o=[...e.immutableHdRoutes,...t.traceSimplificationSolver.simplifiedHdRoutes];return[{hdRoutes:n,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,minTraceToPadEdgeClearance:t.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:t.srj.minBoardEdgeClearance,otherHdRoutes:o,netByConnectionName:IK([...n,...o],t.connMap),enableCrossingViaReduction:!0,preserveRouteEndpoints:!0,iterations:2}]}),W9("traceWidthSolver",Ic,t=>[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srjWithPointPairs.connections,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15,layerCount:t.srj.layerCount}]),W9("globalDrcForceImproveSolver",Nz,t=>[{srj:t.getSrjWithMaterializedPreloadedTraces(),hdRoutes:KJ(t.traceWidthSolver.getHdRoutesWithWidths(),t.netToPointPairsSolver?.newConnections??[],new Map((t.highDensityStitchSolver?.mergedHdRoutes??[]).map(t=>[t.connectionName,t]))),connMap:t.connMap,effort:t.effort,maxIterations:16,enableLargeBoardBroadFallback:!1,enablePostSolveClearanceRelaxation:!1}]),W9("pipeline9JointDrcRepairSolver",k9,t=>{const e=t.getPreloadedTraceUpdatesAfterHighDensity(),n=t.getSrjWithMaterializedPreloadedTraces();return[{srj:n,srjWithPointPairs:n,originalSrj:t.originalSrj,newConnections:t.netToPointPairsSolver?.newConnections??[],newHdRoutes:t.globalDrcForceImproveSolver.getOutput(),updatedPreloadedTraces:e.updatedPreloadedTraces,mutatedPreloadedTraceIds:new Set(e.mutatedPreloadedTraces.map(t=>t.pcb_trace_id)),connMap:t.connMap,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter,defaultViaHoleDiameter:t.viaHoleDiameter,effort:t.effort,colorMap:t.colorMap}]}),W9("lengthMatchingPostProcessingSolver",uK,t=>{const e=t.netToPointPairsSolver;if(!e)throw new Error("Pipeline9: length-matching post-processing requires NetToPointPairsSolver output");const n=e.newConnections,o=new Map;for(const e of t.srj.differentialPairs??[])for(const t of e.connectionNames){const e=n.filter(e=>e.name===t||e.__rootConnectionNames?.includes(t)||e.__netConnectionName===t);if(1!==e.length)throw new Error(`Pipeline9: differential pair connection "${t}" must resolve to exactly one final point-pair connection, got ${e.length}`);o.set(t,e[0].name)}const i=t.pipeline9JointDrcRepairSolver.getOutput(),r=(t.srj.differentialPairs??[]).map(t=>{const e=t.connectionNames.map(t=>{const e=o.get(t);if(!e)throw new Error(`Pipeline9: differential pair connection "${t}" is missing from final routed output`);return e});if(e[0]===e[1])throw new Error(`Pipeline9: differential pair ${t.connectionNames.join("/")} resolves both members to "${e[0]}"`);if(void 0===t.traceGap)return{connectionNames:e,lengthTolerance:t.lengthTolerance};const n=e.map(t=>{const e=i.filter(e=>e.connectionName===t);if(1!==e.length)throw new Error(`Pipeline9: differential pair connection "${t}" must resolve to exactly one final HD route, got ${e.length}`);return e[0]}),r=t.traceGap+n.reduce((t,e)=>t+e.traceThickness/2,0);return{connectionNames:e,lengthTolerance:t.lengthTolerance,minimumCenterlineDistance:r,maximumCenterlineDistance:r}});return[{hdRoutes:i,differentialPairs:r,buses:t.srj.buses??[],connections:t.srj.connections,obstacles:t.srj.obstacles,bounds:t.srj.bounds,layerCount:t.srj.layerCount,obstacleMargin:t.srj.minTraceToPadEdgeClearance??.15}]}),W9("powerTraceExpansionSolver",UJ,t=>{const e=t.opts.powerTraceExpansion??{},n=e.onlyConnectionNames??JJ(t.originalSrj);return[QJ({originalSrj:t.originalSrj,newlyRoutedTraces:t.getNewTracesBeforePowerExpansion(),currentPreloadedTraces:t.getUpdatedPreloadedTraces(),expandedConnectionNames:n,resolveConnectedTraceAliases:!0}),{allowNewVias:!1,...e,onlyConnectionNames:n}]})];setSimpleRouteJson(t){this.srj=t;const e=Yo(this.srj);this.viaDiameter=e.padDiameter,this.viaHoleDiameter=e.holeDiameter,this.minTraceWidth=this.srj.minTraceWidth,this.connMap=ii(this.srj),this.colorMap=wo(this.srj,this.connMap)}getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;computeProgress(){const t=this.activeSubSolver?.progress??0;return(this.currentPipelineStepIndex+t)/this.pipelineDef.length}_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),"lengthMatchingPostProcessingSolver"!==t.solverName&&"powerTraceExpansionSolver"!==t.solverName||(this.MAX_ITERATIONS=Math.max(this.MAX_ITERATIONS,this.iterations+this.activeSubSolver.MAX_ITERATIONS+1)),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.visualizeStage(this.activeSubSolver);const t=this.escapeViaLocationSolver?.visualize(),e=this.netToPointPairsSolver?.visualize(),n=this.componentDetectionSolver?.visualize(),o=this.componentTopologyGeneratorSolver?.visualize(),i=this.globalTopologyGeneratorSolver?.visualize(),r=this.topologyMergingSolver?.visualize(),s=this.nodeDimensionSubdivisionSolver?.visualize(),a=this.nodeTargetMerger?.visualize(),c=this.singleLayerNodeMerger?.visualize(),l=this.strawSolver?.visualize(),d=this.edgeSolver?.visualize(),h=this.deadEndSolver?.visualize(),u=this.availableSegmentPointSolver?.visualize(),p=this.portPointPathingSolver?.visualize(),m=this.multiSectionPortPointOptimizer?.visualize(),g=this.uniformPortDistributionSolver?.visualize(),f=this.highDensityRouteSolver?.visualize(),y=this.highDensityForceImproveSolver?.visualize(),_=this.highDensityRepairSolver?.visualize(),b=this.highDensityStitchSolver?.visualize(),x=this.traceSimplificationSolver?.visualize(),v=this.mutatedPreloadedTraceSimplificationSolver?.visualize(),S=this.lengthMatchingPostProcessingSolver?.visualize(),I=this.powerTraceExpansionSolver?.visualize(),C=this.traceWidthSolver?.visualize(),P=this.necessaryCrampedPortPointSolver?.visualize(),M=(this.highDensityRouteSolver?.visualize(),this.originalSrj),N=M.outline,w=[];if(w.push({points:[{x:M.bounds?.minX??-50,y:M.bounds?.minY??-50},{x:M.bounds?.maxX??50,y:M.bounds?.minY??-50},{x:M.bounds?.maxX??50,y:M.bounds?.maxY??50},{x:M.bounds?.minX??-50,y:M.bounds?.maxY??50},{x:M.bounds?.minX??-50,y:M.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),N&&N.length>=2){const t=N.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),w.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const T=Oo(M),R={points:[...M.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,layer:Fo(e,M.layerCount),label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(M.obstacles??[]).filter(t=>!t.isCopperPour).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)",layer:jo(t,M.layerCount),label:T(t)}))],lines:w},E={traceColorMode:this.visualizationTraceColorMode},A=Yj({srj:M,visualizationOptions:E}),O=pi(R,A),k=this.preprocessSimpleRouteJsonSolver?.visualize(),L=this.globalDrcForceImproveSolver?.visualize(),D=this.pipeline9JointDrcRepairSolver?.visualize(),z=[O,k,n,o,t,e,i,r,s,a,c,l,d,h,u,P,p,m,g,f?pi(R,f):null,y,_,b,x,v,C,L,D,S,I,this.solved?pi({lines:w},Yj({srj:this.originalSrj,visualizationOptions:E}),this.visualizeFinalOutput()):null].filter(Boolean),F=pi(...z);return"net"===this.visualizationTraceColorMode?xq(F,this.colorMap):F}visualizeStage(t){const e=t.visualize();return"net"===this.visualizationTraceColorMode?xq(e,this.colorMap):e}visualizeFinalOutput(){const t=this.visualizationTraceColorMode,e=this.getOutputSimpleRouteJson();return Ho(e,{traceColorMode:t})}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.portPointPathingSolver?this.portPointPathingSolver.preview():this.netToPointPairsSolver?this.netToPointPairsSolver.visualize():this.escapeViaLocationSolver?this.escapeViaLocationSolver.visualize():this.componentTopologyGeneratorSolver?this.componentTopologyGeneratorSolver.visualize():this.componentDetectionSolver?this.componentDetectionSolver.visualize():this.preprocessSimpleRouteJsonSolver?this.preprocessSimpleRouteJsonSolver.visualize():{}}_getOutputHdRoutes(){if(((this.originalSrj.differentialPairs?.length??0)>0||(this.originalSrj.buses??[]).some(t=>void 0!==t.maxLengthSkew))&&this.lengthMatchingPostProcessingSolver){const{hdRoutes:t}=this.lengthMatchingPostProcessingSolver.getOutput();return t}return this.pipeline9JointDrcRepairSolver?.getOutput()??this.globalDrcForceImproveSolver?.getOutput()??this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOriginalFixedHdRoutes(){return(this.originalSrj.traces??[]).flatMap((t,e)=>oQ(t,e,this.originalSrj.layerCount,this.viaDiameter,this.connMap))}getChangedPreloadedTraceSections(){return this.portPointPathingSolver?.getOutput().changedPreloadedTraceSections??[]}getPreloadedFixedRouteStateAfterHighDensity(){const t=this.getOriginalFixedHdRoutes(),e=this.getChangedPreloadedTraceSections(),n=TK({traces:this.originalSrj.traces??[],fixedHdRoutes:t,sections:e}),o=0===e.length?[]:RK({traces:this.originalSrj.traces??[],sections:e,stitchedHdRoutes:this.highDensityStitchSolver?.mergedHdRoutes??[],layerCount:this.originalSrj.layerCount}),i=new Set(e.map(t=>t.traceId)),r=t.filter(t=>i.has(this.originalSrj.traces?.[t.preloadedTraceIndex]?.pcb_trace_id??"")).map(t=>t.connectionName);return{originalFixedRoutes:t,updatedFixedRoutes:[...this.highDensityRouteSolver?.getUpdatedFixedHdRoutes()??n,...o],replacedConnectionNames:new Set([...this.highDensityRouteSolver?.fixedRouteReplacements.keys()??[],...r]),mutationMasks:new Map([...this.highDensityRouteSolver?.preloadedTraceMutationMasks??[],...o.map(t=>[t.connectionName,Array(t.route.length-1).fill(!0)])])}}getPreparedMutatedPreloadedTraceSections(){const t=this.getPreloadedFixedRouteStateAfterHighDensity();return eQ({updatedFixedRoutes:t.updatedFixedRoutes,regionalMutationMasks:t.mutationMasks})}getPreloadedTraceUpdatesAfterHighDensity(){const t=this.getPreloadedFixedRouteStateAfterHighDensity(),e=this.getPreparedMutatedPreloadedTraceSections(),n=!0===this.mutatedPreloadedTraceSimplificationSolver?.solved?(({updatedFixedRoutes:t,sections:e,simplifiedHdRoutes:n})=>{const o=new Set(e.map(t=>t.connectionName)),i=new Map(n.map(t=>[t.connectionName,t]));if(i.size!==e.length||n.some(t=>!o.has(t.connectionName)))throw new Error(`Pipeline9 trace simplification changed the mutation-section set (expected ${e.length}, got ${n.length})`);const r=new Map,s=new Set;for(const t of e){const e=i.get(t.connectionName);if(!e)throw new Error(`Pipeline9 trace simplification lost mutation section "${t.connectionName}"`);const n=e.route[0],o=e.route.at(-1);if(!(n&&o&&HK(n,t.section.start.point)&&HK(o,t.section.end.point)))throw new Error(`Pipeline9 trace simplification changed mutation-section boundary "${t.connectionName}"`);const a=XK(t.section,e),c=t.section.sourceRoutes[0];s.add(c.connectionName);for(const e of t.section.sourceRoutes){if(r.has(e.connectionName))throw new Error(`Pipeline9 attempted to simplify fixed route "${e.connectionName}" more than once`);r.set(e.connectionName,a)}}return t.flatMap(t=>{const e=r.get(t.connectionName);return e?s.has(t.connectionName)?[e]:[]:[t]})})({updatedFixedRoutes:e.normalizedFixedRoutes,sections:e.sections,simplifiedHdRoutes:this.mutatedPreloadedTraceSimplificationSolver.simplifiedHdRoutes}):t.updatedFixedRoutes;return(({originalTraces:t,originalFixedRoutes:e,updatedFixedRoutes:n,replacedConnectionNames:o,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a})=>{const c=new Map,l=new Map;for(const t of e){const e=c.get(t.preloadedTraceIndex)??[];e.push(t),c.set(t.preloadedTraceIndex,e)}for(const t of n){const e=l.get(t.preloadedTraceIndex)??[];e.push(t),l.set(t.preloadedTraceIndex,e)}const d=[];return{updatedPreloadedTraces:t.map((t,e)=>{const n=(c.get(e)??[]).sort(fK);if(!n.some(t=>o.has(t.connectionName)))return t;const h=(l.get(e)??[]).sort(fK),u=t.route.some(t=>"through_obstacle"===t.route_type),p={...t,__replaces_pcb_trace_id:t.pcb_trace_id,route:u?xK({trace:t,originalTraceRoutes:n,updatedTraceRoutes:h,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a}):_K({trace:t,updatedTraceRoutes:h,layerCount:i,defaultViaHoleDiameter:r,obstacles:s,connMap:a})};return d.push(p),p}),mutatedPreloadedTraces:d}})({originalTraces:this.originalSrj.traces??[],originalFixedRoutes:t.originalFixedRoutes,updatedFixedRoutes:n,replacedConnectionNames:t.replacedConnectionNames,layerCount:this.originalSrj.layerCount,defaultViaHoleDiameter:this.viaHoleDiameter,obstacles:this.originalSrj.obstacles,connMap:this.connMap})}getSrjWithMaterializedPreloadedTraces(){return{...this.srjWithPointPairs,traces:this.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces}}getUpdatedPreloadedTraces(){return this.pipeline9JointDrcRepairSolver?.getUpdatedPreloadedTraces()??this.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces}getMutatedPreloadedTraces(){return this.pipeline9JointDrcRepairSolver?.getMutatedPreloadedTraces()??this.getPreloadedTraceUpdatesAfterHighDensity().mutatedPreloadedTraces}getNewTracesBeforePowerExpansion(){if(!this.highDensityRouteSolver)throw new Error("Cannot get new traces before high-density routing");const t=qJ({connections:this.netToPointPairsSolver?.newConnections??[],originalConnections:this.originalSrj.connections,hdRoutes:this._getOutputHdRoutes(),layerCount:this.srj.layerCount,obstacles:this.srj.obstacles,defaultViaHoleDiameter:this.viaHoleDiameter,connMap:this.connMap});return vK(t,this.originalSrj.traces??[])}getPowerTraceExpansionFixedTraces(){if(!this.powerTraceExpansionSolver)throw new Error("Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver");return this.powerTraceExpansionSolver.inputSrj.fixedTraces}getOutputSimplifiedPcbTraces(){if(!this.solved)throw new Error("Cannot get output before solving is complete");if(!this.powerTraceExpansionSolver)throw new Error("Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver");return[...this.getPowerTraceExpansionFixedTraces().filter(t=>void 0!==t.__replaces_pcb_trace_id),...this.powerTraceExpansionSolver.getOutput()]}getOutputSimpleRouteJson(){if(!this.solved)throw new Error("Cannot get output before solving is complete");if(!this.powerTraceExpansionSolver)throw new Error("Pipeline9 invariant violated: solved pipeline is missing the unconditional power-trace expansion solver");const t=[...this.getPowerTraceExpansionFixedTraces(),...this.powerTraceExpansionSolver.getOutput()];return{...this.originalSrj,traces:t}}},G9=String("0.0.886"),U9=({nodeWithPortPoints:t,obstacleMargin:e,traceWidth:n,viaDiameter:o})=>{const i=ro(t),r=e+Math.max(n,o)/2+1e-6;return{minX:t.center.x+8*(i.minX-t.center.x)-r,maxX:t.center.x+8*(i.maxX-t.center.x)+r,minY:t.center.y+8*(i.minY-t.center.y)-r,maxY:t.center.y+8*(i.maxY-t.center.y)+r}},Z9=(t,e)=>{const n=(t.ccwRotationDegrees??0)*Math.PI/180,o=Math.abs(Math.cos(n)),i=Math.abs(Math.sin(n)),r=t.width/2,s=t.height/2,a=Math.max(r,r*o+s*i),c=Math.max(s,r*i+s*o);return t.center.x-a<=e.maxX&&t.center.x+a>=e.minX&&t.center.y-c<=e.maxY&&t.center.y+c>=e.minY},q9=(t,e)=>{for(const n of[e.connectionName,e.rootConnectionName,e.portPointId,e.pcb_port_id,e.prevPortPointId,e.nextPortPointId])void 0!==n&&t.add(n)},J9=(t,e)=>Object.fromEntries(Object.entries(t.netMap).flatMap(([t,n])=>{const o=n.filter(t=>e.has(t));return o.length>0||e.has(t)?[[t,o]]:[]})),K9=({obstacle:t,connectedTo:e,preserveRotation:n})=>({type:"rect",layers:t.layers,...void 0===t.zLayers?{}:{zLayers:t.zLayers},...void 0===t.__zLayers?{}:{__zLayers:t.__zLayers},center:t.center,width:t.width,height:t.height,...n&&void 0!==t.ccwRotationDegrees?{ccwRotationDegrees:t.ccwRotationDegrees}:{},connectedTo:e,...void 0===t.circuitJsonMetadata?{}:{circuitJsonMetadata:t.circuitJsonMetadata}});function Q9({nodeWithPortPoints:t,connMap:e,obstacles:n,obstacleMargin:o,traceWidth:i,viaDiameter:r}){const s=U9({nodeWithPortPoints:t,obstacleMargin:o,traceWidth:i,viaDiameter:r}),a=new Set;for(const e of t.portPoints)q9(a,e);for(const e of t.portPointsInPairs??[])q9(a,e[0]),q9(a,e[1]);const c=n.flatMap(n=>{if(!Z9(n,s))return[];const o=(({obstacle:t,nodeWithPortPoints:e,connMap:n})=>{const o=new Set(e.portPoints.flatMap(t=>{const e=n.getNetConnectedToId(t.rootConnectionName??t.connectionName)??t.rootConnectionName??t.connectionName;return[t.connectionName,e]})),i=new Set(t.connectedTo.filter(t=>o.has(t))),r=new Map;for(const t of o){const e=n.getNetConnectedToId(t)??t,o=r.get(e)??[];o.push(t),r.set(e,o)}for(const e of r.values()){if([...i].some(t=>e.some(e=>e===t||n.areIdsConnected(e,t))))continue;const o=t.connectedTo.find(t=>e.some(e=>e===t||n.areIdsConnected(e,t)));void 0!==o&&i.add(o)}return[...i]})({obstacle:n,nodeWithPortPoints:t,connMap:e});for(const t of o)a.add(t);return[K9({obstacle:n,connectedTo:o,preserveRotation:!0})]});return{connectivityNetMap:J9(e,a),obstacles:c}}var t8=(...t)=>{const e=new Map;for(const n of t)for(const[t,o]of Object.entries(n)){const n=e.get(t)??new Set;for(const t of o)n.add(t);e.set(t,n)}return Object.fromEntries([...e].map(([t,e])=>[t,[...e]]))};function e8({nodeWithPortPoints:t,connMap:e,colorMap:n,obstacles:o,obstacleMargin:i,traceWidth:r,viaDiameter:s}){const a=U9({nodeWithPortPoints:t,obstacleMargin:i,traceWidth:r,viaDiameter:s}),c=(t=>[...new Set(t.portPoints.map(t=>t.connectionName))])(t),l=o.flatMap(t=>{if(!Z9(t,a))return[];const n=c.filter(n=>t.connectedTo.some(t=>t===n||e.areIdsConnected(n,t)));return 0===n.length?[]:[K9({obstacle:t,connectedTo:n,preserveRotation:!1})]}),d=new Set;for(const e of t.portPoints)q9(d,e);for(const e of t.portPointsInPairs??[])q9(d,e[0]),q9(d,e[1]);for(const t of l)for(const e of[t.circuitJsonMetadata?.pcb_smtpad_id,t.circuitJsonMetadata?.pcb_plated_hole_id,t.circuitJsonMetadata?.pcb_port_id,t.circuitJsonMetadata?.pcb_via_id,...t.connectedTo??[]])void 0!==e&&d.add(e);return{connectivityNetMap:J9(e,d),colorMap:Object.fromEntries(Object.entries(n??{}).filter(([t])=>d.has(t))),obstacles:l}}var n8="https://hd-cache2.tscircuit.com",o8=31e4,i8=1835008,r8=16777216,s8=class extends Error{constructor(t,e){super(e),this.reason=t,this.name="HdCache2RequestError"}reason},a8=t=>t instanceof Error?t.message:String(t),c8=new Set(["pcb_smtpad_id","pcb_plated_hole_id","pcb_port_id","pcb_via_id","source_component_name","source_port_name"]),l8=t=>!(!t||"object"!=typeof t||Array.isArray(t))&&Object.entries(t).every(([t,e])=>c8.has(t)&&"string"==typeof e),d8=(t,e)=>Math.abs(t-e)<=1e-9*Math.max(1,Math.abs(t),Math.abs(e)),h8=1e-6,u8=(t,e)=>{const n="ordinary"===e?h8:.001,o=new Set;for(let i=0;i<t.route.length-1;i++){const r=t.route[i],s=t.route[i+1],a=r.z!==s.z;if("through_obstacle"===r.toNextSegmentType){if(!a)return!1;continue}if(void 0!==r.toNextSegmentCircuitJsonMetadata)return!1;if(!a)continue;const c=[],l=[];for(const[e,o]of t.vias.entries())Math.hypot(o.x-r.x,o.y-r.y)<=n&&c.push(e),Math.hypot(o.x-s.x,o.y-s.y)<=n&&l.push(e);if(Math.hypot(r.x-s.x,r.y-s.y)<=h8){if(0===c.length)return!1;for(const t of c)o.add(t)}else{if("regional-fallback"===e)return!1;if(0===c.length==(0===l.length))return!1;for(const t of[...c,...l])o.add(t)}}const i=t.route.at(-1);return void 0===i.toNextSegmentType&&void 0===i.toNextSegmentCircuitJsonMetadata&&t.vias.every((t,e)=>o.has(e))},p8=(t,e,n)=>{if(!Array.isArray(t))return!1;const o=new Map;for(const t of e.nodeWithPortPoints.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}const i=new Set(e.nodeWithPortPoints.availableZ??e.nodeWithPortPoints.portPoints.map(t=>t.z)),r=U9({nodeWithPortPoints:e.nodeWithPortPoints,obstacleMargin:e.obstacleMargin,traceWidth:e.traceWidth,viaDiameter:e.viaDiameter}),s=(t,e)=>(o.get(e)??[]).some(e=>"number"==typeof t.x&&d8(t.x,e.x)&&"number"==typeof t.y&&d8(t.y,e.y)&&t.z===e.z);for(const a of t){if(!a||"object"!=typeof a)return!1;const t=a;if("string"!=typeof t.connectionName||0===t.connectionName.length||!o.has(t.connectionName)||"number"!=typeof t.traceThickness||!Number.isFinite(t.traceThickness)||t.traceThickness<=0||"number"!=typeof t.viaDiameter||!Number.isFinite(t.viaDiameter)||t.viaDiameter<=0||!d8(t.viaDiameter,e.viaDiameter)||!Array.isArray(t.route)||t.route.length<2||!Array.isArray(t.vias))return!1;for(const e of[t.rootConnectionName,t.startPcbPortId,t.endPcbPortId,t.regionId])if(void 0!==e&&"string"!=typeof e)return!1;for(const o of t.route){if(!o||"object"!=typeof o)return!1;const t=o;if("number"!=typeof t.x||!Number.isFinite(t.x)||"number"!=typeof t.y||!Number.isFinite(t.y)||t.x<r.minX||t.x>r.maxX||t.y<r.minY||t.y>r.maxY||"number"!=typeof t.z||!Number.isInteger(t.z)||t.z<0||t.z>=e.layerCount||"ordinary"===n&&!i.has(t.z))return!1;if(void 0!==t.traceThickness&&("number"!=typeof t.traceThickness||!Number.isFinite(t.traceThickness)||t.traceThickness<=0))return!1;if(void 0!==t.pcb_port_id&&"string"!=typeof t.pcb_port_id)return!1;if(void 0!==t.insideJumperPad&&"boolean"!=typeof t.insideJumperPad)return!1;if(void 0!==t.toNextSegmentType&&"through_obstacle"!==t.toNextSegmentType)return!1;if(void 0!==t.toNextSegmentCircuitJsonMetadata&&!l8(t.toNextSegmentCircuitJsonMetadata))return!1}const c=t.route;if(!("ordinary"!==n||s(c[0],t.connectionName)&&s(c.at(-1),t.connectionName)))return!1;for(const e of t.vias){if(!e||"object"!=typeof e)return!1;const t=e;if("number"!=typeof t.x||!Number.isFinite(t.x)||"number"!=typeof t.y||!Number.isFinite(t.y)||t.x<r.minX||t.x>r.maxX||t.y<r.minY||t.y>r.maxY)return!1}if(!u8(t,n))return!1;if(void 0!==t.jumpers){if(!Array.isArray(t.jumpers))return!1;for(const e of t.jumpers){if(!e||"object"!=typeof e)return!1;const t=e,n=t.start,o=t.end;if("jumper"!==t.route_type||"0603"!==t.footprint&&"1206"!==t.footprint&&"1206x4_pair"!==t.footprint||!n||"number"!=typeof n.x||!Number.isFinite(n.x)||"number"!=typeof n.y||!Number.isFinite(n.y)||!o||"number"!=typeof o.x||!Number.isFinite(o.x)||"number"!=typeof o.y||!Number.isFinite(o.y)||n.x<r.minX||n.x>r.maxX||n.y<r.minY||n.y>r.maxY||o.x<r.minX||o.x>r.maxX||o.y<r.minY||o.y>r.maxY)return!1}}}const a=t;return"ordinary"===n?((t,e)=>{const n=e.portPointsInPairs??[];if(n.length>0){for(const[e,o]of n)if(!xs(t,e.connectionName,_s(e)).has(_s(o)))return!1;return!0}const o=new Map;for(const t of e.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}for(const[e,n]of o)for(const[o,i]of Dr(n))if(!xs(t,e,_s(o)).has(_s(i)))return!1;return!0})(a,e.nodeWithPortPoints):((t,e)=>{const n=(t,e)=>{if(t.z!==e.z)return!1;const n=t.x-e.x,o=t.y-e.y;return Math.hypot(n,o)<=.001},o=new Map;for(const i of t){const t=i.route.some((t,e)=>{const n=i.route[e+1];return!(void 0===n||d8(t.x,n.x)&&d8(t.y,n.y)&&t.z===n.z)}),r=i.route[0],s=i.route.at(-1);if(!t||!r||!s)return!1;const a=e.portPoints.filter(t=>t.connectionName===i.connectionName);if(!a.some(t=>n(r,t))||!a.some(t=>n(s,t)))return!1;const c=o.get(i.connectionName)??[];c.push({start:r,end:s}),o.set(i.connectionName,c)}const i=(t,e,i)=>{if(n(e,i))return!0;const r=o.get(t)??[],s=[],a=new Set;for(const[t,o]of r.entries())(n(e,o.start)||n(e,o.end))&&(s.push(t),a.add(t));for(;s.length>0;){const t=r[s.pop()];if(n(i,t.start)||n(i,t.end))return!0;for(const[e,o]of r.entries())a.has(e)||(n(t.start,o.start)||n(t.start,o.end)||n(t.end,o.start)||n(t.end,o.end))&&(a.add(e),s.push(e))}return!1},r=e.portPointsInPairs??[];if(r.length>0)return r.every(([t,e])=>i(t.connectionName,t,e));const s=new Map;for(const t of e.portPoints){const e=s.get(t.connectionName)??[];e.push(t),s.set(t.connectionName,e)}return[...s].every(([,t])=>Dr(t).every(([t,e])=>i(t.connectionName,t,e)))})(a,e.nodeWithPortPoints)},m8=class{constructor(t,e=n8,n={}){this.autorouterVersion=t,this.serverUrl=e;const{cacheVersion:o}=n;if(void 0!==o&&0===o.trim().length)throw new Error("hd-cache2 cacheVersion must not be empty");this.cacheVersion=o}autorouterVersion;serverUrl;cacheVersion;stats={batchRequestsStarted:0,batchRequestsCompleted:0,batchItemsStarted:0,batchBodyBytesStarted:0,batchMaxBodyBytes:0,batchCacheMisses:0,singleRequestsStarted:0,batchInvalidLines:0,batchUnknownRequestIds:0,batchDuplicateRequestIds:0};solveMany(t){const e=t.map((t,e)=>this.createPendingSolve(String(e),t)),n=e.filter(t=>null!==t.serializedItem),{batches:o,singletonSolves:i}=this.prepareBatches(n);for(const t of o)this.fetchBatch(t);for(const t of i)this.launchSingleSolve(t);return e.map(t=>t.promise)}createPendingSolve(t,e){let n;const o={requestId:t,input:e,serializedItem:null,promise:new Promise(t=>{n=t}),resolve:n,settled:!1,singleSolveStarted:!1};try{o.serializedItem=JSON.stringify({requestId:t,input:e})}catch(t){this.settleWithFallback(o,"request_serialization_error",a8(t))}return o}settle(t,e){t.settled||(t.settled=!0,t.resolve(e))}settleWithFallback(t,e,n){this.settle(t,{kind:"local-fallback",reason:e,error:n})}parseSuccessfulResponse(t,e){if(!t||"object"!=typeof t||Array.isArray(t))throw new s8("invalid_response","hd-cache2 returned a non-object response");const n=t;if(!0!==n.ok)throw new s8("remote_error","string"==typeof n.message?n.message:"hd-cache2 returned an unsuccessful response");if(n.autorouterVersion!==this.autorouterVersion)throw new s8("version_mismatch",`hd-cache2 returned autorouter version ${String(n.autorouterVersion)}, expected ${this.autorouterVersion}`);if(n.cacheVersion!==this.cacheVersion)throw new s8("cache_version_mismatch",`hd-cache2 returned cache version ${String(n.cacheVersion)}, expected ${String(this.cacheVersion)}`);if("cache"!==n.source&&"solver"!==n.source)throw new s8("invalid_response","hd-cache2 returned an invalid cache source");if("ordinary"!==n.solutionStage&&"regional-fallback"!==n.solutionStage)throw new s8("invalid_response","hd-cache2 returned an invalid solution stage");if("regional-fallback"===n.solutionStage&&(!e.enableRegionalFallback||"string"!=typeof n.ordinaryFailure||0===n.ordinaryFailure.length))throw new s8("invalid_response","hd-cache2 returned invalid regional fallback metadata");if("ordinary"===n.solutionStage&&Object.prototype.hasOwnProperty.call(n,"ordinaryFailure"))throw new s8("invalid_response","hd-cache2 returned regional metadata on an ordinary result");if("ordinary"===n.solutionStage&&"failed"===n.status&&e.enableRegionalFallback)throw new s8("invalid_response","hd-cache2 returned an intermediate ordinary failure");if("solved"===n.status&&p8(n.routes,e,n.solutionStage))return n;if("failed"===n.status&&"string"==typeof n.error&&n.error.length>0)return n;throw new s8("invalid_response","hd-cache2 returned an invalid solve result")}parseBatchCacheMiss(t){if(!1!==t.ok||"CACHE_MISS"!==t.code)return null;if(t.autorouterVersion!==this.autorouterVersion)throw new s8("version_mismatch",`hd-cache2 returned autorouter version ${String(t.autorouterVersion)}, expected ${this.autorouterVersion}`);if(t.cacheVersion!==this.cacheVersion)throw new s8("cache_version_mismatch",`hd-cache2 returned cache version ${String(t.cacheVersion)}, expected ${String(this.cacheVersion)}`);if("string"!=typeof t.message)throw new s8("invalid_response","hd-cache2 returned an invalid cache miss response");return t}async fetchSingle(t){const e=new AbortController;let n=!1;const o=setTimeout(()=>{n=!0,e.abort(new Error("hd-cache2 transport timed out after 310000ms"))},o8);o.unref?.();try{const n={autorouterVersion:this.autorouterVersion,...void 0===this.cacheVersion?{}:{cacheVersion:this.cacheVersion},input:t.input};let o;try{o=JSON.stringify(n)}catch(t){throw new s8("request_serialization_error",a8(t))}const r=await fetch((i=this.serverUrl,/\/solve\/?$/.test(i)?i.replace(/\/+$/,""):`${i.replace(/\/+$/,"")}/solve`),{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:o,signal:e.signal}),s=await r.text();let a=null;try{a=s?JSON.parse(s):null}catch{if(!r.ok)throw new s8("http_error",`hd-cache2 request failed with status ${r.status}`);throw new s8("invalid_json",`hd-cache2 returned invalid JSON with status ${r.status}`)}if(!r.ok){const t=a&&"object"==typeof a&&"message"in a&&"string"==typeof a.message?a.message:`hd-cache2 request failed with status ${r.status}`;throw new s8("http_error",t)}this.settle(t,{kind:"remote",response:this.parseSuccessfulResponse(a,t.input)})}catch(e){const o=e instanceof s8?e.reason:n?"transport_timeout":"transport_error";this.settleWithFallback(t,o,a8(e))}finally{clearTimeout(o)}var i}launchSingleSolve(t){t.singleSolveStarted||t.settled||(t.singleSolveStarted=!0,this.stats.singleRequestsStarted+=1,this.fetchSingle(t))}handleBatchResponseLine(t,e,n){if(0===t.trim().length)return;if(t.length>r8)throw new s8("response_too_large","hd-cache2 returned an oversized batch result line");let o;try{o=JSON.parse(t)}catch{return void(this.stats.batchInvalidLines+=1)}if(!o||"object"!=typeof o||Array.isArray(o))return void(this.stats.batchInvalidLines+=1);const i=o,r=i.requestId;if("string"!=typeof r)return void(this.stats.batchInvalidLines+=1);const s=e.get(r);if(s)if(n.has(r))this.stats.batchDuplicateRequestIds+=1;else{n.add(r);try{if(this.parseBatchCacheMiss(i))return this.stats.batchCacheMisses+=1,void this.launchSingleSolve(s);this.settle(s,{kind:"remote",response:this.parseSuccessfulResponse(i,s.input)})}catch(t){this.stats.batchInvalidLines+=1,this.settleWithFallback(s,t instanceof s8?t.reason:"invalid_response",a8(t))}}else this.stats.batchUnknownRequestIds+=1}async readBatchResponse(t,e){if(!t.body)throw new s8("invalid_response","hd-cache2 returned an empty batch response body");const n=new Map(e.items.map(t=>[t.requestId,t])),o=new Set,i=new TextDecoder,r=t.body.getReader();let s="";for(;o.size<e.items.length;){const{done:t,value:e}=await r.read();if(s+=i.decode(e,{stream:!t}),s.length>r8&&!s.includes("\n"))throw new s8("response_too_large","hd-cache2 returned an oversized unterminated batch result line");let a=s.indexOf("\n");for(;a>=0;){const t=s.slice(0,a);s=s.slice(a+1),this.handleBatchResponseLine(t,n,o),a=s.indexOf("\n")}if(t){s.trim().length>0&&this.handleBatchResponseLine(s,n,o);break}}if(o.size!==e.items.length)for(const t of e.items)o.has(t.requestId)||this.settleWithFallback(t,"missing_response",`hd-cache2 batch ended without result ${t.requestId}`);else await r.cancel().catch(()=>{})}async fetchBatch(t){const e=new AbortController;let n=!1;const o=setTimeout(()=>{n=!0,e.abort(new Error("hd-cache2 batch transport timed out after 310000ms"))},o8);o.unref?.(),this.stats.batchRequestsStarted+=1,this.stats.batchItemsStarted+=t.items.length,this.stats.batchBodyBytesStarted+=t.bodyBytes,this.stats.batchMaxBodyBytes=Math.max(this.stats.batchMaxBodyBytes,t.bodyBytes);try{const n=await fetch((t=>{const e=t.replace(/\/+$/,"");return/\/solve-batch$/.test(e)?e:/\/solve$/.test(e)?e.replace(/\/solve$/,"/solve-batch"):`${e}/solve-batch`})(this.serverUrl),{method:"POST",headers:{accept:"application/x-ndjson","content-type":"application/json"},body:t.body,signal:e.signal});if(!n.ok){const t=await n.text().catch(()=>"");let e=`hd-cache2 batch request failed with status ${n.status}`;try{const n=t?JSON.parse(t):null;n&&"object"==typeof n&&"message"in n&&"string"==typeof n.message&&(e=n.message)}catch{}throw new s8("http_error",e)}await this.readBatchResponse(n,t)}catch(e){const o=e instanceof s8?e.reason:n?"transport_timeout":"transport_error";for(const n of t.items)n.singleSolveStarted||this.settleWithFallback(n,o,a8(e))}finally{clearTimeout(o),this.stats.batchRequestsCompleted+=1}}prepareBatches(t){const e=new TextEncoder,n=void 0===this.cacheVersion?"":`,"cacheVersion":${JSON.stringify(this.cacheVersion)}`,o=`{"autorouterVersion":${JSON.stringify(this.autorouterVersion)}${n},"items":[`,i=e.encode(o+"]}").byteLength,r=[],s=[];let a=[],c=i;const l=()=>{0!==a.length&&(r.push({body:`${o}${a.map(t=>t.serializedItem).join(",")}]}`,bodyBytes:c,items:a}),a=[],c=i)};for(const n of t){const t=e.encode(n.serializedItem).byteLength,o=0===a.length?0:1;i+t>i8?(l(),s.push(n)):((a.length>=100||c+o+t>i8)&&l(),a.push(n),c+=(1===a.length?0:1)+t)}return l(),{batches:r,singletonSolves:s}}},g8="ordinary_then_regional_without_fixed_copper_v1",f8=class extends VQ{autorouterVersion;hdCache2ServerUrl;hdCache2CacheVersion;requestTimeoutMs;hdCache2Client;launchedRemoteSolves=!1;waitingForRemoteNode=null;remoteRequestByNode=new Map;remoteResultByNode=new Map;logicallyTimedOutNodes=new Set;constructor({autorouterVersion:t,hdCache2ServerUrl:e,hdCache2CacheVersion:n,requestTimeoutMs:o,...i}){if(super(i),1!==i.effort)throw new Error(`Pipeline9 networked high-density routing requires effort=1, received ${i.effort}`);if(this.requestTimeoutMs=o??3e4,!Number.isFinite(this.requestTimeoutMs)||this.requestTimeoutMs<=0)throw new Error(`Pipeline9 network request timeout must be a positive number, received ${this.requestTimeoutMs}`);this.autorouterVersion=t,this.hdCache2ServerUrl=e??n8,this.hdCache2CacheVersion=n,this.hdCache2Client=new m8(this.autorouterVersion,this.hdCache2ServerUrl,{cacheVersion:n}),this.pendingEffects=[],this.stats={...this.stats,remoteRequestsStarted:0,remoteRequestsCompleted:0,remoteBatchRequestsStarted:0,remoteBatchRequestsCompleted:0,remoteBatchItemsStarted:0,remoteBatchBodyBytesStarted:0,remoteBatchMaxBodyBytes:0,remoteBatchCacheMisses:0,remoteSingleRequestsStarted:0,remoteBatchInvalidLines:0,remoteBatchUnknownRequestIds:0,remoteBatchDuplicateRequestIds:0,remoteCacheHits:0,remoteSolverResults:0,remoteSolvedResults:0,remoteFailedResults:0,remoteOrdinaryResults:0,remoteRegionalFallbackResults:0,remoteRegionalFallbackResultsApplied:0,remoteRegionalFallbackResultsDeferredToLocal:0,remoteTransportFallbacks:0,remoteLogicalTimeoutFallbacks:0,remoteFallbackReasonCounts:{}}}getSolverName(){return"Pipeline9NetworkedHighDensitySolver"}async waitForAllRemoteRequests(){const t=[...this.remoteRequestByNode.values()];0!==t.length?(await Promise.all(t.map(({promise:t})=>t)),this.syncClientStats()):this.syncClientStats()}createNodeInput(t){const e=this.enableRegionalFallback?Q9({nodeWithPortPoints:t,connMap:this.connMap,obstacles:this.obstacles,obstacleMargin:this.obstacleMargin,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter}):{connectivityNetMap:{},obstacles:[]},n=e8({nodeWithPortPoints:t,connMap:this.connMap,colorMap:this.colorMap,obstacles:this.enableRegionalFallback?e.obstacles:this.obstacles,obstacleMargin:this.obstacleMargin,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter});return{solvePolicy:g8,enableRegionalFallback:this.enableRegionalFallback,nodeWithPortPoints:t,connectivityNetMap:t8(n.connectivityNetMap,e.connectivityNetMap),colorMap:n.colorMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,effort:1,obstacles:n.obstacles,regionalObstacles:e.obstacles,layerCount:this.layerCount,nodePf:this.nodePfById.get(t.capacityMeshNodeId)??null}}syncClientStats(){const t=this.hdCache2Client.stats;this.stats.remoteBatchRequestsStarted=t.batchRequestsStarted,this.stats.remoteBatchRequestsCompleted=t.batchRequestsCompleted,this.stats.remoteBatchItemsStarted=t.batchItemsStarted,this.stats.remoteBatchBodyBytesStarted=t.batchBodyBytesStarted,this.stats.remoteBatchMaxBodyBytes=t.batchMaxBodyBytes,this.stats.remoteBatchCacheMisses=t.batchCacheMisses,this.stats.remoteSingleRequestsStarted=t.singleRequestsStarted,this.stats.remoteBatchInvalidLines=t.batchInvalidLines,this.stats.remoteBatchUnknownRequestIds=t.batchUnknownRequestIds,this.stats.remoteBatchDuplicateRequestIds=t.batchDuplicateRequestIds}recordFallbackReason(t){const e=this.stats.remoteFallbackReasonCounts;e[t]=(e[t]??0)+1}trackRemoteSolve(t,e){const n=performance.now()+this.requestTimeoutMs;this.stats.remoteRequestsStarted+=1;const o=e.then(e=>{const n=this.logicallyTimedOutNodes.has(t);n||this.remoteResultByNode.set(t,e),"remote"===e.kind?("cache"===e.response.source&&(this.stats.remoteCacheHits+=1),"solver"===e.response.source&&(this.stats.remoteSolverResults+=1),"solved"===e.response.status?this.stats.remoteSolvedResults+=1:this.stats.remoteFailedResults+=1):n||(this.stats.remoteTransportFallbacks+=1,this.recordFallbackReason(e.reason)),this.stats.remoteRequestsCompleted+=1,this.syncClientStats()});this.remoteRequestByNode.set(t,{promise:o,deadlineAt:n})}launchRemoteSolves(){const t=[],e=[...this.unsolvedNodePortPoints].reverse();for(const n of e)try{t.push({node:n,input:this.createNodeInput(n)})}catch(t){this.trackRemoteSolve(n,Promise.resolve({kind:"local-fallback",reason:"request_serialization_error",error:t instanceof Error?t.message:String(t)}))}const n=this.hdCache2Client.solveMany(t.map(({input:t})=>t));for(const[e,o]of n.entries())this.trackRemoteSolve(t[e].node,o);this.syncClientStats()}async waitForCurrentRemoteNode(t,e){const n=e.deadlineAt-performance.now();if(n<=0)return void this.recordLogicalTimeout(t);let o;const i=await Promise.race([e.promise.then(()=>"request-settled"),new Promise(t=>{o=setTimeout(()=>t("logical-timeout"),n)})]);void 0!==o&&clearTimeout(o),"logical-timeout"===i&&this.recordLogicalTimeout(t)}recordLogicalTimeout(t){this.logicallyTimedOutNodes.add(t),this.stats.remoteLogicalTimeoutFallbacks+=1,this.stats.remoteTransportFallbacks+=1,this.recordFallbackReason("logical_timeout")}startRegularSolver(t){const e=this.remoteResultByNode.get(t);if(!e){const e=this.remoteRequestByNode.get(t);if(e){this.waitingForRemoteNode=t;const n=this.waitForCurrentRemoteNode(t,e);n.then(()=>{this.waitingForRemoteNode===t&&(this.pendingEffects=[])});const o={name:`hd-cache2:${t.capacityMeshNodeId}`,promise:n};return void(this.pendingEffects=[o])}return void super.startRegularSolver(t)}this.applyRemoteResultToRegularNode(t,e)}applyRemoteResultToRegularNode(t,e){if("local-fallback"!==e.kind){if(this.stats.regularNodeCount=Number(this.stats.regularNodeCount??0)+1,this.activeNode=t,"regional-fallback"===e.response.solutionStage){if(this.stats.remoteRegionalFallbackResults+=1,!this.canUseNoFixedCopperRegionalResult(t))return this.stats.remoteRegionalFallbackResultsDeferredToLocal+=1,void this.finishRegularSolverFailure(e.response.ordinaryFailure);this.stats.remoteRegionalFallbackResultsApplied+=1,this.stats.fallbackNodeCount=Number(this.stats.fallbackNodeCount??0)+1}else this.stats.remoteOrdinaryResults+=1;if("failed"===e.response.status)return this.error=e.response.error,this.failed=!0,void(this.activeNode=null);this.finishActiveNode(e.response.routes)}else super.startRegularSolver(t)}canUseNoFixedCopperRegionalResult(t){const e={...YQ(t,this.connMap),availableZ:Array.from({length:this.layerCount},(t,e)=>e)},n=$K(e,this.getUpdatedFixedHdRoutes());return 0===n.fixedRouteSectionsByConnectionName.size&&0===n.fixedObstacleRoutes.length}_step(){if(this.syncClientStats(),this.launchedRemoteSolves||(this.launchedRemoteSolves=!0,this.launchRemoteSolves()),this.waitingForRemoteNode){const t=this.waitingForRemoteNode;if(this.logicallyTimedOutNodes.has(t))return this.waitingForRemoteNode=null,this.pendingEffects=[],void super.startRegularSolver(t);const e=this.remoteResultByNode.get(t);if(!e)return;return this.waitingForRemoteNode=null,this.pendingEffects=[],void this.applyRemoteResultToRegularNode(t,e)}super._step()}},y8=class extends H9{hdCache2ServerUrl;hdCache2CacheVersion;getSolverName(){return"AutoroutingPipelineSolver9_Networked"}constructor(t,e={}){if(super(t,e),1!==this.effort)throw new Error(`AutoroutingPipelineSolver9_Networked is only available at effort=1, received ${this.effort}`);this.hdCache2ServerUrl=e.hdCache2ServerUrl??n8,this.hdCache2CacheVersion=e.hdCache2CacheVersion,this.replaceHighDensityPipelineStep()}replaceHighDensityPipelineStep(){const t=this.pipelineDef.findIndex(t=>"highDensityRouteSolver"===t.solverName),e=this.pipelineDef[t];if(!e)throw new Error("Pipeline9 highDensityRouteSolver step is missing");const n=e.getConstructorParams;this.pipelineDef[t]={...e,solverClass:f8,getConstructorParams:t=>{const[e]=n(t);return[{...e,autorouterVersion:G9,hdCache2ServerUrl:t.hdCache2ServerUrl,hdCache2CacheVersion:t.hdCache2CacheVersion}]}}}async stepAsync(){if(this.solved||this.failed)return;this.step();const t=vX(this);0!==t.length&&(await Promise.race(t.map(t=>t.promise.then(()=>t.name,()=>t.name))),this.solved||this.failed||this.step())}async solveAsync(){const t=Date.now();for(;!this.solved&&!this.failed;)await this.stepAsync();this.timeToSolve=Date.now()-t}async solveUntilPhaseAsync(t){for(;this.getCurrentPhase()!==t&&!this.solved&&!this.failed;)await this.stepAsync()}solve(){throw new Error("AutoroutingPipelineSolver9_Networked requires async execution. Use solveAsync() or stepAsync().")}solveUntilPhase(t){throw new Error("AutoroutingPipelineSolver9_Networked requires solveUntilPhaseAsync().")}};function _8(t){if(t.solvePolicy!==g8)throw new Error(`Unsupported Pipeline9 networked solve policy ${String(t.solvePolicy)}`);if(1!==t.effort)throw new Error(`Pipeline9 networked high-density solving requires effort=1, received ${t.effort}`);const e=new ti(t.connectivityNetMap),n=(({input:t,connMap:e})=>{const n=XQ({nodeWithPortPoints:t.nodeWithPortPoints,colorMap:t.colorMap,connMap:e,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:{[t.nodeWithPortPoints.capacityMeshNodeId]:t.nodePf},obstacles:t.obstacles,layerCount:t.layerCount});return n.solve(),n.solved?{status:"solved",routes:n.routes}:{status:"failed",error:n.error||"Pipeline9 ordinary high-density solver failed"}})({input:t,connMap:e});if("solved"===n.status)return{status:"solved",solutionStage:"ordinary",routes:n.routes};const o=n.error;if(!t.enableRegionalFallback)return{status:"failed",solutionStage:"ordinary",error:`Pipeline9 regular high-density routing failed: ${o}`};const i=YQ(t.nodeWithPortPoints,e),r=$K({...i,availableZ:Array.from({length:t.layerCount},(t,e)=>e)},[]),s=new FQ({nodeWithPortPoints:r.nodeWithPortPoints,colorMap:t.colorMap,connMap:e,viaDiameter:t.viaDiameter,traceWidth:t.traceWidth,obstacleMargin:t.obstacleMargin,effort:t.effort,nodePfById:{[t.nodeWithPortPoints.capacityMeshNodeId]:t.nodePf},obstacles:t.regionalObstacles,layerCount:t.layerCount});if(s.solve(),s.solved)return{status:"solved",solutionStage:"regional-fallback",ordinaryFailure:o,routes:s.getOutput()};return{status:"failed",solutionStage:"regional-fallback",ordinaryFailure:o,error:[`Pipeline9 primary high-density routing failed: regular high-density routing failed: ${o}`,`regional fallback failed: ${s.error||"Pipeline9 regional fallback solver failed"}`].join("; ")}}var b8=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 x8(t){const e=`${t.connectionName}:source-${t.sourcePointIndex}`;return{boundaryExitPointId:`fanout-exit:${e}`,planeExitPointId:`fanout-plane:${e}`,traceId:`fanout:${e}`,viaObstacleId:`fanout-via:${e}`,planeEndpointPointId:`fanout-plane-endpoint-point:${e}`,planeEndpointTraceId:`fanout-plane-endpoint:${e}`,planeEndpointViaObstacleId:`fanout-plane-endpoint-via:${e}`}}function v8(t,e,n=!1){const o=n?t.planeEndpointVia:t.via;if(!o)return null;const i=o.spanLayers.map(n=>{const o=e.indexOf(n);if(o<0)throw new Error(`FanoutSolver: via for "${t.connectionName}" uses unknown layer "${n}"`);return o}),r=x8(t);return{obstacleId:n?r.planeEndpointViaObstacleId:r.viaObstacleId,type:"rect",center:o.center,width:o.diameter,height:o.diameter,layers:o.spanLayers,zLayers:i,__zLayers:i,connectedTo:[t.connectionName,t.trace.pcb_trace_id]}}function S8(t){const{inputSrj:e,plans:n,layerNames:o}=t,i=e.connections.map(t=>({...t,pointsToConnect:t.pointsToConnect.map(t=>({...t}))})),r=[],s=new Set;for(const t of n){const e=i[t.connectionIndex];if(!e)throw new Error(`FanoutSolver: output connection index ${t.connectionIndex} is missing`);const n=x8(t);e.pointsToConnect[t.sourcePointIndex]={x:t.exitPoint.x,y:t.exitPoint.y,layer:t.targetLayer,pointId:"plane"===t.termination.type?n.planeExitPointId:n.boundaryExitPointId},"plane"===t.termination.type&&s.add(t.connectionName);const a=v8(t,o);a&&r.push(a);const c=v8(t,o,!0);c&&r.push(c)}const a=n.flatMap(t=>[t.trace,...t.planeEndpointTrace?[t.planeEndpointTrace]:[]]),c=a.flatMap(t=>t.route.filter(t=>"x"in t&&"y"in t)),l=Math.max(e.defaultObstacleMargin??0,e.minTraceWidth),d=0===c.length?{...e.bounds}:{minX:Math.min(e.bounds.minX,...c.map(t=>t.x-l)),maxX:Math.max(e.bounds.maxX,...c.map(t=>t.x+l)),minY:Math.min(e.bounds.minY,...c.map(t=>t.y-l)),maxY:Math.max(e.bounds.maxY,...c.map(t=>t.y+l))};return{...e,fanoutPlaneConnectivity:n.flatMap(t=>"plane"===t.termination.type?[{connectionName:t.connectionName,layer:t.termination.layer}]:[]),bounds:d,connections:i.filter(t=>!s.has(t.name)),buses:e.buses?.map(t=>({...t,connectionNames:t.connectionNames.filter(t=>!s.has(t))})).filter(t=>t.connectionNames.length>0),obstacles:[...e.obstacles.map(t=>({...t,center:{...t.center},layers:[...t.layers],connectedTo:[...t.connectedTo]})),...r],traces:[...(e.traces??[]).map(t=>({...t,route:t.route.map(t=>({...t}))})),...a]}}var I8=1e-9;function C8(t){return"circle"===t.shape}function P8(t,e){const n=-(e.ccwRotationDegrees??0)*Math.PI/180,o=t.x-e.center.x,i=t.y-e.center.y;return{x:o*Math.cos(n)-i*Math.sin(n),y:o*Math.sin(n)+i*Math.cos(n)}}function M8(t,e){return Math.hypot(t.x-e.x,t.y-e.y)}function N8(t,e,n){const o=n.x-e.x,i=n.y-e.y,r=o*o+i*i,s=r<I8?0:((t.x-e.x)*o+(t.y-e.y)*i)/r,a=Math.max(0,Math.min(1,s));return Math.hypot(t.x-(e.x+a*o),t.y-(e.y+a*i))}function w8(t,e,n){return(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x)}function T8(t,e,n,o){return function(t,e,n,o){const i=w8(n,o,t),r=w8(n,o,e),s=w8(t,e,n),a=w8(t,e,o);return(i>0&&r<0||i<0&&r>0)&&(s>0&&a<0||s<0&&a>0)}(t,e,n,o)?0:Math.min(N8(t,n,o),N8(e,n,o),N8(n,t,e),N8(o,t,e))}function R8(t,e,n=1e-9){if(C8(e))return M8(t,e.center)<=e.width/2+n;const o=P8(t,e);return Math.abs(o.x)<=e.width/2+n&&Math.abs(o.y)<=e.height/2+n}function E8(t,e){if(C8(e))return Math.max(0,M8(t,e.center)-e.width/2);const n=P8(t,e),o=Math.max(Math.abs(n.x)-e.width/2,0),i=Math.max(Math.abs(n.y)-e.height/2,0);return Math.hypot(o,i)}function A8(t,e){if(C8(e))return Math.max(0,N8(e.center,t.start,t.end)-e.width/2);const n=P8(t.start,e),o=P8(t.end,e);if(Math.abs(n.x)<=e.width/2+I8&&Math.abs(n.y)<=e.height/2+I8)return 0;if(Math.abs(o.x)<=e.width/2+I8&&Math.abs(o.y)<=e.height/2+I8)return 0;const i=-e.width/2,r=e.width/2,s=-e.height/2,a=e.height/2,c=[{x:i,y:s},{x:r,y:s},{x:r,y:a},{x:i,y:a}];let l=Number.POSITIVE_INFINITY;for(let t=0;t<c.length;t++)l=Math.min(l,T8(n,o,c[t],c[(t+1)%c.length]));return l}function O8(t,e,n){if(t.layer!==e.layer)return!0;const o=(t.width+e.width)/2+n;return T8(t.start,t.end,e.start,e.end)>=o-I8}function k8(t){if(!Number.isInteger(t)||t<1)throw new Error(`FanoutSolver: layerCount must be a positive integer, received ${t}`);return 1===t?["top"]:2===t?["top","bottom"]:["top",...Array.from({length:t-2},(t,e)=>`inner${e+1}`),"bottom"]}function L8(t,e,n){const o=n.indexOf(t),i=n.indexOf(e);if(o<0||i<0)throw new Error(`FanoutSolver: cannot build via span from "${t}" to "${e}"`);const r=Math.min(o,i),s=Math.max(o,i);return n.slice(r,s+1)}var D8=new WeakMap;function z8(t){return t.netConnectionName??t.rootConnectionName??t.name}function F8(t,e,n){if(!e)return!1;const o=t.get(e)??new Set,i=o.size;return o.add(n),t.set(e,o),o.size!==i}function B8(t,e){const n=new Set;for(const o of e)for(const e of t.get(o)??[])n.add(e);return n}function j8(t){const e=D8.get(t);if(e)return e;const n=function(t){const e=new Map,n=new Map;for(const o of t.connections){const t=z8(o);e.set(o.name,t),F8(n,o.name,t),F8(n,o.rootConnectionName,t),F8(n,o.netConnectionName,t);for(const e of o.pointsToConnect)F8(n,e.pointId,t),F8(n,e.pcb_port_id,t)}for(const o of t.traces??[]){const t=o.connection_name?e.get(o.connection_name):void 0;if(t){F8(n,o.pcb_trace_id,t);for(const e of o.connectsTo??[])F8(n,e,t)}}for(let e=0;e<2;e++){let e=!1;for(const o of t.obstacles){const t=B8(n,o.connectedTo);if(1!==t.size)continue;const i=[...t][0];for(const t of o.connectedTo)e=F8(n,t,i)||e}if(!e)break}const o=new Map,i=t=>{const e=o.get(t)??t;if(o.set(t,e),e===t)return t;const n=i(e);return o.set(t,n),n},r=(t,e)=>{const n=i(t),r=i(e);n!==r&&o.set(r,n)};for(const t of n.values()){const[e,...n]=[...t];if(e)for(const t of n)r(e,t)}for(const e of[...t.obstacles.map(t=>t.connectedTo),...(t.traces??[]).map(t=>t.connectsTo??[])]){const[t,...o]=[...B8(n,e)];if(t)for(const e of o)r(t,e)}for(const[t,n]of e)e.set(t,i(n));for(const[t,e]of n)n.set(t,new Set([...e].map(t=>i(t))));return{connectionNetKeys:e,tokenNetKeys:n}}(t);return D8.set(t,n),n}function $8(t,e,n){const o=j8(t),i=o.connectionNetKeys.get(e),r=o.connectionNetKeys.get(n);return void 0!==i&&i===r}function Y8(t,e,n){const o=j8(t),i=o.connectionNetKeys.get(n);return!!i&&e.connectedTo.some(t=>o.tokenNetKeys.get(t)?.has(i))}var X8=1e-6;function V8(t){return"layer"in t?[t.layer]:t.layers}function W8(t,e){return t.some(t=>e.includes(t))}function H8(t,e){const n=[];let o;for(const i of t.route)"via"!==i.route_type?"wire"===i.route_type&&(o&&o.layer===i.layer&&M8(o,i)>X8&&n.push({type:"segment",segment:{start:{x:o.x,y:o.y},end:{x:i.x,y:i.y},width:i.width,layer:i.layer}}),o=i):(n.push({type:"via",center:{x:i.x,y:i.y},diameter:i.via_diameter??0,layers:L8(i.from_layer,i.to_layer,e)}),o=void 0);return n}function G8(t,e){return"plane"===t.type&&"plane"===e.type?t.layer===e.layer:"plane"===t.type&&"via"===e.type?e.layers.includes(t.layer):"via"===t.type&&"plane"===e.type?G8(e,t):"plane"===t.type&&"segment"===e.type?t.layer===e.segment.layer:"segment"===t.type&&"plane"===e.type?G8(e,t):"endpoint"===t.type&&"endpoint"===e.type?W8(t.layers,e.layers)&&M8(t.point,e.point)<=X8:"endpoint"===t.type&&"obstacle"===e.type?W8(t.layers,e.obstacle.layers)&&R8(t.point,e.obstacle,X8):"obstacle"===t.type&&"endpoint"===e.type?G8(e,t):"endpoint"===t.type&&"segment"===e.type?t.layers.includes(e.segment.layer)&&N8(t.point,e.segment.start,e.segment.end)<=e.segment.width/2+X8:"segment"===t.type&&"endpoint"===e.type?G8(e,t):"endpoint"===t.type&&"via"===e.type?W8(t.layers,e.layers)&&M8(t.point,e.center)<=e.diameter/2+X8:"via"===t.type&&"endpoint"===e.type?G8(e,t):"obstacle"===t.type&&"segment"===e.type?t.obstacle.layers.includes(e.segment.layer)&&A8(e.segment,t.obstacle)<=e.segment.width/2+X8:"segment"===t.type&&"obstacle"===e.type?G8(e,t):"obstacle"===t.type&&"via"===e.type?W8(t.obstacle.layers,e.layers)&&E8(e.center,t.obstacle)<=e.diameter/2+X8:"via"===t.type&&"obstacle"===e.type?G8(e,t):"segment"===t.type&&"segment"===e.type?t.segment.layer===e.segment.layer&&T8(t.segment.start,t.segment.end,e.segment.start,e.segment.end)<=(t.segment.width+e.segment.width)/2+X8:"segment"===t.type&&"via"===e.type?e.layers.includes(t.segment.layer)&&N8(e.center,t.segment.start,t.segment.end)<=e.diameter/2+t.segment.width/2+X8:"via"===t.type&&"segment"===e.type?G8(e,t):"via"===t.type&&"via"===e.type&&(W8(t.layers,e.layers)&&M8(t.center,e.center)<=(t.diameter+e.diameter)/2+X8)}var U8=class{parent;constructor(t){this.parent=Array.from({length:t},(t,e)=>e)}find(t){const e=this.parent[t];if(e===t)return t;const n=this.find(e);return this.parent[t]=n,n}union(t,e){const n=this.find(t),o=this.find(e);n!==o&&(this.parent[o]=n)}};function Z8(t,e,n){return Boolean(e.connection_name&&$8(t,e.connection_name,n.name))}function q8(t){const{inputSrj:e,routedSrj:n}=t,o=n.fanoutPlaneConnectivity,i=k8(n.layerCount),r=new Map;for(const t of e.connections){const e=z8(t),n=r.get(e)??[];n.push(t),r.set(e,n)}const s=[];let a=0,c=0;for(const t of r.values()){const r=t[0],l=t.flatMap(t=>t.pointsToConnect.map((e,n)=>({type:"endpoint",connectionName:t.name,endpointIndex:n,point:e,layers:V8(e)}))),d=e.obstacles.filter(t=>Y8(e,t,r.name)).map(t=>({type:"obstacle",obstacle:t})),h=(n.traces??[]).filter(t=>Z8(e,t,r)).flatMap(t=>H8(t,i)),u=[...new Set((o??[]).flatMap(t=>$8(e,t.connectionName,r.name)?[t.layer]:[]))].map(t=>({type:"plane",layer:t})),p=[...l,...d,...h,...u],m=new U8(p.length);for(let t=0;t<p.length;t++)for(let e=t+1;e<p.length;e++)G8(p[t],p[e])&&m.union(t,e);const g=new Map;for(let t=0;t<l.length;t++){const e=l[t],n=g.get(e.connectionName)??[];n[e.endpointIndex]=t,g.set(e.connectionName,n)}for(const e of t){const t=g.get(e.name)??[],n=t[0],o=void 0===n?void 0:m.find(n),i=t.flatMap((t,e)=>void 0===o||m.find(t)!==o?[e]:[]);c+=t.length-i.length,0===i.length?a++:s.push({code:"original-endpoints-disconnected",connectionName:e.name,disconnectedEndpointIndices:i,message:`Connection ${e.name} has no physical copper path from endpoint 0 to original endpoint${1===i.length?"":"s"} ${i.join(", ")}`})}}const l=e.connections.reduce((t,e)=>t+e.pointsToConnect.length,0);return{valid:0===s.length,checkedConnectionCount:e.connections.length,connectedConnectionCount:a,checkedEndpointCount:l,connectedEndpointCount:c,issues:s}}var J8=1e-6;function K8(t){const{inputSrj:e,segment:n,bodyObstacle:o,connectionName:i}=t;if(o.connectedTo.length>0||!o.componentId)return!1;const r=e.obstacles.filter(t=>t.componentId===o.componentId&&t.layers.includes(n.layer)&&Y8(e,t,i));for(const t of r)for(const[e,i]of[[n.start,n.end],[n.end,n.start]]){if(!R8(e,t,J8))continue;const n={x:e.x-o.center.x,y:e.y-o.center.y},r={x:i.x-e.x,y:i.y-e.y};if(n.x*r.x+n.y*r.y>J8)return!0}return!1}function Q8(t,e){return M8(t,e)<=J8}function t7(t,e){t.push(e)}function e7(t){const{srj:e,trace:n,connectionName:o,layerNames:i,issues:r}=t,s=[],a=[];let c,l;for(const t of n.route){if("via"===t.route_type){const s=L8(t.from_layer,t.to_layer,i);a.push({center:{x:t.x,y:t.y},diameter:t.via_diameter??e.minViaPadDiameter??e.minTraceWidth,spanLayers:s}),c&&Q8(c,t)&&c.layer===t.from_layer||t7(r,{code:"disconnected-trace",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} reaches a via without a matching ${t.from_layer} wire endpoint`}),l=t;continue}"wire"===t.route_type?l?(Q8(t,l)&&t.layer===l.to_layer||t7(r,{code:"disconnected-trace",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} does not continue from its via on ${l.to_layer}`}),c=t,l=void 0):(c&&(c.layer!==t.layer?t7(r,{code:"disconnected-trace",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} changes from ${c.layer} to ${t.layer} without a via`}):Q8(c,t)||s.push({start:{x:c.x,y:c.y},end:{x:t.x,y:t.y},width:t.width,layer:t.layer})),c=t):(t7(r,{code:"unsupported-route-point",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} contains unsupported ${t.route_type} geometry`}),c=void 0,l=void 0)}return l&&t7(r,{code:"disconnected-trace",traceId:n.pcb_trace_id,connectionName:o,message:`Trace ${n.pcb_trace_id} ends at a via without a wire on ${l.to_layer}`}),{trace:n,connectionName:o,segments:s,vias:a}}function n7(t){const{inputSrj:e,routedSrj:n,clearance:o}=t,i=[],r=k8(n.layerCount),s=[],a=[e,n].flatMap(t=>t.connections.flatMap(t=>t.pointsToConnect.map(e=>({connectionName:t.name,point:e}))));for(const t of n.traces??[]){const o=t.connection_name;o&&e.connections.some(t=>t.name===o)?s.push(e7({srj:n,trace:t,connectionName:o,layerNames:r,issues:i})):t7(i,{code:"unknown-trace-connection",traceId:t.pcb_trace_id,...o?{connectionName:o}:{},message:`Trace ${t.pcb_trace_id} does not identify an input connection`})}for(const t of s){for(const n of t.segments)for(const r of e.obstacles){if(!r.layers.includes(n.layer)||Y8(e,r,t.connectionName))continue;if(K8({inputSrj:e,segment:n,bodyObstacle:r,connectionName:t.connectionName}))continue;const s=A8(n,r),a=n.width/2+o;s<a-J8&&t7(i,{code:"trace-obstacle-clearance",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,layer:n.layer,obstacleId:r.obstacleId,message:`Trace ${t.trace.pcb_trace_id} on ${n.layer} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId}; ${a.toFixed(4)}mm is required`})}for(const n of t.vias){const r=a.find(({point:t})=>M8(n.center,t)<=J8);r&&t7(i,{code:"via-at-endpoint",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,otherConnectionName:r.connectionName,message:`Via in ${t.trace.pcb_trace_id} is placed directly at an original or routed connection endpoint`});for(const r of e.obstacles){if(!r.layers.some(t=>n.spanLayers.includes(t))||Y8(e,r,t.connectionName))continue;const s=E8(n.center,r),a=n.diameter/2+o;s<a-J8&&t7(i,{code:"via-obstacle-clearance",traceId:t.trace.pcb_trace_id,connectionName:t.connectionName,obstacleId:r.obstacleId,message:`Via in ${t.trace.pcb_trace_id} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId} on its layer span; ${a.toFixed(4)}mm is required`})}}}for(let t=0;t<s.length;t++){const n=s[t];for(let r=t+1;r<s.length;r++){const t=s[r];if(!$8(e,n.connectionName,t.connectionName)){for(const e of n.segments){for(const r of t.segments)O8(e,r,o)||t7(i,{code:"different-net-trace-clearance",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:e.layer,message:`Different-net traces ${n.trace.pcb_trace_id} and ${t.trace.pcb_trace_id} intersect or violate clearance on ${e.layer}`});for(const r of t.vias)!r.spanLayers.includes(e.layer)||N8(r.center,e.start,e.end)>=r.diameter/2+e.width/2+o-J8||t7(i,{code:"different-net-trace-via-clearance",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:e.layer,message:`Trace ${n.trace.pcb_trace_id} violates via clearance to ${t.trace.pcb_trace_id} on ${e.layer}`})}for(const e of n.vias){for(const r of t.segments)!e.spanLayers.includes(r.layer)||N8(e.center,r.start,r.end)>=e.diameter/2+r.width/2+o-J8||t7(i,{code:"different-net-trace-via-clearance",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,layer:r.layer,message:`Via in ${n.trace.pcb_trace_id} violates trace clearance to ${t.trace.pcb_trace_id} on ${r.layer}`});for(const r of t.vias)!e.spanLayers.some(t=>r.spanLayers.includes(t))||M8(e.center,r.center)>=(e.diameter+r.diameter)/2+o-J8||t7(i,{code:"different-net-via-clearance",traceId:n.trace.pcb_trace_id,connectionName:n.connectionName,otherTraceId:t.trace.pcb_trace_id,otherConnectionName:t.connectionName,message:`Different-net vias in ${n.trace.pcb_trace_id} and ${t.trace.pcb_trace_id} violate clearance on an overlapping layer span`})}}}}return{valid:0===i.length,checkedTraceCount:n.traces?.length??0,checkedSegmentCount:s.reduce((t,e)=>t+e.segments.length,0),checkedViaCount:s.reduce((t,e)=>t+e.vias.length,0),issues:i}}var o7=1e-9;function i7(t,e){if("layer"in t)return t.layer;if(e&&t.layers.includes(e))return e;const n=t.layers[0];if(!n)throw new Error("Endpoint completion received a layerless point");return n}function r7(t){const e=[];for(const n of t)e.at(-1)&&M8(e.at(-1),n)<o7||e.push(n);return e}function s7(t,e){const n=r7(t);if(n.length<3)return n;const o=[n[0]];for(let t=1;t<n.length-1;t++){const i=n[t-1],r=n[t],s=n[t+1],a=M8(i,r),c=M8(r,s),l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c};if(Math.abs(l.x*d.x+l.y*d.y)>1e-6){o.push(r);continue}const h=Math.min(e,a/2,c/2);o.push({x:r.x-l.x*h,y:r.y-l.y*h}),o.push({x:r.x+d.x*h,y:r.y+d.y*h})}return o.push(n.at(-1)),r7(o)}function a7(t){const{inputSrj:e,plan:n}=t,o=i7(n.targetPoint),i=function(t){const{inputSrj:e,connectionName:n,target:o,targetLayer:i}=t;return e.obstacles.find(t=>t.layers.includes(i)&&Y8(e,t,n)&&R8(o,t,1e-6))}({inputSrj:e,connectionName:n.connectionName,target:n.targetPoint,targetLayer:o}),r=e.obstacles.find(t=>t.componentId===i?.componentId&&0===t.connectedTo.length),s=r?{x:n.targetPoint.x-r.center.x,y:n.targetPoint.y-r.center.y}:{x:n.targetPoint.x-n.sourcePoint.x,y:n.targetPoint.y-n.sourcePoint.y},a=Math.hypot(s.x,s.y),c=a>o7?{x:s.x/a,y:s.y/a}:{x:1,y:0};return{outward:c,perpendicular:{x:-c.y,y:c.x}}}function c7(t){const{plan:e,branchStart:n,viaPoint:o,assignedLayerPath:i,terminalApproach:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,candidateIndex:l,chamfer:d}=t,h=i7(e.targetPoint),u=s7(i,d),p=s7([o,...r?[r]:[],e.targetPoint],d),m=u.map(t=>({route_type:"wire",x:t.x,y:t.y,width:s,layer:n.layer}));n.layer!==h&&(m.push({route_type:"via",x:o.x,y:o.y,from_layer:n.layer,to_layer:h,via_diameter:a,via_hole_diameter:c}),m.push({route_type:"wire",x:o.x,y:o.y,width:s,layer:h}));for(const t of p.slice(1))m.push({route_type:"wire",x:t.x,y:t.y,width:s,layer:h});return{type:"pcb_trace",pcb_trace_id:(g={connectionName:e.connectionName,sourcePointIndex:e.sourcePointIndex,candidateIndex:l},`fanout-completion:${g.connectionName}:source-${g.sourcePointIndex}:${g.candidateIndex}`),connection_name:e.connectionName,route:m};var g}function l7(t,e){return!t.issues.some(t=>t.connectionName===e)}function d7(t){const{trace:e,endpointSrjs:n}=t,o=n.flatMap(t=>t.connections.flatMap(t=>t.pointsToConnect));return e.route.some(t=>"via"===t.route_type&&o.some(e=>M8(t,e)<=1e-6))}function h7(t){const{inputSrj:e,fanoutSrj:n,plan:o,acceptedTraces:i,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,clearance:c}=t,{outward:l,perpendicular:d}=a7({inputSrj:e,plan:o}),h=[...o.via?[{x:o.via.center.x,y:o.via.center.y,layer:o.targetLayer}]:[],{x:o.sourcePoint.x,y:o.sourcePoint.y,layer:o.sourceLayer}];let u=[],p=Number.POSITIVE_INFINITY,m=0;const g=e.connections.length>32?600:Number.POSITIVE_INFINITY,f="plane"===o.termination.type?g7({trace:o.trace,endpoint:o.exitPoint,layer:o.sourceLayer,distances:[.2,.3,.4]}):[],y=[..."plane"===o.termination.type&&o.via?[{...o.via.center}]:[],...f,...[.4,.8,1.2,1.6].flatMap(t=>[0,.4,-.4,.8,-.8,1.2,-1.2,1.6,-1.6].map(e=>({x:o.sourcePoint.x+l.x*t+d.x*e,y:o.sourcePoint.y+l.y*t+d.y*e})))];for(const t of y){const y=[..."plane"===o.termination.type?[{...t,layer:o.targetLayer}]:[],...h,...f.flatMap(e=>M8(e,t)<=1e-6?[{...e,layer:o.sourceLayer}]:[])];for(const h of y){const f=M8(h,t)<=1e-6?[[h]]:[[h,t],[h,{x:t.x,y:h.y},t],[h,{x:h.x,y:t.y},t],...[.4,-.4].map(e=>[h,{x:h.x+e,y:h.y},{x:h.x+e,y:t.y},t])];for(const y of f){const f=[void 0,...[.4,.8].map(t=>({x:o.targetPoint.x+l.x*t,y:o.targetPoint.y+l.y*t})),...[.4,-.4].map(t=>({x:o.targetPoint.x+.4*l.x+d.x*t,y:o.targetPoint.y+.4*l.y+d.y*t}))];for(const l of f){if(m>=g)return{blockingConnectionNames:u};const d=c7({plan:o,branchStart:h,viaPoint:t,assignedLayerPath:y,terminalApproach:l,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,candidateIndex:m++,chamfer:0});if(d7({trace:d,endpointSrjs:[e,n]}))continue;const f={...n,traces:[...n.traces??[],...i,d]},_=n7({inputSrj:e,routedSrj:f,clearance:c});if(!_.valid){_.issues.length<p&&(p=_.issues.length,u=[...new Set(_.issues.flatMap(t=>[t.connectionName,t.otherConnectionName].flatMap(t=>t&&t!==o.connectionName?[t]:[])))]);continue}if(l7(q8({inputSrj:e,routedSrj:f}),o.connectionName))return{trace:d,blockingConnectionNames:[]}}}}}return{blockingConnectionNames:u}}function u7(t){const{inputSrj:e,fanoutSrj:n,plans:o,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a}=t,c=[],l=[],d=new Set;for(const t of o){const o=h7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:c,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});if(o.trace)c.push(o.trace);else{l.push(t.connectionName);for(const t of o.blockingConnectionNames)d.add(t)}}const h={...n,traces:[...n.traces??[],...c]};return{traces:c,failedConnectionNames:l,blockingConnectionNames:[...d],connectivity:q8({inputSrj:e,routedSrj:h}),drc:n7({inputSrj:e,routedSrj:h,clearance:a})}}function p7(t){let e,n=0;for(const o of t.route)"wire"===o.route_type?(e?.layer===o.layer&&(n+=M8(e,o)),e=o):e=void 0;return n}function m7(t){const e=k8(t.layerCount),n=[];for(const o of t.traces??[]){let i;for(const r of o.route)if("via"!==r.route_type)if("wire"===r.route_type){if(i?.layer===r.layer){const t=M8(i,r);t>o7&&n.push({obstacleId:`endpoint-completion-keepout:${o.pcb_trace_id}:segment:${n.length}`,type:"rect",center:{x:(i.x+r.x)/2,y:(i.y+r.y)/2},width:t,height:Math.max(i.width,r.width),ccwRotationDegrees:180*Math.atan2(r.y-i.y,r.x-i.x)/Math.PI,layers:[r.layer],connectedTo:[o.connection_name]})}i=r}else i=void 0;else n.push({obstacleId:`endpoint-completion-keepout:${o.pcb_trace_id}:via:${n.length}`,type:"rect",center:{x:r.x,y:r.y},width:r.via_diameter??t.minViaPadDiameter??.3,height:r.via_diameter??t.minViaPadDiameter??.3,layers:L8(r.from_layer,r.to_layer,e),connectedTo:[o.connection_name]}),i=void 0}return n}function g7(t){const{trace:e,endpoint:n,layer:o,distances:i}=t,r=e.route.findLastIndex(t=>"wire"===t.route_type&&t.layer===o&&M8(t,n)<=1e-6);return r<0?[]:i.flatMap(t=>{let i=t,s=n;for(let t=r-1;t>=0;t--){const n=e.route[t];if("wire"!==n?.route_type||n.layer!==o)break;const r=M8(s,n);if(!(r<=o7)){if(i<r-1e-6)return[{x:s.x+(n.x-s.x)*i/r,y:s.y+(n.y-s.y)*i/r}];i-=r,s=n}}return[]})}function f7(t){const{inputSrj:e,fanoutSrj:n,plan:o,acceptedTraces:i,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,clearance:c}=t,l={x:o.exitPoint.x,y:o.exitPoint.y,layer:o.targetLayer},d=o.targetPoint,h=i7(d);let u=0;const p=t=>{const l=c7({plan:o,branchStart:t.start,viaPoint:t.viaPoint,assignedLayerPath:[t.start,t.viaPoint],terminalApproach:t.terminalApproach,traceWidth:r,viaDiameter:s,viaHoleDiameter:a,candidateIndex:1e4+u++,chamfer:Math.max(r,.1)});if(d7({trace:l,endpointSrjs:[e,n]}))return;const d={...n,traces:[...n.traces??[],...i,l]};return n7({inputSrj:e,routedSrj:d,clearance:c}).valid&&l7(q8({inputSrj:e,routedSrj:d}),o.connectionName)?l:void 0};if(l.layer!==h){const t=g7({trace:o.trace,endpoint:o.exitPoint,layer:o.targetLayer,distances:[.4,.8,1.2,1.6]});for(const e of t){const t={...e,layer:o.targetLayer};for(const n of[void 0,{x:d.x,y:e.y},{x:e.x,y:d.y}]){const o=p({start:t,viaPoint:e,terminalApproach:n});if(o)return o}}}const m=[[d],[{x:d.x,y:l.y},d],[{x:l.x,y:d.y},d]];for(const t of m){const e=t[0],n=M8(l,e),o=l.layer===h?[0]:[.4,.8,1.2,1.6];for(const i of o){if(l.layer!==h&&(n<=i+.2||i<=1e-6))continue;const o=p({start:l,viaPoint:l.layer===h?{x:l.x,y:l.y}:{x:l.x+(e.x-l.x)*i/n,y:l.y+(e.y-l.y)*i/n},terminalApproach:t.length>1?e:void 0});if(o)return o}}}function y7(t){const{inputSrj:e,fanoutSrj:n,plans:o,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a,effort:c=1,routeDownstreamConnections:l}=t,d=[],h=n7({inputSrj:e,routedSrj:n,clearance:a}),u=q8({inputSrj:e,routedSrj:n}),p=o.filter(t=>i7(t.sourcePoint)!==i7(t.targetPoint)&&M8(t.sourcePoint,t.targetPoint)<=.25&&!l7(u,t.connectionName));let m={traces:[],failedConnectionNames:p.map(t=>t.connectionName),blockingConnectionNames:[],connectivity:u,drc:h},g=0;if(h.valid){let t=[];const o=new Map(p.map((t,e)=>[t.connectionName,e])),c=e.connections.length>32?1:3;for(let l=0;l<c;l++){const c=new Map(t.map((t,e)=>[t,e])),l=u7({inputSrj:e,fanoutSrj:n,plans:p.toSorted((t,e)=>(c.get(t.connectionName)??Number.MAX_SAFE_INTEGER)-(c.get(e.connectionName)??Number.MAX_SAFE_INTEGER)||(o.get(t.connectionName)??0)-(o.get(e.connectionName)??0)),traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});if(g++,l.drc.valid&&(l.connectivity.connectedConnectionCount>m.connectivity.connectedConnectionCount||l.connectivity.connectedConnectionCount===m.connectivity.connectedConnectionCount&&l.traces.length<m.traces.length)&&(m=l),t=[...new Set([...l.failedConnectionNames,...l.blockingConnectionNames,...t])],0===l.failedConnectionNames.length)break}}else d.push("Fanout prefix failed emitted-copper DRC; skipped completion");const f=new Set(p.map(t=>t.connectionName)),y=o.filter(t=>!f.has(t.connectionName)&&!l7(u,t.connectionName)),_=[];if(h.valid)for(const t of y){const o=f7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:[...m.traces,..._],traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});o&&_.push(o)}const b={...n,traces:[...n.traces??[],...m.traces,..._]},x=new Set(q8({inputSrj:e,routedSrj:b}).issues.map(t=>t.connectionName)),v=n.connections.filter(t=>!f.has(t.name)&&x.has(t.name));let S=[];if(h.valid&&v.length>0&&v.length<=12&&l){const t=new Set(v.map(t=>t.name)),o={...n,connections:v,buses:n.buses?.map(e=>({...e,connectionNames:e.connectionNames.filter(e=>t.has(e))})).filter(t=>t.connectionNames.length>0),obstacles:[...n.obstacles,...m7(n)],traces:[]};try{const i=l(o,{effort:c});S=function(t){const{inputSrj:e,fanoutSrj:n,localTraces:o,candidates:i,clearance:r}=t,s=[...n.traces??[],...o],a={...n,traces:s},c=q8({inputSrj:e,routedSrj:a}),l=i.filter(t=>t.route.length>1&&t.route.every(t=>"wire"===t.route_type||"via"===t.route_type)&&!d7({trace:t,endpointSrjs:[e,n]})).filter(t=>{const o=q8({inputSrj:e,routedSrj:{...n,traces:[...s,t]}});return o.connectedConnectionCount>c.connectedConnectionCount&&l7(o,t.connection_name)}),d={...n,traces:[...s,...l]};if(n7({inputSrj:e,routedSrj:d,clearance:r}).valid)return l;const h=[];for(const t of l.toSorted((t,e)=>p7(t)-p7(e))){const o={...n,traces:[...s,...h,t]};if(!n7({inputSrj:e,routedSrj:o,clearance:r}).valid)continue;const i=q8({inputSrj:e,routedSrj:{...n,traces:[...s,...h]}}),a=q8({inputSrj:e,routedSrj:o});a.connectedConnectionCount>i.connectedConnectionCount&&l7(a,t.connection_name)&&h.push(t)}return h}({inputSrj:e,fanoutSrj:n,localTraces:[...m.traces,..._],candidates:i.filter(e=>t.has(e.connection_name)),clearance:a})}catch(t){d.push(`Downstream router failed: ${t instanceof Error?t.message:String(t)}`)}}else!h.valid&&v.length>0?d.push("Skipped downstream router because the endpoint-completion baseline failed emitted-copper DRC"):v.length>12?d.push(`Skipped downstream router for ${v.length} unresolved connections (bounded at 12)`):v.length>0&&!l&&d.push(`Skipped downstream router for ${v.length} unresolved connections because no routeDownstreamConnections callback was provided`);const I=[...m.traces,..._,...S];for(const t of y){if(l7(q8({inputSrj:e,routedSrj:{...n,traces:[...n.traces??[],...I]}}),t.connectionName))continue;const o=f7({inputSrj:e,fanoutSrj:n,plan:t,acceptedTraces:I,traceWidth:i,viaDiameter:r,viaHoleDiameter:s,clearance:a});o&&I.push(o)}const C=function(t){const{fanoutSrj:e,completionTraces:n}=t,o=new Map(n.flatMap(t=>{const e=t.route.find(t=>"wire"===t.route_type);return e?[[t.connection_name,{x:e.x,y:e.y,layer:e.layer}]]:[]})),i=(e.traces??[]).map(t=>{if(!t.pcb_trace_id.startsWith("fanout:"))return t;const e=o.get(t.connection_name);if(!e)return t;let n;for(let o=0;o<t.route.length;o++){const i=t.route[o];if("wire"===i?.route_type){if(void 0!==n){const o=t.route[n];if("wire"===o?.route_type&&o.layer===e.layer&&i.layer===e.layer&&N8(e,o,i)<=1e-6){const r=t.route.slice(0,n+1);return M8(o,e)>1e-6&&r.push({route_type:"wire",x:e.x,y:e.y,width:i.width,layer:e.layer}),{...t,route:r}}}n=o}else n=void 0}return t});return{...e,traces:i}}({fanoutSrj:{...n,traces:[...n.traces??[],...I]},completionTraces:I}),P=q8({inputSrj:e,routedSrj:C}),M=n7({inputSrj:e,routedSrj:C,clearance:a});return M.valid?{simpleRouteJson:C,traces:I,report:{attemptedLocalConnectionCount:p.length,attemptedDownstreamConnectionCount:y.length,completionTraceCount:I.length,searchPassCount:g,errors:d,connectivity:P,drc:M}}:(d.push("Final endpoint-completion output failed emitted-copper DRC"),{simpleRouteJson:n,traces:[],report:{attemptedLocalConnectionCount:p.length,attemptedDownstreamConnectionCount:y.length,completionTraceCount:0,searchPassCount:g,errors:d,connectivity:q8({inputSrj:e,routedSrj:n}),drc:h}})}var _7=new Set(["left","right","top","bottom","top-left","top-right","bottom-left","bottom-right"]),b7={top_left:{direction:"up",preferredExit:"top-left"},top_middle:{direction:"up",preferredExit:"top"},top_right:{direction:"up",preferredExit:"top-right"},right_top:{direction:"right",preferredExit:"top-right"},right_middle:{direction:"right",preferredExit:"right"},right_bottom:{direction:"right",preferredExit:"bottom-right"},bottom_right:{direction:"down",preferredExit:"bottom-right"},bottom_middle:{direction:"down",preferredExit:"bottom"},bottom_left:{direction:"down",preferredExit:"bottom-left"},left_bottom:{direction:"left",preferredExit:"bottom-left"},left_middle:{direction:"left",preferredExit:"left"},left_top:{direction:"left",preferredExit:"top-left"},top:{direction:"up",preferredExit:"top"},right:{direction:"right",preferredExit:"right"},bottom:{direction:"down",preferredExit:"bottom"},left:{direction:"left",preferredExit:"left"}};function x7(t){const e=[...t].sort((t,e)=>t-e),n=[];for(const t of e)(0===n.length||Math.abs(n[n.length-1]-t)>1e-6)&&n.push(t);return n}function v7(t){let e=Number.POSITIVE_INFINITY;for(let n=1;n<t.length;n++){const o=t[n]-t[n-1];o>1e-6&&(e=Math.min(e,o))}return e}function S7(t,e){const n="x"===e?"y":"x";let o=Number.POSITIVE_INFINITY;for(let i=0;i<t.length;i++){const r=t[i];for(let s=i+1;s<t.length;s++){const i=t[s];if(Math.abs(r.center[n]-i.center[n])>1e-6)continue;const a=Math.abs(r.center[e]-i.center[e]);a>1e-6&&(o=Math.min(o,a))}}return o}function I7(t){return{minX:Math.min(...t.map(t=>t.center.x-t.width/2)),maxX:Math.max(...t.map(t=>t.center.x+t.width/2)),minY:Math.min(...t.map(t=>t.center.y-t.height/2)),maxY:Math.max(...t.map(t=>t.center.y+t.height/2))}}function C7(t,e){const n=e.componentBounds?.[t.componentId];if(!n){const e=2.25*t.pitchX,n=2.25*t.pitchY;return{minX:t.bounds.minX-e,maxX:t.bounds.maxX+e,minY:t.bounds.minY-n,maxY:t.bounds.maxY+n}}if([n.minX,n.maxX,n.minY,n.maxY].some(t=>!Number.isFinite(t))||n.minX>=n.maxX||n.minY>=n.maxY)throw new Error(`FanoutSolver: componentBounds for "${t.componentId}" must contain finite, increasing bounds`);if(n.minX>t.bounds.minX+1e-6||n.maxX<t.bounds.maxX-1e-6||n.minY>t.bounds.minY+1e-6||n.maxY<t.bounds.maxY-1e-6)throw new Error(`FanoutSolver: componentBounds for "${t.componentId}" must contain every component pad`);return{...n}}function P7(t,e){if([t.minX,t.maxX,t.minY,t.maxY].some(t=>!Number.isFinite(t))||t.minX>=t.maxX||t.minY>=t.maxY)throw new Error("FanoutSolver: sharedBoundary must contain finite, increasing bounds");for(const n of e)if(t.minX>n.bounds.minX+1e-6||t.maxX<n.bounds.maxX-1e-6||t.minY>n.bounds.minY+1e-6||t.maxY<n.bounds.maxY-1e-6)throw new Error(`FanoutSolver: sharedBoundary must contain every pad of component "${n.componentId}"`);return{...t}}function M7(t){return"layer"in t?[t.layer]:t.layers}function N7(t){const{point:e,connection:n,componentGrids:o}=t,i=M7(e),r=[];for(const t of o){const o=t.obstacles.filter(t=>t.layers.some(t=>i.includes(t))).filter(t=>R8(e,t,1e-5)).sort((t,o)=>{const i=t.connectedTo.includes(n.name)||t.connectedTo.includes(e.pointId??"")||t.connectedTo.includes(e.pcb_port_id??"");return i!==(o.connectedTo.includes(n.name)||o.connectedTo.includes(e.pointId??"")||o.connectedTo.includes(e.pcb_port_id??""))?i?-1:1:t.width*t.height-o.width*o.height});o[0]&&r.push({grid:t,obstacle:o[0]})}return r}function w7(t){for(const e of t.pointsToConnect)if("layers"in e&&e.busId)return e.busId;const e=/^BUS[_:-]([^_:-]+)(?:[_:-]\d+)?$/i.exec(t.name);return e?.[1]??null}function T7(t,e){if(void 0!==e){if(!_7.has(e))throw new Error(`FanoutSolver: bus "${t}" has invalid preferredExit "${e}"`);return e}}function R7(t){if(void 0===t)return;if(0===t.length)throw new Error("FanoutSolver: availableCornersAndSides must contain at least one boundary region");const e=[],n=new Set;for(const o of t){const t=b7[o];if(!t)throw new Error(`FanoutSolver: invalid availableCornersAndSides value "${o}"`);const i=`${t.direction}:${t.preferredExit}`;n.has(i)||(n.add(i),e.push(t))}return e}function E7(t,e){if(void 0===e||"boundary"===e.type)return{type:"boundary"};if("plane"!==e.type||"string"!=typeof e.layer||0===e.layer.length)throw new Error(`FanoutSolver: bus "${t}" has an invalid termination target`);return{type:"plane",layer:e.layer}}function A7(t,e,n,o){const i=e.pointsToConnect.filter((t,e)=>e!==n).sort((e,n)=>M8(t,n)-M8(t,e))[0];if(!i&&"plane"===o.type)return t;if(!i)throw new Error(`FanoutSolver: connection "${e.name}" has no target beyond its BGA pad`);return i}function O7(t,e){let n=0,o=0;for(const t of e){const e=t.exitTargetPoint??t.targetPoint;n+=e.x-t.sourcePoint.x,o+=e.y-t.sourcePoint.y}if(Math.abs(n)<1e-9&&Math.abs(o)<1e-9)throw new Error(`FanoutSolver: cannot infer an escape direction for bus "${t}"`);return Math.abs(n)>=Math.abs(o)?n>=0?"right":"left":o>=0?"up":"down"}function k7(t){return{x:t.reduce((t,e)=>t+e.sourcePoint.x,0)/t.length,y:t.reduce((t,e)=>t+e.sourcePoint.y,0)/t.length}}function L7(t,e,n){switch(e){case"left":return t.x-n.minX;case"right":return n.maxX-t.x;case"up":return n.maxY-t.y;case"down":return t.y-n.minY}}function D7(t,e){return"up"===t.direction||"down"===t.direction?t.preferredExit.endsWith("left")?e.minX:t.preferredExit.endsWith("right")?e.maxX:(e.minX+e.maxX)/2:t.preferredExit.startsWith("top")?e.maxY:t.preferredExit.startsWith("bottom")?e.minY:(e.minY+e.maxY)/2}function z7(t,e){return"up"===e||"down"===e?t.x:t.y}function F7(t){const{busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s}=t,a=s.filter(t=>!(void 0!==n&&t.direction!==n||void 0!==o&&t.preferredExit!==o));if(0===a.length)throw new Error(`FanoutSolver: bus "${e}" cannot use its requested exit with availableCornersAndSides`);const c=n?void 0:function(t,e){try{return O7(t,e)}catch{return}}(e,i),l=c?a.filter(t=>t.direction===c):[],d=l.length>0?l:a,h=k7(i);return[...d].toSorted((t,e)=>L7(h,t.direction,r)-L7(h,e.direction,r)||Math.abs(z7(h,t.direction)-D7(t,r))-Math.abs(z7(h,e.direction)-D7(e,r))||t.preferredExit.localeCompare(e.preferredExit))[0]}function B7(t){const{busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s}=t;if(s)return F7({busId:e,explicitDirection:n,preferredExit:o,connections:i,sharedBoundary:r,availableRegions:s});if(!o)return{direction:n??O7(e,i)};const a=function(t){switch(t){case"left":return["left"];case"right":return["right"];case"top":return["up"];case"bottom":return["down"];case"top-left":return["up","left"];case"top-right":return["up","right"];case"bottom-left":return["down","left"];case"bottom-right":return["down","right"]}}(o);if(n){if(!a.includes(n))throw new Error(`FanoutSolver: bus "${e}" direction "${n}" is incompatible with preferredExit "${o}"`);return{direction:n,preferredExit:o}}if(1===a.length)return{direction:a[0],preferredExit:o};let c;try{c=O7(e,i)}catch{c=void 0}if(c&&a.includes(c))return{direction:c,preferredExit:o};const l=k7(i);return{direction:a.toSorted((t,e)=>L7(l,t,r)-L7(l,e,r)||t.localeCompare(e))[0],preferredExit:o}}function j7(t,e){const n=function(t){const e=new Map;for(const n of t){if(!n.componentId||n.isCopperPour)continue;const t=e.get(n.componentId)??[];t.push(n),e.set(n.componentId,t)}const n=[];for(const[t,o]of e){const e=x7(o.map(t=>t.center.x)),i=x7(o.map(t=>t.center.y)),r=S7(o,"x"),s=S7(o,"y"),a=v7(e),c=v7(i),l=Math.min(...[r,s,a,c].filter(Number.isFinite)),d=Math.max(...o.flatMap(t=>[t.width,t.height])),h=Number.isFinite(l)?l:d,u=Number.isFinite(r)?r:Number.isFinite(a)?a:h,p=Number.isFinite(s)?s:Number.isFinite(c)?c:h;n.push({componentId:t,obstacles:o,xCoordinates:e,yCoordinates:i,pitchX:u,pitchY:p,bounds:I7(o)})}return n}(t.obstacles);if(0===n.length&&t.connections.length>0)throw new Error("FanoutSolver: no componentId-tagged pad footprint was found");const o=new Map(t.connections.map((t,e)=>[t.name,e])),i=function(t,e){const n=e.buses??t.buses,o=new Map,i=new Set,r=new Set(t.connections.map(t=>t.name));for(const t of n??[]){if(o.has(t.busId))throw new Error(`FanoutSolver: duplicate bus id "${t.busId}"`);for(const e of t.connectionNames){if(!r.has(e))throw new Error(`FanoutSolver: bus "${t.busId}" references unknown connection "${e}"`);if(i.has(e))throw new Error(`FanoutSolver: connection "${e}" belongs to more than one bus`);i.add(e)}const n=E7(t.busId,t.termination),s=T7(t.busId,e.busExitPreferences?.[t.busId]??t.preferredExit??e.defaultPreferredExit);if("plane"===n.type&&void 0!==s)throw new Error(`FanoutSolver: plane-terminated bus "${t.busId}" cannot also specify preferredExit`);o.set(t.busId,{...t,sourceComponentId:t.sourceComponentId??e.sourceComponentId,direction:e.busDirections?.[t.busId]??t.direction??e.defaultDirection,preferredExit:s,termination:n})}for(const n of t.connections){if(i.has(n.name))continue;const t=w7(n);if(t){const i=o.get(t);o.set(t,{busId:t,connectionNames:[...i?.connectionNames??[],n.name],direction:e.busDirections?.[t]??i?.direction??e.defaultDirection,sourceComponentId:i?.sourceComponentId??e.sourceComponentId,preferredExit:T7(t,e.busExitPreferences?.[t]??i?.preferredExit??e.defaultPreferredExit),termination:i?.termination??{type:"boundary"}})}else{const t=`connection:${n.name}`;o.set(t,{busId:t,connectionNames:[n.name],sourceComponentId:e.sourceComponentId,direction:e.busDirections?.[t]??e.defaultDirection,preferredExit:T7(t,e.busExitPreferences?.[t]??e.defaultPreferredExit),termination:{type:"boundary"}})}}return[...o.values()]}(t,e).map(e=>{for(const[t,n]of Object.entries(e.connectionExitTargets??{})){if(!e.connectionNames.includes(t))throw new Error(`FanoutSolver: connectionExitTargets contains connection "${t}" outside bus "${e.busId}"`);if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error(`FanoutSolver: connectionExitTargets for connection "${t}" must contain finite x and y coordinates`)}const i=e.connectionNames.map(e=>{const n=o.get(e);if(void 0===n)throw new Error(`FanoutSolver: connection "${e}" is missing from the input`);return t.connections[n]}),r=function(t){const{busSpec:e,connections:n,componentGrids:o}=t,i=new Map;for(const t of n){const e=new Set;for(const n of t.pointsToConnect)for(const i of N7({point:n,connection:t,componentGrids:o}))e.add(i.grid.componentId);for(const t of e)i.set(t,(i.get(t)??0)+1)}const r=[...o].sort((t,e)=>{const n=(i.get(e.componentId)??0)-(i.get(t.componentId)??0);return 0!==n?n:e.obstacles.length-t.obstacles.length})[0],s=e.sourceComponentId?o.find(t=>t.componentId===e.sourceComponentId):void 0;if(e.sourceComponentId&&!s)throw new Error(`FanoutSolver: source component "${e.sourceComponentId}" for bus "${e.busId}" was not found`);const a=s??r,c=a?i.get(a.componentId)??0:0;if(!a||c!==n.length)throw new Error(e.sourceComponentId?`FanoutSolver: source component "${e.sourceComponentId}" is not an endpoint on every connection in bus "${e.busId}"`:`FanoutSolver: bus "${e.busId}" does not have one component endpoint on every connection`);return a}({busSpec:e,connections:i,componentGrids:n}),s=i.map(t=>function(t){const{connection:e,connectionIndex:n,sourceGrid:o,componentGrids:i,termination:r,exitTargetPoint:s}=t;for(let t=0;t<e.pointsToConnect.length;t++){const a=e.pointsToConnect[t],c=N7({point:a,connection:e,componentGrids:i}).find(t=>t.grid.componentId===o.componentId);if(!c)continue;const l=M7(a).find(t=>c.obstacle.layers.includes(t));if(!l)throw new Error(`FanoutSolver: connection "${e.name}" has no source layer shared with its BGA pad`);const d=A7(a,e,t,r);return{connection:e,connectionIndex:n,sourcePoint:a,sourcePointIndex:t,sourceLayer:l,sourceObstacle:c.obstacle,targetPoint:d,exitTargetPoint:s??d}}throw new Error(`FanoutSolver: connection "${e.name}" does not touch component "${o.componentId}"`)}({connection:t,connectionIndex:o.get(t.name),sourceGrid:r,componentGrids:n,termination:e.termination??{type:"boundary"},exitTargetPoint:e.connectionExitTargets?.[t.name]}));return{busSpec:e,sourceGrid:r,preparedConnections:s}}),r=function(t,e){if(e.sharedBoundary)return P7(e.sharedBoundary,t);const n=t.map(t=>C7(t,e)),o=2.25*Math.max(...t.flatMap(t=>[t.pitchX,t.pitchY]));return P7({minX:Math.min(...n.map(t=>t.minX))-o,maxX:Math.max(...n.map(t=>t.maxX))+o,minY:Math.min(...n.map(t=>t.minY))-o,maxY:Math.max(...n.map(t=>t.maxY))+o},t)}([...new Map(i.map(({sourceGrid:t})=>[t.componentId,t])).values()],e),s=R7(e.availableCornersAndSides),a=[];for(const{busSpec:t,sourceGrid:n,preparedConnections:o}of i){const i=B7({busId:t.busId,explicitDirection:t.direction??e.busDirections?.[t.busId],preferredExit:t.preferredExit,connections:o,sharedBoundary:r,availableRegions:"plane"===t.termination?.type?void 0:s});a.push({busId:t.busId,direction:i.direction,preferredExit:i.preferredExit,termination:t.termination??{type:"boundary"},connections:o,componentId:n.componentId,componentObstacles:n.obstacles,componentBounds:C7(n,e),sharedBoundary:r,xCoordinates:[...n.xCoordinates],yCoordinates:[...n.yCoordinates],pitchX:n.pitchX,pitchY:n.pitchY})}return a}function $7(t){return"left"===t||"right"===t}function Y7(t){return"right"===t||"up"===t?1:-1}function X7(t,e){return $7(e)?t.x:t.y}function V7(t,e){return $7(e)?t.y:t.x}function W7(t,e,n){return $7(n)?{x:t,y:e}:{x:e,y:t}}function H7(t){switch(t.direction){case"right":return t.sharedBoundary.maxX;case"left":return t.sharedBoundary.minX;case"up":return t.sharedBoundary.maxY;case"down":return t.sharedBoundary.minY}}function G7(t){return $7(t.direction)?t.pitchX:t.pitchY}function U7(t){const e=$7(t.direction)?t.xCoordinates:t.yCoordinates,n=t.connections.reduce((e,n)=>e+X7(n.sourcePoint,t.direction),0)/t.connections.length,o=Y7(t.direction)>0?Math.max(...e):Math.min(...e);return Math.abs(n-o)<1e-6}function Z7(t,e){const n=[...t.connections].sort((e,n)=>V7(e.sourcePoint,t.direction)-V7(n.sourcePoint,t.direction)).findIndex(t=>t.connectionIndex===e.connectionIndex);if(n<0)throw new Error(`FanoutSolver: connection "${e.connection.name}" is missing from bus "${t.busId}"`);return n}function q7(t,e){return t.x>=e.minX-1e-6&&t.x<=e.maxX+1e-6&&t.y>=e.minY-1e-6&&t.y<=e.maxY+1e-6}function J7(t,e,n,o,i){const r=e-t,s=Math.floor((r-o)/(n+o)+1e-9);if(s<1)return[];const a=t+(r-(s*n+(s-1)*o))/2+n/2;return Array.from({length:s},(t,e)=>({value:a+e*(n+o),kind:i}))}function K7(t){const e=V7(t.connection.exitTargetPoint??t.connection.targetPoint,t.bus.direction),n=$7(t.bus.direction)?t.bus.sharedBoundary.minY:t.bus.sharedBoundary.minX,o=$7(t.bus.direction)?t.bus.sharedBoundary.maxY:t.bus.sharedBoundary.maxX;return Math.max(n+t.traceWidth/2,Math.min(o-t.traceWidth/2,e))}function Q7(t){const{bus:e,connection:n,targetUsesVia:o,interstitialEscape:i,compactBusTracks:r,traceWidth:s,viaDiameter:a,clearance:c}=t,l=($7(e.direction)?e.yCoordinates:e.xCoordinates).toSorted((t,e)=>t-e),d=V7(n.sourcePoint,e.direction);if(r){const t=Z7(e,n);return(l[0]+l.at(-1))/2+(t-(e.connections.length-1)/2)*(s+c)}if(!o||!i)return d;const h=function(t){const e=($7(t.direction)?t.xCoordinates:t.yCoordinates).toSorted((t,e)=>t-e),n=t.connections.reduce((e,n)=>e+X7(n.sourcePoint,t.direction),0)/t.connections.length,o=Y7(t.direction)>0?e.at(-1):e[0];return Math.abs(o-n)/G7(t)}(e),u=s+c,p=Math.ceil(e.connections.length/2),m=(p-1)*u,g=a/2+s/2+c+.001,f=Math.round(h)+1,y=f*g+(f-1)*m,_=Z7(e,n),b=l[0],x=l.at(-1),v=_<p?b-y-(p-_-1)*u:x+y+(_-p)*u,S=$7(e.direction)?e.sharedBoundary.minY:e.sharedBoundary.minX,I=$7(e.direction)?e.sharedBoundary.maxY:e.sharedBoundary.maxX;return Math.max(S+s/2,Math.min(I-s/2,v))}function ttt(t){const e=Y7(t.direction),n=[...t.connections].sort((n,o)=>{const i=e*(X7(o.sourcePoint,t.direction)-X7(n.sourcePoint,t.direction));return Math.abs(i)>1e-6?i:V7(n.sourcePoint,t.direction)-V7(o.sourcePoint,t.direction)}),o=[...t.connections].sort((n,o)=>V7(n.sourcePoint,t.direction)-V7(o.sourcePoint,t.direction)||e*(X7(o.sourcePoint,t.direction)-X7(n.sourcePoint,t.direction))),i=[n,[...n].reverse(),o,[...o].reverse()];for(let t=1;t<Math.min(n.length,8);t++)i.push([...n.slice(t),...n.slice(0,t)]);return i}function ett(t,e,n,o,i){M8(e,n)<1e-9||t.push({start:e,end:n,width:o,layer:i})}function ntt(t){const{preparedConnection:e,bus:n,targetLayer:o,track:i,exitAxis:r,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,viaHandedness:d,interstitialEscape:h,spreadLaneIndex:u,clearance:p,terminateAtVia:m}=t,g={x:e.sourcePoint.x,y:e.sourcePoint.y},f=Y7(n.direction),y=G7(n),_=function(t){return $7(t.direction)?t.pitchY:t.pitchX}(n),b=o!==e.sourceLayer,x=$7(n.direction)?e.sourceObstacle.width:e.sourceObstacle.height,v=b&&!U7(n)?x>=y?x/2+c/2+p+.001:.5*y:b?Math.max(.5*y,x/2+(b?c:a)/2+p+.001):x/2+a/2+p+.001,S=X7(g,n.direction)+f*v,I=V7(g,n.direction)+d*_*.5,C=W7(S,I,n.direction),P=c/2+a/2+p+.001+u*(a+p),M=h&&y>=P+c/2+p,N=M?W7(S+f*P,I,n.direction):C,w=W7(M?X7(N,n.direction):S+f*Math.abs(i-I),i,n.direction),T=m?C:W7(r,i,n.direction),R=[],E=[];let A;if(E.push({route_type:"wire",x:g.x,y:g.y,width:a,layer:e.sourceLayer,start_pcb_port_id:e.sourcePoint.pcb_port_id}),ett(R,g,C,a,e.sourceLayer),E.push({route_type:"wire",x:C.x,y:C.y,width:a,layer:e.sourceLayer}),o!==e.sourceLayer){const t=L8(e.sourceLayer,o,s);A={center:C,diameter:c,holeDiameter:l,fromLayer:e.sourceLayer,toLayer:o,spanLayers:t},E.push({route_type:"via",x:C.x,y:C.y,from_layer:e.sourceLayer,to_layer:o,via_diameter:c,via_hole_diameter:l}),E.push({route_type:"wire",x:C.x,y:C.y,width:a,layer:o})}const O=m?[C]:M?function(t,e){if(t.length<3)return t;const n=[t[0]];for(let o=1;o<t.length-1;o++){const i=t[o-1],r=t[o],s=t[o+1],a=M8(i,r),c=M8(r,s);if(a<1e-9||c<1e-9)continue;const l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c},h=l.x*d.x+l.y*d.y;if(Math.abs(h)>1e-6){n.push(r);continue}const u=Math.min(e,a/2,c/2);n.push({x:r.x-l.x*u,y:r.y-l.y*u}),n.push({x:r.x+d.x*u,y:r.y+d.y*u})}return n.push(t.at(-1)),n}([C,N,w,T],Math.max(a+p,2*a)):[C,w,T];for(let t=1;t<O.length;t++){const e=O[t-1],n=O[t];ett(R,e,n,a,o),E.push({route_type:"wire",x:n.x,y:n.y,width:a,layer:o})}const k=x8({connectionName:e.connection.name,sourcePointIndex:e.sourcePointIndex});return{busId:n.busId,connectionName:e.connection.name,connectionIndex:e.connectionIndex,sourcePointIndex:e.sourcePointIndex,sourcePoint:e.sourcePoint,sourceObstacle:e.sourceObstacle,sourceLayer:e.sourceLayer,targetPoint:e.targetPoint,targetLayer:o,termination:n.termination,direction:n.direction,exitPoint:T,trace:{type:"pcb_trace",pcb_trace_id:k.traceId,connection_name:e.connection.name,connectsTo:[...e.sourcePoint.pointId?[e.sourcePoint.pointId]:[],...e.sourcePoint.pcb_port_id?[e.sourcePoint.pcb_port_id]:[],k.boundaryExitPointId],route:E},segments:R,via:A,length:R.reduce((t,e)=>t+M8(e.start,e.end),0)}}function ott(t){const{preparedConnection:e,bus:n,viaDiameter:o,clearance:i}=t,{sourcePoint:r,targetPoint:s}=e,a=.5*Math.max(n.pitchX,n.pitchY);if(M8(r,s)<=1e-6||M8(r,s)>a)return[];const c=(()=>{switch(n.direction){case"left":return{x:-1,y:0};case"right":return{x:1,y:0};case"up":return{x:0,y:1};case"down":return{x:0,y:-1}}})(),l=Math.SQRT1_2,d=[c,...[{x:l,y:l},{x:l,y:-l},{x:-l,y:l},{x:-l,y:-l},{x:1,y:0},{x:-1,y:0},{x:0,y:1},{x:0,y:-1}].toSorted((t,e)=>e.x*c.x+e.y*c.y-(t.x*c.x+t.y*c.y))],h=Math.max(o,o/2+i),u=[h,Math.max(h,.5*Math.min(n.pitchX,n.pitchY)),Math.max(h,.625*Math.min(n.pitchX,n.pitchY)),Math.max(h,.75*Math.min(n.pitchX,n.pitchY))],p=[];for(const t of[r,s])for(const e of u)for(const n of d){const o={x:t.x+n.x*e,y:t.y+n.y*e};M8(o,r)<=1e-6||M8(o,s)<=1e-6||p.some(t=>M8(t,o)<=1e-6)||p.push(o)}return p}function itt(t){const{plan:e,preparedConnection:n,planeLayer:o,viaPoint:i,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c}=t,l={x:n.targetPoint.x,y:n.targetPoint.y},d=function(t){const e="layer"in t?t.layer:t.layers[0];if(!e)throw new Error("FanoutSolver: plane endpoint has no copper layer");return e}(n.targetPoint),h=L8(o,d,r);if(!h.includes(o))throw new Error(`FanoutSolver: via for "${n.connection.name}" does not cross plane ${o}`);const u=[{start:i,end:l,width:s,layer:d}],p={center:i,diameter:a,holeDiameter:c,fromLayer:o,toLayer:d,spanLayers:h},m=x8({connectionName:n.connection.name,sourcePointIndex:n.sourcePointIndex}),g={type:"pcb_trace",pcb_trace_id:m.planeEndpointTraceId,connection_name:n.connection.name,connectsTo:[...n.targetPoint.pointId?[n.targetPoint.pointId]:[],...n.targetPoint.pcb_port_id?[n.targetPoint.pcb_port_id]:[],m.planeEndpointPointId],route:[{route_type:"wire",...i,width:s,layer:o},{route_type:"via",...i,from_layer:o,to_layer:d,via_diameter:a,via_hole_diameter:c},{route_type:"wire",...i,width:s,layer:d},{route_type:"wire",...l,width:s,layer:d}]};return{...e,planeEndpointTrace:g,planeEndpointSegments:u,planeEndpointVia:p,length:e.length+u.reduce((t,e)=>t+M8(e.start,e.end),0)}}function rtt(t){const{segment:e,plan:n,segmentIndex:o,srj:i,allowSameNetMerges:r,obstacles:s,clearance:a}=t;for(const t of s)if(t.layers.includes(e.layer)&&!t.connectedTo.includes(n.connectionName)&&!(r&&Y8(i,t,n.connectionName)||K8({inputSrj:i,segment:e,bodyObstacle:t,connectionName:n.connectionName})||0===o&&t===n.sourceObstacle&&e.layer===n.sourceLayer||!(A8(e,t)<e.width/2+a-1e-9)))return!1;return!0}function stt(t){return[...t.segments,...t.planeEndpointSegments??[]]}function att(t){return[t.via,t.planeEndpointVia].filter(t=>Boolean(t))}function ctt(t){const{plan:e,srj:n,sharedBoundary:o,clearance:i,allowSameNetMerges:r}=t,s=function(t,e){return{minX:Math.min(t.minX,e.minX),maxX:Math.max(t.maxX,e.maxX),minY:Math.min(t.minY,e.minY),maxY:Math.max(t.maxY,e.maxY)}}(n.bounds,o);if(!q7(e.exitPoint,s)||stt(e).some(t=>!q7(t.start,s)||!q7(t.end,s)))return!1;const a=stt(e);for(let t=0;t<a.length;t++)if(!rtt({segment:a[t],plan:e,segmentIndex:t<e.segments.length?t:-1,srj:n,allowSameNetMerges:r,obstacles:n.obstacles,clearance:i}))return!1;for(const t of att(e))for(const o of n.obstacles)if(o.layers.some(e=>t.spanLayers.includes(e))&&(!r||!Y8(n,o,e.connectionName))&&E8(t.center,o)<t.diameter/2+i-1e-9)return!1;return!0}function ltt(t){const{plan:e,otherPlans:n,staticClearanceCache:o,blockingBusCounts:i,cacheKey:r,srj:s,sharedBoundary:a,clearance:c,allowSameNetMerges:l}=t;let d=o?.get(r);return void 0===d&&(d=ctt({plan:e,srj:s,sharedBoundary:a,clearance:c,allowSameNetMerges:l}),o?.set(r,d)),d&&function(t){const{plan:e,otherPlans:n,srj:o,allowSameNetMerges:i,clearance:r,blockingBusCounts:s}=t;for(const t of n){if(i&&$8(o,e.connectionName,t.connectionName))continue;if(e.sourcePoint.pcb_port_id&&e.sourcePoint.pcb_port_id===t.sourcePoint.pcb_port_id||e.sourcePoint.pointId&&e.sourcePoint.pointId===t.sourcePoint.pointId)continue;const n=()=>{t.busId!==e.busId&&s?.set(t.busId,(s.get(t.busId)??0)+1)},a=stt(e),c=stt(t),l=att(e),d=att(t);for(const t of a){for(const e of c)if(!O8(t,e,r))return n(),!1;for(const e of d)if(e.spanLayers.includes(t.layer)&&N8(e.center,t.start,t.end)<e.diameter/2+t.width/2+r-1e-9)return n(),!1}for(const t of l){for(const e of c)if(t.spanLayers.includes(e.layer)&&N8(t.center,e.start,e.end)<t.diameter/2+e.width/2+r-1e-9)return n(),!1;for(const e of d)if(t.spanLayers.some(t=>e.spanLayers.includes(t))&&M8(t.center,e.center)<(t.diameter+e.diameter)/2+r-1e-9)return n(),!1}}return!0}({plan:e,otherPlans:n,srj:s,allowSameNetMerges:l,clearance:c,blockingBusCounts:i})}function dtt(t,e=1){const{srj:n,bus:o,targetLayer:i,acceptedPlans:r,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,clearance:d,compactBusTracks:h,staticClearanceCache:u,blockingBusCounts:p,allowSameNetMerges:m=!1}=t;if(!Number.isInteger(e)||e<1)throw new Error(`FanoutSolver: maxAlternatives must be a positive integer, received ${e}`);if("plane"===o.termination.type){const e=function(t){const{srj:e,bus:n,targetLayer:o,acceptedPlans:i,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,clearance:l,staticClearanceCache:d,blockingBusCounts:h,allowSameNetMerges:u=!1}=t,p=n.connections[0]?.sourceObstacle;if(!p||"plane"!==n.termination.type)return null;const m=n.connections[0].sourceLayer;if(o===m)return null;const g=[n.direction,...["left","right","up","down"].filter(t=>t!==n.direction)];for(const t of g){const m=t===n.direction?n:{...n,direction:t},g=$7(t)?p.width:p.height,f=G7(m)/2-g/2>=a/2+l-1e-9,y=f?[0]:[1,-1];for(const p of y)for(const g of ttt(m)){const y=[];let _=!0;for(const b of g){const g=V7(b.sourcePoint,t),x=ntt({preparedConnection:b,bus:m,targetLayer:o,track:g,exitAxis:H7(m),layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c,viaHandedness:p,interstitialEscape:!f,spreadLaneIndex:0,clearance:l,terminateAtVia:!0}),v=[...ott({preparedConnection:b,bus:m,viaDiameter:a,clearance:l}).map(t=>itt({plan:x,preparedConnection:b,planeLayer:o,viaPoint:t,layerNames:r,traceWidth:s,viaDiameter:a,viaHoleDiameter:c})),x].find((r,s)=>ltt({plan:r,otherPlans:[...i,...y],staticClearanceCache:d,blockingBusCounts:h,cacheKey:`plane:${n.busId}:${o}:${t}:${b.connectionIndex}:${p}:${s}`,srj:e,sharedBoundary:n.sharedBoundary,clearance:l,allowSameNetMerges:u}));if(!v){_=!1;break}y.push(v)}if(_)return y}}return null}(t);return e?[e]:[]}const g=H7(o),f=o.connections[0]?.sourceObstacle;if(!f)return[[]];const y=$7(o.direction)?f.width:f.height,_=o.connections[0].sourceLayer,b=i!==_,x=U7(o),v=G7(o)/2-y/2>=c/2+d-1e-9,S=b&&!x&&!v,I=b?v||x?[0]:[1,-1]:[0],C=[],P=new Set,M=(t,f,y,_)=>{if(C.length>=e)return;if(y>=t.length)return void(t=>{const e=t.map(t=>`${t.connectionIndex}:${t.targetLayer}:${t.exitPoint.x}:${t.exitPoint.y}:${t.segments.map(t=>`${t.start.x},${t.start.y},${t.end.x},${t.end.y},${t.layer}`).join(";")}`).join("|");P.has(e)||(P.add(e),C.push(t))})(_);const x=t[y],v=Z7(o,x),I=[K7({bus:o,connection:x,traceWidth:a}),Q7({bus:o,connection:x,targetUsesVia:b,interstitialEscape:S,compactBusTracks:h,traceWidth:a,viaDiameter:c,clearance:d})].filter((t,e,n)=>n.findIndex(e=>Math.abs(e-t)<1e-9)===e).flatMap(t=>function(t){const{bus:e,connection:n,preferredTrack:o,traceWidth:i,clearance:r}=t,s=($7(e.direction)?e.yCoordinates:e.xCoordinates).toSorted((t,e)=>t-e),a=Math.max(...e.componentObstacles.map(t=>$7(e.direction)?t.height/2:t.width/2)),c=$7(e.direction)?e.sharedBoundary.minY:e.sharedBoundary.minX,l=$7(e.direction)?e.sharedBoundary.maxY:e.sharedBoundary.maxX,d=l-c,h=l,u=[{value:o,kind:"preferred"},...J7(c,s[0]-a,i,r,"margin")];for(let t=0;t<s.length;t++)u.push({value:s[t],kind:"corridor"}),t<s.length-1&&u.push(...J7(s[t]+a,s[t+1]-a,i,r,"gap"));u.push(...J7(s.at(-1)+a,h,i,r,"margin"));const p=V7(n.sourcePoint,e.direction),m=(s[0]+s.at(-1))/2;return u.filter(t=>Math.abs(t.value-p)<=d+1e-9).filter((t,e,n)=>n.findIndex(e=>Math.abs(e.value-t.value)<1e-9)===e).sort((t,e)=>Math.abs(t.value-o)-Math.abs(e.value-o)-.001*(Math.abs(t.value-m)-Math.abs(e.value-m)))}({bus:o,connection:x,preferredTrack:t,traceWidth:a,clearance:d})).filter((t,e,n)=>n.findIndex(e=>Math.abs(e.value-t.value)<1e-9)===e);for(let h=0;h<I.length;h++){const b=I[h],P=ntt({preparedConnection:x,bus:o,targetLayer:i,track:b.value,exitAxis:g,layerNames:s,traceWidth:a,viaDiameter:c,viaHoleDiameter:l,viaHandedness:f,interstitialEscape:S,spreadLaneIndex:Math.min(v,o.connections.length-v-1),clearance:d,terminateAtVia:!1});if(ltt({plan:P,otherPlans:[...r,..._],staticClearanceCache:u,blockingBusCounts:p,cacheKey:`boundary:${o.busId}:${i}:${x.connectionIndex}:${f}:${h}`,srj:n,sharedBoundary:o.sharedBoundary,clearance:d,allowSameNetMerges:m})){if(M(t,f,y+1,[..._,P]),C.length>=e)return;if(1===e)return}}};for(const t of I)for(const n of ttt(o))if(M(n,t,0,[]),C.length>=e)return C;return C}function htt(t){return dtt(t,1)[0]??null}var utt=1e-9,ptt="1"===globalThis.process?.env?.FANOUT_FLOW_DEBUG;function mtt(t){const e=t.connection;return t.sourceObstacle.connectedTo.find(t=>t.startsWith("connectivity_net"))??e.netConnectionName??t.connection.name.replace(/::fanout:\d+$/,"")}function gtt(t,e){return t===e.connection.sourceObstacle||t.connectedTo.includes(e.connection.connection.name)||t.connectedTo.includes(e.netKey)}function ftt(t,e){const n=e.x-t.x,o=e.y-t.y,i=Math.abs(n),r=Math.abs(o);return i<utt||r<utt||Math.abs(i-r)<utt?[t,e]:i>r?[t,{x:t.x+Math.sign(n)*r,y:e.y},e]:[t,{x:e.x,y:t.y+Math.sign(o)*i},e]}function ytt(t){if(t.length<2)return t;const e=[t[0]];for(const n of t.slice(1)){const t=e.at(-1),o=Math.abs(n.x-t.x),i=Math.abs(n.y-t.y);o<utt||i<utt||Math.abs(o-i)<utt?e.push(n):e.push(...ftt(n,t).reverse().slice(1))}return _tt(e)}function _tt(t){if(t.length<3)return t;const e=[t[0]];for(let n=1;n<t.length-1;n++){const o=e.at(-1),i=t[n],r=t[n+1];Math.sign(i.x-o.x)===Math.sign(r.x-i.x)&&Math.sign(i.y-o.y)===Math.sign(r.y-i.y)||e.push(i)}return e.push(t.at(-1)),e}function btt(t,e){if(t.length<3)return t;const n=[t[0]];for(let o=1;o<t.length-1;o++){const i=t[o-1],r=t[o],s=t[o+1],a=M8(i,r),c=M8(r,s);if(a<utt||c<utt)continue;const l={x:(r.x-i.x)/a,y:(r.y-i.y)/a},d={x:(s.x-r.x)/c,y:(s.y-r.y)/c};if(Math.abs(l.x*d.x+l.y*d.y)>1e-6){n.push(r);continue}const h=Math.min(e,a/2,c/2);n.push({x:r.x-l.x*h,y:r.y-l.y*h}),n.push({x:r.x+d.x*h,y:r.y+d.y*h})}return n.push(t.at(-1)),_tt(n)}function xtt(t,e){const n=[];for(let o=1;o<t.length;o++)M8(t[o-1],t[o])<utt||n.push({start:t[o-1],end:t[o],width:e,layer:"top"});return n}var vtt=class{edges;levels;nextEdges;constructor(t){this.edges=Array.from({length:t},()=>[]),this.levels=new Int32Array(t),this.nextEdges=new Int32Array(t)}addEdge(t,e,n,o={}){const i={to:e,reverseIndex:this.edges[e].length,capacity:n,initialCapacity:n,...o},r={to:t,reverseIndex:this.edges[t].length,capacity:0,initialCapacity:0};this.edges[t].push(i),this.edges[e].push(r)}buildLevels(t,e){this.levels.fill(-1);const n=new Int32Array(this.edges.length);let o=0,i=0;for(n[i++]=t,this.levels[t]=0;o<i;){const t=n[o++];for(const e of this.edges[t])e.capacity<=0||this.levels[e.to]>=0||(this.levels[e.to]=this.levels[t]+1,n[i++]=e.to)}return this.levels[e]>=0}sendFlow(t,e){if(t===e)return 1;for(let n=this.nextEdges[t];n<this.edges[t].length;n++,this.nextEdges[t]=n){const o=this.edges[t][n];if(o.capacity<=0||this.levels[o.to]!==this.levels[t]+1)continue;const i=this.sendFlow(o.to,e);if(0!==i)return o.capacity-=i,this.edges[o.to][o.reverseIndex].capacity+=i,i}return 0}maximumFlow(t,e,n){let o=0;for(;o<n&&this.buildLevels(t,e);)for(this.nextEdges.fill(0);o<n;){const n=this.sendFlow(t,e);if(0===n)break;o+=n}return o}};function Stt(t){const{direction:e,availableDirections:n,items:o,grid:i,obstacles:r,traceWidth:s,clearance:a,occupiedNodes:c,acceptedSegments:l,connectorSelectionOffset:d=0}=t;if(0===o.length)return{routes:[],usedNodes:[],unmatchedItems:[]};const{boundary:h,step:u,columnCount:p,rowCount:m,nodeCount:g}=i,f=t=>i.points[t],y=s/2+a,_=s+a,b=new Uint8Array(g);for(let t=0;t<g;t++)!c[t]&&i.obstacleFreeNodes[t]&&(b[t]=1);const x=(t,e)=>{const n=xtt(t,s);return n.every(t=>r.every(n=>gtt(n,e)||A8(t,n)>=y-utt))&&n.every(t=>l.every(e=>T8(t.start,t.end,e.start,e.end)>=_-utt))},v=new Map;for(const t of o){const e=`${t.source.x.toFixed(6)}:${t.source.y.toFixed(6)}:${t.netKey}`,n=v.get(e)??[];n.push(t),v.set(e,n)}const S=Array.from({length:3721},(t,e)=>{const n=e%61-30,o=Math.floor(e/61)-30;return{x:n,y:o,distanceSquared:n*n+o*o}}).sort((t,e)=>t.distanceSquared-e.distanceSquared),I=[];for(const t of v.values()){const e=t[0],n=Math.hypot(e.connection.sourceObstacle.width/2,e.connection.sourceObstacle.height/2)+a+2*u,o=Math.round((e.source.x-h.minX)/u),i=Math.round((e.source.y-h.minY)/u),r=[],s=new Set;for(const t of S){const a=o+t.x,c=i+t.y;if(a<0||a>=p||c<0||c>=m)continue;const l=c*p+a;if(!b[l]||s.has(l))continue;if(M8(e.source,f(l))>n)continue;const d=ftt(e.source,f(l));if(x(d,e)&&(s.add(l),r.push({node:l,connectorPoints:d}),r.length>=12))break}if(0===r.length)return null;I.push({item:e,equivalentItems:t,candidates:r})}const C=[];for(const t of[...I].sort((t,e)=>t.candidates.length-e.candidates.length)){const e=0===t.candidates.length?0:d%t.candidates.length,n=[...t.candidates.slice(e),...t.candidates.slice(0,e)].find(e=>{const n=xtt(e.connectorPoints,s);return C.every(e=>e.netKey===t.item.netKey||n.every(t=>e.segments.every(e=>T8(t.start,t.end,e.start,e.end)>=_-utt)))});if(!n)return null;t.candidates=[n],C.push({netKey:t.item.netKey,segments:xtt(n.connectorPoints,s)})}const P=new Set(I.map(t=>t.candidates[0].node));for(const t of C)for(const e of t.segments){const t=Math.max(0,Math.floor((Math.min(e.start.x,e.end.x)-_-h.minX)/u)),n=Math.min(p-1,Math.ceil((Math.max(e.start.x,e.end.x)+_-h.minX)/u)),o=Math.max(0,Math.floor((Math.min(e.start.y,e.end.y)-_-h.minY)/u)),i=Math.min(m-1,Math.ceil((Math.max(e.start.y,e.end.y)+_-h.minY)/u));for(let r=o;r<=i;r++)for(let o=t;o<=n;o++){const t=r*p+o;if(!b[t]||P.has(t))continue;const n=f(t);T8(e.start,e.end,n,n)<_-utt&&(b[t]=0)}}const M=1+I.length,N=M+g,w=N+g,T=new vtt(w+1);for(let t=0;t<I.length;t++){const e=1+t;T.addEdge(0,e,1);for(const n of I[t].candidates)T.addEdge(e,M+n.node,1,{gridNode:n.node})}for(let t=0;t<g;t++){if(!b[t])continue;T.addEdge(M+t,N+t,1);const o=t%p,r=Math.floor(t/p);for(const e of i.neighbors[t])b[e]&&T.addEdge(N+t,M+e,1,{gridNode:e});("any"===e&&((!n||n.has("left"))&&0===o||(!n||n.has("right"))&&o===p-1||(!n||n.has("down"))&&0===r||(!n||n.has("up"))&&r===m-1)||"left"===e&&0===o||"right"===e&&o===p-1||"down"===e&&0===r||"up"===e&&r===m-1)&&T.addEdge(N+t,w,1,{isSink:!0})}const R=T.maximumFlow(0,w,I.length),E=t=>{const e=1+t;return T.edges[0].some(t=>t.to===e&&1===t.initialCapacity&&0===t.capacity)};if(R!==I.length&&ptt){const t=I.flatMap((t,e)=>E(e)?[]:[t.item.connection.connection.name]);console.error("single-layer flow group failed",{direction:e,achievedFlow:R,requiredFlow:I.length,unmatchedConnections:t})}const A=[],O=[],k=[];for(let t=0;t<I.length;t++){const e=I[t];if(!E(t)){k.push(...e.equivalentItems);continue}const n=1+t,o=T.edges[n].find(t=>1===t.initialCapacity&&0===t.capacity&&void 0!==t.gridNode);if(void 0===o?.gridNode)return null;const i=e.candidates.find(t=>t.node===o.gridNode);if(!i)return null;const r=[f(i.node)];let a=i.node;const c=[a];for(let t=0;t<=g;t++){const t=N+a,e=T.edges[t].find(t=>1===t.initialCapacity&&0===t.capacity&&(void 0!==t.gridNode||t.isSink));if(!e)return null;if(e.isSink)break;if(void 0===e.gridNode)return null;a=e.gridNode,c.push(a),r.push(f(a))}O.push(...c);const l=ytt(btt(_tt([...i.connectorPoints,...r.slice(1)]),u/2)),d=xtt(l,s);for(const t of e.equivalentItems)A.push({item:t,points:l,segments:d})}return{routes:A,usedNodes:O,unmatchedItems:k}}function Itt(t,e){const n=ftt(t,e),o=ftt(e,t).reverse();return n.length===o.length&&n.every((t,e)=>M8(t,o[e])<utt)?[n]:[n,o]}function Ctt(t,e){return Math.abs(t.x-e.minX)<utt?"left":Math.abs(t.x-e.maxX)<utt?"right":Math.abs(t.y-e.minY)<utt?"down":Math.abs(t.y-e.maxY)<utt?"up":null}function Ptt(t){const{items:e,grid:n,obstacles:o,traceWidth:i,clearance:r,availableBoundaryRegions:s}=t,a=s?new Set(s.map(t=>t.direction)):void 0,c=new Set(e.filter(t=>t.connection.sourceObstacle.width>2&&t.connection.sourceObstacle.height>2));let l=null;for(let t=0;t<4;t++){const t=e.filter(t=>!c.has(t));let s=null;for(let e=0;e<4;e++){const c=Stt({direction:"any",availableDirections:a,items:t,grid:n,obstacles:o,traceWidth:i,clearance:r,occupiedNodes:new Uint8Array(n.nodeCount),acceptedSegments:[],connectorSelectionOffset:e});if(c&&((!s||c.routes.length>s.routes.length)&&(s=c),c.routes.length===t.length))break}if(!s)return null;if(s.routes.length===t.length){l=s;break}const d=new Map;for(const e of t)d.set(e.netKey,(d.get(e.netKey)??0)+1);let h=!1;for(const t of s.unmatchedItems)(d.get(t.netKey)??0)<2||(c.add(t),h=!0);if(!h)return null}if(!l)return null;const d=[...l.routes],h=i/2+r,u=i+r;for(const t of c){const e=d.filter(e=>e.item.netKey===t.netKey).flatMap(t=>t.points.map((e,n)=>({route:t,point:e,pointIndex:n}))).sort((e,n)=>Number(n.route.item.bus.componentId===t.bus.componentId)-Number(e.route.item.bus.componentId===t.bus.componentId)||M8(t.source,e.point)-M8(t.source,n.point));let n=null;for(const r of e){for(const e of Itt(t.source,r.point)){const s=xtt(e,i),a=s.every(e=>o.every(n=>gtt(n,t)||A8(e,n)>=h-utt)),c=s.every(e=>d.every(n=>n.item.netKey===t.netKey||n.segments.every(t=>T8(e.start,e.end,t.start,t.end)>=u-utt)));if(!a||!c)continue;const l=ytt(_tt([...e,...r.route.points.slice(r.pointIndex+1)]));n={item:t,points:l,segments:xtt(l,i)};break}if(n)break}if(!n)return null;d.push(n)}const p=d.map(t=>function(t,e){const{item:n,points:o,segments:i}=t,r=o.map((t,o)=>({route_type:"wire",x:t.x,y:t.y,width:e,layer:"top",...0===o&&n.connection.sourcePoint.pcb_port_id?{start_pcb_port_id:n.connection.sourcePoint.pcb_port_id}:{}})),s=x8({connectionName:n.connection.connection.name,sourcePointIndex:n.connection.sourcePointIndex});return{busId:n.bus.busId,connectionName:n.connection.connection.name,connectionIndex:n.connection.connectionIndex,sourcePointIndex:n.connection.sourcePointIndex,sourcePoint:n.connection.sourcePoint,sourceObstacle:n.connection.sourceObstacle,sourceLayer:n.connection.sourceLayer,targetPoint:n.connection.targetPoint,targetLayer:"top",termination:n.bus.termination,direction:n.bus.direction,exitPoint:o.at(-1),trace:{type:"pcb_trace",pcb_trace_id:s.traceId,connection_name:n.connection.connection.name,connectsTo:[...n.connection.sourcePoint.pointId?[n.connection.sourcePoint.pointId]:[],...n.connection.sourcePoint.pcb_port_id?[n.connection.sourcePoint.pcb_port_id]:[],s.boundaryExitPointId],route:r},segments:i,length:i.reduce((t,e)=>t+M8(e.start,e.end),0)}}(t,i));if(!function(t){const{plans:e,items:n,obstacles:o,traceWidth:i,clearance:r}=t,s=new Map(n.map(t=>[t.connection.connection.name,t.netKey])),a=new Map,c=new Map;for(const t of e){const e=s.get(t.connectionName),n=a.get(e)??[],o=c.get(e)??new Set;for(const e of t.segments){const t=[e.start,e.end].map(t=>`${t.x.toFixed(6)}:${t.y.toFixed(6)}`).sort().join(":");o.has(t)||(o.add(t),n.push(e))}a.set(e,n),c.set(e,o)}const l=i/2+r;for(const[t,e]of a)for(const n of e)for(const e of o)if(!(e.connectedTo.includes(t)||A8(n,e)>=l-utt))return ptt&&console.error("single-layer route violates obstacle clearance",{netKey:t,segment:n,obstacleId:e.obstacleId,distance:A8(n,e),requiredObstacleDistance:l}),!1;const d=i+r,h=[...a];for(let t=0;t<h.length;t++)for(let e=t+1;e<h.length;e++)for(const n of h[t][1])for(const o of h[e][1])if(T8(n.start,n.end,o.start,o.end)<d-utt)return ptt&&console.error("single-layer routes violate copper clearance",{firstNetKey:h[t][0],secondNetKey:h[e][0],first:n,second:o,distance:T8(n.start,n.end,o.start,o.end),requiredRouteDistance:d}),!1;return!0}({plans:p,items:e,obstacles:o,traceWidth:i,clearance:r}))return ptt&&console.error("single-layer adaptive exits failed exact clearance"),null;for(const t of p){const o=Ctt(t.exitPoint,n.boundary);if(!o||a&&!a.has(o))return null;const i=e.find(e=>e.connection.connection.name===t.connectionName);i.bus.direction=o;const r=s?.filter(t=>t.direction===o),c="up"===o||"down"===o?t.exitPoint.x:t.exitPoint.y;i.bus.preferredExit=r?.toSorted((t,e)=>Math.abs(c-D7(t,n.boundary))-Math.abs(c-D7(e,n.boundary)))[0]?.preferredExit??("up"===o?"top":"down"===o?"bottom":o),t.direction=o}const m=new Map(p.map(t=>[t.connectionName,t]));return e.map(t=>m.get(t.connection.connection.name))}function Mtt(t){const{srj:e,buses:n,traceWidth:o,clearance:i,availableBoundaryRegions:r}=t;if(n.some(t=>1!==t.connections.length))return null;const s=n.flatMap(t=>t.connections.map(e=>({bus:t,connection:e,source:{x:e.sourcePoint.x,y:e.sourcePoint.y},netKey:mtt(e)}))),a=e.obstacles.filter(t=>t.layers.includes("top")),c=n[0]?.sharedBoundary;if(!c)return[];const l=function(t){const{boundary:e,obstacles:n,traceWidth:o,clearance:i}=t,r=o+i,s=Math.round((e.maxX-e.minX)/r)+1,a=Math.round((e.maxY-e.minY)/r)+1,c=s*a,l=Array.from({length:c},(t,n)=>({x:e.minX+n%s*r,y:e.minY+Math.floor(n/s)*r})),d=o/2+i,h=new Map;for(let t=0;t<n.length;t++){const e=n[t],o=Math.floor((e.center.x-e.width/2-d)/1),i=Math.floor((e.center.x+e.width/2+d)/1),r=Math.floor((e.center.y-e.height/2-d)/1),s=Math.floor((e.center.y+e.height/2+d)/1);for(let e=o;e<=i;e++)for(let n=r;n<=s;n++){const o=`${e}:${n}`,i=h.get(o)??[];i.push(t),h.set(o,i)}}const u=(t,e=t)=>{const o=Math.floor(Math.min(t.x,e.x)/1),i=Math.floor(Math.max(t.x,e.x)/1),r=Math.floor(Math.min(t.y,e.y)/1),s=Math.floor(Math.max(t.y,e.y)/1),a=new Set;for(let t=o;t<=i;t++)for(let e=r;e<=s;e++)for(const n of h.get(`${t}:${e}`)??[])a.add(n);return[...a].map(t=>n[t])},p=new Uint8Array(c);for(let t=0;t<c;t++){const e=l[t];u(e).every(t=>E8(e,t)>=d-utt)&&(p[t]=1)}const m=Array.from({length:c},()=>[]);for(let t=0;t<c;t++){if(!p[t])continue;const e=t%s,n=Math.floor(t/s);for(const[i,r]of[[1,0],[0,1]]){const c=e+i,h=n+r;if(c>=s||h>=a)continue;const g=h*s+c;if(!p[g])continue;const f={start:l[t],end:l[g],width:o,layer:"top"};u(f.start,f.end).some(t=>A8(f,t)<d-utt)||(m[t].push(g),m[g].push(t))}}return{boundary:e,step:r,columnCount:s,rowCount:a,nodeCount:c,points:l,obstacleFreeNodes:p,neighbors:m}}({boundary:c,obstacles:a,traceWidth:o,clearance:i});ptt&&console.error("single-layer adaptive-exit grid ready",{nodeCount:l.nodeCount});const d=Ptt({items:s,grid:l,obstacles:a,traceWidth:o,clearance:i,availableBoundaryRegions:r});return d||null}function Ntt(t){return"left"===t||"right"===t}function wtt(t){return"right"===t||"up"===t?1:-1}function Ttt(t,e){return Ntt(e)?t.x:t.y}function Rtt(t,e){return Ntt(e)?t.y:t.x}function Ett(t,e,n){return Ntt(n)?{x:t,y:e}:{x:e,y:t}}function Att(t){switch(t.direction){case"right":return t.sharedBoundary.maxX;case"left":return t.sharedBoundary.minX;case"up":return t.sharedBoundary.maxY;case"down":return t.sharedBoundary.minY}}function Ott(t){if(t.length<3)return t;const e=[t[0]];for(let n=1;n<t.length-1;n++){const o=e.at(-1),i=t[n],r=t[n+1],s={x:Math.sign(i.x-o.x),y:Math.sign(i.y-o.y)},a={x:Math.sign(r.x-i.x),y:Math.sign(r.y-i.y)};s.x===a.x&&s.y===a.y||e.push(i)}return e.push(t.at(-1)),e}function ktt(t,e){const n=[];for(let o=1;o<t.length;o++)M8(t[o-1],t[o])<1e-9||n.push({start:t[o-1],end:t[o],width:e,layer:"top"});return n}function Ltt(t){const{item:e,srj:n,acceptedSegments:o,traceWidth:i,clearance:r}=t,s=e.cornerChannelPrefixes;if(!s)return null;const a=e.direction,c=wtt(a),l=Att(e.bus),d=i+r,h=i/2+r,u=Ntt(a)?e.bus.sharedBoundary.minY:e.bus.sharedBoundary.minX,p=Ntt(a)?e.bus.sharedBoundary.maxY:e.bus.sharedBoundary.maxX,m=u+i/2,g=p-i/2,f=Rtt(e.connection.exitTargetPoint??e.connection.targetPoint,a),y=d/2,_=new Set([Math.max(m,Math.min(g,f))]);for(let t=Math.ceil(m/y)*y;t<=g+1e-9;t+=y)_.add(Number(t.toFixed(9)));const b=[..._].toSorted((t,e)=>Math.abs(t-f)-Math.abs(e-f));for(const t of s){const s=t.at(-1),u=Rtt(s,a);for(const p of b){const m=Math.abs(p-u),g=Ett(Ttt(s,a)+c*d,u,a),f=Ett(Ttt(g,a)+c*m,p,a);if(c*(l-Ttt(f,a))<-1e-9)continue;const y=Ett(l,p,a),_=[...t,g,...m>1e-9?[f]:[]];M8(_.at(-1),y)>1e-9&&_.push(y);const b=Ott(_),x=ktt(b,i);if(!x.every(t=>n.obstacles.every(n=>n===e.connection.sourceObstacle||!n.layers.includes("top")||A8(t,n)>=h-1e-9)))continue;if(x.every(t=>o.every(e=>T8(t.start,t.end,e.start,e.end)>=i+r-1e-9)))return{item:e,points:b,track:p}}}return null}function Dtt(t){const{route:e,direction:n,exitAxis:o,signedShift:i,maximumShift:r,obstacles:s,requiredObstacleDistance:a}=t;if(r<=1e-9||Math.abs(i)<=1e-9)return 0;const c=Math.sign(i),l=t=>{if(t<=1e-9)return!0;const i={start:Ett(o-wtt(n)*t,e.track,n),end:Ett(o,e.track+c*t,n),width:0,layer:"top"};return s.every(t=>t===e.item.connection.sourceObstacle||!t.layers.includes("top")||A8(i,t)>=a-1e-9)};if(l(r))return r;let d=0,h=r;for(let t=0;t<32;t++){const t=(d+h)/2;l(t)?d=t:h=t}return d}function ztt(t){const{requestedTracks:e,currentTracks:n,candidateTracks:o,maximumShifts:i}=t,r=e.length+1,s=o.length+1,a=Array.from({length:r},()=>new Float64Array(s).fill(Number.POSITIVE_INFINITY)),c=Array.from({length:r},()=>new Uint8Array(s));a[0].fill(0);for(let t=1;t<r;t++)for(let r=1;r<s;r++){const s=a[t][r-1],l=Math.abs(e[t-1]-o[r-1]),d=Math.abs(n[t-1]-o[r-1])>i[t-1]+1e-9?Number.POSITIVE_INFINITY:a[t-1][r-1]+l;d<s?(a[t][r]=d,c[t][r]=1):a[t][r]=s}if(!Number.isFinite(a.at(-1).at(-1)))return null;const l=[];let d=e.length,h=o.length;for(;d>0&&h>0;)c[d][h]&&(l.push(o[h-1]),d--),h--;return d>0?null:l.reverse()}function Ftt(t){const{direction:e,activeRoutes:n,obstacles:o,boundaryMinimum:i,boundaryMaximum:r,traceWidth:s,clearance:a,requestedTracks:c,maximumShifts:l}=t,d=s+a,h=s/2+a;let u=null,p=Number.POSITIVE_INFINITY;for(const t of Array.from({length:Math.round(d/s)},(t,e)=>e*s)){const a=[];for(let n=Math.ceil((i-t)/d)*d+t;n<=r+1e-9;n+=d){const t=Math.round(n/s)*s;o.every(n=>{const o=Rtt(n.center,e),i=Ntt(e)?n.height:n.width;return Math.abs(t-o)>=i/2+h-1e-9})&&a.push(t)}const m=ztt({requestedTracks:c,currentTracks:n.map(t=>t.track),candidateTracks:a,maximumShifts:l});if(!m)continue;const g=m.reduce((t,e,n)=>t+Math.abs(e-c[n]),0);g<p&&(p=g,u=m)}return u}function Btt(t,e){switch(e){case"up":return"top-left"===t?"minimum":"top-right"===t?"maximum":null;case"down":return"bottom-left"===t?"minimum":"bottom-right"===t?"maximum":null;case"left":return"bottom-left"===t?"minimum":"top-left"===t?"maximum":null;case"right":return"bottom-right"===t?"minimum":"top-right"===t?"maximum":null}}function jtt(t){const{items:e,direction:n,boundaryMinimum:o,boundaryMaximum:i,traceWidth:r,clearance:s,borderDistribution:a,currentTrackByConnectionName:c}=t,l=t=>c.get(t.connection.connection.name)??Rtt(t.source,n),d=[...e].toSorted((t,e)=>l(t)-l(e)||t.connection.connection.name.localeCompare(e.connection.connection.name)),h=r+s,u=o+r/2,p=i-r/2;if(p-u<h*Math.max(d.length-1,0)-1e-9)return null;const m=d.map(l);let g=[...m],f=h;const y=new Set;if("even"===a&&d.length>1){const t=m[0],e=m.at(-1),n=Math.max(h,(e-t)/(d.length-1)),o=t=>{const e=[...m],n=Math.floor(d.length/2),o=d.length%2==0?n-1:n;if(o!==n){const i=e[n]-e[o];if(i<t){const r=(t-i)/2;e[o]=e[o]-r,e[n]=e[n]+r}}for(let n=o-1;n>=0;n--)e[n]=Math.min(e[n],e[n+1]-t);for(let o=n+1;o<e.length;o++)e[o]=Math.max(e[o],e[o-1]+t);return e},i=t=>t[0]>=u-1e-9&&t.at(-1)<=p+1e-9;if(g=o(n),i(g))f=n;else{let t=h,e=n;if(g=o(t),!i(g))return null;for(let n=0;n<32;n++){const n=(t+e)/2,r=o(n);i(r)?(t=n,g=r):e=n}f=t}for(const t of d)y.add(t.connection.connection.name)}const _=[],b=[];for(let t=0;t<d.length;t++){const e=d[t],o=e.bus.preferredExit;if(!o?.includes("-"))continue;const i=Btt(o,n);if(!i)return null;y.add(e.connection.connection.name),"minimum"===i?_.push(t):b.push(t)}if(_.some((t,e)=>t!==e)||b.some((t,e)=>t!==d.length-b.length+e))return null;const x=2*h;if(_.length>0){g[0]=u+x;for(let t=1;t<_.length;t++){const e=Math.max(f,m[t]-m[t-1]);g[t]=g[t-1]+e}}if(b.length>0){const t=d.length-1;g[t]=p-x;for(let e=t-1;e>=d.length-b.length;e--){const t=Math.max(f,m[e+1]-m[e]);g[e]=g[e+1]-t}}return{byConnectionName:new Map(d.map((t,e)=>[t.connection.connection.name,g[e]])),enforcedConnectionNames:y}}function $tt(t){const{item:e,points:n,segments:o}=t,i=n.map((t,n)=>({route_type:"wire",x:t.x,y:t.y,width:o[0]?.width??.1,layer:"top",...0===n&&e.connection.sourcePoint.pcb_port_id?{start_pcb_port_id:e.connection.sourcePoint.pcb_port_id}:{}})),r=x8({connectionName:e.connection.connection.name,sourcePointIndex:e.connection.sourcePointIndex});return{busId:e.bus.busId,connectionName:e.connection.connection.name,connectionIndex:e.connection.connectionIndex,sourcePointIndex:e.connection.sourcePointIndex,sourcePoint:e.connection.sourcePoint,sourceObstacle:e.connection.sourceObstacle,sourceLayer:e.connection.sourceLayer,targetPoint:e.connection.targetPoint,targetLayer:"top",termination:e.bus.termination,direction:e.direction,exitPoint:n.at(-1),trace:{type:"pcb_trace",pcb_trace_id:r.traceId,connection_name:e.connection.connection.name,connectsTo:[...e.connection.sourcePoint.pointId?[e.connection.sourcePoint.pointId]:[],...e.connection.sourcePoint.pcb_port_id?[e.connection.sourcePoint.pcb_port_id]:[],r.boundaryExitPointId],route:i},segments:o,length:o.reduce((t,e)=>t+M8(e.start,e.end),0)}}function Ytt(t){const{srj:e,buses:n,traceWidth:o,clearance:i,borderDistribution:r}=t,s=o/2+i,a=new Map,c=new Map,l=n.flatMap(t=>t.connections.map(n=>{const r={x:n.sourcePoint.x,y:n.sourcePoint.y},s=function(t){const{srj:e,bus:n,connection:o,traceWidth:i,clearance:r}=t,s=n.direction,a=wtt(s),c={x:o.sourcePoint.x,y:o.sourcePoint.y},l=Ttt(c,s),d=Rtt(c,s),h=i/2+r,u=(()=>{switch(s){case"right":return n.componentBounds.maxX+h;case"left":return n.componentBounds.minX-h;case"up":return n.componentBounds.maxY+h;case"down":return n.componentBounds.minY-h}})(),p=t=>Math.min(...e.obstacles.filter(t=>t!==o.sourceObstacle&&t.layers.includes("top")).map(e=>A8(t,e))),m={start:c,end:Ett(u,d,s),width:i,layer:"top"};if(p(m)>=h-1e-9)return null;const g=Ntt(s)?{minimum:n.componentBounds.minY,maximum:n.componentBounds.maxY}:{minimum:n.componentBounds.minX,maximum:n.componentBounds.maxX},f=a*(u-l),y=Rtt(o.exitTargetPoint??o.targetPoint,s),_=i+r,b=Att(n),x=[-1,1].map(t=>{const e=t*((t<0?g.minimum-h:g.maximum+h)-d),o=Math.max(f,e),r=Ett(l+a*o,d+t*o,s);if(a*(b-Ttt(r,s))<_-1e-9)return null;const u=[c,r];if(!u.every(t=>t.x>=n.sharedBoundary.minX-1e-9&&t.x<=n.sharedBoundary.maxX+1e-9&&t.y>=n.sharedBoundary.minY-1e-9&&t.y<=n.sharedBoundary.maxY+1e-9))return null;const m=Math.min(...ktt(u,i).map(p));return m<h-1e-9?null:{points:u,obstacleDistance:m,targetDistance:Math.abs(Rtt(r,s)-y)}}).filter(t=>null!==t).toSorted((t,e)=>e.obstacleDistance-t.obstacleDistance||t.targetDistance-e.targetDistance);return x.length>0?x.map(t=>t.points):null}({srj:e,bus:t,connection:n,traceWidth:o,clearance:i});return{bus:t,connection:n,direction:t.direction,source:r,...s?{cornerChannelPrefixes:s}:{}}}));for(const t of["left","right","up","down"]){const n=wtt(t),d=l.filter(e=>e.direction===t&&!e.cornerChannelPrefixes);if(0===d.length)continue;const h=Ntt(t)?d[0].bus.sharedBoundary.minY:d[0].bus.sharedBoundary.minX,u=Ntt(t)?d[0].bus.sharedBoundary.maxY:d[0].bus.sharedBoundary.maxX,p=Att(d[0].bus),m=new Map,g=new Map,f=new Map;for(const e of d){const n=Ttt(e.source,t),o=n.toFixed(6);f.set(o,n);const i=m.get(o)??[];i.push(e),m.set(o,i)}for(const[n,o]of m){const i=f.get(n),r=new Set(o.map(t=>t.bus.componentId));g.set(n,e.obstacles.filter(e=>e.layers.includes("top")&&!!e.componentId&&r.has(e.componentId)&&Math.abs(Ttt(e.center,t)-i)<1e-6))}const y=[...f.values()].toSorted((t,e)=>n*(t-e)),_=new Map;for(let e=0;e<y.length;e++){const r=y[e],a=r.toFixed(6);for(const e of m.get(a)??[]){const o=Ntt(t)?e.connection.sourceObstacle.width:e.connection.sourceObstacle.height,i=Math.max(e.connection.sourceObstacle.width,e.connection.sourceObstacle.height)<1.5?o/2+s:0,a=Ett(r+n*i,Rtt(e.source,t),t);_.set(e.connection.connection.name,{item:e,points:M8(e.source,a)>1e-9?[e.source,a]:[e.source],track:Rtt(e.source,t)})}const c=y[e+1]??p;if(0===_.size||n*(c-r)<=1e-9)continue;const l=[..._.values()].toSorted((t,e)=>t.track-e.track||t.item.connection.connection.name.localeCompare(e.item.connection.connection.name)),d=y.slice(e+1,e+3).flatMap(t=>g.get(t.toFixed(6))??[]),f=l.map(e=>Math.abs(c-Ttt(e.points.at(-1),t))),b=Ftt({direction:t,activeRoutes:l,obstacles:d,boundaryMinimum:h,boundaryMaximum:u,traceWidth:o,clearance:i,requestedTracks:l.map(t=>t.track),maximumShifts:f});if(!b)return null;for(let e=0;e<l.length;e++){const o=l[e],i=b[e],r=Math.abs(i-o.track),s=Ett(Ttt(o.points.at(-1),t)+n*r,i,t);M8(o.points.at(-1),s)>1e-9&&o.points.push(s);const a=Ett(c,i,t);M8(o.points.at(-1),a)>1e-9&&o.points.push(a),o.track=i}}const b=jtt({items:d,direction:t,boundaryMinimum:h,boundaryMaximum:u,traceWidth:o,clearance:i,borderDistribution:r,currentTrackByConnectionName:new Map([..._.values()].map(t=>[t.item.connection.connection.name,t.track]))});if(!b)return null;const x=[..._.values()].toSorted((t,e)=>t.track-e.track||t.item.connection.connection.name.localeCompare(e.item.connection.connection.name)),v=new Map,S=o+i;let I=S;for(const t of x){const e=t.item.connection.connection.name;if(!b.enforcedConnectionNames.has(e))continue;b.byConnectionName.get(e)-t.track>=-1e-9||(v.set(e,I),I+=2*S)}let C=S;for(let t=x.length-1;t>=0;t--){const e=x[t],n=e.item.connection.connection.name;if(!b.enforcedConnectionNames.has(n))continue;b.byConnectionName.get(n)-e.track<=1e-9||(v.set(n,C),C+=2*S)}for(const o of x){const i=o.item.connection.connection.name,r=b.byConnectionName.get(i)??o.track,a=v.get(i)??0,c=o.points.at(-2),l=c?n*(p-Ttt(c,t)):0,d=r-o.track,h=Math.min(Math.abs(d),Math.max(0,l-a)),u=Dtt({route:o,direction:t,exitAxis:p,signedShift:d,maximumShift:h,obstacles:e.obstacles,requiredObstacleDistance:s}),m=Math.sign(d)*u;b.byConnectionName.set(i,o.track+m)}for(const t of b.enforcedConnectionNames)c.set(t,b.byConnectionName.get(t));for(const e of x){const o=e.item.connection.connection.name,i=b.byConnectionName.get(o)??e.track,r=Math.abs(i-e.track),s=v.get(o)??0,a=p-n*(r>1e-9?s+r:0),c=e.points.at(-1);if(Math.abs(Ttt(c,t)-p)>1e-6)return null;const l=e.points.at(-2);if(l&&(Math.abs(Rtt(l,t)-e.track)>1e-6||n*(a-Ttt(l,t))<-1e-6))return null;const d=Ett(a,e.track,t);l&&M8(l,d)<1e-9?e.points.pop():e.points[e.points.length-1]=d}for(const e of x){const o=e.item.connection.connection.name,i=b.byConnectionName.get(o)??e.track,r=Math.abs(i-e.track),s=v.get(o)??0;r>1e-9&&s>1e-9&&e.points.push(Ett(Ttt(e.points.at(-1),t)+n*s,e.track,t)),r>1e-9&&(e.points.push(Ett(Ttt(e.points.at(-1),t)+n*r,i,t)),e.track=i);const c=Ett(p,e.track,t);if(M8(e.points.at(-1),c)>1e-9){if(n*(p-Ttt(e.points.at(-1),t))<-1e-6)return null;e.points.push(c)}a.set(o,e)}}const d=[...a.values()].flatMap(t=>ktt(Ott(t.points),o));for(const t of l){if(!t.cornerChannelPrefixes)continue;const n=Ltt({item:t,srj:e,acceptedSegments:d,traceWidth:o,clearance:i});if(!n)return null;a.set(t.connection.connection.name,n),d.push(...ktt(Ott(n.points),o))}if(a.size!==l.length)return null;const h=(o+i)/2+1e-6;for(const[t,e]of c){const n=a.get(t);if(!n||Math.abs(n.track-e)>h)return null}const u=l.map(t=>{const e=Ott(a.get(t.connection.connection.name).points);return{item:t,points:e,segments:ktt(e,o)}});return function(t){const{paths:e,obstacles:n,traceWidth:o,clearance:i}=t,r=o/2+i,s=o+i;for(const t of e){if(Math.abs(Ttt(t.points.at(-1),t.item.direction)-Att(t.item.bus))>1e-6)return!1;for(const e of t.segments)for(const o of n)if(o!==t.item.connection.sourceObstacle&&o.layers.includes("top")&&A8(e,o)<r-1e-9)return!1}for(let t=0;t<e.length;t++)for(let n=t+1;n<e.length;n++)for(const o of e[t].segments)for(const t of e[n].segments)if(T8(o.start,o.end,t.start,t.end)<s-1e-9)return!1;return!0}({paths:u,obstacles:e.obstacles,traceWidth:o,clearance:i})?u.map($tt):null}var Xtt=1e-6;function Vtt(t,e){return M8(t,e)<=Xtt}function Wtt(t){return"layer"in t?[t.layer]:t.layers}function Htt(t){return[...t.segments,...t.planeEndpointSegments??[]]}function Gtt(t){return[t.via,t.planeEndpointVia].filter(t=>Boolean(t))}function Utt(t,e){return Vtt(t,e)&&Wtt(t).join("\0")===Wtt(e).join("\0")&&t.pointId===e.pointId&&t.pcb_port_id===e.pcb_port_id}function Ztt(t,e){const n=t.x>=e.minX-Xtt&&t.x<=e.maxX+Xtt&&t.y>=e.minY-Xtt&&t.y<=e.maxY+Xtt,o=Math.abs(t.x-e.minX)<=Xtt||Math.abs(t.x-e.maxX)<=Xtt||Math.abs(t.y-e.minY)<=Xtt||Math.abs(t.y-e.maxY)<=Xtt;return n&&o}function qtt(t,e){return t.x>=e.minX-Xtt&&t.x<=e.maxX+Xtt&&t.y>=e.minY-Xtt&&t.y<=e.maxY+Xtt}function Jtt(t,e,n,o,i){t.push({code:e,message:n,...o?{connectionName:o.connectionName,busId:o.busId}:{},...i?{otherConnectionName:i}:{}})}function Ktt(t){const{trace:e,plan:n,issues:o}=t,i=[];let r,s;for(const t of e.route)"via"!==t.route_type?"wire"===t.route_type?s?(Vtt(t,s)&&t.layer===s.to_layer||Jtt(o,"disconnected-trace",`Trace ${e.pcb_trace_id} does not continue from its via on ${s.to_layer}`,n),r=t,s=void 0):(r&&(r.layer!==t.layer?Jtt(o,"disconnected-trace",`Trace ${e.pcb_trace_id} changes from ${r.layer} to ${t.layer} without a via`,n):Vtt(r,t)||i.push({start:{x:r.x,y:r.y},end:{x:t.x,y:t.y},width:t.width,layer:t.layer})),r=t):Jtt(o,"unsupported-route-point",`Trace ${e.pcb_trace_id} contains unsupported ${t.route_type} geometry`,n):(r&&Vtt(r,t)&&r.layer===t.from_layer||Jtt(o,"disconnected-trace",`Trace ${e.pcb_trace_id} reaches a via without a matching ${t.from_layer} wire endpoint`,n),s=t);return s&&Jtt(o,"disconnected-trace",`Trace ${e.pcb_trace_id} ends at a via without a wire on ${s.to_layer}`,n),i}function Qtt(t){const{plan:e,preparedBus:n,inputSrj:o,outputSrj:i,sharedBoundary:r,issues:s}=t,a=o.connections[e.connectionIndex];if(!a||a.name!==e.connectionName)return void Jtt(s,"connection-mismatch",`Plan index ${e.connectionIndex} does not identify connection ${e.connectionName}`,e);const c=n?.connections.find(t=>t.connectionIndex===e.connectionIndex);if(c&&c.sourcePointIndex===e.sourcePointIndex&&Utt(c.sourcePoint,e.sourcePoint)&&c.sourceObstacle.obstacleId===e.sourceObstacle.obstacleId||Jtt(s,"source-mismatch",`Plan ${e.connectionName} does not start at its prepared component endpoint`,e),n?.termination.type!==e.termination.type&&Jtt(s,"termination-mismatch",`Plan ${e.connectionName} does not use its bus termination`,e),0===e.segments.length||e.length<=Xtt)Jtt(s,"not-broken-out",`Plan ${e.connectionName} has no non-zero escape geometry`,e);else{const t={minX:Math.min(o.bounds.minX,r.minX),maxX:Math.max(o.bounds.maxX,r.maxX),minY:Math.min(o.bounds.minY,r.minY),maxY:Math.max(o.bounds.maxY,r.maxY)};e.segments.some(e=>!qtt(e.start,t)||!qtt(e.end,t))&&Jtt(s,"outside-routing-bounds",`Plan ${e.connectionName} leaves the routable SRJ/shared-boundary area`,e),Vtt(e.segments[0].start,e.sourcePoint)||Jtt(s,"disconnected-trace",`Plan ${e.connectionName} does not start at its source pad`,e),Vtt(e.segments.at(-1).end,e.exitPoint)||Jtt(s,"disconnected-trace",`Plan ${e.connectionName} does not end at its declared exit`,e);for(let t=1;t<e.segments.length;t++){const n=e.segments[t-1],o=e.segments[t];Vtt(n.end,o.start)||Jtt(s,"disconnected-trace",`Plan ${e.connectionName} has a gap between route segments`,e),n.layer===o.layer||e.via&&Vtt(n.end,e.via.center)&&e.via.spanLayers.includes(n.layer)&&e.via.spanLayers.includes(o.layer)||Jtt(s,"disconnected-trace",`Plan ${e.connectionName} changes layers without a connecting via`,e)}}const l=Ktt({trace:e.trace,plan:e,issues:s});if((l.length!==e.segments.length||l.some((t,n)=>{const o=e.segments[n];return!o||t.layer!==o.layer||Math.abs(t.width-o.width)>Xtt||!Vtt(t.start,o.start)||!Vtt(t.end,o.end)}))&&Jtt(s,"trace-plan-mismatch",`Trace ${e.trace.pcb_trace_id} does not encode its declared route segments`,e),e.planeEndpointTrace||e.planeEndpointSegments||e.planeEndpointVia)if(e.planeEndpointTrace&&e.planeEndpointSegments&&e.planeEndpointVia){const t=Ktt({trace:e.planeEndpointTrace,plan:e,issues:s});(t.length!==e.planeEndpointSegments.length||t.some((t,n)=>{const o=e.planeEndpointSegments?.[n];return!o||t.layer!==o.layer||Math.abs(t.width-o.width)>Xtt||!Vtt(t.start,o.start)||!Vtt(t.end,o.end)})||M8(e.planeEndpointVia.center,e.targetPoint)<=Xtt)&&Jtt(s,"trace-plan-mismatch",`Trace ${e.planeEndpointTrace.pcb_trace_id} does not encode a valid offset plane-to-endpoint dogbone`,e)}else Jtt(s,"trace-plan-mismatch",`Plane endpoint geometry for ${e.connectionName} is incomplete`,e);const d=e.trace.route.find(t=>"x"in t&&"y"in t),h=[...e.trace.route].reverse().find(t=>"x"in t&&"y"in t);d&&h&&Vtt(d,e.sourcePoint)&&Vtt(h,e.exitPoint)||Jtt(s,"disconnected-trace",`Trace ${e.trace.pcb_trace_id} does not span its source and exit`,e);const u=i.connections.find(t=>t.name===e.connectionName);if("boundary"===e.termination.type)if(u){const t=u.pointsToConnect[e.sourcePointIndex];t&&Vtt(t,e.exitPoint)&&"layer"in t&&t.layer===e.targetLayer||Jtt(s,"output-exit-mismatch",`Output connection ${e.connectionName} is not attached to its fanout exit`,e);for(let t=0;t<a.pointsToConnect.length;t++){if(t===e.sourcePointIndex)continue;const n=a.pointsToConnect[t],o=u.pointsToConnect[t];n&&o&&Utt(n,o)||Jtt(s,"downstream-endpoint-lost",`Output connection ${e.connectionName} did not retain downstream endpoint ${t}`,e)}}else Jtt(s,"output-connection-missing",`Boundary connection ${e.connectionName} was removed from the output`,e);else u&&Jtt(s,"plane-connection-retained",`Plane-terminated connection ${e.connectionName} remains in the output`,e)}function tet(t,e){const n=Htt(t),o=Htt(e),i=Gtt(t),r=Gtt(e);for(const t of n){for(const e of o)if(t.layer===e.layer&&T8(t.start,t.end,e.start,e.end)<=(t.width+e.width)/2+Xtt)return!0;for(const e of r)if(e.spanLayers.includes(t.layer)&&N8(e.center,t.start,t.end)<=e.diameter/2+t.width/2+Xtt)return!0}for(const t of i){for(const e of o)if(t.spanLayers.includes(e.layer)&&N8(t.center,e.start,e.end)<=t.diameter/2+e.width/2+Xtt)return!0;for(const e of r)if(t.spanLayers.some(t=>e.spanLayers.includes(t))&&M8(t.center,e.center)<=(t.diameter+e.diameter)/2+Xtt)return!0}return!1}function eet(t){const{inputSrj:e,outputSrj:n,plans:o,preparedBuses:i,sharedBoundary:r,clearance:s}=t,a=[],c=new Map,l=new Map(i.map(t=>[t.busId,t]));for(const t of o){const e=c.get(t.connectionName)??[];e.push(t),c.set(t.connectionName,e)}for(const t of e.connections){const e=c.get(t.name)??[];0===e.length?Jtt(a,"missing-plan",`Connection ${t.name} has no fanout plan`):e.length>1&&Jtt(a,"duplicate-plan",`Connection ${t.name} has ${e.length} fanout plans`,e[0])}for(const t of o)e.connections.some(e=>e.name===t.connectionName)?Qtt({plan:t,preparedBus:l.get(t.busId),inputSrj:e,outputSrj:n,sharedBoundary:r,issues:a}):Jtt(a,"unknown-plan",`Plan ${t.connectionName} is not an input connection`,t);const d=function(t){const{plans:e,inputSrj:n,sharedBoundary:o,issues:i}=t,r=new Set,s=new Map;for(const t of e)s.set(t,[]);for(let t=0;t<e.length;t++){const i=e[t];("plane"===i.termination.type?Boolean(i.via):i.segments.some(t=>Ztt(t.start,o)||Ztt(t.end,o)))&&r.add(i);for(let o=t+1;o<e.length;o++){const t=e[o];$8(n,i.connectionName,t.connectionName)&&tet(i,t)&&(s.get(i).push(t),s.get(t).push(i))}}const a=[...r];for(;a.length>0;){const t=a.shift();for(const e of s.get(t)??[])r.has(e)||(r.add(e),a.push(e))}for(const t of e)r.has(t)||Jtt(i,"not-broken-out","boundary"===t.termination.type?`Connection ${t.connectionName} has no continuous same-net copper path to the shared boundary`:`Plane connection ${t.connectionName} has no terminating via`,t);return r}({plans:o,inputSrj:e,sharedBoundary:r,issues:a});return function(t){const{plans:e,inputSrj:n,clearance:o,issues:i}=t;for(const t of e){const e=Htt(t);for(let r=0;r<e.length;r++){const s=e[r];for(const e of n.obstacles){if(!e.layers.includes(s.layer))continue;if(Y8(n,e,t.connectionName))continue;if(0===r&&e.obstacleId===t.sourceObstacle.obstacleId&&s.layer===t.sourceLayer)continue;if(K8({inputSrj:n,segment:s,bodyObstacle:e,connectionName:t.connectionName}))continue;const a=A8(s,e),c=s.width/2+o;a<c-1e-9&&Jtt(i,"obstacle-clearance",`Trace ${t.connectionName} on ${s.layer} is ${a.toFixed(4)}mm from different-net obstacle ${e.obstacleId}; ${c.toFixed(4)}mm is required`,t)}}for(const e of Gtt(t))for(const r of n.obstacles){if(!r.layers.some(t=>e.spanLayers.includes(t))||Y8(n,r,t.connectionName))continue;const s=E8(e.center,r),a=e.diameter/2+o;s<a-1e-9&&Jtt(i,"via-obstacle-clearance",`Via ${t.connectionName} is ${s.toFixed(4)}mm from different-net obstacle ${r.obstacleId} on its layer span; ${a.toFixed(4)}mm is required`,t)}}for(let t=0;t<e.length;t++){const r=e[t];for(let s=t+1;s<e.length;s++){const t=e[s];if($8(n,r.connectionName,t.connectionName))continue;const a=Htt(r),c=Htt(t),l=Gtt(r),d=Gtt(t);for(const e of a){for(const n of c)O8(e,n,o)||Jtt(i,"different-net-trace-clearance",`Different-net traces ${r.connectionName} and ${t.connectionName} intersect or violate clearance on ${e.layer}`,r,t.connectionName);for(const n of d)n.spanLayers.includes(e.layer)&&N8(n.center,e.start,e.end)<n.diameter/2+e.width/2+o-1e-9&&Jtt(i,"different-net-trace-via-clearance",`Trace ${r.connectionName} violates via clearance to ${t.connectionName} on ${e.layer}`,r,t.connectionName)}for(const e of l){for(const n of c)e.spanLayers.includes(n.layer)&&N8(e.center,n.start,n.end)<e.diameter/2+n.width/2+o-1e-9&&Jtt(i,"different-net-trace-via-clearance",`Via ${r.connectionName} violates trace clearance to ${t.connectionName} on ${n.layer}`,r,t.connectionName);for(const n of d)e.spanLayers.some(t=>n.spanLayers.includes(t))&&M8(e.center,n.center)<(e.diameter+n.diameter)/2+o-1e-9&&Jtt(i,"different-net-via-clearance",`Vias ${r.connectionName} and ${t.connectionName} violate clearance on an overlapping layer span`,r,t.connectionName)}}}}({plans:o,inputSrj:e,clearance:s,issues:a}),{valid:0===a.length,checkedConnectionCount:e.connections.length,brokenOutConnectionCount:new Set([...d].map(t=>t.connectionName)).size,issues:a}}var net=["#ef4444","#2563eb","#16a34a","#9333ea","#f59e0b","#0891b2","#db2777","#65a30d","#4f46e5","#ea580c"];function oet(t){if(!Number.isInteger(t)||t<0)throw new Error(`FanoutSolver: copper layer index must be a non-negative integer, received ${t}`);return net[t%net.length]}var iet=new Set(["top","bottom","inner1","inner2","inner3","inner4","inner5","inner6","inner7","inner8"]),ret={"0603":{padLength:.8,padWidth:.95},1206:{padLength:.6,padWidth:1.6},"1206x4_pair":{padLength:.8,padWidth:.5}},set=(t,e)=>{const n=t.indexOf(e);if(n<0)throw new Error(`FanoutSolver: cannot visualize unknown copper layer "${e}"`);return n},aet=(t,e)=>`z${[...new Set(e.map(e=>set(t,e)))].sort((t,e)=>t-e).join(",")}`,cet=t=>{const e="layers"in t?t.layers:void 0;return e&&e.length>0?e:[t.layer]},det=(t,e)=>t.__zLayers&&t.__zLayers.length>0?[...new Set(t.__zLayers)].filter(t=>Number.isInteger(t)&&t>=0&&t<e.length).sort((t,e)=>t-e):[...new Set(t.layers.map(t=>set(e,t)))].sort((t,e)=>t-e),het=(t,e,n)=>{const o=set(t,e),i=set(t,n);return t.slice(Math.min(o,i),Math.max(o,i)+1)},uet=(...t)=>t.find(t=>"number"==typeof t&&Number.isFinite(t)),pet=t=>{const e=uet(t.min_via_hole_diameter,t.minViaHoleDiameter),n=uet(t.min_via_pad_diameter,t.minViaPadDiameter,t.minViaDiameter);return Math.max(n??t.minViaDiameter??.3,e??0)},met=(t,e)=>{let n={blue:[0,0,255],orange:[255,165,0],purple:[128,0,128],red:[255,0,0]}[t],o=1;const i=/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)(?:\s*,\s*([\d.]+))?\s*\)$/.exec(t);i&&(n=[Number(i[1]),Number(i[2]),Number(i[3])],o=void 0===i[4]?1:Number(i[4]));const r=/^hsl\(\s*([\d.-]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*\)$/.exec(t);if(r&&(n=((t,e,n)=>{const o=(1-Math.abs(2*n-1))*e,i=(t%360+360)%360/60,r=o*(1-Math.abs(i%2-1)),[s,a,c]=i<1?[o,r,0]:i<2?[r,o,0]:i<3?[0,o,r]:i<4?[0,r,o]:i<5?[r,0,o]:[o,0,r],l=n-o/2;return[s,a,c].map(t=>Math.round(255*(t+l)))})(Number(r[1]),Number(r[2])/100,Number(r[3])/100)),!n)return t;const s=+Math.max(0,100*o-100*e).toFixed(2)/100;if(s>=1){const t=n.map(t=>Math.round(t).toString(16).padStart(2,"0")).join("");return t[0]===t[1]&&t[2]===t[3]&&t[4]===t[5]?`#${t[0]}${t[2]}${t[4]}`:`#${t}`}return`rgba(${n.join(",")},${s})`},get=t=>{const e=new Map,n=(t,n)=>{if(!t)return;const o=e.get(t)??[];o.includes(n)||o.push(n),e.set(t,o)};for(const e of t.connections){const t=e.__rootConnectionNames??[e.name];for(const o of t){n(e.name,o),n(o,o),n(e.__netConnectionName,o);for(const t of e.pointsToConnect)n(t.pointId,o),n(t.pcb_port_id,o)}}return t=>{const n=(t=>{const e=new Set;return t.filter(t=>!e.has(t)&&(e.add(t),!0))})([...t.connectedTo.flatMap(t=>e.get(t)??[]),...(t.offBoardConnectsTo??[]).flatMap(t=>e.get(t)??[])]).join(", ");return t.layers.map(t=>n?`${t}\n${n}`:t).join("\n")}};function fet(t){const e=k8(t.layerCount),n=(t.traces??[]).some(t=>t.route.some((e,n)=>{const o=t.route[n+1];return"wire"===e.route_type&&"wire"===o?.route_type&&o.layer===e.layer&&!iet.has(e.layer)})),o=new Set(t.connections.map(({name:t})=>t)),i=n?[...new Set((t.traces??[]).map(({connection_name:t})=>t).filter(t=>t&&!o.has(t)))].map(t=>({name:t,pointsToConnect:[]})):[],r=[...t.connections,...i],s=(a=r,Object.fromEntries(a.map((t,e)=>[t.name,`hsl(${340*e/a.length}, 100%, 50%)`])));var a;const c=get({...t,connections:r}),l=[],d=[],h=[],u=[];for(const t of r)for(const n of t.pointsToConnect){const o=cet(n),i=t.__rootConnectionNames??[t.name];u.push({x:n.x,y:n.y,color:s[t.name],layer:aet(e,o),label:[t.name,i.join(", "),o.join(",")].join("\n")})}for(const o of t.traces??[]){const i=o.route.filter(t=>"jumper"===t.route_type),r=(t,e)=>i.some(n=>{const o=.01;return Math.abs(t.x-n.start.x)<o&&Math.abs(t.y-n.start.y)<o&&Math.abs(e.x-n.end.x)<o&&Math.abs(e.y-n.end.y)<o||Math.abs(t.x-n.end.x)<o&&Math.abs(t.y-n.end.y)<o&&Math.abs(e.x-n.start.x)<o&&Math.abs(e.y-n.start.y)<o});for(const i of o.route)if("via"===i.route_type){const r=het(e,i.from_layer,i.to_layer);d.push({center:{x:i.x,y:i.y},radius:(i.via_diameter??pet(t))/2,fill:n?s[o.connection_name]:"blue",stroke:"none",layer:aet(e,r)})}else"through_obstacle"===i.route_type&&l.push({points:[i.start,i.end],strokeColor:met(s[o.connection_name]??"purple",.35),strokeWidth:i.width,strokeDash:[.1,.1],layer:aet(e,[i.from_layer,i.to_layer]),label:`${o.connection_name} through_obstacle`});for(let t=0;t<o.route.length-1;t++){const i=o.route[t],a=o.route[t+1];if("jumper"===i.route_type){const t=s[o.connection_name]??"rgba(255, 165, 0, 0.8)",n=ret["1206x4_pair"===i.footprint?"1206x4_pair":"0603"],r=Math.abs(i.end.x-i.start.x)>Math.abs(i.end.y-i.start.y),a=r?n.padLength:n.padWidth,c=r?n.padWidth:n.padLength,d=aet(e,[i.layer]);for(const e of[i.start,i.end])h.push({center:e,width:a,height:c,fill:met(t,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:d});l.push({points:[i.start,i.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*n.padWidth,layer:d})}else if("wire"===i.route_type&&"wire"===a.route_type&&a.layer===i.layer&&!r(i,a)){const t=set(e,i.layer);l.push({points:[{x:i.x,y:i.y},{x:a.x,y:a.y}],layer:`z${t}`,strokeWidth:i.width,strokeColor:oet(t),...n?{label:o.connection_name}:{}})}}}for(const n of t.obstacles){if(n.isCopperPour)continue;const t=det(n,e);if(0===t.length)throw new Error(`FanoutSolver: cannot visualize obstacle "${n.obstacleId??"unknown"}" without a valid layer`);const o=1===t.length?e[t[0]]:void 0,i=met("bottom"===o?"blue":"red",.5**t.length),r=n.shape,s={center:n.center,fill:i,layer:`z${t.join(",")}`,label:c(n)};"circle"===r?d.push({...s,radius:Math.min(n.width,n.height)/2}):h.push({...s,width:n.width,height:n.height,ccwRotationDegrees:n.ccwRotationDegrees})}for(const n of t.jumpers??[])for(const t of n.pads)h.push({center:t.center,width:t.width,height:t.height,ccwRotationDegrees:t.ccwRotationDegrees,fill:"rgba(255, 165, 0, 0.3)",stroke:"rgba(255, 165, 0, 0.8)",layer:aet(e,t.layers)});return{rects:h,circles:d,lines:l,points:u}}function yet(t,e){if(!Number.isFinite(e)||e<=0)throw new Error(`FanoutSolver: ${t} must be a positive number, received ${e}`);return e}function _et(t,e,n){const o=new Map(e.map(t=>[t.busId,t.connections.length])),i=new Map;for(const[e,r]of Object.entries(t))i.set(r,(i.get(r)??0)+(n?o.get(e)??1:1));return[...i.values()].reduce((t,e)=>t+e*e,0)}function bet(t){return t.balanceLayerLoadByConnectionCount?.25:.01}function xet(t){return t.reduce((t,e)=>t+Number(Boolean(e.via))+Number(Boolean(e.planeEndpointVia)),0)}function vet(t){const e=t.connections.reduce((e,n)=>e+("left"===t.direction||"right"===t.direction?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length;switch(t.direction){case"right":return t.sharedBoundary.maxX-e;case"left":return e-t.sharedBoundary.minX;case"up":return t.sharedBoundary.maxY-e;case"down":return e-t.sharedBoundary.minY}}function Iet(t){const e="left"===t.direction||"right"===t.direction;return t.connections.some(t=>{const n=t.exitTargetPoint??t.targetPoint,o=e?t.sourcePoint.y:t.sourcePoint.x,i=e?n.y:n.x;return Math.abs(o-i)>1e-6})}function Cet(t){const e="left"===t.direction||"right"===t.direction,n=e?t.xCoordinates:t.yCoordinates,o=t.connections.reduce((t,n)=>t+(e?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length,i="right"===t.direction||"up"===t.direction?Math.max(...n):Math.min(...n);return Math.abs(o-i)<1e-6}function Pet(t){const e="left"===t.direction||"right"===t.direction,n=e?t.xCoordinates:t.yCoordinates,o=t.connections.reduce((t,n)=>t+(e?n.sourcePoint.x:n.sourcePoint.y),0)/t.connections.length,i="right"===t.direction||"up"===t.direction?Math.max(...n):Math.min(...n),r=e?t.pitchX:t.pitchY;return Math.round(Math.abs(o-i)/r)}function Met(t){const{buses:e,escapeLayers:n,escapeLayersByBusId:o}=t,i={},r=new Map;let s=0;for(const t of e){const e=r.get(t.componentId)??new Set;e.add(t.direction),r.set(t.componentId,e)}for(const t of e){const e=t.connections[0]?.sourceLayer;if(!e)throw new Error(`FanoutSolver: bus "${t.busId}" has no connections`);if("plane"===t.termination.type){i[t.busId]=t.termination.layer;continue}const a=o[t.busId]??n,c=a.filter(t=>t!==e);if(a.includes(e)&&(Iet(t)||Cet(t)))i[t.busId]=e;else if(c.length>0){const e=r.get(t.componentId);if(e.has("left")&&e.has("right")||e.has("up")&&e.has("down")){const e=Pet(t);i[t.busId]=c[Math.max(e-1,0)%c.length]}else i[t.busId]=c[s%c.length],s++}else i[t.busId]=e}return i}function Net(t){const{bus:e,srj:n,config:o,staticClearanceCache:i}=t,r=o.escapeLayers.filter(t=>null!==htt({srj:n,bus:e,targetLayer:t,acceptedPlans:[],layerNames:o.layerNames,traceWidth:o.traceWidth,viaDiameter:o.viaDiameter,viaHoleDiameter:o.viaHoleDiameter,clearance:o.clearance,compactBusTracks:o.compactBusTracks,allowSameNetMerges:o.allowSameNetMerges,staticClearanceCache:i}));return r.length>0?r:o.escapeLayers}var wet=class extends b8{constructor(t,e={}){super(),this.inputSrj=t,this.options=e,this.config=function(t,e){const n=yet("traceWidth",e.traceWidth??t.nominalTraceWidth??t.minTraceWidth),o=yet("viaDiameter",e.viaDiameter??t.minViaPadDiameter??t.min_via_pad_diameter??t.minViaDiameter??Math.max(2*n,.3)),i=yet("viaHoleDiameter",e.viaHoleDiameter??t.minViaHoleDiameter??t.min_via_hole_diameter??.5*o);if(i>=o)throw new Error(`FanoutSolver: viaHoleDiameter ${i} must be smaller than viaDiameter ${o}`);const r=yet("clearance",e.clearance??t.minViaEdgeToPadEdgeClearance??t.minTraceToPadEdgeClearance??t.defaultObstacleMargin??t.minTraceWidth),s=k8(t.layerCount),a=e.escapeLayers??s;for(const e of a)if(!s.includes(e))throw new Error(`FanoutSolver: escape layer "${e}" is not available in a ${t.layerCount}-layer SimpleRouteJson`);if(new Set(a).size!==a.length)throw new Error("FanoutSolver: escapeLayers contains duplicates");const c=e.borderDistribution??"preserve";if("preserve"!==c&&"even"!==c)throw new Error(`FanoutSolver: borderDistribution must be "preserve" or "even", received "${c}"`);return{traceWidth:n,viaDiameter:o,viaHoleDiameter:i,clearance:r,compactBusTracks:e.compactBusTracks??!1,allowSameNetMerges:e.allowSameNetMerges??!1,singleLayerPushAndShove:e.singleLayerPushAndShove??!1,singleLayerAdaptiveExits:e.singleLayerAdaptiveExits??!1,borderDistribution:c,layerNames:s,escapeLayers:a,maxLayerCombinations:void 0===e.maxLayerCombinations?256:yet("maxLayerCombinations",e.maxLayerCombinations),balanceLayerLoadByConnectionCount:e.balanceLayerLoadByConnectionCount??!1}}(t,e),this.preparedBuses=j7(t,e);for(const t of this.preparedBuses){if("plane"!==t.termination.type)continue;const e=t.termination.layer;if(!this.config.layerNames.includes(e))throw new Error(`FanoutSolver: plane-terminated bus "${t.busId}" targets unavailable layer "${e}"`);if(t.connections.some(t=>t.sourceLayer===e))throw new Error(`FanoutSolver: plane-terminated bus "${t.busId}" must target a layer below its source pad`)}const n=this.preparedBuses.filter(t=>"boundary"===t.termination.type).map(t=>t.busId),o=Object.fromEntries(this.preparedBuses.flatMap(t=>"plane"===t.termination.type?[[t.busId,t.termination.layer]]:[])),i=Object.fromEntries(this.preparedBuses.flatMap(e=>"plane"===e.termination.type?[]:[[e.busId,Net({bus:e,srj:t,config:this.config,staticClearanceCache:this.routeStaticClearanceCache})]]));this.escapeLayersByBusId=i;const r=function(t){const{busIds:e,layers:n,layersByBusId:o,maxAssignments:i}=t;if(0===n.length)throw new Error("FanoutSolver: no escape layers are available");if(!Number.isInteger(i)||i<1)throw new Error(`FanoutSolver: maxLayerCombinations must be positive, received ${i}`);const r=e.map(t=>o?.[t]??n),s=r.findIndex(t=>0===t.length);if(s>=0)throw new Error(`FanoutSolver: no escape layers are available for bus "${e[s]}"`);const a=r.reduce((t,e)=>t*e.length,1),c=Math.min(i,Number.isFinite(a)?a:i),l=[],d=new Set;function h(t){const n={};for(let o=0;o<e.length;o++)n[e[o]]=r[o][t[o]];const o=JSON.stringify(n);d.has(o)||(d.add(o),l.push(n))}if(a<=i){for(let t=0;t<c;t++){const n=[];let o=t;for(let t=0;t<e.length;t++){const e=r[t].length,i=o%e;o=Math.floor(o/e),n.push((i+t)%e)}h(n)}return l}function u(t){let e=0|t;return e=Math.imul(e^e>>>16,569420461),e=Math.imul(e^e>>>15,1935289751),(e^e>>>15)>>>0}const p=e.map((t,e)=>e%r[e].length);h(p);const m=Math.max(...r.map(t=>t.length));for(let t=1;t<m&&l.length<c;t++)h(p.map((e,n)=>(e+t)%r[n].length));for(let t=0;t<e.length&&l.length<c;t++)for(let e=1;e<r[t].length&&l.length<c;e++){const n=[...p];n[t]=(p[t]+e)%r[t].length,h(n)}for(let t=1;l.length<c&&t<20*c;t++)h(e.map((e,n)=>u(2654435761*t+2246822507*n)%r[n].length));return l}({busIds:n,layers:this.config.escapeLayers,layersByBusId:i,maxAssignments:this.config.maxLayerCombinations}).map(t=>({...t,...o}));this.layerAssignments=function(t){const{preferredAssignment:e,generatedAssignments:n,maxAssignments:o}=t,i=JSON.stringify(e);return[e,...n.filter(t=>JSON.stringify(t)!==i)].slice(0,o)}({preferredAssignment:Met({buses:this.preparedBuses,escapeLayers:this.config.escapeLayers,escapeLayersByBusId:i}),generatedAssignments:r,maxAssignments:this.config.maxLayerCombinations}),this.MAX_ITERATIONS=this.config.maxLayerCombinations+2}inputSrj;options;preparedBuses;attempts=[];layerAssignments;config;escapeLayersByBusId;evaluatedAssignmentKeys=new Set;queuedAssignmentKeys=new Set;assignmentRepairDepthByKey=new Map;pendingRepairAssignments=[];routeStaticClearanceCache=new Map;routingPrefixCache=new Map;groupedBeamEvaluated=!1;nextAssignmentIndex=0;nextGeneratedAssignmentIndex=0;bestAttempt=null;endpointCompletion=null;getSolverName(){return"FanoutSolver"}completeBestAttemptEndpoints(){this.options.completeOriginalEndpoints&&!this.endpointCompletion&&this.bestAttempt&&(this.endpointCompletion=y7({inputSrj:this.inputSrj,fanoutSrj:this.bestAttempt.outputSrj,plans:this.bestAttempt.plans,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,effort:this.options.endpointCompletionEffort,routeDownstreamConnections:this.options.routeDownstreamConnections}))}getValidationBoundary(){if(this.options.sharedBoundary)return this.options.sharedBoundary;const t=this.preparedBuses[0]?.sharedBoundary;return t?this.preparedBuses.slice(1).reduce((t,e)=>({minX:Math.min(t.minX,e.sharedBoundary.minX),maxX:Math.max(t.maxX,e.sharedBoundary.maxX),minY:Math.min(t.minY,e.sharedBoundary.minY),maxY:Math.max(t.maxY,e.sharedBoundary.maxY)}),{...t}):this.inputSrj.bounds}validateCompletePlans(t,e){return eet({inputSrj:this.inputSrj,outputSrj:e,plans:t,preparedBuses:this.preparedBuses,sharedBoundary:this.getValidationBoundary(),clearance:this.config.clearance})}evaluateAssignmentWithStrategy(t,e,n){let o=[],i=[],r=new Map;const s=1===this.config.escapeLayers.length;if(s&&this.config.singleLayerPushAndShove){const t={srj:this.inputSrj,buses:this.preparedBuses,traceWidth:this.config.traceWidth,clearance:this.config.clearance,borderDistribution:this.config.borderDistribution},e=Ytt(t)??(this.config.singleLayerAdaptiveExits?Mtt({...t,availableBoundaryRegions:R7(this.options.availableCornersAndSides)}):null);e?o.push(...e):i.push(...this.preparedBuses.map(t=>t.busId))}const a=[...this.preparedBuses].sort((t,o)=>Number("plane"===o.termination.type)-Number("plane"===t.termination.type)||("group-by-layer"===n?(e[t.busId]??"").localeCompare(e[o.busId]??""):0)||o.componentObstacles.length-t.componentObstacles.length||(s?vet(o)-vet(t):o.connections.length-t.connections.length||("deep-first"===n?vet(o)-vet(t):vet(t)-vet(o))));let c,l=`${n}|`;for(const n of s&&this.config.singleLayerPushAndShove?[]:a){const s=e[n.busId];if(!s)throw new Error(`FanoutSolver: assignment ${t} has no layer for bus "${n.busId}"`);l+=`${n.busId.length}:${n.busId};${s.length}:${s};`;const a=this.routingPrefixCache.get(l);if(a){o=[...a.plans],i=[...a.failedBusIds],r=new Map(a.blockingBusCounts);continue}const c=new Map,d=htt({srj:this.inputSrj,bus:n,targetLayer:s,acceptedPlans:o,layerNames:this.config.layerNames,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,compactBusTracks:this.config.compactBusTracks,allowSameNetMerges:this.config.allowSameNetMerges,staticClearanceCache:this.routeStaticClearanceCache,blockingBusCounts:c});if(d)o.push(...d);else{i.push(n.busId);for(const[t,e]of c)r.set(t,(r.get(t)??0)+e)}this.routingPrefixCache.set(l,{plans:[...o],failedBusIds:[...i],blockingBusCounts:new Map(r)})}let d=S8({inputSrj:this.inputSrj,plans:o,layerNames:this.config.layerNames});const h=o.length===this.inputSrj.connections.length?this.validateCompletePlans(o,d):null;h&&!h.valid&&(c=h.issues,o=[],i=this.preparedBuses.map(t=>t.busId),r.clear(),d=S8({inputSrj:this.inputSrj,plans:o,layerNames:this.config.layerNames}));const u=this.preparedBuses.length-i.length,p=o.reduce((t,e)=>t+e.length,0),m=1e6*(this.inputSrj.connections.length-o.length)+1e5*i.length+p+.1*xet(o)+_et(e,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config);return{summary:{assignmentIndex:t,busLayerAssignments:e,routedBusCount:u,routedConnectionCount:o.length,failedBusIds:i,score:m,...c?{validationIssues:c}:{}},plans:o,blockingBusIds:[...r.entries()].toSorted(([,t],[,e])=>e-t).map(([t])=>t),outputSrj:d}}evaluateAssignment(t,e){let n=this.evaluateAssignmentWithStrategy(t,e,"default");if(n.summary.routedConnectionCount===this.inputSrj.connections.length)return n;for(const o of["group-by-layer","deep-first"]){const i=this.evaluateAssignmentWithStrategy(t,e,o);if(i.summary.score<n.summary.score&&(n=i),n.summary.routedConnectionCount===this.inputSrj.connections.length)return n}return n}evaluateGroupedBeam(t,e=!1){if(this.config.escapeLayers.length<2)return null;if(this.preparedBuses.length>56)return null;const n=this.inputSrj.connections.length;if(n>64)return null;if(1!==new Set(this.preparedBuses.map(t=>t.componentId)).size)return null;const o=[...this.preparedBuses].sort((t,n)=>{const o="plane"===t.termination.type?1:this.escapeLayersByBusId[t.busId]?.length??this.config.escapeLayers.length,i="plane"===n.termination.type?1:this.escapeLayersByBusId[n.busId]?.length??this.config.escapeLayers.length;return Number("plane"===n.termination.type)-Number("plane"===t.termination.type)||(e?t.direction.localeCompare(n.direction):0)||o-i||n.componentObstacles.length-t.componentObstacles.length||n.connections.length-t.connections.length||Pet(n)-Pet(t)||t.busId.localeCompare(n.busId)}),i=n<=24,r=this.preparedBuses.some(t=>t.connections.length>1),s=i?48:n<=32?24:12,a=i&&!r?4:1;let c=[{assignment:{},plans:[]}];const l=t=>t.plans.reduce((t,e)=>t+e.length,0)+.1*xet(t.plans)+1e4*this.preparedBuses.reduce((e,n)=>{if("boundary"!==n.termination.type||!Iet(n))return e;const o=n.connections[0]?.sourceLayer;return t.assignment[n.busId]===o?e:e+n.connections.length},0)+_et(t.assignment,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config);for(const t of o){const e=[];for(const n of c){const o="plane"===t.termination.type?[t.termination.layer]:this.escapeLayersByBusId[t.busId]??this.config.escapeLayers,i=new Map;for(const[t,e]of Object.entries(n.assignment)){const n=this.preparedBuses.find(e=>e.busId===t);i.set(e,(i.get(e)??0)+(this.config.balanceLayerLoadByConnectionCount?n?.connections.length??1:1))}const r=t.connections[0]?.sourceLayer,s=Iet(t),c=o.toSorted((t,e)=>(i.get(t)??0)-(i.get(e)??0)||(s?Number(e===r)-Number(t===r):Number(t===r)-Number(e===r))||t.localeCompare(e));for(const o of c){const i=dtt({srj:this.inputSrj,bus:t,targetLayer:o,acceptedPlans:n.plans,layerNames:this.config.layerNames,traceWidth:this.config.traceWidth,viaDiameter:this.config.viaDiameter,viaHoleDiameter:this.config.viaHoleDiameter,clearance:this.config.clearance,compactBusTracks:this.config.compactBusTracks,allowSameNetMerges:this.config.allowSameNetMerges,staticClearanceCache:this.routeStaticClearanceCache},a);for(const r of i)e.push({assignment:{...n.assignment,[t.busId]:o},plans:[...n.plans,...r]})}}if(0===e.length)return null;e.sort((t,e)=>{const n=l(t)-l(e);return Math.abs(n)>1e-9?n:JSON.stringify(t.assignment).localeCompare(JSON.stringify(e.assignment))});const n=new Map;c=[];for(const t of e){const e=JSON.stringify(t.assignment),o=n.get(e)??0;if(!(o>=2)&&(n.set(e,o+1),c.push(t),c.length>=s))break}}const d=c[0];if(!d)return null;const h=S8({inputSrj:this.inputSrj,plans:d.plans,layerNames:this.config.layerNames});if(d.plans.length===this.inputSrj.connections.length&&!this.validateCompletePlans(d.plans,h).valid)return null;const u=d.plans.length===this.inputSrj.connections.length?d.plans.reduce((t,e)=>t+e.length,0)+.1*xet(d.plans)+_et(d.assignment,this.preparedBuses,this.config.balanceLayerLoadByConnectionCount)*bet(this.config):Number.POSITIVE_INFINITY;if(!Number.isFinite(u))return null;return{summary:{assignmentIndex:t,busLayerAssignments:d.assignment,routedBusCount:this.preparedBuses.length,routedConnectionCount:d.plans.length,failedBusIds:[],score:u},plans:d.plans,blockingBusIds:[],outputSrj:h}}prioritizeFailedBusRepairs(t,e,n){const o=JSON.stringify(t),i=this.assignmentRepairDepthByKey.get(o)??0;if(i>=2)return;const r=[],s=new Set,a=t=>{const e=JSON.stringify(t);s.has(e)||this.evaluatedAssignmentKeys.has(e)||this.queuedAssignmentKeys.has(e)||(s.add(e),this.queuedAssignmentKeys.add(e),this.assignmentRepairDepthByKey.set(e,i+1),r.push(t))},c=[];for(let t=0;t<Math.max(e.length,n.length);t++){const o=e[t],i=n[t];o&&!c.includes(o)&&c.push(o),i&&!c.includes(i)&&c.push(i)}for(const o of e){const e=t[o],i=this.escapeLayersByBusId[o];if(e&&i){for(const s of n.slice(0,4)){const n=t[s],c=this.escapeLayersByBusId[s];if(n&&c&&i.includes(n)&&c.includes(e)&&(a({...t,[o]:n,[s]:e}),r.length>=8))break}if(r.length>=8)break}}for(const e of c){const n=t[e],o=this.escapeLayersByBusId[e];if(!n||!o)continue;const i=o.indexOf(n);for(let s=1;s<o.length;s++){const c=o[(Math.max(i,0)+s)%o.length];if(c!==n&&(a({...t,[e]:c}),r.length>=8))break}if(r.length>=8)break}this.pendingRepairAssignments.push(...r)}hasCompleteBestAttempt(){return this.bestAttempt?.summary.routedConnectionCount===this.inputSrj.connections.length}shouldEvaluateGroupedBeam(){if(this.groupedBeamEvaluated||0===this.nextAssignmentIndex)return!1;return this.hasCompleteBestAttempt()||0===this.pendingRepairAssignments.length||this.nextAssignmentIndex>=this.config.maxLayerCombinations}_step(){if(this.shouldEvaluateGroupedBeam()){this.groupedBeamEvaluated=!0;let t=this.evaluateGroupedBeam(-1);if(t||(t=this.evaluateGroupedBeam(-1,!0)),t){this.attempts.push(t.summary),(!this.bestAttempt||t.summary.score<this.bestAttempt.summary.score)&&(this.bestAttempt=t);const e=this.bestAttempt.summary;return this.stats={assignment:e.assignmentIndex<0?0:e.assignmentIndex+1,assignmentCount:this.config.maxLayerCombinations,routedBuses:`${e.routedBusCount}/${this.preparedBuses.length}`,routedConnections:`${e.routedConnectionCount}/${this.inputSrj.connections.length}`,failedBuses:"none",bestScore:e.score},this.completeBestAttemptEndpoints(),void(this.solved=!0)}if(this.hasCompleteBestAttempt())return this.completeBestAttemptEndpoints(),void(this.solved=!0)}let t;for(;!t&&this.nextAssignmentIndex<this.config.maxLayerCombinations;){const e=this.nextAssignmentIndex%3==0;let n,o=!1;if(!this.groupedBeamEvaluated&&this.nextAssignmentIndex>0?(n=this.pendingRepairAssignments.pop(),o=void 0!==n):e?n=this.layerAssignments[this.nextGeneratedAssignmentIndex++]:(n=this.pendingRepairAssignments.pop(),o=void 0!==n),n||!this.groupedBeamEvaluated&&0!==this.nextAssignmentIndex||(n=e?this.pendingRepairAssignments.pop():this.layerAssignments[this.nextGeneratedAssignmentIndex++],o=e&&void 0!==n),!n)break;const i=JSON.stringify(n);o&&this.queuedAssignmentKeys.delete(i),this.evaluatedAssignmentKeys.has(i)||(t=n)}if(!t&&!this.groupedBeamEvaluated)return;if(!t)return void(this.hasCompleteBestAttempt()?(this.completeBestAttemptEndpoints(),this.solved=!0):(this.failed=!0,this.error=this.bestAttempt?`FanoutSolver: best layer assignment routed ${this.bestAttempt.summary.routedConnectionCount}/${this.inputSrj.connections.length} connections`:"FanoutSolver: no layer assignment could be evaluated"));const e=this.evaluateAssignment(this.nextAssignmentIndex,t);this.nextAssignmentIndex++,this.evaluatedAssignmentKeys.add(JSON.stringify(t)),(!this.bestAttempt||e.summary.routedConnectionCount>=this.bestAttempt.summary.routedConnectionCount)&&this.prioritizeFailedBusRepairs(t,e.summary.failedBusIds,e.blockingBusIds),this.attempts.push(e.summary),(!this.bestAttempt||e.summary.score<this.bestAttempt.summary.score)&&(this.bestAttempt=e),this.stats={assignment:e.summary.assignmentIndex+1,assignmentCount:this.config.maxLayerCombinations,routedBuses:`${e.summary.routedBusCount}/${this.preparedBuses.length}`,routedConnections:`${e.summary.routedConnectionCount}/${this.inputSrj.connections.length}`,failedBuses:e.summary.failedBusIds.join(", ")||"none",bestScore:this.bestAttempt.summary.score},this.groupedBeamEvaluated&&e.summary.routedConnectionCount===this.inputSrj.connections.length&&(this.completeBestAttemptEndpoints(),this.solved=!0)}computeProgress(){return this.solved||this.failed?1:this.nextAssignmentIndex/this.config.maxLayerCombinations}getConstructorParams(){return[this.inputSrj,this.options]}getOutput(){if(!this.solved||!this.bestAttempt)throw new Error("FanoutSolver: getOutput() called before a complete fanout was solved");const t=this.validateCompletePlans(this.bestAttempt.plans,this.bestAttempt.outputSrj);if(!t.valid)throw new Error(`FanoutSolver: completed output failed validation: ${t.issues[0]?.message??"unknown validation error"}`);const e=this.endpointCompletion?.simpleRouteJson??this.bestAttempt.outputSrj,n=new Map((e.traces??[]).map(t=>[t.pcb_trace_id,t]));return{simpleRouteJson:this.endpointCompletion?.simpleRouteJson??this.bestAttempt.outputSrj,fanoutTraces:this.bestAttempt.plans.flatMap(t=>[n.get(t.trace.pcb_trace_id)??t.trace,...t.planeEndpointTrace?[n.get(t.planeEndpointTrace.pcb_trace_id)??t.planeEndpointTrace]:[]]),completionTraces:this.endpointCompletion?.traces??[],...this.endpointCompletion?{endpointCompletion:this.endpointCompletion.report}:{},planeTerminations:this.bestAttempt.plans.flatMap(t=>"plane"===t.termination.type&&t.via?[{busId:t.busId,connectionName:t.connectionName,layer:t.termination.layer,via:t.via}]:[]),busLayerAssignments:this.bestAttempt.summary.busLayerAssignments,busDirections:Object.fromEntries(this.preparedBuses.map(t=>[t.busId,t.direction])),attempts:[...this.attempts],validation:t}}getOutputSimpleRouteJson(){return this.getOutput().simpleRouteJson}visualize(){return fet(this.endpointCompletion?.simpleRouteJson??this.bestAttempt?.outputSrj??this.inputSrj)}};function Tet(t){const{minX:e,maxX:n}=t.bounds,o=(e+n)/2;if(!Number.isFinite(o))throw new Error(`Detected component ${t.componentId} has bad bounds`);return o}function Ret(t){const{minY:e,maxY:n}=t.bounds,o=(e+n)/2;if(!Number.isFinite(o))throw new Error(`Detected component ${t.componentId} has bad bounds`);return o}function Eet(t,e){const n=(function(t,e){const[n,o]=Tet(t)<Tet(e)?[t,e]:[e,t];return o.bounds.minX-n.bounds.maxX}(t,e)-2)/2;return Math.min(4.5,n)}function Aet(t,e){const n=e.filter(t=>"bga"===t.componentKind).map(e=>function(t,e){const n=t.obstacles.filter(t=>t.componentId===e.componentId);if(0===n.length)throw new Error(`Detected component ${e.componentId} has no physical obstacles`);return{...e,bounds:{__type:"rect",minX:Math.min(...n.map(t=>t.center.x-t.width/2)),maxX:Math.max(...n.map(t=>t.center.x+t.width/2)),minY:Math.min(...n.map(t=>t.center.y-t.height/2)),maxY:Math.max(...n.map(t=>t.center.y+t.height/2))}}}(t,e)).toSorted((t,e)=>Tet(t)-Tet(e));if(2!==n.length)throw new Error(`Pipeline 10 requires exactly two detected BGAs; found ${n.map(t=>t.componentId).join(", ")||"none"}`);const[o,i]=n;if(o.componentId===i.componentId)throw new Error("Pipeline 10 requires two distinct BGA component IDs");if(Eet(o,i)<2)throw new Error("Pipeline 10 cannot provide 2mm fanout margins while retaining a 2mm routing corridor");return{first:o,second:i}}function Oet(t,e){const{minX:n,maxX:o,minY:i,maxY:r}=t.bounds;return{minX:n-e,maxX:o+e,minY:i-e,maxY:r+e}}function ket(t){const{minX:e,maxX:n,minY:o,maxY:i}=t.bounds;return{minX:e,maxX:n,minY:o,maxY:i}}function Let({inputSrj:t,source:e,target:n}){const o=Eet(e,n),i=Oet(e,o),r=Tet(n)>Tet(e)?"right":"left",s="right"===r?"left":"right";return t.connections.map((t,n)=>{const a=t.pointsToConnect.filter(t=>t.x>=e.bounds.minX&&t.x<=e.bounds.maxX&&t.y>=e.bounds.minY&&t.y<=e.bounds.maxY);if(1!==a.length)throw new Error(`Connection ${t.name} must touch ${e.componentId} exactly once before fanout`);const c=a[0],l="right"===r?i.maxX-c.x:c.x-i.minX,d=[{direction:"up",distance:i.maxY-c.y},{direction:"down",distance:c.y-i.minY},{direction:s,distance:"right"===s?i.maxX-c.x:c.x-i.minX}].toSorted((t,e)=>t.distance-e.distance)[0].direction,h=l<=o+1.2?r:d;let u="up"===h?"top":"down"===h?"bottom":h;return"up"===h?u=c.x<Tet(e)?"top-left":"top-right":"down"===h?u=c.x<Tet(e)?"bottom-left":"bottom-right":c.y>Ret(e)+1e-6?u="right"===h?"top-right":"top-left":c.y<Ret(e)-1e-6&&(u="right"===h?"bottom-right":"bottom-left"),{busId:`pipeline10_fanout:${e.componentId}:${n}`,connectionNames:[t.name],sourceComponentId:e.componentId,direction:h,preferredExit:u,termination:{type:"boundary"}}})}function Det({inputSrj:t,source:e,target:n}){const o=Eet(e,n);return{buses:Let({inputSrj:t,source:e,target:n}),sourceComponentId:e.componentId,availableCornersAndSides:["top_left","top_middle","top_right","right_top","right_middle","right_bottom","bottom_right","bottom_middle","bottom_left","left_bottom","left_middle","left_top"],componentBounds:{[e.componentId]:ket(e)},sharedBoundary:Oet(e,o),maxLayerCombinations:256,balanceLayerLoadByConnectionCount:!0,compactBusTracks:!0,borderDistribution:"even"}}var zet=class extends kt{constructor(t){super(),this.inputProblem=t,this.fanoutSolver=new wet(t.inputSrj,t.options),this.activeSubSolver=this.fanoutSolver,this.MAX_ITERATIONS=this.fanoutSolver.MAX_ITERATIONS+1}inputProblem;fanoutSolver;_step(){if(this.fanoutSolver.step(),this.progress=this.fanoutSolver.progress,this.stats={...this.fanoutSolver.stats},this.fanoutSolver.failed)return this.error=this.fanoutSolver.error??"Fanout solver failed",this.failed=!0,void(this.activeSubSolver=null);this.fanoutSolver.solved&&(this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.fanoutSolver.getOutput()}getOutputSimpleRouteJson(){return this.fanoutSolver.getOutputSimpleRouteJson()}visualize(){return this.fanoutSolver.visualize()}preview(){return this.fanoutSolver.preview()}},Fet=class extends kt{constructor(t){super(),this.inputProblem=t,this.autoroutingPipelineSolver=new H9(t.inputSrj,t.options),this.activeSubSolver=this.autoroutingPipelineSolver,this.MAX_ITERATIONS=this.autoroutingPipelineSolver.MAX_ITERATIONS+1}inputProblem;autoroutingPipelineSolver;_step(){if(this.autoroutingPipelineSolver.step(),this.progress=this.autoroutingPipelineSolver.progress,this.stats={...this.autoroutingPipelineSolver.stats},this.autoroutingPipelineSolver.failed)return this.error=this.autoroutingPipelineSolver.error??"Autorouting pipeline failed",this.failed=!0,void(this.activeSubSolver=null);this.autoroutingPipelineSolver.solved&&(this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){return this.autoroutingPipelineSolver.getOutputSimpleRouteJson()}visualize(){return this.autoroutingPipelineSolver.visualize()}preview(){return this.autoroutingPipelineSolver.preview()}},Bet=class extends Dt{componentDetectionSolver;firstBgaFanoutSolver;secondBgaFanoutSolver;autoroutingPipelineSolver;get currentPipelineStepIndex(){return this.currentPipelineStageIndex}get startTimeOfPhase(){return this.startTimeOfStage}get timeSpentOnPhase(){return this.timeSpentOnStage}pipelineDef=[Lt("componentDetectionSolver",UZ,t=>[{inputSrj:t.inputProblem.inputSrj}]),Lt("firstBgaFanoutSolver",zet,t=>{const e=Aet(t.inputProblem.inputSrj,t.componentDetectionSolver.getOutput());return[{inputSrj:t.inputProblem.inputSrj,options:Det({inputSrj:t.inputProblem.inputSrj,source:e.first,target:e.second})}]}),Lt("secondBgaFanoutSolver",zet,t=>{const e=Aet(t.inputProblem.inputSrj,t.componentDetectionSolver.getOutput()),n=t.firstBgaFanoutSolver.getOutputSimpleRouteJson();return[{inputSrj:n,options:Det({inputSrj:n,source:e.second,target:e.first})}]}),Lt("autoroutingPipelineSolver",Fet,t=>[{inputSrj:t.secondBgaFanoutSolver.getOutputSimpleRouteJson(),options:t.inputProblem.options}])];constructor(t,e={}){super({inputSrj:t,options:e}),this.MAX_ITERATIONS=1e8*(e.effort??1)+1024}getSolverName(){return"AutoroutingPipelineSolver10_BgaFanout"}getConstructorParams(){return[this.inputProblem.inputSrj,this.inputProblem.options]}getOutput(){if(!this.autoroutingPipelineSolver?.solved)throw new Error("Pipeline 10 has not solved yet");return this.autoroutingPipelineSolver.getOutput()}getOutputSimpleRouteJson(){return this.getOutput()}getOutputSimplifiedPcbTraces(){return this.getOutput().traces??[]}get srjWithPointPairs(){return this.autoroutingPipelineSolver?.autoroutingPipelineSolver.srjWithPointPairs}initialVisualize(){return Ho(this.inputProblem.inputSrj)}finalVisualize(){return Ho(this.getOutput())}},jet=class extends kt{constructor(t){super(),this.inputProblem=t,this.simplifiedRouteByTraceId=new Map(t.simplifiedHdRoutes.map(t=>[t.connectionName,t])),this.MAX_ITERATIONS=t.preparedInput.preparedTraces.length+1}inputProblem;simplifiedRouteByTraceId;outputTraces=[];nextTraceIndex=0;getSolverName(){return"ApplyTraceSimplificationSolver"}_step(){const t=this.inputProblem.preparedInput.preparedTraces,e=t[this.nextTraceIndex];e?(this.outputTraces.push(this.applyTrace(e)),this.nextTraceIndex++,this.progress=this.nextTraceIndex/Math.max(1,t.length)):this.finishApplication()}applyTrace(t){if(!t.mutableHdRoute)return structuredClone(t.originalTrace);const e=this.simplifiedRouteByTraceId.get(t.originalTrace.pcb_trace_id);if(!e||void 0===t.uniformTraceWidth)throw new Error(`Simplification removed trace "${t.originalTrace.pcb_trace_id}"`);const n=Mo(e,this.inputProblem.preparedInput.srj.layerCount,{defaultViaHoleDiameter:t.viaHoleDiameter,obstacles:this.inputProblem.preparedInput.srj.obstacles,connMap:this.inputProblem.preparedInput.connMap}),o=n.filter(t=>"jumper"===t.route_type),i=((t,e)=>t.map(t=>"wire"===t.route_type||"through_obstacle"===t.route_type?{...t,width:e}:t))([...structuredClone(t.leadingTerminalVias),...n.filter(t=>"jumper"!==t.route_type),...structuredClone(t.trailingTerminalVias),...o],t.uniformTraceWidth);return((t,e)=>{const n=t.filter(t=>"wire"===t.route_type);e.startPcbPortId&&n[0]&&(n[0].start_pcb_port_id=e.startPcbPortId),e.endPcbPortId&&n.at(-1)&&(n.at(-1).end_pcb_port_id=e.endPcbPortId)})(i,e),{...structuredClone(t.originalTrace),route:i}}finishApplication(){const t=this.inputProblem.preparedInput.preparedTraces;this.stats={inputTraceCount:t.length,outputTraceCount:this.outputTraces.length,inputRoutePointCount:t.reduce((t,e)=>t+e.originalTrace.route.length,0),outputRoutePointCount:this.outputTraces.reduce((t,e)=>t+e.route.length,0)},this.progress=1,this.solved=!0}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error("Cannot get applied traces before conversion completes");return{...structuredClone(this.inputProblem.preparedInput.originalSrj),traces:structuredClone(this.outputTraces)}}},$et=(t,e)=>{const n=t.at(-1);if(n&&(o=n,i=e,Math.abs(o.x-i.x)<=1e-9&&Math.abs(o.y-i.y)<=1e-9&&o.z===i.z))return void 0!==e.traceThickness&&(n.traceThickness=e.traceThickness),void(void 0!==e.pcb_port_id&&(n.pcb_port_id=e.pcb_port_id));var o,i;t.push(e)},Yet=(t,e,n)=>{for(let o=e+1;o<t.length;o++){const e=t[o];if("wire"===e.route_type)return ko(e.layer,n);if("through_obstacle"===e.route_type)return ko(e.from_layer,n)}},Xet=({fromZ:t,toZ:e,previousZ:n,nextZ:o})=>n===t?[t,e]:n===e?[e,t]:o===e?[t,e]:o===t?[e,t]:[t,e],Vet=(t,e)=>{for(const e of t)if("via"===e.route_type&&void 0!==e.via_diameter)return e.via_diameter;return e},Wet=(t,e)=>{const n="start"===e?t:[...t].reverse();for(const t of n){if("wire"!==t.route_type)continue;const n="start"===e?t.start_pcb_port_id:t.end_pcb_port_id;if(n)return n}},Het=t=>({route_type:"jumper",start:{...t.start},end:{...t.end},footprint:t.footprint}),Get=(t,e)=>{for(const e of t.route)if("via"===e.route_type&&void 0!==e.via_hole_diameter)return e.via_hole_diameter;return e},Uet=class extends kt{preparedInput;seenTraceIds=new Set;nextTraceIndex=0;constructor(t){super();const e=structuredClone(t.inputSrj),n=fX(e),o=ii(n);this.preparedInput={originalSrj:e,srj:n,connMap:o,colorMap:wo(n,o),immutableHdRoutes:[],mutableHdRoutes:[],netByConnectionName:new Map,options:{...t.options},preparedTraces:[]},this.MAX_ITERATIONS=(n.traces?.length??0)+1}getSolverName(){return"PrepareTraceSimplificationSolver"}_step(){const t=this.preparedInput.srj.traces??[],e=t[this.nextTraceIndex];if(!e)return this.stats={inputTraceCount:t.length,mutableTraceCount:this.preparedInput.mutableHdRoutes.length,immutableTraceCount:t.length-this.preparedInput.mutableHdRoutes.length},this.progress=1,void(this.solved=!0);this.prepareTrace(e,this.nextTraceIndex),this.nextTraceIndex++,this.progress=this.nextTraceIndex/Math.max(1,t.length)}prepareTrace(t,e){if(this.seenTraceIds.has(t.pcb_trace_id))throw new Error(`Duplicate pcb_trace_id "${t.pcb_trace_id}"`);this.seenTraceIds.add(t.pcb_trace_id);const n=Yo(this.preparedInput.srj),o=(t=>{const e=t.route.flatMap(t=>"wire"===t.route_type||"through_obstacle"===t.route_type?[t.width]:[]),n=e[0];if(void 0!==n&&!e.some(t=>Math.abs(t-n)>1e-9))return n})(t),{traceToSimplify:i,leadingTerminalVias:r,trailingTerminalVias:s}=(t=>{let e=0;for(;"via"===t.route[e]?.route_type;)e++;let n=t.route.length;for(;"jumper"===t.route[n-1]?.route_type;)n--;let o=n;for(;o>e&&"via"===t.route[o-1]?.route_type;)o--;return{traceToSimplify:{...t,route:[...t.route.slice(e,o),...t.route.slice(n)]},leadingTerminalVias:t.route.slice(0,e),trailingTerminalVias:t.route.slice(o,n)}})(t),a=this.preparedInput.connMap.getNetConnectedToId(t.connection_name)??t.connection_name,c=void 0===o?void 0:((t,e)=>{const n=[],o=[],i=[],r=((t,e)=>{for(const e of t)if("wire"===e.route_type||"through_obstacle"===e.route_type)return e.width;return e})(t.route,e.defaultTraceThickness);for(let s=0;s<t.route.length;s++){const a=t.route[s];if("jumper"===a.route_type){i.push(Het(a));continue}if("wire"===a.route_type){$et(n,{x:a.x,y:a.y,z:ko(a.layer,e.layerCount),traceThickness:a.width,pcb_port_id:a.start_pcb_port_id??a.end_pcb_port_id});continue}const c=ko(a.from_layer,e.layerCount),l=ko(a.to_layer,e.layerCount),[d,h]=Xet({fromZ:c,toZ:l,previousZ:n.at(-1)?.z,nextZ:Yet(t.route,s,e.layerCount)});if("via"===a.route_type){$et(n,{x:a.x,y:a.y,z:d,traceThickness:r}),$et(n,{x:a.x,y:a.y,z:h,traceThickness:r}),o.push({x:a.x,y:a.y});continue}const u=d===c,p=u?a.start:a.end,m=u?a.end:a.start;$et(n,{...p,z:d,traceThickness:a.width,toNextSegmentType:"through_obstacle",...a.circuitJsonMetadata?{toNextSegmentCircuitJsonMetadata:a.circuitJsonMetadata}:{}}),$et(n,{...m,z:h,traceThickness:a.width})}return{connectionName:t.pcb_trace_id,rootConnectionName:e.rootConnectionName,startPcbPortId:Wet(t.route,"start"),endPcbPortId:Wet(t.route,"end"),traceThickness:r,viaDiameter:Vet(t.route,e.defaultViaDiameter),route:n,vias:o,...i.length>0?{jumpers:i}:{}}})(i,{layerCount:this.preparedInput.srj.layerCount,defaultTraceThickness:o,defaultViaDiameter:n.padDiameter,rootConnectionName:a}),l=c&&c.route.length>=2?c:void 0;if(this.preparedInput.preparedTraces.push({originalTrace:t,mutableHdRoute:l,leadingTerminalVias:r,trailingTerminalVias:s,uniformTraceWidth:o,viaHoleDiameter:Get(t,n.holeDiameter)}),!l)return void this.preparedInput.immutableHdRoutes.push(...oQ(t,e,this.preparedInput.srj.layerCount,n.padDiameter,this.preparedInput.connMap));this.preparedInput.mutableHdRoutes.push(l),this.preparedInput.netByConnectionName.set(l.connectionName,a),this.preparedInput.colorMap[l.connectionName]=this.preparedInput.colorMap[a]??this.preparedInput.colorMap[t.connection_name]??"#2563eb";const d={...t,route:[...r,...s]};this.preparedInput.immutableHdRoutes.push(...oQ(d,e,this.preparedInput.srj.layerCount,n.padDiameter,this.preparedInput.connMap))}getOutput(){if(!this.solved)throw new Error("Cannot get prepared traces before preparation completes");return this.preparedInput}},Zet=class extends kt{constructor(t){super(),this.inputProblem=t;const e=t.preparedInput,n=Yo(e.srj);this.traceSimplificationSolver=new vc({hdRoutes:e.mutableHdRoutes,otherHdRoutes:e.immutableHdRoutes,obstacles:e.srj.obstacles,connMap:e.connMap,colorMap:e.colorMap,outline:e.srj.outline,defaultViaDiameter:n.padDiameter,layerCount:e.srj.layerCount,minTraceToPadEdgeClearance:e.srj.minTraceToPadEdgeClearance,minBoardEdgeClearance:e.srj.minBoardEdgeClearance,netByConnectionName:e.netByConnectionName,enableCrossingViaReduction:e.options.enableCrossingViaReduction??!0,preserveRouteEndpoints:!0,useTraceWidthAwareClearance:!0,enableVertexShortcuts:e.options.enableVertexShortcuts??!0}),this.traceSimplificationSolver.MAX_SIMPLIFICATION_PIPELINE_LOOPS=e.options.iterations??2,this.activeSubSolver=this.traceSimplificationSolver,this.MAX_ITERATIONS=this.traceSimplificationSolver.MAX_ITERATIONS+1}inputProblem;traceSimplificationSolver;getSolverName(){return"TraceSimplificationStageSolver"}_step(){if(this.traceSimplificationSolver.step(),this.progress=this.traceSimplificationSolver.progress,this.stats={...this.traceSimplificationSolver.stats},this.traceSimplificationSolver.failed)return this.error=this.traceSimplificationSolver.error??"Trace simplification failed",this.failed=!0,void(this.activeSubSolver=null);this.traceSimplificationSolver.solved&&(this.progress=1,this.solved=!0,this.activeSubSolver=null)}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error("Cannot get simplified routes before cleanup completes");return structuredClone(this.traceSimplificationSolver.simplifiedHdRoutes)}visualize(){return this.traceSimplificationSolver.visualize()}preview(){return this.traceSimplificationSolver.preview()}},qet=class extends kt{constructor(t){super(),this.inputProblem=t;const e=t.preparedInput;this.drcEngine=new s_(e.srj,{connMap:e.connMap,traceClearance:e.srj.minTraceToPadEdgeClearance??.1,viaClearance:.1}),this.MAX_ITERATIONS=3}inputProblem;drcEngine;phase="baseline";baselineErrorCounts={};outputErrorCounts={};getSolverName(){return"ValidateTraceSimplificationSolver"}_step(){return"baseline"===this.phase?(this.baselineErrorCounts=this.evaluateErrorCounts(this.inputProblem.preparedInput.originalSrj),this.phase="output",void(this.progress=1/3)):"output"===this.phase?(this.outputErrorCounts=this.evaluateErrorCounts(this.inputProblem.outputSrj),this.phase="compare",void(this.progress=2/3)):(this.assertNoNewDrcErrors(),this.stats={baselineErrorCounts:this.baselineErrorCounts,outputErrorCounts:this.outputErrorCounts},this.progress=1,void(this.solved=!0))}evaluateErrorCounts(t){return(t=>{const e={};for(const n of t.errors)e[n.type]=(e[n.type]??0)+1;return e})(this.drcEngine.evaluate(t.traces??[]))}assertNoNewDrcErrors(){const t=[...new Set([...Object.keys(this.baselineErrorCounts),...Object.keys(this.outputErrorCounts)])].filter(t=>(this.outputErrorCounts[t]??0)>(this.baselineErrorCounts[t]??0));if(0===t.length)return;const e=t.map(t=>`${t}: ${this.baselineErrorCounts[t]??0} -> ${this.outputErrorCounts[t]??0}`).join(", ");throw new Error(`Pipeline 11 simplification introduced DRC errors (${e})`)}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved)throw new Error("Cannot get Pipeline 11 output before DRC validation");return structuredClone(this.inputProblem.outputSrj)}},Jet=class extends Dt{prepareTraceSimplificationSolver;traceSimplificationStageSolver;applyTraceSimplificationSolver;validateTraceSimplificationSolver;pipelineDef=[Lt("prepareTraceSimplificationSolver",Uet,t=>[{inputSrj:t.inputProblem.inputSrj,options:t.inputProblem.options}]),Lt("traceSimplificationStageSolver",Zet,t=>[{preparedInput:t.prepareTraceSimplificationSolver.getOutput()}]),Lt("applyTraceSimplificationSolver",jet,t=>[{preparedInput:t.prepareTraceSimplificationSolver.getOutput(),simplifiedHdRoutes:t.traceSimplificationStageSolver.getOutput()}]),Lt("validateTraceSimplificationSolver",qet,t=>[{preparedInput:t.prepareTraceSimplificationSolver.getOutput(),outputSrj:t.applyTraceSimplificationSolver.getOutput()}])];constructor(t,e={}){if(void 0!==e.iterations&&(!Number.isInteger(e.iterations)||e.iterations<1))throw new Error("Simplification iterations must be a positive integer");super({inputSrj:t,options:{...e}}),this.MAX_ITERATIONS=1e8}getSolverName(){return"AutoroutingPipelineSolver11_Simplification"}getConstructorParams(){return[this.inputProblem.inputSrj,this.inputProblem.options]}getOutput(){if(!this.validateTraceSimplificationSolver?.solved)throw new Error("Pipeline 11 simplification has not solved yet");return this.validateTraceSimplificationSolver.getOutput()}getOutputSimpleRouteJson(){return this.getOutput()}getOutputSimplifiedPcbTraces(){return structuredClone(this.getOutput().traces??[])}initialVisualize(){return Ho(this.inputProblem.inputSrj)}finalVisualize(){return Ho(this.getOutput())}},Ket=class extends kc{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e}srj;opts;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)||[],o=n.layers&&n.layers.length>0?Array.from(new Set(n.layers.map(t=>ko(t,this.srj.layerCount)))).sort((t,e)=>t-e):Array.from({length:this.srj.layerCount},(t,e)=>this.srj.layerCount-e-1);let i=n.center.x-n.width/2,r=n.center.x+n.width/2,s=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,o=e.center.y-e.height/2,c=e.center.y+e.height/2;i=Math.min(i,t),r=Math.max(r,n),s=Math.min(s,o),a=Math.max(a,c)}const c=r-i,l=a-s,d=(i+r)/2,h=(s+a)/2;let u=!1;for(const t of this.srj.connections){for(const e of t.pointsToConnect)if(e.x>=i&&e.x<=r&&e.y>=s&&e.y<=a){u=!0;break}if(u)break}const p={capacityMeshNodeId:`assignable_via_${n.center.x}_${n.center.y}`,center:{x:d,y:h},width:c,height:l,layer:1===o.length?`z${o[0]}`:`z${o.join(",")}`,availableZ:o,_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=[],o=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),i=t.availableZ.length>1&&!e;if(e)o.push(t);else{if(i){const e=this.getZSubdivisionChildNodes(t);for(const t of e)!t._containsTarget&&this.shouldFilterNodeForObstacle(t)||(this.shouldNodeBeXYSubdivided(t)?o.push(t):(t._containsObstacle=!1,n.push(t)));continue}this.shouldFilterNodeForObstacle(t)&&!t._containsTarget||n.push(t)}}this.unfinishedNodes.push(...o),this.finishedNodes.push(...n)}},Qet=.005,tnt=class extends si{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 o=0;o<=e;o++)n.push(new hi(t.filter(t=>t.availableZ[0]===o)));for(const e of t){const t=[],o=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of o)n._containsTarget&&n._targetConnectionName!==e._targetConnectionName||e._containsTarget&&(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId&&li(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),o=this.nodeMap.get(e);return n.width*n.height-o.width*o.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 o=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===o.length)return void this.nextBatchNodeIds.push(t);const i=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))))},r=o.filter(t=>t.center.x<e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(r.length>0){const{width:t,height:o}=r[0],s=r.every(e=>e.width===t&&e.height===o);Math.abs(r.reduce((t,e)=>t+e.height,0)-e.height)<Qet&&s&&(e.width+=t,e.center.x=e.center.x-t/2,i(r),n=!0)}const s=o.filter(t=>t.center.x>e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(s.length>0&&!n){const{width:t,height:o}=s[0],r=s.every(e=>e.width===t&&e.height===o);Math.abs(s.reduce((t,e)=>t+e.height,0)-e.height)<Qet&&r&&(e.width+=t,e.center.x=e.center.x+t/2,i(s),n=!0)}const a=o.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:o}=a[0],r=a.every(e=>e.width===t&&e.height===o);Math.abs(a.reduce((t,e)=>t+e.width,0)-e.width)<Qet&&r&&(e.height+=o,e.center.y=e.center.y+o/2,i(a),n=!0)}const c=o.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:o}=c[0],r=c.every(e=>e.width===t&&e.height===o);Math.abs(c.reduce((t,e)=>t+e.width,0)-e.width)<Qet&&r&&(e.height+=o,e.center.y=e.center.y-o/2,i(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(Dc(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e&&(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const o of this.currentBatchNodeIds){const i=this.nodeMap.get(o);if(!this.absorbedNodeIds.has(o)&&i){const r=Dc(i,{rectMargin:.01});o===e?r.stroke="rgba(0, 255, 0, 0.8)":n?.some(t=>t.capacityMeshNodeId===o)?r.stroke="rgba(128, 0, 128, 0.8)":r.stroke="rgba(255, 165, 0, 0.8)",r.layer=`z${i.availableZ.join(",")}`,r.label=`${r.label}\n(unprocessed)`,t.rects.push(r)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)&&n){const e=Dc(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}},ent=class extends si{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,o=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;const s=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,l=t.center.y-t.height/2,d=t.center.y+t.height/2;n=Math.min(n,e),o=Math.max(o,c),i=Math.min(i,l),r=Math.max(r,d);for(const e of t.availableZ)s.add(e);t._containsTarget&&(a=!0)}const c=o-n,l=r-i,d=(n+o)/2,h=(i+r)/2,u=Array.from(s).sort((t,e)=>t-e),p={capacityMeshNodeId:`merged_via_${t.center.x}_${t.center.y}`,center:{x:d,y:h},width:c,height:l,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=Dc(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=Dc(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}},nnt=class extends si{constructor(t){const{simpleRouteJson:e,nodes:n,edges:o,colorMap:i,MAX_ITERATIONS:r=1e6,hyperParameters:s={}}=t;super(),this.inputParams=t,this.hyperParameters=s,this.MAX_ITERATIONS=r,this.simpleRouteJson=e,this.nodes=n,this.edges=o,this.colorMap=i??{},this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=ai(this.edges);const a=this.nodes.filter(t=>t._containsTarget);this.unprocessedConnectionPairs=Xi(this.simpleRouteJson.connections.map(t=>{const[e,n]=t.pointsToConnect;return{start:a.find(t=>xe(t.center,e)<t.width/2),end:a.find(t=>xe(t.center,n)<t.width/2),connection:t}}),this.hyperParameters.SHUFFLE_SEED??0),this.viaNodes=this.nodes.filter(t=>t.availableZ.length>1)}inputParams;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 o=this._dist(e,t.start);return this._dist(n,t.start)<o?n:e});this.closestViaForConnectionStartMap.set(t,n);const o=e.reduce((e,n)=>{const o=this._dist(e,t.end);return this._dist(n,t.end)<o?n:e});this.closestViaForConnectionEndMap.set(t,o)}}}_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),o={prevCandidate:null,node:e,g:0,h:t,f:this.GREEDY_MULTIPLIER*t};this.queuedCandidateNodes.push(o)}let o;for(this.queuedCandidateNodes.sort((t,e)=>t.f-e.f);this.queuedCandidateNodes.length&&!o;){const t=this.queuedCandidateNodes.shift();this.visitedNodes.has(t.node.capacityMeshNodeId)||(o=t)}if(!o)return this.failed=!0,void(this.error="No viable candidates left");if(this.visitedNodes.add(o.node.capacityMeshNodeId),o.node.capacityMeshNodeId===n.capacityMeshNodeId){const e=[];let n=o;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 i=this.getNeighbors(o.node);for(const t of i){const e=t.capacityMeshNodeId;if(this.visitedNodes.has(e))continue;const i=this.computeG(o,t,n),r=this.computeH(o,t,n),s=i+this.GREEDY_MULTIPLIER*r,a=this.queuedCandidateNodes.findIndex(t=>t.node.capacityMeshNodeId===e);if(a>=0){if(this.queuedCandidateNodes[a].g<=i)continue;this.queuedCandidateNodes.splice(a,1)}this.queuedCandidateNodes.push({prevCandidate:o,node:t,g:i,h:r,f:s})}}getNeighbors(t){const e=new Set,n=this.nodeEdgeMap.get(t.capacityMeshNodeId)??[];for(const o of n){const[n,i]=o.nodeIds,r=n===t.capacityMeshNodeId?i:n,s=this.nodeMap.get(r);s&&e.add(s)}const o=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!==o&&!t.availableZ.includes(o)))))}clearCandidateNodes(){this.queuedCandidateNodes=[],this.visitedNodes=new Set}computeG(t,e,n){const o=this._dist(t.node,e);return t.g+o}computeH(t,e,n){return this._dist(e,n)}createSolvedRoute(t,e){const n=[];for(let e=0;e<t.length;e++){const o=t[e];o.path?0===e?n.push(...o.path):n.push(...o.path.slice(1)):(0===e&&n.push(o.start),e===t.length-1&&n.push(o.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,$i(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 o=this.getClosestVia(t.start),i=this.getFarVia(o,t.end),r=t.start.availableZ[0]??0,s=t.end.availableZ[0]??0,a=[];return a.push({start:t.start,end:o,solved:!1,layer:r}),r===s?(a.push({start:o,end:i,solved:!1,layer:0===r?1:0}),a.push({start:i,end:t.end,solved:!1,layer:s})):a.push({start:o,end:t.end,solved:!1,layer:s}),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 o=this.hyperParameters.MAX_CLOSEST_VIA_SKIP??0;if(o>0&&n.length>1){const t=$i((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length),e=Math.floor(t()*(o+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,o=new Set;for(const[t,e]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair&&o.add(e.capacityMeshNodeId);for(const[t,e]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair&&o.add(e.capacityMeshNodeId);const i=this.viaNodes.filter(e=>!this.usedNodeMap.has(e.capacityMeshNodeId)&&e.capacityMeshNodeId!==t.capacityMeshNodeId&&!e._completelyInsideObstacle&&!e._containsObstacle&&!o.has(e.capacityMeshNodeId)&&this._dist(e,t)>=n);if(0===i.length){const o=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(o.length>0)return o[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}i.sort((t,n)=>this._dist(t,e)-this._dist(n,e));const r=this.hyperParameters.MAX_FURTHEST_VIA_SKIP??0;if(r>0&&i.length>1){const t=$i((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length+1e3),e=Math.floor(t()*(r+1));return i[Math.min(e,i.length-1)]}return i[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 o of this.nodes){const i=this.queuedCandidateNodes.some(t=>t.node.capacityMeshNodeId===o.capacityMeshNodeId),r=this.queuedCandidateNodes.find(t=>t.node.capacityMeshNodeId===o.capacityMeshNodeId);if(e(o.center)&&n(o.width)&&n(o.height)){const e=Dc(o,{rectMargin:.025,zOffset:.01});t.rects.push({...e,fill:i?"rgba(255, 128, 255, 0.5)":o._containsTarget?"rgba(0, 150, 255, 0.15)":o._containsObstacle?"rgba(255, 0, 0, 0.1)":"rgba(200, 200, 200, 0.05)",label:[`ID: ${o.capacityMeshNodeId}`,`Size: ${o.width.toFixed(2)}x${o.height.toFixed(2)}`,`Z: ${o.availableZ.join(", ")}`,r?`g: ${r.g.toFixed(2)}`:"",r?`h: ${r.h.toFixed(2)}`:"",r?`f: ${r.f.toFixed(2)}`:"",o._containsTarget?"TARGET":"",o._containsObstacle?"OBSTACLE":""].filter(t=>t).join("\n")})}}for(const n of this.edges){const[o,i]=n.nodeIds,r=this.nodeMap.get(o),s=this.nodeMap.get(i);r?.center&&s?.center&&e(r.center)&&e(s.center)&&t.lines.push({points:[r.center,s.center],strokeColor:"rgba(150, 150, 150, 0.2)"})}for(let n=0;n<this.solvedRoutes.length;n++){const o=this.solvedRoutes[n],i=o.path,r="blue";for(let o=0;o<i.length-1;o++){const s=i[o],a=i[o+1];if(s?.center&&a?.center&&e(s.center)&&e(a.center)){const e=s.availableZ.includes(1)&&a.availableZ.includes(1),o=n%5*.02;t.lines.push({points:[{x:s.center.x+o,y:s.center.y+o},{x:a.center.x+o,y:a.center.y+o}],strokeColor:r,strokeDash:e?"5 5":void 0})}}if(i.length>0){const n=i[0],r=i[i.length-1];n?.center&&e(n.center)&&t.points.push({x:n.center.x,y:n.center.y,label:`START: ${o.connection.name}`}),r?.center&&e(r.center)&&t.points.push({x:r.center.x,y:r.center.y,label:`END: ${o.connection.name}`})}}if(this.solvedSubpaths)for(let n=0;n<this.solvedSubpaths.length;n++){const o=this.solvedSubpaths[n];if(o.path&&o.path.length>1)for(let n=0;n<o.path.length-1;n++){const i=o.path[n],r=o.path[n+1];i?.center&&r?.center&&e(i.center)&&e(r.center)&&t.lines.push({points:[i.center,r.center],strokeColor:"green",strokeDash:1===o.layer?"3 3":void 0})}}if(this.activeSubpath){const n=this.activeSubpath.start?.center,o=this.activeSubpath.end?.center;n&&o&&e(n)&&e(o)&&(t.lines.push({points:[n,o],strokeColor:"orange",strokeDash:"5 5"}),t.points.push({x:n.x,y:n.y,label:"ACTIVE START"}),t.points.push({x:o.x,y:o.y,label:"ACTIVE END"}))}const o=this.queuedCandidateNodes.slice(0,10).sort((t,e)=>t.f-e.f);for(let n=0;n<o.length;n++){const i=.6*(1-n/10),r=[];let s=o[n];for(;s;)r.push(s.node),s=s.prevCandidate;if(r.reverse(),r.length>1){const n=r.map(t=>t.center).filter(t=>e(t));n.length>1&&t.lines.push({points:n,strokeColor:To("purple",1-i),strokeDash:1===this.activeSubpath?.layer?"4 2":void 0})}}if(this.activeConnectionPair){const n=this.activeConnectionPair.start?.center,o=this.activeConnectionPair.end?.center;n&&o&&e(n)&&e(o)&&t.lines.push({points:[n,o],strokeColor:"cyan",strokeDash:"20 5"})}if(this.ogUnprocessedSubpaths&&3===this.ogUnprocessedSubpaths.length){const[,o]=this.ogUnprocessedSubpaths;if(o.start?.center&&e(o.start.center)){const e=Math.max(o.start.width||0,o.start.height||0);n(e)&&e>0&&(t.circles.push({center:o.start.center,radius:e,stroke:"blue"}),t.points.push({x:o.start.center.x,y:o.start.center.y,label:"DIRECTIVE VIA 1"}))}if(o.end?.center&&e(o.end.center)){const e=Math.max(o.end.width||0,o.end.height||0);n(e)&&e>0&&(t.circles.push({center:o.end.center,radius:e,stroke:"purple"}),t.points.push({x:o.end.center.x,y:o.end.center.y,label:"DIRECTIVE VIA 2"}))}}if(this.queuedCandidateNodes.length>0)for(const n of this.queuedCandidateNodes){const o=n.node;o?.center&&e(o.center)&&t.circles.push({center:o.center,radius:.05,fill:"rgba(255, 255, 0, 0.6)",stroke:"yellow"})}if(this.visitedNodes.size>0)for(const n of this.visitedNodes){const o=this.nodeMap.get(n);o?.center&&e(o.center)&&t.circles.push({center:o.center,radius:.08,fill:"rgba(128, 128, 128, 0.5)",stroke:"gray"})}return t}},ont=class extends ys{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,o=e>0?n/e:0;return t.iterations/t.MAX_ITERATIONS+(1-o)}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 nnt({...this.constructorParams,hyperParameters:{...this.constructorParams.hyperParameters,...t}})}};function int(t){const e=new Map;for(const n of t)e.set(n.capacityMeshNodeId,n);return e}function rnt(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}var snt=class extends si{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=int(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 o of n.offBoardConnectsTo)t.has(o)||t.set(o,[]),t.get(o).push(e)}this.pendingEdges=[];for(const[e,n]of t)if(n.length>1)for(let t=0;t<n.length;t++)for(let o=t+1;o<n.length;o++)this.pendingEdges.push({node1:n[t],node2:n[o],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(),o=this.createOffboardEdge(t,e,n);this.enhancedEdges.push(o),this.createdEdges.push(o)}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=[],o=new Set(this.shownNodes.map(t=>t.capacityMeshNodeId));for(const e of this.capacityEdges){if(e.isOffboardEdge)continue;if(o.has(e.nodeIds[0])||o.has(e.nodeIds[1])){const n=this.nodeMap.get(e.nodeIds[0]),o=this.nodeMap.get(e.nodeIds[1]);n&&o&&t.push({points:[n.center,o.center],strokeColor:"rgba(0, 200, 0, 0.5)",strokeWidth:.05})}}for(let t=0;t<this.shownNodes.length;t++){const o=this.shownNodes[t],i=o._assignedViaObstacle,r=t===this.shownNodes.length-1&&"showing_nodes"===this.animationState;n.push({center:o.center,width:o.width,height:o.height,fill:r?"rgba(255, 165, 0, 0.5)":"rgba(173, 216, 230, 0.5)",stroke:r?"orange":"blue",strokeWidth:r?.15:.1}),e.push({x:o.center.x,y:o.center.y,color:r?"orange":"blue",label:`${r?"NEW: ":""}${o.capacityMeshNodeId}\n${i?.offBoardConnectsTo?.join(", ")||""}`})}for(let n=0;n<this.createdEdges.length;n++){const o=this.createdEdges[n],i=n===this.createdEdges.length-1&&"showing_edges"===this.animationState,r=this.nodeMap.get(o.nodeIds[0]),s=this.nodeMap.get(o.nodeIds[1]);if(r&&s){t.push({points:[r.center,s.center],strokeColor:i?"red":"orange",strokeWidth:i?.2:.1,strokeDasharray:"0.3,0.15"});const n=rnt(r.center,s.center);e.push({x:n.x,y:n.y,color:i?"red":"orange",label:`${i?"NEW: ":""}⚡ ${o.offboardNetName}`})}}let i="Offboard Capacity Node Solver";switch(this.animationState){case"showing_nodes":i+=` - Showing nodes (${this.shownNodes.length}/${this.shownNodes.length+this.assignableNodes.length})`;break;case"showing_edges":i+=` - Creating edges (${this.createdEdges.length}/${this.createdEdges.length+this.pendingEdges.length})`;break;case"done":i+=` - Done (${this.shownNodes.length} nodes, ${this.createdEdges.length} edges)`}return{lines:t,points:e,rects:n,title:i}}getVirtualOffboardNodes(){return[]}getOffboardEdges(){return this.enhancedEdges.filter(t=>t.isOffboardEdge)}},ant=class extends si{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:o}){super(),this.inputPaths=[...t],this.capacityEdges=e,this.originalConnections=o,this.nodeMap=int(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 o=e[t];if(!o.isFragmentedPath)continue;const i=n.pointsToConnect.filter(t=>{for(const e of o.nodeIds){const n=this.nodeMap.get(e);if(n&&Xj(t,n))return!0}return!1}),r=0===t,s=r?o.nodeIds[o.nodeIds.length-1]:o.nodeIds[0],a=this.nodeMap.get(s);if(i.length>0&&a){const t=i[0],e={x:a.center.x,y:a.center.y,layer:bo(t)},s=r?[...i,e]:[e,...i];this.fragmentedConnections.push({name:o.connectionName,pointsToConnect:s,__netConnectionName:n.__netConnectionName,__rootConnectionNames:n.__rootConnectionNames})}}}splitPath(t){const{nodeIds:e}=t;if(e.length<2)return[t];const n=[];for(let t=0;t<e.length-1;t++){const o=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]);o&&o.isOffboardEdge&&n.push(t)}if(0===n.length)return[t];const o=[];let i=0,r=0;for(const s of n){const n=e.slice(i,s+1);if(n.length>=1){const e=this.nextFragmentId++;o.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${r++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}i=s+1}if(i<e.length){const n=e.slice(i);if(n.length>=1){const e=this.nextFragmentId++;o.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${r++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}}return o.length>0?o:[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((o,i)=>{if(o.isFragmentedPath){const r=i%2==0?"blue":"red";this.drawPath({path:o,color:r,lines:t,points:e,rects:n,labelPrefix:`Frag ${i}: `})}else this.drawPath({path:o,color:"green",lines:t,points:e,rects:n,labelPrefix:""})}),"showing_fragment"===this.animationState&&this.currentFragmentIndex>0){const o=this.fragmentedPaths.length-1;if(o>=0){const i=this.fragmentedPaths[o];i.isFragmentedPath&&this.drawPath({path:i,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]),o=this.nodeMap.get(e.nodeIds[1]);n&&o&&t.push({points:[n.center,o.center],strokeColor:"orange",strokeWidth:.15,strokeDasharray:"0.3,0.15"})}let o="Offboard Path Fragment Solver";return"showing_original_path"===this.animationState?o+=" - Analyzing path...":"showing_fragment"===this.animationState?o+=` - Fragment ${this.currentFragmentIndex}/${this.currentFragments.length}`:o+=` - Done (${this.fragmentedPaths.filter(t=>t.isFragmentedPath).length} fragments)`,{lines:t,points:e,rects:n,title:o}}drawPath(t){const{path:e,color:n,lines:o,points:i,rects:r,labelPrefix:s}=t,a=[];for(let t=0;t<e.nodeIds.length;t++){const o=e.nodeIds[t],c=this.nodeMap.get(o);c&&(a.push(c.center),r.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||i.push({x:c.center.x,y:c.center.y,color:n,label:`${s}${e.connectionName}\n${o}`}))}a.length>1&&o.push({points:a,strokeColor:n,strokeWidth:.1})}};function cnt(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var lnt=class extends si{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,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),r=n.targetMinCapacity??.5;n.capacityDepth=$s(i,r)}this.connMap=ii(t),this.colorMap=wo(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?oo():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}srj;opts;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=[cnt("netToPointPairsSolver",ma,t=>[t.srj,t.colorMap,ri(t.srj)],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=wo(t.srjWithPointPairs,this.connMap),t.connMap=ii(t.srjWithPointPairs)}}),cnt("nodeSolver",Ket,t=>[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.finishedNodes}}),cnt("mergeAssignableViaNodes",ent,t=>[t.nodeSolver?.finishedNodes],{onSolved:t=>{t.capacityNodes=t.mergeAssignableViaNodes?.newNodes}}),cnt("singleLayerNodeMerger",tnt,t=>[t.capacityNodes],{onSolved:t=>{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),cnt("edgeSolver",ui,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),cnt("offboardCapacityNodeSolver",snt,t=>[{capacityNodes:t.capacityNodes,capacityEdges:t.capacityEdges||[]}],{onSolved:t=>{t.capacityEdges=t.offboardCapacityNodeSolver?.enhancedEdges||t.capacityEdges}}),cnt("deadEndSolver",Qc,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)))}}),cnt("initialPathingHyperSolver",ont,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)}}),cnt("offboardPathFragmentSolver",ant,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 o=e.getFragmentedOriginalConnectionNames(),i=e.getFragmentedConnections();o.size>0&&t.srjWithPointPairs&&(t.srjWithPointPairs={...t.srjWithPointPairs,connections:[...t.srjWithPointPairs.connections.filter(t=>!o.has(t.name)),...i]},t.connMap=ii(t.srjWithPointPairs))}}),cnt("edgeToPortSegmentSolver",Nc,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.offboardPathFragmentSolver?.getFragmentedPaths()||t.initialPathingSolver?.getCapacityPaths()||[],colorMap:t.colorMap}]),cnt("segmentToPointSolver",Lc,t=>{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments&&t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=>{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),cnt("unravelMultiSectionSolver",gl,t=>[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),cnt("highDensityRouteSolver",zs,t=>[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap}]),cnt("highDensityStitchSolver",Ca,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),cnt("uselessViaRemovalSolver1",Xa,t=>[{unsimplifiedHdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount,connMap:t.connMap}]),cnt("multiSimplifiedPathSolver1",Za,t=>[{unsimplifiedHdRoutes:t.uselessViaRemovalSolver1?.getOptimizedHdRoutes()||t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline}]),cnt("uselessViaRemovalSolver2",Xa,t=>[{unsimplifiedHdRoutes:t.multiSimplifiedPathSolver1.simplifiedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount,connMap:t.connMap}]),cnt("multiSimplifiedPathSolver2",Za,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(),o=this.mergeAssignableViaNodes?.visualize(),i=this.singleLayerNodeMerger?.visualize(),r=this.strawSolver?.visualize(),s=this.edgeSolver?.visualize(),a=(this.offboardCapacityNodeSolver?.visualize(),this.deadEndSolver?.visualize()),c=this.initialPathingSolver?.visualize(),l=this.offboardPathFragmentSolver?.visualize(),d=this.pathingOptimizer?.visualize(),h=this.edgeToPortSegmentSolver?.visualize(),u=this.segmentToPointSolver?.visualize(),p=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),m=this.highDensityRouteSolver?.visualize(),g=this.highDensityStitchSolver?.visualize(),f=this.uselessViaRemovalSolver1?.visualize(),y=this.uselessViaRemovalSolver2?.visualize(),_=this.multiSimplifiedPathSolver1?.visualize(),b=this.multiSimplifiedPathSolver2?.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 S=Oo(this.srj),I={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,layer:Fo(e,this.srj.layerCount),label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).filter(t=>!t.isCopperPour).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)",layer:jo(t,this.srj.layerCount),label:S(t)}))],lines:v},C=[I,t,e,n,o,i,r,s,a,c,l,d,h,u,p,m?pi(I,m):null,g,f,_,y,b,this.solved?pi({lines:v},Ho(this.getOutputSimpleRouteJson())):null].filter(Boolean);return pi(...C)}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 o of n){const n=o.__netConnectionName,i=o.__rootConnectionNames?.[0],r=e.filter(t=>t.connectionName===o.name);for(let e=0;e<r.length;e++){const s=r[e],a={type:"pcb_trace",pcb_trace_id:`${o.name}_${e}`,connection_name:n??i??o.name,route:Mo(s,this.srj.layerCount)};t.push(a)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},dnt=1e-9,hnt=t=>(t=>"wire"===t.route_type)(t)||(t=>"via"===t.route_type)(t)?t:(t=>"through_obstacle"===t.route_type)(t)&&Math.hypot(t.end.x-t.start.x,t.end.y-t.start.y)<=dnt?{route_type:t.route_type,x:t.start.x,y:t.start.y,from_layer:t.from_layer,to_layer:t.to_layer,width:t.width}:null,unt=(t,e)=>t.layer??e.layer??t.to_layer??e.from_layer??t.from_layer??e.to_layer??"top",pnt=(t,e,n)=>t.width??e.width??n,mnt=(t,e,n,o,i)=>({x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n,layer:o,width:i}),gnt=(t,e)=>({...t,x:Math.abs(t.x-e.minX)<1e-6?e.minX:Math.abs(t.x-e.maxX)<1e-6?e.maxX:t.x,y:Math.abs(t.y-e.minY)<1e-6?e.minY:Math.abs(t.y-e.maxY)<1e-6?e.maxY:t.y}),fnt=({x:t,y:e,layer:n})=>({x:t,y:e,layer:n}),ynt=({x:t,y:e,layer:n,width:o})=>({route_type:"wire",x:t,y:e,layer:n,width:o}),_nt=(t,e,n)=>{const o=e.x-t.x,i=e.y-t.y;let r=0,s=1;const a=(t,e)=>{if(Math.abs(t)<dnt)return e>=0;const n=e/t;if(t<0){if(n>s)return!1;n>r&&(r=n)}else{if(n<r)return!1;n<s&&(s=n)}return!0};return a(-o,t.x-n.minX)&&a(o,n.maxX-t.x)&&a(-i,t.y-n.minY)&&a(i,n.maxY-t.y)?{startT:r,endT:s}:null},bnt=(t,e)=>t.x>=e.minX-1e-6&&t.x<=e.maxX+1e-6&&t.y>=e.minY-1e-6&&t.y<=e.maxY+1e-6&&(Math.abs(t.x-e.minX)<=1e-6||Math.abs(t.x-e.maxX)<=1e-6||Math.abs(t.y-e.minY)<=1e-6||Math.abs(t.y-e.maxY)<=1e-6),xnt=(t,e,n,o,i)=>{var r,s;(r=o,s=i,Math.hypot(r.x-s.x,r.y-s.y)<=dnt)||t.push({type:"pcb_trace",pcb_trace_id:`${e.pcb_trace_id}_keep_${n}`,connection_name:e.connection_name,route:[ynt(o),ynt(i)]})},vnt=({obstacleId:t,start:e,end:n,layer:o,width:i})=>{const r=n.x-e.x,s=n.y-e.y,a=Math.hypot(r,s);return a>i+dnt?null:{obstacleId:t,type:"rect",layers:[o],center:{x:(e.x+n.x)/2,y:(e.y+n.y)/2},width:a,height:i,ccwRotationDegrees:180*Math.atan2(s,r)/Math.PI,connectedTo:[]}},Snt=({connection:t,point:e,endpointIndex:n})=>({obstacleId:`${t.name}_route_endpoint_${n}`,type:"rect",layers:[e.layer],center:{x:e.x,y:e.y},width:e.width,height:e.width,connectedTo:[t.name,t.__rootConnectionNames?.[0]??t.name]}),Int=({trace:t,ripIndex:e,start:n,end:o,region:i,allowInteriorStart:r,allowInteriorEnd:s})=>{if(!r&&!bnt(n,i)||!s&&!bnt(o,i))return null;const a=(({trace:t,ripIndex:e,start:n,end:o})=>({name:`${t.connection_name}_reroute_${t.pcb_trace_id}_${e}`,__rootConnectionNames:[t.connection_name],pointsToConnect:[fnt(n),fnt(o)]}))({trace:t,ripIndex:e,start:n,end:o});return{connection:a,endpointObstacles:[Snt({connection:a,point:n,endpointIndex:0}),Snt({connection:a,point:o,endpointIndex:1})]}},Cnt=(t,e,n)=>{const o=[],i=[],r=[],s=[];let a=null,c=!1,l=0,d=!1;for(let h=0;h<t.route.length-1;h++){const u=hnt(t.route[h]),p=hnt(t.route[h+1]);if(!u||!p)return null;const m=unt(u,p),g=pnt(u,p,n),f=_nt(u,p,e),y=mnt(u,p,0,m,g),_=mnt(u,p,1,m,g),b=0===h;if(!f){xnt(o,t,l++,y,_);continue}if(d=!0,f.startT>dnt){const e=mnt(u,p,f.startT,m,g),n=vnt({obstacleId:`${t.pcb_trace_id}_keep_${l}_bounds`,start:y,end:e,layer:m,width:g});n&&s.push(n),xnt(o,t,l++,y,e)}const x=mnt(u,p,f.endT,m,g),v=gnt(mnt(u,p,f.startT,m,g),e),S=gnt(mnt(u,p,f.endT,m,g),e);if(a||(a=v,c=b&&f.startT<=dnt),f.endT<.999999999){const n=Int({trace:t,ripIndex:i.length,start:a,end:S,region:e,allowInteriorStart:c});n&&(i.push(n.connection),r.push(...n.endpointObstacles)),a=null,c=!1;const d=vnt({obstacleId:`${t.pcb_trace_id}_keep_${l}_bounds`,start:x,end:_,layer:m,width:g});d&&s.push(d),xnt(o,t,l++,x,_)}}if(a){const n=t.route.slice().reverse().map(hnt).find(t=>Boolean(t));if(n){const o=Int({trace:t,ripIndex:i.length,start:a,end:{x:n.x,y:n.y,layer:n.layer??n.from_layer??a.layer,width:a.width},region:e,allowInteriorStart:c,allowInteriorEnd:!0});o&&(i.push(o.connection),r.push(...o.endpointObstacles))}}return{keptTraces:o,rerouteConnections:i,rerouteEndpointObstacles:r,clippedTraceSegmentObstacles:s,hadIntersection:d}},Pnt=(t,e)=>{const n=structuredClone(t),o=[],i=[],r=[],s=[];for(const n of t.traces??[]){const a=Cnt(n,e,t.minTraceWidth);a?a.hadIntersection?(o.push(...a.keptTraces),i.push(...a.rerouteConnections),r.push(...a.rerouteEndpointObstacles),s.push(...a.clippedTraceSegmentObstacles)):o.push(structuredClone(n)):o.push(structuredClone(n))}const a=((t,e)=>{const n={minX:t.minX,maxX:t.maxX,minY:t.minY,maxY:t.maxY};for(const t of e){const e=Ee(t);n.minX=Math.min(n.minX,e.minX),n.maxX=Math.max(n.maxX,e.maxX),n.minY=Math.min(n.minY,e.minY),n.maxY=Math.max(n.maxY,e.maxY)}return n})(e,[...r,...s]);return{...n,bounds:a,obstacles:[...n.obstacles,...r],traces:o,connections:i}},Mnt=(t,e)=>{const n=new Map(e.connections.map(t=>[t.name,t.__rootConnectionNames?.[0]??t.name])),o=(e.traces??[]).map(t=>{const e=n.get(t.connection_name);return e?{...structuredClone(t),connection_name:e}:structuredClone(t)});return{...structuredClone(t),traces:o,jumpers:e.jumpers?structuredClone(e.jumpers):structuredClone(t.jumpers)}},Nnt=(t,e,n=[])=>[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join("\n"),wnt=1.8,Tnt=.95,Rnt=.8,Ent=.95,Ant=class extends si{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;regionId;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.regionId=t.regionId,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=xe(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 o=this.boundsSize.width/this.cellStep,i=this.boundsSize.height/this.cellStep;for(;o*i>n**2&&!(this.cellStep>t.minDistBetweenEnteringPoints);)this.cellStep*=2,o=this.boundsSize.width/this.cellStep,i=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR;const r=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&&!r&&this.handleSimpleCases();const s={x:t.A.x,y:t.A.y};this.initialNodeGridOffset={x:s.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:s.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 Wi([{...t.A,...s,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,regionId:this.regionId,route:[{x:t.x,y:t.y,z:0},{x:e.x,y:e.y,z:0}],traceThickness:this.traceThickness,jumpers:[]}}get jumperPenaltyDistance(){return wnt+this.straightLineDistance*this.JUMPER_PENALTY_FACTOR}isNodeTooCloseToObstacle(t,e){e??=this.obstacleMargin;for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){const o=Ont(n);for(const n of o)if(be(t,n.A,n.B)<this.traceThickness+e)return!0}for(const o of n.jumpers||[])if(this.isNodeTooCloseToJumper(t,o,e))return!0}return!1}isNodeTooCloseToJumper(t,e,n){const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=Math.abs(o)>Math.abs(i),s=(r?Rnt:Ent)/2+n,a=(r?Ent:Rnt)/2+n;return Math.abs(t.x-e.start.x)<s&&Math.abs(t.y-e.start.y)<a||Math.abs(t.x-e.end.x)<s&&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||!(xe(t,this.B)<2*e||xe(t,this.A)<2*e))&&n}doesPathToParentIntersectObstacle(t){const e=t.parent;if(!e)return!1;for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){for(const o of Ont(n))if(fe(t,e,o.A,o.B))return!0;for(const o of n.jumpers||[])if(this.doesSegmentIntersectJumperPads(t,e,o))return!0}}return!1}doesSegmentIntersectJumperPads(t,e,n){const o=this.obstacleMargin,i=n.end.x-n.start.x,r=n.end.y-n.start.y,s=Math.abs(i)>Math.abs(r),a=(s?Rnt:Ent)/2+o,c=(s?Ent:Rnt)/2+o;return!!this.doesSegmentIntersectRect(t,e,n.start,a,c)||!!this.doesSegmentIntersectRect(t,e,n.end,a,c)}doesSegmentIntersectRect(t,e,n,o,i){const r=n.x-o,s=n.x+o,a=n.y-i,c=n.y+i;if(t.x>=r&&t.x<=s&&t.y>=a&&t.y<=c)return!0;if(e.x>=r&&e.x<=s&&e.y>=a&&e.y<=c)return!0;const l=[{A:{x:r,y:a},B:{x:s,y:a}},{A:{x:s,y:a},B:{x:s,y:c}},{A:{x:s,y:c},B:{x:r,y:c}},{A:{x:r,y:c},B:{x:r,y:a}}];for(const n of l)if(fe(t,e,n.A,n.B))return!0;return!1}findObstaclesBetween(t,e){const n=[];for(const o of this.obstacleRoutes){const i=this.connMap?.areIdsConnected?.(this.connectionName,o.connectionName);if(!i)for(const i of Ont(o))fe(t,e,i.A,i.B)&&n.push({A:i.A,B:i.B})}return n}computeHComponents(t){const e=xe(t,this.roundedGoalPosition),n=this.getObstacleProximityPenalty(t),o=this.getEdgeProximityPenalty(t),i=this.getFutureConnectionStartEndPenalty(t),r=this.getFutureConnectionLinePenalty(t),s=t.parent,a=s?.hComponents,c=s?xe(t,s):0,l=(t,n)=>{if(void 0===n||c<1e-9||e<1e-9)return t;const o=(t-n)/c;return(t+Math.max(0,t+o*e))/2},d=l(n,a?.obstacleProximityRate),h=l(o,a?.edgeProximityRate),u=l(i,a?.futureConnectionStartEndProximityRate),p=l(r,a?.futureConnectionLineRate),m=d*e,g=h*e,f=u*e,y=p*e;return{distanceToGoal:e,obstacleProximity:m,edgeProximity:g,futureConnectionStartEndProximityPenalty:f,futureConnectionLine:y,total:e+m+g+f+y,obstacleProximityRate:n,edgeProximityRate:o,futureConnectionStartEndProximityRate:i,futureConnectionLineRate:r}}computeH(t){return this.computeHComponents(t).total}computeGComponents(t){const e=t.parent,n=e?xe(t,e):0,o=e?.gComponents??{distFromStart:0,weightedMmNearObstacle:0,weightedMmNearEdge:0,weightedMmNearFutureConnectionStartEnd:0,weightedMmNearFutureConnectionLine:0,jumperPenalty:0,jumperPadFutureConnectionPenalty:0,total:0},i=o.distFromStart+n,r=o.weightedMmNearObstacle+this.getObstacleProximityPenalty(t)*n,s=o.weightedMmNearEdge+this.getEdgeProximityPenalty(t)*n,a=o.weightedMmNearFutureConnectionStartEnd+this.getFutureConnectionStartEndPenalty(t)*n,c=o.weightedMmNearFutureConnectionLine+this.getFutureConnectionLinePenalty(t)*n;let l=o.jumperPenalty,d=o.jumperPadFutureConnectionPenalty;t.isJumperExit&&(l+=this.jumperPenaltyDistance,d+=this.getJumperPadFutureConnectionPenalty(t));return{distFromStart:i,weightedMmNearObstacle:r,weightedMmNearEdge:s,weightedMmNearFutureConnectionStartEnd:a,weightedMmNearFutureConnectionLine:c,jumperPenalty:l,jumperPadFutureConnectionPenalty:d,total:i+r+s+a+c+l+d}}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 o of this.futureConnections)for(const i of o.points){const o=xe(t,i);o<e&&(e=o,n=i)}return n}getFutureConnectionStartEndPenalty(t){let e=0;const n=this.getClosestFutureConnectionPoint(t);if(n){const o=xe(t,n);if(o>this.FUTURE_CONNECTION_START_END_PROXIMITY)return 0;const i=o/this.FUTURE_CONNECTION_START_END_PROXIMITY;e=this.FUTURE_CONNECTION_START_END_PENALTY*(1-i)**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 o=be(t,n.points[0],n.points[n.points.length-1]);e=Math.min(e,o)}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 o=1/0;for(const t of this.futureConnections)for(const i of t.points){const t=xe(e,i),r=xe(n,i),s=Math.min(t,r);o=Math.min(o,s)}if(o<this.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY){const t=o/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 o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){for(const o of Ont(n))e=Math.min(e,be(t,o.A,o.B));for(const o of n.jumpers||[])e=Math.min(e,this.distanceToJumperPads(t,o))}}return e}distanceToJumperPads(t,e){const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.abs(n)>Math.abs(o),r=(i?Rnt:Ent)/2,s=(i?Ent:Rnt)/2;return Math.min(this.pointToRectDistance(t,e.start,r,s),this.pointToRectDistance(t,e.end,r,s))}pointToRectDistance(t,e,n,o){const i=Math.max(Math.abs(t.x-e.x)-n,0),r=Math.max(Math.abs(t.y-e.y)-o,0);return Math.hypot(i,r)}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)),o=this.OBSTACLE_PROX_SIGMA;return this.OBSTACLE_PROX_PENALTY_FACTOR*Math.exp(-n/o)}getEdgeProximityPenalty(t){const e=this.getClearanceToEdge(t),n=this.EDGE_PROX_SIGMA;if(e>2*this.EDGE_PROX_SIGMA)return 0;const o=xe(t,this.B),i=Math.min(1,o/(2*this.EDGE_PROX_SIGMA));return this.EDGE_PROX_PENALTY_FACTOR*Math.exp(-e/n)*i}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 o of n){const n=2*wnt,i=t.x+o.dx*n,r=t.y+o.dy*n,s=this.findObstaclesBetween(t,{x:i,y:r});if(s.length>0)for(const n of s){const i=this.calculateJumperExit(t,n,o);i&&!this.exploredNodes.has(this.getNodeKey(i))&&(this.isNodeTooCloseToObstacle(i)||this.isNodeTooCloseToEdge(i)||!this.isJumperPlacementValid(t,i)||(i.gComponents=this.computeGComponents(i),i.hComponents=this.computeHComponents(i),i.g=i.gComponents.total,i.h=i.hComponents.total,i.f=this.computeF(i.g,i.h),e.push(i)))}}return e}calculateJumperExit(t,e,n){const o=wnt,i=Math.sqrt(n.dx*n.dx+n.dy*n.dy),r=n.dx/i,s=n.dy/i,a=t.x+r*o,c=t.y+s*o;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,o=e.y-t.y,i=Math.abs(n)>Math.abs(o),r=(i?Rnt:Ent)/2,s=(i?Ent:Rnt)/2,a=this.obstacleMargin,c=[t,e];for(const t of c){const e=[t,{x:t.x-r,y:t.y-s},{x:t.x+r,y:t.y-s},{x:t.x-r,y:t.y+s},{x:t.x+r,y:t.y+s},{x:t.x-r,y:t.y},{x:t.x+r,y:t.y},{x:t.x,y:t.y-s},{x:t.x,y:t.y+s}];for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(o)continue;const i=Ont(n);for(const n of i){for(const t of e)if(be(t,n.A,n.B)<this.traceThickness+a)return!0;if(this.doesSegmentIntersectRect(n.A,n.B,t,r+a,s+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 o=this.getJumpersInPath(t);for(const t of o)if(this.doJumpersOverlap(n,t))return!1;return!0}doJumpersOverlap(t,e){const n=this.obstacleMargin,o=Math.min(t.start.x,t.end.x)-Tnt/2-n,i=Math.max(t.start.x,t.end.x)+Tnt/2+n,r=Math.min(t.start.y,t.end.y)-Tnt/2-n,s=Math.max(t.start.y,t.end.y)+Tnt/2+n,a=Math.min(e.start.x,e.end.x)-Tnt/2-n,c=Math.max(e.start.x,e.end.x)+Tnt/2+n,l=Math.min(e.start.y,e.end.y)-Tnt/2-n,d=Math.max(e.start.y,e.end.y)+Tnt/2+n;return!(i<a||o>c||s<l||r>d)}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:o,maxY:i,minY:r}=this.bounds;for(let s=-1;s<=1;s++)for(let a=-1;a<=1;a++){if(0===s&&0===a)continue;if(!this.ALLOW_DIAGONAL&&0!==s&&0!==a)continue;const c=t.x+s*this.cellStep,l=t.y+a*this.cellStep,d=knt(c,o,n),h=knt(l,r,i),u={...t,parent:t,x:d,y:h,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 s=this.getJumperNeighbors(t);return e.push(...s),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 o=e[t];o.isJumperExit&&o.jumperEntry&&n.push({route_type:"jumper",start:o.jumperEntry,end:{x:o.x,y:o.y},footprint:"0603"})}this.solvedPath={connectionName:this.connectionName,rootConnectionName:this.rootConnectionName,regionId:this.regionId,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){if(void 0===e)return Number.NaN;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=xe(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 o=this.getNeighbors(t);for(const t of o)this.candidates.enqueue(t)}drawJumperPads(t,e,n,o,i,r){const s=e.end.x-e.start.x,a=e.end.y-e.start.y,c=Rnt,l=Ent,d=Math.abs(s)>Math.abs(a),h=d?c:l,u=d?l:c;t.rects.push({center:{x:e.start.x,y:e.start.y},width:h,height:u,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:o??"jumper",step:i,label:r}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:h,height:u,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:o??"jumper",step:i,label:r}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*l,layer:o??"jumper-body",step:i,label:r})}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:Nnt(this.connectionName,this.rootConnectionName,["Input A",`z: ${this.A.z}`]),color:"orange"}),t.points.push({x:this.B.x,y:this.B.y,label:Nnt(this.connectionName,this.rootConnectionName,["Input B",`z: ${this.B.z}`]),color:"orange"}),t.lines.push({points:[this.A,this.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:Nnt(this.connectionName,this.rootConnectionName,["Direct Input Connection"])});for(let e=0;e<this.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let o=0;o<n.route.length-1;o++)t.lines.push({points:[n.route[o],n.route[o+1]],strokeColor:"rgba(255, 0, 0, 0.75)",strokeWidth:n.traceThickness,label:Nnt(n.connectionName,n.rootConnectionName,["Obstacle Route"]),layer:`obstacle${e.toString()}`});for(const o of n.jumpers||[])this.drawJumperPads(t,o,"rgba(255, 0, 0, 0.5)",`obstacle-jumper-${e}`,void 0,Nnt(n.connectionName,n.rootConnectionName,["Obstacle Jumper"]))}for(let e=0;e<this.futureConnections.length;e++){const n=this.futureConnections[e];if(n.points.length<2)continue;const o=n.points[0],i=n.points[n.points.length-1];t.lines.push({points:[o,i],strokeColor:"rgba(0, 100, 255, 0.6)",strokeWidth:this.traceThickness,label:Nnt(n.connectionName,n.rootConnectionName,["Future"]),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[o,i]=n.split(",").map(Number),r=n.endsWith("_j"),s=this.debug_exploredNodeValues.get(n),a=s?.gComponents,c=s?.hComponents,l=c?.distanceToGoal??0,d=[r?"Explored (jumper)":"Explored"];d.push(`g.distFromStart: ${a?.distFromStart.toFixed(2)??"?"}`),d.push(`g.nearObstacle: ${a?.weightedMmNearObstacle.toFixed(2)??"?"}`),d.push(`g.nearEdge: ${a?.weightedMmNearEdge.toFixed(2)??"?"}`),d.push(`g.nearFutStrtEnd: ${a?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??"?"}`),d.push(`g.nearFutLine: ${a?.weightedMmNearFutureConnectionLine.toFixed(2)??"?"}`),d.push(`g.jumper: ${a?.jumperPenalty.toFixed(2)??"?"}`),d.push(`g.jumperPadFutPenalty: ${a?.jumperPadFutureConnectionPenalty.toFixed(2)??"?"}`),d.push(`h.goalDist: ${l.toFixed(2)}`),d.push(`h.obstacleProx: ${c?.obstacleProximity.toFixed(2)??"?"} (${l>0?((c?.obstacleProximity??0)/l).toFixed(3):0}/mm)`),d.push(`h.edgeProx: ${c?.edgeProximity.toFixed(2)??"?"} (${l>0?((c?.edgeProximity??0)/l).toFixed(3):0}/mm)`),d.push(`h.futureConnPt: ${c?.futureConnectionStartEndProximityPenalty.toFixed(2)??"?"} (${l>0?((c?.futureConnectionStartEndProximityPenalty??0)/l).toFixed(3):0}/mm)`),d.push(`h.futureConnLine: ${c?.futureConnectionLine.toFixed(2)??"?"} (${l>0?((c?.futureConnectionLine??0)/l).toFixed(3):0}/mm)`),d.push(`g: ${s?.g.toFixed(2)??"?"}`),d.push(`h: ${s?.h.toFixed(2)??"?"}`),d.push(`f: ${s?.f.toFixed(2)??"?"}`);const h=d.join("\n");t.rects.push({center:{x:o+this.initialNodeGridOffset.x,y:i+this.initialNodeGridOffset.y},fill:r?`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:h})}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 o=e[n],i=o.isJumperExit??!1,r=o.gComponents,s=o.hComponents,a=s?.distanceToGoal??0,c=[`Candidate #${n+1}${i?" (jumper)":""}`];c.push(`g.distFromStart: ${r?.distFromStart.toFixed(2)??"?"}`),c.push(`g.nearObstacle: ${r?.weightedMmNearObstacle.toFixed(2)??"?"}`),c.push(`g.nearEdge: ${r?.weightedMmNearEdge.toFixed(2)??"?"}`),c.push(`g.nearFutureConnPt: ${r?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??"?"}`),c.push(`g.nearFutureConnLine: ${r?.weightedMmNearFutureConnectionLine.toFixed(2)??"?"}`),c.push(`g.jumper: ${r?.jumperPenalty.toFixed(2)??"?"}`),c.push(`g.jumperPadFutureConn: ${r?.jumperPadFutureConnectionPenalty.toFixed(2)??"?"}`),c.push(`g: ${o.g.toFixed(2)}`),c.push(`h.goalDist: ${a.toFixed(2)}`),c.push(`h.obstacleProx: ${s?.obstacleProximity.toFixed(2)??"?"} (${a>0?((s?.obstacleProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.edgeProx: ${s?.edgeProximity.toFixed(2)??"?"} (${a>0?((s?.edgeProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnPt: ${s?.futureConnectionStartEndProximityPenalty.toFixed(2)??"?"} (${a>0?((s?.futureConnectionStartEndProximityPenalty??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnLine: ${s?.futureConnectionLine.toFixed(2)??"?"} (${a>0?((s?.futureConnectionLine??0)/a).toFixed(3):0}/mm)`),c.push(`h: ${o.h.toFixed(2)}`),c.push(`f: ${o.f.toFixed(2)}`);const l=c.join("\n");t.points.push({x:o.x,y:o.y,color:"gray",label:l})}if(this.solvedPath){t.lines.push({points:this.solvedPath.route,strokeColor:"green",label:Nnt(this.solvedPath.connectionName,this.solvedPath.rootConnectionName,["Solved Route"]),strokeWidth:this.traceThickness});for(const e of this.solvedPath.jumpers)this.drawJumperPads(t,e,"rgba(0, 200, 0, 0.8)","solved-jumper",void 0,Nnt(this.solvedPath.connectionName,this.solvedPath.rootConnectionName,["Solved Jumper"]))}const{minX:n,minY:o,maxX:i,maxY:r}=this.bounds;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:r},{x:n,y:r},{x:n,y:o}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}};function Ont(t){const e=[];for(let n=0;n<t.route.length-1;n++)if(t.route[n].z===t.route[n+1].z){const o=t.route[n],i=t.route[n+1],r=t.jumpers?.some(t=>{const e=Math.abs(t.start.x-o.x)<.001&&Math.abs(t.start.y-o.y)<.001&&Math.abs(t.end.x-i.x)<.001&&Math.abs(t.end.y-i.y)<.001,n=Math.abs(t.start.x-i.x)<.001&&Math.abs(t.start.y-i.y)<.001&&Math.abs(t.end.x-o.x)<.001&&Math.abs(t.end.y-o.y)<.001;return e||n});r||e.push({z:o.z,A:o,B:i})}return e}function knt(t,e,n){return Math.max(e,Math.min(t,n))}var Lnt=.8,Dnt=.95,znt=(t,e,n=[])=>[t,e?`rootConnectionName: ${e}`:void 0,...n].filter(Boolean).join("\n"),Fnt=class extends si{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 o=new Map;for(const t of e.portPoints){const e=o.get(t.connectionName)??[];e.push(t),o.set(t.connectionName,e)}this.unsolvedConnections=[];for(const[t,e]of o){const n=Dr(e);for(const[e,o]of n)this.unsolvedConnections.push({connectionName:t,rootConnectionName:e.rootConnectionName??o.rootConnectionName,points:[{x:e.x,y:e.y,z:0},{x:o.x,y:o.y,z:0}]});if(0===n.length&&1===e.length){const[n]=e;this.unsolvedConnections.push({connectionName:t,rootConnectionName:n?.rootConnectionName,points:n?[{x:n.x,y:n.y,z:0}]:[]})}}this.hyperParameters.SHUFFLE_SEED&&(this.unsolvedConnections=Xi(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=>({...e,points:Xi(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Vi(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,o=Math.abs(e.x-n.x)<1e-6,i=Math.abs(e.y-n.y)<1e-6;if(o&&i)return}const{connectionName:e,rootConnectionName:n,points:o}=t;this.activeSubSolver=new Ant({connectionName:e,rootConnectionName:n,regionId:this.nodeWithPortPoints.capacityMeshNodeId,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:ro(this.nodeWithPortPoints),A:{x:o[0].x,y:o[0].y,z:0},B:{x:o[o.length-1].x,y:o[o.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,o,i){const r=e.end.x-e.start.x,s=e.end.y-e.start.y,a=Lnt,c=Dnt,l=Math.abs(r)>Math.abs(s),d=l?a:c,h=l?c:a;t.rects.push({center:{x:e.start.x,y:e.start.y},width:d,height:h,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper",label:i}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:d,height:h,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper",label:i}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*c,layer:"jumper-body",label:i})}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:znt(e.connectionName,e.rootConnectionName,["layer: 0 (single-layer)"]),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 o=this.colorMap[n.connectionName]??"blue";for(let e=0;e<n.route.length-1;e++){const i=n.route[e],r=n.route[e+1];t.lines.push({points:[i,r],strokeColor:To(o,.2),layer:"route-layer-0",strokeWidth:n.traceThickness,label:znt(n.connectionName,n.rootConnectionName,["layer: 0"])})}for(const i of n.jumpers)this.drawJumperPads(t,i,To(o,.5),e,znt(n.connectionName,n.rootConnectionName,["jumper"]))}}const e=ro(this.nodeWithPortPoints),{minX:n,minY:o,maxX:i,maxY:r}=e;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:r},{x:n,y:r},{x:n,y:o}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}},Bnt=Ss;export{G9 as AUTOROUTER_VERSION,lnt as AssignableAutoroutingPipeline1Solver,Wl as AssignableAutoroutingPipeline2,ef as AssignableAutoroutingPipeline3,JX as AttachProjectedRectsSolver,yl as AutoroutingPipeline1_OriginalUnravel,rK as AutoroutingPipelineSolver,Bet as AutoroutingPipelineSolver10_BgaFanout,Jet as AutoroutingPipelineSolver11_Simplification,Pc as AutoroutingPipelineSolver2_PortPointPathing,Nf as AutoroutingPipelineSolver3_HgPortPointPathing,xX as AutoroutingPipelineSolver4,xX as AutoroutingPipelineSolver4_TinyHypergraph,EX as AutoroutingPipelineSolver5,EX as AutoroutingPipelineSolver5_HdCache,rG as AutoroutingPipelineSolver6,rG as AutoroutingPipelineSolver6_PolyHypergraph,rK as AutoroutingPipelineSolver7_MultiGraph,lK as AutoroutingPipelineSolver8,y8 as AutoroutingPipelineSolver9_Networked,H9 as AutoroutingPipelineSolver9_PreloadedTraceGraph,Mc as CapacityMeshSolver,Pd as CurvyIntraNodeSolver,n8 as DEFAULT_HD_CACHE2_SERVER_URL,wz as GlobalDrcBranchPortfolioSolver,Nz as GlobalDrcForceImproveSolver,Ls as GrowShrinkHighDensityIntraNodeSolver,Qg as HighDensitySolver,Bnt as HyperSingleIntraNodeSolver,Qn as InMemoryCache,Fnt as IntraNodeSolverWithJumpers,eo as LocalStorageCache,g8 as PIPELINE9_NETWORKED_SOLVE_POLICY,QX as PolyHighDensitySolver,KX as PolyIntraNodeSolver,KX as PolySingleIntraNodeSolver,Ss as PortfolioSingleIntraNodeSolver,oG as ProjectHighDensityToPolygonSolver,Ant as SingleHighDensityRouteWithJumpersSolver,$s as calculateOptimalCapacityDepth,Ho as convertSrjToGraphicsObject,oo as getGlobalInMemoryCache,no as getGlobalLocalStorageCache,Pnt as getRerouteSimpleRouteJson,js as getTunedTotalCapacity1,Mnt as reconnectReroutedSimpleRouteJsonRegion,io as setupGlobalCaches,_8 as solvePipeline9NetworkedHighDensityNode};
/*! Bundled license information:
is-buffer/index.js:
(*!
* Determine if an object is a Buffer
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*)
deep-rename-keys/index.js:
(*!
* deep-rename-keys <https://github.com/jonschlinkert/deep-rename-keys>
*
* Copyright (c) 2015 Jon Schlinkert, contributors.
* Licensed under the MIT license.
*)
@tscircuit/curvy-trace-solver/dist/index.js:
@tscircuit/find-convex-regions/dist/index.js:
(*! Bundled license information:
is-buffer/index.js:
(*!
* Determine if an object is a Buffer
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*)
deep-rename-keys/index.js:
(*!
* deep-rename-keys <https://github.com/jonschlinkert/deep-rename-keys>
*
* Copyright (c) 2015 Jon Schlinkert, contributors.
* Licensed under the MIT license.
*)
*)
@tscircuit/hypergraph/dist/index.js:
(*! Bundled license information:
@tscircuit/find-convex-regions/dist/index.js:
(*! Bundled license information:
is-buffer/index.js:
(*!
* Determine if an object is a Buffer
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*)
deep-rename-keys/index.js:
(*!
* deep-rename-keys <https://github.com/jonschlinkert/deep-rename-keys>
*
* Copyright (c) 2015 Jon Schlinkert, contributors.
* Licensed under the MIT license.
*)
*)
*)
*///# sourceMappingURL=index.js.map